From cffb1f3e5da189a85cdf17e9c95fc1fcff582c3a Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 5 Nov 2019 17:46:15 +0100 Subject: [PATCH 001/176] IBC alpha --- x/ibc/module.go | 1 + 1 file changed, 1 insertion(+) create mode 100644 x/ibc/module.go diff --git a/x/ibc/module.go b/x/ibc/module.go new file mode 100644 index 000000000000..a81836a9c7ed --- /dev/null +++ b/x/ibc/module.go @@ -0,0 +1 @@ +package ibc From d5a94375ef208fd829a907611805b7465171befb Mon Sep 17 00:00:00 2001 From: Joon Date: Tue, 5 Nov 2019 08:53:04 -0800 Subject: [PATCH 002/176] ICS 23 Implementation (#4515) * add mapping * rm unused mapping/*, rm interfaces * rm unused code * mv mapping -> state, rm x/ibc * rm GetIfExists * add key * rm custom encoding/decoding in enum/bool * fix lint * rm tests * add commitment * newtyped remote values * newtyped context * revert context newtype * add README, keypath * reflect downstream ics * add merkle * add test for proving * soft coded root keypath * add update * remove RootUpdate * separate keypath and keuprefix * add codec * separate root/path * add path to codec * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * reformat test * rm XXX * add godoc * add query * update query.go * update query.go * add Query to boolean.go * fix key * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * revise querier interface to work both on cli & store * rm commented lines * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * remove Mapping * remove store accessors * refactor ICS23 * cleanup types * implement batch verification * gosimple suggestion * alias * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * complete types testing * delete empty test file * remove ibc errors from core error package * start batch-verify tests * minor changes on commitment types * use testsuite * upstream changes * context changes --- client/context/context.go | 47 ++++++++ client/context/query.go | 113 ++++++++++++++++--- x/ibc/23-commitment/codec.go | 18 ++++ x/ibc/23-commitment/commitment_test.go | 37 +++++++ x/ibc/23-commitment/merkle.go | 143 +++++++++++++++++++++++++ x/ibc/23-commitment/merkle_test.go | 122 +++++++++++++++++++++ x/ibc/23-commitment/types.go | 65 +++++++++++ x/ibc/23-commitment/verify.go | 62 +++++++++++ x/ibc/24-host/errors.go | 19 ++++ x/ibc/24-host/utils.go | 11 ++ x/ibc/24-host/validate.go | 98 +++++++++++++++++ 11 files changed, 719 insertions(+), 16 deletions(-) create mode 100644 x/ibc/23-commitment/codec.go create mode 100644 x/ibc/23-commitment/commitment_test.go create mode 100644 x/ibc/23-commitment/merkle.go create mode 100644 x/ibc/23-commitment/merkle_test.go create mode 100644 x/ibc/23-commitment/types.go create mode 100644 x/ibc/23-commitment/verify.go create mode 100644 x/ibc/24-host/errors.go create mode 100644 x/ibc/24-host/utils.go create mode 100644 x/ibc/24-host/validate.go diff --git a/client/context/context.go b/client/context/context.go index 2fd6ff66f8be..07168ecdf6ca 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -99,6 +99,53 @@ func NewCLIContextWithFrom(from string) CLIContext { return ctx.WithVerifier(verifier) } +// NewCLIContextIBC takes additional arguements +func NewCLIContextIBC(from string, chainID string, nodeURI string) CLIContext { + var rpc rpcclient.Client + + genOnly := viper.GetBool(flags.FlagGenerateOnly) + fromAddress, fromName, err := GetFromFields(from, genOnly) + if err != nil { + fmt.Printf("failed to get from fields: %v", err) + os.Exit(1) + } + + if !genOnly { + if nodeURI != "" { + rpc = rpcclient.NewHTTP(nodeURI, "/websocket") + } + } + + ctx := CLIContext{ + Client: rpc, + ChainID: chainID, + Output: os.Stdout, + NodeURI: nodeURI, + From: from, + OutputFormat: viper.GetString(cli.OutputFlag), + Height: viper.GetInt64(flags.FlagHeight), + HomeDir: viper.GetString(flags.FlagHome), + TrustNode: viper.GetBool(flags.FlagTrustNode), + UseLedger: viper.GetBool(flags.FlagUseLedger), + BroadcastMode: viper.GetString(flags.FlagBroadcastMode), + Simulate: viper.GetBool(flags.FlagDryRun), + GenerateOnly: genOnly, + FromAddress: fromAddress, + FromName: fromName, + Indent: viper.GetBool(flags.FlagIndentResponse), + SkipConfirm: viper.GetBool(flags.FlagSkipConfirmation), + } + + // create a verifier for the specific chain ID and RPC client + verifier, err := CreateVerifier(ctx, DefaultVerifierCacheSize) + if err != nil && viper.IsSet(flags.FlagTrustNode) { + fmt.Printf("failed to create verifier: %s\n", err) + os.Exit(1) + } + + return ctx.WithVerifier(verifier) +} + // NewCLIContext returns a new initialized CLIContext with parameters from the // command line using Viper. func NewCLIContext() CLIContext { return NewCLIContextWithFrom(viper.GetString(flags.FlagFrom)) } diff --git a/client/context/query.go b/client/context/query.go index 2a553d663367..2a01a7577a0c 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -3,6 +3,7 @@ package context import ( "fmt" "strings" + "time" "github.com/pkg/errors" @@ -12,6 +13,7 @@ import ( tmliteErr "github.com/tendermint/tendermint/lite/errors" tmliteProxy "github.com/tendermint/tendermint/lite/proxy" rpcclient "github.com/tendermint/tendermint/rpc/client" + ctypes "github.com/tendermint/tendermint/rpc/core/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/store/rootmulti" @@ -28,6 +30,55 @@ func (ctx CLIContext) GetNode() (rpcclient.Client, error) { return ctx.Client, nil } +// WaitForNBlocks blocks until the node defined on the context has advanced N blocks +func (ctx CLIContext) WaitForNBlocks(n int64) { + node, err := ctx.GetNode() + if err != nil { + panic(err) + } + + resBlock, err := node.Block(nil) + var height int64 + if err != nil || resBlock.Block == nil { + // wait for the first block to exist + ctx.waitForHeight(1) + height = 1 + n + } else { + height = resBlock.Block.Height + n + } + ctx.waitForHeight(height) +} + +func (ctx CLIContext) waitForHeight(height int64) { + node, err := ctx.GetNode() + if err != nil { + panic(err) + } + + for { + // get url, try a few times + var resBlock *ctypes.ResultBlock + var err error + INNER: + for i := 0; i < 5; i++ { + resBlock, err = node.Block(nil) + if err == nil { + break INNER + } + time.Sleep(time.Millisecond * 200) + } + if err != nil { + panic(err) + } + + if resBlock.Block != nil && resBlock.Block.Height >= height { + return + } + + time.Sleep(time.Millisecond * 100) + } +} + // Query performs a query to a Tendermint node with the provided path. // It returns the result and height of the query upon success or an error if // the query fails. @@ -49,6 +100,12 @@ func (ctx CLIContext) QueryStore(key cmn.HexBytes, storeName string) ([]byte, in return ctx.queryStore(key, storeName, "key") } +// QueryABCI performs a query to a Tendermint node with the provide RequestQuery. +// It returns the ResultQuery obtained from the query. +func (ctx CLIContext) QueryABCI(req abci.RequestQuery) (abci.ResponseQuery, error) { + return ctx.queryABCI(req) +} + // QuerySubspace performs a query to a Tendermint node with the provided // store name and subspace. It returns key value pair and height of the query // upon success or an error if the query fails. @@ -72,40 +129,64 @@ func (ctx CLIContext) GetFromName() string { return ctx.FromName } -// query performs a query to a Tendermint node with the provided store name -// and path. It returns the result and height of the query upon success -// or an error if the query fails. In addition, it will verify the returned -// proof if TrustNode is disabled. If proof verification fails or the query -// height is invalid, an error will be returned. -func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, height int64, err error) { +func (ctx CLIContext) queryABCI(req abci.RequestQuery) (resp abci.ResponseQuery, err error) { + node, err := ctx.GetNode() if err != nil { - return res, height, err + return resp, err + } + + // When a client did not provide a query height, manually query for it so it can + // be injected downstream into responses. + if ctx.Height == 0 { + status, err := node.Status() + if err != nil { + return resp, err + } + ctx = ctx.WithHeight(status.SyncInfo.LatestBlockHeight) } opts := rpcclient.ABCIQueryOptions{ Height: ctx.Height, - Prove: !ctx.TrustNode, + Prove: req.Prove || !ctx.TrustNode, } - result, err := node.ABCIQueryWithOptions(path, key, opts) + result, err := node.ABCIQueryWithOptions(req.Path, req.Data, opts) if err != nil { - return res, height, err + return } - resp := result.Response + resp = result.Response if !resp.IsOK() { - return res, resp.Height, errors.New(resp.Log) + err = errors.New(resp.Log) + return } // data from trusted node or subspace query doesn't need verification - if ctx.TrustNode || !isQueryStoreWithProof(path) { - return resp.Value, resp.Height, nil + if ctx.TrustNode || !isQueryStoreWithProof(req.Path) { + return resp, nil } - err = ctx.verifyProof(path, resp) + err = ctx.verifyProof(req.Path, resp) + if err != nil { + return + } + + return +} + +// query performs a query to a Tendermint node with the provided store name +// and path. It returns the result and height of the query upon success +// or an error if the query fails. In addition, it will verify the returned +// proof if TrustNode is disabled. If proof verification fails or the query +// height is invalid, an error will be returned. +func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, height int64, err error) { + resp, err := ctx.queryABCI(abci.RequestQuery{ + Path: path, + Data: key, + }) if err != nil { - return res, resp.Height, err + return } return resp.Value, resp.Height, nil diff --git a/x/ibc/23-commitment/codec.go b/x/ibc/23-commitment/codec.go new file mode 100644 index 000000000000..7e90e8cac69e --- /dev/null +++ b/x/ibc/23-commitment/codec.go @@ -0,0 +1,18 @@ +package commitment + +import ( + "github.com/cosmos/cosmos-sdk/codec" +) + +// RegisterCodec registers types declared in this package +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*RootI)(nil), nil) + cdc.RegisterInterface((*PrefixI)(nil), nil) + cdc.RegisterInterface((*PathI)(nil), nil) + cdc.RegisterInterface((*ProofI)(nil), nil) + + cdc.RegisterConcrete(Root{}, "ibc/commitment/merkle/Root", nil) + cdc.RegisterConcrete(Prefix{}, "ibc/commitment/merkle/Prefix", nil) + cdc.RegisterConcrete(Path{}, "ibc/commitment/merkle/Path", nil) + cdc.RegisterConcrete(Proof{}, "ibc/commitment/merkle/Proof", nil) +} diff --git a/x/ibc/23-commitment/commitment_test.go b/x/ibc/23-commitment/commitment_test.go new file mode 100644 index 000000000000..2535f5705e29 --- /dev/null +++ b/x/ibc/23-commitment/commitment_test.go @@ -0,0 +1,37 @@ +package commitment_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + + dbm "github.com/tendermint/tm-db" +) + +type MerkleTestSuite struct { + suite.Suite + + store *rootmulti.Store + storeKey *storetypes.KVStoreKey + iavlStore *iavl.Store +} + +func (suite *MerkleTestSuite) SetupTest() { + db := dbm.NewMemDB() + suite.store = rootmulti.NewStore(db) + + suite.storeKey = storetypes.NewKVStoreKey("iavlStoreKey") + + suite.store.MountStoreWithDB(suite.storeKey, storetypes.StoreTypeIAVL, nil) + suite.store.LoadVersion(0) + + suite.iavlStore = suite.store.GetCommitStore(suite.storeKey).(*iavl.Store) +} + +func TestMerkleTestSuite(t *testing.T) { + suite.Run(t, new(MerkleTestSuite)) +} diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/merkle.go new file mode 100644 index 000000000000..ab428eeaf737 --- /dev/null +++ b/x/ibc/23-commitment/merkle.go @@ -0,0 +1,143 @@ +package commitment + +import ( + "errors" + + "github.com/tendermint/tendermint/crypto/merkle" + + "github.com/cosmos/cosmos-sdk/store/rootmulti" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +// ICS 023 Merkle Types Implementation +// +// This file defines Merkle commitment types that implements ICS 023. + +// Merkle proof implementation of the Proof interface +// Applied on SDK-based IBC implementation +var _ RootI = Root{} + +// Root defines a merkle root hash. +// In the Cosmos SDK, the AppHash of a block header becomes the Root. +type Root struct { + Hash []byte `json:"hash" yaml:"hash"` +} + +// NewRoot constructs a new Root +func NewRoot(hash []byte) Root { + return Root{ + Hash: hash, + } +} + +// GetCommitmentType implements RootI interface +func (Root) GetCommitmentType() Type { + return Merkle +} + +// GetHash implements RootI interface +func (r Root) GetHash() []byte { + return r.Hash +} + +var _ PrefixI = Prefix{} + +// Prefix is merkle path prefixed to the key. +// The constructed key from the Path and the key will be append(Path.KeyPath, append(Path.KeyPrefix, key...)) +type Prefix struct { + KeyPrefix []byte `json:"key_prefix" yaml:"key_prefix"` // byte slice prefixed before the key +} + +// NewPrefix constructs new Prefix instance +func NewPrefix(keyPrefix []byte) Prefix { + return Prefix{ + KeyPrefix: keyPrefix, + } +} + +// GetCommitmentType implements PrefixI +func (Prefix) GetCommitmentType() Type { + return Merkle +} + +// Bytes returns the key prefix bytes +func (p Prefix) Bytes() []byte { + return p.KeyPrefix +} + +var _ PathI = Path{} + +// Path is the path used to verify commitment proofs, which can be an arbitrary +// structured object (defined by a commitment type). +type Path struct { + KeyPath merkle.KeyPath `json:"key_path" yaml:"key_path"` // byte slice prefixed before the key +} + +// NewPath creates a new CommitmentPath instance +func NewPath(keyPathStr []string) Path { + merkleKeyPath := merkle.KeyPath{} + for _, keyStr := range keyPathStr { + merkleKeyPath = merkleKeyPath.AppendKey([]byte(keyStr), merkle.KeyEncodingURL) + } + + return Path{ + KeyPath: merkleKeyPath, + } +} + +// GetCommitmentType implements PathI +func (Path) GetCommitmentType() Type { + return Merkle +} + +// String implements fmt.Stringer +func (p Path) String() string { + return p.KeyPath.String() +} + +// ApplyPrefix constructs a new commitment path from the arguments. It interprets +// the path argument in the context of the prefix argument. +// +// CONTRACT: provided path string MUST be a well formated path. See ICS24 for +// reference. +func ApplyPrefix(prefix PrefixI, path string) (Path, error) { + err := host.DefaultPathValidator(path) + if err != nil { + return Path{}, err + } + + if prefix == nil || len(prefix.Bytes()) == 0 { + return Path{}, errors.New("prefix can't be empty") + } + + return NewPath([]string{string(prefix.Bytes()), path}), nil +} + +var _ ProofI = Proof{} + +// Proof is a wrapper type that contains a merkle proof. +// It demonstrates membership or non-membership for an element or set of elements, +// verifiable in conjunction with a known commitment root. Proofs should be +// succinct. +type Proof struct { + Proof *merkle.Proof `json:"proof" yaml:"proof"` +} + +// GetCommitmentType implements ProofI +func (Proof) GetCommitmentType() Type { + return Merkle +} + +// VerifyMembership verifies the membership pf a merkle proof against the given root, path, and value. +func (proof Proof) VerifyMembership(root RootI, path PathI, value []byte) bool { + runtime := rootmulti.DefaultProofRuntime() + err := runtime.VerifyValue(proof.Proof, root.GetHash(), path.String(), value) + return err == nil +} + +// VerifyNonMembership verifies the absence of a merkle proof against the given root and path. +func (proof Proof) VerifyNonMembership(root RootI, path PathI) bool { + runtime := rootmulti.DefaultProofRuntime() + err := runtime.VerifyAbsence(proof.Proof, root.GetHash(), path.String()) + return err == nil +} diff --git a/x/ibc/23-commitment/merkle_test.go b/x/ibc/23-commitment/merkle_test.go new file mode 100644 index 000000000000..bfd2dc5a485c --- /dev/null +++ b/x/ibc/23-commitment/merkle_test.go @@ -0,0 +1,122 @@ +package commitment_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + + abci "github.com/tendermint/tendermint/abci/types" +) + +func (suite *MerkleTestSuite) TestVerifyMembership() { + suite.iavlStore.Set([]byte("MYKEY"), []byte("MYVALUE")) + cid := suite.store.Commit() + + res := suite.store.Query(abci.RequestQuery{ + Path: fmt.Sprintf("/%s/key", suite.storeKey.Name()), // required path to get key/value+proof + Data: []byte("MYKEY"), + Prove: true, + }) + require.NotNil(suite.T(), res.Proof) + + proof := commitment.Proof{ + Proof: res.Proof, + } + + cases := []struct { + name string + root []byte + pathArr []string + value []byte + shouldPass bool + }{ + {"valid proof", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, []byte("MYVALUE"), true}, // valid proof + {"wrong value", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, []byte("WRONGVALUE"), false}, // invalid proof with wrong value + {"nil value", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, []byte(nil), false}, // invalid proof with nil value + {"wrong key", cid.Hash, []string{suite.storeKey.Name(), "NOTMYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong key + {"wrong path 1", cid.Hash, []string{suite.storeKey.Name(), "MYKEY", "MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong path + {"wrong path 2", cid.Hash, []string{suite.storeKey.Name()}, []byte("MYVALUE"), false}, // invalid proof with wrong path + {"wrong path 3", cid.Hash, []string{"MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong path + {"wrong storekey", cid.Hash, []string{"otherStoreKey", "MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong store prefix + {"wrong root", []byte("WRONGROOT"), []string{suite.storeKey.Name(), "MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong root + {"nil root", []byte(nil), []string{suite.storeKey.Name(), "MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with nil root + } + + for i, tc := range cases { + suite.Run(tc.name, func() { + root := commitment.NewRoot(tc.root) + path := commitment.NewPath(tc.pathArr) + + ok := proof.VerifyMembership(root, path, tc.value) + + require.True(suite.T(), ok == tc.shouldPass, "Test case %d failed", i) + }) + } + +} + +func (suite *MerkleTestSuite) TestVerifyNonMembership() { + suite.iavlStore.Set([]byte("MYKEY"), []byte("MYVALUE")) + cid := suite.store.Commit() + + // Get Proof + res := suite.store.Query(abci.RequestQuery{ + Path: fmt.Sprintf("/%s/key", suite.storeKey.Name()), // required path to get key/value+proof + Data: []byte("MYABSENTKEY"), + Prove: true, + }) + require.NotNil(suite.T(), res.Proof) + + proof := commitment.Proof{ + Proof: res.Proof, + } + + cases := []struct { + name string + root []byte + pathArr []string + shouldPass bool + }{ + {"valid proof", cid.Hash, []string{suite.storeKey.Name(), "MYABSENTKEY"}, true}, // valid proof + {"wrong key", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, false}, // invalid proof with existent key + {"wrong path 1", cid.Hash, []string{suite.storeKey.Name(), "MYKEY", "MYABSENTKEY"}, false}, // invalid proof with wrong path + {"wrong path 2", cid.Hash, []string{suite.storeKey.Name(), "MYABSENTKEY", "MYKEY"}, false}, // invalid proof with wrong path + {"wrong path 3", cid.Hash, []string{suite.storeKey.Name()}, false}, // invalid proof with wrong path + {"wrong path 4", cid.Hash, []string{"MYABSENTKEY"}, false}, // invalid proof with wrong path + {"wrong storeKey", cid.Hash, []string{"otherStoreKey", "MYABSENTKEY"}, false}, // invalid proof with wrong store prefix + {"wrong root", []byte("WRONGROOT"), []string{suite.storeKey.Name(), "MYABSENTKEY"}, false}, // invalid proof with wrong root + {"nil root", []byte(nil), []string{suite.storeKey.Name(), "MYABSENTKEY"}, false}, // invalid proof with nil root + } + + for i, tc := range cases { + suite.Run(tc.name, func() { + root := commitment.NewRoot(tc.root) + path := commitment.NewPath(tc.pathArr) + + ok := proof.VerifyNonMembership(root, path) + + require.True(suite.T(), ok == tc.shouldPass, "Test case %d failed", i) + }) + } + +} + +func TestApplyPrefix(t *testing.T) { + prefix := commitment.NewPrefix([]byte("storePrefixKey")) + + pathStr := "path1/path2/path3/key" + + prefixedPath, err := commitment.ApplyPrefix(prefix, pathStr) + require.Nil(t, err, "valid prefix returns error") + + require.Equal(t, "/storePrefixKey/path1/path2/path3/key", prefixedPath.String(), "Prefixed path incorrect") + + // invalid prefix contains non-alphanumeric character + invalidPathStr := "invalid-path/doesitfail?/hopefully" + invalidPath, err := commitment.ApplyPrefix(prefix, invalidPathStr) + require.NotNil(t, err, "invalid prefix does not returns error") + require.Equal(t, commitment.Path{}, invalidPath, "invalid prefix returns valid Path on ApplyPrefix") +} diff --git a/x/ibc/23-commitment/types.go b/x/ibc/23-commitment/types.go new file mode 100644 index 000000000000..1b70f4f04d9c --- /dev/null +++ b/x/ibc/23-commitment/types.go @@ -0,0 +1,65 @@ +package commitment + +// ICS 023 Types Implementation +// +// This file includes types defined under +// https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments + +// spec:Path and spec:Value are defined as bytestring + +// RootI implements spec:CommitmentRoot. +// A root is constructed from a set of key-value pairs, +// and the inclusion or non-inclusion of an arbitrary key-value pair +// can be proven with the proof. +type RootI interface { + GetCommitmentType() Type + GetHash() []byte +} + +// PrefixI implements spec:CommitmentPrefix. +// Prefix represents the common "prefix" that a set of keys shares. +type PrefixI interface { + GetCommitmentType() Type + Bytes() []byte +} + +// PathI implements spec:CommitmentPath. +// A path is the additional information provided to the verification function. +type PathI interface { + GetCommitmentType() Type + String() string +} + +// ProofI implements spec:CommitmentProof. +// Proof can prove whether the key-value pair is a part of the Root or not. +// Each proof has designated key-value pair it is able to prove. +// Proofs includes key but value is provided dynamically at the verification time. +type ProofI interface { + GetCommitmentType() Type + VerifyMembership(RootI, PathI, []byte) bool + VerifyNonMembership(RootI, PathI) bool +} + +// Type defines the type of the commitment +type Type byte + +// Registered commitment types +const ( + Merkle Type = iota + 1 // 1 +) + +// string representation of the commitment types +const ( + TypeMerkle string = "merkle" +) + +// String implements the Stringer interface +func (ct Type) String() string { + switch ct { + case Merkle: + return TypeMerkle + + default: + return "" + } +} diff --git a/x/ibc/23-commitment/verify.go b/x/ibc/23-commitment/verify.go new file mode 100644 index 000000000000..7c620c2b5a90 --- /dev/null +++ b/x/ibc/23-commitment/verify.go @@ -0,0 +1,62 @@ +package commitment + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// CalculateRoot returns the application Hash at the curretn block height as a commitment +// root for proof verification. +func CalculateRoot(ctx sdk.Context) RootI { + return NewRoot(ctx.BlockHeader().AppHash) +} + +// BatchVerifyMembership verifies a proof that many paths have been set to +// specific values in a commitment. It calls the proof's VerifyMembership method +// with the calculated root and the provided paths. +// Returns false on the first failed membership verification. +func BatchVerifyMembership( + ctx sdk.Context, + proof ProofI, + prefix PrefixI, + items map[string][]byte, +) bool { + root := CalculateRoot(ctx) + + for pathStr, value := range items { + path, err := ApplyPrefix(prefix, pathStr) + if err != nil { + return false + } + + if ok := proof.VerifyMembership(root, path, value); !ok { + return false + } + } + + return true +} + +// BatchVerifyNonMembership verifies a proof that many paths have not been set +// to any value in a commitment. It calls the proof's VerifyNonMembership method +// with the calculated root and the provided paths. +// Returns false on the first failed non-membership verification. +func BatchVerifyNonMembership( + ctx sdk.Context, + proof ProofI, + prefix PrefixI, + paths []string, +) bool { + root := CalculateRoot(ctx) + for _, pathStr := range paths { + path, err := ApplyPrefix(prefix, pathStr) + if err != nil { + return false + } + + if ok := proof.VerifyNonMembership(root, path); !ok { + return false + } + } + + return true +} diff --git a/x/ibc/24-host/errors.go b/x/ibc/24-host/errors.go new file mode 100644 index 000000000000..afc1c26ea303 --- /dev/null +++ b/x/ibc/24-host/errors.go @@ -0,0 +1,19 @@ +package host + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// IBCCodeSpace is the codespace for all errors defined in the ibc module +const IBCCodeSpace = "ibc" + +var ( + // ErrInvalidID is returned if identifier string is invalid + ErrInvalidID = sdkerrors.Register(IBCCodeSpace, 1, "invalid identifier") + + // ErrInvalidPath is returned if path string is invalid + ErrInvalidPath = sdkerrors.Register(IBCCodeSpace, 2, "invalid path") + + // ErrInvalidPacket is returned if packets embedded in msg are invalid + ErrInvalidPacket = sdkerrors.Register(IBCCodeSpace, 3, "invalid packet extracted from msg") +) diff --git a/x/ibc/24-host/utils.go b/x/ibc/24-host/utils.go new file mode 100644 index 000000000000..c75f356561f6 --- /dev/null +++ b/x/ibc/24-host/utils.go @@ -0,0 +1,11 @@ +package host + +// RemovePath is an util function to remove a path from a set. +func RemovePath(paths []string, path string) ([]string, bool) { + for i, p := range paths { + if p == path { + return append(paths[:i], paths[i+1:]...), true + } + } + return paths, false +} diff --git a/x/ibc/24-host/validate.go b/x/ibc/24-host/validate.go new file mode 100644 index 000000000000..6632d27c25c1 --- /dev/null +++ b/x/ibc/24-host/validate.go @@ -0,0 +1,98 @@ +package host + +import ( + "regexp" + "strings" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// ICS 024 Identifier and Path Validation Implementation +// +// This file defines ValidateFn to validate identifier and path strings +// The spec for ICS 024 can be located here: +// https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements + +// regular expression to check string is lowercase alphabetic characters only +var isAlphaLower = regexp.MustCompile(`^[a-z]+$`).MatchString + +// regular expression to check string is alphanumeric +var isAlphaNumeric = regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString + +// ValidateFn function type to validate path and identifier bytestrings +type ValidateFn func(string) error + +func defaultIdentifierValidator(id string, min, max int) error { + // valid id MUST NOT contain "/" separator + if strings.Contains(id, "/") { + return sdkerrors.Wrap(ErrInvalidID, "identifier cannot contain separator: /") + } + // valid id must be between 10 and 20 characters + if len(id) < min || len(id) > max { + return sdkerrors.Wrapf(ErrInvalidID, "identifier has invalid length: %d, must be between %d-%d characters", len(id), min, max) + } + // valid id must contain only lower alphabetic characters + if !isAlphaLower(id) { + return sdkerrors.Wrap(ErrInvalidID, "identifier must contain only lowercase alphabetic characters") + } + return nil +} + +// DefaultClientIdentifierValidator is the default validator function for Client identifiers +// A valid Identifier must be between 10-20 characters and only contain lowercase +// alphabetic characters, +func DefaultClientIdentifierValidator(id string) error { + return defaultIdentifierValidator(id, 10, 20) +} + +// DefaultConnectionIdentifierValidator is the default validator function for Connection identifiers +// A valid Identifier must be between 10-20 characters and only contain lowercase +// alphabetic characters, +func DefaultConnectionIdentifierValidator(id string) error { + return defaultIdentifierValidator(id, 10, 20) +} + +// DefaultChannelIdentifierValidator is the default validator function for Channel identifiers +// A valid Identifier must be between 10-20 characters and only contain lowercase +// alphabetic characters, +func DefaultChannelIdentifierValidator(id string) error { + return defaultIdentifierValidator(id, 10, 20) +} + +// DefaultPortIdentifierValidator is the default validator function for Port identifiers +// A valid Identifier must be between 2-20 characters and only contain lowercase +// alphabetic characters, +func DefaultPortIdentifierValidator(id string) error { + return defaultIdentifierValidator(id, 2, 20) +} + +// NewPathValidator takes in a Identifier Validator function and returns +// a Path Validator function which requires path only has valid identifiers +// alphanumeric character strings, and "/" separators +func NewPathValidator(idValidator ValidateFn) ValidateFn { + return func(path string) error { + pathArr := strings.Split(path, "/") + for _, p := range pathArr { + // Each path element must either be valid identifier or alphanumeric + err := idValidator(p) + if err != nil && !isAlphaNumeric(p) { + return sdkerrors.Wrapf(ErrInvalidPath, "path contains invalid identifier or non-alphanumeric path element: %s", p) + } + } + return nil + } +} + +// DefaultPathValidator takes in path string and validates +// with default identifier rules. This is optimized by simply +// checking that all path elements are alphanumeric +func DefaultPathValidator(path string) error { + pathArr := strings.Split(path, "/") + for _, p := range pathArr { + // Each path element must either be alphanumeric + if !isAlphaNumeric(p) { + return sdkerrors.Wrapf(ErrInvalidPath, "invalid path element containing non-alphanumeric characters: %s", p) + } + } + return nil +} From ec747fc5ebbdc67bf601115907d1a86f80f411d5 Mon Sep 17 00:00:00 2001 From: Joon Date: Tue, 5 Nov 2019 08:56:38 -0800 Subject: [PATCH 003/176] ICS 02 Implementation (#4516) * add mapping * rm unused mapping/*, rm interfaces * rm unused code * mv mapping -> state, rm x/ibc * rm GetIfExists * add key * rm custom encoding/decoding in enum/bool * fix lint * rm tests * add commitment * newtyped remote values * newtyped context * revert context newtype * add README, keypath * reflect downstream ics * add merkle * add test for proving * soft coded root keypath * add update * remove RootUpdate * separate keypath and keuprefix * add codec * separate root/path * add path to codec * add client * add counterpartymanager * fix manager * add Is() to counterobject * add readme, reflect ICS02 revision * reflect downstream ics * test in progress * add test * in progres * fin rebase * in progress * fin rebase * add CLIObject in progress * cli in progress * add CLIObject * separate testing from tendermint * add key to node * add root and storekey to tests/node, add codec * rm cli/query.go * fix test * fix lint * fix lint * add handler/msgs/client * rm relay * finalize rebase on 23 root/path sep * fix lint, fix syntax * rm freebase, reformat query * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * add godoc in progress * reformat test * rm XXX * add godoc * modify store * add query * update query.go * update query.go * cli refactor in progress * cli refactor in progress * add Query to boolean.go * fix key * fix cli / merkle test * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * fix dependency * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * rm commented lines * address review in progress * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * add verification functions * ICS02 module.go * top level x/ibc structure * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling * start batch-verify tests * minor changes on commitment types * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * use testsuite * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes --- x/ibc/02-client/alias.go | 85 ++++++ x/ibc/02-client/client/cli/query.go | 258 ++++++++++++++++++ x/ibc/02-client/client/cli/tx.go | 172 ++++++++++++ x/ibc/02-client/client/utils/utils.go | 75 +++++ x/ibc/02-client/doc.go | 10 + x/ibc/02-client/exported/exported.go | 123 +++++++++ x/ibc/02-client/handler.go | 78 ++++++ x/ibc/02-client/keeper/client.go | 104 +++++++ x/ibc/02-client/keeper/keeper.go | 205 ++++++++++++++ x/ibc/02-client/keeper/querier.go | 77 ++++++ x/ibc/02-client/module.go | 32 +++ x/ibc/02-client/types/codec.go | 30 ++ x/ibc/02-client/types/errors/errors.go | 73 +++++ x/ibc/02-client/types/events.go | 21 ++ x/ibc/02-client/types/keys.go | 67 +++++ x/ibc/02-client/types/msgs.go | 173 ++++++++++++ x/ibc/02-client/types/msgs_test.go | 140 ++++++++++ x/ibc/02-client/types/querier.go | 66 +++++ x/ibc/02-client/types/state.go | 24 ++ x/ibc/02-client/types/tendermint/codec.go | 18 ++ .../types/tendermint/consensus_state.go | 89 ++++++ .../types/tendermint/consensus_state_test.go | 52 ++++ x/ibc/02-client/types/tendermint/doc.go | 5 + x/ibc/02-client/types/tendermint/header.go | 28 ++ .../types/tendermint/misbehaviour.go | 96 +++++++ .../types/tendermint/misbehaviour_test.go | 64 +++++ .../types/tendermint/tendermint_test.go | 87 ++++++ .../02-client/types/tendermint/test_utils.go | 47 ++++ x/ibc/24-host/errors.go | 5 +- x/ibc/alias.go | 29 ++ x/ibc/client/cli/cli.go | 43 +++ x/ibc/handler.go | 30 ++ x/ibc/keeper/keeper.go | 19 ++ x/ibc/keeper/querier.go | 24 ++ x/ibc/module.go | 131 +++++++++ x/ibc/types/types.go | 15 + x/ibc/version/version.go | 13 + 37 files changed, 2607 insertions(+), 1 deletion(-) create mode 100644 x/ibc/02-client/alias.go create mode 100644 x/ibc/02-client/client/cli/query.go create mode 100644 x/ibc/02-client/client/cli/tx.go create mode 100644 x/ibc/02-client/client/utils/utils.go create mode 100644 x/ibc/02-client/doc.go create mode 100644 x/ibc/02-client/exported/exported.go create mode 100644 x/ibc/02-client/handler.go create mode 100644 x/ibc/02-client/keeper/client.go create mode 100644 x/ibc/02-client/keeper/keeper.go create mode 100644 x/ibc/02-client/keeper/querier.go create mode 100644 x/ibc/02-client/module.go create mode 100644 x/ibc/02-client/types/codec.go create mode 100644 x/ibc/02-client/types/errors/errors.go create mode 100644 x/ibc/02-client/types/events.go create mode 100644 x/ibc/02-client/types/keys.go create mode 100644 x/ibc/02-client/types/msgs.go create mode 100644 x/ibc/02-client/types/msgs_test.go create mode 100644 x/ibc/02-client/types/querier.go create mode 100644 x/ibc/02-client/types/state.go create mode 100644 x/ibc/02-client/types/tendermint/codec.go create mode 100644 x/ibc/02-client/types/tendermint/consensus_state.go create mode 100644 x/ibc/02-client/types/tendermint/consensus_state_test.go create mode 100644 x/ibc/02-client/types/tendermint/doc.go create mode 100644 x/ibc/02-client/types/tendermint/header.go create mode 100644 x/ibc/02-client/types/tendermint/misbehaviour.go create mode 100644 x/ibc/02-client/types/tendermint/misbehaviour_test.go create mode 100644 x/ibc/02-client/types/tendermint/tendermint_test.go create mode 100644 x/ibc/02-client/types/tendermint/test_utils.go create mode 100644 x/ibc/alias.go create mode 100644 x/ibc/client/cli/cli.go create mode 100644 x/ibc/handler.go create mode 100644 x/ibc/keeper/keeper.go create mode 100644 x/ibc/keeper/querier.go create mode 100644 x/ibc/types/types.go create mode 100644 x/ibc/version/version.go diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go new file mode 100644 index 000000000000..00519d9da512 --- /dev/null +++ b/x/ibc/02-client/alias.go @@ -0,0 +1,85 @@ +package client + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/02-client/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" +) + +const ( + DefaultCodespace = errors.DefaultCodespace + CodeClientExists = errors.CodeClientExists + CodeClientNotFound = errors.CodeClientNotFound + CodeClientFrozen = errors.CodeClientFrozen + CodeConsensusStateNotFound = errors.CodeConsensusStateNotFound + CodeInvalidConsensusState = errors.CodeInvalidConsensusState + CodeClientTypeNotFound = errors.CodeClientTypeNotFound + CodeInvalidClientType = errors.CodeInvalidClientType + CodeRootNotFound = errors.CodeRootNotFound + CodeInvalidHeader = errors.CodeInvalidHeader + CodeInvalidEvidence = errors.CodeInvalidEvidence + AttributeKeyClientID = types.AttributeKeyClientID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryClientState = types.QueryClientState + QueryConsensusState = types.QueryConsensusState + QueryVerifiedRoot = types.QueryVerifiedRoot +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + QuerierClientState = keeper.QuerierClientState + QuerierConsensusState = keeper.QuerierConsensusState + QuerierVerifiedRoot = keeper.QuerierVerifiedRoot + RegisterCodec = types.RegisterCodec + ErrClientExists = errors.ErrClientExists + ErrClientNotFound = errors.ErrClientNotFound + ErrClientFrozen = errors.ErrClientFrozen + ErrConsensusStateNotFound = errors.ErrConsensusStateNotFound + ErrInvalidConsensus = errors.ErrInvalidConsensus + ErrClientTypeNotFound = errors.ErrClientTypeNotFound + ErrInvalidClientType = errors.ErrInvalidClientType + ErrRootNotFound = errors.ErrRootNotFound + ErrInvalidHeader = errors.ErrInvalidHeader + ErrInvalidEvidence = errors.ErrInvalidEvidence + ClientStatePath = types.ClientStatePath + ClientTypePath = types.ClientTypePath + ConsensusStatePath = types.ConsensusStatePath + RootPath = types.RootPath + KeyClientState = types.KeyClientState + KeyClientType = types.KeyClientType + KeyConsensusState = types.KeyConsensusState + KeyRoot = types.KeyRoot + NewMsgCreateClient = types.NewMsgCreateClient + NewMsgUpdateClient = types.NewMsgUpdateClient + NewMsgSubmitMisbehaviour = types.NewMsgSubmitMisbehaviour + NewQueryClientStateParams = types.NewQueryClientStateParams + NewQueryCommitmentRootParams = types.NewQueryCommitmentRootParams + NewClientState = types.NewClientState + + // variable aliases + SubModuleCdc = types.SubModuleCdc + EventTypeCreateClient = types.EventTypeCreateClient + EventTypeUpdateClient = types.EventTypeUpdateClient + EventTypeSubmitMisbehaviour = types.EventTypeSubmitMisbehaviour + AttributeValueCategory = types.AttributeValueCategory +) + +type ( + Keeper = keeper.Keeper + MsgCreateClient = types.MsgCreateClient + MsgUpdateClient = types.MsgUpdateClient + MsgSubmitMisbehaviour = types.MsgSubmitMisbehaviour + QueryClientStateParams = types.QueryClientStateParams + QueryCommitmentRootParams = types.QueryCommitmentRootParams + State = types.State +) diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go new file mode 100644 index 000000000000..6f6a487bbbf6 --- /dev/null +++ b/x/ibc/02-client/client/cli/query.go @@ -0,0 +1,258 @@ +package cli + +import ( + "errors" + "fmt" + "strconv" + "strings" + + "github.com/spf13/cobra" + + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// GetQueryCmd returns the query commands for IBC clients +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + ics02ClientQueryCmd := &cobra.Command{ + Use: "client", + Short: "IBC client query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics02ClientQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryConsensusState(queryRoute, cdc), + GetCmdQueryHeader(cdc), + GetCmdQueryClientState(queryRoute, cdc), + GetCmdQueryRoot(queryRoute, cdc), + GetCmdNodeConsensusState(queryRoute, cdc), + GetCmdQueryPath(queryRoute, cdc), + )...) + return ics02ClientQueryCmd +} + +// GetCmdQueryClientState defines the command to query the state of a client with +// a given id as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query +func GetCmdQueryClientState(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "state [client-id]", + Short: "Query a client state", + Long: strings.TrimSpace( + fmt.Sprintf(`Query stored client state + +Example: +$ %s query ibc client state [client-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + if strings.TrimSpace(clientID) == "" { + return errors.New("client ID can't be blank") + } + + bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) + if err != nil { + return err + } + + res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), bz) + if err != nil { + return err + } + + var clientState types.State + if err := cdc.UnmarshalJSON(res, &clientState); err != nil { + return err + } + + return cliCtx.PrintOutput(clientState) + }, + } +} + +// GetCmdQueryRoot defines the command to query +func GetCmdQueryRoot(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "root [client-id] [height]", + Short: "Query a verified commitment root", + Long: strings.TrimSpace( + fmt.Sprintf(`Query an already verified commitment root at a specific height for a particular client + +Example: +$ %s query ibc client root [client-id] [height] +`, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + if strings.TrimSpace(clientID) == "" { + return errors.New("client ID can't be blank") + } + + height, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return fmt.Errorf("expected integer height, got: %v", args[1]) + } + + bz, err := cdc.MarshalJSON(types.NewQueryCommitmentRootParams(clientID, height)) + if err != nil { + return err + } + + res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryVerifiedRoot), bz) + if err != nil { + return err + } + + var root commitment.RootI + if err := cdc.UnmarshalJSON(res, &root); err != nil { + return err + } + + return cliCtx.PrintOutput(root) + }, + } +} + +// GetCmdQueryConsensusState defines the command to query the consensus state of +// the chain as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query +func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "consensus-state [client-id]", + Short: "Query the latest consensus state of the client", + Long: strings.TrimSpace( + fmt.Sprintf(`Query the consensus state for a particular client + +Example: +$ %s query ibc client consensus-state [client-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + if strings.TrimSpace(clientID) == "" { + return errors.New("client ID can't be blank") + } + + bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) + if err != nil { + return err + } + + res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryConsensusState), bz) + if err != nil { + return err + } + + var consensusState exported.ConsensusState + if err := cdc.UnmarshalJSON(res, &consensusState); err != nil { + return err + } + + return cliCtx.PrintOutput(consensusState) + }, + } +} + +// GetCmdQueryHeader defines the command to query the latest header on the chain +func GetCmdQueryHeader(cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "header", + Short: "Query the latest header of the running chain", + Long: strings.TrimSpace(fmt.Sprintf(`Query the latest Tendermint header + +Example: +$ %s query ibc client header + `, version.ClientName), + ), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + + header, err := utils.GetTendermintHeader(cliCtx) + if err != nil { + return err + } + + return cliCtx.PrintOutput(header) + }, + } +} + +// GetCmdNodeConsensusState defines the command to query the latest consensus state of a node +// The result is feed to client creation +func GetCmdNodeConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "node-state", + Short: "Query a node consensus state", + Long: strings.TrimSpace( + fmt.Sprintf(`Query a node consensus state. This result is feed to the client creation transaction. + +Example: +$ %s query ibc client node-state + `, version.ClientName), + ), + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + + node, err := cliCtx.GetNode() + if err != nil { + return err + } + + info, err := node.ABCIInfo() + if err != nil { + return err + } + + height := info.Response.LastBlockHeight + prevHeight := height - 1 + + commit, err := node.Commit(&height) + if err != nil { + return err + } + + validators, err := node.Validators(&prevHeight) + if err != nil { + return err + } + + state := tendermint.ConsensusState{ + ChainID: commit.ChainID, + Height: uint64(commit.Height), + Root: commitment.NewRoot(commit.AppHash), + NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), + } + + return cliCtx.PrintOutput(state) + }, + } +} + +// GetCmdQueryPath defines the command to query the commitment path. +func GetCmdQueryPath(storeName string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "path", + Short: "Query the commitment path of the running chain", + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCLIContext().WithCodec(cdc) + path := commitment.NewPrefix([]byte("ibc")) + return ctx.PrintOutput(path) + }, + } +} diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go new file mode 100644 index 000000000000..4cbc97b39842 --- /dev/null +++ b/x/ibc/02-client/client/cli/tx.go @@ -0,0 +1,172 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" +) + +// GetTxCmd returns the transaction commands for IBC Clients +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics02ClientTxCmd := &cobra.Command{ + Use: "client", + Short: "Client transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics02ClientTxCmd.AddCommand(client.PostCommands( + GetCmdCreateClient(cdc), + GetCmdUpdateClient(cdc), + )...) + + return ics02ClientTxCmd +} + +// GetCmdCreateClient defines the command to create a new IBC Client as defined +// in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create +func GetCmdCreateClient(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "create [client-id] [path/to/consensus_state.json]", + Short: "create new client with a consensus state", + Long: strings.TrimSpace(fmt.Sprintf(`create new client with a specified identifier and consensus state: + +Example: +$ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node0 --home ../node0/cli --chain-id $CID + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + + clientID := args[0] + + var state exported.ConsensusState + if err := cdc.UnmarshalJSON([]byte(args[1]), &state); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + + contents, err := ioutil.ReadFile(args[1]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &state); err != nil { + return fmt.Errorf("error unmarshalling consensus state file: %v", err) + } + } + + msg := types.NewMsgCreateClient( + clientID, state.ClientType().String(), state, + cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdUpdateClient defines the command to update a client as defined in +// https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#update +func GetCmdUpdateClient(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "update [client-id] [path/to/header.json]", + Short: "update existing client with a header", + Long: strings.TrimSpace(fmt.Sprintf(`update existing client with a header: + +Example: +$ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home ../node0/cli --chain-id $CID + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + clientID := args[0] + + var header exported.Header + if err := cdc.UnmarshalJSON([]byte(args[1]), &header); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + + contents, err := ioutil.ReadFile(args[1]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &header); err != nil { + return fmt.Errorf("error unmarshalling header file: %v", err) + } + } + + msg := types.NewMsgUpdateClient(clientID, header, cliCtx.GetFromAddress()) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdSubmitMisbehaviour defines the command to submit a misbehaviour to invalidate +// previous state roots and prevent future updates as defined in +// https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#misbehaviour +func GetCmdSubmitMisbehaviour(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "misbehaviour [client-it] [path/to/evidence.json]", + Short: "submit a client misbehaviour", + Long: strings.TrimSpace(fmt.Sprintf(`submit a client misbehaviour to invalidate to invalidate previous state roots and prevent future updates: + +Example: +$ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 --home ../node0/cli --chain-id $CID + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + clientID := args[0] + + var evidence exported.Evidence + if err := cdc.UnmarshalJSON([]byte(args[1]), &evidence); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + + contents, err := ioutil.ReadFile(args[1]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &evidence); err != nil { + return fmt.Errorf("error unmarshalling evidence file: %v", err) + } + } + + msg := types.NewMsgSubmitMisbehaviour(clientID, evidence, cliCtx.GetFromAddress()) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go new file mode 100644 index 000000000000..5d0786267373 --- /dev/null +++ b/x/ibc/02-client/client/utils/utils.go @@ -0,0 +1,75 @@ +package utils + +import ( + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" +) + +// QueryConsensusStateProof queries the store to get the consensus state and a +// merkle proof. +func QueryConsensusStateProof(cliCtx client.CLIContext, clientID string) (types.ConsensusStateResponse, error) { + var conStateRes types.ConsensusStateResponse + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: []byte(fmt.Sprintf("clients/%s/consensusState", clientID)), + Prove: true, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return conStateRes, err + } + + var cs tendermint.ConsensusState + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { + return conStateRes, err + } + return types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height), nil +} + +// GetTendermintHeader takes a client context and returns the appropriate +// tendermint header +func GetTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, error) { + node, err := cliCtx.GetNode() + if err != nil { + return tendermint.Header{}, err + } + + info, err := node.ABCIInfo() + if err != nil { + return tendermint.Header{}, err + } + + height := info.Response.LastBlockHeight + prevheight := height - 1 + + commit, err := node.Commit(&height) + if err != nil { + return tendermint.Header{}, err + } + + validators, err := node.Validators(&prevheight) + if err != nil { + return tendermint.Header{}, err + } + + nextvalidators, err := node.Validators(&height) + if err != nil { + return tendermint.Header{}, err + } + + header := tendermint.Header{ + SignedHeader: commit.SignedHeader, + ValidatorSet: tmtypes.NewValidatorSet(validators.Validators), + NextValidatorSet: tmtypes.NewValidatorSet(nextvalidators.Validators), + } + + return header, nil +} diff --git a/x/ibc/02-client/doc.go b/x/ibc/02-client/doc.go new file mode 100644 index 000000000000..2b6952ba97eb --- /dev/null +++ b/x/ibc/02-client/doc.go @@ -0,0 +1,10 @@ +/* +Package client implements the ICS 02 - Client Semenatics specification +https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics. This +concrete implementations defines types and method to store and update light +clients which tracks on other chain's state. + +The main type is `Client`, which provides `commitment.Root` to verify state proofs and `ConsensusState` to +verify header proofs. +*/ +package client diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go new file mode 100644 index 000000000000..e7d1ac5c5411 --- /dev/null +++ b/x/ibc/02-client/exported/exported.go @@ -0,0 +1,123 @@ +package exported + +import ( + "encoding/json" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + cmn "github.com/tendermint/tendermint/libs/common" +) + +// Blockchain is consensus algorithm which generates valid Headers. It generates +// a unique list of headers starting from a genesis ConsensusState with arbitrary messages. +// This interface is implemented as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#blockchain. +type Blockchain interface { + Genesis() ConsensusState // Consensus state defined in the genesis + Consensus() Header // Header generating function +} + +// ConsensusState is the state of the consensus process +type ConsensusState interface { + ClientType() ClientType // Consensus kind + GetHeight() uint64 + + // GetRoot returns the commitment root of the consensus state, + // which is used for key-value pair verification. + GetRoot() commitment.RootI + + // CheckValidityAndUpdateState returns the updated consensus state + // only if the header is a descendent of this consensus state. + CheckValidityAndUpdateState(Header) (ConsensusState, error) +} + +// Evidence from ADR 009: Evidence Module +// TODO: use evidence module interface once merged +type Evidence interface { + Route() string + Type() string + String() string + Hash() cmn.HexBytes + ValidateBasic() sdk.Error + + // The consensus address of the malicious validator at time of infraction + GetConsensusAddress() sdk.ConsAddress + + // Height at which the infraction occurred + GetHeight() int64 + + // The total power of the malicious validator at time of infraction + GetValidatorPower() int64 + + // The total validator set power at time of infraction + GetTotalPower() int64 +} + +// Misbehaviour defines a specific consensus kind and an evidence +type Misbehaviour interface { + ClientType() ClientType + Evidence() Evidence +} + +// Header is the consensus state update information +type Header interface { + ClientType() ClientType + GetHeight() uint64 +} + +// ClientType defines the type of the consensus algorithm +type ClientType byte + +// available client types +const ( + Tendermint ClientType = iota + 1 // 1 +) + +// string representation of the client types +const ( + ClientTypeTendermint string = "tendermint" +) + +func (ct ClientType) String() string { + switch ct { + case Tendermint: + return ClientTypeTendermint + default: + return "" + } +} + +// MarshalJSON marshal to JSON using string. +func (ct ClientType) MarshalJSON() ([]byte, error) { + return json.Marshal(ct.String()) +} + +// UnmarshalJSON decodes from JSON. +func (ct *ClientType) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + bz2, err := ClientTypeFromString(s) + if err != nil { + return err + } + + *ct = bz2 + return nil +} + +// ClientTypeFromString returns a byte that corresponds to the registered client +// type. It returns 0 if the type is not found/registered. +func ClientTypeFromString(clientType string) (ClientType, error) { + switch clientType { + case ClientTypeTendermint: + return Tendermint, nil + + default: + return 0, fmt.Errorf("'%s' is not a valid client type", clientType) + } +} diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go new file mode 100644 index 000000000000..1b1e1807b54a --- /dev/null +++ b/x/ibc/02-client/handler.go @@ -0,0 +1,78 @@ +package client + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + exported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" +) + +// HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient +func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.Result { + clientType, err := exported.ClientTypeFromString(msg.ClientType) + if err != nil { + return sdk.ResultFromError(ErrInvalidClientType(DefaultCodespace, err.Error())) + } + + // TODO: should we create an event with the new client state id ? + _, err = k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + EventTypeCreateClient, + sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgUpdateClient defines the sdk.Handler for MsgUpdateClient +func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) sdk.Result { + err := k.UpdateClient(ctx, msg.ClientID, msg.Header) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + EventTypeUpdateClient, + sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgSubmitMisbehaviour defines the sdk.Handler for MsgSubmitMisbehaviour +func HandleMsgSubmitMisbehaviour(ctx sdk.Context, k Keeper, msg MsgSubmitMisbehaviour) sdk.Result { + err := k.CheckMisbehaviourAndUpdateState(ctx, msg.ClientID, msg.Evidence) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + EventTypeSubmitMisbehaviour, + sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go new file mode 100644 index 000000000000..b75f8174939a --- /dev/null +++ b/x/ibc/02-client/keeper/client.go @@ -0,0 +1,104 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" +) + +// CreateClient creates a new client state and populates it with a given consensus +// state as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create +func (k Keeper) CreateClient( + ctx sdk.Context, clientID string, + clientType exported.ClientType, consensusState exported.ConsensusState, +) (types.State, error) { + _, found := k.GetClientState(ctx, clientID) + if found { + return types.State{}, errors.ErrClientExists(k.codespace, clientID) + } + + _, found = k.GetClientType(ctx, clientID) + if found { + panic(fmt.Sprintf("consensus type is already defined for client %s", clientID)) + } + + clientState := k.initialize(ctx, clientID, consensusState) + k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) + k.SetClientState(ctx, clientState) + k.SetClientType(ctx, clientID, clientType) + k.Logger(ctx).Info(fmt.Sprintf("client %s created at height %d", clientID, consensusState.GetHeight())) + return clientState, nil +} + +// UpdateClient updates the consensus state and the state root from a provided header +func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) error { + clientType, found := k.GetClientType(ctx, clientID) + if !found { + return sdkerrors.Wrap(errors.ErrClientTypeNotFound(k.codespace), "cannot update client") + } + + // check that the header consensus matches the client one + if header.ClientType() != clientType { + return sdkerrors.Wrap(errors.ErrInvalidConsensus(k.codespace), "cannot update client") + } + + clientState, found := k.GetClientState(ctx, clientID) + if !found { + return sdkerrors.Wrap(errors.ErrClientNotFound(k.codespace, clientID), "cannot update client") + } + + if clientState.Frozen { + return sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientID), "cannot update client") + } + + consensusState, found := k.GetConsensusState(ctx, clientID) + if !found { + return sdkerrors.Wrap(errors.ErrConsensusStateNotFound(k.codespace), "cannot update client") + } + + if header.GetHeight() < consensusState.GetHeight() { + return sdkerrors.Wrap( + sdk.ErrInvalidSequence( + fmt.Sprintf("header height < consensus height (%d < %d)", header.GetHeight(), consensusState.GetHeight()), + ), + "cannot update client", + ) + } + + consensusState, err := consensusState.CheckValidityAndUpdateState(header) + if err != nil { + return sdkerrors.Wrap(err, "cannot update client") + } + + k.SetConsensusState(ctx, clientID, consensusState) + k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) + k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, consensusState.GetHeight())) + return nil +} + +// CheckMisbehaviourAndUpdateState checks for client misbehaviour and freezes the +// client if so. +func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, clientID string, evidence exported.Evidence) error { + clientState, found := k.GetClientState(ctx, clientID) + if !found { + sdk.ResultFromError(errors.ErrClientNotFound(k.codespace, clientID)) + } + + err := k.checkMisbehaviour(ctx, evidence) + if err != nil { + return err + } + + clientState, err = k.freeze(ctx, clientState) + if err != nil { + return err + } + + k.SetClientState(ctx, clientState) + k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", clientID)) + return nil +} diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go new file mode 100644 index 000000000000..ce0d54e99782 --- /dev/null +++ b/x/ibc/02-client/keeper/keeper.go @@ -0,0 +1,205 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// Keeper represents a type that grants read and write permissions to any client +// state information +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store +} + +// NewKeeper creates a new NewKeeper instance +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, errors.DefaultCodespace)), // "ibc/client", + prefix: []byte{}, + // prefix: []byte(types.SubModuleName + "/"), // "client/" + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName)) +} + +// GetClientState gets a particular client from the store +func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyClientState(clientID)) + if bz == nil { + return types.State{}, false + } + + var clientState types.State + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &clientState) + return clientState, true +} + +// SetClientState sets a particular Client to the store +func (k Keeper) SetClientState(ctx sdk.Context, clientState types.State) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(clientState) + store.Set(types.KeyClientState(clientState.ID()), bz) +} + +// GetClientType gets the consensus type for a specific client +func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.ClientType, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyClientType(clientID)) + if bz == nil { + return 0, false + } + + return exported.ClientType(bz[0]), true +} + +// SetClientType sets the specific client consensus type to the provable store +func (k Keeper) SetClientType(ctx sdk.Context, clientID string, clientType exported.ClientType) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Set(types.KeyClientType(clientID), []byte{byte(clientType)}) +} + +// GetConsensusState creates a new client state and populates it with a given consensus state +func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.ConsensusState, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyConsensusState(clientID)) + if bz == nil { + return nil, false + } + + var consensusState exported.ConsensusState + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &consensusState) + return consensusState, true +} + +// SetConsensusState sets a ConsensusState to a particular client +func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) + store.Set(types.KeyConsensusState(clientID), bz) +} + +// GetVerifiedRoot gets a verified commitment Root from a particular height to +// a client +func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) (commitment.RootI, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + + bz := store.Get(types.KeyRoot(clientID, height)) + if bz == nil { + return nil, false + } + + var root commitment.RootI + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &root) + return root, true +} + +// SetVerifiedRoot sets a verified commitment Root from a particular height to +// a client +func (k Keeper) SetVerifiedRoot(ctx sdk.Context, clientID string, height uint64, root commitment.RootI) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(root) + store.Set(types.KeyRoot(clientID, height), bz) +} + +// State returns a new client state with a given id as defined in +// https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#example-implementation +func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) types.State { + clientState := types.NewClientState(clientID) + k.SetConsensusState(ctx, clientID, consensusState) + return clientState +} + +func (k Keeper) checkMisbehaviour(ctx sdk.Context, evidence exported.Evidence) error { + switch evidence.Type() { + case exported.ClientTypeTendermint: + var tmEvidence tendermint.Evidence + _, ok := evidence.(tendermint.Evidence) + if !ok { + return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint") + } + err := tendermint.CheckMisbehaviour(tmEvidence) + if err != nil { + return errors.ErrInvalidEvidence(k.codespace, err.Error()) + } + default: + panic(fmt.Sprintf("unregistered evidence type: %s", evidence.Type())) + } + return nil +} + +// freeze updates the state of the client in the event of a misbehaviour +func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) { + if clientState.Frozen { + return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientState.ID()), "already frozen") + } + + clientState.Frozen = true + return clientState, nil +} + +// VerifyMembership state membership verification function defined by the client type +func (k Keeper) VerifyMembership( + ctx sdk.Context, + clientID string, + height uint64, // sequence + proof commitment.ProofI, + path commitment.PathI, + value []byte, +) bool { + // XXX: commented out for demo + /* + if clientState.Frozen { + return false + } + */ + + root, found := k.GetVerifiedRoot(ctx, clientID, height) + if !found { + return false + } + + return proof.VerifyMembership(root, path, value) +} + +// VerifyNonMembership state non-membership function defined by the client type +func (k Keeper) VerifyNonMembership( + ctx sdk.Context, + clientID string, + height uint64, // sequence + proof commitment.ProofI, + path commitment.PathI, +) bool { + // XXX: commented out for demo + /* + if clientState.Frozen { + return false + } + */ + root, found := k.GetVerifiedRoot(ctx, clientID, height) + if !found { + return false + } + + return proof.VerifyNonMembership(root, path) +} diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go new file mode 100644 index 000000000000..5f56b8d6b01a --- /dev/null +++ b/x/ibc/02-client/keeper/querier.go @@ -0,0 +1,77 @@ +package keeper + +import ( + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" +) + +// QuerierClientState defines the sdk.Querier to query the IBC client state +func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryClientStateParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + clientState, found := k.GetClientState(ctx, params.ClientID) + if !found { + return nil, errors.ErrClientTypeNotFound(k.codespace) + } + + bz, err := types.SubModuleCdc.MarshalJSON(clientState) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} + +// QuerierConsensusState defines the sdk.Querier to query a consensus state +func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryClientStateParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + consensusState, found := k.GetConsensusState(ctx, params.ClientID) + if !found { + return nil, errors.ErrConsensusStateNotFound(k.codespace) + } + + bz, err := types.SubModuleCdc.MarshalJSON(consensusState) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} + +// QuerierVerifiedRoot defines the sdk.Querier to query a verified commitment root +func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryCommitmentRootParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + root, found := k.GetVerifiedRoot(ctx, params.ClientID, params.Height) + if !found { + return nil, errors.ErrRootNotFound(k.codespace) + } + + bz, err := types.SubModuleCdc.MarshalJSON(root) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} diff --git a/x/ibc/02-client/module.go b/x/ibc/02-client/module.go new file mode 100644 index 000000000000..3df05cdfbdf2 --- /dev/null +++ b/x/ibc/02-client/module.go @@ -0,0 +1,32 @@ +package client + +import ( + "fmt" + + "github.com/gorilla/mux" + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/cli" +) + +// Name returns the IBC client name +func Name() string { + return SubModuleName +} + +// RegisterRESTRoutes registers the REST routes for the IBC client +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { + // TODO: +} + +// GetTxCmd returns the root tx command for the IBC client +func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + return cli.GetTxCmd(fmt.Sprintf("%s/%s", storeKey, SubModuleName), cdc) +} + +// GetQueryCmd returns no root query command for the IBC client +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + return cli.GetQueryCmd(fmt.Sprintf("%s/%s", queryRoute, SubModuleName), cdc) +} diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go new file mode 100644 index 000000000000..7a141e811a0a --- /dev/null +++ b/x/ibc/02-client/types/codec.go @@ -0,0 +1,30 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" +) + +// SubModuleCdc defines the IBC client codec. +var SubModuleCdc = codec.New() + +// RegisterCodec registers the IBC client interfaces and types +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*exported.Blockchain)(nil), nil) + cdc.RegisterInterface((*exported.ConsensusState)(nil), nil) + cdc.RegisterInterface((*exported.Evidence)(nil), nil) + cdc.RegisterInterface((*exported.Header)(nil), nil) + cdc.RegisterInterface((*exported.Misbehaviour)(nil), nil) + + cdc.RegisterConcrete(MsgCreateClient{}, "ibc/client/MsgCreateClient", nil) + cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) + + cdc.RegisterConcrete(tendermint.ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) + cdc.RegisterConcrete(tendermint.Header{}, "ibc/client/tendermint/Header", nil) + cdc.RegisterConcrete(tendermint.Evidence{}, "ibc/client/tendermint/Evidence", nil) +} + +func init() { + RegisterCodec(SubModuleCdc) +} diff --git a/x/ibc/02-client/types/errors/errors.go b/x/ibc/02-client/types/errors/errors.go new file mode 100644 index 000000000000..c133bcfef808 --- /dev/null +++ b/x/ibc/02-client/types/errors/errors.go @@ -0,0 +1,73 @@ +package errors + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// client error codes +const ( + DefaultCodespace sdk.CodespaceType = "client" + + CodeClientExists sdk.CodeType = 101 + CodeClientNotFound sdk.CodeType = 102 + CodeClientFrozen sdk.CodeType = 103 + CodeConsensusStateNotFound sdk.CodeType = 104 + CodeInvalidConsensusState sdk.CodeType = 105 + CodeClientTypeNotFound sdk.CodeType = 106 + CodeInvalidClientType sdk.CodeType = 107 + CodeRootNotFound sdk.CodeType = 108 + CodeInvalidHeader sdk.CodeType = 109 + CodeInvalidEvidence sdk.CodeType = 110 +) + +// ErrClientExists implements sdk.Error +func ErrClientExists(codespace sdk.CodespaceType, clientID string) sdk.Error { + return sdk.NewError(codespace, CodeClientExists, fmt.Sprintf("client with ID %s already exists", clientID)) +} + +// ErrClientNotFound implements sdk.Error +func ErrClientNotFound(codespace sdk.CodespaceType, clientID string) sdk.Error { + return sdk.NewError(codespace, CodeClientNotFound, fmt.Sprintf("client with ID %s not found", clientID)) +} + +// ErrClientFrozen implements sdk.Error +func ErrClientFrozen(codespace sdk.CodespaceType, clientID string) sdk.Error { + return sdk.NewError(codespace, CodeClientFrozen, fmt.Sprintf("client with ID %s is frozen due to misbehaviour", clientID)) +} + +// ErrConsensusStateNotFound implements sdk.Error +func ErrConsensusStateNotFound(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeConsensusStateNotFound, "consensus state not found") +} + +// ErrInvalidConsensus implements sdk.Error +func ErrInvalidConsensus(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidConsensusState, "invalid consensus state") +} + +// ErrClientTypeNotFound implements sdk.Error +func ErrClientTypeNotFound(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeClientTypeNotFound, "client type not found") +} + +// ErrInvalidClientType implements sdk.Error +func ErrInvalidClientType(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidClientType, msg) +} + +// ErrRootNotFound implements sdk.Error +func ErrRootNotFound(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeRootNotFound, "commitment root not found") +} + +// ErrInvalidHeader implements sdk.Error +func ErrInvalidHeader(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidHeader, "invalid header") +} + +// ErrInvalidEvidence implements sdk.Error +func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidEvidence, "invalid evidence: %s", msg) +} diff --git a/x/ibc/02-client/types/events.go b/x/ibc/02-client/types/events.go new file mode 100644 index 000000000000..7e7f9a508cee --- /dev/null +++ b/x/ibc/02-client/types/events.go @@ -0,0 +1,21 @@ +package types + +import ( + "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// IBC client events +const ( + AttributeKeyClientID = "client_id" +) + +// IBC client events vars +var ( + EventTypeCreateClient = MsgCreateClient{}.Type() + EventTypeUpdateClient = MsgUpdateClient{}.Type() + EventTypeSubmitMisbehaviour = MsgSubmitMisbehaviour{}.Type() + + AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) +) diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go new file mode 100644 index 000000000000..8d97ca893324 --- /dev/null +++ b/x/ibc/02-client/types/keys.go @@ -0,0 +1,67 @@ +package types + +import ( + "fmt" +) + +const ( + // SubModuleName defines the IBC client name + SubModuleName = "client" + + // StoreKey is the store key string for IBC client + StoreKey = SubModuleName + + // RouterKey is the message route for IBC client + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC client + QuerierRoute = SubModuleName +) + +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space + +// ClientStatePath takes an Identifier and returns a Path under which to store a +// particular client state +func ClientStatePath(clientID string) string { + return fmt.Sprintf("clients/%s/state", clientID) +} + +// ClientTypePath takes an Identifier and returns Path under which to store the +// type of a particular client. +func ClientTypePath(clientID string) string { + return fmt.Sprintf("clients/%s/type", clientID) +} + +// ConsensusStatePath takes an Identifier and returns a Path under which to +// store the consensus state of a client. +func ConsensusStatePath(clientID string) string { + return fmt.Sprintf("clients/%s/consensusState", clientID) +} + +// RootPath takes an Identifier and returns a Path under which to +// store the consensus state of a client. +func RootPath(clientID string, height uint64) string { + return fmt.Sprintf("clients/%s/roots/%d", clientID, height) +} + +// KeyClientState returns the store key for a particular client state +func KeyClientState(clientID string) []byte { + return []byte(ClientStatePath(clientID)) +} + +// KeyClientType returns the store key for type of a particular client +func KeyClientType(clientID string) []byte { + return []byte(ClientTypePath(clientID)) +} + +// KeyConsensusState returns the store key for the consensus state of a particular +// client +func KeyConsensusState(clientID string) []byte { + return []byte(ConsensusStatePath(clientID)) +} + +// KeyRoot returns the store key for a commitment root of a particular +// client at a given height +func KeyRoot(clientID string, height uint64) []byte { + return []byte(RootPath(clientID, height)) +} diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go new file mode 100644 index 000000000000..612f7e543e53 --- /dev/null +++ b/x/ibc/02-client/types/msgs.go @@ -0,0 +1,173 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +var _ sdk.Msg = MsgCreateClient{} + +// MsgCreateClient defines a message to create an IBC client +type MsgCreateClient struct { + ClientID string `json:"client_id" yaml:"client_id"` + ClientType string `json:"client_type" yaml:"client_type"` + ConsensusState exported.ConsensusState `json:"consensus_state" yaml:"consensus_address"` + Signer sdk.AccAddress `json:"address" yaml:"address"` +} + +// NewMsgCreateClient creates a new MsgCreateClient instance +func NewMsgCreateClient(id, clientType string, consensusState exported.ConsensusState, signer sdk.AccAddress) MsgCreateClient { + return MsgCreateClient{ + ClientID: id, + ClientType: clientType, + ConsensusState: consensusState, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgCreateClient) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgCreateClient) Type() string { + return "create_client" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgCreateClient) ValidateBasic() sdk.Error { + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if _, err := exported.ClientTypeFromString(msg.ClientType); err != nil { + return errors.ErrInvalidClientType(errors.DefaultCodespace, err.Error()) + } + if msg.ConsensusState == nil { + return errors.ErrInvalidConsensus(errors.DefaultCodespace) + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("empty address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgCreateClient) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgCreateClient) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgUpdateClient{} + +// MsgUpdateClient defines a message to update an IBC client +type MsgUpdateClient struct { + ClientID string `json:"client_id" yaml:"client_id"` + Header exported.Header `json:"header" yaml:"header"` + Signer sdk.AccAddress `json:"address" yaml:"address"` +} + +// NewMsgUpdateClient creates a new MsgUpdateClient instance +func NewMsgUpdateClient(id string, header exported.Header, signer sdk.AccAddress) MsgUpdateClient { + return MsgUpdateClient{ + ClientID: id, + Header: header, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgUpdateClient) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgUpdateClient) Type() string { + return "update_client" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgUpdateClient) ValidateBasic() sdk.Error { + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if msg.Header == nil { + return errors.ErrInvalidHeader(errors.DefaultCodespace) + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("empty address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgUpdateClient) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +// MsgSubmitMisbehaviour defines a message to update an IBC client +type MsgSubmitMisbehaviour struct { + ClientID string `json:"id" yaml:"id"` + Evidence exported.Evidence `json:"evidence" yaml:"evidence"` + Signer sdk.AccAddress `json:"address" yaml:"address"` +} + +// NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance +func NewMsgSubmitMisbehaviour(id string, evidence exported.Evidence, signer sdk.AccAddress) MsgSubmitMisbehaviour { + return MsgSubmitMisbehaviour{ + ClientID: id, + Evidence: evidence, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgSubmitMisbehaviour) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgSubmitMisbehaviour) Type() string { + return "submit_misbehaviour" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgSubmitMisbehaviour) ValidateBasic() sdk.Error { + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if msg.Evidence == nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "evidence is nil") + } + if err := msg.Evidence.ValidateBasic(); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error()) + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("empty address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgSubmitMisbehaviour) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgSubmitMisbehaviour) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go new file mode 100644 index 000000000000..cd416fabdfe8 --- /dev/null +++ b/x/ibc/02-client/types/msgs_test.go @@ -0,0 +1,140 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + "github.com/tendermint/tendermint/crypto/secp256k1" + cmn "github.com/tendermint/tendermint/libs/common" +) + +func TestMsgCreateClientValidateBasic(t *testing.T) { + cs := tendermint.ConsensusState{} + privKey := secp256k1.GenPrivKey() + signer := sdk.AccAddress(privKey.PubKey().Address()) + testMsgs := []MsgCreateClient{ + NewMsgCreateClient(exported.ClientTypeTendermint, exported.ClientTypeTendermint, cs, signer), // valid msg + NewMsgCreateClient("badClient", exported.ClientTypeTendermint, cs, signer), // invalid client id + NewMsgCreateClient("goodChain", "bad_type", cs, signer), // invalid client type + NewMsgCreateClient("goodChain", exported.ClientTypeTendermint, nil, signer), // nil Consensus State + NewMsgCreateClient("goodChain", exported.ClientTypeTendermint, cs, sdk.AccAddress{}), // empty signer + } + + cases := []struct { + msg MsgCreateClient + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "invalid client id passed"}, + {testMsgs[2], false, "unregistered client type passed"}, + {testMsgs[3], false, "Nil Consensus State in msg passed"}, + {testMsgs[4], false, "Empty address passed"}, + } + + for i, tc := range cases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +func TestMsgUpdateClient(t *testing.T) { + privKey := secp256k1.GenPrivKey() + signer := sdk.AccAddress(privKey.PubKey().Address()) + testMsgs := []MsgUpdateClient{ + NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, signer), // valid msg + NewMsgUpdateClient("badClient", tendermint.Header{}, signer), // bad client id + NewMsgUpdateClient(exported.ClientTypeTendermint, nil, signer), // nil Header + NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, sdk.AccAddress{}), // empty address + } + + cases := []struct { + msg MsgUpdateClient + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "invalid client id passed"}, + {testMsgs[2], false, "Nil Header passed"}, + {testMsgs[3], false, "Empty address passed"}, + } + + for i, tc := range cases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +var _ exported.Evidence = mockEvidence{} + +const mockStr = "mock" + +// mock GoodEvidence +type mockEvidence struct{} + +// Implement Evidence interface +func (me mockEvidence) Route() string { return mockStr } +func (me mockEvidence) Type() string { return mockStr } +func (me mockEvidence) String() string { return mockStr } +func (me mockEvidence) Hash() cmn.HexBytes { return cmn.HexBytes([]byte(mockStr)) } +func (me mockEvidence) ValidateBasic() sdk.Error { return nil } +func (me mockEvidence) GetConsensusAddress() sdk.ConsAddress { return sdk.ConsAddress{} } +func (me mockEvidence) GetHeight() int64 { return 3 } +func (me mockEvidence) GetValidatorPower() int64 { return 3 } +func (me mockEvidence) GetTotalPower() int64 { return 5 } + +// mock bad evidence +type mockBadEvidence struct { + mockEvidence +} + +// Override ValidateBasic +func (mbe mockBadEvidence) ValidateBasic() sdk.Error { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence") +} + +func TestMsgSubmitMisbehaviour(t *testing.T) { + privKey := secp256k1.GenPrivKey() + signer := sdk.AccAddress(privKey.PubKey().Address()) + testMsgs := []MsgSubmitMisbehaviour{ + NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, mockEvidence{}, signer), // valid msg + NewMsgSubmitMisbehaviour("badClient", mockEvidence{}, signer), // bad client id + NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, nil, signer), // nil evidence + NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, mockBadEvidence{}, signer), // invalid evidence + NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, mockEvidence{}, sdk.AccAddress{}), // empty signer + } + + cases := []struct { + msg MsgSubmitMisbehaviour + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "invalid client id passed"}, + {testMsgs[2], false, "Nil Evidence passed"}, + {testMsgs[3], false, "Invalid Evidence passed"}, + {testMsgs[4], false, "Empty address passed"}, + } + + for i, tc := range cases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go new file mode 100644 index 000000000000..7638c0200882 --- /dev/null +++ b/x/ibc/02-client/types/querier.go @@ -0,0 +1,66 @@ +package types + +import ( + "strings" + + tmtypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/tendermint/tendermint/crypto/merkle" +) + +// query routes supported by the IBC client Querier +const ( + QueryClientState = "client_state" + QueryConsensusState = "consensus_state" + QueryVerifiedRoot = "roots" +) + +// QueryClientStateParams defines the params for the following queries: +// - 'custom/ibc/clients//client_state' +// - 'custom/ibc/clients//consensus_state' +type QueryClientStateParams struct { + ClientID string +} + +// NewQueryClientStateParams creates a new QueryClientStateParams instance +func NewQueryClientStateParams(id string) QueryClientStateParams { + return QueryClientStateParams{ + ClientID: id, + } +} + +// QueryCommitmentRootParams defines the params for the following queries: +// - 'custom/ibc/clients//roots/' +type QueryCommitmentRootParams struct { + ClientID string + Height uint64 +} + +// NewQueryCommitmentRootParams creates a new QueryCommitmentRootParams instance +func NewQueryCommitmentRootParams(id string, height uint64) QueryCommitmentRootParams { + return QueryCommitmentRootParams{ + ClientID: id, + Height: height, + } +} + +// ConsensusStateResponse defines the client response for a Consensus state query. +// It includes the commitment proof and the height of the proof. +type ConsensusStateResponse struct { + ConsensusState tmtypes.ConsensusState + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewConsensusStateResponse creates a new ConsensusStateResponse instance. +func NewConsensusStateResponse( + clientID string, cs tmtypes.ConsensusState, proof *merkle.Proof, height int64, +) ConsensusStateResponse { + return ConsensusStateResponse{ + ConsensusState: cs, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ConsensusStatePath(clientID), "/")), + ProofHeight: uint64(height), + } +} diff --git a/x/ibc/02-client/types/state.go b/x/ibc/02-client/types/state.go new file mode 100644 index 000000000000..8c60260df0a2 --- /dev/null +++ b/x/ibc/02-client/types/state.go @@ -0,0 +1,24 @@ +package types + +// State is a type that represents the state of a client. +// Any actor holding the Stage can access on and modify that client information. +type State struct { + // Client ID + id string + // Boolean that states if the client is frozen when a misbehaviour proof is + // submitted in the event of an equivocation. + Frozen bool `json:"frozen" yaml:"frozen"` +} + +// NewClientState creates a new ClientState instance +func NewClientState(id string) State { + return State{ + id: id, + Frozen: false, + } +} + +// ID returns the client identifier +func (s State) ID() string { + return s.id +} diff --git a/x/ibc/02-client/types/tendermint/codec.go b/x/ibc/02-client/types/tendermint/codec.go new file mode 100644 index 000000000000..46814fec2479 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/codec.go @@ -0,0 +1,18 @@ +package tendermint + +import ( + "github.com/cosmos/cosmos-sdk/codec" +) + +var SubModuleCdc = codec.New() + +// RegisterCodec registers the Tendermint types +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterConcrete(ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) + cdc.RegisterConcrete(Header{}, "ibc/client/tendermint/Header", nil) + cdc.RegisterConcrete(Evidence{}, "ibc/client/tendermint/Evidence", nil) +} + +func init() { + RegisterCodec(SubModuleCdc) +} diff --git a/x/ibc/02-client/types/tendermint/consensus_state.go b/x/ibc/02-client/types/tendermint/consensus_state.go new file mode 100644 index 000000000000..3ad0892a9ea8 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/consensus_state.go @@ -0,0 +1,89 @@ +package tendermint + +import ( + "bytes" + "errors" + + lerr "github.com/tendermint/tendermint/lite/errors" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +var _ exported.ConsensusState = ConsensusState{} + +// ConsensusState defines a Tendermint consensus state +type ConsensusState struct { + ChainID string `json:"chain_id" yaml:"chain_id"` + Height uint64 `json:"height" yaml:"height"` // NOTE: defined as 'sequence' in the spec + Root commitment.RootI `json:"root" yaml:"root"` + NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` // contains the PublicKey +} + +// ClientType returns Tendermint +func (ConsensusState) ClientType() exported.ClientType { + return exported.Tendermint +} + +// GetHeight returns the ConsensusState height +func (cs ConsensusState) GetHeight() uint64 { + return cs.Height +} + +// GetRoot returns the commitment Root for the specific +func (cs ConsensusState) GetRoot() commitment.RootI { + return cs.Root +} + +// CheckValidityAndUpdateState checks if the provided header is valid and updates +// the consensus state if appropriate +func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (exported.ConsensusState, error) { + tmHeader, ok := header.(Header) + if !ok { + return nil, errors.New("header not a valid tendermint header") + } + + if err := cs.checkValidity(tmHeader); err != nil { + return nil, err + } + + return cs.update(tmHeader), nil +} + +// checkValidity checks if the Tendermint header is valid +// +// CONTRACT: assumes header.Height > consensusState.Height +func (cs ConsensusState) checkValidity(header Header) error { + // check if the hash from the consensus set and header + // matches + nextHash := cs.NextValidatorSet.Hash() + if cs.Height == uint64(header.Height-1) && + !bytes.Equal(nextHash, header.ValidatorsHash) { + return lerr.ErrUnexpectedValidators(nextHash, header.ValidatorsHash) + } + + // validate the next validator set hash from the header + nextHash = header.NextValidatorSet.Hash() + if !bytes.Equal(header.NextValidatorsHash, nextHash) { + return lerr.ErrUnexpectedValidators(header.NextValidatorsHash, nextHash) + } + + // basic consistency check + if err := header.ValidateBasic(cs.ChainID); err != nil { + return err + } + + // abortTransactionUnless(consensusState.publicKey.verify(header.signature)) + return header.ValidatorSet.VerifyFutureCommit( + cs.NextValidatorSet, cs.ChainID, header.Commit.BlockID, header.Height, header.Commit, + ) +} + +// update the consensus state from a new header +func (cs ConsensusState) update(header Header) ConsensusState { + cs.Height = header.GetHeight() + cs.Root = commitment.NewRoot(header.AppHash) + cs.NextValidatorSet = header.NextValidatorSet + return cs +} diff --git a/x/ibc/02-client/types/tendermint/consensus_state_test.go b/x/ibc/02-client/types/tendermint/consensus_state_test.go new file mode 100644 index 000000000000..2f4129226228 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/consensus_state_test.go @@ -0,0 +1,52 @@ +package tendermint + +import ( + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/tmhash" + tmtypes "github.com/tendermint/tendermint/types" +) + +func (suite *TendermintTestSuite) TestCheckValidity() { + // valid header + err := suite.cs.checkValidity(suite.header) + require.Nil(suite.T(), err, "validity failed") + + // switch out header ValidatorsHash + suite.header.ValidatorsHash = tmhash.Sum([]byte("hello")) + err = suite.cs.checkValidity(suite.header) + require.NotNil(suite.T(), err, "validator hash is wrong") + + // reset suite and make header.NextValidatorSet different + // from NextValidatorSetHash + suite.SetupTest() + privVal := tmtypes.NewMockPV() + val := tmtypes.NewValidator(privVal.GetPubKey(), 5) + suite.header.NextValidatorSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) + err = suite.cs.checkValidity(suite.header) + require.NotNil(suite.T(), err, "header's next validator set is not consistent with hash") + + // reset and make header fail validatebasic + suite.SetupTest() + suite.header.ChainID = "not_mychain" + err = suite.cs.checkValidity(suite.header) + require.NotNil(suite.T(), err, "invalid header should fail ValidateBasic") +} + +func (suite *TendermintTestSuite) TestCheckUpdate() { + // valid header should successfully update consensus state + cs, err := suite.cs.CheckValidityAndUpdateState(suite.header) + + require.Nil(suite.T(), err, "valid update failed") + require.Equal(suite.T(), suite.header.GetHeight(), cs.GetHeight(), "height not updated") + require.Equal(suite.T(), suite.header.AppHash.Bytes(), cs.GetRoot().GetHash(), "root not updated") + tmCS, _ := cs.(ConsensusState) + require.Equal(suite.T(), suite.header.NextValidatorSet, tmCS.NextValidatorSet, "validator set did not update") + + // make header invalid so update should be unsuccessful + suite.SetupTest() + suite.header.ChainID = "not_mychain" + + cs, err = suite.cs.CheckValidityAndUpdateState(suite.header) + require.NotNil(suite.T(), err) + require.Nil(suite.T(), cs) +} diff --git a/x/ibc/02-client/types/tendermint/doc.go b/x/ibc/02-client/types/tendermint/doc.go new file mode 100644 index 000000000000..f0e27c7696a7 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/doc.go @@ -0,0 +1,5 @@ +/* +Package tendermint implements a concrete `ConsensusState`, `Header` and `Equivocation` +for the Tendermint consensus algorithm. +*/ +package tendermint diff --git a/x/ibc/02-client/types/tendermint/header.go b/x/ibc/02-client/types/tendermint/header.go new file mode 100644 index 000000000000..c2d9cfebc9c5 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/header.go @@ -0,0 +1,28 @@ +package tendermint + +import ( + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" +) + +var _ exported.Header = Header{} + +// Header defines the Tendermint consensus Header +type Header struct { + tmtypes.SignedHeader + ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` + NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` +} + +// ClientType defines that the Header is a Tendermint consensus algorithm +func (h Header) ClientType() exported.ClientType { + return exported.Tendermint +} + +// GetHeight returns the current height +// +// NOTE: also referred as `sequence` +func (h Header) GetHeight() uint64 { + return uint64(h.Height) +} diff --git a/x/ibc/02-client/types/tendermint/misbehaviour.go b/x/ibc/02-client/types/tendermint/misbehaviour.go new file mode 100644 index 000000000000..512bb0f72161 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/misbehaviour.go @@ -0,0 +1,96 @@ +package tendermint + +import ( + "fmt" + + yaml "gopkg.in/yaml.v2" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + + "github.com/tendermint/tendermint/crypto/tmhash" + cmn "github.com/tendermint/tendermint/libs/common" + tmtypes "github.com/tendermint/tendermint/types" +) + +var _ exported.Evidence = Evidence{} + +// Evidence is a wrapper over tendermint's DuplicateVoteEvidence +// that implements Evidence interface expected by ICS-02 +type Evidence struct { + *tmtypes.DuplicateVoteEvidence + ChainID string `json:"chain_id" yaml:"chain_id"` + ValidatorPower int64 `json:"val_power" yaml:"val_power"` + TotalPower int64 `json:"total_power" yaml:"total_power"` +} + +// Type implements exported.Evidence interface +func (ev Evidence) Route() string { + return exported.ClientTypeTendermint +} + +// Type implements exported.Evidence interface +func (ev Evidence) Type() string { + return exported.ClientTypeTendermint +} + +// String implements exported.Evidence interface +func (ev Evidence) String() string { + bz, err := yaml.Marshal(ev) + if err != nil { + panic(err) + } + return string(bz) +} + +// Hash implements exported.Evidence interface +func (ev Evidence) Hash() cmn.HexBytes { + return tmhash.Sum(SubModuleCdc.MustMarshalBinaryBare(ev)) +} + +// ValidateBasic implements exported.Evidence interface +func (ev Evidence) ValidateBasic() sdk.Error { + if ev.DuplicateVoteEvidence == nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "duplicate evidence is nil") + } + err := ev.DuplicateVoteEvidence.ValidateBasic() + if err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error()) + } + if ev.ChainID == "" { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "chainID is empty") + } + if ev.ValidatorPower <= 0 { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Validator Power: %d", ev.ValidatorPower)) + } + if ev.TotalPower < ev.ValidatorPower { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Total Power: %d", ev.TotalPower)) + } + return nil +} + +// GetConsensusAddress implements exported.Evidence interface +func (ev Evidence) GetConsensusAddress() sdk.ConsAddress { + return sdk.ConsAddress(ev.DuplicateVoteEvidence.Address()) +} + +// GetHeight implements exported.Evidence interface +func (ev Evidence) GetHeight() int64 { + return ev.DuplicateVoteEvidence.Height() +} + +// GetValidatorPower implements exported.Evidence interface +func (ev Evidence) GetValidatorPower() int64 { + return ev.ValidatorPower +} + +// GetTotalPower implements exported.Evidence interface +func (ev Evidence) GetTotalPower() int64 { + return ev.TotalPower +} + +// CheckMisbehaviour checks if the evidence provided is a misbehaviour +func CheckMisbehaviour(evidence Evidence) error { + return evidence.DuplicateVoteEvidence.Verify(evidence.ChainID, evidence.DuplicateVoteEvidence.PubKey) +} diff --git a/x/ibc/02-client/types/tendermint/misbehaviour_test.go b/x/ibc/02-client/types/tendermint/misbehaviour_test.go new file mode 100644 index 000000000000..f5e75e12f785 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/misbehaviour_test.go @@ -0,0 +1,64 @@ +package tendermint + +import ( + "testing" + + "github.com/stretchr/testify/require" + + yaml "gopkg.in/yaml.v2" +) + +func TestString(t *testing.T) { + dupEv := randomDuplicatedVoteEvidence() + ev := Evidence{ + DuplicateVoteEvidence: dupEv, + ChainID: "mychain", + ValidatorPower: 10, + TotalPower: 50, + } + + byteStr, err := yaml.Marshal(ev) + require.Nil(t, err) + require.Equal(t, string(byteStr), ev.String(), "Evidence String method does not work as expected") + +} + +func TestValidateBasic(t *testing.T) { + dupEv := randomDuplicatedVoteEvidence() + + // good evidence + ev := Evidence{ + DuplicateVoteEvidence: dupEv, + ChainID: "mychain", + ValidatorPower: 10, + TotalPower: 50, + } + + err := ev.ValidateBasic() + require.Nil(t, err, "good evidence failed on ValidateBasic: %v", err) + + // invalid duplicate evidence + ev.DuplicateVoteEvidence.VoteA = nil + err = ev.ValidateBasic() + require.NotNil(t, err, "invalid duplicate evidence passed on ValidateBasic") + + // reset duplicate evidence to be valid, and set empty chainID + dupEv = randomDuplicatedVoteEvidence() + ev.DuplicateVoteEvidence = dupEv + ev.ChainID = "" + err = ev.ValidateBasic() + require.NotNil(t, err, "invalid chain-id passed on ValidateBasic") + + // reset chainID and set 0 validator power + ev.ChainID = "mychain" + ev.ValidatorPower = 0 + err = ev.ValidateBasic() + require.NotNil(t, err, "invalid validator power passed on ValidateBasic") + + // reset validator power and set invalid total power + ev.ValidatorPower = 10 + ev.TotalPower = 9 + err = ev.ValidateBasic() + require.NotNil(t, err, "invalid total power passed on ValidateBasic") + +} diff --git a/x/ibc/02-client/types/tendermint/tendermint_test.go b/x/ibc/02-client/types/tendermint/tendermint_test.go new file mode 100644 index 000000000000..11817f73e9ff --- /dev/null +++ b/x/ibc/02-client/types/tendermint/tendermint_test.go @@ -0,0 +1,87 @@ +package tendermint + +import ( + "math" + "testing" + "time" + + "github.com/stretchr/testify/suite" + + "github.com/tendermint/tendermint/crypto/tmhash" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/version" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +type TendermintTestSuite struct { + suite.Suite + + privVal tmtypes.PrivValidator + valSet *tmtypes.ValidatorSet + header Header + cs ConsensusState +} + +func (suite *TendermintTestSuite) SetupTest() { + privVal := tmtypes.NewMockPV() + val := tmtypes.NewValidator(privVal.GetPubKey(), 10) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) + vsetHash := valSet.Hash() + timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) + tmHeader := tmtypes.Header{ + Version: version.Consensus{Block: 2, App: 2}, + ChainID: "mychain", + Height: 3, + Time: timestamp, + NumTxs: 100, + TotalTxs: 1000, + LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt64, make([]byte, tmhash.Size)), + LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), + DataHash: tmhash.Sum([]byte("data_hash")), + ValidatorsHash: vsetHash, + NextValidatorsHash: vsetHash, + ConsensusHash: tmhash.Sum([]byte("consensus_hash")), + AppHash: tmhash.Sum([]byte("app_hash")), + LastResultsHash: tmhash.Sum([]byte("last_results_hash")), + EvidenceHash: tmhash.Sum([]byte("evidence_hash")), + ProposerAddress: privVal.GetPubKey().Address(), + } + hhash := tmHeader.Hash() + blockID := makeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) + voteSet := tmtypes.NewVoteSet("mychain", 3, 1, tmtypes.PrecommitType, valSet) + commit, err := tmtypes.MakeCommit(blockID, 3, 1, voteSet, []tmtypes.PrivValidator{privVal}) + if err != nil { + panic(err) + } + + signedHeader := tmtypes.SignedHeader{ + Header: &tmHeader, + Commit: commit, + } + + header := Header{ + SignedHeader: signedHeader, + ValidatorSet: valSet, + NextValidatorSet: valSet, + } + + root := commitment.NewRoot(tmhash.Sum([]byte("my root"))) + + cs := ConsensusState{ + ChainID: "mychain", + Height: 3, + Root: root, + NextValidatorSet: valSet, + } + + // set fields in suite + suite.privVal = privVal + suite.valSet = valSet + suite.header = header + suite.cs = cs +} + +func TestTendermintTestSuite(t *testing.T) { + suite.Run(t, new(TendermintTestSuite)) +} diff --git a/x/ibc/02-client/types/tendermint/test_utils.go b/x/ibc/02-client/types/tendermint/test_utils.go new file mode 100644 index 000000000000..a88bd13d3b1c --- /dev/null +++ b/x/ibc/02-client/types/tendermint/test_utils.go @@ -0,0 +1,47 @@ +package tendermint + +import ( + "github.com/tendermint/tendermint/crypto/tmhash" + tmtypes "github.com/tendermint/tendermint/types" +) + +// Copied unimported test functions from tmtypes to use them here +func makeBlockID(hash []byte, partSetSize int, partSetHash []byte) tmtypes.BlockID { + return tmtypes.BlockID{ + Hash: hash, + PartsHeader: tmtypes.PartSetHeader{ + Total: partSetSize, + Hash: partSetHash, + }, + } + +} + +func makeVote(val tmtypes.PrivValidator, chainID string, valIndex int, height int64, round, step int, blockID tmtypes.BlockID) *tmtypes.Vote { + addr := val.GetPubKey().Address() + v := &tmtypes.Vote{ + ValidatorAddress: addr, + ValidatorIndex: valIndex, + Height: height, + Round: round, + Type: tmtypes.SignedMsgType(step), + BlockID: blockID, + } + err := val.SignVote(chainID, v) + if err != nil { + panic(err) + } + return v +} + +func randomDuplicatedVoteEvidence() *tmtypes.DuplicateVoteEvidence { + val := tmtypes.NewMockPV() + blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), 1000, tmhash.Sum([]byte("partshash"))) + blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), 1000, tmhash.Sum([]byte("partshash"))) + const chainID = "mychain" + return &tmtypes.DuplicateVoteEvidence{ + PubKey: val.GetPubKey(), + VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID), + VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2), + } +} diff --git a/x/ibc/24-host/errors.go b/x/ibc/24-host/errors.go index afc1c26ea303..e6a526e6d0f8 100644 --- a/x/ibc/24-host/errors.go +++ b/x/ibc/24-host/errors.go @@ -14,6 +14,9 @@ var ( // ErrInvalidPath is returned if path string is invalid ErrInvalidPath = sdkerrors.Register(IBCCodeSpace, 2, "invalid path") + // ErrInvalidEvidence is returned if evidence is invalid + ErrInvalidEvidence = sdkerrors.Register(IBCCodeSpace, 3, "invalid evidence") + // ErrInvalidPacket is returned if packets embedded in msg are invalid - ErrInvalidPacket = sdkerrors.Register(IBCCodeSpace, 3, "invalid packet extracted from msg") + ErrInvalidPacket = sdkerrors.Register(IBCCodeSpace, 4, "invalid packet extracted from msg") ) diff --git a/x/ibc/alias.go b/x/ibc/alias.go new file mode 100644 index 000000000000..7c1ad02349e2 --- /dev/null +++ b/x/ibc/alias.go @@ -0,0 +1,29 @@ +package ibc + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +const ( + ModuleName = types.ModuleName + StoreKey = types.StoreKey + QuerierRoute = types.QuerierRoute + RouterKey = types.RouterKey +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + NewQuerier = keeper.NewQuerier +) + +type ( + Keeper = keeper.Keeper +) diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go new file mode 100644 index 000000000000..5657d2aad3c7 --- /dev/null +++ b/x/ibc/client/cli/cli.go @@ -0,0 +1,43 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ibcTxCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "IBC transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + ibcTxCmd.AddCommand(client.PostCommands( + ibcclient.GetTxCmd(cdc, storeKey), + )...) + return ibcTxCmd +} + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + // Group ibc queries under a subcommand + ibcQueryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Querying commands for the IBC module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + ibcQueryCmd.AddCommand(client.GetCommands( + ibcclient.GetQueryCmd(cdc, queryRoute), + )...) + return ibcQueryCmd +} diff --git a/x/ibc/handler.go b/x/ibc/handler.go new file mode 100644 index 000000000000..5dc802b6f063 --- /dev/null +++ b/x/ibc/handler.go @@ -0,0 +1,30 @@ +package ibc + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" +) + +// NewHandler defines the IBC handler +func NewHandler(k Keeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + switch msg := msg.(type) { + case client.MsgCreateClient: + return client.HandleMsgCreateClient(ctx, k.ClientKeeper, msg) + + case client.MsgUpdateClient: + return client.HandleMsgUpdateClient(ctx, k.ClientKeeper, msg) + + case client.MsgSubmitMisbehaviour: + return client.HandleMsgSubmitMisbehaviour(ctx, k.ClientKeeper, msg) + + default: + errMsg := fmt.Sprintf("unrecognized IBC Client message type: %T", msg) + return sdk.ErrUnknownRequest(errMsg).Result() + } + } +} diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go new file mode 100644 index 000000000000..fce91fb353bd --- /dev/null +++ b/x/ibc/keeper/keeper.go @@ -0,0 +1,19 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" +) + +// Keeper defines each ICS keeper for IBC +type Keeper struct { + ClientKeeper client.Keeper +} + +// NewKeeper creates a new ibc Keeper +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { + return Keeper{ + ClientKeeper: client.NewKeeper(cdc, key, codespace), + } +} diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go new file mode 100644 index 000000000000..7cbd4ec9c499 --- /dev/null +++ b/x/ibc/keeper/querier.go @@ -0,0 +1,24 @@ +package keeper + +import ( + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" +) + +// NewQuerier creates a querier for the IBC module +func NewQuerier(k Keeper) sdk.Querier { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + switch path[0] { + case client.QueryClientState: + return client.QuerierClientState(ctx, req, k.ClientKeeper) + case client.QueryConsensusState: + return client.QuerierConsensusState(ctx, req, k.ClientKeeper) + case client.QueryVerifiedRoot: + return client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) + default: + return nil, sdk.ErrUnknownRequest("unknown IBC client query endpoint") + } + } +} diff --git a/x/ibc/module.go b/x/ibc/module.go index a81836a9c7ed..675b18aa1ddf 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -1 +1,132 @@ package ibc + +import ( + "encoding/json" + + "github.com/gorilla/mux" + "github.com/spf13/cobra" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// TODO: AppModuleSimulation +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the staking module. +type AppModuleBasic struct{} + +var _ module.AppModuleBasic = AppModuleBasic{} + +// Name returns the staking module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterCodec registers the staking module's types for the given codec. +func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { + client.RegisterCodec(cdc) + commitment.RegisterCodec(cdc) +} + +// DefaultGenesis returns default genesis state as raw bytes for the staking +// module. +func (AppModuleBasic) DefaultGenesis() json.RawMessage { + return nil +} + +// ValidateGenesis performs genesis state validation for the staking module. +func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { + return nil +} + +// RegisterRESTRoutes registers the REST routes for the staking module. +func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { + /// TODO: +} + +// GetTxCmd returns the root tx command for the staking module. +func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetTxCmd(StoreKey, cdc) +} + +// GetQueryCmd returns no root query command for the staking module. +func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetQueryCmd(QuerierRoute, cdc) +} + +// AppModule implements an application module for the staking module. +type AppModule struct { + AppModuleBasic + keeper Keeper +} + +// NewAppModule creates a new AppModule object +func NewAppModule(k Keeper) AppModule { + return AppModule{ + keeper: k, + } +} + +// Name returns the staking module's name. +func (AppModule) Name() string { + return ModuleName +} + +// RegisterInvariants registers the staking module invariants. +func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { + // TODO: +} + +// Route returns the message routing key for the staking module. +func (AppModule) Route() string { + return RouterKey +} + +// NewHandler returns an sdk.Handler for the staking module. +func (am AppModule) NewHandler() sdk.Handler { + return NewHandler(am.keeper) +} + +// QuerierRoute returns the staking module's querier route name. +func (AppModule) QuerierRoute() string { + return QuerierRoute +} + +// NewQuerierHandler returns the staking module sdk.Querier. +func (am AppModule) NewQuerierHandler() sdk.Querier { + return NewQuerier(am.keeper) +} + +// InitGenesis performs genesis initialization for the staking module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the staking +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { + return nil +} + +// BeginBlock returns the begin blocker for the staking module. +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { +} + +// EndBlock returns the end blocker for the staking module. It returns no validator +// updates. +func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} diff --git a/x/ibc/types/types.go b/x/ibc/types/types.go new file mode 100644 index 000000000000..535a8f2461e5 --- /dev/null +++ b/x/ibc/types/types.go @@ -0,0 +1,15 @@ +package types + +const ( + // ModuleName is the name of the IBC module + ModuleName = "ibc" + + // StoreKey is the string store representation + StoreKey = ModuleName + + // QuerierRoute is the querier route for the IBC module + QuerierRoute = ModuleName + + // RouterKey is the msg router key for the IBC module + RouterKey = ModuleName +) diff --git a/x/ibc/version/version.go b/x/ibc/version/version.go new file mode 100644 index 000000000000..a7d3275fae5b --- /dev/null +++ b/x/ibc/version/version.go @@ -0,0 +1,13 @@ +package version + +import "strconv" + +const Version int64 = 1 + +func DefaultPrefix() []byte { + return Prefix(Version) +} + +func Prefix(version int64) []byte { + return []byte("v" + strconv.FormatInt(version, 10) + "/") +} From 2ae542a41b9ae90852a9b95e430a44b62a959409 Mon Sep 17 00:00:00 2001 From: Joon Date: Tue, 5 Nov 2019 09:01:33 -0800 Subject: [PATCH 004/176] ICS 03 Implementation (#4517) * add test * in progres * fin rebase * in progress * fin rebase * add CLIObject in progress * cli in progress * add CLIObject * separate testing from tendermint * add key to node * add root and storekey to tests/node, add codec * rm cli/query.go * fix test * fix lint * fix lint * add handler/msgs/client * rm relay * finalize rebase on 23 root/path sep * fix lint, fix syntax * fix querying * extract out context withstore * fix 02-client test * fix 23-commitment test * add query in progress * rm freebase, reformat query * add cli/handler/msg in progress * add cli/msg/handler * add CLIQuery, fix tests * fix golangci * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * add godoc in progress * reformat test * rm XXX * add godoc * modify store * add query * update query.go * update query.go * cli refactor in progress * cli refactor in progress * add Query to boolean.go * fix key * fix cli / merkle test * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * fix test * fix client * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * fix dependency * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * rm commented lines * address review in progress * address review, rm cleanup/closing * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * update expected client keeper and export verification funcs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * start batch-verify tests * minor changes on commitment types * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * use testsuite * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * fix --- client/flags/flags.go | 1 + x/ibc/03-connection/alias.go | 102 ++++ x/ibc/03-connection/client/cli/query.go | 130 ++++ x/ibc/03-connection/client/cli/tx.go | 569 ++++++++++++++++++ x/ibc/03-connection/handler.go | 102 ++++ x/ibc/03-connection/keeper/handshake.go | 256 ++++++++ x/ibc/03-connection/keeper/keeper.go | 171 ++++++ x/ibc/03-connection/keeper/querier.go | 54 ++ x/ibc/03-connection/module.go | 25 + x/ibc/03-connection/types/codec.go | 21 + x/ibc/03-connection/types/connection.go | 143 +++++ x/ibc/03-connection/types/errors.go | 73 +++ x/ibc/03-connection/types/events.go | 23 + x/ibc/03-connection/types/expected_keepers.go | 22 + x/ibc/03-connection/types/keys.go | 41 ++ x/ibc/03-connection/types/msgs.go | 300 +++++++++ x/ibc/03-connection/types/querier.go | 83 +++ x/ibc/03-connection/types/version.go | 96 +++ x/ibc/client/cli/cli.go | 3 + x/ibc/handler.go | 15 +- x/ibc/keeper/keeper.go | 10 +- x/ibc/keeper/querier.go | 33 +- x/ibc/module.go | 2 + 23 files changed, 2265 insertions(+), 10 deletions(-) create mode 100644 x/ibc/03-connection/alias.go create mode 100644 x/ibc/03-connection/client/cli/query.go create mode 100644 x/ibc/03-connection/client/cli/tx.go create mode 100644 x/ibc/03-connection/handler.go create mode 100644 x/ibc/03-connection/keeper/handshake.go create mode 100644 x/ibc/03-connection/keeper/keeper.go create mode 100644 x/ibc/03-connection/keeper/querier.go create mode 100644 x/ibc/03-connection/module.go create mode 100644 x/ibc/03-connection/types/codec.go create mode 100644 x/ibc/03-connection/types/connection.go create mode 100644 x/ibc/03-connection/types/errors.go create mode 100644 x/ibc/03-connection/types/events.go create mode 100644 x/ibc/03-connection/types/expected_keepers.go create mode 100644 x/ibc/03-connection/types/keys.go create mode 100644 x/ibc/03-connection/types/msgs.go create mode 100644 x/ibc/03-connection/types/querier.go create mode 100644 x/ibc/03-connection/types/version.go diff --git a/client/flags/flags.go b/client/flags/flags.go index 62f2a8d012f9..0dbaa4c68d15 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -54,6 +54,7 @@ const ( FlagRPCWriteTimeout = "write-timeout" FlagOutputDocument = "output-document" // inspired by wget -O FlagSkipConfirmation = "yes" + FlagProve = "prove" ) // LineBreak can be included in a command list to provide a blank line diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go new file mode 100644 index 000000000000..27757d8163e5 --- /dev/null +++ b/x/ibc/03-connection/alias.go @@ -0,0 +1,102 @@ +package connection + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/03-connection/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +const ( + NONE = types.NONE + INIT = types.INIT + TRYOPEN = types.TRYOPEN + OPEN = types.OPEN + StateNone = types.StateNone + StateInit = types.StateInit + StateTryOpen = types.StateTryOpen + StateOpen = types.StateOpen + DefaultCodespace = types.DefaultCodespace + CodeConnectionExists = types.CodeConnectionExists + CodeConnectionNotFound = types.CodeConnectionNotFound + CodeClientConnectionPathsNotFound = types.CodeClientConnectionPathsNotFound + CodeConnectionPath = types.CodeConnectionPath + CodeInvalidCounterpartyConnection = types.CodeInvalidCounterpartyConnection + CodeInvalidVersion = types.CodeInvalidVersion + CodeInvalidHeight = types.CodeInvalidHeight + CodeInvalidConnectionState = types.CodeInvalidConnectionState + CodeInvalidProof = types.CodeInvalidProof + CodeInvalidCounterparty = types.CodeInvalidCounterparty + AttributeKeyConnectionID = types.AttributeKeyConnectionID + AttributeKeyCounterpartyClientID = types.AttributeKeyCounterpartyClientID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryConnection = types.QueryConnection + QueryClientConnections = types.QueryClientConnections +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + QuerierConnection = keeper.QuerierConnection + QuerierClientConnections = keeper.QuerierClientConnections + RegisterCodec = types.RegisterCodec + NewConnectionEnd = types.NewConnectionEnd + NewCounterparty = types.NewCounterparty + StateFromString = types.StateFromString + ErrConnectionExists = types.ErrConnectionExists + ErrConnectionNotFound = types.ErrConnectionNotFound + ErrClientConnectionPathsNotFound = types.ErrClientConnectionPathsNotFound + ErrConnectionPath = types.ErrConnectionPath + ErrInvalidCounterpartyConnection = types.ErrInvalidCounterpartyConnection + ErrInvalidVersion = types.ErrInvalidVersion + ErrInvalidHeight = types.ErrInvalidHeight + ErrInvalidConnectionState = types.ErrInvalidConnectionState + ErrInvalidConnectionProof = types.ErrInvalidConnectionProof + ErrInvalidCounterparty = types.ErrInvalidCounterparty + ConnectionPath = types.ConnectionPath + ClientConnectionsPath = types.ClientConnectionsPath + KeyConnection = types.KeyConnection + KeyClientConnections = types.KeyClientConnections + NewMsgConnectionOpenInit = types.NewMsgConnectionOpenInit + NewMsgConnectionOpenTry = types.NewMsgConnectionOpenTry + NewMsgConnectionOpenAck = types.NewMsgConnectionOpenAck + NewMsgConnectionOpenConfirm = types.NewMsgConnectionOpenConfirm + NewConnectionResponse = types.NewConnectionResponse + NewQueryConnectionParams = types.NewQueryConnectionParams + NewClientConnectionsResponse = types.NewClientConnectionsResponse + NewQueryClientConnectionsParams = types.NewQueryClientConnectionsParams + GetCompatibleVersions = types.GetCompatibleVersions + LatestVersion = types.LatestVersion + PickVersion = types.PickVersion + + // variable aliases + SubModuleCdc = types.SubModuleCdc + EventTypeConnectionOpenInit = types.EventTypeConnectionOpenInit + EventTypeConnectionOpenTry = types.EventTypeConnectionOpenTry + EventTypeConnectionOpenAck = types.EventTypeConnectionOpenAck + EventTypeConnectionOpenConfirm = types.EventTypeConnectionOpenConfirm + AttributeValueCategory = types.AttributeValueCategory +) + +type ( + Keeper = keeper.Keeper + ConnectionEnd = types.ConnectionEnd + Counterparty = types.Counterparty + State = types.State + ClientKeeper = types.ClientKeeper + MsgConnectionOpenInit = types.MsgConnectionOpenInit + MsgConnectionOpenTry = types.MsgConnectionOpenTry + MsgConnectionOpenAck = types.MsgConnectionOpenAck + MsgConnectionOpenConfirm = types.MsgConnectionOpenConfirm + ConnectionResponse = types.ConnectionResponse + QueryConnectionParams = types.QueryConnectionParams + ClientConnectionsResponse = types.ClientConnectionsResponse + QueryClientConnectionsParams = types.QueryClientConnectionsParams +) diff --git a/x/ibc/03-connection/client/cli/query.go b/x/ibc/03-connection/client/cli/query.go new file mode 100644 index 000000000000..266ac4bf02d3 --- /dev/null +++ b/x/ibc/03-connection/client/cli/query.go @@ -0,0 +1,130 @@ +package cli + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +// GetQueryCmd returns the query commands for IBC connections +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + ics03ConnectionQueryCmd := &cobra.Command{ + Use: "connection", + Short: "IBC connection query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics03ConnectionQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryConnection(queryRoute, cdc), + )...) + return ics03ConnectionQueryCmd +} + +// GetCmdQueryConnection defines the command to query a connection end +func GetCmdQueryConnection(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "end [connection-id]", + Short: "Query stored connection end", + Long: strings.TrimSpace(fmt.Sprintf(`Query stored connection end + +Example: +$ %s query ibc connection end [connection-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + connectionID := args[0] + + bz, err := cdc.MarshalJSON(types.NewQueryConnectionParams(connectionID)) + if err != nil { + return err + } + + req := abci.RequestQuery{ + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryConnection), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return err + } + + var connection types.ConnectionEnd + if err := cdc.UnmarshalJSON(res.Value, &connection); err != nil { + return err + } + + if res.Proof == nil { + return cliCtx.PrintOutput(connection) + } + + connRes := types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height) + return cliCtx.PrintOutput(connRes) + }, + } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + + return cmd +} + +// GetCmdQueryClientConnections defines the command to query a client connections +func GetCmdQueryClientConnections(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "client [client-id]", + Short: "Query stored client connection paths", + Long: strings.TrimSpace(fmt.Sprintf(`Query stored client connection paths + +Example: +$ %s query ibc connection client [client-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + + bz, err := cdc.MarshalJSON(types.NewQueryClientConnectionsParams(clientID)) + if err != nil { + return err + } + + req := abci.RequestQuery{ + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientConnections), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return err + } + + var connectionPaths []string + if err := cdc.UnmarshalJSON(res.Value, &connectionPaths); err != nil { + return err + } + + if res.Proof == nil { + return cliCtx.PrintOutput(connectionPaths) + } + + connPathsRes := types.NewClientConnectionsResponse(clientID, connectionPaths, res.Proof, res.Height) + return cliCtx.PrintOutput(connPathsRes) + }, + } +} diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go new file mode 100644 index 000000000000..22ccf7777d31 --- /dev/null +++ b/x/ibc/03-connection/client/cli/tx.go @@ -0,0 +1,569 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "os" + "strings" + "time" + + "github.com/pkg/errors" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + abci "github.com/tendermint/tendermint/abci/types" +) + +// Connection Handshake flags +const ( + FlagNode1 = "node1" + FlagNode2 = "node2" + FlagFrom1 = "from1" + FlagFrom2 = "from2" + FlagChainID2 = "chain-id2" +) + +// GetTxCmd returns the transaction commands for IBC Connections +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics03ConnectionTxCmd := &cobra.Command{ + Use: "connection", + Short: "IBC connection transaction subcommands", + } + + ics03ConnectionTxCmd.AddCommand(client.PostCommands( + GetCmdConnectionOpenInit(storeKey, cdc), + GetCmdConnectionOpenTry(storeKey, cdc), + GetCmdConnectionOpenAck(storeKey, cdc), + GetCmdConnectionOpenConfirm(storeKey, cdc), + GetCmdHandshakeState(storeKey, cdc), + )...) + + return ics03ConnectionTxCmd +} + +// GetCmdConnectionOpenInit defines the command to initialize a connection on +// chain A with a given counterparty chain B +func GetCmdConnectionOpenInit(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: strings.TrimSpace(`open-init [connection-id] [client-id] [counterparty-connection-id] + [counterparty-client-id] [path/to/counterparty_prefix.json]`), + Short: "initialize connection on chain A", + Long: strings.TrimSpace( + fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: + +Example: +$ %s tx ibc connection open-init [connection-id] [client-id] [counterparty-connection-id] +[counterparty-client-id] [path/to/counterparty_prefix.json] + `, version.ClientName), + ), + Args: cobra.ExactArgs(6), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + connectionID := args[0] + clientID := args[1] + counterpartyConnectionID := args[2] + counterpartyClientID := args[3] + + bz, err := ioutil.ReadFile(args[4]) + if err != nil { + return err + } + + var counterpartyPrefix commitment.Prefix + if err := cdc.UnmarshalJSON(bz, &counterpartyPrefix); err != nil { + return err + } + + msg := types.NewMsgConnectionOpenInit( + connectionID, clientID, counterpartyConnectionID, counterpartyClientID, + counterpartyPrefix, cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdConnectionOpenTry defines the command to relay a try open a connection on +// chain B +func GetCmdConnectionOpenTry(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: strings.TrimSpace(`open-try [connection-id] [client-id] +[counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] +[counterparty-versions] [path/to/proof_init.json]`), + Short: "initiate connection handshake between two chains", + Long: strings.TrimSpace( + fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: + +Example: +$ %s tx ibc connection open-try connection-id] [client-id] +[counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] +[counterparty-versions] [path/to/proof_init.json] + `, version.ClientName), + ), + Args: cobra.ExactArgs(6), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext(). + WithCodec(cdc). + WithHeight(viper.GetInt64(flags.FlagHeight)) + + connectionID := args[0] + clientID := args[1] + counterpartyConnectionID := args[2] + counterpartyClientID := args[3] + + prefixBz, err := ioutil.ReadFile(args[4]) + if err != nil { + return err + } + + var counterpartyPrefix commitment.Prefix + if err := cdc.UnmarshalJSON(prefixBz, &counterpartyPrefix); err != nil { + return err + } + + // TODO: parse strings? + counterpartyVersions := args[5] + + proofBz, err := ioutil.ReadFile(args[6]) + if err != nil { + return err + } + + var proofInit commitment.Proof + if err := cdc.UnmarshalJSON(proofBz, &proofInit); err != nil { + return err + } + + proofHeight := uint64(cliCtx.Height) + consensusHeight, err := lastHeight(cliCtx) + if err != nil { + return err + } + + msg := types.NewMsgConnectionOpenTry( + connectionID, clientID, counterpartyConnectionID, counterpartyClientID, + counterpartyPrefix, []string{counterpartyVersions}, proofInit, proofInit, proofHeight, + consensusHeight, cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdConnectionOpenAck defines the command to relay the acceptance of a +// connection open attempt from chain B to chain A +func GetCmdConnectionOpenAck(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-ack [connection-id] [path/to/proof_try.json] [version]", + Short: "relay the acceptance of a connection open attempt from chain B to chain A", + Long: strings.TrimSpace( + fmt.Sprintf(`relay the acceptance of a connection open attempt from chain B to chain A: + +Example: +$ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [version] + `, version.ClientName), + ), + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + connectionID := args[0] + proofBz, err := ioutil.ReadFile(args[1]) + if err != nil { + return err + } + + var proofTry commitment.Proof + if err := cdc.UnmarshalJSON(proofBz, &proofTry); err != nil { + return err + } + + proofHeight := uint64(cliCtx.Height) + consensusHeight, err := lastHeight(cliCtx) + if err != nil { + return err + } + + version := args[4] + + msg := types.NewMsgConnectionOpenAck( + connectionID, proofTry, proofTry, proofHeight, + consensusHeight, version, cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdConnectionOpenConfirm defines the command to initialize a connection on +// chain A with a given counterparty chain B +func GetCmdConnectionOpenConfirm(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-confirm [connection-id] [path/to/proof_ack.json]", + Short: "confirm to chain B that connection is open on chain A", + Long: strings.TrimSpace( + fmt.Sprintf(`confirm to chain B that connection is open on chain A: + +Example: +$ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] + `, version.ClientName), + ), + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext(). + WithCodec(cdc). + WithHeight(viper.GetInt64(flags.FlagHeight)) + + connectionID := args[0] + + proofBz, err := ioutil.ReadFile(args[1]) + if err != nil { + return err + } + + var proofAck commitment.Proof + if err := cdc.UnmarshalJSON(proofBz, &proofAck); err != nil { + return err + } + + proofHeight := uint64(cliCtx.Height) + + msg := types.NewMsgConnectionOpenConfirm( + connectionID, proofAck, proofHeight, cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// lastHeight util function to get the consensus height from the node +func lastHeight(cliCtx context.CLIContext) (uint64, error) { + node, err := cliCtx.GetNode() + if err != nil { + return 0, err + } + + info, err := node.ABCIInfo() + if err != nil { + return 0, err + } + + return uint64(info.Response.LastBlockHeight), nil +} + +func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "handshake [conn-id-chain-1] [client-id-chain-1] [path-chain-1] [conn-id-chain-2] [client-id-chain-2] [path-chain-2] ", + Short: "initiate connection handshake between two chains", + Args: cobra.ExactArgs(6), + RunE: func(cmd *cobra.Command, args []string) error { + + viper.Set(flags.FlagProve, true) + + // --chain-id values for each chain + cid1 := viper.GetString(flags.FlagChainID) + cid2 := viper.GetString(FlagChainID2) + + // --from values for each wallet + from1 := viper.GetString(FlagFrom1) + from2 := viper.GetString(FlagFrom2) + + // --node values for each RPC + rpc1 := viper.GetString(FlagNode1) + rpc2 := viper.GetString(FlagNode2) + + // ibc connection-id for each chain + connID1 := args[0] + connID2 := args[3] + + // ibc client-id for each chain + clientID1 := args[1] + clientID2 := args[4] + + // Get default version + version := types.GetCompatibleVersions()[0] + + // Create txbldr, clictx, querier for cid1 + viper.Set(flags.FlagChainID, cid1) + txBldr1 := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx1 := context.NewCLIContextIBC(from1, cid1, rpc1).WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + // Create txbldr, clictx, querier for cid1 + viper.Set(flags.FlagChainID, cid2) + txBldr2 := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx2 := context.NewCLIContextIBC(from2, cid2, rpc2).WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + // read in path for cid1 + path1, err := parsePath(ctx1.Codec, args[2]) + if err != nil { + return err + } + + // read in path for cid2 + path2, err := parsePath(ctx1.Codec, args[5]) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + msgOpenInit := types.NewMsgConnectionOpenInit( + connID1, clientID1, connID2, clientID2, + path2, ctx1.GetFromAddress(), + ) + + if err := msgOpenInit.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenInit}) + if err != nil { + return err + } + + // Another block has to be passed after msgOpenInit is committed + // to retrieve the correct proofs + // TODO: Modify this to actually check two blocks being processed, and + // remove hardcoding this to 8 seconds. + time.Sleep(8 * time.Second) + + header, err := clientutils.GetTendermintHeader(ctx1) + if err != nil { + return err + } + + // Create and send msgUpdateClient + viper.Set(flags.FlagChainID, cid2) + msgUpdateClient := clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) + + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + fmt.Printf(" [OK] client(%v)\n", clientID1) + + // Fetch proofs from cid1 + viper.Set(flags.FlagChainID, cid1) + proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) + if err != nil { + return err + } + + csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1) + if err != nil { + return err + } + + // Create and send msgOpenTry + viper.Set(flags.FlagChainID, cid2) + msgOpenTry := types.NewMsgConnectionOpenTry(connID2, clientID2, connID1, clientID1, path1, []string{version}, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), ctx2.GetFromAddress()) + + if err := msgOpenTry.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenTry}) + if err != nil { + return err + } + + fmt.Printf(" [OK] client(%v) connection(%v)\n", clientID2, connID2) + + // Another block has to be passed after msgOpenInit is committed + // to retrieve the correct proofs + // TODO: Modify this to actually check two blocks being processed, and + // remove hardcoding this to 8 seconds. + time.Sleep(8 * time.Second) + + header, err = clientutils.GetTendermintHeader(ctx2) + if err != nil { + return err + } + + // Update the client for cid2 on cid1 + viper.Set(flags.FlagChainID, cid1) + msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID1, header, ctx1.GetFromAddress()) + + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + fmt.Printf(" [OK] client(%v)\n", clientID2) + + // Fetch proofs from cid2 + viper.Set(flags.FlagChainID, cid2) + proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), connID2, storeKey) + if err != nil { + return err + } + + csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2) + if err != nil { + return err + } + + // Create and send msgOpenAck + viper.Set(flags.FlagChainID, cid1) + msgOpenAck := types.NewMsgConnectionOpenAck(connID1, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), version, ctx1.GetFromAddress()) + + if err := msgOpenAck.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenAck}) + if err != nil { + return err + } + fmt.Printf(" [OK] connection(%v)\n", connID1) + + // Another block has to be passed after msgOpenInit is committed + // to retrieve the correct proofs + // TODO: Modify this to actually check two blocks being processed, and + // remove hardcoding this to 8 seconds. + time.Sleep(8 * time.Second) + + header, err = clientutils.GetTendermintHeader(ctx1) + if err != nil { + return err + } + + // Update client for cid1 on cid2 + viper.Set(flags.FlagChainID, cid2) + msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) + + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + fmt.Printf(" [OK] client(%v)\n", clientID1) + + // Fetch proof from cid1 + viper.Set(flags.FlagChainID, cid1) + proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) + if err != nil { + return err + } + + // Create and send msgOpenConfirm + viper.Set(flags.FlagChainID, cid2) + msgOpenConfirm := types.NewMsgConnectionOpenConfirm(connID2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + + if err := msgOpenConfirm.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}) + if err != nil { + return err + } + fmt.Printf(" [OK] connection(%v)\n", connID2) + + return nil + }, + } + + cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") + cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") + cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") + cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") + cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") + + cmd.MarkFlagRequired(FlagNode1) + cmd.MarkFlagRequired(FlagNode2) + cmd.MarkFlagRequired(FlagFrom1) + cmd.MarkFlagRequired(FlagFrom2) + cmd.MarkFlagRequired(FlagChainID2) + + return cmd +} + +func queryProofs(ctx client.CLIContext, connectionID string, queryRoute string) (types.ConnectionResponse, error) { + + var connRes types.ConnectionResponse + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: []byte(fmt.Sprintf("connections/%s", connectionID)), + Prove: true, + } + res, err := ctx.QueryABCI(req) + if err != nil { + return connRes, err + } + + var connection types.ConnectionEnd + if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { + return connRes, err + } + return types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height), nil +} + +func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { + var path commitment.Prefix + if err := cdc.UnmarshalJSON([]byte(arg), &path); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(arg) + if err != nil { + return path, errors.Wrap(err, "error opening path file") + } + if err := cdc.UnmarshalJSON(contents, &path); err != nil { + return path, errors.Wrap(err, "error unmarshalling path file") + } + } + return path, nil +} diff --git a/x/ibc/03-connection/handler.go b/x/ibc/03-connection/handler.go new file mode 100644 index 000000000000..854436eadd6a --- /dev/null +++ b/x/ibc/03-connection/handler.go @@ -0,0 +1,102 @@ +package connection + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +// HandleMsgConnectionOpenInit defines the sdk.Handler for MsgConnectionOpenInit +func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenInit) sdk.Result { + err := k.ConnOpenInit(ctx, msg.ConnectionID, msg.ClientID, msg.Counterparty) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeConnectionOpenInit, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + sdk.NewAttribute(types.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgConnectionOpenTry defines the sdk.Handler for MsgConnectionOpenTry +func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenTry) sdk.Result { + err := k.ConnOpenTry( + ctx, msg.ConnectionID, msg.Counterparty, msg.ClientID, + msg.CounterpartyVersions, msg.ProofInit, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeConnectionOpenTry, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + sdk.NewAttribute(types.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgConnectionOpenAck defines the sdk.Handler for MsgConnectionOpenAck +func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenAck) sdk.Result { + err := k.ConnOpenAck( + ctx, msg.ConnectionID, msg.Version, msg.ProofTry, msg.ProofConsensus, + msg.ProofHeight, msg.ConsensusHeight, + ) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeConnectionOpenAck, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgConnectionOpenConfirm defines the sdk.Handler for MsgConnectionOpenConfirm +func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenConfirm) sdk.Result { + err := k.ConnOpenConfirm(ctx, msg.ConnectionID, msg.ProofAck, msg.ProofHeight) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeConnectionOpenConfirm, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go new file mode 100644 index 000000000000..21a005b12c9f --- /dev/null +++ b/x/ibc/03-connection/keeper/handshake.go @@ -0,0 +1,256 @@ +package keeper + +import ( + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// ConnOpenInit initialises a connection attempt on chain A. +// +// NOTE: Identifiers are checked on msg validation. +func (k Keeper) ConnOpenInit( + ctx sdk.Context, + connectionID, // identifier + clientID string, + counterparty types.Counterparty, // desiredCounterpartyConnectionIdentifier, counterpartyPrefix, counterpartyClientIdentifier +) error { + _, found := k.GetConnection(ctx, connectionID) + if found { + return sdkerrors.Wrap(types.ErrConnectionExists(k.codespace, connectionID), "cannot initialize connection") + } + + // connection defines chain A's ConnectionEnd + connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.GetCompatibleVersions()) + k.SetConnection(ctx, connectionID, connection) + + err := k.addConnectionToClient(ctx, clientID, connectionID) + if err != nil { + sdkerrors.Wrap(err, "cannot initialize connection") + } + + k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: NONE -> INIT", connectionID)) + return nil +} + +// ConnOpenTry relays notice of a connection attempt on chain A to chain B (this +// code is executed on chain B). +// +// NOTE: +// - Here chain A acts as the counterparty +// - Identifiers are checked on msg validation +func (k Keeper) ConnOpenTry( + ctx sdk.Context, + connectionID string, // desiredIdentifier + counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier + clientID string, + counterpartyVersions []string, + proofInit commitment.ProofI, + proofConsensus commitment.ProofI, + proofHeight uint64, + consensusHeight uint64, +) error { + // XXX: blocked by #5078 + /* + if consensusHeight > uint64(ctx.BlockHeight()) { + return errors.New("invalid consensus height") // TODO: sdk.Error + } + + expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, clientID) + if !found { + return errors.New("client consensus state not found") // TODO: use ICS02 error + } + */ + + // expectedConn defines Chain A's ConnectionEnd + // NOTE: chain A's counterparty is chain B (i.e where this code is executed) + prefix := k.GetCommitmentPrefix() + expectedCounterparty := types.NewCounterparty(clientID, connectionID, prefix) + expectedConn := types.NewConnectionEnd(types.INIT, counterparty.ClientID, expectedCounterparty, counterpartyVersions) + + // chain B picks a version from Chain A's available versions that is compatible + // with the supported IBC versions + version := types.PickVersion(counterpartyVersions, types.GetCompatibleVersions()) + + // connection defines chain B's ConnectionEnd + connection := types.NewConnectionEnd(types.NONE, clientID, counterparty, []string{version}) + expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) + if err != nil { + return err + } + + ok := k.VerifyMembership( + ctx, connection, proofHeight, proofInit, + types.ConnectionPath(counterparty.ConnectionID), expConnBz, + ) + if !ok { + return errors.New("couldn't verify connection membership on counterparty's client") // TODO: sdk.Error + } + + // XXX: blocked by #5078 + /* + expConsStateBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConsensusState) + if err != nil { + return err + } + + ok = k.VerifyMembership( + ctx, connection, proofHeight, proofConsensus, + clienttypes.ConsensusStatePath(counterparty.ClientID), expConsStateBz, + ) + if !ok { + fmt.Sprintf("couldn't verify consensus state membership on counterparty's client\n") + return errors.New("couldn't verify consensus state membership on counterparty's client") // TODO: sdk.Error + } + + */ + + _, found := k.GetConnection(ctx, connectionID) + if found { + return sdkerrors.Wrap(types.ErrConnectionExists(k.codespace, connectionID), "cannot relay connection attempt") + } + + connection.State = types.TRYOPEN + err = k.addConnectionToClient(ctx, clientID, connectionID) + if err != nil { + return sdkerrors.Wrap(err, "cannot relay connection attempt") + } + + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: NONE -> TRYOPEN ", connectionID)) + return nil +} + +// ConnOpenAck relays acceptance of a connection open attempt from chain B back +// to chain A (this code is executed on chain A). +// +// NOTE: Identifiers are checked on msg validation. +func (k Keeper) ConnOpenAck( + ctx sdk.Context, + connectionID string, + version string, + proofTry commitment.ProofI, + proofConsensus commitment.ProofI, + proofHeight uint64, + consensusHeight uint64, +) error { + // XXX: blocked by #5078 + /* + if consensusHeight > uint64(ctx.BlockHeight()) { + return errors.New("invalid consensus height") // TODO: sdk.Error + } + */ + connection, found := k.GetConnection(ctx, connectionID) + if !found { + return sdkerrors.Wrap(types.ErrConnectionNotFound(k.codespace, connectionID), "cannot relay ACK of open attempt") + } + + if connection.State != types.INIT { + return types.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not INIT (got %s)", connection.State.String()), + ) + } + + if types.LatestVersion(connection.Versions) != version { + return types.ErrInvalidVersion( + k.codespace, + fmt.Sprintf("connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version), + ) + } + + // XXX: blocked by #5078 + /* + expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, connection.ClientID) + if !found { + return errors.New("client consensus state not found") // TODO: use ICS02 error + } + */ + prefix := k.GetCommitmentPrefix() + expectedCounterparty := types.NewCounterparty(connection.ClientID, connectionID, prefix) + expectedConn := types.NewConnectionEnd(types.TRYOPEN, connection.Counterparty.ClientID, expectedCounterparty, []string{version}) + + expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) + if err != nil { + return err + } + + ok := k.VerifyMembership( + ctx, connection, proofHeight, proofTry, + types.ConnectionPath(connection.Counterparty.ConnectionID), expConnBz, + ) + if !ok { + return errors.New("couldn't verify connection membership on counterparty's client") // TODO: sdk.Error + } + + // XXX: blocked by #5078 + /* + expConsStateBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConsensusState) + if err != nil { + return err + } + + ok = k.VerifyMembership( + ctx, connection, proofHeight, proofConsensus, + clienttypes.ConsensusStatePath(connection.Counterparty.ClientID), expConsStateBz, + ) + if !ok { + return errors.New("couldn't verify consensus state membership on counterparty's client") // TODO: sdk.Error + } + + */ + connection.State = types.OPEN + connection.Versions = []string{version} + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: INIT -> OPEN ", connectionID)) + return nil +} + +// ConnOpenConfirm confirms opening of a connection on chain A to chain B, after +// which the connection is open on both chains (this code is executed on chain B). +// +// NOTE: Identifiers are checked on msg validation. +func (k Keeper) ConnOpenConfirm( + ctx sdk.Context, + connectionID string, + proofAck commitment.ProofI, + proofHeight uint64, +) error { + connection, found := k.GetConnection(ctx, connectionID) + if !found { + return sdkerrors.Wrap(types.ErrConnectionNotFound(k.codespace, connectionID), "cannot relay ACK of open attempt") + } + + if connection.State != types.TRYOPEN { + return types.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not TRYOPEN (got %s)", connection.State.String()), + ) + } + + prefix := k.GetCommitmentPrefix() + expectedCounterparty := types.NewCounterparty(connection.ClientID, connectionID, prefix) + expectedConn := types.NewConnectionEnd(types.OPEN, connection.Counterparty.ClientID, expectedCounterparty, connection.Versions) + + expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) + if err != nil { + return err + } + + ok := k.VerifyMembership( + ctx, connection, proofHeight, proofAck, + types.ConnectionPath(connection.Counterparty.ConnectionID), expConnBz, + ) + if !ok { + return types.ErrInvalidCounterpartyConnection(k.codespace) + } + + connection.State = types.OPEN + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: TRYOPEN -> OPEN ", connectionID)) + return nil +} diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go new file mode 100644 index 000000000000..1488c6c03ec7 --- /dev/null +++ b/x/ibc/03-connection/keeper/keeper.go @@ -0,0 +1,171 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// Keeper defines the IBC connection keeper +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store + + clientKeeper types.ClientKeeper +} + +// NewKeeper creates a new IBC connection Keeper instance +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, ck types.ClientKeeper) Keeper { + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/connection", + prefix: []byte{}, + // prefix: []byte(types.SubModuleName + "/"), // "connection/" + clientKeeper: ck, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName)) +} + +// GetCommitmentPrefix returns the IBC connection store prefix as a commitment +// Prefix +func (k Keeper) GetCommitmentPrefix() commitment.PrefixI { + return commitment.NewPrefix([]byte(k.storeKey.Name())) +} + +// GetConnection returns a connection with a particular identifier +func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyConnection(connectionID)) + if bz == nil { + return types.ConnectionEnd{}, false + } + + var connection types.ConnectionEnd + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &connection) + return connection, true +} + +// SetConnection sets a connection to the store +func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(connection) + store.Set(types.KeyConnection(connectionID), bz) +} + +// GetClientConnectionPaths returns all the connection paths stored under a +// particular client +func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyClientConnections(clientID)) + if bz == nil { + return nil, false + } + + var paths []string + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &paths) + return paths, true +} + +// SetClientConnectionPaths sets the connections paths for client +func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths []string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(paths) + store.Set(types.KeyClientConnections(clientID), bz) +} + +// addConnectionToClient is used to add a connection identifier to the set of +// connections associated with a client. +// +// CONTRACT: client must already exist +func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID string) sdk.Error { + conns, found := k.GetClientConnectionPaths(ctx, clientID) + if !found { + conns = []string{} + } + + conns = append(conns, connectionID) + k.SetClientConnectionPaths(ctx, clientID, conns) + return nil +} + +// removeConnectionFromClient is used to remove a connection identifier from the +// set of connections associated with a client. +// +// CONTRACT: client must already exist +func (k Keeper) removeConnectionFromClient(ctx sdk.Context, clientID, connectionID string) sdk.Error { + conns, found := k.GetClientConnectionPaths(ctx, clientID) + if !found { + return types.ErrClientConnectionPathsNotFound(k.codespace, clientID) + } + + conns, ok := host.RemovePath(conns, connectionID) + if !ok { + return types.ErrConnectionPath(k.codespace) + } + + k.SetClientConnectionPaths(ctx, clientID, conns) + return nil +} + +// VerifyMembership helper function for state membership verification +func (k Keeper) VerifyMembership( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + pathStr string, + value []byte, +) bool { + // FIXME: commented out for demo + /* + clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) + if !found { + return false + } + */ + path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) + if err != nil { + return false + } + + return k.clientKeeper.VerifyMembership(ctx, connection.ClientID, height, proof, path, value) +} + +// VerifyNonMembership helper function for state non-membership verification +func (k Keeper) VerifyNonMembership( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + pathStr string, +) bool { + // FIXME: commented out for demo + /* + clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) + if !found { + return false + } + */ + + path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) + if err != nil { + return false + } + + return k.clientKeeper.VerifyNonMembership(ctx, connection.ClientID, height, proof, path) +} diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go new file mode 100644 index 000000000000..85bb02559e78 --- /dev/null +++ b/x/ibc/03-connection/keeper/querier.go @@ -0,0 +1,54 @@ +package keeper + +import ( + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +// QuerierConnection defines the sdk.Querier to query a connection end +func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryConnectionParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + connection, found := k.GetConnection(ctx, params.ConnectionID) + if !found { + return nil, types.ErrConnectionNotFound(k.codespace, params.ConnectionID) + } + + bz, err := types.SubModuleCdc.MarshalJSON(connection) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} + +// QuerierClientConnections defines the sdk.Querier to query the client connections +func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryClientConnectionsParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + clientConnectionPaths, found := k.GetClientConnectionPaths(ctx, params.ClientID) + if !found { + return nil, types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID) + } + + bz, err := types.SubModuleCdc.MarshalJSON(clientConnectionPaths) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} diff --git a/x/ibc/03-connection/module.go b/x/ibc/03-connection/module.go new file mode 100644 index 000000000000..713ed04d6c6b --- /dev/null +++ b/x/ibc/03-connection/module.go @@ -0,0 +1,25 @@ +package connection + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/cli" +) + +// Name returns the IBC connection ICS name +func Name() string { + return SubModuleName +} + +// GetTxCmd returns the root tx command for the IBC connections. +func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + return cli.GetTxCmd(fmt.Sprintf("%s/%s", storeKey, SubModuleName), cdc) +} + +// GetQueryCmd returns no root query command for the IBC connections. +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + return cli.GetQueryCmd(fmt.Sprintf("%s/%s", queryRoute, SubModuleName), cdc) +} diff --git a/x/ibc/03-connection/types/codec.go b/x/ibc/03-connection/types/codec.go new file mode 100644 index 000000000000..23fb04e37a8f --- /dev/null +++ b/x/ibc/03-connection/types/codec.go @@ -0,0 +1,21 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" +) + +// SubModuleCdc defines the IBC connection codec. +var SubModuleCdc = codec.New() + +// RegisterCodec registers the IBC connection types +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterConcrete(MsgConnectionOpenInit{}, "ibc/connection/MsgConnectionOpenInit", nil) + cdc.RegisterConcrete(MsgConnectionOpenTry{}, "ibc/connection/MsgConnectionOpenTry", nil) + cdc.RegisterConcrete(MsgConnectionOpenAck{}, "ibc/connection/MsgConnectionOpenAck", nil) + cdc.RegisterConcrete(MsgConnectionOpenConfirm{}, "ibc/connection/MsgConnectionOpenConfirm", nil) + cdc.RegisterConcrete(ConnectionEnd{}, "ibc/connection/ConnectionEnd", nil) +} + +func init() { + RegisterCodec(SubModuleCdc) +} diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go new file mode 100644 index 000000000000..07eb0a25c6ac --- /dev/null +++ b/x/ibc/03-connection/types/connection.go @@ -0,0 +1,143 @@ +package types + +import ( + "encoding/json" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +// ICS03 - Connection Data Structures as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#data-structures + +// ConnectionEnd defines a stateful object on a chain connected to another separate +// one. +// NOTE: there must only be 2 defined ConnectionEnds to stablish a connection +// between two chains. +type ConnectionEnd struct { + State State `json:"state" yaml:"state"` + ClientID string `json:"client_id" yaml:"client_id"` + + // Counterparty chain associated with this connection. + Counterparty Counterparty `json:"counterparty" yaml:"counterparty"` + // Version is utilised to determine encodings or protocols for channels or + // packets utilising this connection. + Versions []string `json:"versions" yaml:"versions"` +} + +// NewConnectionEnd creates a new ConnectionEnd instance. +func NewConnectionEnd(state State, clientID string, counterparty Counterparty, versions []string) ConnectionEnd { + return ConnectionEnd{ + State: state, + ClientID: clientID, + Counterparty: counterparty, + Versions: versions, + } +} + +// TODO: create a custom JSON marshaler + +// Counterparty defines the counterparty chain associated with a connection end. +type Counterparty struct { + ClientID string `json:"client_id" yaml:"client_id"` + ConnectionID string `json:"connection_id" yaml:"connection_id"` + Prefix commitment.PrefixI `json:"prefix" yaml:"prefix"` +} + +// NewCounterparty creates a new Counterparty instance. +func NewCounterparty(clientID, connectionID string, prefix commitment.PrefixI) Counterparty { + return Counterparty{ + ClientID: clientID, + ConnectionID: connectionID, + Prefix: prefix, + } +} + +// ValidateBasic performs a basic validation check of the identifiers and prefix +func (c Counterparty) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(c.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty connection ID: %s", err.Error())) + } + if err := host.DefaultClientIdentifierValidator(c.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty client ID: %s", err.Error())) + } + if c.Prefix == nil || len(c.Prefix.Bytes()) == 0 { + return ErrInvalidCounterparty(DefaultCodespace, "invalid counterparty prefix") + } + return nil +} + +// State defines the state of a connection between two disctinct +// chains +type State byte + +// available connection states +const ( + NONE State = iota // default State + INIT + TRYOPEN + OPEN +) + +// string representation of the connection states +const ( + StateNone string = "NONE" + StateInit string = "INIT" + StateTryOpen string = "TRYOPEN" + StateOpen string = "OPEN" +) + +// String implements the Stringer interface +func (cs State) String() string { + switch cs { + case NONE: + return StateNone + case INIT: + return StateInit + case TRYOPEN: + return StateTryOpen + case OPEN: + return StateOpen + default: + return "" + } +} + +// StateFromString parses a string into a connection state +func StateFromString(state string) (State, error) { + switch state { + case StateNone: + return NONE, nil + case StateInit: + return INIT, nil + case StateTryOpen: + return TRYOPEN, nil + case StateOpen: + return OPEN, nil + default: + return NONE, fmt.Errorf("'%s' is not a valid connection state", state) + } +} + +// MarshalJSON marshal to JSON using string. +func (cs State) MarshalJSON() ([]byte, error) { + return json.Marshal(cs.String()) +} + +// UnmarshalJSON decodes from JSON assuming Bech32 encoding. +func (cs *State) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + bz2, err := StateFromString(s) + if err != nil { + return err + } + + *cs = bz2 + return nil +} diff --git a/x/ibc/03-connection/types/errors.go b/x/ibc/03-connection/types/errors.go new file mode 100644 index 000000000000..b2a2cbe2ad5f --- /dev/null +++ b/x/ibc/03-connection/types/errors.go @@ -0,0 +1,73 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// connection error codes +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName + + CodeConnectionExists sdk.CodeType = 101 + CodeConnectionNotFound sdk.CodeType = 102 + CodeClientConnectionPathsNotFound sdk.CodeType = 103 + CodeConnectionPath sdk.CodeType = 104 + CodeInvalidCounterpartyConnection sdk.CodeType = 105 + CodeInvalidVersion sdk.CodeType = 106 + CodeInvalidHeight sdk.CodeType = 107 + CodeInvalidConnectionState sdk.CodeType = 108 + CodeInvalidProof sdk.CodeType = 109 + CodeInvalidCounterparty sdk.CodeType = 110 +) + +// ErrConnectionExists implements sdk.Error +func ErrConnectionExists(codespace sdk.CodespaceType, connectionID string) sdk.Error { + return sdk.NewError(codespace, CodeConnectionExists, fmt.Sprintf("connection with ID %s already exists", connectionID)) +} + +// ErrConnectionNotFound implements sdk.Error +func ErrConnectionNotFound(codespace sdk.CodespaceType, connectionID string) sdk.Error { + return sdk.NewError(codespace, CodeConnectionNotFound, fmt.Sprintf("connection with ID %s not found", connectionID)) +} + +// ErrClientConnectionPathsNotFound implements sdk.Error +func ErrClientConnectionPathsNotFound(codespace sdk.CodespaceType, clientID string) sdk.Error { + return sdk.NewError(codespace, CodeClientConnectionPathsNotFound, fmt.Sprintf("client connection paths not found for ID %s", clientID)) +} + +// ErrConnectionPath implements sdk.Error +func ErrConnectionPath(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeConnectionPath, "connection path is not associated to the client") +} + +// ErrInvalidCounterpartyConnection implements sdk.Error +func ErrInvalidCounterpartyConnection(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidCounterpartyConnection, "couldn't verify connection membership on counterparty's client") +} + +// ErrInvalidVersion implements sdk.Error +func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidVersion, msg) +} + +// ErrInvalidHeight implements sdk.Error +func ErrInvalidHeight(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidHeight, msg) +} + +// ErrInvalidConnectionState implements sdk.Error +func ErrInvalidConnectionState(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidConnectionState, msg) +} + +// ErrInvalidConnectionProof implements sdk.Error +func ErrInvalidConnectionProof(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidProof, msg) +} + +// ErrInvalidCounterparty implements sdk.Error +func ErrInvalidCounterparty(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidCounterparty, msg) +} diff --git a/x/ibc/03-connection/types/events.go b/x/ibc/03-connection/types/events.go new file mode 100644 index 000000000000..2ede46db907c --- /dev/null +++ b/x/ibc/03-connection/types/events.go @@ -0,0 +1,23 @@ +package types + +import ( + "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// IBC connection events +const ( + AttributeKeyConnectionID = "connection_id" + AttributeKeyCounterpartyClientID = "counterparty_client_id" +) + +// IBC connection events vars +var ( + EventTypeConnectionOpenInit = MsgConnectionOpenInit{}.Type() + EventTypeConnectionOpenTry = MsgConnectionOpenTry{}.Type() + EventTypeConnectionOpenAck = MsgConnectionOpenAck{}.Type() + EventTypeConnectionOpenConfirm = MsgConnectionOpenConfirm{}.Type() + + AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) +) diff --git a/x/ibc/03-connection/types/expected_keepers.go b/x/ibc/03-connection/types/expected_keepers.go new file mode 100644 index 000000000000..1a114f6f8374 --- /dev/null +++ b/x/ibc/03-connection/types/expected_keepers.go @@ -0,0 +1,22 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// ClientKeeper expected account IBC client keeper +type ClientKeeper interface { + GetConsensusState(ctx sdk.Context, clientID string) (clientexported.ConsensusState, bool) + GetClientState(ctx sdk.Context, clientID string) (client.State, bool) + VerifyMembership( + ctx sdk.Context, clientID string, height uint64, + proof commitment.ProofI, path commitment.PathI, value []byte, + ) bool + VerifyNonMembership( + ctx sdk.Context, clientID string, height uint64, + proof commitment.ProofI, path commitment.PathI, + ) bool +} diff --git a/x/ibc/03-connection/types/keys.go b/x/ibc/03-connection/types/keys.go new file mode 100644 index 000000000000..7dd82ae80a2e --- /dev/null +++ b/x/ibc/03-connection/types/keys.go @@ -0,0 +1,41 @@ +package types + +import ( + "fmt" +) + +const ( + // SubModuleName defines the IBC connection name + SubModuleName = "connection" + + // StoreKey is the store key string for IBC connections + StoreKey = SubModuleName + + // RouterKey is the message route for IBC connections + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC connections + QuerierRoute = SubModuleName +) + +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths + +// ConnectionPath defines the path under which connection paths are stored +func ConnectionPath(connectionID string) string { + return fmt.Sprintf("connections/%s", connectionID) +} + +// ClientConnectionsPath defines a reverse mapping from clients to a set of connections +func ClientConnectionsPath(clientID string) string { + return fmt.Sprintf("clients/%s/connections", clientID) +} + +// KeyConnection returns the store key for a particular connection +func KeyConnection(connectionID string) []byte { + return []byte(ConnectionPath(connectionID)) +} + +// KeyClientConnections returns the store key for the connectios of a given client +func KeyClientConnections(clientID string) []byte { + return []byte(ClientConnectionsPath(clientID)) +} diff --git a/x/ibc/03-connection/types/msgs.go b/x/ibc/03-connection/types/msgs.go new file mode 100644 index 000000000000..10ede21b1124 --- /dev/null +++ b/x/ibc/03-connection/types/msgs.go @@ -0,0 +1,300 @@ +package types + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +var _ sdk.Msg = MsgConnectionOpenInit{} + +// MsgConnectionOpenInit defines the msg sent by an account on Chain A to +// initialize a connection with Chain B. +type MsgConnectionOpenInit struct { + ConnectionID string `json:"connection_id"` + ClientID string `json:"client_id"` + Counterparty Counterparty `json:"counterparty"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance +func NewMsgConnectionOpenInit( + connectionID, clientID, counterpartyConnectionID, + counterpartyClientID string, counterpartyPrefix commitment.PrefixI, + signer sdk.AccAddress, +) MsgConnectionOpenInit { + counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) + return MsgConnectionOpenInit{ + ConnectionID: connectionID, + ClientID: clientID, + Counterparty: counterparty, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgConnectionOpenInit) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgConnectionOpenInit) Type() string { + return "connection_open_init" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgConnectionOpenInit) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + } + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("missing signer address") + } + return msg.Counterparty.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgConnectionOpenInit) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgConnectionOpenInit) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgConnectionOpenTry{} + +// MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a connection +// on Chain B. +type MsgConnectionOpenTry struct { + ConnectionID string `json:"connection_id"` + ClientID string `json:"client_id"` + Counterparty Counterparty `json:"counterparty"` + CounterpartyVersions []string `json:"counterparty_versions"` + ProofInit commitment.ProofI `json:"proof_init"` // proof of the initialization the connection on Chain A: `none -> INIT` + ProofConsensus commitment.ProofI `json:"proof_consensus"` // proof of client consensus state + ProofHeight uint64 `json:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgConnectionOpenTry creates a new MsgConnectionOpenTry instance +func NewMsgConnectionOpenTry( + connectionID, clientID, counterpartyConnectionID, + counterpartyClientID string, counterpartyPrefix commitment.PrefixI, + counterpartyVersions []string, proofInit, proofConsensus commitment.ProofI, + proofHeight, consensusHeight uint64, signer sdk.AccAddress, +) MsgConnectionOpenTry { + counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) + return MsgConnectionOpenTry{ + ConnectionID: connectionID, + ClientID: clientID, + Counterparty: counterparty, + CounterpartyVersions: counterpartyVersions, + ProofInit: proofInit, + ProofConsensus: proofConsensus, + ProofHeight: proofHeight, + ConsensusHeight: consensusHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgConnectionOpenTry) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgConnectionOpenTry) Type() string { + return "connection_open_try" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgConnectionOpenTry) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + } + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if len(msg.CounterpartyVersions) == 0 { + return ErrInvalidVersion(DefaultCodespace, "missing counterparty versions") + } + for _, version := range msg.CounterpartyVersions { + if strings.TrimSpace(version) == "" { + return ErrInvalidVersion(DefaultCodespace, "version can't be blank") + } + } + if msg.ProofInit == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof init cannot be nil") + } + if msg.ProofConsensus == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof consensus cannot be nil") + } + if msg.ProofHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + } + if msg.ConsensusHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0") + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("missing signer address") + } + return msg.Counterparty.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgConnectionOpenTry) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgConnectionOpenTry) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgConnectionOpenAck{} + +// MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to acknowledge +// the change of connection state to TRYOPEN on Chain B. +type MsgConnectionOpenAck struct { + ConnectionID string `json:"connection_id"` + ProofTry commitment.ProofI `json:"proof_try"` // proof for the change of the connection state on Chain B: `none -> TRYOPEN` + ProofConsensus commitment.ProofI `json:"proof_consensus"` // proof of client consensus state + ProofHeight uint64 `json:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height"` + Version string `json:"version"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgConnectionOpenAck creates a new MsgConnectionOpenAck instance +func NewMsgConnectionOpenAck( + connectionID string, proofTry, proofConsensus commitment.ProofI, + proofHeight, consensusHeight uint64, version string, + signer sdk.AccAddress, +) MsgConnectionOpenAck { + return MsgConnectionOpenAck{ + ConnectionID: connectionID, + ProofTry: proofTry, + ProofConsensus: proofConsensus, + ProofHeight: proofHeight, + ConsensusHeight: consensusHeight, + Version: version, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgConnectionOpenAck) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgConnectionOpenAck) Type() string { + return "connection_open_ack" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgConnectionOpenAck) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + } + if strings.TrimSpace(msg.Version) == "" { + return ErrInvalidVersion(DefaultCodespace, "version can't be blank") + } + if msg.ProofTry == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof try cannot be nil") + } + if msg.ProofConsensus == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof consensus cannot be nil") + } + if msg.ProofHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + } + if msg.ConsensusHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0") + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("missing signer address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgConnectionOpenAck) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgConnectionOpenAck) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgConnectionOpenConfirm{} + +// MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to acknowledge +// the change of connection state to OPEN on Chain A. +type MsgConnectionOpenConfirm struct { + ConnectionID string `json:"connection_id"` + ProofAck commitment.ProofI `json:"proof_ack"` // proof for the change of the connection state on Chain A: `INIT -> OPEN` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgConnectionOpenConfirm creates a new MsgConnectionOpenConfirm instance +func NewMsgConnectionOpenConfirm( + connectionID string, proofAck commitment.ProofI, proofHeight uint64, signer sdk.AccAddress, +) MsgConnectionOpenConfirm { + return MsgConnectionOpenConfirm{ + ConnectionID: connectionID, + ProofAck: proofAck, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgConnectionOpenConfirm) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgConnectionOpenConfirm) Type() string { + return "connection_open_confirm" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgConnectionOpenConfirm) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + } + if msg.ProofAck == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof ack cannot be nil") + } + if msg.ProofHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + } + + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("missing signer address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgConnectionOpenConfirm) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgConnectionOpenConfirm) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/03-connection/types/querier.go b/x/ibc/03-connection/types/querier.go new file mode 100644 index 000000000000..6fbb151342f4 --- /dev/null +++ b/x/ibc/03-connection/types/querier.go @@ -0,0 +1,83 @@ +package types + +import ( + "strings" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/tendermint/tendermint/crypto/merkle" +) + +// query routes supported by the IBC connection Querier +const ( + QueryConnection = "connection" + QueryClientConnections = "client_connections" +) + +// ConnectionResponse defines the client query response for a connection which +// also includes a proof and the height from which the proof was retrieved. +type ConnectionResponse struct { + Connection ConnectionEnd `json:"connection" yaml:"connection"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewConnectionResponse creates a new ConnectionResponse instance +func NewConnectionResponse( + connectionID string, connection ConnectionEnd, proof *merkle.Proof, height int64, +) ConnectionResponse { + return ConnectionResponse{ + Connection: connection, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ConnectionPath(connectionID), "/")), + ProofHeight: uint64(height), + } +} + +// QueryConnectionParams defines the params for the following queries: +// - 'custom/ibc/connections/' +type QueryConnectionParams struct { + ConnectionID string +} + +// NewQueryConnectionParams creates a new QueryConnectionParams instance +func NewQueryConnectionParams(clientID string) QueryConnectionParams { + return QueryConnectionParams{ + ConnectionID: clientID, + } +} + +// ClientConnectionsResponse defines the client query response for a client +// connection paths which also includes a proof and the height from which the +// proof was retrieved. +type ClientConnectionsResponse struct { + ConnectionPaths []string `json:"connection_paths" yaml:"connection_paths"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewClientConnectionsResponse creates a new ConnectionPaths instance +func NewClientConnectionsResponse( + clientID string, connectionPaths []string, proof *merkle.Proof, height int64, +) ClientConnectionsResponse { + return ClientConnectionsResponse{ + ConnectionPaths: connectionPaths, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ClientConnectionsPath(clientID), "/")), + ProofHeight: uint64(height), + } +} + +// QueryClientConnectionsParams defines the params for the following queries: +// - 'custom/ibc/client//connections' +type QueryClientConnectionsParams struct { + ClientID string +} + +// NewQueryClientConnectionsParams creates a new QueryClientConnectionsParams instance +func NewQueryClientConnectionsParams(clientID string) QueryClientConnectionsParams { + return QueryClientConnectionsParams{ + ClientID: clientID, + } +} diff --git a/x/ibc/03-connection/types/version.go b/x/ibc/03-connection/types/version.go new file mode 100644 index 000000000000..bf74a52dae92 --- /dev/null +++ b/x/ibc/03-connection/types/version.go @@ -0,0 +1,96 @@ +package types + +// GetCompatibleVersions returns an ordered set of compatible IBC versions for the +// caller chain's connection end. +func GetCompatibleVersions() []string { + return []string{"1.0.0"} +} + +// LatestVersion gets the latest version of a connection protocol +// +// CONTRACT: version array MUST be already sorted. +func LatestVersion(versions []string) string { + if len(versions) == 0 { + return "" + } + return versions[len(versions)-1] +} + +// PickVersion picks the counterparty latest version that is matches the list +// of compatible versions for the connection. +func PickVersion(counterpartyVersions, compatibleVersions []string) string { + + n := len(counterpartyVersions) + m := len(compatibleVersions) + + // aux hash maps to lookup already seen versions + counterpartyVerLookup := make(map[string]bool) + compatibleVerLookup := make(map[string]bool) + + // versions suported + var supportedVersions []string + + switch { + case n == 0 || m == 0: + return "" + case n == m: + for i := n - 1; i >= 0; i-- { + counterpartyVerLookup[counterpartyVersions[i]] = true + compatibleVerLookup[compatibleVersions[i]] = true + + // check if we've seen any of the versions + if _, ok := compatibleVerLookup[counterpartyVersions[i]]; ok { + supportedVersions = append(supportedVersions, counterpartyVersions[i]) + } + + if _, ok := counterpartyVerLookup[compatibleVersions[i]]; ok { + // TODO: check if the version is already in the array + supportedVersions = append(supportedVersions, compatibleVersions[i]) + } + } + case n > m: + for i := n - 1; i >= m; i-- { + counterpartyVerLookup[compatibleVersions[i]] = true + } + + for i := m - 1; i >= 0; i-- { + counterpartyVerLookup[counterpartyVersions[i]] = true + compatibleVerLookup[compatibleVersions[i]] = true + + // check if we've seen any of the versions + if _, ok := compatibleVerLookup[counterpartyVersions[i]]; ok { + supportedVersions = append(supportedVersions, counterpartyVersions[i]) + } + + if _, ok := counterpartyVerLookup[compatibleVersions[i]]; ok { + supportedVersions = append(supportedVersions, compatibleVersions[i]) + } + } + + case n < m: + for i := m - 1; i >= n; i-- { + compatibleVerLookup[compatibleVersions[i]] = true + } + + for i := n - 1; i >= 0; i-- { + counterpartyVerLookup[counterpartyVersions[i]] = true + compatibleVerLookup[compatibleVersions[i]] = true + + // check if we've seen any of the versions + if _, ok := compatibleVerLookup[counterpartyVersions[i]]; ok { + supportedVersions = append(supportedVersions, counterpartyVersions[i]) + } + + if _, ok := counterpartyVerLookup[compatibleVersions[i]]; ok { + supportedVersions = append(supportedVersions, compatibleVersions[i]) + } + } + } + + if len(supportedVersions) == 0 { + return "" + } + + // TODO: compare latest version before appending + return supportedVersions[len(supportedVersions)-1] +} diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index 5657d2aad3c7..04289628f640 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -21,6 +22,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ibcTxCmd.AddCommand(client.PostCommands( ibcclient.GetTxCmd(cdc, storeKey), + connection.GetTxCmd(cdc, storeKey), )...) return ibcTxCmd } @@ -38,6 +40,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { ibcQueryCmd.AddCommand(client.GetCommands( ibcclient.GetQueryCmd(cdc, queryRoute), + connection.GetQueryCmd(cdc, queryRoute), )...) return ibcQueryCmd } diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 5dc802b6f063..ed740f39183e 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" ) // NewHandler defines the IBC handler @@ -22,8 +23,20 @@ func NewHandler(k Keeper) sdk.Handler { case client.MsgSubmitMisbehaviour: return client.HandleMsgSubmitMisbehaviour(ctx, k.ClientKeeper, msg) + case connection.MsgConnectionOpenInit: + return connection.HandleMsgConnectionOpenInit(ctx, k.ConnectionKeeper, msg) + + case connection.MsgConnectionOpenTry: + return connection.HandleMsgConnectionOpenTry(ctx, k.ConnectionKeeper, msg) + + case connection.MsgConnectionOpenAck: + return connection.HandleMsgConnectionOpenAck(ctx, k.ConnectionKeeper, msg) + + case connection.MsgConnectionOpenConfirm: + return connection.HandleMsgConnectionOpenConfirm(ctx, k.ConnectionKeeper, msg) + default: - errMsg := fmt.Sprintf("unrecognized IBC Client message type: %T", msg) + errMsg := fmt.Sprintf("unrecognized IBC message type: %T", msg) return sdk.ErrUnknownRequest(errMsg).Result() } } diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index fce91fb353bd..dafe8892d167 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -4,16 +4,22 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" ) // Keeper defines each ICS keeper for IBC type Keeper struct { - ClientKeeper client.Keeper + ClientKeeper client.Keeper + ConnectionKeeper connection.Keeper } // NewKeeper creates a new ibc Keeper func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { + clientKeeper := client.NewKeeper(cdc, key, codespace) + connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) + return Keeper{ - ClientKeeper: client.NewKeeper(cdc, key, codespace), + ClientKeeper: clientKeeper, + ConnectionKeeper: connectionKeeper, } } diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index 7cbd4ec9c499..43db6f574dc0 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -1,24 +1,43 @@ package keeper import ( + "fmt" + abci "github.com/tendermint/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" ) // NewQuerier creates a querier for the IBC module func NewQuerier(k Keeper) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { switch path[0] { - case client.QueryClientState: - return client.QuerierClientState(ctx, req, k.ClientKeeper) - case client.QueryConsensusState: - return client.QuerierConsensusState(ctx, req, k.ClientKeeper) - case client.QueryVerifiedRoot: - return client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) + case client.SubModuleName: + switch path[1] { + case client.QueryClientState: + return client.QuerierClientState(ctx, req, k.ClientKeeper) + case client.QueryConsensusState: + return client.QuerierConsensusState(ctx, req, k.ClientKeeper) + case client.QueryVerifiedRoot: + return client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) + default: + return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName)) + } + + case connection.SubModuleName: + switch path[1] { + case connection.QueryConnection: + return connection.QuerierConnection(ctx, req, k.ConnectionKeeper) + case connection.QueryClientConnections: + return connection.QuerierClientConnections(ctx, req, k.ConnectionKeeper) + default: + return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName)) + } + default: - return nil, sdk.ErrUnknownRequest("unknown IBC client query endpoint") + return nil, sdk.ErrUnknownRequest("unknown IBC query endpoint") } } } diff --git a/x/ibc/module.go b/x/ibc/module.go index 675b18aa1ddf..21ba001210de 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -13,6 +13,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -37,6 +38,7 @@ func (AppModuleBasic) Name() string { // RegisterCodec registers the staking module's types for the given codec. func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) + connection.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } From 428241256bee808532804ee9afbde98bdf522f67 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 5 Nov 2019 18:04:49 +0100 Subject: [PATCH 005/176] ICS 05 implementation (#5193) * fix lint * fix lint * add handler/msgs/client * rm relay * finalize rebase on 23 root/path sep * fix lint, fix syntax * fix querying * extract out context withstore * fix 02-client test * fix 23-commitment test * add query in progress * rm freebase, reformat query * add cli/handler/msg in progress * add cli/msg/handler * add CLIQuery, fix tests * fix golangci * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * add godoc in progress * reformat test * rm XXX * add godoc * modify store * add query * update query.go * update query.go * cli refactor in progress * cli refactor in progress * add Query to boolean.go * fix key * fix cli / merkle test * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * fix test * fix client * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * fix dependency * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * rm commented lines * address review in progress * address review, rm cleanup/closing * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * start batch-verify tests * minor changes on commitment types * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * use testsuite * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * upstream changes --- store/types/store.go | 4 ++ types/store.go | 1 + x/ibc/05-port/alias.go | 39 +++++++++++++++++ x/ibc/05-port/keeper/keeper.go | 77 ++++++++++++++++++++++++++++++++++ x/ibc/05-port/types/errors.go | 37 ++++++++++++++++ x/ibc/05-port/types/keys.go | 31 ++++++++++++++ x/ibc/keeper/keeper.go | 4 ++ 7 files changed, 193 insertions(+) create mode 100644 x/ibc/05-port/alias.go create mode 100644 x/ibc/05-port/keeper/keeper.go create mode 100644 x/ibc/05-port/types/errors.go create mode 100644 x/ibc/05-port/types/keys.go diff --git a/store/types/store.go b/store/types/store.go index 5b5e64742552..bd8a3d58c85a 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -277,6 +277,10 @@ type StoreKey interface { String() string } +// CapabilityKey represent the Cosmos SDK keys for object-capability +// generation in the IBC protocol as defined in https://github.com/cosmos/ics/tree/master/spec/ics-005-port-allocation#data-structures +type CapabilityKey StoreKey + // KVStoreKey is used for accessing substores. // Only the pointer value should ever be used - it functions as a capabilities key. type KVStoreKey struct { diff --git a/types/store.go b/types/store.go index c34b6d437d09..db18b127b69d 100644 --- a/types/store.go +++ b/types/store.go @@ -69,6 +69,7 @@ const ( // nolint - reexport type ( StoreKey = types.StoreKey + CapabilityKey = types.CapabilityKey KVStoreKey = types.KVStoreKey TransientStoreKey = types.TransientStoreKey ) diff --git a/x/ibc/05-port/alias.go b/x/ibc/05-port/alias.go new file mode 100644 index 000000000000..a74c7fe61537 --- /dev/null +++ b/x/ibc/05-port/alias.go @@ -0,0 +1,39 @@ +package port + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/05-port/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/05-port/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" +) + +const ( + DefaultCodespace = types.DefaultCodespace + CodePortExists = types.CodePortExists + CodePortNotFound = types.CodePortNotFound + CodePortNotAuthenticated = types.CodePortNotAuthenticated + CodeInvalidPortID = types.CodeInvalidPortID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + ErrPortExists = types.ErrPortExists + ErrPortNotFound = types.ErrPortNotFound + ErrPortNotAuthenticated = types.ErrPortNotAuthenticated + ErrInvalidPortID = types.ErrInvalidPortID + PortPath = types.PortPath + KeyPort = types.KeyPort +) + +type ( + Keeper = keeper.Keeper +) diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go new file mode 100644 index 000000000000..5a7a9fb05bae --- /dev/null +++ b/x/ibc/05-port/keeper/keeper.go @@ -0,0 +1,77 @@ +package keeper + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +// Keeper defines the IBC connection keeper +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store + ports map[sdk.CapabilityKey]string + bound []string +} + +// NewKeeper creates a new IBC connection Keeper instance +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/port", + prefix: []byte{}, + // prefix: []byte(types.SubModuleName + "/"), // "port/" + ports: make(map[sdk.CapabilityKey]string), // map of capabilities to port ids + } +} + +// GetPorts returns the list of bound ports. +// (these ports still must have been bound statically) +func (k Keeper) GetPorts() []string { + return k.bound +} + +// GetPort retrieves a given port ID from keeper map +func (k Keeper) GetPort(ck sdk.CapabilityKey) (string, bool) { + portID, found := k.ports[ck] + return portID, found +} + +// BindPort binds to a port and returns the associated capability. +// Ports must be bound statically when the chain starts in `app.go`. +// The capability must then be passed to a module which will need to pass +// it as an extra parameter when calling functions on the IBC module. +func (k Keeper) BindPort(portID string) sdk.CapabilityKey { + if err := host.DefaultPortIdentifierValidator(portID); err != nil { + panic(err.Error()) + } + + for _, b := range k.bound { + if b == portID { + panic(fmt.Sprintf("port %s is already bound", portID)) + } + } + + key := sdk.NewKVStoreKey(portID) + k.ports[key] = portID + k.bound = append(k.bound, portID) + return key +} + +// Authenticate authenticates a capability key against a port ID +// by checking if the memory address of the capability was previously +// generated and bound to the port (provided as a parameter) which the capability +// is being authenticated against. +func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { + if err := host.DefaultPortIdentifierValidator(portID); err != nil { + panic(err.Error()) + } + + return k.ports[key] == portID +} diff --git a/x/ibc/05-port/types/errors.go b/x/ibc/05-port/types/errors.go new file mode 100644 index 000000000000..20031c826107 --- /dev/null +++ b/x/ibc/05-port/types/errors.go @@ -0,0 +1,37 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// port error codes +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName + + CodePortExists sdk.CodeType = 101 + CodePortNotFound sdk.CodeType = 102 + CodePortNotAuthenticated sdk.CodeType = 103 + CodeInvalidPortID sdk.CodeType = 104 +) + +// ErrPortExists implements sdk.Error +func ErrPortExists(codespace sdk.CodespaceType, portID string) sdk.Error { + return sdk.NewError(codespace, CodePortExists, fmt.Sprintf("port with ID %s is already binded", portID)) +} + +// ErrPortNotFound implements sdk.Error +func ErrPortNotFound(codespace sdk.CodespaceType, portID string) sdk.Error { + return sdk.NewError(codespace, CodePortNotFound, fmt.Sprintf("port with ID %s not found", portID)) +} + +// ErrPortNotAuthenticated implements sdk.Error +func ErrPortNotAuthenticated(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodePortNotAuthenticated, "port failed authentication") +} + +// ErrInvalidPortID implements sdk.Error +func ErrInvalidPortID(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidPortID, "invalid port ID") +} diff --git a/x/ibc/05-port/types/keys.go b/x/ibc/05-port/types/keys.go new file mode 100644 index 000000000000..b1250e0e4463 --- /dev/null +++ b/x/ibc/05-port/types/keys.go @@ -0,0 +1,31 @@ +package types + +import ( + "fmt" +) + +const ( + // SubModuleName defines the IBC port name + SubModuleName = "port" + + // StoreKey is the store key string for IBC ports + StoreKey = SubModuleName + + // RouterKey is the message route for IBC ports + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC ports + QuerierRoute = SubModuleName +) + +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-005-port-allocation#store-paths + +// PortPath defines the path under which ports paths are stored +func PortPath(portID string) string { + return fmt.Sprintf("ports/%s", portID) +} + +// KeyPort returns the store key for a particular port +func KeyPort(portID string) []byte { + return []byte(PortPath(portID)) +} diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index dafe8892d167..c9708a6e79a1 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -5,21 +5,25 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" ) // Keeper defines each ICS keeper for IBC type Keeper struct { ClientKeeper client.Keeper ConnectionKeeper connection.Keeper + PortKeeper port.Keeper } // NewKeeper creates a new ibc Keeper func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { clientKeeper := client.NewKeeper(cdc, key, codespace) connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) + portKeeper := port.NewKeeper(cdc, key, codespace) return Keeper{ ClientKeeper: clientKeeper, ConnectionKeeper: connectionKeeper, + PortKeeper: portKeeper, } } From 87d09fd22014bd539ac59d267c4973bca4da7fb4 Mon Sep 17 00:00:00 2001 From: Joon Date: Tue, 5 Nov 2019 09:08:55 -0800 Subject: [PATCH 006/176] ICS 04 Implementation (#4548) * merge from ics04 branch * merge from ics04 branch * fix lint * add port * fix test * add mocks * fix connid -> portid in handshake.go * add mock * add ibc module.go, finalize mock * add keeper * add StoreKey const * fix test * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix cli errors * fix dependency * fix dependency * reflect method name change * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * reflect downstream changes * fix from address in tx cli * fix cli in progress(squash later) * fix cli * remove timeout, add channel cli * fix golangci * fix cli * Clean up * fix mock cli in progress * finalize cleanup, mock cli wip * add cli for mocksend * fix handler * rm commented lines * address review in progress * address review, rm cleanup/closing * rename mock packages * fix interface for gaia * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * update test * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * refactor: remove store accessors, update keeper and types to match spec (WIP) * update handshake and packet * implement packet timeouts * implement send and receive packet * implement packet ACK * update handler * add channel errors * channel querier * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update ICS04 with downstream changes * Implement tx cli actions * add MsgSendPacket handler; msg validation, errors and events * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * rm legacy tests; add query proofs support * remove capability key generation and authentication logic * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * downstream changes; custom marshal JSON; msg validation, and update errors * update errors and aliases * start batch-verify tests * update msg validation and CLI UX * minor changes on commitment types * fix channel and packet check (#5243) * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * authenticate port ID; remove send packet msg from CLI * comment out handlers * use testsuite * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * upstream changes * upstream changes --- x/ibc/04-channel/alias.go | 123 +++++ x/ibc/04-channel/client/cli/query.go | 55 +++ x/ibc/04-channel/client/cli/tx.go | 535 +++++++++++++++++++++ x/ibc/04-channel/client/utils/utils.go | 70 +++ x/ibc/04-channel/exported/exported.go | 16 + x/ibc/04-channel/handler.go | 153 ++++++ x/ibc/04-channel/keeper/handshake.go | 410 ++++++++++++++++ x/ibc/04-channel/keeper/keeper.go | 146 ++++++ x/ibc/04-channel/keeper/packet.go | 357 ++++++++++++++ x/ibc/04-channel/keeper/querier.go | 32 ++ x/ibc/04-channel/keeper/timeout.go | 195 ++++++++ x/ibc/04-channel/module.go | 25 + x/ibc/04-channel/types/channel.go | 225 +++++++++ x/ibc/04-channel/types/codec.go | 28 ++ x/ibc/04-channel/types/errors.go | 73 +++ x/ibc/04-channel/types/events.go | 27 ++ x/ibc/04-channel/types/expected_keepers.go | 31 ++ x/ibc/04-channel/types/keys.go | 85 ++++ x/ibc/04-channel/types/msgs.go | 379 +++++++++++++++ x/ibc/04-channel/types/packet.go | 108 +++++ x/ibc/04-channel/types/querier.go | 71 +++ x/ibc/handler.go | 22 + x/ibc/keeper/keeper.go | 4 + x/ibc/keeper/querier.go | 9 + x/ibc/module.go | 2 + 25 files changed, 3181 insertions(+) create mode 100644 x/ibc/04-channel/alias.go create mode 100644 x/ibc/04-channel/client/cli/query.go create mode 100644 x/ibc/04-channel/client/cli/tx.go create mode 100644 x/ibc/04-channel/client/utils/utils.go create mode 100644 x/ibc/04-channel/exported/exported.go create mode 100644 x/ibc/04-channel/handler.go create mode 100644 x/ibc/04-channel/keeper/handshake.go create mode 100644 x/ibc/04-channel/keeper/keeper.go create mode 100644 x/ibc/04-channel/keeper/packet.go create mode 100644 x/ibc/04-channel/keeper/querier.go create mode 100644 x/ibc/04-channel/keeper/timeout.go create mode 100644 x/ibc/04-channel/module.go create mode 100644 x/ibc/04-channel/types/channel.go create mode 100644 x/ibc/04-channel/types/codec.go create mode 100644 x/ibc/04-channel/types/errors.go create mode 100644 x/ibc/04-channel/types/events.go create mode 100644 x/ibc/04-channel/types/expected_keepers.go create mode 100644 x/ibc/04-channel/types/keys.go create mode 100644 x/ibc/04-channel/types/msgs.go create mode 100644 x/ibc/04-channel/types/packet.go create mode 100644 x/ibc/04-channel/types/querier.go diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go new file mode 100644 index 000000000000..25f73b478565 --- /dev/null +++ b/x/ibc/04-channel/alias.go @@ -0,0 +1,123 @@ +package channel + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +const ( + NONE = types.NONE + UNORDERED = types.UNORDERED + ORDERED = types.ORDERED + OrderNone = types.OrderNone + OrderUnordered = types.OrderUnordered + OrderOrdered = types.OrderOrdered + CLOSED = types.CLOSED + INIT = types.INIT + OPENTRY = types.OPENTRY + OPEN = types.OPEN + StateClosed = types.StateClosed + StateInit = types.StateInit + StateOpenTry = types.StateOpenTry + StateOpen = types.StateOpen + DefaultCodespace = types.DefaultCodespace + CodeChannelExists = types.CodeChannelExists + CodeChannelNotFound = types.CodeChannelNotFound + CodeInvalidCounterpartyChannel = types.CodeInvalidCounterpartyChannel + CodeChannelCapabilityNotFound = types.CodeChannelCapabilityNotFound + CodeInvalidPacket = types.CodeInvalidPacket + CodeSequenceNotFound = types.CodeSequenceNotFound + CodePacketTimeout = types.CodePacketTimeout + CodeInvalidChannel = types.CodeInvalidChannel + CodeInvalidChannelState = types.CodeInvalidChannelState + CodeInvalidChannelProof = types.CodeInvalidChannelProof + AttributeKeySenderPort = types.AttributeKeySenderPort + AttributeKeyReceiverPort = types.AttributeKeyReceiverPort + AttributeKeyChannelID = types.AttributeKeyChannelID + AttributeKeySequence = types.AttributeKeySequence + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryChannel = types.QueryChannel +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + QuerierChannel = keeper.QuerierChannel + NewChannel = types.NewChannel + NewCounterparty = types.NewCounterparty + OrderFromString = types.OrderFromString + StateFromString = types.StateFromString + RegisterCodec = types.RegisterCodec + ErrChannelExists = types.ErrChannelExists + ErrChannelNotFound = types.ErrChannelNotFound + ErrInvalidCounterpartyChannel = types.ErrInvalidCounterpartyChannel + ErrChannelCapabilityNotFound = types.ErrChannelCapabilityNotFound + ErrInvalidPacket = types.ErrInvalidPacket + ErrSequenceNotFound = types.ErrSequenceNotFound + ErrPacketTimeout = types.ErrPacketTimeout + ErrInvalidChannel = types.ErrInvalidChannel + ErrInvalidChannelState = types.ErrInvalidChannelState + ErrInvalidChannelProof = types.ErrInvalidChannelProof + ChannelPath = types.ChannelPath + ChannelCapabilityPath = types.ChannelCapabilityPath + NextSequenceSendPath = types.NextSequenceSendPath + NextSequenceRecvPath = types.NextSequenceRecvPath + PacketCommitmentPath = types.PacketCommitmentPath + PacketAcknowledgementPath = types.PacketAcknowledgementPath + KeyChannel = types.KeyChannel + KeyChannelCapabilityPath = types.KeyChannelCapabilityPath + KeyNextSequenceSend = types.KeyNextSequenceSend + KeyNextSequenceRecv = types.KeyNextSequenceRecv + KeyPacketCommitment = types.KeyPacketCommitment + KeyPacketAcknowledgement = types.KeyPacketAcknowledgement + NewMsgChannelOpenInit = types.NewMsgChannelOpenInit + NewMsgChannelOpenTry = types.NewMsgChannelOpenTry + NewMsgChannelOpenAck = types.NewMsgChannelOpenAck + NewMsgChannelOpenConfirm = types.NewMsgChannelOpenConfirm + NewMsgChannelCloseInit = types.NewMsgChannelCloseInit + NewMsgChannelCloseConfirm = types.NewMsgChannelCloseConfirm + NewPacket = types.NewPacket + NewOpaquePacket = types.NewOpaquePacket + NewChannelResponse = types.NewChannelResponse + NewQueryChannelParams = types.NewQueryChannelParams + + // variable aliases + SubModuleCdc = types.SubModuleCdc + EventTypeChannelOpenInit = types.EventTypeChannelOpenInit + EventTypeChannelOpenTry = types.EventTypeChannelOpenTry + EventTypeChannelOpenAck = types.EventTypeChannelOpenAck + EventTypeChannelOpenConfirm = types.EventTypeChannelOpenConfirm + EventTypeChannelCloseInit = types.EventTypeChannelCloseInit + EventTypeChannelCloseConfirm = types.EventTypeChannelCloseConfirm + AttributeValueCategory = types.AttributeValueCategory +) + +type ( + Keeper = keeper.Keeper + Channel = types.Channel + Counterparty = types.Counterparty + Order = types.Order + State = types.State + ClientKeeper = types.ClientKeeper + ConnectionKeeper = types.ConnectionKeeper + PortKeeper = types.PortKeeper + MsgChannelOpenInit = types.MsgChannelOpenInit + MsgChannelOpenTry = types.MsgChannelOpenTry + MsgChannelOpenAck = types.MsgChannelOpenAck + MsgChannelOpenConfirm = types.MsgChannelOpenConfirm + MsgChannelCloseInit = types.MsgChannelCloseInit + MsgChannelCloseConfirm = types.MsgChannelCloseConfirm + Packet = types.Packet + OpaquePacket = types.OpaquePacket + ChannelResponse = types.ChannelResponse + QueryChannelParams = types.QueryChannelParams +) diff --git a/x/ibc/04-channel/client/cli/query.go b/x/ibc/04-channel/client/cli/query.go new file mode 100644 index 000000000000..04bfcfcbbe92 --- /dev/null +++ b/x/ibc/04-channel/client/cli/query.go @@ -0,0 +1,55 @@ +package cli + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + + cli "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" +) + +// GetQueryCmd returns the query commands for IBC channels +func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics04ChannelQueryCmd := &cobra.Command{ + Use: "channel", + Short: "IBC channel query subcommands", + DisableFlagParsing: true, + } + + ics04ChannelQueryCmd.AddCommand(cli.GetCommands( + GetCmdQueryChannel(storeKey, cdc), + )...) + + return ics04ChannelQueryCmd +} + +// GetCmdQueryChannel defines the command to query a channel end +func GetCmdQueryChannel(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "end [port-id] [channel-id]", + Short: "Query a channel end", + Long: strings.TrimSpace(fmt.Sprintf(`Query an IBC channel end + +Example: +$ %s query ibc channel end [port-id] [channel-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + + ch, err := utils.QueryChannel(cliCtx, args[0], args[1], queryRoute) + if err != nil { + return err + } + + return cliCtx.PrintOutput(ch) + }, + } + return cmd +} diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go new file mode 100644 index 000000000000..833ed29af01c --- /dev/null +++ b/x/ibc/04-channel/client/cli/tx.go @@ -0,0 +1,535 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + "time" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + abci "github.com/tendermint/tendermint/abci/types" +) + +const ( + FlagOrdered = "ordered" + FlagIBCVersion = "ibc-version" + FlagNode1 = "node1" + FlagNode2 = "node2" + FlagFrom1 = "from1" + FlagFrom2 = "from2" + FlagChainID2 = "chain-id2" +) + +// GetTxCmd returns the transaction commands for IBC Connections +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics04ChannelTxCmd := &cobra.Command{ + Use: "channel", + Short: "IBC channel transaction subcommands", + } + + ics04ChannelTxCmd.AddCommand(client.PostCommands( + GetMsgChannelOpenInitCmd(storeKey, cdc), + GetMsgChannelOpenTryCmd(storeKey, cdc), + GetMsgChannelOpenAckCmd(storeKey, cdc), + GetMsgChannelOpenConfirmCmd(storeKey, cdc), + GetMsgChannelCloseInitCmd(storeKey, cdc), + GetMsgChannelCloseConfirmCmd(storeKey, cdc), + GetCmdHandshake(storeKey, cdc), + )...) + + return ics04ChannelTxCmd +} + +// TODO: module needs to pass the capability key (i.e store key) + +// GetMsgChannelOpenInitCmd returns the command to create a MsgChannelOpenInit transaction +func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-init [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops]", + Short: "Creates and sends a ChannelOpenInit message", + Args: cobra.ExactArgs(5), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + counterpartyPortID := args[2] + counterpartyChannelID := args[3] + hops := strings.Split(args[4], "/") + order := channelOrder() + version := viper.GetString(FlagIBCVersion) + + msg := types.NewMsgChannelOpenInit( + portID, channelID, version, order, hops, + counterpartyPortID, counterpartyChannelID, cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + + cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") + cmd.Flags().String(FlagIBCVersion, "1.0.0", "supported IBC version") + + return cmd +} + +// GetMsgChannelOpenTryCmd returns the command to create a MsgChannelOpenTry transaction +func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-try [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof-init.json] [proof-height]", + Short: "Creates and sends a ChannelOpenTry message", + Args: cobra.ExactArgs(7), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + counterpartyPortID := args[2] + counterpartyChannelID := args[3] + hops := strings.Split(args[4], "/") + order := channelOrder() + version := viper.GetString(FlagIBCVersion) // TODO: diferenciate between channel and counterparty versions + + var proof commitment.ProofI + if err := cdc.UnmarshalJSON([]byte(args[5]), &proof); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(args[5]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return fmt.Errorf("error unmarshalling proof file: %v", err) + } + } + + proofHeight, err := strconv.ParseInt(args[6], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgChannelOpenTry( + portID, channelID, version, order, hops, + counterpartyPortID, counterpartyChannelID, version, + proof, uint64(proofHeight), cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") + cmd.Flags().String(FlagIBCVersion, "1.0.0", "supported IBC version") + + return cmd +} + +// GetMsgChannelOpenAckCmd returns the command to create a MsgChannelOpenAck transaction +func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-ack [port-id] [channel-id] [/path/to/proof-try.json] [proof-height]", + Short: "Creates and sends a ChannelOpenAck message", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + version := viper.GetString(FlagIBCVersion) // TODO: diferenciate between channel and counterparty versions + + var proof commitment.ProofI + if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(args[2]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return fmt.Errorf("error unmarshalling proof file: %v", err) + } + } + + proofHeight, err := strconv.ParseInt(args[3], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgChannelOpenAck( + portID, channelID, version, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + cmd.Flags().String(FlagIBCVersion, "1.0.0", "supported IBC version") + return cmd +} + +// GetMsgChannelOpenConfirmCmd returns the command to create a MsgChannelOpenConfirm transaction +func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "open-confirm [port-id] [channel-id] [/path/to/proof-ack.json] [proof-height]", + Short: "Creates and sends a ChannelOpenConfirm message", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + + var proof commitment.ProofI + if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(args[2]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return fmt.Errorf("error unmarshalling proof file: %v", err) + } + } + + proofHeight, err := strconv.ParseInt(args[3], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgChannelOpenConfirm( + portID, channelID, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } +} + +// GetMsgChannelCloseInitCmd returns the command to create a MsgChannelCloseInit transaction +func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "close-init [port-id] [channel-id]", + Short: "Creates and sends a ChannelCloseInit message", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + + msg := types.NewMsgChannelCloseInit(portID, channelID, cliCtx.GetFromAddress()) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } +} + +// GetMsgChannelCloseConfirmCmd returns the command to create a MsgChannelCloseConfirm transaction +func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "close-confirm [port-id] [channel-id] [/path/to/proof-init.json] [proof-height]", + Short: "Creates and sends a ChannelCloseConfirm message", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + + var proof commitment.ProofI + if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(args[2]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return fmt.Errorf("error unmarshalling proof file: %v", err) + } + } + + proofHeight, err := strconv.ParseInt(args[3], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgChannelCloseConfirm( + portID, channelID, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } +} + +func GetCmdHandshake(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "handshake", + Short: "initiate connection handshake between two chains", + Long: strings.TrimSpace( + fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: + +Example: +$ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-client-id] [cp-port-id] [cp-chain-id] [cp-conn-id] + `, version.ClientName)), + Args: cobra.ExactArgs(8), + // Args: []string{portid1, chanid1, connid1, portid2, chanid2, connid2} + RunE: func(cmd *cobra.Command, args []string) error { + // --chain-id values for each chain + cid1 := viper.GetString(flags.FlagChainID) + cid2 := viper.GetString(FlagChainID2) + + // --from values for each wallet + from1 := viper.GetString(FlagFrom1) + from2 := viper.GetString(FlagFrom2) + + // --node values for each RPC + node1 := viper.GetString(FlagNode1) + node2 := viper.GetString(FlagNode2) + + // client IDs + clientid1 := args[0] + clientid2 := args[4] + + // port IDs + portid1 := args[1] + portid2 := args[5] + + // channel IDs + chanid1 := args[2] + chanid2 := args[6] + + // connection IDs + connid1 := args[3] + connid2 := args[7] + + // Create txbldr, clictx, querier for cid1 + viper.Set(flags.FlagChainID, cid1) + txBldr1 := auth.NewTxBuilderFromCLI(). + WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx1 := context.NewCLIContextIBC(from1, cid1, node1). + WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + // Create txbldr, clictx, querier for cid2 + viper.Set(flags.FlagChainID, cid2) + txBldr2 := auth.NewTxBuilderFromCLI(). + WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx2 := context.NewCLIContextIBC(from2, cid2, node2). + WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + // // get passphrase for key from1 + // passphrase1, err := keys.GetPassphrase(from1) + // if err != nil { + // return err + // } + + // // get passphrase for key from2 + // passphrase2, err := keys.GetPassphrase(from2) + // if err != nil { + // return err + // } + + // TODO: check state and if not Idle continue existing process + viper.Set(flags.FlagChainID, cid1) + msgOpenInit := types.NewMsgChannelOpenInit(portid1, chanid1, "v1.0.0", channelOrder(), []string{connid1}, portid2, chanid2, ctx1.GetFromAddress()) + if err := msgOpenInit.ValidateBasic(); err != nil { + return err + } + + err := utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenInit}) + if err != nil { + return err + } + + // Another block has to be passed after msginit is committed + // to retrieve the correct proofs + time.Sleep(8 * time.Second) + + header, err := clientutils.GetTendermintHeader(ctx1) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid2) + msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), portid1, chanid1, storeKey) + if err != nil { + return err + } + + msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenTry}) + if err != nil { + return err + } + + // Another block has to be passed after msginit is committed + // to retrieve the correct proofs + time.Sleep(8 * time.Second) + + header, err = clientutils.GetTendermintHeader(ctx2) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid1, header, ctx1.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid2) + proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), portid2, chanid2, storeKey) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", proofs.Proof, uint64(header.Height), ctx1.GetFromAddress()) + if err := msgOpenAck.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenAck}) + if err != nil { + return err + } + + // Another block has to be passed after msginit is committed + // to retrieve the correct proofs + time.Sleep(8 * time.Second) + + header, err = clientutils.GetTendermintHeader(ctx1) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid2) + msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), portid1, chanid1, storeKey) + if err != nil { + return err + } + + msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + if err := msgOpenConfirm.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}) + if err != nil { + return err + } + + return nil + }, + } + + cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") + cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") + cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") + cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") + cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") + cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") + + cmd.MarkFlagRequired(FlagFrom1) + cmd.MarkFlagRequired(FlagFrom2) + + return cmd +} + +func queryProofs(ctx client.CLIContext, portID string, channelID string, queryRoute string) (types.ChannelResponse, error) { + var connRes types.ChannelResponse + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyChannel(portID, channelID), + Prove: true, + } + + res, err := ctx.QueryABCI(req) + if res.Value == nil || err != nil { + return connRes, err + } + + var channel types.Channel + if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { + return connRes, err + } + return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil +} + +func channelOrder() types.Order { + if viper.GetBool(FlagOrdered) { + return types.ORDERED + } + return types.UNORDERED +} diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go new file mode 100644 index 000000000000..580a2bf1fb83 --- /dev/null +++ b/x/ibc/04-channel/client/utils/utils.go @@ -0,0 +1,70 @@ +package utils + +import ( + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// QueryPacket returns a packet from the store +func QueryPacket( + ctx client.CLIContext, portID, channelID string, + sequence, timeout uint64, queryRoute string, +) (types.PacketResponse, error) { + var packetRes types.PacketResponse + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyPacketCommitment(portID, channelID, sequence), + Prove: true, + } + + res, err := ctx.QueryABCI(req) + if err != nil { + return packetRes, err + } + + channel, err := QueryChannel(ctx, portID, channelID, queryRoute) + if err != nil { + return packetRes, err + } + + destPortID := channel.Channel.Counterparty.PortID + destChannelID := channel.Channel.Counterparty.ChannelID + + packet := types.NewPacket( + sequence, + timeout, + portID, + channelID, + destPortID, + destChannelID, + res.Value, + ) + + // FIXME: res.Height+1 is hack, fix later + return types.NewPacketResponse(portID, channelID, sequence, packet, res.Proof, res.Height+1), nil +} + +// QueryChannel returns a channel from the store +func QueryChannel(ctx client.CLIContext, portID string, channelID string, queryRoute string) (types.ChannelResponse, error) { + var connRes types.ChannelResponse + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyChannel(portID, channelID), + Prove: true, + } + + res, err := ctx.QueryABCI(req) + if res.Value == nil || err != nil { + return connRes, err + } + + var channel types.Channel + if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { + return connRes, err + } + return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil +} diff --git a/x/ibc/04-channel/exported/exported.go b/x/ibc/04-channel/exported/exported.go new file mode 100644 index 000000000000..8fb84f7c1c01 --- /dev/null +++ b/x/ibc/04-channel/exported/exported.go @@ -0,0 +1,16 @@ +package exported + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type PacketI interface { + GetSequence() uint64 + GetTimeoutHeight() uint64 + GetSourcePort() string + GetSourceChannel() string + GetDestPort() string + GetDestChannel() string + GetData() []byte + ValidateBasic() sdk.Error +} diff --git a/x/ibc/04-channel/handler.go b/x/ibc/04-channel/handler.go new file mode 100644 index 000000000000..31c97b668e1a --- /dev/null +++ b/x/ibc/04-channel/handler.go @@ -0,0 +1,153 @@ +package channel + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit +func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenInit) sdk.Result { + err := k.ChanOpenInit( + ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, + msg.Channel.Counterparty, msg.Channel.Version, + ) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelOpenInit, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry +func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenTry) sdk.Result { + err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, + msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, + ) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelOpenTry, + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), // TODO: double check sender and receiver + sdk.NewAttribute(types.AttributeKeyReceiverPort, msg.Channel.Counterparty.PortID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck +func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenAck) sdk.Result { + err := k.ChanOpenAck( + ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight, + ) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelOpenAck, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelOpenConfirm defines the sdk.Handler for MsgChannelOpenConfirm +func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenConfirm) sdk.Result { + err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofAck, msg.ProofHeight) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelOpenConfirm, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelCloseInit defines the sdk.Handler for MsgChannelCloseInit +func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseInit) sdk.Result { + err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelCloseInit, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelCloseConfirm defines the sdk.Handler for MsgChannelCloseConfirm +func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseConfirm) sdk.Result { + err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofInit, msg.ProofHeight) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelCloseConfirm, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go new file mode 100644 index 000000000000..f71115da4792 --- /dev/null +++ b/x/ibc/04-channel/keeper/handshake.go @@ -0,0 +1,410 @@ +package keeper + +import ( + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// CounterpartyHops returns the connection hops of the counterparty channel. +// The counterparty hops are stored in the inverse order as the channel's. +func (k Keeper) CounterpartyHops(ctx sdk.Context, ch types.Channel) ([]string, bool) { + counterPartyHops := make([]string, len(ch.ConnectionHops)) + for i, hop := range ch.ConnectionHops { + connection, found := k.connectionKeeper.GetConnection(ctx, hop) + if !found { + return []string{}, false + } + counterPartyHops[len(counterPartyHops)-1-i] = connection.Counterparty.ConnectionID + } + return counterPartyHops, true +} + +// ChanOpenInit is called by a module to initiate a channel opening handshake with +// a module on another chain. +func (k Keeper) ChanOpenInit( + ctx sdk.Context, + order types.Order, + connectionHops []string, + portID, + channelID string, + counterparty types.Counterparty, + version string, +) error { + // TODO: abortTransactionUnless(validateChannelIdentifier(portIdentifier, channelIdentifier)) + _, found := k.GetChannel(ctx, portID, channelID) + if found { + return types.ErrChannelExists(k.codespace, channelID) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) + } + + if connectionEnd.State == connection.NONE { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state cannot be NONE"), + ) + } + + /* + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + */ + channel := types.NewChannel(types.INIT, order, counterparty, connectionHops, version) + k.SetChannel(ctx, portID, channelID, channel) + + // TODO: generate channel capability key and set it to store + k.SetNextSequenceSend(ctx, portID, channelID, 1) + k.SetNextSequenceRecv(ctx, portID, channelID, 1) + + return nil +} + +// ChanOpenTry is called by a module to accept the first step of a channel opening +// handshake initiated by a module on another chain. +func (k Keeper) ChanOpenTry( + ctx sdk.Context, + order types.Order, + connectionHops []string, + portID, + channelID string, + counterparty types.Counterparty, + version, + counterpartyVersion string, + proofInit commitment.ProofI, + proofHeight uint64, +) error { + _, found := k.GetChannel(ctx, portID, channelID) + if found { + return types.ErrChannelExists(k.codespace, channelID) + } + + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + // NOTE: this step has been switched with the one below to reverse the connection + // hops + channel := types.NewChannel(types.OPENTRY, order, counterparty, connectionHops, version) + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + // expectedCounterpaty is the counterparty of the counterparty's channel end + // (i.e self) + expectedCounterparty := types.NewCounterparty(portID, channelID) + expectedChannel := types.NewChannel( + types.INIT, channel.Ordering, expectedCounterparty, + counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofInit, + types.ChannelPath(counterparty.PortID, counterparty.ChannelID), + bz, + ) { + return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + k.SetChannel(ctx, portID, channelID, channel) + + // TODO: generate channel capability key and set it to store + k.SetNextSequenceSend(ctx, portID, channelID, 1) + k.SetNextSequenceRecv(ctx, portID, channelID, 1) + + return nil +} + +// ChanOpenAck is called by the handshake-originating module to acknowledge the +// acceptance of the initial request by the counterparty module on the other chain. +func (k Keeper) ChanOpenAck( + ctx sdk.Context, + portID, + channelID, + counterpartyVersion string, + proofTry commitment.ProofI, + proofHeight uint64, +) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.ErrChannelNotFound(k.codespace, portID, channelID) + } + + if channel.State != types.INIT { + return types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not INIT (got %s)", channel.State.String()), + ) + } + + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + // counterparty of the counterparty channel end (i.e self) + counterparty := types.NewCounterparty(portID, channelID) + expectedChannel := types.NewChannel( + types.OPENTRY, channel.Ordering, counterparty, + counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofTry, + types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), + bz, + ) { + return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + channel.State = types.OPEN + channel.Version = counterpartyVersion + k.SetChannel(ctx, portID, channelID, channel) + + return nil +} + +// ChanOpenConfirm is called by the counterparty module to close their end of the +// channel, since the other end has been closed. +func (k Keeper) ChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, + proofAck commitment.ProofI, + proofHeight uint64, +) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.ErrChannelNotFound(k.codespace, portID, channelID) + } + + if channel.State != types.OPENTRY { + return types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPENTRY (got %s)", channel.State.String()), + ) + } + + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + counterparty := types.NewCounterparty(portID, channelID) + expectedChannel := types.NewChannel( + types.OPEN, channel.Ordering, counterparty, + counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofAck, + types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), + bz, + ) { + return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + channel.State = types.OPEN + k.SetChannel(ctx, portID, channelID, channel) + + return nil +} + +// Closing Handshake +// +// This section defines the set of functions required to close a channel handshake +// as defined in https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#closing-handshake + +// ChanCloseInit is called by either module to close their end of the channel. Once +// closed, channels cannot be reopened. +func (k Keeper) ChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.ErrChannelNotFound(k.codespace, portID, channelID) + } + + if channel.State == types.CLOSED { + return types.ErrInvalidChannelState(k.codespace, "channel is already CLOSED") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + channel.State = types.CLOSED + k.SetChannel(ctx, portID, channelID, channel) + + return nil +} + +// ChanCloseConfirm is called by the counterparty module to close their end of the +// channel, since the other end has been closed. +func (k Keeper) ChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, + proofInit commitment.ProofI, + proofHeight uint64, +) error { + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.ErrChannelNotFound(k.codespace, portID, channelID) + } + + if channel.State == types.CLOSED { + return types.ErrInvalidChannelState(k.codespace, "channel is already CLOSED") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + counterparty := types.NewCounterparty(portID, channelID) + expectedChannel := types.NewChannel( + types.CLOSED, channel.Ordering, counterparty, + counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofInit, + types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), + bz, + ) { + return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + channel.State = types.CLOSED + k.SetChannel(ctx, portID, channelID, channel) + + return nil +} diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go new file mode 100644 index 000000000000..6169c72ffc3a --- /dev/null +++ b/x/ibc/04-channel/keeper/keeper.go @@ -0,0 +1,146 @@ +package keeper + +import ( + "encoding/binary" + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// Keeper defines the IBC channel keeper +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store + + clientKeeper types.ClientKeeper + connectionKeeper types.ConnectionKeeper + portKeeper types.PortKeeper +} + +// NewKeeper creates a new IBC channel Keeper instance +func NewKeeper( + cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + clientKeeper types.ClientKeeper, connectionKeeper types.ConnectionKeeper, + portKeeper types.PortKeeper, +) Keeper { + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/channel", + prefix: []byte{}, + // prefix: []byte(types.SubModuleName + "/"), // "channel/" + clientKeeper: clientKeeper, + connectionKeeper: connectionKeeper, + portKeeper: portKeeper, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName)) +} + +// GetChannel returns a channel with a particular identifier binded to a specific port +func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyChannel(portID, channelID)) + if bz == nil { + return types.Channel{}, false + } + + var channel types.Channel + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &channel) + return channel, true +} + +// SetChannel sets a channel to the store +func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel types.Channel) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(channel) + store.Set(types.KeyChannel(portID, channelID), bz) +} + +// GetChannelCapability gets a channel's capability key from the store +func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) (string, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyChannelCapabilityPath(portID, channelID)) + if bz == nil { + return "", false + } + + return string(bz), true +} + +// SetChannelCapability sets a channel's capability key to the store +func (k Keeper) SetChannelCapability(ctx sdk.Context, portID, channelID string, key string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Set(types.KeyChannelCapabilityPath(portID, channelID), []byte(key)) +} + +// GetNextSequenceSend gets a channel's next send sequence from the store +func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyNextSequenceSend(portID, channelID)) + if bz == nil { + return 0, false + } + + return binary.BigEndian.Uint64(bz), true +} + +// SetNextSequenceSend sets a channel's next send sequence to the store +func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set(types.KeyNextSequenceSend(portID, channelID), bz) +} + +// GetNextSequenceRecv gets a channel's next receive sequence from the store +func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyNextSequenceRecv(portID, channelID)) + if bz == nil { + return 0, false + } + + return binary.BigEndian.Uint64(bz), true +} + +// SetNextSequenceRecv sets a channel's next receive sequence to the store +func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set(types.KeyNextSequenceRecv(portID, channelID), bz) +} + +// GetPacketCommitment gets the packet commitment hash from the store +func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyPacketCommitment(portID, channelID, sequence)) + return bz +} + +// SetPacketCommitment sets the packet commitment hash to the store +func (k Keeper) SetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64, commitmentHash []byte) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Set(types.KeyPacketCommitment(portID, channelID, sequence), commitmentHash) +} + +func (k Keeper) deletePacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Delete(types.KeyPacketCommitment(portID, channelID, sequence)) +} + +// SetPacketAcknowledgement sets the packet ack hash to the store +func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64, ackHash []byte) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) +} diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go new file mode 100644 index 000000000000..0590f3cfd37c --- /dev/null +++ b/x/ibc/04-channel/keeper/packet.go @@ -0,0 +1,357 @@ +package keeper + +import ( + "bytes" + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// CleanupPacket is called by a module to remove a received packet commitment +// from storage. The receiving end must have already processed the packet +// (whether regularly or past timeout). +// +// In the ORDERED channel case, CleanupPacket cleans-up a packet on an ordered +// channel by proving that the packet has been received on the other end. +// +// In the UNORDERED channel case, CleanupPacket cleans-up a packet on an +// unordered channel by proving that the associated acknowledgement has been +//written. +func (k Keeper) CleanupPacket( + ctx sdk.Context, + packet exported.PacketI, + proof commitment.ProofI, + proofHeight, + nextSequenceRecv uint64, + acknowledgement []byte, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + if channel.State != types.OPEN { + return nil, types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + ) + } + + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelCapabilityNotFound(k.codespace) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return nil, errors.New("port is not valid") + } + + if packet.GetDestChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + ) + } + + if nextSequenceRecv >= packet.GetSequence() { + return nil, types.ErrInvalidPacket(k.codespace, "packet already received") + } + + commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + } + + var ok bool + switch channel.Ordering { + case types.ORDERED: + ok = k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.NextSequenceRecvPath(packet.GetDestPort(), packet.GetDestChannel()), + sdk.Uint64ToBigEndian(nextSequenceRecv), + ) + case types.UNORDERED: + ok = k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.PacketAcknowledgementPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), + acknowledgement, + ) + default: + panic(fmt.Sprintf("invalid channel ordering type %v", channel.Ordering)) + } + + if !ok { + return nil, types.ErrInvalidPacket(k.codespace, "packet verification failed") + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + return packet, nil +} + +// SendPacket is called by a module in order to send an IBC packet on a channel +// end owned by the calling module to the corresponding module on the counterparty +// chain. +func (k Keeper) SendPacket( + ctx sdk.Context, + packet exported.PacketI, + portCapability sdk.CapabilityKey, +) error { + if err := packet.ValidateBasic(); err != nil { + return err + } + + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + if channel.State == types.CLOSED { + return types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel is CLOSED (got %s)", channel.State.String()), + ) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return errors.New("port is not valid") + } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + ) + } + + if packet.GetDestChannel() != channel.Counterparty.ChannelID { + return types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State == connection.NONE { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection is closed (i.e NONE)"), + ) + } + + consensusState, found := k.clientKeeper.GetConsensusState(ctx, connectionEnd.ClientID) + if !found { + return client.ErrConsensusStateNotFound(k.codespace) + } + + if consensusState.GetHeight() >= packet.GetTimeoutHeight() { + return types.ErrPacketTimeout(k.codespace) + } + + nextSequenceSend, found := k.GetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return types.ErrSequenceNotFound(k.codespace, "send") + } + + if packet.GetSequence() != nextSequenceSend { + return types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet sequence ≠ next send sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceSend), + ) + } + + nextSequenceSend++ + k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend) + k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), packet.GetData()) // TODO: hash packet data + + return nil +} + +// RecvPacket is called by a module in order to receive & process an IBC packet +// sent on the corresponding channel end on the counterparty chain. +func (k Keeper) RecvPacket( + ctx sdk.Context, + packet exported.PacketI, + proof commitment.ProofI, + proofHeight uint64, + acknowledgement []byte, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + + channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetDestPort(), packet.GetDestChannel()) + } + + if channel.State != types.OPEN { + return nil, types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + ) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetDestPort()) { + return nil, errors.New("port is not valid") + } + + // packet must come from the channel's counterparty + if packet.GetSourcePort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID), + ) + } + + if packet.GetSourceChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return nil, connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { + return nil, types.ErrPacketTimeout(k.codespace) + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.PacketCommitmentPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), + packet.GetData(), // TODO: hash data + ) { + return nil, errors.New("couldn't verify counterparty packet commitment") + } + + if len(acknowledgement) > 0 || channel.Ordering == types.UNORDERED { + k.SetPacketAcknowledgement( + ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), + acknowledgement, // TODO: hash ACK + ) + } + + if channel.Ordering == types.ORDERED { + nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) + if !found { + return nil, types.ErrSequenceNotFound(k.codespace, "receive") + } + + if packet.GetSequence() != nextSequenceRecv { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv), + ) + } + + nextSequenceRecv++ + + k.SetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv) + } + + return packet, nil +} + +// AcknowledgePacket is called by a module to process the acknowledgement of a +// packet previously sent by the calling module on a channel to a counterparty +// module on the counterparty chain. acknowledgePacket also cleans up the packet +// commitment, which is no longer necessary since the packet has been received +// and acted upon. +func (k Keeper) AcknowledgePacket( + ctx sdk.Context, + packet exported.PacketI, + acknowledgement []byte, + proof commitment.ProofI, + proofHeight uint64, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + if channel.State != types.OPEN { + return nil, types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + ) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return nil, errors.New("invalid capability key") + } + + // packet must come from the channel's counterparty + if packet.GetSourcePort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID), + ) + } + + if packet.GetSourceChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return nil, connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.PacketAcknowledgementPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), + acknowledgement, // TODO: hash ACK + ) { + return nil, errors.New("invalid acknowledgement on counterparty chain") + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + return packet, nil +} diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go new file mode 100644 index 000000000000..3618c5f29fd4 --- /dev/null +++ b/x/ibc/04-channel/keeper/querier.go @@ -0,0 +1,32 @@ +package keeper + +import ( + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// QuerierChannel defines the sdk.Querier to query a module's channel +func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryChannelParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID) + } + + bz, err := types.SubModuleCdc.MarshalJSON(channel) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go new file mode 100644 index 000000000000..3ae481373de3 --- /dev/null +++ b/x/ibc/04-channel/keeper/timeout.go @@ -0,0 +1,195 @@ +package keeper + +import ( + "bytes" + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// TimeoutPacket is called by a module which originally attempted to send a +// packet to a counterparty module, where the timeout height has passed on the +// counterparty chain without the packet being committed, to prove that the +// packet can no longer be executed and to allow the calling module to safely +// perform appropriate state transitions. +func (k Keeper) TimeoutPacket( + ctx sdk.Context, + packet exported.PacketI, + proof commitment.ProofI, + proofHeight uint64, + nextSequenceRecv uint64, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + if channel.State != types.OPEN { + return nil, types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + ) + } + + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelCapabilityNotFound(k.codespace) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return nil, errors.New("port is not valid") + } + + if packet.GetDestChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + ) + } + + if proofHeight < packet.GetTimeoutHeight() { + return nil, types.ErrPacketTimeout(k.codespace) + } + + if nextSequenceRecv >= packet.GetSequence() { + return nil, types.ErrInvalidPacket(k.codespace, "packet already received") + } + + commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + } + + var ok bool + switch channel.Ordering { + case types.ORDERED: + ok = k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.NextSequenceRecvPath(packet.GetDestPort(), packet.GetDestChannel()), + sdk.Uint64ToBigEndian(nextSequenceRecv), + ) + case types.UNORDERED: + ok = k.connectionKeeper.VerifyNonMembership( + ctx, connectionEnd, proofHeight, proof, + types.PacketAcknowledgementPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), + ) + default: + panic(fmt.Sprintf("invalid channel ordering type %v", channel.Ordering)) + } + + if !ok { + return nil, types.ErrInvalidPacket(k.codespace, "packet verification failed") + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + if channel.Ordering == types.ORDERED { + channel.State = types.CLOSED + k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + } + + return packet, nil +} + +// TimeoutOnClose is called by a module in order to prove that the channel to +// which an unreceived packet was addressed has been closed, so the packet will +// never be received (even if the timeoutHeight has not yet been reached). +func (k Keeper) TimeoutOnClose( + ctx sdk.Context, + packet exported.PacketI, + proofNonMembership, + proofClosed commitment.ProofI, + proofHeight uint64, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelCapabilityNotFound(k.codespace) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return nil, errors.New("port is not valid") + } + + if packet.GetDestChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + ) + } + + commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + } + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + counterparty := types.NewCounterparty(packet.GetSourcePort(), packet.GetSourceChannel()) + expectedChannel := types.NewChannel( + types.CLOSED, channel.Ordering, counterparty, counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return nil, errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofClosed, + types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), + bz, + ) { + return nil, types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + if !k.connectionKeeper.VerifyNonMembership( + ctx, connectionEnd, proofHeight, proofNonMembership, + types.PacketAcknowledgementPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), + ) { + return nil, errors.New("cannot verify absence of acknowledgement at packet index") + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + return packet, nil +} diff --git a/x/ibc/04-channel/module.go b/x/ibc/04-channel/module.go new file mode 100644 index 000000000000..4f9b17b03144 --- /dev/null +++ b/x/ibc/04-channel/module.go @@ -0,0 +1,25 @@ +package channel + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/cli" +) + +// Name returns the IBC connection ICS name +func Name() string { + return SubModuleName +} + +// GetTxCmd returns the root tx command for the IBC connections. +func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + return cli.GetTxCmd(fmt.Sprintf("%s/%s", storeKey, SubModuleName), cdc) +} + +// GetQueryCmd returns no root query command for the IBC connections. +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + return cli.GetQueryCmd(fmt.Sprintf("%s/%s", queryRoute, SubModuleName), cdc) +} diff --git a/x/ibc/04-channel/types/channel.go b/x/ibc/04-channel/types/channel.go new file mode 100644 index 000000000000..98bbb9b44f1e --- /dev/null +++ b/x/ibc/04-channel/types/channel.go @@ -0,0 +1,225 @@ +package types + +import ( + "encoding/json" + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/errors" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +type Channel struct { + State State `json:"state" yaml:"state"` + Ordering Order `json:"ordering" yaml:"ordering"` + Counterparty Counterparty `json:"counterparty" yaml:"counterparty"` + ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` + Version string `json:"version" yaml:"version "` +} + +// NewChannel creates a new Channel instance +func NewChannel( + state State, ordering Order, counterparty Counterparty, + hops []string, version string, +) Channel { + return Channel{ + State: state, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: hops, + Version: version, + } +} + +// ValidateBasic performs a basic validation of the channel fields +func (ch Channel) ValidateBasic() sdk.Error { + if ch.State.String() == "" { + return ErrInvalidChannelState( + DefaultCodespace, + "channel order should be either 'ORDERED' or 'UNORDERED'", + ) + } + if ch.Ordering.String() == "" { + return ErrInvalidChannel( + DefaultCodespace, + "channel order should be either 'ORDERED' or 'UNORDERED'", + ) + } + if len(ch.ConnectionHops) != 1 { + return ErrInvalidChannel(DefaultCodespace, "IBC v1 only supports one connection hop") + } + if err := host.DefaultConnectionIdentifierValidator(ch.ConnectionHops[0]); err != nil { + return ErrInvalidChannel(DefaultCodespace, errors.Wrap(err, "invalid connection hop ID").Error()) + } + if strings.TrimSpace(ch.Version) == "" { + return ErrInvalidChannel(DefaultCodespace, "channel version can't be blank") + } + return ch.Counterparty.ValidateBasic() +} + +// Counterparty defines the counterparty chain's channel and port identifiers +type Counterparty struct { + PortID string `json:"port_id" yaml:"port_id"` + ChannelID string `json:"channel_id" yaml:"channel_id"` +} + +// NewCounterparty returns a new Counterparty instance +func NewCounterparty(portID, channelID string) Counterparty { + return Counterparty{ + PortID: portID, + ChannelID: channelID, + } +} + +// ValidateBasic performs a basic validation check of the identifiers +func (c Counterparty) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(c.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty connection ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(c.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty client ID: %s", err.Error())) + } + return nil +} + +// Order defines if a channel is ORDERED or UNORDERED +type Order byte + +// string representation of the channel ordering +const ( + NONE Order = iota // zero-value for channel ordering + UNORDERED // packets can be delivered in any order, which may differ from the order in which they were sent. + ORDERED // packets are delivered exactly in the order which they were sent +) + +// channel order types +const ( + OrderNone string = "NONE" + OrderUnordered string = "UNORDERED" + OrderOrdered string = "ORDERED" +) + +// String implements the Stringer interface +func (o Order) String() string { + switch o { + case NONE: + return OrderNone + case UNORDERED: + return OrderUnordered + case ORDERED: + return OrderOrdered + default: + return "" + } +} + +// MarshalJSON marshal to JSON using string. +func (o Order) MarshalJSON() ([]byte, error) { + return json.Marshal(o.String()) +} + +// UnmarshalJSON decodes from JSON. +func (o *Order) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + bz2, err := OrderFromString(s) + if err != nil { + return err + } + + *o = bz2 + return nil +} + +// OrderFromString parses a string into a channel order byte +func OrderFromString(order string) (Order, error) { + switch order { + case OrderNone: + return NONE, nil + case OrderUnordered: + return UNORDERED, nil + case OrderOrdered: + return ORDERED, nil + default: + return 0, fmt.Errorf("'%s' is not a valid channel ordering", order) + } +} + +// State defines if a channel is in one of the following states: +// CLOSED, INIT, OPENTRY or OPEN +type State byte + +// channel state types +const ( + CLOSED State = iota + 1 // A channel end has been closed and can no longer be used to send or receive packets. + INIT // A channel end has just started the opening handshake. + OPENTRY // A channel end has acknowledged the handshake step on the counterparty chain. + OPEN // A channel end has completed the handshake and is ready to send and receive packets. +) + +// string representation of the channel states +const ( + StateClosed string = "CLOSED" + StateInit string = "INIT" + StateOpenTry string = "OPENTRY" + StateOpen string = "OPEN" +) + +// String implements the Stringer interface +func (s State) String() string { + switch s { + case CLOSED: + return StateClosed + case INIT: + return StateInit + case OPENTRY: + return StateOpenTry + case OPEN: + return StateOpen + default: + return "" + } +} + +// MarshalJSON marshal to JSON using string. +func (s State) MarshalJSON() ([]byte, error) { + return json.Marshal(s.String()) +} + +// UnmarshalJSON decodes from JSON. +func (s *State) UnmarshalJSON(data []byte) error { + var stateStr string + err := json.Unmarshal(data, &stateStr) + if err != nil { + return err + } + + bz2, err := StateFromString(stateStr) + if err != nil { + return err + } + + *s = bz2 + return nil +} + +// StateFromString parses a string into a channel state byte +func StateFromString(state string) (State, error) { + switch state { + case StateClosed: + return CLOSED, nil + case StateInit: + return INIT, nil + case StateOpenTry: + return OPENTRY, nil + case StateOpen: + return OPEN, nil + default: + return CLOSED, fmt.Errorf("'%s' is not a valid channel state", state) + } +} diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go new file mode 100644 index 000000000000..0839edede775 --- /dev/null +++ b/x/ibc/04-channel/types/codec.go @@ -0,0 +1,28 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" +) + +// SubModuleCdc defines the IBC channel codec. +var SubModuleCdc = codec.New() + +// RegisterCodec registers all the necessary types and interfaces for the +// IBC channel. +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*exported.PacketI)(nil), nil) + cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil) + cdc.RegisterConcrete(OpaquePacket{}, "ibc/channel/OpaquePacket", nil) + + cdc.RegisterConcrete(MsgChannelOpenInit{}, "ibc/channel/MsgChannelOpenInit", nil) + cdc.RegisterConcrete(MsgChannelOpenTry{}, "ibc/channel/MsgChannelOpenTry", nil) + cdc.RegisterConcrete(MsgChannelOpenAck{}, "ibc/channel/MsgChannelOpenAck", nil) + cdc.RegisterConcrete(MsgChannelOpenConfirm{}, "ibc/channel/MsgChannelOpenConfirm", nil) + cdc.RegisterConcrete(MsgChannelCloseInit{}, "ibc/channel/MsgChannelCloseInit", nil) + cdc.RegisterConcrete(MsgChannelCloseConfirm{}, "ibc/channel/MsgChannelCloseConfirm", nil) +} + +func init() { + RegisterCodec(SubModuleCdc) +} diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go new file mode 100644 index 000000000000..37d3925b513e --- /dev/null +++ b/x/ibc/04-channel/types/errors.go @@ -0,0 +1,73 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// channel error codes +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName + + CodeChannelExists sdk.CodeType = 101 + CodeChannelNotFound sdk.CodeType = 102 + CodeInvalidCounterpartyChannel sdk.CodeType = 103 + CodeChannelCapabilityNotFound sdk.CodeType = 104 + CodeInvalidPacket sdk.CodeType = 105 + CodeSequenceNotFound sdk.CodeType = 106 + CodePacketTimeout sdk.CodeType = 107 + CodeInvalidChannel sdk.CodeType = 108 + CodeInvalidChannelState sdk.CodeType = 109 + CodeInvalidChannelProof sdk.CodeType = 110 +) + +// ErrChannelExists implements sdk.Error +func ErrChannelExists(codespace sdk.CodespaceType, channelID string) sdk.Error { + return sdk.NewError(codespace, CodeChannelExists, fmt.Sprintf("channel with ID %s already exists", channelID)) +} + +// ErrChannelNotFound implements sdk.Error +func ErrChannelNotFound(codespace sdk.CodespaceType, portID, channelID string) sdk.Error { + return sdk.NewError(codespace, CodeChannelNotFound, fmt.Sprintf("channel with ID %s on port %s not found", channelID, portID)) +} + +// ErrInvalidCounterpartyChannel implements sdk.Error +func ErrInvalidCounterpartyChannel(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidCounterpartyChannel, msg) +} + +// ErrChannelCapabilityNotFound implements sdk.Error +func ErrChannelCapabilityNotFound(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeChannelCapabilityNotFound, "channel capability key not found") +} + +// ErrInvalidPacket implements sdk.Error +func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidPacket, msg) +} + +// ErrSequenceNotFound implements sdk.Error +func ErrSequenceNotFound(codespace sdk.CodespaceType, seqType string) sdk.Error { + return sdk.NewError(codespace, CodeSequenceNotFound, fmt.Sprintf("next %s sequence counter not found", seqType)) +} + +// ErrPacketTimeout implements sdk.Error +func ErrPacketTimeout(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodePacketTimeout, "packet timeout") +} + +// ErrInvalidChannel implements sdk.Error +func ErrInvalidChannel(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidChannel, msg) +} + +// ErrInvalidChannelState implements sdk.Error +func ErrInvalidChannelState(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidChannelState, msg) +} + +// ErrInvalidChannelProof implements sdk.Error +func ErrInvalidChannelProof(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidChannelProof, msg) +} diff --git a/x/ibc/04-channel/types/events.go b/x/ibc/04-channel/types/events.go new file mode 100644 index 000000000000..b82b3e8700cf --- /dev/null +++ b/x/ibc/04-channel/types/events.go @@ -0,0 +1,27 @@ +package types + +import ( + "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// IBC channel events +const ( + AttributeKeySenderPort = "sender_port" + AttributeKeyReceiverPort = "receiver_port" + AttributeKeyChannelID = "channel_id" + AttributeKeySequence = "sequence" +) + +// IBC channel events vars +var ( + EventTypeChannelOpenInit = MsgChannelOpenInit{}.Type() + EventTypeChannelOpenTry = MsgChannelOpenTry{}.Type() + EventTypeChannelOpenAck = MsgChannelOpenAck{}.Type() + EventTypeChannelOpenConfirm = MsgChannelOpenConfirm{}.Type() + EventTypeChannelCloseInit = MsgChannelCloseInit{}.Type() + EventTypeChannelCloseConfirm = MsgChannelCloseConfirm{}.Type() + + AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) +) diff --git a/x/ibc/04-channel/types/expected_keepers.go b/x/ibc/04-channel/types/expected_keepers.go new file mode 100644 index 000000000000..ab88a2284f27 --- /dev/null +++ b/x/ibc/04-channel/types/expected_keepers.go @@ -0,0 +1,31 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// ClientKeeper expected account IBC client keeper +type ClientKeeper interface { + GetConsensusState(ctx sdk.Context, clientID string) (clientexported.ConsensusState, bool) +} + +// ConnectionKeeper expected account IBC connection keeper +type ConnectionKeeper interface { + GetConnection(ctx sdk.Context, connectionID string) (connection.ConnectionEnd, bool) + VerifyMembership( + ctx sdk.Context, connection connection.ConnectionEnd, height uint64, + proof commitment.ProofI, path string, value []byte, + ) bool + VerifyNonMembership( + ctx sdk.Context, connection connection.ConnectionEnd, height uint64, + proof commitment.ProofI, path string, + ) bool +} + +// PortKeeper expected account IBC port keeper +type PortKeeper interface { + Authenticate(key sdk.CapabilityKey, portID string) bool +} diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go new file mode 100644 index 000000000000..f308640b2e32 --- /dev/null +++ b/x/ibc/04-channel/types/keys.go @@ -0,0 +1,85 @@ +package types + +import ( + "fmt" +) + +const ( + // SubModuleName defines the IBC channels name + SubModuleName = "channels" + + // StoreKey is the store key string for IBC channels + StoreKey = SubModuleName + + // RouterKey is the message route for IBC channels + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC channels + QuerierRoute = SubModuleName +) + +// ChannelPath defines the path under which channels are stored +func ChannelPath(portID, channelID string) string { + return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) +} + +// ChannelCapabilityPath defines the path under which capability keys associated +// with a channel are stored +func ChannelCapabilityPath(portID, channelID string) string { + return fmt.Sprintf("%s/key", ChannelPath(portID, channelID)) +} + +// NextSequenceSendPath defines the next send sequence counter store path +func NextSequenceSendPath(portID, channelID string) string { + return fmt.Sprintf("%s/nextSequenceSend", ChannelPath(portID, channelID)) +} + +// NextSequenceRecvPath defines the next receive sequence counter store path +func NextSequenceRecvPath(portID, channelID string) string { + return fmt.Sprintf("%s/nextSequenceRecv", ChannelPath(portID, channelID)) +} + +// PacketCommitmentPath defines the commitments to packet data fields store path +func PacketCommitmentPath(portID, channelID string, sequence uint64) string { + return fmt.Sprintf("%s/packets/%d", ChannelPath(portID, channelID), sequence) +} + +// PacketAcknowledgementPath defines the packet acknowledgement store path +func PacketAcknowledgementPath(portID, channelID string, sequence uint64) string { + return fmt.Sprintf("%s/acknowledgements/%d", ChannelPath(portID, channelID), sequence) +} + +// KeyChannel returns the store key for a particular channel +func KeyChannel(portID, channelID string) []byte { + return []byte(ChannelPath(portID, channelID)) +} + +// KeyChannelCapabilityPath returns the store key for the capability key of a +// particular channel binded to a specific port +func KeyChannelCapabilityPath(portID, channelID string) []byte { + return []byte(ChannelCapabilityPath(portID, channelID)) +} + +// KeyNextSequenceSend returns the store key for the send sequence of a particular +// channel binded to a specific port +func KeyNextSequenceSend(portID, channelID string) []byte { + return []byte(NextSequenceSendPath(portID, channelID)) +} + +// KeyNextSequenceRecv returns the store key for the receive sequence of a particular +// channel binded to a specific port +func KeyNextSequenceRecv(portID, channelID string) []byte { + return []byte(NextSequenceRecvPath(portID, channelID)) +} + +// KeyPacketCommitment returns the store key of under which a packet commitment +// is stored +func KeyPacketCommitment(portID, channelID string, sequence uint64) []byte { + return []byte(PacketCommitmentPath(portID, channelID, sequence)) +} + +// KeyPacketAcknowledgement returns the store key of under which a packet +// acknowledgement is stored +func KeyPacketAcknowledgement(portID, channelID string, sequence uint64) []byte { + return []byte(PacketAcknowledgementPath(portID, channelID, sequence)) +} diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go new file mode 100644 index 000000000000..a6d7d856e34f --- /dev/null +++ b/x/ibc/04-channel/types/msgs.go @@ -0,0 +1,379 @@ +package types + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +var _ sdk.Msg = MsgChannelOpenInit{} + +type MsgChannelOpenInit struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + Channel Channel `json:"channel"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelOpenInit creates a new MsgChannelCloseInit MsgChannelOpenInit +func NewMsgChannelOpenInit( + portID, channelID string, version string, channelOrder Order, connectionHops []string, + counterpartyPortID, counterpartyChannelID string, signer sdk.AccAddress, +) MsgChannelOpenInit { + counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) + channel := NewChannel(INIT, channelOrder, counterparty, connectionHops, version) + return MsgChannelOpenInit{ + PortID: portID, + ChannelID: channelID, + Channel: channel, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelOpenInit) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelOpenInit) Type() string { + return "channel_open_init" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelOpenInit) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + // Signer can be empty + return msg.Channel.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelOpenInit) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelOpenInit) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelOpenTry{} + +type MsgChannelOpenTry struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + Channel Channel `json:"channel"` + CounterpartyVersion string `json:"counterparty_version"` + ProofInit commitment.ProofI `json:"proof_init"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelOpenTry creates a new MsgChannelOpenTry instance +func NewMsgChannelOpenTry( + portID, channelID, version string, channelOrder Order, connectionHops []string, + counterpartyPortID, counterpartyChannelID, counterpartyVersion string, + proofInit commitment.ProofI, proofHeight uint64, signer sdk.AccAddress, +) MsgChannelOpenTry { + counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) + channel := NewChannel(INIT, channelOrder, counterparty, connectionHops, version) + return MsgChannelOpenTry{ + PortID: portID, + ChannelID: channelID, + Channel: channel, + CounterpartyVersion: counterpartyVersion, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelOpenTry) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelOpenTry) Type() string { + return "channel_open_try" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelOpenTry) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if strings.TrimSpace(msg.CounterpartyVersion) == "" { + return ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank") + } + if msg.ProofInit == nil { + return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + } + if msg.ProofHeight == 0 { + return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + } + // Signer can be empty + return msg.Channel.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelOpenTry) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelOpenTry) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelOpenAck{} + +type MsgChannelOpenAck struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + CounterpartyVersion string `json:"counterparty_version"` + ProofTry commitment.ProofI `json:"proof_try"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelOpenAck creates a new MsgChannelOpenAck instance +func NewMsgChannelOpenAck( + portID, channelID string, cpv string, proofTry commitment.ProofI, proofHeight uint64, + signer sdk.AccAddress, +) MsgChannelOpenAck { + return MsgChannelOpenAck{ + PortID: portID, + ChannelID: channelID, + CounterpartyVersion: cpv, + ProofTry: proofTry, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelOpenAck) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelOpenAck) Type() string { + return "channel_open_ack" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelOpenAck) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if strings.TrimSpace(msg.CounterpartyVersion) == "" { + return ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank") + } + if msg.ProofTry == nil { + return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + } + if msg.ProofHeight == 0 { + return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + } + // Signer can be empty + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelOpenAck) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelOpenAck) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelOpenConfirm{} + +type MsgChannelOpenConfirm struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + ProofAck commitment.ProofI `json:"proof_ack"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelOpenConfirm creates a new MsgChannelOpenConfirm instance +func NewMsgChannelOpenConfirm( + portID, channelID string, proofAck commitment.ProofI, proofHeight uint64, + signer sdk.AccAddress, +) MsgChannelOpenConfirm { + return MsgChannelOpenConfirm{ + PortID: portID, + ChannelID: channelID, + ProofAck: proofAck, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelOpenConfirm) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelOpenConfirm) Type() string { + return "channel_open_confirm" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelOpenConfirm) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if msg.ProofAck == nil { + return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + } + if msg.ProofHeight == 0 { + return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + } + // Signer can be empty + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelOpenConfirm) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelOpenConfirm) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelCloseInit{} + +type MsgChannelCloseInit struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelCloseInit creates a new MsgChannelCloseInit instance +func NewMsgChannelCloseInit(portID string, channelID string, signer sdk.AccAddress) MsgChannelCloseInit { + return MsgChannelCloseInit{ + PortID: portID, + ChannelID: channelID, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelCloseInit) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelCloseInit) Type() string { + return "channel_close_init" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelCloseInit) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + // Signer can be empty + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelCloseInit) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelCloseInit) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelCloseConfirm{} + +type MsgChannelCloseConfirm struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + ProofInit commitment.ProofI `json:"proof_init"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelCloseConfirm creates a new MsgChannelCloseConfirm instance +func NewMsgChannelCloseConfirm( + portID, channelID string, proofInit commitment.ProofI, proofHeight uint64, + signer sdk.AccAddress, +) MsgChannelCloseConfirm { + return MsgChannelCloseConfirm{ + PortID: portID, + ChannelID: channelID, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelCloseConfirm) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelCloseConfirm) Type() string { + return "channel_close_confirm" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelCloseConfirm) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if msg.ProofInit == nil { + return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + } + if msg.ProofHeight == 0 { + return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + } + // Signer can be empty + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelCloseConfirm) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelCloseConfirm) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go new file mode 100644 index 000000000000..8d170cc62a9d --- /dev/null +++ b/x/ibc/04-channel/types/packet.go @@ -0,0 +1,108 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +var _ exported.PacketI = Packet{} + +// Packet defines a type that carries data across different chains through IBC +type Packet struct { + Sequence uint64 `json:"sequence"` // number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. + Timeout uint64 `json:"timeout"` // indicates a consensus height on the destination chain after which the Packet will no longer be processed, and will instead count as having timed-out. + SourcePort string `json:"source_port"` // identifies the port on the sending chain. + SourceChannel string `json:"source_channel"` // identifies the channel end on the sending chain. + DestinationPort string `json:"destination_port"` // identifies the port on the receiving chain. + DestinationChannel string `json:"destination_channel"` // identifies the channel end on the receiving chain. + Data []byte `json:"data"` // opaque value which can be defined by the application logic of the associated modules. +} + +// NewPacket creates a new Packet instance +func NewPacket( + sequence, timeout uint64, sourcePort, sourceChannel, + destinationPort, destinationChannel string, data []byte, +) Packet { + return Packet{ + sequence, + timeout, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + data, + } +} + +// Sequence implements PacketI interface +func (p Packet) GetSequence() uint64 { return p.Sequence } + +// TimeoutHeight implements PacketI interface +func (p Packet) GetTimeoutHeight() uint64 { return p.Timeout } + +// SourcePort implements PacketI interface +func (p Packet) GetSourcePort() string { return p.SourcePort } + +// SourceChannel implements PacketI interface +func (p Packet) GetSourceChannel() string { return p.SourceChannel } + +// DestPort implements PacketI interface +func (p Packet) GetDestPort() string { return p.DestinationPort } + +// DestChannel implements PacketI interface +func (p Packet) GetDestChannel() string { return p.DestinationChannel } + +// Data implements PacketI interface +func (p Packet) GetData() []byte { return p.Data } + +// ValidateBasic implements PacketI interface +func (p Packet) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(p.SourcePort); err != nil { + return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source port ID: %s", err.Error())) + } + if err := host.DefaultPortIdentifierValidator(p.DestinationPort); err != nil { + return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid destination port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(p.SourceChannel); err != nil { + return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source channel ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(p.DestinationChannel); err != nil { + return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid destination channel ID: %s", err.Error())) + } + if p.Sequence == 0 { + return ErrInvalidPacket(DefaultCodespace, "packet sequence cannot be 0") + } + if p.Timeout == 0 { + return ErrPacketTimeout(DefaultCodespace) + } + if len(p.Data) == 0 { + return ErrInvalidPacket(DefaultCodespace, "packet data cannot be empty") + } + return nil +} + +var _ exported.PacketI = OpaquePacket{} + +// OpaquePacket is a Packet, but cloaked in an obscuring data type by the host +// state machine, such that a module cannot act upon it other than to pass it to +// the IBC handler +type OpaquePacket struct { + *Packet +} + +// NewOpaquePacket creates a new OpaquePacket instance +func NewOpaquePacket(sequence, timeout uint64, sourcePort, sourceChannel, + destinationPort, destinationChannel string, data []byte, +) OpaquePacket { + Packet := NewPacket( + sequence, timeout, sourcePort, sourceChannel, destinationPort, + destinationChannel, data, + ) + return OpaquePacket{&Packet} +} + +// Data implements PacketI interface +func (op OpaquePacket) GetData() []byte { return nil } diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go new file mode 100644 index 000000000000..707e9076ca39 --- /dev/null +++ b/x/ibc/04-channel/types/querier.go @@ -0,0 +1,71 @@ +package types + +import ( + "strings" + + "github.com/tendermint/tendermint/crypto/merkle" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// query routes supported by the IBC channel Querier +const ( + QueryChannel = "channel" +) + +// ChannelResponse defines the client query response for a channel which also +// includes a proof,its path and the height from which the proof was retrieved. +type ChannelResponse struct { + Channel Channel `json:"channel" yaml:"channel"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewChannelResponse creates a new ChannelResponse instance +func NewChannelResponse( + portID, channelID string, channel Channel, proof *merkle.Proof, height int64, +) ChannelResponse { + return ChannelResponse{ + Channel: channel, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ChannelPath(portID, channelID), "/")), + ProofHeight: uint64(height), + } +} + +// QueryChannelParams defines the params for the following queries: +// - 'custom/ibc/channel' +type QueryChannelParams struct { + PortID string + ChannelID string +} + +// NewQueryChannelParams creates a new QueryChannelParams instance +func NewQueryChannelParams(portID, channelID string) QueryChannelParams { + return QueryChannelParams{ + PortID: portID, + ChannelID: channelID, + } +} + +// PacketResponse defines the client query response for a packet which also +// includes a proof, its path and the height form which the proof was retrieved +type PacketResponse struct { + Packet Packet `json:"packet" yaml:"packet"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewPacketResponse creates a new PacketResponswe instance +func NewPacketResponse( + portID, channelID string, sequence uint64, packet Packet, proof *merkle.Proof, height int64, +) PacketResponse { + return PacketResponse{ + Packet: packet, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(PacketCommitmentPath(portID, channelID, sequence), "/")), + ProofHeight: uint64(height), + } +} diff --git a/x/ibc/handler.go b/x/ibc/handler.go index ed740f39183e..b80267dd7d92 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" ) // NewHandler defines the IBC handler @@ -14,6 +15,7 @@ func NewHandler(k Keeper) sdk.Handler { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { + // IBC client msgs case client.MsgCreateClient: return client.HandleMsgCreateClient(ctx, k.ClientKeeper, msg) @@ -23,6 +25,7 @@ func NewHandler(k Keeper) sdk.Handler { case client.MsgSubmitMisbehaviour: return client.HandleMsgSubmitMisbehaviour(ctx, k.ClientKeeper, msg) + // IBC connection msgs case connection.MsgConnectionOpenInit: return connection.HandleMsgConnectionOpenInit(ctx, k.ConnectionKeeper, msg) @@ -35,6 +38,25 @@ func NewHandler(k Keeper) sdk.Handler { case connection.MsgConnectionOpenConfirm: return connection.HandleMsgConnectionOpenConfirm(ctx, k.ConnectionKeeper, msg) + // IBC channel msgs + case channel.MsgChannelOpenInit: + return channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelOpenTry: + return channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelOpenAck: + return channel.HandleMsgChannelOpenAck(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelOpenConfirm: + return channel.HandleMsgChannelOpenConfirm(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelCloseInit: + return channel.HandleMsgChannelCloseInit(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelCloseConfirm: + return channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, msg) + default: errMsg := fmt.Sprintf("unrecognized IBC message type: %T", msg) return sdk.ErrUnknownRequest(errMsg).Result() diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index c9708a6e79a1..52158b48b140 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" ) @@ -12,6 +13,7 @@ import ( type Keeper struct { ClientKeeper client.Keeper ConnectionKeeper connection.Keeper + ChannelKeeper channel.Keeper PortKeeper port.Keeper } @@ -20,10 +22,12 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) clientKeeper := client.NewKeeper(cdc, key, codespace) connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) portKeeper := port.NewKeeper(cdc, key, codespace) + channelKeeper := channel.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, portKeeper) return Keeper{ ClientKeeper: clientKeeper, ConnectionKeeper: connectionKeeper, + ChannelKeeper: channelKeeper, PortKeeper: portKeeper, } } diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index 43db6f574dc0..fc2527df104c 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" ) // NewQuerier creates a querier for the IBC module @@ -36,6 +37,14 @@ func NewQuerier(k Keeper) sdk.Querier { return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName)) } + case channel.SubModuleName: + switch path[1] { + case channel.QueryChannel: + return channel.QuerierChannel(ctx, req, k.ChannelKeeper) + default: + return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", channel.SubModuleName)) + } + default: return nil, sdk.ErrUnknownRequest("unknown IBC query endpoint") } diff --git a/x/ibc/module.go b/x/ibc/module.go index 21ba001210de..791517826f03 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -39,6 +40,7 @@ func (AppModuleBasic) Name() string { func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) + channel.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } From bd85998e5304f4b039f8a8324aeb0f1228663ea9 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 5 Nov 2019 18:15:59 +0100 Subject: [PATCH 007/176] IBC v1.0.0 (#5245) * applying review in progress * apply review - make querier interface * fix cli errors * fix dependency * fix dependency * reflect method name change * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * reflect downstream changes * fix from address in tx cli * fix cli in progress(squash later) * fix cli * remove timeout, add channel cli * fix golangci * fix cli * Clean up * fix mock cli in progress * finalize cleanup, mock cli wip * add cli for mocksend * fix handler * rm commented lines * address review in progress * address review, rm cleanup/closing * rename mock packages * fix interface for gaia * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * update test * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * refactor: remove store accessors, update keeper and types to match spec (WIP) * update handshake and packet * implement packet timeouts * implement send and receive packet * implement packet ACK * update handler * add channel errors * channel querier * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update ICS04 with downstream changes * Implement tx cli actions * add MsgSendPacket handler; msg validation, errors and events * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * rm legacy tests; add query proofs support * remove capability key generation and authentication logic * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * downstream changes; custom marshal JSON; msg validation, and update errors * update errors and aliases * start batch-verify tests * update msg validation and CLI UX * minor changes on commitment types * fix channel and packet check (#5243) * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * authenticate port ID; remove send packet msg from CLI * comment out handlers * add ibc module to simapp * ICS20 implementation (#5204) * add ibc bank mock * modify handler * import channel * add receiving logic * add cli proof handling * modify cli * modify receiver type * modify errcode * optimize codes * add denom prefix when source is true * refactor code * error return * switch ibc antehandler to decorator pattern * fix name/comment * ICS 20 implementation (#5250) * move ics20 code to 20-transfer * clean code * fix compiling error * add transfer module * address ICS20 comments from review * add routing callbacks * clean code * add missing err return * modify err type * modify err type * add supply handling * modify proof type * add comments for msg and packet data * add timeout supply handling * modify module account name * use supply keeper for burn and mint coins * restructure keeper * update alias and module.go * golangci linter * add ics20 handler to IBC handler * update callbacks * update ICS20 escrow address * fix querier routes * fix create client cli * minor updates * ibc querier test * Refactor ibc/mock/bank into ICS 20 (#5264) * Most of code port from mock module to ICS 20 * A few minor fixes * Apply suggestions from code review Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * Fix suggestions from autolinter * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Fix order of messages * Add invalid height error code, check non-nil proof * Fix linter error * Return the underlying error * Tendermint starts at height 1 * Apply suggestions from code review * setup ics20 test suite * add event to MsgRecvPacket * update ibc keeper test to use test suite * Add handshake commands * WIP connection handshake * WIP Connection Handshake * use testsuite * Add cliCtx.WaitForNBlocks * fix connection handshake in progress * fix connection handshake in progress * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * upstream changes * upstream changes * upstream changes --- simapp/app.go | 24 ++- types/result.go | 9 + x/auth/client/utils/tx.go | 39 ++++ x/ibc/03-connection/client/cli/tx.go | 66 ++++--- x/ibc/20-transfer/alias.go | 62 +++++++ x/ibc/20-transfer/client/cli/query.go | 68 +++++++ x/ibc/20-transfer/client/cli/tx.go | 150 +++++++++++++++ x/ibc/20-transfer/genesis.go | 17 ++ x/ibc/20-transfer/handler.go | 43 +++++ x/ibc/20-transfer/keeper/callbacks.go | 184 +++++++++++++++++++ x/ibc/20-transfer/keeper/keeper.go | 68 +++++++ x/ibc/20-transfer/keeper/keeper_test.go | 35 ++++ x/ibc/20-transfer/keeper/relay.go | 193 ++++++++++++++++++++ x/ibc/20-transfer/keeper/relay_test.go | 6 + x/ibc/20-transfer/module.go | 18 ++ x/ibc/20-transfer/types/codec.go | 21 +++ x/ibc/20-transfer/types/errors.go | 51 ++++++ x/ibc/20-transfer/types/events.go | 17 ++ x/ibc/20-transfer/types/expected_keepers.go | 44 +++++ x/ibc/20-transfer/types/keys.go | 46 +++++ x/ibc/20-transfer/types/msgs.go | 138 ++++++++++++++ x/ibc/20-transfer/types/packet.go | 70 +++++++ x/ibc/alias.go | 9 +- x/ibc/ante.go | 51 ++++++ x/ibc/client/cli/cli.go | 4 + x/ibc/handler.go | 8 + x/ibc/keeper/keeper.go | 9 +- x/ibc/keeper/keeper_test.go | 37 ++++ x/ibc/keeper/querier.go | 3 - x/ibc/keeper/querier_test.go | 102 +++++++++++ x/ibc/module.go | 4 + x/ibc/types/types.go | 13 +- 32 files changed, 1569 insertions(+), 40 deletions(-) create mode 100644 x/ibc/20-transfer/alias.go create mode 100644 x/ibc/20-transfer/client/cli/query.go create mode 100644 x/ibc/20-transfer/client/cli/tx.go create mode 100644 x/ibc/20-transfer/genesis.go create mode 100644 x/ibc/20-transfer/handler.go create mode 100644 x/ibc/20-transfer/keeper/callbacks.go create mode 100644 x/ibc/20-transfer/keeper/keeper.go create mode 100644 x/ibc/20-transfer/keeper/keeper_test.go create mode 100644 x/ibc/20-transfer/keeper/relay.go create mode 100644 x/ibc/20-transfer/keeper/relay_test.go create mode 100644 x/ibc/20-transfer/module.go create mode 100644 x/ibc/20-transfer/types/codec.go create mode 100644 x/ibc/20-transfer/types/errors.go create mode 100644 x/ibc/20-transfer/types/events.go create mode 100644 x/ibc/20-transfer/types/expected_keepers.go create mode 100644 x/ibc/20-transfer/types/keys.go create mode 100644 x/ibc/20-transfer/types/msgs.go create mode 100644 x/ibc/20-transfer/types/packet.go create mode 100644 x/ibc/ante.go create mode 100644 x/ibc/keeper/keeper_test.go create mode 100644 x/ibc/keeper/querier_test.go diff --git a/simapp/app.go b/simapp/app.go index 53e671a1242d..347e32a687c2 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -22,6 +22,8 @@ import ( distr "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/ibc" + ibctransfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/params" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" @@ -54,16 +56,18 @@ var ( params.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, + ibc.AppModuleBasic{}, ) // module account permissions maccPerms = map[string][]string{ - auth.FeeCollectorName: nil, - distr.ModuleName: nil, - mint.ModuleName: {supply.Minter}, - staking.BondedPoolName: {supply.Burner, supply.Staking}, - staking.NotBondedPoolName: {supply.Burner, supply.Staking}, - gov.ModuleName: {supply.Burner}, + auth.FeeCollectorName: nil, + distr.ModuleName: nil, + mint.ModuleName: {supply.Minter}, + staking.BondedPoolName: {supply.Burner, supply.Staking}, + staking.NotBondedPoolName: {supply.Burner, supply.Staking}, + gov.ModuleName: {supply.Burner}, + ibctransfer.GetModuleAccountName(): {supply.Minter, supply.Burner}, } ) @@ -101,6 +105,7 @@ type SimApp struct { GovKeeper gov.Keeper CrisisKeeper crisis.Keeper ParamsKeeper params.Keeper + IBCKeeper ibc.Keeper // the module manager mm *module.Manager @@ -123,7 +128,7 @@ func NewSimApp( keys := sdk.NewKVStoreKeys(bam.MainStoreKey, auth.StoreKey, staking.StoreKey, supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey, - gov.StoreKey, params.StoreKey) + gov.StoreKey, params.StoreKey, ibc.StoreKey) tkeys := sdk.NewTransientStoreKeys(params.TStoreKey) app := &SimApp{ @@ -172,6 +177,8 @@ func NewSimApp( staking.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), ) + app.IBCKeeper = ibc.NewKeeper(app.cdc, keys[ibc.StoreKey], ibc.DefaultCodespace, app.BankKeeper, app.SupplyKeeper) + // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. app.mm = module.NewManager( @@ -185,6 +192,7 @@ func NewSimApp( distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper), slashing.NewAppModule(app.SlashingKeeper, app.StakingKeeper), staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper), + ibc.NewAppModule(app.IBCKeeper), ) // During begin block slashing happens after distr.BeginBlocker so that @@ -200,7 +208,7 @@ func NewSimApp( auth.ModuleName, distr.ModuleName, staking.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName, mint.ModuleName, supply.ModuleName, crisis.ModuleName, - genutil.ModuleName, + ibc.ModuleName, genutil.ModuleName, ) app.mm.RegisterInvariants(&app.CrisisKeeper) diff --git a/types/result.go b/types/result.go index 41a31b84ba3c..5821cab538bc 100644 --- a/types/result.go +++ b/types/result.go @@ -100,6 +100,15 @@ type TxResponse struct { Events StringEvents `json:"events,omitempty"` } +func (res TxResponse) IsOK() bool { + for _, lg := range res.Logs { + if !lg.Success { + return false + } + } + return true +} + // NewResponseResultTx returns a TxResponse given a ResultTx from tendermint func NewResponseResultTx(res *ctypes.ResultTx, tx Tx, timestamp string) TxResponse { if res == nil { diff --git a/x/auth/client/utils/tx.go b/x/auth/client/utils/tx.go index d2212a039ad4..ccba257d4ded 100644 --- a/x/auth/client/utils/tx.go +++ b/x/auth/client/utils/tx.go @@ -113,6 +113,45 @@ func CompleteAndBroadcastTxCLI(txBldr authtypes.TxBuilder, cliCtx context.CLICon return cliCtx.PrintOutput(res) } +// CompleteAndBroadcastTx implements a utility function that facilitates +// sending a series of messages in a signed transaction given a TxBuilder and a +// QueryContext. It ensures that the account exists, has a proper number and +// sequence set. In addition, it builds and signs a transaction non-interactively +// with the supplied messages. Finally, it broadcasts the signed transaction to a node. +func CompleteAndBroadcastTx(txBldr authtypes.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg, passphrase string) (sdk.TxResponse, error) { + var res sdk.TxResponse + txBldr, err := PrepareTxBuilder(txBldr, cliCtx) + if err != nil { + return res, err + } + + fromName := cliCtx.GetFromName() + + if txBldr.SimulateAndExecute() || cliCtx.Simulate { + txBldr, err = EnrichWithGas(txBldr, cliCtx, msgs) + if err != nil { + return res, err + } + + gasEst := GasEstimateResponse{GasEstimate: txBldr.Gas()} + _, _ = fmt.Fprintf(os.Stderr, "%s\n", gasEst.String()) + } + + // build and sign the transaction + txBytes, err := txBldr.BuildAndSign(fromName, passphrase, msgs) + if err != nil { + return res, err + } + + // broadcast to a Tendermint node + res, err = cliCtx.BroadcastTx(txBytes) + if err != nil { + return res, err + } + + return res, err +} + // EnrichWithGas calculates the gas estimate that would be consumed by the // transaction and set the transaction's respective value accordingly. func EnrichWithGas(txBldr authtypes.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg) (authtypes.TxBuilder, error) { diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 22ccf7777d31..cef560ccdd57 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -349,6 +350,18 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } + // get passphrase for key from1 + passphrase1, err := keys.GetPassphrase(from1) + if err != nil { + return err + } + + // get passphrase for key from2 + passphrase2, err := keys.GetPassphrase(from2) + if err != nil { + return err + } + viper.Set(flags.FlagChainID, cid1) msgOpenInit := types.NewMsgConnectionOpenInit( connID1, clientID1, connID2, clientID2, @@ -359,11 +372,14 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenInit}) - if err != nil { + fmt.Printf("%v <- %-14v", cid1, msgOpenInit.Type()) + res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) + if err != nil || !res.IsOK() { return err } + fmt.Printf(" [OK] txid(%v) client(%v) conn(%v)\n", res.TxHash, clientID1, connID1) + // Another block has to be passed after msgOpenInit is committed // to retrieve the correct proofs // TODO: Modify this to actually check two blocks being processed, and @@ -383,11 +399,12 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) - if err != nil { + fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] client(%v)\n", clientID1) + fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) // Fetch proofs from cid1 viper.Set(flags.FlagChainID, cid1) @@ -409,12 +426,14 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenTry}) - if err != nil { + fmt.Printf("%v <- %-14v", cid2, msgOpenTry.Type()) + + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] client(%v) connection(%v)\n", clientID2, connID2) + fmt.Printf(" [OK] txid(%v) client(%v) connection(%v)\n", res.TxHash, clientID2, connID2) // Another block has to be passed after msgOpenInit is committed // to retrieve the correct proofs @@ -435,11 +454,11 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] client(%v)\n", clientID2) + fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID2) // Fetch proofs from cid2 viper.Set(flags.FlagChainID, cid2) @@ -461,11 +480,13 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenAck}) - if err != nil { + fmt.Printf("%v <- %-14v", cid1, msgOpenAck.Type()) + + res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] connection(%v)\n", connID1) + fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID1) // Another block has to be passed after msgOpenInit is committed // to retrieve the correct proofs @@ -486,13 +507,14 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) - if err != nil { + fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) + + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] client(%v)\n", clientID1) + fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - // Fetch proof from cid1 viper.Set(flags.FlagChainID, cid1) proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) if err != nil { @@ -507,11 +529,13 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}) - if err != nil { + fmt.Printf("%v <- %-14v", cid1, msgOpenConfirm.Type()) + + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] connection(%v)\n", connID2) + fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID2) return nil }, diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go new file mode 100644 index 000000000000..66028740581e --- /dev/null +++ b/x/ibc/20-transfer/alias.go @@ -0,0 +1,62 @@ +package transfer + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +const ( + DefaultPacketTimeout = keeper.DefaultPacketTimeout + DefaultCodespace = types.DefaultCodespace + CodeInvalidAddress = types.CodeInvalidAddress + CodeErrSendPacket = types.CodeErrSendPacket + CodeInvalidPacketData = types.CodeInvalidPacketData + CodeInvalidChannelOrder = types.CodeInvalidChannelOrder + CodeInvalidPort = types.CodeInvalidPort + CodeInvalidVersion = types.CodeInvalidVersion + AttributeKeyReceiver = types.AttributeKeyReceiver + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + BoundPortID = types.BoundPortID +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + RegisterCodec = types.RegisterCodec + ErrInvalidAddress = types.ErrInvalidAddress + ErrSendPacket = types.ErrSendPacket + ErrInvalidPacketData = types.ErrInvalidPacketData + ErrInvalidChannelOrder = types.ErrInvalidChannelOrder + ErrInvalidPort = types.ErrInvalidPort + ErrInvalidVersion = types.ErrInvalidVersion + GetEscrowAddress = types.GetEscrowAddress + GetDenomPrefix = types.GetDenomPrefix + GetModuleAccountName = types.GetModuleAccountName + NewMsgTransfer = types.NewMsgTransfer + + // variable aliases + ModuleCdc = types.ModuleCdc + AttributeValueCategory = types.AttributeValueCategory +) + +type ( + Keeper = keeper.Keeper + BankKeeper = types.BankKeeper + ChannelKeeper = types.ChannelKeeper + ClientKeeper = types.ClientKeeper + ConnectionKeeper = types.ConnectionKeeper + SupplyKeeper = types.SupplyKeeper + MsgTransfer = types.MsgTransfer + MsgRecvPacket = types.MsgRecvPacket + PacketData = types.PacketData + PacketDataAlias = types.PacketDataAlias +) diff --git a/x/ibc/20-transfer/client/cli/query.go b/x/ibc/20-transfer/client/cli/query.go new file mode 100644 index 000000000000..1795e1919edb --- /dev/null +++ b/x/ibc/20-transfer/client/cli/query.go @@ -0,0 +1,68 @@ +package cli + +import ( + "encoding/binary" + "fmt" + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/version" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + abci "github.com/tendermint/tendermint/abci/types" +) + +// GetTxCmd returns the transaction commands for IBC fungible token transfer +func GetQueryCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + queryCmd := &cobra.Command{ + Use: "transfer", + Short: "IBC fungible token transfer query subcommands", + } + + queryCmd.AddCommand( + GetCmdQueryNextSequence(cdc, storeKey), + ) + + return queryCmd +} + +// GetCmdQueryNextSequence defines the command to query a next receive sequence +func GetCmdQueryNextSequence(cdc *codec.Codec, queryRoute string) *cobra.Command { + cmd := &cobra.Command{ + Use: "next-recv [port-id] [channel-id]", + Short: "Query a next receive sequence", + Long: strings.TrimSpace(fmt.Sprintf(`Query an IBC channel end + +Example: +$ %s query ibc channel next-recv [port-id] [channel-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + portID := args[0] + channelID := args[1] + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: channel.KeyNextSequenceRecv(portID, channelID), + Prove: true, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return err + } + + sequence := binary.BigEndian.Uint64(res.Value) + + return cliCtx.PrintOutput(sequence) + }, + } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + + return cmd +} diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go new file mode 100644 index 000000000000..28870567b55c --- /dev/null +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -0,0 +1,150 @@ +package cli + +import ( + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + channelutils "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// IBC transfer flags +var ( + FlagSource = "source" + FlagNode1 = "node1" + FlagNode2 = "node2" + FlagFrom1 = "from1" + FlagFrom2 = "from2" + FlagChainId2 = "chain-id2" + FlagSequence = "packet-sequence" + FlagTimeout = "timeout" +) + +// GetTxCmd returns the transaction commands for IBC fungible token transfer +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + txCmd := &cobra.Command{ + Use: "transfer", + Short: "IBC fungible token transfer transaction subcommands", + } + txCmd.AddCommand( + GetTransferTxCmd(cdc), + GetMsgRecvPacketCmd(cdc), + ) + + return txCmd +} + +// GetTransferTxCmd returns the command to create a NewMsgTransfer transaction +func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "transfer [src-port] [src-channel] [receiver] [amount]", + Short: "Transfer fungible token through IBC", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + + sender := ctx.GetFromAddress() + srcPort := args[0] + srcChannel := args[1] + receiver, err := sdk.AccAddressFromBech32(args[2]) + if err != nil { + return err + } + + // parse coin trying to be sent + coins, err := sdk.ParseCoins(args[3]) + if err != nil { + return err + } + + source := viper.GetBool(FlagSource) + + msg := types.NewMsgTransfer(srcPort, srcChannel, coins, sender, receiver, source) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(ctx, txBldr, []sdk.Msg{msg}) + }, + } + cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") + cmd.Flags().String(flags.FlagFrom, "", "key in local keystore to send from") + return cmd +} + +// GetMsgRecvPacketCmd returns the command to create a MsgRecvTransferPacket transaction +func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "recv-packet [sending-port-id] [sending-channel-id] [client-id]", + Short: "Creates and sends a SendPacket message", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + + node2 := viper.GetString(FlagNode2) + cid1 := viper.GetString(flags.FlagChainID) + cid2 := viper.GetString(FlagChainId2) + cliCtx2 := context.NewCLIContextIBC(cliCtx.GetFromAddress().String(), cid2, node2). + WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + header, err := clientutils.GetTendermintHeader(cliCtx2) + if err != nil { + return err + } + + sourcePort, sourceChannel, clientid := args[0], args[1], args[2] + + passphrase, err := keys.GetPassphrase(viper.GetString(flags.FlagFrom)) + if err != nil { + return nil + } + + viper.Set(flags.FlagChainID, cid1) + msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid, header, cliCtx.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + res, err := utils.CompleteAndBroadcastTx(txBldr, cliCtx, []sdk.Msg{msgUpdateClient}, passphrase) + if err != nil || !res.IsOK() { + return err + } + + viper.Set(flags.FlagChainID, cid2) + sequence := uint64(viper.GetInt(FlagSequence)) + packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), "ibc") + if err != nil { + return err + } + viper.Set(flags.FlagChainID, cid1) + + msg := types.NewMsgRecvPacket(packetRes.Packet, []commitment.Proof{packetRes.Proof}, packetRes.ProofHeight, cliCtx.GetFromAddress()) + if err := msg.ValidateBasic(); err != nil { + return err + } + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + + cmd = client.PostCommands(cmd)[0] + cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") + cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") + cmd.Flags().String(FlagChainId2, "", "chain-id for the second chain") + cmd.Flags().String(FlagSequence, "", "sequence for the packet") + cmd.Flags().String(FlagTimeout, "", "timeout for the packet") + return cmd +} diff --git a/x/ibc/20-transfer/genesis.go b/x/ibc/20-transfer/genesis.go new file mode 100644 index 000000000000..facde722a27d --- /dev/null +++ b/x/ibc/20-transfer/genesis.go @@ -0,0 +1,17 @@ +package transfer + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +// InitGenesis sets distribution information for genesis +func InitGenesis(ctx sdk.Context, keeper Keeper) { + // check if the module account exists + moduleAcc := keeper.GetTransferAccount(ctx) + if moduleAcc == nil { + panic(fmt.Sprintf("%s module account has not been set", types.GetModuleAccountName())) + } +} diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go new file mode 100644 index 000000000000..731a6c27e7f5 --- /dev/null +++ b/x/ibc/20-transfer/handler.go @@ -0,0 +1,43 @@ +package transfer + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +// HandleMsgTransfer defines the sdk.Handler for MsgTransfer +func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Result) { + err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), + sdk.NewAttribute(types.AttributeKeyReceiver, msg.Receiver.String()), + ), + ) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgRecvPacket defines the sdk.Handler for MsgRecvPacket +func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (res sdk.Result) { + err := k.ReceivePacket(ctx, msg.Packet, msg.Proofs[0], msg.Height) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + ) + + return sdk.Result{Events: ctx.EventManager().Events()} +} diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go new file mode 100644 index 000000000000..8594783e6456 --- /dev/null +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -0,0 +1,184 @@ +package keeper + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +// nolint: unused +func (k Keeper) onChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + counterparty channeltypes.Counterparty, + version string, +) error { + if order != channeltypes.UNORDERED { + return types.ErrInvalidChannelOrder(k.codespace, order.String()) + } + + if counterparty.PortID != types.BoundPortID { + return types.ErrInvalidPort(k.codespace, portID) + } + + if strings.TrimSpace(version) != "" { + return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + } + + // NOTE: as the escrow address is generated from both the port and channel IDs + // there's no need to store it on a map. + return nil +} + +// nolint: unused +func (k Keeper) onChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + counterparty channeltypes.Counterparty, + version string, + counterpartyVersion string, +) error { + if order != channeltypes.UNORDERED { + return types.ErrInvalidChannelOrder(k.codespace, order.String()) + } + + if counterparty.PortID != types.BoundPortID { + return types.ErrInvalidPort(k.codespace, portID) + } + + if strings.TrimSpace(version) != "" { + return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + } + + if strings.TrimSpace(counterpartyVersion) != "" { + return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid counterparty version: %s", version)) + } + + // NOTE: as the escrow address is generated from both the port and channel IDs + // there's no need to store it on a map. + return nil +} + +// nolint: unused +func (k Keeper) onChanOpenAck( + ctx sdk.Context, + portID, + channelID string, + version string, +) error { + if strings.TrimSpace(version) != "" { + return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + } + + return nil +} + +// nolint: unused +func (k Keeper) onChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + // no-op + return nil +} + +// nolint: unused +func (k Keeper) onChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + // no-op + return nil +} + +// nolint: unused +func (k Keeper) onChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + // no-op + return nil +} + +// onRecvPacket is called when an FTTransfer packet is received +// nolint: unused +func (k Keeper) onRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, +) error { + var data types.PacketData + + err := data.UnmarshalJSON(packet.GetData()) + if err != nil { + return types.ErrInvalidPacketData(k.codespace) + } + + return k.ReceiveTransfer( + ctx, packet.GetSourcePort(), packet.GetSourceChannel(), + packet.GetDestPort(), packet.GetDestChannel(), data, + ) +} + +// nolint: unused +func (k Keeper) onAcknowledgePacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, +) error { + // no-op + return nil +} + +// nolint: unused +func (k Keeper) onTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, +) error { + var data types.PacketData + + err := data.UnmarshalJSON(packet.GetData()) + if err != nil { + return types.ErrInvalidPacketData(k.codespace) + } + + // check the denom prefix + prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourcePort()) + coins := make(sdk.Coins, len(data.Amount)) + for i, coin := range data.Amount { + coin := coin + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) + } + + if data.Source { + escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) + return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Sender, coins) + } + + // mint from supply + err = k.supplyKeeper.MintCoins(ctx, types.GetModuleAccountName(), data.Amount) + if err != nil { + return err + } + + return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Sender, data.Amount) +} + +// nolint: unused +func (k Keeper) onTimeoutPacketClose(_ sdk.Context, _ channeltypes.Packet) { + panic("can't happen, only unordered channels allowed") +} diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go new file mode 100644 index 000000000000..95576d4609f3 --- /dev/null +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -0,0 +1,68 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" +) + +// DefaultPacketTimeout is the default packet timeout relative to the current block height +const ( + DefaultPacketTimeout = 1000 // NOTE: in blocks +) + +// Keeper defines the IBC transfer keeper +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store + + clientKeeper types.ClientKeeper + connectionKeeper types.ConnectionKeeper + channelKeeper types.ChannelKeeper + bankKeeper types.BankKeeper + supplyKeeper types.SupplyKeeper +} + +// NewKeeper creates a new IBC transfer Keeper instance +func NewKeeper( + cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + clientKeeper types.ClientKeeper, connnectionKeeper types.ConnectionKeeper, + channelKeeper types.ChannelKeeper, bankKeeper types.BankKeeper, + supplyKeeper types.SupplyKeeper, +) Keeper { + + // ensure ibc transfer module account is set + if addr := supplyKeeper.GetModuleAddress(types.GetModuleAccountName()); addr == nil { + panic("the IBC transfer module account has not been set") + } + + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/transfer", + prefix: []byte(types.SubModuleName + "/"), // "transfer/" + clientKeeper: clientKeeper, + connectionKeeper: connnectionKeeper, + channelKeeper: channelKeeper, + bankKeeper: bankKeeper, + supplyKeeper: supplyKeeper, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName)) +} + +// GetTransferAccount returns the ICS20 - transfers ModuleAccount +func (k Keeper) GetTransferAccount(ctx sdk.Context) supplyexported.ModuleAccountI { + return k.supplyKeeper.GetModuleAccount(ctx, types.GetModuleAccountName()) +} diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go new file mode 100644 index 000000000000..77c423052098 --- /dev/null +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -0,0 +1,35 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/keeper" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.keeper = &app.IBCKeeper.TransferKeeper +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go new file mode 100644 index 000000000000..d87a589bbd80 --- /dev/null +++ b/x/ibc/20-transfer/keeper/relay.go @@ -0,0 +1,193 @@ +package keeper + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// SendTransfer handles transfer sending logic +func (k Keeper) SendTransfer( + ctx sdk.Context, + sourcePort, + sourceChannel string, + amount sdk.Coins, + sender, + receiver sdk.AccAddress, + isSourceChain bool, +) error { + // get the port and channel of the counterparty + channel, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) + if !found { + return channeltypes.ErrChannelNotFound(k.codespace, sourcePort, sourceChannel) + } + + destinationPort := channel.Counterparty.PortID + destinationChannel := channel.Counterparty.ChannelID + + // get the next sequence + sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel) + if !found { + return channeltypes.ErrSequenceNotFound(k.codespace, "send") + } + + coins := make(sdk.Coins, len(amount)) + prefix := types.GetDenomPrefix(destinationPort, destinationChannel) + switch { + case isSourceChain: + // build the receiving denomination prefix + for i, coin := range amount { + coins[i] = sdk.NewCoin(prefix+coin.Denom, coin.Amount) + } + default: + coins = amount + } + + return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, coins, sender, receiver, isSourceChain) +} + +// ReceivePacket handles receiving packet +func (k Keeper) ReceivePacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, height uint64) error { + _, err := k.channelKeeper.RecvPacket(ctx, packet, proof, height, nil, k.storeKey) + if err != nil { + return err + } + + var data types.PacketData + err = data.UnmarshalJSON(packet.GetData()) + if err != nil { + return sdk.NewError(types.DefaultCodespace, types.CodeInvalidPacketData, "invalid packet data") + } + + return k.ReceiveTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestPort(), packet.GetDestChannel(), data) +} + +// ReceiveTransfer handles transfer receiving logic +func (k Keeper) ReceiveTransfer( + ctx sdk.Context, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel string, + data types.PacketData, +) error { + if data.Source { + prefix := types.GetDenomPrefix(destinationPort, destinationChannel) + for _, coin := range data.Amount { + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + } + + // mint new tokens if the source of the transfer is the same chain + err := k.supplyKeeper.MintCoins(ctx, types.GetModuleAccountName(), data.Amount) + if err != nil { + return err + } + + // send to receiver + return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Receiver, data.Amount) + } + + // unescrow tokens + + // check the denom prefix + prefix := types.GetDenomPrefix(sourcePort, sourceChannel) + coins := make(sdk.Coins, len(data.Amount)) + for i, coin := range data.Amount { + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) + } + + escrowAddress := types.GetEscrowAddress(destinationPort, destinationChannel) + return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Receiver, coins) + +} + +func (k Keeper) createOutgoingPacket( + ctx sdk.Context, + seq uint64, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel string, + amount sdk.Coins, + sender sdk.AccAddress, + receiver sdk.AccAddress, + isSourceChain bool, +) error { + if isSourceChain { + // escrow tokens if the destination chain is the same as the sender's + escrowAddress := types.GetEscrowAddress(sourcePort, sourceChannel) + + prefix := types.GetDenomPrefix(destinationPort, destinationChannel) + coins := make(sdk.Coins, len(amount)) + for i, coin := range amount { + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) + } + + err := k.bankKeeper.SendCoins(ctx, sender, escrowAddress, coins) + if err != nil { + return err + } + + } else { + // burn vouchers from the sender's balance if the source is from another chain + prefix := types.GetDenomPrefix(sourcePort, sourceChannel) + for _, coin := range amount { + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + } + + // transfer the coins to the module account and burn them + err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, sender, types.GetModuleAccountName(), amount) + if err != nil { + return err + } + + // burn from supply + err = k.supplyKeeper.BurnCoins(ctx, types.GetModuleAccountName(), amount) + if err != nil { + return err + } + } + + packetData := types.PacketData{ + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: isSourceChain, + } + + // TODO: This should be binary-marshaled and hashed (for the commitment in the store). + packetDataBz, err := packetData.MarshalJSON() + if err != nil { + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidPacketData, "invalid packet data") + } + + packet := channeltypes.NewPacket( + seq, + uint64(ctx.BlockHeight())+DefaultPacketTimeout, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + packetDataBz, + ) + + // TODO: Remove this, capability keys are never generated when sending packets. Not sure why this is here. + key := sdk.NewKVStoreKey(types.BoundPortID) + + return k.channelKeeper.SendPacket(ctx, packet, key) +} diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go new file mode 100644 index 000000000000..e6aa98f9eacd --- /dev/null +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -0,0 +1,6 @@ +package keeper_test + +func (suite *KeeperTestSuite) TestSendTransfer() { + err := suite.keeper.SendTransfer(suite.ctx, "", "", nil, nil, nil, true) + suite.Error(err) +} diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go new file mode 100644 index 000000000000..269be2377f6e --- /dev/null +++ b/x/ibc/20-transfer/module.go @@ -0,0 +1,18 @@ +package transfer + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/cli" +) + +// Name returns the IBC transfer ICS name +func Name() string { + return SubModuleName +} + +// GetTxCmd returns the root tx command for the IBC transfer. +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetTxCmd(cdc) +} diff --git a/x/ibc/20-transfer/types/codec.go b/x/ibc/20-transfer/types/codec.go new file mode 100644 index 000000000000..ba018b3fc676 --- /dev/null +++ b/x/ibc/20-transfer/types/codec.go @@ -0,0 +1,21 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterConcrete(MsgTransfer{}, "ibc/transfer/MsgTransfer", nil) + cdc.RegisterConcrete(MsgRecvPacket{}, "ibc/transfer/MsgRecvPacket", nil) + cdc.RegisterConcrete(PacketData{}, "ibc/transfer/PacketData", nil) +} + +var ModuleCdc = codec.New() + +func init() { + RegisterCodec(ModuleCdc) + channel.RegisterCodec(ModuleCdc) + commitment.RegisterCodec(ModuleCdc) +} diff --git a/x/ibc/20-transfer/types/errors.go b/x/ibc/20-transfer/types/errors.go new file mode 100644 index 000000000000..51f95d560a01 --- /dev/null +++ b/x/ibc/20-transfer/types/errors.go @@ -0,0 +1,51 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// transfer error codes +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName + + CodeInvalidAddress sdk.CodeType = 101 + CodeErrSendPacket sdk.CodeType = 102 + CodeInvalidPacketData sdk.CodeType = 103 + CodeInvalidChannelOrder sdk.CodeType = 104 + CodeInvalidPort sdk.CodeType = 105 + CodeInvalidVersion sdk.CodeType = 106 + CodeProofMissing sdk.CodeType = 107 + CodeInvalidHeight sdk.CodeType = 108 +) + +// ErrInvalidAddress implements sdk.Error +func ErrInvalidAddress(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidAddress, msg) +} + +// ErrSendPacket implements sdk.Error +func ErrSendPacket(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeErrSendPacket, "failed to send packet") +} + +// ErrInvalidPacketData implements sdk.Error +func ErrInvalidPacketData(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidPacketData, "invalid packet data") +} + +// ErrInvalidChannelOrder implements sdk.Error +func ErrInvalidChannelOrder(codespace sdk.CodespaceType, order string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidChannelOrder, fmt.Sprintf("invalid channel order: %s", order)) +} + +// ErrInvalidPort implements sdk.Error +func ErrInvalidPort(codespace sdk.CodespaceType, portID string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidPort, fmt.Sprintf("invalid port ID: %s", portID)) +} + +// ErrInvalidVersion implements sdk.Error +func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidVersion, msg) +} diff --git a/x/ibc/20-transfer/types/events.go b/x/ibc/20-transfer/types/events.go new file mode 100644 index 000000000000..759548ae1827 --- /dev/null +++ b/x/ibc/20-transfer/types/events.go @@ -0,0 +1,17 @@ +package types + +import ( + "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// IBC transfer events +const ( + AttributeKeyReceiver = "receiver" +) + +// IBC transfer events vars +var ( + AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) +) diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go new file mode 100644 index 000000000000..252eb8060645 --- /dev/null +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -0,0 +1,44 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" +) + +// BankKeeper defines the expected bank keeper +type BankKeeper interface { + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error +} + +// ChannelKeeper defines the expected IBC channel keeper +type ChannelKeeper interface { + GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channel.Channel, found bool) + GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) + SendPacket(ctx sdk.Context, packet channelexported.PacketI, portCapability sdk.CapabilityKey) error + RecvPacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, proofHeight uint64, acknowledgement []byte, portCapability sdk.CapabilityKey) (channelexported.PacketI, error) +} + +// ClientKeeper defines the expected IBC client keeper +type ClientKeeper interface { + GetConsensusState(ctx sdk.Context, clientID string) (connection clientexported.ConsensusState, found bool) +} + +// ConnectionKeeper defines the expected IBC connection keeper +type ConnectionKeeper interface { + GetConnection(ctx sdk.Context, connectionID string) (connection connection.ConnectionEnd, found bool) +} + +// SupplyKeeper expected supply keeper +type SupplyKeeper interface { + GetModuleAddress(name string) sdk.AccAddress + GetModuleAccount(ctx sdk.Context, name string) supplyexported.ModuleAccountI + MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error + BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error +} diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go new file mode 100644 index 000000000000..09b54dcadea5 --- /dev/null +++ b/x/ibc/20-transfer/types/keys.go @@ -0,0 +1,46 @@ +package types + +import ( + "fmt" + + "github.com/tendermint/tendermint/crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +const ( + // SubModuleName defines the IBC transfer name + SubModuleName = "transfer" + + // StoreKey is the store key string for IBC transfer + StoreKey = SubModuleName + + // RouterKey is the message route for IBC transfer + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC transfer + QuerierRoute = SubModuleName + + // BoundPortID defines the name of the capability key + BoundPortID = "bank" +) + +// GetEscrowAddress returns the escrow address for the specified channel +// +// CONTRACT: this assumes that there's only one bank bridge module that owns the +// port associated with the channel ID so that the address created is actually +// unique. +func GetEscrowAddress(portID, channelID string) sdk.AccAddress { + return sdk.AccAddress(crypto.AddressHash([]byte(portID + channelID))) +} + +// GetDenomPrefix returns the receiving denomination prefix +func GetDenomPrefix(portID, channelID string) string { + return fmt.Sprintf("%s/%s/", portID, channelID) +} + +// GetModuleAccountName returns the IBC transfer module account name for supply +func GetModuleAccountName() string { + return fmt.Sprintf("%s/%s", ibctypes.ModuleName, SubModuleName) +} diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go new file mode 100644 index 000000000000..506676e66d7e --- /dev/null +++ b/x/ibc/20-transfer/types/msgs.go @@ -0,0 +1,138 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +type MsgTransfer struct { + SourcePort string `json:"source_port" yaml:"source_port"` // the port on which the packet will be sent + SourceChannel string `json:"source_channel" yaml:"source_channel"` // the channel by which the packet will be sent + Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred + Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address + Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain + Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred +} + +// NewMsgTransfer creates a new MsgTransfer instance +func NewMsgTransfer( + sourcePort, sourceChannel string, amount sdk.Coins, sender, receiver sdk.AccAddress, source bool, +) MsgTransfer { + return MsgTransfer{ + SourcePort: sourcePort, + SourceChannel: sourceChannel, + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, + } +} + +// Route implements sdk.Msg +func (MsgTransfer) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (MsgTransfer) Type() string { + return "transfer" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgTransfer) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.SourcePort); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultPortIdentifierValidator(msg.SourceChannel); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if !msg.Amount.IsValid() { + return sdk.ErrInvalidCoins("transfer amount is invalid") + } + if !msg.Amount.IsAllPositive() { + return sdk.ErrInsufficientCoins("transfer amount must be positive") + } + if msg.Sender.Empty() { + return sdk.ErrInvalidAddress("missing sender address") + } + if msg.Receiver.Empty() { + return sdk.ErrInvalidAddress("missing recipient address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgTransfer) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgTransfer) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Sender} +} + +type MsgRecvPacket struct { + Packet channelexported.PacketI `json:"packet" yaml:"packet"` + Proofs []commitment.Proof `json:"proofs" yaml:"proofs"` + Height uint64 `json:"height" yaml:"height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` +} + +// NewMsgRecvPacket creates a new MsgRecvPacket instance +func NewMsgRecvPacket(packet channelexported.PacketI, proofs []commitment.Proof, height uint64, signer sdk.AccAddress) MsgRecvPacket { + return MsgRecvPacket{ + Packet: packet, + Proofs: proofs, + Height: height, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (MsgRecvPacket) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (MsgRecvPacket) Type() string { + return "recv_packet" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgRecvPacket) ValidateBasic() sdk.Error { + if msg.Height < 1 { + return sdk.NewError(DefaultCodespace, CodeInvalidHeight, "invalid height") + } + + if msg.Proofs == nil { + return sdk.NewError(DefaultCodespace, CodeProofMissing, "proof missing") + } + + for _, proof := range msg.Proofs { + if proof.Proof == nil { + return sdk.NewError(DefaultCodespace, CodeProofMissing, "proof missing") + } + } + + if msg.Signer.Empty() { + return sdk.NewError(DefaultCodespace, CodeInvalidAddress, "invalid signer") + } + + return msg.Packet.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgRecvPacket) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgRecvPacket) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go new file mode 100644 index 000000000000..a9df673cc19f --- /dev/null +++ b/x/ibc/20-transfer/types/packet.go @@ -0,0 +1,70 @@ +package types + +import ( + "encoding/json" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// PacketData defines a struct for the packet payload +type PacketData struct { + Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred + Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address + Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain + Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred +} + +func (pd PacketData) MarshalAmino() ([]byte, error) { + return ModuleCdc.MarshalBinaryBare(pd) +} + +func (pd *PacketData) UnmarshalAmino(bz []byte) (err error) { + return ModuleCdc.UnmarshalBinaryBare(bz, pd) +} + +func (pd PacketData) Marshal() []byte { + return ModuleCdc.MustMarshalBinaryBare(pd) +} + +type PacketDataAlias PacketData + +// MarshalJSON implements the json.Marshaler interface. +func (pd PacketData) MarshalJSON() ([]byte, error) { + return json.Marshal((PacketDataAlias)(pd)) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (pd *PacketData) UnmarshalJSON(bz []byte) (err error) { + return json.Unmarshal(bz, (*PacketDataAlias)(pd)) +} + +func (pd PacketData) String() string { + return fmt.Sprintf(`PacketData: + Amount: %s + Sender: %s + Receiver: %s + Source: %v`, + pd.Amount.String(), + pd.Sender, + pd.Receiver, + pd.Source, + ) +} + +// ValidateBasic performs a basic check of the packet fields +func (pd PacketData) ValidateBasic() sdk.Error { + if !pd.Amount.IsValid() { + return sdk.ErrInvalidCoins("transfer amount is invalid") + } + if !pd.Amount.IsAllPositive() { + return sdk.ErrInsufficientCoins("transfer amount must be positive") + } + if pd.Sender.Empty() { + return sdk.ErrInvalidAddress("missing sender address") + } + if pd.Receiver.Empty() { + return sdk.ErrInvalidAddress("missing recipient address") + } + return nil +} diff --git a/x/ibc/alias.go b/x/ibc/alias.go index 7c1ad02349e2..abb2aae3c59a 100644 --- a/x/ibc/alias.go +++ b/x/ibc/alias.go @@ -12,10 +12,11 @@ import ( ) const ( - ModuleName = types.ModuleName - StoreKey = types.StoreKey - QuerierRoute = types.QuerierRoute - RouterKey = types.RouterKey + ModuleName = types.ModuleName + StoreKey = types.StoreKey + QuerierRoute = types.QuerierRoute + RouterKey = types.RouterKey + DefaultCodespace = types.DefaultCodespace ) var ( diff --git a/x/ibc/ante.go b/x/ibc/ante.go new file mode 100644 index 000000000000..0e1f7f635d70 --- /dev/null +++ b/x/ibc/ante.go @@ -0,0 +1,51 @@ +package ibc + +// // TODO: Should extract timeout msgs too +// func ExtractMsgPackets(msgs []sdk.Msg) (res []MsgPacket, abort bool) { +// res = make([]MsgPacket, 0, len(msgs)) +// for _, msg := range msgs { +// msgp, ok := msg.(MsgPacket) +// if ok { +// res = append(res, msgp) +// } +// } + +// if len(res) >= 2 { +// first := res[0] +// for _, msg := range res[1:] { +// if len(msg.ChannelID) != 0 && msg.ChannelID != first.ChannelID { +// return res, true +// } +// msg.ChannelID = first.ChannelID +// } +// } + +// return +// } + +// func VerifyMsgPackets(ctx sdk.Context, channel channel.Manager, msgs []MsgPacket) error { +// for _, msg := range msgs { +// err := channel.Receive(ctx, msg.Proofs, msg.Height, msg.ReceiverPort(), msg.ChannelID, msg.Packet) +// if err != nil { +// return err +// } +// } + +// return nil +// } + +// func NewAnteDecorator(channel channel.Manager) sdk.AnteDecorator { +// return func(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { +// msgs, abort := ExtractMsgPackets(tx.GetMsgs()) +// if abort { +// return ctx, host.ErrInvalidPacket +// } + +// err := VerifyMsgPackets(ctx, channel, msgs) +// if err != nil { +// return ctx, sdkerrors.Wrap(host.ErrInvalidPacket, err.Error()) +// } + +// return next(ctx, tx, simulate) +// } +// } diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index 04289628f640..cc6bd3bd7822 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -7,6 +7,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -23,6 +25,8 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ibcTxCmd.AddCommand(client.PostCommands( ibcclient.GetTxCmd(cdc, storeKey), connection.GetTxCmd(cdc, storeKey), + channel.GetTxCmd(cdc, storeKey), + transfer.GetTxCmd(cdc), )...) return ibcTxCmd } diff --git a/x/ibc/handler.go b/x/ibc/handler.go index b80267dd7d92..07fc9f831be8 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -7,6 +7,7 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" ) // NewHandler defines the IBC handler @@ -57,6 +58,13 @@ func NewHandler(k Keeper) sdk.Handler { case channel.MsgChannelCloseConfirm: return channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, msg) + // IBC transfer msgs + case transfer.MsgTransfer: + return transfer.HandleMsgTransfer(ctx, k.TransferKeeper, msg) + + case transfer.MsgRecvPacket: + return transfer.HandleMsgRecvPacket(ctx, k.TransferKeeper, msg) + default: errMsg := fmt.Sprintf("unrecognized IBC message type: %T", msg) return sdk.ErrUnknownRequest(errMsg).Result() diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 52158b48b140..2145416efb55 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -7,6 +7,7 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" ) // Keeper defines each ICS keeper for IBC @@ -15,19 +16,25 @@ type Keeper struct { ConnectionKeeper connection.Keeper ChannelKeeper channel.Keeper PortKeeper port.Keeper + TransferKeeper transfer.Keeper } // NewKeeper creates a new ibc Keeper -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { +func NewKeeper( + cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + bk transfer.BankKeeper, sk transfer.SupplyKeeper, +) Keeper { clientKeeper := client.NewKeeper(cdc, key, codespace) connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) portKeeper := port.NewKeeper(cdc, key, codespace) channelKeeper := channel.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, portKeeper) + transferKeeper := transfer.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, channelKeeper, bk, sk) return Keeper{ ClientKeeper: clientKeeper, ConnectionKeeper: connectionKeeper, ChannelKeeper: channelKeeper, PortKeeper: portKeeper, + TransferKeeper: transferKeeper, } } diff --git a/x/ibc/keeper/keeper_test.go b/x/ibc/keeper/keeper_test.go new file mode 100644 index 000000000000..4aee65b6db9e --- /dev/null +++ b/x/ibc/keeper/keeper_test.go @@ -0,0 +1,37 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/keeper" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper + querier sdk.Querier +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.keeper = &app.IBCKeeper + suite.querier = keeper.NewQuerier(app.IBCKeeper) +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index fc2527df104c..ee934fabd018 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -26,7 +26,6 @@ func NewQuerier(k Keeper) sdk.Querier { default: return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName)) } - case connection.SubModuleName: switch path[1] { case connection.QueryConnection: @@ -36,7 +35,6 @@ func NewQuerier(k Keeper) sdk.Querier { default: return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName)) } - case channel.SubModuleName: switch path[1] { case channel.QueryChannel: @@ -44,7 +42,6 @@ func NewQuerier(k Keeper) sdk.Querier { default: return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", channel.SubModuleName)) } - default: return nil, sdk.ErrUnknownRequest("unknown IBC query endpoint") } diff --git a/x/ibc/keeper/querier_test.go b/x/ibc/keeper/querier_test.go new file mode 100644 index 000000000000..62e37faac203 --- /dev/null +++ b/x/ibc/keeper/querier_test.go @@ -0,0 +1,102 @@ +package keeper_test + +import ( + "fmt" + + "github.com/stretchr/testify/require" + + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + + abci "github.com/tendermint/tendermint/abci/types" +) + +// TestNewQuerier tests that the querier paths are correct. +// NOTE: the actuall testing functionallity are located on each ICS querier test. +func (suite *KeeperTestSuite) TestNewQuerier() { + + query := abci.RequestQuery{ + Path: "", + Data: []byte{}, + } + + cases := []struct { + name string + path []string + expectsDefaultErr bool + errMsg string + }{ + {"client - QueryClientState", + []string{client.SubModuleName, client.QueryClientState}, + false, + "", + }, + { + "client - QueryConsensusState", + []string{client.SubModuleName, client.QueryConsensusState}, + false, + "", + }, + { + "client - QueryVerifiedRoot", + []string{client.SubModuleName, client.QueryVerifiedRoot}, + false, + "", + }, + { + "client - invalid query", + []string{client.SubModuleName, "foo"}, + true, + fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName), + }, + { + "connection - QueryConnection", + []string{connection.SubModuleName, connection.QueryConnection}, + false, + "", + }, + { + "connection - QueryClientConnections", + []string{connection.SubModuleName, connection.QueryClientConnections}, + false, + "", + }, + { + "connection - invalid query", + []string{connection.SubModuleName, "foo"}, + true, + fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName), + }, + { + "channel - QueryChannel", + []string{channel.SubModuleName, channel.QueryChannel}, + false, + "", + }, + { + "channel - invalid query", + []string{channel.SubModuleName, "foo"}, + true, + fmt.Sprintf("unknown IBC %s query endpoint", channel.SubModuleName), + }, + { + "invalid query", + []string{"foo"}, + true, + "unknown IBC query endpoint", + }, + } + + for i, tc := range cases { + i, tc := i, tc + suite.Run(tc.name, func() { + _, err := suite.querier(suite.ctx, tc.path, query) + if tc.expectsDefaultErr { + require.Contains(suite.T(), err.Error(), tc.errMsg, "test case #%d", i) + } else { + suite.Error(err, "test case #%d", i) + } + }) + } +} diff --git a/x/ibc/module.go b/x/ibc/module.go index 791517826f03..2e91d5540df0 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -15,6 +15,7 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -41,6 +42,7 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) channel.RegisterCodec(cdc) + transfer.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } @@ -116,6 +118,8 @@ func (am AppModule) NewQuerierHandler() sdk.Querier { // InitGenesis performs genesis initialization for the staking module. It returns // no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { + // check if the IBC transfer module account is set + transfer.InitGenesis(ctx, am.keeper.TransferKeeper) return []abci.ValidatorUpdate{} } diff --git a/x/ibc/types/types.go b/x/ibc/types/types.go index 535a8f2461e5..bce43911994f 100644 --- a/x/ibc/types/types.go +++ b/x/ibc/types/types.go @@ -1,15 +1,22 @@ package types +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + const ( // ModuleName is the name of the IBC module ModuleName = "ibc" // StoreKey is the string store representation - StoreKey = ModuleName + StoreKey string = ModuleName // QuerierRoute is the querier route for the IBC module - QuerierRoute = ModuleName + QuerierRoute string = ModuleName // RouterKey is the msg router key for the IBC module - RouterKey = ModuleName + RouterKey string = ModuleName + + // DefaultCodespace of the IBC module + DefaultCodespace sdk.CodespaceType = ModuleName ) From 4dda39e21ee7233f347edf083a766677769009f9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 5 Nov 2019 18:20:44 +0100 Subject: [PATCH 008/176] IBC demo fixes (#5267) * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * refactor: remove store accessors, update keeper and types to match spec (WIP) * update handshake and packet * implement packet timeouts * implement send and receive packet * implement packet ACK * update handler * add channel errors * channel querier * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update ICS04 with downstream changes * Implement tx cli actions * add MsgSendPacket handler; msg validation, errors and events * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * rm legacy tests; add query proofs support * remove capability key generation and authentication logic * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * downstream changes; custom marshal JSON; msg validation, and update errors * update errors and aliases * start batch-verify tests * update msg validation and CLI UX * minor changes on commitment types * fix channel and packet check (#5243) * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * authenticate port ID; remove send packet msg from CLI * comment out handlers * add ibc module to simapp * ICS20 implementation (#5204) * add ibc bank mock * modify handler * import channel * add receiving logic * add cli proof handling * modify cli * modify receiver type * modify errcode * optimize codes * add denom prefix when source is true * refactor code * error return * switch ibc antehandler to decorator pattern * fix name/comment * ICS 20 implementation (#5250) * move ics20 code to 20-transfer * clean code * fix compiling error * add transfer module * address ICS20 comments from review * add routing callbacks * clean code * add missing err return * modify err type * modify err type * add supply handling * modify proof type * add comments for msg and packet data * add timeout supply handling * modify module account name * use supply keeper for burn and mint coins * restructure keeper * update alias and module.go * golangci linter * add ics20 handler to IBC handler * update callbacks * update ICS20 escrow address * fix querier routes * fix create client cli * minor updates * ibc querier test * Refactor ibc/mock/bank into ICS 20 (#5264) * Most of code port from mock module to ICS 20 * A few minor fixes * Apply suggestions from code review Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * Fix suggestions from autolinter * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Fix order of messages * Add invalid height error code, check non-nil proof * Fix linter error * Return the underlying error * Tendermint starts at height 1 * Apply suggestions from code review * setup ics20 test suite * add event to MsgRecvPacket * update ibc keeper test to use test suite * Add handshake commands * WIP connection handshake * WIP Connection Handshake * use testsuite * Add cliCtx.WaitForNBlocks * fix connection handshake in progress * fix connection handshake in progress * Add print debugging (old-school) * Add log line * More debugging * Set prove flag to true * More debugging * Use store query * Fix query, hopefully * Fix query path * Hmm * Fix context bug * Generate & return & use consensus state proof * Print debugging * Add debugging * Begin working on the channel creation command * remove submodule prefix from keypath, fix addConnectionToClients to treat nil as empty array * fix OpenConfirm, rm debugging code * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * Update bound port * Add from flag to ICS 20 commands * Undefine flag * add debug * Uncomment channel message handlers * fix validatebasic identifier failure * Fix printing * add debug code * CLI debugging * fix counterpartyHops, channel handshake working w/o port * Fix compilation error * Push channel query command update * Remove unused code * Add gaiacli keys test * Update error * Add printf * fix token restriciton * comment out port * fix querier to retrieve the next sequence * Alter command to take arguments * Name it packet-sequence * add packet query utils * Use the querier * Packet is JSON * printf the value * fix query packet * fix packet receive in progress * lol * export Packet fields, rename Packet.XXX() -> Packet.GetXXX() * fix route * add debug * comment out port logic from packet.go * token transfer now working * fix client tx * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * Apply suggestions from code review * clean up * finish tendermint tests * complete merge * Add tests for msgs * ICS02 changes * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * upstream changes * upstream changes * upstream changes * more cleanup --- client/keys/add.go | 35 +++++++++++++++++++ client/keys/root.go | 1 + types/coin.go | 4 +-- x/ibc/04-channel/client/cli/tx.go | 49 ++++++++++++++------------- x/ibc/20-transfer/client/cli/query.go | 6 ++-- x/ibc/20-transfer/client/cli/tx.go | 8 ++--- x/ibc/20-transfer/module.go | 5 +++ x/ibc/client/cli/cli.go | 2 ++ 8 files changed, 77 insertions(+), 33 deletions(-) diff --git a/client/keys/add.go b/client/keys/add.go index 8ff444010a00..5c07da49aea8 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -36,6 +36,41 @@ const ( DefaultKeyPass = "12345678" ) +func addKeyScriptingCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "test [name] [mnemonic] [password]", + Short: "Add a recovered mnemonic to the keystore encrypt it, and save to disk, for testing", + Long: `Derive a new private key from an existing mnemonic file and encrypt to disk. + +NOTE: This is insecure and only meant to be used during testing!!!! HERE BE DRAGONS! +`, + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + kb, err := NewKeyBaseFromHomeFlag() + if err != nil { + return err + } + + _, err = kb.Get(args[0]) + if err == nil { + return errors.New("key already exists, exiting") + } + + if !bip39.IsMnemonicValid(args[1]) { + return errors.New("invalid mnemonic") + } + + info, err := kb.CreateAccount(args[0], args[1], "", args[2], 0, 0) + if err != nil { + return err + } + + return printCreate(cmd, info, false, "") + }, + } + return cmd +} + func addKeyCommand() *cobra.Command { cmd := &cobra.Command{ Use: "add ", diff --git a/client/keys/root.go b/client/keys/root.go index b95740a2c036..2b3cb6d95034 100644 --- a/client/keys/root.go +++ b/client/keys/root.go @@ -30,6 +30,7 @@ func Commands() *cobra.Command { updateKeyCommand(), parseKeyStringCommand(), migrateCommand(), + addKeyScriptingCommand(), ) return cmd } diff --git a/types/coin.go b/types/coin.go index c64ba0dca500..cb4ab5c6c138 100644 --- a/types/coin.go +++ b/types/coin.go @@ -589,8 +589,8 @@ func (coins Coins) Sort() Coins { // Parsing var ( - // Denominations can be 3 ~ 16 characters long. - reDnmString = `[a-z][a-z0-9]{2,15}` + // Denominations can be 3 ~ 32 characters long. + reDnmString = `[a-z][a-z0-9/]{2,31}` reAmt = `[[:digit:]]+` reDecAmt = `[[:digit:]]*\.[[:digit:]]+` reSpc = `[[:space:]]*` diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index 833ed29af01c..265ec880d73a 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -356,17 +357,17 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) - // // get passphrase for key from1 - // passphrase1, err := keys.GetPassphrase(from1) - // if err != nil { - // return err - // } + // get passphrase for key from1 + passphrase1, err := keys.GetPassphrase(from1) + if err != nil { + return err + } - // // get passphrase for key from2 - // passphrase2, err := keys.GetPassphrase(from2) - // if err != nil { - // return err - // } + // get passphrase for key from2 + passphrase2, err := keys.GetPassphrase(from2) + if err != nil { + return err + } // TODO: check state and if not Idle continue existing process viper.Set(flags.FlagChainID, cid1) @@ -375,8 +376,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err := utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenInit}) - if err != nil { + res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) + if err != nil || !res.IsOK() { return err } @@ -395,8 +396,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + if err != nil || !res.IsOK() { return err } @@ -411,8 +412,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenTry}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) + if err != nil || !res.IsOK() { return err } @@ -431,8 +432,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) + if err != nil || !res.IsOK() { return err } @@ -448,8 +449,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenAck}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) + if err != nil || !res.IsOK() { return err } @@ -468,8 +469,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + if err != nil || !res.IsOK() { return err } @@ -484,8 +485,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) + if err != nil || !res.IsOK() { return err } diff --git a/x/ibc/20-transfer/client/cli/query.go b/x/ibc/20-transfer/client/cli/query.go index 1795e1919edb..4be0103385ee 100644 --- a/x/ibc/20-transfer/client/cli/query.go +++ b/x/ibc/20-transfer/client/cli/query.go @@ -15,15 +15,15 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) -// GetTxCmd returns the transaction commands for IBC fungible token transfer -func GetQueryCmd(cdc *codec.Codec, storeKey string) *cobra.Command { +// GetQueryCmd returns the query commands for IBC fungible token transfer +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { queryCmd := &cobra.Command{ Use: "transfer", Short: "IBC fungible token transfer query subcommands", } queryCmd.AddCommand( - GetCmdQueryNextSequence(cdc, storeKey), + GetCmdQueryNextSequence(cdc, queryRoute), ) return queryCmd diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index 28870567b55c..13917f47a62d 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -12,8 +12,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" channelutils "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -26,7 +26,7 @@ var ( FlagNode2 = "node2" FlagFrom1 = "from1" FlagFrom2 = "from2" - FlagChainId2 = "chain-id2" + FlagChainID2 = "chain-id2" FlagSequence = "packet-sequence" FlagTimeout = "timeout" ) @@ -96,7 +96,7 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { node2 := viper.GetString(FlagNode2) cid1 := viper.GetString(flags.FlagChainID) - cid2 := viper.GetString(FlagChainId2) + cid2 := viper.GetString(FlagChainID2) cliCtx2 := context.NewCLIContextIBC(cliCtx.GetFromAddress().String(), cid2, node2). WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) @@ -143,7 +143,7 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { cmd = client.PostCommands(cmd)[0] cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") - cmd.Flags().String(FlagChainId2, "", "chain-id for the second chain") + cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") cmd.Flags().String(FlagSequence, "", "sequence for the packet") cmd.Flags().String(FlagTimeout, "", "timeout for the packet") return cmd diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index 269be2377f6e..a1e12ec35d8f 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -16,3 +16,8 @@ func Name() string { func GetTxCmd(cdc *codec.Codec) *cobra.Command { return cli.GetTxCmd(cdc) } + +// GetQueryCmd returns the root tx command for the IBC transfer. +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + return cli.GetQueryCmd(cdc, queryRoute) +} diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index cc6bd3bd7822..4818d68008d6 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -45,6 +45,8 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { ibcQueryCmd.AddCommand(client.GetCommands( ibcclient.GetQueryCmd(cdc, queryRoute), connection.GetQueryCmd(cdc, queryRoute), + channel.GetQueryCmd(cdc, queryRoute), + transfer.GetQueryCmd(cdc, queryRoute), )...) return ibcQueryCmd } From 7a97b78031698828eb3521235efb81889e080a23 Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 7 Nov 2019 23:24:22 +0800 Subject: [PATCH 009/176] Add unit tests for ICS03 (#5275) * add Is() to counterobject * add readme, reflect ICS02 revision * reflect downstream ics * test in progress * add test * in progres * fin rebase * in progress * fin rebase * add CLIObject in progress * cli in progress * add CLIObject * separate testing from tendermint * add key to node * add root and storekey to tests/node, add codec * rm cli/query.go * fix test * fix lint * fix lint * add handler/msgs/client * rm relay * finalize rebase on 23 root/path sep * fix lint, fix syntax * fix querying * extract out context withstore * fix 02-client test * fix 23-commitment test * add query in progress * rm freebase, reformat query * add cli/handler/msg in progress * add cli/msg/handler * add CLIQuery, fix tests * fix golangci * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * add godoc in progress * reformat test * rm XXX * add godoc * modify store * add query * update query.go * update query.go * cli refactor in progress * cli refactor in progress * add Query to boolean.go * fix key * fix cli / merkle test * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * fix test * fix client * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * fix dependency * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * rm commented lines * address review in progress * address review, rm cleanup/closing * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * update expected client keeper and export verification funcs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * minor changes on commitment types * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * implement ics25 * update comment * refactor method name * fix file name * add test case * refactor code * refactor code * blocked the consensusState check * refactor code * fix golangci comments * refactor testcase * replace rootMultiStore with simApp * remove unless code * remove unless code & refactor test case * refactor testcase * goimports code * clean up --- x/ibc/03-connection/keeper/handshake_test.go | 311 +++++++++++++++++++ x/ibc/03-connection/keeper/keeper_test.go | 75 +++++ x/ibc/03-connection/types/msgs_test.go | 156 ++++++++++ x/ibc/keeper/keeper_test.go | 6 +- 4 files changed, 545 insertions(+), 3 deletions(-) create mode 100644 x/ibc/03-connection/keeper/handshake_test.go create mode 100644 x/ibc/03-connection/keeper/keeper_test.go create mode 100644 x/ibc/03-connection/types/msgs_test.go diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go new file mode 100644 index 000000000000..b8884c56b3ee --- /dev/null +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -0,0 +1,311 @@ +package keeper_test + +import ( + "fmt" + + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + abci "github.com/tendermint/tendermint/abci/types" +) + +func (suite *KeeperTestSuite) TestConnOpenInit() { + suite.createClient(testClientID1) + counterparty := connection.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + + success := func() error { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty) + + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.True(existed) + + expectConn := connection.ConnectionEnd{ + State: connection.INIT, + ClientID: testClientID1, + Counterparty: counterparty, + Versions: connection.GetCompatibleVersions(), + } + suite.EqualValues(expectConn, conn) + + return err + } + + connectionExists := func() error { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty) + return err + } + + var testCases = []TestCase{ + {success, true, ""}, + {connectionExists, false, "connection already exists"}, + } + + for _, tc := range testCases { + suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + } +} + +func (suite *KeeperTestSuite) TestConnOpenTry() { + suite.createClient(testClientID2) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) + + connectionKey := connection.ConnectionPath(testConnectionID2) + consensusKey := string(client.KeyConsensusState(testClientID2)) + + invalidProof := func() error { + proofInit, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + + counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx, + testConnectionID1, counterparty, testClientID1, + connection.GetCompatibleVersions(), + proofInit, proofConsensus, + uint64(proofHeight), uint64(consensusHeight)) + return err + } + + success := func() error { + suite.updateClient(testClientID1) + proofInit, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + + counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx, + testConnectionID1, counterparty, testClientID1, + connection.GetCompatibleVersions(), + proofInit, proofConsensus, + uint64(proofHeight), uint64(consensusHeight)) + suite.Nil(err) + + //check connection state + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.True(existed) + suite.Equal(connection.TRYOPEN, conn.State) + return err + } + + connectionExists := func() error { + suite.updateClient(testClientID1) + proofInit, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + + counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx, + testConnectionID1, counterparty, testClientID1, + connection.GetCompatibleVersions(), + proofInit, proofConsensus, + uint64(proofHeight), uint64(consensusHeight)) + return err + } + + var testCases = []TestCase{ + {invalidProof, false, "invalid proof"}, + {success, true, ""}, + {connectionExists, false, "connection already exists"}, + } + + for _, tc := range testCases { + suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + } + +} + +func (suite *KeeperTestSuite) TestConnOpenAck() { + suite.createClient(testClientID2) + suite.createClient(testClientID1) + + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) + connectionKey := connection.ConnectionPath(testConnectionID1) + consensusKey := string(client.KeyConsensusState(testClientID1)) + + connectionNotFound := func() error { + //suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + return err + } + + invalidConnectionState := func() error { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.NONE) + //suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + return err + } + + invalidVersion := func() error { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) + //suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, "1.0.1", proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + return err + } + + invalidProof := func() error { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) + //suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + return err + } + + success := func() error { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) + suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + + //check connection state + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID2) + suite.True(existed) + suite.Equal(connection.OPEN, conn.State) + return err + + } + + var testCases = []TestCase{ + {connectionNotFound, false, "connection not exists"}, + {invalidConnectionState, false, "invalid connection state"}, + {invalidVersion, false, "invalid version"}, + {invalidProof, false, "invalid proof"}, + {success, true, ""}, + } + + for _, tc := range testCases { + suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + } + +} + +func (suite *KeeperTestSuite) TestConnOpenConfirm() { + suite.createClient(testClientID2) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.OPEN) + + connKey := connection.ConnectionPath(testConnectionID2) + proof, h := suite.queryProof(connKey) + + connectionNotFound := func() error { + //ErrConnectionNotFound + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) + return err + } + + invalidConnectionState := func() error { + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.INIT) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) + return err + } + + invalidProof := func() error { + //Error proof + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) + return err + } + + success := func() error { + //Success + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) + suite.updateClient(testClientID1) + proof, h = suite.queryProof(connKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) + + //check connection state + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.True(existed) + suite.Equal(connection.OPEN, conn.State) + return err + } + + var testCases = []TestCase{ + {connectionNotFound, false, "connection not exists"}, + {invalidConnectionState, false, "invalid connection state"}, + {invalidProof, false, "invalid proof"}, + {success, true, ""}, + } + + for _, tc := range testCases { + suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + } +} + +func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", storeKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + +func (suite *KeeperTestSuite) createClient(clientID string) { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := tendermint.ConsensusState{ + ChainID: chainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, clientType, consensusState) + suite.NoError(err) +} + +func (suite *KeeperTestSuite) updateClient(clientID string) { + // always commit when updateClient and begin a new block + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := tendermint.ConsensusState{ + ChainID: chainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, clientID, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, clientID, state.GetHeight(), state.GetRoot()) +} + +func (suite *KeeperTestSuite) createConnection(connID, counterpartyConnID string, clientID, counterpartyClientID string, state connection.State) { + counterparty := connection.NewCounterparty(counterpartyClientID, counterpartyConnID, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + connection := connection.ConnectionEnd{ + State: state, + ClientID: clientID, + Counterparty: counterparty, + Versions: connection.GetCompatibleVersions(), + } + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, connID, connection) +} + +type TestCase = struct { + fun func() error + expected bool + errMsg string +} diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go new file mode 100644 index 000000000000..9c086f647d06 --- /dev/null +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -0,0 +1,75 @@ +package keeper_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" +) + +const ( + clientType = clientexported.Tendermint + storeKey = ibctypes.StoreKey + chainID = "test" + + testClientID1 = "testclientid1" + testConnectionID1 = "connectionid1" + + testClientID2 = "testclientid2" + testConnectionID2 = "connectionid2" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.app = app +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (suite *KeeperTestSuite) TestSetAndGetConnection() { + _, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.False(existed) + + counterparty := types.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + expConn := types.ConnectionEnd{ + State: types.INIT, + ClientID: testClientID1, + Counterparty: counterparty, + Versions: types.GetCompatibleVersions(), + } + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID1, expConn) + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.True(existed) + suite.EqualValues(expConn, conn) +} + +func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { + + _, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1) + suite.False(existed) + + suite.app.IBCKeeper.ConnectionKeeper.SetClientConnectionPaths(suite.ctx, testClientID1, types.GetCompatibleVersions()) + paths, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1) + suite.True(existed) + suite.EqualValues(types.GetCompatibleVersions(), paths) +} diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go new file mode 100644 index 000000000000..7c94f3036936 --- /dev/null +++ b/x/ibc/03-connection/types/msgs_test.go @@ -0,0 +1,156 @@ +package types + +import ( + "fmt" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/stretchr/testify/require" +) + +func TestNewMsgConnectionOpenInit(t *testing.T) { + + type TestCase = struct { + msg MsgConnectionOpenInit + expected bool + errMsg string + } + + prefix := commitment.NewPrefix([]byte("storePrefixKey")) + signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") + + testMsgs := []MsgConnectionOpenInit{ + NewMsgConnectionOpenInit("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, signer), + NewMsgConnectionOpenInit("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, signer), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "test/conn1", "clienttotest", prefix, signer), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "test/conn1", prefix, signer), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", nil, signer), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, nil), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, signer), + } + + var testCases = []TestCase{ + {testMsgs[0], false, "invalid connection ID"}, + {testMsgs[1], false, "invalid client ID"}, + {testMsgs[2], false, "invalid counterparty client ID"}, + {testMsgs[3], false, "invalid counterparty connection ID"}, + {testMsgs[4], false, "empty counterparty prefix"}, + {testMsgs[5], false, "empty singer"}, + {testMsgs[6], true, "success"}, + } + + for i, tc := range testCases { + require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + } +} + +func TestNewMsgConnectionOpenTry(t *testing.T) { + type TestCase = struct { + msg MsgConnectionOpenTry + expected bool + errMsg string + } + + prefix := commitment.NewPrefix([]byte("storePrefixKey")) + signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") + + testMsgs := []MsgConnectionOpenTry{ + NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "ibc/test", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "test/conn1", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", nil, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, nil, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, nil, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 0, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 0, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, nil), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + } + + var testCases = []TestCase{ + {testMsgs[0], false, "invalid connection ID"}, + {testMsgs[1], false, "invalid client ID"}, + {testMsgs[2], false, "invalid counterparty connection ID"}, + {testMsgs[3], false, "invalid counterparty client ID"}, + {testMsgs[4], false, "empty counterparty prefix"}, + {testMsgs[5], false, "empty counterpartyVersions"}, + {testMsgs[6], false, "empty proofInit"}, + {testMsgs[7], false, "empty proofConsensus"}, + {testMsgs[8], false, "invalid proofHeight"}, + {testMsgs[9], false, "invalid consensusHeight"}, + {testMsgs[10], false, "empty singer"}, + {testMsgs[11], true, "success"}, + } + + for i, tc := range testCases { + require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + } +} + +func TestNewMsgConnectionOpenAck(t *testing.T) { + type TestCase = struct { + msg MsgConnectionOpenAck + expected bool + errMsg string + } + + signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") + + testMsgs := []MsgConnectionOpenAck{ + NewMsgConnectionOpenAck("test/conn1", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", nil, commitment.Proof{}, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, nil, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 0, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 0, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", nil), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", signer), + } + var testCases = []TestCase{ + {testMsgs[0], false, "invalid connection ID"}, + {testMsgs[1], false, "empty proofTry"}, + {testMsgs[2], false, "empty proofConsensus"}, + {testMsgs[3], false, "invalid proofHeight"}, + {testMsgs[4], false, "invalid consensusHeight"}, + {testMsgs[5], false, "invalid version"}, + {testMsgs[6], false, "empty signer"}, + {testMsgs[7], true, "success"}, + } + + for i, tc := range testCases { + require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + } +} + +func TestNewMsgConnectionOpenConfirm(t *testing.T) { + type TestCase = struct { + msg MsgConnectionOpenConfirm + expected bool + errMsg string + } + + signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") + + testMsgs := []MsgConnectionOpenConfirm{ + NewMsgConnectionOpenConfirm("test/conn1", commitment.Proof{}, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", nil, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 0, signer), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 10, nil), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 10, signer), + } + + var testCases = []TestCase{ + {testMsgs[0], false, "invalid connection ID"}, + {testMsgs[1], false, "empty proofTry"}, + {testMsgs[2], false, "invalid proofHeight"}, + {testMsgs[3], false, "empty signer"}, + {testMsgs[4], true, "success"}, + } + + for i, tc := range testCases { + require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + } +} diff --git a/x/ibc/keeper/keeper_test.go b/x/ibc/keeper/keeper_test.go index 4aee65b6db9e..acf6b4a52241 100644 --- a/x/ibc/keeper/keeper_test.go +++ b/x/ibc/keeper/keeper_test.go @@ -16,9 +16,9 @@ import ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - keeper *keeper.Keeper + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper querier sdk.Querier } From 0c268c2f5700003d14b84ad30dfa06d287e0b97e Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 7 Nov 2019 23:28:18 +0800 Subject: [PATCH 010/176] Add unit tests for ICS04 (#5286) * fix test * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix cli errors * fix dependency * fix dependency * reflect method name change * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * reflect downstream changes * fix from address in tx cli * fix cli in progress(squash later) * fix cli * remove timeout, add channel cli * fix golangci * fix cli * Clean up * fix mock cli in progress * finalize cleanup, mock cli wip * add cli for mocksend * fix handler * rm commented lines * address review in progress * address review, rm cleanup/closing * rename mock packages * fix interface for gaia * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * update test * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * refactor: remove store accessors, update keeper and types to match spec (WIP) * update handshake and packet * implement packet timeouts * implement send and receive packet * implement packet ACK * update handler * add channel errors * channel querier * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update ICS04 with downstream changes * Implement tx cli actions * add MsgSendPacket handler; msg validation, errors and events * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * rm legacy tests; add query proofs support * remove capability key generation and authentication logic * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * downstream changes; custom marshal JSON; msg validation, and update errors * update errors and aliases * update msg validation and CLI UX * minor changes on commitment types * fix channel and packet check (#5243) * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * authenticate port ID; remove send packet msg from CLI * comment out handlers * add ibc module to simapp * ICS20 implementation (#5204) * add ibc bank mock * modify handler * import channel * add receiving logic * add cli proof handling * modify cli * modify receiver type * modify errcode * optimize codes * add denom prefix when source is true * refactor code * error return * switch ibc antehandler to decorator pattern * fix name/comment * ICS 20 implementation (#5250) * move ics20 code to 20-transfer * clean code * fix compiling error * add transfer module * address ICS20 comments from review * add routing callbacks * clean code * add missing err return * modify err type * modify err type * add supply handling * modify proof type * add comments for msg and packet data * add timeout supply handling * modify module account name * use supply keeper for burn and mint coins * restructure keeper * update alias and module.go * golangci linter * add ics20 handler to IBC handler * update callbacks * update ICS20 escrow address * fix querier routes * fix create client cli * minor updates * ibc querier test * Refactor ibc/mock/bank into ICS 20 (#5264) * Most of code port from mock module to ICS 20 * A few minor fixes * Apply suggestions from code review Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * Fix suggestions from autolinter * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Fix order of messages * Add invalid height error code, check non-nil proof * Fix linter error * Return the underlying error * Tendermint starts at height 1 * Apply suggestions from code review * setup ics20 test suite * add event to MsgRecvPacket * update ibc keeper test to use test suite * Add handshake commands * WIP connection handshake * WIP Connection Handshake * Add cliCtx.WaitForNBlocks * fix connection handshake in progress * fix connection handshake in progress * add channel unit test * add more channel tests * fix channel test * refactor channel test * add capability test for channel * make channel testing work * optimize channel test * delete types/errors.go * modify capability test * uncomment * add msg tests for channel * fix port capability store * fix channel test * use simapp * modify channel test * refactor channel msg test * go fmt --- x/ibc/04-channel/keeper/handshake_test.go | 329 ++++++++++++++++++++++ x/ibc/04-channel/keeper/keeper.go | 10 + x/ibc/04-channel/keeper/keeper_test.go | 132 +++++++++ x/ibc/04-channel/types/msgs_test.go | 304 ++++++++++++++++++++ x/ibc/05-port/keeper/keeper.go | 10 +- 5 files changed, 780 insertions(+), 5 deletions(-) create mode 100644 x/ibc/04-channel/keeper/handshake_test.go create mode 100644 x/ibc/04-channel/keeper/keeper_test.go create mode 100644 x/ibc/04-channel/types/msgs_test.go diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go new file mode 100644 index 000000000000..5a8ce10ceb4a --- /dev/null +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -0,0 +1,329 @@ +package keeper_test + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + abci "github.com/tendermint/tendermint/abci/types" +) + +func (suite *KeeperTestSuite) createClient() { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + suite.NoError(err) +} + +func (suite *KeeperTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) +} + +func (suite *KeeperTestSuite) createConnection(state connection.State) { + connection := connection.ConnectionEnd{ + State: state, + ClientID: testClient, + Counterparty: connection.Counterparty{ + ClientID: testClient, + ConnectionID: testConnection, + Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + }, + Versions: connection.GetCompatibleVersions(), + } + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) +} + +func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state types.State) { + channel := types.Channel{ + State: state, + Ordering: testChannelOrder, + Counterparty: types.Counterparty{ + PortID: counterpartyPort, + ChannelID: counterpartyChan, + }, + ConnectionHops: []string{connID}, + Version: testChannelVersion, + } + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, channel) +} + +func (suite *KeeperTestSuite) deleteChannel(portID string, chanID string) { + store := prefix.NewStore(suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)), []byte{}) + store.Delete(types.KeyChannel(portID, chanID)) +} + +func (suite *KeeperTestSuite) bindPort(portID string) sdk.CapabilityKey { + return suite.app.IBCKeeper.PortKeeper.BindPort(portID) +} + +func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + +func (suite *KeeperTestSuite) TestChanOpenInit() { + counterparty := types.NewCounterparty(testPort2, testChannel2) + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.NotNil(err) // channel has already exist + + suite.deleteChannel(testPort1, testChannel1) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.NONE) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(types.INIT, channel.State) +} + +func (suite *KeeperTestSuite) TestChanOpenTry() { + counterparty := types.NewCounterparty(testPort1, testChannel1) + suite.bindPort(testPort2) + channelKey := types.ChannelPath(testPort1, testChannel1) + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.INIT) + suite.updateClient() + proofInit, proofHeight := suite.queryProof(channelKey) + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel has already exist + + suite.deleteChannel(testPort2, testChannel2) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // unauthenticated port + + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.NONE) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) + suite.updateClient() + proofInit, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel membership verification failed due to invalid counterparty + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) + suite.updateClient() + proofInit, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) + suite.True(found) + suite.Equal(types.OPENTRY, channel.State) +} + +func (suite *KeeperTestSuite) TestChanOpenAck() { + suite.bindPort(testPort1) + channelKey := types.ChannelPath(testPort2, testChannel2) + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.updateClient() + proofTry, proofHeight := suite.queryProof(channelKey) + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // channel does not exist + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // invalid channel state + + suite.createChannel(testPort2, testChannel1, testConnection, testPort1, testChannel2, types.INIT) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort2, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // unauthenticated port + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.NONE) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) + suite.updateClient() + proofTry, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // channel membership verification failed due to invalid counterparty + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.updateClient() + proofTry, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(types.OPEN, channel.State) +} + +func (suite *KeeperTestSuite) TestChanOpenConfirm() { + suite.bindPort(testPort2) + channelKey := types.ChannelPath(testPort1, testChannel1) + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) + suite.updateClient() + proofAck, proofHeight := suite.queryProof(channelKey) + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // channel does not exist + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // invalid channel state + + suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.OPENTRY) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort1, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // unauthenticated port + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.NONE) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) + suite.updateClient() + proofAck, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // channel membership verification failed due to invalid counterparty + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) + suite.updateClient() + proofAck, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) + suite.True(found) + suite.Equal(types.OPEN, channel.State) +} + +func (suite *KeeperTestSuite) TestChanCloseInit() { + suite.bindPort(testPort1) + + err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort2, testChannel1) + suite.NotNil(err) // authenticated port + + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.NotNil(err) // channel does not exist + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.NotNil(err) // channel is already closed + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.TRYOPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(types.CLOSED, channel.State) +} + +func (suite *KeeperTestSuite) TestChanCloseConfirm() { + suite.bindPort(testPort2) + channelKey := types.ChannelPath(testPort1, testChannel1) + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) + suite.updateClient() + proofInit, proofHeight := suite.queryProof(channelKey) + err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort1, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // unauthenticated port + + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel does not exist + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.CLOSED) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel is already closed + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.TRYOPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) + suite.updateClient() + proofInit, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel membership verification failed due to invalid counterparty + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) + suite.updateClient() + proofInit, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) + suite.True(found) + suite.Equal(types.CLOSED, channel.State) +} diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index 6169c72ffc3a..dc6bbd3fb021 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -144,3 +144,13 @@ func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID stri store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) } + +// GetPacketAcknowledgement gets the packet ack hash from the store +func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyPacketAcknowledgement(portID, channelID, sequence)) + if bz == nil { + return nil, false + } + return bz, true +} diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go new file mode 100644 index 000000000000..f05cc56db841 --- /dev/null +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -0,0 +1,132 @@ +package keeper_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" +) + +// define constants used for testing +const ( + testChainID = "test-chain-id" + testClient = "test-client" + testClientType = clientexported.Tendermint + + testConnection = "testconnection" + testPort1 = "firstport" + testPort2 = "secondport" + testChannel1 = "firstchannel" + testChannel2 = "secondchannel" + + testChannelOrder = types.ORDERED + testChannelVersion = "1.0" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.app = app + + suite.createClient() +} + +func (suite *KeeperTestSuite) TestSetChannel() { + _, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.False(found) + + channel := types.Channel{ + State: types.OPEN, + Ordering: testChannelOrder, + Counterparty: types.Counterparty{ + PortID: testPort1, + ChannelID: testChannel1, + }, + ConnectionHops: []string{testConnection}, + Version: testChannelVersion, + } + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort1, testChannel1, channel) + + storedChannel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(channel, storedChannel) +} + +func (suite *KeeperTestSuite) TestSetChannelCapability() { + _, found := suite.app.IBCKeeper.ChannelKeeper.GetChannelCapability(suite.ctx, testPort1, testChannel1) + suite.False(found) + + channelCap := "test-channel-capability" + suite.app.IBCKeeper.ChannelKeeper.SetChannelCapability(suite.ctx, testPort1, testChannel1, channelCap) + + storedChannelCap, found := suite.app.IBCKeeper.ChannelKeeper.GetChannelCapability(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(channelCap, storedChannelCap) +} + +func (suite *KeeperTestSuite) TestSetSequence() { + _, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + suite.False(found) + + _, found = suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceRecv(suite.ctx, testPort1, testChannel1) + suite.False(found) + + nextSeqSend, nextSeqRecv := uint64(10), uint64(10) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + + storedNextSeqSend, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(nextSeqSend, storedNextSeqSend) + + storedNextSeqRecv, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(nextSeqRecv, storedNextSeqRecv) +} + +func (suite *KeeperTestSuite) TestPackageCommitment() { + seq := uint64(10) + storedCommitment := suite.app.IBCKeeper.ChannelKeeper.GetPacketCommitment(suite.ctx, testPort1, testChannel1, seq) + suite.Equal([]byte(nil), storedCommitment) + + commitment := []byte("commitment") + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, seq, commitment) + + storedCommitment = suite.app.IBCKeeper.ChannelKeeper.GetPacketCommitment(suite.ctx, testPort1, testChannel1, seq) + suite.Equal(commitment, storedCommitment) +} + +func (suite *KeeperTestSuite) TestSetPacketAcknowledgement() { + seq := uint64(10) + + storedAckHash, found := suite.app.IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, seq) + suite.False(found) + suite.Nil(storedAckHash) + + ackHash := []byte("ackhash") + suite.app.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, seq, ackHash) + + storedAckHash, found = suite.app.IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, seq) + suite.True(found) + suite.Equal(ackHash, storedAckHash) +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go new file mode 100644 index 000000000000..c57a35af74ad --- /dev/null +++ b/x/ibc/04-channel/types/msgs_test.go @@ -0,0 +1,304 @@ +package types + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/stretchr/testify/require" +) + +// define constants used for testing +const ( + invalidPort = "invalidport1" + invalidShortPort = "p" + invalidLongPort = "invalidlongportinvalidlongport" + + invalidChannel = "invalidchannel1" + invalidShortChannel = "invalidch" + invalidLongChannel = "invalidlongchannelinvalidlongchannel" + + invalidConnection = "invalidconnection1" + invalidShortConnection = "invalidcn" + invalidLongConnection = "invalidlongconnection" +) + +// define variables used for testing +var ( + connHops = []string{"testconnection"} + invalidConnHops = []string{"testconnection", "testconnection"} + invalidShortConnHops = []string{invalidShortConnection} + invalidLongConnHops = []string{invalidLongConnection} + + proof = commitment.Proof{} + + addr = sdk.AccAddress("testaddr") +) + +// TestMsgChannelOpenInit tests ValidateBasic for MsgChannelOpenInit +func TestMsgChannelOpenInit(t *testing.T) { + testMsgs := []MsgChannelOpenInit{ + NewMsgChannelOpenInit("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg + NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id + NewMsgChannelOpenInit(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long port id + NewMsgChannelOpenInit(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // port id contains non-alpha + NewMsgChannelOpenInit("testport", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short channel id + NewMsgChannelOpenInit("testport", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long channel id + NewMsgChannelOpenInit("testport", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // channel id contains non-alpha + NewMsgChannelOpenInit("testport", "testchannel", "1.0", Order(3), connHops, "testcpport", "testcpchannel", addr), // invalid channel order + NewMsgChannelOpenInit("testport", "testchannel", "1.0", ORDERED, invalidConnHops, "testcpport", "testcpchannel", addr), // connection hops more than 1 + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", addr), // too short connection id + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", addr), // too long connection id + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", addr), // connection id contains non-alpha + NewMsgChannelOpenInit("testport", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", addr), // empty channel version + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", addr), // invalid counterparty port id + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, addr), // invalid counterparty channel id + } + + testCases := []struct { + msg MsgChannelOpenInit + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "invalid channel order"}, + {testMsgs[8], false, "connection hops more than 1 "}, + {testMsgs[9], false, "too short connection id"}, + {testMsgs[10], false, "too long connection id"}, + {testMsgs[11], false, "connection id contains non-alpha"}, + {testMsgs[12], false, "empty channel version"}, + {testMsgs[13], false, "invalid counterparty port id"}, + {testMsgs[14], false, "invalid counterparty channel id"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelOpenTry tests ValidateBasic for MsgChannelOpenTry +func TestMsgChannelOpenTry(t *testing.T) { + testMsgs := []MsgChannelOpenTry{ + NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // valid msg + NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short port id + NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long port id + NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenTry("testport", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short channel id + NewMsgChannelOpenTry("testport", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long channel id + NewMsgChannelOpenTry("testport", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", proof, 1, addr), // empty counterparty version + NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 0, addr), // proof height is zero + NewMsgChannelOpenTry("testport", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // invalid channel order + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection hops more than 1 + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short connection id + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long connection id + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection id contains non-alpha + NewMsgChannelOpenTry("testport", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // empty channel version + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", proof, 1, addr), // invalid counterparty port id + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", proof, 1, addr), // invalid counterparty channel id + } + + testCases := []struct { + msg MsgChannelOpenTry + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "empty counterparty version"}, + {testMsgs[8], false, "empty proof"}, + {testMsgs[9], false, "proof height is zero"}, + {testMsgs[10], false, "invalid channel order"}, + {testMsgs[11], false, "connection hops more than 1 "}, + {testMsgs[12], false, "too short connection id"}, + {testMsgs[13], false, "too long connection id"}, + {testMsgs[14], false, "connection id contains non-alpha"}, + {testMsgs[15], false, "empty channel version"}, + {testMsgs[16], false, "invalid counterparty port id"}, + {testMsgs[17], false, "invalid counterparty channel id"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelOpenAck tests ValidateBasic for MsgChannelOpenAck +func TestMsgChannelOpenAck(t *testing.T) { + testMsgs := []MsgChannelOpenAck{ + NewMsgChannelOpenAck("testport", "testchannel", "1.0", proof, 1, addr), // valid msg + NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", proof, 1, addr), // too short port id + NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", proof, 1, addr), // too long port id + NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenAck("testport", invalidShortChannel, "1.0", proof, 1, addr), // too short channel id + NewMsgChannelOpenAck("testport", invalidLongChannel, "1.0", proof, 1, addr), // too long channel id + NewMsgChannelOpenAck("testport", invalidChannel, "1.0", proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenAck("testport", "testchannel", "", proof, 1, addr), // empty counterparty version + NewMsgChannelOpenAck("testport", "testchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenAck("testport", "testchannel", "1.0", proof, 0, addr), // proof height is zero + } + + testCases := []struct { + msg MsgChannelOpenAck + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "empty counterparty version"}, + {testMsgs[8], false, "empty proof"}, + {testMsgs[9], false, "proof height is zero"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelOpenConfirm tests ValidateBasic for MsgChannelOpenConfirm +func TestMsgChannelOpenConfirm(t *testing.T) { + testMsgs := []MsgChannelOpenConfirm{ + NewMsgChannelOpenConfirm("testport", "testchannel", proof, 1, addr), // valid msg + NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id + NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id + NewMsgChannelOpenConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenConfirm("testport", invalidShortChannel, proof, 1, addr), // too short channel id + NewMsgChannelOpenConfirm("testport", invalidLongChannel, proof, 1, addr), // too long channel id + NewMsgChannelOpenConfirm("testport", invalidChannel, proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenConfirm("testport", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testport", "testchannel", proof, 0, addr), // proof height is zero + } + + testCases := []struct { + msg MsgChannelOpenConfirm + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "empty proof"}, + {testMsgs[8], false, "proof height is zero"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelCloseInit tests ValidateBasic for MsgChannelCloseInit +func TestMsgChannelCloseInit(t *testing.T) { + testMsgs := []MsgChannelCloseInit{ + NewMsgChannelCloseInit("testport", "testchannel", addr), // valid msg + NewMsgChannelCloseInit(invalidShortPort, "testchannel", addr), // too short port id + NewMsgChannelCloseInit(invalidLongPort, "testchannel", addr), // too long port id + NewMsgChannelCloseInit(invalidPort, "testchannel", addr), // port id contains non-alpha + NewMsgChannelCloseInit("testport", invalidShortChannel, addr), // too short channel id + NewMsgChannelCloseInit("testport", invalidLongChannel, addr), // too long channel id + NewMsgChannelCloseInit("testport", invalidChannel, addr), // channel id contains non-alpha + } + + testCases := []struct { + msg MsgChannelCloseInit + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelCloseConfirm tests ValidateBasic for MsgChannelCloseConfirm +func TestMsgChannelCloseConfirm(t *testing.T) { + testMsgs := []MsgChannelCloseConfirm{ + NewMsgChannelCloseConfirm("testport", "testchannel", proof, 1, addr), // valid msg + NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id + NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id + NewMsgChannelCloseConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha + NewMsgChannelCloseConfirm("testport", invalidShortChannel, proof, 1, addr), // too short channel id + NewMsgChannelCloseConfirm("testport", invalidLongChannel, proof, 1, addr), // too long channel id + NewMsgChannelCloseConfirm("testport", invalidChannel, proof, 1, addr), // channel id contains non-alpha + NewMsgChannelCloseConfirm("testport", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testport", "testchannel", proof, 0, addr), // proof height is zero + } + + testCases := []struct { + msg MsgChannelCloseConfirm + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "empty proof"}, + {testMsgs[8], false, "proof height is zero"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index 5a7a9fb05bae..cdb48010237f 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -15,7 +15,7 @@ type Keeper struct { cdc *codec.Codec codespace sdk.CodespaceType prefix []byte // prefix bytes for accessing the store - ports map[sdk.CapabilityKey]string + ports map[string]string bound []string } @@ -27,7 +27,7 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/port", prefix: []byte{}, // prefix: []byte(types.SubModuleName + "/"), // "port/" - ports: make(map[sdk.CapabilityKey]string), // map of capabilities to port ids + ports: make(map[string]string), // map of capability key names to port ids } } @@ -39,7 +39,7 @@ func (k Keeper) GetPorts() []string { // GetPort retrieves a given port ID from keeper map func (k Keeper) GetPort(ck sdk.CapabilityKey) (string, bool) { - portID, found := k.ports[ck] + portID, found := k.ports[ck.Name()] return portID, found } @@ -59,7 +59,7 @@ func (k Keeper) BindPort(portID string) sdk.CapabilityKey { } key := sdk.NewKVStoreKey(portID) - k.ports[key] = portID + k.ports[key.Name()] = portID k.bound = append(k.bound, portID) return key } @@ -73,5 +73,5 @@ func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { panic(err.Error()) } - return k.ports[key] == portID + return k.ports[key.Name()] == portID } From 51ecc980e05a44ab10fb929753465d94ebfa30c3 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 11 Nov 2019 11:57:27 +0100 Subject: [PATCH 011/176] IBC alpha general cleanup (#5291) * remove prefix from keeper; update client queries; address ICS02 comments from @cwgoes * add proof for root query * golangci * remove hardcoded bind port logic * space * WIP: register errors * register errors; make format * use new instead of register; unescape path * golangci --- client/context/context.go | 2 +- client/context/query.go | 24 ++- x/ibc/02-client/client/cli/query.go | 60 +++++--- x/ibc/02-client/client/utils/utils.go | 24 ++- x/ibc/02-client/doc.go | 2 +- x/ibc/02-client/exported/exported.go | 11 +- x/ibc/02-client/keeper/client.go | 9 -- x/ibc/02-client/keeper/keeper.go | 23 ++- x/ibc/02-client/keeper/querier.go | 6 +- x/ibc/02-client/types/codec.go | 1 - x/ibc/02-client/types/errors/errors.go | 101 +++++++++---- x/ibc/02-client/types/keys.go | 5 + x/ibc/02-client/types/msgs.go | 18 +-- x/ibc/02-client/types/msgs_test.go | 7 +- x/ibc/02-client/types/querier.go | 53 ++++++- x/ibc/02-client/types/state.go | 9 +- .../types/tendermint/consensus_state.go | 13 +- .../types/tendermint/misbehaviour.go | 10 +- x/ibc/03-connection/alias.go | 3 - x/ibc/03-connection/client/cli/query.go | 8 - x/ibc/03-connection/client/cli/tx.go | 7 +- x/ibc/03-connection/keeper/handshake.go | 3 +- x/ibc/03-connection/keeper/handshake_test.go | 3 +- x/ibc/03-connection/keeper/keeper.go | 29 ++-- x/ibc/03-connection/keeper/keeper_test.go | 5 +- x/ibc/03-connection/keeper/querier.go | 4 +- x/ibc/03-connection/types/connection.go | 8 +- x/ibc/03-connection/types/errors.go | 94 +++++++----- x/ibc/03-connection/types/keys.go | 5 + x/ibc/03-connection/types/msgs.go | 45 +++--- x/ibc/03-connection/types/msgs_test.go | 3 +- x/ibc/03-connection/types/querier.go | 3 +- x/ibc/04-channel/alias.go | 2 - x/ibc/04-channel/client/cli/tx.go | 3 +- x/ibc/04-channel/exported/exported.go | 7 +- x/ibc/04-channel/keeper/handshake_test.go | 3 +- x/ibc/04-channel/keeper/keeper.go | 42 +++--- x/ibc/04-channel/keeper/keeper_test.go | 5 +- x/ibc/04-channel/keeper/querier.go | 2 +- x/ibc/04-channel/types/channel.go | 13 +- x/ibc/04-channel/types/errors.go | 97 +++++++----- x/ibc/04-channel/types/keys.go | 5 + x/ibc/04-channel/types/msgs.go | 70 ++++----- x/ibc/04-channel/types/msgs_test.go | 139 +++++++++--------- x/ibc/04-channel/types/packet.go | 19 ++- x/ibc/05-port/alias.go | 28 ++-- x/ibc/05-port/keeper/keeper.go | 33 ++--- x/ibc/05-port/types/errors.go | 39 +++-- x/ibc/20-transfer/alias.go | 39 ++--- x/ibc/20-transfer/client/cli/query.go | 3 +- x/ibc/20-transfer/keeper/callbacks.go | 35 +++-- x/ibc/20-transfer/keeper/keeper.go | 28 ++-- x/ibc/20-transfer/keeper/relay.go | 10 +- x/ibc/20-transfer/types/errors.go | 51 ------- x/ibc/20-transfer/types/keys.go | 4 +- x/ibc/20-transfer/types/msgs.go | 29 ++-- x/ibc/23-commitment/merkle.go | 9 +- x/ibc/24-host/errors.go | 49 ++++-- x/ibc/24-host/validate.go | 10 +- x/ibc/keeper/keeper.go | 9 +- x/ibc/keeper/querier_test.go | 2 +- x/ibc/types/errors.go | 33 +++++ x/ibc/types/types.go | 7 - x/ibc/version/version.go | 13 -- 64 files changed, 783 insertions(+), 653 deletions(-) delete mode 100644 x/ibc/20-transfer/types/errors.go create mode 100644 x/ibc/types/errors.go delete mode 100644 x/ibc/version/version.go diff --git a/client/context/context.go b/client/context/context.go index 07168ecdf6ca..e683ff2c3701 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -99,7 +99,7 @@ func NewCLIContextWithFrom(from string) CLIContext { return ctx.WithVerifier(verifier) } -// NewCLIContextIBC takes additional arguements +// NewCLIContextIBC takes additional arguments func NewCLIContextIBC(from string, chainID string, nodeURI string) CLIContext { var rpc rpcclient.Client diff --git a/client/context/query.go b/client/context/query.go index 2a01a7577a0c..be664f1c8420 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -129,11 +129,10 @@ func (ctx CLIContext) GetFromName() string { return ctx.FromName } -func (ctx CLIContext) queryABCI(req abci.RequestQuery) (resp abci.ResponseQuery, err error) { - +func (ctx CLIContext) queryABCI(req abci.RequestQuery) (abci.ResponseQuery, error) { node, err := ctx.GetNode() if err != nil { - return resp, err + return abci.ResponseQuery{}, err } // When a client did not provide a query height, manually query for it so it can @@ -141,7 +140,7 @@ func (ctx CLIContext) queryABCI(req abci.RequestQuery) (resp abci.ResponseQuery, if ctx.Height == 0 { status, err := node.Status() if err != nil { - return resp, err + return abci.ResponseQuery{}, err } ctx = ctx.WithHeight(status.SyncInfo.LatestBlockHeight) } @@ -153,26 +152,25 @@ func (ctx CLIContext) queryABCI(req abci.RequestQuery) (resp abci.ResponseQuery, result, err := node.ABCIQueryWithOptions(req.Path, req.Data, opts) if err != nil { - return + return abci.ResponseQuery{}, err } - resp = result.Response - if !resp.IsOK() { - err = errors.New(resp.Log) - return + if !result.Response.IsOK() { + err = errors.New(result.Response.Log) + return abci.ResponseQuery{}, err } // data from trusted node or subspace query doesn't need verification if ctx.TrustNode || !isQueryStoreWithProof(req.Path) { - return resp, nil + return result.Response, nil } - err = ctx.verifyProof(req.Path, resp) + err = ctx.verifyProof(req.Path, result.Response) if err != nil { - return + return abci.ResponseQuery{}, err } - return + return result.Response, nil } // query performs a query to a Tendermint node with the provided store name diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index 6f6a487bbbf6..cc5cb3364c89 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -7,15 +7,17 @@ import ( "strings" "github.com/spf13/cobra" + "github.com/spf13/viper" + abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -44,7 +46,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { // GetCmdQueryClientState defines the command to query the state of a client with // a given id as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query func GetCmdQueryClientState(queryRoute string, cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Use: "state [client-id]", Short: "Query a client state", Long: strings.TrimSpace( @@ -67,24 +69,33 @@ $ %s query ibc client state [client-id] return err } - res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), bz) + req := abci.RequestQuery{ + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), + } + + res, err := cliCtx.QueryABCI(req) if err != nil { return err } var clientState types.State - if err := cdc.UnmarshalJSON(res, &clientState); err != nil { + if err := cdc.UnmarshalJSON(res.Value, &clientState); err != nil { return err } - return cliCtx.PrintOutput(clientState) + clientStateRes := types.NewClientStateResponse(clientID, clientState, res.Proof, res.Height) + return cliCtx.PrintOutput(clientStateRes) }, } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd } -// GetCmdQueryRoot defines the command to query +// GetCmdQueryRoot defines the command to query a verified commitment root func GetCmdQueryRoot(queryRoute string, cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Use: "root [client-id] [height]", Short: "Query a verified commitment root", Long: strings.TrimSpace( @@ -112,25 +123,34 @@ $ %s query ibc client root [client-id] [height] return err } - res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryVerifiedRoot), bz) + req := abci.RequestQuery{ + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryVerifiedRoot), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), + } + + res, err := cliCtx.QueryABCI(req) if err != nil { return err } - var root commitment.RootI - if err := cdc.UnmarshalJSON(res, &root); err != nil { + var root commitment.Root + if err := cdc.UnmarshalJSON(res.Value, &root); err != nil { return err } - return cliCtx.PrintOutput(root) + rootRes := types.NewRootResponse(clientID, height, root, res.Proof, res.Height) + return cliCtx.PrintOutput(rootRes) }, } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd } // GetCmdQueryConsensusState defines the command to query the consensus state of // the chain as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Use: "consensus-state [client-id]", Short: "Query the latest consensus state of the client", Long: strings.TrimSpace( @@ -148,24 +168,16 @@ $ %s query ibc client consensus-state [client-id] return errors.New("client ID can't be blank") } - bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) + csRes, err := utils.QueryConsensusStateProof(cliCtx, cdc, queryRoute, clientID) if err != nil { return err } - res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryConsensusState), bz) - if err != nil { - return err - } - - var consensusState exported.ConsensusState - if err := cdc.UnmarshalJSON(res, &consensusState); err != nil { - return err - } - - return cliCtx.PrintOutput(consensusState) + return cliCtx.PrintOutput(csRes) }, } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd } // GetCmdQueryHeader defines the command to query the latest header on the chain diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 5d0786267373..955e06f50e7c 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -3,23 +3,36 @@ package utils import ( "fmt" + "github.com/spf13/viper" + abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" ) // QueryConsensusStateProof queries the store to get the consensus state and a // merkle proof. -func QueryConsensusStateProof(cliCtx client.CLIContext, clientID string) (types.ConsensusStateResponse, error) { +func QueryConsensusStateProof( + cliCtx client.CLIContext, cdc *codec.Codec, + queryRoute, clientID string, +) (types.ConsensusStateResponse, error) { var conStateRes types.ConsensusStateResponse + + bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) + if err != nil { + return conStateRes, err + } + req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: []byte(fmt.Sprintf("clients/%s/consensusState", clientID)), - Prove: true, + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), } res, err := cliCtx.QueryABCI(req) @@ -28,9 +41,10 @@ func QueryConsensusStateProof(cliCtx client.CLIContext, clientID string) (types. } var cs tendermint.ConsensusState - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &cs); err != nil { return conStateRes, err } + return types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height), nil } diff --git a/x/ibc/02-client/doc.go b/x/ibc/02-client/doc.go index 2b6952ba97eb..cfe3c76c6af7 100644 --- a/x/ibc/02-client/doc.go +++ b/x/ibc/02-client/doc.go @@ -1,5 +1,5 @@ /* -Package client implements the ICS 02 - Client Semenatics specification +Package client implements the ICS 02 - Client Semantics specification https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics. This concrete implementations defines types and method to store and update light clients which tracks on other chain's state. diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index e7d1ac5c5411..e611b94301fa 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -6,17 +6,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" cmn "github.com/tendermint/tendermint/libs/common" -) -// Blockchain is consensus algorithm which generates valid Headers. It generates -// a unique list of headers starting from a genesis ConsensusState with arbitrary messages. -// This interface is implemented as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#blockchain. -type Blockchain interface { - Genesis() ConsensusState // Consensus state defined in the genesis - Consensus() Header // Header generating function -} + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) // ConsensusState is the state of the consensus process type ConsensusState interface { diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index b75f8174939a..3ee7a53143bf 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -60,15 +60,6 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H return sdkerrors.Wrap(errors.ErrConsensusStateNotFound(k.codespace), "cannot update client") } - if header.GetHeight() < consensusState.GetHeight() { - return sdkerrors.Wrap( - sdk.ErrInvalidSequence( - fmt.Sprintf("header height < consensus height (%d < %d)", header.GetHeight(), consensusState.GetHeight()), - ), - "cannot update client", - ) - } - consensusState, err := consensusState.CheckValidityAndUpdateState(header) if err != nil { return sdkerrors.Wrap(err, "cannot update client") diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index ce0d54e99782..3911c1f98f0e 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -23,7 +23,6 @@ type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store } // NewKeeper creates a new NewKeeper instance @@ -32,8 +31,6 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) storeKey: key, cdc: cdc, codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, errors.DefaultCodespace)), // "ibc/client", - prefix: []byte{}, - // prefix: []byte(types.SubModuleName + "/"), // "client/" } } @@ -44,7 +41,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetClientState gets a particular client from the store func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := store.Get(types.KeyClientState(clientID)) if bz == nil { return types.State{}, false @@ -57,14 +54,14 @@ func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, b // SetClientState sets a particular Client to the store func (k Keeper) SetClientState(ctx sdk.Context, clientState types.State) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := k.cdc.MustMarshalBinaryLengthPrefixed(clientState) - store.Set(types.KeyClientState(clientState.ID()), bz) + store.Set(types.KeyClientState(clientState.ID), bz) } // GetClientType gets the consensus type for a specific client func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.ClientType, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := store.Get(types.KeyClientType(clientID)) if bz == nil { return 0, false @@ -75,13 +72,13 @@ func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.Client // SetClientType sets the specific client consensus type to the provable store func (k Keeper) SetClientType(ctx sdk.Context, clientID string, clientType exported.ClientType) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) store.Set(types.KeyClientType(clientID), []byte{byte(clientType)}) } // GetConsensusState creates a new client state and populates it with a given consensus state func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.ConsensusState, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := store.Get(types.KeyConsensusState(clientID)) if bz == nil { return nil, false @@ -94,7 +91,7 @@ func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.Co // SetConsensusState sets a ConsensusState to a particular client func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) store.Set(types.KeyConsensusState(clientID), bz) } @@ -102,7 +99,7 @@ func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusSta // GetVerifiedRoot gets a verified commitment Root from a particular height to // a client func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) (commitment.RootI, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := store.Get(types.KeyRoot(clientID, height)) if bz == nil { @@ -117,7 +114,7 @@ func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) // SetVerifiedRoot sets a verified commitment Root from a particular height to // a client func (k Keeper) SetVerifiedRoot(ctx sdk.Context, clientID string, height uint64, root commitment.RootI) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := k.cdc.MustMarshalBinaryLengthPrefixed(root) store.Set(types.KeyRoot(clientID, height), bz) } @@ -151,7 +148,7 @@ func (k Keeper) checkMisbehaviour(ctx sdk.Context, evidence exported.Evidence) e // freeze updates the state of the client in the event of a misbehaviour func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) { if clientState.Frozen { - return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientState.ID()), "already frozen") + return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientState.ID), "already frozen") } clientState.Frozen = true diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go index 5f56b8d6b01a..8956a72fab2e 100644 --- a/x/ibc/02-client/keeper/querier.go +++ b/x/ibc/02-client/keeper/querier.go @@ -21,7 +21,7 @@ func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt clientState, found := k.GetClientState(ctx, params.ClientID) if !found { - return nil, errors.ErrClientTypeNotFound(k.codespace) + return nil, sdk.ConvertError(errors.ErrClientTypeNotFound(k.codespace)) } bz, err := types.SubModuleCdc.MarshalJSON(clientState) @@ -43,7 +43,7 @@ func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([] consensusState, found := k.GetConsensusState(ctx, params.ClientID) if !found { - return nil, errors.ErrConsensusStateNotFound(k.codespace) + return nil, sdk.ConvertError(errors.ErrConsensusStateNotFound(k.codespace)) } bz, err := types.SubModuleCdc.MarshalJSON(consensusState) @@ -65,7 +65,7 @@ func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]by root, found := k.GetVerifiedRoot(ctx, params.ClientID, params.Height) if !found { - return nil, errors.ErrRootNotFound(k.codespace) + return nil, sdk.ConvertError(errors.ErrRootNotFound(k.codespace)) } bz, err := types.SubModuleCdc.MarshalJSON(root) diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index 7a141e811a0a..551403e6ad89 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -11,7 +11,6 @@ var SubModuleCdc = codec.New() // RegisterCodec registers the IBC client interfaces and types func RegisterCodec(cdc *codec.Codec) { - cdc.RegisterInterface((*exported.Blockchain)(nil), nil) cdc.RegisterInterface((*exported.ConsensusState)(nil), nil) cdc.RegisterInterface((*exported.Evidence)(nil), nil) cdc.RegisterInterface((*exported.Header)(nil), nil) diff --git a/x/ibc/02-client/types/errors/errors.go b/x/ibc/02-client/types/errors/errors.go index c133bcfef808..1e9510df6c44 100644 --- a/x/ibc/02-client/types/errors/errors.go +++ b/x/ibc/02-client/types/errors/errors.go @@ -4,70 +4,111 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // client error codes const ( DefaultCodespace sdk.CodespaceType = "client" - CodeClientExists sdk.CodeType = 101 - CodeClientNotFound sdk.CodeType = 102 - CodeClientFrozen sdk.CodeType = 103 - CodeConsensusStateNotFound sdk.CodeType = 104 - CodeInvalidConsensusState sdk.CodeType = 105 - CodeClientTypeNotFound sdk.CodeType = 106 - CodeInvalidClientType sdk.CodeType = 107 - CodeRootNotFound sdk.CodeType = 108 - CodeInvalidHeader sdk.CodeType = 109 - CodeInvalidEvidence sdk.CodeType = 110 + CodeClientExists sdk.CodeType = 200 + CodeClientNotFound sdk.CodeType = 201 + CodeClientFrozen sdk.CodeType = 202 + CodeConsensusStateNotFound sdk.CodeType = 203 + CodeInvalidConsensusState sdk.CodeType = 204 + CodeClientTypeNotFound sdk.CodeType = 205 + CodeInvalidClientType sdk.CodeType = 206 + CodeRootNotFound sdk.CodeType = 207 + CodeInvalidHeader sdk.CodeType = 207 + CodeInvalidEvidence sdk.CodeType = 209 ) // ErrClientExists implements sdk.Error -func ErrClientExists(codespace sdk.CodespaceType, clientID string) sdk.Error { - return sdk.NewError(codespace, CodeClientExists, fmt.Sprintf("client with ID %s already exists", clientID)) +func ErrClientExists(codespace sdk.CodespaceType, clientID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientExists), + fmt.Sprintf("client with ID %s already exists", clientID), + ) } // ErrClientNotFound implements sdk.Error -func ErrClientNotFound(codespace sdk.CodespaceType, clientID string) sdk.Error { - return sdk.NewError(codespace, CodeClientNotFound, fmt.Sprintf("client with ID %s not found", clientID)) +func ErrClientNotFound(codespace sdk.CodespaceType, clientID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientNotFound), + fmt.Sprintf("client with ID %s not found", clientID), + ) } // ErrClientFrozen implements sdk.Error -func ErrClientFrozen(codespace sdk.CodespaceType, clientID string) sdk.Error { - return sdk.NewError(codespace, CodeClientFrozen, fmt.Sprintf("client with ID %s is frozen due to misbehaviour", clientID)) +func ErrClientFrozen(codespace sdk.CodespaceType, clientID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientFrozen), + fmt.Sprintf("client with ID %s is frozen due to misbehaviour", clientID), + ) } // ErrConsensusStateNotFound implements sdk.Error -func ErrConsensusStateNotFound(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeConsensusStateNotFound, "consensus state not found") +func ErrConsensusStateNotFound(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeConsensusStateNotFound), + "consensus state not found", + ) } // ErrInvalidConsensus implements sdk.Error -func ErrInvalidConsensus(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidConsensusState, "invalid consensus state") +func ErrInvalidConsensus(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidConsensusState), + "invalid consensus state", + ) } // ErrClientTypeNotFound implements sdk.Error -func ErrClientTypeNotFound(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeClientTypeNotFound, "client type not found") +func ErrClientTypeNotFound(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientTypeNotFound), + "client type not found", + ) } // ErrInvalidClientType implements sdk.Error -func ErrInvalidClientType(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidClientType, msg) +func ErrInvalidClientType(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidClientType), + msg, + ) } // ErrRootNotFound implements sdk.Error -func ErrRootNotFound(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeRootNotFound, "commitment root not found") +func ErrRootNotFound(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeRootNotFound), + "commitment root not found", + ) } // ErrInvalidHeader implements sdk.Error -func ErrInvalidHeader(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidHeader, "invalid header") +func ErrInvalidHeader(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidHeader), + "invalid header", + ) } // ErrInvalidEvidence implements sdk.Error -func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidEvidence, "invalid evidence: %s", msg) +func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidEvidence), + fmt.Sprintf("invalid evidence: %s", msg), + ) } diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go index 8d97ca893324..eba16d0c169c 100644 --- a/x/ibc/02-client/types/keys.go +++ b/x/ibc/02-client/types/keys.go @@ -18,6 +18,11 @@ const ( QuerierRoute = SubModuleName ) +// KVStore key prefixes +var ( + KeyPrefixClient = []byte{0x00} +) + // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space // ClientStatePath takes an Identifier and returns a Path under which to store a diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index 612f7e543e53..f09e126666ff 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -1,8 +1,6 @@ package types import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" @@ -43,13 +41,13 @@ func (msg MsgCreateClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgCreateClient) ValidateBasic() sdk.Error { if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(err) } if _, err := exported.ClientTypeFromString(msg.ClientType); err != nil { - return errors.ErrInvalidClientType(errors.DefaultCodespace, err.Error()) + return sdk.ConvertError(errors.ErrInvalidClientType(errors.DefaultCodespace, err.Error())) } if msg.ConsensusState == nil { - return errors.ErrInvalidConsensus(errors.DefaultCodespace) + return sdk.ConvertError(errors.ErrInvalidConsensus(errors.DefaultCodespace)) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("empty address") @@ -98,10 +96,10 @@ func (msg MsgUpdateClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgUpdateClient) ValidateBasic() sdk.Error { if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(err) } if msg.Header == nil { - return errors.ErrInvalidHeader(errors.DefaultCodespace) + return sdk.ConvertError(errors.ErrInvalidHeader(errors.DefaultCodespace)) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("empty address") @@ -148,13 +146,13 @@ func (msg MsgSubmitMisbehaviour) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgSubmitMisbehaviour) ValidateBasic() sdk.Error { if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(err) } if msg.Evidence == nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "evidence is nil") + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "evidence is nil")) } if err := msg.Evidence.ValidateBasic(); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error()) + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error())) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("empty address") diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go index cd416fabdfe8..f7e022ecc89c 100644 --- a/x/ibc/02-client/types/msgs_test.go +++ b/x/ibc/02-client/types/msgs_test.go @@ -5,12 +5,13 @@ import ( "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/secp256k1" + cmn "github.com/tendermint/tendermint/libs/common" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" - "github.com/tendermint/tendermint/crypto/secp256k1" - cmn "github.com/tendermint/tendermint/libs/common" ) func TestMsgCreateClientValidateBasic(t *testing.T) { @@ -103,7 +104,7 @@ type mockBadEvidence struct { // Override ValidateBasic func (mbe mockBadEvidence) ValidateBasic() sdk.Error { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence") + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence")) } func TestMsgSubmitMisbehaviour(t *testing.T) { diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go index 7638c0200882..0bf71ebaa6ae 100644 --- a/x/ibc/02-client/types/querier.go +++ b/x/ibc/02-client/types/querier.go @@ -3,9 +3,10 @@ package types import ( "strings" + "github.com/tendermint/tendermint/crypto/merkle" + tmtypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - "github.com/tendermint/tendermint/crypto/merkle" ) // query routes supported by the IBC client Querier @@ -44,13 +45,34 @@ func NewQueryCommitmentRootParams(id string, height uint64) QueryCommitmentRootP } } +// StateResponse defines the client response for a client state query. +// It includes the commitment proof and the height of the proof. +type StateResponse struct { + ClientState State `json:"client_state" yaml:"client_state"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewClientStateResponse creates a new StateResponse instance. +func NewClientStateResponse( + clientID string, clientState State, proof *merkle.Proof, height int64, +) StateResponse { + return StateResponse{ + ClientState: clientState, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ConsensusStatePath(clientID), "/")), + ProofHeight: uint64(height), + } +} + // ConsensusStateResponse defines the client response for a Consensus state query. // It includes the commitment proof and the height of the proof. type ConsensusStateResponse struct { - ConsensusState tmtypes.ConsensusState - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + ConsensusState tmtypes.ConsensusState `json:"consensus_state" yaml:"consensus_state"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewConsensusStateResponse creates a new ConsensusStateResponse instance. @@ -64,3 +86,24 @@ func NewConsensusStateResponse( ProofHeight: uint64(height), } } + +// RootResponse defines the client response for a commitment root query. +// It includes the commitment proof and the height of the proof. +type RootResponse struct { + Root commitment.Root `json:"root" yaml:"root"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewRootResponse creates a new RootResponse instance. +func NewRootResponse( + clientID string, height uint64, root commitment.Root, proof *merkle.Proof, proofHeight int64, +) RootResponse { + return RootResponse{ + Root: root, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(RootPath(clientID, height), "/")), + ProofHeight: uint64(proofHeight), + } +} diff --git a/x/ibc/02-client/types/state.go b/x/ibc/02-client/types/state.go index 8c60260df0a2..6ae3d0552693 100644 --- a/x/ibc/02-client/types/state.go +++ b/x/ibc/02-client/types/state.go @@ -4,7 +4,7 @@ package types // Any actor holding the Stage can access on and modify that client information. type State struct { // Client ID - id string + ID string `json:"id" yaml:"id"` // Boolean that states if the client is frozen when a misbehaviour proof is // submitted in the event of an equivocation. Frozen bool `json:"frozen" yaml:"frozen"` @@ -13,12 +13,7 @@ type State struct { // NewClientState creates a new ClientState instance func NewClientState(id string) State { return State{ - id: id, + ID: id, Frozen: false, } } - -// ID returns the client identifier -func (s State) ID() string { - return s.id -} diff --git a/x/ibc/02-client/types/tendermint/consensus_state.go b/x/ibc/02-client/types/tendermint/consensus_state.go index 3ad0892a9ea8..f57887045a2f 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state.go +++ b/x/ibc/02-client/types/tendermint/consensus_state.go @@ -2,12 +2,14 @@ package tendermint import ( "bytes" - "errors" + "fmt" lerr "github.com/tendermint/tendermint/lite/errors" tmtypes "github.com/tendermint/tendermint/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienterrors "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -41,7 +43,7 @@ func (cs ConsensusState) GetRoot() commitment.RootI { func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (exported.ConsensusState, error) { tmHeader, ok := header.(Header) if !ok { - return nil, errors.New("header not a valid tendermint header") + return nil, clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace) } if err := cs.checkValidity(tmHeader); err != nil { @@ -55,6 +57,13 @@ func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (ex // // CONTRACT: assumes header.Height > consensusState.Height func (cs ConsensusState) checkValidity(header Header) error { + if header.GetHeight() < cs.Height { + return sdkerrors.Wrap( + clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), + fmt.Sprintf("header height < consensus height (%d < %d)", header.GetHeight(), cs.Height), + ) + } + // check if the hash from the consensus set and header // matches nextHash := cs.NextValidatorSet.Hash() diff --git a/x/ibc/02-client/types/tendermint/misbehaviour.go b/x/ibc/02-client/types/tendermint/misbehaviour.go index 512bb0f72161..1edde8ec1c04 100644 --- a/x/ibc/02-client/types/tendermint/misbehaviour.go +++ b/x/ibc/02-client/types/tendermint/misbehaviour.go @@ -52,20 +52,20 @@ func (ev Evidence) Hash() cmn.HexBytes { // ValidateBasic implements exported.Evidence interface func (ev Evidence) ValidateBasic() sdk.Error { if ev.DuplicateVoteEvidence == nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "duplicate evidence is nil") + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "duplicate evidence is nil")) } err := ev.DuplicateVoteEvidence.ValidateBasic() if err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error()) + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error())) } if ev.ChainID == "" { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "chainID is empty") + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "chainID is empty")) } if ev.ValidatorPower <= 0 { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Validator Power: %d", ev.ValidatorPower)) + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Validator Power: %d", ev.ValidatorPower))) } if ev.TotalPower < ev.ValidatorPower { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Total Power: %d", ev.TotalPower)) + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Total Power: %d", ev.TotalPower))) } return nil } diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index 27757d8163e5..b73456d28dc8 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -29,7 +29,6 @@ const ( CodeInvalidVersion = types.CodeInvalidVersion CodeInvalidHeight = types.CodeInvalidHeight CodeInvalidConnectionState = types.CodeInvalidConnectionState - CodeInvalidProof = types.CodeInvalidProof CodeInvalidCounterparty = types.CodeInvalidCounterparty AttributeKeyConnectionID = types.AttributeKeyConnectionID AttributeKeyCounterpartyClientID = types.AttributeKeyCounterpartyClientID @@ -55,10 +54,8 @@ var ( ErrClientConnectionPathsNotFound = types.ErrClientConnectionPathsNotFound ErrConnectionPath = types.ErrConnectionPath ErrInvalidCounterpartyConnection = types.ErrInvalidCounterpartyConnection - ErrInvalidVersion = types.ErrInvalidVersion ErrInvalidHeight = types.ErrInvalidHeight ErrInvalidConnectionState = types.ErrInvalidConnectionState - ErrInvalidConnectionProof = types.ErrInvalidConnectionProof ErrInvalidCounterparty = types.ErrInvalidCounterparty ConnectionPath = types.ConnectionPath ClientConnectionsPath = types.ClientConnectionsPath diff --git a/x/ibc/03-connection/client/cli/query.go b/x/ibc/03-connection/client/cli/query.go index 266ac4bf02d3..f4502807f859 100644 --- a/x/ibc/03-connection/client/cli/query.go +++ b/x/ibc/03-connection/client/cli/query.go @@ -69,10 +69,6 @@ $ %s query ibc connection end [connection-id] return err } - if res.Proof == nil { - return cliCtx.PrintOutput(connection) - } - connRes := types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height) return cliCtx.PrintOutput(connRes) }, @@ -119,10 +115,6 @@ $ %s query ibc connection client [client-id] return err } - if res.Proof == nil { - return cliCtx.PrintOutput(connectionPaths) - } - connPathsRes := types.NewClientConnectionsResponse(clientID, connectionPaths, res.Proof, res.Height) return cliCtx.PrintOutput(connPathsRes) }, diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index cef560ccdd57..b3115069adbc 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -12,6 +12,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" @@ -25,7 +27,6 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - abci "github.com/tendermint/tendermint/abci/types" ) // Connection Handshake flags @@ -413,7 +414,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1) + csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), cdc, clienttypes.QuerierRoute, clientID1) if err != nil { return err } @@ -467,7 +468,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2) + csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), cdc, clienttypes.QuerierRoute, clientID2) if err != nil { return err } diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index 21a005b12c9f..f9288f7d9ae2 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -8,6 +8,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // ConnOpenInit initialises a connection attempt on chain A. @@ -157,7 +158,7 @@ func (k Keeper) ConnOpenAck( } if types.LatestVersion(connection.Versions) != version { - return types.ErrInvalidVersion( + return ibctypes.ErrInvalidVersion( k.codespace, fmt.Sprintf("connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version), ) diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index b8884c56b3ee..e0c0cce29c11 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -3,11 +3,12 @@ package keeper_test import ( "fmt" + abci "github.com/tendermint/tendermint/abci/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - abci "github.com/tendermint/tendermint/abci/types" ) func (suite *KeeperTestSuite) TestConnOpenInit() { diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index 1488c6c03ec7..337e6dd66a88 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -16,22 +16,18 @@ import ( // Keeper defines the IBC connection keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store - + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType clientKeeper types.ClientKeeper } // NewKeeper creates a new IBC connection Keeper instance func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, ck types.ClientKeeper) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/connection", - prefix: []byte{}, - // prefix: []byte(types.SubModuleName + "/"), // "connection/" + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/connection", clientKeeper: ck, } } @@ -49,7 +45,7 @@ func (k Keeper) GetCommitmentPrefix() commitment.PrefixI { // GetConnection returns a connection with a particular identifier func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) bz := store.Get(types.KeyConnection(connectionID)) if bz == nil { return types.ConnectionEnd{}, false @@ -62,7 +58,7 @@ func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.Conne // SetConnection sets a connection to the store func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) bz := k.cdc.MustMarshalBinaryLengthPrefixed(connection) store.Set(types.KeyConnection(connectionID), bz) } @@ -70,7 +66,7 @@ func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection t // GetClientConnectionPaths returns all the connection paths stored under a // particular client func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) bz := store.Get(types.KeyClientConnections(clientID)) if bz == nil { return nil, false @@ -83,7 +79,7 @@ func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]st // SetClientConnectionPaths sets the connections paths for client func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths []string) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) bz := k.cdc.MustMarshalBinaryLengthPrefixed(paths) store.Set(types.KeyClientConnections(clientID), bz) } @@ -92,7 +88,7 @@ func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths // connections associated with a client. // // CONTRACT: client must already exist -func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID string) sdk.Error { +func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID string) error { conns, found := k.GetClientConnectionPaths(ctx, clientID) if !found { conns = []string{} @@ -107,7 +103,8 @@ func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID st // set of connections associated with a client. // // CONTRACT: client must already exist -func (k Keeper) removeConnectionFromClient(ctx sdk.Context, clientID, connectionID string) sdk.Error { +// nolint: unused +func (k Keeper) removeConnectionFromClient(ctx sdk.Context, clientID, connectionID string) error { conns, found := k.GetClientConnectionPaths(ctx, clientID) if !found { return types.ErrClientConnectionPathsNotFound(k.codespace, clientID) diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 9c086f647d06..bf6dfe0d7839 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -3,14 +3,15 @@ package keeper_test import ( "testing" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" - "github.com/stretchr/testify/suite" - abci "github.com/tendermint/tendermint/abci/types" ) const ( diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go index 85bb02559e78..8802ec7443fe 100644 --- a/x/ibc/03-connection/keeper/querier.go +++ b/x/ibc/03-connection/keeper/querier.go @@ -20,7 +20,7 @@ func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte connection, found := k.GetConnection(ctx, params.ConnectionID) if !found { - return nil, types.ErrConnectionNotFound(k.codespace, params.ConnectionID) + return nil, sdk.ConvertError(types.ErrConnectionNotFound(k.codespace, params.ConnectionID)) } bz, err := types.SubModuleCdc.MarshalJSON(connection) @@ -42,7 +42,7 @@ func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) clientConnectionPaths, found := k.GetClientConnectionPaths(ctx, params.ClientID) if !found { - return nil, types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID) + return nil, sdk.ConvertError(types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID)) } bz, err := types.SubModuleCdc.MarshalJSON(clientConnectionPaths) diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 07eb0a25c6ac..23ec6ca5709b 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -55,12 +55,12 @@ func NewCounterparty(clientID, connectionID string, prefix commitment.PrefixI) C } // ValidateBasic performs a basic validation check of the identifiers and prefix -func (c Counterparty) ValidateBasic() sdk.Error { +func (c Counterparty) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(c.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty connection ID: %s", err.Error())) + return sdkerrors.Wrap(err, "invalid counterparty connection ID") } if err := host.DefaultClientIdentifierValidator(c.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty client ID: %s", err.Error())) + return sdkerrors.Wrap(err, "invalid counterparty client ID") } if c.Prefix == nil || len(c.Prefix.Bytes()) == 0 { return ErrInvalidCounterparty(DefaultCodespace, "invalid counterparty prefix") diff --git a/x/ibc/03-connection/types/errors.go b/x/ibc/03-connection/types/errors.go index b2a2cbe2ad5f..d62e14a49218 100644 --- a/x/ibc/03-connection/types/errors.go +++ b/x/ibc/03-connection/types/errors.go @@ -4,70 +4,92 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // connection error codes const ( DefaultCodespace sdk.CodespaceType = SubModuleName - CodeConnectionExists sdk.CodeType = 101 - CodeConnectionNotFound sdk.CodeType = 102 - CodeClientConnectionPathsNotFound sdk.CodeType = 103 - CodeConnectionPath sdk.CodeType = 104 - CodeInvalidCounterpartyConnection sdk.CodeType = 105 - CodeInvalidVersion sdk.CodeType = 106 - CodeInvalidHeight sdk.CodeType = 107 - CodeInvalidConnectionState sdk.CodeType = 108 - CodeInvalidProof sdk.CodeType = 109 - CodeInvalidCounterparty sdk.CodeType = 110 + CodeConnectionExists sdk.CodeType = 210 + CodeConnectionNotFound sdk.CodeType = 211 + CodeClientConnectionPathsNotFound sdk.CodeType = 212 + CodeConnectionPath sdk.CodeType = 213 + CodeInvalidCounterpartyConnection sdk.CodeType = 214 + CodeInvalidVersion sdk.CodeType = 215 + CodeInvalidHeight sdk.CodeType = 216 + CodeInvalidConnectionState sdk.CodeType = 217 + CodeInvalidCounterparty sdk.CodeType = 218 ) // ErrConnectionExists implements sdk.Error -func ErrConnectionExists(codespace sdk.CodespaceType, connectionID string) sdk.Error { - return sdk.NewError(codespace, CodeConnectionExists, fmt.Sprintf("connection with ID %s already exists", connectionID)) +func ErrConnectionExists(codespace sdk.CodespaceType, connectionID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeConnectionExists), + fmt.Sprintf("connection with ID %s already exists", connectionID), + ) } // ErrConnectionNotFound implements sdk.Error -func ErrConnectionNotFound(codespace sdk.CodespaceType, connectionID string) sdk.Error { - return sdk.NewError(codespace, CodeConnectionNotFound, fmt.Sprintf("connection with ID %s not found", connectionID)) +func ErrConnectionNotFound(codespace sdk.CodespaceType, connectionID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeConnectionNotFound), + fmt.Sprintf("connection with ID %s not found", connectionID), + ) } // ErrClientConnectionPathsNotFound implements sdk.Error -func ErrClientConnectionPathsNotFound(codespace sdk.CodespaceType, clientID string) sdk.Error { - return sdk.NewError(codespace, CodeClientConnectionPathsNotFound, fmt.Sprintf("client connection paths not found for ID %s", clientID)) +func ErrClientConnectionPathsNotFound(codespace sdk.CodespaceType, clientID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientConnectionPathsNotFound), + fmt.Sprintf("client connection paths not found for ID %s", clientID), + ) } // ErrConnectionPath implements sdk.Error -func ErrConnectionPath(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeConnectionPath, "connection path is not associated to the client") +func ErrConnectionPath(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeConnectionPath), + "connection path is not associated to the client", + ) } // ErrInvalidCounterpartyConnection implements sdk.Error -func ErrInvalidCounterpartyConnection(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidCounterpartyConnection, "couldn't verify connection membership on counterparty's client") -} - -// ErrInvalidVersion implements sdk.Error -func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidVersion, msg) +func ErrInvalidCounterpartyConnection(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidCounterpartyConnection), + "couldn't verify connection membership on counterparty's client", + ) } // ErrInvalidHeight implements sdk.Error -func ErrInvalidHeight(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidHeight, msg) +func ErrInvalidHeight(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidHeight), + msg, + ) } // ErrInvalidConnectionState implements sdk.Error -func ErrInvalidConnectionState(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidConnectionState, msg) -} - -// ErrInvalidConnectionProof implements sdk.Error -func ErrInvalidConnectionProof(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidProof, msg) +func ErrInvalidConnectionState(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidConnectionState), + msg, + ) } // ErrInvalidCounterparty implements sdk.Error -func ErrInvalidCounterparty(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidCounterparty, msg) +func ErrInvalidCounterparty(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidCounterparty), + msg, + ) } diff --git a/x/ibc/03-connection/types/keys.go b/x/ibc/03-connection/types/keys.go index 7dd82ae80a2e..40eda70e340f 100644 --- a/x/ibc/03-connection/types/keys.go +++ b/x/ibc/03-connection/types/keys.go @@ -18,6 +18,11 @@ const ( QuerierRoute = SubModuleName ) +// KVStore key prefixes +var ( + KeyPrefixConnection = []byte{0x00} +) + // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths // ConnectionPath defines the path under which connection paths are stored diff --git a/x/ibc/03-connection/types/msgs.go b/x/ibc/03-connection/types/msgs.go index 10ede21b1124..e302badac9c4 100644 --- a/x/ibc/03-connection/types/msgs.go +++ b/x/ibc/03-connection/types/msgs.go @@ -1,10 +1,10 @@ package types import ( - "fmt" "strings" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -49,15 +49,15 @@ func (msg MsgConnectionOpenInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenInit) ValidateBasic() sdk.Error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) } if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid client ID")) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("missing signer address") } - return msg.Counterparty.ValidateBasic() + return sdk.ConvertError(msg.Counterparty.ValidateBasic()) } // GetSignBytes implements sdk.Msg @@ -120,35 +120,35 @@ func (msg MsgConnectionOpenTry) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenTry) ValidateBasic() sdk.Error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) } if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid client ID")) } if len(msg.CounterpartyVersions) == 0 { - return ErrInvalidVersion(DefaultCodespace, "missing counterparty versions") + return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "missing counterparty versions")) } for _, version := range msg.CounterpartyVersions { if strings.TrimSpace(version) == "" { - return ErrInvalidVersion(DefaultCodespace, "version can't be blank") + return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "version can't be blank")) } } if msg.ProofInit == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof init cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof init cannot be nil")) } if msg.ProofConsensus == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof consensus cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof consensus cannot be nil")) } if msg.ProofHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) } if msg.ConsensusHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0")) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("missing signer address") } - return msg.Counterparty.ValidateBasic() + return sdk.ConvertError(msg.Counterparty.ValidateBasic()) } // GetSignBytes implements sdk.Msg @@ -205,22 +205,22 @@ func (msg MsgConnectionOpenAck) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenAck) ValidateBasic() sdk.Error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) } if strings.TrimSpace(msg.Version) == "" { - return ErrInvalidVersion(DefaultCodespace, "version can't be blank") + return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "version can't be blank")) } if msg.ProofTry == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof try cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof try cannot be nil")) } if msg.ProofConsensus == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof consensus cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof consensus cannot be nil")) } if msg.ProofHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) } if msg.ConsensusHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0")) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("missing signer address") @@ -274,15 +274,14 @@ func (msg MsgConnectionOpenConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenConfirm) ValidateBasic() sdk.Error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) } if msg.ProofAck == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof ack cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof ack cannot be nil")) } if msg.ProofHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) } - if msg.Signer.Empty() { return sdk.ErrInvalidAddress("missing signer address") } diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go index 7c94f3036936..87fbae8b7276 100644 --- a/x/ibc/03-connection/types/msgs_test.go +++ b/x/ibc/03-connection/types/msgs_test.go @@ -4,9 +4,10 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - "github.com/stretchr/testify/require" ) func TestNewMsgConnectionOpenInit(t *testing.T) { diff --git a/x/ibc/03-connection/types/querier.go b/x/ibc/03-connection/types/querier.go index 6fbb151342f4..c254bebd6b4c 100644 --- a/x/ibc/03-connection/types/querier.go +++ b/x/ibc/03-connection/types/querier.go @@ -3,8 +3,9 @@ package types import ( "strings" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/tendermint/tendermint/crypto/merkle" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // query routes supported by the IBC connection Querier diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index 25f73b478565..8ce587180679 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -36,7 +36,6 @@ const ( CodePacketTimeout = types.CodePacketTimeout CodeInvalidChannel = types.CodeInvalidChannel CodeInvalidChannelState = types.CodeInvalidChannelState - CodeInvalidChannelProof = types.CodeInvalidChannelProof AttributeKeySenderPort = types.AttributeKeySenderPort AttributeKeyReceiverPort = types.AttributeKeyReceiverPort AttributeKeyChannelID = types.AttributeKeyChannelID @@ -66,7 +65,6 @@ var ( ErrPacketTimeout = types.ErrPacketTimeout ErrInvalidChannel = types.ErrInvalidChannel ErrInvalidChannelState = types.ErrInvalidChannelState - ErrInvalidChannelProof = types.ErrInvalidChannelProof ChannelPath = types.ChannelPath ChannelCapabilityPath = types.ChannelCapabilityPath NextSequenceSendPath = types.NextSequenceSendPath diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index 265ec880d73a..fea92f900ee9 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -11,6 +11,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" @@ -24,7 +26,6 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - abci "github.com/tendermint/tendermint/abci/types" ) const ( diff --git a/x/ibc/04-channel/exported/exported.go b/x/ibc/04-channel/exported/exported.go index 8fb84f7c1c01..6fd31751fef6 100644 --- a/x/ibc/04-channel/exported/exported.go +++ b/x/ibc/04-channel/exported/exported.go @@ -1,9 +1,6 @@ package exported -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - +// PacketI defines the standard interface for IBC packets type PacketI interface { GetSequence() uint64 GetTimeoutHeight() uint64 @@ -12,5 +9,5 @@ type PacketI interface { GetDestPort() string GetDestChannel() string GetData() []byte - ValidateBasic() sdk.Error + ValidateBasic() error } diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 5a8ce10ceb4a..fde534b0f26d 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "fmt" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" @@ -10,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" - abci "github.com/tendermint/tendermint/abci/types" ) func (suite *KeeperTestSuite) createClient() { diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index dc6bbd3fb021..0de7cc329288 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -15,11 +15,9 @@ import ( // Keeper defines the IBC channel keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store - + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper portKeeper types.PortKeeper @@ -32,11 +30,9 @@ func NewKeeper( portKeeper types.PortKeeper, ) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/channel", - prefix: []byte{}, - // prefix: []byte(types.SubModuleName + "/"), // "channel/" + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/channel", clientKeeper: clientKeeper, connectionKeeper: connectionKeeper, portKeeper: portKeeper, @@ -50,7 +46,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetChannel returns a channel with a particular identifier binded to a specific port func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyChannel(portID, channelID)) if bz == nil { return types.Channel{}, false @@ -63,14 +59,14 @@ func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Cha // SetChannel sets a channel to the store func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel types.Channel) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := k.cdc.MustMarshalBinaryLengthPrefixed(channel) store.Set(types.KeyChannel(portID, channelID), bz) } // GetChannelCapability gets a channel's capability key from the store func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) (string, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyChannelCapabilityPath(portID, channelID)) if bz == nil { return "", false @@ -81,13 +77,13 @@ func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) // SetChannelCapability sets a channel's capability key to the store func (k Keeper) SetChannelCapability(ctx sdk.Context, portID, channelID string, key string) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) store.Set(types.KeyChannelCapabilityPath(portID, channelID), []byte(key)) } // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyNextSequenceSend(portID, channelID)) if bz == nil { return 0, false @@ -98,14 +94,14 @@ func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) ( // SetNextSequenceSend sets a channel's next send sequence to the store func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := sdk.Uint64ToBigEndian(sequence) store.Set(types.KeyNextSequenceSend(portID, channelID), bz) } // GetNextSequenceRecv gets a channel's next receive sequence from the store func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyNextSequenceRecv(portID, channelID)) if bz == nil { return 0, false @@ -116,38 +112,38 @@ func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) ( // SetNextSequenceRecv sets a channel's next receive sequence to the store func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := sdk.Uint64ToBigEndian(sequence) store.Set(types.KeyNextSequenceRecv(portID, channelID), bz) } // GetPacketCommitment gets the packet commitment hash from the store func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyPacketCommitment(portID, channelID, sequence)) return bz } // SetPacketCommitment sets the packet commitment hash to the store func (k Keeper) SetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64, commitmentHash []byte) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) store.Set(types.KeyPacketCommitment(portID, channelID, sequence), commitmentHash) } func (k Keeper) deletePacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) store.Delete(types.KeyPacketCommitment(portID, channelID, sequence)) } // SetPacketAcknowledgement sets the packet ack hash to the store func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64, ackHash []byte) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) } // GetPacketAcknowledgement gets the packet ack hash from the store func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyPacketAcknowledgement(portID, channelID, sequence)) if bz == nil { return nil, false diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index f05cc56db841..299b0ab9c5e5 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -3,13 +3,14 @@ package keeper_test import ( "testing" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - "github.com/stretchr/testify/suite" - abci "github.com/tendermint/tendermint/abci/types" ) // define constants used for testing diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go index 3618c5f29fd4..3bf671d1e0fb 100644 --- a/x/ibc/04-channel/keeper/querier.go +++ b/x/ibc/04-channel/keeper/querier.go @@ -20,7 +20,7 @@ func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, s channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) if !found { - return nil, types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID) + return nil, sdk.ConvertError(types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID)) } bz, err := types.SubModuleCdc.MarshalJSON(channel) diff --git a/x/ibc/04-channel/types/channel.go b/x/ibc/04-channel/types/channel.go index 98bbb9b44f1e..d14c42ad6e2c 100644 --- a/x/ibc/04-channel/types/channel.go +++ b/x/ibc/04-channel/types/channel.go @@ -5,8 +5,7 @@ import ( "fmt" "strings" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -33,7 +32,7 @@ func NewChannel( } // ValidateBasic performs a basic validation of the channel fields -func (ch Channel) ValidateBasic() sdk.Error { +func (ch Channel) ValidateBasic() error { if ch.State.String() == "" { return ErrInvalidChannelState( DefaultCodespace, @@ -50,7 +49,7 @@ func (ch Channel) ValidateBasic() sdk.Error { return ErrInvalidChannel(DefaultCodespace, "IBC v1 only supports one connection hop") } if err := host.DefaultConnectionIdentifierValidator(ch.ConnectionHops[0]); err != nil { - return ErrInvalidChannel(DefaultCodespace, errors.Wrap(err, "invalid connection hop ID").Error()) + return sdkerrors.Wrap(err, "invalid connection hop ID") } if strings.TrimSpace(ch.Version) == "" { return ErrInvalidChannel(DefaultCodespace, "channel version can't be blank") @@ -73,12 +72,12 @@ func NewCounterparty(portID, channelID string) Counterparty { } // ValidateBasic performs a basic validation check of the identifiers -func (c Counterparty) ValidateBasic() sdk.Error { +func (c Counterparty) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(c.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty connection ID: %s", err.Error())) + return sdkerrors.Wrap(err, "invalid counterparty connection ID") } if err := host.DefaultChannelIdentifierValidator(c.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty client ID: %s", err.Error())) + return sdkerrors.Wrap(err, "invalid counterparty client ID") } return nil } diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go index 37d3925b513e..318c78017d34 100644 --- a/x/ibc/04-channel/types/errors.go +++ b/x/ibc/04-channel/types/errors.go @@ -4,70 +4,101 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // channel error codes const ( DefaultCodespace sdk.CodespaceType = SubModuleName - CodeChannelExists sdk.CodeType = 101 - CodeChannelNotFound sdk.CodeType = 102 - CodeInvalidCounterpartyChannel sdk.CodeType = 103 - CodeChannelCapabilityNotFound sdk.CodeType = 104 - CodeInvalidPacket sdk.CodeType = 105 - CodeSequenceNotFound sdk.CodeType = 106 - CodePacketTimeout sdk.CodeType = 107 - CodeInvalidChannel sdk.CodeType = 108 - CodeInvalidChannelState sdk.CodeType = 109 - CodeInvalidChannelProof sdk.CodeType = 110 + CodeChannelExists sdk.CodeType = 219 + CodeChannelNotFound sdk.CodeType = 220 + CodeInvalidCounterpartyChannel sdk.CodeType = 221 + CodeChannelCapabilityNotFound sdk.CodeType = 222 + CodeInvalidPacket sdk.CodeType = 223 + CodeSequenceNotFound sdk.CodeType = 224 + CodePacketTimeout sdk.CodeType = 225 + CodeInvalidChannel sdk.CodeType = 226 + CodeInvalidChannelState sdk.CodeType = 227 ) // ErrChannelExists implements sdk.Error -func ErrChannelExists(codespace sdk.CodespaceType, channelID string) sdk.Error { - return sdk.NewError(codespace, CodeChannelExists, fmt.Sprintf("channel with ID %s already exists", channelID)) +func ErrChannelExists(codespace sdk.CodespaceType, channelID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeChannelExists), + fmt.Sprintf("channel with ID %s already exists", channelID), + ) } // ErrChannelNotFound implements sdk.Error -func ErrChannelNotFound(codespace sdk.CodespaceType, portID, channelID string) sdk.Error { - return sdk.NewError(codespace, CodeChannelNotFound, fmt.Sprintf("channel with ID %s on port %s not found", channelID, portID)) +func ErrChannelNotFound(codespace sdk.CodespaceType, portID, channelID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeChannelNotFound), + fmt.Sprintf("channel with ID %s on port %s not found", channelID, portID), + ) } // ErrInvalidCounterpartyChannel implements sdk.Error -func ErrInvalidCounterpartyChannel(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidCounterpartyChannel, msg) +func ErrInvalidCounterpartyChannel(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidCounterpartyChannel), + msg, + ) } // ErrChannelCapabilityNotFound implements sdk.Error -func ErrChannelCapabilityNotFound(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeChannelCapabilityNotFound, "channel capability key not found") +func ErrChannelCapabilityNotFound(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeChannelCapabilityNotFound), + "channel capability key not found", + ) } // ErrInvalidPacket implements sdk.Error -func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidPacket, msg) +func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidPacket), + msg, + ) } // ErrSequenceNotFound implements sdk.Error -func ErrSequenceNotFound(codespace sdk.CodespaceType, seqType string) sdk.Error { - return sdk.NewError(codespace, CodeSequenceNotFound, fmt.Sprintf("next %s sequence counter not found", seqType)) +func ErrSequenceNotFound(codespace sdk.CodespaceType, seqType string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeSequenceNotFound), + fmt.Sprintf("next %s sequence counter not found", seqType), + ) } // ErrPacketTimeout implements sdk.Error -func ErrPacketTimeout(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodePacketTimeout, "packet timeout") +func ErrPacketTimeout(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodePacketTimeout), + "packet timeout", + ) } // ErrInvalidChannel implements sdk.Error -func ErrInvalidChannel(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidChannel, msg) +func ErrInvalidChannel(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidChannel), + msg, + ) } // ErrInvalidChannelState implements sdk.Error -func ErrInvalidChannelState(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidChannelState, msg) -} - -// ErrInvalidChannelProof implements sdk.Error -func ErrInvalidChannelProof(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidChannelProof, msg) +func ErrInvalidChannelState(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidChannelState), + msg, + ) } diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go index f308640b2e32..7849b37f90e1 100644 --- a/x/ibc/04-channel/types/keys.go +++ b/x/ibc/04-channel/types/keys.go @@ -18,6 +18,11 @@ const ( QuerierRoute = SubModuleName ) +// KVStore key prefixes +var ( + KeyPrefixChannel = []byte{0x00} +) + // ChannelPath defines the path under which channels are stored func ChannelPath(portID, channelID string) string { return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index a6d7d856e34f..6f69c5d6ea86 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -1,10 +1,10 @@ package types import ( - "fmt" "strings" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -46,14 +46,14 @@ func (msg MsgChannelOpenInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenInit) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } // Signer can be empty - return msg.Channel.ValidateBasic() + return sdk.ConvertError(msg.Channel.ValidateBasic()) } // GetSignBytes implements sdk.Msg @@ -109,23 +109,23 @@ func (msg MsgChannelOpenTry) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenTry) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if strings.TrimSpace(msg.CounterpartyVersion) == "" { - return ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank") + return sdk.ConvertError(ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank")) } if msg.ProofInit == nil { - return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } if msg.ProofHeight == 0 { - return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) } // Signer can be empty - return msg.Channel.ValidateBasic() + return sdk.ConvertError(msg.Channel.ValidateBasic()) } // GetSignBytes implements sdk.Msg @@ -176,20 +176,20 @@ func (msg MsgChannelOpenAck) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenAck) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if strings.TrimSpace(msg.CounterpartyVersion) == "" { - return ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank") + return sdk.ConvertError(ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank")) } if msg.ProofTry == nil { - return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } if msg.ProofHeight == 0 { - return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) } // Signer can be empty return nil @@ -241,17 +241,17 @@ func (msg MsgChannelOpenConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenConfirm) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if msg.ProofAck == nil { - return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } if msg.ProofHeight == 0 { - return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) } // Signer can be empty return nil @@ -296,11 +296,11 @@ func (msg MsgChannelCloseInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelCloseInit) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } // Signer can be empty return nil @@ -353,16 +353,16 @@ func (msg MsgChannelCloseConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelCloseConfirm) ValidateBasic() sdk.Error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if msg.ProofInit == nil { - return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } if msg.ProofHeight == 0 { - return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) } // Signer can be empty return nil diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index c57a35af74ad..3754ea4efa1a 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -3,9 +3,10 @@ package types import ( "testing" + "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - "github.com/stretchr/testify/require" ) // define constants used for testing @@ -38,21 +39,21 @@ var ( // TestMsgChannelOpenInit tests ValidateBasic for MsgChannelOpenInit func TestMsgChannelOpenInit(t *testing.T) { testMsgs := []MsgChannelOpenInit{ - NewMsgChannelOpenInit("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg - NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id - NewMsgChannelOpenInit(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long port id - NewMsgChannelOpenInit(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // port id contains non-alpha - NewMsgChannelOpenInit("testport", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short channel id - NewMsgChannelOpenInit("testport", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long channel id - NewMsgChannelOpenInit("testport", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // channel id contains non-alpha - NewMsgChannelOpenInit("testport", "testchannel", "1.0", Order(3), connHops, "testcpport", "testcpchannel", addr), // invalid channel order - NewMsgChannelOpenInit("testport", "testchannel", "1.0", ORDERED, invalidConnHops, "testcpport", "testcpchannel", addr), // connection hops more than 1 - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", addr), // too short connection id - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", addr), // too long connection id - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", addr), // connection id contains non-alpha - NewMsgChannelOpenInit("testport", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", addr), // empty channel version - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", addr), // invalid counterparty port id - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, addr), // invalid counterparty channel id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg + NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id + NewMsgChannelOpenInit(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long port id + NewMsgChannelOpenInit(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // port id contains non-alpha + NewMsgChannelOpenInit("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short channel id + NewMsgChannelOpenInit("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long channel id + NewMsgChannelOpenInit("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // channel id contains non-alpha + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", Order(3), connHops, "testcpport", "testcpchannel", addr), // invalid channel order + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", ORDERED, invalidConnHops, "testcpport", "testcpchannel", addr), // connection hops more than 1 + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", addr), // too short connection id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", addr), // too long connection id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", addr), // connection id contains non-alpha + NewMsgChannelOpenInit("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", addr), // empty channel version + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", addr), // invalid counterparty port id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, addr), // invalid counterparty channel id } testCases := []struct { @@ -90,24 +91,24 @@ func TestMsgChannelOpenInit(t *testing.T) { // TestMsgChannelOpenTry tests ValidateBasic for MsgChannelOpenTry func TestMsgChannelOpenTry(t *testing.T) { testMsgs := []MsgChannelOpenTry{ - NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // valid msg - NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short port id - NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long port id - NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenTry("testport", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short channel id - NewMsgChannelOpenTry("testport", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long channel id - NewMsgChannelOpenTry("testport", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", proof, 1, addr), // empty counterparty version - NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty proof - NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 0, addr), // proof height is zero - NewMsgChannelOpenTry("testport", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // invalid channel order - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection hops more than 1 - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short connection id - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long connection id - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection id contains non-alpha - NewMsgChannelOpenTry("testport", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // empty channel version - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", proof, 1, addr), // invalid counterparty port id - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", proof, 1, addr), // invalid counterparty channel id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // valid msg + NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short port id + NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long port id + NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenTry("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short channel id + NewMsgChannelOpenTry("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long channel id + NewMsgChannelOpenTry("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", proof, 1, addr), // empty counterparty version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 0, addr), // proof height is zero + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // invalid channel order + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection hops more than 1 + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // empty channel version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", proof, 1, addr), // invalid counterparty port id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", proof, 1, addr), // invalid counterparty channel id } testCases := []struct { @@ -148,16 +149,16 @@ func TestMsgChannelOpenTry(t *testing.T) { // TestMsgChannelOpenAck tests ValidateBasic for MsgChannelOpenAck func TestMsgChannelOpenAck(t *testing.T) { testMsgs := []MsgChannelOpenAck{ - NewMsgChannelOpenAck("testport", "testchannel", "1.0", proof, 1, addr), // valid msg - NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", proof, 1, addr), // too short port id - NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", proof, 1, addr), // too long port id - NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenAck("testport", invalidShortChannel, "1.0", proof, 1, addr), // too short channel id - NewMsgChannelOpenAck("testport", invalidLongChannel, "1.0", proof, 1, addr), // too long channel id - NewMsgChannelOpenAck("testport", invalidChannel, "1.0", proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenAck("testport", "testchannel", "", proof, 1, addr), // empty counterparty version - NewMsgChannelOpenAck("testport", "testchannel", "1.0", nil, 1, addr), // empty proof - NewMsgChannelOpenAck("testport", "testchannel", "1.0", proof, 0, addr), // proof height is zero + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", proof, 1, addr), // valid msg + NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", proof, 1, addr), // too short port id + NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", proof, 1, addr), // too long port id + NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenAck("testportid", invalidShortChannel, "1.0", proof, 1, addr), // too short channel id + NewMsgChannelOpenAck("testportid", invalidLongChannel, "1.0", proof, 1, addr), // too long channel id + NewMsgChannelOpenAck("testportid", invalidChannel, "1.0", proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenAck("testportid", "testchannel", "", proof, 1, addr), // empty counterparty version + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", proof, 0, addr), // proof height is zero } testCases := []struct { @@ -190,15 +191,15 @@ func TestMsgChannelOpenAck(t *testing.T) { // TestMsgChannelOpenConfirm tests ValidateBasic for MsgChannelOpenConfirm func TestMsgChannelOpenConfirm(t *testing.T) { testMsgs := []MsgChannelOpenConfirm{ - NewMsgChannelOpenConfirm("testport", "testchannel", proof, 1, addr), // valid msg - NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id - NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id - NewMsgChannelOpenConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenConfirm("testport", invalidShortChannel, proof, 1, addr), // too short channel id - NewMsgChannelOpenConfirm("testport", invalidLongChannel, proof, 1, addr), // too long channel id - NewMsgChannelOpenConfirm("testport", invalidChannel, proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenConfirm("testport", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelOpenConfirm("testport", "testchannel", proof, 0, addr), // proof height is zero + NewMsgChannelOpenConfirm("testportid", "testchannel", proof, 1, addr), // valid msg + NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id + NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id + NewMsgChannelOpenConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenConfirm("testportid", invalidShortChannel, proof, 1, addr), // too short channel id + NewMsgChannelOpenConfirm("testportid", invalidLongChannel, proof, 1, addr), // too long channel id + NewMsgChannelOpenConfirm("testportid", invalidChannel, proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testportid", "testchannel", proof, 0, addr), // proof height is zero } testCases := []struct { @@ -230,13 +231,13 @@ func TestMsgChannelOpenConfirm(t *testing.T) { // TestMsgChannelCloseInit tests ValidateBasic for MsgChannelCloseInit func TestMsgChannelCloseInit(t *testing.T) { testMsgs := []MsgChannelCloseInit{ - NewMsgChannelCloseInit("testport", "testchannel", addr), // valid msg - NewMsgChannelCloseInit(invalidShortPort, "testchannel", addr), // too short port id - NewMsgChannelCloseInit(invalidLongPort, "testchannel", addr), // too long port id - NewMsgChannelCloseInit(invalidPort, "testchannel", addr), // port id contains non-alpha - NewMsgChannelCloseInit("testport", invalidShortChannel, addr), // too short channel id - NewMsgChannelCloseInit("testport", invalidLongChannel, addr), // too long channel id - NewMsgChannelCloseInit("testport", invalidChannel, addr), // channel id contains non-alpha + NewMsgChannelCloseInit("testportid", "testchannel", addr), // valid msg + NewMsgChannelCloseInit(invalidShortPort, "testchannel", addr), // too short port id + NewMsgChannelCloseInit(invalidLongPort, "testchannel", addr), // too long port id + NewMsgChannelCloseInit(invalidPort, "testchannel", addr), // port id contains non-alpha + NewMsgChannelCloseInit("testportid", invalidShortChannel, addr), // too short channel id + NewMsgChannelCloseInit("testportid", invalidLongChannel, addr), // too long channel id + NewMsgChannelCloseInit("testportid", invalidChannel, addr), // channel id contains non-alpha } testCases := []struct { @@ -266,15 +267,15 @@ func TestMsgChannelCloseInit(t *testing.T) { // TestMsgChannelCloseConfirm tests ValidateBasic for MsgChannelCloseConfirm func TestMsgChannelCloseConfirm(t *testing.T) { testMsgs := []MsgChannelCloseConfirm{ - NewMsgChannelCloseConfirm("testport", "testchannel", proof, 1, addr), // valid msg - NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id - NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id - NewMsgChannelCloseConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha - NewMsgChannelCloseConfirm("testport", invalidShortChannel, proof, 1, addr), // too short channel id - NewMsgChannelCloseConfirm("testport", invalidLongChannel, proof, 1, addr), // too long channel id - NewMsgChannelCloseConfirm("testport", invalidChannel, proof, 1, addr), // channel id contains non-alpha - NewMsgChannelCloseConfirm("testport", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelCloseConfirm("testport", "testchannel", proof, 0, addr), // proof height is zero + NewMsgChannelCloseConfirm("testportid", "testchannel", proof, 1, addr), // valid msg + NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id + NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id + NewMsgChannelCloseConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha + NewMsgChannelCloseConfirm("testportid", invalidShortChannel, proof, 1, addr), // too short channel id + NewMsgChannelCloseConfirm("testportid", invalidLongChannel, proof, 1, addr), // too long channel id + NewMsgChannelCloseConfirm("testportid", invalidChannel, proof, 1, addr), // channel id contains non-alpha + NewMsgChannelCloseConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testportid", "testchannel", proof, 0, addr), // proof height is zero } testCases := []struct { diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go index 8d170cc62a9d..8cfadf458487 100644 --- a/x/ibc/04-channel/types/packet.go +++ b/x/ibc/04-channel/types/packet.go @@ -3,7 +3,6 @@ package types import ( "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -37,29 +36,29 @@ func NewPacket( } } -// Sequence implements PacketI interface +// GetSequence implements PacketI interface func (p Packet) GetSequence() uint64 { return p.Sequence } -// TimeoutHeight implements PacketI interface +// GetTimeoutHeight implements PacketI interface func (p Packet) GetTimeoutHeight() uint64 { return p.Timeout } -// SourcePort implements PacketI interface +// GetSourcePort implements PacketI interface func (p Packet) GetSourcePort() string { return p.SourcePort } -// SourceChannel implements PacketI interface +// GetSourceChannel implements PacketI interface func (p Packet) GetSourceChannel() string { return p.SourceChannel } -// DestPort implements PacketI interface +// GetDestPort implements PacketI interface func (p Packet) GetDestPort() string { return p.DestinationPort } -// DestChannel implements PacketI interface +// GetDestChannel implements PacketI interface func (p Packet) GetDestChannel() string { return p.DestinationChannel } -// Data implements PacketI interface +// GetData implements PacketI interface func (p Packet) GetData() []byte { return p.Data } // ValidateBasic implements PacketI interface -func (p Packet) ValidateBasic() sdk.Error { +func (p Packet) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(p.SourcePort); err != nil { return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source port ID: %s", err.Error())) } @@ -104,5 +103,5 @@ func NewOpaquePacket(sequence, timeout uint64, sourcePort, sourceChannel, return OpaquePacket{&Packet} } -// Data implements PacketI interface +// GetData implements PacketI interface func (op OpaquePacket) GetData() []byte { return nil } diff --git a/x/ibc/05-port/alias.go b/x/ibc/05-port/alias.go index a74c7fe61537..de0907a93212 100644 --- a/x/ibc/05-port/alias.go +++ b/x/ibc/05-port/alias.go @@ -12,26 +12,22 @@ import ( ) const ( - DefaultCodespace = types.DefaultCodespace - CodePortExists = types.CodePortExists - CodePortNotFound = types.CodePortNotFound - CodePortNotAuthenticated = types.CodePortNotAuthenticated - CodeInvalidPortID = types.CodeInvalidPortID - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute + DefaultCodespace = types.DefaultCodespace + CodePortExists = types.CodePortExists + CodePortNotFound = types.CodePortNotFound + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute ) var ( // functions aliases - NewKeeper = keeper.NewKeeper - ErrPortExists = types.ErrPortExists - ErrPortNotFound = types.ErrPortNotFound - ErrPortNotAuthenticated = types.ErrPortNotAuthenticated - ErrInvalidPortID = types.ErrInvalidPortID - PortPath = types.PortPath - KeyPort = types.KeyPort + NewKeeper = keeper.NewKeeper + ErrPortExists = types.ErrPortExists + ErrPortNotFound = types.ErrPortNotFound + PortPath = types.PortPath + KeyPort = types.KeyPort ) type ( diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index cdb48010237f..54e5e1ad13de 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -14,9 +14,7 @@ type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store - ports map[string]string - bound []string + ports map[string]bool } // NewKeeper creates a new IBC connection Keeper instance @@ -25,22 +23,13 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) storeKey: key, cdc: cdc, codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/port", - prefix: []byte{}, - // prefix: []byte(types.SubModuleName + "/"), // "port/" - ports: make(map[string]string), // map of capability key names to port ids + ports: make(map[string]bool), // map of capability key names to port ids } } -// GetPorts returns the list of bound ports. -// (these ports still must have been bound statically) -func (k Keeper) GetPorts() []string { - return k.bound -} - -// GetPort retrieves a given port ID from keeper map -func (k Keeper) GetPort(ck sdk.CapabilityKey) (string, bool) { - portID, found := k.ports[ck.Name()] - return portID, found +// isBounded checks a given port ID is already bounded. +func (k Keeper) isBounded(portID string) bool { + return k.ports[portID] } // BindPort binds to a port and returns the associated capability. @@ -52,15 +41,13 @@ func (k Keeper) BindPort(portID string) sdk.CapabilityKey { panic(err.Error()) } - for _, b := range k.bound { - if b == portID { - panic(fmt.Sprintf("port %s is already bound", portID)) - } + if k.isBounded(portID) { + panic(fmt.Sprintf("port %s is already bound", portID)) } key := sdk.NewKVStoreKey(portID) - k.ports[key.Name()] = portID - k.bound = append(k.bound, portID) + k.ports[key.Name()] = true // NOTE: key name and value always match + return key } @@ -73,5 +60,5 @@ func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { panic(err.Error()) } - return k.ports[key.Name()] == portID + return k.ports[key.Name()] } diff --git a/x/ibc/05-port/types/errors.go b/x/ibc/05-port/types/errors.go index 20031c826107..d15b07bf0791 100644 --- a/x/ibc/05-port/types/errors.go +++ b/x/ibc/05-port/types/errors.go @@ -4,34 +4,41 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // port error codes const ( DefaultCodespace sdk.CodespaceType = SubModuleName - CodePortExists sdk.CodeType = 101 - CodePortNotFound sdk.CodeType = 102 - CodePortNotAuthenticated sdk.CodeType = 103 - CodeInvalidPortID sdk.CodeType = 104 + CodePortExists sdk.CodeType = 228 + CodePortNotFound sdk.CodeType = 229 + CodeInvalidPort sdk.CodeType = 230 ) // ErrPortExists implements sdk.Error -func ErrPortExists(codespace sdk.CodespaceType, portID string) sdk.Error { - return sdk.NewError(codespace, CodePortExists, fmt.Sprintf("port with ID %s is already binded", portID)) +func ErrPortExists(codespace sdk.CodespaceType, portID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodePortExists), + fmt.Sprintf("port with ID %s is already binded", portID), + ) } // ErrPortNotFound implements sdk.Error -func ErrPortNotFound(codespace sdk.CodespaceType, portID string) sdk.Error { - return sdk.NewError(codespace, CodePortNotFound, fmt.Sprintf("port with ID %s not found", portID)) +func ErrPortNotFound(codespace sdk.CodespaceType, portID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodePortNotFound), + fmt.Sprintf("port with ID %s not found", portID), + ) } -// ErrPortNotAuthenticated implements sdk.Error -func ErrPortNotAuthenticated(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodePortNotAuthenticated, "port failed authentication") -} - -// ErrInvalidPortID implements sdk.Error -func ErrInvalidPortID(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidPortID, "invalid port ID") +// ErrInvalidPort implements sdk.Error +func ErrInvalidPort(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodePortNotFound), + msg, + ) } diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go index 66028740581e..ab75c9dab2d2 100644 --- a/x/ibc/20-transfer/alias.go +++ b/x/ibc/20-transfer/alias.go @@ -12,36 +12,23 @@ import ( ) const ( - DefaultPacketTimeout = keeper.DefaultPacketTimeout - DefaultCodespace = types.DefaultCodespace - CodeInvalidAddress = types.CodeInvalidAddress - CodeErrSendPacket = types.CodeErrSendPacket - CodeInvalidPacketData = types.CodeInvalidPacketData - CodeInvalidChannelOrder = types.CodeInvalidChannelOrder - CodeInvalidPort = types.CodeInvalidPort - CodeInvalidVersion = types.CodeInvalidVersion - AttributeKeyReceiver = types.AttributeKeyReceiver - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - BoundPortID = types.BoundPortID + DefaultPacketTimeout = keeper.DefaultPacketTimeout + DefaultCodespace = types.DefaultCodespace + AttributeKeyReceiver = types.AttributeKeyReceiver + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute ) var ( // functions aliases - NewKeeper = keeper.NewKeeper - RegisterCodec = types.RegisterCodec - ErrInvalidAddress = types.ErrInvalidAddress - ErrSendPacket = types.ErrSendPacket - ErrInvalidPacketData = types.ErrInvalidPacketData - ErrInvalidChannelOrder = types.ErrInvalidChannelOrder - ErrInvalidPort = types.ErrInvalidPort - ErrInvalidVersion = types.ErrInvalidVersion - GetEscrowAddress = types.GetEscrowAddress - GetDenomPrefix = types.GetDenomPrefix - GetModuleAccountName = types.GetModuleAccountName - NewMsgTransfer = types.NewMsgTransfer + NewKeeper = keeper.NewKeeper + RegisterCodec = types.RegisterCodec + GetEscrowAddress = types.GetEscrowAddress + GetDenomPrefix = types.GetDenomPrefix + GetModuleAccountName = types.GetModuleAccountName + NewMsgTransfer = types.NewMsgTransfer // variable aliases ModuleCdc = types.ModuleCdc diff --git a/x/ibc/20-transfer/client/cli/query.go b/x/ibc/20-transfer/client/cli/query.go index 4be0103385ee..6aad7157e228 100644 --- a/x/ibc/20-transfer/client/cli/query.go +++ b/x/ibc/20-transfer/client/cli/query.go @@ -7,12 +7,13 @@ import ( "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - abci "github.com/tendermint/tendermint/abci/types" ) // GetQueryCmd returns the query commands for IBC fungible token transfer diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go index 8594783e6456..444e966b97c8 100644 --- a/x/ibc/20-transfer/keeper/callbacks.go +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -5,8 +5,11 @@ import ( "strings" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // nolint: unused @@ -20,15 +23,19 @@ func (k Keeper) onChanOpenInit( version string, ) error { if order != channeltypes.UNORDERED { - return types.ErrInvalidChannelOrder(k.codespace, order.String()) + return channeltypes.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") } - if counterparty.PortID != types.BoundPortID { - return types.ErrInvalidPort(k.codespace, portID) + // NOTE: here the capability key name defines the port ID of the counterparty + if counterparty.PortID != k.boundedCapability.Name() { + return porttypes.ErrInvalidPort( + k.codespace, + fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", portID, k.boundedCapability.Name()), + ) } if strings.TrimSpace(version) != "" { - return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -48,19 +55,23 @@ func (k Keeper) onChanOpenTry( counterpartyVersion string, ) error { if order != channeltypes.UNORDERED { - return types.ErrInvalidChannelOrder(k.codespace, order.String()) + return channeltypes.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") } - if counterparty.PortID != types.BoundPortID { - return types.ErrInvalidPort(k.codespace, portID) + // NOTE: here the capability key name defines the port ID of the counterparty + if counterparty.PortID != k.boundedCapability.Name() { + return porttypes.ErrInvalidPort( + k.codespace, + fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", portID, k.boundedCapability.Name()), + ) } if strings.TrimSpace(version) != "" { - return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") } if strings.TrimSpace(counterpartyVersion) != "" { - return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid counterparty version: %s", version)) + return ibctypes.ErrInvalidVersion(k.codespace, "counterparty version cannot be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -76,7 +87,7 @@ func (k Keeper) onChanOpenAck( version string, ) error { if strings.TrimSpace(version) != "" { - return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") } return nil @@ -122,7 +133,7 @@ func (k Keeper) onRecvPacket( err := data.UnmarshalJSON(packet.GetData()) if err != nil { - return types.ErrInvalidPacketData(k.codespace) + return sdkerrors.Wrap(err, "invalid packet data") } return k.ReceiveTransfer( @@ -150,7 +161,7 @@ func (k Keeper) onTimeoutPacket( err := data.UnmarshalJSON(packet.GetData()) if err != nil { - return types.ErrInvalidPacketData(k.codespace) + return sdkerrors.Wrap(err, "invalid packet data") } // check the denom prefix diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index 95576d4609f3..c42786f42741 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -22,7 +22,9 @@ type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store + + // Capability key and port to which ICS20 is binded. Used for packet relaying. + boundedCapability sdk.CapabilityKey clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper @@ -34,9 +36,9 @@ type Keeper struct { // NewKeeper creates a new IBC transfer Keeper instance func NewKeeper( cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, - clientKeeper types.ClientKeeper, connnectionKeeper types.ConnectionKeeper, - channelKeeper types.ChannelKeeper, bankKeeper types.BankKeeper, - supplyKeeper types.SupplyKeeper, + capKey sdk.CapabilityKey, clientKeeper types.ClientKeeper, + connnectionKeeper types.ConnectionKeeper, channelKeeper types.ChannelKeeper, + bankKeeper types.BankKeeper, supplyKeeper types.SupplyKeeper, ) Keeper { // ensure ibc transfer module account is set @@ -45,15 +47,15 @@ func NewKeeper( } return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/transfer", - prefix: []byte(types.SubModuleName + "/"), // "transfer/" - clientKeeper: clientKeeper, - connectionKeeper: connnectionKeeper, - channelKeeper: channelKeeper, - bankKeeper: bankKeeper, - supplyKeeper: supplyKeeper, + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/transfer", + boundedCapability: capKey, + clientKeeper: clientKeeper, + connectionKeeper: connnectionKeeper, + channelKeeper: channelKeeper, + bankKeeper: bankKeeper, + supplyKeeper: supplyKeeper, } } diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index d87a589bbd80..dae2180dc44f 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -5,6 +5,7 @@ import ( "strings" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" @@ -61,7 +62,7 @@ func (k Keeper) ReceivePacket(ctx sdk.Context, packet channelexported.PacketI, p var data types.PacketData err = data.UnmarshalJSON(packet.GetData()) if err != nil { - return sdk.NewError(types.DefaultCodespace, types.CodeInvalidPacketData, "invalid packet data") + return sdkerrors.Wrap(err, "invalid packet data") } return k.ReceiveTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestPort(), packet.GetDestChannel(), data) @@ -173,7 +174,7 @@ func (k Keeper) createOutgoingPacket( // TODO: This should be binary-marshaled and hashed (for the commitment in the store). packetDataBz, err := packetData.MarshalJSON() if err != nil { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidPacketData, "invalid packet data") + return sdkerrors.Wrap(err, "invalid packet data") } packet := channeltypes.NewPacket( @@ -186,8 +187,5 @@ func (k Keeper) createOutgoingPacket( packetDataBz, ) - // TODO: Remove this, capability keys are never generated when sending packets. Not sure why this is here. - key := sdk.NewKVStoreKey(types.BoundPortID) - - return k.channelKeeper.SendPacket(ctx, packet, key) + return k.channelKeeper.SendPacket(ctx, packet, k.boundedCapability) } diff --git a/x/ibc/20-transfer/types/errors.go b/x/ibc/20-transfer/types/errors.go deleted file mode 100644 index 51f95d560a01..000000000000 --- a/x/ibc/20-transfer/types/errors.go +++ /dev/null @@ -1,51 +0,0 @@ -package types - -import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// transfer error codes -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodeInvalidAddress sdk.CodeType = 101 - CodeErrSendPacket sdk.CodeType = 102 - CodeInvalidPacketData sdk.CodeType = 103 - CodeInvalidChannelOrder sdk.CodeType = 104 - CodeInvalidPort sdk.CodeType = 105 - CodeInvalidVersion sdk.CodeType = 106 - CodeProofMissing sdk.CodeType = 107 - CodeInvalidHeight sdk.CodeType = 108 -) - -// ErrInvalidAddress implements sdk.Error -func ErrInvalidAddress(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidAddress, msg) -} - -// ErrSendPacket implements sdk.Error -func ErrSendPacket(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeErrSendPacket, "failed to send packet") -} - -// ErrInvalidPacketData implements sdk.Error -func ErrInvalidPacketData(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidPacketData, "invalid packet data") -} - -// ErrInvalidChannelOrder implements sdk.Error -func ErrInvalidChannelOrder(codespace sdk.CodespaceType, order string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidChannelOrder, fmt.Sprintf("invalid channel order: %s", order)) -} - -// ErrInvalidPort implements sdk.Error -func ErrInvalidPort(codespace sdk.CodespaceType, portID string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidPort, fmt.Sprintf("invalid port ID: %s", portID)) -} - -// ErrInvalidVersion implements sdk.Error -func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidVersion, msg) -} diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go index 09b54dcadea5..469456bbd946 100644 --- a/x/ibc/20-transfer/types/keys.go +++ b/x/ibc/20-transfer/types/keys.go @@ -22,8 +22,8 @@ const ( // QuerierRoute is the querier route for IBC transfer QuerierRoute = SubModuleName - // BoundPortID defines the name of the capability key - BoundPortID = "bank" + // DefaultCodespace is the default error codespace for the ibc transfers + DefaultCodespace sdk.CodespaceType = SubModuleName ) // GetEscrowAddress returns the escrow address for the specified channel diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index 506676e66d7e..d0e7d9fbbe72 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -1,13 +1,12 @@ package types import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" - host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" - + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -46,11 +45,11 @@ func (MsgTransfer) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgTransfer) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.SourcePort); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.SourcePort); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source port ID")) } - if err := host.DefaultPortIdentifierValidator(msg.SourceChannel); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.SourceChannel); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source channel ID")) } if !msg.Amount.IsValid() { return sdk.ErrInvalidCoins("transfer amount is invalid") @@ -106,25 +105,25 @@ func (MsgRecvPacket) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgRecvPacket) ValidateBasic() sdk.Error { - if msg.Height < 1 { - return sdk.NewError(DefaultCodespace, CodeInvalidHeight, "invalid height") + if msg.Height == 0 { + return sdk.ConvertError(connectiontypes.ErrInvalidHeight(DefaultCodespace, "height must be > 0")) } - if msg.Proofs == nil { - return sdk.NewError(DefaultCodespace, CodeProofMissing, "proof missing") + if msg.Proofs == nil || len(msg.Proofs) == 0 { + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "missing proofs")) } for _, proof := range msg.Proofs { if proof.Proof == nil { - return sdk.NewError(DefaultCodespace, CodeProofMissing, "proof missing") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } } if msg.Signer.Empty() { - return sdk.NewError(DefaultCodespace, CodeInvalidAddress, "invalid signer") + return sdk.ErrInvalidAddress("missing signer address") } - return msg.Packet.ValidateBasic() + return sdk.ConvertError(msg.Packet.ValidateBasic()) } // GetSignBytes implements sdk.Msg diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/merkle.go index ab428eeaf737..3c41559f4b4f 100644 --- a/x/ibc/23-commitment/merkle.go +++ b/x/ibc/23-commitment/merkle.go @@ -2,6 +2,7 @@ package commitment import ( "errors" + "net/url" "github.com/tendermint/tendermint/crypto/merkle" @@ -90,9 +91,13 @@ func (Path) GetCommitmentType() Type { return Merkle } -// String implements fmt.Stringer +// String implements fmt.Stringer. It returns unescaped path of the URL string. func (p Path) String() string { - return p.KeyPath.String() + path, err := url.PathUnescape(p.KeyPath.String()) + if err != nil { + panic(err) + } + return path } // ApplyPrefix constructs a new commitment path from the arguments. It interprets diff --git a/x/ibc/24-host/errors.go b/x/ibc/24-host/errors.go index e6a526e6d0f8..0ff6ad59d896 100644 --- a/x/ibc/24-host/errors.go +++ b/x/ibc/24-host/errors.go @@ -1,22 +1,47 @@ package host import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// IBCCodeSpace is the codespace for all errors defined in the ibc module -const IBCCodeSpace = "ibc" +// SubModuleName defines the ICS 24 host +const SubModuleName = "host" + +// Error codes specific to the ibc host submodule +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName -var ( - // ErrInvalidID is returned if identifier string is invalid - ErrInvalidID = sdkerrors.Register(IBCCodeSpace, 1, "invalid identifier") + CodeInvalidID sdk.CodeType = 231 + CodeInvalidPath sdk.CodeType = 232 + CodeInvalidPacket sdk.CodeType = 233 +) - // ErrInvalidPath is returned if path string is invalid - ErrInvalidPath = sdkerrors.Register(IBCCodeSpace, 2, "invalid path") +// ErrInvalidID returns a typed ABCI error for an invalid identifier +func ErrInvalidID(codespace sdk.CodespaceType, id string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidID), + fmt.Sprintf("invalid identifier '%s'", id), + ) +} - // ErrInvalidEvidence is returned if evidence is invalid - ErrInvalidEvidence = sdkerrors.Register(IBCCodeSpace, 3, "invalid evidence") +// ErrInvalidPath returns a typed ABCI error for an invalid path +func ErrInvalidPath(codespace sdk.CodespaceType, path string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidPath), + fmt.Sprintf("invalid path '%s'", path), + ) +} - // ErrInvalidPacket is returned if packets embedded in msg are invalid - ErrInvalidPacket = sdkerrors.Register(IBCCodeSpace, 4, "invalid packet extracted from msg") -) +// ErrInvalidPacket returns a typed ABCI error for an invalid identifier +func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidPacket), + fmt.Sprintf("invalid packet: '%s'", msg), + ) +} diff --git a/x/ibc/24-host/validate.go b/x/ibc/24-host/validate.go index 6632d27c25c1..8c20c0065282 100644 --- a/x/ibc/24-host/validate.go +++ b/x/ibc/24-host/validate.go @@ -25,15 +25,15 @@ type ValidateFn func(string) error func defaultIdentifierValidator(id string, min, max int) error { // valid id MUST NOT contain "/" separator if strings.Contains(id, "/") { - return sdkerrors.Wrap(ErrInvalidID, "identifier cannot contain separator: /") + return sdkerrors.Wrap(ErrInvalidID(DefaultCodespace, id), "identifier cannot contain separator: /") } // valid id must be between 10 and 20 characters if len(id) < min || len(id) > max { - return sdkerrors.Wrapf(ErrInvalidID, "identifier has invalid length: %d, must be between %d-%d characters", len(id), min, max) + return sdkerrors.Wrapf(ErrInvalidID(DefaultCodespace, id), "identifier has invalid length: %d, must be between %d-%d characters", len(id), min, max) } // valid id must contain only lower alphabetic characters if !isAlphaLower(id) { - return sdkerrors.Wrap(ErrInvalidID, "identifier must contain only lowercase alphabetic characters") + return sdkerrors.Wrap(ErrInvalidID(DefaultCodespace, id), "identifier must contain only lowercase alphabetic characters") } return nil } @@ -76,7 +76,7 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { // Each path element must either be valid identifier or alphanumeric err := idValidator(p) if err != nil && !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath, "path contains invalid identifier or non-alphanumeric path element: %s", p) + return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "path contains invalid identifier or non-alphanumeric path element: %s", p) } } return nil @@ -91,7 +91,7 @@ func DefaultPathValidator(path string) error { for _, p := range pathArr { // Each path element must either be alphanumeric if !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath, "invalid path element containing non-alphanumeric characters: %s", p) + return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "invalid path element containing non-alphanumeric characters: %s", p) } } return nil diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 2145416efb55..2c28b5c9dd51 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -3,6 +3,7 @@ package keeper import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -28,7 +29,13 @@ func NewKeeper( connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) portKeeper := port.NewKeeper(cdc, key, codespace) channelKeeper := channel.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, portKeeper) - transferKeeper := transfer.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, channelKeeper, bk, sk) + + // TODO: move out of IBC keeper. Blocked on ADR15 + capKey := portKeeper.BindPort(bank.ModuleName) + transferKeeper := transfer.NewKeeper( + cdc, key, codespace, capKey, + clientKeeper, connectionKeeper, channelKeeper, bk, sk, + ) return Keeper{ ClientKeeper: clientKeeper, diff --git a/x/ibc/keeper/querier_test.go b/x/ibc/keeper/querier_test.go index 62e37faac203..81abe9ffadb1 100644 --- a/x/ibc/keeper/querier_test.go +++ b/x/ibc/keeper/querier_test.go @@ -13,7 +13,7 @@ import ( ) // TestNewQuerier tests that the querier paths are correct. -// NOTE: the actuall testing functionallity are located on each ICS querier test. +// NOTE: the actuall testing functionality are located on each ICS querier test. func (suite *KeeperTestSuite) TestNewQuerier() { query := abci.RequestQuery{ diff --git a/x/ibc/types/errors.go b/x/ibc/types/errors.go new file mode 100644 index 000000000000..086851321b6a --- /dev/null +++ b/x/ibc/types/errors.go @@ -0,0 +1,33 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// common IBC error codes +const ( + // DefaultCodespace of the IBC module + DefaultCodespace sdk.CodespaceType = ModuleName + + CodeInvalidProof sdk.CodeType = 234 + CodeInvalidVersion sdk.CodeType = 235 +) + +// ErrInvalidProof implements sdk.Error +func ErrInvalidProof(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidProof), + msg, + ) +} + +// ErrInvalidVersion implements sdk.Error +func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidVersion), + msg, + ) +} diff --git a/x/ibc/types/types.go b/x/ibc/types/types.go index bce43911994f..6722e5f3a426 100644 --- a/x/ibc/types/types.go +++ b/x/ibc/types/types.go @@ -1,9 +1,5 @@ package types -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - const ( // ModuleName is the name of the IBC module ModuleName = "ibc" @@ -16,7 +12,4 @@ const ( // RouterKey is the msg router key for the IBC module RouterKey string = ModuleName - - // DefaultCodespace of the IBC module - DefaultCodespace sdk.CodespaceType = ModuleName ) diff --git a/x/ibc/version/version.go b/x/ibc/version/version.go deleted file mode 100644 index a7d3275fae5b..000000000000 --- a/x/ibc/version/version.go +++ /dev/null @@ -1,13 +0,0 @@ -package version - -import "strconv" - -const Version int64 = 1 - -func DefaultPrefix() []byte { - return Prefix(Version) -} - -func Prefix(version int64) []byte { - return []byte("v" + strconv.FormatInt(version, 10) + "/") -} From ee8bde2162cd891297832e5952b3dd7d726e702e Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 12 Nov 2019 10:34:14 -0800 Subject: [PATCH 012/176] Fix codec issue in ics23 --- x/ibc/23-commitment/codec.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x/ibc/23-commitment/codec.go b/x/ibc/23-commitment/codec.go index 7e90e8cac69e..6e977ac1e678 100644 --- a/x/ibc/23-commitment/codec.go +++ b/x/ibc/23-commitment/codec.go @@ -4,6 +4,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ) +var SubModuleCdc = codec.New() + // RegisterCodec registers types declared in this package func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*RootI)(nil), nil) @@ -16,3 +18,7 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(Path{}, "ibc/commitment/merkle/Path", nil) cdc.RegisterConcrete(Proof{}, "ibc/commitment/merkle/Proof", nil) } + +func init() { + RegisterCodec(SubModuleCdc) +} From ae8ea8f391935ed252ec7e37e973d047967f0cff Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 12 Nov 2019 10:46:17 -0800 Subject: [PATCH 013/176] Modify codec registration style to match previous working state --- x/ibc/02-client/types/codec.go | 8 +++++--- x/ibc/03-connection/types/codec.go | 8 +++++--- x/ibc/04-channel/types/codec.go | 6 +++--- x/ibc/23-commitment/codec.go | 8 +++++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index 551403e6ad89..d595f583baa9 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -7,7 +7,7 @@ import ( ) // SubModuleCdc defines the IBC client codec. -var SubModuleCdc = codec.New() +var SubModuleCdc *codec.Codec // RegisterCodec registers the IBC client interfaces and types func RegisterCodec(cdc *codec.Codec) { @@ -22,8 +22,10 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(tendermint.ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) cdc.RegisterConcrete(tendermint.Header{}, "ibc/client/tendermint/Header", nil) cdc.RegisterConcrete(tendermint.Evidence{}, "ibc/client/tendermint/Evidence", nil) + + SetSubModuleCodec(cdc) } -func init() { - RegisterCodec(SubModuleCdc) +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc } diff --git a/x/ibc/03-connection/types/codec.go b/x/ibc/03-connection/types/codec.go index 23fb04e37a8f..4317d3c6d539 100644 --- a/x/ibc/03-connection/types/codec.go +++ b/x/ibc/03-connection/types/codec.go @@ -5,7 +5,7 @@ import ( ) // SubModuleCdc defines the IBC connection codec. -var SubModuleCdc = codec.New() +var SubModuleCdc *codec.Codec // RegisterCodec registers the IBC connection types func RegisterCodec(cdc *codec.Codec) { @@ -14,8 +14,10 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgConnectionOpenAck{}, "ibc/connection/MsgConnectionOpenAck", nil) cdc.RegisterConcrete(MsgConnectionOpenConfirm{}, "ibc/connection/MsgConnectionOpenConfirm", nil) cdc.RegisterConcrete(ConnectionEnd{}, "ibc/connection/ConnectionEnd", nil) + + SetSubModuleCodec(cdc) } -func init() { - RegisterCodec(SubModuleCdc) +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc } diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index 0839edede775..06c268e3e307 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -6,7 +6,7 @@ import ( ) // SubModuleCdc defines the IBC channel codec. -var SubModuleCdc = codec.New() +var SubModuleCdc *codec.Codec // RegisterCodec registers all the necessary types and interfaces for the // IBC channel. @@ -23,6 +23,6 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgChannelCloseConfirm{}, "ibc/channel/MsgChannelCloseConfirm", nil) } -func init() { - RegisterCodec(SubModuleCdc) +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc } diff --git a/x/ibc/23-commitment/codec.go b/x/ibc/23-commitment/codec.go index 6e977ac1e678..1fc535cfc0ca 100644 --- a/x/ibc/23-commitment/codec.go +++ b/x/ibc/23-commitment/codec.go @@ -4,7 +4,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ) -var SubModuleCdc = codec.New() +var SubModuleCdc *codec.Codec // RegisterCodec registers types declared in this package func RegisterCodec(cdc *codec.Codec) { @@ -17,8 +17,10 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(Prefix{}, "ibc/commitment/merkle/Prefix", nil) cdc.RegisterConcrete(Path{}, "ibc/commitment/merkle/Path", nil) cdc.RegisterConcrete(Proof{}, "ibc/commitment/merkle/Proof", nil) + + SetSubModuleCodec(cdc) } -func init() { - RegisterCodec(SubModuleCdc) +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc } From e12d24731001548a23564904314188b9c8106654 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Tue, 12 Nov 2019 14:59:00 -0800 Subject: [PATCH 014/176] write port tests --- x/ibc/05-port/keeper/keeper.go | 2 +- x/ibc/05-port/keeper/keeper_test.go | 76 +++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 x/ibc/05-port/keeper/keeper_test.go diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index cdb48010237f..0c46b40e0c8f 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -47,7 +47,7 @@ func (k Keeper) GetPort(ck sdk.CapabilityKey) (string, bool) { // Ports must be bound statically when the chain starts in `app.go`. // The capability must then be passed to a module which will need to pass // it as an extra parameter when calling functions on the IBC module. -func (k Keeper) BindPort(portID string) sdk.CapabilityKey { +func (k *Keeper) BindPort(portID string) sdk.CapabilityKey { if err := host.DefaultPortIdentifierValidator(portID); err != nil { panic(err.Error()) } diff --git a/x/ibc/05-port/keeper/keeper_test.go b/x/ibc/05-port/keeper/keeper_test.go new file mode 100644 index 000000000000..f4bf12590428 --- /dev/null +++ b/x/ibc/05-port/keeper/keeper_test.go @@ -0,0 +1,76 @@ +package keeper_test + +import ( + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/keeper" + abci "github.com/tendermint/tendermint/abci/types" +) + +var ( + validPort = "validportid" + invalidPort = "invalidPortID" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.keeper = &app.IBCKeeper.PortKeeper +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (suite *KeeperTestSuite) TestBind() { + // Test that invalid portID causes panic + require.Panics(suite.T(), func() { suite.keeper.BindPort(invalidPort) }, "Did not panic on invalid portID") + + // Test that valid BindPort returns capability key + capKey := suite.keeper.BindPort(validPort) + require.NotNil(suite.T(), capKey, "capabilityKey is nil on valid BindPort") + + // Test that port is added to bound list after BindPort is called + ports := suite.keeper.GetPorts() + require.Equal(suite.T(), []string{validPort}, ports, "portID not added to bound list") + + // Test that rebinding the same portid causes panic + require.Panics(suite.T(), func() { suite.keeper.BindPort(validPort) }, "did not panic on re-binding the same port") +} + +func (suite *KeeperTestSuite) TestAuthenticate() { + capKey := suite.keeper.BindPort(validPort) + + // Require that passing in invalid portID causes panic + require.Panics(suite.T(), func() { suite.keeper.Authenticate(capKey, invalidPort) }, "did not panic on invalid portID") + + // Valid authentication should return true + auth := suite.keeper.Authenticate(capKey, validPort) + require.True(suite.T(), auth, "valid authentication failed") + + // Test that authenticating against incorrect portid fails + auth = suite.keeper.Authenticate(capKey, "wrongportid") + require.False(suite.T(), auth, "invalid authentication failed") + + // Test that authenticating port against different valid + // capability key fails + capKey2 := suite.keeper.BindPort("otherportid") + auth = suite.keeper.Authenticate(capKey2, validPort) + require.False(suite.T(), auth, "invalid authentication for different capKey failed") +} From 6cd6d4fa96d650db6e36555044d3c4b8ba4e7159 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 Nov 2019 17:12:54 -0500 Subject: [PATCH 015/176] ICS-02: Keeper Tests (#5329) * add keeper tests * fix tendermint tests --- x/ibc/02-client/keeper/client_test.go | 113 ++++++++++++++++++ x/ibc/02-client/keeper/keeper_test.go | 102 ++++++++++++++++ .../types/tendermint/consensus_state_test.go | 4 +- .../types/tendermint/tendermint_test.go | 46 +------ .../02-client/types/tendermint/test_utils.go | 48 +++++++- 5 files changed, 266 insertions(+), 47 deletions(-) create mode 100644 x/ibc/02-client/keeper/client_test.go create mode 100644 x/ibc/02-client/keeper/keeper_test.go diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go new file mode 100644 index 000000000000..923a6e710981 --- /dev/null +++ b/x/ibc/02-client/keeper/client_test.go @@ -0,0 +1,113 @@ +package keeper_test + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/stretchr/testify/require" + tmtypes "github.com/tendermint/tendermint/types" +) + +const ( + testClientType exported.ClientType = iota + 2 +) + +func (suite *KeeperTestSuite) TestCreateClient() { + // Test Valid CreateClient + state, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + require.Nil(suite.T(), err, "CreateClient failed") + + // Test ClientState stored correctly + expectedState := types.State{ + ID: testClientID, + Frozen: false, + } + require.Equal(suite.T(), expectedState, state, "Incorrect ClientState returned") + + // Test ClientType and VerifiedRoot stored correctly + clientType, _ := suite.keeper.GetClientType(suite.ctx, testClientID) + require.Equal(suite.T(), exported.Tendermint, clientType, "Incorrect ClientType stored") + root, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()) + require.Equal(suite.T(), suite.consensusState.GetRoot(), root, "Incorrect root stored") + + // Test that trying to CreateClient on existing client fails + _, err = suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + require.NotNil(suite.T(), err, "CreateClient on existing client: %s passed", testClientID) +} + +func (suite *KeeperTestSuite) TestUpdateClient() { + privVal := tmtypes.NewMockPV() + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + altSigners := []tmtypes.PrivValidator{privVal} + + // Test invalid cases all fail and do not update state + cases := []struct { + name string + malleate func() + expErr bool + }{ + {"valid update", func() {}, false}, + {"wrong client type", func() { + suite.keeper.SetClientType(suite.ctx, testClientID, testClientType) + }, true}, + {"frozen client", func() { + clientState, _ := suite.keeper.GetClientState(suite.ctx, testClientID) + clientState.Frozen = true + suite.keeper.SetClientState(suite.ctx, clientState) + }, true}, + {"past height", func() { + suite.header = tendermint.MakeHeader(2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + }, true}, + {"validatorHash incorrect", func() { + suite.header = tendermint.MakeHeader(4, altValSet, suite.valSet, altSigners) + }, true}, + {"nextHash incorrect", func() { + suite.header.NextValidatorSet = altValSet + }, true}, + {"header fails validateBasic", func() { + suite.header.ChainID = "test" + }, true}, + {"verify future commit fails", func() { + suite.consensusState.NextValidatorSet = altValSet + suite.keeper.SetConsensusState(suite.ctx, testClientID, suite.consensusState) + }, true}, + } + + for _, tc := range cases { + suite.Run(fmt.Sprintf("Case %s", tc.name), func() { + // Reset suite on each subtest + suite.SetupTest() + + _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + require.Nil(suite.T(), err, "CreateClient failed") + + tc.malleate() + err = suite.keeper.UpdateClient(suite.ctx, testClientID, suite.header) + + retrievedConsState, _ := suite.keeper.GetConsensusState(suite.ctx, testClientID) + tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) + tmConsState.NextValidatorSet.TotalVotingPower() + retrievedRoot, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()+1) + if tc.expErr { + require.NotNil(suite.T(), err, "Invalid UpdateClient passed", tc.name) + + // require no state changes occurred + require.Equal(suite.T(), suite.consensusState, tmConsState, "Consensus state changed after invalid UpdateClient") + require.Nil(suite.T(), retrievedRoot, "Root added for new height after invalid UpdateClient") + } else { + require.Nil(suite.T(), err, "Valid UpdateClient failed", tc.name) + + // require state changes were performed correctly + require.Equal(suite.T(), suite.header.GetHeight(), retrievedConsState.GetHeight(), "height not updated correctly") + require.Equal(suite.T(), commitment.NewRoot(suite.header.AppHash), retrievedConsState.GetRoot(), "root not updated correctly") + require.Equal(suite.T(), suite.header.NextValidatorSet, tmConsState.NextValidatorSet, "NextValidatorSet not updated correctly") + + } + + }) + } +} diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go new file mode 100644 index 000000000000..da81be0edb12 --- /dev/null +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -0,0 +1,102 @@ +package keeper_test + +import ( + "testing" + + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + testClientID = "gaia" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper + consensusState tendermint.ConsensusState + header tendermint.Header + valSet *tmtypes.ValidatorSet + privVal tmtypes.PrivValidator +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.keeper = &app.IBCKeeper.ClientKeeper + + suite.privVal = tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + suite.header = tendermint.MakeHeader(4, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + + suite.consensusState = tendermint.ConsensusState{ + ChainID: testClientID, + Height: 3, + Root: commitment.NewRoot([]byte("hash")), + NextValidatorSet: suite.valSet, + } +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (suite *KeeperTestSuite) TestSetClientState() { + clientState := types.NewClientState(testClientID) + suite.keeper.SetClientState(suite.ctx, clientState) + + retrievedState, ok := suite.keeper.GetClientState(suite.ctx, testClientID) + require.True(suite.T(), ok, "GetClientState failed") + require.Equal(suite.T(), clientState, retrievedState, "Client states are not equal") +} + +func (suite *KeeperTestSuite) TestSetClientType() { + suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) + clientType, ok := suite.keeper.GetClientType(suite.ctx, testClientID) + + require.True(suite.T(), ok, "GetClientType failed") + require.Equal(suite.T(), exported.Tendermint, clientType, "ClientTypes not stored correctly") +} + +func (suite *KeeperTestSuite) TestSetConsensusState() { + suite.keeper.SetConsensusState(suite.ctx, testClientID, suite.consensusState) + + retrievedConsState, ok := suite.keeper.GetConsensusState(suite.ctx, testClientID) + + require.True(suite.T(), ok, "GetConsensusState failed") + tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) + // force recalculation of unexported totalVotingPower so we can compare consensusState + tmConsState.NextValidatorSet.TotalVotingPower() + require.Equal(suite.T(), suite.consensusState, tmConsState, "ConsensusState not stored correctly") +} + +func (suite *KeeperTestSuite) TestSetVerifiedRoot() { + root := commitment.NewRoot([]byte("hash")) + suite.keeper.SetVerifiedRoot(suite.ctx, testClientID, 3, root) + + retrievedRoot, ok := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, 3) + + require.True(suite.T(), ok, "GetVerifiedRoot failed") + require.Equal(suite.T(), root, retrievedRoot, "Root stored incorrectly") +} diff --git a/x/ibc/02-client/types/tendermint/consensus_state_test.go b/x/ibc/02-client/types/tendermint/consensus_state_test.go index 2f4129226228..07c1015a3067 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state_test.go +++ b/x/ibc/02-client/types/tendermint/consensus_state_test.go @@ -27,7 +27,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { // reset and make header fail validatebasic suite.SetupTest() - suite.header.ChainID = "not_mychain" + suite.header.ChainID = "not_gaia" err = suite.cs.checkValidity(suite.header) require.NotNil(suite.T(), err, "invalid header should fail ValidateBasic") } @@ -44,7 +44,7 @@ func (suite *TendermintTestSuite) TestCheckUpdate() { // make header invalid so update should be unsuccessful suite.SetupTest() - suite.header.ChainID = "not_mychain" + suite.header.ChainID = "not_gaia" cs, err = suite.cs.CheckValidityAndUpdateState(suite.header) require.NotNil(suite.T(), err) diff --git a/x/ibc/02-client/types/tendermint/tendermint_test.go b/x/ibc/02-client/types/tendermint/tendermint_test.go index 11817f73e9ff..cb3e572d6289 100644 --- a/x/ibc/02-client/types/tendermint/tendermint_test.go +++ b/x/ibc/02-client/types/tendermint/tendermint_test.go @@ -1,15 +1,12 @@ package tendermint import ( - "math" "testing" - "time" "github.com/stretchr/testify/suite" "github.com/tendermint/tendermint/crypto/tmhash" tmtypes "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/version" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -27,49 +24,11 @@ func (suite *TendermintTestSuite) SetupTest() { privVal := tmtypes.NewMockPV() val := tmtypes.NewValidator(privVal.GetPubKey(), 10) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) - vsetHash := valSet.Hash() - timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) - tmHeader := tmtypes.Header{ - Version: version.Consensus{Block: 2, App: 2}, - ChainID: "mychain", - Height: 3, - Time: timestamp, - NumTxs: 100, - TotalTxs: 1000, - LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt64, make([]byte, tmhash.Size)), - LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), - DataHash: tmhash.Sum([]byte("data_hash")), - ValidatorsHash: vsetHash, - NextValidatorsHash: vsetHash, - ConsensusHash: tmhash.Sum([]byte("consensus_hash")), - AppHash: tmhash.Sum([]byte("app_hash")), - LastResultsHash: tmhash.Sum([]byte("last_results_hash")), - EvidenceHash: tmhash.Sum([]byte("evidence_hash")), - ProposerAddress: privVal.GetPubKey().Address(), - } - hhash := tmHeader.Hash() - blockID := makeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) - voteSet := tmtypes.NewVoteSet("mychain", 3, 1, tmtypes.PrecommitType, valSet) - commit, err := tmtypes.MakeCommit(blockID, 3, 1, voteSet, []tmtypes.PrivValidator{privVal}) - if err != nil { - panic(err) - } - - signedHeader := tmtypes.SignedHeader{ - Header: &tmHeader, - Commit: commit, - } - - header := Header{ - SignedHeader: signedHeader, - ValidatorSet: valSet, - NextValidatorSet: valSet, - } - + suite.header = MakeHeader(3, valSet, valSet, []tmtypes.PrivValidator{privVal}) root := commitment.NewRoot(tmhash.Sum([]byte("my root"))) cs := ConsensusState{ - ChainID: "mychain", + ChainID: "gaia", Height: 3, Root: root, NextValidatorSet: valSet, @@ -78,7 +37,6 @@ func (suite *TendermintTestSuite) SetupTest() { // set fields in suite suite.privVal = privVal suite.valSet = valSet - suite.header = header suite.cs = cs } diff --git a/x/ibc/02-client/types/tendermint/test_utils.go b/x/ibc/02-client/types/tendermint/test_utils.go index a88bd13d3b1c..ac25a13fabbf 100644 --- a/x/ibc/02-client/types/tendermint/test_utils.go +++ b/x/ibc/02-client/types/tendermint/test_utils.go @@ -1,8 +1,12 @@ package tendermint import ( + "math" + "time" + "github.com/tendermint/tendermint/crypto/tmhash" tmtypes "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/version" ) // Copied unimported test functions from tmtypes to use them here @@ -38,10 +42,52 @@ func randomDuplicatedVoteEvidence() *tmtypes.DuplicateVoteEvidence { val := tmtypes.NewMockPV() blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), 1000, tmhash.Sum([]byte("partshash"))) blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), 1000, tmhash.Sum([]byte("partshash"))) - const chainID = "mychain" + const chainID = "gaia" return &tmtypes.DuplicateVoteEvidence{ PubKey: val.GetPubKey(), VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID), VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2), } } + +func MakeHeader(height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { + vsetHash := valSet.Hash() + nextHash := nextValSet.Hash() + timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) + tmHeader := tmtypes.Header{ + Version: version.Consensus{Block: 2, App: 2}, + ChainID: "gaia", + Height: height, + Time: timestamp, + NumTxs: 100, + TotalTxs: 1000, + LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt64, make([]byte, tmhash.Size)), + LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), + DataHash: tmhash.Sum([]byte("data_hash")), + ValidatorsHash: vsetHash, + NextValidatorsHash: nextHash, + ConsensusHash: tmhash.Sum([]byte("consensus_hash")), + AppHash: tmhash.Sum([]byte("app_hash")), + LastResultsHash: tmhash.Sum([]byte("last_results_hash")), + EvidenceHash: tmhash.Sum([]byte("evidence_hash")), + ProposerAddress: signers[0].GetPubKey().Address(), + } + hhash := tmHeader.Hash() + blockID := makeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) + voteSet := tmtypes.NewVoteSet("gaia", height, 1, tmtypes.PrecommitType, valSet) + commit, err := tmtypes.MakeCommit(blockID, height, 1, voteSet, signers) + if err != nil { + panic(err) + } + + signedHeader := tmtypes.SignedHeader{ + Header: &tmHeader, + Commit: commit, + } + + return Header{ + SignedHeader: signedHeader, + ValidatorSet: valSet, + NextValidatorSet: nextValSet, + } +} From 3a8f469d782ac3464dd6fd1a9fa5eca0ad290d94 Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 21 Nov 2019 01:22:13 +0800 Subject: [PATCH 016/176] Fix proof verification; remove store key prefixes; add additional path validations (#5313) * fix poof verify * minor cleanup * fix tests * remove key prefixes * fix tests --- client/keys/root_test.go | 2 +- x/ibc/02-client/types/keys.go | 2 +- x/ibc/03-connection/keeper/handshake_test.go | 8 +- x/ibc/03-connection/keeper/keeper.go | 15 ---- x/ibc/03-connection/types/keys.go | 2 +- x/ibc/04-channel/keeper/handshake_test.go | 87 ++++++++++---------- x/ibc/04-channel/types/keys.go | 2 +- x/ibc/05-port/keeper/keeper.go | 4 + x/ibc/05-port/keeper/keeper_test.go | 7 +- x/ibc/23-commitment/merkle.go | 7 +- x/ibc/23-commitment/merkle_test.go | 3 +- x/ibc/24-host/validate.go | 10 ++- 12 files changed, 73 insertions(+), 76 deletions(-) diff --git a/client/keys/root_test.go b/client/keys/root_test.go index 6794d725e6f0..1e85a696f850 100644 --- a/client/keys/root_test.go +++ b/client/keys/root_test.go @@ -11,5 +11,5 @@ func TestCommands(t *testing.T) { assert.NotNil(t, rootCommands) // Commands are registered - assert.Equal(t, 11, len(rootCommands.Commands())) + assert.Equal(t, 12, len(rootCommands.Commands())) } diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go index eba16d0c169c..acebca3ee09a 100644 --- a/x/ibc/02-client/types/keys.go +++ b/x/ibc/02-client/types/keys.go @@ -20,7 +20,7 @@ const ( // KVStore key prefixes var ( - KeyPrefixClient = []byte{0x00} + KeyPrefixClient = []byte{} ) // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index e0c0cce29c11..fede95f47fe9 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -79,12 +79,12 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { connection.GetCompatibleVersions(), proofInit, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) - suite.Nil(err) + suite.NoError(err) //check connection state conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) suite.True(existed) - suite.Equal(connection.TRYOPEN, conn.State) + suite.Equal(connection.TRYOPEN.String(), conn.State.String(), "invalid connection state") return err } @@ -172,7 +172,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { //check connection state conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID2) suite.True(existed) - suite.Equal(connection.OPEN, conn.State) + suite.Equal(connection.OPEN.String(), conn.State.String(), "invalid connection state") return err } @@ -228,7 +228,7 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { //check connection state conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) suite.True(existed) - suite.Equal(connection.OPEN, conn.State) + suite.Equal(connection.OPEN.String(), conn.State.String(), "invalid connection state") return err } diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index 337e6dd66a88..d86a527d169c 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -128,13 +128,6 @@ func (k Keeper) VerifyMembership( pathStr string, value []byte, ) bool { - // FIXME: commented out for demo - /* - clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) - if !found { - return false - } - */ path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) if err != nil { return false @@ -151,14 +144,6 @@ func (k Keeper) VerifyNonMembership( proof commitment.ProofI, pathStr string, ) bool { - // FIXME: commented out for demo - /* - clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) - if !found { - return false - } - */ - path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) if err != nil { return false diff --git a/x/ibc/03-connection/types/keys.go b/x/ibc/03-connection/types/keys.go index 40eda70e340f..dbdbc576c61d 100644 --- a/x/ibc/03-connection/types/keys.go +++ b/x/ibc/03-connection/types/keys.go @@ -20,7 +20,7 @@ const ( // KVStore key prefixes var ( - KeyPrefixConnection = []byte{0x00} + KeyPrefixConnection = []byte{} ) // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index fde534b0f26d..a383e3622bda 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -108,23 +108,23 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.NotNil(err) // channel has already exist + suite.Error(err) // channel has already exist suite.deleteChannel(testPort1, testChannel1) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.NONE) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) suite.True(found) - suite.Equal(types.INIT, channel.State) + suite.Equal(types.INIT.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanOpenTry() { @@ -137,35 +137,36 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.updateClient() proofInit, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel has already exist + suite.Error(err) // channel has already exist suite.deleteChannel(testPort2, testChannel2) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // unauthenticated port + suite.Error(err) // unauthenticated port err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.NONE) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel membership verification failed due to invalid counterparty + suite.Error(err) // channel membership verification failed due to invalid counterparty suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) + fmt.Println(proofInit) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) suite.True(found) - suite.Equal(types.OPENTRY, channel.State) + suite.Equal(types.OPENTRY.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanOpenAck() { @@ -176,40 +177,40 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { suite.updateClient() proofTry, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // channel does not exist + suite.Error(err) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // invalid channel state + suite.Error(err) // invalid channel state suite.createChannel(testPort2, testChannel1, testConnection, testPort1, testChannel2, types.INIT) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort2, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // unauthenticated port + suite.Error(err) // unauthenticated port suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.NONE) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) suite.updateClient() proofTry, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // channel membership verification failed due to invalid counterparty + suite.Error(err) // channel membership verification failed due to invalid counterparty suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) suite.updateClient() proofTry, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) suite.True(found) - suite.Equal(types.OPEN, channel.State) + suite.Equal(types.OPEN.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanOpenConfirm() { @@ -220,70 +221,70 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { suite.updateClient() proofAck, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // channel does not exist + suite.Error(err) // channel does not exist suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // invalid channel state + suite.Error(err) // invalid channel state suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.OPENTRY) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort1, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // unauthenticated port + suite.Error(err) // unauthenticated port suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.NONE) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) suite.updateClient() proofAck, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // channel membership verification failed due to invalid counterparty + suite.Error(err) // channel membership verification failed due to invalid counterparty suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) suite.updateClient() proofAck, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) suite.True(found) - suite.Equal(types.OPEN, channel.State) + suite.Equal(types.OPEN.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanCloseInit() { suite.bindPort(testPort1) err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort2, testChannel1) - suite.NotNil(err) // authenticated port + suite.Error(err) // authenticated port err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.NotNil(err) // channel does not exist + suite.Error(err) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.NotNil(err) // channel is already closed + suite.Error(err) // channel is already closed suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.TRYOPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) suite.True(found) - suite.Equal(types.CLOSED, channel.State) + suite.Equal(types.CLOSED.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanCloseConfirm() { @@ -294,37 +295,37 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { suite.updateClient() proofInit, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort1, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // unauthenticated port + suite.Error(err) // unauthenticated port err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel does not exist + suite.Error(err) // channel does not exist suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.CLOSED) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel is already closed + suite.Error(err) // channel is already closed suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.TRYOPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel membership verification failed due to invalid counterparty + suite.Error(err) // channel membership verification failed due to invalid counterparty suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) suite.True(found) - suite.Equal(types.CLOSED, channel.State) + suite.Equal(types.CLOSED.String(), channel.State.String(), "invalid channel state") } diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go index 7849b37f90e1..27c444959ec7 100644 --- a/x/ibc/04-channel/types/keys.go +++ b/x/ibc/04-channel/types/keys.go @@ -20,7 +20,7 @@ const ( // KVStore key prefixes var ( - KeyPrefixChannel = []byte{0x00} + KeyPrefixChannel = []byte{} ) // ChannelPath defines the path under which channels are stored diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index 450c76418ef8..3d17a6881be8 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -60,5 +60,9 @@ func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { panic(err.Error()) } + if key.Name() != portID { + return false + } + return k.ports[key.Name()] } diff --git a/x/ibc/05-port/keeper/keeper_test.go b/x/ibc/05-port/keeper/keeper_test.go index f4bf12590428..320471d56030 100644 --- a/x/ibc/05-port/keeper/keeper_test.go +++ b/x/ibc/05-port/keeper/keeper_test.go @@ -1,9 +1,10 @@ package keeper_test import ( + "testing" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - "testing" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -46,10 +47,6 @@ func (suite *KeeperTestSuite) TestBind() { capKey := suite.keeper.BindPort(validPort) require.NotNil(suite.T(), capKey, "capabilityKey is nil on valid BindPort") - // Test that port is added to bound list after BindPort is called - ports := suite.keeper.GetPorts() - require.Equal(suite.T(), []string{validPort}, ports, "portID not added to bound list") - // Test that rebinding the same portid causes panic require.Panics(suite.T(), func() { suite.keeper.BindPort(validPort) }, "did not panic on re-binding the same port") } diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/merkle.go index 3c41559f4b4f..33d84408f997 100644 --- a/x/ibc/23-commitment/merkle.go +++ b/x/ibc/23-commitment/merkle.go @@ -91,8 +91,13 @@ func (Path) GetCommitmentType() Type { return Merkle } -// String implements fmt.Stringer. It returns unescaped path of the URL string. +// String implements fmt.Stringer. func (p Path) String() string { + return p.KeyPath.String() +} + +// Pretty returns the unescaped path of the URL string. +func (p Path) Pretty() string { path, err := url.PathUnescape(p.KeyPath.String()) if err != nil { panic(err) diff --git a/x/ibc/23-commitment/merkle_test.go b/x/ibc/23-commitment/merkle_test.go index bfd2dc5a485c..01dc9f2edcb4 100644 --- a/x/ibc/23-commitment/merkle_test.go +++ b/x/ibc/23-commitment/merkle_test.go @@ -112,7 +112,8 @@ func TestApplyPrefix(t *testing.T) { prefixedPath, err := commitment.ApplyPrefix(prefix, pathStr) require.Nil(t, err, "valid prefix returns error") - require.Equal(t, "/storePrefixKey/path1/path2/path3/key", prefixedPath.String(), "Prefixed path incorrect") + require.Equal(t, "/storePrefixKey/path1/path2/path3/key", prefixedPath.Pretty(), "Prefixed path incorrect") + require.Equal(t, "/storePrefixKey/path1%2Fpath2%2Fpath3%2Fkey", prefixedPath.String(), "Prefixed scaped path incorrect") // invalid prefix contains non-alphanumeric character invalidPathStr := "invalid-path/doesitfail?/hopefully" diff --git a/x/ibc/24-host/validate.go b/x/ibc/24-host/validate.go index 8c20c0065282..f6b3d14751e7 100644 --- a/x/ibc/24-host/validate.go +++ b/x/ibc/24-host/validate.go @@ -88,10 +88,14 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { // checking that all path elements are alphanumeric func DefaultPathValidator(path string) error { pathArr := strings.Split(path, "/") + if pathArr[0] == path { + return sdkerrors.Wrap(ErrInvalidPath(DefaultCodespace, path), "path doesn't contain any separator '/'") + } + for _, p := range pathArr { - // Each path element must either be alphanumeric - if !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "invalid path element containing non-alphanumeric characters: %s", p) + // Each path element must be alphanumeric and non-blank + if strings.TrimSpace(p) == "" || !isAlphaNumeric(p) { + return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "invalid path element containing non-alphanumeric characters: '%s'", p) } } return nil From 7c987feed0b7f178659c48637561cdcbc92372cb Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 21 Nov 2019 18:33:22 +0800 Subject: [PATCH 017/176] Add ICS20 tests (#5308) * add ics20 test * delete debug * fix ics20 test * revert and modify * optimize test * add ics20 msg test * fix test * add packet tests and more msgs tests * add ReceivePacket and callbacks tests * fix callbacks test * add handler tests for ics20 * fix handler tests * minor cleanup * test all positive amounts * update test suite NotNil to Error * fix ics20 tests * expected error --- x/ibc/04-channel/keeper/handshake_test.go | 2 +- x/ibc/05-port/alias.go | 1 + x/ibc/20-transfer/alias.go | 1 - x/ibc/20-transfer/handler_test.go | 271 ++++++++++++++++++++ x/ibc/20-transfer/keeper/callbacks.go | 71 +++--- x/ibc/20-transfer/keeper/callbacks_test.go | 168 +++++++++++++ x/ibc/20-transfer/keeper/keeper_test.go | 61 ++++- x/ibc/20-transfer/keeper/relay.go | 29 +-- x/ibc/20-transfer/keeper/relay_test.go | 279 ++++++++++++++++++++- x/ibc/20-transfer/types/msgs.go | 10 +- x/ibc/20-transfer/types/msgs_test.go | 189 ++++++++++++++ x/ibc/20-transfer/types/packet.go | 37 +-- x/ibc/20-transfer/types/packet_test.go | 39 +++ 13 files changed, 1061 insertions(+), 97 deletions(-) create mode 100644 x/ibc/20-transfer/handler_test.go create mode 100644 x/ibc/20-transfer/keeper/callbacks_test.go create mode 100644 x/ibc/20-transfer/types/msgs_test.go create mode 100644 x/ibc/20-transfer/types/packet_test.go diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index a383e3622bda..efd704c28d21 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -80,7 +80,7 @@ func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID } func (suite *KeeperTestSuite) deleteChannel(portID string, chanID string) { - store := prefix.NewStore(suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)), []byte{}) + store := prefix.NewStore(suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)), types.KeyPrefixChannel) store.Delete(types.KeyChannel(portID, chanID)) } diff --git a/x/ibc/05-port/alias.go b/x/ibc/05-port/alias.go index de0907a93212..ef3b6be60633 100644 --- a/x/ibc/05-port/alias.go +++ b/x/ibc/05-port/alias.go @@ -26,6 +26,7 @@ var ( NewKeeper = keeper.NewKeeper ErrPortExists = types.ErrPortExists ErrPortNotFound = types.ErrPortNotFound + ErrInvalidPort = types.ErrInvalidPort PortPath = types.PortPath KeyPort = types.KeyPort ) diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go index ab75c9dab2d2..ee87c56d8b3e 100644 --- a/x/ibc/20-transfer/alias.go +++ b/x/ibc/20-transfer/alias.go @@ -45,5 +45,4 @@ type ( MsgTransfer = types.MsgTransfer MsgRecvPacket = types.MsgRecvPacket PacketData = types.PacketData - PacketDataAlias = types.PacketDataAlias ) diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go new file mode 100644 index 000000000000..89fad1195d09 --- /dev/null +++ b/x/ibc/20-transfer/handler_test.go @@ -0,0 +1,271 @@ +package transfer_test + +import ( + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/cosmos/cosmos-sdk/x/supply" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" +) + +// define constants used for testing +const ( + testChainID = "test-chain-id" + testClient = "test-client" + testClientType = clientexported.Tendermint + + testConnection = "testconnection" + testPort1 = "bank" + testPort2 = "testportid" + testChannel1 = "firstchannel" + testChannel2 = "secondchannel" + + testChannelOrder = channel.UNORDERED + testChannelVersion = "1.0" +) + +// define variables used for testing +var ( + testAddr1 = sdk.AccAddress([]byte("testaddr1")) + testAddr2 = sdk.AccAddress([]byte("testaddr2")) + + testCoins, _ = sdk.ParseCoins("100atom") + testPrefixedCoins1, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort1, testChannel1))) + testPrefixedCoins2, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort2, testChannel2))) +) + +type HandlerTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp +} + +func (suite *HandlerTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.app = app + + suite.createClient() + suite.createConnection(connection.OPEN) +} + +func (suite *HandlerTestSuite) createClient() { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + suite.NoError(err) +} + +func (suite *HandlerTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) +} + +func (suite *HandlerTestSuite) createConnection(state connection.State) { + connection := connection.ConnectionEnd{ + State: state, + ClientID: testClient, + Counterparty: connection.Counterparty{ + ClientID: testClient, + ConnectionID: testConnection, + Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + }, + Versions: connection.GetCompatibleVersions(), + } + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) +} + +func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channel.State) { + ch := channel.Channel{ + State: state, + Ordering: testChannelOrder, + Counterparty: channel.Counterparty{ + PortID: counterpartyPort, + ChannelID: counterpartyChan, + }, + ConnectionHops: []string{connID}, + Version: testChannelVersion, + } + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) +} + +func (suite *HandlerTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + +func (suite *HandlerTestSuite) TestHandleMsgTransfer() { + source := true + + msg := transfer.NewMsgTransfer(testPort1, testChannel1, testCoins, testAddr1, testAddr2, source) + res := transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // channel does not exist + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // next send sequence not found + + nextSeqSend := uint64(1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // sender has insufficient coins + + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.True(res.Code.IsOK(), "%v", res) // successfully executed + + // test when the source is false + source = false + + msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, source) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // incorrect denom prefix + + msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, source) + suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.True(res.Code.IsOK(), "%v", res) // successfully executed +} + +func (suite *HandlerTestSuite) TestHandleRecvPacket() { + packetSeq := uint64(1) + packetTimeout := uint64(100) + + packetDataBz := []byte("invaliddata") + packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + packetCommitmentPath := channel.PacketCommitmentPath(testPort2, testChannel2, packetSeq) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) + suite.updateClient() + proofPacket, proofHeight := suite.queryProof(packetCommitmentPath) + + msg := types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + res := transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // packet membership verification failed due to invalid counterparty packet commitment + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // invalid packet data + + // test when the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.True(res.Code.IsOK(), "%v", res) // successfully executed + + // test when the source is false + source = false + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.True(res.Code.IsOK(), "%v", res) // successfully executed +} + +func TestHandlerTestSuite(t *testing.T) { + suite.Run(t, new(HandlerTestSuite)) +} diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go index 444e966b97c8..57c772e67b2f 100644 --- a/x/ibc/20-transfer/keeper/callbacks.go +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -6,36 +6,36 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // nolint: unused -func (k Keeper) onChanOpenInit( +func (k Keeper) OnChanOpenInit( ctx sdk.Context, - order channeltypes.Order, + order channel.Order, connectionHops []string, portID, channelID string, - counterparty channeltypes.Counterparty, + counterparty channel.Counterparty, version string, ) error { - if order != channeltypes.UNORDERED { - return channeltypes.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") + if order != channel.UNORDERED { + return channel.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") } // NOTE: here the capability key name defines the port ID of the counterparty if counterparty.PortID != k.boundedCapability.Name() { - return porttypes.ErrInvalidPort( + return port.ErrInvalidPort( k.codespace, - fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", portID, k.boundedCapability.Name()), - ) + fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name())) } if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") + return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -44,34 +44,33 @@ func (k Keeper) onChanOpenInit( } // nolint: unused -func (k Keeper) onChanOpenTry( +func (k Keeper) OnChanOpenTry( ctx sdk.Context, - order channeltypes.Order, + order channel.Order, connectionHops []string, portID, channelID string, - counterparty channeltypes.Counterparty, + counterparty channel.Counterparty, version string, counterpartyVersion string, ) error { - if order != channeltypes.UNORDERED { - return channeltypes.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") + if order != channel.UNORDERED { + return channel.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") } // NOTE: here the capability key name defines the port ID of the counterparty if counterparty.PortID != k.boundedCapability.Name() { - return porttypes.ErrInvalidPort( + return port.ErrInvalidPort( k.codespace, - fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", portID, k.boundedCapability.Name()), - ) + fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name())) } if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") + return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") } if strings.TrimSpace(counterpartyVersion) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "counterparty version cannot be blank") + return ibctypes.ErrInvalidVersion(k.codespace, "counterparty version must be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -80,21 +79,21 @@ func (k Keeper) onChanOpenTry( } // nolint: unused -func (k Keeper) onChanOpenAck( +func (k Keeper) OnChanOpenAck( ctx sdk.Context, portID, channelID string, version string, ) error { if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") + return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") } return nil } // nolint: unused -func (k Keeper) onChanOpenConfirm( +func (k Keeper) OnChanOpenConfirm( ctx sdk.Context, portID, channelID string, @@ -104,7 +103,7 @@ func (k Keeper) onChanOpenConfirm( } // nolint: unused -func (k Keeper) onChanCloseInit( +func (k Keeper) OnChanCloseInit( ctx sdk.Context, portID, channelID string, @@ -114,7 +113,7 @@ func (k Keeper) onChanCloseInit( } // nolint: unused -func (k Keeper) onChanCloseConfirm( +func (k Keeper) OnChanCloseConfirm( ctx sdk.Context, portID, channelID string, @@ -125,13 +124,13 @@ func (k Keeper) onChanCloseConfirm( // onRecvPacket is called when an FTTransfer packet is received // nolint: unused -func (k Keeper) onRecvPacket( +func (k Keeper) OnRecvPacket( ctx sdk.Context, - packet channeltypes.Packet, + packet channelexported.PacketI, ) error { var data types.PacketData - err := data.UnmarshalJSON(packet.GetData()) + err := k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) if err != nil { return sdkerrors.Wrap(err, "invalid packet data") } @@ -143,9 +142,9 @@ func (k Keeper) onRecvPacket( } // nolint: unused -func (k Keeper) onAcknowledgePacket( +func (k Keeper) OnAcknowledgePacket( ctx sdk.Context, - packet channeltypes.Packet, + packet channelexported.PacketI, acknowledgement []byte, ) error { // no-op @@ -153,19 +152,19 @@ func (k Keeper) onAcknowledgePacket( } // nolint: unused -func (k Keeper) onTimeoutPacket( +func (k Keeper) OnTimeoutPacket( ctx sdk.Context, - packet channeltypes.Packet, + packet channelexported.PacketI, ) error { var data types.PacketData - err := data.UnmarshalJSON(packet.GetData()) + err := k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) if err != nil { return sdkerrors.Wrap(err, "invalid packet data") } // check the denom prefix - prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourcePort()) + prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) coins := make(sdk.Coins, len(data.Amount)) for i, coin := range data.Amount { coin := coin @@ -190,6 +189,6 @@ func (k Keeper) onTimeoutPacket( } // nolint: unused -func (k Keeper) onTimeoutPacketClose(_ sdk.Context, _ channeltypes.Packet) { +func (k Keeper) OnTimeoutPacketClose(_ sdk.Context, _ channelexported.PacketI) { panic("can't happen, only unordered channels allowed") } diff --git a/x/ibc/20-transfer/keeper/callbacks_test.go b/x/ibc/20-transfer/keeper/callbacks_test.go new file mode 100644 index 000000000000..fb505cf190ac --- /dev/null +++ b/x/ibc/20-transfer/keeper/callbacks_test.go @@ -0,0 +1,168 @@ +package keeper_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +func (suite *KeeperTestSuite) TestOnChanOpenInit() { + invalidOrder := channel.ORDERED + + counterparty := channel.NewCounterparty(testPort2, testChannel2) + err := suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, invalidOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "") + suite.Error(err) // invalid channel order + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "") + suite.Error(err) // invalid counterparty port ID + + counterparty = channel.NewCounterparty(testPort1, testChannel2) + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.Error(err) // invalid version + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "") + suite.NoError(err) // successfully executed +} + +func (suite *KeeperTestSuite) TestOnChanOpenTry() { + invalidOrder := channel.ORDERED + + counterparty := channel.NewCounterparty(testPort2, testChannel2) + err := suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, invalidOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", "") + suite.Error(err) // invalid channel order + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", "") + suite.Error(err) // invalid counterparty port ID + + counterparty = channel.NewCounterparty(testPort1, testChannel2) + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion, "") + suite.Error(err) // invalid version + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", testChannelVersion) + suite.Error(err) // invalid counterparty version + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", "") + suite.NoError(err) // successfully executed +} + +func (suite *KeeperTestSuite) TestOnChanOpenAck() { + err := suite.app.IBCKeeper.TransferKeeper.OnChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion) + suite.Error(err) // invalid version + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenAck(suite.ctx, testPort1, testChannel1, "") + suite.NoError(err) // successfully executed +} + +func (suite *KeeperTestSuite) TestOnRecvPacket() { + packetSeq := uint64(1) + packetTimeout := uint64(100) + + packetDataBz := []byte("invaliddata") + packet := channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + err := suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.Error(err) // invalid packet data + + // when the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.NoError(err) // successfully executed + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(testPrefixedCoins2, totalSupply.GetTotal()) // supply should be inflated + + receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testPrefixedCoins2, receiverCoins) + + // when the source is false + source = false + + packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.Error(err) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.NoError(err) // successfully executed + + receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testCoins, receiverCoins) +} + +func (suite *KeeperTestSuite) TestOnTimeoutPacket() { + packetSeq := uint64(1) + packetTimeout := uint64(100) + + packetDataBz := []byte("invaliddata") + packet := channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + err := suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.Error(err) // invalid packet data + + // when the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.Error(err) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.NoError(err) // successfully executed + + senderCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Sender) + suite.Equal(testCoins, senderCoins) + + escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) + suite.Equal(sdk.Coins(nil), escrowCoins) + + // when the source is false + source = false + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Sender, sdk.Coins{}) + err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.NoError(err) // successfully executed + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(testPrefixedCoins1, totalSupply.GetTotal()) // supply should be inflated + + senderCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Sender) + suite.Equal(testPrefixedCoins1, senderCoins) +} diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index 77c423052098..e5023a662caf 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -1,24 +1,53 @@ package keeper_test import ( + "fmt" "testing" - "github.com/stretchr/testify/suite" - - abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/keeper" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" +) + +// define constants used for testing +const ( + testChainID = "test-chain-id" + testClient = "test-client" + testClientType = clientexported.Tendermint + + testConnection = "testconnection" + testPort1 = "bank" + testPort2 = "testportid" + testChannel1 = "firstchannel" + testChannel2 = "secondchannel" + + testChannelOrder = channel.UNORDERED + testChannelVersion = "1.0" +) + +// define variables used for testing +var ( + testAddr1 = sdk.AccAddress([]byte("testaddr1")) + testAddr2 = sdk.AccAddress([]byte("testaddr2")) + + testCoins, _ = sdk.ParseCoins("100atom") + testPrefixedCoins1, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort1, testChannel1))) + testPrefixedCoins2, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort2, testChannel2))) ) type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - keeper *keeper.Keeper + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp } func (suite *KeeperTestSuite) SetupTest() { @@ -27,7 +56,21 @@ func (suite *KeeperTestSuite) SetupTest() { suite.cdc = app.Codec() suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) - suite.keeper = &app.IBCKeeper.TransferKeeper + suite.app = app + + suite.createClient() + suite.createConnection(connection.OPEN) +} + +func (suite *KeeperTestSuite) TestGetTransferAccount() { + expectedMaccName := types.GetModuleAccountName() + expectedMaccAddr := sdk.AccAddress(crypto.AddressHash([]byte(expectedMaccName))) + + macc := suite.app.IBCKeeper.TransferKeeper.GetTransferAccount(suite.ctx) + + suite.NotNil(macc) + suite.Equal(expectedMaccName, macc.GetName()) + suite.Equal(expectedMaccAddr, macc.GetAddress()) } func TestKeeperTestSuite(t *testing.T) { diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index dae2180dc44f..8c3a6bb2ea5b 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -7,7 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -23,18 +23,18 @@ func (k Keeper) SendTransfer( isSourceChain bool, ) error { // get the port and channel of the counterparty - channel, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) + sourceChan, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) if !found { - return channeltypes.ErrChannelNotFound(k.codespace, sourcePort, sourceChannel) + return channel.ErrChannelNotFound(k.codespace, sourcePort, sourceChannel) } - destinationPort := channel.Counterparty.PortID - destinationChannel := channel.Counterparty.ChannelID + destinationPort := sourceChan.Counterparty.PortID + destinationChannel := sourceChan.Counterparty.ChannelID // get the next sequence sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel) if !found { - return channeltypes.ErrSequenceNotFound(k.codespace, "send") + return channel.ErrSequenceNotFound(k.codespace, "send") } coins := make(sdk.Coins, len(amount)) @@ -54,13 +54,13 @@ func (k Keeper) SendTransfer( // ReceivePacket handles receiving packet func (k Keeper) ReceivePacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, height uint64) error { - _, err := k.channelKeeper.RecvPacket(ctx, packet, proof, height, nil, k.storeKey) + _, err := k.channelKeeper.RecvPacket(ctx, packet, proof, height, []byte{}, k.boundedCapability) if err != nil { return err } var data types.PacketData - err = data.UnmarshalJSON(packet.GetData()) + err = k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) if err != nil { return sdkerrors.Wrap(err, "invalid packet data") } @@ -164,20 +164,15 @@ func (k Keeper) createOutgoingPacket( } } - packetData := types.PacketData{ - Amount: amount, - Sender: sender, - Receiver: receiver, - Source: isSourceChain, - } + packetData := types.NewPacketData(amount, sender, receiver, isSourceChain) - // TODO: This should be binary-marshaled and hashed (for the commitment in the store). - packetDataBz, err := packetData.MarshalJSON() + // TODO: This should be hashed (for the commitment in the store). + packetDataBz, err := k.cdc.MarshalBinaryBare(packetData) if err != nil { return sdkerrors.Wrap(err, "invalid packet data") } - packet := channeltypes.NewPacket( + packet := channel.NewPacket( seq, uint64(ctx.BlockHeight())+DefaultPacketTimeout, sourcePort, diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index e6aa98f9eacd..7546fc48a98c 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -1,6 +1,281 @@ package keeper_test +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/cosmos/cosmos-sdk/x/supply" + abci "github.com/tendermint/tendermint/abci/types" +) + +func (suite *KeeperTestSuite) createClient() { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + suite.NoError(err) +} + +func (suite *KeeperTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) +} + +func (suite *KeeperTestSuite) createConnection(state connection.State) { + connection := connection.ConnectionEnd{ + State: state, + ClientID: testClient, + Counterparty: connection.Counterparty{ + ClientID: testClient, + ConnectionID: testConnection, + Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + }, + Versions: connection.GetCompatibleVersions(), + } + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) +} + +func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channel.State) { + ch := channel.Channel{ + State: state, + Ordering: testChannelOrder, + Counterparty: channel.Counterparty{ + PortID: counterpartyPort, + ChannelID: counterpartyChan, + }, + ConnectionHops: []string{connID}, + Version: testChannelVersion, + } + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) +} + +func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + func (suite *KeeperTestSuite) TestSendTransfer() { - err := suite.keeper.SendTransfer(suite.ctx, "", "", nil, nil, nil, true) - suite.Error(err) + // test the situation where the source is true + isSourceChain := true + + err := suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + suite.Error(err) // channel does not exist + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + suite.Error(err) // next send sequence not found + + nextSeqSend := uint64(1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + suite.Error(err) // sender has insufficient coins + + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + suite.NoError(err) // successfully executed + + senderCoins := suite.app.BankKeeper.GetCoins(suite.ctx, testAddr1) + suite.Equal(sdk.Coins(nil), senderCoins) + + escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, types.GetEscrowAddress(testPort1, testChannel1)) + suite.Equal(testCoins, escrowCoins) + + newNextSeqSend, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(nextSeqSend+1, newNextSeqSend) + + packetCommitment := suite.app.IBCKeeper.ChannelKeeper.GetPacketCommitment(suite.ctx, testPort1, testChannel1, nextSeqSend) + suite.NotNil(packetCommitment) + + // test the situation where the source is false + isSourceChain = false + + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, isSourceChain) + suite.Error(err) // incorrect denom prefix + + suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, isSourceChain) + suite.NoError(err) // successfully executed + + senderCoins = suite.app.BankKeeper.GetCoins(suite.ctx, testAddr1) + suite.Equal(sdk.Coins(nil), senderCoins) + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(sdk.Coins(nil), totalSupply.GetTotal()) // supply should be deflated +} + +func (suite *KeeperTestSuite) TestReceiveTransfer() { + // test the situation where the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + err := suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.Error(err) // incorrect denom prefix + + packetData.Amount = testPrefixedCoins2 + err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.NoError(err) // successfully executed + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(testPrefixedCoins2, totalSupply.GetTotal()) // supply should be inflated + + receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testPrefixedCoins2, receiverCoins) + + // test the situation where the source is false + packetData.Source = false + + packetData.Amount = testPrefixedCoins2 + err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.Error(err) // incorrect denom prefix + + packetData.Amount = testPrefixedCoins1 + err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.Error(err) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) + err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.NoError(err) // successfully executed + + escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) + suite.Equal(sdk.Coins(nil), escrowCoins) + + receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testCoins, receiverCoins) +} + +func (suite *KeeperTestSuite) TestReceivePacket() { + packetSeq := uint64(1) + packetTimeout := uint64(100) + + packetDataBz := []byte("invaliddata") + packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort2, testChannel1, packetDataBz) + packetCommitmentPath := channel.PacketCommitmentPath(testPort2, testChannel2, packetSeq) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) + suite.updateClient() + proofPacket, proofHeight := suite.queryProof(packetCommitmentPath) + + suite.createChannel(testPort2, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + err := suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // invalid port id + + packet.DestinationPort = testPort1 + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // packet membership verification failed due to invalid counterparty packet commitment + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // invalid packet data + + // test the situation where the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.NoError(err) // successfully executed + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(testPrefixedCoins1, totalSupply.GetTotal()) // supply should be inflated + + receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testPrefixedCoins1, receiverCoins) + + // test the situation where the source is false + source = false + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.NoError(err) // successfully executed + + receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testCoins, receiverCoins) + + escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) + suite.Equal(sdk.Coins(nil), escrowCoins) } diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index d0e7d9fbbe72..2a353de56cff 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -45,18 +45,18 @@ func (MsgTransfer) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgTransfer) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.SourcePort); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.SourcePort); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.SourceChannel); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.SourceChannel); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source channel ID")) } - if !msg.Amount.IsValid() { - return sdk.ErrInvalidCoins("transfer amount is invalid") - } if !msg.Amount.IsAllPositive() { return sdk.ErrInsufficientCoins("transfer amount must be positive") } + if !msg.Amount.IsValid() { + return sdk.ErrInvalidCoins("transfer amount is invalid") + } if msg.Sender.Empty() { return sdk.ErrInvalidAddress("missing sender address") } diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go new file mode 100644 index 000000000000..f0b500b10d2f --- /dev/null +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -0,0 +1,189 @@ +package types + +import ( + "fmt" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/merkle" +) + +// define constants used for testing +const ( + invalidPort = "invalidport1" + invalidShortPort = "p" + invalidLongPort = "invalidlongportinvalidlongport" + + invalidChannel = "invalidchannel1" + invalidShortChannel = "invalidch" + invalidLongChannel = "invalidlongchannelinvalidlongchannel" +) + +// define variables used for testing +var ( + packet = channel.NewPacket(1, 100, "testportid", "testchannel", "testcpport", "testcpchannel", []byte("testdata")) + invalidPacket = channel.NewPacket(0, 100, "testportid", "testchannel", "testcpport", "testcpchannel", []byte{}) + + proof = commitment.Proof{Proof: &merkle.Proof{}} + emptyProof = commitment.Proof{Proof: nil} + proofs = []commitment.Proof{proof} + invalidProofs1 = []commitment.Proof{} + invalidProofs2 = []commitment.Proof{emptyProof} + + addr1 = sdk.AccAddress("testaddr1") + addr2 = sdk.AccAddress("testaddr2") + emptyAddr sdk.AccAddress + + coins, _ = sdk.ParseCoins("100atom") + invalidDenomCoins = sdk.Coins{sdk.Coin{Denom: "ato-m", Amount: sdk.NewInt(100)}} + negativeCoins = sdk.Coins{sdk.Coin{Denom: "atom", Amount: sdk.NewInt(100)}, sdk.Coin{Denom: "atoms", Amount: sdk.NewInt(-100)}} +) + +// TestMsgTransferRoute tests Route for MsgTransfer +func TestMsgTransferRoute(t *testing.T) { + msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + + require.Equal(t, ibctypes.RouterKey, msg.Route()) +} + +// TestMsgTransferType tests Type for MsgTransfer +func TestMsgTransferType(t *testing.T) { + msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + + require.Equal(t, "transfer", msg.Type()) +} + +// TestMsgTransferValidation tests ValidateBasic for MsgTransfer +func TestMsgTransferValidation(t *testing.T) { + testMsgs := []MsgTransfer{ + NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true), // valid msg + NewMsgTransfer(invalidShortPort, "testchannel", coins, addr1, addr2, true), // too short port id + NewMsgTransfer(invalidLongPort, "testchannel", coins, addr1, addr2, true), // too long port id + NewMsgTransfer(invalidPort, "testchannel", coins, addr1, addr2, true), // port id contains non-alpha + NewMsgTransfer("testportid", invalidShortChannel, coins, addr1, addr2, true), // too short channel id + NewMsgTransfer("testportid", invalidLongChannel, coins, addr1, addr2, false), // too long channel id + NewMsgTransfer("testportid", invalidChannel, coins, addr1, addr2, false), // channel id contains non-alpha + NewMsgTransfer("testportid", "testchannel", invalidDenomCoins, addr1, addr2, false), // invalid amount + NewMsgTransfer("testportid", "testchannel", negativeCoins, addr1, addr2, false), // amount contains negative coin + NewMsgTransfer("testportid", "testchannel", coins, emptyAddr, addr2, false), // missing sender address + NewMsgTransfer("testportid", "testchannel", coins, addr1, emptyAddr, false), // missing recipient address + NewMsgTransfer("testportid", "testchannel", sdk.Coins{}, addr1, addr2, false), // not possitive coin + } + + testCases := []struct { + msg MsgTransfer + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "invalid amount"}, + {testMsgs[8], false, "amount contains negative coin"}, + {testMsgs[9], false, "missing sender address"}, + {testMsgs[10], false, "missing recipient address"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "Msg %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgTransferGetSignBytes tests GetSignBytes for MsgTransfer +func TestMsgTransferGetSignBytes(t *testing.T) { + msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + res := msg.GetSignBytes() + + expected := `{"type":"ibc/transfer/MsgTransfer","value":{"amount":[{"amount":"100","denom":"atom"}],"receiver":"cosmos1w3jhxarpv3j8yvs7f9y7g","sender":"cosmos1w3jhxarpv3j8yvg4ufs4x","source":true,"source_channel":"testchannel","source_port":"testportid"}}` + require.Equal(t, expected, string(res)) +} + +// TestMsgTransferGetSigners tests GetSigners for MsgTransfer +func TestMsgTransferGetSigners(t *testing.T) { + msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + res := msg.GetSigners() + + expected := "[746573746164647231]" + require.Equal(t, expected, fmt.Sprintf("%v", res)) +} + +// TestMsgRecvPacketRoute tests Route for MsgRecvPacket +func TestMsgRecvPacketRoute(t *testing.T) { + msg := NewMsgRecvPacket(packet, proofs, 1, addr1) + + require.Equal(t, ibctypes.RouterKey, msg.Route()) +} + +// TestMsgRecvPacketType tests Type for MsgRecvPacket +func TestMsgRecvPacketType(t *testing.T) { + msg := NewMsgRecvPacket(packet, proofs, 1, addr1) + + require.Equal(t, "recv_packet", msg.Type()) +} + +// TestMsgRecvPacketValidation tests ValidateBasic for MsgRecvPacket +func TestMsgRecvPacketValidation(t *testing.T) { + testMsgs := []MsgRecvPacket{ + NewMsgRecvPacket(packet, proofs, 1, addr1), // valid msg + NewMsgRecvPacket(packet, proofs, 0, addr1), // proof height is zero + NewMsgRecvPacket(packet, nil, 1, addr1), // missing proofs + NewMsgRecvPacket(packet, invalidProofs1, 1, addr1), // missing proofs + NewMsgRecvPacket(packet, invalidProofs2, 1, addr1), // proofs contain empty proof + NewMsgRecvPacket(packet, proofs, 1, emptyAddr), // missing signer address + NewMsgRecvPacket(invalidPacket, proofs, 1, addr1), // invalid packet + } + + testCases := []struct { + msg MsgRecvPacket + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "proof height is zero"}, + {testMsgs[2], false, "missing proofs"}, + {testMsgs[3], false, "missing proofs"}, + {testMsgs[4], false, "proofs contain empty proof"}, + {testMsgs[5], false, "missing signer address"}, + {testMsgs[6], false, "invalid packet"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "Msg %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgRecvPacketGetSignBytes tests GetSignBytes for MsgRecvPacket +func TestMsgRecvPacketGetSignBytes(t *testing.T) { + msg := NewMsgRecvPacket(packet, proofs, 1, addr1) + res := msg.GetSignBytes() + + expected := `{"type":"ibc/transfer/MsgRecvPacket","value":{"height":"1","packet":{"type":"ibc/channel/Packet","value":{"data":"dGVzdGRhdGE=","destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid","timeout":"100"}},"proofs":[{"proof":{"ops":[]}}],"signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}}` + require.Equal(t, expected, string(res)) +} + +// TestMsgRecvPacketGetSigners tests GetSigners for MsgRecvPacket +func TestMsgRecvPacketGetSigners(t *testing.T) { + msg := NewMsgRecvPacket(packet, proofs, 1, addr1) + res := msg.GetSigners() + + expected := "[746573746164647231]" + require.Equal(t, expected, fmt.Sprintf("%v", res)) +} diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go index a9df673cc19f..f7c79b9be07e 100644 --- a/x/ibc/20-transfer/types/packet.go +++ b/x/ibc/20-transfer/types/packet.go @@ -1,7 +1,6 @@ package types import ( - "encoding/json" "fmt" sdk "github.com/cosmos/cosmos-sdk/types" @@ -15,28 +14,14 @@ type PacketData struct { Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred } -func (pd PacketData) MarshalAmino() ([]byte, error) { - return ModuleCdc.MarshalBinaryBare(pd) -} - -func (pd *PacketData) UnmarshalAmino(bz []byte) (err error) { - return ModuleCdc.UnmarshalBinaryBare(bz, pd) -} - -func (pd PacketData) Marshal() []byte { - return ModuleCdc.MustMarshalBinaryBare(pd) -} - -type PacketDataAlias PacketData - -// MarshalJSON implements the json.Marshaler interface. -func (pd PacketData) MarshalJSON() ([]byte, error) { - return json.Marshal((PacketDataAlias)(pd)) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (pd *PacketData) UnmarshalJSON(bz []byte) (err error) { - return json.Unmarshal(bz, (*PacketDataAlias)(pd)) +// NewPacketData contructs a new PacketData +func NewPacketData(amount sdk.Coins, sender, receiver sdk.AccAddress, source bool) PacketData { + return PacketData{ + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, + } } func (pd PacketData) String() string { @@ -54,12 +39,12 @@ func (pd PacketData) String() string { // ValidateBasic performs a basic check of the packet fields func (pd PacketData) ValidateBasic() sdk.Error { - if !pd.Amount.IsValid() { - return sdk.ErrInvalidCoins("transfer amount is invalid") - } if !pd.Amount.IsAllPositive() { return sdk.ErrInsufficientCoins("transfer amount must be positive") } + if !pd.Amount.IsValid() { + return sdk.ErrInvalidCoins("transfer amount is invalid") + } if pd.Sender.Empty() { return sdk.ErrInvalidAddress("missing sender address") } diff --git a/x/ibc/20-transfer/types/packet_test.go b/x/ibc/20-transfer/types/packet_test.go new file mode 100644 index 000000000000..8471fb0cf2da --- /dev/null +++ b/x/ibc/20-transfer/types/packet_test.go @@ -0,0 +1,39 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// TestPacketDataValidation tests ValidateBasic for PacketData +func TestPacketDataValidation(t *testing.T) { + testPacketData := []PacketData{ + NewPacketData(coins, addr1, addr2, true), // valid msg + NewPacketData(invalidDenomCoins, addr1, addr2, true), // invalid amount + NewPacketData(negativeCoins, addr1, addr2, false), // amount contains negative coin + NewPacketData(coins, emptyAddr, addr2, false), // missing sender address + NewPacketData(coins, addr1, emptyAddr, false), // missing recipient address + } + + testCases := []struct { + packetData PacketData + expPass bool + errMsg string + }{ + {testPacketData[0], true, ""}, + {testPacketData[1], false, "invalid amount"}, + {testPacketData[2], false, "amount contains negative coin"}, + {testPacketData[3], false, "missing sender address"}, + {testPacketData[4], false, "missing recipient address"}, + } + + for i, tc := range testCases { + err := tc.packetData.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "PacketData %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid PacketData %d passed: %s", i, tc.errMsg) + } + } +} From 321463f3692f0bd468bcb6fa6f12aa4a820de92c Mon Sep 17 00:00:00 2001 From: vincent Date: Mon, 2 Dec 2019 16:44:55 +0800 Subject: [PATCH 018/176] Add IBC REST endpoints (#5310) * add rest framework * add rest endpoints for ibc connection * add rest endpoints for ibc client * add rest endpoints for ibc channel * modify ibc rest api * add rest endpoints for ibc transfer * fix query route * fix receive packet * fix query client state api * use sub module name instead of icsxx * use const for prove judgement * modify ibc rest api * add api docs to swagger * add ibc config * fix proof path in swagger * return query result proof * update swagger docs * parse prove * clean up * fix ibc rest api and swagger docs * fix host validate * fix typo * add submitMisbehaviour error response in swagger * fix rest queryRoot and swagger doc * add response comments for each REST functions * fix rest function comments --- client/lcd/statik/statik.go | 2 +- client/lcd/swagger-ui/swagger.yaml | 1199 +++++++++++++++++++- types/rest/rest.go | 11 + x/ibc/02-client/client/rest/query.go | 248 ++++ x/ibc/02-client/client/rest/rest.go | 39 + x/ibc/02-client/client/rest/swagger.go | 61 + x/ibc/02-client/client/rest/tx.go | 164 +++ x/ibc/02-client/module.go | 5 +- x/ibc/03-connection/client/rest/query.go | 102 ++ x/ibc/03-connection/client/rest/rest.go | 62 + x/ibc/03-connection/client/rest/swagger.go | 46 + x/ibc/03-connection/client/rest/tx.go | 204 ++++ x/ibc/03-connection/module.go | 8 + x/ibc/04-channel/client/rest/query.go | 63 + x/ibc/04-channel/client/rest/rest.go | 75 ++ x/ibc/04-channel/client/rest/swagger.go | 55 + x/ibc/04-channel/client/rest/tx.go | 336 ++++++ x/ibc/04-channel/module.go | 8 + x/ibc/04-channel/types/msgs.go | 20 +- x/ibc/20-transfer/client/rest/query.go | 60 + x/ibc/20-transfer/client/rest/rest.go | 38 + x/ibc/20-transfer/client/rest/swagger.go | 27 + x/ibc/20-transfer/client/rest/tx.go | 118 ++ x/ibc/20-transfer/module.go | 8 + x/ibc/client/rest/rest.go | 19 + x/ibc/module.go | 41 +- 26 files changed, 2985 insertions(+), 34 deletions(-) create mode 100644 x/ibc/02-client/client/rest/query.go create mode 100644 x/ibc/02-client/client/rest/rest.go create mode 100644 x/ibc/02-client/client/rest/swagger.go create mode 100644 x/ibc/02-client/client/rest/tx.go create mode 100644 x/ibc/03-connection/client/rest/query.go create mode 100644 x/ibc/03-connection/client/rest/rest.go create mode 100644 x/ibc/03-connection/client/rest/swagger.go create mode 100644 x/ibc/03-connection/client/rest/tx.go create mode 100644 x/ibc/04-channel/client/rest/query.go create mode 100644 x/ibc/04-channel/client/rest/rest.go create mode 100644 x/ibc/04-channel/client/rest/swagger.go create mode 100644 x/ibc/04-channel/client/rest/tx.go create mode 100644 x/ibc/20-transfer/client/rest/query.go create mode 100644 x/ibc/20-transfer/client/rest/rest.go create mode 100644 x/ibc/20-transfer/client/rest/swagger.go create mode 100644 x/ibc/20-transfer/client/rest/tx.go create mode 100644 x/ibc/client/rest/rest.go diff --git a/client/lcd/statik/statik.go b/client/lcd/statik/statik.go index 48a9278324ee..0639033f1870 100644 --- a/client/lcd/statik/statik.go +++ b/client/lcd/statik/statik.go @@ -8,6 +8,6 @@ import ( ) func init() { - data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00 \x00favicon-16x16.pngUT\x05\x00\x01\x80Cm8\x00\xbd\x01B\xfe\x89PNG\x0d\n\x1a\n\x00\x00\x00\x0dIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x01\x84IDATx\x01\x95S\x03Luq\x1c\xfd\x8c\xf1\xc3\xec0\xa7)\xcda\xb6k6\xb2\x9b\xf9\xb2k\xc85/\xdb\x8dqx\xc6\x94m\xcc{\xef\x7fO\xff\xf3l\xdc\xed\xf2\xe0\xfe\xf8\xc9\xffP\x14\x11/\x14[\xa3P\xc4\xa1\xbc?\xf1t>7\x12s\x13\x03\x85\xca7IR a\xb5j\x8f\xa71\xbe]\x88\xf6\xb9L\xf0\x1c\x93\xcf\xda\xe3)\x10\x93f\x8d\xe4\x06\x13\xcf\xde<\x9b\xd14\x95\x8a\x92\x81OA\xcfF\x89\xdd<\x9b M\xe6}L\xe4\x07\x15\xc5\xf5\xe3\xffI\x0c{\xd6\x8d\xffs\x994\xbasfh\xae?\xafk\x1aprw\x10 <\xb9\xdb\xc7\x86\xa6\xd1\x19I\n\xa8\xb1\xd7\x84y3g\x171T$\xb5c\x7fq\xfbbq\xbfk\x8e'\x1dQ\xb0\xc2,\x92\x0bx|;F\xe5\xf0\xef\x00\x83\xf2\xa1\x1fx|?q\xbd\xcb\xc2\x16\x80ZF\xf0\xc4J\xf3\xe3\xe4n1\xcc\x17k`:}\xcby\xe8\x98\xcbB\xc7|6z\x97r\xd14\x9d\x06\xd3\xf9\x8a\xe4\x94\x90\x8b\xb6\xd9\x0cP\xebc@\xd0|\xbe*\xc94\xc8\xa7\x98'\xcdh\x00\xe3\xd92\xa6vK}\x0cB\xa4\xf0+D\n\xc7\x81)\xb0\x10\x9a\xe3\xa9\xd8\x8bx\xe4(\xa2\xbb\x8dl\x0d\x01\xb6\x8a-\xf378\xbe\xdd\xc7\xa6\xb6\xc9\xd9\xc6d\xd8\\m\xf4\x0c\x92 uQ\x0e\xd2\xf5\xb3\xd1\xf1w\xdfQ\x16\xb34a$\xa1\xc4\xc4(V\xbcF\xd9\xdf\xa4\x91\xe9\xb0&,\x12+\xcd\x93\xcf\x1c\x1cb\xdc\xca\x00qt\xeb\xcc-\x14\x89\xfe\xfc\x0fm2j\x88\xec\xccs\x18\x00\x00\x00\x00IEND\xaeB`\x82\x01\x00\x00\xff\xffPK\x07\x08\xd4`4t\xc7\x01\x00\x00\xbd\x01\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00 \x00favicon-32x32.pngUT\x05\x00\x01\x80Cm8\x00u\x04\x8a\xfb\x89PNG\x0d\n\x1a\n\x00\x00\x00\x0dIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\x00\x00\x04|ID\xc4\xcf\xd0@\x04&%\xad\x1e\x16\x0f\xf7\x8d\x97AR\xfa\xca\xe7l\x87\x05\xf8\xd2\xfb\x0c\x84\x1d\x0dLVY\xdc/ju\x13\x1a\x88\xd2\xa0\xaaa\x82|nzp_\xf4\x03\xc8 \xd4;^\x8a9}\xeeu\x9a\x91 `\x04\x14s\xec\xe1\x0c\xc6]\xa3\x05``\xd1w\x12*~ \x00\xf3\xae\xd3\xa0\x9cb\x82\xa2bx(\xb3n\x1fqx\xd2\xf2\xda4\x1d\x8a}\x1ck\xd4>\x9cI+\xeb\xb3\xf4k\xc8u`L\x93\xf3]4\xb5\xd0\xc3\xe33\xd9\xee\xd7\xf2\xd9\x19\xea\x18\xc9\xc1Y:\x18\xfb(-\xadN\x82\x06e\xd5\x1f0\xa2\x1dV\xf8\xbe0\xc1\x985\x01\xf8\xd2~\\\xa6\xa5\xb5)&\xf6\x98V\x80l\xe4\x03\xf8\x03\x04\x00s\x9a^\xec\x85\x00\xf4+\x0b\x00\xe1:G\xf2p\x96\x0e\xc4,\xe46\x1e5\xbbP\xdd\x15J\x80}\xce\xa4\xe2\xc8{m\xa4\xe2\xc3\xc2\x01\x07\xc0\xdb\xa4\x18-\xa1\x931\xba\x10S\xfa%\xb6P`\x10\x19v\x99#|Gg\x9b \x10W\xf6\x8dI1\xba\x92\xd66\x17E\x12\xfa\xd9\xa8\xf3UTe\n\x1b\x95\x9d\x81f\xe5\x18\xa5umc\x81\x86\xa6\xeb\xec \x804\xcbg\x17\xa19\xfa\xc6\xf7<\xa3\xbd\xf2\x0e\x7f\x02\x80\x97Y\xc7\xac\x184$h\xa3v\xba! \xcc{\xcd\xb4!\xb1\xd8\x92%h\xe3\x93\xdc\xd3_\xda1\xe6\xaei\xcf\x83\xa6p\xbc$\xf0\xb2\xda\x94\xa2q\x14B@\x13\xdb\xff\xf3\xd7\x0d\xfaA\xb9\xc5n{\x8e\xd6Y\x08\x01u\xc1'~\x16\x8e\xe9\x04\xa2\xfbA+\xc74\x0c\x98\xab\xd7:\xfc0\xd1v\xaf$\xa2#\xb7\xf1\x08\xfdm!OXh8\x10j|g\xd1\xe0a\xb2\x99\x04\x9a[y\x9a\xbdk\xf24C$\xa0\x9e#\x9f\xa3\xa8\x001\xc6\x1a\"\xc0\xe4i\xa6\xcc0\xf3\xf7\xb7\xf5XE\xb8\xe0\xa1\xc9\xc2\x0c\x90\x83\x80$\x838\xdf\xd6\xe3\xd4\x82FNG\x0f\x876\x8a\xbf1\xa8d(\xa7@\x8cQX\x90\xdb\x19\x9f\xc5YG\xe9\x9e\x00\xa5y3]\x9aJ\xe1\"\x00\x00\x00\x00IEND\xaeB`\x82\x01\x00\x00\xff\xffPK\x07\x086B\xc8\xd7\x7f\x04\x00\x00u\x04\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00 \x00index.htmlUT\x05\x00\x01\x80Cm8\x9cT]k\xdc:\x10}\xdf_1Q\x1e\x92\\\"\xfb&\x81p\xf1\xb5\xfd\x90\xa6\xa5\x81\x94\x06\x92}(\xa5\x14\xd9\x1a{\xa7\x91\xa5E\x92\xf7#!\xff\xbdX\xf6\xae\xb7\xdd\x90BYX\x8f\xe7\x9c9\x1a\x1d\x8d\x9c\x1ep\x0e\x1f\x1f>\xddBe,8/<\x95 \xc9yKE\xeb\xc9h(Z-\x15B\xd1\x92\x92\xc0y>I\x0f\xae?\xbf{\xf8r\xf7\x1ef\xbeQ\xf9$\xed\x1e\xa0\x84\xae3\x86\x9a\xe5\x13\x80t\x86Bv\x01@\xda\xa0\x17P\xce\x84u\xe836}\xf8\xc0\xffc\x03\xe4\xc9+\xcc\xef\x97\xa2\xae\xd1\xc2\xf4&\x8d\xfbL\x8f*\xd2\x8f`Qe\xcc\xf9\xb5B7C\xf4\x0c\xfcz\x8e\x19\xf3\xb8\xf2q\xe9\x1c\x83\x99\xc5*c\xae\xd7\xe0-E!\xbb'A\xa5\xd1\x9bbjD\x8d\xf1\\\xd7\x9b\xeaJ,:\x9c_\x9c\xaf.\xce\xa3\x008zB\x97\xb1\x90a\x10\xff\x9d\xde\xd9\xe5\xea\xec\xf2\x17\xbd\x90\x19\xf5\xc2\xc6\xfa\x18\x82\x9bC\xf8<<\x01\n\xb3\xe2\x8e\x9eH\xd7 \x14\xc6J\xb4\xbc0\xab\xff\xb7\xb8Y\xa0\xad\x94Y&\xc0\x1b\xf3\xc4]i\x8dR\x85\xb0\x8e/\xd0z*\x85\xda\xe7\xf2u\x02=q\x83\xbdL\x86\xe0\x9f\xd3M\x90\x14X\x19\x8b\xe3\xbb\xa8<\xda7\xfb#=CK~O\xb40r\xbdW\xd8\x08[\x93N\xfe\x1d\xdb+D\xf9X[\xd3j\x99\xc0a%\xba\xdf(\xd5\xfd\xa7\xf1\xd6\xaf4\xee'\xac\x0b;\xf9\xc1OI\x0b \xb9;\x0e,OcI\x8b|2\x18^Z\x9a{p\xb6\xdc%\xf1~\xc6\xa3\x1f\x8e\xe5\xdd*\x81\x94\xbfY\xe1\xbc\xd0R(\xa3\x91\xcf-:\xf4o\x14\xf7/K\xd2\xd2,#\xa3\x95\x11\x122\xa8Z]v\x17\xec\xf8\x04\x9e7N\xc51\\\x85{&\xc0\xad\x9d\xc7f\xc8\x97F;\x0f-A\x06\xc3m\x99\xde\\\x85\x9e\x8fGG[\xab\x12`Q\xeb\x8c\xd8v\xfb_}K7\xd3F\xfe]\xb1\xa1\x82h%q{\x8b\x9b6\x88/\xc4i }\xc07u~}\xe5\xad\xfd\xc9\x98\xe7q\xd8_}o\xf1\x92%\x9dx\x15\x9f\xd3yO\xbdX]\x1aA\xc9>t\xd6o\x93\xd3\x92\xf2\x04l\xc5\x8d\x92jz\xc1jN\xd6\xf2\xa9\x87\xfa\xb5]\x05\xcc\xf9\x1acB\xa9,\x9f\xd0\x08\x05\xb7\x962\xec\xdb\xb6\xe2\x16b\xc6\xd5\x942H\x05KfI\x06\x7f\x9c\x98\xa8\xc0\xd5\x9c\xa2\x0c\x13\xa3\xe7U\x8e\xb55;'Nk\xe6\xd0\x9d;\xd4%^\x14\xbd\xd5\xf7\x92QN\x8e.\x1c`\x079m\xe3\x9e\x8a\xfe\xed\xa2\xad\xe0y>\xe6\xe23\xdc\xf8u\xa7=\xa3\xf6\xa1\x98\xb4\x17g\xa9\xf4\x1dA\xa8Z\xe4\xf6\x88_\xfc)\xf8\xd5N\xcf,\xea\xb4\xabS\xf2\xd2\xe0v\x10\x90\x82\xbd\xb3\xe1\xc1g\xc8>\x120\x0c{\x1d\xbd\x1c\xd1\x7fd\xb4\xbf\x82|\xf7\x9f\xd0\xa7\x1e\x82\xc5`H\xc0\x94F3p0$H.\x0f]v3\xaa\x9b\x1c\x83EW}\xba4\x12O`_\xb5!H5\xd1 \x9a\x0c\xaa\xcd\x04\x8cE\xe7M:\xe1\x08\xfe\xefQ\xab\x02\xfe\xb7A\xeb\xb6k\xbb\x05{\xef\x8e\xde\x84\xcb\x9c\xb2\x8f\x04\xd7U\xf9\x9aQ:\xbe\xf51\xf1\x1a\xaaW\x97uR\xdd\xe7\xf59\x974\xb7\xfc5s\xd0\xc4P\xdf\xdd\"\xd7\x96\xc2\xdab7x\xb8;\xfc\x01\xfa'\x00\x00\xff\xffPK\x07\x08]\x12r 9\x03\x00\x00T \x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00 \x00swagger-ui-bundle.jsUT\x05\x00\x01\x80Cm8\xec\xfdyw\xdb6\xf68\x8c\xff\xffy\x15\xd7\xfa\xf6\x9b!kZ\xb1\x9d\xa5\xad\x13\xc5\x93\xc5m\xb3g\xe2\xa4\xcb\xa8\x1a\x1fZ\x82,6\x14\xa8\x90\x90m\xb5\xf2\xef\xb5\xff\x0e.\x00\x12$\x01\x10r\xdc\x99\xf9<\xcf\xc3s\xdaX\\\xb0\\\\\\\xdc\xfdn\xc1tI\xc7,\xc9h@\"`!\xfc\xf9?\x00\x00\xbd\xec\xf4w2f=\x18\x0c\x80\xad\x16$\x9b\x02\xb9\\d9+\xe0\xd6-\xd3\xd3y6Y\xa6\x04\x0e\xe5\x1f}\xf5\xf6\x00X\x10\xc2\x01\xf4T7\xfaG\x132M(\xe1-\x8a\xbf\xfa\xf1|\x02\x87\xf2G0\x1c\xe1\x80\x0e\\\x839T\x7f\xf5\x8f/\xe2\xb33\x92\x7f|\xfedI'));&\xe6'\xffs\x15\xb0YRD\xd5\xf4\xd5\xd4s\xc2\x969\xd5\xc0\xa2\x1e\xf0\xeb<\xce\x81\xc1\x00\xfe\xbcz\xf0?\xe5M\xf5*\xd0 \xd7_\xe6W2\x85\x80\x0d\xf3Q\xa8\xda\xe5?\x14t\x1e\xd4^\xe5mg|t\xc3|\xc4\xbb\xa8=\xc4\xb6\x0e \x8fZw\xd3\x03\xd8\xdak\xdf\x96]\x1c\xc0\x9fW\xb5gW\xf5N\xe5\xa8\x08\x1f\xd58N\xd3 S\x83\x8b \x8b@\xfbEC\xfe3\x85\x01l\xedj\x0f\xca\xd6\xaand\x9b\xb4?\x87\x01\x90\x08h\x7f\xcc\xa7\xc5\xff\x98\xc0\xa0\x8ep\x11\xb4@F\xfb\x99\xc4\xc5\xf5\x1a\xde\xe2\xd2\xf7\x05J\xbc\xcb\xb3\x05\xc9\xd9J~\xd9\x86\xd08\xa3\xd3\xe4l\x99\xc7\xa7)\xb1\x80\x85.\xe7D=\xdfm??#\xec\x00\xf2:\xc4\xc2j\x8e|\x0e\xb46\x87\xe6\xe8\x15\x86 Z\x93\xfe\xc9 )^\xab\xbd\xd1\xc25\xfdR+\xc1\xe7\x1a/SV\x1f\x03\x1c\xf8}\xed\xb1\xd6\xb4? X\x04\xbd\xb8\xc7\x81\x1c\x01\xabO/k.Q\xb3;\xd9\x8c\\\x99E\x9e\xb1\x8c\xef\xca\xfe,.\xde^P\xb5F\x02\x9b\xf0\xfbz\xfb\x0b\x18@\xef\xf6$)X/\x02\x1a\xd0>'\x12w\xef\xde\x13\xaf]\x05\xc3\x06~P\xbd\xff\xde\xb2 P\xb0<\x19\xb3^59\x9d\xdc\xd0\xe0\x1b\xd5T\xd4D\xb5ZS\xf5\x8f\xbe\xbdw'\x0c\xbc\xbe3\x0f\x81\xe9+-\xb6\x08S+\xd9\x05PN#\xb6\x02\x02 -XL\xc7\x9c\xbe\xb10\x046\xcb\xb3\x0b\xa0\xe4\x02>\xac\x16\xe4(\xcf\xb3<\xe8=\x8d)\xcd\x18p\xe0B\x0c\xe34.\n\x88\x0b\x88\xcb\x1ezacG\xde\xcct\xaaG\x1c\xc1\xf3\x08)\x15\x0d\xf6\xef\xef\x87\xf5M\x94\xc0\x00\x82\x1c\x06\x90\x85|\x07\xe4\xf5\x1d\x90\xc3\x81\x01y%\x9cZ\x1bO\x1f\x8f\x01\x96M8\x96t\x98\x18\xc1\x8c\xafd9\x04|\x06|\x13\xef>\x00\n\x0f\x81\xf5SB\xcf\xd8\xec\x01\xd0\xedm\xd3G\xa0f\x8d\xc4\x99\x8e\x1e\x18\xdf\xc8\xfb\x15m\x81A\xfd\xe7z\xcd\x89\x11\xe4}\x9d@I4\xe9\x9d\xc7\xe9\x92\xf4 \xa1\x90s\x88\x05y\xff\"OX\xf9F\x18A\xb0\x1bA\xa2 \x10\xf2\xc9\xe5\xfdOd\xc5igk(\x0djo\xda\xb9%\x009.\x18\x08\xb0\xf6*E*\x16h\xdb\\\x1c\x04\xb9\xbc\xcf\xbf\xd6)H\xbd\xcf+\xbf\x1d\xa5\xef\xc4\xfaHJ\xc4\xa0\xc17\xf7\xef70\xadB,N\xca\xff\x9dX\x7f\xf7\xde\x7f\x0e\xe9\xad\x04\x84\xe8\x14\xe3=\x99\x92\x9c\xd0\xb1\"\x1b\x9c\xd7\x81Y\\\xd0\xbf18%\x84BB\x13\x96\xc4iR\x90 \xec@\xb1\\\x90<\x08kop\x12C&\xbd\xd0x\x86l1\x8e\xd3%c\xb65\x18@p\x9e%\x13\xd8\x85\x01\xe7\xd2\xe0\x10zK*N\xedI\x0f\x0e\x9a(\xcc\xe9\x1bg$+\xaep\xab\xe4\xed\xf8\xc7\x04\x0e\xf4s\xe9\xaf[R\x18@\x1cp\xec\xfa6l\xaci&\x1f\xdd\xb9\xfb]\xf3Q\"\x1f\xdd\xbd\x17\x86&>0n\xb3\x05\xea|6p\x05\xc4\x8d\x1e\xc4\xb6\xb9\xae\x87'\x16\x90\xdf\xba\x05t\x99\xa6\xb8\x92\xccr\xf6\x1cs,\xe1\x8ceN\x8a\x82\xcfs\xbe,\x18\x90\x84\xcdH\x0e\xa7D4\x90\xe5\xdaa\x14\x01?\xacz\xb0\xbd1v4\xd0\x8eT\x04\x88o5d@\xab\xd7\xf9\xe8k$\xca\xc8\x19\x16,_\x8eY\x96\x9b\xa0\x0d\x88\x0f\xe9\x92\x1c\x00i3\x85\xd0d\x1c\x0d\x8c%\xbf\x14\xdd6\xb3\x96\xd0fPw[/5\xc87'\xae\xf2PPk|\x88\xd3\xcfk\xc7\x01\x13\x92\xce\xc9 \xc2\xe0\xe4\x84\x1fT\x1b\xf2\x01\xb8\x1b*\xa0\xe7\xae\x83\xd6\xbc\xd5T+|\x85\x1e\xe7y\xbc\xd2x\xc3\"M\xc6D\xdb*\xa0o\x17f=\xae\xc5\xdc\xeb\x8b/\xf9\xceqNbV;\x99\xc20\xd2\xf1\xa4\xaf-9\xe7\xc7\x1b\xdb\xc8<\x14\x03C\x0f\xd5\xee\xc5}-6\xec\x8b\x80\x84^-\xe6\xce\x16\x97U\x8b\xbf\xfa\xb6\x989[,\xaa\x16_\xfa\xb6\x98t\xcf\xfa\xd6-\xd8J\xab\xa6\x7f\xf0m\xda@\n\xb5\xa6\xb7\x82-\xc1\x1c\x91\xe1t\xe4\xd7\xe0\xd2\xb7\xc1\x85g\x83\x85o\x83\x13\xcf\x06\xd3\xee\x15_\xaf\xb1[\xaf\xe6\xc6\xbe\xe3\x9b\xb5\xc6\xa7\xffbA.X7\x16d\xea\x8fD\xfcA\xfbI\xf1\x9c\x95\x9ck,\xee\xbc$+\xc2\xc5\xf5\xa5|\x81N\xc8%\xde(\xc4\x8d\xc7E\x91\x8d\x93\x98%\xe7\xfc\xa3T\xdc|\x9bOH\x8eo\x8d\xf9\x0d\xd5\x06\xef\xba_\xb5\xc0\x07\xd0?&\xfc\xbcJ\xda\xf4c\xca\x05\xc4\xbf\xff\xfd\xe4\xe4\xf9\xeb\xd7\x1f?<~\xf2\xea\xe8\xe4\xf9\x87\xa3\xf7\xf8\xc7\xc9\xdf\xff\xdekS\xd6E\xfb\x8b\x97G\xbf\x1e=\xb3\xbc>1t\xf0\xe6\xd9\xd1/\xd6\x0ff\xed\x0f\xde\xbe\x7fv\xf4\xde\xfa\xc19\x0c\xe0^\xfb\xf6\x1c\x06\xb0\x07\x0f\x1f\xc2\xb9A\xf1\x00\x03\x98\xc3\x0e\x18\x8e\x96\x15*\x9c\xda\xf7O\x8dZ\"\xa8\x8e\xb2\xad\xbd\xd6SC3'\xd7i\xc6F\xcb/\x9c\xd8J\xfa\xd8$g\xc4\xf6\"O\x92|dn\x91\xc8\xa3\xa1lp\xd7o;]\xf2\xd3\xcc\xf6\xf0\xd8q\x12q\xbee\xbd\x86\xdd\xb6\xf4W\x13*_\xc7l\xd6\x9f\xc7\x97\xfc\x90&R\xb2\x84\x1dT\xb4\xf0c\x88\xb3Tx8\x06\xa8O\x13Rh\x06\x0f\x81>\x80\x8c\x8b\x9f\xf90\x1b\xf1\xe3j\x98\xc160\x83\xac)A\x99{\xcd\xf6\xa9s94\x9e\x8c\xf4\x8b\xe4\x0f\x05S\xfcs\x80\x0cE\xc2\xe9\x02#\xc1cq\xba\xf2'^\x1d\x7f\xb2B\x12\x99P\xba\x9c\x9f\x92\xbc\xc6\x82\xba$o\x8a\xd0\x7f\xf4\xe8\x91 \xfc\xa0\x1a\xe5|&\x15\x1c,_\xa9\xbb\xfb\xdf\xdd\xfd\xee\xfe7\xfb\xdf\xdd\xc3\x19\xd2R\x05\xfb&~cn\x85/2m\xe3\xba\x0d|\x0c\x1e\xc2.\x1c\n o\x03\xab\xc9,\xe0\x00\xcec\x97\n\xaf\xc1\x14\xda\xdaxkb\xe2\x1aM\x05rm94\xe4Zs\xe8\x08\xa1\x1e\x1e\x0e`\x87\xe2\xc9^g\xce\x0d/3x\xc4\x01\xe85\xb0w\xd6\x95\x97\xa3z-G\xee\xb9a?\xf8\xb6\xc7\xfc\xda{\xed\x018}c\xc0!P\xce]\xcb\xc5\xd6\xf77\x83m \x9c\xf5n\x087\x9cC\x12\xef%\xa8di\x9d\xf4\xfa/\x8e\xdf\xcf9\x1dhS\xe6\xdf\xf9y\xd1\xbe\xfd\x06\x06\xb0\xdf\xbe\xfd\x9e\x9fR\x95tW\x19K\x8eW\xf3\xd3,\xe5\xeb(\xfe\xea\x8bM\x9d\x19\x8c \xcf\xc4I\xa7^0\x1cm\xaf`\x00\xef9\x8e<\xb3\x1d\x01\x1f\xcd4\x87\xcd\x92\xa2O\xc9%\xf3f\xc6?\xab\x95\xb2\xe8\xa8\x94\xc1\xa4Z(\xbe\x05\xf7j\xcb6\xe4\xdf;\xa8(\x1cB^\x9e!\x19\x1c \x91v\x9e\x86\x99Y\xb2\x9bd\xd4v\xe2z\xd2\xea\xef]T\xc19$\x81~\xcequJ\x9a\x96A\xfd\xe1\xe6>\xb7~\xf4ec\x9f\xb8\x19\x83\x866H\xb3\xf4!\xcexu\xf1\x93\xb9\x0be\x91\xe1C\xb5\"\x82\xd4!\x08\xa3\x85\xdf\x8c~tw'\x0e\xd3\xf7Hk\x87\xefG|\xcb\x90\xe1\xb3\x91a\x08\x0d\xb5\xcc@?\x13\xd5\xf0\xbcF\xf4\xb3\x07\x8c\xd5\xc9\xabCXp)^]\xbcpv\x81\x1a\xa0\xe6\x91\xa3\xb6cB\xd0 \xab\x84\xe8>\xcb\x8e\xc9g\xbc\xa5Z7\xb7\x0d\x1aP\x0b\"\xc5'\x93M\x18\x95X\xe4\x02\x181\xae4(M\xa9M\xbfut\xb9 cF&\x82A\x83,\x87DIE\xa27\xc8\xa6b\xcb\x15\x11\x7f\xfa \xa5\x1b\xf1\xe8\x00\xb5\\\xb6n\x8d\xab\xc8\xaf+_d\xfb\xf5\xcb\xe0\xdeg\x19\xcab\n\xe2r\x11\x96\xed\xb5 \xfdi\x9e\xcd\x8f(\xcbW\xe5\xcb\xc4w\x94/\xbfl\x94\x86\x81\x11} |\x9cR\x8aT\xb7\x96\xdec\xfb\xc19\xb6\xe0\xcb\x07\xa7F\x13\"4\x19\xdeo\x8cL\xff\xf5QSU\xb1\xec\x98\xe5 =s)\xdd\xb4\xc1\xf6\x86\xcf\xe5\x01=\xea\xd5{\x88\xe0c\xff\xe5\xd1\xaf\xc70\x80\xe7\xfc\xef\x9f\x1e\xbf\xfax\xc4\x7f\xfd\xce\x7f\x1d\xbd\xf9\xf0\xfe9\xfe|\x13\xd5\xfaOh\xc1Q\x1f\x06\xcdQe\xcb|Le\xf2\xd9\xb3M\xd3\xd8^\\\x7fQ\x11|''%\x00{|$\x7f\xf6\"\xe8]\xf5\x9cc\x1e\xc7\xe3\x19yO\x8a\x0e\xeb\xa8\xd6\xd5\x96\xe8\x0b?\xc4sOt-e\xbd\x8f\x14\x1fL\xf0\xfc\xd2\xdf\x1c\x88\x17+\xac\xef\xb3L\xc8\xb2a$\x1eI\xc1Q\xfbH\x9e-\xf2\x05\xd74\xca\xfe\xbb\xac\x18\xdaDR\"\xbdx\x04\xa3\xd8\xd2\x01\x98{\xc8\xf2\x0d\xba\x18wv\xc1\x82_#x\x11F\xf0km\xf1\x15\xbd\xf5\\\x133\xa6\xbf\x14-\xbf\xf4\xc7\xf4\x97\x0eL\x7fY\x1b`EI=\x9b6\x0d\xf1\xe5\x0d#\xfc\x90#\xfc\xa8\x8d\xf0/o\x18S\xf6\xbcz\xf8\"Liw\xc1\x82\x1f\xc4z\xfe\xe0\xbf\x9e?8\xd6\xf3\x87\x06\xe5b_\xb6\x96/\xfaI!Z\xc8\x08\xff\xa5\xb4\xb7\x1c\xbd\xa5\xba\x96\x8f_S\xe4\xbelko\xbf\x8a\xe0\x9f\x11\xfc\x12\xc1?\xdaJ\xd3\xe3\xa3\x7f\xa0\xc2\xd4&9\x12\xe2\x10\x1dOb\xe4\xca\xd0\xa3L'6\x1b\xb1\xaf\xcc\xd2\x83\xe2/\xa5q\xe9\x13Y\x15F\x1eR\x8cDr\x83\xd5PN\xf8\x07\xc2\xc7\xadF\x077\x19\x1auN>\xa9\xf4\xf3\x96\xf9\xa3\x80\xe1\xaf\xa0\xcb\xbb\xbb\x93\x86\xb3\xa8q\xef\xa9<\x0c\x86#\xaf\x8e2KG\xea,\xaa\x0c\x18\xff\xf04\xb0 7fm\xf0+\xdeZ\xf0\x95\xd4\xb5\x12\x12\x0cG\xa1_\xbbq\x07r\x08\xa3fR\x883\x0fy@\xd9\x05 \xdb\\\xf3\x93\xea\x8d\xdc\xfc\xc6\x1f\xd5\x1b\xd4\xfc\x86Q\xca9\xac\x84\x9cR\xf5d\x16*\xbfL\xd2\x19~\x8a\xe0|\x04\xfc\xb8O6\x92x6\x92Y\x97\x1d@/\xcc\xc2\xdc\x97OO\x08r74\x8b\xc2\x8d\xe4?7\xb0\xc5\x80\x1e\x06|(W\xd7k\x08)\xf1T\x97\x11\xc9\x9a\x99\x81\x9a\xd9D\xf0\xd2\xca\x91\xf0\x03\xa2\xb2l\xecE\x10\x0b3F\x0c\x0f\x07\x90<\x80\xd8\xeeF\x07r\x1cK\xde\xc6\x90r\xd1\nv \xe6\xb2\x95\xc5\xad\x0e\xd4b\x0b\xbd\x1e\x0b\x96\xc3\xbdQ\x84\x8a\xbb\xe5pw\xc4\xbf\x8c\x80\x84\xa5\xa6$\x86mh+\xe1\xa0%~\xa9K}\xd6zhU\xfb\x936\xab\x8c\x9et~Df\xfc\x17/\x93q\x85\xac\x90\x15+\xe7\x02\x0c\xc7\xc6\x8f\x81\x93\xa5P\x97r\xfe\xf0_X\x05\xfc\xedmx\x04 \x1c:\x1a\x07?u\xa7\xba\xacjOu]\xc1\x01|F\x07F.\xcaKL\x12\xe8L\x86{\x8d\x93\xa8\xfc\xa8}\xdb\x03M\xb2\xfc\x1ax2\xb5;\xb1*\xca\xa4y\x94\x0b_L\x8eR\x11XQ\x83\xe3M\xfd\x0c\xa3\xd5\xbe\x91\xba\xcf\x0c\x9bx\x19\xd0\xb0?\x8f\x17\xd5\xba\xbb\xda\x05m\xd2\x08Q\x0c\x1d\xa06\x10:Ts\x13b\x1d\xd2\xaf\xff\x81!\xa9-\xd0^t\xb4\xeaD\xd0\xeb\x99|\xcd\xf8\xd5\xeb5=\xf7\xf0;N\xd3\x17\xde*\xab\x85\xfbT1\xf0#/9\x1b\xc1\xa1\xb4 \\:\x7f\x95\x14\"\nfB\xc4\xf3_\xeb\xcf_\xc7\x0b\xa1\xbb\xf2\x1a\xce\xc4=\x1ce=\xae\xf9]\x0d\x14O\xdd\xd4\xaa\xe9\xaf\xf9Acf\xdf\x11\x1cwHe\xbe$\xb0%\xf5\xef\x0c-\xcc%Fm\xd9\x18%\xc1\x82j/\xeem\xa0\xa6\x97N\x08o\xa7V#\x06So\xb8\xb6f \xb8y\xf9f\x10\x868\xa1\x00=\x0f\xf4\xbb\x9bN\x10\xec\x93\xf4\xa7f[f\xc7Q\xd2'\x9f\x97qZ\xa0J\xde\xf4\x02\xd3^\xd8Ro\x07\xcc\x93#?\xf7Z\xf2\xee\xe5\x8d\x03\x11M\xa4\xd9\xb5+\x87\x07\xed&+o\xca\xc7\xda\xcd\xe6\xe7''\xb3\xb8\x98\xb5\x1a\xa8n\x97\xaf\xd4\x1e\xac\xd7B\x7f\xcco.\xe5\xb0\nu\xa3\x907\xc6\xea\xc6\x18=\xa5;\x90\xb2\xe9\xc1!\x0d\xd1\xf8\xdb \x1b\xe5Z\x81\x9e}\xe6\xb6\xf9H\\\xac\x06J\x88})#\x04\x1d\xe6\x8f>9'\xf9*\xe8T\xa8\xa8K\xb1B9\xda\x00\x83P\xec\x82Nv\"\xe3@\x98\x91 CNQ8/\x06\x94\xc3\x15o\xeeb\\\xa1\xed(\x00\xf4\xdf\x97\xfdq.\xc2c\x8f\xa8q\xda\x16\xa8\xe5gc\xee\xbc\xf1\xaaZ@\x0b\xcd\xd1\xd5\xbe\x88m\xda\x0d\xdbB\x90\xb4 \x0exg\x0d\x0f\xf9\xe6\xa5xK\xc7\x12\x10\xa9\x05\x81\x01$f\x08\x1b\xa17\x15\xc10\xc6/\x16 \xb6\x8frE*\xd1\xc7\x14<\xa8_\x1c\x9e\x9c\x13\xdd\xc2\xd8\xb4\x00\x9d\xa43\xfe{\x86<\x01\xe9\x9f\x11\xf4\x8a\\\x85\xfc \xbf\xab\xddB\x1cQ\x185\x95\x1ek\x06\x8a \x885V\xf1q\xaa\x11\x13\xbe\xa8\x0b/\xba7w\xd3\xbd-T4\xea\xf1bsM\x02\xe2\x1c\xbbj\xc0\x8c\x8fB\x9f\xa3\xbc\x1e\x1a\xfa\xa4\x86/\xcb\x1e\xdc\x86\xdd\xd2\x9fE\xfa\xbd\x84\x91zC}\xe8:\xd8\xfeY\x0e\xed\x9ff\xc4\xf9\xa7\xb4\x19tl5\x1b\xb4\xce:\xa0U\x8b\x8c\x11*\x02O_\xa1\x15q9\x0b\x99\x97b\xd5X\n\xad\x0d\xf3j\x9c\x91@\xbaZE\xa0\xe2\xfb\nF\x16\x10\xc3\xfb\x98\x9e\x118]\xc1n/\x8cpo\xe19\xb4\x1b\xd5W \x0d5\xe8[z\x1bv\xc3\x08i\xba\xf6\x02\xc5e\x94K\x18\x9f\x16\xe8z\xc8\xe0\xa1\xe4\xd8\xf8\xdb;T\x99pN\n\x16\xe75\xdd&\xa1\x13M\xb5y\x82C\xc3\xc1\xeaX\xa3\xa3\x07\xfe=&I\x1a\x04\x0cv8\x01\xbe\x0d\x94\x8bV!\x97\xcd7\xc3\x9d_JX\xfeb\xc6\x9d_\xbe\x0cwN\xcd\xbaD\x81/\x9aJ\xe9\xf1i\xc1\xf2x\xcc\x9a\x96 K\xb3'\xc4\xe5fz\xe1|z$\x9f\xea\x0f53\xd6\xf0\x1f#\x15`\x1a\x10\x12\xc1K\x8e\x19z\xdc\xc3\x19\xe9\x0c\x04\x82\x86\x15\x86\x93G\x94\x0f4M\xfb\xf0\x932g\x84\xa3\xb6gc\xa3\xcf\x8dL25\x7fY\xadG\xe9![S-U\x1e\xb2\x03\xc8\x85\x8b\xac\x15W\xa4\x8a\x88\x04t\xc80\xecn\x07=\xba\xb2\x11\n\x7f\xbc\xa3jgf\x1c\x15\xadT;\xf3\x9a\xac\x9fu\xc84Q\xe3\x14Z\x937\xbe\x95\x9956\x9bikJ \xaa7\xbd\\M\xa8/\xf4\xc3CbD\xf9Z\xdf\xb3\xb8p&\x02\x80\xa6\xa5S4\xdd\x08\x93o\xa9\x02\x1a\xbd|\xe9\xc6\x12\x9d\x8a\x9dU\x99\xaa\"\xc9V\xeb;-\x11;-\xe1;-{\x00\x89;\x16:\xe6\xdf\xe3bf\xb0\x03 \x1c@b\xd1\xf35vf<\x8a n\xee\xc6\xc4\xa8\xb4\xb5\n\xa3\x89\x17\xc8\xae\xb3=%\xb8\xac\xfbS\x03\xa1uw\xe6\x9d{8\xb9\x89=\xbc\xd9*(\xc8\xa1\xa65\xfb\xf7\xed\xf9\x98\xef\xf9\xd8o\x8fk\x8b8\x9cU\x87\x1c\x95\x87\x1c5\xee\x8b\xd2[\xc5c\xad\x91\xf7\x0dk\xbb\xb2&4iB\x86\x85{V\xd8\xf2SP7\xcb\x86v\x94\xb1\xe8$\x9e\x04\xd4\"\x83\x96\xbb8{\x00[\x01F\x9cKyT\x08\xa4\x18\x8b\xb7'\xb4\x10A&d\xe2\x08\xf2\xedm\xb9\xab\x1e\xd8\xa5\x91\xbc s#L+}\xf5\x8d\x025\xcb7\x86\xaaE\x9d\xf3D\xd7\x12\x8b\xed\xf2\xbd\xa5Y\xcb\nl\xbe\xd5\x98\xb6\x0e\x1dZ\x0e\\$\xe1\x8c\x8e{@,\x8dX(\xaf\x8d\x10\xe4\x12\xe5\xf3\xff\x02\x94\xaf\x0e\x15\xfd\x14)C\x08D\xca\xa2\xb6\x83\x80~\xa0\x94\xc6\xa8\x07\x1e\xcc[6LF\x11'T\xadC\xc226\xbeK\xa8\xa6%\x12\xbb\xe4A\x17\xdd\xa4.m\x12\x9a\xd8\x86\xc9H\x84C\x96c\x8b\xeb\x03;\xcdI\xfc\xa9\xbd\xa06lk\x1d[\xc6\xe5\xfd\x8f\xed\xbe\xc6\xc2Z \x9ai\xb1\x8d/\xdf\x08\xab\x8a+\x01\x8f\xaac\xb5Ka\xd8\xbdQA\xc1\x0d\x11\xa5\x02\x9eC\xb1(\x82\xf2\xe4\x1e6\xbe\xe6\xb4.+\xf67\x1f\xfa3\xbcsI\x03\xe6\xe4\xfa.v\x0dA\x1b\x0e\xa1\xf7\x9e,H\xcc`8\xea\xc1A\xf5\x0b\xbd \x98\xa6\x16\xda\x86^u\x0f\xbf\xe5wX2'\x05\xb4\x9d\x8e\xe7\xd7g\xcaML\xb8\x18\x82\x81\x01\xaf\xf5\x93\xd0q\xba\x9c\x10o.|Ft\xc5W;*\xab\xd1<\xa6,\xf0\x99Hm\xffpPYQ^\x8b\xd9\x13S\x85\x03\xa5\xad\xab\x8d\xec\x83\xb0\x13\xc3\x8e\x08\xa6k2\n\xcd\x91\xe6\xe4\x9c\xe4\xc5&n\xda\x1dp\x9d\x90\xcb\xb7\xd3\xeb\x83\x15\x0eQc\xb8\xb3\xe7\xec&\x8d\x0b\xf6\xfc\x06\xba\xaa0\xb4\xb3\xcb\xeb\x0bS*UT\xb9\xc4\x98+\xcaJ\xb0\xca\x03\xa36\\\xda<\xd1\xa8S A\xbd\xe6\xb2\xb9\x94\xb3\x11\xab\xba\x19\xb1Vl&<\x04\xaa(N\xc5\x02Q \x89\xd0\x98\xf0F]7\"~xP\xd8\x1a4\xa5\x91\xd2\x13\x0fI]\xf5\x0e\x87m\xcc\xd4\xa6z\xde\xb6\xf7s\xfa\xbe\x92\xf4}u\xc3\xf4\x1dU\xc6\x8a\xbc\x8b\x1f\x1au\x17\xda\xddm\xe8\xf5\xfb\xfd\xea.\xa1\x13\xd8\x86@\x08\x15\xeaE\xb2\xe0\xed\xc1\xe9\xaa\xf69Y\xf0\x86{!\x9e\x07\xed\x93`u\xb3'\x81\x1an\xa5\x8b\x84\xaf\xebCi\x9d\x11\xabk\x9d\x11\x8as\x08\x08\xec\xe8}\x87p[\xeb\xcf\xba?0@zW\x18\xe452!n\xf05B\x9d\xf84\xcd\x0c\xb6\x87\xc6\x90\xbd\xcf\x9d\xc6\xa1Rv\xaa\x1d.\xe8R \x02\xb2\xcb\xa7\x91\xb0\x15\xe0\x19S\xdd\x0d\xe1\xe1\xa0\xf4-]\x91`7\x82\xddP\x1eO+\x89\xdcg\x84\x05\xbaU@\x99\x0c\xf8}f\xb8\x8f k\x9f]\xab\xeb\x1c6\xe7eTemy,\xf6-\xf8\xbf:\x92\x0c\x06|.vi@d\x17p\xaf3\x94\xf6D\xb5\xd0\xb5\xf3 4\x13mp\x89\x03\xed\xc3j\xf5\x85\xe7#\x0eGB\xd4@sV7s\x16V\xd8\x8dz\xc3J$\xe0\x90\x93\xf2`k\x03S\xf8\x1a\xf3\xe0iw\xeb*G\xeaT9\xd6%\xc4\x08\x12\xa3\x06\xd1\xbcl\x19l\x8b\x11\xed\xf0\x01\xe4\xfe\x0b\xd4\x92\xd7\x8c\x00\xdc\xfc\x00\xae\x80g\x1co\x03\xa0\x969\xf9\x02\xd9\x0c\xce\x9b8\xec\x95 \x9d9\xd5!\x0d\xe8\xf3E\x7f\x84\x16\xc9\xbf\x98\x03P\xca\x17\x94\xd7c\x1f\x91kuC\x0c\xc1\x8a4\x16F\xf8}\xc8\x1fe\xb8\x1d\x9aU\xc5\x13\xfegy_\x92,\xf9 \x9eq\xe7ed\x91\x81\x8f8%*\x9d\xd3 \x89\xe0\x94\xe0\x9f\x17\xd5\x9fG\xea\xcfSRF\xf4\x887\xb5@\x1e\xf1\xbe\x0c\xf29jH0|\xa1/\x89-\xbb\x04\x9el\xc9|\x89 &v\xf6\xab\xd3\x8e\xdf\x0b\xaa$,\x11\xec\x87*\x7f\x06\xbe~\xe0\xbfk\xee\xdf\xbbw\xe7\x1e\xdc\xe2\xe7\xd9\x9a\x13s\xfb\xc6)\xdfd\xe2M;\x92\xe3^\xd9F\xb7\xbbG\x8f\x1e\xc1\xde\xfdP\xde\xe1O\x02V\xde|\xf8\x10\xf6\xee\x8b\xdc3!\xac\x9b\xce\xf8\xb6P\xa6\xe3._Il\x1en\xc1\xde\xee7w\xbe\xb9\xbb\xf7\xed\xfe]X\xc3\x9d\xfd\xfd\xbd\xfd\xfd{w\xbf\xe1O\xfc\x9c2\x9fZ:\xd2)&\xac\xd7\x8e\xe0\xeb\x92\x86Z4\xd5\xdd>\x8f\xaa\xa3\xb6\x07\xa3\xbb\xe3\xae\x9e\xb7\x9a#4Px\xc5\x18\xa8qY\xe6P\xa5=\x18\xd8}\xce\x12\xf4)\xdc\x92C\x15\x0e;\xc2\xa7\xc21P\xd0\xf0t\x17\xd66\xe7(q\xec\x8d\xe0\xbd\x80\xf5\x1b\x993\x83`:\x1cxF0\xf1\x19>\xe7T\x1c\x1b\xe7K}\x9d,\x0bp :\xdb\x08\xc7gq1{\x9aM\x88\x06\x19u\xcb\xa4\\\xc4\x96\xaa\x90-\x1d\xa4\x9e \xb43\x9e\x1f\x9a\xbe\xaa\x08\xbfw\xc2c\x8d\x84a\x97\x1a3\xa9\x9c\x0b\xcb\xaf\xc9\xf09\x19y}\xb9\xf5\xd6:n\xb05\xceOS\xb4q?/\x8e\xaaT\xd8\xe8\x0egz\xe25\x16[g\xdd\xe0\xd5\xbf\x96\xa3\xa0\xd9\x84|X-\xf8\x96\xdb\x0d\xa1\xb8H\xd8x\x06Au\xbf\xab)~\x8d\xe3\x82\xc0\xdeA\xe7{\xa0\xd1\xfe\xfe\x92&\x9f\x97\xe4\xf93\xfb\x1c\xd5\x85\xcd\x7f\xb7a\xf3\x93l\x8c\x01\xc3G)\xe1\xff\x88\xc96n\x96cp6mVj\x83\xdcR\xdaj\x19\xdf3\x7f\xcd\x97k{\xfb5\x89\xf4\xa3\xef\x16\xbc\x16{\xff5\xee}G\x88\xc8\x07\x12r\xac/\xa4,z=G\xd7\x06\n=V6\xd5\x01\xfe@\x97\xe7\xa6\xc7`\xefMFw\xc8%#\xb4H\xaa@\xc2\x02\xe2\x9c`\x92\xe38M\xb3\x0b2\x81\xb8\x80OdU\xf4\x9b\x89\xb3\x9b\xdd\xf3\x0de-n\xf1\xdc\x98\xc3X\xbf|\xd2\x11\xab\xab\xbb*\x86~iI\x8c;\xde\x94|\xbay\xf1\x01\xcc~\xb1\xea\xc2\x15j\xac\xc3\xa6$C\xb2\xc9Z$\x89\xc6\xc1\x9b>\x08\xad\x0d\xb9\xd5m\xfa\xa5\xcb\xda\xfe=\xf7\xe3\xc5\"]I6\xde\x12\xd1\xaf_W\x91\x83L\xf23\xb0\x03\xb2\xddD\xb0\xe6\x94^\x91\xbc\x16\xde\x7f\xa4\x08!\x96AA\x18\xc4@\xf9>\xa8 \xa7\xc6\x08\x19\x95{\xc2\x89\xfa\xfc*\xe7`\x9f\xfd\x06\xf4\xc4y\xeaot\xda+\xe5kI\xd68\xc3\xa0e\xb41\xe6\x03h@\xeb'4]\xf1&\x85\xd6\x14\xd5\xa4c\xe1\xd4{J\x80s\x0fd\xd2\xf7\xf4\"\xfdd\xe1\xedKu\x0c\x13\x8c\x92f\xa1 \xf5b\x16\xfc\x85;{\xf0\xb5HU\xd8\x1f\xcf\xe2\x9c3/\x8fY@Q\x98\xb1\x8aG\xc7\xa4\xed#\xad\xff\xe2\xbd?&U\xc6\x84\xa48*ic\x9bj\xbc\xf5\xdaa,_9\xf0V\xa9;\x8d4\xf3\xcf\xab\x08z\x7f\xefE\x82]\xb4\xea\x04\xc6\xb18\xe2]{\\\xf6cs\xf57\xa0Y\xd8\x16\x97\xdf\x91\x08>XE\xe6\x9fI\xfc\xe9u\xdc\xd02\n\x06/xGd\xe6\x02\xf9\x92\xa1qqF\xb6\xa1\xfc\x1c;<9I\xe6\xf3%\x92p\x8em''\x8d\x14\xed\x1d)\"\x03lE\xfc\x0e\x9e\x93&\xd2\xf3\xfe\x7f\xe7o\xec\xdd7$\xa6\xe4\x0f\xf6\xef\x192\x1f\xbf\xb7\x0cY\xb2\xf86)\xfa\x95e\x03\x9c\x91@\xc4f\xa1tV\xb9\xcd/H>\xcd\xf2\xb9P\x7f\xc7\xa2\x8d\x8b\x84\xcd \xa6\x90\xd0iB\x13F\xa0H\xfe \xbe;\xf0\xa3[\x8cw&\x0d\xfbE$\x0d\xfb\x8cMp\xfeb\x1c\x94\xf9\xd3\xf9\xb3>\x1f\xd9\xeb%\x8byO\x85\x16\xd6\xd2\xa5\xab\xce\xad\xe9\xed^\x91\x80*-?\xedO\xb3\xfc(\x1e\xcfj\xf1V\xc6@\x06u)R\x8a\xdc\x15m\xa9\x9b\xd4e\x8a\x82\xf6\x03\xe7g\xef\\ \x7f\x90\x8el\xe6\x1fI\x04'|\x9e\x1f\x89G2\x9d\xd2| B\x8a\xcb\x038r\xa9\x88\\\x8bd%!\x1d\x15\x86`{\x00\xfb]\xa2\x14\xda\x85\xe1Q\x95@\xc6p,\xbfN\x8a\"\xa1g\x82 \xc3^?\x91\x95\xc8f\xc1\x86\xd4\x94fR]\x82y\xe6/E\xfcU\xde\x97-\xdc\xbds\x9d\x11\xfc\xd76_\n\x85\xa7\x96\x01\xeau\xbc\xb0\xa6<\xfb\xf8\x85\x96\xc5\x93<\xcb*\x959\xff\x81\xa2s\x19K#\xf26\x85&\x93b\xad\xebb\xa3\xae\xff\xa1'\x85r\xcf\xa9 \xec9\xdd\xa0i\x9c\xc8r1\x89\x19y\x8e/\xaf\x0c\xd5\x0cm\xdfn\xba\xb29\x99g\xe7\xa4S\xd26\xccz\xe5nxBR\xc2'\xe0\xdbtk\xd6\xbeS^m:e\xd1IsA\xdc\x89\xa3\x85\x08Y\x92\x17\xa5G;\x94\xae \xa12\xce\x94\x13\x18\x92\x91l\xd4c,m\xf4\xb0\x8c\x06\x83]\xd1)R\xc6b\n\x14w\xf8\xc8\x96$\xda'\x91\xc4\xb9\x8c\x03\x15\xa6\x8d\x95]'\x1aw\xfa\xe2qr\x17K?<;Q<\x97)c\x12YM\xcbb\xd6RW\x01\x03\xc8\x82\xa5\x83\x06\xca\xe5*p\x02K\xe9\xac\xdb\x8e!\x03\xab\xd4qF\x82\x04cH\xd0p\xc3\xf7n\x04\xbd\x84\x9e\xc7i2\xe1\x94\xf8]\xccf69\x88\xcf&\x85\x01\xc4.\x0fT\xfe\xd2XNy\xc5\xa7\x8c\xd4*\xe5\xfb\xc9\xfe\x01?\x07I0\xae\x16\xd0\xa9(\x9d\xe2\xec\xc7r\xf6\xe2\xd7\x8a\xff\x92\xbb=H9\xbe\x06I\xc5\xcb\xb0\x10\xcf\x8e4\x82\xa9\x81\x07\x90{\x9eR\xd4\xe9Z\"\x1ee\xdfy\xd9\x9b\xe4\x9aZu\xd0\x1a;`\x9c\x92\xd8Y\x94Hk\xbc\xed\x16\xc3\x84?\x84Ym\xc0:\xea\x8d\xb3\xee\xf6k2P\xe7\x04J\x8b,_\xa9\xb8x-t\x11&\x06@\x8e\x86 b\xb1\xfeE\\<\x16\xf44@\x1f\xb6\xfe\xc9 \xa1\xc52'o9\xbd\x0e\xea\xc4[\xb1R\xce\x81\x97\xbd{\xee\xc1\xd6\xf9P?7\xf4\xd1pQ\xec\xd2\x0d\xb6\xb8x\xae41\x9b\xf5\xaf\xf7\xd3\xb12%\xc86\xebA\x9e[\xce\xb67spR\x1a\x11r\x01/\xfde\x9e\x8d\xbc\xd0\xbe\xd4\x89Y;\xdcKo\x1b\x94\x03\xdb\x99E:\x88\x08\xba3\x93\x80a\x82\x19\x86\x19eL6\xf7H\x94}\xea\x80\x80\xb6\xda\x9d{K\xed\x98\x8a\xc11`+?\xd2\xfeI*\xd6Fgk\xa2*\xaf\x03\xb24\xc8\xe15\x1a\xd2r?\xe8\x0c\xce\x9edp\x0c\xd3I\n.\xb9\x0f\xe0\xb3\xc1s\xe8{\x12\x01\xb2W\x8dd\xc0\xaf\x1f\xbf\xb3TO{\xc2\xdf\xd6\x81dS\x0f\xfedO\xfc\x81\xc3oOH&*j\x19\x1f\xac5>\x9c @,\x9d\x9c&l\x8e\xe0PN\xb14\x13.\xc8\xd4\xab\xcf\x9f\xaf\xd3\xe78[Rv\xed._\\\xa7\xcbOd\xf5\xa3`\x8aY\x0b\xba~\xdd\xfezs\xdd\xae\xbc;}\xd9\xdd\xe9 \x13\xa5FK\xa7\xe6*\xc2\x86V\xbe\xcd\xf1\xf8\x93H\xd3\xa9(\xcaW$\x90\xbf\xfc\xb4\xa1?t\xa6x\x14\x15\x90D\xc6\xaaVRJ[\xb3_u6k\xa6m\x1ce\xac\xe5o\xd1\xab\xf8\xc0\xe6\x8eyr\xb2\xc8\xc9\xb9\xc9\x14\xec\x97\x85\xe5\x9f\xbeIQ\xeb\xc5_\x9f8\xf2\xf6fJ\xaa#\x11d\xa5H\xc7\xf0\x87F\xe9\xa8\xb8!\xa5\xbb\\\xfc\xaa\x13\xbd\xcck\n\xbf8\x93R\x7f\x8fz\xed\xe0{>\xa0\x7f\x92`\xd73\xff\xdd?\x9c\xb8z.k\x92\x9b\x8d\x9c\n\x15-\xab\xadt8\x17\xc1\xa9\xc5\x9d\x12d~\xd8\x8b\xe0\xc4\xa1\xbc\xc1\x04pL\xf5\x86\x91/\n\xbc\x11h\xcaU\xb1\xb8I\x04q\x18\xc1\x96T}T~U\xe6\x0eD\x1e\\\x19~\x18$\xb2P\xd7!\xe7\x02\xa4\xf6`g\x0fK~\x1d4\xab\xc9\xf1\xeb\xcae\n\x17zvl\xc6g\x14{U\xf9\xc6\x9fp\x9bW\x93\x1cZ\xa1'\x8a\x8f\x19\x1f\x9b\x82@m\xc8C\xea*\x8b\xb2>c\x16\x95\xd4\x07Q\x97\xb4\xd5\x14\xa4\xa5\xa3@O\xb8\\p\x08\x19\xee6\x93\xbe\xc2\x82\x8f\xd2\xe9\xa6\xd4/\x89\x05\x8d`\xe9\xe4U\xb8D%$\xb6\xc0\xf8\xe9\x01GD\xb9\x9e\x84\xf3#G\xc12\x8c\xe0(\x881\xeb\xc3\x05?'D\x0e\xd7!\xff\xcc7\x9d;cn\x1e\xaa\x95\xa8\xf4W\xe1\xf6\xd9\xba\xff\xc2\xcf\x13\x976\x80c\xea[l\xcc\xf2\x08\x1b\x0c\xf8\x02h\xac\xf3\x8br\xa6\xb2\xbaP\x04\x99\xc9\x96\x83\xbbW$\xde\x0e\xaa$_U\xcb\x07\xda\xdf\x8f\x1e=\xe2\xf4\xe3\x16\x9c\x99\xf7\xf9\xb2\xde\x08\xba\xe9k\x1fY),\x1f\xef\x8f8^\xaci\x1b\xc3Z\xfc\xb1\xc4qI\xbd\xea\xb0\x82\nl\xc3\xb9\x84\xccH\xe8\x15\x07\xf5\xd5\xcdB\xfe\xe5C\xf1\x1d\xe1+\x0d\x070L\" \xbeK\x9e3\x17\xbd\xac\x12k`\xf5\x82Z\x86\x02Z\x9a\xe8:\x12\xdfph\xd1a2\xb2\xd3\xcc\x02M\xb46\xeds\x1c,\xd1-:\xe0\xaf\x15\xf5\x8c\xc6>~ \xd3V4\xa1\xba\xae\xc2\x90\x1f_\x8be1\x0b\x0c\x9eEV\xf2\x12+\xa0e~@\xce\x9c@.w=zmUj\x95[\xb7\x00\xb3\xb0\xd6\xd4+\"'c\x99\xd8Wl\x7f?\xce\x12\xc1S\x82\xc9h\x87\xbc\xa3QX\xe3\xc8\x98\x0fG\xa6.\xe5l\xc0\x86\xb6\x04x\xea\xca\x10\xab%\xf9'5\x115FEKl\xad\xfe\x01F.J]\n\xd9\xcd\xb4\x99wU8\x8d\xf2|\n\x0b\x90\xd1a\x9a\x82W\xc9\x99\xd6\x8e\xb9d\xb7\xe0\xb8\x85\x14\xa9\xe8\xb2\xf9\x1f\"\x7f\x9dJ\xdb\xff\x0e\xec\xc1!L\xfa\x8bLT\x82\x98\x0cSN\x8dZ7\x86|\xe4\x9c\x1f\x9f\x08\x06S\xfc\x0e#\xec9hh\xff&\x95)\\ \xcc\x11L\xbaX\xd2\xab\x08~\xbc693F\x97!vY6+\n\xf5\\\\ \x82z\xfdp\x11\xf9IP\xf6\xb1hF\x12EC\x84\xa6\xd7J\xd8x\xc3\\\xce\xb9%\xb8\xbb24\x1b\x95\xb3\xc3%\x13\x8f03\xf2H\xc4q \x19\x89\x99\xd8\x89&x\xaeM\x17k\x99\xa1U\x02\xe8\xa7$\xc8m\xa0\xd2\x04D&Y\x1e\x8a@b\x0e\xa9\xb2P\xf0]\x9a\x9f\xa7u\x18\x9a_\x1acL\xe5\xd6\x00\x82\x14n\x81 \xb5\x91\xae!\xa1\xce\x1a\xca\x1c3AUtz\xc9D\x93\x08|s\xe7\x0b5B\\.\xf3;|\xef\x8d\xe1\x10\x16\xc3\xe9\x08\xdc!\xeb3\xa1(\x9b\x08\x0b\x8cX\xe8\xfaZ\x99g'\xd4\x04\x13\x8f\x83B\xc0\x01E\x97\x85F\xde\xc7N\xf2\xeep\xf3\xaaU\xfc\x92\x0c\x01\xdf\xcf\xa2\xde\xcc<\x8c\x103v\x1fHV\x9f>\x80%\xa6\xf9\xe1\xb81\x80\xbd\x10\xe2\xe1r\x84hp\x0b5\x0bl\x98lo\x8f\x1c5\xeb@\x13J\x87\xf9H\xa8\xb8\x84/|\x80 \x05\xb7\xb1\xda\x98\x81\x90\xf0\xc7\x8b\x08\xd2\x08\x96\x11\xcc,\x90\x94\xe79\xff\xbf\x08S/\xa1\xc4\xe5?\x16,\x86{\xf0/\x98j\x9c\x8b\xba\xe3h\x0f?\xde357\xab\xda\x99\x99\x11\xf1tSr\x7f\"\xd1m\x86\x14\xfc\x00R\xf8\x17\x92\xfd\x14\xd6`\xc1\xd0\x0b\xed\x93\x82\x05\x8b\x08\xa6\x11\xcc\"8\x0d\x9b\x01\xf8\x1d\xe2\xc7yY\xed\xa3\xf2\x80\xb0\x1f\xb5B\xbdZ\xa6\xbf\xc9\xb5\x08Z!\xc5P\x80O\xb9\xa7\x1eb\x99=Q\xf3\xacslz\x97\x88\xf6\xf5\x0e\xdd*\x8d\xa4\xfa\xcc1\x06\xb7\xa2#\xe9\x92\x16\xf0%\xb5L5\x00\xa8\xbbn\x19\xa2\x81_0\x80\xafH\x90X\xed\xe7\xe0\x14\x17\xc6\x19e \xdd\xa8\xf8C\xbb\x7f\xedW_\xf8\xccv\xecj\xa8\xb6\xa7mct\xe6J\xb5\xe6Im\x10\x90:0\xf9*\xa7|\x06s\xb8\x0dw\xdb-\x8f\xd5\xb3\xfd\xf6\xb3i\xf9\x9d\xcds\x7fa\xf1\x188\x97\xb1CG\xc6\x80a\xe4\x9b\xbb\xf3XZ\xe4\xea \xe6\xc9+\xa9\x9d\x99/\xa4\x18:\xec\xaa\xe7D\xdd5\x1e\xc4`r\xa9\x03\n^\x89\xe3:\x87G\"kt\x0e\x0fa\x0e\x87p\x81\x99\x07\xf2\x08U\x0c\x18g\x8a\x85 X@\xfb,\x13\xf2w\x88ei\xd9\xc6n1\xe8'r\x9c\xfc!z6\xa4\x01\xe9\xd2\xf4\x96\x9a\xda\x0e\x7f\x13\x93\x17\x89\x9f\xa7\xc5\xc4\xed0\xa2\xe5\x01\x99\xb1\x8e< \x0b\x16\xc1\x05\xe1l2\xf3\xc8\x03\xa2 \x1f\x81=\xc6r\xc1\xb4#\xeeKsZ\xbcJ\n\x06\xc3^\x04\xbdQ;\xa9E\xad'\xcf\xa4\x16\x89\xaa\x15_%\xc5\x0f\xcb\xac\xe4\xa4\x9e\x95\xdcq\x9ar\x01\xb6d-1I3\x8e<\xcb\x93\xb3\xc4\xe6\xd9\xa6d.\xde\x13\xed\x8b2\xa1\x04n\xc1\x99!\x14\xd2\n '\x0c6\xcb\xae\xe1k\xbf@\x901\x04\x99d\xabjU\xf3\x1dE\xa00\xb1\x7f\xe5\xc4\xc6\xe0\xa1\x96\x0dvs\x975\xc0c\xe1!\xec\xc2!|\x92\x19\x0cq\x9b\xed\xca\x08SqsW\xa8\x1f\xf7\xc43f\x8c.\x03\xb0'\xd8c\xe8\xfb\xa4\x16\xd3\xfcNe\xcf9aq\x92\xba\x19*\xe5\xdeo})q\x06\n \x14\xdfb\x94\xc08^\xc4\xe3\x84\xad\x84A|\x00\x97Xo\xbb\x195 \xe4A\x14\xb12\xf1R\xd6x\x89\xf4ORrN\xd2\xea]\xfb\"n%~\xe1\x06\x89\x08\x9b\xa8BL\xcbuV^\xf6b\x14\x1c^\x9b\xb8\xdc;7\xd3\x05\x82E\xac\x14~\xad \xa4\xcf13z\x17^\xb9\xe2,k\xdbj\xb3\xf4-H \xcaJ\x1c\x9aU\x03 \xcb,\x992T\\h2\xaf\xcah\xaf^R\xba\x0d\xf1p\x91&c\xe4\xdb\xf6lQ\xbb\xb5\xc1&\xb4 \xf9&d\xa0\xd1\xcbn'8\xfe\x0d\xc9$tjZ\xfeTK\xab'\x9b\xc0\x15\xe6\xf8\xd3\xc8>!%%\x81j\xd7NE\xc1\x19)'(\x16\xcbb\xd6\x05 %\xbcU\x11\xfa\x96]\xae\xc1\xc9\xca \xe1\x1b\x16\xbai%\xe0\x9f\x90\x11\x91dQ\xd9R-;\xbe\xe6\x16\xbc\x8b2\xbb\x96\x16\x11%w*\xe8*l\xe3\x1e\x1e\xe6^%\xd9\xea`\xcb|\xf3:|R\x87\xecn\x04;{\xeeV\x97\x14wWW\xcb\xad\xf5\xb8\x16\xb0\xad\xa1a\x9f\xf0\xc8\xd9\xf1\x05\xb3#\xfbd\x99HnH7\x07\xb1\x17(\x9a@\xee\x00\xf0&\x89W\x1e\xfb'^i\xf7\xe1\x95\x90\xa3\xd9\x91o\xe2\x95vw\x1b\xe4\x19y\xec\x97g\xc4\xdc\x87\xd7\xb4\xce\xaf\x93\xd7\xe3qg\x9e\x91&\x9fx,\x08\xad\xd7\x89\xa6o\xc2v\x11\x8dz\xcb\xbe\xf5\x97\xce\xbf\xa8\xee_9\"Y\xe2\xaf\xac\xfa\xe7\x1e\xddfI\x19\xca\xedi\x17gOJ\xe4\xb3\xaf\xcd\x06\x05a0\x14\xb1\xabB.\x9e\xa8\xa7\xec\xdfW\x04\x86b\xd1\xd6\x8d)\xd0F\xd9)\x9aur\xa5\xfe\xd8 _\xbc\x02\xa1s@\xa1\x04\xc1\xa2\xd7w\xa6\xd7\xad\xec\xdc\x98\xc8_\x92d\xe2\x82\x05:\x9b\x135\xb8\x9c\x1a\x87\xa3s7\x91\xc6\xdcl\x94\x90\xc2\xb4\\I\x81\x12\xf6\x00&\xac\xad\xc1\x9a\xb1v\xe2\x89W\xcf\x8f?X2O\x9c\xa3\x05]\x83\x9cM\x7f5gV<\xc0\xb1\xa3h\xac%-\xa8f\xd2\x8cn\xd3\x7f\x9d\xb3\xe1\x8c\xa9`\x90sV\x05\x83\x9c\xb32\x18\xe4\x9c\x95\x89\"\x9f\xc8\x9c\x91\xda\xbbx\xbf|[\xbd\xa5~\xe1\x8b\xa5\xfd\xed\x89\xb2\xc5i\xb7\xd5\x17\xea\x17>\xaaR{=)\xf3|U\x0f\xcadOOj\xd9\x9f\xf0\x85f\xe2\xa0'\x0d\x89\x19_\xd2\x93\xf4<\xd1r\xf6\xc8\x87z\x0e\x9d'\xb5\xa4:\xa2\x0b=\x03\xce\x13=#N\x04\xf3\xb6\x08\xf4\x84L\xb3\xdcd}\xb4iZh\xe9\xd0\x84\xde\xcc\x0c#\xdb\xca\x8d\x81\xeb\\\x86^hL\x97Y\xbb\x88\xfaC\xe1\x13e\x0e\xad\x15\x0e\x80\x8f\\\xadK=\xe1p\xc4O2s7\x99\xf4\xbb\x10\xaaHs/LT\xbd\xb0S\xf2\x18\xf4Q\x0c]\x06,,R\x1fs\xba\x15\xd7\xc0\x8c\xb0\x85\x1d\xd4q\x86!\x8e\x06\xdfJj\xa0jSe\xe3\x80\x85\x95,\xf3\x80\xf2\x12\x06p\\\xe5\xce2\xcf\x7f+1\xabTj\x8e\x13\xbb\x0f\xa0\x10.\xa6\x05\xfaIJX\x14\xa3R\xfc\xb2\x12\xe4\x0c\xddD\x96%\xf48\x8d\x0f#X6)\x98\x01G\x1fO\x19i\x1d\xef\x9d(\x1a\xd4q\x14\x83\x8c\xbf\x00S\xa5\xf5\x13\x85\xfa\x0e\x84\xcd\xdc\x08k\xee\xc4\x0b\x07\x93:\x0e\xda,J\x88\x839&\xcb\xe4\xd8\xa5\x83\xd1\x80\x82\xf8Rf\x86\x0c\x1a\xbf6DN\xb5Y\x9c('\x9b\x8ceoRY\x91\xa1\x92/\x92~mq9M\xceD\x85\x11\xc4udi\x1fog,\x82\x15\x8b8\xd3\xe0J\xa3~b?\xad*^]\x1d\xe2F\x08KEay\xb2\x1b_\xc2\x04-,\xc8\x1dQ3Ryf\x87O-\x91\x88d\x1cv\xc3\xc6\xc4\xa0\x16\xf7\xcc\xe7\xb6\x8c\xc0jc\xad\xe9q\x96\xb5rV\x16O\x13u)b\x12K\xff\xa5C\x85`\xe2x?PQ\xee\xf8\xd3\xce\xa3\x82\xf4K\x89e\xe5\xc3]\xf4\x8c\xdd\x81\xd8\xfd \xaa\x18\xf9k\x16\xbe\x11_y\x04s\xc4\x1d\xfe\xf2\xdca\x0f\x95@\xe8\xe4\xe1\xd5\x95\xa0\xe3,\x9fvZ\xee\x87SG\xd1\x11\xd0\xd4\x12X\xedq'\x85\x03N5\xdd\x9f\xc8\x96\xd1\xb3k9$\xe6\\)`\xdcvx\x97/a\xd1t\xcb\xcfPs\xdc\xb1\xac\xc2\xa9\xd5\x7f\x01S$/\xf5\x05L\xe0\xd1#\xc8\xdc\xdf\x8d1\x00f\x9b\x1f\xeb\xea\x03\xc72\x8d\xcb\x05\x1d\xdf\xf0\x82\xe2\xb9\xf6\xc0\xea`\xa1_|\xed\x8d\x19]L\x97Z\xf4\xa5M\xe8k^\x89,\xb2\xc7E\x9d.\x85|\xf3ZJUh\xe7\xcbv;\xbe\xba\xf80\xd2\x86/a\x17\x82\x83.\xf5#\x92\x8f\xe1\x00\xd2.$\x079\xf2X\xb8\xa2\x17\x98y?\x13\x87R\xc2Q\x83\xf2S;\x0b\xedn \xe0\x9c\x92co ]l=\xf6K(qaL\xf6c;D\x96\xad\xec\\\xe7\x0e\x8d\xc2\xb2T\x93\xc3\x0e\x17\x92\x96\x9a\xaa\\\xfc\xd4T\xe5\x0co(=9\xc5_U\xd6\xa3e\xa9$\xcf\xf0\x87&5&\xe2\x86\xd4\x97\xc7\xe2W=\xb9\xd7\xd2\x0b\x14G\xcc\xa5Q;c\x18\x06}\xc6\x07$\xec\xfa\\|\xf34\x85_\xb6\xa1l\x03q,\xfc\xf1er\x1ewL\x05\x11N\xf3\x0f\x15qS\x8a\xd9\xd6\x07\xc8\x0b#^j\xbe\x14\x99kc\n\x96\xb3\x83sK\x1b\xc4u\xb8td\xcc\x19\x0b\x13\x9f\xb4\xe5\x89\x8d\xa1`\xe1\xd4$\x8d\xc5 \xa5\xf2F\x05\x92\x0d\x136\xde\xb2c\x18\xc0\xd8\x1c6h[\xd1\xa2>\xf2\xf2\xf8'\x95[\xa6\xdeUT\x83\x9d\x80<\n;-\xde\x12\x0e\xcb\x9b\xcaD\x16\xeb\xe3l\xc7 \xd8\xf0\xe6\xd8\xce\xd3\x95j6\xf4\x07(c\xf0\x88\xe6\x99J\xa4\x07\xea\x9c\x05\"?\x97dK\x91+\xe5\xa3\xe2\xe2\xa5g\x1a\xc3\xa7\xf6\x91\x94\x16\xf4\x86\xedW\xb7\xac\x9a\xf9A\xf1\xe5C!\xd0(V\x10\xb6\xe1\xdc\x86t5sD\xc9DJ\xbe\x15\xbf~ \xfc\x16\xd0\x15\x07\x0b\xab\x0eJ\x1f\x06\x11\xaa\x95\xa3'\x03\xffhg\x00\xe7N\xc4\xeb*\xf3n\xad\xe8\xe5L\xd2\xa3\x05\xbd\xa8\xa83Q\xeeX\x7f\xa2\xe2\x0f,\xe5\x8d5\xb3\xbe\x9en\x07\xf33\xd8\xd9\xf6\x0e\xf6?\xf1a\xff1\xc6\x03\xb6m\xc5\x19\x96\xa5\xcc\x8c\xd8H\x91\x9b>@\xb3\xd1.\xfe\xbd\x8d!c\xbc\x05\x83\xc7\x02\xc7\x87\xb8\xb9\xbf\x92.2\x15s\xdc[j\xd8\x86\x86_\x13\xa7R\x13\xfb+\xd1#\xd5\x91i\xac\x82N\xb7a\xccG\xfd \xc4\xe7r\x1fa\xf5\xac\xb4\xbe\xe3\x0fa\xa8\x8cG\xe9H\xee*.\xd8\x8da[e\x1f(\xf8\x9f\xe7\x86\x11\x8d\x85L\xc8\x1f\x8f#QF}\xcc\x0f\x00\xf1o\x82\xff\xba&2\x15\xd2X\x82\x11\x04\xf8\xe72|\x00\x0b\x0e\x11\xec\xb9\xe0\xbb\xc9k\n\xb5\xa1\x8b\xf1\x9a\xf1n\xd2\xe5N2\xc3 \x8a\x87\x18#!\xc8\xc6RH\xdc\x07|`x[Soat\xe3\xc4\xbc\xb2X0]|s\xeb\x16\xc6\x01\xa3h6i\xa8 :h\xc5\x1c#X\x90\x90\xa7bz\x9c\xdf(\x1e\xc0\n\x1e\xc19\xff\x87S\x82.Y\xe2\x14\x060E\n\xb22+I\xd4\xc5\xbb\x9bK\x92s:\x12\xfdV\xbf\xad \xa4\xcc\xfc\x9d\xfaP\xf4|\x8e\xb4\x0b\x060\xe9\xa0L\xa0\x18|\x05\xb2\x80/\n\xc6\xac\xcfj\x8a\x93\x1c\xd9\x98e\x88g\xdd\xa3\x01,B\x8898\x16\xb8h\xf8o!\xdc\x16*\x07\x85VSR\x0f(\xda2\x85O\x96\xee\xc8\\8\xce8\xa5B\xfcp\xae\x9c\xdc\x87\xa9S\x98\xe1\x0bs\"\x84\xeeG\x8f\xf8\x81\xeeZ\x18>\x80\x13\xa4\xae\x8b\xea\xf5\x10Ns\x12\x7f\xb2\x7fu\"\x05\xb5\xed\x01\x04bK\x85\xf05\x9c\xe0&\xd9)!#\xf7\xd3\xf0\xc4,\xdc\x9a\x177\x15X\xfdH\xaa\x11E;M\x90\x16|ev`\xcc\x97(\x15\xfb\xe1\xa1\xd8\x0f\xb5\x0f\xca\xe5,8%\x90\xef+\xea\xb2#\xa9\xca\x8e1\x8ar\xe3\x94\xa4KTkT\xc7\x89`\xbbI\x8d\x9d_V\xba\x1d\xc08\xce\xca\xbd*\xd5\xdd\xabf\xbe\xeeU\x9cL\\\xb0 \x16\xe2\x0eFj6\xa3\x1b-\xc7\xf1c\xbf|\x91\xb9\x9e/\xb2\x16A_eY[\xba#B0)\xb6\x93 F \xc6\x9a\xbe'\x15\x10~$\xf7l\x82\xeb++\xfd\xc5A!RJ\x8aU\xbf\xe9\x94\x92\xb9\x88GK7@\x8f\x04\x1e)\xa7\xc9[\xb7D\x82\xa8\xca+9A\x92\xa2 \xdf\xccrcY\xa9\xb7])\xe6\x84[\xf5.*\xe5\x94\xce\xfa\x9co\xcas\xaf\xf6\xdf\xb9\xdbw\x16z|.\xdc\xe1>\xb0\xaa\xbe#\xbf\xb5\xb1\xdf\xcd\xf9\xff\xfa\xfa\x8e\x1f\xdcP,Ka\x8e\x9b\x08gk\xf0\xb5oJ\xbe\xba\xea\xe1\x9dfT\xb1+!\xaa\x14\xe1(\x02\xe1\x8f\x03\xb4\xdb\xf7OD\xea \x91;<\x15\xf6e\x8f\xdc\xe1^sz\xeeT&\xac\x842a\xc5{|\xcd\x02Q\xdd\xe6\x88\x05\xadP?K\xeb\xbf\xbb%\x0ci\xda\x89\x14KoM\xbd\x14K>8)\x1c\xfc\xbcHI\xc1,\n\xff\xa2\xe2\xf8\xf9\xd1\xba\xb4\xa9\x12\x06\"o\x93\x19o\x85~\xa2KQ\x18K\xf28\x10\xda\xd3\xea\xe7>|\x0d\x89r\xdcD\x1b\x910V\xb6\x93\x9fZDXu\xc9\xfe\xb5\xf9H\x15\x0bJk\x96}\x14\xf6Y\xf6\x92\xac\xc8\xe4\x98|\x0e\xc2\xcd)3\x19\xeeZ\xb8\x86\xb0?M\x93E\xc0;x\x1d\x8b|:\x1anr\xa2\x9b\xd7p\xb5\x8e\xb9\xba\x933:\\\xa0\xf1L\x95}c\xa10\xfe)%\x86\xe6\xdc\x1bkj\x0bND\x96J45(/\xb5X3\xabm\xa6B\x80\x18Qi\x19\x0e\xf7F]\x8b\x9d\x0b\xd5\x9eXG9\n\x91j\xdd:\x081?\xe9L\x1f+\x12Z\xb5\x10\xcbB)\xb2\x19+\xc9\xb0\xf1=\xb9\xfc\x9e(\xca!|\xc3%\xe5\xc8\xcc\x9c\x0c\x07\xe3kt\x7f\xf7\xcc\xbc\xfc\xa6\xc3\xeb\x04\xdd\x954\xaf\x93\x93eA^\x92U\x01U)\x0bE\xf1\xdaI|m\x9d\xbe\xb7\xd0tc\x8f\x9b7\xff\xec\xafm\xfe\xd5_\xdb\xfc\xc7\x8e8\xb6\x7f0W\x8aXV\x1bA\xbd{~\x83o\xf1.\xafN\xad9CR\xe6\x08\x8b9\xaa\xe2%\x9d\x0d\x9d\x97e\x92\xe5G\xb2\xfe\x19\xfa^9\x15b\xfe\x83\x05}7\xc9n\x02\x0b#\x12\x99*\x8a\xf09\xcd\xe2\xa2\xd3\x0d\x15\xf4\x8e\x12:N\x97\x13R4\xab\xda\x97-\xaa\x176kv\x16\xdb[\x1c\xc7\xe3\x19yO\x8a%\x86Q\x12\x1aaE3\xe9Q\xf8\x91\xe2\xe3Z\xd9.W\x04\x93\x12C\xcc\xce\x14P\xa7P\xadzV\x9e\x8c\xa1\xf4:\x14\xbc\xa1]\x1da-v\xa5y\xa7n:?\xa1\xef\xe5\x07\xc1\x9b.\xa9^i7UW\xa2]\xbb\x98\xaeXx?'Vu)\xbbf\xee,_\xab.\xe4RHg\x1d[uU\xfb\x0c\xdd\\\x87\xbb\x1d\xd9\x90\x00\xc3:\xd5\xbb\xda\x87{\xa3H\xfb\xbb\xe5^\xd8\xbc\xdcfQ+\x19Q\x97-\x8b\xb9\x1f>\xf2\x95\xc2\x15\xfe\x9d\xcbLp\x00\xbf[\x11\xa9v\xd3F{?ws\xba\x9d\x148o\x12\xdd|s\xd2b\xa7\x01y3\xa4\xd3\xa7\xa82\xc6\x81bbz7\xc5\xadj\xa6d\x18&\x8c\xbe\xf6\xa2\xc4Nn\x14\xedp@N\x02\xe43\xbck\x13\xa0\xac\xc3\xd9\xa6N\x83\xf2\xa0\x9a\x91\xfaXZ\x04mD)\xeb\x98\xb2\x99(\xf9\xcc\xb9\x86\xc3o:\xeb*o@i\x94\xf8\x9atR\x19t\xb4\x93\x04F\xc9\xaf\xf6\xb7\xcf\xa5OZ&h\x83\xdbE\x05}\x13\x9c4H\xc9\xef\x1cZ\xcbHC\xb6\x18)\xd0\x92\xe3\x9bq\x01\xc0\xa2NhUE\xb4\xec\xf1\xef\xbb=\xd7\xdc\x1b\x9c\xea,\x16m\xeev\xba s\xe4\xe2\xb2\x88`\x7f\xd02\xe7\xcd \xa9S\xe0\xa3y\x06\xa0sW\x1b\x8c\x13\xf4\xbd(\xa4D\xdb\x961pW\xa8Yj\x90-W:\xc1\xb2'\xd4\x04\xc8\xbc\x8f;{\xb0cHa\x0d\x92{h\xd2X+WP\xa7\xb1\xb5\xc6--_\x8f\x8d\xeb\xe0\x0e\xa9\x81\x97\xa3\xe6\xe8\x90\xff8\x0f\xd7Q\x8c\xe4*\x82-\x1b\xec\xcc\xb1E\xae\x19\x19\xcfx{\x0f^[\xfe\x0f_\x95_\xc7\xc9\x8e\x9b1k\xa2\x9a\x15\x8f\xcf\xcbD\xbd~\xc7o\x86\xc7\xd4\x8a\xf7\xb2\xb5U\x11\xc4\xccq\xfaf\x7f-;P\x8e\xa7\xcd\x0bH[\xbb\xa1\xb4P(t\x98\x0e\xa6\xc0\xe5My\xae\xc5 \xd8\xcf\x98\xa5\xb9*/t#|\xe2p\xeb\x05%5\xe8|\x02~P%R\xdc\xde\x8e \xe3\x0d\xe5\x12\x02hn\xb6\xe7\xf9\xe4Sm\xfa\x84\x81Z<7\x1f\xe1\x03\xa6&\x1f\x918*/v\x03m\x036\xc3\xd3\xf9S\xe1\\\xdc\xc9\x8d\x80\n\xca\xa8s$\x89\xfb\x0be\x08K|\xb8\x12\x906\xb1b\xb8\xeb\xb0\x9a\xa9\x0b\xb3Y\x1a\x13\x83\xeaW\x1d_\xc6h*\xd4r\x02}\xc6\x8a\x882\xb7:\"\xcf\xd8\xcap\x82U\xf01\xf3;~\xb6\x81'\xbe\xc4\x8fX\"N\xf9\x0c7r#\xe2B\xc4\x1e\xdcF\x1f\x1c\x0cDD\x9f\x1c\xf9\xfe[Y\xc1,\xeb\xcc\x9b\xc4\xd1\xe6\x9d\xa8cf\xb7'|@\ni \xc8\xe1\x04\x0c\x12X\xaf!\xe6\x7f\xc5e\x8f\x1c&}\x96 \x15\xbav\x10\x07a\x05)\xf3\xa0\xa4\x93w\x0c;&\xcc,`0\x10\x9e~\x01\xdfl\x85tD\xda\x85\x03c\xa5\x89s\xe9\xd5\xe8>vR\xc5bV\xe1\x06K\xac\xac\xa5\x8c\xa1\xcb\xca\x80\x18\xc1\x16\x9eR\x992\x8b-\xcb4>A\xda<+<\x8ea\x99\xe1\x86\xc9p\xd3*)\x10\x93E\x15\x15\x93\xb6\xcd\xe9$\xa6\x9b1\xf8\xb1\x85\x11\xa4_\xa6\xa7\xca\x9c\xe09\x96!\xda\xa4\xc2\xbcf!F\x11\xb4\xdd\xe5\xaf\xf45\xbe\x9e\xb2N\xda\xf4x\xff^K\xe4\xd6\xd3)\xb4\xd1Zm\xab\xf8\xec\xeb\xe3\xb1\xbc7|\x96\xaa\xb5z\x10B\xd6yZrxmo\x17\xf0HC\xf9\xae\x93\xd8+\xfa\x1d\xba\"\xe0\xf9u\xe5V\x13\x10T\x13tM\xa1\xe4\xaa1 \x96\xd2\xe2\x11\x0c\xb0g\x91\xa8\xa3\x13\xc9'\xcfU\x92\\\xf4\xc6\xd05\x95\x9b(\x08\xeaXk;0\x7f\xf2=0\xddd\xfb\x86x`;\x19K|\xf6\x08 \x1c.\xef\xe72\xc8\xc2E\xa7\xba\x11\xdd\xc1i\xa7\x9d\xa4J\xa4\xe4\xc6\xd3\xb2\xc9u\xa7aE\xb5\x8a\x16\xdb]\xb8\xd9\xee0\x02C\xa0\xe5\xcd\xf0\xdc7\xb0,Y\xee\xb3.\x9b0\xf7_~\xdel@\xb0p\x93\xe3\"\x19\x12\xb5\xabk\x92uP\xa4De\x1d\\JZ\x11\xd6Y\x7f\xa4\x0cY\x832d\x918\xc2\xb2.\xba\xd0-7L+\xabG\x07\x8f\xcf1\x04+\xf9\x8d\xf1/\xde\x81\xe0\xf2\x8a\x1a\xde\x8ee<\x93\x83\xbd\x87\x8bY\x92\x12\xb0:\xe5\x81\xae\x0e@\xdb\x95>\xf3\x04\xfb\xd8\x88\xe6\xf9 ?\xde\x88\xe1\xe3\x8b-\x01\x0e\xfcE:e\xa9s$\x07P\xce\x86\x04E\x07\xed9WUC\xac[\x99_\x85\x89\xb2e\x1d\n\x04\xd0\xb8\xe7-\xf4\xbcJ\xe1!\x16\xac\xb9\x05q\x80U\xfb\x90(\xa7\x18\xa8\x0d\x07*M7R\x04*\xcb\x01$()\x86\xa5$\xb1\xb5\x8b\xc59\xedxeW\x95\xf3\x85\xe5_\xb7K(\xfd\x15\xa6\x8c\xdc.\xae\x81\\\xc5aG\xa1\xf3\x1b\xa3R\x92\xadJ\xbc\x94\x14\xc4\xcbd\x02\xea\xdc\x92\xa9\xe672\xcf\xa6\xbe\xf4\x06d/\xb9\xa4\x00\xa5\xfb\xf5po\xc4%T\xd4\x10\x06K\x15O\x81\xd8\xc5\x8f\xd18H\xab#\x93\x96\x84#\x8f\xc4\xf9\x99v\x93E~-\x85sn\"K\xa3\xa5\xad\xe5u\xb6\xa0\\\xb4\x90\xac\xa3g\x97\x1di\xbb(`\xd7\xaa\xdd C\xbb\x01E\xf533\xfd\xec\xa4\xa8\xc2#\x13]@M\xf2\x8b\"\xb8Kk\xda\xe8\xccN-\xc5\x9eT\xda\x8d\x9a\x83 \xeb(\xe2$\xe1>\xccq\xe4\x99(\xbdx\x08\xe2C\xe9^\xc6\xac\xee\x83e\x96i\xeb\x11\x91\xf4\x8b,g~\xd2\xacb\xa2\x022\xbc3\x8a\x80\x0e\xef\x8c\x10\xcb\xc9p\x7f\x04;@\x87\xfb\x86\x0c\xc1aU\x90\xbc\x91\x95\xc1j\xb1I\x86l\xa4v\xd2\x00\xf6\xdbm6+\xf4\xb9\x1a\xe2\xa0\x1f\xee\x99\x06&8\xd7_e\x8d\x0f\xe1\xd6\xfdR\xfc\xfa!h(\x04m8\xf5\xc2\x89S\xc2\xdfE\xc3+\x0f\xbb\xd1\x17\xe2 \x1fJ\x89\x1bV\xbc\xc8\xc9d9\xde@\x87![\xff\x15=+\x05;G\xd1\x87S(*,\xf9\xf2\xdd\xb6\x0c\xd4\x8a\xe5&\xdfWG@\xca&\x03\xaf\x0f:\x12\x89\xf9\xcc\xc3\xf5\xf4|\xff\xd5\x8b'\x13\xf5s\xec[N%\x8f\xbfu\x0b\xa8\xa6\xbf\xad\x85M\xae\xd7U4\x82\xf8\x05[\x03\xde\xedz-b[\xbd\xc6\xfb\xb2\x8a\xbf\xf8\x02\xa1Y\xea:\xf91OH\x90\xfbz8\x97k\xd6\xf2\xb3\x04\x81\x84\xf3\x84\x06u\xcb\x14\x0c\xfc\xf6u3\x0b\x9f\xf0\xf3\xac\xce\xc4\xdfE\xbcv&Bx\xb6T\xfd\x0bM\xa2\x81Z\xfa=i\xa9\x10\xe4\x95\xd9\x92\xf0\x81\x06\x94\xf6|\xba\x05Y\xe2\xc1\xb9\xe5\x9e\xc0U\x97\x022_\x1f~2\xc1O\x01\x86\xb0W>\x97\x1c\xdf\x1d\x07\xfe\xf5\xf5m\x1e\xec\xff\x06\x9c!\xaef\xa7\x00\x86\xba \\\xce\xe4\x9a\x80\x92X\xe0\x02\x88H@\xd2/\xb29\xb9N\x07\x1c\xbd\x1c\xcd\xcb\xfaR\xffFFJ\xe5\xc7\x8c\x11\xbb\xa5\xb3\xaf,Gq](\xe2\x00]\xb3\xbcy\x81\xf8\x87\xce\\\x08\xc2\xc4\"jr\x90\xfe8\xa3\x05\xcb\x97c\xd4,\xfb\xd1\xf7\xaf,\x8e\xdeI\x99\xcdFD a\x89\x116\xcb\xb3\x0bD\xf1\x0f\xab\x059\xca\xf3,\x0fzG\x97\x0b2fd\x02\xc3\x97\x11\xfc4\x02\xb6\\\xa4\xe4\x00z\xb0\xdd\xcaHk\x19\xc3?\xdd\xd1U\xaf\x88\x8cG\x08#x\xea\x1b`\xf5\x8b\xbb\xcd\xa5\x00[^\xb1A\x19\x17x\xbd\x9a\xfe\x87\xbb\xe9z\xc4V {\xfaUc\xb88\xb7\x15j\x81\\^\xbd\x12\x8f\xea\x1c\x9c\x14\xd7\\zT\xee\xf6\xd6\x13\xb41\xce\x9aY\xdd\xf1-\xe9\xa4/\xf3\xac\xbf\xd0\xb3\xcbW\xdf\x0bm\x13k\xa7.\xb5\x8c\x9eu\xe6\xba'\xf0Hf\xa3<\x10\xc5>\xe0\x10v\xf8\x0f\xbfs\x9fZ\xb6\xf2\xb9\xf4E\xfb\xc9x\xe0\xa3\x14m\xe7\xa5\xf9\xd3\x9f=0\x1f\x8f\xc0\xd3\x94@\x96\x03\x06E\xef\xa4\xc9\xa7r\x0f\x98I\xbc\x18\x14\x1f\xb5\x81@X\x97\xd9\x0b\x16yG\xe2d\xc1A\x94$\xd0\x99SLX\xb0\x13Z\xb0\x98\x8eI6\xd5*\x9e;\x9c\"\x10r\x88\x1e\xf5Ok\xc9>\xf3\xc0\xa6z.\x9bpr\xe8\xfc\xa2\xa8\x96\xea\xd6\xb2\xc6U(\xe5'\xb2*\xac~\x89\xea\xda\xf2\xe3\xca\xf4\x8b\xe5+\x8f\xb7\xf8\xc5\x8c\x11\xae^\x9d\xa8K\xceeB\xa6 %\xef\xf2lAr\xb6\x92\x9c\xaf\x7f+\xfc:#L\x13-7\x19\x83\xbat\x12$\xc2&7j\xe2\xaa\xdb F\xbf\x8a\xdax;\x8fo\xd3uF\x1a\x89\x98#\xe8=\x8d)\xcd\x18o\x1d2\n1\x85\xa4L\xcf\x9b\x93q\x96O\xfa\xbd\x92d\x8ah;\x07\x8bi\xba\xba3\xb7\xa9\xcb\x12\x8d\xd0\xbc\xae\xfa\xa7 \x9d\x04U\xd4]\xf7gW0\x8e\xd9x\x06\x086\xf7\x80\xae\x02\xe5\x9a\xae\x8e\x88X\xea'\x90\xeb\xa7\xf1\x9c\x94\xa1\xc3\x9fD(^\x8c?&d\x1a/S\xf6\x13\xe7\x960\xe7\x8c\xb5\x1b\xfb\x00\xc4\xea\x88\x80\xc3\x8f\xa4\xa9\x98P\x97\x05q2\x94)\xcaS\xab\x15C\x9d\x99t]\xa5\xe4\xa7\xb1P\"\xda\xb1\xa9h\xd3\x7f\xb1\xe0\x1d\x8b\xe0#gL\xde\xdd\\\x95\xaew7Y\xa5\xebm>!9\x99\xbc\x8e\x17\xf0g/\x82\xdeU\xbbV\xd7\xbbk\xd4\xea:\xd7k\x04\xf0\x95\x125\xfc\xed\x90\xadyh\xc9b:\x18F\x8a\x1f\xd2PT\xa6m\xd5\xd0z\xf7o\xaenS\x96\x9d\xe1S\x92I\x95\"}\xb4\xb5{\xa1\xcc\x88\xe0\x1c\xf5f\x95\xbf~g\xae\xdaG\xef\xae_\xfbHo\xb8]\x06\xb5\xd6p-\xf5\xb8\x0f\xb0+\x90U\x9f\x06\xa8\xb8\xd1 \xa7?rv\xbf\x91nDGD+\xf2i\xa30\xd8\xd2\xba\xdc\xe8E\xbe\xb9\x80\xa1\x0e\x90\xa1\x05\xd6\x12\xde\xe57/\xbf\x12\x17\xed\xa1O\xf3l~DY\xbe\x12\xbaRM\xf9\xd3\x8d+\x9b\x15J\x10\xc2\xdf\xa0U%\xc1#\xbf6\xab\x11\x85Z\xb7V3BEH\xe4\x12\xd5?\xb2.+\xdf\xd5\xaf\x99t\xe5$\xfe\xd5\x16\xd4\xd1\xc2\xf4\x9d-\xf2^\x18$\x1a\x84dRh\x84t\x00\x1fX\x1d\xbe\xc3\x99\xaanP\x83zY\xe7\xc0\xb0o#`\xc1\x1b\x16\xc1\xafa\x04o\xaeA\x81\xdb\x82\x1fR`\x13&\xd4\x9ao\xc4\x0dt\x96K\x13m\x8b\xa2i\xce\x86Q?rL>oD3\xb0q\xf5e\x9b.\xbc\xa9\xc3\xcd+T\xe8\\\xab\xc8l\xc67\x0e\xdf\xef\x159\xdc2%\x1b\xac\x8dQ%\x1b@\xa3\x86\xf74A\xd7\x1d\x89y*+\x87=8\xfc*l\x05\x896\x80 0\xb7\x13;t\xb2h\x06\x02\xa7\x02\x9fk\x87\xcd\x06`\xc8\xaf\x03\x06\xda\x00\xc3<^\x18\xf0\x15$\x18Z\x85_\xde|\xd9\x19\x119B\x94\xda(\xa99\xe0\xd6&\xaf\x99\xf3<\x1c\x97I\xc0l1KW\x9c@\xa9|\xcb\xff\x14\xeb\x10\x8a,=e\x0fV\xd5y\xd9|\x16\xc9|\xcd\x14\x0eD1 SWa'Q\xd8\xechB\x1b\x9f\x0e\x96\xd0\x01Au<\x99\x8f\x0bZ\xd7=\xb5\x0c\x1aV\xd4m\x82\xcd\xba\xa8\x9e\nye\x19\xa2N\xef\x8bRL@\x83\x8aP\x1a\xa2\xa2Y\xac\x02\x16\xc4G\xbf\xb0\xd2\xbcbZ\x0e\xd7RT' \x0b\xde\xb3\x08^\x86\x11\xbc\xd7\x97\xca\x14\x08\xe8I\xc4\xcbh\xc06%\x7f\xffe\x9b\xab\x93\xd2\xd8\xd7\xc7\xb8\xe9\xbcy3\xdca\x08r_\x96\xcc8S?\xbc\xff\"\x84\xbd\x11\x0ce\xbe\x18\xca\x14\x862\x85\xa1\xa2\xda\x96\xc2K\xaf\x9aa,x\xc6\"\xf8!\x8c\xe0\xd9\x97s\x10\x0e\xe4{v#\xc8\xf7Wb\x18\xf3\xc7/\xe3dn\x0c\xbf\xfe\xc3HT\xe1\xcf\x86\x88\xf4Jr\xba\xaft\xe8\x10)\xcct\xf1\x10\xedu\x94,D\xb3\x9fW\xff\x95\x88\x84\xc7\xa5\xed!\xbf\xbeb\x81\xb5\x88\x9e\xe6d\x11;\xdf*\xd1\x15K\xf4\xa30 \xaa\x12\xa3\xd8Z\xdd\xdc\x157-R,\xbf\xdaz9#\xa2\x1b\x81\xfd_\x83\xe8\x1e\x91\xa1~{\x01\xca\xf0\xca\x9a[\xb8\xa3\xa2\x86Z/\xd6\xe5e\x89\xde\x95\xae\x11\x82@\x0eS\x18\xa0~)\xde%\xee|S\x0e\x1e\xf7r\x06\x87\"\x91\x8b@\x89\x1cQ\xa2\xba\xb9'n\xee\xb5\xf3\xe5\xeb\x97\xc5e\xd1\x83&\xd4\xce\xe1z\x1a\x827\xf6G\xcf\xec\x8f^\xd9\x1fa\x8e\xaa \xa7\x11\x9c\x10.ZP\xed\xcd/T\xb0.\xa9\xe4A\xb7\xa1g\xd5\xb0\xd6:\xdc\xf8\xf8\xaci\xd4\xf9\xe7o/he\xf2qw\xe6\xa9L\x10v\xd0YY\x1d\xdd\x85\xe6\xf5\xcd[\x1b\xdc\x90\x18\xe2\x94ks\xe1\xe2\xeba\xf5\xb7\xd2Y\x18b6\x9b3\xf1R\xfeV\x92\x89Qe%\xfa\xbfuK\x1b@M\x9fk\x9eli\x1f\xd7l\x03v\x9dT\xff\x84\xcc\x17l\x85br\xf9c\x001\x95\xa2\xf6/\xa4\x9d\xf2\xb41UO\x8dq{\xd1*+\xb5\xb0P\xffM\xb3j-\xe9'\x9a]P\xf8DV\xd0\xfb\x1bl\x03\x81m\xf8[\x0f2\n\xfc\x97\xc2c\x8b\x91\xbc\x06\xbd\xad\n|\xb2\x98~Y\x8b\xc3\x8c\x14\x1ez\xc3\x9a1\xa1\xbeD\x85\xd2ku\xe0V\xad,\x846\x9a\n\xe7\xe0\xa0Z\x87v\x1d\xe6\xda\x1ax*\xd7\xed\x1b\xc7OCZ\x9f\xa9\xccS\xea\xca\xac\xd8\x9a)\xeb\x9ci\xfb\xe8\xae\xcd\xf4\x86\xb4\xfd\xce>\xae\xcf\x1eX!\x91\x07\x06\\k:jZ:\x00])e1Y_uk\xd8\x8dS\xbc9v\xf3\xdf8C\xe25\xc1\xff\x84 \xa1\xbeA62\x0dT\x1b@\x06\x0d\xf8\x1a\x04\x1ap\xa8w\x82\xcc\x16z\xd7j\xc0\xb1\x15\xa8\x8c\xc5\nuxO\xd7\xed\xd3\xf2\xd7\x19a\xefT\xf3o\xa7\x9c\xb4\xd8\x11E\x1b\x7f\xde\xcc\xe4\xed\x17(\xb2\xec(\x99--\xfe\xebu\xdd\xcb\xb0\xaf\xee\xf6\xde\xa3\x93D\xcf\xab\xb3\xc2\xdd\x993'\xfd9E\xff\xde\x94\xcacgk\x1c\x94\xc9\xe9\xf9\xb3k'\xa7O\xae\x9d\x9c\xde\xc5\xc1\x97\x92t<\x99\xd8\x8b\x11\x18\xb6\xa6\x17 S7 \xb7\x82-\x04\xe1\x16\x19N\x9b9\xa4\xeb,zF+[UFK\x0bUy\x1b\xeb`\x97\x0f\xda\xe5\xb73*Jdk\xd5\xb2\xab\x9b?'\x18\xd4\xa2\x1e\xf0\x9f\xd5\xc3V\xf9m\xf5\xe0\x19!\x8bF\xf1\xed\xfa\xc3F\xb3\xeaV\xfd%c\x01\xef\x8c\x1aJ\x8dg\xd4XA\xbc\xbc\xdd\xae \x9eQ\x8f:\xe0\x19\xed\xdb\xeb\x80\xe3CW\x1dp\x16\x144\x82#\x8ey\x05\xbd1\x07\x93\x82\xa2-Yf\xd0\xf6\x96D\x02Nq\xfb\x9f\x88\xb0?\x9bZ\xbd1\xa9\xaawL\x98U\x9a*\xbeH\x9a\xaa\xb8Vg\xbb\xf1d\xe2\xdb\xee\xa4\xc0\x9aq\xac\xac\xbcC\xb7\xb7CH\x026\xa4\xa3\xb0}\xec85\x8a\xe5\xb1\xcd\x8f\x1d\x8b\xfa\xc6x\xec(\x07\xa9Z$\xc1p\xb7yx4\x96>\xa1\x8c\xe4\x05\x19\xb3\x9b]\xfe*\xa3\x12\xf3\xab\xbd.0\xc4/\xbeC6\x94\x98NeS\x18\x9f\x17\xcb~-,0\xf0\x14N\xbfg\xd6'\xe7$_y\xb4\xac\xae\x12\x1dJ#\x8cE\xf5\x0b\x02 \x90\xcd\x93\xa4\xc5\xa6$\xeefZ\x1aHR,OY\x1e\xff\x7f8\xf2o\xc2\x91\xeb\xc6ry\xa2\x08&\xb2\xbai\x14Q<\xa4\xcf1\x85`\xc43G\xab\xe5\x10\x81\x93\xebi\xf4$9H7I=/K\xaf6\xd1q\xafCM\xd3\x1e\\[\xe7T\xdf!Y\xce|y\x819\x0d~.\xbdw:Nf\xde\xee\x93\x95\x8f^\xc2\xd08\xebn\xff/\xd2 \x15\x7f\xadz\x85iZ\x85\xb61\xcf#3t\x90c\xcc\xb9\xafa\xd88\x1d?\x85Xk\xc4\x9b\xea\x80L\xf9\xb0;\xd5[\xc5\x7f^\xfb\xb3\x99\xc2G\xf65\x8f?\x91\xe0\x0bu>8\xfb\xa48FM|J\xdb*\xa01\x8d`\xcaq\xac\xf7\xf7\xbf\x9f\x9c<\x7f\xfd\xfa\xe3\x87\xc7O^\x1d\x9d\x1c\x1f}89\xf9\xfb\xdf{mG\x90\x05\x7f\xbb\xf0P\x1aM:\x11\x81X\xaa5\xb1f\xb5&\x05\x05U([j\x88\xb1\x1c\x9c<4\xa5w<\xae\xf0|\xc1V\"|\xba\x04\xa3\x9f\"b\xd6\xbd\x17\xebJ\xae\x85#\x08\xa3\xcaf\xdf(_G\xd5\xb4\x88\xc8\xea]\xad)\xf3M\xc2}\xee\xa4Kc\xcc;\x10\x8c\xf9xg40\x99j,\xed\xce\xbf@\xa5u!TZg\xb4\xd2d]\xfc\xbfM\x93u\xe6\x86_\xa9\xee3\x14X\xd4\x7f-\xe8pJ\x95\x03\xddBSj-*\xa5\xd6\xa2\xae`R?\xeb\x0f$k\xb0\xa0\xba\xcej\xe1\xa3\xf0Y\xb8\x14>\x8b.\x85\xcf\x82\xaa}\x08\x038\xa7\xf2\x06\xdf\x8a\x88\x92\x11\xb0`N9q\n#\x98\xdf\x9cFh\xfe\x97h\x84\xe67\xa9\x11\x92\xfe\xf7.\xc5\xd0\x9cV~\xfa\x82r\x9f\x19(\xf7\x8aFp\xca\xf7\xc9\xdc\x83\x16\x9flJ\xd8N\xffC\x84\xed\xc2 \xcd\x95 l+>\xde\x13\x1a<\xf7/\xbby\xf4\x05\x84\xed\xad l\x97\x1aa\xe3\xb7\xfaKZ\xcc\x92){\x9c\xa6\xbe\xd1\xfc\x97\xde\x8a\xee\xa7nE\xf7)\xad\x1clO\xf5\xbdvA\xe5\x0d\xb9\xd7Np\xaf\x1d\xd1\x08.8\xb5<\xba\xb9\xbdvt\x93\xbb\xe2\x98\xc5\xe3O0\xe4\x1bb\xd4\xde\x10G\xd7p\x05\xa9\x1b\xe3g$6\x14\xaaG\xbd\x15\xd1\x92r\x93\xf0\x81H\xbcNvv\x1e\x84\xf8\xbd\xf0\xaa\xb2\xef\x058\x04\x99\x84\xc6\x14\xf7W\x1b\xf9\x82\x90O\x1b\x01\x88\x8f\xba2\x1c\xf2_\x86\xec\x1d\xad^\x96\xc5\xac\xab\x97J\xdbP\xae\xaf\x9f\xd6\xa1\xd4\xf4\x95\xce$\xb8\xfb\xb7[\xedD\x1a\x03\xcc\x07\x1e!0\x9bo\xc1\x0e\xecq\x88?\x12j\xc3\x9d\x9d\x10?\xb3\xf1\x05\x98Y\xa5lcH-\xb9\x0f\xf9\x825\xd7\x82_\x86D\xcbu|\xb4\x04S\x96\x9c6\xae\x87\x16o\xd5\xac\x18*\xef\xd6\xcb\x9f3\xe9\xda\xff\x98\x9a\xc5\x93\xd6\xe2=\xe6\xa4\xc8C0\x91\xead\xb4u\x05$\x0c\x05G\xe4^\xbf*\x07I\x87\xd4\x82\x0c\xb8\x19\xba\x1d\x9b\xaa\xe4\xed\xcb\xf0\xa0\x0d84&\xb2\xe4\xd9P\x00*4pT\xa7\x10\xeb\xdfN\x9d\x0f-2\x8aw\xca\xc0X\xdb\xfa\xb3\xc6\xfa\xd3\xeb\xae\x7f\xdb\xfd\xba\xb5\xfeYge*\x1de\x8b4\x19\x93`\xcf\xdd\xa6<\xa66i\x97\xa3\xa1\xa7:\xca\xd4\x95\x0f\x067\xbb3\x9d\xa2\x8d\xd67\x9fF\xb6\xb8\xce,6\xb12}i|\xb6D\xa9\x06\x06m\x82W\x9c\x15q\x83\x8d#\x89\xcf\x91\xc9\x89\xca[\xe9\xe8Q\x0e\xd6\xc7\x15\x8cbq\x11\xa2\x7fe\xd6p\x7f\x08jM\xd7-TeG\x17\xa49\xfa*M\x8f5\xc6\xaf<\x99\xf2\xda\xc9\x84e\xce\xb2:\xc9\xe2\x07\xcd\x83\x10\xeff\xee\xd3\xdd\xbd\x88yc\x11\xb3k\xad\xdfcj\xaa0\xddX\xc3\xcd\xd4V\xa5.\xa9\xad\xb9\xaa\x10\x94\xe3\xeacZMH\x9f\xcc\x86a\xc8\xfa\xcc\xf6,z\xa8\xa3kkAe\xdc\x81\xbe$\xd5\xd1\xa2y~\xb9\x90\x82\x8a=\x977\x10!\xaf%\x13\xccU0\x08\xd5\x92 \xe27y\x07\x13\xe85Y?\x1d\xa9\xd7l3\xb3\x0e\xb1\x9a\xa9\xf1\xec\xcb\xfdNn\xcf\xc8\x84N\xaf\x7f\xc5O\xe4]\xf1\x03\xb2\xdf\n\xd0\x91\xf0\xec\x17\xcb`Q\xd1\x98g(Z\xead\x1e\xba\xb2\xf393\xf3\xf9D\x05\x1c\xa1\xd6\x15\x85\x9a\x01\\\x1a\xa4\xf7c\x1a\xc1S\x93\xde\xf5\xc3\xe3\xa7/-\x9a\xd7O\xfc\xfd#\x0fi\xffq\xe9\xae\xd7\x91?\xb4.\xf3\x7frf\x94\xa9\x98\xe1L\xe7\x84\xb3\xa6\xa3^V\xd1\xbf\\\xfc\xaaS\x07\xbf\x94\x81o\x9d\xa7\xee\xb1\xd0\x03\x1cs\x80<\xa6A\xcb=\xc5\xd2\xe8\xbbnq\xb1D{\xabYR;\x9c\x86\xa8\xa3cCjH\x84k\x85\xa4\x9e\xbe\x8bU\xbc1\x0d#\xa8\\&\xb5\xd0\x88\xe3\xd5\xfc4K\xb1B\x82\xeby\xb3\xadf}|\xfd\xd7':|Z\xaa\x17?\xf9h\x03?\xb9\xb4\x81\x9f\xba\xb4\x81\xbc\x0b\xdd\xb6\xf6D\xb7\xb5E@\xfb\xcf+\x02\xf91\xe2\xcbDM\xe9\xbfdJl\x8f4_\xafH\xe0bE@.8\x91\xb9qE\xa6\xed\xeah_\xaf\x8d6zh0\x06U\xbe\x07\x8b\xe9\xcdi\xdaV\xd8c\xa61\xad\x15\xc4\xbbm\x9a\xc0\xb2\xe7tB.\xc9\xe4\x98|\xf6\x00\x8cF\xe2\xdf\xcb\xa8s\xbf^^\x1c\xfb\xb7\x8e\xc01\xa6\xc2\xf6\xd1\xccc\x82\xdf\x9e\xfa\xa4\x07\x9c\x85Y-H6\xc5\xfc\xda/\x8eQ\xe7\xc8\xff\x10\x16\x1e\x0b\xf8P\xbb\xc4\xdf\xf1\x9d\xde\xdb7\xff-\x13|\xfb\xa6\x9c\xe2\xdb779\xc9\x97du\x0dAC\xf8\x13\xd8\xfa\xa4\x93F\x8f\x1eU\xa3\x10\x98\xfcS\xcc\x89\x1aX\xcc\x1b\xa0\xebI\x0f1\xa1\x89\xb9<\xb8aXB+\xb4\x19,j\xc8\x125W\x9c\xa1\x84\x8ay\xbbYh.Sc\x18\x08\xe7@|6o\xa3oRZR\x04=\x84C\xe8aE\x028\x80^\xd4\xb3c2\x83\x01\xf4\x0czTu} \xa6\xbbp\x9c\xcaR\xfd[{\xe8\xb2\xba-,%\xfc_t3\xdaR%\xa4\xb4I\xe1\x9a\x96^4x\xe6\xf4\xda\x9c%\xc8\x1d\xe0\xc5\xb7}\"\xab/ ?\xcf\xbdVt^\x93C=\xd0\xaa\xdcb\xf5\x94\x9d^\x9d\x89\xb3t\xc3\x0d\x16A\xe6\\\xe0\x06\xae\xb5\x1cT\x1e\xc2>\xe6G\xe4\x98\x02\x07b\xc3\xb6\xb6\x83\xae\x06\xc0\x9a\xb5\x0e\xe4\xc8\xe0\x10\x82LR9l.\x94\xed\x92\xb2\xf4\xad\xa8\x18\x988\x0b2\xe7\xfe {\x9f\x9c\xcd\xd8\x86pS\x84Ig\x84*C\x94\x9b>I\xaeG\x9a\xdes\xab\xdd\x1dl\x83\xc6^\xfcq\xb7D*=\x19\xaeWWh\\\xbe&\x06?\xb9\xde!\xc1\xb9\x91\xcdz\x14yYD\xac\xdc\x1b\x8a\xa5\xc2LY0L]\xe5^5&\x9a3\xb3\x06\xe4\x80\xb9\x1f\x94\xba\xbf\x80\xd6\xfc\xee\xd5\xcb\xe9\x92\xbd\x8a7Q\x0f\x88}\x8d\x1e2\xbb\x11\xec\xecy\xf5\x92\x14G\xf3\x05\xf3\xb11\xc8^4\"\xae\xcb\xe9M\xc9\xfd@.c\x9d\x19\xf5\xe0EmFH\xaf\xd9\x8c\xb3%m\xee\xfc\x8e\xf9<\x0dH\xa5J\x12\xdb^\n\xb0\xe2\xe3\x0d\xf4*\xd8\xfb\x13_\xf6T\xf6\xefK\xa5@\xa3T\x1fI\x10V\x06)W\x06<%\xe5\x98\x88w\x17\xeb\x8a\xdf\xcb\xbc AU\xa7\\T\x12\xe7\xbbR\xcfy\xec%\xb5i2\x97\x99\xddU\x97\xa3\x94\n\x9e\x05\xba\xb9\xcdR!\xefJ?o}V\x8f|^\xc6\xe9&\xc2\xd69)\xc9\x86W\xfb2k\xa6\xc7V\xd3\x1dN\xcdk\x8b\x81Z\xfd\x13L\x97W+\xceDHu\xdf\xcd)\xd6\xab\xb7\xfeN\xc3\x86\xaa\xd5\xcd'\xd6\xaa\x1at\xf9\x8e5>&\xc6<\xa0\xea\xba\xf2\xe4\xf7\xc4.}\x93m\xb8\xdf\xa5\xf8\x81;|\xa3\xd3\xa5\x14Y6\xe7,,\xd5\";xn\xea']V\xc2%m\n\x97\xbc\xefa\x16\x01\x1d9\x05L/\xd6\x8aO\xff%\xf1%n5o\xf4M\x84=T\x8dQc\xa9]\xf3\x98\x1agd\xc7\x8a\xe8 7\xb3z8\xda\xb2\x99MF\xb1!rx\x0e\xa5\x02\xdc\xa6\xe3\xf1_-\xcf\xa1\xbc$r\x05\xfdF\x91o\xcc\xbc \xe8\x1f\xfb5\x9f\xc6\xec\xf5\xb5\xa51\xdf5\x02m\x13\xffb\xae\x93\xa4\xae&m\xabk\xea\xbb6\xb2\xd6Bn8k]\xc7\xa1\xae\x895o\xf1\x8d%O\xd9\xe2\x06ga \xd9\x1f5)\xc1WD\xd0\x8f\x12\x7f\x8c\xe1\xa7\xdd\xab\x0d\xcc\x90\xf5\x82y\x1e\xd8R\xa1\xa4.\xef\xfa\x14\x1f\x9fa]m\x9b>5\xaa\xfcd}\x07\xfe\x9cz\x0e\xddTnZ\xf8\x03c\xa1MUa:\xabU\x98\xee\xcc\xb6\x9c`\\\x90GV\xe4\x00}\x1a\xb1Z:\xc6-\xa9\xa4\xc4I\x04+\xceJ\xafB\x14\x13V\x95\xbf\xa7\x19D\xaee\xf1:\xad\xce\xf2l\xb9\xf8w\xb0\xe2~6\xbc@f\xbb{\xc7P\xd5\xc5\xf9wO\x06\xde\xc8\xb9w\xe9\\\xf8\x95\xb59w\xfe\x99\xe0\xdc\xbb\xf7\xb5~I\xf0\x04\"\x04r\xbd\x86\xe1(\xc4\x18\x06\xccY>\x8c#HFp\x00\x89\x87q\xd0A\xc7\xec0P(\xe8G\x81\xb3:\xe5\xed4?U\x14\x8cD\x90\x04&\x12\xa9.\xcb\xf87\x165f\xf1&r\x06\xd2!\x99py%b\x08V\x9e\xbd<\xdf\x84\x86\xab~\x9e\xd3M{J\x8a\xe3\xe5\xa9g\x81\xcfR\x06\x1c\xd8|\xc2\xcaJ)\xc2\xea,y\xf4J'\xe4\xb7\xb4\xe5y\\&\xc6\xd9 \x9f\x96y\x8a\x0b\xce\x0bm2\xc9\xc05K 3m\x96ay\xd3\xffT\xfbDVo\xa7\x1b\x0c\xa9<\xd483\xb7\x11$o\xc0H(\"\xce\xfd\x8f\xf8\x9aV\x86\xef\xea\xe7-)\xd5\xa7\xdbts5Z\xab\xe4W\x1f\xf9Y\xff\xfe^^g],\xbc7\xae\xb11\x97U\xbb\xefy|\xb9A\xaf/\xd8F*\x8cy|\xb9\xe9\x99\xfa\xa2\x96\x8f\xc8\xab\x13?\xa3Yk\x06p\x08\xef\xa9pa\xf9\xe8'(\xcd\x13z\xfd\xe9\x88\xee\x98\xe8\xcewn9\xd9\x18\x13\x8d!\x8f`n\xbe\xf8\x94,6\x80\x9d\xd6\xfe\xeb\x98\xcd\xfa\xf3\xf82\xb0T$\xb6t\xd6\x14\xbe}\xa5\x04\xcb\x1e\xe3M\x06D\xbb\xe3=\x90\x9fgI\xba\xa1\x99\xa1\x1c\xccO\xd74l|J\x16\x1f)K\xd2\xcd\xba\x15@WC\xdeL\x05%\x12\x82m\xd6_\xdb\xcaa\xc8\x0c\x06\xe6\xfeX\xfc\x89l\xb0\xbc\xacf\x80\xb8\x06J\xf1\xfen\x18\xa5x\x93\x9b\xa3\x14\xff\xeaKP\xea:\x92\xc4?\xbc\xb8[\xad\x84\xd1G\x8aj\xdeZ\xf26\x8c\xac\xec`x\x15;\xcd\xac\xdaeuq\x91.\xab\xc7\xe6i\x05Zja \xd8\xb1\xbb\xb5sY\xcf\xbf\xa3\xec\x7f\xc9\xb8\x19\x04\x1f\x82*\x91e\xd7\x0c\xb5f*\xe9\xa7\xfc\xf6\xd6-\xd8\xde\x8eQH\x95\x0dZ\n\x95\xab\xeb*\x8c \xb6\xbeq\x15\x81^\x06\xe9\xbfhU\xb2|\x93e!5o,\xfe\x9d[\xae\xe5\xd7\xd2\xe1Q\xa2.9N\xcf(K\xfdB\xdf\xa9e9\xd3\xee\x0f\xc0?\xe2Q\xbf\x9c\xd1\x8f\xfae\x89\x95\xd0/e\xba\x89;\x8bS\xa9K\xe8\xf0kE\xaa<\x1c\x1aUD\xa3\xac\xdf\xeb7\xd1B:\xab\xfa\xbd\x9d\xe2\xdb{\x1d\xae\xad`\xdaki\x04\x05j<\x0f9i\x1b\x0c\xe0\x8d\x14s>s\x8c,\xf0\x05\x91\xe6o)=C\xfe\x0b\x16\xb7\x8b\x088)\x80\xf1\xe1\xe6\x9aW~\xf0\\\x97\xa9(\x0f\xad\xcd\x98\n\x15C\xb0!_\xba\xb9\x186\x8b\x8b\xd9\xd3l\xb2\x81\xa3\x0b\x9bU\xd9\x05\xb0\x8a\xf3L\xcf6\xd0\xcd#@\xb9\xbd\x84\x83\xf2`\x00{p\x1bv\xcb\x8d\xe6 ]\xcaL:\xeeT\xf0\xf9\xb9\xf2\xa36\x16\x0ea\xcf\\\xf5\xb6|M\x0c\xcck\xf1\x1b\xdf\xf0\xd1^\xa2\x90~\xe7\xee\x9d\xfd\xef\xf6\xbe\xbds\xefN\x18\x95\xb7\xe1\xe1C\xd8\xbb\x07k`\xf0\xe8\xd1#\xd8\xd9\xbb\x17\xc1\xdd\xfb{\xdf\xde\xbd\xf7\xdd\xee7\xcd\xf7\xeeh\xef\xdd\x89\xe0^\xf5\x1c\xd3\xb9\x07\x0c\xb6\xe1\xce\xb7\xf7\xef\xee\x7f\xb7\xbf\xf7\xdd}Xs\x98\xfe\x8bo\xe9\x7f\xc9\xcf\xf6\xeeG\xb0\xbf\x7f\xf7\xfe\xb7\xfb\xfb\xf7\xca\xe6\x8f\xe5\xe7\xd8M\xf9\xe6\x9d\x08\xee\xec\xdf\xbf\x7f\xf7\xdb\xef\xbe\xdb\xfd.\xd4\x9bpl\xb9@\xe7\x0f(\xd6\xba<\xdc\x10j0\x80;{\xf05\xe4\xb0\x0d\x9fi\xf0\x94\xe0\xa6yJ\x02\x16\x86|F\xf6\xce\xc1sw\xaaKh\xc5\xaf\xd1K}R>\xdd\x943\xc2\x8e:;\xd8\xacq\xcfvCc9k( \xa2\x89\x14\xd6\xee4\x95\xc1|/~\x10\xc9\xc9\xb4\\\x00\xfa\x1b\x1f\xe8p\xaa\x02\xbc?\xd0\xe1+\xfe\xf7\x07i\xb2(\xf8-\x19:*n\xcb\xc0\xea\xf2\xbe\x1e8\x04\x03xF\xf1IB\x8b\x85\xc8\x8d\x8f\x9f\x1cg\xcb\xbc\x9eW\xc6\x04\xb2\x86\x12I\xba\xb7\xd6g\x87\xad\x8fgqBE\xdb\xd2\x96)ng\x94\xc5 F\xa5\xe3\x10\x84\xee\x12c\xc4s\xd3)9M\x93\x0dB#K\x01\xe5#\xb3\xae\x84I\xed\xb38j\xb9\xf7\xfbZ\xff\xedT1\xb7\xcb\x02N\xe1n#\xc3j)M('\x89a\x12A6\xb2\x17\x9f\x06\x10FU\xcd&\xe9)4\xce\xe3\xc5\xcb\xba\x0f\xb2/\x8c\xae\x01\x04\xbe\xeeMXt\x89\x19-X\x88h\x04\x07\x10\xb0\x93\xeb\xec\xd6\xd7\x14\x93\x9btf\xeexn\x07\x92\xdaI\xf5\xbe,\xed\xfc\xde\xd9\xce\x90E@F^\x8d\xbd\xb1\x90\xc3\xe6\xd9\xdc\xb1\xd9\xb6\x88O2.h\xc3\xd32\xac\xf773\xac\x9d\x1b\x1e\xd63\xf7\xb0z\x05\xd2\xc0\x9a\xf1\x03\x0e\xe1\xc5\xf1\xdb7}\xf1(\x99\xae\x84\xdaVRK\xcf\xdc\xa2\xaf\x9c\x04\xf8\xd8\x9a\xc9\xd3\xd2\xdc\xc7N\x0c\"\xf0\xb0\xe4\xe0\x08<\xc2\xbfw\x90\x9d\xf3\xea\xe0\xb3G\x07\x9c\xf5\xd9\x86\xfd\xfb\xf7\xee\xde\xbds\xef\x9b\xfb\xdf\xc16\x04\x843d\xf7C\xf1\xe7\xa3G\xb0\xdf>}\xeb\x0b%[{M\x87\x0bu$\xbe\xae\x8eD\x19\xa8\xc5\xef5\xceD\x91^\xa0|\xd08\x14;\x89\x9a\xec\xb6\xb1\xb0\x0c\xa3o\x0f0\xfc\x161\xa5>p<\xd82s\xf2\x93/M\xdf\xe0\xa73\xbf\xd1\xc0\xa9=\xbf\x93b\x9a\xd0 JO\x9e\xdd~\x817\xdd!:\xd3\xc1\x01\xec\xb4\xfd\xffLfN>*?\xc3\xd5\xb9\x9e>S\x99\xa8\x9c\xa3\xd1\xd2\x0c\x97{\xc7\xcb\xd53\x8d\x0b\xf6\xfc\x9a#+\x8dq\x7f\xd9\xe8n\"~\xc3\x13qn2~\xc3\xb7\xcb\xc5\x06}*Dm\x86\x15\xd9\x9d\x98\xf9:U\x96\x02.u\x8a\xa0Z\xb1\x10\x98\xf6j_\xfe\x89\x15\x8c;\xb23\xf2\x8b\xa8\xec\x8c\x9c`\xef*\xe7~t\xce\xafRDt\x04\x85VI\x15\x959\xa3\x03{J0\xef\xc9\xd1\x1eB\x0e\x07\x90\xab\xd0\xfdc=\x02x_94\x88\xd61\xc7\x81gP\xb0r\xee\xfc\"\xf2Qz\xab\xfe\x15$\xe4:\x8e\x9f\xa2\x9a\xbdW\xeb7\xe4\x9a\xe8\x89\xfd\x1b;\x0d6\xd2k\x87\x88\x82\xaa\x14]]\x0b\xa5e^\xafG\xd3\xdc\xba%\xf8\x8b\x99\x96dU\xe1\xed\xb5\xfc\x11EUmKV\xa5M\xdd\x117s^j\xc1\xe3\xd1\x00v1\x07\x85%\x90\xc8\x02(d\xbefUt\xd1\xce^\xf5\xa5<\xb4Z\xd5\x14\xc1v\xc61\x92/\xb2b\x13\xd3\xe6\xf5\x93|\xf8\x99\xf5\xaa\x12\x03%\n\xec\xc3\xd7\xea\xd7\x0e\xec\x89\x02\x03\x0e\xcb\x9f-\xf5\xa1~)\xa3\x01s\xca\xe5\xeaJ\xbe\xd8V\xd79 \xad\x8d`+\xc1R\x00b]Eh)\x17\xd1\xb30\xd4\x92\x96b\xb3\xf2\xbe\xb3\xe5+\xde{\xe4\xca\xa3\xa1C\xd4l\xb6\xf3\x06i\x84\xb0\xaa\x19\xd0~\xc7\xfe;'\xefo\x0f\xbd\x86\xfd\xac\x84l\xc6!\x1b\xc3\xff\xe5\xb2\x03\xdfz\x1c\x07\x92\x9a\x0b0\xc6\xfc\x1e\x88w\xe0\x10>\xf3\xb9\xc7\"\x1d)Zm\xd4\xcfL\xa5\x8c\xed\x02\xbf\xd3ZbIU^Q \xefm\x9c\x92\xf8\xdc\x87\xf3Rf\xb9!\xefbd8\x94C\xc7bq\x1e\xe5\xa5 \x00J\xff\x12\xc1\xcb~6EgZ\xebg\"?\x89\xe6\x9d\xef}\\\xc3\xbf\x8e\x1f\xf8\x9e\x11\xaa7\xed\xde\xe3y\xf2\xffq-\xbd\xeaK\xf5\xc7+\x1a\xb9\x90\xcd{\x0c?'l\xe6sN)\x99G\xef\xc5\x8do\x9c\xa7S\x01\x02\xed\xf1\xdbL\x96\xb5;W!\xa7\x08Uz\xd8\x89\xd27\xe87\xcb\xba-\xef\xd0q\xbd=\xfc\x8dy,\xc4 Q\x0bZ\x9a\x95\xbd\xe4\xb4\xeb\xe6\xd31T\x9d\x86\x9b\xd9l\xd8|\x95\xc3\xcd\x03\xda\x89\x96g[\x94\xd0\xaeY \xf4\xc7\x9a%A\xbf]3)\xfc\x1a\xe9J\xda\x10\xef\xbd\xac-\x9f\xb8\xf7C\xadiq\xef\x84\x18>\xbe \x86\xaf\x8fH\xf3\xf36TT~\xb9\x03\xa0m\xb8\"P_\xb4\xef?\xcd\xd2\x94 \xa4\x0f\xe0\xd4\xe0\x03\x81\x01b\x1f\x0d\x0f\xf4\xb4\x92\xefX\xfb\xb9\xc8\xcb\xb70<\x91\xa9\x02\x8f\x8c\xa3d\x07P\x18\x1e\xe8Y%\xe7\x86\xe7\xef\xc98\xcb'\x07\x90\x9b\x9e\xc5\xf4\x8c\x1c\xc0\xca0\x89\xf7dAb\xde\xa4\xe1YR\x1c\xc0\xccp\x7f\x9agsLmkK\x97|\x15\x01\xe9\x93\xcbE\x96\xb3\x02\x93\xc4 \xac\xbcr\xfb\xb4\xf5\x96\x05\x81\x82\xe5\xc9\x98i\xf9i\x94 ]\xdbn\x9a\x0f\x8d\xdeQ\xb3u\x15\xfb\x16G\xb0\x8c\xa0hn$L\xc6\x1e\xb00\x82-\xe3\x1e\xe6]\xa7m\xfa\xa7\xa5\x01C=OX&L;\xca\xf3,\x0fz\xaf\x13\x9aL\x132\x01r9&\x0b> \xc8\xc6\xe3e\x9e\x93\xc9\x03\xe0\x93d3\x024\xa3;s\xf5\xe2\x84\x9c\x03\xa1\xe7I\x9eQNu1\x02\x8b\xbf4]\xa6)\x10\xde*\xccIQ\xc4g\x04b:\x81x2Ix\xb3q\n3\x92.\xa6\xcb\x14.\xe2\x9c&\xf4\xac\xe8\xf7\x0c\x14\x9b\xa4\x05q\x90\xfc1\xe7i\x9a\xc0r\xf8\xf7L\xed\xfcfP\x07\x05\xeb\xe7d\x91\xc6c\x12\xdc\xfe\xbf\xc5\xed\xb3\xa8\x9b\xa8AE\xd8\xc6\xc3\xe9\xf6v;\x84\x17\x90\x8a\x85a\x9f\xc6s\x0c\x8dxN\xcf\xe3<\x89)\x83\x9f\x92,\xc5\xe4\xdb\x86\xfc\x92\xad;l\x96g\x17\x90\xf6\xa7y<'\xc5\x87\xec\x1dV\x91\xd9k\xa6b\xd3\xb0\xfa\xcb\x91\x98\x06w\xee\x86f\xdc\xcd\xaf\xdf\xba#K\xa2L~>!\xd3\x84\x12\x95\xfc\x9c\x8bE\xbd\x93\x13R\xbc\xce&\xcb\x94\xf4L\xa4T:I5\\\x9e0\x8f\x12\xe7\xbb\x9ef\xf3yF\x8f.\x19\xa1\x85\xcc\x7f\x8e\xf7\x1bwH1\x8e\x17XS\xf1UB?\xbd\x8b\xb1\xae\xa2J\x9d\xdf\xba]\xcc\xe24\xcd.\x8e>/\xe3TV#d\xfd\xd3e\x92N\xbe\xcf\xf2\xf9\xb3\x98\xc5\xe2\xb5,g$\x97OY&o\x92<\x89\xd3\xe4\x0frL\xe2|,\xda[\xc4y\xa1\xff>#\xec8\x9e/Rr<\x9e\x91\xb9\xf8\xee\xaf\x17\xc7o\xdf\x88\x9d\xd1\xe9\x01\xc6\xf2U\x07\xb3\x8c\xb6*D5\xab\x8eF\xe8\xa8o\xdd\x82^\x86\xbd\xf6D\x11\xb2\x86\xb1\xa0\xb7\xa4b\x9fNzp\x00\\\x82*\xf8\xc6\x8d\x97)\x0b\x03\x16\x86\x8ex\xd7+\x18\xc7l<\x03q8\xb6\x1e\xcb\xef\x1a\xd9\x1b\xae\xf8^\x16\x03J\xa6\xabNH\xc8F\x8e\x05\xc3|$\xf9f-\xa9<\x1c4\xfb\xc6\x1e\xe2<\x8fW\x1bt@d\xb3\xe8]\xa3\xff-\xeaI\n+\xefp\xd4\xeeH\xb0%\x92O\xd2z\x03b\x0eM\xe3\xabr\x84\x1eT\n\xae\xe6\xb3\x9eAB\x0b\x16\xd31\xc9\xa6\xb0RK\xd2\xe7[\xd2\xf5i /\xc6\x01U\xcf\x86\x8b\xb7\xd2\xb2)\xce\xb8\xcb\xb4\xbc$\xec\x8b\x8c\xce8\xdb\xea\x95\x8a\xd9\xac\xde4\xd5Nd\x98`\xf0Cv\xcc<\x0b\x05)\x15\xa3)\x87\xbb\xd2\xfd\xecF\xb0\xacP\x91\xb4\xb3\xf3v [\xe6\xf0\xc5!3$\xe80\x14\xbe\xeb*\xc6N\x879\x17\x0f\xc90\x1f\x89\xf4\x8at\x99\xa6fMt+\x13&\x82\x8cf\xf9\x1c\x0f\x0f\x81s\x03\xb8\x8c\x90N|O}\x91\xd6<\xc1vOIQ\xd2\x9dc\xd9\xc7\x92\x8eo\xbe\x175\x11\xaff\x9b\x99\x9a\x8dT\xe2u\xbc\xf0A'+\xca4\x93\xfa\xba\xf4\xa2\xf5ue\x01_Y\xa1\x8a5\xe5\xee\x84?\xdb\xa5\x84p\xc8\xef\xb1\xcb\x7f\xdb\xa8K\xc5x9^\xa7\xee$s\x1e\x08Y\xd7\x81 U\xda\xfcn\\\xdd\xa5\x18r\xb1\x01\x98\x8aU\xc1\xc8\xfc\xc3lI?\xbdN&\x93\x94\\\xc49\xf1E\x9c\xee\xfd\xcf\xfa\x93\xa4X\xf0\xb3I2\x8eH\x97\x9cp\xe9n\xd4\xf4\xb2\xd3\x82\x05\x1d[\x08\xcd\x93\x01 0\x959\x0b,\xbel`\x14#\xccw\x0d\xe7\xa0\\#\x0e\x80e\xf14\x9btC\xf9\xbcL\xb2\xa5\xaal[I4+55\xc1\x05?[.\xf8D\xfc\x93\xa8+\xe0\xec\xf7Ty\xd4m\xe8\xf5Bc\x06\xa5\x10\x19pK0\xf3\x95\\f~\x82\xf9l<\x8c\xce\xa9N9\xa5\xc0\xe1\xbc\xa7\xfc3\xd0\x8a)V/\x8a\x13\xb2\x0d\x0eu\x9a\x11\x99\x83\xc0p\xec2\xce>\xb0\x91\x1d\x96\xf5^\xfaI\x81\x9dQ\x91\xf8\xfe\xa05\x88\xf6\xfcg\xc9\xd9,M\xcef\xdd\xdc\xa5Z\xe1I6Fu\xab\x99\x01\xd9\xaa\xf8\x8c\x9e!s\xaf\x08N`\xe4\x92=\xcd(#\x94\xa94\xac\x8f\xe0\x1e\xb9S\xc5\x03\xe9\xafX'\xdf\x8d+\xb5\xec0\xba\xd2@\xa4\x83\xab\xfa\x88\x90\x0b\xdf\x8dP=\xb2\x1c\xee\x8e\"\xd44\xecE\xa8@ \xfd\x84R\x92\xff\xf8\xe1\xf5+\x91q\x18\x16\xa8V\x10r\xb2\xa8g\xbb\x80\x87\xf0\x0d\x92\xc9\xdf~\xc3\xfdJ\xa5\xe7\xdc\xd8\x99m\x86\x03\x84\xf7\x94\xaa\xae\xb7\xb7\x8b\x910\xafM+\xd8\xecE\xb05\x86\xf5\x1a\x16\xf0\x08\xbe\x15\xbd\x08\xaa\x80w\x87\xb7\x7f;\xbe\xddg\xa4`\xc18\x8c\xf8\xdb\xfc\x83\xdb\xc3\xaf~\xbb\x18i\xf7\x83\xdem9\xb2\xf5\xbal\x80\"iN\"\xf8[\xefo\xa0\xdcN\x92\x08z\x7f\xeb\xe9?\x97\xc3\x02v\xe0\xee\x08\xb6\xd1)\x9e\xf2g\xbd\x9d\x9d\xdf.\xefp\x99\xbc\xba\xf5\xf5\xed\xdeh\xb8\x18\xb9\x8de\xb8,SQ\x98\xa1\x1f/\x16\x84N\x9e\xce\x92t\x12\xc4\x9a\xc8}\x94\x12\x8efA\xafX\xc4\xb4\x17\x86\xfd\x82\xb0\xc7\x8c\xe5\xc9\xe9\x92\x91\xa0W\xb0\x15\xaa\x03\x86\xbdq\x96f\xf9\x01\xfc\x9f{\xf7\xee=\x80iF\xd9\xce\x05\x11 qO\xb3t\xf2\xa0\x17\xe1\x8a\xe1\x7f\xfa\xabxo4\\\xc0!\xae\xdd\x1d8\x84}8@\x08\xdf\x87C\xb8+\xff\xe6\xf7\xef\xc0\x01l\xdf\xfeW\x10\x07\xa7\x05\xcb\xe31[\xa7I\\\xac\xe9d\xadL\x0fk\xbeg\xd7E0_\x17$g\xe1\xe1z\xc9\xb2p}\x1a\xc4\x05Y\x93\xb3\x84\xae\xb3,\x0dHL\xc3\xc3uN\xe2O\xeb\x15#\xe1z\x8c\x8f\xf9\x81\xb3\x9e\xc5\xf9\x1aE\xdb\xc9:\x8d\x8bb\x9df\x94\xac\xb3\xf9\"]g\xb4`\xeb\x8c\xb2\x84.I\xb8\x9e\x90\xe0tyvF\xf2\xf58\x99\xc7\xe9z\x9c\xc69YO\x03\xbe\xc7\xd7$\x0f\x0f\xd7 M\xd8:\x0d\xc8Y\xcc\xc8\x9a0\x12\x1e\x86\xebI\xb6\x9ed\xcb\xd3\x94\xacI0\x9ee\xeb\xb48L\xa6\xeb\xb4 A2\x0d\x0f\xf9<\xb0\xf6\xe8\x9a.\xe7\xebsB\xd9\xfa2\x18\x93\x05[\x93\xf1z\x11\xa4\xc98a\xeb,g\xe1\x9a\x91\x80N\x8a5*M\xd69\x0d\xc3\x90w\x9d\xa6l\x96g\xcb\xb3\xd9:N\x0b\xb2Nh\x9c\x06\xe9\x8a\x0f\xe5\x92O'\x8b\xf9\xd7\x01\x89\xc73>\xfb\x84p\xb0e\xf3\xf5\x92\x8e\x03\xbe{\xf9\x00\xcf\xd2\xec4N\xd7g\x19\xcb\xd6g\xcb8\x9f\xac\x93`\xba\x9e/\x02\x81\x03\xc5Z\x1b\x04\x0d\x12\xb6F\x95~p\x92\xd11 \x0f\xd7i\xc2\xa1\xb5dk%\xfa\xacY@\xf2i<&k\x92\xd38\x0d\x0f\xc3\xc3u\x11\xae\xd3 \x9e\x9fN\xe25a\xebl\xfci\x9d\xd1\xb3p=\x0f\x92q\x9e! \\\xa3\x8ai-\xd4\x08\xe1\xfaM\xfcfM\x83xN\x8a\x05o)f\xc99Y\x93K\xb6&\x17\xeb$]gl\xbdL\xd3p\x9d\x05\xc8\x16\xad\x17\xc2\x10\xbe\xce\xd7K\xb6>'y\x9eLH\xb8^\x04\xf1\xf8S|F\xd6q\x1e\xcf\x8bu\x9e\x9c\xf3u\xc93F\xc6\x8cp@\xb0l\x9c\xa5\xeb\xe5i\x9a\x8c\xc3u\x1e\xc4 \xc7\x98 \x9ed4]\xf1\x85\x9b\xae\xcf\x92\x82\x91|\xbd 1[\x7f^&y5\xefb\xbc$k\xa1b[\xb3|\xb5\xe6T1\x0c\xd7Ep\xba\xe2\x8b\x1f\xa7d\xb2&\xe9t=\xcbr\xb6N\xce(\x99\xac\x93?\x10<1K\xc6kT\xe7\xacY\xbe\x1c\xb3\xf5\xf2\xb4\x18\xe7\xc9\x82\xad\x97\x0b\x92\xafWt<\xcb3\x9a\xfcA&\xeb\x8b\x84\x8dg!\x87\xe8|\x91\xf2\xc1\xcf\x08]\xcf\x92b=\xcb\xb3\x8b\xe2p\x9d\xc7\xb4H8\xd2\xe4K\xb2\xceW\xeb\xd5\x82\x041\xee\x8f \x99\xae\x93\xc9\x9a\xc6s\xb2\xce\xa6a\xb8^\x064\x18K4\x9f\x90i\xc0\xd9E\x8e'\x19]\xa7\xa4(\xd6\x85\x18#K\xd2p]\x90u\x91\xf0\x05:\x0f\xe2|\x9d\xe4l\x19\xa7\xeb,\x99\xacQm\xca\xd7\xe7\"\x18\xcf\xe2\xfc\x84\x89\x01\x91\x9c\xacgIJ\xd6 \x9b\x85\xeb\xcb,_\xaf\x12\x92N\xc2\xaf$\x01\x9cr~iw\x14r\x16T'9\x8a\xdc| \x97\xecM6!\xc14\x0cC\x91Al\xc1)\x94\xa0\xeb\x9cF\x1c\xf0\xf3c\xaa\x1d\x00{{\x0f`k\xb8\x17\xc1\xed\xe1o\xb7\xff\xbc\x1a\x06\xbf\xedl\x7f=x\xf8\xe8\xe0\xc1\xfa\xb7\xdf\xfa\xd1\xe1\xd6\xad\xbf\xff\xfft\xfa{{\xf8\xdb(\xac\xdfhPhI\xa0\xc7\xbc\xe3\x0cS\x93sR\xff\xb0\x07[x\xceH\x12=.\xa9\xf3\x98\x1fS\xdb\x90\xc26\x12\xe8m\xd8\x1b\x95\x7f\xee\x8f\x90 \xffvyg\xbc\xb5\xb3\xd3So\xf2{\xb7\xbf\xae\xff\xbc\xcdi\xe1\xff\x11-\x8e\x86;;\x8b\xd1\x03\x87\x07\xcf\x14\xb6\x070\xf6e.\x8d2\xda<^|\xc8\x1a|\x97M\xf5as\xb1\xe4\xc7b#\xc9~\xf9\xcapo\x04\x87\xf5\x9f\x07\xd0\xfbDV\x06\x96D)\x06\x0d\xed\xef[\xdb\xdf\xaf\xb7\xbf?\xaa1[\xaf\xe3\x85\x89\xe1k0\x90\xaf\xe3E?)\x84\x96\x04=\x81\x84\xf7\xc3\x06\x1cd\x9dc\xa4\xa2\x82\x0dE\x0b\x89\x89g\xe4\xfd\xd3*\xef\xfd^\xa5\x11\xea\xcfI~F\x02\x93\x14x.\xa3\xe5\xbbG\xc3\xdf\xe4\x8c\x155V\x07\xe2O\x0bK\xf4\xbc2\xecl\xed\x99\x9fM-:]p*=K\xe6o\x11\xc1\x04\x06(~&\x9a\x96RE\x06\x04!\xa6 \xe4\x83\x0b\xf8\xb6\x9e\xd4\x1c\x85\xc2\x07r\xd8..\x8e\xf72\xe3\x14\xc3'8\xfd\\\x8e%\xab\xc62C\x17Y\xe7Ws\x0e\x83\xceP\xf63|k\xaf\xe3\xad\x15\xe7i\x83\xb3\x08h\x99m'\x82\x9c3X\xc12\x82yS\x0d\xad_mTPB\xc7\x8a\x0b\x1d\xb1r\xfe\xc0\xec\x87\xb1H\x9a\xb72s\x83\x06b\xa1\xab\x86\x8d\xdf\x8c\xa5k\x05r\xe5\x86\xef\xa7\x9c\xfbHm\x18a\xc7\x15~ma \xdeI_n\n\xedo[\xe2\xe6\x8e\xee@\xf1\xf7\xa14\xe0M}\xe1\xd0\xba#\xc7\x14\xb7I)\xb9D\x8e\xf4\xfb$%o\xe29\xf9>\xcf\xe6R\xa6y\x96\x14\x8b\xac@\xe3\xeb\x8f$\x9ex\x94\x95W\"\xde\xedi\x92\x12~l\x0fz\xc1\xf0_\x0fF_\x87\x0f\x0e{\xb7\x93>\xb9$c\xa3\xe1\x00\xcb\x9e\x08\xdb\x00g\xea\xebm\x94MT-\xd8\x88\x93\xaa\x9e\x82\xcdh\xb2\xa1F\xaa\x8c\xf9\x19\x94\x12n\x99\xa6m\x08-\xe2b\x1c\xa7O\xe3\x82\xc0\x00\x9e\xd6\xef|/\x07\xd9 \x1a\xd9\xc3\xd3\x80Tf\xe2\xdf\xfa\xc3\x7f\xf5o\x8f\xbe\xfe\xea6\x17%B\x93\xc6*\xa6 K\xfe \x1f\xf3\xb4\xb3\x07\x0e\x802vlK\x8b\x1d\xe3\xc2\x9a\xd0u\xb8ekM18\xd6{\x0e\x8dG\xf0\x19a\x8f\xc7\x9c\xcb\xe7\xd8\x92gi\x9a\xd0\xb3\xf7\xa4Xd\xb4\xe8\x86F\xe3$\xab\x14\xfe\xfd\xa4\xd0\xb4\xff\x9a:\x84/\x8dMcP?\xf6\xccoV\xfa\xa5\xbaCx\x97Wry\xc2\x15,\xceY\xf1s\xc2fAo\xbfW\xea#u\x15*:\xe9\xf5\xc6b\xf7\xf4\xf04\xfd\xf3*\xac\xb0\xd0V\xa8\xc1LlK\xd5N\xd0\x93]\x88&\x8dv\x12K\x1b|\xcb\x06\xd40.s#a\xa9|\x93\xa6.5v\xa1\x0d2CVA\x887\x9b\xb7\xf1dB\xc8\"]\x1d\xb3\x8e\xbaLmJ\xf3\xdeP\x86\xffye\x0eLi\xe0hf09\xd9\x15\xdaU\x1cQ\x1edC6\xc2\xbdr\x08\x13\x92\x12F\x80\xdf\xe1B\x0d\xff\x87\xf3\x03\xe2\x0dj\xcce`\xcaV\xabl\x03\x06\xb2\xa7\xa2!\xbd\x08\x89)`\xd6\x95\x19HV We=\x95Y\xd7r\xa6X\xad\x16\xa4k\xc1\x89\xb0Z\x94\x87\x12 \x1d\x0c\x84F|s\xad\x89\x08\x84}o\xdf\x00R\xc5\xect\x19$\xcdQ\xc2\xe0\xe2\x13\x88#\x15\x03\xebS\xf4\xbd\xf8\x90\x95\xfe\x1c\x1ek$\xbe\xb1\xac\x91\xd6\x9b\x15M\x1a\xa6\xbf\xfa{\xe7\xb2\x92\xe7I@\x83oL>\x12ctH\xba\xf7\xcd\x9e\xe1\xd9T~x\xef\x1b\xa3{\xc5B\xb9f|\xbbkz<)\x1f\xdf5=\x9e\x95\x8f\x8d\xe3:\x97\x8f\xef\xdf36>W.%\xbb\xf7L\x8f\xcfpV{\xdf\x99x\xff\x95\xfc\xf4\x8eqR\xa7\nX\xfbw8\xe2\xd7\x9e\x97\x04\xfa\xa4\xc3w\xe1\xd6-\x0c\xe1P\xbeU\xd2\xb5\xd8\x8c\x8b\x12\xa5M\xa5\xea\x9bQ\xf3\xfa/\xbe\xb0\x170\x80\xf2\x08lO\xe5\xc8\xe0\xc0\xd3\xad\xd9o\xc9\xc8fsL{\xb06`]ndv\xae\n\x047&on\xfc\xd8\xd9\xf8\xd6\x16q\xdaW}(\x95c\x0dtO\xa9\x89\xfa\xc8\x06\x86\xa7\xce\x91\xf2~\x17U\xbf\xfc\xe7\xd4\x7f\x18u\x07\xaeN\x16\xce\xa1\xf8\xd9\x8c\x8b\x18Z\xc4a\x0b\x8br\xc7\xda\xf8\x9dz\xe3wD\xe3NN\xbcn\xa2\x97} \xefQ\x7f\xc8\xca\x87\xeb5 `\xcfk\xc7\x88\x0e-\xab\xfd\x18\x9d\x84\xab\xfc\xdf\xb4b\xbfM\x9a\x15\xd0\xfd\x00\x86\xd4\x92\xf6\xces\xa3\xc1!h\x02AR\x04\x182\xc5Q\xd5\xcaq\xf9\xa05\n?\xb6\x06|\xfc\x0e\xf0\x08'\xf8i\xd6&\x06\x82{k\xd4l\xeb*`\xb3\xc5{\x99k\xc3\x1cR\xceY\x0d\xa9\xc1\xeau\xd5\xdc\x12\xeds\xef\x93\xc5\xe1\xb1s\x7f\x80\xb2\xa7\xc2#\xa8\xc2\xc4{?\xc5\xe9\x92\xc0|Y08%\x90\x92\xa2\x006\x8b)\xc8\x96\xbd\xca\xd9?\xb68fn0\xa6\x87\xf61\x9d\xa1\xc2=\x97\xc3\x12\x8d{\x0d\xeb\xad\xd9\x85\xb4\xfb\xb4@9\xf3\xf6\xbfv\x0e\x7f\x9bl\x07\xbf\xf5\xf9?\xe1\xa1\xb2\x0chRjc\xa01H\xb6\xc7gp\xef,>\xaf\x9b\x8d\xcecP\x14#\x01\xcf<\x87\xf5\xc1\xe4\x9b\xeb7&<\x95\xb6\x02\xe2\xf0)\xb4Cn\x9a\xa4\xc4k\x80\xaf-\x0e\xc5~c\xec\xb1|Iz\xb2n0?D\xa7qZ\xe87\xb6v\xb5\xbf\xf7\x14#o\x1b\xf5\xa9\xe8\xdek\xe0\xcf\xcd\xce\xd1~\xe3\x16\x835\xa8{\xecc\x93/\xfb\x0c\xedw\x9b3\xb7\xdf\xe0\x92\xe2M\xfc&\xe0\x9f\x95\xce\xc2\x8e\x95V\xcd{\x8d\xec\x8d\xc9\xef\xdcoTJ\xd8S\xa2F\x9fe\xaf\xb2\x0b\x92?\x8d\x0b\x12\x84\x11l\xdd\xfe\xd7\xf0\xcf`t8\xdc\xdd\xf9.\xde\x99\x8e\xfe\xfc\xf6j\xa7\xfc\xfb\xae\xc7\xdf{\xfbW\xc3\xf0j\xe4E\x18\xf8\xc8\xbd&\xfc\xde\xea~\xefOL+\xde\xc4\x8f\xce\x8b.\xbc\x86\xf7\xcc\x1a3\xb0\xf9\xf06 \xf9\x1b\x8c\xf0\x95%\xd2\xc1{|[\x94\\\xc0{rvt\x89\xfe\xc8\xae\xa5\x9dfi\x9a]\xc0Bv\xd2\x83m\x93\x03{\xfd\x0co\xc7et\x8e\xec\xba\x9c\xed\xad[\xb5\xdfv\xae\xd6\xc6\xf1\"\xab\x87\x94\xe74\x9b\xac\xa4RY\xa8\x17\x13\xda\x13N\xf2\xf8\x0b\xcdX'\x97\xf3\xb4\x87\xee\xf2\xda\xcd\x9eEU\x99T\xea\xce\x9c\xa0\x9b\xc2\xc4\xf6j\x0c\xc2;J\xbe^`\x84\x8b\xe8\xc8\xa2\"\x8e\xcb\xd5\xca\xedv\xc7X47\x97|\x8e\xa5\xf3\xb1\xf6\xa6d=,oN\xab79q\xb6\xbd\xb6\xa8^\x9bf\xf9\x8f\xe0,\x82\xd3\x08N\"\xb8\x88\xe0(\x82\xcb\x08\x8eG\x0d\xe1\xd59\xf6J\xdfd|\xc5V\x92\x0eYB\xe4\x9f\x9f\x86\xcd\xb9\xbf\x97\xb4\x1e\xa6 I'\x90\x14@3\x06\x8b<;O&x\x02\x98(\xb6j\xf4\xdc5X>\xf1\x8f0\x80WA\x16\xc1\xb9\xc3%\xe1#\x1a8\xc4x>\xfa\xba\x1a\x80\x1c\xc2\xa4\xda:\x93\xae\xd1|\x86\x01\xbc\xe7\xa3\x998F\xf3Y\x1b\xcd\xe7MG3\xeb\x1a\xc2\xf70\x80g|\x083\xc7\x10\xbe\xd7\x86\xf0\xfd\xa6CXV\x00q\x96\x1d\xe1\xa3\xf9\x03S]a\x91\x11\xfbh\xfe\xd0F\xf3\xc7\xa6\xa3\x19W\xa3\x19w\x8d\xe6 \x0c\xe01\x1f\xcd\xd81\x9a'\xdah\x9el:\x9a\xfa\x91\xd85\x9e\x9f\x1c^K\xeaB\xee&\xf8 5\xe41#;\x8c\xcbQ\xd8\xfc\x02\x0e\xe1\xf7\x00Uh\xbd%\x176\xca\xbbo\xc4\xdd\xe7\x82\x88\xda\xf9\"u\xc9\xd9\xfedsb\xa9\xc8l\xfd`\xeb\x9a\xdf\x8f0\x80\xd7\x81\xab\xda\n\xce\xee\xc7\x0d\xc6\xf8c\xf7\x18k\x87g\xd7\x10\x7f\x86\x01\xbc\xed\x1e\xe2\xcf\x1b\x0c\xf1\xe7\xee!\xd6O\xe8\xae1\xbe\xc0\xec\x8d\x9dc|\xb1\xc1\x18_t\x8fQg\xb0\xbaF\xf8k\xc7\xd0N\x91\xf9)\xd90\x9f\x81\xfe\xaax\xd6\xe74\x18\xf6\x12F\xe6E/\x02\xc1g\x8f0\xc9N\xcb\xcc\xdd\xe5\xe9\x01\x9a`\xd5\xb5\xed\xf8U\xc3\xa4_\xd1E\x82#\x0b\x86\xaa\xd6\x97P=|'\x1f\xeaT\xe0Wd\xc0\xf8\xd3\xe7\\\xa8\x8c\xa4\xb9]\xac\x83{\xb0\xfcJDVKC\xde\x95\xe6\x85\x995\x0e,\x99\xc4\xd4\xe5\xac7\xdb\x89\x13\x1a\x83\xdc\x85\x12/a\x00\x1f\xba\x91\xf6\xa5\x0f.H`\xbd\xf4\xa5\xc6V\xab\xb7\xc1{\xa5\x9dF\xc1\xcd))7\xa3/w66X:Az\x05m*\xf6\xb7\x0cZ\xa6\xf8g\x0e\xef\xdb\x97\xf3T\xea\xae\x98U\xbeK\x84\xcf\xd5\xe5<\xc5m\x8b\x7fa~\x12\xd7\x9a\x0b=\x0f\xff\x86K\xf9\xf2\xdb?\xaf\"\xfe\xfdW_\xe5d\xaa;\x03\xac\x16\xe8\xb4F\xfa\xb8\xaf\xc5\x9f\x0b\x91\xcf#!\xf2w\x95\x16\xe6]\xf5\xe4\x10\xfe\xf6\xf0\x907~N\xf2\"\xc9\xe8\xa0\xb7\xd7\xdf\xed\x01\xa1\xe3l\x92\xd0\xb3A\xef\xe3\x87\xefw\xbe\xed\x1d>\xfa\x8dJ\xb7v\xf8\xe5\xf5+ \x97\xb8\xc40\x8e)g>O \x9c\x11\x8a\xc9\x19' B\x94\xfef\xf5~R\xd7yY^\n\xa7\xd3\x9fsQ \xb8\xfd\xdb\xf1\xd7\xbf\xdd\x0e~;\xde\x0e\xbf\xba\xed@\xf6\n\x88\xb2\x84\x94'*C\xddXx\xa6,\xb5\x93\xa7\xa8/\xfb\xe5\xf5\xab#17\xe1J\xe2\xe3\x01r.\xcb\xaa\xd5\xdb\x13\x9b\xe0\xfb<\x9b\x8b\x8d \xdbk\xcfH)\xc5l\x92]\xd2%\xd9%a\x08\x87M?\x98\xa4\xf2\x83\x81\x83F\x8eJ\xe9\xa3\xa9\xa7?q\xba}\x9d\xcb\xcc\x86\x7f\x1at\x85 \x93\x17V\xe2|\x9a\x8d1\xcbN\xbf\xc0\xc6-\xfa\xa5Joi\xdbZ=\xa1\xa4w)MD\x16\x94byZ\xb0<\xd8\x0b\xfb\xc5\"MX\xd0\xbbe\xd2\xc6\x80\xee\x9f\x9eCB\x81\x86@\xfb\xb3\xb8x{A\xcb\xdc7\xb9pS\xc4(\xc3a>R-\x0e\xb8XE\x86\x132\xce&\xe4\xe3\xfb\xe7O\xb3\xf9\"\xa3\x84\xb2 \x1f\xee\x8e\xc2\x11\x0c \xe7T\xe8\xd6-0\xbe\xb37\x12v\xd5\x9e\x0f>\xa9m\xdd^\xb3v\x1a\x1b7m\xb5Z\xc5\xfd\xca\x97\xab\x81\xd0\xd6\x8cD\xca\xfdA\x0f\xb6MO\xc9\x90\x19\x0d\xb3\xfd\xdf\xb3\x84\xe2\xf2\xb4\xa7&S\xf5\xb8\x07\xa5\xe6S\xcb\xb9\xa1r\x17Sr\x01$`\x9a\xb9\"\x82\xde\x92Mw\xbe\xed\x85au\xb7w\x1a\x17\xe4\xfe]\xd3\x18\xaa\xd4A\xed\xae3\x0c6K2Z\x1c\xe3[6\xaf\x9d8]\xccb\xcf\\\x83\xa0\xbb\x8f)m\xe2\xac\x17\xe2\x16J \x07h\x9c\xf3)i\xcf,G\xb6yc\xce \x9be\x93k\x8fF|n\x1b\x8fz\xea\xcdD\xb4\xc7\xc8\xe2\xb3\xbf\n\x9c\x8d!{\x0f\xd2\x80\x99\x8d\x14S~\xec\x8c\xc9I\xa5\x8a\x8d\xe6\xe4\xc7z\xfa+_^b\xf5\x10\xd1\xd8\x96\x1c5\x88\xbd\xeao&x\xbb!\x8d\xf8\x06\x8dL\xfb3\x0f\xb5\xc4k\xfb\xbb\xb7\xcf\"\xe8m\xf7\xc2\x91\xdc\x9f\xa6%\xb5R)\xe6\xda\xd4\x86\x94]\xb5\x95\xb48\xd6\x94J3N\xb8f\x15\xe1\xa2\x9aSN\x97\xcb\xc8F\x1e#\xf5\x91\xd7a\xae\x94b\x96\xbcd^\x04\xd8X\xa0\x063\x8ektL\x9a\xb31\xa5Q\x9e\xcc\x03m\x91~\xc3\xecx\xbd\x13\xb4\xd8\xf4z\xae\xe1Z\xb2\xaay\x0d\x93\xc3\xec\xb4\x82\xd9\xc7\xb6{Yd\xc8\xe3\xe6\xd54ig\x9b\xe8N\xc2z\xfb_\x97;%s\xdd\xb9l\x915\xf7\xdc_9Bi\xffY\x97\xf6\xa5ui=ZK\xbb\xd8ZZ\xbd\xfc\xa7\xf2?\xd5\x83\xb2\x90\x16\x0d\xee\xdd\x0d\xfbO\x96\xd3)\x91\xde\xe2\xd7\xca\x06hN\x88\xd9\x9cfI\xa9\x8c\x92\x99\xc8\x15\x0f\xff\x7f\xf2\xde\xbc\xbbm\x1cK\x14\xff\xbf?\xc55\xa7_\x8a,\xd3\xb4$\xaf\x91\xedx\xb28\xdd\x99\xc9\xf6b\xa7\xea\xd7\xa3\xf2xh\n\x92\xd8\xa1H\x15\x17;\xae\xb2\xe7\xb3\xff\x0e.\x00\x12\x04\x01\x92rR\xd3\xfd\xde\xe3\xc9\x89E\x12\xc4r\x01\\\xdc\xfd\x9e@\x15\xcb\xf2\x13\xf1\x83\x9c\xc7\xa2\xfc\x17$\x0b(\x81p\x047a\x16\xe6\xb0\xc8\xf3\xd5x{{\xe6\x07\xe4:I\xbex\xf30_\x14\xd7^\x98l\xa7\xf4\xbb\xedi\x12d\xdb\xf8\xf1\x16#\x9fRo\x91/\xa3\xd3P\xc4nd\x94\x86\xcb\xf3\xb9A\n\xc7\x90\x1fA\xba\xb9\xe9@\x0c\x9b'`=\xf1\xd3y6\xb94Q$\x157\x97\xa2\xcb\xaeB\x1f\xb2:\xeaq5ED\xcd$\xed\x1f\x94\xb3\n\xc8\x99uG\xe2l\xa2\x99\xa4\x16\x1dS\xe5\x15\x98C[\xd2\x1a\xd8\x12\xc58j\xc4\xca\xca\n\xef\xbb\xc4\xa8'\x14\xd8\xe7\xa4\x1f\xac\x932\x1a\xf1#\x9a\xacB\x19\xcbcf\x1d\xa8nz\xf5#\xcb\xfd\xe0\xcb#\xba\x80\x11\x98\xd9\xb8\xe9/:r\xfa\xb7W\x9b!\xb7\xd0}D\xb3\xc2\xb8\x17[\xd6\x18\xfd\xf6j?\xc5H\xcfk\xb5^\xd4\xb3\xbd\x88\xa8=\xad\xca\xa8\xf2\x84\xc84'\x04\x8b\xac\xc3\x8c\x102x\x06{p\n\x19l\xc1\x1e\x8c1\xf3R\x00'\xb0w\x04\x01\x1cCv\x04\x01E\xe3\xd1$\xa0\x05.\xe5\xda&AKb\xf0\x1b\xee\xa5n\xb6\xa3\x86R\xdb3\x93\xe9\xac\xd4c\xc1\xb0\x8d\xe2:q\xd1\x16\xd0\xd4\xc4\x9eux\x8a\x03\xb75 \xdb\xe5\xdf\x1c\xdcR,h\x8a\xc3\xa3p\x8afOSzb\xc2\x7f\xd1\x9f\x05\xfd\xf9_\x90\xcc\x90Zd\xcfV\xecYV\xacV\x11=\x7f\xf2\x84=O\xf0\xb9\x0b\xe4\xeb\n\x03\x9c\x80\x1fC\xe9\xd8\xe1\xfd=\xe3\xa1\xbf=\x8d\xe8A\\z)\x19\xc8\xb3\xbch\xe5X\xc4EK\xde \xe7\xb2\xe8H\xe9\xde\xa9\x8b\x16\x97\xb0\x8d\x99\x95\xd9\x03\xdb\xacN\xe4\x0b\x1d\xf3y\x1eJ\x91~h\xb2taQ\xaeo\n9\x8f\xc2pQfP\x88\xda<\xf1\xc5E;?/\xe5W\xf3\xd6\xf2f\xd8\x1a\x82\xc5\xf5\xda\xe4\xd9\xc2_\x911\xac\x9aoD\xa07\xed\xcb\xa5\xbfzY\xbe\xef\x8d\x1ef\x88\x9c\x1ew\x06F\x18\xe5>\xb3\xf5\xe7\xb6\xb6\x87X\xbc\xd9Z\xdb\xf9\x8a\x9f\xf4<+\xb5'#V\xd0<\xeb\xdaN6\xb9\xcd\xae\xb3\xcap2\xb1V\x0dg\x8d\xae\x9f\xbf\xf2~\xfe\xca\xfb\xf9+\xf6\xf3WM\xd9\x94\xc7\xfb\xcfl\x8b\xed\x7f\xcb\xed?\xe1D\x87.\x9b\xb3\xadi6,S,d\xf6\x9a\xc7\x99\xec&&z\n~\xb3\xaf\x82+\x11|t}\xbb\xf2\x11h\x9c\xc7\x84\xfeu\\\x1f\x1e\xb3R\xa5\xef\x85\xfc}\xac\x8e_\xf4\x97\x16\xaa0+r\x1ae\xcen\xbb\x14>\x03\x06F\xac\x05\xdf}\xd0\x8c\xac\xd00]\xe2]\xce\x8f\xe1\xb4\x0c\x9e\xa7\x9b\xb0\xb5N\xe0}~\x02\xefK'\xf0\xbe\xee\x04\xde\xef>\x81\x05\xd5\x00'\x80\xa6+)\x0b\x9e\xc7\x8c\x1c]\xe1\xbd\xcb\xe2\xb3\x9e\x02QQpm`2\xe2\xe5\xc9\xe8\xa5\xe3\xb14u\xa2\xc0\xf6\x1b\xe7\xe3\xad\xcfl\x9f\xb2\x15 \x18S\x16\xc6\xac@\x88\x05<\x94\x97\xb0\x86\xebk\xad\xb1\xa2\x98&A\n\x0f\xbc1t\xb4++\xf6\xc2\xac\xec\x96\xfa\xcd\xa0\x16\\U7\xed\x99\x96\xfco\xd2ar\xf4D\xed\xec\x8b\x89\xa7P6\xa9X\xec\xac\xd5\xe44B\xda\xa6#\x87\x8f\x81X \xdb\x89\x95\xa8/\xb1\xf2_\xa5\xac\xe0\xbft\x14\x8aQ\xec\xd8\x8c;\xe2\xb4\xc2=2\xc9\x1b\x9b\xa0\xaf\xe0\xaeI\n\x02\xf2\xc6\x8b\xb4\x1b/(7^\xc4I\xdfH\"}g\x8c\xf4\x9d\xc11DG0\xa3\x1b/\x98\xcc\x9a\xa4\xef\xcc\x10\xd0i\x85\xaa\xa6\xc44\xe7\xb1\xbdj\x9ds\xbaf\x0b3\xfd\x84F\xd0\xf6\xeaQKB\xa2_3\xcd\x92X\x18\x96D\xd8E\xbf\xa2K\x00#\xd5\xfa,\x10fW\xc1'S\xef\xe7\xa3\x19\x00-#\x1ce\x0d]\xc4y_\xa5\xc9\xea\xa2\x1cS\xd6\xe8{\xb9\xe2\xb4\x99V\xca\x95s\x83\x91\xab\xca\xc8\xf5.\x92\xb8\x03\x97\xd3\xac<\xa1-,\xe1\x18\xe6G\xb0\xa4\x8b\xc4<\xa5\x18ZJE\xb27.,\xcbEL{9\xa1\xfd]\xd2_\x97V\x89t\x03\x13\xb5K\x81x'\x9f\x82\x08\xae\x12\x80w\x1d\xf3\xd0\xb1\x19\x85xC\x17.\xbb\xb9\x1f[\xb7`\xa2\xdd\x82a\xb9\x05\x13\xc7\xe5 \x10\xc1\x87cH\x8e\xc0\xa7\xd0\x0c'~}\xbb\xf9\xe6s\x0eQ\x07vU\x01r\x88:]\x16\x7f \xf3\x8d\xb8r\xb7\xab!\xa2[\xae~\xfe\xcaq\x84\xdaq\xf8\xe58B\x8eJB \x95\x14\x0c\x95\x14p\x0c\xe1\x11\x14t\\\xfe\xa4h\xa2\x92\xc2\xa4E\xe2(\x8cLrC \xe3^\xca\xda\xf6\xd2\x17r\x97]H\xfb\xc9NV\\\x08\x9a\x91 \x89\xa7e\xd7\x9c\xe6V\x8bM[\xad\xc9\xe6\xb6o5\x90\xa1\x8b\xe1~\xe5H=\xe5\xbe\x9b\xb1}G\xb1jP\xee;\x8a\x9cW\x1c9\x9b9T\x81N3u\xef\x05.\xcc\xca\x99G\xa4\xb8\xf5\x8c\x02\xc5\xa6\xe3\x08&\xb3K\xfa\xcc\xa9v\xa1\xdf\xc6s2\x8bi\xe3Nl\x92\xe5\xa0\xc5\x8a\x0fNs\xf5\xea\x0f\x98l\x9d\x9d<3\xd3\xe7\x92\x05\x8bb\xb7U1\x060\xae\xbdk\x9eK\xb1\xa9\"\xb4\xd1\xd2r\x15\xb5:G\x97Z\"\xee\xff\xa5\xd3\xfe\xb1\xc7y\xd1~\x9cO\xff\x87\x8e\xf3\x9b2\xcec%\xffi=X\xbb4\xebK\xc4x7-\x18o\xd9\xb5\xeb\xe9)\xbdTw\xfd\xc2\x85\x9b\xda\x89\x8b\x1c\xe2M\xf7Y\x0b=%J\x9d\xc6\n\xed[u\xd5\xdc\xaa\x95|G\xfeT\xfc\x925\x85\xcc~\xecQ\x8a\xa3\xed\x1f\xcb\x9f\x8c\xc3\xde\xf2\xb3,\x9cWl\x92\x1d8p\x1e\xc6\xd3\x94\xc0y\x92.\x8a\n\x01\xfdk\x14\x06$\xce\x08\xbc{sQ>\xfcq\xbb\xfc)tR<\x8d\xd9\x9c\xe4\x92)\xd7\xf9\xdd\xf2:\x89\xb2\xa6\xae\x8a\x97\xae%\xb9\x94\xbek\xea\xae\x1a\x1fp\xcb\xca\xbb7\xd9Y\\,\x19\xda9\xd2\xc2\xcdH\xc4\xe8=\xa9pS\xf3\xe6\x18\x94Z\xc3\x89\xdcp\xbb<\xba\x83\x85u\x93\x7f\x1d\x98|\x11\xc9\x04\xb1\x8e5%\x96\x0b\xd6\x1e\xb34\xd4\xc2\xee\xbd\xbf$\x99M\x9c\xc9\xe0\xb2\xb5\x0355\xf1\xef\x0fL)<8\x82\x18\x8eaH\xffR\x84\x97O\xac+\xba\x15X\x0f1\x0f\xd3\xcb\x85\x9f\xbeL\xa6\xc4\x8e\xd1t.\xd6\xf7\xd7\x1a\x0cG;\xbb{\xfb\x07\x87O\x99}KK_s\xc5\xa6\xadK\xc4\x95\xabq\x84\x00$\x0b5\xab=\x8c\x8bXw-I\x91\xe8\xc9p3\xb4\xb6\xb2\xd2\xb6\xc2\x94\xd7\xc4\xbb\x9aE\xfe<\x83'PPZ\xe5\xa5\x1f,\x08K\xa5@[\xd1\xcbxo\xcaLG\x154\xe8\x17)\xd1$\x80\x06\x11\xa7\x82%m\xc2\x82M\x9c@\xc6\xb2\xb8\x02\xed\xe7\xb55!zV\xed\xea\xc3Vm\xfb\x0d\x8fx\x1fO\xc2\x8e8\xea\x19\x02\xddw\xbc\xabi\xb2|\xf3\xaa\x9d\xa2f\x16\xb2Z\xaeN\xbepTGU\xd4\xd1\xe4\x08\xa1\x91`P\xfa\xf3\xf0:\n\xe3\xb9Yy..\xda`d'\x94\x8b\xecjP\\3\xdbw\xa1\xcd\xa3K\xbe\x02\x9e\x91FC\x08\xa8\x97Y\xe7L\xaf\xd4\xb6vF\x16\xed\xa7\xb1\x98A5\xdd\\\x12bi\xde\x9f\xe8\xd7\xe6\x9f\xf4\xdf\xeb\xb6\xc0\xb4\xb9\xb5\x19\xd1\x9aU4(\xbd92\xec~&qa\x96\xd7\xb0\x81%M\xc4\x03w\x7f#\x98\xda\xdb[\xf9)\x89q\xc3:\xb2vA\xb3\x01p?U\xc5\x0d\x83\x83jI\x91\xd2U\x11\x87q\x84U\xa4\xde*Y\xd9\x8e\x83\xd8\x8a\xf6Y\x98U>y\x02+z\x96\xaa(E\x90\xac\x7fj\xb6%\xb8\xe3\xfa8\xe7$\x7f\x19%\x19\xc9rq\xc6\xbcN\x93%\xed\xf2\x18\xa6\xaeZ\xb4Y\xa6\x9d\xfc\x12\xf4\xfeT\x1b\x97^\x82 \xca\x0b\x99I\xba\x84\x13y\x18\xc2\x9c\xfb\x87\xd5\x81\xd8\xe8\x1c\xfd\x86vLt\xb2\xabsa=\xfb:\x91Z\xc6\x98\xcc\xd6\xce\x0e\xba\xf2T\xcf%7\xba\xf2Y\x07\xa7\xc3V\x98T\xdc\x11V\xf7\xa4\xaa\xfb#\xae\x13\xd4\x8f\xda\xd6\xce.\xb6\n'\xf5\xb7\x86v\x8e\xca@\xfcl\xc5\xe4b\xc5\xe01!\xf7\xdd\x08\x7f\xa9P\x1b\x84W) \xe8\x96\xadvl\xc3nD\x14\xe1KC!ub\xf9]\xafe\xd3\nf&L\xe7\xd1\xb2\xe9\xc9Y\x1b.\xdd/E\x14\x19\x8d\xa5\xf5<\xf8\x02\x9f\xaa\x04\xa4\xdc\xc5\xea\xb0\xac\xbeR\xce{\xe6\x1d9\x06k\xe4\xedy{\x96\xaeMM\xc0\xe6\xab+\x86\x01\xe8\xdf\x13q^~+);\xd0\x19\xe0N\xac/a<\xa5|}J\xb2$\xba!,\xf7Z\x9ca\xae)z#D\xc8\x1ff\xf4n\x95\x92i\x18\xf89a\x9f\xacR\x92\x91\x18\xcbq\xf3\xffs\x9e\xec\x8de}{\x1e\x85~F2\xeb\xb2I.O\xac,\xf0#?\xc5\xb2\xe4\xd7\x82\xc4\x01~\xb7\xf4W\xab0\x9e[\x97\x1d\x92\x11#y\xe5\x82__ \xe1\x8c\xe5\xb9\xc8\x85'\xac\xcc\xe1\xe6}\xc3\xb4\xd3Z\xb6x\xd8 \x0f\x9d\xc1?\xcc\xd0w\xb7b\x1bS\xfb\x87\xcf\xf1\x978\xb9\x8d\x81\xa9.\xc0\xfa\x81\x13\xa8?X\x10f\xb0$9%\x80\x90KD\x03oHf\xac\x0cae\xfe\xf6\xfc\xdd[\\\x04\xde\x0f\xcaju\\\xc8\x17a\xe6\xe5\xfe\x9c\xae8~G'\x0f7:\xfe\xe0\xf1\xed\xf9;>\xa1\xf8Z\xfc\xbe\xbf7\x8b\x96@b\xd3\x15\xb3\x07^c\xb9.\x98[Ky'\xd7\xda\xea*\xa1\xad\xb5Z`,\xbctu[\x1fO\xb9\xf4\x18f+\xef\xd4Q\xf35\xc9\xc7-\xee\xea\xa5\xe4\xc5\x8a\x05k\x0f\xeae\xe5\x85\x8c\xec\x1cs\x1e\x95\x9f\x96\x1f\xf8B\x9e%hB\x8c1 \xaf\xb7\xb8\xaf\x08'\x9e\x90\xcb\x9eK\x93^\xfe\xa4d\xc6LR\x9f\xc6\x82\xf2\x1d\x17\xf8\x92\x0e\xab%-\xd6\x95ii\xe3Rc\x0b\xbb\\\x82b\x81W\x165\xf4@\xea\\\xd9\xbdx\xf4\n\x85\x8dvG\x8em\xdd~\xc9\xd4\xf8j\x8c+\x1f\xee\x1b\xd8\xf2\x1d\xc7cR\xdd&s\xaeM\xdc+\x99\xe3\xda\xfd\xfc^\xf8\x02G\x91\xdb\xfd=\xd8\\\xf6\xe6\xd3\xd9\x0f\xc5C\x1f\xf5\xb0cH\x1c\xdbb\xfda\xc6`\x92\xb3\xd4\x83\xe3ey\x82\xa9\x92\xd3>\xb0\xd1#\xfd\\\x0e\x15_\x0f\xdc%\x80\x19\xda\xb1\xbd\xb7\x7f\xa8\x06\xacO\xf8\xab\xa7CG+7\x08\x8dC\xef\x1f\xa3\xde\x10\x9f\xfe\xe1O\xcd_\xe5\xbel\x13\x89\x0bmD\xdb\xc1\x00\x1c\x81\xab\xf6}\x15\x11\xa7\x17\x81)\xce\xf1\xa5\xf0\xae\xfa\xb0\xb3Y\x90\x08\x05S\xb0Gz\xa5,_\x96\xf1}\x88!\xe1\xcc\xef\xfd\x8e`*\xed1\xd8J:\xb5`bH%\xeb\x19\xc1\xbck\x98\xe3\xa6@\xd5u-\xef\x1a\xe3V\x18%[\xb0\xbcj\x94EbHW\x8e\xa4\x9e;G|\x9c\x06\xe6\xb5_`\xb7\x90\xa7\x16\xf3\xb5\x88\x0e\xa0_\xbe\xaf\xee\xa0t\x1b\xe8\x18\x9bIi\xc6\xb2\xf64c\xd0\xb3i\xe0\xcb+\x14(\xd67W\xa7\x1f\x9f\xf6\xa9\xe0\xa1\x1a/\x1f\xd8\xea\xd4\xd0\xcd:\x91\xb7\xd0\xe6\xfayN\x96\xab\x1c\xf2\x04\xa6\x84\x1d\xf5E\xca\xbc\xd9\x84\xbdni`\xa0*\x03\xaa\xcdl\xf7\xa2^%:u\xbf\x1d\xc9\x0f\xf7\xb5H~4\xfc\xbf\x16\xc9K\x07\xa0^\x1c=\xdc\xd3\x82d\xf7\xa9F\x1a\x1d\xdb\x0d!u\xc1\x1e\xab\xa9M\xfaz]\xa3\xf2\xc1\x05f\xbd\xb2\x02\x0c\xe0\x0d\x99\xf7Z\x8f\xaa\xa6e\x81\xbf\xe8\x0b,\xca\x02\xe7\xfa\x027e\x81\x8f\xfa\x02\xcb\xb2\xc0\x0b}\x81yY\xe0g}\x81;8\x81)\x9cB\"\x92.\xd1\x99\xe5\xd9\x97~7e\x11\xbb\xc6h&\xa5\xb6W_\xe8\x8a\xd7\x9c\xc2\x18\x16\xf4/\xcb\xecd\xa7\xbc\x95\xdf\x1f\x9c\xaa\n\x03\x9b\x8f\x9a\x9ei)\"\xca\x1d:1\x98\x9a|\x03\xf3\xe0^)\x11\x8a\xae&\x11\xd3\xb1\x14\xf6\x1d\xaa\x7f\xe8h(\xb1\x1d\xc0)\xbe\x841\xaa\x81\\\xb8c:!\xac[k\xbf\x85\xa5O\xb14\x8caI\xcb\xd1JB{\x86&yc\x98c\x07\xb0\x9a\x13\x98\xc1i\x07c\x00\x12\x83_\xd1\xb8z\x0b?\xf9B\x96n\x11f\xb5x\x1e]\xe2\xd3\x0c\xf3#\x83\xad\xea\xd6\xba\xbe\xa3W\xe0g\x04\x06\xe3\xcerP\xb7\x8f\xd1L\xa1za\xcd\xc3\xf5k\xb6u\xf8\\\xbd\xb0\xf2\xd1c*\xd7\xc60\x92\xaf\x0ea\xb1Z\x996W\x99\xb8\xccu\x95b)f5C\xe7\xdc\xad\x94\xa3\xfa\x1a5\xdau\x90\xc4\xa1\xd5\xfebr\xd9r\xc3\xea\x02\x88\xb3d\xd47\xca\x86\xa8N\x91\x19\xae\xfe\xd7\xfc\x0d\xaa5]\xc0of.\xfb\xcc\xb6\xef\xbc\x1b\x96\x14\x1b7^u\x87\xb8\xc4a[n\xe6r\x8c\xf4\x89~sM\xff\xdb\xb8\xa6\xaf\x9e<\x01\xdf\xbev\x01\xab5\xa7(\xc9\xbc\xd7\xcci;\xf3\xfe\x02'0\xa2?\xce\xe1\x04v\xe9\x8f\x8fp\x02\x87\xf4\xc7\x0bZf\x9f\xfe\xfa\x19N`\x07K}\x86\x13\xd8\xc7b\x9f\xe8\xdb\xd1\xa1[\x93\xb70Q\xfc\xbaR09\xeeT\x85=n\xc3x\x9a\xdc\xd2!\xb1_\xde;\x0c2q\x82ZL8\x15\xef\xc7\x86\xcf3\x12a\x10e\xfaW\xfd\x14\xdf\x8dAL\x84m\x89\xd9^\x84\x99\xe5\xc8\xa6_Zq\xdb\x9c\x8b\xdb\xe6\xdf(n\xeb\xe2\xbc\\~b\x8f\xf6\xd5\xd3\x16\x03\x81\xd1S\x9eE\xcaN\xeb\x9cT\xda\xceI\xa5\xa6e\xa1e\xa0\xda=\x1aPBEx`\xb0\xb0\x96\xd9(w\xb5\xc7\x7fT\x901h\xd4\x83\xa44r\x1ak9\x9b \x89g\xe1\xbch)q\x9b\x86\xb9x[\x1f\"\x86\xa0g\x07r\xec\xd6T\xb1\xd0=wfym \xd1\xd8\xde\xdb\xd9Q\xa6\xa8\x9a\x91Z\x7f\xf4M\xeavH\x8d\xfb\xd4\x8b7\xe3>\xfd\xff\xc6\xb5\xa7\x8e\xeb\x8f_z\xe52j\x17\x15\xd6\x94%\xc3#\xc8\xb5\x860\xb9\xde\x10\xe6F\xcd\xd4\xa0\xb5NoDr\xeb\xb0\xea+\x0dUx\x8072I/\xb9\xf7\x94\x89\xe3\x01\xbd\x89\x00=\xa8\xde\xef\xef\x0d\x06\x07\xec\xfd\xfe\xde\xde\xce\x1e]I\xfc\xd7\x13`\xf2&z\xb7\xaby.*\x1c\x94\x95\x1d\xb2\xe7\xc3a\x95]J\x14\x1a\xee\x96\xa5v\x86\xb5\xcf\x87\xa3\x83\xf2\xd5p\xef\xa9\x03<\xbf\xd63\x18\x0e\x87\xbb\xc3\xe1\xd0a\x97\x04\xd3&T4\xbe\xba!\xcf\x02\x87\x9d6\xa11\x8a\xfe\x18\xc06\xc1\xb6 l\x9d`\xf9}\x07\x9e=\x83\xa1\xca\xbe\x8b\x8b\"\xbf\xbd\xfd\x9d\xd1\x80~5\x1c\x8cv\x10&FM\xaf\xce\xac\xb6I\xf5k\xd1\x9a\xeeS\xad)\xf8\x0dw6\xdd~bO\xfc\xad\xdf\xfe\xe5\x92\xfe?\xd8zz\xf9\xfb\xd0\xdd\x19>8G\xdbs\xc5\xe0\x8dR\xc5\xdb\xff\xf9/\xb6}:\xfe:\xf1\xb7f\xbc\xf0\xe1\xc3\xfd\xa4\xfc\xe98\xdb\xcaW,\xe7\xec\xeep_+\xb4n7\xc5R\xc4\xa5|\x88\x89\x1d\xf0\x14\xcc\x01\xe3\xd0w\xf6PO\x92{\x01\x1f\xf1\xf3\xdc\x1e\xe0\xb2\x88Dx.F\xabc|\xab\xaf\xcc\x946\x9f\x0c/\xeb\xb9\xaf\xe0\x140\x80\xea\x9b8\xb7\xf3\xd2D\xcf\x85\xe1>\xa5h\x1a\xaf\x86\xf4\xd5\x00\xe3\xb4\x16v\x8cD\x8f\x01\xcc+\n\xb8\xc9\x93\xe3g\xd6\xe5v\x1d8S\xe9\xcd\xbc\xfe\xaai\x02B/\xeb\x895\x06\xeb\x89\xbf\\\x1diB#[\xc7\xf86\xca\xb5/\x9f\xe1\xcb\xb9\xf6\xe5\x0f\xd6\x0f\xf4\xe5\xafE\x92\x1f5b\xd15\xa7\xed\xc6\x88S\x16\xb2\x11\xb6\xac-\xe0V\xba=\x84x\x93K\x06a\x86\x1eK\x9a\xc1\x85\xe1:\xfa\xe0\xd6dVR2Lq\x0c\xe6z#c\xb4`\x149H\xf8W\x06\xe6\xbeKum\x0coH/2\x89/y\xe4\x1bm\x19]\x0c\x91\xfa<95Z\xdb\xc5l\xc0=\xd2\xe9q\xa0[\x1368\x8e@.y\x04\xf3V \x11\xff\xb4q<\nSW~\xbe5\xcd\xa9\xeb\xdd\\\xf8xN\xd3\x9fE\xcc\"\x1d\xbek\xcfgWJ\x1e\x84b\xd4\xfa\xe5\x17\xcb\x81c\x18p\xcd\x16)\xe3,\x86.X\x7f\x1eZ\x8e\n\x99\x9f\xfc(\x9c\x9e\xc5y\x98\xdf\xbddf(>}\x81x3\x99\x92\x8fI\x88j\xea\xc2e\x9ajZ\x17\x96\x0eI/A\xb4\xd4\xb5'\x86\x9ee\xae\x9c\x18\x08\xbb\xc5\x06\xff\xd7\x1c\x03\x84w\xb6\xb1\x12I\xd80\"\x83\xa8v\xea\xc2\x8d\x0e\x19\xb51Ak\xc9\xd8\xa5\xa0\xd6U\xe0\xcbS)\xc1;\x8c\xf5\xf2\x98\xae\x1e\x19E\xeb\x0dn\x8f1K\xfb\xeai\xcbD\xeb{\x87Z\xd1\xfa\x81Z \x13\xad\x0fGj-\x8f\x93\xad\xbb\x92\xf4\xdc ^_t\x89\xd7o\xba\xc4\xeb\xcb.\xf1\xfa\xbcK\xbc~\x07'L\xb6\x8d\x923.\xe3f\n\x13!A7\x8a\xbc\xcd\xa2\xf5\xc5\xba\xf2\xf8+8\x81kI\xd8G\xbf\xb9\xae \xff~\xd7\xa5Q\xaaD\xechY)\x89\xd8\xd1+\xd3f\x82v\x14\x91\xdfA]\xd0~\x87\x82\xf6S\xb8\x831\xc4\x0eJ\xd4\xe9\xb1\x8c\xc2\xa5\x00\x8fp!&G\xc9\xb9Q\xa0X\x98\x04\x8aw\x8c\xc4\xb8c\xe2@!2\xfc\xec\xb8\x80\xb2\xc2\x0d\x9ee,\xe4\x02\xc3\x15\x06\x08\x10\x02y\xf1\xd6\xbe\xe2\"G\xa301\xf5\x02\xa6\x9eJ\xdc\xffi\xc1\xa2Y\xf5\xa5*\xb3\xb8\xeak\xa0\xaa\xc4\xf8\x06Uw\"\xdd\xa0\xdb\x96J\x00\x15\x9a}hP=\xdc\xf0\xa8\x01\xdc\xcc&\xc4\x1c\"\xda\x85W``KtM0R\xdf<\xf22*\x95\xed\x82\x85\x11\x15~\xec?\x9c\xa0\xe1\x0coH\n\xba\xec\xbb%\xf9\xe4\xa0U\xcd\x0f\x0e\x8fF\xf6\xactu?\xde.}\"\x9e\x19\x03\xfe\xaegP\xa7\xf1X\x8b\x99\xea3\xb7\x0b\xc7\x85\xd4N\xbd\x8f\xb0 \xa9\xf7\x1a~\x84\xa4=\x02\x83\xe0o,\x0b&\xe4\xd2\xa6c0\x02)gF\x03\n\x05}\x7f\x0f9w\x88\xa3_K\xd9\xe0\xeb\xc3u0 #\xc6O\xae\xb15\xddG\x15\x8e\xba\xeaU\xdc\xc3\xfa$_\x84\x95\xd1\xfa\x83,on\x9a\x19\xd0\xfab:\x0c\xa3\xb4\x1aq\xd5\xc0\x05r\xe3G\x8em\xb1\xc7U\xf5F# \xcd\xb1Y\xc9\xdc\x11\x93\xb1[\x1d\xaf\xf6\x9d\xa4\x905Q\xe3S\xdd\xe6\xfc\xfe\xa2\xc6^\x9e\xb37\"\x19E\xa3\x01\x91xb\xacMT\xb1\x08\xb3SV\x160\xf1\xf0j\xb9\xd0\x84\xe7C\x91\xd89\xf6\xb2\x15 \xceIDh/2\xcd#\xbc\xfb\xb7,i\x15\xf7\x89\xa3\xcc\xf4\xad. \x8e\xb8x\xa7}\xbb\xa0\x0cmi \\\xd7\x1e\xd25\xa8XH\xff\xfe\x80\xb1lb\x9d\xa5\x80|}H\xc3\xb1\xc6\xdeF\\\x0f\x18\xd5\xd3\xd4l\xeeB\xd8\xf7x\x85j0\xe2\xd4\xb8\xf5\xd3\xd8\xb6p\x95\xde\xa6\xfejE\xd21\x04I\x11M\xe3\x1fr\x98\x13\x16\x17\xd4r\xdc\xa6\x9fa\xb3 \xad\x17\x99@dt{\x0c\xfe\xa1\x86\xf4\xcd\x86[\"\xe3\xf2\xcdGiZ\x7f\x15\xaa\x9bO0\xae\xcd\x944\xcc\xf9\xae\xbe\xc9v\xbc\x81g!\x8d\x9fW\x0c\xdan\x17\x13f\xe6\xfe\x0f\x9d.\xeeU\x1d\x15:\xc1\xa7h\xe3\xcf\x08\x91J\xde\x8eqCE\x02l?\xe6\"\xf7\x0d\xc3\x88\x1f-R\x1c\x1d\xa8RBLy\xd1\xe4\xd1d*\xa0\xa4\x06\x18\xda\x96\"\xb2\x887M\x8e*\xa5\xfcb\xd2\xcaQ\xea\xa1\xa7\x0f\xcf$\x8f\xa6\x1f\xaco\xfa\xc4V\x16\xae\xbdL\x03[\x03\x03\xed\xba\"\x0d[s\xa9tx?\xd6\xfc\xb2\xdb\xcc\x7f\xae\x8b\xf9E\x92D2\xb3\xd9\xab}I\x90\xac\xda\xa7\x0b\xab\x1bu1\x84\xdcv[uZ\xf2+k\x80\xfa\x99-\x9f\xb23\xa6\xf1\xdc\x95\xa2\xe6\xd4\x0b\xab\xd1s4\x87\x13\xba\xb4\xa3\xeb1\xda\xe8P\xb4\x8a\xe4Qj\xc7\x8ekN\xdb_\x1e\x0d\xa2\xdaZ\x89\x1a\xe1\xfe\xd0h\xcf\x9a\x93\xdcb\x91j\xe8\x9cg\xe2\xae\xb9I\xad\xe7A@\xb2\x8c\x9e\x7f\x18\xab\xb9X\xd19#S\xd36\xb5\x90d\xe1u3\x86\x8c\x99\x87\x95\x0e)kn\xe4~Vb\x0dw\x84\xb5\xac\xc4\x1e\xd7\xa4\xbab\xbe\xa5\xc9N\xb7a\x83\xcb\x81\xce\x88,\xb6w\xf6v\xb5\x8a\x91}Uz[\xf0\xe2\xaa\xe7\x02J\x9f\xecCu\xafD\xac\xd1]u\xe4L\xf1\xaf\x96\x9ei\\\xadV\x18\xb0\xb3\x0eS\xb4L\x9b\x93\xfcc\x92Dd\xaa\xe6\x87Xh\xe4\x1a7%2)\x1f\x97'\xeb\xb2\xc1\x1d\x9cy\x98\xde\xea\x13 \x928\x08#r\x91\xfaq\xe6\xb3\xd2O\x9e\xc0\x0d0'\xff\xe1h\xc72YOP\xeem\xa2l\xdb8\xccY6\xcfq;\xe3\xc5<]\xc34\xbf+i\xdb\x8ce\x18\xc3\xbc\x18\xecX\xae}\xa5\x88\xa54\x82\xabu\x1a\xd98\xa9\x9a\x81S\xb0g(\xb5\x0d\x08%\x19\xcd\x9f9.\xdc\xdaH\xfe\x95\xdf\x9e\x18\xc3\xb0?\xa8t\xe6z\xc0 \xfc(\xba\xf6\x83/\xff\xbb \x05\xf1R\x92\x91\\\x11{<\x16\"\xf5\x9a\xe3$\x0fgw\xcf\xa3H\xad\xbd\x1a\xc8\xa5nI\xdd5\xe3\xff1\x1f\xe7j\x98\xd2\x9a\xb2\x9d6\xb8\xf2\x95\xebj\xfa\xd7\xd8\x07\xa2\x19\xcd\xba=i[\xd5R%\x1b\x83v\xdb\xa8\xeb6\xe35\xe2]-\x93\"\xce1\x15\x06lA.\xdf\xb7V{\xd5F\xdej\xe1\xa2\x88G\xeb\xab\x96\xc5\xfe\x18\x8ev-\xc4\x9c\xe2\xb9C\x7ffI\x9a\xdb\xd7\x8e\x0b\xab\xcd\xcdz%Ud\xba*\xaca\xce\xa3\x1a6\xd7\x0b\x17tR\x04:\x9b\xc4\x06\x0fQ\x1f\xe7\xe8jE\xe2i\x18\xcf_\xf2\xd9\xcb\x9a\x0c\x1c\xba\x156\x0b\x96\xb3_xQ2\xbfHVo\xc9\x0d\x89>a\x88'c\xa0\xa3\x1b\x1e\xbd\xd6\x90\x9e(\xf4\xae\x82\"MI\x9cs\xc6\x0c\xf3\x89c\x9e\x03?\xc8E\x1b?3\x16\x0b\x8f\xe4\x88\x8d\xa2\x11g\xcba\n\x03\x8be\x03,VS?',\xb8WD\x97\xd4{\x7fI\xe8\xaa\x14\x0c\\\x1e.\x89\x9dt\x19\xab\x00\x87F\xe6\xadH:K\xd2\xe5g\xac\xf7\xcd\xec=\xa1\x84\x85\x9f\xde\xd9\xa1\x8bF\x0d\xcd\x85\xcct\xa7 *n\xa5F\xcf\xe2)\x8b\x0c\xae\xe7>{D\xbe#\nf \xf1\xaf\xf4\xaf\xedO\x82K\x97\xef\xc2\xe2:\n\x03\x11\xb8\xc6V}>\xfe\xd4\xfc\x95\xd8\xb2\xdf\x19D*R\x9c\x93\\\x1a\x1b\x9f\x90\xac\x03\x8d\xf1\xad8oC\x87\xc2-4I\xfb\xe0\xc4v\xb4\x14z)\x89\x88\x9f\x11\xbb\x89\xa0\x1c\x03\xd6b_\xb6!\xa4Z\x9d\xba\x99\xee@v]\xa1\x86\xf8\xd2\xea&\xb6\xa1\x02i$\x16$\xcf\xd1\x89>M\xc6N\x88\xc2-E\\\xd0\x93\xe2\xd5R\xa1k\xd6\xf3\xa7S\x8a\x9c\xc3x~\x91\xd8w\x8a8\xef\xb6M\xcc\xc9\xa3\x0b\x95h\xf1\xfe\x1e\x16\xc6(Y\xb3\x0e\xb7:\xa1\x88\xbb\x93\x8f\x1c=\x86!b\xf0\xf6\x95HKO\xd7\xc2]9\xad\xba\xd4v\xdaN\x19{\xc3\xa8<}\xf3\xe2\xe4\xd0\x04\xb5\x03-\xfd\x08\xb9|\xd4\xd7\xd6tWG\x8d\x82\xa4\xb3\x06/`\\\xed,2V}\x81^Sn\x8cL\x19\xee\xcb\x9a\xeb\xb4\xcc\x17\xd3\xb2`\x97t,7^\xbd\xaaf\x05m\xfb\x84\xe3\xb9\xcf\x1c\xb5\x97\xe75\xd1\xdbP\xf2\x16\xc3\xec\x05m3\x8c\xe7\xbcQFFb\xa0\x81\x9c\x0b\xe8PZ\xe0]\xb1C\x03\x8b\xbfGm\x08\x17Ji^\x9c`N\xbc!\xd2\x98\xdaQ\xb5\x8ed\x16\x15\xd9\xe2\x85\x02\xd5[\x85\x19\x8a)G\xceT\xca\xcd\xe5\x88/\xf5\xf3g\x16\xb1\x88\x8b\x94L\xc3\xbe\xe5\xb4\xe2>\xbd\xb6\xb0I^\xb0\xfe\x08@\x9f\xe7\xa9\x9f\x93\xf9\xddz}9\xa0}\xd1gOQ\x00\\\x92T\x87\xf8\xc95\xdd:\xbe\xf2Es\xda\xc5GO\xe9G7\xfa\x91\xb5M\x9a\x9f\xf9\xab\x1e\xa9T\x03[\xb3\xe6\\N\x97\xf0[\x8f\xd5\xf5\xd2\x8f\x7f\xc8\xc5\xb2\x06?\xc6&@\x1cP\x10\xc6\xe0c\xe8E\xf25\x87\xdb\x05II\xc1\x87\xe2c\x08\x85\x1c\xaeI\x18\xcf\xc5\xf6\xf4\xe8\xb8\xa6%5\x80\xfds\x19n2\xb2>z\x81\xd6\x19>]C\xce\xb0\x11\xdb{C\xc7l\xb4\xc3q\xc0\x01\x9d!\xbd*\xe9\xf7\x07\x17,\xbf\xa1B\x02FytP\x06r\x13]s\xeaxU\x9c\x8c\x87G\xa84\xc5\xd3.O9\xcc~@\xc1\xf2T\x17\x1f\x07_\x8d\x86\xea\xab\xd0\x14h\xa2\xd4b\xa0\xcd_\x861!\xe4\xf7\xa5\xf6\xa4\xd3[^\xc8tUSWz=@\xd7\x8e\x95\xf5\x0b\xdd\x1d%U|\xaf$\xe5Q\xcf\xe4\xd7,\xe2i\xa9\xa0\xa9\xcc*O\xab1\x8e\x0d]]\xcf\x83\xe8\xbb*D\xc4/\xd9;\xb1\x1b\x18\xd2\xac\x9d@hW\xfa\xae\xd6)\xe3\xfd\x97\xc3JR\xe8H\x86\x00c\xd4\x03U\xddk\x9d\xc3\x7f\xc4\xfc\xad\xd1\xf7\xc7oG\xb3\xd4\x93\xb3\x97J\xc4O}S&\xfc\xd6 \xd0\x9a^Bgx\xfe=\xc6( T\x0d\x86\xe6\xaa\x84\x94\x0bTu\xf2T;\xb6\x9f:.L\xaci\x98\xad\xe8\x01\xf2\x12=\xa9-\x17\xac\xab\xdcOylVz\x1b\xfbyx\xc3\xfc+1\x96c\xf6\x8a\xcd\xf7\xc7\x94\xd0gd\xca\x9eRT\xee\xcf\xd1\x08\xee\xa5\xa94B\x1f\xca\xdd%j\xd8p\xdf\x18K\xdb\x10\x1d\xad4\xfb\xd3ft\x03\\\xd4\xa7\xd8i\x96\x01\x8e{\xe3Y\x0c\x00\xec`\xf0y \x8f=D\xc5\xecX\xfa&\x9e\xf8\x9a\xdc!\x0d\xe8\x08Y\x1d\xe6B\xf5\xd4Y\x87S\xdd\xc31l\xb08\x8e1\xb7\xde\xfb\xa9i\xbc(i\x84\xbd&\"\x80\x13\xa0\xdcU\xd8\xb0\x9aR\xf6\x1bZY\x89\xc8\x9d\x1a\xc4\x81<\xb1\xbe\xfc\x9f\x9acN\xedL\x96\\\xd5\xa7l\xc5\xfa\xf6J\x9c\xea=$L\xcdAmh&\\H \xd4\xd5\xda,\xc9t\xd5\xc4\xabw\x05}\xa1\xea\x8fl\x87\xd9\xf8a\x88\xcc:7#M\x08\xafM~r\x02h\xadf\x9e\x95\xc6\x8c\xb4r\xa7Y\x9e\xac\xa4I\xe9\x00\xda\xfa\x80P\xeaGH(\xcfZ@\xc1\xb0\xea\x0bD\xbd\xbc\xc2\xda\xa3\x13\xa6\x80\xee\xbd\xb8:\xc1\xb1\"i\x86\x99\xc4\xbb\xd7N\x98}d\x85\x19\xdaj\xb4\xd3\xd6\x8c\xfc\xadv\xbf\xd4J\xf7\x96\x9a\xd6\xa6\xa7\x07\xae\x84z\x0c\x0d\x96\xd1\x0c\xf1\x0f\xd3\x84k\xa3\xd3\xeb\x94\x15\x95\xd0\x9aebB\x146\x89//\xb5\x12\xd1j_;.dU\xe7\x98kc\xe6\xf9\xc5|I\xe2\xfce\xe4g\xbd\x1dNd\xb8\xa8\xbe'5\x1f.\x84\x8d!b\xda\x0d\x8fn\x10\x93[\xf5\x18J\x99\xec\xbf\xfc\xd0\xa9\xdda\"\x16\xf9A\x9d\x98\x06\x8c\xa6.\x8f3E&\x18\xfbR>f<\x9e\x8b\x98\xa4\x19\x908H\xa6a<\xafgD\xc8\x17$\xc6\x8d\x87\xc9\xd2\xca\xc3\x0fD\xe0\x17\x1fx\x03\x06e\xb88c\xb9\xc1@/\xd57\xffF\x18\x19\x18\xcc\x04\xf4S\x13\xb5\x88\x85\xc0\x0cCC\x8c\x9b\x1f\x84}n}\xdc<\x9b\xa6\x0f\xac\xa2\x16gp\xbd\x03\x1d\xae\xdb\x17\x0c\xdb=y\x82LO\xb9\x1e\xe4w\xcdC\xbe\x85P\xc3\xd0>\xde\xf5]N\xde\xf2l\xdd1FWA\xcf\xf3\xea1\x1cWv\xcb\xeaV\xfd!\x99\xcd2\x92\xff@\x97@R\xe4\x90\xcc\xe0:)\xe2if\x9a]\xb5MZ9l\x82\x8d\xb6\xfd\x03\xc7\xd8\x0e\xdbs\xfd\xdb\xc9\xeb\x99\xd1\x99!juO!\xd5@\nuE\x80\xae\x08n\xe0\xb1\xee1\x05\xb3\xbe'\xad\x88)oCD\xb4\x00\xcf|\xd8\xbaU4J\xe2\xda\xec\x8f\xf5\xde,\xdd\x04\xa1\xb84\x9f#@\xcb\xe8\x0e\xf7\xf7\xcc\xed\xde*\xf2\xd9a\xdb\xd4od^\x98\x9dq\xbca\xc7\x8ei\x13 \xd4bIh\x83\x1d\n\xac+%\xee\xd1\xed$\x90\xce\xd3\x01\xdc\xc3\x82M\x9c\xde\xe2\x10\xf8\xe1\x8a\xd3\x81\xc7V\xea8\xdem\x1a\xe63/HX\xa7\xdcL\x8d\xe1\x98\x11\x91\x84rZ$\xb9)\x1bUJi\x08\xfag\xf3\x04\x86t`\x18\xbax\xb4\xb7\x07O \x9f\xa4\x1a=\xd7Z#\xd4$^\x85r\xdd<;\xa1\xbc\x95\x89jy^e\x96\xf1#\x0c\xbfB\xf8\xce\x82\xc8O\xe7\x842\xa8~\x0cK\xffk\xb8,\x96\x90\xa1;\xc7\xe0+\xe5\xb3}9\xcd\xf5p\xdfAWNJ6i)\x9e\x12a\xdf\xf7\x1c\xd4\xa2u%J'\x8b\x9c;JH\xcb\xf5\xdb\xb4\x0f\x92\xd6\xdasHe\xbc0\xfb)$,\xd0H\xf31\x9d\x88\xfb{ \x06\x14/\xf7\xb4\"0\x9b\xbd\xd5\xb8\xd6W\x8c\x9e\xa5\x13r\x80\xb4\x9c\xdb\xa1\xc0\xa9\xcd\xb2'\x9a\xedU[\xbe\x1b\xc3\xa3#\xa7\x14\x0d\x1bOB\x14\x88Z~\x16\x84\xa1\xa5\x17\x8b\xb2\x12\x91\x9f\x87\xf1\xb0\xb5\xc8u\x18\xfb\xe9\x9d\xa1\x08H\x12(\xfdq\xc2*A2\xaf\xad\x95\"\x9fm\xb5\x96`\x84vg/^\xdb\xc41\x02\x1c\xaa\xe6\x82l\xd4\xde\x9f \xdb\xea(\x91\xcf\x86\xfb\x11\xe9*\xb3\xd5R\x08\xaa~\x8f\xe0\xc7v\x08.\xc8\xd7\xeeZbx\xf6\xec\x19\x18\xac\xb6\xf9t\xfa\x19\xd9\xdf\xed\xae\xea\xb7.@\n\xa32cE\xa8\xedpzO\x0cp&\xcc\xc6\x1d\x95;\xf5\xe8f.\xcf\x8f\xd6\xf8T\x95\xbe\xeb\xd1\xd7M\x1b\xc7\"\xf6\x16\xd1F\xc6\xe7riz\xfc\xb9\xe2\x10L{5\xba\x94\x98*\x83\xc6\xa1B\x01\xa4\xa4\x189\xc0\xb64\xd3h\x10\xb7\xc4\x94;L\x99\xf0\x1cOn\xe49\xe1\x99,\x91;\xc575\x11\x1d=\xdd\xb7\xca'\x87 b\xa1I\xcf\x1cV\xe1f\xecB\x98\xbd\xf7\xdf\xdb\xb1S\x16K\xf8\xe1\\\xca\xb7\xb6`\xe8\x08\x91\x80(T\xbe\xdcDZ?\xa6\x07 \xe9p\x84@\xcb\x95V8\x00\x8f\xfe$7\xdd\\\x19@\xa2\x8c`m1\xa3\xd7\xcc\xcdm\xf4k\xafk\xf9A\x8bH\x8c\xd9\xdd#\xcf>K\x93%\xe5\x15S\x07\x15\xc35\xae\xac\xc6J\xe5\x15\xfb\xb45\x841\xcc\x95\x15eX!Z\xe1\x13\xaf8\x87'H\xeb\xb8\x069\x83\xe9\xd0\xad\xc4\x17\x92\xf6\x97\xc7\xd9\xc5\x08\xa4\xa7\xadE*\xf5\x04\xe7Z\xb5\x85#?\xcb\xdf\x18>\xc0\xb1O\xf2\xcb\xb6\xd1ky\x97\x1b?* {\xc1\xae0\x08Q\xce\x843Z\xfd\xe8q\x15\xfe\x06d\x12\xb2\xf0l\x86\xd8o\x85\xb4p\xf5%2\x89\n\xd6O\xb1\x14\\\x95\x89\x14\xd8\x89\xc6\xf8\xef\xb4\x8a\xc6\x99*h\x14\xe9!~\xb8q\xa1\x15>\xe0gY\xfd\xd1\x96\xf4\xcc(/@\xb2\xb6\xa2\xd8GL\x18X\xddw\xee+\x9fEO-`\x9bEQ\xe5\x7fc\xfc\xab\xd9o\x8dG\x8a`\xd6\xd4Q\xde\x8dai\x92FX\x00{\xe2\xa5\xc4\x9f~~\x13\xe7\xc3\xfd\x17gv\x0e?\xea\xdc\x18\xf5\xfb\xdc\xa8E\x16\xce\x8e\xa6A#M\x87j\x98#\x08\xe1\x18\x8a#\x0877\xf5L\x19\xf0\xc6px\xa1\x83\xfdG\xad4OQ\x1cp<\x1c\xc2\x16\x04\xadr\x1dQS\xf9!]9\xb4\x9b\xa1\xe3\xb2\xcfa\x93\x03(+\xe7-\xa0\x001V\xc9\x91\xec\x16K\"\xc1j\x0ca\xeb\x84\xf7\xc6\xe5P0 g3lb\xd8\x84\x0c\x9eAQ\x9e$\x05lA\xe60\x7f`\x84\xda3d\xe6\xc2\xad\xad\xb6!\x97\xc4\xf3\x8c\x07\x0b\\1\x1ep\x05\xc7\x90\x1d\xc1\xaa\x0d\xe8P\x03[{>\x1cCz\x04\x9b\x9b~\x1b\xfa\xa0\xc7\x84\x9c\xf7\xa2\xb8\xce\xf2\xd4\xa6|\x82\xef\x02O\x8d\xa1_X8H\xa4\xd6\x8a\x8a\xa0\xf0\xf5e\xc9\x84\xee4f\xba\xdb\x03\xe9\x89\xcaz-\x9a\xeb\x8eE\xc3+{a\xbf\xa6\x1bJ^\x16\x0e\xaa\xe4\x9a&@\xa6\x96\xae\xfa\xb6d6\x18(\xeb\x94smM.]Y\x14V\xb2\xf2L\"\x963\x87K&8\"r\x02\x94\xb8C\xa2\xafK\xa8\x98\xaf;\xe8\xdb~\x83\xae\xc1\xa6W\xc5g\xfd*~a\xff\xb6~\xa7\xbf\xf6\xad\xbb\x97V\xa3\x92W\x96\xde\xb6|\xd6\xa4\xadF\xa4\xa0\x15\x1b\xb6\x9d\xd3\xd3i\x84i!\x1c\xbe \x19+!\xcd\x9f\xcf\xf9M\xcaO\xc3!\x8f\xdaL\xd1\xc6\xde\xbe\x0b!\x9b\xf6\xc4)\x7f\x9a4yF\x94\xfc\xf0\xad\x0b\xfe\xbc\x8d\x9f\xad\xb3\x10t\xd8q\x8d\xc5\x84SH\x91\x07yq\x97\x13\x91\xf1\x9dbU\xf5!WQ\xe5u\x9b\xae\xb6~\xbdl\xeb\x17\x05\xf3;?_x\xcb0.i\xc6\x1e\"[:\x9f\xe8\x1aq\x04 \x8an\xdb\xd0&\xa5\xbd]\xb4\xafu1F\x07\x99$-\xc9\xe5\x03\x11,\xc1X\x82\x9e\xe0\x11e\xa5w\x9e\xc2)\xec\xc2\x98\xdd\x8dv\xe0\x14v\xf8\xdd\xf0\xe9\x10Na\x04c\x93\xe8\x05iE\xd8\x84\x19\x1c\xa3\xb0O\xc8\xeffm4D\x9f\x04\xb8\x11\x1c\xc3ptX\x12rQ\x8b^ \x04\x9da.\xd2'-.m\x8er\x19\xc3\xa7#x\xc2\x88X2\xa1\x83\x1b^:L8@\xd9\x17{g\x08O r\xe0\xf8\x18\xf6\xe1\x1e\xf6w\xe0 %^\x9f\x89\x0cb\xd8\xdd\xec;t\xd7`\xf6).\xb9\x7f<3>\xde\x8d.]e(!\xf6\xbe\xfe\xcc\x97F4\xdc+G4\x1c\xc1=\xd8bL\xf2\x10}:\xc4\xd1`\xf7\x80\x7fw\xcc\x13\x96\xdd\xdf#9+%x\xfb^\xe3\xdf}\xfc\xf8\x8b\xf2ng\x0dh\xd4\x9f\x15\x06\x08\x1d*\x10\x92@\xe6\xd7AV8\"\xef\x1b\xad\x89\x82\x8c\xa5\x92\x1bI`\xd2\x0eQO\x12\x97\xc6X\x94/\xc2\xcfi\xdd;.\xee\xe4!\xc5s\x81\xdc\x9e\x1d\x94i\xe4\\H\x19>\x0f\x98\x18u\x00O\x00\xf3\xc5\xdd\xb3I\xe4\xdc\x0c\xcb%w\x0f<\x95\x1cer\xc4w\x18\x1bg\xf3\x04fM\x8co\xc2\xd2\xdd\x14\xc9M\x19\xa7\xa9M|\x8a\x8aq\x8a^\xbe\x94$\x9f&\x1d\x1d\xb71>\xe7b\x10\x9d\xde\x02$\xdd\x85\xa5\xc9V&\xaeT\xaf\x0c\x04(\xc3\xa2\xa4\xa8=\xa4\xc7\xeb\xe6I\x9f\xce\xf0\xe3&u\x99j\xeeK\x07\x11\x157\x81l7\x8eO\xf9.\xf7\xb8b\xe9\x84\x1e\x0e\xb9w\x1e%\xb7\xe5\x93\xf6y\xd8$U\x84N\x82\x12V\x0dC\xc0\xba\x95y\xa8\xba\xb37\x1b\x1e8\x90{o\xde\x9f\x7f<{yq\xf5\xee\xf9\xffw\xf5\xe2o\x17g\xe7t=\x0dL\xb2\xb8\x139\x89\x0e1\x98\x05\xe9\x9fwy\xf6\x18\x83\xdf\x0b\xdf\x1a\xc5di\xd8a\xa2R\xb3J2\x9fie)\xbd\x00\xb0\xe5\x18N\x92\x1e\x01\x13\xc4\xc5{\xb5\xdb\x94\x1f\x89K\x8f;\x1e\\\xd8\x1dqZi\x96$\xb6c\x14\x87\x12\xca\x901K\xd3'O\x84'x\xf9\xcc\x1eb\xc2\xbcJ\xa9\xd8\\\xaa\x9d\xd9\x0d\xf8\x1864\xb2\x93\xfa\xbab\xf1u\xbe\xbc\xf3\xbf\x96\x91\xa3|\x1b\x05\xcb\xab$\x89\xce\xc3\xdf\xe8t\x1e\x0e\x9fb\xf2\xa1+\xeea\xd3\xb9\xe2\xb5\x13[sJT=\xbf\xb8`\xbb\x87\x1f\x8cT\x7fd\xf3\xf0EZ\x0b\xcc\x16!\xb5\xec Y\xeb\xa3v]\xd1\x91k\xcb\xb8\x06\xfb\xc9st\xf5\xa7\x0d\xb1_\x18\x1cJ+!\x13\xdetY\xa9Xa_hmM\x98\xe1K\xdd\xd5\xad\xcd\xccAV\xec16\x08\x02ZGc\xdf\xd43\xd0\xc9\xb5\xd5\\j\xb5\xd0B\x0c\x933\x0c\xd2\"\xd5\xa5\xbc\x07\x99\xc4\x97FvK\xc8\xa5j\xc7\x83\xad\xcb\xb3\x0f\xdcV\xdc\x84\xee\xcc\xbd0\x13\xe7>7F1\xb3\x812\n\xf7\xff\xa0\xf9\xa3\x97\xcf\x8c\xb9Q\x13\xce\x19_\xe1 \xdf\xb1\x16\xa1Z\xb7is\x91J\xce\x1e'\xb0p\xa1F\xe9I\xc7\xe7\xc6\xa0\xfe.\xbb\xf5W\xc3\xfd\xb6x\x9d\xa0\x06\x0fh\xd3\x13\x11\xad\x9eH6\xd7\xe4=\xc9(\x89]\x99\x0e/\x8b(\x0fW\x11\xa1\x10\x1c\xeeo]\x87\xb9\xf6X\xac)\x1a\x06Gh\xbeK\x8e\xd8\xf2\x1b9p#\xe2\x9f\xba\x98\xb4R\xc7\x7f e\x82\x1cB\x04\x04\x10\xeb`\xd9\x19}W\xb0\xec~#XvF\x8f\x02\xcbn\x03,;\x8e[=\xa2`b\x7ftZ\xb85\xa0\xb5\xbf\xfb]\xa1u\xf8\x8d\xd0\xda\xdf}\x14\xb4\x0e\x1b\xd0:\xd0Ck_y\x9d\xe8\xda\xf9\x83F0\xcc\xe6LX}a\xfc\x16x&\x8f\xa7\xf2(\xb1\xfa\xd5\x8b~S\xb1Z\x890\x90\x90\x1f\xa2\x19\x1e.\xba>M\xa0\xd9(\x96>>\xa1\xbd\xe5w\x9d\x1f\xe3\xeac \xa4\x89\xe4\xcc%\x19(\x1b\xa5\x1b\xd0\x83\xee\x14\x17\xef\xc5\xc7j1\x9b\x9c\xac\xa0\x0f\xb5\n\xbd(Vq\xf1\xc6_\xae\xd3x\x1b\x9d+.^\xef\xf3u\xeam\xa5\x8e\xa1\x1f\x85,.\xde\xfe\x87u\xda\xef\xb4\x1d\x86\xaa\xe2\xf3u*n\xa1\xc6\xa1\x17E\x0e=\xa9rX\x872\x87j4\x17\xfdF\xd3I\xac\x03\x94v\xd1Z\xc6\xfa3\x8b\x0eUz+\x8e\xb51\x14\xd4\x8b0w\xc4M\xb0\xac\xbef\xd3\xa0\xa5\xc9\x1eD\x0c\x12\x1c\xac)\x0cI\x1d\xa9\x93_\x0b?j\x8f\x1f\x01ZiC\x87lA:\x0c\x85\x8df\xeb\xc1\xc3\xcf\x80\xfb{\x8e,KY\x88\xde/\\\x19E\x18g+L+\xd6\xefd2)F\x98\xffRC\xca\xdf\xdaqq>=\xe3f\xd3%]Q\xba\xf3 \x8e\xe4\xfe\x92\xde\xd2\xcf\x83\x85\xbd\xed\xfd>z\xd8\x9e;\xde\xdf\x930\xb6-\xb0Dx\xb0\xb22\x9e\xec\x89\xa5P\xf7<\x0f,\xc7q\xc1:\xe6\xf4\x06\xae+]6\xf4:\\\x0c\xf2\xa4N\xa3\xf6\xef?\xd5*\x8fW;YU\xcfmf{\x8e\xda\x11\x0e\x90\xb1Z.-\xed\xb6\x94\x17\xcc\xd6,i\x9c\xa8\xb9\xf0u\xa7'pY\xef\xfd=\np\x06,\xd5\x9cr4\xeb)>\xee\x8f\x9e\xd2G\x80\xf6\xd1\xa6\xf1\xa6\xf0\x8c\xf7'\xa7\xbfZ\xdd\x84\xaa\xf2\x9d.\x04Je\xe6RH\x07\xb8\x10\x97\xbf\xd2\xf2WR\xfe\xaa6_/\xf1^\x88\xae\x03[t\xf5`\x0e,\xd8\xa2\xcb\xa9\x90%z\xa1\x0b\xbe\xc3\xcc7\x10\x9c\xa5^0\xe1*\xd8\x9ae\n\xd3\xec\x0e\x8e`\xc6\x0ci77gf `4\x991 `0\x99\xb5J\x00i7ia\xd6KZ\xda\x8c\x83\x1f!\x01\x0c\xe1\x18\x8d\x90Q\x02\xe8\xc31\x84f \xa0\x8c\xa5\x82\xa8\x98\x92>\xb1\xc6\xa4\xb6\xb8q.\x82\x92\x9b\xe3\xdbf z\xd3\xba\x7f\xad\xc6\x96\xf5\x90\x1a\x98:\xaf\xad\x11\xc9\xe4\xff[\x1b\x1a\xb66\x84\x1e\xfaz\x0cf=\xbdp\xdf\xd4E\x10\x86\x1cm}\xa5\x10?X\xac\x0f\xda0@\\X\"\xe2\x87\x984\xd99\xba\xa8\xf1\xe5\x1f\x1a\x03\x03\xa9\x91\xfe\xd4\xd8t\xa6\xeacz&IB\x07s\x1c\xcc)\xf9\n\xb2x\xa1'D\xff\xde\xc1\x0c\xe5\xa5O\x7f\xce\xed\xa9\xf7p\xc2\xf5z\xc9\xda\xeeU\xadud\xaf\x17\x17Fu\xc3\x1d\xee\x8e\x96\\\x02\xea!\x9e`P\x9e\xe3c8\x84\x1f)\xfd{\n \x8ca\x08[\x908\x0e\xdahk^\xf4\x1a\xf0\xfb\xb5\x06\xbc;z\xba\xfbt\xff`\xf4\xf4;\x8dz\xd7<\xea\xbc9\xac\x1d\x1c\x16\x03F\xaf\xc1}\xea\xbd?\xbeea\x99\x96j\x0b>y\xf4\xfa|U\x1bQ[J\xc6\x90\xeeB\x04\xc0\xc0e\xa0v!\xe1<\xae\\\xc7h\x87\xbd\xa3\x10\xd8\xed\xd5\x87\xb7\x8f\xee\xc3\xa1\xa1\x0f{#\xf6\x8e\xf6\xe1P\xe9\x83|\x97\xa9t]\x1f\xfb\x1d\xe1\x15\xd7OI}\x02\xff\xfd\xdf\xc4U\x83`\xe6p\x8a\xa9Z\xfe\xfb\xbfs\x97\x9d\x14,\x0c\xe5&=\xb5\xcb\x1dBD\xc4\x11B\x0f\xf6\xf2Q\xeaT!\xc9\xec\\\xf9&\x17\xdf\xe4\xe57\xb9\xf4\x0d)\x9f\x10\xc7`\x03\xecT:\xcf\xd2\xea\x1aaa\x0c\x90\xb9\x96\xfc\xa4\xa4\xc0`K\x8d\xcb/\xae\xb8\x0c\xf3\x9b\x08q\x86\x81\xbb\xa81\xe7\x9cNH8\x19\x13S\"\x80\x0d\x04)\x00\xd2\x95\n\x07\xaa\x85V\xf7\x80P\xd8\x0f\x11\xd5\xe0\xedYO\xb9\x1a\xe1\x92\x19!\xb8A\xaaM\x90\x13\xb2|\xa3\x05\xf7\x89\xe56!\xdcgoX\x12G\x9b\x9bt\xd89\x17\xae\xffxB\xe9\x1e\xe7\x88\x13\xb5\xec\x1b\xd8\x84\xf0\x12~\xd4\xb9v\xebIY\xfd\x88_\xfccF\x0c\x9b\xb0\xb5\x95\x8bq\x1f\xe1\xd2\x1et\x0c\x97~\xf0\xed\x03>\xec\x83\x10\x84\xc6\xa9\x1c\xe3\xd0U\x15\x1cl\xe2\xfa\xb48\xdco.\xab^\x8d\x8e\x0c\x8drK\x0f\x04\xca\xf0\x12\xcf\xfc~\xfdhN\xf6\xb7\xf5\x03\xa9\x8dZg\xfa\xf4cg\xf4Hx\xec\xaa\xfd\xb0\xcd\x00\x91\x1f\x8d\xf0\x11\x8b\xf37\xdc?88\x18\x0d)\x17Q\xbe\xdf\xe9\xd9\xedG\x82\xaf\xd1\xedF\x1f(gc+#\x18\xee7\x87P\x1b\xd5\xcee\xab\x08\x9fv\xfb\xff:\x8c\x06\xcfN\xf8\xe7\xc3\xd1\xa1\xc3E\xe1[\x9cv\\%\xb76\xa5\x12(X\x1d\xc7\xedF\x07\xff\x10\xf4W\x03\x8c\x84\xdb\xd2\xcb#$/\x9bX0T\xb0`\xda\x0e\xa4P\x03\xa4\xd0\x08\xa4\xb0\x07\x90\xbe\x13\xcaD\xdf\xebr\xc5\xa3:\xefG\xc0\x88\x10[\xd2>@\xaf\xd3\x9e\xd8u\x0d\xe4j\xc4fM8\xde\x88\xd8\xaaF\xe4b\x84\xfd\xce\xe8`\x9f\x0e2\x86S\xc6\x08\x0d\x86\x07\xfb\x03\xb8\x87\x18\xc6\xdd\x14\xc8\x1a8\xfa\xd1\xc3a\x83\xb8\xaf\xa1\xf0?n8\xdf\x0f\xd5\xaf\x87\xe9\xebx\x92>\x1b\xed\xf6\xean?\xe8\xf7\xef.\xb6\xdc\xect\x0f\xe4\xde\xd5\xdd\xd7Q\xe2k\xb0\xfb\xe3\xba\x9b`\x95\x95\xa2ac \xb8\xbe^\xdd\xf8^Pktc\xd8\xb7\x1b\xaf\x92\xe2:\"\x8f\x04\xc7ag?\x06\x82\x01\xed\xd7\x8fG\xc2\xa3\xbb\x1f\xc3>\xfd@\xe6\xd9\xc8\xcd\x18\x848\xc8\x86n\x92\xda\x01\xc7\xacXPm\xfbF5 P\x0f\x93\xd8\x81-\x8a\xf2M\x8e(\x899\xc6_\xd8\xe2\xf4\x81\x1b\"\xafBN\x13AI\xc4\x8dc\x92\x15eD\xc4 \x10\xd8\x86\x84\xc9\x81\x8c\xe8\x8d\x16n\xc5b%$\xb5d\xc2?\x10\x921\x161BSc\xa4$AS\x88\xcfJ\x88nm%\x18 \x8e\x93\n\x1a\x90&\x02\xa4\xe1w\x03i\x83\xa8h\xb7`\xd1\x00U\x85%E\x16{{.\xeaQ\x8c\xf9~pv\x10\xe4\xb3(IP\xd2\xcd\xb1\xb5\xbc\xca\xb8\xc9\x7f\xaf\x81\xe8(\x90o\x1e\xcb\xc8e\x92\xe3\xb6\xd1\x9cj\xb6\x87[\xcd\xd9\x90\xcd\x19\x8aH)M\xf5\xf7Z\x03,G*=|z\x0e\xb27\xa5\xfc\x07\x0e\x92\x8fF\x1d$\x1f\xbbf\x90\xc3\xb5\x06\xa9\xa3V\xbey\x90\xbb\xae$\x12\xef5RF\xb3\x88\xd1\x8ev\xa5\xe1\x8e\xaa\xe7\xc3}\xc3\\k\x963\x85\xcc{\xfd\xf4\xb7\x92E\x12d\xfe\x80\xe9_\x1f2\x06\xa8\x0c\x0dP\x19\xe9\xd7\xccN;d\x86\xbd!\xb3\xe6\x11+\xa4\xc72X6\x8c\x06G\x02\xd57\x8e\x07\x0c\x1d\xad\x97\x9d6\xce\x96\x84\x1d%[\x1a7o\xbd=\x18\x9e\xc5\xfa\x83\xa5#J\xef#Op_:n\x88\x10y3\x89z\xc1~\nsLv\xb6\xd3\x01]\xe2\x97\x05\x86(r\x95s\xdf\xa6\xa7\x94\x0f\xcf\x9e\xc1\x80\x9e\xa3\xc5w9\xaf\xd6\xa4\x00\xfeO\x99\xe8\x16*\xe2\x9b&[\xcc\x85D`\x84\x15\x81\xb1\xf6\x8co\xfecf\xfc\x0f!P\x86\xa3\x03\x17\xb6\x86\xa3\xc3\xb5i\x14R\xd3!Q\xd02\x9f\x84\xe1\xb7\xd0/\x7f \xf9\xb23:\xd8\xa7cE\x19B?\xd4\xfe\x07\xd20\x7f \xf3\x88\x81\xfe\x81t\xcc\x1fH\xc6T\xf9\x10\\%\xedA\x8f!\xb7\xcfm\x0f\x12\xa7F\x12}\x13A\xf3\x07\xd23f\x10\xd5\xb7o\xcdHB\xec\xe2\x1eP\xfc'\"~\x0c\xf2\xa7v(\xbeR\xe6\xac\xcb\xab\xa2ji\xdd\xf9RZ\x1a\xf6j\xc9$Ejo\xea\xedc\x06e\x12\x14\xad\xd5T\xe7\xa8\x82du\xb7\x1e\xddR\xa5\x9b\x1c\xa0Cd\xe9\"X\xd9\xd5\xe7\x8a\xa7\x97\x94\xa5\xa42E\x90\x0b\xd0\x0f\xf3\xb2F\xae\xe2HK\x12\x10\x9d\x17\x98\xf7eWz\xa7\xb0\x11 \xa5\xea\xa0\xdc\xad\x8e*\xf26\xc3\x9b\xdcO\xe7$?\xcf\xfd4\xef\xce\x86Z\x9a\xf1\x003\xd6T\xba\xa1o!K\x8a4 k\xb4\x90\xb6\xf5\x97\xd5v\x16O\xbb\xebJ\xeb\xce\x17%\xf4\xeb3*\xd9_\xe5\x18{iK\x9a\xa8\xda\xcbM\xadU.\x12\xb4L\xbf\x95\xea\xe3\xd6\xe3\x1cTn\xa8\x18t\x99+\x07\xb1\xc5\x96\x904 \xb0t \xc3#HxV\x83\xad-4\x0bK`\x13\x10I\"\xae\xa3w\xba\xb8/\xa5\x93\x11eA\x86d\x07X\x18\xaf\xf5\xb2\xfe\xb105\x8aY\xda\x1a\xedk\xf3\xb9d$\xaf\xf2\xb8\xd4Lubf\xf6\x14:\xfa\\\x98B\xef\xd7\x86\x08fa\x14\xad\x87\x084NWkg\xb6\x16\xe9 0\xa4\x06?6\x95\x1d\xa2M\x9f+\xe1\x85\xe6'.\xcf\xba\xd1\x95\x19 $\xde\xaa\x16\xb0\xdcdy\x04\x18\x80\xe8\x18m\x8c\xc5Am\x88\x8ff\xce\xb7\xaa&\x9b\xd1\xe4\xc33\xf9\xb3\x97\x19\xbf\xfb&\xf36\x80\x1d\xdb\xad\xe7\x02NM^\xc5&\xcf\x8fF{\x95\x12`:-\xc9\x9b)\xcb-\xe2T\xe9\x17a9\x00n\xab\x87>\xca\xb5A\x08\xbc\xe8OB\xf8_P\xaca\xb3\x977b\xe4\xd4\xfb@\x07\xfb\x19N`{\xf2\x9f\x9b\xbfl\x0f\xb6\x9e>\xdf\xfa\x0f\x7f\xeb\xb7\xad\xab\xcb\xed\xb9\xc9\xf5\xe6\xd7\xf6\x10\xae\x80\xca\xd9S\xb0\x06\xe8\xf4_O\x13:V\x1e\xd4\xfbfh\xf0\xb5Q\x01x\xa3\x0f\xd0\x96\x03\x8f\x8a3\x84\xed\xce\x1c\x97\x95\x83L\"\xc2\xf3\xeb\xf2:\xb4\xa7P Y`\x9bFb\x07\x07\x9ea4\xef=qD\xef\x1d\xec\xec\xee\xb6!\xdc\x90\xe7\x873\x97\x80r\x93>\x83\xbd\xfd\x9d\xe1\xd3\xae\xc2\xf4b\x89(vh\x7f\xb6\x86\xb43<\x99\xc4h\xe7\xa9\x0b\xc3\xa7C\x17\x86\x87O[\xd0\xba\xb8\x82$\xce\xc3\xb8\xd0\xe7R\x12\x979{\x10\xf0\xbe\xfb R?\x19\xa5z\xf2\xf5O\xd4{\\$\xed-u\xb6\xd2\x9e] \x97\xc9\xfe\xce\xc8\x98BP\\\xfd\xa0\xe2\xfe\xc1]\x8e\xb9\x8f\xc6>lR\xban\x8b\xa7 8>\x86!3t\xd9\xe2\xa3\xd1\xd6\xc0O\xc5\x84\xf3==\xc6c>\xc9\xab\xfd\x1b\xb3D\x15]\xfb\x8c58d\xd9Y\xba\xd2\x1f\xf0\xce\xc4\xad\xe3\x10\xf37\x1a\xec\xf6l}\xb4^\xeb\xf0\xec\x19\xe62\xc0\x00\xdb\x98\xd0 \xa6w\xa3\xc3^\xdd\xc2y\xea\xd7\xaf\x9d\xf5\xfb\x85I\x17F\xa3]\x16\xc2\x03\xf6\xe1 \xed!\xf6n\x8d\xbev\xa0F\x1c\x07O\xd9\xa0\x8b3 \xd2i\x05\xc9\x94\xc0*1x\x91\xc9U\xb2\xf1\xee>b\xbc\x87t\xbc\xbb\xe4\xeb*I\xf3\x0cN\xe0\xf7\x07\x89v,\xc1\x106<\xd2\x1b\x9b7#\xf9E\xb8$I\x91\xc3\xc2g~\xa0\xd7\x84\xc4 B\xe6W\xf0~\xd04\xe0w7\x10D\xc4O\xbf\xa1\x89\xa2\xb9\xe0\x19n\xc5\x18`e\xef\xab\xe8\xc2\xe5#\n>\x95o\x16T\xe3\xc9 \xf3\xe2\xda`\xf9\x8e5\xf5\xd0C\xb6z\xecv\xd4\xab\xcf\xb7!\xaab_\xd4\x97\x81\xc8\x0f\xa17\x955\xa6\xef\x10U\xb2\xa5SF\xcb\xd79\xfc\xb7\xb6\xd0\xac\xab\x94\xd2v\x07\x0f\xa8&l\xa3Z\xac\x8d\x95\xa0\x1d\x03f\x9d\x11\xdf\xc8\xbc\xa6\xb4\x10O\xe5\x9b\xb1\x8av[\x13k\xd0\xeaU4-\xdf\x19\xe6\xc9\xd4\xa9\xda\xe2=\xad\xdf\x8e\xd5,\x89\xad\x1d\xa3M\xa8Y\x15\xcb_\xb6\xb4\x9a\xe8\x1e\xe7\xa9\xcd&Jb\xb3\x00C\xbf\xd4\x9f\xcdx\x12\xda\xe6\xc6Y5f\x04\xb3\xb7b\x1a\x0b\x9bW\x05\xa5X\xe0\x14[\x14\x01\xc4\xed\x08\xc3\xa7b\xdd.D\x92\xecuj;\xed\xfbu\xdah\x16\x89\x88\xc0\xc4L\xd2\xb3\xad\xb0W\x1a\x8a\x01\xfb\xd8\xc6KR\xa6S\xf4\xed\x083\x11\xe9\xd79~@\xb1d$\xe0\x8aA\xc4x\xf6\"\x9e\xf2cv\xe9\xa5El\x9b<\xfc8(\xe4&;v \xf0D\xcfl\x8f\xea\xe6N\\\xfd\x8ev&T\xa7\x98K^\x86U\x1a_\xe9\xa1\xdd\x16P\x12Q \xab\xc8G\x14\xc8b5h+\xa5\xabV~\xe1\xf6o\xc6\x8c\xc2\xc4\x95\xda\x06\xf9\x12\xf4\xc2^\xe2\xean\x08d\xf2K\xc6\x9b\xe6\xe6a\xad.@\xa3\x01\x8eL;\x1a0\x8f^\xfb\xe6A\x05\xd8C\xebN\\h\x858(\x0b\x9c\x15(9\xe1B{\x96\xe6\xe8D\xcaZ\xaa\xab\xee\x86n\xec\xaa\xc5\xc4\x8b\xc9\xd7\xfc\"\x0c\xbe\xb4\x12\xa7b\x9fR\x8a\x80\xd1\xbc\x8d\xb8\xcdM\x93!\x94W\xa8\xc5\x9e\xc1\xb0 \xce\x12\x17\xc4\xcc'\x93\xb2*\xea\x97G\x10onRr-f\x86XR\xe8\xe8F\x98\xfd\x883\x1b\xe4V\x80\x0fe\xf7\x98\x15Z\xa2\x07\x03\xfa_aO%T\xe8\xc2B\xb6\xabG\x00\x9b\xcfF> <\x1c+[\x8e\xd5\\\xd4\xaaM\xbc<\xcc#\x0cJz\x9d&\xb7\x19I-\xfa\x90\xff\xe6a\xf2\x13\x8f\xc47H\x07\xd2\xdf~:\xbf\x11y5\xbd\x1b\x92ft\xfeX$\x93\xf2>+K\xe3\xbb\x1b\xfcn:}\x1bf9\x89\xb1\xde\x1b\xf6\x12\xdd\xd1\xd9\xef\xd9L\xfcL\xc92\xb9!ja\xf6\xf4y\x14\x89\x17\x99xC\x96a.~\xafR\xb2\"q\xa3%\xfe\xf8C\x1c4\xea\x8d\xa4\xea\xccK\x8d\xef\xc0\xc9e\x1dz\xd7a\xdc\x99\\\xa5A\xb5\xae\xd2$ YV~\xccC\xa4HA\xf1\xea\x8d\x04\xb7\xd3\xb6\xf9\x16\xac\xd2\xb6\xa5|\xb6\x98\x86\xe9\xe3z\xc6>\xed\xeaW\xb1\xf4\xb3/=z6\x90\xb6>h\xb8\x10E\xc5o\x15\x19AEO\x90KL\x9c\xcc\x90\x98G\x84\x1a\xa0\x8a\xd8\xda\x90Uu:}\x0f\x06\xb1\x15\x03\xf5\xcb\x8aU\x19C\x83k|\xc4@\x9aH/\xd5\xe2\xd0\xca\xbe\xe6\xa4\x0bk&f\x94\xd8\xc0p\xc7'0\xa4\x88E\xd2\xdeT\x98jx\xc9\x835\xc8\x8f\x9a\xf4DlLx+duZ\xb0\x19\xd7\x07\xa8\xc2{\xb5\xd7Lt\xcfP{\xea\xa8\x02|\x9fb\xdep\xe2\xd7\xb1\xaeof\x961\x17\xd6\x86\x88\xa2\x19\x0b\xd0 \xc3&\x91\xa1\xa1GnHzW\xcb\"\xdd\x95\xda\x0c\x19\xb7x\x92^j\xf8\x1bts\xb1\x19W\xcdp2\x9b\x04\x17B\xc7a:\xb5\xd05s\xf2Z\xde\xbb1\xf15\xc2\xb5 \xc7\xb8\x84cN\x0f;8\xc5\xe0\x14C\x1e\xd98e\x07\x1c\xcb\xb9 )\x85k3\xa9\x9d\xe4-\xa0\x16\x97\x00]\xfb\xa6\xef\x03}6\xc4Y\x9a,[Yv;4\xcc\xc3\x83\xf1\xb8\x8f\xbc\x94dE\x94\xbf.\xe2\x80\xae%\x17\x9f\x04\xc9rU\xe4~\xce\xd9\x94\xce\xcd&6Z\xe3\xe5\x03\xab/#\xf9\xa7GWJgH[q\xed\xa1L\x0c\x88_\xb9wuE\xb2w\xc9\xb4@\xf6\x8d\xf2i\x98:\xd6/\xa2\xfc\x1dY&,soB\x9f\"\xda$\x02\x8b\xbedH\x94\x11\x1d\xe5\xcb<-\x82\xbcH\xc9\xb4D\xb6}\x18\xefGP\x99\xbeBe6\x99s+\xc1<\xb8F\xea]\xc8\xfeM\x1dg\x87C\x06\xb30\xcd\xf2*^\";\x18\xfc\x18X\xf5p\xbb )\x01\xe2\x07\x0bX\xf1\\\xbb\x94\x11\xf0A\x9c%\x9a\xa3\xc3Gk\xb0\xb2SG\x0d\xa0\xd0\xbd\xc6\xd3\xf8~!wYC\x88UR\x8bq\x1dU\xb5\xf9\xc3\xd3\x0dY_\x0e\x8e\xdb\x93\xe4\"Z\x84\x9cW\x08\x81\xd3~\x03F\xfb\x11N\xfb\xe5\x93\xb4\x9d\xee\x03i(^J\xa6E@l\x85\x13\xea\"\x98\xc9\x84R\xcb\x97\xcc\x18R\xa3\x8es\xe1\xf7\x07E %\xb1\x9fu\x91\xb6\x8f\x04L}\x99\xd3\xf5m'z\xb5\x97\xc2\xa7 \xee#\xb6\x87\xc3\x03\xe5@D\xc6\xc6\x1e\xed\xee8zV4\xb6\x87\x83\x01\xa5\xfc\xda\x1a\x00Y\x84'\xd2'$6Z\xabK\x83\xea\x91TLZ\x12\xcc\x18tM\x96\xb4\x1a\xea\xc1\xaeaD\xed\xcc\xf5\x86\x1c\x0b\xd5\xc4G\x8b=\xb6\xf1H>Z\xedq\xac*$\xeb\xfb\x8e\xc9\x9c\xc6`\x8d\xbc=o\xcf\xd2\xad\x12\x8d\xfd\xe1\xd5\x153\xd4\xa4\x7fO\x84\xdb@o\xf0\x8d\x0e\x0e\xd6\x86\x9f\xcc\x85\xca)\xe7j\xb2\xeau\xa7Q\xbf`\xf7\x0ev\x95\xe7!\x7f\xbe\xa7<\xa7{\xc7\x9ap\x9c\xf8\xbe\x88\xa2K%Tx!\x17\xf8,\xd2\x9d\xab\xa524n?E\x13\x04f\x0fx\xe1\xcf\xcb\xcc\xde\xdf\x01R\xd2\x89Bo\x0b\xcc|2\xe6\n\x16\x08c\x8ev\x99q'\nF\xc6\xc8&?\x16\xb0{OGz\xc8>\xdd\xeb\x9cx\x0d\xbd,\x96q\xc2\xdej\xb7E\xca\xb2\\\xc4%\xd8\x1e\xdb\xf7\xd1Su\x96Y\xdf\xf7w\xd41\xb1Uqp\xd89$\xc3\x0c\x85\x0c\xde)\x83w\xb26\xbc\xf5\xb2> !\xef\x0e4#\x91NXJl\xb4\x93\xd4\x82V\x99h\xce0\x89s c\xa42\x84U\x98\xf9\xbc\xab\xbdx0\xc0\xad>\x96\x90\x1f\x14\xfbR\xb5\xa1\x17\xc6\x0b\x92\x86\xfc\x149\x1c:\xcd3-\xb6w\x06\xeaL\x16\xac\xae\xda*\xac\xea\xb2g.\xf8\xd2\x9br\x80\x19\xae\xbd\xa2\xd2\"\xf0\x14I\x83#\x88\xe0\x18*uFD \x80\xe6\xda\xa5\x04t6\x89\x14\x18\xce\xaa\xfa&\xc1%\x8a\xb9\x94G\x94)\x93\x1f\xb4\xebwg\x86C\x879\xc7\x88@\xda\xc9\x0cfU~IJ\x12\xce\x1a\x84\x96_W\x95\xb9P\xa8\x0f\x10\xfbo\x08\xd7\x89\x94\xf8S\xff:\xe2\xb1c\x17aV=9a^\x80\xf5\xf2\xb7i\x98\xd7\xcb\x97Oxy\xa6q\x89\xa2\xe4\xf6\xaf~4\xfb\xb0\"1'\xd3\xeb\x15\xd5K\x94\xb55>,\xabL\xe2\x80\xd8\x16\x89\xa7\x96\x0b\xabvp6\xb5\xf4\x9a\xba\x85\xc3\xc1\x95\x18\xc0y\xee\xe7\xc4#\xf1\x94L\xe9\xcb\xb4\xd4\xc5\xd9S\xd6\x85.\x1d}c\x0e\xb16[E\x0d\xf4\xe2;\x99\x1d*\x1f9\x19.\xaf!\x17,\xd1\xaf\xbf\x86\xf3\xc5\xcf~N\xd2w~\xfa\xc5r\xd56\xe2bIRZn\xdc\xd0\x85\xcfI>n\xa7\x98\xc5\xe6\xd6\x00b!7[\xdf\xfc\xd5\x80\x1c\xb7\xd7P\xa6$\xcb\xd3\xe4\x8eL\x1b\xdd\xef\xddE\xc9\x9f\x86\xf5V\xacS\xec-]@\x8d\x12\xb5\xf1TK\xac\xfe\xa5W\xf6\x0d\xbd\xce4\x80(\x0b(d\xb9B\x08\xd4\x06\xa2\xc7\xc8\x7f\xfc\x10*\xfd\xb3i\x10\xb4\x88Q\xe1M\x19,I\xe1z\xc5\xbf\xea:\xe4\xb1Av\x80\x14Q$6,\xae}W\xdeGyM{\xff]\x0e\xca\x9d\xe1\xc8\xb1\x1f{\x8a\x93\xca=\xabT\x91t\xd1\xe8k\xf6o\xff@w\x90\xb3\x10\xf7\xfe\xd7G\xf6;\xb1\x07.\xd2\x1e\xdf\x00\xccu\xcbk\xa9\x94\xa1flvl\x1f:]\xf2\xbe\x90;~z\xe2l\xfb\x98$\xc2\x16\xc0\xc4@\x0b\x82\xa6\xf9\x1d*8\xf4\xb2;\x19\xc1 \xc3Pz\n6\x05\xd6F\x0bez\xd0\xd2\xef\x1b\x86\"\x1a\x9a\xb2}\xd4D>\xca\xf1h\xa7\xe7\x8cm\x8d\xf6,t\xb7\xc5\xedVP.\xde\x16\x9bH\x03\x1f8\xe6\x1b.I\xa2\xf3\xf07R\xe2\xad:L\xe8vl\xa4o\xad\xdd\xfa((\xab=*\x1a\\&\x16\x9cNi\x9d\x94\xb9I\xc6\xed\xa8@\\%\xfb\xda:-q\xad\xcf\xdc\xba\"\xf6\xe6$\xa7\xf7\x88\xac\xd0\x01\xca\xa7O\xcb\xf1\xa2czu{\x02\xc3\x81C\x0b\xa4$\"~F\x98\x84\xaf)\xa1}\xd0\xa8oc\"\xd2\xa9b\x83\xe9X\x05\x08\xbd\xf2\xdbD-\xd5\x0b\x06\x8fY\xe4 \xeb\xa6\xd6Y\xe8\xa0[\xec1\x8b\x10\xe0\xe8\xc0\x01\xda5\x0f\xbauO\xab\xe8\x03\xce|\x91\x92\x06@\xbbD;\xe2\xfa\x16h\xa5\xdf\x05Zi\x19G\xa9\x114Z\\\xfd\x01\xd6\x88\xc8\x00z\x98\xcd\x92\"\xed\x02Y\x8bT\xf1[\xa0\x96|\x17\xa8%R\xf4\xa9\xd4Q\xf5\xf9\xe2Z\x0bp\xae\xd6\xf1\xb8\x8e\xca\xf4Gg\x81O\xdb\xe4ju\x03\x7fmq\xb3\x98tO\x95.%\xfcy\xb7l\xc4p\x94\xa7v\xb2\xfe9.\xf7\xe8\xd1-s\xb9\xd1#\xc8\x08\x89\xfa\xda\xd1\xcb\x8a\x0e\xb5\xe2\x96\xe1P}\xce\x98\xfd\xe1\xfe\x81c[Y\x1aX\x1a\x9e\xff5\xefH)_k\xca\xdfX\xfe\xc1\xc2\xf1\xb2U\x14\xe6\xb6%J\xcaR\xd8\xd8\xde\x1f8\"a\xf99F\xca\xe8\x03$\xce=\x93\x9a\x05\x98m\x94~\xe1\xda-tr\x84\xc8d\x0d\xafx4FH\xe4\x87\x14s[\xb1\xbf$\x16\x1a\xd1$\xd5=7\x9fDIxi\xd2cK\x9f\xf9\xd5\x17>/\x87\xf2\xd6M\xf6{\x0c\x19\xb3H\xe0\xde\xcb\xb9\xe3\xb0\xa8b,\xb6\xcbi)c\x871\x14\xe2\xb6\xf64\xa9\xd6\xc4\x18\xec)\x89HN\xf0\xbd+\xbd\x92\xd7\x94c\x97\x93(3\x85\xe54\xb5hu\xf84h!\x87\x04\x14\xa7}&>Ja$a\x87\xdc\xfeZH\xa1sM\x94z:9\xf4\xc1\xa9\xc4A\xc0\xb8\xcb^\xa5\xd76\xeb\xa4\xbe\xf5\x9bo\xb4o\x10\x81\xef\xeckw\xdf\xde\xaeJ\xc53Q\xdb\x81Z<\xe3\xc5UYj\xc4\x9f\xab\x12\xbb\x80?W\xeb\x99\xf1\xe7*2X\xa1\xd0\x8ci\xb3\xce\"B\x0f\xc4z\x81\xa9T\xe0\xb5O\xc9\xe4\xbbz\x81\x05+\x10%\xb1\xbe\x82\x1b8\x81\xb4\xfeh\xd9I\xb47t7\xd0<\xc8\xe7Z\xb2\xf9\xe5\"\x8c\xa6)\x89\xc7\x86sx\xe9\xaf\xc6\x10zK\x7f\xd5$\x0b\x80 1\xcf\xfc`A\xcb\xf0\x9f\xfarAR\xc49-\x85?\xf4e\xf2\x045\x9f\xb4\x14\xff\xa9/\x97\xc4\xd1\xdd\x18f\x8dw\x1a\xca\xe5e\xb2\\%1\xa1M'^y\xd3,\xf7\xb1HI\xadl\xedA\xb3|m\x05\x8cA\x03\x1cy\x86\xc7\xa0\x81J\x98\xfd\xe4G\xe1\xb4,Rx\xf5'\x9aN\xa6\xc9\xea\x82\x99De\xa6.\xbd\x8c\xfc,\x1bC`z\xcf\xd7\xe4\x18\xa6\xa6\x12\xef\xc2\xafa<\x86e\xf3\xfd\xab\x0f\xef\xc6\xe07\x9f\x97J>\x8d\xf1\xe9\xd5U\xb6J\x89?\x1d\xc3M}q\xea)\x829>\xfdc\x90Nc\x93\x87L\x12\xf0\x94\xb2\x1e\xf6h\x7f\xbf\x12\x14V\xe2\xa5\x85\x9f}\xb8\x8d\x85\xc8P\x8b\x9cF\xfb\xaa\x9eO\xcf\xa1~!wc\xd8\xd0XA\xa6d\xa6\x7fqu\x95\x91\xc8\xfc\x0e)\x84\xb1\x9a\xbeX\xeb\x10\x9a\x19O\nI\x9cG\xbc\x94T\xbbJ'?\x8e\xfaU\xf3\x85\xdcI\xd5\x88_BU\xa1\xe1\x1cX2C\x03Y\xd2\xd4*\xd3\xeb\xcf\x7ff'\x96vE\xe6\x98^\x994_\xe0\x1ch\xb6\x16NA\xdc|\xbeJ\x93U6\x86B\x03\xff\xe46\xa6|PhZ\xd6P\x01\xa7\x8a\x0b#\xbd\x0f\xea\xc7\x88\x060:`\xa4\xcc\xd0\xfaw\x1d\x97\x06&\x0b\xf0\x15\xe8,\xc0\xd1\x9b\x96\x11\x04:\xde\x19\xd5S)\x84t\xf1\xe4,3\xcf\nm9R2s\\\x88\xc4\xc3\x19:\x98\xc0&\xa0\xd2\xcfqky\x06=\xb6\x84\x05\xe91.\x9f4\x8b1z\xb7^\x10\x9f!\x1d\x14\x96\x921\xe6\xb5\xb6Q([\xd3\xe6\x99\x87}f\x1f\x93OR5\xe3.\x05\xdfTg\x18\xb5\x05\xa3&d\x98\x0eh\xea\x80\xef\x05\xfc\x8c\x84Fl\x8f2\xe2\xc3\x14\xbd\x944\xcb\xb4T\xf2-J\xc3\x9e)\x85\x11S\xef\xdd\xc01L\x8f\xe0fs\xd3\x81\xc5\xe4\xa6n\xd8s\x83\x811\x9b\\\xee\xc0\xad\xf7\xa9\xee\x8f\xf8\xd0\x18 \n\xdf\x88\xb0?\xa3\xf0\xcat=\xa5\x9d\\\xa21\x87\\\xb2\xd9|\xb5.\x96N\xcd\x96\x8c\x02^\x9a\x81e\xc3\xe0\xfeA\xb77\x02\xba\xdag.\xac0\xa9&z4\x05E\x9a\xd2\x03\x10\xfc\x1aK\x13\xd4\xc9\xaa^Fp\xca&C\xb7\x9e\xd2 P\xbbWs\x8f\"\x0f\xae\xa4P\x9a\xa7G\xfa\xf3x\xfa\x89\xc5F\xf8w\xd2\xa9t\xa8\xc6\xe81\x86\"w\x19\x96\xa5\x7f\xf8>\xa0?\xf8:'\x1e\xc3*\xf4\x17b\x1eu\xfc\x12M\xd1\x13_\xf8\x0c\xb8\x94\xa8\xb4\x7f\x7f\xa8*n\" \xd4\xba\xd0-\xdc|\xb5\x00~8h\xce~\x0cj\xdd2\x16\x8d\x87_\x17\xd2\xf1kHg!\x90\x0e\xdb5\xe5\xf2\x90q\xd0T\xc5A\x0c\xdel\xe1\xe39.\xaf\xe9\x12mi\xde9\n\xb6\xf1\x0d\xd8\x86=\xb7e$F\xf9\xbb\xba~\x8c\xe2\xbd\x15\xf3\x81\x99\xd1?cqG\xcbj\xb0\xd3rM\xec\xb4t`\xd5\x07;-;\xb1\xd3\xbc\xc4NK\xc7\x85;\x86\x9d\xee\xe0\x18\x96GpG\xb1\xd3|rW\xc7Nw\x06\xecT\xeb\xd0\xbc\xd7\xfe\xe7{c\xea\xc2B \x81\x9b\xba\xfe\x9c.\xfe:u\xfch&\xb8\xa6Gc\x0bD\x90\x12\x0c\x8d\xc9\xad\xca\xa4i\xf0'\xe8&M%\xb1\xd3\x81\xe3\x9d\xdf-\xaf\x93HO\xe9\xa6\xebU7:\xd4\x9b\x0d\x0d\x0f\xbf\xcd\xd6m\x83C!\xa9\x0c\xd0q\xc1\x7f\x8b\xdd\xdb\xc8 \x81|\xaa\xaa\x19\x19\xd3\xbf\xdf\xb0#bt\xf5\xfe\xb0sdf\x94+E\x12\xe4f]p\n\x13r\x89\x96g\xfe\xb7\xc8\x131\x1e~cxJ\xf8\xbb~\x13\x11\x1aB\x972\x95\x1b\xa9\xechH\x13W`\xe0b\xd8lD\xe1\x11k\x7f\xc0j\xa4\x93I\xfbF\xe8\xddV\x02\xa7`m\x0d,J_u\x8c\xbf\xc6p\xe9$E\x9cUb\xe7+F\x1c\xea9C\xc4\xcb\x8a\x15I\xaf\xb8yq\xc5lU\xd6c\xacR;\x97eqM\xec\x15$\xb1\xd0E\x9a\xc4\x17\x98\x98_\xcb @\x87]\x8a\xb8\x84\x89\x82\x9e\x0b\x03\xd6\x8dY8/D=\x1a\x9f\x81\xda\x93\x87\xbaU\xf1\xa3\xc0\xd6\\\x0e\xaa\xd7\xb9\xc2\x88\xc45(\xd7\xe0Z\x9f\x80\x98\xdc\xa2\xe9r-.w f\xf8\xfe\xb6\x07\xfb\x9d\x9b\\\xb7kj\xa6\xceJ\x98\xd8\x97~\x1c'9\xd0\x86\x11\xc5%)\x14q\x19sH\xbb[\xbe\xcb\xa0\x1a^\x1f\xcaxyt@\xfb\xa0\x81@P\x10\x91b\x04_\xba_S\xb9\"\xe6\xfb\xdb\\\xdd\x9ch\x19\xab\x99c\xe5\xfe\xf02\x9d\xd0\xec\xe3\xc9\xf4\x87x.\x89\x93\xa8>\x04\xdd\x0c\xd9\x03\x17B1 g\xed\xc3\xa9\xe7\x8c\xb9\x06\xa0\xb5\x18\x0d\xab;M\xf2\x99\x16f\xab\x18\xff\xf7\xc3\x8cr\xa8\x98X\xe6\xfe\xbeK\xceT\xc6\xd6\xe6Lm\xccX*\xd2dj\x1b\x10|\x048\xca\xc7\xa5\x9c'\xed\x92\xf30S\xef\xfb{a\x06\xde\xc4\x0b \xefg/\xcc\xde'\xf9\x82EcH\xdd\xda\x0b\x06\x8a>\x04K7=W\xf5An\x83\x0b\x93\xfb4\xa1\xee\x04NBpjbB\xc9\x079\xd5o\xad\x99\x94\xac\x88\xdfo\xdd0\xcf\x1e\xf5\xe8\xc6\xa5\x133\xda;f^\xd61lb\xd4L\xccP\x85\xc5\\\xefL\xcf\xc1\xe6F\xf4[e\x81\x1a\xcby1\x18/\x8c\x83\xa8\x98\x12\xa1\x95\xe9p\x1fG\xef\xe0\xb2\xad\xda\xeb\x07\xae\xc9\xed[S\xb3\\\x9bEM\xee\xe5\xfe\x9c\x9b[\xd3_O\x9eP\x1e>\xa4\x8b\x88\x89\x92\xe9O<\x13M!a\x1f\xd0\xaeJkJ\x86ofa\x94\x93\xd4n]\x91PAn\x8b\xc7J.\xb1v\xaeV*\xad\x93\xe6\x84i\xa2\x16r\xf3\x15\x9c\x0e\x14:\x88\xdf\xf7\xf7hK\xc6\xde/WQ\x18\x84,\x1dIy#\x97 _\xa5\x12\xe5\x8d\xae\x8e\x9e3\x85\xb2A/J\xfc\xe9\xbfs [Y\xe0G~jq1\xbex%\xd3Y\x89m]\xa0s&\xbac\xc6I\xbc\xc5\xbeA\x84LO\xbc|A\xa0\xec\x7f\x14f\x18\x07\xdf\x87,X\x90\xa5\xef\xc1\x1b\xf1*%Y\x12\xdd\xd0\x13!\x99AV\x04\x0b\xe6\xed\xdf\x08l\xe3Y\xcdIe\x86=\xc9r\x15Fd\xfa\xa6\x82\x9c\xcf]\x08,\xd1\x01\xcb\x85\xc9\xa5\xfa\xc1\xd9\xd7\xe6\x07\x02\x9e\xda\x0f(m\xf9\xce_)\x14v\x03\x9etK\xf2\x1d\xa4\xd5X\xd0\x8b\x01k\xac\x95\xdf\xe3{\xf2kA\xe2\x80\x98K,\xfd\xd5\ns\x1f\x98\n\xcc\xfc(\xba\xf6\x83/c9h\x97\xb8\x1e\x94H\xf3\xd0q\xea\x8b+\x9e\xb0\xadx9\xc1m\x8af\x16\x9eh\xa9z\xa6\xf1\x15m6GQ9a\xa8\\\xe7\xa7|\x84q\xed\xf3#\x16,v\xe8H2'R!!U\xae\x08Fj\xd2\xd6\xae\x16\xc3\x9aP\xc9Jz\x15\xde\xab\xb3\xd7\xcf?\xbf\xbd\x10\xfa\x95R\xc1\xdf\xb6\"\xc4j\xa8w3\xbb\x0d1\xb2\x9c:h\x1d\xdc\x03?#0\x1ck\xe7\x03\x83'\x8a~)p\x9c\x0c\x0c1\x02\x0c\xf1\x96\xb1\x9d\x91\xb9\x1d\xb9b\xb5)\xd5G\\\\\x86\xa6\x04\xd3\xa2\xfd\xa6\x86d~N\x93x\x0e\xcc3\x141\x88h\x12\xd7\xcf9\xc3&|\x16J\xe9D\x9b\xba!\xe4y.SA\x0e\xa2\x83u^{\x92;.l\x90^\xf1_\xc49+[K\x17\n\xa2R\xf0\xe6\xf9\x8a\x04\xe1,$\xd3\x12-\"C\xcfQc\x06v\x92RD\x19\xc6\xf3\x88\xf0\x11r_]\x07\x83\xc6\xfba,pn\xed\xad\xa72\xb5k\x84\xb1\xd1\x0d#\\w\x18\x7f{\xfe\xee-\xc7\xde\xb51P\xbci\x1a\x81\xf4\xae\xd1\x7f\xb1\x8f\xc9-\x14\xb6\xe6\xdcb\xc7\xa7V\xaa#\xf0\xf8X\xf5\x05\xac \x93\xbb\xad1\xd7$\xf6\x86\xc3\x9a\x19\xdf\xa1\x96\x96K\xda\xe4\x956\x81'\xf4\xa5\x1aXLn+\xd4\x1e+\xef>\x9f_\\}>?\xbb\xfa\xf8\xe9\xc3\xc7\xb3O\x17\x7f\x1b\xeb\x92\xa1\xfe\xf5\xf9\xf9\xd5\x8b\x0f\x1f\xde\x9e=\x7f\x7f\xf5\xd3\xf3\xb7\x9f\xcf\xc6\xb0\xab/\xf5\xfe\xf3\xbb\xb3Oo^\x8aR\x87\xfaR\x1f?\x9c\xbfA\xd6@)>2\xd4\xfa\xe1\xa7\xb3Oo?<\x7fu\xf6J\xed\xc6\xce\xa8\xf9E\x18\xd3\x85\xf1\xea\xc3;\xc1\x10\xbfD\x19[\x97\xf3\x12H\xb2\xd1P\x7f:\x02'v\x89\xc7\xab\x0e z8\x98NS\xe0\xe2h\xe2\xbd\xfa\xf0\xeey\x9e\xa7\xe1u\x91\x93\xf7\xfe\x92d+?\xe8\xfe6\xd3\x7f\xdb\xf5Y$>\x13\x00\xe8\xf5U \xbez\xc7\xe3\x9d\xbc#\xf9\"\x99\xf2\xef\xf4\x98\xba\x94W\xccP^\xe1\x85\xd9\xcb\"\xcb\x93e\xd9_J\x18\x16\xdeU\xe3\xb9\xb0\x97\xe4^U\x9a/\x9d\x16\xba\x1f\xf0`]\x95s\xa0\xea\xd7fL\x12f[\xbb\x87\x96\x0b\xb3\x16co\xdaw\xa4\xcd\xbc&Y\x98\x877\xc4X\xa7\x1e\xcb\xf5\xab\xfc\xc3\x0dI)\x07E\xa6\xc6\xe1\x9b\x90b\x93\xc9\x95/\xc3F\x06~\xf2/<\x05\xe2\xb0 \xf8L\x1e\xa5x\xa6\xefd\x19*(\xb5\xad\xbd\x01\xee?\x174[\xb4ms\x03\xdf\x9a7\xe8\x9c>\xeb\x08[\xb5\xf0j{\x02N\x14sA\xf9\xd2\xbbi\x00:\x96k\xb1\x88\xad\xd4\x8e;\x0es|\xcd(\xaf\x17\x19\xbf\x92w\x1b\x9c@\xc4\xca\x07\xc6\xf2\xf5\xcd\x06'\x10\xb0/dD7\x99]6lv\xc4\xa5\xe1\xd7jO4\xbeq\xd6\xf8\xf9\xd6\x7f\\\xf9[\xbf\xfd\xf2K1\x18\xbc\x1cl\xe1\xdfW\xfb\xec\xcf!\xbb}\xcdn_\xb3\xdb\xd1\xeb\xd7\xf4\xcf\xce\x01+\xbcs\xf0\x8a\xfdyMo\x87\xaf\xf1\xedh0x\xb9\xc5\xfe\xbe\xc2?\xac\xf0hx\x88o_\x0e\xd8\xed\xeb3z\xbb3\x18\x0c\xe9\xed\xab\x03\xfc\xf6\xf5S\xf6\xf6\xf5\xab\x97x\xfb\xea5\xbb}\xfd\xfa\x95&|Is\x05\xbdyu\xf5\xfc\xe2\xe2\xd3\x9b\x17\x9f/\xce\xae\xde?\x7fw6\x06k\xea\xe7\xfeVJ\xfc \x0f\xa7Vs\xfb}\xfa\xf0\xe1\xa2\xed\xa34Ir\xcdg\xf5/\xae\xce/\x9e\x7f\xba\xb8z\xf9\xd7\xe7\x9f\xb4F\x85Ji^\x0e6\xc1\xfa\xe5\x97-o\xb0\xf5\x14\x81\xfc\xe2\x00\xa19\xe0\xc0\xddg\xd0\xdcy\xcd\xa0\xb9;\xd0t\xa3Z\x1cz\xae\x1e]\x0d\xb3,d\x8e\xd2\xf1\xd4O\xa7\x0c\xff\xeb\x91y\xcbQ=n\xa4\x16\x00\xb4DV\xca\xf7\xa1\xb3\xea\xfa \xa6\xfai'\x13jj!3\xe2\xc00\xf5\x03\xb7\xbd\xb2I~\xe9\xc8\nr\x8d\xd6\x15\x8c\xa8B|3ln7\x13)\x8a\xe6\xcdFS\xcf\xef\xceO\x1c\x1c\xee\xd4\x18\x8a\x1df\xa3\xfc\xd4\xc0W4x\n\x8a\xef\xfc`\xf1\x89\xcc2.\xe1Bi\xc7\x157\x9d\xe264:a\x87\x9e\xcfX&E\x9cK\xf6\xf1\xea\xd8P\x98\x1f\xa2\xb5\x94^.V eZ\xaf\xc6\xae\x7fi\x94\xe7\x10\xb5\xdf\x92\xce\xa7\xf9\xd2K\xc9\x8cI\x91\xe7$\xffD7\xff;\xda\xea'\xe2O\xefl\xc7#\xf1\xaf\x05)\x08z\x04R\xcc\xdc\x86_\xe7$\xffk\x92\xe5\xef\x93i\xe7\x8e(\xbb*}c\xb7:6\x17q+P\xb5\x8dxSRN+3\xb1S&\x94>S+n\x08\xb0\xeb\xfd\xe0\xf1\xf3Z'74M+\xe3\x8c\x94^4'\x12\x95:(T\xc6\xc4\x13!\x97/_\x05I\x9c\x93\xafF\xdfdM\n\x10\x90\xd6S\xeae\x8b\xa4\x88\xa6\x9fWS?'\x08\x14_\x9ft\x18\xf0\xacA-B\x1d\x82\xbe\xc3\xec1\xeb \xb0\xc5\xa8]\xf6\xd5\xe3\x16`\xdcc\x016\x11P\xdbT\xadH:K\xd2%\x1b\xef\x9b\xd9{\x12\x90,\xf3\xd3\xbb~\xfe\xcb\xc4\xbb*\xf0\xcb\x17~\x1e,\x98\x86\x8f'\x8a\xc51\x9ajo\xac\x9f\nk\xe81`\xf8=0\xe0\xc8\x10\xedo\xb8\xfbT\xab?\x1b\x19\xfc6w\xf6\xd4\xf2\x183\xad2\x08\x91\"YN\x93\xa0\x10\xd3\xab J'^{\xe2\xc7\xbb\x84)q\xf4\xb5\xc5\xfeM8\xc7h\x9erf\xe5\x93\xe6{\xaf\xc8H\xfa|\xce\x1b\xde\xfe\xe5\xfal:'\xbfl\xff2\xdd\xf6r\x92\xe5\xb6\xa6\xa0\xf6\x1c\xd0\xf8x\xd0\x8d\xd7\xf0\xa9\x00\xd9\x82\xcc\x8b\x93\xa9\xc1:*\xe69V\x995\xa7~W\x8b8\xedz\x8e\xa5\x16?\x9e\xc7\xb1\x8cK:\x00\xc3Y\xb2,h\x93\xf4\xd2\xc5\x1d\xa5\xd9\xbch\xc5Z\xed\xb6E\xbe\x8c0\x8a\x1c\xda\x8e\xd1;\x07\xc6\xd2{\x8aP(\x1c}V\x00\xf1\x8bi\xfd\xd6\xd6]\x84Q)\xbbv\xd2p\xc8=\x16(\xdc\xf0?\x94db\x02\\\xdd\x0b:\xf7\x95\xd9B\xed=\xa5\xe1\xea2\x0bf\xeb\xc1\x03\xeb\x89\x92\x82a\xf9\xfc\xe9\x0d\xc6\x83\xd2C\xe1\x1c+\x10\x85\x84\xd2\x94A\x8e\xb7\xaf>\xbc\x93\x7f\xb3\xca\xc5\xddE\xf2\x85\xc4\xec\xc6\xcf\xfd\x8b\xd4\x8f\xb3\x19I\xdf\xe4d\x89\x0f_\x87\xbcQ\xba\x9d\x9fG\xd1\xcb$\x8a\x18\xc7\x8bO\x94\xdb\xd7I\xba\x14\x0e\xca\xf4\x9e\x85t\x16O\xde\x91i\xe8ce\xef\xc2%\x1e\x80\xcc\x8d\x9b\x9e\x03S\x8a\xce\xde\xf9+\x97\xfe\xc52\x1f\xfd\x90\x8e\xe1\xd7\x82d\xac\xeb\x1f\xa3b\x1e\xc6\xfc\x0f\xfb\xf2\xfc\xa7\xbf\xbc\xc5\xb5\x8e\x05\xce\x7f\xfa\x0b#\\\xc5\xddG?_\x9c\x93yy\x9b\x84q.n$(\x9c\xff\xf4\x176\xee$e\x83f\xd15^\x14\xb3\x99\xa8\x8b\x82\xfb|A\x08\xfb\x9c\xa2\xa1\x8b\xd4\x0f\xbe\xbc\xe4\x00/\x1f\xb0\xbb\xa4\x08\xb0G\x96\x88\xe7\xe1\xd2y\xcc\x18\x99\x93\xa1(Dl\xd1L\x1f\xb4\x93\xee\xccb\x92iv&\xddK)\xdd\x89\x8d73\xe0\xfb-\xa8,G\x15t\x81\xce\x1b3\xee\x8a\x94`\xc8Q\x17\"\xba\x10'\xd1%\xdd\xee\x1e\xc2\xb5c\xcd\xab8\x91\xa1\xa62\xbcI\x17\x024\x1c\xe9\xb1\x08T\xe2eQ\x18\x10\xfb\xd0\x85\xada\x97!\xafi\xbb\x9b[\xeb\xce3\xd5\x99c\xea{\x04\xc7\xeem\xd8o$xj\xee \xf6\x10\x9e\xd0s\xbf\xb9\\\xea\xee\x07\xf6\xc8PNrd\xb0w\x0de\xb8\xbb\x84\xa2;_\x0fAJ\xb8pG\xe5\xbd8\x0f\xb7o\x8a\xd8\xde;xp\xe5\xe5\xe3B\xd2\xb5\x84\x8c\x1d\xdc\x1d8\xdeL\xd7\xc3=},\xe6&\xee\xee\xda z&\x82E\x99M\xd0\x1e%\xe6&\xc6D\xf6\xc9\x08\xb9\xf6\x93\xa0l\xac\xb92T\x97\x93\xbe3\xb9&\xa4\xba\x98\xf4\xdd\xbd=\xc7\xde\x18\xd4D\x95\xa3\x9d\x03\x87\xc7\xedq\xc1jF\xcf\xd1\x9bG^QR\x8eG\xfb!\xc2\xfe\xee\xaa\x9e\x82\xe3\xa1%\x06\x8f\xb0\xb6\x12\xd1\xc2\xae4>\xfee\xb8\xba\xabPooRK\xfe}\xaa\xa5\xa8\x10\xa8<]L\xe3\xf54\x895\xe1\x18\x90\xdbB\xff\xdb\x9c\xf1Wbl\x9b'\xa5\xaf\x84n\x8e\xcd\xaeK\xbc\x9d\xa1qn\x1d\xed\xe4\xfe\x13!\xf5\x162n#\xb6\x87\x83\xa1c\x1b\xa7\x9a\xb7{@\x11\xbb>\xae\xef\xef\x0f.X~#\x8c/\xf4\n\xe5+7\xd1x\xa9\x88\xe7\x1c\xcf_\x07\xe8\xfd\xe0\xda\x9aQ|c\xa3!Vn\xcf>\xadU\x8ftat#\x89\xddk6e\xb3(\xdd\x01\xc0\x02\xcb\x86\xf1#\x17\x1c\x81g0@\x1e#ET\xf1t08\x18>}:\xda\xdb=\xd8\x1d<}:\xa4,\xc7\x9a4\xfd\xb7d\xb5lM\xa1\x07[0d\xe6\xc0\xd6\xbb0fVs(\x12\x06B\xc9\x0f\xf8\x17\x0cyFi\x90#\xb8 \xb30\x87E\x9e\xaf\xc6\xdb\xdb3? \xd7I\xf2\xc5\x9b\x87\xf9\xa2\xb8\xf6\xc2d\x1b\x15\x99\xdb\xd3$\xc8\xb6\xf1\xe3\xad) \x92)ar\x9f\xd30\xbe\xf1\xd3\xd0\x8f\xf3\x13\xac\xb2\x96:\xa6L\x1bHQ\x8e\xf5\xc4O\xe7\xd9\xe4\x92\x95\x8bi\x15\x9f?\xbd\xa9d\xdfRb\x19\xd8\x84\xa1\xeao\xc4\xea\xc0Qc\xae\xb6\"\x8a`I\xb2\xcc\x9f\x13t\xb4\xcb\x08>\x8f\x93xk)F<%7@\xe2\x9b0Mb\x14\xaf\xd2\x8f\xf1C\x1cG\x06~<\x05\x7f:\x0d)\x80\xfd\x08\x16$Z\xcd\x8a\x08n\xfd4\x0e\xe3y\xe6)n27<,d\x95oHM \xc0\xa8\xbc\x04\x85d\x14\xf6o\x04p\xe0\xa70\x89\x90\x9d\xc2\x8c\xb8\xb3\xd4_\x92\xec\"\xf9\x98\xac\xe0\x84\xceT\xf2\xc8\x8d\xd1\x87\xbe\xe3IC)]CJ\xb7\xeb\x1c\xc9\xd3\xf5Vk\x8bI\xa7x\x03\xedj\xaa\x86\xf7\x998\x03\x1a\x91\x04\xa1\x81\xf4r\xe1\x1d\xd5\xba+\xa4\xc6j.Up\xdat\xb1\x1aW)L\xf0\xd9%\x93\x94\xc6\xcd\xc8\xc0\xd887T\xe9\xdb\xbcu\xcd\xca\x9b\x932\xf2z\xdf\xa3\xdc\xb5_\xa5\x1a\xaf7\xa5\xa6\x0fi\x99\x8ee\xcdJMu2}M\xbf\xaa4\xda\x0bm\xadl\xd6{\xd7\xaaqU\xd7\xd6\x8aa\x0f\xfa\xd7\x8a\xc5;k]\x1b\x9e\xb2\xab\xa2\xae\xc2Od~\xf6u\xd5\xb7\xb6r\x8d\xb2\xcf:\x16i\x0f\xa7F\xb9\xee\xfe\x8e\x8dR\x1b\xaf\x14\x0f\x84^\xbd\xa7\x1fu\xf4\x1dq\xea\xda\x15\xe3WR\xcd\x0c\xcfIf\xe5X@\xd7\x9e0\xea\xe8\xdd\xa4(\xd5\xb9d>\xa6\xe1\x12\x0d\xfc\xfaV]\xedk\xd4\xeb\xe9P\x07\xbe\xd0l/|n\x88\xe5\xa0[\xe2P\xcf\xc4\xa7\xed?\x93O1\x970~S\x16{p\xca\x185\xb1\xbd\xb7\xebx\xec\xbd\x9e\n]\xdf\xfdWs\x8e\xe1\x04J\xc1K9'#\x0e\xd9\xbf=\x7f\xf7\xf6\xeck@V\xfcx\xc5\x97)\xf13\x9cY\xc2\x1f,\xfd\xf4\x0b\x0b\xfc\xc0n9\xe9pR%v\xa1\xe5)\xcc\xec\"\xfe\x12'\xb71\xb0g\x8e\xe5\xc0&/\x85\x95\x9c\x82\xc52\xfe\x89'\xe5)f\xe3\x99b9n\xd9\xe5U^\xa4\xe4<\xf7\x83/\x17\xa9\x8fQ\xc6\x0codk\x19)\xee\x01\xad\x10\x9fe\xb4$\x86\x0d\x14\xc4\x87\xc3\x9f\xd1.K\xe9\xcd\xca_iK|\x0b\xd6 9\xedOj\x8c\xbb\x90\xd6_\x8a\xb1\xb6\xae\xec\x1b9\x1b\x01\xce\xd3&Xc\xd0G\x0c\xc9)e\xd79 .lT\xc1\xfcq\x1e0\xe1\x07\xa3\nM\xd3\xe1(\xa1\xb4\xd6\x8e\x83\xd3%\x8884E\x91\xa0\xd3\x94*>$\xa5\xff\xc8$\xb6wv\x07\x8e\"h\x15\xbe\x83\xf8\xfe`o\x88\x96W\x07{#\xb5\\\xe5j\x82\xe5vx\xb9]\xfew\x8f\xff\xddw$w\xf1G\xecN\xf1T\xe6\xaat\xe9:b{\xd4Hu\x11r\x13\x08\xf5\xb90\x8dP\xa5\\E\x15\x103\xf5\xe6L\x14NX\x0c\xaf&\x92\xc8L\xd2-\xd1\xd3\xb61\xaaeso\x1af+\xca\xc82O\x0fo\xb5\xf032\xfdD\xe6a\x963\x05\x08Z\xeeNbs\x14\x89\xc2&\x8d\xa0\xec\x0f\xf4Y\xdc\xb4\nJ\x99\xaa\xdd\xbb\x12\xcd\x8a\xa1\xa2\x01\x8b\xf6\x05\x8b\x1c/\xbdy\xc3\xcf\xb6\xc6'\xe5\x0b\x17\xeaq\x86\x9a@\xd4\x04\xd4\x14\xe1\xfaz\xc1\x03\xa5\xfc^\x9e\xfa7$\xcd\xc8\xc5m\xf2\x91\x96\xb3\x89w\x95\xfb\xe9\x9c\xe4\xb4+.dJN\x9bf?\x02\xbd\x18}\xad\xbe\x98\xe6\x97\xd9\x99\xc8\x1dj\x14\x03!\x9e\xa3|=\xa6\xd6@\x05\xb8\x00$\xd3M7#X\xd2K3\xfaX\x1d1@]\xe6\xd1\x1c\xff\xcc\xb4H\xd1\xc8\x85\x99s)PH\x95\xf1\xb7-\xef\xce\x8f\xf5 \xa1\xfb\x9a\xafj\xcd\xc0\x1f\xb3\x84\x93o[\xc2\xd0 \xc8U\xdf\x05\xadB\x80\x16\x9a\xa9\x0bw\xa0I\xc6\x04\x1c\xae\xd3\x86\xce\xd7\x0f\x82bYD~^.\x85W\xbcM\x92u\x19pb\xf0\x83\xa8\xd5R\xb2\xad\xfa\xf3/\xe1\xea\x02;\xde\xab!U\x15nj\xe8U\x98\x92 _s\x14\xab\x9e\x95\x9f\xc59I\xdf\x12\xff\xc6\x00\xa6\xd2\xb4W\xd7R\xb5\xed\xaajlf\xcd;\xe3 ]L\xabF\x7fRO\xf1\xe97\x1f\x8d\x86\x93Q\x1fy\xaeyb\xf2\x88\xceC\xdd\xc9\xa8;I3\xc3I\x1aUI\xa6~Ws0a\xcc\xf9\x86\xc9\xd1\xacK\x8c\x04b+\xd9\xa1G\xbe\x92\xa0\xc8\xa5y{\x13\x7fH\xa7\x84\xd3\xedh\xfb\x95}$i\x86\x1b?\xb7\x193&\x13\x94\"\x0f\x91\xdd\xd8\xdd\xf5^\xf5f\x8f\x11\x81n\x0cZ+\xeb\xcd\xb9\xb3\xca\x86\xad\x95-\xfaVfy(\xe9\xf4\xae\xd2$A\x93\xaa7\xaf\xea\xf5\xd6\x17\xd2M\x03\xadH\x1e\x00\xcdF\xd8\xcb\xb3\x1b\x12\xe7\xccl\x01\xe7a\x0c\x89\xa7\x7f\xd3D\xf4\x8dr\xd9\x0b\xee\xde\xa7\xa9\x83\xbfk\x9d\xb2\xa2\xa4\xdb\xfa\x19\x06ku\xe51S@ZOw-\xfcR<\xd6\x1cD7\xdce`\xd1H\xf4I/;\x9a\xe4,\xfbh\xc4\"\x81\xfd\xfe\xe08\x93\x10#H\xe8\xeb\xc2\x94_\x8d\xf3\x81\xd9\xebd\xda0b>\x1a|z\xd3p\xfa\xb1\x1a\xbc\xeeY \x866\x00J\x84o\x0f\xa3|\xa1I\x8b\xb4=\xa3\xe4C\x9f9\x00)6\x84v1\x8b\x0b\x835XI\xfc2\n\x83/\x96>\x90B\xa3\xdcK\xc6\xe6\xf6(\xfe*)\xae#\xd2\xb7r\xa9t\xff&\xde%EF^%\xb7\xf1:e\xd7\xac\xfe]r\xb3V\xd95\xab\xff\xbc\xea_\xb2\xbbj\x90\xf4t\xf6\x06\x92\x8a\xfeu\xc4\x12\xbcbT\xc0\xdc\x05\xeb\xba\xc8s\xb6Cy2H+\x8cWE.?\xc8\xd0\x14K~\x92\x93\xaf\xb9\x9f\x12\x9f?sZ\xbc\xa8[#s\x88K\xf4\xb2\xe98\x05\xa0\xea \xc4\x85\x87s\xe3\xcd\x03\xb3\xceV]'DDJ\xf59\x8bY\xed\xc8b:=\xeeH\x8dx\xa8T\xf2SZ~\x92^\xb6a\x00\x96/\xe8\x11H`=\xb4\xc5\xf9\x8a\xdb0\x8a^\xd5Z4=g\xed\x9bG\xae\xc7AX\x1dO\x81\x94N(tz\x0c\xfey\x14\x95lC\x17\xd5)\x98<=\xe0\xeby\xbc\x15\x12[\\\x14O6\xfcpc\xb4\x82\x89&\xf1\xe5$\xbflC\x8ab\xfcf\xf0\xeb\xc4\x06\xe2B\xf8\xa4\x86i\xd0=\xb7\xb9\xa1<\x87)\xef`\x8f=\xf1\xa0J\x90\xf2\xd4\xe7\xc7{\x7f\xca\xbb\x84g\xe8\xf2\xa3r\xc5H\x83\x9a\xfd\xa1\xdff\x7f(.a\x87\xe8O2\x03|p^\xba@O \xda\xc8\xab\x8dF\x1e\x83\x19\xf2\xccv8D.7\xa4\\\x91~q4\x11K\xf3 \xdf\xdea+\xbc\x99\xebU\x13\xdefR;\xc0\xbe\x05\x1a.X!\xba\xd2$ Y\x86U\xffo\xdaHW\xf5b\xcf\x04M\xe8\x94\xfc\x01d\x88%\xe1\x14V0\x86\xa9\xe32\x80Q\xaa\x0c\x93\xb1\xfa^JP\xd5\xfd\xd2/\xe6\x8b\x9c\xe9\xc2[\xbbyu\xb5*\xd29\xe90\x81\x89*S\x0fc=\x12\x91\xf4\xc2\x8f\xbf\xf4\xcb\x8f\x1d\xd5\xeb,\xef\x0c,!\x0b\x01\xf0\x8d,a#\x85\x97` \xd5$A\xfa\xe8:7!\xb9\xed\x9aK(\x83\xe9\xd1\xd2U\xd0n\xbc\xd5\xaf~1\xfd\x89\x16e\x82\xf0\x99\xf4n\xc3x\x9a\xdc2\xcb\x81\xb2b\x8d\x87%H\x87P\xeea\xe2\x85W\xdcKM_\xb8<\x0eO!\x16!o\x7f\n\xc9-\xc6t\xe5\xfe'?\xb3\xc6\xc7\xc0z\xd1\xdc\x85MffJr?\x8c\xfa\x00\xac\x04\x12\xfb\x84\xb6\xdb\x199\xbb5B\xa6\x0b\x89\xda\x16oCRZIy@\x1bf\xa3\xf8\x85\xe7\x17s\n5\xcc\xa3e\xfb\xcc\x0bT^\x94\xfe\xb7/J\xb5\x93\xcb\xe4\xa6\x13_\x10\xcc\xa7\x1e\xe4o\xe2\x9c\xa4\xb1\x1f \x01\x1d\xdd&\xa8El\xdb\xae=\xc4R\xe5t\xe8\x9bi\xab}\xe1w\"\xd3\xbaF\x9e{\xff\xae\xdd\x90\x92\xbe\xde$#1C\xcah\xd7\xac\xc7?\xbdTS8\xa9\xd5\xf7\xdb?nH\x8d\xbcLVwi8_\xe4`\x07\x0e\x8c\x06\xc3}\xf872\x85\x9f\xfd\xdcT\xec\xefdz\xcb\xea\xabl\xc5\x02\xbaz\xd1E\xb0,\xff\xe3\xf6\xffQ}\xdc0\x1f(\xfa\xcd\x05u\xab\xd6:)\xa9D\xbd,\x91G3t\x02\xc8\x14\x16\xe1\xd9\xbe\xa5\x10\x17\xcdh\x95-\xe1,\xc4\x86\xafl\xeat\xf49plo\xcc\x9f\x0c\x92\x90\x85\xcbaR3Q\xa5$\x958\x81P1Y8\x81\xd0\x01\xc2\x9c\xfe\xda\xa8\xb32}L\xddb+u\xca\xaf\x13\xcf_\xad\xa2;\x9eP\xa9\x95\xbf,+\xaby\xc3\x86z\x82O\\\xe5D`F\xa0\xd4\x11\xc6\xc6\xa9\xc8\xcb\x93rG\x17\xde\x1f\xff\x9b\xe9G\xc2\xf2\xceZ\xd0\x1aKR\xc6c\xacy\x814\xeai0\x92\xd2\x85\x0eGk\xd7\xb4\xa2-x\xb2\x9e\x9e\xfa\x81C9\xc7\xd8\xb4(\xcb\xade\xf7\x95T\x9e\x0f\xf6zV\xc8\xdc.\xb8\x0f\x8a\xe3\x9e\x1b:\xd5\xf3?\x81A\xaf\xda]\x16*\xbc\xde\x9a\xe8i\xea\xc7\xd3diw\xfan\x18\xbak1\xf36\xdb\xf2\x82$\x0e\xfc\xdc\xae\x85\xc4\xc74\xc6cJeX\xce\x95\xe5\x82\xbd\xb9\x19\xc3&\xa4Ne\x0e\xb1\xb3\xff\xf8\xe43\x8dh\x06<\xb5e\xe39Sp\xec6\xe6\xcb\x07\x83\xd5|\x05\x8d\xdcc\xd9o\x87\x83\x81\x03\xa7\xfa\xd2\xd0-ZF\x94V\x06Y\x0d\xe9\xf2\xdd\x188.\xa46\xe5\x9d\x13\xa7\xdd\xd0\xdd\x14\x8c\\\xb6v\x7fh\xb4g\xcdInQ\\\xc1\xacW2q\xd7t\xfc\xb2\x9e\x07\x94aKR%\xdc\xb4\xc9\xf3\xcbBw\x0c^7\xe5\x0cE\xb2i\x0f_P\"\xf1\x11KTsP\x89\"\xeb\x9a\x17\xc7e\xce\x88F\\\x9f>=\xc1\x9d\x11\x9002l\x9aY\x94$iW\xef\x0c]\x0b\xb3\xf7\xfe{\xf4\x81\xd9\xc44\n\x03\xe6\x12\xc3v}\nc\x88\xd7O\xe8!\xe1\xa4Q\xaf\x87J\xe3>\xc3\x99\xa6\x91\x1b\xb4\xc4qn\xf4\xc1 \\R\xcaK\xddh\x98\xd6\x88\xcb\xd4\x93\x9d\xfe=\xd1\xb0n\x9aO\xea\x9d\xa91p\xf2\xa5\xf0\x8c\xba\x05\xd9\xe7\x0c&\xd5\xa9[\x92ofC\x08X\xe3\xd05\xef\x97\x7f\xa0\xe7\xaa\xd9Gr_\x9f\xc8b\xcf\xe4\xc3\xd9\x89\x0eR;Y?\xffZ\x97\x98gO/\xe69\xd0Iy\x98\x87Y\xf3\\\xc4A\xd5\x1f3\xbd\xff\xb0;\xc7\x9e\xd9\x14.cF<\x1ao[\x96\x94\xdeGk%\xcb\x82 \xb9\xd4\xb9\xf7\xa2\\\x7f`\xf0\x06\x8f\x1a\x11\xd8C\xb3\xe7\x1cH\x82']8`!^\x9ad\x97]\x84\xaaT\\\xe3%\xe72\xef<6\xa6f\x02\x0ds\xc21X\x1f,\xd8\x84\xcdMM\xf2oq\xddj\x93l@\xe3\xdc\xc1'\xad\x92\xf9\x99H\xeb\xa2\x8dfB\xaf\x7f?\xfb\xdb\x184\xf6#\xef\xcf\xce^\xe9\xd3\x17\xce\xfc,\xffw\xa2\x86\x873mg\xcc\x1a\x90\xc8A5\xb5n\x0b\xcc[]\x9f\xb6\xf2\x14\xacs\xca\xfdX\x1f\xd1X\x9f\x98e\x1d\x1b!NOk\x04a,\x97\xd5:\xf4\xdaj\x97{lT\xd4\x9bu\xd6R6P]_\xc4\xa5\x9fLq\x86N\xd2K/lNl\x13\xf2s\x92\xffL\xfc/\xeb@\xfeQ\x00\xd90\x84H\x84&<6\x86\x7f\x088zi\x05\x92\xf8uJ\xc8o\x9dBn\xa8*\x8f\xd0\x1e\xd4\xa3\x8b\x9b\xfe\xc2\xd8vO\x9e\x80\x00\x13\xfd\x1d\xd8u\xb6K\\:\x02\xb0\x8d6c\xfc\xee\xef\x0fe\xb8\xe77\xd9Y\x19yC\xfb\xf5Z\xb4\xc9\xef\xdf\"]\xd6W\xadw{\xcf]\xb0\xaa\xc8F\x0d\xf7w\x8e\xf2\xe4xG\x947\xf7^\xbe={\xfe\xe9\xea\xc5\xdfPs\x847\xf8\xeb\xfd\xd9\xcfW\xcf?_\xfc\xf5\xea\xecS\xf5\xe0\xfc\xe3\xd9K\xfa\xe0\xea\xc5\xf3\x8b\x97\x7fm<.\x1f\\\xfc\xf5\xd3\x87\x9f\xdfkJV/J\xc5\x05\xedCLn/(}\x1b\x9f\xa5\xed\x9eg|u4\x97\x0e\xc5A\xda\xa8\xcd+\xff.J\xfc\xe9\xb8%\x83$\xd4\x89y\xb5C\x18/\xf3[z\xa59@\xca^\x91\x8e^\x9c\xafH\xf0\x8d@\xc9\xbe\xbd\xf9o\x06\x81&\xbe^\xef>\xbf\xba\xa6;\xd7j2\x01\x0d\xc4]~\x9c\xadH\xa0i92\x1f\x02\x8dO\xb5\xad\x06\xbac\xa5\xfc\xd4/\xf2\x85\xa6\xd5Y\xedT\xc2\xd2\xb8\x80\x95b\xab\xaa\x18;\xc9\xaa\x92W\xd7w\xcc-\xb37_\xb6\xaf2X\\\xc6\xaeK\xdcY\xba?3\xa5\xc0\xe5\xda\xe1C\xdaH\xed\xfb{\xb4\x0fa6?\xc4\xa1\xef*\xeasMfs\x7f\xc7\xe1\xec\x96\x0b\x16s?5E\xaf\xeaE\x98H5\x0f\xf4\xee\x88\xfb\x0d\x19\x0bO\xf7?\xd03\xb0\xfb\x03\xbd\xf0e\x7f\xb0\xdb7\xdc\xb1\x10nli\x98\xa1\x98[U\x01W\xd3\x0c0\xe6\x16W\xe2\xd6\xd7\\\x92r?c\\@\xb6s\x04\x9b\x9b9\x1cCl\x0c\xb3\x99\x1a3\\3\xafa\x92\xdb)f\xcfK'\xc3\xcbv)\"\xbd2\xd9\x0b\x98\x9f@\xa9[{\xccm\x0fO \xa9?\x9f\x13\x96\xfc\xaa\xf6p\xe1\xa3\xe5J\xfda\x86%\x8b\xbauK\xb6\xde\xdc\x0f\x07{}$c*\xd8$\x93\xd0\x13)_x\xbc\xb5u\xd4\xe4C\xb8\x94~\x12_\xb2\xfc\x83\x92\x19\xb0\xf6\xac\xd8\x1a>z\x8f\x0c\xba\x93\xd1kFS\x0d\xe4\xeaj\xea\xe7\xfe\xd5\x95\xb6_\xa9\x9d;p\n\xf1D\xc3:\xe7\x94u\x16\x8f\xc7`-\xfcla\xd1\x134\xf6\x96\xfe\xea\xd1\xe31\xb8C\xed7\xe2\xf2\x89\xf0v\x06w\xa8]\xfd\xc6\xec\x11\n\xd7\x84\xeeD \x9dlA\xde\xa5!\x85\x86.:\xc6)\xf86*\x93\x12\x9b\xe0\xba tg\x89T\xddc\x94\xb8v\xc0M\xee\xdbZ\xbd'\xde-\xb9^\xf9\xc1\x97\x8fIt7\x0b\xa3\x88\xab\xe4\xa7d\x95\x92\xa0\x99\x17\x14=\xdeW~\xbe\xc8\xb8=I\x15z\x99\x7fY\xde\x9e\xb0\xf4\xb3z\x06\x8f\xb8`\xb1dM\xda\xd8f\xb5p\x91\x9a\xf0tk\xc5>#^\xd4x\xad0\xd6\xad\xfd\x0c\xffG\xfa\xa8\x11\xc64\xfa\xd8\x9c\xad\x13\x18>R_\xab\x9a&\xd4\x07@w\xdd\xf6\x7f\xda\xa7\xe3\xc1\xfdd\xb8\xf5\xf4\xf2\x97\xe9\x8f\xce\x9f\xb7\xbb\xb6\x88\x01\xa3$\x95\xb1\x8f>\xef\xfb\xc6\x86\xfd\xff\xb3\xf7\xef}q\xe3\xc8\xe20\xfe\xff\xbe\x8a\xc2\xe7\x9c\xac=\x18\x03I&\x97\xce\xb0,\x03\x9d\x1d\xce\x06\xc8\x0f\xc8\xcc\xce\xaf\xc3\x971\xb6\xba\xdb\x1b\xb7\xddk\xab\x9b\xb0\x9b<\xaf\xfd\xf9\xa8$\xd9\xb2,\xd9\x86\xb0{.\xcf\xd7\x7f@[\xd6]\xa5RU\xa9.T9\xd3\x18\n\xc9`\xc4*{\xf2\x04\\\xd5EI\xde\xf0A\xb2\xb1\xc7M\x87\x0b\x1e]\x80xX\x80\xc0\x1f`k\x97\xff\xfa\x0f\xf4e\xcfi}\x8c\xc5\xfb\x80\x99\xd2]L\xf5\xcd\x82\xed(\x17\xfa5\x8a\xe9\xa2\xf9z\x8b+\xd8\x18\xf1\n\x86\x03P\xba\x82*\xae}\xc8\xa1\x83\x90\xd2\xb1\xa1`\x1f^Y\xc8\x9dg\xfa\xfd\x99 w\x9e\xe9\x0e\xc6\x05V}\xa6\xd3\x99\xa5\x99*M\xc5%\x81^\x0d^\x18\xb9\x85\xd7&\xa4S7\xf7\xdats\xea&Zj\x8c\xa9\xa1\x96:\xc7\xd4\x95\x96\x8a\xe1\xdd\xea%q\xb9\xe1\x91\xe2m(\xfc9!\xb7W\x08vk\x97\xbb\xe3`\x7fQ\x97\x8c\xbb\xacqw=\xae\xd5\x947\xca\x9e\x84K\xb5X\xee\xf1\xd01j\x96\xf7E\xbeHJ\"\xb3%\x01\x0f*N\\^_\xd8\xc8|A\xa8Z_\x88YV\x8d,\xbf\x90\xf0\x93\xd6\xec\x8ao\x0fw=\x08ZK\xe3=_\xa62\n|c\\9r\xcf6\xfd\xbc\xd8\x9d\x8b\"\xf4\xc1>\xa4n\xc6\xdd\xdbh\xd7~\\\x81P*)\x18/\xf7\xf1Z>\xea\xbc\x967\xac\\\x9b\xa6\xc5z\xa6\xc3\xea\xc1\xe9\xb4T\xb1\x1cVE\xb5\xca\x96j\xe2a\xd5\xe0\xfa[\xaa\x98\x0f\xab\xa2\x82\x8fFn\xa3\x8a\x81\x8235\x05\xf2AV\x0d\n\x89\xfd\xecu/\x95e\xbf|\xce5\xaeG\x88nF`\xb4%\x13}W\xb4arq\xaa\xf49F\xb4v\xbf%T\xe1\xd8\xf2\xd5\xce\x90Au\xf2\x0d;\xdc\xb9>\x1e\x82\xe8[\x97x^\xcdJ\xc8x0l\xf3f\xf0\x03$o<\x94i\x91I\xee\xd2I\xb6\xb9y\xe5]\x19\x07\xcf\x8d\xf2\x90\xd7\x16\xf4\xa8\xa6_?h\x02\xccr\xfb\xfaZ\xb45\xb4\x0d\x1a\xacIQ&\xdc\xef\x92PE\x92IA\x92\xc5\xe4\xf3\xd9\xd4u\xd6;\x81\xe3u\xe7\xd8e9\x9e<\x11\x02:s\x8eW,\xcf~\xcf\x85cF>\xd3\xcb$\xd2n\xb1z\xf4u\xfaUX\x18V\xad\xd5X~\xefDa\x9a\xde\x84\xd1'\xa7\x92\x1eb\xf8Y\xb8!\x8aZ\xcb\xef-\xaa\xc5ka\x07\xc7c(\xb4\x94\xb3\x8de$\x8e4\x06F\x92\x0f\xa2\x85\x9d\x1e+_\x8b\xc2\x97|$*\x08\xe4LZ\x8d}\xa0G}K>\xed\x1a{ie\xf5\x11\x1aT\\]\xdb\xa2X&\x1f=\x10\x89\xfat\xe9w\xc9\xe7Q\xbbjU>\x93Ooo\x9f\xffk{k\xd5N\x93OW\x87\x07\xd9b#.D\x12SRS\xee\n\xb6\x90\xb3 \xb9\xb9B\xc8\xd0\x9e\xdc \x1e$\x93ps\xf3\xaaa\x8d\x10\xf6D\xe5\xfd\xe6YQ\xcd\x03zt\xfd\xbf\x0e\xbd\x81\xd68<\x14\xe3\xd5hL=wU\x07\x89\xdf{f\xcdx\xbb\xa6\xb5\x89\xcc/\x84\x97E\x93<2\xe9;\xb2\x92\x0c\x91\xe0$\xbb\xc2s(S\xfc\xc2u\xd9\xb5Y\x84\x10y\xf5]\xa9F\xfe\xca\x83i\x91/\x00\x9d\x83\x85i\x9aG\xca\xcf\x0fY\x19NI+\xe1\"\xcdo\xb5#\x81\x91\xa3n\xe2\x16\xdc\xa7\x0c\x0d*w\x94\xa1\xe7C\xe2\xe6<~b\xc8\xdb\xea\xa7G\xf0h0x\xce4\x1f\x0c\xceA\xe34\xc8rq\"\x88\n\xcc\x94\x8biRX\x0f\xf9\x1c\xdc\xb3\x8b\xbdg\x97\xd6\xc5\x8e\xeeI\xb0j\x9b{6I\xae\x0d\xc1\x14\x98\xc2\x05\xc2>\x14\xc14\x91Z\xc1\x8c\x86\x13\xaf\xcaoT\xb07\x8c],z\xaf\xf2\xe9?a\xec\xf5\xd2\x98\x16E\x01\xbe\xff\xc2\xce\x15\x01\xeb\x81`G{\x05\x87\x83h=u#e\xee\x8b\x97\xdf{\xae3\xcd\x8bq\x18\xcd\x9dA\xa8\xa8O\xe3\xf5\xd9\xaeY\x10\xf1\xcc\xe2\x06r\xf7\xb5.)\x10\x82\x88W\xaa\x18\xd7\x1dL\x8c#R\xc3\xf8$+T\xcfL\x8d3\xdb\xbaC\xfe\x01\x9e6\\\xe5n4\x84\xban)\x9c\xc3r\x97\xb1D\xb0/\x0c\xc2\xcb\xc6\xd1\xf5T\x04\x8c\x94\x8c\x0dFO[\xa1I\x13\xe7\x0b6\xd0n\x08\x93\xc3J\x7f\xd3\x89\x1c\x11\x93KI#2\x04\x97\x92v\xebx\x9e\xcf\x0d\xe1\x1b\xa3\x82Z\x91\xc6\xe0\xc6\xb0\x19\x96%kgP\xc5\x9fI\xfbs\x1d\xa2G\x8fK\x0c%\xdb\xfen\xee\x96\xac[ld\xb5x\xf6\xab\x17\xcc\x86\xf2\x83b\xa9|\xdd\xef@u\x0di^\x15\x945\xf1@\x06\xe6\xc5I\x1b\x8b\xf3LY\x1c\x86\xceh\xa5\xec\x03#H\xc4=\x88\xf8\x8e\x16\xe8\xcd\xef\x19\xb7qS\x1a\xe5\x1fqA\xd3\xba\x0f\xca\x17\x0d\x18$ \x945 \xac\x0c\x80P\xb6\x00\x01},\x98\x16\x1d\x05\xd3\x86%G\x9bd\xc3J7A\xc1\xa0\x01\xa4\x82B\xa9\xafv*V;\xf5D\x0c\xbd\xe8~(\xa9\xc6\x12\xadp\xb9\x02I<5_\x01={f2\x18\xcb\\\x8b\xb0rwW\x17nrt\xb7\xfbB\xc7M\xdc\xa7D[R\xa9\xaa\xbd\xb8TS\x82\xd5\x87\x88\xbe\x05\x97&\xb8\x8e}\x98\xfb\xb0\xf6a\xe1\xc3\x0c\xf6`\xa9\xaa\x89\xdbhU);n}dD\xa5Y\x94w\x87\xc2\x06\xde\x11\x06\xd9Oa\x04:\xbae\xcf\x0d\x92\xe0\xcd \xb6q\xc6\xb3\x1e\xe3\x8e\x84r8i\x99v\xb0\x1a\x13wf\xd4\x19E\xba3\xe6\xa6\x072F\xef\x1b\x88\xe1\x0fp\xf3\x06n67\xcd\xd46\xab\xd1]\x08G\xacwn\xe8\xce\x91T\xbd\xb9\xf2\xf0\x8em.\xee\xd8\xee\\L\xf3P\x06\x81\xb7_\x0b\x1e\x0b\xb2\xba\x9a]4!\x1a\xcd\x7f\xcd}\\\xc3\x1eTq'\xde\xc0\x066\xb9F\x8e\xc3\xf5\xbc \xce3b\xb8\x14\x06\xb5\xb3\xb9\xbb\xf6\xe1\xce\x879\xb7\xc5\xe3w\xc4\x03\xba\xf6\xd5\x0b~<\x1f\x1f\xfc\x99\xc7j\xa5\xc1\xf9\xf8\xf2\xc3\xf9)\xec\x89\xdd\xf6\x8d\xe7\xb3\xd5'u\x11\x1c\x8d\xdf\x1e|xw \xfd\xfe\xa9ww^\xf5\xf8\x9d~)\xfcL\xbf\x12\xff_\xdf\xdb\xdf\xb4BR<\xb7\xdcm\xec\xe8\xdb<1\\\xf1\xdc\xdf\x94\xd1rH\x85Fm\x8aD1pD\xee\xc5\x0d\xb1\x18\xddd\x83\x00\xad6a&\x1f\xec\x96\xd6+W\xa8\x869O_\xeaGCU\xcchc]}\xb5-\xdc\x0e\xa7}\xd9\x7f\xdep\x05\xa7\x07\x82\xc9\x8cxp\xf8\xda \xb39FQ\xde\xe2(\x10\xa6I\x16\xa6ig\xd7:;\x0eP\xb9&\xeb\xcf\x08r\xa4Q\x9a\x97b\x00\x9d\x05\x9aF\xe6\xdcu\xc5\xe0\n\x86\x0c\x0e\xba\xe6\xde\x93\xa8\x15{\x1a@\xba\xd2\xb0\xd9)\x81d-\xb0\x11s\x03a\xdbu\x8b|V\xed\xab\x05\x90\xd8\x81\xfb\x83GM?\xae\xff\x93U\xbcNh\xe7u*\xcffA$\xa0\xf8\x80\xbaa\xa7+\n\xae\x01\xd6\xa3T\xc5\x88,\xe7\xc9\xdfV9}\xd3\xe1\x8b\x83=7\x05 ?\xd9\xb3\xf0\xd6^\x0di-\\,\x1f\xa5\xb1\xd7C\x1a\xfb\xb7\xcfO_>Fk/:\x14\x0d\xa1j-}\x94i|\xd1\xa3b\xc8\xdb\x9a}k[\x83t\xd8\xa2<\xa3I\xb6j\xdf\x0c\x81\x95\xc5\xe3|0j\xf6\xbb l2\xfcX\xaen\xf8\xb5\xb5\xbb\xf2!\xf4\xe4e>\xe3@\x19+\xbc\xa9#:s\xe5b\xaf\xca\xfa\xf7Y\xc9v\xe50\xd2C\x0c<\x92\xbaH\x83\xea2\xfa\xa67\x851\x0b\x852\xb5\xd9@\xaf\xcd\\\x96\"\xbf\xce@ [\x92\x96FId\xb8\xb5\x9d\xa2p\xa1\x99\xb6l\xa3\xabvx>\xf6\xd0|yp\x93\x17t\x04N\xc8\xfe\x1b\xd0\x1f\xcb\x92%\x0b\x0c\xe11\xce\xe2\x11\x94\xae\x13\xca\x04\x92\xc5\\\xff\xb9\x99\xd4]\xcb1%<\"H\xb3\xaeD&\xeb5\xd6\x1f\xba\xeb\xbd\xa0!\x1b\x89Zg\xc9\x92\xf4\xfax\xa2\xb1\xae\x1f\xd3U1\x02\xe7&]\xe9&\xed\"\xc3a\x98\xbdO\xc3\xbb\x118Q\x98-\xd3\xf0\xae3\xdb\xe5\xbc\xc8W\xb3y\x9d\x9b\xf2\x04K\xa1y\x98\xcd\x08\xcb\x8c?,\x99RT\x01w\"\x8c e\xce\x92/\x96y\x99T\x0b\xe6Du\x82uu\x94Bb\x1e\xd5b\x1dS\xa6\x14\xfc\xb0\x8cQ&\xa0\x96\\a\x9a\xadhF\xc9gzB\xb2\x15\x16\xc2\xb7\x05\xc9V\xb6\xecK\x9c\xf8|i\x9b\xf5\x15v{e\xe9\xa9\x12\x1ek\x04N|\x93v\xcc\xe1Q\x11\xceX\xa6\"\x9c\xd93\xf0\xd9ey\xac\xd3\xca\xb3QRT\x19)\xb1\x80\x16f\xfd\x9cP\x99\xf3sb\x1bG\x11\xce0\xc0\xa3\xc8\x99\xb2\xdf\xf6\xacg\xeb\xaa\xf5|\xdd\xd5\xb8\\w\x96\xb3c\xc1\x8f\x8a|\x89\xb9\xf2\xa5%\xc3\x8ao\xd7\n\x9ec\x91\xd0\x05\xd7\xe3\xc5\x92&\x84\xcd'\xe1\xbf,\xd9\xb2\xa8\xb8[R\x9eQ\xfe\xb6e\x8dE\xb6\xd8\x9a\xa5(r67\x84\xfd7gy\x9bG\xabr\x04\xce\x94\xfd7g9\xce\x96\x08x<\x02\x981\xcb\x9f\xc9\xddQ~\x9b\x8d\xc0\xf9D\xee\xe2\xfc\xd6\x82\xca\xfeL\xee\xde\x17\xa4,y\xbe%\xfbi\xcd\xf8a\xc9s\xad,\xab\xf0\x0e-\x93\x19\x0f2\x92f\xca\x8cs\xe9\xca|Bh\x18\xab\x05\x16\"\xc1^H\xc2\x0c\xcb\xdf\x013U\xe0\xb8\x118\x0b\xf6\xdb>\x07U\x108\x99\x95qW\x1dY\xcfp\xee1gn\x9b~\x9e\x91\xef\x03\x9e\xd3\xba\x11D\x988\x99\xd16\xbb\xef\xc3\x121\xdd\x92\xfd\xb7eY\x95<\xcb\xaa\xb4e\xe1G\x89\xfd\x1ca\x19\x92l&\xf2$\x99\x05\x19\xbd/\xf2\x99\x80\x9b\xa5\xf8i\xcex\x1eRRm\xcb\"\xa4\xa4kKr \xdb\x08\x9c\x12\x7fX2\x11\xf2 \xb7Y\x89?\xec\x99\xf80J\xfe\xcb\x96-\xe5\x91=\xab.\x962\xa5\xb3\x9f4LS\xde\x07\xfe\xcb\x92mU. b\xec\x92\xff2g\xbb$\x9f\xa9\xdc\xd1T\xfe\xb6dM\x16\xa4:\xf3h\xb2 ]\x87\xdde\xbe\x8a\xe6\x87a\x16\x116\xa5\x94\xbdE\xf8\xd6\x91\x9d\x1f0\x98\xd7\xde_\xf6U\xec\x17\xcci\xdf/\x98U\xeeX\xcc\xdb\xb1e\xf1\xda/Q\xa9>Z\xa5\xd4d_3\xcdX\xd1\xcfy\xbaZ\xd4P\xb7\xc6\xd7\xae\xf5\xfc%L(\x87\x96[\xfe\xcb\x92mNp*o\xd9\x7f\xcd\x04\xb4Y`\xcex(\x1e\x85\xa6\n\xa2w|\xe4\xc0\xa6\x90\x18\xb9\x8d8\x04^P\xa6ID\xdc\xa7^\x93\x1dX\xa3j\xdb?\xbe\xa2VE\x93\x94>'2\xd2Z\x1d\xa4\xb0}\x990 p\xad\xa9\xa2~\xf99:\x8f\xf9)\xcc\xe2\x94\\\xe6\xcbwdMRw\x1d\xcc\x1b \x9e\x0f\xeb\xa0]=\xec\xf5{ll\x8e\xa2$t\x9ca@\xcc\xbe\xae\x19\xdb{\xf2\xc4\x98\x1e\xd4\xd5\xb6\\\x01j\xb3X\xb6\x9b7\xb5.5\x88\xdc\x0dc?\xbe|\x01\xe3\x87\xa0\xaa\xdf\xed\x0e1\x97b\x81\xcb|\x80S\xd1\x86\xa4\x98\xfa\xd0\xed;O>b\x00=j}\x95\x16\xde\\D\"\x99\xcc\xaf`\x0f\x96\x9b\x9b>D\x13\xf6&\x82\xfcV\xaf\xed\xe5\xe6\x11 `\x0f\x92V\xc0\xc6#\xc20%\xc9\xa2\x84\x94\x13r\xd50f\xcb\x87\x08\xb3P\xcb\x9d\xed\x1c\xabu[\xa1\xc7\x99\\\x89X2+\x1e\xa7\xd8\x91{\x9d\xcb\x86Wht/v\xbd\x07\xfbfp\xa2E\xb8\xfcqu\xc3\xd6\x11?(\xb5\xf8\x12e\x08\xb3\x9d\xd4\xe5G\xfd7\xd5\xa8\xd4 \xaa}@%Gg'H~\\\x88\xf3\x96W\xe4TGqc\x02\xe4\xa1\x0c\x1b;\x9d}\x16\x01o\x95\xf6\xaa\xea\xeb:\xee\xd9cC\x0d\xc6\xc2\xbf\x1c\x9f\x1e\x9d\xfdr\xfd\xd3\xc1\xe9\xd1\xbb\xb1\x1c\x0bR\xd4r(x\x86p\xbe\xbb\x1e\x9d\x9b\xba\x92\xde\x16\xa3s\xef1\xbc\xb7\xa2dUEf\xc1}\x96\xf2\xd8\x17_\n\x01 \xf3\x04\x90`uI\xe6\x08\x15\xd7\xc1\x93\xd5\xecO\x92\xf5\xf5\xa8U\x81\xec\x10\x96G\x1a\x97u\xca\x87\"\x10\x1f\x85N\n\xbeck\x98\xc0\xba\x1d\x9b\xf7\xd6\xb0\xb6W>\xc4\x93\xd5\x15\xef.n\xc7\xbdVHy\xe8;.\xf4Z\xfb\x03\xd5\x80b\x867\xa8\x9f-\x85bK7\x1aK\xfd8\xfdhB\xcf\x90\x8e\x88\xc86<4\xe9\xfbpF\xfe\xf2k\xcfA\x86\xb7\x17\xfa\xad\x1e+\xdd\xe9Kz-\x9c\x86\x9a\n\xba\x0e\xa2\x19\xfcm\xd2\xe3\x92\xf7$\xaa\xd3\x06UQ\xa0k|$+W\x85\xc0`?\x87\xe9\x8a\x9c\xe4YB\xf3\x02 \xba\xdeq*\xae.\x90T\xc0K\xdcu`\x984\x97\xed\x80\x0d\xcc\xb41\xed:|\xd8$\xac\x82\x82L\x0bR\xce\x95~\x95\x96\xfb@\xd3R/\xf8\x18\x94\xd2\xe8\xebzZ\x87\xecR\x1fm?To_-\x06\x08\x83<\x904\xc5\xd4Ur\xa5\xd1P\xb4\xe6\x94k\xb4^\x17\xab\x94\x94\xd7\xd7\x0d\xdd\xf0\xeb(\x8c\xe6\x04\x13-\xd7\x8b\x85Bp\\_O\x93,\xc6\xdcv\xaa\xa5\xad\xf7W5-\xc8\x04~\x8d\xb7\xb5\xfb\x06\xa8\xd5\xb1`\xb3\xe0ds3\xbbB\x85\x01\xae*s\x0fO\x83\xbe6\x82(_,\x93\x944\x07a\xbaB'\xa2\xfb\x06\x96\x83M\xa1\xe3hT\x0cQ\xc6)\xecI\xddn\xda\x8e\x04\x84\x13\x98\xfc~\xe3\xf5\x18\x07\xa8\x95\xa2\xae\xfe?\xd0\x07q\xaby[ OY\x92\xc7\xda\xe2\xae\xf3:\x86oD\xa9\xec\xc9\xd4)p\xd1!X\x86\x13!\x07G\xf9\xe0\xbe|\xd1Z\xe5#\xcd\x82if\x88M\xdd\x1a\xad\x0d\x1cB:\xd0\xf2\xa5\xa8a\x99o\x01\xa3\x11\x1a^\x12\xb1\xbe\xea>\xa3\x19Doq\xb5\x81B\xb5\x8c\x16V\xd1\xef\xc3\xa2$\x05\xb0\xe9C\xc3\xb2i\xbeB~\x1f6A7K\xd7\xf6Eq\x15L\xa5\xf1g\xebK\x98b$c\xfc\xff\xe5\xcb\x90]\xdf\x9c\x9d\x1b2\xcd\x0bb4\xf7k\xb9\xb1ZK\xcfx\xbd\x93\x94Hm\x9c\x8eI\xca\x1fs\x92\x82r\x89l|\xee\xc3\x8e\xc9\xf5!C+F\x13R\"\xd9K\x93C\xc4if4/\x0dS:\x82\xa4\x9e\xf2\xd6\xb6\xbb\xd7\n\x84SJ\x8a\xff=\x0b\xc0o~\xff\xa7-\x02\xc34\xf7@\x13F\x04\xa0M\x08\"/\xdb$\x18T[z'\xc10q8 \xc5cM\x02\xefA\x9f\xf2\x17\xcb\xd0\x0cJ\x8b\xae` \x8c\x00e\x06\xdc\xe3cs.\x86\x1dy\xf5Y\xd9\xd2\xa0\xe7\x87\xd9\xb0j4\xba\xa4\xda%fU!\xca\xce\x1e\xc3N8g]\x87E\x98\x853R\x8c \xc9\xd6a\x9a\xc4bg0\"\xc5\xb4'\xa0\x8d\xbd\xe9\x95:*=\x84\x13\xe6\xbe\xef:\xc5I\xd9Z(}\"\xdc\xeee\xf2\xfe\x17\xcc\xe5\xeec\xcc\xe5\x8cP\xde\xbb\x01jo\xc2\xcb\xc1\x9e\xdeB\x0d\xef\x15\xe1\xe9\xb6\xfa1!W\xda\x1e\xfd\xea\xdf\xdf\xf3{\xbf\xbb\x93\xce\xbd\xbb\xe6nC\nn1hq\xd6\x8e\x16\xc0\xc12/O\xc2\xcf\xed\xaf+\xf9\xb5\xfd\xa9\xc4OIy\x9c\xbd\x0boH\xda>x\x94\x8f^M\xc7\x9b\xf2\xa5,\xcf\x87l\x11\xd2hN\xe2\x8b(_\x92\xb2\x8e\x0dj\xfc\xbc\xb5\xe5\xb7*C>\x05{\x8bf\xf5x4)\x9d\x10\xa2\x14F\\\xed\xbe\xe1\xa3\x82\x1f 4z\x9ag\xfdz\xcd\x0fN7\x07\xa1\xca\xaf\xea\xecaq\xcf\xf3 \xdb\xdclCr\x15\x82\xfb\xf53\xe1\xdb\x11\xbd\x04\xb2\x9f[[V\xd2\x99\x0b{\xcc\xbc+\xea\x80\xb5\xbe\xb4u\xabP)\xb7$EP~J\x96\x97\xf9'\x92\xd9\xc3\xef\x80\xa2\x11\x0f\xfb\xdc\xc5\x19_l\xcb\xa4\xc3\x1e\xf7\x0cb\xfd\x9a\xc1\x16\x9ft\xbe\x06+}\xfeK\xff\xe1a\x15^\xdb\xa2`r)\xba\xeb\xfc\xdd\xf1\x8cq\xa5\\%\xb6r\xa7V\xaa\xd4w\xbd\xa8=B\x15\x02\x8f\"\xc1C]\xc7a\xc3\x17\x0d\xf6j\xa3\xa9\xf5\x0f\xd3\xb8m\xc8IL\xa1H\x9d\xc30\xfb=\x85(LSX\x10:\xcfc\xc830b\xd4\x96\xcb\x8d{\xcew+&\xa20S\xd8\xf5\x02)x\xd2no\xd0a\x87\x08\xe0\xe2\xe6M%\xf5^\x1f\xa4\x96\xc5H`\x1f\xb4\xaa\\\xf4:\xaf\xd8\xb1\xdd\x7f`}\x9d1 S\x14\xd5\x15jD8\xcdW\xb8\xc0\xb6y\x1b\xc1!\x8dd\xf2\x97\xedr\xedt\x19\xae\x9c\x87]+\x10\xe1\xc8\x18\xd3^\xdd\x9e\xa1\xe6\x8eJ\xd1?\xc7\xd9\xf4\xfeun\xfcs\xbak\x83\xe4<[\x93\x82\x82p\xfbKsX\x16\xc9\"\xa1\xc9\x9ap\xefON\xdf.\xd3\xd6\xb9\xe9\x0c\xec\xfb\x9d\xfb\xfa\xe5\xd0\xadpd\xd4w\xdd'\xb8\xf0\xf4\xf5B\xd7\x1f\x0dE\xfa\xae\xe7:\xc7\xe3\xeb\xf7\xe7g\x97gz\xd0\xd1U+jA\xe3s\xd9%\xc8\x02)\xcc\x12\x8e\x99\xdc\xdd\xef_x\xae\x93L\x8bpA\xf4\x86\xe4S\xe0\x05\xa0\xcdS+\x8f\xc2\x12\xa0I\x10#7\x97ix\x07{\xe0dyF\x1c\x1f\xa3R\xecx\x0d;\x17\xee\xa4\xb0,\"\x96\xed\xaf\xe1:\xe4VE#\xc7\xe7\xa4(\x0dP\xe3/\xa3\xbf$Y\x9c\xdfV\x08\xc3\x0b\xf2%\xc9\\\x1e*\xa0H(q\x9d\x1fx\xd1?T\xc2\xec\xb7{\x1c\xbf\xfe\xf0q[|r0?\x1a\xbc\xba\xc2\x95\x14 \xde\xbe\x81bk\xeb\x8d\x07\"<\x8b\x12oe\x92L\x8a+\xc3\x8d\xa4\x00\xcc\xd2\xd5\x0e\xc4\xaecE\xa0\x1eP\xa3\xb6Zi-#\x02\x16\xa2v\xe9.Kq\x8e\xcf\x8f\x17N\x91\xa0\x03t\x1f\x9a\x9f\x85\x93\xd3I\x88n,\xd1\xfe\x04=\x9fka\xd4\xa5\xe3h7\xfb\xff^D\xfa\x17O=\xd7\xf9D\xeeJs`\xdf\xdd\xdd\xfe83\x96\x8e\x17\x82\x86w\xf1\x07w(\xf9\xe0~>5\xd9$\x17\x13\x871\x11\x05\xd9\xfaky]\xce\xc3\x82\xc4\xd7\xd7\x8el\xd4\xfc\x0d\xef\xfb\x1f8\xa2\\\x8e(\xe7#\xfa\xc7\xd7\xbe\xf1\xd8\x10\xab\xa38\xd2\xf7\x9b\xd7\x90~R\xbe\x97 |6\xf5M\x04\x99O\xf3wy\x14\xa6\x84\x9f#\xbe\xe4\x9e'\xb0u\x82~\x07\xd1\xa1\xacsVG]B\xbb\xb2\x02\xcd\"-T\x18;\\\xc34%8be\xe9F\xc2\x12\x19\x1e\x008\xde5#8773\xd8\x84\xc2\xab\x18\x13F\xc4\xf7\x9dl\xd6\xbd\xf0\xd2\xe2\xea\xf7\xd9\xffx\xb6\xf7y\x0f\xa9\xf4\xe2\xe5C{\xfb\xa8\xa4\xd2\xee\xeeK/\x98\x9a\x899\x93\x07\x17\x13\x9e\xea\x1b\x87\xf9\xbe\x07\x95a6r$V3!='5A\xeeC\"\x03\x84\xa2\x03\xb6\xf6foz\xa25\xdd\xecH\x87\xc6\xcd\x8d~\xcf\xb9\xea\xf5\x80\xf3t\xd74\x03\x18{\xbdw-\x19#b\xcf\x04\n\xcem3X(\x03_\xf2\x18B\x82\xa7!\x0d\xdf\x11\xc6XI\xa0\x13L\x8c\xa5\xf9\xf2Eu\xd4\x9e\x19$a?\x86\xb1\x8cW\x04\n9ju\xcf\xc7=)g\x95\xec]}\xaa\xcb3\x11\xd5J\xa0\xd1*\x11e\x13\xe8\x8eVc\x1d\xbf\x81uy\xfa\xbdY\xd4\xf0\xbdM\xce\xd9\x07\xbe F\xefd\xc8\xbf5W|k\xfc\x9b\x03\x9b\x90\xa1\xbf\xdb8'e\xf6{\na\x14\x91%\x85\x82\xcc\xc8\xe7\x96\xd3[\x01\x11\x02\xa9~\xdb\xa6f[\x14\xa5\xc5\xfd\x9b\xd3x\xc6\xc3\x1el\x07\xdb\x9aH\xc9x\xe2:\xdb\xc1\xb6\x03\x13r\xe5jnu\xaa\xa3\xd6(\x80\xef=\xbe\xe9\xa4\xb8\xe2\xf6\xb8\xb0am\x03z\x8et\xd3\xfcn\xdc3\xe0\x11\xc5\x8d\x8c\xb4\xfd\x90\xec=L(\xb27F\xac\xda2Q\x16\xa2\xad\xd6 \xc9M\xa0\x9f\xefx\xc1\xf4\xa1k\x9b\x07\xfc\xcc\xe7\xec\xa9|\xe1\x81\xa1\xfe\xf1\x15\x83.\xd4\x19\xfe\xa1Gtq\xae\x91\xc4!xAs@\xdd\x1d\xd4\x97'\x90d\x1c\x93\xac0f\x95 c\x0b|\x1c\x06\xd3\xd65I\x1f\xac\xb7\x97DH\x8cf\x84*\xfc0\xef\xb6\xd9\x8d\x07\x0fXz\x7fT\xdf\xa1\xcd\xb5\xfd\xddFs\x90\xdf\xc1\x1fc\xc2\x05iI\x9e\xc19\x89VE\x99\xac\x89\x94\xb8\x92\xcf\x94dq\x92\xcdZ\xc5\xc2\x15\x9d\xe7\x05\xfc\x9c\x84\xd1\x9c\x94i\xb8\x86w9-\x17a\x96\xaf\xe1\x87T\xfe|\xf5\xfa\x8f\xb3E\x98\xa4A\x94/\xfe\xd0\xaa#M\"\x92\x95\x04N\x8e/\xb5oz\xd6\xcb9\xe6\x82w\xa2\x84{r|\xe9\xf5\x949\xcc\x97wE2\x9bSp#\x0f\x9e\xee\xec>\xdbz\xba\xb3\xfb\xca\xd8\xe5\x9e\xaa\xde\x93b\x91\x94\x18\x14,)aN\nrs\x07\xb3\"\xcc(\x89}\x98\x16\x84@>\x05\x06_3\xb6L9\x84\xd9\x1d,IQ\xe6\x19\xe474L\xb2$\x9bA\x08Q\xbe\xbc\x83|\xaaW\xcf\xce\x11(\xf3)\xbd\x0d\x0b\x02a\x16CX\x96y\x94\x84\x94\xc4\x95\x1e/Zf\xc04II .\x9d\x13p.D \xc7\xc36c\x12\xa6\x90d\xed\xca \xc8\x9cp\x9b\xd0y\xbeb(\x9d\x83M\x92g\xbe\xf0s\xcdz(?\xa7\xc9\"\x11\x0d\xb2\xe28\x8b%\xd0\\\xaf{U\x12\x1f\x07\xe5\xc3\"\x8f\x93)\xfbOp\x0e\x96\xab\x9b4)\xe7>\xc4 k\xe9fE\x89\x0f%K\xc4\x05\xf4\xd9(\xb7\xf3\x02J\x92\xa6\xac\x86\x84\x94\xc6\x89\xa9\xfb\x8eE\xf0\n\x80-\x06\x15\xd3\xcbz\x05\xb7\xf3|\xd1\x1cgR\xc2tUdI9'X&\xce\xa1\xcc}\xbd\xfarU\xdd+\xb0\xd2\xd3>\x1a\x1f\x81sp\x01\xc7\x17\x8e\x0f\xbf\x1c_\xfet\xf6\xe1\x12~98??8\xbd\xfc\x15\xce\xde\xc2\xc1\xe9\xaf\xf0\xe7\xe3\xd3#\x1f\xc6\x7fy\x7f>\xbe\xb8\x80\xb3s\xbd\xe6\xe3\x93\xf7\xef\x8e\xc7G>\x1c\x9f\x1e\xbe\xfbpt|\xfa'\xf8\xf1\xc3%\x9c\x9e]\xc2\xbb\xe3\x93\xe3\xcb\xf1\x11\\\x9ea\xfb\xa2\xe6\xe3\xf1\x05\xab\xfbd|~\xf8\xd3\xc1\xe9\xe5\xc1\x8f\xc7\xef\x8e/\x7f\xf5\xe1\xed\xf1\xe5\xe9\xf8\xe2B\xaf\xff\xed\xd99\x1c\xc0\xfb\x83\xf3\xcb\xe3\xc3\x0f\xef\x0e\xce\xe1\xfd\x87\xf3\xf7g\x17c88=\x82\xd3\xb3\xd3\xe3\xd3\xb7\xe7\xc7\xa7\x7f\x1a\x9f\x8cO/\x038>\x85\xd33\x18\xff<>\xbd\x84\x8b\x9f\x0e\xde\xbd\xc3\x96\x0f>\\\xfetvn\xea\xfd\xe1\xd9\xfb_\xcf\x8f\xff\xf4\xd3%\xfct\xf6\xeeh|~\x01?\x8e\xe1\xdd\xf1\xc1\x8f\xef\xc6\xbc\xe5\xd3_\xe1\xf0\xdd\xc1\xf1\x89\x0fG\x07'\x07\x7fb}?\x87\xb3\xcb\x9f\xc6\xe7\x98M\xf4\xfd\x97\x9f\xc6,\xa957\xa7pp\n\x07\x87\x97\xc7g\xa7l\xcc\x87g\xa7\x97\xe7\x07\x87\x97>\\\x9e\x9d_V5\xfdr|1\xf6\xe1\xe0\xfc\xf8\x82\xcd\xde\xdb\xf3\xb3\x13\x1f\xd8R\x9c\xbdeY\x8eO\xdb\x9d>=\x1d\xf3J\xd9\xaa5\x17\xf7\xec\x1c\xdf?\\\x8c\xeb\x9e\x1e\x8d\x0f\xde\x1d\x9f\xfe\xe9\x82uH\xcd\xacC\xcdv\xe3]\x9e%`!\xf7\xa5\xf4\x02\x92\x8c\xc1g\xc4\xe3\xfc\x8a\xf3\xb5J9\x12\x97$\x8d\xc4s2\x1b\x7fn:\xf1S\xe2oAS\xc7\xdd\xd88\xea\x874Z\xb6q\x10R&AE\x04\xaa}\xf9\xab\x0e\xca\x00#dI\xa8\x12\xa6\xc1XU\xa5x\xc26<\x1a\xd0\x19\xbc\x92\xf7w\x95M\x89\xa7\xb2U,\xc1E%\xa4\xcbdA\x1a\xd2.k%|\n\x1b\xd5\xf0$\xa3ZVK\x17\xebCF>/I\xc4N\x992\xa1+\xe1\x83e\xd0\x8a\xe4VI\x97\x14\xd3\\_#o|}\xedT\xf7PUh\x99\x96\xb0\xab9ak\xe1\x94\xcbH%\xda\x00\xc1\x10\xe0h\x17\xad\xccd\xd4\xfa:\xd0G\x1d g\xe7\xaa\xd3\x96\xc6R\xefS\xaf%\xab\x9c\xec\x18\xae\x14\xe5M,7\x9e\xec\xce+*\xe4jz\xb5N\x1aZ$\xf3\xeb\xf3\xaa\xbc\x0f\xbb\x06\x9d=k\x14M\xc3\x04\xa0\xf9]%\xe0\xc4\xb7\xa6~\xe0\nidA\xb2~\"w\xa5\xbb24iu\xa1\x0f\nc\x84\x12\x9f\x90\xfb\xa2G\xe1I\xee\xa2gz\x1e\x19$T\xc1\xc2\xd0S\xd2\xe8\xa9\x8c\x9c\xeb\x86\x93\xb2\xba\xf54h6\xaay*\x90%f\xeb\x06\xf5Y\x0b\xa5\xea\xc9\xd0x\x8cm\x03\ntN\xd5\xdd\n\xa8\x8b\xa2\x85G\xaf\xee\x83\xd9~i\x8e\x0c\xa35\xe5\xe2\xba\x97\x8bw\xb3F\xa2\x90\xf9\x8a\xb7\x04-\xd6\xd5\x94\xb6\xf7-\xf5\xf9\xea\xf9\x90[s|E\xdd\x96\x11?\x06\x9a\x13\\\x88O\x86\xd5\xa3\x8d\xd5\xa3m8\xa3ze\xbc\xd7\xbc\xc2f:\x0f,l\xec\xa0!d%\x1bMhA1\xcd\x80\x94\xcf=\x11Oq\x10\xbf|\x1f\xa5K\x9b\x00\xbb\xbd\xf4D\x89\x92\xc4\xd6\xd6b\x94\x88\xcc\xba\x01u\xb4\xd4{qZ'W(\x11n\xe7\xcf\xb8>\xba\x1et\x9a=\xea\x8e\xa7\x86\x1do\x0d7,Q6\x9d\xe4\x96\xbdc\x0c\xb9\x94\x08\xffqO\x9e\x98\xa6\x85\xf1\xf7[\xbb\\\xc6W[\x08M\xf2+6\xbcb\x92_a<\xf7\xc3\xa4\x88ViX\\90\x92\xa9\x04\xb3\xf9\x90 \x97\x0e;\x08P\xe2\xa3!\x00\xaa)\n\xac!\xf6#\xe56ih\x9f(\xcc\xd3D\xda\xd0\xf2\x0bR\x96\xe1LV!\xdf\xf6\xea/C+*i\x18}\x12\xd5\xf0\xdf{2\xd5P\x85\x14\xc57w\x04\x03\xf0 \x06\x922\xde\x06\xe1m\xca\xe4\xad\xf8\xc2-?\x84\x1f_\xe0~\xd5\xf2\xecn\x91\xafJ\xc7\x83Mpp\xfe\x1f\xacP\xf8\xfd+\xf35\xe3\x0bc\xc8#\x96n\xf2|\xcc\xd2\xf5k\x80\x95H\x7f\xed\x99\xcc'K\xbb\xd8\xc9\xa4\x10\x8d\xda8J\x84\xbb\x1d\xae\xf0j\xd0\x9d\xe2zS\xdc\x19? \x0b\xd7{\x03\x9b\x9b\x14~\x80\xcc\xa8S,g\xa2\x1do \xa4\xec\xbc$\xd4-0\xfeW1\xd9\xbd\xb2\xe9\xed\xd6\xbf\x14\xa5'\xde\x07\x86\xac\xfdF\xb2P\x8f\xc2`\x1ceS\x15\x9em\x94f\xe2{\xe9\xf9\xe0\x9c\x84K\x9b\x10x\x90V\xbc\"Un\x85\xd0\x13\x10e\xf1\xea\xf8\xc2\"\xd2|\xd1\x12\x81\n\x88\xda\xd5E\xf4\xa5H\x7fi\x84\xb4\xd4\x0ei\xc2< \x0ei\xc8\xad\x140\x1a\x99\xd1\xca\xaaL\xfe\xce\xf1\x05\xfbaX\xf4\xd4\xb0\xe8\xb9\xdfH\xae\x16=i\xa6\xf3E\x0f\x9b\x89|\xd1W\xcdD\xbe\xe8es\xd1S\xe3\xf2\xa8C\x1e\xacN\xdb\xf0\x9b\xb2\xb5\xcb\x1d\xa7\xd0\xca\x9c\x98\xeb\xdcK\x1f$\x9b\x9b\x19\xfc\x00\xc5\x1b\x0f\xc8$\x87M\xc0\xf81\xed\xb05\x92o\xd3\xe6l08\xbdx\xaa#\x1c\xa1\xf2\xfcZ\x07\x1bcL6\xa3\xaaS\x0b\xda\xba\x84\xc4m\x18\x0c\xd5\xe0\x8a]\xec\xb9\x8a\xb1\x90,@B\\Q\x1e(\xdc\x90\x1b\xb6[E\xc7Z\x8dj\x10\xb8V\xbe\xaf\xba\x03\x1dF\x83\x9a\xf7\xf4\xea\xbe\x8b`>%\x9e\xebkcZ\x83\xf6t'\x9a\x97\x8c\xf6\x14'\x03\x16\x0eq\xd37\xaa\xb6\x08u\xc7A\xab\x99\xb3\xaf<\xe8L\x15E\x15\xd56\xb8\x87\x92\x8dU;\xbd\xd9\x9ey)\x06!\xed\x0e\x1b\xb1z\x95\x9e\xe9\xab\x015\xf2m!e\x90\xbaB\x16\x8e\x08\xffl\xd0 \xcbcry\xb7D\xd2\xc9d\xfe\x88\xf7Af:\x92;\xa4\xc7zH\xa3\x1e\x83\xe9%\xdfW8\xbb\xd5\xd4\xec\xf1\xab&\x19t^\xb0&&\xbf\xe0l\x1e\xdd\x15\xec\xc3*HJ-7\xb2\xd4\x9a\xde{{\xfeAgPv\x9f=\xf7\xaa\xcb\xd5!z7\xafwv^\xee\xbe~\xfd\xf4\xfb\xe7/\x9f\xef\xbc~\xbd\xfbP6\xc5\xe4\xbf\x1d\xe7\xf1\x0f\x8c(\xc7_\xff\x81\xbe\xf1\xb93\x02\x02?\xec)\xa2\xb0\xfek\xb1{\xf5\xa6\x1b1I\xdc\xde\xba\xd4\xed\xe9\xceC\x80\xfb\xe9K\x9d\xc0\x04\x01\xdd\xdf\x08\xc1l\x13\xe4\x8f\x00\xc1\xd5NH\x1a\x10\x8cU\xa3\xb9cDJ\x83\xc5\x9env\xd0\xca\x00\x9d\xf7\xe0 \xe5]u\xeb\x05\xf9\xdb*)H\xe3\xc5uV4I\x1d/`\x03\xb3xb\x01U\xae\xfc\xe5\x8b\xdc\x8e7 \xdeD6^du\xc6zz\x02[}u=\xfbf\\=`3v(W\x99\xaf\xd6[FT\x0c\x04\xb6?\x06_>N\xdc\xfd\xd1\xe4\xffL>^]}\xf7\xc5\x9d8\xbf\xbf\xf2\xdc\xfd\x91\xbb\xbf\xf1q\xd7\x9b\xfc\x9f\x8f\x1f\xaf\xbe|\xfc\x18x\xdf\xed\x7f\xdc\xf5>\xea\x81Yx\x00\x98\x8f\xb7\xdf\xfd{oH\x07\x8b!S\xc3\x8eI\x17\x8bV\x92t\x01\x98F\"k\xc3\xad\xb0\xc7\xc6\x1ed\x08\xd4%R1JB\x158B\xa64\xdc\x0em\xa0F .?\x8f\x05\xc2\xa3\xc8n$\xea\x9b,A\xf9\xf6H\xa4\xd3<\xf7^\x86\x0e\xf7BD\xf7\xa4\x1f\xcd\xf2\"A\x99pm\xd3\xcaE\x17\xf5\xc1\xb9\xbe&\xe5I\x1e\xafR\xe2\xe8\x1a B\x1bAU\x08AC\x9b\x05Y\xe4\xc9\xdfI|\x11.\x96)y[\xe4\x8b\x8bhN\x16\xa1\x90*\xf0\x8f\x87\xa8,\xf8\x97\x93w\xe3\xcf\x98\x8d\xb3\x10\xf8\xf3/\x8bT+\x94dSR(\xefe\xbbfq\x00\x824\x81i\xd4\xac(z(\xec\x98\x89\x1b\x0b\xdd\xcc}\xf1\xfd\x0b\xcf\xb0\x0f\xf0\xd3\x8b\xd7\x9e\x91\x97\n\xed\xeb\x83\xa0\x10\xd4\xf3(T\xf5\xdaXKFF\xd0\xddZ\xfd\xae\xfdk-|\x19\xb6+\xe1\xa2\x99\xe1qm\xa5,\xa7\x95\xc7\x10F\x8bg\xbd&\x8b0I\xef\xd1\xc2\xaa$\xc5\x1f _\x8c \xca\x17\x83\xda\x12\xfdb,(\xd9\xa2\xc9\x828\xc3[t\xe5\xf5\x95\x17\xd0\xfc\xf8\xe2L\xa8\x84\x19\xf8\x02\x83<\x05\xd1\xc4\xf0\xb6\x06\xc5u\xe3\x95^O\xd3<\xa4\x8f\\u\x92Q2{\xf4\x0e\x0bT\xd8G\xff\x83\xb2\xca*\xf6\x94\xb88\x10 \x8dW\xad\xf2\xa5\xdd~\x13\xdc\xdb\xbcLw'\xa4\xcc\x82mt\x17\x9d\x0frr%\x99\xdeyF\xff3 \xc4f4h3a\xf2AO6\xc14/\x16\xa1\x812\x02\x81\x12V\x13\xd4O\xbcv`\x13\xb8\xa9\xcc\xca\x18\xd5S\xc2%\xf6.)\xdf\xae\xb2\xc8s\x13\xc6c%\\O\xda\xf9\x90}\xca\xf2\xdb\x0c\xb5 \x85K\x1b\xec]\xd7\xd4\xa46\\Xa%\xcb\x0d\x93<2[7\x89\x7f\x00\xa4\xa3\x15U\xd6\xfa\x8ep\xf7\n\xf6\x9b\xaf\xa3\x96)\xa8|r\xd3RP\xcbR \x99\xd9\xb1\x14\xca\x97\"P\xe1\x8035V\xb3Vg\xaa9\xef\x1c[\x16\x00m\xce\xb26\x844\x93\xcf\xa2\xe3\xdb\x0c\xc9\xb0\xcf\x0bC\xc0f\xf60\x1c6\xc3;j\xf3\xf7\x1b\xfc\xbe,\xc841x\xb4b\xcfuU\x03F\xab5g\xba\xe5S\x9b\xad\x16\xe6\xef\xe3\x8aG\xb6\x1c\xe0a\xc7\x01\xceN\x90\xd4C\xa8\xfa\x97\x9c\xe2a\xdf)\xee\xb2Y\xbd\xc3K\xff,\xa7\xe1\x8cM\x8e\xc3\xcd\xa5\xdc\x1b\xd8\x87\x1bF\x96\x8f\xd0>\x16u\x01\xee|\xb8\xe6\xde\xd2\x17\x13\xf6\xdd\xf9\xbcH\xb3r\xc4\xce\x8e\x1b\x96 _\xd1_\xc1\xb5\x85\xc0Q\x0f\x05\xc48\x91\x0d\xf9\xb2\xdc\x11\x83\x07\xd8\x03\xfe\xff\xcb\x17\x98qK\x10\x9f\xa7HU\x0d\xe5\x85\xe5\xe1P\x023\x11\xa9>\xae\x88\xbf\xf5$\x93nn\x9b'\x04\x9e\x0d\xd3\x81ns\xe5\x13\xc9\x1d\xc8\xfd\xb6\xb2\xca\x85\xdf^v\"\xe4V\x9d\xa6\xd6\xf94g\xad\xcf\xef\xdd\xba|\xb6\xac\x8b\xfb\x8d\x0bs\xaf\xf6E\xaeV\xa6\x01\xe4\xb6U;\x91M\xfd\x85\x99\xdc\xee!\xa7\x0f\x199\xad\xec\x19\xb4$\x95\x1b\xf0\xc2N\x9d\xb2\xbe]\xe8q\n\x0e9\xde\xd8\xb8\x98\x1c*\x84\xf7\x97/\xb0T?\xd4$7#\xc6-\xd3\xd5h\x87\x95\xe2H\xa2\xfa){(\xde\x03\x06\xb3h\xa9\xd2\xb5l\xf2a\x03\xff\xd4R\xbc\xc3\xba\x90Jc\x9d\xad\xde&;Wv\x96E}\x0ed\xff:\x0fm\xfd9\x93\xa5\x04D\xd91\xbd|\x16\x93j\xd4\x12\x1d\x1e^UG\x16\x92M\x07l\x04\x07\xd04\xb5\x9dN\x0e\x91\xef\xc1\xff\xcdOg,\xfd\x8c%~b\x7fJ\x9c\x8b\xee\x85\xf9\xdaw\x80\xc9\xa7\xd9\xd9=hw\xbe\xe1\xf3H\x9dA\x8d\x18\x94\x03p\x1byx\xba\x05\xce\xd5\x87\xad\xfa{d\x99.\x86\x15h\x82\xc7{Tw\xe5;\x05\xd1\xa8pa\xf0^\xa2[\x8e\x04\xde\xf7L[\x17j\x94\xcc\xa4h\xa8\x0fQ7\xa9\xcd\x118\x07\xd9\x1d\x9d\xa3\x0dT\x98\xc1\x0dAc7\x0bU\x80\xe1Q\x86\x9e\x08zC\xa5\x8doeH\xee\x11\xcf\x99\x018R\xcc\xdc\xb8 \xffSv\xd4W,\x15&\xcd\xd9\xf9\xdbB\xff\xb7lQo9WV\xa2]\xb8Xa\xc6\xe1M\xcc}\xb7\xf6\xfb\xab\x0fcV\xd1X\xef\xfaW\xe3=\xc8\xd4x\x89'\x05\x8e\x11\xff\xda\x84R\x86\x0d\xb3\x86\x9c+\x97x\xc3s3\x93\x19lL\xa24\x94\x81{M~\x0b\x92,\xc6\xc0*\xceG\xaa\x85c\xd3\xaf\xe1\x00\xcda;.\xa5X\x7f\x92\xba?\xd3\xbe\x1b.-\x7f\xda\xaf&Q\xcd][t\xcf\xd5\xf0\xc8\x9aq\x87\x95V\x9ex\x15\x87\x05O[\x84\x9f\xabxrU\xc6Fb\x85\x1b\x95 hw\xc1`\xd7$\x85\"2OCl\xd8YY~?\x8ds\xd5\xd8\xa0\xbb\xe2\xc4Z\xb1\xeaz\xc5\xb0\xd2\x0dGY>d\x01\x06W\x19/\x12\xca\xdd\xdcc\x9a\x12\xac\xa3\x9ayy\xbb\xd8\xf8\xaaMz\x9dG\xac\xfeI\xf3\xfb\xaeV\xbe$z\x0e\xbb\xd4\x03\xa9&\xe5\x06\x9b*\xc6(D\x06\xa8\x10\xbe\xebL\x1e\x152X\xacJ\xca\xd0g\x08<\x1e\xf2\x9a\x88[)\x8b\x1b\x05#\\\x11\x0eo\xf5\xcc6GD\x16 \xed\xb7\x9f\xe7\xfe\x8f|X\xf9P\xfa`\xf0\xc4\xac\x83\xb9\xabm\x03\x0c!'\"\xe5\n+\x1c$\xc4\xd4l\x01~F\x05'\xb7\x9d\xce\xd5\xd2\xda\xe9\xd2\xd0\xceDo\xb1\x9e\xa1\x8b#U^\xe3\xa9\xc6oc^5\x9f|\x03\xcd\xc3F\x1f eZ\xbe.\xbf\xff\x90E\xe1j6\xa7>\xac\xb2rI\xa2d\x9a\x90\xb8\x1a\x1bv-\x00\xf7\xf7\xb0\x89\x0e\xa2\x1d\xcf\xe4.\x84\xb7\x17\x05\"j5\xa7\xde\xa3&\xdak\xcdq\x82^\xa2\xd4\x19\x98\x90+\xbb\x92\x05\xd7\xc2\xc8<\x0f\xca\xdb\x04UXt9\x97i\xca\xa2\xb0$\xb0k\x8e\xf4/\\\xb0\xa2[t3\xd5\x82>\xa4\xdb\x9f\xb0\xd2\xa7\xbd\x95\xfa\xcdu\xba\x7f\x13\xcf\xee\xd9\x84\xfa\xf6\xf4\x9e\x0d\xca\x9b\x7fc\x99UE\xd4\xf7[\xe1\xb1\xfd\x18.\x97\xe9\x9d\xe8\xe0J\xd7{\xad\x84\xf4\xb9k\n\\\x83,\xd4\xfd\x1a\xc4C/\xc5\xeb-n\xda\xe2y\x95^t\xc9C4r\xc7\xe5Pnnz\x90N\xca+\xad\x8bF\xfc\xa3j\x954\xb1L\x18\xc7J\xcc\xd0N\xe5!\xb6\xe3\xc26$oX\xfc\xce\xa4\xb2\xda\x1aYV\xa7^\x17\x96\xecAU\x0d<\x93\x91[5\x02)~cx\xd3u\x94/\x0e\xfa\xff(\\\x1a\xc8.y(\x90\xaf:8\x02\xaaU\x94\x04\x08/\xa5\x9f\xf6\xae\x074\x87$\x8b\n\xc2\x90\x0d\xfa\xb7\x08\x9c\xd6\x92J\xe4\xea\x9b\xe9/\xd9\x7fZ\x84\x11\x1e\x82\x8d\x04\x0cL\xd7u^\xe7h\xe6\x00\x1b`\x15\xb9&<\xfa\x8du5\xd9\xc3\x03\x88d\x12\x83\xee\x83[\xfd\xdec\x8c\x8dyU\xd0\x08[F\xd8J8M\xf0\xad\xeb\xd4\xbf\x13\xfb\xb7\xdaA\x9a\x0e\xe3\xad\xd6F\x07\x81\xad\xed\xd1\xb3\x156:\xc6\\\x15\xe5\x9ci\xeb\x8ax_g\xf4\xd1\x87\x98~\xe6>y\xd2\xb9/\xda]2\xb7f\x05t\x8a\x0e\xc8\x1a#\xd6\x97G8\x02\x90K\xd8\x9eh\xa3\x0d\xb7J+\x19\x8a\xe8\x8dh\xf0#cC\xaa\x0b\x0eF\x9e\xa6\xb0\xf04\x96\x93!\xb3\xa1\x03\x83\xc6\x04N\xd0\x9bjo\xbc\xb1W:\xa9\xf6\xcc\x16\xb4\xf8\x0e1\x13]\xcbh\x03\xeat\x10,\x9b\xc8\xd26\x8d\xc4\xdd\xf1\xea\xdbx\xbfE\xfc\x19(?I\xe3\xc3H\x8b\x16e\xea\xeba\xbe\xca\xba\x05\x02:\xbboS\xae\xa0\xed\x85m\xc3YRy\x94\x14\xd3`q\xa0R\x87+\x96\x16\x9c\xfd\xf8F\xe3F\xec#4\x1c\xe6\x95\xbaJ\xa3T\xbfI\x80n\x0cD5\x0f4\x99\xfbl\xe7{\xcf\x0b.hA\xc2\x85\xa0H\x82s\x12\xc6\"\x02\x1b\xbe\xffR$T\xbcg\xee\xee\xeb\xefQ\x80y\xb4Z\xa6\xe437\x80\xe3)\x97E\x98\x95\xd3\xbcX\xf0\x8aww0\xf5}X\x96\x97\xf3\"_\xcd\xe6<\xf3\x8b\xe7\x83LMz\x1d\x01\xf28_&T,\xdc9>\xdf\xf1l\xf4\x9fA\xd7\x1e481II\x12\xc6|\xa1|\x84\x07\xaa\xe0\xa7PF\x8b\xbbf\xd24\xc9\x92f\xc0E\xdb9\xbd\xd19\x07\xfa#-\x0f\x08o\xd4~\xb6\x93F\xaf\xec\xf9\x04R*\x8c\xe6\xfb\xea\xb3\x16^d\nd\xe0o\xc2\xc8 \x82P\x1f\x1a,\xb9\x93\xc5\xe8fk\x8b\xf1y\x18v\x1d+`3h-k\xbe\x07\x02\xac1\xca\x8bO$>'\x7f[\x91\x92\x96o\x0b\xf4\xe9mJ\x96\x8bDP/\xcdPlO\xd3\xdb\x92\xcfW\xee\x91\xa5\xf5\xedk\xc7\xeeV\xb7\xd3]\x9b\x0fYq\x11\xc6\x06\x0dn\x8a\xfc\xb6\xe4\xd4\xcb\xc4Y\xef\x04\xbb;\x8e\x0f\xec\xc7\xeb\xc0\xb9\xaa]\x81\x04kR\x94I^y\xf9\xf0\xe1{\x8fk\xd2\n{\xda\x04\x87w\x99\xe8KpW\xed\xd3\x0b\x1a\xa2-\xfc\xac\xdd\x9dT\xd8\xad\xbc\xd0\x8e\x954H\xb29)\x12\x81\x15^\xed\x1aX\xaa\xc8h-\x02(|\x12z\xa6#\xdc\xe0\xcf\x06\x99IL\x05\xfe\xd1=\x0e\x80\xd4uvw\x9f\xefJG6\xed,\\u\xebC\x92\xd1W(i\x025`\x8d\xd7R1e\x03\x98\xfb\xa8\xa1\xc5\x1a}iE\x0d\x0b,l\xf983bg\x10\"6\xee\x82\x8a\xa3C\x0420\x84Q\x05e\x1fSU\xf6k \xd5\x11\x99\xf0\x8b\x8e\x93\xd9\x15\xfc\xeaz\x7f\xea/\x10\x19z\xb7\x0f\xbb/`\x04\xbb/\x9e\xbdzn\x99\x85FW\xd0\xaa\xf4\xcb\x17A\x0c\xe7\xb0\x0f9\x8c\xc4\\\xa4\xf5\x87\x94Q$)\x8c \xf2\xcd\x95\xd4\xb1~\xdc\xf6w\xafF\xe6az\x18\xa62,\xa7/\x0f\x02\x12\x1f\x15a\x92\xa9\x89\x1c\xe7i)\xcdr\xfclh\xa6\xc5\xa4\xa4E~'\x12\xcd+\x82\xf1\xf99\x7fE\x82\x98Dy,\xa2\xc9\xd8N\xaaF\x1eVxZ\xb5\x86B\xb2q\x16\xe5\xa2\xb7\xa4\x95\xf6\xe5\x0b8+:}%\xe5I*\x13\x87 l\xc5\xb5\xa1rD\xab\xe4)\xef\xb2HJL\xd8\xfb\x0dn\xe5\xf7\xdcZW+\x9cg\xa8\xff\xd2\xab\xb8\x0b\xedC\xb3\xef\xc4\xe4A\xdc\xaeoU\xec\xd8\xad\x84RpY\xf4]\x16u\xe7\xe3\x81\xe0\xb0\xe3\xd1\x8d\xfd@d\x14c\xff\xa8\xe4C\xb4\xb9%\xb2\x81\x8a\xc6 \x15\x7f \xf7\x1eII\xe6+\xbf\xd9\"X\x1b\xf9\x8a\x871\xf5\x0c\xc4\x87\x99\xa6\xd2\x9f\xad-\xe5x\xf71r\x80[\x9fJn\xeeC\xe1\xf9\xca9\xe5^\x08\xa6\xdco\xad\x03\x97\x9br\xb9\xa8\x14\xa9\x12\xc1\xd8\xf3+,V\x19\xe3\x15\xdc\xdc-\x1e\\\x81\x0f\x17\x1cT\xecZ(\xe89\x8aO\x00es\xd0A\\\xf5+\xf8\xe0\xad\x01\xec\xc1\xd8\xd5YD\xfd \xf1\xcc\x90{\x07\x7f\xb7\xb6 C\xde2\xb9\xa2dX\xea-gB}\x8cfZ\xba\xd78\xcd\xfcj4gsv\xed*\xef\xf6\x91\x1b\xbfXi!\x05\x01\xa8@Y'\n\xf8kl\xfa\xba\xdb\x8d\xfciX\xd2\x1f\xbb2T`\xa6\xd4\x88\x8a\xcem$\xaa\x03\xc2\xae\xb9\x03\x92\xdf\xdai`-\x8d<\xcc\xc8-\x84\xfcf\xb11\x016\xba\xe0\xce\xbc\xad\xb9\xe6s\x930\xd8p\xe7\xfc\x12\xec\x8ew\x00\x8d\xbe\xd9\x8f\x06-\xe05\x1c\xa0\xdeY|\x9f2n\xf6V#\xfaX~N\xa6(\xe1\xa2ok\x0e\x0e7\x08\x9e\x94f}\x0c\xbe\x86\xca\xc5\x87\xc4\xcb\xe2\x8b\xed\"A|^\xeb%\xd7u\xd1\xb5\xbd\xac8\x01\x95\xc22e\xaf\xfej/\x8eg\xb4R\x98\xbf\xef\xc9/\x9e\xe7\xc3T\xb9-\x1e\xb4\xa67M\xa4\xc8E\xe9\xc6k\x03\x15\xec\x19\xfaP\xf6F(_\x05>\xc7\xcb\x03\xe5\\\xc4\xa8+r\xa6\x18\xe6\xa4\xf2$\xe4a\x87\xf9\x17\x97\xb7^\x7fSk\xd9\x1d4\x9ake4\xa6Ad\xd0\x17\xf0Q>\"\x06\xa3<\x83\x9e<\x01\xaa\x10C\xb8\x06-\xe2Hb\xe4\x98\xa59\x06,\xfc\xd5\x15\x07\x84\xc68\x16n\x8d\xbb\x07\x8d\xf3\xd6\xdawj\xa4?\x0c\xb6\x0c\xeb\xca\xb1\xb2\x86:\xcc\xb2\xa0j\xf9PD\xcfo#\xd8\xc9g\x9b\xbf\x8a\xf87b&;\xc1\x91\x8b\xcd\xcd5\xf4\x8a\x0e\x83AtZi@l\xe6\x93(\xa9e\x05\xe6\x0c\x95R\xf4\x8a\xa3\xcd\x92\xcf\x1b:\xfd\xcb\xf1\xc6\x82k=\xa1w \xbc'\xc3\x1c\xbb2\xd0'\xce\x86\x0f+\xd8\xdc3\xc9\xd3\xd8\x93\x07a\x9a\xf2\x83\xa0\xe4^\xd8\xe4\xee\xe3;\xa6\xf2\x92\xe6\x83\xe30\xd2\x82\x1f\x00Mx\xd9\xdc\xc4\xac\x1dG\n'I\x18\xb9b\x11\x0b$\xa2\xaf\x89*\xe7\xf1\xecb\x04qN`?l\xe7L\x1b\xd6\xbb(\x08)&\xee\x94\xc8T\x9c|\x10\xcdW\x99\x85\xd1\x92\x0f\xea\x0b\x05DP\xf6\xddy\xb99r\xbf\x88\x87\xc1}\xb5B\xbb\x88\x99\x1a\xdc\x1c\x8c \xad\x16-\xf5\x19\x036\xd5\xc0\xc1\x0b\xae\n\xb9\xa3\x81S\xdau\xf4\xca\x83\xbd\xa6\xb9\xf9\x1e\xb2\xd4ZW\xa9\x87\x0bhn\xa4Z\xb4\xc8H^\x86\x06fM\x07\x9d\xc2\xa7\\\x8f\xb4\xbc:\x85*\xf1\x96\xb6\x07xx\xf0\xc9\xd5\x1b o<6\x0c\xb4=\x92\xa28\x9c6\xebJk\xe1\xe9\x0c\xc2\xca>A~\xb7\x171\xb3s$e\x1e|p\xf8pZ.\x92\xf4gF\xe8\x08\x0d\xad\x84\xc8\xb5\xdbI\xa3\xfe\xa8\xb7{\xd5\xd4\x1b\xdc\xda\xa8\xcfW\x1f\x1c\x8d\xe9\xe6}\x85\xa4\xacE\xbfBYI\xcbX//\xe3nH\x18\x07\x8e\x0f\xce\xd1\xf8\xfd\xce\xce\xce3\x8b\x8f3ho\xf0*\xb9\xd7\xfd\x99\x85E\x10\xb1\xb4\x9e<\x11\xbf\x82yX\x1e\x0b~\x0bl\xa1C\xa5\x9b\xe8z\x99&\xed\xd2Wh(\x07{\x03s\xfb\x16X\xb8\xf3\x0d=\xeb\x08\xe0\xd5/O\x92Z\x90\x1bsU\xdf\x94\xd4\xfc&\xdb\xed\x9c\xe3\x92\x0e\xa6\x9a\xbc\xa4\xc2\x8f\xce\xfaN\xcb\xaf\x88\x85\xe6\xbd\xe2;y\xce5\"\x9c\xb4\xee\xe5}P\x15G\x97\xc9\x92\xf4a\x07.\x01h\x1e4uP\x90\xc30\xcbr\n\xac\"\x1f\xd8\xafB\xdcp\xea\xac\x88\xd6r[$i\xbf\xa3C\xb2\x9e\x1b\xf0\x1b\x18s\xbb\x8d\xfd\x86\xc1#7\x88\x0b\x85\x8d\\\xa5\xab\xd01:W\xa1_V\xae8\xdd\x02\x17\xb4P'4\xb6\x1fi+$\x0d\x94\xe2\xdc\xed\xaa;L\xf0**Y\x06\xd3\"_\xe8\xf1\xe3\x00DH\x05\xcb\x16D\"\x85\xebWpT\x8dT\x18\xe3\x0b\xf6\xf1U\"@FmsEX\xbc\xe1\xd1$\xd3\xcd\xdak;\x86\xac\xaa}\xe1\xf9\x90\x0b\xb9\xfb\xfe\xb0\xb3[R\x03\n\xc8\xf0\xa5\x0f\xa7\x94\x14@\xb2\xd8\x16d\xd3D\xdd(G\xb4\xc5y\x86\xd8\x8b\x19\x9e\xdc\xab\x16\xe7m\xe7\xd2A\xb9\x9e1Y-\xc9'\xb4\\$\x80B\xdc\xd4\xa4\xf2>\xf7\nN\x1az\x80'\xe1\x1dn\x15>\x11\x98\x1bQ\x0fF'+Q_\xc0\xf1\x8c\xd1\xa3\xb9,A\xb1\xa3\xc989\xd4\xbc\x8er\x0dm\x1eg\xeb0Mb\xc8\xf2l\x8bW\xbb-N\x1a\xe4s\x1c\x0f\x95\xc5\xb9/\x8e\xe6\xbc\x87\xcdy/xJ.\xf9\xd0v\x10\x10\xb9\x069\x97\x99\xf2\x00\xd2n\xde$\xc0B\xc3\xde\xaf\xa4A\xb6\xf5AU\xae\xdek|S\xd5}\x078\xd1o\xf4\x8c\xd7Axw#\x17E\x8b[\x82{Jl_\xda\xe1\xc2G>F\xf2H}\xbeVz\x18\xf6\x8a\n\xee\xb2\xa4\xda\xa0\x8c\x88\xcc\x95\x0d\xcf\x15\x03,\xce#\xcc|\x9e\x94F\x18\xf8\xce\xc2\x18\xb9@>\x95\xd8j\xd3\xaa\x1b\xc9\xeaF\x0b\xb8:8\x12m\xde\x0c\x9a\xcb \xed\xfd\xa6\xeck\xa7\xc3GR-\x18\xc4\xed\xc1\x05\x0c}p\xc3=\xb6\x19\xd8Z\xfb\xfc\xdb\xb8\xe0n`\xc3\x1d7\x02\xc3\xcd\xbb\xfaH\xb1\xc2\x08\xf4P\x84\xda\x83\x07\xce\x08\xb2\x1eY\x85\x90<\x8c \xe9\xce\xc8v:\x8fgo\x07M\x1f-\x86S)\xca1O\xc3\xc8\xc8\xe4\x1b\xf3Z\x85<\x9b{\xd0vs\x06\xb5\xa4G\x95\x94\xacj\xfc\xd1\x89\x9e\xcb.\x8c\xb5\xf2A\xa2\x8cvL\xa0& \xc3\xa0j\x10\xf1\xa4\x11\xee\x1c\x1a77\xbb\xea^eCjo\xf0l\xcdV\xda3 \x1b\x16H\x9e\xbflm\xf9\xca\xad(:\x82\xac\xef\xcb\x14\xa9\x07\xbe\x19o\xcf\xda\x02\x13\xbc=\x93$q'\x11X\x12z\xd4\xba1\xef\xa6\x95\xd0\xd6\xd2\xe2\"O\xb8\x99\xa2\xf9\xbb\xfc\x96\x14\x87a\xc9\x8d,6\xdc\x893'\x9f\x19w$\xee\xdd\xd9\xff-\xfc\x11\x96Q\x92\xb0\x1f7I\x16\x16w\xf8+,\xc9\x8b\xe7\x98+*\x9f\x8a\xff[OE\xb1\xdd\x17\xe8k\x17k\x90\xbf\x8b\xf0VQ3r l\x82\xe3xZ?P\xcf\xa8\xb2\n\xd0Ng\xe9`\xb2\xde\xf3\xe8d\xb2G]W\x83+\x83\xf2\x81I3\xd7\xca&5X\xe6[\x93\xda\x89\x91\x83&U\x9c\x83\x91\x91\xe2F\xae\xba\x97\x93\xee\x18W\xe3\x80h\xef\xdd\xe6\xe8\xbc&\x84]\xdf\x87\xcf\xc8\\\x85J\x15\xd7C\x1e\xe3\xc4\x19\xb1\x96,\x96)Y\x90\x8c\x92\xb8\x87\xb5\xa9/\xe7\xb8h\\\xfdF\xb2x`g\xaa\xbb\x8c!{\xdb\x1a\x90 \xa9\x02\xc2\x055\xe2\xeeW\x11\xbd\xdf\x8b\x99\xa8\xcd\xbf\xa1\xe9$\x83{\xa8\xaf\xee\xa8\xa5\xcc\xabP\xf1MQ\xab\xb0\xc8\xcbc\x8e\xe2p\x87\x16R6\xcb\xd8\xad\x06\xd2\x192S\x80\x07q\xad\x1f\xb4S 7\xfdJX]\xd5\xb9\xaf\xd2\xb2\x19\xbf \xcc\xb3\x88TB\xb7\x0e\xd2\x8d\xd6*G;\xbe\xa2\x9a\xd5\x16Q\x83r\xa8\x14-Fe\xe0\x16\xacT\x97\x8c\xdb\xee^\xdbJY-\xd3\xd5v\xa5\x84\xae#\x14\xd1\x81\xf6\xd8\xda\xdb\xbcl\xf4\xc7\xca\xe7Z\x9aw;\xdb\xc7\xd8\x8d\xf7\xdc\xf9\xf5%\xf7Z\xfe\xd6\xb6\xe9*S\xf3ToZ\xae:O/\xbf\xcb%%Y\xecz>\xd0V\x0c\xf8\xdf\xd5=U\x03\n~\xcf\xa0\xd4}\xb6\xf3\xcac\xc7\xe1\xf1bA\xe2$\xa4\x04\x13w\x87\x85\x0ex\x8c(\x83F\x04\xf2\xbbf\xe7\xbf\xb9\x1b\x99\xfb\xe2\xf5\x8e\xe7z\x95\xdbN\xc6-a\x98\xc8\x17\xafw\xbfa\xa8\xeb\xcam\xfc\xcb\x1ds\xf0\x84\x17\xa6\x88?\x99\xfb\xea\xa9!\x86\x97n]-\x0e\xf6f\xc6\x95)jSWx\xa0R*E\x867\x9a\xff\xc5\xb4\xa1.y\xdf\x05\\W^\x1b\"_u\xa5\x0f\xb51\xa2\x12\x9f!\xb4\x98W6\xcb\xe1\x85@\x86\xc1W\xb9A\xb0W\x9b\xbaF\x9a\x93\x05~F\xa0sI\xf4p\x11y\"\xce]\x04\x7f\xd8\x83\x1d\xc6&\xb0\xb4\x914H\x96vN[\x90\xba\xa5\x1by\xde\x1b\xe0a\xee`s\xd3p\x1d\x85z>\xaa\x94\x95rq\xc2T\x1c\x8d\x13z\xe5C\xe1N\xbdz\x8c\x1a\xbf&R\x15w\xc9\xdf\x00\xcd\x0d#\x89\xd6i$\x05\x95Z\x07\x86\x11\xb5&\xd1\x1b1\xd3\x8bHaJ\xc2\xc4nD\n\x8aT\xb8\xf1\xe1+\x97\x12tw\xaa\x06,\x967\xce#\\r\x11\xc0\xe1\x92|\xa6\xa7yL\\\xc7\xe9p\x1cn\xd0\x00QT\xaf\x06\xdc\xaf \x83\xd3\xc1\xe6{\xf2\x80\xe7\x97\xeb\xdc=\x16\xb5\x9d\xdfC\xfc_f\xfd\xfe/\xb11\xe3W\xb3D\x05\xad\xd6\x9a\xe4\x94E\x8e[;Z\"B\xf3\xa3\xca\x8f'8\xd1c\xd0\xc8\x077l\x1e\xc4!\xe5\xe1|\xf6`s3\x81\xff\x80\xa7\\\xdd\x01k\x0b\xcay2\xa5.z\xa1\x10\xe2\x17ix-(\\6\x82 \xad\x96qH\xc9\xbb\xf0\x8e\xcd\xf3\x00*\xd7@\xb2cD\x0f\x83\x80u\x19\xde\xa5y\x18w\x84\xfb\xa9;\xf06I)\xe9>\xe5{:`\x10\xc9\x0e\xeb@9\xcfo\xfb\xc9C\xc6\xa0\xb6|B\xf5\xf8>\xe7\xc1\xb4\x94\x04#UE*\x17\xb0\xba\xfby\x06\xc5\xb6\xe1\xae:\x86ke\x1b\xb3\xd9\xc8\x14\xbf\x8e=l\x16\xb2\x91\xe1.\xc5f]\x88s\x17\xcd\xc3lF\x84UW\xff\x0c\xdes\xfe\xda\xbe\xe3\x1d\xe7\x11\xa70|\xe4)\\\xe41\xb9\xd7\x0c\x9a\xb8/c\xd0\xae\xf6\x06vR\xdc\xb1\xd7|\xf7\\\xf37\xa7\xcd\x9f\xb5\x91\x81Vr\x8a\x1b\xcfi\xb3p:Z\xd1\xca\xb1\xc1:m~\xae\xc2J2;\x83+\xee\xa2\xf2\xbf\x1ea\xe2\xf5mH\xc9\x8fd\x9a\x17d\xfc\x99D+\x14l\xd2 \n3\xf1\x8a~.y\"k\x0cOR%m\x1e\x96?\xe5\xe2\x12\xa6\xfa\xfeKB\xe7'\x84\xf2Y[\x86E\xb8 \x94\x14\xe6\xd4\xe3,JW%\xab\x94P\x9ad\xb3\xb7ya.\xf6\xe3\xddqL2\x9a\xd0;\xfc\x1e\xa6i~{Y\xdc\x1d\xd3\xb3\x15\x95\x85\x16\xec\xa8\xafn\x0ddj\xa1\xbf\x96\xcb<+\x89\xb9P\xa9\x16)\x1b\x05\xf8\x1b\x0dg3\x12\x9f\xc9\xb1\x96\xcd\xa1\x97\xac\xbb\x97\xe1\xac\xca{Dh\x98\xa4\xd5\xab)\xfby\x9e\xd3c\xaet\x87r)\xca\xa3Z\x88\xf6\xe6rzo\xc2\x92\xbc\x0f\xd1\xacO\x00@Rw`\x9ad\xf1Q\x95\xc6+!\xd1\xaaH\xe8\xdd\x91\x96U\xa6\xf3i.\xf2x\x15\x89\xa6\xa2<+W\xb2\xdd\xbc9\xc2eH\xe7\xb2\xfcb\xcd\xfd!I\xe3g\xfcM>SRdaz\x94G<_\x92M\xf9^M\xca\xb3\x83\x8bg\xbc\xec\x92D\xd5\x8f\xff,9\xa8\x9c\x932O\xd7$\xbeX\xdd\xd0\x82\x88\xe6Y\x06\xedC+\xbdQS\xf5r\x91\xaf\x8a\xa8\xce|Ay_WE}\x19\x8b,\xaf!>\x82\xa2\x15\x94\xb9\xafLA\xdaQ\xa5'GyA\xd1\x0c\xf1Wt\x87\xf8+\x9aH\xafn\x13cm\xbf\x97\xd0nVa\xb0\x1c\xfd\x08\x17\xecL\x9d\\1\x96bF\xe8q\xe6N\x9c\x05\xa1\xa1\xe3\x83\x83K\xe6T.\x9e5G\xb5\xd4\xf3a\xe2T\xdb\xact\xae<\x1f\x0f\x8d\x12Eh\xffy\xe1\xb9\x93+\xcfC\xc8\xea\xb1\x87\x94\x97\xa0\xc1I\xb8\x0c\x92\xf2$\\\nE%\xec\x93\xeb`\xb0\x06\xaf\xd6\xf4\x16\xc9I&\x12\xb5\xb9A2\x81\xf7\xe4$\\z*9\xea\xab\x98\xe1g\xae\xe0\xd2\x7f\xf7a\x9a\xae\xf7Bj%)\xbf \xb1O\x94\xe7\xf1\x0e+\x93%\xa7\xea]RR\xcf\xf5\xbc\xa0 l\x1f\xb9\x8d\xaet\xdd\xc1\xc8\x08\xa4\xb1\x081A\x959\xd9\x97o\x88\xb8\xaf?/R\x87[5\xd4\x89]r\x19F\x9c\xbbj}\x9b\xe0\x04\x0el\xca\n\xf8r0\xb0j\xce\xbb\xbe\xfc\xffP\xa3\xa87\xa7\xbe<\xe6AX\x8e\xb3\xff\x1a:\x87\xf1\x84|\xf2\x83\xa4d\xffT\x81$ \xca|A\xbe\x11f+\xe0\xd4\x94\x8d\xfbf\xe4\x92\x07\x1d\xba\xf49>\xa5$\xa3,\xc9\x0c\xabz\xc7\x14\x08}\xd3\x9aH6\xd5\xb1K\xbcj\x9f\xf7\xed\xef\xd6~f\x0b\xda&\xd5\xb8\x8b\x92\xfb\"\x8f\x81\x953Tz\"n\xceZ\x1fQ\xa7\xac\xb5\xb5x\\]r+vW\xbb\xd8\n\x1d\x93`1yb]\x8bM\x811\xd2\xcd_Fp\x89\xd1\xf30j\x15\xcb\xe8,V)M\x96aA\xb7\xa7y\xb1\xd8\x8aC\x1a:u\xb6\xbcX\x1c\xb1\x14\xcc\xcapE\x12\xe1q\xb8\xfdy\xeb\xf6\xf6v\x0b\x8b\xac\x8a\x14\xaf\xd7I\xecT~\xda\x8d\x04\xb96U\x06h\x14\n*\x15\xc0\x189\x1aI\x894\xf2\xe5\x9d\x00Z\x1d\xe3\x87\xf5\xe1\xde \x83&dy/\xb0c\xc7\x8a\x9c}\xc3\xa1\xd2\xc6*\xd1\xaa(HF\xdf\x0bR\x84\xd3e'\xcdS\x19A\xc5\xfd^\xbfrY\x99y\x04~1\xf4\xd2k\xd6\xc1\xce\xff\x893#\x14\xe1{\xc5\xff\xe5%\xfe\xe7\x1e\xba\xd8\xaf|\x89D\x0f\xfb9'a,\xf6B4g?\xd0\xcb\xa6\xa3E\xd2\x88z\xc5\xde\x15Wf;\xd7\x00Z\xf7\x9fS\x1e%M\xa5VX\xd1P\x08\xcb/HJ\"\x9a\x17\x9e\x1b\xf5\x05\x82\xac\xb0\"\xee\x8b\xaaBM\x9d\x9fs\x04\x9cHz\x94\x86V\x85\x1e\x15\x9d7Q\xd3d\x8f\xd2\x0c\xab\x8e\xa3\x0cG\xf7\xfc\xef\xeb\x04\xe1\xa35\xc8k\x14\xcdf9\xdd\"qB\xf3\xc2\xd6\x01A\x9e>J\xf3\x7f-\xf3\xac\xa2>8\x18\xe9\xb3\xacm\x86%\x87$\x8dp~\x94\xce\x14\xa2\xbe\x9e\x0e\xf9Vz\xbe\x97\\R\xdbC\xecSh\xccB\xf7\x11\xc5Qr\x8b\xce\x91\xcd\xca\x80\x89\xc3\xe8\x03~M\xa8\xa6d\xdc\x8f1\xce\x05\x8f\xca\x8a \"~b\x19\x9c\x151)H\xccg%X\x90bF\x18\xc3S\xd3\xa9#\xdd\x16K[\xbbx\x08\xb3\xf4mK\xd9\xdd\xd3\xa5\xdf\x00<\xcf\xd7\x97\xbeZ\x87\xf6\xaa7\xde\xe7*\xff7\xa8c\xd3\x96\xbaC\xb3\xc6\xb5\x88#)\xb9K\xf34\xcc\xfd\xee\x0b\x16\xd1\x98n\x0f\x8a0+8\xd8\xfe\x8a\xbb\x86\xf1Wi\xaf#\xc8\xcai\xde\x9e*m\xae\x16|d\x1aG\xfd\x98\xddP\xab6\xac\\\x83\xb57\xb7\xbb\x1e\xd8\xae\xda\xaa\xa8\xb3u,h\xc3\x9f \x84%\xe5\x0c\xe6\x0e,\x06v`{\xbd\xefNv\xb6^_}\xe7}\x0c\xda\xbf\xb6\x93\x80|&\x11#p\xb8\x0b\xb7]\xd3lH\xe9\x87\xb9+\xf1\xc0\xae\x10I\xeb2\x02\xaag\x12\xee\xdaB\x18s\xe3\xb3\xbe\xc6\xf1\x0e\x9a\x07\x0e \xca\xe4\xef\x04~\x80]\xaf\xb9\xfb\x05\x17\xdbf)%\x03\xd7\x93\xad\xb9\xd6\"\n\x1d\xec\x83K\xda!\xe9H\x87\xca]\xdd\xd5\x8d\xaad\xd5Uk\x18bc\x1bV\x83\x1c\x10F\xae\\\xb3\xb6\xf0d0\x15\x97K\xd9\xf0\x9a\xb7\x8f\\W\x1f\xb6\x9a\xbd\x9a\xf2\x0bB\xe7y\xdc\xab\x9f_-\xb7U\xa6.\x9f\x84U\xc6\x18\xfb-\xc6\xd8\x9bU\x07\x80\xc3\x95\xe5J\xdat/\x8f\x87\xf0\xa8\xb9\xda\xfanh\xbc\xdf\xe8r\xc3oCR\xbc\xe1\x0bB=\x974\xd9\xb8\xbe\xe3\xe5Z\x97f>vGd\xd5}\x1d\xb9\x95\xc8\xab\x12\xb2~[O$\xd5)\xeak \x9e\x0c\xc8\xca,\xf8}\xd4n(U\x1b\x89\xfc\x968\xba\x97\xd0\xab]\xbfY)=d\xd3\xeav}\xa0W\xbe\xd031\x82xS\xb0!\x08g[\x15v\xb5\"\xd4 F\x99D\xeb\xa6\xdcoI\xe2\x1fe\x96\xd5.\xda\x85\xa1P\xcd\xb6r3\xf0(\xed\xcb\xfa\x8cK+\xee#\x1e\xa5!V\x97\x99I\xac.@\x1e\xa5\x1dQ\xdd\x006\xa5\xfbf\xc6\xdc\x99;\x1fn|\xb8\xee\xbe\xceku\xac\x11\xd8\xdd\xaa\xc5Qe\xe7\xd7\x8c\xaeSu\xd0\xe9\x9b\x02\xf9\xa0\xd7\xa3\xae\x0c2\xd3FS\x18\xda\xaf\xb5\x06j\x07o\x13:\x97\xaa6\xe5\x80\x91\x19+\xd1p>'Z\xe4\xd0\xab\xf4\xa1#W\x1f\x03b\x17|\x8ekP\x11\xd5\x9f\xaf5\xe3S\x1f\x04\xcd\xdeU\xe9\x8f\xdc;\x83E\xb2\xfe|m\x85\xb6o\xe7\xb0~\xb6\xfbpnt\xca\x80|\xe4c$%\xb4\xbd\xa5\xa1h\xae\x97#\xeeC\x1fe\x8b\xb3\xbaz\x0f\xc7\xc6\xfbg\xd9\x87\xfa\x8a\xb6\xf7\x94\x92S\x82~\x81*\xc4\\]\x02q\xe5\x01W\xd9G\x83\xee\xcf\xa05\x1a\xe5\xc6\xcc\xa0?\xd1\x89\xc6\x9a\x83\xbc\xd0\xd8\x08\xe5z\xda<\xed\xb7>\x8c\xfd\xc1\x13A\x06\xdf{\x81r\xc6+`N\xab\xf3YEl|5\xaflJ\xb7\xf2d\x0e\"\xf4\xab\xcfH\xf8]\xf4\xcc'\xf7\xa2\x10\x02\xe9\xf0\xd0\x07QZ\xfdD\x06\xce\xb2@=\xc6A1\x8c\xbf\xd32\\G\xe8\xd9\x03\xfb\x08C\xfb \xf6\xed\xff\xd5\xea2\xf4^\xcbZuC\xb9w\x94w\x8c\x1d\xfb\x11TPn\xc8\x9fz6\xee!'\xb1\x0d\x8a\x18\x83\x10F\x95i\x10\x9c\xe2x\x0e\xf3l\x9a\xccJ\xb6<\xf6\x85\xc5\xcb,\x06\xb8\x17yAM>\xd0\xe5\xc3\xfd\x10\xd7{\x92\xe7\xef\x04\xf5\x0b\x94O\xe4\x05\xfd\xf1n\xd8\x9a(e\xcd\xee\x00\xba\x02\xd4\xea\x8f\x9c\x0f\xa3\xdej!t\x1fV\xd8?R\x94\xca\x1cL\nK\x14}P\xe9\xeb}\x90]\xe8\xb0\x11\xff\xea5)\xa6>\x0f\x0c\xf2\x9e\xdd\xd8g\xe9\x83\xbc\xee\xb3\xbe\x1a\x93\xbc'^z\x02{8t\x8aU\xb8\x05^\xd0\xf7\x0eV\xc1\xdb\xdd[\xbb>\x96F\xdc\xd9[\xd6\x01z\xa0\x8a\x0e\xca\x11$\xf7F\x04\x86\x9d\xd9\xdc\x82\xbe\xa6\x07e><\x86\xca\x9ck\x192\xaf\xf0~\x17\x1a\x9f\xf0LST\xb4\x1e\xa93\xbc\xbe>&\xa1\xf1~\x80]ik\x90=J\x8f\xb4j\xef\xd5\xb13\x8e#\x9b\xban\xf7\xe0O\x0e\x95\x1b_\x96U\xb2\xc9&\xa8P\xb4\xeb\xee\xd1\xc2\xa7\xc1-\x98\xb4\xfa\xee\xd1\xd0\xc1\xe0\x86\x0c:\x85U;\x1d\x0dh\xc6)M\xbd\x10\xa3\xfa\xe2\x90\xdeK\x04v\xef\xbbw\xa3JW\xf3|5\xa3\x92\xfcA\x8a \x03\x9b\xb4\xcaW\x8a\x81\x9c\xb0\x14E\xe7\xb89\xb2\x06\x9d,\x15\x9c2y\xc9\xe2\xd8\xc6\x08\xe2\xa4\x1eX\x0b\xa6\xcd\xc3r\xce\xc5\xac\xf8\xf30\x8f\x89q@\xa0\xe3y\xc3\xa5\x9aXq\x93\x11\xca\x03Y\x85JQI\xed\xb6Y\xf7NMi\xb7o^\xb7N,\xf3\x9ec\x99\x1ee^\x1d\xda-\xc2y\xe9)+\xab\x16\xc2@\x13\xa9c\x7f8\x98^'\xb2\xa3\x0c\xab\xe6\x0cf7\xf4{\x1f\xe3.\xbe\xffh\xfe\x19\xdb\xf7\x1b\x01\xa5\xb0\x80\xc7P\x90\xb0\xae\xca\x99\x98\x93\xdc0\x95&\xe5\xf0oD\x83\xbc\xd0\xd5c\xa1\xb8\x07T\x97\xd4\x9ah]\xba\xa1\x0d\x04\xd7y1\xa5N\xa4<\xac\x0c\xb8\x02p/Z\xd7\xc1\x8e}\xd0\xf7\x17\xf2i\xcd\x0e'\xfa>W\xf5\x93k\x1d\xff\x07Hj$\xdanH|\x8d:r\x06\x17<\xdc\xcc\xb1V\x1a\xc5\xf8\xcf\xce\xb6\x08K9\xd9Q\x02\x12\xaa\x11\xa2do\xe0\xd2\xde\x9f\xff\x81*\xa9lRz\x95R\x0d\xb3p\xf2\xaf\xd155\\\xa3\xa0\x99\xb2\xf4\xf1\xd2\xb9\xbd\x1f\x88\xd0\x85\xccU(y^y\x9d\xf7A\xb9T7\xe5#\xaa\xe5\xb5;\xbd\x97@x\xff\x83A\xac\x1a\xaa\xa0x\xa7\xd4\\\x8a\xdf\xb5\x7f\xb11\x1e7\xe5p\x95\x05M\x1f\nl\xcc\x8fP\xaa\x0b\x16!\x8d\xe6\xee\xf6\xffq'\xe1\xd6\xdf\xaf\xd8\x9f\x9d\xad\xd7\x9b\x1f\xb7\x82\xab\xef\xbc\xd1\xb6E\x0b\x97\xbb\xa0HJ\x19\x90\x80\xb1\xed\x1c\x92\xb3V\xd0\xc1\xd6)\xcb/P$\x8a\x14\x92\xef\xd6G\xe7Z\xac\x0f\x1f\x9e\xc33\xe6\x9ar^\xc3\xf6\xc1`h\xd47%\xa2s\x13gN\xe9\x12\xd54)]\x96\x8a\xb7\xac\xe3\xaa$\xf7\x90U\xb7\xdce\xf4\xd4)\x0d\xe9\xdd,zd\x8a\xc7\xa1S\xecF\x19-\x8d\x07\xdb\xe6Rp/z\xdf,M\x96\x03\x02\xcfJqj\xe5\xfa\xd1\xa0\x0b\x93\xa9\xeb\xd8\xc65\x7fm\xf7\xc4\x8c\xd6\xf61\xde#W\xf3> \x97\xda\xb6\xf9\xaf\xb7\x8d#\x8a5\x9c\xf8\xddp8\x98\xcf\xd4\xd7\x92p3\xf3\xa6W\xc2\x92\xd0\xd6+\xe7\xc7\xb9E\x12J\x80\xc7\x8b%\xbdC\xfb\x9f\x8az\xc6\xaf\x12N\xf1\x93\xb4\xa8\x92\x89\x9a\x16\xe0a\x18\xcd\xd5:M\x86S\x82O7\x7f\xc2\xb4\x0bi\x9c\xb5\x0c\x8b\x92\\\xe6\x95U\xd5\xc5\xf8\xf2\xfa\xe2\xf0\xa7\xf1I\xc3\x9c\xfa||q\xf6\xee\xe7\xf1\xd1\xf5\xc5\x87\x1f/\xcf\xc7\xc6oj\xda\xd9\xfb\xf1\xf9\xc1\xe5\xf1\xd9\xe9\xf5\xc9\xf8\xf2\xe0\xfa\xe7\x83w\x1fx\x99\xc3w\xe3\x83s\xf6~\x8c\xf9\xde\x1f\x9c\x1f\x9c\\(_\xce\xc7\xff\xbf\x0f\xe3\x8b\xcbF\xca\xc5\xfb\xb3\xd3\x0b^\xfc\xdd\xd9\x9f\x1aYXoO>\\\x1e\\\x8e\x8fZ\xe9\xedw\xa5\"S\x0fD\xdf\xc7'\xef/\x7f\xe5\xe9\xd7\xc7\xa7\x87\xef>\\\x1c\x9f\x9d\xaa\x19\xf0\x93\x9a\xf0\x9f\x17\xcd\x0c\x1f\xce\xdf\xa9\xaf\x17\xef\xc7\x876\x034\xd8\x83\x1b7s\x9f~\xaf\x93\x9d\xb9\xf8\xf2\xea\xb9\xfe%\x91e\x9e\xe9_B\xf1\xe5\xf9S\xfd\xcbJ\x96\xd9i\x15*\xc5\xa7g\xcf^\xe9\x9f\xd2\xea\xd3k\xfdS$\x9b\xfa\xdek\xd0\x8f\x1c&/\xfaT?%\xb6z\xc7\xe8\x8e\x82,\xd30\"\xee\xf6G\xba=\xf3\xc1\x01\xd0\xf1\x96\xcdkc\xad/\xd6Fsh/q\xdd>\x1f+3g\x8d\xaej\x9e\x1c\xcd\xbd\xf5-\xb6\xf9\xa7\x1d]\x18\xe0\x1c\xe0\x03j\xe9?\xb8\xf5\xdbok\x9d\xa1\x85\xde\xc5\xec\xe9\xc2\xf8\xa1]\xe0\x06\xf6\x88\x13\xcd\xbc\xb8! bO_>w\xf4\xc5\xcc\xa9q\x95?\x8b\x86\x9e8P,\xf7?x\xb4\x9f\x86\x0b2\x02K\xf0\xa8%?\n\xac*\x85I\xf9\x97E\xaa[\xfd\x00\x0crL\x80\xf3\xd6)\x89\xb4\x1b\x9b\xfe\x8b\xa6\x0f\x87o\x9d\x1c1\xb9\xddSS\xdcsjR\x12\x16?\xeb\xa7\xed\x83A\xfb\xf8A\xf3q\"\x14D\xdbj\x1c\x03\x96U\x9av\xa1\x91a\x1f)\xdb\xd3\xfd\xbf>\xa8\xfb}\xbb\xc1\xb2\x9c\x9f\xc8\xdd\x08tS\xbd\x87\xcc\x80\xb4\x1d\xfb\x1f:\x03\x1a\x1f{\xcf\x19`\xf0\xab\x10\x96\xdf2\xf6\xcb\xc7\x1d\xbbT{\xbe\x87\x0f\x10eD\x92r\xfe\x96\x01\x9d\xfc\xb7\x18PI\xe8}\xd9[\xdb\x80\x8e\xee= \xce\x9ew \\6^\x0bx\xca\xf1\x1ad\xc3\xb6\xf16\x89\xd9iEd\xbe4\xd9\xa5e\xaen\xd1\x19W\x05Z\xf4\xe5\\|\xda}\xd9\xfa\xb4\x96Ti\x9b\xcc]\x88O/_\xb4\xc8\xdcY\xf5\xa9Ej\xdfI\xc3R\x13\x93{c=\x14dh\x1e\xd51\x04\xe9v\x0ca%w\x1a\xf3xm`\x1e\xd0\x14Q\xfa\x9fA;\xc8\xe6\x18n\xdb\xfcG\xa3\xc8\xaaH\xb5\x12c\x03\x07\xd3(\xc2\x95\xa8\x1be>\x9b\xd8\xa0F!<\xd2\xb5R\x83\xb8\xabF-\x84\xf1\xc9\xbc\xae\xfa\xfaF\xab\xf5\xd0\xc2\xc7\xf1\x8a$\xf3l\xec\xd0'\x13O\xc8\xcb\x95\x84^\xcb\x8bt\xad\xd4\x81\x81\xb3T\x0b!\n\xd3\xca\x9cup\xa9uYq\xe9m\xa9\xe3\xbd\x81\xf3\xe5e\xd3|f)ca\xa0y1D\xb9\xb6Q\x9e\x18\x99\xf1fAS\x8b\xc7\x9d\xec\xbdZ\xbesi\xfe:@\x8a\xd0\x00\x95J\xccz\xbd 4\x14\x87j\xb3\xceS\x8b\xb4\xa2QOm\xde\xda({\xde#\x051\xd6q]r\x81\x8bV\xd7Q\x05\x0c\x95\x80\xc5a\xcb/e\xaa\x8d\xcc\xef\x86\xaa\xb8\xb9;>\xba\xa8\x16R\xc5J\xdc\xa6\x9bH\xab\\zS\xe8\xd3K\xfeV\x19:\xad9\xb8\xc5\xe7\x01\xe6,\xcdGLQe\x937J\x96\x8c\xdc\x99\x10)\x8a\xce\xea\xf8\x95\x9c027g \x85{R\x83\x1c\xd4\x1a\x16\x10\xc3@\xc0\x97/\x90\xb8\x18\xb0\n\xc1\xb6C\x87\xabD\x0bqF\xda\xb1i-\xda$\x1d{\xbez\"h\x91\\\xaa\xa0\x0c\xa7\xe4]\x1e\xc6\xc6h]j4=\xf3T\xf2\xa5a\xf4t\x9e\x8aX\xfb\xe8\xf1-\x0f2r\xcbx\xf6qq\x9fN\x9b\xa7\x8f=)Y\x93t\x042\xa0\x935\xdf\x82\x94e8c\xc4GP\x90\xb0\xcc;\xcc\xe4\xd2$\xc3|\x8b\xb0\xf8\xc4OQ\xf6+`\xc9\xa8\xdb[\xbfmb\xe4 .:\xb3\xcck{\xf2l[\x05\x03\x1d)\xde6\xf7\xc0Uba\x85\xb0\x0f\xce*\xe3\"et\xf2\xc1\xb6VTo\xad\xd0\xe3&\xe0M\xd1\x88\x1bz\xec\xd0\x1fH#}0\xc4\x95\xfb[\xa5\xbf\xa5Hf; a0\xecM\xab\x86d\xe5\x85\xa8\x7f\x7fBus6`\x8f\x82t\x83\xde\xbbO\xa1\xf2\xff2\xed\x00\x8a\x15\xecA\x18L \x8d\xe6\xf6L%f\x12S\xd5\x01`\x98\xed\xe0\xc2\xc0\xe3\xc8'\xaaD\xb2\xb8\xfa)\xec\xc3?\xbe\xc2\x08R{\x91\xa9\xbcT\x14:\xc2f\xb5\xa0\x0fh, 7\xe6mXd\xdc\x91\x84\x98\xa2\xc6:7\xc2tB\x99d\x11\x81\xf5\xb3`w'\xd8\x810\x8b\xe16IS\xb8!P\x90E\xbe&1$\x19\xac\x9f\x07;\xc1\xce\x1bX\x95\x04,r~\x11\xd0s\xc3\xf1|\x0ep\xb6XW\x0c4\x18i>\xedRv\x8e10\xd9\"\x8fI*/ZN\xc2\xa8\xe8\x88*5\xc7\x12\xd5\xcdVO\xee5\xe6\x16C9\xce()\"\xb2\xa4y\x87R\xf5B\x94\xe0\x04\x8cR\xc42\xcaz\x95\xeb8?y\xe5i\xc1\xad\x9dG\xf0\xfb\xf6\xca%x\x1e\xac\x8a\xd4\xaa\xfe\xc5&\x8fq\x15\x11\x83\x88wIFNW\x8b\x1bR\xbc\xcd\x0b\xb4\xcf\xdb\xb7}h\x86\xdd0\x84\xc2\x90\xcf]\xd5\xcd\x0bZ\xd8\\w\xcb\x1b\xb7\x0eT\x8f[\xca\xe8cH>\xac\x8dN3\xe4\x9b\xb0$Gyd\xe5\x1dA\xb8\x00mB\xc8\x08b{\xf6&x\x8c\xa0c\xd3\xb7ac\x04\xeb\xae\xec-\xc0\x18\xc1\xc2\x98\xfd\xab\x17\xd09\xc9\x06\xe8WA\xe3\x8e\x95M\x98\xbd\x03\xec\xe1\xf6\xad\xfc\x1a\xd6\xae*\x9eL\xc1Mz \x0c\xa8$\x02\x0e\xba\xf3\xcf\xcc$\x06\x082\xa3y\xfb\x9f\xe1\x1do\xa6(\xd6t\x0d\x11T\xe5\xbc\x81\xda\x9a\xeac%K\x08?\xcf\xd9\xa4LWi*\xb6\xc8\xcc\xbd\xf3\x95\x14i\x15\xc0\xd2\x96\xdc\xc8\xb5\x91\xbd~ \xfe\x9a'\x99\xeb\x04\x8eZ\x04)\x15FU\xcb\xd8\x93$\xa0\xdcE\x9b\x9c7\x1f\xb5s\x84\x8b iu\xccr\x9a\xef\x93\x89\x0f\x8e kz\xa3?\xcb\xa7\x11\xcf\xaa#\x10\xa8\xfa\x08\xb9! Dc\xbd\x85\x86X\x01\xda\xa1\x8e= #\x13/qV\xc6E\xf1#j\x99\xe4\xdf`9XhWfvS\xaaVr\xcb\xfc`r\xa5\x1dGo\x85>\xda\xa2&\xc6\xd8kZ\xbf\x96\x15Y\xcdh\xc7\nh\x81X\x03\xdfQ5b\xa8\x0f!\x0f\x80\xe2C\xec\xc3\xdc\x87\xb5\x0f\x0b\x1f*k\xdf[\x1f\xc6V\x85\xa1\xba\xed\xdbb\xd0\x86\xc1p\x0bo\xdexP\xde&\x9c\xca\x0f\x96\x05F\xfc\xe2\xc1\xd0\xbb6Z\x14\x96\x04vF\xddk;\xe5\xe7\xd7\xdf\x82\xf2\xae\xa4d1d\xe3\x12\x19\x8c\xf1y7\xdc\xb0\xe7\xa6 a;\x92\x9a\xfa\xd8\xc1\x05lH\xc2\x89\xc9\x8d\x00\x1e\xe9\x05`\x04q\x9e\xfd\x9e\xc2<\\\x13\x08\x81\x0f\x06h.\x0c`\x08\xe4\x99\x0f\xe1M^\xd0$\x9b\x05\xdcaQxS\xac\x96h\xe2\xc1\xda\xb0\x05\x07\x069\x93\xcf\xfbg2\xd3yQ\xc1\xc6\x92\xa2\xa8)d\xc1\xb1N3\x1fi\xe2\xbc\xa2\xf2\xf8P8\xef\x97#E\xaaS\x9e\xa1\xa4\xfc\xade\xee9\x04\x94\xd6\"R\xe8`\xacK\x0dw\xf3\xb6\x87U\x1eb\xe8\xd4\x14\x91\xf0\x12\x91\xf0\xa2\x1fh\xe1\x1bp\xb0\xe9\xf9\x16\xbclz\x86\xe0j\xd3S)\x14\x8au{\xeaw\x99\x1b\x9a\x1el\xf9\xe9\x83[\x0e9\x91K2\xea\x0b\xb6\xbc \xe5*\xa5'\xe1\xd2\x17\xbc5\x83\xf2_\x12:?\xe4\x0e=%\xcaV\xa0\xed\xa5\x0f\x89\x9b\xe2\xf9z\xbfi\x93O\xc5tL9\x1f6\x8c\x96\xd2\x1f\x13[r\xf7\xb0\xaat\x96\xe5\xe6a\xd5\x98\xd8\x19\x83\xa2\xd2\x90\xc7\xc8\xea\xdc\xde\xbb\xaa>bQ\x7f\x10\xbc^>\x18\xbc\"\x05\xbc\x96\x88x9\x9f\xc4\x8f\xba\x88sWP\x04a\x9a\xe2 R\xba\x1e\xf7f\x86\x8c\xcc\x10n\xc9\xf6\x0c\xe4\xa2lO\x9b\xbbZ\"w\xb5\xd4\xcc\x16\\.\xa1\xb8?\xfbdz*l`b\xa0\xe6\xee\xfa\x7f\x1b\x03ez\x1e\xc2T\x99\x9e{3Z\xa6\xa7\x9f\xf92=\xa8Pm`\xba\x16\xd2\xbd\xf6\xac>WW\x885\xe3\xf6\x87\xb4\xfa\xd0\xa2\x83\x1e:\xbd\x15f\xef\x94\x10u=\x96\xa3`\x04\xf6\x08\xf0\xb6\xe7A\x88h\xf7\xfb\xfba\",\xe4\x90,v\xeeW\x0e\xd4\xcdX\xd2|i\xf1\x91cz\xba\xa9g\xf9|\xc5\xe8\xf1&G\xb6\xc6\xdc6\xc9\xa4\xfa\xb4\xae\xf0z|)\xa8O5Xs\xd0\xcf\xde:\xba\x07\xfd\x95Q\xc3\xab\x8an\x13\xb8d\x00bW \xd6\x9d\x9a\x9c\x0d\xbb\x93\xab\xcac\xcfR\x9a\xd0\x074\xff\xcf\x8b!D\x84\x15\x9c\xa7\x8a\xc8X\xd4\xd6=\xc0\xae\xf5\xe1\x90\xdb\xc3~\x8e\x95\x83\x92{-\xafxz\x1f\xaf\x8dx0\x10I&>\xed\x06\x07\xe4\xf1\xfaz\xf4\xba\xbbG5c\xf1\x1aO\x87\x1d\xec!^V\xba\xbb\xbb\x9e\xafK\xfe\x02j\xbb{\x80\x8aL\xed\xa1Sc\xb3\xa1\x83\xcb\xc6>\xae \xd3\xdef\x9e\xd9\x9b\x19\x8a\x11\x86\xec\xfe6\xd0\xab\xbb\xda\x87\x89\xb1\xd4\x841j\xbb\xaf\xafZ\x1f\xaf\xda\x0e2\xe0\xd9\xf7\x0d\x9d{\xab\xb5\xc77^\xec\xffM\xc6\xc1\xf4+\xa8\x03\x0cC\xfaV\xf7LX\xbd}m\xdb\x02\xdc\xd3\x11x\x8fJ\xdcy{\xff~\x8b\x8e\x9fT\xd8l\xaf\x99m\x80\xfe\x10\xdb\x1c+o\xfdO\x1a\xdd\xc4\xe2\xc0F\x0cO\xc5\x83\xf7\x1bi\xcb0\xe9[\xd6\xee\xf0A\xa3\xab\xb4\xa5\xcdC\xe4.\xc1\xef\xbd\x84]\xf6X\xdf\xae'\x7f\xf1\xcf\x18\xe9#\x98\x13\xf0\xb058\xea\x9f\x85\xe9\xc2\xf0iS\xb7v\xd3\xbc\xed\xc1j\xae\x03&\xa5_=\xd7\xfc\xb9`'\xb6\xc9\xcd\x81e\xc9>uAK\xc3\xb8\xef\xbf\xe7h\xffv\xaf\xd1\x1e\xf4\x8c\xb6e\xe0\xf8\xbfa\xd0g]\x83n\x18y\xf6\x1e\x9c\x1d\xe34\x8c\x857\xff\xbe\xab\xf9\x96\xd9io\x17\x86*\xe5\xd9Tn\x8aa*{\xf9P\x95\xbd\x95&\xeb6\xe7\x12\xf1\x06\xc3\xf2YOu)\x12\x96\x0c<\x18\xca3\xe7\xe1r$qW`\xcc1\xc5\x1c\x95\x8e\xa8\x05m\xc2\x1e\xacl\x9c\xc1\xfd\xb4S\xac\x9a)\xe6\xec3\xbc0\xe0\xacD\x9b|M\xa6\xe0\xce\xe0\xc9\x13\x98)\xa1\xc7\xf4w)y\xd2\x93\x85{\xd2~\xf1\x93\xa4iY\x0d\x1bBK\x86{\xc7\xaa\xcf\x89\xf6\x1e3\x98\xa5w\xc6\x0b\xcf;\x1d\x07\xb9\x93\xd4\x87\xe8\x8am\x84\x8c\xad6\xd2X^\x17\x9bJ\xd4)\xd9k\xbe~\xf9b\x8d\x1f\x00\xca\xd6P\xcbLx\xc3\x1d\x1e\x0c\xdd\x0dt\x0e\x8e\xa1\xfcv\x84\x8b\xa52\xf9;w\xda\xe1\x9a\xea\x82=p\x0c\xbe\x97\xc0\xcc#\xa0H\x07\x83\xc8}\xa6\x1f\xaa\xc8Lq-\xfa\x91\xcaH\x01\xcd/\xd0\x12\x96\xb1\xcf\x02<*\x00?\x8eQ\xc8\xa7\xbe\xefi\xdfG\xbcP\xca\xfeD\xa2\xf3\xcd\xfcY\x90/\x8fcw\xc6\xefc<\xd4)\xe5d\x96k]\x136\xa97\xb0\x07)l\x823r`\x13\"\xf3\\2v\xb6\xe0\xb1>\xca\xa0D\x1c@\xe2\x0bLro\x90ko%w\xe8_]\x8bjX\xbe\x9f\xc3\" oR\xd2\xa5\n\x05\x18,\x9d\xe5\x1eU=\xe9\x96\x08\xb0\xa5,\x97aDFpc\xcd\xf8\xb5_\xbap\xfb\x08=\xedo\xbf{\xce\xabv+\xf7>\x15t]{\x12\x91\xec\xc35\x8c\xe0\xd6G5^=R\x1d\x0e\xa2\x9d\xec\"\xa0\xf0\"\xad\xa8u\xa2L+\x9d\x17B\x87!\xdfm\x7f\xe7\xd8\x17y\xac\xb6\xfac\x1es\x9c\xc4\x8b\x9bK\xb1\xc1\xdd\x05I\xf9\x9f\x17g\xa7\\0\xed\xb9cT\x8cW\xab\x81=`\x19\xb86\xbc;\xf6F0f\xfba\x8csi\xc8<\x16\x93\x0c\xa3\xf6\xa7\xf6\x86n\xa5\xb0\xa1|\x163\xaf\xb8\x01\xf9\x07z\xe6m\x8f\xe33\xee\xc4\x9bU\x92J2\xcc\xfd\xec\xf9P(\xc4\xa8\xab\x1c\x90\xf5A\x08\x9f\x0d\xb5\x11\xc3\x11\xa6R\x19\xbd\xfeq\xd7\x0d!\xe0\x84\xea*:\xea\x93\x9bG\x99u\xab0\x16m\xc2\xd32\xc0\xbc\xe1\x9bD>_U\xf8k\x0e\xd3p\x97\xcc\xc6u\x01{p\x14R\x12d\xf9mG\xa8\x9bLRg.\xd1\xd5\x05\xad\xd3F\x83x\xc5Qj\xa3\x0d\xd8\x82\x8bj\x0dyO-c4\xa8O}\xf5\x84\xa0\xad\xbfyuJ{\x1a\xea8c\xb9\xf6F\xd7}\x0b)\n.^\x98\xab~m\xccg\x9ei@\x8d$\x0b\xafI\xdan{\xf4aK\xf5\x04\x83\xa3\xaf\x1d\xab\xa3\xaf\x9d\xa6\xa3\xaf\x9d+T\xe37P\xef\x15%\xda\xfe\x96uR\xa0\x89\xd8\x07\xb9b\x9e\xc3}\xfeP\x0c1\xc9\xcb9Wf\x1fi\xdd\xa4\x9bT\xd2$\xc14\xebR\x9a\x0f+}\xd5\x01\xf4;\xe9\xe7\x07\xca\xea\xf6\xdf\x16\xa5\xce\xed>\x0c\xb9\xfa\x80\xe6\x1d\x8b_K\xd8\xa9\xfc\xb0\x1d_W8x\xednl\x8a\xf7\xc9\xed\x03\xcb\xce\x08D\xa6\xa3\xca\x9c\x9d\xd1J\xdb\x9f\x17\xe9v\x12P\x86\xac\xa6\x96N\xccq\x00\x15\x81\xd8\xe8\xbe\x0f\xb1\xfd\xec\x16\x80\xb0\xd2\xb8C\xd4},\x9a\xb85\xb1md\xa1\xfcm\xd1\xbf\xe7\x8a\xdf\x96\xa5\x96\xd8\xa2\xdfb\xd8V^\x92\xc4V\xednS,\xdc\xa9\xa5\xab\xc2\xb4\xd9b\x9fa\x0c\x97\xbb4\xa0\x1c+\xce\xc1_=\xce\xa8H@>/\xf3\x02\xfd>7\xe7\xbb\xb2\xf1\xcd\xdc\x97\xcf\x9ej\x90P\xdb\x087\xbdO\x19\x9b\xb4\xb57@,\x89\x91]\\n\x00\x12f\x11\xbaUD\nKA\x80\xe8\x11\xb4\x80$\x03\xe2\x01\xde\xea\x03\x9b,T\xb4p\xd1\x1f\xeb\x08\x92,\xca\x8b\x82D\x14\x92l\x9ds\x07x\x1b\x16W\x8e\xe4~3hv\xe7U\xd9(\xb9\xaf\x9f+\xcdT\xc3\x0f\xa6CD\"\x19\xb9\x1d\x805Y\x8f\xda{\x8d\xd15\xc1\xb2\xc8\x17 \x8a4YUdX\x9096\xe9\xca\xfcRm\xbe\xb3\xf6,;?\x861\xbc\x17mEyV\xd2b\xc50\xb3M\x97\x11O \x1f\x0f\x1b\x83\xbc\xd6\xf3y\xe7\xc5\x05*\xcb\x84\xbe\xe5D\"\xa3~1M\x0b.\xf3U\xb5;\x1c\xb4t\xf5\"}\xbfcZ\xa4\x01bB\xd4\xb0\xe3GW\x921\xd8D~\x9aLrv\x16\xe3\xbf=\xa0\xec\xdf\x08\nVG\xee\xe3\xeb\xbf\x04\xf2^>\xdf\xb5\x8c\xaax\x8c\xea_\xbd\xb0\xd4\xce@M\xd7g\"\x9f\x97i\x12%t\x04\x13\xd6\xb1\xe7\x8c\xe0u_>\xff^\xfc\x7f\xe1\xa9\xdeP\x1f\xde\xbb\x0eJR\x99\x97\x17\xbb\x167\x93\xec\x9b\x8e\xea@\xd0=\x9a\xc7\xca`s\xeb\xea\xbb\x91\xb7\xef~\xdc\xfe\xb8\xed\xed\xbb\x93\x8f\x17\x1fK\x0c\xc9\xd9.\x1eb\xf1\xc9\xc1\xd6\xff\x1f+\xe0\xffw\xb6^on\x05W\xdf\x8dX\x05\xdb\xedB\x8c|\xb1\\\xad:\xff\x86\x9e#\xc3r\xae\x87\xf3\xae\xb3\xec\xb3,\x7f[\x91\xe2\xce\x9eg[\xfatDG\xca\xd6l\x7fd\xd9\xc2\x15\x92x\xbb\xb6\\\xa7\xe1)\xeb\x13\x8fH.\xaf\x86w;\nl\x8f\xdc\x8f\xf1\xa6\xf7\xef\xdb\x18\xc8\xbch\x14\xebo\x04{\xac5\xd4*c\xa8\xa6}\xce\xc9\x87M\xe7\x08v\xcd-\xe3D\x8e`\xb7\xf5Q\xf5# \xaa\x9b\x8d\xd4\x8e\xaf3\xaepo\xb3\x94C\x015\xfa\x83s+\xc3m\x1a\xa4\xe2\xd4\xe2\xc2@\x8bp\xd5\xb9I\xf3\x9b\x91#d\x9e\xcb\"\xa7y\x94\xa7\x1e\x87{v\x96\xb8\xab\x8c\x94Q\xb8\x94\xbc\x13\x9bF\xcf7WH\xd2\x92\xe8\x8e\xea\xf6t\xf7\xd8\xf2A<\x981\x1cX\xb7E\xb0b\x1fJO\xeaz\x14\x93\xcc \x91\xac\x1bR-\x99\xad\xda\xd6uS\x84\xa1\xdb$\x03\x94\x90\xba\xacr6_\x93LG\xaf\xf2Ql\x14\x8a\xa0L\xc3rNP\xfc\xec\xd6o\x8c\xb0\xa5\x9cQ\x9f\x17dj\x8a\xfa\xd3J\x91\xbc\xe9\xef\x9a\xd9\xccp\x11u{;\xad\x02\xfaZ\x89g\xf3\xa4\xc8\xb5\x1e\x01\xe5\x0e\x9f\xd9\xbf\x80\xe6\xef\xf2[R\x1c\x86%A)\x8fc\xb1v\x17\xa3\x1f\xc1\xc6\x06\x9d<\xb5\xec\xbe\x82\x94\x94U\xff\xac\xbd\xd1\xf4+V\xf3\xd0\xa7\xb6C\x14*J\x8f\x1d\xf1*\xb17\xad\xbdPW0E\xcd\x82\x176\x83\xdc\xec\xa9\x94\x1a\xf7sn\xc1\xb0\x12\xc1\x91-\xdc\xcc\x02j\x97\xdd\xe6\x1c3\x96c\x9eX\xb8\x8a;\xd8\x83\x9dv\x7f\x10L+\x88f\x84\xd3\x02\xad\xf5\xe5f\xaaR\xb8=\x8e\x8f\xcb\xcf\x1d@s\"B \xfe\xb3Q\xf50\xabJ\xe4\\\xcc\xe7\xf1\x82)RH\xec\x9c\xdap\xd9q\x13\xb9\x84{.\xf6\xbc\n\x0f\xe0\x85H(A\xdd\x87Y\x03\xea\xe5\xef/_ \xe1\x1eu\x95\x8cU\x15\xc8\xf8\xc9\x17DL\xea\x9b\xe3\xf8\\l\xc1h7\xea7ku\xd7\x93\xa7l\x83N\xb6\xdd\xe0;o\xbbq\xf4xo\xe0\x0e~\x80\xb5\x10s\xbc\x81\xbb\xcdM\x0f\x91\xb5\xcbx\xd8\xf5\xe4\xee\xca\x9b\xec\\\xf9\xdc\x12{\xb2{\xe5C\xc9f\xa5\x84}\x98M\xe6\xb8\xef\x19|\xb7]j\xb2\x1c\xff\x8f\x1b\xa3,@\xfaX.=~\xc9\xe1dh\xfe\xa2f_\xb2>\xee\x83++\x15\xa0\xb3#tT\x95\xa4\x1861\xb7\x87A\x87\xb5\xfczf,\xcfs\xc6(\xfc\x15\xbb\x9c\xf7C\x14\x8eq\\z1\xdek\xcf\xf3\xe5@\xf1\x9f\\\xa5\xe5\xe4\xd9\x15\xae\x96Hd+\xb0\x9c<\xbfR\xebe\xff\x9a\xa8\xc0\xb0}8`\xcd\x02<\xe9\x90\x14\x12\xbf=\x84+\x15 @\xf1c?\xab\x8e\x91 \x9a\x87\xc5\x01uw\xc4\xdc\xea\xdfy\xef8GQ\x9f=\xa2\xd5*\xd3\x00?\x11\xa0\x92\xdd\x18\xe9\x0c9\x14g\xdb\xf1\x82r\x99&\xd4\xe5?\xe5\x0cn\xedz\xd2a5Q2x\xbep\"\xc1A\x8e\x1b\xbce\x93\x02\xb6\x18\xfd\xc1\xb7\xd2.7s\xdby\x03\xc5\xd6\xd6\x1b\x0f#{\xe0M\xd9\xa4\xb8B\xcf\x19\xac\xba\x08#\x13\xec\"~\x0d\x9a\x19\xdcf\x0e\x1fB\x06\xd6#\xee\xb7\xc3\xdd\xa9\x03Z\xb8 \xf7j\xe0C\xab\xc4\xd6V\xb7\x94\x19\xd7&\x0bVY9O\xa6\xd4u\x1c\xcf\xc7~\xb2\x89\xceq\xa9\x82\xea\xed\xcb\x17\xc8\xb8\x0e\x1cf\xcb\x84\xce\xfc\xb6)\xa2\x8a\xb2*\xbe\xbabl\xde\xd8\xb7\xbc\xa0*f\xe0\xfa\xa93\x19a\x97\xff\xe0\x85yf~{\xc8\xdeV%)\xc4b\xb36\xca\xf26/b\xfc\xcc\xbe2B\x13\xa7d\x89\xdf\xd9\xab\\\xb5Q\xab\xfcr\xb2S\x81}\xa3.\x86#\x04\x02d_\xf2\"\x99%\x19oP\xc1\x86\xa2\xbb\x88l\x93\x94\x8c*\x98\x95y\xf6\xd5\x97Mp\xb6\xb7\x1d\xd8\x94\xc5F\xe00|\x8dM3b\x01\xab\xaf/3\xb53Q}\x9b\xf2J\x85)B\x1b\xc4KBG\xbd\xac\xa7|\xf0\xe0\x13'\x94\x19R*\xeb\xaf\xae\x0bh\xae2\xca9\x86n\xa5\xd1\xdeX\x17\xd2\xdd\x84\x8b\xd4\xaa<\xa8x\xa0\x85d\x82\x17\xc9=\xe6_C4{9\xd7\xd0c\xee*Zc0K}H\x14p\xdd\x17~1\x12 \xb2I\x05\xb2\xd5\x95/\x0f(o\xc8Q\x8d\xc3\xe92\xd7\x84\xa1#\xa98\x9a\xa1\xa3I\xf8\x96\xe2\x13\xbd\xb9'\xba\xcbS\xd9$\xcb\x1e?\xc64#O7\xb4c\xdb\xa3\x8f\xf1\xe6\xbfos\x1a\x9a\xb2Yv\x85\xffxe\x0b'\x12!\xd0`\x99/\xdd\xaa\xc3bSS\x81\x96F\x8e\xa7\xcc\xbf\xfc\xa8\x14\x7f\x9c\xc9\x97 \xd17F\x95\x08\xa2\xcd\xf3\x94\xf5\xa9\xa6\xa56z\xa2N\x0f\xeb\x95\xa4\x8d\xfa\x94\xbcQ\x0c\xd0o\xf4=\xc8\xd6\x13\x0dW\xd9\xc4V\xad\x0b'3\xfbx\xe0\x8f\xc0\xf97\xcb\xb5\xb6\xfaHhP(\x82\x0da\x16\x1e\xb2M\x05&\xe5V\xf5\xf9*X\xc2\xc7@\x15R\x8c=\x08~\x8d\x99\xccF\x1f\x15\x05Rr\x02\xa1\x84\x1f`U\x91\xaf%;\xe7\xed\xf3\xcd\xca10ZM\xca\x0e\x0d\x9dT\xd2q\xc9$\x9d\xec^\xb1\x1e\x8a_\x1a5w\x8fnK\xa2\xa1>\x11\x93\xc6\x89\x98\x18O\xc4D=\x11\x13\xc3\x89\x98\xe8'b\"O\xc4\xa4\xa1\xde\xd3\x0e\xeei\xba\x9f\x14\x05F=\xb2o@\xd7vMNI\xf1\xa5\x8f\x04\x89\xf0\x8c\x84\xf5%\xd3\xbb\x0e\xcd\x1b\xca\xe5\xd1v>\x0f@\xc6\xc9\x95\xe3\xb7\xd0e\xd8%1s\x85\xdc\x04\x85<\x1c\xb7\x18\xa9\x88B\x07\x81\xb8;\xfa\xc4\xe3\xb4n\"\x1d)\xd0\xcb>\x9f\xf2\x91\x1d\xf9U\x97\xfc\x15\x9d\xc4 \xcc\xcd=%\x8d\x11\x7f\x15\xb9T}\xe7\xc7H\xfd\x05I\x7f\x96\xfeGG\xfe\xcc\xf8J\xf3\\\x92\x10\xcf\x87\x8d4X\xa6\xabY\x92\x95\x93\xec\xaa\x0biR\xb9\x86\xe35\xc9h)\xeby)\xeaQ\xab\xe9>5\xe4)G\x03\xb2\x167\xab\x1d\x1e\xad\x14D\x9fd\x10z\xb0r\xc3Iy\x85\xeb\\z\xb2\x17\xaf\x1c\x94;\x19<_\x82\x11\x17\xab\xd7\xb4\xed\x95\\\xd9h\xfe\x94w\xf94\\\x90\xa3\xa4\\\x864\x9a\x0b\xedd\xb6\x19\xcen\xb3\xcaP\x99{\xc9b]{\xed\xa0*BGY!8m\xceA\xad\x8f\xb1\x9c\x87%\x89\xcf\xc9,))\xd7q`uhS\xc6A\xcd\xb0|\xd5\xfc%l\xfe\xacR]\xaeS\xab\x0d\"\xf1<(\xdd|\x92\\\x89\xe9\xe8\xd9\xe9P\xa3?=\xae\xed\xefLy6HPh\xc3B\xfcR\xba\xed\x0f\xa2\x07>c\xd3;\x17\xaf\xb4/\x9e^'\xbfB/\x19\xf5\xc1\x17kwg\xa7\x02\xe7\x8e\xccH\x06\xb7s\x1c\x91%\xc9b\x92EI\x95M\x01\xf1Iv\x15\xc4J\x0ee\x10\xf2\x97\xa4K\x9a\xfd\x16\xfb\xaam\x95e\x83\xa7\xb6\xda\x91e,\xfd\x19\xd5!\xb5s/\xf3\xb2LnR\xd2\x82M\xe1\x01\xa0 \xa1\x19;\x9e\x10y\xbc\xc7\x11a\x8c\xc9>\"#\xafVf\x97\x9d\x81u0\xba\x8a\x83\xe7\x92&~0\xb0\x95\x0bu\xd6\xbf\xa7\x1b\xe5\x8fw\\)e\xc0M?\n\xa5,\xb2f.\x0e\xc3k\x11\xeb\x0e#m4\xd1G\xa7\xe6\xe2N\xc5\x8e!\x133\xeeI\x10\xadH\xb9\x93\x8b\xafr.\x9f\n\x9c\xc4\xf3\xe0\xad8\x17\x80\x0dD\x9fH\xa1\xf6L\xf4\x8c\x88 \xe6\xc0\xf66/p\xd2\x87\xce3 \xe2\x06T\xb7\xc7\x8flUk\x13V\x17\x16\xf6\x1d\xdc.\x84\xb2*\xb3[g]\x1b\xc3\x86\x8e\xbbNqn83\x08\x8f\xcb\xa7\x02)\xd4\xac1`^\xf9\xe0\xc9\xaeC@\xd1 V\xa0\x80\x96}\x96\xb2Iq\xd5\x01uP\x1f:b\xc2\xdbQ\x85\xe4\xd3u\xfe\xcaG\x92\xcd\xab4\xed\x82\xaa\xeb\x82\x94\xa4\xb1}Gv5Nh\x11[\xb9\xb8\xe4A\x8fg\xad\x8d\xc3\xe5\xe1\xe2\xb2\x94\x91]\xed\xe1Wd\x8e\xe4'\x8c\x97O\x12\x88\xedg~\x1f\x12\xa1\x1e\x0f\x9e\xdb\xde\xd7\xa2{\xd4\x88\x13$Yk]\xd6\x8evC\xbc>\xf6\xa0\xd0\xdb\x0d\xd5v\x8bI\xd8\xbc\x804j\xd9\xaa\xf4;_\xcf\x87S\xe9\xdc\xa3\xa2\x99VG/\xd0\xee\xd3\xdd\xa7\n\xdd+Hw\xf7\xb51\xfe\xc6\xaaC\xdd\xad\xa6\xb9P4\xfc\xe5\x0b8\xab\xecS\x96\xdff[\xb8\x8e\x9a\xf0\x85\x04\x11w\xe9p\x19\x163B\xf1biF\xe8i\x1e\x93\xb7E\xbe8\x16\xf7\xa8n\x81\x97\x84\xfb\x10\x06I\xb6\xce?\x91?\xad\xc2\"&\xf1a\x98\xa67a\xf4 }Cp\x7f\x99\xd8-\x82W\x14\xe6\xbcU\x16\xdf\xd0zc\xef4\xa9\x8a\xb6\xdeER\x8e\xb38)\xe7}\xf8X\xecK\x87\xe6\xcb\x93|U\x92\x0fK)\x94b\xd3C\xf3\xe5e\xbe\x8a\xe6\xe3,6%\x1f\xb2\xf1\xa7\xe2K\xd7\xb6N\xca\x93|M\x1e\xd0\x1dV\xcc\xd4\xb2\x92\xde\xdd\xee\x05\x0d\x0b\xfa\x80\x86\x8f\xf2\xdb\xcc\xd40\xd67\xa0e\xa1\x82{\x94\x14$\xa2\x129\xf4u\xa2>\x1c\xaf\xe5\xe9\xf8.))\xc9\x88M\x0b;k\xe6\x960i\xc0\x03M?T\x94\xd3\x10\x8cXx\xe6\x18\xa1\x8dA\xb4\x19\xde3\xcf\x18\x18\x18\x14\xfc\xc4\nS\x97\xd83J\x95<#\x90\xfb\xc6 0}\xac\xc6[},\x06-\n/M\xca\xe36\x95j\xb9\x16]WV\x80C\x97\xa6\x18\xbc4\xec\x9c\xd5\x9d0w\xe8\x01I4\xb6\xf3\x06r\xf8\xa1v\xd5\xfc\xe4 l\x90 )\x19b\x0fg\\[\x9e\xe6\xcb%\x89]\xef\x0d\xe4\x9b\x9b^\x8d\x1d'\xf9\x95\x0fE[U\x12\xa4\xc2\x10^X7\x90\xa9!\xe3\x03W\xe9!K\xc4Fr@/\x8b\xd5`J\xbe_\xbay\xff\xed\x06\xf7\xdar`\\[\xdaI\xbc)\x84!\xbf\x19\x87\x1f\x1a7\x7f\x1d+\\lnv;\x18B\x8azR\\\xb1Ue\xe4\x9f\xa2\xfd3)\xdajG\xa0\xdc\x15\xa0\x87\xe0'O\xd8\xa6\xe6\xc1\xb3e\xc1n!\xa9\xbe\xd8Xe\x97\xfaU\xe7\xde\xee\x847\xda\x05U\xf3\xb0\xac!\xaa\x0f\x80\x14\xf1E\xbb\xbd\xaeV0\x9e7\xef4C\x98\x0cq\x0el\xab\x08\x0ce\xf5@/\xed\xd6t\xd4|\x9f\xd6Zh\xbd\xbb\xb5\xa4<`k\x81\x0e#{\x91\xa5\xe4\x18\x82\xba\x14\xcf\xdb3\x9ew\xf9-Zw,\x16y\xf6\x90\xe6,U\x0cj\xfb}\xc8\xce\xa1{\xce$6\xd9,\xd93\x8f\xb4\x08\xd7\xa4(\xc9\xe5m\xfe\x9e1\x8c\xc3\x14\x11\xaa\xe6\xf4\xe2U\xa1!m\x8e3J\x8aw$\\\x1bZE\xd7\xe6FYu\xab\xed\xba\x1a\xadp'\xfc\xa0\\&\xc93\x93g\x0f\xfe\xf10_,\xf3\x8c\x11\x03\x05\xe9]\x00\x90'l\x1b\xbf\xb4Q7\xaf\x9fU{\xc9\xc7\x10\xa6C\xea\xcf\xcd\xf5\xff\xce\xfcfa\x8f8\xc6x8{\x042 U\x95\\\xf1:\xb9\x0dd\xcc\xb1\xaah\xcb\xa4\xa33j\x14kUQ\xa1\xc2\xc9\xee6\x86\x02\xe5^M\xe3FL\xccN\xcb\xca\xac\x9b}je/\x08\x1a\xca\x1c\x86\xab\xd9\x9c\n\xd7\xe1\x9d\xb2\x02v\x8aY\xcdr\xd6\xc2&\xd4\x12\x14\x86\xdb\xe4\x14\xf5Y\xf4\xadp\x91<\x1c.\xcc\x164&n\x97S7\x94\x13\xd7_\xbe\x00 \xca\"\x1a\xa7dA2|\xbfM\xb28\xbf}\xa3O+\xdb\xef4@\x9b\xaer\x99gq\x92\xcd>\x94D\x96\x93\xfaG\xd6\x1c\x9e\x0f\xcfxh\x9c \xcbc\x82F\xfd\xfb<\x8c\x1c\xc9\xf0\xe0i\xe8(|\xab5\x8e\xd0-t\x9f\xaa\x163y\x10\x85\xd9\x87\x92\x1c\x9d\x9dT\xe0\x1b\xe7\x11\x1a\xef\x06\xc9b\xc9{\xca/'\x9f<\xb1}\n\xe6a\xf9\x96\x84tUH\x7f'\x1b{\xd6z\x94\xcc\xae\xe3\xf8\xa8\x1d\xdc\x98\xd9\xed\xef\xbekB\xcdwp8'\xd1\xa7\x92Af\x98q\x81?$%\x94\xab%[_\x1e\xc0\x89\xce \x08.IP\xc7\xe82=['E\x9ea7\xb4J\xf56N\xcf.\xc7#\xb8\x9c'%\x8f\x0f\x95\xe5\x14n\xf3\xe2\x13\x08\xa3\xbd\xf4\x0e\xa9\xce,\xcf\xb6f\x8c\xc6I\"\xde\x13\xd6\x8fh\x0ea \xbf\xf1H\xca\xbf\xf9z\xd5\xbf\xa1\xb8\xee7\x1f~K\xf30f\xff\xd1\x08\xfc7\x1f\xa3Q\xfd\xc6\x1ds\xfc\xd6\xd7\xc1\x1f\xf3\xa2\xc8oK\x98\x16\xf9\x02N\xf2\x98\x14Y\xf2\xf7\xa2\xaf\xd4\x1f\xd1^\x14\xfe\xc1\xb5\x0f\xbe\xd6\xd7%\x17\xab\xe94\xf9\x0c(D\x84L\x98\xaf\xcf\x02p\xa24\x89>9z\xbdUE\xfb7y\x9e\x920chq\x89K\x8e\xab\xc3\x16\x07\xd7@$\xa2\x9c\xb7\xb1J\xed\x1a\xa51AU#c\\dE\xedenW\x90\xb036\x0b\xd3\xd6\x874\x89HV\x92z\x9a\xe0Y\xb0\x13\xec,\x0b\x02\xee\xe1\xaa\xa4\xf9\x02~\\%i\xec\xc1\x1789\xbe\xd4\xcao7\xde}\xbb-\x9e\x8eL\xd0~@\xddS_\xbe\xf0[\x82\x0d\xd7 \xe3\x18\xe7Z\xd2\xc8\x0e\x83Z\xb9GjVA\xbfY\x91\x1c\xb5\x93g\x0el\x9a\xfc`\xa1PP\xad\xecM\xbbOF\x92e-\xae\xa0\xab\x8d\x1a\x15$\xa4\x12=\xb9N\x9c\xacM\xea\x1daP\x12z@i\x91\xdc\xac(q3\x1f\x84\xb3\xe47\x8e\xd0\xfe7\xaa\xc2\x84\x93\xcc&2\x05\x85\x9d@Mb\xae\xbdr;'\x95\xd8\x0c\xa4~\xf2\x10\xac\xc2\xef\xe6\x03^\xde\x07\xe7Y\xb0\x83\xaa\xd6\xc9\xa3!\xd3\xd6\xd1}\x90\xd2\x118aJ\xffL\xee\xf4\x90\xbayF\x8b<\x1d\x81\x13\xd1\"m\x7f?!4\x1c\xa1\xdb\x82\xb0\xfd\xf1b\x9eLY\xcd\xa8W\xcd>\xd7C\xb0\xd0:\xb6\x03\x0e\x0dW\xb3\x90&k\x82\xf3\xd3\x86\x12\xf43v\x92\xc7\xc94!\xc5\x05\x0di}\x8d\xd4\xfe\xd4bO%\xa0\x16\xad\x1b\x83\x8aS\xc43dc\x83\xaa\x90PC\xc1\xb0\xf3\xbau\xcd\xf2\x08K\x99\xb9\xaf^\x1b\xd4_2\xf7e+=\xe1j1\xbb\xdcv\xf4\xd9k\xfc\xf7t\xf7\x95\x1e\xfd\x9a\x8b\xe4w\x9f\xeb\xe5W\x98\xfe\xec{\xb3X\xbe4b\x151d\x93h\x92S\x18\x93\xdd+!\\\xa7\xe8\xb5\xf8\"\xb9I\x93l\x86\x1eu\xa6IQ\xd2\xc3y\x92\xc6\x86)_\x8b\xab\xf6\xc4\xedc\xafH\x90d%)\xe8\x8fd\x9a\x17\xc2\xb1D]\xa1q0\x91\xad\xaeB\xd4\xc58\x0dQ_\x8b?3\xe94XM\xb7Z3\xb3ob\xdcl(07+\xeaTaK\xec\x840\x8fI\xa4\xcc\xb8]\xb8\x95\xba\xdc\xee\xba\xe0\xd7\xf7\xdc\x82\xbdCk4\xafh_\xf5\xd1\x88g\x1c\x1cZ$Q\xb4\xdaA\x91s:l2\x97\xd6\x03l\x88\x1c\xae\xba\xcf\x9d\xec\x1a\xee\xdfb\xac\x1b?\xef\\\xf1;v\x12\xf0`\x9b\x08\x89-\x0eK\x0355+\xed\x1eFl\x83\x89\x8e\xe5\xab\xc4\xef\xddK\x87|P\xcfR5\xfbZ\x0cc\xfc\xe6\x0861\xa3\x15\x8b|U\xa6w\xe7d\x99\x86\x11a$?\xe3\xe3N\xc2\xe2\xd3j\xd9DS\xeb\xb6k\x8c\x9e\xf2-\xef \x05\xcfuD\xd2d\x91P\x12_\x92\xcf\x03\x0d<\xe4\x84\x11\x8571K~\xf9\xbda\xe7\xb4\xe6\"\x1c\xe8>\x17\x9e\xa7n\xe1\xeb\x14\x08\xeb\x19\x8a\xf6\x18\xe4\xe4x=\x02\xfb\xe0\xae\xf0\xde\xcf\xf3!v\xf9u(E\xd5||\xeb\x95]-\x8b<\"e\xf9\x01=\x14\x97\x03\xc4e\x0d\xeb\xae\x9d7\x90)\"\xe67\x90\xd9u\xab+\xf0\xb2\xea\xabHS\x98\x02oXm\xf5@\xa5]\x7f|z1>\xbf\xbc>98\xff\xf3\x87\xf7=j\xf6\x88u\x0b\xe9\xd8\xc7\xe7GJ\x11\x84SJ\n6\xa7}\xd1\x0d\x06\xd9\x05\x9c\x9c\xfd<\xbe\x1e\xff\xe5\xf8\xe2\xf2\xf8\xf4O=\x1d\x9a\xf2\x0eL\x85\xb8\xf6\x9f\xd4\xa3\x8b\xf1\xc0\xf9 \x1b\xf3\xf3\x18M_\x8e\xffry}xvz9>\xbd\xeci|\xf5\xe8\x8d\x9f\x8fq-N\xcf\x8e\xc6=m/\x9b\xeb0T\xc9\xe9\x9e\xf2\x9a5\xa6>\x88\x1a\xb3{\x01\x9a\xd3\x05#\x9f\xe7\x94.G\xdb\xdb\xb7\xb7\xb7\xc1\xed\xb3 /f\xdb\xbb\xaf_\xbf\xde\xfe\xcc>kd\xf3\"\xa4s{\x99W\xdb'!\x9d\xe3\x9f\x93wZ\xc9r=3\x16{\xba\xb3\xb3\xb3]\xaeg\n\x01\xfe8C\xed%u\xd5\xe8\xe9\xb5\x0d\xf6\xc9\xc5\xc1r\xc9\x10(\xfe@S\xde\x0f\x19\x0f~\x1f\x85\xe9[y>*\x94P%\x826\xaa\xbfvV\xd3\x1f\xd6N^L\xa9\xad\xb4aI\x17\xac\x8e\x1e\xdb\xdb\x8cQ\x8d=s_\xed\xbc4\xd0\xf1\x99\xfb\xf4\xc5+\xcf\xcd\xdc\x97\xdf{AR\xfe\x1c\xa6I\\\xc9\xe6\x1a\xb9CE\x19\xdee4\x7f{\x12nV\x94\xe6\x99\xd9\xaf_4'\xd1\xa7\x9b\xfc\xb3\xf9k\xb2\xc0\xf8\xfe\xa6O\xf3$\x8e\x89\xa5\xd2\"\x8c\x93\xdc\xf2\x89\xa0\xed\xa6\xe9S\xb9\xbaY$t\xd4\xd2L\xb6i \xe9\xeb\x8d\xe2\xee\x0dv\xc8\xe3\xa0H\xfc.\xc9>10\xac?`x\x04\x99\\\xb8\xce\xab\x97N\xaf\xae\xb2\xde\xcc\n\x95X]\xadR\xa9\x9f\xc8\x93\xf2\xec\x10\xe5mR\xc7\xfc\xd5\xab\x9ev\x0c\xdePZ\xed\x88Q\xf5\xb4\xf4\xba\xd1\x92\xfc\xc5\xc002\x9a\xd2\x8a\x88\x11Ch-P\x18f2\xa1\xa8\x93\x19N\xb8.\xd6\x15\x17N\xcb\xee\xf0\xb7\x82\x84\xf1Y\x96\xde\xf1\xb78)\xc3\x9b\x94\xc4\x8c\xbcb\xfd\x1f\xa1\xcb\n\xe1 \xeb\xd7|%\xc3\x83\xc6\x10\xc2o\xd8\xad\xdfX\xd2\x12h\x0e!\xa3y\x160MH\x1a\xc3mB\xe7\xf9\x8aB\x98\xc1o\xb2\xc1\xdf`\x1efqJ\x8a@\x91\x93\x16$\x8bI\x01!\xb0\x8el\xe5\xac'XC\x00\xc7\\\x90\xc7\xeb+\xe7\xf9*\x8d\xe1\x86\xc0bEY\x171\xd4\xfeo\xc22\x0e\xbd\xf7\xfd\x16\xc0\x19\x9d\x93\xe26)\x19\x99@(\x90\x84\xbd\xab\x1d\xc8\x0b\xf8M\x8e\xf8\xb7\xc0d2n\xd9~$~\xf8\xfc?\xe2\x94\x8b\xbe\xfc\xb7\x98\xf4C\xd1\x97\x7f\xd2\xb4\xcb\xd2#H\x026\xf3\xbf\xeb\xc8?\xb5\xda\x13-\xdb\x9b\x16u\xc8m|\n\xbf\xcb\x99\x11\x94q\xdb\xfc\xbf\xd3J\xb0\xe5\x08\xe95\x9b31\xa9\xdc\xff\"\xe4S\xf8\x8d[~m\x82\xf3[\xd0\x0ckh\x94]::m\x00\xa2Oq\x0b) \x18\xbc/\xf2%\x1aE\x0c\x83\xcc\xa62td\x03^6\xbe\xc8\xa4\n-%\x16\xd1\xa4\xb8b\xc74\xe7\x9a\x1c\x06\x88\x8e/\xee\xeb\xf2\x0e\xcb\xa9D\xf5\x89\x83\xe0\xcd%\xdb\x89\x0c\xfb\xc7\xba5\xedV\xdb\x99T\x99\xafP\xd5\xdeN\xde.u!\x81|zI\xd4&d\xcd\x08\xfdY\xc7\xbe\xa6.V\x9a5\xf5\xf1\xb5\x8f68(\xbc\xa8\x12\xff_\xf6\xfew\xbdm\x1cY\x18\xc4\xbf\xf7U\x94\xf9;\xa7\x0f9\xa6\x15\xc9v\x9cD\x89\xe3\xe3v\xdc\xd3\x997\x89sbg\xfa\x9d\x9f\xc6G\x0f-A\x16'\x12\xa9CRv<\x93\x9c\xeb\xd8o{\x0d{\x01\xfb\xec%\xed^\xc2>(\x00$\x08\x14H\xcaq\xf7\xf4\xec;\xfc\x90X\x04\x88?\x85B\xa1\xaaP\x7f\xc4_\"X\xf5\x8d\x15\xc4\xdf\xee\xfb\xc4\xa6=\x8d\xbd\xeb\xa7\xea\x11\xaa\x8d\x84\xd9a\xf5Z\x1f\x81|\xdd4\x06i)vVn\xc6V\xc1\xb7+$T\x94Ql\xd7/\xe4\xfd\xa9\x1c^m|M\xb3q\xb4\"\xab\xc8vJ\xf2{\xa4\xfd\x10\xce.*\xf8\x1aFI\x10?\x1c;\xd5!\xb1\x08\xe8\xfd\x12|\xa7\xe4\x18\xb7\xcc2\xfb\xe2\x1f*\xf5\x8c\xa9\xc4\xb1]\x88\xa0\xd2f\xa0\xda)cI\xa9\xd5\xa0k7Z\x95T\x15N\xab\xcb\xd26|UO\xe5\x98\xb4/b*\x90\xb3@\x92L\x96\xc8h\x18\xc4\\@\x06\x8f#\x8a\xc4M\xb6\xc1\xc1\xaa\xa7\x95<\xd0X\xf0\x0dv\x06\n\x0bd\xae\xd6\xca%\xabN\x83\xdd\xa6)\x0e\xb9\x8f\x95\x8a2q\x9f\x8e\xcc\x87\x16\x0du\x00\x8f\xb0\x0e\xfeQ\xf0}\x82\xdc*\xda\x1f\xa2\xa0Xa>9\xe5FB\x80N-\xa2\xa4\xba\x9a\xec\xdbwFZl\xb1\x9a\xcf{i\x16#\xec\xc2\xedZE\xadV\xd1z\xff)\xa1\xfb\x89\xdd!%\xb2q\xdc\xa8cjW\x84\x87\x90\xb4\x10\x15\xe1\x04\xc4\x0fg\xcf\x9aK\x08*\x00#\xcd\x8a\xf89\x06Q\xb2\x071\x03\x7f+\xab\xdc\xb3G\x91H\x99\xb9\x95\xfal\xc4\x7f\xa1\xaa\x1e\xffp\xdf\xf8\x96\xd06\xd6\xef^\xc8\xd9y\xc1\x15\x9c\xeb\x0b\xb75\x10\x7f\x132\xa6^\xb7\xd0\xea\x12\x17\x8b\x18\x81'\xab\xaca\x85\xbd\x94\xbd\xceU\xd0I\xd7=\xb7B\x1e\x12b\xf5\x10\x91\x88wUl5\xfe\xe6\xa8^%\xb6\xaa\xc40\x84Z\xfcG\xbc\x8dV\xe9\x9a\xd1T\x07\xff\xc4\x97\x9f\xd8\x9d|\xf7\x89\xdd=\xc4Z\xd17\xcb\"Tf\x1bAV\xac/M\xaa\xbdCo\x08\xdea\xdf\x11y\xd1\x1bb\xf1\xae\x9d\xba\x9bH\xf8\xa3\x80\xfd/\x9c9\xf6=4J\x08\x14u\xf7\x1f\x8d\x0e\x87\x97\x8f\xae\xc3\x0e\xe7\x87\xbaZ\x1e1\"\x96c\xa3._\xc5\x0f\xfdV\xa0\xf4q\xda.\xa0\x1c\xee\xf2\xe2\xe1&@\x11\xe0\xf0U\x8466\xea\xa3\xb7)\x87\x95\xf8\x8dQ1Y/__ D\xf4w\x05\x83S\xbd\x18\x04\x81\x06M\xff\xb0\xff\xe5p7xx\x80V\xf8J\xd3\x8a\x07 \xce\xec\xe2\x8a\xf6\x0fP\x916\x18\xec\x9a\xd7\xe6\xf2z]\xde\xab\xef\xef\x05\x9d=\xda\"BN\xec\xb1\xe4\xbf\xd6l\xcd\x04\xdfP\x8f\xccm\xb7@h\xbbJ\xdb I\x94\x1a\xcf?\xfd\x14+\xe8C\x0csQ\xa9\xb8\xe4\x82\x8ah/z*B!\x11\x014\xb3\x8e@\x92\x04fF\x8a\x8e\xf2\xf7\x0b\xd8\xed\xe3\x95\xdb6x\xe0\xf3&\x86\xc0q5\x93a\xaeB\xf0\x02^\x16x\xa0g\xffs\x87\x16p\x9d\x1fh\xeb\xed\x1a^\xa2\x0e}\xad\x03\xbd\x01\xdb\xed?\xce\xdf\xa6\xeb\xa4h\x97\xa0\xd4R\xd1\xfd\x83n\x86RH3\x94\xdeXH\xfclZ\xdaT\xd77\x89!I d\xaa\xecr\xbb\x08\xed\x8b2\xd9k\xe9\xbc\x88U\xed\xe1\xa9mc\xaf-\x94\x9cEu\x84\xd2\xeeb\xbd\xf1\x8a\xa1\x95\xa9\xea,\x87#\xea\xad\x08\xbf\x88\"\x13\xf5\xcd!\x8c\x8a\xcb\x10\"\xebB\xbb\x11 \xaf\xa51^\x07\x11\x93\x91\x03%\xdej\x03\xa5\xbe)\x07\xda\xecM \x07\xfac\x9aM$-\xe8\x8aM\xf4bH\xe3\xder@Z\xc3(\x98\xf0\x11\x15fJ\x0crH\xf2\xe6\x1e-\xaa\xba!T3\x9aH#\xf4rd\xd8\xf0\x7f\xf0\x9e\x14\xac\xaa2\xbdo9l=\xc1\x82\xa6\xd4\x97\xbf|\x02\x99\x85\xf5_\xd5\x90\x17\x84\x9b\xa2a\xd2\x80\x86\xc9e \xf0\xb0\x0b0\xcfYA\x01\xd2\x05\xc5\xc4 E1[?\xa1\xc0\xf8\xe5\x0b\xd0\x05\x870\xba\x0c\x02\x85\xb0|\xd4\xa6{\"=jy\xe3\xe4\xd8=\x0e,\xa86\x8327\xc7h,\xac7\x96\xc9\x0e\xf9\xf9\xdb\xbe1\xcc\xe5\xec\x0093\xd6\x99.\xf7I]\xc0\xee\xae\x87#\xe7\x07\xea\x86l\xc77x\xc9'\xfe`/\xa0\xb8\x90\xbd}\x9a\x0b\xe1<\x86\xee\xaf\xa9\x8f#\xbd\xff8\xba\xdd\xed\xdeT\xc1\xdeP\x928I\xa7\x8c\x16j&\xf3(\xe3\xa5h/\xccP\x1b\xc0yI_(\xbaU)^M\x0d\x84?ARZ\x06\x0e\xf6\xf8\xde\x92\xc8P\xc0\xcbC\xd8\xdbE\xd5\xc1^\xa9[(`\x08\x1bJ\x9a\x15h\xad<\x15\xd2\xc5`\xf7)y\xdd\xbao\xde\xc2b\x98\xc7\x91`\xa1${si\xb0\xe3k8\x04u\x0d]\xe9V\xeaurB\xfbR\xaf\x81q\x0e\xcb \x80\xf5\xb2 \x86,\xa8+k\xec\xdb\x89\x85\x90\xeae\xde\xc3M\x97[\x18a\xf3\xf7\x18\xaa\x8b\x05|\xdfD\x8dJ\x0fdf,\xf2\x84\xe24\xa15\xe9\xd3\x0c\xe7\xa4\xd4Ex\xb5\x8c8\xa8$\xd2yO\x1a\xf7\xaam~X\x0f\xfe\x9e\xe8w\x01\xc2\x8eK\xf4\x94\x04\xbc\xea\xec\xbe\x08\xb5\xfb\xecI a\x8c>\x83j5\xcff!4\x82\xbe\x93\xbc\xa2\xf7\xe3\xcaJ\xd3\xb2eA&1\xd2a\xe7\xb3\xde\xd5]\xc1\xde\x08u\x12\xcd\xf8b6\x9a\"\xe8\xe5\xac\xf0\xc5\x0f\x0cb\xdd\xe6\xdec\x8e^\x05\x87\xc4\xf5\x9b\xc7yo*\xe6\xa5R \x0e!\xe2EJmm\x16\xba\xc1\xa0\x00\xaam\xfc\x01n\xf2G\xfa\xc6\xff\xef\xbe\xd8\xf8\xfa\xbeG\x94\xc4\xa8\x0b\xc5\xfc\x03\x9b\xac\xb3<\xc6$\x86\xebP\xf8r\xf1\xf7mWB\xb8w\x8d\x8dk\xedX\xc5\x95H\xaabs\xab\x9e\xa7|(\x84s\xb8f\x1c%\xe84z\xda\xce\xd2u\x82~\xbcY\x9a\x16\x8e\x9c\x98\xe6~\xc6I\xce\xa3\xfc\xa3BhmB\xc0\xec`\xf3q\x15\xc4\xb0\x99{\x16&B$fuq\x8e\x01\xcb{ \x94\xfe&u\xec\xc5c\x90\xfc\x1a\x14\xf4}\xe4\xc0\x02\x02\xd9\xd4\xf3\x95\xcc\\V^\x94\xb9\xc6\xa7\xae\xdbb\xdf\xb4u\xd5\x9f\x08\x15\xaar\xd4\xeeyjg|\xd4qV\xe9(\xb9l\x99\x18\xb9\xdb\xaa\xe4w_\xeb\xb2~3\xef^\xa2E\xa1\x19(;\"yH\xc3\x12\x91\x92\xbdL\xf9\xa9l\x9cD\x96,\xe1K\x89\xb9 \x12\xf9\x13\x0fl.\x89\xc8\xdfe.fyh\xf0wE\xc6\x98\xe5\xd8EN\x14\xcd\xb5Y]B\xf0q\xdbh{\xa3\xe8!w)l\xb1:\xc6\xd0\xa8d \xcb7Q\x08\xef\x83\xc7\xa6\xbeD\x08\xefOLY_\xba8\x0e\x1e\x93.\x8e\xcf\x06OZ%\xac\x86k\x04\xce\x06Q\x97\xc0\xbc\x81]G\x19\x17\xf2\xf7\x1ce\\\xc8\xdfw\x94q\xf1\xfe\xc0Q\xb6\x82Cx\x0c\xea:\x9cH\xa2<\x05y\xfd\xbd&iV9\xd9\"\xe4\xb4w\xde\xc8D\xdf\x84\xb0\x0c1\xd1\x1bnKL\xea\x96\xfa\xd7A\x08W\x98kv\x8d\xd9\xe4\xf6\x82\x10\xc6\xfcL\xf1\xef*6\xfbV\x90\x99S\xf4\x05?\x82)\xefo\xccE\xa4\\\xfd\xeaW\x06R\xcfa\x0c/\xe1\xf69\xdc\xba\xb6*\xdf\xa6\xfe\nc_p\xa2,\xa3\xe4/\xe1\x10\xae\xfc\x1b8\x84\xbb\xd1\xede\x08\xb7!\xf0\xc1\x99Z>\xb3\xa1$\x80\xd3\xd1-\xe7\xf5\x974\x11\xe1OI\xc5\x96A\xb7TA\xa0\x18\x9a\xbdf\xbf\x17\xd0\xcfjw\xff\xa0\x9a{\xdc\xb9\xb9\x9b\x0e\xad\x1dtn\xed\xb6Ck\xbb\xed\xad\x9d\ny\xe5\xc6\xbd$\xda\x891i\xe4\x7f\x14\n\xc3\x11\x17K\x86\x80\xd9\xf5&p\x04\x13\x18\xc2i\xad\xba\xe9\xeax/\xcd\xa9\x14\xdb\xc4a^j$\x8a\x10\xbc*\xd3\xb7g\xfa^H\xd3z\x9d\x0d\xe3T\x13Sv\xa5Y\xfcW\x95\xde\x1d\xcf\xdf\xf2\xe5\xf1\x04\xed\xca\xa4-\xda\x0fQ\x1eO\x8e\xd7\xc5\x9c%E\\\xa6bpV\xff1\xcd\x96\xef\xa3,Z\xe6F\xad\xd5jA~\xfe\xbeJ V\xf4V\x19;V\x05\xaf\x97\"!1\x16\x9c\x9c\xbd\xfb\xf1\xf5\xef?~8\x1d\x1f\x7f\xbc\xf8 _\xfd\xf1\xf8\xcd\xebW\xc7\x17\xa7\xf8\x83\xbf=\xfb\xf0\xfa\xff\x7f:>\xe3\x7f\xee\xe2\xcb\xf7\xb2\xbaU\xf0\xe6\xec\xf7g\x1f/\xea\x1f\xe2\xaf\xf3\x9f\xce~\xc6O\xc6\xef\xcf\xde\x7f|\x0f\x87\x8a(|W\x81T\x86\xcf\xf5\x13\x7f\xff\xb1yE\x9f\xca\x92\xdd=\xea\xf2\x1e\xbf\x19\x04\xb5C*\x9f\xa7\xb7\xaf\xf8\xa2\xc6\x1c4\x9d|\x9e\xecm_`\xea\xf9 A\xa1\xa3\xbbE\x1aM\x87\xcdbG\xb9\x16\xdf\xd2;A\xfe\xbb\xf5\xbeH\xaf\xd3u'V\xdf\xd5\xf5\xea\xbe]\x97\x13?\xe3\x7f\xed~\xcb\x18\xa6\xf7\x1d\xc3\x04\xa3=\xaf\x05\xe2\x7f\xcb\x08\xe6\xf7\x19A\x1d\xb1#\x85\xbe\xfdg&\xfe\xaee\xd1\x9ee\x96\x92\x0bV\xa7OZ\x9e\x10nEJn\x13&\x1e\x15\xf5\x92\x8a\x1c{zJ\xacv\xcf\xa26\x89\x89c'{|\xab\x8dW\xe9j\xbd\xf2\xec+\x8c:%\xf0J\xcc0\xaa\xae\xea\xf4\xc3\x13\xc8kT\x9ab\xcaK\x17\xf9\xf1V\x19\x1b\x97\xed\x8fSD=/\xa4\x89\x98gU4\xa0?\x17}i\xc4\xd0S\x17\x97\xd8\xa6E8\xbd\x12\xe1p\x10^\x8d\x1a9\xe8o+NV\x9c\x1c\xc5\x95\x94\xcay\xdcp\xc7X\xb3!\xe2m\xd1cY\xd6XKx\xd2\xf3\xc6\xe8\xf2H\xc4,K?\xb1\x84\xae ,\xa8\xa5[#]e!\xf2RM\xe6l\x19\xd15&\"\xc2E\xb4t\xf8\xfb\x8b\x9b\xb1kV\xf8\xdel\x91\xdeR\xe1\x82d\xc4\xf4uO\xe2x/\xbf\x8d\xae\xafY\xf6\xf1\xf5\x076\xc5\xb8\xcf\x822\x85\xe0E\xe51+t\x063\xcep\x88\x1c;\xbd\x84\xdd\xf2e;\xcd\xcc\xa4\xfe\xea\xe1\x8d\xbc\x9e\x92G\x04\x7f\xf2t\x9dM\xd8P\xe5\x90\xa7\xe1\xc1n\xd8b\x08\xdem\x94%qr\xed\xa8%%\xc1!x\n\x8f\xc4\x91\xbf\x8c\xee\xe0\x8a\xc1\x1a\xddgCXEy\xce\xa6\x90\xa3y\xc5m\x94\x83\x88\x0e\x86J\x8e\x9ce7,\x83\xf7F\x95\xe4\xdf\n\x89ml*\xc2|a\x1eRQ\x9b\xb0C\x0cB\x88z\x18J\x0c\xed+~M\x10a\xafm\x00\xf2\xfb!\xc4j\xdd\x03?\xa2<\x821\x13\x97qH5\x0c\xdf\no\xa8\x1e\xdc C\x88\x88.\\$U\xa7\n\x14\xaf\xf6\xeb\x92\x04\xd6\xb8\x11c\x11X\xc3\xb9\x11\x059(\x13\xab\x91u\xd62\x84\x87\x98\xa0\x9b$Tu.\xac\x8bt\xf5L\x84zu\x11\xb3\xa4x\xedhk\xa6\xd59g\x93\x8c92\x9b\xaf\x9c&\xba\xfc\xb9\xce\xa2\xa4\x18\x8b\xf3\xdfS\x03s`\x1e\x7f\xf2I\xca\xabrp\xa6+\x96K\xfbF |\x16\x01\xac+A\xf5\xa0\xc7\x9e\xa3l.}\x15\xcd\xf7JKy\xc5\xa5 A\xc0\x16p\x04\xf3^\x9dL\x1c\x82\x87\xf2\x06\x9a_\xf2\x1d\x92\xf7\xae\x8a4\n\xfc\xa8\xcc\xf8\xba\xc6\xbbM^\x96V\xbbgEy\x9d\xf3G-:\x89\xfc\xae\x8f\x14 \x87\xb0&\xe9\x8a\xcc\xc1[\xce\xc2\x9f\xa0\x06`*\x97s\x1cs\x08M\x82\x10f\xf5\xf79\xae3\xdf<\xe8\xba\xd5y\xf2\x93r\xf2\xb3\x00\xd3\xec\x99\xf2\x9b\x83&\\\xa5\xd3\xbb\xa1ji\x1d/\xa6\\8{\x15\x15Q\xe0\xaf\x1c\x8a\xcdu\xb6\x18\x8a\xe0\xce\xbe\x87T\xe3c\xb60Y\x0e\xf5\x08\xb8\xc6\x0eD`\xd1\x94e9\xc9\x96\xf2\x07AH\xb2\xcdPR3\xe2N\xdcI\xafB\xb7\xb0\xf9[\"U\xa9\xac\xc1w\xdf\xb7\x10\xb3f\xe2\xb2\xeeH\\l\x93b\xfd\xa9a\xe7\xb0\xcb\xce\xdc\x84\x8a\xd0\xc1\x00\xd4S#lr\xfbL26eI\x11G\x8b\xbc\x9d\xc4\xa5m\xb4\xcdI\xa3\x1eb{M\xee\xb3e6\xd9{r\x83\xb4\xec=\"r~\xc7\x0d\xe4\xd6\xe9\xb4\xdb\x00\xb98\xf3D\xba:\n\xc6\xf6c\xb6hV\n;m\x8f\xb3\xb2\x8fV!\xa1h\xe5\x1b\x8a\x96\xadVt\xd8j\xc57o\xb5\x1a\xbaG\xfa\xbe\x1bO8\xc7\xefF\xf7 f\x08(z\x13g\xd81\xac\xa5\x0e\xa6!8`\xa1\xd5\x12\xc7\xd4\x10\xd6\xee\x9aj\x11\xc7\xeb,\x1e\x12V\x04\xd0\xb8\xc3\xb2\x07\xd8af\xd2U\xf5\xb4\xef\xb0t\x93\x1df'\x9c\xbe\xd7\x0e\xa2\x95\xa8\xff\xdcJ\xb5\xe7a\xb6\xd2o\xe6\xd4\xfa\xbbm\xe3\xbf\xff\xe6\xbc\xff\xf1\xb7\xd9\xe6\xfc\xa5\x8e\xbf\xeaZ\xe4\xc1x\xc7\x99C\x13%\x90\xfe\x9a\x152\xeb\x1f]+\xef\xc6\x7f.:i\xcf\x84\x824\x8d\xf2\xbds\x0c\xae\x9e\xbaR\x15 \xbdh\xbeb\x93\x96\x8a\xabrx-\x15\xa7Ho8\xe68\x96\x0e\xcbQ6\xa0+\xdc\x94W2(}\xcd\xe1\x08\xfe\xf6\x15\x9cR\xc6\x12\xdb\x93\x08AW\xb9\xae\xb7\xb8T-.\xe9\xeaw-\xec\xf9\x95\xd05dD\xa4 \xfe\x8c[4\x97\xb7p\x08\xfeJ\xc3\x07\x1f\xad\xe2\xff\xf65\xe8E\xd3)\xde\x11E\x8b\xff\xe0\xf0\x11\xd6\xfa\x82-\xa3\xdb:%\xae\xaf\xf4\xb2Y/\xce\xcf\x8e\xcf\xf7\xfc\x80\xcb\xb0\xfd\x10\xa2J\xa0\xbe\na\xd2\x13\xb1\xf7\xd9\xf4\x1cul\xbe\xc8\xac\x0cC\xa2\xee\x8c\xcfXV\x08\xeb^\xe2\xbaU\xd1-\x1c\xd5\"\xf6\x89\xa6\xb2\xaa\xa9\xdb@\\\xa6\x9f\xca\xb4\xf4\x87`\x08\xfa\x7f\xfb\x1a\x82,\x0c\xe1\x96\xb2\xe3\xe3[\xee3\x1c\xc2i\xe9\xd1\xe0;\x88\xc89\xd1\xbc\x93\xa8\xf2\xf3|\x85a\xcc+\xd9\xf2\xd1_\xf24 \xa1`\x9f\x8bG\xabE\x14'!\xfc\xee\xd1\xef\x1a\xa8\xbcw\"\x82[\xee\\\xdc\xad\x98g4\xf6y\xe7\xf6\xf6vg\x96f\xcb\x9du\xb6` ?\n\xa6\xb6b\x13\x04\xb5\xba\xa6\\\xb3z3VL\xe6\x8eY }\xfd\xec\xd8'\x18\xd6i\x08\xde*\xcd\xcd\xdb\x0c\xf5\x94d\xf5\x9c.\x97\x12\xfd\x8dc_\xe0i\xe18\xf9e\x9c\x1bt\xf3\xe2`N\xb3!\xac\xfd\xa0g\xbfw}\x9f\xaf\xd2$gD\x03V\x81\xd5\xc0\xd7\xa0\xc7\xf92\xbf\x99[\x02\x8d+\xd3,KYo\xcaO<\xf7\x92#\xf5\x97.\x91B\x1b\xfd\xe5\x0bx\xaes\x0d\xd4\x15\x88\xfc\x02;9\xd5>\xa3\xed X/\xfd\x84\x0e\xcc_\xbe@\x06G\xb0hWw\x83\xa6\xf2v\xd0Z\xe8\xa8\xd2\x86\x8e\xeaqhP\x7f\x13\x16\x85\xa0T\xe0yG\x158\x94\x8c\xc1\xd8=\x00\xa9\n\xb7\xf9zP\xdd\xfd\x03\x00\x8f\xf5\xf2\"*\xd6\xf9\x05\xfb\xec\x9a\x08\x85\xe6\x98\xaai\x03<\xaf\xacQY\xa0l\xfch\x04D\xcb\xc5r\xb7\x89\x9b]\xf5K\xec\x90\x06\xae\xf9\xa6\x0c\x00P\xfb\xc4m\xf2C\xe7\xa6\xd2\x1f%\xdbh!M*\x17\xad#}\x03\x8bL\xa4\xcd\xe6E\x99\xdc\xb9\xc2sp\xfb\x10\xbc\x10\x98H\x16%\xc2\x04\xe0\x0ft\xee\xc5\xbf\xc6S\x96O\xb2x\x85b\x9e\xfe\x91\xf6\xbe\xf6\xa9\xfeA\x93m\x92\x96k\xcb\xf6\x0e\x02\xa0|\x86\x00\xfd\xec\x7f\xf3\x18\xbd\x01\x1a\xd7^\xfd\xf6l\xab\x10\xad\xfe\x14-\x17\x82\x81s\x99\x10\x95\x19\xa7\xc8\xe8\xbb\x98k*\x15!U\xeb&\x12Y\xb3\x89\x84\x91\xbb\xb6v\xb7o\x0d\xac\xd1\xd8\x94\xdedR\xea\x89\xab\x0bk\x0c\x87\x1cM-g\xea\xc6\xc4p\xb2\x19\x91\x0fT\x13X8\xa2^\xcc\xb3\xf46\xe1\xa8\xaa\xd3\x9f 4q\xfe\xb7\xb7\xf4\x8b4\x9a2a\xc8vq\xf6\xfb\xdf\xbf9\x1d\x0b\xeb\x8bs|\xf5\xf1\xfd\xab\xe3\x0b\xfdU3^\x98\x16\xc5\xbf\x14Z\xacUh\x86Flh\xb1=\"\xb4\x11\xa5\xed\x91q\xd2s\x0e\x9e\xd9 *PrH\x16\xe9\xf5\xf5\xe2\x9b\xcc\xd1\x08\xe5\xe5}\xac\xa1\x88e\x93\x064\xf9X@\x8ep\xc9&\x96\xbf\xfcH\xcc\xcc\xd3W\xa0D\x9br\xb2m\xba\x86\x1a\xfd\xbf\x07\xf6\x97\xafK;\xadL}D\x07AG\x03\xfd<\xc3\x8bmi\xae\xcf\x92\x9b\x9aA\x7f!\xcd\x17\x95\xc9?\x92\x1b\xe4e\x95}?\xe7\xbcr\xcd\xe0\x7f\x95\xe6\xc20[\xfdz\x1bq\xc1M\xf5%\xed\xb7e1\x9e\x9e\xd6Z\x90j\xe3\xf1U:\xbd\x1b#\xf6y\xb6,e5&\xb3T\x8d/\xfe\xf4\x9enN2Vx\xbfk4\x18\xd5\x1b<\x7f\x7f\xf6\xee\xfc\xb4\xa9E\xb1\xd3\x9b\x9a\\\xd7\xe1\xc5\xc14\xfe\xe3\xf1\x87\xd7\xc7?\xbc9%\xe6,\xa06\xbe\x91\x08/\xa7\x8d-\xde\xeb\xd8\xbf\xd1\x02\x95R1\xc2\x12\x7f\xb7O\xba\xc2\x0e\x1e\x9b\xf1\xad\x84/\xecc\xb3\xbap\x85}b\xbe\x16\xee$\xfb\x8f\xcd\xf0\xa8\x0b\xe19kjK&b,\xfbf\xf5\x99\x18\xcc\xb3\xc0\xf7\xe2\x82e\x11Fv\xaaWYq\xfe\xdf\x1f]b,\x14\x8c\x9c\x91p\x8e\x1a\xe2\x04\xe4K\xdf\xf4ui\x94\xd2@Sl\xcc\xe3\xbc\xbe-*\xc8:\xdd}Q\xfa\x9a\x87\xca\xd3\xd5l>\xf7\x13\xacdFQ\xe2+u\x17\xc2U\x08c\xe1\xea\xda\xae\xe0\xc50\x10\x98 \x0b\xf3R\x9c\x94\x9e\x8e'V~Z\xf5tr;\x15148\xe4\x1a\xf2\xad\x89J\x88\x9fM\xd5\x80\x96{\x1b\xebk\xdf$\xec\x16\x12\xe9\xa7\xee\xc8\xe7\xa6\x9eMT\xa9\x9b\x8c\xa8\xfbH\xec\xbe\x08\xf3\x13\xf4P\xc4\x10\xb5\xaf\x15B\xdb\x95>K\x07 \x0e[8<\xa4n\xe3\xce\x85\xd8k\xbd?\x11\xdc\x02\x1d#\x8e?\x9f\xe0\x10NF3\xcc\xfas2\xf2\xfe\xfd\xdf\xcb\x8d\x85\xafn8>\x9d\x8cn.\xed/\x8f\xe1\x10>\xa1\xc3\xb4\x7fC\xdc|\x9d\xc1!\xdc\xc0\x11|\x86#\xb8\xf5=\x96\x14Y\xccr/\x80!\x1c\x97~\xd9\xf6g\xe8\xd4\x85\xb1&\x84~\x1f\xfb\xef\xc9\xafyoF\x82@\x8e\xf5\xefQ\x1f?\x86C\x98\xf8\xefeT6v\x0b,\x08\x02\x8c\xe5i\x86\xbc\xe2\xd5\xc7\x98\xb3\x13?\\\xf8\xe3\x10N\xe55\xb7\xb8\x93S\xa8\xa0\xdf1\x8c%\x94\"^}\x16\xc24\x08B\xf8\xcc[\xc0\xbc_\xe5\x02\xf1\x1e?\x89X \xbc\xf5s\x19i\xf4\xb8#\x95\xf9T\x05c0\xb4i8\xba\xef\xbf\x87\xadk\x0c>\x8f[}\xeb\\,\x90\x1a\xda \x0e\xed8\x08a=*\xb8\xa8z\xcc\xff:\xe5\x7fMC |\xa49\xfc\xee\x9c\xf6ObNC\\D\xbej\xb7\xbe\x9a\xa6\xe3\xaeS\xc4Y^V\xd5\x91n8*\xcbU\x1d\xc2\x19\xb1U\xe0\x9a\xdeV(\xd8_I\x1f}\xfc\xff\x84O=\xe6S\xbf\n\xe1ntuI\\\xa8\xa2\x03x\xea\xa7\xbd\xf7\xb0\x0di\xefG\xf8\x1d\x08o\xff\xf3\x00\xe9\xef\x1d\x1d\x80e\xc3(\xf7\xfa)\xb0\x95\xf8\xfb\xfb\xa8\xd5\xddJ\xfc\xc7\x83\xc0\x9dQP\xf6\xf5\x04\xb6\x0e\x1d\x829?\x80\x0f\x02\x99\x9f>\x04/\xb2ds\x10\xc9w\x86\xedDL\xf5f\x83\xdc\xc0\xb6^\xe5\\!\xefg:\x07\xdaxLG\xc9|B\xe5\x85\xe1l\xc1^\xe0[9cd\xb0\x8d\x83A\xe0{\xafO\xc7\xef?\x9c]\x9cy\xf7\x0e\xb0\x11\"g\x92\x92\x894\x84\xc2\xd2z\xbdp\xc5M\xc3P\x82\xeb\x00\x12\x0ci\x89z{\x7f\x8d\xb0\xc0\xa8\x902\xc4/\xf1\xe1\xf32 \x0e\xbc\x84\xfcy \xbf\xe3G\xc0(\xdf\xde\xbe\x14f2\xff\x1d\xfb\x0bl\xed\xcb\x97\xaa5\x1a=\xcd\xa8\xe2\x9d\x17hw\x10\xf4T\nb\x1a\xa4\x99\xb8\x8fP\x95d\xd0\xdd\xcdzq\xa1\x01u\x0bb/\xb5\x8d\x0e&\x1d\xa7GN\x06\xd3\xac\x07\x8btj\xe4$\x8a\x08\xcdy\x8ca\xe8F\xf1%\x0c\xe9\x13\xc1\x0en\xaf\x07 \xad\x97\x1e\x19\x91\xef\xab\xc3hX\xffL\x86\x88:\x82\x08\x86T\xe4\xf8\xce\xd0\xdf\xdb#\xa0\x9f\x8d\xbc\xf1x\x92fl\xe7/\xf98\x9fG\x19\x9b\x8e\xc7\xe2\xa8\xf7]e\x87\xf0\xb7\xaf\xad\x1b\xcf\x01\xd2t$r8\xfa\xa9\xd0\x9c\xfe\xedk\xd02\x1f\x17=\xbd\x9fF\x91%\xeb%\xcb\xb8\xf04\x84-\x7f\x00\xdf\x03E\x01\x94\xf7\xb4\xaa\xb7\xeb\xa8w\x9b\xc5\x85\xaa\xb3\xef\xa8\xa3\x14#\xb5\x82o\xba\xd8\xa9Z.\xb7\xef\xfe\xe3\xc0\xdf\xd2\xb5\xd4\xfc\xddA\xe0\xcbh\xbf\xe0\x89?\xbc\xa6$\x1a\xa8g\x1e\x17p\x08\xd2\xa2\xaeT\xca\x8f\xe3\xfa\xcdG\xe8>U\xf8\x98\x98L}/\xda\xb3!Rj\xe0\xc71I\xc5\x12xyXQ\xc6#b\x15%L]<\xe34M\x98\x9d\xe0\x15\x86\x18\xcc\x0d2\x91\x7f\xa0\x9a\xdb\xf6a\x19V\x8f:Feg\x04\xaf,\xfb\x19\xd4\xfb\xd1\x10z\xc3cr0\xa0\x03R=\xde\xbb\xefv++4\x05\xd3\x8fC\x88\xc4y(\x17>\xf5\x0bS&V\x0f\x1e\x05~\xe2(\x15A\xa6]\xd1\xd2\xe4\x98rx\x01}\xe1\xd7\xfeR\xb8V28\x02\xcf+\x85\x00\xbeP1\xb6\xa4\x05/\xcc\x83\x00^\xc0\xe3\xc7\xbb\xcf\x0e\x90\xbd\x83\x97\xf0\xf8`o\xf0L4\xb4\x0d\x03\xe9\xa8\xc9iKd}\xcc+\x88\x06\x0e\xf6v\xb1\xf3\x887\xf0do\x7fO\xf6/\xeacG0\xc44H\xe2m\xbe\x88'\xcc\xcfC\xec\x04s\xd5D\xb0#\x9b\xd9\xe6\xe3\xdc\x91\x83z\xf1\x02\x06\xfd\x00\xb6\xe1\xe0\xf1\xe3\xbd\x83_v\xb7\x9b\xfa\x11\xa9\xab1\xb1G\x86-3\xe9\xbeT\xd5\x98\x1a\x9c\xb5\x0c\xf1a\x9e\xc6RWs@\xebj\x06\x96ng\"\xeb\x9b\x83\x94\xca\x9a'\xffT\xd6\x10\xcf?\x955\xfa\xf3Oe\x0d>\xffT\xd6\xfcSY\xf3Oe\xcd/\xa6\xacqjj\x06duw\x18\xd1\x03\xc7\xdd\xc9\xe3\xbe\x83o\xd3\xc2\xb3w\x12DQ\xfcL\xdb$\xa5\x0d\xf9\xca\xb7Q1\xef-\xa3\xcf6\xcf J\xe2\xa4\xc3 \xe9\x18\xb0d\xb4\x19\xf2\\}8\xe2b4l\x83\n\xc2\x19\xfb\xcc\x88\xc9\x0f\x1b\xac\x8f\x9e\xc8#4\xb2\x96\xc4\xb9\x9e1c%_\xbf\xceOK\xb9/,\xd27\xe9$Z0)\x1b\x95)Qpo\x9c\xcd\xbc^\xbeZ\xc4\x85\xef\x85\xde\x86\xec\xfb\xde\xde\xaf\xa2Dq\x04\xad\xdd\xa5\x95i\xc8o\xe5+6A\xfa}\x8f\x15\x95\xea\xb2H.hk\xca\x14\xcd\x13,\xc2CH\xfd\x16Q\x923?\nF\xf1e \x13\xef\xa4z\x92\xf3\xeeh-b\x17\x87J)h\xddR\n^v\xff\x89 \xab\\nL\x07/{`\xf2\xc4\x13Zs\xc2Y\xd9\x89\xca\xcdl\xb3\xb0\x93^\xce\x8a\xd7\xcb%\x9b\xc6Q\xc1l~u\xd2\x9b,X\x949j\xcc\xb1\xc6[a4\x7f2\x8f\x92\x84\x19~\x867X\xe3U\x9c\xaf\xa2bb\x98},m\xe5\xe55\x11\xca\xe7\xae\xed@CA\x1e\x0ea\x9b\x9fe6I\xe6'\xcf\xb5\x99:\x85\xce\x90\x01\x9a\xe1\xc5\xb5\x93\x9b\x95A\xd2x\x85\x10\n\x9f\xf0 \xa8\xbd1\xa6s\xd5\xcad\xdf\xc9\\ \xc2Q\xa5\xdeV5\"<\x96\xa7(D\xae\x1a\x9b\xac\xa5\xfd\x18]\n\xad\xed\xe09D\xd95n\xed\xbcR\xec&\xcf\x03\x95C\xa3,\x1d%\xdb\xdb\xe6I'\xf7\xcf\xf5h{{y\xd9\xb6\xd0\x02(\x7f\xe5\x0c&_\x87\x9b^\x92\xde\xb6\xb6\x86\xb5\x9c\x0d\xcd\xe1H(\x13|$\x93\xec\x16\xe6A\x8f\xd3\xbd\xdd\x10R\xfcc\xd0K\x93*\xb4\xf9\x95\x08T\x1f\xf9qo\x95\xe6\x85\xdc\x85Hk\x06\x18\xcfi\xd2\x8b\xa6\xd3\xd3\x1b\x96\x14o\xe2\xbc` C\x9aN.\x86\xd6\x00r{\x93^\xbc\xe4=\x9e\xa3\x17P\xceG\xd6<\xb5\x89>\x06<@=/\x04\xefw\xf54\x07\xf6\x88|ON\xc8C\xaejK\x8c\x1c]\xa5\xd2$c\xd1\xf4\x0e\x03\xee\x89p|(]/|O\xf8&a\xaa\x15\xf7\x88\xf2^\xb4Z\xb1d\x8a\xf9\xe8}\xed\xab\xa0g\xb7\xdc\x86\xc3y/c\xcb\xf4\x86\x89\xc6\x90g\x0e\xcb}\xea\xf4\x1c\x80\xa6\xcc\x959+.\xe2%K\xd7\x85\x86\x11\x9c\xe9\xa8\xbe\x0f\xeaF\xb3\xd6\xf7V\xa4Y\xa4\xd5C\x98VM\xe0_]\xb9\x15\xf7`\x1b\x9doh:\x8a\xeaF\x9a\x1f\xbf\x19\x02k'\x9b]\x1cv\xdc]\x13\"\x1f\xc8\xae\xdb:n\x81\xde\xa6\xec\xce\x13:D\xff\xe0I{V3G\x9e\x8f\x0cie\xea\x17vj8\x91\x90\xa8-\xb5q\xdc\x9b\xb9\xb2\xfe\xfa\xfd\x10\x92^\xc6\xf2tq\xc3\x02\x8cl\x8f\xa9\xfc\x96\xb1\x96\xdfjC\xc0X\x10\x10\x80yF+\x01\x91\x0dDg\x86v&\x90\xe2\x00\xe9|\xf3\x98\xc7\x8f\xcb\xc9Z\xdaT\x91wF\xb2x[[\x9c\xc9\xf3>\xb0\xeb\xd3\xcf+\xa4\x8di-%\xe6\x86s\xb6\xf8<\x95\xb0\x81\x9c\xf3\xe3{\xe1\x82ZN?\xed\xc9\xab7\x11\x9aA^\\\x89w\x9cK\xb10>\"\xc2\"F\xd2A\xc0O\xf0\x161\xeb\x9d\xa3C(\x17ac\xb7\x05\x00\x88l\x9e\xb6\nA&\x8c\xf1B\x88\xee\x0d\xc4g\xae\xdb\x84Zf\x97Nr\xa9\xa6\xeb\xc9\xea\xc9\xc57\x1a\xd1\xee\x9eC\xa69\xd8Cyc\x12\x15\xbe'\xf8)O0\x1dB\xc2\xab\x875\x9e\xd5\xeez5\xbe\xf4]\xb4d\xbf\x8e\x9c\xbdk\"\xa2\xdc\x934~Z\xe6\x0fR\x9aylj\xce\x854c\xdd\x9eKaf\xcf\x14Z\x16.@\xbc\x92\x0e\xc8\xba\xe4&\xe0&lS\x8e`\x01- peF$\xcc\x98'\xae\xf9\"\xbf\x90\xda\xb7\xd2\xccL|`\x1eH_\xad\xaedN\xa5\x92\xf4\xa6\xfeV\xd6\x9bii\xfdB`\xa3\xe2\xb2m\xc5\xcc\xe5Jp\xa7\x96\xb1C\x1el;\xa8D\xae\xf8\xc9\xa5\xe0\x8a-~\xa6\x13R\xb9Y\x94\xd2\xdd3\xf1\x1f\xef\x99\x18Ty\xeb\xd4\xfdr\xbat\xd9v\xed\xf4\xec\x80\xde\xa4O\xcc\xf7\xb1c3\x08\xf4\xb6\xac=\xe4\xbd\x93\x95tGS\x94Ey\x1e_;\xd4Q[\xb8\xb5[L\xaa\x944KE\xb4-\x1c\xef9\x92\x9c\xdf-\xaf\xd2\x05\x15[\x06\xb9\xe9\xe8j2e\xb3\xeby\xfc\x97O\x8be\x92\xae\xfe+\xcb\x0b\x8f<)e:\xd1'!dJ\xbf\xe4\x05\xbdY\x9a\x9dF\xad\xd1\x1a\nq\x86\x18\x0e\xadA(,\xc4r\xe1l\x1b\xf0\x0e\xca\xf3I\xdc\x95\x89\xa2\"\x08d\x98L\x0f\x93\xeeVn\x16_\xeb\xcc~\x9b\xd7\\\x84{\x9e\xc3\xdc\x94rC\xa49\x83PFK\x9f\x85\xa8!\x89{\xb3\xe7\x90\xc3KX<\xb7\xf9\xd2\xb2\xe5\x95\x90=\xd7\x9ap\xbc\xe0\xc2q(\x14!\\\xfe\xf3\xa7\xe510\xf1\xa7B\x98\xf1\xa7A\x88\x8a\x90y9\x86\xa5H\xc2u\x03/a\xf9<\x00I&\xa6!\xead\xe6\xa3eiQ\x95\x8cV\xa8S\x1f\xad\x1c2\xb8\x96a\x0d\x86\xdd\xb2J\xb5\xed\x9eA\x9f\xe6\xd7\x06\xa6nI\xec\x9e\xdd\x03j\xf7\xf8\xbc\xe0\x80s\x8f\xfe`\xf7 \xa8\xd9{<\xc5\xd7\x8f\xf7\x1e\x93)\x1a\xd6\xd4\x98\xa1t\xd7\xcc\xd2U\xae\xb9\xfdV)\xd4\x95_o\xc6f\xb9\xcc\xe2\xc7\x7f\n\xafh\x9c\x19\xea\xef5Jc\xf7\x9d\xff\x1d\xfb^\xd4\xdd\xa8\xd7\x9aof\x9c\x7f`\xd1\xa4\xd0\xf3\x10\xf2\xed\xa2W\xc9e>\xfd6\x9e\xb1\x8c\x85e\xe4\x82wg\x89\xc7\xbc\xbe[\x87e\xca\xf8\xa7\x8f\xbd\xa0>\xbf\x9e\x91\xd3\xbf\xbc\xaf\x0ceD\x05\xa2\xae\xcab\xafR\xb7\x85\xe0\xa9)\xd4u\x06\xfa$gi6a\x1f\xed\x00\x01\xe4j\x19\x1d\xfeX}\xab\x04x\xd6qp,\x04O\xeb\xba>\xbeE-\xab\xf1Z\xcfj\x9c\xd7\xf3#\xb3[X\xd4^\x1a)\x97s.\xd3\xe5z\x03ZkA\xfd\xcb8\x7f\xbf\xce\x98\x85\x15[\xfd&\x95AY\xd3r\xe5\xe2\x8di\xa5\xb9\x86\xa8p_\x82\x92\xf8\xcf\x02\x9b\xbc\x18\x0bc\xf5l\xfe\x90\xae\xafa\x861\x0c\xba\xfe\x07\x91\xcb\x13q\xb5k\x1fjk\x10\xf5+X;nb\xee\xbf\x04\n\xe8z\xc2\xb0\x07n\x9aT'\n^\x84\xef.\xf1\x17\xdf\xb8\xf5_\xbe\x97q\xdc\xed1q\xaf\xe4\xa1\xc9\xf0A\x7f\xd0\xdf\xfb\xc5F\x9a\xf8\x8f\xf7\xefm\x9d\x86\xe2\xd6\xd6`C\xd6\x98\x1eP\xed\x82\xf0\xfc\xf4\xe4\xc3\xe9\xc5\xf8\xd5\xd9\xf8\xdd\xd9\xc5\xf8\xfd\xf1\xf9\xf9\xf8\xe2\xa7\xd7\xe7\xe3\xb3\x0f\xe3?\x9d}\x1c\xff\xfc\xfa\xcd\x9b\xf1\x0f\xa7\xe3\x1f_\x7f8}\xf5\x0d\xees\x0f\xe65O\xc1u\xd7\x12\x0f\xa51\xe0\x01\xed\x92\xf7\xd82\xd0\x92v^\x074\xc3\xbd\xfb\xe4q\xdd^\xf4\xc9\xbe\xfe\xbb\x87)\x13=\x91k\xfe\xbcH3\xe65\x98}\xaa\x05\xed]i\xb3\n\xabV\xd2\xe5U\x9c\xb0\x0fl\xba\x9e\xa0\xd7gkKi\xcd\xdb\xa0j\xe9*N\xa6\"\x8c\xd0 \x1fY\xda\xa9\xb1\xd8\xd1X\xb4Z-\xee\xde\xc6\xd3\xe9\x82\xddF\x9d&\x189Z\x9ap2\x9fwia\xbd\xb1\x1b\x85\xe3 Ps\xe8\xd0g\\\x1bs\xd1\xd3o\xcb\x80\xc9|\xb0V\xf46\x8e\x8aFJO\x92.a\xf4\xb3\xda\xad/\xe7\xb1\x11\xf9\xc4\xb5\x98(38m-\x15\xf1\x16\xff\x88:\x9f0\xa5/\xc5BED*\xe5\xd3\xcf+\x8c\xf9\x00\xc5\x9c\x01K\xe6Q2a\x19\x14)\\1\x88\xca\xe9\xf6\xa8\xe8\x8ajq}\x16\x08C\xd9Z\x0d[+A\x8e\xa9h\x1bS&\xb0\xbf}H72\x99/\xa1g\xc6{j\xfb\xf5\x84pM\xe1\xef\xf1\x9e\xda~\xbd\x92\xa7W\xad\xa0D\x88)\xa9\x8e\x9c\xe1\xda\x8a\x1c(\xe2\xfa[X\xc6\x06&\xb0\xe8F\xe7MVS\x8bNM\xdc\xd0L\x8csAX\xd3\x82,\xd4\xe5]\xebj\x80v}M\xa5O\x95s\x98\xfaA\x08\xb32\x9a\x8dU\x0d\xb4\xa94\xda(\x8a\xd4\xdb\x0d\x15@\xea,\xb6\x06!\xef\xd5\x1e\x91\xfe(\xd9}&\xb23\x9f\xd9W\x14\xe63C\xfd\xc4\x84\xf9I\x08\x03\xda\x8a\x0b\xac]A\xbfu\xad\xe4\xd2\xbd\x92[Y/B;\x02k\xe9d\xf08X\xae\xf3\x82/\x19\xc6\xe2\x05!x\xe5=\xf8\x983\x98\xac\xf3\"]\xc2\xb2\xa4\xe8\xa8e\x88\xf2\xbbd\x02\x91\xf8\x9c\\^#-:\xeb\xa1l`\x0d\xe1\xdf\xca!Dw\x98\xb2}\x1e\xdd0\x88\x12(\x83\x1d\x83\x87jiPvG=\xf8\x89W\xb9K\xd7\xb0\x8c\xf3|\xc5\x16\x0b6\x85\x08PD\x89\x92\xe2\xe8\xdf\x1c\xa3Y\x11\x00P\xa7g\xd9\xfdT\x1a\x804\xce\xcd\x1dFs%E\x1bNSr\x7fA\x9a\xc2~\x85Y\x9cD\x8bEc\x1b\x03\xfb3\x9b|\xe8\xf6\x12\x9c\\\xcd\xc4\xd9 \x93\xa6k\x89\xe1\xb7\xb7]\xc8\x7f#3\xb6\x17\xa3\xc4aD\x92\xb6^\x80\x82\xa6\x92\xfb\xce]m\xe9\x0c\xc8\x15\xf7^\xbf{}Q\xff\x94V\"\xadI\xc3L\xb5hd\xec\xf1|}\x95O\xb2\xf8\x8a\x91\x11\x96\xafKq\x87\n\xf5\"\xe4'\x89$m\x92\x1f\xdc\x9bp\xf2\x93,a\x9f\x8b\x0f]O3\xf5H\x1d\x0f\x05Y\xf58!\xac\x1e*Th})BX\x8f\xd2^\xd4j?sS\xf9)\x11I\xacu+Fz\xb8\xdaJ\xb5C\x1a\x14\xb4 5\x91\x0e\xeb\x8b\xbb\x15\xa3\xe0\x9d^\xc9t\x89\x12\xd8\x8a\xec!\xac\x9d=\x96\xe4\xb6\xddJ\x9f\x95\xf6\xd4\xe2/\x7fn\x9e\xeb\xfaC\x93~@)\xa2\xe1pQ\xa2Ma9\xc3\xeaO\xa3\x0d\x82z\xd6\x89\x06\x7f;l\x90z\xba\x9cQ\xf8&\xe8\x843P\x0d\xcf\xf2&\x01\x81|\xcc\xc2\xc6\xf2\x05\x11)\x87\x0b]\xb4K\xecc\xeb\x0e0&Q\x91\xef\x94!x\xff\xfe\xef\x9c\xb9\xfc\xfc\x88\xff\xac\x07\x93\xff\x06\x89Z\x17\xf1\x1d~i\xd6\x9d\x8d\x14E\x1f\x9bWB\\\x1a(o\xc7\x84\xd8|I\x84\xc2Qfk.\x9f\x87\x9cp\xfa\xad\xd7\x10\x1eh\xa5Mo\xad\x8c\x1f;\xb9a\xb3X\xaf!\x92\xb9\xe2\xb5\x81\xe8\xa6v\xc1\x1c5\xea4\x90{\x89\x91{\x01\xcc\xd7\x8a\x7fm\xa1hS*\xdal^\xbc\xc0\x1b\x93\xc8b\xcbxs\xa8$\xe6\x1cIQ5\xd1\xb7\x9bH\x90\x1d\x17\x8e\x07a\xcd:\xda\xb3mY\xc8\xa3\xca-\xd7%\xba+2\xbe\x91\xf0I\x02^uV\xa1\xf7\x83 \xda\xe3~\xd0\x8bzB\xa3e\x82~cm\xd5\xa6\xf5\x9dkm.u\xc9\xcc0\xf2.\xacP\x97\xc7x_\xa6q9exIq\x19\xa8Y\x83^\xda\x8b/xQ\xc5\x18\x95\x08\xd0|\xda\xd0\xac\x8d\xdd\xf8\x80n\xbc\x18\xf5/I\x04)zBz\xf5k\xb0l\x18AWB\xca\xfc\xa2\x87j\x18\xc9\x80\x87\x15T\x88\x13\xc88\xec\x1fDq\xf8`J\xbc\x10\n\x15\x00\xb9\x8b\xf2S\\\x10\xd5(\xb7&}\xc0\x11xq\x12\x17q\xb4\x107P\n,*\xabr\x91\x82\xae\x9b\x83!\xa6\x1c\xbf\x89\xd3u.\xd3)gl\xc2\xe2\x1b6\x85\xab;]\xffP\x8b\xec\xaakM\xcb\xd1w\x81e\xb5g\x9f8\x9cQ-\xdb{y\xb1i\x1e\x19\xca\x84\x9frG\x1d\xc0#\xd3\x98]\xb8Q\x1cA=b\x02\xe5\x90\x86r\x0d\x1cA^\x1e\x07e\xc5j\xf5)}5GJ\x8a\xba\x13y\x06\n\x97Q \xaf\x1f\xfb5\xcb\x95\x82KXh\xc3kW\x8d\xf4\xaa\x0bL\xee!\xe8y\xc0\x17\xd6\xa3i~A4\xa6\x08z_\x18\x9fp\x1c\xe3@,\xf8\xaf\x9d5\xc7\xaa\x9d>G\x96d\xb3\xadS\xed{\xa7\xbd\x9c\x96\x0f\xa8\x84\x0e\x9e>\xe2\x08\x92\xb6t\x87\xa5G\x1f\xbe\xae\x0f^_\x0cm\x80Ay\xb6%\xfe\x9e2\xf0\xde\xdc\xfc\xb6\xcd\xbcag l\xbf\xe5\xa9\x8b\xb6\xf4}\x18j\xb1\x01\xd2\x92\xb0g\xc1s\xd8\xde\xe64={\x1e@*\xe8y\xe1\xb3Qr\x89\xcaT\x87\x1dh\xba\x19\xd4\xb5\x83\xf1\xc9A\xe0{E\xfaq\xb5b\xd9I\x943\x97\x15'}Hv\x02\x0eqA\xaf\x06\xb0C\xd8\x1c\x8bh\x97\x94\xaf\x7f\x81>_\"%\xc6!\xec\x14\xf0\x12R \xcb\x14\xb6\xd1h\x0b]\x81\x12Y\x90r|\x0c\xca\x8f\x12\xd8>\x844\x10\xe0\xe6\x1f'\xf2\xe3\x04v\xf8\xef\x97/1v7\xff\xe3\xd0\xcczU.h\\.U\x8aK\x95\xc1\x0bH\x9f\x07\x10\x8f2\xb4\xa5\x19e|$\xf4a\x17\xb7\xac\x92\xb9D|.\xc2\xc2\xd5\xf7F\x7f\xfe\xf3z\xb7\xdf\x9f\xfe\xf9\xcf\xeb\xe9\xd3~\x7f\x87\xff?\x9b\xcd\xfe\xfc\xe7u\x7fO\xfc\xec\xef\x1d\xf0\x9f3\xb6\x8b?glw\x86\xdfL\xf1\xe7n\x7f&J\xfbL\xfc7\xbb\xdc\xdc`W\xce#\xe9\x15,/\xdaM\xcf\xbabG\x08\x19\x85 \xa9\x03A\xe2\x86\xbdD\xac\x1a\xdee\xc6\x12\x03\xf8\nmo\xa7\x97\xb8v)\xbc\x80\xf8y h\x9e\xcfw\xd7(\xbdD\x0f0\xc76\xdb\x90\xb8U\xdbl\xf0\x9420\xae\x84\xf1J\xcdA\xc6\xd7\x8fI\"\xe3\xd6\xb3\xa0\xe1\x9a4\x04)\x9c\xf6\"\x05\xad\"H\x89[\x83\xa4M\x84US-\x99,ZQ-v\xde\x11(\xdeLXldhx5\xea\x13\xa6\xcf\xa0\xd6[\x04*\xb7\xc5{<\x0f\xb9\xec\xe5\xa7\xd5A\x17c\x1eHs\" \xc7)r`\xd7\x07`\xd7,q]e\x00\x88{9o\x14/\xb4\xbe|A'\xc1\xdaG_i\x94)\xbfO\xd8\xad\x1f\xf7N\xf0\x17\x97\xe38\x0bo\xe0\x13\x7fT\x15\xcc\x8e\xa0\xef\x9ax3\x94\xb3ng\x05\xfbd\x19\xf5\xc6\xba\x04}\x9c\xdf%\x13%,\x9b\x82tM\xd6vUZ\xeb\x95~\xcf\x12\x116\xc0U;\xd7k\xbf\xcf\xd2\xcfw\x97\x8e\xab\xf7\x16\xf9\x18\xad\xff\xdb\xc4\xe1\xcc\xe5F\x81\\\x0c:\x95\xe2_\xeb\xf2\xaf\xb8\xfc\xab\xcd\xc8\x86\xa2\xdd\xb6\xd6\xa1\xc52\xb8y\x92\xa5i\x17\xb5\x01\xdd\xeax\x0d\x11m\xff'\xfe\xb4d\x86jmY\xf8\x8fm\xd2\xecWj\x11\xf4\xd4\x10\x1b\xa2\xfa\xa0\x1f\xf8\x89\x7f\xb0\xff$\xd8\x88{ih\xd0\xdc%b\xf3\xec?i92\xcbKo\x19\xfa\xc8q\x80\nv\x15\xad\x0c\x95.\x06\x8a\x92h\xab\xa2-\xe53\xb4\x95\xfa\x89\xf0kV\xf4\x1c#\x02&h\xae\xaa\xf7\xc7x\x97m\xa7r\xc3\xacim\xdc\xee3\xda0\xe4\xc0\xca2\x14\xa1\xb1n\xed\x15\xa7\x07\xbbm\xd8\xae\xd8\x80<\x84E\x08\x13\x8a\x19@g\x02\xf8\x9e\x0c \xaf1\x8cv\xa9\xc8\xa8Dq\x07x\x1f\xc6\x019E \xfb3@\x1f\xdd\x97\xb0j&%\xc2\x8f\x9a\x9f0\x94nm\xce[\x11\xc5\x9a\xe85\xc7%\xb6\xdb\xbaq\xf08Kq\x87f\xbd\xbf\x96`\xe0\x12\x17?\xb63B\xf4\x04\xc5\xf9\xa0\xbb\xb8\xa0N\"!k!dE\xce\xfb\xdc\xc0\x0bX=w\x1d\xe5\x98\xa7\x96\x8c\xef\x02\xd2)\xba\x18\xdd\x10we\x1c\x00y\x80M\x8c\xf9\ns)\xd9\xbf\n\xe1\x0eC\x1d\x15\x88\xa1\x13\xcc\xca\xe8\x8b8F7\"\x9d\x13\x7fK\xb7\xa6\x99r\x8c]*\x1f^o\x1c`\xea\x9a8Y;\x92\x0c.\x0d\xcb:\xfd\xb9\xcaX\xf4\xc9*\xb1I!:\xa77\x8db\x0b\xa5\xf1V]V\xed\x93\xd8\xbf\xc6j\x9cA\xbd\x13\x9a\x1a\xbe\xfb\x17\xd2\xcdTl\x8bIP\xe1\xd2\xb50\x06p&\xbdl\xea\xb1 \n\xe0\x84\x04\x90\xd0\xf8*\xe2\xa7\xc4\x18+\x86/\xd0\x15\xee\xa3\x85\\\xdar\xe0\x8e\xe1|\xeb\x82\x90\x87\xc8\xa4'<\xcaQCZ\xfe(\xeaN\xe9\xf8\xd7\xbd\x84\x95o\x92\xf35\xc9\x9e\xc4\xac\x9a\x98\xefT\xcc\x97\x84\xa9e>N2\xbf\xf7$\xe8}\x8c\x93\xe2)\x8a\xb1\x0fr^\xee>\xa3B\x80r\xb1\x87\xbe\xc79\xd8\xbf\xaf\xe8)\xe2\xa5~\x93/\xddSz\xac\xbb\xedcr\xeb2b\xa1\xa5q(g\xf8l\x8e0\xf4_\xe6\xc7!$\x1dp\xa4D8x\xfc8\xf03\xc7\xd6M7\xebc\xd0\xa7\xa3RqN\xcd\xbf\n!'&v\x0d\x870\xf2X\x96\xa5\x99\x17\x827Y\x08\x7f5o\xca\xf2\"K\xef0\xb0N\xb4\x16\xef2\x96\xaf\x97\xcc\xbbt\xb9\x08\xdd9\x11&\x06y\x1b\xc3a\x88\xde\xe0ROf\xce\x154\x1aU\xe8F\x86\xb1]\x0f\xbd\xc9\xc5\xed\xd3\xdbt\xca\x9b\xdc\xdab\xda\x0b\x19Z\xd9\xb7\xeb\x99o\xbe|\xc1O3\xb9\x7f\xce\xca\x12\xc7\x1d\xa40r\x98\xc7\xd7\xf3\x9f\xa3\x82eo\xa3\xec\x93\xbd& id\xd5\xeeO\xed\x1f\xac\x89\xd1\x1d\xc1\xe0\x00\x8608\xd8{\xba\xef\x80Bm(\xfc,\xe0S\x12'\xa42\xa5\x10\xb0\x88\xaa\x82(\x90\xd9c\xd6!\xdd\x08\xc6\xfb\x9d-\xd24\xf3\xedr\x15\x96@\x08\x8a \\\xeeo\xca\x84\xed\x18\xe4R\xcb\xd8\x1e\x8b<\xe9\x9c\x8f\xd5_\x9d\xa4k\xf4\xa5W\xf5f\x8b\xf4V\xa4\x1a\xd7j\xb2D\xa4\xc8/\xf3\xb5\xb3d*\xe8W\xed-\x87\xb2\xf8\xb6|\x85.>\xc2\x9d\x05\x7f'\x8cM\x15\x91\xac5(Z\xa3\x8a\xd4\xda\x89 \x8aF\xfbbC\x9cO\xe6l\xba^\xd4G#\xf7\x8f\xf9\x12-\xe9N\x93I*\x87\xca\xacw\\\xae^\x17\xb3\xa7*\xe3|t\x1b\xc5\xc5\xab,\x8a\x13\x0dNr\xaeo\xd3\x8c\xd5\xdb\x9f\xa4S\x96\x99\xe0+{\x13oY\xf5\x8a\xa3\xc4\x1c/\xb2\xe6\x92\x82<\x0bzBE\xf1J\xb4\x15\xd8M\xb3[\x98\xfbU#\x81\xdd\x8fVX\xc3W\x97\xe7\xd7\x95\xdb\xf3\xcb\xa4\x1c[\x88\x8b:e\xb8\xaa8\x08>\xb4+\xd2\x95\x0dG8\xce\x8c\x03\x92\xd7\x17DK\x04\xa9\xa8\xad\xb8\n\xf1 \x14\"4\x03\xcc\xebV4\x06\xdb/w|\x10\xba\xd8f\x89\x1b\xda\x87\xea\xcdaU\x1a`\x14\nW\xdcx\x07 \xc7\xd5m\\\x16B\xeab\xe9%\x17\xc1\x0c\x88\xd8`\xabL\xcd\xe1\x08\xfc\xc8\xd8c\x9d\xf8\x04\xd4\x8d\x8b=\xac\xd6\xc9\xee\xa7\xaa(\xf1\xcc\xd5\x1ah\x9c{Y\x99\xb7\xde\xe4b\"\x94\x01\x8a*!\xd4%\xddRy\xd3\xc2*\xb1\xd06o\xb8N}aX\xb1\x91d'\xf6\xed\n\xa0\xb9xI\xb9\xfa!\x9c\x93\x97\xf7\x1ct\x11\x86.\xf2\x91f#\xbew\x82+B\x81\x9es&\xa2\xe4,zq.\xd8'?\x13\xce\x07\xfa\xb6A\xcd%e\xbb\nztn\xa5*1NKa\xa8W\xf7Mz\x9d\xdcD\x8bx\nI\x9a\xec\x88f\x1f\xc9\xc3a2_'\x9f<39\x9dz\xf0\xb8wLDnk\x02n\x11F\xb0\n!F\xe1\x93\x13p\xbf\xe4bb\xcc\xc7c\x0cY\x1a\x9c\x96\xf1\x97\xfb\x1c\xa3]\xf37?&\x93\xc5qi\x16\xb3\x0bi6\xc7\x1c6\xcdv\xde\xc6\xdc\x16\xbdY\x96.i\xdc\xc0 f\xfc\x94\xd6\x8f<{\xbe\x9aC\x9e\xe0({\xeb$\x9f\xc7\xb3\xc2\x0f \x9a\x15,\x03\x96L\x81\xdd`\xf0\x8f\x00s80\xb48\x10!\xfa\x10X\x02U\xbb\xb4\x8d[F5|z\xf6\xa3h\xd2\"\x0eQyd`nK\x0em\x8c\x0bXn\xda\xdb,\x96\x97{&\xb4\xa5\x8e\xaeJ\xf5\xa5\x8fw\xc0{\xfbT\xed\x9bz\x99\x0ci\x8c\xe9\x9ej\x03\xa2\xb0\xcfT,\xb6\xad\xd5\x16\x93`\xe2$\x84\xd5\xb9 \xdc$r\xc0/L\xe6\xb0b\xba\x98\x93\x8e|\xf5\xcd\xf8\xe3\x0e\x1a\x7f\xab\xd1xj\xc0E\xc9E}\xff=\xd4\xddEp)\n\xc1\x16\x1d\xf1)\x88\xb5\x9eFE\xc4\x97\x1ac s\xa0\xf9}\xb1\xa6\x1d\x89\xa2@\xd2\x92\xa6*\xe4Kx\x1b\x14\xa5\xad\x01\xee\xfb\xef\x914\x06\xa1XT3\x10d\xed\x17\xed\x94q\xa5\x87q\xf2J\xc6\xeb\xdb\x93\x9f\xea\nc\x82\x7fP\x01\xad\xea\xaf+\xce\xcf^bB\n\xae\x8d\xc7\x89\x80\x8e\xee\xfd\xc6\xfe\xf9 \xdf\xee,\x13\x82\x06\xbf^\xc5\x88,\xd5\xdf\xf5\n\xe3u\xa2\xd7)\x7f\x19\xb5\xaa:\xad\x87\x99\x90\x06\x10;\xd6\x8b\x05G\x10+\xccw\xbdq^\xb7K\xc37\"EE\x06\xe4\xf29\xc9AVG\xf4\x04\xcfoC{Th1\xdb|\xa4kxld&7/r\x15eu\x86\x9b\xa1;\xa1 \xfb\xc2\xba\x07U\xac\x9e\xf4\n\xc3\xa0\xa9\xe3*\x1c\x1a\x126;\xfcH\x1d&r\xcf\xb5\x9e\xe4\x97/_\xc2\xa0\xf6k\xb7\xf6k\xbf\xf6\xebi\xfd\xbb\x83\x10\xd8\xf6v`:]\x83\xe0\xb6\x03T>\xbd\xa8q\x17\x0c\xe7\xab\xa0\xa9\xcf\xbc\xb04\x06\xfd\x10\xfa\x1dc\xdb\x9c\xd3PPW*\xed\xc2\x97\xdd;\x97\xf3-e\x05\xc7\xfa\xa9\xef\xf1\xd7\xea\x9d\x17V\x8b\x1eP\xdfH\x9d\x88\xe2\x04\xd2*\xf5\xc6 \xba\xa3\x0d\xe1\xa4f\xe6\x02\x0d\xf3<\xa1\xe7)\x87\x04j\x92\x9e\xc8\xb0\x80\x0c\x87\xfe\xee\xc2N\xea@\xf7\xf3\xc9}\x82\xd4\xf4!\xc8\x82\x9b\x1a\x92~\xa8O\xf2X\x10\xd6\x8e\x13\xbb\xca!\x864\"\x01\x0bXV\x9c\x16\x17\x10\xce\x9c\xab\\\xeaK8x\x8bx\xf2\x89\x1ag\xa7>\xde\xb7\xaf\xb0\xc2v\xa1y\xa3zB|w(\xe6,eZ\x85\x90\xa8\xd9\x96\xe8\x18\x82\xb9d\xdarn6\xa5\x8bo%\x02\x88bS\xdf\xe3\xe3\xa9m\xeb\xe7\xf5AJ\x0b\x01\xa5|\xf2\x83\xe7\x86\xc0\xe3\x1a\xe1\xdb\xb6C\xc88z\x8eDWH\x1d-F\xa9{\xaf\xe3\x98\xdeu\x13I\xfaB\xfbU\xb9\xb0\x08\x07\x16\x0c7D\xe2\x15_$\x91\x93\xa4\x16^\x8a\xb8g\x92%;\xa6\xf4\xa0\xff\xd2\x15:\x99\xd8\x93\xcd\x1a\x02)Mx\xe2\xecd\x9a\x91$\x9f\xef\xc0\xb4\x95\x02\x0d\x01 \xa5\x0dM 1\x8a\x00\x8d\x9er\xfd\xa4r\x832\n(\xa9\x9b\xd0\xfeZ\x9al\x0d\xc3\x0f-\x99\xee\xcb\x17\xa5f\xa8n\xac\xe5\x8c\x87`\x89\xef\xa2\x9d\xb0\xfc$l\xd4\x01\xbd\x16\x97\xc40\x84s\x95q\x81\x13D\xd7<%\x81>T*\xa8@k-p0\xfe\xdf\x7f\xafzq\xb5\x8d|\xb2\x0c\xd0Q\x03\x8d\x13}\xa6\xbe\xc7\xebUJ\x82\x10C|\x18Q\xae\x04\xe4\xaa\x93\xc6\x96\x97q\xfcS\xe5\xf6\x00\x0b\x96\xe7P\xcc\xa3\x04ny\x8de\x94}\xf2\xc4\xb8P\xb9\xaa\xc0\x86\xcd*\xd1\xeeH\xad\x05\xff\x91\xe2\x95\x19\xde!\xa4b\xe1\x91\xbf\x93R\xf94\xc5\x01{A\xa8}_S\xa9HM\x91\x05@J\xa3T\xd38\x9aJ\xb5@or\x10\x1a\x82\xb0X\xc1\x04WP\xae\x8aX\xdaL\x1e\xf1}8*\x05\xbc\xa1<\"\x8f\x1cz-\xfe\x7f?\xd0u\x7f;\xa8\xec$gQ\x02\xd01\xa3\xa4\xdaJ\x9a\xc2C\xe2\x8f\x1a*\xea\xc6\xcbk\x94\xda]\x14?\xb0\xea\xa7\x9b\xa1 \x1ew\"(Z\xc3\xc4\x85\xa6\x80x\x00q\x8e\x81s\xe3\xe5JdH`6\x1d6n b\xcc2\xd2\xca\x8c\x96\x82\xd6\xf7B\xb8#\x8b\xa7Y\x14'^\x083\xb2T\xed\xcf%Y*g\x17\xc2\"\x109S\x8d\x8f\x13N\xaa'\x0deWd\x99\xa467AX\xc6\xbd\xde\x8au-!^\xeb\x8fo\xb3\xb8\xa8]\xbcn\x99/\x91\x08\x96\x9f\xcc\xa88\xb9_\x1b\xd6w\xe2\xbc\x8a\xc6\xb5E\xceP\x18\xeeM;\xc5\xb2\x8e\xeb\x06#\x1a\xef\x8b\x04\xf2\x8c\xab\x8cQ9^\\X\x17\"\xea!|\xeb\xc9X\xc6\x02\xc6\xd5.\xa0A\xac\xb20Pes 24\x00\xd4\xb2!8O\x05\xc4$1\xc1P\xb6\x14*j\xc5Jk\x1c\x8e\xbeBt\x91\xd1@k\xe4\x12\x1d&%qW\xa1\x0ej\x15^\xc2\x80W\xda\x11\xcd\xbe\xf3+\xfa/x\xcc\xad\x95b\xa2f\xd1\"g\x80\xddB\xc6\xf2U\x9a\xe4,\x04ek\x9e\x98\x17\xb0\xb5%n(\xdd\xde\x96\x93\xeb\x8bl\xca\xbc\xbdMw\xe3\xb2\x05\x88\x8aT\x15A\x08W~+5\x13\x08'\x10L\xbc\x17\xe7\x82\xc1\x98\x10\x11!\x9a\x06y\xed\xdcV-\x84\xf9\x8a\xa4 \xee\x8e\xee\x9ai\x93l\xbb\xf5\xb8\xd8\xb4\xdb\xab\xa6n\xab\xc3.\xe9\x89\xbf\xbb\x9d\xfdJ\x9e\x15;\xb1$\xfed7]o\x07\x00\xac`n\xba\xb1\xef*c+\x96L\x15P*/=\xb3D\xe4\x98iP\xa1\xf7\xc6h\xc2\x97\x0b\xe4\x91?F\xc5%\x1cA\xe4\xeb/\x02\xb4\xe3\xab~\xd7-\xb2j\x9f\x1e\xc2( k\xaf.\xb1\x8a\xf0\\J\x1c\x04OCeu`\x8b\x03\xa5\xce\x1f\x88w\x06W \x90^\x9e3|3\xc7%\xa1\x95w{\xc8\x8aU7r\x89\xbc\xcd\xf3\x03\xebR\xdf2\x82\xb1\x18\xf3&\x9d\xd5F*\x03\xf7\xdaWL\xd4\x90Jz\xc1\x1f\xc2\xc9%\xd6b9\xeb\x1c\xbdR\x11\xce\xe3\x9c\xfeh\xe0\xfe\x88U\xcc\xa5,\x87#lIXq(\x89Q\x96\xe1Qi8f\xd8^\x19\xfa)8\x90\xd6\xf0j\x11KvA\x18\x13%R\x92%p\x18\x9d\xfd\x9c\xfcB\xe9\xf0#\x0f\x0b'\xa8S\xa8\xcf\x9c\xde,\x9b\xce\x8an\xa5\x163\xb4\xff\x1cb\x0c\x15\n\xf1\xf6v\x00\xd9(\xbet\xc1\xa0Qak\x19\x0e\x01I\xa6nd\x9c\xc3w~Q\x9d\x9f\x0d:8D\x89H[l\xf9\x99\xca\xd9\x13\x850\x08\x0c@\xec\xa0\xe4cc\x93d~\x14\x08\xe5_\xa3\xfe\xa5\xb6{]\x0b\xdf\xb49S\xeb\xc6\xb5Ib\xcek_Vn\x10\xd2p\x83\xc60A\xd1\x05g\x12\x94\x82\x98\xdb\x00\xadT=(\x02C\xf0l*FRe\xb3\xa2\xdao\xc1\xe5.B=\xe0]Q]\x89\x9c\x11.G|\xe7R\xef\xc5\x85\x88\xa5\xc9\xc9\x1c\x0eM\x99\xa6\xec\xca4}\xcey\xa9<\xd4\x04\x853\xb9\xa6\x9b\x1c\xabM\xeb\x1fM\xcb\x93\x0e\x0e\x0d\xcc\x08\x0dU1\xdav\xb4\x98\x19\xde\xc8@\xfb\x9d\x00]\x9e\xb9\xc6QS\x9d2\xcc`\xf7[1\x15\xa4YJ\xdd\xd0D\x19\x1fY\xe6'\xf5\x1b\x88\xf7\xa4\x01\x12\xe0\xd9*\xd1<\x08(;CC\x0f\xc5\xb9\xdb6@U\xaaV\xbe\x8b\x04\x87\x0dr\xb2B\xc7\xd1\xb0E\x82\xb0\xe3>\xc2\x83\x1b\x99w\x87\x05e\xfd\x1c\xd1\x14s\xf2\xab\x0e\xd3\xbd\xcd\xa2\xd5F\xa7\xbb\xfb8\xef|\xf6g\x8e#\xa2<\x1eR\x8c\xc7\x83\x0c\xa5\x10\xa7[\xc5^NN\xa6\xbe\xc7g\xb3bS\x90\xc2}R\xf7\x97P\xba\xf8f\xc9\x99 \xcb\x87nnP\xf2\xec\xd6\xaf\x0f\\Z3p^c\x16\x9a\xa9\xb6\x8d\xbc\xa5&A\xf2\xd6%,HW4\xfe\xe8\x90P\xc2i\x0d\x14~Z\x9b\xa3\x90SS\x8e.[\x89\xe17R*\x95QS\xafY\xef\xa7B\xa4\xf7\xcd\x0f\xb0\x9e\xb2JQb?\xce/\x0d\x04\xd1U\xba\xf1R\x90\xa4\xb6l\x806\x93\xba\xcf\xd4<\xceG\xe9%\xd4c7kR\x81,\xf4UE\x0d\xa9\xdb\x1c\xee[\xd1K\xab\xcb8\xf3/B%3=\x85F\xc7\xf5\xfe\xca\xe1\xdc\x80\xfa\x1agt]^1\"\x83\x84Hp=\x8a/\xb5\x9d\xde\xbb\x8a\x93\xa9\xa4n\xbc\xa8\xc1#\xa7\xd0\xbd)\xdb!\xa3\xa1\xd0X\xde\x1f\x16\x81\xf2\xfe\xce\x14\xe7Z\x89\x11\xf6Di\xda\xd3\xc5\xddD\x91\x90\x9ao7\xe9z\xc2\x92\xf5\x92e\xbc.\x97\x13lj\xb3\x91k\nEak\x17G\xf6\x1c\xeb\xb3C\xbf\x8f\xf1,K\x97\xfcT\x86Cx\xfb]UV\xcf\xac\x10b\n\x1eG\x82\x05C0\xae\xe5j\xb0\xe3Mti\xa2-\x1b\x90\x88\x99Q\x16\x94\n\x83\x94<\xaa\x1b\xb4,_\xc9Q\xd7?\x97~,\x1d\x0c\x8f\xee}\xd7\x03m~D\xee\xd0\x02\xe23K;M\xbc\xaeZsn:\xf4\xb2\x8e\x84\x9f\xde\x11:\xe1\x94\xd6\x9b\x1b\xf4\x83p\xae\xb1\xb3%\xd3\x93*yA9Y\x08s\x9d{\xba6i\x17\xa7\xd6\xc0\xfcF\x08\xd4?\x96\xaf\xfd\xf2\x04 ;h\xb8\xb7\xe4=\xce\x11\xe7\xcb\xf5 &bv 5(\xf3e\x1dV8(\xbc~E\xd0\x92\xfa,\x87\x9cU\xfbYzd\xb5\x10\x93{\xc3}@\xf3w\x99\x1d~\xc1\xf2\xa1\x996\xb6`\x84u\xf8\x96\xe5\x1d\x90\xdf\x12#\xb0\xca\xcd)\xd4+\x08]Vs\x1b\xc6\xa2\x9aNU\x06\xf9\xe9\x9ca\x87\x0c\xc8\x96\x95\xa1g\xaa\xfbvDd\xafL>\xabG\xcf\xca\xd9B\x04\xb5\xe4\xff\x7f\xf9\x02\xb7q2Mom\xfa\x92\xd2\xe1\xef\x91\x93p93\xd1Y.\xa0\xc4\xb4xZ\xf9N\xf5\xc6h\x89\xfd#\xd2K\x07x\xf0\xcb^\xce\x8a\x8bx\xc9\xd2u\xd1Q\xccI\xd8-\xc4~*N\xb0\xeak\x8c\x87P1@!\xe0\x00d\xa1\xa5\xb7\xc0~_'\x05\xcbn\xa2\xc5=;V\x9f\xd3=\xabR\xa2k}d\xa8\x80\xa9}\xd0*\xffH.\x1f5\xb1\xbe\xd5|\\S\x97fl\x86\xb6\x91\xba\xec=3\xe6k|\x84\xed\xb6\x81\xa4\xb6\xc6\x02\"YX\xe2\x011g\x96d\xe9b\xd1EA\xa4C\xc7g\xbc\xb9\x05\x93?_OQ\xfc\xd0_\xd9\xf8\xc5{['D\x7f\x0f\xd2\x99i\x0e\xc7{\x1b#\x9c\x8f'E|#\xb4\xaf\x91\xfa\xf3[:\xa7/\x08\xe5M\xaaV\xd5\xaeW\xc0\xcbC\x99S\xc9l\x15\x0e\xa1\xda2~+/\xcaz\xe34Q\x93\x17\x97\x12\xe5o\xea\xb6\x87p\xb9\n1\xa4\xd5n\xa0\xf6\xdcr\xc9\xa6\xb1\x08\xce\xd2N\xc2\xea_Ta+*Rh\xd5\xe08X\xb2.za\xb9\xf36\x1c\x82\xf1\x0d9\x08\xbbNm\x18\xf5\xe2\xea|\xe8\x94\xe0lc\xe6\xd9\x11S-Eeb\x9c\xebq\x88\x9a\xf1SY$\xe1\x9d\x82\xe7\xc16\x17\x82q\xbeE\xfa&\xbd\x15 \xc9|\xa7\xfd7\x1a\x11ys\xf6\xd9\xa3\x8d{D9FBj\xa9\xb0\xd3\\#\xca'q\xdcX\xe3*N\xa2\xec\xae\xb9J\x94\xb3\x83\xfd\xe6\x91L\xf2\xdd\xb6\n;-5\x8a\xd9\xe0`\xc1\xda\xea\xec\xb4V\xca\xa2[G9h\x1e\xda\xfd{\xda\\\x95\x1e\xde\xf6\x16\xaf\xefnG6,\x8a\x931\x08\x95B.\xdc \xac\xab'\xb8\"\x81\xed\x0c\xbc\xba\x90\x92S\x11x\xd6r\x11T<\x7f\x1e\x94\x03s\xb6\x0c]p\x17:\xe1\xafz:\x0c\x12\xba\xa0!tBE\xe8\x88\x8e\xd0\x15%\xd5\xa3M\x03k\xb7\xcdd\x11\x15q2h\xed\xbdq\xf7\xaaG\xf5-\xdbl\xeb\xbaq\xbbC'\xd2\x02\x1dh\x9cz\x94\xba\xae\xc1\xe8\xa9mO\x82r\xb1h\x0e\xb2\xa5\x1eN\xb3}I\xb4\xeb\xf4ZD\xa3\xd0R\xd8\xea\x0f\xa5#\xa4n&\x1d\xd1{\xc5\xe5b\xed\x989<\x94\xd1\nE\x120\xdb+\xc4\xfb\x98|J\xd2\xdb\x04\x14\x15\x18\x82\x18\xb6[{\x88V{uJT\x05v(#\xd3Q,W\x07\xb4\xc7F\n\xf6\x99C)/\xdb\xe4\xac\xd3B\x80\x8e\x88\xd1\x08n#\xd7VR\x81\x1d\xcc\xe2\xc5\xe2M\x84z\xba\xf5\xfd{i\xc4j}^\x93\xda\xbcf\xa2\xc7\xbd\x8dzlDX]\x89),\xc0\x0ea\x15\"\xe7\xe4k\x1d\x9b\x92B\xed\x17\xd6[Dy\xf1\x8e\xa1\xa0\xadB#\xf2W\x17i\x81\x92\x92\xfe\xeed\x1e \x9f:\xdd\x1f\xb0\xa6\x0d,\xff,\xcf\xaa\xc8&\xf3\xa5\xa9\xc5\x8bC\x18\xec>QIb\xe0\xe5Kx\x0c\x87\x87p #B\xe3\x9b}\xfef\xb0\x0fG\xb0\xa7^\xed\xf1W{}8\x82}\xf5\xea\x80\xbf\xda\x85#\xd8\x19\xc0\x10vv\x1b\x87\xb4v\x1c\x9fJ\x1bXM\x7f\xa7\x0e\"[\xca\xdf\xc4\x05\x1a-Ov\x9f\xf2\xbd\xec\x0f\x9e\xed\xc2\xf7\x98\x14<\xd0\xac\x99\xeaK\xe1\xfd\xdf\xff\xd7\xff\xe9\xa0\xb2\xe8cTU\x97\x16\x83\x9ak\xd8\xa0\xe9h\xa5\x062p\x0dd\xd08\x10\xa0\x06\xb3k\x0c\x06\x7f\x9b\x1d\xee\xba:\xdc\x95\x1dv&\x9e\x85T\x88>\xa7\x90L\x93$\x12t\xb0\x1f\x1aX\xffB\xf36\xc3x^\xe8\x97YCy\\V}\x1f\xf0\x0f\x03c_\x94\x89\x0d\xeb\xfcVho*\x11\x17\xac\xa9\xa32\xc2\x99\xbe\x9f\xcb\x11\xefh!\xd0\x9a\xf7^N\xaa\x00\xf8z\x95\xd9T8\x8a\x07\xf0\xaf\xb0\xcb7P\xbfI)_\xa5n\xf4K\xf2\xee\xb6#i\x0e\x04\x80\xd7\x91\x93y\x94\x9d\xa4Sv\\\xf8\x9a\x0f\xac\x199Z=\x18b\x9f\x8b\xdd\x8f\x1f\xef>;\x004\xcc\x7fq\x08\x8f\x0f\xf6\x06\xcfj&_\x06.Y\x04m\xdfX\xb8Q_\xa4-\xd6 \xb2{i\xd6\x19Xu\x06\x97!$\x95\xa3\xfa\xce\xe0\xfeF\x1e\x14\xde\x9a3\x19\x103\xd9m\x9f \x1f\xa5c\xe1*4C\xa87\"\xd2\xc2M1\xeb7\xe2G\xda\x81$n?\xa8\x9c\xec\xf5\x8d\xd4r\x11\xe4&\xc7\x0d\xdc\xcb\xb6ksj\x10\xe8\xdb\x01\xc1\xc8\x95h\x84\xcc\x84\xdcbj\xfc\xd66\xdb#\x89T_z\x9b\x1c\xd5\xd6J\xb2\x1a\xd2\xf1\xcc71b\x0fv !\xb0bOY\xa4%j5\x1a\xf1\xa3\xd6\xf47\xed\x87 t\x0c\xbf\x86iI\x0b\xcd\x9a=\x1c\xaa\x91[\xe9\xa8\x11;\xcaA\xf7C\x04\xb0\x81\xa9\xc3\x16lX\xb9\x99\x1d\xc7\xf9\xd0\x0c\x8ci\x03\xf3\xd4\x06\x0b\xada\xf5WQ\x8f\xe7\x06\x87\x10\xd75\xd3\x8a\x91t\x0b\xff\x95\xcdmy\x06\x95\x82\xa1\x01~\\\xb6\xd0t|\xee\xb4\xff\xe3*\xef%\xfab\x96\xac\x99b\xe2\x85\x9c\xe3\xe8\x18t\x03%\xd5Mhs\xbb\xf5\xbd/\xec\x14\xd1\xe5\x9bD\xa3\x04c\x92V\x00\xd71\x89\xf3\xfc\x9c\x10$\x81\xe2/\xeao\xf0:I[\x91:\xd4\xa5\x88\xd0xK\xf5\xc0\xf8\x8f\x1cV\x1d\x9d\xebc\x92RL\xe3]\xc2\x8d\x99\x17\xbd\x81\x01\xae\xec\x93+\x8aAs\x0e\x19\xbc\xe0M(\xd2hW\xba\x91\xd9\x03\"\xbf\x18e\x97\x0e\xfe#E\x0d}\xd9L\x8a\x8e\xbcB_\xaf\xa1@\x8aG_\x08)\xdd\xc8\xce\x0e\x0e\x86\xaf\xde\xce\xae\x10\xb3\x9b\x06\x86\x8c\x956\xb2\xa0\xf3\x18v\x7f\xfd1\xc8\xb60\xf8\xce\xa1\xca\xd2Y\x1f\xd5\x1e=*\xd5y}\xfb\xb8M\x8bQOhly\x9b*\x96\x01\xfb\x8d\xaf\xad\xf3-\xb1\xa9\x8c\x1e\xa0\x01v\xc0O,\xcaMn\x0c\x9a\x05\xef\x0b\xcfijh\xf5|a\xf5\x0d\xa3\xa9\x17\x9a\xa9g};\xbe \x08\xa9C4h\xe4\x85\x1eT@\xa9C\xeb\xde\xc3\xd1\xc4\x98\xfa\xa45 \xc68\xa5\xeeu5\xa3\x9b\x1ei9Nn\xb4\\Pt\xa63LcS\x164\xa9\xd7\x11\x87\x11\x04\xb5\x84*\xf5\xb4 \xb1\x9d\x01\xabfu_Zc\x14Y\x94\xe4\xb34[\ns\x0c\xca3\x06C\x83_\xa8z\x1dl\xa7\xc0d\x9b\x8d^h\xa9*\xe9\x95\xb5\x9a]9*\xb1\x0d\x0f\x9c\xc9\x95[J\xdb\xca\xea\xf2\x983v\x80\xe068\x84\xae\xa2\xc9'\x15\xaaf\xb9^\x14\xf1j\xc1\xa0\x88\x97,w\x86\xbcW\x03\x99\xaf\x93O\xa5\x9bJ9\xba\xea\x8d\xcc\xfaW\x94W\x852ut\x88Y\xf8\xdc\x93M\xbb\xda\xc5\xf3'5Lw\xfc\xd4\x8al\xaeLd\xe1\x05\xa4D\xe0\x8d\xaa+\xdf,\xb6z\xfcZ\x99\x81Ri\x04\x19\x9bj\x88C\x99I\xeakN\xd7\x90`\x14\xf1.\\\xc5\x1c\xf4\x8d5*u3\xafT?/h\xfb%\xc2\x13\x83\xaa\xa6E\xf3h\xcc-RNT3y\xaa\xde\x1d\xea5\xdc\xa9Ff\x8bu>\xd7\x1a\x10\xbf\x0fU\x89\xb2\xbaG\x9b\xedU\xc6J_\xbd\xa8M1J\xf1S\xca\x1d\xa3\x8eg\xe4\xc8\xf4\xd1\x1c\xe9\xbfj\x99\xd3Hnl]\x12\xd7\xfa\xa2p.r-\xc9U\xb5\x7f\x9a\xe7\xb1v\xb1}\xb5\xab\x14\xc2\x88\xd4\xe6\x12j\x99GY\x15\xee\xde\x8a\x14\xa0\x0eL\xeb\xa2\xe3$Z,\xf86\xac\x16y\x9a&\x0cn\xe7,\x81\xdb2\xa9\xd2\xd6!\xf4\xcd\\\x86B\x8bi\x10\xcd\x1au\xdc\xb0\xbb\xbc\x88\x17\x8b\xdaV3\xbb,!C\xb8\x03TB[j\xa5V\x0b\xb5w~,\xd8\x95x\xc3\xe0\xee:\x816']\xa3 \xa5\xdfS\xbd}\xcb\x9d\xac\x1ay}0\xb5\xfd\xd6&)X\x00\xae\xbev\xc4\x98qvk\x8b\xb2t\x97ug\xb3\xa63\x13\x85\x13\xfd\x80\xe1P\xa9\x1dB\xac|\xa3]\xb7\x17!le\x06\"\xd1\xf2Q\xe7#\xc7\xcf\x8c5\xc2\xf3\xe5\x17:q\xbe:Al:\x174\xdf\xaa4\xc2\xb6t;)t\x88\xe25\x82\x02\xb8\x88\"\\cW0\x0c\x93\xc9\xc0\xf4-.\xcb\xd7\x1b\x0dU\x93\x15\x03\\\xf4\xea\xdc\x960!\xb6\xb7A\xdf \x89\x8e\xa9\x1at\xfe\xccd\x14\xed\xd6\x8c-\xd6l\x90Q\xf8\xc2fZ\x10Y\xe1Cn\x12w\x83\xb8\xdc\x8b\xd7\xd6\x98j3\xeb$G_\xcc#\xa9KEiv\x1aM\xe6\xf5\x8aq\x95\xdf~\x92\xb1\x1a.tK\xdf\xab\xf0*\x16D\x93\xa4\xaa\xd2\x8a\xb4\xb4\x1am\x03 \xe7\x069\x8eug\xb4iV\x10M]\x12\x99`\xbe\xc08\x80\xc0F\xc9\xa5U\xf9\xab/\xf3f\xa3\\`\xaeUX\xd34\xc2}\x97\x8b\x84g\x00\x7f\xfb\x86&5\x0c\xd0Sen\x92\xb7\x16\x89\x1d\xb9jq\xfe.z\xe7c\xfa_\xd4b\x14B\x7f\x817w\xdf\x7f/\xd5\x15;\x98\x9b!\xc5\xe8\xd6\xc32\xfc\n^ \xb5\xa7O\xef4\xc7\xba\x0b\xce\xc1\x93\xa7\x81\xcf\x87$\x916\xca\xf3\xf8:\x81!\x16=\xfbV\x9b\xc2\x10\xd2\x10\xb3\xc9\x85\xb0\x0eA\xf5h\xec\xadNv\xbd\xd6\x85\x05\x7f\xb4\xb8 Evg|E{g-B\x90Q\x00I'\xacI\x9a\xcc\xe2\xeb\xb5r\xc3\xea\xd3\xcc\x7f\xe4t\xd2js\xe2\xc2,\xd8C0\xcc\x80\xb5u\x85IT\xda\x8fU\xa7\x93\xb8\xf4Xhw\xb9\x99%Y7\x0f\xdd=\xec\xfa\x90\xab\x91\x88\xd0\x86$\x14\xc3\x8d\x13\xd4\xa35\x0cJ\xa6\xa5.\x0b\x1d!ez\x0d?\x13\xf9\xc1\x05K\x81\x9eZ\xd5*e\xfa\xad\n^\x17\xc9\xd4\xd2\x83\x83 \xc4\x8c\xa8\xa3\xcb\x10\xe2v\xaa\x1aR\x1ap\xce\xf9\xacG\xec\xb2d\xe6\xf9\x8fz\x15${\x05\xf6\xf3\x1c\xd8\xce\xce\xf3@\xb9\xb9z\x91\x07\xdb\xe0oo'A\xa5\x82\xda;0\xe5zM\x8f\xa2\xdc&|o\x96\x88\x9c\xb9XTJ\x1c>o\xb0\x90Q\xeeC\xf0\x02\xd8\xe6\xff\xfcM\xb51K\xa4\xc3\xa68;+\xc7\x81\xe7\xf0\xf5y\x9de\xec\xbcF\x04\xc5G\xf9\xc6\xb1f\xaeD\xf2 \x9eZE`\xa9\x1e\xec\xbd\xc9\x9f\xc8OB3\x01\x95\x03\xfd\x81\xba^\xfe\xfa\xad\xc4I\x88\x1cT&u\x1a\xe9\xeb\x00\xaa\xaa]\xb3\xe2\xec6Q\xd5^\xb1|\x92\xc5\xab\"5\x0c\xa8#\xd7\x07\xef\xa2\xa5\x19\xd3d\xed\xaa{~\xb7\xbcJ\x17y\x87\x93\x89\\cA\x82\xe5\xd1\x9c\xf9\x85\x89\xa7('\xea50\xca@\xe4\xe7\x81bv*\xf1\x9b\xce-G\xae4\x7fpOg\xa1H\xba\x9eQ>\xb6\xfa\xd2\x93M\xa0\xa1\x86\xfd]\x1d\x81\\\xaa\x0e\xcc\xe7\xbe\xfe\x07\x9b\x89n\xe0SJ\xe8\xb4\x9c\xfd]\xbd\x95o\xdc\x15\x8f)\xfe7\xf1\x07\xfb\xe6n\x89iO0\xce\x9e\xde\x17I\xf9\xc1Fd\xc2\xe3\xfb\xa7\xa4v\xa3\xddK\x12\x0c\x19\x92+\\!\xbd#\xc1\x87\xac\xa9\xe5HF\xd9%\xfa8)_\x8a\x08\x05\x12\xf5\x85\xb5$I\x0b\xa0\xf5>\xba1\xfcr\xe8[[R\xdb'B\x10\xd4\xd3\xc8}\xf9\xe2P\xe0![\xefR\x10\xceY\xdbh;\xa1\x05\xcdH\x15!x\xe31\xcb\xdf\xa6\xd35\x9a\x9c\x98K\x89\x8c\x8e.W\x06\"\xde<\xda}v\x81\x88\xbdX9\x17\xae\xdf/\xd6\xd7q\x92\x0f\x1d{\x8be\x99\xab\x08\xb0\xed\xe9z\xc2\xb2|\x08~\x9f\x0b\xbar\xe9\xcd\xe2E\xc1\xb2\xee\xc4\x80\xf5>\xb1\xbbs\xf6_~\xd0c7,\xd3\xc8\xb4\x13\xb4`u_\xb4d\x0bD\xa9mT4d6Q\xb2?z\xb8f\"\x16aw\xb2\xefDg\xd6[\xb2\xec\x9a\xf9N \x19\xc5T\";\xdc\x06X0\xfe\xe1O\x0f\x8d\x08\x9a\x1e\xa3\xf2 N~\x0dtH\xe8pZ\xbf\x06\x805)\xb2.\xc2\xc5B\xe5\xb6k^\x97\x89\xcb\x0f\xf3m%\x94\x0f:\x0b\xe5j2\xa6\\./e\xec\xc9\x95\xaa\x03\xc3{\xfa;\xfb/>\x83\x85uG\xc5\x19\x9b!\x18WS\x0bv\xc3\x16\xc32`|\xadl\xc9\xf2<\xba\xe6Go\xe9\xe6\x8d\xb5\x8c\x1e\xff\xbe\xa2\xb7K\xaf\xd5\xa4\xe1\xb4`\xfb\x97\xfc|\xc5&C(z\x9c\xc98W\xda$\xfc\xf5\x87\x04\xd6\x91\xb28f\xf35\xe8\xc0\xb1\xaaok\xa2\x80\xd8\xa1\xf8b\x15 \xbe\xc4l\xba\xc2G\x87\xf6\xf0\xc9\xae\xa9\xd4\x7fH\xed!Er\x08\xf7\xf8\xff\x15\xf4\x80 \x87\x8e7\xd3\x11\xd2\xe4]q\x8f\xc6\xff\xdc\xab\xfe\xdc\x0f\x02a:\xf3\xf7'_\xb4!\xa3\xeb\xc0\xe8\x80\xc67e\xb41\xc4ZI\xc7\xbd\xa0\x17'S\xf6\xf9l\xe6{\xd2\xe21\x9dA\x84g\xbd\x9f\x07\xa6\x11)\x947\xd1/a\xc7\xe9\xf6\x7fS:q\x1b] \x07ft \xa3:S\x96\xb6\x98\x05\xa1\xf0\xbd\x90\xea\x1e\xf4i\xe7z\xfb\xa1\xab\xc3>\x92\xd8\xed\x0ebB\xadqq3\xe1\x9b\x88\xd0\x90\xd7\xcdh\"\x91i\xdc*'4\xb1\xab\xe5\xef\x970\xc0\x83}\x1b\xbc4\xc3\x18)\x05\x0c!\x1b%\xb0\x0d\x83K\xa3\xea\xae\xac\x8a\xc0\x0b\xc1\xd3kj%X\x80\xbf\x9c\x03\xfc\x1a\x82\x97\xcf\xd3\xf5b\nW\x0c\"\x97Z\xc3O6\xc9$\xe0&~\xbf\xe9\xfdD\x9c\xbdEO\x1c\xfc$\xa1\xd1nu\x1dD}\xb0\xf7TCZ\x071\x0f\x91_\xfcMC\xe6\x1b(\x8dkw\xfa\x14\xf9\x11&@\x9e\xf2s\xeay\"e\xeaj\x11M\x98\x9f\xb0[\xf8\xc0\xaeO?\xaf\xfc$\x04\xef\x9aW\xf7\xbc\x80\xd2\x1b({\xa2\xdf:\x1e.\xa2\xbc@ss\x11Yr\xb1\xc0\x1fy\x19\x16\xd6@+R\xb4\x10\x98\xf6\xd8|\x1d[M\n\xa5\x8b0{U\x0cl\xd0q\xf5\xea\x80l\xd3\xb1\x94k\xae\x8b}JXU\x9a\x16cm\xaa\xa9\xd6\xc1B\x8f:n\x1aB\xd9=oG\xe3\xc8\xbf\xc5$\xe9A\x97\x9d\x90F\x1cs\xb0a\xdb\xe5\x92}\x11\xdd\xa5\xeb\xa2\xdb={)\x88\xfc\x03\xdc\xafS8\xfeP\x1c2}\xbf\xbe\xdb\xef\xbb\xef\xd7\x9fv\x16\xe5\xffW\xe0\xab\xff\xbe\xdb\xca\xc6\x99P\xaahvM\xa3\xa8HaM\xfc\xd0X\xb3& \xb4\xb0\xab\xe6\x98\xa4\xd3\xb8\n\x96hm\xaen\xe7\xa3J/\x90\x86\x90\xf7>\xbe\x7fu|q:~s\xfc\xa7\xb3\x8f\x17-\x8a\x82\xfaQ+\x88\x00\x9e\xa0R\xb9\xa7S\xc2\xc6\xde~|\xfd\xe6\xe2\xb4M\x91\\\xefM\x08\xde\x9b\xf5v\xfe\xd3\xd9\xcf-\x9dX\n\xca^>Oo\x13\x9b\x0e\xa9\xa3b]j\xed\xabO\x8ay\x9c\\\xbb\x1c\xe0\x94\x16\x1f\xdb\x95\x87T\xd5\xc8\xdf\xf8\xd8;\x1ev\x1c\x0e\x19\xe1\xd8\xd8\n\x07 \xf5\xb7g\xafN7\x06\x07\xce\x8d\x06GUi\x99N\x99c\xfa\x18\xea\xdc\x1fy\xbcJ\xee]\xaa\xfb\xab\x84\x0f5\x13\xb1C\xd0\xc6\xd9\xabO#\xfd\xad\x1c\xa5|\xd9\xce\xd7\xcbe\x94\xdd\xe1\x94o\xe7\x91\xc8\x0f\xc4\x7f\xc4\xf99_U\x11\x86}\x9de,)~D<\xd5\xdf\xb8\x98-u\xec<\xdd\xfbUO\x1d\x82\x95\x13de`Z\x97\xe5\x92\xda\xe8T\xa5\x9aS\x07\xf6\xe8Z#\x13\xda\xf2\x86\x04\xb4\xba\xb6&\xc9\x80S\xdd\xb50\xd6\xa5 {\xb4\xd6\x8brw'i\xb6\x8c\x16\xf1_\x19\xba{\x05\xd2\xfe\x1d\xfb\xd6wp\xae\xef\xe0\x00\xcb\xeb\xaf\xf9w 9\xcc\x1a\x0eu\xda\x8d\xa5\xdd\xab.\xa0\xd7SX\xe9\xa6\xb1pT\xff\xe9\x8e\x9e\xd3>kj\xef\x1a\xea\xe5\"0\xa6jo\x1bA\x94\xbaK\x06\xb6\xfc\xdb\x81\x1d\xdfBf\xc3c\xd3\xb8Hk\x18\xd2\x89\x94T\xf2\xcf\xdeAG\xd7/N\xa5\x8c\xa1\xd0jt9\xc0\x14\xf3\xe6d~\x12\x8c\xfa\x97!$\xa3\xc1%zc\xfa&EoTm\xab\xbb!\xd6\x13\xcd\xda\xc2\xa90\x14\xd7\x90#\x16\xfec\xd2\xc8Y\xa4\x0e\xac\xf7\xf8]\xfd\xaf\xce\xb0zb\xd2\x0c\xa9\x96x\x16\xf8^\\\xb0,\xc2\xa5\xb0\xc9\x9b\xe1K\xd9\x06o\xc7\x8a\x9b\xa1\xf4\xfd\xac\x87\x0dk\xc9\xc71{\xdaa\x8d\x9f\xddp\x8a\x8dsI\x8d\xb0\"\xf6\xfa\xab\xe5\x1a=\xb9\x1ce\x97f\xfe\xbdX.b\x93\xa4\x06\xaa\x1f#*Q(\xa1\xc8)NM^\xa5\x1a\x108\xb1[oA\x83 \xedx\xd3\xd9r_\xc4AB?\xe6*\x84\x93\x19oE\x913\xf3=\xbdi4\xc0\xd1R!?\xccb\x02\xa6X\x86Y\x97\xda\xa0\nMr\xb0z\xa6i\xc2\x86b\xdc\x9d\x83^\x878\xb0\x0d\xba\x8f\xa86\x98\x1f;\x08\x03\xeb\xe0\x1e\xd5\x05\xcb\x7f\x05\xfe\xe9\x97VE\xe4xk\xea^\xbe\xdb,Z\x1d+\xfdBC\xee\xe8\x7fH\x85\xc5\xde\xaf\xcb:.Paa\x99\x94\xaf\xcb\xa2\x81Y\x94\xcb\xa2\xbd\xfd\x03Z\x97AD_\xfd\xa7.\xe3\x97\xde\x97$:\xadHw\x81X\x95\xec\x99%\x91,yj\x954i),!c!\x9b\xd9\xb3\xba\x9eH\xb5\xc6\xc0x?\x93\xefwI\x84j\x08S\xfaK\xd8\xb9\xd4\xf4,\x99\xa6g\xd1\xac\x0f\xb3\x10fJ\x06?\x7f\x7fz\xd2M\xefQ\xe6G\xd0\xa2\")\x81\x1b\xa3\xe9\xa2Z\x04-Ru\xa5\x08\xe8\xa3V\n\x01\xc7`>~x\xd3m,\xb2\xb3u\xb6\xd0\xfb\"\xc4\xf6\x86\xce\xfep~\xf6n\xa3\xde\xfe\x92\xa7\xa6\xb4u\x96MY\xc6\xa6\x9a\xee%\xe8\xdc\xff\x87\xd3\xf3\xb37\x7f<}\xb5\xc1\x18P\xf8\xc9X\x9e.n\xd8\xd4\xbb|\xf8\xb1\x8c\xcf?\xfep\xf1\xe1tc\xad\x0c\xad\x8fI\x84\x13\xbd]\x98J\x13\xdab\xde\xa2\xa4Qs=__\x15\x193e>]\xad\x14\x04\x0ehd\xdd\xa1\xf0\xfe\xf8\xc3\xf1\xdb\x87\x9a:\x9f\x9d{\xe6Y\xb4|\x17- \xd0\xc4U\x85\xd7\x84\xd6o]\x15\xdb\x85y\x13\xcc1\x9cg/\xce\xff\xe7\x92\x88 7!tB\xea\xbd\xf0T\xe6\xe7\xcf\xfc$\x9d\"\xd1\xda\x8a\x05g\x0dG\xb0\x16\xaa\x88$Z2\xa17\xeby\xb0\xad\xde\xc6\x89|\xc7?\xde\x11\x05\xaa\x1d\x1f\xf3\xf7\x97_\xc4\xf61\xca\xe9\xea\x02\x8e\xc0\xc3\x19\x8d?/\x17\x1e\x0c\xe5/Z\x7f\xa0i\xf7\x18\xe6\xf3F\xeb$7\xd6dA\x08#\x0f\xa1\xc9\n\x86Wv\x93\x10f\x97A\x08yg\xac9}\xfb\xfe\xe2O\x02w\xc6\xaf\xdf\x9d\xbc\xf9x\xfe\xba\x95\xb0l\x84EoY1O\x89\x1a\x0f\x83Kq2Y\xac\xa7\xect\xb9*\xee\xfe\xc8Ak\xf3-\xc2\x1cx+.y\x1ee\xc2v\x1be\x89\xef\xfd\x1ce \x06\x1el\x02\x08L\xd0\xe4\"I\x0b\xb8f \x17^\x19D\x80c\xfb\x1f\xec\xae\x87\x16d6\n\xe4\x18\x1d\xd7\x81#\x0f\xb3\xe8c\x04@\xce\xd9g/\x84\x9c\xaf\xfd\xba}\xed\xffx\xfc\xe6uE3\xce\x7f\xbd\xe5\x8e\xf3\xb3\xe3\xf3=z\xad5\x05YGH\x04\x84\xfa\x9f0\"\xe7\xb4\xe3\xd1\xe7\xe5\xe2Q\xdc+X^\xf8\xb1\xd8\xde\x1c\x0d\xd6K\x96\x8f\xc5\x96\xa4\xbe\xe4{x\xd2\xe3\x9ca\xc4\xa1\xf3s\x8c\xf3\x8bd\xcc\x10ArB\x18\xb1\x86!6\xdfcl4]c\xb7_R\xd3\xefx\xfb1S\xd6\x8f\x1a\xed\x10m\x95\x8e\x15\x94\x01\x95K\xecV\x18\"\x8e\xb0\x9bh\x11\xf3\xc9\xbd\xe7\xad\xa3\x91\xfb\"\x84\xb4\x835\x18\x87FAR\xe4\xa2\xa2\xc8!(\x0b\x85Ks\xfe\xa4\xd1\x93\x1d\x15\xa5}\x7f\x08\x93\xfco\xdc%\xdavx(\x1cH\xdaq`t\xd9\x15\x07\xbaX\x03\x81\xc5F\xd6\xacCj\xdd\x12\xb0\xdf\x18\xf0\xe7\xa7\x17\x9c\x9b{\x7f\xf6\xee\xfc\xc1\xb8\xb8\xcc\x8c\x07\x035\x1e\xce.\xc3k\x9d\xde\xd2A\xc8\xd6\x0ef\xc3_\xa3\x13\x1d\xc2\x07\x8e\xc0\xd0\xea\xdb\xa0\x15\xd6\xd2dP,\x8e\xfcC\xd1V/!\xcf\xc6\xd2\x90_T\x92? \x9e\xaa\x88\x8au\xce\x19\x16U\xb5zS_\x9bP\x96g,_\xa5I\x8eY\x02\xb2\xa07g\xd1\x94\xa19\xd2\xba\xfc\xfb\xcb\x17K?\xc0\x17c\x824\\\xe3}\xb1\x1d\x8e*i\x08\x91\x8b\xdd_;(\xe4B\xc1\xae\xf7\xc3\"\xbd\x12\xda\x97iTDzPm\xbb\x8e?A\x8a\xed\x1aD\x08^\xc1>\x17\x9cr\x88\xd6\xf8\x112\xe9\x88\x95\xff\xf1\xf1\xf4\xbc\xedJ\x7f\x03\xa4\xfc\xaf\xcd\x902\xd6\x90\xb2U\xec\xf8\xaf5\xcb\x0b9\xe9\xd8\x05\xf9.\xa2\x05\x9f\xf9\xdb\x8f\x17\xc7\x17\xa7\xaf\xfe\x91 \xb0\\\x17Q\xc1\xa6\x1f\x1e\x0e\x10\x929<{\x7f\xfa\xe1\xf8\xe2\xf5\xd9\xbb\xf1\xdb\xd3\x8bc~B||0:\xd5$r9\xa4\"\x01\x92O\xec\x8e\x96\xa6F\xad,\x85\x83[\xeaz\x1eYN\xa0\xe5J(V\x0e\xb5\x0e\xae\xcf\xf3 \x080{dY\xbd\xd2\x0el\xfcI\xab\x90\x8d\x9f\x1eUX\xe2\xaa\xb7\xe0\x87ll\x9f\xaci\xd0M\x1b$\x98\x87\x87>\xc5\x9a\xb0\xa3qOL\xd9\x82I&C'\x87Y\x08\xe9e;\xde\xab\xc9<\xe8\xd6\x7f\x98\xb9\x94{\xbb\xe3T8-;?\xf9\xe9\xf4\xed\x83\xadI>\x993\xeat\xfe&*\x96\xf2s,\xd6\x11\xd5\x13\xfdTT,\x13\xca\x87/_\xb0\x9e\xbc\xb6\x1dR\x1fxc \x83s\xf1\xe6\xb2\x9e\x97$(\x7fv\xbe\xbf\xdd\xa3c\x99=\xdb'4\xdd\xf2\xb67_\xb1I\xccr\xaf\x8b\x1d\x00\xb9\x16!\xb2d\x99\xcf\xd0_?/\xb2\xf5\xa4H3\x12zZ*\xa8HK\x0f\x7fx\x08~\x82mD\x01\xdf\xdb\x98\xdbh\x08\xa9n+\xd0\xe9*\xe1\xa6\x16\x87\x15\xe7\xb8\xff\x8cV\xd8\xef\x99 \x91\x86\x85\xfb\x94\xce>\xf1\x07V\x948\xa9\xb1\xa7\x14\xf6\x93\xde*K',78\xdbU\xc9\xfd\x94\x89\xf6k\xe5S,\xafg\xc0\xaf\xd7\x98c\x8d\xb7\x82\x9f<\x99GI\xc2\x0c\x85\xdb\x0d\xd6x\x15\xe7\xab\xa80\xc35/1\x1di\xed\xd55\x11\x80\xee\xae\xed*\xf7F\xa67\xd8\xb6\xc3_\x83\xd4\xea\\\x1bWJ>s\xe6\xbeW\x97Z\xd7V(R\xf5\x08\xba\x82\x15B(|B\x92\xa9\xbd1\xa6s\xd5h\\\xc1\x1fu\xe1%x\xcez[\xd5\x88V|\xe7O1\xc6\xc1\xaa\xb1\xc9*G\xba\x8c\xd6\xcaQ{\xf0\x9c2lJ\xaa\xe8\xaa\x95\x11S\xb2\xbd\xed\xb8g\xbb\x1emo/[o\xda\xd7\x8e$\x1a\xf2\x06\xe8\xc7j\xe0\xa1\x15\xae:\x84\xcc_\x06!,\xbf\xd3^5\xc7\x86\xd7VG\xff\xc8\x93[\x00\x87\x90\xf8\xcf\xf6\x02\x7f\x16\xe0\xb5l#\xec\xd0\x94\xe1\"\x9e|\xf2#\xff\x0e\xe3\x94\x0ct\xfe\x0f\x86p\x83\xc6`\xbd$\xbdmm\x0dk9\x1b\xc2\xd0\xc2\xb12\x19N\xd8-\xcc\x83\x1e'{\xbb\xfct\xe2\x7f\x0czi\"\x8578\x84\xab\x10\xbb\x8b\xfc\xb8\xb7J\xf3B\xeeB$5\x03d>&\xbdh:=\xbdaI\xf1&\xce\x0b\x96\xb0\x0c\\\x01\x0b\xb5\x06P\xdb=\xe9\xc5K\xde\xe39\x86S\xcdU\xd0c\xf7\xd4&\xfa\x18|tt\xe3\x07\xca\xef\xea\xa6\x87\xf6\x88t\xa7\xa1\xab\x10\xb6\xc4\xc8y_^\x9ad,\x9a\xde\xa1\x1d\xc2d\x1e%\xd7\xcc\x838\x81\x85\xef\x89 \xaf\x1e_>\xf7\x88\xf2^\xb4Z\xb1dz2\x8f\x17S_\xfb*\xe8\xd9-\xb7\xe1p\xde\xcb\xd82\xbda\xa21\x91 \xa7\xdc\xa7\x06\xce\xd6\x16\xb5a|\xac\xb8\x88\x97,]\x17\x1aF\x84\xd0\xaf\x1f\xb8\xfa\xd1g}?\x84\x95q\x06pZ=\x84i\xd5\x04\xfe\xf5\xedq2\x1bM\xebh:\xea\x08\xc2\xcd\x9f\x9b!\xb0v\xb2\xd9\x18\xc9\xb5\xb5kBQ\x02\xb2\xeb\xb6\x8e[\xa0\xb7)\xb3\xb3\xfb\x94dvv\xfb\x8f\xef\xc3\xe2`\xb2\x10\xa4\x95\xa9_\x88|\x1b:\x9b#\xed\xedJK\x08[\xf1\x82\x91\xa2{3;\xa5\x98\xf8\x82\xf3\xc2\xa8\x05\xe3b\x92\xb4\xa4\xe5\xec\xc32\xce7\x8cs[\x8fu\xffd\xef[\x02\xda\x17\xba\xe5\xc0!l\xb9\xcc\xb9w\xfb\xbf\xa4Q\x8e>\x1eY\xa7\x8b\xa5d+\xf3\"\x9c%\x1d\xa1\xc5]\xa8\x8f\x89\xe1\xd40j\x8aw2\x9a\x13\xd8\xe3\x81\xccOC\x88\\\xb5\xa112\x85zn\xa4\xb3}1J/\xfd\x88\xd0\x10\x98\x8f\xd0\x0e\xa2\x8a\xc2Y\xb7=\x8a\xb3ztF\x9e\x0c$\xa3\x1e\xdb\xe0K=x\xeb\xb7\xeeM\xd3\xa4\xda7%`\xd5N\xf0\xf3\x00c\xfav\xd0\x80\xab'\xf3=\xce\x15\xcb\xc8\x1b\x89\x88\xd7 \xd2'\\\xb6exq\x918\xc2^\nM\xc0\xb7R_\x84\xc9\x8e\xe5\xff\x98\x0d\x87\x8b\xdb\x9b\xa1Q5\xe9\xc1>}\xca>1\xe5j\xa9R\xd83St\xca\xfc\x15\xe6\xa1,\xc4\xf0\xa7\xfd.g2\xba\x1f\xe4\xd4\xc9\xbc\x15\xa1d\xa9TP\xf5\x8dX\nb\\\x84\xdf\x19\x84(\xb2\xa3\xa7|\x8aQ\xe2\x82@Jb\xa1\x90\xdaa\x07\x06!J\xe9\xecy\x99o\x12\xc5\xbe\xed\xed\x05\xbc\x80\xc9s\xd7\x81\xc2%\xa4\xb5_\x8c\x16\x97\x0e\x82\xcc\x05w\xc2y\x81O\x01{\x995I\xc7\\\xa6_\x8d\xa6\x0e\xe9XO\xaf\xcd\xbb\xe1\xc2C\xee\xdf\x840\x0da\xc5\x99{QA\x98r\xceQ\x80\xb9\xe1\x9c\xfc\x0d\x0c!\xe6c\xc6@\x17\xfc\xcd\xe8\x92\x9f\xceT\xf8!\xebM\xe6\xaf\xb0\x83y \x00\xc6\x87\xf7\x9d\xfb\x13\xb5>\xf7E\xc2\xbd\xfdN\xbc\x1bq\x14{\xe31\x9a\xb9\x8e\xc7b\xaf\xe0\x9e\xe0\x8c\x88\xfc\xc0\x86z{V\x9cZ\x12\x19\xa2\\Z\xa1\x12V1Zb\x1a\xc3\xbf\x01\x95\xd7\xa3\x82\x0b\xf7\x1b\x9a\xb5k\xf4\xc9\xe4\xc5\xd261\xab9\x10\x16C\x95\x9c0\xc4\x0d\xc1\xab\x9b\xe2\xb6\xc5\x8f\xc10\x94\\&E\xb3\x07B\x06p\x9b\xf7\x7f\xf5\x1d\x8b\x9dv\x81\xc7/lN\x1cBQ7\xa1\xc8Q\x17\xcd>\xb3\xc9\xba`\xf2N\x0b_ \xfb\x81?\xe4ir\xbeb\x13\xed\x95\xfc\xe9\nJ\x11\xfb\x89\xbfO\x862\xe7%\x83=\x87\xa3<\x91\xecX\xad\xc5/c\x0b\\\x9bL\xa3\x0cU\xa9\xec\xf3\x15\x9bH\x07\x05R\x1aj\xc4VfX\xf6TL{(L\xd1rv\x91rx\xcbz\x89^\xc55\xa1\x90Z\xa9_c655\xa1\xa9\x1b\x0c+\xc71\x14 #\xcc\xe5\x04\x11\xbc\x80\xe29D\xdb\xdb\x01\xc4\xa3\xe8\xb2\x96&$\"\x0e\x08\x13d1\x82*N\x14\x06\x7f\xa8_\xcf\x9dD\x939\xa3\\\x8c\x94\xd4\x11\x8f\xfa\x0e\x07\xa5\xdc\x0eP\xbf\x0e\xab;\xce\x80\xb2K\xe0\x8f_\x8f\xb9I\xe5\xacq\xf2\xe9F\x7f9\x1a{\x05\xbd\x7f\xc9\xd8\x8c\xa3<\xdeb\xf3\xedh\xcc\xd2W\xa3\n\x81]n\xc2\x80\x87\xd4F\x7fh\\!\xcd\xb8\x94\x0c\xda[\xa4\xd7\xb2k\xe1\xb6\xea\x9b\x1a\xdc\xfah-J\xb5\xc1h\xcb\xb0\x8c\xf7\x1f/\xc3`\xc7\xd2\xae\xd0\x8aRcP\x95\xbf?]\xef\xa2c\xb8\xd1c\xbd\x9d\xa4\xcbU\x9a`VJ\x0b\x04e\x94\xb6\xf3\"\xcd\x1c\xd6\x01Z\xa0b\xbb\x02\xde\xaa\xd5z\xb1\xeb\x08\xab\xa6\x8c%S\x96\xd9\xa5\xb9\x0c\x1c\xfe\x89\xbd\x8dV+6=I\x93\"\x8a\x13\xaa\xea\xa2\xdc\xbeK\xb6L\xe3\xbf\xb2\xc0\x8fDvr\x91>:F\x1e\xdcJ\xa2\xe5T\x0bfiZ\xbcN\xf8\xda8\x9d\xd9\xf4\x99\x0d\x810\x1c\xe7\x0f1\xf8\xa19\xd0\xdc\x1e\xe8\x02\xc7J7)\xa05\x84\xb5\xfdYd\xdd\x88\x80\xc5\xcb\xba=\xd5Z/\x9a6r\xf6\x02\x0d\xd9(\xc2\xd9\xe2\xf4\x05\xbf\xa8\xe3\x17Tk\xeft\xfe\x02d\xe58\xf3\xfe\x94bf\xd0=\xea7\xb2\xf1uTD\xfa'p\x04\xff$0\xb0\x81y\xbb\xe6\xcc\xdbcj\xbe\xd7$[\x17\xcb\x12\xda\xe5\x0cK\xac\xd6\xd6\xaa5\xca\x01\x11?1\x0b\x16\xb2\xc0\xead\"\x0b\xac>f\xb2\xe0\xc0,X\xe1\xd2\x99\x97\xe4S\xac\xbe2\xde\xcee#O\x9eXC\xbd\x11\xe2\xffc\xf3\xfa|)?y\xfa\xf8\x19\xcd\xe6^\xff\xbal._W+\x1d\xb4C\xe5k\x13\x81\x06\xa3l \x8eR\xa7\"Y=\x9a&\xb9\xad*\xd4\xaf\x18\xf2\x8aM\x12\x1a\xefL\xda\xe1L\xcc\x02?\xeb\x952\xb3\x8a\xe8\xbf\xae\x19\x9594\xe7n\x0d)\x90:\x04\xfd\xd1F:\xab\x19\x06%r\x98\x8b\xda\xdbQ\xfb\xdc?\xb1\xbb!xb\x1f{\xf4A\xa0?\x9224r\xec\xd4#\x07>-\xf5\xd7\"\xee\xc7\xa9Hl\xcf\xe9\x91a\xbf\xf67\xf4u\x0fdn\xf3U\x96\xaer\xf9\xf7$M\n\xf6\xb9h\x81#\xb4\xc2\xf2\xebe\x10\x12\xe1\xd8\xcbb\x7f\xd5+\x89\x9dK9\x8d\x98KC-\x95\x9c\xc2\x0d\x1fp\xc2&\x85\x16\xdb\xa4-\x80\xeb\x8dL\x8eo\x9a_\x7fE31\xe6S\xd1'\xd5\xa3PD?\xbe\x96\xd1\ns\xd0_\xa4\xfc\x04@\xdb\xe7v\xa9\xc1h\xb0}\x9d\xf1\xde\x9a\xba\xc7\xd4\x1f\xf7\x9a|\x0d\xfc\xa4\x8c\xf1D\x146d\xf6Ij7\xee\x0d\xd4d#J\xb2\x01\x15\xf9\xadP\x107t\x1f\x96rl@5\xeeC1Z\xa8\xc5M\xef}\x96\xde\xc4\x9c\x97\xef\xd0\x18 j\xa6Y+j\x82\xe0\xb16\xa3Qn\xf2t_:\xdf@\x97Zh\xd2W\xb1\x81`h$\x0ci\xb4\xf4j\x8c(]r\xc6)\xe7\x8c\x1b=\xa7by\xd9JS&\xd2\xba'\x1670\xc9(\xbd\x0c!\xc3\x7f\x19\x99\x88\xa6i6c\xbc\xacp\xb0\x9f\xc44\x85\xcdc\x830\xde,\xb1C\x9d0\xb8x\x1c\xf58(\x82\x9b|\xeb\xa4\xff>\x14C\xa4\xac\xc5\xda8\xb6\xf6\x93\xe2\x8a\x03'\x12Z~\x8c\xb2G\xa3^\x13=\xb5\xa9J\xb1)U\x11\x14e\xa2\x90\xfb\xe7x\xb1\xf8\xc0&,\xbeA\xa1%o 2&\x81id%\xf9\xa3M\xb8\xda\xbd\x9b\xd2\xd4\xafM\xa4\xa7#y\xdc\x944\xaa\xcb\x06\x0e\xd8e\x1d7\x14 \x8a\xa4\xd3\x96\xa6\xee\x8b8A\x18\xb9n\xdc\xf4\xa7@a#\x0e\xc1\xcb\xd2\xb4p\xdd\\\xa8\xa7\x9d\xa5\xdb\xd8\xec\xc1A\xfa\x1a\xc8\xde\xd7P\x97B\xc9\xedn\xc5c\x03\x8db\xa9\xaaY\x08\xde\xf1j\xe55\xcc}\xde\xabl/x\x7f\xbek\xe6q\x88\xb7\xa2\x81\xc5\xcc\xb4\x1aUTJ\xb3$Z\x12z\x8e\x16\x90{\xd3\xf8\xc6\x92\xe5\xd5\x93\x17w\x0b\xd6\x14\x14i\x15M\xa7\xe8B\xee\x0d\xd8\xb2\x01k'\xe9\"\xcd\x86\xe0\xfd\xff\xa2(r\xe4\xbd\xb3W0\x04\xef\xff\xf9\xdf\xff\xb7\xff\x03<\xf7\xf9\xea\xc5\x9e\x00\\\x08\xdeI\xe9\xa8.\xd7\x96/\x0c\xe6\xbf>\x84\x02\x8e\xc0\xe38\x0f%\xb5\xf0`\xc8\x17\xd1\x0b!g\x0c\x8a9+\xbd\xe3=+\xe4w}b\xb7\xad\xca(\xb5&\xdd\x18f\xb9B[>\xab\xd8o!oW\xdcx\x9c\x7f`\xd1\xa4h\x17.\x9a\x0dI\xf5\xa7\xf3\xd1\xa5\x9e\xf2\x08k\xa7:\xd0\xc2\xdf&N\xfe6i<\xad\x92{\xf0\xb7\xd0*\xd5\xd1'RB\x9eHI+\x9f\x0b\xdd\x89\xb9z6%\xea\xea\xa9\xae\x02:\x9cI\xea\xe9 \xe1&n\x1a\xdcI\xc2\xc5\x1bwz\xda\xd2\xbd\xa8Dl\x01\xa3\x06\x0d\xa8Y\xb5\xed\xde\x1dZM\xfdJ\x06\x95\x91\xb7\x83Yy;\x88\x96\xa9\xe2v0\x85\x17\xc0\x9eC\xba\xbd\x1d \xd7Y\xbb\x1dt1\xb0\xa0\xdf.\xe9h\x9b9 \xd7\xc9TP\xb6XOG\xc5\x87\xea\"\x92\xe36\x89G:d;VL=\xc27\xbb\xc0c\xc6\x8d\x1f\x8e\x99Q\xd4\xddPgW0\xb4\x94\xc6\xf6\x19\x9d\x86\x10\x9b@\x8ag\xe0\x97\xc6[U\xe2\xbf4\x90A+\x13v\x0b\x17w+v*\x12x\xbdcl\n\x11\x88\x0fB(R\x981\x0e\xfd\xa8:#z\xf0s\x94\xc3u|\xc3\x12\x880\xd5\x8d\xaf\x99\x04\xa5\xfcPY'BM>\xe5\xe7\x89q\xe1\x9aZA08\xd6 \xa3-3*\x84\\U\xce\x8b\xc5\xbc]\xe4(\xb0\x1b\xfe\xf3N\xb1\x9f>\xfa\x14\xe0\xcf[?\xc2\x1f\xb7\x82[\xf3\x99\x1f\xf4\x16\xe9\xb5\x0c\xeeR\x9d\x86\xb38\x99j\xc7\x1e\xe70$\xb3Q\x0e\xa0\xd3%\xa1\xdb|_Nx\x08\x89\xff\xe4\x89i\xc8W\xe9\x8c\xeb\x97\x03]\xba\xa4\xaf'\xdc\x03\x99G9^\xb3\x0bG\x89w\xe9\x94\xe5C\x18\xddX\x12\xc2:\x04\xe1V\xa4\x90\xd5w\x10T4\xdb\x16\xb1\x93\x1c'\x838\x94\xd7x\n$x\np\xc4Jz\xf2,\x80\xa1\x8a_\x87\xb1\x89\x9d:\xee\x05\xca\x11\x92\xfd\xec)\xa4\xc6hl[\xfd\xc6\x03\xd0\x81\x8e\x8dwR4,\x0b\xa1U\xd1\x1b4\xb8@\xd26[g\xd0\x84\x1b\xec7\xf1\\\xf5Q\xcbKC\x93\xceO\xd1b\x8cz[\xc4K\xa2\xc4SE;\x8bt\x12-<\xbb\x06[F\xf1\xc2~\xbdL\x93bn\xbfN\xd6\xcb+F\x8ck\x15\xe5\xf9m\x9aM\xed\x92\x8c\xef\x07\xfbu\xce\xa2lBtP0b0\x9c\xef'\xde\x923^gD\x03\xb7\x8c}\xaak`\xdb\x94tN.W\\N*v\xb6\xfe\xab\xce\xb5\x92\xac\xae\xce\xe5\x16p\x04[[\xd9Hp\xce\x98b\x8e\xcf4\xcaX$+T\xe3}p\xfc\x12\xa9\x03\xcf'\\\x8c|\xc3f\xc5\xd0\x0c\xe1U\xabq\x91\xae\xac\n\x19\x9be,\x9f\x8b\n\xb8m\xf3\xb6}\x98\xf5\xac~Q:\xf8\x1c\x9aE\x17)\xfaK\xf7\xeejm\xb4\xee\xc3\xec\xdb\xe1\xe4R\x83\xfa\x83\xc7\xa6u\xbatM\xb7B\xc1E]\xd4W\x9c\x82\xb7\x86\xd6f\xbdY\x9c\xe5\x05\xaa\xf4\xddZ\x1b\x94\x9f\x12\x112\x06\xd3ic}\xferO\x8aS\x1cC/\xeeV\xd5\x89s\x93\xc6S_\xbc\xc7\xa5\x83\xc3v\x0f\x15@`k\xeaX\x8bU\xd2V\xc5T\xfbvW\xf9r\xae\xba\x15\x82{\"a]918\xe2\xc4]\x04\xd3AMy}j\x15\xde\x04F0\xa6o\xa0\xdc\xdd(\x07}\x1f\xcbz\xb3t\xb2\xce\xcds\x86v^~\xf0\xdd\x1f%\xf1\x12c\xdb\xbf.d\x90\xfb\x93t\x9d\x104\xf6*\xcd\xa6,{\xbd\x8c\xae\xd9\xd9\xba@\x06\xbf\xa1\xca\xf9\"\x9e\x10$Y\xab\xf1s<\xa5\x8e\x95\xab\xf4\xf3\x8f\x0b\xf6\xd9Y\xf0\xfb,]\xaf\xc8\xd2\xb3l\x1a'\xd1\xc2Qa\x92.\xd6K\xd7\xdcDan\x17\xcc\xc8\xa1\xcc\xc48n\xe9\x92\xf7i\x1e\x17\xf1\x0d1{^z>\xcf\xe2\xe4\x13]\xf6\x8e]G\xee/1\\\xb1]t\x9d\xc5\xd3\x0f\xd4Xd\xc1iB\x1c\xc5\xb2\xec|\x15%\xee\xc2\"\xca\x08X\xf1\xd2\x13\x84WS\x99\xb3WQ\xec\xeeX\x96\xd3}\xcf\xd2\xa4\xf8\x99\xc5\xd7s\xa2l\x11'\xecd\x11-\x89\xb5\xe7E?9>KW\xd1$.\xee\x88\x02\x1a\xdci\xb6\x9aG\x14\xaa\x14\xd1\xd5y\xfcWb\xedn\xe3izK|\xf0\xd7\xd7\xc9\x94\xc2\xae\xbf\xa6\xe9\x92\x98z\xbcX\x9c\xb9\xc6:[\xa4\xe9\xd4Y\xca\xb9\xd9\x86\xc2,\xfd\xc4^E\xf9<\xca\xb2\xa8\xb1B:\x9b\x91\xdb^\xd4x\x1b\x17,[\xc4\xcb\xd8Y\xa3e\x0c%A(\xcb\xbe\xda\x17p#\xefgv\xf5).\xbc\x10\xbce\xce\xff}\x9b\xfe\x95\xffw\xe6i\x9a\x1e\xa9\x89\xf9\xc4\xeer?\xeb\xe2\xee\x9d\xdauh\xa7\xe3Q\xeba\x0e\x9a:\x11\x13WL\xe6Qv\\\xf8\xfd\xa0W\xa4\x1f\xb90+5\x99\xbc,__ \xc3\x0b\x7f@\xd9\xa4\xa3!\xe8%gf\xf4\xd0\x97X\xa6\xa98\x8d{\xca\xd8\xa2\xf1q\xfe1\x89\x8b\x05\xcb\xf3w\x92i7\xdcs\xf3y\x9a\x15\xf3(\x99*\xad\xd5\xe9\xe7U\x94\xe4\"'\xa3=\xc5\xabh\xf2\xe9:K\xd7|\x8f\xd3\x00\xa8j\x1c\x17E4\x99/\x19Ev\xed\xda'\xb4\xaccW\xc4#\xa4KEA\x8d\xd3\xe4\x7fnR\xf9O]*\x7f`+\x16\x15C*\x8d)\xa1:\xb1;i\x87\xdd\xfd\xc7\xdeiD\x92\xc29F\x81\xa5\x8eC\xba^\xe9\\\x98\xc76W*W\xb6\xfb\xd0~H\x8b\x82\x93\xc2\xa6\x01\x8a:\x9d\x86)\xaav\x1a\xac\xa8z\x8f!\x0b\xf1\xa9i\xc0\xbcF\xa7\xe1\xf2\x8a\x9d\x06\xcb+\xdec\xa8\x1f\xc4y\xd84V\xac\xd2i\xb0X\xb3\xd3h\xb1\xe6=\x86\x8bbg\xd3`/\xd2U\xa7\xa1^\xa4\xabN\x03\xbdHW\x1b\x0d\x93\xf3&\xae\x11\xf2\xb2\x96Ny\x95?FY\x1c5\x11\xca&\xfeG\xafC3\"\xeaib\x87\xd4\xc3[\xf91Z\xc6\x8b\xbb\xae\xf3O\xd7\x05o\xd8\x05\x02Y\xdc\xb2D\xb2V\x0b\xacd\xad\x86\xe5\xf9\x8e\xfe\xe5P\x15\xc4\xf8\xf6\x9b\x84\xaa\xc4\x7fj\x06\xe3K\x85a\xd0`\x1f\xe3\x02\xee\x89\xf0\x80O\xfb\x96\x83\xbc4 \xc2rv\x0b\x1f\xd8\xf5\xe9\xe7\x95\xef\xfd\xe7\xc8\x83m\xc8z\xc7\x17\x17\x1f^\xff\xf0\xf1\xe2t\xfc\xee\xf8\xed\xe9\xf8\xfc\xe2\xf8\xc3\xc5\xf8\xe4\xa7\xe3\x0f\xb0\x0d\xde%]\xa9,\xfe\xdd\xbfXi\xcd\"\"\x1e\xfbZ\x06\x80(_\x96w\xa5\xb9\xf3\xaetkkmG`\xc7\x00\x81\x11\xf1\x9e\xcb\xfd2\xfb\x1a\x1a\xb4\xf9\xeb\x11\xbb\xc4\xb0\xaf\xa8\xdd\x85!\xf8\x91\xf6\xa6\x16H\x9bNs\xdc\xc5\x9e\x10\xf3\x84\xcc\xa3\xfc\x874]\xb0(\x11:\x80\xef\xbf\x87\xad\xaa\xe8\xddz\xc9\xb2xR\x16\xc5\xf9\xbb\xe8\x1dg\xfeT\x05%\xce\x99\x15\x0bx\x01\x83\xb2\xd6\xd9\x0d\xcb\x16i4eS\xab\xaf\x01\xa9\xc0\x03\x89<\x13[\x1f\x87V\xcbo\xa3\xec\xd3z\xf5c\x9a\xbd~\xd5\xaaJ\x13\xd3\xcez\xaf_\x8d\xeb\x88\xc0q\xe0\x90cHj\x85\xb4\xae#@\xce\x8a\xe3\xa2\xc8\xe2\xabu\xc1\xac>\x1d\x8c.f\x9b(\xbf\xf2\x89\xee\x89\xe0\xefM3\xfd\x90\xa6m\xd7\x95\xe5T?\x9c\x9d]\xd8\x93\xfd\xb7C\xcf\xfb\xb7\x0d\xe6i\xf4HB\xd7\x9a&\xd1uXK\xdcK\xf4k\xccT\xed\x8c\x0ePV\xea?\xbc\xfc\xe6\x1f\xc5,'\xf6\xd7Q\xad\xc2\x08U\xc8\xb4Q\x15j ]\x82\x0bF\x8b\x14.\x1f\xa5~\xd0\xf3huc\xe9\x07\xd6\x8b\x14tl\xb3\x0e\xf5\x94\xf6\xff\xe6n\xfc\xf2E\xbcl\xd8@\xfdRE\x1e\xab5\x86!\xfe\xad\x90\xbb\x93\xbe\xb2\xc4\x9d8?Y\xe7E\xba\xac\x16\x15\x01X\x91\x0d\xbc\xc1\x1a\xa2\xf8V\xf5 \x01\xba\xc1*\x1b\xbdtXl9\xc4\\RL\x15{\xa7\xc00#\xc6`<\xaf\x05\xd1\x11\x80ndk\x880\x92\xb6\xe0[a\xe1[\xd1\x8co\xa4\x1f!h8\x94\xf60cW\x9c&T\xbeD\xf5\xf0\xa6\xe2@hw]\x06~l\x913GgP\"x\x8a\xee\xbd\xba\x02\\\x98}\x89\xabb\x13pb\xb9\xe8\xeeT\x9b|\x02y\xf11/\xed>\xd0$Q\x81\xe8\x8eo\x8cK:@\xabzZ\x06\x0e\x9a\xbdQZ\xdfq4\x93\xa4?k\xfb\xa3|\x15M\x1c{\xb5\xfa\xea\xc8\xa0~\xef\xce\xfd\xb5\xc8\xa2\x877\xbc\xe8.O\xed\xe8\xb4\xd3\x8eN\xac\xf6}l:P\xa9\x8c\x8c\xf7\xd8\xa5s\xc4\x8e+|\x9b0\x08Hc\xd0}\x82\x14\x14\x06^Lz\xdaV\xd2(\x86\xdcA\x1d\xf7\xa0\x8b\x0886a.\xf3\x00\xf8\x8a& P\x89\x84\x15\xfaXmH\x15%\xa4\x1a\xc7V\xc7\xf4Mh\x145\x8c\xee==\xf0\xc9\xb71%r\x9e|\xa5\x85\x7fgJ\x94\x06\x9c\xad\nU\xf0\xe3\x06r\x84\x1d\xdb\x04\xc2\xbd\xd9\xab\xa3U' \xee\xddj\x1f\xabG\xc0F1\xb2\xd3\x03\x0c\xfb\x8b\x7f{\x0e\x9fc1J{a\x8d\x93\x9d8d\xc5\x97\xf4>\x12\x17\xe2m\xc8R\xfer\xc8f\"9\xe77\xcaf\x03*lq\xe2\xef\x0e\x1c\x11\xc6\xcdp\xeb2\xcf\x97\xd9\xca\xba\x92\xdc\xb6\x06\xa4\x91lnq\xb1x\xd7\x8bV\xccY\x9a\xa25\xcd\xebW\x95\x0dv\xcd\xdci\xc5\x92i\x9c\\\x7fD\xa3\"\n]\xda\xbe\xc1\xe5\xb7\xb1\xc6\xf0.\x10w\xed\xf2\xcaU\x06C \xf1\x04\xc3\x9aW\xf6B\x94\xfdL\xc5\xb1|\xff=(\x03>\x89\x98>\xeb-\xd7\x8b\"^-\xa8\xb4P\x15\x1e8\xc5=\x82X\xde\x94\xd9\xd8\"\xcc\x81B\x1b(\xf5\xd2UaGEu\xde\xba\xa3\xbbA&\xc4d\xdd\xe5 \xa9\xbb\x1cd#AhG\xe9\xe5\xff\xcb\xde\xbbv\xc7\x8d\x1b\x0d\xc2\xdf\xf3+J\xcc\xacCF4\xad\x8b\xc7c\xb7G\xd1\xeb\xb1\xe5\x8d\xb3\xe3\xcbZ\x9e\xe4\xeci+Z\xaa\x1b\xdd\xcd\x11\x9bdH\xb6de\xac\xe7\xb7\xbf\x07\x85\x0bA\x12 \xc0\xb6<\x93d\x1f|\xb0\xd5$\x88K\xa1P\xa8*\xd4\xe5\xac\x93\xc0\xa4\xd5\x92\xd2B\xdcn\xc1L\x89X\xd0\xcd\x0e\xb1\x8b\xa7\xf9\x197\xa4\xd2\x93\x02\xacPaLU2\xc7[\xf1\x0d\x9e\"\xed\xe7Gj\x82xQ:\x1a\x13\x137\"A\xc3\xa6\xde\x02O{r\xda\x01R\x907\xb3@&\xa0l\xdb!t\x87\xba\xa3#\xac\xb1\xe2k\xe2\xc7\xd3\xbd\xee\x17F\xcc\x12\x7f\xe9\x05\xef%\xa9\xff\x9cW5\x06Mq8\x9f\x84<\xc1b\x19\x99\xecA\xf3\x8c\xd9\x01Nz\xd6\x8c\xe2\x8d~\xb3q_xv\xb8\xf4\x97k\xf0\xc8]\xe7\x9b\xac\xfe\x1b\xeb\xcba\"\xe2\xa0U\xf6\xb6\x8e\xdd\xed\x8c\xbf\x07>QZ$\xc8\x9c1*\xc9\x92:\x89Sn\xb9*\x08\x07et2\x984!?\xf1\xbdI\x8f\xc9\x12\x8eU\xecs\x83\xaeP\xc2\x7fX\xcc\x17EXw\x8d%\x8e\xa20@\xf2\x10\xceoy\xe7\xec\"\xcf|~\xeb\x0e\x04\xdf\x85\xba\x9b\xd8\x0eP\xcd\xb9\xe3*.|\x1ec\xcb\x18\xd5\xe0\x96\x85\xaa5\xd9\xf9_\xc7\xd5kN\xbc'\x92\xa0\xd7\x0dA\xefch\xa8\xa6\x8d\xa8\xf9\x8eW\x13r\x1eu\x16\x99\xbe\xdc\xa0\xc9\xcfF\xb7\x8d\xc3\xee^e\xc1\xa3\xf1\xd3\xe7\xcc!\xc8\xb6\xc6\x06/\x0f\x15\x13\x87\xfa,\xf2\xaaf\xa0\xd7\xec-\xd3\xc6bVmZD\xb2n\xb1\xd6\xc8\x0cY\xe7\xa1e\"\xd6\xfe\\Y4{_Je8\xd2-\xb1\xbe\xdf\xd2N8\xc4\xde.\x99\x7f\xb6\x8da \xd9q\xaf\x19A\x08%Ztex\xb6i*42\xd3N\x0f\xbb\x8e\x07\x9amW\xa5]\x0c\xd5\x15?D>\x13\xaf\x17)G\xfe\xfa\xaaLm7\xb0m\xae\xe7u\x19O\xfbx\xbf\x1b\x91\x80g\xcdy\xd45q\xdc\xf0\xe7\xdd\xfb\x8c\x8a;:\xd3\x0e\x809<3\xdewx\x13 \x19\x93N<==\xb4\x96m\xd6\xab\xf7\x11\xcd\xfb<\x1c\x97\x91\x8fxz\xa2}\x91/\x8f\xee\x88\x98\xc7\x00\xf1\xd3\x0e^J\xb9\xccc\xd9\x92Zi\x8e\x86\xf4b\x86\xb3\x88)\xb1h\x03z\xb9S\xeb:\x84A\xfc4\xa1:z!=D\x11|\x8bI%\xbb\x17\xc2\x0cv]\xbc@Ax\xf9\x0eU\x80\x16\x0d\xa3\xbcu\xbc\xd6\xe6nP\x0bg\xab\x85\xf2\x18\x9e\xaf\xc8\xec\x12\x03K\xf1\xc05,\xf55\xe4\x0b\xf8\xbf\xe8\xa3\x05\xbb\xe0\xfd\xdfH/\x9a\x82Q\xb1\x03\x8a!\xb5A\xac\xf5\xf3\xe8<\xbf\xceHI \x87\xef\xed\x1f\xeeyMX\x89\x04\xd5\xc9\x13 \xf2\x10f6\xae\x98\x16MV,\xb6\xec\xc8\xb7\x1c\xc1\x86#\xdc\xab\xac&e\x16\xa72|\x8b\x8f\xc1%]<`\xc4\xac\x1a\x8cQ3p\xdd\xbb'NPf\xf5\xda\n\x95\xa5\xffF\x8dfK9\xc3&\xa4\x8c\xcb'%\x0b%(?\xea\x03\xc9g\x10\x088\x082r\x0d\x15\x9b\xae/~\xb3\x1a~\x1e\x04\x11\xe7\xb2)\xa3\x83\x87}\xd6zr\x04\x19C4\xbcr\xcb\xe7]r\xc16\xae)7\x99\xc7\x9c\x12\xba9\x89\xdb\x0b\xc3\x9d+s\x0c\x1c\xe1#\xb5G\xec\xd8\xf7\xc2\x86\x02\xb4q\\\xde^\x9c#\x00\xd1p\x8fy\x8f\xcbGk\x96\xc1\x97\xb9)w\xf3+\xd1\x92\xfb\x95\xea\xbf\x98t\x05\x86s\x16\xc9\xa1N0g\x8a\x1a\xe4l\x02\xcd\xadC7\x81,{\xf3uN\x92\xef\xbay\xd6\x94P\x17}\xd4\xfd\xf3\xdb\xd3\x0f=\xc7\x00Z\x9e\xbf}\xfd\xee\xed\xe9\xab\x0f'\x13\xd0\x88\x02'\xaf\xdf}\xf8?\x138\xe8\xbfY\x92\xfa\xc3M\xe1\xc4\xb8\xb7/~;'\x01\xdd\xe8\x11v\x83\xea\xea\xa4\xfak\x9c&s\x11\x15\n\xd1\xd6\xb0 \xf8\xbeN\"9\x05\x98@\x12\xd1\x99\x8a\xa4g\xa5\xef\x1d<\xd2'o\xec\x88\xd4\x067\xf1/\xb5=`\"x\x1f, f\xc68Y\x17\xf5\x8dD\xa4\x97\xf1\xac\xce\xcb\x1b'\x88R\x92o\x9bR\x1f;\xfa\x8d\xb1]\xe7\xd4\xa5\x90\xa7\xed\xb0l`\x90Dl\xa2\x94k8\x82<\xbcS\xd8\x9a7\x07\xdf\x05,Ve\x0f\nm\xf5\xf3\x95\xd6K\xdcpL\xd8\x00\xc5\x81\x94S\x04\xa7Tk\x9fR-\x86\xa9\xdc~\xc4v\xd5\xaf%\x83\x8e\xddb\x82ZK\xfbI\xf5\x01\xdd;\xc6M\xa8\x15\xc8&\x19l_\xac\xb7\xce\xd2\x88\xbd\xfc\x9f$#e2\x93cx\x9e\xc6\x95\xd5! \xf8\xd2j\xb0\xbeO\x9bX?\xad\x89:w\x92\xb8l-\xf9\xeb\xeby\x19\x9aQ\xfb\xe1#\xc6\xe1\xef\xf7rj\x08YB\x97\x81S\xec \xff\xa0\x9fiD\xd1\x94{\x91\xa7\x11,\xbc\x89\xe7.\x08H\x9c\xa1\xfc\x8b\x86\x7fW\xef\xceItIn\xe0\x18\xe2\x88T\xb3\xb8 >>\x08P\xc5T\xe7,G\xaa\x7f\xf8H57\x12\x7f\x8d\x89\xd9\xd51=\xa2\xc7\xc6\x9e\x92+\x9e\xa7\xa9\na\x16\xea\x13q\xd2E)BLr\xc2gQ\x1b\x04 %\xd2\x1e\xe5\x00\xd1\xb7\xcb\xbb`\x92\xaaxD\xf9\xaa\x9a\x13\xa2&\x94\x9a\x88\x94\xd10O\xbc\xae\xc26\x89'\x0dTy\x17u\xf4\xcd7|d\x18\xf4Or\xf83\x7f\x81 \xf1\x85p\xa2\x07\x8b\xc6\x0e\xa3\xf7\x84\x13\x94U\xeb\x05\x86\xda\xf0\xbc\xae\xb9\xc5\x97\xfaA\xb2\xd0\xa9h\xcb\xb2 \xa1\xc2tn3v(\xeeuo\x7f\x17\xec\xf6\xf7Q'\xe0%S\x7f\xe9N\xad\xc2\xec4\xfe\x92\xd7Q\x04lq\n\xf5\x177k\x02\xe4\x98\xf2\xa9\xf5?\xa2G\xbb\xb4!\xf6\x98\x07\x12\x06\x89\x0c\xa2\x92\x14i<#\xfe\x83\xe9\xc7\x8f\x7f\xff&\xfa\xe3\xee\xb1\x1fL?\x9e\xfdr\xfb\xf9\xec\xc12\x04\xef\xe3\xc7o\xeeyJ\xb5vW\x9f\xa5oT\x10\xfd\xf1\xd8?>\xfa\xf8\xf1\xa3\x1f|\xc6m\x1b\xed\xf2\x07g\x01\xb6\xf4\xcd~\xf4\xc7c\x86\x18\xdft\x03\xc2\xeb\xbd`\x85~\x8d\x8fV\xa7n\x96\x06|hF\xdc\x0d\x10?\x184X\xd8,\xef\xb7\xbf\xf9]\xff\xaf\x8e\xb2\xae\xe1*\xd8\x11\xb3(\xf3\xb5Qm\xf2:\xc6T\xde\x85\xff:.Z\x06|\xaf\xe3\xc2AQ\xd3\xaa\x85\xdbL\xb6\xd6y\x1e\x18\xdb8%5\xfb\xe8\x94\xd4\xad!\x9c\x92\xdaa\x08\xadZ\xca\x10\xfa\xcf{q\xa4\xaex\x92r*#\xbc\x8e\x8b>b\xae\xf8\xcbS\xd2am\x9c\x12\x9a\xcd\xa3\x8a\xd4\xecm{\x0d\xc3v\x0e\xea\xa1\xe5\x9fGK\xd2\xd7@\xb3D\xb8\xc3\x0d\xcc\xb9i\xa0\xe6\xe3\xd8\x16T\x8ew\xde\xe0\x8f?g4\xb4g\xa1\x85l\xf2\xf0@VQ<\x9fkF1\xecx\x0e<\x07\x83a\n\xd6\x98\x94\xfd)\xac\xf4Sh6\x94\x8e)\xba\xe2\x99\xe6\xbb\xee\x07\xc0\xb3\xf2\xe9\x9e/\xad\x13\x03Eg\x1a\xe9C\x1ai\xda\xbd\x19\xd3.&~~\x95\xd5>\xe1\x1e\x9b\xfe>ej\xf74\x8a\x8a-P[\\\xdf-\xb5T\xef\x8ae\xc8\xac\xc7c\xbd8s\xf4\xed\n\xab\x8bi}6~?\x0c7\xcd#.\xe9\x9av\xdd-*\xafq\x15D\xeb\xb8\xf0o\xb6\xd8.\xc3\xe3\\\xb3l\xf8\xddD\xf9.\xbb\xc9 \x00k\x0d\x00\\\xf7\x9a\n\x80\xb5\x1e\x00\xbf\xeb\xffE\x87E\x05\x85\xe9\x99\x8e/97\xf3%yo\x1eF\xf3\xa8+\x99\xc2y\xb6J\xd2\xf9\xab\x17:\x99\x0c\xc3Oe\xd2\xab\xfa|\x8c\xb5\xd7\xb5E\xc8\xf6>f\xd8G\xc6B\xd13\xcd\xffO\xd9e\x96_g\xc8s\xf8h\xc2\x0f~\\\x03c\x80\x16I\xca\xa2\xf2H\xd6\xe6\xef\xd1\x1f\xa7\x1f?~|p\xf6\x80Y\x1c\xef\x827au\xd3$#\xccM\x9a>\x0c<\x14<\xb19\xa69\x9b\xc3\xc5\x0d6\x9b\xc9\xf7\xaa\xf3\x87nB'}\xb8k\xf4\x05\xde\xef\xc9\xba\xa8o\xb0\xc1q\xf7\x1b\xde\xefk\xf2\xa96}(\xd4\xd8\xfc\x8f \xff#\x9a'U\x91\xc6hY\xca\xdc\x98\xf0i\xc6\x7fJ\x80\x0e\xce\xec\x93\x01\xa3B\xc4\x90Sz\xde\xbeh\xba\xd1Z\x97\x94\xa2b\xa3\x91\xefW\xcaE\xa5\xb7\xd7\x19)_\xbd\xe8a\xab\xd4\x8b\xa2\xe5\x8c\xae\xef<\x08B\xb8\xc6\xfc\x91\x80\xb1\xc8\xcf\xab|S\xce\xda\x1cE{'\x9d\xf6\xb4\xb6yvJXH\x9d\x92dcL\xab\xf4\xd6\x92\x14\xd03\xdf\xdb\x7f\x88\xd1\x923\xb9\xa1\xe8\xee\xeaW\x97\x92z\xc9$\xf5\xb2\xa5\xbe(\x87-\nY\x8e\xb9\xd2\x90Z\x1f\xb8\x0e/\xf7\x13\x93m\xa1\x1ck+:\x7f\xdc\x8cY\xaf\x8c\x8b#\xc2\x83\xf9(\xcch\xeb!6\xbaO\x1b\x8d\xa3\xa4z\x9do2\xba\xc9Xo\xdf\xed\xb7;+\xe2\x92d57\x90R~\x1ea\x8cr\xe5\x01^\x8e\xca\xd6\x0f<&\xec\xc9\xf7.\x176\x1d\xd5h\xf6\x03Y\xe4%y\xdd\xbaAu3\xe7/}c\xb8H\x0e\x87 h2\xaf\x03FSc\x03\x9e@\xa6\xaf\xc0\xec\x9e\xcc\xf6oby&05\xac\xbd\x84\xb9\xd9V\x8f\xc55\xe4\xc1s\xc6Z#\n\xc8\xfd\xc4\x1b\xd1\x83n\x9b\xddC1JA\x194\xfe\x91\x98\xd5\x8bb\xd5\x1b\x96y)\x87N|\xfd`\xea\xf6V\xae\x95a1\x97Va\xf1\xa6b\xf0\xc6r\x95\x92g\x030\xdbf\x8c\xa8\xc7m\x01\xac\x8e\x94\xb5\xdd\xdd\xb5\x8c&[\xdf)\xc8X\xa4\xc7\x16\xa4\xf6\xf5\x90\xaa|\xa2K\xc7x!\x82\xf7\x0f\x8d\xbb\xd8\x94K\xc2\x87N\xe6r\xf0\x95\xc5\xd5\x14\xc3j\x9eF\xe7EI\xaeHV\xbf\xdb\x94\xcb$3*j[\xc9\x94\xf6\x9e\x02\x81\xef\xe1B\xd2fb\xa6\xcd\xb4\x9c\xfb\x17Sr\xe6\xaa8\x03\x9c\xf8@\xd0\xfa\xe1[\xdaf\xb7\x7f\xc9\xe2 \x85\xcaN\x17\xa9\x86\xfa^\x92\xfa9\x8f\xecW\xc7\xb3\xcbg\xf39\xc9\xe6\x9b\xb5\xebHtVO\x836L\x82~\x9c\x0c\x86\xaf.\x99\xe5$Z\n\xe9\xcf\xbe\x1av\x8f\x18\xeb@\x1a\xae\x81s\x11\xd2*\xcav\x9e\x80\xa2\xe4Z\x88\x08\x87\x06\x8aL\xc1N\x9b\xcf\xa3\xf39\xb9\xd8,_\xbd0\xae\x00\x8e\x0d\x99\x9d\x16L\x7f\xb8y\xf5B\xc4\x9c\x17EcB\xdb\xfd\xc4\xb6\x14\x12\xcd\xf9z\x00y\x1a\xb0!|B\x8e\x9f\x08\xce\xeb\x1d\xdf\xbcC\xc8\xd3\x15i{\xb8\"\x8f.7\xfc\x18\xc4T*\x124\x12\x0b\xa6\xf5\xb4t\xaf0\x8f\xae#\xe8\xf0\xb1\x83\x839q\xf3)n\x1at\x1d\x84\x03\x18\xc4\x19\xe9\xd4=g\xb9]\xbbw\x87\x01\x12\x0e\xb6\xefpT\xecO\x89\xf2n\xa3{'\x19$\xb7\xe19@G\x1e\xcfk$Gi\xff\x15Y&UMJ\xc2\xe8U\xdc\xe5@\xaa\xd5\x9b<;\xad\xe3l\x1e\x97\xf3\xbf\xc5e\x96dK$\xbe\x0e\\\xb0\xf1FB\xa4>,I(\xf2\xc2N\xaat\xd8\xecH\xa2N2\x94;\xb5/\xc6\x86\xda?\xc5\xa7\xdb\x1b\x010G\x97\xeeu\xbf\xde\x9e\x969\x1b\xba\xe9{\xa09gH\x14\xcf\xe7'T\x80\xfc\x91{+2'\xa8\xeeSn\x1e\xb6\xb3\xaf\xb5\xadn\x1a]\xe7Wc\xd2\x8a\x08\xff{C_c1\x90\xc5\x9b\x881\xa4'6\xc9'\xd3<\xf0=\x8a\x00\xbb\x0c4w<\x959\xd1w\xb3\xcd,L~\xb5\xfd\xed?\x8b\x8bzS:\x06\xee\x80\xedW~\xef\xae\xc15\xb0\xf2\x9a\x8bKQ\x06`f\x1f]\xa9\xff\xd8\x05\xcc%\xe7\xa0^\x88$\xba\xeaL\x8d\xe6\xdf\xad\x84kwA\x0d\x1e\x1f\xe8\xc2\xf8\xd1\xe7\xfaP\x11\x87\x8f\xba\x99\x00\xb8[\xddw\x07A\xbb\xfd\x8d.M/\xf3aM\xf2\xecy\\\xc4\x17I\x9a\xd4\x89=u\xc2\xd5\x97&\xa0\x80\x8e\x14\xe6\xb7SQ\xdc\xbb\xc7\xb2Ox<\x8d\x00^\x1b}\xfe\xdcKI\xc1\x9e\x95\x1b\"*\xceXL\xff\x93yR\xc7\x17]\xa7`\x93\x03o\x92g\xaf\xb2E^\xb2(\xf4\x16\x0c\x17\x1a\xb6x`Jz4\xc5\x18\xfb\x04\xdd>\x8c)\xbe+1\xa0\xf7\xccc\x1c\x03\x1cj\x97\xc8G\xb7\x91M\xa4\xce\xc2'Zy\x1el'nI\xaa:/\x89l\xc7i\xf9\xd9\x05[lJ\xda\xc3tZ\xca\x9c\x0d\x13\xc6j\xedi\xeb\x14\xed;G\x9c\xe9\xc7\xab\xb52\x84\xdc7\xe5l`\xa1\xe30!\x90\x19z%\xd6\xd8D\x95\n\xbe2\x84*\x08!\xf1\xcb\xe1\xd0E*\xcc\x9d`\xa5\xd7\x1azr\xda\x18l\x1e\x13Q\x90\x007\x96\x1e\x83*\x16\x93^\x81\x17~\xa8\x87,\xc9\xe6\xad\xaa'\xd9\xbc\x8f\x15\xfd\x81I\xebP ^\xd9B\x7f\xb3\xab\xbb\xd6\xb4\xf1m\x12a\xbf\x1f\xee'\x87\xb8`\xf2\xf5\xcc\xb8\x8eD\x08*\x01\xf7\xb4\x12\x18b>)8\x10\xefg\x11=1\x10\x80\xbe7[\xc5e<\xabI\xe9\x85p\x9f\xa7\xf9\xe2\n\xee\x01\xb1\x04A\xcc\x1b\xa2\xcc\xe3`3\xdaV4Y\xfa\xb9\xddR-\xd2]\xbd\xc5\x98\xf7\xd5\xb0*\xe1\xf3\xe7a\x941\x98\xb8\xe3\x04F\xaa\xef+\x03\xf2[n\xd0\xea\xa82\xe3*3\xbb$\x99&\xd6\x15E\xc5V\xaa\x7f\x91\xb6\x9b2w\x86\x1d\xd4\xdd \xb4v\xd8\xd9\x0bp\x04\xaf\xe3z\x15\xad\x93\xccG\xa7\xad\xd6b\xfd\xc6\xfb\x02\x1dt\xf86\xf8@>\xd5\x83[!\x89fy\x9a\xc6EE|d\xe1\x12\x13bg\xf2e\x0fYs\xb8\xcf_\xb3Y\xe9\x12\xcf\x8aH[\x95\x82\x93CQ\x94\xf4<\x12\xcb/\xb8\x15\x8f\xe4\x96\xe2\xa6\x830>\x01\xee\x8d\xd9q\\\x11\x02\xa2XO8n\xfe\x14\xdcy\xd0\x84\xe2\xeb+B\xf5\xea\xa5\x86\xf7\x9e\xd5\xc9\x15Q\xf2\x08\x91\xe8\"\x9fwRH \x81z(\xbc\x8f\xee\xbb\xdf\xb5\xff\xda\n\x9cW6\xef\xdb\xc7z\x86\xb3\x17f:\xd6\xfb\xea\xb2(\x0e\xfb\xdfv\x1b\xafZ.^}\x0f\xaf\x94\xf5\xf2\xb0+\x15\xcf\xf8\xf3n?\xcc8\xfe\xf0\xdb\xee\xf3\x82\xcf\xad\x1bub\xce\xfa\x17\xe1\xb0\x1f>\xea\x0e`\xc5:z\xdcy|\x85\x8f\x0f\x0e\xba\xe3Z\x8364\xdb\x92u\xdf\xcb\xdfu\xc3\xb9\xf6n3\x17\xaa\x03\xdb\xfe\xc3'\xddQ\x9d\xf3\xee\xbb\xd3\xb9n\x1c\xdb\x92~\x00\xe4N\xe5\x13\x8cQ\xa6\x8b\x1f\xdc\xaa\xf6 \x8e\xba\x9e\xd2\xa7p\x04O\xda\x8f\x9e\xd3Z\x9dj\x97\xc68\xde\xcf\x8c&h\xcc4L&\xcf\xa2\xbb\xf6\x14\x1fu\x93qMZ)\xc8\xba\xac\xae\xce:\xec\xad\xb9Sz\xb6\xca\xa0\x80\x8c\x84\xabO\xfck\x96\x8ew\xd8\xfa\xec\x9d\xd8n!\xf2\xa4\xdd\xbe\x90\x96\xb7\xa9\x06%O\x8b\xa8\x9f5\xdbtv\xc6\xe6\xe8=\xec.\xd1\x14\xf2\x03\x8e\xc0C/~\x16\x8ck\xc2L\x155w$1\x1cC\x0c\x13\x88\xbb\xf6x1\x9a\xe2\x05\xa1T\x95\xd5\xc9\x9a\xf4\xaet{\x13\xa6\xfb~\xd5\x89\xf3@\xc1\x94\x85<6\x01w\xa9D\x07\x98n\xf8\xa8DU\xcd\xd1\xfe\xe8Q\x95`\xc8\x81s\x16\xbdC1\xa0\x88\xcek\x0eD\x1e\x0e\x89e\x87\xffQ\x8d\x88\xf0*\xabsLa\xbd\xc1\x85\"\xb8P\xd9\xb0\xb5\xe4\x07eUuKJ\xc9\xe3:B\xe0\xbe'\xb3<\x9b%)\xf9P\xc6Y\x153\xfeuI\xeawy\x9e\x92\xb9\xbf\x83\xcc\xc1,\xdaT\xe49\x9e\xe6|\x01;\xb3\xce\xa3\x82\x94T\x02\xf5\xdf \xb1\x11\xe4|\x10\xe1`\x7f%I \xe5)\xf2\xe1i\xbd6\xe9\x8d\xf0*d/\x84U\xb4\xc94\xeb\x86\xd6D\x9d\xed)\xf8\xec\x9e\xf4\x15<\x85\xbaI\xfb\xf74\x80\x9a\xab\x81\xf0\xb7\xaf\xbc\x1b\x1e\xec+\xb3\xa5\xf0\xb3\xf1\x96\xc2U\xa4\xcbj\xae\xf3Q\x13f%t\xe9>\x7f\x86\x9d,:_\xe5\x15\xbf\xdb\x18cC\xfc\xb3\x91\xf4\xec\xf8;\xdc\xdeU\x02u\x07\xfd\xde$\x1f)\x9f\x9dj\x9e=\x1f\x06\xdc\x1b3\xe0\x1c$U\x0e^=\x9b\xce.\x88\xef\xdd\x1b\x0fN\xdc\x06mX\xf20{\xfd\x9bW\x93e-\xbb\xf6\xc2\x16\x9e\xe7Y\x1d'\x19)_e\x8b\xbcO\x05z\x07\x83\xf8\x8bN\xf1}\xffl{a\xb3\x88\xc7\x08R%^\xbe\xc2\x11\xbc\xefZ\xa95\xc3}\xa1\xf8(%U;\x88\n\x0f\xe7\xf9\xa2\x15\xd9\x06\xe3\x11\x0d\xf4.\xe6N\x07\xa0\x10\xfdfn\xb4A\xde\xd3\x87\x1e1T#\x82\xd2\xb9\xff\xd8\x93\x8c;\xdfL\xe0E\x87\xeb\x10A\x11\xaa\x1fn\x18\x01B(L\xe0\xb2\xc3\xd4a\xa2\xd4\xd7y\x96\xd4\xb9K\xc4\xc7\xae\x84\xd1\x112\xcf\xd9\xbd8\xedl\xc0\xd2U\x7f\xe8B\x03\xb6\x1f\xa3\xd6\xb8\xfc2\xb4\xab\xaf\xaf\"\x92\xfdcC6\x82T\x8b\x00\x19\x92x\x86L\x08\x95\xf5\x9e\xc7iz\x11\xcf.\xd5\x8a\xb9F~\xa2\x87\xd8\xe0\x9c\x196\xbc!\xd7\xd6ik\xe7\xfc3\xcf\x19R\xfa\xde\xe1w^\x10\xc2&\"Y\xb5)\x89\x92\x14\x97\x03\x02\x93J\xf77\xab\x10=1\xde<\xc6\x13\xee\xd6XG\x17T`!sf\x0dQ\xf9\x1f\xd0\xacY\x8cJ\xdf$\x0b\x8c+1\x89o$#\xad\xb8\x9c\xc6g\xf4\x8bp8\n\x07\x83\xd6\xe9\xe6\xa2. \x9e\xf2\x92(8C\xacc\xc6\x82\\`\x11\xadbT\xaerH>\xa6\x90\xfcQ0\x1f\xba\xee\xd4N\x1c\xd6\xf7\x8bF|\x15]\xc5i\x82&#\x1c\xeb\xfc<\xe4|\xde\x8b\xb7\xaf9A\x11\x96\xec\xad0C\x0dr<\xf1B\x93\xad\x8c\x07\x94\xaa\x93\x18\x83\xa3\x15qU%\xd9\x12b`\x95!M. \xfca\x9e\\\xfd!\xc4\x97\x80\xfdr=\x85\xe8\x07\xdf\x07\x90\x97\xf0\xfd<\xb9\x82\x07\x7f\x8a\xd0-DL\xd0\xb1\xc7YJ\xdb\xc7\x0e_\xe6\xf9@w/\xf3\x9cu\xf62\xcfEg\x99\x1a\x03Z\x89U\xc6\xf9f\xec\xf5\xc3*\xa9`\x1d\xdf\xc0\x05\x81Y\xbc\xa9\x98W\xcd&K\xf0\x02!\xc9\xb38Mo \xcd\xe39\x1dP}\x9dC\x92\xcdIA\xe1\x9b\xd50\xcb\x8b\x84Tt\xc8lL\xdc\x07\xc7\xb0\xa5\x98\x9fX\xdc\x19\xf9\x0b\xd3m\x1bR\xf8 h\xe2\x9ci:\xb0\x9a\x9fRq\xbb\xe0n\xa7\x06\x05\x122H\xe7E\x99\xcfHU!o\xc6\xc3\x99\xfaUt>c\x7f\x1a\x15B\xf4\xeb\xa5~\xe2T\x92\x7f\xe3\xeb\xf2d`\x12\x8c\xa1QSa?\x1d\x12{\x0cSY\x80\x7f\xee\xcf\xd8\x15\x80Y\x07L{X\xb0\x1e\xfaB\x05\xe5\xde7\x17i2\x93\xf1\xbb-\x96)sa,k=[\xd4\x9237\xf3\x85\xf9\"\x14@\xab\xa1\x17E\x9eq\xba\xc3\xd2O1\xac@\x82\xa4d\x1e\x84\xb0\xd0\xb6\xa3\xbfk\xfd\xb1'\x07<\xc3\xd8xvS\x0e\xe0\xc0]!\x1f\x99\x19\x00\xb7\xa6\x12\"r\x84;o}\x93\x82\xfd\x06\x8e\xe0\x95\xb1\x89\x0b*\x82a\x13)\xfe\xab C\x00\\9\"\x89w\xf7d\xa5\"a\x16\xc2E\x08I\xe0\x88\x08\xc6C\x8b\x1bK\xe3\x92^\x07!\\\xdb\x8f.\xb7\xfb\xfcf\x95\x07N Ud\x1c\xce\x08\xa2_X\xdb%\xd6\xcf\xcd\x81\xf8p\xcfD\xe6j\xdc\xed:\"\x83\x8e\x0c\xc6T\xb5\xaf\xd0n{_Q\x96\x7f\xe0\x01\x020\xd4D\xa3\x9191\xd0/!V\xed; '\xaf\xcb\xddc/\xa7u\x8f/9\x0b\xfb\\\xcek\xa1;@\xeb\x98\x9e\xb7n\xeb\xa7F\xf7\xa0;\xde\x93\x10b\x1dD(\xac\x14N\x8e\xb9\xa5\x0d\x86c\xdd\xe0^\x1b\n\xee3\x8ffq\xf6\x9el*\x9e\x19\x8a\x8eb\xd3\xc92C\xc5\x0b2\x8bg+\xc2v:\xad\xa1oQP\xf6M[_6\x8f\x9e\xff\xf9\xe4\xf9\xff:\xfd\xe95\xaa\x16\x99\xf6Q\xdf\xc2\xa6\x97\x93c\xc4\xc7\xe2t\xd8D\xf9\xa6&\xe5\x9f?\xbc\xfe\xd1\xd4Ke\x1b_\x08\xdd\xa8\xbc\xa2\x88\x13b \xb5Q\xe1\xe2Y\xaf\x16\xe9\xba\x90\xa9\x97O\xe2\xce)\x94\x9e\x94A\xa8\xfaWf\xcc\xb1r\xb0e\x10\x8c\x80H\xf5\\\x06\x9c\xe1\x91\xbf\xe5j\x1b\x1c\xec\x85P\xc0.\x1c\xec\xa1S\xf4\xc7\x0c\xfc\x8a\x94W\xa4d\xd5g\xe6\xea\xfa\x99\xe9tWtg\x1dx!h\xaee\xfb4\x03\xb5K\x86F\x0e\x19\xaf\xdd\xd3\xef\x19P\x81\x07\x98r\xd5\x90\xe9'\x94GIV\x91\xb2\xfeP\x12\xc2\x1c\x1b}F\x9d\xe81`\xe4\xd3.X\n\x80P\xb3\xd3kE\xab>\xf2:\xefG|\xfa\x85\xf7O\x87\x8f\xbe\x0d\xf4\xcd\x9b\x8f\xa5\xc6\x0fH\x03$TM*\x1a\xe37|\xed\x98\x95@\xd9DS}\x1a\xa01\x8fN\xb9l\xd0A\xb1\x060\x00\xeb\xb1\xf6;\x98\xc8Z,\xe4+\xcf\xeb\xd7\xb3\xf8\xfb\x82\xab\xbb::?'\xd5\xeb|\xbeI\x89F\xcd\xc3C\xb2f~\xf7\xea\x0d\xc3\xe7b\xbc|4\x7f)\xd5f\x8e\xa1\xd4Z\xd8\xcd\x859\\\xdb\xb4\xeeV\x1d\x0d\xaf\x83r>\xff;\xaaVqA:f\xd3t\xe7\xce\xca\xe4\x82L\x94\x8at\xfa\xa8\xc2\xfa\xc7&)\xc9\xbc=\xe2yR\x15\xf4,v\xfe\x80\xf9\x94\xd5C=4+\x10\xdc\xe1\x12\x84-8\x98\x11W\x7f\x0b\xcd\xaf<\xc0\x14\x16I\\\x89\x90\xb2\xccK\xf5\x8e\x04\x1f\xf4\xb8.\xfd\xddt\xbd*\xf3k\x8c\x80t\xc2\xbfj/\xa9\xde\xbc\xdb O\x95\xcb\xe4\xc7\xdd\x1bJ~\x9b\xdc\xb3S\x14\xa9\xae\xba7\xa41\xaf\xdf\xc5\xde\x0d\x7f\xdem\xbf\xe2\xcf\xbb\x17\xc0\xfc\"\xb9\x97^\x80_$\xf7\xd2\x0b,\xf8\xf3\xee\xc5/\xbbH>x\xa2\xbbH\xce\xfc\xc3\xc7\xddy\xb1\xfb\xe3\xfd\xc3n\xfbW\xbc\xfd\xee\xb5\xfa\x9a_\xabw\xdbY\xf2\xe7\xddy\xb1\x1b\xe4\xde=\xf4\x05\x07\x7fw\xba\xe7\xbc\x99\xeep\xae\xf9\xf05W\xc4\xb4zw\x94\x9f\xf0y\xef\xda\xfa\xb4\xafN\x7f\x0eG\xddh\xda\x97p\x04\x0f\xdb\x8f\x9eQN@\x04\x00|V.\xf1\x12\xa9:\xebD\x18|\xab\xd6\x12\xa1\xeb\xba\x95\xde\xa9\x950\xf4n\\\xe7\xa5\xa9\xf6\x07\xb5\xb6\x88<\xd8\xae\xf2\x9a\xdfb\xcb\xdf\xd3gg\x94g\x9b*\x03.\xe3\x9b3O\xf7\xf4\x87\xcdbA\xca\xde\xbb\x17q\x1d\xff5!\xd7\xbd\x17<\xc7\x87\xee\x03\xd2{\xf82\xcd\xe3\xfa\xf0@\xdf=\xbe|\xf4P\xff\xf2UV?6\xbe\xd9\x7fd|e\xea\xecu\\\xf4\x9e1\x17\x14\xf1\xf8C\xe7-\x8b \xd8\xfb\xe8\x94\xd4\xfdg\xc8\xdf\xf5\x1f\xdf\xac/\xf2\xb4\xf7\xf8\xa7\xc487|\xf5<\x8d\xd7\x05\x99\x9bk\x98\xa6O\xdf\xb5\xe6O\xc9\xbc\xf2\x1e\xc9\xa8\xf8\xeam\xe7\xe3\xbf\x91\xf8R\x02ig?\xd4262,\xef\xab\x10~\x0e\xe1M\x08\xefu\xb7w/B\xbc\xbb\xc9\xe0\x1e\x9c\xf6\x99\xeb\x9f\xf8\xab\xe7\xfdW\xff\xe0\xaf.\xdb\xe7\x03ei_\xe1%\xee\x0b*\xb5\xc31\xbc\xa2\xe3\x90#\x98\xd0\xdfA\x10\xaa\xda\xd3\x17R\x84x\xd1ol\xe7Z\xcd[\xdaa\x9e\xe8\x0c^\xe2\xbdBWJ\xa5\x9f\xbe4\x89\xc1thW~M%\xee\x1fe\xd3\x18\xd5\xf7E\xf7\xe02\xc4\xbf\xa5\x1d\xff\x13\x8e`E[\xe9\xbd\xa5\xe5\x078\xa25\x8e\xe0-\x15\xb8\xf1\xafwz\x05\xc6\x85:\xc1\x8a\x8e\xe2G\x83\xaa\x03[\xf9 \xdb{F\xff\xfa\x01\xb5ToLr\x81\x98\xeeO\xac\xee1\xfcr\x0b\x13Xv'\xff\x13\x1c\xc3\x82v\xbd\xf1_0\x1d\xe7\x04f\xf4w\xcc\x7f\xf7\x1a7\x82F\xf4\xba\xf3z\xfa\xcf3\xd9\xc1\x1b\xee/\xfb\x8bA\xefH\xc7\xb8\xa6\x1d\xfe\x93N\xbf\xdf\xdb\xef\xcc\xbf\xde\xa3\x0d\xde{`!\x18\xcb\xa0\x8f\"\x7f\x85#x\x8f\x9aj\x1d\x9a\xfcU\x0e\xf2\xaf\xfd\x97\xef16#bF\x88~\xed\x0d*\xca\x08`\x92}\xe9\xd9t\x00\xde\xdcbXC\xbf\x14\xbb\xb1D&\xe7}\xd7\x12<\x08u\xe8\x7fn\xeb\xd2p\x9f\xf3\x02\xc7\x9d\x87\xa0t\x9c\xbbvLa\xf6g8\x82\x7f\xc01b\xc6\x1c&P\xc0\x04\xff\xbe$7\xd5\xab\x0c\x03\xe2\xf6:\xfd\x1b\x1c\xc1K8\x16{{\x02\x7f\xee\x01\\h5\xfd\xbf\xd1U\xab\x15\xde\xcf4\x93\xbf!5)1\xc6\x13z\xe8\x9e\xa1%\xfd\x0b\x9c\x8f\xdb\xec\xe4\x93\x91\x1c\xe7\xc1\x93.\x87$8N}\"\xaa\xef\x1e\x8f\x9669<\x12\xe6u\x81W~;\x18Z\xbc\x95\xeb`\xe4\xb8\xf7\x1f\x1b\x92\xc2\x1ety2\xce)?\xd6g\x85=x\xd2}\xbei\xc2\xf62\x0f[\x11A\x97\x1d\xa0\x15%#\x83\n\xdfV\x94\x8d\xe9\x19\x8b\xb2\x81\xce[\x14\x04<\xcc\xc6\xb0{{{}a\x02\xb1\x1e\xe8N\x06\xc1\xeab\xeb\x81v\xd8cX\xb9{\xd4\xf6\xab\x8d\xcb\x9c\xb4\xaeuG\xae\xf0\xe3\xc7z\xcc<\xec\xc9H|\xb0\x8f\x0f\xb7\x1dl\xe2+\xa9\xa0\x99\xc9\x18&\xec\xf7\xbe`\xf0]4\xcc\xa5\xde2\xfed\x1b\xa6\xfeF\xa3Q\xa3@\xaeZi\xd7\xa8L\xe1Z\xc6\xfb\xb0\x0f\x13\xc0\xe0\xfd}\xe2e\xbdc\x93\xa8KA\x1a\x0b\xb9\x82\xc5\xfd\xbc\xbf\xcf\xaebs?i:c\x1d\xa1\x14\xc9\x82\xf7o\x82\xa7\xb0\xbb\x1b\xc3\xf7\xb0y\x1a@\xc5\xcd\x11\xa65\xecB|\xa6?\x17Y\xe3\xfawr@\xa9\xec\x816\xb5/{\xa9\x9f\x06\x90\x8a^L=\x08\xf6\x87\x05\x0c\xcd\xfc\nS\x8a\x11\x96S3\x04\x9d\xdeo\xfb\x85\xefn%a\x0f\xbe\x1f\xf8\xa5\x01A\xbf\xc0\xf7\x91S*\xa6\x15i\x12\xab\x87\xe05*\x16\xaf{Y\xce\xb3\xd3*w1\xb7\x81A\x05c@B\x0d\xd5\xcbzZ\xae\xa6\xf5\xa7=H\x99\xf7$\xea\xe2\xd9\x0dV3\x05\xc9\x1f\x90\xfe1^w\x04N\xd1\x884M\xe9/\xafr\x9b\xc0\xbc^,q\xdayTs\\\x11\xb4\xdedQ}\xc94;3\xd8\xdb)\xb0\xa4k\xd9\x80\xc2\xcf\xfc\xfd'\x07\xc1\x17h\xcf\xbe\xf6\x92\x1bM \xf54\x03\xc3\x88\x18\xbd\xa4\x92l\x91k3\x87\xd1\x92\xe6Km\xee0\xc0\x94\xb5e6\x81C\xfdKT\xdcM\xe0a\xef\xa5\xc659\xb3\x1ao\x82\xb2nSrF\xb9\xb6\xfb\x9a\xfb\xd0~\xd3\xccOs\x96g\x8bdYEi\xbeDs\xc0~=F\x02J5\xdb\x00\xa8f\xa7\x89\x8d\x91`\x97Z\x92 \xcb[\xafDR\xc5\x12\xfe\x04\xfb\xa8\x87f'\x00\xa5\xca\x94\xb0\xee?\x05J&\xcb\xa7\x10\xef\xee\x06\x94F\xd2\ngjkZ\xb2\x89\xa0\xfa\xd3\x91\x12\x92\x95+M\x83)9\x8b\xe2\xa2H\x11\xe5\x06\x0d\xda\xc5\xe9\x1a\xd1\xb5D\xfd6&)f\x17\xee\x1e}\x88\xf7\xb3\\/\xdb}\x8fOY\x05\x8aD\xbd\xf7\xf4!{\x8d\x18\xd8{\x8fO=\xad[>^Vc\x0e\xa8\xca\xe4\x17\x8f\xa8\x99\xf4\x91\xc00]\xa7S\xc2\x9a\x07\x8e21]M\xe3\xd7\xb9vpc\x8f\xc4\xc6\x978\xae\xa5u\xfa\xb3\xc0\xc0`\x90\xce}\xc4:\xbe$\x7f\xae\xeb\xc2\xa7\xc4\x97\xbc\xa4\xaf)Y*\xf2\xaa\xc6\x1f\x06\xd5\xc3\xc5&I\xe7\xef\xc9?6\xa4\xaa\xd5\xe6\xd4\xe7\x06\xd2\xc1r{\xab\x1f\xf1G\xfa\xfa%\xa9\xf2\xf4\xaaU\x9f?\x1a\xac\xcfMM4\x9f\xf17\xfa\xaf+R&q\x9a\xfc\x93\xbc'\x95\xfa\xad\xfa\\\xffe^\xbc\x9a\xab_\xacHZ\x90\xb2\x8a\xe8\xf3\xbbEc7\xdc\x91\xc4\xad\xd6\xeb\x0c\xf0\x84\x9e\x96\x8d\xfa\x84\xfe\x10-\xf7\xe9\xd1\x15w\x1d\xa1\xb5\x8cGQ2\x81\xd2p\xd2\x98\xa3\xe3\xf2.'\xba\xa8<\x1aM\x8e\xe0C\xe8h\x91+\xc8\xc5\xa0Q>W~\xa1\x97N\x94r\xcd\xa7|a\x00=\xf0If\x1anF2\x15k\xceNDx\x0d\x83\xe7wGp\xd0\xb9\xdd\x00^\xb9\xe5\x9c\x7f\xf9\xfc\xd9\xc0A\xb0\xaf\xf5\x90e\xfb\x7fS\xc6\x17)\x19\x00e\xb6Y\x13Q\xc7\xc0\x10,I\x8f.\x01h\x82\x10C\x1d\xd9On\x01\xb0\x1e\xbf\xa8\n\xe9\x96#\x9f\x88-\xd3\x1f\x138Dl\x11\xad\x8c\xc0\x9d:\x9a\xfbY\x08^\xcc\xfd\x8a\xb3\xfe\xd4s\x17\xfb\x18\xde\x9c+\xef\xdaO\xbdRG\x05KL\x05\xb5_Gt?\x1f\x1c*\"\xaf?\x1d\x1c\x82J\x072\xff\xe1\x81\xf2e8<\xf8\xce\x97\xdfn\xfbek\xb4\xe3\xbe\xdc\xba\xcf\xc3\xc3\xc7\xe6O5R{\xfb\xd0o\xbd\x92$\xb2\xd4c\xb7@-\x0dr\x13c@\x1fy\xf6\xdb\x93T\xea\x07\x93\x1b\xf1M\xec\xb6.\x1f\n\x7f\x82\x83\x8e\xb5x\xc3\\\x1e\x9c\xc1q\xfb\xe7\xc4\x98\n\x8d\xb29\xbe\xa6\xf5Cc\xeb\x87\xed\xd6\x0f\xcfP\xff\x1eDW\x07o\x0bRbL\x9aWh^\x12\xd7 \xc6/\xb9y\x9d\xcf5\x1e\x9f*\xa8[\xa9\xddTE\x0b&kP,\x10&\xe8\xf87\x13\xf4#\xf0I\x10\xb0(Qy\xd39s\x84U\xd2r}\xac0\xc7\x96\x174\x86a\xab\xf6'\x01L \xe1W[\xfaE\x1e\x9e\x9e\x9e\xbej\xfd\xc5\xcc\x02\xc9@8K\xdd\x12\x8dC\x00\xfb\x12\x99\xc8\xad\xc0A\xbfnG\x84\x80]\xf0\xce1}P+QZ\xb5\xf3\xff\xfd\xfe\x9b\xff\xf1\xf7{\x7f\xf4\x83\xf3\xdd\xa3\xe9/\x1f\xcfn\x9fN\xbe\xff\xd3\xe7\xe8\xe3\x83\xe3\xf0\xe3\xc7?x\xde}\x96<\xed\\g\x99\x0b\x0df\xb0\\\xe8\xcc\xf3\xb0\xb1\xa1\xdbo\xfa\xad\x95~}\xff<\xf8\xe5 \xbc\x0dD\xd3J\xe6\x12\xff<\xf8\xa3@\x80\xe6\x83\xe9\xf9Y\xf0\xc7o\xf8s\xcb\xc6UF\x851X\xe7~M\x87\xd1\x0f\xa4nX\xdc\xd8v\xa0\xf0\x06\xbd\xfb\xfdtL\xa667\xb66+N\x1fw\xf6\x90\x03q\xc6\xc4\xcaDWA\xdc\xc1\xb1\xe0Vb\xcf\xeel\xb3g?\x7f\x86\x1d\x12\x15q\xbd\xaa\xfa\x8du\xaa\xb3jC\xb1-@Qs\xf1\xea\xfd\nR\xb6\xcf!\xc9\xa0\xd4\x9b\xa8*\xeaXZi\x9a\x1b\xa2\xcc\x03\x87\x85\xf7\xee\xd9\xfbg\xafO>\x9c\xbc?e\x83O\xa2:\xff\xa9(laSD\xb9\xe2\x0eg\xb4\xa7ibP\xa6\x8aB;\x8c\x07\xe9el\x83}\x1cX\x87\x04\xd0\x18j\xdbk\x8aR\x15df\x8c\x13\xa6+t\x95XX\xd1\xdc\xfd\xa35\xa9W9\n]-(\xbb7 i\xfed \x9c\xa8Z4:(]\xc1\x0c4\xbe\xc9\x06]-(\x85\xa1W\xb2D\xe8\xcd\xe0Gz\xa7\x97\xfe\x9b\xf6\xaf\xadT\x96\xa0U[b\xe3\x9a\x0bp*g\x95~\xe6\xef?\xee\x06\xff\x00n\xb6\x86o\xbby(\xea(\xa9\xde>;=t\x125\x98.$/H\x16\x17\x89\x91\x89\xe0Y\x15(\xae\x17\x0d\xae\xd3\xc9\x1ez\x1a\x16<\xa9N\xaf\xe3\xe5\x92\x94\x07#\xc6P\xb1O\xb6\x18\xc3\x81n\x0cy\xf1j\xce\x12\xf0\xd7Q2\x7fY\xe6\xebwq\xbdz\x8d\xf8\xcd\xdcI\xeb(%\xcbxv\xf3\xaa\xff6\xa6o\x97\xa4\x96\xc7\xf9\xfb\xf8z\x84\xf8\xc2\xd9[F}\x8f\xd9Ib\xd7\xd7J\xc9/\x12[\xd7\xbc5\x18!f\xbb\xd5\\+\x11\x8b\xcb&\xa1\xdf;x\xe2$\x83'Nb\xa3z\x89\x12\x19i\xc7p\xef%H^\xa2\xf2\x85\x83\x0c\xca4\xf7\x13\x19\xf0\"\xf6\xf9\x1f\x9b\xb3\xa8\xca\xd7\xc4\xb7\x03\x14\xba+\xc2\xee\x16\xb5uu\x91\xd7\x0c\xd9\x10\xd0>>\x9bK\xdc\x80#\xd8\xd0\x87$\x9e\xad\xd4\x87\x15\x8b\x93Q\xaeQ\xcb\xc5w\xc4\x98\x0dQ\x90\x99~mY\x005D/\xb3\xd4\xa1\xb3\xd9\xc1\xb5F\x96\xaf\x8e\xbe\xf9F\x8emn\xba\x8b\x82\xde\x89m\x0c2+\x0e\xda\xccx\xca\"\x9f\xbd\x17\xc2\xa2uZ\x0e\xac\x9d\xc0\x18\xcc\x92\x15\xafIMJ\x0d\xdb!\x8a\x1cgE\xc7\x19\x07\xb0\xe3\xb0\xe7D\x91r\xe0\x948\xf0\x08;\x9did\x0d\xf6{\xb3<\xab\x93lC4\xa9a\xd4r\xc5]qs\x9f9\x7f\x99\x9cqE\xa1\xddj\x83\x02uK9\xad\xa8tB\xffc\x91\xca3\x8a\xc6\xf8\xf4\x08\xa6\x99ev\xc0\x87\x86\x87\xcb\xb4r\xa8M\x076k\x84\xa6\xfd\x00f}{'\x13\xbd\xd4\x15\x12\x9d\x9f\xe7e\xb2L\xb28U\xc4)\xe6\x96\xa1}\x83\x12\x8cBT\xc2\xf6O\x96\xb7\x9f%L\xe7W\xed\xd6\x81\xe8\\\xab\xbbE\x86\x00Td\xc4\xac-\xf4\xba\xcd\x98\x02\xbc\x80#\x98M\xf7\x1c\x00NKa\x84\x91\xe9\x0d\x15P\xda0*:0\xaa\xac=\x9b\x19%\xfb[\xe4\xe5\x9bm\xcc\xce\x18\xeb\xb6\x04\x0e\x9d\xb9%U\x84ZV\x06\xda\xd7-\x92^\\QzQ\x07\xe0\x15e>\xdf\xcc\x08\x1f\xdc\x15\n\x02\xb3<\xab6\xeb\xf6\xb3\x8a\xcc6eR\xdf\x88g\x9f?\x83\xbf\x9a^\x9d\xa1\xb1\xdb\xd5Y\x08s\xb6\xf3V\xba\x0ca\xddB\x01\xb3A\xc6f\xa5\x909v\xa64\xed\xd0\xbf\xb97\xa0\x03\xc8\x80\x83m\xcd\x14\xf5N\xf5\x81{\x18\x98\x14\xe1\xbar\x03G\\Ab\x9f'X3pt\x8b\\\xa0\x8b\x10\x9d\x16(\xd1M\x1b\xa2;\x0f\x9e\xc2\x8eO\xa7\xe8_\xc0\x11\x9cG\x19\xf9T\xfbA\x10\xcd\xf3\x8c\x04O\xf9\xe4]\xc1%\n\xed\x8f\xb2z\x17,\x00\xa8\xdb\xbcD\x91#>\xa1(um'3\xdd\xc2n\x90N\xce\xc6\x8eZ\x94\xde.\xa3\x0c\xcf\xc9\xb6\xad\x01\x87\xc7\xa7\x91h\xa4+\xa7#QKW\x9e\x8fD7]\x19\x87\x82\xba\"\x17\xf92D\xa7\x95\x0eZ^\xd3\xe5\xa3\x98I\xa1\xe6_\xc2\x11<\xebb\xe6'\x8e\x99;\xf6\xab\x981\xe5\x8a\x87\"\xbf\xdc\x06uu\x85bb\x87\xd7v>\xc5mE\xde\x1be\x1e\x81\xb7\x19*p\xc4\\\n\xc4\xbcq\xfe\xd4q\x9d\xac\xb5\xb6\x150n\xfdJ\x0f\x1b\x8d\xf9K\xef\x89<\x89T\x85\x08G\x8e\xceMQ_E\xbb\xe0J\xd8\x87\xdf\xe9T\xb4\x85P\xd1\xf6\x82Z\x03\xf7\x17\xb6k(\xf8\xf0\x98\x07\xa4b\x11\xa1\\\x15rs\x08\x8d\x06\xab\xdf\xe9jL\xa7D\xb9w\xfc\xfb\xc7\xeb\xb3\x07\xcb\x84]\xfe\x0d\x80u\x9c\xe9\xc1\xe3'\x036\x16\xffo\x98\x1e\xdc\xcd\xd5s\x9a\xc7\xf3S\xa3\xc2\xb0\x94\x9c3\xd3R\xd0\xe6\x0d\xe9\xdb\xf5\xc9\xc6\xe4\xdb\xcb \x90(\xbf43\xf2\x9b2\xa5U6e\xca\\\xc5\x8c\x15\xab:\xae7\x15\xe6$\xc1\xbfl5Y\x8aPQ\x9b\xfe2\x7f\xb1\"\xf1\x9c\x94\xd5\x04\x12\x9fD\xfc\x87\x81B\xe8\x1b\x89\xe1\x08r\xf1\xe5\xd4\xe3y\x84\xee\xd3\x9d\xe7\x19\xf4\x10\x1b\xccC\xf9\xf93\x9c\xfb\xb1\xd9\x0f\xca\xdf\xa0kKM>\xb1\xf8\xe5\x17i~\xc1\x14X\x17\xe8'\x1e\x88\xcd\x1c\xd5+\x929(\xb9)\xc9\xceY{hH\x97G\xf3\xb8\x8e\xd9\xdf\x9b\xc0r\x00]\xf5\"\x01;(\xea\x84\xa63.\x8a4\x99\xa1\x02\xe9\xc1\xcf\x15\x8bO\xc1\\w\xfer\xfa\xf6MT\xc4eE|LA\xb4l\x8c>\xe3\x05\xf91\x8f\xe7C\x0c\xf4-\x1d\x85\x0e\x84\xa2\xe4\x98\x01\x01\x8e(\x85\xc8\xa3\xfc\xe2g0j\xf5\x9dX\x83\x9c\x8d\xf5\x84\xdbl\xeb\xb9\x01\xfd\xe9\xc3a\x91\xf7\xa9\x83\x9b\xe1B2\x9cT\xaaO\x19\xf6\x8c\x94a\xafM\x19\xf6\x18e\xd0\xe3\xaa\xce\xbf\x04\x94\xa5\x15\xe3SC\x8e\x10\xa1\xd6e\xf6@:\x1d\xaf\xf9r@ \xba9\xcd\xe8@\x85\xbf \x9a\xfaGI\xc5\x1d\xa1\xa6\xd9Y\x00\xc7\xac\xd2\x04\xa6\xf4\xff\xb3\x10\x7f\n\xb9\x8b\xe2\x93\xf0U\xd1@\x1d\xf1\xb7\x1b,s\xc0ld\xe0\xa4\xd0Gfy\x99\xf0#C\xc4\x89\x13\xcfd\x9c\xd1\xa3\xadl\xaeVm\xfb\x0dS\xe0\x17\x12\x15I\xf1\xa5\x06,\xcdM\xe3,Oy\xd6\x9a\x97\x98\xf0\xcc||\x90(N\xd3\xfc\xfad]\xd47\x18;\xd8|||\xd9\xcc\x8fE\xf2\x1dJ\x1f\xf5WX\xdd\x04@es\xfdb\xc8\xc8\x1f\xfb9\xcb\xdfp\xc1\xa2k\xa8 \xcd\xe5\xd7y\xff\xe3+\x91~'\x9b\xe5s\xf2\xd3\xfbW\x86\x80P\xa0p\x92\xa8\xcdM\xb8j\xe8\xa6\x99]\x1eX\x1dma\xd0\xfc\x16l\x81\x19\x95\xcf;\xf7\xe4:\xee0\x08\xcdW\xbe\xb9m\xa9rfd\xd4\xde\xbf8C\x97G\x18\xfe\x1d\x8e!\x8f\xd6q\xe1'A\xf4s\x9ed\xbe\x17zt\xf3z\xebMZ'\x0c}\xd4J0\xe9\xd4\xd7\x03`V]M\xc0\x0b\x0d\x06\x99\x15\xbe\xfd\x1f\x07{\x86\xf75{\xbf\xf7\xc4\xf0\x9en\xbfj\x02\xdeg\xaf\x0fP\xa4^\x94\xe9\xc0\x14\xd0\x9e\xe7\xb4M\xab\xe1{\xe0\xceU#\xda\x02\xce73U'7Dx\x85\xd1\xd64\x1b\xb8>\xa1\x9bvg\xa7\x8c\xaa\xcb\xa48\xa1\x88\x9ed\xcba\xab\x82\x9c\x87\xeb\xefo\x0bc\x88V\xe0l\x95\x1d\x83EQ9\xf6/\xa2)\xc6^ny\xe2\xbf\x9d6\x82v\xa3Q\x88\"6\xf84\xa1\xc7\xcf\xc6\x8f\x8d\xeeJ\xa2pc\x1fC\x1a\xd2\x10\xf2 \xd4\x05v\x0e)Oo$0\xeb\x86\x9dB\xa90Y\xa0\xe1\x91~\x14l\x85\xcc\x0e\x0eI6Of\x14\xa3u\xf1R\xbb9o`\x00\x8f\xd3\xdf\x8e\x95Aq\xc3*\xf9\x08\xee\xd4\xf3\xd0\x9d\\[=\xc7\xd6\xfe\xb1!\xa5!\x8203\xa9Y\xe4\xe5Z\x7f\xd0\x0c\x86fM\xfb\xfb9 \xc6X\xb3@\x83\x04\xb1\x9fL\xc9\x19;)\x07\x10|`3\x168\x15\x83\x8c\xc3d\x12\xf9\xf29\x7f\xf9\x01_\x9a\xed;P\xe8{\x80\xf4\xbb\x88\xcb\xfa\xe3\x03\n\xa9\xfbT\"y\x90D5\xa9j\xbf\xb0\x9a|\xf08j\xa6\xf8\x9d\x80J\x04.\x01d\xe4\x1a\xe6\xa1\x06\xa8=\xf6\xd4*\xd6\xb06\xa3\xb8(H6gAu\x92i}\x86\xf6\xbdC\x00\xd6om\xa6\xf4\x94\xe3\xac\xfc\xc40\x1d\x1ez\x98\xe1T\x7f\x07j\x91L\x1bq\x058\xf8V\x98)\xb2*\xd2\xa4\xf6\xbdco\x00\x01\xae\xa0g\x0b\xbc\n\xa1\x1b\x8aB-K\xba\x9b\xa6{\x03G ^ O\xf7\x07j\\\xa0=\x86\x19\x85nl\xf8q\x8e\xe9\x96\x04 db\xe6\xcd\x00\xb2t\x90#\xd7 \x87\xeb\xa6\xe3\x8bu>%f%6e\xab.ZCl\xa8\xf4\xf9PFmP\xa9u?\x0b\xa7(&\x8c3\"\xc4\xb5-\x9d\x8d(\xf2fSG\xb0C\x96\x0c\x08\xcfG\x12\xb0l\xbf{O!\x83\xef\x81<\x85lw7\x10bYC\xb8\x87\xac\x8d\x04gRG\x8b$\xadI9~1\xccZ\xfb[\xc1O\xde3\xb9@@\xd3LI\x8f\x84c\x0fv\xf1(\xf7\xfal\x1d \xa3p\x11BE\x99^}{L\xe1u\x04K\xd8\x85\xeb\xb0\xd9\xd4x\x928\xecj\xed\x94\xbe\xb2\xc1q\x08uT\xad\xf2M:\x7f\x91_gi\x1e\xcf\x9f\xa1Z\x8deg%\xe9\xc2p\xdd.\xed\xc3\xfc\xcc?\xe8eK\xa4Eh\xc5\xf7\x86\x94\xe2Z\xa3\xe6\xb9\xd0\xa7\xeb^\xae\x1a\x8b\xe7\xfe\xcb+\xf1Rc\x0f\xad\xba\x1a\x0b\x9b`\xf9\xec\xcf\xec\x8c\x136\xc1l\x07Ri\xf8m\xf9\xbf\xe9\xea K\xce5)\x97\xe4U\x86\xcf\xde\x96\xb4\x02\x1cA\x8ao\xb8\xc3\xb7C\xc0\x1bh\xd6Zz\xdf\xd8\x11\xdf,\x11\xb2]Y\x7fq3\xda\xfa\xb2E\xad\xfb\xad(B\xf2\xeeg\x90a \xbaK\xab\x9b\x03\xaa\x8c\xf5,2\x08\x82\xaa\x01\xbf_\xf2\xc8\xe85\xfe\x95\xf9\xa4\x97\xa8[6\xd1F}Z\xf9\xe0;\x8d\xc5\xfdZ\xa0\xb5\x169\x97\x02\xc5\xbe\xd5\xbd\xbd\x11\xdf\xf6Ru\x02?\xf5\xe4\xae\xd2\x83\xa3\xed(op\xda\xe8\x83a\x02\x9a\xf4\xee\xdd\x1d\xc0\x8f\"\xdbI \x88?=2\xaf\x14S+y\x94\xad\xe3\xf2RRj f\xae\nUL,!\x17Kn\xa0\x97\x01\xf6\x8d2\xc0~[\x06\xd8?\x1b\x08C(Ng9\xcc\xeb2.\x1c\x0f\x14\x16\x82\xfdi\x00\xd5u\xc2T\xc5QQ\x92+\xe4\x8d3\xf2\xc9\xca6\xce\xe2\x8a\xc0\xded\xb0\x0e\x08\xd3,\x93\x10[\xdb\x84X\x91\xc2\x1e5\x02\x14\x96u@O\x1c\x0c6\xbf\x92\x04\xac\xf9\xfb\xf3gL.\xa7\xdd6q\x10\xc2N\x1c\x95,\xa4\x04\xa6)\x9b\x91\xa2\xce\x07w\xb9Z\x18`\xe0\x08\xf6\x1d\x0d\xb1.J\x12_Zk\xda\xef\x87\xe5\xb5$\xef\xff\x11\x9d~\x7f\x1e\xda\xfb\x17\xb5\xe0\x9a=r[3\x12\xd5{\xcc\x1c\x9fdu\x08\xf4\xe7h8=\xf9u\xc1\xc4\x87\x1c;\x00\xe1\x89\x1d\x08,\xe3lmYjlm\xdfa\x1f(\xa7_<$|\xc6&\xe13\x1c\x96/y8+\xce\x81\x19\xbb\x90<\x9a\xb1\x1f~\xb8\x88\x08z\x92,\xec\x1f\x86\xca\x0ex\x14\x82\x8f\xf9\x1eJ\x8c\xed\x82\x071\x06y\xa1O\xcbt\xf8\"\x0b$\xe0\x1c\x90Q\xb2\xab*2\x8aa<\xa1{]=@|\x16\xaf\xd4\xadw\x07,\xa0[A\xed\x1a HU\xe4YE\xbe\x84\x82\x1c|\xf7\xebn\x8d.\x0598d$\xa47\x13\xa3\x0eP\x14\x84\xdc\xc1\xa1\x1b\xe4HT\xef\xb7\x89\xc8\xfexP=\xfauA\xc5\xc7l\xc9\x0f\xc3\xc0\xe0\x82\xbe\x8c\x8c\x18\x9c\xc3Da\xcd}goN\x82\xe5\xd0\x01\x83\x10$.\x1d;n\x04I\x0b\x0e\x9e\xe0b\x1e\xb0\xbb\xb4\xb8\x9e\xad\xfc\xfd\xc3\xc0\x10\xafFW\x9ai\x1c\xda\xa7\x01w\xb8\xba\xcc\xc4\x8b\x8e\xdd\x01.\x87\x0eh\xce\x1a\xf4s\xae\x94c\x19%J\xc5Z#\x08\xf8\x8f\xe7\xf9\x1c\xc3\xc5\xf2\x9fL]\xc5L@ \x97{Q\xde\xc6G\xf5A\xa8\xbb\x99S\x0b\x1b\xa5\x03\xda \x19\x8b\xf2\xcb\xd1\xeb\xf3\xd0\x02'Q\xeev}\xf0\x16\xd1\x0d\x9c\x89\x0e\x9c\x89\x04'}\x1cv\x93\xcfw\x0b\x82\xf1\xe1\x81\x1d\x8c\x92\x8c\xc6\x17\xe5\xa6\xa8}\x8f=\xf0\xc2^ \xefna]X\xf0 +y$\x9b{#\x86R\xd5y1`\"\xa9\x07\xf9-K\x93\x871S\xa7\xc6o\xa7\xf4\xcc?x\xa2\xd7\xf9i\x02\x18\xdc\xea\xd4D|\xa0v\x85t\x03\\\x16\x92\x10\x07'%![(\x8d\xdbnVB\xa125*{\x06%B>\x98\x07\xfe\xcfU\x9e}\xfe\xb4N?\xdf\xc4\xeb\xf43\xa6\x00\xfdx\xf1\x80\xf1\\_|\xb9\xd3\x8d\x10\xb2\xad9\xe1\xc3\xfd\xffxk\xc2\x81\xc1\xb4/1I\xa0\x06Q\xfe\x1eCi\xe2\xd5\x97\xf7\x00\x83\xa0\xe0M\xba]F\x16\xe6\x04\x99`\x02\xddkTS\xe3\xb3\x01\x13)#\xa3\x85\xbaR\xba9\xd8\xbc\x9b\x00\xcfti\xce\x95\xa5\x19GZ5S\x991+g\x9d9\xaa#i]\x0c3\x19\xeeW\xa4\xfc\x0b\x85\xf1\xd2\x8d\xcaiL\x85\x9d\xf1\x19i\x94ua6\xca2\x0db\xee0\x08Q\xb9e&\xeb\xd4\xfaJ\xdf:zAY\xf6\xb8\x88\x9b4x!\xe1\xc5\xf3\xb9\xb0\x8a\xff\xfc\x99\xb2#\xeb\xfc\x8a\xb4\x9f0\x06\xc5\x10\x99\xc6\xb8/;\xc6Z\xa6 ^\x0d\x82\x0f\xa7\xff\xf93\xd0\xb9\"$\xd7\x9b:\x16\x90D\xc9\xfb\xc6\xd1\xd4x=\xd8\xcf\x15o\xdfo\xe0AA\xd7\x07\x80|\x8a\xb7\x16\xbag/\x08)\x9a\xe7n8\xb4t\xc0\xa1\xaf\x8e\xc87Fcl\xb3\x87\x06\x1f\xe1\xa9\xbc\xd6Z\x92\x1aM\xaf\x7f\xb8y\x97'\x19\xa5\x08\xfd\x18\xb8\x00.n\x0f\x82\xbcw\xb2\x86\x86\xda\x88\xd1\xbf3\xff\xbas\xa3\x84\xbe\xecz1t\xeb\x7f\xce_\x1ej\x0d\x06\xae\x87\xec\x10N\xc4\xa7\xda\xdb\xdcO\xe26W\xf7\xf2T|\xaa\xb5~x>d\xc3p)>\xd5:\x0c>\x13o\x1f\xf7\x8d\x18\x9a+\xdc>4\xe3\xf9|2,'\x8b2(3\x81\x90\x9b\xe8>\x1d0\x1c\x1c\x92\x9b@\x91\x9d\xb4\x154\x08\xd6o\x89\x93\x85 $\xbaw\x94\x8a\xde\xe9|9a\xb6Ny\xfb !\xf5\xba\xab1S\xba\xe8\x1a'\x8a8\x899\x19\xca\x86\xa3\xe5\xdc\x06\xdd %\xad\xb7!L\x87\xb6\xa3\x89\x9a\x9b\x0e\x1ae=\xdb\x8a\x0b\xdd\x9a\xdaV\xf1\xaa!\xb6\xe6\x11f\xcc\xeb\xf85\xa9c\x1c\x1d\xa9\x00\x83}\xadI\x8d\xaa\xcd\xb5_3\xd5B\xc7\x8f\\\xd0\xfc\xcf\x9f[xEk^\xe9)\xd7U\xc8\x9b\x15\xe9l\xafl00\x9e\x85\xf5Y\x10\xde\xf1\xc8m\xc0\\v\x0e\xc7a<\xbb\xd0\x83`)A0\x1ee\x14\x06\xe0\xc2\xc8\x00h\x9f\x8a\xdd\xd7{\xa9a\xcf\x8a\xb8$Y\x8d\xa1\xba5<\xda\x10\x83\xd6\xf1\xf0\xac\xed\xf1\xaa\x95\x84\x9aG\x98B\x17\xf1\x95]\x9b0\xbf\x97\x92\xf9\xbd\x18aE\xfbE\x9f\x18\xd4\xc3\xa2s\xb0\xa5O\xf1\xba\xef\xfd\xa3\x01\xc6\"\x8d\xeb\x9ad\x13\xd0\x04}Yl\xd2\xf4\xe6\x8d\x08g\x84s\x1e\xe1;\xbe\xf0g~\xea\x93\xae\xf6\x1a\xf4\xe3\xc8:\xddh<1\x93\xea]\x99\xaf\x93\x8a\x8c\x18D\xc1\xb5\x86s\x9f`,\x14\xa7\xb1p\xcf\xae7\xe4\xda\x117\x86\xe3\xa3\xf0\xa1\xe0}m\xa5U\xb5\x01\xb8\xa8\xdb`\x08\xcf\xc1U\xc4j&\xf7\xaeL\xd6I\x9d8kA\xdcg\xb9\xf9\xcdg\x99T\x7f\xa9\xf2\x8c\xcb`+\xdd\xfb\xe7L\xde\xed\x89i\x16\x84\x92jn!/\x9b\xb4\xdc`\x1a\x18\xefQ\xe3\x1b\x9fT\xaf\xb9&b\x02W\xba\xd7\xcf\xe6s\\\xb0\xa6\xdaZW\xed\x7f\x92\x8c\x94q\x9d\x97#\xe6\xf5\\\x92d\xe5\xfb\x97\xcd\xd7ns\x13\x1fL@\x93P \xa9\x18\xdb=\x81B\xf7\xf2\x84\xe5\xaeu\x1eq+x\n~\xdc\x1fc\xeb \x95\xdf\x15C\x1f\xa9\x0c\xfd\x9dRap#t\xa3\x8e}A\xae\xb4'\xdb~\xba?\x94fm\xf8\xd3'{\x03\x86M\xb6O\xb7\xcebw\xb0\xf7\x9d\xf9\xd3\xff`s*q\xbfw\x07\xfeJz>\x8c\xe5o\xe8;\xae\xe8k\x97\xbcv\xcfF]_\x9d\x850\xb8N\xea\xd5\xf3\x92\xccIV'qZ\xc11xI6K7s\x82&`U\xbc&\xf7Y\x9cx\x8d+\xb6`\x03\xc4z\xdb\x14yd@hB\xe7\xbe\x81Pm\"p\x9d9\xbd&`G]XML\x01\xecX\xf5\x1e\xb0\x8cyTA\x8d\x177,\xfc=\x9b\xd1\xb6&\x9a\xd0g\xc6\xcf\x06\xd2\x1b\xcd\x9a\xe5\x99h\"\x88\x01\x8aw\xaea\xe0@\x95c/\xf2\xb9>x\xa7.\xcb\xc9\xef\xcc\xbf~\x85\xdb\xbdd\xe8\xb2,\x1e\xf0\xe9]\xc7\x97,\xb7\xf2_N\xdf\xbe\x11N\xbd\xb3\x94\xc4\xe5\xf3x\xb6\"6\xbb\xd6**\xd2\xcd2\xc9\xaa\xa8$\x8bJ\xf9\xb0cB|\xeb\x9aQ\x1eT\xc2R\x9b\x17J\x10\x97z\x95\x18\x92\x99\x9c\xa0X\xd8\x19\xe0<\x9f\xe1\xf0X\x14]\x12\x84\xdd\x19,TX\xf8\xd7C\xeae\xddf2\x84;\x01\xd3f\xba0\xe0\x97~JB\x8c\x9a\xb6\x07m\xd0i\n\xeb \x01N\xd5\xb0cI\x81\x931MM\xd3X\x13\xf2>\x08\xf5\xdf\xad\xf5\xdf1\x9cN\x08~\xc7\x8f.$\xec\x85\xb6~\x9c\xa6o\x17A\xd8\x8d\xf9n\x06\xb55k\x9b\xbc\x11\x1a\xa6<\x17qE^\xe4\xb3 \x9clCi\xf8\xf0\x07IfW[\xa1\xe5\xbdE\xa1\x82\xfe\x8b\xa4\x9aQ1$c\xec\xaa\x86\xebmj\xf3\xd5y\x1d\xcf\xca\\\xcb?\x8b\xb2\xce\xe7$\x15\x94\x86W\xefGE\x01\x854\x9e\xbb\xe4E\x86\x8eos\xdc\xac]b\xf4mv\xd5\x1b&\xdb\xb8\x1d\x8b\xf2\xa5\xee\xc7\xa2\xb8\xba!\x8b\"\xcf\x8a\x9e\x07\x87\xc9\x16\xb4[\x98\xeb\xa0[\x8fc\x1c:D\x91#\xb48v\x882\xac\xf2\xe6\x8e\x1e\xe6f\xb4>\x1b\xa283D\x9d\x0f\x9c}8D1(\xd2\xfd\x00&0\xeb%\x13\xb3\x9d\xe6\xa0\x90^\xc2N\x083\x8b9\x94pl1\x1cd\x8bE\x92\xa2{W\xff~\xde\xc4\x8fT(\x8c\xbe\xee\xaa\x1d\xb0\x0b3\x17\x19R\xdc\xb1]\xd2\xa3E\xfa\xcak9\xc66}\xd1\xd7^\xf2\xa6U\xc2\xa5\xaf\x89\xf1\xe3\x9dy\xf9\x0b^\xdb\x91\x97?g\xebr\x99\x14B\x97\x87<\xa7\xbe\xf25\x8b\xe7U\xd7\x1a\x19\x1d\xb8\xc1\x13\x89\xf8Ibd\xfai\xad\x13tc\x0e\xb1E\xbc\xd5\xbe\xa6\xffl\x04\x9d\x0b1fN\xed\x97\x18\x91\xd1\xcck\x8c\xe03\x1cy\x8c\xdb\xc0?\xe1t\xbf\x9b\xfa\xbd\xcfZn8\xf7\xa8\xb5\xb4\xe2\xd2\xfc\xbe\xe6\x15K\xbbY\x19Rnf\xfe\xd6\xba\x83\x83\xbd\xad\x93\xbb?\xd9Z\xfe\xdfZ\xfa\x1f\x18\xabU\xf6W\xdf\xdc\xb9\x10a\xe2\xc8\x0d\xfaOy\xa2\x9b\xd9\x03TAE\xb3\xb8\xa87%9\xad\xe3\xd9\xe5\x872\x9e\x1186\xbd\xe1\x04\x9d\xfe\x1b\xcd\xf2\xac\xaa\xcb\xcd\x0c\xdd\xdf'\xecYEkR^C\xfan\x06\xec\x99\xe5\xaaA\x1fx+k\x05\xde*Y\xe0\xad\x92\x05\xde*ww\x03\xc8\xa6e;\xf0Vi\xe0\xacqpkRU\xf1\x92`\xae\xc6\xbd\xb3\x90\x99\xd0\xd4\xad\x93J\xa7l7\x11\x8c\xac\xb9\x8bW\x9dUC\xf5\x05\xcf\xedC\x8f`\xf5\xa9\x02:\xfai\xd8q\xa8\x1a\xad\xf5\xfb\xed\xf12\xa9^\x96\x84\xa47o\xe25\xb1\xe7w\x90\x86\xe4S\xd2\xf2\xc7\xd1\xae\x1d;\xc4\xa5\x0b\x9d\x91\x80\x97Q\x92\xcd\xc9\xa7\xb7\x0b\xca\xa5\xfc \xee\xefS\xda\x9d\xcb\x87Y\xf30q\x0d=)WZ4BX#}$\xb1\x12e\xf4i\xf2\x1a\xb9K\x17M?\xc7:\xb80 \x1dX\xe5\x85\xa0f5\x0b\xc1\x13\xe7\x05\xfe\x10\xf9\xf8^\xb4\xbf\x98\x89\x90\xb4\xd5\x83j\xb6\"\xeb\xb8\xfb\xb4\xd5\x88\xf2\xbc\xdd\x95\xda\x0c\xef\xe8\x946\xa7\x1f{\x82cg\xfd= \x9f\xe2u\x91\x12\xefl\x0c\xc6v\xc8\xf7\xc3/ \xc3\xadW\xff\x96*X$G\xc6\xedp\x07\n\xda\xfe6B\xf3\x86~03\n\x87\x8cG\xf9\xc3`\xef\x8c\x9c\xed \xc5T\xef3r%\x91>\xb9F\xab\x8f~'\x1d!TP\xdd~E\xb1g\x90r\x97\xa4\xca\xd3+\xe2w\xb5\x82\x96}[G\xf3\xa4\x8a/R\xc6]-\xe2\x19\xc1\x00Q\xdd1\x84\x18]\xfb\x92<+\x92\xeaC\xbc\x94\xd9C\xfd:\xd0G)\x1e\xa2A\xb34!\x99\\\xc1Nt\xb7\xdfL\xcbxh\xd62\xfah\xed\xffm\x80\x91\xe4\x1e\x05\xba\x8a\x82\xa1\xd4\xa7\xf3\xa9\xc4[\xad\xb7A\x8a\xbb\xf9;\x03SY\xfa\xa9!\x8cb\xe6\xef?2\x06Q\\\x0cEP\xd4\x86\xb0[17\xf9'\x86\x00\x8a\x99\xff\xad\x8e#^s\xbe\xb7\x0d\xd8\x1ce\x0d48\x94\x82A\xae\x06CL\xe5\x8f\xe8\"\xc9\xe6~\xb6I\xd3\x90\x7f\x16\xf0X\x1f\x14\x9f1m\xad\xd2\x04\x7f|\xba\xb9\xa8KB\xdf\xce\xd5\xb7\xe4\x13\x99mj\xb4\xd0\x11\x7f\xd3\xc7\x9d\x18\x8fi\xebA\xabB\x13\xf01\xed=\xa4\x15\xdbJd\xe5g\xc82\x85\xb0\xb3\xe1\x87M\x92\xf2f\xae\xa2w\xcf\xde?{}\xf2\xe1\xe4\xfd\xf9\x0f?\xbd\xfa\xf1\xc5\xc9\xfbS\xd3f\x82#Xi_\xd0\x0f.h\x9b\xef\x99\xd4\x84\xed\xaa\x0f\x10r$-X\x9f\xfd\xdd\x90\x17\xaf\xe6\x13Xc\xe2\xfb\xf6\x86\xc0q+-\xc8\xac\xd1\xe2\xf1\xffY\xd8\x17\xfe\x00\x9d\xfc\x98 \xc5\xfe4\x99\x8e\xdao [\x14\xa5\xbd\xcbm\x17o*n\x0d \x84`\x1d(.\xe8y4\x96fe/l\xf4R\xc8\xc3xt\xef{\x83\xbe\xbb\x94\x08WRi\xcf\x02\x88\xd7\x06\xed/\x89Vy\x85\xbe\xba>\xff\xf3\x082\xfc#@ 3I\x80\xbf\x17\xbf\x8e`\xca\xc5\xdcY\x9e\xca\xe8(\xde\x84\x8a\x13^p\x86_^\xc4\x15y\x17\xd7+\xfe\xa9\xfcy\x04T\xba\xb3/\x80\xaa\x03\xc9\xc7\n\xca\x16e\xd3\xde\x80\xd01\xfc\xe9\xfe\x17\x98\xb8l\xadW{\xb2\xf7h\xdbO\x0f\x1fn\xad\x1f{\xb27` \xf4\xef%\x9a\xa9\xbf\xee\x9c\x1bG\x9bdv\x01\x89\xb8I \xd5\xeb\xb8\x18\x08.\x9e\xc3@\x84\xf0d\xc8\x1dX\x1a\x0chu\xbe\x9b![\x83j\xc8W8\x15\xedj\x87$\x82\xa1\x1fj\x9d\x85\x17C\x9e\xc42C\xa86h\xb4\xe0\xe5\x0f\xf6\x86\xdc\x81\x87Y2E\x14\xbd\xf6I@E\xc1\x02\x8d\xb6\xad\xaa\x1a\x11n\xfdP+5\x89x\xeb\xda\x81\x8b8\xda\x87\xda\xb7\"\x8e\xf6Cm\xc3\"\x8e\xf6C\xed2 o\xf0\x87Z\xafm\xe1\x0e\xfeP\xeb\x98\xed\x94\x08A\xb9\x00\x1e<\x80;\xf9\xb5\x98\x98K\x82^.\x12\xf6b\x98\xcdd,\x92g\xf1'\x99\x93\x8b\xcd\xf2GrE(\xe7\x98d\x8b\xdcR_\xde\xfaO-\xael\xac\xe2\x9f\x93\xaa\xce\xcb\x1b\xb3\xd5\x9a(\x8cy\xb07+|s\x1d\xaa\x16\xcc:|.Y:\xdb\x07U\x1dSi\xc46\xd4\xc2\xb5\xbd\xc6\x0c\xc3\xd2\"\xaf\xf8\xa1$d\x82\x9b\xea\xdc,4\xa9\xa5Z\xe5\xd7/\xe8\x02\x9a31\x89\x12\xa7\xa93\x1c\xd8\xd2Q2M\xa5 FY-h\x91&\x17\xafI\xbd\xca\xe7\xd5\xa4\x8b\xab\x9dd0\x14u\x035\x10\xbcu\xdc\x1d\xc6\\\x93RJ\x14\xca\xc1\x04\xfc\x06eI$\xb7w\xbe$5S\x16\xf0\xceE\x05n\xf3\xad\xd6\xe3\x8f\xfa\xd5Wq\xf5~\x93\xc9\xaa\xecg\xbf\xdau\x19\x17\x05\x99\xbfk\xce&\xfaT\x98\xfa\xac\xe3\xc2\x97\xd5X\x1d\xa5\x89@\x84\xe4\x91\xc0\x89\x1a\x13j\xd1\x01\xc7>fD\xd4T\x8c\xe7s\x7fz\x166\x1cp`\xf9\x80\xe3\\\xf3\x11\x7f \xbf\xdb\x14\xf3\xb8&\x1c\xec\xbe\xda\x94\xde\xd2`\xd0\x11\x87\"\xc1\xbcA\x02\x12\xc2\xd4L\xbd.\xc9\xcd\x04<\xa4L\x03h\xc7Y\x03\xbb\xee@\x14\xe4\xef\xe94\x1a\x9a\xc7\x8c\xf5m\x1f\x82z\x9bV\x87Z-1\xbbBc\x17j\x19\xaa\x8c\x8f!\x83\xfb\xb0\x0f\x13\xd8\x0bBd?\xf6\x9fB\x0e\xdfC\xf6\x14\xf2\xdd\xdd\x00\xcai\x8e73\xadK\xb6\xdc\xc1%\x17\xdd\xbfy\x94\x95 J\xf3e\x13\x86Jc\xbd\xa1\x16\xb39\x8b\xc1Fd\xe8\x90a\xcbtE\xca\x8b\xbc\x1a\x8a\x04\xb1\xd5B\xc9v\x99\xf3_{\xd9l\x0d\xc0\xbf\xcf\x82M\xbd)\x06\xce\x84]\xf0\xce(C\x7ff\x8b\xca&\xcaWX\xcb\x86*\x8dYNKx\x05P\x04dAE\\lk\xd4\x827\xb9\x83*\x13Qr\x83\x08\xd0-B\xfa\x99*\xf4\x99\x9ex\x98F\xb8d\xd70h\xf4\xde\xab\x10\xc0\x04t\x04\xda\xc7\xb0m9\xbf\xc9Qk0\xe9G\xc4\xab\xca\xad\xdcu\xb7\\m\x93P[\x14>\xd1\x9d^\x889\xcc\xc5G\xaeHy3\xce\xb1Y-R\x86<\xe2I\x98\x9d\xbe4$\x1bkU\xb1o*\xde\xb7T\xd4tL-K?\x0f\xc1\x988\xb1[0\x16D\x08\xb3\x10\x16!\x14\xe8\x14\xbf\na\x8d\xee\xab7\xf6\xb1\x80n\x85p\x1a\xc2\xf3\x10.Cx\x16\xc2\xdb\x10\xde\xb9A\xbe[,+\x11o;~\xd0\xadL,V&\xdeje\xbae\xdb\x95\xea\x16\xcch\xdd\xa7A\xf9\xa8\x00\x16C%\x96\xf9r\xb6[\xa4nq\x0fk1T\xec!*l\x85\xa5b\xb8$7x\xd3\xbf\x98.T#\x9a;\x07\xde\xc3\xff,\xe0\xf1\x9d\xd7L\x0f\xe3D\xe3\xd9\xe9\xa3>\xf9\x92\xdc \x0d1%.u-,\xe2\xff\x97o\x93f\xa4\x8f\xbfl@\xe0\x96\x11\xc4V\\\x93H\xd9\n\x9a\x89)\x98\x1b\xa2\xe2m1\x9d\x9f\x85\xa8G[H\xab+\xd5l*\x08Q\x8d\xa6>\xc2\x93\x1dC\xa9\xcc\xf1\xcfu\x88\x87B\xa2\x0dD1\x9b\xe6\xd17\xdf\x94dq\xc6\xb2\x95\xee\xec\x85\xa8=\xdb\xd9gf\xbf\"\xed\x91\xa4\x99\xfb\x0fC\xb4\x0d\xee\xb8\xbe\xd0\x9fU\xf3\xd3\x98 \xd3\xb58\xa7C\xb2\x15J\x1c0\xce\xc5'8\x82\x13\xc4\x1d?\x08\xa2y\x9e91r.Eb\xe4\xe1\x7f\x18m\xc0\xe8&p\x04\x9fD\x10\xf9\xe7p\x04\xf9\xf4\xf4,\xc4\xf8\x95\x0b!\xf7\x9c\x06!\x86\xac\xd4\x9c^\xcf\x83\x10\xdeb\x96\x17\xc4\xb2\x10\x06\xd3\xfa\x8e)\xf1\xd8\x84H\xb6\xf2\xaf\x04\xf5\x9dg\xff\x0d&K\x91^W:\xb2\xf6\x16\xe5\xb6\xd9\xf4\xed\x19\xd2\xb4\x80Y\xb8\xa5d\x19\xd7\xe4\xff$$\x9d\xfb\xa5\xcf\xd8\xd6\"\x08\xc1\xab\xf7\xbc\x10\x0e\x1e\xdd\x05\xcdr\xc9\x81e+\x18x\x9aJ{\xa7,d\x0c=\x83\xef\x1c\x1f\x0e-)\xb8\\\xcb\xbf\n>P\xa0\xbd\xc3\xcc\x06\x19\x8b\xd0\x96a$\xbbw\xff\x0d8K\xe9r\x80\x87\xfb\n\x0b\xf8\x1c%\xbcK\xcc\xddZ\xdc\xc5\xfe8tt\x15\x1c*\x82Q\x89\x9b\xf4\x8b_62\xb8CV\xf0\xf0Ny\\\xc7\xcc\xaaC\xe5\xce&v\x07\x94M\xb2\x91\x87\x98\xb3\x153\x0b\xc6\"c\xde\xc3\x80\xf3\x9e{\x8c\xf7\x8c\xadi\x02m\x85\xc9\x1cw \x9b\xcbq?Ty\xe1\x87\xfb!\xec\\P2s\x12\xf1]\xa4\xfc\xddM\xc05\xb68\xa5Hs)\x9426c>\x0ca\xe7\xfc\xce\x89\xe2\xc3;\xd8\x81\xf0/D\x14Y\xde\xbd\xeb/\x9b\x14[\xc1;\xd86\x92D/\x92,\xa9V\xfe\xc3\xc3;\xc1-\x87D\x89\xb6\xd2\x1b\xd9\xde\x9d\x8c\xec\xf1\x97\x8dl\x1b?sS\x913t\xf4?7\x95\xedp\xf26\x84\xd8\x9e\x98\xd0V\xa6Tj\xa7$\x97\x92\xaf\x87\x8f\x1dB\x1a\x9b\xca\x94\xd2\xbc\x10\xa9\xc8\xc3\xef\xdc\xee\x0e\xba\xc5\x10\x15r\xa8\xdc\xb2\xc4\xf1\x9d\x8b\x83\x9b D\x9b+\x0c\xc9\xcb\xcf\x8d\x82\xeb.\xe6\x8a\xeeBj\xe2\x1f\x852f\xac\xa2\xba\xc8uw\xf8\xdd8mc\xf5\x19\x88\x81[`1\xa5\xd5\x18\x84x\x8d\x1e\x02w\xa1\xae(%\x97\xb4\xa5zb;\x9a<\x1e\xdf\xf9N[\xc2\x11\xac\x85\xc6\xa1\xec\x88m7\xfeR\xbcZ\xf28\xa3K)\xc1\xed\xefo\xb3J\xfb[p\xa4\x02\xdd$l\xb7\xd0En\xc1\x97\xb1\xf1n\xc1`\xcaq\x1el\xc1Pn=\xd0-N>\xb9W\xf7\x1fQ\xe8\xb2\xd4\xd3\x9cA|\x14\xf0\xfd\xbd\xc7\xf6w9\x9a?d\x12\xfa\x16\xfc\xa0\x1c\xd6\x81JO\x0e(\xff\xb7\xa0<\xdfJ\xe1\xffV[\xf2\x7f\xce\x99\xc4\xbb\x85%3\x16c\xa2\xfc\xdd\xd6\xf7}\xe5\x97j\x8b~-Z\xc1\xf8\xb3\xf9\xb8An\xad\xa0\x91\xee\x8c\x9c\xcb9\x18\xcb\x7f9\xe73\xef\x96^\xcfc\xf9+\xd6\xf3\xc8\x93\xe8K\xf8'9\xe2\x91\xfc\x92\x1b\x0e\xdc\x86P\x8e\xe7\x87\xa6\x8fB$(t\xf7\x1e\x8ca\x7f\xa6\x07\xc8\xee\xd0Mu\xe0\xc8\xee8\xb07\x16k\x8a[\x9f\x04}\x03\xe2\x9c\x99\x1d\x96\x81\xcd\x8a\x18\xa4=\xe8\x9bxM&\xc0\xa3.|\xfe<\x14~Q\x94V\xe8Y\x95!\x92\x8f\xfd\xdc2\xfa\xd1Q\x8d\xecVN\x94(\x8d\xb6r\xb2\xd1@\xbbw\x9b(\x8aE\xe4\xaam\x16\xdb1\x1eU\xbc?\x9c\xcc\n\xa4\xf7\xd6\x92\xd4\x82\xd3\xac^\xe6%k\xce\xaf\xd5\x8c\xae\xbf\x0d\xd0U\x83\xec;\x84\xbd4\xec\xecX|\xb72\xd8J\xc9K`\xa1\x0c\xb9\xd2\xfb\xcc-u\xa7Z$\xe8q\xe8\x16\xe0~\x05\xe8. \xc7hno?\x02\xb8\xd6\xf9\xa9Q\x13\"\xd9\x11\xa5\x06>\xb1\x1c\x1f\xaa\xd7n\xcb\x1f`Z\xf3\xfc3_\x11\x14\xef7\xd9\xf3|\x93\x0de\xb0\x1a\x0d\x0buB]\x98\xfbDl\xb0\xaf8)\xde\xd7\x87d\xc8 \x7f\xf4\xb4\xf4K\xdc\xcc\xcbm\x951\xe2\xcf\xb4V\xedeX\xf2\xaa\xaf\x08\x0fA\xe7^es\xf2\xe9W\x03\xc9\x87\xa4\xc0\xe4\xcbj\xe7N0\xf2\xb2\xcd\xfa\x82\x94\x1e\xec4\xbe\xd9p\x0c\xf7\xf7\xc1\x94&\x0d\xee\x04Lt\xb7\xde%t$\xbdkX\x83\xbb\x1f=w@\xd8\x96\xae9\xd8\xc8\xb6\xcc\x92\xc7\x916_C\xd4\xb2\xb3\xb6\xbf\x87\xf2\x9c\xa7TG\x1f\x8c\xa1x\x91_\x08+v\x80}E(\x0d\x03\xa5a\xf1\xda\xe9;\xe8f\xe1y&F\x1e\xach\x8d\xd7\x0b\xec\x1f@\xc6\xbd\xcd\x19Dm\x8bE\x0bf\xd8\x19NY\xa1\x16\xb4\x9b\xd0\x1aqKV\x025\x82\x19sK\xf0\xbb+\x00\xde\xff\xcck\x88!\xcb\xb3\xfb,\x0f0\xf3\x1b\xf3Bp\x19-\xf0!d\x91\xf4\xf1b\xb1\x83\x1b?.1\xf5\xb0\xc5Ys\x1e\xcb'2=\x91\xf0\xd5\xec\xb19\xcd\xf7l\"\xad\xf7\x1fV$s\x82+h\x8cM\xd5\\\x1a\x1a\x88U\xd2\xcd\xca'\\\xed&\x86\xbb]\x7f\xe2\x14\xd0\xf4\xc5\x96E\xb2\xc3\xba\xcc\x15\xdd\xe2\x96\x93D-\xfd\x8c\xc7]\xfc\xb463,\xb0~\x0d\x8e\xbc\x03\x991D\xc3\x06\x97v\xe6\xebvL\x16\xb1\xd2hO\xd1qJP^!\x19\xd5\x19\xe3\x88Z\\\xf5\xae\xc8\xb4\xbf\xdc6xdA$q\xba+\xfesM\xe2)\xe6BW\xc75\xc1\xf0\xbev\x14p\x0c\x1ebY\xe1\xe1\x11\xb3\xc0\x14\xd8\xaet\x81mvp3dJ\xa7\xbf\x02\xb2\xb0\\\xc6\xdb\npV\x84iq[]:\xd5\xc4\x07\xb4\x81\xe8{\xd8\x13!n8U\xfeP&d\x0eu\xce\xf3;C\xdc\xf6\n\x86z\x15\xd7\x90T\xd9\x1fj\xa8W\xa4$;\x9e\x0c\xb7\xd9\x1dFU\xa4 \x95\x18C\xd8\xff\n\x00\xee\x11\xdf\xaf\x05^'>\xb5\xd9c\xfc\xafN\x14\x19''!\x11eN\xb7M]\xb6\x154S\xcd\xac\x95m\xfb\x070\xbe\x81\x06\x8d\xd9\xfe\xe9x\xbb\xda\xdc(\x03~\x890\x0e \xee\xfdkB\xa5\xaa\xe5k\x1c\x07\xaa\xd2h\x0c\xee90\x90\x8d\x97\x18\xa0\xe6p/\xd4\x0bBH\xe1\x04\x15h\xa8\x1c\x93'\x05\x95k\x9eW\xb8\x1f-\x01\xd8\xbf\x00\x1c\xcf7eI\xb2\xad\xa0\xe2\x08\x11!w\xe8\xb4u\xfc\x15\x1f\x04\x7f\xfa\x95tG\xfd\xfeG\xccu\x14\xf5\x89\xf4\x92\xbb\x95\xb6\x9b\x00\xe6\xd7\xb0\xfbU\xe8q\x17\xf4#\x00b\x83\x87:\x97\x99\xda\xc7W\x99\x05')o\x17\x1fn\x8aQ:\x80\x11\x1b[\xd8<|\xa5\x8d\xf8cr1b\xe0\x8e\x83F\xf07a+\xee~\xe0\xe7K\xf25t\x8f\x0d\xcb\x8a\xc9\xf1\xdb\xdc\xeaW\x80\xbf\x12\x14\xe3+\xcc\x86m\x82&\xfc \x9d\xd4\x90\xb8\xb4\xf54\xaa\xadf\xe1\xbe\x07z\x13\xa9\xe8D\xbe\xce\xd9\xc4\x83\x8f\x8c\x99\xc8\x98Y\xf44\xe8\xc6\xc3\x08\xfe\x04>;\xd1\xbf\xc6,gi\x9e\x8d\xa2X\x8e\x93\xfc\xcb\xe9\xdb7<@\x1feMsE6\xfd\x1a\xe7\xab\x88\x8d5b&\xb6\x89H\x97lb\x9f4-\x84 \xce-\x81W\x93\xcc\x97k.\xda\xac( a\xfbH\x14\xd09\xfe\xedW\xc6\x99sM\x19\xc0\xba\xb9\xcf\xb5\x19\xc9\xa0R\xcf\xc9\x11_D\x8ck:h\xf1\xec\x0e\xc2\x06\xed+\x97\xda\xa8\xdc1\xb8v\xb7\x88}i\x8a\xb0\xa6+}\xe9\xe4\xeb\xf6f\x87\x85\x88\x96\xed6\n5\xb6+\x9ekN_\x89\x00b\xf8\x1d\xfba\xfd\xce=\xca\x04\x1b\x8d\xaa\x8a\xf5\x13\x11\x0eI\xa0I\xa3\x9a\x0dB\xf5\x9e\x99\x07\xb3M\xbed\x131]0\xbbV@\x9a\x8c\x11C\xd5\xdfx\xd3\x16\xb6\x1f\xb2\x0c\x1e~\xef\x19Rl\xca8k\xea\xff \xf6\xf7\xb4\xd7\xe5\xd6\x98\xbc\xa2\xb0\xf5\xcb\\\x17O,\x9cT\x99r?P\x99\xf4\xc3\xf7\xfeF\xfepE\xa0$\xf1lE\xe6\x10\xc3*.\xe7\x90&\xeb\xa4\x86|A\xc7\xcbMT\xa0\xdcd\x95g\xa3V\x0eD\xa2DW\xb9>\x87.5\x93zK\x03\x97}&\x92\x08i\x9b\x19oy\x00\xe3\xac\x0f\xc0\x01\x00\x00\xd0_\xfe8M\xfd\xcd\x97\x8e\x0fi\xa0\x88\x97\x13\x82\x0cmfm\xe56p\xcdN\xd0-\xdb\x91\xb4/\xd8\xa9\xbc\xc3Q\x03\xcd:Xv\x04\xa5}\x89\xc4\xb9\x9aE\x1a]\x85o \xab'J\x8e\x0dtu-p\x1f\x1cla\xc7]\xa6\x95\xaa\xd9\x97\x0bPD\x11\x87\xc7P&_]\x89\x99\xf1\xfe\xa8o6\x8e\xd1\xa3\xd4\xe2\x0e\x06Qdh\xb2\x8a\x99 w\\\x08J\xbf\x0e\xd9\xaa\xfe\x98\\\xf8A\x10<\x85\x1d\x9fB\xc0\xaf0\xa9A\xcb\x8c\xff)\x87M\x00\xc4\xaf\xf8\xe5\x87\xf3`\xc6\xdft\x89\x12s\xcbi\n0;\xc5\x11\xe5\x16\x16I\x16\xa7\xe9X\x80\x8d\x071-; %\xd7\x85bL]Hc\xeaQ\x8dm;l\x10\xeer\x01\xb70\xde\x8c\xfa\xdc\xcd\x86\x15\x9ck\xde\xb2;p\xd2G0\xeb\xe7\x12Q\xac\xe2\xb0(\xed+Q\x8ck\xeeO-\x91A\x9d\x8cQEa'\xfe\x04\xfaY\xfeu\xe56p\xb1\xa4\x1d\xb9\xceRTj\x99K\x95cf\xd12!2%\xec\xee\x16\x97\xf8i\xd6\x1a\xd2,\xc0\xf1`\xbc\x1dxo\x90\x8d1&}\xef\xd5\xad\xeel:1J\x07%YT\x13X\x0b4\xd1\xd3sL\xa1<\x81\xe5p\xad&\x05\xd7\x04n,Ue\x04\x9c \\\x88\xaa\xfd\xa9\xb4O 5\x0c\xf9u;By\x93ay\\<\xf8\xc3\x87\x03\xf1\xe0\x87?=x\xfc\xdd\xb6\x9f>\xde:\xa5\xe4\xc1\xf6\x91\xef\xf7\xf7\xb6\xfdt\xff\xbb\xed\x13\x04\xec\x7fIF\xca\xd6+\xa9\x94\xf9\x8d\xe2\xed\xeb\x07\x93\x1b\x95\x98,2LT\x93\x8aY5\xe9\x07\x80\xb5jq\x80Q\x99\xecm\xebV\x9d\xe5Z\x8a\xa1$i\\'W\x04~z\xffc\x08\xd7I\xbd\xca75\xac\xe2\xab$[B\x0c\"\x13E\x84Y\xbe'\xf0\x07\x19\xf4\xf4\x0f\xf2\x1d\x7fZ\xe3S].Bh\xa0\xf8\xa9'\x97\xd6Z\xf5w\x9f2\x89ep\x82^b\x84\x9e \x9f\x0c \xcf\xf3M:\x87,\xaf%DJ\xb2 %\xc9f\x04.\xc8,\xa6X\x93/&\x80\xb3\x16\xb92\x11\xc3:c6\x0d$\x1e\xc4)\x1f!\xe9\x05h\xa3P\xfb\xde\xef=\xb7V7\xc6\xe9 \x9b\xbfwS\xa2\x89o\x8b\xda\x084\xe09\xd5\x98\x9eeA0\xc0\xb1 \xab\x80\x14\x99\x90\xe1U\xa6\x0c\xc2E\xc3 ,{\x8b>\xec\xbfr~\xce\x15\xabz\x1eA\x97\x91\xc6\xca\x10\xf3\x91\xa9C\xe1v\x81\xee\xb8W\xf9\xa4+\xce\xda\xfaKM\xf8\xed\xb6\xd0\x95\xbe\x03!B\xeaWY\x88\xcep\x0c\xbae\xae\x038\x86\x1a&\xd0_\x96:\x80 \xf8\xb4U8\x82W,G\xf8_N\xdf\xbe\xe9\xcf\xdb\xc8O\xf2\xcey\x1b\xb5>U`\x88\xef\xdd@\x90Zq}\xa6\xbd\x85f\x9a7.\x17\x7f\x0f\xfbR5V\xf7\xeb\n\xdc>\xed\xde\xd1\xe91\x1d\xcd\x18\x9b\xac\xe4e\x87\xca\xf6\x89J\x91'YMJNG\xe8\x9e\x87yN*\xacC>%U\x0dI\x06\xf3|\x86\xa1\xa9\xb5\xf9Th\x91\xadh\xce\x14\xcd(\xf9t\xbb\xc9\x16\xf5P\x9e\xe9\x11\xad\x95\xfe\xb21\xf9 \xea\x8c?\xdc\x14\x84\xeb\xfbN>\x15dV\xa3\xaa\x8f}\x14\xc2\x12\xadi\xe9\xbcU\x90\xd1\xc3\xd3\xdbd,\xaf\xcc\xdc\x03\x96|\xe0\xaau\xa3c\x9e\x92\xf7\x80Y(\x92\xe9\xde\x99\xbc!!Q\xb5\xb9\xa8\xea\x12s\xc1\x80\xe7\xc9~\xa6g0\xc1\x0cXHb\x1fx\x01\xd3\x86\xb9a\xdfb\x90~\xeb@\xc3\xd9\x82\x13\x89J\x9b\x8cT\xb3\xb8 >\x91\xc9\x9f\x1e\xfc\xd7\xfe\x83e\x88\xb9\x9d\x94g{\xf8\xec\xbf\xbazP\xd3\xd0\x8a\xc1\xa15\xfdkzg\x1d\xed\xa9\xbd\x7f|\xc0\x1e\xee\xbbv?\x1fdP~\xf6\xeb\xc6\xa4wG\xa3\x95\x11\x9b\x97D\xb3U\\>\xab\xfdZ\xda\x0b\xe9\xe9\n\xcb^\x86\xa6C\xf7u\x1e\xfe\xbc/\x8e_j\xdac\x8a!;\x98\xb9^ \x0e\xfb\xf1{\xfe\x03k\xd0_;t3;M~%\xf8\xcc\x10\xb4:1q\x0d\xf5\x01\xef\xc5K\xcdpsL\xf5\x95\xf3\xc0\x15\x1f\xf0\xda\xb9\x0cA\x1b2Sh\xd2\xec\xa7\x0e\xf4\x01\xc1)\xe01\xdd\x12\x13\x84\x00\xb22q\xe1\x17A\x93@Z\xdb\xda\xad\x9f\x19V#\x86#\xf0\xf1\xee\xc2\xfb\xbe*\xc8l\x1d\x17\xf7);\xf8'/\xa0\xd4\xed\xf7\xd8\x89\x9ep\xd6p\x84\xce\xfc\x1d\xdb\x81\xe9Y\x80i\xcf^\xe43\x0cZ\xea'\x98\xca\xd0\x86B\x1b8\x02\xcf3Q\xffq\x19\xadi[\x1b:|\x84Q\x81\xb7\xaa\xf9t\x83$\x86\xfe\xef\xda\x9c\xd2$n\x92\x18c\xb6\xcf\xfd\xd8h\xe8\xa1\xe3h\x86\xe7\x9eO\x13\xbc\"\xc2\xff\xb9\x93\n\xbf\x7f\x89\xbb\xfbW\xfdu\xe7 \xbd\xdaC\xa3Kr5\x94\x93k=\x94Xk9\x98\xb0K\xa6\x82\xd2~{1\x94X\xeb\x9c%\xba\xd5e\xb3\xbd\x16}jSH\x9d\x88>\xb5\xcd~\x1aL\xf2{:\x94\x13\xeb\xb9\x18\xae\x16J\x97B&\xef\xbfz\xc6\xd3\xea\xbf'\xcb\x93O\x85\xef\xfd\xdd\x9f\xc6\xf7\xffy\xb6;y\xf0\xe0\xf3\x83\x07\x81\x17\x82\x97x\x9a\xef\xder}\xf5\xf3\xe6\x8c\xf5(k\xf7\x9e,\xf0\xf0\xf6\xec2\xb4(x\x03&2M\xe2\xc7,_\x7f\x87\xebGk\x00\xe0\x17\x9c:\x04\xef\x0f\xf2\x1d#\x87\xbd\xe7\x1f\xf8\xa4\x07\x94?\xaf\x8d\x8a(f\xcd\xf1MI\x16\x06K\x0e\xa1\x91\xec\xce\xdf@\xdbE\xc1\x8b\x00\xbc\x86a\xa7\xd2^\x08\xda\x83I\x14\x94\xc8i\xad\xcb(\xa9^\x96\x84\xa47o\xe25\x99\x07~e\x0d\xeeN\xfb\xc2\xb4sJ\xf6#?\x93\x14\xd3~1\xaag\xe2\xda\xc20\x05\xd1\x04\xd6\x9b\xaa\x86\x0b\"Y8\xf0)\x9a\xdc\x7fO\x16\x81\x913U\x0bk\xc5\xe1\xfe\x98\x8f}\x02\x0e\xd9A\x16\x1b\xbc\xa3_\xd9,\xcamW\xa4\x14\x8e\x0b8B\xb1\xdc\xdek\x81\xa1\xb7\xf7\x1c\"E`\xd8\xee)\xf3\x9b\xb5en\xa3\xe5\xca\xf1\xbe\xca\xed\x02\x85\xb6\x96\xd2\xae\x0b8\x86\xdc/BH\xa9 gL.+\xca\xb8\xdb\x01\x8e, =-\xec\xb5A\x15X\xe6v\x88\xc0\x18\xd4\x01\x8e>\x0c%\xae\xdc>p\xc5!\xd0\x1f\xc8\xad\xd7V$[6\x91\xc7\xac\x9d\xdd8\"\x03\x12\x90\x95?\x0f\xe1*\x84\n\xcd\xbb\x1c\x16\x029\xa1M\x9aR\xb6\xeb\n\x8e\xc1\xbfA\x91y.\xfc\x07\x19\x9f\xe8/\x05u\xf1o\x02\xc62/9\xd1\x1dV\x93q\x99\xf6_\x06%\\)\n\x8c\xc6\x88\x80\xee\xa9%OhD\xe9(Bh\xe3_\x850\x0f\x82\x88+\xad\xe0\x18\x96\xf2\xef ,\xbb&]N[\x0ddl\xa3\x11\xbb\x0d\xb6\x00/\x8c\x051l\x01f\x18 j\xb0o@\xe0j\xa4\xa5\xc6\xc5\x98\xd3\xa9\xe9\xa9\xa2\xdeZ\xe7W\x84\n3\xb0t\xc8\xfaE\xf7\xefEK\x1b$\xa4\xe4\n\xd3\xdf\xb8-\xc77\x1c\xae\xd6\xca\xb63\x0b\x84\xc6\x89\xee\xca+\x14R\xd3f\x96\x17\xa12N\x91\x1b\xd0\x9acT\x14\xb9\x94W\xd6\xea\xb7\x81\x03\xe8\xdc\xce+\x10\xc4l\x9c\xc5\xb6Z\x84\xfa@\xab\x005\x15iST\xc4\xf5**\xc9|3#\xfe\xd6C\x00\xf52\x96ytNk\xbc:\x9d\xd6nA\xa2h\xc1\x8c\xfd\xee\xfb\x08F$\xa55\x15>hU7\xcc\x9d\xe4\xb9\xb2$S\xb5'\x7f:\x82=\xd4U\xec\x85\xcdmn\xe0\xd7AG\x1cv\xf2\xa4\xd3\x15q\xb1\xe3\xd7\xd3\xcc\xe1\xb2\xbf[\x86\xe2\xf2\xe8\xca\xad_\x8f1\xb7\xb9\xf5K\xe1\xa5q\xd1\x88\xe4\x17\xd6o\xed7\x12\xdd\"p\xc9\xc6\xb5\x81\x95\x011\xbf5\\\xf8\xf7\x9ejd\xb0W\\\x80T$\xbc\xd7&23\xcfg\xcf\xe3\xd9\x8aL\xe0\x9d\x1e\xb5\xe3\x8b*O75I\x167\x13\xc8\xf5uf)\x89K\xde\x8c\x9b\xd2\x85\xf33;\\\xf1;')\xa9 \xbb\x8a\x98t\xf1\xf7\xdd6\x91-\x94\x16\xcd 6\xa8x\xf4\x93TE\xf0 \xbc\xd5W\xba.\xe3\x82\xd7H\xf45\x96\xa4F2n0\xbfG\xdd\xf7\x04b\xfd[\xf2\xa9.\xe3Y\xfd\xb2\xcc\xd7\xd8\xc8F_M\xde\x06\xb9.\x87r\x19x\xce\xee\x920\x81\xec0\x88W$\x9e\xa3\xa1\x87}\xd3<\x9b\xcdHQO\xc0\x8b\x8b\"Mfh\x8f\xf3\xe0\xe7*\xcfBP\x9f\xdc\xc4\xeb\xd4\x1b\xde/\xc3\xf47\xcd\xe3\xf9)\xdaF\xef\x98\xe3\xaf\xdd:\xdf\x0c\x8a\"\xe8^\x84G\xf6\x80\x91\xce\xb6-_K\x02_\xc5\x0b\xf2c\x1e\xcf\x07=\xb4F\xe1-\xc7\x19#\x0fH\x97\xe1\x1dcF?\xe4\xe8\xa42\x81\x99\xbe\xaa\xb8\x1f\xf9\x8b\xfa\xc9%\xc9&\xb0\xe8\xd3\xa5\xa0k\xb9\xc3\xa7\x08G\xf0\xaa\xaf\x8a\xfc\xd9\xaa4\x17*V\xa2^\x0f\x10\xf5z\xa0cp\xd0\xeeD5J\xa9{\xe6FcMZ\x1enm\x0ds\xf0\xed\xf6\x9f>\xfa\x02C\x1a\xf5\xcd\xaf\xa0Z.\xad\xeb \xdb\x1a\xec\xc0\xb0\xd1\x0e\xe8\x8fI\x93\xc29\x17\n\\3\xba\xf6\x87\xc1\x14\x95h\x12\xa7Q!\x99\xb5\x94 ^1\xe8\xa7\x85lv\x1c\xadI\x1dS\xa4\xe6\x7f\xb24\\6\xe5\xe6f\x1b\xe5f\xdeUnn\xacZ\nf\xd0\xd4Isk\xfb\x08T\x0dl\xfb\x16\x1a!\xd8\xe813\x88i\x9b&\xc3$\xb5\x08;\x8fH\x88\xabL\xb1m\x89\x003\xf8Vhn],\xdag\x98\xee\x04\xb7\xc3\xf0X7[\xf0.\x80\x1d`B,8\x82Y\xcf\xfe\xa2[\xa8x\xcd\xf8\x1d\xfc\xc0\xdfca\xd89\xfb\xf4\xcbm\x08\xb3 \x88\x10\xd6n:\xd7i\"\xe5\xe8M\x08\xbf\xdc\x062c6\xe9\xf8\xa78\nb\x887I;\xc4\x97\xfd+\xe0_624\xe5\xb8\xed\xb8A\x0b.\xa4\xa3\x8b\x81\xa0W]\x13\x89\x94`\xfeqH2h#*\x8b\xbdT\xb9\xe0)(\xe6\x1d\x1d\\\xb5\x9bU;\x9b\x18'\xd1\x9a\x94K\xf2\x82\x90\x82\xae\x98E`\xba\xb5\xc5n\xe2\xad.\x98\xac\xdci|\x16\x04!\xcc\x18]\xa2\x84J\xd6\xe2\xba\x9b\xa9D\x96M\x08\x1eV\xf3\x02\xfaM\x9fG\x10\xc5Y\xd6i=\xc1XTc\x0eu\xeb\x19\xd9z%e\xf7\xdf\xc8\xd8T\xfd\xf5+\x1c\xd8\xf9\xd0\xadl\xd2\\\x90\x8e?&\x1b\x9b\xf0Qgei9+{\xd9\xd6q\x1d\xec^\x82\xe2\xbc\xec8\xa6O\xcf\xec\xea\x9d\xfe\x1d\xa2E\x1c\xe9wC\xa9q\xd2\xb1]+\xa3\xaa \xb3\x10\xaa\xa1})e\x90\xfey\xe2@\x84\xdd\xb4}\x9bi}\xa6,h\x19\xc9\xa5{\x1d\xcf\xca\xdcO\xed\xa4e\x94.E\xe0]\xe3\x87j\x0bR\x03\x0d$\xf2\x0e9\x1dv\xec\x18P\xb4\x04\xea\x8a\x88s/\x0bac\x10\xb3\xb4O%!\xd64d5\\\xfdoJ\xf6oB\xc9\x9a\xa4\xcd\xa3(\x99i/\xd0\xd1\xc6z\x1aa\xda\x08\xd2\xb1qC\xd9\x122d\x06NK<\xdd\xb4w\xf4:\x9f\x93T\xc0\x9d\xedjZ\xc7\x80\xeaN\xbbY\xe5\xed\xed\xbbx\x14\xe3>~\xaf\xc5\xff\x8f\xef5\xfd`\xcc.*\xd2T@\xdf\xf3l\x95\xa4\xf3\x92d\x13]\x8cq\x16e\xb0v3BM\x86l\x95\xe4\xe1&b\"\xca`\x0b$*\xca\xbc\xce\xff\xca\x9fgp\x8c\xbbe\xd3\xde-\x99R\xab\x89P\x8a\xc6\xc4W\xec\x99\xbf\xa7\x04\x8c\x08|\x12\x89\x99i\x94\xcb\xc6\xd3T\xb5\x84e_Ok\xc3\xa5V\xab\n\x1cAB\x913\x13\xa3\xd1\xba\x19t=\xf9~u\xc2\x19\x0fY\xfcm\xf8\xcbC\xdd\xcbJ\x98\xd7i-\xe8RA\x90\xb5\x0d\xcfTM\x91 \xf2\xae\x17i\x9d\xb4\xf6\xcc\xb0M\x86o-\xf3\x9cR\xc1\xdc7\x9a\xba\x81\x8d\xe8t\x1c\xc9I\x08S\xf3hd\\\xac\x11\x81\x89\\\xb8\xb9\xabnP\xf5\xb8$\x19\xc6\xc2\xda\xb1\xa5\x1bB\x1b\x13[\xfb\xa0\x08\xc5dJ\xd4t\x03v\xd5\x08p\xa3\xe3L\xee\x00;K\x17O\xcb38\x86\xc4\xa7\x7f\x0821a\x8fq\xbd\xe8\x83\xc1V\xb8\xe7u\xe2\xcb\x85f\xcdl\xd2t@\x91\xae_\x7f{\xc0\xa9;\x8e;G\x17\xc5\x97\xb1;\xa7g\x81\xd6\x19FL\xccE\xed$\xd9\x04\x19\x15\x92\x81$S\xd3,*\x7fS\x9ei\xef)\xe4\xf0}c\x87~\xef\x1e\xf8\x0c\x03\xf2\xb3\x10|D\xb8\x86lN\xcb\xb3\xe0)\xe4\xbb\xbb\x01\x0b\x911--\xd7\xfbb\x1a\x18\xe0E\xa1\xd7_eu\xd8\x8e\x18\xb3F\x0e\xdb\xaeu\x03A\x945\x82cfi4Q\x9f\x1e\x888\xc9Hu\xd0\xafE\x11\x1cu6\x0dN\xfb\x12Ui\x8dA\xa8\x05\x0f@\xdd\xc9#6\xa4\x98j9\xcd\xd0\xa8\x9eE\x8e-Y\xfe\x85\x1c\xad\xd4\xd0\xe8?\x04\xfalxg*\xc4w\xf4V4\xfa\xb7\x9b\x99\xf7\xd9X\x06o\xf8\xd6\xe5p\xc0\xf1\xf9\xdf\x8b5T\x7f\xfd\n\xdc\x84\x10\xc3\x1e\x0e\x89aZnB\xf0!\xfbZ\x8b{\xc1\x88\xeck\xe5;\xc9\x89<2q\"\x99\xff\xed\x00\xf6\x0cr\"W<\x03Y\x87\x99\x94\xa2\x1bKs\xab\xf2*\x03\x9b\x1a\xb7%f\x0b\x9e\x85\xb0\x08\xa1\x08a\x1e\xc2\nMF\xd7h\xbdv\x03G\x10\x97Kt5T2m\x1d\xa0uYc@!\xabL\x0f\xe8!\xda\xfaI\xf9v\xfdn\x97Z\x141\xf6\xeb\xd29\xf2\x14\x9e.O\x9f\x06P]'L>\x14\xd9, \x86\xce\xb1\xd11LW\xe8\x90\xd5S(\xce\xe1\x08nx\\\x99\x93\xacNJ\xf2\xa1$\x84\xa5\x18\xbe\x11\x86\xf5,\xb50\xad\xf6\x8f\x0d\xa9\xeaWYM\xca\x19)\xea\xbcd\xc9\x86\xe9\x9b\xaa\xc8\xb3\x8a\xb4^\x15\xf8\xaa\xad\xe7b\xd9Jo4\xb22\xcbGl'\xd2\x80\xa10\xea\xd5\x8b\xa4\x9a\x95\xc9:\xc9X~\xbe\xcc\x8d{\x92\xa6~\x06+\x90n\xe9O\xd9x\x83\xdf-\x1a\x98L`\xe1\xf6m\x1bh\x13(\xdc>\xebCu\x02s\xeb\x97\xb7!\xda\xce3\xf6[\xa6\xbe9\xbd\x8e\x97KR\x06\x0e!\xf3\xa0 {h\xadKe\xb15\x86\xf2d\x8aY\"\xb2\xac~\x1bv%\x8cN\xea\x0d*\x8c\xael\x863\xa2\xb0\xe1\xac\xdd\xc0\xd6\xcf\x80\xe1\x1a\xad\xab\xbaL\n\x11\x85\x14\xedl\x06\xadcD\xb1^\x12\xe1&\xfe\xd6y\x13/\x99\xe3/\xc9\xea\x10vJJ\xc2\xda\n|\xe6\xdb\x99\xa9\xcc\xe7\x12\xc1\xcfW]\x91\xf8\x97|Y2\xf4\xd6C\x16\x9f\xaeQ|Qn\x8a\xda\xf7X\x87^\x08K\x97\x19X2\xad\x8e\xc9\xac*\xb5\x18\x96L\xaaF\xc6\x960VI\xebb\xd8\x9f\x8a\xb8\xa5\x93j\x8b\x81\xc3F\x0e\x0d\x93\xb0p\xb9X\x9e\x14V\x9d\x99\x1f\x8ce\xaa\xfe\xbdX#\xfd`\xf2A&@s2\xef\x19O\xe6\xbd\xf6\xc9\xbcg:\x99{kjSE1\x0b\xe97\xf1z\xc0+\x809d\xaf1\n\xbb\xb9\x16\xc6\xe2\x8d(Yf\xe1\xb2\x0c\xb9\x9a\x9dG\x08|\x94\x89\x1eV\xfbFX\xed\xb7a\xb5?\xc4\xc5\x80\x8a\xdb\xe4\x13\x99mj\x16rZa\xcf\x86\x891#\xc2\x04I\x8ay\xc7\x86]\x1aDB\xf0\xfa\xe7\xae\x87O{G*}\xbc\xa9H\xf9\x92\xd4\xb3\x95g\x8d\xc1&V\xd4\xca0\xb0%\x9d@9\\M\x0d\xcaeI)\xac,\xffP\xa8\xb4\xdb\x10\x12\x831\xb7\xf5\xd6\xde\xac\x1f6\xed\xb6\x9a\x1d\x1d\x94\xe6k\xbb\xe4*\xd9\x0b\xfd\xdbF\xcd\xc1\x03\n\x1c\x03\x95\xd4\x0d\xa0\xcd\xb1-\xbe\xcc\x1f\xe2\xa5\xbeV\xd2n3\x87c\xf0\xf87\x1e\x18\xcd\xa4c\x96\xec\xe7\xe0m\x03\xe4\xe7\xf9\xba\x88\xeb\xe4\"I\x93\xfa\xe6u>7\xec\xe2\x8d\xc1\xdb\x96\x96\x05\xbe3\x92\x12\xc6\xaf\x90x\xb6\x92\xdd\x06\xf4\xa8\xb0s\xfa\x8d\xb6\xdbNb\x18\xd8l$&\xc5Z\x12\xc7\xf4[\xdaO\xa3:^Vp\x0c3\xfeg\x00\x13\x98&gc\xcd\xc0[\xce\xb4G\xaa3\xad]\xbb\x8a1\x1cX`\x1c\xfc\x8f\xddF\x0c~\x06\\\x97\xcd\x00\x9e\x17\xaf\xe6\x81\x9f\xe2\xfd_n\xdb\xf0\xa2\x0c\xa3\xc6\x04bk+:W\xedn)PDv\x1b\x11\xe7\x98\xed\x8d\xc2\x18\xba%\x8a\xa0_\x86\xfd\xd2-\x12q\x9c\xfd\xd9Z\xe4\xccL\xdeE\xb1\xf9wQ\x8c\xdaLgg\x01\xd0\x7fwwCH\xa6\x9e\x07\xbb0\x83]|D\xf1\xa5\x18n\x83\xa9\xa9\x9b\xb0D\xf4\xecK\xb0M\xfb\x8aP\xcc\xa4\xa2)\xed\x8a\xa2\xa4C\x04a\xacz\x04s\x16\x8a|\xfcp\x81wK\xe5^:L{m\xeeyA+\xb7:\x9c\xd3\xde\xcc\x89\x9bAQ\xe2\xb31\x17\xc6\xba\x06\x06Z\x7f\xa9\xd66;\xfb\xcaj\xb0\x10\xea\xa8\"\xe9\xc2\xe0'\xac\xde\xb2\x1d\xf6-\x10\xd6\xf1%9aL\x0c\x1cQ\xb2\xc1\x1e=+\x92\xeaC\xbc\x94\xb4\xa1\x92\x7f5\x95\x9d\xf4Vw\xc0\xb2\xea\xf7\x1dj\xce\xd4\xe1\x1b\x9d\xf63^\xb3hMh\x80\x1a\xd9h\xe2v\x07*t8?s\xad\xd9\x85Ic`\xa2\xb5\xa5\xe1@\x96w29$\x99\xe9>KVJh\xa5r\x9a\x9f\x0d*\x9c$\x81\xab\xb47\xf4\xc0x\xb5l\x9a\x9f\x05\xd8Xs\xf8V,,\x8d\xb9i\xceMO\xf0\xebi\xa2W\xf2\x9b\xf9\x0e}\xc3q\x91T\xba`\x81=\x1b\x0d=\xe6\xffK\"\xfaV \xf8\x8f\xd9\x03nK\xd9\x9e*=K\xfa\x84Q(\xf6\xbf\xd5\x9a T\\u\xdf\x7f\x93\xda\xb0\x02\x9a%\xd1\xbalj\xd6z6\xc6}\xa5g\x89\xca\xb4\x12:\xd7CMW\x0b\x16.\x8d\x1d\x1a\xfa~\xba\xf03:\x17*\x88\xa9\x13\xdf\x9a\xa5\x19w\x07\xf6\xe4` \xce\xf1\x7f\x86\xa6\xe7\x0b\x85O\x85\xd14\x1f\n>\x89*2\xdb\x94I\x9d\x90*\x04\"\xee*0JPV\x7f\xb8)\x08{\xca\x14\x08\xcac\xc3I\xc3\xa4\xaej\xb6\"&\xd9\x8c\x89\x9c\x9a;\x11m\xed\x8a\xd7\xee\xdf\x93h\xab\xcf\x98\xdc\xcd\"\x19\xfcT\x1ax\xf2\x05\xd6\x92\xea\x0f}\xa5\x82\x81\x87\x0f\xf4\x87|~\x13\xa2\xb6\xb8\xbc\"\xa5a\xf2s\xaeP\xa6U\xfe\x1a\x97I|\x91\x12\x83S\xed\n\xab\xae\xea\xdapE\xb1\xe4R\xaeP\x93\xe8k\xdd\xb4k\xfd\xb0I\xd2\xb9\xb1\xb2\x08\xe2\xf5)J\xaa\xb7\xcfN\x0f\x03\xbf\xd6\x1c\x147\xe8\xaeO\x1b~\x0b\xc7p.\xef!\x95\x88\xe8\x86 \x83\xef\x8c\xc4bS\xa6\x13cd\xa3YI\xe6$\xab\x938\xad&\x80Z\xf6Ut\x9d\xd4\xab\xe7\xcds8\x06/\xc9f\xe9fN0\x0ca\x15\xaf\xc9}\x16C\xcc\xd0h\xe3\x08l85gy~\x89q\xdeuF\x84\xfd\xf9\xc5\xa8\xfd\x7f\xa7A[z\xb4\x07!T\xb2B\x0fS\xe1\x08*\xca\xf4\xf3\x1a\x12\xed(=7\x80\xf2\x83\\\xaa%\xa9%\x91}\x1f_\x07CQew>\xa8\x91U\x9f\xfb^\xc3\xa4P\x89'\xc3\xd0\xb1Y^\xc3\"\xdfds\x9d\xab\x10\xed\xfb5F\x9e\x94\xd4C\x0f\xbeWmm\xd3k8\x86_na\x02\xaf\xf5\xd5\x7f\xc66\x87t1o\xb0\x86\x10\xd7\xf5\xf3{\x17m\xca\x14v\x8f\x8c\xa6\xa1\x83\xaa\x01F\x93\xcc\x01\x03$\xcd0\xdeT\xb2\x8dm\xbcU\xec\xec{c\x18\x9dF'\xf1\xc6pdr\x1d\xc4\xcf}\xcc\x0cB\xd8\xc9\xa4\xa5\x8d\x88(\x10ql\x0e\xe1]\x1fr\x12joBx\xc7\xd7\x80\xa2\x17J\xc1?\x07Q\x9d\xffT\x14\xa4|\x1eW\xc4\xc7\xa08G\xb0d\xca%=~\xbc\x97*\xfej\xfa\xe6\xccT\xb3\xe4\xd8\xce7b\x14\xa3\xbb=e\xa7\x0ch\xf7\x02\x8e\xe0\x99\xe2\xa9u\xea\xbfR\xc8_\x104\xcf\xdf\xb7\x9ek\x9a{1B+'4\x8a7S\x12%\xd9\x80-ai\x89\xb3\x85\xaa\xbd\x8b|~\xe3\xc9\x18\xb2\x8ca@\xbc\x8b\xd5\xbf\xa3\xc6h_Z\xb4-;\x11\xb5\xd0:\x8a}\x94\xc5k\xfck9e\x7f\x9fQn\xce\xf0>\xc1M\x1e\xb10\xadX\x19&p\xe9\xb3\xbfCx\x11tn;D\xc2\x96\xeb\xb8\xcc|\xef\x9d\x80+\x8f\xd4\xcf\x9a\xc6p\xfdI\x05\xf1\xfa\"Yn\xf2M%\x83\xdb\xd7+\x02<\n3\xee=X\xc5\x15\xac\xf3\x92\xbe\x893\xc83\xd2(\xfa1;\x00~\x91!\xee\xf7z\x88\xb39\xbe.\xe2\xaa\"\xf3\xfbI\xa6|\x8b\xba\x8d\n\xe6 \x8b#\xc6\xfa\x848\x83?$\xd9\x1f\xd8\xdb\xc8\x0bB\x11\\\xebh8\xf6bG\xd5%u\xeb\x8a8\x86\x91\xb9\x1bsCy\xf2\x85\xbd\n\x8cCHJ2\xa7\xbfvH\x84\xb7\xe2'\xeb\xa2\xbe\xf9+3\xf9nH2\xf7\xe2|/>h&\xd8\x06\x06\x856\x9dgQ\xe6W\xc9\x9chI\xb5:\x99\xb7]L\xf3\x98;\xa8@E\x8ev\xf5M\x81\x88\xa2\xd1@\x976\xaf\x0d\xe0[@I\xa3:\x90.\xdf\xcdK\x03d\xa02\x058M\xb48\xec\x85;\xb6vqA\x84\x97\x8c+\x1c\x91!\x041\x18\x15s\x80l\xf2\xbd{\x90Y\xb4\xce%\xf9\x871\x0e\x8d(rl\xd6@h\"3\xc1p-E\xa9\xfcj\xb8\xa6\xcdz\xc4\xd9\x9c\\\xa7f\xa6\xa4\xf1\xc7\xbe\xa9\xc3/\xcc*@\x0f6u\xe8N\x9d\xa0\x9d\xf1;\xcem\xd2\x9e\xae\x9b\x9e~\x0c\xe1]\xc0\x83\xef\x9ct\x1e\x07\xe2\xcc\xc3M\xda\xb6\x80\x97\xe7a`\xf1\xbd\xa43\xfc\xa9\x9f\x8aM\xf9~l\x98/q\x9c\xc8&\x8c\xde\x18\xa0J\x96\xbb\xe0cP\xfb{\xc8\xdeb\x18\xec&goE\xca\x04M\x8b\x06l\xceoC\xfa\x99\xbe\xa7\xe6\x10~\x8ec\x82#\xf8\xa9\xbf6\xfd\x13\x9c\x0d\xee\x9d\n\xe8>\xc3\xc1\x02#\xa17\xf6\xab\xec\x7foHy\xf3\xb6|\x99\x97\xeb\xc0\x7f\x17\x84\xf0\xeew\xed>Z?m\xf7\xac\xcama#\xb20\xb9\x97\x9e\x80ng\xbbMV\x06)/\xdbo\x14K\xa7\x1b\xc5\\\x11\x02\xcd\xb5\x12'A\x15\xa4\xbc\xec$TB+\x99!\x12\xffXp\xe6\x03\x86{\x15\xdf\x02J\x92\xb6:\x84\xa9\x87<\x9e\x87\xf7\x85~\xc9\x82\xd3Rv\xf1\xc7\xfc\xbaa\x17=6\xb0\xca;\x0bD\x9c\xb7\x81f\x1cj75\xcc\x03N1n\xbb\xf9\xfd\x8c\xc7\xd94sj9\xc5fDi\x97,\xae\x14\x91\n*\xc6\x8dL\x85*\xcd@6\xa59*\xdb\xd0\x0d_!c\xe9\xe5\x01\xfc \xee#\xcf\xe6\xa7\xec&\x86\xce\xb2\x9a\xaaUL>\x93;io\xba\xb2\xa1j\xbawF\xc7'\xda\xdb;\x0b(1\x14\x8dz\xbfxM\xcfn3o9zL\xcf\x98\x87\xc7\x83_\xfc\xe9\xdfo\xcfv\x83\xdb\x07K\xd5\xcf\xe3)\x0bs\x81\x862> \x9e\x06T\xb6\xd8T+\xbf\x9c\xee\x9f\xd9}6\x0d*`?\xdd\xe6f~\x16]\x89\xfd\x85\xbcq\xf3sJ\xac\x97\xa1b\xc2\xed\xaf\x86\x8fo\xe0\xc4g\xc3\xef\xf3\xa5\x0d\x9b\xfd\xb3\xb2\x13\xc9\xfd\x17\x99\x1c\xe6\xd6\x0b\xc1[\xda\x02\x81\xd0\xa5O\xa5\x97j9\xe8\xccd\xba\xdb\xd4\xf7\xd0\xb5\xc6\xb2m\xac;\xb9\x1c\xb1\x85\xcd\xae\xef\xc2\xe2\xcb\xd6 ]\xca\x95<\xb6\x19\x93l\x8b\xdfPj\xbe\xa9-\xdf\xd0\x13\xe6\x9d\xcf\x1dLgy\x8a\xb4\xf4\x9d_\xb6\x1f\xd8F\x9b\xe0\xbe[\xe5\x15z\x1e\x96\xf8\xd7\xf0\x17\xcc\x85\x8e\x92s\x14T\x1c\xfap\xc9\xac\xcb\xf1E\x84O\xf3\xe97H\x9e\x138\x86\x9cb\xf4\xe4\x01\xe6\xd4\xf0\x13\xd8\x85\x18\x9d\xf0\x82\xe9F\xf5\x00\x84c\xd8\xb4\\\x99`b\xc8\xbaz\xeb\xa7!hr\xb2\xdf\xfa\xe8\x9bk\xa7\x15\xe3x\x8a!=8H\x8e\xc2\x85\x0b\xc8\xdb\xc7z)R\xb2XX\x8c.j\xe5\x03\xa8E\x97\xb7}oT\xf3 T\x98\xf4K\xfc`;\x0e\xfd\xad\x8cma\xf4/\x8a!1\xc3\xcd\xa4\x83\x9b\xab\xba.\x06p\x87\x19\xf4\n\xdcL\xe4_C\xf8\x96\xe27\"\xb0\xbb\xad\xf6\xcc\x82\x99]\xac\x9caz\x17>\xc9\xae\x99+\x96\xf6\x89\xf0\x1b\x17&\xc6\xf2\xbfy\xf80E\xdd\xc4n\x98e\x8di&i\xa2\xe6nU\x03\x82\x7flH\xf9\x95V\xc86{ &\xb3\x8e\xbd\x8ep|\x08\x03\xf6\x17\x87\xc0\xce>w{\xbbw\x0f\xbc\x8b'?\xbd\x7f\xf5<_\x17yF\xb2\xda\xcf4\xbe\xa7:\xcb\xea\xbc\\\xbf\x88\xeb\xf8_\x12\x00~\xc64\xc1=\x0b\x16F\xa5\xe8\xd8\x11<\xf8\x87D\x13\xfa\xcbiC\x89-a\x1ee\xa7\xe3I\x7f,\xe6o]\xb6\xab\x1ei\x1d\xfc\x05\xfe\x93\x03\x0d\xa8\xbf\xee\x9c\xc5\xe8\xcb\xf9\xf9\x90\x12P\xc4`\xd2\x8a\xc8B-\xf9\xed\xe3q\x81r\xff\x05\x08\x8e\xb9bC\xa9\xcdu\x10*QU\xdf\xa4\x03\x95P/K\xd14\x1d\xf6\xae\xe9\xabr\x86%\x18\x8c_g\x1b!8moZp\x16\x13HP?_%\xeb\x82\"\xd4\xe0\x17|J\x13\xd8\xd0ol\x990X6\xa0 \xec\xec\x1b\xab\x99$\xcb!\xfa\x9f\x0b\xd2\xaf\x0bL\xf2\x1f\xc9\x98\x99\x19\xb06K5\xcc\x88l\xfa\x91\x0e\xbcM\xc6mF=n\xdb\xa5\x04+\xd2\x99\xb6\x8b\xe2\xcd )\xde*\x86\x8d|Op\xc3\xb1\\me\xa4\xb4\x0f\nq\xca\xacY!\xdb\\$\xc5\x8c\xa9\xbc}?\xf3\x86\x0fAQ\xf8n\x19\xb5\x15E\xc1-\xe9\x98r\x95\xf7\xe3\xe8\xce\xcew\xa7\ni\xb7\x0f\xc5\xb6\xe3\x07\xf6{\x82f\xb4\xf0\xd0IP\xcd\xc6\x1dJ\xee;e\xf4\xa1\xd0\xdf\x1e\xad'\xb7}U\x0b]\xdf\xa9\xc7S(K\xe6\x8c\x12\x9e\x9a\xbf\xec\x9ad\x11\x14\xbb\xa6g\xae\xdd\x81\xeat!\xc1\xb0\xff\xa8\xe3\xe5\xac\xdf`[t\xe2\xfd\x0f\x14\xfcM\xed\xfd\x9c'\x99\xefi\x9c\x13\x95w\xd0E\xd8_]#\x9b\x0cid\xe3F#\xdb\xd5\xb9\xb2[\x90\x17I\x85\\!\x99S\xfc\x88g5;\x01\xf3P\x1f\xc3\xdeb\xb8i8_\xb5VF\xf5X/\xb0Krcc\x04\x9cTl\x16M,3\xfd\xb42D\xcc\xafk\x88\x1e\x00W\xeb\xda\xe7(\n\x87\x13\xe6\xd6\xb2Ku\xe2(\x1c\x8e\xe1h8\x8f\xa0\x7f\xe6\x88\xc2\xa2\\2\xa6\x92\xb15M\xb6\xdc\xf1{lc\xca;/7Qhrv\xc1\x81\xa4\xf1\x05I\xbb\xe3`.\xf2_e4\xd1\xe0h\xd6q]&\x9f\xbe2X\xc6&r\xe1M\xb2,2 \x1c\xd3\x83\x84\xb9\xfbQ\x06\xef)\x05U\xcdX=\x0c#2a\xaa\xce\x10\x7f\xe9\xc70\xe0\x8e\x8a``\x8a\xb4#\x9b\xa7\xbe\x90`\x13\xee\x1c\xdb\x8ccB\xfb73\x9e[\xc0\x15\x1c`\x0b\xcaBkn\x02\xc0(\xed\xb3-Q\xc43\xf2\x82\xa4\xc9:\xa9)\x93\xee4\xfd\x94O_\x99\xf8o;o\x0f\x83\x15\x18RX\x0d\xcc\xbeH\x8a\xd1\x93\x9f\xfd\xcbM\xfe3\xc6\x0eu\x9dh\xde\x0d H\xeb\xa1AE\xc7\x1d\x92\xbe}\xc2\x1c\x92\x1e\xe9\x1d\x92\x985\xf9#]~\xff\xd4i%\x05\xec&\x0f\x8e\x7f?=\xfb\xffv\xbe\xb9\xf7\x07?\xf8\xe3n\xf8\xf4\xc8\x93\xf7\x19\xdcp\xb6?\x15\x8d&~L\xa7\x0f\xfe>\x8d\xef\xffs\xef\xfe\x93\x8f\xf7\xa3\xf3\xff:\xdb\xfd\xe6A\x12\xd5\xa4\xaau,\xd7\xb6~\x01O\x0e\xf7\xb7\xb7\xd1?\xd8\xfe\xd3\xc3/0\xefo\xbd\xfa\xb7\xd4\x8a\xca\x00\xa9f\x95\xa6\xdd5\xb5\xec[ a\xcc\x9a\xc1\x84(\x96\x08\x95\x9a|(\xd8\xe6`\"\x14\xb3\xdb\xef\xa2\xef=\x8bw\xa3\x86\xcbbtR\x8c\x84\xc2\x9d\x18\xdc{\xe7\xed1\x16b\x8c\x06\xdfeLx \x80\x89F[q\xeb\xd7\xd4\x10n\xe4\n\xb3-\xdc\xbb\x07;;\x1d\xfd\xea\\D\xc8\xd2\x7f\xb8\xee\xc7\xc6\x8aC\x98z3a\xf6\xac:\xfd\xde\x9c\xb2\xf0\x00<\xb6\xcfP*)\xe5\xa6l\xd1\xbd\\]H\xe3\xb4E\xdb8\xad3\xf42P\x14\xd8W\xf4\x1f\x16\xd3\xa6s}\xd5\xc0\x0bG\xd5\xfc\x94a\x7f\x8e\xc1_il4\x06X\x13\x19\xe0&\x83$\x1bN\xde\"8\x98\xf9t(\xb6$p\xa4^O\xb3\x01{\x0f\xb4\x07\xb0\x9d\xd3R\xa1\xcb\xf3\xd6\x7f\xfel\xbb\x10\x03\x8e\xfd9zN\x0c\x9b\x9b\xb0!X\x9bCy?.\x92\xffEx4\xcc8\x00\x0f\x17\x93\xdf3\xf2\xe0\x98\xfeB8\x19\xc8\xeb\xf0$\x08\xc1c(\xd1\xab+.\xcf;\xb5\xd9\x9dp\xaf\xb6\x08\xc0\xa6\xd6\x1e\x9e\x1d\xa8>\x18\xcc/^\x8c\xde\xce\xf2\x80\x8c\x01\x1aW\xc9L\x8c\x86\x85\xccp\xfd\x1e\x14\xae \xc1@\xc1\xf6[\xcfnAuYT\xc4Uu\x9d\x97\x03a\xcatE\xc8\xb3\x8a\x7f,\x0buA\xd9\xa3\xca\x01z\xa2\xc8\xb5\x8a\x9e\xa9w\x8ep\x04\xde\x0f\x14\xfcN\xf1\xbf\xbc\xe5\x81*-R\xae>R\xa1\xe0r\xf9\xb9\x87a\xdf\xe9\x06\x8eVq\xf5\xf6:\x13'`{x\xb9-_\xb2d\xb3 \xcf)Bi\xfa\xdeS\xa8\xe1{8\xf8\xf6\xd1S\xd8\xdd\xad\x03 ,\xda&\xf3\xca\xa1t\xff{\xd8\x7fD\xb9\xb1=\xc5\xf2\xb1\xe5\x17\xd4q\x0c2\xab\xef:>:\xbeR\xb3\x8ebJ:?\xe4l\xca\xb6\xb3V\x91\x18\x8e\x00s\xce\xd5Q\x91\xc6I\xc6>\xa7\x9c\x1a\x87\xdd\xac$qM\xfcl\x93b|y\xca\x0b\x96l\xda%|/\x1d\xb8\xe8\xdc\xcb@UV\x91iy\x86\xf8\x98\xd1?\xd8\xef\xee\x92sS\xe9f\xcd1)6)\x97\xa43\xfe,\xec;\x92\xa2\xba\xb6IC\xd9\xe1\xc3\xd9\x0d\x99T\x7f \x9d\x9b\xd6\x03\x81\xd6\xed\xc6\x0e\x96\xeb\xa8\xb3\xa5E*gVDk\xfa%r\x9cS:\x1d\x83\xe8\xe5\xe7\xedE\xf8\xfc\x99\x8a(i\x9a_\xbf\x13\x18\x8c\x0fw\xcah\x16\xa7\xa9\xdfEo\xba7\x18\x11 S\x0cv\xbb\xb37b\xc3\x0fy\x809LK&\xcd\xecBLp\x87D\xbb\xfa\xbd\xa0\xcd}\xef\xdf\x8c\xcd)A'\xd0\x16\x9aS\xdc@m\xa7\xae\x95^#\xc7\xe0g}\xc1:\x0b!\xd1*\xc0\x18\x8c \xbe>\x062M\x10\x9f\x15\xad\xb6\x84\x02}\xc5k\xfc\xff\xec\xbdk\x97\x1c\xc7\x95 \xf6]\xbf\"P3KU\x0d\n\x8d\xee\x06@\x11MAt\xa3\xbb\x014\xd4\xe8n\xf6\x03 \x00a\xa0\xac\xcc\xa8\xaaDge&\xf2Q\xdd\x8d\x11\xe6\x90#\x8a\xc2\x83;\xb3\xde\x91\xa8\x91=cy\xd6$H\x00\xb3^\xdb\xeb\xb5\xd7\xf6\x8e\xf7\x1c>\xd6>Gs\xa8\x99\xbf\x80?\xb0\xfe >\x117\"2\xf3\xde\xc8\xac\x02 R\x9c\x1d\xd59\x12\x1by\xe3\x1d7\xee+\xee\xbdqFcp[\xfcSc\xeeB\x81M\xe2o(X%\xf9B\x8e\x97\xbe\x9cjS\xf7\xf8a\xda\x0e\xada4\xd6\xe1j\xd2\x1b^\xf7\xebc6ms\xc2#v\xf4\x88\x01\xe8t1bT\xde.\x01\xbe\x90\xa6\xfe \x9cDs\xd4\x18\xca\xf3\xcb\xa6\x0f\x13\xd2H\n\x88\x9d]\x0foX\x06\xc6\xd1\xc0<.$\x95F'A\xfb\x8b\x93\xaa7\xa8_\xc9\xb1X\xce.|Tf\x17f-\x946\xc0<e\xbe\x9e\x9e5_O\x7f\xc7|\x9d\x9b\x9f\x97q\xc5G\xf5\xc0\xe4\xa0\xd8\x82\x80\xb2\xb9\xf9W40\x12\xd8\x0e_\xe7gO\x96>\xcf\x9d\x9eg\xb2\xd9\xef\xb1\x97o\xb0\xa3\xe2\xcb\xfc+\xecG\xec\xe5\x13\xec%f\xea\x9c:5\x7f\xfae\xd3\xff\xa9\xef\x9c8y\xb2hb~\xfe\xa4nbn\xbe\xdc\x06\xb4\xca^b/\x9f\xb07\xddND\x0bs]\xb9\xb0/\x9f:u\xe2e)S\xcc\xcd\xce\xcb\"\x1d\xf6\xdd\xef\xb2\xb9Y\xf6#\xa6\xbe\xa0\xb5\x97; C89k\x86\xf0\n\x19\xc2\xdc<\x19C\xf3\xd0:\x0d\xac\xc2\xce\xd5\xddh\x14;ns\x14n\xf5\xcd6\x8aaQ\xefV\xdd\xc5Cd\xbdr\xa0\xe2g\x9cD\xf1\x02kE\xd5\x0c{\x96fI\xeef\x91zH\xbb\xf4\xa1\xe8\xab\x16\"4\x85b|\xdfb_VaU3/\x16C \x1bTS=\xfe\xcf\xe6g\x8f\x0f\x8a\x16\xca\xf7\xc4\xd5\xc50\x97\xb2\xad\xadsK'N\xbf\xf22J\x1f\xd3\x97i\x89\xe1m \x8a\xbd[\xe7\x96\xe6\xbes\xe2\x95ib\x8c\x88\x90\x19uY\xeb\xa8-\xf3\x04\xa5\x13jh\xcf\xd1\xcd\xc4+\xe6j'f\x1e-\xf5W\x8b\xc0a\x00f\x95\x9eo_\xf5\x0e\x02E(6P\xbe\xbdF\xb7/l\x9f\x9e\xc3a4\xbe\xfa>\x8f\xbe\x9b0W\xb5\xbd\x93n\xfdY\xe9\x04H\xef\xc8P\xbf{\x02O\xb9H\xc7\xac6/;\x9b,;\x99<\x13\x19\xf9\xf8\x1a\xe33\x03\x9e\xed\xf8#\xde\xee@\xf5\xd2\xbf\x17T\xbc\xfe\x11x\x19\xcf\xa2!Vt\xa6\xe2\xbb\xcc\xf62\x03\xe7@\xca\x9f0\xb0\x05\xf9\x97\xfcc\x9aY2\xb5\xf0A\x97\xb9\xf5t;oC\n\x97\\\x12h\xb52G,~f\xba\x02/\xf6\x0fhp\xf1\xef\xa9\xea\xfb\xd2\x80\xa0\x0b\x1e\xf1\x85\"\xa03\xe3\xe8\xd3\xd1\x01\xf3\x91\xfag\xd6\xe92\xc7\xcc\xb4\x81\x07\xa5\xb2\xe9z&#\xad\"\xe94\x13ef\xb2\xca\xbc\x083E\xbaDSm\xc9\xd0\x02`bA\xc5\x18\x14\x1c=\xda|\xe7);\xbe\x1e\xdcP,.\xb81U\x87\xba\xc8\xb4\xe9\xfeX\xad~\xa7\x7fc\xf5\xe8W4\xf1\x8d\xd4X\x96\xcaj\\\xf6\xb4\xc67M\xd2\x8c\xba\xe4s\xb5{\xde/v\x88\xc5\xd3n\x90\xdc\x9c\xfeL\x1a%Y\xbb\xd3e\xb1\xf9K\x06\xea\x95\x9e\x88\x14{\xf7=\xd8\xc3c\xc7\xeawM\x0e\x04v\x8c\xc5\xd3l\x98\xc1\x8e/\xd8\x99\x8c\xed\xbb\x1e\xdc\xe8\xb2#N\x9b_wotY&\xff?\x9c\x8c\xdbZx\xd14\xa8\x90yi\xfa\xfd\xbb\xc5\xb1\xab\xc0\xee\x96\x1c\xa6\x8c\x7fR\xde,kHu\x9c\x15Y\x17\xcfT\x1e\xce\xbaki0\xadm\xf0H\x1bH\xab\x95\xa8\x8a\xef:\xffV\xe9\xbbA\x0e\xe9\xcc\xa9;\xa9(\xfb3n\x14\xcb\xb7\xf8j\xc0\x92_I\xf1\xa8\xa0\x0c\xea!d[\x8f\xd7go<\xaf\x04\xa49%=(\xc0\x0e\xe8u\xb3\x8d}\x9e8=ka\x9f\x13/\x98\xd5\xe2Fj`H\xad\xbbK\x19o\xd8\x9e?1[1\xb4_L\xa3pS\x1cw\xfd\xa0\x9b3S\xfc\x13\xacN<^\n\xa2P>*=s\xd3\xfc\xb3*\xee\xe5\xd6%p#\xfe[G\xc8s\xa9+\xd4\x11\xa2\\&O\xa9;\xdc\xf9\x8c\xf8o\xf5@\xd9\x14\xaa\xc0*\xa9Kw\x03\xd0K\xean5\xb5\xd5\x9e.\xa7d\x02\xa2w\x0b\x17P\xd4\x1f\x8f\xab\xfcO\xc3i\xe4Mt\x97\x85\xb0q\xa6\x8cM\x8bs\x95\x93JR\xe3\xa7R ~\xd3\xd2\xcf\x91\xb9\"\xbc\xeb\x8cN|.\x1f\x98?2\xdb\xe9\xaa\x82V--a\xaf\xb1Dp\xc2\xd9.\xe3\xf2\xeeDH[l\x81\xc5\xf2\xa3\xcc\xb8\xdcR\x179\x00\xa2\xab4V\x99\x0d\xed\xe8XAE\x8b\xa5\x95\"=x\xb0{\x9e\xee7\x8a\xcd\xce\xb93\xa5\xe6\xe4\x1d\x8a:\n\x16\x9b\x9dlF\x9d\xc7\xe7jJ\x8bl\xe2T\xd6\xb7,\xa5C\xd3\xacT\xa3\x05\x8eO\xd1\x93D\xd4\x10D\x94.\xc3\x0d\x89\xad\xaa\x0c\xa1S?\x06ql\xca\x1d\xdaw@\x9a@\xe4\x11cg\x04\xf75\x88\xd81Od\x01\xb8\xc3\xb2a\x12\xed\x8b-#\xcai\xbb\xb5#\x1a0\xce\xc1\xac\xef\xf8\x01\xf7Z]\xd6\xdaY\xd9\xde\xb9\xb9\xb1\xb9\xb2\xb5\xb8\xb3\xba\xb1~\xf3\xdc\xe2\xea\xda\xcarK\xa2T\xd8e|\x82\x18\x86\x16G\xac8E\x92\xba\xcd\xad\xae]i\xc5\xab[\x88\xb7:\x0f\xecf^\xd9\xaa<\xef\xb4\xcd\xb0\x90\x18j\xeb&\xcd+h\x1e\x81g?\x8c\xe2\x1f\xca\x8bL\x9ed\x87\xccOY\x18eL\xa8\xf9Q\xbfX\xe2\x94\xa9\xa8J\xe6\x87l\xeb\xdc\xd2\xb1\x97O\xcf\xce\x8b\x05/\xd6zc\xf3\xe6\xea\xfa\xe5\xc5\xb5\xd5\xe6\xf5\xd6\xcbR%V\x95\x7fE\xca\x92\x8fT)\x8eU)m\xe6l\x03=`\x90WW2\xd0\xac\xdd:\xde\xb2\xd8>a\x17\xc8\xe7!;\xc3,\x8f\x16\x8cKv>\x0b\xb31!b\x146h\x80\x1d\xd6\x84\xe3J\xd3\xe2\xa1|\x1a\xae\x8e:\nb\xf8\xaa\xf5\xcaWl\xf9@\xda\x16\x877\x14\x95-\x11a\x08\xde.\xc7\xb3]\x1f\xdc`\xaf\xc9)\xf4\xc18\xd6\x9e\xed\xb2\xa1N\xc5z\\f\xe7\x1b\x8a\xee\xc7\xec\x18\xe4\xe2o\x8f\x98\xa1\xbc\x95\x00^\xd9\xf8aA\xb8G\x82R\x0f\x8f\x1e\xc5\xf7\xc8^\xad\x89_\xe2\xfa1@\xf4AG.\x9e\xa7\xad\xee\xd6\n\x0d\xae\x8aL\xe3\xbf\xb4\xf6\x95\xa5\xd2A\xa7\xf9H\xac\x1c\xc4\xdc\xcd\xb8\xc7\x9c\x90\xe5a\xea\x0f\x04\xba\xf7\x9c\x94\x1f\x9b\x9be\xea9d\xa6\x08\xf3\xc8\xd9\xf3\xc3\x01\xcb\x86\\6\x96\xf0>Ox\xe8r\x0f\nH\x80\xf4\xe9c<\xe0\xf2\xa8\xef\xfb\xd9P~\xbe\xc3\x93\xe8\x98h\xd6\x03\x81\xb5z\x8a6\x17w.\xdc\\][[9\xbf\xb8vsqkk\xf1\xea\xcd\xd5\xf5\xe5\x957\xd4\x99\x02\xed\x8e5\xbd\xe5W\x9d\xb2\xdc9\xb1\xa0\x7f\xfc\xc7\x83iu\x1b\xa6\x96p\xc8\xbew\x86\x8d'\xdd\xcb\xc8\x85\xae\xf2H\xf1e\xc0\xbeg6q\x021\x1fr\x19\xc6\xe1\xf7}\xbd&\xec\xd2\xee\xf6\x0e[\xdf\xd8a=\xce\x06\xd2W7a\xd9\xd0 a\xc5\xa5\xc1V\xd0'\xb5\xb8\xa9\xa0Jf\xc9\xab\x0bzyqmw\xe5\xe6\xc6\xee\xce\xcd\x8ds7\xcfn\xec\xae/oO\xbf\x96\xf2\xde \xd8\x92\xb4\xdc\xa7\xd7\xc5\xf4n\xc0\xedV\xd8e^\x97\x0d\x04\x99\xeb|\xfd<\x8b\xd5\xd1R\xfd\xb3\x08\xccE \xc3@\xb9\xc5\x1c9\xc3\x06E\xaa\x83?n\x15\xf8\xe2\xcc\xe4!\xe4\x9a\xdct\xb2a\xe1)8\x90\xa7\xbb\x113\xf0\xaa\xe5\xdf\x9cU\xab]1\xbaZ\x1e\x032Y\xc3\xa8l\x02s\x7fz\x81\xd9&\x16\x13\x07\xe1\xe6\xa5\x91\x7f\xb3\x94\xdf\xce\x05\xe5a\xa3<\xcd\xc4qq\xc2\xe2\x18l\xaf\xbc\xbe\xbb\xb2\xbe\xb4rs}c\xe7\xe6\xe2:\x10\x14\x1c\xe12-\xbb5\x9e>\xf2F\x9f\xef3\x1d\xd6\xa4\x0e\xb9\xf2\x00\xebB>Msk\x9a\xb3\xef\xb2\xf4U\x96\x1f=\xdaa\xfe\xf5\\\x86`\xcau\xba\x9e\x0bN\x05\xf7\xf7\x12R\x16\x8d\xac\xda\x8bO\x054\xbfqC\xe2 \x1bRw\x0bU\xbd\xf6\xa2^\xf4\xd3IVJ\x96rB\xa6\xba\xa9\x10&\xb5%\x1bg/\xae,\xed\xb4\x00k\xc5z\xbcJFy$\xbf\xce\xc5\x01\x9a\xb6\xdf\xafD\xa2\xab\x1f\x9eq\xbe-_\xd9\x81\x826\xe5xEa:b\x87\xa9\x86-\x0cr\x8aa)\x9f(9\x92\x82\xc4\x1d\x07\x12\xa7>\x177\x81\x8dc\xfdv\xfdX\xe5\xa9K3'Q\x1c\xbeu\xbc\xf5\xed/6\xde\xb2\x1a\xc7\xa9\x1a\xc7\xa5\x02 X\xadm\xb9\xa5\x027\xedr\x8b\xc2t\xb9\xe3\x84\xa7\xe2X\xb5U\x88\\/\xe0\x025~(F\xf5C\xe6\x84\x1e\xfb\xa1\x18\xcd\x0fK(\xd4\xa9n\xcd\xb9\xad\x8dK7\xb7V^\xdf]\xddZ\x994W#/\x98\xa9V\xd4c\xf3\xb5P+\xcd\x02\x94o\xa1\xb5Eq\xca\x99\xcb\xd2\xd3O\xdd\xf1\xbc\x1fv\xd9\x0f\xd5\xc8\xd4\"\x88\x115,\x02\xc8\x1b_\xfd*83C'\xdd\xd5\xc9n\xdaz%\xbeyK\xb1\xb4\xb8.H\xdd\xd2\xc6\xfa\xce\xe2\xea\xfa\xcd\xdd\xf5\xe5\x95s\xab\xeb\x13\x96\xc6r%Q6\xc5\xa8e\xa87cB\xa0\xb4<\xe3\x85:\xd8\x98_\x83)kxD+\xd8E 1\x1e_\xd2\x98\x94\x1d\x05\x15I\xfd\xb3y\x0f\x96\x9cP.4OdT\xb2\xa3\x16\xb7$\xe48\x99\x14f=\x9e\xfa \xf7\xa4u\xcfB\x03\xd5\xba..\x97W\xb2I\xe6\xab\xc1\xad\xb2\xe5\xc2|,\x0c\x0fM+\xed\x83W\x99\xa3\xdc\xac\xa2\xe7\x9a\xb8\x98be\xce\x8e\x9c\xa9\x10\xf33\xe6E\x1c\xf0\x91\x1f\xf8if\x99\xfd\xee\xfa\xd6\xca\xf6\xc6\xda\xe5\xc5\xb3k+\xd3\xce\x7f\n\xfaZ\x8fQ\x81\x10\x07\xdb\x16\xff}\xfdk2\xd0\xea\x1f\x18j\x81\\O\xbc\xa3\xab\xc9}.~wo\xd0c\xa3\x7fb\xaa\xd2\xeb\xbdq\xc9\xe4\x9c\x03\x99\xf9\xe2K\xec\x9a\x98\xc7\xd4\xfb&\xd9\xc3\xd4\xfb\xd6(\xd7yZ\xae\xc3;f\xf7\x8b\x93B\xd4\xf3Iq/J\xb8\xd6\xdd\x87\x1d\xd6oW\xe4\xeb\xb0\xd3\xc5\x02\xb7\xd0\x03~\xf4#\xa1\x11\xd0F\x1aL\x1e\x89L\x19\xf6\xa3\x1f\xd5\xe5\x01\xac\x84t(\xd7\xfc\xc2\xab1\x12\x82y\xd2\xe6\xd7\xa3\x1b\xd2\xb79\xd4\xc6\x9dI1\x0b\xcd\xee\x81\x926\x94\xfdn\xf1\x1a\xd7]\x81\x88\x1f\xecLm0\x99\xf9K:\xed\xca\xf7\x92\xcf\x1enF~\x98I\x0f\xfa\xc0Du\x17\xfc\xee\x0cs\xcdW\xd8\xdb3\xaco\xbel\xc9p\xbd\x04\xc7\xe7\xe2y\xe9\x0b2u\x8bb\x91\xd4A\xebM\xbe>\xc5V\xadaR\xd6\x8c\x8a\x85\x12\x13\x1c;\x81\xef9\x99\xf4\xe9\x8aK\x1f\x84\xd6\xe5}K\x15\x9b\xc6\xb3-l\xcf\xbfR\xea\xbd\xd6w\xdb\xa6h\x1dI\x94\xb72\x9f\xb9\x99\x81{\xac^\x9e\x9d\xc3\x98\xab5Y\x0de@U\xe6\x0b\xa9#\xe1.\xf7\xc7<\xe92\xf3\x96\x84L)\"x\xe2\x11|\xcc4*!\x1c\xf9BQ\x0b_(\xad\x0cM)SN'Sr\ni\xcf\xcfw*\x8ew\x96<25\xbe\x93\xf4\x909\xfd\x8c'k\x91\xe3M\x13a \xafk\x93(\xcaVC\x08\xc4>C?\xe9w\xc9\xd1\xf7\x19?\xf4\xb3\x8d\xc5<\x1bB\xb2\x98<\x1b.\xca\xde\xd2\x197\n\xfb\xfe O\xb8\x80Zj\xc6 7)\xdc\x16e*(is\xee\xf9\xa1\xd7\x86\xcb\x0f\xe94\xdeT\x0d\xf2\x1a\x9dan\xb5\x16%O\x94\xa5\xa6\x99\x93\xf1\xcd \x1f\xf8\xa15\x0eD\xfcD?u0&W_\x12\x87t\x81Ez\xb3\xeay\xb7\x03\xcb\xd2\x185\x96\xf2\x80\xbbY$Z\xb4\xbf\x0fY\x93\x95\x16r\xdd\xd4\x0ft?q\xe2E\xdd\xbf\xfdQ\xae\x89\xee!U\xdaa\xdd\x05\x0c(v\xb5\x8a\xf0\x91B\xf8\x13\xa7O\xe2\x9c\x19>\xbc<\xd4\x9e?A\xb2M:\nt\xe2\xf4)\x0c\xca\x0dH\xe6\xd90\xb0&\xb7c`C(\xdbc\xd3\xed{&\xa3J(iWQW6\xbc#\x89\xea&$\xe80\x91D*\x05@\x06\xd1\xdf\xfczX\x93K\xa2L$x9\xff\xa7M6\nj}\xaf\xa7\xcfzY\x93\xf1\xb2Y(s5\x89\xb5\x18\xdb\n\x9d\xacL;\x0c\nQ|/\x1e\x0d\xd9\xd6\xa7\x85\x16\xca\xa5\xcdR\x14\x12\xdc\xd5r\xfaMz5?\xddX\xdc>\xd1\x91 \xcd&>\xb2\xc1\x16\xd8\xf5\x96%\xd3b\xcb\x12\xa6*\xd4\x82\xbc\xdd\x11r\xc8j\xd8\xben\xd2E\xa4]v=\xbbA\xd2\xc1\xc0F\x04\xec5\xe6\xcb\x07\x99\x13\x94\n\xb3![\x99\xfd\xdc\xebdq\xb5\xae5:u\x9c\xcd\xcf\xd2F0\xc5\"8\x0b,\x98\xc9\xa2\x8b\xdb\xe8=gHS+NB#\"\xf4\xeb\x1c\x8d4U\x98\x1a\x0b\xfci\xb0\xc0\x81\xb7[j\xb1 7O ~eX \xc3\x98-X\x907aA\xca^c\xd1\xf3b\x81\x0d\xcb\xd5\x96\xa5So\x19\xfb\xa6\x89F]\xed\n-\xa5#\xca+$\x84d^r\x14d\x8e<\x00\x90Kq\xf5;\xe8+$\x1b\x9e\xc3\x11\x16\x81\x8a\x87\x98\xb7\xf2\x14\xf7\xeb!\xa7\xfa\xaf2\xa9\x97\xfeT:'kT\xca\xc9\xdae\xc1\xcc\xf6\x85\x8d+7\x17ww.\xdc\xdc\xdc\xd8\xdc\xdd\x9c\x90oY\xfb\x95e3\xb1-\x9f\x9f\x9e\xd1L\xca\xb3v+\x1dF\xfbe\x84\x17\xa8Q\xda;\xfbx\xc4P6\xb6V\xaf\xad<\xefH(B'&Op?\x89F\x17\xb7;BW&\xa5\x80\x90\x0c\xc4\x80\x8b\x1c\xc1-x8CV\xbe\xe4\xc4\x1d\x1c\xf8n\xd4%\x1ef\xc9\xe16\xbf\xdd\x9e6\xe3\xba\x96\x0dP\xbaN\xdee8\xb0U\xff\xe4,\xaf\xcf\xd6\xe46H$t\xae\x06\nIe\x159i\xc1 \x17T*\x939\xcfjl\x0c\x95T\xab2\xc7H\xe9\xa5\x1d\xbf#W,\x92[\x1c\xda\xcdG\x85\xa9\xac\x94\xdf\xd4\x9a\x97\x87\x95\xc2}\x8aq\xca\x93.\x86\xa9\xb9R\xebFC\xfca`\xaf\xab\x19\x96u\x9aLm|\xdb\xccET\x0e\xbbL\xd5ot\x9f.xe^?*H3\xb7P\xce\xa6\n\x8f\x93\xf5\xb2\xc8)?\xdaS\xf7Ls\xa7S\x1e\x96\xda\xba\x1b]\x98j[\x7f\x98\x98\x11B\x066\xc3y,\xa1\xb7\x10\xad\xa6?\x8a77\xc4\x9f\xf3/\xe6D\x86\x92Q\xdb\xcfaX\x97,\xd9\xa9\xf1u2\xe7\x10\xde\xeb!o\xfd\n\xaa\x17u \xcfH\x95\x14$z]$\xd6T\x96\xc6\x81\x15\x96\x88\xd7\xb9\xd1-\xe7\x05\xac[\xaa\xb5\x8d\xf3\x1b\xbb;/f\x81,\xc4hf\xdf\xcf\x86\x97\xf2\x0c\xaeG\xa6\xc8\xa8h\xc9\xe4\xd5\xf8\x8c+\x9f\x81\xc0\xb2\xda\x10^\x0b\x9a\xd5\x98N,\xb8\x96L^\xc0\xa5\x8d\xf5s\xab\xe7w\xb7V$/z\xde\x85l\x1a \x18\x16,\xdcG\x8d\xea\xb7+\xc0t\xc1\xf6\xb8\x04\x83\x94s\xf2\xd3E\xb3x\x90\xd4\xad\xfaO\xaf`\xa9\xe7\xa2d\x0bLY\xe0\xbe\xa4\xd2\x0f\x94\x98\xee\xd9\xc3ug\xc4S\\q'2}H\x90`\xd5a\xa9\x9a\xe5\xb8i\xdbS\xde\x0e\xdb'\x89t\x15)\x08\x95\xa1 o\xc3),D9J\xb4z\xbe8\xe2\xafDV\x1a\xab\x04B\xf5\xc7\x8a\x9a\x05\xcb\x967\xcb\xe2\x01\x19\x82\xec\x90Z\xe5\xe8\x08enr\x1f\x8a\xbc#\xd9\xa9\x83p\xa6v/'\xf7\\\xd3\xf1tb\x0b\xd2\xa2l\x0f \xb4\x8d\xec\xe4\x80\xecT\xfb\xcaQh\xe4\xa05?\xcd\x88\x90\xc5\xca\x96\x8b\xe7\x16\xb4\x18\x12\xb6\xa2\xa9\x84-fD\xaa:\x81\x8b)\x9c\xae\x17\xbaXIYt\xac\xe2c\xb9T.\xc9T\xd2\x95/%\x86\xe0\x1b\x9b\xa7\xc3vn#\xb9]\x9c\x17\x91\x92\x12\xeb\xe1o$\xa7S#@H\x11\x80\xce\xcb\x8d\xc24\n\xf8\xcc\xbe\x93\x84\xed\xd6\x95\xc5\xad\xf5\xd5\xf5\xf3\x0b\xcc>2?e\x1e\x8f\x13\xee:\xe00\xeb\xb1}?\x08X\x8f\xeb0\x1e\xed\x91\x19\xf2\x83\x8c\x8d\x9c[Q\xc2\xc6\\g\x9aB7\xe2;\xd3\x04\xbb\x11\xe7\x99\xce`,I\x98?\xa1W\x1b\x8f\xc1\xbf\xca\x9b\x039PF\xa9\xba(\xd7\x95T\xd0\xbc\x97^b\xed6\xbcp\xa1$\xe3(\xe6i\xab\xd3\x99\xd9\xe3_h%\x99\xf4~v\xa30s\xfc0U\x17N\xb2\x87T\x8bI\xdc\"w\xeb\xdf]\xe5\xc1\x98+I(\x08\xa2}\xeem\xc3\xa8\xba,\xed\xa8\xe46\x99\x84\xfb]f9\xe9\xba\x1d\x1f\x9e\n\x95\xb9\xcd\xec\xf4\xc0\xaf\xa3\x07\xddI\xa2B\xfdbh|u\x92\x81\xbc\x08L\x0b\x07\xb79V\xcd\x15f\x8a\\\x9f\xbb\xc1^\xab\xfes\xa1\xe9TMEtT\xa16\x18\xfa\n\xaec\xe7~e\xc6\xa3\xfa\xecL\x9f\x84\xdc\x1c\xf14\x1a\xf1)\xc5fSG \x1e/\xe1\x9b\x9f\xa4Y\xbb\x06G\xac\xb2t\xd3.V\xe4\xbf\xc9\xfc}\x82da3rh\xa2\x84\xb8 \x92D_$\x13\xa9\xeeg1\xa6\x06\xe2\x0b\x9b:\xe3\xa7\xe2?\x10\x1b|\xe4H\xa6\x8c\x95\xcf\xbd\xcf*\x97#2\x9b\xf2\xce\xcc\xc8\x89\xa7h\xa5\xd4\xd2\x91#!\xec\x7f\xddv\x1b\xaf\xd1#s\xb6\xad\xd7\x87\x0b\x99W\x19E\x84\x8a\xa2\xf0\xa5\x11A+F\xe5]\xff\x16\xfbFhD\xfc\x80\xbb\xb9\xf4,\xb0j!]\x95\xe5f\xfe\x94E\xd7\x90\xd6\xceH2\x88\xa4\xaa($\xcd\x8aB5^\xb8\"\xe1\x17\xe3\x99R/\xad\xa0\xb7]\xcd\xcf\x9a\x04)|\x9aj\x9f\x83\x89\x94\x1a\\\xe7\x8e\xe8\xa8\x0c\xd6\xd90\xaayr,\x97%\xa6x\xc1M,C\x968\x0d\xcf\xc9\xd6\x1f\x95\xe2\x80/(\x03\x90>\xeeb\x9f\xaa_\xd4\x89\xae\x97\x1eJ\xd4\x7f\x81%5*\x88\xdc~+hb\xfb\xe5W\xdd\xca\x1d\xe0VMS\xf6s_K\xc8x\x1b[\xa9\xac\x0d\x80\x93_\xcd\x1by\xb0\xa3\x0b\xcc\xb1\x83K\x0f\xde\xd4\xd8(\xcb\xaf\xe6X^\xbf\x95rJ\x1d-\xfa\x86P\x89/\xe3\xf1\xd2\x0f\xebnB\xd3\xa1\x94\xd8Vn\xe7N\xf0}~\x08(\x86\xbe\xd1\xf5\xaa[*j?\x917G\xdf\x80\x15\xa4#K\xdba\xfb$y\xe7:2>\x16\x13\xfd\x8dj\x05I>\xd3\xb7\x10\x16{\x82\x02\xf1\xf3\xa2\xfd0\x98\xd2\x1d\x89Y\xc8emj\n\xfd+\xf4D\x9e$\xea\x02\xb9Y]aZQ\x9at\x8d\x8c\x7f\x8e\xa94u?\x10\xf8Tp\xfb\xc95\x02I\x9f\xfb\xa0\xc4v\xcc\xddv6\x93 ~'\xf4\x8a< \xda\x9d\"\x93\xbf.\xb6\x9b\x04u6\n\xfdk\x1e\xbbL\x14#8\xac\xea\xa2[7\xc6\x00\xfe ,\xdc\x0d\xb8\x934\xbc\x8d\xa1\x7f\xcf\x83dB\xfe\x0f\xa6h3O\x82\x05[\x9e\x16\xfc\x13\x03\xde\x96^\xd1G\x1a\x1e<\xd4?\xf5 \xe9j\x98\xf1\xc4\xe5q\x16%\x0b2=\x0f\xfe*\x96j:\xf9\xb5\xfc#w\x8du\xbf\x1a\xef\xee\xf2/\xe1i\x1c\x85)'C%\x9f\x7f\xfbcu\x13\xee\xf10\xf3\x9d ]`\xad\xd4\x19qEg\x1b\xe2\xe0\xf4O\x91\xb7&\xa7\xf6\xf2OP\xc98[\xa8\xbe\xe2y+\x8d\xc2\xee\x1f\x1c\xff\x83\xc9\xe4\xad\xf9\x94\xdc\xed\xccdC\x1e\xb6\xfb]\xd6o\xb8$\xb0Bj\x96\xc9r\xc8\xa6\xd5\x8c\xb4@x\x1d\xa2\x1d\xcc\xd1\xec\xb2V\x11*\xa4i\x8a\xf9\x08zG\xab\xe1\x0d\xf4\xaa\x1553&Nx\\N\xdf\x01r\x95\x11G\xfcg\x01\xc4p)\x90Ws h\xdf\xa8\x92\x1d6\xebLdT\xd9a,\xa8\x85\x90\xb5n\xc2\x02\xddT\x93\xbb B\xf8\x04\xbcQ\xae#\xb6\x04n\xfaW\xb3I\xe4\xab\xcd\xff\xb9V\xb7\x0d\xaa\xdbh7\xe3N\xb7\xb9\xc6)\xa2\xce\x8c_\xfe\xddm\xb2\x0c\x97\x7fU+qe\xb8pc@\xcc\xd4\xfag\xbb\xd9\xb0\xda5i\xe7\xd3\x04\xd8L\x8a[113\x8d\xd9!u\x10N3v\xd5\xa3\xd5B\xb3\x0d\xd8\xf6S\xb3\xb6\xbc.g<\x98 \xd1)]\xf0nQD\xe6;m&=\xf5\x98\xdc`\xed,\xa2\x88j\x1e\xa0\xa2\x9b\xfa-\xfb\xbf\x90\xb5k\x82\xe7O\xf5\xab \xca\x99\x9f:&\xe7\xab\xf2 \xfa\xed\xda\xe5\xbe\xace\xf3\x85\x9e\xa4\x1a\xf32\xab\xe2M\xdf\x8e7\xf6\xba\xea\xdai\xbaH\xb9t\xe6EG\xca}\xe9x6j7u\xdba\xfb\xf4 \x12\x9c\xa6\xee\xa8N\x9c\xb0\\R\xc9\x00NZ\xc5Q\xa0\x93\xb3\xb3\xb6P\x04\x00\x11\x0bm\xaa\xc6pr\xb6\xe6\xecXB\xb9\xfe\xe9\xc5\xb3}\xcd\x01\x18c\x95T\xb2\xda\xc8\x80gk\x91\xeb\x04 `-4\x9b\x03\xb5\xf7\x834K\xc4N\x92\xf2\xab\xceHU\xed\xb4\x0bi\xa9q,\xbf}bf\xec\xd8g\x0fw\x130Tk\xfb>|op6\x85\xf3S\xb9v\xc0U'^w7_\xa2\x96\x169\x9b\xe9\x87`C\xef`E\xb9\xee\"^O\xe9\xb9\\#\xac\x06*}\x99[\xb9*\xa0\xf2\xb7<\xb7\xe6\x9cFh9\xda\\)\x1f~\x97\xf96\x03\xbf9\x0d~\xfd\x1dIh5\xe2\x87U#>{\x8d\xb5\xa3&\xfb\xbdR!:\x02w\x9f\xab\xd8n\x12\xb4[\xe2CU\x89\x08KV\xfd\xc2\xa8?\x93'\x81@2x\x81]HH\x99\x8a\x84#\xe7%\x04\x03\x89ED\xfd\x06\x9f\x9f2\xe6\x0fx6%\xa6q\x15\x0d\x83\xdf\xdf\x94\xf6\xfc\x05\x19J\xf8\x0d\x9d\xa5v\xef\xe8*\xe1q\xde\xf6\xda\x9f\xf4\xf0\xf0\xbf\xbc\x87\x07e\xb0u\xb1~\x82U\xdb\xef>e\x00\x91\x8e\xad+\xc5sE]\x96\xce\xecn./\xee\xac\xdc\x84\xd8\x86\xed A\x0df\xef\xe0\xb9\xf1j\xb4J\xa1\x04\xd0P\n\xdc\xeb\xce\xc6\xf9\xf3k\xd3\xf6\xfa\\1)8U\x89\x19\xb2\x8a\x05;\x82\x02=\xa2o\xc2=\xf7\xf3\xc9\xd3\xd7\x0d[\xb5\xd9\x1f\xa6\x91\xad\xa7\x90o+ \x16\xea\x8b1e-\xe0\xf8\x15\x8d\xe7\xd09\x9f\xfb\xbe\x91C&\x1b\x95c\xb4[xtNa\xb2f%\x84\xda\xf7C/\xda/.3\x86NZ\x93\x00\x0d\xff\xb2\x99\xc09\x8c\xf2L\xc7uKJ\xbe\xccy\xbc\xe6\x87{\x17\x9ct8\xcd\xfd\xd2\x04\x1b]-\xf4K\x98|\xc4\xae\x9a\xfc\xb6\xb5\x1b[\xf2\xcc\x99\x90\x06\xc4$\x1d\xdaq\x06\x0b\x85\xbb\x10\x1dJ\xe5\xcb\xdd\"\xd1\xacEUq\xa4\x9a`UU\x00\xf4\xb2-|\x07@\xdf\xb1+\x17\xce\xd7'W\xff\xf6 \x89\xbc\xcc\xd8v\x93(\x08v\xc0\xf5.U\xffPw\xe0\xf2[\xc2\x1d\xefp'\x82r\x8a\xb8\"\x1c\xae\xd45!X\xcd\x0e\x8f\xfd\xda\xb8\xf6\xbe5\xf2\n\x0c-'g\xb1\x97d\xaej\x9c>AR\xa34\x86\xb6c\xde(\xdf\xa0l\x07V\xac\xe8\x7f}X\xc1\xd4*\xc5\xe5e\x9cH/\x0b\xc67\xc9\xcf\x06\x9c5\x81&5\xc4\xbdLKp+\xef\xf8c\x0f{\xd8h-\xafU\xde\xc2\xcfT\xee\xe3\x08r\x1f\x17\x9e\xf6y\x8d\x99\x1e\xb2*V\xa9y\xd4\xe9\xb2\xb0\xdd\x91\x8f0\nT\xf4\xc3Ag\x8aG`\xc5\xfeG\x13#D\\Yj\xae\xe1\xd6 0O@k\xa14\x10Bi \x84\xd2\xa0\xa1\x9eV\xa6\x13!\xef\x8b\xe3#+\x9fK\xa2\xd1j\xba=\x8c\xf6\xc3\xef\xf3C\x89\x88u\x0d\xc8\xdca}\xf4:ls\x7f1\x8d&\xeeO\x8e\xa5\xf1\xd8\x19\x16O\\\xa9\xa1,\xd5\xb4Rr\xc0n\xa7\xac\x9e:B\xcc\x12\x93\xef\xc8\xa4\xa2\xf5u\xe7\xe5\x9d\x8cyX\xf65\\\xbb-\xe3\xd0\xe1\xcaA\xd3\xa4M'\x83v\xd9Q\xe6Iw\x16\xf1\xd7P\xaaTs\xd5\xf6^z\xe9\xb9\x1b\xac\x8b\x84\x98\xea.\xbe\xaa\x07N\xff\xb2Z\x95hT7\xc4\xc3\xf4\xb7\xf9j\xa4\xd6\xd8\xca\x8a\x8b( \x107\xa1\xcd\x9bYTs\xfdd\xae\x9dp\x1eIE\x06\xafs\xfaTW\xe3T\x86\xb5\x0cf\xaa95[GX\x85RV\xe4\xb2z\x0c\x9f\x92`2\x85\xe6`z)\xa8p\xa7J\x9f$\xbbh\xc2\x8f\xb1\xc9\x06\x04\x0f\x90\xcc5\x1c\x8d\xd6\x11\xf08\x13\xc4\x8c\xe9\xcc\xf9\x91\xa9\xd8\xe9J\xc4o*\xd1L4|\x9c\xf9w\xfah\x12\xfd\xd3'\x9e\xebwhT\xba\xdd\xf6\xf1\x9b\xc7\x07]\xd6b\xad >\x1c\x13(\x94#\xe9\xa8o\xe8\xa6\xa0\xa2\xbb%\xaa\xda\xf6\x1b\xe6\x18J\xfe\xdav\xba\xf0\xdc@h\x8eP\xdby!\xe7rl\x95\x9f&2\xf3\xa9,l\xac\xe2\xf7\x8b\xd0S\xe0\x9f\x96\xeb\x043\xa9Y\x03\xd7xi\xf9i;\x01\xfd;0Z:\xef\x80\xe1:D\x1a\x0c\x92\x11%g\xc7e*\x92\xa5-t\xacq\xddF5\xb2\xe8\x8b[\xb9f!A\xca\xbd`&\xec\x87\xc5Zn:\x89\x98/\x17\x92\x8cY9u\xd7-\x0b\xc8G\x1eg\xb2\xa8\x96\xac\xff\xd68\xc4@\xae(\x96\xf7\xa7\xb1\xd7O\xc3%d\xbb\x8aWP\x87\x1340\xbb\xe5\xa9\xda\x8d=\x9e\x01m\xc4\x94f\x04M\xf0\x8d\x97\xaf\xfeC\xe1U3\xe5\x97\x84|\x14\xe7\x19\xf7\xb6\xb3\xc3@\xe6#\xae\xad \xd6\xb4\xe5\xf4\xd2(\xc83\x95S;\x99\x89\xa3T\xc6\xea\xd4W\x93\xf1\xf7\xec5v\xbc\xed\xe4Y\xf4#X\xc7\x1f\x0d}\xcf\xe3a\xe78[\xa8\x02:\xc7\xeb\x99O\xab\xef\x1fp\x0f\xf7\\\xbc\x90f\xafidx\x99^\xf0U\xf9\x1fG\xf0\xe0b\x91^\xad\xa7\xd221\xbdm\xa5\x9cN\x97\xb5\x8f\xc8wTZi\xe6d\xbe\x0b\xae\xd3\xe5\x81\xbd\xf4\x12\xf3eZ\xe0v2\x13\x8dy\xd2\x0f\xa2}v\x94\x15\xff\xb8Z\xf9\xd7\x1b\x9d\xc2\xdd\xde>\x17=\xd3IX\x88\x14\xc5 \x960\xc0\xf3\xdaT\xa9\x93\x8d_\x88\x96-\xb0\x86D\xe7\xba\xec\x02\xab\x89q\x13\xbf\xcaQ^`\x83\x06,.\xb3\x9f\x056\xae/I\xa4\xae\x056\xb4\x13\x1f{\x1b\xa5{\xe9\xfa\x95\xa8r\xa6i\x1d\xbf\x18\xc3\x9e\xccM\xef$\xf5UZ\xac\xed\x01\xb4_\xd4{\xa44\x8b&\xa9\x1e^;\xf1\xbb,\xb7SgDX\xb2\xa1\x9fvY\x9d]\xd5\x08\xc1\xa9\xd5\x90\xed\x1aCv\xda\xe9J\xeb\xed\xec\xab\xac\x0f\x8f\xf8\xf5\x8f\x1e\xed0\xf7z\xbfj\xc8\xee7\xbf\x16/\xd8\x9cO3\xa7\xc2 \xe5\xbb\x83\xc1\xcc\xcd\x9b\xd2\xb9\xec\xe6M\xed\x12]\xf2)\x0f:\x1d\xe9a\xa6L\xe2\xbc\xcb\xae\x8b\xba&\xc9\xb2\xdb\xe9\xc8\xf0\x99(\\\x8b\x1co\xa2\xfdL\xff4\x07\xf6g\xe2$\x8a\xd3\"\x93\xc2L\x16\xc1\xc1j\xca5\xc0\x14\x17F\x92G8\x939\x83\xae|\x04U}]\xf5\x1a8*\xbe2\xadH\xb0\x82?\xd4\xe9\xc4p\xc3\x10\x12G\x02{V\"J\x96K\xe6\xe9\xbc\xb4\xd2\xf06<\x92I\x82.\xaby\xf6hO\x88=\xad\x84\x87\x1eOj\xcc\xa6\x8a\xdaL\xbc]a\xc5\xa0Rdq0Q\xaai\xec\x84\x84\x9c\xd1F\xfa\x0b\xf0\x9c\x04\xe0Cm\xe1\xbb\xdd\xda\x9e\xb8z\x90B\"F\x1d?\xa7\xab|\xa3\xd3E)\x19\xee\xb6\x8b.\xcc\x15\xf37\xda\x87\xe7\x1bG\xfaCi\x176\xff\xfc\x1d\xd9/\xfd~G\xf6\xbf8\xd9\xb7\xe8\x85\x9a\x13d\xce\xe0\x0b\xd3\xec\xf0w4\xfbw4\xfb\xab\xa6\xd9\xcf\xe7\x1ag!?\xb5It\xa28='\x13\xb2=\x87\xe3R10\xc4Kt\xba\xaf\x93\xb3\xa7-L\xe3E\xe5\xfb\xfa\xe6\xeeG\xa3\xb7(\xc9{gy/\xa5TA\xbe\xd5~\x86\x85&`\x13\x87\x0f\xfc\x97\x85\xa1\x93\xcc\xd4l\x8a`\xa8)\xed\x19\xcc\x04\xeaB$\xf9tlD\xff\xa6\xf5\x1e\xc2?U/\x91\x0f\xc0w\x1b\xbc7'\xb6f7\x9a\x19h\xb3\n\x03\x13\xbf\x98F!\x9e\xfc\x146L\xf6%\xe6os\xe3jwf\xa2P\x90\xdc\x80g\x96G!m?\xb3\x8c/\xbd\xc4Zz\x10\xe5@\xcdP^\xec\xa6<\xdb\xf1G<\xca\xa5\xbb3<\xb8\x7f\x86\x1d\x99\xeb|\x95+_\x0b\xad1s\x92\xaf\xd3\xd2Y9\x15\xeb\xa1/\xefF\xf9\xbd\xc6\x96\xe7d\xce\x82?r\x06\xfcx:\x1e\x1c=\x18\x05\xaf\xf6\x9c\x94\xbf|\xb2\xbbya}\xfe\xda\xe1\xd9\x13\xce\x95\xadYgy\xd6\xbftkq\xdf\xbd0\xf0W\x97\xceF\xd7\xae\x04\xa1s\xe1\xf5\xd3\xab\xb7V\xf7/]8{r\xd5_\x1c\xf0\xf3si/\xbctzu4\x9c\xf5.,\xbe\xbcvx\xfa\x84w\xc2\xcd\xbd;\x97\xf2\xde\x89\x8b\xe1\xda\x9d\xd5\xfdK\xcb\x8bc\xf7\xc4\xb5p\xd5?;\xef\\\xb9|\xe2\xf5\xd1\xe9\x93\x9b\xdb\xab\xfb\xab\xcb\x8b\x83K;\x8b\xfb\xab\xcb+\xfb\x97\x96V\x07\xee\x85\x8b\x81;\x7f\xf9\xd0\x1b]>\xeb\x9e8\x1b\\=\xb1\xb5}\xf5\x8d\xad\xb8wg\xd6\xe7+s\xf1\xb5s\xc1\xbas\xe5u\x7f\xf5\xfczz\xf5\x8d\xf5;\x9b\xdb\x17\xd3k\x17.e\xee\xe8t\xda;\x1f\xe4\xd7\x0eW\x07\xee\x89\xadS\xbd\xf3\xbb\xa7WG\x17\x87W\xe7\xb3\xd0\x1d\x9d\x9e\xeb\x8d^\xcf\x9c+s\xc3k\xf3\xbb/\xaf\x9e?5\xee\x8dv\xbf\xb3z\xbe\nw\xcf\x9f\xbe\xe3\x88\xbe\xe6O\xbe\xbcz>\xc8\xc5\xdfW\xaf\xec\x0f\x9c+\xa7b\xef|0\xec-\xa7\x83\xab\xa3s\xb7\x9cy\xef\xb0w\xe2r~mi\xee\xf0\xda\x1bg\x83\xabo\xbc^W\xde\xdf\xbcup\xcby\xe3\xe2\xad\xde\xf9\xdd\xc1\xd5\x13\x83\xd3\xab\xb7v\xf7W\xfd\xb3\xb7\xf8\xce\xac\xbf\xbe\xb3\xe8\xaf\x9e\xbf\x16\xf7\xce\xef\x9f^\x1d\xc91\xf9\xab\xe7O\x85kW\xce\xcdz\x17V3\xf7\xc4\xd6ao>\x0b6\xb7/~\x87\xcf\xaf\x8f{\xa3k\xf1\xb5\xc3S\xb7z\xf3\x07c7\x9c;\xbd\xea\x9f\xcd\xaf\x1d\xce\x0d\xbd\x0b[\x87ko\xac\xcf\xba\xa3\xd3\xc9\xb5\xed9\xb3o\xfcDv\xab7\x7fj\xe4\\qso>\xd8\xf3\xce\x0fO\xf7\xb7W\x07\xbd\x91\x9b]}ck\xd6\xf5\xe7\x0eQ\xdb\x87W\xafl\xc5\xde\x1b\xeb\xb8\xdc\x1d\xef\xc2\xc5\xb13\xbf\x9b];\x7f\xee\x8es\xfe\xdc\xa1;:w\n\xd5\xdd\xbb\xfa\xc6zt\xf5\x8d\x8b\x87W\xdf\x08d\xfdb\xfc\xab\xb7\xd6wv\xe7\xc4\xffV\xfd\xb3\xa6-\x18\x93X\x93\x15\xb1&\x87\x9b\xdb\xabw\xd6K\xf5\xd6\xael\x0d\xdd\xf9\xe1\xd0\x0d/\x0e\xc5z]\xda\xb9:\xbbvk\xef\xce\xa5;W\x0f\xd6\x97/\x1d\\\xba\xf3\xfa\xfc\xfa\xf2\xca\xdc\xea\xf2\xee\xfc\xda\xad\xbd\x13\xebw\x06'.\xed\xbc~g\xfd\xce\xe0\xf0\xd2\xce\xa5\x93\xab\xb7N\xber\xf5\xca\xa9\xb8w\xe5\xdc\xec\xb5\xcb[\x87W\xaf\x9c\xbasmt\xfa\xb0\xb7}V\xae\x99s\xe5\xe2\x9cw\xfe\xf2\xc6\xd5+sb\x8dg\xdd\xd1\xb9\xdc\x9d\xbf6vG\xb3\xfe\xea\x85\xadS\xae\xc0\xa1\xf0\xe2\xd8;\x7fn\xf6\xda\xf6\xea\xe0\xea\xfc\xb9\xf4\xea\xec\xdc\xf8\x9a\xc4\xad\x83\xb87\xbau\xf9|\x90]{\xe3\xd2\xe9\xd5[\x8b\xdf\xb9\xb4\xbd:\xb8v\xe1\xb2\x98\xf3\x81{\xb8:\xb8:\xba\x1c:WN\x9e^\xbdu\xf6\x8eX\x0b\xc0\xab\xade\x81g\xde\xf2\xac\xef\\9\xb5w\xed\xca\xb5\xb87\n\xc4X\x8en.\x9d\x1e\xf6F\x81\xd8\x9f\xe0\xf2\x85\x8b\xc3^\xb8>\xea\x9d\xb8\x98m\xde\xda\x1f_\x9d\x0f\x0e\xaf\xce\x1f\x04\xe2oq\xe66\x07\xd1\x99\xd67D\"X\x8a\x82\xc0\x89Sx\xbab\xcd\x0f\xf7\xe4\x1f\xe0\xcb#\xff\\\x0d\xe3\x1c\xfe\xda\xe1\x07\xd9b\xc2!\x0d\xea\xd9<\xcb\"\xe0\x16[\xd2KX6\xa5\xfe+\xb3}\xcb\xb7{\xeb\x82\x11\xa5\xff51Ch\xcf\xecW\xac\xafS\xf6mF\x10G7f3i\xf4mF\x90T\x01H\xef\x81\x02\x10#\x88\xab\x00\x15#\x88\xf4\x13\xb7\x9b\xbf\xbf&\x87m\xdaqLx\xbd\xb10p\xab\x85!3\x16\x06\xae^L\x98}\x95\x85\xec\xbb\x8c\xbf\xca\xc2\xa3G;L\xc5\x0d\x17\x16\x86\x10\xa9\xe1jb\xd9tI\xa3U\xe9#G\xd0\xac:3\xb7\"?l\xb7X\xab3\x93%\xfe\xa8\x8dEg&\xb5\xfc2f\xd5wd\x96#\x9b\x14\nLl \x99R\xdbSb\x1c\xc9\xa8a\xa4|G\xdc\xe9(\x99\x05\x8a\x17\x12K]\xec+\x1aIPj\x0b\x9e\xdfE6\x85\xccj=\x98`9\x98\xd6j\xa0\x11\xa4\xd0\xd6\xebET\x95\x834\x0f\x82\xd4M\xb8\xed\x81)\xfd\x0bM\xc9\xfa2\x96\\q\xbc\xcb\xae\xb7\x8a\xf6e&\x9d<\x08j\xdf\x1e\x93\xc9\xec\x8cg\x8e[k\xf5\xe0 \x88B4\xaf\xad!\xed\x84\xd4J\xf7\x9d\xc1\x80'\xc7\\\x8dn2\xabN\xc8^c\xadcr(l\x81\xb5\xea\xbc\xc6\xa7\x1fG\x9b>3\xe97\x99e\xdc\xc0I\xd3u\xf9XZ\xdc\xf6g\xcc?+\xafj\x95\x7fw'\xbb>\xde\xe8Tb\xfd\xdb\xae\xc5\xceR\xa5\xde\x1e\xf1\x97\x1bE=?\xe0bI\xaa\xfb\x9c9\xbd\x80g\x0b\xacu\x0c\xfeB`\x8f\xa7{Y\x14\x0b\xb8\xfa\x13\x15\x08\x9cd \x9a=6\xf4JW\xb3\xafV\xe8A\xf0;J\x00\xbf\xdf\x1a%\x18\xfa^CV8\xa0\x01{\x9c\xc7K\x90\x8d\xb3\xa1=I\x0b\xf8\x0c\xa0\x93\xd0\x02\x01m\xba\xd2\x9bB\"\x88\xf8Sb\x05\xf1\xdb\x90DC\x0cE\x90\x8brw\xe2\xdf\xd0\xa2|\xabQ!\"k\x19\x94c-\xd9b\x8b< k\x86%\x93\xf1\xbe\xf4\x12;\x12NAe\xc0\xb6*C\xe8\x9b\xa9\xcc\xf5\x1a{\xb6\xe1\xd89\xf3C\xe65\xbb>z(\xedG;\xefL\xd2\xf6\xf5u\x83W\x1b\xec\xa4\x7f\xa2\x83\x1c\x1e\x0d2F\xdc)L :\xc8\xa9\xa85\xb1'\xa6z\x0b\xd8w\xd9\xdc4}0\x99\xd4Q\xbe\xe5\xd2\n\xa3\x90\x0b\x02=mT\xad\xa0\xea~\x98O\x91hob =\x84^\x10\xb9{0\x86\xae\xf9\xe8F\xc11\xf9(\xa5\xfc\xde\xd8\xd6\xf3\xda%t\x0cW\x8c\x0c%\xd7K\\\xc1\\\xca8u\x88=\x11\x97\xbf0\xa7J\xb3\xc3\xa0\xf6yl\xfd\xf3\xfc4\x0e\x9c\xc3\x05\xe9}\xacv\xd1\xf2nG\xf9\xd7`9+1\xc7\x9a\x14J/\x86\x19v\x8d\xc2\xf3;\xb6\xf3\xe2\xd8\xce$T\xf4\xfc\xb1\x1d\x0dK|jZ\xc9\xa9\xa8R\x16\xa1Z\xfb\x89\x13\xc7<\xa9u\xd2{!\xd8S\x1c\xc4vI\x85\xfe\x1d&}}\x98\xd4\x93\x8b\xfeU#\x93\xea\xe5+\xc5\xa5\x8e\xfe&\x98?\xcd\x91Y\x1af\xabF|.\x19t\xeaQp\xd2\x82f\xfc s\x12\xee\xb4*\xb7\xec2\xb5\x936\x1d}\xf1\xc6}\xd1\x02j\xb9r\x86\x8c\xa1j\xaa3Tw\xa1Ws\x80(\xdb\xd4\xe6\xab/z\xb0dV6(-\xc7b\xe9b\x08\x85lo\x81\xeb\xe8\xcc\xba\x17 \xd4jB\x00\xa7<02\x15&\xfc\xb5\xc0\xf8\xcc(\x0f2?\x96V\xa7\xeb\xad\x96\xf4\x0bo\x89S \xaf\xf6j\xb3\xac\xaa\xa3\x17Q\xa4\xedZ/~\xf5\xef\x1bC\x13\x9e_\xa9Q\x0f\x0d^\x16\x1d4\x14\x06\xedF\xafj}\xb9\xa4hte\x14g\x87\xb2\xdd\xfa\xe2\x91\x1e\xab\xdc\x17\xd8?\xf9<\x12{\xcd\xfe\xbd-\xb3u!\xc8\x17\x15\xfa\xc4\x81jt\x0f)Q\x16+\xf9\xab\xad\xa8\x17\xaa1\xab\xac\xc6\xb6\x86\xe5 \x97\x86N8\xe0\xc6?\x05\xfei-/P\x94\xbdV?\xdd(V\"n\xfdt\xd5\x80Z\xf6d\xd6w\xbb\xacu\xecX\xab\xa3DWA\xf6\xaaq\xca\xd3\x054|\x99\x012}R\x1a\xa2 Y1\x91m\x999\xb7)}\xfd\xddnQ\xe8\xb7\xc9\xc2\n|92\x87\xac\xfe\xd5\xa3T\xbd\xd7\xa8\xda\xab\x86\x93BM\xcb\xd4\x81\x9e\x99\n\x8a\x95\x9b\x9a\x18\xf2\xc9'\x91\x1a\x08\x9e\xd6m7\x93\x83p\n*\xe3K\xab\x02\x84\xd7+N3\x939\xc9\x80g3\x80Ei\x83\xf3\xb43\xe1\xa5\x1b\x01\x8f\xd8k\xcc\x9f\xce\xd0\xaf\x7f\xc6\xb7\x06\xe8\n\xb7\xfb\x91\xdd}\x9e\xe0~\xd3\xa4\xc4\xe7\x9a\xf6\x04=\xd4\x93\x97\xe5\xba\x103\x04\x81!\x13\x0f\xbbS\xd3l\x17\xdc\x1a\x12[\x88>\xc2\xff\xeaR\x8f\x85\xd0`.\xd8\x9a':A\xe8g\xbfe\xc1\x9f\x91\xb9\xb2\x17\xc2\xec\xd9d\x86\xcf\x9e\x83\xe9\xb3)\x88\xab\xf3e\xf4\x00\xe8 X`\xad0\x8ab\x1e\xf2\x84\x85Q\xc2\xfb\x9fCe\xd5e\xb0\xce\xb6\xd1\x8c\x98c\xf3\x04\x9d;\xf4\x03/\xe1\x96\x90\xeeIK\x0e\x9a\xbc}U'\x9a\x8d\x86\xdc\x1f\x0c\xe5c\x13ymR\x18\xf1\xebE\x89\xc7\x93\x05eUj\x10H\x9cd\xe0\x87\x0b\xac\xe1\xa1\x92\xd8\xf1\x95\xfa\xf2O\xc9\x04\xb0\x1ee\x8b\xa1?r2\xee} \xc9_\xdfN\x17'\xccO7\xc4Y\xf5\x1a\x84\xc2\xb1\x8e\x19,\x1fL\x85\xf0\x82\xb1\xd4\xe2v\x18\xa5n\xe2\xc7\x99\xbe\x00\x98@6\xef\xda\xce\xc1oO\xe5Q\xab=I\xdb\xd1\x0b8I\xdb\xa9'\x11\xac\xb41\xec5p:\x0e\x95\x8f1,\xfc\xc4\x9dI:F\xe3!\xe8by\xb3\xe3\xc5\x8b\xa6z\x15,\xa2\xa9\x1a\xc6\x82v\x00d\xec\x9b\xe1\xffK\x9dp\xbcZ'\x1c\xcf\xe6j\xe3\xeb*6\x1f\x1c\xcf\xe6j\x93+\x8057\xa2gs\xb5 \x14\x80\xe4\xecw\x15\xe0\xf4+\xa71\xa8\xaf@sd`\xb1\x86\xd8\xfdt\xbc\xaf\xc7OG\xffE\xb4\x91\xe7\xa5\xf5E\xfcQ\xd2\xb5\xa5 \xc1d\xbc\xd6\x8c5!\xee(\xa8\xc4\x1d\xb9\xe0\x15\xe4B\xdc\x91{\xf4h\x87\x05\xd7\xdd\xaaW\x90k\xb9\xe0SK)\xa8\x866\x99\xe5\x84\x11\x81\xdf\x19aF\x115\x9b\xd5\xc5\x1c\x052\xe6(\x99\x19\xf0\xecR\xe4\xf1@HO\x13E\xec\xd2\xf8\x94\x17?7^\xfc\xad\xdf;^z\x15\xfbxKf\x93+2\x87\xfd\xe1\xcc\x1f\xfc\xde\x0f\xca%~p\xfcx\x97\xb5\xa4\x05\xc0\xd6\x96k\xd2\xd8\x1eO\xdd!\x1f9\xa4\xc9\x9aB\xbaQ\xd0\xca\xc8\x14\xee\xaaIo\xf1\xfe\xb6\xac\xf2<\x93N\x14[\xab\xbc\xbf;\xd3\xf7C\xafx\xde\xdbf!\xb8\xdb\x85\x9c\x14\x84\xa1'\xc4 \xa5V8H\xad\xc2\x81\xf3<\xc2\xc1\xd7\xca\x18Uj!\xb9=\xcdJ:\x9f\x98\xff\x94)2\xca\xa7}\xf9\xd8\x81\xc2r\x83\xebK\xe5\xb2T\xc2o\xe7~\xd2\xc4\x99SY.l4\xd2\xb9\x8a\xcbo\xf1~}\xa1\xbe\x99\xc3f\xeds\xf9L\x11`>\xa3nz\x9b\x8d\x832\x8dd\xbb\x05\xecN\x9e\xe4V\x83\xb9b\x08\xa5%\x95\x9aXx\x0c\x857\x13\x7f\xe4g\xfe\x98O\xac0bgX+\x92#i\xd0\x1e\x06\x82\x04\xc2\xab\x902)\xd0\xef\xff~\xc2\xfbuna2 \xa9|\xccx\x00\xe1\x0f\x1a\x07\xcbt\xab=\x10\xb4\xec\x88S\x14sJ\xc5\xccIo\xa7P\xcc\xb8\xa3\x04\xb5\xd6\xdcI\xa1~\xe5[\xa2\x91\x18\x06\x93\xff\x7f,\xf3\xb3\x80\xd7Z<_`\x7f\xd0\xd3\xcd\x9b\x19?\xc8j\xfb\x8b\x05_\x10\xbc\xa8\xb6c\x7f4h\xec7M\xdc\x05\x16\xb6O\xce\xcd5!\x95V/\xe7g\xe3\x83\x86\x8d\xdf\xf7\xbdl8\xb9\xd8Du\x96\x19\x15t\x8d\xf7E\xbfs|4\xe9\xa5=\x95\xbcL\x92\xc2\xc0\x11\xd8<\xa1F/\xca\xb2h\xb4\xc0Zb\xb0\xb5%k\xe2_\xea\\G\x04\x15=\x94\x89\x1a\xfctcq\xfbD\xbbS:\x07\x1e\x8f\x13\xeeJ\xcd\xad\xa6z\xba\xef\xcbL\x84\xae1:J\xbe\xe9\n\xa5\x8c-\xb0#G\x06]y\x06\xcb\xa7+;\x8c9\xbc\x997j2\xf9\xb8N\xca\xcd\xd9]h\\\x99 \x87\xc7\xa3\xb6\xa1\xc6\xe6\x18Bo5\x86\xc6:\xcfelb*\xc0N\x90\xdc\x05\xd6@\x9d\xf5\xaf\xe0F\x8d\xf7)\xfa\x07\\\xa6\xf1\xa12\xfd\x0b\xe5\x14\xa7xL\xbf\xc0\x85\x05v8\xb9\xb8d;\x0b\xccm^\xb4\xa6\xcc\xb1\xb0\xff\x8e\xe0\x0b_n\xfb\x87_r\xfba\x08/v\xf7\xff\xf1m\xa8\x96I\xea\x1e\x8b\xd3\xbf)\xf6T\xbd\xf8X\xbf\xa9P,\xccG=\x9eL,\xe6\x87\x19\x1fLQ\xae\x17E\x01w\xc2\x86rZ\x03\xfc2\xc86\xfe\x92vh\xa6\x91C\xc9\xa9\x13\xef\x02\xd9\x7f\xe9\xd8d\x85O\x8c\xe7\xac\xb5\x0c\x95\xb0s(\xb7d\xe70\xe6\xd4,\xa4\xd7\xa8o\xf6YZ\xa2\xb9w\xc9\x89\xa5Lm\x93\xd0\xab\x1b\x17\x9b\xaaB\x97i\xae\xa46o\xca*\x15\x95\xa3\\\x0b8Um=\xd8\xcd\xa28\x1c\xc4j\x99\x92\x88?\xa9\xa8\xa2\xf1E!q\xc4\xaaE\x8a}n*\xc5\x0fbG(\xac\xb1`\x87EA \x00hx\xd3\x14*\xf1VS.\xf0\xd3\xf2\xc2\x14\xa8Q\x8d\xa6\x87L\xa5\xbf]\xfb\x9e\x18Q\xea\x08\xdd\xfd\x8e\x0c\x90\n\xa8\xc1/\xb7Y\xd6\x84\xe6\xda\xce\xc1J\xd6\x95EN\xce\x9d\xea\xd8\x8c\x7f\xb2\xd0\xec)\xab\xfdO\xc2\xe6N\xd8\x0dm\xf9\xd7kh36\xb0\x19\xc7\xf3.D\xd1^\xbb\xd5\xe3\xfd(\xe1\xdbjy\x14\xd9M\x1b\xd3:\x9a{\xe6a\xc2\xfb0\xcc\x94g\x8bY\x96\xf8\xbd<\xe3m!\x80\xb7\xba\xf6\xdb\xbfN\xb74LlzM\xa7q\x89;\xfe\x87\xd7\x17\x8f]\xfbA:{\xec\xf4\x91\xd7~0s\xe3\xe8\xef\x1f\x1f\xa8d\xc5Ug8\xba\xda\xf5i\x98\x8a\x85\xd1\x88\"\xf0\x94\xae\xf5\xe2\xf2\xf2\xcd\xc5\x9d\x9d\xad\x05v\xbd\x05\x97\xe8\xadj\x86P\x92\xda\x82\xd5\xe6c\xc2C).\x11\xd3(O\\\x8bE\x00\xee\x19\x1a\xfc\x89\xfcBm8s\x06\xee\x0eZ\xd2w\xbc*B\x08\x95;mgE\xd6\xe6\xa4N{\xac\xbb\x94\xach\xabN\xb2\xe7E\xfbaU\xa4\xbbK\x0d\xac\x10\xbbq\x86\x85|\xbf\xb0c\xd6\x08\x8f\xc3l\x14\x88clg}\xd9a\x1c\x0d\x12'\x1e\xf2\xa4\xbeP/\xe1\xce^Z\x0f\x0f\xfcp\xcf\xef\x1f6\x17\xd8\x91\x9b\xbc\xc0Z7{\x81\x13\xeeY\xd2\xa8w\xd4EK;\xb3(\xd0\xae\xcc\x12\x96\xa3\x850w\xff\xafI\x15\x05\xf8\x9fq\x8d\x91\xe3\x8aa\x7fJ\x86\xa6\x01\x04\xb1FN \xd6\xeb\xd9Gx\xd7\x17/m.\xb0\xd6K\xa4|l\xf9\xba\x18J\xccy\xfc\xe7\xb84|\xbf\xf7!\xfd\xae@\x8f\x7fNA\x00\xf8K\nH\x83H>)\xf1\xec\xf1_P\xe0X\x02\xfe\x1b\x02\x90\xb3\xbbGvDz\xa6\xb6\x9e=z\x9f\x02d\x94\xac\xb5\xca(\x85\xf9`,\x02\x90\xe3\xc8\x16?\xb2\x03{\x12\xf8\xd8\x0e\x94\x07\xf2\xd1\x13;P\xf6\xf9\xe8\xa9\x1d\x08\xb3\xf8\x1b;P\xe2\xfc\xa3\x7fm\x07\xca\x85y\xf4?\xda\x81\x12#\x1f\xfd\x1b\nL2\xb9\x02\xbf\xb2A\xc6r\x8e\x0f\x08]\x01\x18L\xe3\xaf(0\x05\xfc\xbfGhE8HEo\x9f\xfc\x84\x02\xee8\x89\xc0\xe7g\xff\xfc?`T\x8c\x06\xd2\xee\xfa)9\xd0\x1a\x80[[\x8c\xe2>\x1c\xf5\x7fO\xaa(\xc8\xcf\xff%\x86\x88S\xf0\xec\xfe=\xf2Y\x10>\x89\x88d\xe9bID\x1fcJ\xe6\x00F\xdf\x7f@\xbe\xfbr\xc1\xee?$\x80(]`\xado\xe3Y\xc4qpxN1#+\xa9s\xe28\x89\x0ej\xc6-@\xfc\xb6u$\x8b\x89\xf4\xac\xb2l\x83\x06|\x80k\xa4.\x10\xcf\x7fI\x0e\xb1\x81\xfco\xa4N\xea\x0f\xe4\xc0\xef\xff\x8cT\x12X\xf0\x07\xe4\xeb\xe1\xa8f\x17\x04DM\xe6\x9f\xe3n2?\xf0$\x8d&L\xd1@\xfe\x07\\'\x17\x02G\xeb\x13\x82Q\xea;!!\xfbn\x14\xfa!\x1c\x14\xcc2\x9d}\x05\xf9\x08S\xf5\x9e\xe3\xee\xb9\x11\xd0\xab\xfb\xefZ\x80Z\xcf\xee\xbdG\xa0\x89\xa4\xbaO1}\xef9\xc9\x98\xcb\xb1<\xc0\xfd\x9du\x92}.1\xfb]\xcc\xbb{\x05\x08\xa3\x1a\x80\x80dS`/\xd9\x13\x80?%\xf3\xee%{\x99\x06\x92%\xab]\xeb\xb3 s\x90\xfd\x81\xcf\x98\xe7\xf6\xbc\xdby$\x97\x1dK\n=\xee:y*W\x0e\x8f\xec\xac\x04q+\xac\xd7\x08\x1b\xc5\xd9\xa1\\\xf4G\x98\x92\xf4\x04~X\x91\x83'a\x94\x8b:oc>qV\x82\x82\xc0Ok\xc0\x99\x9430\xf9\xeb\xa9\xef\xff\x0b\xfd\x0e\xa2\x0c\x1dB\xb6\xcf9\x1co\xd2\x89\x96\xb4\xc8\xbej\x00f6=\x7f\xe0\x02\x05~\x88\x05O\x01\x02\xd1\xf3\xd9/0 \x16\xb0\x1c\xaa\xe1\xc3\xdf\xf3\x07\x91\x17\xc1\xb9\xc4\xb2\x93\x80\xc5\x01l\xe4GX~\x12\xc0\xcc\x1fq\x80ZF\x93\xdeV}~D\xd0\xdd\x1f\xa4\x99#\xb9\xc5_\x90\xa9\xfb\x83,\xf1\xa5,\"\xf4&Q\xe6=rr\x8b2\xd0\xc3{\x98\xd6\xf4\xfcAnF\x8e\xa9W\xcf\x1f\xa83\xfa\xd02)s\xda\x1e\x92\xe5\xd8s\x92h_\x80\xde\xc7\xd4\xa2\x178\xee^\x10\xdd\xe1J\xb8\xfa\x10\xcb,\xb2@z;w\x12 \x7f\x0f\x0b<\x12\xae'%K`5\xa1R\xc2,\x0d\x968*\xa5\x02\xb8\xb5}\xf6\x0b\xb2;\xe5R\x89\xbaT~\xf6\x1e\x96\x02\xa4\xae- \xff\x023\x86^\xb077/\xeb\x90\x03\x12\xec\xcd\x9d\x94\x10BE\x82\xbd\x13\x00\xc1\xc2\xb2LO !\x98\xa1\xf5B\xb1\x18g\x9e\xfd\x183\xda^\xc8o\xe7\xbe$\x07\xf7\xff\xda\x02^\x07\x94~\x8a%\xc0^\x08\x80w\xb1\xbau\xd6\xc8B\xff\x07\xaebd!2nh\xeb\x01\xe9]_i\xdb@\xfb\x99\x0f\xe8E\xe6\x1a\x1d\xf4@J\xf9\xf0>\x05-\xaf \xc8\xcf\x7fa\x81\x04\x12\x82YT/:\xf0\xa0\x0eV4\x04D\xd6\xf9\x19^\x04\xd1\xda\x96\xac\x83%\x11\x01\x91\x07\xd6\xb2\x08\x07\x1e\xd4!\xa8\x10\x1dx\xb2\xce\xcf\x08O\x8f\x0e.\xc8*\x96\x01H2\xfa3r\xf6\xa2\x83\x0b\xcb\xb2\nVo\x05D\xb2\xce\x9fciD4\x06u\xe8.\x1c\x0ce\x9d\x9fa\x92,Z\xdb\x95u\xb0\xbe\" \x92\x95\xfc\x9c\xf0\xfc\xe8`\x08u\xb0\x02$ \xb2\xce\xcf\xc8i\x8e\x0eF~\x08\x04\xea\x01\xa1\xf2\xd1\x81&^\x0f\x08k\x8d\x0e\x0c\xd5}\x80\x15\xb5^t\xb0\x0b{\x8e\x95\x0d\x01\x01<\xc1\x82i/:\xc8\xa1\xce\x7fk\x81\x00\x9e`\xa5S\xb4\x06{\x8e\xb5N\x01\x01<\xf9\xa5\xa55\xa8ci-\x07<\xb1`\xddeY\x85\xd0\x92\xe8@\x9e\xfd\x9f\x11\xca\x16\x1d\\\x06\xd4\xb2\xec\xece\x89[?'\xb49:\x18C\x1dB\x95\xa3\x831\xe0#V\xb6Dk\xb0j\x844F\x07\x97a\xa5\xb1V'Z\x83:XA\x11\x10Xi\x0b\x0e_\x86U\xb3\xec\xf5eXi\x0b\xfa\x8c\xa1\x8e\x05y\xc6\xb0\xd2\x04\x0b\xeae\xe8\xb3\xca\x98\xf6k\xb2o\xf5\x80qO\xb2\xf7\x8f\xf1a=\x0bZ\x10\x95\xb7zF=\xfa\xdf \x84\x8f\x84p\xf7\xec\xad?#\x90:\xc9>Us!R}/\x8d\xc4:\xff\xe0\x07\x96\xefR\x85\xff\x90\xc8#i\x14\x0c\xd3\\\x02\x7fEHv\x1e\xc8m{\x93lu\x1e@j1\x1bH)o\x7fj\x01HM\xf9 \xb6L\x08\x08\xe8\xcax \xce\xe6F\xdf\xb35\xa7@\xb8\xd6\x92\xb6E~\x8a%3\xd7@~J\xea\x80\xfc\x88\x89\xbc\x12G\xefar\xe9:\xb16ta\xf9\xcbu\xe2^\xa2d\xc3\xc7\x98\xd5\xb9N\xac\x9a|\x8c\xf5\x7f\x01R\xb5\xf0\xe8\\'VB\xecc\xcc9\x96\x9c\xd8\xcf\x9c`\xd9\xef\xf7y\xc2\xc3\xccw\x02\xc9\x14~\x82w\xdaubPY\x1e\xff\xe7\x7f\x8f\x1bq\x9d\x04\xb6\xf3-,1\xbaN\"\x15\xd3_\xd3\x05;\x0c\xf8!h\x17X\nqu_\x8f1\x82.\xe9\xf6>\xc5<\xd35\x10Z\x87{\xbe\xd4\xc7\xc9\xb2\x18\x08\xe6YKJW\xf8\x14\xa3\xb4\xab\x01xc\x96J\xaa=V\xc0\\7W\xf3\xa1\xa3\xce\xe34\x95\xc7\xf41f\xf6K\xb0e\x9fb\xb3\x8b\xab\xbe\x93\xfdW\x93\xf9\x18\xcb\xa9K\x02\x1086\x90[R\x1b\xb1\xce\xe6J\x7f\x86\xd6\xc7\xf8\x84.\xf10\xe3\xc9\xb2\x1c\xc4\xc7\x98\x1c\xb9\x12\xe8\xd9\x81K\xfd\xc4\xbe\xdfZ\x9f\xc3D|\xe9\x02\xa8\xd6x{\xdc\xa1\xfc\xfe\x0fdC\x87\x1c$\xe5\xbf\xc4b\x98\x84\x8c\x9c\xc4\x0e]\x1a\n\x12\xfa9\xedF\xaa\xcd\xa4\x17\xb0\xe4\xfd\x82l\x00\xa0\xc6\xaf \xd5\xf0\x13W\x91\x1a,\x9f\nP\xc0\x9d$\x89\xf6\xb56\xf2\xce\xffY_\xc6\xe8\"\xef\xfc_\xd6B\x1eX\xc4\x9e=\xc0\xb2\x8a\x02k\x0d\xf8\x01\x96K\x14\xdcS\x06\x9d\x07X>Z\x92\xf0e%\xd0c\xd9E\xd5\x16L\xf5cL\x9c\x15l[T\xfcs|\x9a\xa0\xd9KF\xd2\xc3B:\xc07\xb5\xb0\x87%u\x00\xef\x18y\xcf\xb2\xba\x92c|\x88\xb5z\xd7\x07=\xd3\xb6\x1f}}\x8c?\xc2\x07\xd2\xf5\x93\x11\xd8^\x9fb\x0b\x82\xeb'\xa9B\x8b\x0f\xb1\xcc\xb5$\xd4\xb7}?\xe5KQ\x98Ey\xb2\x1af|\x908\x923\xde\xc3\x87n)\x88R\xbe\x94'\xc1\xe1r\x94\xf7\x02\xfez\x1ee w\x90-1%\x8b2dc\x82\xbc'\x97\xe6\x97X\x0c\x93\x90\xdc\xcf\xac\xc0\xa5\x08\xac\x89\xcf\xee\x91\xe3\xad \x0b\xb6\x1ap\x03\x83Ey\xd7\x80\x88\xfd\x16@\xb7k`\xa3\x91 Y]\xdbw1\xec\xff\x8a\x02\x80\xd5\x12\x16\x14\x8d\xe2>L\x07Kb\xae|\x19a\xc4\x15\xdd\xb6\xd5\x0c\xf8\x01`\xd7\xdbx_\x8d\x99\x90p\xca(\x1chv\x8bI\xddR\x14\x0e\x92\\ux\x1f\x0b\xbaK\x05\x0f!\x18V\x80\xf0\x11\xb3\xe1\x15-#\xb5t\xdb,\xb4\xfaNw N\"\xb8\xd6\"\xacI\x82r7\xb3C76\xaf\nR@d\x9e(>\xac\xfb\x9e\x02g\xc0\xe7q)\xca\x05?i%\xa2e\xa6\x90\xec!\x99M\xee9I\"W\xe7}26 \x93\xeb\xf3>^\x1f7\xe7\xb1\x84<$s\xcdy*9\xc7C\xacM\xb9y\xa0\x97\x1b\xdbv\x01$\xa7\xf5>\xd6A\x96\x94\xbd\x95\xf0i\xf8~\x0f\xab\x9an.\x84b%\xf9\x126\x92\xc7J\xfe&\xd7:nn\xe4e\xc2\x96s#/\x13\x11+\xd7\xf2\xf2\x03K\x83\x11\\\xe4\x91c\xaf\x84\xbc{O,\x02rn\x90\x92\x90T \x92\"\xe0\xfbX\x8dv\x05y\xe7\xb7\xe3\x84\xbb5\xdb\"\xe1i\xee\xd6mN\x12\x1cjc.\xd6\x80$\xb00\xe7\x12\\\xcd\x93D\x1a\xe6?\xc6J\xb7\x9b'c$\xb3\xd0\xad\xd7E\n\x91\x85N\xbc~d\xea\xba\x87\x0e\xaa|\x83F\x04V}\x83v\x0f_\xc5\xb8\x87\x81\x9b \xda\xf3\xec]L\x90\x97e\xaep\x01z\x13Sc\xaf\x00a\xc1\xd4s\x02}\xa3\x81\x0f\xd8\xb2\xdeh\xd2\xdc\"\x00~\x8aq\xde\xd35(\x00\xc4\xb171QXv\xd2!\\\xb0\xe1\xbd\xf14\xe4\x01f\xea^\xc9>\x8f\x97\xd5\xeb\x05\xd2\xd3\xe0\xd7X\xc8X6Z\x15\xde#\xcf@pc\xcb \xb3cv\xe2\xc1g,\x1e,\xdb\xb5M\xf0\xf5\xf8 >\xb3\x9e\xd7\xb0]z\x1d\x7f\x8a\x8f\xf3\xf2r\x94%\x0e\x984\xdf\xc7\x94\xd7\xf3\xa2,\x05!\xe41FQ\x8f\x0b\x0e\xff1\xd6\xe7\x969p\x1e\xac\x18,\xf3\x00\xae\xbf\xc8\xdc5\x00\xcf\xde+\xe9_\x18i\xbd\xbe\x9f\xc2\xd1\xf9\x00\xbb\xe0,k\x85 \x8f\xc0\xd3\x00\xb28\x17\xe0B\xe9\x03l\xeb\xf5\x86\x0ep\x8a\x9fb!Y@`=\xb1\xcc\xb0\xec;n\xe2g\xbe\xeb\x04\x8bun[\xa52\xa06\xfc\x1a\x0b\xa7\x95\x12B\xd6\xd5mQ,,J\x9eW\x9eT?\xac/\xb2\xa3\xae\xeb\x7f\x8d\x8dx\x9e\xefH2\xfb\x10[\\\x96}g\x14\x815\x86\xc0\xbc\xc90#Gcs\x9e\x80\xa75\x10\xb9h\xd8 N\xad0\xe4\x00\xf8\x03\x07\x04\xe3\xdf\xe0U\xf2\xfc\xd4\x97b\xeeCL\x18=y\x13\xf4 \xc1n\x7f\xec\x83c\x83\x1d\x12\x85\xc6\x94\xfe\x90 \x9a?\x8e\xc2\x03+h\xf9\"\x9ct\x8c5\xde-P\xda\xb1\x1c\xe3\x05n\x94\xc8\x81\xbf\x8b\xf9\x9b\x17\xb8\x89|b\xe0\xd9\xbb\x98\x0f{Q\x10H\x94\xfe}\xdc\xbd\xb9\xa9\xc2:\xb2gD]\xacH*c\x06\xde\x0e\xaf\x06q\xa3Li\xc2?&(\x16eJ\x9f\xc1$[B\x94Pq\x1f\xd3\xa0\xe5([\xb9\x9d\x83>8+:f\x01S\x0c\xae\x01\xd8Z\xc1\xb5\x9d\xf4\xd9}\x8c\x1f+\xb0hX\x0d\xe5\xb0fX\xca\xe1\xcbJ\xd2 \xaa\xc9\x8a\xba\x05\xc2\x83\xd5Fz\"cpU\x01\x1fR8\x9f?\xc1R\x1c\xef\xeb\x860cZ\xd1:\x066\xc3p\x0d\xc07FR\x8bz\xf6\x04o\xc5\x8a \x8b -\x19\x08fy| \x89\xf7\x132\xedA\xaa\x8e\xca\x13l\xe4\x05e\xed \x96\xe2VJ\x86_\xd2\x7f\xe0\x87\x19OdW\x7f\x86 \x13\x87K\xed\xb71\x93\xe2\x01\x0c\x0d\xef8\x0f\xcc\xd0\xf0\xda\xaf\xe8\xe8\x0b\xbc\xc6\\\x03H'B_\x94c\xc6\x04IBR\xb8\x86%@\x99ky{\xe4\x04\xc1\xb6\x91\x08\x7f\x81\xe5\xe3B\x17\xb5\xd7\xbf\xcc\x13\xdc\xc6{\xd8Y\x84\x8fRI{\xdf\xc4\x9cS\x00\xe6NH\x10V\xa3$H\xba\xbe\xbdI\xfa]?\xbf\xc0Z\x9f\x91\x83'-\xef\x9f\xe1\x0b8\x1e\xaa\xce1G^\xd1.\xfe\x0474\x80`\x87\xd1\"\xb0M\x8e\x1b-\x82\xe0`\x0cT\xf4!\xc1\x80\xd8IR\xe0\n\xd8*\xc3\xb5\xf4\xfe\x18Sx\xe5\xb4\xfb9&\xd6+\xc6\xd9\xfbs\xda\x8f\x01\xe1Z\x02$\xb6\xf67\x04p[_\n\x12\xba\xc7o\xd7\x931~[y\x97\xdc\xc7k\xcdo\xa7\x81\x13f\x83,\xb1\x1fT\x00\x07<\xb5\x9f\x16\xa3\x07=\xa6#\xcd\x1dy\xc4\xce\xd8\xaah\xad\xdf6\xa0\x9c\xc3\xb5\xe8}\xcc\x92Vn\xe7~\xe0\xf7\x12?\x97s\xf9)\x16\x18JN\x946\x08\xd8\xae\x1ec\xa5\x81\xdf\x1e\x17\x1b\x8e\xa5h\xaeY\xe0\x07d\xc3\x13Mq\xf1\xa1_\xd1nA\xd8\x10\xc55\x00\xf3m\xaeI\x0e\xd1&W\xd4\xbe=\xc6\xd7&\xbcnCW\xc0tE\xf8\x06|&|i\xe7\x82\xa0\xdb\xb8[\xb0\x96~\x82'\xb0\xa2\"%\xc8IV\xdf y\xc9\x13\xe9R\xff'\xd8A\x8a\x1f\xb8\xa2\xc2\x11\xf2\xd9\x87\xad\xbf\x87\xe9\xd1\x8a\x80\xa4V\x10?\x88\xb9\x9b9:^\x86\xac\xfa\xca\x01${\xf0\x9d@^/S\xdeY\x14\xb03\xd7\xbe\x13\x04\xbe\xbc$T\x96G\xc2d\xcf\x81\x98\x80\xa5\xe6>\x88 \x98\x82\xf6\xf9Hu\xf5K|\xf3\xd0\xef\xfb\x10\xf8\xf8\x9f\xff\x06\xcf\xb3\xdf\xd7\x10Z)\xd0 \xdc\xd59\xcd\xe4\xb1\x9c\xd6\xd7\x00L\xe2\x8a\x01`5\xe2\x9c\x1f\x04\xdc\xc3l \x13\\(ec>X\xec\xea\xdf\x82\x9e\xfa\xb70 p\xc0B\x87\xc5\xaeb\x9e\x18\xeb\xfbA\x16J\xf4x\x0f\x9f\xd3~\x18 \x06\xf0\x9f\xc8\x96\x19\x96\x81\xf5\xb3\xbea\x19\xf8\x10\x9d\x8b\x92E\x10'\xee\x91=\x88\x12\xa7\x1e$\xfdX\x1eb\xc3\x87\x00\xc0\xbd\x00\xe6g\xe7\xa2<\xf1y\x92%p\x0bL\xe6\x14;I\xa6\xfd\x1e\xb0\x10\xdaO\x1cW\xba\xb3\x7fL&& \x92\xa9\xff\x04\xd3, \x12L\xfdc\xbc\x9f\x12rJV\xc2\xc4_\x82^\x96 <\x01 zE\x82\xb0\xe0.@\xf30\n\xb2 \x02\x04}aF$@\xd2\xe1\xfec\xac(I\x08T\xc2\xfb%A0\nl\xfa\x13\xa0\x93P\x0bK\x19\x02t\n\xa6\x85e` \x82\x06\xb1=W\x80\xbe\x03 l\x13\xe8'\x0e\xb0\x97\xb7\x08%HT\xe8\xc3\xbbX\x08?\xa7y\x05\xd9{\xa3\xfbb\x81p\xa0U\xaf\xff\x07\xf3\xe2\xf3\xca\x08\xfd9\xdevm\x9d\xfe\x1c\xb3\x17Y\xc3\x13\x12\x08^\xb8\x81\x81\xe0\x15\x18\xc0\xcd\xed\x13l\x970\xa2\xc9\x13L\xd6\x00$\xf9\xfb\x13L\x8e\x15\x0c\xe6\x8a\x91~\xc0S5Yz\xf3.`0\xc8'\x988\x9c\xd7\x1c\x0b\xab\x17\x03\x0d\xc0\xec\xf7\xbcTd\x1fb\xda4\x00? ,\xac\x0c\x065\xc5\xfd\x11l\xce\xdbXx:\xaf\xaeN0\xa7\x1e\xa8\xab\x13\x82qpc\x80\x9b\x19Hg\xcfgO\xc8\x1e\x83\xbc\xf2\x04s\xaeApK~\xc7\xd3\x1d\x84\xea\x00\x92\x05\n\x8b\x98a\x0b\x10\x10\x98\xec\xc5\x9ckud]\x96U}\xaf\x82\xcf\xb4\xaf\x01X\xc6\xf0G\x0eh^\xb6\xb6\x06~\xe8$\x87\xab\xf6\xd5\x199\x83@\x9d\xe8\xb71j\x0b`\xec@\xca$\xbaw#\x99\xc5\xb4\xf5)\xd6\xd4\xfd\x91\xb4<={\x80Y\xb8?\x8a\xa5\xc3\xec\x7f\xc2\xf8\xb4:\x8a\x03\x1f\xd4\x1f\xe2`\xe2\x87l\xc1v\xf9\xe5\x87\xae2\xb0\xbd\x8d\xafc\xcc\xde\xdd\xc3\x8a\xb7\x84\xa8\xd0\xfd\x0f\xb1\xbe\xec\x87*\x87\x06\x99\xd1\xaa\xc2\x12\x82q\xea;\xd9\x8d0s\x81\xc6<\xc0B\x9c\xca\x08\x0d\xb1\x1a\x98\x81V\x9c\x97,\x8d\xf2\xa4\xae\xd9Uy\x11\xc8M\xf6$\x92X\xc4\x0f\xb3\xc0I\x86\xd2 \xf7\x11\x16\xda\xfc0\xd3A\x14\x1fa!q5\x1c\xfb\xa9/\x1d\xac\xc0fb![\xba\x88\x89qz\x0bK\xe5\xab\x1b@I\xb0m\xd5\x8f@\xf4!X\xabo\xbc0\xc1\xf35\x00\xdf%\xac\x1a\xae\x86\xf9\x92o \xd8\xac\xb5\n'\xf9s\xcc\x07\xd5 \xff\x1c\x0b\x16~\xed*\xf9Z\xca\xfe\x18\xb3\xf9U\xcd\x15\xc9\xe12\\\x11k?\xdaC\x92\xe2|\xea\x87Z\xf0&49\xf5A\xc8}HF\x9d\xfa`#~\x88\xbd_%DZb\x1fb\xca$@c\xfb 2\xfb\x0e\xeb\xfcS\x9f\xe2\xcbp\xdf@\x08\xc1\xcc\xf7\x00-\xb0\xee\xe1+\xc0?`s\xe8\xaa\xbaq\xc1\xac\xdbW\xdf1V\\\xd4\")\x9e\xfa-\x0d\xc0\xeb\xa8l\x1b\x18%\xc0\xb4\xf1\xf7xm/j\x06\x86y\xff-\x0d\xc02\xca-E6\xff_L\x1d/\x1a4\xc5\x87\xe4\x96\x81`}\xea\xa2\xc1!,\x94\xde2\x10\x8c\x90\x17S\x9e\xc0d\xf0\xce\xde\xd2\x90\x7f\xc0\xf2\xc4E\xbdQ\xd8\xa6uKo\x14\xe6\xf8\xdfw\xe2X\x9e!|\xe6\xf64\x00\x930 \x90\x97\xbfX<\xf9\xbe1\x8abo\xa5=\x03\xc1\xab\xf9}\x18/\xe9\x1d>\xe3\xbe\xbf\xafw\x0b\x0b^{\x1a\x80\x91zo\x90@B\xa8O\xb1\x90\xf5}\x15\x0d\x8cwdOE\x03cn\xf5}\x85qX8\xd9S\xd64,\x7f|\xdf`\x03\xa6\xf1{\x06B\xea\x18l\xc0\x82\xd6\x9e\x86\xfc9&\x9b\xc1\xa2\xd6\\\xf0\"\xae\x99\xfc\x02\xf88\x04\x06\x82W8pJ1\x04\xf80\x06\xce q\xe0\x16\x13\xb3\xff5g\xd4\xf3$\xbe`\xdc\x0f\x0c\x04\xabOk*k\xe6\xaf\xb0\xf8\x14h\x00\xdeM\x01\x80\xfc\x8e\x98\x11\x05\xc6\xb3\xccR \xcc\x8exC\xd7\x1c\xf9\xe2\x9a\xbe\xc4\xc23\n\x1cH\xb8\xf61f\xf0kZ\xab\xc7RK\xa0\xed\x00\x98\x85\x98\x986\x1b@\xc6\xf6\xfd\x14\x8b\x18\x12\xd2\x97\xec\xe0}|\xf9 `\n\x84e#\x01\x02\xe1\x81\xa8\xa2\x02\x14\xc8\x95x\x07\xcfH\x06\xd6I\x81\xe5}\x8a)\x89\xb6\xe7|\x80y\x8f\x80e\xb2\xda;\x98\xcb\xa8\x1b\xd2'\xa4\xa7\xc5\xcc\xf1\xa1'\x8a'\x06\x84\x89z\xe0@D\xf2\x13,\xfe\x0b\x00\x98\xa8\xfe5\xb5\x18\x05g\xd5\xb2\xbf\x8f\xa9E\xd0\xd3\x10|\x98\x03\x9d\xe4\xef\xaf\xb0n\x10\xf4\x12\xb0:\xfc\x91\x0d \xea\\\xa7\x80=9\xecGX\xd1\x16\x904\x00D\xc6\x1c\x12`2\x8f\xd1#\xcc\xac\xd6\x8c\xb7!V\xd0\x03\x03\xc1B\xca\x9a!\xbd\xf8\xf8\x05\x06\x82\xa5\xa4\xc0\xe5\xb0\x13\xefb\xd6\x13\xb82\x16\x15\xaf\xc1\x1a\x90F\xb2\xa5\xf0\x99t\xec\xb9R@}\x1f\xb3\x89\xc0\xe48\xc4\x84QB\xc0\xe2AN\x9d\x97x\xda\xe1\x143\xf1\xc0K\xf2T\x03\xc9.x`\xd2x\x87l5\x18!1 \x06\xf2r\x1f\x9fT\xe9\xf2/\x88\xcfY\x81\x07\xe01GhP%.\x80\x90\x81\xb5\xb2\x0d\x89R\x8f\x8a\x85\xc9V\xb7\xec\xedN(\x89)\x80\"\x04\xb0,g\xba\xd1\xc7\x90\x1cj\xd1\xd2\x12\xf7\x03H\xc7J\x91C\xc0\xc1\xf9\xbf\xbc\x14x\x19\xa1\x94t\xd7.\xf9\x8dc\x0b\x85.Ur\x1b\xc7\xb6\x9ej\x11\xed5\x8ei\x87(u.\x88\xa0\x8dw\xb1\xe9VLZy\xe0\xeb,\x7f\xc4\x1f\xbeT\x06\x02|\xdf!\xe7\x85\xf73\xb3|\xa0\x1ec+5\x0d\xf8 FaQ\xa4j+$\xf6\x99\x80\x14!\xadT\x8b\xa4\xb5[-\xcb\xa8iA)r>t\xa9\xf4v\xee\x0f\x8a\x1e1\x11\xb6\x05'`\x8a[\x8a\x9e!\xa1\xa4\nV,\x8c\x0d\x83\xab\xd8\x82%\x1d1\xd4l\x98p^\x84\x98\xe1\xd9\xc8FJ)\x1f\x1f\xe0S_.\xa0\x90\xe9CL\x9c\xcbe\x8c}\xf2\x01\x16\x93D)\x08\x92)\x0d\x19\x0b,P\xa8:-|\xa7\x0feJ\xa1\x1aXG(\x17\xd0\x07\x00\xeb\x04(\xda\x03\xe3.\x8d\xf4 \x82\xd0\n8\\S\xfc\x80\x0bi\xba\x19p\xc1CD\x1a}\xf3C k\xc9'\x80\x9e\xbe\xb4\xee\xbb\xba\x99#\xf2\x9e\xf1 x\x8c\xd7+(\xf9\x04`\xedM\xc1\xe4\x1a<\xc1\xb4&\xe0\xa9\x9a\xacE\xce\xe0\xa9r\\x\x82o\xd4\x03\x9e\xa6\xa5\xab;,\x81\n\xb0\xb6\x13`\x0dZ\xc0\xf8m\xe5\xf7jYc\x01\xd5`\xb25kO\xaa*\x14\xa1U\xa2\x08\x12\xb0 \xe1\x8a\xeeHrA\x94\x80\"\x95\xb8\x0d&\xcdC$\xc7x\x00k\xd9\xb6|\x06\xd7\x92GD\x18\xd0~:T\x1eOJ\x04\x92X{\x12\xa5\xc0R\x01=1\xb4\x91\xec\x00\xa4\x00z\x93X>\x12E3\x1f\x10\xca\x98:Z\xf9\xc6\xf8\xb9\xa6\xafF\x88dh\x8c\x92X\x98ZS\xaa5\xa1\x95\xb5\xdfk\xa4\x81\xc08}ac\x88\x80\x80`J8vz\xbbg\xb3\xc7\xa4z\x82\x041Rc] B\x92vb\xf8\x8c\xc8\x8b\x06\x82\xed\xbbk;\x0b\xac\xf5]\xfcQ\"\x05\xe5\x9a\x99\xa5l\xa0\x9d\xce\x08\xdd6Ng\x84\x86d\xb5\x82\xa4T\x8c\x16l:QP\xa8K\x84=e\x9a\x9d\x7f@hQ\xc9U\x8d\x98v4K&t$K\xe0:\x97hK\x81\x0e1&\x89\xf3\x83,\xd1\xeerdRy\xe2\x19\xc3\x0e9\xb3ybB\x90\xc9\nV|\xd0>\xb2H\xf3\xda\x07\xcd\x02S\xb7\xfa\x1f\xe3\xdb+\x13.\x83g0r\x80\x16\xfc%\xd6\xec\x04\x80\xc3\xe3\x1b\x04v \xc4\x89\xf71\x91\x1e\xc1\xf7w\xf0\x94\n\xfeT\x032\x96\x0dl\x1e\x03\xb0a)Xa\x03\xb0\xb2y\xe0k\x92\x91\x93\xec\x01\xc5z\x0f\xdf\xfd\x8et\xb6\xc5g\x1fa\x99\xf9\x12H\xa0\xd8\xbc7\x82\xcf\x98\xbd\x8eL\xca*l\xe5\x18\xe9H\xe6{\x98\xb1\x8f\xb8\x93\xe6 \xf7\x8a\x07\xb6\xb0\xf2q\x89{~>2Ndoa\x82{\x89\x07\x81\x1f\xeak\x01l\xf4\xbe\xa4\xd5\x01l\x88\x1bi\x00>\xe2\xa3\xa1\xdc\x9c\xb7\xc9\xea\xfb\xae\x0c?\xfb\x18K:*-\xe8=l(\x19\xf9\x9e\xfd\x8d\xa2\x91\xef)\xba\xf0\x14\x13\xd6\x91\xef\xd5\xa4\xcf-\xb2\xc0`\xb2.!\xf0\xc6\x16^\x1b \x82\xd1a \x0e@R]\xf9\x08/\x81\xcc\xc9\xaa\x13\xaf\xde\xc3\x8cq\x14\xb8\x90\xad\x10\xdb\x8fG\x01\xb3\xb4g\x1e\x1a\xa3\xb0\x0c\x1e9\xf8%\xa6M\x12\x02f\x85:\x18\xf8\xfc`\x1f\xbb\xb0'\x9d\x8c?\xc6\xd4:,R\xcc\xd3\xb1\x97r\xc9S\xa0\xce$\x89\x97}]\xdf\xe5|\x86\xb7*4\x10lz_\xd7w9\x9fa\xae\x11\x1a\x08\x96:C\x93r\x96\xf6S\xce9k\x19\xb9Jt\x89Q|\x1d\xc88\xd6\x14B\xf8\x8c\x15\xca\xd0Pw|\xbaT\x82_\xb2\xd4\\{F\xbd\x8fYU\xc8\xf5\xdd+V*D% y\xc7\nQ\xaa\x02\x85\x99\x88g2\xfdu>p2\x7f\xcc\x11\x1fy\x13KW\xba\xdc\xce\xd0w\xf7\xa6*\x16N.u\x99'\x87\xcd%Ko\xf5`KS\xc8S\xaer\"a[AX\x04l[&\x9cf\xdc\xa3A%$\x82\x02\n\x96-\x7fD\xde]\xe7\xfb\xca1\xf9\x07!\x19\x82 \xaf&\xf4\x86\x17\xf1\xd5\x18\xb6\xae\xf9.6\xb8\x85\x1a\x80\x87\x19\xea\x988\x8a\xd9*,\x0e;\x16\x86:\xce\xcd\x06\xb8]\xdfX9\xd6\xcd\x06O\xeb@:4\xccRI\xef\x13\x96\x1aB\x1d\xd6b!\xc9\x03\x00a\xb95\xd4\xc6[\x028\x9f\x01\x06=\xa5\x030\xd1\x0eX\xb7\x0cM\xb8\x03!\xacCexx\x8a\xd5\xbbPj\x0b\xf7\x08\x0e\xc3Cq\x0f1\xf3\x0b}\x10>\x1eb\xa9/\x04\x8c'\x0d\xad+\x93'V\x11Be\xf2\xc4\xea^h|8\xb0\xba\x19\x1a'\x0eZGI)XD\x0e\xf5E2]Du\x97\x8c\xa5\xb5\xb0z\x13L\xc7P\xb9\n&\x03\xb1\xdc \x92M\xb2\\!\x92\xed\xd278dx\xc5\x15\x8emJ\xe5[\x1c\x1b\x19jM\xdbr\x0e@\x1b\xa3\xddh\xb5\xf5!&W\xa1\xd1[\x1fbkZ\xb8\xa6\xce\xc8\x13:8-\xc1c6\xb5\x1e\x9dM\xb8#Y\xd8[\x98\xbb\xadG\xa1\x04\xfa\xe1@\x13w\"l\xac\xebX\x11\"\x9d\x18\x01\x16K\xec\xfam62|\xd0\n\xf0\xe7\xf5(\xab&\x95\xc7\x86\xc9_\x01.\x06\x81)\x7fQ\x06\xc5b\xda\x86b\xe3\x9d\x0d\xe5\x0c\xf7\xc4V\x9e\xa2\x08\x0e\xcclh\xadX&\xcc2\xd6\xa3\x8c\x86\xe2\xd8ZB\xf18\x14\xe1\xa3L\xb9B\x13I\\@\x8c/\xb4\xbd\xa2r\x87\xb6\x03\xc7N}\xbb\xf0\x10\xf4C\xac\xd9\x02\x0cr\x98c\xe3\xd5z\x94aO\x00r\xe8Q\x19\xe3\x0c`[\x19\xabG\x00\xa1\x15\xb2`\x0d\x8dS\xb0by1\xd5U\x05\xca\xc8c\x1dHY\xea\xb2\x0f\x95^\xac\xd6\x95+p\x06\x93\xd7\xf5(\xab\x93\x07\x9f\xfc+[sT(|\xf2\xd7\xb6\xadV\xa2\x00\xf6\xc8\x93\x10\x85\x04v\x18 \x01\xd6\xa9\x01\x06H\x805\x8f\xf5(\xdbL\xb8\xcb=\xf5\xd2\x0b\xb6\xf3\x95\xe0f\xad\x9e\xfc\x1b\xdb\xe4t\xb1\xea\xba>\xb4P\xac->\xe6I\xca\xcbD\x0fOG\x94\x92\x195\xcb\xc8IdlTHc\xa7EOA%\x8b\xe1Y\xa86\xe4\xc1\xd9\xce{*\xe7\xdb\x03+\xb6\x97K\x15\xcdYX\x84.\x18\x8b9C\x83\xd6\x01V\xcb\x15Mb\xd3\x97(Z\x8c\xedO(k7\x05\n\xb7\x1c\xa2#\x8b\"\xae\xcb\xb9\x07\xbb\x8e\x0d\xfa%x\xb1\xeb\xd4XQ*\x86v\x1d\x1b\x1aK%\x8b\xf3\xf4\x1f\xed\x0d\x96\x16\xea\xc75\xb3Ck\xf4\xc0\xc23\x8bn,\x93\x93\xc0\x82\xccXx\xa2,Qeg\xc4Z\xa4J\x15=Y\x86\x81\x99?\xd1\xd6\xe3\x1a\xa9@\x00\x9c P \xf1mPH\xcd\xf1\xf4o\xe9+\xb4\xa1\x8e\x80\xbbG\xa5\x810\x8e\x02\x1d\\\x88M\xc9!?}\xc7Z &Id\xcc4\x8f\x1b\x88\xb2\x02\xabI\xd6T\xd6\x93\xb4\xf4\x9b\xa9|;D\xc8\xd7qx\x9f\x10\x8b\x96\x81\x10;T\xa6\xbc\xd1h/\xe8yr\xaa\xe2\x96K\xc0d\xa8\xaeK\x9e/\xa7\x07\xbfRD\xb5C\x04\x0dy\xa5A\xec\xc3\xf2+1\x0f\xcb,\x9a\xbfG\xbfrH\xda\xf86\xbe\x13\x0es\x9d-\x96\xd8\xb3\xc7\xfa='\xcb.^^\xd6\xcf\x14\x12+\xd8e\xf3\x82!\xb1\x18\x8cM-B\xe6\xc6\xa6\x16Y\xc6\xb1N\xbbe\x19\xc7\x18\xf2\xcf\xd8 \x17t\xb8\n9\xbc\xe3\"\xfe\x1d\xdf\\\x85cm\xcbz\x1f\xdb\xe9\xc3\xb1\x8ee\xb0\xf5\x06. v\x88\xb9\xc4\xb7\x815\x0b{\x9f\xd0\xdd\xb1\xe1\n\x0f\xfe\x9d\xad\xa6~[\xf8?X\x80\xfb\xc6\xe8Oh\xda\xbe\xe6\x99\x04\x15\xf65\xcf\xb4B\x14W\xa3\xb0P\x9b\xc7\xf1\xd5\xe1\x86I\x11\x81\xef*\"\x03\xc1W\x81Q\xdd\xf3\x99\x91\xba\xac%\xeffn\xe8\xf4\x11XF\x894\x00kc*\\\x1b\xef=Dk\xff=\xd6\x89\xa2\xda\x1797\xf4\x9bM\x9f\xe1k\xed\xc8@05\x8a\xe0!\x98g\x1fa\x9a\x13\xe9\xd7\xce\xb0\x93V\xe4\xa5\x91\n{\xc2\x96\xdd\x8d\x15H\xbd\xf0\x19\xde\xff\x88+\x00Y\xf8\xbeZ\xc6G\xd8\x95iC\x1b\xfeI[\x1a\x80\x0f\xa6\nV\xff5\xde\xa9\x0d\x93\xc4\x824e \xd8\xa4\x1d\x81\xb1\xfdC\xcc\xba\"\x9d\xa8\xe7\x116\xc3DC\x81\xfd\x9fc9&\xaa{\xa112\xa6hl\x06\x8f\x02\xbd&d\xeb\x03\xf3(\xe1#\xec\xb4\x13\xe9\xc4\x12o\xd2Z0\x17,\xcbn(O\x98\xcf\xb0\n\x1bi\x006]o\x8c\xf8\xc0\xb1\xceR\x01~\x83\x19\xe8\x86\xf4\x8f\x90\xe9\xa7\xb1M3*@x\xef#%R=\xc2\x86\x9fhT\xfb.\xec\x861\x9e\xe2+\xd2\xc8@\xb0\n`\\)\xb1\xf1i#\xe6\xa1\xf5\xc5U|\xbdo\n\x16E\xb0_Z\x14sx\xf0\xf0\x11\x96\x11\x8c\xef%y\xc5vC\x0e\xeb1\xa1 N\xe2k\xbf\xc8(\x17\x04)\xc0\xb3\xf01\xa6\x14Q\xe2\x81\xb5\xe7mL\x8b$\x04R\x8a\xd8`2\x13\x17\x16>\xa2\xc4\x13\xb8\xff1A\xe4\xc4\x1f\xa8\xec$d#\x13\xf5b\"\xde\xc6(I\x83\x08D\xb9\xc7\xf8>7J$\xa9zLH\xb1\xfd%\xe1\x0d\xa3\\\x90\x01k\xc7\x0fB\x89u\x8a\xa4O\xc8.\x1a\x08!\x94\xeau\x8f\x07\xb8\xca\x86\x11\xf4\xf0\xf6F\x06\x82\xa9\xc8F\xe1s\x8bq\xb2p\xc7%\x8f\x1a\x03\xc8\x81zx\xa97T\xb6\x06\xb2\xd2\xea;\xd9\x9a\xb1\"q\xefbanc\xccu|\x11!2\x12\xa6\x82k\x9f\xfd\x19fe\x1a\xaa\xc2 \xff\x94\xac\xfb\x98'\x9bN\xc2\xc3l\xc8S\xb86\xfc3|\xd4\xb42\x85M\x06B\xd7\x13\xd8\x87\xe7Q\xd1\x01-\x95\x94\xb8\xf2\x14s\xfc\x92}\x82B\x94m\x02\x016\x9d\xc4<\xcfF\x81\xc0\xc61\xf9\x8b\xe13&}1O\\\xc91\xfe\x19\x05\xf82\x1f\xca\x0c\x05\x8c \xd6\xf3Mlt\xd6\x94\xe7\x01\x99>O2\x1eJ\x81\xecM\xac\x85lj\xfe\x8ayu\xac\x01XX\xde\x84\xa7\xd2\xb1\x96\x1b\xc3S\xe9\x98\x1c\xc7Cxu\x00\x1f\x8ax\xa8^q\xa6\xfeX\xf1P=\x17\xfd\x17\xf8&tS\xf6\x8c\xe9z,;\xc6\xfc.\xf63wX\x9b';\x86Q\xe1S\x12\x07N\x08\xef\xc7\x93\xa4i\x00\x82\x84jx\\\x02\x06i\xb7-\xd5$\xd1?j\xf9\xec(\xc6\xff\x11\x16\x92\x05\x104\x7f|\xb2\x04D\xd7\xc2\xa6\x04\x01\xf3\xa4\x9aE\xde\x81\x93 p\xf3#\xb8\x11\xe4\xe0\xd3\xfa\x18\x0bE\x9bA\x9e\xea\x87\xd9?\xc6h#\xaa\x8d\xc2:\x88:l\x1f\x11\x1c \xf24\xdb\x97c\xfc\x08\x8b\xeb\xf1\xc8\xd6\xdaf\x04\xc9\xa8\xc4\n\xcba\x92\xcc\x83\xb1\x90\xb9\xb4\xa1\x10c\xd9\xa6\xbe|\xc5bml\xa4\x04l\xbf\x8a\xa3\\>\xf6\xf81\xde\x95M\xb9\xecO0\xd3\x05S\xe4}\xcc\x0d\xe3DE\x18a\xc2nL\x94\xf7\xb1<\x1d\xc3[\xf5O\xc8y\xd0\x96K\xfa\xdd\xad\xe9\x9b\xbb\xa50&:\x02\xee\xaaw\x83\xad\xe3(\xdf\xb3\x90\xb6-\x97,5%\xaa\x96\xf6\xda^\n\xab4f2e\xe3\xab\x05T\x8e\xd4\xc2\xb2\x96\x84+;\xce\x13\xccu%P\x87Ya\xe9J\x00\xb5\xc5\x10\x0fh3Q\x16\xc37\xe9\x16i\x08>E\x12\x92\xdaq0\xd1Qht\xf8p\xc1j\x19z\xc3\xc0\xd5S\xed\x98\x02m\x96\x1ej'\xd4)\x89\xfaN\xa0\x04\x00\xac\xb3\x08\xa0V3\xde\xc5\xca\x94\x00\xa698\\\xbfKx\x87z\x7f\xed\x1e\x96D7\x93(\x8e\x12\x9dI\xed\x1e\xc6\xcc\x02\xac\x12\xb5\xe1\xfa\xa2a\xf0\x9b\xb7\x80\xea\xb6-N\xf2\x04\x04\x83\x07\x98en\x1a\xa1\x11\xdb\xc6bc\x91\xc6\x86\xc9Mx\x95\x87\xac\xbf\xfc\xfc\x1b,\x96\xc6y\xe8*\x13\x17\x06\xbd\xae9,&\xd7\xb75\x00\xef\xc8\xed\xbal\x8b\xafk:\x87\xcd\x13\xb7\x0d\x9d\xc3\xec\xe2\xb6\xc1\xd9\xb7\xb0\x80\xf9\xbaY\x15\xact\xdf6\xab\x82\xf9\xfc\xed\xdc\xc9x\x12\xfa*3\x01\xc9\x8c*\xe0z\xf4\x98\xeb\xea\xd8\x94\xd7l\xdf\x15\x91\xc2\x02\xd5\xeb\xbb\x1b;\x0b\xec\xdb\xado\xe3*Qf\xf9\x9c\x98\x84KX\x9b\xd0B\xec\xbd\xbf\xfd;\xcc{\xb6\x8c/5\xde\xa0\xc4@0\xc3I\x1c\x0f\x12\x90\xde\xc3;\x91\x94\xb34a\xfa\xb1\xa5c;1\x1a&\x1a\x80u\xf0\xc4\xa4U\xc2'S@\xe4\x94\x1ea^\x9f\x14 \x97hs*s\x12fo[Z\xd9\xc4R\x97\xb9\xfc\xa2\xfd\xab\x1a6\x00\x10\xbc\x0f0]KLR%:\xe6\"\xa9\x12\x19Bq\x97f\x81\xa8JX\x84J\x8atKXQL\x8atK\x18\xf1\x13\x93n\xe9\x03L\x0f\x92R\xba%\xac\xe9l\x99tK\xefc\xa4O\x8aLLX\xd2(]\x03\x92E7 \x97\xb0\xc2\x94\x14\xb9\x98(\xeae>\x10M\xac5IH\xa8\xfd\xe7q\xbd-\x93\x8d [\x18\x13\x03\xc1\x1c%1y\x9a0\x05HL\x9e&\xb2[:O\xd3]\x1b@\xd4\xb9A\x01*O\x13\xa6\x84I)O\x13\x16\xd3\x93R\x9e&<\xa3-\xe3\xa7\x8f\x15\xfb\xc4@0\x03\xdf2~\xfads\x0d\x04\xd3\xd6\xc4\xe4i\xc2\xc6\xb3\x04\xf24\xe15\xd8\x02\xcd\x91\xe0>8\xc3b\xad'\xd1y\x9a0kM\xbc\xc0\xa4\\\"\x87\xdf\xe4p\"\xf8V\xe4p\xa2 \x15\x17Jh\x19\xc8\xe9\x04?9\xf0t+@g\xc9%\xd4\x99;\x81\xc9\x92k\xab\x08\x88K\xc6\xc6A\xdey\x0f\xeb\xae[+\xe7\x05\x91\xc3|5\x81W\xfe\xf1g\x8b\xff\x0fvV\xd6E\xd03r5\xc5vcT\x90<\xb7\x9a\x14\x890\xb0=\")\x12a\x90\xe6U\x0eh\xb2BZ\x90 \xdd\xe8\xc4\x16\xf8\x16\xdb\x84'\x93\x17\x7f\x13\x9d\xd8\xe2\xa7\x04\xe7\x8a\xc4\x16\x98ln\xc98\xba\xcf\xb1\x8e\x95\xc8\xcf\xbf\xa1]DR+'\x8cX\xc6\x88\xe3|]\x18\x8bQ$9\xe6>\xc8}\x820\xa7\xaa\xf7\x84\xb5v%g\x17fTE\x89J\xd4\xfbO\xf1\xfd_\xd1\x91I\xda\x85\xe9\xbfl\xaa\x9c\xb5\x0b\x93\nY\x80\xa6\xed\xc2*\xb5*\x86\xf3v\xe1\xd3b\x8a\x95\x12wa\xb3\x16*\xa3\xf3\x0ea\xf1G\x16;W\x8b\xa7\xe5\x04V:\xc2\x95\"Z\xa9\x10\xf8\x06P\x8c\x13EP\xf6.\xeb:\x97\xf2\x80A)\xc2.D)\x9c{\x8bPf\x9ff\xd4\xb2.\xa2N\x97\x85em\x0d,\xb0\x13[F,\xcfr\x13Z(\x8a\xa0\x8cYx:\xc4\x17\xf1\x01\xa1\xceVG\xc4\xa6B\x85\xf7\x1a\x96\xdad1\x925\x0bK\x04\xaaTur\x98R\xa9B\xa5\xa4WX\x8b\xab\x94\xd0\xf8\x87\x05s\x94\xd3\x8c N \xae\x9b\xc0\xbak\x02\x87\xee\xd7D\x88\xf2\xd3\xea\x83\x8d\xa4\xa2I\xa6CP1\xd0\xe9 \x08\xfa\x05\x90\xf3\x81HQEf\x1bL\x0c\x93jf\x1b\x02\xd6\x81\x0cO \x933 d0WLL\x02\x19\xbc\xe8\x89I \x83iKbn\xd3\xb0&\xb8\xa5uQ\xc2\x95\x8d.J\x04\xde\"/ \x1duqGB\xf0/\xcaC\xaf\x94\xe0\xfe\x03\xac\xde'0\xc6\x8e\xe53\xdc\xf8>\"\x9a]\\r;$<\xc2d\x03!\x04\x19\x85\xf0\x90\xb3[d\xea\xc0\x06\xb5-};E\xebh]\x1b\xfb\xc6l)\xc9\x8b\xec}\xedw\x99\\\x83\x08\xd1&\xb9\x06\x16l\x93\"\xb9\x06\x01\x15\xa9)\x082\x17t \xc7ni\xdf\xc3\xf7\xb0\xa5\xab\xe4db\x81H\xc2zE:\xe2\xc5\x93\xf7d\xbc\xb5\xe8:\xf2a0\xefR\x88\xdc\xc9'd'G*\xaf<65\x08\x00\x84\xaa\xfd\x0d\xcd\x02\xb5\xbdqn\x07\xce*\xa9\x16\xf538\xadX\x9c\x01G\x9f\xe3\xf4\xab$\xe3\x1fb!_\x00\xd4E\x1aa!F\xf0\xc5rQj d\xc9bG]\xc1\xfe\x92\xa0\x99\x04\xe9w\xfd,\xd0\xc4z\xf0\xd3\xdbJ\x96x@\x98\x9f\x80\x80\xaf\xd1\x9f\xd3\xb5Ko\xab\xdc!\x0f\xb0\xb0,!P\xefg\x965\xbf\xad\xfcg\x88\xd4t[\x076`\xb5\xa7\x08\x94x@(\xce\xedR\xf8\x82\xb5^\xe1\xd7o\xab\x0b3 \xb4\xd4D_<\xc04P\x82L \\\x0dPuH\xebJK\xd9{\x98\xd5\x97^\xae'R@=\x08j\xe1g\xa8\xc8.\xd2p\xc0\x86\x02\x85R\x8f\x17\xcb\x16\x06\xd8X\xa4h\x8a\xb0\x11Yn7\xd4#\xa6\xf8\x93;p\x83L\x1e\xf2Oo\xe75\x80\xda\xeb\xa5msk\x89u\xc8\xd4hR\x98#\xa7\x0d\x02I\x03mJ35\xee\x87\x98jogp\xfa\x08 U\x80\xbf\xb0\x01d[\x7fAD\xc6,q\x04\x9f\xe6q\xea\x07r \x7f\x83\x95$]D9_as\\\x9a%\xd2\xeeE\xb2\xdfm\xc3\x01|H\xf0Z\x1dL\xc2r\xf3\x9e~\xb3\x9b\xa8\x0e&\x16\x89\x02\xe0d\x91\x19\xe7=\x9d\xaa\xe7)\xe1\xbayo\x94\x83\x07\xf3S\"[\xe7=\x90\xfa\x9fb\xbb\xa2\x80@_\x84\xc0\xe6=\xcdE\x9f`\xb2\x9c\xe6=\xc3E\xb1^Z\x1c#\xdb\x1a\x990*+H\x11\x05\xcb\xb4\xcb\x11T\xd6\x0e\x8b\xb3d\xaf\xad\x12\n\xdb\xa6 \xd0\xdbu\xeb\xa3\xfd\x1f\xb1-A\x80`\xd3\x9f\x12\xec\x11 \xc8\xf2F8\x86\n\xf6\xa2\xfaj\xee\x96]\x8f\xb0\xd6*\xc0e\xd7#\x8cL\xe5`_\xd2\xb6%\xd2\xb7\xa6\x04r=\xaa\xeb\xa5\x14\xe1k\x19\xa7\x0eY\xb3\x80\xca\xaeGD5\x15p\xedzD\xd4S\x01\xacUPs\xb7^\x0b\xcd\xdd\xe1\xce\xd0\xb1_Bm\xc3e\xd2=\xc2\xf7j\xbf\x83!\xf0\x97\x98\xb8n\xc3v?\xa4\x15\x80}\xd2\xd3\x1a\xcf \xf2\x82OO\x9a\xc7\xf3\xe2;\x91M\xf3\xf8\x84\xf8N\x84\xc7<\xd6\xe4\x05[ \x05H#(\x11XM\x84 \x05\x009\xa0\xd8\x1e\x1b\xd2\x83\x05\xb8j@w\x0d\xb08\xa0\x96\xa6\x87\xca7\xfcWXQ\x9405 |!\x9c\xe6\xb1I\xdbJOSl\xa8!\xa55\xb1\xa2\x86Dp\xcdcE\x0d)\x1d\x8855|J\xc45#\xed\xd8\xb6\xbfn]*b\x90eI\xca\xe1\x94V\xa8\xa6h\x96\xa1\x96)\x9ae\x8e\x9a\xa2\x11\x9e\x9e\xc7z\xad\x89\xc0!@@\xd1\x08\xbb/b\xd6\x88\x19\xc6\xc4\xacachjb\xd6\xac\x90\x9a\xbc\xd7\xe9~\xa8\x8d'D\xba\xb9\x03\x91S\x9f`=q\xc7\x113\xfaA\x86>gN2\x80\x9dy\x17Oh\xc7\x91!\x9aX\xaf\xc8\xe4\xe7\xdf`\xe4\xcf\x94\x9d\x9f\xf8\xea\xef\x18k\"i\xc9@\xb0\xa6\xb1cl\x80\xd8\xfe\x92\x19\x08\x96\xa9\x94zF+H\xdd\x0c#\xbf\xce\x9c\xfcclw\xcdx\xa0\xbcb\xdf\xc5\xeclG\xdb\x8b\xf0 \xcc4\x00\xdb\xcd\xb3!O\xf8I\xd1\xd8=\xb2,\x02\xd4\x8f@b'\xd0\xac\x11\xba3\xe4\xf0\x06*\xa6g\x99\x06`\xb6)\x01\xe9\xa1\xc0\xf7\xdf\xe0\xc3)ac;\xc4w\xf7J\x197\xf1A\x91\xf0:cJ5\x03\xe2[\xbf\xa2/\xf5gC?T\x9e\x8d\x98\xdeU\xb3\x1dbh6\xdcS\xb1\xbdtD\xf5\xe3\xb9\xb0\xb1\xb5.N\x066\xc7d\xc3(\x11X\xf8 \xe6\x1c\x86\xbb\x93\xb6t<\xce\xaf\xb1%\x1a\xa5\xdb\xc0\xc4\xce\x92k\x03\x8bq(\xd1\x06\x99\xa0\xba!\xf9\x84\xe0\xa0\x00\x80\xec\x8d\x15z\x00\x01\xc1\xf8\x88\xa0\xa8\x00\xc2\xbb\xb9XP\xc9\xea\x1e\xe0\xce\"\x0e>B\xd8n\x99\x81\xd7\xee\x03r\xd2\xa3\xb8\x07\xe7\xed],\xd0dQ\xac\xd3\x18\xe3\xa1\xed\x18\xdb\x06\xa6\xed\x99\x81`\xca! *d\xe3)6\x1bdQ\n\xc3\xc6rSVx_\x93\xa3\xb6\xb5\xb8,\x99\xe4\xdb\x84\xb0$\x0e\xec\x91\x05R\\\x9f\xbf\x87\x15.\x0d\xd4\xde\x0b\xefaA\x0d\xc7\xee\x93\xac\xea4t\x9f\xa4W\xd7E@F\xc6HJ\xe2\xfa\xc9\xa5\x9a%\xac\x9f\\\xafe\x89zU\xe5\xd9/\xb0IL_\xc9\xd9z6\xb6\xc1\x8f\xb0\xdc\xbb\x93\xf8q\xc0\x97\xeb\xe8\xb2\x80\xaa\x9a\x96\xe1\x02\xea\x7f\x88]\x06\xb3\xc4\xcf\xd4\xd6~\x84e\xa3,\x89\xf9\x1d\xe5F\xf5gx\x0fw\x8c-\x00k\xbe\x99\xb1\x05\x10\xa2\xa5nz0\xfb\xcf\xd4U\x0f\x96_v\xb4\xf9\x9f\xa0\xb7\xb6\xff\xe3E\xd81\xcf\x0f\xd0>4\x04_\xc0d\xfb>\\\x8c\xdc'\xdb\xb4\x1f\x0d\xb9\xe3U\xf3K\x12\xea\x08\x85\x90w\x13&1\xbb& \x1e\x1f\xba\xdc@\xf0~\xefj\xd1\x07\x8b*\xb9\x96\x960?\xcau\x0d\x0c\x10M\xe9\x00\xfb\x0f\xf0\xb6\xec\xf6\xd4\x93\xca\xf8\xa67W\x80\x7f\xc0s\xde\xed%\\\xc6y\x7f\x86\x97,7\x10L\x13wu\xb4>\xde\xb3\\\x030\xfe\xed\xc2\xa8\xb0\x1c\x93\xc3\x98\xf0\xa9\xcf=\xed:\x809\xc6\xae \xd6\xc7\x04<7\x10LZs\xe3\xca\x89M]y\xe1?\x88\xf9\xe1\xae\x16s\xb0\xd8\x91k\x00V\xd7vM\xc0<\x16as\x03\xc1\x879\xd7\x9e\x85da\x86N\x02\xeen\x98d\xe6& -\x1ern\xde\xc5\xc2\xdaJ.\xdf\xa7\x12\xa0w1\x95\xca\xcbOWY\x80*6\xe5]l\x1e\xcd\xcdC\x18X\xfc\xda\xd5\x11\xf2X\\\xcf5\x00\xbb\xedC\xb0\xed\xc7\x98\xc1\xee\x86\x9e\x8e\xa9\xc5\xef\xe5\x00\xc8\x84\xd4\xe2Ce\xc0:\xa6\x16\xd3sY\x00\x07\xd5\xe2{(c\x8a}\x88\xf1SBt\xb6\xff\x07\xf8\xa8\xed\xaad\x0b\x9fa\x0c\xc95\x00k\xf4\xbb\x86\xc5c\xcd-7\x10L\x04\x9b.\x1cw\xe3\xc2\xb9\x86\xd0\x95\x02f\xa9Wv\xda|\x1f\xdb\x8c\x15\xb8r'KOh\\\xbd\xb3\xc5\x8a\xc5n,\xa4\x81b|\x18\x9eW\xe1\x96\xfa\xd8+\x98\x9c\xeaX91\x9aw?\xc8\x19\xd2%\x8a\xa7\xa4\xc8a\x8ak\xb77\x8e\xf1[MX\x9b\x94E\xd0\xad1\x96awU\x08\x14^\xe4\\}\xc7\xeb*\xbe\x0fm\x15v\x8d\xc1\xfbs, \xe6\x85-\x9cn\x93v\xbf\xc4\x95$\xa4\x187mSa\x10x\x7fb\x99=O\x0c\xa9\xc1\xe7)/?\x02e\x01jRC\x16\\9\x19~F6Z\x03\xb0\xd8\x92k\x0f\xaa_`\x82\xbbkD\x1d\xc2?\x8c\xa8\x83U\xb7\xdc\xbc<\x84\xeb\xecj\xdd\xe83L\xbbr\x03\xc1\xf2w\xae\x9d\xbb0M\xca\x8d\x0b\x17\x96ps-\x0b\x90\xd5\xdeUy\n\x08\xe1V\xdf\xb1.\x97\xef\x1ba\xfd\x11\x96\x9d\xc6N8\x80;\xc8G\xb8\xb9\xb1\x934\\\xab\x8c\x9dD(\xce\xd2c\x01\xaf\xd0\xd8I\xc2H\xe8\xbe\xf0\x9a\x06\xc6\xc2\xb1\x93\xd4\\\xc6\x08\x88o\x0b:\x17\x80\xfa\xb8\xc6\xb1\x16\xa7,\xed%Vz\"\x00\xe0`\x8f\xe5\x86\xb1\x93\x18O\x0clR\x11\xb0\xea\x1d\x03\xbd\xd2-\x97Q7\x0d5\x85*\xa6\xbd\xe62\xca\xc0g-\xa4-\"\xc4\xb6!`H\xd3\"\xaf\x03\x97\xca\x18\xaaH\xfc\xa1/+\xcd\xfa)f\xe1c\xc53\x9e\xe2\x83 \x002\x8a\xef)>\x08\x97A$\xc4\xe4l\x0c\x9f\xf1\xf0\x8a$f\xb8\xeb\"\x87\x19\xee\xa1HaFFe\xea`]H\xb6&%\xaf\xa7\x98\xe3^V\x9e\x9c\xf8\xa6m\x0c\xdfI\xea\x991\xe7j\xb9\x1e`qx\xcc\xb9\xd2W\xb1\n1\xe6A\xe0\xc3\xbd\x02&w\x97y\xa2\xda{\x93\x1c\n\x0d\xfa\x11\xad\x93\xd5\xd5\xc8j\xca\x97\x13\x9bb\xb9T\xc3\xd5\x13\x17u\xd5\xb7y\xec$\x8e\xf2+\xff+,B\xebR\x85\xe5\x07#3}\x04\x04\x13\xe5\xcbZ\x0c\xc7\xc2\xf6X\x030\xee\x8e\xb5\xc4JQ\xdf\xe4\x8e\xb4dz\x1c\x9b\x9c\x8b\x96\x0c\x89\x97\x8dx\x86\x95\xf1\xb1\x81\x10:[\x1b\xef=6o\x17\x92sg\xd8\x16!R\x86ma\xc5z\\\xba\x01\xb6\x90\x8b\xd2-\xb0\x15j\xeeKj\xa0\xbc\x8eZ].\x0e\x17\xd6\x00\xc6w\xfc\xc1\x1dG\xb2\x82G\x18\xf1\xafh\xbfV\xcc\xfd\xf65\x00\xf3\x9d}\xee\xa9\xf3\xf0\x18+\x00W\xb8\x07Q\xbd\x0f\xf1\xe8\xf65\xe4\x1e\xde\x17 \x81C\x89qj\x9f\xfb*[\xcc\xdb\x18\x97\xafht\xc3\xf3\xd9\xd7\x00<\x9f+\x063\xb0\xa0\xb3o \x98\x94\xec\xdb;\xdfO\xac\xa7g?\xe1N6\xb4\x82\xae\x18D\xc2\x87`\xdf \x12\xd6A\x0e\x94'\xd4C\xcc\x04\x0f\xd4\xce<\xfb\x05\x16\xc0\x0e\x94\x13\x14\xd1\x9c\x0e<-\xfe\xe0k\xe67\xf4za\x9b\xc2\x81\x06\xe0\xfd?\xd0\x0f\xb5\x90\xb7o\x0f\xb4\x8eL\x9e\xbb}Cf#\xc06\x90\x03\xf9\x15\xab\x00\x07:\xbd$y\xcb\xf7@\xdfA\x927|\x0f\xd4\xf3d\xe4!\xdd\x03\xfd\xe2\x0bf\x05\x07:\x99\xe0Gx\xaf\xde0\xe8\x80\x95\xef\x03\x03\xc1,\xef\xa0\x88\x0d\xc1l\xea 2\xd6A\xb2\x91:<\x9d\xbc\xdc{\xa0}>\xc8\x83\xbdo\x18L\xc2\xc4\xea\xc0`\x12&\x8a\x07\xc6;\xee#l\x1f<0\n\xd7G\xf8\xb6\xed\xc0\x88\xcc\xa4\xa7q\x0dK>\xd8\xaf%\x00W\x8d\x8d\x0e\x93\xdfC\x03\xc1\xb8yu\x11\x84\x12\x8c\xe6\x87\x0e\xd8\xaf\xf0\xfe\\\xd5$\x0b/\xda\xa1\x06`\xbc\xbc\n\x1d`\xd9\xe6\x10\xda\xc7\xa4\xfd\x90\xcbdBX5\xbb\xaaO\n\x96\xdf\x0f5\x00\x8f\xe7\xea*\xf4\x8b\xef\xa2\x0f}\xe8\x18+\xadW\x0d\xe2a?\x9fC\x03\xc1D\xff\xaaA\x14L \x0f\x0d\xa2`JxU\xd9\x0b\xb1\x08t\xa8\x0c\x86\xa4<\xe8;\x9f\xe1\x83z\xa8\xf4 l\x00\xb8fBQ0\xc2\xdf1\x10LT\xae\x99\x1b\\\x8c\x1ew\x0c\x04\x93\x90k0\x0d\xbc\x8cw\xe03F\x82k\xea\xe5vL\"\xee\xa8\xef\x98\xa6\xdc\xe1\\?\xe2\x89\x19\xc65\x9eDW|/\x1b\xd6?\xa3vM]\x9fb\xc9\xf0\x8e\xfa\x8eq\xe5\x9a\n\x9b\xc6]\xdd\xd1\xc8E\xa6\xa3,\xfe\xa4\x030\xf8\xff=\xee\xe0\x8e?0!c\xf8l^\xd3ar\xf8\xb6\xed\x8e\xc1;|v\xae\x19\xbc\xc3D\xfa\x8e\xc1;|p\xef\xec\xdf\x92k\x85 \xd7\x9d\xfd\x10\x00\xef\xb6\xcc\xf7\xbb\xf2\xaf\xbb]\xd6\xcfC\xe9g\xda\xe6]\x96uY\xd8a\x7fd\n\xb5\xf2\x94\xb34K|7k\xbdj\xbe\x8e\x9d\x84%\xec\x0c\x0b\xdb'\xe7^\xe9T\xbb\x8a\xe4\xf7\xf9\xeftf\xf2\x90\xa7\xae\x13\xf3K^Q\x93\xcf\xf0\x838J\xb2\x94\x9d\xa9\xf6[\xeeTw\x11v\x99\xdfeN\x97\xe5\xec\x0c\xcb\xaa\xdd\x88\x9fh\x84\xcf\xc4Qz\xc99x\xb5\x02\xf5\xfb\xac\xfd\xf2,;sF\x14H\x13w\xc6\x1d:\xc9R\xe4\xf1\xc5\xac\x9dup_\xe2\xd7\x8f\x12\xd6\xce\x8e\x1e}\x95e\xec\xbb,}\xd5VF\xb7<\x07-\xb7Cfo\xbe\xc3\x12\x9e\xe5I\xc8\x8e\xcc\xbdZ\xdb\xc8\xcb\xf3\xb2\x91\xd0\x14v\xd8\x19\x96\xb4\xa36\xb4\x98\x06\xbe\xcb\xdb9;\xca\xe6\xc4\xeat:]v\xe4\x08\x9f\x89\x9d$\xe5\xc9\xcc\xd8 |\xcf\xc9\xf8\x9a\x1f\xee\xb5\x9d\x0e{\xe9%\xd6\x96+!\x16\n\xea\xf0\x99\xc0\x0f\xf7\x96\xa20\xe3a\xc6\xce\x88e<2\xdb\xb1\x8f\xe7\xb4\x1a\x8bhGV\x17K\xc0^\x13\x7f\x9fa\xf3l\x81eG\x8f\x92\x8aw\xc9\x173\xebo\xd5\x97\x93\xeb\xec\xb33lV\xad\xb4\xe8\xf3\xc4<;\xd2\xb4\xa0\xa2\xcc\x91v\xc8\xbe\xc7^\x11\x7f\x86\xec\xbbl\xeed\xe7\xd5\x0e\x19\x81XX\xebd:j.t\xfe\xfe\x83\xf4\xe8\xf1A\x97\xb5X\xab3\x93E\xf2\x0eg\xc9Iy\xfb\x85\xe0\xf0F\xef\x16w\xb3\x19\x8f\xf7\xfd\x90o&Q\xcc\x93\xec\xb0\x9duY\xeb\xe6M\x9e^\x8a\xbc<\xe0\xad.\xc1\xd6 \xe7\x0b\xec\xc8l1\x82N\x97\xc9V\x9c<\xc8\xca\xd3\xac\x99%\xc5\x147\x1a\xc5Q\xc8\xc3,]`\x8en\x89\"\xfb~\xe2\xc4K\xa5\xa2y}\xd14s2\xbe\x19\xe4\x03?L\x17jXA\x1as\xb7\x0e\xc6Tw\xdb<\x90\xb9&\xd2\x05\x96\xd0^\xf4/-J\xf9\xd6Bw\xedu\x9d<\x1b>\xc7\x08\xa2\xe7i;r\xd2\x13Mm;r\x8f\xd2\x05\x96\xd6\xcf+\xe1^\xeer\xd1\xb5[\xbf\xd4\xfaWZ\x84\xc0>P\xf2\xf5n\xcd)\xbcK\xe9l\xdc\x0e\xdb'\xe7\xe7;\x16\xc9\x14@'0\xc87\xa0\x93\x18$\x88W_\x82NaP\xaeA'H\xadT58\x7f\xe2e\x0c\nt_'\xc9\x08]\xdd\xe0\xc9\x13\x9d\xce\xab\xdf20}JX\xbf\x9e\x1c\x08\x02\xc6g\x8a\xc3\xc8^c\x9c\xd96Um\xce\x02\xe3u+j\xe98\xa6\x1d\x0b\x92Mz-\x88t\x95\xd4j\x0e\xfeGw)\xbb \xf3 `G\xce0N\xe59\xc9P$\xcfc~\xc8xG\x93\xa18\x89\xb2(;\x8c\xf9\xcc\xd0I7\xf6CM\x90f\\'\x08\x04Q\x0bA\xd6\xc9\xae\x877\x04S\xb9\x1e\xde@|N\x0d\xb3L\x8b\x04-,-\x02\xfbF\x90J?\xdd\xdew\x06\x03\x9e\xcc\x0b\x8e7\xe3\xa7\x1b\x8b\xdb'\xe4\x9f)O\xc6\xb7\x1b(\x82\x103y\x91\x942\xc5#KtY.\xddJ\xa4\xec\xaa\x93\xe6\xc7\x03&\"\x99\xb0\x90\x00\n\x17^l\xb1\x97{fz\xaek\xcd\x03\xcc\x9f9o0\xefp\xde\xa4=/2+vD\x00\x01 \"\x80$)Y\xd5}\xb0\x96\xad$\"\x10\xd7\x1d;\xf6}'a\x00\x9b*\xfaf\xe7\xbe\x92\x1bl\xbf\x0d\xf1\xed\xd6\x8e\x12\xc6}-\x8cW[\xd1\xde\x07]=\x1d\x13W\x0d\xd8;#\xc5\xe1U^\x10z\x91R\x1c_aP\xfc\xeb\xbb\x9c6\xa2&\xday_\xf6\xa6\x0b!\xdf\x16\xc7\xce\x1cz\xec\xcb\x85\xcdc\xa7\x851\xd5\xf8\xec\xa3\xcc\x94\xf7t\xc8\xb0/\x9fq\x03\xf4\xc5L\xd94s\xb7\x89\x85\xf1o E\xe3\xdf\x12\xfe\xc6\xbfk\xdc\xce\xfe\xac\xd0\xfe\xddLI,e\xffvUw\x8f\x91C\x1d\x82\x83)\x84\x13\xbcXn\x86\x7f\x95\xb8\x17\x87\xed\x85\xf9K\x1f\x89\x15F\xfe\x18\xcee=\xbd\xce=\xfb\xb9MP\x0c\xed6\x93\xc4_\xbf?=#\xe1\x9f\xa3\xe4IY,\x92,\xfc\x99\x18\x88\x8a\x9cR\xd1JZ\x9e\x96\x8c\x1e\xa8Hy\x05!\xe2+ \x91\xd2D\x88\xe4\x9f\x86\xd8\x16\xbf\xe8\x84#\x0d\xaan.\x95-\xee\xceP\x7f7k\x87.\x83}\x7f\xed6\xccvq\xab\x8c'\xdc\x01\xc2+>t\xdf{\x11\xe6\x85\xd3\x06\xfe\xeav#q\x91]\x1d\x92\xbf\xdb\x8e7O\xb2\x03\x7f\xb60\xcc\x0d\xa4[\x93\x1d\x06\xbe\xee\x0e\x1d\xc7\xd8Q3\xa2\x14R\x8a\xe9\xe6\xb1\xba\x14u\x0e\xd3\x91\xa6\x94\xe2\xdf\x92Q\x01\x94\x0d\xb1\x14g\xd8J(\xcb>\xb6P\xbe\x84bn\xfe\xc1c\x7f\xf6}D\xf7|\xd2\x04\x00m\xfdk\x0d\x03\x11#\x03\x92\x96\xf9\xc2\x8e\xc9\x05\xf8\x14\x81\xf3\x1b\xbd\xda\xd6_\xaeQ\x056\xf3\xe6aT\x90l\x00|@}\x88\x18FE\x91-Q\xd6\xbdv\x1cG\xc1v8.X\x8b\xa2H-\xfc\x14!\xd7\xf2\xd3\xf0\xcf\xe4J\xbc\xa1\x84\xc2\n\xc3/;\xfd\xd0>\xe2?\xc8\x7f\xadt\xe5*\x99\xbfJV@o\x8d\x8a\xad\xf2\"\x12\x9f\x15\x0b&2\x7f\x92e\xfe\x95\x9d\xc1c\x18\xc1>d\xb0\x01#\x98\xc0\xa6\xe3\".\x18=\x82\x10\xbe\x82\xec\x11\x84\xeb\xeb\x0e$\xd3\x90V8\x96[\x9b\x86\xc7\xdd\xcd\xa4}\xfaws\xd9\x97\x155\xe3\xd3\xcb=j1\x8b\xd3\xe2\x98\x92\x8b3\xbf\xb0\x13\x87r\x93mV3\xd1^\xff\xac\xe0\xf7\xbf\xff[\xf2\x8c\x9a\x9a\xbdK\xa1\x82\xdc\x06W\x1f\x0f\xe3\xebVe\x91\xef\x84\x8d\\\x99\x81\xbd3\xd6y \x03+\x13%\xf5\x86\xa1Z\xa7GB\xa0\xd5\xe4E\x1d\xde\xd6\xc8\xd7\xe6m\xbev\x18\xf1\xb2\x12\x8f\xe3\xf6*#\xccK[\xe1\x9fB\x89\x7f\xe2\n\xff\x14\x1c\xff\x14\x12\xfe\xc9\x18\xfe\xc9\xe0+(\x1eAF\xf1O<\xcd\xba\xf8'\xd3\xe0\x9f\x04Ug\xb7\xc6?\x127E\xf1\x8f\xdfB/1\xc59]\xd1\x8e\xe9\x88\xaf\x84\xd7?)+E>gV\xa9\x8b\x07\x99\x0e\xa2\xa3MH\xaa\xa2\xfb*N\x88\x15u\x98\xa4Z\xa9\xf1P\xaf\xd4\xd8T)5X\xd1H%\xcdcEz\xa5\xc6\xd6\xef\xab\xd4\x10\xbfd\x91\x7f\xb3\xa1\xa7~\x14\x9d\xfa\xb3\xf7\xf9\xa4&b\x9as\xf9\xb6(\xd2'\xa8\x88\x8b\xd4\x15\xde\x12Lc\xf5u\x12\\Mj\xfa\xbcY\xe7\x90a#\xad\xfa\x92\x97?M\xe2\xc2\x0f\xd1\xdfL\xa3\xbc\x94:;\x08B\xf4V\xc8\xd55_\xa7\x84%\xff\xa9\xfa\xd6(\xe9\x12Q\xf1E\x18\xbf\x9f@(j}\xe6\x87\xc3\xb7c\xbb\xab\x9fKxI\x07\x90C\xbc\xbe\xec\xd8\xa6p\x8cUF\x14l\x91\xa8XQ'\xf1\xd1A\xb4\xff.%\xa8\xf5B\xc0\xedr-\xb1\xb8\x18*ex\xb7\x0e7\x0cI\xc9\xec\x8d_,\xba\xe5LJbU@TA\xa6\xa5\xb0)\x0b\xe7`\xaf\x15\x95\x1e\xb0:\x03\x9cH\xe0\xe9ul+O}J\xf5\xd0\xdb\xc4\x05\xebU\x02\xd5$\xda\xcc4\x9d'SI-\xfd\xb4\xa6-z\x94@\xda\x8e\x83\xf0\xbc\x03e\xe2yO\xae&\x12c\"\x9ekW\xdf\xdcb\\\xcd\"\xc6\xeb\xaf=\xc8\\\xc7\xaa\xf1\x81Z_|\x91\x91\xb9\x10\x13\xecc[0\xb9\xd9\xf8A\xcc!W\x16_\xab\xc6\x17\x99XI\xba\x9b\xf2\x00\xa3jc\xe90\xd5\x8c-\xf0=\x9bUR\xaaa\x02\x83\n\xf7LZ\n\x0c\xf9\xd1q\xd3\xd0\xbf\xf3\xa5\x0b\n\xfe\x94\x98\xd6\x12pX\x13\x98\x99\xc5\x01\xb8\xe4Q\x8f\xc8\x00\xfd\x86,s\xa5%)\x16I\xd0\xdbV\x8a\xee1=\xa2\x15q\x9e\xe9=\xc3\xd8t\x17r\xba\xdd=\x12\x99(J.\x8e\xb2\xab\xe7\xc5\xeb\xb2\x98\xb4\x8d9\xe5\xe7Z!<\xd0\xbdo\xbfko\xe3\xb0C\xcb\x8eY\xfey\x194uo\xa3Pu\xe7\xd0\xcb\xc8\x0e\xc5\x9d\x13\xf6\xdf9\xe1\xe7}\xe7d5\xf1\xa1\xbbu\xa4*\xdf\xd3\x85\xeb\xd6\x0b\x07\xdfNX'\x9e\x87g\n\xa8/\xab\xfb\xabb \xba\x95\x98\xb1\xf8<\xee\x96D\xec\x0ee\x06\x84GW\xa9b\x9c3\xac\x12\xe6\x07\x97dV\x16\x8a\n\xf3\x9e+4\xc5\xf2$~\xba\xf0\xe33\xc5\xf7\x01\x82\x8d\xf5\xd2\xcf\xde\x07\xc9E\xac\x92?.X\x95e\x12\x90\xe8\xe0\xd2_\xa6\x11QU;g\xd5:\xb4\xa1\xaa\xee\x12\xb85q\xc1\xe4\x01\x01\xc9gY\x98\xd2\xad\xb7*]f\xf7\xb3\xb3\xd6g|\xe9\xf8'\xe4\x02\x12\xefu\x16\x90\x8c\x04/\xfd\xb4y\xce\xe9ZG\xb4\xda\x99\xf7\x9e\x08\xe1w\x98\xe5E\x9bu\xa3\x80v\x05{p\x86]\xa8\x90\xd6)\xec\x81\x95\xe0)fw\xd3U\xcd\xef\xa3\n\xdar\x81\xc9f\xdb\xb6?H\xa2\\\x19n2\xbc\xf5(\xeb\x1b\xce\xf0B\xba\x97\xcc\nRl\xe4EF\xfc%\xbf\x08\xe9$\x98\x91k\xe4\x85q@._\xcfm+\\\xfag\xe4\x1e[\x88N\xa1_\x06a\xa2+<\x0f\x03B\x0bu,\xf0 \xdb\xd6\xe7qZ\x16*m\x03\x9f\xcb\x0c\xf6\xeb\x0b\xae\x85DOt7\x1d\x93f[\xf3\x90b\xecK\xf3;\xc1\x0e\xa1\x82V\x98t\n\xb5\xa3)\\lL;(.'\xd0\x8f*/\xae\"b\xb2^\x07\xf4\x1a\x880\x98\x07\x1d\x9d\xb6b\xf72\x026F\xeb\xdf\xfe\xf5\x8f\x96\x90}\xdf\x14\x07\x81\x0e:NN\xf0p\xea:/]\x88(\xc0\xdf|\x85\x1a\xbdfI\xba\xc1O\xb8v\xba\xf6\x17\xfc^p,\xe7#L7 iFf~\xa1\xdb\x0b\xca\x95\x0b\xbcQ\xd5\xa4\x97\x82\xfc\xb7\xd8\x0d\xd3\xf8nw\x88dj\xb8w\x9c\x12\xe1\xec\x1a\xa9\xb0\x06+\xab\xabta\x1a\xf6<6\xf2\xfeA\x98\xa7~1[<\x8f\xc3\"\xf4\xa3\xef9\xcb\xaa`J\xc4\xc3n\xff (\xf8\x12\xf1H\x13\x9c\xa0\x9f\x94\x05\x1b`\xc1\xbaz\x01\xb4\xcd\xc8\x9c\xde\x04B}E\xcehs\x13\x06\x8a\xcf\xe7\xb0\x0f\x01L`\xae\xffhU*\x15\x18\xa5\x8azu\x83\xfd\x86z\xef\x9d\n\x1f(\xa5\x1dZC<\x18p\x07\xc9 \xb24\x9d\xfd@\x05'yRf32\x81es\x04\x86\x83\xb2P5\xd3\xbbW5K>\x01_\xc1p\xcb\xfc\xf8\x04\xcan\x0dr\x99\xfaq\xf0\x8c\xa4\xc5b\x02#\x85t@\xf0\xdbJ\x01\x9c\x80\xda+a\xb8\x83$\xac\x02\xf8jA\xd8\x9c \xc2d\xe2WQ\x9f\x13&z.\xe4\\w:3Y\xfb\xa3!\x12j M\xd5\x15\x90\xd58B\x96L#\x06\xec\xdd\x19\xe8]\xe9 \xefz\x8c\xa7\x15\xe9\xa2\xad\xd2\x90\xbc\xc5\x14\xeb\x95\xb0\xaf\xad\x9e\x18g\xcc\x89\x9d\xee\xed\x05B\x98\xc8\x996\xedh\xd2L\x12\x03VJn\xf8\x17\x0b\x8dW-\xfa\xaf~\xb2\x19\xff\xd4\xd4\x81\\\xc9zS\x818X=f\xaf\xf2\x83\"i!\x04Y\xdbCQd2\x87Z\xd1nY\xbd\x8a\xd1\xc2\xcb\xd3(,l\xeb\xc7\xd8r\x86)\xd3\x15\xad\xc4\xf0\x186a\x9f\x1b\xb3\x11X\x87\x91\xe3\xfd\x94\x84\xb1m\x81\xe5\xc0:\x14`V\xe0\xf2\xcat\x10\xeaM\xa3\xb8\xaa\xa5\xa9\xf5\xc5\x06\x8d\x1d&/\xfa\xe5z\xd8\xb6\xa8\xa8\xf3\xe6=q\xdc4,\xb4#\xafF\x91\xb2\xe5#\xef\n\xf6 \xc5\xb7\x9f\x1b\xf13S\x918 /\xe8\x908!/\xe8\x908>/Pz\xbb\xcfT$N\xce\x0b:*\xcf\x88\xdb\xe9\xd6c\x9d *gf\xa0rf\x9f\x9e\xca1;e\xf6P9x\xa5\xbb=\xc2\x90U\xa1'L\xce\x18\xd3\xd3k\x88M\x9f\xd0\xcbI\xc1\xbe\xaa\xd5Hx\x06\x14gY\xee\xe3{?\x0b\xfd\xd3\x88\xa0\xc8c\x85\x0e\x85R;\xec#\xc8bn\xb3^(\xfa\xd3\x7f\x951O\xfc2\xcbH\xcc\xbf4\xd3j\xd5\xa4\xcfH\xf1\xa4(\xb2\xf0\xb4,\x88m\x05~\xe1o\x9c\xf3>\xfb\xe8\xac\xe6\xc2\xa9\xaf\x06K,\x8d\x05{\xd5\x8d\x82\x91pb\x83\xa9\x0e3\xa66\xc68AZ9\xd1\x97\x9f\xfb\xd1\x04|e\xf1\xb5f\x8f\xabE\x1f\xb4\xa3\x8c\xe3\xc0\xddd_R.\x97\x04\xac\x85\x8e\xe9/\xef\x04\xcd\xdc:\xdc\x00\xfa\xafh\x90\x08\xb4\xbd7T\x9cE8\x8c\xb3\xa8\\\x8b\x9f\x85\xc1\xcb\xa4\x8c\xdb\xc9\xff\xe0\xa32\x19\xdcB^\x0d'\xa4 \xbcH\xf9\xd3\x96\xebcZ\x08%>#\xc7\xcb,\xb2\xfa/^\x15Y\xd7Z\x8b\x1f\xc2(zKf$<\xc7\xcb2\x1f\xb0&\xbd\xa7|\xc8\xa2\xc4\xb2sJ\xdf\xc9^\x15\x1f$\x955{\xe3+\xf5\xdaS\xba\xaf\x1eqk#\xd0\xb5\xab\xf9\xceD\xc4\xd1\x15@/\x19o\x1e\xc6\x81D\xfc\x0d\xa4\xfc\niwyl\xc5F\xdf\xda6LF{h\x8c\x11Vdl\x0b\xb0b\x15`\xe9\x1b\xb3CVO`\xc9\xdc\xaa<>\xa2\x96:zu\xfa7\xb1[\xf3\xc5o>|\x80\xac\xc7\xb0\x11$\xac\xd9n\xa2\xf7Cf\x92\xda_\x0fqj\xa1P\xb7Zz\xe6\x0e\xd4\x08\xb7\xa7Ha\xb31\xf4`\xdf\xa9\xf8\xc4\x8c\xd3\xee\xfc\x98\x0f\xdc7\xcd\xe9\x1e `9\x98\xcf\xc9\xac\x08\xcf\x89\xf8\xd2\x88E\xd0\xfb\xaa}\x92{\xd5\x1d\xb2k\x94|\x92MgW{\x82\x06\x1e5\xb3\x04\x87\xc7\x14\xf4\xf2\xf0g\x0d\n\xe4c\xceo*\x14\x91\xd5|\xc2\x13L\x0d\xd8\xae\xbe\x93\xc8?%\x91\xb1\x9bE\xb1\x8c\xbeA%\xf3\x8d;aa\xd1\x8c\xbd\xd4\xea\x03\x04\xf0&y\xad\xeb0fT 3\xb7k\xda\xa2\x98\x00\xa6o\xe1\x13&p\xeb3\xa0\xe6g[\x8693:C\\!W\xd7\x03\xa7\xdb\xa8\xa7\xb3G\xf6\x8a\x841N\x8e\x905\xf5\x00\x1374\xbe\x0b\x88\xa3\xb4LY\x90`\x83\x8eP\xb7A\xd6S^\x0b\xde\xbd}1\xb1\x0c]7Dg\xa1\x9d\xe1\x8c\xb4\xb5\x17\xdb\xb5d\x8b\xd3\x0c\xd2y5|\xd8\xb4s\xd2Wk\xd89\xf9\xab\xdd\xa9}\xe0\xd5c\x89\x03z\x7f\x0d\xf1\x98\xce\x1a\xda\x06\xd4~\x1bC\xea\xf1\xdb\x95\xc4\xe5\x12\xcd\x11ns\x8e\xe9\xd3\xe2\xe8z\xaf\xf9\xfa\xec\x13\x13\xcfkZ\x8e\xc6\x14V@\x050`\xbf\x06\xa2\x03\xa8\xe2?\x92`B/\xf3\xbd=Hl$\xa6\xfa\xa9\x1c\x86\x1a\xfa\xeb \x9cc\xacH\xb1\x87\x89\xfaq`\xa2\x9fm\x88\x96\xb8}\x93\xe5\xa6\xb5\x05\xb9T\xf1s\xf2\xc3G\xccW\xa2\xcf&\x0e\x86\x83\x83\xb9\x91.\x0c\x9a\x16D\xeb\xf0Q[Ctj\xf4\x88[\xeb\x05\xee\x13\xbb\xce\xf1\xed\xe7&v\x8dtb\xd7H'v\x8dtb\xd7H'v\x8dtb\xd7\x88\x89]\xebQEL\xc0\xaa\x12\xabF\x9f^\xac:\xbb\x8dXU\x12\xac(\xa4\xa7]\xad\xadVy\xdc\x92Z\xdeJy|+\x11\xcf\x9dr?}\xbcM1\xc4)F\x19\xe9\xa3\xa6Q4\xb7\xa5\xeb\xb5\x10\xb2\xa5\x98\x81I\xdbMk\x1f\xa1w\xee1+\xa4p~\xe5\xd8\xed:\x15\xd2\x17\xb0>GI8\x962\x0fE4\xe5a\xf3\xe8\xe3\x9d\xb9\x8b\xdb\x0fYX\x90\xd7qt\xd5\xc0\xbc\xedG\xa7\xabp%\xb0\x1f\x0c\x08\x83\xa1\xb7W\xcc\xc0\x80\x96\xe9\xee\xaa\xd3g\x02\xd9\x85\x1f\x07\x11y\xbd\xea\x88[\xa0;\x14\xd0(\x10\xdf\xfb)O\xe2{\xa1W\x90\xbc\xb0\x0b\x16\xc0^\xb6\x1d\xe0yf`2\xc8\xa6\x00VY\xbe\xf6\xe17m\xaf\xbc\x91vlX\xc1\"9;\x8b\xc8\xf3\xfc \x08\x8b\xaf\x93K0$\x99\x91\x1f\x19\xbf\xb2\xb1\x0f[y\xe9\xdb~\xb9W(F5\x815\x8c'\xc0\xfe2~\xa7\xb6\xc0\x84\x1e\x98\xc7\xa46\x9d\x08W\xf2#\x8fE\xe1|!\x9e\x0e\x82\xd6W\xe5\xa7A\xa3p\xa4\xc3\xea\x14t'w{f\x1bV\xb2\xa9\x80\x15\xf8o\xfa\x08\x05u\xe3\x16\xaa/\xf1\xc1*S\x1d\xf6[\xdd\x02\x02V\xb1\x82\x001\x85\x16\x9e\xe0\xb6\x04\xf5\xdf_~\xa9\x9e\xaa-Ur\\X\x93\x1a\xab\\N\x18\x11\xd8\xf8\xb3\xd2\xeb\x0f@\x0b2d\xae\x8e\xf1o\xbc\xd4\xcf\xc2\xe0]\x1a\xf8\x85.\x08\xc2M\xd7X\xa2\x11\xf8*\xcbo\xb4\xeb\xac\xda\xa5;\x9a\xb2V\x10\x05+\x1e\x86a\xeaxXA%\x0f\x15ie\x88\xb6\"?\x99P\x9f\x0f\x101A\xa5\x9f\x1fx?\x86\x98O\xce\xfa\xba,\n\xb3c#p\xba+\xb3\xad#rY<\xc9\x88\xd2\x15M~JV}\x11\x9e-\xa2\xf0lQ0\xb0\x9a\xf4T\xe1\xee\xab\x97\x9ef\\zz\x13W\xe0\x81\xd2\xd3\x94U\xcc\x0c\xa3@\xf2\xad\x8f\"\x1f\xaa\xf0\xd5SK\x91M\xcer!9\xee\xd9'\xc7\x85s\x13\xa3a-vk\xab\xe7*o^`\x19XS\xbfo\x99fC\xe6%b\x11\xa8\x82R\xf4\xcf\xe9\xc6c\xab|\x13\xf8\x94\xdfqH\x9bX\xb8Rz\xfe\xb4\x15\x01\x15,\x17\xce\xf1_\n\xa2\x06 \x83y8\xbd|\x1e\xacd\x17\x0b\x9ck 3\x12\xe0\xed&\"b\xf6~\xc5\x08\xa2\xfa\xe0\xf5\x7f\xd1q\xae\xe8\x91\xc7\x00\xdb\xbb\xbb\xdc\xbc7~\x9e_$Y\xb0\xf2\xe6\xfd\x11\x9fO\xb1w7\xdb\x0d\xbf,\x12z\xddG\xa4\xa0\xbb\x12\x93\x8b\x8d\x94\xcfu\xc0\xd7\xb1\x08\"8\xf8\x0b\x0ea+|q\xf3\xdd_\xe8\xfdkz\xc2z\x88\xa7\x07\xdd\xe7C\xf6\x85>\x84^\x9e\x83,\xe4\xa1\nf\xda[\xd5\xe0\"\xc8\x8a\x0dF\xf4\xda\x12\x11\xb6\xe4\x94\xf8\x19\xc9\xf8\xbdj\x82\xf7\xdf\xe9\xc6\xc3\xe1\xdd\xea\xca\xbb\xf1u\x87\xd7B\xf0\xd9]u7\xba\xe6\xee\xf6\x8ac\x16\x89\x16.\xcf\xe7\x86\"\x87_m\xab\"\x9c\xbb@6w\x81h\x86#\x99\x01\x08\xc6\xe8\x7fl\xda\xa9a\x08\x81,\xfb\xeb\xd4\x11\xab\x12\x0c\xf6\xfe\xed\xd1\xd1\x1b\xccLK\xe2\x82\xcbR'P\xc6y\x99\xa6IV\x90\x80IR\x08\xa5\x97\xac\xffh\xc1:\xa4\xb0N\x7f\xddN\xfc[\x0f\xaf\x16\x017W8\xed\xb3e\x919\xf6.{\xd1\x002\xb9)c4r\xc6\xab7-\x98\xf4\x1b\xcf\xb4\xab\xccLH_+D\x0b\xb5\x1e\xd5$3c33\xf1e\x95\x82\x92\xaf\x1d\xcf\xe9\xc3\xc4e\xfd\x02$w\xb3\x00\x9d\x99\xa8\xb2\x92\x1b\xb3\xbe\xd1;'O}J\xe3\xd6\xab\xa7\x96\x1e*s\x9d\xd1\x01\x9d\x99\x00\xca\xb4\x9cd\xc8r2Q\xbby9\xd9\xc5=h9\xd9\xeau\x86l\x17\xd5\xec\x15\x06\xb7\xf54\xe5\x15\x87\x9e\x94\xbf\xe2\x11\xa4E\xefT3\x96g\xbe\x17r\xe2\x95\xa7*\x0f\xdbp\xdbK\xd0\x90\xd5\xd0\xa0\x1fL\x15\xe9G\x0d0tM\xb4k\xa9r\xbc\xfa\xf4\x07q\x05LT-\xa7j\xe4\x03\x82\xc8\x19h;\xe5)T\xc7\xa9Q\x07\x8d\xcb\xebxn\xd2\xd5\xe17\x12\x08B\x87\xa0\xba\xbd\xfa\xf2ws\xf6MZY~\xfbp\x03\x85\x82\xde\xaaYGW\xa7\x06 \x96\xf7\x95R>k\xf1\x80$\xa1\xe7\xbc\x8d+u\xe5;pKo\xea\xa2\x11[p\xb8;t\xdb\xa1\xba\x9eT6(\xc2\x9b\xd6\xa3Z4\xa4*U\xef\xfe\x8d\xe2Yw\xe5J\xffhB\x83\xed-\xbd\xd4`\xab\xc3\xd3\x87UQ\xc7\xad\xd9\xaf\x8a\x1e\xe8d\x07\xdb[\x0fu\xd2\x83\xedme\x8ckV\xf4yX\xf2\xc9\xfb\xd9lHX\x8dHym\x9aSyR\x16\x8b\xe7\x05YJ\xb9\xc7\x9b\x15\xea\xec\x0c\x93ZR\xd0\xacR\xa7\xa26\xa6<%3\x1e\xb6\xd0\x9ba?\x98\x90\xeb\xeb\xab\xe7\x01\x89\x8b\xb0\xc0\xa06b\x08\x7f&W\xa8*\xc2\xbe;\x8db`mQ\xf5i\x12\xe7\xe5\x92\xe4?0\x01\xd1JB\xfb\xdea\x17\x8aa\x8b\x0eQX\xe0\xd8Ek\xd0\x9a\xe12_\xcf#\xfft\xd0\x00\x05\n\x97\xd2\xf2\xb1\xbc\x0f\xb0\x8f\xd1\xe0z-%\xea\x0f\xbf\x0f\xf3\x10\x85'k\x9bj*\x8d>\x14FN\xfd\xd9\xfb\xba\xb2:\x1c\x14\xa2QK\xd4^uP\xdd^\x0cCR\xcd\xc00(FO\xab\xd7\xde\xec\xc2\xa5\x98\xbbzT\xca5U\xf6\xa8A\x1f\xf0\xb9j9\xf4\xbb04z\x04\xd3n%\xf1Qv\x95\x94\x05:\x07\xeb+'\xbc2\xf3g\xee\xa9\x1cr\xbd\x99X{}M\x96\xe5\xd2\x8f\xa2\xe4\xe2(\xbbz^\xbc.\x0d\x96P,\x87e\xc1\xeb\x1d\xc4\xfei\xa4\"\xd5\xc4\x83\xf1\x1f\xbc\xb9A\x0b\x12\xad\x10\x0e#\xa8\xebb\x1ag}\xcd\x05\xd6\x1c\x18L\xf6\xbc\xaa\xdc\x1b\x1fv\xc9\xb6`H(\xd9\xb3\xaa\xea\x80!\\UZ\xce\x97\xa8\xc5\xd4\xd7<\xad\x06\xfb\xc6\xa8\x13=a\xdd\x0b\xad\x8e\xbe\xe2\x05\x86e\xaeQf\x8f\xc3\xd8\x01\xab. \xa5?\xd2\xc8%\xfb\x80\x07\x85;BZZ_\xfb\x90\xd5~Z\xa1\xca\x1e\x0f\xb0\xa7\xac\xfe\xdb\xdaM\xbc\xef\x8b\xf7\xb0\x07%\xa5m\x0c>\x7fO(Q\xe5\x859e\xbe\xf4\xb5^\xc3\x1e\x9c0\x16ArS7\xcd\xee\x0d\xec\xc1\xa9\x97G\xe1\x8cP\x9c\xb51rx\x82\xef\xc6\xf7F\xe5\xdf\x8dS\xad\x1a\xb4oZ\xcd\xcd\xc7\xe8\xacO\x05w'}\x0eP\xf5\xdd\xb8\x9f\xd5\x838T>~\x155\xd3\xcc\x1c\xac\xfdX# \x02\xc5l\xc3\x82,\xc1\x82u\x9e}\x8b\xd9\x93v\xae^\n\xf7\x96\x8f\xaa\x1b]2S\xc3\xca\xac\xa0\x13\x1c\xa6\x04\xd5\xf6\xc4#2W>F\xf5ZQv\x86\x1f\xba\x9a\x9er\x0c\xd9x?\xd1~J\x83\xf9h\xdb\xd9\"\xb9\xfe17\xb3F\xedR\xcce\x17\xcd\x9bu-\x1c\x98\x06J\x18\x0d\xa2\x14\x8b\x88\xa7A3\x193=6H1]r 9K\xb3\xf1\xb4\xdd\x02*\xe5\xf5\xaf\x1b\x1e\x10r=\xf4fI\x19\x17\xf6\xad\xceD\x0b\x1c#2\xa0cmg\"7\xcf\xb0\xee$\xc4\xb8zO\x14\xe7W\xa0\xa6\xaf\x96\x0d\xa8\xb3\x18<\xe2Y\x12\xc1,\x89N\xd8\x85\x03\x8d\xdd\x8aN\xd0IK7\x13\xeb\x15\xbap}\x8aq\xc8nO\xda\xe1<\x93}\xa3\x1c\xe3\xb8\x1a\x99\x94\x06\x99P\x82\x8c:%\x9f \xee7\x9fV]\xbd\xf4S/\xcc_\xfa)\xf3\x17R\xd8\x1f\xd2\xe7\xda\x0e\xa5\x8e\x07&o\xd2\xcd\xe7\xa2\xcf\x8fh\x1e\x1bc\x95@G\xcaj\x88ZB\x1fA\xc1O\xe0\x94\xd1\x80}\xd9\x84j\xb6g\x02\x06\xfe\x80>\x99\x7f\x81W\xe6\x04z\xe2T\xa4\xac\xd6\xa2F]?\x84\xc8\x82\xf8\xb5|\xc9\xbe\xc2\xf4%\xc6v\x98\xdb\x94\xec\x94h\xae\xdf\xcc\x04\xd4\xe7\xa3#\x7f!\xa4H\xf2\x97-QV\xff\xbaK\xb2t\x03\x07%jsNo\x02\xe7}\x8b)\xb8\xb7 \xf4\x04\xd7\xaeBEN\xe0\xbd\xb6\xa2.^h#;\x1c\x06\xd8\xbb\x0b,\x7f\x13\xe31m\xc7i}\xdd\xbfJ m\x90o0\x01\xcbj\xdc\x9bm\xb2\xe6\x8e\xee\xad\x8a\"\xab\xef.\xb8\xcbY\x1e\x1a\x07\":\x9f\xf0\xb0\xe2\x98Z\xb2K\xb8\x1a\x0e\x8a\x8c!\x14,c\x1f\xc1y]-\xf5\x13\xdb\xa1\xa4\xe2\xeb:t\xab\x9e9\xb8\x93\x95\xff\x87d/oJ\x0f\xd7\xe0}\x82w=\xa3\xda_\xd7r\x01\x8c7\x80; \xfd\xa9\xbd\x81\xb9$\x03#%\x1a \x83\xa6\x87\xb1\xae\xda\xa5iN\\\xe6y&\xe2\xfb>\xade4\xdc\xff\xe8\xccmk\x8a\xafL + y\xf2 \xf05\x10\xe9\x00\x1c\xef=\xb9\xc2\x1b\xdfH\xa8\xf3\x8b\xa1_\xd8/\x9e\xa5\x97\x93\xe2mg\x06\x03r\x1c\x8bh\xf8fd\x0dm\xdcn\xacmr\x0f\x1e\xc6\xfeI\xd1<\xf9\xd2m\xa0\x06Zw\xcaM@r\x93\x83t\x17\xb8\xf1\xa9\xd1,\xb7Blo\xf4+\xd2\x08\xfc\xf8zP\xbd\xef[\xe0\\\xbd3\x01s\x9d\xf8\xa1/\xf9\xaf|i\xaf\x06\xc1\x03\xdc\xdc\xb5\xa6T\xedG\xa85W\x9be?\x84\x03W0\xcck\xea\xdb\x8e)\x0f\x19C\xe3\n3D\x9d\x12\x0f'\xb5\xe5sY\x0dr\xc0\xa9\x84\xd5h)\xf1\xf0\xc3\x9c\xd0^\x9f\xc7L5\xd4\xfba_\xa4\x90\xc1\x88g\x95 ~Fh\xa7F\x97\xab_\x03Z|t\x03\x8bo\x95\xa5\xf7\xb9\xe8M\x1dD\xb6%\xa9\xe9\xcb\xb5\xd4\x12\x01\xf5Uoi\xb8\xba\xda\xcd\x86\xbe\xac\xab\x92\x95\x94\xdb\x13\x98\xd6!SZ\xf1h\xe9\xaa\x06\x06\x1b\xaf\xf3\xcf\xd0\xa8\xc6e\xa6\x0b\x1d\x03\x16\xcc)\x95\xc1\x1e$H\xecdM\xd3\x91\xccl:\xd2\xf4\x93k\x81\xac_[\xe8\x89W\xab\x98)\x0e4\x94SZ\x83\x85\x83\x84\x9a\xbaZ\\?\xadod\xe9G\xea$\xedyq\x15\x11\x9de)%\xfb\xcf\xb2\xa4\x8c\x83\xa7I\x84\x19\xdc\xff\x7f\x0f\x1e\x9e\xce7\xb7\xbb\xf7t\xeb\xe4\x19\xc6\x92fj\x19\x9dL\"\x9c3\x1bx\xab\xdd\xa8E\x17\xdf\x92O\xfegj\x0d\xd6\x03E\xd9\x10(\xd2\xd8K5\x0dj?\xcf\xe9\x07\xdax\x16\x81\xce\x18.\xd0\x19\xc3\x05:c\xb8@g\x0c\x17\xacf\x0c\x17\xa8\x8d\xe1\x82\xda\x18\xae\xebd\x93r\x0f\x81-\xa5\xb1[\xf0\xe9\x8d\xdd\xcc)\xfe$c7\x15\xed'\x19\xbd(L\xde:\x9e\xc2\x83M\xdbn\x95Q\xf8\xf31\xbf\xe93\xae)jO\xe0\x1es\x11JPO-t\xde\xd98M.\xadc\x03}O!L\xeb%\xcc\xd7i\x8d\xf9M\x88\xe0\xc2\"\xeeX\x9a\x91\x99_\x08i\x80\x1dsI\x8e\\\xc0.\xd7>U\xda0\x86\x8e\xcd\xa7n}\xe3\xc2\xcf\xe20>3\x89\xffE\xdd\x89uW|e\xec\xfd\x94\x84\xb1m\x81^\xe8\x91\xe8{J\xbd\x97t\x16\x1d\xfa\xf3\x97kW\x86\x01\xc3Pd\xb9\xb9\xc9\xb6\x88\xa4\x94#5d\x0b#\x97\xa9\x1f\x07\xcfX\xbd\xbaoOzO\xcf\x9b:\x01\xd4\xcd\x1c!\xfb\x1c \x19_\xa6\xbf\xb3\x16\x9f\xe75\xf4\xef\x0e\x1a\x9f\xad\x83\x86\xc15C\xaf\xa8\x890\x91c\x97\x89\x02~\x93\x87\xde<\xc9\x96\xbe\xa2_\xee\x92\xc1\x03\x9a\xab\xfd1\x84K\xd7\xda\xde\x1eD\x18\xd9\xfb4\x8c\xfd\xec\x8a\xbd\xc1\xecB\xd6\xa9\x9f\x93\xddm\xf1F\xef\xa9\xc1@_\xef\xd2\xa0\xf4\xe4\xe0\x01\x12\xe7\xa12\xdd\x90\x84\xeaJ\x1eS\n\xf6\xc1\n\xe3s?\n\x03\x8b\xc9\xe0\xbbm\x86E\xd4\xfc\xa2\xd4\xd4\\E$\x9a\xdbU\xcaK:\xda|\xba\xa9\x08\xd2\xaf\x90\x07\x04a\xce\xd9\xdc\xc2\x0b\xf3g\xfc\xaf\xe6a\xf8\xcch{\xb7\xca\xbd\xdfL\xef\x0duR~\xe1\xe8\x9e+\xde\xd5u3\x92\xa7I\x9c\x13I\xea\x01R\xa6\\\xcd\xebJ\xde\xc3\xdbnEN\xd2\xb9\xcb\xc6\xf6}\x05\xd6\xd3\"\xb7P\x8b\xdc\x8c\x84R\x15\xf0\xacP\x06<\x8b\xab\x80g\x94\x88\xccX\xc0\xb3\x0c\xbe\x82\xe2\x11d\xeb\xeb\x0e\xc4\xd3\xac\x19\xf0,\xd3\x07<\xab\x15\xf0&\x92\xadJzwx\x95\x17di;M\xdb\\\xfc\xeb\xbb\x9cN\xc7HW1Z\x96\xd9e:v\xc6r\xbf2j\x96\xad8?\xde\x0d^L<\xad\xdb\xf6\x0f\xdd_\x8a\x8d\x0c\xcd\xd1J\x854\xb6\x80}\xc0\xd4\x18\xcd\x06\xacc`\x81t\x9b/\x95x\x0e)\xd5\xe7\xb1\x1d\xf3\xec\x05-XW\xc0]kl\n\x03\x88V\xd3Sag\xfa\xcc/|\x8b}\xe22\x85\x03\xcbZr\x8c}\xb78YWw\x18\xee\xaa\xffn\xe3\xa6\x81\xa8N\xeb\xdd\x8d\xa4\xd3\xba~(j\x84\xd2?\x14q\x1eT\xae\xcc\x98\xb8\xa1\xbe\xf0\x84\x0f\xb3\xd6\xc9:\x91P\x9b\x9are~\x00Ul*\xc59\xc6\x80\xa2\xfb0\x0d\x11|;s\xc2\x98\xcf.\xc4\x02\x94\xf5\x15\x9a\xe7\x0bH\x94\x13\x15S\x8b\xbc\x96\xa6\x9d\xa2\xdb\x8ei\x1b\xb3a{\x93\x0f?\xc8\x9f\xc9\xa6\xc4C6\xc5\xbc#\x03\xb7#6n\xc7\n{\x11W\xaa\xb4\xcc{\x9dq\x17\xf5\xd4\xb1\x1d\xe5\xd6t.\xed!\xfb\xe3Br\xbb\x9d {w\xc6\xef\xdb\x99\x84\xc5\xddeq>\xf7k\x84\xe2\x9b6\x8a%#\x17\xa8G_M\xb5e\x08Mn\x9d\x82\xa8\xa7\x89G\x9de\xa3\xb4}\xa2\xbcrl\xdah\xac\xd9\xb6\x81\xb1\xbai\xeb\xa5\x97\x914\xf2g\xc4\x8e\xc9\x05\xbc%g\x07\x97\xa9m\xfdb\xc1:`D\xc6k\xcb\x05\xeb\xccr:*9\n\x11\xa5\x04\x1f\xf8\xf3\xf7\xa5+\x95\xca\x8e\xd2\x8e\xedqG\n\x1a\xf2\x92Q'4\x0fSX\x8c\xb7v\x95T]\xf9;\xb2\xac\x14\xfb\xfer\xed\xb6\xa5\x82\x99\x0b\xbe\xf7\xee\xcd\xb3'G\x07'\x87\x07/\x0e\x9e\x1e\x1d<;9}\xfd\xea\xe8\xe0\xd5\xd1\xc9\xd1\xdf\xde\xfc\xfbZ\xaa\x88\xe0\xd5\x16\xf5\xf0\xcd\xebW\x87\x07\xbf\xcf\xaa\xeadR\xaa\x98\xac=\xeb\x91\xb8\x10\xeaH\xf1U\x16\x84a\xaf\x93\xef\x9f\xbc}\xfe\xe4\xeb\x17\x07w{du$\xc4 \x0c\x16{\xef\x89\xc2\xa8\xc5\x17K\xad\x069 \xef)\xef\xfe\xcc\x85\xd0H\x11b\x05\xe3V\x94.\xf8\xcd\xf5\xcdnq%\xd72\x8fQ[\xbd\x97\xf0\xd7;\x0f\xa4\xfb6\xa1\xcb\x82y\xf4\x92\xec\xc0\x9f-l\xbdh\x01\xe9>\xef^\x18\x07\xe4\xd2\xfb)gr?-\xd5Gw4\xb1U1\"\x88G.\xd3$+\xf2)#\x80R?\x9f\xf9\xd1S?'\xdf\x84\x11\xa1\xdb\xe8\xd8\x85s\x8c\x1b#.\xd1}\xe9w\xdbAH\xba~\x07-\\loo\xefR\xb2H\x8c\x03\xd7eg\xb43\xe8k\xc3\xb2\x0b\x1b\x8d\xad\xb1L\xd0\xd4\x11\xbd\xecU\x0c5*Z#\x93\xa6W P\xdfd\xc92\xcc\x91r\x89\xed\xed\x9d\xfb\x8e\x0b\x87H\x91\xd7\xa65^^\xf8Y\x91\xff\x102\x0dIlo?\xd8\x1d4\xc3\xd8~8FM\xef\xc3\x07\x9dU\xda\xde\x19\xd6F\x1fpno?TB\xe7\xf6\x8e\xca\xc0%\xb6\xef\xb7_3b\xef\xfeHZ\xe9\xe6H\xc7[\xf7\x1d\x1b\x05n.X\xf8\xaf\xd5\x83\x87P\xbbt\x82\xd2;\x9b\x08'\xb3\x13\xda\xff\xa6\xf8\xe3=ES\xf5~\x18\x92x4T\xa6'\n!|\x15\xac\xe0Da\xd7\x18W\x85\xe1\xfa\xba\x12{\xac\x11\xdcTxL\x19\x94J\x9cm\xd7s\x10\xa2\xb9\xc4\x1e\xa1MzB\x0f\x9bE\x0f;\x8b\xd3\xc6\x8d\x0cYZ\xd9\xfa\x1d\x992\x99C\xec\xe2O\x89;\xbav\xab\xcah]\xf3D\x08*Q\xd7\xc0W:\xb3Y\x17\x0e\xfe\xac\xabg\xb6E\xe2\"\x0b\x890\x9co\xc3\x8f\xbc~\xf2F\xca\x0b\xac\x8e\xd0\xd8\xfb\xa5j\xaf\xf9*\xaaP\x17\x8b\xb9\xda\xdd\x93 \x89)\xdb\xb2f\xa6\xfdoy.F;\xeas\xf1\xb0\x1d\x95\x91\x1d\x8b\x87m\xc1\xb6\x8f\x9c\xc6#\xe9,\xeflb4\xf3\xd8\x1e=tl+,H\xe6\x17\x98CV\x0f\xbb|q(,\xd5\xb3k\xa1\x82>y\x1b\xa9\x11\x11\xc6\xef\xf6U:\x9e\x98\\\x16\x142Gn;u\x00\xed.\xc4\xb6)+\x0b\xcf\xaba\xaf\xb6\xdc\x12\xc2Q\xdf\x86[\xbb\xeau\xdd\xd5\xe2\x95\xedm\x07\xf6\x95\x9coHr\xe81@N\xecv\xa2\xa1Jk\x10\xbb\xb8y!\xaa\x07\x90\xda\xadT\x079S\x16\x94\xf0\x18\xf2G\x0ed\xde\xdc&\\\x182\xcd\xd7\xd7\x8f](\xa6q[\x08!\xa8\x8c\x9b.\xd8\xfd\x91\x9a|\x18\xa9!q{g[\xb3duw\x1a8\xab)\x0e\x96wFGQ\x94l%\xf4q-#$9\x84\xcaES U\xa3\x14\x1c#\x05iBI\x1cv\xa9\xc2\xda\x9e\xde\xb5\x117\xed\x11D\xf0\x18f\x8f\xf46\xc0\xb45\x9bne>\x9d\xad\xaf\x1f;\xb4\xcd\xd2\xa9\xcdU:\x1f2\xe1S\x7f\x970[_\xef\xe9\x16\xaf\x87\x19\x841\xe4Ho\xe4\xd3\xd91\x0b+\xea\xd4r\x0f\xac\xf2\xe1\x03j\xa2\xaak\xe5\xcb/a\xa3\x19\xbbhE\x1c'a\xb3]\xd5\xa9{\xe9\x17\x0bo\xe9_v\xc1\x88\x95\x84q\x1f \xe9\x11\xba\xcd\xb0\x0dq\x1c\xf8\n6a\x9f\x9e8X\xa7C\xdc\xa4\x97 C)7F\"\xea\xf9P\xac\xbds'\xc0\xaf\x83\xfc\x10\x83\xb8SHbD\x9eM k\x0d|\xb3#\xa2\xf3k\x8dPp\xc8\x0e\x88B+\xc1\xc6\x94\xe3\xda}\xf8\x009%/\"\x14\x87\xf1X\xb4\x9c\x9a\x9d\x80\x8dr8o\xb6\xf0\xb3\xa7I@\x9e\x14v\x8ek\xbe\xb33~\xb8K\xbf\x0d\xe11\xec\xecn\x8d\x1e\xb2\x86\xd6a\x84\xe0\x87\xb6\x04\xb6\xdf\xf9\x98V`\x0d\xecn\x8d\xb1s\x9f6p\x7fk{\x8b\xf7\xcf\xeacGt'a\xc2\xdf2/\xbd\xdc\xc5N\xc6\xb4\xcc\x87\x0d\xde\xcc:\x1d\xe7\x06\x1f\xd4W_\xc1h\xd3\x81u\xd8\xdd\xd9\xd9\xda\xbd\x1b\x08\xef\xdc\x1f\x1c vu\xd8\x90\x02\x8b\x83\x12e~\xa5\x0d\x8a*\xdc\xbd7\x90\x19\x13\x1f\xb6\xc4\xf0\xc5\"K.\x802\xef\x98%\x1dO\x80\x05a\x0eqR\x00R\x00\xa7\x11Y\xd3X~dv\xc1\xa2\xf0\x11g\xc5sB/\x81\x07\xc88\x8c\xb7\xb7\xf1\xdf\xed\xdd\x87\xec\xdf\xfb[\xec\xdf\x07\xfc\xfd\x83\x9d\x0eg\xb1\xbb\xe9\x08\xaefHg\xbd\x84\xd4\xaejgd\xd2(\x99\xc6\xf6\xe8\xbec[E\xc2N\xd5\x91\x7ff!\xdbi\xfdlQVn\x9d\x82\xfc\xda\x1eX\xd3\x04o{\xf8\xf9\xd8b\x0c\xd7\xfd-\xc7\xe6\x14@\xed\xc9\x00UCV?mU\xb5\x89\xe9j\x90l\xa7\x90i\x1dK\x1ah\x0c\xa94d-\xe4\x85\\\xa3\x1c\xfe\xa6\xc32\xac\xd8\xa3\xcdQ\xbf\x0d\xf5}:I\xb5(\x9f\xae\xe3\x03\x87Y\x1e:.X\xbe\xd2\xfe\x10\x83ik{i\xf7\xd6)l\x99\x088\x9e_\xaf\xc1\xa0\xf9KDK?\x11\xa2\xb8;0)\x0d\xbb4\xc4\xd5\xf8\xa8s\x0c\xd5z0Le#\x9d\xc3*\x02\xb6\xcdTG\x02$\xd8\x86d6\x13U\x89\xf3U\xf5\xa7\xd2\xb0\xe9\x1bE\x1e\xe5\xf5|\xf56\xd7>\xcep\xdb\xf8\xc6z\xea\xc7\xff\xb1\x80Y\x12\x9f\x93\xac\x00\x0e\xe9E\x02i\x16.\xc3\"<'\x8c\xcdZ\x95\x9a\xef;\xf3\xdb\xbbm\xc91\xc3\xc6\xe3\xed-%\xcd:RJ\x15Z\xec\xd3\x03\xc1>\xdd\xff\xef\x99}\xd2\xb0\xa5\xdb\xbb\xea\x95\x1dw\xc48>\xc7\xca\x94 }~p\xf2\xe6\xed\xeb\xa3\xd7\xed\x80\x15e\x9b\xdfo\x16\xb7\xc5\x01\x9d\xf58g\xb9+\x0b\xde\x15E\\\xe1<3D\xc6@+\x0c-5\x84$w\xe1\xa1S\x90\x17\x84y\x1a\xf9W\xf4v\x88\x93\x18\xf3E\xdb\xe3\x9d\x11\x9a\xf5\x938x\xba\x08\xa3\x00Y\xb7\xc2\xcb3\xcacX?\xf9\xe7>\xf3\xe9\x9dXU\x16J\xee\xfb\xf7C\x18\x07\xc9\x85\x17$3\x14\xa18^\x92\x92\xd8F\x18\xb9\xc8\xc2\x82\xd8\xd6W\xec\xd3\xc7\xa2\x8a\xf7\xcd\x1eC\xd1_\xfdx\x8f\x17\xa1j\xd7\x9bEI\x8e\xe9\x0ds<\xc1\xdf<\x82lc\xe3\x91\x03\x01\x89HA \xaf\x01i\x1aN\xb3c\xbdMYn\xb7`H\x8dI\xf9E\xc1,8)\x9dfD\xad\x889\x95tF\\F\x11J\x90)\x15g\x97-x'\x0ecpcrA\xf9\xbef1s\xff\x8aYZ^\x82\xa6g\x98\xd5\xc2qei\xab\x90p%v|+\x9a\x7f\xa46\x1e\xec\x9c\x08\x0e\xf9\xdb\x0f\xf4\x94\x1f\xbd\x98\xff{\x90\x1d\x8cF\x0f\xd4d\xf1\xb8\x8d\xa0\xb9\xf0`w\xd7\xb1\xd7\xda\x02\x075\xca\xb8\xc1\xfd\xce\x97\xa8\xe4\x84t\x17\x17\xe0\"u_Sfiz\xacX\xf3\x98\xf2\xd5\xa5\xc3\xa4\x04>\x8a\xf31%<^\x9b\x91\x88,\xa4\xf8\xf0\x11\x14BX\xcb\xf7\x03\xbf\xa3\xa8\x01w\x83\xb9\xa8\xfc\xa7\xd0\x8e\xb0\xb5\x0f\x1f\xea\xd6\xd4[\x14\xddt\x8b\x1e>\xd4\xac$\x83N\xdb\xfa\xd9r\xd0\xd5\x82\xd2\x81\xcf\xf3\x83\xb8\\2\xbe\xc1\x96`\x18L\xe6\xd1\x82\xd2=\xac\x93\x83\xd0s\x8d\xe6;y\x1a\x85\x85ma\x8e}\xde!\xb9\xf9 \xed@\x95\xd0ti.\xa7m\xdd\xdc{'\xd3\xe0\xd6\xff]T\xf5\xdf\x92\xa8J\x83\xb2\xb6w\xdb\xef\xc3\x01\x94\x8c__\x94\xd5\xc5e\xbcN\xcfH\xf1FT|=o^\xab\x1aX$\x02\x9d\x01fp\x0e\xf1dMQ\x1b\xad\xa2\xf0)\xa9\x90\xc4y\x91\x95\xb3\"\xc9\xd0\xe4 \xc28/\xfcx\xd6-\xddo\xfe-\xdd\xbe\x93\xe6g\x1c\x0f\xec\x83\xdf6\x00_q\xfdw\xb6nz&9\xfe\xc8V\x17XT\xf7'g\x1f(;P\xb1\x0c\x0f( \xcd\x98\xca-\xc7\x15\xde\xf0[\xfc\x82E\xc6\x80'\x8f\xb5G\x9bc\xc7\xe5>\xb5\x94Z\xc0\x83\x1b\xb5\xb8\x05\xf6\xaa!kp\xd1s6\x17\xba\xb3\xa0\x13m\xe1\xe9\xe1\xe1\xdb2\"/\xc2\\\x11\xec\xe0\xe9\xe1\xe1!%M\x9f\x91Y\xe4\xb3x\xd3\xdd\x80 O\x0f\x0f\xd1\x14\x817\xd1.\x8dB\x12\x17o\xc9\xacP\x97?{\xfd\xd2X\xc8\xe6\xa2->J\xde\x93X=\xf8g~\xe1\x1fe~\x9c\xcfI\xf6\xbc Ku\x1b\xdf\x84\x91f\xe4\xdf\x1e\xbd|\xf1$\x8a\x9e&Q\xc4\"P\xa9\xab\xf4\x95\x7f\x93dK\xee\x85\xa4\xae\xc0\x9c%\xb4U^\x92 \xf4\xd53|\x19. e\x89qs\xbb_\xbe\xf2\x97$x\x95\x04\xe4\xa5\x9f*J\x93@\xb3\xebo\xfc0\x16\xe1O\xd4K\xf3&*\xcfB\xc5|\xd9{\xcdp\x0e\xbf\xff\xd3\x0b\xbc\x8a\xd4m\x1e~\xff\xa7W\xe5\xf2\x94d\xda\xe27\x98%X\x03\x0b\xb4< c\xcd\x80\x0f\xbf\xff\x93 \x90\x0e\xbf\xff\x13\x83\x94$\xd3\x80\xc9!f\\\xfb\xba\x9c\xcf\xb5\x03\xa4\x07\xe5pAH\xa1^\xd5#rY\x1ce\xfe\xec\xfdS\xddQ\xa9jh\x8a\x93rV\xad]Ur\xed\xa2+zb\x07\x945a\x94\xf89|\x05\x0b\xc1s\xc2\xf9\xfa\xba\x8aZ]\xba\x18\xc9~1=W\x18\xbcQ&4\x98\x9e)JN\x91\xacW\x95\x9c\xc0\x1e\x9cR\xa4\x7f\xaa\xba\x90\x80_\xc5'H~\x9e\xd0\xfb\xf7\xc3\x07(\xed\x13\x17f.\xa4\x8e\x0b'\xd3y\xfdn\xee\xc2\x19E~\xd33\xca\x80\xa5.\xa8\xe2\xd2 r]\xd2[=s\xe0d\xba\xc4\xcfC\xfa\xf9\xd2\x85l\xba<\xae\xc5\x9b0\x14a\xf7\n\x804J\xcb\xed\xfbj\xbe\x03\x11w\xe3\xbd_Q\x94:&n\xbc\xbd\xfb\xefv%\xff8v%z\x82\xef\xbec[e\x9c\xcf\x92\x14\xbdU\xda$\\\"\xfc\xf5T\x07\xa6\x123@2\xcd\x8e\x99R`\xe7\x01\x1a\xaff.\xfc\xa2\x97\xf6u\x98\xfaiv<%\xf4\x18\xc9\xf6\xf0\xca\x99\xe8$\xfeF\xd8\xfb\x0c\xed\\\x84\xb1\xa9/(\xa9\xf1v[\xc2\x92W\xc4V\xe35\xa7\xb0\xc6\xaa\xb8%*\x8d\xcf\x9c5\xdf\x16\xd4\xb0p%\xf7\xb7[\xaf\x03\xdez\x1b\x85,8\ni\xd7?\xe7\xef\xdb\xf6\x10K\xd6\xebN\x1b\xb5\x9c\xf1\xf7[\x8e\x97\x93\xd6\xba_\xb1\xb6\x1elvb\xe1\x9dr`m\x8f\xea\x84\xb7\xd6\x1e\xd5\x05\x7f\xdf\x1e\xd5\x01R\x9a\x95\x8c\xbeYx\x89\x85i\x96\xccH\xde\xf2D?\xc4\"\xae\x98k\x16=\x85=\xb0\xf8Gx\xceg\xf6e\xab\xd7\xf7f\x89\xee\x13\xb4\xb0\xdd\x83So\xde,xM\x0f\xc4\x9aY\xda[dW\x1a\x9eW\xe0\xc8C/#y\x12\x9d\x13\xbb\xbdz\xf2\x83\x1e\x1aM\xf6g\x8f\x1ea\xa1\x1e\xccS2C\xfcr<(\x1b\x96x\x88\xfd\xde\x85\xf7z\xd6\xf7\xba\xcb\xd2\x83d\xc7\xf0\x14\xfdQU|\x1c\xdf\x8b\xb7\xe4'F\xd9\x1e\x9c\x93\xb8p\x98\x0fK\xb1 \xb1\xfd\xde\x919\xb4\xa2\xd3\xcd5\xcc\xfcb\xb6\x00\x9cCK\xf9\xd6\x06\xbf7\xbdsF\x15\xb5V\xa8\xbcf\xaf\xa5\xf4\xbb\xe6d*m\xb5\xcd\xe21\xd0a;8\x85\xe6h[\xe0r\xd4\x87\xed@\xe8\xb9\x88w\xa2\x95\x88\xd02\xc4\xb7\xea\x0d8\xe7\xb6\xcb\xc4;\x99\xa9k\\\xe95\xaa\xf2\xd3\xe0.\x89wr\xcex\xcb\x11`\x8c\x9a\x93\x9c\xb1\x97\x9b\x8c\xb5\xac\x05K}p\xc5\x85\x995\x02M`\x1f\n/y\x0f\x13(\xbc\xb9\x1f\xf6\x84@\x87*A\x14?\x1c\xfd\xd5#^\x9d\x02\\\x7fm\x9649H\x96~\x18\xab\x17P<\xfa\x13,?%\xa5?\x124\x1b\x19\xf3\xb5[PP\xf9 \x89)\xfck\x0fF\x8e+\xe2\xff\x94H\x81\xec\xa1I\xb5\x8d\x81*f\x1e\x89\x0b\x92\xd9\\\xa7P\xda\x19\xf2\xe8\x98\xa1\xd8#\x97aas\x06\x7fm\xd3au\xf6\xd0\x1b\x81\xdbX\xefCd\x1f\xd8\x16?w\x1b\xb3\x85\x1f\xc60\xbb\x9aE\xc4B\n\x08Ma\xde\xd8\x14\x82\xf7!d\xda\xd2\x18\xfdK\"Z\x9cc\xc9\x04\"[\x91\x1dP~\x1a\xe7\xb2wYp\xfck>\x9f\x1f\x9fDd\xf7\x84\xdf\xbc6\xe0#\x88k\xd9t\xf8\xc8\x01\xdf\x8e\xa7\xe1\xfaz[9 ?\xf4\x90\xa0\x90\xdc\xad\x8e\xd5\xc8\x05\xd42\xaf\x89}z\xa9\x1b\x93\"z\xe6\xb5\xe9\xf8\xbf\xec\xc5Egl\xf1s\x03\xfd,\x1eD[(\xc4\xe5f\xfbxB\xb5\x13\xa5[\xfc\xbc\xa3\x80\xa9J\xe7\x14\x08(|\xc0C\xe0\xf0\xa3c\xea\xed\xa7\xde\xdeV\x85_54\xca\x80U-\xfa\xb7l7,\x01S\x05\x87\xa9\xaa\x02\xdf.v\x0b\x9b\x92u\x0e\x00'\x01J\xf4L\x0d>\xfa\xc6\x9dz\xd5\xbbv\xc2T\x8er\xaa\xddu)\xbc\x93\x00\xaf\x10\xfcA1\xbd\xcb\xd6\xa0\xf0N.hA\xe1x'\x94\xa2\xa7d\x85wB/\xc81\xfe\xf2\xc5W\xccG\xfdd\xc6\xed\x0d\xe9Eqd\x17(\xc40\x8e\xfc\xed\xb0\x91\xbb\x15o\xaeV\xf5\xac\xc5\xdeI\xa0\x03\x86\xb8\x9e\x14*\xcd\xf9\x9c4\xd7\xaf\xf9\xda\xa5\x9d\xb1\x1b\xb0:X\xf5\xe5\x073\xb4\xec9\xa5\xa7\x19\x89\x87\x00\xc2\"'\xd1\\\x97?\x8f>\xb8\xceo\xd0\xbcj\x7f(\xf1\x04\x12\xaf\xde\x7f\x17\x9e\\L\xc0\x90l\xb1\xaa\x16h\xd3\xb2\x8aGC\x95\x8bg\x18\xc5\"\x0c(\xe9}\xfc\x16/\x98\x11\xde\xcd\xaf\xf8\xef\xbb$\x03^\xb1\xbe\xb2\xde\xc0\xdb\x86\x9b\xdf\xa1wL\x05\xfe1\x03\xff\x11\x85\xef\xd8\x855\xddx\x87\x8d\x93\x8f\xcf<\x91\x01\xfb\xd7\xb3w\xd7\xda\xf9w\xe7\xdd\"2\xea\x1d\x7f\x8dg\xfd\xd0x`\x17<\x82\xe7\xa1\x0b\xe2PX.X'\x0b\xcbq1\xd4\xa9\x0bY\x9d\xc5\xbau*\xd4\xe0Cl\x04\x13\xd6n\x05)\xe2\xcf\x16r1.\xfa\xabf\xfe\xec\xe6\x97\xd5_\xd7.\xbb\xc4\xf5\x93d\xd2>A\xd9\xb1\xbf\xe4\x9b\x97\xbd\xc9e f h?\xfc\xeb\xbcSy!Wf\x84b= \xa7i\xdeco?\x189\xf6\xa1l[\xdb\x1e\x1f\x89\x07\x84\xfa\x17\xac\xdc\x13{)v\xcd\x9cS\xfc=\xec)\xd9T\xa6\x7f\xc6\xb3A\x19\xacf\xad\x9a3G\xba\x97br\xce\xfd \x19C\xefb\xfe\xe7\xa4\xb5&\xb3*\x07U\xb5\xc6\"Y\xcc\x89\xdf.\xcbi\xd9\x11\x9f\xc7\x1a\x05\x93Xp(\xcd}n\x9e#\x04\x97\xbe(v\x92\xc5\"\x13!\x88q\xeaa\x88kG{\xe5\xd41\xb9\x80\xecQ\x17\xba\x04U\xc8n\\\xfa\x86\xdf(\xa8'}\x8b \xd5GNU\x84Z\xe6=v2\xb0D\x86\xe6SoNwy\x88\xb2\x98\xe0\xcdv\x88\xdb\x89?}JA\x93\x0b\x16\xf4m\x82\n\xf5\xc6$\xe7\xf6\xdc\xfb\x13\xac\xc3\xdc\xfb\x01\xff\xff\x0d\xfc\x11\xd6^\xb7\x01\xf2\x8d \x8a\x0e\x1b\x1f3\x13S[\xc6\x15\xdc\xfe}\xec\xd8\xf2+\xa6v\x90L\xe0Y\xc7\x87\x8d.%|\xd3\x9e\x1b]\x9e\xbeM\x16\x04\xd2\x13\x15f\x02I\xf4\xb4\xe9V\xdc\xbe\xc3\x14\x16j@\xeb\xacS=\\\xbb\xa4+\xbc\xf6\xda1\x8e\x1a\xf7\xbbo\xd8|T\x17v)\x0eG\xb5o\x870\x81>\\\xd7\x19\xda\x9a\xfd\x9a\xc9\xeb\xb7\x1fl\x99\xa2\x85\x1ez\xcc\xea\xd9\xc3\x13d\xbf\x97\xc1\xc24-?\x8a\xfa\xa6$\x93\xaa\xea[\x8fa-\x9d\xf1\x10\x8b\x86`\x14\xdf$\xbc\x8a^d\x13\x0e\xe7T\x05\x1e\x9d\x1a\"4\x03o\xd2\x90$\x1f\xb8~m\xa4\xa7\xb1\xce).\xa7\xd7\xc8p9\xeb9\x0f\xb6\x14\xae\xaf\xf7S\x80\xe8!a\xe8\x1f\x90\x98F\xcc\xcbP =\x9b\xeb\xebn--\xa3\x10\x81(r\xf8\x08\x01;\xa6\xa4E.\x88\xf4iy\xcc0\xdf\xc6\x062\x18\x99\x1d\xf7Q\x85Z\xa6\x198\x98KM)\xeb]\xeb\x8f|\xe8\xa1-Ub\x87\xde\xf9\xd0\x8b%\xf3g\xbdg\xf7\xae\x00]\x0f\xc5\xc9\nP\xbc:luw\xbd>v`\x90\xe6i\x93\x08jw a;\x90\xd9\x89i\x07$\x14\x84?o\xa4\"dB\xaf\xf6\xd4\x91\xc7\xb4\x1b\xb6]\x05\x8a\xed\xb9\xaasmo\x0f\x98\x84\x07\xc2\xb8f\x0dk\xa7\x8f\x18\xd6\xc1\x9a@\x18\xcf\x92,\xa3\xb7u\x18\x9f'34K\xd2\xb9\x9a\xdd\xdc\xbe\xb8\xa3\x02\x14z~\xb5;\xf7\xf6}\x95\x9f\xbc\xc2\x86\xbb\xe4f\x01m\xcdc\xce\x9bi\xdb\x02F,\xb0W\xe3\xdd\xac\xe5C\xc2u\x1c\xa6\xdd\x98\xbb\x90\xaa\x08\xa8\xc0\x85\x85\x0b\xe7\xae\xb0\x07Ia\xbf_2\xd4Y\\\xf1\\\xa30Ze\xff|\xc5|Fq E-p\xeb\xd4;E\x13\x96\x0e\xdc(I\xe6\xb3\x9b\xfa!\xa20\xd5>sT\xf3C\x9dJ\x802|a\x9d\xe0<\x82\x00\x1e\xc3\xe9#8\xd5Y\x9a\xa2\x95\xe9\x92\x07\x8c\xbd\xb2}\x9b2#dzz\xecL7\x8f]XLG\x18+\xf0\xca\xc6wN\xed\xa7\xba\xc4\x9f\xb3\xca\x0cu\xd9<\x8ej\x13X\xa6\xf7\xc1da\xdcq\xea\x11\xaca\x97\xe7^L.\x0b\xdbq\xbc \x89\x89\xc6\x1a\xb7\x1alb\x9f\xbbp\xe5\xc2\x82\x07\x82\x82b\xd8\xd0\xae\x1d\xef\xeb\xb7\x07O\xfeL\xc9ezq\xbd=8z\xf7\xf6\x15\xec\xc1l\xb5C\xb6\xd3o%-\xe07\xe90\x90JFW\xe0:\xd8\x87\xc2\xa6\xf7\x14.\x7f\xcc\x97\xbfh_\\\x15\xafk\x8c,I<\xd6\xacB\xe6\x87\xe0'\xe1\xaf\x90\xa1\xd8\xb0rhs\xdb\xfa\xc6?4\x7f\x0d^\xab\xae!QR\x1b\x99Hf\xa0M@7Y\x98\x0c3\x1f\xe1+*\xcd\x11\xaf\x11;cv3L\x8c\x87\x86W\xd3\xe4\x98\x0b\xf5n&:\x8d\x1c/a\x98\xc3NuY\xa1f\x0b?\xf3g\x05\xc9\x9e\xf9\x85?Q\xba\x94q\xfb\x9c\xde\x85H\xbd\xc0/\xd0j\x8aNe\xde\x03\xdfJ$\\\xf5\xa1\x9a\x85'\xde\xdc.\xd0TOA\xf0a\x82\xb4\x12\xb9\xe0\xaeK\n\xac\x1aX\xa5\x90\xe3M\x88\xa7u\x14nLo\x18\x89\xfc\xa4%U\xed\xde\x7f\x82Y\x9b\xde?\x9ef\xc7m,\x1br\x16\xae\xef\xec'M3y`\x13`,\xd4\xac\xd3q H\x04\xe3\xaaB:\x1d\x1c\xc5\xd3\x12t\xfc\x01\xb8\xf3C#t\\fg\xde\x1bX\x87\xcc{kP1\xcd\xc3\xd8\x8f\xa2\xab\xa1\xd2w\x9f+\x8d\x93*j0\xe5\x88\xc5\x1f\x1a\xd1{\xacSr\xab\x92\xd9\xb4\xd5\xc7\xb1,\xa7\xd4\x1ab\xf3\xcfJ\xcchj;m\xbd\x8a\x89\xcc\xeal\xb4\xfc\xa8\x8c\xcb(\xebF\xa9\x8b\x8f<.\x86`V\x1b\x96^u\xf9\x11\x81\xb7\xebP\"\x02\xf7l\xb7\xc0\xf1\xd0\x00\x88E6\x18\x08\xf1\"\\\x84\xb9\x01\xdcB\xa5}\xad\xd0J\xc7\x1eACwn\x0b0\xa9\x953\x8e\x1d\xa3\xd2\xa4_M=dAc{\xfb\xc1}\xae\xa5\x7f\xc0\xff}\xd8\x8cj\xc7\xc3co?\xe4Q\xed\x1e\x8a\xf7;\xfc_\xfe\xfdC\xfe\xfdC\xf6\xfd\x0e%G\xf0\xdf\x11\xffw\xcc\xff\xdd\xe2\xffn\xf3\x7fw\xf8\xbf\xbb\xfc\xdf\xfb\xfc\xdf\x07\xfc_\xde\xde\x88\xb77\xe2\xed\x8dx{#\xde\xdeh[\x19e\x8f9\xdb\x0eY\x8b^0\x1aw\xc2x\x87U\x90J\xbc\x92\x9f\xf2\x10\x8f]\x94(WJ\x02\x82\xfe\xc1-\xc8CD\x88\xe6\x04k\xcc\xd0}\x84\xf1V\xaa\xa0\x19Ul\x91\x0e\x82\x94\x1b\xed\x83\xd0:o\x9f+\xb4\xdc8\xe9n\n?_$\xed{\x0c\xbeVL\xc0\xa2\xc2\xed\xc1z\x9d\xc8\xcf\xc78; \xc5'\xa3\xd1h{4\x1a9\"v>C\x18o\xfd\xf8\x8c\xebH\nYG\xe2\x03\xa6\xb3\x84Y\x12\x10H\xe9dtv\x96\\i]\xc0W,\xba%\xecc4 \x0cy\xca\xa2_\xae\x83m\x17\xb0\xb1\xc7\xca\x1dx\xfc\x18\x10~\n\xf8\x0f0\xda\x1co\xc3:\x8b\x99\xd9\x9b1\x17$\xfc\xcb\xb3\x0c[\xb7\xc3a\xbd`\xa6\x8b\x1b4\xda\xdcR`+\x0dPd\xfe\xc5pP`\xb15\xbc\xcc\xbf\xe0LiX\xcbnM\xe0A\x81\xa7d`\x12\xc3c(\x1f9\xc0-\xb9x\xe4\xd6bZ\xae\xaf\x1f;\x18F\xe2+&kiV\xa8\xc1\xa6<6X\xab\xf9w\xb3\xf4\xea\xeb\x83\xe2\xacM\xc7\xb6\x8a,\\Z&\x85y\x9b\x9bV-\xaa`\x059\x15\xb2u\xbb\x01\xf7\xc2\xca\x8e&\xd6\xdf\xa6:\xbc\xd4\xf6\xc3\xf6{\xba}\xd6\xd4\x82u\xf0YD\xce\xaeXS$\xdb\xfa\xff\xd3Z%\xff\xcf\xfac\x9b/\x8a\xea\xaau\xa5/\xda\xb5f\x03\xb8o\x90\x85\x12\x8aT\xb2\xc0\xc7\x1d\x0e#S\x04k\xb2\xe6O\xc9\xb1\xcd\xbc\xf3~\xfb\xf5\xff\xf8\xb7\xff\xc2\xe2\x9d\xf2\x9fX\xa6l\xe3Zs\x8b\xd3\xb5I\x98;s\x89J\xbe9\x86\xe3\xed0\xca\x807\xfe\x97_\x82\x9dLcZ;GWnA\xfbR\x94_\xca\x07\xb9e\xf9\xd2Z\x809\xec\xc1\xcc\xa3\xb0\xda\xc7\xa0\x81\x04\x8er0eT\x05\x8e\x803\xef6\xe1jE\x96]-w\xc1\xc2\xbc\xeccM\x85HTh\x11\x1ej\xc1\x82Z\x0b+\x8fT\xaem\xfdX\xfc\x18\xffx\xfe\xe3\xfc\xc7\x0c\xfe\xed_\xff\xeb\xff\xf5\xeb\x7f\xfd\xd7\xff\xf3\xb7_\x7f\xfd\xed\xd7\xff\xfc\xdb\xaf\xff\xc3o\xbf\xfe\x8f\xbf\xfd\xfa?\xfd\xf6\xeb\x7f\xf9\xed\xd7\xff\xf9\xb7_\xff\x97\xdf~\xfd_\x7f\xfb\xf5\x7f\xfb\xed\xd7\xff\xfd\xb7_\xff\x9f\xdf\xfe\xf3\xff\xfd\xff\xfe\xfa\xeb\x8f\xe5xs\xfc\x00\xff\xff\xf0\xc7rN\xe6sk\xc8\x19\xbb!M9\xde\xde\xc1(n-vF\x8f\x91g\xe2\x8a~\xd2{I\x0b\xd5q\xafm\xf3 $r\xc3 \xea\x02\x8a\x8d:\xe1%(n\xb1,\x8f\xc4\x01\xe6_Q1x\x14\xc8\xe9\xa7[\x8em\x89z\x96\x81\xa6\x11u\xfaVJ\\_\xa1X*\x17\xe4\xf6\x95\xe76V\xdcg\xf0\x18F\xb0/\xa5#\x1e\x1d\xd7\x06\xcc\xcaV2\x96\xf1\xc7\x1c\xd3\xacl\xe9Iy\xee\x1b\x11\xf9\xddN\xd0\xe493 \x18~j\x0d\xbc\x82O\xc7\xcdM\xe1\xd1\x0f\xb3DM \xf7\xdc)a\x03\xeaK\xbbd6\x15\xf9\xef\x02O\xf7\xc7J\xde_\x06\x8d0\x9eEe\xc0\x82]\xe8@C\xd4\xe9\x03\x8d\n\xed\xff\xa7D\x02\x8e\xba\x07\x0fS;\xbd\xc6\x08\x91\xab\x80\xc3\xed\x0ecc\x99\x06\xe3\x8e\x8c\xa4\xc4/&x\x83\xef:+v\xd9\xb7_\xa3\x91\x96\xb6\xb8\xa9\xb4\xb8\x0e\xdcO\x99`\x05x\xa3\xc0E\x91\x89>\xe4\xf1P[\"S\xf48\xe5a\xfaC\xd8\xdb\x83\x11\xdc\x83M\x05Ca=M\xca\xb8\xa8\x1d\xb7br\xe6\x17\xe19is\x12\x0f/\xc9\xdd\x0f\xbd(>\xc9\xd8\x93\xb8\x98%\xd1\xc78\xb2\xb4i:|\xd1\xfc\xc7<\xb6\xb4\xaf<\xfc\x99|\xbcY\xf0\xd6?\xe6$\xc2\xc2\x8f\xc2Y\xbe\xd2\x1c\x86L!\xfc\x14\x80\xb42\xf2\x19\xb4\xfa\x88\xf6\x17\x19\x99\x7f\xe4\xa5\xcf\x97~\x14\xad4\xfc!\xa3\x17\xad~\xf4\xc5\xa7\xef\xdf\xaf\x06\xfc\x83\xc6/\x9a\xfd\xf8\x13(O\xef~\xf4\xe5'\xc1\xfey\x99~\x84\xa1\xa7w4\xf4\xd8\x1e\x8d)\xb9\xbc\xf4\x8b\xd9\xc2rad\xae.\x0dfZ\xd5S\x8a?\xd5k\"\x1e\xc1\x19\x10\x93\x921\x91e\x0f(z\xa8\xd2\x99\xc5\xd3B\x9f\x19C2\xafO`_\xd8\xe11/\xaa \x9a\xc0q)o\xecL\x8bc!\xc8\xcf:qA >\xbe\xe1jrQ\xa3\xe5\xc2\xf8\x06\xeb\x99)<4`\xd0\x92\x86}K\xea7\x964\x93\x974\x1b\xb8\xa4\x12?\x91a\\\xb3\x04W\x95\xbd\xe1k\x19:,N\xd3\xdd\xadhN\xfc\xec\xdf\x01\xf4\xee\x963\x8d\xc2B \x9e\x1d\x03K\xfd: \x0dGl\x8fw\xda\xbe& D!\xdd\xd7L\xef\x86J\xb4\xae\x90\xc4\x9a\xa1\xf1\x8a\xe5\x9f\x9e\xce,\x9ew\xe2\x9e}\xea\xfc\xf1\x9eC\x99\xe3\x0f\x1f`\x1bu\x1e\x05\xc9\x8b\xba|\x7f\xe2\xdcsac$\xc2:\xd1zc\xac\xe7\x9f\xca\xb5|lH\xaa\xc4\x1a\xf3\xea:\xde\xbeC\xffkT\x92\xcb\x1d[*\xa3\xdc;-\xaf\x8a\xbd\xfd\xaaP\x05r\xe7\xdc\xf7Y\x12\xa8\xde\xb3\x9d\xfd\xfd{\x1e\xb9$3\xdb\xb2\xe8\x1c\x15P3DO\x02\x92\xad\x9a\xd0]\xaa\xe3\x06@\xd3'gOx!\xf14<\x95%\\;\x95\x8a\xfc\xedZ\"\xa7_\xab\x83\xe8\xe1\xe8\xd4\x9f\x9d3K\xff\xdc\x85\x08\xc3T\xcfY8}\x93\x93z\xc0B}\x86gq\x92\x91\xa7>\xc6\xf6\xb3B\x0b&\xf4\xda\x83uZ\xb6,\xa3\"\x8c\xc2\x18\x8b\x96\x8d\xa22\x0eQ\x11\xbf\x0fV\xd9(\xc8\x8bp\xf6\xfe\x8a\xbe\xbf\xe2\xef\xf5CX\x98}\xe4\xcf\x9b\xbbY\xc0>l\x8f\x1fn?\xdc\xbd?~\xb8\x83\xe6\xfe\x8f\x1f?65\x80\xd1g\xeb\x03O\xbc\x1c\x83\xa3\xbb\x10\xc0:Xg:\xfb\x01\x94\xfea\xd0\x06t\x8e\x90Z`J\xce%o\x876\xf2\x85\xbd\xbf\xf6\xe3\x8f\xb9c\xb9\x10\xa84\xd4\xd5\x83\xfe\xeeK\x06\x8b<\xbe\xe7\x9amG\x18y\x0cE\xcd\xb0\x0e\xf9t\xf3\xb8\x82\xf0\xc7\x80\xf1\xd5\xec\x94\x07?\xe12\xa5\x85+>p\x1c\x17\xd6\xd0\xb6\xbf!\xf1\xc2\xa4!\x9b\xc7\x95F.s\xcd\xe4O\xe3\xc1\xa9\xcf1.\x01\xcc\xe1\xab\xae\xe4{\x03\xc6\x8f`\xbe\xbe\xee\xc8;S\x8b\xd8\xe6h\xe8k\xe3\x8f=\xa5D\xbc\xf1\\;nw\xf0|9\xbe\xaaC0\xa2]\x00s\x14J\xe9\x07l%F\x0e\xcf.!-\x1b\x8b1\x1f\xb9\x90V\xad\xee\xc1\xb9\xe3|\x00\xbec,\xa3O{\xfb\xe8\xa0\xeb\xc1\xc19\xecC\xca\xcb6]8\xc7O:#hY.3\x8f\x06kS\xa0F!\xd3\xdct\xa4\x15\xb3\x07a\xb6\xe6\xa5\xd9FW\xb0\x0f\xd3c\x98\x08\x1cT g\xdb\xdc\xa0Z\xcc-\xd1\x08\x1a\xa2\xeb\x06d\xd5\x8d\x08\x01\x89\xac\x8ak\xb2*\xeb\x90U\xb1\x8a\xac\xcaV\xa5\x03\xcc\xf2\xfa\xd4\x8e\xed\xedQ[\xec\x9c\x88\x92q\xbb$\x14%;\xed\x12\x9f\x97\x8c\xee?h\x17\x95\xbchgk\xb3]\x94\xf3\xa2\xadNO\x11/\xb9?\xden\x17\xcdz\x03\xf7U)\x98\x88wrB\xf2\x97IPFD\x97C\x14$\x99\xff/\nW\x10\x8c\xbb\xc7r\xe2\xe9B\x99\xd5\xf9\xdex\x0c\x86v\x8a!o\xe1\xe7\xaf/b\x91\xbe\xb5\nC\x17s\x95\x0d3\xb6 \xdd\x84oP\x83\x10&\xa6\xf3\xcb\xa8\xe0\xa1\x99\x9a\xa0A7e\xbb\xb3Ts\xae|q\x1e\xfd\xa1z/\x96\x0eR-\x8b\xdaY;\xcc\xf4<\x18Y\xa3.E\x92\xd6Y0\xde\xdd\xd9\xdd\x1c\x05-E\x1b\xbdv\xad-o\xf4\xc0\x1b\xb7J\xe8}j\x9d\xfa\xf1OI\xab\xe0\x8c\x16\x1c\xfa\x85\x0b\xe3\x1dxR\x9e\xc1xs\xf4\x006\xefOv\xc6\x93\xf1.\xfc\xe9\xe5\x91t\x10\x86\xe9\ns\xb1\xf4\xde9\xc9\xf20\x89s\xbc*;/?|\x80_\xae]E\x89\x97_\xf8gg${\x17*\x9d\x97x\xb5 (\x02\xdd\x9e\x85\xc5[r\x1e\xb2\xf2\x85\xb2\xfcY\x98\x15W\x13\x08\xba\x85\xa7e\x18\x05G\xe1\x92\xe4\x85\xbfL'p\xd6\xad\xb2\xf4g\x8b0&\x93v\x0c\x85.\x07Ph\x1d\xaf\x82dy\x12\x06,\xcf\x94\x1ao\x06\xc9\xf2U\x12\x10S\x95<%\xb3\x89\xde\x88*\x8b&J5,/\xccMMG\xfeUR\x16\x13\xb0\xbe\xf6s\xf2\x02\xff\xd0\xb4\x14$\xb3\x83\xcb\xd4\x8f\xd9r[Q\x98\xebj.\xfd\xcbg,\xf5( \x8e\xfc3c\xff\xf30*Hf\xaa\x81\xe6\xa4~\x91d\xefp\x9e\x8b\xa2H\xf3\xc9\xbd{IL)^\x01=^\x98\xdc\xab*j\x86\xc5|\x97r\xfdB\xce\xca\xbcH\x96\xfar\x9eO\xf5uJX\xea\xaa\xe7A7\xa9N\xab.\xcfz\xf4\xac\xd4%\xbb\xaa\xea\x13\x92\xbe\x08\xe3\xf7a|\xa6\xaf\x94\xb1\xd6\x9e\xc7\x05\xc9f$-\x92\xacOc[\x7f\xc9\xb0\x97\xb2\x82f\xba\x19\xc9\xd3$\xce\xc9'\xea._$\x17\xe8\xd3M\x02\xbejj\x073\xa8q\xeb\xcb$ \xd1[\x12\x07$\xc3u\xb3\xc8\xa5\xbfL#\xa2\x83`\xe9+\x04\xe5\xe0\x19I\x8b\xc5\x04\xb4{R\xd7\xcf\x87|@\xa7ppY\x10<#\xb9~\x1fi\xbd\xa7\xc9r\x99\xc4\x83j\x97)\xc5\xc3$8,O\x97a\xc1\xa2M\xe4\x13\x98Zg\x04\xd5.i\xc9\xfeIr\xfc\x97e\xd1\xa5\xbf\x92\x94nU\x8e\xfa\x01\xe2\x07X\x89\xcb8\xad\"\xf3g\xc4\xd20\x9eiFrR\xd0>\"\x81\xb0u51C\x17\xad\xa9\xa9\x10\xc6a\x11\xfa\xd1!\xddX\xfd\xd1\x9a\xc7\x86c\x99,\xd3$\xa6|\xcb\xa4\xed<\x05jp\xa2\xfc?%\xd3\xe7^\xeag99D\xb9Y'M p\x82\x89x\x1c\x057\xf1:OF\xac)\xa5X?\xe5\xdd\xf8b\x8d\x1c\x9b\xdeq\x05\xd2\xde\xb1\xa2\xb7+\xed5\x91_\xe5\x05Y\xaa\xc8\x08\xf1T\xd8+\xf5\xf8\xcfU\x0eW\xb5M\xa9\xc7\xf7V\x03kl\x9b\xda\xb3\xd2\x8eJ\\\x1ff~U\xd4J=\xf6K\xdd\xb7x\xc4\x95\x90z\xec\x97\xb6\xb2f\xaeP\xdf\x98\xc6~X\x1d\xdd\xc5)\x1e\xbc]S\xaf\xcc\"\xfd84;\x01\xa9'C\x7f\x97@V\xc4&\xe8\xfb\xa4\xa2\xa7O)=\xdd\xaa\xdd\xfa\xbbEZ\xdb\xa7HRK\xfdS\x15\x9a\x078`\xb2\xdc#\xa5\xc0\x86\xb0\x073\xc7\x85\x13/'\x05\x1bCn\x97\x8e\x0b\x17\x02;=\xc1\x99\xe7^\x94\xf8\x01 0\x8fI\x9d=\x9d6\xb5\x16\xd3CE\x7fZ \xf2\x84\x16KQ\xb0\xe9BX\x8f\xb2\xc4y3^p\xd3\x85\xa4S\"%|ck$:.\xd3\xc0/\xc8\xbb,\xb2-\x0b\x07\xd6-|\x91\xf8A\x18\x9fQ\xe8/s\xdb\xca\xcb\x19\x06~\xd1\xd4>L\xc9\xcc\xa6\x83\xc8:\x83\xc0d)\xcdo\x82\xe4\"\xa6s\x07\x0c\xea\xc1g\xaa\x1d\"\xd6\xe8\xf4+\xda\xe0\xc5\xe8\x81#6\xc0\x81\x0b/C\xd2\xa7\xde\x14\x17\xac'i\xaa\x93\x97V\x91J\xb0\xfeI\xa8\x0d\xcd\x0f\x1c0s9\xb2\xc6\xdfK\x92] \xf8\xab\x9b\xd0\x8bR\xab\xe1\xe5bXj4\xc9\xa3\x89P\xe0\xc0T8\xbceL\x06\xd0x\x89`\xf7\xe1\x03\xf04\x1e\"k\xc7\xe1\xfb0MI\x00YM\x07\xc6 \xfc\x0bk\xe5_ \xc9\xf07\xfd\xf8_\xe0\xc2\xcf\x11\xed\x87\xf3\x90\x04\xbau\xe2x\xe8\xa2\x8b\x18\xba\xe7\xeb\x92bB\x0e\xf2L\xa6\xc8~\xbf\xcb\"\xa5\xac\x0d\xe5\x98\x8dM\xee\xbc\xa0G\x9b\x9d\xa8\xaf\xaf\xdeq\xb0Y3\xd6\xf8\xf0\xc1\xd8\x82\xe2\xfa\xc6K\xed\xb2;\x1d\nlo\xc92)\x08\xfb^M\x81\xab\xd8\x90\xd4\xeb\xbeU}\xa9`)\xe8\xa7\x9d\xd7M\x1c\xec\xc2\x01fb\xb0\x8d\xf3\xbc\xa4\xd5\\\xb8\xa0\x87\xf1@r\x03\xba\x96\x91,\xe9\xa5E\x1c2\xe1\xd8\xde\x19=\xe88\xf0\x8ev\x1c\x8f\x8b\xfd\xde\x93\xab|HC\xf5\xcau\xac\xa0\x99\xb6\xf5\xe1\xae4\xe1\xd8\x1e\xef\xdcwx\xbaM\x03\x95\xd1631\xbb\xed4\xb3s\x03\xacnX\"/C\xb3\xa3J8\x18\xdb;\x9d\xc0\xb0\xb5pq\xd2\x9fb\xb3\xb3\x03\xdc\x83\x1b\x1d\xbe[\xfbp\x7f\xdb\xf1\xe6rL\x94!-\x0e\x9cD{\x9bn7\x89\x9d1\xf3\x07\x1f\xdd\xe7~\xe4c\xeeW>\xbe\xaf\x04\xaf\xc3\xab\xe5i\x12\x0di\xbb\xd7J_\x9d\x8e\xb7\x13\n\x83G\xe9m\xe7\xb2\xe4\x913\xda[\xca\x83\xf4\xee\xb4\x83\xf1\xf2\x19\x8c\xb7\x1d\xef\xcf\x07\x7fk\x96\xb1\xd4\xa1;\xed\xf1\x88\xcc\xa1\xed\x011\x81\xf6\xc3vX\xa1\x94{\x87\xb4\x8d\x13x\xea\xd0\xb6O\xc2\xa2\x82\x94\xe6\xfbs\xfe^\x9d9tg\xdc\xae/2\x87\xb6'\xcc\xb2\x86n\xb5G\xc3R\x86\x8e\xdb\xb5Y\xc6\xd0N\xdc\x87\x0b\xbe\x9a\xed\xb9\x1e\xb0%h\x8f\xf1\x92Wo\xcf\xf5\x90\x8f\xbd]\xff)\x1bL'X\xca{\xb6\xe5\xed\xd7O\x04Bj\xbe~\x0d{\xf0\xb4\x9d$\xf4\x0d\xec\xc1\xfb\xf6\xcb#\xcc\xfb\xd9z\xf9\x12/\x08\x06\xd7\xcd\x92\xe7\xd5\xd5\xd1|\xff\x13\xec\xc1sJ.<\xafQz\xb3\x06\xbd`\x02\xdb:Y\x84A@\xe2\xb6\xca\xff-+-\x927Y\xb8\x0c\x99\xbfM\xb3\xc63\xd4\x03y)g(\x9f\xe7\x07q\xb9d!\x91\x9b\x15_\xd0\x1b\xd2\xb6r\x1c\xfd\x06c\x05\xb3\xabvs\xef\xe4Z\x9dd\xc6\x7fg\xa5I\xba\xa1\xa9\xf0\x0d\xecu\xb4I\xcd\x1a?\xeb\x02\xc2\xbcl\xd6\xfb\x1aW\xf4/\xac\xb1f\xd1\xf7\xb0\x07k_cf\x88\xaf\xa5\x8c/\xad\xbf\xbdy\x18\x07O\x17a\xd4R4|\x0b<\x82odvr\xe6w\xce}X\xdb\x83K\xfb\x0d\xf2fh\xd7\xab&\xd0\x87\xc5\xd8\x82\xba\xe17\xb2\xad\xb0Y*\xc2\x93,\xdf\xd7V\xbav\xbcn\xd0#P\x8aA\xae\x9dv\xddkG\x0eg\xa3\xb1]\x03 !\xbf\xb6\xbfQ\x9b\xd3d\x92\xac\xe2\x9biq\xec\xc2\x9b\xaa=\x1e\x10\x92 \xb7\xf9\x0d\xfd\xf9\x06\x9b\xe9\x04\xc0\xbf\x86 \xbcin\xd9\x0f\xbd|\xbb\xe0\xd9\xdf1\xaf\xf1K\xfbe\x0d\x08&\x1d%fL\xef\xaa'\x9b\xdd\x7f\x07{\xf032\xc5\x0c\xea\x1bP\xeb\x89\x9b\xbb\xb1\x88\x06\x80R4B:\x0b0\xa8\xa5F\x94\xfd\x97\xa6\x19\xfcm`l\x80\xaa\xe1=\xb1I\x7f\xb3\xff^m\xe0\x15\xcb\xe2\x02{p\xc13\xd6\xd1w\xb4$\xb1\xdf\xa1\x91\xc4>\xc6\xd7\xa9\x10\x10f\\\xa5\xfd\xbdby\x85\xa7\xaf\x8e\xa7\x053s\x11\xbf\xf7x\x0e\"\xdc\xb4Xw\x10\xea&)\x17\xb1\x89\x89\x8bT\x90\x0d\x93\xba\xc3\x0f\x1f\x18\xf4\xbdr\xe1\xc0\x1ea6uJ\xa6\xd4\xfd\xd2\xe1\x7f[\xad\x06\xfd\xb6\x86V\xd3b\xfey\x88q\xc8\x95\xd2\xf5\xad\xd6\xbc\xb3\xe0\x1fK\x9e\xe8\xb3\xa0CKXj+\x16e\x97IP\x98\x1fe\xf2\xc8\x81\xbf\xa1\xfe\x1d\xc3\x05&\x18\x06\xa60j\xdf\x8d)7\xfe4\xf88=k\x18\xaf\xe0\xc6\x13\x96\xaaP\xdb\xf3\x1a\xd6\xae\x01\x08A\x83\xe5\xf7\\K(0\x11f\xc1e\xaf\xd9\x05\xa2\xec\xda\x17\x9f\xff\xf9N\xfc\x16%\x0cz\xe8o\xbay\xe4\x18\x0b\xdbv4\xcd)~1d\x8f\x98\xdd\x05]\xff.\\\x0b)\x11\x89\xa9\x9e\x94\xff\xc8\x11{\x82\x87\xcd\x17\xb3\x8a9\x04\x7f#v+dSz7-\x0c\xe70l\xce\xaa\xae\xf73nmi\xdb/M\x81\x0d1\x08\x14=N2\xa2\xef&\xc4\xb0\x18IZ\x87{\x92\x92\xd0w\xf2b\x9c\xf3\x8cj\xa9\xca\xebw\xb3\xe1\xf5\xbb)\xf9\xe6\xbb\x9d)6\"B*\xaf\x13\xe0Y\xdajl\xc0SZ\xfe\x9d](\xcd\x03\xce\xfe\x9a\xbe:\x16\xf8\xc2\xae\x8f\xbc\xb8'\xbe\xad\x0d\xe9\x10\xa9\xab\xd2\x1d]+\xa5|H\xf2}O\xff\xf7-\xdd\xc3N.@\x18\x14I5\xa7T^\x8bXp\\\xf8\xa1\x99\xeeM\xce8h\x15I\xe5\xe3\xdd'\x04)0C\xdf\xfb?\xc8M?\xc5\xa4t_\xb8\x94E\x81=\xf8\x1bF\x90\xdby\xe8\xe0_\x87\xf8\xff\x7fF\xae|\xbc\xc3\xde\xfd\x89\xf1\xe8\xbb\xec\xaf\xbf\xf2\xfc\xc6k\x94\xdf\xdc\xc6e-\xe9\xfc-\x15\xc3`\xb9\xf4kD0\x0b\xfc\xbaWR\xf5\x83\x1d4$2t\xc4\xbe\xedc\xaa;\x1fS\xdd\xf9,[\xda\xcf\xed\xf5f ;\x91\xe8\x16Y\\V\x1d\xe7\xbfPva\xe1\xe7\xcf\xf9\x01p\xc3\xfci\x12\xcf\xfc\xe20\xcd\x88\x1f \x9b#(0\x17\x9d\x85\\n\xbd\xeb2\xd7\x0c\x97\x07\xe8u\xd1\xde\xd3\x958)W\xec\xcc\x91\x7f\xe6\x96q>KR\xda\\.LC-\xd7\xa2\x17\x01a8\xe2/\xf5!!\xe4\x91\x03\x81\xfd\x97)!\xcd\xb4\xe65\x12\"\x98\x8f*\xf0\xf2\"\xc9\xe8\xe5\x12\xf3V\nR7\x13\xd3f\xce\xed\x82L\xe3V;t\x05\x0f\x1bk\xc7Ox7B]\xbf\xfdG%;{Ao\xb5\xf5=\xb47\xdf\x87\x17\xf4TM\xd8?{\xdd\xe4\xea-\x04\xfc\x9e\\}\xd3\xdf\x15Z\xe0\x7f\x87\x16\xf8\xc6\x9c=>0\x1a\xb8\x83\x9b\xa0\x19<-\x8c\xe1\x85ZCA{z\x81t\xdc\x9e\x9c\xba\xc3H\xc6\x9799$\x05\xaa\xb1\x8d|\xda\xf7\xaa\xf0\xc0\x9d\x96\xc2e\x1a\x91!-5\x93\xcd^w\x8eJk\xa3\x19\xc3\xdb\x8dq\x84A\xd4\x07$+\xedZ%\x17\xb0\x0f\x976\xa6\xa5\xfc\xb3}\xc9h\x1d\xe3f\x07d\x1e\xc6D\xa8\xa8'\xf07CqH\xf2 \xfc\xb9Y\xe1\x8c\x14\x92\x8a\xfb\x19\xc9gY\xc8\xd4\n_\x98*\xbe\xf2\x97\xb4\xb1\x7f6\xd5a\xc7 \x9f\xc0_\x1b\xeb\x88\"\x96\xe6b\xdakx\xc5\x1a\x98|q\x11\xbel\xc7<\x16\x8c\xda4.\xa3\xe8\x18c\x99\xfdd\x0b\xba\xd3\xfa\xe5\x9a\xbf\xe9\xae\xbd\xdf1,m}\xc26\xb7\x851\x1d\x17\xac\xef\x0e_\xbfR\x04\x01\xa9\xb4\x0c+\x10?\x9cd#\xc7\x8c\xa3\x18=R\xc5\xe0\xa1,\x05\xa7\xc9\xea\xeb>ib!\xf1\xf0L\xde\x9c \x1a\x1d\xbb`\x9f\xda\x9d\xa4n\x9c\xc4\xffN\xf6\xbf9\xe3\xd5\xecb\x089.\xfaRJ\x87X\x987\xa44;\x06\xf5\x8eK\xfb-\x1c\x0d\x1a\x00\x0e$t\xect\x1a.\xfc\xc4\xb5*\xcf\xbb\xc2\x87\x06XIB\x84\xe9[$\xc6c{g\xd3\x91\x85\x0b.\xbcm\xd4cI\xb6^\xcf1_\xe8\xcb\x1aq\xb3\xbf\xfdb\xe1\x82E\xff\xb1\xf8=;\xe7j\xa6\x1a\x06\xd66\x07\xa9\x00j\xe9xG\xca)\xa2B\xa9\x93\xd8QBaU\xbd\x94\xe0\x073e\xda\xb7\x98\xc5\xe5\xed\x1a\xce(2HV\xa0\xea\xbb\\\x00O\xf1\x11\xed=\xf4\xe6,/\xcb\xe6#(kH\x8d\x1e9\x90W\x16\xe8\x94`/\xa7\x11\x12\xe5HN2\x10V\x1f`Ia\xb8\xda\x8av\x84\xdb\xc2\x9b\x90\x92]\xdd5\xfd\xe5\xda\x13\xa4D\xb3\x10\x83\x03\xd5\x86\x14\x02\x96/\xc28H.P\xc9\\\xfd\xe2BS\x05F\x84}C\xa1\xcdZ\xa0\xb8]v\x8b\xab\xb5\xa3\x83\xa88\x0c\x8akM\xd9H\xe1\x07l\xf2\x18G\\\xe58\xeb\x95n\xe9\x93\xd5T\x04\x88\xca\xda\xaa7\xf9\xbb\x18\"w\xf4Q4\xd1<\xc06\xcf\xbf\xdc\xd4\x14\x0e\x02\x00\xa6K\xb1-?\xbf\x8ag\xcfWR\xc8\x89OY\xfa\x12\xa4\xa5\x07}\xa7\xd6|\x15\xde\xe9UA^\xb0#0\xe4\\F\xdas\x89\xe9\xa5:%\x19\x96\xb4}:\xf9Ro\xd1\xdb\x13\x83/9p\x0f\xb6aC\xe2\xcd\xaf](\xbc\"\xf9\xfa\xaa <3\x9catm\x9e\xfd\xa4\xb0\xe7\xce1|\xf5\x15\x8c\x1e\xc0\x87N\x11\xac\xc3\x88\x17\x8f\xd5\xc5cV\xbc\xab.\xddr\xe8JL\xf3\xf5u\xbc\xa60\xb2\xf2.| \xe3\x9d\x9d\xf6\xfb\x07\x9d\xd7\xe3\x9d\x1d\xf8\x12Z\x89\xa4\xc6<\xc5\xb5\xb8:\xd5\x93\xd1\x0c\x96\xce\xe5\xf1c\xd8\xeev\xd2\xc2\xb6\xa3A\xbd\x8c6\x8dK\xb6\xad_\xb1\xc7\x8fa\xa6\x87wZ\xb0u\xfd\x12v\xb7\xe8\x0bko\xcfB)\xf7\x98\xb7\"\xf6\xcbf\xed\x8cq\x1f\x1e8\xb0\xaemx\xb4)Z\xa6\x80Q\xb5\xcc\xbb\x1aK]Y\xed\xa1\x0b)L7\xdc\xf4\xb5\x82\x7f\x16B\xc7D\x12>Ze\xcc8\x8f@N\x0f\xfb.\x8c\x8b\x07l\x1f\xf7\xe5?&,\x9f\x0b\xdb\x14\xeb\xc9\xd7O\x9f\x1d|\xf3\xa7o\x9f\x7f\xf7\xe7\x17/_\xbd~\xf3\x97\xb7\x87G\xef\xbe\xff\xe1\xaf\x7f\xfbg\xfft\x16\x90\xf9\xd9\"\xfc\xe9}\xb4\x8c\x93\xf4\xefY^\x94\xe7\x17\x97W?o\x8e\xc6[\xdb;\xbb\xf7\x1f<\\\xbfg\xf1h\xdc\x0c\x8f\xf8\x95t\xbe\x84\xaf \x7f\x04\xeb\xeb\xa5\x03\x19K\xc6\xedOK:\xf0\xa9/\x83r\xe9`,c\x95[[\xa4\xc7\xea\x02\xd8\xba\x84U\x01\xff\x01\xb6)\x1a\x13\x8c6E\x9e\\\x16\xf8\xc1vn\xc2\x84!f:^9mfw\x1df:\x8c_g\x8cB\xf7S9:z\xc1v \xa6\xff\xac\xef\xc1\x96\x83\x00c\x13\xba\x13\x14\xe5P\xec9\xda\xbd?\x1a\xed>\xd8d>\xf6\xd3\x92\x9e-\x06\xe9\x14\\w\xc6\xbc\x84\xa1\x0fV>>\xa6\xac\xb9\x80|;\xc4\x8cZ\x08\xff\x0f$\x98\x0f\xf1\xcd\xb8\xfdfWz\xb1\xbb\x05_B\xd8\xe6\xa9*\x8a\xa6{\x14\xaa_\xc9\xd4\xda\xb0d\x08\xdaD\x08\xda\x1dS\xd0\xb2NTE[JzC^\xcd\xc2\xcb\x88\x1f(T\x81<(\x8a\x02\x0cCW\x10\xea\x0f\xe0\x8f\x90PZ\x80b\x06\x85`\x94.\xfc\x88\xaek\xe9\xa8k\xa0\xbf>\xaeY\xb7\x8c^\xcb\x1b\xf7\xbb\xef\xd1~\x06\xf6\xb1\xe3\x11LT\x01\x0bR^e\x83\x96+\x9a\x0e\x10QR2a\xde\"w\xb8\xc3\xfe\xfa\x1e\xa4\x0c\xc3\x04\xf0%\x9f\xc3\xc6\x8cM\x02\x02x\xfcx\x0f6f\x94rX\xa7'\x18f\x18\xd8\x14\xeb\x8fwv\xe1\x8f\x10\"\xc2d\x1d\xb8 \xda\x9b\xc1\xc6\x1e\xcc_\xf9\xaf\xb8\x8c\xa7\xc0\xb6\x18x\xec\x83\x8dY\x04D1o\x92!\xef\x19j\xe9}\xd1\xd6R5\xcf?\x85\x0dX\x1c\xc3\x87=\x18\x8d\xe9\xc1:o\xddp7b\x8a\xb9\x10\xa4)\x9c\xb6\x0b\x17\xac\xda\xac\xb5#B\xe5\x96S\xb2\xb1\xab4bAj^)\xa3G$\xbcd\xac\x8c+\x81%[\xaa\xb8\x12X\xa2\x8a*A\x0b:_\xe4\xbc\xa0\x13l\x82\x99\x9a\x8e\xef\xb7U\xaf\xcc\xd6\xb4mf9\xc7ff\xad\xb7)o\\\x11\xe6\x82\xd9\x9a\xee\xec\xb6\x03]/\xaaO\x1e\xb6?\xe1\xf6\xa6\xe3v\xdfK1\xb7\xce\xac\x99\xc5\xa9&\xa0\xc3\xd5\xa7\x0f\xe8p:D\x1a&%\x1bm\x82\xca\x89IU_M\x8b(UA\x92t\x9e\xb15J\xe5{\xed\n\xb8\xd6\x88\x0d\xb4y\xdc\xd5\xcb\xab\x82\x7f\xb4\xdc\xc9\x84a\x8d\x8b\x05i\xbb@-p\xcb\xcd^\xc1\xbd\xce\xc5+\xb8\xcd\x9a\xbc\xe3L\xde\xc7\xd0\xf1@\xd6\xd7\xcb\x92\xa4x\x1eS\xd4\xd1S\x11\xe7\xfdF\xccN\xe1\xd4\x0c]M\x99xN\x932\x0e\x0e\xc5\xc45\x95\x8a$\x89N\x93K\x8d\xc34bz4\x00\xa8\\\x18\xe9\x1d\x81\x16\x01\xd5\x1b\xef4\x8c\x03\x1e\xf0\x87\x95\xa1\x82\x99\xdd<{p\xeaVn\xd63\x14r|w\xc8\xf6\x9ayUr\xe1[\xb3\x93\xfe\xb0\x85\xe2\xa9\x18s\xda\xfe\x99\xc7\xf6\xf9hQ\xc6\xef_\x86A\x10\x91\x0b?#\x8e\x1d;\x86\xc0i \x06\xf2\x12\xe1FNN\xde\x1e<{\xf7\xd7\x93g\x07\xdf\x1f\xbd~\xfd\xe2\xf0\xe4\xe0\xafG\x07\xaf\x0e\x9f\xbf~u\xf2\xf4\xf5\xcb7\xaf\x0f\x0fNNP\x87\xc7\xbcGsE$\x1c\x90\xc8\xc6M\x97\xd6D=\xe9!\xaa\xdd\xf9\x84\x12;b\xfa\x9ez\x98\\\xffS\xa5*wTf$6?\xaf\x8eXk\x0cO\xc2\xbdK\xd1\x1a\x05\xdfVN\xb5\xf8\x17?\x1e:\xadRk\xbce}$\x89\x0b\xd3\xee\xba\xbf'W\x13\xb0\xe8f\xd1\x19)\xdc\xa2\xf9\x05gTCC\xcb\xc2\x04a\xa6;\xdf\xe6\x90U\xe8\x81\x8dFLx\xc0hz}l\xd7\xd4\xa9\x07txp\xc4t\xb0\xf2\x0b=\xb0\xc9y\x80\x81\xd8&\xd0\x16\x0f\xe5}\x18t\x879\xa37\x1cJ\x91b\xc09\xfe\x1a\xc5JNC\xdb\xa8\x06KU\x9b\xdf\x94\xf1\xac\xf1-\xb1\x0b4\xa0\xd5y\xf9\xaa\x1aQ\x8c\xc0[\xfai-:\xd7jW\xe5\xa7\x1e@\xc7\xde\xb5\xfd\\;^F\x82rF\xec\x0b4\xa35\x0f\x957\xacA\xa0\xc0t4mTg\xeb\x02\x00^p\xfc\xc5qU\x8c,\x01\xb7\x06m\x1cH\x85\xfe\x03\x9a\xd7r\x1f\x00\x08\xfcF\x9b\xd6O\xf1\x9c\x07\x17U\xc0\xedX\x0b\xb7\xe3\xe6\xfd=>\xeeq\x0d\x07Nd&\xde\xc2\xcf_\xa0\xb7\xb6yD(T\xd0W\x19\n\xd3\xa8\x07T\xa9\xdf\x0b\xcf\x9f\x17${\xc1\x9d\xa7\x91\x83X\xdbt\xe1\xc0\x96J\x1cY3\x1f\x9bB:\x9a\xcf\x84\xdc\x0c?\x1e}\x1e\x12\xd52M\x14\xd9\x9f\xc5c\x82\xdc\xbb=`\xcd\x99dB\x18\xd1\x7f*\x07\xcd\x03\x00TY\x80\xeb\"\xfd4\x85\x95\x18\xb0z\xd3\xc5\xbb\xa1\xad\xf0\x18T\xba\xe3\xd13\x02\xceG\x16\x82K\xe2o\x06u\xfe|9\x81\xb9XZ}\xb5\xb7\xc4\x9f\x15\x93:H\xa2\x1as\nn\x8cqi\x12\xcf \x18\xc6\xe5\x96p\xce\xa7u{p\x92\x07\xa9\x8bX5xdw9\xb0\x01\xc2\x82!c\x87\xce\xf8\xbbo\x0c3\xcaW\x99\x91\x96\xb7Q\x0c\x14\xf6\x14q\xf7\x06\x0f\xab\x894\x07\x0c\xcdxE2b\xc4p\xef {(b`\x0bLmW\x97\x18\x9f\x99,.a\xbea\x8c|JN\x7fz\xe9\xa7\x0e\xbdA\xfa\x97\ndZ\x89\xf1\x18\x99fW\xb9\x87V+\xd6\x0f\xa9X\x93\x9a8\x1bB\xe6\xf7RH<\xc6-F\x82&\xd3\xf8x\x85H\xe0\x82\x10Y\x91\x0c\xe9J\xf8br\x013\xef\xa5\x9f\x9a\x19\x05\xe0\x84\x89\xcc\x15\xf7s\x93k\x99)\xc2\xb0\xfc\x08\x93\x80lZx\x94\x1d\x18\xd0x/\xa3\x0d\x12'u`\xc7\x8e\xc9_N~\xf8\x88\xab D \x97\x0c'\xc6/\xf5\xac(\xa8\xc4\xbe\xed\x07aO\x0d\x95\xc8\x0f\xbbm\xa8,\xe4\x08X\x9b.\x04\xde,Y\x9e\x86\xb18M\xb9\xc3r\xea\x9f\xf6&\xc97\xa3\xdf\xa3\xabt\x88L\xa8W\nC\xa6\x9b\xc7^\x91\xbcKS\x92=\xf5sb\xa3\x11P\x15+\xbeW\xec\x86\xa7\x9e\xcd\xcd\xb1\xf5H\xa2\x1aP\xacH\xe7!?\xe7<\xb6y\xac\xcc\xf8-\x1eTT;\xf28\x92&}\x9c\xc1:\xc5u\xa1\x9aU\xba\xcd\xa5L\xc9\x13A+\x0f\xd8\x80!\xb72\xdfN\xdb\xca\xab\x86o7@N\xef\xdfbx\x02\x915\xc7\xe7\xf3v\x07\x82\x05^\x06d\xc5\xcb\xa0\x03T\xc4`\xd6\xa2z\x1a\x02\x06\x8a^\x1c\x13\xa0\x14\x9dL\xe0\xf2\xa3a\xb5o ?j\xeel\xc0n\xf5\x9ef\xba]\xc3\x98\xd1\x06_\xa8\xf2W\x07\xdd\x86\xc6\xcd\xfd\xe8\xbfpi\xaf*\xac0\x8d\xeb\x0c\x0e\x1b\xf7\x9dc\xef\"\xf3S>\xa4\xdeK:\xe3\xf8U\x03h\x03\x04\xbe\xe2\x0e\xca\xa6q\xcf\xb5\xc6\xbbD\xe3K\x14\x10 A\x91\x9d0\x1f\x17\xb4UL\x8e\x1d\n]m\x9ad\xc8P@Z\xaa\xde\xa3\xd9~\xc4\xbd\x88\x87\xa3!\xaci\xa9:\x14Q\xc4t\x8fB\xbf\xd8~\x90\x90\x90\xcfY\xe6\xc8\x16\x89\x92\x87\xb2\xb4\xad\x10\x13\x12\xe4P$\x954\xaa\x96\xd2\x16\x0b\xbf\xe0\xafs\xf0\xb1\x91\xaa\xcc\x0e \x14\x0b\x02\x17\xec\xe4\x00CD\x8e\x0e\x11\xc9\x0f\xef\xe8\xc0\xcez$\xdd<\xf0\xe67\xbcO)\x88\x08\xbd\xafM$\x82\xb6\xf8n\xf1\xc4*\xd7\x8e Q\n\xa2\xce\x8c,\xb26\xb2\xa8%D\xfd\x01\x0e\x9a'S\xce\xa5\xa3J\xe7%?\xe2TN3 9<4)\x16A\xb87)qL\xc2\xd0J5\xf8^\xc4\x12v\x10K\xb1\xc2\xf0A\x16\xcaO\xb3a\x88\xc5\xef\"\x16\x9f!\x16\xb4x\xf5\x99M\xaa\x82\xd9\xe9\x1d\nH\x14\xd5\xca\x88\xa5\xb2\xbe\x0d\x15\x1c\x0d3Mb\x83\x0d\x1dn#\xcdlr\xc3GP\xae\xaf;h\x0e\xdd\xe0M\xca\x9e\xe5\x10\x8f@\xf1\xc8\xcf\x990\xda\x94\xcb\x8b\x9e\xc7v\xe2\x1cS\x8e{\xe6\x17\xb6\xaf \xad\xdb\xcfM\x10\\hBp\x02\xc0~?\x0c\x17\xf6\xa1\xb7\xc2\x80\xde\xd4<\x0e\x08\xf4\xa6a\x81n\x87\xdeP\xca7\x08\x99\x0d\x90\x94fM\x0b\x17\x15.X]^\xd0\x14\x08\x10\njL\xec\xad^\x0e\xf7v\xe2\xbe\xa6|\xfd\x1fg]\x06#\x16\xc1m\xb3C\xabr\x11\x15\xcf\xf5G\\\xe3o\xe2\x01K{c\x99\xe5\xc4+\x93\xc7z\xeaV\x83\x92\xaa\xb05<\xb6\xf9\xbe~\xf4\xd0\x96,\x8b\xb2[m\xce\x9d\xd2jJz\xaa\xd2\x98T\x14\x99\xb3\xa2\x84EEa\xf5RFz6\xb0\x97\xc1\xe1-\xf4\x1e/\xf9ix\x84u\xc9\x8f\xb0\"?2\xa7\x8a\xe6\xe4\xc3W\x90=\x02\x9f\x92\x1f\xe1\xd4o\x92\x1f\xfe\x00\xf2\xe3\x9c\xa7C=\xb0cAl`*$\x0d\xa9\x11\x1a\x93W\xf2\x87O^i\\\x81\x89(m\xd6c\xe9\xd8\x85\xcd\xa2\xca\x1b\xdb4X\xd7|\x14q\xc5] )\x08\xc6\xe6\xfa\xf0\xa1\xa3\xf1\x13jt\xf5R\xcah\xca\xab\x85[\xed\xc8\x1d\xe2Q\x9f\x18\x99\x84\x1f\x80nl4(<\x0d\xc5\xbc\x9ff\xc4\xa7\x07\xcd\xa9\x10\x17\x90\xc1\xa6 \xd2\xc6\xd7\xce\x8b\x85\x99\xcd\xe8k\x1a\xe4\xeb\xb4\xe8\xb3\xe1\x82\x017\x9b\xfc\x08\xe9\x1f\x05\xfd~\xf8\xd6\xbb\xff\xb7\x1f\x94(\xdeB*!\"\x06\x0cZ\x1e\xe0\x1d\x0e\xabI\x1f\xba5\x138\xf7^\x1d\xfcpr\xf4\xed\xdb\xd7?\xbc:9x\xfb\xb6_\x03#\x1e\xcc\x80\xa0\xcf\x92\xa5zR\xff*J\xfc\x80\xa5\xf8Y\xc8j\x84AM\x98\xb5\x1bX\x03\xe6a\xecG\xd1\xd0-\x12@\xd5[\xd9\xdc\xb5\xc9\x02\xb0p\xb42\xd7[b\xaa\x97~\xca(\xe8\xe4M\x96\xa4C\x90\xd5\x10\xf9\xb7\x11\xcf\xf4\xb6\x04M\xac\xd2\xb2\xe3!\x03H\x9a\xdb.\xc93\x8e^\x87\xaf\xca \x92q\xd8\xb2\x0c!\xee\xec\xa6\x87\x02\x8a\xe5\x0dVL\xc8\x81\xd5VG:P\xea[\xb6c\xfam\xf5\xea\xdaV:\xaa\\hCG\xddZ\xc5\xab2\x02-\xd4\x0d\x9b\xac\xa2\x1b\x0d\x8fT\xde!\x0dA\x860\x03\x95\xb4\"\x83\xea\xcbF\x9a\xcd\xea\x05\n\xd8j\x96\x04)\x9a\xd6\xd5\xd6\xaa2\x80Z\x15T*\x91\xc8r\xe6\x1a$\x91\xf0*\xf9\x1a\x067\xe8H\xe9\xf7\xc1n}\x89&\xb6\x9c\x8c\x9b\xc6\x14\x18x\xf4\xea\xf6`\xa7\xd91\x86\x95\xc1yu\x1b\x99&.\xc4\xc7\xc6\xaf\x9bp\xa7\xd0\x19\xb7\xbe\x91\x13\xfdk\x9a\xd5\xba\xee\xcb\x8c}w[\xdb\xbb\xaa\x8a\xa1Y;\xddC\x18\x9b]B\x98\xa261$\xe5ow\x18V\xa9\xa3\x1aoe\xd5\x8f6\xc2.\xc8\xb2\xd5a\xca\xa2j.%\x9d\x8b\xdfG6\x9c\xf3,K~\xaf\xa8\xb2 `9\x93\xd6\xd2O\xa7\xf9\xb1+$\x9fye\xb1\xde\xd8\x96\xee\x9bir\xac|)O\xb2\xb7\x02\xed\x13\xe3z\xf4Ub\xf3\x13\xb0\xdfW\xdd LU_\xf2}\x88W\x8d\xf4I#2\xa1*J\xc4\x81>Z\xc6\xaa\x9e$*\x9c\xe9xQr\x86\x02]\x850$\x96\x93\xa9\xef1Ij\xcb\xf7\xc3D\xec\x0b'F#\xb1\xa0'\xa3\xa5\xb0\x98*N8\xab8\xe1B\x84\x12\x7f\x04 |\x05\xc5#H('\x9cQ\xf8\x92W@wb\x05\x82GcpN\xa7\x13\x17\xa6\xf4\xba\xaf\x00&SY\xae\x0c\x8d\xe5\x85\x11C\x9a\x19\xc3\x08\xcfE\xd7\x036\xd7\x7f\xe8\xfe\x92\x13\x8d\x9f\xe0\xdb\xdeX];[c\x85\x17\xb0\x9c\x14\xa9.U\x07\xc8S{\xca \x9dE\xdbI\x99\xb4\xa3\xca_\x0f\x19g=\xae\xf1\xa64\xdc\xcc\xce0\xcce\xc6b\x86\xb2|7\xda\xb8\xa1\xedX\x9e\x98+\xc5\x9b\xd7#q\x86\x0c\x85.\xd9\xb6)\x87\x94\x9f\xe7\xe1Y<\xa4\xa9\xfeY\xe9'\xc3z\x99`\"\x98-g\xc59\x98\x93\x0c\xc9\xa7\xf2Z\xbd\xfb\xd9\xed{\xa1\xeb\xd8\xf6\x9ef\xb1\x055\xc1\x1a\xb7\xd4\xb9\x8cv\xb6\xdaYyJ\xcc\x1aP\\$O\xf8\x01\x7f\x93$\x11i\xa5{\xc3Yx\xf3\xa4\xccL\xb5\"\xd8\x83{?\xde[\xbfw\xa6\"\x86gZ\xbfi\xdb\xb2`\x1d\xd0\"\x13MG\xed\xc8\x05\xeb\x8b/\xefYf\x94>W\xca>Q\xd0C\xeb\xf0\xfc\x1c\xf4\xcfY\x12\x17\xe4\xb2`1<\xf9\x9b2\xa6\x7fo\x1a{Hu\xe7Ul\x0b\xc1\x9e\xba\x18_\xd0\x9e\xd8m\x0b\xd33_\x99\x84\x19\x0f\xb1\x81\xac\xaf\x9bg\x1aHaI\x94\xf3\xcdH\xce\xf0\x98\x98\xf1{r\xf5&#\xf3\xf0R\x9a3_\x94\xb8\xb3(\xd9J\x8b\xb2\xe8_\x146\x9c\xee\xb2\xf8XZ\x8d\xad[\xa14\xaci.\xafi\xb7\x98\x02_\xc9\xd66o\xadms\x03\x9a\xc4WD\xa9\xfbs\nq\x19\xaeo\xe8\x15\x0b\xbfx\xcb\xd4\xac\x02\xd8)\x05\xcf\x13\x9e\x02\xcb\xe1\x98xa\xfe\xbd\x1f\x85\xc1ADh\x0d\xda\x0e}\x1f1\xc6 Jb\xf2$\x0e\xde2x\xfe3\xb9\xa2\x1d\xf8\xb0\x0e\xf6ZD\xe7\xcf\xe2\x9e MF\xff\xa2T\x01{\xbf\x0f\x96\x05\x13\x98\xd9\xf8\xa7\x03\xeb`\xdd\xb3\x1c\x0cU\xe8\xb8\"\xf0n\xe4\x98\xc1\xe5\xdc\xee\x0f\xcf\x04{`Y\xcd\x85\x113dq\xb9h\x8d\x19e\xc0\xd9\x10\xba\x1c\x03\xdd\xab\x802\xd2\x88\n\x02\xbb\xc0([\xd8a\xb3\xb2O\x87\xb3p\xa1\xa4\\\x92\x97\x91\x88\xf89\xb1K\xf3\x1c\x96=We\xe3\xce\xaf\xef\xf4\xb9\x14P7 \"\x95\x81I\xcd\xd88\x1a(\xaco\x9d\x8e\xc6\xcb\xce\x01\xa1\x9b\xe2\x07\x01]\x830>;J\xec\xb9\x98\xe8\x8d\x06R\x1dd\xa9W\xf9,K\xaf\xefp\xcc\x81\x0by\x8b\xae9\xeb\xc8>\xe7Iv\xe0\xcf\x16\x93^b\x06\x84-7\xb3\xb5\x96\xa2\xac+\xec\xc5\xabk\xb4 I*\xb7f\x84\xa3\x94\x85\x84\x9aWp\xd4\x8e\xc3\xdc\xc4\x0cK?\xfdH\x03\x9e*\xa8`\xfe\x15\x9e\xbf\xcc\x15\xbb\xc0\x9c\x8f\x8diJ\x96~\xfa<.\x92\x1f\xc2b\xf1g\xb1\xdb\x98?5\xf6\xa3 \x9c7+\xe3\x8e\x0e\xd0\x00\xf2\xd1\xe0\xb2-\xd9h\x8ckU$\x88\x12\xfb$y\x82\x95\xe8[\x80B,\x80\x1a\xa5vRg\xd5\xf0\xa9\xa6\xa2\xce\xf0\xed-\xa9\xa8\xd1f\x9b.\xc2\xc0\x7f\xb1\xfd\xc0\xe9\xb34\x16)U<\x91R\x85B+g\xa3\x86H<\x9b\xdf\xa5I\xda\xa3\x83b\xa7\x17\xfdjY(\x16Epr\xdd\x06\xc4\xe4\x02\xbf\xef$gP\xd0\x8a\xe6Y7R\x85\xd1&1)\x8fm\x8dw0\xc7\x85\x84\xdb*\x1fN\xc5\xfaPv\x92\x16\xa5I\x12\x1d\x86?\xd7n\x9d\xcd5\xa1\x97\x9b9\x9d\x04\xa5 \x92.\x01\xdb\x1d\xb7\x8c\xdf\x06\x9c\x15\x90\xc5`\xc6m\x89\x1bc\xe61%\xe3\x1a{\x01g\xf0}\xfa\xb6\x9a/K\xc7T\xfd\xb9\x07#L\xc6$\xb0\x18\xec\xd1\xbbS\x91\x9bIAZ\xc6\xa4I\x83O\xda\x0bB\x9f\x0e=?p\x0dn\x02\xe4 \xad\xddJ\x80\x0e*`\x8fyl~\xd5r\x80\x12\xe6A\x05\xf7\x9dT\x15\xa0^\xceb\x91\x91\xce\x82\x0e\xb90\xe0\x96\xab\x95\xdd\xc9je\xae\xf0\xcb\xeb\\1\xe2\x19\xbe`\xcax\x1e\x8a5\xeb\xf2\x81\xdd%3\x98\x91\xdcf\xd5\x92;Y\xb5\xa4Z5FM\xa8\x9d\xc0VZ\xb8NB\x88n\x0b\x9a{\x8d\x99k|\xac{m\x9b\xa5Z\x1e\xef\xdeW\xc5\xa2\x8b\xed\x9d\xadv\"]\xbf\xbe\x10c{g\xbb\x13^\xaed\xe5\x0f\x1d\x17,\xaf\x9d\xc6\x95N\xc8\x9aX\x9ax\xc5\n\xc4#\x08-\x0c \xd2\xcdx\x80\xef\x05cB8\x8b\xe4{$\x9f\xf9)\xb1 c\x92&\x18Z\x9e\xe5Q\xb0\xb7v\xdb\xd22\xb8\x990\xae\xa2\x06y\xdc\xccj\"\x84\xc7w\x9a\xb90\xd7\x11H\xa9\x8bq\xf2\x84\xb9F\x1761_I#05\x86\x91\xfd\x12\xacSz\xa2\xfcX\xbc\x12YP\x90|sk\x07F\xbcd,\x16\xab\xd9\xc27X\xd7\x8a\xcb\xe5)\xc9\xe47\xf5\xaa\xf2.\n\xef\x8b/\xf8\xc8\xd0\x15\xb2\"wg\x94{)\\\xca\x83\xb2\x00\xcd\xfbP\xc2: \x05\xb2\x89L\xb0\xe3\xc2HM\x13/0\xc6\xa5\xf2\xc8\x9c#\xb3)59\x81\x18\xd6A\xa1y\xa1\xab\xd2\xe4\xcf\x0b\x8d\x06\xa1\x92j/\x99\xc4zII\x8c*\xbc\xf6r}\xdd\x81\x05\xac\xef\x01\xb1S\xba\x0f\xd3\xe5\xb1\x0b\xe78\x97\xd4\x85\xa5\xc3w\xaf;\x02Ml[\x90\xd8\xa2P\x99\x8d\x10\xf8\xf0\xcf\xfaP\xd8\x95\x8b\xd1\x04\xcf8m\xd7\x13Z\xe6\x0c\xc1\xa0\xf0H\\d!\xe91s\xa9\x16\xe5\x84-\xca\x9a}\x05{p\xea\xc5\xe4\xb2\xb0\x1d\xc7\x0b\x12L\x1d&-\xcc\x15K;#\xad\xcd\xc9\xfa\xba~u\xc4CW\xa9\x7f$\xda\x01\xe8\x17H\x91i\xd2\x8e\xe1\xae\xcdSU(\x92P\xdd\xc1\xca4\xc7\xca\x0e\xc2P\x0e_\x0d\xc6\xd6\x9e5\x01koS\x03\xc1\xd6\x04\x8b\xc7V\x17J\xb4\xf2\x02\xeb\x0b\n\x93\x1d5\xc0\xbd\xe9\xde\xe4\xf8\xdeY\x1fc.5TL\xc9q\xb7_#GY\xc6w\xb3(\x9b8m\xdd\xa2\xec\x8di\xf1d\x95Ea\xcba[\x1e;\xccd\xba\x89\x1az\xbaV\xeco\xd4D\x13//O\x19\x15`\x8f\xd1\x97Pz1r\x1ci5\xed\xbd\xcd\x0f{c\xe7\xee\x17\xb4\x86W\xf5\xd9\xb9\x13\xfd\xd7\xfd]\x87\xc7\xe8\xfc\xc6\x9f\x15Iv\xd5=\xc5\n)\xc0\x84\xa2H\xbfM\xa5b\xd1\xe9i\xc6JOO3e\x85 \xc8H\x9e\xb3:\xec\xb7\xb2ZFx/\x19Qw\x94\x15\xe1,\"\xbc\x0e\xfeVV\xcb\xc3\x80W\xa2\xbf\x94U\xca LX\x15\xfaKU\xe5\x14\x8bO\x95E~\xce\xda\xa7?\x94\x15\x82\x90\x95\x07\xa1\xba8\xe1\xc5\xea\x9e\xc33V\x1c\x9e)\x8b\xa3d\xf6\xfe\xefeR\xf01T\x7f*+'\xc1\x15\xab\x96\x04W\xca\nl\xeb\xd4\x1bwZ\x16E\x12\xb3\n\xf8SUi\xe6\xc7\xe7>\xdb\\\xf6S])\xa5\xe0\xcak\xe1oe\xb5\x90\xcf\x8a\xfePVH\xf8\xd6\xd2\x1f\xea\n\x11/\x8f4\xc5gYR\xa6\xa2\x0e\xfe\xa1\xaa\x18\xf8\x05\x03F\xfaCW!\n\xf3\xa2\xaaD\xffPV\x0cX\x95@YH\xd8p\x03\xa2\x1cn@\n?\x8cr^\x05\x7f+\xab\xcd\xd9\xca\x06s\xe5\xaa\x06\xa1\x1f%\x0c\xa6\xd8Ou\xa5s^\xe3\\Y\xcc\xc7\xa9\x1e&_\x05\xe5\xfc\xc9\x12\x0b\xc9R]xJ\x02^~J\x94K4\x0fI\x14`\xd2\xe7\xcc\xb6\xc4\x1f\xea\x8ag2\x98\xd5\x7fj*\x97\x19\x11\x15\xcbL L\xf3$\xc1\\\xb5\xff\x1f{o\xda\x1d7\x92$\x08\xbe\xdd\x8f\xf5+\x9c\xf1\xaa% \x03\x0c1H\x89\x94B\xa2\xd8J%\xb3[\xdd\x99\x92FRVMw0\x8a Fx0PB\x00Q8xdQ\xef\xf5\xcc\xec\xdc\xf7\xee\\=\xf7\xd9\xb3;\xf7\xb1\xc7\xec\xce\xf4\xf4\x87\xce\xfc#\xf3\x07\xf6/\xecs3w\xc0\x017\x07\x10$\x95U\xbbo\xf1\x81D\xf8\x05wssss3s3Q\x08^\xe9B\xc9R\x16I\xc81.\x86\x90\xbd\x18\x92\x99\xdb\x98\xb9Mf\xee`\xe6\x0e\x99y\x1f3\xef\x93\x99\x0f0\xf3\x01\x99\xb9\x8b\x99\xbbd&\xf7qB\xc4\x8b\xad\x80\x04\n\xbe\x92\x85\xcaU\xb6\xb0\xae\xb1\x85l\x85n![\"\xca\x89\x17\xaa\x00\x92X\x92\xc0\x06\xf3\xc4_\xe2\xe4\xe2+Yh\x89K\"X\x92\xeb!\x88V9\xe2\x1c\xbc\xd1ERY\x80\\\x95\xefO\x10\x90\xefOH8\xbe\xe7\x97\xa7\x1cQ\x15_\xa9B\xa1\x7f\")\x04\xbc\x91E\xf8)\x8f\xf0K\xf8J\x16Bh\x85$\xb8\xc2 z/\xb3\xa3\xf7T\x81\xa5\x1f`G\xc5\x0b]`%\xf3\xc9\x89^\xfa\xc9{\x99\x9f\xd0\x1f\xe0Q\x8e\x05x\x94\xdb\n\x04\x99$%\xea\x07]P\xd2m\xf1b) \xb1\x17\xde\xa8\"\x91\x8f\xa40\xf2IR\x18\xc5\x18M\x19\xcb\xc8\x1fTA<0B1y\xac\xa5\n\xe1\xf4\xd2\xdbU\xbc\xca\xca\x85\xa4~X\n*\xba\x17[i^\x9cg\n\xa7\xf1\x95*\x84\xdf\"?\xb2\xf2\x13\x1fg\x00\xde\xc8\"\xc14StU\xbe\x93\xc5T\x11[v|Zp\x8c\xea\x07U\xf0gP\xe2gTV\x82\x03I\xc8\x91$\x08\x85\x84\x84@\x92\x9f \xcf$^\xa8\x02\xd8/\xb2C\xa9\xbf\xc4\xef\x8a\x17\xb2@\x89:v\xc4I\xf9\xb4\x98N\xf9N\x17\x0b\x15~\xe1+Yh\xe9\x87\x88b\xf0F\x16\x89\xf3d\x8a\x13\x82\xafd\xa1\x95/;\xb4\xf2\xe9\xdedI\x1c!I\xc5W\xba\xd0\xa5d\xe0\xe1\x8d,\x92#\xeb\x9d\xe6$\xf3\x9d\xe6\xcb\xa5\x9f\\\xca\"\xf0N\x17\x93\xf3@\xaf\x97\xcc?\x91\xfd\xc80R,Q\xa4\xe0\x9d3\x1b\xf3\x9c!\xd9\xcdH\x92\x9b\xf1\x8b\xac8\xd2\xa8\x1fdA\xc1[`)\xf1F\x16Y`\xfe\x82\xceT[vf\xdb\xb3\xb3@n\x87\xe2\x85.\x90)x\x887\xb2\x08R\xcd\x8c$\x99Y\xe2O\xdf\xcb|\x7fJ\xd2x$\xf0$u\xcf\x11As\x12;\xcf|\xfc\xf0\x99O~\xf9,\x98qW\xfc\xfa\x9c$\x11<\x0c\x83\x95<@\xcaw\xaa\x18\xae$\x9a5Y\xfa\xa7\x92\xbb\x11oT\x910\x88\xb0\x84x\xb1\x15\xf0\x93_K\xfcY\xc0\xa3\xac(Z&Q\x95\x96~\xaa\xf6\xf1\x94\x9c\xe3\x95\x82\xd0\xca\x02\x9d\x95\x9fe<\x89T\x19\xf1N\x16\x8b\xc3\xcbSI\x00\xe5\xbb\xadX1R\xf5\x83*(\xc6\xe4\x87\x95\xd1V\x93\xc8J\x8a\xb8&6\xd2\x9a\xc5\x92\xc8d1M\xec\xcf$=<#\xe7Q\x10\x85\x82:\x90\x05\n\xa2\x9b!\xd5\xad\x94\xb0\xc8\x88P\x05{\x0b2\xa2\xaa]f\xb5w2\x1a\xfb\xae\x1e|\xac\xd2 eMv\xc3~\x18\xc6\xd7\xf8\xe1\xba\xe95j`)\xfdk\xe4\x0c\xeb\xe1\xb5r\xd9\xf7zq\xb4\xa8\x7fp\xff\xbeeL\x8df\x1f\xcal\xe3&\xf2s&\x8doi\x19\xba\xfa\xcaT\x94x\xf2\xc4\x8f\xe2\xe8r\x19\xe7\xe9\xd3\xa7\x84\xa8tn\x95\xaf\xfah\x99v\xe6\xf4\xe0\x8dB;\x06\x82#\xc1\x98\x9e9\x85\x12\xd5RN\x0c\x17\xca\x15\xe3\xb6\x14Dm*\x14\x95\x8aUKA\xc55\x9f5q\xcd\x0c\x19\x8e@0\x1cg\x8eR\xde\xda\n\x02\xd0\xb1 \xbc\xda\n\xfa\xd1\xe5\x88-\x9cD7\xb3{ \xdab;(_\xcd\xdb\xe4\xdd\xeaQ\x9a\x9c\xaa\x7f\x1fk|\xcc\xfaS\xd3wh\xb7\x9a\\\xdd\x94b\xe6\xf4\xd4U\x13\xf6u\x8f\xf5!8j\xefk\x16\xcf\xcbx]\x98\x91`\xc6\xc2OY \x03\x16\x8b\x9a\xef.W\x9cEq\xe6\x83\x8a>\x88\xd2`\xc6\xd5P\x07m~\xb0\xce\xe4\xbd\xc0\xac\xd5\x99#\xdcn\xad;[k\x83\x01\x93\x9f\x00+F\xc7\xef\xee\xf4CBF\x05f\x16\xc3\x8f\xc5\xf0\xeb \x12 \xc5\xb4\x14\xd3\xd2|\xb5\n\x03>cY\xacC\xcdc\xfcb\xc5\xa7\x19\x9f1?B\xe8\x0c\x08g\xb1\xfa\xd3|Q\xbfP8\x87\xa8p\x0e\xd9\x13-\xc8u\xd8\xefw\x05\x0d\xdc\xd6p|\x8f\x85\x05f\x89\x1e\x8fE\xdfC\xf16\xe9y,\xef\x0091AS\xddf\x11.\xe5\x95\x16\x0e7\x18,ey^\x7fl>T\xe8\xa5\xc8q\x93\xea\xe0Q\x80\xdd|%\xae\x89\xe4|\x0d\xc4\xce?>b\xe7\x9d\x11\x9b\xa5At\x1ar\x8c\xbf \xd9\x80\x9ba\xf9M&\xde\x16^Ja\xe8\xf7J\x887\x1cp\xba\xa6\xad\x0e\xdey\x8e\xf1\xeeN\xe4/\xc1\x98\x95\xb8\x9fC=y\xab}\xb1\xedA\x1c\x1cL\xe3\xa8\xb8;qu\xc5\xaa)\xd0\x9bri\xb7c\x9fz\x94\xd1\x99\xd1X\xa7\x16>\x00\x14\x7f)\x90]\xcd\xa4\xa8\x0e%|(\xf1\x8bCw\x0b\x17\x05\xfa\xafk\x12\xb9\xc6\xbbL\xf5\x07\xd0f\xe9\xf0q6q\xeb\x0c\x86>\x01I9\x01\xb1\x05\xd8\x91IY\x80\xa4\xbc\x8cg\xbc\x95\xa3\xb8 \x0cm$\x03\xf9\xca\xef\x95`\xfc\xc2875\xd6V@\xeb\xbbZ;M\xea\xc6\x81UL\xba6*\xf1\xec\xd7_\xcb\xebpd\xf8\xcd\xd61k\\\x17\xf8\xa5h\x1d\xb6\x18\x90?X\xf8\xe9\xab\xf3\xa8\xb8[\x1ev\"\xfd\xac\x99A\x1b\x00\x83\xd6\x8d5c7e\xcf\xd8/\x80t\xc5\xd1\x1a[4q:\xd0<\xe5\x18\x07\xb4\x06\xbb\xbe\x9b-\xdd\x02A\x8a\x95\xa1{X\xe6\x05\x83\x9e\xeb\x17\x8fm\x8f\x18\xd4J\xcc<\x07\x7f\x1e:\x8c\xdb\x97\xa6Xp\xbf\xf1\xf6\xd5\xcb\x01\x9eu\x83\xf9\xa55\\\x80z\xd6\\i`\x1f\xaao~\x1d\x96Z\x1c\xc1\x8eY,\xcf\xa6\xfd\xf2\x1a\xe8\xf2\xee\xb2\xdd\x9cL=\xb7\x862\x157\x1f[\x8fYV\x99\xe9\xac\xfd(\xa6dAb\xef\xec@\x1f\xa9\x9d!*:\x1e8\x1bC\x8f\x15\xb3\xa7\x9c\x87T\xe6\xa6\x80\xd5\x80\x1d\xd6\x8f\xa5\xb0},\xf8\xf4}\x01\xc6\xd4c'y\xc6\x12>\xe5\xc1\x19\x9f\xb1_I\x99\x9f\xb1 \x9a\xf1\x0b\xf6+\xe9\xa0\xe7\xb1\x13\xf4\xed\x05\xf7\xa4k`\xb3\xcf\xee\xf7\xb2\x04\xa5o\xd1r:\xfc\xf6\xe9`\xda\n\xe2\x9d\xbc\x8f\xeaWX\xd3jo\x05\x81v;QG\xd6\x99\xc6vY\x9f\x96\xa5x{\xeb-]t0\xddT\xcf\x0d\xa7\xf4\xff;\xac\xc6\xd7\xf8\xc5\xaf\xd7\xe44:\x1d\xe0\nfa\x1cv\xc4\xd9i\x97f\x99lz\x0en n\x85\x0f\x99\x17\xa0\x9e\xb7\xd6i^\x12\xdd\x16\xcc\xed1%\xfc\x02BK~oX\x9fv\xc6\xfa\x10\xb0\xbe\xee`\xae\xfe\x18X\x1f\xde\x00\xeb\xc3[\xc7z\x85\xc2>:\x93\x04\xfe\xa9\x8dk)V\xca\\\xac\x94N(-J\xaf`\xa5\xcc;\xae\x94\x8d\xd5zpz\xcf\xe5\x99l\xdeL\x8e\x8f\xa2O\xfdY\xa1\xc2\x10\x195\x9e\x0da\x80\xd7\xf9{L^\x139\x8a@\xd3\x06\xb7J\xc8Z\xfa%\x13\xe5\xa7K\xd6\xef\xb0L\xcf\xe4\xa5\xb2\x95\x93zln\xae\xf6y\xb7\xd5.\xe0\xb6(\xc0\xb6\xf8\x05\xadc#\xf5\x83vE\x92\x99>\x87(\xfcQR+y\xfd\xef\xa0pR\x7fu\xc5\x86\xec\x1ed\xc0K\xc6F\x8c\xc3\x85I\xb8\xed\x07\x0cZ\xa5\xb5\x0f\x96o\xcfhJ\x02\x17g\x97J\"\x81\xe8\x84\xe2=\xf0\xd8\x1c`\x92\xa37\x1ep\xb1\x13#+\xfa\xdc\x0f\xc3 :-D\x0e)\x83\x95\x03\x8e\xb9\xd9,H\xf84\x0b/Y\x90\xb2(F65N\x04\xd18\xb9\x84\xc0*_\xaf\x92x\xb5)\x88N\xfa5[\xf9\xd3\xf7\xfe)\x1f\xb0\xafR\xce\xbe.\x1a\x1c\x00\xc3Z\xfct\xdc\xaf\xc5:\x9b\xfaa(\x9aX\x0e\xd8\x1b\xee\xcf\xd82N\xb8\xe0\\\x17Y\xb6\x1a\xdd\xbb7?\x19,\xf9\xbd<\xe5\x9bP{\xb3\xfc\x8eu\x91hx(f<\x19\x07\x13v\x007+\x8b\xcb\xa1*\x0d\x89\xc4\xbb\x05/\xcf:\x15\xa2\x19\xa4`\xe5(\x18\xef\x94%\xfcgy\x90\x80TQ?O!\xdf\x1dd\xa9$\x067b\xdc\xa9\xe0H\xdb\xa5k\xa6+\xe61\xbc3\x92\xa1\x0d*\xb4^\xba\xd6B\x1co\x10\xd7\xdd\xd5#\xc6\x10c,\x91\xa4\xdbm\xee\xa4v\x9b\xbb\x8b\x10\xe11\xdb\x80\x10\x91A\xed\x16ucMV\xeaBb\xbcB\xadM\xe4\xd0\x0e\x9a5nvS}\xea\xc8\xf5\x82\x17\x9f\xae7\xbbAx-\xf0cc\xe9\xf8\xe3\xe1\xa4\xd3@X\x17\xd9\x8e\x0d\xa3\xa5[\xd8\xf6\x05k~\xbf\xeeu\x96&s\xa7\xcdWL\x95\x9e\xc5\xba?\xd5\xe5\x85\xec\x80I\xbb(\xe0\xfc4\xf1\xfa\x1b~zx\xb1*\xef\x81\xf7XGG@\xf2K\xca\xf4\x08\xaf\x9c\x82;\x89\xb7ZJ6\xee\xfd\xea\xaf*\xd7\x1b\xef\xfc\xd3\x1e,\xe0\x16k\xb2L\xef &\x9bpD\xa7W\xa2\xe3\xaa\x07\xf58r6\xe0^\xda\xddwiN\x98a,\x05\xb5+UZx\x07\xd9\x84\xbc\x9a\x9bSR~m8\x01ht\xb0T\x99\xa1\xcf\xfcL\xfb\xfa\xcc\xcfx\x8f\xc6J\xa3&\xcemY7\xe1\xa7\xfcbE\\1\xb6\xa1Q7x\x9e4#+-\xd0/v\xec\xe6\xad\x1a\x91\xb6i\x1bn\xdd\xf6\xd4\xe8\xfd\x088\x9b\xc6=\xb4y+\xc620\x03M\x05$\x98;\xf4\xa8\xa9C]iL\x9b\xd3\xb7\xea/YIs>\xc9\xf6Q\xc5V\xa6xl^;\xa9\xb0}\xc1J\xcf\x07z\xc2\xdc\xd3\xa4b7\xf0C\xd0\xe4x\xa7P\xe9\xdfR\xfb\xbd\xe1\x83\xc1\xee@z\x1e\xb8Vkg\xa5\x8f\xe9\xdd\xfb\xee\xa0\x88\x98@Y\xf3\xb6\x19\x1b\x07\xb2\x9d\x07\xa4}\xef\x83\xfb{\x16\x83]\xdfQ\x92\xb9\xdb\x18\x87aG\x8c\x9d\x1fn\xd3n\xa3\xeb&\xca\xa2\xb3\xbdep\x11Di\xc7I\xad/xuf\x19\x13\xd2\xc3\xd4j\xef\x8b\x9f\x1c\xb1\xdeg\x87\x9f\xbfxyx\xfc\xe5\xb3\x97\xbfe\xf1\xad\x90f~\x16L\xbb\x95])\x0c\xefTZ\xfaS]\xa3\xc2\"\x08g\xcf\xd7\xadu\xca\xb3\xcf\x90\x1a@\x84\x9dj\x9d\xe3/\x0f\xdf\xfc\xda\xe1g\xf6\xaa/\xa2 \x0b\xfc\x10\"\x17\xadY\xf5\xb9\xd6\xddu\xaa&<\x82\xbb\xb4\xaa\xc6\xab\x97\xcf\x0f\xad \x94+\xe8\xc7A\x18~\x89\x8eK;\x80\xa4\xa8\xf6Y0\xbbF-\xf1\xb17\xa8($@j\xc3\xa3E\x9c\x0bp\xc86\xbeZ\xcd*\x10\xed:\xc8z\xbd.\xfd\xfd,\x98]\xa7\x1a|.Zv\x86\xcfW/\xdf>\xfb\xfc\xf0\xf8\x9asB\xd5^\x1b\xc8T#k\x0c=\x87\xa2\xc5\x1c\x8dX\xef\xd5\x8f\x0e\xdf\xbcy\xf1\xd9\xe1\xf1\xa7\xcf\xde\x1e\x12\xbc\x8f\xd9Nh%:\xb0\x10\x93\xe0\x8c\xcf`5}\x9e\xc4\xcb\x86\x15\xd9\xe5[S\xeb\xb7fA\xba\n\xfd\xcb\x97p\xe3\xbb\x13G\xce\x80\xf0j\xf5X]\xac\xab\x1e\x8b\xd6H\xd1\xd4\xce_\x13\x1cgK(\xb9B\xed\x11\xa1\x9a;\xaa\xb8a\x8b\xfa}W\n\xb4\xc7\xd1d-\x15\x17AJ;\xf7\x9b\x0f\x8c\xda\xe2\x88.C\xa6\x19y\xa4\xabP\xd6\xd0\xb5k\xf7\xca\xd2\xa1\x1b\xf4\xc5\xd8;\xd6\xe8N\xad.8\x13\xaa\xa7\xed\xb3\x85c\xa4B\xcb#\xb2\xf4Z\x08\xa9\xed\xc6kt{\xa5q\xa9\n\x84E\xda\xba\xf0+\x98\x87\xce\x1d\xd8\xe8^\x94u[C\xac\xba\x8e\x82\xa8\xbdU\xf5(>\xaf\xdd\xa6_=\xd0\x9f\xba)`\xd4\xd9\x14\x90)\xb1\x97\xe0\x16A\xd3\xd9\xed\xb3\xe2 \x9c\x8d\xd8cw\xc1\x88\xf6y\xe8\xa7\xe9\x88\xfdV\x9c3\x1f\xf4!\x19_\xae\xb2 :eY,C\xcf0\x9f%<\xe5\xc9\x19\x9f\x01\xa6\x88\x9ez\xec\xeb_I\xbf\xf60\x16>n\xd8\xd1\xd1\xdd\x8c\x9dp\x06\x11\xf2A\xb4\x0b3\xdac\xef\xf9\xe5\x80}\x86M\x05\x19\xf3S\xe6G\xa5\xc1\xb4j\x11R\xb8?{,\xca\x9c\x07a\xc8\xd2L\xfc=\xe1\xcc\x9fNy\x9a\x06'a\xd1\xb8n.~\x97vRo{\x94\xd8\x0b\x80\xd6A\xea\xa5\x1e\x90~\xad3;L\xe3\xb9Cs\xa2\xd9\x01\x0b\xc7\xd1D\xca\xe9\xbb\xf7\x83\x95\xa7\xcb\xc0\xa1\xb6C\x10{\xe4\x1e\xebu\x9e_1\x95\x02\xb2\x97q\x9eh\xb6\xc2\xa0 \xcb\x16~\xc4\xe2h\xca\x07\xec\xdd\"H\x05\xe4\xe7a0\xcd\xd8\xd2\xbf\x14s3\xcb\xb9h\xc9\xc7Mm\xd0C\x07\xc8gq0s8\xc6\x95_\xc0\x8b\xc7\xa8\x80S\xb6\xa7Y\xff\xab?\xf2#\xb4\xc7\xe5\xfa\xd3\xde\xac\xbd\xc4\x07\xa42\xeb\xd04?\xcf\xe2\x93 \x9aU-\xee\xd7PA\xd3\x81u\x98f#\x98\xd6\x11+\x13\x88\x95\x8e3;b\x9d\x10U\xee\xdc\x11\xc8Te\xe1\xd0Ml\x05\x8f \x12\xc2\xdc\x9fr\x1bB\xc5g`\x87Q\x9a#\x86eXj\xc9\xb3ENDg\x9f\xe5Y\xfci\x10\xcd^\xfbAb\x89TY\x8dR\x19\xd5\x97\x99\x0f\xcbl:@\xee\x1f\xa6T\xbe\xbb\xa4\xbfw\xf5\xc0\x1c\xd7\x1bC\xbb\x8a\x1cC\"\xb6\xedJg\xf2^h4\xce;X\x8e\xad`\xd8\xc6\xf7\xda\xf5\x80sg\x85!w\xa6fm\x97M\xc7\xf9D\x0c:li\xa9\xc1\xef\xb3\xfe\x881\xcd(\x02\xd8\xd6S\xd6d7\x0d\xc6+\xe0\xac{\x05\xb7\xdc\x86H*\x06\x8a\x92w\xdb\xc1\xc0P\xbfmR\xf4\xe7L\xba\xcfN[\x03\x96\xeaO\xe0\x80\x13q;\x13\xb0\xac\x13@\x99\\_\x81_E\x85\x11\x81 \xd1l\x15\x87\xc1\xf4\x92\xfdJ\n(\xfd\x9e\xc3\xeb\xf9\x82G\xb8\x02O\x81\xdd,\x96\xa6\xa8\x02\xc4x\x89\xb3\xdf\xd0\x9d\x03\x96`\xe4\xd2\x85#^\x042\xb0\x11\xd5C\xf4\xe0\x8be\xcf\x8a\xb2\xdd\xa0/\xddA\xcb\xda\x1d8+(\x1ec\xd0\x93\\|\xc7+*7\xd6m\xe0\x15\xcc-\xbe\x13\xa1\x9fY\xf7\xfb\xea\xb1$p\xa4AY\x83\xaf~\"=\xf3Xo\xc9\x93S\xaeB\x1c\xbd\x8c?\xcbW\xa1\xd8\x90\xf9o\xf2\xcb\xd4qG\xec\xb9\x1f\x89m\x17\x8a\xb1(\x8e6\xb1\x99\x14\x08x\xe62\xe2\xc8\x82Q\xca*:=`\xf8Z\xbf\xf5.\x91\x06-\xf8\xb5\xec<\x96\xf4;\xc5\xed^p\xfa\xa9\xbf\xe4\x18\x06]l\xbd\x9dv\xd6\xc7\x02D+\xf0\xf0*\xf6\x044\x92SE\xa7~\x9eJk\xb2\xf3\xb8.\xb6u\\\xb1\xc5\xd5\x0e\xd3\x8e\xab8\x0e\xc9w\x8b\x15P\xe9\xa7\xd8\x1c\x17\"\xf5=\xbfL\x15\x0b,\x19S\xcb\x0dUeB\xd8 -\x16m\x96\x88:{i\xdd\xf70\xb04F\x83\x15\x10\xf1\xcaH\xb2\x96{\x8e\xe2\x81C\xad\xa5\x96]=\xaaL\xe2\xca{(I{\xe1\xd2\xd6#\xb2\xef\xde\xe0^\x98\xf0\xd5\xcc4\xa5\x9b\x13\xe3\x14\xc0\x0b\x1dV\xa4\xdbz<\xbb1\xe0\xad\x00\xb7\x02\xf5\x9a]]\xb6\x1e\x1524\x9e\xa3\x94\xc4\n\xec\xb5/\xd5[1C\xd1\xa9\x87P\x13\xb4\x82\x86)\x83\xd6\xe3\xe3 \x85J`\xe3\xb7\xb1E\x96&H\xaa\x89\xb4\x97\xed\x1d\xac\x88\xea\xaf\xddG\xda\xde\xa5S\x1fO\xac}\x94\xfe\xc1\xa5\x02\xa9\xb3p\x0b\xfa\x87\xf2\xf8d\xc0\xa3\x9f\xe5<\xe7o\xb4\xa6$\x86\xad}z-\x06\xdc\x11N\xca\x16g\xa3\x0e\xb0\xeb\xc3\xea\xd8\x1e\xd6\x97iF\xa2\xce\xb1\xaeT\xd7y{vB\x90\xb6\x12\xb2M\xe42\xab\xa9T\x93\x06sPV\xa2\x89yXP\x91\xd7\xee\xdc\xe9\xf0e\xf5T.\x11r\xb2]\xcf\"\xeag\xfd}\xb6\xdd\xd6>\xab\xc9,\xdb\x8f\x05L\x9e\x88\xb2q\xc4\xfal\xd8\x81O\x85\xe0\x0b\xfbH\x99\xe2\xeb\xfaA\xf8\x00\xe8\xab\"\xda\xad\xa4t\x9b[C\xe7&|\x0e\x0e\xc4\xbc\xca\xbaP6\xeaQi1\x9fq\x19\xcb\xc7>\x90\xc2\xcaWT\xa9\xb1\n\xec\x80Lv\xdcV\x81^\xe0\x10\xacY\x0evuUs2`\xa6\x7f\x85\xf8\xc4\x88-\xc5\xc9W\xa2\x7fq]]\xf0.\xe2\xd3=\xb1\xb9\xe8\xea)q\n@~_P\xc14\xd0\x14w=\xb7\x06\x91\x9c^\xad-'\xde\x04\x84\xe5\x15c\x97\x88\x9f\xb3cOO\xac\xf8\x10\xc1h\xc8Z&\x85\xe22\xa8_>\x90!O\x9d\x95n\x00\x9e\xb9\xae\xc7VN\xe6\xb1S\xf5\xc2\xd5\xcb%\xec\xb0u\xb5\x08\\EP\xc1\xe6\x0bMI\xbd\x98\xe3\x82\xacB\xef\x1c*\xda=\xd6\xc3\xc0\x07pnr\x06\x83\x81`\x98M\xd1\x16NO\xb0\\\xa15\n\xf3\xd9\xd7\xd8\xc0\xd7\x92\x93\x04f:u\xf5\xf1\xcb@%N-I\x86\x9bj\xe4w\x9a,\x93n`\xd0s\xd6\x12\xd3\x0c\x0co\xca\xe2\x91cs\xe6g\xa7zr\x00F\x0cg\xee\xca\xe0\x96\xc3\xfb;\x10\xdd\xf2v\xc7\xb3\xbdG\xdb\xe2)\x1b\x00\xb1\xd5\xc5.Ek\xfd\x12*5Z\x0b\xc1X\x1f\xeby\x96#$\x8f\xf2%O\xd0\x01\xfe\x86%\xd0\xe8)\xef*]Q[\xf3\x80\x96\xb5\x13b\x82\xc6\xbe\x07\xdf{\xbf\x83[\xe9\xb7D\x93\x8e\x9d'\x1b\xcf\xea\x08\xc4\xf6\xd9\xd0Bv\x18uz\xb8\xc1\xfao\xa3E\x80\xb7\x9e\x14A\xe3M\xa3*\xca\x927\x95\xe0&\xf5 >Iyr&\x86.\xce\xdcp\x0bXK\x1a\xc9\xa0\xbc\xe2P\xad\x12{\x10\xd1]+\xb4\x8fvr\x19:\xc7\xd6\n\x92;\xf0\xf7\x02\x91\x8a\x80\xc7\xf0\xcf\x00Bn\xa4\x98[\x8fYP\x11\xf0\x04\xb4\xcb\xa2\xb3\xc2)N@\xc8f\xb6<\x1a\xc4|\xecO\xf0\xe2\xa7xA\x07G\xb6\xbd\x8ai\"\x11\xbd\xc7u\xeb\xab-\x93\xd8\xa6\x16F\x8a\xe6\xbc6:\x08\xca\xaa +\x04\x04E\xc5F\x91\xe9\x99\xe6a\xabY\xf2\x85\x07C\xec\xbamm\xeaO\x06\x1e\xc7\x04;\xfb\xe2\xe5\x8bw\x8d\xc5?\xb4\\Q\xd5No\xb1\xcb\xb2E\x12\x9f\x83P\x05n\x119w\xdf\xf0Y>\xe5 \xeb\xdde}\x96\x81\x1b\x90\x9e\xc4`>c\xc5V\xc9fy\x82*[\x90 \x05\xdfH\xe3\x9b\x17sT\xaf\x81\xd8g\xe5\xa7)j\xe2DZ\"[\x0e\xd2\xb2\x19\x8f]\xc69\xca5\xf8\xc5*\x0c\xa6A\x16^\x16\x0bf\xc1U\xfb\xd8\xe0\x80\xbd\xab'\x81\xfe-\x8a\xc1B\xb0h\x15\xba!\x1a\x9e\xc5\xd1\xdd\x8c\x9d\xfbQ&:\x91\xf2\x8c\xf9\xd2\x01\x81X'\xa0\xbf\x93\xbd\xc2\x8eL\xfd\x08\x0c?\x80\xb9\x91\x86\x83,\x9ek-7\xb9\x96\x11\xd3\x1f -\x10\xad^\xdc{\xfd\xe6\xd5\xa7\x87\xc7_\xbd\xfc\xcd\x97\xaf~\xfc\xf2\xf8\xd9\xf3w/^\xbd<\xee\xb1>\xfb\xd2\xcf\x16\x83\xc4\x8ff\xf1\xd2q+\xa1\xcd\xb5\xe0\x9e{\xee ]\x85A\xe6\xf4z*\x80o\xe3\xe7k\x93\xdb\x15\xbd\x10\xb5\xe8\xed\x86\x01>\xdd\x00K@\xbb\xbfJ\xe2\x13\xf1\x1ed\x0b\xe63\x1c6|v\xc0>\x83 \x12\xcb5\x8b\xd9\xc2\x8ff!z\x99P\x98\xce\xfa\xec.\x8b\x13\x16g\x0b\x9e0\x1f\xd6 \x88\x18z\x08\xe1Ozh\xd6\xb5\xf2\xd1<\x8a_\x82\x8d\xd54\x06/\xa3 X\x96\x06g\x80:\x85yO\x81q\x1a\x9aM\xf3$\x01\xa3\x03\xc0)\x81\x1c~t\xc9\xf2\xe8}\x14\x9fG\xea\xbb\x1e\xcb\xa3\x90\xa7)\x0b\xb2\x1a\x12\x07\x11;_\x04\xd3\x05\xde \xa4>PAZ\x8f%\xfc\xd4Of\xd0X\x8c+\x06\xbf!\xc1\xd2\x0d\xcd\xd1\xa9\x86\xc0\xd9\x13D\xd9\xc1]\x8b&\x86\xd0\xfe95\xd3\xa0\xca\x01\xd3(\x0e\xc2\xf1\x06\xfa\xddEo)\x96\x87\xd83\x0b\x9d\xa4\xd2`\xc6\xb2\x12\x14\xc9\x80\x8f\xb2\xf8*/\xbd\xbc\x88\xceb4\xdcz\xed'>\x84u\xff\xb2\xf0\xb1\x9b\x15\xac\x84\xf4\xf4@\x124\xf0\x16$\xb6\xae]\x97\xd8\xbbD\xd6\x83]#+(\xb2\xf6\\\xf2X\xeb[\x95\xba\xd2v\xa4\xb2\xfey\xf3\xfa\xb7\x1e\xc0\xb5\x05_\x1bj\xa2\xe6\xd8[\x0bd\xb1^\x8d\x82\xff/1\xe9\x15\xbds\x04\xe5%\xa61P3L\xcdU\xf0}\xcf\x15E\x9c\xed\x8e\x9f\x82\x1a\x89\xa6\x0e\xb5\x1b\x81\xa4\xb9\xa5'\xbb\xb7Y\x9cp6\x8b9zc^\xf8g\x1c%\xf3\xc1L\xc9\x1c\x06\xecK\xff=g\xf2*//#\x8c\x94J\x85\xfa\xe6\x1b\xa4\xday\xf7|\x11\xa7\x1c\xa7&\x05\x99\xb0l7\x1d\x10\xc1k}I'\x0b\x14s\x0d\xed\x13\xba\x0d-\xb6\x84\x17\x19\xaaM\x07A\xaa^\xf5\xb8.\x85\xbbd\x1f$\xd8A\x8aB\x91\xe2\\\x9e\xd5\xa2\xa2\xa8\xc1e18&\x88*\x81\xdf^,\x979\xc4\x83/\xbeZ\xdec\x9a\xc7a\x18\x9f\x07\xd1\xa9rx\x10\x80S\xaa\xbb\xac\xcf\x02T\x1a\xdc\xedy\xacw\x17eL\x83\xbb\xe6\xd8\xe1\xc0%f\xef-\xff\x19(#\xf0\\\xe8\x0e\xe6A\x98\xf1\xa4\xe5\xa8 \xc7\xbba\xdc\xdf\xaa\x1da\xeaZ)Y/\xd7e\xc0\x07\xac\xa7]\x19\x04\x81\x04^\x94,J\x1d\xb0\x9e\xf2\xeb\xd0c\xa3\xe2G\xc0S\x14\x97\xe1\xc0ss\xe0l\x1e\xe7\x118\xa5\xbe\xab&E\x03\x7f\x16\xb3y\x10\x15a\x83\x04\\Q\xf0\xaf\xe4_\x853 \xbcC.\xc5\x1a\x0dp\xd6\xef>\x96\x9dD\xff\x13'\\J\xeaf\x83\xbbuw\xca\xb7\xbf\x1b\xde\x1aE\xf3\xd6\"\x0euo\x9c]tH\xa4d\x13UH\xa0\x1a\x12X\xaed\xa7\x97+)\x0bEQ\xe7\xad\xc8?\xeb\x02(M\xb6y+\x13\xa4W\xacB\xab\xa0\xd0b\xd7\xae\x07\x00/\xe7\xa9:#]>\x199\x8fP\xc4\xfd\xe8\xa1[\xedy\xe4<\xd8\xdb\xead\xe0Y\x1e\xa1\x87\x86\xafC\xe9l\xf0\x91\xeb\xf4\x8a\xd8\xe0\xa4\xad\xf3\xde\x96\xc5\x8a;r\x86\x0f\\\x8d\x8a\xaeq*\xb0\x1d\x084ER6\x8e\xd1c\xad\x16\xbb\x1c\xee\x14@4\x81:\xcdJ\x1c]~\xd7 \xc0\xcdV\x86\xf7~\xe2\xfc\xca\xf6\xd6\xd5Q\xea~\xe2\xfc\xd4?\xf3\xd3i\x12\xac\xb2\xab\x99\x9f\xf9\xee\xbd`i\xc2\xf2\xde\xf8'G\x17\xdb[\x9bG\x17{\x87\x93{\xa7\xf5\"\x01\xb69\xfe\xc9h\xd2wG\xf7N\x97\xe6qk\xdc\x1b\x08Bt\xaf7\xa1\xe1]\x05h\xeaGA\x16|\xc3\xbfJ\xc26a\xd5\x99\xb4\xb5\xf1\xe4\x8e!\xaf\x95\x89cA\x8fRKw\x12\x10j\x05\xfd\x010\xec\xaf\xe6\x0e\x1foM\\\xf6\x94m\x12\xee\x97\x9d\xdc\x95&\xe7N\x04\x12\xc0\xa5\x9fM\x17N\xe0\x8ad4\xd9\x11\x873\x96\x0c2\x9ef\xe8\xb6\xa4\xe7\x9f\xc4y6: \xfd\xe8\xbd\xd86r\xb8\x1d\xae'V\xbe\xb3\xa6\x15e\xb9<\x1e\xd8\xec\xff\x1f\x0e]#\xdci\xc3f\n.\xa2\x07Y\xfcE|\xce\x93\xe7~\xca\x1dpG\x02\xfa\xa3\x03&\x90\x94\x8d\x0c\x1f\x1f\x96\xe5\x15\xaf7\x84]\xca\x9e>r\xb6\x1f\xda\x96\xaf}z\x95\xb0\xdbI\x1c\xeeVG\xb3\xe6\x1a+\xbb\xb7W\x17]|/\xa6\xe4`H\xdelF\xde\x0d$g\xff\xbf1y1\xc7\xf5 \x8e\xba\xd9\x8cw\x03t!d\xb9\x96\xe5\xb8\xbe\xa2)\x84\x13\xeb\xc1r\xa3g\x8f\xf2\xaf\x0b\xcb\xea\x9aCh\x96\xf5\x80\xc5\x03\x19\x94@\x814F\x12\x18 \xd1\x90\xe2y\xa34\x93\xa8\x0e\x96\x91hd\x91\x0d\xa6\x0b?y\x969[\x16%L*\xcb'N\xe4\xb1\xa1\xb2P\x82\x08!\xd9 \x0d\x83)w\x1a\"\xb0\xe4c>\x01\xc5wU\xd8\x7fm\xda\xbb\xfd\xb0\x1d\xc4\xf6cl\x0c;\x9a\x14\xdf\x93\x98T,2\xe9\x02\xea\x80\xc5\x82w\xf7\xd8\x06\x98\x01D\xec\xe9>\x8b\x95Ux\xf1\xa9\xeb\x8e\xe6\xc1^\x9d l\xc1\xbb\x9b\xd0g\x8e\x08\x02\x97\xb4\x92\xf6\xc5b\xe3h[\xbf\xc4Ks\xb65>\xa1\x10\xb97>:\xcag\x0f\xb7\xb66\xc5\xff\xf9|^\xbf\xf4\x96\xa8B[;Xhkgw~t\x94\xcf\xf96\xfc\x9c\xf3m\xf1s{k\x06?\xb7\xb7\xcc&\xe0\xc6\x00|fg:\xc6\xcf\x9c\xd8>\x07\x86~\xe3\x9f\xb4t\n.\xf49\x07#\xbd\xd1\x19\xdf\x85\xe2\xb3\xf9|\xe2\xfe|\xfb\x03y\xc5Oo\xf7d>\x9f@\xc2\xd4\xfe\xa1T~\xa8\x08\xe1sU\x84\x01r\xc5[\xef\xa0V!T\x9f\x99\xf3-\x8e\xff\xe6\x93\x03\x15\xe1\xc9\x91\x9d\xde\xde\xda\x9a\xc9V\xc7\x18\x93)\x9f\xc8\x95~\x85A\xe2\\k\x1b=\xf7\x93\xfaY`\xaa\xf5r\x1c\xa8\xae\x1e\xf4\xf0\x1a<(\x08\xa3z\xfb\xb5~\xcf\xd9\xbe\x0c\x8c\xe0\xc0\xe8\x9c\x83\xfdr\xa40\xe8)F\x8a\xec\x9d\xf6\xae\xbb&\xb8\xe4*\xe7p_t<\xb9\xee2\xde~hc\x08m\xcb\x98\xf2%/G\xdb\x1b\xdf\xfdo\xbf\xf3\xbb\x93\xde\x8dF\xd6\xbc\x9d\xa8\xdd\xdd \x1c\xb1o\x14,\xbe\x0f,\xbe\x0b\xce\x1ez\xbd\x1b\xdd9\xd2h\x9c\x058\x06\x0b\n\x87\x9e\xf1\xd1\xc5T\x1c\x8bf\xbbG\x17\xb3\x87\x9bG\x17\xf3\xdd\xa3\x8b9\xbc\xcc\x8f\xf2\xad\xa1X\x19\xf9\xd6po>\xb9w\xda\x00\xc2u\xc9\xc3M`\xed\x80\xd0\x1a\xa4\x82 \xa9U\xd0\x0c<\x96\xd4a{} \xdew\x9d\xea\xd7{\x7f\xf8;\xbd\x11\xeb=\xab\xad\x9b\xde\x1f\xfe1:\xf9\x8f\xd3\xc9\x7f\x82N\xfe\x1f\xe8\xe4?I'\xffC\x91\xec\x1b\xc9\xff\x88N\xfe\xc7t\xf2?\xa1\x93\xff)\x9d\xfc\xcf\xe8\xe4?-\x92\x9f\x1b\xc9\xff\\$O\x8d\xe4\xbf\"\x92\xeb\xde\xf1{\x7f\xf8\xefD\xf2\xccH\xfe3\"\xb9\xee;\xbe\xf7\x87\x7f\x96N\xfest\xf2\x9f\xa7\x93\xffg\x91\xcc\x8d\xe4\xff\x85N\xfe\x17t\xf2\xbf\xa4\x93\xff\x82H~a$\xffE:\xf9/\xd1\xc9\x7f\x99N\xfeW\"90\x92\xff5\x9d\xfco\xe8\xe4\x7fK'\xffU\x91\xfc\xd2H\xfe\xf7\"92\x92\xffG\x91\xfc\xcaH\xfe\x9f\xe8\xe4\xbfF'\xffu:\xf9o\xd0\xc9\x7f\x8bN\xfe\x0f\"96\x92\xff#\x9d\xfc\xbf\xd2\xc9\xff\x1b\x9d\xfc\xbf\xd3\xc9\xff\x89N\xfe]\x91\xfc\x95\x91\xfc\xb7\xe9\xe4\xbfC'\xff]:\xf9\xff\x14\xc9\xb9\x91\xfc\x7f\xd1\xc9\xff\x99N\xfe/t\xf2\xdf\x13\xc9\xf5\xd8\x01\xbd?\xfc}\x91|i$\xff\x01\x9d\xfc\xa7D\xf23s9\xfc\x9eH\xf7\xcd\xf4\xbf/\xd2\xdf-\x8c\xf4\xff*\xd233\xfd\x1f\x88\xf44\xad\xa7\x7fK\x93\xe5oi\xfa\xfb-Mh\xbf\x05\"n\x90\xb7o\xff\x04\x9d\xfc'\xe9d\x80\x80A\x0c\xbf\xfd3t\xf2\x9f\xa3\x93\xff\x02\x9d\x0c\x84\xd6\xa0\xa8\xdf\xfeY:\xf9\xcf\xd3\xc9\x7f\x91N\x06\x12d\x90\xe5oij\xfd-P&\x83Z\x7f\xfbW\xe9d \x13\x06\xfd\xfd\xf6\xaf\xd1\xc9\x7f\x83N\xfe[t\xf2\xdf\xa6\x93\x81\x04\x19\xf8\xf6\xed_\xa7\x93\xff&\x9d\xfc\xbbt\xf2\xdf\xa1\x93a\xcd\xfe\x9a\x91\xfc\xf7\xe9\xe4\x7fH'\xffc:\x19\x16\xe7\xa9\x91\xfc\x0f\xe8\xe4\x7fD'\xff\x13:\x196\xfb_7\x92\x7f\x8fN\x06\x1e\xc0X\x98\xdf\xfes:\x19\xb6Xc\x07\xfb\xf6_\xd0\xc9\xff\x8aN\xfe7t\xf2\xbf\xa3\x93a\xfb66\xb6o\xff%\x9dLo\x9a\xdf\xd2\xbb\xe3\xb7\xff\x9eN\x86\xed\xe47\x8cd\xd8N~j$\xc3v\xf2\x9bF\xf2\xff!\x92\xdf\x1b\xc9\xff\x89N\x86\x9d\xe0\x0b#\xf9?\xd3\xc9\xbfO'\xff\x01\x99\xfc\xdd\x1f\xa3K\xc3.\x13\x1a\xc9\xff\x85N\xfe\xafd\xf2w\xbfC'\xffq:\x19H\xaf\xc1\x8d|\xf7'\xe9\xe4?M'\xff9:\x196\x01\x83\xa5\xf9\xeeO\xd1\xc9\x7f\x86N\xfe\xf3t2\xd0o\x83I\xf9\xee/\xd1\xc9\x7f\x85N\x06Bm\xf0\x17\xdf\xfde:\xf9\xaf\xd2\xc9@c\xdf\x18\xc9\x7f\x83N\xfe[t2P\xcd\xc4H\xfe\x9bt\xf2\xef\xd2\xc9@\xa8\xdf\x1a\xc9\x7f\x97N\xfe\xfbt\xf2?\xa4\x93\x81\"\x1b\\\xc1w\x7f\x8fN\xfe\x07t\xf2?\xa2\x93\x81\"\xbf3\x92\xff)\x9d\xfc{t2\x90\xde\xccH\xfegt\xf2?\xa7\x93\x81\x98\x1aL\xe1w\xff\x82N\xfeWt\xf2\xbf\xa1\x93\xff\x1d\x9d\xfc\x1f\xe8d\xa0\xb1\x06\x0b\xf9\xdd\xbf\xa4\x93\xff5\x9d\xfco\xe9\xe4\x7fO'\xffG:\x19H\xef\x8f\x8dd \xbd\xe7F2\x90^\x83\xc7\xfd\x0eH\xaf\xc1\xcc~\xf7\x9f\xe8\xd2@z\x7f\xdbH\xfe\xcft\xf2\xef\xd3\xc9@L\xbf1\x92\xff\x0b\x9d\xfc_\xc9\xe4oav^\x98\x1b\x0f\xc0*0v\x9e\xef\xf0\xb8fp.\xdf\x01\xb3\x14\x9b\xe9\xc0X\xde5\xc9\x1b\xec\x1bi\xa9\xd9\xb5)Hi\x8f>\xd7\x16rw\x12\xb0\x11\xce\xd4F`\xa3[\xa9p\x03\xc9Z=\xf6\xa3\x12;R\x96\xdf\x84\xc4M\x9am?l\xf7\xbcG\xabT\n\x0b\xc5}\xd0+x\xba\xea\x04u\xf4\xfa\xc0AA%\xd5\x10~\xa9\x86\x80\x00T(\x87\xcd\xba\xc9a)\xb5\x01\x18Tlmm\x1e]l\xcf\x8f.v\xfc\xcd\xa3\x8b\xfb[G\x17\x0fN6\x8f.v\xb7\x8e.\xf6\xc4\xcb\xde|\xd2\xbfw]%\xa3\xeadt\x93N\xfa\x9b\xdfL\xc6\xcf6\x7f{r\x05\x7f\x7f\xbe\xed}\x80\xb4\xab\xf1\xd6\xe6\xa3\x89x\xc5L\xf9\x02\xa9W\xe3\x9f\xe0\xcf\xad\xcdGlr\xef\x9a\xdd\x8f\xd0Pb-\xb5O\xa1\x939:\xba\xf0\xa7GG\x17'\xc3\xa3\xa3\x8b\xd9\xde\xd1\xd1\xc5\\\xfc\x01\x01\xab\x008B\x1c@\x8e0\x07\xa0#\xd4\x8f.NP\xe0\xba%\x05\xae\xbbsvt\x94\x89\xea'GG\xa2\xae\xbf\x05r\xd9\xf9\xfc\xe8(::J\xa0\xd0\xf6C\xfc\xf7\xe8\xe8(\x1f\xee>\x14%\x86\x0fA\xf9 \x1a\xc2\x7fC\xfc\xb7\x8d\xffv\xf0\xdf}\xfc\xf7\x00\xff\xed\xe2\xbf=\xfc\x87mn=\xc2\x7f>~\x01;\xf7@\xfc\xdb\xd9\xda\xda\xaa\x11\x18\xd46\xf5X\x9fE\xac\xcfz\x16M\xd2\xac\xdf3\x17\x1cH\xa1\xb7\xf7\xe4\xb0\xf7Nh\xa5\x91\x98j\x01\xd4\xb9\x80\xd4|\xf7\x08\xa5\xddG\x17\xa6\xea''5Q\xaak\xa0\x18\xa9}\xd0\xda\xf4\xb3\xcd\xdf>BA;H\xdaQ\xd4~t1\xe36u\xd3\x1az\xad\xf0Zz-\xd0\x18\x8d;\xf7k\xae)\x98\xfcB\x0d\x96S\x8a\xa4\x95Vt\xda\\t&\x8b\xae\xa9>\xb8\xb2\xa9\x12\xdd\xba2naU\xc6\xcd,\xca8R\xf5\xc8R\x8f\x85\x9d\xf4s3Z?wV\xd1\xcf\xd1\xed\x89\xbc\xda}\xcbe\xa9b\x19OQ\xa3\xa7\xe0\xdf\x17`\x03\xc5\x95s0\x9a]\x85\xe1\xd5\xf2*\xe1W\xe9Uvu\xc6]\xf7@\xaa\xef\xc6\x89\xc7\xa6\x1e\xeb\xfd\xb0g\xaa\xff\xd8\xcah\xe8\xb3\xab/\xbe\xb8\xfa\xf2\xea\xcd\xe1\xd5\xdb\xabwW?:\xac5\xc4\xfalnk\xac\xec\xdf\xbcK\xffT\x8d\xb6\xcf\xf79\xc0\x1d\xeb\x87\xd7\xa6\xec\x1b\xce\x06\xd8t \xea\xa6l\x10\xc0\x14\x97\x1d\xb0\x15\x18A#\xe3\xef\x17\x0eG\xd9Z\xa8S\xdc\xb5~d\xbdk}o\xfc\x93\xc1\xa4\xff\xc3{\x03~\xc1\xa7N,z\x10\xc35\xb1\xf2m\xf0\xe2\xf0\xf8\xf5\x9bW\xef^\x81\x91~\x0f\xac\xb8{\xe8\xc8\xd1I\x93\xa9{<\x1c\xa0E\xd3\x88\xf5z\xd7\x85\xc4F >\x18@`\xd6k\x8c\x14\x91~\xcf\x1d\xf7\x8e\x8f\xa7q\xc27\x7f\x9a\x1e\xa7\x0b?\xe1\xb3\xe3c\x9b\x95\xfdu\xa5\nv\xdf6\xed2\x83\xf6s[7\xb0\xa9\xad\x01\x88\xcb\xc2\x87\xcd\xe3\xce\x1de\xde[!JcN{\x05)\xe9\xd2\xe6>\xcb\xd8\x01\x1b\xb2\x11l\xda\xd7\x05\xbf\xa0\x9e\xc4 \xeb\xf88\x8cg~\xba8\x16{\xfdqqg\xe8\xf8\x988v\xb5\xb8OX\x17\xb9*PR\xf0\xa8\x02#\x983\xc7pZ\xcc\xb4\xf3sf\xc0\x8fULN\xf7\xd1\xa6\xb4\x98\xee\xa6@J\xb2VPx\x15\x86\x95.\xbeP\xd8\xfd\xde.\xf0\xbf\x7fx\x16\xc6\xe7\x07\xd5+>0\xc4X\x1b\xf8\xed\x0e\xb4\x01\xcb\xda\x06\xd9\xe4=\xacu\x9c\xe5\"\xeaW\x17#rdC\x8fEb\xe8\xfbh\x8d\xaf\x89\xd82i\x9d\x9c!\x83pS\x02\xd1\xc6\x96\x8c'\xb7\xc4\x88\x0cw(\xf6\x18\x83\xd7h\xcc\xd8*\x0c\xa6\xbc\x0d\xf2\x9d\xd0\x8bf}\x13D\"rN6\x9c\x88=A\xc7\x11N\x04\x9e\xa0\xd4\xd5\xd4M6\x14\xebm\xb0\x8a\xd1WD\x89\x8f`\x1e\xef\xb1\xcd\xcd\x02H\x1e\xdb\xba\xd6\x9e[@\xe9\x174z\x1c\xbb.\xba\x1dG\x93\xf1\xb0m\x0b\xba\xd5\xa1\x146\xaa\xd5\xb1\x08rW\xb91\xf6\x11\xba\xd2u5\x9b\x80\x8d\x01\xb0\x91\x15\xb0\xb1\x04\xac\xd3\xefkH\x12a\xec\xd0\xb1\xf8\xf0\xc4\x85\x08P\xe3X\xc0[F9j_\xdb\x0d\xc3\xddn\x1d\xae\x0d\x89\x12\x15\xf9\xcd\x95G+\xdb-\xa1\xebr\x01\xad\x14\xc9\x8e\xdf\xd2S\x1d\xd9\x9d\x1e\x9e\xe8\xd1\x81\x1b\xf0\x9bQ\xbe<\xe1\x89\x96\x90\x02\xe7\xa9%\x9c\xc4q\xc8}\xe9\xf4M\xf0\xa6\xc7\xc7@\x89\x8e\x8f{2\x10\xc0Hs\xce\xf7}\xceFe\x1d\xc0d\x9c\xf2\x0eb\xfc\x8f\xdc\x07\xdc\xa1>f\x1f\x1a\x16a\xd9\x0fz\x05F\x80\x8c4e\x03\xc1\x034\xeeU7\xdeHnk\xc8\x8a\xc9\x8d\xf7fK\x8f\xb6{7\xae\x8eI\xe5\xdc\xfdV\x90X\xa6\xa5(\x80{\x10\xe9u\xef\xac\xe2w\x9d\xbcI\x06\x8e/b's\xa9\xfa\xaa\x8dT\x11\xb8\x1d\xa2\x05&o\xaa\x05\xe0{(j\xec\xbb\xfe\xc8q\xa4N>\xe6\x13\xb8|\x90wu3k\xa6\x9cI\x8f\xbc\xbc\x00\x87\x95\xf3\x0ea'a\x07,\x1f\xa7\xc0C\x87\x82\xc1\x0c F\x9a\xb1\x1bH\x03w\x87\xf5[ \xf2\x02\x84!`AL\xd8~\xd4*A\xb2\x12\xc6\xd8F\xa3\x87\x15&\xe6\xce\x1d\x96\x8d\xb7&\xe3\xed \xde\x19\x14\xef[\x82\xbd\x13/\xc3\x89\xd8\x82\x8ao5\xdd`\x8e\xa4\x13Q\x88\xb6\x16QAB\xaf\x0d\xb5\xa1qwF]\x8d\xa3\xa064%U\xdbm0\xc4\xaf\x0bd#\x80\x99\x02\x1d\x91n4\x8d\xe1\x0b\x04K\xcd\xe4)\xdbg\x1b\xb9y8,\xce\xf4\x85\xdf\x98\x8dZ\xfc\n\x10\xb0\xf2\x8a\xc7\x03\x96nnZ\xa5\xabs\xd1\xbdqjq}=\x85`\xa18\xbbs\xc1G\xc0\x166\x9e\x8f\xb7&\x02\xb97\x1c\xf1\x06b\x92\xd2\x93\xcdFS\xac\x0f\xe8\xdec\xd6\xef\xa7\xec \x0b\xad\xbdZ\xb1}\xe6\xa8\xae\xb9V\xe7i3\x10\x0d\xaf,\xb9\x0b1IV\xaf\xde\xc5\xd0l\x04\xa5\xe6\x90\x04B\xdco8\xab\xe6\xd1\x8aG\xc6}\xb7\xd3\xbe3\x86Q)\x1bBQ\xe7.\x94\\\xb2}\x96;3\x8f-<\xb6\xc2U\xe1\xb13\x0b\xc5\x04\xba\xabwy f\x12\x0b\x8f\xcd<\x16\xb0+y_\xeeL,\xcae\xf3\x08\x1afP\xd5\xba\xc1\xa1\xad\xf5\xeai}J\xea\x07HT\xd1\xacu\x86\xbc\x01\x8b\xd8~\x04\xca:\xf3\xb5\xa2\xac\xe4\xd5o\xbd\xc3\xfa\xc7T\x7f\xbb\xf1x\xb7\xf4\xad\x9b\xf2r\x16\x8d\xe0C\xea~\x9fH\xaf\x97\x07b\xbd\xd5\xead\xa1\xeb\xa9\x8c \xbfLy\xd9\x8a\xe7ft1\xa6\xb1G\x91\xa5\x15V\xf0Gb\xab+\xdcT=a>\xdbd\xc3bM\xe6\x95\x83\\\x15\xd3\xfb\xfdH\xa2\x90H5\x9b7\xc6!\x17L\xe0\xe4\x1d\\M[\xf8Z\xc5\xd6\xde\x90\x93\xb5n\xc5u1\x9ade\xb7\xa9x\xa7\"\x9d\xd2\x1c \x14\xaa\xab?Sl\xbf\xaeq\x08ew\xea\xcdL%\xdfTO\x9f\x9b\x9c\xc1J\x0f\xac\xfaLy\xf0\xac\x9b\x97\xcc\xaa\xa5\x12\xff\xb2^b\xa1\x97\xc0M\xbb^\xe4\xec\xe6\xc2S\xc5\xa2,=v\xea\xb1K\n\xffO\x04+\xe2PG\xa1c\xc8\xc9\x88\x9cs\xb6\xcfN\xd8\x01\x9b\xb1\x11\xcb\xc9\xba\x87l\x9f\x1d\x17%\xa86.\xc4^/\x1a:\x17\x9c\xcd\x8a\x1d\xb0\x05\x1b\xb1sW\xfc\"8\xa6\xb7\xa2\xb8h\xf5P/~h+\xfe\\5|h.\xe7\xe7bK\x0fA\xd7e\xaedX\xa5!\x9cb\x8a\x8d\xd2\\l'\xe0+\xc5\x83A42>\xc5\xf76.\x8a\x06/A*x\xa964\xd7c'\"e\x8a\"\xdb\x98\x98\xb5\x11\x0bd\xeay%\xc3\x1c\xdb\x86\x13\xb1;lN\x0eM\xcc\xf6{\xb6\xcf.@\x0c\\\xb8\x96\xe9\x1d\x1f\x9f'\xfej\x05\x82jb\xa2\xc4\xf3\x8c\xed\xb3\xb7Z\xb5\xac^\x8d&w\xef\xc5\xb8\x9e5\x9d\x07_\xb1}\xf6\x9e\x1d0>\x00Wr \x11mp\x9a\xfe\x9a\xed\xb3g >-\x8bg4[d\x05\xf6\xa9\xf3\xcac\xaf\x15\x1c/\xdb|^\xd3l\xd0\x06L\xaac\xb6\xee\x9b\xd3w\xfd\xad\xd1\xd8\xea\xe4\xc1o\x9b6\x96\xd9\xdd\x1ev\xf5\xe3zv\xcbf\x1du.M\xb7\xef\x80\x02\xfel\xe6\x80w\xe1\x1a0\xc4\xe3k\xf4\xcd\x9f\xcd\xc0\xabP\x99\"\xb6D4\xca\xf0\x0d\xfb\x8b\xa0jj\xe1\x93\xf0\xad\x037\xba\x99\xae\xa6\x13O$w\xd3\xc8\xed\xb4s~\x9f\x8cX\xfb\xb7\xec\xbae\x00\xbb\x93\xb5}\xc2\x8a\xd06/I\x86\xb9\x93d\xf5\xb6(7\x17\x14\xdf\x90K\xfc\xafo\xf8\xa9L\xaf\xb7\x13\x9a\x1b\xbb\xe0\x01\xb6\xcd\xed\xbf\xd8\xa3?E o}\x93\xae\xf0\x03\x9f\xf9\x99aiZa\x05\xc0\xa3e#+\xf0\xa5\xbf\xa2\xf8\x00-\xd8\xfb\xf2\x84\x1bM,\xf5\"h\x97R/r\xaa\x17y\xcb\x0dn\xe3\xb2\x92\x0f\x12\xf0z\x91\x93J\x11\x10\x81\xd7\x8b\x1c\x1b\x8c\xcf\xa7\xf9|nv\xf8\xbc\x066\xffG\x01?\xaf\x17:,\x9c\xaa\x15\xeb\xde\xe2\x9b\xea\x02\x18\x83\x03v\x88\xfb\xc2\xabyg\xd7k\x8aX'\x1e;\xf4\xd8[\x8f=\xaf\xe3~z\x1e\x80\x0f4R\x8e\x05q\xdc\xceGF:\x93; \x1f\x9c\\f\xfc\x0bd\xf77\xc41P\xfb}u\xc50\xff\xd5|\x9e\xf2\xac\xcc\xc7\xdf\x8d\x1c\x88x8x\xa3:\x01\x00{\xd2\x1b \xfe2\xcbCG\x8f\xe9\x8e\x16:\xcb\xb6\xden\xbcu\x04u\x8f1\x18\x0c\xbce\xaeKl\xfe\xf0\xb5\xb9\xf95H_Y\xd2\xcf\x1a{\x178}\xee\xb1>%y\x86\xda\xb3\xc6\xda|\x10\x81Oq1&x\x03O+K\xe53\x1c\xc2\x9d\xe0\x0fK\xf3KK\xa7/\x9b?\x8b\xfa\xa0~\xc5(\xa9R\x7fA\xd7W\xbcZn\xa9vj\xaf\xf6\x0c5\xfd,\xb4\x8b\x8b\x80/sD\xfb)x{\x85\xb3\xde\x86\x12R\x00\xbb\xfa\xac\x15\xfb\x14\xfb\xf6\\\n\x1b\xec\x9f{U\xb4\xf5\n\xe0aa\xd8\xd8\xd5>\x9bz\xecyy\x14\xb5\x7f\xf858\xb4{\x0f\x88\xf8\x1eC\x15\x94\x0b\xb8\x91!|^\nm<\xf6\xda\x02\xde\x13\xfb\x8a.\xf9\xf8\x0b\xe55P\x0cJ\xfe\xb0J\xaf\x99\xb6\xce\xda\x94\xcf\xed[\xf4\xba\xec\x9c\x0c\xe1\x04\xd3K\xcb\xaa\xb8\x195\x82\n\xa5\x0e\x0d\x8e\xfb\xfdl\xc2\xf6\xc1\x86\x9e\xd7\xee\xa2\xb9\x1fC\xc4\xf5q\x86\xd786\xbe\xf6\xb0\xecv\xb3\x8f(\xf1\xc7\xd0\xe4xn\xe9\xb0\x8f\xf2\xde\x94\x02\"\x08@\xd8\x1d\x16\x9bp\x9c\x82f\x8e:\xcb\x0b6hJ\xf2\xffb=\xcc\x05\xe1H\x9c\xcc\xd5tC\x1b\xa1\x95z\x14\xd1\x8a\x04\xe34\x7f\xccV\x0dJ\n\xc1:M\xc7+\x8b$\x7f\xc3 A\xc0\x00^\x9aG\x9aA\xdb\xcc\xed\xa8\x95\x10\xdfX\x80\x190E\xc1\xc47`4\xa9\x0c\x87R4\xba \xa8\x98\x12\xf0o\xd4\xbc\xab\xa6\xba`-U\xf1P\xea\xdf*\xa0\"\x18\xb9P\x1c\x9eV\xec \x9b[!s\n\x1a\x10\x05\x1f\x8b\"\xe4\x12,\x07g\x16\xf0\xf9n!\xfe \xe1B\xe5%\x1cWg\x80E\x1c\xf0g\xc4|G\x9c`!\x15\xd1+\xb5)~u\x05\xc4 ;\x10=\xdc\xdf\xc7\xd3w.\x1bA\xd4\x84vO\xecJb\x90\xa8\xd0\x14\xfc$\xe1\xfe{#\xc7T\xe1.a{\x03\x9exZ\x1a\x92\x83m\xc6\xac\x89>\x83\xea\x07\xf0wi\x03\xfc1\xb0\\Z\xab4\xe8\xcf\x81\x17\xd3\x8a\x99\x03:\x16\xeb\xe6\\|\xad\xda\xc9@F\xec0R3\xd4D\x91\x01\x06\x8fE\xde\xb1.\xa6\x86\x14\xb2,|\xf3\\/{\x8eF\xdf\x08\xfa\x0e\x1bX\xaao\xa1\xc5\x0f\x81\xe0g?\xa8V\\\x9f\xf4\x13\x87\xcfJ|\xc7\xcd!F\x83\xb5 (\xd0\xdc|\x0b\x03>\x8e'b)E\xec K\xacK\xc9\x87\xa5T\x8fZ(\x9e\xcc\xf1\x01i\xd1\xac\xd9 \xc6q\xbf\x0f\xb1\x0e;\x80(\xf8\xde\x00\xa1\xa23\xaa\x91\xf2\xc7.K0(cf\x04'\x91\xbdKZzg7E\xa0\x05\xf9\xf7\xa9\xfb\xe2\x94\x94\xbcm\x0b\xb3\xc8\x1dbiZ\x9eHf\xeb\xc6\xd0\xb5|\xa7\x953[\x170C\xcbMz\x03`>\x84)-\xc1\xe3\x8f\x0b\xf0}\x1e\xc6~\xb6\xb3-\xb5\x08\x80\x80\xb5\xcc\xdd\xfbt\xe6\x8b({h\xcd\x19\xeeZ\xb3l\x1f\xfb*\xb06\x08Y\xcfC\x7f\xb9\xe23{ \xdb7E^\xe5\xa3\x1b[\x9e\x9e\xafaP\xad&\xdd^E\xf0P\xcb+\xe48\xb5\xf4R\x08afp#Q\nr\xea\xb3!q\xc5\xc8\x00\xa9N-MIrj\xc9J\x17TKVB\x9dZ2\x08r\xeaiRxSK\xfe1\xf7\xdf\x17\xfd\xd8\x18z\xeb-\xc1@.\xc1\xd8\xe1E\x94&\xb1\x1fm\xf8c\xb1*o`\xdaK\xfb\xa0\xd85\xac\xdfn\x81C\xae\x8f\x0dc5\xe9\xf1\x98L\xfb'u\xf6\x18O,,[$6\xe7\xc2\xec\xc6\xd5\x9c\xf6G\xae\xb9\x91o\x00\x03~\x87e\xa8\xea\xb5\x10\xe86\xcb\xd7\x86\xb3\xc6\x9e\xebh\x81\xb6<\xd93\x8b\xe9\x05}\xfd\xc8N\xe5v\\\x07\xae8y\xac\xa7\xd6\x8b\xed\xe2\xd9\x0d\x9a~\x9d\xc4\xcb \xe5\x1f\xa1\xe5\xb7<\xfb\x08\xad\xca\x95uK-o\x1b\x97v\xe5\x8aX\xdf\xc0\xb3\x12\x856.B8gE\x00\xda\xa8\xe1\xf4\x15\xc0\xf1!\xb2\x1c.\x90m\n(\xb6 \x99\x0f\xe9\x06\x96\x95\xd2E0\xcf\x9c\x06D\xd5.\xfe\x03k\xd1\xb64E\xf9\xc0\x89\x8b\xbd\xcb\xde\xb2x\x00\xf8q\xc3\xa2\xa2)-\x99\x8aS\xe1$\xec\xa9\xf4%\xa6\xf6\xbc\x91\xd8\xc0Y\x9f9\xd2\xc8\xfd\x80\xf5\x9e\xdc\x13TM\xfe\xee\xb3\xde\xd3\x9e^Jn\xa0\x82\xa1\x8aD\xe9\xa3Hf\x83\xa6\x10\xe4\xa0\xd4\xc2\xb3\xcfb`\xdf\xc2\xd4)kC\xc7\x138J\x96\xbf\x07\xfej\xc5#\xf0\xef\xe0\xe9\xf84\xc0\xc4\xb8\x92\xa8\xcc\x18\x9c\x0dq\x06\xdd\xd8\xeaB\"\xe0N\x06br\x01\xb5*\xbc4pi\x80*W\xbf2s=`=\x86e\xb5\x072\x0e\xd6\xabN/\x8a3\xe6\xa7ip\x1a\xf1\x19\xcbb\xe6\xb3\x95\x9f\xf0(\xdb\xa0\xf8\x07\xf5\x9ci\xfe\x91\xe8^\xaa\xa7\xf4H\xa3 f\xec\x0d\xe7\x8e\xd6[IT#\xaf\xd2\x02\x8a\x80\xfa\x82\xc1P\x94\xd6\xf5\x9agE\x7f\x14{\xe9P\xbc\xa2zlT\xca\xc2f\x08\x9a\xd7uJ\xb4\x0d\x17\x0d<\xc4\xd0\xe0\x84\xcb\x95\xd7\x1d\xc1\xe7\xaa\x1c\xd1\xd3\xce$\xd3*\xfa\xac]d+~}pK\xc7\xc3\xce\x83\x07\xf2\x80\xdd$\xe8W\xdbyu\x80\xbd;\xbd\x11\xeb\xdd\xf1\x97\xab\xc75\xa2x\xb7wW\xe4\xfc,\x8f\xb3zV\xef.VZ\xc5\xa9\x91\xf5\x04\xb2B\xb3\xceS\xc88\xcd\x1ek\xc1\xfa\xda\x04\xe3\x16\xa9\xb8$^\x92\xb2\x01\xf1*\xc4=\xce\xf8N\xef\xc9\xd3\xbb\x18c\xa1U\xd8\xa6\x04\xccFP>\xe0\xd9\xca\x8e\x92\xd0\xad\x91G}\x08\xf1\xe3\n\xdc\xa5\x19\xc1\xa3\x1dwpx\xc6\xa3\xecp\x19d\x19O(o\x1f\xe6A:\x913\xbd\x08\x0cu\xb5x\"\xe7\xe1\xd0ub\x0f\xfc\x97\xc4\x837%\xc5\x14_\xbc\x0f\x89?N\x82\xacH\xdc\xdd}\x00\x89\x9f\xe5\xab\x90_\xc8\xa4]Hz\x97\xf8Q:\x8f\x93\xa5L\xdd\x83\xd4\xd7~\x9a\xbe[$q~\xba\x90\xe9\x0f!\x1de\xe2x\xb0\x8bu\x97\x1f\xc1\x8a\xb7\xe97\xce4\xdf]6\xc9yL\x9fF\xf9\xe0\\\x0d\x07U \xb8\xd5\x88D.j\x80\xd5\xd8\xca\xcfS\xae\xbd\x1a\xc7&\xfa\x93\x01I\x85\xa2r\x1f\x82\x16\x13\x9e\xe6\xcb\xca{\xe3\xa9,\x1a\xc4Q\xc1\x92\xc5`,\x08 \x89\x1fD=\x8f\x05\x90r\x1c\xa4o\xb3Y\x00r\xfcL\x1b\x18\x1e\x9e\xc1\x119\xd4\x12l\x9c\xc7r`\x88\xc4od\xdb<\x96\xd6\xa5xg\xd2Ztch\x83oN\x0e\xd6\x87\x8f\xf9r\xc7\xe5H\xc7\xbaA/\xed\xd0 y\xa9\x8d\x0ff<\xcd\x92\xf8\x12\x17\xb6\xfc\xd1\xf5\xb3!M\xb7\xc5\x16:u\\OZ\x02$\x830H3\x1e\xf1\xe4\xb9\xd8\x87\xa4\x13\xe1\x1e\x17\x9bi\xcfU\xfbk\x9d\xde\xd2_\x9cZ\xd1d\x19\x9f\xf1/\xe4wjsndj\xf3oV\xd5\xe7\xb9\x9eW\xce9Y\x13F$\x98%\xea\xabz\xae\xed\xab\xd3\xc6\xafN\xc9v\xcb\xdc\x86\x95\xa0\xc8-br\xa5\x9f\xf5\x14\x1d\xdb\xa7\x06\xb6O\x8b:\xd5\x14<\xca\x08\x02\x04gL\xaf\x95\x86\xbb\x10`\xa9\x89\xac\xf7\x04!I\xb3$\x98f=\x92\xaa\xdf\x1f\xba\x03\xbc\xadDZ\x08\xec\xb6z\x9c\xaf\xe3R\x81f\x9cD\xb3\x8d\xf6m\x8d\x15\xa6\x91\x9ci7E3Wg#\xdf]\xae\xb8d%\x9f\xfb\x91\xe0&\xc5>\xc3|6\x0d\xfd4e~\xca\xfc\xe2K\xc4\xb9\xf0C\xe9\x86\x1b\x19\x9e\x05\xf7g\xd2LK\xa6d~\x10VS\xe4y`\xdf\xea\\\x99i\xbb\xbc\xe9E\xaa\x99QS\xbc\xad\xe5h\xe9g\xbe\xd5;Y\xc4/2\x94G\x99\xe34y3}(O\xc1\x16\xa9\x18.\x88}@Q>\xaa@%\xab\x82$\xf3\x98\x8c\x01\x80\xcdT\xa1\xe1U\xc6\x9eG \xfc\xfe\xf8\xc3/\xfa\xdb\x05\x062\x06\x89\x06 \x10\x06\xebc\xac!\xc6:c6Fl#\xf0R\x00V\xb6\xdat`\xe5\xeaH#z4\x10\x10\xa1\xcf3\x12\x01\x87\xc6\x10\x0f\xaa\x03\xaa\xe1x}\xca\x8b/ \xf0\x16\x91A\x949\x05a\xce\xde\x04\x11\x15\xf5\xae\x11\"M\xbdkY\x81\xd5\xaf\xfd4\x0e\xda\x1d\xb8#\xfc\xf7\xeb\xf0\x97\xd0\xa3|\xe6Tn4\x15\x9d\xc5kM=\x14\xc7\xc3\xacHoH\x02n\x8f]\x16\xb1\xfe>\xe8\xc03\xcb\x9c\xd1f\"5\xf8\xc5\xd1\xd4o_D\xcdcJ\x06~\x18\xc6Sg\xcbb\x8an`LQ\xb3\x0d\xedJ\xc8\xc0\xb19F\xb3)\xf9\xbd\xaf\xa2\xd4\x9fs\x87\xb3\xa7O\x9f\x82x\xd2\xaf\x82/\x17\xd3\xf9\x98\xf9\x8f]\x00\x9c\x0f\xdf@\xa8\x06x\xa3>\xf7@\x97\xb6\xbaD\x9b\x1fQ\xa5\xaf\nV\x0c||\x04\xba\x0d\xc4\x81\x01\xe2\"\xe1\x83`\xb5d\xf4\xb7 JW|\x9aU~\x0c\xa6y\x9a\xc5K \x13\xa5t\xa6\x98\xa0q\xbd\xe0\xa4 \xd9\xd5j.*\x11r5\x1c\xd6\x88YI\x8e\xe5\xf2\xa6(\xae]\xfa,to\xa0/\xd2\xc6k=rw6H\xa2\xb6\xef\xea\xeeN+nH\x8eD=\xb0\xefC0\xcb\x17\xcb%\x9f\x05~f\x95jH\x05\x0d\x1a\x19I\xbf3\xe6}7\xfd \xe1\xa2\xbb=\x7f\xda\xa0\x9baRw\xc3\x07\xb3x\n\x922{\xb9Uitt\xca\xb3\xd7\nI^\x81R\x83\xcc\xb0\xba\xb0\x12M\xad\xc0\x92D\xc0\xe4]\xb0\xe4q\x9e\xc9\xe8\x88\xdc+\xfd\x1c\xac\x92x\xca\xd3t\xd2\x835\xfc\xf3\x0fEpIy!x \x0b\xa0\xb1m\x1b\x1dQ\x8f\xa6\x07j\xa4\xdc\xfa\xb3p\x88\x0b_\xea\xb1 \xb8\xd8HG\x9d\xa6O\x80\x12u\xb0\x8a\xd3\xecK\xe9@M\x9c6\xf9 X\x8a%\xf9v\x9a\x04\xab\xccj\xef\xa3\x1eE\xc47\xb6\x9a\xa5\x88LJ\x12\x05\xb3nu\xd1\xa6?\x05\xf3W\x94o\xdb\xf4\xeaOF\xeb\x10\xf4\x07\xf7\x86\x12\x02N\xaf\xe7\xb1\xde'=y\xaa(?\x1c\xd5o\xd9UZ\xa1g\xc2qA\"%\x9b~\xbe\xf0\xa3\x88\x838\xdb\x01{J~\xce\xaaY\xee@\xc0}H\x0f\xb8\x11\xb9\x16\x0e\x07\nn\x93y\xae\x81\xa7\x01tb\xbb\x02\x14\x0b\x16\x82l\x0c\x16b/\x8e\x12\xee\xcf.\xd3\xcc\xcf\xf8t\xe1G\xa7\x1c|\xdd\xcc\x07\xd3\x84\xfb\x19\x97\xa2w\xa7\x97\x02R\xf5\x04`\xc0\x8eq^\x90\x00Yd\x9d\xae*\xd4\xb3~\xc5\x8e`\xd9\xc0\xec\xf1:\xe8%E\xbdt+\xc8d\xc5\xf2d\xfc|\x11\x8430s\xced\x9e\x1d\x8fD-\x94m\xabZv\xc0w\x87SI\xed\x9c\x85\xc7\xb6\x8c\x1bF\xea\x11\xa4\x03\xc43=}\xcf\xf8\xa1\xd8\xed\xe0\x16P\xe2G\xb3x\xe9\xc8@\xb5\xc8m\x14=h4a\xcc\x06i\x9c'S.ob\x08\x8c\xd1\x83sI\x1b\xa5\x812\xe9\x93|\x172%A4\xe3\x17\xaf\xe6\x8e\x0f\x02\xbd\x85\xd3\x97\xe9\xa0pq\x14\xd3b3q\x14\xeb\xd8\x9f\xcd@\xd8\xaad\x14\xb0*\xeb\x89NO.\xba\x1el\x7f\x1bC\x10\xfc\x0e\xfc,\xf3\xa7\x0b(\xe9\xf4\x8a\x85)\x052Ig\x00T\x89\x8c/XX\xa43\x96\xf9\xf5p\x93*&\xa1\xf3\\kR\xb5\x8d\x9a\x19/\x97DGy7q\x80\xd1\xe6MF\x7f\x156\xbd48.\x14\\\xea\x10\xb1 \x11\x0f#\xe4>#\xf6DwM\xd0\xef\xbb\xca\x97@Qo\x0c\xaaA\x8b\xdd>\xd3\xec\xbe\x9aW\xa1\xd8\x8fO\xfc\xe9\xfbF_\xe3\xe2\xf1\x93\xd3\x942\xb8S\x0fq\xacU\x8f\xdc\x86\xc2q:A\x01w\xe2\xa4\xae\xc7\xd2~\xdf\x86p+<\xa2\xe9sG\x1c\xa4\x1b\x8c\x08f\x0d\x16%\x18\x947\xac\xdfhd-M6\x18\xa9\x80t\xd4\xa5\x88\x04\x0d\x94\x86\xe88L#\xca!\x19\xebV=p\x85\xad\x8d\xc8N ?|\xf5'K.;p\x02\x1b\x1dW\x8f\xfe\xa8\x81\xa0RW\xa0Y;\x83\xa3\x9e\x04\xea \xack\xee\xbdz\x94\x91u\xd2\"\xbb\xa0\x1e0\xbc\xde\xb2\x1b\xdfRO\xa3\x01%\xf5\xb4\x98i\xd7\x1f\xe8\xd3p\xdd>%\xe3-\xeajw\xd3s\x9d~m_\xa7_\x1eK\xc6\xc3\xef\xa3w;\xd7\xef\x9d\xf8\xbb\xfd\x91\xfb\xd8j\xebM=\xa0\xb0\x0fA\xe4@\xd8{P\x0f\xcdQWJ\xd8\x98\xa3\xa2\x00\x9b\x07\x91\x1f\x86]\xe8\xc3\x0c\xd8\xb9i\x87\xf3\x825\xb7\xab\xe1oM\xb6\xe7\xf4\x8a\x98\x05:/\x94\xf2p^^aW\xf7W\xb3E\x90\xc2\x0d\xd7\x11\x14\xd0\x94\xc0\xba\x11\xc0\x0e\xec\xc5v[\x80\xee\xd7\xa2\x8a\xed\xc3B6\xed\xc4\x17\xadV\x06a<\xf5\xc3\xb7Y\x9c\xf8\xa7\xbc9\xe6\xda\xd4\x07\x02\xd8\xe6\x15\xa45\xda\x19\xd3U\xca\x95\xef7\xc6^\x97>#\xc0\x9c\xac\x97%9\xc7\xc3?\x9e\xfb\x9d\xc8\x1dd\xf1\x17\xf19O\x9e\xfb\x84\x06Y\xff\xd5\xf9^\x1fS\x97a\x9c^\x14\x7f\xc6W \x9f\x82\xe9ZO\xbb\x97g\xf6Wi\x9b(\xd7\xaa\xf5\x9b\x82M\x1b\xfe\x06ycS/\x119=\xd0\x10\xd5\xbaV7>\xb29\xf7f`\x90\xd0\xcb\x12\x7f\xca+M\xb0\x036\x8d\xa34\x0e\xf9\x002\x1d\xf0w\xa4\x92\xce\xfd$B7\xe0\xb0\xf7w\\SL\x17\x17 \xa9\xc9@%UZb\xb5\xadC\xebR\xea\xb4\x86hA\\\xc5\xf9N\x99\\j\x0cw\x86\x96+\xe5[\xbbd\x00\x98\xc0\\\x1f\xa8\xdc\x03\xc2\xa0\xe9\xf7\x82\x12\x890v\x98\xe1N\xbb4%!\x02\xe8\x8b'\x1e\x04\xd1\x82'A&\x1d\xc1\x0c\xc1\xd2C\xa59\x01\x9a\x99\x04\x9a`\xfd8\xd3\x8cF\x9a\xa0\xc5\x007\xf0\x94\xdc\xea/\xa4\xc1\xb6&r\x86\x8f\x1et\x9a\x9fj\xad\xdd\xebT\x1a>\xba\xef\x96f1\xd7\xac\xaf\x19\xd0ti\xa1M\xe3\xbc3\xa4\x02\xe8\x8bt\x8bK\x82\xbd\xf6[\xea\xf5\x89\x92\xaa\x08\xbc\xac]\x1e\xe0\x0c^H\xa2\x9b?\x88\xe2d\xe9\x87\xc17<\x81k\xa9\xa0\x96s2\xed\x8678.+\x95\x0d\xa5G\x0c\x7f\xe0\xa7\x97\xd1\xd4E\xcf\x04\xfe`\x95\x04\xcb \x0b\xce\xc4\xd6\xa7\x8c`\xd8A\xf5\x13p\xb1z\x0b\x0e\xeb\x19\\\xb3\xc0\xaaF\x89m\x17<\x7f\x8f\xea\xb5\xb5vE\xb1\x1d\x17bQU\x13\xf70Q\xbc>\x84f\x8a\xae\x82\xe5\x8f\xb3\xb7\xf5\xc8\x95Q\x8d\x96\x8146r\xf6\x86\xa0\x9f\x19\xcc\x82t\x15\x97\x89\xbb\x90\xb8\xf4/\x9e\x9d\x16i{*M&lc\xcd\x84\xcf\xc1@\x85'*}[\xac8\x81(\xfe\x9a\xab\xa6\x0d\x91v\xf7(D\x02\xa1\x8f\x7f\x92\x9a\xa8\x049\xf30\xd6\x1dbwC'\xa5>J_\xfa/\xd1_\x05\xba\xe8\x00,\x11Get\xa7\nN?\xee\xdcaA\xfay\x10\x05\xe0\xa2\x1a\x1c\x0dq\xf0\xf2\xe1\xc4\xd2\xdfP\x9bQG'0\xd4\x88\xc3\xde\xb6\x0b\x82[\x18c\x1a\x9cF0\xf5\xbb{;\x9d\x88F\xfb'\xac\xfb\xb3Re\x15\x1f&\x17\x18m6\x05h/\x0d\xe0\x9c!z\xa5\xdbT\xbf7\xb7\xb7\xd6u\xe7\xb1\xc60\xec\xb6\x99\xdadz\xe5\x8c\x03Q\xd0=\xb2pi:\x81>pn\xa3\x9f%b?\xa0\xbd\xd2\x0e\xef\xd7\xfd\xdaH\x02Y\xf7\x98$\x03V\xee\xd1\x01+\x05\x9dm\x86\x0e\xe3\xb4\xb3\x81\x08oCUgX\xec\xe5\xe8\x10\x03n^I\x97\n\x15\x9a\xebjtG\xd1\x1b\xc2\"\xfc\xd5J|\x1d\xf3 l\xe8\xca\x9f\xf4\xb4\xe6\xce\xa8\xe5\xcc\x9bbEt\xd8z\xa0\xda =6\xf7X4\xe6\x13\x88\xe9\x81Nx\xc8K\xe5\xb6\xe3\xea\xad\xe0\xf2\xae%\x16\xe0\xce\x90\xf6K9\xbco\x89 \xfcp\xcf\x1d,y\xb6\x88g)Ejw\x0d\xff\xc0\xa9\xe4\xec\xeaG\xa8\x90^\x0cp,\xac\x96\x9cv]6\xf3re\xa0\xa6\xb1\x9a\xad\xd9(\xa0(G\x12\xcb\x80\xd7\x86\x82!1\xe3\x9a\xdf\x80\x05\xa4\xf2e\x90uXX\xc4Q\n\xec\xbb=vVD*\xf5\xd8\x89\xc7\x8e!\xc8\xec\xa1\xc7.0\x9a\x96\xc7\xde{\xec\x99\xc7^y\x10tk\x0e\xe7/\x9a\xe2c\x00\x11y\xa1\x14i\xb9\xdc\xbd\x0b\xf14\xee\xd6\\#\xe8\x1aW-\x10\xff\x02\x9cu\xea\xc9\xae\x07Qq.\x06\xa7<\xf3 \xf2\xcd\xc5 \x15\xaf\x97\xf0\x8a\x9a\x0d\x0f\x02\xd9\\\xa0\x06\xc5\xf5J\xc1\xcc \xe1i\x1c\x9e\xf1$\x85\xe6_\xc9\xad\xa5H\x15\x8b\xfa\x19SA\xf3\xed\"-Vn\xc0\xd2\xb4\xaa\xa0 &\xf9\x10\x1b\xf2+\xf8\x1e\xf8\xbeq\x02\xb7\xec\xd2>n\xd2K\x91\x08\x8aIb\x9b|-f\xab8\x89C\xe0]_Z&\x9f\xf2\xac\x07\xab6@s<\xd7c\xaf\xc9\xe8%\xa2\x0f\xe8tO\xf0LAi\x808-\xe8 \x9e\xe2\x83\xf1\xd6DP\x80\xb0\x9e\xae\xfa\xbc\x8f\x9e\xa1\xecB!bd\x8a\xb7H\x9c\xde\xf3 \x99\xe6\xa1\x9f\xb0 :\x8b\xa54\xc7c\xbd\xe7/\xde<\xff\xea\x8bgo\x8e_\xbc\xfc\xd1\xab\xe7\xcf\xde\xbdx\xf5\xd2\xa6x\x17\xad\x9e:\x01!\x8bA\xa5\x92\xe8C\x03\x18o\xa9'r6^\xa3J2\xf6\xd8s}^R5/R\x89/\xf8\x90*\xfd\xf4\xd8\x99[x\x15\x14\xeb\xa3Q\xe0\x06\xc7gzV-C\xc5\xbb\x02\x8dh\xa3\xae\x13\x14\xa8[\xe2\x90\xc5\xaa\x10\xf4m:\xb2\x97xT\xc7\x97Rf\xc6F5$s=\x1b\x9a\x17\x9d\xbe\xe5IB\x93\x000\x19&\xa6\xa9\xb8C\x8eV\xad\xa6'l\xdd\x93\xfa\xed\x92\x02\xfd\x8e'lyRT\x0c\xab\xd0\n\xa6\xb8qZ\xe3*5\xa0\xfc\xda\xc12\xbd)5h\xe8\xdc-O\xdf8\x16k,\"'/V\xf3\x16U\x82\xf21\\c>\xa9\xfc\x8f\x93\xe04\x88\xfc\x90T\xf8+n}\xc4\x9e\x99\x99\x92\xd5\x7f \xde\x83`\xb7W?\xcd\xb2\xa7<\xebr\x15T\x0e\xf2U\xc1\xe8\xbdr\xb8\x0b\xbb\xdc\x01[\xa2\xb3\x07\x89\x14\\L\x86I\xf5\xcc//\xfct\x8d/[\xe6\x91r\x12o~\n\xf7\xdb._\xb3\x900\x86\xfd\xa5{\xc00\xaa\xfa\x9d;\xec\x12-\xa5\xd8>{\x0d\xbc\xaa\xb4`\xc0\x1f\xefu\xb4\xc0\x9c\x1e\x86\xa8\xa3\x1cE\x99\x83\x006a\xd4\xae\xf2P\xa2\x15\"N(\x83\x80\xc8w\xee\xb0\x13q\xe6\xd3X#\xaf\xe8\x18|\xa5\xd7\x15\xb0q4j?\xb52M\xa0#\x16\x7f!\x10y\x0bz\x0f6\x02\x1b\xac2\xf9y\x91,\xa1TZRA\xfcW\xf0\xe41\xab\x08\xf5i\xdf\x15f\x7f\xc5\x18Glaf\x14\x87\xe1\x0e\x00\xe6\xc8\xd9\xca\xe5i~\xb6\xbe\xbc\x8fMV\xcd~\x95\x05-\x8b\x1a\x883.A8\xe5\xe1\xf1\xae\xe4d2\xe0d\"\xe4\xd1\xfc2\xc6]\xbdC\xeb\xec\xe9\x85\xa8[\xb6&7\xbfj\x93\xacmi\x11\xe4\xa3\xdcTp\x17\xf1\xcb\x00}\xf5\xfe\x9e\x83\x14\xbd\x95\xf5\xe0\xad\xb0\x93\xdd(\x87.\xf7\xdc\x91\xda\xef4\xb0r9k\x02\xa0%u\x8b\xb0\xb3bE\x9b\x82\x97\xc3\x8f\xd6O\x1f\x82\xd8K\xd8\x93\xdd-\xb1\xa0\xa1\xe3\x1210\xe6\xbe\xd9\xff\x95\xf3\xcc#\xfa\xac\x0b\xbfF,\x00\xd7UV\x12\x1b8\xc7D\xae\xa4]\x81\xe3\xab\xd3\x8e\xf9\x15\xd8\x89\x02\xe7\x9c\xca\x83\xbd\"p\x0e\xcd>\xfbE\xca\xad\x1c\xf1w\x86T \x10q$\xb7h\x99\xea\xe2-\xb1\x97\x83`r0\xf5WY\x9e\xf0\xb7\x99?}\xff.\xf1\xa7\x9a(\xa9\xe2\xab\xa3U#\x15I{D\x94wR\xd1n\xf3\x8aphH\x88\x90\xd2\x9a\x90\x89<\x0b\x07N*\xddm\xe5\xb8\xa9I\x8f\xa4\xca\xa9=hdR\x19\xd50\xc2\x9b\xb8\x81*\x1b\x0d\xa6\xf1L\xe0^\x0eWu \x08D\x84\x8c\xea\x9a\x0e\xa8\xd7\x90\xc7\x93j\x05\xdc\x81\xa5\x90\x02}\x85t\xd7.H\xf7n\x0e\xed\x15e\x1e\xc7#\xd6K\xfcozu\x1ae\x96=\x11\x18\xdf\x9b\x9d\xfb\x1d\xcaf\xc97\x97#\xd6\x13\xffz\x06\x8a\xf3\xc1<\x8eY\x9f\xf1\xc1\x89\x9f\xc0\x7fQ\x0eh\x83\xe8\xca\xec\xdc\x87z\xb7,\xb8\xdd5\xa2B5Hn\xd7\x08\x9c`\xd1\x10\x94\x17q\x02\xc3\xe4\xd6c\xdb5\xbe\x1blu\xb9.\xe9\x04n\xb4b\xa4M\x8a\x1a\xedV<|\x9c@\xfc\xd1qBX\x9b\xb6\x9a\xecD\xe8\xac@\xac\xebV\xf3\x0bd\xf8\x87\x8f\x99\xcf\x9e\xb0\xf41\xeb\xf7}y\x85\xadX\xa0\xfe\xc4\xc3\xf8\xd4\xca=Q\xee\x9a\xea\x13\xcd5KT\xe8EHL\xff\x18\xaa\xc3\x87CT\x1dj\"vT\x1e>\xdc\xfe\xd8\xcaCz\x12\x15\x8f\xa1\xf9\x96\xed\x15Z\xf5\x1ex[\xac\xceC\xe3\xa4\xd26X\xb7-P\xa6\x94#\xda\x00\xda\x96S\xbd\xe3\xb2\xd31x\xc3-\xe6\x06\x8fg\xeb\x1a\x9f\\\xab\xef\x04\xc5\x94\x9f\x18\x91\x97\xa6\xf0\x16\xda\xc8\x98\x9ak\x0e\x1c\x86}\xe7\x0e\x8b\xc7J11\x11\xebr\xdd\x10\xb9\xed\xa8)\xd0\xfc\x01\xe2\xbf\xbc.W\xb9s\x9b\xf9A\xa4V\xc3\xee\x0dV\x83\x82\xb6N\xe6\xd7\\+M{]R\xf6Ulz\x1b\xcae\x88Ju`\xf7R\xbe\xeb\xeby\xf38\xee\xdd\x8e\xaa]\x0d\xd3\x00\xa5\xbc\x0es]l\xa8\x1d\x11+\xcae\xf6\xf46\xf5\xef\xb5\xeb\xa4\x9er\xc8N\xe9\x80\xe6\xb4^t\xd5Y\x953\xeb\xaa\xcaY4\xabr\xce,\xaa\x9c\xda\xe7\x96]5>\xa7\xed\xc1n\xab\x15.I\x8a1\x8d\xa3yp\x9a\x83\xf6\x95\xa6\x1a\xbc\xd0\xce\xd2\xae\xaf\x95\xa7\xa4&\xba\x92\x1b\xdf\x164*i\xe3V\x98\xe2X\xac\x87\xb69\x185\x9c\xea\xb8\xd7;>\xe6\x1c\x0c\x07\x0e4\x07s\x90&\xcer\"\xe9rp\xe6\x87\xb9\xe0h\x16J\"sV\xab\xed\xb1K\xd7\xd3\n\xcab\xd1\x98O\xd8\x01\xe5t]\xe6\x88\x7f\xe8\xb1\x0d\xacO!u\x9f\x8dQ\x9b\x9aM\xca$\xe9\xad\xa3\n\xb1\x1a\x8d\x8f\xa6|\x04\x94\xbe\x1b\x94<\xdd'\x98z*\x80\x8a\x95[>c\xb9F]\xee(J5u\x8c5\xe0*\x992\xdah\xb7\x8a\x05\x07;\x02\xba\xaf\xa2i\xe1\xd4\xe7\xf8\xb8#(\xe6\xf3\x11\xf0\xbe]!!\x89\x04-\xe7F`l\xd0hS\xf1\xa7@\xd7\x97q\x80J\xc4r\xc7|\xd2\xa1\x9e\x896\xe8`T\xd46!\xc6\x14\xeb\x1d\xe0\xed71y\xc98\x98\x08\x1e6pY\\\xfa\xe5\x8d)\xb8b\xae`\x94\xb7\x95s*%\xd2\x97(\x98\x8c\x03i%7\x14\x88\x99\x0c\xd2\x15\xdc|\x0c<6\xa4\xee\xee\x81*-)?\x9b4~V\x8ac\xa3&\xeb\xf8\xb6iG \xa2\xdfzG\xf1\xac\xf0j\xd18\xef\x16:!\xb6\xe3\xb8:\xa1\xf6\x19\xa1\xe7\xb1\xd9\x19<\xccbD(\xc9d\xac6-\xde\n\xdew\xcc\xf0\xc8\x92\xb1',\x12\xd3\x9d\xb9,\x18g\"\xb3z\xd91k\xb8\x08\x07\x1f\x8d\xc1\x81\x05^h\x95\xedn=\x06\xc2\x1b\x8b\xca\xd8\xb4\\\xc5I\xa9\xc9!\x1b\x95\xbaTu\xa3\xac>\x96&\x00t\xb9\xb55+\x88\x0b\xe8\xa9\xec\x03c\xedw\x8b\xba\xdc\xc6\xaa~\xaf\xc6\xb0\xdc\xfc\xeb-\xb7\xad\x9a\xbe\xeeU\x84G7\xebK\xa7[U\xbf\x10\xfc\x14\xcf\xaa\x06\x05\x1b\xe6\xfd\x80\xfe\xf5\x81\xf2\xc6,8\x8b\xa9S\x17z\xe2^:u\xe2z\xba\xd8X\xa6N\xe0R\x84g\xea\xe8\xe6\xd0hG\xb8t~\xfe\x01\x85q:{\xdc\xec\xf5G\x19\x8bi\xa1*\x17N\x88\xce\x88\x8bSc5T\xa4\xc72e\xb4\xc4\xf6Y\xfe\x03vS\x8eY\x9e\xa3\xea\xb1~\x1b\x04\xab\x04\xdb,\xf88\xd2=q\xf9\xbdf\xe7\x01\x1a\xdd\x1f,\xfdU\xbb#hU\x81\x1d\xb0\xcc\xe1\xe3\x08T\xcf\xe2\x7f\x15%\\\xe9|\xc9\xc9+Zi\xf3\n\xff\x07o\xbdc\x0d\xc8\xbd@\xe0\xd516O O\xc5\xbe\xa1Zq\x05\xd7u\x12D\xb3\xf6P\xb6\xddg\x16\x8f=\x8f(S9\x9c\xa8 \x85\xff\xd7<\xd5\xc5(\xda\xe0\x10\xce\xfdv\xba\xdd\xe9 \xadD\xcb\xc8\x98\xe2H\xe6I\\\x0b\xc8\xd5t\xdcF\xff\xed\xe0]\x00\xe6p\x0c\x82d\x0fe\xc4\x13\xd7c\x9f\xc6q\xc8\xfd\xc8\x01V&+}.C\x01\xd4\x05\x81]\xf4m\x8cY\x13\xe4<\xdav\x07A\xc6\x13?\x8big\x8e\xc6\\\xca%\xfa\xc8fAN\x1a\x90\x1bK7\xa5\xe5\xc9!\xbd\xfe\xa7\xf2\x9bur1\xaf\xe3U\xa7c\xb5yX\x9e\xdd\xc6a\x94\xc8\xd7\x0f\xa3f.\x1c\xe6\x08\x1f\x8c\x1f\xac'\xf9\xeaQ}\xddET\xb2\xa5V\x13\xcaV]\xd2\xdbF]\x128Z*%\xf3)J\xe6C\xe7B\x06\x08\xbf\x90\x0e\x12\x99t\x19\x0eh\x0e\x13'R\x02\xf4\xf8\xec\x16\xbe\xf2\xaa\x8d[\xfc1\xc0 \xe8\xc2zF\x9c3y\x89F\xaeN4\xf7tN\xb5\x10\xc5\x82\xa4 \x16\xc9\xdb\xdb\xf2\xc2\x9e8\x9f;\xcb\n\xc71t!b\xd9>\xe3p\x19}i\xe1\x86\xf0T'\xbe\xda\xc2\x85W[\xaft\xaa\xe2f\xe4T\xb05\x91\xcb\x96h\xcc\xc7I\x0bJ\xf5\xc8\x91.\xc9\x02\xe6\xa5R3e !\x03\x7f`/\x040\x9f\x1bzdf*'\x9cs\xe8n2\xb1\xc2\x02\xe0p\x02f\xae\xe7\xf2J*\x1a\xd2\x08\x82\xa9\xe0#\x0e\xc8\xe2l~\x02\xce\xc5\x9c\x128\x1b\xc7\x83Y\x1c\xf1\xc7.(\xe0/\xd8\x81b\xe2\xd0\x1a\xf8\x18%&\xd2\x90\xbd\xf8%\xf6ogVHS\x0e=\xb6p\x96\xb02fp\xddJ\x82\xf9\xb0\xfe\xd1~\xdf\x125K\xcc\x1c\x11\"\xa84\xf7\x9c6`\x03@\xe0\xb4\x123\xdb\x1c=\x8c\xd7\x03\xb9]\x0d'\x0e%B\xc8Py\"GZ%\xed\xb3\xc3\xc1t\xe1'\xcf\xe3\x19\x7f\x969[\xae\xcb\x9e\xee\xb3\x07\x0f\xb6\x1f\xed\x82\xc5\x12{\xb2\xcf\x1e\xec\xee\x0c\x1fA\xf9Cp:9\xee\xf7\xa3\x89\xb4g0\xc0y(\xedG\x0e\xad <+Ax&A\xd8\xef\x9f\xd9\x81v\xd6\x82\x8e\x1a:\x89=\xf0\xd4D\xb8\x02z\xbe\xa3\xad\x9d\x1a\x00\x9dS\x97^P\xe40%4\x15o\xd7\x1d_H~\x00\xbb2\xab\xc8\xee<\xb6,/\x89B\x8c\x90\xa2\xe6\x0d\xf6\xf5\x9a\x96\xe2\xd1\x8e\xd4R\\.O\xe2\x10U\x12\x8f\xee\xdf\x82J\xa2v\xc2)\xf48\xb5-\x1e>[\x91\xc3\xb6\xe9vH\xbe\xcb\xdcb\xc8{(8J\xcd\xf9Bm\xf7`\xfb\xb2\x88\xd3\xcbx\x9a\xc9\xee\xd5\x8d:i\xf5\xa22o\xac\x9b>\xddD\x89\xa8\x97\xd9H\xc6\x95Q\x14,\xd9\x04\x953F~\x16\xbfV\xdaM(B\x95\xc0N\xbf\xf3O'\xb7\xc74\xea\xba\x0e\x8b\x8aC!_\xfdZL\xd8\xac\x90\x98v\xd54\xcc\xbbi.V\x84B\xc2d\xfa\xc2\xfa\xed\x90\x1az\xed\x1b\xe8U;\x97\x14X\xb5\x06\x1a%\x8e+=\xda6i\xa5\xeb\xeaf&\xe7`\x81\x9b\x80\xb3(\xbb\xef50}57\xbb \x92\xc0\xc5\x98c\xac?\x8c\xa1q-wF\xe3\xca)\xb4z\x98\x8f\xbb\\\x8f5\x89[\xbd\xb3\xfc\xd6:\xeb\xc3\xcdrP\x04\x01\xf4CG\xf3j!\xc5h\xda^\x0b\x01\x1a{\xa5\x15\xa1\xe0B\xa6ND[ \xce8\xfa\xa2\x0c\xe2\xe8\xf8x\xc4r\xf0/\x9aQ\xe6|\xc7\x91\xbf\xe4e\x993\xa7n\x02\xfd\xa1*\x1f\x99:q\xfd\x93\xf38\x11\xd5\x9b\xb1L\x0ez\x86\x8a0\xf87\xc2\x7f\xfb,v\n\x8anHE*\xbf\xdf\xf3\xcb\xcf\xbb|\xccb:\x0e\x8b/cA\xc4R`jgv!\xfel\x9cM\xd0\xd6\xb9\xd4\xdc4vm\xe1\xa7/$\x96(X&\xa8\x06\xd1r\xd0\xa2\xaf\xa7\xa5\x18\x01\xd3\x83\xf49\xc8\xaa\xde\xaeT\xc8\x97Zsf\x01\xd9\xaa\x99a6.\xf7\xb1z\x932Y5$\x7f\x1a\xd5\x97\x82\x1c\xd6\xeaB\x9a\xac\x08\xefF-\x19\x19\xa9VO\xc5N\xc2\x9a\xf2\x97Q7\xe5~b|\x12\x13eM\xfcaV\\\xf1i\xc0\xd3zMLUU\xf1\x17Q7\x0c2\xa3f\x18dE\xbd0\xc8\x8cZ\x1a\x0fP\xab\xab\xe5\xc8\x16\xb4\x14\xa2\x9d\x82S0\xda)r\x8av\x8a\x14\xa3\x9dW\xddS\xdfoT!\xeb\xc2_E\x95j+\xae\xd6\xb1\xd8\xde1\xfd\xcb]\xbe\xaa\xc8\xb7\x031\xdcQ\xf01\xa8\x91Q\xd6g=\xd70 \xad\xfc\x863\xc5\xaby\xd7\xaf\xa6\xb5\x98Z\xcc\x1c\xe5\xbc:\xcaXG&\xaf\x0d\xac\xea\xfa\x89\xfc\x0e-\x1e\x95\x8cw-B<8\xc8(0\xce\xd1;E\xf7\xaa@D\xe8\xd5\xb4\xe7)\x98\xf6\xb0B\xd0^!\xae8\xe3\xafp\xcct\x13UHPM\x94l\xf9M\x1cj\xe9\x02\xda\xdd\xb5=\x19\xa1\xdf3\x108P\x9c\x03\xba\xf6/\xf8\x06\xfa\x1c$'\xeb\xd6\x8dG[E\xfc\x1b\x1bx\xd9\x87D\x93\xab+\x91\xaf\xc7*\xc0\xb2o\x8b\xb2\xe0\xc6\xb4\x1e\xca\xe0\xce\x1dV-2\xae\x16\xaa\xce\xfcm\x0cYM\xa0a\x12\xa5>U]\xc6`K\x81\x12\x88.\xcb\xb8\x10\xc0V\x17\xb2\xe3\xae\x8d*Uk9\xee\x02x\xe2_,\x04\"gg\xb8}\xed\xa1\xd8\xdd\x06\xfdR\x0d\xb2\x12\xf2|\xbd\x01\xa6\x86CqX\x18\x88\xe6\xa6)\x88\xf2\xcf\xa1\x1d)\xb0o\xa2R\x0d&\xee\xedY\xcc\x9e\xe9^`\xd6\x1d*\xc1N7O\xef\x01\xb1XR\x9e\x91\xd7g\xe1\xaeQ-\xea\x9d8\x12\xd1\x91\xa4\xa0t\xe2\xf0\xc1)'.\xd3i\x01R\x07)\x071a\x06/\xfbP'\xe5\x10\x9d\\\xdenC\x15\xa0\xfa\x81%\xf0\x07\xdc9\x93\x01\x8f\xb0\x90\n~$\xca\xe0\xad)\x88\xd1\x0d\xfd\x94\x1f\xc8\xd0\xc1Dv;\x14k\x8d\x89)\x04 J\xdej\x1eb\xb5\xa0\xff\xbd\xff\xbeW\xcd\x97\x87\xa2\xfd\xf2\xd20\xc8e'\xeec\xb6\xb9\x99@D\x9f\xfe>\xeb\xfdw V\x00q4\x89 \xd9\xf77j\xb5\x19\xea\xf7%Ik\xbfB\xd8\x12\x95\xc3\xcb\xf0\xd6`\x82\xf2{A\x02\xb8\x18h\xac\xc2<\xe1@\xb3q\xbf\x9f48\xf61\xd0\xb5\xcb>Q\x8b'\x7f\xcb\x17\x18\x86\x86\n8\xae\x8b\xf8Z\x00mc\x1f ]i\x06*)3=\x82\xd3\xbc\xdd\xc5\x8beA7\x9f\xe6\x99f\xc2JwG=\x01\xd8\x8bZ\xb3}\xeb\"QOPD\xdf\xf2\x8b\x15\x13\x8c}\xb8\xba Fe\xaf%>-J\xda\x06\xc0\x14>>f1{\xc2|\xb6\xc9\x86\x8f\x9b\n3\xd9\xb0t\xa7\x07\"\"\xb9?\x04\xa0\xed\xe4\xe3x\xe2j\x0eW\xad\xdd+Z\x83.\x0e'\xa0C\xe9\xf7ckaS\x05\xa9\x1e\xf9\xad\x96>\xb1\x03\x15\x8eN~N\x81\x8fl\x97\xfe\x9a6*#\x9f\xb8M\x9eV\xd0\xc8jo)\xd0(@ao\x03\x1a\xe5\xcdh\x04\xd2\xc4\x8eh\x94\xba,\xc7\x10\x0e\xfd\xbe%\xf0PK`\x03@\x1ah\xe3\xeaJ\xbe\xec\xb3q\xe3DS+\xb3\x9ao\xcd\x9e\xc8\xab{\xe2;\xf2V\x9c\xc4\xd4M\xe9\xfc\xc3 \xcaI\xcfa\xd2c\x81\xf6h(\x1b@\xd5-i\xe4\x0e\x19\xa2\xa2\xc7\xf2\xf1P&~\xc4\xae\x17}\x1fN\xc6\x01\xe0\xb8\xff\xf8F\xfdv=\xd5\x18N\xe05\xf0WJ8\xc9p\x8b\xe6P\xd7\xf3\x8e!\xdd\xc74`\xb2\xdf\x8c\xc9\xb9\xb4/o\xc6\xf5\\\xe9\xc1\xad\xa5B\xd8\x0e:\xac\x05\xc9l\xf9\x02\xbb\xec\x8bAT\x81X\x80\xe3\xb4\x0b=\x0d4,\xedNO5\xee\xdf\x07t\xc8\xc7\x81FO\x9bIi\x88\x88\xe2\xa3\xa7&\xec\xebp2\x8e\x01\xe9\x82k\x10\xd6[\xe9Yq\x15\xb7\xe8\x8c\xa8\xaf\x0c\xf7c\x0f\x10Z\xe4U\x92\x1e\xb3\x0d(&\x15\xe0w\xee\xb0P\x117\x176\xdcp\xb0\x8aW\x8e\xeb\xe1\xa4\xc8_n\x87\x96\xd7X.\xda}\x80.\xeb\xa4\xab\x03\x16\xc9\xa7\xe8|\x89\xd9\xfc\x0f\xe8_7\xe0\xca\xaa\x9a\xff\xbd-y?\x11\xdd\xd2\x0e\xc0\xa9\x9dt\xec|\x93+\x89k1q\xfa\xb7\xd79\xca\x81\xc2\x9b;?\xff\x00\x84\x92;/\xfd\x97x\x0b\x91;;\xf7\xbf\xcf\xb3N\xc1\xf5o\xec\xdf\x8e\x1c\xac\xca:_\x13\xack\xf2\xc6u\"y\x1bl\xb1F.2\x0f,\xe1,fpU\xe6-.\xb9\xb4h\x1cwZuU&\xab\xcd\x7fh\x8642\xc1\x03W\x84\xbf\xfa}\xee~\x9c\xbdP\x93XA\x10)\xd8\xf87`\xa0x\x86\xaf\x12\xab\xa8\xf2\x9b\xa0\n\xb7Ct\x08~\xe5#\xd0\x9b\xdb<\x05\xd2B\x06\x1a\xd5#++j\xe3\xe3\x08x\x10%\x83\x1b\x1e#\xad\xbe\xaf\n\x89@\xc1:\xa1\xa142\x11\xbc\x95\x89h\xdc\xa6\xb3\xca6\xddr \xeb\xc434\xb2\x96-\xfd(\x97\xb7\xfc\x8c\xf5\x10\xd6\xba\xd2\xad\xc7\xa9\x02\x9c\xd2\x00i\x0b\xaf\xdcD\x8fY\xae\x81\xb3\xe0\xc0\xfd\xb2\xa7\xa9\xe4\xc0s\xc5\x81\x8b\xbcT\xe3\xc0surH;\x9c\x1c\x9aN\x0d\x96\x13\x03\x9c\x16R\xf8\xe8p\x02N>\xfa\xfd\xbc\x0b\xdd\xbc\xce(\\O}\x06\xce\x11\x99\xc7\x02\xb0/\x10hHxN\xee@\x0b;a8\x1es\x91\xcb\xc7\xc1\n\xb2\x14\x82\x18 \x93\xc7\xbbk\xe3<\x9e\xa1B8C\xb5\xb3\xa6)B$W\xc1\xbf\xe5)\x0d\x91\xdf_\x03\xf9eo6\x1a{\xd3rd\xc8\xf4\xcf\xe7&#\x9b\x13,r^e\x91\xd3*\x8b\x9c\x16,r^\xfe\"Xd\xb3ekO%G,f\xaa#xn\xb0e\xd9 9\xbb\xe6\xf2\xf2t\"nv\xf5\x07\xf4\xaf[\xda\x03m\xbe\xc1\xe9\xcb3;C\xfa\x82\x9b\xe9K\\\x1aY\x1a\x17_R\xdb\xcd\xb7j\xb1\xf5\\\x84[6m\x88\x16!\xe3\x18\xb4\xdcx\x97B\xd3\xb9\xc7V\x1e\xd8WN\xa5\x81\xa21\x1f\x8b\xa6\xcc3\xd0n(\xc7sf\xfe\x12\xf2\x95\x13\xc6*F\x97\xf5\xc0$\xbc\x99\x97S\x9cF\xe9_\x98\xc4\xad\x04|C\xa9\xa8\x0ep\xaf\xd4*\xa9\xa7\x9d\xad0\xe5\xb1/A3\xbb\xb4`\x9f\xb7<\xb69\x14[\xc3\x99\xbc}2/\x9c\"\xac\xc4\x9b\xa9s\xead\xb1\x1c8\x1a\x00\xd9Y\x83\xe1\xf2\x87\x1a\xf8\xe2H\xb9\xe9m\x87]\xe3\xf5v\xf2\x02%+\xcc\xdd4\x17\x05$\xcct\xc3\xbd}6\x9e\x81\xcb\x8aH\x19\xf1!u\x8f\\\xd4\xc1\x01h \xeeM= nH`\x91\x89tb%}L@\xa8|e\x93\xdfbD\xa3\x1e\xe0?\xect\x94\xf2\x15\xbb\x901\x0d`\xbf^\xa0\xf7\x8d\xd2%2\xac-\xf4\x07\x1b\xe0~%\xbd\x19'\x10M!\x8e2~\x91A,\xa6\xe44u\x0b\xfb\xcd\x04\xe3G\xc4\x88)A\x89BbNlq\xa2[I#\x86\xfb\x96k\xab\xcd\x0d\xc7\x19^\x8c\x94F\xe1\xd6E\x11\x89\xa1\xf3jd-\xe9\xffC5\xcf\xb8\x1da\x14\xff\x8c,\x05\x1f\x043\xbb\xe4O\xfa\xc2d\x8d\xf1\xfc\x01\x03q\xbb\x13\xadaOf\xe3\xb4t\xdb\x8b?\xe2R'ct>\x03W\x9a\xa9t\x80\xc8\x0e\x98\xd2\xec:\xe0P\xdcY\xa0\xe0\xdc\xde \x86\xf6lbnG\xb8\xe2\x1b\x8bbh\xe7\x06Q_\x89Ri\x89R\xa9G\xaf\xaeXF6\x88\x8b;\xc9nCI\x14\xc3\xd5/\xc7C\xf5n\xd7\x90\xf5Gk\x8c\xb7\xdc\xb4gr\\\xe8)\xdc\xc2\xb5\xa1\x087wBy\x9b\xd9\xf4\xfeB\x1d\xb6q+\xa6\xa8\x00\x97\xbc\xb4\x94\xb3\xca\xae.U\xb3\x1c\xe2\x03NOp\xc9E\xb8\x00}\xcd\x05\xf9\xb2\xc5\xfd\xcc\x07OR\xd9\xb4\x03\x95\x85\x95#I\xe1\x1adr0=\xa9Q\xca\xc1\xf4\xc4-\x0d\xa0\xc5\xcf\x02\xd7\xf1G4\x08\xc4\x96)\x9d\xef\x001e\xa3\x12\xa9\x89\xeb\xe38\x8a\xc2\x9bu\xfbvA\xb0\xeb\x14\xb1\x9c\x01\xb1\xbc\xba\x02BY\xec\x9c\x0b\xdd\xabv\x95\x84b\xa2FEU$\x19 \x98 n\xb1\xf5^\xb9\xbcn\xa7r\xa2\x0bD\xff5>\xa6\xe8\x0f4\xaa\xba\x13\x0b\x8cl_\x1d\x92\xce\xc8\x9e\xf3\xa2\xe7&\xea\x1ac)~\xde\n3k2\xad\xc8\xcc\xee\x191\x18\x03\x99^\xbf\xc4\xed\xcb\xf4\xba7]\x15K\x8c\x0epc2\xb9\x1dn\x0c\xc5N/[p\xf0\xd8/\xfe\x8fd$d\xb8X\x1fG\\\xfd/\xd2\xdd:[\xabB\x19val\xb5\x0b7\xc6\xac\xc4M\x99s\xea\xa6\x11S\xa62[\xca\xec_]\x0e\xac\x96)\x14T\x1c\xfc\xa3\n\xf2\xb3\x01\x91\x96\xe8k!w{\xac\x0f\xde\x1eX\x9f\xf5\xee*3\xcf3?\x0cfL\x0dv\x19\xcf\xb8q\xf1\x8d\"I \xee\xeb\xb65\x11Z\x02\xf4\xc2\xb0r\xc7/ES1:X\xf5\xa5\xc9\x14\xb1Q%\xf4\xe14\xc2\x8aC\x8f\xcde\x13f\x19\xd1\x95i\xabS&\xbd4`\xee\x98\xb2\xb7Q\x8f\x18BH\x04\x9c\xfb\x12yj\xce\xb8\xf8=b\x9f\xf1\x8cO3>cy\x14'3\x9e\xf0\x19\x13\x88x%\xb0\x8e\xdd)\"sC\xf8\x9e\\t\xcec\xe7\x8b`\xba`A\xc4\x002K\xff=O\x19F\x1fc3hMpC\xf1\x9c\xa5\xf9t\xca\xd3\xf4\xde\xdc\x0f\xc2<\xe1,X\xae\xe24\x0dNB\xce\x9c\xf3\x05\x8fD\x13wu\xec\xbe\x0b\x13\xeb\x1eE\xcf\xe3(\x0df\x80N\x04m3*?\x1c7\x1f\x1b\xc6 \x15\xbd\xc8\x02\x89\xb5N\x0e\x84'T\x9dc\xac\xf0\x96:\xbbh9S$k\x9d)H\x13\x97\x8fz\x8a\xa8\x8b\xa6\xa5\x90\xe0#\xe9\x89\x9b\x14\xb7JOY\x06\x90k\x06[\x86\xe7\xe3\xfa\xc5\xfc\xea\xe5\xf3\x9b\x03\x88p}\xa5NYm\x91\x96\xad\x86*\xe8\xf9\xfdV\xe7Q\x9c\xca\xd6\xbf\xbd\xd1\xe8\xa2\x1f\xaf\xe28\xe5\x15\x19p\xe8\xa6]\xfc\xd3\xa2\x895H\xad\xcd\x89\xa3\x0eC\xaf\xfd4\xe5\xb3B\x10\xa3\x05\x84\xc6K4\xc1\x9c\xcf\xea\xf1\x8cn\x17~{\x86JG\xcc\xf3\xbd\xf1Qt\x94\x1c\xe5\xdb[\xdb\x0f\xe1\xef\xa3\xc9\xbd\xd3u\xc1\xac\xd0_\xcc:\x89\xfb\x85\xc2\xe2)\x1bnm1\xe5\x80.\x93\x0eX\xb7<\xf6\xe8\x11\x1c\x13\xff\xdb\xef\xfc^O\xde\xff\xcf\xd4=iAq\x9b\x97\x8a\xfc\xcao\xbc}\xf5r\xa0\xc0y\xe9pW6?\x04\xc5Fm\x19\xdd.p\xff_\x83\x9cJ\xcf1~\x19G\x9b\xd3\x98'S<\xc6e\xb1DD\x17o\xf2N>\xea\x85\x8d\xdb\x88\x11o\xd3&\x96\xdf\x0b\x06\xb3 ]\xc5\xa6L\x85p\xa9)\xfaV\xb3\x81\x08 6\xa5\xa2\x9dg\xa7]W\xe0\xcc\x03\xa7B\x1e\xab\xf93\x05\x89#\xf8\xe4AY\x0b\xdbg+\xc5\x96.@\x89P,\xd0\xd4\xb2@\xd3\xe2\xc7\x01\xeb\xe1za#\x06\xbea\ny#\xeb\x8b\xcf\x17\x1d%\xf1u\x86\x0e\xd6R\x9e\xbd\x0b\x96<\xce\xb3\xf6sO!\x00\x8aH\xe1\n\xb7\xe9\xbb\xc4\xa7\x06y\x94\xf0\xb9\x18@\xf9\xcb\x81\x88\xa7\xe0UNt\xe6\xce\x1d\xd6\x8b\xf8E\xf6.\x98\xbe\xef\x81u\x90J\x86\x05\xa4\xba)\x12E\xc5\xf5\xfb/\x8f,\xcb\xbasa\xd9\xff3[\xff\x97\x95\xfe/\xb5\xfe\xb7hpj\xf3@.\xfb\xca\xd8f\x18\xef\xbf\xd0\x98\x8a\xb3\x15B\xc8\x80\x0c\xa7 \xa3\xd7^\x92A\x15\x05.\xf1\xcf\xb9\xd8XE\xb3g\x18\x1ct\x7f\x7f_\xcf\xb9\xba\x92Q\xdb\xcb4\xb1m\x0fvvv\xd8\x88M\x9d\xb9\x83\xa6\xe8z>\x1aGmI\xcc^\xb2}\xf6\xf3\x0f\xd2\xaf\xd6\x90m\xb23\x97}\x82\xd2M%\xaa\xa8\x03\x07t\xde9\x05\"\x18\xec\xd5\x15\x83\x01\xb2}\x0dK<\x16\xb4O\xbbE\xda!\x1e\x0d\xaa\xfb\x1aT\x1d\x0d\x84\x9e\xae\xb0\xabl\xa1h\xbb\xe6\xc4\xae\x8b\nA\x08\xe8W\xb1\xb3\x91\xc6\x03\xd2b\xae\xb2\x8c}'@Hu\x12O\x84\x1e\x0b5 \x05\xfc\xa4$\x9c\xa6\xdf\xa7\xea\x1eT\x839\xbd\x0d\xcd\xdaP\x96\xd5\xd1\x96\xdc\x8b\xd0\\I \x01bp\xec,\xbb4\\Ctn`\xb9\xe5c\x88q\xc6\xf8\x8b\xdf\xb7\xb2\x05\x1a\xbe\x98\xd5\x11\xf3\xd1\xda\\\xb3\xe0\xca\xa4\x01\x87\xd8\x0e\x9e\xb2\xb8\xc9\xb7\x08\xbf\x98r>K\xd9\xd2\xbf\x08\x96\xf9\x92\x15z\x8b\x0c\xa1\xf2}9\x1b\xd9\x1e\xde\xdf\xbb\xffpg\xf7\xfe\xde\xf5\xdbk\x07\xe76\xad\x17\xdd\xd5\xafx\x04bG\xee\xb8\x1d\xcb8R\xc4^\x9c\x14{q.\xdd\xc0Kk\xf258\xe5\xe6\x8d\xd8G\x13\x9bf\xc4\xd7\xdd\xfb\x02\x8b0X\x04\x99\xeaZ\xbb\xc1\xc0i\xf9)b\x0b\x12\xa3W^\x11\x0cr\x00\x99\xd2\x1d\xc2m K\xcb\xe46(\x9f\x83\xf6xW\xeb\xae\xb1\xb32\x044q\xf3\x01\xc2F\x9a\xc9y)\xff23\xd3\xa6\xcc\x10\xda*R\x1f\xed\x15\xa9\xc3\xedm\xb8\x0f\np\x02\x18 \n\x8e]\xae&\x02\xdcz\xff\xf7\x1f\xfc~\xafq\x1d\x9av\xef\x84\x1d\x85\x8e\xb1 \x82\xc178j{\x15D\x96a>\xabK\xb5\xea\xbe;\xd1\x05\x87\x1f\xdc\xe2\xc2N\xe4\xec\x0co\xe2\xdb\x93\xf4]/\x1a\xee\x1d\x1f\xf3\xf4\xcbx\x96\x87\xbcW\xa7\xda2T\x90\x1eJ\xc1EY\x0f\xc4\xd3k\xb2UQF\x00\x89*\xec\xb1X\xbd\x96\x1b\xd0\x07\x93\xdd\x08\x1cq\xb8}Pw\xf3\x1b\xcb\xac\xfb\xdb\x10\x95\xb3\xc8S\x1d\xc0\x90cd\x1f8\x12\x99r\x9c\xd2\xef+\xb5Ca\x9c\xc0\xba\x9f\xbe\xf5\x88\xe9/\xc7\x04\xa8}\x87&\x8b\xd3x\xb9\x8a#A\x0e)8\xa8\xe7\xd9j5b\x97\xc5\x0cZ\xcb\xf9y\xb6\x88\x93\xe0\x1b_\xf4\xe4u\xbc\xcaW#v\xd2\xbd\x1a\xff4\x8bF\xecx\x8d\n\xafV<\x81\x8fA\xcd\xf3n5\xd3\x11;l/\xf9,\xcf\x16/2\xbe\x1c\xb1\x8b\xf6\xc2\xa2\xd9C4{{\xdb^:\x16\xc5\xb7G\xecY{Q\x7f\x15\xfc&\xbf\x14}\x19\xb1\xe7\xed\xc5O\xfc4\x98b\xe9\xf7\xed\xa5\xe5\x91\xe4U{\xc908\xe3ox\xba\x8a\xa3\x94\x8f\xd8\xeb\xf6\nA4\x8fG\xec\x8f\xb4\x17|\x11\xcd\xe3\xe7\x18\xd8\x9d'#\xc6y{\x95\xdf\xc8\x97\xabw\xf1k_\x8c2\xebP>\x8e\xc2 \xe2?\xf2\xc3`\xe6gq\xf2\xa9?;\xe5#\xf6\xaeCE\x85]\xe9\x88}\xb9F\xf1\x11\xfbi{\xe9\x02u\xdf\xe6\xcb\xa5\x9f\\\x8e\xd8\xcb\xf5+} A1G\xec\xcd\xfaU\x11~\x9f\xb5W\\\x04\xa7\x8b08]d\x82\xe1\x18\xb1\x9f\xb5\xd7H$\xa6\xa4#\xf6y\xf7\xd2#\xf6M\xf7\xc2\x9f\xc6\xb3\xcb\x11\xfb\xb4\xbd\xc2\xcaO\xfc%\xcfx\x92\x8e\xd8\x8f\xd6(\xfe&>\x1f\xb1\xdfh\xaf\xc0/\xf84\xcf\xf8\x88\xfdV{\xd9\x05\xf7g\xd0\x91\xdfl/\x0bF\xb4\xe9\x88\xfdZ{Q\xb8\xc5\x17e\x82y\x1d\xb1\x1f\xb6\x97\x8f\xcfxr\x16\xf0\xf3\x11\xfb\xed\xf6\xc2\xf38\xce\xc4\xc2\x8c:,\xb4\xcf\x830\xe3\x89\xb6\x9a\x93\x0e\x95^\x0b\x88\xe3t\xc6\x1d\x8aO\xf3$\x1c\xb1\xa0C\xc9t\xba\xe0K\x81\x83~\x87\xc2o\xb1\xb0\xd6\xf7\xbcC\xade<\xe3\xe1\xe1\x85\xbf\\\x85|\xc4\xc2\x0e5\xbe\x145~\x9c\xf8\xab\x95\xf8\xc6\xb4k\x8d\xe7q\x18\xfa+\xb1F\xd2\xaeUFl\xde\xb5h:b\xab\x0ee\x0f\xa3|)\x9b\x9eu(\x8e\x8c\x8e\xac\xb0\xe8P\x01\xcc6e\xf9\xb3\x0e\xe5\x0bg\xf7\xb2\xce\xb2S\x1dd\xb8F\xec\xb4C\xe9w\xc9\xe5\x8b\xecU\x9e}\x9ag\x99 \xeb\x97\x1d\xea|\xe9'\xefg\xf1y4b\x17\x1dJ\x7f\xea\xa7\xfc\x0b\xff2\xce\xb3\x11{\xdb\xa1\xfc\x8fx\x92\n\xde*\xf1O\x97>\xae\xb7\x11;\xe9^\xf1m\xe6/W#v\xdc\xa1F\xb1a\x1c^d#\xf6\xc5z\x15\x80|~\xd5^\xe7\xb5\xa2\xb7\xf0\x91__\xa3\xc2\x8bh\x1a\xe63~\xb8\\\x89\xd9\xfcq{\xcd\xa2{\x10i\xe4\xc5\x1a\x154\xaap\xda^\xed3\xceW_\x04\xd1\xfb\x11;\xef\x00e\xc1\xff|%H\xda\x1f\x1d\xc8\xd7\xe6\xb2\x02ap\xeb\xc6\n\xeaw\x03i;;}\x96\xa6\\p\xf8\x87E\x87\xc8\xd2\x9d\xe4\xd8\xb4\x9frV;K<\xef\xa4F\x88:\xb5\xf5\x9eh\x8b\xd4\x1c\x8dg\x05\xbc\xd9\xbc|M\xcbW\xbf|\x0d\xcaW\xeal\x8az@\xf9\x8a\x87\xbb\xb0L\x88<6-\x7f\xad\xca\xd7E\xf9zV\xbe.\xd5k\xe3\x89\xf7\x15\x87\xe0\x03\x8f\xa8#/\xe6m\xef\x1a\x11\x8e\x8a\xbc\x9d\xedz\x9e_\xe4\xdd\xdf3\xa2\xe5\x14y\x0f\xef\x1b\xf1\x80\xca<\xe3\xf8\x1d\x96yF_\xa6E\xde\xa3\x9dz\xde\xbc\xcc3\xfa\xb2*\xf3\x1e\xd6\xf3fe\x9e\x01\x97\x85\xca\xbb\xbfe|\xef\xac\xcc3\xda\\\x16y\xc3\xadz\xde\xa9\xca{\xb4c\x8c\xef\xb2\xcc3\xc6pR\xe6\x19\xdf;.\xf3\x8c1\x9c\x17y\xf7\x8d\xbe\x1c\x96y\xc3z\xdeE\x99g\xcc\xfb\xdb2\xcf\x80\xcb\xf32\xcf\x98\xf7\xf7e\x9e1\xef\xcf\xca<\x03.\xaf\xca\xdaq\x07\xdc\xebv\x11G\xab6\xcd5\xd9\x1amW\xc7\xceQzs\xa8\xc5\xe8=}\x10\xa0\xad\x1a\x04D\x10\xa0\xadj3b\x1a5w\xc9\x807\xbfU5\xb2\xf5x\xfd]ugDN48\x81\x1eD\x837\xf0\x03tX7#\xd7\x12\x8e\xa3\x00X)\x8d\xb3\xdb\x87.>\xaa\xdd\x02\xb2\xaaM\xf1\xc1\xaf\xf3\x14Y\x11\x8f\x84)\xc3\xf6\xd4j\x82\x10\xaf\xb4F\xf5\x98\x06z\xc2\xff\x8c\xf9H\xf5-\\j6\xaf\xbe&\x13\xc9\xd0\x19\x14&\xc5\x1b\xd3\xd1\x0c\xc6\xc2\x82D\xff\xda\xaalar\xad\xaf\xb54\xe7\x05ab\x9b\xe7\xac5\xd6\x1a\xec\xe4Y\xe5\xae\x1d\xb1s\xdd\xc7\x01n\x96\x06\xb8\xa9\x0c\x106]\xb7_$\xa9\x86;\xb8\xbfg0\x14.\xe7\xac\xa9\xcc\xb93D|\xc1\x83\x0c\x83\x9b\xd1\x1b\x98\xa3!G\xe2\xac\xf3\x00x\xcf!\x85\x97\xb0|\x0e\xcb^\xcf\x05\x8c\xea\xbe\xec\xc3\n&p\xed\xac\xa7\xcbY\x1f\x96\x8c\x8c\xb0\xaf\x86\x10+\xe6^\x99\xf4-\x0e\xc6\xb5p\xf7\xc7A<\x87\x0e:f,\x06!\xbdM\x1d\xd7E\x0f\n\xcd\x10\x88\xb3@\x17\xadi4\xc0\xab\xe8>\xb0\x01q\x8b)Q\xa4\x19\x944b\x924}\x9f5W\xc9%\xa6\xe0\xfd7!\x1b\xd5\x8d\xcd\xc9\xc6\xb3\x9d/<\xc10{6;\xc9\xe3\xc1B\xd4\x89\x9c!\xab\xc8\xa6NyT\xeb\x07\x12\xef\xd0\x19\xed\xed!)\x15\x14\xf5\xd9\xa6 \xac[\xe2\xef\x9e\xf8\xfbTKh?p\xf3\xc46]Y\xc0\x95\x87\xcd\xec\xcb0\xbf\xb5\x88i\xbc\xcb\x9a\x83A\xa0'\xd0\x92$VI\xe8BO\xb8\xd7\x82u\xa9\x14\xcf\xf9zU\x87r)\x1a\xa9\x96_\xf3N\xb7\xab\xe5+A\xe7\xab\xe5KQ\xbe\xe3\x0e\x12ZQ\xcb\xde Z\xbf\xe3:U^_\xf4^\x9d\xda\xb9h\xad*Y\xde\x88\xf2*;u\x88\xb1ws+\xb3\xf2\xc3[\x1eI;\x8e<\x9aT\x82q\x9e\xe0#\xb1\xee\xe5G\xaf\x18\x05\x17/!\x01\xf7\x9c\xdb*w_1\x0f\xa9(b\x0f`\x1fw\xc9\xc5`Q~p\xcc\xd8\x97\x8e\xdd\x04T\xef\xcf\x0e\x8a\xdd\xc9\xc9\x00\xa3\x8f]S\xa7\x8aG\xea\x87QC\xa7\x9cZ\x17\xed\xa6\xa6\xa13z\xe6*\xb9\xcbg\xad\xac\xfd\xe4\x87:W}\xb82\x1b\xc3\x1b\xa2\xe1\x08\xc2\xe5\xbcb\xf4]{>\x8a\xb5\xf8H\xff\xe0\x11\xd3\x0e\xafi\xc8M\xdb(w;\xbbr\xd5\x94\xa7\x9a\xa0\xf7\xe6 \xc8\x9f\xab\xe8\xf7\xa1q\xce\xd7\xf5\x8c\xa5P\xcc\xa3\xe3t\xd6\x0e\x8fi\xa9\x8b\xea\x84G\x11\x1f\xb6p\xa2)\x0f\xa7<\x98\xd3\xa6`\x85 M\xf0\xe9\xe0\\\xebM\x0bH\x83\xcfCt\xa7\xd4/\xc0\xb5\x08xH\x07\xe7\x9e\xbe\xc6]\xb3\xc5-\xa8\xd2#O\x18z~\xcd\xcd.\xd1\xd0\x91\x0e\xce\x93RZ\x8c\xbcE\xa37\xb9\xfc\x08c\xd8\x82|F\x18\x817\xba\xc2\x98\xa5\x0b\xe2[nq\xe4'\x11\xf1.ps4W\x0fDu\x86p\xcd\xb5=\xac=\x8fV\xc4oH\xede\xde\xc1\xea'c\xf2\x0c\x1at:\x9b\x02v\xe8\x14\xfb\x07\xda\xb5\xe2\xaf}tj\x15\x0e\xb2\xac>\x97\x83\xc6\xe0\xa0\xb9\xbd7\xa0aJcG\xf0\x1f\x19\xba\xbap\xdfPo@o\xfd\xd4\x11\xeed\x9d\xa1\xcb\xeb\xb0\xdd\xa6\xd8\xe2\x07\xce\xa1\xd3\x15\xfbn\xc3\xbb$~\x08\xde\x9d\x17\xd0.\x0fI\xcd\xd6\xf1\x83\x13rk\xd8<1N\"\x9cA\x13\x87\x9f\xd8\x81\x13\x9b\xa9\x01T\xf7e#Xp\xfc\x1d\"\xe6'&\x11\xe8\xdc.\xd5\x8f\xde\x95\x07\x9f\xd4\xf8\x8d\xc8\xb7\x08\xaf\xec\x89 O\xec\xa08uR\x94D\xad#\xff\xd8n\xe4\xfch\xd2\x0f\x9e{\x15\x0e\xce\x8d\x01=\xc3bR(`\x8b9\x19\x8e_\xfb\xb1\x8b:q\x19\x98\x99o\xac\xe2\xf0\x03\x8f\x84\x8f1\x8c\x98`\x1e\xe6\xe0\xa7 \x0d\x16\xb60\xba\x08\xe7\x0f\xe8&=i\xcb<\x81\"Z7\x9f\x85\xe77c\x08\x9b9\x93\xf3\xf9X\xcd\xf1\xaf\xfb\x18\xb8r\xf9i\xc7\xb1\xa4\xf9E@\xe0|\x14\x01\x9e\xd9\xf7#\xf1\xfd[\xb2\x01Gy\xbe\x8c/?\xf9]v\xc6\xe4\xe8\x1fr\xf4\x1f1\xfc\x0e\xfb\xd01\x8d\xb7\xdd8\xc5\xf8\xec\x13i\xb1~\x0dk\xf7\xd98\x7f\x8deQy\xbb*\xfe\x11\xb8\xd7O\xac\x1b\xf6RD.>\xe9\x83\xdc\x14\xdd>t\xcf/\xbbn\x1f\xe6\xdc\xd5Jx\xcc\\\xfaU\x17;=\xfaP\x07\xd1\x84\xb7\x9bc\x8a\xfcY!.V\xa0\x1f\x15=\xd7\xe0\xa1\xa8\xbb\xfa\xfc\x107O\x925Ppv\xfc\x97z\xf2\xf2\x92\x84\x8b/\xfc\xc7\\\xf2~\xf8\xeb\xbaV\xf9R\xad\xcc\x19\xc5b@nq\xa5&\xd4\x1d\xbb\xaes\xa2\xc4\x8c\xaa\x8d\x8f\x86\xe3fQP\x8ar\x07\xceJ\xae\x9ak\xd3\x15FWe\x9dtGI\xce\xca\xcey\xb67\x98\x80e\xd4\\\xe3\xd9\xc9jq\xe9\x07\xd9\x18v\x16\x8b\x9f\xe3\nL\xbc\"\x97\x8f\x841k\x80\x7f\xad>K\xd8\xb3S1\x8f\xceH\x0dTS^\xe7\xf2>Bti\xd2\xdc\xcb\xebH\xd6\x11\xaa\x10\xe48\xcd8$\x82\xe8\x18\x89\xb9\xd4\xc1\x84\xf4\xa6\xea\xb8\x89\xdd\x14\xe9\x07\xa8\x98\xa18Q0\x04\xecG\xbc\xaf\x1a\xb9\xf9#\xc6\xa4\xe0\x93#\xf1D\xc5\xe6\x8b\xc1\x82\xad\xb2\x15\xa5\x8b\x08\x0f\xfb\xfb\x80>r\xfc+a\x1c4\xbd\xe1\xbe[c\x0c-R\x9a\xe4\xc2Y\x0c~\x82\x1e,\x06\xbf\xe1\xffx\xbfr\\E\xc8\x0f\x92):)\xbd\x1c:\xcf\xf6\\G%\x15B\xbb\xba\xeb:j\x11\xa9*Xy\xbf'\xa5\x1e\x15rS\x9d\x1a\x83N\xd3\x1aK\xfe\xe8@G\x98@\xd1<1\xf4\x14\x10w\x1d\x1e\x8aD\x8bg50\x15\xc3u2\x06\xe0\xce\xb1k\x1d5.w\xd3\xb0\xc5\xa8n\x9cL\xee\x8d|\xd9Nro_+\x9aV \xe9\x1c\xb3\x86\x1ao\xc8N\x06x\x84\xbb\x03\xdc@\xce\x95\x8a\x15\xb6i\x91 h\x9a\x92\xca\xa9\xea\x0f=N\xb4R\x83\xd2\x92\xbb\xf2Z\xb57\x91\xa8b\xd6\xd8\xf8\xed\x05UIFm\xb9 A4iI\x90\x0f2\x96\x8b\x99\xc5\xbaf\xa4\x9c\x9d\"\xed\xd5\xac\x18|\x01\xf6\xc1\xef\xf5\x9a\x19\xc0\xc4\x90\xb6C\xfd\x88\xec\xc9\x9c\x02\xb2\xbd\xd9\xeb\xf5\x0be\x19\xc3\x88\x96\xa9\x0e\xd4O\x82\x9cE\x92'q\xc8D\x12\x89\x8d\x0d\x94/b'lb\n\x8d23\x084W\x9a\xd2\xd6\xd3eG\x90.\xc6\x03\x1e}\xc2\xf1\x07\xd7m\xcf\x95\x98x\x8d{\xf7[!\xba\x19\x8b\xa3\x07`\xf1\xc3q\xab\xbe\xea\xc5\xb6\x03\x8b2O#\xdd\x82}\x05\xa2\x81\x08\xc0\x1b\xd9V@!A\xf8\xf5KmMtgu\\\xdcuc\x94\xc1\xf2P\x93\x1b\x1f\xb9\xce4\x8f\\P\x87\x9cG\x12\n\xc3\xb1~%e\xb8\xa1 P\x8c%L\x85\x9aT\x03\x12lg\xd4\xa2\x9dt:\x9c\xa9m\xf5!\xd5gd\xc7\x167[\xb6\xc8Z\x19i\xda\x15\xe5\x86\xd6\xb7\x1e\xd4:\xfb\x7f\xd3\xd8\x87xj\xe8i\xfb\x0bzb\xffo5\xf4'\xea\x180N\xe9B\xc4=\xc66\x94SQ\x8b\x91f\xbb\xb1\xea\x8d\\d\xb9\x1d\xc5\x14\x84\x83\xf7Y\x8a.1\xc7\x17 \x8d\xaf)\x06v\x88\x07\xbf\xd1\x8b_\xfc\xb4\xfa\xac\xfc>O#\xad\xbd\xde\xcc\xf0\x91\xf6z3\xa9^o\x86\xce\xb3-\xd7!M\xd7\xf9ZNX\x1ay\xb5\xca+\x19\xf7ui\x13\xf0> \xa5\x00\x94\xde\x88\x90*\xa4\x06\x16o\x00\x9e\x035&\x98\xe6J\xeeE\xd8G\xbe\x9c\xa2\xdd\xc5\x97(\x88\"M\xd2\x0cPEScl4\xc8\xa3\xd5cl\x1c$\x04\xa9\")\xb6\x8d>V/)\xb5\"\x00\xc2\xaf|\xca\xf8\\\x9e\xaf\xbf\x00'qy\"D\xdb\x9a\x90\x81\x0cv\xe9\x04\xd6\x06\xf3D\x1e\x1d\x9fcgH\xae\xfd%I\xa5n<\xff9HR\x12\xceI\x10\x85\x1a\xad\x05\xc6\x7fC\x83\x1ey\xda\x98\x00z-\xf2\x7f\xe5\x15\x1d\x83\x1a\xaeq\x8a\xf2\xe3\x89\xc8\xa5\xadu)|\xce\xad\xda\x8frU\x95.M\xb5\x06\x92\xfa\xdd\xb1\xe0\\\x94\xb6\x8b5\xec\xc3<\xf2x\x94\x1c\x1e\xff\xeb\x94\xde\xa6G\xd1\x9c:]\x9d\x8e\x92\x8b~\x81;\x888\xe5p\xd6\xba\xb0Q\xec\xe3]\x92\x98x)\x8d_\x93\x94\x8c\xaby2@J|m\x00\xb1\x1e\xccI\x8a\xb7\xbel*\x8b\x06\xfc\xd6\x12\xe1\xbc\x0f\xedf\xbb\x16A\x08\xf5\xdd/\xc21\xc4\x06~\x0cS\xb2\xf2\x9d\xd4\xb4D\x80\xfb\x8e\xc7\xb2b\xef\xc1>\x86\xcf\xa5<\xfe\x0c\xcf\x0e\x1a\xa2\x9e\x1c\x1f\x19\xe6\xd4\xea\xdch2\xbd2\x9c&5\x93J_o\xa8\xc5\xc5\xef\x9a!\x8fLA\xae\xda\x804\xd0\xfe\xdaN\x95,\xb0>\xc1,\x8f\xa8\x15\xf1\x88Zq-D!W\x07\xe1ej\xcaD\x06\x8cf\xbapR\x0c\x93\xaaa\xc0\xa2p\xe1/\xb3\x98\\p#\xdb\xfa\x12/i\xda\"\x0c\xa0\xa2\x0djB\xcd\x07\x9e\xff\x8d\xeb\xa87\xa13\xaccm\xd5\x89\xc1\xf2*\xcbm\xa2\x8aNc'\x1e|\x80\x1e\xc4\x83\x8f\x16i^\xa4\xf7j+\xe8\x10\xa1\x9e\x8b$G\xc1\xf6\x82/\x7f\x18\xa4\x9c\xd0\x84\x1e\x9a\xa0c5E]\x08\x93blF\x93\x17\xf1\x1aOH\xe0\xb8U\x11\xd6v H\xe5\xa8\xb6\x82\xee\x1a\x8f1\x99}\xf8\xee\xe3\x12\x91\xd3\x1e4,\xb3\x96\xe8;\"o\xddt\xcf\xcfM\xf7\xca\xe8xbA\xc44n\x8d\x84\x11#\x11\x987\xda\x88n\xbe\xd6\x92A*\x00\xc3\x01E\x93\"\xa1u\x1d\x17r\xb0\xeb\x84(\x9f6k\x04\xdb\x00T\x82\xce\xba\xde&b\xf4\xd9A\xa32\x99_\xc2\xe9*\x15\xbb5+J\x0c\x01?\x88\xe9\x92\x864f\x0c\xd8\xc7,L\xfd\x15\n\xdd\xc2\xa9gIS\xc5\x95\xe7\x88\xach\xe2\xc4\xee\xc0\x0f\xe7\xf4\xf6x\xc1\xda\xaf\xbe\xdcu\xe1eM\xe3\xe5\x83\x08c\xa7\xeb\xae\x809&{\xd1\x0d\xa8\xe0c\xcb\xd6\xb7{\xec\xd4\xc2\xb4\xec\xfa\xb7\x94\xc8\xf9\xc8;\xd5yx\x11}S\xf7~\xb1p\xc6\xeb%\xeb`\x8b\xf7\xb5\xeb\xae\xb6\xa5\x18u\xd6\xeel\xf4;\x0c\n\xa37tU\xaf\xf8`\xd5\xb1\x9c/v\xd95\xab^\xcb7\x91\xdd\x93\xbb\xd5E\x14\xc0D~\x19\xd7\xccVA\x9c5\xfe\xc0O9@\xd0\xbe\xf1?\xffS\xfe\xec\xd6\xeb\xa3\x8e\x92\x87}}[~\xa9T\xa6y3\xc17e\xb0\xc3S\xb2\x14\xef)%\x9a\xb7\xf0\x92*BX\x95\xce\x94zMOX\xf7\x99\x91\x15\x04\xc2z.\x04\xc8\xf0\xa9\xa8\xe9\xb9\xad8w\xc7\xd4\x0d\xecC\x80\xb9\xa6d\x93\x0c\xde\xee\xe0&&\x8c\x99?\xaf\x93))\x03t\x93,Y\xd3pN\xe7')\x89S\x0d\x0c@H\x04E\xcd\xbf\xfa4\x98\x1bj\xa2C\n\x8f\xa9\xe4\x87:\x90\x820\x06\xefz\xd1j\xcd\xf6\x92\xa9\xa5k\x9ePA\xfbl\xa5qC\xc4\xf2)\x995\xd1Bhb\xce\xf4\xc0Z\x16\xbbfI\xd3\x0fr\xe3\x1c/\xf4#\xbc\x83}X\xb2e^:K\xe7\xbd3\x9d\xb9\xbaKS\xf48\xb9C\xb3(\x14n\x85pw\x87I\xb3ej\x91;\xcd\x8blD\x17h\x9c\xad\xde\xf9\x1e\x96~\x95\x028;+M+\xb7\xa5\xfa\x17\x15\xeb\xed\x93>\x9cT\x8an\xfbp2M\x18\x88o1MW@\x90\xc6\xb3\xe5\xfcIb\xa4(\xbf\xf8\xa5\xcf\xd7mp6\xc3\x83\xd2\x19\xb2\x0fW8m\x8c'\xaeu+\xb5!j$n\xe8\xaf\x9cs\xf5\x0d{dh\xed\xde`\xa7\xf9\x04\"t\xca\xe2\x1e]\x0f\xb9'\xcbU\xcb\"\x9f\x0e\xe5\x8e]Jk\xfa%\xd0\"\xf7+\xc4\x8f\x8b*vuY\xd97 \xb2}\xb8\xc8O\xe3\x074\xd6\x9d\xf2\xd3\x18\xf2\x01Ur\x1e\x82\\\xe0+z\xd7\x9c\x8a\x04\x14R35\xa46\xa8\xf9\xaf\xa7\xd2\xa8\xc4\xba\xbe\xec\x94\xbe\xa6qB\xab\\\xb4\xfa\x91\xa3\x83f;>\x91\xd9@\xde\x1d\x19\x15\xd4\xeaG\xca\x06\xe9`\x1d\xadMZM\xf5\x83\x0c\xb5\x98fn\xd0\xc3\x91\x08\xd3h\x84\x1c\xb5\xb8\x91\x92^l\x94\x1f\xb3\xa5\x1c(\x02q\xde\xde\xd0\xd6\x9e\x96Hx|`l\x91\xdf\xf7\xe1\xb4D\xe8\xf4\xa0Q\x0e\x8c1\x9c\xeaW%\xa6 m\xb4\x02\x91\x1f\xccz\xc1\xedp\xe8\xb5b\x9a%\x14y\xf2gBCy\x81;8\x17?B\xf1L\x81'\xffM\x03\xba$\x18\xa5\x84'\x92\xc4\xd2\x15\x86 \x95\xd9\xc0\xba\xa2\x94\xc4K\xa5\xa54\xbe;\x0c\xd3\xd8\xa7\x89\xcc\x97\xec|p\xfb\xd0i\xb0h,\xa2\x9d\xb3uG\x91\x17\xbaiWxo\x88P\xdbCW\xe1N\xb8v\x86;Kux\xea\xb4\x9eL\n;\x12 \x86X\x1d\xe1[i :z\xf0'i\xb4n\xa1\\\x03i\x00\x95\xa3\x8f\x19\xb7\xa5\x0dU\x05H\xd3\xe1l XP?\xb2\xb8\xd8`*}\xd4\x93p\x98\xd0\x01\x1eJ\xf2\n\x86-\x82\xf9eU\xd3\x14_\x93zb\x020\x83\x821\"L\x8c<\xbc\xf5\xe8:\xc5\xa8\xb4\x0f\xc4J\x06\x9c|\xa0v\x00\x156\xdf\xcd\xb4*vL\xa9\xf6\xd5\x8f\xd4J\x0d\xc4\x96\x140\xecC&\xf0\x16m\xc4\xc5NA\xef\x11\xae\x04\xaf\xa3\xba\xc4s\x86\xcc\x1d\x8b_\x85y\xe4\x12\xc5\xfd:\x1aHg\x9d\x0d\x18=\x07\x1fU\x11\xcfacC\x1b\x17B\xfd\\\x8b\x1c\xffU\xac\xf2\x1b\xcc{@H\xb1\xa4\x15\xf2\x81D\xc08\x8a\xc4\x9e$\xac\xb7w\x91\x97\x13\xe8\xd8\xe9\xd2pn3\x1d\x97\xad\xc8W\xe1\xc5>\xe4d\xabi\xa2 &\x8b\xb9kD6\xf4>tQ\xc3\xf1.\xf2\xba\x96\xd3M\xfd\x04\xe5\xd7\x85J\x18\x1bhw,\xe1\x9dm\xd0f\xb4P\xa3\xcc/0=/\x1f\xb0\x02\xb7\xa2\x10\x1d\x10\x9a\xc7\x01\xda\x96\x8b\xb9\x94\xdaV\x8a\x1b\x1b\xfe\\\\z&\xdfs\x8a\x8d\x0d\x7f6i\x1et\x1f\xbc\xa3\x0d\xd4\xfc\x1b\"\xf7F\x1a\xdfA\x92\x92\x94b\xd6\xf4\x1b?\xbd\x8c\xb2T(\xc5\xa2X\xde\x07\xb4Yy\xf8n\x10\xb7\xd6\xb0\x98\xf9?\x84\x84\x93\x8b8[\xa7-l\xac\xe5G\xe15\xed\x94*\xcc)\x95\xf1Z@~r&\xb0B\xa9B\x03\xbf+?\\\xb9\xaa\xa1\x18\n+\x10W\xb6rny-\x96*.-U3VI\"m\x10\xe8\xd5\xcfEL\xc9\xd57]D@}&\xa6)\xc5\xc6\xc5y\x8f\xfa\x02\x99>\xac+}z\xf0\x16Q\x01\x0e\xc8\xd4%\xbe2el\xcc\x17\xac\x9c\x05\xdb\xe5a\xe2s\xd7\xd7\xfc`@-^#wA\xe4\x11K\xfb@\xc4a\x99\xf6\xb11\xc7\xc2=\x8a\xa3W\x1do\x1f\xae]a\x0e,GA\x1d\xf2 \x06N\xbe\xf6\x00\xa4\xff\x16\x1cVi\xc58<4\xcb\xc6\x1fLJ\xf3\xc7\xf6a\x0c\xe2\xea\xa3R\xd3\xc9Y7\xb9\x83\x04\xf3\xc2\xfe\xd6\x98s\xd1D\x19\xc0\xfctf=\x84Q\xbc\"A\xa9\x07y5\xed\xa8o\xa4n\x1f\x0c\x1e\x7fz\xa0/\xfc\xd0O\x1a\xfd\x13\xf2\xda\x05\xc7o'2iNd\xda\xf9\xd3k\x88L\xda\x82\xc8\x84\xea\x8e\x11\xdbKe\x9csL\x0c\x95\xad\x81\xc9\x89\x17)\x8d\x19e\xe9\xa3\xe3\xb8 h\xf0P\xb2\xdd\xca\xdbC~\xfe\xfd\xa0)\xa8\x92\x80d;\xa2\xcb\x8d\x84\xdb\xb2\xa4\xa0\xd9\xb5\xb1\xd8\xb5\xcd\xfd\x81\xa26\x8b\xed\xbb[\xfd|0\xd9d\xab\x1f\xfb\xb1\x0e\x05\xc10\xcb\x11\xf0\x85GG\x8d\x0b\xf2\x03&\xca\x07\x82\xef!iJW\xeb\xb4\xfb j*\xb5\x01x\xe32\xae\xea%\xad&\x82\xea\x0eR\x94\n\xf6\xe5\x91Woc\x8c7`\xe7\xecc\x9adAzDVt\x0c\x0d\x01-\x18]{\x17yc\x83m\"p\x85\x0e?\x9d\xb8\xe2A\xa1\xab9u,\xc4@\x03q\xac\x95VM\xc0J?sy\xf6\xbcA\xcd+q\x95\x9f\xf1\x8a\x9eI\x89\x0fs(\xf2\xe6\x1d\xea\x01Q\xcb\xa7\xe9D\xaa\x82[\xfb\x0e\x11Z\xe5S\x07\xef8\xa7:[f\xb1\xc8\xfe\xe0\xdc\x0f\xaf#\x8c\x02j\xb3\x15P?\xb9\xdd\x80U\x8b\x99\xb7f\x8a\x95(?\\s\xc8\xd6n\xae\x11\x08rm-\xf8 \x90 \xa6d~\x07q\x16\x86~\xb8\xb4\x89\x01E\xabZc\xf9jU\x95\x1e\xe5\x19\xc6\x0d\xd9\xf0\xe5GL\xf4\xadA9\x0e\xcd\x9a\x85\xb0\xe0\x00\"<\x96\x10O\xfd\xe7\x8d*Z\xc9\xf6\x85\xf9\x06m&\xef\xa4\xa9Q\x10\x0dg\xe8\x14B\x18\x064\xd3W4\x96m\xd32\xc8\xca\x08\xe3\xeb\"\xafns\x1f\xa0(\x85\x1a+\x7f\xa9x\x06\x12\x13\nZ\"\x97\xc7\x85Pjb\xc3B\x0d\xdb|\xfe\xe4\x92\xb9\x8a]E\xa3\xcd0+\x90x!q\x92m\xbc\xcb~\x9b\xde\x01\x9d\xa9j\xba@\x07_m\xf0v\xe2C/1\xb6\xa1BU\xc3\x01\x97O\x9d\x82o\xe5\xad6l\x18\xd8\x87\xb9\xbd\x8a\xd4\x17\xdd\xe4D\xa8\x19\xb1K\xdcq\xd2\x9a\x99\x10\xc0\x957 \x13\xb8\x841\xac\xfb \x8e\x8b\x87\"i\xe3u\xa6\xfa\x11I\xfd\xb0\xabvZ06\xc6\xb1\x18k\xe3\x0b_\xb3\x07T\\MrQ\xc3\xc9\xf1\xae\x90Y\xa4ZV\xd2\xad\xc4\x8eX\x06F\xbaV\xfa\x99-}\xd8\x07\xe2\xf6+\xc97M\xc7\xf0\x8d\xed\xc42;S4\xaeX\x8ai\xb5$z\x99\xd7\x89\xc4\xcb\xdc\xb3\x07\x87\xd1v\xa6\x8d\x11\x1c\xda\x0eQ,E\xc3\x08\xdb\x0e\xab\x15\xd0\x0f1\x9e\xa0\xe1\xe1\xad\xed\xe1\x89\xed\xe1+=0\xa6R\x01\x91c\x9d$=\xb3\xfc\xce\xcal\xd8&?\"hg;\xf1Le\x83\x05\x93\x84v\xb2\xadW\xb7j\xee\xaa\x9f\xf0\x95\xc5\x9a\xb4Nu\xd4\xd1\xa83\xb1\x19\x1a\xe4]\xf9\xad,\x8d\xe9\x8dt\xa7W \xda\xc0\xc3A\xc9\xb2\x90\x07\xbc\x8ey\x90\xbc\xa6\xd7@\xe1:n\x1c:\x0dg\x18a n\xc9{Hr\xd5\xd9\xdf\x177Fm:\x04\xe5\xa8\xc9\xda\x13a\x10\xd7\x11 \xbf@n\x1e!\x14pE\xcb=\x8dE`\xa0(E\x03L\x05\x8bV/]\x17&r\x1dr\xef\xa2` \x9e>\xc8\xb8\xa3\xfaI\x1d\xb9\x99\xa8X\xa2V\xaf~~\x88\xeb\xae\xfaI\x9d|\xd3>\xacC\x17\xc6u\x10|\xd5\xd4\x93\xdc$\x01C\xc9'-\x07\xd2j\xc8\xcd\n\x04\xe2d-x/\xb1w\xd2Z\xb0\xf8R\xad\xb6T\x08\x14J\x06\"K;\x87\xa0\x8f{z\xcc\xa8B\x9dv\xb5\"]\x07\xd6\xc8/<\xec\xa6\xd4\x0bL\xe5\xfd\xacF\x11U\xb0\xb9F\x99\x13or\xea&\x0e*\xb3\x92\xb6`\xac}L:/\xc74\x10\x80\xa9^\x1f\x17\xca\xd8\xc2PB\xcc\xd5\xd0e\xaev\xbc6\xd3\x84T\xc3:\xe5\x1d\x943\xd0\x9f^\xd2\\\xa1\x02\xf3\x88&\x10F)\xac\xe3\xe8\xda\x9fS \xf0\x18\xdf\x7f\x0c\xbcA\x93b\xc8\x86\x0b\x9aH}\xdaE\x8c\x90*\xc7}e%\xc5\xa85\xf4\xb9&H\x0bz,\xf1\xcf\x02\x80Hh\xc5\xebK\xac\x81\xa8\xbc\xeb\x89\xf4B\x90Tm\xe0\x95\x88\xe0\xed\x9dt\x8a4D\xe8\x9dfx}!\xe2\x99\xa7\x85B_\xa8\x9b\n\xee\x02\xcf\x95\xb4\xa4P\xb2\xdb\x19\xe8f\xc0\xb3\xcd\x8f\xcb\xef6\xa0@\xbe\xfc|\xd0\xe0s\x1c !\x88#\xc4\xd4W\xab\x9d{lwa\xd1o \xae\x1d\x1e\x03\x9d\x0egu\xf4\xa9\xaf\xc3\x88\x9b\x9ar\xa0\xc9\xcbd\xcc\xc72\x9a\xb9}\xd8T\x1f\xabz|\xa0\xdc\x1d>\xd7\xd2c\xd1\xd6\xcc\xad\x9b+\xa19]\xdan\xce\x1f\xecs\xa6\xea\xed\xd9\xfd\xbd\xf6\xfa,\xcdMR\xa4L \xbd:R\x8e\xbf\xa5F\xf6\xab\xd1\x94\x0d\x03;\xd5\x0f\xac2W\xd8\x87\xa9}]\xb8\xa9G}e08\xacd\x92\x8f9\x10\x8b\xc8N M\x9d\xea\xfd\xbei\xa4\xef\xf5#E\xaaj\xd3\x16\"|\xa7\xc4p\x07\x81\xb4]\xa1\x12|\x7f R\x9fom\x8fJ\xcf_\x1d\x7f<,?/eU\x1a\xbc>|s\xf0\xe9\xdd\xe9y\xb5\x9fQ\xa5\x1fY\xef\xcd\xa7w\xefJ\xf5\xb6wJ\xf5\x82\x88\xcc\xf1\xc2\x94}\xa9>8\x08\x82\xfc\xd9\x01\xe3 \x8a\xc7 Y\xd0w\xf2]\xf9CWA\xb6\xa1\xfcV\xab\xcd\xb3\xd5\x1a\xb95\xf6\xa5\xfa\xfek\xf9P\xfeP+\xfc\xf5\xe0\xfd\xbb\\q-`\xb0W\x9a\xdb\xfb\xb7Go\xdf\x1f\xbc\xb3-G[0Z \x98x\x84\xbb\xedv\xd9\xb7n\xe9\xd9\x9a\xc4\x18F\xd1w\xba\xf8\xb5\xfc\x14\x93\x19\xcb\xe7\xe2G\xb9\x06\x99\xcf_\x95<\xa5|\xa7[.\xeb~\x93M\xfc\xb4\xea\x06\x1d\x15\x00-\x95\x8b\xb4Z\xdb\xfaDq\x08\xbdRyV\x80\xacT\x9eh\x9cE\xad^\xa1\x01F\xbd-\x15y\x18\x07\xbaL\xaba\x1f\xb6\xcaE\x0c\x81\xb6\xcbE\xf3z[\x97\xf5\xb6\xae\xebm\xad`\x1f\x9eL\xcfn\x87\xc3\x8d\xb3\xdb\xe1\xd3\xb3\xdb\xe1\x8fg\xb7\xc3Wg\xb7\xc3\xc3\x8d\xb3\xdb\xd1\x9b\xb3\xdb\xbd7\x1bg\xb7O\xb7\xcfn\x9f\xeen\x9c\xdd>{s\x96\xbdy\xf3\xe6\x10\xff\x7f3\xbb\x9f\x9ee\xaf\x9f\xb2\x97\xb3\xd7?\xbey3s&\x1dV\xf2\x8a\x97\xb0\x1a\xee\xbd3\x19O\x7f/W\xbb\xff\xdd\xadT{R\x1e\xd6R\x0c\xeb\xe9\xceY\xb69\xdc|\x8a\xff?\xab\xd6\xba\xc3Z\xfd\xb3\xe9\xd9\xec\xec\x1fg\x9f\xab\x8f/\xd8\xe3\xdf\x9d\xc9\xb8s\xdf\xe9\xdcw\xa6d\xe3\xefg\x1b\xb3^\xc7\xfd\xf3\x13\xbf\\\xf3\xbc\xa89\xfd\xbdh\xcfu&\xe3\xff\x98\x0e7\x9e\x91\x8d\xc5\xec\x1f\x9b\x9f\xef\xf9\xf7\xbf\x9fm\xfc_\xcf\xcf\x9e\x9cM\xc6\xff\xf9h\xff\xacw\xf6\xe7\xfe\xf9\xd9\xa0\xf3?g?<>s\xce\\\xf6\xf6\xcc\xfd\xe1\xcfO|\xddYqc<+F\xc3\xc2\x8an\xb4\xc5\xbf+\xd4\xbc\xde\xd4\xa1\xb1\xa9gEK[\x9b-Z\xba}HK8\xbe\x87\x8e\xf5\xc4\xd8\xc3\xf6v\xd1\xd4\xb3\x91\xf2}K\xe9b\xb3\xf4c\xa7E\x87\x1a\xbd\xbaF\xc5,\xc7\xf0\x14^\xec\x0bgI\xf6mg\x0f\x13Zn\xb0\x07cx\xb6\xc7\xca0\xaa\xf8\xd6&\xdc\x0b\x9bF4a\x1c\x0d7\xd1\x9ca\x83U\xea1\xb0\x8cacd\x1d\x98F\xff]\x8c\x82Or\x02\xdd\xb3a\x97\xf7\x9c\x97\xfc\xff\xb0@\xadr\xc1JF\xa3]\xa5(\xc5J\xd5\x82Q\xbe\\\xac(\xe4EjK\xd7X4\xdcT\x8a\x16\xbc\xd6\xb6R\x14\xf3Z\xa3\xa2\xe8\xff\xcfJ\xb6\x94\xd7\x00\x0b\x8a\x97\x1ew\x1f\xc3\x18\xb6\x95i<\xc1\x11\xaa=\x9d\xb1\x92=e8\xff\xe7\x7fc\x9d\x1d\xa5\xe4\xff\xc6:\xeaL\x91*\xb0\xd2\xa7\xc3J\xe93V\xda\xedZ\x17\xe1\xc0\xb8\x08\xb8\xfe\xbb;;[;0\x01\xeet\x87y\x0b_]\x92\xf8U4\xc7\x9c\xa8c\xed\x83\x9d\x9d\xcdg\xbb\xd0\x03\x87!\x0eka\x17^\xbe\x84\x11\xe3uvv\xb76\x87\xe5G\x8f\x18\xbc\xb7\x14o\xd9\x82_\xcb\xed\xe4\x8e\x85\x9a\x043\xee9\x9b;\x8c5\xfb\xa0);\x054\x97;\x85\x17\xb0\xb9\xb3\xfb\x1cN{=\x17\x8e\xa7\xa73\xd8\x87+\xe7\xd4\x85 \x8c`\x0c\xc3>|(\nu\xc4\xe9\xbdV\xc1\xa9\\\x94Dx\xdf\xc7\xc3\x17\x0f\x16~@C\xb2\xa2\xa8,\x0b\xd7Y\x8aN\xb4Q\xe2\xa7huH\x07\x81\x1fR\xb5\x0c6D!:\xd0\x97\xe6^\x1f\xcb[\xedX8\xcf,\xc6i}\xff\x0f\xed\xfbt\x10\x85\xbf\x918\xf4\xc3%w\x8d\xce\x7f\x8a@\x85\xa8U\x12\xed\xeb\x16\x87\xad\xcbQMe\xc4\x18\xb7\x9a\xd1\x99V\xb9{]$\xa4\xab\xcb\x8e\"7\xf0>\xd0\xc15\x8d\x136\x8dG\x8f8$\xba\xf3l\x1d\xf8\x1eF\x1d\x84h\x01\xff\xc1\xba\x84\xb9\x1fS/\xf5\xaf\x91\xc7\xe2IC\xf2\xa4:\xf9\x9b\xe5\x9a@<\xc6`&@o\x89\x97\x06w\xc0d]\x99\x03\x12\xe3E\xb3A\xb0-\x85w\xe0O~w\xd8\xa17\xeb\xb9g\x03\xf9\xed\xcfO\x06\xf4\x96zN8\x1d\xce\xb8\x17\x1b\xef\xc8\x0f\x82\x8dE\x14\xaf\x98\xa4\"\x1a\x04L\xb0I\xa1>Z\xc6\x8e!\x03\xf96L\x9d\x18\xc3B\xe2^\xf1\xcb\xe5\x9b\xb2\x9c\xcf.*z\xcbB>\x13r\x11\x88\xf6%\xccD\x9f20\x1b\xe7?\xe5\xc3}\x081\x12%\x1dx\x97\xd4\xbbz\xe7\x87\xf4\xc7\x98\x92+\x0c{\xc1v\x90\xec\n\x0d\xdc7\x8b\xaf\x7f\x88^\x93l\xcd8Y:o\xe8\xb4\xb4\xba\xd5\xccb\x07?=\x0c]\xea\xb8\xb2iX\xed\xd3\x83\x9f,\x8b\x9d\xdeDE\xc2O\x06\x988\x07\x08\xf2\xc7\xb8\x0e\x17\x83\x94&\xa9\x13\xa3\xa8][\xda\x94,\x81'o\x01g\xe1\xc7I\x9a7\xe8J \x94\xc6\xc0zI\x84\xeef\x90\x92\xe5{\xb2\xc6\xcb[9\xe2\xc7\xe9%\x8d)\x9a\xbb\xc1:\xa6\xd7~\x94%\xc1\x1d\xcc\xa9\x17\x90\x98\xce!\xc9\x16\x0b\xff\x16\xa9b\xf71\xf4 \x86\x1e<\xee*\xc3x\xec\xf6\xe1\x9c\x0f92\x0fy\x1dS\xd6\x8c\x93P/\n\xe7-\xc6,\x07;\x8dg\xb6xr::\xfa\xd1b'\x89\xb7\x0cy>\xb5\xf2\xba\xa2f\x10^\xe8QA\x18\x93Ib+\xdcH\x11q\x8c\xd1\x81\xf1(\x89\xb8\x83\xad\x8fw\xbfB\xed\x06\x11\xbc\x00\x9f\xfd\xe9\xed\xc3\xc8\x15<\x83C\xb0\x8e'\x8e\xb4\x03\x06PW\xf0~/\xf6y|8\x82|\xcfh\xb4=\x1a\x8d\n`\xd3\xdb5\xf5\xd8\x9e\xb8&\x81?\x87\xbf\x9c\x1c\x1f\x15\x11\x0cuv\x8bhp\xb5\xe2\xab\x96)4\x84-E\x92\xc6\x94\xac\xd0\x16\x89\xf8a\x02a\x14n\xacc?\xe4[=o6\xd1\xb6+n=\xd8\xbc2\xd3\x9ai\x96\xecu\xb1d5\x87M\xbc\x7f\xe1\xeb\xd5\x87\xa0\xdc'B8\x1e\xf8 \x17\xfd\x9cP\xc1@\xa1\xaaY\xd1xIaE\xd6k?\\&\xcf\x11\xdb\xc4\xdd\xd6\x1c\x92(\x8b=*.9\xd8&P\xc9\x1aC\xc3\x8c\xaf\x1e\x13\x16\x1d\xc58\xf6\x8a\xdea\xa2\xb7|A3x\x01\x01\xfb\xc3\x17\x14\x9dd\xa6\xd9,\xdf{)\xda&`r!\x1e\x95 \x9c\x12\xb6\xeb\xf9\x0fU#\xae\x03\xcf;\x05\xa3\xd5t\xaa:P\x05}\xf0\xeax\xcd\xb0\x90\xb3MN\xa4\x9e2y\xc4\x11\xf8\x07\xe6\x83N\xc9r|GV\xc1 \x8a\x97\xfd\xcd\xe1ps\x8c\xf0\x13\xa6\xf3u4gm\xf3\xf4\xd2~\xc2\x99\"\xdf\x96\x958\xe0\xe0\xf4\xf0BL\xc2.\x80\x17\xe0\xb1?\x1cv\x12\x17\xfci0\xd3\x9b\xe4!\xf6\xe6\xd5\xeau\xf09\x1d\xfc\x91\xf0\xbb\x95$\x8f\x82\xcc T\xa7X\x13^\xe0p\xbe\x08\xd8\x1e\xc3\x0c_5\xd6i\x1f2\xfe\xa4`\xb0\xca|\x01\x9dK\x14\x83+z\x87!M\xd2i\x84\x17\x7f\xf9\xadM8\x8dfZ\x01(\xb5.\xfe\xa7V\xb2\x94\x102D\x8aMN\xa3\x14JR\x8c\x1c\xf32\x15?{=&Vl d\x98\x80\xa3>\xea\xe7\xa2\xa6\xb5E\xce\xcb\x15\xaf1\x1e\x9d\x83\x87\x00\x02\x16\x9d\x9e\xd8\xf6\x92\x84\x8aSx|\xd6\xc3\xe4C\ng\x8a\x13\x90\x8dY!\xf37\xd3\xd9]J\xc69\x94\x19\xfflSx.\xb2~GZchqyr\xe8D\xees\xd7\xd4Z\xaf\xa7\xb6\xa7\xdd)\xb8\xdb\xb6\xb8he\x08\xf0?\x8f,\x979mz\xd6\xbe\xfc\x19n.}\xc62\x8c\x86\x05#7\xda*\xbe\x8bb\xc3\xb8;7x\x14\xe12\xd6k t>a\xf2\x90f@\xf7!fx\xc5\xd7\xfbm8\xe7\xe6\xcd\xc3\xe7R\x90e\x0b\xa0>d\x95\x1f<\xed\xcf\xba]\xb6!8\xf4b\xba1G\\e$/\xf8c\xcel\xce\xe9\xc2\xf7|V\xec\xe3S\xe4\xfe\x91k\xb3b\xe5\x1b\xc3~\xed\x8bD\xb3r\xc8ZR\xd0q\xb6wpl\xa6\x8d,2\xe7n\xefr[\x01\x0c\xfd$\x84\x96z]\xe81\x82\xdaTe\x93\x13\xc1\x90m\xc5\xad\xbe\x80MC\xff\x9d['u\x1bd\xc8\xbfke\xc0QNjTf\x81\xeb.R\xcc\xda\xcfc\xce\x15\xcf\xe2AL\xd7\x94\xa4N\xf7\x0c\xcdd`\xa3\x94(K\xd7\xf5\x8f\xda\xae\xafE\\A\x89Q)\xd1X\xe2\xf9\xdck2\xf4.\xaby\xb3A\xa8\xa5u\x99Q2M\xae\x11\xeetQ\x08\x95\xbcM1=\xfe\x831\xb8\xf2;;,\x88\x90 \xda\x11+lk\x9b\x93\x13\xfc~\xebX_Dtp5\x97\xbe\x92\xb9\xed\x0c\xfbP\xa6\xffHbY\xf1\xc6\xc8\xad\xef\x96}\x06c\x99\xbb*\x0b\x82v\xa3\xafu\x9f{.\xf0\x0d\xc2O\xdf\xdf\x04q_\xf0<\x1e\x1d\xcc\xce\xc2\xbb\x92\xc8\xe1\x96\xc7\xd7\xa6\xf3~q\xd8#-\xc8\x8f{1\xa5\x97\"^\x8c\x00\xb0+\xce\xb1\x0b2W\x89\x00\x93Z\x08$\xf4o\x19\x0d=\n4Lcm\x94\x80|b\x15\"\x93ji\xa9$\x01\x9dL\xe0\x08\x13\x9c\xd0W'\xc7\x1dd'\xe8\xe0\xca\x0f\xd1\xaaG\x8e\xa0\xdb/6\xd3>\xe3\x0c\x9b\x18\xca_\xcd4*g1\xf95\xbev\x07T1\x9dMq\x8b\x9f&N\xf3\x11P\xd8\x0f\xe8\xdaQ6\x0c\x9b\xbfI\x03C\x84X\xc9\xafv\x18U\xde\x15\x1cP\x9b\xd3\x82\xf1@\xc8\xcfw\xcc\xdcA\xe5\x851lq.)b\xef\x12%\x01g\xb7\xd3\xe9\xb6o\x85\xbf\xd1\xedC\x99\xd11\x98<\x1b\xd9\x816\xdd\xd5^\xcc\xd9\x00\x85\x0b\xd8\xdd4\x1e\xfd\n\xe5(lF\xd8\xecc\x9d \\\xdaem\x86W\xb0\x89Y\x98K\xb04\x9cK\x9d\x80\x10Do\xfc\xf4\xd2\x0f\x81\xc05\x8d/H\xea\xaf\xd8\xcaW\x15<\xa6p \x82sS\xe6\xdb\xb9\xe5\\\\\xbe\x9al\xaf\x11\x98H \x98,\xa5\xceC\x08\x90B\x10\x06z\xeb\x05d\xc5\x11pE\xe2\xab\xa4\x9b\xa7k\xae\xc0\x82\x1dP%\xf1\xa1\x87\xc9\xed\x84bG\x95QCR\xd1\xe9T\xfaL2\xef\xb2$r\xcb\xcc\xe5U\xf4\xe1\xa4\xbd\x1d\xdc\xeb\x0b\xdd\xbc\x9ew\xb9R\xaa\xd0\x15\x18!\xb5\x08\xa2\x1bF.\xd9v\x8d\xe2\xd2\xf8\xcb\xab\xa6#\x7fx\x90u\xce\xf5\xfd1x5\xc0h\x8c\xf6\x1b\xb1\xcb\x03KH\"\x1a\xc3\xb8\xae\x06\x0b]\xa5F\xaep\ng\xa8\xe6\x1a\xb3]*N\x89\xa2\x16+\x93Ou\x8f\xeb\xf2\xb3\xac\xcf\xb5mY\x98k\xd6\x94UG\xcdZ\x88\x9a\xb5\xc7\x98\xda\xdeJ\xbc\x7f6\x13o\x0dY~\xca\xc9r\xf8\x15d\xd9\xcc\xc8\xe8Is\x08\xa2\x86J\x9e\x0d\x03(af\x15\xab\xe5\xc6\x0d\xc5\xc6\xe5\xa2f\xe7\xc4 \xd9\x0en\xd3\xa2\xf6\x84U\xb6M\xae\x03)\xf6cy\na4\xa7\xb0\xca\x92\x02\xdfH\n\x01%I\x8a\xaa{E\xcbV:\xa6\xed\xbb\xa9a\x81\x7fS\xb4a\x9as\x01\xddqQ\x1b\xb6\xea\xc3\xb2\x0fw}\xb8\xe8\xc3y\x1f\xae\xf8e\x94\xe6\xd0~o8\xcc\xff0\x1c\xe6\xcab\x07~\x92\xd2\x90\xe6\xb2\x12\xff\xe5t\xa35\x0d1\xbfx?\xc7~~}\xa3@A\x16\x08~E\xfe\xcc9\x15^\x80jO\xd8Gc\x88u\xc1\x97-\xf8W\x11q\xad\xca\x88:\xefs~\xb5\xcc\xbe\xc1\x84\x03\x01\xd3_\xa9B\xa6\x90:\xf0\xba\xae\xfa\xf0\x85P\x84\x9d\xa2\xf1\xa5\x8b\x17\x1e\xec\x85\xd3\xfa\x19*N\x14\xe4\xa0\xee\xefq3>w\xcb\xc3\x9b\x14\xa3[q~\xec\xbb\x0c\x12\xc6\xd8\xbcn\xfdV \x832\xbfg\x83\xf4\xf3\x1b\x9cS\xf6`-6\x15\x93\xfa\xce1\"w\x0et/'i\x98\n\x80\x1d+}\xb8*\x1f5\xa5{\xc4\x1cR0\x01\xde+\xca^W\x08\x9c\x87\xdc\xb1\xf4\x0b%ob\x96\xce@X\xee\x98%4\xf6YXBr\xcf-\xcf.%Nj\x9f^[\x9f\xae\xacO\x97\x86\x0d\x08\xc2\x8eF\x97\xa7\xf2\x0b\xe4\xc7\x85PY\xb7\x93\x1f3\xa3\xe7\xbf\xf4Vn\x16'\xfbB`\xe6B\x1b\xa9\xf0\xb4\xbb\\(@\x81f\xe7\xa9\xf8~\x7f\xcfhyl\xb5\x84F\xad\x13\xd2\xc1\xb0\x0f^.\x02\x1auP\xea{\x8a\x80\xd7\xe8F\x880n\x03\xb1C'c\xfb\xdcP\xb5\x81\xbfR?l\x84;\xdc\xde\"s\xe1\xd6\xd4y\x85S\xce9F\xc2X\xf8\x94&k\xe2)\xa7\x8f\xaa[\x05td@\x0e\xfa\x8a\xdemp\xd3\xea\x84\xae \xf7\xf0\xc8\xd9\xe9\x8b \xf2\xae\xa4\xd6\x9a\x1d_(l9x\xd7\xb0\xe8\xc3\xbc\x0f\x97}\xb8\xe6w\x05n\x1f\xf7\xc6\xb5\xa0\xd2\xa2\xe8N\x109\x81\xdc\xc8|\xb2\xbf\x97\xf9\xfe\xc57$\xc1\xb7\xc3\xa5e\xf2+\xa6\x04\x88\x97vF\xe9\xba\x91Q2\xe5'a\x80\x17\xe6\xa0\xce\xba\x19\x17\xf8\x9d\xd8\xb3\xad\xbe\xd0\x83sM\xac.P\xbd\x85\xf2\xb1>G\x9b\x9caX\x1beQ\xf9a\x1d\x8e6wD\x8fC\xde\xe3?\xda8\xf4|\x01[\x15\xbb}0\x80\xa1|\xf2\x0b\xfc_[\x19\xab|\xab\xb1\xbd\xda\x06\xbc\xe2\xbe\xb0.\xbe\xf2\x9b4\x8e\xbb\x97%\xdc\xbdVp\x97\xd1\xdb\x1c\x7falR\x1b\xc7\xe6\xc3d^\xf0\x1f\x9c>\x82\x17\xadV\x04.hzC\xa9P\xf8xQ\x10P.\xc0R\xeeD\xc8H\xa3\xc7\xb6\x95H~\xc9\xc5=\x1f\xef\xd99\x9a\x88\x13a\x0dm//@F*%\xf6\xeb\x8a\xd4\xcdU\x0e\xe5\xeb\x84@\xb9N\xf0\n>%Q(h\xa9\x19\xe3\xc2\x97\x05z\x02\xf9\xe5H!\\ \x8ew\x8d\xe4Xj\x9b\xdb\xe0Qe\x04\xba\xb1/\xca$\x9f\xad1\xd2\xb8\x18\xe9\xbc\x874d\xc1]\x81'\x10\xf3{\x13\xac\xc0\x17A\xa9\xc3*\x89\nI\xb5ga\x1e\xde\nI'\xe0\xcc\x1f0G\xd6-\xd6\x1f\xb5\xd8\xb3\x0fQ\x13W\x90\xb1\xaasd-\x9d\xb3\xd1\xa2\xee\x83 \xd9<\xfdn[R]\x15T\xe7f!\xd5$\xf0y\x96g\x0b\x0c\x8a\xab}\xb4\x86Z\xfe9\xf9\xd1\xe9\x01 \xa7\xa9b\x11I\xf3\"\xba\x82\x87\x7f0\xe1\x16\xb7\x08\xa4\x15\xddntP\x04I\xa6\x95\xab.\x8f\x04$.S\xacnW\x12\\b\xf0deC\xdb\xde\xb2N\xbf.h\x89\x1bU\xe22\xfc\xdcg\xe4k\x82+-\x1a\"\xc8\x7f\x8d1\x80\x17\xc7K~=\xcd\x99\x1b\xef2Z!w\xb3B\x86\x92q-\xfe\xc2\xd7[\xe1A\xb3\xd8\x83b\x80\x83\xc4\x83\xbbI\xa0\xbc\xc8\x93ne\xb9\xb3D&\x9d%6F\xbfF\xf1`\xdf\x18\x11\xbe\x8e5\x0c^\x87\x0e1\xea\x16\xac\xe65m0D?\x0ey\xaf\x86]\x9b\xf9\xfe-\x89Y\xc6!X\xc7\x07_3FP\xc7\xd9\xb9q\x88r\xcf\xad\x19\x90aC*\x1b\xce0P\xc5\x1a\xa8j\xe4\xd37\x8d\xbe\x9d\xf2\xc4\xe9x5Y\xe9\x05;\xe4\x1e=\x92\xd6CDc=\xd4\x06b\xe6%\xebxP5{x \x0bdC\x169{\xc1\x1f\xb8}\xb8A\xd4[\xf7z_\xbc\xd9\xeb\xb3\xb3\xe3C\x82\xf3\xbe\xae\x98\xd3TLf\x02\xf4A\xe9\xc1\x1a\xc6\x8c\xb5\x1e\x8b\xb70\xc4\x88\xcc\xf1\xa8\xd8\xe2\x9c\x85M)\x0f\xecA\xed\xcd\xaa\x0fa\x11=\x01\xb6Q\x18\xc7\xb0\xca\xd9\xb8\x96\x83\xe7Zo\xf9\xe6\xc8\xfa\xe6Z\xf0\x8ccA\xed\xd60\xd1M\x17\x90\xee\xd8\xdaix^\x1e!\xb7\x16\xee\x0c%\xe9\xea\x8b\x83\xbbj\xfe\x05\xd5M\xf8\xdc\xfd\n\\e\x9f\x8fB_\xaaj`;\xa3\xb6\xa4\xd3(@W\x8ek\xc9A=P\xbc\xd53'[\xcf\xbe\xfez\x12\xdar\x0bUi!\xc6\xec\xbd\xfb\x9a\x0b\xc76\xe3\xb1\xb0\x1c[\xdc\xa0\xdf\x9a\xf2\x82\xd5\xfb(8\xf6\xd2\x821\xee\xbe\x01,e\x9e\xa5\x00\x8cE\x17\x18\x97\xe6Y\x85D\x19\n\x863\x0e\xa9\xd7\x8d\x83\xb7\xe6\xf9\xd0#1b4\xf6\xe3\xb2\xc3H\x88_u\xf0\xf2}\x94Kt\xfb\xfb\xfb%\xc3\xdfG\x8f\xb8\xf1\xe4\xc4\xca\xefK\x1f\x9f\x82\xe3O\xfcp\x19P\xf8[\x16\xb1\xaab\xedEBJ\xf3,5\x1b\xe9!b\x86\xbe\xd3o\xb1ST\x01\xc3\xb0k\xb69z\xb4P\xd3}\xfb]\x13\xa29\x85v\xd7\xb4\x18\x8fU3\"|W\xb3|\xd0Z\x8a6t\xabC2!>\xaa\xb16e\x9b-\xf6\xa2\xae\xab\x9bvW4\xae\x8a\xfd\xe6}\x98\xeb53\xee/\xca\x90\xfex\x9a\xcd\xdc\xd2\x01\xf3\x01}G\xd4I\xb6h\x11%\x9c\xd1\xa60\x83\xc3`\x93l/m\xa2+\xf1^.\xcal\xc3\x18\x9e\xee\xe4?\x99\xd80t\xe1%\xfb\xaf\xc5]Y\xc4/\xb4}n\xb4\x1d\xb1\xf7\x9eC\xb4\xb1\xe1b\xef\xaf\xda\xc2\x8a )0\xc1f\x1c\x1f^\xbc\x80m\x17z@r\x91*\xdf\x81\x97\xf4\x96\xcc\xa9\xe7\xafH`wiR?*(\x0f\x1c\xbf\x82/f\xbe\x85\xc3RR\x81\xab0\xba \x81&\x1eY\xd3\xdc\xd8\xd3\xd6u}g\xd8)iVPR\xbe\xf5M\x94\xb4\xde\xf0w\xa2\xa4\xf3(\xbbhCI+\x83i\xc1K<\x84\xb4\xeaG\xa1%\xad\x8a\x1aG\xc95o\x0e\xbd\xc6!\xad\xa7\xaa\xdb\\\x87\xd1|\xf1\xdd\x86\xaa\x1a\x1aie\xee\xc4M\xe0n\x85\xf5[\xe7\xc4\x89\x19\xd9l\xd3b}0\x0f2y\n|\x92<\xc8\xe2Ic\xfc\xd8/\x9b:)*\xf5J8\x16\xd5\x10\xf2q\x16\xe6j\x80\xb9\x18G\xc5(N9\x93T5}8\xab\xde]\xd5\xd9U\x86&_j\x8a\x82ZWO\xea[\xd9IiV\xce\x99/\xba\x19z\xdd:^3b1\x88\x9c8\x1ew\xfb\xe4D\x1a\x85\xde\xad\xa7\xc5\xf7\xedM\xa5|\xab\xf8.\x15}\xf8cW\xad\xf4L\xf9\xae\xd4\xd9\xdaS\xea+\xe5\xcfx\xa8\x07\xcf\x8a\xe5x\xe2\xec*\xdd\x0b\xb5\x99\xc7u\xf4\xb7\xcd\xdbHHg\xf7\xf7\xdc\xbe\x8f\xa1y\x8b\x8d\xd5\xcc\xaeD\xe8K^fw\x85\xd5\xba\xd8`\x9e\x95\x0b\x11\xd6\x19\xd6Dp|A\xbfh\x8a\x16\xe1YI\xaf\xb8\xb5\xd3v\x10\xf6\x01\xa0\xafL\x8b>\x9b\xb4\x12\x8dGM1G\xafY\xfb\xc8\xda\xbc\xc1\x8a\xcdV\x10Y\xaef\x91\xd74\x8a\xf1Y\x90\x17p\x95\x89rrn\x8cjw\xd4\xfb\xf6\x04o\xf2C\x14\xf9\xfd\x8b\xb5U\xe2#S:X+\xda\x839\xab\xc0\xe7\xfe\x1f\xdcx\x80\xd1'u%\xc4\xfduI\xe7\x16|{=\x8e\xbe\x14/\xc08/\xc3\xe9gg$y\x191\xde\x0d\xc8\\\xdb\xe6t\xfbp((\x9fS\xae!\x0c\xcd\x0c\xcb\xd1\xe0\xf2`:\x11\xabC\xedtr2\xc2]\x82\x05\x99Y\x94\xe8\xcb\xba\xaeQ\xe1\xacH_ZQr\xf2\xf7\x87@\xa1\xdc\xd1:\xf7f\xc9\x8d\x0d\xba\x93.\xea\xa6,u\x95\x12q\xb3[\xd8\x81\x15gur\x19e\xc1\x1cmu.\xc95\x05\x12\xdeI\xcbk\xbc\x84\x95\xfe\xde\xad\xaf\xbb\xf3{\xc5Buv\x9a\xcf\n\x8d<\x85\x8dg\xa5i1\xean\xa7[\x14\xe8\x9d\xcd\xba\x93n1S\xab&y\xc9ugw|\xed\x85\x11\xd2\xe9\xdd:OZ\xf7\x1c\x96\xf0\x02\xee\xd8\x1f\xf4\x1f\xb7\xd2\x1c\xe7\xa2\xde\xcet9s\x072\xe0\xbb2u;\x9dPp\xe2b\x90'lW]\xd3\xe4:_\xf0\x1b\xe6/\\\x82o\xbb\x7f\x05\xb1/\xb1t\xe7\xb6`T\x0b\x86N\x19\x13\xbfw\x16\xc7\xdb\x91\xf0\xf0;\x9a\x863\xa9cc\xf4\xf4\x0f\xa1q\xe0\xf44W\x82\x15hZ\xd2<\xfc\xc9\xdcy\x99\x1e\x0c\x15\xd1H\xec\xf7\xc2=\xdfN(\xdaV\xe4\xf1\x1c\xdaW\xdet\xcb\x11]D\x84\x07u\xdc\x0c D\xb3W\x13T\xd0\xadH\\\x8b\xdb\xf2[\xc1\xd3\x8bi\xa2\x9d\xc6Z1N+\x03\xa6N\xa4\x1f=\x82%w\xf0,\xaf\xbd_^{\xc8Cq\x84Q\xb8qp\xf2\xea\xed[%\x9eL\x02$\xa6\xe0\x87)\x8d\xd71E\xc7\x87\x04\xc5\xad<\xe8\x9c\\\xda\xa4\x166\xa0\x85<;\x81\xed\xddf \xbb\x82\x15h\x80\xb0RA\xf1\xa4\xdeP\xa9d]\x1f\x1a\xc5\xa8\x0b\x15\xe8Yxp\x94\xd6\xc3z\x18\xff\xd5\xd1Fa,bAQqv\xa0\xcc\xc3\xce\xc8\xa1\xe4\x17\xf2\xb8v2d\x0c-\x03\xa0\x98\x02\x82@\xc4\x92\xb1Wrhn^\xd0\x87\xdd\x9d\xcd=\x11+U}i(k\xb2r\x8e\x15#\xb7J\xfb\xaeE\xde\xe9\x90\xde4\xdf\xaca\xe6 \\B\xc0DL\xf8[F\xcfds/~\x08\x96G\xd4Id\\\xf6T~\xbd\xbfg27>,\x02Y\xb2\xe7\xc5\xafr\x13\x9c\x13\xc1*\xe2\xeb\xfd=W\xeb\xb3\xa7\x18\xa0\x8a=\x93\x91\xaa\xf2'9\xbb\x86o\xca\x1f\xe5\xb6KB\x8cL\xc2\xcd\x07\x8a\x81\xc0\xfd\x80\xce\xdf\x8a:2\x97 \xe7\xdf\x0d\x95O\xf9\xd3|\xe8\xb8v\x052\x88rE\x171\xccG\x8b\xea\x08\xf5\xa7\xd4H\xa8e\xaa!\x10O\xf7,\xf7'\xf2\x17eB\xcb\x97S\xc3\x04\x86b-\x11\x93\x86\xdd\xaev\xe5\x97s\x93t\xf2\xdc$EZ\x12_3#%$V\x11\x82-\x86\x17\x10\xb1?<\x04[\xea\xf8\xd3xf\xa7-?i7\x9c\xdc\x99\x7f\xd5\xad\x1f\x1b\xb1p\xe8\x96\xd9P4\xfb\x95\xd5\x1a\x89%\x95\xb5$X\xa7C\x8dOA\x91\xc9!r\x8a\x8b\xc3\xfc\x86>\xa7\xa0~\xa8P\xd7>\\d),\xa2\x8c\x9drQL\x1f\x94\xc9\xa1He\xf0K\xbf\x9e\xfa\xe0\xa7\xbe1kA\xd3-D\x8b5E\x94\x89\x07\xf46\xa5\xe1\xdc\xa9\x83\x8fo\xea1\x90\xf2|Xg\x95\xe5\x90\xc8\xf7\x85\x8d\xfdI\xf9\xa9M\xe3`\xa5\xccb6?}\xe9l\xea\xf1\x81\xbf>c\x81.\x98h\xe4\x94B/V\xa7\x81tL\x1c$\xf2l\xb9\xc8\x16\x0bN\xba\xeb$3,\x93\xccX\xfc\xf4\xa2 [\x85\xa5@\xa7\x05\xde))\xd8\x07K\x9a\x9e\x84\xfezM\xd3&\x00\xd7\xcc\xd5\xeb{\xb1\xa3\x0c\xd7U\x95\x06:\xd9\x1bD\x00\xf8m\x85c\xd8\xdb\x11\x11p\xc4\xadKi\xb6\xc2:\x80\x1d\xe7\x1b|?w\xcf\x86g\xf1Y\xf8\x7f\xfe\xb7\x9aU\xa0;\xf0\xc39\xbd=^8\xcah\x90\x8a\x1f\xa4N\xc4\xef/\x0c!\xab\"\xd8@2^\x06\xf2\x06\xf6\x9b\xc2\x13\xd8\xe4\x9c\x87^X\xc3q\xc3`0\x00\x1c|o\x1fv\xf4RJ\x1bw3\x04\x91/ A\xea\x90 \xf0B\xc5\x0d\x85\xbd\xfab\xd0\x10#X\x1c\"\xc8\xf8F\x052-\xa0\xe2\xabP!\x0c\xbe_\x01\x15\x81Q\x99\x84\x87\x98\x00\xe7\xea\"\xee\x8aX\x98R\x02\xaa\xa1\x84\xe4\x95\xa1\x01x\x8f\x07\xcc\xefUkAO\xb3\xe6=\xe5\xbc\xe8A\xf7\xf7\xaeJ\xa0\xd4=\x94F\x9c\xfb\xb5\xe6\xe6UB\xf6u\xbb\xda3\xbe\xd8\xfa\x8caE\x0e\xe2\xb1\x1fr\xe1\xb1x\x86\xd1\x92\x1f\xe3U9\xe3XH\xca%\x186)\xa7\xa0\x04(\xd7\xf5\xd8\xdc\x04%(\x9e\x8b\x02~\x05\x82;\x10\x85r|VP\x03G\xa8\xa8x/c\x0e5\xd4]j\xc9tNi\xbe\x92h\x8ev\x953Em\x9d\x9d\xc6\xb1\xa3 \x87\x93\xa4q\xb7_\x81\xf5\x95\x1f\xce\xc7\xc5}n\xe9Y\xae\x90\x1d7\x98w\xd4t\x9e\x98D\xa2\x94\x8b\x00\xca\x07\xbb\xfb/\x82\x00\xfd\x9b\x11\x02\xb9c\xde\xb7\x85A\x95\xb9\xfe\x97\xc3`E\xd6&\x18\xe4\x8e\xb6\xdf\x16\x04\x15\xd7\xd0\x7f=\x08\xd8\x08\x1f\xb4\x13\xc4\xedA\x13\x00|\x19\xbe\x07Ek\xabm\xf0u\x9e\x8cR\xc8\x01&h\xca\x98\x9d\x8f\x1eA\xf7\x7f\xc4\xcd\x1d\xf2\x02E\xb9\xd3\xc5 \x15\xcf\xbaG\xd5\xdf\x9f\xde\xbd\x13\xbf+\xbcv\xf3R7\xac\xb4\xad\xb9uL1\x10Y#\xe0T\xcc\xc1Q\xdaZ\x8d\xe9:\xa6 \x0d\xd3\xb1\xa6%\x8f\x84Q\xe8{$h\x98\x01\x14\xbdv\xffG\x93J\xb3~5\x12D74\xf6HB\x1f\xd02\xaeK\x9b\xc6\xb3\xf5\xfa\xc1\x8d\xe3\xa2\xb6i\xdc#+\x1a<\xb4q\xfd\xc8m\xeb2\xa7\x0b\x92\x05\xe9Iz\x17\xd01tsxu\xff\xe5\xfb\xfd\"\x8a\xfe\xa9\xfb]c?\xd5z\xbf\x97\xf6u\x1agT\xdd\xc7\xa7\xd5\xdf\x1f?\x1d\xca}\xcd\nv\xd4\x97\x17$HJ\xb5\xdf\xd4\n\x0e\xde\x9d\x1c~)]\xb0m\xe4\x87\x0c\xfc[\x12\x90\xeeT\xa4\x13\xf81\x8a\x02J\xc2\x19\xef\xa3\x96\x9cN\xb2\xa12\x03\xed\x17\x93\x1b\x1dQ0&\xc8\x95\xf6\xa00\x91\x00\x1a\x83X\xa56\xdbXG#Z\xf5\xc5\x81=\x96\xeb\xdd\xa6/\x1d\xc9h\xd7\x97\x9c\xd7\x1b\xc3\xbc\xfe\x1d(\x88)C\xe2\xee\x03\x93\x9c\xd6\xb2\xa7\xed\x14\x03\xd54D\xda7\xb4\xa74$\xbfUI]\xa4#u~\x98\xfe;P:\xae\xb4Q5\xd8Z\xcc\x89\xccn\xf5\xba\xa8\xde \x95'q\xa3ylw\x83\x1bB\xf1[\xd4i4C\x19\xad\xdb\x13y\xdesY\x8eN{\xbdh\xe6\xf6\xa1;\x14\x99\xfe\x8d\xe29j=z\x82!\x8b\x1b=\xbfp\x14\x17\xbcQ\xb5+S\xfb\x90\xbby\xf4z\xa4\x9fb\xe6\xb7\x959\x8ev\xddA\x1a}b\x02\xe9+\x92PG@\xa2\xb1\x9a\x0526\x1c\xab\xc8\x85b*\x15I&aO\x0f\x02\x9f$4\xb1\xe1\xe2t\xb3\x0f\xdd\x0b?\xecjR \xe4\x98>\xedC7\xf2R]\x95\x1c\x8e\xd3\xd1\x10\x13Uy\xbaZ%\x88OG\xbb}\xe8^\xd2\xdb\xee\xf7\xbd\x0b0\x8b\xb5\xe5b_\x08\x90\x1f\xe9\xf2\xf0v\xedt\x7fw&\xe3\xe9Fo6q&\xe3\xe1\xfdt\xb4\xf1l\xc6\x8e\xd8\xf3\xd9\x0f\xae3\x19\x9f\x9d\x0d\xe4/VaJ\x0fgXY\xa4\xc4\x9d\xdc\xe7\x15z\xda\xc7\xc5/\xd1\x8c3\x19\x97\x0f\xf2\xa2\x07^\xf9\xecl\xe0L\xc6~\xb8\xb8\x7f\xcb\xfe\x1d\xbdq\xefyQH\xc2\xfb#rt\x7ftp\xe4\xba\x7fV-\xef1.?&\xedU:\xa7O\xcczB\xad\xf0\xbc\x08\"\xf2]\xc4gU\xbf\xcdoF\x18\xa5u:\xbe\xe0`\\\x95\xf9\xa1S\xd5zo\xf6\xcdy\x1am@\x189B\xd8\x07\xc9G\x08\x03\xe4\x1a;2H\xa3w\xd1\x8d\xdc\xd2\x8c\x97\x80 ;\xc8\xc7 b\x00Og}\xe8\xf66\x94+tdX^\x8a\x13\x86\xdf\xa1\x16\xccH\x1fX\xcdE\xc1{\x08\x0b$\x98\x88\xc3l\xf0\xe1\xf8\xe4\xed\xe9\xdb_\x0f\xcf\xdf\x1e\xbdy{\xf4\xf6\xf4\xaf0\x96\x8f\x8e\x0e\x7f:\xa8>\xea\x0eB\x12\x16\xcd\x1d\x91#\x18CZf1\x04is\xd2/\xe33\xa22\x9f\xf1\x86!\x8e\x95\xd3\x10\xb6w1\xe74\xa2\x07t\x95JN#f\xaf\x9b9\x8d\x10~`|\xf3\x18\xbf(\xa3J\xff\x9dx\x0d\x873\x1b\x9d}\xee\x8d\xa1\xe15\xda2\x1b%Bi\xc2\xf8P\xaf\x1c\xf2\x93#r\xc4\xfa\x82\xe4\xc6O\xbdKp\x8c\xca\x03\x8f$T\xd5D\x8e\xb5\xb5@\x01\x0e\"\x9f^<\xe2\x8d\xe5z\xdc6\x8d\x1d\x1d\x1cY\x1b\xcb\x15\xb5\xad\x1a#G\x1a\x8dl\xe1\xf8l\xdcnB\xeb\xf7=\xa0\xc5v\xfe7\x83\xd6\xdb\xa37\xdf\x0eZo\xc3E\x1bh\xd5)\xd0\xf7\x83\xd6\xc67\x05\xd7\xc67\x85\xd7F#\xc0t\xbb\xbdx}8\x18j\xc6\xa2\x9cKe\xbe\xb7\x0f$\xcf\xe95\x810?\xa6\xba\xb4\xcb\x0e\x14\x1e\x083\xb4\x11\x93\x7f\xd6mC\x8d\xff\x8aj\xfcW\xce\x1e)\xff\xb9\x1b\x8e\xe9\xc7\x9f\xbb\x8d\x1c]c\x8b\x93\xca/\xc6\xbb\x9d\xa6\xb3\xfb)\x9c\x9d\xa5\xb3\x9e[z8V{/\xfd\xe0\x0c\"/\xf9\xc1\xe5\x1c\"\xb6\xf0\x83\xf3\xdf\xf7\x0ec\xc6\xdcj7\xa5\xf7\xdd\x89\xebNJ\xac\\\xab\x1b\xdd\xd4_\xd1$%+\xa3)\xcb7\xe7\xd6\x8a\xb0\xe5\xd1\x80\xdeRO0my\xa9/K\xbf\x03\xbf\xa6\x89\x87b\xb85Y\x0b\xf7L\xfd\xb9\x97\xdf\xe0 \x0b\x96\xcf\xc3\xcd\xb9\xb2b\x12j\x9erW1\xf3>\x8c\xe3(v\xba\xafIJs\x9fZ\xca\xcat\xc1\x99|\x91W\xb4\x97NG3\xce\xfc\xf4\xd2\xe9\xe6\x8c{-\x11\xfesk\xd6\x87N:\xdd\x9e\x15f\xb0\xf4\x06X\x07\x0e\xfbo\xf0\xe9\xf4\x95#\xc0\xa0\xf3\xc3\xf3E\x98\x8a\x1ek\x82G\xa9\xe8\xa5\xd3\x9d\x19\x8fO\xd1K\xa7\xbb\xb3>\xa4\xd3\xbd\x99\x89\n\xa3\xca\x15\x03\xdfN\xf7f\x82+\x1d\xf6a\xcb}\x0e\x8b\xc2\xa7r\xeb\xb9\x0b\x0b4\xf0\xd3Q)l\x87u\xb7\xa8\xd3?\x13z\xa5\xd3g3\x04<[\xb3]\xba\x0d?\x80\xb3;\x84\x1f\x10Z\xc3\x19\xf4\xa0\xe7\xa4\xd3\xd1h\xc6\xd0l(\x95\x80\xb8 \xea\x9b\x1bkW\xc4g0\x82M\xc1\x9e\x85\x8bQ\xd5\x1f=\x02o\x90\xd0\xf4\xd4_Q\xc7\x1b,\xc57\x1760\x88\xa6gCa?LR\x12z\xf4x1\xc6\xeeZph\x96M\xc6\x88\xfa\xdb\x93cA\xd7\x8d\x8e\x00\xdf\x8a\x10?\x90\xcc\xf0\x04\xfc\xdf\x8f\xc4t_\xbcP\xac\"L\xe6O\xdf\x0e\x0c\xc5\xcf4\xbe\xab\x0c\x8b\xc3hg\xdb\x1d\xfc\x88\xb6\xc2E\xaf\xe0\x11dd\xd8L>\x97\x1a\xb4(\x18\xba\x07?\xbez}\xf8\xe6\xa7\x9f\xdf\xfe\xe5\x97w\xef\x8f\x8e?\xfc\xd7\xc7\x93\xd3O\xbf\xfe\xf6\xbf\xfe\xfa\xdf\xe4\xc2\x9b\xd3\xc5\xf2\xd2\xff\xe3*X\x85\xd1\xfaoq\x92f\xd77\xb7w\x7f\x1f\x8e6\xb7\xb6wv\xf7\x9e>\xeb=\xd9?\x0b\xcf\xe2\xee\x03%x\xae\xe4\xf9\x1e+\xf6\xc57\xe0\x06J\x1d5^\x8e3\xfa\xe8\x1b\xae\x88B\x1e\x030\xe4\xbeC\xa1\xed\x9e\xa8\xe3 i'\xb9\xfcK\xa5\x19;\x8f\x06\x08\xbb\xdb\x8d7G)\xbc\x80a\xab\xdb\x1f\xd4\x8b\xefj\x1f\x1b)a\x0c\xff\x01OQ\x01]\xc6\xfb\xaf>:\xa3\xb2\x02cz\x16\x9f\x85\xfb3\xa1\xc60\x03=\xb2.K\x86\x91\x80\xb4\x8f\x12\xf3r\x07\x86;\xa1\xdc\xd3{\xf8\x1c\x18\x94\xc9sH{=\x17R\xf8\x0f4\x05\xe3*\x13~\xa5\x13\x88L\x11\xf0\xf2%\x8cv\xe1\x11l\xee\xec\xb8}P\x8b\x9fVK7wv\xe0\x11$\x8c\xec'\x98\x0e\xe4\xc5\x0b\xd8\x85{\xc8rt\x88$:\xa4\xba\xe3U,\xd1\x10dH\\\x82\x03\xfb\x01v\xf1\x9a\xe6\xab\x86\x04c\x18=\xcdu=\xe5\xb6\x86\xda\xb66E)\xbe*|\x0f\x19h\xd4:\xdb\xf9\x9b1\xa6\xdfX\xc4\xd1*\xff\xe2\x04(\x16 \xbd\xc7\xaf\xdf\xd4~\x15C|0)\x87S\xd0\xf67'm\x11:\xe6n.F\x82b@>\xd2Hk2\x0b\xad1`\xe7V\x05;q\xe7g\xd3\x08\x97\x8f-\xfa\xee\x16\xf2|J\xe9\xa6\xaet\xb7R\xb8\xbb\x05\x8f\x00Mr\xd8\x8c\x9c\x88a\xecS\x17z@\xa7\xa9\xf9R\xb5\x8c\xa0[\xfc\x0e\xf1\x1b\x8f\x08\xc6\xb0Y\xa0k\xa9\x9d\xa1\xae\x9d\xedZ\xe1\x8b\x17P\xedqw\x1b\x1b\x1e\x15\xc8\\j\xb9>\xc0\x17/j\x0d\xefn\x97\xdb\xebC\\F\xbc\xfc\xd7Ws\x10f\x89\xb6\xa6\xff+\x87\x9c\xacs\x08F\x85\xe1\x03\x99\xb4\xc8\xe2\xd1`\xf0\xea\xf8\xca3\xdfd\xcf_\x91\xd7\xb8*\xdcx\x1cP\xdb~\xe3\x97\xd2A\xee%\xccv_\xf8\x9c+\x83\xcd\x1ed\"uh0MgE>\xb0\\]\xcb\x01>\xeb\ny\x15\xd5\xb2q\xb3Q\x87\x88\x89\xe3\x87\x10\xdb\xadx\"\xd1$Jj\x16\x8eB\xd6\xcf\x1a\xbb\x96\x9f/\xb2\xd6A\xe6\xa7\xb9\x0fVM\x98!$\xf9\xa1H\x9a\xc1\"\"[\xb4\xca\xdf\x91#Ny[~!\x83S\xd7O\xfc\xb3\\\x8dZ\xec\xfa/\xdc\xc4k\xe2\xc7\xc9\xbf\xd7.\x16\xbe\xbb\x96\x9dJ\xc4\x8c\x0e\xe2\x98\xdc9\x99t\x81\xcco{\xd8\x16\xce\xbel\x0bg\xb8\x85\xf5[7j\xbdu}\xf4\xe7G\xc3!\x85\xe2^\xd1\xbb\x84\xbd]u\xf17\xb5B\xa6\xe9\x8c\xd12\x7f:d\xe7\x0c\xfe\x9d\xcd\xfe\xe9hoXG\x1dW}]\x0d{&R\xd1\x18\xd6\xd1/\xad#\xd1\xae#1\xad#[-\x82\xab\x15\xd5@\xdc\x07_\xc0.\x12\xb0\x8b\x10vF6\xc6\xff7\xd8\xc1\xe5s\xfb\x81\xfb8\xa1\xc6\x0bt\xbdw\xe1\xf7\xdb\xc4\xd6#\xd6\x0f\xc1\x10\x08L9\xc9\xc2\xbe\xb0D\xccIm8Mg\xd6\xfd\xf2mQ\xdeD\xe9\xff\xed<*\xffH\x9ed\xe1\x9c.\xfc\x90\xce\xbfR\xfbb\x81\xc3\xc3\xa1\xea\xd6\xf2\xcd?T\xa6\xbb\x8e\xfc\xb9\x8c/f\xeb]'\xcd\xd94\x7f\xffn\xae\xd1\x7f$Ob\xba\xa4\xb7\xdf\xe5F\xe5\x01\xca3\x1f\x03\xd5`\xbd6\xe7S\xeeW\xa7\xe7\xb3\x19\x11xr\xf6\xc4\x99.\xfd\xd5\xec\x07\xf7\xcfO\xe4\x05\x87\xbez\xac 9\x00\xd2z\xfa\x89\xd4\xbe\x0f\x8dw \xfc\xc2C\x9a\xf2\x86\xd3\x11\xcab\xf2\x16\xe1%\x93K[\x9c\xd8\xac'4\xeb\x9d\xa6\x85!P\\\xb2 *\x9a\xa9\xb5\xf2\xbd\x8f\xe1\x7f\x0e\xc4\xe56Q\x80\xceo\xe1\xaa\xd0-\x19\x13\xf5\xc1\x001\xbc\xd0*.H\xd3~U\x96\xf9J*\x913j\xbc\x83\xb6&1\x0f%(\xd6\x05a\xb0\xea\x01\x1d$Q\x16{\x14z\xac\xc0\x08X:X\x06\xd1\x05 \xc4\xd5_o\x1f\xbaK\x1e\xb9\xaf\xc8D_\x11\xf5\x9fV\xca3\x9b\xd2\xaf\\5i\xd6.\x94_\x08`\x1f\x9eU\xc8 \xec\xc3\xa8r\xad\xb5\x80}\xd8\xda\xac`\x03+\xdb*\x97\xcdY\xd9v\xb9\xec\x92\x95\xed\x94\xcb\xaeY\xd9^\xb9l\xc5\xca\x9e\x96\xcb\x96\xac\xac2\xbe;\xd8\x87\xed\xcaX.XY\xa5\xdfsVV\xe9\xf7\x06\xf6a\xa7\xd2\xc7!\xec\xc3n\xa5\xbd[VV\x99\xdb +\xab\xf4\xf1\x8a\x81\xaf\xe2\x93x\xc5\xca*\xef\x1e\xb0\xb2\xddr\xd91\xe6/\xacT\xfc\x80\x85\x95^N\xb1\xb02\x95\xf7\xb0\xafA\xfa\xe1\x18\xbaggC\xcdQ\xb4\x87O\x88\xe6\xc9S|r\xa1y\xf2\x0c\x9f\xa4\x9a'#\xdeQ\xa8{4\xc2G\xd7\xbaG\x9b\xf8h\xa1{\xb4\x85\x8f\xaa\x0c\x1d\xfbl\xf2\xa1Wu\xd1\xec\xb3\xb5=\x86\xc7gg\xdd\xc7\x9a\xb1\xf3\xbe\xce\xce\xb4\x9d\xf1\xde\x8et\xcfv\xf9\xd4\xceu\x90\xda\xdc\xe2\xad\xbe\xd3?\xe4\xad~\xa8(\x1a\xcaU\xdf\xb2\xf3\xba{\xd7\xedC\xf7\xaf\xec\xbf;\x9a\xe0w\xf1\xe7\xf0\x84\xfdA\xb6\xb7{\xcc\xff?b\xff\xe3W\xfe-\xc2\xaf\xfc\xffc\xac\xbdX`E\xf1\xe7\xcd\x9b\xeeL\x17U\xe3\x8f:\x9d,\xb4\xb6\x95\xabhn\x82\xb2ou-\xeb\xf3\xc8\x19\x9b;;.\xe7\x85n\xbb<\x80\xeff\xb9\xad\xdc\x1a\x19\xab\xef\xee\xecl\xc9\x172\xf1\xc2\xb6\xe6\x05=\xd7\xde\xe1\x8dlo>\xdb~\xb6\xbb\xb7\xf9l\xc7u\xcb\x11q\xbdhNa\x1d\xf9\xa5\x8c\xb9<\x00\xe2\x8a\xdc\xc9L\x0c\xcb\x98\x92\x94\xc6<\x19\xc3\xf0\xf6\x8d\xf8\xe8X\x07\x1c\xe8'1\xd0\xa7\xe5\x95-\xfd\x92\x87\xde\xd9YW\x84u,\xe28\x0e\xf1\xfd\x8d\\Vv\xa1\xa7\x08p\xba\xc8%G\xf5\xc5R\xa2X\xf3x\xe1y\x98n_\x06\xc9\x961\xa7\xdf\x93\xf4r\xb0\"\xb7\x0e\xa6\x0c\x17\xc5\xf7\xf7\xb0\xe9\xcah\xdfW\xfe\xfamxM\x02\x7f\xce\xdbR~\xab\xa1\xb9\x17At\xf3\x8e^\xd3\x00\x99X?9\x8a\x18L\x97\x0e-\x9e\xb8\xd2\x17I)\x93\xbd\xa4w\x81\x08\xc1]:YMLu=%p\x93Ym\xe1\xdb\xff\x8f\xcf\x06\xcds(\x12\xa2pk\x0d\x9e\x845\xae\xdc\x1b\xa4\xf9\xd5\x0c\x8f\x04\xe0?\xe7ARG\x90\x89\x86X?\xac=\x91\xe4!\x18\xa8>\x97}\xc8xg\x19^\\\xab\x8f\xa6\x19\x1b_8%3\xd8\xaf\x06\xc3\x05E\xcd]\xc6gGA1\x868\xd8b\"\x0d%s\xdc\x89\xe2\xf4\x17z\xc7\xb3\xcf\xe4?\xca\x01\xddC\xfa\x9b?\x97\x01\xd5\xf3_\xf7\xf7\xf0T\x86C\x0f\xa3\x8ft\xc1\xdb\x10_\xd5\x16\xc2\xe8U\xb4Z\x93\xf4=\xdb\xce\xbc\x8eR\xa0\xd6\xf4\"\x86\xdd\xe8zu#@\xa9\x14\xa85\xbf \x84\xbcLOd{\xe5\xf0\xb6\x1cu\x1e\xd3`\x85E\xe4\xfaR\xb6F,\x99g\xec\x0d\x92Ra\xaf\xc0K\xb3\x84\xce_\xabOJ\xb1\xfet4\xe2\xa3v3!\xd2\x8b\xdd\x14\xc1~%\x9al\xea\x8at\xc6\xfc~nc\xc4\xf1\x9a\x8d-Q\x83\xa5\x81\x0f/ y\xeeb\xda\x064`\x97\xd9\xfa\x85K\x1f;\xfb\xc1w\xd1\xec\x87\xfb\x8a\x88\xac\x16\xa2\x83\x04\xb3\xbd\x95\x9e\xb0.ydW\x1f\xad\x86\xf8\xf7P\xd5C\x9c Q0\x14x\xdd\xdb\x87\xc8eC\xec\xedW]\xcb\x04\ngV\x10\xbd\xb6\x85\xe3\xd6\x87\xdb\x95\xe4\xf2\x07H]k\xdb\xef\xea$Z\xca\x1c\x08\xb1\x05\xc3>\xfe\xd5\xbe\x8e\x9f\x8c\x0dmm\x96\xa3T\x8d6wQ~\xdf\x1dU\xc3`m>\xdba\xbf\x18\x87RxP0\x96D\xfc\xba\xbf\x87\x9d\xbd\xad\xed\xed\xf2{\xec0\xdeb\xbfx~\x8a\xbc*+\xdf\xadt=\x1am\x8fF#\xebD\xfef\x9c\x08N\xb1\xd2\x0f\xb6\xcc\xbe^\x14__\x15_\xaf\x8a\xaf\xc7\xc5\xd7\xd3\xe2\xebM\xf1\xf5\xd2:\xac7\xc6a=\xf9\xfd,\xfc\x01dT\x13u\xb9\xe57\xb6\x91\xfe^\x0f<\xf2#cs\xcaE\xbf2Y\xa5\\\xf43\xe3m\xcaE\xbf\x01\x06\x99\xae\x0f\xf2/\xf6\xd0\xebl\x1c\xbej\xe7\xd4\xd1\x84B \x0c\xe5\x0b\xdc\xe9<\xeeG\xfd\xe9{N\x07j\xe5\x8cS\xfd$\x12\x92\x96r\x96TV\x12\x83\xf3t\xde9\xfc0\xca\xb0\xec\xbc\xf8z[|\xbd)\xbe^\x14__\x15_\xaf\x8a\xaf\xc7\xc5\xd7\xd3\xe2\xebe\xf1uU|\xbd+\xbe\xae\x8b\xaf\x1f\x8a\xaf\x87\xc5\xd7e\xf1u^|\xbd.\xbe\x9e\x14_\x0f\xc4\xcc\xcc\x89^49\x1f\xd2\xbaJ(7y\x18r\xba\xaaP\xd9^\xcfv\xb3\xd5\xf9$\xc8\xae\xd2\xbf\xafD\x05\xfaM\xaf\x04f+\xf7\x96\x8d\xfdoZc)\x13\x83\xfd\xc5\xc3\xd4\x0e\x12 \x9f\xe7rd\x1d\xf6a\x01hQ\xcdX\x15\xe4Ya\x03\xde\xe3\xe9\xf2\x92[\xf1vA$\xd2\x9c\xbeg'\xc3\xac\x8f\x88\xe9\x1b\xf4\xdc\xb9P\xc1@\xf4\xb5\x00\xd1n$\x1c%\x0e\xbaq\xa8\x7f2\xb7&\xc6\x85\xdcM\x00\x13\x08\xe1%<\x83\"\xed\xd2o0\xc6\xf2\x9fa\x0c\xbf\xc2\x98\x8f\xb2\x13\xf1\x87\x7f\x871\xfch%m\x7fU\xa8Fu\x85\xe8`\x9e\xadJ\xbc\xb7\xe9.\x84\xdf\xfe\xa6\xd5\xdb\xdf\xee\xe3\xc7\x86\x9b\xd9N\x85!\xe3\xa1\xfd\x19H\xde\x16!\x08\x14W\xd3\xc7\x18\xa0\x1dz\xec\x9b\xfeF\xd9\xcf\xb9\x0b;\xe9\x94\xfc\x17'\xed\xf3$\xc6\xbeH\xdeL\x14\x85\xa3\xd1eY\x80\xb0Q~\x92\x1f)G\xe97\x02\x94\xdcYd\xc0H}\xa6\xd9\x90\x87D\xe3\xd9\x82\xccv\xa8 p\xa2\x9ah6\x9c\xe5\x19H\x15T0\xc5n\x04\xeb\xbd\x0d@\x9e$\xa9\xbe{\x8d\x96\xaf\xe8Q\xfd\xf7F?jM\x06{\x90o\xff\xd8\xf8\xb6\xc0\xed\xc2\xe7\xe51z\xbb<~\xdcuM\xf8\x0e\xb2\xf5_\x9b[\xbfg\xad\xff\xc2\xf3\x04r\xbca\xcd\xfe\xe4|dE\xbe)M\"\xb6\xfess\xeb/\x8d\xad\xb7\xc67(\xcb\xee\xb0\x0fO\x9c\xb3\xb0\xe7:\xd3\xdf\xcf\xc2\xd9\x0f\xee\x93\xa5~W\xa9\x1f\x94\xc9\xb3\x9a|\xe1r\xd9DP\x96\x0c&\x90\xa1\x9aA\xb8U@4\x08H\x92\xbeeo\xf0\xfc\xe0\x7f\xce#\xd3\x0d\xfb\x98\x7f;u\x0d{Z\xfd\xa0\xa8~\x16\xcaP0Ct\xffd$^\xfe6c,\x88\xc9k$l\xf5#b\x0c\xc6\xaa\x0b\xb01\xc1\xa7\xfaam'\xc0\xc3\xbc5O\x04\xc4\xc9\x15O7\x1b\xc6\x0cyJ\x18>\xcb\x00o\x80|\xb6\xd3\x13\xe81Y\x0f\x13\xdc38\x88\n0a_\xc7<\x9f\x1d\xf4\xe0\xcfN\xc0\x85I\xbc\xb5\xb0vf\x8ey \x05*\xfa\xc6J\x9f\x19z\x12\xb7 \xdb\x7fk\xc4\xf6\xc7\x98\xac\xa4\xf9~O~rA\xba\xe0\xca\x85\xa4l\xe4\x91\x84\xce\xb4\xc2\x08\xbd\xe4\x02\xda.\xa0\xe7\x0e\x13\xd7v\xb7F\xc8\x04\xd4\x83\x95\xfa(\x15\xf3wv\xb76\x87PD.\xdd\xda\xdeb\xc26*\xa6\xfepF\xc3Mt`Na\x83\xb7\xce\x93\xc9l\x88\xd7z\\\x86c`c\xbc\xdb\x98\xeb\xbc\xde\x0b\xab\xd9\xde>t\x90\x93\xf9\xe4`Zh:\xf5g0\xe6\xa7\xdc\x1fz\xb74\xf5#\xafSmk\xe6\xf2\x8c\xa2\xfa\x86D \x08\xf3\x92\x95t\xba\xfej\x1d%\x89\x7f\x11\x08\xc7\xf71\xf8BU\xc9\x8d@x \xb2n\x13c\xf7\xd9\xb1\xcb\xf3\xbf\x983K\xc1\xbe\xe4\xd7\xa4\x02\x10\xe3\xafin\x01\xe221)\xc5\x95\xd2\xea/B\xb6\xdfx\x8em\xfd{\x9b\x9c\x1e\xe5\xcf\xd8(\xba\xbd..\x97\xdc\x94\x1b\xfc\xb09\x0b\xbb\xd6\x19\xfed\x14\x84MCf\xb8Q\x90\xd4\x8d\x11\xa6\xf7\xb4\xf6\xf1g-\x14\xd1\x1aAq\xbcV\xc9k\xce\x1bTl\x87UE\x96\xe2CY+:\xae2\x90\x85*\x9d\xc0\x0b\x08\xd8\x1f=\x07\x89\xa2\xa3\xe31)oJf\xee\xa0\x88s\xc0P\xc4\x1b\xe4\xf6\x06\\\xcb\xdd\xf1*5\xba\xdc\xbc\x80aR\x9e9\x90\xd3XY/Z\x80\xfaR\xdeN\xder\xa5#F\xfal\x82.\x95\xea]\x98\x80\x87\xdf\xc7\xd0\x9dt\xfb\xe0\x0dr\xbb\x04\xdb\xb1\xc2\xdaXp\x95\xa8\xb8\x1a\x99b33>\x0e5>N\xdfh>\x91\xf1\xbb\x00\xb5K\xee\x13\xa1\x94\xb03sa\xa1\xe2\x06\x0d\x80\xfaA9/\xa9\xf5\x85\x11-\xca\xf4\x99'\xe8\xf7D\x82\xfe\xc7/1k\xbf\xe0\xfdc \x9eG\xd7i\x82Wo\xfc\x04\xe6i\xc2\x10\x02\x8f\x9bN\x9a\xf2\xb4\xa6\x8b\x19\x9f\x99\xf9\xe41OY\x8a\xc3\xb1\xb6\x8a5\xfe\xb4\xc6&K+\xe6w\xec\xfa\xd1\xffU\xd2\xf1\xf1M_\x95\xd9\xd5\xfb\x83|\xc8a\x9fo\xe5\xb0\x0f\x9d\x11F\xc1\xc9\x7f\x0e5\xd9\x82\x13\xc8\xb1\x847Q\xcd\xdb\x9a\x13?U\xa4}\xc1#\xc4\x95\xa5\xdcjVS\xd6|\xd0\x87E\x1f\xed?\xea\xdeR\x0cAQ\xd9\x91?B\x17\x1f\xf9\xa4\xae.C\x85\x9d\xa3h(\xc5\x8dXqI\x92\xcb\x04\xa1\x8b7f\x85o\x06\x02\xeb\xd1#\xb6\x05\x95\x02T\xdb\xdc\xdf\x83P\x84K\xa5\x02\x12\x86\x97 R.\xfb\xa8*u\x85Z\x8aVn_\xa6\xc1\xcc-\xa0\xdf\xfd!\xa6\x8bs\x86\xe3\x15\xf1\xderQ\x8d\xd3\xc2\xb6;\x9a\xc6q\x08\xba\xf2}\x9eR\xdc\x00W\x97\xaf\x1c\xcf*\xab\xde_\x8aU\x96\xc7\xcd\x04\x9cN\xcd\x96I\xa3!\x92\x9f\xb2r\xb9\xaf.\xb0\xc5\xa2\x95\xdf\x1c\xa7\xc4\"\xe0]V\xeeYM\xb9\xf1\x91\xd6H\x1f\x04y\xa5\xe8\xc2%~w\x9aT\x80J\x0e\xd9\xe2$\xd0\xb4\xa3\x145\xb4\xa8\xbe\\\"u\xf9u\xe7*K\xd0\x92\x80\xc0\x05O|\xc3\x13\x98\xdb\x8c\x10\xa1\xa4b\xe5,\xc4e\xe9\xbe\x8d<\xe72\xd8\xc8E\x95=\x135\xc4\x823\xc8\xf8\x0c\xa9\x1d\x0c\x89$\xae\xb5D\x88\x89p\xca\x18\x9c\xcb\xa9?\x9b\xf5\x05\x8d\xe1\x96\x80\x19O\xcb\xce\xffq\xbc\xc7\xdd\xd5b\x07 \xe4\xc7\xbd\xc1\xbe\x15\x1e\x15L\xf0\x90\x89\xe0e\x1dO,\x1d\xd6,\xe77\x9f\x88 N\x13\xc6\xa8\x8a\xaf\xd0\xc5\x8d\xd7\x93\xaf0\x0e\x83S\x81\xd2\xdc\xd4\xa9$|\x1a\xc1\x17\xf4<.z\x1eC\x97\xe1uo_\xed\xdd$\xedHZk\xa2\xee\x89}&g\xe4K\xda\xe2\x14t\xe4QNG\x90\xc9\xe3\x9d3\xd9\xac\xbe[m[\xb5b#\x914\xec\xd3\xa0y\x9fz-\xf7i5\xa7\xb6\x97\xa3o%\xa7vV\xbf\x8a\x9f\xa0\x00\x8eR\x93\xa0`\xfc\x18\xc2\xbb\xddn\x1fq\x02\x95 S\xb6?\xbci\\`3N\xb63\xe2\x87_\x01\xd22N*\x8dq\x04\xcb\x8a%f2\x96q8\xc8x\xa3eF\xbd\x0e\x17\xaf\xb099\x14R\x1e\n\xb2\xe6Y{lR\x8f\xf5\xee?X\xaf \xeb\xbf\x11\xa3\x9a\xd0\xa9\x0b]\x05\xa9\xeac(\xa8\xa5\xf6`.\x1d-e\xf0~\xc9iRx\x00\xdb03\x93\x98i\xc16\xc5l'4\xd9\xe8\xa8\x84\"D[\x1d\x95\xe4)$4B\x12J\xcad\xa6%1\xc1\xb7\xba\x1b\x0c!\xc4W\x9e5\xb8Xy\xfb\xc2g\xca\xc2\x13\xce!\xcd\x9a\x16\xfd\x9fAF\x1a\xd6\x88\xb4X#\x85\"\x84&\x8a\x90\xf3\xbe\xd3xV\xdeA*1\xf091h\xd8\x8c\xae\xd0U\xb6\x82;Q7\xdc\xb4+S-7\xc2\xbe \xf0\xad6\x9cY\x94\xcc\xb7!\xd7(\x89@\x03I\x93\xf4X2\xd5k\xf4m\x84\xaa*-\x0b\xb98F.\x02\x8a\x9eT\x10-\x801/|,i\x048W$Kz!K/'\x95\xf9\x87G\x8f\xf8\xc5\xa4DbT\xe0\xd6\xc1]+i\xe2K\xca\xab\xc1\xc5N*\xc4\xce\xeeKu=\xfed\xee\xa8.\xd2\xe9D\xb5\xff2+\x03sm\x94.\xd4\x8c\xce\x1d\x87\xc7\xbb\x94-\xa3\xfb\x97\x89~*\xb4\xb3\xbe\xa2\xb9\xe5c'O \xa6\xd1\x80\x98}\xec7\x94\xc0\x14\xa1zO[Xy\x15ia|\xdc\x9c1\xf7ui\xbc\x85\x0fy\xbd\xd4\xed\xf3ce\xe0'<\xb4C\xaa\x89\xce.?Uf851\xc3\xd4I\xa7\xfeL@\xcd<\x12{G\xd5X\x11\x15K\xb8\xc8\xd6y\xc4y\xeb\xb0\xee\xc4\xca\xd0$\xe2dZ\xb9R\xf5\x0d\x97\xa8\x90\xaar-\x82,\x9a\xfa\xd3p6\xabL+\xd5\x98\x03\xe6\xe12b\xbb\xd2\x8fR\xab\"\x9b\xb5s\xc43\x02\xb0S\xe8\x1fUOB\xa9\x97V\xcc2q3\x84\xc8\x03\x85}6GZ\x9c\xb0\x13\x08%\x8b\x85\xda\xcbR\x0e\xf2b\xe7\xe5n\x9fr\xfbR\xaadh\x1f$dA_W\xac\x15,\x96{|\x8a\xf1\x80\xde\xa64\x9c;\xf5}\xc4m4\xc7@\xca\xab\x85'~et_\xe4\xf6\xa3z\xb1Z\x07,\x0d\xe9\xd5\xac\x07x\xd9\xd6q(\xecC\x8f\x9aC\xcaX\xa3\x99\xf3h\xe1\x97i\xba\xd6\x04\n\xe7\x0fo\x12C\x0cq\xd1\xdfS\xc1\xec\xd57T\xd1\xb8\xae \xd9zC\xf3\xdb\xdb[\xf6\xf6\x17\xda\xb1+-l\x8e\xec\x0d,\xa3\xf5%\x8d\xedm\xec5Lr\xe1\x07\xa6P\xebzs\x04\xeda\":\xf9\x16\x98%\x1d\xca\x1a\x83\xc4\xd47~d\xbc\xde\x99S/\x9a\xd3O\x1f\xdf\xbe\x8aV\xeb(\xa4a\xea(Q:\xcfzh\xb2\xc0\x18+\xcd\xceM\x07\xdc\x7f\xc2_\xdc5!{NT\xaa\xf1\x05$\xed\xd1\x9e\x8c\xdcQ\xdc\x0f\xa1\xcb;R\x9d\xcd\xf95\x0dZOO\xd0#\xde\x85X(6\xd1H\xf2\xd1#\x10G\x0f\x0dkS\x8cP\xb2\xdbG\xb6\xa0\xfe\x94'\xf03\xd0\xbe\\\xf4I\xd1O\xf2\x8f\xc8\x0f\x9d\xee\xa3\xae[!o}H\xb9go 2U\xb0\x94.\x92\xd1@b\xfa\xfb\xfe\xe4\xd1\xac\xe7\xeeO\x9c\xe9\xef\x8f\xb8\x95\x04\xae\xfa?>?G(\x86V3\x01i0\x159\xe8\xb4i6\x8fb\x156\xabg\x0b \x9b\xe2\x87\xfc\xba\xd7\x89\xa7\xfe\x8c\xb1\xc9-x\xa6\xf8a\x08^\xf8FnU}\x1a\xb9o\xe4\xde\xee\xb6\xd67rk\xb8\xa9\xf1\x8d\xec\x1e\xde\xae\xa9\x97\xd2\xb9\xaag+W\xcb\x14\xdf\x97\xf2\x93$\x7f\xe2\x87-\xc8\xb8\xe1\xcaL\xdc\x94\xf5a\xdd\x87y\x1f.\xfb\xe8\xc9\xa8\x89\x01\xba2X\xe2.\x0d\xe5w\xa8\xf9-\xafSE\xb5Yl\x8a\x92?\xf4\xe9\xdd\x9ar\x9fh\xa2\xe6R\x06\x950\\\xe8\xcf\x10\xb9+\x03=\x02\xe1\xddK\x1du\x04.\x04\xec)\xec\x8bh=\x1c\x10)W\x1a\xd3\x01Y\xaf\x83;'\xeeW#>}6\x0c\xf0\xdc\xech\x8f\x16\x12\xb0\x01\xe6\xfc\xedJ\xbc\xa0Kn\xb7\xf2R\x90\xa1P\xdei\xa0\xe8\xc0Z\xb9f\xcf\x16\xad\xc6t\xa35\x97dC\xa2\xb8\xb3t\xbbj\x01\xce\xb9\x9ac\xe3\x90\xed\xe0Z\xb59\xec\x83\x08\x05\x1fe\xa9s\xd3oa\x94\"A\x91\xc2\x068\x08\x0f{\x00\x88%L a\xdc\xdaB\xbep\xed\xd6\xf3s\x00ga\xabn\xdf\x06\x88\x1cZ\x1d\xad\xe7\n2\xa0Av\x00\x13\xb8`\xaf\x8c\xf9\x9d\x8e\x8a-5 M\xdf\xe3m\xd3\x1a\xe81\x97\x01\xea\\\x0bz\xb6Bl,$^f+\x1a\xa6 \x0f\xe4\x9f^\xfaI\x1fo+\xa8Ei\xc2^V\x90\xad\x10\xbf\x9b\x97\x0f\x14t\xe5\xbd\xd4\x91\x80 $\xab\x02fkmC\x9f\x1d\xd3\xc2\xb3\xd1-]u5\xea\xcd_8\x97m\xe4\xf0\xfa\xc6BSyG\xd7\xa8\xdb\xaf\x8cT{r`\xaa\x0bF\x85\xee\xefQFrB\xae\xfbA:\xd9a\xe7-\x99\xfb\xe1\x92g\xdap\x18\x95\xec\xae\xc8\xedo\xc4O\xbbty\xbb\xb5PS\xe5~p\xa2{#\x97u\xff@ *\xdd\xeb9\xe1-]B\x0f\xab\xac\x05\x82\xe43\xa1\xaf\x0f\x9d\xd8\xa9\xc4\xcd\xccs\x08\x15\x0c\":`\x8c\xc1#\xe1\xe3\x94\xcd\x0dH\x02\xb9|\xd9\xa9\xd8O~\xd6\xef\xd0\x1a\x80\xc6\xa0]\x14\x14-\xba\xe7\xe7\xd8\xfe\xf99R\xe4\x7f|\x86I\x15LZ-\xa89\xe8\x16\x8fC\xe7l?s\x1di\x15\x85\xe2`\x9f\x81vw\xe8\x0e\x16NUp\xee\x832\x0c\\\xbc>l\xba.\xeb\x7f*\xc3\xd9u\x1c\xaa\xda\x8c\xa1\x9aM\xe78\xd5\x14y*\xd5G\xcd6\x9e\xb0*0\x8cl\x87\xa8\xebK%\\\x8aFx\xf9\x9c\xd0\x1cM\xd0@\xf6\xb8\xae\x06\xad\x9a\xc1\xfe\xe33\xbf|\x19\x8b\x83\xa6\x82z\xde%\xf5\xae\xc6\x8aEv\xebM\xab\x92\xf5\x02\xe5\x8b\x8d\xdb\x82\xe8\x1b\x8f\x1d\x0fC6\xf0:\x0f\x1b\xd9\x97\xed}\xde\xdf\x18\xc7\xff\xcc}\xe0~oV\x1a2p\xed|E[\nx\xab2\xb4\x90\xad\xf7\xb4I\x88\x9d\xad\xbd-m\xdc\xa1\xa7\xba\xb0C\xa1\xb3]\xad\xcd\x07\xfft\xbbZ=\x10\xe5\xd5\x83\xc0\x13\xbdVG\xb9\xe0\xf5w\x86\xa5\xd3\xf0\x99\xf2+\x1a\xf8![\x1a\xa7\x82U\xeb\x1a\x19Z\xf8\xe1\xfc\xf5\xf1\xfb\xa3hN\xc7Ui6\xa6\xe1\x9c\xc6c\xf0\x07\xfc[e\x92\xe1*\xca\xc24\xd7\n\x1d\xa4\xbc\x11\x7f\xa0\x7fR~\xfb\x9a\xc6\x89\x1f\x85cH\xaa\xad&x\xc3v~\xc1\xe8\x05\x9d\x7fZ\xcfIJ\x931d\x83r\x89\xe15>\xd2\x93\xec\"\x8d)}\x1b\xa6\xd1\xab(L\x89\x1f\xb2y\x14\xc2\xabB\xa1\xf5\x91\x1a\xcf\xcf?\x1e\x1e\xbc:=\x7f}\xf8\xeb\xe9\xf1\xf1\xbb\x93\xf3\x9f\xde\x1d\xffx\xf0\xee\xfc\xe7\xe3\xe3_\xce\xd1CWk9e\x7fM,\n{\xbbU\xc5\x8ar>\x87\xe7iL\xa9.i\xf8\x92\xa6\xaf\x82(\xa1I\xfaV\x10\xe47q\xb4\xe2\xab\x12\x0f\xccO5\xba\x16\x8aK\xc6*\xc8\xcaM1\xc3@\xb9b\x18\x88e\xa0\xf3|\xcc\xfc\x02\x921\xfbR/\n=?`\xcb_\\h|\xaepH\xeboAL\xf6\xf6\xaa\xd1\xca$5\xa9\xeewNM\xf6\x9e\xea4u\xac\xbc\x1a\xdd,\x13\xe5U\xaa$\x88\xe1\xd3j\xbf\x81(\xaf\xf6\xcb\xe9\xc9\xde3==\xa9\x11\xc35'3\xa3*Y\x9a\xf3\xf2\xcd\xea\xe1w)\xcaG\x95\xf2kQ^\x9d\xeeJ\x94W\xc9\xe4R\x94W\xc1p'\xca\xab`\xb8\xe0\xe5[\xd5\xf6\xcfEy\xb5\xfd\x1bQ^\x9d\xef!*\x18\xdb\xf0n|{6\xc4\xce>D>\xeeP\xb8p/\x07\x87\xd74L\x0fW~\x9a\xd2Xl\xf0\x8f\x94x)\x96\xbf\xf3\x93\x94\x864vVn^\xf7C\x90-\xfd\xf0\xe7\xecB\xd4V\n\x8f\xe39\x8d\x1dR\xad\xfb)\xf5\x83D\xd4.Q\x0bga\xab\xcaj\x9c\xc6\x84\x91d\x12\xa0\x80\xde<\x82\xe4\xc7\xbb#\xb2\xa2\x9a\xfbC\xf69\xf1W\xeb\x80*\xd5\xc7pS\xa72\xecs\x18\xa64~G\xc9u\xb9v\xa6\xaf\xfd\xea\x92\x84\xcbrMCv\xb3\x13\x1a\x94\x07<\x86s}\xcd\x1f\xe9\"\x8a\xe9\xdbp\x9d\x95\xab\xd7]\xb4>#d~\x8e\x92\x02\xb8\x020?\xb1\xb5\xf3\xbd\xbc\xf8U@\x92\xc4\xf1\x8c\xf5O\xe9mZ\xa9|\x89\x95_\x1f\xbf\x97\xd7T\xa2\xaaR\xf2*\n\x17\xfe\x1235\xb4\xab\x99\xb4\xaey\xc1\x17}\xb5f%\xe5\xb1\x96\x0b\xdf\x10/\x8d\xe2\xbb\x16\xb1>\xa5\xc2\x81\xde\xc0\xba\x1a\x98\xb2\x80\xa68\xcd\xf3\x0d!\xc8\xf5iL\xc2\x84\xf0\x1e\xee4\x15\x7fd\xbc\x80\x1f.O\xd2\x98\xa4ty\xe7\\c\xa5\xda\xd8\xc3k?\x8e\xc2\x15\x0dS'0K\xf3\xf8\xed\x8b\xc8\xbf\x99F\x08\x00\xfb\x8cw\xa9\x03\xa8Kb\x9flxY\x1c\xd30\xed\x8eu\xf7 \xbc\xca\x9c\xa6\xc4\x0f\x12k\x15?a\xac\xcf\xdcV\xe7\xd2\x9f\xcfih\xab!\xfc\x02mU\xae\xe8]r\x19\xc5\xa9\x97\xa5\xd6\x01\x05\xe4\x82\x06\xb6\nq\x14\xd09M\xbc\xd8_#\x07e\xa9J\xb24\xf2\"FMRj\xab\x87\x92\x97\x1d\x06\xf4vM\xc2y\x03\x9cH\xb2\x8e\xd6\xd9\xda:=zm\x9f\xde*\x9a\x13{\x05\x19\xb5\xbc\xb1R\x82d\x8c-\xaf\xadj\x14\xfb4LI\x13,\xf1\xce\xfa2\n\xe64\xb6V\x8bi\x92\xd8\xc1\x14S2\x8f\xc2\xe0\xce^\xe7o\x99\x1f\xdb\xdb\xe1\xd3k\xa8\x13\xc5\xd6\x1drM\x82\x8c\xae\xc8ms\x1d\xdf\n\x1d\xac\x13F7\x8duRzk\x1d\x10I\xa3\x95\xef\xd9j\\d\x89\x15t\x81\x7fm]\xef\x98\x06\xf4\x9a4\x10\x0eF\x7f\x16\x0b&\x9f[j-crqa\x87?\xa3\xc2\xd7\xb8]i8o\xe8\xd4\x8b\x02\x8f\xf1\xe1\x0du\xd0P\xae\xa1N\xb2&\xd6\xe5\xf2\xa20\x8d\xa3\x06\xca\x884\xe6\x82\xce/\xac\xe0F\xcf\xe8\x15M\x12\xb2\xb4\x82}\x11D7id]8F\xf9\x82\xa6\xfe\xa2\x9b\xd0:\xecu\x94\xf8aB\xadP\x8c\xa3\x9bFH\xc7\xd1M#\xa4\xe3\xe8\xa6 \xd2 M\x13\xff\xef\x08\x99R\x8d\x8a\x00\xf6\xfa\xf8\xfdA\x9a\xc6\xfeE\x96R\xc6\x1a\xb2s\xaf^E\xf2\x1dy\x8d\xbc\xc2W\x9c\xc2\x8aFgX\x95V\xc4\xd5\x81^\xa3\xb3\xb7W\xad.e\xb0\xaap#e\xb0\xaap\x83q\x08\x9f\xf5a\xb4\xd5\x87\xcd\xbd>lmV,[\x990\xb6\xb9\xa9 \x14\x1d\x0d<\x12~J\xe8\xeb\xe3\xf7\xa8O@\xde%\xf1\xd9\xcc\x91\x0fE\xbd/O\x11Q~\x19\xc5\xb5R\xda\xfcjS\xf3\xc8\xc3+\xda\xf7\xd1\x9cb3\xb2\x00\xa4\xc3\xa0,\x18\xa8U\xab\xca\"~\xd3Zm\x9c\xf1\xae\xd5\x01\xb2\x07\x1d\xee\xb2\xe7\xd4\x0dk1\xf5\xbbHv\xc1V\x9f\xb8F\x05\xcaz \x14C\xac\x06\x9a\x07\xbd\x0dS'/u\xdc>\x8c\x86.\x8f\xe7\xa7\x11?+cu:\x1e\xc8HT\x0b\xc0\xec\xbe\xec\x0b\x86\xe4\xabL\xf6Z\x13\xa6{\x95G-\xc5t\xbc\xaf\x84W\x03\xe35K\xf5\x96\xdax\xd2\x17\x85\\\xa1\xe3\x00\xd9g}I\x12:\xffH\x97~\xc2\xf8X?\n\xe5\xb6\xd0Vg\x9f\x8b\xec\x82\xf1zc\xe8F\xa1\"\xb9X\xbc\x10<\xb2N\xb3\xb8\xfe\xca+^^\xb7\xe5\x87\xfa\xde\x96\x9f9]\xd3pNC\x0f\xd9\xdai7\x8d\xd6*\xda\x86\xf3n\x1fX\xe1/\xf4\xee\x03\xe3\"\xc4O\x862b\x98\xf8\xfb\x03IR\xda\xd5$\xe5\xab\xf7\xea\x95\x9a\xffN\x80\xac\xce\xa1\x1d,\xcbo}#p\xfe\x18d\xb1\x80\x92 \xb2\xaf\xa3\x9bP\x0f\xe7_\xe8\xdd\xa7\xb5\xf8\xfe>\xca\x12\x8aU\x1f\n\xe7\x93\x94\xc4\xdf\x0be_U\xba\xf9\x02X\xe3{\xdf\x15\xdabd\xff,xs\xc9\xf6\xfb\x03\x9c\xf7\xf3\x05\x10\xe7/~W\x90\xcb\xb1}C\x98\x97J*\xe3\xbb\x13\xaa\xbe\xbc07\x9b\xba\xd0^\xa5I{r\xad\xb2\x83[C\xe7C\xb3ZD\xd7r\xf7\xa2G\xc5\xab\xf2\xe1\xabk\x18gim:o {\xd0D\xd3S\x9b\xe3\x105\x19\xa8\x97@k\xa9\x84ki\xb7\x00\xd7\xc4\xac\xb3F0j\xb2\x1c\xd7ymhL \xafe\xde\xb7\x01W\xa0\x94G!:1\x05A\xe9\xceIJ\x90\xbbIa\x02\xe9\x80\xfd\xac\xdeI\x14#b]\xdd\xe4,Y}t\x87\x92\x8f5\x84\xa6\xcd\xfa\xba\xd8\x0e\x1e\x86l\xb3\x99FC\x13^\x82\xbaT5\xf2\xd6\x18\xf3k9\xa8\x9e z\xe39]\x17\xec\xbczX\x07\x87\xe1\xbc}\xf3\x82Z<\xac\x07\xfeR\x13\x9d\xe0\xd7O7\xdc\x96\x10\x85\x8fG\"J|u\xb8h=\xd7df\"1M\xd9\xc4\"\x92\xd3\xa3G\xca\x8e-\x07\xba\x16\x031\xf7\x8e\xab\xe1\xf6AI\x18^\x16\x08\x00\xf9a\xf6.\xc6q\x17\xe1{kMp\x1c\xab>:\x0c\xd1j\x8f\xe7\xa9c\xf2\xcd\xcd`I\xd3\xd7$%\x8e\xcb\x81\xb3\x0f>\xdawEQ@\xe7NTu\x05`X\xbd\xc0,\xc4E\xa5\xac\xd8\x03udO\\X\xf0]V\x8bsbp\x05\x95\x97\xd9\xe7Z\x7f\xfb\xdc\x92GDH\x91m\xb7qn\x8c\x07\xc4\xf3\xb2U\x16\x90\x94\x9e\xdeD\x1f\xd8\xf1\xfb\xdaO\xd6x\xf9\x9c\xe0E\xca\xc2J\x8dn\x1b\xf6;\xa9\xcf\xbf\x83\xd1\xa2\xe6U\x13\x9fo\xb6\xe3[m\xc7s\xa7\x1a\xb0F~\xda\x1c\x1c\xf2\x93\x1fF7\x97\xbew\x89\x8bp\x0d\x13\xbe\"cp\xee\xc4u\xd8\xaa\xa9\xabBd0\xf7\x95\x1bv\xe3\xfa\xea\x1b\x04\xe5&\x02Q\x1dc_\xdf\x15C\n\xf5\xef5\x86\xd9S\xf6]3M\xc1\xad\xdc\x82\\0d\xb81\xad,:5\xd4\x17\xb6\x88\x0c\xd7\xf1\xd8\xdc\x04\x07cj\x05\x14\xc0)\x1b\xbb\x11z\xfe \xa6\x01% un\xdc~~\xe0\xf5\x0d\x01,\xf5\xae\xce\xeda\x06\x0fBu.O\xb6Z\xabo\x8e\xe1\x8f\x1eA\xa7\x85iD\xe5m\x87\x0e\xbc4\x0e~\xa1w\xb8\x1ayJ~\xd8\xd0\xd1\xa2\xcf\xd1s\x80\xf2\x83\xf7\xba\xf9\xbe\xb9t<]XD\xa8\xb1\xa8\xf8*\x1b \xba1\x8b\xdcQ\x1a\xda\xd6HX\x01J\x810\xc1\xaa\xac\x96\xbc\x0d\x1d\x9c\xdf\xc4d\xbd\xa6\xf1I*\xb2~\xa4\xe5\"\xf3\xd5\x01gT0\xd0\x980\xd7\x0d8\xaf\xd3\x0d\xb3\xd5\x05\x8d\xf3\x95c\x0b`\x19\x0b(\xacw\x97\xe7\x8c\xc3\x03\xcc\xdc3`\xf4\xb5%Ms\x93TG\x9cyn\x112\x17\x1d\xefk\x15\xb4+\"?\xfa{\x8dz)\x9eB\x81\xd1\xe1D\xafp}\x8f\xa5_)*\xef=\xd595\xab)\xde#q\xa4\x8a$\xe2V\xb4i\x197\xd5@\xe0\xf8\xe5\\L\x17\xf5\x85\x928\x18\xd60\xd7\xe2\xce\xaf\xcfV\x00\x13\xa0\x0e\x0f8\x92]\x04\xbe\x97SMd\x02\xe2\x01\x99\x17n\xa8\x07\xc9G\xba8\x8d0m_\xbf\x1ab\x0bp\xe1B.\xc8\x0d\xce\xa3\x9b\x90Vc\x96\x16K\xc8\xc4\xb7\xe42\xca\x02!\x06\xb5\x81\xa6\x84I]r\x03\xa9\xae\xac]a\xe4\xd0\xa7\x06\xe8c\xb9\xc8\x86\x16\xd3\x85LL)\x86_\xbf\x0f\x89\x8c\x03\xf0\xb5\x03P.W\xecX\x90\x13\xcb\x94\x8f\xc3\xc7\xafb\x1c}\x08\xf1m\x0c#\x9eG+,\xde\x8e\x90\xc0\xf1\xbdY\x062g\x89\xdb\x80\xf7\xff5\xc8\x8a<;\xe2fLW\xd15-\xa3';\xf9\xbf \x82~\x075\\)\xe2\x80Q\x03iP\x8a\xfc\xe6\xc1^\x0b\x13G\xedR\xa7\x91Xh\xf3\xfb\x1e\xe6\\\x9a@d\x89\xfc\xe2\xac\x8d\xc1V\xd8\xe73_\x81 W8z\xe6!\x8b\xf0\xa0\xfb\xfb\xe0\xb5\xc4\x94\xb9h\x16D\x92\xe4\x04\xc6|\xb05\xf5G`\xb8\x96\x07\x19uD\xb4\xe2Y[\xf1,\xad\\WlZ\xc9\xa0 P\x88\xd0\xb8S\x0ds\xc9ov\xf0\x9d\x80S'V\xcc\x17\x0c\xd3`]WVq_\x17\x95\x17\x04dV\xfa\xd1 \x81\xc60\xca\x96\xd1\x08\xd0\xaf\xca\x83\xa2\x9c\xb6\xb3\xe2\xbc\x7f\xf6\xab:\xa8y\xd9\xce\xa98D\x95{\xa9\xeb>\xac\xf8&w\xfb0e\xbf\x1a \xa9\xfe\x8c\xcf\xb0\xf4+\x0f\xd2Z\xf4\x1bv\x8e\xca\x00+~\x14\x0e\xde\x7f:9=\xfftrx\xfe\xe1\xe3\xf1\x87\xc3\x8f\xa7\x7f\xad\x9f\xafj\xf5\x9f\x0fN\xce\x7f<>~wxpt\xfe\xeb\xc1\xbbO\x87\xf5c\xb7Z\xfd\xe8\xd3\xfb\xc3\x8fo_\xe9\xaag\x9a\xea\x1f\x8eO\xde\x9e\xbe\xfd\xf5\xd0\xf6^\xa2y\xef\xf8\xd7\xc3\x8f\xef\x8e\x0f^\x1f\xbe\xb6\x0d0\xd0\x9eR~\xf2*K\xd2h\x95k;\xc6\xf0\x91.\x0fo\xd7J\x94\xfc\x94&\xe9\xe0\xc2\x0f\xe7NHo\xc4c\xa7\xfb\xbb3')\xb9'\xb1O\xdc\x0d\xcc\x01\x14\x0f\x0eNO?\xbe\xfd\xf1\xd3\xe9\xe1\xf9\xd1\xc1\xfb\xc3\xf3W?\x1f|\xc4\xbc@?\xfc\xb9\xab\xcb\x1ao\x0f\x85\xc1><\xb3\x8e\xd6\x07\xb9x\xfc\xea\x92\xc4\x185\xd1R+I~\xa1w\x96\x1a)\xc6\x1c3=\x0e\x82\xe8\xe6M\x16\x04'^L\xa99\xb6\x0c\xd6\xc3\x08%xjx\x96\x0e\x03\xcbp\x13\xcb\xa3\xbb\xd03w\x9f\xa5\xd1+\x11\x12\xc3\xdcD\x96F\x1f\x02rglE\\\xec\x9b\x9f\xd3 \xf8@\xe6s?\\\x1a;auN\xd6\xc4\xb3\xd6\xb9$\xf1\x89e\xd5\xbcK\x12\x04\x14-\x1c\x8c50\xb4\xc7\x18\"\xb87\x8e\xd6\xb7\xc0\xc2\x0bH\x92\xbc}m\x7f\xceYLS\x8d(H\x8cA\x89\xbc\x88\x01\xc1\x8cV^\x14\xa64\xb4@\x80??\x9c\xfb\x18\xe8\xc3^\xef6}O\xc3\xccZ'\xc6\xc1\x9a\x00%*\xbc\xf3\x13\xdb\x88\xa2xnFO/\x8e\x92\xe48\xf61L\x92\xa1\x0e\xb7\x0c2?\xa4\xa7\xbe\x05\xdey|\\\xc3,\xe6t\x81\x81 \x0dO\xfd\xd8\xdc\xb2\x08\x96c~9\xba \x83\x88\xcck\x91 \xf3\n1Y.\xad\x0bEC\x8f \x04\xc6\xe7\x8b(^Y\x1f\x1e\xd8\xe9\x14\xabr\xd8\xa2\x8f\xf74\xbd\x8c\xe6\xd6*G\xd1\xaf$\xf0\xb9\xff\xa9\x01 \xac\x1a\xe7\x0f\xcc-\xc5dE\x7f\x8cb\x8c\x16i\xa8sI\xc9\x9c\xc6f\xa4\xba\xa4\xfe\xf2\xd2\xdc\x05\x0f`d\x1c\xe4\xa5\xbf\xbc4\xbf\x1b\xd3\x85\xf5\xe1;b!`\x97\xe9*x\x13Y&\x96\xa6\xeb\xc3\xbfe\xfe\xb5\xb1\x86\xefY\x16\xd37/\x10\xden\xbd\xc7\xf0\x8d\xc6\x1a)]\xc6~j>\x81|3\xc4\xaf\xe8\xdd\x07\x12\x93\x95\xb5\x86\x15\xc9\xae\xfc\xd0d\xeet83ov*nd\xd9$e\xba]D(4\x7f2\xec\"~]\x19\x95\xea3\x08a\x08|\xda\xd7\xed\xbe\xca>3$WK\xbe\x052\xd5\xd0C\xe4\x87xVE2\x11\x9b\xf4\x99>?\x84.\xd9L\xac\xac\xe8\xa40\x9d\xe7\x89x\x04\x85r\xbas\xff\xfa\xffa\xefM\xdb\xdb\xc6\x91E\xe1\xef\xf3+`\xde9ij,)\x96\x9d\xc5Q\xe2\xf6u;\xce\xe9\xdc\xc9\xf6\xc6N/\xa3\xf6\xf8\xc0$$\xf1\x84\"8\\d\xbb;\xf9\xef\xef\x83\x02@\x82d\x81\xa4lgf\xeey.?\xd8\"P\x00\xb1\x16\xaa\n\xb58\xfa\xbe\xb7\xb9\xf2\x1e\xfe\xfd\xb7\xf4//\xdc\xdf\xae\xb6\x07\x0f\xf1Q\xe8\xa5\xdbX\xbb\xca\xcf\xc5\x9a\xa2\xee\xd6\x04\xd1DL:\xfd[\x91\x8ab\xf8\x8af\xde\xd2M\xdb/>\x01Ug\xb3\xc9yU\x1f\xbc9\xf1\xa8yVH\x94np\xe0\xd6u'\xe1\x82\x1bkd4\x0e\xa2\x88%b\xbb\x08\x9c<\x9b\x9c\x93m\xc2\xc86 g\xbb\xc8\n/B\x1a{\x00\xbds\xfe\x9cx\xa3\xd1\xf3\x81\xd4\x0c\x1d\x874\xcd`\xe1V\x17\xa6\\\xda\xd5O\xb1\xe6\x90\xce\xb5B\x98\x9a\xf4\xf4\x87\x9b3\xba\x80H\x0d\x8e\xf4\xb7^?a\xe7:`\xb3\x8c\x16\xadgkH\xb8;\x1f\x8c\xe7<9\xa1\xde\xd2\xcd\xeaF\x80E/br \x83~\x81\xfa\x89\x1b\x8d=\xd1x\xb1m\xd3\xc1s\xb3?\xa2\x87Z\xdfQn\xe42\x0f7\x99,\xf1\xfc\xd7\xfb\xd8\x7f\xfb\x96\xcdm_\x82\xaa\x1d\xedkT+7nI\xcd\x1cTC\xb7\xaa\xd0x`\x86#~\xf0\x808r\x06\xc05\x03T\xb2\xe5:)\xcb^G\x19K\xd64\x94\xe9\x83\x8a\xde\xbc\xa9\x13)p\xb3 \xcd\xe1\xf3r*\x82\x14\xfe\x8b\x06\x8bO{4\x0c\x19S\xf5\x83\xa9G\xc6V\xaa\xda\xea2\x13%\x0eI\xa3\x12 \xa2\xc0\xf6\xbf\xdb\x98\xa3\xdc\xaf6\x7f b'\xe1\x0d\xd5c\xb7U\xd5n\xb6\x85r\x86\xc3\x08\x16+20\x99\x91\xad\x0c.\xc1x\x81\x8c\xc8\xa4\x18 ]\x1c\x9d\x9c\xb1\x1c7\xa3\x9ez(\xf9AK\xbc=\xb5.d?\xcb[v\x18F\x15\x87\x1d\xc1Jf\x9c\xbc&UX\xec\xbaH\xef:7\x13[U\xfa\x9e\xe0\xe4\x05\xc9\x9e\x13\xbe\xbd= \xd1\x8c\x9f\x8bI\x98q\x04\x05i\xf5\x9c\xe6\xdcO\xc9\x8c\x9d\xdf\xef\xb6\xb3\x1c{XP\xa4\xbb\x1ec\xa0\x13\x89h\xed\xcd&C\xf2\xdd\x0b\xc9\x1f\x16\x02\xec\x03'Kr\xe6|\xff\xdd\x908/\x1e\xca\xcc\xef\x9d\xf3\xe6\xc1(J;/\x80\xb1\xfc\xde\x01`\xf5\x1b\xf1\xf4=\xdb+a_d\x97\xdc\xbf\xf9\xfeE\x96\xe8b\xc9\xf7/\x1e\xaaDK\x1d^\xd9\xda\xf5\x82\\\xaf\xc2(=\x00\x8eo\xfa\xf0\xe1\xd5\xd5\xd5\xf8jo\xcc\x93\xc5\xc3\xdd\x9d\x9d\x9d\x87\xe9zQ\xb4~\xbdhT5G\xa9x\xe7/\xceT\xf6\xe8\xf0\x85\x1f\xacU\xcb\xe0\xd7y\xf38\xa4 \xa3\n\xfc\xc5\x8a\xc6\n\x1a~!\xd0\x1e\x0f\xa7d\xb6\xdb\x1c\x01\xddi\x8f\x87\x8b\x84\xe7\xba\x9e\xe2\xd56\x1a\xe2 \xd9\x82E\xben\xc4<`\xa1\x9f\xb2L\xd5P\xbe\"%c\x9a\xd0\x95.(1\x8b*\xa6_\x90BY\x82vAM`\xeb\xdc\x11y\xb7\xb0\x90\"wDn\xcacy\xad\x8bdyT\xe5!l\x92\x1e&4\x13\x9a\x84\xe7\xcc9\xcf\xf0\x9c%\xb3\xdcog~#\x08\xa0,0\xad\xbb\xa7,w\xfa\xcc\xf1\x82\xc4\x0b\x81\xc5\xf5\xc2 \xfe@\xb3\xa5\xf8\xed\xb39\xb8n`a\x18\xc4)d/\xc4\x9f`E\xa5\xaf\x07\x08\x80\xa2\xfe\xd3\xe4?\x13\xea\x07,\x02-\xdd\x15M\xc1\x03D\xac\xaaR72\xf0\x93\x877\x0b^\xfc\xd4u\x88\xc244\xebHddJ'\xcd\xb8\xf4\x0d\xc1\xae\xa5\x060\x84;8/(\x1b\xfba6\x07\x0f>\xc4\x1b\x12*\x7f\x99\xc1xk^N:i\x88@\x9c6\\\x9e\"\xf3\xda)\xa2N?p!\xe4\xfcEpV\xd4\x02\x11T\xe8?\xe7/\xa5m\xb5\xf3\"\x0c\xa2\xcf\xe4\xe1\xf7\x0e\x99\x12\xe7\x85\xa3HP\xe7\xfb\x17\x0f\xcb\xdfN\xd9\x95`<\x0f\x12M}\xa9\xe4C\xd9e\xd4\xd3\xed]\x0f\x01T\xc8`Qwoe~q\xe1BO\xeeW\x1f\x9d\xb8\x82(\xe6\x83\x99\x80\xab\n%\xfb\xd0\x0e/\xa2>\xac$Nl\xde\xc1<\xa2S,\xd1p@\xa3\x19\xc9z$=-\x97\xa8\xcfI\x8eK7R5\x85x\x9c\xc1\x86\x02\xa6\n[\xfa\xa4\xce\xbe\xaa0\x83\x0dW>\xb1\xaa\xbe\x9e.\xe3\x0cN\x1e\xd7;+\xe3\x0c\xee=\xae\xc3\xaf\xf1\x15\xa5\xc2\x0c\xee\xd4;\xab\xc2\x0c\xee\xd4 \x91\x1b\xd5\xfc\xfa`\xaa0\x83\x0d\xbb\x8d\x0b)\xb5\xd9{6\x18B\xb8\xc4\x9d\xba\n\xa4\x8a7\xd8\x18\xbe\x13U\xf0\x11\x14\x9c\xf8\xeb\xebB\xa2`r\x0b\xa2\x85\x16{\xf7\xa8\x10\xf9;\xe4l\x19\xa4D\xd0\xf6\x82c%W4%:L,\xb9\xbc!\xff%\xce\xa9H\x9cS\xff5Fn6\xfed\x7f\xd3\x1f(Ka./\xde\xa1'\x83\xb4Z\xfd?36\xbe\xc8\xe8\xe2\\\x1a\xd7(s\xcfl\xac\x97\x85\x1e)\x99jY\x0c\x8a\x1fu&{O\x1dA\x1d\x88\n\x87\xf6\xc1?$\x0e\x81\x0btA\x8f\xa9\x91P\xaa;\x84\xcf \x9c\xda\x96\xb2\xe5\xc0\x8b\xe1\x1a\xc3\x91\x0f\xf6\x89]M\xb4uO6\xfc\xc9\x0eHu\x11\x9b\xd9\xb6\xfa\xce\xc0\xa3\xa4\x15B\x8a\x94\x9fL\x9cA\xa5\x81p\xcf^1\xd158\xf72W\x14\xddu\x86\xb0\xec\x07\xed.M>\xb6x\xdc\x90N\xb6\x133P\xfd\x15\xea!\x19\xf1\x88\xa8m\xa6\xd9\xf8b \xa1!\xda[\xe4\x05\xac\xf2\x07\x0f\xf4\xcfRN#h\xb6\xd7`\x99#a\xa6\xe2W\x87 \xd3\x91\x9b\x0dI\x00>\xb2\x16L\x06\x8e\x85\x88\xc7\x1f\x19\xf5o\xdc\x81v\xa6\xe5\xbe\xc4\xee\x0e\xa0QQ\x9aM \x12\xeb\x99\xa0\xb6v\x16\x97\x9a\xa1:3\xa6\x88\xdf\xe7\xafVKQd\xb6^6\\ \xcd\xc7q^\xc6\xc1\x05\xe7\x92\xa2\xcd\xca\xcfd\xbd\x85*Y\xb7\xa7}i\xbci|l5\x8ey*G\xf0g\xe9\xca\x02\xbe\xd8^\xcd\xa7F5\x97\xb7\xa9\xe6\x1f\x8dj\x16\xdd\xd5\xe8_b5\xbej\x1ca\x19\x8f\x8f.y\x02w\xd3\xe2\x7f\xed\xcc\xcbx|L#i\x0e\xe0x4\x8aCzc\x05)\xfc\xe1h\xc8L&4\x0b\xbc\xcc\xe5|\x1c+\x0f\x85\x8e\xaf\x12<\xcc\xab`\xc6\xe3\x93U\x9c\x05\xe0K\x90\xc9_\x08H\xe4%7q&\x81\xf4o\x0c\xccW >\x9a\x9d$p\xa3\x0e\x91\xfd\x9a\xd9o8\xf5\x99/\xfd\xd6:!\xbc@\xc8\x0f\x0b\xe0[\x96Q\xdf\x04^\xa9\x04\xbc\x80\x8a\x9f\x04\xb0)\x12\xe4\x08\x1c\x96\xe7\xa9\x18\xb0X\xfcG\xb2\xe5L\xe1\xd3$2\x81\x88\x80\xfc Z _$\xa0X\xe6\xc4\xeag\x13\xe8#\xcdX1s \xcd\x98m\xd6N\x19\x03\xf3\x0b'\x85\x1f8\x80lQ*\x7f! \x19\x0d\xa5\xcf\xc9T\xfeB@\xf24\x06I\x8f\x93\xca_M\x90\xb3`\xc5t\xb4$'\x0bV,\xc7B\x1ae<\xfe\x89\x87\xf9\xaa\xec\xdd\x1a^m\xfd\xfb\x99\x06\x99l\xfe\x95\xfce\xd0\x11\x18 \xf6{c\xff^\x8f\xb3\x84z\x9f{\xec\xfd\x1f\x1aeK_\xcb\x82\xe0~\xfdR\x1f\x98{\xf5\x8b\x1a\xb1\xf3\x199 \xea3\xd5\xcc\xc2W\xbe.\xfe\xc8)<\xf4ft\x81\x1du\xd2\xd3{\x00\xba\xfb\xd6 ?\xeap\xc6\xdd\xb5\xcb\xeaMW@\x05>\x06\xb9\xa9/\x86%\xfeA\xba\x1bU\x0e\xdc\xd4\x1e\x01\xb9\x8f\xfc\xcf\x06\x96k\xe0\xcb\x84\xd1\xcf\xcd,\xd9\xb0u\xe03nm6\xcd\xfd\x00\xcb%\xa6\x0c=+]a\xdb\xfbp>$\xaf\x06\xe4U]\x1e\x93\x01\xb1\xd7Vx\x1c\xe7\xe9\xd2E\x86 \x1b\x92W\xb3\xec\\t\xdcB7\xb7v\\j\xac\xdd\xef\x8c\x9cH4Y\xe0\xcb[\xceI\xb0Z|\xf3v\x0d\xc9\xb7\\Us\x9e\xac\xee\xb7\x0b\x1f\x19h\x88\x11'Q?Z\xbap\x9a_\xae\x02)\xb4\xd4\xbfn\xd7\x8d\xc0\x128E\xad \xe9*\xce\x1a\xd7\x8b]g4a\xf4~\xc7\xe1\xb5\n/>\x14\xad\xd3?\x99=$\x01\x82;\x7fj\xe0\xce\x1b\xa0\x9b\xe4\x89\xd0\x87p\xfa\x11\xe5\xfd\xe5%\x07&k\xb8\xa4\xe2\x94Fs\x12<\x1d\xae@\xb0\x0c\xb6\xba\x14\xc7\x1f\x96\xb5\xb4\xd4\x15\xac,\"\x90@\xc6\x14\xc5\xb2>\xb3\x9b\x05\x8b\xf0\xbc0\x88>\xe39\x82\x9e\xc1s\xd4\x1d\n\x96\xa5Ug\xb1<8\x0e\xf1\xac\xab\xcbN\xe1\xcd\xcf\xe84\x89Uf\x95\n\xc5\x89\xad%j5w}\xf3\xff\x80\xff\xbe\xe6WW,\xca\x83\x8c\xad\x90\xf2\xe4\xc7\x9ap\xedW\xd0\xa2\x99\xd1\xd1\xefG\xa3\xbf\x9d\xab\xff\xd3\x8b\xdf\xc6\xbf\x8d~\xf3\xcf\xff\xf2\xe7\x87U\xf0\xbf\"\xb7\x95\xff i\xb5\xd3\x06#B\xfe\x8cJ3\n\xedJ\x1d^\xd0\x199\x03\xf2\xfd\x01\xd9\xa9J0\x02[\xa4\x92\xbfA\xb0\x01\xe4{\xbf\xb4\xc5\xd8\x13|{\x15\x17u\x85\xc4\xf9Oy\x03\xfeW\xf03\xfb\xe5\x0bq\x7f\x05\xf3su\xcf!\x08\x98\xc7\nW\xfeU\xdf\xbd4\xdc\xbc\x16\x04NUFb\x86\x03\xc9\xe8\x824\\C\xea\xcc\x88\xaeX\x1aS\x8f}\xfa\xf8\x9aT\xe3ph\xb9\x94\xbee\xa8e\xc7 [\x07r\x9e\xb9e\x9dRZ[\x1a\xa4\x05,u%\xa99\x17\xb4\xbe\xa5\x9d*\xbcv\xee\xc6\x16\x08\xd5s\x18\x92\xd7Q\x90\x054\xd4t\xbb\xa0%\xe7C\x92\x0c\xc9\xd5@\xfa\xd8o\xfa\xf4\xfb\xda\xe6fP|\xfd\xa4\\\x98\xf0\x8d\xf71\x8b\xce\xe8B\x9a\xdd\x1cE\xfe\x87\xf2\xda*\x85\x0f\xb6,\xf6\xebZ]JA@\xd6\xa5[k\xe9\xa7h\xfe\xd6\xb5@)?\xce\x8a]yN\x0e\xc9\x89X\xdeR\xf3\xebD\xaet\xb2M\xae\xc5/\xb9\xfc\xadKC\x02\xf7@\xe0\x1b\x92\xaf]\x14O\xc7\xc9\xf2\xa68\x82\xe6c\x9ag\x1c\xc2\x88H\xd3\xba\xd6r\xc1x. M\xfe\xe3\x9fr\x14w4\xeb\xd3\xbfSwZ\xa9\" r\x99gY+-\xf7o\xd0\x8dNz\xb3\xa3Q\xff\xe8O\xbc(\x99J\xab\xbeN\x0f\xcc\xd0CCQ+\xd6\xc8\x03l\x83\xb3\xb0\xb8\xd2H\xe0J\x03?\xc7@\xa7\xa7~\x8f\x91t\xc6\x89\x06/\xee\xb3\xa4\xc5T\xcf\x0c)\x11\xd8\xcfP\x0d\xfa\x1ek\x03x\xa7\xfe\xa8N\xa1\x04\xe2\xa2\xd8\x0e\x04\xfdt8\x87\xd5\x8f\x03\xba$\x92\x96\x01\xcb.7P\x7f5&\xc6$6\xdc\xfd\xe3\xebP+\xa2\x08\xa2-\x80x\xf6r\x9a\xe5\xfc\xbe\xe2 \x94H\xdd@-\xa6\x8e\x06\x135\xa29\xc1\xdc\xeccOA'\x9b\xf4\xe4\x9fK,\x0c\xeb\xe8\x90\xbcm\x8e(\xc8\xd4\xc4\x87\xbcz\x9bk~ ]1\xd8\x10(\x01\x85.\xab\x94\xda'\xb9\xd4 \"\xdb\x07\xc4\x01\x15\xa5\xbc}\xc2\xfb\xc6\xcb0\xcc\xc2#\x9f%g\\\xf0\xf9\x81'\xdbA\x0eID\xa6\xfa\xf4\xa9\xd2\x1cf[\x1a\xad\x07\xfa\x03\xf4\x8eZ\x80^\xbfT\x15\x83\xech\xd0\xea\xd3\x1d;\xb5\xfb\xf9s_\x17\xe1Kp\xe2\x80\x93\x16\xb5\xad\xe6J1\xf7\x1c\x1f\x14\x0b\x85\x8f\xa5\xce#\xccRB\xca\x04divP=b\xc1\x7f\x98\x15\x1aYZUL\xd0\x1b\x86\xe2\x98M\x01R?T\xadu\xc0\x0df\x84p]\x83\x9d_)Q\n\x0c\xdc\x89\x1b\xb4\xd1\xc5f \xda\x86\xd3\x12\xbd\xef\xa5\xfcQ\x13\x8aT\xc5[\x18\xff7\x0f\"\xd7qng\xa7O\xca\xa5\xfc\xb3I\xa3 \xce\xf37\x15\x02,\x19{K\x9a\x1ce\xee\x8e\xd8\xbb\x90\xbcM\x1225\xe2^\x10\xeb\xca\xab\xd1\xb7\xbd\xa5\xa6Z\x89\xed~\x97X>\x86\xd3T\x94\x17\x08\xe2\x7f\xc6bs\xa4\x83\x89\xc0\xe8 \x84\x86\x06\x0c\xd8{\x05Z\x1bY\x9c\xd5i\xfbB\x94\xec\xca\xces\x12\x92\x17$\xd5\xb6\x94$\xdc\xde\x1e\xe8fI\x0e6\x19\x92t\x16\x9ew\x912\x8d\xe8\x14\x1e\x0b\x8c\xf0\x14\x9ba1\x8c6i\x0e\x0d\x06e\xdc\xceHv\xb0h\x81\x9b\xc1\xc9\xdf\x8czR7\xe8\xab\x16\xbb\xc5\x16\x00\x19=\xbe\x8c\x82o+\xd7\xefb\x8c\xb8M\xdc\xcb\x15 \x82f\xda\x96%\xb9\x17J\x9a\xdb\xa4\xb3\xbaMh\xe6\x9d\xda\xd4)\xba\xe56\xf1\xacn\x13\x9ay\xa76\xf5\xe0\x03\xb9M\xec\xaa[\x85f\"$\xb3\x9d\x01\x7fW\x14j\x13\xaapE@7`\n,\xa3 \xc4V\x19v\x8b\xf8\xfa-\xde\x95\xda\xd1\x15M\x8c!\xb9\xc6\x83\xe3\xde\x95\x03\xec1\x1f\x97X\x83\xee\xf0\xc9\xcee\xd9\xc1t\xfe\xd4\x8f\xe9\xac\x9f\xfc\xc8\x0co\x80\xade\x8cI\x0b\xcf\x98 >\x00\xf4\x03:\xf3\x08\xc3(Y~4Y\x1f\x7fl\x96 \xe7\x91Yq\x85+\xeb#YN\xed\xecZ;\x1f\x05\xfd\x0cD?\xd3\x01I\xeb\xed\x0e\xa4\xec\x1fX%pU\xf2\xc7\xd7\xc1,8\x07B\xbd\x83\x9d\xb33\x8f\xedW\x8e\x92Z@\xb8`r\x08\x03G L\xad\xdc\xe6\x89`\xcc*\x0c\x1fka\xf8f\xd8A\xecB\x11\xd1\xed9\x90\x81q\xc5dfn\xaa\xd1\xc4\x83M\xd6x\xebZ\x12\xe0\x10\x98\xa6\x87Pb.\xa6\xb0}\xf1\x0dI\xdc\xb5\xa7Hek\xc4\x03\xb2\x15#{\xe3\xcb\x172\x87\xb1\xc0\xf3n\xb5o\xaa_\x9e\x0f\xd0\xca\x1f< \xb1\xa8OL\xc1\\\xfc\xb0\xecR\x91\xd7!\x81\x90\xfbM\x14E\"\xfb\xe9\xa7\xa0\xe0Q\xe9\x94\x98\x1aC85\x07|;\x95k\xa3\xdc\xaa=j\xaf\xc9n\x06\xf6\x9d\x9c\xb2\xacm\x1b\xb7\xdf\x8d\x17\xdf\xdb`\xa3w\xa3`\xdf\xa6|^\x7f\xca\xddrX\xedI\xd1K_u\x81L\xed\xd8\xc5\xdf0\x10k3\x05\x84U\xd4l\x80\x12\xd8\x15\xe3\x98c'\xb2\xf5\xfc\xbd5\xd7]\xb0\xb6\xac\xc2\xda\xb2~\xac\xed\xdd\x99c\nZz-6|\xd6L\xc5\xd1\xe3\xd5\xe6m\x02\x05\xd0\x8f\xbfU\xb5\xa9\xc1\xc6\xf3\x92\x8d/G\x0b/\x16vq\xffx1\xaf\xf25\x03\xbd[\xbc\x07\xcf+\x9f1\xe0\x11\x1aKg\xa5\x05q\xa4B]e\x06\xff\xabIr\x89\xb8#uF{\xa2\xc8\x16 _\x03\xf8\x8c]gJ\xf8\xe8V,>\x03PF(\xe4\x16\xd6\"d\x9b\x04\x03\xe3\x98\xcc\xc9!\xa1P.\xaf\x95SW\x92\x8e\x14\xf2\x1aE\xc2\x1a`\xd1\x81\x10\x0bg]\xdbL\x8a\xffy\x07\x0e\x85\x8b]\x84\xed\x1d%F\xab\x1b\xd5 u\xe6\x91]\x95\x10\xabyC\x9e\xfd\xff\xe9\xe2\x19\x8f\xd6\xf9\x95c\x87[\x01\xd8\x0f\x07iV\xdezvT<\\\xed<'\x11yA\xb2B\xfa\x15mo\x0fH6\x8b\xce\x95\x0e\x87\xcd\xf2\x9c\xf4a\xe7\xda\xf8\xd9\xde<\xe6\xf58\xcdx|\x96P\xefs\x10-\xbaN\xc7\xce6\x81\xc3\x82\xb6&-\x19\xf5\xdboo\xb9\x7f\xd3\xd2\xde\xc4u\x9e6\x1f\xe93\\\xf6\xd9i*C\xea\xa7\x8f&\x8bA6\xe0\x07\xa2\xf4h|\xc7\x03\xf1\xe9\xb3\xba\xcb2\x0e\x86\x87\xa3U:\xea\xf4\xdc]_\xeaj\xeb&n\xe1e\xdd\xe5C\xe2\xac\xd2\x913\xa8\xe3\xda;\xb5\xfb\xe1\xc8\x1d\x0f\x1e.n\xd9\xbe\xb2u\xc9\xb0\x1b\x85kW\xe0\xe3\x8c\x7f\x12\x14$\xe2\x02\xfc\xeb\xbdv\xceF\xa5(\xaa!\x19\x07\xe9\xa7(\xc8B\x96\xa6\xef\xc0\x7f\xd9\xa0k\x1cZ]\x19iQ\x02h@9\x97\x9c\x87\x8cV\\\x17\xcb\x0c\xa5\xc0_z\xe0\xaa\xed\x04\xady\x11\xa4\xef\xe8;7\xab\xa1\x07\xbd2DU \xe80\x9c(s\xc4?\xe5\x83\x07\x84K/\x922\xd2\x05\x99\x82\x08\xbc\x11!\x80HG\xe3`\x96\x99\x04+\xd0\xcf\xca\xc4y\x13_7N\xf7;N\xca\xfe\x0e6)\x0f\xff~\xb7\x8d2\xa8\xec\x94\x11l\x95\xfbl\xf7Cwv4\xfa\xdb\xf9=m\x16g\xf4\xe7\x893\xb08\xc3\xbfCk\xfb\xb5H\xcb\x0b\xfe\xf8\x8a.\xae\xa2 z\xe6\x17\xdb\xb8\xb6\xd8\"y\xf9\x90\xcd\"pq-M\x89\xa5\x14>\x82\xd54\x8b\xec~\x05\xc8m;lpg\x8fw:\xf7\xafej\xbes\xbe#\xdb\xb0\x88\xc8\xb6x\xb9\xe7\x86M\xcc\x86i\x92\xa9\xda\x10q\x08\x87\xecL\xd9\xfcb\xa2l\x8e\xcdE\x97A7\x01?\xa9\xea\xa6\x1b\xdc>\xa4 !(|\xa7B\xda\xff\x07\xf7\xe0[\x13\x84\x9ft\x931\xbb\xce\x12\xeae\xbat\xd9\x1e+s\x8e\xcf\xc2\xbd\x84~\xd9}2\xc0\xec\xe09z\xe8h\x9e\xc1\xb2\xcc\xa3\x19\xabn\xc0s\xcc*=\x9a9?\xb3\xcb\xcfA\x06\xae\xff\x80\x1c\xb9*\xde3\xc8\x7f\xcb\x7f/3W\xf2E\xe6\xac\xd22\xe3\xedi\x99\xfe\xbeL\xe6\x90\xda\xf8jm \x12\xe3`hN3\x8d\x82\x15\xb8\xf8\x02OM\xdcu\x8et\x823$\xe5\xcbI\xe4c|KQ:\xc8\x98\xf4\x14\xd6R\xc7k\x0d\xd3Z\x93\n\xf5g\xad\x05\x9cqa5d\x89\xa0?\xcd\xae\x9c\x15)\xa2\x86\xf2\x0d:S]\x81My\x02\xe6v\xde\\\x0d\xa6k{q\x00\xe6\xfd\x18\xf6\xca\xa0\x8a}\x01Q\x1b\xae\x82\xc8\xe7W\x80\x04\xa5\xa8\x8d\x04csf\xca\x97!i\x02\x14\x83\xdf\x0e\x06#[\xbe\x0e\xaac\x82\xb4\xa5\xa8\xa22\xb4\xc6[o\x9f\xd9\x82\xc6\xa13v^P.\xe2\xe5y\x03d+0a\x90h(\xe2\xe4 \x1aE\x0d\x113\xce)\xa2\\b$5\\D\x91\xbc\xd2.P`\x88\xce\xd1\x8d_qIJ\xee\x8e\x946s\xfc\xdct\xc1,%_\xbb\x93\xba\x0f\xe3\x1c\x97:J\xc7\xcf\x8f\xf6\x8cCE\xbb#~\x86b\xc7\xb0\xdb\xbd\x19h\x13 zY\xc6@5\xeb\xf5\xac\x07\xaa\xe3-\x99\xf7\xf9\x92_\xebHU:,\x1c\xb8\x84\xe7\x95\xd4\xc3R;d\x0c\xc5\x98oj\x8c\x8c!R\x9b\x05\x1d6\xa3)\x98\xaa|\x1b\x88\x95\xe8x\xa1$ nf\x11\xed$\x1a\xecX6\xb2A\x9a\x93\xb2\xff\x98\xcf\x1a\xf1\xc8\xb0\x9aR\xe8f\xb9f\x850\xa8m\x10\x10(\xba\x15\x80^k\x80F\xfeWX\xddx\xe3Tx\x7f\xd5\xbd\xf6o(\xd8\x9fd\xd8\xc16H\x15\x99P\xcfg\xa4\xccFX\xed\x9e*\x90*\xf4P!^\x91\xa7\xdb\xa5\xabJ\xc8!h\xe8[\xaaR\xfd\xc0++\xddc\xd6K\xeb\x9c\xe6\xd0\xb5\x9e6\xa6\xd9\xff\x06\xeb.\x1b\x9b#\xd9\\O\xac\xa7\x8b\x8dj\x9f\xcb1\xca\x8a-uh\xfc\x9e\x96\xdfm\x1d%sR\xcc:aN\xa1F\xf9kJl\xb7\xffU\x8f\x1f]s\xd1M\xcc\x92\xc6m'\xa6\x11\xde.\x9b\x95\xfb\x9d]3/\xcf\xd8{\xf5q7k\xb7mK\xc74\xa5\xb1\x1bv\x1aI\xae\x0b\x85\xf6\x88\xaeZ,\xe4Azh`Ce\xfbk\xe8k\xa2\x14\xbf\xf9\x14G\xa68Xr\xfb=\xd1\x10\xee0\x82\xe7\xc43\xc2\xf7=\x1f@j%\xa9\xdf\xd7\xe6P\xec\x1f9KnNA\xf7\x96'Ga\xe8\xca\x9b\xdb\x99\xe8\xf5\x81\xa0i\xff\xcf\xe9\xfbwc)i\x08\xe67Re\x01D\xd8\xdf\x9d\x83\xda\xcc\x81\xea\xfd\xf9w\x03\xe9\x02`\xe79\x89\xc9\x8b\"\xf4\xd9s\x12oow\x0d\x01Q#\xee\x83\xd6Y\xdc!\xb3$j\xdc\xfdR'\xc3\x1f\xcfy\xb2\x82\x19\x08\xe0g\x9f/\x12\xf5\xd5\xa5\x1ew=\xdeb\xec\xe1\xd2\xb5\x1e;\xcd\xf6,\x95c\xadg\xe0\xe4\xbb\\d\xcbn\xc9*.\xfa\xec\xce\xb5\xe7\xa0\x01\xa8\xf4\xf3u|\x19D>\x1a\x9eO<\x1e\x8f\xb2\x84Ko\xb2\x1e\xa6N\xd0\xaaM]\xa1<\xba\xf0\xc0\xda\xea@\xbfe\xf3Kd\xab\x10`sn\xca\xe3\xe9\xc1\x03\x12\xa0\xdaq\xf8\x06\x13\xdc\xb4\xa3\xaa\x85;\x1b\x88}\x8b\xcc\xbe&\x17\xad\xd5\xe0\xb8\xb1N\x9b4+\xaeZ\x84\xe1x|N\\)'\xe4pG\xa1M\xde\x00{\x0f\xf4\x0f\xc1\x8d\xeeX\xc4\xf2\xc5MD\x11\xd2\xad\xc4Y]\xb8\x1aD\xec4I\xe5]\xa1\xab\xbe6$\x93\x1d\x90\x18\xb5\xdc\xc9\xb8\\\xeai)\x8f1RcK\xb7VbH0\xa9,\xdb/\x91\x0c\xbe\x80e'\xca\xe2\x1a\x1c\xaf\x039\x8b!\xd6\xa3\x16\xf2*x\x03_W\xcfr\xd9\xd4JJ\xf1\xc9&\xa4[\x03E\x01\xb5f\xd9\x81y\xaec\x0d8.\xf3\xca\x8au\xe2\x01\xd9\xda\xaaC\xb6\x926u/\xe8\xdfl\x7f\xda\xb6Fs*\ne\xb1\xd6\x05\xa8\xf4\xab\xa4\xd7\xd66\xed\x1c\xe9\x05\xb6\xc5d\xa5KA\x08\x02\xbd\xb7~\x02\x9a\x06\x1a\x85\xdc\xa3\xed*I+\x1ee\xcbv=\xaa\xae\xaf]1f\xd3n#\x10a\xb5\xdc2C\xe3-\xea\xa0i\xf5\xd32\xaa\xaa\x82>\xdf\x8ej\x0c\xa2~\x9a\xc7\\\xc1\xb0[(3eb*\xdd\x11H \xa99?,\xbbdl\xa2zZ_(\xfc3u\x05\xcd\xe2\xcd\"M\x9dC\xea\xad\x04\x17f5\xce\xe9\xc9\xf1\xc7\x93\xb3\x8b\x97\xef/\xde\xbd?\xbb\xf8ptzzq\xf6\xe3\xeb\xd3\x8b\xf7\x1f/~}\xff\xe9\xe2\xe7\xd7o\xde\\\xfcpr\xf1\xea\xf5\xc7\x93\x97\xce\xed\xbfi\x08K\xeaR\x11\x15o\xb9\x1e\x0d+\xc0\x85\x1f\x94\xe0q\xa0\xf2\xf2^\x0f\x8e\xdf\"\xb3\x90V\xa4\xf6{\x90\xfa\x15\x9c\xe6\xe2\xc7Z\xad\xae\x88K\xc7\x86\x1d\xc8\xaf\x90[\x10\xe9\x9f\xacq\xd3&\xc5 \xe5)Z\xa6\x1f\x92\x8cl\x8b\x92SiN\x01\xd2\xc8\xad\x9d\xba\x9c}0$Y\xb9:*#\x1c\xe2\xee\xd9\xb8\xe9K\xc2\xd0\xa5\x96\x94\x8b2\xf6\xab\x17,d3\x92!\x01\xc4\x03\xea\xd5\xd7\x99[\xbf\xa8 V\xe4\x10\x0c[\xbc\x80\x98=\xb7X@\x08\x90\xc0PDo2\xca\xdbb\xf7OI\xea\x96\xfa\xef\x03\xf9\xd1\xad\xc9\xb0\x16\xe0\xb7]7\xa9\xe0\xc6\x0c{\xf4\xa4b\x8fn-J4\xf7 .\x0ef\xe1\xb9\xe4~\xfa0>rEv\xb36\x80\xda[\xa1,\x8a\x1b\xa5Y\x90l\x9dl\xda\xed\xe5\"r\xbd\x08\xa6$\xefX\x04\xdf\x96\xe8\xb1s\x1c\x06!\x19X\xe8\x9f\x8a\x037\xd7\x01xg\xa8K\xb6\xd2n\xb7\x14\x87&\x16\xf9e9\x9cm\"\xbf2l[\x8b\x14\x12\xa1\xeaJ\x99oU$\xa7\xbf\xaaN\xcc\xe2\xd5\x0ei\xe1\xbf\xc0\xe7\xa3\xb9\xf7\xec\x02\\\xf5-\xaft5\xcd+\xd7r\xa4\xcf!-U\xee\xeez`nt\xbb\xd0\xbcE\xa0\xf8A\x9aoz\x8b\x90\xf6\xbaE\x08;n\x11\xf4/\xfc\xb8\xdap\xb9j\x81E\xc9\xff\xd8\xad\x9e\x12\xd7y6q \x82\xfe\x1fmRp%\xaf\xbe\x1f\xe1w\xb9\x13\x1c\x159nC\xa1\xf7\xbf\x8b\x9c:\xe8\xbe\x1f\xb1\x9c\xf8\xa6fT+\xc5@\x1b\xe2p\xbb\x187$\x07\x9d\x0ed*\x96QnE\xd7V\xac\x85]\xb1\x16\xaa'n(\xc5 \xa1:F\xc9\x8b\x032\xd1\xf2\xb9=G\xf9~ g;\xe7\x03\xe9\xdc\x16\xe644\xb8r\xa9\xc8K5\xd7\x00\xc2\x9b\xe6\xfc4R\xfa\x1efUq\xbc\x94S\xfc_&w\x0f6\x95\xbb\xab-\x9eK\xc9hZ8m\xec\x10Rv\x8c\xfa\xbfD\xfcH7\x92\xfc%\xf5]\xd7E\x92v\x10\xe3\x92\x9e\xc2\x07Z\xda(F%%\xe2\x96\xfc5\xafH\x9d\x1ar\xab\xa8.\xb7B\xa4o\xcd\x15o\x17\x995+\xac\xc9\xc0\xda\xe6\xf1\xb6D\xdbf3#E\xc9Yi\xc1\x89P2\xea\x82\xdb\x8e\xee\xa1\xafY)\xc5\xd8\x90\xfd\xff\x96\x94\xc5\xee.f\xcf\xe4\n\xf8]\x19\xe4X\xda\xf2l\xaeg\xa3A\x9f*v\xc3\xa85\xfd\x90\xf0\xa1\x9dQ\x04Y\xbfv\x90\xd6\xd6\xec\x14\x1cGgC8;i\xdd`\x99\x0dE-\xc5\xe7\xa4\x06\xa9\xbd\x86\xf28B\x17V\xc7\xaa\xe0bU\xd0\x86\x05q\x04\x12T\xd8\x0fQ}M\xf0\"\x9a\xf6d\xdffg\xa5\x95\xbeg\xaer+h_DR\x1d\xca9;\xf9\xe5\xec\xe2\xf8\xfd\xbb\xb3\x93wg\x16G\xacD]1\xc3\xd0X\xa2 \x8bg\x0e\x07\xb8\xcf\xae\xbb\xbcR\xce\xd5M}\x17\\\xc6{UG\xe7\x19K\xca\xfaP\xb8\xaf\x03\xcc\x1d\xa4m14\xdd\xd8\xfe\x8f_\x07\xa7'g\x17o\x8f>\xfe\xf5\xd3\x87\xff\xb7\nH\xdeq\x1c\xdbVCf\xf8\x16\xbc\x1dIp\xdb/\xd7\xcf\xc9\xea\"\xb4\x8f\x1aG\x14\xb5\xcd\x87v\x9c\x809r6W\x89\x19Wz0\xa5\x92\xa0\xb0\x9f\xcf\xe2\x1c\x84\xab\x97V\xe7wp\x0c\x0d\x0b\x973\xed'\x1f(6\xb5\x83\xf8\xdd \xcbn\x90\xb5\xf5\xe6B?\xb0\xe1=\xa9*\xddZ\x15\x0cC}\xcb{\x9d\xe4\x00Qc\xb3\"\xeav3\x99y=\xe8\x02\xf1,\x04E8\xf3z\xa8oIU\xad\x059$\xee\x1c\xa4\xb9su\xe4\x97\xc1cVC\xb2\x1eB$\x9e\xc1@\x86\xe3yK\xb3\xe5xE\xaf\xdd\x95y\xc0\x0b\x80!Y\xd5\xce\xfc\x18|\xf1\xad\x80\xb1h/\xabB:\x95M\xb8(\x11\xe8\x91\x04s\x17CBg\xcbs\xdd\xa2L\xd9B-\xb7\xb7\x07C\x12\x0b\xf2b\xad\xf9|\xed\x81\xc7E\x9c\x7f\x98\x8f]\x7f\xab\x9c`>h\x1a\x03zR\xbaUk\xb2\x89\xf5]\x980\xc2g\xde\xf9\xa0\xcdm>\xf8?\xd2\xe8}^\xfa\x0fi\xd2\xb5\xcdK\x17\x82\xf6\x00\xc3\x7f\x91\x95\\o=\x087<\x05\x9b\xe7^f\xfah\xb5\x84\x9c\xec\xd3\x81bA\xf6vLF\n7\x05\xe6\x92|!\x80\xeb\x96y\x1d\xa8\x98\x94\xf4g\xfb\x9eU'\xef\xdb\xf7?\x9d\\\x9c\xfc\xf2\xfa\xf4\xec\xf5\xbb\xffl9|\x89y\x00w#?\xe3\x1c\xae\xf4\xa9\xbb\x94{\xcd\xae\x11\xaf\xac\xc7E\n\xb1L\xed}\xcd\xeb\xc7\x13\xd8\xc3\xef\xde\xbf<\xe9;\xab\xdd\xe3\x7f\xd7\xfd\xdbB\xa2\x93\xfeT5\xe9IY\x93\x8em\xdbkV\x9bg\xf8-$a\x85\xc5w\x95\xb4H\xd4\xa9b\xe0\x05Qe\xd4\xbbm\xe6Q\xd5s\xcd\xe9\x0b<\xf8\xb0\x19b\x8f\xe1w\xf0\xc4\xde\xfcH\xbaBl\xb6\xf4O\xf8\x9bEt\xedA\xea\xadD\xd7\xa5\x9b'\xd4\xd6W\xb9\x17\xa8\xfb\xe1 \x86\xa7\xae\xfa-8)\xa5\xdb\xbb\xbb{ \x97\xde\xdd\xdd\xad\x0b\xb4\x89\xa1x\xb6_\x1b\xb4\xdau91\x85\xccy\xc7\x81\xbfV\xb6\x1b\x86\x17&\xd60Z$\xe6} \xa8\x89H\xa1\xb7\xb4\xb3\xe7\x82^i*\x89U\xc7FV\xbfu\xa0*x\x0fN \x11\x15\x0f\x81=.N\xde\xfd4%N\x9cp?\x87^ \xe8\xe4\xe7\x93\x1f>\x1c\x1d\xff\xf5\xe2\xf5\xbb7\xaf\xdf\x9d\\\x9c\x9e\xfd\xfa\xe6\xe4tJ\xb6&\xd5F\xd4FJ\x8b\x0b\x9b\xdfE\xa4\xd8\x1b\x13M\xfa\x8e\x8a\x0dL\xb5\x80v\xb9j\xdd0\\?Z\xbc.>\x9d\xcb@\x01\x1b\x88\xf1\xda\xba@\xa1\xc2\x14\xa2U{\xe0k\xd7\xde#\xf0\xe9\xd1y#+\xf8\x9c\x0e\x9e/n\xf1\xbd\xa4\x1f\xd4\xba6\xee\xcd\xf3 \x06\x15\xd8%\xb8\xd8b\xb3\xf8\x1c\xb8\x0d\xbf~G\xda\x8f\x1d\\\x83\xf5n_k\x1e\xbd9@?(p\x97C\xb2\x1e\x0cH2\xae\x07Sq}`\xc3\xf2!\xf8b\xca\xa4\x1f\xa2\x96\xb1\xd3O\x0f\xbfJ\xfa\x91*JTV\x9dT\xa8W\x1f\xdc.\xd4\xbd\xa2\x8a6mM\xfa\xc4(#\x06w\xcd\xdd5l\xfa~\xa5TOW\xfd\xa0\xc57\x16\xd0\xfaZKW\xf5\xa5\xdb\xaf\xbeH\x8a\xcf;\x98Z\xd2\xca\xd8\xb6\xe7\x96k\x9c\x0d\xc8V\xc3\xc7[\x0cV&\x80\xf8\x90\x05.\xcd\xf5\xc1[[|.\x98\xf5\x8d\xa7\x0em\xd7]Y\xdc\x96\x13\xbdj(o\xf1vG\x88\xc5\xe3]\xd4\xb9\xa55r\xc4O\"\xf3A\xc6\x84\xa3\xb4\x8c~\x90Q\xa9\xa4\xd4\xd0\xb1I5\x94\x17|_\x07\xca\xb5\x8c8\xac\x1f?V\x13p+z\xa2\xf3*\xdc\xa2d\xd7PV\xa7\x96\x8bs\xa5dW\xf7\x89\x99*U\xbd\xba#\x80P\xb5\xa5\x9e\xeeU|h\xee=y\\'P\xe68\xe5\x13\xcb\xfa\x1a>9}Y\xdf\xbe\xa2w&\xf5\xea\x96\xaa;\xf5v\xacK%\xfbzO\x05Z\xaa9\xce\x14Xd\x17\xbb\xd2\x07\xc7T\x7f`\xb7\xf2\x97\xe8\xca/\x15H\xcb\xe5rS:\x7fU\xd1 M\xdf\x15\x18u\xc8\xc8\x01 \xc5\xbe\x96:\x89xX\xe8\xc6\x02\x85\xbb\x0b\xe9\x94Z\xaa\xf7(\x12^*\x97Wbf\xd5c\x0d(*B\xf5\xa9\xa2\xb5_]\x82\x17\xcd\xb1\xbbB\xe9$\x8fGi\x96\xe4^\xaf\xebALM\xcb\x88\xf3eq\xf7\xeb\x89\xad\x9c\x06\x19;\xbb\x89YA\xf4\xcb\xbc@i\xc6\xd4\x92\x8d\xd0\x8f\xcd\x8c\xca%l-_\x0e\xdb\x0f4\xf3\x96\xd2\xffZ-?f\x91\x1fD\x8b\xb2\xedH&h\xd6\x80\x03#<\xff\xa3\xf4\xb9\xa5\x15\xeb\xb6&\xb5\xfcW<\xf1\x98\xbc-\xa8dk\xc1\x9f\x18!d(\n\xb9\xa0\xc6|\xb5|\xb5>j\xa9\x80,\xdf'r\xb1\x16C\x9e)\xafOJi \xef\xc71\x0d\xc3K\xea}N\xeb\x1f\xa2ah4\xe3\xe7 \x0c?I\xa4\x0c\xddi\xac\x0c\xabZD[\xe46\xab%z\xbd\xb3\x1c\xed\xe9\xc5\xf66\xbaV\xb2\xd6\x85b'\xdd\xe9\xd0\xb8\xf3\xe9\xaf\x83G\x14\xe6U\xe3\xaa\x14}\n+\x11{!\xcf\xf61\x1ce\xe8g\x0eJ\x82\x0b\x96\xc9\xe5%\xbdl\xb5|\xc6o\xf5\xbeS\x7f\x14v\xd9r\xb7X\x89\n\xc1\xfa\xd8x\x1f\x07)\x04\xbe*f\xb7\xe5lv\xbd\x96\xb6-\xcb!\xd08\xa8B\x08I\xca\xd0F\x13\xfafD\x86%1LV\x97\x1ay\x1f\xf6\xf2eF6\xe8\xf8\x87\x9d\xe9\xb3tl\xb2\xeb\xb6N\x05\xd2\xb8!\x91\x1e\x06b\x1eD\x99-\xa0\x07\xee\xaa^?E\xd4Vl\xa5V\x9b\x83#f\xed\xda>o=\x0e\xc6 \x97\xa4\x91K\x07u\x1c\x86\xee=7o\xd9\xf9\xa0\x96]\xadC#\xa7\n\xdd\xf0\xc1(Y/`2\ne\xaa\xc2\xc2\x83\x016\xbeV\xba\xb2\xc9bo\xed\x808\xa2\xd2\xeb;\x0fu\xdbZ\x0dn\xb9\x1ao\xb5\xf8\x8aq\xd6\xe3f\xa7IZ4_\x83\x12\x83 \x8a\xb8@|.\x96\xe1v,\x87\xa0\xc7\n\x08\xf4\xa4\x07\xe5<\x0f\x86\x15\xc1~\xa1\xaan\xce4\x90\x0543&\xdc\xb5 \x03\xd7\xca\xe5\xbd'\x90\xb78\xecQ\xcf\x18\xa4\xa1flp0H0,b\x08\xe6\xcd\x81\x07a|\x95|\x02i8\xdc\"x\xe3\x93\xb7\x1f\xce~m\xbf>\xb2,hI\x85\xcc\x11\x15\xdeD/\x92*\x81\xbe\x0cB\xdf\xa0\xd2\xb1(\xde\xc8z\xec\x1f\xd2\x8a\x187\xb3\x15\xb1\x9f\xa5\x03\xbd>\xbfi\xf4+\xa2E\xf0\x96ov\\\x02d\x8dmc\x97\xdcII\xbf\x87q\x8c\x0f\x1e\x90\xad\xac\x8d\xa7\xecs\x87\xd0\xc1\x92\xee\x0c\xdb\xef4\xf4S\xb9\xb8, \xbam\xe2\xa0mw\x07\x1d\x01\x05\x08\xe8w\x07\xd1\x9a\x7ff\xff\x99\xd3\xc4g\xbe\xe6\xa9A\x05\x00\xadU\x9a\x93e-!E )\xac\xd6\xf1*\xda\x82a\xd9\xb6\x08\xe8i51\xbf\x05\x1c\xd3W\xba\xa5\xd8\xa2&\xe1\xf9\xf6\x14r%\xdb&\xe3h\x95\x03\xe1\x92\x16\\\xb8e\x93\xb4\x84:p\x99\x8dE\xec\xb3\xe5/V4\xfd\xac\x10U\x9f\xed\xben3\xa7\x04\x1eVuM\xcc\xa3%\xec\x07\xf8\xdb-C \xc4v\xfc\x8e\xf9\xc1\xd6O5~N6 \xd1,9o\x0d`c\xf5\x14\x87\x8dKU\xd2\xb2\xf9\xd0\x18\xe3j=\xf2\xf4\x99\xb3Q\x83\x8c\x93\xa5w\xabL=\xfb\x8d\xa4AM\xca\xc6>\xa5\x81t3[6\x8f\xe8\xe8\x0c\x8d\x1c\x19\xa8\xa1\x0d\xa1VC\xf0 \\\xb5\xf2rpl\xac\xb6\x82\xa5~\xba9K=\x90\x1f\xc2j\xd5B\x8f\xfd\xcdj\x15g\xbe\x1d\x89\x96.w\xbf\x02\xdf\xdb{\x0f\x13\x83\x1d\xeb\xb5n\x80`7;\xd4_\xab\x0f\xf3\x81\xd1H\xaa_X\xf7\xaf~]Q\xbd\xef{\xe5\xceM\xa1\x9e\xe8T\x1b9\xd9\x86\x84\x95\xdeCyP\x011\xc7@I\xaa\x9f\xaa\xa4b\x1f\xe4\xd9\xf0z\xfe\x8e\x89\x0dJ\x93\x9b>\xfb\xb2P\x8e\xc1\xdayH\xe6ME\x80\xcc\xb0\x14\xab\xc2\x0f\xcb\xfb\x11M\xc7\x97\xce\xa8\x0f\xac\xa7\xe1\x97/\xf6\x83\xee\x10\x1f\xa3\xf2;\xd5\xd9jO\xad\\;\x99M\x94 \xb6\x1b\x95>SPk z\x0f\xd0a\xfdI{\xe2\xb8\xc8\xf4\x97 0\xc2\xde\xa6\xa2\xbb\x16\x16i\x08\xbc\xcc\xd6\xa4m1\x17D\xc3\x81\x0c\xd2\x9b\x83\x11\xb8N\x9dJ\xd7[jF\xab\xf7\x04\xc1@\xd5o\xd3\xbeX+\xc7&\x9dW\x11\x10\xe2\xd8\xe6\x1d\x88\xc0\xd5#X\xe5\x03\xeeW\x9f\x1cJ\x17\x98\xb4Ji~\x94\xeb\x1b\xbc\xa6td\xbb\x9e=\xa6\xd9Z\x07\xfe7\xfb]\xe1r\xa1\xb0\xbdGq\x8bw(\xeb\xf6\x80\xf8h\xe3t\xc9\xf3\xb0$K\x8b\xad\x13\xc3\xc4\xa0\xb9\xa25\xf3\xa1\x8c\x82\xacg\xb5\"\n?8 \xd2\x8c\x03\xda\xe5\xbb\xe1\x90x\xb0\xac\xb6|\xf1E\xd1\xa3!\x99\x03\x9f\xde\xbe{\x86$&\x87\x9a7\xeb$e\x01\x91\xd5\xdb\x1aI\x9d\x19\xb8(ab\x17\x81\x95 \xb6\xd5\xc57\x9b\xb4m0$\xb4\x10\xea{\xe2E\xcb$\xe6Cc\xe5\x1e`\xa6=-$\x909\xbb=\xd5O*|Y\x0f)My,5\xd0f\x1fb \xe1,\xect\x93\xb5\x08\xc6m \xcc\xccVii\x11\xb5]dHGo\x0f\x1e\x90\x89r\xa4+\x1d\xc6\x14\x85\x93\xd9\x8e\x85p6\x88\xb1\x03E\xb2\x08\xfc#\n\x88sF~T\xb9\x84\x13\x19\x132%;\xcfI^\xf1\xee\x96\xb7\xfb\xc5^\x1bf\xd9v\xb2\x89\xbbtH\x1c=\xe5\xa6'\xc2\x94\x1c\x92T\xea\xd8H\x8dE\xb9\x1c\xa6$\xbd\x05e\x85\xf8\xbf\xc1\x96#\xbakn\xa1y\xad\xaf\x87\x87\xda\x13A\xdfe*\xb0\xf1\x0f2d\x9b\x1bV\xee?d[,8\xd3#\xda\xe3O\xa8%\x809\xbc(\xf4\x02\xbe:\n\x91\xe0\x90\x845\x19\x81D \xe07\x0b\xc9(\xee\x03p\xaa\xc0\xd4\xe6\xa8\xa0\x8a\xb0@\x15\xd9P\xb7E\xe2\x95\xd0@\x15I\x15\xef}\xac\xcb\x06\\\x18\xe8\xa1\xec#o\xbf2\xc2\x86L\nO\xc2B\xe9Ut\xbf\x1fv\xb24\xe8V\x18\xaa).iEU\xd1m\xc8g\xbb,\xb7\x1d\xc5\xd9\xa4\xd7s\xe2.]\x10\x95\x0f0\xf2URb\xacMP\x9a\xd9\xa4\xc8\x1d\xca\xac\x1a5U%\xa16{Y\xf1 r\xaah\x88\xbb@\xd7OS\x92\x8d\xb9\xdb\xd6Ou\x1a\xbb\xa5\xd9d\x03\x896\xef'\xd1&-\xb2\xba\xd6\x90\xac\x9a\x18\xc4\xc4\xdd\xc5\xfc\x95:1fJ\xcd{E\xdbT\x8bm\xda\xddp8\x0d\xc5\xf0\xfd\x1cdK\xe9]@\x1c\x01!\xca\xa2\x91\xdeR/\xb4\xe2\xfe\x9c+\x1d\xe3-c\x1b\xd8\xd9Y\xf7\x9fy\xb9\xfb>i\x8az\xda0\x08\xeb\xc9\xcb\x14\xc62\xb2\x11\xee\xddZ\xdc\xb7q]4P\x95\x14\x16+|\xd1F2\xe4c\x85\xf4T\xa7[VS\xeb\x95\xafx\xba\xaf\xb8\xd0iA\x06N?_\xc9<\x88h\x18v}\xd9\xec\x05\xca\xf5\xea\xa7\xd5\xf9\xec\xad\xdb\xdf.*\xd5\xdaA\xcc\xd0\x0eb\xa8v\x10+\xb5\x83\x9em\xc8\x16\x0f\xfbI\xb2h\x96Qo\xf9\x91\xcdos\xa2.X\xf6!\xbf\x0c\x03\xafp\x94f\xe9\xb9\xe6\xf2#\xcd\xe5Ov\xda\x18w\x194\xa7w\xedn\xa4\x14\x99\x0e\x0e\x80=\xd3\xaf\xe4\x8f\xaf@I\x8b\xb7\x81\x0c\x04\xd7\xcbv\xc7g\xc8\x98\xd8\x06D\x05\xd5\xb3\x8d\x07||\xc6\xce\xfb|W\xcdl\xdf\x8d\x7f;\xe1s\xf3~\x10\xcc!*)\xe3B9\x86[\xdcQ\x15\xa8\xae\xa6\xae\xa6l+j\xa9\xacPbS\xf9\xfa\xb5\xaf@\xaa1\xb0\x1b\x8fQ/\xcc\x8d!L\xedc\x02\x96\xf0\xb4\xdf\xa6\xb2\x93\x19\x88\xcd\xaa\xc56R*X\xdd\xc9\x96a\x82\xd7l\x1d9\xcd\xb2no\x17\xc9_\xef\xde\n\x94\xb1<\xbdY]rp\xc7*\x7f\x8d\x057\\ys\x9dD\x8c\xdc\x98\xc9U\xed\x00\xba{\xb23\xd9\xd9\xc3{\x95\xfc\xb3Z*\xa3s\xf2\xa4:\xed\xe0W\xf3\x7f\xffo\x9dy\xeb8\xcc*\x04\x0c\xa8\xe6\xcd\x92s\xd8=3~^\xc3|\xe0\xb3\x1dkmy\x01X\x0f\x0cp\xab\x91i\xb1\xb2\x95V\xb2\xcf\x1b\x9d\x90F4\x9b\x19\xc7\xf2\x0e%;0_\x12CR\\Y\x19\xc1\x12\xda\xf6?\x18/\xb53^\x86^\x0e\xb7\x9a9\xed\x0c\xa5\xa9md\x1a\xdf\xba\\\xda\xddvG\xb8\xaa\x0e\xd2\xbf\xca\x04\xd7\x16\xdc\xd5r\xda\xe3\x96\xb4\x08\x02m\xbbS\xd6(\xc5\xd57@-\x8e\xd3\xbf\x891\x17\x1eb\xe4I\xdd3\xba\x0e1\xf2\x14\xb1\xe6*\xcd\xad\xf6'\x0d\x07\xa79x\xa4\xaa~\xbai\xd9\xacd#\xd5S\xabb\x1e_\xfc.6E\xd8D\x12p>%L9\x8f\x0d~g\x10\xef\x97\xaa\x1a\x87:_\x90\xaag\xfc4\xa3Y\xe0I\x1e\xca\x10\x0f\xe5);6\xa3\x19\x9b\xf2\xd0\xbc\xb4NP\xea\xe5\xb4\xd5k{\xd3\xdd\xa9\xe0\xe2\xcb6)\xe5\x8a\xb4\xe3\xb4V\x8b\xa4\xea!\xa8v\xac6EN\xfd*M;*5\x0c2\xfaUX\x1f\xa8\xb6\xfa}\xa6\xa9\xa8\xda\xccW\xc1J\xed\xcfV0\xad\xe6\xd9\xb2\x8a\nP7,\x0d \xc03\xaa7\x18\x12>\xa6\xbe\xff\x81\xf30\x88\x16g\xdc\x0dk\x18\xe1^\x1c \xef\xee>2\x10\xbfD\xfa&\x14o#@\x8a\xb5\xcf\x9a\xe7\x0d\xa9\xc5\xb8o\xe1Q@\x15\xc6eD\xd3|p.\x0eH\xb6L\xf8\x15\xacjA\xd8I\xfd_\xe7\x98F\x11\xcf\x88\xc0<\x84\x12/\xa4iJhJh\xf1%\x07\xc1\xee\xea\xd6\xb8\xd0\xb5\xca\xca%/\xce\x83\xea\x92\xa8\xce\xa1\xa6\x9bM\xf3\x14X\xd3\xac\xdb\xe6G\x9b\xbb\xd4\x10\xfb\xb0R\x9dB5Z\x81\xaa\x8e\xe9-\xf2\x97z7\xc6A\xfa:\xaa`\x17\xe0\xdc\xea\xb5\xe3\xb2\x19\xbcE\xd5k\xb2\xf6\x9en\xd8\x1c\xa3\xea\xba\xc3w\xbc-\xb5\x0b\xa1\xceU\xb5a{\xcc\xea\xdd\xa6\x1e\n\xde\xa6S\x96}\xab\xf6\xe8\xaa-m)1\x88\xc9a\x9b\xa8\x81\xdf\x07j\xb0\x9c\xc5\xfb\xb6\xb3\x189\x8a{\xac\x1a\xe4\x0e\xb5f\x87\xfa\x8e\xfbu\xa5\xc5[\xdb\xad\xfa|%\xf5\n\xab\x83jbbjb\xe2j\xa3\xbb\xcd-\xad\xbeb\xa8\xbc\xa0\x08\xfcc@\x1e\xc9\xf6v\x93\xf8\xaa6\x91\xa2\x9d\xdd\xd4\xf0R\x0b\xec\x1d\x02\xec\xd9\x88\xad\xe2\xecfJ B\xa5\xf1\xb9m\xe2\x10D\x0bW\xfa!\xa8\x93 m\x14|*\xfb\xc9\xaf\"\x96\xbc\xe4^\x0e\x12\x0e\xe55\x89\xaf@HfSb\xd06\x0b\xe38a\x1e\xf5\x96\xacP\xe5\x967P\xdcEn1\x9b\xf2\xc0\x9aT\xb7FX\x1d\xca0^\xceo\xd7{\xde\xd6h$\xc6!\x17\xbd\x1f\x8d~\xbb\xdecNm\xaf\xd5\xce\x02\xab\x8eW\xf3\xf0\xef\xaf\xc4^t\xdb\x1a\x04\xba\xadQ-\xda\xea(\x930\xce\xa3\xea\xd8\xd6j/qK\x8d\xda\xa0\xf7\x82R&\x15b\x03\x0f\x1b\xc0Q4\xea\x14\xb8\xc0\x01\xe7\x19J\xd0\xba\x07\xd1]j\x99\x99\x91Y]k\x86\x07\x0eP.\x06\x86\xf39\xe1\xcfI3\x80\x1d\x89\xea\x9b\xb4\x12\xb5{G\x1a\x03e\xcf }\x0e\xbfh\xb5t\x80\x96~N\"2\"\x01\xf9\x9e\xec<\x1f\x80\xbc\x8bU\xaf\x91\xa2\xd1\x08-\x16\x90\x11\x89T1@\x04\xd5b\x01ZL\xef\xfe\xe89\xc9G\xa3\xe7v^\x1dB\x02\xb71\x8dHK\x1b\xad\xb0\xac$R\x15\xa5\xff\xa9 a\xae\xb3j\x0b\x83\xf4(\xf2XZ\xa5\xc8m\xa7\xacm\x89$\xc9lr\xbe\x89\x96W\xdb\xdc\xf5gIk\xea\n\x06\xea\xb5\x88\x08\xda8\x07i\xe8\x88\xec\x0e\xbcS\x05\xd1\x01*\xf1v\xa6x\x1c\xb1\xeb\xec4\xb8\x0c\x83h\xf1\xdcJ\xa7\x93\xda\xc5X\xa6\x14Z\x9e\x14\xd6q\x12\xe9\x0e\x86d_2A\xe3H\xab)>x@j\xf8\xcc\x80\x90\x11\x0d[\xbeJ\xcaE\\\xc7 \x16c-\xfd\xb4G\xe0\xb6;\xd3\x94\x04\x981,=\x17\x8d\x9e:A\xe1U\x0fx\x1c\xab\x9d[\xcedVWa\xba\x9b\xa8\xe2vD\x81\xc0\xd0\xb7\x15q\xdc\xcb\x85\x8aEj\xfa\x08'\x07\xf1\x1bL\x19h\xb1:x\x16\xef\xcb\xfafqJh\xf3\xb0\x15\x83\xd7\xb5\xd7 (\x02\x07)\xd8\xce\x04\xd1B\x85M\xb4\xb8\xa0k\x9b_Qfv\xdb6\xf2\xf1<\xcc\xd3%\xb4\x82)-\xf4T\xaa\xa1\xf3\x86\x04Gv%+\xbb!e0\xc9`\x08\x85A\x17m\xee\xd6<\x91}%W\xcb d\xc4\xadKT\x8cX\x82 \x97\xe1\xe4E\xa5n-b\xe1 \xa1\x81\xc5Qd\xce\xf8\xf9\x90,\xc7\xcaC\xd7\x99\x9a\x03\x97U\xa6C:\xb53\x87j\xd8\x18;\x1c\x17\xc7v.\xde\xa6\xa9\xd1\x18&lu\x18$Du\x81\x18\x19\xf5\x01h\xde\x19\x96M\x06n\xb1\xa2\xaa!\xf8\xc5qv\xc5\x8f\x92\x05\xf0\xb5\"\xa7\xe2dx\xad\x1c\xefW\x1b|\xc1\"z\x192\x7f*0d5\xa7:\xc4X\xdc\x95\x9f_\xbf{\xf9\xfe\xe7\x8b\x1f\x8f\xde\xbd|s2%\xc1\xd8\xa3\xd1\xa7\x94\xbd|\xff\x96\x1c\x92\xab \xf2\xf9\x15\xc1\xca\xa5,\xfb\xb1Vy\xbb\xe4\xa81\xe1bQT\xc7\xa6\xf1\x85\x13\xdd\xb1\xce\xaa\xd5\x10\x88Sb\xab\xb5\xd6 mV\xdar\xfc\x96U\xb7U\x9a%4\xfeAJ\x1faQ\xf4\x13V\xeb\xdb\x0drH\xf8X\x06\xf0W\xb1\x89\x96\xa0Z-\x0e@\xa8N\x124r\x99\xb1\x81\x16\xd7v5\xe8X\x892o\xdb\"%\n\xbd\xaf&\xadx\x14d<9\xf5\x12\x1e\xca\x88\xe8]\xd3\xaaQf;\x94x\x98\xeb\xb9r\xad\"\x8e\x9b\xbeV\xdb\xda$<\x8a\xc1\x97U\x0c\x89\x93B#\x1dD\x8d\xa2\x8aN\xcc\x11\xe9)\xd3(\x17T\x1b\xd1$0f\x0c\x86\x06\x02\x05\xb4\xc6\xeei\xb7\xcfI\xc7U\"\xce\xf5\xedr\x81\x1eF7\xf18a!\xa3)so+\\(\xde,$\xd7\x12RoEr\xf5S\xc1.\xc4`?K\xe4\x067\x1d\x86\x0eY\x91q\x88\x8c\x03\xc4\xc5\x8a\xe9\x82\xfd\xf2~>O\x99\x0c\xd82\xf6\xb5\xc6\x82\xfe\xa1m4\xe4:z\xc3\xe6\x88\x00\xf5FW\xf5\xeb\x06U\x9d\xf1\xaaX\xf0+\xc1\x82\xceC+;\xbfm\xa9\xf1O\xd5_\xb7\x9a\x89\x92\xf8\xdd\xaf3\xaa\xea\x9acb!~\x1b\xd7\"\xed\x81\x16\xf6\x9e\xe0\x91\x16&\x8f\xeb\xf5\x84\n\xbe\xde\x1e\x0f\xa7\x97q\xbe\xc9\x10B\xd0q\x10\xfd7\x83qi\x8e\xef\xcb\xf7ou\xfc\x8d)I\xda OVqvcT\x9b\xb7\x02\x0b<\xf3!\xcc\x17A\xf4c~)\xb8\xdf~\xc0\x9f\xb2 L\xc5\xd9\xde\x05~\xb2\n\xb2\x8c%S\xf0\x9bg\x05\xfd\x11t\x88\x8a&\x87m\xb0\x05\xef\xe8\x95P\xd5\xf5\xf6/\xe0\xbc\x1e\xd7\x99\xa6\x00g\xb1\xa8e-\xa9\xb5\xf7\xb4\x9e\x9eV\xd4\xc8'\x8f\x9e\xd6\xd5\xc8\x15\x17\xb6[\xff\xbe\xd7-\x03\x01\x8e\xe0\x94\x85r\x08_G\x82\xd9\xa5\xf8\x98+\xd9H>N\x80\x16eE\xa9\xea\xc0c\xf1\xb9\xcd/v\xca\x7f\xb4\xbc\x97\x8e\x0b\xa2\xaa\xc3&\x92\x8eK\xa2\xce\x85X\xe3\xbd\x0c\xad\xea\x02)+\x1dP\xa9\x1f \x94S\x17D\xddu\x04\x94\xa4\xa8\xa2\xb0.F\x9da\xc6\xad=:\xb6\xd1w\"\x9e\x05\xf3\x9b\xa30\xc4\xbeU\xed(*\xf8B\x98\xfbv\xc9W\xbb\xe5Aa^Pk'\xa8Q\x94\x94Ldx\x99D\x8c\x14\x0c-\xd5\xca\x86\x8e\xef\xd5\x06\xc1\xab\xad\x83z\xc5\xb7\xb2A\xc0:\xdf\xf1\x9d\x8d\xcd\x12Z)l\x9b\x81\xc1&\x0d\xae\xf8\xa8n\xfb\x18b\xa6`W\x18hl\x11\xed\xca\xba\xa1\xc6]y\xed\xcd\xae\xf3\x82,\xc5>7\xb0.\xcc&\xcfR.\xbf\x12\x91%\xee\xdc\x14)\xa4C\x12\x0f\x86$\xa8\xf2\xee\xf3\xba\xe1\x15\x14\xbf\xe3\x01\xd6\x90\x05*]\xea\xddz\xdc\xa7@\x1dl{\xa8\x18\x8f\xb6h)\x94\xd78\xdap[*\xa8%\x96\x8d\x98KO\xe6\x85\x90\xe0\xc1\x03\xe2\xa4\xfa\x80\x01\x85/M\xb9\x8a\xac-\xd71\x8f-\xc8W\x8cZ\xf3\xe8l\xce\xeb\x82e\x928N\xa7$'\x87=N\x00\xcd3\x16tt\xd16u}\xff\x91F\x8b\xd6\xa0,`\xdb1\xce\xd8u\xa6d8vP\xb8\xb3\x1d\xfby\x1c\x06\x1e\xcd\xac\xd7\xb5 \x84\xaa?\xe3\n\xcb\x9dI\xb7\xa6C\x92\xc8\xd3\xca\xff\x00\xbb\xcd9\x89|@\xaaI\xe6\xd8\xb9=-rK\xcc\x16\xb6\x9e\xb9-\xbc\xa1\xf8VC\xed\xcf|X\xe4OA\x03\xa5\xe9\xf7\x95\xe0\xcc\x1e\xe9\xc2\x07\xc4\x98$\xb9\x12*\x84\x8dX4H\xb2mh\xe5-\xb1`\x9dv\xd4-k\"\xe6\x174mz\x86\x05\x95\xf3M#o\xc9!\xdep\xd7tKH\xb9,\xed\xb0\xd2\xb7\xc1\x9c{y\xda^iP\x02v\xd5\x99k\x7f \xb0\x86\x8f2\xd7\xe6\x91\xb0]$\x90\x8fa\xe2\x0b+\x80\xe2\xeazH\xf21\x8b\xfcf\x06>\xf9:XC\x9f\xd8=\xa8\x07\x00\x82.!b\x98\x04P\xb723\xf5\xd1\xaf\x8cpu\x14\x07\xe4\x90\xec\x10A\x04g\xfc\x14\xd40\xdcA\xe7~\x0eA\xf2\xee\x85<\xd2h\x02\x1f\xdfPa\x15\xf1]p\x06\x12e)\xec\xe8P\xedh\xb7>\xc6C=\xea\xaau\xf6\xe5\xe8)\x0d\xa7z\xf9\xd0,/^\xcd\x99R\xef\xd5\xae\x87\x9bt]\xf0\xbb\x1e\xd9&-\xee+c\x13\xadV\x90)\xde\x9bX\x0c\x06\xe03W\xb94\x8b\xf5\xf0p\xbb\x03#\xad\xd2\x14\x8f=\x1e\x864N\x99%`k_\xf4\xe6\x8bs\x83L\x89\xd7\x81\xe6\x04\x9c'\xd0W\xcfu\x8a\x90\xf3\xa9\xf5\xb8\xear\xb52\xd4\n\xcb]\xe7V\xf7icX\xbagbQ\x90CIL\x00\xf2\x801!\xd3\xe2\xd7\xf7\x05\x8c+\x01X\xe4\x0f\x15\xa2\x03\x08\xf0Zi\x94\xd5\x99,\xf2\xc1\xd4\x14?\xd9d\xba\x9c{\xc7[\xd2\x84z\x19K\x1ci\x19\xce[\x8e=^\x14\x16\xcb\xa4R4!\xa3\xa2\xb8\x18\x1a\x8c\xeb!=\x84\xb0D\x1d\x1b\xc8)\xd3\x86\xc8\xf4Q\x81\x1eN\xf6\xa5E\xd4\xb9\xc1f\x81;8\xef\xdc\x86DI\x1d\xde\xd2l9^\x05\x91[\x0e{\xc7G\xf2\xaa\x93\x03=\xad\x94L\xcd\xca\xe4\xf4\xb6\xa9\x95\x89\x035\x1a\xb3\xebL\x94\x7f\xf0\x80P\xf2=i\x0d\xc7C\x0c|\xdd\xe2\xa0\x8d\xa86Ri\xff\x92Z\x01\xed\x9aJZ9\x15\xb4\xd6i\xc7xx\x1a\xd0f7FTo\xc1\xe9\x87\xd7\xa7\x87\xf3\x0d\x11\xa0~\xe6%\"\x0c\xe1L\x15\xe8\x9aK\\=\x04\xc7Eb\xc1\x1f\x85!\xd4\x96\xba\x10/\xe8{\xc0 n$\xb8\x0c\xf9\x959\x00\xcb\x99q=U\x91\xa7+\x82\x8d:\xd7\x08\xb6\x91-\x8a\x1a5\xe1\xc2{b\x1d\xfeN\xb1>.\xc5\x93\xb3\xbc\x11\x13T$\x17\xdcKbWB\x00\xe1\xfdx\x1e$\xa9t\x91_(\"\x18I\x95\x82\x9a\xdb)\x12\xb1\xdb{n\xff\xa0\xdd\x16\xca\xd4\xa0+\xf5\x1a+\xea\x86\x8d\x82\xb2\xad\xa5\xeaCuH\xff\xd4\xfc\xd5\xdb\xb3G\xc5`-\x01\x9cl\x18\x9f\xed<'\x91\xb5'{\x92\x13,\x88\xbf6\x1cJ\xc1i\xed6\x89\x80\x1bQ\xa4\x90Fr$ /\x94\xea$%\xdf\x9b\x86b\xf6\xad\x16\x81\x96)\"\xd3\xd4\x8f\\\xceS\x92\x91\x11\x12\xa6\x8a\x90FHi\xfd\x04\x851b\x05\xb8\x91\"\x07\x8c\xbb\xd1\xe0\x9b\x9a\x7f\xec\xef\xedX\x8c\xb0\x8be(\xd5\x9c,\xfc\xfa\x96b{\xb6\"\xb0\x01WVe\x11$%n&\x13\x137\x1a\x14\xfaR\xc6:\x13\xb8\xc2\xf1$\xf1\x98*\xbb\xb6C\x88f#\x93D\xb1)\xd9\xda\x92\xf1mhR(\xda\x7f\xe0i\xa0\xb9\xb4\xad-w\xf2\x84< V 1\x84\x0d\x15\x8d;\x0f\xdb\xa4c\xd8\xac\x17~\x80F\x1e< {\xe0\xe9\xa6\xc9\xdb\xdc\xa1}\xfd\xda\xa1\xb9^\x97\x899\x19W\xec+\xe0\xf2\x8fL\x8b\xe3e0\xf6\xd9\x9c\xe6a\xf6S\xc0\xaeD\xa6$;Pd\xb6\xe5nI\x17\x83\x16_Qc0\xba9\xac\xder\xaa\xd4)\xeak \x84:\x118D\xaf\xa4W\x95\x9c\xa5v{\x13\xe0\x1d]\xb1\xfb\x9dwg\x99e\xf1\xf4\xe1\xc3\xab\xab\xab\xf1\xd5\xde\x98'\x8b\x87\x93g\xcf\x9e=\xbc\x0e\x83\xe8\xb3\xd3\x94\x90!\xf0\xbf\xbc}#\xca\xec?\x8c\xe8\x8a\xa51\xf5\x98\xd3\x94\xa05\xf1\x12\xf5<\x16e?\xb2`\xb1\xcc\xa6\xc4\x91\xaf\xa3%\xbc#>\x9a\xa8\xe7\xe5\xab<\x04O\xd6;H\xb6\xef\x07Y\xb0\xb6d\x86\xc1\"\x12s\xff\x03MY\x18DL|O\xa7\x8d.U\"\xf6\xd10\xe4W\x1f\x19O|\x96@\x99\xf2\x15\x85\x8e\x97\xf4\x92e\x81\x87\xb7b\x15\x87A\x96\xfb\x966&\xf42\xf0^\xf1d%>\x04/\xa39OV\xd8wR\x0fn\x07\xb1Z\xb2, .\xf3\x8cI7\x88N\xe5\x1d\xabJ\xe7\x8b\xa5g\xc2\x8bw\x0c>\xcf\xf8G\x06\xc6\x92\x02\xba|\xc3`\x7f\x0fVy\xb6D\xdb)\xc6\xfcU\xc2\xfe\x91\xb3\xc8\xbb\x99\x12\xa7\xf2\x8e\xd4%\xf2?$|\x1e\x84LA\xab7\x0b\xac\x98\xcf\xd3e0\xcf\x14\xb4x\x1f\xa5\"\x01+p\xc9\xaf\xf1V\xb2E\x10\xe19\x01M\xf1\x8c\x1b4\xd9\xa3\xa1\xf7\x16\x0e`G\xffD\x1a\xe2\xd1\xb8\xd8\x0f\x1e\x8d\xed\x9b\xc1\x0b\x83\x18\xffN\x18\xc4\x1f\xa8\x18tG\xfc\x1c\xc54[Z\xca\x7f\xcca,\x01,\xc9\xd1\x91\xd4\xb5}\x8a\x02\xc1w;\x95w\x0c\x9e\x87\xb3#\x1b?\x98\xcf\xf3\x94\x1ds\xe9\xabsJ\x9cZ\n\xd2\x1b?H$go\xa9\x11\xbc\x9eZ\xf2\xd6\x81m |\xbe\n\"Z\xc1\xef:\xa9\x0d\xbd\xfb\xb9\xa5:|\\}\xbca\xcc_0\xb5\xb7\xf5O\xe4[,dkj\xed\xb8\xd4[\xfb\x81z\x9f\x17 \xcf#_\xd4\x05I\xa3\xcb\"\x0d\xab4\xc2'U\xd0L\x91m\xda\x04\x9b\x9bD4\xfc\xc8R\x9e'\x1eK?\xb2\x7f\xe4A\xc2\xe0\xa3\xb6<\xe4\xe3\xf3 \x0c\xd1\x0f\x88\x8c\xf71\xf5\x02\xf0k#\xdeF\\\xbeZjQ\xa8\x08 -\xa8H\xeew\xdb\xe72\x96|d\xa9\xacB\xfe\xb6V\xa1q\x99\xf1\x86\xc1\x86\x9c\xfb\xc7\x02\x13\x08P\xf12\x02\xbc`\x035\xba\x0b\xc0-\xfd\xe5^\x9e\x8a\x99\xc5\xfb\xc2\xa3\xec\x15]\x05!T\xc5\xa3l4\x877\xb4\xa2(;\x05]\n \x98\x06\xbf\xa3\x03\xa7\xc0\x8e\xfc\xff\xce\xd3\xcc\x04\x1eQH\xb2\x95\xc9\x12\x96y\xcb\xa2\x80|\xb5\x02\xdf\x84eC\xc4\x8b\x05\xf0'\x9a\x04\x12U\x00\xe8Z\xbeZ\x80\x7f\xd6g!\xc0^\xd9\x0eC\xa9\xae\x83\x0fg\xc2Wx\x06\xbe\xc3\xe7\xf8\x0e_L\xf0\xe4]<9\xbc\x89\x97\x8a\xfe\x82\xdf\xa3\x08'\xbe \xf3}\x12\xb0(\x03\xcc\xf0#O\x82\xdf\x05\x9f\x18\x16%y\x99;Z\x16\xd9=\xea\xfa\x89%Y\xe0YjZ\xabL[=\xe0\xb8\xdb\xd1?1\xa8\x84\xfa\xa2:\xd0\x12\x99K\x9a\xb5\x91\xd6RNo\xc2\xca;\x02\xbf\xa4\xd1\x02Ned\x98a8\x8e\xfc\xf5/S\xe2\xc0\xef\x11\xf5\xd7\xa3k\xac\x16\x91\xfb> \x16AT\x02sxG\xe1\x03\x9f\xf1EB\xe3\xa5\x85\x90\x0fVt\xc1L\x92\x01\x12ZI\x86 \"xU\x11\xbe\x86\x80\xd8\xf1X\x8c/\xeb\xcfx*\xbeJ?\xe3_\xf8\xbc\x87'?\xc2\x93Y\x12\xb1\xf0-\xcd\x92\xe0zJ\x1c\xf3\x15\xe9\xad\xcc\x16\x93\xfa\x06\xe4UE\x892\xc9R\xca6\xd9\x9f\xd9\x0d\xdci\xa4P\x95\xfa\x8d\xd6qs\x1a\x8b\xd3^\x01\xaa\x17\x1c\xf2,Xi8\xf8\x89@Iy[\x81;\xcdW\x14:\xcbXr*p?\xac\x0b\xf9>Je\x02V@\xa040\xa6\x95'\x8d~\xb7\x1e6`\x8f\x0e\x05\"v\x14-\x00\xe96\xd2\xb0r\x1cp\x012\xb2+\x9a|f\xc9 \x90\x1c\xf2\xf7\x88\xa1\xb4\x86\xcc|\x1b\x18\x80\xab\xc0\x0ex*\xaf\x085h*o\xa1,\xc0\x05\xd7c\xbeZ\xa15\xf60\xde\xac\xb0?\x07>\xac?\xe3\x0d\x85M\xf1=U\x84\xcb-qV=\xc9R\x9d n\x87\xcb\x96lE\x15\xa2\xc6>\xcf-\xd2\x82(_\xbd\xf72\xba\x86\xf5[\xbe \xdf\xd0R]\xa4\x12\xae\x89\x164O\xbaa\xc73\xa5<\x04\xcd ld\xa7q\x00\xd9\xf2m\xdc6_\xb3d\x1e\xf2+k\xa6\xd8\xe4Z6:%\x8eN\x1a\xc5*\x0d\x1b\x17\x05s\xb6\x0c\xbc\xcf\x11KS\xb3\\\xa6\x13\x91\x821\x0d\xa2\xec\xbd\x92\x08\xc1\xcb\xc8&\x10\x8ai\xc4S6\x018\xf1k4A\x81\xb2e\x81&\xcb\x17\x1cRP\xe7\xb5\xf5\x88\xa4\xda\xcb\x9a\x07v=\xc9^\xaa\xf6)\xeb78\x1c[\xa0\xee\x0e\xe0\xf2}\xc4 \xc1V\x00\x97\xa3\xc8\xac\xa3\xec\x17]\x8f\xf8m\xad\xe2(\xfb\xd5\x80\xfb\xb5\x05\xeeo\x06\xdc\xdf0\xb8\x84\xa5,Y\xb3\xa30^R\xf0\x1bo\xbc\xb7\xc1\xa71\xf3\xb2\x8fby\x9b\xa5\xcaT\xb4,`\xee5+\xc6\xb7\x92\x80\x94\xc07\x9d \xa2r|\x18\x136\x17#(\xfea\xd5\xb1\xf9\xaf2\x17\x1b\xb2\x82\x9ey\x0d+\x0b\x00U\n\x08cP\xba=a1\xa3\x19(\x89A\x81\xe2\xcd\n\xfbR0\xe1N\xf1\x1b\x85\x93<\xe8\xc9u\xc6\xa24\xe0Q\n\x05\xea\x89-%_1\x9a\xe5 3\xcb\xe9$\xb4\x94\xd2oA\x074\xcdCK\x16\xcflR\x94\x04g7\x12\x1c\xf7\xa6\x1e\xb5\xb0\x87)c8\xc3\x9f.i\\!I!\xa1\x95$MC\x1e[\xbe\xa2 \x184\x8fyyH\x13C\xe8SO\xc2\xbe\xa5@N\n\xb9\x84SO\xc2K\xd9\xba\x1b'\x8c\xfaoY\xb6\xe4>\xd4U\xbeb\xf5\x94\xda]\x02\xb8|Ca\xfd\x97l\x1dh\xe1\xa5\xf9\x8aB\xb3\x15.\xe0\x169kKN\x90y\xcb\xb3 \x84\xe5h\xbc\xa1\xf5\xf3X\xd3\x86\xe2\xb7\x95.\x14\x99\xa5\x0c\x02@\xed\"\x884K\x82\xcf,[&<_,\x8dc\xb3\x92\xdevvV\x00\xcd\x03\xb4ZC\xdb)*o\xb8,\x03\x94\xf0\xcf\x96\x95 Y/i\xba\xa4IBeWE\xca\xc8\xd7I\xf8\xa7T!^\xae\x81\xa2\x14\xb7\xaf\x04\x01\xf3&\x88\x98G\xe3\xb2L(\x13Z\x0b\xfc7\x0f\xa2j \x91b-\xf26\xc8\x04\xdd\xb1\n\x8c\xa6\xad\x8a4k1s\xbe\xa1L\xeb\x8c\xf3\xcfL\xd3\xc2\n\xfc\xcaB\x0c\xa7y2\xa7\x1e;\x95X\xc81_1\xe8\x1b\xb1\xd4\xdf\xd0h\x91\xd3\x05\xc0W\x12\x90\x12\x19\xbd\x0c\xa5\xb7&\xb1d\x8c7\x146Y0 \x02\xd4/+\xcc\xaf\x05\x0cv\x96e\xec:;\x02\xfdV\x01\xc6\xae\xb3\x91\xd4v\xb5\x80\xbed\x1eO4\x0e\x00p\xbfH\xb1\x141\x91/\x94h\xc3\xbd\x02\xa0\xa0\xf9\xca\x17\x0c\x92\xa3\x1b!+\xe98$7\xc7%\x019. \xc8E;k\x14t\x91\xd6\x86\x06\n \x13\x05\x94%\xdb\xb6\x7f\x1e\x05\x9e\x8d\xb7Qy?\x04~\x00\xf5\xc1\xdb\xe82\xf0\x03{E\xa0|e@\x83\xaa:\x0e\x9e\xa5\x1fXr\xb2\x92\xc0Y:\x8a\x05\x85\x8a\x11\xbf\xeb#\xe3>\xd7Y\x8f\xca\xeb]\x0c\xf8G-\xaar\xd6#%\xb6\xc2\xc0^\x9b\xb2%g=2dM\x18\xf8\xdb\n\x87\xe8\xacG&\xcb\x88\x15P\xdb\n\x19\xd65\xf32\x9e\x9c\xcc\xe7\xcc\x13xF\xbe\x8e\x18\xbcc5\xb1$\xb5\xb1jk\x96dG\xfe\xfaW\xa8&\xc9@\xf0\x86\xa1\x1d\x91Y\xca\xdd\x00\xb4E\xecVB\xffZ\x83F\xeb\x0e\xd8\xd5\x0f\xfcZ@\xca_\x16\x983\xc0 \nL\xbe\xa0\x90ip\x19\x846n\x18P%>\xacW<\xf1K\x89\x8fxk\x91\xf7\\% \xa9Q\xb7E\xeam\xb4\xc2o\x8cp\x9a\xf1\xba\x90\x95\\\xdb\xef\x87\xafq\x04p\x8d#\x80\xeb\xe3%\x8d\"\x16J\xad[@\x91\xf5$\xec\x1ba\x10}>\xf2\xb2\x1c\x88^\x07^\xa7T\xbe[\xc1\x13/\xe1\xa1\x01.\xdfm\xe0?& \x88\x96\xb0\xcb\x04\x15EC\xe6G\xb3\xd2\xb6\x1aO\x97\xfc\xaa\x00L\x97\xfc\xca\x06x\x16dF\x95\x99x\xb3\x82\xca\xab\\\x05\x89_\xe2^\xaf\xc2\x1f\xc0\xd3\xb6s\xbd\n\xa7\x97\x14U\x98\xb8^\x85\x11\xbe\xc8 \xe7\x17\xf8\x00\xd4\x10\xa5SLAG\x81\x8a\xb3W})\xa4\xe8:\xbc^\x85b\xcd\xea\xf6`J;D\xfa2@\x1as\x83/\xae\x1b|q\xdd4\x17W= \xf9\xf2\xefh]\xbfs\xbe:\x8a\xfc\x0fT\x1cQ\xe5K\xab\x7fT\x8a*\x1f)\x17\x02\x81\xc0\x95\xf5@\x11Dz\x1982Ug`\x84R\xcc!\x04il\x85\xa4Y\x1dil\x806 \xb9\xec\xdb >v\xd6!\x17z\x1b\x84Z\xe1\xad \xb0\xb2m\x10zI[\x8c\xdc\x8a\x85h\xcfWk\xb0WH\xd9\xc6\x8cL\xcd\xc8]\xa4\xaa\x9d*#\x02\x8e?\xb3\x9b\xd4\x0d\x06\xe39ON\xa8\xb7t\xed\n\x84t\\\xae\x08\x19\xe7vgH\x02\xf1\xeb\xc1\x03\xe2\xd2q\xe3\xeb\x12H@\x18\xeax\xdf$@\xc7N\xddu\x02\xc7\xedW[\x82\xfe`\x0e\x15\xa4\xa3\x85Guk\xd7T\x81\xef\xe2>>\x1e\xe3>>vw\xeb\xd5\xcf\xc16\xbdj\xcb\xaa50\xdf\xea\xf8\x05\xa69k\xc3;\x8b\x80\"/\x0e\xc8\xa4\xe6=\xb1i\xaeN@2\x12\x02]\x83o\xd0xIS\xe6\x7fd\x8b \xcd$\x15\xaf\x97\x10\n.\x1e\xe5\xf1~J\x1c\x1eID\x85\xa0)\xfdh\xd7\xf6\x06\xb4r\x11\xe5\xa0e\x90\xf5M@\xd9&\x16LC\xe4\x01^\x9a9\x19\x8f\x7f\x08\xf3\xc4\x19\x12\x07\x04\x01\x10\x1b\xfb-\x8br\x95\xf2\x8a{y\xaa~\xff\x95\xdd\xbc\xe4WQ\xf9\xf6)V\xbf\xdf\xf2\x06\xe8I\xe47'\xab\xa9\xa2\xbf\xa1EV\x8b\x05q\x87\x0b\x12\xfbf*\x0dM\xa7=\x0d\x82Mc\xd4io\xd3\xe0\xc2du\xda\xcfB\xd8\xb0j\x9dV\x8d\\\xf1m\xdb\xb17\x88\x1a\xed\xa6\xa5a\xab\x85b\x0f\xdb\xc4[\x8e\xbb\xb4KP&\x84\xd3\xc2PA\x07\xc7o\xb1\xf3\x92Q\x12\xa4\xf1I\x0b\x14\x8f\x05\xd0%\xcf#\x1f|5\xc4v\xd8\x90\xcd3\x13\xf8\x0d\x9b\xdfn\x94\xbf\xba~m<\xc0\xb2n\x0d\x8a\xfa\x9e\xbb\x16\x07,6\xde\x80~\x9a\x03\xa9\xcd\xfes\xc3\x93J\xac\xe6aH\x96Cbq\x10\xa7\x06\x9fC\xb4xr\xa0]58C\x91\x04|\xa6\x98\xd7!I\xc6\xa5\xea\xba\x8e\xb8\xf3Ry\xb7c\xa9\x0bf\x99\xd5\xfe\xfd \xf9\x8c%N\x93h\xfce3X\xee\x9aE\xa0\x84\x9aNImF\xd8u\x96P/\xd3wtu\xca\xa4%|\xf4\xd6\xa2\xc3\xea_\x0fdF\x0em\xb1\xd3\x06d\x8a\x9a[\x88'\xbd\n\xdam\xde=\x9a2\xe3\xd8\x9bZW\x9a\x1b\xba\x1c\x82\x9d;Y\x923\xe9#\x9e\x8f\x95\xaa\xed\x89\x1f\x80\xc8Q\x9a\xf1\xf82\xb6\xc7R\xfa\xa2\xd5\x07T\x8b\xd1!\xb8\x82\xc7\xb3\x8b\xf6\xc1\x99mo^qd\x96\xc7d\xf1\xe5\xbb}\xb8<\xe9\xed_\x87\xe3\xd6\x12\x17\x8b\xf4\xfc\x8eI\x89\xe0_\xaa6\xe9S\xdc\xd2 \xb5\xa6\x14\x19@n\xa4E{G\x0b\xeaT\x8b\xbdz\xb1t\xe7\x83^\xdd\xd2$TG\x97$m\xd5\xd9!\xd5\x91\x0edFZ\x1c94\\b\xfa\x1f\xf2\xec\x0d\xf8\xd3d\xf5\xe8k\x16\xaf\xa3%\xf1*M\x97a\xd1\x03u\xb5c\xb5\xc1\xc3\x8d\xaf.!\xf5\xae\xcc\x0c\x1e\x99\xc9\xe6\xaf\xbb\xc9\xfbP\x9c\xc9\xc9\x95\x05\xdbc\x94\x9b\xd9\xdf\xab\xf3J!\xce\xfc(\x8f\xdd{u&g\xae\xd2\xeb\xf0\xb1jM=\xdd\x97\xf0\x8f\xea\xbdZ\xaa\xf4\xfa(\xacUz\x9d\xe9Z\xa9A\xab\xc3/\x14|\xdd\x07\xdf\x8d\x1c\xcd\xfa\xe8\\*\x1e\xad>\n\x17e\x84\xaa?\xbe\xd6\xf2\xaej\xe1\xe8g\x0e\xbd\xe4\xe0G\xc0\xa1Q \xdd\xe3\x9dD~\xe5\xfdu\xc6\xf4\x15\x89\x91\xaa\xfd\x0f8\x97\x8a\x95\xf1h\xf4!\xa47\xc6\xcf3ya\x08)a\xe0}\x86\x1fUn\xc7\xe3\xb1,\x91C]>\xcf/Cv\xac\x81\xfd\x84.\xf4\x7f\xd5*\xf9S\xfa7\x90/\xd7A\xa6\x7fC\x8c7\xfd\xf2~]\x02\x15\x8d\xf5\x13\x0e\x1c\x92\x9f\xcb.)<3$\x0e[\xc5Y\x00Q\xcc\x1c\x16y\xc9M\x9c\xe9\x17_\xfdH\x12\x0e\x15\xce5{\x16D\xb1lv\x10\xadi\x18\x00\xd4\xe7\x92_\xfb\xccn>$pO\x02\xbf%k\x16r\xea\xeb\xff\xcc\x7fI3Z\xbe\xbde\x19\xf5\x8d\x94\xa2\xd5+\x93\xd5\x83\x97\xb7\\v\x14^\xde\xe7%\x94\xee\xf5\xaa\xe4\x06c\x9afL\xfe\xc8S\xf9C\xcd\x93\xf8\x0f\x12m\xe2\xc4 _\xe8\xc6&4c\xe5\xc0\x80s>\xc7t\xf1\xeb\xa4\x8c}\x96\x83\"~\xa9\x1a\xd2\x8c\x86\xa1J\xcd/WrV\xd2<\x8d\x99\x9c\xb9,X\xa9P\xd4\xf0\xc6soy,\xc8\x87\xb0xUS\x0c\xbfu\x07\xe1\xa5\x18\x08\xb8\x1f\x0b\x8cE\xba\xe6a\xbe2\x1a{EA\xf6\x0e?\x97\x8c\x85\xcey\x0f)\x91f\x8d\xd8l\xe7|\x9c\xf1Oq\xcc\x92c\x9a2w@\xb6\x05c\x16\x06\x1es\xeb\x9b\x95(\xcbg\x87G\x10\xe3\xb7\x99\x0bv\x98\x19\x8f-\xd9\x1c\x15x\x90;\x8a5Z\x0c\xc1KiFD\xb6\x89s\x0f\x92\x8c\x04\x91*T\x0f\xe3\x0b)P\xe3Cr5K\xce\x8b\x80\xd9\x00Y\xf3\xd2~\xa2PS\x91X\x08\x07\xae\xad\x16\xca\xce\x18\xe2P\x8d/\x12\xce\x81.}\xfd\xb2\xac\x1f\xa9\xe9\xd4^\xd3e\x9ee\xd2\x0c\xf8@\x06\xe0T\xdb\xdbHH\x8d#W\xa6\x08TF\x13FU\x9a\xf1m\xfdK\xf4\xec\xb8\x95\x92\xbf\xd8\x90\x92\xe7(\x13D\x13B\x87pR\\\xcd\xd89.-\xd8\xba\xe9 \xf5\xfb\xd3\xeaGpjtPT\xc7\xeaD\xe8\x07\xa6O\x8b\x0e\xe8\x97U\xcc\xdd\x01}\xa2\xb0z\x17X\x81\xf1;\x01\xfd\x1e@pRt\x00\xbd\x86\xd5\xd5 $\x0f\x96\x0e\xb07\xe2P\xe9\x01\xa3\x0e\x9c^\x90\xc5a\xd4\x03Z\xe2\xe7\x0e\xc0\x0fp\xfat\x01\xf5X/\x1f\xd4\xa9\xd5\x05\xa6O\xb4\x0e\xb8\x8f\xe5i\xd7\x05 'a\x07\xd0\xa9<\x1b{@\xf5\xe8\xc3\xa9:S\xbb\xc0\xe4y\xdb %\xcf\xe2\x0e\xb0\xb3\xf2\x9c\xee\x80\xfc\xc9<|;`\x7fV\x07\xb3\x9d\xbf\x12<\xc0\x1d\x19\xe5\xbfj\x8a\xab\x9do\x94\xfe\x9e.\xdd\xa8M\x82\xac\x9f\xfbf#!\xb8\xd3\xdd\xba\xd9\"\x88(`\xba\x84)\xa2\x19\xde\xdd\x9a!\xc9\xf4\xf6\xa1\xdeU\xaeq\xe4\xe9\xba\xc9p\xbf4X\x81\x8e\xbev\xc9G\xaa\x80@Y\xf6\x01\xb4Nc\x15\xec}7\x1a\x7f[P\xe6\x1d\x80\xdd\x12\x18\xa2\xe6.\xbe\xdb\xdc\xbd\x14\x9cUGc^*\xae\xab\x17X\xd6\xdd\xb9\x97\x9a[\xeb\x01'9\xb9\x1e\x80}F\xf5e\xc1\x01v\x02\xf2\xae\xadkq\xadHz\x8e\xfb\x99\xc1\xf6t\xe1a\xcd\x12\xf5\x81\xeb\xb3\xa8\xcfJV\xaa\xbd\x8f\x16\xef\xb8\xa4g\x1f\x8fLABG\x9b\x8e\x9aB\x86\xbe%\xfa\xf4\xa4\xc5\xbb^\x9f\x9e\x9cU\xd8\xcd\xf6O\xad\xef\xf6)\x19\xe4\xa7\xe3\x1b\xab\xbb}\xe3g\xe0\x88\xdb?\x81\xf8\\\xd3O\x9fO\x1c\xf3\xb8\x93~;\xeeF\x98\x1f@d\xd1\xde\xd2\xa6?\xc4\xa6\x08\x96\n.-q\x9d\xfd'\x0e\x1e\xc8H\xf0M\x17\x10\x90\xa1\xbc%\xba)9\xadf\x01u\x80\x05\xed\xb7?\x17\x83!\xb9\xa8\x94\xbd\x07\xa1/\xdcV\xf3H\x1e\x89\xa5\xdcw\xeb\xd4e\xe3\x8b\x8c.\xd0\xdb1b\x08j\x05\x1fm\x17\x0f\x04z\x18\x90`\x83\xf8\xac\x9f\x08\x96\xfe\xcb\x17\xe2\x9e(\xde^G\x85\n\x0c\x89\xdf\x0d\x16_\xaamh\xae\x820|\xc9B\x961\xcb\xf0\xdc\xfb\xd8Djll\xbd\x8c\xce\x95\xc3Iw0$>4\x0dR\xbb\xfaU\xbcYd\xef\xc7\x90zG\xd9\xfb\xa3}\xd4\x81=o\x11\x18h\xf7nc\x8f\x86\xa1\x8a\xacn@\x97\xcd.~%c\x9aC\xbc\xf8\xe3\x90\xa6\xa9\xcb\xeba@\n\xa9\xb0\xf4\x8f\xd0\xd4\x06a\xd2/\xb1\xe0-\xb0\xec8e\xb9\xcf\xcb\x0b\xed\xca\xadhM\xfd\x8a\xdf\xd3\xa85o,\x9a+\xc4\x0b\x83\xf8\x92\xd3\x04\xf8\xe6>~\xda\xb54\xa9RP\xe9\x94\x1c\x126\xae\xa4\x17\xb7\xa6\xd5\xe4\xaee\x85Mw\xf0-\xa7;\x90^\x86\xcdI\x08\xeec\x12&\x93\xc9\xbf\xc1\xdaM\x98@\xe2\xbeV(\xff\xf6k\xafy\xf1\xc3-79\xb8\x87\xbd\xcf\xecf\n\xf7V\xf5[4\xa2<\x02d\xa0\xe0\xdf\xdce\xe2\xf1\xb2$\xfc+T\x80f\x83/\xb5\x96|\x1a\xb6\xe5\xaeXF[\xb2\xa51\xa8-\x17|\x19\xa0\xd8\x81\xc8\xb8\x16o\xb9\x1f\xcc\x03pA\x90 8wwR\xbf\x18\x14\x8f\xb7\xa4\xc9q5\xf4~\xe7v\xfd\xccnb\x10\x1cH9\xae\xd4\xfd8\x94nm\xa7\xb5x\xa4\x04\x17\x8f\x7ff7\xb7\xf8\xaa/\xb8V\xf3\xa3_\xbe@z\x1e\xd7\x9a\xc2\xc6\xea\x03}\xdbs\xb5\x0c\xbc\xe5\x86\xadi\x19\x83\xfbll%\x05Eg\xf4[b\x00:$\xc1\xb7P\xe9m\xee_\xfcP9I\xbd)qNR\x8f\xa26\x05\xa0=}I\x93)q\x08\x92\xfd\x06\xf4\xad\x9c\xa3$\xe1W\xe27\x02\xf2)\xd6\x00\x9f0\x83\xc6\x8f\xca\xd0\x04 >ZLM^\xf2\xabH\xc3\xc8\x9b\xc7&\x08\x0b\xa7\xc4\x91\xa4\x1a\x92\xfd3\x18K\xbe?E\xb2\xde\xb2(\x9f\x12\xa7\xa2\xf9\xda\x00:\x8a\xe3\xb4\x13H\xb2MS\xe2\xc8\x1fo\xb8\x87\x19O\xbc\xe5\xbf\x7fH\x82\x08\x14\x84\x00?9\x9f\xa2\xc0gQ&\xf0\x89\xdfjg\x80\xa3\xe0\xfd)q~\xa0\xdeg\x9b\x85\xc5\xb3)q\xce\xe8%\x923\xd9\x15}\n\x19\xc5\xcc#&{ba\xc8\xdb\xedf\xe6\x13\xd1M\x8b\xaf\xcb\xc9S5T \xc7\xec\xc7&\xa2\xc1G!ZR\xb4U\xca\xe6\x9b\x99\xbb;S\xb8(L-\x03\xbb\xfb\xb4m%\xef\xedZ\xd6\xf0\xde\x1e|s\xc1\xd0\xf5\xb9\xf7H\xe5Z\xd6\xdd\xdec\x18%\xcc$|O\x8c\xd1\x8f\x1cu\xcb\xb5\xf7\xb4c\xdb\xec\xed\xb7n\x9b\xbdg]{\xe6\xd1N\xc7\x8ey$Z\xfe:J\x19\xea3\xe7\xd1\x93\xb6\xed4\x81\x95\xf3\ns52\x81u\xf3j\x17\xcd\x12\x83\xf9j\x0f\xcd\x12\xady\xf5\x08\xcd\x12My\xf5\x18\xcd\x12\xc3\xf8\xea \x9a%\x06\xf0\xd5S4K\x0c\xde\xab}tC\x88Q{\xf5\x0c\xcd\x9a@\x97w\xd0<9\x1c\xe8x\xec\xc2xL\xd0\x01y$\x06\xe4]\xbe\xb2\xac\xe8 \xccQ+6\xd9\xdd\x15U\xbce\x19\xada\x0e\x9c\xcb\xb3\x9f\xc0\xd2\x0b\xfegvc\xbb\xd1\xcd\x04\xc99\x03\x90s\x19\xec\xf63\xbbir\xa9\xc0\xfcV0\x1ah\xc8\x97\xde\xe3\xab\n\xb9_\x1b\x8d@\xcf~[\xa3\xb4\x7f|\xabld\xa2\xfc\xe1\x93C\x8d\xcc\xc8\x94\xc8\xb0:\xe3y\xc2W\xc7\x8a@\xab\x07DF\x15d7\xa2;\x82YAy\xc0x\xd5\x06eJ\x9cr\xc6\xee\xc1\xc9\xb6\xd4\x11\xfb\xd7s0>\xcd\xa8t\xf7\xc3\x92\x7f\x1d\x03\xd3\\-\xa0\xbb\xc3R\x1bI/\xb5\xa9\xcf\xda\x81<\xb8]\xf4;\xa0\xee\xc4\x96\xdc\x91%\xb2q&\xd5\xb5\xfd?\x86i\xff\xb7X\xf1\xb1\n\x15\xfd\x7f\x8b\xb8\xe9\xdf\x04O\xb00\xa3\xbft\xf1\x84\x1a\xf1JhCv%\x13\x04\x16\x05\xd5\xba\x97\xd5\xfc\x11\x1b\x1b\xc9\x0d\xc6\xaf\x11\xa74\xcc\xe8\xaf\x1b5\xe5\xd7zS~\xad6\xe5W\xbc)5(\x1c\xa8Ws\xff\x86-%\xc8\x91\x86\xff\xdfj\x19 \xce\xf2\xf1\xa0\xb9\xac\x9eu\xd1\x1b\x88\xac\\\x1f\xe0\xcd\xb1\xbe\xc8x\xfc\x86\xadY\xa8\xe2\x02O b`u\x11\xf8\xe0\xf5KdO\x90\xecJ\x84\x8e\xa9\x8a\x91R\x84\xc0\x80 \xa9\" \xc2\xa9U\xa3y\xd8\xb0\xeb\x85\x8co\x83\xe8O^dta~B\xe0\x82q\xc6\xdf\xf0\xabB{\xd3^\xa9\xb6\xfd\xfe\xf4\xf1uQ\x87\x91F\xa6\x88\xda\xfesl{F\xb5}x\xab\x196\xa7\xaf:3\xf5x\xcfS\xb2U3\xa0\xcfS\xf6*\xb8\x14\x13\xb25\xb9\x8f\xb6\x18\x91c\x1e\xd5\x15\xe6\xc51\xff\xf0\xb7\x87\x87\xdf?\xac\xa6\x0b&\xf9\xe1\xdf_\xfc\xb6\xf5\xdb\xe8\xb7Q-\x0f7\xd4?\xfe\xf1\xe4\xf8\xaf\xa7\x9f\xde^\x1c\x9d\x9d}\xbcxw\xf4\xf6dJ\x1cA\xc7\x8c \xe4\xf0\x08b*\xa79\x1a&\xc3\xf7\x8fU\xee\x19\x97\xb1\xb4\xbb\xf0\x081\xe8i\x9ct%\xe6\xd5^\xc6\xd2LTt\x08\x01f\xd88aqH=&\x10\xaaC\x1c\xb2M\xe8\xb8\xd9~\xb2M\xbe;p\xbe#\xdb$\x13?\x9d??\xf8\xae_@s\x1a}dy\xca\x9a=\xe9\x8a\x80\xa8c\x9b\x16\x16\xec.\xd6\xae\xf6\xce\x8aJ 6QL\x93\x94\xbd\x8e \xf0\xe4dg0\x94\xc1\x7f\x80\x8eo\xf6\xc2\xb6/\xeeY\xa4\xf6\xe4\xf1\xe3\xddI\x17\x92\xab\x0fQ\x11\xc7KL\xf6d\x08=\xdc\x91\x91\"wdH/V\x84\xdb\x12ks\xf4\x88< \xc1s\xc2\xc9\x0bB\xd1\x10_E\x8d\xb9\x19f\x90\x93m\xf2h\xe7\xd9\x93!\xa1\x03Y:\x17\xff\xb6\x0f\xc8\xa3\x01\x89\xc4\x7f7\x13\x7f\xd9X\x0b\xa4\x8f2\x97\x0f\x06d\x1b\xcd \xdbd\xd2\x96\xb9\xdb\x96\xb97@f9#\xffq@\x121\x00\xffa\xc6\xa6&\x8d T\x91\xdaD\x17\xc48lo\xab\xf6c\xcdGq\xa0+?5 _\x88\x1b\xa9\x9f/^\x90\xc9\x93\xfb\xc0G\xe6\xac;\x93\xc7\xe3'\xe3]\xe7\xf6\xb5u\xd8,\xb9\x91\xfb\xe8\xc9`(m\x91p\xdb\xa5I\xdd\x9aG{bx40\x8f\xec}\xa8\xe5\xd9\xc6\xa1\xb7\x04;\x1e)kw\xd6\xa2/'\xe0&\x8a\xfb-\xe3\xce)pV\x85\xd5\xbb\x01\xac7\x1b\xe8O\xd4T\x8a\n\xdcL\x06\x11\x1e\x08\xf4\xc7\xed\xe6\x9e\xcd\x16\xa1\xa1\xb4\x04\xf2\x8c|&N\xfd\xc4u\x1e=rDY\xf1\xeb\xb13\xac\xb8\xf3\xb8\xe7\xf8WbB\xf6,\x83\x9f\xa86\x9d\xe6\x97Y\xc2\x04\xd2\xe3EX\xe0\xdb\x7f9\x1b_\\\xb0\xf4-\xf7\xf3\x90\x81!\xdeP\x86\x87\x8b\x98\x97\x01\xa6\xfe\x90\xf0u \x86BG\x1dm\xb6:p#w\xff\xf1n}\xe5\xf1\"\xeb\xd1\x00e#\x02\xabY\x83\x8a\xf7h4M\x1ejM,\xa7\xa2\xa7MIwL\xc5J_\x12\x1dw\xad\xda_\xae\x93\xefyDU\xad-\x83\x18\xb9u\xfb<\x0eK:r'\xd8\x96\x16\x19{O\x1f\x9b\x18T&=\xc1\xc7\x9a\xfes\xc7Z\x9f;-\x07\x9en\x99\n\x1a\x8d|o\xab\x1fU\x016\"n5\xe8\xdd`@\xb2e\xc2\xafH\xc4\xae\x88@2`\xdc\xe0:\xc74\x8axF\x04oJ(\xf1\x04\xc3IhJh\xf1%\x07\xa1~\x14\x17\x8b\x99\xdd\xaf\x95\x95y\xff\x862\xb3e\x1f\xd9\x9c%,\xf2t\xf3\xc4\x87\xc8\x92\xa6\xd1w\x19\xb9d,\"A\x14d\x01\x0d\x83\x94\xf9dD\xd2\xd3\x05\x1b\x93O)+\xeb\x1b\x83\xb4\xa2xu\x07$\xe3\xf2d\xcc\x96l5&\x1f\x19\xf5\xc9J`m\x9a\x11\x15hu~9^\xb1\x87y\xca\xa4\xa8cT~\xc5\xa9\xdf\x8a\xe1\xa3\x91\xb5-~\x1b]A`\xd0\xcb\x95 \xb8\xe1&\xaf\x80\x0b\x08\x95kn\x04C^r\x1e\xa2\x19\xa2\xb1h\x86\x8c\x94\x8bf\xc9\xa3\x15\xcd\xd2\xce\xc5\xb1\xac\x9b\xd5\xa5\xa5\x114\xc2[\x0d\xfdy?Ge\x8bLK\xdb\x90r\x9a:\xb2\x14\x95\xf2Jk\xc7,\xa5xd\xab\x0fr\xa4\xc7F$\x17\xe2\x01\xe0]\xb8\xa6b\x18kW\xbf(\xff\x1e\xd5\x160\x91r\x83\xb1\x99 \x0e\xec\xa2\xec\x1d\xf0F\x83\xa8o\xa2\x14u\x82\xd14\x0d\x16\x10\x9e\xbb\xaf\xb0\xe79\xc9\xc8\x0bB\x93\x05\x88\x94S%\xe6yN\xb2\xedml\xaf\xe8\xa5^\x14\x98e\x88\xe1t\xf1\x89\x84\x04\x91\xe8\xa1j^y,-i\xfa\xfe*R\x8e&o$-')qqN3\xa9\x1b\x1f\xcd\x92\xf3\x1e\xd7\xdd\x86 9~\xe8\xb4\x8d8Q\x9d\xf2\xccN\xa9Q \xdf\x93=\xd1\x1e\xc95\x01\x8e,\xfb\xbdwN\x0e\xab\xaf\xb8\xfb\xd4\x159 ?p\x1e2\x1a\xa1\xa6\x04\x0b\xa2\x0c\xe3\xe7\xcd\xbc\x1b\x84e\xd3\xe9x\x14n}S@\x0e\x89\xbb#\x0e=5\n\x03)\x81\x88\x9b\x88\x0b<\xa2\x80\x8b\xc0\xe6\xf7\x05\xbd\xe3\x8d\xe3H\xf2z\x1dNb\xdc\x99^u\xcd]Y\x8a\xe6\xd58\x00\xe5\xdb\xbdp\xd4\xeeJ\xcb\xd3\xe8\xcb\x17\xb2%\xe8oZ\xd2\xdf\xba\xce\x12j e$\xf5\xb2\x07\x82\x0d\xa8\xbb\xb2\xd5\x0f: \x95\x11\xbd\x8f1\xa9N\xd1\x1d\x87\xc5\xaf\xe0\xad\x96\x91\xa9\x00\x9a\x83\xe3\xd70\xdf\xa6\xe3\xf3\x96%\x0b\xe6\xdfit\xba$OX9\xb1_/\x8b\x02\xed\xacf\x8b\xf3j\xd2\x85\xa1H\xc1N\x1a\xcb\x08\x1b\xd3\xcd\xa6oKV\xb9*\x07O\xcc\xc8)L\x0b>\x81\x06\xa89}f\x0d\x9bL^\x90\x9e\xe6\x97\xa9\x97\x04\x97\xfd\xe7K\xb5\x1d\x97\xa9\x89\xc6\xe4Q\xaa+\xed\xd3\x86,\xb9)\x1a\xd1\xb7\x0d+p\xbeQ\xffZ9\x1ef\xe2\x81q\x1f8.\x92%\xdc\x92F~\xa8\xa8\xe2\xf1e\x10\xf9\x90<\x18\x0cI#\xdbE\xfc\x8c\x10\xb47\x9f*\x1f\xef\xd5\x9f^=qu\xb3\xaa\xbd\x13\xecd\xaf\xa6\x15\x92\x83\x97\x81\xff\x96\xe7Q\xe7]\xab~\xe0\xa3\xe64\xb9\x9b}\xef\xe7 \x0c?2\x8f\x05k\x84\x93h\xfb\xf0U\xcbN\x90[\x0c\xdc\xc3\xa8\xb9j\xf2@M\x7f\xe5\xfaik\xea\xa7hu\x9b\xd1\xf9\x84\xcc\x94)\xb3\xe8\xd5\x8e\x02~\xa3\xaf\xd7\xb17h\xa5\xd7\xcf\xc2jz\x15c\x18\x19\xb6q,\xb2\x9b\xecd5\x7fm\x9c\xf7?0\x16}H\x98GC\x0f\\\x19\xf9\xca[\x7f\xadi\x06H\xc0#\x10\xa3T\x1b%o\xe6\x99\xaf\xb4\xd4\xab\x99v\xa2\x0b\x01\xaa\xf1%\x0d-|\xfd\xd4&\xc6\xc4\x04}\xa7\x06\x14\x1fk\xfb\xb5\xcf\xa1VCY}\xf9[\x02:\xb9\x07\xc6\xd8\x8eK\xe9Z\xfb\xd9\x07\xec\x8b\x14'\x00\xd1\xd9\xd9L]\xe8\xaa\xc4\xc3m\x1c]\x9f\xea\x08&\xcd\xef\xa2\xf2\xebO\x96\xdcl\x00M\xcc\xab \x1a\xc7\xe1\x8dk\x11\xe2`\xcfW\xe2\xd1vo\xc6\xb6G}s9\x06y\x9a<\xb0\x97\xbdk\xb0\xcb\xb3\xccGQ+6r^\xee\x8a\x0e\x8aI?\xb0<\n\xe7\x9a\xfd\xcaDp\xd3\xb5\xc4\xc8o|\xb7\xab\xd1\x18\xf4\xc7#\xedb?\xd2k\xa8z\xe1\xb4T\xef\xc0~\xd3l\xca\xb4q\n\xc8|\xbe\xb6\xaf\xb8\x16\xe9e\x1f\xbc\xb5`\x99\xb4\xb7\xf2\xb5zu_\xec\xa59\x8c\xea\x15\xc7\xf5\x908g\x9cP\xcfci\n\x97\x12W\xb2\xfa\xe2\xf6kHnxN\"\xc6|\x92q\x88\xe0\x1f\xcco\xc8\x1fD]kNI\x96\xe4\x8c|%T\x16\x9f\xf3<\xc9\x96\xc5\xe50\x01\"\x12\xeeF\xe0~q\x00\xf7HcgP\x1c\x04\xf3t|U\xedQ\x9fq\xe8\xa7\xda\xa5\x1f}\xcdi;\x10\xdb\x11qT\x96l\xae\xab\xf6\xa2\x81\xf9\xd1\x96\xe5\xdf^\x0b\xad\x9c\x02\xb6=\xd7^G\xae\xeb\xa8\x1d\xbd\xf6\xdd_\x1cw\x16\nb\xd2AAL\xfa\xef\xfc\xcd(\x08\xaa\xefih\xbb`-\x95{\xbeuX\xc2\x8e0Hp \xe6\x80\xf5R\xad, /e\xba\xce\xc8!\xd4m\xc2\xb6\n\x88:\x84\x84\x1e\x12\x1d\xb1\xfe\xccU\xb4D[~@\x0ee=;dJ\x803u=\xbd*l\xe7\x8a+x\xa7\x10`\xe7UXT\x82\xe2\xb6]\xc5\x16L\xf2\xd6\x96\xeb\x81\xd6\x07\x8c\xe6\xa0\x18\"\xab\xe8\xc1\x95\xbcqN\x0eIN\xa6jY6i\xc8k\xa5\xf9\xc1\xd5\xf5\x99\xca\x01\x1e#q\xff\xf8\xda$\x95\xbb\xee\xd3d\xe0\xe9\x1a~\xc2#`\x10\xc0\xfd\x03\xd1\x88TX\xc7j\xc5\xd5U\xb4l\xac^um^\xb5\xdf\xaf\x16Z\x93\x03\xe5!\xe0~\xb4\x1e\x87v\xa5\xbez'\xc1K\x90ti[\xdcR\xd5\x8f8\xcd\x98U-\xea\x9a\xc7KR\x83\xa9#\x19\xb0>\xd4\x1a\x83\x82\xd3L\xd4K\xf9\xe5\xda\x81T\xa8G\xf2\xb2j\x9bj\xa44\xbf\xddyN\x02\xf2\x82D\x85zf\xb0\xbd\xdd\xc4\x91\xc0\xd3p\xa5\x194$\xd1,8\x07a\x12\x9b\x89\x9f\xe7\xf2\xeeE\xfe\xb6\xb6\xad\x18\xac\xda\x0e\xf9\xb6Sh\xd9\xe7\x05\x00\xca0\x1b\xd4|\x02\x82\xce#\x00\x06\xdb\x7f\x9e\xa4\xf2\xbc\xe9\x89&\x957\xc2\xa7J\xb4\xd6\xd1[(QV\xd0J\x83\xe3#C\x0c\xb9\x08\x8e\x04\x1a\xd6\nv5\x12\xaf\x17\x94\x1aw8v[\xa0\xcaS\xd2\x0e\xb4`\xd9\xcb^\xb5\x01`\x12\xac\x99\x0fd\xd5\xab\x84\xaf:J\xac\x82\xeb j\xc9/\xceS;H\x06\x8a\xdf\x08+\x8dh\xe7f\xd6\xf1\x8fZG@\xee\xc3\xd6f\xca\xed\xdc2k4\x0c\xc1\x05E[~K\xf9B\xf7\xb8\x0d$\xc8n\xfa\x0e\x85\x81\x0b}6\x0f\"V\xa0\xa0\xe6\xce+A\x17,3\xb0\x15\xc4\\k\xc2s\x1b\xfc)\x98 %\x02[\x89\x97,\xf5\x92 \xce0^\x8fV\n\x19\xdaMMPA\xcaPAEP\xa5'\x85[\xe9\x17\xb4H\xea\x86C\xe2\x0d\xc9\x1cCD\xa0['\x0d-L\xcd:\xcf\xc6\x8e\x0bx\xd4\x0eG?\x023\xc4`g\xeb\xb5\xf0\x12\xb1h\x7f\x0cX\x1d\xb83hc,\xda\x88\x16\xc1e+\xe2S>\xb8\xf8\xb0}\x8a\x13\x1d\x1d\xd8\x17\x84\xb1G3\x97\xbb\xde\xc0\xc6\xe5\x14\x87\xdbR\x9e[K\xf2\x82\xf8\xc5\xb9\xb5\xbd\xbd\xec\xea\xb8 \x1b\xfc\xd9\x121+\xd0\x8fRN\x9e\xad\xc1a]\xa6\xfe\xcfE;\xe7\xb3\xf5\xb9\xd5o\xbd~\xc4WV`\x1f\xee\x0d\xc9\xbaC`\xd8O\xfc\x1a\x89\xb1_\x0f\xc9\xaaC\xf2e\xcaW7\x16\x83\xa1\xa9j\xa56%\xfeMp\x14\xd48\x12\xab\xde\x97\x12\xb7\xd7Y\xd8\xed\x81\xa2^\x1aL\xd1\xf8\x90\x04\xb8A\x9a\xd6\xdcn\x0e:\x084\x9a\xb3%\n\x18\x96\x08\xd9@\xc6\xbaeWD)\xaf\xbe\x0d\"\xf0fH\xd8\xb5\xc7b\xd8\xcf\xdc\xf3\xf2$a\xfes\"\x9a\x9f-\x19\x89x4Zi@\x9f\xad \x8b\xd6A\xc2#\xe0\xab\xc5\xa2\x06\xc9^\x1e\x86\x04\x82\x9a\x92\x15KS\xba`\x84F>\xa1\xbe\x0f\x11OhH\x96,\x8c\xe7yH\xaeh\x12\x05\xd1\"\x1dc\xda\xe2,L\x99eQ\x89>\n\xcehV\x1f\xa6s\xbb\xe0\xc3\x83\x9d\x86f\xbb\xd5\xa1\xc8\n\xbf<\x0f\xff#}\xb8\x18\xf6\x13\x1d\xeau3\xf3\xb6\xb7\x9b\x01\x1c\x88d\xfa\x07\xd2\xee\xe1\x808\xaf\xa35M\x02\x1ae\xe4\xa7\x80K\xe1\x15b\x00\xd1H\x91\xf2\xact\xd2\xec\xcc\x1f_\xf1\x1d\x828Hi\x02\xea\xd5\x87\x89\xd0\xa4#\xa8l\xd8A\x95\x13C}L\xbaE\x91\xf6\xd1!\\k\x83<\xb04\xaf\x9a\x0c\x86\x98\x8d\xff`Hr\xd1QO0d\xa0h,\xc5o\xa2\x7f\xdc\x8d\x86\xe4\xe9\x90\xa4\xd8\x01T\x1c>s\xe3;\xcf\xc9|4z> \x01\xa8\xfc\xcd\xe6\xe7-R\xa2\xeaR\xb3\x99\xdd\xa2\x0b\xcf\x1c\x8c\xde\xbe\xe5\x8a\x06\x8b\xae\x8d&C\xa2E\xbc0U\xe4\x90\xec\x80Nvy|F\xe4\x05I\xe0\x86R\xe9\xd2\xb9l\x16\x9dK.~\xf0\x1c\xa7b\xea1V{o\x99\xc6\x9a\x96;\xe6\xc9\xa3.{d\xac\xab\xa6\xec\x06\xd6\x11w\xb3AE\x90u?\xad\xdb{\xba\xffo\xd1\xbcF\x88t\xd9\xbcI#\x02\xbbB7O\xea\x88\x82vK\x07\xba\xfa\x89\x9e\xad\x89\xcb\xca \x8eA\xc3\xb7\x91\xbe(\xe2\xa84D\xac\xd3\xd9\xb9E\x9e\x91\x835\xd0\xc0u\x0c\x1b\x0c\xa0\x88sP\xe0\x83\x8b\x00*\xe5\x13L\x9c\xfc \xd1\x8e\xc6q\x9e.\xdd\x1c_\xbb]\x06\xb4\xdd\xbb\xae>\x06\xba\x7f\xf5^\x14Hr\xeb\xa0.]%\xd5\x9d\x1aDj^` 3\xd9\xfe\xba\xaa\x9e\xc6\x81\x9b-\x9f\x8e\x88\xdb\xdaM\x1321\x1c\xe2j+c\xb3\x83\xaay\x8f\x8c\xebdx\x95\x14i8\xd3\x05\xd4>R\x8f\x14\xb9B=\xacR\x0ff%N\x943\x81\xa0\x9c\x90\x03Q\xf5!I\xc6?\xe4\xf39K\xc8T\x99}\xdaX\xb3CB\xc74\x0c\xb9\xf7)J\xe9\x9c\x15\xf0\xd5A\xee\xbd\xbb \xa9;\xed\xd21\xca\x91\xc3`]h\xa4+e\xe4\x06\x04QL0\xdc\xc6\xb8\x11h\"\xb3+\x02z\xdez\xe1\xa3\xba\xe3\xc5\xc7=\x1e\xdf\xb8\xc9`h\xf52\xf7uP\n\xf2\xdc\xc9\xde\xa3A\xe1\xeek\xf3-\x80\x0c\x88q\xe64\x1bi\xf4\x1d\xd9\xe9\x99TP#\x07\xe4(I\xa8\xe8\xc5\xa08\x99\x9e\x0fH6\x8b\xce!0|t~\x1f;\xa2\x13\xdfO\xf6\xefr\x1c%\"\x13P\x9d)+\xbc\x9f\x96\xed=\xedt\xdcqO-\xab7+\xba\xff\xa3C\xa3M\xfb\xa6H\x14\xabQ\xdd\x05\x16\xc9\x8a4\x82\xd5B\x13\x03\xcf\xccv\xce\xe5\xa9\xa0\x8f '\x88|v\xedH\xcd\xe0d\x0co\xd0\x0e\xf85$\")\xce3\x95\x14\xe7YeSm8\x93\xbb\xbb8\x93\xb0\xff\xb4N\xae\xabS\xfb)\xee\xdap\xff\xe9\x1e\xca%\xec?\xad\x9f\xf2b\xd4\x9d\x99D\xb8\xdaQ\xc0\xb9\xd3d\x19\n\x98\x974cu\x00\xcf\x04xK\xe3z\xfe\xdc\xcc\x7f\x07\x8eD\xea \xb1 \xf2\x91-N\xae\x1b\xb5\xf8&\xc8)\xcb\xea\xf9\xcbJ>Lm\x1dd]\x01\x01\xe9_\x1dde\x82\x00\x86\x91GF\x1dnQ\x1b\x14\xfaS\xc0\xae\xea@7&\xd0\xab\x90\xd3lo\x17\xea\xac\x03^6\x00\x9f\x01\xd4\xb1\xbbA\x1d\xe2\xef\xc4Z\xd3\xde\xc65\x89\xbf\xbb\xbd\xbc\xe7j+a1\xd6\xb7]\xa9\xfb\xb6\x1b\x90G\xf8R\x9d<\xc3tk\x04\x1b\xdbzH\x90\x9aL\xcd\xc9\xb8\x143;-\x91\x0c*^\xf5\x9aHH<}<\xfb)\x83\x07\xc1~\xe0\x00\xa6\xbb\xbf\x06@\xcd\"V\xb0i\x01\xbe\xf3\xf0\x18`\xdd\xbb\xc5\xb2O[93\xbd\x04,\xab\xa4{\xe3j\xd6h\x7f\xa76\xb2bYL\x9e4\x97\xc4K\x9a\xb1q\xc4\xaf6\xc5:\x9a\xdeA&0hj\xbf\xf5\xe9\xfbZ;\x02\xb5\xf9 \xc8\x01{\x8e\x88K\xc9\x08\xf5O+\x98L\x88\x86#\x0e\xa7\xef\xc9\x0e\xf6\x15\x0d\xb7\xbd\x9d\x91\xef\x0fHapnx\x8e\xdei\xaa\xd4}\x95\x1a\x82\x19\xae\xd7W\xdb\xb8\x9a\xcd,j\xbc'\x89\xe1\xe4\x11.\xe3hluEn?\xc3\xc9\xed\x06S\x9a\x93\x03T\x0d&\x85\xf4\x86\x16L\xd8}\x95Y-\xe0\x011\xde\x89G@ \xdb\xcd\xe0\xf0\x92\xb1\xbb\x80\xc6L\x95\xd6Os\xd8\xc5\x94\xa0\xf3[\xd5\x0c\xc9\x06$,\xf1\xb1\xe6|\x80D\xcafQ\x1d#[\xa8+o\xb3\xa9\xda\x7f\x86\xc7\x93\xd8\xdb\xe9\xbe\x1a\xb7R\xbc\x05\x08v\n\x13\xe3\xfb\x18iG\xf4\xbahU\xa1\x90\xfc\xaf$\xbf\xa2YPeL\xec\xbbR\x14\xd9\x85\"\xbb\xe7\x16\xc5\x10\xa2\xe7\x85\x1aW\xd6\xda\x9f;\xea\xe6Ip\xdan0\x1a\x81mu\xd1\x06\xa9Y\xcf]\xf3`\xcd\xe5U\xb4l\xfc\x0b\xb2g2\x06T\xdak\x81^c\xb1p\x05\x95A\xb6\xb7\x13\x08\x16h\xc3\x12\x9aP\x8ef\x89E\xf5\x1d\xcc\x95\x81\xdcNe4\x8f\xa6\x92\x92U\xb8V\x0bip\xeb\x83\xbeyp\xab\x95fa\xc2\xf7\xf6m\x11\xe5\xfap\x83\x81\xab\x83='bS\x92m\xe28\x1b6\xbd+\x12\xcb\xfe3\x1c\xcb\xed?{j \x1bWo+\xd8/\x03j\xf2xH\xaa\x8e\x8aB\x9a.e(\x882\x91\xe6\xd9\xb2\x9a\xb2\xe4i\xcd\xfd\x8f\x18\xa4&\x8cR\xb0\xae86Jku\xa5\x8c&^-\xed\x1f9Knj\x1f\xa0\xd9\xb2Y\x9dH\xad} asRs)T.\xb2l\x0c!P\xc9\x01\xb9\x1c\x92l\x9c\xb0\x94\x87\xebN\x97\xaejr\xc1\xc7\xdd\xd6\x04\xfc\xba\xe9\xa2\xa6\xaf\x9a\xafF\x95r\x1f\xf5\xac\x98\x91C\xb4\xf2b3V<\xac\xc3g\xe6\x0eRIl*y\x16H}.\xad\xd7D\x15\xdf\xf9\x01D\xe0\x96_\x81\x18\xcb\xa6\x1f\x0f\x99\xac\xafZ\xaa\x0d\xfb\x94\x88%\x15TW.\x85\xd0\xc1\xee\x8c\x8e~\xdf\x19=\x1bo\x8f\xce\xb7\xa7\x83\x87A\xf3\x98}8\x9d\xed\x8c\x9e\x9d\xff\xe5\xcf\x0f\x9bG\xed\xc3\xbf\xbb\xbf=\xfc\xed\xe1\xa1{\xb8\xf5\xdb\xc3\xc1\xec\xef\xbf\x1d\xfe\x96\x9e\xffe\xe0\xfev8\xfb;\xfc:\xac\x97\x02\xb3\x04\xe7\x0fgH\x9c\xaf\xe2\xcf\x17\xf1\xe7\xb7\xdf\xc4\xdf\xbf\x8b?\xff\xe5\x9ck\x03\xa1\x99\xf3B\xa4|\xef\x0c\xc9w\xcew\x90\x07q\x80E\x81\x04\xfeF\xf07s\xce\x07\xcd\xd3{\xe6|WV\x15\xd6\x00\xe6\x00\xf0\x1f\xa2\xf8C\xf1\xe7P\xfcy.\xfe\xfc\xaf\xb2\x90W+\x14C\xa1\x12\xfe\x7f95s\n\x1fFd\xb6-\x87\xf4h\xf4\xb7\x8b\xd1\xf9\x1f;\xc3'{_\xeb\xa3\xb0T\x83\x8f\x80\x0e\xdc\xf1_\x06u\xf85ja\xf8\xdftM\xa5!\x1b\xce\x958\x06\x80\xd3\xe0(j\xd6{\xabo\xff\x89\x05\xfa \x88\xcb\x84V.r,\x86\x89s[\x99\x05\x8f\x976\x83\xc8y`\xe3\xdf\x1ch\x84\xd3\x92\x99Zs\xe7-%Uk\xacEE\x83:\x87\xedF\x9d%\xfb\xe8Yri\x93q\xfc\xff\xec\xbd\xeb~\xdbF\x928\xfa}\x9e\xa2\x84\xec8@\x08R\xa4\xe4+mZ\xeb\xc8\xcaF3\x89\xedc\xd93\xbb\x87V\xf4\x87\xc8&\x89\x18\x048\x00\xa8K\xc6\xdeg9\xcfr\x9e\xec\xff\xeb\xaa\xeeF\x03\xe8\x06@\xdb\xc9dv\x07\x1fl\x11\xe8{\xd7\xbd\xab\xab\xe8\xfa:\x17<\x06a\xa6\\\x8d\xc9\xbc\xa2S\x95\xa6\xe4\xb5\xd2\x1b/4R\xa7\x94(\xb7\x1a@\xdde\x0e\xc7\xa1Q)I\xe9\xdb\xec3\xe2\x12\xbaF,-)\x05^\x05i\xb0f9K\xe1\xebm\x1a}M\x19\x05.\x19\x04\"gU-\x81\x80\xc9Q=,<\x01_.\\\xe7\xc81(s[\x94Q\x8b\x14g\\h\xd3\xea|\xe5xp\xc4\xe9\x02\x8c9a\xa8\xd7\x8f(S\xc6&\n\xf3\x9a\x97z4\x1d\x9e\xc3\x04\xff+\xaeV\xbd{\xb7\xbfD\xf2d\x18\xf0%\xa6\xfb\x99@4\xf89 \xe3Z{|\xf5x\x91\xcbA\x9e\x86k\xd7\xf3a\x0fS\x8d\xcb\xb4\xc54\n>\xe6\x06\xf3\x17\xef\xe7\x02&\x90\x91#\xc3\xa5Ew\xbd(\x07\xf0\x16\xcc\xff\xb2\xcc\xf9/\xeb\x02\xc3\x05J\xc1\x17\\\xf8>\x92\x81\xd0\xa4\xd4\xc1\xdfV\xa4\x8e\x1c\x8e\xe0V\x80\x9bV\x18\xc3\x96\xe6\xa9;\xf2T\x10n\xe3\x07(\xa2\xad\xc9N\x1c\xa7\xd2\xc5\xdf?\x8a82e\\\xac-\xfe5\xd7\xd6\xcd\x8b\x82\x91\xffl\x8by\x02\x13py\xe5\xeb\xe9\xf0\xdc\x1b\xe4\xc9\x0f\xc95K\x8f\x83\xcc\xe8>^\x15\x08O|\xa0-\x15\x13\xbb\xaey\x1f@m\xb4x\x19\x81\xab\xa6\x18\xc1\xf0r\xb0\xc6H\xea\xfb?q\x96=\xfd\xe9\xdf\xdf\xed\x9f\xf7\xfe]\xfc\xbfo\xbc\xef\xca\x87\x8dn\x83\xfb\xfb\x0e\xc2\x8e\xea~\xe8\xc3\x81a\xd4{7\xd4\xdd\x9d;\xb0\x9e^\xe3\x8dZ\xb74\xec\x03\xaf&\xd5V#\x91\xd6\xe7\xb0\x87m\xf1-,\x9a\xdf[N\xaf\xcd\x97t\x95&}\xe6\xc3\xb1\x8f\x9e\x87\xfd\x91\x8f\xde\x82\xc3\xc7\xf0\x0c\x9e\xc0F]\x85zfNP\xc6\x1f\x81\xec\xeeK\x1c\xbeD\xf4\xcd\xf4\xd9\xb9\x88/\xdc'tz\xcf\x87\xf4\x12\x9e\xc0{z\xcd\xfb{iP\xaa\xb8^J-\x1e\x13)\xa1\xcaGpY8\xffpJ\xf2\xef\x98\xa9\xbb\xf6\xd2\x87\xf7\xa2\xdf3ZO\xbcw0\xf4\xe1\xd8S\x90\x81\xaf\x8e1\xa1}YM\x98\xb3Y2go_\x9f\xaa E\xee\x99\xe7\xc9\xb5\xb1(\xbd\xda\x82-\xba,\x18_\xf2\x97\x8f\x8bi\x96\x17n\xf1y\x0bG\x15d\xb1K \xfce\xddG[\x95\xf7\x95Uy\xef)\x12\x94f\xec\xfb$\xcb]\xaf\xae\x14\x95\x7f\x7f\xf8\x00\x8e%\xb3\xd6+<\xd7&\x9c(U\x12\x8e\xe7\xce\xb9\xe9[\xe9\x974'\xf4adP\xd5\x11\xec_\x99\xef\x81+\x00\x7fS\x1d\xb2\xa0\xec\xfb\xef\x06\xfb\x9e\x0f?r\x82\x83\xbb\xe8\xc3\x1b\xb9b\xb4\xa1?6\xee$\x88Y\x9e\xc2\x04\xdeL\x9f\xb5\\\xa2?Et<\x15\xd4e\xdezq^\x0d\xffgA\x85_\xd0\x10_\xc3\x04N\x15\xa0\xbd\x80'\xf0\xfa1\xbc\xe0\xa3<\x1d\xccVAz\x9c\xcc\xd9\xb3\xdc}\xe1\xc1S\x18\x1d<\x80#\xf8\x19z\x13pn8\xcf\xc5?O\xa7/\x1a\xc6\nrY\x7f\xee\x97\x8b~ \x19\xc2\x198\x1e\xf4\xe0\xd2\x80\x15\xcf\x8b\x12\xedc\xb9LY\xf0\xbe\xb1T\xdd\xbc\xd4\xfc\xa5\xfe\xd6\x88GO\xe1\xe0\xde=\x99\xeeA\x1b\xbd\xe3H\xc9\xc0\x86\xe8eV\xec\xc3+-vvQ%\x1d\xe4\xc9\xb3\xb3\xe3\xd3\xd3\xf2\x17\xd3\x05b\x0e2\x7f\x93\xbd\xa0\x15\xe6\x08\x9c1\n\xa1\xea\xcd\x98\x83\xbeq\xbe\xdfu%D:\xe9\xfb\x0ez\xf07]\xe8\xeai\x8d\xf0))\x01\xc8\xba\nRb\xf2\xcd\xeb\xdb\x07\xce\xbb9\xccp\xea~)\x08\x9d\x06H\x97^+\x1f\xbf\x9a\x9e\x9c[.E\n:\xc5i\xd6\xac\xe06\xad\xa4\x8a/\xf5/\xbc\x8e\x95L\xf1\x8e\x05//\xb8\xd1/\x8d\xa8\xcf\x1b\xfd\x96\x8b\xd8q\x8dm\xfe\xd2\x80\x02\xdf\"\xc9\xff\x05\x97\x05\xabg\xb3`\xc3x_\x8a\x17!y\xfe\xc5#\x84\xfa\xd6L\xde\xeb\xf0^\x97A\xffR\xe2\xad\\\x92/\x18\xef_\xb4\xbd&\xcb\x9e\x92\xbe\xfeR\xe1\x8aC\x1f\xfeR\x05`\xde\xfc\xf7\xe5\xe6\x8f\xaa\x88\xaf\xad\xe9\xf7u\xf1]u\xf7\xbdW\x11\xb1\x8b/RH)\xc6*\xcb\x94\xa4||\xe9\xd5G\xfd\xfd\x8eb\xfdeQR\xd3A8\xb1[NO\x10\x90\xcb\xb8\xa1\x82w\xab\xd2\xa6\xfa\\9\xabj62\xbb\x18\x0d\xc8\x04e\x05e\xd0\xea\xd8\x04\x8d\xbf\xaa\x88\xb54\xc1&R t\xaf\xbfA\x0f\xfe\xda\x80\x89\xba\xba&\xf43\xfc[\x1a\x16+JP%^p\xdd\xc8i:eU\xd4\x05\x05P\xc3\xa0\x992~\xe2?\x06Lc\x9e\xa7\xc5\x199|\xb6\x1f\xfa\x9c\x88\x92 \x7f\x02\\N\xae\x03\xae\x8aM\xac4'\xec\xbbNhc\xf3&\xd4\x0b\xa6Z\xcc\xe2\x95\xadPh *\x1b @\x96\x87YP\xed#2\xcb\xdd!\xf5\x14+\xe6\x18#\xc1*\x9c\xd1\xb0.\x86\xe0p\xberD\xc0\xc7r]\x0ex\xfc[\x0f\x8f\xad\xb6r\xe2\x18\xa8\xabR\x94/\x14-\xca\x16ij\x0fB>Ht7/phz\xf4\xd5y)ZOSLQ#B\x96\x89\x8a\xc7\xe5E\xec{\xab:q\xber|p\xfexp\xe8\xe0\xd7\xd4FEL\x87<\x96\x83\x18\xdc\xa2\xf2\xe1\x8b~.\xe3)\xba\xd5\xd2\x97\xe1\xf4\xc7du\xac\x18\x1d\xcd6\x91\xdcl\x16\x85\xe24K\x1b\xa1O\xd4\xb0\x81\"\x97\xe2\xb7`\xbb\x14\xc2\xa5\x8aQ\x9e\x8f\x14e\xf8\x18\x02x\xa2\"\x84>\x86\xc0\x9ef\x1d\xfdO\xa6\x81\xc9\x83q\xba=\x17\x086\xdd\x9e7\x8c\x8eB\x93\nQ\x02\xbd&V>\x97\xaa\xc9\x96\xc89H\x11\x0cH\x1d\xf5i\xdc$\xae\xcb\x0eL\xe1\x1c\x85\x82\x90\xd4\xba\xd1\x9c\x93\xd5\xc3\xac\xa2Uu\xf8\x18\"x\x02E\xd6\xf9\xa8Y\\\x9c\xc1\x04\xb2id\x11\x17\x1d9\x16B\xb5\x19\xe1\xf1tF\xd1\x08f\x06\xf1\xd5z\\\xbe\x9c\xc6jf\xe2:zI\xc0\x88\xcb\xd2E\xacNN\xeb2\x86ya[6\xadXW@g_\xf5\x8bHU\xd3\xa2\xa3\xb4\xbe\x9c\x16u\xcem+Z\n\x96T\xdd\x9e\x0dm\xcf\xa6dB\xda\xb4\x1b\x1e0\x04\xf1t\xd3\xa0\xcc\xc7\xd39\xed\xc8\xdc\x12K\xcc\xf8\xb6\x11L;l,\xa1\x82f\x95-\x16\xc8\xe7\xb8\xc09\xf8\x87\x0f\xb0./\\i?\x99\xfaQ\x9f\\CD\xb7R@D\x97U\xc4\x16O\x9a\xf4\xf7\xb9\"\xb0\xd2X\xee\x9e\xcb\xa4\x8a\xb8\x1a\x90=\xc0\xabEx\x92O1\x83\xa2\x162*V\xd2E]V\xd6\xaf=$\x07\x1c\xa8VB+\\)\xe3\x03~]\xe9\xfe\xf8\xf5\xcf\xa5\xf5Y c\xc3\xbe!\xdf\xbbmC\x94\xf0\xcf\xc4\x9f\xbcM)\xff3\xfa\xcb\x17\xd8G4LL\x93+\x0b\xb14\x922\xfc\xc3\xd7\xb1tR\x999\x13\xeat,}+\x18\xfeQ\x9a\xc2\x87\x0f\x107H\xff @\xfc\xaa\x8c\xe8\x16\xc1R>x\x04\xd8\xa2\x03\xf0G\xd1\x90+\xe8\xc1m\x87\x05T\x18\xa1y\x99\xe8\x02\x91\xa2\xd4\x9f@\x83\xe4IU\x99\xce9\xe2(\xa1x[H3\xf5\x05\xb8(\xed\x173\xb6\xc4:\xb5t\x0d\x13\xb8\xe0\x8d\\\xd2\x16a\x9bD\x17E\xedz\x9d\x13\x98\xc0u\xfd\xf5MmR\xdad\nL\xe4\xfdL\x0d\x11\x17\xcf8\n\xafJ\xb4\xa0<\x90z\x1b\x1a\xb9\x06:\xfc\xd0X\x8bA9?\x13\x1c\xa5\x84\xa7\x1a\xdc\x92sN\xb1\x08\xae\xe0\xe77\x1c\x81\x8f\xe8\xbf\x89\xfc>\x86\x1b\x85\xb0\xf4\xca\xf34t\xe2\x0d\x97YM\x99@P_\xac\xdc5\xabu\xbd\xa2\xaeW\xd45\x93]\x17\xb4\x82\xa9\xae\x15q\xc2\x0c\x7f>n\xedu\xad-D\x135+^\xef\xc23\x13\x01)\xca\x90R\xa6\xba\x8e\x15\xb6[ B\xa9.\xbe<\xd2\x7f\x8c\xb5\xba>t%T\x1c\xbc*WY\x903\xf0\x8d]\xa9\x13[<\nso\xe8*\x8b\x0f7\x83M\xb2\xe1\x18\xc9\xdf\xdcH\x17\x96\x95\xd7\xb5[K\x7fx\x08\xffb\x1bE/\xd3\xb71Et\x9e\xbb\xb2\x19\xa3|\x8c\xe0\xe7\x95\x17M\xad\xfa\x8d\xe4A>\xb8\xaf\xb8\xd2\xbc\xe7\x16@H\x7f\x15\n\xed\xbf;\x1eyD\x17\xdf\x04b\xfc\xbb#\x8e\x92\x14\xf1~U4\xac:+\x0d\xe1U\xc1\xfd\x1a\x88`\x87\x85\xf2A.\x89[`=\x8eF{/\xe9?\xdf\"E\x93\xb5\xf2p\xa4\x13\x901g\xa2\xa8\xb1\xc9\x11\x1c\x15\x83\xc1\x8f\x9f*\x02\xee\xdd(xQ\x93\xdcT\xbd\xf6J\xbd\x8a\xb1\n\xad\xb5\x18D!\x9dJ\xd2\xd1*\xe9+\x99\xe5\x98v\x1e\x8dw\xfd\x91\x87^\xb0\xefiA\n\xca.\xff\xba)\x0c\xfaB_w\x06\x84e\xc7\x88q\x03\xf9\xcb\xd3\x10\xf0X\x9c\xef\xfa\xf0\x12\xfb\x92\xb2\xe6Kx\x8a\x12\xe8\xcb~\xdf\x03\xd9\x0e\x1e\xc0\xdeL_\x9e{\x9c\xd4!L\xcd\x98\xfbR\xdc\x7f+:\xe0J\x7f\xf9\xb3O\xa6\xe81<\xc3\x81\xd5>\xf6\xfb\x06Z\xbcG\xe7\xd5'\x16\xc3\xf7c^\xed1<\xf34*\xcb\xc7Pi\x89\xb2\x10\xead\x9a\xaf\x95\xb8\xfb\xf0\xf0\xfe\xdd\x07fM\x8ck\xfc\x87\xf7\xcd\xdff\x18f\xdc\xf8\x89\x83\xf9\x81\xa5\xda\x867\xf9\xd0\xfcm\x0e\x13xP\xbd\x13'\x1f\x8ez\x0f\x0e\xcc\xdf\xb8n9:\xb0\xb4\x8a\x91\xf1\xfa\x16]s\x89~\xc97q\xbf\xbfo.\xc0\x05\xa1\xfd\xe9O\xefn\x0e\x86\xfdw7\x0fN\xce-\xe5.\xb1\xdc\xbb\x9b\x83\x93w\xdb\xc3\xe1\xf0\xe0\xdd\xf6\xbb\xef\x86'\xfc\xdf\xfb\xa3\xf3\xfd\xa5\xb9\xd2\x855\x8f\n\x7f\x92+\x96.\xa2\xe4z\x0c\xceK\xf5'Em\x8c\x19\x9bgp\x1d\xceY\na\x9c\xb3%K3\xc8\x13\xd8\xa4\xc9\x8ceY\x83b\xed\xc4I\xde\xbf\x0c\xb2p\xe6\x8c\xc19\x8d\"\xb6\x0c\"\xd1*\x17\x1dn\x1e\x0e\xc1\x8d\x93\x1c\x02\xc0R\x80h\xb4I\xc28\xf7\x9a\x9a\x0d\xe3\xab \n\xe7}l \x9b\xa6\x17\xd4\xb49\xf1\x9d!\x9d\n\x08\xc55\x82>\xcc\xcc\x9f\xb9\x8e\xfac\x90\xaf\x06\x8b(\xb1\xe5\xae\xe4:\x01\x19\xb5\x07\x8b4Y\x1f\x0bo\x1a\xcd\x9dX>\xca\xad\xf8\xcc|<\x00*\xc6\xfe\xeb ^\n/\xdc\x8b)3\xdaE\xed\xad\x1f[o\xd4A\xd5\x1e\xaeB\x85\xa2I|z\xfe\x18b\x0c\xc4\x9eR\x84X\n]n1hI?\xe5\x9d\xc6\xf6\xbeql\xc5\xb0\n\x89\xc2\x0e\x07\xa9\xe1\x00P}\x93\x02y!\xef\x82<\xf8\x89\xb98\xd5\x03\xf4\xfbC\xceON=)\xf4\xe0\xd8\xa5\x13Su\xe6r\xe9s\xc9\xd6S6@\xca \xeb\x15N;;\xcd\xfe\x99}\xdf\xd5\xb6P\xac\x06\xda\x0e\x1f\xaf:\x0d}\xe1D-\x05\xef\x84\xae\xa9\xb9\xa4jk\xee[I\xaf\xe7y\x1c\xb5\xee\xdd;xt\x9f8\xc7\x93 \xdc\xbb\x7f8z\x84R\x0b\xaf\x08G\xfc\xc5\xc1\x10\xe3\xa2\xdc\xbf{ot\x00\xe24\xad\xde\x96G\x01\xce\xb8\xbc\xea\xba\xa3\xe1\xc1!\xdc\xe1\xbb\xf7\xe4 \x8c\x86(\xc5\x88w1\xffq\xff\xde\xbd\xc3\xfb(X\x89*9\x17\xa0\xb8r0\x06\xf5\xe6\x0b\xc2\xd2K\xfbj\x8a\xf6\x10\x13\x9a\x8f\xe4\xe4#O\x9el\x00\x05\xfa\xbd\xa1\xa78\xd7{\xa0\x0e}\n\xa3!\xdc\x01\\\x9e\x0f\xb4\x1dB\xa0\xa1\xb5\xff\x00b\xe5\x18\x1d*\xf2&\x0c!\xcd\x01\xcf\x02\x05\xb4\xed\x08l\xaf\x1aQM\xcd\xa5\x07\x07\x07\xd0\x83\x07\xf7\xe0\x1bp\x19<\x81\x83\xfb\x1e\xf4\xc1u\x87\x18\xcd\x0c7\xfb\xden=\xbf\xb1\xdd<\x90\xcf\x95\xb8\xfd`I\x89\x82\xb8\x80\x98 Gp\xe22\xd8\x879\x06\x95\x03\xbe\xae\xc2G\x81\xde\xe7\xdec\xdc\x8fk\xf8\x06\x16\xf8\xf91G\xe4 D\x1e\xae6\x95\xban\x06\xbb\x13\x97\xe3\xbe{\x8d~3\xf0\x0d\xf0*._\x99\x8d\xb7\xdb\xc4\x7f\xb4\xc3\x98\x86\xdaz\xce\x18L\x075\xf7a\xe9\xc3-9\xe2\x98\x8c\x9a\xf2\xb9\xd0I\xb6\xb5\xd4\xb5\xf9\x16\xbe|8\xbf\xba\xb2\x7f>\xae\x1b\xc8\xe4\x83\xfb\"(\x85\xeeA\xbd\xf6f\x82\x82\xd0\xf3\xe1\xc4\xbdF<\x86\xa7\xc0'xc\xe8\xea\x86\xf0\x9d\xca\xf1\x89\xfe\x11\xb3\x03_J\x0b\xd1u\xaf\x87\xa1\xa7n\xba\xfa\xfcA\x81\xfb/\xdd\xcb\xddp\xfc\xf4sq\xdc\x87\x0b\x9fC\x9b\xb8>QMr!\x1f\x04\xccK\xe9\xc3\xf5\x0c]\xb6\xa4\xb0\x96#\n\xa3\xa8$\x84\x83U\xc9{\xe1\x92c\\\xe0\x11tN\x83s\x8e\x9e\x02\xd5\xde\x13j\xdd\xb85\xaf\xa0R\xc7)\x06{\x99\xc0{\xd5g\xa2\xd5^{\x84\xd9\x97\xed\xa8\xc5\x91)k\x19\xdcS\x91\x81\xfc\x16\x9e\x88,\xe6\xbc\xd6m\x837\xa8h\xba\x0fy\x81\x1a1G\x0d\xf7\x02c\x82pBn\x02\xda\x98C\x12U\xe4\x84\xfe\x82\x96rk\x1a\x9f\xb5o\x10\xa6\xc7\xd2\xea\xe2\xf8{\xbd\x18\xa1\xb8\xde\xef-P\xda3\xfbb\xc9\x07g\xc6IK\xec\xa3\x8e\x1a=\x96\xc8\xcc\xd1q\xce\x919\x14\xc8<\xe7\x0b\x17j\xc8<\xc70(\xdec\x98\x0bd\xe68\xb8\x81>\x87<\xa9\xe8,\xfd\x02\x04^\xb9K.\xf3\xc2\x1f98\x0e=O8\x15\x9c\xb8\xc7\x0dF(O\xf9\xb4\x13OAj\xafW\x97\xf0\xf4\xe7c\xaf\x17\xf3R\xf5\x84S\xd0\x86\xc7\xef\x9b\x84\xa4\xea\x9b\xadU\x17\xbebi\x16&\xf1\x18\x1c4\xe6X\xb4\xd0\xed,;0\xe5\xb2\x96\x0f] \x1a\xc33;\x9b%\x1f\xb01\xbc4O\xd5b\xb4\x10\xed\xfeh\xfe,\xdb<5\x7f\x16.\xf6\xe3\x8e\x12\xb1\\\xd8\xee2\xb4V\xebv\x90\xb3,\xa7\x98|\xceM\xdc\xef;\xd0#\xd2iJ\x99-\x9f\x8f\x16\x02n\x9b\xcf\xdb8\xa4\x19w\x1b\xdfg\xcdh\xa9\xcd\xe8GW\xe6\xa6\xb9[\xb9k\xf8i\xf3\xab\x83\xac\x0fZ\xbeD\x94n\xac\xa6Y\xf9\x88qn\xeb\x8d\x15\xc1nP,g\x14\x02\xd3\xd5c}$\x15\xffC\xdd\xe3\xcf\x90\xe6\x86\xffy8\xb2d\xbb\xe9\x14\xdfC\xef\xbc<\x1f\xe9\"\xd8\xb6\xabb\xbe\xa6\x0c%\xe5\xb9\xf8\x95\xe6\xc9\x91\xaak\xf3\x16K\xab\x88\xf58i\xeb\xec\xc56\x8a:v%\"\x85vjR;1\xde\xad\xf5\x1dC\x89u\xda\xcb|@\x84 \x0d\xf8\xf2\x16z\xec>|\xf4\x88+\xb7\x03\"Kd\xdd\x97\xde\xc9@q\xaa\xba%\xf3.\xf7\xaa^+\x91,m\x8a5\xd2\x12\x99J%\xb1\xa9e\xf0\x81\x96\xb0\x87>\xd4l\xf8x\x84\x81G\x89w\x1cbzxC\xd8\x99\x18\xf2\x8a\x07\x86L\x90\xa19M1zC\x0c\x853D\xe5\xc89\xa8\xb7\x8cqE\xde\xf5\xf6+\xc29\xd3\x0ckU;\x8ct\x01\x1d\xb1\xc3\xca\x888\xac;1\xe6\xa3\xd1q \x1c\xac\x83\x9b?\xb3[\x14v0\x85\xa9zch:\xd2\xcdW\xa5\xaf\x99\x0c\xf5\x19I\xc9 \x13PV\x1bQ\xd61J\xa4\n3\x8c,\n\xbd\x9e1\x833zLJ\xa9{\xe5\xa3\xc9\x9eMg\xc5\xfd\xff-\xfaQ\x0fm\xc6\xc55\x17\xaf\xd5\x81\xa7)5\xc6\x1a\xed\xd7p\x04\xee\x02\xcb\x16gTk!D\xa9wk!\x8c\x8eEY\xfa\x8c\xc7\x94s\xf3\xed\xe1\x85\xe7\x83\xe5b\xf1\x86k\xd6n\xe0\xc3\xdc\xa3\xb0\xd3\xd39\x1e\xb4\xf3\xffI\x16[a\x1cTr\xe0\x9c\xf2\xff}X\x9d\x17\xafV\x16\xec\x87\x02a\x82\x02\x0f\x8a\x89\xe3\xf9\x97\xcc'6\x083\xfc\x9f\x83e\xab\x8by9Q\x90\xb8\xba[CJ\x19&\xb2\x1ecgw\x02\xa1\x8f9m\xf4IWYld\xf8\n\x030atO\x89\x94\xcdA>\xebpB\x95/)gTKm.)\xe5\xe9\x96a\x94\x8bE\x10e\xcc`\x8a\xa4\x06\x05>6\xe7B\xc9\xbe\x0b\xe30g$\xb1\xd0\xc1s\xbd\xbd9[\x04\xdb(ol\xc9q,@\xf3\xd1\xcc\xce\xeb\x84\xb2\x16sX\xb4l\xa7\x97\xbe\xc6\x0dA\xdef\"\x91\xc8\xb3\x1c\x7f\x1eA\xe8\x06(\x9b\xa8\x01\x046\xea\xc0I\xa4\xe1\x16F\xea\x06x\xb5\xc2\x90wW\x8c8qI\xe3\xe3\x9d\xf1\xbf\xba\x08\x92R0\x83\x9e\xb9Of\xb22\n\xa3/\x86\xc2\xb2\xd7\xe4c\xa9\xde\x1c)U<2W\xdc\xd24\x1bF\x84\xf0\xf2\xfb\xa2\x04\xe6`o&\xd6O\x0e\xfa\xeb`\xa3\xe5\x92\\\x07\x9b\x1a\xdb+\x9d\x85M\xcfKV\xcb\xe2\xb8%\xed\xf5<\x99\x035w\xd94\xe5\x05-\xfe*\xd5d\xa8\xa0q{\xcd\x81\xbfy\xbd\xae,\xf9O\xcba,\x99\xd7Y\xb6\xa1 \x97\xbfR\x1a\xd4\xda\xea\xef5\xeb*fb-\x9fn!0\xe5#\xc6\xee\x96\x82.\xe5\x82\xde\xc5\xec\x1ar\xb7\x80(\x97S\x8e\xcb0\x0e\xd2[\xc7\xf3\x8a\xd7\xcee\x90\xb1\xfbw[-\x07V\xa5\xe8\xde]O$M\xed$\xce^iY)\xcdA\xdd\x0f, \xcf\x0f\x87\xe6\x84\xe7\xf7;\x05\xf47\x1c\xc8(\xde3\x01\"\x9d1\x14\x19\x0bb\x91\xb1 uC7\xf6\xd0\xc2\xaa\xc4O_$ \xc6P\xacB\x17\x8e\xd1\xbeV\xb8\xe6 un\x81*}@\x9f6p\xc9 \x84\xbe\x8c\xd7o\x14\xc7`\xf0\x84\xe6\x81\xf0\xe0)\xad\x1a\xaf.j\xa5\x9eN\x14\xd4\x90\x13\xf4n\xc8p\xa5%\xfe5E\x84\x1f\xd57\xf3n\xdb\x86YfL\xb9\x16\xe0\x03\x84m2\x92\xde\xc0^C\xc3\x16\xed\nt2\x9b\x9bQ\xd0\xaa\xaf\xc8\x95-.\xfb\xf9\xb0?\xfd\x89\x02\xf2\xbd\xeb\x7f\xf5o\x7f\xbc\xf3\xf57\xbd\xc1\xbb\x9f.\xfe\xcf\x87\xff>\xdf\x0f\xa5m\xc5\x12\x88L\xfaw\xccVA\x1a\xccrtD\x81\x15\x0b\xe6,\x85E\xc8\xa29\xc4\xc1\x9a\x99\"h(\xf2_\xb2\xd2\x94\xd1\xda2\xe7\x8ef\x87\xb6iW\xf5msg\xa9\xb93\xc9 \xcc\xd4/f7\xba\x19\xc3F$Ak\x88I\x7fK\xbbqWL\xd0\xde\x16\x7f\xe6I\xcc\xc6\xba\x8d\xca\xe0\x10\xa8?\"6\xbb\xd9\xb0\x0b5Rk\x7fkH'%\x06\xbc\x1a\x849\x85\x88\xa7s\xf9)%/\xa5\xb7y\x92\x9e\xef`D\xab\x8f\x13\xe3\x97u\xda\xca\xc4\xbc\x95\xe8\x9f\xb8\x0e6\xa8\xf6\xfb\xe50\x81\x89\x0c>z\x12\xccV\xed\x81\xb1Us\xc1f\xc3\xe29%\xbb\xa9\x8f\x98n`\xa3G\xb5.\xab \x85\xc0\xd0]\x97\xbe\x18:\x98\xb3\xe9\xc8\xe4\x94T\xf4\x88{ \xc4\x93%\xcb5\xa1\xe4E\xb0f\x99\xcb\xbcz\xff\x9d\xe7:\xcd\x1b:\xef\xb4G\xa1\x9d\x9e\xb1\xc1e2\xbf}\x9b\xb1\xb9\x12\x1e_\xa5\xc9:\xcc\xd8 exC\xbaB\x9c\x9eE)\x0b\xe6\xb7\xc0\xffuL\x87jE\x8b\x18\x90\xad\xd3\x00\x83f[\x1e\xbb\x96\x83j\x0f\x02\x0e8\x84$\x8e\x92`\xde\x05\x05\xf8\xc3\xc5\xa6\x94e\xdb(\xb7Y\xe4\xb1I\xc6W\xa0k\x9b\xb1\xcb\x06X\xa1\xb3\x11\xbc\xdb^n\x9bI'_\xab\xef\xc2\x88\xbdFva\xa6R1\xca?&\xe7$I\x0f\x06|w\x9feZ\xb2c\x12\x97:\x8d0k\x826\x94\x9dj9\xef\xabn\xfdP\x99Q\x91b\xd8-\xa5\xe9l\x98A\xc6\x08t\xf5\xaa\x18\x82B\xa4j\xec4\x95\xa8)K\x05\xe2\xa9\x0e\xeb2\xdc\xd1E\x18\x87\xf9\xb7\xc9\xfc\xb6\x93P\xcf\xd7\x85\xaa\xf1\xb6N\xe3\x10\x19\x97\x91\xc6\xe9UL\x07\x01\x1e\x14\x0d\xbda7\xd8\x90\x9d\xf3i\x17\xc1.\xa3\x04\xc3\xda|\x1b%\x97\x9a~\x15f\xaf\xe4\xdf/\x17B^\x91\xed\xf3\xa2\x9d\xdb_$\xe9\xfay\x90\xa3\xf3\xf4w\xe2\xef\x8e\xfd\xc8\xe2\x9d\xfb\xa2\xcb\x05\x18\xcc\x15-\xaco_\xffp\xa6\xbd\xea\xd8\xad\\>M\x9d\xea\xd4{P\xa0\x0c\xe0\xf5d\xb9\xb4\xebJ\x07\x1an\xc1\x84\xe3\x8cL'\xeaC\x0d\x1a8\x1c\xf3\xf5v\xa7\xc6\xfa6\x97Uh\xbe\x07.\x1f\xbcXT\x1e\xf9\x87\x0f\xb0\xa7u\xd0\xb0f\x80WH+\xb2\xac`\x15\xdb8\xdbn\xb8\xa8\xcf\xe6\xf0\xad\x9c\x0d\xaf\xd9\x16\xfc\xada\x95\xecH!s\x94T\xb7\xd0\xe6\xe2H7(\x90Lf\x9ci\xbb\xce,\x89s\x16\xe7}\x1a\"\x1e\x1a\x9a\xb0LE\xc6\x11u\xb3Z]\x1f\x9c\x9c\xdd\xe4\xfb\x9b(\x08\xe3\xc7\\\x8c\xcfX>y\xfb\xe6\xbb\xfeCG\x05\x97-\xb0H\x86\x8cRo\x06\xbc\x95.\xdd\x18\xaayx\xd1\xf5\xd3\x91@\x8d\xa6qz\xc1f\x13\x85\xb3\x80S\xb6\xfd\x9b\xfe\xf5\xf5u\x9f\xa3x\x7f\x9bFda\x9bWgm\x94`\n\xec \nxI4\xa5\x95\xbf\xca\xeb9!\x8521\xef/\xf2\x1b[@j\xbdPy\x11\x0db\x90\xc8\x04P.\xd6\xa5=\x0dz\xad\xcd\xb6\xe2v\xa7\x9e$\x954`\xe1,\xd9r\x8d1\xc9QdS\xe4\x17x5\x082\xe0\x8bnC\xc8\x1d\xc6\xcc\xb1\xadj\x9d\x85BP-\x91\x97\x0e[\xac\xf3\xd8\x1a%8\x92;\xcfq\xd4\xbeO\xa5\xe5\x17X\xc7g\xebz\x83|\xc5bwk2D\x8b\xe1\xe6D\xfeZh\xd2m \x8ak\x05\x06\xc1Q\xda\xfb\xd85i\x88n^\x98\xf74Kx^\xb1\x84OQ\x956\\yq\xf3i#\xeb\x95\xda\x8b\xddU\x0b*+\xa6/D\xa7\x95\xfb\x0c\xb4\xe7\x00\xbe#\xda\x97\x91\xddB\xd1uQ\x8fj,\n \xae\x15\x9dt\xb4\xe7#\x94\xa8\xbah@\xd5\x9f\xb3$\xfe\x9c\xb6\xfft\xf6\xf2\x05\xf9qX\xa9W\xe9\xbdMY\x98Y-\x18\xf2\xcc\xc5U'\x80\x7f\xff\xe8\xa1\xeaP_\x7f\xa4\x15\xba\xb5\xc4x\xe6\x0f\x06\xf5\xddhK,\xab\xeb\x0d\x92\xd06%\xb7\x85m*S\xed\xccR6gq\x1e\x06QFn\xdf\xc5o\xaeF \xf9\x00\x8a\x00\xb7\xe2\x05\xa1X\xe22\xf9FE\xfe[\xb3|\x95\xcc\xb11\xfaS\xbe'\x87\x19\x86\x7f\xf8t*\xaa\x1cx4I\x18\xef\x1cC\xe9\x9d_\xb57\x18\xf6P\x13\x0ci\x96\xca`i^~\xc3\xec\xf3\xd2o\x19\x98\xb3\xf2\xceI\xd6a\xee\xf8\xb0W,NE\x98\xb2/Vn_\xacv\xd2W\x98;\xf3\xe4\xedfc\xcf\x04\x00\x05\x1a\xdc*\x8f\x0ftF\xef\x8f\xb8\xbcit\xe7\xfb\xe8\xe6r0r\xe2\xc5O\xe7?N\xde\xa8\xe8\x87k\xe9\xf8\x84\x7f\xa8\xc2\xe2\x87\x96\xc5)e\x0b\x96\xa6( \xd0[\x17\xdb)BRj\x1d|\x7f\xf2\xecy\xed\x0b]\xc7\xb7\xc0<\xaa\xdex\xd12\x8a\x92k6G\xb6\xf0\x1f'o I\x81\xb7\x06)\xfb\xdb\x96eyfB\x08\"rR\x83w\xe3nV\x99E\x07\xab\x8c \x83MV{L\xb1!/\xdf\xddq\x0cV\xc3F3B\xabxP\xbam8i\xbam\xc8\x9f\x94.\xdd\x93\x05]\xcb&\xd2\xc3l\"\xd0V\x1d\x0f\xf7\x04\xf3\x9b8\xc6\x06\xec\xcc3\x97\x16P\x83[\x10\xd7\x91\x0d\xaf\x13\x83\xf4 \x16S[W\xeb\xf6\xa6}_\x93\x86\x0d\x951\xf4\xd3\xa3w\xf1\xfe.\xbbY\xdb\xacq\xdb\xd5\xd0b\xa3\x08\x8a\xec\xe2C\xed\xb6\xbf\xfeH\x7f\x07\xb9qc\xa7\xb9A\xd0\xf7*\xf5\xab\x9e\xb5\xf2\xf9\x9c=\x98[\xf9*q\x84\\O\xb8B\xaa\xf3\x04\x1c\xe1\xea#\x95\xe4,\x0f\xf2-'\xb7\x0e\xfd\xe5`jLN\xf3\xe4\xa71\x1c\x0c\x87\xa2t\xf2^\xc5\x8b\xa5\x8fO'\xfc\xab\"\xe7\xe2\xed\x138TU\xe8\x95\xb49\x14\xbfj\x1da\x9118/\xff,\xc7f\xe7\x05\xbe\xce\xb5r\xfc_\x84\x9a\xab\x90\xa9j@\xd5\xd2/4\xf0\xb0\xc1\x82\xe5\xe68rW\"\x16\xa0\x19*tS\xc2\x18\x9c\x8a%\x01\xa7g\x08w\xc6\x1fy@5\x06\x87\x0e\xa7\xa80\xfaX\xcac*|E_\xcd\x8dp\x85m\x0cN\xa1\xd0h\x8dp\x0d\xa3\xf8\xd9*\x00\xf2'Oo[\xcca\xda\xa1\x03o\xdf7eO\x96\xcfG\x98\x05\xe8R\xd7\xd5\xad~odo\xcb\x8c8\xb6l\xc0R\xaa\xe6k#\xfel\xda\x0bM\xfd\x1e\x83\xa3)\x1aT\xa9\x8e\x9ef\xd1\xa8d&\xf4\x10r\xae0\x95\x9dtv:\x95\xfa\xd6\xb9\xe3\x17.P\x85\x1aV\x7f}\x1c\x05\xeb\x0d\x9b\xd7\xbf\x9e\xc6\xf9\xe8\xbe\xb9\x92\xe9\xfdi\x9c\x1f\x1e\x98\x8b\x9b\xde\x7f\x17%\x81\xfd\xc3\xfd\xbb\xe2\x83\xe5z\xea\xba\x93\\\x06\xba\xeb\xc6\x9d;\xc07\xe9/!\xbbn0\xbf\x99\x81\xc0<\x88\xa5\xf4K\x13V\xda0\xe3\x8d7;[\xe9\x8f>\xb4\xc2\x01\xb8\xd5E\x8d\xc4E\xf3@\xebP\x93h-\x11\x9b\xa8\xf8\xbbX\xd9\x11\xa3\x90\x0cB;\x8f\xdd\xd4\xc2\x82$\xcb\"\xf10\xd8L\x99\xe5\x8e\xa1V@$wO\xa0\x07\x8e\x8f\x81\xb1al\xba\x8f\xef\x97\xc6?g\x11\xcbY\xa7\xad\x17EU\x97|\"\x86\xbc\xda\xe5\xf6\x97,\xef\xd4\xb8\xda8\xb9@\xc4F\x82\x8c\x0e\xbb\xf5y\x8e\xcb\xa9R-\x1d\xaf\x82\x9d\x1c\xd0d\x07\x15\x07<77;w\x96\xfb\xca*\x93l\x80\x80\xf2\xea hk_\x08Ym\xb9Y\xe5SI\x96-z\xf4\xacs$\xe7B\xa6\xfc\xe1\xd4\x18\xe3s\xbaqT;\x957\x8c\x11\x9d\";\x98,\xa4u\xd1vkV\xdf\x8f\xba\x83A\xc3 9\xe0)\xb9p\x904\xa32\xfa\xde\x9bM\"\xfaT\xd0\xd5\xe57\x98L\x87\x99\xd8N\xef;\xce\x84\xc5y\x1a\xfe\x16S\xe9\xb6/S\x0eL\x06\xcf\x0fh\x99R\xc51H\x9b\xa1\xc9E\xc8\xb0\x00\x96\xb3\xf8[\xe4\xf3\xcfO~8ys\xc2\xf9%W\xd8}\xa1\x9e\xfb\xe0\xbc|\xf5\xe6\xf4\xe5\x8b3\xfe\xe7\xab\x97g\xf8\xe9\xd5\xdb7\x8ea\x81fZ\x97\xb3(\x89Y\x97\x15\xd7\xa4\xb2\x19ZP\xfc\x86\x15\xbcL\xe6\xb7\xfa)\xdbi\x1cZ\xee\xd8\x1aWP\xa4\xcb\xd7\xc6\xe9\xa9\x97\xf3\xd2\xcb\xf9gNe^9\xf9o\x9a\x14i\x0fc]\xdb\xb0k\x84\x85\xaa1\xae\xaa'\xf6JB\xeb\x18K5D\xd3M\x1a\x94\xcfm\x1a\x8d\x95\x9a\xb2\xc3*\xcf\x07\x9d\xfdi$\xba\xd1\x92\x91\xc5\xa8}\xa1\x1a\x82\x82\xe8\xcb\xe3X\"h5\x9b\xcf\x98R4q\x16N\xd5\xf3\x11\xcc\xd2\xd0\x95\x88c==\x1c\x8e|8\x1c\x1e\xf0\x7f\x0e\xf9?\x0f\xf8?\x0f\x0d\xe82\x1f\xa4l\x1e\xa6\x1d\xd2\x8d\xcb'\\\xa8\xfc.\x97\x9a\x95O\xb7\x96i\x11\xb7\x94\xbb\xa9Pjg\xc9\xdcz@_\x02\xdd\xae\xfb\xd0\x05\xe2\x9a\x95\xa7(\xa1\xa3\xe6\xc6\xcb\xc6;\x80\x1e\x1b|\xafT\xee\x84\xff|M\x06A\x98\xc0\x8c~f\x9b$\xc6{\x9ds\xfe\x1b5\xe7\xae\xab\xaf\xadQ\xcdi-n\x10v@\xb7\xbe \x99\xc3^\x9aml\xa1(\xfc\x9f?\xfe\xf0}\x9eo\xc4<\xec\xa6\x9apG\xcf8\xd0\xb0\xaf\xb9\x14h;\x1e\xb6\xd2\xa7r\x0dB\xc4\xb0\x13\x91\x92\x8f\x02\x9d\x8d\x1br\xc1\xf9Y\x14\xc9m\x13\x9b\xeb\x8a\xa8\xbev\x97\x110#\xa9\xfe0a|qR\xd1\xf8\xdb\xd7?\xa0\xca\x1c\xc2\x11\x84\x03\xed-\x8c\x81\x95\xfdI\xfe\xb3/\xf6\xa3\xcf+\xb5\xf8\xbcH\x93\xa2\xea\xc8\xd0\x0b\xe6\xe9\x97?\xf8257\x19\xbb\x82\xc7\xe0%x;\xe6\xf8\x08\x16\x9d\xa9\xb1|\xd2\xaak\xe8\x0b\x96_'\xe9{i^\x87E\x10Fln\xf2\xfd\x90\x8f\xe8:\x0f\xd7,\xd9v:o\x97\xcf\x17\xeb|\xc3b7Q\xc7Q \x9d\x7fa\xaa\x1d'\x8cg\xd1v\xce\xe8\xf0!)\x9d\xf6p\xc9*\x1c\\\x87\xf9\xea\xb8tND\x15\xd5\x16\xddn\xe46\x96|\xc1\\m\x17\x05\x17!/\x0c>\x00 B;\xf9G\xcb'\xe4\xea\x95\x80:B\x03\x8b\xbb\xb4|\xb8$\xc9+\xc5sWsoO\xb4C\xb7#:\x8a\x1b\xeb/mR\xa9\x99\xd8\"\xf9\x1cl\x92\xe8v\x11F\x91\xc9+X\xfd\xe5:[y\xd1_\xbfk\x90\xb1h\x01G\xf4\xdfXS\xb1>\xeb\xa2l\xec>\x1a\x9a\xae\xaf\xf0\xf7\x0f\xcd\x17\x92\x1e>\xb2\xdc<*\xef\n\x85!\xe6\x84\xb0\xdc\n\x1e2\x8f!)\xbfUQ\x02\xc6\xb5\x9c\xf7\x9f9\xbf\xc3\x87\xd5y$j\x1e\xf5\xf9\xd5!\xeb2\x0df\xef\x19\x9fHg\xd3\x00f\x84\x9b\x9e\xd7e*\x83\x0d+\x8c\xe7\xe1\x8c\x95Zo\xe7\xab\xd4\x01f\x96\xa3\xe4s]zJ\xd9\x86\x05\xad10@\xeb\xa5\xdej\x19d\xeb\xf7\xd2\x9e\x079+Y\xcdN\xcf^\x92\xe1\xac\\\xd6\x1c\x8dg\xce\xa2p\xcd\x15\xb31\xde\x0e\xae}\x97\xc1n\xf6\x0cR-}K\xc7\x90\x8a\xe0\x13\xb6\"\x7fA]\xfde\x1c\xdd\x8e\x8d9\x063\x96\x86A\x14\xfe\xc2\xf8\\vX\xad\xa0v{U>\x86\xbd\xc8\xde\x87\x9b\x17\xdb(\xca,c@p\xe6\x05\xbe\x0f\xe2y\x84\x91Q*V\xf3J\xa3\xba\xc6\x0eL\x04~Q\xf1\xc82\x1f\"\x9f\x8buE\x88\x04\xd3l\xa4%\xdb\xc0R\xd1\xdbZv\xa0{\x82F\x1eV\x89\xb8Xwe\xba !\xdd\x82\xaft\x7f\x0e\xbe\xb6Tq\xe36\xd6RW\xc2\xaf\x9a\x04\xfdP\xb9LQ\x06\xb4\x15\xa7\x93|D[\x01\x0c\xe8\xfbf\xb8\xe2\xcd\x9f+\xf4\x8fm\x81u\xb0{\x9c_\xa1\x84U\x8f\x97A\xefe \x80\xea\x87t\x10f\xe2V\xc1\x95\xa7\x0d\xff\x08\xa6s\x17#\xc4\xc3\xb8:\x07\x8f#\xfb\x84\xa3\xfd\xdc\xcd\xdc\xab\xd2\xa7s\x18\xf3\x9a\xb1^F\xb8x\\y\x9eA\xa5\xe2\x9b\xbd\xf6\xd1~n\xb2\xe0\xe0\x96\x15\xcc\xf0J\x0d\xd1\x10\xff\x8f\x97-\xdf7\x8a<\x0f\x8f\x07\"\xcb\xd6\xdaU\xdc\xdbJ\xda3\x13t\x808|\x98\xc1\x11\xdc\x0e\xb2$\xcd\xdd\x19\xdf\xe0. \x9a\x94\xa9\xf3\x92\xbc\xdd.\xe1 \xac\x95\xb7[\xafw\xd9\xa4\x7f_\xc0\x04\xd6\xd3K\x8b\xc1\x0b\xdd\xbd\n\x80\x9d^`&\x07wY\xbd9\xef^yp\x04K\x99S\x86\xb9\xbc\xa8\x0f FP\xf3Z\xd0\x96\xcf\xb3V5\x86\x1e\xb8\\8p\x06|\xe7/T\x9e\xd2\x0b\x95\x9b\xb4\xb9Q\x03\xd1\xaa\xbd\x91\xfb_&CfQ\xa0\x91\x99\xa9s\xfd:\xe1\x0b\x80n\xe5\xa6\x83 \xcb\xc2e\xec\xfe\xfd#606\xc6\xcdQ\x01\x99\x02\x89\x07x\x8aS\xdc\xf7-\xbd\xd7\xc8W!T\x05\x05\x810\xba\xd1\x9c\x88\xfa\xab\x00\x03\xa0_2\x08\xd4\xe4j9E\xaeD\xdc\x1b\x0do\x82\x81bjp\x04[\xed\xd7X\xffV_\x89\x19\n\xc4u\xe2\x11\x0c\xea\xcc\x01\x8e\xcc\xaf\xc7\xb05\xbc\xae\xf7\xb5\xb0\xf7%\xf9\x14u\xa1~a\xcb\xf2W\xbd\xc1\x8d\xb5A\x11\x18\xea\xa8\xf8s\xac\xa8X\xbd\x1d\xae\xa2\x1b\xb9N\xb1\xb1G\xda\xdfES\x86\x05]\xd9\xdb\xca(\xa5\xbc\xf8\x83N\x8b\xea\x0d\\\x15;K\xb0\x85\x9eU\xcf\x93\x1cy\x8e\xf6\xb3^u\xdd\xd0\xb7.n\xd0 Jop\xa5\xf57\xf5\xd6\x97-\xab]H<\xdaji/\x8be+^\xd6\x91\xad\x04\xd4$\xdc{\xea/4\xa2\x0bo\x93r\xd5\"\xf3U\xa7\xc8\x15\x89h0gi\xe6\x17\x1dY\xb0\xf3m\xfc>N\xaec\xa1k@\xb2A\xf1g\x93&W\xe1\x9c\xcd\x8d\xf8)\xc2\xb1\xe2\x80\x8b\xae\xa6\xb2\xa7\ni\xb7l\xda\"\x8c\x08\xa1\xd1\xa1\x95s\x12\xf9\xces1/\\\xfd\x06\xae*\x80\xba/&o\xd7\xab\xd5\x07z\xedc*\x82*oF!D\xc6\xc2)\xe8\x98\xee.:\xe1\xfd\x0bj]\xbd\xf8s\x8d\x9d\xa2\xff\xc2w\xb4h\xc2\xc0R~9\xe6\x8a?*&\xa8\xba\x07X@\xbc\xe1lF}\x1csE\x9f\xeb\x15\x8e^\xa7>\x9b\x1b\x98@8\xbd\xaeL\x06\x83\xc8\xb8U\x96\x1f{\x18\x0d\xeb\xce\x1d\xc9\xdc\xabw\x1c\x15\x0f?#\x1e~\x06O\xe0V\xe3\xe1g6\xe1\xf6\x18&p;=3\xf0\xefE\x89w\xc7\xd3c\xe2\xdd|\x07N$\xb7\xcd\\\xfe\x1e\xa3\xf8\xde(\x0e\nG0\x97$\x83C\xd6\xca\x87+\x9f\x0bV\x17>,\xab\x8c\xf5cm]\xdec\x07\xe8f\x16\x19\xcc\x9c\xcf\xd0P \x90.\x98\xcf\xff\x9f-Ko_\xa5l\x11\xde\xf0m8r\x0c1\x9e\xc4\xce\xbf/\xf2 \x0c\xe1\x08\x9eA\x0f\xdeW\"\xfc\xe0_\xbf\x8az\xdd\x82\xeb]\xf4nEN\xcd*\x12~Vn#\xb6B\x1c\xa4\x7f\xe0,v\x0c\x07\x06\xa5\x91\x1c(Qi\xa4?ME\x9au\xd29\xdb\xe4\xab1\xdc30\xc1 \x0d\xd6,g\xa9\x18\xc0\x88\x1d\x1a\nEA\x18\xd3j}1]0\xe8\x10L\x05\xda\xbce\xd5\x0ekl\xeeH\xcb\x92\xb1\xffn\xe0N\x7f\x1aL\xcf{\x1e:\xb2N\xffmt\x8e\xf7\xfa,\xbeW 6z\xdf}7\x9d\xfe4}w~\xfe\xcd\xb9gK\\\x03b\x16\xe5\xc2\x94h*m:\x86\xe3\xd4\x0d\xc5Gq\xa5\xda'\xb2\xc5n0!\x85\xbdb\xd6p\x8e\xcd\x97\xa9\x16\xcd\xacZ`/\x1e\xe8[ \x98/\x0c9Z\x15\x1504\x1a\xa5\xab\xae\xc0\xb0$\xdav\x83vF\xa7\xe2\x86;[`=\xfdQ\xc4R\xe4\xf6VB\xb3\x1b`\x08G\xb1\xa88\xa6\x08\x9e@<@\x90n\x0c\xf3\xcdg\x1cA\x0fC\xe7\xef2\xf3`::\x17[3\xf2\xa1/\x02v\x7f\xc6J\x04\xc6\xa0\x14`]\x0ci\xab\xe1\xdd\x8a&HQ\x92\x10\xa3\xc0E\xe8M\xd6\x01tA\xb0Ry\xb9\x0d\x1c\xa9r\xca\xf2\xa2%7\x1b\x89\xe4\x03\xc3\xc7\xd0\xef'm\x8d\x81@\xd0\x90\xa2\x98\xb3i\xd2\x90\xda[>(9LE\x0c\xb6\xc0Cl\xc44\x08\xd3sO\xb28\x9b{\x99\xfet\xb8M-\x1f\xb4\x18\x97\xc1\xe3H\xf2\x86Y\xca\x82\x9c\xa1\x0eg\xd2\xefl\xcf\x95\x08\xe5\xc7\xb7\x8d\xd8b\x91\x9f\x91+y\xe7\x95\xd7\x81\xb6\xc6\x1e\xc9\xd7\x1a\xfcq-\xcc\xbe\xc7\xd5\x87S 4_\x9f\xc6\xb9\xbb\xf5ad\n\xd9`z\xf6\xc2\xecE\xf0\xc2\xcdp\x88\x01b\x1f\x06\xbd\x17\x06\x9a\xcc\xc31\xe3\xab\x8c\xc2\x8c\x8a\x1c\xc8i\xc6P|\xcc\xe8\xd3\x13\xa4\xc7\x8a\xa9\xc1\x91\xda\xc0iv\x8eQ\xf0\xc7\x10N\xb7\xf8g\xeb\xc0\xcc\x18\xa2?\x1cT\xc3\xc6R\xcdm\x08l\xb3\x0f\xe5\xa3\x9b \xec\xa9\x15\xa9\x98\x9a?\xc3\xcc\xf0 \xf6\x84X\x88\x03U{B\xe9\xbd\xd1\x9e\xa0JX4\x96\xe7l\x07{\x02\x8ei\x10.\xe3$e\xba\xe4\xa7dB\xc3G\x1f\x87 \x8d\x0c\x13S\xacl\xbd\x80\xb0D\xbef\xcb\x93\x9b\x8d\xab}\xf10I\xa5n\xae\x085s\x85\xe4\x12\xbc\x83\xba\xe5S~\xc3?eI\x8c\x83=\x11\x9eZ\xc1\xa0\xf8\xe9#f\xb1\xcd\xb1\xf0B\x0e\x06\x17\xea'f\xa5\xc8f\xc1\x86\xbd\n\xf2\x95\xba0\x8b\xa5\x0c\xefy\xf1ml\xab`\xfcR\x1e\xfe\xd6\x90\xd7\xaf\xd5\xad^\xc0c\xbb\xcf\x01]\xd0\xbc\xccXzE\x1e\x9c\xd3syk\xf3\xf2g\xa8f\xfc\x80\xba<]\xbdQ\x17\xed<\xb4\xb6@\x95\x9cv]\x06\xb3\xf7\x14\xc8\xad4`\x98\x98\xa2mV\x07h\x8a\xfd=\xab/I)\x8b*\xe5\x9cJ1-\xb9\xa471<\x81\xf41\xc4\xbd^]\xcb@\xdb\xce4>\xa7e\xc3H\x0bd[\xb7N\x0d\x19VlQ\xb7/S\x16\xbco\x99\xd9\xc2\xcd\xe9\xbe\x88\xaf:\xe3\x7fm8\x14s\x11\x0b\xd3D\xa8\xdfR{E\xabJ\x81\xaaz\x1b\xa2\xa4\xe1\x08\x81R\xc8\x8a\xefF#q\xa8\x1b\x891\x94\xad,.`\x8a\x15\xfb\xa8n\xfc\xf0_n\x88\x89\xbf4jY\xdf\xac\x85\xab\xb2\x01\xd4,\x1a\x18b\x82\x92\xe9\x98\x96\xda(\xa4\xe7\x83<\xf9\xd3\xd9\xcb\x17@9X'\xea\x85k\n\x14\xa3\xe0\"D\x9epAK\xfdg\xce\x9ar\x8f\x84\xa1\xf2[\xe6\x91\x98\xb37\"\xde\x17\x94\xac3\x99\xb0\xced\xfd~\xa3X\x83\xe6\x18\xe4T\xd3\xec\xbc\xc1\xa2\xb8\x97\xd6.\x8e\xf9\xb0\xf1*\xd2g>\xdd\x9cWt\xd0\x08Mf$\xc0\x94\x8f\x98rO\xc5\xac\xb7\x9bg\x92\x0d\x1e\xd9\xac\x93+\xd6\x90o{\x13\xe4\xab1\xdd\x0c\xdc'\xf3\x98\x81\xe0\xb9\x1b\xfb\xc5\x1c\\HK\xae\xd7\x16\x03\xd2\x95\xc8\xf9\xc2\xe7n7\xaf\x18\xf2ADP$i\xa2\x1f\x86B3\xbd\xd0\x8c\x0b\x89.\x89\xa2\x1cJ[\xe7\xcb\x85\x1d2\x11`;\xee\xde\xd0o_r(\x96\x1d\x05\xf3\x86u\x87\x1d\xd6\xbe\xb9\x15\x11}9\xd5X\xa0;kr\x81\xedjF5\xfbEm9\xe0*j\xb2W`\x8f\xb9YDNMm\x08\x15\xb5\xcez\xbd&\xeb'\x07\x8e\x0d\x9e%f\x0d\xc0Q\xc3-f\xc3-\xae\xfau\xde\xbf`>\xff\x87\xed\x1d\x1fm\xd3\xf6u\xd8=\xcd\xc5X\xfd\xc5\xa5\x1c\xc1\x96\xdb\xeciZQ=+\x02\x97\x94:\xb6\x80\n,\x99\xbe\x9bE\x9cR\x08\xb3!\xf1\xf5\x82\xa1\xe7\x94`871tPL=\xd7\x98\xba\xd2\xe1\xf9\xeb\xf2\x9a\xd4\x02 \xf1\xda\x898\xdao\x95vJz\xb9\x90?\xb9bq\xfeC\x98\xe5,F\xfb\xa3\xed\x93\xeb\xac\x93m\xc6\xb6\x1b\x87\xac.\xd6b\xef\xd9m{!lk\x9e\\\xc7m\x05\xdf\xb3\xdb.\xc5f\xab ^2,\x85\x807Of\xdb5\x8b\xf3\x81\xfc\xe3$b\xf8;\xc8\xf3`\xb6\xc2\xda\xae\x93\xc4\xe59u\xad\xa5O\xb1k\x9d\xea\x8c\xbb\xd6+/@\xd7Z\xfazt0A\xc4\x15\xb9;\x16\xaa\x01iO\xb1\x99J\x9b\x80z\x86y[\x8c m\x84\xddV\x12\xa7\n~!R'\x1f\x03\xc9+\xf4\xc3\x12\xc9C\x9e\xadw%r\x80\xc7>\x8c,\x08\xc9 _\x87\xaehH\x02\xb1\x0d\x13\x0d_-\xc8h,i\xc0G{\x8bu\\\xb3\xb5\xa9J6\xe3\xdb\x9c}\n\xbeUju\xc27SO]0\xa7\xdeW1\xb5\n\xeap\x8eT\xc0\x01\x85n`\xd7@I\x99\xbcRD\xd6\x8fd\xad\x8aYJ&\xa8\x19\xff\x8dv\xbe\xb4\x9b\xa0bp \x91F\x90B\xb1Em\xbd\x9a\x01\xac\xc9h\xa8\xb4\xe3\xcfI\x02\xd69\xadW)\xe1\xafQ\xa9\xd63\x94\x1d\x95~\x8d!\xf6\x06\xd9*\\s\xf6\xdd:/\xb9dZ\xc6\xb7%\xeer\x86'\xf2v\xa2%\x06\xdd\x12q'\x90\xadi\x92\xa7\xd9DdH\xab#}!-Ck\x0d\xf6\xa3mo\xbd?C\xee\x17uK\xcb\xac\x82\xd2\xfb\xfa\xb1\x19\xd3\x8c=\x9d\x9ce\x99\x0f\x0e\xff\x831\x87\x1cij\xb56\xa2\xfciv\x12o\xd7\x14\x11\xc3P\xf7\xc3\x07\xdd\xa5\xec\xa3Kq4\x0b\xc8\x89\xe1\x08}\x0b\x12oPD\xb3\x9f@JVR\xfdUb\x04\x94\x9d|\n\x8d`JQ;p\xe12\x11F\xad\xfaQ\x85\xf4(\x1d\xa8Y\xf6F.y1ih\xba\xebU\xda\xd1\xe6\xf1\xb1\xc1,\x89\xb3<\xdd\xce\xd0\xc0=\x99\xe8\xdf\xd0t \x86\xabv \x8e\x8aI\x8d\x0d#3A\xb9\x1d\xea\xb4\x93\xcc#\x0ee\x11\xb6\xaa\x9fh\xf2\xf7\x1a_\x1c\xeb0:)9z\xd7\x8bR\xa2\xc8#Sz!\x07\xcf\xe5K\xed\xb5\xf4\x9b\xb6\xe1\x96!g\x8f\xc4e}\xc8 \x0d\x00\xb3\xc2\x8c\xd58\xb4/\x81[\xc9Bo\xea\xcc\x90\x7fG\xe9\\\xeb`\xe3\x86\xcdc5\xe4\xa4\x91\xf4\xdcz$,\xe9y\x15\xbdE\x80%7\x9f\xc6\xe7\x18W\x9dM\xe3Z\x10\xfc:\xb57\x8c\xca\x90\x87\xa6\xa4\\+\xbaZ\x18\x82G\x15\x83\xa3*2\x1d\x9d\xf3\xb5\xd4\x7f\x8eIX5;\xf0bT6\xb6\n\xae\xc2d\x9b\x8e\xc15\xf4u`\xed\xeb\xa0\xdc\xd7\xc19\x1e3z\x83r\xabx\xc5N\x9a\xd5J#Pg\xe4|\xeb\x9a\xad\x0d\n\xb91&u\xb9\x15\xcf'+:}\xf3\xa5\x13e\xc4\x85\\%\xf2F&Y\xb7\x94\xbf:\x9dF\xe7t\xda\xad\x1f\x91\xceD\xe2\xe8\xe1c\xd8\xc0\x13X\xa8\x067v#\x18o\x11#WL7\x0d\xa7\xe6+.\xf0L\xe7\x0d%\xae0\x97\xe3\xaa\xc1\x12\xb5\xc6\x12\xe1tn\x8b\xef^\xba\x8a\x80W\xde\xec\x12?\x96- \xe3\x13X7\xa9\x1b \xe6\x8a\x0e z'k8\x02>\xa8\x0e>\x83!%\xc0\xce\xd0\xebk\xba\xf4a\xeb\xae\xbcs\xa3\xbb\x99|D\x9clQs[\xbbz \x1fu\xadE\xa76m\xf3\xd7\x8av\x9a\xfb-\x1ex\xdb\x86 \x1f1V\x07O\xbd\x1d\xe1\x17VA\x13Z2\xe9+pk\xbe,)\x9f\xf2\x1a\xd8\x07\xa0\x97Z\xd5J\x18\xd5\\\xfd\xc0H5\xd3)\x17f#\xd5\"\x12$NA\x90\x84\x1dA\x8en\x1ecL\x1e\xcd)\xc1Hd6(R\x1a\xf0\x02\xe7zk\xd3\xd4,\xefg\xe4\x16Q\x8c\xdd/\x06=\x88\x93\x1f\xb7y\x907*\xe6j\xf0\xcc8\xf8\\\x0d^\xe6g\x18\x92\x1e\xcdH\x8f\x06\xc1\x07\x8a\x81V\x0f \xd5@\xc9\xbf\xd1<\xd2\xeb0_\xbd\xc4+R5\xdfI{\xba\xd5L}\xafl]\x8b\x8cg\x0f\x0c!\xf3\x8fC\xec>\x1a\xdd\xab\x10\xa0\x8b\x0b\x96\xfd\x98\xcc\xb7\x11^\xf3\xdf\xad\xcb\xd8\x1d=x\xc0\x17\xd0}t@\xff\x8d\xee\x8b\x9f#\xf1\xff\xa1\xe7\x97\x05[wt\xcf\x1b\xfc\x95\x05\xef\x7f\x0c6]\xfah\x10]}\x99\xc9\xf7p\xe4\xb9U?\x8ePtV\xbd,C^\x0e\xa3\x83\xbb\x95\xf7[j\xea~5Y0\x0d\xfa\xd1\xa8\x1a\xbb\"\xa2\xf2\xd5\xe6g\xf8\xfa^\xd5{d!\xbcG\x0e*\xef\xf1\xdcr\xb0d9_\x91\xf2\xa7y\xc1\xbb\xc2\xec\xe4&gq\x16^F\x95\xcb\x1e\x9c\xedd\x83\xed\"\xcb\x93\xb4\xf2\xe9\x8a,\xca\xa5w\xed\x01d\xab^\x076\xaa)Y\xb8\x88\x8ag\x904\x86%qbx\xaed\xd3V\xd7\xe3\xf2\x98\x97FYg\xc9:\x05\xd6\xc0{\x13(A\xdb\x89\xbf\xa4q\x1bcj\x06\xf9\x88 \x0b?\xe0\x1c\x8e`\xe5.\xc4\xec\x1d\x01\xcf\x8e\xe7a\x0c&\x94}1\xfa\xb6HU\x14\x16\xb37v`8\xf4\xab\x8b Yy\xca\xedAK\xb2\xc1\x9c-\x0c\x83\xf4\xd1?d\xc7m\xb8\xadj\xa8\xee\xa3\x83\xa1\xe7\xaaV\xf1\n\xde\x12o\xbb\xef\x0d1\x96Q\xb1\x963\xb7\xcd\x18\xf1\x00\xf6&\x80\x96\xa5[\x0fs\x7f\xc9\xbb,\x8b\x94\xb1_P\x18\xa4\x17\x9e{\xe5\xf9\xf0\x80\xd6Yc\xff\x1fI~\xdf\xba.\xa6l\xe3\x9f\x8f\x0b\xad\xd0]\x977I\xbb!\xb3\xf4|\x08\x06/NN\x9e\xe3\x01\xba\x0f\x89;u(\x8e\xae\xe3\x83\xb3\n2\xfe\xdf\x92\xe5\xfc\xbf\x8c\xe5\xce\xb9\xdf\x00w\x12\x96n\xb5.j\xeb\x8c>\xf2\xb5x\xc1!\xc6L\xd2\x1a\xcf\x0d^\x1c\xa0`:'\x03\xc4\x1c\x9d\x10\xcc`@\xb0\xb7(\xd2\x7f\\,\xc4\xe1TSP\xe3P\x065\xbeXL\xd99\x8d\xc2\\Zj\x86|U@\xe8\x9b\xbc&\x8c\x0d\x97\x18\xec\x0e\x91\"\xa8-\x02i^\x8b\xe5\xffQ\xdfc\xfa\xbbs\xa2\xf0G\xa3\x87\x96\xc8I\x8dh$\x07\xc6\xae]\xd4\xbe\xf5\x10\xaf\x9d\xf8b1\x82\x1a\x7f\x10\x1c\xab\xc6\x96\x04\xbbz\xe4\xb9N\xb6a\xb3\x90\x95\xd2\x84t\x93\xd8\x10\xf8\x8cb\nj\xe5\x1c?LW(\x84\xf1I3\xa2\xa0}\x8a\x9c\x85PJBHK\\\xcd\xce\xe5\xa9\x1c\x08\x82\xa6\xfb\x90\n\x90T\xe6\x10\xf2\x18\x9a\x86\xe7\x9e\xf2\x1f\x12\x85\x8b\x1c\xf1\x92\x96R7\xe3\xd6T\xf6\xdd\x85\x03Z\xe7\xe1}\xe3\xfas\xf6o\xe6\xba\xc2\xcd\xb3Z-0\xef\xa6\x10\x1a\x86UaBH:w\xab\xef#%\xaf\x18\xa5\x86\xaat\xd0$5DnU\x92\x9b\xe3\xdb\xea\xc8WxxT\x86\x93\xaeR\x00\x1b\\`\xea\x07\x17\xff \xd2\xb1\xae\x1e\x10\x94~\xae\xdbN\xcb\x90\xb2\x04hrojg\xd9\x86\xa3P\x8cr\xe3\xb2A\xd0D\x94+\xe5\x19\x17F\x10\xf0j\xa5\xaa\xd9\x90\x0b\x98Zk\xd6\xc3\xaa<\xd2A\x16\x91|a)\xe8\x9c5 \x94:\x83\xcb\xa7\xa3\xc6\x15Z\x05\xad\x01\xd2\xa4\xc8\xb2W\xf4\xda\xd4b7\xf9B\x1e;4\xcd$F\xe7yT\xf5r\x99\x021\x10\xf1\xa5Y=\xbete\x1c\xc4|\xdb&'WT\x043\xd6\x01\xa0M.\xca%\x00\x18\x9cv\x0d\xb3\x11\xb5\xfe;\x07\x99\x88%\x90\x07\xa2\xb9\x8f\x97\x08\xf6\xf6\xfe\xbb\x9aTF\xfd\xe57(fe!e\\#u>\x84\xb6\xa9\xa3\xdbc)J\xa35\xc4\xeb\x96\x7f\x8d\xb0E\xe7\"$g\xd7\x8b\x9c\xdcE\xd8\xe0\x82S\xbcU\xaf\xe7\x83@r\xa2\xcc~a$\x04\xbc|\x97\xb9)\x8e\x88M\xc3ss*|\xfb\xd2\xa5n\xa4\x8b\\\xe6av\xdbv\xf9\xa0Gg\x80\x92\xbd\x04\xf3\x91]x\x97@\x9b\xec \xe2s \xbeR\xd2s\xeey\"\x11\x03I\xf71_\x93\x99\x1b\xab\x9c8\xc8\xe4D\xfe\x85X\x89\xfd\xc6\xbe,\xee3\x1d0Z>\xff\x88\xd9\x8bD\x0f\xa6\xa9\x9bgi\x80\x10\x1f\xa2f\xcc_\xd4\x91\xc0\x86\x01)YK\xd1\xb7x\xcft/\xb8<\xa1\x14'\xc4H\xbb\xc8\xc5\xa5\x9bt\xcaP9\x9b d7\x0dM\xa8\xd8c\xb8*P\xfb\x0f\xf0\x05$\x94\xaa( \x04D\x8b9\xa3f\xb6\x08\xcc\xf6\x06\x12L\xeeU[\xc9,RQd\x91Wf\x16\xf9fa\x16\x876$uW\xc3\x9b\xce\xf1\xf5\xdd\xa17X\xd4e\x13\x8b\xf9\xe6\x8a\xea\xdcm\x15\x82%\xa5$\xed\xf3\xd6$\x13_\xe2y\x003\xd8\xe6/`\x02\x97\xf5\xd7\xd7\x9c\xbf\xe1!!\xa30;f?\xd4\x13\x98\xc0\x05G\x86\x8b&m\xef\xc6p\x1e%@\xf3\xcaz\xba\x89\xcd\xba\x18\xad\xe7D\xe5\x16\xe1Rx`W\xa5\xf9\x83*\xf4\x85'\x93*\xb8\x1ez\"\xb9U\x95\xca\x83#p/0\x91\x8b\xaen\x1aqm\xc6\xbf\\\xa0j\xea\\\xcc0\xeb\xe2\xe0b&\xa4\xc1K\x9dO a\xc0\xebsK\x1f\xf2\xe9\xf5y\xcd\xca\xc0)\xc0\xca\xe5\xcb\xe9\xa3\xc3\x94O\x04\xd3\x173\xf4\x97,\xf7WA\xe6g,\xf7\xdf\xb3\xdb\xcc\xa7<\x1f\xbe\x98\x8eO\xb7\x0f\x1c\x99\x9e\xce\xe7\xa3\xe9&&\xe0\x16\x82\xbcnZ\xa8\xacu\xb2\xc1 \x8c\xe1\x84\x9c\xcdq\x03\x1c\x1c**L\xa4Em]}\xc3K:{S\xa8uN\xb4e\x16 \xbe\x9e\x9cn\xa1LA\xfa\xd5\xc2\x8d\x0br\x8e\x06\x07\x1a\xae:\xaf\xb3\xab\xec*\x0f\xd1\xc5\x8c\xab\xec\x05\x05\x1frr\xed[\xd5})\x0f\x15z{R+W\x15\x89=\x9f\x82H\xcd\xcb\x8b\xe0d\xe1/\xcc1\xf1\xf6\xb2t\xdc&\x9a\xd1,\x06\xbc\xb5\xfaPjP<&(^W\xcd=dIY\xfap\xed\xf9\x90\x95G\x1a\xe3\xadOe\xf0\xf1|\xd8\xb8b;n(G\xd3\x85\x0f\x89\x9b\x0c\xfe\x03z\x90\x0c\xfe\x8a\xff~\xe7\xc3\x8d\x9c\xf9\x9a\xb3\x90\xb3\xc9J\x98\xa4\xcd\xb0\x16\xa1\x1eTy\xaf\xec#\xe72=O\xb5\xe7\xc3\xfe\xf4\xa7\xa0\xff\xcb\xb0\xff\xe8]\xff\xab\x7f\xfb\xe3\x9d\xaf\xbf\xe9\x0d\xde\xfdt\xf1\x7f>\xfc\xf7\xf9~8\xc8Y\x86\xb9\xd7\xcc\x81Wd\x82\x97\xd9*H\x83Y\xceR\xceW)\xcd\x00,B\x16\xcd!\x0e\xd6\xc6\x9c/\xca\xfa\x94'?$\xd72\xaftyq-sn\xb6\x84t\x9e6\xeb\xd4\x99\xc1\xf1\x11t'$#p\xc5\x98u\xa4\x95\xac\x82\xd6\x10\x93Iv[\x957{[\xfc\x99'1+9\x88\xb5$<\x11\xb7\xa2\xccI\xac\xc0\xa8\xe2\x99\xdf\x1a\xbcF\xc4\x80+i\xc3rS\xb2\xb0\xd6\xb5\x92\xb2C\xbd\xdf\xce\xd9~\x0d\xde}\xa0\xa5\x02\x14\x97sJ\x19\xf2\x13\x0c\xfd\xb1S\xbe\x0c2\x1eQ\xd6bs\x82\x0c\x91\xf9\xbf\x1e\xcd\x14\xbd\xeaL\xddu\xe9\x8bM\x87\xe7>0c\xe86\xadG\xdc\x03q\xee\xb6d\xb9\xe6\x1e\xf7\"X3\xae\xfd\xef\x90!\xaf:\xd7\xa9)\xab\xdcGS\xe6B\xdb\x1e\x19|\x13A]k\x90\xd9\xf8\x95\x04-\xb2 \x0dR\xc6\xe7S\xcd\xdb\xf2,JY0\xbf\x05\xfe\xafc\xba\xcc\\\xc9\xef\xdfi\x80\x06\x7fF(K0\xb5\xd4LM\x81\xec\xd8\x8eY\x93r\x97\xcf6\xdbF\xb6D)x\xff}\xb7\x8c;\xb1\xcb(aZw\x1bO\xa7\xa52\xf8n\x82F\xf1\xf8Z\x15\xb9\x97\xcdT*FW\xa9\xdc\xce?\xf2\x01\xdf\xddg\x99\x96\xac\x96\xdc}:\x8d\xd0\xe0\xc7 \n\xda0\x86\x8cvCP\x04\x9f1\x8cE\x9fQ\x91\x8f\x98\x03\xecm\xce~\xa0\x0b\xbb\x0d3\xc8\x18\x81\xae^\xd5C\x15\xfc\x12'\xd4i*QS| \xc4S\x1d\xd6G\xd54\xdf\xad\xa7E \x0f/JY\x05\xe9\"UC\x12\xa0\xd0\x9c\xdd\x81yZ\x0eE\x91\xd9\xdc\xa0\xa6\xcbG\xf9\x05\x16\x89\x8e\xbe\x8d\x92K\xcd%\xbf\x9a\xecXo\x9f\x17\xed\xdc\xbeL~\xcd\xfb\x90\xe1g:\xf6#\x8bw\xeeK\xcf\x7f\xce\xfb\xab$@\xef\xd8\xad\\>u\xc1\xa2I\x86\xd0z\xd7\xd2mC)\x87\xd4\xba\xd2\x81\x86[\xe8\xf7\xc9\x04\\\xca\xec\xc0:4\xc4\"\xb7\xb9;5\xd6\xb79\xbdB{\x00\x03\x90&\xf1\xf2\xc8?|\x80==S\xb5}\xcd\xd0\x00\xb3\xac\xc8\xb2\x82U\xe8\xd7-\xbe\x95\xb3\xe15\xdbr\xab5\xac\x92\x1d)\x84+hm\x0b\xab1\xa7\xe5\x83\x05K\xf9\xdffI\x9c\xb38\xef\xd3\x10\xf1\xf8\xd6\x12\x04\xadT7\xab\xd5\xf5\xc1\xc9\xd9M\xbe\x8f\x01\xa9\x1es1>c\xf9\xe4\xed\x9b\xef\xfa\x0f1\x04W\x05\x8b\xe4\xe1\x98z3\x10W-Z\xbb1T\xe3\xed\x7f\x0e\x12\xa8\xd14N/\xd8l\xa2\x90\x92<\xee\xdf\xf4\xaf\xaf\xaf\xfb\x1c\xc5\xfb\xdb4\xa2\xe8\xfc\xf3\xea\xac\x8d\x12\x8c\x96a\x8d\x88)\xd1\x94V\xfe*\x8d&!i\xcc\xe6\xfd\x0d)d\xb4\xe44\xf6B\xe5E4\x88AY\x12]\xb1j\xb1.\xedi\xd0km\xb6\x15\xb7;\xf5$\xa9\xa4\x01\x0bg\xc9\x96k\x8cI\x8e\"\x9b\"\xbf\x98t\x17\x82\x0c(\x93]\xa3e\xa2\xcb\x989\xb6\x9d\x9b\xb7\x99\x04\xda\x12&\xb7nq\xc9\xaaY\xa5\x04Gr\xe79\x8e\xda\xf7\xa9\xb4\xfc\x02\xeb\xf8l]o\x90\xafXl\x8aM\xfdQ\x92\xdf\x9c\x88G\xeb8\x7f\x13Pl\x17\"`G\x11P>vQP>\x15\x91\x90o\xb3A\x16\x94\xcf\xc7_\x0bM\xba-A\xc9\xf3\xbe&\xfd\x91\xbfzaS\xcde\xdc\x17\xf2\xba\x1f\n\xaf{u\xb5E:\xdf\x9f+\x1b\xc7`\x91&\xeb\xe3U\x90\x1e's\xe6\xe6\xd3F\xd6+\xb5\x17J\x99`\xcbk\xfa\xd1\xb2\x10\x9dV\xee3\xd0\x9e\x03\xf8\x8eh_Fv\x0bE\xd7E=\xaa\xb1($\xb8Vt\xd2\xd1>\xc7\xf37B\xd5E\x03\xaa\xfe\x9c%\xf1\xe7\xb4\xfd\xa7\xb3\x97/(\x06\xaf\x95z\x95\xde\xdb\x94\x85Y\xab\xe7\x0f\xf9\xf5\xd1\xfd,\x0fU\x87\xfa\xfa#\xad\xd0\xad%\xc6\x08\x94`P\xdf\x8d\xb6\xc4\xb2\xba\xde Q\xda\\F\xf9T\xf1\xcd\xac\x94)\x95\xe9\xbf\xb9\x1a%\xe4\x83\xc2Gv\xa5r4\xc7\x98\x8f\\e\xd7\xf5\xe4NQ\xd6VlL&p\xa5\xf7\xc9\x9c\xd1\xdbd\xce\xfcR\x82\x18`\x9a$\xcc\xbb\xc2l\\z\x06\xf6\x8a\xbd\xc1\xb0\x87\x9a`H\xb3T\x06K\xf3\xf2\x1bf\x9f\x97~\x7f\xf8P_\xa1\x0f\x1f\xc0I\xd6a\xee\xf8\xb0W,NE\x98\xb2/Vn_\xacv\xd2W\x98;\xf3\xe4\xedf#\xed\xbe\x8d\xc8}\xabe\x1a\x87\xa7\xd0\xa7{H\xa6\x8c\xdd\x1f\xdd\\\x0eFN\xbc\xf8\xe9\xfc\xc7\xc9\x1b\xc7+\xefcN\x7f\xa8\xc2\xe2\x07\xe5\x9d\xc1W)[\xb04EI\x80\xde\xba\xd8\x0e\x99V+\x1d|\x7f\xf2\xecy\xed\x0b\xf9\xcbZ`\x1eUoN\xf90&4\x9b#[\xf8\x8f\x937\x90\xa4\xc0[\x939\x873\x13B\x10\x91\x93\x1a|5\x8e\x8f\x0d\xf7\x17\x1d\xac2\x82\x0c6Y\xed\xd3p\xedz\xf2\x8c\xfe\x8ec\xb0\x1a6\x9a\x11Z\xc5\x03B\x1e\xd1~cxb\xfe\xe0\xf6H\x0b\xba\x96M\xa5\x87YT\xa0\xad:\x1e\xdc \xe67q\x8c\x0d\xd8\x99g.-\xa0\x14d\xf8\xed\xeb\xd3\"&\x19\xd7\x91\x0d\xaf\x93\xeeq\xe1:[\xb77\xed\xfb\x9a4l(\xad\xf4\xfe\xbb\xf4\xe8]\xbc\xbf\xcbn\xd66k\xdc\xb4\xda\xe5\x8d\"(\xb2\x8b\x0f\xdd2\xda\x8b\x8d\x1b;\xcd\x0d\x82\xbeWi\xed\x0e\x82|>g\x0f\xe6V\xbe\x9a+_\xfa\xbf\x17\x82\xbbH\xd0-\xae\xeeI%\x99R\xd5SXs\xfe\x17\xe6\nC\xf7\x0d\xf9i\x0c\x07\xc3\xa1\x8c\xfe\xfa^\xfa\x85\x88\x8fO'\xfc\xab\"\xe7\xe2\xed\x138TU\x8a\\\xf8E'\xfcW\xad#,2\x06\xe7\xe5\x9f\xe5\xd8\xec\xbc\xc0\xd7\xb9V\x8e\xffc\x8a\xfc\xaa\xa1\xb1j\x17)/7\x1axDZo\x1b4\xaf\xac\xc7n\xba)a\x0cN\xc5\x92\x80\xd3\xb3\xe4Q\x92\x07Tcp\xceD\xcc\x88P\x06\xa6\x90\xc7T\xf8\x8a\xbe\x9a\x1b\xe1\n\xdb\x18\x9cB\xa1\xd1\x1a\xe1\x1aF\xf1\xb3U\x00\xe4O\x9e\xde\xb6\x98\xc3\xb4C\x07\xde\xbe_=\xc3\xd0\x9f\x8f0\xc3\xe0\xd4\xcd\x94\x174\x97\xca\x91\xbd-3\xe2T\xa3\x1f\xcbGJ\xd5|m\xc4\x9fM{\xa1\xa9\xdfcp4E\x83*\xd5\xd1\xd3,\x1a\x95\xcc\x84\x1eB\xce\x15L`\xaa\xe2\xd5\x9cJ}\xeb\xdc\xf1\x8b(6\x85\x1aV\x7f}\x1c\x05\xeb\x0d\x9b\xd7\xbf\x9e\xc6\xf9\xe8\xbe\xb9\x92\xe9\xfdi\x9c\x1f\x1e\x98\x8b\x9b\xde\x7f\x17%\x81\xfd\xc3\xfd\xbb\xe2\x83%,A\xfbuP\xf9H^\xc0!\x94o\xd2_Bv\xdd`~3\x03\x81y\x10*[\xaf\xb0\xd2\x86\x19o\x9cS\x88\xdd\x87v\xa5\xc4\xc1\xd6\x10C$.\x9a\x07Z\x87\x9aDk\x89\xd8D\xc5 \xd5\xca\x8eP\x94D\xb5\x9d<\x83\x9a\xae\xde)?\xbeu\xb0\xb1:Di\x05`\x82\xa7\xd0\x18\xfd\xd4\xc7\xe8\xa706$\xff\xc1 ^\xc5\xf8\x85\x93z\x97\xad\x17EU\x97|\"u\x9f\xf6J\xfbK\x96wj\\m\x9c\\ b#\xe4f~T\x9a'\xa5{l\xebx\x154\xfbFU:\x96\x1d\xd4\xc2Bs\xe8h\xeb+\xabL\xb2\x01\x02\xca\xab'\x80\xa0\xad}\xe9\xf3\xdb\xe1\x1a\x14\xd4\x02\xdc\xc8\x1e=\xeb\x1c)\xdc\x8d\x88L\x95\xfb\xc5\x18\xe3st\xfc\xcak\xa7\xf2\x861b\xd0\xb2\x0e&\x0bi]\xb4\xe5\xfb\xd3\xf7\xa3\xee`\xd0\x92\xea\x8d\xc9\xc8lfT\xc6\x8b\x89f\x93\x88>\x15\xf23\xfe\xf5'\xd3a&\xb6\xd3\xfb\x8e3\x11\xae\xd2\xbf\xfeT\xba\xed\xcb4\xae\xdf\xf7\x92O\xd3\x94*\x8eA\xda\x0cM.B\x86\x05\xb0\x9c\xc5\xdf\"\x9f\x7f~\xf2\xc3\xc9\x9b\x13\xce/\xb9\xc2\xee\x0b\xf5\xdc\x07\xe7\xe5\xab7\xa7/_\x9c\xf1?_\xbd<\xc3O\xaf\xde\xbeq\x0c\x0b4\xd3\xba\x9c\x89\xf4\x17\xad+\xaeIe\xd2\x13\xdc\xbe\x82\x97\xc9\xfcV?e;\x8dC\xb3+\x96!\x16\xf5G\x1f\"Bnm\x9c\x9ez9/\xbd\x9c\x7f\xe6T\xe6\x95\x93\xff\xa6I\x91\xf60\xd6\xb5\x0d\xbbFX\xa8\x1a\xe3\xaazb\xaf$\xb4\x8e\xb1TC4\xdd\xa4A\xf9\xdc\xa6\xd1X\xa9);\xac\xf2|\xd0\xd9\x9fF\xa2\x1b-\x19Y\x8c\xda\x17\xca\x90D\xb7\\\x84\x96\xc7q,\x83nDm\xa6\x14M\x9c\x85S\xf5|\x04\xb34$/\xd5L\x0f\x87#\x1f\x0e\x87\x07\xfc\x9fC\xfe\xcf\x03\xfe\xcfC\x03\xba\xcc\x07)\x9b\x87)\x05\xd8\xed\xc4\xd2\xb8\xa0.RK]jV>\xddZ\xf6:\x88\x97UwS\xa1\xd4\xce\x92\xb9\xf5\x80\xbe\x04\xba]\xf7\xa1\x0b\xc45+OQBG\xcd&\xeb\xa4|,\xea\x93\x11\xf4\xd8\xe0{\xa5r'\xfc\xe7k2\x08\x02\x86^\xe5?\xb3M\x12g|{\xe7\xfc7j\xce]W_[\xa3\x9a\xd3Z\xd3%\x17\xd0\xad/H\xe6\xb0\x97f\x1b[(\n\xff\xe7\x8f?|\x9f\xe7\x1b1\x0f\xbb\xa9&\xdc\xd13\x0e4\xeck.\x05\xda\x8e\x87\xad\xf4\xa9\\\x83\x101\xecD\xa4\xe4\xa3@g\xe3bN\xa7gQ$\xb7Ml\xae\xeb\x91\xb1\xc4\xee2\x02f$\xd5\x1f&\x8c/N*\x1a\x7f\xfb\xfa\x07G&\xa2\x0f\x07\xda[\x18\x03+\xfb\x93\xfcg_\xecG\x9fWj\xf1y\x91&E\xd5\x91\xa1\x17L\x0f(\x7f\xf0ejn2v\x05\x8f\xf1\xc1$\x97\xcb\xe7\xa3\x8f`\xd1\x99\x1a\xcb'\xad\xba\x86\xbe`\xf9u\x92\xbe\x97\xe6uX\x04a\xc4\xe6&\xdf\x0f\xf9\x88\xaes\x8a\xfe\xfd\x0f\xe9|\xc3b7Q\xc7Q \x9d\x7f\xe1\xe5&'\x8cg\xd1v.\xe2\xd4%\xa5\xd3\x1e.Y\x85\x18\xa5\xec\xb8tND\x15\xd5\x16\xddn\xe46\x96|\xc1\\m\x17\x05\x17!/\x0c>\x00 B;\xf9G\xcb'\xe4\xea\x95\x80:B\x03\x8b\xbb\xb4|0j\xe4 c\xf1\\\x0f\xa6\x9ah\x87n*}\xa0\xf6\xd2&\x95\x9a\x89-\x92\xcf\xc1&\x89n\x17a\x14\x99\xbc\x82\xd5_\xae\x9e\xc1\x163[\x90lQ\x8d\x85\xf6\x07\xd1xiqv\xbai\x94\x9bn\x19\xdd\xbb\xeb\x0d\xc8\x98b\nd\x1b\x1a\xb7\xc0lQ\x14\\\xc0pLQ5\xd5J\x13\xa2Q'\x10\xcd\xa4*\x8d\x9b\xf4\xc6\xe5\x03\xd1|\x13m\xeb\xa9\xfe\xaa\xb6\xd0\xc6\xcd\n\xb5\x18\xef2\x89\xec\xdd\xf2`W\xf9Ml\xe9\x9eQF\xffE*KN\x910\xdc\x9a&\xe7J\xc4\x1b\xcd\xe0I\x11N\xfa\x88k\xd6\xc2\xbf\xe2Y\xee\xa2s\xfd\x8b\xe0E\x9d\xcee\xd7!\xae\x9a5\xdb\xfd,\xc8\x18\x0c\xc7V\xc0\x97\x0dX\x8f\xd7\xe5\x83\x0d\x1d>\xb0\xb7$\x1f-\xd9\x80\xb8z\xd5\x10Y@>\x98\x86\xad\xb9\x18\x0e\xe0\xeea\xfb\x00\xf0J\xac\xcb\xd7\xf4\xf0\xa0\x85\xdb\xc8\xc0\x86\xadm\x06\xd3\xa8\xd73'\xea\x94\x8fY\xf2\x82\xe6\xc9\xe1\xa4F\xf6\xfe\xb9\x0c\x1b\x92<6\x83\xa7\x13\xb8\xfb\x90On\xc6!\xeb\xde\x03\x0f\xd7z\x06}\xb8\xfb\xd0>O\xe5\x95\x8b\x0d\xdc\xbf\xa7\x1ax0,\x1a\xb8\x7f\x0fz0\xb2\xdc\x10\x86\x1d\x1ch\xa9\x97G\x0fT/\xa3\xe1Ac\xf0<\xf9\xa8\x15>|\xe0k\xcb-p\xab#\x045\x96\xb2o\x10\x08\xb0\xe5+\xf1\xe8\x01\xae\xc4'l3\x1f\xe8\x81}\xa0mPp\xd0\x0c\x05\x82\xc4\x98\xa0 \xfd\\(H\x7f\xe7P\x10\xea\x10\xf1\xeb\x83B\xfa\xd9\xa0\xa0F;\xba\x0f\xdf@\x0c=\x93Q\xfd\x0f\xf6_\x82\xdf\x05ER\xe2\x08\xfaz\xea\x94\x8f\xbe\xc6\xca\xf8\n\x15\xab\xa2XVP\xf2\xf2;\xb8w_2\xaa\xc7\xb0\x85'pp\xef\xfec\xe8\xf5\xb6\x1e\x04\xd3-\x86#\xfe\xa3\x03=p]\xfeqt\x1f\x8e\xc0\x19:\"]r\x0f\xb6\x05\x97\x1d\xdd\xf7<\x9b\x87\x8d\xcc\x9e\xd6hFo\xb8E\xd9\x9b\xf0\xfe\xca[\\\xf2ft\x9cR\xceP\xe1\xac\xc8\xb4T\xc5F\xcdRj\x94%\xb6j:I!\xf0=<$\xf9\x8fkNw\xefi\x7f\xdf/\xfe~\xa4\xbd\x1f\x1dh\x1f\x12\x0e\xfb\x87\x8f\xf8\x8c\x12\x0e\xfbw\x0f\xd4[B\xdc\x84\x10W\xbd%l\xc4\xb7\x8f\x86\xea-a\x0f\xbe\x1d\x1d\x1cX\x04xtd\x80>\xc4*\x1dh\xce\xd7P^(BE\x9b\x8b\xd3|K\x0f\x1e\x12\xbdO9T\xfb\x80\x05\x83ib\xb1\xdd*\x82\xc1\xeb\x1e\x0c\xef\x1a+\x8f\x1e\x1d\x00\x0e\xf7)\xdc?\x87\x1e\x7fs\xf0\x10>\xc0\xfdC\xb8\x03\x9dZ\xbew\xef\xe0\xd1}5\xe7{\x0f\x0e\xef\xde5utppWv4:\xd0{\xa2\xbe\xe1\x0e\xdc?\xdcm\x00\xcd\xd6\x87\xb0\xc1v\x80\x10\xd2\xeb\xe9pW2*\xbd}}*\x94\xb1\xb7\xafOa\x1dD\x8b$]3\xab\xdb!\x08\xfb\xc5hx\xc0\x07]\x81P\xdf\xb4\x18w\x87\xf0\x81\x12\xc5\xdd\xbfw\xef\xf0>b\xad\xa8\x9ex\xf0\xe4 \x8cx\x81\xd0\xf3p\xbd\x1e\xd6\xd6ktP[\xb0\xe6u4\x0e\xbc\x03\x01+\x02\x890\x8c\xfbT\x12qs\xe8\x15\x80\xea\x95c7\x96\x15\x95\x96\x88\x05\xd4\x97\xe5\x8e\n\xef\xd8\x94\xb9\x85#K\x98}\x17\xc6!E\xe4:\x02\x87\x93?,~\x99$\x11\x0b\xe2zSG\xe0\xe4\xe9\x96!Y\\\x04QF\x7f9\xfa\xb8\x0b:,\xf5\xa5hw}\xc9\xae\x1e5\xc51,8\x02F\x1e\x18vQ\x87h\xd1\xc2\xc5-&\x0c\xa4[+U\xa5\xc8\x9c\x0fX9\xf1:w\x04MF\x87UgR\xb9ht\xa5\x12\xfa\xd2\xd8\xca_\x89\x0e\xd8\xa2\x18%bD\xba\xe6H\x96\x03<\xb3\xa9\x7f\xe4\xf8B\x99b'\xf6d>\xa6%,qM=\xe3\x83\xcc1\x1c\xa8\x88$\\\xbd\xdbrvL\xd9\xf29GZ\x10+Z\xc0\x13\xd8r\x1e\xb4h2\xe1S\xaa\xe1EC\xa6\x879\xa5$n\xc9\x16\x11\xba\x19\xe6\xb7\xedU\xd3A\xca\x87\xafm\xf9\x12\xf8\xbcQ\x08Skp\x05\x13\x98\xab\xf9\xaea\x02W4\xdf%\xcds O\xe0\x8a\xcfs\xe9\xc1\x8c\xd3\xa4\x15\xf4p8\xf3\xe9\xf2\x9c\xf3\x1b^`-\xd4\xb0\xde\x04\x9a.V`\x08+\xbep\x91^\xdeLp\x88r\x97{\xe4\xdd\xb5W\xaf\x8bj\x02gf\xedDL\xc7o.v\xa1\x8f<\x024\x995\xbe<\xba\x04\x86\x88_\xa1-\xea\xc6\x87\x0f2[\x8fdFJ|,\xb7`\xa8\x9d\x17\"CM\xec\xba\x12)\xf1c \x08\xb5%$\x8fp\xdbW\x8e\x1b#vXn\x94P\xbdN\x8e\x93\xc1:\xb8\xf93\xbb\xcd\x94\xee\xae\xde\x18\x86\xc5\xd1m\x04\xfbU\xb5p\xa6\x84 ^`f\xa8\xb8\xc1m\x93T\xd2443\x15\xaa\xdb\xaf\xb0\x9b\x0d\x8e\xb3\xfe\xd1&\xc0r\xbc\xde m\n}D\xe1\xe9\xb9\x8f\xc86$,\x1b\n\x0c\xf3\xf1\x94\x99\x13\x96K\xf1\xff\x05\x9d\xc1\\\xd3\x7f'T\xe8\x86\xb0\xf1\xa6\"\x00\xdf\xd8\x04\xe0\xb3\xaa\x00|c\x11\x80\xcfp\x8c\xb9^tm\xa5\x1c\xbc\x82\x18<:]\xb9\x87\x0f\x10\x1c\xcf\xe0\x08\x07:\x821\x9c\xa8\x9d9+\xc4\xe0\xb3B\x0c>+\xc4\xe03RJ\xd5[\x12\x83\xcf\xa4\x12 G\xc0es\xe8\xf5(\xc2\xda5Y\x9b\xb1\x8f \x86\x91\xe6\xb4\xc7j\x0e\x035CJ\xba\xa2\xcdp\xd9\xaa\xa0\xf2\x8a\xbd\xde\x12\xabn=\xb8\x82'\xe0\xbe\x87 \xdc@\x1f\x96\\B\xa38\xd5\xb7\xba\x04~\xe5\xc3{N\xa2\xc4\x96]a\xf1^\x9bIl\x96\xc4y\x18ow=\xe6\x03\xe1\x0d7\xe4\x00\xf3\x9bo\xc5Ee+\xcc4\xdc\xf8\xf6\xee\xa1\x18'o\x077\x10\x8e\xc0\xe5\xebz\xa5\x86[]\xd6\x1b\x0f\xe3\xa9q\xd2\xf5\xc7\x83\xa1\xc0\x11\xea\xbfR\xf3\xd2T\xf3R\xaby-\x8f,\xd4\xf6\x188H\xa1\xb7\xf4zk\x1cn\xd6\xc4\xe5\x8f}\x90\xb0\xb1\xb6o8oN\xce\x97\xc3\xd3{\x1b\x04\xc1X\xfb^\x9d\x10B\x98\x8c\xf88\x81\xc8\xbd\xf5a\xc3\xdf]\x8b\xe2\xfc\xdd\xa5x'\x8e\xc4W\xeaH\xfc\xd6\xf3 \x98\xde\x9ec(KXMW\x82\x96\xf0\x17\x86\x9bY 4(\xf7\x18\xe5\x98\xdbsO\xbf\xa6\x85r\x06\x1c\xc1\xf1\xf4Xk\xe6\x12\xc6\xb2\x8b\xe9\xb1\x0f\x97\x16\xc5\x8c\xaf\x06\x06\xf5\xea\xf7\x17^\x93\xc1\x8cou\x99\x16\xdeb/D,\xd5.\x12UE\x8c\xa8\xef\xe7\x1f\xec\xbf\x16\nt\xaet\x95\xe5\xc3\x07X\xf2/^\xfd\x93\x0e\xb7\xe5\xdd\xe3;\xb7\x86'\x90\x19v\xce\xfb\xcc}\xe3Hb\xdd9D\x84\xcf\xd9\xa3\ns\x90B\xc5\x1f\xcak\xd69\x93\xc1#K*\x83\xc3\x87#\xaf\xfdtO\xba\x13\xc8\xebpp\x04\x7f\xffH \x0dAB\x8b\x91\xeb\xc7e\x9d2]\xea\x03\xaeF\xd5\x13\x03\x1e\xb6GI\xb4'\x85HE\xa7\xad~p\xa2|\xe2\xb2Z\xfa\xb3\xd6\xc8p\xd69\x8d\x0e-s\xba[M[D\x81\x05\x1f<\xea2U\xc3\x0cJ\xfaT\x7fD:\x94\x12\x16Qt\xfc\xfbG.\xad\x04\xa83\xd9D\x16\xbc\xf01\x0d,\x9a\x10\xe6\xe9\xe3#\x88\x0c\x82L\xec\xce\xf8\x07\xa0\x98\x81>\x84nDA:g6\xbd\x18\x8aU\xcfv[`\xf3\x19\xeb\xfe7{E\xdb\xdf\xc0,I\xde\x87L\x7fs\x9cln\xd3p\xb9\xca\xdd\x99\x07\x07\xc3\xd1A\xff`8\xba\x0b\xaf\x93u\x10\xc3\xd9*\xbf\x8d\xd6A\xdcT\xe1\x1e\x1d\x9e#\x0f\x99\xa3*O\xfcf\xc4\x99H)w\n\xc4\xd3\x0d\x95\xc3?&\xb0u\xe7>d\xed\xa1)M8SI\xe4\x9d\xb14\x0c\xa2\xf0\x17\x93~\\],E\xa0\xc4v\xd7WZ7O}\xf8P\xbdm\x88pY\xa8n\x05d\x86\x16\xc8L0\xa9\x1e\x88\x06\xc3\x0cB\xf2\xfe\xab\xee2\xeep\xd0\x12\xa8R\x81y\x1c\xac\x9b\x1a\x93\x1auX\x8b4A\x07|\x18\x9e\x9b\xfa\xda\xb6\xf6u\x15D-]\xe1uu\xe8\x813q\xa0\x07\xdbz\x8f\xc2R\x06)W\xb5\x9f-\xadW<#(\xca@\xdft\x18\x8b\xc7\xd4\xd9\x8b\xe0\x85\x1b\x99\" \x89\xaa\xd9\n\x831 \x0dxA&\x00\x03\x14g(\x98?\x86\x1f\x83\x9b\xfe\xb3%\xc3\xc1\xff\x18\xe4\xab\xc1\"J\x92\xd4\x8d\x9a\xa87\x1e\x87\x0c\xe6\xc9:\x08\x8d=\xe8o\xb0\xd7\xe4\x15$'(\xfa\x98\x9cUe\x9b\xea\xd3\xe6\xdd\xe0D\xc1\x8d\xb3C\x87?\x047\x9f\xd3\x9b\x90\xc5v\xe8\xf0sf\xd8\xeaF\xd4\x04\xf4j\xbfu\xa8\xaf\xb5\xd4\x81\xffj2k1L\xc9Y\xebF\xca\xba\x1aP?N\xa9\xab\x04\xfb\x8f\xe1\x9b\xfd\xf2k.\x9a\xed\xff4}\xb7\x1d\x0e\x87\x8f\xf8\xbf\x07\xc3>\xff\xef\x01\xe3\xff>\xa4\x1f\x8b\xc5y\xef\xdf\xf6M\xc7c\xdb\xdf\xeax\xac\x1a\x93\xb9\xfc\xd7'I\xf8\x1dC\xaa\x8b\xfek\xcb\xeb2-\x1c\xc4t\xefk\xd7\xfb\xe6|\x7f\xd9\x16\x8b\\\x1eK\xa0\xbbF\xc9\x9e;\xf4J^\x1ae'\x8d\xf2\xec\xdb4H\xbd\xe3n\xb3,\xb9i\xc8\x1c\xf32+\xb2\x92\xc7c\xbb<\x9eV\xcd\xd3\xb1E\xe4N\xd1U\x00\x1d\x07\xee\xdc\x81\x14m\x97\xf7\x0fG\xe8q\x11C\x0fF\xfa\xc9|\x83X^s\x08\xc1\xca\x16\xc1\x9a\x0e*\x9fbW\x07h\x1c\x12n\x1c\\un0\x1c\xcb\xe3\xcf\xd1\xf0\xe0.|C\xde\x1a8v\x0fz\x90\xf0\x1f\xd8^\x8f\x8e\xf2\xed\xe4'\xa7\xebp\x07w\x87ey(\x84}\xb8\x7f\xb7\xf8\xc7\xf3at\xf0\xd0Z\xc6\x83?\xc2\xfd\xbb\xd62\xe5\xcf!\xfeB\x1f\x84^\xa3\x1bg\xa3\xbd\xban\xf25\x9c\xc6Qh\x89\xbb\x0f1B\x04\xcd\xf4\xe0ny\x84i\xf3$S\xc3\x04R\x9a\x00\xe7\x97\xbc\x03\xfeR\xb5?zt`l\xa0^WTH;\xd8\x0d\xda\xd2O\xea\x90\xb2gw\xf3\xe7@\xc3la\xf9\xedF\xb2J\x91\x86\x0b\x96(\\\xa6z\xfe/\xcb\x19\xb2\xc4\x93\x86[d\xa1\xddAs\x9e\xb4`F\x80V!v\xc3f\x8d\xa9\xc5\x94\xb62\x99L h4\x0d\x83\xd2\xcbCx\x02\\\xbao)\x9c\x90S\xcd\xf0\\\x19\xa7\xc2^\xcf\x0c\xc8p\xbd\n#\xa6\x14'>\x14s\xbb\xd2v\xc7\x81N\xf3x\xe9\x8f\xcc\x19r\xfe`\xdfIK\x8a\x00\xd0\x9d\x04\x85v\xbaS\xbb\xc2\xach\xa3\x8eZz\x8d;\"\xbd\xc1\xd4\x99\xfet\xee\x9c\x97\xcd\x07d;\xe0\xa2l\xcd\x9e\xa3\xda\x12\xa4\xbd\xed\x92\xf0\x0ea\x81\xb0\x1a!%\x1bd\xc96\x9d\xd9\"Fx\xbe,\x18\xca\x82\xe48\x98\x0efI<\x0bD\x10Gv\x0d\xaf\xd9\xf2\xe4f\xe3\xa6\"\xe0\xcf\x07\xc7\xab\x99]\xc1H\xba\xd8`\x11\xc6\xf3\xe3U\x90\x9e\xc6sv\xd3fB\x93\x0f\x87\xd1\\\x87\x0f\x85\x89\xfd\x86\xb3\xa22\xceZ.>\x95,i\x89\xeb\xf9\x02E\x0b\xd7\x98X\xa2\x1c\xda\x1c\xdcx\x10\x05YN\xc3\x7f\n\xb9\xf7\xd8\xe38\xd0\xb8]\x86\xfc\xcc\xbeX\x8aoos\xb6\xd3R\xc8\xd9\xf0\xd5\xc0\x1b\xb4\xb4 \xe4\x95\x858\x83\xf5q&\xe6x\x8b\xc4\xc5\x9fu\xbe\x1a*\x17\x87n\xa6\xebc\xa6j\xf6\x0d\xe0\xd2\x0c\x9e\x88\xc6\xc6\xbd\xb3EY.\xe4\x1b\xe5\x98\xc9\x85\x8d\xea\x89\x88\xfe$\xe8t\x84\xfb\xd4\x92~KQ\xc6\x84\xeb\x8c\x94)?\x99\x0e\x8dq6tyg\x97\xd5j\xbd)\xa3?r\\Hc\n\xdc\x92(\xe8#\xb50\xee%\x7f>\xb6\xedA\x8a\x06W\xd9\x8b\xf1^\x0c\xd8D\xbc\x96\xa5$\xa9\xf2\xc9\x84\xbcA\x92B\xb4+\xcd\x89\x8f\x15}?\x87\x9e\xafdN\xe95\xca<\xa7\xd0=\xa8\x07\xee\xa2Q\xe0\x10\xde$\x9c\xf4\xbdJ\xc2\xb8\xc5\xe6!\x9f.\xb6\x0f\\\xdb\x99lW\xae\xb1\xc6=DjIU\xc4\x13\xd6\x12\xa1~j\xef\x1b\xa7o\xe1\xfajBo\x84\x85\xe8\x8bM\xac?\xb9\xcf\xd7\xf2\xf9w\xdf\x9d\x1b_\xeek\xbb\xfeQ\x1c\x16t=\x13\xf8\xba\xdf\xef\xbf\x8b1\x00\x96\xb3\xca\xf3M6\xde\xdf\xdf\xb0\x1c\xf3\xdd\x0f\xb2\xeb`\xb9d\xe9 L\xf6\xaf\x0e\xf6\xe5\xaf\x9f\xb3$v\xde\xc5\xf3d}\x11\xce\xc7\xe0|%>\xf4\xb7\xa1\xf3\x8e\x0e\xc1\x82\xd2>\xab\xa60\xf2\xc15-\x07\xf4a\xe6\xc1>$\x1dg\xa5?ie{\xb4\xa3\xc0\x0cz\x10\xc17d\xee\x1d\xdc\x83#8\xc08\x0e\xdf`$&\xfe\xbf{\x17\xfa\xf4\xd2C\x95\xd2\xa6\xe0\xd8\x9e\x02Py\x17#\x0e\xac\x08\\\xdf3t\xef\xf5\xf0\x00\xf2 \x10`\x0f\x88L\xd37.\xb1\xa0\x0b\x90\xbe\xd2\x81\x0f\x8f\x1eiPo\xc7\xce\xea\xf3\xd1\x87G\x1d\x8b\x7ft\x9b\xcb\xd9/%5\x90\x84h\x07S\x85|2wK\xf1\x9e\x8dG4\xf2\xb1\x84\xb4\x93\x8c\xc8N\xa4X\xbe\xdd\x8c\xbb[\xbb\xa1h\xd4\x1571\x91*y\xeap\x8c\x8fU|B\x87\xe6\xdcS\xc6\x9d\xdck\x8a\x1d)\x1f\xe1`\xf4|\x9b\x8a\x00\x90q;\xb8\xb3\xf9\x92\xbd\\,2\x96\x9bBz\xeb\xcf'\xed[\x9e\x8c\xc1\x92\xab\x80>\xff\xd7\xb8\x89\xd6\x85q\x9e\xfc%d\xd7\xe5u6]\x9c\xad>\x92Wc\x9c\xf0o\x93m<\x0f\xe3\xe5q\x14\xb28\x7f\xcdf\xb9\xeb\x0dV\x88'\xed+\x14H\x8a\xae\xf8Z\x0f\xc2\xf6j3YM\xe2j{\x95\xc5N\xbcc\xc3Q\x02zm\xa1n0\x05\xf2\x13Xp\x88\n\x91^<\x85\x19\x1cQ\xbc\x01Z\xc91\x04\xe2\xc3\x06\x8e s\x03N/\xf9\x9b\xa2\x00\xb1\xd2\x06\xccn\x80\x81\x19\x8bs\x96\xd6\xb60\xed\xb0\x8b\x99\xdb$]\x94I\xe1>\x1c@\x8f\xa3\x0b\xc7\xaa\x96]\xe7\x85=OL\xefS\xe6\x94\xe5\xc9f\x0c\x81\xbd\xc0:\xb9\n\xe3e\xc7\x0c\xfcP\xd0\x86\xbd\xbd\xfa!\x90|\x1a\xc6\xc3\x81f,\x80\xa7\xb1\x14.\xdfX[Jca\x833N\xbdUN\xb3\xa4\x14?\x90\x7f\x9cDl]s \x04\xc1G[\x17C,\x82\xd0E\x88\x9f\xfd\x17\x1a\x91\xc5\x8f7\xc9\xa6\xcb\xd0\xd0j\xef\x9a\xfb\xa0x\xd7j\xe0\xd4n\x18/\xc5\xc8yo\xea#/k^N\xa4\\\xddd\xe5\xd2l\xde$\x1c\x92wL]\x81\x9bkIN\xa9P\xa0#\xac\x95\x978\x8cc\x96\n\x89\x01\x97y\x86\xc8Bov\x1c\xa3\x00\xadn\x8b\"\xf5T+\xa2\xe6\xc9\x86\x93 \x14\xde\xe2A\x82,\xca\xb4\xfb`\x06W\x83\xb75\x06%\x0drv\x86\x1bQ\x8b\xeah\xa3G\xd2N\xd5\x08N\x96D2e(i \xcb\xaf \x9c\x03\xef\x8ek\xff_\xbb\xed>k@'h\xec\xe8S`M\xc9\xe7\xac\x04^~' \xdc\x15S>\x0d\nw\x86/\x01/\x7f\xa8\xbct\x82\xf9\xfc\xe4\x8a\xc5\xf9\x0fa\x96\xb3Xd\x0c*L.{b\xcaq\xf2\xff\xb2\x98\xcc/\xf8\x9a\xb9%\x9ac\xbc'&E\x1ag\x15fy\x92\xdeV\xad9\x9bm\xb6:\xcb\x83\x9c\xcc<\xa2\x90y\x9d\xb8L\x13\x92 \x08\xe1\xe05\xe3\x85Qj\xd4+\xd7%\x0b\xcaT*>\x0fj\x95\xf9\xe8\x82m\x9e8\x9e\xda\xdc\xea\x82\xb8N\x94\x04s\xc7o\x87 \xeakWE\xb1ql\xeb \xde\x06\x91%\x86=Wq\x1a\x86\xbdI6\x19\xaen\x9b\xe7\xb5|\x18\x86\xe8&K\xdc/,\x16\xdc\x8cRH\x15\x9f\x12T\xf1\xc4\x8bAQ\xce\x06\xf7\xb0\x87\x97\xf3\xc40e\xb0\xf7\xc1*\xc8\x10\x92v].iUL\x06\xa8\xd0\xb8\xde\xa0\xd0\x08\x9aO\x0dZ\xedC\xd2h\xa7 {\xc9\xa4x\xf0\xed\xed\xe9\xdc\xadM!e\x0b\x99\xc1\xef+\xc7\x9b\x8e\x9a\xf2\x05\x83t\x8ek\x1b\x05\xd4\x0c\x05$L&\x850\x99s\x1e\xc3:\x88\xdc \xe4\x98D\x08\xe9\x9c5\xb5+\xf4Cx2\x81\x14\xc8 \x1d\xd0\xff\xdc \x124\xa8\xa8\xd0\xac}\xd9\xa1\xd9D\xb6\xf6L\xae\xebW2\x8aO\xe1\x86\xe5\xb8?}x\xf7.\xf34J\xe5\xbe{\x97}\xf87\xcf\xe4\xc2i\xc5\x9aY\x14\xce\xdewB\x99\xd2\xb1!\x1b\xe4A\xbad\xf9c:\x89q\x9e9\"\xd8L\x1e,_\x04k\xf6\xd8\x13G\x9f\x9b eq\xfe\"\x997$\n\xdfs\xf7\x90\xb1\x8c(\xe0\xd7\xe0z\x15\xceV\xa4&`\x1a\xc8?\xb3[\xfa\xb5fy\xa0~\xcc\xf24R?\x82\x88\x97j\x8c\xfd\x82\x16\xc86h\x94\x90\xa8\xa8\x94\xa2\x10\xf5\x08d\xe52G\x95\xdf\xe3\x9a\x91\xbc\xfa\xc4\x1a5\xd1\x80\xb6\xb9R{\xca?\xd0\x88\xac\xb8\x96\x82\\\xc7\x8d\xeb\xe7k\xd5\xa7\x94\x02pW\x90\x06\xdd\xc5\x0b\xb3\x18\xe4y\x1a^ns\xe6:\x9cv8\"\x85A3\xd9\x12\xc6\xfe\xe2\xce\xf6W\x0e\xf9\xb7n\xc9C:\x1f\xcc\xa2 \xcb8\x90\xb5\x86\xfa\x91\x06\xdf\x06\xb7w\xf9D\x0d\x840-\xdcZ\xdcQ\x9b\x89\x10\x8fW\xber\xc4\xd1j\x87\xbdB\x0c\x88\xe4\xd1J;\xb9\xca$\xac\x10q\x8c>\x95.\x01egJ\x19'\x08\xcf\xc94\xd5\x06}W\xe2\xcac'\xd6\xa5?\x15^\x02\x93\x16c\x164\xab\xd3\xf2Y\xec\xcc\x19\xa9\x16]\xff,3\x9c\x0c\xfa\xb0@/\xeb;\"x\xd9N\xb3\x94(\xa7\xa4<\xf7\xef\\\xdet\x8c>^\xfa\xf3\x11C\xbb\xa2\x94\x91\xf9\"\x83\xf4\xac\xc1\xe8af'\x16V\xf2\x07{!\xe9\x07\xa7^~t\xcb\xdea\x18\x9e\xd1\x18J-\xc5[\xad\xc1f\x13\xdd\x92\xa7 \x8c9\xac\x7f\xf8\x00\xae~\xa2\x1c\x9a\x0f\xa0;\xdd\xc9\x13\xc1\x1b\xe9\x94\xb2\xc8\xc9\xe7\x83sq\xc1\xb2\x1f\x93\xf96\xe2\x92^y_0}\xdbX\xcf\xc8\xa0\xeb\x99\x926m\xdc\xd8\xbd\xeb\x19\x02\xa8\xf0\x0f\x07\xd5\x0f\xa1\xf8pX\xfd\x10\x88\x0f\xf7\xaa\x1f\xb6\xe2\xc3\xfd\xea\x07L\xf6\xe0\x0e+o#,^MJ\x85'G\xbc\x15\x94&\xf1\x0f\xb2\x88\xb9\x87\x0f\x1fT\x1b^P\x94\x17\xcft1\xd3\x90\xf4Y?\x83f\x83b=E\x9c\xd5:\xac\xcb\x9b\xb1-\x97/A,2E\xbdX\xb1h\xc3\xd2l\x90lN\xe7\xe5\xe1\xb6;\x02\xaa\xd1\x0b\x7f:\x0b\xfe\x91\x9c(F\xe7\x89Lj6\xcf:\xa9\x9e\xf1JA\xb5\x92\x9b\x0f..0\xfd\xd9\x05\xc5\\\x1b\xfa\x18\x19R\x16\xf2<\x91#\x11K\x93{g\xe3\xc1D8\xc8\x93\xe52bg\xab\xe4:\xeeJK\xa4\xb0\x1f\x0e6i\xb2i9c\xcc\x85\xd3\xeem\xb2\xcd\x9fa\xdb-\x15b!\xb7-\x9b\x8b\x91\x97\x1cG8$\xd5\xd5\xcd\xab>\xc25;\xc3\x896\x17E\xad\x96s\xae\xd7,K\xa2+6?\xdb^\xe6)k<\x0f\xc53P\xcd?'@;\xf9@$\xc6\xa95\x84!KV\xc9\xb5;u\xd4\x0c2\x87\xec\xd9\xe7>\xec\xd9\x9c\x9a)u\xcfq\x10\xcfXt\xccE\xe2\xae[\x869j\x04\xbdo\xde\xae\xf4\xf64\x7f\xb9\xcdO\xe2\xe02b\xf31\xec\x85B\xa7\xac|\xb1\xb6b\xc8H\x03\xc5\xd8\xdf\xa4\x1c\x10v\x1a\xfb'\x80[\xb6a\xb3\x1d\x80m\x13\x98b\x8a\xea\x0fA\x1be,j\x10\x0c\x7f\xcbU\xe60\x84.\x1b\x7f!\xbf$F\xc9\xc11\x87ejs\xab\xa3M8\xb9a\xb3m\xde)q\"\xec2-F\xed\x9e\xc6\xaf\xd2d\x99\xb2,\x1b7&\xf2n\x18c\x1d\xfb\xba\x0e\xf6\x13\xa1\xe5\x8cEl\x96'\xe9\xaf\x00/]\x08\x13\x1f\xc2\xab _\xd9aK\xdd\x07\xc0\xac\xf6\x1b6\xab\x12\x15.\x9b\xfd\xe9\xcc\xf5\xe8\x12\xb1\xa9\xc4\xd4\xe1\x03Wt\xa6a\xf9\xcdt\xebW\xde\x82_\x0da\x7f\x85\x0d\xb0\x10\xf6\xf2\x1eX\nu\xdf\x06R\xd1\x9b\xb2\x00\xd6 \xc9\xc8>[\x13zZr\x8a\xfb\xa6;\x97\xb57\xca\x11\xc1\x87\xad&\x85\xf8\xc2\x07\x81OA\x7f;5\xcf\xe3=\xbb\x1d\x83\xb3\x0e6Hb\xde$\\\x8c\xce\x1c\xf34\x84\xe8\xdc\xd9]B\x1aJ\xf2A\xb2i\x07\x98\\\xc8)\x1d\x89A\"\xc4\xb4\x9c\xdc\x1d\xe3E\xb8\xcc\xbc\xb63w\n&?Of'7\x9b \xce\xc2\xa4\x834\xc2\x85G\xb6\xf9!\x8c\xdf\x87q\x8bX\xb4\xa5\xe2a\xb6\x89\x82\xdb\x97]\xa5\xa3L\xaf%R\xd9I\xff\x8f\xe6\x9a\x11\xa9\xb6\xdb\x0d\xd7\xa6\x10\xc6\xd7a\xfe#\xa2]\xcb\xeaa'OO\x16\x83\x1f\x83M\xab\xd2\xfe\xb3\xd0\xf4\x17x\x13\xfcOg^\x0b\x8b\x03T4\xc6p\xda\xdc,\x7f\xf2`\xd9\xe9\x86\x05\xa7\xdfV\xef]\xfd\xc9\xa4\xee\x91[\x14-\xfa.\xf4,\xc7\xc2\xdd\xf4g\xce6)\x9b\x059\x17\xf1OI\xf3-^9B]3\xf6\xa5\x15\xa3\xee\x9a\xccS\xf2!\x0e4\x86\xa4\xbdh\xa1\xa7t\xb8JQ\xd6UZTi\xa8\xaa\x8a-j\x19\x96\xaf\xdb \xc4\x82u\xb7X\xb4\xf7R\xd2/;\\\xf0SzU\x8b.\ne\x15\xaaE\xf6\x80\xbaN\xd9B\xf2AW\x81Z\xf4O\xb0\xe8\xc6-\xda(4\xe8\xc7-B\x12X\xd5\xfd\x16\xce\x0ff\x89\x96\x04b<\xd2\xa9}mo\xb0f\xd6\xd5\x9a\xebzB\x04P\xf7_\xd7\x1fa-\x89\xa4\x89V\xb8\xb5\x0b\x8f\"\xf7\xc7\xb6\xabb\n\x9c\xc7\xf0s\xf3\x8c\nm\xba\xcdh\xdf\x11<\xba\x82\xb4v\xb6-\x96P{\xd3\\\xb5tR)*\x97\xde\xb5U\xd7\x0eiUu\xed][uqD\xa7\xaa\x8a\xdf\xcd\xd5\xa4<5\x86\xcb\xf6\x82\x82\x95\x8f\xe1\xba\xbd\xac\xe2\xe3c\xb8h\x19y!$\x8c\xe1e{Y\xad\xe5W\xcd\xa5K\xf2\xd0\x18\x8e\xbb\x94\xd6Z?k.\xaf Och\xd9\x9d\x92\xe44\x86g\xcd\xa5u\xc1r\x0c'\x1d\n\xa3T9\x86\x9b\xe6\xa2\x8bx\x0co\xac%l\x87\xab\xb5\xb7\x1f\xcf=\xbfrO\xe4\xa3\x9b\x0d^mSfJ1\xb9\x92\xe4\x02-\x1d\xb5\xb3\xa9\x12s\xda\xab84\x16t\x00\xdd\xc7J\xdf*\xbc\xa4Z\xd5\xc4\x0c\xaa\xb2\x84\x8d\xf2k\xc6\x05\xcc\x15#&\x00\x13\xa0\\\x14\xbf7\xc7\xaf\xc8\xe6\xf8\x15\xd9\x1c\xbf\"\x9b\xe3Wds\xfc\x8al\x8e_\xfc\xc3Pw\x1a\x8a\xc8\xb9\xcb\x92k\xfa\xb7\xf6\xd9\x9a5\xfadi\xfeX&k\x8cv\\ip\xc7\xf2?\xd9\xe5Jx\x18bq\x992\xa7\x9a\xd6\xc8\xe8\xd4\xf8\x19\x07\xa7d\xa0Z\xb2\xfc\x07$t\x06)\xbe\xab}j\x17\xdbT\xbe\x83\xaa\x1c\x9b\x14\xdf\xc1l\x9b\xa6\\\xbch\x10t\xd1>\xe9\xc6\x98T\xbc\xd1y\x0d\xef\xe8\xb6\xceO\xab\x90Yd\x1dg5r\xa4O\xeb\xd7\xf0\"\x11\xdc\x03D\xf0\x19\xbcS\xe0|\x8d\xe7\xf5_;\xf0ug\xd2Z\x86\x00\x93@\xd5bg\xfc\xa4=T@a\xb3\xe6\xb6\xac\x06\xa3\xa50\\\xfb(\xcf\xa7\xcc88\xd3\x90\xed\x99\x18\x87Nwg>\xccj|\x84Z\xff\x171\x16\xcf\xfftb\x8c \x8b(\x15\xfa\xd5|a\xb0\x8b\xd3\xac\xba\xf0\xc3WL\x91_\x15_?\x82 \xe5 u3\x8fr\xe8\x0f\x1f\xc3\x0c\x9e@\xf6\x18f\xbd\x9e\x07\xd1tv\xae\xd7\x9c\xce\x0ca\x01\xc5R\xc6x\xe1\xd1\xe6\x9c\x8b\x18\xd8\xca-fA\x14 \x96\xc1|\x98\xf2\xba\xe72\xf4b\x84IZ\xc3\xc1,J\xb2N\xeeV\xc2\xc5J\xb7\xfd\xa11\xfc9G\x85\x10\x7f\xbbU\xffz 4\xc3\x8bZ5\xa6\xc77\xe3\xb7\xe0\\_\x96\xe4ub[\x1d\x0d\x9eqwcj\xba\x03;\xa4\xd3\x15\x96\xa6\x1d\x86\x10\xeeb\xf1\x0e\x84\xf1t\xf0\xec\xec\x8d\xbd\x14\xdfm\xed\x04-\x90)m\x1b\xcc`\x98\x0e\x15\xa1)\xd6\xc1\xa9\x81sS\x8aT\x87\xaf]f\xcb\xd0\xd0\xc6\x8a\xe7\xe1U\x8dT\xeb\x8f\xbaV5\x06g\x1e\x06Q\xb2\xecoo\xacWq\xbfH7\x97\xc1\xec\xfd\x1f\xea\xe57Z<9\xa5>^\xcf\xff\x8d\xfaZ\xb1`\xfe)\x9d\xad\x0e\x95\x1c\xe8<\xbb\n\xc2(\xb8\x8c\x18\xea\xfbI\x1a\xfe\"\\\xb8\x9a6\xfbr\x9b\xe7h\xe0\xb5\x0f8\xbf\xdd P\x89\x92\x9d&\x86\xfc\xa0\x8f\xd3k\xa8\x91\xc4\xba\xb9 \xeb\xec\xbc\x02\xd9\xd5\xb2q\xf4\xd7\xe1<_\x8d\xc19\x186\x0cd%\xa2;\xf0R;\x8f`\x9b\xd5e5\xfdY\xa5l1\x06\xe7+\x9c_\xc3 n\xa20~\xff}\xa9\xb0\x05y\x91\xe9~Y\x00\x9c%q\xce\xe2\xdc:\xfbh\x80|\xee\x8c\xfd\xcd\xf5\x06\xeb`S\xcaI\xdex\xfd\xb7\x85~\xce\xda\xcc\xb6\xc8~[\x0e?\x9e\x9d\xbdi=\xf0\x98\x17,\xc1\x1a\xb7D>e\x13X\xcb\x19\x96\xce\"[\x0f\x81*\xa6\xb8\x96\x93\xdb\x92\x91\xaf\xc5\x00\\1{\xd6\xdd\xa1\xe5c\xb3\xb4y\xf8\xd4\xbe}9%\n\xdf\xfeK_\x12\xcf\xbf\xf4\xa5\xff\xc5\xfa\x92\xe0|]4\xa6\xce\x97S\xf2\xeez@\\\xd7/\x06\x1a}|\x93\xa8\x83g\x9bI&\xafim\xe6\xd4\x15\xffR\xda\xccO,\x80\xac\xac\x8dy\xa4\x8b(\xd9\xedU\xb2\xd9n\x1c4,6+u{{\xbb)>\x89\xa8\x13\x14\xee\xce\xde \x0b\x7f\xb1D\x13\xf9\x92:\x10\xef\xb2\x7f\x9d\x06\x9b\xcd\xa7\x08\xbc\x1d\xe4U\xad\xb3\x04\x8e\xc0\xb9\xccc%\x113\x88\x92\xd9{6w`\\\xfd\xb0\x8d\xc5\xa7\xae\xf2\xaa\xf8\xb5\xf3\x14\xb2M\x10kR\xbb\x1c@\xa3\x98\xfe\xcf\"\xe5\xe2\x82\x7f\xa5\xad\xf1W\x1d\x96U\x13|\x1b\xea\x9bG\x8c\xf4\x14\xddkm#\x8f\x85u\xf8_\x92\x0d\xfcK\xb2\x81\x7fI6\xbf\xbddc\xbd7\xc0\x06Y\x9el8\xd4\x07\xcb\x80\xf8\xb0\x99\xff\xc8\xcb\x05\xd2z,:\xb1\x88&\xe8lop\xa9\xff\x9f(\x8e\x94\x1c\xd5?\x8dy\xef\xc6R9\n\x96\x85\x94\x8b\x0b\xceH5\x9am\xf8\xda\x81\x0b8A\x1a\x06\xfd(\xb8d\x91c\xea\x06h\x9c\xd6\x8e\xe4\xf7\x0e]}!>\xfeO\xc2\x93\xd9g\xf2\xe4\x86\xfa\xe6\x11\xff/\xb4\"\xcc8K\xad\xf1\xd4D|\xa9q\xe1PV11\xdb\x99\x89\x0bo\xc5\x87\x1a\x17\xce\xc4\x87\x1a\x17\x8e\xc4\x87\x12\x17\x9e\xc9\xc8G3\x11\xf9\xc8\xc4\x8fg\xbf=?^t\xe5\xc7\xb6\xb0EU*l\xe5\xb9W\"\xafz\x95\x98[}g\x92:\x0fl W$\x16+\x18$1\xa7\xcd\xc7\xab ^\xb6g0\x02\x8d\xcf\xb1A\x1c\xac-\xbaXP\\[\xab\xb0\xe8\xbf\x7fDL`&\xf4\xe3\xfc.\xc3\xbb\xee|H\x9d\x06S\x0fb\xc7\x1b\xa9\x1f\xdf*\x15\xca\x0d\xc8\xe3\xd7\xd2}\x94,M\x91tv\xe8\xbfY8\x08\xda\x14t\x8a\xab\xd0\xc9@B\xc1\x154\x93H\xcd\xe6\xdd\x1a\x80U@\x819\xa25 \x1d\x19\xe4 \xc9w\x96\x99\xc5b\xcd\\s:\xd3\xa0~\xec\xbe\xc3b\x9a7\xb3\xe3Y|P\x84\xfa\xe0\xbf,8\x0ee\xd9)3\xcaN\xc1?@vj6\xe2t1\xf6\xc4U\x00i\x83\xa5\xee\x87\xeeyW\x1bR\x88\x85\xbb\x9d\xd0\x07t\xd2\xcd\x91\xff4g\xeb\xa6\xabH[*Jy\xe0\xda\x8cO\x19\x15\xfe\x96d\xc8\x96\xa3\xf6\xa4do\xb2\x97\xa5\xc0\x19\x8b0\xcaY\xfaIH\xb7\xb77\xc3k?\x96(\xea\x80\xd8g\xef\x7fc\xee\xbfc\xe7r\xe5D\xd4]\xbc~\x94\xdfnXC\x8c\xd8\xa6\xc1\xcc\xbf\xcc`&;\x0c\xa6Q\x8f\xb0\xdd\xbf\xd8\xdd\x088K\xe2<\x08\x9b\x0e\xd9\xf7\xf66h\x95\xe4b\x87\xb5\xdfE\x92\xae\x1b;Nb\x8a\xf2\"o\xa5(6h\xebvS\xa6\xf6mI\x97Z\x16&\xe8t\xc2\xd9v\xba7[\xb1u\xd0z`\x18\xe3\xf2\xb6\xb4\xb5\xd3\xe9\xa6.\xc3\x8c\x81\x95d\x9a\xe6\x9a\x81vy\xad\xe5\xdeK\xf9\x08\xf5\x13\x8e.\x0bN\xea\x7fA\x00\xbd\xcc\xe3VK\xb5\x00P\x8e^\x0b\xfa\xf3\xc8:\x82\xack\xef\\e\xa6\xa3yi\xa3\xee\xac\xcdjR\x96m\xc8\xce\x0fX\xc6\xf1`\xfciC\x15\x1e!\x84H\x1d=B\xeaS*\x00\xc4\xba\xb8e\xeb\xf8'\x8d\xb5e\x0c|\x8b\xe7I\xdc\xe4\x97\xb1\x83\x97\x8as\x8cn\x1bh\n\x9bs\xa25o\x03 \x01\x94t\x18\xf0E 7\x9b%\x1b\xd6\x9f\xb3E\x83/\x87\xa5\x9bMq,q\xc6[\xc9 H\x19l36\x87<\x81e\x1a\xc49\x041\x04\x9bM\x14\x8a\x80\xd3\xf3p\xb1`)\x8bs\x88\xd8\x15\x8b2H\x16\x10\xccf,\xcbx\x95y\x90\x07\x90\xc4p\xc9VA\xb4\xe0\xdf\xf2\x15\x03\x16\xcfy\xa3\xe9\x00N\x82\xd9\n\x9e\xbd:\x85up\x0bs6\x8bx\x7fI\xcc Ia\x9d\xa4\x0cp2\xd9\xa0i\xf7\xf5Q\xf3\xa6R\xf6\xb7m\x98\xb2\x0c\xbbZ$Q\x94\\\x87\xf1R\xb6\x04Dg\x80b\xe1'1\xcb\xe06\xd9\xc25\x9f\x9a\x9ac\x9e\xc0\x19\xa5\xd1\x85\xb7\xa7\x03\x07\xe3\x03\xef\xc6\x81?\x8d\xfb~\xac\xbb\xd64J<\x9f\xcb\x91A2\x9f\x06%\xc5\xbe\xf0\xdb\xb6\xa6w`\x00\x92\xbd\xb5\x05\x8dA\x10oR\xa9\xda\x19\x04\xa7z\x9ft] \xeal\xa3\xa2\xe4b\xbf7\x1b\xd5\xef\xf2<\xc8\xa7?,\x96\xa8\x7f\xb6\x93\xa1\xffy\x17\xb6\xbe\xa8\xda\xdd\xa6T\x8b\xd0\xaaH\x0b\x9aUo2\x905\xeb\xdc\xbb9\xbaw\x93kC\xe5\xe3\xd1\x16\x1a(\xd8\xc1}^h\xdc\xc1&\xfc3\xbb\xe5\xc3hR\xa4#*|\x19d\xe1\xac\xad\xecL9\xd17+\xdb\xb9\xce\x9a\xcc\xda_v\x1db\x06\x93E\x13C\x9a\x05\x19\x031\x0fgl-\x06bh\xb6\x83\x8dV\xce\x02\x1d\xb5&\xe8\xae9AW\xed j\xfaJ\x87\xc8\x1c:+\xec\x10\xf9c'\x0d\x0dHF\x15\x1a\x9a=\x8d&4\xe8\xf6\xf2\xb9LY`9V\x05\xb5\xbf\x08z\x9f\xb1\xbd\xd1\xbf\xb6\xf7\xf7\xb9\xbd\x92U~\xf2\xcev\x928A\xedn\xf3\\|p\xde\xc6\xef\xe3\xe4:Vas4'nTB\xc1\xf1a\xd1\xf5v+t8\x0bo\x1b?\x8d\x1bz\xe0\xf4\x7f\xde\xae7V\x15\xcb\x90h\xe6\x7f\xf8 \xe8\xefR\xba\xfc\x97L\xf9\xbfD\xa6\xe4\x82V\xd2@HU\x1c\x00\xd7A;E\x93\xd0\x14\x17e\xd7,\xcb\x82%k*\x9d\x16\xa5\xb3d\x9b\xce\xac\x02\xd4\xe7\x92\x1e\xdd\xc6\x83\xb3\xb5\x85m\x05\xcc\xd3}\x1b1\x13\xe4\xea\xcfe0{\xbfL\x93m\xd4)\xd5\xe7\xfbm\x80\x1e\xf5\x07\x97\xe7\x1f\x16\x98\xbay\xa7\xa1t#\xaa\xc9\x95\x16t\x7f\xea;w\x8a\xd4\x10\x9c\xe0\xe14\x1c[z\x9c\xfa\x92\xdbX\xd8\xef\"\x94w\x1b\xdc\x83.(u0\xb2\x81\x12\x95\xba\x99\xc4@\x19\xe6\xda\xf7.\xc44\x8d\xcei\xbc\xd9\xe6m1v\x03*\xfb:\xb9n+\xb9\xa5\x92\xc7I\xa3\xb0\x08*\xff$\x1e\x19\x9fp\xc1\xac\xad\xfc\x8c\xca\xff\x18\xa4\xef\xe7\xc9ukX`\xcaB\xe9\xfc C\x9d\xbe\n\xf2U\x9bO\x0e\x08\x17\x96\\\x04W\x12\xa4\xa9\xb9\xc2\x1c Y\x10E8\x85\xcc\xf5v;\xf0\x92\x8fdo$\x11\xf3%9\x9d;\x1e\x9e\x7f}\xba\xe9\xa2\xdb9W\xcb\x19\xea\xean{\x99Y2g\xaaT\xa2\xe2\x04\xbb\x0e\x07B<\x07t\xfe\xff\xff\x0f\\2pz\x8e\xbd\xa5E\x9b\x11\x84\xa2#OU\x16\x19\xcd\xe7\xce\xf1!9\xb7V\xc6\xb4\xb6\x9bF\x87\x98\xd5}\xc3\xf5\xb2y\xd3\x19j\xd0\xb62\xad\xb7\xf4I\xf7\x19\xcb\xf5\x9a\xb3l\x96\x86\x9b\x1c\xa3^7\xcf\xe5\x93\xc7\xa4\x1f\xfc\n\xbd\xa8\xeb\xd6\x96w\xf5\x8b\x8d\xe24\xde}\x0ca\xfc\xd9#\xa0;\x13j\x14\x88\xeec\x07\xc1\xa4\xc1\xf1\xa04\x18\x07\xbe\xc1\x07\x1a\x9dB\xb6mC \xdb\xc0Dx\x8ep\xe5\xabE\xcd*L\x9e\xf2\x92\x06\xfel\x82%\xcf\x87yS\x98\x8a\xae\xde\x83\x9f\xe4g\"\x1fT\xcd[\x0f\xb2\xa1\xfd\xe4\x1d\xc0\xea\xefD\x9f:\x0b\x1a\xa6\x80\xa9\xa6\xc3\xec\xf2\x907m\x97\xd3u\xc1\xa2N\xbbK\xbb\xa67e\xdd\x85+\x91\xfa\x8e\x15\x97\xbcZN\xe3\xc8[6\x0f\xd2%\xcbi\xe3\xede\xe5\xdd\xb7\x8a\xbf<#\x91\xbcmg\x85\xc0ega6\xf6\xc5\no\xfd\x10\xd3L\x87\xadz\xfc\xbf|\n\x8a\xe7\x93\xac\xbe\xffd>\x05\xb0\x9bN\xde\xe9f)\x88\x9e\x7f\x83\xc4\xdc\x0b*\x186\x8cb\xdb%|\x05\xdf\xd1m\xab\xde\x11a\xa9f\x9d`&\xf3a\x0b\xc1w\xb0\xcdXj\xbfP#v\xbfK\xf6RR\xce\x1b4o\xa9\x9c7\xccS*\xe7p\xd4Bs\xe4\xa8m\x8a<\x7f>r\xf0\xb4\x9a\x19\x7f\xeb\x94\xa8\xffp=\xbf\x8bc\x06\x94\\HZ\x95\x0e\xbaM,\xf5\xfcX\xd3\xf39\xda\xd8\xd6\xbe\xbe\xf0\xffK\xb5\xfdv\xed}\x978\x93\xf0;\xd0\xf6\xa3O\xd3\xf6wS\xdf\x17\xbb\x99\x08\x0c\xda\xbe\"z\xedj\x7f\xf2\xab\xaa\xfduc\xa3\xfetP\xfb[N\xccH#\xb1GH,\xd4~\xe7\xdb \x0bg\xe5\xe8\x88\x8e\xbdj\xab\xce\xdb\xac\xc3\xa7]tx\xfb\xb0\xad:\xbc\xadJ\xd0\xb6\x14\xad6\x89O\xd7\xe1?yLU\xdd\xf5\xad\xe4yR}\xb5V\xac\xa8\xaf\x8e\x0f\x1b\xfc\x9f\xeb\xaf\x0d~e\xcd\xc3\xf9\x82\xfa\xabpC\x9f#q\xa7?[j\x10\xafw$\xde\xfe*\xfa\xf1\x17\xdb\xa8WA\x96]'\xe9|\xe7\x8d\xd2\xed\x0c\xbf\xde>\xed\xbe\xfa\xc16O8g\x8bX\xcew!f\xd7\xfd\x8d\x98c\xb7}\xebXZ@P\xc7\xd2\x9f\xb6\xcb_\xc4\n\xf2Y\xde{\xff$V\x10\xd3\x11yy\xc8\x8b\xdf\xbf\x15$\xd5\xac \xf6R \xda\xf7;\x18I\xd2\x16\x99\x8d\x1c\x9b)\xb5\x176gf\xe0\xc14<\xe7\xb2\x85\xaf\x9b@\x9a\xe4V\x94q\x03\xf3n\xa2\xe5\x84Y\xa3\x0b\x94w\xf5\x9f\xc9\xc7aa\x8d\x1b\xb2\xb0\xf98,l>\x0e\x0b\x9b\x8f\xc3\xc2\xe6\xe3\xb0\xb0\xf98,\xc8\xb2R\xfe\xc0\x05Yw!M,\xfc\x8fGw\x1fxf#\xcb\xe2\xb77\xb2l\xbe\xa4\x91\xe5\xf7\xe6\xf80\xff]:>\x04\x9d\x14\xee\x85*\xd9A\xc3\xe3\xbb8\xe3 B\x17\xf8\xb3\x06\xc5\x07\xa3\x98\x0c\x8a\x04d\xae\xd0\xc8\xed5\xae`Bb\xf7\x86$\\%j\xb5f\x16]Wj\xce\xa2\x90\xc5\xf9\xa9H&\xba\x1a\xc8\xdfm\xed,\x8d\xed\x9c\xb1Y\xca\xf2r[\xf4\xae\xad\xbd\xdbJ{R\xacx\x8379\xb0\xb6\xc8Q\xd8\xbfL\xe6\xb7\xceg\xbb\xa7\x04\x9b\x0d\x9d\xb5\xad\x06\xe2O\xfb\xe0\xbe\x84+\x0b]\xdb\x1c\xc3\xf4\xbc\x01\x14\xc5\xe27\xa6\xdb\xd4W\xb51\xb9favkH\xea(\xd7y\xdc\xb8;\xfan\x8c\xe1\xd6X\xee\x1f\xe0\x8e\xf3\xab\x18\x9b\x9a%\xbd\xaeaU@\x85Vi\xa3?\x00\xbbEV\x81]\xa3\xab\xc0\x8e\x11V@\xb0\xe1\xbc\x83\xcdkKS\xec\x96/\x05\x8a0+\x9d\x8c^\"\xa9I\x07\xa3\xd7\x82Jv0zm\xba\x86y\x01\xe9J\xb2\x83\x85lE\xe5w\xb3\x90]Q\xa5\xae\x16\xb25\x9e\x1b\x84\xd9\xcbgg\x87\xcd%9\x89^\xbb^-\xfe\xe01\xd7c1\xea ^o\xc7\x9f\xcd-\xdd\x16-\x11\xf59N\xd9\x9c\xc5y\x18D\x19\xb5T\\\xa4oi\xea\xff\xb2\xf7\xef\xebm\x1b\xc9\xa28\xfa\xffz\x8a\x12fN\x06\x1c\x93\xb0(\xdf\x99(>\x89-\xef8c\xc7\xde\x96\x9d\xcc\xda\x1ao} \xd0$\x11\x83\x00\x02\x80\x944\x89\xdfe?\xcbz\xb2\xdf\xd7\xd5\xdd\xb8\xf6\x0d\x94l\xcb\x19c\xd6r(\xa0\x80\xbeUW\xd7\xbd\xe6\x98\x04\x06I\xfc\"6/\xeci\x0d\x8eu*I\xc8\xe2\xf9\xd9\x91\xc0\x9f\x14\xfc\x96\xfeSg\x98)\xba\x9d\xb9\x07\xdf\xf7\x0d/\x1e\xa1\x15\xe6Cj\x16\xe5\xc2\x82\xb8t9u\x80W\xc5\xdf;\xbaT\xa7\x9c\xad\x1fG![\xbff\x88\xbf\x08\x040\xf4\x0fsC\xe8;y\\/dK\x1dgT\x9a^\x99\xaf\x94?\x06\x07\xdc\x17\xdfm\xca\xd5\xc1\x18\xe8\xed\x16\x1a\x823\xd2\xb9\xbc\xacL\xca\x02\xbd\x0e\xd57\xe8P\xcb\xba\xca4\xe7Ft\x1e/\xab;\x0d\x9dj\xbd\xf5\xd0g\xa7\xff\xa5J\x9b\xc8\xde8\xd6\xb9\\mM\xc3\x14\xaaU\xd9Zj\x868\x86\xb3\x1d=\xbd\\'Z\xd3\x11F%\xc3\xcc9\xdd\xf8s\xfc\xb9\x1ci\xbf\x99\xf5?\xc9R}\xbcy\xf5l\x80{SRo\xd8\xea\x13o\xf2\x98\xe5F\xa9\x19\xd5~\xef\xea\x9f\x17\xd6\x1d}\x9d\xbe#\xac\x83\xd6\xfds\x1a\xb8\\\xd2\xd7\xab\xcei\x1b\xd4/s3F\x077\x88zm\xc7\xe0<\x89\xd3\xb3\xe13\xca6\x1e\xfa\"\xd6\x93\xb8\x87\x93\xf8\x10!5\x0e\\\x81i\xe7\x1b\x01*=\xb0~\"V\xe5:~\x82AB\x98\x01\xe5\xb4\x92\xb4\xb4\x13\xb2ij\xff\xcf\x068\xaf\xb57pe\xf9\x12;X\xf5\x19\xa3E\xa4\xf4\xe71\x15\x17\xa6\x9a\xf8y@UE\xf1\xaeL3\n\xa8\x1b\xa0r8\x11\xf2u\xa6\xdeDa\x7f>\x0dl\xb7\xb5\xb9\xc2 \xfd\xd2\x9f\xe0'/a\x83@\xfe\xd4JE\xfd\xb1\x11\xb0\xda*Z\x04\xcc\x9aV\x8d!\x08h\xe3=\xf9\xf9b\x9b\xa5\xb1b\x98i\xa3\x8dq\x96/}\x16\x18'\xc6r\x8a\xf94\xb4\x08\x87S6\x14\xd9\xda\xd4\xae\xa9d\xf8|(^\x81r\xafqR\x11 \xdb\xf3\xb9\x0bV\xbd6\xbf\xb8\x1bfiF\x98f\xdc\xbf@?B\xaeoi\xab\xe9\xb48\xf3\x8aA\x02B\xea\xf8\x95\x81=`i=\xb4M\xd7\x0e\x14W\xd9\xf0o\x1b\x92\x1b\xc6\xfc\xbf)\x08d~\xee\xafII\xf2\x02}\xe6)#\xc99E\xd4t\xaa9^|\xdce9\xbf\xfaJ\x8c\x19\xd9'\xc5\x96B\x1e\xd4\xdd;\xa3\x9f@f\xbc\x01'\x14\x8fZ>\xf5\xea\xe9\x0bk\xf642\x1cf\x15\xd8`\x02\xf3g=\xcd\xea\x89\xb3:\xc8,\xd8\xa6\x86\x9fA\x07\xbd\x0c\xda+\x86\xfa\x12\\\x1aB\xde*+\xc4\x87 m\xbd\xfduE{\xe9\xa3\xef\x93\x82YWl\xf6\n\x03\xfd\xb2_\xda\xfb\x85O\xe0n\x18\xcd,.W\xb5\xdfd\xf8\x7fl\xd3\xbdK\xec\x81=$\xfb\xa7\xf8\x8fe:W{-\x01W\xc2\xee\xb4\x92\x98\x9d\x9d\xe3 \xd3\xef\"\xe6\x9e\x0e\xcb^\x0df\xa5\xa1\xd1\x13\x12\xacS:]j\xe2\xa03y\xc1\x8a\x04\xef\xe6\xa9\xa2 \xb8\xb84\xadZEt1\x9cc^\xdfV\xe9\xc3\xe8\xdea9\xa2\x1c\xb8\x01s\xfc%\xba\x8a\xb7\x84\xfb\x8c\xd9PD\xaf0*(i\x08gpf\x06\xe6[\xa9\x9a\x19\xf3\x1b\xf5\xce ^\x9a \x1e\x19\xb6\x05p\xdd\xe4% 54\x89\xb5\xf5|\xed\xba\xd4\"\x9d\x8a\xb9OM\x0c\x8bJ]~\x170M\xc4.H\x8dTp\xe7Q\x9au\x94\xd0iO\xaf\x96\x03\xd6^r9\xbd(t\xdal\xea\xbfMM\x97\xf2\xb2\xd4\x15\x84$\xb5\xef\x18\x8e\xae\xc2\x03R5\xe0\xd0f\xb8\x1f\xcf\x03\xf2\x92\xf87<\xeb=\xb0\x859G\xc9H\xc7'eC\xda\xd6&\x887\x1e\xee\xbd\x0c\xf8\xba\x9e\xdb$\xc0\xff4}\xaf\xde\xd2v\xbf\x91\x15_\xb3\xfa\x97\x1d\x81Ej|\x18\x90\x1e\x1fx\xe7\xab\x14\xf9R(K\xc7\xddz\xcc*\xc7\xdd\xf0\n\x1cw{\xe5\x95\x94\x94\xa3\x94\x94W\"\xbb\x97Wj\xe3\x82i$\xc0GS\xd6n\xc3\xea%\x1b\\\x04\x8b\xe4\xb9\x112\xad\x1dq\xd0\x15O\x0d\x19\x0dq\xc1\xf1\xe1\x10R]\xe2\x92\x8d\x88\xf4\xac\\\x00\x15\x0en^\x10\x13?\xd7\xf8\x1f3\xc7\x82\x19\xe8Y2\xce]\xf9\xfa\x82\x1c\xc2\xd8\xcb\xe0\xe4h\xce\xbd\xb6\x02\x81\xc7#C\xdffU\xa4\xba\x16\x8c\xaf\x94\x96M\xad\x17T\x9b{6`S\xaa\xcd\x7fK\x9b|$\xe06\x8a\x91*\x11\xbc\xc5mZm3\xe1\x1covw\xcf\xd1q\x02\xb9H\x9doj\x8a`\x94\xc1/D\n\x019\x06E\x0bp\xb1\xcc\xf4d\xca==\x18K\xca\xcbJDIH\xce_,\xdctd\xf2\x97\x8b\xa0\xf72\xaf\xa0{\x92\xbe\xd5\xf8uXy\xd1C\xc3crx\x15\x1d qA`/g\x1e\xda\x8a\xf1\xc1\xb7t\n\x18\x84\xb9C\xa23\x9d\xcf\x0dv\xba\xa9\x9c\xc7\xf7\xb4\x89\x84\x94\xf5\x8148\xd8P\x04\\1\x0e\xb6\x91KOY0\xaa\xd5\x14\x9e\xe1\xcbsX\xa4cPE\xdf7\x16\xc9WO\x02\xe3\x98\xacF\xdf?\xe8\xd4\x1e\xe9\x89\xcdy\xc46\xaa\xd5y\xc4\xe6\xd3\xe6_\xfb\xe7\xca\xbf\xbe\xf2\xb2M\xb1r\x9d\x9c\x14Y\x9a\x14\x04\xed\xca\x87\xa8\xd3WP3E\xde|\xd6^ev\x1c\xd2\x1a\xba\x9c\xed\xd4\\\xdf\x95\xf8C\xcca\xcf\xf3y\xc8\xe0\xd8T\xb6^hS0\x87R\xa0d\xe9\xc0\xe1!\x92\xd1t\xc1\xa2X\xc4\xe7*C\xdd!\xaa\xff\x12\xfa\xc17\xaf\x9eV\xb2\x9e\x9bu\x03\xa5(A\xd9b.\x03Vr\xeb\x15 \xa3\x9c\x04\xe5\x9bZ\x9f\xd1\x13\xe8t\x0c+\xfe\xd1\xaf\x9c\xd1[\xf6\x93\x8bS\xa7\x95\x84\xe1\x8b\"9\xa6@\xb09\x8b\xe5\xd4\x19\x89\xba\x06\xa2y\x99Lp\xee \xcd\xe6q\x1a\xbc\xc3\x12\xeey\x1a\x9f\x9e\xceK]\x08c\xdbF\xc4\xff\x92B3\x0b\x11\xf1sI\\\x94\xb1\xde\x89\xa9\xce\xc9\xf5\xcc\xa1\x8aD_\x9a\x03\xe4Z\xd69\x19\xb3\x1f\x07X\x15\xd9\xbd\xf7y\x9c\x05\xd0\xd29\xad\x88\x1f\x92\\b\xf53\xed\x19\xbb\xe0\xc9F\x98\xa1\xa0=\xc0\x9b\xd4\x17\xb2\xce\x1b\xd9\xc1\xbb\x12L{\x81\xcc\xc9N\xea\xd1\x86\\d\xfc(\xc3e\xae\xe9\xa2I\xfb\xe1\x8e\xc1\x81u\xe1\xe8G\x1d\x1aGm8\xf3\xa1M\xa0%Y^\xc6;gr\xb1\xa9\xa7\x06=*\x06W\x9c\xdb\xa1X\xa5\x9b8\xac\x08\xe1\x9b,\xf4K\xdb|\xac6\x15\xcd\xeb$\x0e\x9e\xd0\xf9\xa0tI\xea?\xff\xf8\xa3 E\x0fq\x0e\x81?\xdbO\xd9\xf1\xcd\x9f\xf3?\xda\x10aTd\xb1\x7f\xc11\xeb\xb1P\x7f\xb07\xe4\x0f\xa5c\xf8\xdcR\xb2\x8a\xe9\xd4\xc3\x0eM\xca\x9a\xd6\xf0\x06C=T\xd5\x8e\xe5\x93\xac\x7f\xd3\xafx=\x0b3?T\xcax=\xc7\x07\xfc\xc8\x12\x98\xa2\x87\x0c\x98\xf3\x00\xba\\<\xdfPi8\x14\xe4\xe9!\xf8\xde\xbau\xebI\x9a\xbb\x9b1\x14#\x98\x81\xef\xe5\x9d\x9b\xfa\x86B\xa8\n(S\xa1{cL\xa9\xb0\xa2\xa7+\xcf@$\xd7\x974\xafm\xfd\xf9\xea\x10\xf1\xca\xf4\xc7cSE\x97u\xfdb\x92\x96\x8f\xd3\x00I\x12\x86\x87k\xdf[\xd6\xef\x11\x9b\xf4\x1d\x175<\xfa.\x1a\xc0\xe75x\xe3\x98\xd0\xber\xda\xb7{n-\xd2VlO\x1c\xca\x9f\x92\xa4\x9c`\xe4\xd8[JZ\xb6'\xce#~\x13\xa3\xc24y\x85\x80\xeb\x94\x12\xd7 ,\x16\xea\x9c\x81\x8a\x8d\xfb=\x0b\xcf\xd2\xber\x0c\x87]wm\xa3)\x1c,\x0enk_W\xe8p\xf9\x0c\xc3\xe2\xc8\xe8\xf5%.\xa4\x95z\xa7\\\xe0l=8\x98\xe3\xcc\xc1\x90\xf7\xed y\xcb\xa2\x15\xb5\xef\x9a\x92x<\xa2\xe24\x1e\x06\xc7\\\xe0\x96\x8b\x82`1iMn'\xd0E\xaa\x1c\x99f\x96\xd3\x0fm\xe2\xf6\xd1\x18V\xda\xf4\x06v\xcc\xd7\xed>\xf3\xf5\xe6\xd53-\xdf5\xd4)TD&\xd2-\xa0\x1e\x8f%\xa3\xb7\xd2\xa7Xh\x8e\xe7\x98\xe4[\x92\x83\xd8O\xda1a\xf0\xcc\xc0Q\xb1\xcf\x16\x13\xf6\xeeN#+\xe9~1\xafR\x99\xef\xd85\xb6\x1dw\xec[8\xa8\xd1 \x8d!H\xe3S\xd6d5\xeb\x13z\x8f\x1fk\xban8h$\xd4.\xd1\xd5\xf5\xc7\xca}\x9cv\xea1)\xfd(.\x0cy=J\x8c\xa4\xfdP\xab\xf8\xd1Vo\xe8\x92\x85cX_e(S\xd5\xfe& kfc\xa7\xd1G\x8d\xe0\xba7\x8d\xaf\x81S\xf9\xf8_1\xaa\xed\x84_K\xdd\xf4\xb5\xca\xf7\xb6\n\x8e\xc1\x0d<\x04\xe1\x86\xb8]\x95\x99\xae\x03\x18.4\x9f>7\x0e\x8e183\xb80\xb0\xc8\x0c\x8e\xa5'4\x04\x17m\xf2x\x06\x06\xe6\x9c\xf3\xa7\xda\xcc\x89\xf4j\xca+\xba\x98\xb1\xf7\xf5|<\xd2\xcc\x871\xb4\xb2\xea\xd7\xb1MS\x11=\x96\xe7\x97 k\x10|\xed\x0c\xe6\xe6\x06\xd5\xe1-\x97\xf0\x85\x97\xeb?C\xbc{\xdd\xf4\x9f+\xa5\xfe\x13\x9f\xf4\xb4\x96\x91x\"S\x80\xaed\x9a\xd1\x0d\x7f\xd0\xd3\x8c\x16\xfcA\xaf\x8d\x98?\xe8iF\x03\xfe\xa0\x97\x1dy!\x1a\xdf\x7f\xd0}\x94Q\xf1e%\xb4\xa7h}\xec@\x84\xa2\x83\x8a\x9aU\xab\x8f\xafO\xdd\xda\xda\xd6T\xa9\x94\xa5&*\x99\xfd\xac\x99B\xb9\xb0Q\xbcEm\xc5\x9bE\ne\xac\xd0\\\xc7]\xbc\xc9\xe3!\x96-\x9eU\xb9\xad\xce\x90\xcb\x19\xc2LG\xce`!z\xe9\x12o\x93\xc7.\xe6\xe5\x17;5N\x99\xa3\x00\x95\xe4\x99;\x87+\xd1\x14\xca\xe7*\xe5s\xd5\xd4\xe3\x8c\xdc\x91\xc7\x1d\x8f\xd2\xbc\xe7\xf3\x04`\x9d\xe3\x17\xc9|\x7f\xbaT\xba\x86f\x9b\xb3\xa6\xabd\n\x0f\xc1Y\x95eV\xccn\xdeL\x13*Q\n\xbf\x06/JoV\xef9 \xab\xaa\xd7K\x8a\xab\xb4\xb1\xc5\x0d\\\xa8\x15\xa6m\xcb\x9b\xd2\xc6\x16\x08z\xf9K\x14\xc7\xafH@\xa2-\xd2\xb6\xc2\xc2\xec\xa6\x94\xd3\x85\xe2}\xf8\x12\x81\x88;\xb2p\xac\xc7uB`\xdb\xa5\x02\xddr\x95\x03\x96K\x1eZ'\xf3\xb1o/\xa1\xec\xd4\xbc\"[\xa7\xd8\xa9t\xce\x1b\xba\xe3\xf6\xe4\xd3\xed\xab\x9e\x1a\xb1d\x99W\xf8t.\xffM\xde\xe41\xa3Bu\xb1\x83j\xf2TqF^\xb0\xc9s\x92\x94OXj\x08s\x85\x93-%I{\xcc\xf9\x03\x7f\xbb\x1b,4\x97f\x05\xff\xc6f\x0c\x18\x9f\x88~\x16{Q\xf1\x93\xff\x93\xbbB\xfd\xca\x8a)0\xc4K\x1b\xaf\x88\xa3\x80\xd0M\xb2\xd2U\xc9m\xf9dlzy\xc5|\x13\x9fDw\xc3F \x87\xeb\xa4\xd5:\xea\n\xba@=dU\xbf\xac\x12\x92\xb1\x9d]\xb5\x89\x89\xf5\x0c\xf5\xb5\x00\xb5 \xcb\x17\xf3_\xad\x12\x99\x95\xfeR\x9b-F\\\x9d\xdd\xa7\xcdB\xd3~\xa7\xca[\x93\x9a\xdf\xa8\xf7\x9f6\x8bC\x0b\xdc\xc2& \x8c\xe7\xe8\xae\xbei\xe9\xa1!,\xf0\xe5\xcf|L\xa3m|\x0d*\xb2\xc5\x8d\xc5\xe5*5:\xf1\x89+\xc5@M\x816\xcf\xa2\x82\x9e\x8b\xb4ez\x98&c\xc8u9g\xc4\xc5\xd1\x8f\xc7j\xba%\xaf\xa3\x85\xa5\xad2\x98\xc1bTi \xf3Q\xad\x16\xdc\xb9\xb0\xba\xb8XJ\xd1*3\xa4\x05\x9a\xd0\x8b\x9e\x1e/\xb1\xac\x90\x05\x96\xd0+\xcd\xac\xd0\x1b\xaarE\x169@\x01\x83\xb9\xe9JY\xa17T\xdb\xc7\x08\xaa\x91\x8c\xd8\xe3F>D%d\x13\x8a\"3\xa6\xb5\xfd\x06\xa6\xbaB\xde\xab[\x0d\xaf\x8c\x9fR\xa8\xc9\x17p\x856D \xce\xfe^]8\xe9R\x96mYy\xe6\xcf\xc9\xb2-\xad\xe1\x9b\xaaj\xf8F\xaa\x1a\xbe\xbe\xaa\x86\xefFU\xc3\xb7P\xd5\xf0\x8d{5|Y \xcf\x82K\x05m\xe8@\x04\xcb~\x16%~\x0d\\\xfb\xa7\xe4\xd8\xafi\x88\xe0\x10\xee\x9cq\xe6\x8c\x1bPC%\x02J\x0d\xc2\x8e\xb2`\x15\xc5aN4\x944\x1d\xc6\xa9GC\xb8t\xdf\x9aC\xdf\x0c\x90/\xb0p\xb2\x8e%_\xb0\xc38\x0d\x8e\xce3?)\xb4Q\x14\x19?\xb8I\xf6,J\xdeE\x89fFCQ\x04\xd8Y\xf8qAX\n\xfeL\x0dO\xb9\xf4\x0d\x96\xfd\x8c\xfd\x0c\x1dk\x95\xa0[\x06jSes\xcd@\x1f\xf3\x1e\xeb@\x97\x0c\xd4\x04V\x05\x164\xa1\x1aJ1\x9cb\xab\xb7\x15\xb5r\xc8\xe7yz\xa6\x19\xdcY\x14R\xd2\xe0\x1c\xec\xeb\xbccH\xb4\\\x95\x0cjpo7\x85>\x14\x88\xed\x08\\\xab\xbf\xc4\x14\xcf&\xd8\xe7 r8t\xa9\x9aw5\x9d<\x8f\xa3\xe4\xdd\x0f\x83>\xa6\"6:\xad\xa3\xb6\x86rT\xbc\xc8HB \xf6\x91j\x9er\xa3\xf9@\x92JC'xg\xe2)\x1a\xe6{\xce'BcX\xab\x9d\x16y\xba\xfe\xf1\xd8\xfd\xbd\x1b\xcd\x87\x1a\x0f\xa7\x9e\x94\xf7\xe3k\x97\xd0\xb4/\xd4g*\xa1>S \xf5\x99J\xa8\xcfTB}6,GS\xe6vc\x94\xa9\xe4\xeef:\x97\xf3\x05~\xed^sY\xb96@&\xecg\x1f_\xd8\xd7\x9b\xe9\xbe\x08\xfb\xe2\xfap\xc2\xbeP\xa4\xaa\xe1r\xcbT\x05)\x87\xc3@R\x0dc\xc9\xb4\x07\xe9r\x19\x13d1\xd5\xa0L\x82O\x93\xd79\x15\xf8\xf1\xb8T\x03o8\xf0#? Hl\x00.8\xf0\xd19 6\xba|\xfb\x0b\xa3\xe1.\x1b\xa0<\x08\xadU\x12\xabjq\x8cz\x8e\xed\x10s\xea\x1a\x81\xad2q/+P\x8b\xef^\xb0 \xf5\x8b[\xc6\xef\xce+P\x8b\xef\x9e\xb6\xdd\xce*\xc6J\xc3z`\xb8\xbd)w\x02\x15\x9f\xcf\xbc\x90d9 \xfcRW=\xe0\x1c!\xb98\xa4\x06;F0}n\x8bG\x08c\xcak\xf1\x0e\xa1R\x8dn\xe7;\x84\xd0*\xe0^\xf0\x8f\xf0\xe9\xd2\x95\x9c|\x89\xa0~\x1c\xa7g\xaf\xf3\x8b\xa7\xe5\x8b\x8d\x06\x83_\xb3y\x1b\x98-\xe49\xeb0\xff\xfa\x11\x13?\xd5\xe0O\x11\x9c\xb0\xbd\xf94y\x99\xa7\xcb\x9c\x14\x1a,\xf9\x15\x0e\xe1\x9d\xd7P\xea\xa8A\x7fB\xd0\xa6\xeeF\x0d\xfb\na1\xdd\xb7,\xa3\xb7\xb8\x1e#\xc6 %Q\x9ai\xb5@\xcf\xe0\x10\x1e3#_\x15\x02\xae\xd3\x8f\xbd\xa9\xe1\xb3<\x0d7\x81\x1e\xfc7\xee\x8f\x8c\xa9G\x9eEE9r\x1f\x8f\xe1\xc4iT\xd5\xd5\xf5\xee \x1c\xc2\xb6F\x9bc\x1c\xba{<\x86G\x9a\x97\xfe\xddQl9c\xf8n\x0c/4\xca\xab\xef\x9b\xbd<:/ \xeaI\x8b\x91\xfbX\xd3\xcc\xcf\xc8\x04\xd9\xcd\xda\x0f\x0c\xb6YKX\x0d\xfc\x0b\x03\xe6\xf8\xa6\x83\xfc\x91A\x06,w\x9d\x1a\xee\xbf\x19\x9c\x8d\xf2\xf5\x1f\x0c\xd4F\xf9\xfa\xbf\x18(\xc7G\x1d\xe4_\x19d\xe5\xd5\xc1\xb2,h_\xf9?\x9dW\x8e\xf4I^\xfe\xd9ma\xb3^\xfb\xb96\x17\xca\xfff\xaf\x98\x14\xc2\x84\xf2/!\xcf\xe9S\xe3\x86\xda\xa5\xf7\x19f\x8fe)d\xd1\xc4\xf9-\xec\x9b\xdc\x95\xd0\x9d~\xef\x19\xee+\x1e\x9a\x97{\xad\xec>,F\x87\x838\x9c{\xd3\xb9p\xe4\xe8\xe0R\xf43\xf1\x8c\xa1$\xb6\x16R\x10\x1e\x04\xb4\x7f't\xdfI\xd2\x84\x02\xd8\xe69\xb1\x12\xe6\x9b\xaa\xdb*\xe7c}2R\xf9\xf6\\\x06\xe2\xc0\x0dx\x047\xc0\x91\xe9x\xdbP\xea\xd5\x8e\xc2\x99F\x03\xfe\xefZ\x01\xaa\xd4\x80\xaa\xa6\xe0\x9fZ-\xb1\xc0[\x94ngp\xaa\xeea\x83S\xd5\xfa\x98\xb4}K4\xa7w\xab\x84\xd3Z\x0f\xd7\xf0\x9f\xd1\x1c\xf6\xb53\x84\xca!W=M\xffm\xa7x8\x1f:\xfdC0\xb0R\x8d\xab\xeb\xe2\xbf\x1f\xc3c\xba!\x1f\xb3-\xfe\xc7\x1f\xcc\xff\xe4\xf0\xf0\x10\x1e\xd7\xce(\xea\\\x13\x06?\xe8J\x15u\xeb \xd3\xd5S\x15z-\x03\x18\xbaU'\xee\xed\xe9TC\xe8d\x13\x10\xa7~\x18%\xcb\x89\x9fDk_c\x1f\x19\x8d\xe1H\x9bX\xc8`%\x91\xb5\x8d\xea\xcd\xd3$\xcd\xd7\xbe\"\x07\x10&x\xfa\xc5\xcf\x93(Y\xce\xe0qM\"Fc\xf8\xd5\"\xcf\xd1\xb0\xfe4\xd89}\xa9\xca\xab\xc6Bcf\x10M\x83\xff\xb01G\xfc\xaaX\xd4\xd1h\x0c?\xd1y\xfc \xc3=/\x91\xb6E6,\xc1\xf3N\xc24(v\x9f\xd1\x0f\x86YO\xa2$\x84u\x9a\x13\x08EF\x9f+^\xd8\xd6\x0c\x0c\x1f\xb91\xd0\xd5\xd8\xe6\xa99\xeb\xcceq\xeb\xa7\xa6\x18\xa4\xc23u\x1b\xff[\xd7\x86}\xb0\xac\xc5L\xc4\x91\xf6\x0bJ\x8b\xd6O\xda\xe8X\xf6\xb4\x91c\xa7yj\xa87\xd4\x0f\xbaa\xd7R\xc4\x0c~\xb3:\x85yA\x10;\xf1\xa3\xe2Ef\xf0X\x03\xc5+x\xff\x03\xdd%uj\xb8\xa6\xbaL\xeb\xaa\xdb\xd2\x95I\xeb]\x89\xab#\xb9\xcf\xe0\xb9\x86mi*\x12f\xf0R\x0d\xb9H\xa4Ev\xc4e\xcdP5\xb4d\xda\xecE-\x15\x996\x7fQ\xe6\x97\xab\xe7\xdc\xb1\x93q\xe1\x86nr\x17\xe4P\xb1\xe1*l|\xae\xc1\xc1\xbf\xeap\xd0z2\x98M\xfeX\x0d \x1cV5Ly\xda\x91\x1bgB\x03Q\x98\xe5H\xda~\xf5\xda\x16\x15b\x85;\x12\xda\x91\xe31T\x1f\xd1\xe9!\x96\x84\xbb\x83\x91\x90}l\x06s\xafh\xdd\xd1\xacs\xff\xe5\x0b\xafw\xd3\xf0>\x05\xf9\xd9\xcf#\x8a\xf0?3\xed;\xffH\xef\x89a\x18Mx6\x8ca_8Z,HPF[\">\x85\x9d\x11\xdf\xa9\x9e\xe2}3\xfe}\xf5\x15\xbc\xa4\xff\xbc\xc2\x7fLtq\xa7cV((T4Z\xd5\xd8\xff\xd2\x9eo\xec\xa33x\xf5aq\xdf\x96\x98\xf0H\x16\xa6!\x9b\xc1\x13\xc5\xcc\xd7S\x7f\x15S\xfc\xbcRu\xbc\xa4\x12\xf9\xbcL&\xcb<\xddd(ys\xfd\x95\x91\xb3{.\xdeW\xf5\xe8\x17+\xc9Y{Z\xd9\xce\xe20\x92|\xd9\xb5\xad\xec=3(\xacvJn\x9a\xaa\x1f\xb5(k9 \xf6C\xd3wz4\x86\xa7W\xb5\x97\x85 \x1aT\xc1dCw\xf3.\xcd)]'\xaaey\xa6\x19\xe0\xcf\xba\xd6*\xb5\xf1\x0c\x9e\xa9g\xbaJ\xea\xab\x89*\x11\xcc\x90(\xfb\xa0\x8d\xfd\xb0>\xb7[l\xc4Ul\x98\x86-N\x9b#\xd2\x1aK\xb9\xf5a\x06o\xcc@\xfc\x90\xda\x8a\x80\xbf\x97\xfc\xfe\x934w\x19C\xa59\xfc\xfb\x8c\xb4\x95\xce\xdf~\x1b\xa9A\xe4\x86\xad\x19\xbcV\xbf\x82\\\xac\x89\x9a\x10\xf4\xa0\xf8\xdet\xdc\xfe\x1f\x1d\x06\x93J\x17>\x83\xef\xad1\xce@2vq\x1bz\xb9\xc9\x89\xcce\xa8\xca|'w\x19j\x9c\x1c8)\xad\x87y\xb5\x99d\xcf\xf8\xa6\xec?\xaaQ\x85J\x8a\x0b\x8fY\xbc\xba>5\xcc6\xa1\xf3B\xfa\x12Z\xd4\x9e1\xa5\x17\xd2B\xee\x85\xb4\xa8\xbd\x90\xee5S\x19-4\xeeF_b\x8b\xfe\x03\xdd\x8d\xac\xfc~\x86\xc4\xfb\xe7\xf6\x0e-\xe9\x10\x87\x16\xe6\xa6\xd4\xb6\x13\xa9\xa1}K_\xaa\x0d\xd6\xd039\xa7\x14,\\\x9d\x91-5X\x80`QQ\x95=\xd5\xf0\x0d\x0b\x845\xb9\x9ed\x08\xa5s= Y\xd7V\xe9\xd9\xb1\xa9{+\xfe1\x0b\x17\x94-\x03\xcd\xa3e\x94\xf8\xf1\x0b\x9bW0\x12I8\xa2X\xbd\xb1\x84C\xc8\xcc\xb3z\x81K\xc4\xd5\x1d\xc1&\x8fJ\xadU{\xce\x12(Tu`\xab\xae|_j\x8d\xf9\xa7\x9d\xc4\x0b|:\x9f\x1b\x03\xbf\xcf\xe4/\xbe4\x04\x9a\xf3\x1a'?n\xd6\xd9\xeb\x14\x811;\xc4\x07\xb7.\xd7Z\x01\xd6O\xe8\xfc\x8d\x06b\x8d\x16\xb0\xae*(\x05\xd1\x08 \xa7\xba\x1e\n^P\xc5\xb9\xa9?{f\xaf\xa6\xd3\x05>v\x0c\xd0\x1a\xc3r\xcd\xe3\xc8\xe3\xc6ig\xc3\xab\x92\xfb\xba\xabcc\xafX\xd2\x83\xad\xa8\x99],\x8a\xedn\xe9\xdd\xd5\xc8\"{\xfen=\xab\x93\\D\x8a\x02\x04\xef\xc7 :Qg\xdc\xff\xea+\xb8\xf0\x82t\x93\x94\xae\xaeos\xbdY\xbc&\xb93\xd0d\xcc\x1a\x1e\xe3!N\xd4\x941\x94\x98\xef\x97JMT\"\x89r\xec[\xe1^\x982\x89 \x81\xae\x13\x06\x17\xae\xc2\x01\x05z\xacEu\xd7\xac\xb8\xd2V\xc8\xc9\xb4\x08{\x85B\x87!N\xa1\xbb\xcfL\"D\xb0\xb3\x08q=\x03\x19>i\xa6\xb2\x01\xc5\xa6?\xa32\xa3_\xc4\x04q\xed.&hK:\x9b\xb8\x8fK\x1d\x1b<\xb3\x8e\xf4\xdd\xf7c\x94P\xded\x19\xc9\x1f\xf9\x05\x91%W\xd9\x99P-\x86\x13\xaa\xfa\xbb\xe3\xcf\xa0\xc4\xf1g\xaa\xad\x10\x91S_\x94\x16\xff\xb1\xd4H\xcd\xc0\x95\x034\x11\x89Dc`\x14\xf5\xe9\xc6I\xac\xe2PR\x844\xc6\xa1D\x08\xa6\x8fC\xf1\x11F\x1b?\x82u\xf1\xed\x84\xf7\x82w\xecq\x9d\xc6\xc4\x18\xe1AO\xd8\xb2\x99G\xe4\xc3\x9f\x04y3'\x838\x0d\xe8<\x9d\x9e\xb6\x9d\x9d\xa5@\x83\xcd_\xdazUU\x02\x06\x9d\x02J$`\xd0\x98\xa2\xb2\x06\xdf\xca\x9ao\xfbO\xfbXy\x80J\xd8\x1b\x0d\x0e\xb2,\x0d\x91|\x84Wy\x04^7v\x99\x9e\xaa\xcd\x80\x078\xe4\xe5R\xfa\x87[D\xcf\x84\xfb\xb2\xd3-\xea\x96\xd0\x8f\xd8\xe9\";=\xa2\x8f\x7fz\xf8\x98\xc1\xa63J\xf5q\xb2\xad*\xca\xd7\xe6\xa6>\xe6$\xed\xd27b\xa5\xdb\xe1#\xaf\xd2\xb3\xee\xbe\xe6\x83M\x87j*\xa4\x0c\x9d,\x81\xcc\xfb\xf1\x95~\\Z\x9bS\xd7F\xb3\xb4i\x1d\xbb\xe2P^\xe3R\xfd\xc2\xf2\xa5*c\xbc\xaeC\xa2f*\xeb\x93\x1a\xacU\xe3T\x0d\x96[\xc0\xc8\xeb2\xaa\xcb~\xf6\x06\xe3<\x89H\x8cN\xe5\x1f\xb2\x114Q\xb3\xa2\xa1\xeafZECK\x8f$e~qL~\xc3\xec\xb7\xa6\xcc\xa0\xdbF\x8d\xa8f\x9d\x9f1\x1c(\x881=\xbb\xcb\x93}\x85\xb3!\xee\xe4\x93\xa9$ \xc8\xb0\xad\x12\xd5Q\x84\x0cUT\xa5\xdeT\xb8\x8a\x9e\xa3\xcb\xa9BAy\xfe\xb3\x1f\xcb\xf4<\x9d\x04\x96\xef\xdb\x05\x10\xdf\xcb\xcf\x04\xf6\x99\xebu&\xbcJ\xcf\x0c\xc7\xc2\xed\xe9\x9f\xe2X`\x03\xb59\x19(B\xc8\xcf\x04\xe2Q|\xe8?C\xa6\x14\x1eR\xa63\xfd\xf1\xb8\xfa\xe1\xa2\x92\x91+\x1a\x87\x9d\x14\xd6\x94\x88o]#1ap\x9d\xbd\x1a}&H\xdbG\xcc?Q\x02\x13\n\xf0\xe0\xee\xfe\x9f#g \n\x9f\x98\x949\x1a\xc3\xa6O\xca\x15\x82z\x1fp\x91\xe6\xe0\xd2\xaf\xd1 \xaf$p^Bn\x8c\x13\xceR\xff\x16\xa31N\xf4\xfe\xd7\x10\xc07P|\x0d\xc1\x8d\x1b#\x88O\x82\xb7\xcd7O\x02\xf5\xc1B\xb7v\xc4O\xb2\xbe\xb2\x00ei\xa3\xc2 \xf0\xe3\x98k\x0d\xc8\x18N\xe8\xbboE\x11\x87\x18O\xe1\xc8Cs\x85\x1fG\xff\xae\xa5\x07c\x19\x07zE\x1e\xa1\xe3\xed{?\xbfG\xadBz\x865y^\x936\xef\xab\xfa\x1a\xf3$\xaai\x00\xd7X\xe2\xbe\xa3\xdfc\x7f.\xa2\x98PN\x03S-\n\xef%\xaf|\x0b)Z\x0dY E\xac\xce\x9c\xc07\xacVa\n7 \x82o\x0f\x99;n\xc2\xe2\xbbqs\xf39}\xcc\xd6JV]u\xcc4\x19=E\x17\xdd}\x1fC[u\x95\xb5\xcf\x98\x9c\xbf\x8a\x96\xab\x98\xce9\xaf[I$\xc1P\x1d ]\xc6\xff\xf5\xbb\xf7&\x0b\xfd\x92\\\xaf\xfe}\x02e\xdfV\x1f\x90\xc1vV%h\xe87\x14\xa9\x88\x0f\x15\xc3\xb4:.,0\x86\xc4\xc4\xb9\"\x9f\xeaj!&A\x1a\xaa\xca2\x8eQ/v%\xed\x89\xa1Nx\xc5yY57q\xd5^\x1dt]\x9a\x14Z\xd5M\xe71\x07r\xcc\x96i'\xcb\xf5\xc9\x01YYN\xda\xb4\xe4\xc8\xd1\xf5\xfa\x97\x15!qU\x04KG\xd0\xd5_i\xcc\x19\x96=\x80uD\xbf\xa0\xae{\xfa\x9er\x00\xc6M\xd4W\xc3\x99Tpr\xa7\xd7\xe6N\"\x1e9\xcf\xd2\xbc,Z\xc7S\x9f\xbd\x85\x06\xe7\x99\x903\xf8>N\xe7\xee y+[\x83\xf2\"\xc3\x91ST\xa7\xfc@\xc4\x8ad\xdfL\x83\x92\x94\x93\xa2\xcc\x89\xbf\xeeH\xeb\x1d\xf6'ZT\xf5v\xf7\x0e\x0f\xe1,J\xc2\xf4\xccK\xfcm\xb4\xf4\xcb4\xf7\xd6\xc5\xb1\xbf%\xb4\x0f#\xddC7\xefsV$.\x88\x82k\xa3\x87\x1e\xff\xda\x9bW\xcf8\xc61\x0e\xfe\xcd\xabgn\xae\x91\xe9C\x9e\x0c\xa4\x8b\xa6\xbeL\xef\x1dyX/W\xb8\xb6\xc1!8I\x9aP|\x8e\xbcUN(G\x9c\xd2\xdf\x05)\xbf+\xcb<\x9aoJ\xe2V\x9b\xcfa\xb2N\xa3\x1cq\xcd\x00\xd13\xb3\xfb\x1ec$\x9cq\x15\xd3;\x1a\xd7\xdd\x9d\xa7\xe1\x05\xe5\xd9H\x12>ZEq\xe8F\xc8\xa6\x05t\xeb\xba=\xc0\x9c\xac\xd3-\xa9\x01\x1b\x93\x95\x93m\xfa\xae1Y\xa9\xea\xe8}/E\xc9\xeb L\xc9\x95\xbfR1+R\x89Y\xbeJ\xcc\xda\xa8\xc4\xacB%f\xc5\xfcAOb\nx\xca\xc7\xbe\x1cUKZYU\x12B\x98>+\xe0?\x81`\x95\x8f\xc1\x97\x0bV\xd1u\x14\xacr.Xml\x05\xabt\xa8`\x95{\"x\\\x84\xe1\xfc\xc2B\x04\xad\x84\x0e\xde\xd5\\T\x88\xac\xc3\x85\xbc\xa0\xf5QT\xa8\xba'\x02\x10M\x90\xd5k\xcc\xed\xe2-\xe5\x9f{\xad\xbcg]\x14\xf1T\x8f\x18\xfb\xf0\xfa\"#\xac\xd7V\xdd\xace#\xca~\xe4i\\|\x17\x04$+\x7f@\xf5\xaf\x89\x9f30})\xe6v2\xb0\x8f\x11\xba\xedY\xa5@\xf4\x11To\xa4\xdd \x8c\xceO\xa6\xac\x08\xbad\xea4EZ9\xd1\xd3\xe5\xb4d\xde{j\x00\xe1>\xbb\x91BH\xaa\x17\xbd\x1f3\xabs\xafp4\xdd\xad\x96\x82X!\x15\xc4|;A\xacX\xa5\x9b8\xacX\"ka\xc7\xb4/\x1a>M\xdd\xc0@\xe4NH\xff\xb6(\xbf\xcf\xde\xaab\xdb8x\xfdw\x1bN\x84\xd6q\xb0\xeaO9\x14n\xc6\x0e(\xbb\xd7\x86\x97\x07\xbc\xf1\x17\x15\x0f;-\xfa\xe5J4D\x7f\xb6\x9f2D\xe1\xcf\xd9\x1f}\xdch/\xffG\x92\x06\xf5$\xc1F^d\x1e\x19\xd5z\xe9)C\xd2\xc3\x03=yH,\xbdN65\xac!\xa5,\xf3\xd3\xb0\xcc\x13\x8bl\x841\xefm\xd2\xc6-5p\xc8\xdc\\\x06\xa6\x0d]U=\xd6G\xd5l\xf9\x11Zi\xed\x8e1\x89\xdf\xa34$#7\xd5x>\xac\xb1\x98\x8f\x13\xd4d\xd3T\xd1\xc6w\x9d8\xda\x12\xb1\x86\xa6\xca6~\x1d\xbbj\n\"\x91m\xf5\xaf\xbe\x92\xdd\x16Q\xa4\xb27f\xb5\x84\xf7\xb2\xf5D\xdd\xf8)\x1cB\xd1\xac\xf6\xc7\xa6rIJv\x82>b\xe7)\x95p\xc5\xb0\xe9\xacJ\xcd6\xe229\xee\x0c\xd1+T\x1b\xcc\x98\xd9\xe0J\x9a\xb3q\x01\x10\x971O\x16w\x05x\xd5\x88_n\xcf\xb5)q]\xec\xcfI]3\xc4\xe4\x08\xd5i\x0e8b\xa3\xcc\xad\xcb\xa6\xa5\xad\x16\xc3\x89\xab&(L\xb0\x97\\1\xa2\xe065\xc4\xa6\xde\x7f\xc5\x0c\xe6\x1a\xc0\xc6:\x89t\x17\xfc\xe5 \x8eQ\xbeJ#]\xc6\xabA\xc8Q\xe3b\x94\xe8\x92\"Df\xa5\x9a~E\xb5\xd5^\xea`i\xeb|\x94\x1a^\xae\x99y@\x93\x03\xaa\x93y@CP\x18\xf7\xd8a\x11\xcc\xbcd\x8fk\xd0\x1c'\x8a0}U\xfe\xa5\xe1\xdb\xd4B\xc9(\\k\x86b\x0e{o0=i\xbb\xe8\xa8\xc1\xf2\x1d\xba\xb4+\x8dS\xb8\xe1\x88K\xed\x8eS\xa1\xf0\x84\xde\xe39wU\xcd;\xf4 \xd7&\x03\xbc\xa2~\xd8\x04\xbb9\x8f\x1b@]j\xfe\xa1;\x18G\xc9;\xcd<=\xc3\xc7un\x07\xdd\x8c\xb5<\x9bR\xa5gS\xa9b\xa5\x81\xb3\xd3I\xdf\xc3\xa9T{8\x89\x0bYg\xa5\xa7\x93\xb8\xb0|\xc9\xc9\xd4\x00\x15\x027\x18F\xed\x0c\xcepx\x08)<\xac\xf1\xfc\x94'#A'_G\xce\xb8\x80\x99y\xb9\xd0\xad$\x08a\xc5P\x96\xb8\x8e:[\xb1\x1c':6\x15\xd0\x1d\xf8\xb1\xd0\xa6mQ\xafkh`\x91h#\x13\xa1\x8du\x1aZ\x8b\x90iH\x8cC\xaaO%M8/\x0c:I\x803\x07]u\xce\x8c\xa2\xc6\xe1\xa1.m30\xbe\xa4\xabK\x9aa\xd9\x0f\xa5\xaa\xc9\xdc\x15\x0e\xae\xe5\x87\xc0\xfeT\x85\xfeI\xad\x84U\x14\x85n\x15\x83\xde!\xa1K\x8d\xe7;$u\xe9'C\xeaGX\xd6\x99\x83\x98\x85\x98U\x8a\x1a\xb9'-\xfb\xcf\xaf\x85\xa4\x16\xa7\xea\xa0\xdf\x9b\xd6\x03\xf8\x1c2\xb9\x84*w\xacP\xe5\x8e\x15\xaa\xdc\xb1B\x95;V\xa8r\xc7\n\xa5\xe6\x8b\x98?\x91Z\x10\xdcP\xd8\n\xc2\xcaV\x80\xbf\xa6\xb7z\x05\xa4\x17R\x8b\x03\xaa\x07Te\xa5\xc3\x8fo\\X\xd9\x1a\x17\x88\xc4\xb6 C<\xb3hkjo);O)\x0e\x8d}\x914\xc1'+\xf2N%$n\x90\xba<2)\xb9\x12\xe6\xeb\xd3oF\xfd\ns%\x92\xd1m\xf9\x99\x8b*\xec\xe3\xd2/uJ\xeb\xbcO\xb2\xbbK/\xae\xf7h\xd82\n\xb4\x9a\x11\xc8\xcf\x9c\\\xd1Z\xef6\xfa{Q6\x84\xf4\xe8\xa5\xb8\xa4\xc3q\xfa\xac\x1d\xfd\x94\x02\xbf\xe1\n\xdd\x94\xaeF\xb3\xca\x08-Z\xe0RK\x1d*3\x9aP\xfeB\x0d\xc3\xac%\xe6\x02d\xccbb\xe1\x9a\x13\"\xa0Y\xaf\xb8B8\x9d\x12t\x8b\x10v\x9a\xdau\x0dk\xd0\xd4.\xab\xfeYhj/\xf8\x0cVx\xa4\x06\x9dW\xa0\xf6\xf6\xb1S8\x84\x95\x17%\x0b\x92c\xaeS\x8d\"\xe1\x0c\x0ea\xc9\xc5!5\xd4\x11\x1c\x82\xcf8u&\xe2h\x93\xfa\x9d\xd7\xd0\xe4\xdc_g\xb1>\x07\xe0q\x0d\xced%\x0d\xec#8\x84\xadU'\xdeqH\xe1P\xc5\xe5Q%\xfcw\x0c~\x9d\x86$>b\xbd\xd6\x81\xbf`\xe06%\x80^2\xd0*.\xd3TL\xe75\x83\xb7Tp?\x17\x9b\x16i\x97'\xa1Q\xf4\xc8\xbaPP\xf1\x05\xb8g\xee\xc8$/>\x15+\x84\xc5\xb2x\xc7\x9c1<\x7f;\xe6\x8a\xe7\xe7~6r\x7f\x7f\xdfe3\xba\xd7\xafp\x08O\xb9\xc4\x87\x88\xe9\xf4>\xa0\x16\xf1\xeaP?4M=ma\x98#\x94\xe0\x99W`m\xa0hq1r\xbb0T\xccf@KR\x1e\xe3M\xb6AF\xee\xaf\"\xec\xd70\x9b&A2J\x82x\x13\x92W\xc4\x0f_$\xf1E\x8b\xcb\xec^\xf4\xd0\xa3\xc7\xcd\xaf\xf0\x10\xcaJy\x95\xf0;\xa7U\x9fj\xc5V\xce\x9f\xb9\x8d\xcc\x89\xcd\x151\xf5]L\xfb[\xfaI\x85\xe6\x8d9T\xd1^\x9c\xba\xbe\xe8\x01k\xda\xf7V~Q\xad\x1d\x9d\xf2\x90g\xfb\xacnQ\xb9\x14\x07\x95T\x0b\xd2\x9b\xebd\x0c\xcfu\xf3(\x99C\xcdi\xc4\x80\x7f\xc9\xa3\x92hg\xfc\xbd\xde\xfcq\x8e\xbe\xcc\x94v\x9d[\x04\x8a\x89K\xb0\xc0\x94\x1d\xa2l/+&\xf5\xd7\xbf\xe6d\xe1\x08\x97.\xda\xae\x8a\xebQ\xe0;\xddu?Y8\xf05/a\xdcF\x0bTeo\x1a\x16\xff\xd6\xbc\x9a\xb1p\x0d3\xbe&\x16\xaey\xe5\xda\xb8\xb8\xe6\x95\xf2\x1893\xa4\xe0\xd0[{<5%V\xba\xa4YK\\\xc8t\xc9\xd9IqiMKw*\xcd]\xaeQ\xf2)\xe3\xfe\x9aW\xdb\xa4\xc2h\x9by\xf68[(\x8f\x19\x17\x97,v\xbc~V+-(J_\xd6^b\x1c\xeb\xf0q\n1A3\x06A\x05\xe4\x1b\x92\xa2\xf7\xf9\x18\xde\xed\x98\xdc`\x07M>8p\x03\xdc\x0ds#\xd7l,'\xf4K\x9f\xb9\x85+\x03\xff\xafN\xdd>D\xd7\x1f]\xa1\x9a\x7f\xb0n\x7f\xe7}-[\x8bn\xab\xa7\xa7z\x93\xa1\xaa\xf1\x17\xba\x86E\xd5\x1f_\x94)l\xd8&T\xa7\xc4\x18\xce\xcc\xbb\xcdj\xacL\x9dWQ\xf3\xe6\xd0\x1b6Y\xd3\xcet\x84@2\xf1Q\"\x11\xd6\xa8\x19\xcc5[o\xe84\xbe\xb60q\x1b8\x1e\xf5\x94\xb4\xec\xd7|-\x04#E9\x9b\xee-\xef\x1da\xc7(\x88\xc4\xd5\xc7\xe4\xb7^\xd2\xb9\xe6\xd51\xb1\xcb\xf4>\x8a\xf5\x1e\xc3\\\x9b\x83q\xed\xc7\xb5\x83\x81\xc3\x9d=\n\xd0E\xa1 \xe1\xa8^ar\xa43\x1a\x83\x03l\xe9\xbc\xda\x06Uq\x9b?i:\xf1\x9d\x16\xc5+K\x89u\x9a}MV\xfc\xa6Z^S{\xb1c\xa2\xd0\xd5^D>T\x88\x02L\xb5\xfd\"\x0fIN\xc2\x91\x9bhV\x94\x1fB3\xf8I\xb1p\xd5\xd4\x1di\xa6\xee\x91n\xea\xb8h;\x83#\xeb\x99\xd3\xf7e4\xae\x04\xfc+\xb5w\x0e0r\x1e\xc3C8\xf6\xcaT\xc6\x85v\xa2W\xba\x97\xe1\xc0}i\"T\xc8\xb5i\x14<\xf4JpP\x06 :B\xad\xfe\x11,\x17\x064\xa4p\xa4\xad\x87Yo\xdf\x9fR\xe0\xaa\x92j\x95{\x1f\xbc\x94\x05i\xa5\xb7 \xd5fCF \x85u\xe8\xf7\xf7]s\x89\xcc\x9a\xd7TL6T\xffm\x9b\xd0\xea\xbf\xf8\xcdke\x13Z)sG\xacTQ%+UT\xc9J\x15U\xb2RE\x95\xacTQ%+\xa5Mh%lB+\x8c\xc8\xbf-\xb5\x04\xb1g\xbd/W\xe6\xa0\xf6\xedP\xf4]\x91no\xf5\xf1\x0dE[[C\xd1\x97(\x94\x8e\xd1\xca\x14\x85\xa2\xb7\x88d~^\x90\x90oq\x85X\x85\x91\"\x1bt\xdd\x7f\xd9\x04\x1fd\xf2\x12!)\x9c\x1bSk3\x99\xff|\xa9\x16b)\x10S\x91@\x94\x14\xa5\x9f\x04$]\x00\x0b<4\xebC\x12\x1e,\xf9$\x8aQ=\xa52\x8f\x89+\xf1R\x16\xc6g\x91\xc3\xa0y\xe56\xe6\xb5\xe6\xd5] \xca\x0cobydn\xf3R\x9cD\xd5\xe31~\xca\x0f\xbf+^\x93\xf3\xd2\xd5L,\xd7\x1bZ\xf7\xbc\xd3\xe3\x92\xf2\x07\xac\xaa\xbbN\x03!C\xafO\x1b\xa4r\x95\xd9\x02PN\x90\xec\x15\xd7\xea\x88W\x07a\xec\x942@\xb9)\x95\xbd$b\x7f^\xa2\xabWc\xd5\xb4\xb4d\xd6\xc1g\x16YB\xad\xccu\xac^\xc9&\x97$T\x12\x17\xabR\xc2\xf9|5\x98_\x9b;Xz\x8d\x87\xf0\xfb{\xd0\xba\x0fo\x06d>-\xdav\xa3\xd6nT\xbf\x85\xf5A\x06X\xd5\xe8\xc1\\\xfb\xf2\xa1\xa6\x8b\x92\xcf\xc7~I\xb0\xbe\xe8\xebhMt\"\xf4\xba\x9a\x04\x8d4$\xc9\xf5\xd5\xbc(\xc5\xa7\xcb\x92\x8aL\x0d7\xffo\xc3\x87\xe9_\xad \xf6\x9b\x91W\x92\xa2t\x93\x11\x05\xf6O\x1c>#\x93\xc7Q\x91\xa5\x05f\xe6w\xde\xd2\xe3\xe3\xa6_\x96~\xb0\xa2\x07\xb5xI\x05.\xbe%4,\xa1\xdd\xb7\xa4\xe0\xbd~5\xb4G\xec[\xf4h\x82\xd7\xb9\x9f\x14\x0b\x92\xcb\xba\xd6|\xa3\xd75\xeb\xcfI\xdf\xd0(\x8f\xe9*8\xf4\x98u Jx\x9c\xb9\xe9$\xa4[\xf9\xa2\xca\xb1Q\x92\xf3\xf2\xe6\xaa\\\xc7\x16\xban\x0c\xce\xe9\x1e\xf0\xc2\xcaV%;(\xa5\xc9\x0ed\x17K\x80pa\x84\xed\xca?\xb2\xebT\x9f\x94`n\xf1\x8938\x84\x93\x0b\xca\xd0\x15\x9byQ\xe6n\xea\xc5~Q>MBr\xfeb\xe1:7\x9d\x11\xdc\x80\xe9h\x0c\xa7o\xbd_\xd3(q\x9d\x99n\x9b\x8a\x0b\xed\xfc*D\xd5l\x08=\x13\xd4\xc9\xfdpdZv\xe0K\x7f^\x99{\xc8y\x99\xfbA\xf9\x84\xe7oz\x92\xa7k\xde\x8fF7\x98W\xc4\xc8=2\x18\x84\xe8\x85!<\xb43\xcc\xeaG\xe7\xf3\xdc\xc0 i\x9fR\x1aTy]\xd6\x99+\xe8\xc7%\xb7yB\x8b\x17\xf9\x8b\x8c$\x1c3/eIq|\xa3\xc6\x16\xaa\xfa\xec\x06\x07\\\xd8\xa9\x06\x8a\xb88We3hw>\x863\xfd\xa4\x83q\xe2\x9bYf`\x11 #\xff\xb5\x9aM\x91\xcbc\x06g\x83\xc7\xa2|\x81\xb3\xdb\x14\xf1\x94\xe3`)u\xb8\xce\xa8\xfa2\xe7< $%\x96\xd6\x86\xf9\xa6\x84\x8bt\x93\xc3\xd7r/\xda\x99f\x96k\xda\xe7\x06'\x84\xa2\x81\xdbN~\xc8x\xd7\x9b\x14\xe8_7\xb3\xd8\x8f\x92\x9b\x8d\xd9\xff\xc8\x036\xf0k\xc2\x88\xa7\x181\xcc\xe0\xe6\xff\x8d\xd6\xfe\x92\xfc\xebf\x0b\x87\x12\x8f\xbb\xfd\x14\xaeSl\x97\x8e\xd6\xb0\xd1\xa4\xf9\x0e8\xa8Fv\xc0\xd1+\xdb\xd7K\xed!\x80\xf9\x9ed\x9a\xcb\xe6\xb5\xf6\xcf\x7f\x89\xc2r5\x03g\xba\xbf\xff\xff\x93c\" \xe5W7\x94\x073\x1d\xbb\xa8\xd0\xc8\xf0\xb9\xf37a\x94v\xe6\xce\xea\xb8P\x9f\x8d\xf4\x8bzC\x117G\xaa\x1d\xb1tA\xd1h\x1c\xd7O=\x9d\x11]\xado\x96\xacL\xb5\x89\xe8\xc48\xcc\x7f\x88n\x1f\x04O\x17P~\xfc\xbdQ\x9e\xcbtE\xe22o\x0d\xee\xe4\xf5-\xec\xc3C(lw\x80z\xf9\xad\xcd\x7f\x91:\x9c\xf1M\x92\x93 ]&\xd1\xbfIX\x99\x89p\x8e\xbf\x16\x81A\x94\x89\x10A\xee~\x81\xd4\xdd\xd3E\x8a~\xca\xd9/4\xa4\xf8\xd3M\xe4\x06K\x91@\x99\x8a)\xad\x8d\xf7Z\xb7\xa5\xe5\xa5q\xa4\xe1\xc5Vg,\xc0\xb0Tz\x9e*]\xab\xacm\x916UH\x98Yu'\xcb`\x95\xef\xd0}p\xf7\x8e\xc4\x88\xa7\xd7}\xd6\xbe\x9eY\x1c\x95\xeeM\xf7\x9b\x7f\xdd|x\xf2\x7f\xbf}{\xe3\xdb\xd1\xcd\xe5\xc8[DqIr\x0b\x0fK\xfe!\xc7\xa9\xb2\x0dEkY\"\xdc\x8e\xfa\xba\xdd\xdf\xc8\xb6\xbf7\xbf\xf9\xd7\xcd\x1b\xac\x9b\x9c\x11 \xda\x0f\xfb\xf6\x1f\xc6\xaf\xfe\xeb\xa6\xddw7\xb6\xdf\xb5\x9e@\xec\xc0\x9er\\\x80\xc8E0\xef\xf0^$~\xf8\xbdn\xd6\xf8!\xcf\x9d\xd9\xed\x850JuM|\xf0-Li\x13\x0d]Gm\xcb\x9b\xbe\x85\x87\xed?g\xf0\xbb\xe4\xdcg\xb1[\x82\x83\xed?G\xbd\xad'a\x89\xfb\xa01\x1c\xca\xf4\xa6\x01\x1c\xc2IGeSg\xb2\xa5\x7fu\xe2\xac\xe9x\x17c4\x07\xbb\x0b8\x042\x86\xd4]\xd8\xb8\x13\xf3uR)\xeau!]\xec\x14wK\xd6^\xe4\x96\x94uq\x1e\xc5i\x11%\xcb\xd7\xfe\xd2\x81\x19l\xf8\xdd\x17\x19I\xea\xbb>\xbf{L\xe2E\x1b\xdeyM\xe4\xb9\xbe\xe5\x01\x81\xed\xa3\xf7\xfdH\xe2\xba2\x86TeR\x8eLI\xeaX\xfdq\xa4\xe8\xbd\xe7\xad\x81R\x1e\xdf\xa7\x88\x15O&\xf2\x9e\xd2\xad\x95\xbb\xc9\x18b\x85\x92\x0fK\x89\xc3\x0d\x88\xfa\xef\xa3b\xb69\x83us7n\x8c\xa1\xd0\xd9Y(J\xa4'%L@\xe7\xbe\x1dVP\x07\nM\xa1|\xb8l\xb9\xf0\xef\x0c\xe7 ov\xbb\x1aV\x8f\x109\x1d\xac\x9c\x057 ds\x0f7 \xab~ET\xe8\xc4\x80\x05\xec\xcd\x18\xb0\xeb\xc6\xf0kh\xd0\xa6\x0eN\xb4\xc7\xc3\x81\x02o\x91\xe6G~\xb0\xb2\xdb\x1e\xd9 yK\xf7_\xf7\xe4\xa42jfw\xaa\xf0/\xed\xedu\xfc%F\\\xfb\xfb\xaf\xa6o\xe9%\x12\xb6\xde\xfc\xfb^\xdd\xc0\xdf!'\x19\xf1\xd1vB\x99\xbaoVe\x99\x15\xb3\x9b7\x97Q\xb9\xda\xcc\xbd ]\xdf\xfc5M\x8a`\x15G\xc9;\x92\x977[\xf0\xdf6\xbe\xd4\xfc\xe8\xa34\xbb\xc8\xa3\xe5\xaa\x047\x18\xc1\xc1\xfe\xf4\xf6\xe4`\x7fzg\x0c?\xa6 \x1cW\x1f\xf3\x9a\xef<\x8b\x02\x92\x14$\x84M\x12\x92\x1c\xca\x15\x81\xe7O_\x8b\xdbM\xd0\x9b\xd5od\x06X\xd4c3\xb3\x842\x7frw\xdeq\xe3\x08Ab\xaf\x12$\xc8\x08\xcaU\x9e\x9e\xa1\x9d\xe1\xf5EF\x8e\xf2<\xcd]\x87\x9cgL\xdd\xe6\x03\x7fI\x92\"y\x8a(]\x8e*^\xa3\x0fr\xd0\x05\x81\x1b]0\xe1\xa9@\xc4\xc1\xf4w(\xfb\x1f\xca\x19\xf7A\xa9~\xc3\xce\x98\x8fX\x16\xf4\xfe\xc4@S\x9d\x97Vg\xde!\xc5\x1b\xde\x97\xca\x1e\xb1O\xb1\xa9\xfd*z\xc7|\x8d\xa5\x00\xaa\x97\xd1\x0d\xe3[\x98~=\xa2''\x0b]qS\xb8q\x88F\xf8\x12\xbe\xfd\xf6\x10\xa6c:\xc4\xc3\xee\x18E\x8b\xf4P\xe2o\xb4\x1a\x1f\x86\xed5cxw:2\xe1\x82\xc2\xbb)w\xc9\xc8+\xd3g\xe9\x99\xa8D;\xac\x0f\x1f\xdd\x99\xed3,\xfe\xba\xa82\x1b\xd0_\xf7F\x7f\x8e\x82\xaf\xdb/\x05f\xd4\x05f\x84\x17\xfd\x80h8\x81\xe0\xb9\xaa\x8a\xf6\xa8\xe2\xa8\x8e\xceKM1\xef\xb4[\xb2;U\x97\xecN?\xbeZ\x88 t\x9d\xb1\x98-\x8b\xe6z\xddReh>t\xb7Jy\xa7\xd3Sr^\x92\xa4\xe8\x1d\xf6\xef\x99\xe7\xd4\x0c\x9c1\xf0\xa3)1\xd7\xda\x8e\xae\x1bB=e\x9ecG\xeb\xac\xbc0\x94\x89\xef\xc5\xd4\x8a*\xf1\x98S\xb5~'\x12\xfa\xc9\x88\xeb'\xafU\xc5x\xd5\xc8m\xf0\x10\xb1B\x85\x88Q\xc1\xbf(9\xea\x98\xf9S}\x02\xfb\xfc\x0b\x8f\xa3\x02)\x9d\x14\xa1\xf9\xb9\x8f4\x0f{\x8d\xda-\xf4\xf6\xbb\x0c\xaew\xf4\xa9-\xd4\xa7\xad\x9c\"\x0e\x9d\x96\xe9r\xa9\x11>B\xdesY\xfa\xe7\x9e\xeb\x86\xba\xbfQ\x92mJi#\xcc\x04\xee\x04+\x12\xbc\x9b\xa7\xe7\x12MY\xa3\x0b\xfd\x87\xf8\x1e\x1e!\xa8t\x90(tj^\xc9\xac\x9c\x8c\\Q\xc1\xda\xe3\x1f6\x1e\xb7\xa318\xc7$ \x01'\x95mL\xa7\xe7#\xf4Y\x95\xe8\xff\xa49\xa1\xe5&\x93Pj2Q\x94\x93T\xa4\x88\xbeu\xd0\xcb\x0b\xf0%\x17\xb4\xdc\xb0ag\xd4\xb0\xcd\x05-v\xe0.f\x82\xa1\xeeG_}\xd5\xfa[-F$&\x1bD\xc3\x02\x90TC\x18\xb9\x89'$\xc618\xcc9\x03\xad\xcb\x88\x13\xcc\xbaLD^\xc2\x84\xd5PB\x91\xbfOG\x9a\x96\x14\xebCK\\\xdbai\xb2\xad\x94\xc8y\xad\xc2W\x03\xa5\xd6\x9af\x1fS\x1aX\xc9\xb4\x9b\x1a\x94\x8a\xc4\xda\x05IxT6\xce\x15.\x04N\x1e\xe5\xe4\xdct\x0c\xfe\x186*S\x10\xe6\xf3\xe6\xd5*X\xcdA\x8b\x8c\x05\xc2\x00c\x9ci\xc6KX\xea\xf6\x13\x10u M\xd3\xc8\xca\xb5WHg\\\x18\xb5r\"\x19C\xae\x98\xdbF\xf4\"\x96\xf0`k!\x0e\xb3\xaf\xbe\x02\x07\xb5Y\xb8\xdf\xd2z\xa1t\xfa$\xc1\x9a\xe9\xa2\x96\x01\xcf\xc3\xa88>\xf3\x97K\x92\x1f\xa0N\xd6\x87\xaa\x8d\xf3I\x9d\xf9\xf6\x8f?\xd8]L\xcf\xcbi\x11\x8f\xed\xad\xefW w\xabT\x8aj\x88\xc67f\xd8\x0b\x9e=\xea\xab\xaf\xc0m\xf4A\xd1\x83\xddZ\xaa+`\xef \x07\xb0\x1e}tY8h\xb2Y\xcfI\xfe\x9a\xeb\xc7F\xae\xaf\x88\x93\xeb{q\xc90\xdd\x1d}\x9c|\xedU\x12\x86_\xa28~E\x02\x12m\x91;\x91\xd5\xdc\xb7\xce\xc5Ps\xea\x9fxw\x99R\x88G\x97\xda\x83Hd\xa2\x02 \x1b\xee\x84\x1cf*3\x9a\xcd\xeeJ\xab\xed\xe4F\xad|\xd4#q\xa8\x07,%\xf5h\xc4Q=\xd9\xac\x91w\xf5\x81\xe5b\x88:\xf7u\xad \x17\xcd\xc6{53lJoP\x18\x86\xd2\xd84\x1b\x8c\x03\xa1\xff\x9d\x893#'\xbfm\xa2\x9c\x84\x8cT\xe1\xae\xf2\xd9\x19L\xf72\xba\x89x\x8b(/J\xb7\xb3\x01\xb1\x90e\xc1?+jZ\xdam\xc7bTe\xd1\xee\xee\xb4\xfe\x86lo<\x99\x18\xf4\x01\xbc\x05\xec\xce+\xc3q\x9fX\xee\x8f|@V\x8e\xb4\x865\x98\xcb#.?sm\xaf\x9e\xd7 Z{\xfe\xa6%\xaa\x0b\x95\xb7\x1e#\xad\xe9M`Mo\xc2\xea\xb3\xe6\n\x0f\x85\x91\xde`\x95\x07cj\x11\xafX\xa5gGB\xdde(\xef\xc0\xa0\x1f\xa5\xebu\x9a\xd8\xbcs\x81^\xd9\xce\x8fE\x9a\xb0\xcc\xe7O\xd2|m*)\x9b\xbb\xcc\x98\xfc=\x0b\xaaQ\xc2\x9e\n\xc7\n\xc6n\xa8\x01\xcf\xe0\xb0\xc9\xa2\x9c\x9a\x0b\x98\xceM\xf6\xac\xb6\xc1\xc9`\x15Y$Zk6\xd4\xf6#\x83\x95)\xa8\xec3\x85W\x15S\x10\xd8\xea\x06\x06\xbbP\xd0\xf4\x8f\xa2\x9fh\xa4\xf3\xc1{\xf4\x135\xcd$E\xd9\xc8\\hot\x92\x91I\xbbwk\xf3\x93\xa1\xf4X\xc3\xc2\xa3\xc9\x05\x04\x83\x8b\xb65\x8dL\x81\x12R\x97\xe1\xe4\x88\xe1\xafm\x0d\x8ds\x06nSC\xe3\xb8\xb13\xb8\"\xddT&\xa4 \xde\x94!MEC\n-\x93\x12P\x89^\xfd\x81\xef\xea]\xb9H\xf3\xb5\xaf\xed\xe5\x0b8\x04\xf4\x81^!7Rv\x18\x11\xed\x86x \x87\xf0\x82\xbdP\x1a\x10\xf45%\x00\xb47\x8f\xfd\xd2wL5\xf8\x9eS\xe8'\x15t\x94\xd4\xa1\xe5\xea\x97\x9e\xd6\xc3\xae\x19\x0e5\xf8\xaf\xa2\xf3(\x0cD%Y\x17T\x16\xc0\x81t\xab\xc95\xaf\x9f\xe0\x10\xde\xc1Cx\xd7\xe5\xa1\x1cM$\xe7+8\xc4\xc0GW\xd4\xa2\xe8\x12\xf0\x91[Vy{\x95_y\x0c\x87\xb0n~e\xe0\xfb\xcf,\x12Y\xbd\xb1\x80\xf9\xcd\x02\xe6 \x1c\xc2\xdeT\xab)h0z\xcc\xe9\xfeY\x8dOl=:\xec\xe03:v\xda\xc1gM\xbew\x8c\xfd\xe1\xb7\x84(\x87\x86\xe37\xf5\xf7\x04h\xe3koh\x9bo\xea\xf0e\xda\x03\xec\xf5~\x1b\x8e\xf5\xed\xb7\xfa[U\x1b\xe3f\xccB\xd9\x15G\xb1\x02FWL\xd6z\xa4\xe8\xf3\xf6\xb3\xdc\xfbH\x17&\xa8\xb0\x99\xd9\xba$4\xdf\x8c\x12\xa7\xe5\xde }\xe9\ns\xf8\x0fq&\xba\nC\xffSx\xd82#\xd2\x06\xa1\xa2\x070\xeb=T\xf6\xa6=\xb9\xf8au\xc6\x00VF]\xddC\xabT\x0dA\x1ac\xbe\x10\xdaS\xf5\xd9\xa7\xea\xaf\xf3?\xff\xef\xefN\xc3\x8f\xee*f\xb39Y\x9a:\xe9cx9\x86_Q\x0fu\xe2\xc0\x0d\xf8\x15n\x80\xf3\xd6\x19\xc3w\x18\xc2\xb7\xf3\xac\xb5z\x92\xa7\xd9\x84\x9fg\xca)p\xffJ\x1b\x1d\x833\xd2o\xb5\x1d\xa7 $YN\x02\xbfT\xad\xcf\xfbq}\x96\xd6\xdb\xbf\xf1\x16\xc6\x846\xfe\xfep\xab\x15i\x9c\xe4\\g\xdcb\xdbq\xba\xc6\xb0\xa4}~%\x94\xe3\xaf\xae4G\xfa\xb1\x89\x9dgnW\x14o&\x14\x83\x0c\xeeR\xe7\xff\xb0H\xa9~\xfe\xb3\x1f\xeb\xcb\xb0\xc8g\xa8N\xa0\xbf\xa63\xf2X\xcc\xc8\xe3\xff\xf8\x19\xb9\xc2\x1a+;8wV\xdb\xa9\xe1\xe2\xa9!\xca\xe7Zz\xcc\xeb\x9f\xc8\xbei\xc2\x8a\xbd3\xd4\x0b\xc3\x1f\x7f\xc0\xde\x13\xb3$\xab\xed\x87\xca\xf9\x85\xb2+\xea\xb5\x14\xbdw\xbe\x89\xbe\xfdn\xebG1\xa6\xe2@V\xb4\xf8\xe6f\xf4-=\xe6\xe0\x06\xbc\xb1\x88\x8eo^\xc2|\xaa\xc1\x8f\xda7\x8f\x07\xf5\x8eU\xc9\xcd\xde\x8fZ3\xd5\xe0\x94~\xfb0s&\xd82\xbbi\xe3*A6i\x8d9\xfbM9\x98\xd7t,{\xcf\xb5'Z+\xcb\x13\xc6\xdc\xce\x0cY\xed*)\x07\xcb\xebP\x94\x8a\xcc\xd3\xa3\xad$o\xd0uX\xebM\xb8N\xf3'5\x84`\xabf\xf0T\x0d\xd4\xd8Z\xf2\xedVK\x9d\x8c\xd5\xa2\x14\x0f&\xd0p\xb9m\x83\xcfXx\xbd%\xef\xbb\xabV\x84\xd0\xc5+fB\xccc\x7f\xea\x1a\x12\xf5\\^(\x11\x087\xc3\x0b\x0d\xc5:\xd2-\xab\xf5\xba\xd5\x0e\x96\xdd\xba\x88\x06\xa4\xe0\x0e\xd9\x9a\xacVvZ\x1f{\x8d\x8f\x98\xb3\x8e\xd6A\xb3*\xa2\xf6\x8d<\x89\xa5\x84H\xefX\x01G\x816M\x1d\x8en\x9a\x84K\xda\xac\xa9\xc9\xa9\xec\xe0\xc7\xa4,\xa3d\xf9$\xcd\xdd\xa0'g4\x183\xcdD\xd4>k3\xf8\x89\xb96PY\xf5'\xe4U\xd4\xaf %\xa7~\xf6\xae\xca\x89\xf9\xfa\x97R T\xaeT\x81\xca\x95*P\xb9R\x05*W\xaa`\x98+U\xe0\x16\x8d\x8e\x06jO\xe2\xe0\xe3\xfb?-l\xfd\x9f\xbe\x04\x98\x0b@\xfb\x00\xf38\n\xde}j\x87\x17k?$R[?4goevS\xc30\xcb\xe0\x1aU\xferma\xe2m\xfd8\xe2\x85\x1e\xfcu\xe1\x9e\xa4c\xf0\x91\x02UO\xbe'\x8b4'\xfcp\x12\x00\xa8\xb7\xe3\xb3\xe4\xa5 \x7f\xca|::7\xdd\xd1\x18\x12\x8f\xf0?4\xc7\x82\x18\xb4\xf6\x04\xce\xf0\xf4\xd5\x9c\xa3kn\xe1\xe8\xfb\xec\x02\x12*\x837\xda\xcb<\x0d7\xc1\xb0\xb8\xfe\xca\xdb\x8f\x8d\\\x92r\x80\x7f\x94\x19\xc9O\x04 \xae^\xf5\x1a\xeb\xf8\xdb?i,\xbf)\xf6y\xce\xa2\xabme\x93y\x99\x00G)\x10\xe1G\xfc\xd8f\xa9\xa6\xae\xdb\xb1\x8d\x19X\xee\xab\xb2\xc6H+\xa0I\xd3\xc9\xf8\xaat2\x1bU:\x99B\x95N&\xe6\x0f\xe4\x15\xd0Z\xb9c\xaeY\xc6\x98\xfeG\x84\x1e\xfa/\x0f\x1e<\x90 \xe9\"M\xcac\xa6\xcfv\xa2\xd2\x8f\xa3\xa0\x1b\xa2\xd3\xfa34\xd2'\x03\xe3\x00m\x1a!)\x83\xd6\xab\xbb\xa4\xf6\x93\xee\x94\x1fc\xc72\x03\xaf\x18\x02#\xff\xdb\xe9\xd1\x8e\xa5\x9b\xc0L\xb9`\x00\xf5\x82\x81\xfeEP\xb1\x08\xc62@\xc0\x19\x04:\xac\xb6\x17\xd1\xc8u\xc4\xd6V\xf9\x05C#\x94\x06\x9ae\xe1wVyC\x87\xd0\xf2\xfe\xeb\xe39\x01\xf46&C>\x06\x90\xb7yz\xaaI\xca\x00\x9c>\xff\xc0\xcb\xa9\xea\xe3\xe4\x8dI\x06@\xde\x85\xdd\x86;$\xd3\xc0\xd0.M\xf2\xf4l\xd7^\xed\xd2\\\x90\xc6\xfa\x05\xb8l\x92\x02\xd8\xb1\xddV6\x82\x8f\xdf<\xf3\x1a\x1a\x90\x05\xa1\xf4HR\xe6\x17\xb2\x12\xb9&\xdd\xb1\xf0\x01\xee\xc8?d\x0c\x07\x06\xbf%\x10\xee\xbb'\xfb\x9ax\x10q\xa1\x0b\xef\xc9\xd4\xa2\xda\xcf\x9e$\x1f\x83\x1b\x8d\xaa<\x81\xeaL\xd5\xe2\x12N\xbc\x91\xd7\xf1\x19\x7f;\x12N\xb4\x1dOr\xee=\x02\xb3\xc6S\xa3G\x89\xb86\xb2\xa6Z\x0e\xec\xfa\xee\x9a\xd8W\x8b\xbd\x0c\xe2HJ\xb5`\x97\xf0\x0f\x10\xd7P|\x06\xd6lz \x13\x94\xb8vl:\x92(\xa3?]o|^Fb\xa39H\x13\x9b\xf6)\x97\x80\xb6CGx\xcb\x991\x95\xbe\x83\xa6D\x83\x97\xa0\x80\xe5\xdcb\xa6\x1f\x94F\xfdX\xc3t\x93CHS\xbd\x83\x94c\xeb\x88?x\xcbP\x82\xba)\n\x85x\xf7\xba\x89B\x9fT\x83\x19\xc8\x04\x1e* \xb9\x81\x10xP\xdc\xf93\xa8/\x1b\xfc\xbeDK\xd9g\xf9m#5m$\x90k\xaa/\x19\"m0I\x83\x84Q\x99\xe6F\x0d#SF\x92<\xb7P\\2md\xec_\xa4\x9b\xd2\x02\xbf\xb3p\xb9#\xcc \x884\xdcH\x18\xe55\xf8\xf3\xd5\x07\x84\xcaL\x04\x82gv\x8a\x8c\x04\xe6\xe1\x84W9\x9c+\xeb<\xf3\x0b\x93#\xc8h\xa7tj\xb6\xfc\xfc\xa2\xcdL\xeb\x93\xa7C+\xcc\x19gA>\x05\x0c?u\xc7;\x9e\x95\xa5\xe1h\x14\xec}\xd9<\xa2\x94V\xea\x9d\xf6jo\x9f\xaa\x8f\x9f\xf7c,Mgh\x86\xe9\x90\xf4\xa7\x87\xd031\x7f\x1fVg\xaf\xe9+\xcd\x99\x0fx\x08+\xb7\x03\xc5\x1c\xc3\x1a\xae_\x02\x16Co\xc4\xcd\xcc/W\xf8\xbe\xb2\x1f\xc5\xda\x8f\xe3F-F\xbf\x84\xee\xeb\x0d\x7fW\xf5gt\xce\xebFw\xff\xb3UT\x92\xe3\xcc\x0f\x98k;\x99\xe0\n\xabw\x95U\x15Gi\xaa\x01>\xb05)\n\x7fI\xb4\x07\x8b\x16]\x8cC\xc2\x8a\xa0\x93\x90\x04)3\x91;3p\xb0\x12\x8aah\xc1&/\xd0\xdc\x94\xa5QR*\xb9\x1f\xd9\xd8\xb0\xb6\xb5\x8e\xe6i\xaa(W\x07\x7f\xe2\xcd\xa3$t\x19:\xe4R\xbb\xb6\xf3\xe3f\x9dA\x99\x02\x1d\n\xc5\x96\xbc\xd6U\x88\x1fm\xb24\xd4\x04\xb6\x13m\x91C\xe5\xbc\x8c\x8f\x92ZtwJ\x8e%h\x9fEE\xe9E\x05\xfd\x8f\xdb\xd9\x0c\xf6\x9bI\xb2\x97\xb8\x9f\xb0\xc7v\xd5%>\xc4\xd2\x804\xc8!\xfa\xe3&\xe8\xe5\x91c\xcc\xa4\xdd\xa7\xd3\xa4Z\xc6\xd6\xe7v\xde\x19\x9f\x90\x90Z\x13I\x0c\x0fB\xc4\xfd\xc8$\xcd~3\xff\x99 \xd5\x95\xd2\xa86\xd6Z\xd1\xab\xf6+\x06\xda%\xd3\xd6\xad\x94\xda:\x17\xd3k9\xce\x88W\xa4t\xc0\xb1\xb1\x1d \x11\xfcd\xff\xadW\xa6o\xe8va\xf5\x8a\xe0\x06\x10\xaf\x88\xa3\x80\xb8\xd3N\xc7\x04-\x81^\x1d10\xa7\xccm\xf2\xa4-\xa51\xfb\xc2\x17\xbd.\xbf,\xf5\xbaA\x95\xbb\xefO\xa3\xe1\xfd\xe2\xa0jQ\x01\xe9\x12>\x87\xe2\x13u\x12O\xdc\n\xd7\xd0\x93\xb0\xca\x92\xf58\n\x9f\xa7\x9bD\x16Td\xab$\xaf\x95\xe3\xcdl\x1fE\x95\xce\xa837\n\xf0*?R\x7f\xb2\xda\xf3!;J>`\xea/\xd2\x1bT\xfbN\x9d\xe6\xa9s\xbf*\x9d\xcf+)0\x9dH\x13G\xa4\xc3\xbf\xc4\xf8?\x81\xb9\xa39\x04\x93\xb5\xa3\xe2\"M\xa6\x0e\xec\xaeV%\xddv\xb3\xda\x89\x89\x82^\xc8&\x8edR^dD\xb0\xb7\xc8f\xba ?\xfe\xa5\x9f\xd1\xe9\x11\x0b4\xd6\xec\xd4\x03s\xcd\xf4\x9c\xf5J\xab\xf7\xd5\xc4\x85\xa9\x06SZp6\xe22\xe9fR\xe6C`\xa5\x953\xe8\xdb\xf8\xa05\x81\x9bR\x8fm\x80\xaeE}\xc7\xda\xe9z\xa5\xdbB\xcf\x98I\x12@\x8fzU\xa9\xf9\x08\x93^~\x93\xe6\x16cI\xb5co\x91\xa7\xeb\x1f\x8fG\xee\x89C\x0f\xb5(@.\xff\xe6\xafE\x9a8o\x1b\x9c\xe3\xf8\xday:\xd3\x1e\xbd\x10!\x06\xcf\xa2\xe4\x9d&5\xfcug\x10\x13\xf7\xb6* \xfdg\xc9\x18^\x05?\x98H\xf9\xc1\xa8\xe2\x07\x93\x11\xe3|\xf6\xbf\x86\x0d|\x03\xc9\xd7\xb0\xa1\xfc`t\xb2i\xf3\x83\x1b ?(\xf8\xcd\x0f\xc5\x08F#M\x12i\xcc\xb2\xf8\xda_\xa2\x05\x17u1\xa7\x8d\x1bLx\xa5\xccn\xa1X,\xb8B\xe6\xad\xd9\xb2\xc5i\xaf3:5\x98\xb1\x96\xc7\x003\xfd)\xf2F\xb7\x87\xa8\xe6G\xe87^d\xd7\xb9\x87\x9f\x80c\x1a\x14\xadf\xed\xf4\x91\x0fq\xfaH\x07\xa4\xcad eK\x7f\xb9$aE\xb8\x0b]\xc6G\xcc\\lv 11\x0f\xf6\x8aB;\xee*\xdd\x92|\x1b\x913S\x8d\xc1\x17\x1c\xceA\xa1p\xb0\xf56\xad\xad\xb7U(\x9d6\xaa\x1e\xf8$\x9f4z\xe8/\x0bg\x0c\xa5\xc1Y\x98y\xcf\x08\xa7\x92\x08\x1dI\x8c\xb6\xe2\x9dye\xa86M\xd5OT\xc2*_\xb8\x84\x9f\x05\xec\xe4\xb6\x00\xf5(sF\x1d\xe8\x9cl\xd4\xee\n\x00=;F\xf7jbPL\xd9\x95\xe6\"\xe9}\xd3\x85\xef\xaa3A\xa7\x87\x1b\x0e\xf3\xa2S\xcd\x89o\x9a\x90\xda\xef\xc1\xe0\x93j\xf4}\x00\xd6\xc3t\x00\xab\x0f-\x0bN\x992\x86PG\x06\xc4U\xa7\xeb7\xc32b\xb36d\xb0\x15\x17\xf33\x8b, \xe9N1$G\x05\xce\xde%\x0d/\xad\xc6\x06\x1e\xc3\xc6\xd29}g_\x0b\x10\x1b\xcc\xa2\xa7\xc6\xf8[q\x898\\C\nSzE\xe1\x0c\xd2*\x19\x93\xc5\x0bt\x8b%Z/\x9c&\xe4\x8b\xec\xa9\x19u\x9b\xc0/s\xb2\x88\xce\xb1\xb0]\xbd\x0c\xc6\xb7W9Y\xcc\xc0\xf9K\xf5\x12\x8e\xc6\xa2\xd9\x8a\xde0\xda\xa1'\x1a\xb6\xfe\xdbR\xb0&\x08&\xca\x8f\xfeM\xe0\x1bVUDM1o5\x0c\xfa?\xa5u\x9cv\x01L*\x0b!J01\xc9\x1eHm&\xad;\x03\xe5[\x83SI_\xa4\xb3\x12D\xa4\x04\xc7Z\xe4\x10\xd2\xc6\xae^\xc9\xcd\xfa1\x1a\xbe?i$.H\xbcS\xfe\x077VQ!\xb0=\xaf\xff%\xf9\xc4\xe5\xf9}\xde\xea\xc7\xe5S\xf964\xb1\xa8\xed\xed*'\x91\xcc\xc3\x98\x8fb\xe4\x9e$\xc8\xdc\xc0\x1e{[V\xe4\xbf=\xab\xd7\x8a\x81\xd7\x1d8I#\xd7\x83\x89Y\xc7\xa1\x9b\x98tJ\xcev\xe2\x9fc\x8fnE\xdd\x99\xc3(\xa5\xe6\x0c1\x9a\x99\x81\x87J\xffB\xa2\xe5\xaa\x9cAN\xb9\x9dy\x1a\xb3,\xa4I\x9a\xaf}m\xfc\x9ez\xec\xb2\xe4\x00j\xf0\x96wl\x9c\x06\xef\xaad\x04\x94e\x1b\xee\x05l%z\x08\x9f\x0b;\xe9\x83\xce\xca$\xf6\xe7$\xc6\xf3HQ#|\x0cI\xdbT\xbc\xb3/\x03(\xdbW'\x1f\xb4\xb0=\xd8\x1c\x1b\xff\x05\xd7B\xcb\xf84Y\xa4o\xf2\x18\x8f'\xfa\xfb{\xbf /\xfdr\xa5Q8JS+\xa4\xaa\xd4\n\x91*\xb5\x82\xafJ\xad\xb0Q\xa5V(T\xa9\x15\xe2Vj\x05\xb4C\xb7\x01\xea\xdc\x0b\xdcR=\xdd\xbf\x16\xa9\x17zsn\xc5\x11h\xdc(\xbeD%5\xe1\x86\x9eY\xab\xb4\xd0\xe8x\xd8\xa95\xe7\x8b\xb5\xd3q3(\x16\x84\xb64\xd9\xe4jR\xe4\x9c\x00E\x1dx\xf3\xea\x19\x96\xc1-\xd1g\xc1\x81\xb7\xbb$\x80\xd11\xb6vn\xd1\x06\x0c\x85O\x8c\xa5\xd0\x9b\x05\xb8\x12l\x053\xc6\xc2\x00\xac\x85\x81\x98\x0b\x15\xf6\x86~i\x90\x89\x93\x01\x1aM\x00h:\x9e\xf3\x94\x9c\x7f\xfc\x01N\xb9\"\x10\x92-\x89\xe9\xc9c\x905\xd3\xfa\x0b\x14\x93-\x14|\x1c\x9a\xac\xfd\xc8\x08\xefc\xf2<\x87\xb2p\x16\xf1\x1fV\x8cL\xaa\x15/mX\x1e\xa3\x86\x8aq\x94.\x96\xf5*\xfc$*\xa3\x7f\x937y\x99%r\x90\xfb\xbb\x9d8\xc5\x14\x9e\x945\xd4\xb1\xf3L\xb5\xb9\xc9c\x1d\x10\xb3\xd3\x08\xee\xc4\xe4\xe5^\xa2\x0c\xa9\x83bR[S\xca\xd3A\xc7\xcc\xea\x83L\xee\x15x\xcdc\xee\x98\xbc\xcaV\xa8\xa6\xe1\xb1\x8e\x86\xd3\xdeh\xf99\xe4\x984\x829c\x085\x06\xbc\x9a\x19\xd4\x9cZ\xcd9\xd4\xba\x91\xb6\xcfA\x85\xa3\x8d\xfa\xa4\xb8\x949\xb9y8\xb0\xda\xfe\xd7\xedp(T\x87C\xa1:\x1c\n\xd5\xe1P\xa8\x0e\x87\x82\x1d\x0e2\x92_||\x92\xaf\xd7\xa0\x7f!\xf9\xe2\xb2%\xf9\xc2/v\x97 Z\xc6\x1cXo\xa1\xf8Zn\xa1\xeb\xc1_\xf5\xf7\xd6\x17v\xea\xcf\xb2\xb7v\xd6/4u\x0b\x8b4Ugp\xfa\x8f;\xf7\xae\xc7\xa6\x157\xffDB\xd1\x97\x94B\xda\x94BO0\x9f9K\xff`4\xe5\x03\x9fO\x1ed\xd7\xc8 $\x17\x06\"i\\\xf4&\x0b\xfd\x92\xb0\x86e\xc6\xdbO\x9e{\xe8\xd2d\xf2\x03K\x9d\x83\x82\xae\xa5\x96\xfdG\xa9\xd6\x90B\xe9\x8e\x13\xa7~\x18%K\x96\xd5\xb8\xf4\xf8\x9f\xc7\xa5_n\xb4B\"\xc5[g\xe1G1 \x07\xbf\x8bn\x85^\xb0\xc9s\x92\x94\x1cC\x0c\xd2\xeb\xef\xef\xb5\x82(\xba\xde\xb9\x1b\x0f\x0b\xea\xd1\x9e\xe5$tF\xdc\xdb\xb0y\xff/\xbe\xefk\xb3\xa07%W\xfa/\x8e\x0dmw{S\xfe\xbb\xaa\x1a\x7f5\x07$\x8e\x1f\xebU\xfaQ\xb2CN\xfa|XK rf\xaa'|\x9d\xce\xa3\x98\xcc`z0\xb4/N\x94d\x1b\xfbTCut$\x9f\x05\xfe\xba\xf2\xe5,\xf6\x03\xb2J\xe3\x90\xe43p\x18\xea\xc0\xfc\x02J\x7f\xa9y\xab\xbc\xc8\xd0\xbeE\xceu\xdf\xee%*j\x12M\xf5k\xd5\xc1_c\x8aS\xe6\x1b\xe2T\xd8\xe28\xa0U<\x84U\x81qs\x14\x94\xdcn\xf6\x81\x13x_O^*S\xf1R\x99\x8a\x97\xcaT\xbcT\xa6\xe2\xa5\xb2a%\xc53\xca\x15\xb4\xeeb`L\xa6\x89\x9cY\xe0\xc7\xa6\xfbR.,\xfb\xf8\\X\x08\x87\xf0\x84\xb7\xef!\xebAwO\xbb\xcf\xfa@\x1a\xe8\x84\xd7v\xf0\xa4yYse\xc0{\xa7\xe6\x96\xec8%\x11iK\xfb\xa4Wmn\x19|\xc4B\xa3K\xbf$\xd2\n\xae\xe2\x8a\x8a\xa30*\xbfO\xcfg\xb075\x12\x0bGI\xe4#\xc3.\x86+a\x80`P\x02F\x18\xc0\x13\x81H\x95\xc3\xd8?\xacq]4\xa7\xbef\x96\xac\xcdc\xaa\xd3dx\xb6E\x90\x8cD\x9boB;\x14U\xa2\xb7\xa1#\xf8d\xfel\x8c\xcf\x14\xe7\xde\xa34)6k]\xfeD\xa8\x9c\xd62?\xf7\xd7z@\xe6\xb5\x16\x15\xbcf\xb6\x1e8\x1a\xc2\x1eC\xe5\xb7\x96\xf9\xe5\xea\xb9E\x9a\x8e\xcd\x003\x0ep\n\xbfq\x9d\xefYE\x1c\x0dk\n\x9c\x82o\\\xe759/\xbf\xcb\x89o\x02\xcf\x18\xf8*Z\xae\xe2h\xb9*\x1f\xa5\xa1\xd1\x81,d\xef4R\xf0\x99\xde@\xef\xed\x08\x8bg\xe2Z\x91\x92\xe4\xbfD8[\xfe\xf7\x17OC\x92\x94Qy\xe1\xfa\xdc\xe7<\x1fyu\xd9\x94\xc2\x19s\xd3\xf7\xb3\xa8(Gn\xf7\xc8\xea^[,\xa7\xd9\xe8\x1c\xdb*\xae\xcf?\x9a\x93\xdf6\xa4(\x1f\xd9\xf7~\xddBb\xfai\xc4\xccN*Wq[\xf8,\xc8\xde\x98\xd5\x8c\x0c%\n\xd5\x03}\xfbK\xd1>\x12~=\xec\x05\x1c\xc2\x92\x89\xc7z\xc09\x02V\x07\x85\xd1[\xed\xca\xaa6\xcf\xd3\xf0b\x82X`\xf0zpB\xbf\xf4\x19\xe4\x04c6f\x907#8\xec\xdf\x8e\x92\xfa\xdd(\xd1\xd5\xfc\x1a\xc3\x9c.k\xaa\xa9\xae\xb9\xd8m\xb0\xa7\xa7\xc8\xf0\xc3\x0dpW\x0d\xeb\xa3\x03Q\xb2\xf5\xe3\x88e\x070\x0d\x8a\x93\xdf\x0b\x03\xadk\x8b\x0e+? c\xf2\x82\xdfT\x8f\x9d\xee\xbc\x0b:z\xd5\xc8\x8d\xce@\xaa\x91\x13\xab\n\xa3bp\x9a\x1ej\xca\xae\xee\x8e\x86\x13\x96\x91U_P[\x87\x11\x97i\x9b\x84Q\xa9mX\xd5h1\xa0\xc19\xa6\xa0(\x13\x08\xfc$ 1H\xd6\x86u\x04D%\xb50*\xd5PF\xeck\xa4\xa9(\xd3\xe52&O\x05\x99\xd1\xef\xbc\x87\xe0<\xc2\x1ebG\xe8+u\xd5\x02\xcd\xd2\xb3\x0c\x0e\xa6\xf9X\x95\xeb\xf8 \xd6q\xd8i\xbe\xdb\xf1N\xceKq\x8c\x89L\xb4\xc0\xca\x92\xa9?`\xf4U\xe3\xf8\xbf\xd5Oo;\xf1\xad\x89\xeb\xa9(\x81\xc1\xf9Z\x81\x9d\xad\xe4\xcb\x9a}\xa9L\xea\xd4\xbb\xab\xf0.k\xc7\x9c\xd4\x87\xd1\xaay\\\xf6D\x1eq|\n\xdf8m\x02\xe0\xf6\x04\xe0\xf8\xba\xef\xfd\xfe\xbe+\xbfW\xf3\x17\xca\x1f<\xaaz\x10V\xcf\xdf\xb7\x95\x03\xdb\xa6x\xda\xe5\x97\x9b\x98y\x05\x89\xd9\xfdY\xcdLDU\xde\x10T/\xa5B\xbd\xa4\xd0\x1cQ6\xf9\xe6\xf9:\xbe\x19y%)J*\xceJ\xe1(\x83\x8c\xcbf\x02D\xab\x08<\x84\x84\xc7\x80\xd0\x9e\x9e\x9e\xafYu\xb0\xe6M\x99\xe7P\xb4\x00\x97w~\xef\xf0\x10\n\x9db=\x86C\xd8C\x8e\x0f\x93\x17\xfe\xfe\x9e\x8e\xb2\x903M\xc4+HyLY5W'\x1c\xe1fW\xd4\xb0\x1e\x8d\x9b9\xf1\xf5\x9eH\xc5?\xd7\xb1V\xa1\xd7P\x06(\x12\x9cK\x94u@\xe2\x82\xe0\xdc\xb6\x92\xf3\x17x\x0c\xb8\x0e\xce\xb1\xaa[\xfa.i\xbb\x83L\x88\xacEMc\xda\xcf\xb5)\x0d\x17\xf8\xd97\xad7\x14\xd1I\xafXvK\xb7\xe3R\xae$J\xbcE\xe2E\xc9\x82\xe4\xc7X\xe2\x7f\xe4\xe6<\xdaF\x9dg\x8d\xbe\xb7\xa0h|\x8c=\x16/\xa6\xa8\xefT\xcc\x07+\xb0\xf0K\x1e\x95\xe4E\x12_H\xf3]*\xe6EL{kf\x14\n3\xa1\xf7Lj\x19B=~\n\xf4\xcf\xb5\xa44\x99q\xaf\xf0}\xa2\x90\x90\x0d\x8bOw\xd1i]bc\x0c\xa9|\xdc\xa7C\x06\xee\x92N\xed\x0e\xf8\xe3\x0f\x08G\x0c^\xfa\xf96\x03>\x14\xedl\xe8p\xde%\x98\x89\x82`\xa6\x1d\n\xac\x82\xa3\x84=\xa7Bl\xcb\xe0\xea\x95y\xb4vYA6\xbd!\xb6\xb1\x85\x95ek9\x99\xe8\xc7\xba(\xb0\xb3\xc3J\xea\x8eUh\xa8\xa6k\x0c3+\xd9\xf8;v\x8aURc\xbe\x14^\xc2\xfc\xa8\x0c\xc9\xef\xe5\x96\x8e\xeb\xe9J\x7f\xdd+\x10\xd0\x1f\x0f\xee\xdf\x1a\xfd9\x8a\x10\xfc\xf9\x1c\xc2\x189|\x92\x06\x9bK\x96 \xe2$\x88\x15\x94\xa1\x1cB\x98\x068\x0e\x8f\x9c\x93\xe0Q\xba^\xfbI\xe8:A\x9a]\x98Sd\xc9\xa8\xd4\x07\xf3\xcc\xf0\xb8\x12R\xcd\xb4\x95\x9ck\x88\xeb9%W\xe0\xfd\xae\x0e\xce\xac\x8bK:\x8fX\xee&\xd3\x17\xd5T\xb2]\xbf'\xa3\xd2dQ\xaa\xb3\xcb+\xdb)\xc9y\xe9\xe7D](\x11P\x14CTj)\xbb\xf0\x8ezrs\xe2\x87\x8c7b\xb6q5dk$tZ\xd4\xa0V\x89A[\xc52/\x91\x0bT\xb0E\xf2)\xfd\xa0\xe6\xf7\xebP0\xa7\x7f(m\xe8\xa14\x95\x9dJ\xf4\xc9\xf4\xbe\xecX\xa2O\x1eLUqlj\n$\xbc\xd1N$\xa5\x08(\xe3&\xab?U\xd9|\\gE\xfc\x90\xe4EW$\xa5\xe2h\xe9e\x9bb\xe52T\xc3\x84\x9d\xec\xef\xc9?\x9d\xb1x\x9d\xe5\xd1\xc5\x18N\xfe\xf8o\xce\xdf\xb0zf\x9d\xa1\x08n\xc0\xdf\x9c\xbf\x8dx|\xf4\x06M\x12*V\x93\x9e\xaa{\xfbrTC\xb1Wa@\x0e$9C\xc5U\xe6\x17\x8a\x8dP94.\xc6h{\xea\x9c\x1b\xdd)\xf2HR\xe6\x11)\xa8\x90\x04{.\x16\xba\xa1\xc7i\xe6%\xe4\xbctG#/L\x132\xfa\x9a\x8f\xc2d\x8e\xc4L`6\xd6\x91\x15\xefZ\xe3\xc8\x0d\xc7p`R\xcfS\x9e\xedd\xdfP\xa1b\x8dPS\x89#\xa6\xb8(\x12\xad\x1b\xab\xff\x038\xdd\xd5\xde\xc2\x0dpf\x98?m\xcdW[N\x0b\xfa\x84\x00\x02\xbf\x0cV\xa0>Yc\x86\x11\xb8\xc2}{\xc1{XD\x89\x1f\xc7\xaa\x15V\xaf=\xbd\x98\x12%\xf3\xf8\xa1\xd5\xf8\xed*\x06`h\x0e\xf8\xd6\x89GP\xae\xf2\xf4\x8c\xbb\x07u/\xc9<\xfc\x97\xfa/\xfaA\x8e\x8a\xf34\xbc\x90\xa5\xd6\xa1 \xcez\x13\x97Q\xe6\xe7\xe5\xcdE\x9a\xaf'\xa1_\xfa\xcc\xd1\nG\xe6\xbc|q\xfc\x9a\xfd\xdd\xdd\xbb\x1aNa\xa9\xd9\x8f\xc0-|:\xa7\x8e\xb9f_\x82q}\xaa\xfdy:\xc6\x8c\x1c\xf2\xfd\xc9&\x057\xe7\xc51\xf9\x8d\xefN\xdas\xf7\x14\x0e\xe1\xac\xbb;\x97\xc6\xdd |\xf4G\xfd\x8dw\xca7\xacq\xfb\x01\xcf\xf5qd\xdc\x82\xc0\xb7\xe1\x91v\x1b\x02\x9e\x08|\x0f>q0h>J\x8a\xd2O\x02\x92.j\xae\xdb{\x12\xa1\xb0\xd0\xda\xa0\xe7t\x83\x1e\xfe\xffq\x83z\x89\xbf&\xf4\xef\xaf\xcb\x8b\x8c\x1c\xb2{\xf4'\xdf\xb9(P\xf7\xde5\xeem\x90\xe25X\xedq\x10\x98\xb4?F\x8c\x91\xdb\x05m6\x9f\x1e\x9f\xe8\xb5\x87\xc1\xfcg\x8d=\x7f\xa6\xdf\xf3`\xd94\xf0}x!\xf6\xfe|\xe8\xabe\x0f\x1b\x94\xb7#E\xb5 \x84\x97\x13t\x07uo\xfe\xeb_\xc9\xcd\xe5\x18\x1c\xa7\xab\xd8\xe3\xe3/e\xe5\xac\xdb\x1c\x8d\xcf\xb9\x93[\x8aJz\x9b\x8f'\xc4^7F\xefK\xcc\xca\x97\x98\x95O\x11\xb32 Z%B\x95c\xb0\"k\xab\x9a\xd7\x0dp\xab\xcf\x0b\xf1#29\xd5 c\xa0.K\x1b\xb3\x072\xbeD\xc1/\xa0#\\U_\xb0\x1e\x19\xe2J~\x0dCiZ>\x98\x97\xad\xe3-Q\xde\x148\x01\n\xeb\x1f305\xd6\xff\x9aV\xf0n\xba\xa7\xb1\xd0\x17\x8e\x82H\x9b\xf8\x10\xebr\xdd*p\xcc\xa3\xdb\x1b\xb3x\xfd\xf2c\xff\x00\xca7\xbd\xd2\xad\xea\xbc~_\x91\xf64\xec\xa6\x993;\xae\xd4N+\xbcW\xc3\x95h\xc6\x94\xa3M\x1d\x17o\xc5T\x0e\xf2\x98wF[\x89\xc5\\\xe7[Q\x8c\xdb\xa8\xf6R\x16\x8a\xe1d\x16E\x92\x01u\xfcL\xebdY\xb2\x9b\xf7\xce\xa0Z`\x85\xbd\x95 \xb6%\xbbM[jw\x05\xdf\xf5\x8c\xaf\xf9\xc2\xf7} \xbe\xef\xcfg`\xfa\x14gF\xcd\"\x99\xce\x0d\xcb\xb0\x82|@\x90\x00s\xb1\xa8\xc2\x17\xf91\xac\xd1\x96D\xf8\x02'\xf6\xe6\xd8\xd8\x82\x04\x9b<*/\x1e\xd3}\x1d\x95\xa6Z\xc7t+\xe5\xc6x\xdf\x98A\xf9\x9br\x95\xe6\xd1\xbf\xc9\xf7%\xa5\xb0{\xdd@\xb6\xe6\x15\xb0W\xc4Qx\x05\xf60\x8c\xd4\xe5\xc5&\xff\xf8\x03\xfd\x9d\xae\xc4\xea\xc5\xbax\x890\xda\xcd\xb0\x96\x8a+\x89\xa3m\xce\x86z\"\x02m\xd7\x9a\\\x91>\x84\x94u\\\x9b\xdf\xaa\xb1\xad\xd4\xc6\xae\xcaAX\xb7z<~\xbaJq\xf5\x1f\x9b\xeb\xea\x93zo\xc8\xe3T\x03\xb7ht4P\x1f\xad\xd7\xd9wC\x15Xj\xad6\xd9~\xf8\x80\xd2\x88\xfbP\x89*\xf4\xa1\xc9\x87\n\x1a\xf94\xd2\xe45\xbe\xcchD\xfb\x9e+n\xac\xd3\x90\xc4\x942\x8da\x8f\x07\xaaz\xe4<\xf3\x93\x90\x84#\xa1\xea0\xb8\xc6\n\xf8Y\xff\x13\n\n\xd0\xdf\xc3\xf2\xe9\xdd\x98\xb4&\x18iW\xb5&\x87\x89\x11&\x10S\xc8\xe3\xc8\x94\x1a*S\xb8n=ZE\x9f\xba-\xcd F\x99[\xac\xfeK\xee$\xd8\x86\xeaOI7\x9a\xf7\xc3\xf0^6\x11\xbc\x1f\x8e\x0d[E!9&\xf1\xe2Er\x84\xd3j\xe2\xc5\xf4+\x0d\x15\x1bV\xa1\xb5B\xe7C\xf7D\xd2\x89\x07\xac\xf6F\xdes\x0c\x85!\x1a\x90\x0f\xad\xfd\x11s\x80N\xf0\xf5\x94T\xa3\x19\xb4cw\xd8\xaa\xb6\xf3\xf0 \xb8z\xd4\x82\x98p\x08\x991\x956P\x98|\xaa\xe8\xcd\xfe\xfc\xb2U\xe8b\xae.\xdcl\x88F'\xc1\x0c \xea\xf2\xb6\x0d\xb5\xde*\x8a\xc3\x9c$\x943\xfa(M\xebB\x0d\xcd\x0d\xc9\xc2\xcc\xaasM\xc3Q\xdaxi\x05\x9b\xbc@\xa5[\x96F\x892_\x1c\xf4\xb0\xb7\xba\xcb$\xe7?\xed\xe0v\x1fX\xab\x92\x04%\xaa\x1368\x8c\x8b\x95\xed\x12\x1eP\xe4\xd4\xc7\xa0\"|\x17S\xf6\xcb\xbf Ar\x985a\xbb\x87\xa7\x91J\xf5\x85\x02\x990\xb0h\x1d\xd1\x92\xe8\xb5\xee\xc1\xee\xfc\xeey\xde\xfb\x0e\x89k\xb0C\x1d\xaf\x0f$O\\\xf8i=\x10GO\x9b(v\xdc \xbb\x14\x87~\xbf\x1e\xd2\xf83\xf0\xf9\xbb\x96*\xc11\xfb\xa10\xdc_g\xe5\xe0\xe7!\xc1\xf8A\x19m\xc9k\x7f>\xc8VZ\x99aC\xbf\xf4\x0bR\xa2G\x8e\xfc\xc8\xb6\x92Q\xaa^\xa8\xd5\x12\xbd\xdb\x97\x13JP\x13\x98,\xa2\xa5\x02\x8a\x89%\x86\xc0\xce\x00\x13QW\xb9\x86\x9fS\n\xfc\n\xf9\xaa(Y*E\x18G\xc4\xef#\x8b\x18\xa0k\x1b\x12\xef\xc6\x0d\x97~\xba\x02\xb4HS\xd4\x98\xc1\x98R\xf9\xaa\x8d\x99\xc4\x83\xefc\x0b/W\xc9j7\xb2\xce\xb0-^\xffIg\xafq8\xb5\xe0ly\xef\xc6XG\xee\xc4\xd1\x90\xefG%Y#\x9fY\xd3\x9a\xc3\xc3ff\x9d\xc6\xd9\xf2\x10\x1c\xbe\xb3x^\x96\xc1}\xd3\x07\xadt\xba\x16G\xc9;U\x860\xa8\x92\xd9\xf0$8\x8e9\x9dJ[~\xa8\x86\xa5\x1aDD\xc7{\x14F%`\x8c)\xcb\xbe\xc1\x1a\xe1wX\x154\x8dqd\xd7\xa5\xe0\xe7\xc8\xf5Z\x08\xda\xb3\x88'\xe7i5n\xbbBlTW\xb6>l\xc7\xd6\xb9P\xcc\xb1Y<\x92\xcb\x8c\xe8_}\x05\xe9\x18\x8c\xcb\xa0\xa9\x84\xa65\x071b\xab\xad\x94\xd2.M\xa2\xa1\xf55 \xd5\xa6;h\x1d\x06\xda\xc4'\xa4\xa6\x993\xd0\x14\xb3\x14\x14Y\x97\xef\xb4\xf7\xc0(1~\xdef\xa4\x05\x15\xb1z\x12S\xca\x9f\xf4\xa4\xb2H\xbc\"\x13\xbe\x162\xa9l\xc3\x1f\xf4\xda(\xf8\x83\x9eT\x16K\x0dL(\xfe\xb8qS,W\x1b\x98\x16\x1f_<\xcbl\xc53\xbd\xcfn>\x06\xbf\x7f\x92wy\xdfk\xe3\xb3+\x92\x84ozb\xa2\xc2g7\xed\x8b\x8az\x9f\xdd\xbc6X\x1d\xb6\xb7\x8e\x8aG\xcde\x89\xe3\x01\xabE\xc92\xca\x17\xab\xf4\xcc=a\x94\xb3p\xc6@\xde\xd2o\xf7\xe9\xc0\x989Q\x8c\xbb\xe3\xa5+f\xe9\x0dSH\x85\x1a\xdfN\xa8\xb9\xe6\xbc\xbb\x0dc\x9c6\xf8V\xdd!\x1c\x19B\x9f\x9a\xda\xf8\xe6\x92V\xc7\x05J\xb2Q\xdb\xdb\xb7\x03\xe2E\xc5\xf1*=K\x9aK\xdf\x80\xa6\x1c\xc0[\xccB\xa0?\xa0\xed8\x12\xa6\"\x9d\xa7\xe7J\xdeX\xd5L:\xeejX~o\xa9\xfbu=h\x1e\xb4\xc6\xe3\x93\x84Z\x0f\x8e\x90\x9d\xae\x9ax\xb5ZYY2'P\xf6\xa7\xa9]~l\x97]C\x16\xde\xa7T\xa3\x9f\xf5\x06v<\xabc\xe3\x19\x9d\xe1]\xc3\x19\xed\xea\x1e\x82\xf2\x10\x07\xbe\xad\xd0^\xe2\xf06)g\n%\xc6\x9c\x89^\xcc\xa0c\x84\x16G5\xe7\x02\xfc\xa2\x88\x96h\x931\xeb,\xaa\xe3\x806<\xfd\x1aJ\xf8\xa6w*|\x0d%\xa5\xfcj4\xda\xf2<6\xf5\xa1Pj\x82\xed\xaa&s:\xb4d$\xba]%\xfd\xf6V~\xf1\xe2,\x11l\x0c\xd3\x16b\x04\x02\xeeZr\x92\xd3\x13(9\xc9\xdf\xdaF\xc2B\xe3x\xef\xe3D\x1f\x01S\x1bw\x89\xea\xc4&\xda\xc3\x06\x9aCN\xd8\x81\x9a\xc07PV\xb3\x9b\xe8g\x17\x1a+\\\x9e$\x860\xc6\xdc#\xc9fMr\x7f\x8e\xe7a\xebO,&1\xc6\x9a\x88t\xd3o\x04\xd0\xde\xfe\x18x\xf64\xba$X8\xd1\xcd\xbd\xb3<*+\x88\xd1X\xc1d\x12\xfa\xc1w\xe4B\x1a!\".\xdb\xa0<\xa8\x17\xaa\x9a\xff\x92\x87\x9fh\xa6\xa8\xe27(\xeb\xe66P\x89\xee=^ \x12\xd3B\xe5\xbd\x9c\x84\xe2\xea\xf7\xe5\xbd;\xeao\xb3\xc8\xa8\x8c\xae\xd0\"2\xd5\xb9\xb2\xe2U\x80G>\xee\xb9\xa4\x19\x92Z\x8eD$dB\xce\xe0\xf5EF\x8e\xf2<\xcd]\xe7\x91\x9f$i t\xcf\x80\xcf\x8e\x18\xf0\x0b\xf0\xab\xd6T\x825g\xcbT \xf8\xa014c\x87At\x9a4{\xf9\x8a,HN\x92@t\x956\x08+\xbfH\xfeV\xc2\x9c\x90\x04\xd0\xe5\xd4\x8f\xa3\x82\x840\x81b\x93\x91\xdc\x1d\xb5 \xe8\xb0H\xa8+\xb9\x0f\xf5\xfc\xee\x95h\x97N\x11m\x1d\xd8;\xc4\xcc\x9dt\xf2\x90\xc0V\x13\xd2z\xc2\x98}9\x8e@c\x9e\xdc\xa8\xcd\xba\xf2\xcd\xb1$\xe5K\x81|/\x16nd\xe9\x1e\x0dR\x0c\x1c\x82'\x18\xa5.\x1f\xd2W_\xb1\xc21\xa8\x84V\xa0\xcd1\x9dlz\xe0\xe6\xa4((\xf6\xae7E $*W$\x879a\x1fH\xf3\x06\x1e\x8d\x81\xe2\x99\x037\xaa\x86\x14\xabB\xea\xedX\x9fQ\x8c\x87q\xb1s\xad\xfd\xaaa\x97\xd2\xa4(\xf3\x0d\xe5\xcdL\x96o\xbb\xf8\x8c\x9a2\xea\x8b'\xd0K\xd0\xc2\x996b\x1fX7+\xda*M\xc9'.\x05M\x1cq\x87 \x97\xcfT\xd1\xc2(x\x08\xd2\xfb\x1c7f(\xb9\n\xb4<\x94\x8a)n4\x86\xa62b\x0c)\xbd\xa5-\xd7P\xac\xd2M\x1cV\xef\xbc\xc1l\xa5\x96\x95\x03\xb4\x019\x82\xf5\xc0\xed\xa1\x9d\xd7T\"\xaf\xc2\xb70\xa5s\xd5H\xeeY\xf3 \xd3\xb7\xf0\xb0\xfd\xe7\xacg\x1a\xef^Q+\x01;\xdd\xd7\xaa\x02P\xd0\xa03\xcc\x9f\x81\xa5p}\x910\x1f\x80\x9a$\xbc#\x17\x85\x9b#WNZu(F#\x8flI~Q\xb3\x8b\xdaC\xae\xd1b\xe2E\x05\xf2Ac\xb6y\xb2B\xc9\x0c\x01\xe2\x14\x1e\xfd\xedn\xa2\xb9I\xd1\xcf\x94\x9e\x03\xfd\xeeiW\x12:\xddKO\xa8\x9c\x1c\x9d\x10m\xc7\xe4{\xa0\x8f\xb4\x94S\xef\x18\x06\xbb\xc73\xf1\x9e\xae\xd7\x1b\xdc\xa5\xad$\xc3p\x08\xd1\x18H\x83\x89\x8f4\xbc\x8cNa\x06R\xa5\x19\xb4\x07\xf2\x9e%\x88t\xf7E\xdd\x1d|r\xdd\xb4z\xa14WR\xca\x9f\xdc\xef)\xe9\"\xfe\xa4\xa7\xef\xf3\xf9\x83\x9e\xbeo\xc3\x1f\xf4>U\xf0\x07=}_\xcc\x1f\xf4\xf4}\x81T\xdf\xb7@\xf0\xa0s7\xe3\x1f\xb9\xd7t*\x08\xd5\x8a\xc0\xf0\xe3+\x02\xf5e\x8c\x86(\x02\x15\xc1\xfb=\x97\x0c\xad\"0\x96*\x02\x83J\x11\x18\x8f\xc68\xd7\xfb_\xc3\x02\xbe\x81\xf8kXP\x81%8Y\xb4\x15\x81\x0b;E`a\xab\x08\x8c\xec\x15\x81\x01W\x04.yd\xb2\xff=\xaf\xa9n#\xc7\xf1>\n\xdd_\xcb\xaa\xe0E\xc5\x8b\xef\x8eoa\x01\x87\x93\xdak\xa0p\xc6<\x1e\xc7/\x1cz\xae\x9c8a\x1d1\xe5\xbc\xed\xb5\xf3\x9e\xf7\xeeQ\xc7\x13l@\xff\x1c\xe8\xab\x86\xf0\xb3,\x11\xde\x15h@\x15\x8aN\xce\x8f4\xe7G\xbc\xc0\x93\x1b\xbe\"E\x1aoIx\xbc\x99\x979!\xeeI\xb50\x1d\x85\xaed\x85\\\xbar\xf4\x900\xa5\x17(Z\nU\xdb\xf4\x02\xb1T\xa1\xba\xf9\x04\nU\xbd*\xd5F\xe5\xca\xb2\x1d:\xfaa3<\xcf\xfd\x80\xa0\x8d\x18\xb8#\xb9\xaa=F\xb8,\xa9\x90\x1dE\xb4\xebb\x94$$\x9f\x18z\xa7l\n\x1d&\xad\xdb\xda\x0d\xe1\x9c\x12k' z}\xa4\x99#\xa7\xcc\xb5\x9d\xb1\xcb|\x96\xc6\x98\xf8\xec/w\xef\xde5h\\\x17iR\x1e\xb3o:Q\xe9\xc7Q\xb0C\x9a4\xf5`\xc2\xfa\x90jp\x893GG\x99\x1a/\xa9`^h\xa7(\xdd\xe4\x01\x99\xc1\x91\xbc\xbb\xa3Q\x8d\x80\xe7\x94H\x9f\x8b<\xd0\xe7J\xc3\xb4\x95\x0fw\xc7i\xcf\xa2\x8e\x1b\x0bi2\xd9\xae\xd1=\xe9dj\x80\xa2\xf2\xe4\xa9\x8b\xa7\x8e/\xd8\xf2,'\x81_\xea\x99X\xe0\x02\xe6\nm\xa9^T\xa0I\xf5\x1d~\xe8\x9d\xc7\xad&\x85\x9b\x1b>\x91)\xf3\x1f5\xaf-\xe5\xdc\x03?\xfe.\x8e\x96\xc9\x0c\x9c2\xcd\x0c\xf8I\xaf\x8cr\xff\xc9\xf2\x15\xf7\x9c\xd8\xf7\x0e\xc8\xda\xc03\x1amQ,\x026\xf3(\xfe\xff\x82>\x19p\x08\xce<\x8dC=n\xeaw'\x08\xad\x84&\x0d\x04\xb4I\xca\x86G;Vk\xa5\xde~\xa6=\xa3\xef\x17\xa7\x1c\x99\xee\xfb9\xe7dv'\xcc`K\xa3\xa0A\xa7r\xdd\xb0AIy\x80\x1f<\x7f\xd7s:\xf6sc\xee\xb1\x0c\x81w\xef\xb9\xaa\xcb/\xc7\xddT\x00\x16(\xc7\x03\xbd\xd0V\x99\xc0\x0dp\xf0WN\x7f\x9d\xd2_\xbe\xae'F7\x07!\x0f\x1b-\xf1m\xbf\x00\x83\xd5\xab!\x9b\xf1:\x84\x0d\xcd\x00\x86+\x9a\xdb\xe2\x0e\x02\x81\xa1%\xeeIa\xf0 \xe0Q\xdc\x0b\xb8\xa1\xb3\xa8\x8dd\xd62\xf6\xa46\xa8U\x87\xcc\x99\xf1\xb8\xe7'\xe4\xff\xfc?\xa7\xfdV\xf9\xb1\x0f\xa4\xc4\xea@J\xf9\x81\xa4&\xb2\x18\x8dw>\xe1%b\xbd\"\x8e\x02B{s\xa0,\x08+\xae-/\n\x99\xc2CH\xbd2\xfd\xf1\xb8\xfa\x81S\x9a\xf2 \xb2\x8a\x80\xbc\x0c\x19\x07\xb1\xaf,\x1cU\xac\xc9\x074\x99\xb3{\xf7\xee\xe9i\x07h\xe9\x07\xd8\x1c \x0c\x97\x92K\x92G\x18:\xc6\xc1d\x12l\x86\xda\xf1\xfc\xf3U\xbb\x10\xd4\xbc\xaal\x7f\x1e\xd3\x13\xefX0\x816;\xd5f\xce\x9do\xe0\xef\xf0\xed\xa59]\xc9Q`\"\xd75\xa9\xd6EuZ\xd3\xe9>\x8d\x1e\xaa\x8c\xb5$\xd3\x82D\x1f\xabA\x8c\xe4\x19Is\xb5\xb2\xbf^\xe5z\xa2\x0e\x0c&\xdf\xda\xae\xe8\xaf\x1d\x8am\x88\x197\x91,\x1b\x1f)\xa4W\x9a\xd8\xed+E3\xb0F5\x18\x82n G9T@\xa2\x89\xd2\xdc\x8c\x19\xd5\xa0\x81n\x06\xa7 #\xca\x01(\x92\xad@W\xda\xfc\xe9*\xd1\x11U\xaa\x03\xd0\xf1\xa7/\xe8\xd8\xb8.\x89\x8eL\x9f\xfd\x99\xa3\xe3\xab\xabD\xc7$-\x07 \xa3\x01\xad>\xbf#\x11\x0d\x14Wv\x02\xbe\xba\xec XW\xff\xba\x94 \xa0\xaf\x08\x0e\xe2\xb4\xd0\x94K}\xef\xec\xe0G\x98\x19\xfd\x08\x99\xe1\xee\xba9Pe\xca\xcc\x90\x99\xd4M*\xe2O\xa41\xe4\x99*\x86^z\x971\xa8\xdc\xbc\xac\xdc\xc6\xa0\xf2\xf42\xbbR\x01W\xe1G\x83E\xffd&\xf4\xb7^\x94\x84\xe4\xfc\xc5\xc2\x95\xa4\x12j^\xa6\xd8\xa0%\xcf\xeci\xe1\xfa\x03\xdci\xac\x1c\xe0\xd6\x03\xdcw\xcc&y(p\xe7\xb1\xd2u\xc4\x81h\x02?\x83C\xd8R\xd2~\xb98\x17\xd8\xc5\xbb\x02\xe0\n\"l`wg\x06`\xedo/\x13\xe0d\xd5GK;3\xe8\xe7C\x1b\x9d\x0b\xb5\xeb\x82!\xc4\xaf\xf6L\xf0\xe1\x9bC\xd8\x18\xc8L\xbf\xc2\xd3\x89\xe7yo\xb5#pN\x9c1\xac\x85\xdem\xbd\x9b\xae\x1b:\xfa\xeef\x90\xa9Y\xdf\x0d\xd6:o\xa8\xcc\xb5:\xbd7\x98q\xc1\x18\x97\x05\x95\xe2\xb96\xe2\x98\xfbF\x8f\xd0\x7fX\xaa\xab)\xec\xcf~l\xb4R\nX\xceB\xc9+\x1d\x8aK\x91\xcb\x8a=\xaad\xce\x0c\x1e\xee\x1ej+\x0c\xfb\x1a\x13&m\xa9B\xa9K\xc5\x1b\xb6v\xa3\xa0\xda6C4\x11\x01=\xd4\xfc\x12\xe9\x8c\xc1>\xa51\xb4\xa4\xd8\x80K\xb1V\x078\x0bvN\xb4\x9ex\xd0\x10f\x0d\\\x87\x9dh\x0e\xb5\xe8\xeb\x1bU\x1fcpZ\xf17\xad\xe7\xbd\xbb\x1dy\x14o}\xb6\xb1mr\xc93UI\x9e\x91J\xf2\xf4U\x92\xe7F%y\x16*\xc9S]\xad \xeb\xc5qRy\xd4\xcd\xea0\x9c\xe9\xfe\xe7\"\x80\xde\x9d\xd3\xff]?\x19TR\x14\xa1/\xf4)e\xd0\xf4\x03\xc8\xa0;\xe6\xf8\x87\xeb\"\x83\xdaH\x89\xc9@i5\xddAZ5\xcb\x8a\xfe0Yqc+\xda\x16\x18D\xdb\x0d\x15\xd1{\x03\xb0d\xc4{\xe8\x9f\\E\xa4\x18J\x07\xa0\x06S\x9f\x0d$n\xc4yP\x81\xce\xc2K\x8d\x83/\xd2|\xedk\x95\xb6\xc0\xb7#\x7f\xe1|m\x94\xaa\xb654F\xaa\x1a\xc0\xd7\xd2 \x15\x9f\xfec\xc8\xa7\xb1\x1c\x1c|\x03\\\xa8d\xe1vKR\xd6\x0bG\xf7\xb6\xfeE\x94,\xafL\xf2\xc6\xa9\x19C%\x81\xf3\x95\xb8\x02\x11\x9cw\xf1\xa7\xb4\xdc\xb9\x97\x17\xde\xca/\xcc-\xe9\xe7\xeb\x14\x8fe\x18\x83i.)Y<_\xc7\xe8\xfa\xb7\xfa\x0f\xd9\x13vS\x07;m\x0c\xe3\x84\x83\x81\xf1h\xae\xbd\xf3?\xff\x8f\xfe\xcf\xc1\x14\xe2\xce\x0c\x9c1\x1c\x97y\x94,\xddT\xe7M\xdaL\x94T!\xe8Vw\xe6\x9e\x99&\x83K\xaa[\x03\xa7\xdf\xf2II4=\xbc\x9c\xc2\xcb\\\xfa\xeb:(\xbc\xc6Pz\xe2}I <}\x86\xa7k\x91\xe0I\x14Qj\x8d\xc3&\xd3\x13?\x1e\xfa\xd8\x92T\x8f\x7f\xf6%*\xd9\xb4z\x8c\x87\xc0\x15ef\xe2{\xb2\x97\x0d\xc9*\x05S\xd9\xd9yI3W\x92\x1c\xf9\xa2k\x80|}<\x8be:\xd5\x94?\xe8\xe9T#\xfe\xa0\xa7S\xf5\xf9\x83\x9eNu\xc3\x1f\xf4t\xaa\x05\x7f\xd0B\xf2X\x8d\xe4\xf1\xc7G\xf2\xe0\x8a\xb2\x14\xa5*\x05f\xcf\xbbF\xa6\xc0\xcc\x87+0\x95Y\x8a6R\xc5edR\\~\xb2,Ei\xf2:\xbfH7%\xa6\xdfV\x03'\x1c\xf8\x91\x9f\x04$6\x00\xe7\xcc\xab%\xf1\xe71 \xb5\x01\xfe\x86\xba\xdd\xea\xb3\xb1U\xa8<\xbf\x98\xa4\x1buT\xb7\xb6R\xfb|S\x96\xf6Y\xd1\x9dy\x99\x00o\xef\xf4\x94\xfe\x11\xe0\x84\xd8\x147\x97\x1f\xcb\x94\x0fd\x93\x8aa]\x1f\xaa\x9f6\x1dT\xd4\xfc\x1b\x83\xf3:\xbf\x80\xa8\x84tS\x82\xccdfp\xdd\xd4\x17\xf7\xaeX#V\x12\xaak?i\xe1\xe7\x0c\x9e\xf0\x1d\xd0\xa8\x86\xd6\x01o`\xa8\x19\x9c\xe3\xe8\x0c\xf6jc!&\xc8\xa8\x0f\x95\xebYp\xfc\xcb\xa1\xf2\xe5P\xb9\xbe\x87\xca\xfc\"\xf3\x0bC\x91\x16\xe2E\xc5\xf1\x99\xbf\\\x92\xfc\xc0t\x94\xb0\\?\x1a\x12\x86P~\\\xa4\xc7\xab\xf4L{\xe2\x94\xba\xc3\xa0\x19XP\x8f\xd6\x0bVQ\x1c\xe6$A\xa1\x0e\xcb\xfc\x98?bG\xa6\xb7$/\xa24\x99d\xb9\xbf\\\xfb\xca\x13,\x1d\x7f\x88\xe6NO\xd7\xa4(\xfc%\x01\xc5\xfd\xc9\xc4_\xcf\xa3\xe5&\xdd\xa8\x0b~X\xcd\xa5\x12hu\xab\x0e\x0ey\x83\xb4\x18\xca\x14\x18\xc6\xe2\n@]\xea\x06\x13\xc7\xa8>\x94\x99\xdb\n\xd2\x90\xd4\xad\x15\x0c\xf5X\"V? \xa9\xa4a\xf9j\x9a\x91\xc4\xcf\"\xf6\xea\"\"qXP6 IK\x98\x13\xc8rR\x90\xa4\xc4\x8a\xd4+\x02\x85\xbf&\xc0\xf1\x1c\xd2\x1c^d$\xf9\xee\xe5\xd3\xc6\xb8\xeeY\x8e\xdc9\xdedY\x9a\x97$\x14\x0b*z\xe7\xe7d\xc0\xf8\xf8\xd4\xa0\xf0\xf57\xe7\xc0\xdbw\xfeV\xcdR\xb9J\x0b\x02\xe5\xca/a\xed\x97\xc1j\xc0g\xf9\xb4\xcd\xe0\x96\xb7\xef%l\xf6\xdcE\x9a\x039\xf7\xd7YL\xc6\xbb~k\x1f\xbf5\xf2\x1c\x11\xd3BI\xb0\xc5\x16\xd5\xee\xf3\x0f\xb0\xdf\xae\xdf\xf6^GE\x11%\xcb\xcfgs;\xafWt\x87\xa5\xdb($a\xe3u\x08SR`\xad\xdd\"#A\xb4\xb8\x00\x9f\x1eoQg'X\xef$\xbe#\xa3$\x8c\x02\xbf$\xd5\xd7$\x1b\xb9\xdd\x00|\xd9\x83\x97\x11\x10Z5I\xed\x85\x04q\xf2\xcb<\x0e\xc5\xa6\x96=c|\xca\xe7\xc7\xfd_c\xd5\xe5\xe0\xdc\xf4l\x97\x0c\xd48\xae\xfd8\xae0Q \x96\xe5\xf2\x9cm\x12\x9a\xd9u\xb7\x03\x07\x13\xb6\xe3\x7f\xafY\x92v\x8a\xa0\x8f \xc9\x9eE\xc9\xbb\xcf]\xbd\xdd\x18\x87\x0d\xb2pq]\xa9\xde\x96F/1\xe1\xa0$\xe7\xe50$\xf3\x8d\xb8\x93\xa4\xa8\xe1\x96\x88V\xb5N\x05\x1e\x1a<5\xa11\xd9^\x96\x93-I\xca\xc7\xacG\xae\x84\x92*\xf3\x9b\xae\xb0\xa2[\x89\x15\xddn\xb2\xf4N\x0c\xb4\x8b\xd9&=>\xdbT\xe9g\xa9n\x1f\xe3j\xf7\x1d\x89)\xb6\xb9\xb8+F\xacLk\x0b\xa1s=B\xe7\xed\x19\x94O\x86R\x8a\xe6k\x1b\xd9\xb0RJ UU\xc1\xf3u\x9c\x143pVe\x99\xcdn\xde<;;\xf3\xcenyi\xbe\xbcy\xb0\xbf\xbf\x7f\x13_\x93\xbf\xf4\xcf8J\xdeI\xdf\x9c>x\xf0\xe0&\x16 \x94\xbc\xabM\xf0\x93\xa5\x05rc3p\xfcy\x91\xc6\x1be\xf9{^\x05QQ\xbcF\x94?\xdc\xef\xa3\x7f\x17\x99\xd5\xd3J\x16\x85\xc5\xbc^\xac\xe7i,\x9d\xdamD\xce\xbeO\xcfg\xe0\xec\xc3>\x1c\xd0\xff\x93\x0c\x06\x0bNm\x928\x0d\xdeu\xd3\xd3\xe9z\x97\xb1<\xe0\x12\xa4\x9b\x81\xf3|z\xc7\xbb\x0f\xf7\x7f\x98\xde\xfe\xf9\x8ew\xf7\xd1\xf46\x1cx\xf7\xf6o\xc1\xf4\xc0\xbb{\xf7\x0eLa\xba\x0fS\xb8\xe7\xdd\xbau\x1b\xa6p\x97?\xbd\x0bw\xbc\xbb?\xdf]\x1dl'\xde\xfd\xfd\xe9\xa3\xfbp\xcb\xbbw\xe76\xdc\xf7\xee=\xb8\x07\xb7\xe8K\xb7\x82\xa9w\xb0\x7f\x8b\x0e\x07\xf0\xd9\x01\x1cx\xd3\x07\x0f~\xbe\xff\xc3\xed`\xe2\xdd\xb9s\x0b\xf6'S\xf0\xee\xde\xbe;\x99\xc2\x14\x1fM\xef\x05\xfb\xe0\xdd\xb9\xfd\xc0\xbb}p\x9f\xde\xbb\xf5\xc0{p\x87>\xbd\xb5\x7f/\xa60\xf7\xbc[\xf7\xef=\xba\xe3\xdd\xbdw\x00\xd3\xfb\xde\xfd\xbbS\xb8\xeb\xdd\xb9\x03\xd3\x07p\xcf\x9b\xc2\xf4\xc1\xea\x8ew?\xa0\x9f\x80}\x98\xd2\xcfL\xe8W`J\xbf3\xa9>swB\xbf\x13xw\x0enO\xbc\xe9\xdd{\xde\x83;\xb7&\xde\xbd;\xec\x07m\xee\xee\xcf\x0fh\x97\x1eM\xef\xc1}\xdaG\x98\xde\xf5n\xdd9\x80\xfb\xc0&\xec\xdf\x9d\xf9\x1f\x8d>\xf8\xca_\x9bu\xff\x93\xac\xe0\xf3\xe9\x01\xdc\xff\xe1\xfe\xcfw\x10l\x10\n\x7f\x82\xd5\x97\xe4\xb9\xb8\xc4\xe2\xdf\xf6n\xdd\xbe\x0f\xd3\xdb\xde\xfd\xdb\x0f\x82\x89w\xfb\xee\x03\xfa\xff\x93\xa9wp ~\xdd}p\x0f\xf6\x9fQ4\x98z\xf7\xa7\x0f\xe2\xc9\x81w\xf7\xce\x94\n`\x07\xdaW\xf0Q\xe3\x1f\x04\xa0\x98B\x1f\xc7\x07\xde\xbd;\xf7'\xb7\xbc\xe9\x9d \xfd\xf9\x00\x7f\x1e\x04\xb2\x97\xee\x8b\x97\xaa\xdb\x80\xb7\xc5\xcf\xaa\x83\xf7\xbd\xe9\xfd[1vor\xcb\xdb\xbf5\x0dto\x80\xe8z\xf5\x9ca\x1a\xed\x1d\xf6\x89b\xc2\xf4\x0e]k\xf1;P\xbe\xf2)0AY,\xf7\x12\xf8p\xcb;\xb8\x03\xd3\xfdgw\xbd\xe9\xfe\x038\xf0\xee\xdc\x0f&\xde\xc1\xdd\xfb\x13\xef\xe0\x1e\xffqo\x1f\x17\xf7\xc1\xbd\x07\xe2\x81wo\x7f\x8a\xff}p\xf7\x01\xec\xc7\xf7\xbc\xfb\xb7\xe0\x9e\xf7`\xff~@!\xbc\x83{S\xfc\xef\xbd}:[\xf4\xc5x\xd2\x80\x99\x08 \xfa\xe9)\xb6\x83\xdf\x11\xed\xd2\x15\xec4\xfcL\xf4\xf3\xd3\xce\xfa\xa4\x1fyy\x89\xa9\xbf\xe7\xdd\x9e\xde\x07\x9c\xf8\xc0;\xb8w0\x11\x93\xc6~<\xb8\xf7\x00\xf6\x0b\x9c\xcc{\xfbS\x9c\xc8\xbb8\x91\x0f\xf6\xef\x03\x9d\xce\x00\x97@\xcc\x14\xfb\x81/q\xa0I\x05\xd4XQ\xfc\x14N8[\x81~\x93\xb8\xf3\xe9t\xc7\xd8\xc1\xc9=oz{\xfa\x81\xe6\xfd6\x1c\xdcV\xcd;/\xcbqe\xd3\xfd\x00\xeemo\xffp\xc7\xbb\x7f+\xbe\xe5!)\xba\xf3\xe0\xd9}\xb8\x1bO\xee\x02\xfb\xdf\xd4\xbb=\x9d\xd0\x7f\x9eQ(\x98\xde\xfa\xe1`\xfa\xf3\xbdO0t\x16\xf1~e#\xdf\x87\xe9\xfd\xd5\xed\xed\xe4`5\xb9\xbd=\xf8\xf7\xf3[pw{\xb0\x9a\xde\xff\xf9\xee\x0f\xb7\xfe\xbd\xbe\x05\xf7V\xd3\x83\xed\xe4\xe0\x87\xbb\xdb\xff\x8f\xbdw[r\xe4F\x16\x04\xdf\xfb+\x90l\x9d*\xb2x\xc9d\xd6E\x123\xb3\xb2\xd5j\xe9\xb4\xd6T\xdd2\xa9\xfa\xcc\xce\x90\xacj0\x08\x92\xa1\x8c\x9b\x10\x08ff 5\xd6\x0fk\xfb\x03\xbb\x0f;f\xbb/\xfb0k\xf3\xb2f\xfb\x0b\xf3)\xfd%kp\x07\x107D0\x98U\xea\xd3\xe7LS\xb2\xca\x08\x04.\x0e\xc0\xe1\xeep8\xdc\xcf\xeb\x9d\x1d|\x1c\xc5\x84Q\x18D\xfd\xf3O\x07\x13\x9a\xa6\xfe6\xaa\x9f+G\xfd\xe9\xd9Y\xd5\xa6\xd47\x1f\x9e9\xce\x95\xd5\x87\xe9s\xc7\xb9\xb2\xfa\xf0\xb4\xbaCK\xf1\xc3\xf3j\x13\x81\xf3F\xa5\xdd\x9b\xa9\xba\x9e}\xee0u\xdddA\x80\x9f\x9f\xbb\x82\xedxq\x18\xc6QH\xf9\x8d\xce4\xad\x1c\xc5\xba\xd4$\x9ekP\xd5\x0f\xce\x10R\xee\x91+\xf5\x19\xdeX\x04\xd1\xbb\xf5[\x0c\xd7\x95\xd0}\x8b~\xd6_D|\xc3\xe0\xc3|\xa9S\xfc(\xf0#\xf6*^3rEN\xa6\xa5T<\x0d\x85G\x9d\xbeR\"(\x1e\xba\xaa'\x9d\x8aJv\x86\xa7\xa7\xe6\xc5\xb4x\x9f\xc4[N\x93\x9d\xfe\\x/\xa0S\xbd\xf7\x1b\xe7-\xa9^\n\xe6y=rrE\xc4}\xc2\xe2\x0d\xea\x8c\xfa\xa0\xb1\x19\xc1\xc1qOOWoP\xedL\xc4nIV\xe9\x89J\xa3:\xcd\x8b\xb9\xc9\xe6\xd7\xbb\xa6\x92c\x93\x9c\x056-\xad\x8d\xba\xbd\x1e\xef\xc1\xd5\xc9\x8c\xb3~0gK\x03O\xcaD\x1f\xae\x1e\xfe\xfc\xbe\xba\xa4`\x08r\xf3\x11\x95\xb5UY\xc5\xfb\xc5\xa6G\x84\x15*\x1c\x95j\xb2\xa0tR~\xa9Z\xcb\xfa+\xb80\xc9\x06D\xecx|\x0b\xfd\xfe\x8a\xf3\x98\xf7{\xff\x81\xc7\xd1\x96\xfc\x993\x85\xdet\x15\xb0?\xe3\xa1\xa4\x18\x11o\xc7\xbc\x1b\xb8\x9c\x7f\xea\xa1\x13\x8e\xea\xbd0\x8b\x9f\x18\xabF\x8d\x8cM\x1a\x8c\x88\x02[\xab\xe7!\x87V\xe4\xdc\xb0\xfb\xb4_\xfc6\x98lb\xfe\x15\xf5v\xb9-{m\xd5`sy\x99y\xb4\x84i\xc4\xa6\xcd\x1b\xd7Z\xbf\xbe3+\xc4\xd2\xaa\x10\xc6\xa6\x01W\xd4\xef\x8a\xb4\xde\xf93\x8a\xb8\x82\xc1\x87zj\xaa1\xa1\xfcp\x9dj\x06#\x8d\x99\x9e\xae\x18\xf29\xd5\x91\x16\xedU3\x1eK\xd3~4\x18\x91H\xd3\x89&@\xf4\xa1Z\xb7\xde\x01:!\xb6W\xd6\x94~@\x14\x86\xcea=\xe5\xf5\xa4RZG\xe4\x1b\xb3\xbc?\xe2\xb8D\x15\xbax6\xfa\xa0\xa1\xea\x06\xe2\x03\x06\x0c+\xee2l\xe0\xf7+\xe6B\xd1\xa7M\xe1u\x92 ?H\x0dC\xfe\x15\xf9(|\xbd\x81\xa1?u\x1e\x07\xf85%\xa6%\xb1)D\xfeE!\x01\x9c\x8e\xc4\xa6\x97[&~\xcb\x19U\x14<\xb6/\x0ebZ\xec\xb6\xaf$\xa7nS\xe3\xe0\xba\x9b\x98\x93\xbe\xe9e\x0e\xe1Hk\xfc\x03\x16m\xc5n\x04B\xca\xd9\x08D\x92^\xef\x82\xc4\xe3\xf1\xc5\x80P2\xbc\"|\xce\xe6\xfeR1@\xb6T\x8d\xf8\xc3!\xb6\x84]r#\"-\xcea\x1d\xfa\x8f\x0b\xf7x\x9a\x03>\x1c\xfa\xe4\x92\xc4\x17\x03\xd2\xc3\xa5\x80\x8e\xf3m\x17\xc85\xf6\xaa\x80\xa0\x06\x19U\x16s\x0ej`\x9a5\x8c\xc1Q#\xf0\x91\xb0s\xb2\xa3\xa9\x0bC\xd5\xa7,b\xa9G\x13\xf6j\xed\x92=U\x0e\xce\x92\x80z\xec\xabH\xf8\xc2g\xa9K\x12U\xd9\xb0\x9a\xdf\x8b0\xa8\x8b\xa4?\x17\xb4\xfa\x19J\"?e\xb1`o!\xa6\xd5a\xed~\xef2/\xf3rQ\xd8\x88\xbe\x1f\x95\xeb\x03\x95QG\xb2\xd3\xbb<-\xd4\xda#C\x92b\xf6r\xed\x1eR\xc4.5\xb2\xb9Xj9\xeb\x9a\xf4.\x13\xce^^\xaa\xe2P9\xed\xc3g-\x17\xc0u\xe6\xcbS\xf8zy\xaar\x16\x00 3\xd2\xebR\xb02\x0e\x1b\x16y\xae\x85=R2`\xe0\xe2\x0f\xdeH\x91F\x08\x1d;\x17\x8ekjkX\x1b\x8e\xc305\xeb\x93\x80F\xdb\xef8\xdb\xf8wu\xc9)Q\xe4\x9a\x86\xa9K(Q\xdf\xc1\xc9\x0c\xf8\x9f\xd1\x19'i\x12\xf8\xa2\x7f\xbaH\x87\xa7\xdb\xc1@\x87\xf2\x86H\xde\xbc\x1f\xe0\x12\xc6\x1e\xbe\xf5\xb2T\xc4\xe1\x88x\xf3\xb3\xe5\xc0\xfa\xb1p\xe5\x99\xab,\xcb\xca8\xd4\xed\x17U7\x1f\xe3\xd1\xe3U\xef1\x19\x92\x1d\x0c\xbb\xdf\x8f\xfb\x9b\xc1@\x8d\xf8\xe3\xde\xe3R)\xa7)ia\xc6\xd5\xbc\xad\xd5L\xc1\x0c\xf6\xa3\xc9\xce\xdf\xee\x02\x88p\xf4\xe8\x11)\xbcj\xc3\xd5B\xca\x88\xcc\x133\xd90\xeb\x1e\x15}o\x80n)\xfa\xf6\xd3\xa0\x15\x83\x1c\x88\xa1\x87DK\xeb\xd9d\xc7\xe8\xda\x8f\xb6\xb5%\xd8\xbabv\xaa\x0d@\xc7\xdd\xb7l\xcf\x02\xecb\xb95S\xf1\x91k\xd1Yum\xad\xef\xbap\x00c\xda\x1bM\xeev\"\x0c\xfe\x98\xc1\xb1\xed\xe5\x8e\x93\xd3\x97=X\\;\xfe\x12<\n8\x87k\x95\x05\x01\x13o\x03?\x15\xdd T\x168\x08S\xa1\xa2#G#\x0b\x9a\xa7\x13\xea\xf3\x05\x0b\xbbC\x17\xf8\xd5Y\xca+\xa9A\xd6\x0cU\xe0\xd7;\x19s%\xaa\xad\xdd\xc3\xd5&\x98\xaa\xb9v2\xc0\xdee\x1c\xe8e\x03\x95\x93\x97dJ\xae\xc9c\x92\n\xca\x05\xaeP\xf3 \x96&FTu#L \xbc#'!n\x99\x04E\xb5`[\xdf\xa9\xcfE\x06!\x80\x0c\\\x93\x1e\xa2bR\x9d\x99\xbc\xe6N\xe0\x9a\xe1<\xe9\x17jW;\xe659\x07\xe1\xf1%\x05\x1b\x10\x03\x07R*\xce6\x06\x06\x0c\xf3\x15\xbb(\"\x8c\xc1\x11\xcb\x8cV+\xf0C\xba\xed\"\xb2\x9b\x01|LR\xee\x95 M\xb9\xa7\x01\xad\x8fS\xf6\xd0!oX\xbd~\xb85Q\xcf\xfa\x8f \x0d\xf4hc-4P\xf3\x80\xcc\xd5$\xa0]1.\xe1\xc7\xbd\xc7\xeaO\x86\xeb\xbfH\xbf\xc9i\xaf\xb0\xd0+#\x04\x11D\xbb\xd3C\xc8^'\x16X\xcb\x113\xd5T\x8f\xe2\x81G@\xa3\xb27\xd5r\x0c4\x0d\xf5\xac\xe2\xf5\xfd\x11\xd0\xa8\xecM\xb5\x1c\x03MC=\xfc\x08Pxm\x9e\xf9Q p\xd7\xa8v\xa2\xd8\x1d\xb8\x94\xd8i.E\x03\x7f\x1bi\x0eu\xaf\xd6\x8d`wb\x0c\xa93\xa43\x98\xa3\xca\xac\xea\x90\x1d\xd3\xb7]\xad|\x1d\xe5\x1e\xda\xb3\xf5G\xee\xd9qh\xbc\xae\x96O\x05\x8f\x1d\xa2jc\x15\x98\xbf\xa1\x96# q\xd7s\x8c\xe0\xc5BG\xe9# \xa8\x97_\xb3\xa0{\xf3k\x16\xb8\xca\x1f\x01\x80\xa3\x06?J\xbbC\xe0G\xa9\xab\xfc\x11\x108j\x08)\xaf\x0b\x15\x8d5\xa8\xdc\xce\x1a\x8e\x00\xc2UG\x9a\xad\x0e\xad\xb5\x1c#\xb3U\xf3f\x1e>V\xebN\x8e\xa8;i\xab\xbb&`\xee(_\xaf\xb4.\xf1\x90D\xa1\x1b\xa9\xec\xa4Vj'\xb5\x88P\x12\\9\x88l\x1ao\xc4\xd1M@\x81\x94\\whM=\xd6);\xbb\x13\x1d\x07\xad2T\x95\xf1\x11a`N\xcb\xbaTV\xac\xaa^\x93\xa0\xdb\x0f\xae\x87\xaeVu\xae\xd9R\xd3\xe3KU\xe2\xa0\x14\xf7\xf2\xb1\xa3\x99#\x16\x85\xca_SB\xc5\xb1\x88b\xc1\xder\xb69\x04\xad\xe1D\x7f\xc8\xc2\x15\xe3\x08\x9f\xbf&C2\x1dLD\xac\x1d\x938N\x97\x95\x88\xdb\xdbD\x9cm\xc0\x10\xdb\xc9\xc4P\xea\xcdV\xdf\xac\xc9Kr\x06G\xa6\x9c\x0c\xafHof\xf5\x0c\xf0u0\"\x8f\xd5\n2\xea\x1f\x03\xffX\xd5\xfe\xd2\n\xfd\xbf\xdeD\x8fuL\xdf\xc7=\xe2\xaf\xaf\xac\xc4\xff\xb8\xf7rn>\xf5\x96Jxw.:;.\x80Y]wD\xba3eI\xf8\xf1\xe5\x8eW\xc1M\xc7)Kz\xb0N\x14\x1fn\xce\xa22\xc0\xec_\xa6\x0c\x9a\xaeeSY.\xe3\xa0^\\m\xa1\xa1|k\xcf\x8e\xc0\x9f8PM\x9dj@\xeaT\xc4\xd6|\x14\xea\x07>\xcc\x0fNX;j\xe1l\xd6\xa6\xde\x17,\xac-\x0e\x0b\xcc\x11\x1dt\xe9Kl=4\xf2v\xf1\xc1CE\xb3Fr|o\xefR\xd7\xc5\x105-\x06\x92\xe3|\x01\xe3\xabC\xb4\xa2\xde\x0d\xac\x90\xbf\xfe\xaf\xffM\xe1|e\xb0\xd6\xc7\xc8(\x0e\xcd\xd9\xfa\x08\xcd\xdbZ\xd4D\x9c#\xf6^\xeb\x9a\xb0\xb9>N>rC\x7fL\x0d\xc2Q\xc3Q\x02\xf3\xba\xb2\xe9+\x1f\x03\xa5\xe4\x8ad\xc5\xf3\xc3.\xcb\xa8_\xe4\xa4\x84\xf5]\xc4\xa9\x90}8\x8c\xc8\xcb+\"\xf4\xe9\x1a\x19\x93s\xc5\xc7\x15\x9b.+\xcaP\x13\x05\xd6\x07F\x0b\x85/FmU\xd2X\x89\xb9B\xbf\x82\xc6\xea\xac\x9c\xac\x99\xa5iU\x15\xafh\xcf\x8a\xf5\x9c\x97\xda\xd4 Z\xab\x85=Tip\xc5\xb9\xd4\xcf\xf78P\x03ri\x8f\x0f\xa1\xa9\x8a\n\xd5*\xd9\xecya\xaf.\xa7\xe4SS<\xa8\xcd \xf5\x03\x0f\xfa\xea\xc6]1\xb9\"\xf3\xda\x94\xcd{@\xa8{\xe8\xdb\xff\xec\xf9\xc0q\xf03\xef)\xden\xb2\xbcpg\xe1l\xc38\x8b<\x08\x13\x0f\x19?ug\xd4S\xaa3}\xe6\xced\xe9\xa2\xa0~`\xf2~\xde\x0c\xdc\xb9\xce3=k\x82\x0e\x8e-C\x16 \x03\xdft\xea\xce\x9a\x86\x94\x0b8\x06\xb49\xcf\xdd9\x03?\xba\xf17\xf7&\xd7\xd3\xc1\xb2\x94iy\xc4q\xbf\xc3z\xaahd\xc5\xcb\x84\xdc\x1ej+\x92pvA\x18\xb9$\xb1F\xc6\x0b\xc2\x86\xc3A\xa1\n\x8c$\x12\xcf\xd9r~\xb6\x1c\x11x\x98.]\xa6W\xc5\x03vm\xe5Q\"\x10.n\x84Gi.\xf8\x04\x9a\x02D\xe66X\x01\xa2-\x13\xdfg\x01K\xfb\xbd\xde``\xe1\x16\xe4\x92D\x17D(\xf0\xf9\\,\xfb\xac\xd1\x84\xe3\x03n\xc3\x95,A\x1a\xbb\xc6\x8a\x160\xd7\x84i;\x17\x1c\xcb:\xe1SC6\xb3\xd4\xcae\x01\xa9\x830\xb1I\xca=s\x88\xde?]D\xa7[\xbc\xf6:\x11\xdc\x0f]\xe2m\xc0\xf6,p\xde\xdeRm\xa532?\x1b\x91\xa9\x03?\xf3\xbb\xd8\xf32^\x82CWm\xc2h\x0c\x8f\x14X\xa3\xa2\xbd$\x9b\xb0h?\xb2\x1d\xff\xd8\xc6\xafO\xab\xb6\xaa\xdaJ\xe6y\x93\x91\x0c3\xa7\xb6\xbe\x0b\x0b)\x9c\xe6\xa6#\x12\x8c\xe0\x18\xbb~\x04\xfd\xec\x9c\x9c(\x82<\xf1v\x94\x7f\x19\xaf\xd9\x17\xa2\x7f\x96\x9f\x17\x8f\xa7\xf5\"\x9fO\xebE\xa6\xedE\xb4G}f\x1d\xe4\xf7\x96\xb3^{\x11j\x96x\xa1\x8b#2_\x0eF\xa4\x9f\xc1\xd5b:\"S\xe07gDJ\xf2\xfc\xb3:T\x19\xc8}\x8d\xcd\xc0r\x0c\xc8\x15\xa1\x93$N_\xd1\xbb\x11\x8a\x01\x8a\xc1]\x90\x94\\\x92@\xb1\xb0\xe9\x19\xd4L\x01E\x0b\xb5\xa7\x83\x0b\x92\x0e\x87naR\x873\x0c|\x8f\xf5\xcfG$\x1b\x8c4[\x86C}\xf3\x05\x9a\x1a\x91\xd4\xa0\xb9Y\xf4\xe4\x9a\x8c\xa7dF\xfa>l7\xd9\xde\xa7H\x07\xa5\xac\xa7)\xda8\x18\xe9;\xd8\xd0F%\xc7\x1c%Xo 2m\xe3\xc7+\xb2\x19(X\x1c\x14\xb0\x1bq(\xd0=\xf0'\x82Q=p\xa1\xb8\xccF\x0b\xb4\xa4~\xc9\xd8\xd2\xca)\xd2J\x9aKM\xd3\x12M\xac\x954\x0d8\x85*Z=\xde+\x89R\xd4\xca%\x8dR\x92\xaa\xc0J[.a\xcf\xfc\xa0\x03jY\xd3\x82\xc6\xe2\x82\xf0\x82pt\xd2\xef\xab\xf5\xed\xf7\xf9\xa8`R]\xa56\x88\xe3\x83\x8b\x01\x10 \xaeQ'68S\xb7\xd40\xbfb\xc3\xaa\xe4(o\\\xe1Q>\x14 \xde\xa1=c\xde=\x9bx\xc8[\xef/N\xf9\\6W\xcf\xa6U{B\xaa\xd3\xab\x86\xf8h\xed\xff\xec\xfc\xccIA\xd3\x9c\xbc\xd4\xccp\x14t\x9apB\xe4\x80\xf5\x88\xecFd?\"\xe1\x88l\xbb\xd1\xc5\x03\xa4\xf4\x01t1\xa8\xd3\xc5\xd4\xd0E\x0f\xe8b0\"g\xedt\xd1\xeb@\x17\x13rE\x02K\x17\x15\xd1\xf2\x90.n\xc8%\xc6p\xe8?=G\x8a\xb6\x86\xac\x15\xea\xb8Ac\x9c)R\xa4\xf5\xe0\x82lj\xb4\x12\xc8\x80\xaf\x00\xde\x1c\x80f\x0fM(\xc1R\xc7m\x1ca\xfc)\x03\xa4\x82px\xa5(\xc3G\x04\x0fZ\xb6\xf5\xed`\x1c7\xea\x91\"\xc8\xe4\x9a\xf4\xc3:`\x16(%O@\x86^\x0fSw\x83\x02|\x1a<\x07d\x17\x03\x05\x8c\x93\xad\xd8\xd2\x9a)9J[\xde\xb1U\xbc\xacoX\xcdtD\xbcA\x99M\xa4\x93|s2\xdf\"w\xa8\xa6\xb9.\xbe\xe8\xb8\x9c\xa1\xc3\xe4\x0d\xfc?\xecK\xe9\x8a7m>\x1eS\xf1[\x99\n\x10\xccB\x17\xb4\xc7\x8eR\x92\xb6\xa1>\x92\xff\xf8\xc7\xf3\x9f\"g\xf1\x1b8K\xce\x99\xfc\x1agr\xf2\x1f\xffh\xfe\xe3\x1f\xe2?\xe9/\xc4\x7f\xfcv\xfe\xe3\xbb\xf8\x8f\xff7\xe5?\x0fA\xc1F\xfc\x83\x01\x8fpw\x07n>\xec\x0e.\"\x97\x84_\x90H\xed\xe0JX\x01\x08\x16\xcf\xa3\xe5\xc0\xce\xba\x99\x07\xbd\x03\x11f\x00]\xbb\x10\x91{\x8b\xfb\xd7\x1a\x0d\x90\xcaK\xdb\x0c\x18\x80\xfar\xc2{d\xb5\xf4\xa4b\xf8LJ\x0b\xd9\xaa\xd5\x816\xb1\xfc\xa2\x9a\xddx\xd6B}\xb5\xe8\xdfz\xc5c\x17\xa4\x06\x85\xf5\xc7\x8cB\n$t\x85\x8b\xe6F\x1cF2\x0f\xe8\x8a\x05#r2\x053\x1cGUE\xfdV\xb9\xae\xe9\x88$Z\xce\x0e\x14IMM5}`'z\xfb\xcc\x06#r\xb2\xa9^$\xd2\x93\x9d\x0f\x05\x18%\x0e\\\xdd\x04\x04\xa4\x96\xe4\x95K\x8c\x0en\xd6I\xbeaw\x9c\xc348Q\xd1\xdbpo8\xac}\x06/Q\xb9\xb2\x83:\x15\x1an0\xa0']\xe0%\x0e\x98[\xa0%\xfa\nmK\x90\xc3\x96\x0e\x11\xdd)\xdc% *^\x93>lG\xe7\xcbAG8+\xb4\xbf\x19\x12\x81\x0eh\xda\x82\xcdv\x006\xeb\x08V\xa3\x8e\xc6\xfc\xac\xae\xc6eEh~\x06\xa0\x96j\xac\xfa\xa50\x8c\x1f\x0c}\x95U~\x8cQ\x1d\x8f\xbd\x06\xb8\xe0\xe2\x8a\x82\x1eh\x02\xd0&\x886\xab\xd7x\xfei9\xc8\x97]\x91ji\x83\xf5l\x80\xf2\x8c\x9b\xd3\x9b\xdcs[,\x97@\xac\xf6<_$q\xd2\xcf\x03\xbe\xc4\xf9\xbe3\x8b\x04\x9cg]\x17\x13fJ\xac\xe1\xa8%\xe5p\xa3\x87p\xb5\x1c\x1f\xba\xe6\xf0\x98\xee\xe1\xab\x0e\x0e\xd6Z\xc3|\x1b\xccj\x98\x12\xb7\x14\xe2#G-\xf6\xc9\x1ft\xa3\x84\xc4\xd1\xcbC\xb8u\x10q\xea4\xb2\x96\xd2\x0567\x95n\x83\xae\x05\xb2\nT\x1f$W\xd9d\xbb\xbf\xe6\xcd^\xfdruo\x7f>\xee\x0f\x16\xf3\xc5\xf2\xe7\xf7\xc3\xeb'\x93O\x16o\xe4h\xf6\xeb\xcb\x93\xc5b9\x00E\xf0b\xf1\xc9\xb4\xf71\xf6\x10\x0ey\xa5\xb8\xbb\xef\xb0\xb7()\xcf\x1a\xb6\x0dy\xce\xef\xd9\xf6\xab\xbb\x04\xc4]\xb8&\xd4\x7f#\xe7=\x08\xd2\xb8\x88\xfa\x83\xf9\xf2\xf1\xa27\x19\x9d\\\x8f{\xfafO\xaf\x87\xc1\xb7\xb8\xb9\xdb\x83\xa6\x82\xcbA_\x95*_t\xaeC\xd31n\x97\x9d\x804[\xa5\x82\xf7\xa7\x0e\xbc\x1cL\xd2\x98w\x0cN\xaa\xeb+\x9ck\x9a\x13@W\xbd\xa5\xeeI\xec\xdf\xa0\xff\xc9\x03\xc7\xa5g\xe4\xa3\xc2h\xa3\x82\x04_\xfa\xeb\x11\xe9m{j\xe7\xbb\xb1\x92Q\x9e\x17E\x933$\x98\xbb\x92\xc0\x1e\xa3\xc0\xee\xa6+\xd5\xed\xdd\xce\x9c\xd5\xba\xf3\x93\xe2\x86\xb2\xafH>\x14\xb0\xd2{eo\xf9\x12\xe8\xb2\x18\x8f\x9bk#\x06\n\xc1\xee\x84\xdeLP\xbd\xd9\x1b\x1c\xdc\x1b\x9a\x9f\xd5\x80\x9f\x8d@OF\xf3\xdd\xc6f\x12\xd0T|\x13\xad\xd9\x1d~\xf7\xb4\x0c\xb7g\x81\x11\x8d/@|\xdfL\xd8\x1d\xf3\xfa\x19\xe8-\n\xa5^\xa2\xfa\xfc \x95-\xfe4e\x83N5\xd3\xd9\xe2\xcf\x8a%\x99\xde\x98\x06#\x92\xa0>\x8d\x0cI2\x9f.\xf5\xe0v\x08EG\x0e\xf1\x99\xe2\xef=\xb8q>\xbeo\xd6L\xadc\x07\xb5\xb6\xc5\xb1\xde\xb5\xb8\x91\xcc\xcf\x97\x1d\xa2\xe7\x91\xc3\xf2b\xf1\xf7\xd0\xee=d\xeaT\x0f\xba\x15\xf9\xdb\xcc\xce!>_\xfc\x1d\xe0\xf9\xc5\x9f\x82)\x80\x05\x93/\x921I\xe6O\x0d\x8a6\xabR\xcc/-ho\xfa\x01\xb9$Y!\xe1!\xfd}\xc8t\xd9\x95\xf6K,\xa9\x12aT\x04\x0d(\x8d\x91\x98}\xdd\xf4\xd9\x08\\\x1b\xa4#bR\x04\xea\xb4\xdb)\xe6\x07 7&\xd5\x1cZ\x9c.\x86c\xb9\x98,&rq\x8d\xff\xc9\x93\x93\x93\x139\x1a\xc9\xf1\xf8\xb4~\x98q\xba\xe8\xf7=)B\xc9e2X\x0cN\xb7~\xfd`\xa3>w\xde\x8c\xf4\xfe\xfb\x7fsL\x11W\x1f\xfe_\xc7\x87D}\xf8\x7f\x1c\x1fD8#\xbd\xbf\xfe/\xffw\xaf\xf4\xa5\xc1\xda\xa6\x8b4\x95\xcbQ.iIk\xab\x8a\xbe}\x1a\xe4\xa5\xd2\xde\xa8\xc8\nS\xcd\n\xd3&VXc\xc4v\xd3\x94v\xe7\xc7\x19)\x97;\xcc\x96I\x91\xed*,\xcd,\xdb\x85\x95 gQ9/U\xafx\xd0<\xc8Oz\xfa=<\xa3\xb9&\x01\x99\x91\xc0J\xc3\xf1\xa8\xdd\xf6\xac\xfa\xd3\xd2\x97?\x17\x13\x11\x7f\x1b\xdf2\xfe%MY\xbfbtS\xfc\xa9e\xc6'\x82\xa5\xa2O\x07\x16^Z0\xbf\x18\x8eA\xec\xfe\xef\xff_oPH\x9d\xfc|>z\x0f\x1f\xfe\xfa\x97\xffZ\xfc\xd2\x9f_\x9f,\x07\x7f\xfd\xcb\x7f\x85\x8f\x9fL'\x93\xfa\xd7\x9f\x9f\xe9\xb2\x9fL\xd5\x7f\xc5\x0c#[\xef\xa8T\xee\x8d\x9c\xbf\x19/\x07\xe3\xf1\xb8\xaf\x1e\xe4'\x83\xd3m\x085\xfc\xf5/\xff\xfb'\xe7\x95\xbc\x8bt0\x1e\xf7\x17i)\xdb\xffV\xcb6\x7f3^\xa4\xaa\xd2>>\xd5\xb3\x83\xff\x96\\mM?\x8an\xd5\x12\x8d\xf9\xe3\xde\xd2E\x1c }[\xa7\x08\xa7\xf3\xf1\"\xc5\xdd\xd1\xf2\xd4\xb5\xc3\xa2m\x16\x8a'}a\x0e\x02\x01\x7f\x8d`\x0e\xd3~\xe2#\x120\x85\xbc\x85N\xd6\xdb\xc8\x0e\x98^\xdb\xad\x04\xd0em\x10k\x13\x914WF\x91<\x80\xde\xf8\xceM\x9b=\x92\x1d\x91\xfb\x11Y\x8d\xc8\xdb\x11\xb9\xfd0\x82t\xab5\xbf\xab&\xc2\xb4\xd2\xc4`u.\xc5\x9a\xccFaK\xaer\x88a\xe8\xb60tx\xfct;\xdf\xea\x9c\xe4\xf2\x8al\x06\x17d;\x1e\xb7\x9c(\x99_a\x0c\xb6\n\xb9P\xae\xd2\x9b\x14\xd8_\xd9\x15<\xe8,[\xb1\x19v\xe1\x82(\xc1\xca\x03\xc2\x18\x97vAz\xe3\x13\xe3\x86\xc7\x1f\x0c.\xda\x87\xd9\xfc\xc0\xd7\x07\xb9\"'\xb4\xafPX\xefN\xc6d\xaa\x05\xc2\xd4\xeeW\xa6#rO\xaeH\xef1NL\n\xa6\x89\xa0:\xc0\xb2\x01\x1e[']\xe6\xc3\xfcT\xeb{U\xc3zDB\xf57\xe9\x06\xb5\xf9\xc1\xa0\xb4\xcdc_\xcd\x83\x9a\xcaQeJ\xc9f\xa0\xa7\xf4\xa8\x06\x89\x06z7I\xfdh\x1b0\x18\x8a{\xd5R\xa1r\x95\xb69f\x18\x8a\xbf\x1c\xe0{rM\xfao\xe7;\\j\xc5\xe3\xca\xcc\x91<\";\xb46\xc8\x89 Z\xc4\xce\xcf\x97\x15\xb6\x91\xf5\x0b\x02\x80\x9e`G\xb9\xa7K\xd0&\x7f\x0c\x10\xce\x1e\x08\xc2t\xa9X^qI\x1d^+\xae\x9fj\xca\x8f2V \xbe\xd1\xe5WW\x836\xfd\xf6\xe4\x9a\xdc\x1e\xb3\xcf1?\x18\xc5V\x1d\xb4\xeb\x97\xc4\xe9\xcc\x0e\xddQ%\x11ug\xc4\x11\x07\xbb\xed\xa7\xf7J\x9b\xce\x85\xc0j5T\x8b\x03VH\xff0\x02\xf4\xfe\xfa\x97\xff\xe2\x8a\xa0\xea\xfa\xbd',H\xd9G\xad\xfa\xa3\xee\xc1\xc0\xc0\xbc\xea\xf8\x15\xe4\xa9\xdb\xdb[\xf9\x1b\xb9\x98-N\x17\xa7N\xb9\xc9o\xd4L\x9f\xbe\xb9\\\x9c\xd2E\xfa\xe4\xe5\xa9\x91\x90\xda\xc5#Z3^7F\xe8s\x87^CX\x0b.7\x06\xab\xce&\xe82\xaa\xf9\x9c*\xe3\xc1\x8c\x9c4\xc4\xae`!\xf5[>\x8b[_\x08\xc6\x9b+\xd7\xf2\xf2\xd7Q!0g\xd3\xdd\x16\xf3Ko}\xe1\xed\x14\x92l\x99x}\x9f\xb0\xfeA\xa1\xc1\xa3)#\xbd\x8c\x07\xbd\xd9Add\xc7\xacy%\xb2\xccH4\x81\xc8dl\xfd\x9a\xddu\\\xf60\xaa\xd0\x83?\xf1\xc0\x11\xf9\xa6\xfak:w*\xfe\xe0\xc2n{6\x1c\x08\x98\xb5\xbf\xaf\xa1\xe8)\x90D\x0cjF\x18\x96\xafTB\xbf\xb0\xa3z\xa3s\x9c\xfa\xa3\x92[\x9b\xa6\x9f\xe3\x0c\xcc~j\xfcb63Sg\x8ez\xb9\xea\xb4\xe8\xf2\xf5\x11\x0b\xfc\xe8&\x9d\x11V\x1f\x12\x9a\x89X}U\xcb\xa4\x1c\x93\xda\x15L\xea\xd8\x8d\x0co:\x80*\xeee\n;\x80:|jg\x12eA\xab\xe2E\xdf\xc3i\xd8\xe3\x14,\x95\xee]\x96J\xce\xb1\xaemk\xee;\x1e|\x14\xb6+\xa0o\xb9\xffX\xe7\x1f\xb9\xdb\xa0\x1eXD\x822);\xea\x14\x04\xea\xd1\xb7\xd0\xb5\xdc\x9d\xabr\xb6 \x9f[Vw\xfa\xe6\x92\xce_.\xd2\xa5a\x0d\xdb\x01\x1a\x87\xea+\xa3\xbb\xf1xD\xfc~\x9a;\x18P\x89\xc3\xe1@\xc9\xc6\x90\x0bR\n\x9b\xaf\xbc\xad\x18k\xcc\xcbv\x01\x9e\xe8\x0e\xac\xe0\x90Q\xc9\xf9}\x85\x1b\x14.\x13(\xf4F\xa1\x7f5\xc91\xda\xee:l\xaf\xf6\xa5=e\x08\x05\xfb\x81\x82yo\x15\x06F\xbc;L\xf1\x88\x99tOo\xa3\xd7\xd0\x9a\xde\x11np\xc7\xba!\x97\xb6Y4\xbe\xcdM\xdf \xce%\x15\xec[\x05\xc6~\xbeYN2\x1e\xa0\xa6J\xdb%\x1b-\x1a|\xd4;T\xf5Y\xb5\xb4\x1e\x11\xef\x18\x12I\x1e\xa4\x0d'E\x8dx\x90\xab\xa5\x93\x8eJq\x92\x0b{\xebN\x05 \xb2\xc0C;f\x1d\x8c\x1d\xd1;m\xcc\xab\x87\xbf{9}`\xd5f&T\xfd\x99\x81\xe8p.E\xb4\x02\xf3\xa1#\xf1\xd0)\xb6\x98\xd6\xbd\xec\x91\xd3\xfb\xf0>\x15h\xe0\xd1\xd0\x8d\xc7\xdd\xe1\x0b\xd0\x92\x1eP=!\xc3|L\x0c\x91\xe8 \x0e\xa9_P8\xb4zh\x9f\x1f:\x8fG \xf2\xd1\xf3w_9\xbb\xcaJgWY\xf9\xec\xca\x1b\xd9\x834}vu\xb0\x9d\xf6m2\xee\xd5\x0eV\x82\xe7\x1e\xe3\xf1\x05pI\xadM9\xb9\xb2\x14\x9a\xe0\xadmC/\xe0Sf\xac\xd7/\x06\x8a-\xdb6:\xed\xe0\xf6:(\xe2\x88\xf89z\xc4\xfa\xe6+\x1a\xc0\xd9\xe2U\x8ew\xfa\xe4\xa4\xdc\xa1'\xe4\x0b\xcb\xc7&?\xa6\xd5\x8fg\x93\xe9\xf3\xc9\xd3Jj5\xd3\x97qr\xcf\xfd\xedN\xf4\xbd\x019?\x9b>'\xff\xcc\xd96\xe6\xf7\xe4\x7f\xa2^\xbcJ\xc9\xe5\x96\xb3\xedo\xd4?\xe3\x1f!e\xe2\xc5\xe1\xcbj5\xaf\xbeyM\xbe\xf5=\x16\xa5l=!\x85\x18\x86j\xdc\xd28\xe3\x1e\x83X\x86\x01\xe6IOC_\x8c\xf5\xcb$\xd9%\x07\xa0T\x15\xa6\xb3\xd3\xd3\xad/v\xd9JAp\xaa B\x80N\xdbF\xe1\xb4\xf4\x0e[\xd1Q\xd9\x80\xbd\xddF(\x9e\xfcI\xf8\x81q\xb0\xae\x9d\xe2W\xac\xc4\x9c\x02v\x9c_\x94v\x9fe\xc6Q*x\xe6\x89\x98\xcfH\\_\x88\x19\x0fR\xf7\xb6\xb5eG\x9b\xeff\x1d\x1f#v\xfb\x1f\xfch\x1d\xdf\xba?\x97\xb7\xda\xae\xcay\xa6\xd6.\x9b\xe9{3\xf5\x1c\xc5X\xac.'\xd0\"\x0c\xbe\xa3\x14\x9d\xf8\xe9\x97A\x9c\xa2\x13\x9ck\x18\x89WT\xec&!\xbd\xebGj\xaf2R\xd2\xfc\x0cvK#\xa2\x1d\nT\xfd\xd5\x17\x7f\xa0KC0\"\xe1\x8b{\x0b\xc51e\xf1\xeeV\xab.\x86\x98\xcb\x8bfz\xf5N\xf0\x07\xc1[\xdbP?\x0dJ\xd0\xb2OGX,\xcc\xce\x8cnV\xa5\xe9\x04\xb7F|\xb5\\\xef\xddX\x8d\xc0w\xc1mc\x8c\xa8\xb1\xfaU\xbe\xb6\nj\x0bf\x02w@\xa0,\xc8\xf3=\x94\xfb\x17\x1a\xe8\xa8\x03] s\x15\xef\x02#,=\xf74\x14\xc1\xb7j8bb\x19\x95\x93'\x1e\x0d\x02\x13%FS\xe9\xc1(\x8f\x86te\xa3! rM\x04\x99\x91\x13\xbco\n\xbe\\\xec\xe8\xa0V\x08\x8c\xc7\x05\xf1\xa3T\xd0\xc8S\x85\xe2\x89\" \xaf\xe9V\x15.\xfa\x83\x9a\xd9\xd1}m\x89R\x7f0Y\xa9\xa7>+\xfaY\xea2\x88%\xd23k\x16\x05\xcc\xcf\xa8V\x01\x86\x9c\xbc\xb6\x0e'\x83\xcd\xb1\xa3\x94 \xe0TH\x9a\xe4\xd0\x0cF\x8e\xb3\x0cw\x17^\x15i\xf8q}(\x90\xffc:Q(f{QH\x9b\x141\xbf\x99T \xcb\x85\n\xd5c3\xa9\xd5\x1c\x18r\xc2ssV\xcb\x91!\xb3~k\xce^b\xc2P\xa4\x90\xe2&.\x83#f\xe6u\x81q\x1e719\xcb=f^\xf2RvZ\xbe\x80\xdb\x11\x85\xc5\xd2<\x1f\x05\x81\x05j\xb3\xef-\xc3me\x14l_\xbf6\x17(\x88,H\x05\xcd\xfbQ\x83]Jy?\"1p\x99C\x9e\xb3H>n06}\x81j\xaa~U\xc0\x1c\x19t\xd6\xbe\x7f\xe2\xf2\xaa\xfd9\xcfPIS\xb2\xabS\xfa\xa4\xabTp\xea\x89WL\xec\xe2u\x07d\xc0\xa0f=S\xae\xd7\x05\xe1Ph\x9e\x1d\x1e\x04R\x94\xc3\"\xe2G*\x9b\x98\xech\xfa\xc7\xdb\xc8F\xa3\x8fP\x14a\xf3hI\xd0#X\x03\xfb6\xb8\xd8\x05Fv'X\xb4\xee\x08#\x80\x87\xf2\x1f\xcb\xc5\xfbf\xe4\xaan\xe7\xde7\xdc\xcc)m\x15\x1a\x16\x98\x91\x18AW]\x1b\x9b^a;\xd1\x1b\x00\x93*\xa4\x90\x0e\x13L@\xde)\x14\xd2\x81F\x90\x99R\xbe\xcd\xc01V\x83\x843(u\x01\xc2\x03\xb6\xce\x0d-\x81\x07q\x19\xe9$\xcd\x12\xc6a\x01\xe2\x0d\xe95\x0b\x98`\xe5\xae\x8c*;2\x8a\n\x84\xa8\xd3\\\x07\x81\x9f\xa4~:k\xdd\xa2\x17\x7f\xd6\xa4K\xebh^b\x90\x04\x98\x83(\x0b\x02%VD\xe4\x9a\xf4&\x93\x9e\x12~1\xbc\xa21\xf6Rl\x1f\xf4\xfcc\x12Y\xd5\xf1\x90D] \xb6V\xecvDN%\x0f\x7f\xc19\xbd/x\xe8\xd25\x0c\xf2\x8e\x18eq5r\x83\xf9\x15\x96\xa1\xdd\xeb\xb0\xceG\"\xc4\x9c\xbb\xc0\x1aU\xd2\x95m:j\xc5\x87q\xfd8\xcb1 p\xff\xe5\x8bh\xfd%MD\xc6\xd9\x11\x03s\"&\xdb ^\xd1\xc0\x11\x9e\xf1\xcfP\xed\xf7l\xcb\xee\xfeL\xc2,\x15dG\xf7\x8c\x88\x1d#\x8f\xb7\x8f\xc9&\xa0[\x92\xb2Z`F\xf3\xcbG\xac\xb23\xbc \xb8T\xc1@\x8a\x81\xcf\x00}\xb9\xb9\x80\x1f\xf1\x08\"\xe9\xad\xd9\xdd \xdf7Eh\xbf\x82\xe1(\x8c9\x94Jl\xb5\xdf\xb2\x1b\x8az#Pw}\x84\xeb\\\xc6H\xb9Wf\x99!}\xec\xe3m+W\xdc\xdc\xdb\x9d/X\x9aP\x8f\xc1\x08\xce\x08\x04dr\xec\x0f\x8a\xfa\x8e\xc3\xdb\x02\xb7\xde\xc5\x86+\x8d\x18W\xa0\x1a9#O\x90\xb2\x98\xf2\xfa\xd5\xb7\x9d\xf0\xcanw\xbb\x80V\xdc\x96\x08,\x86\xa1UE12\xa5\xf95\nb\x95\xe6\x8eiMJ\xd2\xeb\xc4\x81S&\xbe\x10\xe5\xbdb\x87\xbbkzC\xa3J\xa6\xfd\xc1\x9c-\xf30\xba]\x1a\xdd\xd6\x1b=\xba\xc5.\xed\xe8\xce\xa5]\x1a\xaa*xtK\xad\x0b\xa9\x82\x829\xfeu\x01n[\x07\xae\xcb PU\x06d\xe8\xc2\xebU)\x0c\xae\xf9\xb9G\xe4K\xc5>\xbb\x8cH\xb1U=\x92\xfd\x1e0\xdf^M\xc3I\x1a\xe4\xbb\xf5\xbass\xb9\x9a\x0d\xd5hf\"\xa0\x82\xfe`\x94\xc7^\xac\x10\x14\xd4\xaf\xe9\xb9\xd0\xdc\x0bo\x11D\xe0\xf8\x1d\xefDr\xb5\x13W\x94\x17\xef/\x98\xc4\x0b\x98\xf4l\x92\xee\xfc\x8d\xe8+\x12<&\xb8\xed\xf7QrP\xdc\x9c\"\xc1l\xe2\x88n\x1c\x9d\x189\x85\x16\x03\xcfu\xc5\x0e\xce\xc2x\xcf\xfe\xee\x07\x8f\x16oX\x95FR\x0de\xbbv\x13\\p\xe2 _\xc0\xa8\xc3\xb1\n\x8e\xb7j\xc1c\xfdtD\x1c\xd7m\xc9!\x8d\xd9G\x9d\x89m}\xc9tY1\xb5\xe6;\x93\xe4\x1dM;\xcf\xbb\x15\x8e\xd0\x9a\xa3GzdX\x9d|\xb8(\xdc+\xdc\xa5\x81LL'w\x81(e\xe2\x1b\xc3?\x8f\x80\xaa\xc6\x89\x8f\xe3\x80\xae&\x8fk\xb1\xf3\x90\x1b\x1d\\\x87\x96J:\x8f\xa2\x16\xbcE\xe5`\xb2\x83\xce\x0f\xb0\xe2\x07\xc1\x0f\xf0\x96y\xef\xb2\x87\xd1\x95 \xaa \xf5\xdcb`2\xd2{\xd9\xcb\xa3\xf8\xda\x91R+\xbdwy\x8a\x05{/{\xcb\xa3T\xc7%\xf0:\x0c\x05\x8a\xcd\x96\x0bYA\xbe\x1a\xc5\xcb\xfc\xaaC\xa7\xd7G\xfb\xc0\xcd\x97\x87\x84j\xe2G\x84\x0d\x08sk\x03\x84\x16\x98\xc9\x90<\xc6\x08\x0b\xb0\xf5\xc0\xa8`\xed\xf4<\xa7\x16\xf5\xd1+\xa5\xbcW\xa2xMou\x84\x88\xfcQD\xdf\xceS\xdc\xa5\x89\xa2\xd6\xc9\xc8\xfcm\xbe?\x8c\xb4\xda\xa3-f\x06\x14\xe5\x1d\x98\x7f<\x0d@\x14`\x85\xd3+T\xb5\xe3X\xfe\x9e\xb3M\x7f\xd0\x82 ~N\"\xa0R\xedoZ\xcf\x04\xbb\x13\xfdBm\xa8\xb7oROt\x19\xbd\x02\xcc\x1d\x05f\xb3On\x1e9bm\x87Dc\x1e\x07(\xe6g\xf9:\xc2\xf6e\x8a\xbcC\xed&\xdb\xe6\x95\x1b\x13u\xa3K1\x1b'\xabA\xd5\x190\xb6!\xb9\"\xbd\xb7\xab\x80F7\xbd\xae\xaa\x942<]P\xae$\x81[-k\xfb\x12\x85\x93\x9a\xa1\xa5\x8dC\xd2\x1b#s\x9bu\xa4\xfc5\x8c\xe9\x02\xa9Uek`\xd7\xf1k\xadF\xae*f\x89\xbb\xd5\xbc\xc0\x11\xcd\x19b\xa2uT\xf6X\xce\xa8\xb0\x15\xbb\xc3@\x1e\x93\xef\xfe\xf8\xc37\xaf\xbf\xf9\x97\xaf\xde~\xf3\x87\xaf\xbf\xf9\xc37\xaf\xffc7\n\xe6<\xd69\x82\x8c\xa9\xf2z\x8f\x0f\x1a\xfe\xd3\xfe\xf5\xac7\x7f\xd3[>\xb9\xee\xc9\xc7\xf37\x8f\x97O\xae\x1f\xcb\xf9\x9b\xc7\xbd\xab\xcb\x97\x7f^\xa4\xcb\xe1\xe0\x14\x19\xdc\xe9\xfc\xcd\"]\x9c\xf5\x1e\xbf\\\x9c^-\xee\xce\xa6\xe3\xc5\xdd\xf4\xeb\xc5\xdd\xa7_/\x87\xa7\x134\x0fQ\xb3\xdb\xbf\x9e-\x16\xe9\x93+\xf5O\x0foM\xdao\x83\xeb\xde\xa8\xe8\xcbd\xaer+Vy\xd9?\xf9\xdd\x1f\xbf|\xfd\x1f\xbf\xfbj\xa0^u\xeab\x91\x0e\xf3W1\"= \xeeQ\n\x15\xaa\xcf\x83'\x86\xdb\xe2\xbb,Tq\xd9?\x85F{\xe0o\xe6t~6\xfe\x9c\x8e\xdf}1\xfeO\xcb\xfcq\xb6|rZ\xad\xb3\x0c\x81\xb0\xad\xa8^\x9d^\x17\xda\xcb\xf9\xf7\x88\xf4\xb6~\xcfE\x0b\xd5\xa0\x7f\xb9\xa3\x9cz\x82q\x13Q\xddhZ\xfa\x8f\xa2U\x9a\\\xc8G\xbf\x9e\xbe8\xbb\x90\x8f\x02\xa1\x9e\xe1q\x8b\x8f\xe7\x17\xf2\xd1OY\x0c/O\x9f\xc1\xbf\x9f_\xd4\xaf\xdb\xab\x1f\x989tA\xd8\xd2n\xa4\xb0\xf7\xb0\xf8Q\xb2\x8c\x98//PUzb|]\x82\xf2g\xfe\xf4@nE\x10ON\xc4A7\x1bAE\x93\x1b\x8f\x88\xd0\x9a\xbaf\xab\x81\xc0\xaa\x87\x91c\xa91Ut\xe7\x8bh\x0d\x93w\xff\x87x\xcdR0'\xf6At\xd1Zv\x7fD\xa2\x81M\xec\x17h\xfeWh\xa4\xa1\xca\xf5\xb5\x8f\x81\x81\xd6\x0d\n\xab\x1b\xa4M>\x86H\xe3fJ\x89wq!@\xc9\xa1\xa9\xf0\xaa\xc3\xd12\n^\xb7Q\xf0\xdc\xa3pD'4\xed\xf4\xbbP\xe5\x06(\x8e\xc3x\xad\xdf\x8dr\xb2Y\xd1I[\xba\xdd\xbcp\xf5~]\xaf\x8f\xc8*\xd79Z\x0eA\xd0\xb1\xf3C\xd3\x01{\xf89\xef\xb02\xa29\x07/\xb2\xcd\xd3E\x0b\x92t\x01\xf3\xd4X!\xda)\x84\xcb\xdc\x99\xf2\x91\xecg\x0f\x99\xba\xbaX\xd4(m\x14V\xc2\xd1'85\xc3\x86\xe2\xb2j\x11|Adh9\xe1\xb3\x92q\xc5\xe1Ds \x0f\xad\xa8\xaa!\x83\xcc\xef\x18Q5\x1f\xfb.H\xdc8\x12\xf9\x0c\x1e\x1c\x88\x0f\x06\xd9\xe0\xd4\x87\x00l\xf1\xf2\xe3\x81\xfb\xabr\x06\x87\xb4\xa4\x1a^\x9e\x8e\xb4S\xb0I\xffz\xe6G\x82\xf1\x08\xbc\xf4\xd1@Z\xf2\xe7\xc7\x91z\x01\x92\x14\xf3T2\x95-\xe1~\xcaR\x99\xecb\x81^i\xeee\xc2\xe35fO\xe5&\xce\xa25\xd4$\xfd0\x8cW~\xe0\xb3H\xfa\xd1:S}`\xa9\x0ciD\xb7\xb0VU\xb9\x84q%tI\xc1\xbc]\x14\x07\xf1\xf6^z;\xee\xa7\"\xa4\xa9\xf4\xe20\xcc\"_\xdc\xcb\xb5\xcf\x99\x82\xe1^\xb2u\xe6a\xf5\xec\xa7\xccO\xa0\x1e?J\x85/2\xc1dH\xf9\x0d\x13~\xb4\x95i\x1cd\x08\xd1\x9eb\x81T\xae(\xdfR_=\xc4\x99\xf0\x7f\xca\x98\\\xa1\xa20\x95j\xfb\xaedf\xe9\x05\x8cF\xf8\x10\x8b\x1d<\xc4a\x92 \xc6\xe5\x9a\x85\xb1\xc7\xa9\x90k\x9f\x86q\xb4N%\xf4\xdf\xf7R\xb9\x8b\x83\xb5\x1fmS\x19\xf8\xdb\x1d\xb4\x9fP.\"Us\x12d\xe1\n \xca\x92$\x80\xber\xeaC\x13{\x16)y4\x95\xd4\xa3k\x16\xdeK\x8fr\x06\xd0\xc4aB\xa3{\xe9\xf1\x0c\x06{\x1d\x87\x007\xbbK\xe2\x94\xad\xe5\x06\x9aI\xe5&\x88\xd5X\xc9-\x0d\x02\xc6\xef\xe56\xf3\x05\xe5\x00\x8e\xbf\xa6\xf7\xf2\xc6WX\x11\xc9\x88e\xa9\xa0\\\xc67~Do\xa9\xe4\xcc\xf3\x13\x96J\xce\"A\x03\xf5w\xef\xb3\xdbT\xa6;\xff&\xddQ\x89\xce R\x009\xe6B\xa6\xf7\xa9`a*\xe9\x96E\xde\xbd\\1\x1e\xf8\x91\xf4h\xc88\x95\x1e\xa0\x85\xf4\xe2\xcd\x861\x85/\xeb8\x95\n\x05\xa2\xadd\xa9\xa0\x82I\xa6z\n\xe03.\xe4&\x13\xab8\x9074\xdb\xb0H\x06\xd9]\xc6\xefeH\xfd4\x8ed\x18G4\xdd\xc90KY\x16\xca\x88n\xe3{\x8a\xb8\xa6\xa0L\xa8\xcf\xd5\x1f\x80)\xf6|\x1a\xe0\xa8\xdeKA\x85\x88c)|\x16\xad\xa9\x1a\xe1=\x0b\xe4\xde\xa7?\xb2T\xee\xfd \xa0\xeaO\xaa\xd0f\x1f\x03d\xfb\xf8\x9en\x99\x04\xccF4P\xa3\xbfN\xa5\xb7c4\x91\x9e\xdaw\xc85\x8d<&a\xd1\xcam@S5\xb2Y\xaa\xd0,\xda\xc62\xf2\xa3\x1f)L\xb4^\x0e2\xdd\xc5j\xd4\xe2\x80r)b5\x03\"\xbe\xb9\x8f\xa5\x88\xe3 \x95\xb7j\x8d\xca\xdb\x98\xdf\xa4\x922\x1eK\xca\x13*i\xeaS\xb9b\xa9\x90+\xff\x86\xc9U\x00h\xf9\xee\x9d\x1a\xdeDzA\xb6\x92^\x1c\xabU\x19'rCy(7~\xba\x93[\x7f#\xe46\xe3\x99\xf4\xa3M,\x7f\x8cW\xa9\xbc\xf1o}y\xc3\xd9Z\x064Z\xcb\xc0\x0fc\x19\xf8\xd1\x8d\x0cY\x94I\xb5\x18e\x18\xaf\xa9\x8ch\xc8d\xa2\xf06Q_\x938\x15\xf2\xa7$\x8e$\xf7\xbd\x9d\xe4\xd9\x8e\xcb\x94\xdd\xddK\xe1'\xa9\x1a/\xa6\xfe\x89\xe5-\x8d\xb6\xf2V-\xe7[\xff\xc6\x97\xef\xe2\x88\xa9%%W\xfeZ\xae|\x05\xf0J\xad#\xe9\xb1Xa\xb0Z\xaar\x1b\xef\xa5\x1f y\xe3\x872\xf4\x03\x191!\xe3(\x901\xdf\xaa\xe5/\x93l%\x15\xc0\x82\x052\x8bby\xcb\xd6\xf2\xee\xeeN\xde\xdd\xbf\x93\xd4\x93t-)\x93t#\xe9VR_\xd2@\xd2P\xd2H\xd2X\xd2\x9f$\xe5\x92\xa6\x92\nI3Io%\xbd\x93\xf4\x9d\\Q\xb9Z\xc9\xd5Z\xae\x98\\m\xe4j+W;\xb9\xf2\xe5\xeaG\xb9\n\xe5*\x92\xabX\xae\xb8\\\xa5r%\xe4j/W\xb7ru/W\n|\xe9y\xd2[Ko#\xbd\xad\xf4v\xd2\xf3\xa5w#\xbd@z\xa1\xf4\x14)\x94\x1e\x97^&\xbd\xbd\xf4n\xa5w'\xbd{\xe9\xbd\x93k&\xd7?\xca\xf5\x8d\\\x87r\x1d\xcb\xf5;\xc9<\xc9\x98d[\xc9\xb8d\xa9dB\xb2Ln|\xb9\xf9Qnn\xe4&\x94\x9bXn\xb8\xdcR\xb9]\xc9\xedZn\x99\xdcn\xe4v+\xb7jb\xe56\x90\xdbPn#\xb9M\xe4\xf6'\xb9\xe5r\x9b\xca\xad\x9an\xb9\xbd\x95\xdb{\xb9\xbb\x91\xbbP\xee\"\xb9\xe3r'\xe4.\x93\xfeZ\xfaL\xfa\x81\xf4C\xe9G\xd2\x8f\xa5\xff\x93\xf4\xb9\xf4S\xe9\x0b\xf9#\x93?\x86\xf2\xc7X\xfe\x98\xc8\x1b&o\xb6\xf2f'o|y\x13\xca\x9bH\xde$\xf2\x86\xcb\x9b[ys/o\xde\xc9\x80\xca`%\x03O\x06\xbe\x0cnd\xc0e\x90\xca@\xc8 \x93\xc1^\x06j\xa9\xca\xd0\x93\xe1Z\x86L\x86[\x19\xeedx#\xc3@\x86\xa1\x0c\xd5\n\x96a\"\xc3\x9fd\xc8e\x98\xcaP\xc80\x93\xe1^\x86\xb72\xbc\x93\xe1\xbd\x0c\xdf\xc9\x88\xca\xc8\x93\x11\x93\xd1FF[\x19\xf92\nd\x14\xcb(\x91\x11\x97Q&\xa3w2\x0eeBe\xc2d\xb2\x91\xc9V&;\x99\xdc\xc8$\x90I(\x93H&\\&\xa9L\x84Lner/\x7fR4M\xf2X\xf2T\xf2L\xf2[\x99R\x99\xaed\xea\xc9t-S&\xd3\xadLw2\xf5e\xfa\xa3Lod\x1a\xc84\x94i$\xd3X\xa6\\\xa6B\xa6\x99L\xf72\xbd\x93\xe9\xbdL\xdfI\xe1I\xb1\x96b#\xc5V\x8a\x9d\x14?Jq#E E(E$E,E\"\x05\x97BH\xb1\x97\xe2V\x8aw2\xa32\xdb\xca\xecFf\xa9\xcc\xeee\xf6N\xee\xa9\xdc{r\xcf\xe4~+\xf7\xbe\xdcGr\x9f\xc9\xdb\x8d\xbcM\xe5=\x93\xf7B\xbe\xa3\xf2](\xdf\xdd\x0e\x16\xab\xd3\xaa\xe6\xb47\"\xe8\xffoq\xbb\x1c\xfc\xa6\xbf\xb8\xfdy:\x9a>\x7f?0\xba\xcc\xb2:\x14r_\xcf\xe6\x8b\xf1\xc5\xec\xd1\xd5b\xb8\xf8d\xb4\xb8]L\x96\xc3\xdf\x14\nD\xf6\x897Ub4\xa3\xb6B\x94\x19\x96\xf3\xf1dh\xc5\x87\xe5p\xd6\xbf>i\xfa\xb48]\x9c\x0e\xfa\xd7'\x8b\xf5pqz=\xe8_c\xca\xb5\x13\x90\xbaJ\xb7?\xb9>E\xa5\xaej\xff\xf6\xf6v19\xbadsG\xad\xf6\x17\xd4\xc5\x8b\xb1\x05|\xf8\xe87\xbf^\x9c\xfe\xd3\xd5\x7f~\xdb\x1f\xc8\xc7\x9f\x80@Tg\xe1O\xbc\x0du\xc8\x11\xb3@\x8c\x0f\xaf\x03y\x12=\x1a\x7f\xe2\x81&-''Y\xb7\"\xdf\xb3\x80\n\x7f\xcfl\xb9\xcd\x81S\xc8\xa3/\xfa\x117\x99$\x87NX\x9a\x87\xd0\xd2\xf7\x19I\x9a\xa1\xb54\x7fF\x1cZc\xf3\x0b\xb1\xdf\x0d\xc1~\xba\x10\xf7vj\xd4E\x08\x81\xdb\xe4\x03\xe3bX!\xf9\x17\xa2_\"W\x87\xf8\xb4\x00$\xc6\x95r\xba\xe8\x9fn\x0f\xdc\xb7\x8fJ\xf9\x07\xa7\xdb\x03<\x1b\xb9\x80\x0d\x0e#%9\x1b\x90K\xd2\x07\xf2\x14\x95\x92-!?9\xeb8\xa6$\x9fs\x87w8\x976\xf2UU0\xeb\xaa\x84\xf4#pK\xd5(X\xce\x17\xb7\xcb\x06\xc1rG\xd3\xaf\xb3 \xc8\x8b\x9a\"-\x12\xbf\xa3\x9a\x8c\xfb?x;\x16\xb2\x83\x15\xb8a\xf8\x0f1_\x7f\xa90d#\x18\xaf\x023\x9b\xbfY\xa4\xcb'\xd7\xa6JG\x15E\xe6\xdb]\x1e5\xd3S\x94\x06tM\x7f2\x1dR\xec\xca\xdcb\xc94!\xfa]\xcc\xd2?\xc4\xe2\xf7to)\xf6\x1f\xf9\xefb\xa1\xad\xd3Z\xb2\x7f!\xbee4\x15\x7f\x8c\x98\xe9q\xa5\x8c\x9f~S\x9b\xcc\x9c\x92\xf5]\xe7\xf1\xce\x13\x89r'\xba,\xd7\xea\x82\xd3](\xce\xeb`~\xb6,\x1f\xac\xb6J\xf1\xbd\x1f\xe9\x9e\xa6\x1e\xf7\x131Cg=0\xce\xbd\xfd\xaa\x9c\xd8\xa5G\x87\x86\xbe\xa3\x89\xa0\x9d\xf1\x13\x86\x8e\xe7\xd5\xfa\x07\xfb\x00\xc7:@\x9fw89c\x13A\xdb\x1avO\\\xded\xbbA^\xc7\x82\x87\x81\x7f\x827&NL\x0f\x9aWQ\xcdW\xac\xf99\x91\xa7\x0d\x05\xbb\xa0\x92\x01\xf3\x84\xd9\xf1m#Q\xcd\xc09\x88$\n#P\xf8\x08\n\xf9Q\xf6\xcf]\x06\xef\x01\xc7\xbc\xaf\x8abS\xd7C\xae\xc2\xbe\x18Jv\x84-7\xf5=\x06\xc2\xa2\xc1\xa6\xb3T\xe3<\xc1\x8e\xc3q\xf6W\x98\xc5\x8fs\xe6\x87\x1ej;\x8e\xc2W\xb8\x7f\xe9Zy\xbe\x1f\xecX\x7fq\x94\xbb6R\xf4g\xfb\xc0\x06\x1f\x80A\x0d\x8d4\xce\xa7\xde\x8a\xfd-fT\xef\xd5\xba\xce\xe9\xeb\xf2\xd6\xaek3E\x0d\x00\x96\xed\xd8\xde\x83\xe6\xd88N\xd3\x0d\x82\xe74;\xe1\x0f\x87\xe2\xb8\x89\xef\xfd\xa6k\x93\x8dh\xf0'\xfe\x80E\x9d\xf1\x00\xf7S\xb9\xc2\x13\xc6\xc3(\x8d\xfb\xa8\x00\xbe>uY\xc3VX\x91\xad\xa2A\x1e5\xf9\xbf\xe3,a\xd1\x9a\xad?\x96\xedI\xc6;S\x99?\xf1.4\xa6tO'\xe3\x0dJ\xa2\"\xb6:\xf7\xb8V\x80\xacn\x9ak\x1f\xec\x90\x94}\xc3d0\xa5=\xed+\x10\xcc\xbdGM\x05!\xf4}G\xaf \x0f\\*\xd0\xb2qv\x9e\xfb\xf4~D\xc3\xe4\x02\xe21=\xeav\xcd\xea\xd85R\xbd6\x05\xed?tN\x8c\xbe\xae\xa8P(\xe7\xc3\x05\xd1\x07\xe7XU\xb5\x83\xa3\xf8\x9f\xcc\x12\xc2\x12\xf6#^`}\xcd\xa9\x1f\xf8\xd1\xf6\x87\x80B\xcc\xf6.\xe3S\xae\xb6\x8bl\xe4V\xd1\x97\x17\xb7\xdb\xe1zS\xf3\xeeAy8,Nb\xd1\x19$\xc7X\x1e\x01J\xef\xb4M\xe1Q\xd4\xe0\x1a\x87\xab\xe3i'/F\x8a\xfa\xda\x94\xf7#\xedh\x11c$\xf16?\xa5\x1a\xb0x\x92\xfb\xe5\x84\xbb\xc0\xf9`\xbc7\xbeeFd\xbe\xc4(>\xfd\xa2\xdbx\x1d\x8a\xeaC\xa3a\x1b\x8c\xc8<\x0fa\xde\x1b\x91\x1e\x04\xa4\x86\xf02\xea-\xf0S\xd1s\x85(\x9d\x973Bm\x9f\x7f@m;\xaek9?\xfb\x80Z\xe0\x93\xaeg\xdaZ\x8f\xbb\xbc \xcbm\xea8\xaf\xd4\xd1\x00;\xa3k?\xda\x9aBO\x1f\xd0pP\xa9\xe3\x99{\xf6v\"\x0c\xa0.\x93\xef\xf9\x03\xda\x12t\x15\xd8\x1e~\xda\xa9\x87k\xb6)\x0em\x15m\xdc\x85\x8aPA\xb1\xcf+\x81\x0d\x97\xee\x98x\xd5\x05\x8a\x14<\x0b\xacW\xb6\x8a\xcb){\xdd\x81\xa1\x1b\x1bF.\x89o\xaf)\xb0\xe1pP\xa8BG\x92\x9f\xb3%\xc4\xe7\x82\x87\xe9\xd2%\x8e\xd1@\xcc\x08\xe6<\x87\xf3\x85\xf9r\xa0\xa9\xd2\xa0BzrJa\x9fh\xc1\xad\x11\x04\x82\xf0\xdf\xb1\xaa\x835\x87\xe6\xcd\xf6E{\xfb-\x00\xbee\xe2\xfb,`)\x1e\xa3\xa3\xa3\x04\xec$\xbaH\x10\xe8\x10\xe1dzA(\xb9\xd4GHl\x12\xf8\x91j\x98\"Q\xbd\xf1\x93\xaf\xc2D\xdc\x7f\xebG,\xedS\x08m@\xc9\xcb+\x12\xa1\x17\xfe\x93>\x9b\x88\x1fv\xfeF\xcc\xe9\x12\xae\xdb\xac\x82\x9bo\xa25\x8b\x84\xfb\xfa\x13\x00\xccq\xe0\xe1F\x08\xd4\x12\xcf\xf9Ru\x91\xc2\xf1\xe6\xc9tpA\xf8p\xe8\x90\x130\xea\x85\xf0\xb7;\xa1`\xcfF\x84M\xfc\x14@4\xb0[\xbe\x90\x19\xb9\xaa\x8f\x9dQ_\x07\xa6\xa7y1\xda\xa86W\x8da%#2\x1c\xdaAB\xaa\xa1\xb9RB9\x8b@\xe8\xad\xd7\xda\x12\x0e&\x1f\xe7\xda\xe7\n\x9f\xcaq\xa5\xcc\x0420S]D\x0bQ\x8b%\x99\x82q*W\x1f\xb3\xb3\xb3\xcf\x9e/\xe5|\x91\x9d?;\x7f\xb6\xc8\xce\xcf\xce?\xd3\x89\xd5R\x01\x94\xca\xce\xce\xe8\xd9i!,X\x111\xe1\x8e\x91\x03+G\x84W\xc7P\x81\xe8#\xa2\xb9<)\x03\x02\x94\x92\xe1>>\xb3\xc7\x02\xd5\x9b\xf3\xc0\xe55\xab7\xc2I0\x02'\x10\xb98\x9b\x8eHo\x11\xa9\x14\xabU\\\x88\xde \x8f^W.\x9f\x15\x18p\x93Z\x1b\xd6V}\x0e5\x94\xd3\xb3\x82p\xf2e\xbcf_\x88~4 \xd7:,,F\xf9\xf3t<\x14\x08\xfe\xa6P\xbf\xa7j\xe8i\xda\x00\xee\x85)\x19\x13o@\xfe\x89<3\xc7\xb5\x90\x08\xc5y\x95z\xe8\xd5\x8c>\x15\x99\xf1\x07k\xe6\xc1\xdc\xab\xd54\xa4\xef\x8f\x14q\xf3#f\xfe\xbe\xa2w\x05\x024*\x05\xb4Al\x1fz\x1epZ\x86U?@e\x18kM\x9a\xeb\xae\xae\x96\xab\xdf\x8a\x00\x9c\x0dj\xa8X\xac;\xdf7\xfd\xaa\x0e\x08/\xbaUD\x1e\xd6\x1a<\xa0\xb8Y\xc7\xfa\xe7li\xd5`(\x11\xb0\xa5\xa2\xbc\x85.\x14=\x9f\xbd\x1f\x95\xda,K\x1a\xadM\xd7]\xda\xeb\xfe\xa2(\x87g\x8f\xfdC\x90]V\x00\x1b\xa0\xe8w\xe1\xea%k\x83\xfa\x87\x84zGC\x9cr/\x978\x0d\xd0z\x15\xd9\x0c\x85%\xc8\x1e\x0c\xde\x97;\xca\xd3C\xaezKn1\x9d\x00F\xf6\xe4\xa9\x06\x19\x02\xfdA\xf0\xfd\x96z5w\xc2\x0e\x86\x0c\xd2\x1f\xb9\x04\x97\xf8\xa6n\x07\xdfP\x10\xbf$\x91#b/Z\xaa\x9d4\x0c\xf2x\xccr\xbb\x04\xa6\x96\xedq\xdd\xd92Q\xc7\xdeV \xa9j\x19\xa98]],b\xb0\x8c\x1a=\x14\xa9,\x81\x82\xb6\xe2\x92\xd4/\xaf\xffy\xa0V\x01F5\xf0\xf1\x10\xce,\x87`9\x02\xb7\xad\x8acpr]Z\x19Pjj\x1c\xc1\xdb\xc4Q>\x82(\xc7\xa8~\x0c\x1c\x93\x91iQ\x05|\xb7\xf6\x05\x19\x83\xe1\xac\xf6 \x1a(\xd4\xbf \x81\xa2\xbc\xf1p8\x80\x88ne\xc8\x06j*Ax\x03&?\x18\x01\x07;\xb3)gZ\x1c\xaa\xf54\xc5\xfe\xe0\xc8\xa8\x15&e\xf7\xcee\xf3xY\\\n\x8d}\xd4c\x9d\xd5}UUD+\xb4\x8d;J\xb42\xa9\xee\x90\x83\xee%b\xf6\x82\x0e,2c*\x96j\x12\n\"\xcd%y\x96\x9b\xe3L\x1ds\x18\x03^\\\x81\x8f\x9a)\xee\xdb\x9aVW\xbe\x03\xe2j-\xb9x~\x8b\xdd\x1fl\x02rHy\x15\xd2\x97W\xe4Y\xfb\xc6J\x81:\x1c\x1er\x06k\xf5\x9cZ\x86\xe3\xa3<\xf6{C\x8c*\x1d\x8b\nUf\xb5\xaf6\xe6TN\x05\xd4\x96\"\x1e\x91g\xe0\xe8\xc5va\x04[\xd2ZyP\xc2\xb8\xaf'*\x10\xd3\x19\x99\x8b\x91\x86\xd7\xa1<\xd1\xe1\xab\x18\xca\x8c\xa5\xcf\xef\x95\xf0\x96\x8bI\xef\x7f\x194\xecN\xdf\\\xc7F\xe8|C/^\xb1\x84\x11\xb3\xc8Z\xcf\xbe\x81\xec\xccd\xaf\xa3\xbaG\x86\xe4)yI6\x8dh\xadrM\xcf_\xa0\xd7\x96\x18u\x1def\xe0\xa1\x82\xe3s\xcc\x13\xb7\xd6\x04\x92\xf7\x08%\xe7\xbeg5'\xc0\xda\xfa\x9e\xda\x03\x0d\xc8\x98\xa4\x03rI\x9e\xb6V\xa45\x159\xc5\x01C\xf9\x89\xe0~\xd8/\xeej\xff\xac7\xb5\xad\x95\xf1\x82\x8d]\x03a\x16\x17\xe4\xa4?\x1cf\xa8\xd1A\xc1 :\x90\x16g$+\xcdH\xb6\x04\x9b\xbe\xd2$\xa84P\x7f\xd8<5]P\x03\xb5\xa8\x8d:0\xb1\xb8\xa2[\xca\\\x84\x00\x04\xf8\xe6\xd1\x06\xe5R9\x0b\x8aj0\xb5\x10\xb0\xbe\x81\n\x01\x9a\x9e\xb9\xe9\x0b\x90\x9en\xd4\xc5\x87vs<\xce\xc9MF\x86\x8ae_\x03\xeb\x81\x93\xbfn\xc4\x07\x94\xf1\x0e\xea\x93PN\xc3tFhG\xc2\x84\x8a\x85\x0c\x16\xa7\x93\x1c\xfd{\xa29\xf5\xb0\xbb\xc7Q\x9b\xf0\x10\xb5\xd9\x93\x97$l]\x89/\xce\xb5\xb1[\x05\xdb\xf7\xc3\xe1\xa0\xb5\xa0\x1e\\\x85\xeey\xac\xdf\x90\xde\xfd\x81\xa5\xc2\x8f\xb6\x1f\xb2\xfc\xf5f\xa3\x0e\x13\xac\xe4\xbd\x92\xc84\x11\xc8Y\x17\xab\xeaA \xeaaa,\x01\xc9\xf3\x91\xbd\"{\x14\xce X\xed\x9e\\\x92\x10\xc2\x11\x15\xd6\xe2~@fd\x0f\xd4,D\x81m^\x98\x0d\xa8/\x17[T\x1d\xe3b\x0b#\xcd\x0bP-TS|\x17\x8e6\x8cO)\x94`b\xb3\xa39\xe9\xf7K\xe8\x10\x97\xd0!^\x02`\xfd\x12\n\xc4\xcb\xc1\x00\x03\xa09IZ\xfb\\7\x8b=~\xabXc\x03+\x9fLGpW\xe7\x0c\xaf\xa6l\xec&-!\x97d}A\x92C\xb1\x0b6\xf3d\xa9/eE\xb0\xfa\xdbt6\x04\xaeA4SC\xf3sSE\xf3k\xf6\xd0\xb5k\xedtf\\\xfd\xdb\xc9Q{\x14\x93\x98\xcf\xd1\xa88c\xa0A{\xfa\xf4\xd3:\x8dF\xc1\xb3\x03\xde;\xdb-\xa2\xc8\xf1x}\x18\xe8\x12f\xc7K\xc7\x8a\x0dH\xf9\xc0aT>~\xb8\xaa\x9c{v\xe4)y\x99\xa6\xa0\xc1\x9a\x19@\x84g1\".wue^P \xed\xfb~0\xca\x97\xa8\xd5K#\x11\x8f\xbb3\xbf\x02\xa0M\xf1om\x9c\xdb&\xa6T\x190\xc5\x1b\xe6\xd3\xa5=\x1d\xd2K\x0b\x17\x13\xcd\x97\x16F\xac\xd6s\x93\x90!\x01Z\x94\xcd\x93\"}\xb2\xe9t\x9e,\xdd\x8a\x83\x12\xf9L\xff.xd\x99\x17:\x0cJ\x0eq\xbf~F\x86%9Gm\xd8\xd3V\xce\xf4\xec\xbcE\xee\xce\x80N>zD\x9e=G\xc9\x1b\xa4\xf0\xe7\x07\xa4pX jEN/HF.I\xea<|\xac\x88\xd8\xb5Vm{O\x11B\xda\xd8\x1e\x01\xbfrVT\xf5\xab(\xef\x9a\xfe\x93\xbe\x8f\x1b\x80G\x8fH\xff\xe4\x84k\xbb\x10-\x13j\xa1\xac\xe3b\xd8\xf1\xe6\x85\xfaaR\xdb\xa0z:}\x14N\xda\xe4\xcai\x90\x0b \xf5\xf9\x90s\xa9\xf4y\x9b\x90\x86\\9.\xa3\xe6\x80\\\x93\xb1\x12\xa8\x0dzE\xae\x89\xe6\x15\xf4\x02)\xe0\xd9S\xfd\xack\xe0\xe4\xb2\x84\x07\xf5Zlc\xbc0Z\xf5\xce\xc7\xad\x9d?N\x0e\x8d\x0f\xadD\xf0\x83\xa8F&_&c\xd7\x1e\xb3e\\.\xc9\xb3\xcf\x14ZF\xe4%y\xfeic5\xa8em\\b\xbc\x1d\x08b\x15=m\xa0\xa8\x1d\xdegj\x0e\"ry\xa5\x80i\x13\x9e\x9e\xa1\xee3R\xb0?{a\xa2\xa6\xb6\x88\x16\x16\xb4\xda\xd7\xa6\xe3\xf7B\xa9\x07\xa2\x87yj\xa7\xd7\xb534p\x87\xd9\xb2\x9b\x19)\x01c;\"\xf7#\xb2\x1a\x91\xb7#r;\"_\x8d\xc8\xdd\x88\xfc0\"_\x8e\xc8\xcd\x88|\xe1\x10\xe1\x00\x15\x94\x08\xa9q\xd4(\x14\xb6\x8e\xbc\x0d\x1a;=\x89\xaa\x12^\xaa\xa4\x95lB\x03\xd3\x96Q\xfe\xd0\x8dO\xe8B\xaa\xb5\xbe\xcf\xed\xb7\xef\x8aV\xb8gG\x12l\xace\xb6\xe4\x1a\xef\x017\xafV\xd8T\xa2\xffj\xad\xd4\xd07\xca\xd5<\x911I\xf0~fg\xfa\x1e\xf35\xe3l\xfd6\xf0S\xd1$\x97A\x9e\x19\xd972\x82\xdb\x87KlJz\xed\x08\xea*\x0b\x02&Z!\xfdpx\xac\xc9\xd2[\xbd\x07\xbak\xdb\xf7\x81\x81\xce\xe0\x82\x9c\xf4O\xfa`\xb6\x836\x98\xb0\x81\xea\xdfW\xd5AkD[K[\xe9Rkf\xee\xc9\x98\xac\x958\xf3\x0cX\xb6*\xadPhG.\xc9\xb4\x94\xa2\xa4\xa8uQ~\xa7\n?v\x9dg\x1b\xc6\xce\x17,<0\x80_}\xc8\x00\x06\xd5\xdd<\xea\xc5\xc0H\xc1\xec\xf5\x0b\x08\xbdq\xec6\x8a;\xf1\xfb\xeaN\xbc,\xdd\x82e\x965\x808\xab\xefU\xb4}`\xd3\xc6\x00\xf7\xa6y%j\xaf\xfe\x16f\x11\x88\x99\x1a\xf5\xb7Vn'c\"\xc8K\x9c\x14\xa7=X\x15\xba\xa0\xda\x9b\xb4\x08\xaeW\x83v\xf3\x80\xa9|\xf0&\x050\xbd\xb0'\xf9\n\xb7(tD\xee+\xd2:\xd1\xa6xj\\\x8a\xa6g\xf8~\xbc]\xde\x8d^\\?\xa0\x82\xe1KrE\xee\xec.\xe8\x07rI\xbe\xbc ?4)\x18\x14\xe9\xbd\x9b\xffP\xb4\xe3kW.\xdc\x1cP,4+\x15\xea\n\x05\xd5\xf8M#\xc7W_\xb7m\xf2C\xce\x08)HAg\x83&Eo\xeev#\xe7{\xe52\xee\xe6C\xb7\xa4\xb0\xd6\xf7\xf6\xeb\xad5\x1cXuAB\xc5\xaf\xca\x1c\x04q\x91T\xa8\xf5\x831\xf4\xd6bdn\xc7\xa8\xa4\x8cG\x8f\xda\xcd\x0cHY\xf2G\x1c\x07>?$\xe7\xf5q\x03\x9c\x8c\xf4\xde\xe8\xdc\x08\xcc%\xe6L\xc6\xe4\xbc\x14\xb7\xd3f\x98GKcAevi\xb9\x851\xd2Y\xad\x08\xca\xf3\x0bm\xc6\xd9\xcf\x13U\xcb\xcb\n!+\x14(\xa4G\xe8\xd8\xbc1k\x97\x82\xa1\x7fO\x9b\x8bv$\x08\x99\xb6g\x1b\x92sT+\xf43\xb3\x0b\xf4\x14\x17x\xfe\x99{\x08\x87\xc3lPVDd\xc3\xa1\xc2m\x16\xed'\xe6VCjn\xae\x94\xd2 \\c-\xeb\x84\xb3\x8d3?~\xd0\x85R+\x9a\xe3\xf1f\x80\x0b;S\xcb\xb8\xa1\xcey\x0f\xae\xf0\xa6Km\x1a\xd9\x8d\x04\xda\x9b\x19o9\xdb0\xce\"\xafY\xbdIW\x8a\xda9\xe2\xe1\x1f\x14\xa9\xe2*?\xae\x1d\xf9\xd1\x03RTI\x10\xcd\x06d\x8c\x82S\xf1\x08%+\x0b/\xc3+\xf2\xac.M\x15.\xa2\x14\x1b(1~C\xd9\xec\xd7\xe1U\xedx\xc7\xb6;.}k\xd1\xe0\xe6\x82Z \"Z\x86z\xac\xa1.\xf6\xdd\xaf\xf64\xfe\x90\xd9}03SR\xca\x07\xe9\xbcL\xea\x07Q\xe7\xe3\xe8\xf2A\xad,\x9c\xe8\xb7ka\x9f>o\xd3\xc2\xe2\xb5\xb5\x03\xd5\xe4ZW\xb3\x16\x1cd\xe6\x82<}\x9e\xf3`P\xce\x82\xca\x94\\^\x91\x17\x17\x03\xe2\x83\xf1Wci\x17\xd5;\xe9\xfb\xe4%y\x81\x10\xea\xfa\xb4.&.S\xb5\xd4\xae1kg\xd8OG\xe4\xa9\":\xf9\xcd\x90\xfa\xf7\xe7\xea\xbb\xda\xfae$7\xcc\xac\x01H\xf3\xcb&`=?(\x08DG\xeas\xf1:W\x13\x8d\xda}\x8bX\xec\xb8\xc9\xfd\x11\x94\xbev\x0c;\x02\xebG\xaa\x9dv+\xa8\x9c\xc6CH\x1fm\xc2r\x084\x18\xb3\x07u\xd1\xdb\xf9\xc1\x1a\x1ci\xcd\x97\xb5\x0ev\xec\x97\x99\x84&R\xd26\x0b\xbf\xacZ\xdd\xa4>\xc4\x12pd\xee\xe1\x88F\x8bV{\xa7K\xcb\x10\xcd{GG\x86\x8aa\x8e=\xe0\xe8\xf7K\xec\x91\x96\x88\x1a\xd5:|\xbfH\xc8\xe8R\xcb$\xfdg\xcf\xf3\x8b\xb8\xb5U\x17#mz\x81:_\x8eE\xe2\xf2B\xee\xc7x\x17\xc6BQ`\xb31l\xd7\xfcb\xb9F\xb5^\xe1>\xdc/\xb0\x9cM\x17\xb4\xbe\xe9\xfca\xa8\x7f\x00\xf7:\x82|\xdc\xa2\x06V\x9d\x1f\xbd|\xdc\xe5\xad\xa8\xea\xbf\xf2\x12\xef03\x87W\xfc\xe0# \x16\x85;\xdfg\xe7\xd5\xbb\xdd\n\x81O\xdf\\\xf6\xe7:x\x9fvu=_\xa4\x8b\xd3\x97U\xd7n>f^\x9c:\xb2\xbf\\\x9ev#4#B]\xb4&?\xa0\xa8H\xc5\xb5\xa1\xab\xd8o\xd63$e1\xba.\xbbxJvMF\xe4$\xdf\xdc\xedD\x18\xb4\xca;\x89\xa2M\x8apx\xb0[zyu\xc0<\xf4\xc5\x99{\xeb\xe4\xb5\xef<\x9f\xe2\xa6\xae\x9f\xb9H\x97\xa7w\xae\x8a|a\xbe\xaci_Y8{._rz\xdfv\x1c\xf3\xecS\x00\x1a\xa4\x96\x93\x96\x1b)\xe6g.\xa5<='\xb2z\xf5\xc0\xfc4\x18`t\xf9\xf9\xa7\xaaf\xa1d\xb7\xe9\xf9y-\xfb\xfb.\xdb\xdeg\x9f6\xf7\x9c\xd8c\xa5\xeaV\x11-a\xd1\x95\x9e?(\xb6R\x87\"W\xd2\xb5\xd7\x13\x0f\x0eC{\x82h\xc0\xe7\xe9|Zq\xd6\xb7o\x0b\xd5m\xfcm\xc6\xa1U\xb5\xb3e\x1c\x9fx\xa8\xfe\xee\xa6\xf0\xef9\xfc\xfb\x14\xfe}\x06\xff>\x87\x7f_\xc0\xbf\x8c\xae\xb1\xd4\xce\xc2\x03\x1e2z\xfe\x86\xd3P\xbb\xc1P\xff\x86\x14>\xc6\xe0\xd9\x0f\x9e\x00\xd28\x13I\x06\xef\xf09A`\x12\x1eo9K\xa1\xf3\xe8b\x12\x9e\x98g\xe0N\xc5=\x8e\xa6\xf1\x11\xd1\x13f\xd8\x04tY\xb0;A9\xa3\xf0\xbc\xc1\x0b\xaf=\x01~'\x04\xc7gF!g\x06p\xec\xfd5\x8b{\xcb\xc9&\xe6_Qo\xd7o\xb9\x808g\xcb\xf2\x0dP\xad\x95\xfa\x90\x1b76\xb9\x8b\xf9\x8aCr\xcc\x95)\xb5u\xc0\xdb\xb6\xecv\xf9\x16N\x8e\xc1BdL\"\x97\xb7\x88v\xf6\xdc\xf5\xcau\xd1\x8a\xa0\xce\xc8\x04\xb2\xc9\xc2];\x17\xbb\x0bJ[]\xe4\xd8Am\xd7\xd0RA\xbf\xa4\xfa\x08J\x12x\xb0,\x9f\xcc\x06\xcd\x14\xd7\x87\x0b\x1d\xa80\xd6\xbb\n\x87J#\xb7\xfb\x81\x1b\xbfZ;\xea\xb7\xd6J\xady\x030\xef\x1199}3\x1f\xcf$Y\x0e?9EW\x9b\xb4]$\x80\x1b\x08\x14C\xa9\xf6{\xb2\xa7\xf6\x1f\x10\x03\xb5M\xad\x92\xe8\xeb\xe7)Z$\xa6\xe4\x92\xe472[no\x9f\xc0\xb9\x947O\x97\xe6\xdaH\x1b\x9fE\xff\x05\xa0\xb8M\xe1\xd1+\xb9W2\xd7\xb2[\x05\x83\x83\xde\x98\x89\x01\xed\xf4\xcd\xecz<\x9c]\x9bq[\xb7\xb3\xdf\xe7\x9f\x01H\xeb\xd2\x81Y \xbek\x92 {se=S\xdf{\x18b\x0b\xce\xbe\xb8\xbf\xdd\x89\xde\x80\xcc\x9c5\x9f\x15\xaa\xeb\x05l\x839MB\xaf\xed\x06\xb7\xea\xdc\x18w\x0c\x05tq\xdc\xdb\x81\xb9o\xc1\x14D\x14\xeb\x9d\xed\xcdB\xca\x85\xfc\x04\xfc\xb3\xf5\x06\x05\x04\x1a\x91\xc4\x8c\xc3Ia\xd2Z\xeb\x8e\xdb-_:\x8a\x0b@\xe8\x0f\x98)\xec>\xc4L\xa1+\x1c\x8ao\x1c\x80C\xc1\x00\x8b\xf6\x97\x84\x83\xff\x92@4/\xfe\xae\xe0\xed\x9a\xc0\xa3\x81\xbf\x8df$\x99\xa7.\xc0>\x02\xec\x1d!<\xacw(\xd0\xb2\x8f\x00\xe9/\xa3W\x10\xbb\x87\x1e@|\xc0R\xe4\x0fm\xf3\x88n\xa9U\xf6\x8b\xb7\xa2d\xc6\x03\xcbh\x0f4\x05\x8f\x0b\x1fDW\x8c\xa0r\x8e\xdb+}\xfb\xa7Efy\xf4\xc88)\xcfiz\xe0\xa6\xe9p\x83\xbd\xd1\xaa\xa6;Q?4^\xa4\x0b\xdd!\x87F\x83|0q!\x058\x1a\x8909DdHW@7F\xa0\xc9\xc3\xf3+Q\x0f\xc4\x15\x95\\e\xe2p\xabrD\x9a\xf2\xc0{Y\x8a\xa8$\x91Y1\xc5j7\x8f\x19\x97F\xb2F\x8a\xa4\xad!\x8a\xca!\x8aE\xda\xa8\x16\xe9\xb8\xf8Hi\x12\x9b\xd689\xb4\xce\x89\x83\x8a\x11\xd8\xa2to\xbe\x99\x90\x91n\xcd\x97W{\xe9\xcdn\xad\x8e E\xbf8\xc1\x03!\xea\xc1\xad\xec\xd0\xfcj\x8f\x7f\x82QI\xed\xf3a\xea\x13\x9b\xdce\x03\\\xb0\xe2\xea|r\xedw\xd8\x06\xc7j\xd3\xe7\x1b\x13z{M\xdf}\x18d\xees\xe8\xbd\x1c7\xc5b\x14\xc7#\xd7\xe9\x8f\xce\x12\x95\xda\x89*\xe3F~\x91}\xb6\xb5\xd6o\x15\xd0\xfb,\xf7\x08\x06\x96\x85\x8f\x1e\xd9\x89x\xe9t\x9d\xb7)\xee\xc3\x8d\xaep\x03\x05\x87\xc3\xcd\xc1m\xbc\x9d\xb3\xcdQ{w\xdf0\xc6\x8d1\x81lm\x03\xd0\xf9h\x9b,m\xa7\\4\xfb\xeb\xbc\xd2\xd6\xc1\x01\xb9\"\xf8\x90\xbdJ\x866\xe9J<\xa8\xf8\xafc\xb3\xb6K2\xf0\xe9^\xdb\x0dn\xb5\xd1\xed\xa1\x1e\x91B\xaf\x1a-\xedIA$\xceF$\xfb\x10\xb6{\x04@\xdd\xb8]A\x03\xac`3\xd8Z\xf4\x8d2m>J$\x1d\x8f\x13I\xb7!\xf8\x98\xfcs\xddlKK\x0e\x11t\x82\xfc\xd3\x89'$_\x9d\x07A!\x05pZe2\x92\x8f\x8f\"k\xf3\x8d\x1b\xf9m\xd6C\xa8B\xf4x\xe1\xb5\x1b}\x9d`\x0d/\x86\x86\x8d\xf4\x89^a\xa6\xf7\xc5#>\xba\x1c\x81\xd2\xa0j)W4\xd9gE\x1f\x89E\xfb\x03\xd8\x12\x14\x13\x14M/\xdd\xc5\x18\x91\xf6\xab\x08\xb9\xb7b\xa7\x91\x1bu\xdfF\xd8\x82\x81\xd1\xbd\xb9\x8d\xb0\x05\xb0\xf4\xf15=x\x1b\xa1\x08\xee\xbe\x08`X\x83oW\x1d\x8adT\x1e\x8du7d%%\x0ciCX\xd2\x05i\x89\xd9F\xa0\x18\xb2\xb1\xfdW\x02\xfb\xcb\xfc\x02^\xd3\xb1\xe2\x01\xb6s\xb0\xac\x83\xf9\xb4\\\xf8\x03\x1a]_x\xb5\x14\xe4\xa5/\xdb\xee\x0f\xfa\xda-\xf0\xa6\xc8j\xb3f\xb7T\xa5\x8e\xd6<\xe3\xb4\x95\x82\x8d'\xd0\xc9\xc1a\x90J\x17@\x1e=\"t8\xcc/\x88t\x01\xadn\xec\xd3\x06\x9a\xef\xbe\xfdP\xca\xfc!\x92\xf8:x\xb8\x80\x1ch\x94,H\xc6\x9b\x11\xb9\xff\xc7\xfd\x04\xe7\xfd\x04\xef\xa3\x1d\xba6\x8a\xcb-\xdb\x87\xe2\xfd\x04\xb7\x91\x9a\x0f\x1e\xb6.\x8d,\xaf\x8f\xc5\x07\x95s\xf1\xd4\x11=\xceZ\xf37\xde\x14\xcc}\xce\x0fP\x13\x12\xd5\xaaE\x9dH#\x19*\xe8\x90R\x971\\\xdb\x0d(\xeb\\O\xc9\x7f>^\xba\x82%o\xd51>\xb9$\xf4\x82\xf8m^]\x88\xa1Is\x1f._\xa5]._\x99_\xdc\xc1\xbb\x0b9\xe8\xe1\x858i\xa9\xf9\xe9\xcdM\xd7\xfb\\\x9aN\xe0j*\xda\x0c\xa4\xcd\xd2b\xbe\xd0\xd3\x11\xe1f\xf1\x15\x97\xca\x01rSYzu\xa2\x03K\xc9\x1d\xf5\xa8\x8b\x19DY\x8c\xaaQ\xac\x8eP\x1eV\x96\xf3CMw\xb4\xc1\xfb\x85\xec\xef\xf2an\"\xeem\xe3\xdc6\x86\x1f\x8d\x88\x1d\x8e\xb0r\xfe\xf4\xb9#\xc0J\xd4?\xff\xb4\x92L\x1b\xe2\xae\x08vgbc<\x9d\xba#wD\xec\x16\xa7\x1as\x9d\xbbs\xb1\xd4\xa3\x89\xcd\xf4\xd4\x9diE\xbd\x1b\xe1{7&\x8a\xcb\xd3\x86`!k\x16\x98\x1c\xcf\xdd9\xfc\xc8\xd6\xf1\xc2\x9d#\xa4\xdc\xc4\x1ay\xda\x10Q\x86\x85\xc9\x8e\xa6\xbe\xad\xe93w\xb64[\x99\x1c\x9f7\xe5Ht\x8egg\xee\x1c\x81\x1f\xd9^?k\x18h{\x95\xc4\xac-\xcc\xdd0\xe0\xc5\x8b'&k\xc3\xb0S\x1d\x1e\xc8dk \xd1\"\xa8 \xe4\xf2\xaca\\Y$|qo2}\xd6%0J\xf6Q\x02\xa3\xe4^\x90\x9c\x81Q\xa8 \x8cB10JE\x11\x0c\xd9\xf7\x18\x81\x99}\xebG7\x8a@\x17\x16i\x1d\xea\xb4n\xe9\xb3\xb7\x81t\x91\xd8\xb7E\xcc\xd5\xbc\xc3\x1c\xc6\xabb\xbe9z\xf9J\x8d\xa1\xafXI\xf1\xf8f\xd63\xf1hU\x89\xb9\x0d\xa6\xdb\x1b\x15\xe3\xed\xf6\xc0H\x0bM\x9c\xd6T\xd0\xde\xd2\xd6 \xcc\x11\xce\xac7\x98\x9f-]\xe6:Y\xc5\xe7\xf5kE*[=\x86C\x9fG\xc6KLa\xd4KQ]j\x88\x02\x8ez\x8d\x8e\xac\xf6\x15u\xafI\x9c:4y([y\xd4\xdb\xb1\x7ff\xa2\xef\xc3\xe5\x97\xb3\x01\xe6W\xe8R\xd1o\xb9MP1l\x03b\x8f \x97$\xbe \xa2Mx\xe2s\x01\"\xcbI\xc1g\x08\x04\xe2\xd2\xa0\xfc\xa0@\x19!\x10\xce3\x86$N\xf1\xdeb={)w>\x17\xefG\xa5\xe90\x1b\xfd\x8e\xfe\xdb\x0fNIy\n\xf2!G\xf7\xf40\x98\x97\xc4o\xd6\nF8x\x91q1s\x02\xc3\xc9\xe7\x11\x8e\xd3t0\xc0}\x84{W\xd6\x18\xe8\x187z\xaa\xf5\x97`\xef\xd4z\xbb\x9dM\x12\x16\xad\xfdh\x8b7\x04S\xee\xcd\xf5H/\x1b\x06\x95\xe0d\xe8R\xa0\xf7P\xe4\xe1;L\xe8\x0f\x9aF\xff\xd8\x802\xcdaO\x1ct\xc7\xeap\xfcF\xa7\xdc\xd9\xaf\xc8\xb1bB\x9dd\xf1:\xc2\xa4\xb7\xbe\xf0v\xc4mw\xed\xd1\x94\x91\xe9\xd9\xcc\xfd\xe1\xf3\xf3\xa6\x0f/\x1a>m\x1a\xad\xa7\x9f65\xdf4(\xd3\xf3\xc6\x91o\x82\xebE\xd38>w\x8c\n)\x98\xd29vbk\xb6\xa1Y \xda\xcb5\xf9S\xeap\x94\xd5H\xec\"\xcb.\x80\x1c\x192\x06T\x89\xd7]7G\x83\xc1\xc5@\xd1&'G\x8e\xf4e\nE\x82\xd4\xb6L\xe8\xbb\xe2UJ\xa3\xad\xf4!\xa3Z\x87\x83Q\xce\x82\xca\xf6\xe2\x1f \xe2w\x1e\x8b\xaa2\xc8\xc9;\xa7\x0d\x17E\xe2v[?=\xbc\xd8\xff\x82\xf1\x81\xd1#\xe1h\x8f\xc8\x89p;\x9a\x85\xd3\xcb\xb3\xd2\xf5TSYyV\x9c\x88ck\x98\x1e\xacA\xbb(9\xa0\xc6\xb0\xf4\x19U^>\x9eS\x12\x7f<>\xac\xb9\xb0~\xd4\x1c\xcd\xfb\x9d\xd4\x189\"\x15\xab\xc9\xedE\xce\x14+\x1e\x92iC\xe8\xd9\xe2\xefC4\x1d\xec\x90\xfe\x9d\xe4[\xe1\x1d\xe5kh\xabE O\xdaw\xbd\xc5\xdf{\xf70\xd7Xzi|\n1SG\x87\x81\xd7\x80\xa7\xf1F\x1c\x02\xbc\x03\xd0N\xa3\x11\x0d\xeb\xc1\x13\xb7C0\x1ch\xdfiv\x17\x0f\x87\xe8\x19\x9a\x93\x96;\xdf\xb1\xa2rq\xe3\xfd\x1b$U\xf1\xc7RF\xd8\xa5\xc5\xb59\xb8\x0e\x9c\xa2\xc0<\x7f\xfe\x02\xfdP\x13\xbd\x19;+\xf4\xaa\xb7X\x9c,z\xbf\xfe\xe4\x9f\x1e=\xee\x0f\x9e\x0cG\x93\xd3\xd9\xc5\xe5\xd5\xcb\xeb\xdf\xcc\x97o\xde\xfe\xf9g\xf9\xfe?\x8f{f\xe3\xd2\x1bt\xbboQ6\xb4Z\x92\xabb$\xa9\xca\xe5\x8b.d\xd5\xd2\xd4\x96\xad\x8a\x92\x9bk\xa4\xf3\xf3\x06\xbf\x8b\x07(\xeep\x18\xe3\xc5\xdf:j\xf9\x8d\x8e1\xf1\xb6\xf0\xf9\xf3\x17\n)\xcc]\xb0(\xbf\x88\xd0\xc4\xc8\x8c\x8fg\x85\x10\xc3+r>r2w\xcd?\xb4\xc3J7\xca\xebM\x15\xf8\xf4\xea\xb6B\xbb\x90\x96N+\x14\xa2\xf2 \xb6\xf9\xc7/\n\xf3k]\x1c\xb6\xb1_5\xbf5\x0fuo\xb1\xe8\x99aV\x1b\xc1\x8f\xb3\xea\x8eE\xe4\xd29F\xb3\xa0\xa0c\x89\x1c\xe3*\xc8\xee \xb3\x11\x01\x0f=\xbc\xb4\xa1\xcc\x0c\xb5\xfa\xfcE\x93+\xa1\x8b\x81*\xe8\"w\xa4,rE\xe8\x12\xc3\xd7\xc1_\xb3\x0b\xb0\x84\xac\xdc\xa7)D \x81\x93\xbf\xe6\x8d,\x85sx\xb8\xceH\x0fAIU=\xd4\x85>>\\\xc0\x19+\xa8\xae\xf2\x00\xb6\xe5\xc5\xd7\x85_4\x84\xed!\xa4\xd9i\x85_\x08\x93?'\x8bh9\x04\x93]\xd2k7Q1\x91|\x9a,S\x0e1\xa6\\\xde\xa5\xb5u\xd2uU\xc4E\xca\x93G\xfd\xfd;Z\x1cJ\xb2\xadu>m\x91\xb1\xcf\x1b\xd6N\xdaN\xf2\xdb\xed\xd7R\xf4^\x06w\x91[\xb257\xfe\xcb9\"\xf3u \xce\x94\xbc$g\x18\\\xa0\xda6\xd8.\xcf\xc0)\x96\xd3\xa7\xb9\x82\xee|0\x02\x03\xca\xab\x83\xd7\xdcL\xaef\x9f\xe7~\xee\xed\x8c*\x9c\xd3|\xab\xb9\x00\xd0\x01\xaeC`\x9ec\xdc0\xb8\x99n\xda\xaa\x81\xcc\x15!\xa8\x05\x0d\xf3\xd1\xa74T\x93\xc7O\xb2\x08\xce\xc9\x98\xa4\xa3FF\xacWt:\"\x1c\x0f\x89\x1c@\x9a%\x97\xe2A~\x8c\x8e\xe4u\x0b\x10>.k\xf4v\xdd\xd8\x19TC\xb6\xf6\xd7\xb6\x80\xceH\x9c\xf7\x161\x0f\xda\x0dY[Xj\x96\n\\\xd2T\xc3\xea@\x11\x9b\x01\xd1\xc4\x82b\xef?\x9a\x8d\x17\xbc\xd8P\xa8\xd7$\x1e\x8f\xc9\xcc:\xc1/|\x84\xe7\x18\x1d6]\x82\xa7\xe7&\xa1%\xfa\xc0\x18J\x04wSxjou\xe6}\xd6\xc1\xd4;\"\xd7zF1\x06\xaa\xd6%T\xe6\xd8\xa2K\xbb\x15\nk6 m3\x8c{\xef\xf6\x98\xd6\xb6\xcb*\xb4\xf8@\xc3\x97\x02\xef\xb0\xdd\xd7\xd6qv02P\xa2\x90Y\x01\xe7A\xad\xfco\x963h\xdf\xfd\xff*\x8c\xa1\xb1\xed\x7f\x13|\xe1\xd9\xd3\x0elAg\xfa[p\x85g\x0d\xee0\xdb\x98\xc2\xc9\x95\xae\xe7\xef\x8e-4\xf5&\xe7\n\xad9\x8e`\n\x1a\x0b\x1f\xce\x13t\x05\xff` \x9dX\x82\x1f\xa5\x7fc\x96\xa0Z\xfc\x07K\xa8\xfcZX\xc2\x8b\x06w\xc3\x7f\x0b\x96\xd0\xd8\xf6\xbf \x96\xa0\xdd\x9e\xb5\xb3\x04\x9d\xe9o\xc1\x12tS\xffNXBSor\x96\xd0\x9a\xe3\x08\x96\xf0b\xfa\x81,AW\xf0\x0f\x96\xd0\x89%\x84\x94\xdf\xfc\x8dy\x024\xf9o\x8c)\xd8\xe46\xd3 \xb3f\x89\x0d\x00\xc50\x00\x14\xa8\xfaT\xea\x8b\xe76\xf5\xf33\x9b\x8a\x9e\xe9X\xd53\xdd\xd1Q\xb9\n\xfeR\xeb\x03\x9b\xa1-}-=mH\x0fZY\x98\xe7Z\xc6\xc2u4\x85\x97\x0c\x1a\xc8\xbb\xc8\xc9;\xeaZ\x03\x18\x89j6\x8a\xa1\x95=\x97\xaaU\x0f:\xdc\x16\x81\xd2`5\x0f\xf7\x9a\xfa\xa8\x10\x1e\xeb\xab\xa7\xcf\xc85\x8c\x02\xf4x\xaa\xf0\xe3i!\x9a\x1f\xb6\xee\x80\x91\x16U\x10H%bt;o\xda\xd1\xd5D\x85\x1c\x91u\xe1\x0c9>G\xa7\xb0\x1e\xc0\xc7\xfb\xda[\xad\xad\x80\xf7\xe3\xdc\x15\xf3\xc9t\xa0\xd0\xbc\xbe|<\x1a\xc1J\x9d\x91\xcc1!4\xc25\xe5t\x07\xbff\x81\x1f\xa63\xe27\x10\x97\x07\xd8Z\xe4RO\xf5\xdap+\xe2l\x9a\x0f\xce\x12\x17Nm\x06uF\xa9C*&\xb0\x01\xc0\xb1O>@\\\xfb\xbb\xdcW>z\x84\xfd\xd3s\xa4\xbax]7\xb7\xb0\x01\x05\x90\xad\xa3C\xea\xd3\xfe\x1b9\x7f\xb3X,\x07\xfd\xc5b\xb1\x18\x00\x83>9\xcc\xf9U\xb6(?K\xd5\xb1\xf8\x80\xcc\x18s\x08\xe3\xdc\xd4\xde\x07}p\xfc\xe1\xc0O\x9du\xe0\x87+2_\x0e\xcc\xee\xac\xfe\xbd\xe0V\xd4E\x0e\xe2\xc3\xe8Xv\x0cR\xa7\xcb\xeb\x87\x84\x8d\xac\xac\x1b\xdc=\xd6\x1c\xa1\xba\x17S\xbd\x93s\x7f\xa9\x06\xaf\xde\x03\xa8p\x96W\x9d&\xb8\x9d\xa9H\xfe\x95%ZXCqm\x07\x90\xd9\x08x\x1fc1\x1d\xbbhJa/\x9b\x17M\xcbU\x1d\xc5\xba\x9e\x92\x97\x07\x8c\\N\x1c\xf8ZM\x83 \xd6\xad\xb54EGo\xb9\x16\xd4\xa60\xc8~9K#k\xa7\x93\xe5v:\xf4\x82\xf0\xe3\xa3\xa3\xf3\xc3\x81\xd7\xa6\x0d\x02}\x87\xa2M\x81\xd5y\xf7\xc0\xeahG\x04\xfd\xd4\xe4\x8e\xab\xe1B\xd7\x8a}\xae\x96cT\x11k2\xe3\x05\x10\x05#-\x12\xe1\x1c5\xc65\x8f\x96\xcd\xe4\xaf\x1bMk\xaf\xfc\x12D9\xad\xaah%|\x0e\x82\x11\xbb \x86\x8e\x98\x1e\xb9\xb4\x08Y$f\xe4\xacN8\xda`\x84\xa8\xcd3\xe2\x82\xb1\x94\xb1\x99~\xcf\xe3\xe5\x04\xdan\xec\x08~\xd6\xd2\xc7\x87R\xf2\xd8\xc1\x80\xb3\xd57\x0f\xa0\xf1\x05\"\xcaK\x04\x94~\xc4\xc0\xe4\x05Y\xe4\xecY\xd5u\x99\xd1\x99|\xe6\xd0\x99\x14\xe2\x8a\x9e\x8d?\x9f\x9c\x80\xf2\xf4\xc9pqzum\x15\xa6\xc3\xdf\xe49\x96\xfd\xebY\xfe6^\xfe|6z1}_\xf8>\xb8\xee_\xcf\x16\x93\xa3J\x0c\x9e\x0c^\x9e\xd6\xf56\x05\xd8&\x8b\xf1\xf2\xe7\xe9\xe8\xfc\xf9\xfb\xc1\xac?\x7fs\xf9rqwv6^\xdc\x9d\x9f-U\xd9\x87\xf3\x91\x92n\xa7U\xc2z\xd1\xa8}\xd0\xd4\xa3_\xa5\x16\x9b\xa2\x13\xaa\x97\xbd\x82(\x04\xaa\x90H\xab\x0f)\xb8\xab?\xe9s\x9b9\xab\xc5\xa1,\x94U\xbb\xa1l~\xb6\xd4\x8dL\xf5\xd5~\x0f\xac\x08\x02\xb5\xe7:\xb1\x02C\xd1/W?(\x8ba\x1dd\xef\xd6\xfd\xc3\xc1]Be\x1d\x1c^\x96\x02|\xe69(\x8e\xd6[\xba\xc2S\xb2\xaa\xe3\xc3\xa3[\xed\xb2\xcb8\xb0\xb2\x87zF\xf2[\x98\x03E\xedN04i\x94\x874\xb5\x13\x986M`/\xa4~ b \x87m\x93\xe9\xfdc2K\xbf\x8f:\x99iu2?\x0e\x91.\xd2\xa6y\xcf\x8b1N\xe7:\xf6\xeb\x8e\xe8(\xa5\xfa\x0fD\xe6\xa4\xab\x18CwR\x0f\x0b\x99?>\x04\xd6\xf48\xfe\x05\xb7u\xf0\x17#\x94\xfa\x18\xffs\x0d>\x1d\xads\xbb\x8d\x80\xb2[\x16\xc3\x1f\xfdo\xb2\xd3\xd1E\x9f\x9ec\x04R\x81\xd9\xd4_(\xee\xd3;\xf8\xa3\x9b\xf6C\xfcW\xbfE\x1b\xa8\xc7O\xf0\x95\xfb\xa9\xf9;Y1f\x13'w\x89W|\xces\x05\xb7\xef\xd4s\xb0\xc6\nq\x19\xc0\x13\xf6-Lyb\xfeB\xa9P\xfc\x84 Y\xa2V\x85z\x8c\xd8-|\x8a6\xf8\xc7\xc7\x7f!\x16i\x14a\x7f\xe2\x84\xfe\x94\xb1 \xf6n`+\xa4\x92\x92\xd8DD\x85b\\\xa4\xf0\x9e2\xbe\xf7=\x86\x8fij\xe2\xa1\x9a\x81I}\xb6\xc7\x8f\xbe~G\xb8\xd2\x10\xffD!&\xc74\xb1C`_ \x0b\xfa\x84\xec p\xca\xa9\xfeD\x188V\xe8\x19\x12;?\x0dY\x9a\x82\x06\x8a\xf4D\xf4\xf4\xfc\xd33x\xc2\x16\x05\xccr\xc6\x01\xae=\x0bC\xe8/\x0e\xc1-\x86t\xbd\xf3\x10j\xf5w\x9c\xa5L#\xca]\x18\xf0\xc4\xb3`\x15^\xb1T\x88\xd3\xf8\xee\xe9\xe7\x93\xe7g<\x7fDd\\\xfbYx'8b\xe8&\xc1?\xf8 \xb1\x82j$\x16\x82z\xbb\x90E\xf8v\xab\xfe]\xb1tG1\xf4\xec\xca\x17^\xeccX\xde8\x80\xb9\xf6h\xa0g\xdd\xdb\xf1\x18\x83\xda\xe2\xd3\x98\xdd \x16\xa566o8f{\x16\x89\x15\xf7\x05\x1bS!X\xb4f\x98\x1d \x0c<\xee\x01\xa8u\x10\xd1q\x12\xd0\xfb\xd4\x8f\xb6\xda\xbf\xa3IR\xb9\xa9\x1f!\xea\xaf\x05T\xbe\xde\xaf\xd4\x1f\xb6>\xbfQ\x7f7\xd4c\xc2GX6\xcc\x84\xf9\x8d\xb6:\x84\xaf\x9f\x02zma*\xb7\xbe\xc0?\xef\xc28\xe1\xb1 \xc0\xbb\x154\x80\xbav\x1e\xae\x04=+~\x82\x7f\xb8^\x13\xde\x0b\xfd\x17\x97\x85@L\xfa\x91BK?\xe2\xdb\x0d\xbbO(\x16\x08h*60\xe0j\xd5\xe0\xa2\xa0[\x8dD\xa1M\xe17:%G\xa5\x10\xeb\n\xd3\xf1\x8e\x05zYE8wa\x16\xea8\xbf\xe1\x1e\xa0\x03\x19[=\xc4\x88; \x0dB\xfc\x9bPN\xdf\xbd\x03\xa4K\x02*L4\xe3\x84\xc7w\x10\x1f8I\xef\x01\xce\x9f2\xc6!\xc1,0\x96\xc6\x19\xc7\x95\xc5\x11iyz\x1fA^.\xf4\xb2a^\x1c\xad\x03\x7f\x83KL\xaf\x88t\x8bk\xf0\xe6>\xc1\xf4\x10\xa6*\x8d\x835\xc5\xc0\xc5I,\xfc\x0d4\x96\xe2\xc4\xa4\x82Q\x00+\xc5\xee\xa8\xd74\x01\xc7)\xb0\xc2\xa2-\xc0\x94\xad\xa1\x81,\xe2\x8c\xc2r\xcc\xc4\xf9\xd9\x19DaVx\xc6}D\xd0\xbd\xcfn\xc79\xf4\xb7l\xe5a\xf6[Aq\xf5\xdd{\xfe\xed= \xc3\xdd\xc6GD\xbf\xe3\xf0\xe9>L\xb7\xbc\xb7|8\xff( \xf9\x9f\x0e&\xbf\x7f\xfd\xea\xdb\xb7\xaf\xbf\xf8\xe7\xb7\xdf\x7f\xf5p\x01\xb8\xa2Eq+\x17+A\xf8I~CE+^\xc8Ic0}\n\xc7\x1aE3\x05\x14\x97\x9f\xea;\x8dN\x97\x0e\x06\x17\xa7\x15\x8d\\\x8a\xe5@u\x04\x98\xac3?\x9d\xbeW\x99\x1f\xce*\x8b\x97v\x1c\x04\xab\xc0\x0f\xeb\xfa\xf8\xa7\x9f\xb9\xb9\xa3w(Z8\xde8\xdd\xb8/\xa9<}\xee\xd6Iy\x9a}\xbai\xa6\xbf1f(9\x93\xf1\x0c'+\x1cI\xa0rA\xf1\xe7\xde\x1dF\xaa \xe6\xd3\xa5b %\xdd\x14\xb9&\xa0\xa1\xf8&\x12}\x95\xc1\xe85\x06#2}\x01\x01\xd6\x8b_Gd\x8aa\xb6\n\x97\x81\xfc~\xa4j\xa1}\xa0\xcc\xb4\xff\xe2\xf9\xf3\xa7OK;\xf2\xa0\xcc\xb6\xea\xc4\x1am6\xc0p\xa8\xb1k)2\xe9X\xf1\x01\x05J\xb5\xa7%\x98\xf8\\eY\xb6\x00\xe1\x14\x95\\\x0e\xec\x1e\xfd\xc2\xfe\xeb\xca\xb3\xac\x05\xb5\x99c\xf2\x95\xe0\xe1\xf6[v\xa7>\xfd1k\x88\xca\x01\x07*iC\xc4\x0e\x1am\xbf\xe3l\xe3\xdf\xcd\xd4\x8e$\xdaft\xcb\xc6.\xed\x8b\x1f\xdd\xf8\x9b\xfb\xc6\xf8*7\xaf)\xdf21sJ\x03\xe2>\x89!\xa8\x08\xe3\xee\n\x809\xa63\xd2\xfb\xeb_\xfe\xcf\xbf\xfe\xe5\xff\xfa\xeb_\xfe\x8f\xbf\xfe\xe5\xbf\xb8\xd4]\xfev\x17`\xfc\x91(\x0b\x1cJ\xa8\xfc\x8clF\xce\xab\xa7\x1c\xa5W/\x0e\x938b\x91p\x8e\xb5\x17s\xe6JW?\x9e\x05\x10\x8a\xa5\x07\x9e\xe4z\xa3<\xea\x8b\xda\x1c\x19+\x19|\x03\xc9E1\"x\xd7\x83\x88{\x1f\xca\x05v\xbb^\x8e\xaeV\xfc\\=\xd8\xa3\x0eA\xfd\xa0\xe7\x08\x83\xe8\x98mto\xd7\x05th\xbe72\xce\xf7\xd4\x06\xd9@`\x1aV\xcf;F\xd7\xc8 {;T2\x890\xb0}\x0f\n\x9fu\x90\xbeB\xd0\xa6\x91\x8e\xa5\xdb\x0dv\x1c\xc7\x83\xc0\x17\x02w\x94b\xa7\xe8\x00)\xc5\x00&y\\\x8e<\x14K5FH!\xc2\x87\x0dHR\x08\xef\x82\xbaP\x07\xfc\xbfr\xbf\xfd\x83,\x14?\xfe\xbb$\x0b-\xcb\xae\x0d\xab\xff\xce0\xc6q\x1d\xbe\x801\x8e\xaf\xff\xc0\x18\xf8=\x04cj\xe9\xe4(F\x82\x0c\xa1\x13\x0d\xfd8\xf4\xffCh~'0?\x94\xd4\x1f\xa2\xf1\xff\n4\x1d\xb6]\xf9\xd2\xe4\xc5}IU\x98w\xaffS\x0b\x83#&jf\x1e\xfez<\x8e\xeeQ?\xbf^s\x86\x07\x04\x943\xcc\xc5\x85\xef\xa1\xde\x97\xa6>N&\xcd\xd6>h=A\xc9\xbaZ\xfb\xf8\x07\x93|\x18\x99\x95\x1d\xda\x12:\xac\xe25\x8c&\xb6\xbc\xca\x84\xd0z{\x1a\xed\xf1D\xcb\xa3\x890\xca|\x16 T\xa6{~\x19\x9b\xbc8\xd0\x7f\xb6<\xce\xf0\xc4+W\xef\xe7\xa7]\x82\x1a\x1cZ\xe39\x18\xf3bNE\x8cZ}d\xe9k\xa6$ d\xf2\x1b\xd4\xf3\xfb\xf8\xdd\xc7\xc32\xcc\x05\xb5\xb0\x80\x99S\x0b\x06\x03\xb6\xf1Y\xb0N\x99\x8e\x11\xb5-\x00\xbf\xf1\xb7\x19\xd72\x01\x96P\xb2\x81>\x1b\xd0\n\xf1\xdd\x14\xfe\x05yl\x87\x87k\xa0X\xde=\x87\x7fA\xe9\xaf\xd6\x83\xf9\xab\x0f\xe2l\x9f\xf3\xf5\xa3\xfe\xc2,\xf8!\x0c\xbf\x1f%x.\x88a\xdbz7+\xa8\x04\xacw\xe0\x81mY\x84IP,\xa4x\xde\x12\x9aC6\x08\xe5\xa6\xfe\xfe\x94\xe1\xf1I\xc8\xa2\xcc\xfc\xf5\x05\xf6>d\xbaC\x11\x9e+F1\xce+\xceN\x9c\x08\x0bil\xc7%\xce\x84\x06\xcd\x9c\xad\xe1\x9fxk0\xef'\xf5\x0f\x9e\xe9q\xc8\xc8\xb3\x15\n\xb6\xf0\x0f\xb5\xe7\x00\xa6\xca\x94\x05\xfa<%\xdd\xd1u\x0c\xc7IiH\x03\x80\"\xd7\xc9\xa7 \xf5\x10\xdc4\xa1XPp\xff\x86\xe9\xa7\x18\x89N*\xee\x11\xdb1\x08]/\xcd\xc2\x90\xe2)\x05\x06\x9d\xd3R\xa7z0\xd8,`$\x05\x0b\x93@\x1f8*\"`V\x90P\x13\x0f\x0f(\xb4\x9a\x195gG\x82\xe3\xbf\x14)\xa0\x80\xbc0\xd6\x19\xf4`\x8f\xc7<{\x7f\x8d\x07\xb3\xb7+\xdes\x04\x8a\x03\xa3\xb0^\xba\x87^\xe0\xd2\x0d\xc46\xb8GQ\xd9<\xafQ.5\xaff&i\xe4\x87T0/\x0epm\xe8\xf706c\xac\x13\x04\xa7Qj\xd0\xd7\x92\x81\xc2\xea\xf5\xb9&\x16^\xe0' \xc5.\xaf\xd9F\x0b\xd1)\x9c\xe5\xb0 \xf0\x93\x14\x17\x87\x1f\xd8E\x81\xcb\x04\xcf\xcb\x0c\xdc\xf0`\x84\xe9\x1b\x86G\x9a\xda\xf6\x1e\xe8\xaf\xfdK\xf9\x96\xd3\xb5\xaf\x97'\x9cnq|J\x11\x97\x99\xa0\x862\x84\x06\xb2\xc2_\xa1+O\xe2\xe0~\x1b\xdbG\xcb5\xe9\xda\xa7A\xb1 n\x90N\xe01q\x8e9\x10\x01\n\x9e\xee\xc3U\xac\x0fq\xef\x84\xf9k\x1a\x05\xabzx\xd0\x1d\x14\x061\xed\\\xef}\x06\xe8\xbc\x87\xae;f=\x82Y\xdf\xb0\xdf\x06z=o\xd8\x97j\x12_Q\xc1\xfd;\x93\xa0\xc5\x88\xd70{z\xb819\xd5\x94U\xbdF\xfb8\xd8\xb3b\xc9\xdf\xf9\x9bM\x96\xb2o\x958\xa3\x99\xb2JL\xed\xde\xf3\x15\xd2\x0bH\x144\x12\x90\x13S\xbe\x0e\xe2XC\xf4u\x16y_\xe4\x8f\xbf\xcd\x1f\xff9\x7f\xfc\x1e\x1f\xff\x99fi\xea\xd3\xe8\xb7A\xa6\xe1|\xc5\xf8\x96\x15\x1e\xff`E\x8aW1Ovq\x10o\xef\xf1\xfd\x8f\x9b\x8d\xa1\xc5\xa87,\x80\xf3C\xc2\xbc,\xa0\xbc\xdc\x97\x1f\x92\xb8\x98\xe9\xb5\xb1\x84`\xaf3\xbe\xca\x02%\xb4\xb8F\x1d\"r\xf4B=\x8f!\x8b\xb4e\x89z\xe6\x1c\x97P\x08\"\x0f\x9a(l8\x05\xc4\x0f-^\xe3\xe9f\x08\x04\x99\xad\x91\x04\x84a\x16\xf8h\xea\x81\xa7\xb0H\x92\xd1\xd8!\xdektN\xe8z\xad\xabMv4\x121\x92b\xae\x89L\xc8\x91\x00\xea\x83\xdc\x04\xa8\x1e&\xfc\x84\xe44\xbc\xb7\x98\x1aj\"\x17j\xd2\xa6\xde\xcd\xa3%s!\x92\xb7\xd0\xa0p\xa8\xa1\xcd\"\xcd\x90\xf0 \x00t\x8cU\x0cc\xf5k\x14\x8b\x1c\xd2\x1a\n$\x9e\xc7\xb4m\x80%\xeb4\xf0\xb7\xfa\x01\xbfd\"V\x12q\xc0\xb4,A\xbd\x1b\xc5`\x10\xefW[K\xbcV1\xd7\x90y,\x08\xd4x\xe9\xf9V\xafj<\xcc\xeb\x8ey78\x94V\xc0\x08(2!/`Hvm\xad^\x8cB\x82\xfa\xab\x97\xa9\x17\xc7|\x8d\x89\x9a:A3\x8a!\x8cW4e\x86g\xd2\xd436>\xe6L\xcf \x84M00\xd3w~\x98!`\xaa\x8a\x8d\x9a \x16y\xf7&A\xd59Nw\xfe\x06\xea[1\xbd\xd2V>\n\x1e(!\x16\x96/ZB\xa9\xbfc\xc3o\xe1E\xed\xffz\x95u\x1d\xf3\xb1Z <\x89\x03j7\x1f\xf5\xe41\n+i\xfe9\xe1\xb11\x9e\xc3\x04\xce\x14)4\xf4\x05f\x07\xbb\x80\x8b\x1d\x12Pf\\#k\xf5\xe2\x08\x18'&\xf1\\\xa8]\x03\x97\xd5Y\xf7~\xaa\xf7,\xc8\x14\xd9z\xcbB\xcd\x06Y\xc0\xf6\x16j#\x04\xf8(\xfc\xaa\xbf\xe3XQ<\\\xf9\xf0nF\xa0 z)V=\xb6#\x82\xaf\xc5bq$\xc6\x1b\x1a\xfaA\xfejP\xdb\xbe\x8c\xe9\xfa\xc7,\x15y\x9a\xe0L\x8bA\xfa]c1\xbc\xed)\xf7i\x94\xe7\xbe\xb5h\xb6A\xd9\x03Z\xda\xc2\x06i\x0b\x1b$`\x9dc\x83?E\xb9\xd0\x08eY\xe4#\xe34 %i\xb5@8u9M\x1a\x950Y\x9e8D-?\x82va\x99\xdf\x00 7\x98\x00;\xb5\x1b\xd8\xa9)\xb1L\x17\xbaa\xf7\x89\x929R\xfd\x92&\x10X]\xbf)n\x00\xcf\x96\xd4\x02%\xcd\xc7,`\x8a\xd6\x8d\x0b\xecI\xd5\xcd\x82\xd0\x8ac\xf8\xae:\x99S\xe1@K3\xf9\xe4\x05\xb16P\x1c\xb3\x84\xef\xbc\x1d\x8d\"\x16\xa0\x00\x84=\xbdw\xa4Asw\xd0\x8f;\xe8\x07\xca\x1f*7\xfc\x03_\xee\xe1\x0b\x18|\xbf\x8b\xe3\x90Fk%09d\x94\xac \xa3\xf4P8\x81U\xaa\x97\xb4\x15{Vl\xcf\x02-k\xdbM\x9a\x17\x07Y\x18\xa56\x13\xbe[r\xad?kQm\xcd\xa28\xb4Y\xd7,\xd1:\x0d+\xcb\xe7l\x1a\x1es>\x07\xbbG\xf5\xc05ykbA\x81\xc2\x1f-q\x17H{\xc4\xc4\xce\xf7n\"\xad\x17\x0b\xecV.\xb0\xfaT\xb5\x05-\xef\x83T\x8a]g\xea\xc50j\xf5\\\xe0\xba!\xbd\xb3_\xfc\xc8>\xc6{\xb55\x81U\x03\x8dFqNL\xa3,\x1f\x07#\xad\xf3\xf8\xd6\xa6\xf1\xf8\xd6\x8e!\n\xcc\x06w\n\xe23\xb7\xbd\xe0\xb6\x17\xb8\xe7\x05\x03\xc5\xfc\xb5\x00\x95\xde\x13\xfb\xef\x98\xde[\xf8Z\x8f\x07\xe8e\xb5\x80 \xb5L\xc2\xbeh\xe2\x03\xa2\x88V\xe2\xe9 \xffV\x96L\xb3\xa4\x9ar\x1f\x86Lp\x1f\xe4\xf1}N}\x0e\x8b\xcex\x83\xe3.\xf0\xa3\x9b\x99\x99\xe3\xbb0\x98i\xebzH\xb7\xe2\xba\xfa`G\x03\xaa\x9cA\x8e\xde\xb2`?I\x8a&\x8f\x81\xd3\n\x89T#7\x9b\xab\x9d\x17$\x1a\x8f/\x06\xa8\xe8\x8c\xb6=ru\x05\xa6\xa6\xf1\x86\x88\xb9\xb9}:\x87[\x98\xeaO\xe5f\xd9\x88\xb0\xb9J^6x\xdf2\xa6\x9b\x95\x83\x0d7\xe4^\xbb-\xae\xebp\x93h\xf5\x16^\xa6\xad\xb7\xaf\xbdc\xfb\x11a\x03\xf2\xc7\xd5\x8f\xcc\x13\x85\xf0\xf2;\x9a\xfe\xf16\xfa\x8e+\xd1A\xdcO<\x1a\xc0\xe0i\xcf\xd1\xba\xd7l\x1e-\x1d\x9eT\x8c\xc9N\xc3\x91\x0d\xd1\x80o\xc0\xbb\xdc\xcf\x8b\x9f\xe7\x8bt\xf1\xc3\xf2\x89\xd4\x7f\x17\xef\x17\xefO\xb7a\xbdG\x89*p\xf9O\x95\xec\xff\xf4\xd2\x99y\x0d\xd6jk*\xe8x\xbe\x18/n'\x8b\xec\xec\xec\xb7\x9f\x8e\x17\xd9\xd7_\x7f\xfd\xf5\xf2\xd4q\xf2\x08%\xd4\x12\xc7\x12\xcb\xe1'\x8e\\{\xc8\xd5\xbf\x9e\xe1\xff\x1b\xb9\x13\x03\x91\xa4\xd7\x12o\xd6H\xc1\x02\x89\xd7-\xa4\xe7\xaf\xe5]\x98$\x83\x99\x9c\xbf\xa1\xe3wK9\xa7\xe3w\xc3\xc9b\xbc\x1c\xf6\xafg\x90\xa6\xdefK\xf9\xc9`P5\xb7#\xda\xb3\x154\xb6\xb8\x1d\xe2\"\x93`\x829se\xde\xaa\xccs\xd5\xcd\xb3\xb3\xb1\xfas~\xa6\xfe\xfd\xe2l\x91M_|\xa6\xfe\xfd\xec\xec\xabEv\x8e\x9f\xcf\xcf\xce?W\xff>\xdf,\xb2\xa7ggg\xcb\xd3m\xbd\xca{rEz\x06 \x8b\xf8\xff\x03hf\x15.\x18%m\xed\xe3D\xc9\x0f\x8a\x86\x90\xeb\x03\x16\xe5\xa4\x803XC\xdd\xa9\xee{2\xeb^\x0b\x03\xc0\xda\xe1f\x13\x10\xd1x\xa6\x18,\x18\xe1\x15\xbe\x81M\xa1\xee\x86]\x13\xe4:\xef\xec\xac\x05\xd2&\xea\xb3r\xc3\xedoH\xff\x0b%\xb5M\xfc\x14\xfe\xf6Y\xa3\x85\xa1%Sj\xd1\x9f\xe1=z]\xc6\x98\xb0_\x10\x01\x11\xe7\x0d \x13\xc3\xe1\x80Ds\x81\xebU,\xeb\xcb\x95\x14\xdc\xf5\xd5{\xd3\xb4\xba\x11\xe4\x0d\x8f\xc3vG\x80\n\xda\xb7m\x07\xae\x85:{J\x00\xd9\xf8\x11[\x17\xe7\xec\xd6\x8f\xd6\xf1-\xb9\x06{\x002\xd3\xef\xe5&\x9d6\x83v\xe4o\x9d\x8d*\xc8\xbe\"W\x84\xf2m\x06\x86`&\x92\xfcK\x8c\x0d_\xf0B`\xb3\xcc\xcf\x96\xe4\xba\xfc:#o\x9b\x02\x9a\xde\x95\x0c`\x9b&\x95\xe4\x10\xdfV\xc7\xd2\xfc\xde\xbb\xbd5\xdcM\xf6\x8c\xa7\xaa\x8bW\xa47\x9d\x9cM\xd4\xae\xfan\xc2Y\x18\xef\xd9Z\xc7\xbd>\xf9\n\x9ck|5Y\xc7\x1e\x80\xad^?\x87~\xe5i\x93(^\xb3\xd7\xf7 \xb3\xb6\x9bw\x13?\xfd!K\x92\x98\x0b\xa8\xead:\"wu0\xd4(\xfe@\x8aU\xb9\xc7\xe2\xcb\x06\xbf~\xeaw\xd3\xf2\xed\x8b\x0eu\xff\x11\xf2\xfcN\xe7\xf9\x9a\xd3ms\xde\xef \xef\xef_\xbf\xfa\xf6\xb5>p\xfc\nO\xa5\xdd\xd9_C\xf6?\xd4,\xad\xcd\xef\x95\xfd\xfe5\xe8\x83\xdc\xb9\xbe\xc1\\4dk\x95\xf5\x15M\xdc\xf9~\xb4\xfc\x1a(\xd27\xe4\xbaRLM\xddW\x93W\xf1;H\xfcB\x08\xae\x12g\xe4\x1bw}\x7f\x80v_\xb3\xbb\x86\xde}\x0f\xdf\xbfD\x8b|w\x96\xdf\xe1\xd8\xfe\xf1\xd5wp[\xda\x9d\xe9[\xc8\xf4?\xbf\xfa\xf6\xf7B$\xdf\xb3\x9f2\x966T\xf7\xa7r\x0f\xbf\x85\x1e\x96\x0b\x92\x19\xf9\xd6]\xf8'h\x86Ej\xff\xf6\xa7\xef\x1b\xfa\xfcu\xb9\x85\x9f\xa0\x05[\x86\xcc\xc8O\xee\xb5\xe4\xe4\x17\xdf5-Z\x85\xf6\xef\x14\xf5\xfd\xff\xd9\xfb\xda\xae\xb8m%\xe0\xef\xf7W\x0c~zR\xfb\xe05\x90\xa4\xb7\xed\x06\xc2!\xb0ii\x03\xe4\x02i\xdaK\xf3p\xcc\xaev\xd7\xc1k\xed\xe3\x17^z\xcb\x7f\x7f\x8eF\x92-\xdb\x92\xec%iz?\\\x7fHXk$K\xa3\x91\xe6E\xa3\x99`\x9c\x92\x8a\x88\xdc\xea\x18\xdb\x10\xc4\xff\x8f@\x98D\xd8\x16S\xfe\x08\xe8mBRI\xc1(c1\xc27\x94\xdb.\xd5\xc8\x87u\xf0\x15\xeb\xa0\x1eK\xbf\xc0\x0e\xbc\n\xa2\xc5\x92\xf7\x1b\x95\x14=\xe4\x8f\x08\xc9G\xc9\xa8\xf0P\xb0u=\xf4{\x84\x9e\x91\\ ${u\x7f\x1e\xce\x18\xb5\xea\xe1\x7fRZ\xef\xb7\x80\x7f\x83\x1d8c=\xa7in^\x97?\xa3T\xdc\x9e\x82\xe6\xae\xf6Kc\xa7\xffE\xf4\x85m\x10\xeat\xf0\xfdr\xaf\xdc\x88\x8e\xe8Ds\xf7\x8d!\xfd\x07\x8c\x8c\xa6\xed\xd4W\xb0\x03\x86\x95\xffo\xd8\x81\x89\xbe\xe8W\xd8\x81\xb9\xbe\xe8_\x18wM[D\x08\xec\x80F\xa4cON0(\xa0\xb6,aez\xcf;@F\x05;\x10\xbb\xffy\xf0\xe1\xe2\x03\xa3\xceq\x98\xbbW\x188\xeb\xca\xcd\xf1\xdf\x04\xffM\xf1_\xeay\x06\xdeH\xed\xdf\x89\xf4\xdf\x89\xb0\xd5\x10\xff-\xf0\xdf\xcc\xf8\x85\xd0\xfe\x85\xc2^\x9c\x11Cb\"\xc0[\x81\x96\xc21\xb1\xb0\xb3\xa9\xadpi+\x9c\xd8\n\xe7\xb6\xc2\x1b[\xe1\xc2V8\xb3\x15\xde\xdb\n\xafl\x18\xba\xb4\x15\xde\x12\x8bB;R\xc8\xa2r\xa0\x91.A\xd2\xa3\xa0\x8a\xf7PZ\x93T\xef\"\xe1\xe4\xc3\xbdD>\x98d7\xed\x97J\xcf\x12\xe1(V\xb9Gq\xa7\x1aSkg\xb5\xd6\xb8a\xb99}uh\xf8\x98R\xc6*\xb1\x97\x85ZI\xfb)\xa5LVB\xfaw\xde\x9d\x8d.\xdf\x9e\x9e\xbc>|3\x92\x9fz\xf2\x04\xa6\x81\xfa\xde\x17\x9b\x14\x0f\x82'\xfa}\xb9wz\xb8\x87\x0d\xfab\x9b\xaa\x17\x1f\xec\x9d\xcbb\xdc\xa8\xe4\xfbw\xc7?\x1f\x9f\xbc?f\x8d\x9f\x9f\xec\x9f\xbc9C\xa5a\xcb\xe7;\xd648\xdb{=\xba|}rz\xf9\xd3\xbf\xde\x8dN\x7f\x93\xa5\xcbF\xe9\xf9\xe8\xe8\xed\x9b\xbd\xf3QY}\xc2\x01\xde\xffx\xf2ftyp\xb2\xff\xeeht|.\x0b\x17\xbc\xf0tt\xfe\xee\xf4\xf8\xf2\xe0\xe4H\x16\xcc\x9a\x05\x97\xafO\xf7~P\xab\xde\xb7 \x0e\x8f\xde\x9e\x9c\x96\xe57\xbc\xfc\xf5\xc9\xe9\xfe\xe8\xf2\xd5\xc9A\xd9\xe3\xab\x1aR\xce\xf6\x8e\x0f\xcf\x0f\xff\xcd\xbav\xe4\x8b\x8dI\x96\xfd<\x1a\xbd\xbd\xdc?9>\x1f\x1d\x9f\xfb\x9ciV\xc4\xf1\xee\xf4\xf0\xf2t\xf4\xc3\xe8\xd7\xb7\xac\xe1\x9c *0\x0c\x11\x91i\xd5f\xfc\x05\xdfa7=\x9cZ\x0c\xecI\xb4\xbc\x0dy%\xa7OT\xdb\xf8Z\xb8%Uh\x80\xd8M\x88\x0f\x8c\xd7\xc6.%>D<\xb3\x97\x84\xcbnf\nX^\x82\x85\xe5_Y\xab\x02\xd7Z2\xa5^\xd2]\x8f\xed\xb3Gj\x97\xd2\x12\xb2P\xebx\xb8\x9a\x0e\xf8\xa2(\x87\xbe\xb3\xc3\xa4\x88\x12\x11c7!\x1e\xd6b-U\xf0UmF\xad\x08Oy\xed\x88\x94\xbf`\xecRQ\x9b\x12\x15\xbe\xaa\xcd&\n\xc9S6\x13\xbbgD[\xe8!\x01\xf0\x8e\x95.Wr\xee\xb8\x85\x94\x1b\x96RB\xfe \xb8*\xab\xb7\xc2\x82\xca\xcb\xdc\xa9\xe7\xf3\xadu\xaa\xdd\xfd\x0c\xdc\xed\x84\xf46\x18\x94J\xbe)&\x82\xfa\x08\xbf\xeb\xa1\xc6Z%\x9f\x07K\xce\xb1<\xbd\xb7\xf4\x04dv\x08\x92\xa0<.:\xb6?\x8f\xe2\x89\xc9\x9c\x01h\xd1\x1b\x87\xf9x\x8ey8\xbaZ\xa7ENR&\x92c\xe8rs\x93\xab \xfb-\xe9\xba\x9e\xac>\xdd8XiF\xd8S\xfa\xf0\x0c!g\x1a\xd3\x9e\xfc\xcd\xb0\xc8$\xea\xce\x16\xa6)]\x0c\x1bv\xf6\xe6\xf3\xd0c\x06\xac\x94\x06\x9f86\xb3p\xa1>\x9f:\x14\xf3\xc4\x89\xae\x97\xd85\x9a\xd8\xf4\x9d<\xef\xbf&\xa5a\x96K2\xf61\xdbNf\xe4\x13M\xc1\xbd\xe1\x1b\x12\xca\x04\xdb|$/\xb77\xc4\x1f\x0e\xac#7\xb8\xee\x9a\xbfn\xeae\x0f\xfb\xc8k\xdb\x92\x85&\xd1\x98\xd1\x0ej\xb4\x03r\x0b\xef\xcc\xc3dO\x1a\xa4$[\xd2$C\x1b$\x1b\xacT\xb4\x1d\x1f\xd2\x80.I\xe2:?\x8c\xce\x1dq/e\xc86\xe7\x0d\xc6\x18_\x8c\xe7a\x9a\x91|\xa7\xc8\xa7\x83\xef|D\x89/\xd2\x9a\x06\x19I&.#@\x8fGE\xa9>\xf3\x08Jb\xd3\xb1\xef\xf5\xc0%\xfb\x92\xcb\x06}\xe0\xf1\x18\x83\xafS\xba8\xc33D\xb6\xcf8e\xdf\x9d\x9ek\xd3\xdc\xa7\xf2v\xfc\x93'\x90\x97\xc6 !\xa8\xe3\x95y\x9e^\x94uIg\xdap\x1d\xc7\xf3\x82+:\xb9\xf7L[x\xa2\x16L\xa34\x93\xcdc1\x13\xc4k\xdb3\xa3\xc7\xf7\xfc\xbc0G\xe9oW\\\xb1\x81\xa1\xb8\xbf\xe4]l\xb6\xefw\x81\xde\xc8]7\xd70 \xd8v\x8c\x00\xca-\xads\xe2~\xbd\x9d\xdd\xcc^n\xcf\x80\xa2\x8f\xf0\x0e\x06~k\x0f\xd3\xf5\x9c\x97\xdb\x1b\xb3\x97\xdb\x1b\x0c\xfck\x03#$\x01\x86\xdb:\x13.\x19.j\x91\x18\x82\xc9\xbd\xe62\x82\xbe\x9e\x9d\\\xdczW\x97/\xb7Qo{\xb9\x1d-f\x90\xa5\xe3\x1dg{\xa3\xf1\xe6\x0eh\x82^\xf2;aL\xd2\xdc\xdd\xf266\x9c\x97_{\x9e\xa6\x83\xc0\xd4T\xae7\xed\xf3N\xea\x11o'\xb6\x07W36\x86\xe7\xa3\xfe{\xa3 \xd4\x1f\xc5Ir\xc3\xde\xf9\xe7\x9fl\xd1\x12\x1f\x8e\x82\xb3\x1fO\xde_\x8e\xde\x8c\xb8\xac/_\xec\x9f\x1c\xd5_\x9c\x8f~=\xf7\xbb\xa9\xa1\xf1\xf9\xa3\xe0\xf5\xe1\x9b\xf3\xd1\xe9\xe5\xde\xfe\xfe\xe8\xed\xb9y\xf5\xd5s.\xd5\x8b\xb4\xaf\x0fWFE\xa9\xfd\xee4\xb4\xdfs\x8d\xf6{\x8e\xb1l D\xe8U6&t\n\xe70\x14\x07\x9d\xa6\x86\x88\xa6!\xc2\xd5h')\x16W$UM\xdd\xa4<\x02\xe2\xc7\xba-\x9f\x07\x0ep\x1c.\x0c)O\xf5\x88\xf9\xd8\x12\xb3\x1a\x973\x9b\xcf\xcf\x17\x04]+\xd8\xff\xc1\x94\xa6\xa3pN<\x95\x0c\x8eQ\xfdT\xdf\x9cb\xe8/\x8d\xcfJ9\x7f\x86 \xce\x03\xc6\x99\xf6\xab\xe3 \xed\x91H\xaer\x07\xcewJi/S\xfb\xf1\xb1\xb3\x89R&\xb3@f\x8a`\\\x05\x969\xe1\xb9\x1al\xf9\x7f\xa5\xf4Q\x91m\xddA\xa7{J\x8a%M\x1a\x13\xc2\xe7\xa3\x83\xfd\xf3\xf3\x8e!\x18\x8eH\xe4\x13\xc61\xbd%\x93\xf3p\x96\x0d!\xb1\xa9f>\xac%\xe4\"\xfd\x80\x01\xff\xd8\x1f]\x8b\x80\x8d\x80\xab\xb2k#\xach\xc2/ \xa2$#i\xbe7\xf9\x18\x8eI\x923&\xdeG\xc4\x01\\i\xed\xba\xae\xb37\xcdI:Bg:\x06\x90p\xc1\xe0\xb3\xc9\x94\xcd\xf97c\xadk\xff]\x9b\x12\x1eT\xb0%\xd3\xf0\xd7\xca1]\xf9C\x0f\xbb\xb6\xb1\xbd1\x0br\x92\xe5.Q\x97\x10\x97\x0eV\xd2\x9d*M=\x18\xc74\xe1\xaa\xa0m\x03\xaba\x99'9\xa9:P\x06\xe8c\x1d\xf4\xc1y\x12\xe7/\x1c\xcf\x93\xa6*\x99\xeaA\xdd\xf7\xb9\xb8X\xfeS\x1fO\xd9\xde\x0f>8\xc0$G\xf9\xe2+\xfe\xc2\xafW\xa8\x82J~\x01,\xa8\xdf\xdd\x81\x84\x0d\x93-\xe2\x90\xd1\xa3}[\xddZ\x85\x0b\x9c\xae\xc8\x05V\xd6\x07\xedpiO8\xda\x13.\xea \x17\xf6\x84+\x1e\xcd\xf2\xca]\xbe>;<\x82j\xc5a\xba\xb6>\x86\xf4v\xcc\x15\xdd\xc3\xda\xe4\x1b\xb5.\xa0\x89\x0e\xfa\x970.z\x82_\x13\xb2d#\xd2\xc7ki>\x82\x15T(\x18\x0253\x04\xd0\xebJ\xea\x83\x8ebl.\xc2\xd2\x11\xac@_\xd6n\xb4\xc8\xec\x92(k\x84\x17\xc5\x07/H\xc2\x05\xf1\x91\xf4\xf2\x00\x0f\x98\x82<\x8d\x16\xae\xe7\xf3\xa0\x85u\xbe\xeaC\x16H\xd4\xf2\x04P\xfc7\"\x8f'\xeb\xc8\x02\x89\x1e\x91J\xb3\xc9m\xf7\x94\x18\x96hJ\xe6_W\x1a\x92\x07d\xb8\x85Q\xe4o\x87G?8\xca\x8e&\x05\x9d0\x88&\x1e\xd29\xfb\x8b\x13\x14w^\xab\xbc]1\xa0]\x10.\x97\xf1=\x1e.\xbf%.?\x8e#\xfcG\xc2\xff\n\xcbL\x12\x91\x07/\xa1\xe0\xbcA\x95PD\xb5\x88\xa3\xc9\"c\xc8\xc7\x90\x12Q\xf7\xa0\x93\xca\xe1\xf1\xdbw\xe7\xbaa\xf2\xbb\x0e\n:\xf0f\x1d\xb7\xb6\x0bs\xf9\x05E b\xad`\x7fy\x1eF\xc5\x8d\x92B\xe3\xc7\xa0{\xd8\xc8\xb0\xb9D3\xec\xc4\x07\xc7Qp\xd5\xd9\xa2\x9d\xcb\x83\x18\xaeB(\x18)\xf8\nY6\xf6d\xad\x1c(\xa7\x03\xfe\x9b\x0d\xcfM!J`\x8f\xfd\x8d\x7f]\x13\xcf\xe8P\xd9|\xd8G\x05#d\x04\x87\xff\xa4\x9dl\xcf\xc3\xa3\xb6'O\xe0\xdf\\\n\xa0^\x8f\x99\x079\xfb8P\xac\xfe\xebc\xaa\xf7\x1b\x18\x88\xc1\xad\x95d\xc0\xa9`E\"\x00\xd1\xcc\x19V\xee_\xa7\x1chN\xf8\x18+\xa4\x12\x82\xb4\xd3w\xcc\xa0\xb6\x86\x97~\x15RPn\x0eT\x04\xc1\x1d{\xaa,0\xdc\x80\xc8m7kw\xe4\xc2\xa4 |\xe8\xa6b\xf5\xc1\xb0\xa2\\\xe6\xfe\xd7g\x18#\xa8\xe3L\xaby\xea\xd5@\xf7\xea\x82N\xd3T\xf3i\xaf\xf8\xd4\xf3\xd5\x93\x01\xba\xb4\xc8h\xea\xb3\x82\xb8\x0f\x9d\x83\xb1\x97\xb6$@\xad\x94alb\xa5\x03\xa5\x03U2\x04b?\xd7\x92wM\xfa\xc8Tl\x13:b\xed\x99\xa9\x07\xf9}[\xa6:\xc3\x80>\x07'G\x0e7\x87\xb0\xc1\xbe\xc0\xef\xa6AB\xeer.X\xbf\xf0Z\x0c\x98W\x14\xa1B\x92R\x18;&n\xc2\xb5\x9a\xa4\xd4\x8f\x14\x8d\xff\x049CU\xe6\xf9p\xcajX:\xde\x9a ]\x97\xf5\xb3`\xbcxr\x17d\xa2\xb1\xbe'|}g\xa3\x8f\xf4\xddG\xf2\xee#u\x87\x1d\x924f#\xe4Qqa\x07\x9c\xdf\xef\x9e\x8d\xd7\x06\x83\xdf\xef\x9e\x11\xc6\x88K\xf3\xceZ\xa5\xeb\xe3\xdetH,\xf7\x0b\xa0\xed\x0b\xab\xd4\x0fr\xcaO1<\xc8\xe7)\xbd\xc5\x83\x1d\xa68\x8e\xd2\x94\xa6\xae#\x8b!\xca \xa19\x84%\xf2M\xce\xb0\xe5\xf7Z\xbd\xc5AU_t\x19\x0b\xd7~t\x12\xa5\xf9}\xf5E\xde\x90\x0f\xe1\x15M1N\x8d\x81x\x8c(]\xab\x1d9t\"J\xb5\xbd\xde\xbb#\xecp\x98GcnHa\xc2\x8a\xce\xec\xd2\x84\xeb\xb6\xe6\xe8\xec\xb1\xa55\xac\xde\x9c\xdb%w\xb2\xf6\x04\x19\x18\x1a\xa8NtV\xdd\x1b\xc1t\xb3M>f\xcc\xcf\x91\x9a\xf7\x08\xba\x916/1\xd4M\xdf\x1e\xf0,\xbb\\HK\xf8\x19J} x\xf5#\x06\xc5a\x98\xed\x04k\x9b\x9eW\xb7w\xbf:9\xf8M\x88\xcb\x95\\\xbd\xcb\xf7J\x18B\xc2\xb4\x03\x92L\xf8\x99Xj:$\xb2\x0bdH_\\\\_\x9b\xe0\x7f\x03\x99-\xb8\x14N\xb6\x1d%\x7f\xb7}\xd5\xac\xc9\x91\xa3\x80+\xea\xf0^\xf3\x9b2\x06W \xfd\x14\xf0\x93\xe6\x13\xb6}\xa3\x95\x8b\x1f\xef\xe9{P\xdeC*8kJ\xbc\x17\xb8\xef\x15u\xae\xc2\x0dL\xb4\x86h\xca]x\xd8T\x1f\x13\x97rnB\x8d\xdc\xe4\x80T\x85\x9c\x9dP\x91\x8c\x98\x1a\xfa\xc60\xb3\xb0\xdae\x18\xc4\xacCG\xc1\x11\xb2-\xf8'~\x9e\x904<\xf0_\x80\x8a\xa6\x17\x1e\x845\x02\xe9\x81C\x90\xf4\x82A\xfb\xcd0b^\xef\xb9V\xc2\x80\x7f\xe3]:\xf3e\xaaK\x1f\xc2\x15&Z4\x88G\xb3\xea\xd9-#\xf2\xd2\x94\xd8\xaa\xf9\xc0\xd6dF\xf2}\x9aL\xa3Y/\x1b\xd8\x1e7\xd2r\xdfdMly\xd6\"\x06\x8aj\xb7ij\xb2rW\x95.\xcf\xfaf\xc3\xc9\xe4GJ\xaf\xfb\xf2\x7f\xfd\xd9\x03\"\x1c\x8f\xa3v\xf8\xa9\xd4\x9f\x7f\xe2^\x84'Sh\xc6\xcc=\xcdU\x8cj\xf3ju\xc1\xf4\xfd\xda\x99\x97^\x90n4\x9b\xad\xd4\xae\x1c\xc5\x85F\xa7Q\x1a\xde\x8b\xe3V\xdb\xc6\xa6\xd1\x0fW\xdbZ\xed\xe5\x832\x16\x9e\xce\xb6\x0c\x8b\x9c\x8a\xa2G\xc5W\x16\xfev\xfcpS\xdeSvs\x1f\x9c\xcbK\x92\x1d\xd1 \x0f\xd3S\xef\xfc\x0d7\xe0\xa9\xa9\x02\x94\xd5)O\x8cb7q\x9f7o\x15PQ\xf0\xb4Y\x10\x89\x82g\xcd\x82P\x14|\xd3,(D\xc1?\x9b\x05\x99(\xd8T%f\xf6b\x8b\xbd(\xdf\x94:F\xdc\x9ey\xf5\x06, *T\xe0\xe9\xb1.\xa8\xaf\x88\xaf\xd6\xf4\x0dlF\xd8\x05\x81\x9f\xb1\x95\xee\xca\x9e\xe5\xb6k\x9e\xee\xa6\x0f4\x10\x1f\xf6\xdc|\x1ee\xdc]\x95\x15\x84\xcd\x027\x0f./\xd1Twy\x89\xccb\xd3\x87T\x01\xf2;\xd3\x88P\xd0%\xbb>\xba\xaf\xab\xe0\xc5\x82\x93\xb4\xb4\x88\x99 \"[/\xaa\x8554]\xc3\xe4`lM\x0dM7<\x01\x0f\x0e3z6\xa7\xb7f\x92[Zmh\xe6\x01,;\x87\x18\xf7Et\x94Li\xba\xe01 ;\x88\xc2\xd2\xa1\xb1\xeds\x0bz\x15\xc5d\x08[OWm\x96\x8aqz\x96\x91N:q1\xed\x84\x98wB\xc4rg\xf8D\x0cXx\x08\xc9\xaes\xba|\x0c\x9a\xc2\x1eh\xfa\xaf\x1e@Q\x0e@\xa7\xb3\xd5\xde<|\xf0|\xe5*\xc2\x83[\xb5Y\nS\n\xa3\xcbe)\xec\xc0\x18\xdf\xfe\xbd\n\x8d\x0fy\xf0SF\x13\x14\x15\xc2Kn\xa1D&\xad\xbc\xbd\xa24&a\xd2|\x8d\xe1\x03\x9b/\xb9\xe9\xb1\xf1\xf65M\x17\x1a.-u\xa8{\xa6*\xb5T\"*KZ:Q$JZzW(\xab\xe8\xb4\xa8{\x9d\xde\x95\x89\x82\xd67bQ\xd0\xd2\xbb\xb8\x94\xd7\x14\x88\xa6\x08>n\xbc]\x8aF\xb6\x9a\x8dp\x01\xed\xdb\xc6\xdb\xb9\x04\xdfj\xf5\xf3F\x16\xb5\x86\xb6\x90%\x9b\xdf\xb4\x061\x13\x89\x8a\xb5\n\xe1\xfd\x97U\x08\x97\xe5\xba`=\x08\xa2\xecT\x84\x85\xf6\x95\xa20\xb9\xf7\x1b\x90\x96bN\xad\x86\xa6x\xa1\x0f7\xe5\x9b8\xcar\x15\x82\x91\xb5\xedw\x98\xdc\xd7i\xf5\xaa\xe5*t\xa3w\xf2\xa1\xc9\xfe\xf9\x86\xb6]\xcd:\xff\x1c:\x7fK\xb5\x97:\x7f\xd6,\xd0\xe9\xfc\xaaF\xfe\xa9:\x7f\xac\xb4U\xe9\xfcuK\x80Q\xe7/\xd3J\x1dD\x93#\x1eG\xb6\x05\xf9\xd7\xa9\xff\x93([\x86\xf9x~\xc8t\x860\xe6\xceP\xc6:\xdc\npc\x07\xe2^\xd2\x92\xc0\xf5\x1a\x17\x1aCS7\xe9\xe4\x9d:\x16\xff\xf7\xd9J\x90\x84\xbb\xd0\xc3\x97Z\x17~:\x90\x18\xd5\x90h\x91\xd8W\xb0\xcb\x14\x08;5\x1c\x0e\xe4AN\x7f\xe2\xd7\xaa9{g?]\xd3a\xbb\xf4\x8b\xb4|.F\x17\xbb\xfc~i\xe9\xfe\x18a\xb8\x9a\xbf\xe0\xa6\x80>*\xa9\x0f\xb4=\xe3\x06\xc6\xd3\x06\xac\x9di6c\x02\xfa\xb88x\xa8\xc5\xc2\xe3\xf9\xaa7_\xc0\x18\xb6\xa1x\x01\xe3\xf5u\x0f\xe2\x8b\xf1\x07\xb5\xe6\xc5X\x13kQ\xc6Y\xc4S\xe5\x1d\x03\xf3\xc3=\xae\x93\x01\x8e\xc38\x16\\\x90\xf8p\xc1\xea\x96\xc1$\xb8\x9e\x96\x96\xdbQ\xaf\xc3\"\xe9\xae\xaez\x8er\x92\x17\xfbh \xa2`\x92\x80G\xec\x0e\x18\xa0\x88\x81X\xbeC\xba4,<\xd1\x9a\xec\x15\xe3\xb2\xf2\x9d\x90\x90\xb4\xc7Sl\x1c\xa3\xa4X\xac0\x16\x81\xe7\xd6\x17\xf5\x1f@\x9bvK\x14a\xf4\xf4%\xe4\x89\xbf\x81/\xf6c?+\x08\x0f]\x8c\x96\xf6b\xb4\x9c\x87J\x99\xb8\x8b\x87N\x08\x8f\xf3d\x8c\\\x07\x82\x85\xa6\x01I\x8a\x85\xd92\xcd:G93\xdd\x15\x7f\xb8\x1e\x0c\xf1\xac\xb7\xe82U#Ou\x1d~\"c\xf3s\xea`;V\xbe\x02u\x8b\x1a\x95\x91Jw\xc1\x89\x12\xcc\x07\x84\xd7\xab;\xee%`\x90\xa8Zm\xda\xa3\x96\xb8\x9b\x80\x82ff\xe5]P\xd1\xaceF@\xb69Z,\xf3{q\xa5b\xcd\xc2\xa2\xa0\xc6\xcb\x90\xc8\xd5\xfd\xc0X\xcft\xbb\xd3\xb8\x86b\xdc\xfch\xba8\x08\xf3Pn\x80\x11\xba\xbb\xaf\xb9\xce\xeb\xb2 JD\x0c\xda\x8e\x83\xa3\xdcu\x0e1\x91\xa4]\x10\xa9\xed\xb7b\x8b5Q\x89\xd5\x82\xc6\xea\x0eEs\x96\x9e}\x12\x1d\xadNC\xad\xa9\xeb\x92\x90e~\xaf!\xc4\xfa dk\xd3\x84\xa0\x85|\xdf\x03Q\xcb0\xcbni:\x91\xb8\xe7R-CFU2\x94\xb9\x07\xffk\xf0\xd9\xbd\xc2\x16Q\xf2\x06[\x1b\xda\xfcK'\xe4\x8a\x16\xc9\x98\x9cG\x0bB\x8b|\x08\xcf\xbe\xb1@+\xa1\xe7\xacb\xe9_0\xdb\xad\xd7\x9fU\x02\x95\x16\xcf^\x02(1\xdc]\xef-dJ\xf3\xe8c\xad\x1e<\xae\x06Bc_\xcc\xd1\xf7\xf5\xc2\xdf\xaa\xf2R\x1ady\x98\x0b!\xc0(\x9c\x1d\xe6D'\x9cY\x1c\xae\xd2 #\xf9\x19k\xba\xba\xdao\x8d\n :hg\x91ri\x88Kj\x19\xc9\xb98f\xacd\xf2\xefW\xb0g\x184w\x98b\x03\xef'\x8fj\xc6k\xbd\x1f\xb0\xcax\xe5\xa5<\x11\xce\xe4/\x19o8\x994\x07\xbb\xcaX\xfb\x04\xc4\x10T\x06;p\xe9J\x8a\xeb\x12\x8a\x04\x06\x048w\xcaslau\x1e\x8d\x80\xd5U\x10\x0d\x1az`\xa1\xdfx\xff\x82\x01\xe2B7^\x9c\x15\x1f\xaefF\xdbH\xed\xe5_\xa3-\x95\xd6\xd7\xf7Q\x1c\x9f\x921\x89n\xf0\xb4,\xeb\xa1@\x19\xe7J\x92\xde\xda\x8e\xd0\xa2\x94]\x8f\x89\x7f\xfc\x9d\x9cN\x9bB\xa0\x92\xa3~*:\xf9\xd9\x17\xb2\xa0\xdau\xc4>\xba$?=\xec\xa7KR\x84\xedV\xed\"\x84\xebR'C\x84\xeaR'\x0b\x842\x99OC\xbc\x11,\xb4\xbeP\xd5\xfa\xec\x06\xd4\"\x88\x92)I\xb9\xf8\xe0FA\x94\x93E\xd6\xedhV?Q\xe9\xe1s\xf6\x8ag\xf7\xef\xf0\x1f\xcbP\xb7\xb5\x88W\xd0\xa6h\xb3&\xbc\xec\xd2v\xe7\xd2\xd3\xed\x13\xb5\xddy\xd7\xc6\xaeH\xd5\xe1\xeaR5T\x92\xb5R;\xecQKf\xdf\xed\xbe\xb7/\xd6\x9c\x85\x96\xa1\xad=\x1b\xa2\xbf\xd7\xa0kz1\xfd\x9b\xf5\xe2\x8ey\x14\x0eW\xdc\xedc\x8dGC\x99\x04\x98]\x91\xfd-\xfet=\xd8\x86\xad\xea^\xca$X\x84KE\x10\xf2\x81v\x11^$\x84\xe6\xb4n\x96\xcf:.\x96\xc9\xd9\xb75\x0f\xe2\x13K\xdc\x10xZ\xd7\x9e\x92\x8b|J \x06\xaf\xf1\xf0[/\xd6J\xb6p\xab\x80'\xeb\x82j\xe5\x9d\x8f\x8b\xe5\xc5\xe6\x07\xbe\xe3\xc1:P\xcb\xdd\xe4\xce{Y\x1dsi\x1f-2\xa2\x0e\xa2T}\xbf>f4\x19\xf0\xed|\xc0\xf4\xeb\x01\xdb.\xad\x0e\x81\xa6\xeeY\xdd\xcd\xa0\xfbd\x05Z\xa7+\x1dF*)]\xf7]\x81\xfd\x04{\xf9\x94$\xa3\xaaO|)\xd8)\xc7\xde\x1dy\x9e\x13Y\x96\xbf\x19\xc7V\xf3\x124\xa6\xf6*O\xe0*O\x06\xd9\x02\xb4\xb3<\xe0\xfaH\xc7\x86K\x93\xfd8\x1a_\xf7\x10^\xd4\xa7\xc4^\xa5\x87\xb9]\x88\xb3\x11\x9d\x03\x03pL\x9e\xa8^\x90S~\xf4\xf3X\xd4\xad\x84\xb6p2\x01\x07\xd6\xab\xcd\xab\xc1\xf8\xb8\x1b\xa1\xf1[%B\x91#\x08\xbdM?06\xee\xbd\xc9\x04\xd8g\xb5\xc3\xef\xb4\xb4\xbc-R\xb2\x8a\xb5\xa5r;\xebeo\xf9\xdf\x81\xdf\xca\x07~\xabj\xa9\xff;(\xd3?\x7f\xd1AY\x97\xceB{\x1d\xa7\xd5\x0f\xca\x0c\xa7\x0bx\xf2%\xf4\x9b\xb4\x9f~\x13\xf69\xcc\xea\x10#\xc2\x9e\x1ba\xba\xbaX/Dz\xa5f\xda\xcfX.\x82\x08$\xb6\xdbFuA\x9d\xbb\xc6MS\xba\xf8\xe9\xccs)jYx\xff\xd3\xc9S\x9e`e\x1a\xc6\x999\xe1\x0b\xe8\xa5\xf9\xb2\x1d\xdb\x81\xd7\xaaB}\xb7I\xe1\xd3L\xe4\xa5\x07\xf1\xa3\xf7\xec\xde{\xb2\\\xa1\x9fl\x1f\xb7X\xc6\xd9\xc2\xc9H\x8esrN\xcf\xc2\xc52\xeee#\xaf\xbc\xbb\\\xf6\xe5\x19\xdb\x1cxm\x8e'\xcf%5w \xfd\xdd`\xa2\xb5\xcb\x1bEF\xd2\xf2\x990\xb4:\x0f\x93ILNVi\xfb\xa6\xccw\xdc\xed\xbb\xa1\x0c^\xe7\x03\xe8\x1b\xbd\x85\xe132\x80\xcf\xe9y\xb9V1\x81\x86\x9dO\x9d\xc3\xf2e\x9bdtw\xb4\xeb8\xf8B\x86\xbc\xffbN\x96\xbb\xce9\xb9\xcb\xf7R\x12>\x92\x9b\xd4\x0c\x0c& \xda\x93\xe50R\x9b+\x06\x04c\x1d\xf6\x08\x9e\xc4\xd8M\x16\xfda\x0d\xcfkF\xbddX\xac\x05d\xc3\x1fi\x94\xb8\x8c}x\xfd8\x97EGm\xb0\x89\xfa\x06\xa0\xad\xf5(w\xbe.\x11\x1f\x81\x1fu\xe3E\x1e\x86\xe2E\x87\x7fz\xc1\x818\x91F\xa7\x89\n,\xad\x17\xf0\x10\x92\xb58\x02\x8f\xef\xc2g\xbdt\xd3\xec\xa6\xe9n\x8c\xf8h\x98e\xd1,a\x8c\xcc.\xa6\xd7\x92>o\xf1\xfc\xceMuE\xe4y\xb6\xef\xf3\x95\xa6bJ\x03]~\n\x03'&=\xf3\xc2c(8\xb4Ta\xac\xe9\x1dH.R]\xa0\x89\xd6\x1b\xc9\x90\xeb$X\xa7x\xda\xc5\x9aK\xd1\x83XO\x9ck\x19\xfe7_@\x02\xdbj\xa2\x7f3\xf6@\x99\xb9\xfc\"1`\x0e\x90P\x99tG\xd2\xf0\n\x05\x8a\xdaO\x91|,e\n\xdb4\x9a\x15\x12hm\xb3L\xda\xc7P\xce\xe3\\\xa6\xc1m\x1a\xe5%D\x99}\xaaI\xa7\x845xM\xee\x19\xfe\xf5\x0b\xbe\xff$\xa8\xd6X>\xa1V\x85\x91\x07\x01u\x15\xd2\xe0\x99\xc3R\xf1\x9eG\x07l{\x157\xb6\x9b\xe6\xc5r\xa6\xd8\x14<\x02F\xbd \x14\x05[\x9b\xdf|\xab\x0f\x86Q|\x91\xbbOn{\x99\xf7\x92\x8a\xb5+{\xad\x9f\xb3\x04\x8f\xf5T\x8b\x80\x95\x9b\xc2\xa1\xed\x87IBs`\xeb\x12B\xce\xfb \xccj\xa1\xd8\xdas\xd2!\x90'}\xbd:\xb0\xa3D\xed\xd9)\x99\x92\x94$\xe32D\xdc<\xca`\x1ef\xc9\xd79\\\x11\x92@\xc4\xaf\xb1D\x19\x99\xc0\x00\xb2bIR\xd7\xabA\xb0\xa1\x90I\x87\xf8\xb0\x86\xc7\x0dJB\xc9Z\x10\x1fm8\xbb\\P\x81\x86F\x0d\xfa\x86X\x843\xc2\x98\x1f'\xfa\x93i\xcb-\xc7\xa2y$\xab9d\x93`I\xd2,\xcarSX\x05\xc9\x14\x92\xee\xd3\xbdd\xa5\xe3kU\x1f\xd0o,=s\xaf\xb0\x1e\xd2~=dO\xe9\x06\xf7\x92U\xe1\x82x\xe9\xcd\x86\xe1\xaa\x12\x9aGS\xbc\xe68,\xb7oxYU|\xf2\xa4\x02J\xf1\x88\xa8G\xbe\x066\xd8!\x08p1\xf8\xaeZP\xe1\xcb\x92\x91\x0e\xf4\xeayUd29\xb7\x89\x12\x13-%?\x93\xfb\x03zk7\xa0\xca\xa7\"\x0f\xa9C\x8a\xda\xfa pFI\xceS\xc20\xf1\xfe\x9a\xdcsdNi:&\xc7\x12\xed\xbe\xc85e0\x10\xb2.\xbe\x8a\x8b\xf4\x91\xfdcUM\xf4\xbbb?\xb8\x86\x80\xf0\x11\xe9\xd7\x1f\x1eQs\x1b6\xbd\x92\x86\xba\x84\x0f\xf9\xc8\x05^\xc4\x06/F\x83V-\x03\xfc\x8a\x84=\xb5\x0f'\xc1\x84\xf2\xf1Z*\xdb\x97^.L)\x8a\xed\xa5\x1b\x0d\xf2I\x82(\x13\xbc\x8e\xdf\xd1a\x02L\xd5)\xab\x9f\x19\xdb\x07\xcd\xcb\\\x87\xddGtg\xd3\xd7\xcf\xbf|\x90\x0e\xa6q\x91\xcd\xfbN#TS\x99\xf3\x9a\xb6\xb4\x13Hf\x8c!\xc7\xab\xb4\xafEk.\x1a\xb2}NOXz\xea\x97\x93\xd4\xa7cI\xc3\xc4$\xce\x18D|Z\xe5r\xad\xfeS\xca\xba\xec5\x9f\x98_\xa0\x86\x03\x1b\xc6J\x0c\xe3^$\x91d&--K\xec8\x81\x04\x0d\xb31\x7f!Wx\x14E\x9e\xa4\xac\x08\x0c\xa2X\xfe\xfeR\x0c\xe8\xf1i3{\x07\xdf\xc1\xa9\xee\xe5\"(\xdd\xe6\x98<\xd6f\x8c\xd8\x8en_\xa9Aj\xcd\x87\x9d\"\xa81r1\xb2\n\xf4=A\x07?\x83\xe8|\xc6\x84O w\xcb\x94d\x19\x93\xda\x17E\x96\x03\x89\xf29I\xe1\x8a\xf0\x06h\xaa\xc8\xd2>\x06\x1dv`\xbd\xfc\x90\x862I\xa5\"U\xba?\xe7N\xae\xc8\xdb\xa8\xe8Pz\xd4\x8ei\x92\xe5i1\xcei\xaaS[\xe4#g\xc0L\xef\x95F\xda\x8e8\xa0>R\xff\xb4\xbbA\xa9\xba\xec\xd0\x94\x8cICK\x92{\xbb\x02\x1bYM\xa2\x86]\xd0\xbe\x17\xf3>DUN\x8a\xe5l:\xeb\xa4\xc3t\xcf\xf2T\xa0a\xbd\xf2\x81\xf630\xbf\x8f\xe2\xf8S-\xcch\x95\xab\x8b!\xaeb`n\xdc\xbf\xe8\xb2\x97X\xac\xc9\x7f\x89K\xac\xdcH;\xb7\xd0D\\\xc6\xab\x8dF\xbf}\xe2\xe8k\x8b\xff\xcf?\xcb\x8c\x85\xb84+g[\xc5\x01\xb7Q\xd2[\x8f1\xddi\xf6!\xa9<}\xb5\x93Q~\xac1}I\xb7\x01\xb5\xe74\xbdK\x16\x9f\x83\xbc\xb8t#{k\x92Xzw\xf1o8\x97\x10\xb9\xbe\xec\xf4\xe5*\x91\x15J\x8a\x04R\xb1k\xbfM\x82\xec\x95\"\x9b\xbc\xbaG\xf5\xc6\xe68\xc3\xa3-TUNP\x1f\xb1\x9c\xef\x8a\x90\x0fB\xab2\x03\x16\x02\xd0\xde\\\x86PQ\xb2,\xf2S25\xc3\xc5}\xcd1\xf2\x916\x9c\xff\xf4I\x1aUZ\x7f\x89\x07y\x19\x96<\xf5\x98\xb8\xb3\xa9XA\xec&aR\x9a\x84\x13n\x12\xc6\xac\x85\xf6\xcfK\x1d\xca\x08\xf4\x80~/\x8e\xa0\x18\xc7\x07G\x12\x85S\x1aQ}pJ\xa2\xc0d\xd1u\xa2\xc0\x83\xfb\x16Q4\xde\xf2y\xe7\xed\x8b\xb9\xe5?\xe4k9G\xd6\xd3\xffqG\x0cKt\xf3\x86]\xcb\xdc\x95_/\x1d\x01\xc4o\xfd\xbe\x06C\x08\xfb\xb6g\x88\x17\x0eC#\x910\xba\x98v\x0c\x89\x95\xd3\x8e.0\x1c\x96\xe3a?\x8c=)z\xb5T\xadB\x99\xba\xb4(r\xaeueb\xe8\xba\"\xf3=\xd8\xd6\xdd\xd7\xad\xcd\x06D{\x93h\x8b\xc2\xad-\xa3\x0d\"w\n\xd9\xc1\n\x97\xf8W\xc7\x99\xa5\xe5\xae\xa0\xdc\xd3\x9d\xd1\xdd\x92\x8cs2QM\xfcmBIa\x07\x8e\xc3\xe3v\x01cz\xce\x85\xf0\xf09\xbb_\\\xd1\xf8\x83\xa6~\x04;\xb0\xf1\x7f\x7f\xcf\xd6\xff\xfc=[\xffjc\xd6\x86\x08\x11\xe2b\xb0\xfea\xf3\xeebs\xf0}8\x98~X\xffjC\xe3\xe6T \xe4\xe6\xd5\xc5\xe6\x96\x01\"\xe3\x10\xf4bs\xf0\xad\x01\x841A\xcc\xad\x7f\xa8\x93\x1d\xd8\xde\xaa\xa4f\xa9\xe9\x81B\xe7:\x11NM;R'\xc3\xd7\xed\xa6\xa6\xfa\xa62\x12OY\x0d\xf5\x7f}\x9b\xac\xa4\xdd,\xdb\x80\xc6x\xf6\xcb\xfey-\xe7\xd9\x91\xd6\xa7y\x949\x9e.\xec\xf2\xa4R\"+\x16,\xd3\xe4\xb4\xc1\xe7\xb0\x03Ga>\x0f\x16\xe1\x9dF\xac+K#\x8d\xf8\xd2\xef\xb6'\xef\xf028`\xdbNBou\xf2\xa7r^\x07\xea\xb9\xd8L\xaf\x7fH\xddC&\xba1\x1e\xa8\xac\xad\xf1\xac\x18\xb5 \xd2d\xddiz\xa7\xea{\xa3\x89\x9e\x08\xd2\xac\xa0\xc9\x97nK\xd3\xc2\xeat\xebX\xa2\xbe\x93\xe1\xba\xab5\xde\xed\x16\xd0hD\xa0BC\xaa\x066\xc0Z}\xf2\x04&B`\xf3@{i\xe5AM\x13\xa4\xb1\xcdc.\x15KF\xa9\x9b2\xa8PmBdF)\xdc\xbdQ\xe5/\xffF'U\x93\x17\x1a\xec\xc0\x8cm\x86\xbb\x90\xc3:\x8f)\xd6u\xc6\x0c\xcd\x0cJk\x9a)\xac\x12\xe6\x13\x18\xc2\xba\xe6\xf3D\xb8\xdc\xf2\x84~\x11\xe6\xf33\x1f\x97\x16\"\x1d\xb4\xe5,\x90\xcdp&\xc1`\x17bW\xe4!u\x9f\xa2\x86\xba\x0bOa\x08\xdf1l\x84\nX\x8a\xfdk\xd0\xb3\xfaK\xf5\x8ci0\x17\xed\xa1>\x1e\xd1\xf9\x10a6\x99\xc2\x87\x0c\x85\x13\xf4w\xd7\x0b\x1cSn\xb2\xd3\x96--e\x13\xb4\xd9\xebIH\x9fpLo\xa8K\xbc\xc6v\x02\xea\"\xbe\xea\xf6w\xb4\\_b|2\xb2Jv\x8ca*\xe9\xdbx\xa0\x17_\xa8x\xdcr\x9e26\xae\xa1Js\xa75\x91;\xe5#;M`\x00\xb1\xb5gJ\xc0\xbd\x98\x11W\xc2T\xb6\x9c\xff\xb5\xcdu\xb7%zB\xc0\x00\xc6\xac\xac\xad\x04\xd8\xfax\xdb\xa9\xf4/l\xe1\xff/k\xf9\xc6\x8c9\xca\x18\xd5f$\x17\x82\x99{\xeb\xf7\xdc\x05K_V\x18\x80\x8b\xb8\xea\xbe\x9c\xba\x84]\xb8q\x13\x1fBYi\xec\xa1\x05\xdf\xb8a\xae6\xab\xa3\xce\x9d?S\x08i\x02\x98\x1dk\x17\xae\xf89\x82\xdb\xa4\xb4b\xb5\xaf\xdf\xf5\x99/\xf3JHx\x1c\x06\xcb\x8cR\xd5\xa5\x8c\xe7\xe4\xe2.\x10L63EJQ\x1bP\x086\xf3\xdaV\xfe.\xb3\x86\xa80\xe6_k\x13N\xee\xf90\xad\xf0\xa9W\x14\x01g\xd6F,\xe2^\xb42c\xed\xcf\\\xb9\xa6\x00\xfb=\x17l\x86b\x8c\xaeq\xcf\xd7\xf4\xdc\xe8\xc5\x95c\xe4\xe8\x1ccbn\xfa0s\x85\x15\x06\xf7\xec\xb54\x88 \xe6f\xe0Y\xb0]\xb6[;\x8b\xf0\xee}\x18\xe5\xdc\xfd\x8cq\x98\xb9{\xef\xa6\x81x-[B\xc3{\xe8\xe3&\xee\xe4i\x18\xc5\xc8K\xd1em\x17\x9b\x96/a\x08\x13L\xe0\xd7\xffhT\xb1\x00#\"0)\x98\xc4B&o_\xf1\xebG\xb1X\x15\xd5\xd2ic\x87}\xbd\xf7\xb9\xafn2v\xa1\x80!\x8c\xdc\x85kH\xf0U{\xa9\xb8\x87IW \x1f\x12\xf7\xd9\x96\xa8\xdc\xa1\xe5I\xe7\xc2z\xf7\x9c`#\x8c\xe3\xe0c\xe6\x0c\xe1\xf9\xf3\xe7~\xab\xb0\xc8\xe7\x1b!6\x9aq\xa8\xa7\xcf\x9e\xea\xa1\xd0\x88\xc7a\x9e}\xffL\x0f\x93\x92I1&i&\xc1\x0c\x1f\xccd\xe2! \xf7\x8d\x01nI\xc6\x83\xdb4\\\x0ej]|\xf6\xfd?[\xf0\xfc\x10)k\x8e\xa5\xdd\x01 8'\xf1\xb2\xec\xe9\xd3g\xed\x01I\xc0\xda\xb8\xbf7\x82\xd5\x87\xfe|\xb3\x8dE \xd9\x18\xfd\xf3\xcd-3(C@mH\xcf\x9b&\x06'\xd8\x98\x10\xb2\x1c\xc4Qr\x1d%\xb3\xfa\xb8\x9eo\xb61[\x83V\x06\xf7|\xb3\x8d\x83\x1al\x1c\xde\xd3\"\x97\xc0m\xcc\xd6\x80\xcb|K\x83<\x9c\xe1\x1c.I\x1a|\xcc\xee\xb0\xf2\xb7}+7+\xb6'~Bo\x93\x98\x86\x93A\x91\xc6r\x96\xbekA\x914\xad\x93\xc6\xd6\xd3v\x1f\x18\x10\xdeG\x18\xe4i\x98dS\x9a.H\x9am\xcc)\xbd\x16-?mO\x95\xa1R\xedGB\xf3\x01\x9d\x0eP\xc9\x16\x0d\xb5\xc9\xa3OC\xcb0\x0d\x17$'\xe9\x80&\x84Nec\xed\x89\xeb\xd3\x18\xd3d\x96\x03\xe9\x0e*\xdbj\xcf+kK]\x04[\xedE\xc0@\x1ak\xffi\x9bN\x19Ts\xe9?m\x13(\x8f\x9dP'\xcd\xf6\x8c\n(\xba\xccxV* \xd9\xee\x1c\xa7\xdb\xc6\xce\xa0YF\x02N\x1d\xea\xd36\xbd \xa8\xe6h\xdb\xd4$\x00[\x03n\x0f%\xa6\x8dm\xe6\xbb6Rh\x98=knn\xed\xceq\xa8\"\x9f\x0f\xc8]N\x92\x8cAo\xe0\x06\xda\xdct44\x83\x95\xcb\xe3\xc5l\x83\xf1\xa0\xabp|\x9d\xc9\xd5\xa7\xc1F\xb3\xce<\xcf\x97\x03\xd6\x01YG\xc3M\x9au\xd4\x89\xd6\x90C\x13\xbc\xda\x1c\xd8vQ\xf6\xad\x8dVs\xc5\x8c\xa7X+\xfb\xd8\x8d\x8b\x94\xfc\xbf\x82d\xf9\xe0\x8aN\xee\x07d\x12\xe5\xb4\xdc\x93\x9e\xb5\xf7\x04[\xed\xb2\xc3m\x8aiV\x13\xdd\xac\xb2\x1d\x95\x9fl\x13\xaf\xa1n\xf9\xb5\xf6\xb2\xc0\x1a5n\xf1\xcc\x80\xfc\xda\x04\x19F\xdb`\x7f\xcf\x0d(m\x92\xe1s\x03y \xe3Sh\xb8E\xbe\xedmJ[OO\xfb\x86\x8f\"\xb0\x82C\\HQN\x16%\xde\x0d\x0b\xa0YQE\x98F\x04\xd1\xd6Q\xa38p\x1b\x93D\x91\x01\xe3\xcd\x06\x16az\xcd\x98\xa1\xfc\xaea2[\xd5\xe8\x84\xc4r\x80\xcf\x0d\x84\xd5\xacD\x938J\xc8\x00\xaf\xb6\x859M\x07W\xe1dF\xe4\x97\x0d\xb4\xd6l\xa4df\xd5B4\xac\x89f\xcd\x1b\x9e\x02r\x90\xe5\xe1bYV\xd6\xec\x00 \xd6\x8aINjs\xb2\xd5\x1ef\x86\xb71\xb3\x8d\xa9\xc0\xdf\xd6\xf7m\"\x910\xb5\xad\xba=\xbd\x8c\x06\x9b\xdcF\xd3\x18\x83R[\xd2\xec\x94\x08\xd3\xe04\x9a\xcd\n\xc1\x1aD\xfeT#U\"\x9cF\x9c~\xde&k\x99\xd5\xeecc\xb4m\xc8\"\x8f\xe2\xba\x8c\xdc\x9e\xc4\x9b\x88\xdc\xd6`\x9e\x1b`RJ\xf3A\x94|$\xe3\xbc\xec\xdcw%\xa46]\x0d5^\xd8I\xdc\xa8fly\xd0\xd4\x8e\xda\xb5\xa5\xad9\xbd \x8d[Z\xfc\x06M\x0e\xeb\xb0U\xbb8S\xbf43\x8d\x92 ,\xf8\x0d\xa1\xaf\x1dX\x07\x02\xeb\xe0|\x1d4\x0d\xbdR\xd7V\xfa'\xff\xa2\xc15\xb9\xb7\xe6O\x16\x95\xc5\x11\x0e\x83v\x95\xcb[\x0f>\xd0 %\x19\x8do\x08St\xeb\x17\x1d)+\x8d\x98\n\xbe\xb5\xf9\x0d\xc7\xee\xc3\x07\xef\x1f\x0f\xde\x8b\x7fll\xfc\x1f\xc8h\x91\x8e\xc9Q\xb8\\F\xc9\xec\xdd\xe9\x9b\x9d*\xc3\xe1\xe0\xaaH&1[\xe7\xc1\"\\\xfe\xff\x00\x00\x00\xff\xffPK\x07\x08-\xe3\xb5\x97=9\x05\x00\xf7\x0c\x1b\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00 \x00swagger-ui-standalone-preset.jsUT\x05\x00\x01\x80Cm8\xec\xbdys\xdc6\x9a0\xfe\xff|\x8aG|w\x152M\xd1\xdd\xad\xc3:,k\x1d\xc7\x9e\xf5\xbb\xf1Q\x963\xf3\x9b\xb7\xa3UQl\xb4\x9a1\x9b\xec\xe1!Y\x13i?\xfb\xaf\xf0\x00 \x01\x10 \xd9\xb2\xb33\xbb5\xacT\xac\x06A\xdcx\xeec\x0b\x16U\x1a\x95q\x96\xba\xa5\x0f\xc4\x83\xdf\xfe\x00\x00\xe0dW\xbf\x92\xa8t\xe0\xf4\x14\xca\xbb5\xc9\x16@\xbe\xac\xb3\xbc,`{\xdb\xf4v\x95\xcd\xab\x84\xc0\x19\xff#\x10\xb5O\x81\xb8\x1e\x1c\x83#\xba\x91?\x9a\x93E\x9c\x12\xda\"\xfb+\x08Ws8\xe3?\xdc\xd9\x05\x0e\xe8\xb8k0g\xe2\xaf\xe0\xfc6\xbc\xbe&\xf9\xcfo\xce\xcb0\x9d\x87I\x96\x92\x0f9)HY\x0f\xa1\xec\xab\xf3\x87\x07\xb7\\\xc6\x85\xdf,\x89X\x8e\x9c\x94U\x9eJK%^\xd0\xe7&\xcc\x81\xc0)\xfc\xf6p\xf2\x87\xbaPT\x85\xd4\xcd\xe5\xca\xf4\x89\x17\xe0\x92Y~\xe1\x89v\xe9\x0f\xb1b'JU\xdavLG7\xcb/h\x17\xcaKl\xeb\x18r\xbfU\x9a\x1c\xc3\xd6\xa4]\xcc\xbb8\x86\xdf\x1e\x94w\x0fj\xa7|T%\x1dU\x14&\x89\x1b\x8b\xc1\xf9\x10\xfb \xfdJ=\xfa3\x81S\xd8\x1aK/\xea\xd6\x9anx\x9bi\xb0\x82S(}H\x83\x88N\x8b\xfe1\x87S\xf5\x10\xfa\xd0Z\xb24\xc8\xf8\xf9\xbc\xbf\x87\xf7x\x1c\x02vL>\xe4\xd9\x9a\xe4\xe5\x1d\xff\xb2\xbdBQ\x96.\xe2\xeb*\x0f\xaf\x12bY\x96\xb4Z\x11\xf1~\xdc~\x7fM\xcac\xc8\xd5\x15\xf3\x9a9\xd29\xa4\xca\x1c\xf4\xd1\x8b\x13R\xd2\xa3^\x06\x97\x97\xa4x+\xeeK\xeb\xac\xc9\x8f\xd8 :\xd7\xb0JJu\x0cp<\xec\xeb\x01{\x9d\x06s\x97\xf8\xe0\x84\x0e]d\x1f\x88:\xbdL\xdf\"\xbd;\xde\x0c\xdf\x99u\x9e\x95\x19\xbd\xa9\xc12,\xde\xdf\xa6b\x8f\xd8i\xc2\xef\xd5\xf6\xd7p\n\xce\x93y\\\x94\x8e\x0f\xa9\x9b\x06\x14pL\xc7\x07\xac\xda\x83;\xd3\xceG*\xf7\xefT\x05\x81\xa2\xcc\xe3\xa8tN\x94[\x99\xc3)\xa4\xee\xfe\xd4S\xf7\x94^\xa8\x99\xf39N\xe7\x8e\x0fNN\x8a,\xb9!\xf4\xcf(K\x8b2\xaf\":\n'N\x8b2L#\xf2~A\x7f\xads2\x8f\xa3\xb0$\xec\x935\x05\x1b)\xd6\xe3[s^\xde%\xf8\xb2\xa0\x7f\xbcH\xe2\xb0 \x85s\xa1\xf6\x9ca\xcfE\x14&a\x8eu\xc9_+\x92F\xf8\xdd*\\\xaf\xe3\xf4\xda\xb9h\xe6PJ`\xb4s\xf9\xe9dS\x1f\xaa\x936\x9c\xa1\xb7\x8c^\x9a\xdf\x1e|\xb1=\x9f\xc9]\xe1\x12/Xd\xf9\xab0Z\xbau\xd3\xadvE+;\x138==\x858\x88\xd39\xf9\xf2~\xe1\x12\xcf\x83r\x99g\xb7\x90\x92[\xc8\xdd\xef~N?\xa7\xd9m\n\xd9\x1a\xa1\x9e\xf3\x1d\x8c\x80\xc0\x08\xbes .`EJ\x88S\x06\xd8c\xac\x90-X\x9d\x92\xd5\xf9\xcb\x8b\xb7?!l\x0f\xbe\xf3\xb4\x8b\xe6\x03\x05\xcaA\x19^3\xc8\x81\xbf\xe8\xe6\xd1\x99\xb1?\xee\xef!\xad\x92\x84\xbf\xe3\x1b\x8a\xaf\xc5\xdf\xf7\xf7\x83\xae\xca\xd6X\xed\x9c\xb7X\x9f\x0bl\xb3\xf9%\xb7\xda\xba\xf4`\xbd\x81\xbc\xd5\xe6\x80a\xb3\xd2Ou>\xf5\xd1\xc3j\xcd/}\xd6\xfcL\xf2y\x8b_j-\xf9\xb0bE\xa5@\xad+\x1fd8\x057\xc5\x0f\x94\xd2\xfa\x83\n\xf1\x9f\x8f\xbf`\xeb\xf4\x14R\n\xea\xe4\xf3\x96\x1a\xce\x9bq\xcd\xd2Yy1\xf0h\xd2\xa7\x9a\x9d\x97y\x9c^\xbb\xc4\xa3\x18\xb2lUzh\x1f\xa8\xca\xf3\x81\x1f\xe9\xac>\xd2\xf5\xb9\xb2\x1dm\xd0F%\x1e:\xba\xc8\x87\x85\x0f\x89\x0fk\x1f\x96\x8c\x06\x81\"x\xdd\xa6r\xe83\xaf+\xfc\xd1\\\xe1\xa6\xaepn\xaepWW\xf8`\xaep]W\xf8\xc1\\\x81\x12\x88\x94\x0b\xc8\xe1\x18n\xe8\xbf3\"N\x17A\x1a\xf8\x81\x12\xf3\xae(\xfe\xed\xc1k\xe8\x0ds\x8b\x97\xbc\xc5\x98\x9eB\xd1Z\\\xb7f\xfe\xe8\nN\xe1\xb2i\x19\xbf\x91\x7f\xe3\xa7'\xadO\xe9\xf5w#Dvx\x98\x10hz\xb8?\x94Lv]\n\xec\xb7\x96\xf4\xdd\x8a\xfe\xef&\x8b\xe70F\x90\xb9\x9aE\x17\x1e\xe5\xa0\xe0\x18Ro\x16]\xf8@\xe9\xa2kZm\x01g\x10\xba R\xc6\xc7p\x87L\x98\xe9\x0e'X\xef5\x7f\x83\xf4\x96\x0f \xfd&\xf1Y\x87\x95\xbb\xf2\xe9\xa1\xa0P\x1e\xb7\xe1g\xcf\x87\xcbYt\x01[\xa7\x90\xe0\xcdu/\xb1\xc6\xda\xf3YOW\xf2[\x17\x7f\x9dB\xa2\x81\xd5f)\xf2 bw9\xf6\xe9I\x83S\x98\xd0?\xfeHI:\xfa\xc79\x9c\xc2\x1e\xfd\xe3\x03\x9c\xc2!\xfd\xe3\x07Z\xe7\x80\xfe\xf5g8\x85]\xac\xf53\x9c\xc2\x01V\xfbH\xdfN\x0f}\xe5\xc6\x17\x9b\xdd\xce]\xe3\xed\xdc\xd3\x8b\xf9\xed\xd4\xef\x1b\xbd\x9dO\x9c'\xd7\xed\xcb\xa9\xf7n`]@b\xe38\xaa\xca\xdc\xd2\xb3\x1c;\xda\xa8\xf3\x8c\x02H\xd2>\\\x1c\xde:N\x83b\xdd\x10F\xa7\xe0\x00\xfd\"\xa5\x18\xe7\x14\x91\x0f\xef(\xf7(%\x90\x84\x11q+\x1f\x9c\xed\xbfVYy\xe2x\x88\x99\xbe\xf3|\x08a\x04\xces\xfamL\xffz\xf6\xc4\xe1d\x9b\xf3\xdc\xb1m\xeffD)\xe7\x8b\xe5\xf2\x94a \xe2\x86\x9e\x0f\xb9\x9b\x07\x1f`\x04y\xf0\x1a\xbe\x87\xd8\xed\xa4\xd2\x04\x1f\xe580+/\\:\x07\xeb\"\x11\\#\x12\x94\xd9O\xd9-\xc9_\x86\x05q\x91{$A\xb1N\xe2\x12\xbf\x0e\x12\x92^\x97Kx\x0e\xbb\xeat=\x1f\x1c\xb6\x86\x94!\xe9C\xdc}\xe8\xc9\xa9R\xc6\xac\xce\xe9\xce\x89\xbbz\x1b\xa7\xf3\xec\x96n\"\xfb+x\x1b\x96Kz\x97\xf1\xdf3\xf1\xfe\xd8\xf2yA\x92\x05\xfd\x98\xfe\xab\x7f\x8a\xef\x8eA\xc0\x01\xd7\x11\x84\xe82.\x1c\xcf\xf5z\xf0\xe05\xc7\x83\xd7\x8f\xc0\x83G\x9d\xa4\xca\xbe\x8e&\xd9\x8d;\xfa\xdfC\xaa\xd8\x89\xb8\x03\x9d\x16\xa0Kb\x90m\xc9\x1b[o0#\xa5\x91d\xe5\x7f\xf27\xed\xe5\xcc\xe9\\b\xfa\xbf\x01\xfb/\xaf^6\xf8p\xbf\xc8\xf3\xf0.\x88\x0b\xfc\xd7\xdcX:\xb8\xb1\xff\xe57E\x9e\xf2\xb0\xb3J9nN\x17\xd0\xbe\x04;\xf2\xe9nM^\xe5y\x96\xbb\xce\xcb0\xfd\xae\x04\x8a\xdd)k\xbd\xcc\xe6\x90\xa5\x00\xec\xac\x9aey\x9bB\xb0\xa6\x15E\xb4e\xb9Vt\xb5\x9a\x1e\x94\xf3\x95\xdfi\x9f\xd0\xf6\xd2\xce\xd3\x89wq\xec\x03\xb9 \x13\xcfuXq\xd3\xfee\xd9\xc7\xbf\xcc\xfb\xf8\x97\x9b>\xfe\xe5\xae\x8f\x7fi\x18\x9c?\xdb\x19\x9c\xe5\xa6\xec\x08\xe5aV}\x8c\xce\x15o\x99\xb2Ns\xc1:\xd9x\xa5.\xdee\xa9\xf1.\x8ckY#3\xa0q-W\xc8\xb5loC\x88\x8c\x05\xbb\xbc\x94\xd5\xa1,\x0b\xf2\n\xc7\x90\"3\xb3b\x8c\xc3Rc^\x9a\xd3\x8f\xb5\xcf\xb0\xb6`rh#Y\xcd\xf7\\\xd7\xdc\xc8\xe9)\xb2:\xdd\x92$\x90H\xc6F\x90d\xa7\xd2\xc5C\xaf'\x05: Dr\xecf\xda?\xa0Oq\x1b#T\n\xf3\xebjE\xd2\xb2\xe0\xb4e\xdfw\xf4\x89\xc2\x82\xc0\xf8\xb8\xb7\x1eH\x02{r\x0be{\x0b\xf5\x07[\x9el\xde\xb2K\x0c\x94\xb5\xfe`\xe3\xd3\xc74\xae\xd0\xd4\xa6\xe7\xa1\xf3m\xab1\xba\xa1\xd6/\xecm\xd5\xea\x95p\xbdN\xee\xb8\xf2\xaf\xde@s\x8b\x0f\xe6u\x11\\\x87\"!\x904!\xb2J\xa5n\xcaE\xce\xfc\xa6\x93\x9b\xcfl\xdc<~\xe6\xba\xab\xe0&\xce\xcb*L\xf0\xe25\xbf\x10\x96x\x9cW\x17\xbc\xfeG\xfa\xcd%\xfd\xdf\x16\xb2\xfc(\x0f`\xdc~\xe2yV\x8e\xfe\x1f\x85\x8b\x9f\xeab3.dk\x953\x1cu\xa8#4\x8a\xa2\x8c\xca\xc3f\xaa$X\xb06\xf7=83W\x96\xd5n\x16\xccE!H\xee\x96\x9e\x8f\xb0'\xa3gtk\x8c\xdc.jL=\x03Y\x04\xcd!\xaa\xeaf\xd5\x0d\x91 \x9f\x87V\x7f\xce5)\x1d\n\xbc\x91\xb8r\n\xf1\xcb@>\xbe\x88\"R\x14Y\xce\x08\x8a\xa2Z\xd3\xfd \xf3-\x0bA\xe1\xdc\x84IEx\xdb\xf4\xd0\x95\x0cY\xa5\x01\xbe\xf0\xfcMI\x0e\xf9\x08l\xa5\xee\xf4\xc8\xb3\xf3\xfd|\x0cO)\x9e0+~\x7f{\xe0\x8a\xcb\xf6\x82\xa2\xe6\xb6S\xa4 w\xd1\xbe\xa0\xea\xfa{A\xd8\xcc\xb3\x9f\xd8o\xe4\x1f\x9a\x1a\xb4\x8f\\\xb4\xebWS\xa3\x06u\xc8\x92K\x82j\xcb%\xda\xdd\xb3\xb0\x85\xa9\xbb7\xf5\x14dk>\xf4\x82\xc5\x0e\x16\xbcF\xecNh5\x99t\xef\xbf:\xb5\xf1\x01;b\x1b\x9f-I\xe67\xb1L\xa8\x9b0\xdf\xa2\x17\xb7}iT\x1a<\x05\xc6k\xd8\xaeL\xdf\xa0\xfb\xf8`uX\xff\x8d\n\x8dne\xba\xb2rCd\x82\x88\x9bc\x1f2\x1f*\x1fB\x1f\n3\xa8\xa4@d\xcbHc!\x03\xd0\xc6\xb9\n\x8fL\xc9T\x88\xe8\x1c\xc9-p\x18\xf76N\x99B\x8e|\x89\x08SJgQT\xe59\x99\x9f\x00\x9dd\xb9$\x90f\xe9\xceJT\x9c\x93\x1b \xe9M\x9cg)\xc5\xffH\x0e\xd3J\x8b*I\x80\xd0VaE\x8a\"\xbc&\x10\xa6s\x08\xe7sTe\x87 ,I\xb2^T \xdc\x86y\x1a\xa7\xd7E\xa0\x9f\n\xfa\x90\xa4 \x1dD*E;3}\xb1.\xcct>}(\x86\x1f\x9bi\x11W]\nR\xcb\x80\x9f\xfck\xf1\xe4\xda`\xdedz\xf8A^\xcc\x92\xd1\xe8\xc2X\xeb\xc1\xf3\xbc \x0dW(\x91}\x93\xde\x84y\x1c\xa6%\xfc)\xce\x92\x10)\x99\xd6WmJ\x8c\xdd\xb2(X\xe4\xe1\x8a\x14\x9f\xb2\x0f\xd9\x9aQ\x1a\xd1\x1f\xcc\x1f\x0e\x82\x01}\x16!OM\x9c\xae\xa4\xac\xeeW\xec\x0b\xb6bvaa\xa3\xd8\xa5\x8eS\xca8\x90`]\x15K7\xed\x10V\xab\xb35_\xacD\x9d\nW\xf2\xca@.\x0b\xe2tI\xf2\x98\x83\xed\xdd}O\xfd\x84\xb1\xe8\x93C\x1d\x03p\x1e}\xf2\xd4\xd8\x16e\xbf*\xe9M=?\xdaK\xec\x86\x0d\x91\xeb\xf9x\x0b\xc7'\x10\xc13\x10\x1c\xd0 D\xa3\x91\xbe\x88\xe2\xc8\x17\xb3H[\xc2\xa4io\xb6`\xcc\xb1Vt\n\xa1R \xa3\xc2f\x94|\xff \xb1\x80\xf9\x16\x8b\x97x\x9e\xccY\xd0\xef\xd4\x91U\x1c\xfb\"\x9b@\x89\xbbP/@\xa9\xec\x16\xb3,(\x83\x9c\x84\xf3\xf0*a@\x98\x1bi\xf0\x92S\xd8\x9a\xb4\xea\xdf\xe6q\xa9\xd6\xafKD}Z\x18&Iv\xfb\xefa\xb2x\xbf&)7\xbdS\x1bRk\xd4\xad\xb5>\xac\x9b\xcc\xd2\x88\xb8\x0eA\x83\xa8u\xf7r\xae[P\xc3\xd0\xf6\xfd=+\xbd\x14\x138/\xc3\x92\x04$\x9d\x13\xb4\xd6\xc9\x83\x94|)?\xc5\xd1gw\xc9\x86\xd0\xdd\xe9\xb2\xbd\x87%m\xcd5\x89\xf2\xccTb\"\xf3b\x8e\x18\xd7\xbf\xc7\xd7\xcb?\x87%\xc9\xdf\x86\xf9\xe7\x16 \xa9\x18\x06j\x86\x83\xfd\xa4\xa5$\xd5\xd4\x17b)w\xab\xde\xfdfB\x9e?h*sR\x94yvG\xe6\xad\xe1\x0f\x1e\xa2$\xcea\xa3\x15\xe7\x14G\xab |\x0c\xf3i\x8e\x98\xfaeP\x8f\x8d\xd60-D]Acu4a\xa12\x113@\xfe\xfd\xa7\xd0X\x9f\xd9&A\xabx\x1d\xdb)m\\p\xc9\xbf\xea\xa3\xfc\xb1C\x86?\xaa$\x11\x17\x16\xcf\xbe/\xdf#\xe2\xcb}\x7f\x13499\xda\xb3\xea\x8a\xec\xbb!\x8e=\xaetN\xd7\xb56\n\xeb\xa3\x8a7\x1c\xdf\xde\xc1\x9e\x01\x8f\xbf\x0d\xcbe\xb0\n\xbfv\xeds7\xde|\x02\xd2\x80\xcc\xe3\xd9\xb73\x88LZ2\x90\xb5\xfb\x87a\x10\xa7\x87\x1b/\xf0\xdf\x85A\x1c64!\xaci+\xc1J8\x93\xee\xa0\xcd\x19\xe3\xdb\x8f\xa8S\xc8\xb5\xb5U\xba\x1d\xf2-\xebg\x9a\x85\xeec\xf7\xdeb\xaeg\x16$\xee\xeb\x06\x96\x8c\x90>:\xf4\\\xa7\xc8#\xdd\xd4\x81\x92\xd3\xb5\xd0\xb6\xcc\x98\x1dI[\xfd\xe5:\x0e\x8c \xf4\xb8=\x8a#j\xca'\x06-\x08\x838-\xd6$*\xcf\xb3*\x8f\xc8\x90C \x08S\xe9f\xf96K \xc1\xa5\x87&\x12=\xb2Y`\xa4\xea\xa9\x8e\x10\x7ffn\xea\x83CYB\x07\xf5@q\xf3\x9b\x1e \x8a\xbc\xe8\xadm\x8c\x97\xa4\xcf\xaa\xe6\x8b\x8a\xd7;\x03\\\xa1\x92i\xb1\x8a\xe0\xd7,N\xdd\xda\xda\xd7\xc3\xf6\x90\xe2\xcd\xe1\xac\x86\x07p\x0c\xa1\xf8\xa9\x94\xc6\xcd\x818\x06wN\x12R\x12|\xefK\xaf\x14K\x8fF\xf2.\xd3[\xf56u0\xd2\xe2.\x1a\xef\x19e;894\xab\x90\xc1\x91\xf8\x08\xb9\xffot\x0d\x7fo\xc0\xb01\xd66_\xbd\x03\x93\xa2\xd9M\xdd\x83\x03\xcf\xc7\xf7\xe3\x86 \xb69\x98\x18\xaf\xe9\xe4@7\xf3\x0b\x8d\xaeT\x9f\xc9\x9d\xd9\xff''\x0b\xf3\x8b\xcb\xcb\x82$\xf6wx]\x8f[ \xcb\xe4%VX\xb7M&[\x83\x9c,\xa4\xcdh7\x13\x0dk\xe63\xb9\xd3\xf6\x14$\x96\xbc\x0d\x1ar!\x962\xc2\x88\xb6\xbc\x92>\xff\xf2/\xec\xf8\x1cC\xd5^\x1c\xfa\xea\x18\xca\xf6\x0b\xdc\x03\x83v\x1b\xb7 m\x97\xaf\xf3l]\x1cChX\xff\xec6%\xf917j\x12\x8f\xd9\xfbI\xb2]\x91\xc4\x1cA\x94\x93\xb0$\xaf\x12\xb2bn\x15}\x94 \x9e\xf1\xda\x17\xa25\xa2\x84\x9e\xc6*I\x0c\xb3\xe0o\xd4\xc1QZ\x83\xdfNY\xdc/\x1e\x14\xc3\xe4\x10\xd3\xc3CP\x03\xef\xae\xb9\xef\xc7\xc2\xf3!\x12\x85 3\x98\x1c\x01\xa1\xfb\xee\xf9 \x8bM\x03v\x84\x05\x1c8\xaeK\xda\xd5\x18\xf2Q+b\x19\x02\xa5\x8c\x810\xe6\xbb\xb7\xbd\x0d[\xa1v5]V\xeeV\xcc\x93\x11\xfd\x1fOZ\xcb\xb7\x84S\xd05\xe8\xb0\x03\xd3\xf6\xca0Y\xc7\xd2\x83*\x88\x96q2\xcfQ\xa4\xa1\xa1%\x94\xb9\xd2\xdaKx\x0e\x13\x13YQ\x0b\xb3\xe6\xc2\xac\xcd]\xd25bb\xac\x1bx\x06\xcb\x13\xb8\x19\x8d<\x98\xcfn.\xe4\xd1\xcdn`\x04S\x83\xfco\xec\xabc\x9a\xab'\xb05\x13\xee\x15\xc8=q\xe8z\xb5\x84\xe4\xc0\x97\x07\x8dO\x94\x9a\x16\xf1#\x9e\x8b;O\xdeD\\xi\x07\xee\xe8\x0et\x0cM\x08\x80\xe9ig\xee\x03c\xfc/\x0eP\x8a\x9e\x96\x14g7\x17\xc7\xaf/\xcc\xeb0*\xb3\xfcn\x90G\xa4v\xc9\x82\xab8\x9d\xbb\xdc\x07\xc9L8\x93@(\xd75/\xc5E\x10%YJ^\xa4\xf3\x8fL\xdc\xfd\x1f\xa4\x97\xb9n\xe6\x18p%\xbd\xcf\xa0,\xfd\x87\xdf\x03\xfa\x07?\xe7e\xc0\xa0\x8a\xcf4\xfb\xebB\x9f?\x1d\xc0f\xf0\xa2\xaa\x0d\x9brTd\x8a\x86\xdb@\x02m\x9b\xe8\x15n\xbfB\xc1\x03\x0e\xbb}j(\x12\xed\x9a\x8b\xb79\xd0\xa9\x14\xa03\x17@\x87\xdd\x9a\xfax\xc80h\xa9\xc3 \xb6\xde\xec\xe0#\x1e\x97\xcft\x0d\xb6\x0c\xef<\x0d\xdaT\x16h\xc3\xca\x15\x15\x11%\xb6T9P\x02g\xb0\xa6\xc5\xa7\x90\xd0\x7f\x8e\xc5/Z\xd7\x00\x9d\xee6\x84Nw\x1e\xac\x87@\xa7\xbb^\xe8t]C'\xbaz+\x06\x9dV\xf0\x0c\xeeN`E\xa1\xd3\xf5l\xa5B\xa7\x95\x05:)\x03\xba\x1et\xff\xf9\xddX\xfa0\x17@\xe0F\x95\x13\xd3\xc3\x1f\x17\x7f\n\x93xn:\xfe\x9bP\xa4\x8a\xbc\x88\x1d\x10AJ00&\xf7\xaa\x10\xc0\x7f\x80~\xe2T\xd2\x0e\x1f\x98Y\xc0\xdd\x83~\xa9@\x87\xb3\x03c%\xcc\xa0+wS\x8f\"P8\xe6\x87\xb0\x99\x8aq\xec\xfa\xc09%\xa6\xab\x8a\x8d\x04ef\x10\xd3\x0b\xc3R\xae!-H\xf9)^\x91\xac*a\x192\xb1\xc5\x15!\xdcK\x97\xcc\x9dn\x91|\xd5\xdfA\x94\x900\xff\x8a.B\xb3\xfc%\xc5s\xd0\x8c\xbe\xd6\xda4Et\xf9\xc6\x06\xc8\xc6\xbf\xcd(\xd3\xb5\x95\"\x880\xb4C\xf7\xb1)\xf6{\xda\xed\x94r\xa4\xec\x0b\xf5\x9a 9\x87\xd1\xa7\xd5\xdc\x1c\xb4l@8\x92l\xb5\x0e\xbd=\xb4\xdb\xe2\n,s[\x16\x10\xf1\xb0eg\x7f\xcdsHm\xb2\x04\xe9 \x9e\xc9?Z\xc4{\xa7\x80(\xad=\x18\xea\xfa\x03\x06\x95\xdb\x06\xa5\x1c\xde3\xf5\xe7\xb1\x04\x85\xa0w`\xb4\x8b\xca\xb6\x8a\xae\xa6\xa2-\x98\nu\xa6i\xfe\xd1\xfeV\xd3@Q\x0c\xb931]\xfe\xb6\x8e\x8e\xf9? J\xe4M\xd5\xeaY:9z\xe0\x83(K\xa3\xb0t#\xb4/\xc4\xb6}\x88D\xa5\xedmX\xba^\x9f\x96\xcet]\xb7\x166j\x96\"\x89\xd0]\x1b\xd4\xe28F\x83uC\x8d\x0f)\x01\x18\xd5\xfaerb;\xe7\xf8\x01\x85\x92\x91X\xd7\x13\x18\x8d\x12x\x86\xdf\xe0\x82\x14\xb3\xe4\"\xc8\xab\xd4\xb5X\xbc\x8a\xa5\x90\xbb\xec\xb9%\xc0%|\xec\x8e\x9a\xf6N\x865\xbc\x92\x0b[Jk\xbd\x1d\xdeP\x85 \x90\xf1d\xc6F\xe9\xa9\x95_\xf8\xc3\xbb\xb1\x830\xf1\xe4n\xd9\x864\xe2\xe9\x87^\xe2\xe9\xef\x08d\xb5\x83\x0c7\xed\xdd\xc3FC\x80V\x07\xc2\x1a\xa0\xbb\x03\xfb\xec\x8do\x1e\xf4\x05{\xe8\xbc\x89s\xbb*qQ\xa5\x92&3\xa44%%x;\x9b\xbbq\x15\x8b\xd3\xb8\xd6:\x0e\xe2\xf1(E\xc0hW\x03\xed<1`\xe9V5J\x1d\xdba\x01\x9d\xcf\xe4\x04Rx\xd6\"\xceO \xa5\xc41\x99\xa5\xb4+\x95@N5\xe28\xe2ZVr+\x96\xcf\xf3a\x82th\x0d\x05\xef\xef\x01\xa3s\x84\xeeR\xa1~\xe7\x92D2\xaf:=\xa6\xc4&p\x9bs)\xde\x06\xee\x85\xd2l\x1c\x94q\x89\xd6\x1f\xceU\x9e\xdd\x16$wh!\xff\xbb\x89\xba\x94\xde\xf0\xf0\x1bq\x10\xe6\xd77\x0c\x7f@\x1cp\xbbAd\xbe\xa4\xdfE]\x1b\xdf\xdd\xe0w\xf3\xf9OqQ\x92\x14\xdb\xbda/Q\xd9\xc0\xfe^,\xc4\x9f9Ye7D\xaf\xccJ_$\x89xQ\x887d\x15\x97\xe2\xefuN\xd6$m\xf5\xc4\x8b\xdf\xa7Q\xab\xddDj\xae\x97\xa1\x98]\xa8\xabw\x15\xa7\xf38\xbd\xeeVR\xe9T\xeb:\xcf\"R\x14\xf5\xc7\xb1f%\xedh[\x14\xdd\xce\x07x\xc89O\x1c\xed\xb3\xe5\x0f\x18\xd9&\\\x88\x91R\xe22y&\xc8\x81\xb3\xe1\xbd\xf9\xd3\xab\xcb7\xef^\xbfy\xf7\xe6\xd3_\xb0\xc6\x04\x9e\xd8V\x9a|)I\xda\x8a\x8bh[\x02\xa6\x9dk\xd3Q6\xf9-.\x0d[:7S-\x9f]\xe2y\x0d\xed\x04\xcf o\xd6\xae\x9c\xc5\x94\xc5\x9e\xa5\x17LD\x1a_|\xfb+$J%9\x9d\xd9]\xa5\x15\xd4\x8fYj\x8c=\xd35\xac:5v\x063n1\x95 N\xa3\xa4\x9a\x93\xa1\xa1\xcb(\xa7_\xf7\xa5\xbc~\xe0\xc6\x0fC[2D@3\x8c_<\x84\x85\xc7C\xe5.\xfdk{[\x84\xc6ce\xf8\xe7\xf66\xe4\xc2\x12\xbd\xd5\n\x1d_\xca\xde\xea\x9c\x06\xbeY\xc4IIr\xb7\xf3-IN(\x11\x17\xa2\x17\n\xfb\x06\xc11z\x0d, \xd4\xe3\xa740d\x0b\x08\xa1\x88\x96d\x15\x06\xf0F\xbcb\xf1\x0d)>\xc8\x16PT\xd1\x12[(Z\xc4a\xe0\x18\x8e\xe3\x12C\x1b\xae\xd6qB\xe6o\x9a\x95\xab8\x0b\xeb\x88\x018>\xcc.\xf4\x0f^}i\x7f \xd6\xd3\xf8\x01E\xcco\xc3u\x17E\nB0\xc4n\x90\xd1\xae\x80>l\xb1\x8e\x8dZv|\xcf\xc3j\xdak\xf0`\x9b\xf6\n\x8b0I\xae\xc2\xe8s+V.}d\x89{\xfdA\x07\xce\x17O:cW\xf1b\x86\xd7\x94\xf9P\x8a\x9e\x9a2C\x0c\xc3vw\x14\x90\x97\x0c\x90\x13\x83Z\xea\x04J\x86\xf9J\x0e\xbd\x1b\xc6W\n\xaf\xa8k\xff@\x12\x0d\xab\xe7\xc55\x9e\x16\xcb\x99\x90/\xb7\xf8+\x0c~|\xf5\xfa\xc5\xcf?}\xaa\xe5b\xa1`\x19:N\x848\x0d\xea07\xf1\xb5\xef\xf2\x80G\x01\xa4\x18\x97\xb6\x8e\xb3\xb1AyF\x9f\xab\x9c\x84\x9f\xdb\xaf\xba\x9c\xe1K\xada\xbd\xab\xc9f]q}\xa8\xa5/\x19\xc8\xfc9\xcf\xd2k`\x9e\x81\x08AD\x97x~\xce\x194\xe1\xbbP\xb3v]F\x01\xcc^\x81\x02vN\x0c\xd6N\xceM \xf3\xe5\x0b\xc8\x0d\xc9\xefz\x80\xa7\xc0\xb3\xb2\x1bN\xa8\x01*\x0dn\x9e\xd7\x916\x05XDn\x88\x83\xc6\x02\xdc,\xa7\x802N\xaf\x13\xc2g\xc8Mq=\xca\xa0\x95a\x9c\n\x98\xab\xbcm\xf9\xec!wA\x1e=\x8dl\xd3i\xd4\x81B\xb59P\xb8i\x9b\x81\xf4\xae5~q\x8f\xc9-\x84\xae\x01o1\xf4id\x89\x05\x1c?\xd6\x1d\xd3\x14\x11\x83\xcc\xa4\xb1M\x1bj\xab\xf8\xdb \xcaP2Ho\x05\xc6\xe4\x81Om\x16\xe9\x83}\xf9j\xcdl\xe9C\xac\x83\xad^},s\xee\x16\x06\xa1\x9b\xb2\xaf\x9a\x0e\xce\x0b\x8a$\x8e\x88{\xe8\xc3\xce\xa4o(\xdd\x0e\xf5{\xbb\xff+\x1d\xea\x87-\xeb?\x80\xd5\xf9\xb7:\xf7\xfb&?U\xe6\xdf\x12\xa7\x8f\xa3\xec\xb3\x9eC:@/+\xb7=\\7+\xf5\xf1\xa3&F\x1d4z\xfaQ\xcf\xd8\x91\x86\xda\xb8a\xfcJj\x19\xc3\xc1\xc8\xb21\xac`\xeaO8\xdc\x0e\xeeR\x81\x9e]G\xe6C\x1e\xaf\xe22\xbe\x19\xbcL*\xa1i\x04\x1d\xf8\xc2p\xbdX\xfc\xc5\xf6\x05a\xe5\xed#\xaeS\xb2FPW-\x16x\xe9\xcb\xfaG]\xed\xc1\xab\xddaR\xf7\xe0\xd0\x0b\xd8{\xb3@es\x0b\x06\x03\xe9\x8e\x1b(9-s=\x80\x08\x06\xf6\x97\x17o\x7fz%\xc2\xae9u\x82\xaa\xb0\xc8d\xdb\xc3U\x98\x7f\xe6\xa6?\xf8\x93\xc7V;mb%\xd1\xfat\xcd\xdc\x8a\xa7`be\x1ef\xb0p\x9bF\xcex\x02\x8c\xba\xa4\xc6b,\xf7\xa4\xe3\xf9\xf5\x90\xd7e\x95\x93\xf32\x8c>\x7f\xcaCth\xb4\xbc\x11\x86\x9cK9\x01X\x86q\x88\xb1\xac\xa05\xd1EYXhy\xbc\x8c\x0eY\xb2\xf6\xaa\xff\xca;,\x9c\xd8 \xe4HZ\xb9\xd5\xf2&W_\x8a\xb9\x0e\xa3U\xea}\x1a\x81s\x0c\x8e\x91f!h%\xd1\xb7 >l1\x07\x9dz\x1f(\x85C\x9a|$\xa6\xed\xd0s\x0b\xca\x94\xd6\xa0\x84\n\xbd\xf6\x026\xf7\x1d\x96\xcdK]\x95Z\x08>K\xdd\xe9x\xeaiV\xf7B\x01\x8a\xef\xf7w'\xe8\x88\xbe\xbf\xdb\xaa\xd7\xc8\xcb\xb1\xde.\xaf\xb7\xc7\xff\xdd\xe7\xff\x1ex\x92\xc5\xcbc\xc5\x9dv/\xc66(S\xcc\xda\xdc lCip,\xd4\xcc\xd6\xdc\xa9\xa5\x9ed\x00\xe7\xeeY\xeap3;Mm\xa0\xdd\x85!ru\xcd\xc4.\x17\x82\xcf\xb8\xa3Q\n#\xc8\xbd\xe6\x00\xef\x1e<>\xae\xce\xe3\x03\xfapV\xea\x11a\x89$%\x8a\x1e\xc4\x84\x87\xf7oE\x1f\xcax\xb9\xce\xb0n\x10=\x99\x05\x8c\xfdg\xf4\xe4\xea\x9bDO6\xdd\x8f\xbfOPa\xd3H\xf0ZF$N,7v\x91dY\xde7:\xcb\xd0\xe2\xe2]\xf8\x0e\x15\xce#\x14#\x8c\xe1\x18\\\xa1\xc1\xc81OZ\xbfD\xc1.\xaa\xe9\x0f\x10\xdcw@\xd5\x10\xb4|\xd4\x9a @X+\x18\xad\xb7\xba\xcc\x13xs\xf5h\xac\xe6_R\xe5\xb2!\x05\xdb\xf27\xfa\x18D\xd7]\xa6\x0b\xad1\xf4\xe4Nh\x0f\xc3\x1a\x9b\xdf6\x92\xdd\xe1#Ah\xb0\xe1`\x14E\xaf\xfc\x0c\x90N\xd6\x9dw0\x0e\"\x9b\x00\xb1\xa6\x12\xd8\x04\x1f\x0e\xbb.qoB\x99\xded2\x8f\x0dTf\x8f\xaefQ\xdaO\xc6\xbd\xb7\xce\x02\x0d\x1e\x15\xd6\xae\x8f^l\x85\xfc\xe2\xf2Z}\xf0\x0c+\xb62\x06VbNm\x19m\xea>\x16\xbe\xdc\xf0\xa8:\xa1k\xa4\xd7\xb0\xed\xca\x87\xc2\xe7\x99\xf0\x0c\x95(\x1e\x8efcC\x00\xe9\x04\xdf\xe8&G\xd9\xb0\xcc{\x1d\x9a/2+.\xba4\x9fZu\x83q\x80\xcf\x8c\x12xv\xbf\x96\xc5(\"\xcf\x98\x07\x00S\x1c\x17|X y\xc0\xe41\xf2\xab\xc2\x87)\x93\xb5\x9eu\xe3BhF\x96\xd4\xf8\x90q\x80\xfa@\xa0/\x16\xa9\xb1\x1d}6}\xc7Xn\x98\x91U\xbf=\x18\x15\xd0\x8f\xbf\x04\xc3.\x9f\xa2\xeb5y\xf01\xedo\x13p\xfd# \xa3\x92\x07L\xff?\x0e\xcf\x84\xec\x9c\xc0M\\\xc4%,\xcbr}\xfc\xe4\xc9\"\x8c\xc8U\x96}\x0e\xae\xe3rY]\x05q\xf6$\xa7\xdf=\x99gQ\xf1\x04?\xde\x99\x93(\x9b\x93>\x81\x9c\x999\xe6\xa3\x91\xc7,\xd5\x9d\xed0\xbf.f\x17X\x8f\xa4\xb4\x89\x9f?\xbey\x99\xad\xd6YJRY\xaf\x96\xc3\x08&\xba\xf2\x8c\xb5\xa1\x06\x7f\x17\xa2\x89,\x1f\x1e9\xbe\x89\x1a_\xf4\x87\x8b?i]\xff\x18\xe4\x10\xee\xba\xaa\x8e\xc1\xf4\xb83\xfa\xba\x0fq;\xacz\xdcs\xea\x06\x9d\x1b\x89\x82\xb2q4\x8f`\xe5\xebb\xf1I\x87\xf7\xcc <\xac^\xb8?\xb4\xff\x12\xeb,\xb7&\xc1\xb78(\x97a\xf9\x11[+\x98\xd8E)z\x1d&\x05Z>\xba\x18H[y\xf7)\xaf\xf8\xab\xb1\xfe\x8a+\x17r\x11\xcfW\xfdn\x19w\x9a\x8f\x88\xb9)\xf9\xf6\xb46^\xf0\x03>\x04\xa5\x9a\xfdO\xe0\x94\x1f\x94\x8d6P\x94v(\xa5\x9e|\xbf\xa5n\xd7\xf7\xf0iI\xe0\x8a 7W\xd9\xbcJ\x08,\xf2l\x05i6'\xc1\xaf\x85__D\xee\xf4\x1ah\xdf\xeb\xcd\xfd[X\x95\xcb,\x07\x80\xd7$\xcf\x8a\x02^\\e\xd5\xe7e8\x8f\x7f%Kx\xb6\xc0\xc2\x7fc\xff\x04Y~\xfd\x1c\x9e \x88\xd4\x94\xb5\x1a\x15\xf6H\x8aA\x12{\xf9\xa4uu\xb9\x1c\xaa\xc5?CC\\\xb4\xb2\xe4A\x93X\x0f\xef\x94\xf2\xb2\xbe\x10\xed\x98+\xd0le\x11|\xfa\xcb\x87W?^\xbe\xf8\xf8\xf1\xc5_.\xcf\x7f\xfe\xf0\xe1\xfd\xc7Op\x06\xd3\xc9\xde\xd3\xbd\xc3\xdd\x83\xbd\xa7p\x0c\x93\xf1\xd3\xdd\xa7{\x93\xc3\xa9\x96\xef\xd6\xd2ah\xc5\x95\x94\xe2\xa4\xc3yF_7\x86\x17\x1f\xc3\xf4Z\xf0\xc9\x14(%\xf1\x1cI\xd190Os\x865:\xcc+l\xb3p\x85\xbd\xd3\xcfqZ\x1e\nCc/\xb8\xbcDl\x7fy\x89!,\x1a\xf9\xea\xb1b*\x82l7o\x00}\x9c\xe8a\xe7\x18\x8c\xe5\xb8\xd3\xa1\x85y=\n\x1b\xc5\x06\xc2\x88\xcb5O\x80\x07\xc4\x97\x95 \x85\x9an\xa0i\xba\xbd6H\xde\x1b\x14\x0d6\x12\x0b\xeb\xb7\x15\x10\xcaN\x89MZ0\x1c\xc9=\x9d\x8b\xda,\xb9\\\x12\xe6\x86\xb2\x88\xf3\xa2\xac\x11?\xac\xaa\x02\xedgB(Z\xd1j\xe5G\x10A\xf6x\x08\x0f\xb63\x105\x01i\x0cr\x1c\xcb\xd6Db\xfd,\x0c\xaae\x0d\x89\xd9l\xe8;!\xb5Q\xe7\xcdm\x87BnR\xdf\x91~\xda\x9c\x89\x16\xcf-W\xe5lo\x03\x91\xcf\x83\xfc\xae\x1dK\xbb\x83\xedFW\xbf\xe0\xea\xae$?\xe1\x89\xf6\xd1\x0co\x0c\x98\xeb\xba)\x86g\x8d4K\xbf\xaa\xdfe\x8bEA\xca\xef\xe8\x11\xc8*4G\xbf\xca\xaat^\xd8vW\xef\x936\x0e#p1\xf7\xf0\xd8\xb3\xf6\xc3\xee\xdc\xf0~0\x00A#cI\xa5\x00n\xa7<\xf0o\x0b(\xd4F.\xd6*x\x81\x8fM\xc5t\x99\xcd#\xe9\x04L\xa4\x0b\x10\xd1\nk\x06H;\xaf\x8a\xc1\xd0O\xd9\xfdc\x93R\xb1\xc5\xd8tx \x1a>\xc7\x05\xad\xf3\xc9\xdf\xdf3\xe7P\xa7*\x17\x87][\xbfU\x04q\xf1\x8a\xc3\x0d7\xb58`\x7f\xe7\x08\xd0\xe2H`\x83!\x056\x94\x1a\xf6\x98n\x12H\xf8t\x0c\xf70g\x1bg\xf6\xd7\x02\x8e\\]\x16T\xa8d\x86\x8e\xb7y\\\x12\xd7\x02U\xd9'u\x96\x02\x97\xf9\x042#\xfc\xb1\x0f\xb1\xf7\xe8\xed\xf2\xfaL\x1f\xc5C\xd7\xb2\xa8\x15\xba\x141uH\xb3j\xd5\x08\xdc\xc3\xd2%\xc2\xe7\xc9\x166c\x08\x906\x9a]Iu\x82\xb8\xf8SLX\xda\xfdv\xb1\xc9\"L\xaa%\x8f\xb4!0\xdb\xa3\xad\xa9\x99-\xd5R\x0e\x11\x1dK\x1caX\xe2\x9b:\xd9f\xd7*pj\xb3\x1eIW(\xc2\x1c\xc3\xfb\x9d\x9cx\xb5\xa2\xcf\x8a Q\xbd\xe5\x84E\x14\xc7\x8eY\xc9\xc5j$a\x19\xa7\x93\xce*Wq\x1a\xe6w\x96* )w\xcd\xe8\x845\x82d^W/U\xb9\xd8\xe9\xac\xc1\x08\xed\xdeQ\xfc\xec\x96\x9eu\xc1\xa1\xe9.*\xa6\xdd\xe3\x89\x8a\x9d\x9e\x1a\xe5br\x90\x90\xbe:;\x1d\x95\xa0\x19\xf7\x14\xbe\xef^\xc1%\xf9\xd2\xdfJ\n\xcf\x9f?\x07\x83?\x114\xdb\x19\x16\xe4`\xaf\xbf\xa9\x1f\xfa\x16\xb2\xd37\x1c\xa0v\x0c\x19\xba1\xc0\x990\x96\xac\x86Ph\xf6SvK\xf2\x97aA0\x03\x19F\xa1k}\xaa\xebR\xcd\xe0\xeb\xa6\x8bc\x11w\xab\x9c\x11\x03\xec\xe7F\x14\x14\xfd\xf9\x02 \xe6\x83:\xbd\x93\x98*\x8b\xfe\xb8\x01\x01eM1\xf2\x05\xdb1l\xa3E\xdc\x92R\xee\x10\x85\x81\xdc?\x0eyNx.K\xe4\xce\xf0\x8d\"\xa2\xa3\xd8}\xa7.9D\x90F+Ie\x1ekp\x94\xfa\xdcB\x82\x852\xc6j1G\xce\xa5\x1ccQ\x88\x04D\xa5\xfa\xe5\x08i\xfd\x94\"\xc0\xb2#\x88\x82\x98e\xdc\xb9\x0e\xc0C\xe0\xc8]\xb7OF\x13\xf6h\\\x99\xc2J\x91\x86}\xda\x99\xc01\\k'\xcarB\x8c\xc2'\xde0\x81m\xa4u|\x8b\x9c\xc1\x86t\x1b\xf1\x85d\x10\xcac\xee\xc0\x19\x1e\x86\xae*\x8d\xe5\x0f\xe7Z\x8d\x95\x93\xb0(\xdfX>\xc0\xb9c\x12%\xfb\xec\x8d\xbc\xcbM\x98\xd4\x84\xbd`WD\xa0\x8a\x9c\x93W\xadP\x14\xe6\x1b\xad\xaf\xbf\x05\x98d,5\x8b%\xbc_(\x1d\\s\x8dB\xa2\x82\xcd[,\xa5\x16`\"\x05\x86\xd1\x18\xffM!\x01'\x04s\x0d\x8c\"=\xc4\x91\x1b\x17Za\x01\xc7ej\xd1\x8eTf\x95\x17\xc4,*\x91\xa0\xd8\xa7L\x18\xd8\xfc\xee\xbdWt\xa5\xa6>\x84\xf0\x04\xff-\xf8\xbf)\xfek\xb8o\xad\"M0k\x1b(\x1f\x06\x0b\x17U\x89\x8c]\xc7<{\xee\xcfo\xd2rr\xf0\xc3+\x97\xc0\xf7r\xb6\x11\xf1\x98\xef\xb9\xd5&H85\xda&\x8d4\x1d\xaaaN \x83g\x10\x9e@6\x1a\x99\x992\xe0\x9d\xe1\xf42\x0f\xc7\x1fQ\xf0\xc1C_-8\x1c\xce`\x07\x16\x9dr\x1d\xd1R\xfd\xa1\x88\xd2\x9dy>\xfb\x1cF|\x81\x8az\xdf\x16tA\xacMr \xbb\xc3\xc2\xd7\xb2\x163\xd89\xe5\xa3\xf1\xf9*X\x80\xb3}mR\x18A\x01\xcf!\xac1I\x08;P\xe08\xf9\xaa=Gf.\xdb\xd9\xe9\x9arM<'<\x88\xed\x9a\xf1\x80kx\x06\xc5 \xac\xbb\x16\x1d\x94\x85\x87\x11\xac=\x16\xa4\x97.\xfe\xbaw\xa5\x81\x9b\xc0\x98\xfc\xbb\xf5\x07\xe3\xeft\xd62\xcbq\x80\x0f1\xa9\xb7+3\xd6\xb3j@vt7k3\xe0[\xf5h\x07\xe8\x061o1J!\xdc\xdf\x9b\xf8\x18\xa1\x04\x97\x90\xb6\x81\xe2\xcd\x05-\xc3\x9b\xa3\x90\xe79\xc4x\x0chqLq\x01\xfea\xee!\xeb\x85\x9d\x19\xfc+L)/7\xb68r\x0bu\xe2\x92|\xe9P=\xe5\xf0\x1c2x\x02\xd3zh\xf8\xabK\xfeP\xb1\xb3W\xb1h\x87\xa3Q\xd5\x05>(\x9aX\x87yA\xde\xa4\xa5K\x82\xa2\xba*\xca\xdc\xa5|B\xe5\xc3\xd4\xf3ar\xd0!7g\xd4\x9a$(\xac\xccu\xcb\x19\xbdi\x98\x8a&\x1c\x00\xf4Dc\x83\x0e\xcde\xcf\xa1\xe1\x8d\xfd\xd5\xfd\x19s\nK\xc7\xc2C\x95\\\xdb\xa0\xd3\xd6\xd3\xd5\xd0\x9e\xec\x06\x03u\x9b\xb2\x11\xd2\xecB 8Q\xb3\xf2L\"\xc6\xb3\xed3\xc1Q\x19D<\xe4\xc4\x8b\xd2M{$\xfam\xc0\xf7\xc0dy\x9bL\xfav\xd8\xa4\x95\xb5\x19\xd4\xf0\x97a\x0d\xff\xd5\xfda\xf3A\x9f\x0fm{\x90VC\x0e\xec\xc0\x83\x93\xf2]\x93\xaeZ}\xb0\xb6\xb7a\xcbu \xc5NS\x0f9\x02~ \x19+!\xed_\xc5\xf9M\xcaO\xc3!\xcb\x84\x93R\xb0\xb1\x7f\xe0C\xc6\xb6=\xf6\xea?m\x9a<+H~\xf8\xda\x03\xff\xaa\x8b\x9fUY\x08\xf4\xe9TXL\xf4\xd5\xa7<\xc8\x0fw%\x91<\xa2[\x85\\E\x85\xfd\x0c\x1b\xd7\x8b\xaeq\xa5RL\xa1\x9af\x1c \xb2\xc5\x10\xf3\x18\x83\x1ab\x14\xddv\x81\xcd\x8c\x85\xf8\xf0E~\x93r\x16\x1bLS\xc5\x83N$\xc6L\x89\xe2A#V\xcaJ\xef\x1e\xc1\x19\xec\xc11\xfb5\xdd\x853\xd8\xe5\xbf&G\x138\x83)\x1c\xdbD/\x08\x91a\x04 \xad\x87[|\x83\xe1Z\x8c\xf8\xc5#\x8f\x8f\x81\x05\xf6kz\xe1kS\xc9p\xf4jY%\xcdh\xb2_\xcfh2\x85{p\xc5\x9c\xe4)Vt\x8a\xd3\xf1\xdeS\xfe\xdd3\xd8\xdf\x9f\x1e\x1dP\x92\x88\x92\xb3\xfbOw\xf7v\xbdo:\xff\xbd\xc7\xcf?\xac\x7f\xedn\xb0\x1ajYhY\xa1Cm\x85\xa4%\xab\xd4%\x0b\xe9\x92\x1d\xec\xef\xef\xee\x03\x06\xf4x\x06\x93\xc9do2\x99J\xcbd\x9c\xa2\x99$\xae\x8d\xb1(_\x84\x9f\xd3\xb6w}\xbc\xc9\x18tl!\xf7\xe7.(>\xa0?\x0f|\x11\xb5x\xc1\xc4\xa8c\xd8\x86\xc9x\xba\x0b\xf7l\x1397\xb3\x7f\xb0;\x1d\xc3={\xb5\xcd\x0c\xc2\xf9w\x1e\x05T\xa3SH\xda\x10\xdf\x06\xa5\xfb)\x12A\x8c\xd8\x15 \x14\xe3\x14\xbc\xbc\xafI>C8,\xee1\xc2\x13\x85\x1b\xf5\x16 \xe9.\x1c\xc7\x0e\x18s\xb32\x10\x04\xf4\x16\x06\xd3\xdcXz\xc0`8\xba\xc9}\xa6\x9a{\xdfCD\xa5\xedEv[\xe8S\xfeE\x82\xda\xb7\xbd\xf0\x81\x04\xe7Iv[\x97t\xef\xc3\xa8l\"\xab`,\xdc.\xbbBT\xdd\xb9#S\xa0\x837\xef\xce?\xbcz\xf9\xe9\xf2\xed\x8b\xff\xef\xf2\x87\xbf|zuN\xcf\xd3\xd8&\x8b;U\x93)\x9b\xcd\x82\xcc\xe5=\xb1\x13\xed\xf9\x8cn\xa4\x88o\x92\xc9\x92\x9e=G<\xb5\x02M\xb6J\xb2\xe3\xb4\xba\x96Y\x00\xd8\x81\xa8\xb3l@8H\xf1\xf0Q\xed\xb5\xe5G\xe21\xc3\x8e\x07\x1f\xf6\xa6\x9cVZd\x99\xebY\xc5\xa1%e\xc8\x98\xa5\xe9\xf6\xb6p\xeb\xad\xcb\xdc\x89\x0f\x13OR*\xb6\x8fjg\x0c4h\xe6\xb0e\x90\x9d\xa8\xe7\xca\xf5\xe8\xc9\xfa\xfc6\xfc\xc2-\xe4P\xc5L\xcf\xd4:\xcb\x92\xf3\xf8o\x14x\x1cN\x8e\xa6\xb4\xe82\xac\xae{M\xb6\xc1\xb6\xb1\x85\xe2\x0c\xa3\x1fo&\xd8\x1e\xe0u$\xb5\x1f5\xe9\x05\x0d\x16\x98\x1dBjW\x1a\x8b2F\xe3\xb9\xa237\xd6\xf1-\xf6\x93<\x9c\xcc\xf66\xff+@{U\xc2\xf3\xb8\xa9e\x17LbF_\x99\xc3\x9c\x16\xbe\xd6\x8a)\xe0)wh7S\xa3\x9d _\x1e\x98\x1a\x01\xc1\xcef\xab\xbf\x81\xed\xa7\xf8\x02Y>D4ca\xd6$\x1bB2\xf3\xbe3\x93\x05`\xde\xd4\x0f\x161\x0b\xea\x86\xc6\x86j\xa1Tb\x00\xf0}\xa7\x05\x17\xe1\xe7\xb4\x08\x17\x83\xe3\xafX2\xb5\xe9\xcdQl\xf1-\x9a\x94\"\xac\x0cjk\xcbmb\xa1\xdd\xdf\xc3V\x19\\\x8a&\x0c\xadG\xd9j\x1d\xe6\xa4\xcf!\x1bd\xf3\xca\xdar\x03\xdb\xd7\xf4QF \xd9\x8b:\xba\xb7P\xac\xb0/\x8c\xb6&\xcc\xf0Eu\\\xee2s\x90\x15{\x8c\x0d'\xf5\xaf\x98\xc5\xa1\xcfdN\x92\x99\xd2\"k\x98Q\x86\xde\xe2t\x8b\xc3\x98\xc5\x17xD\xc9,\xbe\xe8B\"\xa9\xe0\x1cY\xff\xad\x0c$\xf2c\x97\xddZ\x89>\xccw\"\x94zh\x8e\x04g0Q\xe2\xe1Bs^\x84\xf9k\xef\x89\x11l%W\xfe\x94-\xe5\x8fy\xc2}\x06\x06\xdf\xca\x84\xe3\xbf\xc1\x1ee\x80\x8d\xc3?\xa8\x01\x88) )\x0c1\xb3\x18L'\xf8u\xe6\xd5\xc1\xd0!\xb3\xa6\xbc\xfa\xceI\xe2\xa24\x99N\xf2\xe0{\x90-\x04P\xb0YQZ\x0c\x1f\x04\x01m\xa2\xb1\x11>\x98[S\x02$\x18W\x0b!\x0ca\x10\xa4C\xaa\x8b!\x89f\xe9\x85\x95\xdd\x12r)\x05=P\xbch\x86;f>IO\x1d\xa5\x8d\xc2N\x9cW\xdc\x18\xc5\xce\x06\xca \xbc\xfa\x9d\xf6\x8f>\x153\xe6FM8g|E\xf4\xd6\x9e\xb3\x08\xcd\xb9mEg+dg\x8fS\x98\xfb\xa0Pz\x12\xfa\xdc\x1a\xab\xef\x8a\xdbp=9\xe8\xf3\x0c\x17\x0c\x0e\xc6\x8c\xea\xd2\x13\x95F=\x91l\xae\xc9GRP\x12\xbb1\x1d^UI\x19\xaf\x13BWpr\xb0s\x15\x97F\xb4\xa8(\x1a\xc6'h\xbe[\x9e\xb0\xe37\xf5\xe0\x86\xbb&\x11Jm\x8dZ\xd9KA\"\xd1e\x17M\x10\x8b\xa8.\xcb\xee\xf4\x9b.\xcb\xdeW.\xcb\xee\xf4Q\xcb\xb2\xd7Z\x96]\xcfo\x8a\xe82\xb1\x7fLZ\xb8\x0dV\xeb`\xef\x9b\xae\xd6\xe1W\xae\xd6\xc1\xde\xa3V\xeb\xb0\xb5ZO\xcd\xabu\xa0\x15O\xd9?\xfbZ\xf1.\xfbg\xef\xf1kk\x8a\x1f\xd7\xb5\xbah\x9e\xdc\xb5\xc2\x8a\xa6\xa3\x8e\xaa\xc5~\xb6\x02\x08\x9c\xc1\x0b>\x9b1\xa5\xcc\x07\x84\x87\x92\xc7\x93wh\xf2\xe9F+\xf8\x07\x8d`\x98\xcd\x99\xb0\xfa\x1a#\xdb\xf4\\\x9eO\xe3Q\xe2\x0ck\x17\xfd\xa6R\xbd\x91\xda\xd4N*D3<\x8a7\xcda\xb69Y\xc1\x10j\x15\x06Q\xac\xe2\xe1\x9d\xbf\xd8\xa4\xf3.:W<\xbc\xdd_7i\xb7\x93:\x86a\x14\xb2xx\xff\x9f7\xe9\xbf\xd7v\x18\x9a\x86_m\xd2p\x075\x0e\x83(r\x18H\x95\xc3&\x9494\xb3y;l6\xbd\xc4:4v\xd1F\xc6\xfag\x1e\xf9Rx+\x1e\x83\xcd\xbd@~J\xe6\x8e8\x02\xc7\x19j6\x0dF\x9a\xec\x81\x8b\xe4\xd9dmA\xa5T\xa0N\xfeZ\x85Iw`\x170J\x1bzd\x0b\x122\x146\x9a\x9d\x88\x87\xe3\x80\xfb{\x0e,kY\x88\xd9/\\\x9bE\x9c\x16k-xr\x17f\xb2)F\x98\xffRK\xca\xdf9p\x81\x9f\x9es\xb3\xe9\x9a\xae\xa8\xddy\x10Fr\x7f\xc9`\x15\x96\xd1\xd2}\x12\xfc6}xr-2l\x80#\"\xe3\xd6\x8d\xf1\x10\x80,\xc8L\x10\x04\xe0x\x9e\x0f\xce3No\xd4\xe1r\x9e;]\xebb\x91'\xf5\x1a\xb5\x7f\xfb\xad\xd6y<\x05\xb3\xea\x9e\xdb\x0c!\xa2v\x84/\xc8\xb1^/\xaf\xed\xb6\xb4\x17\xcc\xd6,naT\"|\xdd\x11\x03\x8bv\xef\xefQ\x80\x83/b\x1d5\x9b)>\xee\x8f\x9e\xd3\"@\xfbh\xdb|sx\xce\xc7C\xe8_\x9dnBM\xfd^\x17\x02\xad1{-\xa4\x03|H\xeb\xbf\xf2\xfa\xaf\xb8\xfe\xab\xb9|\x83\xc4{\x19\xba\x0e\xec\xd0\xd3\x83!\xcd`\x87\x1e\xa7P\x96\xe8e>T\x1e7\xdf\xc0\x00\xc8B/\x18s\x15\xacb\x99\xc24\xbb\xe3\x13H\x98!\xedh\x94\xd8%\x80\xd1,a\x12\xc0\xc5,\xe9\x94\x00f\x18\xbc,\xe1:sZ\xdb\x0e\x83\x1f!\x01\xcc\xe0\x19\x1a!\xa3\x04\xb0\x82g\x90\xd9%\x802\x94\xc2(\xc2C\"\xbbI}q\xe3\\\\J\x91%\xd7.Ao[\xf7o\xd4\xd9\x9d\x1aR\x03\x03\xaavu\"\x99\xfc\x7fmG\x93\xce\x8e\xd0C\xdf\x0c\xc7l@L\x8b\xb9Y\x93\xb8L|$\xddt\x9f\xf3_\xadVj\x0f\x14\x1d@\x99\x83\xa6\xe4,J\xf9F\xad\x9b\x8f0\xc2\xe0\xb8x\x1d\xa7\x18\x97\xc03\x04d\xe1\xae\x92,r\x81p\x8c\x10\x84\x87\x0f,P\xc7\xcc\xe7\x91t.<\x16\xc9\x11\x92,\xbd\xa6\xfc\xaa\x88Fk\x0f\xa8q\xcf\x00\x85\x18D\xea\xc1\x19\x05\xcc\xac\xd8\x08\x899\x07Ay3\xd9\x9f\x89\xd5\x1db\x94_\xdb\x18K\xa8pGO\xea\n]\xacU,98\xc9\xc1{\x9e\xd7NM\"\xe2 \xe3\xef\xf0\xafA`_r\xeeeg1\xab\xca\"\x9e\xd7A\xa9\xec\xf1I\xf2:\xae\x805^\x86\x02^U'Q\xabJo\x08\xff\xc5/\xdbJ\x0b\x94c\xde\xf2^\xd6k\x18\xdb\xc5\xfb\xbc\xdc\xa0\xcf>\x8e\x8b7y\xb5A\x93_\xab\x8a\x80\xa6\xdb\xdb\x0d\xba\xed\xe5\xb1x\x9b_6h\xf3\x1fN\xd9q>h\xf0\xbd\xdc\x14Z\xf3o\xc4I\xd9,u\x01\x98A\x13s>\xd5\xbd\xa6\x98\xc2\xb1\xdf\xf9T\x97v\xfd\xdf\xf3\xf7\xef\xfa8\n\xbe\"\xe6\x1bJ\xdb9\x06\x11\x0c\xc4\xccr\xcc\xc32<\x06\xdd\x93\x0e\xe9\xa3&oFp\x19\xe6\xb9\x88\x0d\xe6\xf7\xc3R-\xf8*\x05,\xef\xe1\x14\xf6\xc6G\x07\xb6\x90q\xbfv\xe1l!A3I\x92\x1ec\x16\xac\x98\x03\xa3\xce\x97\xd9\x8c\x992@\xa2\xc1)js\xed\x0c\xe40\x87\xde\xcf\xff\xa8S\xfc\x16\x93{3drv\x1bDw\xcb&\xf5t\xb78r\x95\xd8\xa7\xbc\xc1\xb2\xa6+\xa9,\x82\xe3\xb0\xfbG\x98\xab\x1c.F\xe61}\xd3k\xb7\x9ce\x1dS\x8f\x07M\xfdm\xd7\xd4\x15St\x8d\xf1\x90\x877f\xc3\xcbk=^\xc659\xb1m\xd7\xf2Yv\x01#\x98\xee\x1f\xc0\xf7\x90\xcf2S\x90X\xd8t.\x9f\xba\xe6\"4\x12\x13\xd4H\xb0\xd8\x18\xf6H6\x0e#\x01E\x04\xef*NK\xbb}\xc7\x08\xc9 k\xdc\xb7O\xf9]\x9c^c`\x13Lj\x00W\xe4.K\xe7\x82\xf6ak6\xd0\x0b\xf7\xa5*\x82@\xa7\xc8\xc7K!\xbes\xd8\x18\x8ca\x80\xb8\xb0D\xc4\x0f\xb1i\xb2 \xba\xa8\xf1\xe3\x9fY\x03\x03\xe9\x91\xfe\xf4\xd8t\xb6\xe615\x88$t\xb0\xc7\xc1\x9c\x93/ \x8b\x17\x06\xae\xe8\x87\x1ef\x88\xd4>\xfd\x84\xdbS\xef\xe3\x86\x9b\xf5\x92\xca\xed\xd5\xadud\xaf\x17\x1f\xa6\xaa\xe1\x0ewG\x8b/\x00\xf5\x10\xdb\x18\x94\xe7\xd938\x84\xef)\xfd{\x061\x1c\xc3\x04v \xf6<\xb4\xd16\xbc\x184\xe1\x8f\x1bMxoz\xb4wt\xf0tz\xf4\x8df\xbdg\x9f5iOk\x17\xa7\xc5\x16c\xd0\xe4\xde\x0d\xbe\x1f_s\xb0lG\xb5\x03\x9e<\xfa|\xfe\xa4\xcc\xc88\x9dZ\xaer\x7f\xcf\x16`\xec\xb3\xa5\xf6!\xe6<\xae\xdc\xc6t\x97\xbd\xa3+\xb07h\x0c?>z\x0c\x87\x961\xecO\xd9;:\x86Cm\x0c\xf2\xafB\xa7\xeb\x86\xd8\xef\x08\xaf\xb8aJ\xeaS\xf8\xaf\xff*}=\x08&\xe1\xb9O\xfe\xeb\xbf\x88\xcf0\x05\x0bC9\xa2X\xbb\xbe!\xa5\x888RR\xc4^\x17\xe5^\x13\x92\x8c\xe5\xea\x92\xbe!\xe2\x1bR\x7fC\xa4o\xca\xba\x04\x93\x1d\x1b\x03\x985:\xcf\xda\xea\x1a\xd7\xc2\x1a s#\xf9IM\x81\xc1\x8e\x9eeE3\x86\x11\xec\xec\x101\xef\x13<\xda\xe3\x9e\xe9\xd2\x0f\xbe~\xc2\x87C\x00\x02o\x90\xd4s\x9c\xf8\x9a\x82\x83o\xdc\x90\x1e'\x07\xedc5\xa8\xd3\xa9\xa5Sn\xe9\x81\x8b2\xb9@\x9c?l\x1c\xed\xcd\xfe\xbaq \xb5\xa1\x0cf\xc88v\xa7\x8f\\\x8f=}\x1c\xae}A\xe4\xa2)\x16\xb18\x7f\x93\x83\xa7O\x9fN'\x94\x8b\xa8\xdf\xef\x0e\x1c\xf6#\x97\xaf5\xec\xd6\x18.D\xe2Li\x06\x93\x83\xf6\x14\x94Y\xed^t\x8a\xf0\xe9\xb0\xff\xd7A4x~\xca?\x9fL\x0f=.\n\xdf\xe1\xb4\xe3:\xbbu)\x95\x00\xdf\x03\x06\xf3\xec\x05\x07\x7f\x0f\xf0G\x94\x85\x91`[~q\x82\xe4e\x1b\nf\x1a\x14\xcc\xbb\x17)3,Rf]\xa4l\xc0\"}#\x90\x89\xbe\xd7\xf5\x89Gu\xde\xf7\x80\x11!v\xa4{0\x11\xa9\\\x07@\xd7\x0d\x80\xab\x15\x9a\xb5\xd7\xf1F\xf8UX\x81\x8bu\xedw\xa7O\x0f\xe8$S8c\x8c\xd0x\xf2\xf4`\x0c\xf7\x90\xc2q?\x05\xb2\x01\x8c~\xf4t\xd8$\xee\x15\x10\xfe\xfbM\xe7\xdb\x81\xfa\xcd \xbd\n'i\xd9to\xd0p\x87\xad\xfe\xf0\xe1b\xcf\xedA\x0f\x00\xee}\xc3}\x9dd\xa1\x01\xba?n\xb816\xd9(\x1a\xb6\xc6\x82\xeb\x1b4\x8co\xb5j\xadaL\x86\x0e\xe3\xc7\xac\xbaJ\xc8#\x97\xe3\xb0w\x1cc\xc1\x80\x0e\x1b\xc7#\xd7\xa3\x7f\x1c\x93!\xe3@\xe6\xd9\xca\xcdX\x848<\x9d\xa7\x82\xe0\x98\x15\x0b\xaam_\xea\x06\x04:2I=\x96t\xcc\xe6\x88\x12\xdbc\xfce\x1dN\x1fx!H\x13r\xba\x14\x94D\xdaB\x93\xac*#\"N\xa1\x84'\x1039\x90\x15\xbc\xd1\xca\x9dP\xac^I#\x99\xf0w\\\xc9\x14\xabXW\xd3`\xa4$\xad\xa6\x10\x9f\xd5+\xba\xb3\x13c\x808N*\x18\x964\x16K\x9a}\xb3%m\x11\x15\xdd\x16,\x86E\xd5\xd7\x92\x02\x8b\xfd}\x1f\xf5(\xd6|?\xb8;M\x06\\\xb7\xf4\x04\xb4\x96O\x197\xf9\x1f4\x11\x13\x05\xf2\xd5s\x99\xfaLr\xdc5\x9b3\xc3\xf5\xf0\x9b=\x9b\xb0=C\x11)\xa5\xa9>(\x1dl1\x1b\xfb\x91\x166\xd2>\xc9\xc1\x94\xf2\xef8I>\x1b}\x92|\xee\x86IN6\x9a\xa4\x89Z\xf9\xeaI\xee\xf9\x92H|\xd0L\x19\xcd\"f;\xdd\x93\xa6;m\xca'\x07\x96\xbd6\x1cg\xba2\x1f\xcd\xdb\xdfI\x16I+\xf3;l\xff\xe6+cY\x95\x89eU\xa6\xe63\xb3\xdb\xbd2\x93\xc1+\xb3!\x8a\x15\xd2cyY\xb6\xac\x06G\x02\xd4\xb7\xd0\x03\x86\x8e6\xcbN[\xb8%f\xa8d\xc7\xe0\xe6m\xb6\x07C\\lF,=Qz\x1f\x89\xc1+\x19\xdd\x08\x917wJb\x7f\nsL\x86\xdb\xe9\x84.\xf0\xcb\x10C\x14\xf9\x1a\xdew)\x96\xaa\xe0\xf9s\x18S<\x1a~\x13|\xb5!\x05\xf0?e\xa3;\xa8\x88\xaf\xdal\xb1\x17\x12\x81\x915\x04\xc6\xc6;>\xfa\xfb\xec\xf8\xefB\xa0L\xa6O}\xd8\x99L\x0f7\xa7Q\x14\x1d\x12]Z\xe6\x930\xf9\x1a\xfa\xe5w$_v\xa7O\x0f\xe8\\Q\x860\x0c\xb4\xff\x8e4\xcc\xefH\xc2\x04_K{0`\xca\xdd{;\x80\xc4QH\xa2\xaf\"h~Gz\xc6\xbeD\xea\xf5U\x8c$\xc4-\x1e\xb0\x8a\xff@\xc4\x8fE\xfe\xd4\xbd\x8a?i{\xd6\xe7U\xd1\xf4\xb4\xe9~i=M\x06\xf5d\x93\"uw\xf5\xe3c&e\x13\x14m\xd4U\xef\xac\xa2l}\xb7\x19\xdd\xd2\xa4\x9b\x1c\xa3Cd\xed\"\xd8\xd8\xd5\x97\x9a\xa7\x97\x94\xa5\xa41E\x90+\xd0\x0fI\xdd\"Wq\xe45 \x88\xce\x0b\xcc\xfb\xb2/\xbdS\xdc\x8a\x84\xd2\x0cP\x1eVO\x13\xa4\xcb\xf0\xa6\x0c\xf3kR\x9e\x97a^\xf6gC\xad\xcdx\x80\x19kj\xc30\xf7PdU\x1e\x91\x0dz\xc8\xbb\xc6\xcbZ{\x95\xce\xfb\xdb\xcaU\xe7\x8bz\xf5\xd5\x1d\x95\xec\xaf\x08\xc6^\xda\x916Jy92Z\xe5\"A\xcb\xf4[\xb99n=\x12\xc8\x8d\x1b*\x06]\xe6\xcaA\xec\xb1#$M\x0c,]\xc2\xe4\x04b\x9e\xd5`g\x07\xcd\xc2b\x18\x01\x03\x92\x14\xd6\xd1_\xa6\xb8/\xb5\x93\x11eA&d\x17X\x18\xaf\xcd\xb2\xfe\xb105\x9aY\xda\x06\xfd\x1b\xf3\xb9\x14\xa4\xac\xf3\xb8\x94\x8a\xa9N\xca\xcc\x9e2\xcf\x9c\x0bS\xe8\xfd\xba\x00\xc1\"\xc6\xf4\xf6\x1b\x00\x02\x83\xd3\xd5\xc6\x99\xadEz\x02\x0c\xa9\xc1\xd1\xa6vC\x8c\xe9s%\xb8\xd0\xfe\xc4\xe7Y7\xfa2#\x81\xec\xe2$\x07,\xb7Y\x1e\xd1\x87n\xe9t\xff\xa0F\xd4\x96\xf8h\xf6|\xabz\xb2\x19C><\x9b?{\x9d\xf1{h2o\xcb\xb2c\xbfj.\xe0\xdc\xe6Ul\xf3\xfch\xf5\xc7s\x97\x98\xf2\x9d\xf3\xc5b\xa9\x92\xacF\xbf\x1cF\xca\xe0\xe7\x19\xc3\x0dj\x91\xd5*\xfa\xfd`O`\x0c\xe7\xd1\xc4\xcf\xa3\xed\x9b\xa1Tf\x1bl\xe3\xcc\xab%\xba>SF{\xcc\x93\xc8\x8d}h\"{P,gL\x0bo\x87'\x06\x8b}\x04\"L\x93a\x01\"viB\x85\xb6|r\xacB\x96Q\xf8g7\x15)\xeds)\x01\xa6\xd7\x91\xbc\x99\xb2\xdc\"N\x95\xf9\x10\xd6\x13\xe0\xb6z\xe8\xa3\xacLB\xc0\xc5j\x96\xc1\xbfB\xb8\x81\xcd^\xd9\x8a\x91\xa3\x8e\x81N\xf6op\nOf\xff9\xfa\xe5\xc9x\xe7\xe8\xc5\xce\xff\x0bw\xfe\xb6sy\xf1\xe4\xda\xe6z\xf3\xba;\x84+\xa0r\xf6\x0c\x9c1:\xfd\xabiB\x8f\xb5\x02ul\x96\x0e\x7f\xb6*\x00o\xcc\x01\xda\x08\xf0\xa88\x13x\xd2\x9b\xe3\xb2q\x90\x89Ex~S^\x87\xee\x14*1\x0bl\xd3J\xec\xe0\xc1s\x8c\xe6\xbd/P\xf4\xfe\xd3\xdd\xbd\xbd.\x80\x1b\xf3\xfcp\xf6\x1aP_\xd2\xe7\xb0\x7f\xb0;9\xea\xabL\x1f\x96\x88b\x97\x8eggB\x07\xc3\x93ILw\x8f|\x98\x1cM|\x98\x1c\x1eu\x80u\xf1DYZ\xc6ie\xce\xa5$\x1e{\xf6 \xe0c\xaf@\xa4~\xb2J\xf5\xe4\xe7\x1fi\xf4\x98\x10\xaa\xb3Jo/\xdd\xd9\x95\xf0\x98\x1c\xecN\xad)\x04\xc53lU\xfc\xdfy\xc8)\xf7\xd18\x80\x11\xa5\xebvx\n\x82g\xcf`\xc2\x0c]v\xf8l\x8c-\x88\xb4\x89\x9c\xef\x190\x1f;&o\xeeo\xca\x12U\xf4\xdd3\xd6\xe1\x84eg\xe9K\x7f\xc0\x07\x93v\xcf\x83\xef\xdft\xbc7\xb0\xf7\xe9f\xbd\xc3\xf3\xe7\x98\xcb\x00\x03lcB\x83\x94\xfe\x9a\x1e\x0e\x1a\x16\xee\xd3\xb0q\xedn>.L\xba0\x9d\xee\xb1\x10\x1ep\x00\xdbt\x848\xba\x0d\xc6\xda\x03\x1aq\x1e(\x14!\x92\xb4&V\xd2\xdar\xf6\x99p\x86\x19X(i+\x93\xab\xfbu\xd6\x7fy\x8cw\xa6\xe3t'\x13>\xb5\x07\xbfS\xb8&h\xa8\xd4}\xea\x05,\xe8|\xd3q\x19\x90/\xeb,/\x8b:\x85\xf1\xe0\xd6\xf6\x0e5\x8a:f\xc5GZ1\xa5\xd3\x9cY\x86a\xf0y\xd0\xfb\x0b\xc7<\x02\xfb\x89\x15'\xa7\xc0\xefU\xc6\x8c\xae6\xfdb{\x1b\x90\x0d8=\x95\xee\xdd\xc3f\x93\xda\xdd\xf5\\\x16\xb1\xdf\x07'\xcaIX*~m_\xb1\\\xbbOw\x8d\xeb\xb5\xfbt\xcf\xb0`\xb4|_+\xafx\xf9\x81V\x1e\xf2\xf2\xa7\x9e\xc4\x0d\xd4\x07\xbbh/\xe6\x0d\x8f\x0e\xbac\xd0}\xa6\x1c?\x03\x0f\x9f)\xa7sV\xcfk\xad\n\x0d\xa2\x84\x84\xb9\x8b\x87\x9cX\xb3q\xddt\xa7\xd4FQ\x10)\xdd|6\xbe\xf0!\x9fMt\xbb\xff?\xb4\xffRd\xc0t\x0ctWT\x89\xd0\x9c$\x04c\xfc\xc4j\xf95\xa1\x102S\x0b\x97!\xdd\xd7J-,\xb0f\xe8+{_l\xb6\xf7O\xf7,gH\xf9\\_5c\xf8\xfb\x13HwvN\xda\xf0\x17\x05\xa8n9K/p\x01\xa5\xbc\xd1\x1aU\xc9K\xa5,\x9f\xe6+\"\x8ff\xf0\x90\x1b5\x92\x88y\xdad\xc9!\xf4/\xf2\xe8\x8b\xf9\xf4\xe81k\xd8,\xdf\xe5\xe5<,\xc3\xcbK\xe3j\xe4.\xf1\xe0\x0c\xd2\x99E\xbeW\x17\x1f\x83\xb3\x0c\x8b\xa5s\x01\xc7\x90\x06\xabp\xfd\xd8\xf9\xec\x8d-\xe0s\xa2_{\x06\x0e\xf0v\x8b\xa2\x8d`f\xc6D#9\xcb\xe8G!\xe5c\xc7<\xb1\x80\xb0\xc9d\xf7\xb1\x83CP#NH\xec6\xd2N\x8aY\xf3\xaf\x18\xeb\xd3\xb1a\xa8\x9a\xa8a\xd8Hmbbz\xbaY\x0c\x01q\xea\xdbb\x1bT\x12a\x14N\xe3\xb1s\xc6\xd8\"\xaa\x04\xe8\xd8\xe8\xbd\x81\x9d\x98\x1e\xb8\x9d1=l\x1b^\x17\xa7*XB\xf3\xa8\x94:lh\xc6\xd6\xf5\xd8\"\xc1\x0d\xc9\x0b\x8a'j\x0dS]TG\x86sn\xc6\x81\xe3u\xd7\x98\xd0\x1a\xb5]\x8b\xb9\xc6!\xads\xa6,{\x1bO\xa4\xe4K\xf9)\x8e>\xab\xb1\x98;bK\x82\xd8#Q_\x96B\x97\xb6\x08\x0f\x94\x8e\xba\n\xa3\xcf\xc6\x18\x0f\xa2%[\x98\xfb\x9b&\xab$\xb4\xc3J\x9b\xbf\x11\xb1\xb7\xc2.b\x1c\xa3&\x8d{\x02\xd5\xf6$\x80\x14\x16@\x81XI\xb7+X,\xb6\xd8\x93\xdf\xb1\xddb\xbd5}\xe2\x0f\xc0k\x86D+\xe7\xfa\xcd\xac\x83x\x1e\xfa\x86\xda\x93\xdb\xf1\x9b\x0e\xb5\x95{U\x7fzG\xdb\x93\x89\xf1[\x8f\xd6\xb7ir\xc4\xd35\xe0\xde\xd8Z \xcb\xc1\xe9}b\x1ci\x88\x16|\x8a\x1c6\x137\xc1\x83lV\x8dF\x17\xf2-\x99U\x1dq3\xe1[\xac\n\x8bX\xcc\xa5\xc4}\x0bb|\xdd\xc7\xe2? U\xdc\x801 N\xcb,\xda\xee\xde\xa6,\xda\x81\x89*\xc8y\x96B\x13y\x9f\xf5\x91\x8eqJ\x81 \x99q\xae3m\x14\x13\x0f\x86\xe6*\x9by\x86\xe0L\xeb\xf7R3\xe2\xaf\x98e{\xa3\x98\x9c\xa7\x1ek\xfe\xe4 \xb8\xf4\x02L\xa1\xa5\xa2\x84\x1c\x8e\xc1\xcd\xdc\x9cN\xcb\x9734V\x9e\x0f\x99\x1b\xb3H\xb0\xd5\xd0\xccr\x88\x1aL\x8a\xaa!\x01\x88\xd3\x8cc\x04\xde\x80gD\xe3\xa6E\xa1#\x1c\x9a~M\x19b/\xee2\xc5H6\x0fO\x1c\xab\xb8\x85\x01\xf8\xc0%5.1ghKYf\xe8\x98\x9fh\x9e\x13\x1a\x7fJ\x7f\x8f\x15?\xe4f\xee\x03\xb2\xae\xfd^so\xb6\xc6\xb4)\x03\xf3\xb7\xfd\xce\x83\xcb\xa5|\xa3\x1b\x93\xbafZO\xbeH\xa9\xbbwp\xe4\xb9\xce\"\xcb_\x85\x91\x08\xa5\xf5\xa8f%\x1e\xe0H\x17?p\x1e\xe0H\xe7\x0d2\xce\x1b\xe8\x10\x8d\x891\xf6\x9e\x1eJ\x8b\xe2n\xc6\xd0\xf9\x94\xfa\xe2 \xbd\x8d+\xdb\xca\xf4\xf1\x0c\xa6\x94~5\xd8)\x94p\xc6r\x15s\xf3\x8d\xd2g\xc9N\xab$\xa1'\xbcPP\xd7\xf4\xc2W\xa4#\xa8N\x0cy\xe2!\x16g\x15#\xd5\xa6\xa8P\x16v.N\xe4\xf0\x80\x91R\x19\xa1e\xa1Zv\x8b\x01\xd9##]\xcc\x93A\x1a\x12\xa2\xaa\x99 \xd3v\x05\x92V+\xc2_g\xed\xd7\xb7y\\\xb2\x97\xa1\xf2\xee\xc1\x87\x02\x19\xc7\xd8-\xe8\xb0\xe8\xcc\xa2\xe6\x90z\xc1\xf5\x90\xa8\xd3t\xc3\xf8V\xf9\xb00\xb3A\x96]\x89\x1a\xd3\x18\xf3\xe6D\xca\xe6\xecJ\x9bC\xc1\x99\x14\xba\xe8\x182\xce\xe1\xf3\xf7\x14\xae\xa5\xea\xfb\x149\x1c\xb9S\x1e\xc1\x87nh\xd4\x8cAz\xa3\x1d\x06q\x10\x8a\xe6 \x84\x86\x83P\xb4\x0e\x02\x8fa\xde\xde\xf4kR\x1a\xb7\xbc\xa0\xe5\x86\x9dV\x8fB\xd8}\x14Z\x89y\"\xbe\xdb\x11\x1d\x0ff\xc3\xf9\x16 I\x92\xe1\x1c\xdaD\xa9\xc1\x8f\xaf^\xbf\xf8\xf9\xa7O\x9c\xb0\xcc]\x0d\x0e\xb3 \xe7\xc70K\xdd\xfd]O\xcb\xdeO\xbe\xac\x938\x8aK\xfe\xfa)\xdd\x16w\x7f\xf7\x90\xff{\xe4I$\xcf \x18hgP\x05\x8d\x0c\xa9;m p./I\xf16\x9bWZ>\xd6AKG\xdb\x93\x05\\\x8a\xf5C\xea\xd6\x1abwz\xc0AI\xea\xee\x1eq\xaa;u\x0f<\xd7\x11&\x1b\x9f\xc2k\x01Z\x9c\x97\xe7\xe7\x1f\xab\x84\xfc\x14\x17\xa5\xff\xf2\xfc\xfc\xbc\xbcK\xc8\x8f$J\xc2<\xa4#\xa1e\x7f\xa2p\x85UHb\x92\x96\x1fIT\xe2\xcf\x1f\xdf\xbf\x95\xfff\x8d\x8b_\x9f\xb2\xcf$e?\xc22\xfc\x94\x87i\xb1 \xf9\x9b\x92\xac\xb0\xf0u\xcc;\xfd\xf7Oo\x7fz\x91$/\xb3$!8y,\xd1~\xbe\xce\xf2\xd5\xab\x84\xd0[\x8c\xbf\xcf }+J\xde\x92y\x1cbco\xe3\x15\xa1\xe8\x96\xa5\xe9}\x17\xae\xc8\xfc]6'o\xc3\xb5O\xff\xc5:\x1f\xc2\x98\xce\xe1\xaf\x15)\xd8\xd0?$\xd5u\x9c\xf2\x7f\xd8\x97\xe7\x7f\xfa#K&\x87\x15\xce\xff\xf4\xc7w\x88\xa5\xc5\xaf\x0fa\xb9<'\xd7\xf5\xcf,NK\xf1CZ\x85\xf3?\xfd\x91\xcd;\xcb\xd9\xa4\xcf\xd1D\x95\xa1sV@\x97\xfb|I\x08\xfb\xfc\x13eg\xf20\xfa\xfc\x92/x]\xc0~eU\x84#r\x82b\x9d\xc4\xa5\xeb\xf8\x02Z\x8cO0 ~X\xcb\x80\x8b\xd1\xc8\x04g\x11\x1e\xce\x8a\x8b\xf6\xbd\xa7\xe0%\x9fE\x867h0I\xe9\xf2E#\xf4V\xa14\xe6<\xdeJf\xd5\x05\x13\xd2%(\xf9\xa0@\"\x9bE\x94\xab\xc8\x02\\\xd7\x9e\x13\xaf3<\x14\x8e\xfe\xf6P[\x1am*\x96\x13\x02D\x0eH=\x1e\x86\xf5\xd0\x87\x9dI\x1f)e\xbb\xec\xdd\x94`m\"\xd7\x10\x80\x12\xf1\xf72L\xbf+\x81\x0e\x06V\xa4\\fs\xc8R0\xe6\xeaii+7\x1b$\x07-\x83Y\xca\xa9\x0d\xeav\xd2Y\xa8\xc7\xef\x13o\xa6\xbe\x1e\xa1\x87\x19\x16ZR\xa4s\xe3+\xb1\xe3B\xc8\x8b\x80Mlc\xd3\x9f\xa1\xe5\x8eF\x91\xbe\xff\xf4\xde1h\x1aeY\xcc\x83\xfa\xba\xd0^\xb7`\x0d\x1dl\xc9\xa9(w2=\xf4\\'^\xe4\xe1\x8a\xe8\x1d\x89'G\xe8b\x13\xab\"\x92$AA\xc1l0\x8f\x8bu\x12\xdeQ\xac\x97f)q|\x9c\xfb\xa1\x17\x84\xeb5I\xe7/\x97q2g\x99\xca\x83\"\xa7\x80\xd2\xf95\xbc \x8b(\x8f\xd7\xe5\xb1\xe33\xabV\x12DYZ\x92\xb4\xfcs\x9c\xce\xb3\xdb`\x9eEH\\zA\xb6&\xa9\x8bn\x03,j\xa7\xf3\x8c}\xfa\\T ^\x9f2\xc5\xf1\xb3_\x9e\xf0W\x98\x81)\x88\x92\x8cE\x8c/\xf08\xbd>\x81|g\xe7\xc4\x03\xae\x9a\x94t\x8d\xb3l\x96_\xd8\xad\x02\nWS\x89\x9a\xaf5O8\xcf\x94\xd7\x94\xa4\xed\xe7\xa7\x8c\xf0\x89\xabf\x04m\xdb\x0c\x93\xa2\x12\xb7\xf4\xfc:\xdce\xe8\x83\xfa\x9aK$)\xc68e\x0eX\xb4j\xe1\xaaY\x95\x08\xd2\xe0\xc7\x10\xbb\xa9/'\xe8\xed\x07\x87\x02}\xa0\xf7hDb-=~\xae8\x96\xf6\x01?\x9b\xa4\xabx\x17\xbe\xe3\x0e\xce\x1eW\x84\xbb%\xfa\xf5\xb0\x10\xa8\xa9\xb71\xcf.\x11t\xbb\x9e\xeb|&w\x85~\xf2\xd9\xa5U,\xcc7\x1av\x8e\xe1\xa3\xee\xc1\xc5?\x98\xec\xe7\xf1\xa34 #g\xce\xe5e\x94\xe5d\xe7\xd7\xe2\xb2X\x869\x99_^:\xa2O\xf3;\x8a\xe8\x1f;\xa1XL(f\x13\xfa\xed\xa1o:6\xc4\xe9DYZ\x94y\x15\x95Y\xee/\xc3\xe2\xfdm\xfa!\xcf\xd6$/\xef\xfc\xb8\xf8 \xce\xef\xfb\x85\xbf\xe6\xc5o\x8aW5\xbf\xe4\x97\xd9OY\x14&\x84a\x03_\xa0\x05\x9fc\x1e\x99j\xdbl\x95'{^\xb00\xcaTtQKf&\xf6\xfbV\xd6\xcc\x98\xa3\xcau+\xc6#\x9er\xdb\xf9\xb2\xb9\xc6\x18\xd0\x98\x99\xd4\xa0\xb8\xa5\x0d\xcdUfs\xcb\x10PA\xc8,\x94\x17\xbd\xfb\xb7!W9\x9d\x1cy\xee\x96\xec\xeeBq\xcb\xbe\xc7s\xde\xfb\xe0\xb0?\x1c\xbf\xe3\xb0\xa1\xfd\xc9%]\x8a:S>\xf7O\xbaD\x83\xaff\xc8\xbe\x1d\xc5I\xe8\x8d\xb7g\xb6\xaf\xe1\xed\x9a\xa1\xaebHvf\x17\x041@\xda\xee`\x9e\xa5*\xffI\x9f\x07\x06\xbc(\xe0\xc6\xe5m\xe66\x92\x8d\xeb\xad\x9d\x19&\xc2\xfb\x99X\xf7v\xc3[\xb071\xcb\x15[\x9cm\xebF\xd4r\xd7\x02\x89\xb7\xbc[]\xa4K\x08\xd5\xf1\xbb^\xefm2\xed:A\xfd[\xd5%d\xaf\xf3\x11\xff\x9c\xce\xc9\"N\xc9\xdc\xa1H\x84\xc9\x8f\xf8\xabwU\x928Fg1\xa4E;\x119\x0e8\xbf3\x94Jc)g\xc4\xe0\x98\x02QX\xa7\xe6\xd5\xf4\\\xe8\xd1\xca(\n\xbc\x12\xb1\xe7q\xac\x9d\xa1\xb0\x08\xb5\x00\x0e\xab\x80\xc3u+v\xca<\xcfFV\x03KBCP\xe3 m\xdd1T=\x80\xc1D\x02\x8c-\xa8?\x0f\xd3y\xb6r7\xdeM!\x92d\x86\x8a\xaeC \xc2(,]}\x17\xe9xK\x1f\x1c\xef\x92\xd2\x8e\xa3Q*\x92\x04q\xf8\xb1{\xf0x\xb4\xbbk\xbe\n\xfb^M\x8f\xb6/A\xee\xc6\x1c\\\xc7\x9c\xf4\xe3\xf2\x93\xc7\xae\x00\xdd_\xad)fA\xf4\x9bn\x8a7x^\x93\xddn\xaa\xe7\xa8\x9fS\xfd\xef\xa0z\xf6\x9fZ\xf0\xf1\xbe.\xf1\xcb\xcc \xaao\x12\xff\xbb\xf1\xf1\xc1\xc4\xb4\x00\xc1b\xc8>Rn\xc2^ $h\xdb\xe6\x92\x10\xa3\xad\xf3l\x15\x17\x843&\xa5+O\xc4\xea\xc5\xa4y\xb4\"\xd3$\xfdN\x0d\xd2\x9e\x1f\xc29|\xe0}Id\xa5=\xf3!\xea.\xd2\xdalX~\x1e\x04:\xceI\x91%7\x84\x03\xd0\xba\xf0W\x96\x858\xd7\xddZ\x1e\xbe\x82\xff\x98\xec\x99\xa5\x05\x93\xf1#O/\xb3?m\xb2JJk\xc5n\xc6\xffq\xd0L~\x04\x0e\xcc3R\xa4\xdf\x95\x98\xf7g]BN\xae\xc9\x97-\x8b\x8e\x94\x83\xd3\xaf\xba\xd0\xf4\x82b\x8e\xe4\xfe\xabiD\xeep\nO\x82'\x9a|\xc7\x88j\x9d'\xc1\x13\x07f\xe5\x85K\xb4\xbd\x128\xb6\xb5p0\x04o\x93Y~\x81J%\x1f\xb6\xac}@\x0f.7-\xef\xa6z\n\xf3\xe5'A\xa3\xfb@ e\x1b.Tn\xeaN\x0f\x0ft/\xdc\xb8~u\xa8\xbfB\xd2\xceD?\xc4\x01W\xc3 \x85\xd1\xf6\x08\xc8\xeb\xf7g=\xc0DPE\\\xe7\xa8\xed\xd8\xf1\xc0\xaf\xad\x84\x8e2\xd02\x90\xe0\x04\xcb*\xad\xbcFPS\x17I\xe2\x94\xb3f\x8e\xc7\x96\xa1\x9a\x0c\x83*+\x90\xe5\xc3\x91\xb6\x8c!\x9b\xf6\x0ckuWi9I\x0f\xd2\x11\x10\x93\xd9p\xd7N!s\xeb\x1d\xf3:\xb7\xccBPW2A\x9d)@\xb1s\x0f\xff\x1e\xfb\xb7\xc1\xd8\x87\\G\x82h5u\x0f6d\xb6L\x82\x9d\xd4\x9d\x1a\xc9\x9bC\xb3\x01\xc7dl\xf6CAi\xc6c\xc1l\xcc\x1d\x94\x98\xc0G\xfc8Eb\xf4\xb7\x0748j*\xfc\xa6[3:\x97l\xf7\xd0\xbd\x1bC`0\x0f\x84\x98\x87\x9f\x0e)\xf3[v\xb0\xb9U\xb0p\xb5\x08\x06\xbd\xd4Q{;\xb8\x00\xf6\x9a\x94\x92\x84\x89\x0d{C\xbf\x91\xdd\x03}K\x84\xcf\x90\x99\x12\xdd=\xd4\xad\xde\xb9\xcf\xd0\xa1\xceQp\x9f\xa1\xc3\xe9?}\x86\xfeA}\x86(\xaf\x94\xbaO=\x1f\x9c\xb7\xe1\xfa[9\xa1\x1d\xea\xde%\xdc\xebdj\xf6:\xd9\xdb\xd5\x0f ;P\xfa\xf1\x0by\xedG\xfb\x81\x18\xe1o\xc9\x11\x93|\xb628\x06'k\xe4\x0dR\xd5\x8a9\xba\xc4n\x89\xe7\xa1\xa4\xe7\x81\x82\x0c\xc6\xb6\x86\xfd\xc0U_3z\xae\x8f\xc6\xe3\xa7\x93\xa3\xa3\xe9\xfe\xde\xd3\xbd\xf1\xd1\xd1\xa4-nx\xf2\x9f\xee\xd9\xf1\xf8~6\xd99\xba\xf8e\xfe\xbd\xf7/O\xfa\xd6\xc0\xa2\x86\xc1\x10>|:FZxk\xcb%\xd2U\x13\xfa\x13\xc2\xb2\x9f\xc8F\xae13v\xe3hg\xeb\x94\xf9\xee\xe7AI\x8a\x12u\xba\x88\xb1\x84\x0b?\xcb\xffy\xcaC\x97\x96\xf0\xac\xd7\xefd\xc8J\xf5\xad\x82\xed$Xb\xeft\x0c\xf7T\nu:\x08m6\x17\xc2\xec\x84\xd5r\x1e\xa2\xb7\xe1\xc9/\xc1\xfd/3\xf7\xecx\xf6\x9f\xb3_..\xbe\xbfwg\xcew\x17\x9e{v\xec\x9em\xfd2\xf1f\xff\xf9\xcb/\x17\xf7\xbf\xfc\x12x\xdf\x9f\xfd2\xf1~\xb9x\xd2\xbe9O\xfe\xf3\x97\xdb\xef\x1fu@\xb8\x7f_\xa3o\xde\xd2\xc2\xdf\x8bm\xe8>A\x8a9k\xaa\x90bu\xc1U\x96%$L\x9b\x12\xc5Ik\x0bY1z\xbe*q\x9c0\xbaX&\xff\x12_\x10\xb6Cq*d\x88\x1b\xa9\xf9j|\xd4\x96\xe42\xf15\xb9!).\x9d\xf2\x13I\x03!\xe1^\x85_~\x8a\x8b\x92\xa4$o**\x855\xb3/\x8d\xac=\x84|C\xd0\xd5\xd9Xlo\xcc\x04\xda\x9a-8\xedi8\x1bD4k[\x00\xda9L}H\x83Wt-_\xad\xe2\xb2D\xdb{,k\x10\\\xb3\xf2\\\x0d\xa1\xbe\xd5\x16\xbd\xa9\xc3\xa9\xe3\xb7\xea\xfb\x89\xf6}A\xf4\x1av\xa8a3\xd1\x06\x91\xc9\x18\xdd\xc3\x99.\xd7$\x9cH%c\xeduV0K\x8cN\xabm\xf3\xb9\xf2\xd50N\x0f\xea\x8c\xc8*\xee\x8e\xc8 )\x11,\x96\xcd1\x8f&(\x1fsW\xbb\x06\xbf=Pr\x81\xd0\x999M\xd4AwK\xae\x16\xe0k\xee4\xdf*gF.\xedr\xe1\x97i\xa2\xd2x|\x0e\xd9\x14\x97b^\x91!9[\xb0\xb0\x1fb\xf1\x0dY7\xe9\xec\x17\\f\xc7\x1d\xf4~N\xa3\xb0\xba^\x96>Ti\xb1&Q\xbc\x88\xc9\xbc\x9e\x1b\x0e-\x00\xf7;\x9e}\xd7\xf1L\x927\xd6\xdf\x82\xd9t|)\x99 \xefB\xa9\xf6\xd0Z\xe3\xac\xc9\"\xcaW`V^\xd8\xc1.\x83\xcb\xa9\xe75\x0e~\x9a\xed\xb9i\xc9\xba\xfc\xf8\xd2&G\xbfE\x9ah \x7f\xd2\xe5\xca'5\xea\xab\xfb\xb4y\x17\x16\x17r\x82\xde\xb8\xaa}\x92\xb7,\"\xdcD4\xdb\xf6\x91\xed\x84\x92=\xa0J\x813)\xb9\xadG\xbf\xcd2\xe8!\xdct\x1d\xe9\x8d\x83\x0c|\xee\x92@\x0c\x89\x92\xfc\xcd/$\x87}\xfd\xfa2\xae@\xbb\xd2\"\xcaaS\xc4\xc2\x06\x11\x91\x9aOn\xe0\x14fZ\x91\x0f\xe4\xc2X\x91\xf8\xa6\xcet\xb0J\xbb\xbb\x0d\xf3\x94\xcc\x81\xa5\x0b8\xa5\xc8\xbb\x85ZP\xdbjD\x9b\xc7\x06D\x84\xddT\"\xf6\xb0\xde\x1d\xb7)x\x0e\x15vi\x19\x0dsa\x88\xb2\xb4\xc8\x12\xc2\x80\xbf\xeb\xb8i6'\x1e\xd0*\x18>s\x9d\x15E|\x95\x10P\xc8\x84\x15Ye\xf9\x1d$$\xfc\x0csR\x92\xa8$\xf3\x00\xfeu\x0eI=\xeap>\xa7e?\x17\x04\x08\xfbJ\xc7\xf6\xae\x07e\x06q\x1a\xe5\x84\x02\x9b$^\xc5e\xe0\xb4\xb6\xb4\x89\x93j\xa4\xbf\xc4\xf8\xcb<\x8c\x90\x08U\n\\\x91\x0e\xc9v\x932\x14i\x98\xaf\x96^\xb3?\xf9\xf67\xbaY\x82\xc2\xa7(Hy!\xd1\x95&dS25\xd2*\xbb!b\x0et\x98\xb1\xc7\xe3\xbb#\xc2\xa3\x9bNT\xf0#\xa0Y+\x82\x92\xfcKXi57\x10o\x00\xf6\xc9\x96#\xeeYkud}kyS\xfb\x7fQB\xe9w\x81`\xd8\x8c\x0e\xbf\xf4\xcb\xdb\x11w5^\xb0\xfbl$$j\x0c\x901a\x1a\xddQ\xa1s\xcc\xddT\x02k\x94\xea\x97V\xf5\x14\x83\xbdr\xd9T\x0b\x16)\x90T[Q\x15\x98\xaa/\x19<\xd5\xe3-\xab\xb8\xd0p\xa4jlX\x9d@\xb8\xb3C!\x8e!&\x0d\xf0\xc5Hg\xe1E3K\xfa\xab\x99\x17\x9d\xa5R\xc0'\xda\xeeS\xf5\xdf\xc4\xfe\xab\xf6\"I\x86\xf1Vf]{\xebz\xf4\\\x85\xad\x8e97!\xecYf\x1c\xddm\xf3Lg\xf4Q \xa0\xe3\xdc\xed\xed\xce{\xd1\x1e\x92\xb97\xebA'\xe8D\xaf\xccX\xdf\x1en8 \xb6\xb0\xbd\xd0nGLs\xdb'z'\xda\xf9\xc1\xe5\xd0`+\x18y\x9a\xdc\xc2\xd3X0\x83\x1e\xee\xbe Oi\xa1\x8bO\xea\xbbqbotV\xdf\x99\x1dh\xf1\x1d|%\xba\xb6\xd1v\xa8\x93Ag\xd9D\x96\xb6i$\x16'I\xbf\xc6g-\xe2\xcf@\xf9 \x1a\x1f\x8eav\xd17\xd6\x97Y\x95v\x0b\x04tv\xdf\xa6\x1e!\xed\x8dm\x9f\xb3\xc68\x83/\x83!u&z\xee\xd4\x15\x84\x05j?\xbc\xd1\xb8\x11\xfb\x0c;\xc2\x85\xa9_\xf5\x0b 5q.\xcf\xc5!{\xbeO\x0e\x9fz^p^\xe6$\\q\xd7\xdd\xe0# \xe7\xe1\x15Z(\xe0\xef?s\xbfg\xf6\xc1\xe4)\xfa\x86\xfcX\xad\x13\xf2\x85\xa9C1MLP;\xf9\xb1zGS,\xfd\x10\x16\xc5\xa7e\x9eU\xd7K\xa6\xfb\xd8?\x1c\xa4\x83\xed\x0d\xd1d\x0ett#\x92\x99\xb9\x18\x07MyW\x93\x7f\x06\x95?h\xc7\xc4$$\x89\x0b\x8c\xb4\x02\xc2o\x83!\xa1\xb4\xcc\xef\xd4\xa2E\x9c\xc6\xc5\xb2\xcf\xc7\x87>[\x9dK\xa0?\xb5\x96\x8fujG\xed\xa52*{=\x0e\x93r\xa3NQ~\x84\xd6%\x0fD8({\xa3\x80\xfa\xdd5I\xe7qz\x1d]\xed\xecP6\x8f't\x81\x1cW\xd0\xfam\x9b\xf2\x10\x0f \xa2,\xffL\xe6\xdcc\xb5x\x9d\xa3]\xac\xa9XlRIy\\\xd3g\xa7\x86\x00\xa8\xf4y@\xb5\xb7\xc1V\xa8\xe3r\xcb\xb7i\xd5fCB\xee\xe4N\x82\xab<\xbb-\x18\xf12sn\xc6\xc1d\xec\xf8@\xff8\n\x9c\x8b:\xfaW\x13\x0f\x8cA\xc9\xb1\x0f\xfb\x1e\x8f!\xcd\xbci\xb2:\xda\x8f\xda\xdb\xaa\xbe\xa6\xe7e\x88Z\xd9\xeb\xf6pP\xc8\xe2\xee\xeby\x04\xa3 N\x97$\x8f9L\xd8\xd5\xd36\x08\xb1\xa3\xf9\x90\xcc\xc9:'QX\x92c\xbc\xdeO\x0d\x0b\xd8V\x85'\x1c\xfa\xe8z%\xfa\xac\x99\xc6i\xec\xf1\x906\xed\x1aK4\x81h\xf2\xa6(\xde[\x1e\xfcfH\x0c0\xf7\xe1\x86\xf7i\x07\x0cw\xf8\xb1\xe5\xe5\xb5\x114\x03\x97\xaf\x85H\xb23X\xc8N\x1f\xaaW\xda\xf7D\xdcb\"\x0b~\x0dt:\x82\x12\xa6\xe5x\x9b\xcd\xd1\\l\xab\x94\n|\x16V\xd7m\xd7\xd3K(W\xb6\xc5\xfc\xf1\xe8\xf9x_\xbf1PZ\xb5~5X\xc6\xd7\xcb?\x87%\xc9\xdf\x86\xf9\xe7\xf6\x16\xd0'\xc2\x8a\xa2\xdd\x7f\xef\xff`a\x18\xdd\x19L\x0e\xe0\x18&\x07\xbb\x87{\x96UP\x86\x02\\k\xcbh\xd3\x18\xce \x86c\xbe\x16Q\xf3\"\xa2\xe4H\x04\xc7\xb0\xf0\xcd\x8d\xc8\x19\x15[\xef\xbd\x06\x94\x87\xc9\xcb0I\x98\xc0g\xe2\x0b4@\xe6?\xe6a\x9c\xca\x85\x0c\xe2i%\xeaw\x0c3\xa8esR\x94yv\xc7\x0b\xcd;\x92\xe0;\x9e\xe7fN\xa2l\xce\xbd\xablxJ\xa9C?N\xea\xdePB&R\xc1\x00kP-\xbb\xbf\x07\xa7*\x17\x87B\x98$spX@w\\\x9b*\x03\xb3R\x9d\xe2.\x8d\xb8\xb8\x04\x7f_\xe1U\xfe\x90g\x11)\n\xed\xe3,E_\xd1N:O<[\xdd\x94\x92\xfc\xdc41Moe\xd8h>\x9b\xe2\xc9\x99 \xfa.\x8d\xba\xeb1\xf7f\x1cxteG\x87\x94\\\xec\x9f\x95xJ}mE\x07\x0d\x85Q3\x07\xe2\xee\x91\x84\xa4\xbe\xf4\xb7\xe2\x86\xa5?\x0f\x88\x8a\x89g =\xba#G\x8aggGB\xee>\x1a\xe0\xbb\x0dNrc\x1fr\xcf\x97\xb0\x94\xfb\x8as\xe4~k\x1f\x98\xd0\x94 E\x85<\xb5\xe4\\=\xd3_\xd1\xc60f\xbfO\xc5\x1b\xcf\xf3!\x91T\xc5\x83\xf6\xf4R\x05\x8aL\x8en\xdae\"\x1f{\n>\xa4\xbbQ\x89\x9f\x1c\x9e\xa3\xe6@\xc2\x8b\xe8\xbc$V\x8aBN\"0!K*\xc1\xde\xb8\xac\xf7\xe6\x9d\xdc\xcad\xd0l\xae\xa4\xd9\x98&\x91B_\xf4\x03\xf1\x88\xb8\xc6\x1c\x07moc\xf4QA\x0ca\xda\x9b6q\xc4!\xf2\x9c\x969\x06(\xfc\xe0\x96\"\x86\xa5\xc26\xe6n\x03\xbb\x07\xcd\xf3\xd6:vb\xa4?\x0c\xd9\xb4\x04\xcd@t\xd0a\x16\x04\xd5\xdb\x87\xf2y\xa6\x8a\xa0\x98\xcf\xb6~5\xf1o\x84Lv\x82#\x069\x92ln\x89\x02\x02\\\xeao\xe2z\xcd\x98(k$\x05\xe6\nu|\xad\x90\x81\xcd\x82\xad\x1b\xda!\xc7\xa8\xae`&O\x98^\x0e\x95d\x05\x0b\xea\xc6\xa3^\xe0j\xf8\x10\xc2\xe8\xd4$L\xa3\x0f\xc69e\x88\x00\xcd\x7f\xfd\xfa\xf6\xb1\x1bSg4\xf3\xc1q(i\xc1\x10\x80z^F#\xac\xda\x81R\x18IB\xc9\x15\x8bP \xe3c\xcdd)\x8fg\x17\"0<\xc1\xce\xad\x0d\xcf\xb4\xcfz\x17\x05!d\xc4\x9d\xf2\x98\x9a\x8f\x0f\xa2e\x95Z\x18-\xf1\xa0\xb1P \xd29v\xd7M@\xc4\xeb\xe9\x16\xf0\xd0s_\xef\xd0\x04!\x93\xc2\xcd\xc11D\xf5\xa6E>e\xc0\x12\xed8\x98\x17\x8c\xde\xf9\x1a`z\x1b)\xa8\xe8S\xbb\x88\x0b@d?\x0d}2\x1e\x90@\x86\xf2\xado\x81$\xc3\xe0\xf0\x97n\xff(\xc1Abtx%\xab\xb10ld\x85\xfa\xb8\xd0d\xa2\xe1-\xd9O\xbe\x8c\x83\xc6un\x85\x9b%G\xa7\x0d\x0bc\x95Pj\xc0\x1b7A'\xc6SviU\x1aN\"\xda\xeb7\x8e\x05\xf2\xd3\xe7a\x182xe\x9d\x94\x80\xf1_\xbatM\xec\x10\x0d\xe46\xd59\xdd\xdf\x03Q$\x07\x14,Z\x88\x17N\xad T\xd2\x80\x99&{\x18+\\\xd59\xe7\xaa\x90;\x1a\xb8\xa4]\xa8W \xf6\x86\xe6fw\xc8\xd2j\xd3\xa4/\xd9\x94C\xeb\"5\x92EJ\xf2R0p\xad:\x8a\xd4A\xab;e\xe55\x16*\x85\x00I\xbb\x03,\x98\xc8\xec\xe2\x04\xca\x13\x8fN\xa3*\x96,4 \x12\x82t\xd9\xac;\xadyy\xb7\x81d\xaf\x18\xdf\xee\x96J\x1f\xee\xe6\xc4\xfc\xd7\x84\x9b\x93{-{\xac;l:\x8e\xc9\xe5J~0\xcc\xe9\"\xa8%\xae\x9b\x05|\x97U{\xf5\xd2\xbbv\xde\x10\x18\xc7\xe7hL7\x1b+\xc4E#\xf9\xe5\x96JZ\xc5f{)wC\xc2y\xe0\xf8\xe0\xfc\xf8\xea\xc3x<\xde\xb5\xa4F\x83\xf6\x05\xaf\x8b\xed.\xbb\xf8\xda\xb5\xb1\x08\xdc\x13n{\x9b\xff\x15,\xc3\xe2\x0d\xe7\xb7\xc0\xe6\xd3\xf8\x9a\x97IQ\xc7\xda__\xd0\x8bK\xef\xc6\xb0\xda\xbe\xe5,\xac|\xc3\xc8:\xdc\xef\xfa\xe5I\xb5#\xcc\\66-\x1b~\x93\xde\xf6\x15\xf0T\xcd\xdb-\xc9\x8a\xcc\x8f^\xf7a\xcb\x07\x84B\xf3^\xf1]\xedG*5^\xb6\x94\xf2>\xac$\x10\xb1\x8e\xd7\xa4\x0f:0 \x80\x8ah\x9a\x1c\x8a/\xc34\xcdJ\xa0\x0d\xf9\x18\xa7>\xe7\xeaM\x9d\x15\xd1zn\x8b$\xed\x1a:$\xebY\xe4Y\x03cn&\xbb*\xc6\x1e\x19\xdfa\x80\xe4X\xa6\xab\xea\x84\xfb>\xac\x9b\\\xce9nh./\xe8\xd2\x8e\xd2B$\x0d\xd6J*h\x91\xd9|\xf0\x91Zc>\x01\xdd\xfb\x13\x80\xe7\x10\xb4\\A6\x81T\n\x0eM\xa90\xca\x17\xb0\xf0\xd3\x02\x00Rj\x1b\xd1%sr\xd5$\xd3j\xeb[R\xf0}\xd1\xfa\x9d\xe7C\xcc\xe5\xeeg\xc3p\xb7\xa0\x06\xa4#\xc3\xb6>\\\x94$\x07\x92\xcem\xc1*L\xd4\x8d\x84\xa2\xf1\xb0\x98V \xefb\xca\xc3^\xeb\x9c\xb7\x9dK\x07I=c\nZ\"\x9e\xca\xa2H\x00\x89\xb8iH\xe53\xe6\xa9\xa8\x06\xe8\x7f\x1b\xde\xe1Ua\x0b\x81\xb5\x11\xf4\x14PfP\xa0\xb1\x80cM\xd6\xdf\x04\x05a= 9\xa4\xaa\xa3\\C\x9f\"\xd7i\x9a\xa5;\xac\xd9'\x1c\xd3 \x9f\x83\xc1\xbf\xb9A\xae\xb6\xee\x95\xba\xee9+\x89\x05\x1f\x1a[\xf7 f2S\xe6\xe6\xe7\xc6*\x01V\x19\xee~-\x0d\xb2\xed\x0f\xdaq\xf5*\xf1MM\xf7!\xf0R\xd7\xe8\x19\xd5A`\x8e\xdd\xdf\xdc)~}\xb1\xc7\x1e\xe9\xb4\x91<\x92\x9f\x87\xda\x08\xc3\xdeP\x8e\x06_U}A)\x11\x19K\x17\x9e\x99\x05T\x16\x8co\xbd\x03!J9Z|g\xde\x99Y\xaa\x16[\x8d\xac\x86\x91\xb4\xed\x02$ \xd73 \xaaf\xd0\xfc\x1d3\xdd\xd7d_c\xcb\xba\xa0\x05Q-\x18\xc4\xeb\xc1\x04\x0c}\xe7&b#k\xb3\xb5\x1d\xfa\n\x0b\x17\xdc}\xd8\xf0\xc6\x1d\x83A\xf3.?B\xacp\x0cq\x8f\xaa\x8c\"\x1cc\x1c~\xf9\x11\x92\x07c\xee\x05\xf9\xa17\x9d9;\xdb\x8f&\x0b\xd2\x1f Q\x8ey\x19\x8e\x8dL\xbe\xb1\xaeU\xc83:\x85\x89\xf9\xf02I\x8f,) \x1b\xf8\xd1 \x9e\x8b.\x88\x152\xce\x0f/\xb0/\x85\x82\x836 CO\xd5 \xe2I#\xdc\xd9i\x1c\x8d\xba\xda\xae\xd2!\xad+<\x9b\xda\x8bA\xa7!4a\x0c\xc8\xb3\x1f;;\xbe\xa4\x15\xa5\xe4\xab\xa4/\x93\xa4\x1e\xf8\xcb\xa8=k\x0bL\x98\xf6\x8c\x93\xc4\x9dD`A\xca\x1f[\x1a\xf3nZ)\xb6\xa5A\x14\xa4V\x19\x94\xd9O\xd9-\xc9_\x86\x05\xf3\xb0\xd8rg\xce\x92|\xa1\xdc\x11\xd7\xbb\xd3\x7fw\xf0\x8f\xb0\x88\xe2\x98\xfeq\x15\xa7a~\x87\x7f\x85\x059\xd8\xc3ZQ1\xe5\xff\xeeL\xf9g\x93\x83\x84\x88\x16\xc4\xdfyx+\x19\x19\xb9,\xd3\xa2\xa7\x8d\x03\xad\x8cp0\xb59\xe2\x90\xbbm\x8d[\xc1,\xae\x9bt5\x12{@ \xccM\x98 )\x10\xf7\xf6\xb6\x1c\x98\x8e\xb1\xb8\xb5\x8eZ\xc8\xbcr\x19\xde\xe4\x8d \x8bP\x1e3\x10\x8774\x17\xb2Y\xcan)@g\xc8J\x01\"\xe2\xc6>h\\\x0b7\xfdZX]\xb7y&\xd3\xb2)\xd3\x04fiDj\xa1[\x07\xe9F\x1a\x93\xa3\xb1/\x99f\xb5E\xd4 !\x95\xbc\xc5\xa8\x0c\xbc\x82\xb5\xe9\x92\xf1\xdamt\xad\xe4\xdd2\xa8\xb6k\x0bt\x1d\xa0\xf0\x01\xb4\xe7\xd6\xbe\xe6\x852\x1e+\x9fk\xe9\xde\xed\xec\x9f\x9e\xe1~1\x89z\xd3\x1a%\xf7\x8d\xf8[\xbb\xa6U*\xd7\xa9\x7fi\xb5\x9a:\xbd\xfc.\x93\x94\xa4s\xd7\xf3\x81\xb4\"8\xfd\xa1\x19\xa9\x9a\x9b\x11\xb3\xe8\x1f\x8d=\x8a\x0e\xdf\xacVd\x1e\x87%\xd9$\xb5~\x7f\x0e6\xfb\xbe\xf0\x03\xd2\x1b=\xe2\x9b\x0c#u\xf7\x0e\xf7<\xd7\x833\xee\xbf\x8c\xc9\x13\xd1\xb0\xf5p\xff+\xa6z\xd3\x84o>2\x87R\x99\x9a\xd3\xc2\xed\xea\xc1\xc3*\x83k5G\xec\xedPC\xfc\x1275\xb5h\xee\xca\x07\x850\x8a\x0c\xaf\n\xf5M\xf4Uy\x02n\xea\x90\x0d\x0b\x1f4k\xf4\xb8\x95=\xa5\xb2\xf8V\xaa\xdf\xa1B \xc5\x00\xb6\xcc\x1b\xd8k\xfc\\\x17Z\x84\x05\x86#h)\x0bo\xb1\x10Y\n\x16\xf0\xfc\x14\xb3\x14D\xee\x82\xa7\xfc^\xc6\x8d\x93\xd3\x0eDn\xe1.<\xef\x04X\xe4-\x18\x8d\x0c\xea(\xb4\xf3\x91\xa5\xac<\xccP\xc2Q\xe3\x8c\\\xf8\x90\xbb\x89\x94\x02E\xc3\x8f\xbc\xb47\xd3\xfc\xa0\x93\xa6xH\xb4\xb0\x91\x10Tj\x03\x18F\xd4\x9aDo\x96\x14\x8fHa\n\xc2\xc4\xeeA\n\x12]\xa5\xbcx`R\x82\xeeA5\x07\x8b\xd6\xad\xf3\x8b\xb0P\xcc\x9f\xc8\x97\xf2]6'\xaec\xcb\x99\x92ah\x01\xdbx\xb4\xb0\xb8]\x029\x0b\xfb\xcd\x1d\x858\x82g\xcau\x16#\x9bX\xf1w\xb7u\xa1\x90.\xb1!v0\xfdp\xaai\xe5\xc4c\x96\xa8\xa0\xcb\x9aJNY\xe4\xb8i\xe3\xc3\x08u\xfa?V\x1f1x\xe9Zf\x86\x176\x0e\xe6a\x19b\x98\xc2S\x18\x8d2\xf8W\x982s\x07l-(\x96\xf1\xa2t1\x04\x05\x17\xbf\x08\xafkN\xe1\x95\x06m\xd5\x83\x17dW\x05\xc9o\xd0R\xca\xbcx\xd12\xcc\xc3\xa8$\xf9\x8fa\x19\xb6\x82\xfe\xb3V,\x16\xeb\xbd\xf4\x02}X\x9a\x17\x0cai&X\x99\x94{F|(/P\xec\xc0\x15\x94\xa8\xbde\x04\xb0iq\x86\x88\xc5\x1e|3\x1c\xb6^\xe3v\xe4$$p\xec\xaa\xb0&\xc1\xb4\xe4\xf6f\xf6B\xe9\xe8D\xdcO\xdaM\x9d.\xa8C\x8cj\x1c\xca\xdb\xaa\xc4\x84|\xef\xd9\x8e7~\xb1\xb1\xdbze\xbf\x95\xc6\xa6\xffL\xae\xfe#.;:\xb0Th\x1f%\x1bH1\xdf\xa8\xde\xe0\xbb\x80\x8c_\xee\xea\xa2\n\x00\x16\xb8\xd5\xd8lA\xcaO\xf1\x8ad\x15J;\x0c\xdb!U\x182\x80\xa6\xba\xcb\x0e\xfb\xd8<\x98\x96T\xeeA\xba\xb2\x83\xe8\xcaoBeY3h\x9a\xb2f\xaay1\xa7l\\\xfb\xd3}\xfe\xef\xc1\xc6y1;F'\xd2S\x1e\x9a\x92\x8d\xa1\x86\x8f\xa7'P\xc3\x0e\xe7\xdda\x87\xd5X\xe9\x96|WV\xc8 \x84t\xed\x0e\x92,\xc2\xc3~\xdcJaF\x9fe\\\x94Y~g~\x99\xadI\xaa\xb2\x7f\x86J\x98\xf2\xab\xb7\xd6\xeb8\xd1+\xd9\xe6\x0b\xe2\x86K\xf1\x82\x9b3\x7f\x8b\xc9\xcal\x89\xfa\xccV\x1cta\xd8wmxr\xc3\x1dFm\xda\xb8\xb4C\xc5\x9b\xd7\xf1\xde\x0c\x82P\xab=Im\x08\x13\xf3\xb0Ih\x15$\x82B\xbb3\x87\xae\x95\xe3\x83\xf3C\x92]\xd1\x7f_g\xf9\x8a\"=\xe7\xc2;\x01\x16\x16\x13\x13\xf3U\x08\xc0]\xcf\x0b\xe6YJ\x90\xc4E\x8dE\x07\x92\x13z\x97\x98\xe5\x10\xb4\x93\x1f!\xc4)_3\xc693;QV2\x0b/\x86`5,\x91\x0d>\xec\x0b\x93;\x8c\xee\xe0P`\xe0\xd0k\xcb\x0b]=\xc9@\xaf;\xbb$\x1eW\xcf\\\x9f\xb8@h\xd6\xe7>\xdc\xf8p\xe7\xc3\xb5\xde|\x81y\x0f}\x98\x1b\xdc\x92W>\\\xfap\xe5\xc3m/\xbb\x08\x82\x83Z\x83\x08\xb6\xfa\xa2\xc6\x05/\x8c\xf1 \xe8#\xc2\x15v2\x00\x18\xef\x8fe\xec1\x87\xe0k*1C\x8a\x8ej\xd0\xacf/\xfbi\xf8\x86R8i\xad\xdd\xea\xfc\xca\xe2\xfce,\xdddD\xc3Gb\x00vmt\xf9\x05\xbd\xa5G\xe0\xc0\x1bq\xa0\xdb\x95\xce\xe1\xb4^[\n&n\xdaU^Y\xd0\xf1\x0bT\xca5\x82\xedV\x85\xf7p\n/f fNz1s\xfe\xed\xdf\xea\x8b\x85E\xe8\xfc\xf1bvcH\x1a\xfd+\x05\x86L\xdfxc\xe00?S\"\x00\xce\xe0\x1c\xce\xe0\xd6uHZ\xe61)\x10\xa2\xfd\n\xf6\xd4uoX2\xb7<\xbc\xc3\xa9\"\xa2z\x11\xf0\xafio\xef\xdb\x14\xd1\x1bD\xc5W\xf4\x96\xb8o\x18\x19\x8e\"\x0e\xcf\xf3P\xea\xae\x8b\ni\xf5+\xa6>G\xcfj\xf7\xca\x87/>%\x11(\xba\xa5<\x85\x89\xed\xb8\xe2\xabT\xd1\xea\x89\x0fK\xcf\xf3\xe1\x9c\xb6\xf0\x1e\xe1\x8c\xd8 \xec1H\xc3\x15\x93\xad\xbf\xe2x\xfc\xd7\x81P\xe6\xbd\xd5\x9f\xcb\xe3n\xf1[L\xf7\x8bW}\xeb\x15\xdb 1\xb4\x178\xb4_=\x1f\xc2\x19\xa1\x94\xc9\xaf\xf4\xaf/\xf4\xaf\xa5\x0f7f\x11\xdf\xcaj4\xc1\xe6t\x8c\x9bHw\xed\xd6\x15\xd3\xb4\xc8\x14(\x988\x86\xbb\xa6\xba)\xd3\x97x\xf8\xae\x1e\x83A\xb1\xe8\x9bl3A\x90\x89\x97\x14\xc2\xad<\xc0\x7f_\xd0\xa9gt\xea\x97>\xacf\x97\xa6\xf0\xa2,|\x91\x1b\x07\x1f`\x04q\xf0\x1a\xbe\x07wM\xbf{\xe5!\xfc]\x99c\x11\xad\xea\xc2A8\xf7FJH9\xb5\xd0\x0f]\xdfC\x1d\xa7\xa7\xd4\xd2\xe4\xda\x08{\x01\xc1\x8d\xba\xb9\xae\x08\xb3:\xcc\xeb4\xd2\x12}7,\xae\x05\xe4\xb5\x17\xbe+ mk\x0c\x1d\xd6\x81`\x1c\x06\xfd`\xa3\x91X\xe2\xd6\x9aF\xd2\xe30n\x1c\x8c\xd5\x1f\xb9+\xce\xca\x10\xf4S\xf7\xc64\x08DV\x1fX\x9a\x1etb\xe5\x93\xb9\x95\xba\x93}\x16\xa54u\xa7G\x9e]B\xccG\xf3\x14\xb6N-\xcaT\x91\xda{\x1e\xdf8\x9e\x0fN\xf8\xf5j\xd4\xa7m \xa1\xce\xdc\x0b\xc2f\xf2\x1b\x92\xfbS35|\xf4?3\xdd\xa2\xaa\xf6\x9bn\x9a\x19\xa8\x95s\x98\xab\xf1\xcc\xf9A\xa6\x93}\xcf\xdd\xd2)uc&\xf9\xbeu\xb1\xc7\xfa\x0cyB\xc76\")\xda @\x813\x163\x8d\xec\xe5\x9a\xb58\x85\xd0\x83\x94\x1e\xde\x8a\xed_\x88K\xb1\xbd\x0d\x11\x13^\xeb\xc1\x0d\xb8\xf3\"i\xc2\xe7\x16'\x1e\xff\x8e\x12p\xb3b4b\xf1}\xdd\xff\xca\xdc\x08[\xbb\xbfoZ3#\x97h\xb3M\xed\xdd\x9f}s\xaa\xe8\xcel\xfe\x95A\x93\xda\xc5\xf7\x06\xd7\xa4\x94\xb2d\xabV\"\x96c]\x8a\xbd\xe3y+\x91\xc5\x9de\x176\xf9\xae\x9ae\x8b\xf33\x8dW\x85\xf2\xf6L\xfd-\xd1x\xc7\xeag\x9c!?\x83J\x97\xe4n\xb8\xf8\x87\xe6\xc5o%\xe4no\xc5?s\x14\xd7\x03\xee\xcbu\xf8?;G\xb1\xf5\xec\x98\x12/\xfd\xcf\xcd\xa5\xdf\xb9\xcd\xbc\xb7\xf6.+\x16\x8b\xee\x04\xb6\xc1\x04\xd5\xb5<\xb6\xee\xd4RO\xd8,\xd1:{\x96:\xe6\x8c\xb7\x9b\xeda\x9f4m\xb2{\xd0N@\xbf\xfb\xf4\x9f \xe8\xa5\xe7\x7f@\x02\xfa}sR\xc4\x01\x19q-\xe7\xbf\xae`\xb3\x9f\xa4}\xf3@\xe6\xcd\xbe\xc7\x14.\x99y\xe6\x82g\x016\xbf\xa5TOhu\x14\xe1c*DJ\x9c\x82ns\x84 \xd6x6s\x8e\x03\x8e\xc1\xc5\x08\xdb\x98D\xf1e6'/J\xb7\xf0\xe4\xee\x9d\xe7\xc3\xdd\x1f\xa4\xa2e\xe7t\xa5\xdd\x91?r\xf8\x15\xc0!\xa4\xee\xde\xc4s\x13\x0f-i\xbb\x1aK\x1a\xd7\xcb\n\x83\xf4\xfa0\x91\xcc\xae\x1f(eI\xf7\xe1&H\xb3\xdb\xde\xd6\xb0\x96\xb5\xa19\x86\xce\x16\x06\x99\x94\xa2\x9c{\x01\x05zS\x1fb\xfcc\x12d\xe9\x8a]68\xa5\xd4\x07\xc6\xcap\xb3`\x9d\x15%\xbf\x85\x08h&\x18\x81i\x11\x84\xf39&\x1a\x94Se\x197Cj\x00\xc9\xbcE\x10\xafh\x8f\xe7Q\x1e\xaf\xcb\x82\x8e\xac{j\x0by\x0c\xdc\xa1\xdc\x07\xe7{)\xac\x17\x85\x94\xad\x11\xb9\x0e\x9f\x90\x83\xe4\xd4\x16\x1b9\xed\xcb\xc9\xd2\x9c\x84\xf3\xbb\xa2\x0cK\x12-\xc3\xf4\x9a [\x1d\xb9N\x81\xa3r\xbcNK\xf5\"\x08\xd7k\x92\xce_.\xe3d\xeeJ_yA\xbb\xe5\xbe3,\x123\xb1\xc6J\x16MY\xdcS\xab2\xb9\xd3\x94Q\xb2\xa0oN\x84bG\x8f\x99>%\xc4\xd7\xfa\xfe\x18\xd6\x1af\xa0\xb0\xfa\x18\x9a\xecC\x9b\xd1)\xf6\xc1\x9a\x95\x0fVy5},\xce\xf5\xf4\xb996{\xee\xa8\xeb\xd8i\xd7\xda\xdb\xb5\xc5\x04\x9bv\xdd\xd7q\xcf\xeamJ\xe9\xb4\x0c29\xa53\x1ed\xed\xa2O\xbe1u\x89]\xe6YH\x14\xe5\x1e\xea\x9bl\x9e\x857<\xb6U\x16,ZQ\xc4\x05!\x8c9\xc5sRd\xc9\x0d\xf10\x9c-F\xb1[\xc5\x05y\xec\xc2\xb4V\x80-\xcc\x9e\x9d\x04\\\xd1\xad\xef'\x00M\xd4\x9f\xd9\x99\xb2\x0en&9\x963O+N\xdemmQ\x02\xcf\xf9H\xae_}Y#h\x8c\x15\x0f\x9bAS\xb6\xdf\xd6\xda5#u\xa7\x87:A\xd7\xb8v(\xf2\xffA]\xca\x12V\xe3*\xeb\x9dq\x03\x84\xa3\xde\xc5\xb5Q\xd7\x88\xa1\x02\xae\x1b\xc6\xa46\x1eW\x8f\xb12J\x16\xb5\xaeX\x85\x84\x9d\xba5\x15\xcf\xfb\xcb\xb2A\xb9yp\x0e#\xc8\x91Y\xce\xba\xf5\xbc\xf4\x90(\x85\x98\xbf\x9dk*}9|\xd4\xa054\xcb\xae\x89\xecr#\xc2\xb5\xf3}\xec[(\x14\x8e\xba\x8a2\x9d\xd8B\xa9\xf0\x80\x84\x14\x97@\x08Q\x12\x16\x05\x84\x85\xe2%\xfb\xbbLG\x93\xd2\x0bO\xa4\xc9\xbe\xe9\xc4|{W$\xe3Z\xb6\xc8\n\xfe\x02J\xab^\xbc&oS\x96\x1a<\xc5\x18]\\\x9d\x03\xe9h\xd4E\xe8\xe7h\x89\x92Z\x08\xfd\"\xd2\x84\xac\xa0s\x01\x0f\xad\xaeB\xf6\x89\xe4\x95\xbd\x95\x07\x0b\xce\x97\xb1\x80J\xe5\x8c\\l\xb8_\x8f\x03%8WJY\x1d\xea\x1a\xdf\x98\xbf\xda\x1dO\xf5W\x19\x7fE\xe1\x8f\x9c\x86\xb0F|\x86\xdc\xa4\xb5\x89 \x0b\xd4,\x83\xa5\xb2\x1b,iA5\xfe\xd0\xfek#\xf8d\xb9\xea\";\xc1\x163\xc27\x12=\xe7\x14:\x01\xf9\xb2\xceIQ`\xd6\xa4\xaa(\x81\xc4\xe5\x92\xe4p\xc5c\xccf\xb9D\x05\xb1`\xcd\x0e\x8c6\x86J\x1a\xb8\x935s\xccc6\x96\xaa3\x8eJ\xc2\x8d\xed\xe5\x94\xd8-\xd3jC\xa7\xf5\x0d\x0c\x08@\x07\xaa\x91\x96\x85\x95\xd5\xcc\xbd\x0c1,\xd4\xdd\xc6\xfb\xc8\xa8\x11\xb1\xc7g8\xfd\\\xa1CD\xb2\xa1K\\\x83\xcbKJ!}\x93\xfb\xa3\x1aX\xef\x8e\xbfM\xfc\xa4\x03\x93}`\xea\xee\x99\xedz'-\xc5\x12zMS\xe09f\xe1\x07\x0e&\x9eb\x906e\xe5\xbb\xe3\x03\xe3\xf5\x0cMc\x06a\x97\xb6\xce\xb3u\xd1\x845\xa4\x98\xaa\xe4\x01HyIN\x16\x05K\x0d\xc5B\xcc\xad\xe7a\x89\xf9\x0f0Nr&\xad{\xbb\xef\xe2\xef\xd8w\xa4\xba\xdd\x87r\xf4\xa9\xe2# \xa3\xf2e\xb6Zg)\xc1\xbc7\xbf=\xf8J\x95\x82\x94\"EY'\x90\x91\x88\x11%n\xa69\xf4\x90\x04x\xd8\x8f\xdcu\x0e\xf7\xeb\xec\xef|~\x01I\xffZ\x91\x8a\x9c\xf31\xd4V\x15\xbe\x94\x87^\xab\xfb\x92\x87\xa2\x15\x11\x9d|p\xc4\x14T\x01\xa7<\xc9E\x96G\xe4gl\xa8[\xb6f\xe8\xf0u\xf3\xad\x906\x96\x03\x07W\xfa\xe0H]\xab\xe3\x8b\x14\xd8\x17\xcap\xaeP^Qp\x1d)\x85\xaa\x94 \n\x1fb\xb7\x90\x1b\x90Z\xf3\xd4/\xe3\xe2C\x95\x93\xd6\xa9\xe0 D,\x8cB]\xf3\x18B\xf5\xca\xd2\xc6\xa4\xb7\xc5\xb7\x00N\xa9{ ;\xaf\x0b\xf8\xa2\xe1\xbc\xe2mV\xa5%\x99\xf7\xc5\x0d\x14\x14\xb5fc\xa9NC\xdb\xbe6ae\xae/\x1d\x0dm\x18\xe6\xfa\x1f\xc9: #\x16\xa0ph\x1f\xe2n\x18\xea7\x8bm\x86\xec\xf9\xe3\xf7@,\xba\x1c\xac\xfe\x1b7\xfd\xdb\xb7\x1f\xb5\xfd\x04GU\x9e\xe3 \xdd\xdcu\xa2{\x16\xc3\xb2\x9a,\x98#H\xf3\xcburz\x05\x03\xc2\xd4\xf8\x0e\xfa\xdb\x1c\x8c'\xe3\xdd\xdfuQ\x9c\xf3W/?\xbe\xfat\xf9\xe3\xfb\xcbw\xef?]~xq~~\xf9\xe9\xdf\xdf\x9c_\xbe\xffx\xf9\x97\xf7?_\xfe\xf9\xcdO?]\xfe\xf0\xea\xf2\xf5\x9b\x8f\xaf~t\x86\xf4\xa9Q\x12\xd3\x897L*\xd1\x17!\xafu\x97\xcd~z\x14\xfc7T\xb7\xd1I\x8f\xd3\x7f\xba17\xa6\xbb\xba&\x14\n\xae\xb2\xf4\xd5\x97\x92\xa4\x94\xf8-0\xca\xf85)\xb5\x12RD\xe1\x9a\xfcH\xc8\xfa\xa78\xfd\xfc!\xc4\xa4\xcb\x84;\xbb\xb5\x8a\x8be\x98$\xd9\xed\xab\xbfVa\xf2\x1f\xe4\xae\xe0i\x05\xe3d.\x82\xbe\xb0jY^\xb2\xccz$\xb8*3^H\xf28L\xe2\xbf\x91s\x12\xe6\x11ko\x1d\xe6\x85\xfc\xfb\x9a\x94\xe7\xe1j\x9d\x90\xf3hIV\xec;L\xd1\x10\x96\xe4C\x98\x87+\xad\xa4,I\x9e*eo\xe3\xf4'\x91;Z*\x0d\xbf\x18J\xffX\xc5s\xa5\xe0\xc7\xb0$\x9f\xe2\x15Q\n\x99%\x8cR\xf4C\x96%$T;~\x1d'\xeawo\xd2\x92\\#\xad\xd3\x94\xbd\xabVWZ\xd1\xdb8\x8dW\xd5J\x1fn]Fi\xac\x97K\x12}\xe6\xdf\xad\xc8*\x8b\xff\xc6\xba\x8a\x8b7\xabU%\x84~\xa6\xd0>\xe2:_Q\xd6p\xfa\xd4d\xbd\x1e\xd7\xaf\x8fL\xaf3\xfe\xfap\xcf\xf4\xb6\x12\x1f\xef\xee\x9a^\x87\xf5kc\xd7\x05\x7f\xcd9S\xf9\x15\x9d\xdc\xff=\x7f\xff\x8e\xeb\x00\xfa\xec\x19\xec\x9eK\xc2*\x816\xc6\xce\x9b1\xb9-p~\x93\x85\xa4kb\x97\x0d\x11P\x15*+X+\xc6Z\x9d\xf4\xa4\x93\xb2\xa1\xf4:\xedD\xbc\xb8\xeb] \xde\xc8+\x17C\xd6|qy\xe4\x9a2\xfb\xbf\xe7.\xb2]\xaa\xdfj\xdd\xc3\xff\xcf\xde\x9fw\xb7\x8d#\x0f\xa3\xf0\xff\xcf\xa7(\xeb\xc9/C\xb6i\xc5r\x96N\x9c(\x9et\xe2\xa4\xdd\xd9z\xb2\xf42\x8a\xc6\x87\x96 \x8b\x1d\x89TH\xd0\xb62\xf2\xfb\xd9\xdf\x83\x02@\x82$\x00\x82\x8e\xbbg~\xf7^\x9e\xd3\x1d\x8b\x0b\x96B\xa1P{\x85i\x1a\xae;t@E\xb3\xe8\xd8\xaa\xfe\x8d\xbd\xbc\xf70@v4nv4K\x93\xe5O\xef\xdf\xa6S\x92\x125\xef7PO\xab|g\xabr\xe1\x11c*S(VN\xb1\x84,\xe5\x92\xf4\xd9\xbe\xb4}Z\xc0\x8b\x94\x19x\xa3\x8c\xcf\x04oM\x8a\xa6\xde\x93/\x1e\xf1\xfb\xcbp\xe5Q\xccd\x1fe\x14g[\xbe\"\xa6\xf5:\\\x95oB#\xc6 +;D\xf1\xf4C\xe2$\xa2\x80b\x16\xab\x1b\xb8\xa0jV\x0d\x159\xdb\xef\xcf\xa2\x05%J<\xa3\xb1 \x91hA\xefD\xa3\x8d\xf9\xf3\xd9i\x7f\x18N\xe6e\xeb\xc6\x1c\x01\xd2*0J\xc7h\x0dM\xc78{O\xe4^\xd7X#\x9a%\xfe\x18\xc8\xe2$]\xe2 \xc2qn\x08\xef\x03\xa4\x13\xcfcW\xa4m\xc9\xe8\\\xf4\x14e\x05\xdd9\x14}\xe4X\xfd\xf8\x9a{\x91\x13qj\xb6\x8a\x9bu\x97\x10A%^\x87+\x17t2\xa2LJ\xa6\xf9D)\xf2g\xcb\xfdP]W\xe2\xb1\x95\xe5\xa6\x9df&\xd8\xcb\xa0\x12\xd1\x08\xca\x90\xdfa\x97\x7f\xd9\xa8\xcfD=\xabr\xbc\x06\xcb\x9cP\xf7Z\x0f\x84\xa8\xed@\x88D\xa5\xa7\xdd\x00\xf2\xf2n\x1c@\xd4 L\xd9:\xa3d\xf9a\x9e\xc7\x9f_G\xd3\xe9\x82\x9c\x87\xa9]\xe4\x07\x9d\xe5\xce\x04\x13\xd2\x9fJ\xf7I\xc1\x85\xe9K*@\x97Fu/7\xf4H\x86\x0f\x8cyKc\x8fz\xe8\xbfE\x9c$\x8b\xe9\xc3\x1e/_\x8f\xff\xa9\xaf\xe2\xbd\xf1h\x05\x07\xb8v\xb7\xe1\x00\xf6`\x1f!|\x0f\x0e\xe0\x8e\xf8\x9b\xdd\xbf\x0d\xfb\xb0}\xeb_^\xe8\x9dd4\x0d't\xb3\x88\xc2l\x13O7\xd2y{\xc3\xf6\xec&\xf3\x96\x9b\x8c\xa4\xd4?\xd8\xe44\xf17'^\x98\x91\x0d9\x8d\xe2M\x92,<\x12\xc6\xfe\xc1&%\xe1\xe7\xcd\x9a\x12\x7f3\xc1\xc7\xec\xc0\xd9\xcc\xc3t\x83\xf2\xedt\xb3\x08\xb3l\xb3Hb\xb2I\x96\xab\xc5&\x893\xbaIb\x1a\xc59\xf17S\xe2\x9d\xe4\xa7\xa7$\xddL\xa2e\xb8\xd8L\x16aJ63\x8f\xed\xf1\x0dI\xfd\x83M\x14Gt\xb3\xf0\xc8iH\xc9\x86P\xe2\x1f\xf8\x9bi\xb2\x99&\xf9\xc9\x82l\x887\x99'\x9bEv\x10\xcd6\x8b\x8cx\xd1\xcc?`\xf3\x88\xb3<%\x9b8_n\xceHL7\x17\xde\x84\xac\xe8\x86L6+\x0fS4o\x92\x94\xfa\x1bJ\xbcx\x9amPs\xb2Ic\xdf\xf7Y\xd7\x8b\x05\x9d\xa7I~:\xdf\x84\x8b\x8cl\xb0l\xf9b\xcd\x86r\xc1\xa6\x93\x84\xeck\x8f\x84\x939\x9b}D\x18\xd8\x92\xe5&\x8f'\x1e\xdb\xbdl\x80\xa7\x8b\xe4$\\lN\x13\x9alN\xf30\x9dn\"o\xb6Y\xae<\x8e\x03\xd9F\x19D\xecEt3Y\xe4S\xe2\x1d'\xf1\x84\xf8\x07\x9bE\xc4\xa0\x95\xd3\x8d\x14}6\xd4#\xe9,\x9c\x90\x0dI\xe3p\xe1\x1f\xf8\x07\x9b\xcc\xdf,\xbcpy2\x0d7\x84n\x92\xc9\xe7M\x12\x9f\xfa\x9b\xa5\x17M\xd2\x04I\xe0\x06\xf5L\x1b\xaeK\xf07o\xc27\x9b\xd8\x0b\x97$[\xb1\x96B\x1a\x9d\x91\x0d\xb9\xa0\x1br\xbe\x89\x16\x9b\x84n\xf2\xc5\xc2\xdf$\x1e\xb2E\x9b\x15\x8f\xaf\xdc\xa4\x9b\x9cn\xceH\x9aFS\xe2oV^8\xf9\x1c\x9e\x92M\x98\x86\xcbl\x93Fgl]\xd2\x84\x92 %\x0c\x104\x99$\x8bM~\xb2\x88&\xfe&\xf5\xc2\x88a\x8c\x17N\x93x\xb1f\x0b7\xdb\x9cF\x19%\xe9fEB\xba\xf9\x92Gi9\xefl\x92\x93\x0d\xd7\xb3mh\xba\xde0\xaa\xe8\xfb\x9b\xcc;Y\xb3\xc5\x0f\x17d\xba!\x8b\xd9f\x9e\xa4t\x13\x9d\xc6d\xba\x89\xbe\"xB\x1aM6\xa8\xd3\xd9\xa0\xa9a\x93\x9fp\x97\x84M\xbe\"\xe9f\x1dO\xe6i\x12G_\xc9t\x83\xb1\xc4>\x83\xe8r\xb5`\x83\x9f\x93x3\x8f\xb2\xcd\xf7|L\xd1\xce\x06\x87\x11^\xf3z\x8a\xf6\xcc)E\xfb\x14\xab\xfc\xa2AB\xefGR\xbc\xdc\xf4\x86\x99\x06Pw\x06\xae_X\x8b\x8c1\xa6\xd6\xb7N\xf1\xadA\xcb[K\xc6\xd3z\xa7\x01\xc4\"\x83\xc9\x00K\xede\x84za\x00k[\x81\xe2&*H\xa1c\xc9\x84\x8e\\: .1\x19\n\x0fq[\xea\xb9A\x0d\xb1hMU\xdb(\x9a([0\x11\xa7\xc2\x9b\x8d{\x87\x95\x84\xbe$U\xa3\x81\x86\xb8H%\\\xa3\x08J\x80\xf6\xb5l\x12.\x9e\x86\x19\x1b\xd6\x93\xea\x9d\xe7b\x90\xad\xa0\x91\xeaG\x8f\xf6Sn\xe8\xf7n}\xea\x8f\xfe\xd5\xbf5\xfe\xee\xc6-&J4K\x7f\x92~\x16\xc6\x11\x8d\xbe\x92\x8f\xe9\xa2\xb5\x87H\xad_\xabz\xdb0a\xadW\x8b7\xd2\xc9\xd6\x8abp\xa6\xf6\xeck\x8f\xe0SB\x9fL\x18\x97\xcf\xb0%M\x16\x8b(>}G\xb2U\x12g\xed\xd0\xa8\x9dd\xa5\xc2\xbf\x1fe\x8a\xf6_Q\x87\xb0\xa51i\x0c\xaa\xc7\x9e\xfe\xcdR\xbf4\x8b\xe2\xa9\xd7\xaa\xac\x91Wq\xc2e4Li\xf6kD\xe7^o\xafW\xe8#U\x15*\x83\x89\xd7\x9b\xf0\xdd\xc3\xad\xf6\xff\xbe\xf4K,lz\xfe\x01\x98+X\x15\xaa\x1d\xaf'\xba\xe8\x89\xc4\x9b\x1a;\x89\xa1\x8d\x14\x9d\xe64\xe3\xd27\xe2\x17\xca7a\xea*\xb3\xa4\xc5\"O\xa2Y+\xc7\x9aM\x9bx2%d\xb5X\xbf\xa7i\xb4zI\xd65~\xcd\x927\xecZX\xaab\x99[\x94\x81:\xa7L=\xb6ut\xbb\xafZ51\x99N]K\xb7\xd9\xa8\xe4\x8f\xf1q\xb1\xcd\xd4&5\xef5e\xf8\xbf\x19\xb05d\xb1\x86\xa3\x91\xc6\xe4dVh\xe3\x98b\xee\xa1\x17a=D\xd4*\x8a\xc8mv\x87 5<\xa1\x0c\x15o\xe8\xd3V_\x9aU\x90\x91\x86\xec!\x15s\xb1\xa3F\x86\xa2\xdd\xa6\x94\xe2\x80^)\x0c\xb9A-\xeb\xcdp\xddp\xa6\x18\xad\x16\xb4m\xc1)\xb7Z\x94\xd5\x8dMn\xf5P%\xbeU7_n\xdf\xd3T\x94+\x98\x9d6\x83d\x91o\xb1\xd9\x84iM\x18L\xc4g\x1a\xd2\x1f\xa3\x03\xc6\x87\xa4p\xeapX#\xfe\x8da\x8d\x94\xde\x8chR3\xfdU\xdfc\x9bb\"\xfd \xee5\xfc\xfa\xa1\xc8\xbaq\xfbN=<\x05D\xee\x0d\xf4\xb0\xb83\xd0}\xba\x92-\x7f\xbf\xab{\xaa\x0f\x89\xaf\x16_e\x0f\xcf*\x07\x89\n-\xa3\x05\x19\xb3\x16\xf4\xa3\x18\xf5\xe3\x99\x17\x97\x0c\xb8N\xb7\x02\xaa'\x809:\xd7m\xa3\xc1\x01(\"A\x84A\x13\x11\x16Z5\xf2\\.hm\x8d\x95t\xf1<\xc0C\x9c\xe2\xa7Q\x93\x18p\xfe\xad\x9f%K\xd5s\xa2\x8d\xddd\xbd\xac\x95a\x8eb\xc6[\x8db\x8d\xdd\xeb\xb2\xbe%\x9a'\xdf[\x83\xdfc\xeb\xfe\x80\"\x10\xf01\x94\x02T\xef\x97p\x91\x13\x1e\xe8uB`A\xb2\x0c\xe8<\x8cA\xb4\xdck\x8e\xb1\xb9;\xfe0\xf8gv\x18\xd3#\xf3\x98NQ\xe5\x9e\x8aa\xf1\xc6\x9d\x86\xf5Y\xefI\xda~Z\xa0\xa4y\xeb_;\x07\x9f\xa6\xdb\xde\xa7>\xfb\xc7?\x90\xb6\x01EN\xad\x0d4\x04\xc1\xf8\xb8\x0c\xee\xc8\xe0\xfa\xdamt\x0e\x83\x8a!\xe2\x8d;\x0d\xeb\xb5\xceE\xd7mLx*\xd5\xf2+\xd4\xbc\n\xcd\x90\x9bE\x0b\xe24\xc0\x0f\x06\xbfb\xb71\xf6h\x9a\x13N\x1aD\xccR\xb8\xc8\xd4\x1b[\xbb\xca\xdf\x03\xc9\xca\x9bF}\xc2\xbbw\x1a\xf8S\xbd\x8f\xb4\xdb\xb8\xf9`5\n\x1f\xf3\xd8\xc4\xcb.C\xfb\xd9\xe4\xd3\xed68^\xb1\x9f}V\xb8\x0b[VZ6\xef4\xb2w:\xf7s\xb7QIqO\n\x1b}\x9a\xbcJ\xceI\xfa4\xcc\x88\xe7\x07\xb0u\xeb_\xa3\x7f{\xe3\x83\xd1\xee\xce\x83pg6\xfe\xf7\xfd\xcb\x9d\xe2\xef;\x0e\x7f\x0f\xf6.G\xfe\xe5\xd8\x890\xb0\x91;M\xf8\x8d\xd1\x0b\xdf\x9d\x98\x96\xbc\x89\x1b\x9d\xe7]8\x0d\xef\x951t\xa0\xfb\xf0:\x90\xfc\x0e#|f\x08xp\x1e\xdf\x16O\xebpzx\x81\x1e\xc9\xb6\xa5\x9d%\x8bEr\x0e+\xd1I\x0f\xb6u.\xec\xd53\xbc\x19\x9e\xd1:\xb2\xabr\xb67oV~\x9b\xb9Z\x13\xc7\x8b\xac\x1eR\x9e\x93d\xba\x16je\xae`\x8c\xe2\x1ew\x93\xc7_h\xc8:\xbeX.z\xc7\xd0\xf9LyS\xb0\x1e\x867\x17\xe5\x9b<\xc9\x85\xfe\xb5U\xf9\xda,I\x97!5\xbd8\xaf\x8cQ\xec\x00\xc3\xbb\xd3\xca(\xed\xef\x9e\x95\xef\n\xc4\xad\xa7\x1e\x01\x01G\xeet\x950\xa67\xb2f\xe6\\3\x91\xbdT\xcc\x0d\x01\xbf\x8c\xf4\xfd\x83Pe\xf4B\x99\xe0[\xbc_\x15\x9ay\x82\x97H\x16\xd306u\xackJot\x94MN\x92<\xa6&-:\xbbN0\x9c\x8fq$\xcal\xccl\x8d\xb9!\xd4eH&\xa1l\xcb\x8bx\xa6\".\x96X\x06r\xc1\xbe/\xb5i\x95\xcfw[\xbf\xc6\x94\xf1\x92\xf9\xeb\xfe\xf9\xa1\xc1\xc8\x0e\xd2\x00\xd7\xd0B,\xcc\x9e|V\xed\xaa\x9bdvhp\x08\x90\x17O\xef\xad\xd7\x11G6u\xac\xbc\x94\x80\xa7\xc8\x0fD\x7f\xc6/\xda\xed\xcf\xf2\x92\xb4\x88\x1b\xb8{H\xf7 ;\xde\xf88y\\bq\xf6\xe1\xf1\x80c\xe9\xf9\x81\xa1\xfc8h\xf5\xb9 \xb6\xe3\x13F\xd2\xd7\x01\x9c\x16\xb5#0\xb5\xfd\xfb\x00\x0e\xc75\xe1\xd5:\xf6R\xdf\xa4}E\xa7\xe6\x07\xb1\xd4 \xf2\xcfe\xf9 9\xf7w\x82\xd6\xc3,\"\x8b)D\x19\xe6\x0fY\xa5\xc9Y4\xc5\x13@G\xb1e\xa3g\xb6\xc1\xb2\x89\x7f\x85!<\xf3\xa2\x00\xce,N _\xd1\xc4\xc1\xc7\xf3\xd5\xd5\xd9\x00\xc4\x10\xe6\xe5\xd6\x99\xb7\x8d\xe69\x0c\xe1\x0d\x1b\xcd\xdc2\x9a\xe7\xcah\x9ew\x1d\xcd\xb4m\x08\x1fa\x08\xaf\xd8\x10\xea\xa5E\xd4\xeb\xa32\x84\x8f]\x87\x10\x96\x00 \xdbF\xf3\x03\x0c\xe1-\x1bMh\x19\xcd\x0f\xcah~\xe8:\x9aY9\x9aY\xdbh\xbe\xc0\x10\xfe`\xa3\x99YF\xf3E\x19\xcd\x97\xae\xa3\xa9\x1e\x89m\xe3\xf9\xdd\xe2\xb7$/\xe4n\xbc\xdfQC\x1eR\xb2C\x99\x1c\x85\xcd\xaf\xe0\x00~\xf6P\x85\xd6\xcb\x99\xb0Q\xdc}\xc7\xef>\xe5D\xd4\xcc\x17\xc9K\xcc\xf6w\x93\x1bKIf\xab\x07[\xdb\xfc~\x85!|\xf0\"\x0b\xb0qv\xbfv\x18\xe3\xaf\xedc\xac\x1c\x9emC\xfc\x05\x86\xf0\xb9}\x88\xbft\x18\xe2/\xedC\xac\x9e\xd0mc| C8j\x1f\xe3\xcb\x0ec|\xd9>F\x95\xc1j\x1b\xe1\x8b\x96\xa1\x1d#\xf3S\xb0a.\x03}!y\xd6\xa3\xd8\x1b\xf5\"J\x96Y/\x00\xceg\x8f\xfd\x00\xa2\xa6\xa1\xbb\xcd\xd7\x03\x14\xc1\xaam\xdb\xb1\xab\x82I/\xd0I\x82!\x0b\x06\xabV\x97P><\x12\x0fU*\xf0\x02\x190\xf6\xf4)\x13*\x03ap\xe7\xeb`\x1f,\xbb\xa2xJ.\xf6\xa1\xc5g\x90]$M\x93t_\x13/\xa7^\x97\x96x\xb0v\x9cP\x18\xe46\x94\xb8\x01Cx\xdd\x8e\xb47\\pA\x00\xeb\x86+56\xda\xbd5\xfe+\xcdl\nvNI:\x1a}\xbb\xbb\xb1\xc6\xd2 \xc2/\xa8\xab\xd8\xdf0h\xe9\"\xa0\x19\xbco],\x17BwE\x8c\xf2]\xc4\xbd\xae.\x96\x0b\xdc\xb6\xf8\x17\x166\xb2\xad9\xd7\xf3\xb0o\x98\x94/\xbe\xfd\xf7e\xc0\xbe\xbfq#%3\xd5\x1d`\xbdBO\x18\xda\xc7}\xcd\xff\x14%WD\xb9'\xda\x0f\xa7S\xf4M\x0c\x17?\x97O\x0e\xe0o\x8f\x0eX\xe3g$\xcd\xa2$\x1e\xf6\x06\xfd\xdd\x1e\x90x\x92L\xa3\xf8t\xd8\xfb\xf8\xe1\xf9\xce\xfd\xde\xc1\xe3O\xb1pl\x87\xdf^\xbf\x02r\x81K\x0c\x13\x9e\xe2\xf7\x84\xc0)\x89I\x1aR2\x05\x1e\xa4\xf47\xa3\xff\x93\xbc\xa4!LL\xa7\x8f\xa9\xb1\xbd[\x9f\xde\x7f\xf7\xe9\x96\xf7\xe9\xfd\xb6\x7f\xe3\x96\x05\xd9K \xc2\x10\xa2\xd1\xa0\x19\x8c\x08F\xc6B1\x16\x9eJK\xed\xf4)\xea\xcb~{\xfd\xea\x90\xcf\x8d;\x93\xb8\xf8\x80\xb0\x89$\xc2\xc3\xa8l\x8fo\x82\xe7i\xb2\xe4\x1bA\xb4\xd7\x9c\x91T\x8a\x99$\xbb\xa4M\xb2K\xb0\xbcm\xcd\x13&)=a`_\xc9y\x06Pxi\xaaYP\xac\x8e_g\xa2\x0eI=\xa9\x92\xbc\xd8\x12\x94\xe2\xfc\"\x99\x84\xac\xa9~\x86\x8d\x1b\xf4K\xa5\xde\xd2\xb4\xb5z\xa8\xa47\xee\x11y\xf0\x90~\x96\x9fd4\xf5\x06\xbe\xac\x17tS\xa7\x8d\x01\xd5C=\x85(\x86\xd8\x87\xb8^>%\xe5\x8e\x8a\x18g8J\xc7\xb2\xc5!&[\x1bM\xc9$\x99\x92\x8f\xef\x8e\x8a,]^:\xda\x1d\xfbc,\xdd;@u\xa1\xf6\x9d\xc1\x98\xdbU{.\xf8$\xb7us\xcd\x9a\xd9l\xec\xb4\xd5h\x15_\x86+\x07\x7f6\xf19\x12\x83\xea\x8c\x88\x0f\xdb\xd0\x1b\xa2\xb6\xb6\xf9\xb4\x9a\x99T^\x97~\xff\x8f$\x8aqy\x9aS\x13\x19{\xec\x83\x92\xf3\xa9d\xdd\xa0\"n\x17K\xd5yD1W\x04\xd0\xcb\xe9l\xe7~\xcf\xf7\xcb\xbb\xbd\x930#\xf7\xee\xe8\xc6Pf\x10jv\x9d`\xb8Y\x94\xc4\xd9{|\xcb\xe4\xb5\x13.V\xf3\xb0%\x97\xacz\x154\\j\x13\xe7=\x1f\xb7\xd0\x02S\xc1\x85)\xf1\x88\xfa\xccpd\xeb7\xe6\x92\xd0y2\xbd\xf2h\xf8\xe7\xa6\xf1\xc8\xa7\xceLDs\x8c4<\xfd\xb3\xc0Y\x1b\xb2\xf3 5\x98Y\xcb4\xe5\xc6\xce\xe8\x9cT\x94\x8c\xeeQ\x0cF\xbd\x91\xf4\xe6\xa5F\x0f\x11\x85m\xe1\xa5oz\xe5\xdf\xa2\xcc\xd1(\x0e\xd8\x06\x0dt\xfb3\xf5K\x9f\xfa\xff\xd9\xdb\xbdu\x1a@o\xbb\xe7\x8f\xc5\xfe\xd4-\xa9\x91J\x11\xdb\xa6\xd6d\xee\xaa\xac\xa4\xc1\xb1\xa6P\x9a1\xc25- W\xac8\xe5\xb4\xb9\x8ct\xf2\x18\xa9\x8e\xbc\ns\xa9\x143\xa4's\"\xc0:\x8f[d\xcaT:&\xcc\xd9\x98\xd4(\x8d\x96\x9e\xb2H\x9f2\\\xa3c\xb4\xd8\xf4z\xb6\xe1\x1a\x92\xab9\x0d\x93\xc1\xec\xb8\x84\xd9\xd7\xa6{Y\xa0I\xe7\xe6\xd44m\xe6\x9b\xb0\xecd\xf1\xd1\xad\x7f]\xec\x14\xccu\xeb\xb2\x05\xc6\x14t\x7f\xe6\x08\x85\xfdgS\xd8\x976\x85\xf5h#\xecb\x1ba\xf5r\x9f\xca\xff)\x1f\xf0\x94\xdfl\xa7x\xf7\xee\xfb\xfd\x1f\xf2\xd9\x8c\x08\x7fq[\xf5\xa3\xb3\"sSq\xf2\x95x\xa2\xa6\x19\xacX\x8c\xc0%S|o\xc49U\xfe\xe9\x18\x91:nT\x8cr\xca\x06\x89\x94\xae\x1cWjcD\xf59\x0eAaO\xf9T\x94d\xbc\x8bhBL^\x97\xc4\xb8\xbc<\xa4\xaa\x9aL[\xe4K\xe4\x14@-1\xe1c)+S.\xd9zZr\xfdP\xecx\x99\x97\xbe\xaf/\x9b%\xb9\xf4-\xa6\xd6\x16\xc3\xb2\xc5\x17\xae-F\xd6\x16\xb3\xb2\xc5\x1b\xae-&\xed\xb3\xbey\x13\xb6&e\xd3?\xba6\xadI-\xaf4\xbd\xe5mQ.\x87\x8f\x16c\xb7\x06C\xd7\x06\xeb\x898L\x0df\xae\x0d\xce\x1d\x1b\x9c\xb4\xaf\xf8f\x83\xdd:57s\x1d\xdf\xb41>\xf5\x17\xf1R^\x83\x85x\x91\xfc#\xe1\x7f\xc4\x8a3+\xcf\xd5\xcd\xee\xbc$kL\xcf\x17\x8a\x17\xe2)\xb9\xc0\x1b\x19\xbf\xf1$\xcb\x92I\x84\x99!\x00s\xb8\xc4e\x00\x1c`x~\xdc\x97m\xb0\xae\xfbe\x0bl\x00\xfd\xf7\x04k84\xe9\x07\xa6\x19\xf8\xfb\xdf\x8f\x8f\x8f^\xbf\xfe\xf8\xe1\xc9\x0f\xaf\x0e\x8f\x8f>\x1c\xbe\xc3?\x8e\xff\xfew\x8dji\xd5\xfc\xe2\xe5\xe1\xef\x87\xcf\x0c\xaf\xcf5\x1d\xbcyv\xf8\x9b\xf1\x83i\xf3\x83\xb7\xef\x9e\x1d\xbe3~p\x06C\xb8\xdb\xbc\xbd\x86!\x0c\xe0\xd1#]\xb5\xf3S\x18\xc2\x1av@\x93\xaa\x7fi\x90\xf7\x8f\xed5\xae\xf7\xeb\x89$A\xcf\xf9\x9f\\\xa5\x19\x13-?o9\xd8\xb9q\x18\x0b\xbb;\x92\xe4\x0b}\x8bT\x1c\x0dE\x83\xbbn\xdb\xe9=O*\xaf\x7fxh9\x89D\x84\x9bF\xaf^\xa9\x0e%\x0bH{\x98x\\\xa88w\xb0JH*r\x9e\xcb\x94\x05<\xd3\xc6\xeeCLw\x11?\x84h{\xdb\x87t\x14\xf1$\x89\x11\x13\xe8\xcd\xee\xf5\xa9\xd3l\xed\x01\x0d\xaa;:\x06\xa2\n\x98f<\\\x82\xf6\x8f\x8fy\xe9|\xe2\xfd\xc1OW\xf6\xc4\xa9\xe3\xb7\xd6Tb\x85\xf5A)\xe9a\x13\xc1P\xb9\x04\x8f\x1f?6\x995\x84\x92j\x1bb\x11C\xbd\xd9\xc0\x9d\xbd\x07w\x1e\xdc\xfb~\xef\xc1]\x9ca\x19\x99\xf8&|\xa3o\x85MZ\x93\x92\xcf\x04>\"\xcax#\x90\xb7Q\xf1\xe1\x06\x9c?l\xc5\xf2\xeb\xf9\x9c\x0dm|v\x90\xda<\x19jP\x16\x9d\xde\x92Q\x91\x14\x1e\x0da'\xae\x14,\x1cJ\xd0\xd5_&\xf0xXW\xc0\x9a\x06v\xd4\x96\xbd\xf1\x83\x18\xb9\xe3\x86}\xed\xda^\xbd\xaa\x8f\xa1\xbd\x0f\x0e\x80\xab\xc5i\xc4\x986\x97/\xb6\xba\xbf l\x03\x1a\xc5j\xb1\xb4\x8cC\x92\xe5\xe2\x99\xbc`\xac\xde\n\x02\xbf\x9f6\xabT\x83pd\xd6\x9c\x07\xef`\x08{\xcd\xdbo\x9c\xb3\xb6\xf3M\x9d\xa4\xcd6^\xf1\x93N\xbe\xa09\xda\x9e\xc1\x10\xde0\x1cye:\x02\xbe\x1a\x08\xf6<\xca0\xbb\x8833\xfe\\\xae\x94!\x99\xa7\xb4Z\x94\x0b\xc5\xb6\xe0\xa0\xb2l#\xf6\xbd\x85\x8a\xc2\x01\xa4\xc5\x19\x12\x89\xb2\xc0\xd6\xd3\xd0\xe0\x078Mb\xd3\x89\xebH\xab?\xda\xa8\x82uH\x1c\xfd\xac\xe3j\xad\xdcc\x18\xd4\x0fv\xees\xebWW6\xf6\x8b\x9d1\x00S\xd5h\x8a8\xe3\xd4\xc5\xefv5\xe0\xaf\xda\xf4\x1d\x05-\xe7Un\xb5\xc5\x96\xf5\xdd\xfdj\xef\x8e3(o\x90\xd6\x8e\xde`\xedR:ze\xcaM\xa4\x9d\xbb\x92\xb7\xdaiD\xbf8\xc0X\x13\xcc,\xb8\x14\xa7.^Z\xbb(\x92\x01\xa8G\x8e\xdc\x8e \xcf\x95-\x85\xe8>M0]\x83\xb5\x80\xb5\xbc$P\xd1y\xbd\x12\x167\xac\xd5\xe6!\xe7@\xa85\xc3\xfb\x96\xa9^\xd8\xe1\xc5\n3\xd3q\x06\x0d\x92\x14\")\x15 5K2\xe3[.\x0b\xd8\xd3\xcf(\xdd\xf0G\xfb\xe8.o\xeaV\xbb\x8a\xecj\xa6\x083\xc0\xfd\xc5\xb7\xc1\xbdO\x13\x94\xc5$\xc4\xc5\"\x84\xcd\xb5\xa0\x98\x9f\xfd0\xa6\xe9\xbax\x99\xba\x8e\xf2\xc6\xb7\x8dR30\xa2\x0e\x84\x8dSH\x91\xf2V\xe8<\xb6\x1f\xadc\xf3\xbe}pr4h\xe0\"\x14\xef\xd7F\xa6\xfe\xfa\xaa\xa8\xaa\xa8&\x1f\x81e\xb0\xbd\xd1\x918\xa0\xc75\x05t\x00_\xfb/\x0f\x7f\x7f\x0fCx\xca\xfe\xfe\xe5\xc9\xab\x8f\x87\xec\xd7\xcf\xec\xd7\xe1\x9b\x0f\xef\x8e\xf0\xe7\xbb\xa0\xd2\x7f\x14g+\x9e\xed\xbc6\xaa$O\xab\x99\xb9m\xf4\x85\x1d\xf0\xe6\xdc\x0bJ\xcb\xa3g\xe3\x0em\xd6\x1b\"\xdeK\xae\xb7x\xd9Of\x8e\xed\xbc\xf4\n'\x92\xc6\xc0^V\xa7L\xbe8\xb6\xa9\x1b\xdb\xcb\xab/*\x82\xef\xf8\xb84\x8e\xb2\x91\xfc\xbb\x17@\xef\xb2i\xcfQ\xfb\x99\x84\x939yG\xb2\x962\xc7JW[\xbc/\xfc\x10d\xc5\xafB\xd6\xfb\x18\xe3\x83)\x17\x06\x957\x87\xfc\xc5\x12\xeb\xcb\x8a\x0f\xa2\xfc\x99\x14\x1c\xcb\x8f\xc4\xd9\"^\xb0M\xa3\xe8\xdf%\x86HLdB\xcb\x82d\xbc\x02\xa8K\x0f\x89S\x00\xbe\xe8b\xd6\xda\x05\xf1^\x04\xf0\xd2\x0f\xe0Ee\xf1%\xbdu\\\x13=\xa6\xdf\xe0-\xdfp\xc7\xf4\x1b\x16L\xbfQ\x19`II\x1d\x9b\xd6\x0d\xf1\xc65#\xfc\x88!\xfc\xb8\x89\xf07\xae\x19S\xea\xb5\xdd\xf5=|\x13\xa64\xbb \xde\x8f|=\x7ft_\xcf\x1f-\xeb\xf9c\x8dr\xd1o[\xcb\x97\xfd(\xe3-D\x94\xfd\x92\xda[\x86\xdeB]\xcb\xc6\xaf(ro4\xb5\xb7?\x05\xf0\xcf\x00~\x0b\xe0\x1fM\xa5\xe9\xfb\xc3\x7f\xa0\xc2\xd4$9Rj\x11\x1d\x8fCQ+\x83\xd6\x88M\x17\xf6\x95\x18z\x90\xfc\xa50.}&\xebL\xcbC\xf2\x91$\xb26\x88\x1c\xca\xf1gQ\x0b\xab:4\xd2eh\xb1u\xf2Q\xa9\x9f7\xcc\x9f{\x16:+\xe8\xd2\xf6\xee\x84\xe1,\xa8\xdd{*\x0e\x83zm\x1fCG\x91\xa1#y\x16\x95\x06\x8c\x7f8\x1aX\x90\x1b36\xf8\x13k\xcd\xfbI\xe8Z)\xf5F\xe3Ff\x16}\xbby\x0brh\xd2\xe0\x88.\xa8\xdf\xe4\x9a\xbf\x94o\xa4\xfa7~(\xdf\x88\xf5oh\xa5\x9c\x83R\xc8)TOf\xcf\xbe\xabK:\xa3\xcf\x01\x9c\x8dAd\x8a\xed \xf1t\x92Y\xc3\x16\xa0gza\xee\xdb\xa7\xc7\x05\xb9k\x9aEfG\xf2_j\xd8\xa2A\x0f\x0d>\x14\xab\xeb4\x04v\xc29\xa9\xcb\xa8`\xcd\xf4@\x8dL\"xa\xe5H\xd8\x01QZ6\x06\x01\x864\xef>\x84\x1c\x1e\x0d!y\x08\xf9\xf6\xb6\xa9\x11\x10\xe3\x08\xd1S8f\xa2\x15\xec@\xced+\x83\x7f\x15\xc8\xc5\xe6z=\xe2\x85\xa3\xc18@\xc5]8\xda\x1d\xb3/\x03P\x02\xdas\xd8\x86\xa6\x12\x0e\x1a\xe2\x97\xbc\xe4g\x8d\x87\x96\x04s\x0dV\x99g\x83tZ\xa6\xd9\x9f\xbcL\xda\x152B\x96\xaf\x9c\x0d0\x0c\x1b\xbfzV\x96B^\xd2\xf9\xc3}a%\xf0\xb7\xb7\xe11:W\x9b\x1b\x077u\xa7\xbc\x8cjOy]\xc2>\xc7\xcc\xb9P\x1f\xa9i8s\xfbp\xa4E\xbe\xe2w5\x94r}\x8e\xf4z\xa8\xe9\x93j\xbe,\x03\xb8\x05\xbb\x85?\x8b\xf0{\xf1\x03\x89\xce\xf2C\xdb\xc1\xf6\xcfbh\xff\xd4#\xce?\x85\xcd\xa0e\xab\x99\xa0u\xda\x02-\xaa\xaa \xb8\x8a\xc0\xd1WhIm\xceB\xfa\xa5X\xd6\x96BiC\xbf\x1a\xa7\xd4\x13\xaeV\x01\xf4\x9e\xf2(\xde\x8c\x92\x15\x84\xf0.\x8cO \x9c\xaca\x17\x83\x1eAX'w\x83\xea*\xc9\xba#\xb8V~\xa0$\x01\xe0\x9eo\xa2\x1a#.ax\x92\xa1\xeb!\x81G\x82cco\xef\xc4\xd2\x84s\x8c\xc5\"T\xbd\x1f\x89\xa7\x8aj\xf3\x18\x87\x86\x83U\xb1FE\x0f\xfc{B\xa2\x85\xe7\x11\xd8a\x04\xf8\x16\xc4L\xb4\xf2\x99l\xde\x0dw~+`\xf9\x9b\x1ew~\xfb6\xdc9\xd6\xeb\x129\xbe(*\xa5'\xa2\xfaa\xdd2ah\xf6\x84\xda\xdcL\xcf\xadO/\xc4S\xf5\xa1b\xc6\x1a\xfdc,\n\x01\x11\x8f\xd2\x00n\xb0\x95S\xe3\x1eN\x89SIW\xc9\xb5\xb3U`\xe4\x91\xdb\xb4KM\xfb\xe8\xad4g\xf8c]\x05\xf3J\x9f\x9dL2\x15\x7fY\xa5G\xe1![Q-\x95\x1e\xb2CH\xb9\x8b\xac\x11W\x84\x8a\x88z\xf1\x88Q\xae\x14v\xd0\xa3+\x1a\xa3\xf0\xc7:*wf\xc4P\xd1H\xb5\x1bu\x1d\xb4\x93u\xb3\x0e\xe9&\xaa\x9dBc\xf2\xfa\x89\xea56\xdd\xb45\x05\x10\x1e\xa3\xfa\xc3\xc6\x819i\\\xac\xda\x16\xaei\xa1\\\x02/Wf{\x9b\xad\xcd\xf6\xb6C\x14 CuB\x03x\xc1\xe8\xd6\xd5Q\xbd\xee\xe5\xaaC}\xae\x1f\x1eQ-\xcaW\xfa\x9e\x87\xee\xf1lJ\xd3\xf5(wM}\xa2\xeb\xdcX\xbcS\xbe\xb3JSU \xd8ju\xa7%|\xa7%l\xa7E\x0f!1+q\xcfDY\xbc\x14\x173\x82\x1dH`\x1f\x12\x83\x9e\xaf\xb63\xf31V!\xae\xee\xc6D\xab\xb45\n\xa3\xcd\x14\n\xd7\xb5=\x05\xb8\x8c\xfbS\x01\xa1qw\xa6\xad{8\xb9\x8e=\xdcm\x15$\xe4P\xd3\x1a\xfdu{>g{>w\xdb\xe3\xca\"\x8e\xa6\xe5!\x17\x8bC.\xd6\xee\x8b\xc2[\xc5a\xad\x19*\x96\x121\xaeeEhR\x84\x0c\x03\xf7,\xb1\xe5w\xafj\x96\xb5\xd4\xb02\xe8$\xbex\xb1A\x06-vq\xf4\x10\xb6\xbc\x08O\x05\xb5*#(\xb9\xbc\xbdHT]\x84t{[\xec*]\xfdR1\xe5F\x8e -LK}\xf5\xb5\x025I;C\xd5\xa0\xce\xf9\xa2j\x89\xf9v\xf9hh\xd6\xb0\x02\xdd\xb7\x1aQ\xd6\xa1E\xcb\x81\x8b\xc4\x9d\xd1q\x0f\xe0\xd2\x08\x15\x9e\xd3F\xf0R\x81\xf2\xe9\x7f\x01\xcaW\xea\xc8\x17$\xb0\x08!\xe0\xb6\xaa\xa6\x83\x80z\xa0\x14\xc6\xa8\x87\x0e\xcc[4J\xc6\x01#T\x8dC\xc206\xb6KbEK\xc4w\x89\xb1\xf2\xbc\xa4\x9b\xb1M\x9b\x84&\xb6Q2\xe6\xe1\x90\xc5\xd8\xf2\xea\xc0NR\x12~n.\xa8 \xdb\x1a\xc7\x96vy\xffc\xbb\xaf\xb6\xb0F\x82\xa6[l=\x10\xafc\xef\xe1J\xc0\xe3\xf2XmS\x18\xb6oT\x90p\xe3En\x8b\x8dkQ,\xf2\xa0<\xb1\x87\xb5\xafY\xad\xcb\x92\xfdMG\xee\x0c\xefZ\xd0\x805\xbd\xba\x8b]M\xd0\x86\x03\xe8\xbd#+\x12R\x18\x8d{\xb0_\xfe\xe2^\x10\x8aZh\x1bz\xe5=\xfc\x96\xdd\xa1\xd1\x92d\xd0t:^_\x9d)\xd71\xe1|\x08\x1a\x06\xbc\xd2\x8f\xac\xf4\xe3\xca\x85O\xa9\xaa\xf8jFe\xd5\x9a\xc7\x94\x05.\x13\xa9\xec\x1f\x06*#\xca+1{|\xaa\"U\xd2\xba6\xb2\xd7\xa2\xba\xe4\x0e\x0f\xa6\xab3\n\xf5\x91\xa6\xe4\x8c\xa4Y\x177\xed\x16\xb8N\xc9\xc5\xdb\xd9\xd5\xc1\n\x07\xa81\xdc\x19X\xbbY\x84\x19=\xba\x86\xaeJ\x0cm\xed\xf2\xea\xc2\xd4\xeeC\x88\xe1\x91\xb2\xc4\x10;i\"*\xc3\x8d\xeb'ZlUB\xc4Ns\xe9.\xe5tbU\xbb\x11k\xc9f\xc2#\x88%\xc5)Y\xa0X@\xc27\xd6\xd9\x83\xeb\x12?\x1c(l\x05\x9a\xc2H\xe9\x88\x87\xb4\xaaz\x87\x83&f*S=k\xda\xfb\x19}_\n\xfa\xbe\xbcf\xfa\x8e*cI\xde\xf9\x0f\x85\xbas\xed\xee6\xf4\xfa\xfd~y\x97\xc4S\xd8\x06O\x08\x15\xf3B\xcd{\x00=8YW>'+\xcc{\x84I\xe74'\xc1\xf2zO\x029\xdcR\x17 \xdfU\x87\xd28#\x96W:#$\xe7\xe0Q\xd8Q\xfb\xf6\xe1\x96\xd2\x9fq\x7f`\x80\xf4.7\xc8+d\x82\xdf`k\x84:\xf1\xd9\"\xd1\xd8\x1ejCv>wj\x87J\xd1\xa9r\xb8\xa0K\x01\x9e!\xe5\xd3\x80\xdb\n\xf0\x8c)\xef\xfa\xf0hX\xf8\x96.\xa9\xb7\x1b\xc0\xae/\x8e\xa7\xa5@\xeeSB=\xd5* M\x06\xec>\xd1\xdcG\x905\xcf\xae\xe5U\x0e\x9b\xb3\"\xaa\xb2\xb2B\x0d\x85/\x18\x031.\xc3\x1c\xd4r\x07V\x87\x03\xe1Z\x89N\x96\xece\xeeSa\x19((x\xba\x0b\x1b\x93s\x14\x1e\xa1qY\x8d\xd3\x8b\xe1_C5G\xd1w@\xfd\x87\x0c1\x94\x9b\x0f}\xc0\xd7(\xdcR\xdf\xb5\x12\xdcC\xea9\xa5J\x8f\xea%]\x145b\x99\x9a\xffg\xaax\x99\xeb1\x0d\x94UxEG\xd4\x9e(\xb7\xea\xb1\xf2\x96ao\x00o8\xac\xdf\x89\x9c\x19\x14\xd3\xe1\xc0+\x9e\xe8\x1c\x9f3*\x8e\x8d\xb3\x83\xef*Y\x16`\x9fw\xd6 \xc7\xe7a6\x7f\x9aLU\xc8\xc8[:\xe5bT\xaf\nV~\xe8\x08B3\xe3\xf9\x9a\xd6\\M\x11~G\xdccM\xadPji\xa3\xfe5\x1d=\xa5c\xa7/\xb7>\x1b\xc7\x0d\xa6\xc6\xfb\xa2\xea\xc1\xfa(;\x8c\xf3\xa5\x08\xc0Bw8\xdd\x13\xa7\xb1\x98:k\x07\xaf\xfa\xb5p\x98\x8c\x93)\xf9\xb0^\x11@\xd2\x9e\x9dG\xbc\xfeYq\xbf\xad)vM\xc2\x8c\xc0`\xbf\xf5=Ph\x7f?\x8f\xa3/99zf\x9e\xa3\xbc\xb0\xf9\x07\x1d\x9b\x9f&\x13\x0c\x18>\\\x10\xf6\x0f\x9fl\xedf1\x06k\xd3z\xa56\x88-\xa5\xac\x96\xf6=\xfd\xd7l\xb9\xb6\xb7?\xd0@=\xfan\xc2\x07\xbe\xf7?\xe0\xde\xb7\x84\x88\xbc\xa6>\xc3\xfa\x8c\x18=\x1c\xc1\xc1\xd1\xb5\x8aB\x7f\xc8\xfa\xc8C\xfc\x81.\xcfu\x8f\xc1\xde\x9b$\xde!<\x95q\x19H\x98A\x98\x12,\xfa\x86\xd9\xb5\xc9\x14\xc2\x0c>\x93u\xd67\xd5=\x90\xdd\xb3\x0d%\xa2\x8dy9\x89\xd2#$\x80\xa7\xd4\x14W\"/R\xec\x9b}\xd8\xb2\x04x\xb1k\x92\xc4\xb3\xe84w|\xfb<\x8d\xa8\xdb\x9b\x82O\xd7/>\x80\xb9\xa4\x1e\xa8\xe5\x0d+N\xf5\xddH\x86`\x93\x95H\x12\x85\x83\xd7}\xe0\x1b\x1b\xb2\xab\xdb\xd4K\x95\xb5\xdd{\xee\x87\xab\xd5b-\xd8xCD\xbfz]\x06\x162\xc9\xce\xc0\x16\xc8\xb6\x13\xc1\x8aSzI\xf2\x1ax\xff1F\x08\xd1\x042B!\x84\x98\xed\x83\x12rr\x8c\x90\xc4bOXQ\x9f]T\xce\xc1<\xfb\x0e\xf4\xc4z\xeaw:\xed\xa5\xf2\xb5 k\x8caP2\xdah\xf3\x01\xd4\xa0\xc5\xcb)\xb3&y\xfddT\x93\x96\xa5y\x18\xf7@\xa6}G/\xd2\xb7\x06\xde\xbeP\xc7\x10\xce(\xa9\x16\niiG\x03\x05\xbep{\x00\xdf\xf1T\x85\xfd\xc9\x829\xf3Ld\x15\x16\xd6\x97)\xdc\xbdu\x9d\x11\xfcW6_r\x85\xa7\x92\x01\xeau\xb82\xa6<\xfb\xfa\x8d\x96\xc5\xe34IJ\xcd,\xfb\x81\xa2s\x11K\xc3\xf36\xf9:\x93b\xa5\xeb\xacS\xd7\xffP\x93B\xd9\xe7\x94\x11z\x14wh\x1a'\x92\xaf\xa6!%G\xf8\xf22h?c\xcd\xdc\x92}p)Y&g\xed\x92\xb6f\xd6K{\xc3S\xb2 l\x02\xaeM7f\xed:\xe5e\xd7)\xf3N\xea\x0bbO\x1c\xcdE\xc8F\x89\xcb\x03\xe1\n\xe2K\xe3L1\x81\x11\x1d\x8bF\x1d\xc6\xd2D\x0f\xc3h0\xd8\x15\x9d\"E,&Gq\x8b\x8flA\xa2]\x12I\x9c\x898P.\x80-\xcd:\xd1\xbc\xd5\x17\x8f\x91\xbb\\\xf8\xe1\x99\x89\xe2\x99H\x19\x93`\xf0Hk\xc5\xd8\x0c\x86\x10y\xb6\xb2\xdcb\xb92\xbe\\\xc2Y\xb7\x19C\x06F\xa9\xe3\x94z \x03\xb2\xc8\x1b\x9c\x11\x1a@/\x8ay\xb5\xfb\xcfd\xfd3V\x883Cf\x82%\x80-\x1e\xa8\xec\xa5\x99\x98\xf2\x92M\x19\xa9\xd5\x84\xed'\xf3\x07X\xa0\xd4\x9b\x95\x0bhU\x94r\xd6e&f\xcf\x7f-\xd9/\xb1\xdb\xbd \xc3W/)y\x19\xe2\xe3\xd91 `\xa1\xe1\x01\xc4\x9e\x8fc\xd4\xe9\x1a\"\x1eE\xdfi\xd1\x9b\xe0\x9a\xea\x96\xd9\xfa\x0e\x98,Hh-J\xa44\xdet\x8b\xa1\xdc\x1fB\x1c8\xc9yL\xd2\xa3gp BaE\x0c\xe3n\xa0\x9e\x14CQ\xb4S|\x83\xc1\xfb\xc3\xf2\xac\xe0w\xc3\x05\x15\xf5N\xb6\xc4M_pw\xd6\xc9,Iz\xda\xaat\x90\x90\"\x02\xae\xb2ks>\xc0f\x1f\xbfF\xd5\x92c\xb6\xf3\xa4\xe8\x08\xfd\x97\xea|\xd2\xa0\xe9\xc8\xd1\xec\xaeJ\xa0\xec\x86pM\x0fFl\xa9\xd2L\x12 \x84\x03\x07\xad\xaf\xf8\xde \xf0\xf3e8\x90\x7fI\x1d\x0d\x12\xd5}\x88Gj4^\xb3\xa8m\xcb\xf1\x81M>#\x18,\xdbi\x9d#\xd2m\x8dY\x1fN\xeb|%\xd0\x17\xc3J\x88\x87b\x85\xe3\x88\xfe7\xa2\x02\xae\xd6\x81\xfa\xebzQ\"KR\xea\xca\xe7\x1c\x11\xef\x17R\x98\xfd\xdb\xdb\xfda\xdd\x81uT\x1b'\xed\xedWd\xa0\xd6 \x14\xb2\x16[\xa90{\xcdu\x11:\x06@.)\"\x16\xe9\x9f\x87\xd9\x13NO=\x1f\x8f\xa1\xe3c\x12gyJ\xde2z\xedU\x89\xb7d\xa5\xac\x03/zw\xdc\x83\x8d\xf3\xa1zn\xa8\xa3a\xa2\xd8{;\xd8\xc2\xecHjb\xba\xf5\xaf\xf6\xd3\xb22\x05\xc8\xba\xf5 \xce-k\xdb\xdd\x1c\x9c\xa4F\x84\x9c\xc3\x0dw\x99\xa7\x93\x17\xda\xb7:1+\x87{\xe1m\x83r`3\xb3H\x0b\x11\xe1\xc1v\x1e\xc1\x043\x043\xca\xe8l\xee\x01/\xfb\xd4\x02\x01e\xb5[\xf7\x96\x9cI\xc9\xe0\xe8\xb0\x15\x0e\xe0\x9f\xb4dmT\xb6&(\xf3: K\x83\x1c^\xad!%\xf7\x83\xca\xe0\x0c\x04\x83\xa3\x99N\x941\xc9}\x08\xcf5\x9eC\x1fi\x00?\xd0f2\xe0\xd7O~6TO\xfb\xc2\xdeV\x81dR\x0f\xfenN\xfc\x81\xc3oNH$*j\x18\x1f\x8c5>\xac @\x0c\x9d\x9cDt\x89\xe0\x90\x90\x8f\x13\xee\x82\x1c;\xf5\xf9\xcbU\xfa\x9c$yL\xaf\xdc\xe5\xcb\xabt\xf9\x99\xac\x7f\xe4L1i@\xd7\xad\xdb\x17\xd7\xd7\xed\xda\xb9\xd3\x1b\xed\x9d\x1eS^j\xb4\xdc9E\x84M\\\xfa6\x87\x93\xcf\xc8\xbc\x14\x14\xe5'\xea\x89_n\xda\xd0\x1f[S<\xf2\nH\xa6}\xac\x0b\x025!\x0f\xad\xa9,$fGAA}\x10u\xa9FM\xd1\xd4Q\xf8X\xe4\x0c9\x84\x08w\x9bN_a\xc0G\x11%^\xe8\x97\xf8\x82\x06\x10Zy\x15&Qq\x89\xcd\xd3~\xba\xcf\x10Q\xac'e\xfc\xc8\x85\x17\xfa\x01\\x\x0cU\x18\xc4_\xc8\x1c\xae#\xf6\x99k:wB\xec;\xbeVy6\xf74\x9eEF\xf2\x92K\xa0En@\x8e\xac@.v=zm\x95j\x95\x9b7\x01\xb3\xb0V\xd4+<'c\x91\xd8\x97o\x7f7\xce<\xb1\xef\xeeR\x9433\x15\x002\\\x0cu\xf8Ue\x1a\x8e\xb7\x92\x8c\xba\xf2\x9c\xab\x84\xcc\x9ax<\xb9\x8a\xce\xadjx\x9e\x8d2\xf2\x85\x1e>jY9\x13@r\x97e\xe1\xdb\x1c-Cq\x7f\x16\xb1\x93\xc1\x01\xfd\x8a\x8f\xcb\xc4\xb9\xcdA\xfa\xbeb\xedb\x07\xb2\x9af\x17\xe9jy\x8am\x18\xa9\xc0\x94\x87\xca7W7\xb5\xa7\"\x1a\xaa\xf8\xc4\xb6\xe2\x80&pq\x1e\xa5U\xabi\xab\xf7pE\xfe^\x8a\x1a\xa3\x08x\xec\xd2\xf8\xad\xc6e\x02o\xabA0\xa6\xa5\x93\x17\x95n\x19\x86\xf4\xb1\x97\xd5z\xd2\x05A\xc3\xb2\xd2\xf1(\x1a\x17\x0e!\x9a\x81bf\xf2\xca\xd1\xe7\xc5\xa3]G\x89#l9iA\x84\x86x\xf7\xef\xde\x7f\xf0\xe0\xf6\x9d\xbb\x0fx,\xcf\xce\x10\x03ax\x1c\xcc\x9d\xdb\x83{w\xef~\x7f\xef\xae\xef3f\x0f\x1f\xec\xc1M(\xbeQ\xee\xdfa'\xd3\xde\xdd\xbd{w\xee\x0en\xdf\x0d\x80\xc2\xb6h\xea~\x00\x83\xbd\xefy\xf3\xf2\xde\xe0\x9e\xdb42\xe2(\x85\xa4\x02\xc5\x0fm\x15E\xa3\x11\x19\x0b\x01\xa3\xd6\xbb\xfa\xeb\x0b\xba\xba\x08\xde\xec\x0b\x15\xe6p\x18\xb2\xbf\xb9\x15.(\xffD\x9dz\xf1\xd2Q\x1c\xc0\xef-N\x11\xe6\xb9T\x0eCUz\x17\xc7\"g.\xa2\xf2X\x84G\x90\xf3\xd3\xd1HH\xa7\x88\x9e\xd1(\x193\xd4)s-\xb2\x1b\x03\xe7R\xe6\xb5Y\x19\xcd\xf0*\x1fi\x9d!\x16\x1b\xe1;6\xc0\xd3\xb9:\xdd \x9f\xee\x0c\xcfc9\xdd <\x02\x8cm\xda\x9abB\xe0l4\xc1I=\x84\xc9\xf6\xb6\x81![\xc0\x90\x7f\xa7\x17\xc8\x16p\xc0\x9b\x19\x8cq0\x11\xec3\xeeWQN\xea\xbf\xe3|\xb0\x17\xa2g\xd4\x02]\xc9.\xbc\x84IQaIH\xb3\x96\xec8\x18\xc4\x81\x0e~[!\xfb\x7f\xe1\x9a\xf0x\x08\x13]\x98\x8a\x15y\xe4\xc5\xa5Z\xe9\xb1\xf8\xdebp\xaf\xa0\x9b\xe0\xfah\x00\xe8\x88\x1a\xc0\x88u4\xf6+\x1c\x19q\xe1\xc8\xe4%\x9d\x0d\xc8\xc8\x94\x00O^\x11b\xb5 \xff\xb4\"\xa2\xe6\xa8h\xc9\x8d\xd5?@\xcbE\xc9K\"\xbb\x9e6\xb3\xae2\xabQ\x9eMa\x05\":LQ\xf0J9\xd3\xd81\x93\xf7V\x0c\xb7\x90\"em6\xff\x03\xe4\xaf'\xc2\xf6\xbf\x03\x038\x80y\x7f\x95\xf0J\x10\xf3\xd1\x84Q\xa3\xc6\x8d\x11\x1b9\xe3\xc7\xe7\x9c\xc1\xe4\xbf\xfd\x00{\xf6j\xda\xbfyi\n\x97\x02s\x00\xf36\x96\xf42\x80_\xafL\xce\xb4\xd1e\x88]\x86\xcd\x8aB=\x13W<\xafZ?\x9cG~R\x94}\x0c\x9a\x91D\xd2\x10\xae\xe95\x126\xd60\x93snr\xee\xae\x08\xcdF\xe5\xec($\xfc\x11fF\x1e\xf38..#\x11\x1d;Q\x07\xcf\x95\xe9b%3\xb4L\x00\xfd\x84z\xa9 T\x8a\x80H\x04\xcb\x13#\x90\x88E\xaa\xcc$|C\xfd\xf3I\x15\x86\xfa\x97f\x18S\xb95\x04o\x027A\x87\xdaH\xd7\x90PGue\x8e\x96\xa0J:\x1d\x12\xde$\x02_\xdf\xf9J\x8e\x10\x97K\xff\x0e\x1a\xdd\xe1\x00V\xa3\xc5\x18Z\n\xb1sE\xd9\x9c\x9b\xc5\xf8BW\xd7J?;\x1e%>w8(8\x1c0\x94|\xa5\x90\xf7\x99\x95\xbc[\xdc\xbc*\x15\xbf\x04C\xc0\xf63\xaf7\xb3\xf6\x03\xc4\x8c\xdd\x87\x82\xd5\x8f\x1fB\x88i~\x18n\x0ca\xe0C>\n\xc7\x88\x067Q\xb3@F\xc9\xf6\xf6\xd8R\xb3\x0e\x14\xa1t\x94\x8e\xb9\x8a\x8b\xf5\xc8M\"\x98\xe3A\x1f\xcc\xcf\x1e\xaf\x02\x98\x04\x10\x0605@R\x9c\xe7\xec\xffj\xb9z\xb5H\x7f\x93*\x11\xb4x\xb2\x04\xb6\"\x12\x0df\x81c\\\xeaWxS^q\x0eRQp.W\x88?{k\xe03V4\x1fc\x9ck\x0e\xdb\xc6\xd4\xb8\xd0~xs\xa8iA\xd6\xc2!\x15\x1c\xb6\x84\x9a1M \x14\nu\x84\xda\xb6@\xaa\xa8\x84\\!P\xb8\x80.\xa9\x80\x8e\xab\xd6\x10tb\xcf\x86\xf0\x08\"\xdc\xb1>\xbb%h\xbb\x97\xf0-\x1b\xf3\xd7w\x06\xa8\x9d\xe5\xf7\xe8(\x84m\x97rn\x86\xc2\x1f*\xee\x19\x8f\xcc\xe3\x82\x9d(\xac\xa8'5\x93\xe6y\x95\xbb\xe0&\xda\x93\x00\xce\x1b\xe7\xe5/\x7f-;aa$Z\xf8\x08\xce\x10Df\x11)\x81\x03Ht,\x82\xceo\xf2\x97\xffel\x82\x94\xcd\xb4/L\x1cNa\xc6&LF\xa1\x81Lg<\xf8\xc6\x911\xa0\xc4\x9bu=\xa2\x85#\xadC\x0f\x05O\x81\xf6z\xc3\xb1\xd2.\xc3\xed\xec\xac\xe0\x11,\xae,\xb7U\x08\xecn\xa0?\xe0cy\xc0s\xa1y\xc0%\xe5R,c\x14d\"\xce\xfc\x0c\x1e=\xc2#\xbf]L\x9b\xa1\x98\xa6[\xac\xca\x9beT0\x1e\xb3!\xfe\x89\xb4\xd1\x8b`3d\xc2T\xce\xf9 \x06yc[\xad\xf2ZIB\"-k\x01\x92\xbd\x98 \x87\x11\x1a\xcd\x8c\xab\xedm\xfd\x9a\xcf\xbb\x9e\xf2\x8cS\xcc\x88\xc7\x99\x99\x05\x93\x9c\x8cta^\x90K\xe9\x00\xb2\xaaQ\xcbi\x95ZrNj\xc5\x98\xa4:\xd9xyej\xf9\xdf\xacKz\xf9\x9f#\x86\x82\xae\xe9wy\\\xe6Z\x14\x86\xbab\x8e\xa1\x92\xc0\x8f+\x7f\xb8\xbe'&\x8a_\x1d\x0eZH\xe1\x9a1\x14K\xf2\xff }WXr\xee\xb3\x8a\xd5\xf4E\x99\x97P\xc0\x92M\x80\xb1\xee\x13\x93\xf1\xb4\xb3\xa6\xa5]\xcb\xf2\x1f\xd4\xb0\xbc\xd4\x00`\xde\xd8\xe0/\xae\xbc\xc1\xa5\x18\xc3\xa3B\x0b\x9f+\x86 2\xa2\x8e\xdf\x18\x8cu\x0c\xc9\x8b\xeb\xd9\x835U\xaev\x99\x90\xe4!\x06W\x87i\\./\xc3\xea\x19\x05\x12(\xf3\x08\xfd\xc6F\x0ce\xc0\n\xc3H\xd8\x87\x0c-\x01Z4\xaa\xac\x1a\xb68,\xca\x10\x89e\xd3\xe1\xadXv\xde\xa5f\xd7#\xd1)w~c\x91+\xba\xf3\xd2\xb9\xf6\xa5\xfeve\x0d\xac\xa4=n\xd0\x91\x94\xd3\x91\xa8V\xb6\xe8!\xa4\xa2\x84L\xea\x94\"9.\xea\x97\xa0\xe7\xc1X\xadwY\x9f\xdc\xaf\xfaY\xfcrm\x93\xe3L\xa6\xdb\xd4\x0c\xbcN!|\xd5\xe6\xa5\xe7w\x18(\x12(\xb3\xcf$\xfdJ9\x06\x13,@\xa7=}qE0H\x8a\xac\xa0k\x03\xad\x88w\x83\x06\xf0\xd5\x0f\xe0\x86\xdaKL.ZS;\x14P\xa6\x12\xca\xe8_\x19\x94A\x02\xdc\x99\xf2!\xd8\x8b6\x88\xfa\x13\x04\x17\xc9\xac\x0e\xc7\xd4\x98<\x0b\xaa\x8e#\x03)f\x8b\x89Z8\xd6\xa8\xa8\xadZ\n\xe1\xdcg3\xd5AI^\x97en\x9bT\xee\x96\xb6n\xb0\xbe\x99\xa8b!>Q\xf0\xce\xd7v\x1f\x91l\xc4\xc1'\xddS\x0f\xb0\xcc\x1e\xafy\xd6:6\xb5KD\xfbj\x87v\x95FR~f\x19\x83]\xd1\x91\xb4I\x0b\xf8\x92\\\xa6\n\x00\xe4]\xbb\x0cQ\xc3/\x18\xc2O\xd4K\x8c\xf6s\xb0\x8a\x0b\x93$\xa6Q\xdc\xa9\xf8C\xb3\x7f\xe5W\x9f\xfb\xcc\xb6\xecj(\xb7\xa7ic\xb4\xe6J5\xe6I\xad\x11\x90*0\xd9*c\x1e\xea5\xdc\x82;\xcd\x96g\xf2\xd9^\xf3\xd9\xa2\xf8\xce\xe4\xb9\xbf2x\x0c\x9c\x89\xd8\xa1\x0bc~=\x87<\x96\x9a\x88Z\xf6\xe5\x9cxJ\xcaI\x8d\xf0-O\x82\xc8\xa3\x96\x0c\xa3\xb1\xbd\xc6\x03\x1fL*t@\xde3~\\\xa7\xf0\x98g\x8dN\xe1\x11\xac\xe1\x00\xce\x89\xb7\x8b\x0c\xcfY \xe2L\xb1\x10\x04\xf1\xe2>M\xb8\xfc\xedcYZ\xd2\xd9-\x06\xfdD\xdeG_ \xf6\xacI\x03\xd2\xa6\xe9-4\xb5-\xfe&:/\x127O\x8b\xb9\xddaD\xc9\x032%-y@\xd8ArN\x19\x9bL\x1c\xf2\x80(\xc2\x87g\x8e\xb1\xe49\xbc\xc4\x11\xf7\xad9-^E\x19\x85Q/\x80\xde\xb8\x99\xd4\xa2\xd2\x93cR\x8bH\xd6\x8a/\x93\xe2\xfbEVrZ\xcdJn9M\x99\x00[\xb0\x96\xe8+\x83#O\xd2\xe842y\xb6I\x99\x8b\xf5\x14\xf7y\x99P\n7\xe1T\x13\ni\x02P#\xbbF\x05\x06\xdd\xb2k\xb8\xda/\x10d\x84\x83\x8c\xb3U\x95\xaa\xf9&\xbfo\xf4\x0d|\xac:\xb1\x11x\xa4d\x83\xed\xee\xb2\x06x,<\x82]8\x80\xb7\x82\xc7\xc3m\xb6+\"L\xdfJ\xa7\x04\xb4\x00\xf0gD\x1b]\x06`N\xb0Gp=\xe5b\xea\xdf)\xed9\xc74\x8c\x16v\x86J\xba\xf7\x1b_J\xac\x81\x02\x08\xc5\xcf\x18%0 W\xe1$\xa2kn\x10\x1f\xc2{t\xc2\xabG\x0dpy\x10E\xac\x88\xbf\x14\xd5^\xa2\xfd\xe3\x059#\x8b\xf2]\xf3\"n%\x8e\xe1\x06Q\xfa\xd0Z\xee\x00\xf8\xd8\xd6\xba\xd0\x13\x8e\xc6\xec$\xd3w\x13 \xbf\x0b\xae\x8a\xd4\xf7\"\xaa^\x98)y\x0e\xea(F6\x03\x16\x16\xa9\xcf\x19\xdd\xca+`F\xd8\xc2\x0e\xea8}\x1fG\x83o%\x15P5\xa9\xb2v\xc0\xdcJ\x169@9\x84!\x1c\x96\xb9\xb3\xf4\xf3\xdfJ\xf4*\x95\x8a\xe3\xc4\xeeC\xc8\xb8\x8bi\x86~\x92\x02\x16\xd9\xb8\x10\xbf\x8c\x049B7\x91\xb0\x80\x1e\xa3\xf1~\x00a\x9d\x82ip\xf4\xc9\x8c\x92\xc6\xf1\xde\x8a\xa2^\x15G1\xc8\xf8\x1b0UX?Q\xa8oA\xd8\xc8\x8e\xb0\xfaN\x9cp0\xa9\xe2\xa0\xc9\xa2\x848\x98b\xb2L\x86]*\x185(\x88/Ez\xc8\xa0\xf1\xab#r\xca\xcdbE9\xd1d.z\x13\xca\x8a\x08\x95|\x81\xf0k\xcb\x8bi2&\xca\x0f \xaf\"K\xf3x;%\x01,I\xc0\x98\x06[\x1a\xf5\x13\xf3iU\xf2\xea\xf2\x10\xd7BX(\n\x8b\x93]\xbf\x0c\x80J\xbe\xd4\x165\xc3\x0f}3|*\x89D\x04\xe3\xb0\xeb\xd7&\x06\x95\xb8g6\xb70\x00\xa3\x8d\xb5\xa2\xc7 +\xe5\xac\x0c\x9e&\xf2\x92\xc4$\x17\xfeK\x07\x12\xc1\xf8\xf1\xbe/\xa3\xdc\xf1\xa7\x99G\x05\xe1\x97\x92\x8b\xca\x87\xbb\xe8\x19\xbb\x03\xb9\xfd\x93 F\x9a\xee@n\xe0\x1b\xf1\x95\xc7\xb0F\xdca/\xdb\xec\xa1\x02\x08\xad<\xbc\xbc\"t\x9ce\xd3\x9e\x14\xfb\xe1\xd8Rt\x04\x14\xb5\x04V{\xdc\x99\xc0>\xa3\x9a\xf6OD\xcb\xe8\xd9\x15\x8e\xa8>W\nh\xb7\x1d\x80\x0c\xab\xab\xbb\xe5G\xa89nYV\x11 \xea\xbc\x80\x13$/\xd5\x05L\xe0\xf1c\x88\xec\xdf\xcd0\x00f\x9b\x1d\xeb\xf2\x03\xcb2\xcd\x8a\x05\x9d]\xf3\x82\xe2\xb9\xf6\xd0\xe8`\xa1^l\xed\xb5\x19]tW\xa1\x8b2 }\xf5+\x12E\xf6\x98\xa8\xd3\xa6\x90\xaf_\xa1P\x85\xb6\xbel\xb6\xe3\xcb\x8b\x0dcR\xf3%lCpP\x08&G\xf2\x19\xec\xc3\xa4\x0d\xc9A\x8c<\xe7\xae\xe8\x19f\xde\x8f\xf8\xa1\x940\xd4\x88\xd9\xa9\x1d\xf9f\xb7\x04\xb0N\xc9\xb27\x90.6\x1e\xbb%\x948\xd7&\xfb1\x1d\"a#;\xd7\x99E\xa3\x10J59;\x9b\xd98UU9\xfeTT\xe5\x04oH=y\x8c\xbf\xca\xacGa\xa1$\x8f\xf0\x87\"5&\xfc\x86\xd0\x97\xe7\xfcW5\xb9W\xe8\x04\x8a\x0bb\xd3\xa8\x9d\xa2i\xd0C\xc5\"\xb7\xeb3\xf1\xcd\xd1\x14\xfe\xbe e\x13\x88s\xee\x8f/\x92\xf3\xd8c*(w\x9a\x7f$\x89\x9bT\xcc6>@^\x18\xf1R\xf1\xa5\x88l\x1b\x93\xb3\x9c-\x9c\xdb\xa4F\\G\xa1%c\xce\x8c\x9b\xf8&\x1c\x0e|cHXX5I3~B\xc9\xbcQ\x9ed\xc3\xd0\xc6[t\xccXi}\xd8\xa0iE\xb3\xea\xc8\x8b\xe3\x9f\x96n\x99jWA\x05v\x1c\xf2(\xec4xK8(nJ\x13Y\xae\x8e\xb3\x19\x83`\xc2\x9bC3OW\xa8\xd9\xd0\x1f\xa0\x88\xc1\xa3\x8ag*\x15\x1e\xa8k\xe2\xf1\xfc\\\x82-E\xae\x94\x8d\x8a\x89\x97\x8d\x02P\xfa\x91<1\x8f\xa4\xb0\xa0\xd7l\xbf\xaaeU\xcf\x0f\xf2/\x1fq\x81F\xb2\x82\xb0\x0dg&\xa4\xab\xfarJ&R\xf0\xad\xf8\xf5C\xee\xb7\x80\xae8XXuX\xf80\xf0P\xad\x14=\x19\xd8G;C8\xb3\"^[\x99wcE/k\x92\x1e%\xe8EF\x9d\xf1r\xc7\xea\x13\x19\x7f`(o\xac\x98\xf5\xd5t;\x98\x9f\xc1\xcc\xb6\xb7\xb0\xff\x89\x0b\xfb\x8f1\x1e\xb0m*\xce\x10\x1623bc\x8c\xdc\xf4>\x9a\x8dv\xf1\xefm\x0c\x19c-h<\x16\x18>\xe4\xf5\xfd\x95\xb4\x91\xa9\x9c\xe1\x9e\x12s\xc0\x0d\xbf:N\xa5\x1a/Q\x88\x1e\x13\x15\x99f2\xe8t\x1bfl\xd4\x0f}|.\xf6\xd1\x84\x8dkR\xdd\xf1\x070\x92\xc6\xa3\xc9X\xec*&\xd8\xcd`[f\x1f\xc8\xd8\x9fg\xba\x11q\x99\x90=\x9e\x05\xbc\x8c\xfa\x8c\x1d\x00\xfc\xdf\x04\xff\xb5Md\xc1\xa5\xb1\x04#\x08\xf0\xcf\xd0\x7f\x08+\x06\x11\xec9c\xbb\xc9i\n\x95\xa1\xf3\xf1\xea\xf1n\xde\xe6N2\xc5 \x8aG\x18#\xc1\xc9F\xc8%\xee}60\xbc\xad\xa8\xb70\xba\xd1pda\x905\xff\xe6\xe6M\x8c\x03F\xd1l^SA\xb4\xd0\x8a5F\xb0 !\x9f\xf0\xe9-a\x08\xd9CX\xc2c8c\xff0J\xd0&K\x1c\xc3\x10\x16HA\x96z%\x89\xbcXwkAr\x8e\xc7\xbc\xdf\xf2\xb71\x81\x94\x9e\xbf\x93\x1f\xf2\x9e\xcf\x90v\xc1\x10\xe6-\x94 $\x83/A\xe6\xb1E\xc1(\xf6iEq\x92\"\x1b\x13\xfax\xd6=\x1e\xc2\xca\x87\x9c\x81c\x85\x8b\x86\xfff\xdcmaR8(4\x9a\x12z@\xde\x96.|\xb2pGf\xc2q\xc4(\x15\xe2\x87u\xe5\xc4>\x9cX\x85\x19\xb60'\\\xe8~\xfc\x98\x1d\xe8\xb6\x85a\x038A\xea\xba*_\xf7\xe1$%\xe1g\xf3W'BP\xdb\x1e\x82\xc7\xb7\x94\x0f\xdf\xc1 n\x92\x9d\x022b?\x8dN\xf4\xc2\xad~q'\x1c\xab\x1f\x0b5\"o\xa7\x0e\xd2\x8c\xad\xcc\x0e\xcc\xd8\x12M\xf8~x\xc4\xf7C\xe5\x83b93F \xc4\xfb\x92\xba\xec\x08\xaa\xb2\xa3\x8d\xa2\xec\x9c\x924D\xb5Fy\x9cp\xb6\x9bV\xd8\xf9\xb0\xd4\xed\x00\xc6q\x96\xeeU\x13\xd5\xbdj\xea\xea^\xc5\xc8\xc49\xf1r.\xee`\xa4f=\xba\xd1p\x1c\xff\xe1\x96/2U\xf3EV\"\xe8\xcb,k\xa1=\"\x04\x93b[\x99\xe0 Z\x01M\xe9{&\x1c\xc2\x8f\xc5\x9eMp}E\xa5\xbf\xdc\xcbxJI\xbe\xea\xd7\x9dR2\xe5\xf1h\x93\x0e\xe8\x91\xc0c\xe94y\xf3&O\x10Uz%'HR$\xe4\xebYn\x0c+\xf5\xb9-\xc5\x1cw\xab\xdeE\xa5\x9c\xd4Y\x9f\xb1My\xe6\xd4\xfe\x91\xbd}k\xa1\xc7\xa7\x9ce~M\xca\xfa\x8e\xecVg\xbf\x9b\xb3\xff\xf5\xf5\x1d_\xdb\xa1X\x94\xc2\x9c\xd5\x11\xce\xd4\xe0\x07\xd7\x94|U\xd5\xc3\x91bT1+!\xca\x14\xe1(\x02\xe1\x8f}\xb4\xdb\xf7\x8fy\xea \x9e;|\xc1\xed\xcb\x0e\xb9\xc3\x9d\xe6\xf4\xd4\xaaLXre\xc2\x92\x8d\xeb\x03\xf1xu\x9b\x0b\xe25B\xfd\x0c\xad\xffl\x970\x84i'\x90,\xbd1\xf5R.\xf8\xe0(3x\xfdb=6LIA\x0c\n\xff\xac\xe4\xf8\xd9\xd1\x1a\x9aT C\x9e\xb7I\x8f\xb7\\?\xd1\xa6(\xcc\x05y\x1cr\xedi\xf9s\x0f\xbe\x83D:n\xa2\x8d\x88\x1b+\x9b\xc9O\x0d\"\xac\xbcD\xff\xca|\x84\x8a\x05\xa55\xc3>\xf2\xfb4yI\xd6d\xfa\x9e|\xf1\xfc\xee\x94\x99\x8ev\x0d\\\x83\xdf\x9f-\xa2\x95\xc7:x\x1d\xf2|:\nn2\xa2\x9bVp\xb5\x8a\xb9\xaa\x933:\\\xa0\xf1L\x96}c\xd4%\xc2\xc3\x9c+1\x14\xe7\xde\\Q[0\"\x12J\xd1T\xa3\xbcTb\xcd\x8c\xb6\x99\x12\x01rD\xa5\xd0\x1f\x0d\xc6m\x8b\x9dr\xd5\x1e_G1\n\x9ej\xdd8\x08>?\xe1L\x9fK\x12Z\xb6\x90\x8bB)\xa2\x19#\xc90\xf1=\xa9,\xb4\")\x07\xf7\x0d\x17\x94#\xd2s2\x0c\x8c\x1f\x90\x93s\xcc\xbc\xfc\xae\xc5\xeb\x04\xdd\x95\x14\xaf\x93\xe3<#/\xc9:SJYH\x8a\xd7L\xe2k\xea\xf4\x8d\x81\xa6k{\xec\xde\xfc\xab?\xb7\xf9g\x7fn\xf3_[\xe2\xd8\xfeAl)b\x89:\x02R\xed\x9e\xdd`[\xbc\xcd\xabSi\x8e6\xb1?\xc0b\x8e\xb2xIkCgE\x99d\xf1\x91\xac\x7f\x86\xdeg\xb6\xbe\xdd\x07\x0b\xean\x12\xddx\x06F$\xd0U\x14as\x9a\x87Y\xab\x1b*\xa8\x1dE\xf1d\x91OIV\xafj_\xb4(_\xe8\xd6\xec<4\xb78 's\xf2\x8ed\xf9\x02\xf9\xdf8\x00\xc5\xa3\xf0c\x8c\x8f+e\xbbl\x11L\x85ZO\xebL\x01U\n\xd5\xa8g\xe5\xc8\x18\n\xafC\xf4\xb5\xa7fu\x84\xb1\xd8\x95\xe2\x9d\xdau~\\\xdf\xcb\x0e\x82wmR\xbd\xd4n\xca\xaex\xbbf1]\xb2\xf0nN\xac\xf2\x92v\xcd\xd4Z\xbeV^\xc8\xa5\xd0\xd6:\xb6\xf2*\xf7\x19\xba\xb9\x8ev[\xb2!\x01\x86u\xcaw\x95\x0f\x07\xe3@\xf9\xbb\xe1^X\xbf\xecfQ#\x19\x91\x97)\x8b\xb9\x1b>\xb2\x95\xc2\x15\xfe\x99\xc9L\xb0\x0f?\x1b\x11\xa9r\xd3D{\x9f\xb7s\xba\xad\x148\xad\x13\xdd\xb4;i1\xd3\x80\xb4\x1e\xd2\xe9RT\x99\x97%O\xcd\x85~\x0b\x19{(r\xd0G\x18&\x8c\xbe\xf6\xbc\xc4N\xaa\x15\xedp@V\x02\xe44\xbc\xab\x12\xa0\xa8\xc5\xd9\xa6J\x83R\xaf\x9c\x91\xfcXX\x04MD)j\x99\xb2\x9e(9\xcdY\xc5\xe1w\xe6\x14\xce\xdd)\x8d\x14_\x93V*\x83\x8ev\x82\xc0H\xf9\xd5\xfc\xf6\x99\xf0I\x8b8m\xb0\xbb\xa8\xa0o\x82\x95\x06I\xf9\x9dA+\x0c\x14d\xcb\x91\x02\x85\x0c\xdf\xb4\x0b\x00\x06uB\xa3*\xa2a\x8f\x7fl\xf7\\\xb3o\xf0Xe\xb1\xe2\xfan\x8f\xbb0G6.\x8br\xf6\x07-s\xce\x9c\x90<\x05\xbe\xeag\x00*w\xd5a\x9c\xa0\xeeE.%\x9a\xb6\x8c\xae\x8c\x07\x83J\x8dl\xd9\xd2 \x16=\xa1&@\xe4}\xdc\x19\xc0\x8e&\x855\x08\xee\xa1Nc\x8d\\A\x95\xc6V\x1a7\xb4|56\xae\x85;\x8c5\xbc\\\xac\x8f\x0e\xf9\x8f\xf3p-\xc5H.\x03\xd82\xc1N\x1f[d\x9b\x91\xf6\x8c7\xf7\xe0\xb4\xe5\x7fpU\xf9\xb5\x9c\xec\xb8\x19\xa3:\xaa\x19\xf1\xf8\xacH\xd4\xebv\xfcFxL-Y/[[%A\x8c,\xa7o\xf4\xe7\xb2\x03\xc5x\x9a\xbc\x80\xb0\xb5kJ\x0b\xf9\\\x87ia\nl\xde\x94gJ\x9c\x80\xf9\x8c \xf5Uy\xa1\x1d\xe1\x13\x8b[/H\xa9A\xe5\x13\xf0\x832\x91\xe2\xf6v\x00\x91\x87~ \x1c\x02hn6\xe7\xf9dS\xad\xfb\x84\x81\\<;\x1f\xe1\x04\xa6\x1a\x1f\x91X*/\xb6\x03\xad\x03\x9b\xe1\xe8\xfc)q.o\xe5F@\x06eT9\x92\xc4\xfe\x854\x84%.\\ \x08\x9bX6\xda\xb5X\xcd\xe4\x85\xd9,\xb5\x89A\xd5\xab\x8a/34\x15*9\x81\x9ecED\x91[\x1d\x91gfd8\xc1(\xf8\xe8\xf9\x1d7\xdb\xc0\x17W\xe2G\x0d\x11\xa7l\x86\x9d\xdc\x88\x98\x101\x80[\xe8\x83\x83\x81\x88\xe8\x93#\xde\xff,*\x98E\xady\x93\x18\xda\x1c\xf1:ff{\xc2k\xa4\x90\x86\x80\x1cF\xc0 \x81\xcd\x06r\xf6W^\xf4\xc8`\xd2\xa7 W\xa1+\x07\xb1\xe7\x97\x90\xd2\x0fJ8y\xe7\xb0\xa3\xc3\xcc\x0c\x86C\xee\xe9\xe7\xb1\xcd\x96 G\xa4]\xd8\xd7V\x9a8\x13^\x8d\xf6cg\"Y\xcc2\xdc \xc4\xcaZ\xd2\x18\x1a\x96\x06\xc4\x00\xb6\xf0\x94\x8a\xa4Y,,\xd2\xf8x\x93\xfaY\xe1p\x0c\xcb\x0c7\"\xdc\xb4L\nDDQE\xc9\xa4m3:\x89\xe9f4~l~\x00\x93o\xd3SEV\x1e'*\xb2\xea\x95\x8eY\x06B\x87\xd6\x81J8Nu\xfd\x95S\xc3\xa2\x03\x92\xd4\xd7\x12E\x9cqW\x02\xe3\xf3I+1\xbe\x12\xcb&|o7\x1b\xd8\xc2r\x90\xf9\xf66<\x82\xa4\xdcl\x13F\x83\n\xad\x9c8\xc7b,\xf8\x80\xe7X\x84h3\xe1\xe65\x031\n`\xa2\xa3G\x93oT\xd6 \x9b\x1e\xeb\xdfi\x89\xecz:\x896J\xabM\x15\x9fy}\x1c\x96\xf7\x9a\xcfR\xb9V\x0f}\x88ZOK\x06\xaf\xed\xed\x0c\x1e+(\xdfv\x12;E\xbfC[\x04<\xbb.\xedj\x024P\xb5N\xa1\xe0\xaa1 \x96\xd4\xe2Q\x0c\xb0'\x01\xaf\xa3\x13\x88'Oe\x92\\\xf4\xc6P5\x95]\x14\x04U\xac5\x1d\x98\xbf\xbb\x1e\x98v\xb2}M<\xb0\x99\x8c%.{\x84x\x16\x97\xf73\x11da\xa3S\xed\x88n\xe1\xb4'\xad\xa4\x8a\xa7\xe4\xc6\xd3\xb2\xceuO\xfc\x92je\x0d\xb6;\xb3\xb3\xdd~\x00\x9a@\xcbk\xe2\xb9\xbf}Y\x92\xd4e]\xba0\xf7\xdf~\xdet X\xb8\xc9q\x914\x89\xda\xe55MZ(R$\xb3\x0e\x86\x82V\xf8U\xd6\x1f)CT\xa3\x0cQ\xc0\x8f\xb0\xa8\x8d.\xb4\xcb\x0d\x8b\xd2\xeaa\x7f\x99q\xa2\x0b\xac\xe47\xc3\xbfX\x07\x9c\xcb\xcb*x;\x13\xf1L\x16\xf6\x1e\xce\xe7\xd1\x82\x80\xd1)\x0fTu\x00\xda\xae\xd4\x99'\xd8G'\x9a\xe7&$\xfcz-\x86\x8fo\xb6\x04X\xf0\x17\xe9\x94\xa1\xce\x91\x18@1\x1b\xeae-\xb4\xe7LT\x0d1oeve:\xca\x16\xb5(\x10@\xe1\x9e\xb7\xd0\xf3j\x02\x8f\xb0`\xcdM\xc8=\xac\xda\x87e\xf2'\x18\xa8\x0d\xfb2M7R\x84X\x94\x03HPR\xf4\x0bIbk\x17\x8bs\x9a\xf1\xca\xac*g\x0b\xcb\xben\x96P\xfa3L\x19\xa9Y\\\x03\xb1\x8a\xa3\x96B\xe7\xd7F\xa5\x04[\x958))\xa8\x93\xc9\x04\xe4\xb9%R\xcdw2\xcfN\\\xe9\x0d\x88^RA\x01\n\xf7\xeb\xd1`\xcc$T\xd4\x10z\xa1\x8c\xa7@\xecb\xc7h\xeeM\xca#3.\x08G\x1a\xf0\xf3s\xd2N\x16\xd9\x15r\xe7\xdcD\x94F\x9b4\x96\xd7\xda\x82\xf0\x8eJ\x90\xac\xa3g\x97\x19i\xdb(`\xdb\xaa]#C\xdb\x81\xa2\xba\x99\x99~\xb1RT\xee\x91\x89\xd1\xaa:\xf9E\x12\xdc\xd0\x986:2SK\xbe'\xa5v\xa3\xe2 HZ\x8a8 \xb8\x8fR\x1cy\xc4K/\x1e\x00\xffP\xb8\x97\x11\xa3\xfb`\x91e\xdaxD$\xfd,I\xa9\x9b4+>!\x1e\x1d\xdd\x1e\x07\x10\x8fn\x8f\x11\xcb\xe9ho\x0c;\x10\x8f\xf64\x19\x82\xfd\xb2 y-+\x83q\x97\x96;i\x08{\xcd6\xeb\x15\xfal\x0d1\xd0\x8f\x06\xba\x81q\xce\xf5\x85\xa8\xf1\xc1\xdd\xbao\xf0_?z5\x85\xa0 \xa7^Zq\x8a\xfb\xbb(x\xe5b7\xfa6\xed\x82,u\xe0\xdcRG\xe0\xcaK\x02\x99\xad\x0f;\x99\xe0w\x0fC\xd8K\x9fK\x86\xef\x96\x03\xff\xea\xfa6\x07\xf6\xbf\x03g\x88\xab\xd9*\x80\xa1n\x02\x973\xb9\"\xa0\x04\x16\xd8\x00\xc2\x13\x90\xf4\xb3dI\xae\xd2\x01C/K\xf3\xa2\xbe\xd4_\xc8H\xc9\xfc\x989\xe6\xc7\x14\xce\xbe\xa2\x1c\xc5U\xa1\x88\x03\xb4\xcd\xf2\xfa\x05\xe2\x1f[s!p\x13\x0b\xaf\xc9A\xfb\x93$\xceh\x9aOP\xb3\xecF\xdf\x7f28zGE6\x1b\x1e\x81\x84%F\xe8(6j\x0d\x810\x01\xc9\xcd\x818mI\x9c\xcc9\x88\x82\x04Zs\x8aq\x0bv\x14g4\x8c'$\x99)\x15\xcf-N\x11\x089D\x8f\xea\xa7\x95d\x9f\xa9gR=\x17MX9tv\xc5\xa8\x96j\xd7\xb2\xe6e(\xe5g\xb2\xce\x8c~\x89\xf2\xdar\xe3\xca\xd4\x8b\xa6k\x87\xb7\xd8E\xb4\x11\xaeN\x9d\xc8K\xcceJfQL~N\x93\x15I\xe9Zp\xbe\xee\xad\xb0\xeb\x94PE\xb4\xec2\x06y\xa9$\x88\x87Mvj\xe2\xb2\xdd F\xbd\xb2\xcax[\x8fo\xdduJk\x89\x98\x03\xe8=\x0d\xe38\xa1\xacuHb\x08c\x88\x8a\xf4\xbc)\x99$\xe9\xb4\xdf+H&\x8f\xb6\xb3\xb0\x98\xba\xab=s\x9b\xbc\x0c\xd1\x08\xf5\xeb\xb2\x7f\x12\xc5S\xaf\x8c\xbak\xff\xec\x12&!\x9d\xcc\x01\xc1f\x1f\xd0\xa5']\xd3\xe5\x11\x91\x0b\xfd\x04r\xfdq\x88\x81\xbcK\x93\xe5aL\xd35\xd7\x95*\xca\x9fv\\\xe9V(\x81\x0b\x7f\xc3F\x95\x04\x87\xfc\xda\xa4B\x14*\xdd\x1a\xcd\x08%!\x11KT\xfd\xc8\xbc\xacp\x00\x1f\x88p\xe5\xecPmA\x1e-D\xdd\xd9<\xef\x85F\xa2AHF\x99BH\x87\xf0\x9aT\xe1;\x9a\xca\xea\x06\x15\xa8\x17u\x0e4\xfb6\x00\xe2\xbd#\x01\xbc\xf0\x03xw\x05\n\xdc\x14\xfc\x90\x02\xeb0\xa1\xd2|-n\xa0\xb5\\\x1ao\x9b\x17M\xb36\x8c\xfa\x91\xf7\xe4K'\x9a\x81\x8d\xcb/\x9bt\xe1]\x15nN\xa1BgJEf=\xbe\xb1&>Jr\xb8\xa5K6X\x19\xa3L6\x80F\x0d\xe7i\xaa\xcd\x88yJ+\x8798\xfc\xd2o\x04\x89\xd6\x80\xc01\xb7\x15;T\xb2\xa8\x07\x02\xa3\x02\xcf+\x87M\x070\xa4W\x01C\\\x03\xc32\\i\xf0\x15\x04\x18\x1a\x85_\xde}\xdb\x19\x11XB\x94\x9a(Y\x1e\x13\xd5\xc9+\xe6<\x07\xc7e\xea\x11S\xcc\xd2%#P2\xdf\xf2?y7>\xcf\xd2S\xf4`T\x9d\x17\xcdG\x81\xc8\xd7\x1c\xc3>/\x06\xa4\xeb\xcao%\n\xdd\x8e&<\x1eT\xb0\xf8\x16\x08\xca\xe3I\x7f\\\xc4U\xddS\xc3\xa0aD\xdd:\xd8\x8c\x8b\xea\xa8\x90\x97\x96\xa1\xd8\xea}Q\x88 hP\xe1JCT4\xf3U\xc0\x82\xf8\xe8\x17V\x98Wt\xcba[\x8a\xf2$!\xde\x1b\x12\xc0\x0d?\x807\xeaR\xe9\x02\x01\x1d\x89x\x11\x0d\xd8\xa4\xe4o\xbems\xb5R\x1a\xf3\xfah7\x9d3o\x86;\x0cA\xee\xca\x92ig\xea\x86\xf7\xdf\x84\xb0\xd7\x82\xa1\xc4\x15C\x89\xc4P\"14\xe5\xa6\x10\x81\x97N5\xc3\x88\xf7\x8a\x04\xf0\xa3\x1f\xc0\xabo\xe7 ,\xc8\xf7\xeaZ\x90\xef\xcf\xc40\xe2\x8e_\xda\xc9\\\x1b~\xfd\x87\x91\xa8\xc4\x9f\x8e\x88\xf4Lp\xba\xcfT\xe8\x10!\xcc\xb4\xf1\x10\xcdu\x14,D\xbd\x9fg\xff\x95\x88\x84.1\xa6\x87\xec\xfa\x89x\xc6\"z\x8a\x93En}\xab@W,\xd1\x8f\xc2\x00:vr\xb1\xb5\xbc\xb9\xcbo\x1a\xa4Xv5\xf5rZD\xd7\x02\xfb\xbf\x06\xd1\x1d\"C\xdd\xf6\x02\x14\xe1\x95\x15\xb7p\x8b\xf3\xa4\\/\xd2\xe6e\x89\xde\x95\xb6\x11\x02G\x0e]\x18\xa0zI\xde%o}S\x0c\x1e\xf7r\x04\x07<\x91\x0bG\x89\x14Q\xa2\xbc9\xe07\x07\xcd|\xf9\xeaepYt\xa0 \x95s\xb8\x9a\x86\xe0\x9d\xf9\xd1+\xf3\xa3g\xe6G\x98\xa3\xcaK\xe3\x00N(\x13-b\xe5\xcdoT\xb0\x86\xb1\xe0A\xb7\xa1g\xd4\xb0V:\xec||V4\xea\xec\xf3\xb7\xe7qi\xf2\xb1w\xe6\xa8L\xe0i\x9e\xe6Eut\x1b\x9aW7oep#\xaa\x89S\xae\xcc\x85\x89\xaf\x07\xe5\xdfRg\xa1\x89\xd9\xac\xcf\xc4I\xf9[J&Z\x95\x15\xef\xff\xe6Me\x00\x15}\xae~\xb2R\x99\xa0\xda\x06\xcc\xd3\xec\x1f\x93\xe5\x8a\xaeQL.~\x0c!\x8f\x85\xa8\xfd\x1bm\xa6<\xadM\xd5Qc\xdc\\\xb4\xd2J\xcd-\xd4\x7fS\xacZy\xfc9N\xcec\xf8L\xd6\xd0\xfb\x1bl\x03\x85m\xf8[\x0f\x92\x18\xd8/\x89\xc7\x06#y\x05z[%\xf8D1\xfd\xb2\x16\x87\x16)\x1c\xf4\x86\x15cBu\x892\xa9\xd7j\xc1\xadJY\x08e4%\xce\xc1~\xb9\x0e\xcd:\xcc\x955pT\xae\x1b7\x8ey\xa6\xc48\xfb({\x8f\x9a\xf8I\xdcT\x01\xcd\xe2\x00\x16\x0c\xc7z\x7f\xff\xfb\xf1\xf1\xd1\xeb\xd7\x1f?<\xf9\xe1\xd5\xe1\xf1\xfb\xc3\x0f\xc7\xc7\x7f\xff{\xaf\xe9\x08\xb2bog\x0eJ\xa3y;\"\x18\xaa5\x91z\xb5& \x05Y([j\x88\x91\xcd\xe5\x87\xa6\xf4\x8eg\xa0^\xae\xe8\x9a\x87O\x17`tSDL\xdb\xf7bU\xc9\xb5\xb2\x04a\x94\xd9\xeck\xe5\xebb9-\xca\xb3z\x97kJ\\\x93p\x9fY\xe9\xd2\x0c\xf3\x0ex36\xdei\xec\xe9L5\x86v\xd7\xdf\xa0\xd2:\xe7*\xad\xd3\xb8\xd4d\x9d\xff\xbfM\x93uj\x87_\xa1\xee\xd3\x14XT\x7f\xad\xe2\xd1\"\x96\x0et+E\xa9\xb5*\x95Z\xab\xaa\x82I\xfe\xac>\x10\xac\xc1*VuV+\x17\x85\xcf\xca\xa6\xf0Y\xb5)|V\xb1\xdc\x870\x84\xb3X\xdc`[\x11Q2\x00\xe2\xadcF\x9c\xfc\x00\xd6\xd7\xa7\x11Z\xff)\x1a\xa1\xf5uj\x84\x84\xff\xbdM1\xb4\x8eK?}N\xb9O5\x94{\x19\x07p\xcc\xf6\xc9\xda\x81\x16\x9ft%l\xc7\xff!\xc2vn\x85\xe6\x92\x13\xb6%\x1b\xefI\xec=u/\xbby\xf1\x0d\x84\xed3'l\xef\x15\xc2\xc6n\xf5\xf38\x9bG3\xfad\xb1p\x8d\xe6\x7f\xef\xac\xe8~bWt\x1f\xc7\xa5\x83\xed\xb1\xba\xd7\xcecqC\xec\xb5\x13\xdck\x17q\x00\xe7\xd4\x0f\xe0\xe2\xfa\xf6\xda\xc5u\xee\x8a\xf74\x9c|\x86\x11\xdb\x10\xe3\xe6\x86\xb8\xb8\x82+H\xd5\x18?'\xe1\xb4\x89\xcf\xa8\xb7\xa2JRn\xea?\xe4\x89\xd7\xe9\xce\xceC\x1f\xbf\xe7^U\xe6\xbd\x00\x07 \x92\xd0\xe8\xe2\xfe*#_\x11\xf2\xb9\x13\x80\xd8\xa8K\xc3!\xfb\xa5\xc9\xde\xd1\xe8%\xcf\xe6m\xbd(9\xbe\xe5\xfa\xbai\x1d\nM_\xe1L\x82\xbb\x7f\xbb\xd1N\xa00\xc0l\xe0\x01\x02\xb3\xfe\x16\xec\xc0\x80A\xfc1W\x1b\xee\xec\xf8\xf8\x99\x89/\xc0\xcc*E\x1b\xa3\xd8\x90\xfb\x90-X}-\xd8\xa5I\xb4\\\xc5GC0e\xc1i\xe3z(\xf1V\x8d\x8a\xa1\xfcn\xad\xfc\xb9p\xed\xff#\xd6\x8b'\x8d\xc5{\xc2H\x91\x83`\"\xd4\xc9\x98\x1f\xda\xa3\xbe\xcf9\"\xfb\xfa\x959HZ\xa4\x16d\xc0\xf5\xd0m\xd9T\x05o_\x84\x07u\xe0\xd0\x08\xcf\x92gB\x01(\xd1\xc0P\xf5\x18\x8a\xf5o\xa6\xce\x87\x06\x19\xc5;E`\xaci\xfdIm\xfd\xe3\xab\xae\x7f\xd3\xfd\xba\xb1\xfeIke*\x15e\xb3E4!\xde\xc0\xde\xa68\xa6\xba\xb4\xcb\xd0\xd0Q\x1d\xa5\xeb\xca\x05\x83\xeb\xdd\xe9N\xd1Z\xeb\xdd\xa7\x91\xac\xae2\x8b.V\xa6o\x8d\xcf\x16(U\xc3\xa0.x\xc5X\x11;\xd8\x18\x92\xb8\x1c\x99\x8c\xa8|\x16\x8e\x1e\xc5`]\\\xc1b,.\xa2V\xe95h\xb8_{\x95\xa6\xab\x16\xaa\xa2\xa3sZ\x1f}\x99\xa6\xc7\x18\xe3W\x9cLi\xe5d\xc22gQ\x95d\xb1\x83\xe6\xa1\x8fw#\xfb\xe9n_\xc4\xb4\xb6\x88\xd1\x95\xd6\xef\x8fXWa\xba\xb6\x86\xdd\xd4V\x85.\xa9\xa9\xb9R\x10\x14\x0e\xf0L*\xa8\xbd2\x99\x8ea\xc8\xea\xcc\x06\x06=\xd4\xc5\x95\xb5\xa0\"\xee@]\x92\xf2hQ<\xbflH\x11\xf3=\x97\xd6\x10!\xad$\x13Le0H\xac$\x13\xc4o\xd2\x16&\xd0i\xb2n:R\xa7\xd9&z\x1db9S\xed\xd9\x97\xba\x9d\xdc\x8e\x91 \xad^\xff\x92\x9fH\xdb\xe2\x07D\xbf%\xa0\x03\xee\xd9\x8f\xcb`\xb2\xfa\xeag\xc8[je\x1e\xda\xb2\xf3Y3\xf3\xb9D\x05\\\xa0\xd6\x15\x85\x9a!\xbc\xd7H\xef\x87q\x00Otz\xd7\x0fO\x9e\xbe4h^\xdf\xb2\xf7/\x1c\xa4\xfd?\nw\xbd\x96\xfc\xa15\x8f=kF\x99\x92\x19\x8eTN8\xaa;\xeaE%\xfdK\xf9\xaf*upK\x19\xf8\xd9z\xea\x1er=\xc0!\x03\xc8\x1f\xb1\xd7pO14z\xd4..\x16ho4K*\x87\xd3\x08ut\xec\x9f&J\x18!\xa9\xa6\xef\"%o\x1c\xfb\x01\x94.\x93Jh\xc4\xfb\xf5\xf2$Y`\x85\x04\xdb\xf3z[\xb4\x06\x11\xf5\xd7\xdbx\xf4\xa4P/\xbeu\xd1\x06\xbe\xb5i\x03\xdf\xb6i\x03Y\x17\xaam\xed\x8b\x9aE%\x80\xb8\x7fT\x12\xc8\xaf\x01[\xa6X\x97\xfeK\xa4\xc4vH\xf3\xf5\x8cz6V\x04\xc4\x82S\x91\x1b\x97g\xda.\x8f\xf6\xcdFk\xa3\x87\x1acP\xe6{0\x98\xde\xac\xa6m*\xb0GOc\x1a+\x88w\x9b4\x81&G\xf1\x94\\\x90\xe9{\xf2\xc5\x010\n\x89\x7f#\xa2\xce\xddz\xf9\xe9\xbd{\xeb\x08\x1cm*l\x17\xcd\"W\x87pa\x84p\xefn\x1d{!\xa7,\xd2\x94]\xd2I!\x17;\xf6\xde\xa9\xdb\xec:\xbb\xed\xbcI^u\"\xa6\x9d\x9a\xcf\xaa\xb3R >\xce,\xac?/WY\xaa!\xe4\x9c\\ \x052\xae\xee#\xbc\xb86\xd0\xbf\x8a\xb2\x0eK\xbe\"\xd7\xd5/7C\xb8\xf7\xdc\x1b!\xc7r\xb2 \xe3\x9eK\x0f\xa5\xa9\xc3\xb1\xfc\x85Y\xbb\x04\xdb&\xc6\xf2\xba\x9f\xbe\xf2\x12\xc3\xcc\xb91\x8f\x97\xd9e\x94?\xc5\xb0\xc7}\xce\x14\xc2\x01\xe4\x98\x92|\x1fB\xea!\x7f\xd8\x8f2\xc1'J#\xe0\x88\x8e\xb5\x94[\xbd.}wOo\xf5*\x10\xc0\xe2\xf5\xad^\xa6\x8a\x1dP1\x16D\x0d+\x8f\xfd\xabA\xed+\xfb\xb8\xcfD%\x84h\xb4\xebP\xe79)\xed\xad\xb8\x08\xa1\x97\xa0\xc7\xae\x0c\xc4\xcd<\xa5\xd0j\xb3\xde\x96\xbc\xcc\xd9W\xcfD\x95(Q\xfdBW\xd7X^\x92\x92ci\xe9!L\xeaT\x14\xc7\xc4$N\xf9T\xd2S?\x90\xf7f\x8b\x90R\x12{[\xbb\xc2\x12\x83\xdaEM\xd1\x13\xebV\x00\x01\x1c%\xcd\xa8\x13\xba\xc8-\xc4\xfd\xa0\xec\xc0\x87f\x1fJ\x85X\xd86XN\xe4e\x06\xf8%\xaf\x8d\xd6,g\x8b\x0f\xa5\xfaV\xe3\x0e\xed\xc6\x8eH\x8f^\x97\xb4\xc9*\xbbV\xf5 v\x897\x98\xda\x12#k\x0b!4n\x91\x98\xa6Qe\xac.CU\xf4{\xef\xdc\xba9#\xe9\xda\xf1Lq\xe4\x82cK*\xf2\x16.8\x0d\xc0V\xf2\x13\x8a@s\x8e\x03\xbc\xd6\x11~\xa1\x14Z\xe3Z\xa2\xad\x81\x01\xf8uG\x12\xd0\x03\x86\x13]G\xc8\xd4O\xae\x1f\xd4|\x82\x9a\xf0'0\xf5\x19Ok=\xbaT\x8db\xc0d\x9fbNT\xcf`\xde\x00UOz\x80 M\xf4\xe5\xc15\xc3\xe2Z\xa1n\xb0\xa8 KP_q\xeei\x89y\xbb\x89\xaf/S\xa3\x19\x08\xe3@\\6o\xbd\xef\xc2\x92\xc2\xe9!\x1c@\x0f\x19\x1f\xd8\x87^\xd03c2#\xc1=\x8d\x1eU^\xdf\x82\xe96\x1c\x8fE\xa9\xfe\xad\x01\xba\xacn\xa3\xd2\x14\xffE7\xa3-YBJ\x99\x14\xaei\xe1E\x83gN\xaf\xc9Y\x82\xd8\x01N|\xdbg\xb2\xfe\x06\xf2\xf3\xd4iE\x97\x159\xd4\x01\xad\x8a-VM\xd9\xe9\xd4\x19?K;n\xb0\x00\"\xeb\x02\xd7p\xad\xe1\xa0\xf2\x08\xf60?\"\xc3\x14\xd8\xe7\xf9\x90\x1a\xdbAU\x03`\xcdZ\x1b\x01\x84\x03\xf0\"A\xe5\xb09_\xb4K\x8b\xd2\xb7\xbcb`b-\xc8\x9c\xba\x83\xec]t:\xa7\x1d\xe1& \x93\xca\x08\x95\x86(;}\x12\\\x8f0\xbd\xa7F\xbb;\x98\x06\x8d\xbd\xb8\xe3n\x81Tj2\\\xa7\xae\xd0\xb8|E\x0c\xfer\xb5C\x82q#\xddz\xe4yYx\xac\xdc\xbb\x18K\x85\xe9\xb2`\xe8\xbaJ\x9djL\xd4gf\x0c\xc8\x01}?(u\x7f\x03\xad\xf9\xd9\xa9\x97\x93\x9c\xbe\n\xbb\xa8\x07\xf8\xbeF\x0f\x99\xdd\x00v\x06N\xbdD\xd9\xe1rE]l\x0c\xa2\x17\xf5dR\xe4\xf4\xba\xe4\xbe/\x96\xb1\xca\x8c:\xf0\xa2&#\xa4\xd3l&I\x1e\xd7w~\xcb|\x9ex\xb4T%\xf1m/\x04X\xfeq\x07\xbd\n\xf6\xfe\x83+{*\xfaw\xa5R\xa0P\xaa\xaf\xd4\xf3K\x83\x94-\x03\x9eD\x0d\x1d\xf1nc]\xf1{\x917\xc1+\xeb\x94\xf3J\xe2lW\xaa9\x8f\x9d\xa46E\xe6\xd2\xb3\xbb\xf2\xb2\x94R\xc1\xb3@5\xb7\x19*\xe4]\xaa\xe7\xad\xcb\xea\x91/y\xb8\xe8\"l\x9d\xd1\x82l8\xb5/\xb2f:l5\xd5\xe1T\xbf\xb6\x18\xa8\xd5?\xc6ty\x95\xe2L\x94\x96\xf7\xed\x9cb\xb5z\xeb\xcf\xb1_S\xb5Z\xcf$\x0e\xc6A\x0b\x1d3\xc3@\xa2\xa0\x1b\x05\x8e\xaa\x94\xb7\xd5\xfc\xa4P\xb0\x00\x12OG\"\xe5e\x18\x7fgQc\x1ev\x913\x90\x0e\x89\x84\xcbK\x1eC\xb0t\xec\xe5\xa8\x0b\x0d\x97\xfdp\xaf\xd1.=E\xd9\xfb\xfc\xc4\xb1\xc0g!\x03\x0eM>aE\xa5\x14nu\xe6<\xba\xa2\x13r[\xda\xe2<.\x12\xe3t\xc8\xa7\xa5\x9f\xe2\x8a\xf1B]&\xe9\xd9f)`\xa6\xcc\xd2/n\xba\x9fj\x9f\xc9\xfa\xed\xac\xc3\x90\x8aC\x8d1s\x9d y\x0dFB\x1eq\xee~\xc4W\xb42lW?mH\xa9.\xdd.\xba\xab\xd1\x1a%\xbf\xfa\xc8\xcf\xba\xf7\xf7\xf2*\xebb\xe0\xbdq\x8d\xb5\xb9\xac\x9a}/\xc3\x8b\x0e\xbd\xbe$\x9dT\x18\xcb\xf0\xa2\xeb\x99\xfa\xb2\x92\x8f\xc8\xa9\x137\xa3Yc\x06p\x00ob\xee\xc2\xf2\xd5MPZF\xf1\xd5\xa7\xc3\xbb#\xbc;\xd7\xb9\xa5\xa43&jC\x1eA\xdf|\xf69Zu\x80\x9d\xd2\xfe\xeb\x90\xce\xfb\xcb\xf0\xc23T$6tV\x17\xbe]\xa5\x04\xc3\x1ecMzT\xb9\xe3<\x90_\xe7\xd1\xa2\xa3\x99\xa1\x18\xcc\xefW4l|\x8eV\x1fc\x1a-\xbau\xcb\x81.\x87\xdcM\x05\xc5\x13\x82u\xeb\xafi\xe5\xd0d\x06\x03}\x7f4\xfcL:,/\xad\x18 \xae\x80R\xac\xbfkF)\xd6dw\x94b_}\x0bJ]E\x92\xf8\x87\x13w\xab\x940\xfa\x18\xa3\x9a\xb7\x92\xbc\x0d#+[\x18^\xc9NS\xa3vY^L\xa4\x8b\xaa\xb1yJ\x81\x96J\x18\x08vlo\xedL\xd4\xf3o)\xfb_0n\x1a\xc1\x87\xa2J$l\x9b\xa1\xd2L)\xfd\x14\xdf\xde\xbc \xdb\xdb9\n\xa9\xa2AC\xa1ry]\xfa\x01\xe4\xc67.\x03P\xcb \xfd\x17\xadJ\x92vY\x16Z\xf1\xc6b\xdf\xd9\xe5Zv\x85\x16\x8f\x12y\x89q:FY\xaa\x17\xfaN\x85\xc5L\xdb?\x00\xf7\x88G\xf5\xb2F?\xaa\x97!VB\xbd\xa4\xe9&o-N%/\xae\xc3\xaf\x14\xa9\xb2x\xa9\xcaKF4R\x11\xc3\xdb\xfa\x01\xbb2\xe1\xac\xea\xf6\xf6\x04\xdf\x1e\xb4\xb8\xb6\x82n\xafM\x02\xc8P\xe3y\xc0H\xdbp\x08\xef\x84\x98\xf3\x9cad\x86/\xf04\x7f\xa1\xf0\x0c\xf9/X\xdc6\"`\xa5\x00\xda\x87\xdd5\xaf\xec\xe0\xb9*SQ\x1cZ\xdd\x98\n\x19C\xd0\x91/\xed.\x86\xcd\xc3l\xfe4\x99vpt\xa1\xf32\xbb\x00\xd6e\x9a\xab\xd9\x06\xday\x04(\xb6\x17wP\x1e\x0ea\x00\xb7`\xb7\xd8h\x16\xd2%\xcd\xa4\xb3V\x05\x9f\x9b+\x7f*\x8a\xdf\x0e\xf4Uo\x8b\xd7\xf8\xc0\x9c\x16\xbf\xf6\x0d\x1b\xed{\x14\xd2o\xdf\xb9\xbd\xf7`p\xff\xf6\xdd\xdb~P\xdc\x86G\x8f`p\x176@\xe0\xf1\xe3\xc7\xb03\xb8\x1b\xc0\x9d{\x83\xfbw\xee>\xd8\xfd\xbe\xfe\xdem\xe5\xbd\xdb\x01\xdc-\x9fc:w\x8f\xc06\xdc\xbe\x7f\xef\xce\xde\x83\xbd\xc1\x83{\xb0a0\xfd\x17\xdb\xd2\xff\x12\x9f\x0d\xee\x05\xb0\xb7w\xe7\xde\xfd\xbd\xbd\xbbE\xf3\x87\xe2s\xec\xa6x\xf3v\x00\xb7\xf7\xee\xdd\xbbs\xff\xc1\x83\xdd\x07\xbe\xda\x84e\xcby*\x7f\x10c\xad\xcb\x83\x8eP\x83!\xdc\x1e\xc0w\x90\xc26<\x8f\xbd'\x147\xcd\x13\xea\x11\xdfg32w\x0e\x8e\xbbS^\\+~\x85^\xaa\x93r\xe9\xa6\x98\x11v\xd4\xdaA\xb7\xc6\x1d\xdb\xf5\xb5\xe5\xac\xa1 \x88:RX\xb9SW\x06\xb3\xbd\xf8\x9a''Sr\x01\xa8o\xbc\x8eG\x0b\x19\xe0\xfd:\x1e=c\x7f\xbf\x16&\x8b\x8c\xdd\x12\xa1\xa3\xfc\xb6\x08\xac.\xee\xab\x81C0\x84W1>\x89\xe2l\xc5s\xe3\xe3'\xef\x93<\xad\xe6\x95\xd1\x81\xac\xa6D\x12\xee\xad\xd5\xd9a\xeb\x93y\x18\xc5\xbcma\xcb\xe4\xb7\x93\x98\x86\x11F\xa5\xe3\x10\xb8\xee\x12c\xc4S\xdd)9[D\x1dB#\x0b\x01\xe5+1\xae\x84N\xed\xb3:l\xb8\xf7\xbbZ\xff\xcdT15\xcb\x02V\xe1\xae\x93a\xb5\x90&\xa4\x93\xc4( \x1a\x9b\x8bO\x03p\xa3\xaab\x93t\x14\x1a\x97\xe1\xeae\xd5\x07\xd9\x15FW\x00\x02[\xf7:,\xda\xc4\x8c\x06,x4\x82\x05\x08\xd8\xc9Uv\xeb\x87\x18\x93\x9b\xb4f\xeexj\x06\x92<\xd5\xaa}\x19\xda\xf9\xb9\xb5\x9d\x11 \x80\x8e\x9d\x1a{g \x87\xf5\xb3\xb9e\xb3mQ\x97d\\\xd0\x84\xa7aXo\xaegX;\xd7<\xacW\xf6a\xf52\xa4\x81\x15\xe3\x07\x1c\xc0O\xef\xdf\xbe\xe9\xf3G\xd1l\xcd\xd5\xb6\x82Z:\xe6\x16}f%\xc0\x87\xc6L\x9e\x86\xe6\xbe\xb6b\x10\x85G\x05\x07G\xe11\xfe\xbd\x83\xec\x9cS\x07\xcf\x1d:`\xac\xcf6\xec\xdd\xbb{\xe7\xce\xed\xbb\xdf\xdf{\x00\xdb\xe0Q\xc6\x90\xdd\xf3\xf9\x9f\x8f\x1f\xc3^\xf3\xf4\xad.\x94h\xedCT\xaf\xc2h`\x95\xcb\xe5\x95|\xb3\xad\xaeu@J\x1b\xdeV\x82\xa5\x00\xf8\xba\xf2\xd0R&\xa2G\xbe\xaf$-\xc5f\xc5}k\xcb\x97\xac\xf7\xc0\x96GC\x85\xa8\xdel\xe7\x0c\xd2\x80[\xee*1~\xd8\x7f\xeb\xe4\xdd\xed\xa1W\xb0\x9f\x15\x90\x8d\x18ds\xf8\x1f&;\xb0\xad\xc7p \xa9\xb8\x00c\xcc\xef>\x7f\x07\x0e\xe09\x9b{\xce\xd3\x91\xa2\xd5F\xfe\x8cd\xca\xd86\xf0[\xad%\x86T\xe5%\x95p\xde\xc6\x0b\x12\x9e\xb9p^\xd2,7b]\x8c5\x87\xb2oY,\xb6/op\x02 \xf5/\x01\xdc\xe8'3t\xa65~\xc6\xf3\x93(\xde\xf9\xd6s\x96\x14\x1b\xdf+\x88\x81\xb8\xc7\xe8\x80\xc8H\x13\x94\x94\xc8\xcd\xc7\xa9\xab\xcb\xdd\x92z\xbbj\xcaj\x97>\xae\xe0_\xc7\x0e|\xc7\x08\xd5\xebv\xefq<\xf9\xbf^I\xafzC\xfe\xf1,\x0el\xc8\xe6<\x86_#:w9\xa7\xa4\xcc\xa3\xf6b\xc77\xc6\xd3\xc9\x00\x81\xe6\xf8M&\xcb\xca\x9dK\x9fQ\x842=\xec\\\xea\x1b\xd4\x9bE\xdd\x96#t\\o\x0e\xbf3\x8f\x85\x18\xc4kA\x0b\xb3\xb2\x93\x9cv\xd5|:\x9a\xaa\xd3p=\x9b\x0d\x9b/s\xb89@;Q\xf2l\xf3\x12\xda\x15+\x81\xfaX\xb1$\xa8\xb7+&\x85\x17\x81\xaa\xa4\xf5\xf1\xde\x8d\xca\xf2\xf1{?V\x9a\xe6\xf7N\xa8\xe6\xe3s\xaa\xf9\xfa\x82\xd6?oBE\xe6\x97\xdb\x87\xb8 W\x04\xea\xcb\xe6\xfd\xa7\xc9bA\x10\xd2\xfbp\xac)\x90\x81\x01b_5\x0f\xd4\xb4\x92G\x1a\xe7 \x9e\x97o\xa5y\"R\x05^hGI\xf7!\xd3\xe5{\xbb\xbb\xd3O\x9f\xf2\xe9\xfd\xdd\xdd\x1d\xf6\xefl6\xfb\xf4)\xdf\xbd\xcd\x7f\xee\xde\xbe\xc7~\xce\xc8\x1e\xfe\x9c\x91\xbd\x19~3\xc5\x9f{\xbb3\xfet\x97\xf0\x7ffc\xd3\xe0\xcc\x14\xad\x100(\xc9\xa8J\xc7.\xbb\xc1i\xb0\xfb\xa0\xc6\xeb0.\xb2wx\xb1\"\x13J\xa6\x10\x16\xed\xf4\x14c\x8f\xbc\x07\x89\x96\xb0G3\xf0\x94\xf8\x88-\xc5D\xb0\xd9\xc8\xecA\x1cE\xb4\xaf\x11\x1f\xe8\x9e\x864<>\x16\xd9F\x9bX\xa9h\xf1\x84\x14[\x83\x0c\xbb&\x9a\x1aTQP\xb9]\x14\x82M\xaa\xf7yQ\xc4\xbcz\x933\xc4a\xf5f\x86ofUB4\xe9\xb6:\xb7\x1f\xe8\x97\xe7\xce\x83\x96\xe3\x18\xa8\xc8\xcb\xc1Co\x1b\x8e\xeb\xca\xe6\x15\xc6\x0eOT\xe6\x04R\x9c\x80\xf2\xd1V\xc4\xb8\xab\x9b7\xd9\x1f\xb1\x8fJay8\xc6\xec\xaf\x98\x1dA\x95\xfe(\xeb\xf2\xca'\xfe\xed\x07\xb7\xb5\xb3\x1e|_G>\x81\x94\x0f\xeei\x90r\xd0\xc4\xc7\xbd6\xd2!k\xb9pG\xe1\x99\x0e\x15\x17\x98\xb5\xf8&\xe4\xcd\x03\x17\x0b\xb2\xca\xb2\x8c\x8d\xa7s\xc4H\x9dY\x8a\x11\xa8\x15\x03\xe4\x1c\x81\xec-\xd8?sx\x0c+;]F\x9d!\x0f\xd0\xf5\x9b-bAK\xfeX\xa9-6\xc5%n\xb6u\x06C\xd8\x194G\xbd\xe62t\xe3\xfe\xa9\x00C\x08\x07|'\x82\xf4\x8e\xae\xb6\x8dy\x01fx\xfc#\xa9\x0f\x80\xff \xbc\x06\xe8\xf6\xf6\x19<\x82\x956\x11\x00\x1b\xd6\x92\x81ttf\xe0n\x8e\xb1(\xcc\x99\xc6Q\x9c\x01 \xf3\xb1\x89\x13\x18\xc2\x02\x0e \xf3\x8e\x03X\x06p\xc6\x03\x91py\xf7!\xf3\x96\x01\x1c\xe3]\xbe\xfa3\x0d?SK\xe2{b\x92\xae\xd9{'>0\x018\x8aM)\x0b\x10\xa2\x03\xfd\xb3\x93\x94\x84\x9f\x1bO\x9a\xe7\n\xeb\xe8\xd46\n\xb6e;\xd8\x0c\xf0\x93\xc4;\xc5\xd7n\xde\x04oY\xe6\x8c\x9e0\x08Q\xb9-f~\x89K\xa7<\x16\xdf\x18\xdel\xeb\xd1\x06\x050B\x02\xb4\xd0\xb8\x04\xb2\xc8\x08Nb\x89\x0bt\x8c\xfbh\"\x96\xb6\x18\xb8a8\xdf\xba \xda\x13y&N\x10t\xba-~0\xfc_\xff\x9f\xea\x876n\xc8H\xa5\xeas\xa9\xd4_\xdb\x11 /%\x11\xa7\x98&o\xbf\xa0Ml\xdb\xc5\xf0\x08\xd2\x87\xcd\x95C\xd3\xb8GG\xf1\x18\x01\xa7r\x86\xbbZ\xfeOI\xef\xd4\x91\xcc\xdf\x19\xd4y\x83\xe2pkRyQ\x91\xa98^\x9b\xf4\x1e%\x19\xa5\\S\x93\xfc\xa3*\x08\x9f\x1de\x87q\xbe\xe4\x8a\x9f&{\x92\xda\xad\x1db\xe2\x85\xb8VE\x06\xcf\xf7\x85 \xde\xae\xec\x13\xad0\xe6\x9bak.X\xcc\x00z\xec\x0fBz\xfc\xc4\x0d\x9b\xf7\xab\xfd\xe9\x8f\xb4\xcce),\x99\xf2\x15\x06Qch\x10\xeb4\x18h\x9e%m*\x97-\xd2\x8f\x93)aB3\xdek6\x81\xab\x89\xa2w\xb3\x1d\xca\x8d\xd4\xac\x1dZiG\xa3sbk\x9es\xe0\x16\x90A\xc1\xe4\x00\xd2\xfe\x0f\xf9lF\xcaS\xab\xf95\x03\xa3\xc7\x8e\xb7\xb0\x1fe\xb5\xb7Q\x8a\x8d\xccJ\"E\xe2\xa9(\x89\xee\x0f\xfc\xc2X\xdc}\xdf\x1b\x988\xda?''\xabp\xf2\xf9\xe7d\xb1\x9eE\x8b\x05\x0fY\xe9O\xc9*%\x93Z\xedG&O0\x96t\x15\xd29k}4\xc6L\xf1\xf3h1MI,\xbe,~\xb2\xe7e\xb9\xb4)\x99E1\x91\xfb\x0bqr\x91\x84S2\xed\xe9\x14\xab\xa4\xd8a\xfbz\x0e\xa2K\xd1\x19\xda_4\x1e7\x95\xd4\xe6qF\x7f\xc9\x18#\x8716Wk\x08\x83J\x02\x9b\xced\xd4 #\x0c\xea\\t\"\xee\xdf\xd1p\xcb\xb8\xdf\x92~\x94\xb1\xfd4\xe5Q\n\x95\x97\xf8f:\x80\xc8\xcbQ\xe5\xa4\xa7;a\xb7\xb1\xdf\xdd\xbd\xaaZ\x91\xf2\x83\x8d\xd1\x81\xb4]\xb9\xd8\xbe\xb74g\xaa<\xc9\xe5;Z\x87\x17\xa9!\x10\xfa\x05\x91E\x90\x8e\x85;_\xcd\xdf\x84p\x8f\x92H\x16'\xf4\xe2\x9a\xa9\xeb\xf2\xaaX0\xb8_\x97\x818\x16|\x7f\xbf\x15\xc2m\xec\xc4.\xf72\xf0\xb8\x1a\x88\x07\xf1\x17\x9cD\xa1X\xe1\xd2\xe0#H\x1e\xfa<\x85\xe8(\xf2\xc8(\xde\xde\x1e\xfbc\xbdv\x8f\x7f!\x082-h\xebU!\xa0\xd7\xd9\x0d\x1a\xd8.v\xc1^\xfd`\xe3\x8a\x8c;\xdf_\x05^bJii\x18\x8c\xc4{\x07\xc0\x90a\x1f\x12/\xaf\xb8 9M\xae\x97g\x042\x9aF\x13\xaa\xa8\xf6*^X\x0d?\x11\xe9j\x13{\xdf?\xa8\xebF\x94\xe9\x1c7E@&\xbas\x98\xdd\xfb\xbe\xf6\xe5q\xff\x1d \xa7\x8cN\xbe\xa7\xfc@YV_`\x80\xbe\xeb\xf7\x0f\xcfHL\x0f\x97\x11\xa5$mv\x10\xb6\x81Q^%\xd1\x8f2Jb\x92b\xd1M\x8er\x8d\x0ft\x96{\xb1%\xea(\x01\"\xb88\xf6\xee\xef\xfa\x82\x03h\xbe1CA\xfdc\x14\xd3\xfbH\x07\xd9\x9e\xad\x9c\x9f\xcd\x99-85\x1b\xd4\xc0\xb6\xe8G\xf1\x9c\xa4\x11\x15J\xaf\xbb\x1a\xf3\xc0\x8a\xa3\xdd\xdd:\xb1\x06\xa12\xd0 \xd5\xec\xfe\x8am\x9fU\x7fJN\xf2\xd3Er\n\x07\xca\x0f\xaf\x97\xd1\x94\x84\xcb\x9e\x0f\xfbmC\x9f\x06(\xfb\xb3!\xd4w\n\x08\xe1\x88\x81\xb2\x8eK\xe5\xd4\x98X]7\xf9\xb3\x86O\x19\xf7\xd0#i\x9a\xa4=\xc6\xbd.\x92\x8c\xb0?\xa6$\xa3i\xb2f\x7f\xae\xc2\x9c\xdfKI\x96/Iol\x8a\xd6Y\x1a\xd1%\x01\xa1i\x8e\xbd\xbd\x81\xa8a\x81b\xab\xae\xbe\xa0$\x16\x04\xa28\xa3a\x94w\x86\xe5S\xdf\x0f \x13j\x85F\xb6?\x13 OJ\xe5\xb8)\xdaS\xe1!h\x0d\"M\xb0 \xdd\x147i{ym\x8f9q \xa8\xaa\xe2{X\xae\x93^\x89\xc7_\x14xfSJ\x9e\x15\xc5\xdd\xc4\xcb\xacu[*\x15\xce\xc3J\xaa\xc4\xa0N\x04\xdd\xe2\xaa\xd1\xd8\x0f\n\x9d?l\xb3\x86\xab\xd4\x17\xf6\x8b\xaf\x0dJT\xed]RR\xae\xdd\x00\x0e\xb5\x86I\x06\xba\x1c\xeb,zH\xb3\x11\xdf\x9d\xe0\x8aP\xd0\xcf9\xe5Uy&\x85F\xc4KQ\x15\x92\xaa\xdbf\x86\x94\xa6\x19}I\x94\xb8\x83a!\x0c\xd5NK\xcc\x12\\u\xaa\xe8\x1d\xc5g\xe1\"\x9aB\x9c\xc4;\xbc\xd9[\xe2p\x98\xcc\xf3\xf8s\xcf\xb7\xc5\xd3\x18&\"\xb6\xb5\x06n9: \x06\\*A\x02\xee\x15\\L\xc2\xe0\x99\xd7\x86,\x1c\x89\xc4*?\xc6\xc8\x1f\xcf4\xff\xfa\xc7e\xa5\xf9\x9f\xa5j\xf3\xed\xcc#<]\xb1bND\xd8\x10\xa7\xe4#bn\x13\x0c%\xd7\xe3\x06N0e\xa7\xb4z\xe45\xe7\xcb\x16B,\x02\xe7(\xfby\x9c\xcd\xa3\x19\xf5|\x08g\x94\xa4@\xe2)\x10\xc6\xf5\xf7\x10\xd7\xce\x11\xedd:;\x04\x16GU\x97\xb6q\xcb\xc8\x86\x0f\xdf>\xe7M6\x88C^\x1c\x19L\xfa\x8f\x19\xb4 &>\x92\x9b\xf6<\x8d\x84\xae\xbd\x0em!\x85\xcb\xb5:\xa8\x8cw\xc0z{[\xee\x9b\xea3\x9fW\x8fb\xcbP\x1d\x90\x0e\xfb\xea\xaa\x83\xb6\xb5\xda\xa2\x02LH\xb8\xab\xdc\x04n\x92\xa2HV\x8d9,\x99.j\xa4#\x97^\xeeF\xe3\xcf\x15\x1a\xaf\x1b0)\xb8\xa8\x9b7\xe5\x1eVh\xdf\x16\xe1l\xd1\x01\x9b\x02_\xebiHC\xb6\xd4\xa8\xf7b@\xf3v\xf9\x9a:\x12E\x8e\xa4\x05M\x95\xc8\x17\xb36t\x94\xb6\x02\xb8\xff?{\xff\xbe\xdc6\x924\n\xe2\xff\x7fO\x91\xc2o\xc6\x03|\x84h\x92\xba\xd8\xa6M\xeb\x93e\xb9\xc7\xd3\xed\xcbH\xb6\xbb{\xd8\xfa\xa9!\xb2H\xa2\x05\x02l\\(\xab\xc7:\xd1gw\xcf^#\xf6\x01\xf6\x9f=o\xb0O\xb0\xb1\x11\xe7MN\xef\x03\xec+lTV\x15P(T\x01\xa0,\xf7\xec9\xdf\x87\x88nS\xa8B]\xb2\xb2\xb22\xb3\xf2r\xef\x1e\x92F\xc7e\x8bJL\x9a\x16\xfa\xe85\x87\xe7\xd2}C.\xb8\x18\xd4\x9d\x1b\xa9\nU\x17$\x85\x7f\xb8wO\xf7\xba\xe0\xfc\xaaK\xac\x91\x81\xdb\x05\x0c6to\xd7\xf6OO\xf86F\xc3\xe7%\x83\n\xc1\x88\\\x8b\xdf\xe5\n\xe7Y(\xd7\xc9\xffRj\x15u\x1a\x0f3&\x0d vdA@\x11D\xe3\x06.7N\xeb\xb6ix]\x8es\xdf\xc8\xec\x08\xf5P\x19\xd1C\x91\xebN\x1b\xa9\x80.\x02\xd25f\xf1\xa6r\xf3,Hv\\f\xb8\xa9\xc0#\xc8>\xbbl'\x98\x99\xd1qyg\x8eK\x19\xb9\x92SB\xc5\x9fC\x81 \xdfs\x8d'\x0f\x9f\xa3\xd4<\x93 (\x87\xa2z\xc4+]\xf8\xc9[/K\xca.P5]l\xf5\x8b\x94_\n\x86r\xfaT\xd7YBd)\xa9\xd5\x9c\xda\xc91\x95\xcd\xa2\x885\x86z\xb2p\xc3j\x94G_U\xac|\x84\x11<\xdcy\xf8p\xbf\xf7\xd0\xa4/95\xa2n\xae>\x7f2b\xfe\x8dU:N\xf2#\xbb\x87d\xb6B\x9dS\xa6\xf0=(\x1f\x08\xd2\xa9\x9a\x93\xe6\x05\xf1\xa6]z\x08\x88\xb2aQm\x88a%\x80(\x07\x1ac\xa2U\x8dA3!\xcb'\xf6t\x04\x1fQ K\xff\xa5\x9dloSY\xeb\x13\x1d2F\xf7*\xfd5(\xfd\xb5[\xfa\xeba\xf9\xbb}\x17\xd2NG\x9bk\xe0\x86\x9d3\x08U \x0e\xe8!\x92CS\x9e9\xa9h\x0cz\x98\x9f\xb9\xd59}\xac\x87Bn(\xd7H\x8f\xaa\xbd\xf7\xe9\xe9\xa9*+(\xd6/l\x8b\xbe\x16\xef,\xb7XtG\xf7\x0d\x9bI\xce \xb0|\x1f\xef\xfc\xc9\xa5}\xc8#/\x1eV\xdceM\xf3<\xd4\xcf\x93\x0f \xc4$-\xe4.\x18\xc3!\xbf{\xd56\xa0\xcb\x1b\xe3n!%}\x08\xb2\xe0\xaa\x86\x04\x9d\x8e\xf2I\xfe\xa4u`2u\xfc\x93\xb1\xe3\xd2\x05Ln5FY,\xc1z2\x86K\xda\x7f[\xa4\xe0!I\xc10\xea\xf6\xd7\xc2\xb6\x96\xde\xf5\x05\xa1\xab\x86\xf3@\xf5B\xcf\x92\xd94\x17m\xfb\x8a\xce\x9d\xc7Ny0\x0d\xc0\x1a\xa9\x89\xbfL@\xb84\xaer\xae/\xa1\xe0M\xfd\xc9\xa5n\x9c\xad\xfax\xd9\xbc\xc2\x02\xdb\x99\xe6M\xd7\x13\xe2\xbb^1G\xaa\xca\xb4\x1c!Q\xb3\xcd\xd1\xd1\x05u\xc9\xa4\xe5\xdclJ\xaf>\x97\x08 \x8a-l\x8b\x8e\xa7\xb4\xad\x1f\x97\x07\x99\xa7R\xe6\xe3s\x1e+\x02\x8fi\x84\xef\x9a\x0e!\xe5\xe89`]!u\xac0J\xf9\x91\"\xc4\xcf!l\xa5\xec6\xf5i\xa9\x0d\xbb\xa4\xc0\x91\x0f\xa3\x9f\"?\xb4-\xbc\x13\xe9\xf3\x9eyI\xcd\xc1%\x0b\x1a\xdc\x9f\x92\x14>\xb1EQ@\xbc\xd8F\xd9&\xd4X\x94\xd6\xa9Z\x0c\x1a\x8a\x94\xed]\xf5\x00=\x00Lu$\x97H\x91B\\\xb9@[-u\xf2,\xc8\x1c\x06\x9a.\x88\x04\xe5p\x93\xf0\x96\x05\xc5\xa2\xad\xea/\"\xc4\x13Wmt\xd5\x07\xef1qlf\x15\\\n\xdb#\xf0\x8dDI<\x88\xed\x8f\x81\xc5r\xa4\xf4\xa46\xf7\x14\x08uf>\x80\xfa\x81\x82\xb8\x91\x81\xa7\x10\x15p\x8c\x8a\x13\xbf!\xb2\xb2?\x03;c\xd6I\xc5\xe7>\x95\x8e#\x18\xf2\x1f\xe5\x85f\x9b\xc7\xc6\xe9g\xb5\xa6\x96\xe2\xa9\xb4ow:\xb1\xcb\xc1\x81\xab\xbe`Zf\xfefX\xbc!\xdd\xd4\xf3\x03\xae\xe7\xe7\x02\xbc\xa8\xecr\x08A1\xc4\xcc\xa4\x91\x93\x1f\xb3\x85\xa7xn:\x1d}xc0jFA\xb2m\x17\x13\xddFw\xa0\xaam\x0e\x085)q6\x89\xab*p|\xd2\xf5\x82 \x9a\xbc\x0f\x13oF\xdaE\xe1m\xb1+(\xca\xd7\x98\xc5\xc6l\xa7N\xa2\xd55\xaa\xde\x04\xe7c\x97\x83\xe4\x8b\xe0\xbc\x1eSaS\x9c\xf7k\xc2]\xb8M\xc1\x974\xb9\xee\xf0+~\xde\xb9\xc5 K\x19E\xc3ev\xb9{\x13\x9bp\xf4\xb9\x8c\x0c\xbb\xde\xe1\x13\x7f\n=\xd95\x93)\x98\xffd\x910\x17Ql\xc7\x024\xa5\x9dB\x14\xe2\x9d\x02Y\xae\xd2k`J\xe8?i\xe6Bd%9\x13\x02\xe4\xfb\x17\x89\xfd\x7f\xabMrb\x8c\x1dj\xd6\\)=rU\xa1\x98$\xb3\xd2,_V\xf7\\\xce\xcbVD:\x9b\xce\xdej9\xa6\x93v\"I\x8fk\xbfr\xc9\x84\xd9\x93C\xd8\xe9\xe8/\xb20\x1a\xfa8\xe4vq\xc5\xbd\xaaQY\xb6\xadJ\x0f\xf2_\xb2B'f{\xb2^C\xc0\xa5 \x8b\x9d\x9d)\x8c`\xe5\xc5 y\x19\xa2[J_\x17\"e]\xf2;+\xe1\xa0\x9e\x12b\xa43=z\xf2\xf5\xe3\xca\x0d\x9dQ@N\xdd\x98\xffyE\x93-a\xf8\xa8\"\xd3}\xfa$\xd4\x0c\xc5\x8d5\x9f\xf1\x10*\xe2;k\xc7\xcd?qku@G\xec\x92\x18\x86pl\xf3\xcblJ\x10M\xf3\xe4\x04z$TP\x8e\xd4\x9ac`\xfc\xef\xdd\x13\xbd\x98\xdaF>\x99\xa5\x13-\x83\xc6\x88>\x0b\xdb\xa2\xf5\n%\x01\xe6\x15\x11#$\xd2N\"\xd2IS\x95\x97q\xfc\x0b\xdb\xe2u\x02\x92$\x90.\xbc\x10\xaeh\x8d\xa5\x17_Zl\\\xa8\\\x15`\xc3f\x85hw \xd6\x82\xfe\x11\xe1\x95\x19\xde!\xf8l\xe1\x91\xbf\xe3R\xf94\xc2\x01[\x8e+}_R\xa9pMQ\x05\x80:\x8dRI\xe3\xa8*\xd5\x1c\xb9\xc9\xbe\xab\x08\xc2l\x05C\\A\xbe*lic~\xc4\xf7\xe0 \x17\xf0\x86\xfc\x88<0\xe8\xb5\xd0\x0e\xc7\x91u\x7f\xdb\xa8\xec\xd4\xce\"\x07\xa0aFa\xb1\x95$\x85\x07\xc7\x1f1T\xd4\x8d\xe7\xd7(\xa5\xbb\xa8\xb8\x92w\\Q\x10\x9f\xb7\"(R\xc3\x9a\x0bM\x06q\x07\xfc\x04\xc2(\x05\x7f\xb9\n\xc8\x92\x84)\xa9\xd2a\xe5\x06\xc2_\x91\xd67\x10\xb5\x01\xd5\xa2\xb6\x97\x13\xc9\x95\x8f\xae\xc6\x91d8eb\xad&^B\xa07\xd4\x96\x01:\xe0\x0b{\xac\x1af\x0f\x99 }1\xb6\xdfo\xd3\xfe\x98\xfft!\xad\xc9\x13S\xd3\x15\xbfOi\xec\x8b] 5^wI_0\xd3\xb3\x0e\x95n\xe9\xce\xc7%\xc5 \xa0\xa3?N!Z\xa5\xc9\xe8\x8f?Yn\xa9\xb6\x9e\x1f\xa3\x8b\x8c^([\xcc\x90\xb0\xcf\x15r$\x9c\"YJ\xf9\x1dP\x92N\xa3,U\xde\x908\xa6\x92;\x0c\xe1\\\xb9%\x80\xb2\xc3\xb5\xce\x88X<\x0b\xdb\x8a\xc2,\xa4\x03\xb5\xd8m\x92\x08\x88\xca.\xdf\x99\x1e%\xee.\xbc\xe4=\xd6b7\xd8\xa5\x17\x8c\x06,lk\x12\x10/\xccVB\xa7\xb6\x8c\xd6\xdc\xf6\x8d\xc4vn\x1e:\xd7\x96\xce\xfc\xd0O\x16\x96\x0bKm\xf14\xf6\xfc\xd0r!\xd0\x96\x8a\xfdy\xad-\xe5\xb3saB\x89G\xf5\xe3\x90\x92\xeaYM\xd9\xb9\xb6\x8cS\x9b\xb5\xe3\xa2\x85/\xde\x82E\xb2\x96\x10\xaf\xf5\xcf\xafb?-]\xbcn\xa9/\x91\x08\xe6\x9f\x04\xfa\xa8\xf8\xe6\xf5\x9d\x19\xaf\xa2qm\x913d\x86{\xd3\xc68P\x808^2\x18\x91x_\xe4\x11\xc2n\x14N\x88\x00\x0dZ\xbeu\xa3\xb0\x04e=\x9e\x07\x8d\x14\x174v\x15Mrz;\x01B<|\xb3\xbe \x9fs|\x92\xd5\xba\x8e\xa2\xe5\xc5\xf3\xa7\xf8{{\xbb8\xcf\xca\xb58\xfc\x8c+\x8cQ1m\x886~(h\xc1\x7fc\xeb\x84-\x06\xe3b\x17\xe8A\x8cx\xa8\xd1-\xac\xb9+9-3#\xd2\xda\x9c\xab\x171\x89M\xd0\x05\xa1\x12\xe7\xd4*\xcd\xadq(\xfa\xb2\x83\xdd\xees\xa9\\\"\x97\xe8}\xc4\x89\xbb\xf0<.Ux\n}Z\x89\x87_=\xb1\x0b\xfa\xcf\xe3t\xae\x04\x135\xf3\x82\x84\x00v\x0b1IVQ\x98\x10\x17\x84\xady\xa8^\xc0\x96\x96\xb8\xa6\xb4\xd3\xe1\x93C.\xa4\x8b\xedm\xba\x1b\xaf\x1b\x80(H\x15q\\8\xb7\x1b\xa9\x19C8\x86`\xec=;\x17\x14\xc6D\x17L\xb1f\x90s\xe3\xb6j \xcc\xe7Z\nb\xeehYO\x9bx\xdb\x8d\xc7\xc5\xa6\xdd\x9e\xd7u[\x1cva\x97\xfdnw\xf6\x0by\x96\xed\xc4\x9c\xf8k\xbbi{;\x00P T%\x1b\xfb\xaeb\xb2\"\xe1T\x00\xa5\x08P\xae\x96\xb0h\xcd5*\xf4\xee9\x9a\xf0%\x0cy\xf8\x1fcr\x06\x07\x90\xd9\xf2\x0b\xf4n\x92\xfe.[d\x95>\x1d\xc18tK\xaf\xce\xb0\x8a\x08\x1e\xad'x\x12*\x8b\x03\x9b\x1d(e\xfe\x80\xbdS\xb8\x02\x86\xf4\xfc\x9c 1f\xa1 \xb4\xfcn\x0fY\xb1\xe2F.\xe4\xb7y\xb6S\xb9\xd4\xaf\x18\xc1T\x18\xf3Z\x9d\xd5&*\x03\xf3\xda\x17L\xd4P\xbdL\x15\x8f\xc6\xc9\xa5\x90\xc3I\x89\xa3\x17\xd8\xa1\x0d_O?\xea\xd7|T0\x97\xbc\x9c\x07\xccfV\x1cBb\xe4exT\x96\x1d3H\xc5+\xa3t\n\xf6\xb95\xbcX\xc4\x9c]Hy\xc4YnH\xaf\x1f\xf8Vmp\xd2\xb8\x18\x98Y\x83\xedCy\xe6\xfa\xcd\xb2\xe9\xac\xf4\xad\xe4\x8a4\x16\xe7\x1a\"x\x02\xfec\x88:\x1d\x07\xe2qtf\x82A\xad\xc2\xb6b8\x04Z2\xb5\xe61\xdcNlR\x9c\x9f5:8D\x89LZl\xfeY\x97eg\xb03\x17\x9d\x97K\x80\xd8F\xc9\xa7\x8aM\x9c\xf9\x11 \xe4\xbf\xc6\xbd3i\xf7\x9a\x16\xbensF\x95\x1b\xd7:\x899)}Y\xb8Ap\xc3\x0d=\x861\x8a\xce8\x13'gm\xcc\x06h\xb9\xeaA\x10\x18\x8dRY\x84,)lVD\xfb\xf5\xb8\xdcJ\xa8\x07\xbc+*+\x91c\x8d\xcb\x11\xdd\xb9\xba\xf7\xecB\xa4\xa2\xc9\x89\x0d\x0eM\xb1\xa4\xec\x8a%}\xceq\xae<\x94\x04\x85K\xbe\xa6\x9b\x1c\xabu\xeb\xefM\xf3\x93\x0eF\nf\xb8\x8a\xaa\x18m;Z\xc4cL\xdb\x02:?s\x95\xa3\xa68eR\x85\xddo\xc4T\xe0f)eC\x13a|T1?)\xdf@\xbc4GP.\xa2\x9c\xeb\xec\x0c\x15=\x14\xe5n\x9b\x00U\xa8Z\xe9.b\x1c6\xf0\xc92\x1dG\xcd\x16q\xdc\x96\xfb\x08\x0fnd\xde\x0d\x16\x94\xca9R(\xe6\xf8W-\xa6{\x15{\xab\x8dN\xf7\x9a\x1b\x80\xb6g\x7fl8\"\xf2\xe3\xc1\x07?\xe4\xa2\x1d\xd7B4\x89\xbd\x94\x9c,l\x8b\xcefE\xa6\xc0\x85\xfb\xb0\xec/!t\xf1\xf5\x92s\xca,\x1f\xda\xb9A\xf1\xb3[\xbe>0i\xcd\xc0x\x8dI$S\xed*\xf2\xe6\x9a\x04\xce[\xe7\xb00&\x1e\x94!!\x84\xd3\x12(l\xbf4G&\xa7\xfa\x14]\xb6B\xc5o$W*\xa3\xa6^\xb2\xde\xf7\x99Ho\xab\x1f`=a\x95\"\xc4~\x9c\x9f\xef0\xa2+t\xe3\xb9 \xa9\xdb\xb2\x0e\xdaLJ>S\x14\xbb\xc6\xfe\x19\x94\xe3\xd2JR\x01/\xb4EE \xa9\x9b\xdc\xed\x1b\xd1K\xaa\x9bR\xe6\x9f\x87\x81\xadM\xe5\x07\x065\x86\xaf\xbb.\xd7qF\xf3\xfc\x8a\x11\x19$D\x82\xf98:\x93vz\xf7\xc2\x0f\xa7\x9c\xba\xd1\xa2\x1a\x8f\x9cT\xf6\xa6l\x86\x8c\x84B\xe7\xfc\xfe\x908\xc2\xfb;\x16\x14\xa7\x10#\xaa\x13\xd5\xd3\x9e6\xee&\x82\x84\x94|\xbb\x9b\xa3\xd8hL\xaa6rM\xd1Q\xd8\xd2\xc5Qu\x8e\xe5\xd9\xa1\xdf\xc7\xf9,\x8e\x96\xf4T\x86\x11\xbc\xfb\xa7\xa2\xac\x1c1\xdb\xc50\xd8\xed\x02g\x97bpW\xa3M\xb4iB\x1fNc]\x84\xbaz\xa4\x8dI\xeakO\xea\x1a%\xcb\x8dv\xd0\xe5\xcf\xb9\x1bK\x0b\xbb\xa3[_\xf5@\x93\x1bQMd\x01\xfc\xac\xa2\x9c\xd6\xbc.Z3\xee9t\xb2\xce\x98\x9b\xde\x01\xfa\xe0\x14\xc6\x9b\xed\xfbA8\x97\xb8\xd9\x9c\xe7\xf1\x85\xb8 |,\xd0Z\xc7\x00\x91F\xcf&\xe9\xde\xb420\xbb\x16\x02\xe5\x8f\xf9k;\x8f(\xee\xb6Ppo\xf1$\\\x07\x94-\x97'\x18\xb2\xd9\x85\xbaA\xa9/\xcb\xb0\xc2A\xe1\xed+\x9e\xccZu\x96A\xcc*\xfd\x99;d5\xd0\x92[\xc3\xbd\xafg\xef\xe2j\xf4\x85\x8a\x0b\xcd\xb4\xb6\x05%\xaa\xc3\xe7,o_\xfb\xadf\x04\x95ru\n\xe5\nL\x95U\xdf\x86\xb2\xa8\xaaO\x95B~>?\xf6\x9f\xec\xa4\xc8\xb0\x12#H\x84\xec\xd4\x9a\xca\xe1\xf0\x13\x12\xcch\x15\xfc\xf7\xd3'\xb8\xf2\xc3itU\xa5/\xbe>\xb272\x12&_&}\x00\x7f\xc81\xcd\x9f\x16\xaeS\xdds4\xc4~\x816\xc8\x06\xf0\x00\xf2\x9a I\xdf\xf9K\x12eiK)'$W\x10\xd9>;\xc0\x8a\xaf1\x1cB\xc1\xff\xb8\x80\x03\xe0\x85\x15\xb5\x05\xf6\xfb2LI\xbc\xf6\x82[v,>\xd7\xf7,J5]\xcb#C\xfdK\xe9\x83F\xf1\x873\xf9\xa8\x88\xad&\x96\x8fJ\xda\xd2\x98\xcc\x94\xec/\xec\x8d<_\xe5#l\xb7 $\xa55f\x10\x89\xdd\x1c\x0f4s&a\x1c\x05A\x1b\xfd\x90\x0c\x1d;\xa5\xcd\x05\x84\xff\xf9r\x8a\xd2\x87\xfc\xaa\x8a_\xb4\xb7,\xd4\xf4w'\x9d\xa9\xd6p\xb4\xb7s\x84\xf3\xe1$\xf5\xd7\xe8'\xda\xf5\xc4\xcf\xcf\xe9\\\x7f?\xc8/R\xa5\xaa\x1a\x8dV\x91bQm\x15FPl\x99\xe6\\ri\xf7<\n\xc5\xe4\xd9\x9dD\xfe\xb7\xee\xb2G\xe3q\xe5bD\xab}G\xec\xb9\xe5\x92L}\x16\x9b\xa5\x99\x84\x95\xbfP\xb2e\xb2\x01\xa95(\x0e\xe6\xac\x8b\\\x98\xef\xbc\x0d\x87\xa0|\xa3\x1dD\xb5Ni\x18\xe5\xe2\xe2|\xb8M\xde\x9a&\xde\xd9\x14P\xcdGU\xa2\x9f\xc8Q\x88\xea\xd1S\xd8#\xe1\x8d\x82eA\x07R~\xab\x99F\xdfDW,W\x8em\xb4\xfeF\x13\"kA>Zz\xd3\x1eV\x8eq\x90\x1a*l\xd7\xd7\xf0\x92\x89\xef\xd7\xd6\xb8\xf0C/\xbe\xae\xaf\xe2%d\x7f\xb7~$\x93d\xd0Ta\xbb\xa1F:\xeb\xef\x07\xa4\xa9\xcevc\xa5\xd8\xbb2\x94\x83\xe4\x9fm\xc8+\xd9hq\x95\xfbwWwxys\x1b\xf2\xfc\xe8\x18\x19Ee+\x90\x0b\xf7\x07i\xeb\x07.(`3\xff.\xae\xa3\xf8T\x18\x9e5\\\x03\x91\xc7\x8f\x9db`u\xca\x97F\xdc\x85V\xf8+\x9e\x16\x83\x846h\x08\xadP\x11Z\xa2#\xb4EI\xf1H\xd3\xc0\xdaM3 \xbc\xd4\x0f\xfb\x8d\xbd\xd7\xee^\xf1\x88\xbey\x9bM]\xd7nwhEZ\xa0\x05\x8d\x13\x8fP\xe9\x98\x87\xd5\xb8'A8X\xd4\x87\xd8\x12\x0f\xa5\xd96'\xdaez\xcdbQl\xf5\xb4\x9f\xeb4\x84\xba{I\xbc/\x13\xd12\xb6\xca\xc1\xc5\xed\xd213\x1a\xf1X\x85,\xbdQ\xd5'\xc4z\x1f^\x86\xd1U\x08\x82\n\x0c\x81\x0d\xdb\xa8\xc7`\x07l\x99\x12\x15a\x1d\xf2\xb8t:\x8e\xab\x05\xdac#)\xf9(\x92\xc6\xb06)\xe74a\xa0\xd3Dh\x04\xb3\x89k#\xa9\xc0\x0ef~\x10|\xe3\xa1\x96\xce\xbb}/\xb5X-\xcfkV\x9aW\xc0z\xdc\xd9\xa8\xc7Z\x84\x95U\x98\xcc\xfek\x04+\x96f\xdc\x96:^\x98$g\x10\xe3\x0d\xbc$}MP\xce\x16\x81\x11\xe9\xabwQ\x8a\x82\x92\xfc\xeeh\xe11\x8f:\xd9\x1b\xb0\xa4\x0c\xcc\x7f\xe6gUV\x13\xd6\xfa\xc9\x08\xfa\x83\x07\"c\x03<}\n{0\x1a\xc1>\x1c\xc0@\xbc\xd9\xa5o\xfa\xbbp\x00;\xe2\xd5\x0e}\xb5\xd3\x83\x03\xd8\x15\xaf\xf6\xe9\xab\x01\x1c\xc0v\x1f\x86\xb0=\xa8\x1d\x92g8>\x852\xb0\x98\xfev\x19DU!\x7f\x13\x07h\xb4;\x19<\xa4{\xd9\xee?\x1a\xc0=L\x0f\xebH\xb6L\xe5\xa5\xb0\xfe\x9f\xff\xeb\xff4PY\xf40*\xaas{A\xc91\xac_w\xb4\xea\x06\xd27\x0d\xa4_;\x10\xd0\x0df\xa0\x0c\x06\xffV;\x1c\x98:\x1c\xf0\x0e\xdb\x13O\xae\x0f}\xacC2I\x90\x08\xd1\xbd~\xa8`\xfd\x13\xc9\xd7\x0c\xa3y\xa1Wf \xe5qY\xe5}@?t\x94}\x91\xa7l+\xf3[nuS\xb1\xa8`\xb5\x1d\x89\xcb4y?\xe7#\xde\x96\x02\xa0\xd5\xef\xbdD\xab\x01\xa0\xebe\xa7\x85'\x10q0!\xf9\x08\x1dWjt\xf2\xc5\x0cs\xf2n\xb6\"\xa9\x0f\x03\x80\x97\x91\x93\x85\x17\x1fESr\x98\xda\x92\x07\xac\x1aWZ<\xb4\xd1\x98J\xdd{{\x83G\xfb\x80f\xf9OF\xb0\xb7\xbf\xd3\x7fT2\xf8Rp\xa9B\xd0v\x95\x85\xe3)\x9a\xc7\x12D\x06gj\x9d~\xa5N\xff\xcc\x85\xb0pS\xd7\xe6\xd9\xae\xbc\xd1\x9bxh\x89\xa32\x93\xbef&\x83\xe6\x99\xf41\xe5\x85v\xe1\n4C\xa8\xd7\"R]\xaa:\x90\xef\xc3\x0f\xa4\x03\x89]~X\n\xe5@jQ\xdaH\x0d\xf7@fr\\\xc3\xbdtL\x9bS\x82@\xaf\x1a\x0eL\xb7\x12\xa4\x1623\xed\x16\x13\xe3\xafl\xb3\x1d-\x91\xeaq_\x93\x83\xd2ZqV\x83\xbb\x9d\xd9*F\xec\xc06\xde\x94\xa8X\xb1#\xec\xd1B\xb1\x1a\xb5\xf8Qj\xfa\xb3\xf6\x83\xe3\x1a\x86_\xc2\xb4\xb0\x81f\x05w\x87j\xda\xadtP\x8b\x1d\xf9\xa0{.\x02X\xc1\xd4a\x036\xac\xcc\xcc\x8e\xe1|\xa8\x07\xc6\xa2\x86yj\x82\x85\xd4\xb0\xf8E\xca\xd1\xdcX\xc6\xc7\xa8d\x1b\xe4\xa7\xf5\xc2\x7faq\x9b\x9fA\xb9`\xa8\x80\x1f\x97\xcdU\xdd\x9e[\xed\x7f\xbfHB\x87\x9e\x989k&\x98x&\xe7\x18:\x06\xd9\xba\xf12u\xbd\x84\x02>\x1e}\xae\x9a\xdeJ4\xb2\xbd\x8d\x83\xa1\xab\xb7=`bv\xdd\xc0\x90\xb1\x92F\xe6\xb4\x1e\xc3\xe0\xf7\x1f\x03o\x0bC\xef\x8cD\xca\xbc\xf2\xa8v\xf4\xa3\x12\x9d\x97\xb7\x8f\xd9\xb0\x98\xe9 \xcb[\xbeJ\x15E\xb8~\xf5\xeb\xca\xf9\x16V\xa9\x8c\x1c\x9e\x01\xb6\xc1\x0e+\x94[\xbf1\xb4,x\x8f\xf9M\xeb\x86FKL\x1bFR/\xd4S\xcf\xf2v|\xa2!\xa4\xfaq\xd5\xf3Bw*\xa0(+p\xeb\xe1\x14bLy\xd2\x92\x04\xa3\x9cR\xb7\xba\x99)e?/^\x17\x176\x035y\x1f\xcfq\xae\xcf\xcb\xac\xd1\xae#\n#\x04J\xd9T\xca9\x13\xa2j\xda\xf0\x92\xc9}n\x8b\x91\xc6^\x98\xcc\xa2x\xc9\x8c1tn1\x18\x17\xfc\x9d\xa8\xd7\xc2r\nT\xaeY\xe9E/T\x85\xdd\xbcV\xbd\x1fG!\xb5\xe1y3\xb90\x0bi[qY\x1c3\x06\x0e`\xcc\x06\x85\xd0\x857\xb9\x14qj\x96Y\x90\xfa\xab\x80@\xea/Ib\x8cw/\x06\xb2\xc8\xc2\xcb\xdcG%\x1f]\xf1\x86\xa7\xec*L\xadx\x1aWW\x93O[<\xe2\x80apl\xe1}\xe0+\x86;\xb6_ k.\xecc\xe1 \xf8\x9a\xa8\x1bEW\xb6Z\\\xe9\xf1\xa6\xb0\x01\xd58\xdd\xd1\x8e%\xc4\xd1\xd9H\xcak\xae\xaf\xc1\xc1\xc8\x82]\x98\x8a)\xe8kk\x14\xdafZ\xa9|\\\xe8\xad\x97t\x0154\xd5\xa4P\x1e\xb5\x89E\xf2\x89J\x06O\xc5\xbb\x91\\\xc3\x9cgd\x16d\xc9Bj\x80\xfd=\x12%\xc2\xe4\x1e\x0d\xb6W1\xc9\x1d\xf5\xb2&\xbd\xa8\x8e\x9d\x12\xbe\x18e<\xd3\x8fL\x1a\xcd\x81\xfcW)g\x9a\x96\x19\xf3r\xdaZ^\x14\xcaDz\x9c\\\x15\xfb\xa7~\x1e\x9e\x89\xeb+\xdd\xa4hLH\xabLB)\xb1`Z\xc4\xba\xaf\x84 \x10\xe7e\xe5\x9e\xe3\xc8\x0b\x02\xba\x0d\x8bE\x9eF!\x81\xab\x05 \xe1*\xcf\xa8\xb45\x82\x9e\xa5\xe9?U\x89f\x89:n\xd8]\x92\xfaAP\xdajj\x979d4\xbe\x00\x85\xcc\xe6W\xf2\xaa\xb9\xd2;;b\xdcJ\xb4adw\x99@\xab\x93.Q\x90\xdc\xe9\xa9\xdc~\xc5\x97\xac\x18yy0\xa5\xfd\xd6$(T\x00\\|m\x080c\xec\xb6*\xc9\xea\xbb,{\x9a\xd5\x9d\x99(\x9b\xc8\x07\x0c\x85J\xe9\x10J\xf37\xd2m;qa+V\x10I/\x1e\xb5>r\xecXY#<_\xbe\xd0\x89sc\x04\xb1\xeaYP\x7f\xa9R\x0b\xdb\xdc\xe7\x84\xc8\x10\xc5[\x04\x01p\x16B\xb8\xc4\xae`\x0c&\x95\x81\xe9U\xb8,[n\xd4\x15M\x16\xfc/\xe9\x96\xb9-f@\\\xdd\x06=#$Z\xe6i\x90\xf93\x95Q\xac\xb6\xa6l\xb1z{\x0c\x96{=\xe4D\x969\x90\xab\xc4]!.\xb7b\xb5%\x9eZ\x97\x89\x17sH\xcaBQ\x14\x1f{\x93E\xb9\xa2\x94\xe2|\x12\x93\x12.\xb4K\x8b+\xf0*bDSKU\xb9\x0din3\xda\x04@Lgz\xef\xde\x06\x8c\xb6\x9e\x15DK\x97\x10\xbd\xd9\x1c \x18\x04\x10\xd2qxV\xa9|c\xf3\xb4\xb8\x18\xc9X]+\xb7\xa4h\x84\xdb.\x97\x16\x9e\x0e\xfc\xfd3\x9a\x940`\xc7iZ93\xcd\xf5\xf5\xab\x96\xbc\xf6^\xdb\x98X\x16\x95\x18\x84\xa9/\xf0\xe2\xee\xde=\xae\xad\xd8\xc6\xc4\x0c>\x86\xb6\x1e\xe6\x8e\x95x#\xd4\x9c\x1d\xb9\xd5\x1c\xcb\xfe7\xbb\x0f\x06\x8eM\x87\xc4\x91\xd6K\x12\x7f\x1e\xc2\x10\x8bv>\xd7\xa2\xd0\x05\xdf\xc5Tr.x.\xcf\xe6:P\x13\xa4N\x9aH\x0b\xe8\xee+\xe8#\xe7\xcc\x8f\xaf\x95\xaf\xf4\xaeY\x13\x17x\x08@\xad\x07\xd6$\ng\xfe<\xab\xc9$.\x985\xbdl\xd1\xe4\xc1\xb5\xf6\x82\x8c\x0cA1\x02\x96\xd6\x15&^n>V\x9cN\xec\xcec\"]\xe5\xc6\x15\xc9\xba~\xe8\xe6a\x97\x87\\\x8c\x84\xc55\xd4B\xd1\xdd8\xa12\xa5h J\xa6\xb9*k\xc4s\x06\xa60\xa4\x87>B\x86\xb1\x14\xe8\xa7U\xacR,_\xaa\xe0m\x11\xcfn\xfc\xe8\xa1\xe3b:\xd4\xf1\x19\xcbl\xdd@U]\x9d\x02\x9cr>\xde8=\xcb\x99y\xfaG\xb9\n\x92=\x82\xfd<\x86t{\xfb\xb1#|\\-\xcf\x82\x0e\xd8\x9dN\xe8\x14\x1a\xa8\x9d}U\xae\x97\xf4(\xc2i\xc2\xb6f!K\x98\x8bE\xb9\xc4a\xd3\x06 \x0fq\xef\x82\xe5@\x87\xfe\xef\xef\xa2\x8dY(\xbc5\xf1\xec,\xdc\x06\x1e\xc3\xcd\xe32\xcb\xd8z\x8d4\x14\x1f\xe5\x1b\xc3\x9a\x15b\x8f\xc2\xe7\xe0\xa9E\x9c\x8a\xea\xa1\xba7\xe9\x93\xd9\xe8\nU\xde z\xf4\x07\xdd\xed\xf2\xcd\xe7\x12'&r\xe8\xb2\xad\xeb\x91\xbeTM:\xe7\xe7$}s\x15\x8aj\xcfI2\x89\xfdU\x1a)\xf6\xd3\x99\xe9\x83\xd7\xdeR\x0dh\xe2\x99\xea\x9e^//\xa2 iq2i\xd7\x98\x91`~4\xc76Q\xf1\x14\xe5D\xb9\x06\x86\x18\xc8\xec\xc4\x11\xccN!~kC\x0d\xeaW\x1a\x9b\xb6\x99\x87M\xc4\xc2\x14j\x14?\xf2\xd2k\x9b@\xee\xb2\xfa]\x19\x81L\xaa\x0e\x0f0\x82\xdb\x7fY3\x91\xed{r ]/g\xffS\xb9\x95\xcf\xdc\x15}\x1d\xff\x1b\xda\x0fUUs\xa4w\x03\xa3\xdc\xe9mq\x94\x9ek\x9a,xt\xfb\xe4\xc4n<8\xd3B!Fj\x85\x0b$w\xc4\xd8\x10O\xb7\x1a\xe18>C\x07'\xe1H\x91\xa1<\"\xbe\xa8\xacH\xd8\x00g\xb9\x8fv\xfc>\x1f\xfa\xd6\x16W\xf6\xb1\xf0\x03\xe5\x14r\x9f>\x19\xb4d\xc8\xd5\x9b\xf4\x83\x0b\xd24\xdaVX\xa1\xe7\xa3\x88\x0b\xd6\xf99I^E\xd3\x0c\x0dN\xd4\xa5D>G\x16+Yt!/N\xc8\xf7\xde28BnE\x93\x16\x7f]D\x88\x0e\xed\xbdAO\x83q\xc8\xfc\xb0\x80\x0dq\xb7\x18\x04\x1c@\x0cC\xcd\"\x0bSS5\\p\xd1\xa9n`\xb5\xa8\xaa'\x0f|-#\x91\xe3\xaf\x9bx3\xf2M\xe4M+ \xacjID\xce3\xb1\xd0\xc8q|\x88\x03I\xba!\xb9zG\x89@x\x1c\xc7v\xa1IB*\xad\x1c\x97\x1bz\x916\x11\x84\x9d\x87\x06q\x88\x8e\"\xb6\xcbs\xf0\xc3I\x90M\xc9\x10\xc6\xa1=\xe8\xed8g\x12\x12\xfcC\x07\xd3\x1f\x0c\x9c3\x85\xb0-W\x81?\xf1S,\xdf\x1b<\xc0P\x06{\x83\x87\xfc\xdfG\xec\xdf\x9d\xde\x1dM\xe2N7S\x10y\xcc[\x99t\xdf\xbd\xf9\xea\xabo\x8e\xcf\x8f\xde\xbc~\xf1\xf2\xabS|\xf5\xfe\xed\xf3\xc3w\xf2\xab\xda\x9d6\xe8\xed\xfdN;-[M\xbd\xaa\xf6\xd2@\x165\x07\xf3\xf5\x8a\x0c!\xab\x9e\x10+\xef\x9a\x02d\x08v\xcf-\xb6\xa0c\xff\xfdF\xd5\xe2\x02(\x9a?\xd2M\xa3\xf9<\xa87\x0ej\x18\x91&\xabJ>\xa2\xd4\xd4uy12\xfd\xbaYL\xb2K\xce\x19\xe4\xac*\xaf\xa8Y\xff\xfc#63K^\x81\x1cod\xad\x89n\xaeU\xad\n|\x1eA!2\x12\x8dJ\x0ef%l\xec\xef\xa9\x0c\xc8\x97\xc2F^\xa7\x85b'\xa7\xca~\xc8\xe2:\x94\xd1\x8c}U\x1d\x04\xdf\xbca\x83\xae@\xa3i\xd8H\x17\xa1\x18\xac\xa0\xa9\x16\x8b\xde\x19\xba\x9br\x87\x94\x1a\x10\xf9\x1c\x18\xdeQy\xa1\x8f\xb7\">\xdd\xd1\xd6%\xb9N\x90\x91&\xdc\xa3\xc2\xc2\x1d\\\xbc\xc3\xe47C\x16\x14w\x1c\x9e\x9d\x95t.\xa22\xdeZ\x1e\ny\x05%\x0c\x0e\xe9\xd8f]\xa0\x91\x86T\x1d\xc3\xd0\xa7\xb1O\xff\xd2\xe2O\xa3haT}7~\xb9\xd1\x01\xcc \x9a&\x18\xde4\n))\xda2\x1ew\xb7\x1c\x9d:4\xbf\x1cJyK\x96\x87\x98\x90\xfc\xeezE8o\x0c\x1d\xb0\xc4\xed\xaa\x977\xbae\xba\xafn\x18\xec\x86\x9b\xf8\x91~\x0f\xef\xedj\xb7\xf0#\x95\x05\xcbP\x18.\x1a\x0e\xed\xc1\xbecg\x94\xf2\xec;\xb6\xe5\xa7$\xf6\xd2(\xa6\xe8\xd3t\x94\xa7r\xf0\xb2\x1b\xa7F;\xa8\xbb\xba.h&\x8c \xa6#\xa8\xe2EH>\xa6t\x13i\x12\x91\xd3\xdd\x80m\xe3b\xbc\xcc\x87\xbd\x19\xb0%\xf5\x84\n?N\x1a\x1fh\xc1\xba\xdb3\x93\xc0=\xe9\xea\xa3\xc4\x94\xfb$i\xca%\xe8W\x14\x9dEf-\x17\xd7.B}\x04\xe5\xd02N\x81\x98\x06\xae\xf7\x18\x85\xbd\x07;\xbb;\xbc\x7fV\x1f;\xa2\xc8\x82\xce\xdf\xf4-\xf3\xc2L\\\xecd@\xcb2\xd8\xe6\xcdt\xe88\xb7\xf9\xa0\x9e<\x81~\xcf\x81\x0e\xec\xef\xed\xed\xec\xdf\xcd\xa6\xaf\x1c\xa9\xfc\xe0\x18\xf4\x8dg\xea\xc0\xe9\xceI*\x0e\xf9\xe6[Y\xa4\xf3\xeaIjd\xf1H\x03\x8b\x87<\xd1E@L\x0c^l\x13n{\xe4\xdcz'\xf6w\xf4\xd7#\nOV\xa10(\xa4\xb5\x03\xdb+\x92.\xa2z\x034\xc9\x8dl\x0b\xa3\xcd\x0b\x9a:\xf6\xcf0\xc0\xc5\xd8\xfa\x97\x7f\xc9\x87\x83\xaf\xa21\xa5Ng\x9b\xcd\x9b\xae\xf6\x0eJ\xbb\xfd\x1d&\xf5\x0evv\xf9\xbfLM:\xd8ej\xd2\xc1^\xaf\"\x0e\xf7\x1f9B\x14o\xd3Y#C\xad\xc3G\x99E\xf6\xc7\xa1\xddwlK\xdc\xc6\xbf\xf3\xe6\x96s\x06#\xb0~\xc1L\x8d\x1d\xba\xcf\xb7F`\x8d\xd9E\x0b\xfcrf1\x1d\xc1N\xcf\xe1VK\xa5\xe8\xbd\xa2\xa1\xba\xb0\xdd\x1c\xf2y\x9b\x16t\xe89\x80\x01L;`\x9d\x95\x9c\xe3\xb6\xda\xe9\x07d0n\x85\xf6\xee\x80%G\n\xed\xdd\x1d\xc7\x1cx\x8d\x8f\xe4\x01\x9d\xa2^\xd7\x1c\xda\x8f\x1e9\xb65\xf5\xd7Tl\xb0<\xad\x19\xccF\x81\x86\x1fT\n\xd5\x9b\xcc\xaeW\x00\xa0\xd5\xe4%]\xbf\x89\xd0\xd4\xb3\xe6\xe8\xaa\x81'\xb1\xdeV\x813\xe9~\x95\xea\x10\xd3\x95\x9a]\x8e\x13\xc0\x96#\xe6\xb1\xc7\x05I)|\xd1j\xe9\x99\xda(\xca\xd4of\x9b\xb7\xb9\xf5e\x86\xab\x92X\xeb\xc8\x0b\xff\x94\xc2$\n\xd7$N\x81\xa3y\x1a\xc1*\xf6\x97>\x06+\xc4)l*\xd25m\xf7\x81\xe1\xfc\xe9\xef\xe8%\xe8~O\xe5_\xaa\"t\xff\x01\x17\xa1\xfb\xff\xaaE\xe8\x87\x86\x83]}\xcf\x01\xbb\xab\x03,\x05x\xcf\xb1\xad\x97\xc7\xe7oO\xde\xbc{\xa3\x1ez\x9e\xaa\x9e*\x17\xab\xda\xab\n\x15U\xba/F\x8c>?\xf9\xe1>/b9FxXV&\x1e\xa7\xdd\x17\x8f!F\x8b\xb3) HJ\xe4\xac7\xe3h\x1c\x9fir\xa6\n.W\x8d\xed\xaa\xa7\xa3%c\xe5rP\xc7v\xa6b\xbc\xbb\xdc\xca\x1d\xefF<\x05\xdd\xd1\x80\x1b\xd8\x0d\xad\xe7B\xb9\x98{\xe3\x8c3\xb4'\xc6\xec\x93hzVX\xc0\x8c$}\xac\xcf\xb2\x19\xdf\x16\xf1\xf7\x0c\x14\xc5\x80\xf75\x1c\x1b=\x92\xff5(\x8f\xf6\xf4\xa4b_wEG\x99\xc2\xbeco\xb5\xa3\x16\xb78\xd99\x80<.5T\xe9\x00\x82\xa8\xfaz\xc2\xcc7\xab\x10Gsv\xcfaJ\xa2\x8c\x19Z{\x08\x8b{\xf7`\"\xfc\xb44\x1f>\x96\xa3@\xe1j\xe0w\x94,\xe0Z\xb0d!\xff.\xb2'\xd8\xda\xa7OEk\xfa\x05\x9a\xdcv\x81vM<\x12\xb7\xe3\xb3~\xb1\x1c\xba\xe1\x90\x01|\x99\x1c\xe7\xf7\x8ev\xaf\xc0\xe0\x12\xc2\x9a\x18\\\xce\nS.#f\x96\xec)&\x10Km\xcb\xa2\xfb6\xb7\xfa\xbf\xedT*H\xc5pmWg\x9c@ \xb6I\xb5\xdb8\x95\x92^\xe2\xdf\xf4\x94\xff\x15\xe9)\x0d\xe4j\xb0\xa3\xfa\x1dD-8\x18\xc9j7?\xb1j\xcf\xd19I\xdf\x8a\x8aof\xf5A\x92s\x90pZF\xf7\x94\x0b\x11n\xabqt\x06C\x93i\xdf$\n\x934\xce&i\xc4r\xe3\x83\xe4\xb7_.=(\xff-\x1d\xbb\xc3\xf2g\x9c\x08\x1c@\x06\x8aG\xf3\x86\xe0\xef\xdfzK\xcaV\xc7\x9b\xf5\x9e\x1f\x9d\xc2w\x07\xfdH\xf3\x03\xdc\x15\xda\x97\x9e\xe3\xf2\x93h\x8f\x1f\xad(\x0e\x08\xcf\x94\xdd]\xc7\xc5\xfdLe\x03\x177\xed\xa4,\"\x04\xecUI\xb9\xc0\xf2\x82'\xe2~wQq\xcc8:==\xc9XN\xbe\xaa\x19\xc7\xd1\xe9\xe9)eH\x9f\x93I\xe0\xc5\x1e\x9da\xd5E\xe3\xe8\xf4\xf4\x03\x15\xafx\x13ji\xe0\x930=!\x93T_\xfe\xfc\xcd\xab\xdaB6\x17c\xf1\xbb\xe8\x92\x84\xfa\xc1?\xf7R\x8fy\x11\x92\xf8eJ\x96\xfa6^\xf8\x81a\xe4\x7f~\xf7\xea\x9b\xc3 8\x8a\x82\x80L\xf4S\xa7U\x9a\xca_D\xf1\x92k\xbb\xf5\x15N \xfd\xdeX\xe5\x15\x99\xfa\x9e~\x86\xaf\xfc%\xa1b0.n\xf5\xcb\xd7\xde\x92L_GS\xf2\xca[iJ\xa3\xa9a\xd5\xdfz>]\xb1\x9f3\x92\x18\xd6\xe5m\x90\xcd}\xcd|\xd9{\xc3pN?|\xf5\x0d\x1eC\xfa6O?|\xf5:[^\x90\xd8X\xfc\xd6K\x17\xa7\xc4\x80\x0b\xb4<\xf2C\xc3\x80O?|U\x87H\xa7\x1f\xbe\xca\xfdM\x0d5\xa2,\x9e\x10\x16z\xdeP\x83n\x94\xd3\x05!\xa9\x1e\xaa\xef\xc8\xc7\xf4]\xecM.\x8fL[%\xafa(\x8e\xb2I\x0e\xbb\xbc\xe4\x86\xa5\x0b\xf7m\x0cY\xc98\xf05<\x81\xa9\x904a\xdd\xe9\xe8\xf8\xd4k\x17\xe60\x82\xe9x\xad\x18\x9d\xd2g #X\x8c\xe7\x9a\x92sd\xe7u%\x170\x82sJ\xf1\xcfu\xa7\x11\xf0c\x18\xdd\x89\xed\x0bz\xf6~\xfa\x04\x9e}\xe1\xc2\xcc\x85\x95\xe3\xc2\xc58(\xde\x05,\x07s2\x9e\x9f\xb1\xe8\xbaK\x8d/\x03R\xd6kz\xa2\xc7\x0e\\\x8c\xaf\x99\x1a\x99~~\xedB<\xbe>+\xf4\x99\xd0\x96Z7*}\xb4>9\xf4\xbd\xe1~_\xd5\x05e\x82\x954In\xfd\x9d\x07\xfff\xf9\xf4_\x8e\xe5\x93\x99\xd7pl+\x0b\x93I\xb4\xa2\xd2L\xa22o\x1a\xa7m \xdf\x84f\x01\xfcq|\xc6\xae\x00\xfa\x0f\x1c\xdbG\xef\x8f\xbf\x9b\xf5{\x15I~\x1c\x9f\x8d\xd33\xc5\x89^;\x11\x93~\xbf\x16\xf5\xf8\xa2\xea\xc4\x93\xbb5\xc4j\xbfMe\xb7^\xbe\xa1T\xa6;\x11lV\xe9-c\xae\xf6U\xab\xa8\x19\xbe\xae\xdc\xed\x04\x8ckS\xde\xae\xd8[U\xc3\xb0`M\xab\xaf\xa7\x9ct\xa8\xd6\x91k\xf6~W\x1d\xca5\x17,\xd5^\xe7\xfc\xfd\xae\xd3M\x88\xb2e\x97\xbc\xad=\xc7V\xbe:\xe7,\xb1*\xd5^\xf0\xd6T\xf8\\\xf1\xf7*\x01\xfc\x88\x1cf\xae\x8fW\x8eE\x91\x0c{B\x12\xc5\x91\xf0\x18\x8b\xf8\xfd[\xb9\xe8\x10F`\xf1\x8fp\x87\xcf\xecS\xa5\xd77\xf5\xea\xdb\x9f0\x92\xde\x08\xce\xbb\xb3r\x01\xa5\x84[[\xf5\xaa]\xb3\x7f\x9d\xa0\x8e\xc7\xdd\x98$Q\xb0&\xb6\xba\xa6\xf2CX ZY\xe6\x19\xd1\xdd\xcb\xaf\x01\x93\x15\x99 a9\xab\xdd\xc3\xea\x93\xdao\\xc\x96v5\xd9\xfaA\xb2\x0394zl\xf1\xa58!?1\x86\x163_\x8a\xac8\x0b\x12\xdao\x1cY*\xab\x8a\xe55\x1e\xb27*\xf6\xbdl\x9c\xf3\xba\x9aX\x05\xa4s\xc4\xde\xc2\x98\xaf\xe5\xc9\xe4w\xf1,p)\x0e\xdb\xc1)\xa8\x89\xb4J\x7f\xbej\xa2s \xae\xb4\xd2\xee\xb9Q B\xcb\x14\xc7\x01\xf9Y\xe7\xe1\xbc\xcf'\xfa\x1a\xcb\xe6\xa4U\xa0J\x94i\xf7|\xcd\xe4\xc9>.e\xf7\x1c\x00\xe9F\x97\x18\x94e\xe6\xf9\x9ahc\xea\x93\xe0\xc5\x03\xdf\x1b\xcd\xd5'\xbc:E\xb8\xe6\xda3\xac=\x8d\x96\x9e\xdf\x94 \xc4\xb8\x81\xe5\xc7c\xc1.>}b19)\xec0\xdc\xd8[\xc6E\xd1\xbfF\x18\xa4t\x8b)\xf9=d=Fh\xedoc\x0e\xadY\x97\x84)\x89m~\x81\xe0\xd91\x8a\xe6\x94\xc5\x9du\xc9G?\xb5\xb9P\xbf\xd5sX\x1d\x8c\xb4\xb3\xe2\xe6\xff\x070\xb1?\xda\x16\xdfw\xdb\x93\x85\xe7\x870\xb9\x9e\x04\xc4b\xa1\xea\xe9:\xbe\xb4)\x06\x1f\x087\xd0\xd0\x85\xc4\x85 -N\xb0d\x08\x13;6S\x03P\xf7e#Xp\xfc[\x19\x9f\x1f\x9f\xc4\xc4\x94f[<75\xf4\x08\xc2B\x19\x1d=v \xb3\xc3q\xd4\xe9\xe8\"\xc8\x8a\x87n\x12\x1e\xe1&p\xd4p\xad\x9a\xde\xde6\xf6\xb6)\xfe\xea\xb1QF\xac\x1c\xe8\x7ff\xaba \x9c\"\x1c\xa7\xf2\n|\xb9\xd8)\\\x83Rm\xd0I\xa0\x12\xddS\xad\xb7~\xedJ\x9d4\xc2n-\x05S\xab\xc2\x85t\xcf1S\xb4\x8d?X\x184\x84\x01\xe9\x9e_\xd1\x02\xe2t\xcf\xd7,F\x1d\xe9\x9e',{\x04\xe1+l\x13\x86y\xa4{>\xe1\xc6\x94\xf4\xa0xe\x13\xd4]\xd4\x8e\xfcu\xbb\x91\xbb\x86\xc8g X\x9a\xb0{\xae\x0d\x05\x0f\x18\xec5\x9f\x14\xde\x90\xf39\x19\x8e\xdf\xfac\x17\x03M\xb2\x00\xf6bc\x15\x87\x1fL\xd0\x88\xe7\x82\xeefd\x1e\xa6\xe0\xa7 f\xaa\xa9\xa4\xfc \x9c_\xa2%\xd5A[\xe6 $!\xbd\xf9,<\xbf\xd2zGV\xaaM\x87\xba\x84\x82\xf2c\xe0\xca\xc5\xd3\x8ec\x11\xe6\xa1\xf4<~\x8d\x07L\x1f\xcf\xe6\x13\xfe\xfb.\xd9\x80\x93\"\xf3\xed\xadO~g\x88y\xc39\xfa\x87\x0c\xfd\xfb\x14\xbfC\x17\xb6L\xe3m7N>\xbe\xfa\x89\xb4X\xbf\x86\xb5\xbb1\xce\xbf:o\x85\xc9(V\xfc\x12\xf7\xfaq\xed\x86\x9d\xf2\xa8I\xc7.\x88Ma\xb9`\x9d/,\xc7\xc5t\x14\xae\x1c\xd5\xbaU\x14\xa3\xd4F4a\xed\xe6\x98\"\xfeT\x88K-\xd0O\xca\xf1\xb4\xcb_\xe6\x7f\xdd\xb8\xec\x107O\x92\xa9\xf9r\xce\x0e\xff\x92O^\xf6&\x91U\x97\xe5l\xe5\xebJ\xe5\x85\\\x991\x8a\xc5\x80\x9c\xb2-\x8f=\xd8\xddw\xecc\xd9\x86V\x1d\x1f [\xc4\xfc\x16\xa2\xdcO\xb6\x88uu\xac\x0b\x97-\xac\x8f\xa8\x0c5\xd2\x8a\xa9\xec\xca\x19\xf7\x06\x15\xb0\xca\xb5F\xe5\xd4\x83\x94\x92s\xe9\x07\xd9\x18z\x16\xf3?\x87\nL&R\x08_\x0e\xe3<\xf0\xa8\xa7\x96a*\xdfW|\x1e\x98\xb8>\x14\x12Jy\x9d\xcb\xfb\x08\xd1\xa5\xce.\x03\xca\xd6\x89L\x85\x90\x8f\xd3\x88C\x8e\x12.\xcd\xa4\xa0\xc6x\x1a\x8f\xab\xd8%\xb8\xc2\"];?Q\xf0z\xf45\xc6[\xc8\xb3\xf33&\x05KNx\x89\x8c\xcd\xe7]*s\xfe\xd4\xe6\x828\xc5\x93\xed\x18\x97\x13\x7ff\x94\x83\xe6\xc1\xe9Q\x8d-\x1b\x9e8.\x04v\xd0\xfd\n:\x10t\xbf\xc5\xff\xbf\x80\x7f\x86\xadK\x15!\xdf\n\xa6\xe8\xb8\xf41\xb3&\xb5eZ\xc1\xad\xdd\x1f8\xb6\xfcJD\xa3\xcb\x0d\xddY\xc7\xa7\xa5.%z\xa3\xce\x8d\x82\xa7i\x91\x05\x83\xf4\x93\x8e2\x81\xa4z\xea\xb9\xb9\xb4\xef\xb0\xe8\x9bzD\xab\xc0\xa9\x18\xae\x8dl\xd3\xd6\xa5S;j\\\xef\xa6a\xf3Q]\xd9\xf9\xe6\xc8\xd7\xed\x98'\x93i\xc0S\x05\x92\xf6%\xd3\xd4\x0fv\x1fJV\xf0\x95\xbe\x8f\xbb\xcc\xc0\xb9\x8b;\xc8~#\xa3E\xdd\xb4\xbc h\x9a\x92\xcc\xaa\xeaO=F\xb5L\xf6BxsQ\xaf\xbe\xf1y\x15\xb3\xca&j/\xa9\n::\xd6\xdc'\xcaO\xa4\xb7\x9b\x93\x1f\x8a\xe8\x86\x14\n\xf4YSZN\x8f\x91\xf6zV\xb4\xb0\x82\x11D\x9dN3\x07\x98\xd4\xa4p\x10O\xc8(/#\x81tov:n\xa1-\xa3\x18\x81$\xb2\xfd\x08\x01;\xa6\xacE\"\x98\xf4\xb1w\xc6(\xdf\xf6vFKb;l\xe2\n\x8dB3p4\x97\x9a\xd2\xd6\xbb1o\xf9\xa8\x8bG\x97oG\xddu\xdb\x83%\xf6&\x8d{\xf7\xae\x10\xdd\x8c\xc5\xfe\x06X\xbc9nUW\xbd\xd8vP\xa3\xcd\xd3\x88\xb7P\xbf\x02>[\x81\xd8\xf6\xebV@\"A\xf8\xf3V\x97\x83L\xe9\xa5N\x9dgp)\xdd\x1c\xa0\xda^\n \xc84<S l\xc4\xe5\xb6\xa6m\xef\x97m\xe2\x81\x8d\x9fIN\xb38Z\xdaQ\x83\xad\x0c;7\x07F\x90\xe8ma[[\xd6\x17\x01T\xb6\x8a\xb4\xe3\xaa\x86Y\xe8\xcf\xd5\xf7z~A\x02\x9c\x9e\xd8\xa0g\xbf\x06\xa6\x90\x1f\xb9MP\x85:\x9f\x00\xf10\x0f\x80\xb0\xba\x00\xe2\xd1\x9cj.\x0el\x83\xee3]\x1b\xa9\x1d\xd5\xdczk\xe9\xfa\x9d\xa4\xa9\x90\xc8\xa5\x9e\xcbV=\x00\"-u\xe2\xf4\xa6\xa2.\xe4~\x0e\xbb\xfb\xd2\xba\xc5v\xdc}\x0b\x1d\x88\xbb'5wJ3?\xf4\x82\xe0\xba\xad\xba=\xe3\xb7\xc4~\x1e\xc1\x9aJ\xc2\xe2\x0f\x83\xae=4\xddjk\x98\xdd\xca}q(\xab&\x8d\x96\xd7\xfc3\x8fRGT\x84\x95/R\xea\xf8\xab\xca2\xcb\x8f\xce\x9a\x8c\x8al\x94\xad\xf8\xc2\xe3\xe2 u6\x1a\x96\xf9\xae\xf2\x0b\xa2n\xc5\x7fD\x84?\xd8S\xb0\xf1\xb4\x06\x0f\xd3\xb85\x0e\xd2C0\xd5g\xe0\x86<\xd1\x97\xce\x9eV\xdcB\x87]\x82\x86\xed\xfc\xee\x7fX\\\xc68v\x88\x97$\xcd\xd7\xd2m\xe0\x19\xda\x83\xbd\x01\x8f=\xb7\xc3\xff\xdd-\xc7\xaa\xdb{\xc0\xff\xe5\xb1\xea\xf6x\xac\xba\xfd\x1e\xff\x97\x7f\xbf\xcf\xbf\xdf\xe7\xb1\xed\xf6\xf9\xf7\xfb\xfb\xfc_\xde\xce>og\x9f\xb7\xf3\x80\xb7\xf3\xa0\xcf\xff\xe5\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=x\xa4\x8d\x9d\xc7|j\xdb\xc0\xa2\x11\x8b*\xbeNQ\x1ep\x13\x8f\xe3#\x1e\xae\xb2J\x10\xe5J\xd1\x94\xa0\x17\xb0\x82xH\x06\xd1z`\x8b\xd9\xb5\xf71\x9eJ\x1e\x16#\x8f\x1dR!\x8fr\xa3M\x08\x9a3\xb4\xdc\xe4r|\xe6\xe2\x9c\xf3\xccPy\xa4\x9c\x8c\xf9\xe9\xc6\xf0\x142\xb3v\x80g\xb9\xeb\x14\x99\xa52\x8c\xa2\xe3Sj\xd2\xef\xf7w\xfb\xfd\xbe\xc3r\xf7\x8a;\x91\x13/\x9c\xf3K\x11R\x8e-\xbe\xf6\x02\x7f\n\x93hJ`E'c2\xab\xe4w\xd4\x04\x9e\xb0H\x9dp\x80\xb1~0B,\x8b\xe4\xd9\x01\xdb&\xb0=b\xe5\x0e<}\n\xfd\x1e\xca\x14\x7f\x84~o\xb0\x0b\x1d\x16\xffS\x97|\xcc\xb4'C\x9eSP\xcd\x9c\xbb\xe1\x8ek\xc22CT -\xa52`D\xec]\xb5\xc7\x03\x16;\xa3\x1b{W\\\x10\x8d\num\x1dnP\xcc\xf1\x18\x8e\x84\xf0\x14\xbc\xc7\x0edl]x\x08Z2\xf6:\x9d3\x07\xe3D\xdc\x87\x9eF\x8a\xb0\x8e\xa2,L\x0b\xe7\xac\x90\xcc\xbd\xd4_\x13U|\xe0\xc1\xf8\"x\xaa\x1ar\xf1\xc7\x8e\xe0\xe9\xd3\xa7#\xe8;\xdc\x9b\xb53B\xc3#zb2\x07\xd7\x90\xbdz\xac\xac\xd3\xef\xa7\x84\xdb\x948\x17 \xda\x9a6aQ\xb3n\x1b\x16\xb5\x9a6\xa2\x8eD\x97\xfa\xd0\xad\x00\xe2\x88o\xe7\x84r\x93\x1d\xea\xe6\xe1DM\x99/\xe2[\x10\xd6\x18\x97\xad \xac!\x15\x92(\xec\x84E\x0b%\xac\xf1g\x11\x07\x93dBW\xc5\x0b'\x8b(\xdeH2\xa9\xe5\x06\xf9b`\xd4z+\xf4\x96\xc4\xaaK\xec\xf9\xd9\xc3\xbf\xf0\xe7\x1b\x8d\xbd\xcd\xd0Y\x9b\x16\xfe\xf7\x05G\x1e\xf8\xe1\xe5\xdd\x8f\x9d\xb7\xfa\xc5G\x1f\x05\xd3\xbb\x1f\xfc\xef0\xf0\x99\xff\x91\xdc\xfd\xc8\xd3\xf4\xf7\x18z\x14\xa6\x93(\xf8\x12\xbb\x956MG/\x9a\xff\x82;\x96v\x95\xf8\xbf\x90/7 \xde\xfa\x17\x9c\x83\x9fz\x81?I6\x9aB\x9b\x19\xf8\xbf\x03\x16mLvZ\xc1\x1e\xc9\xfd\"&\xb3/\x0b\xf8d\xe9\x05\xc1F\xa3o3x\xd1\xea\x97\x06=}}\xb9\x19\xe2\xb7\x1a\xbeh\xf6\x8b\x8f?\xbb\xb8\xfb\xc1g\xbf\x07\xd5O\xb2\xd5\x17\x18\xf9\xea\x8eF\x1e\xda\xfb;\x8em-\xbdt\xb2\xb0\\\xe8\xd7\xd7\x96\xc62\xce\xebi\x15\x9dz\x88\x88GH\x02i\xddE\xa2/+\x1aP\xcf\x90\xe7_\x0b\xc7\xc4\x9c\xdaB2\x9b\xf7\xe1@\xd8\xd81\xcf\xa8!\x9a\xb7q}n\xe8\x8c\xc9\x99P\xd8\xc7\x95X\x1f\x10n\x9a\xd5\x9f\x03\x93\xeb\x14-\x17\x06\xb7\x00g\xecV\xdd.\xa0\x15D\xa3&\x88f%\x88\xc62D\xe3\x96\x10\x95\x04\x88\x18C\x95\xf9\x08T\xf6\x86\x832rX\xe8\xa5;\x03hB\xbc\xf8\xdf\xd0\xf3\xce\xa0\xb9\n\xfcT\x8b\x9c\x15\xcbI3\x98\xc4EFh\xf7wUc=\x10z\x8f\xeakv\xb9\x867eU\x8d\x885A\xe3\x14\xcb\xbb\xb8\x98X\x92\x89mYt\x8e\x1a\xa4is\x1d\x02\x92%\x9a\xd0\x01\xe8\x03\x01@\xd9\xd7f$\\\x8bx\x12\x9d\xdc\xceMM\x86\"\x7f\xbb\xe5\xcb\xa9\xd3\x8a\xa8x8:\xfdgkf\xc2\x9f\xb80\xc1p\xd3\x01\x0b\x8b_\xe7u\xbe`\xa1;\xfdy\x18\xc5\xe4\xc8\xc3`}\x96o\xc1\x90\x1ey\xd0\xa1e\xcb,H\xfd\xc0\x0f\xb1hY*\xcaB\x1f\xaf\xda\x0f\xc0\xcaJ\x05I\xeaO.\xaf\xe9\xfbk\xfe\xde<\x84i\xbd\xd3\xfb\xba\xbc\x9a\xb4\xb3\xdd\xc1\xa3\xddG\xfb\x0f\x06\x8f\xf6\xd0\x8e\xff\xe9\xd3\xa7u\x0d`4\xd9b\xbf\xa7\xdd\x04\x83\x9c\xbb\xb0\x80\x0eXs\x93\x85\x00\xaa\xfaX\xf0\xaa\xb8\xdc\x02\xbb\xcb\xbc\xe6\xed\xd0F\xfe`\x1fl\xfd\xf0C\xe2X.,t\xd7\xd0\xf9\x83\x0e\xec\xd7\x0c\x17y\xc0\xce-\xdb\x9e`(1\xd4*C\x07\x92q\xef,\xc7\xf0\xa70E\xad\xe1\x8aG3\xe1*\xa4\xa9+>p\x1c\x17\xb6\xd0h\xbf\xa4\xe0\xc2\xc4\x1f\xbd\xb3\xfc\xe2-v\xebY\x9f\xd2\x83S\x0f0\xd0\x00\x04\xf0\xa4\xaa\xe4\xde\x86\xc1c\x08:\x1dG^\x99B\xa3\x16\xa0\x15\xaf\x8d?FZ\xe5w\xe9\xb9q\xdc\xea\xe098\x9e\x141\x15\xf1\xf2\x9f9\x00\xad\xe8\x07\x0c\x12}\x87g\x89\x90\xc0\xc6b\xc5O\\X\xe5\xad\x8e`\xed8\x8f\x1d\xb8\xee\x06^\x92\xbe\xc4\xb6\xf1>\x83\xf7s\xef\x9e\\\xa4\xc6\xf4\x16\x0f\xdf\x8cSv%S\x84\xf5\xde\x9a\xb1\x06(\xc9\xc4,<\x9f>\x01_1\x96\x93G]>:\xe8bp\xb0\x86\x03X\xf1\xb2\x9e\x0bk\xfc\xa42\x02\xc5,\x99\xb9*X=A\x1a\x85\n\xb3\xe7H\x10\xb3[Q\xb6\xf2\x99\xa9\x92+8\x80\xf1\x19\x0c\x05\x0d\xcau\xb1\xaa\x14\xa8\xd7iK,\x82\x81\xe5\xba\x05Su+>@b\xaa\xc2\x82\xa9\x8a+LU\xa8c\xaa\xe2M\xd9\x80z\xe5|f\x87\xf6\xe0a_U3\xfb\xbchg0P\x8b\"^\xb4\xd7\x7fHIL^&\xc6\x80A\xf1\xf5\\\x1a.f\xda=?'\xc9\xabh\x9a\x05\x18G\x1e\x86\x9a\xa5\x98\x92\x99\x97\x05\xe9P\xbd\x9f\xff\xa7\xea/q\xd2\x8e\xfd.\xff\xca\x85\xa8\xf8i\xa46|L\xd5\xbe'\xd1r\x15\x85\x94\x80\xe8F\x06\x98{B\xf8.}\xe3]GYJ\x17\x8fw\xd8\xb4Y\x8a H\xa8\"_Ny\xb7_S}\x8eW\xe2\x82U@\xbcr\x0b\xc2\x03\xc7\xcb\xe1\xea\x9d*\x9aLl\xca\xf9=\xd4\xa1 \x16\xed\xf5th\xc2\x8a*\xc8\x95\xe5E;j\x91\x97\x17\xed\xabEI^\xf4@>\xda\xf0\xd5\xfe\x9e\x1e\x15'\xbf?*\xcej/\x18\xf3\x91\x91:\xc1\x9f\xd2\xde\x1c\x9b\x1dN\xe8\x88\xe3bA\xa6\x16\xd8\xa4{~\x8e\xce\xe7\xe7\xe7\xc8&\xf4\xdc\x02\x1f\x1d\x9b8\x0e?\xadX\xf5\xfcxTE\x0c\x1d\x98h[\x9e\xd4\x96\x0b)\x1fFTz;\xae\xce\xe5\x92\\\x0f\xc1\x8aI8%\xb1\xe6\xa6\x94\xe3]#3\xb0\x96\xf3c\xac\xe2he\x88?\x03\"UFwN\xd2#\xb1\x85\xcduYd\xf0dE&,!P\x14\xd74\x1c\xb3\xd0\x1fq\xdc\xa2.\xdd\x13\xc4\xb6\x8e\xa20\xf5\xfc\x90T\x1cn\xe4'buO\xa2\xab\xbaZ\x99h1\xa8\xab\xe5\xb1Z\x18\xb57\xb10\x9c\xa9\xb9\xf2\x84U~\x17\xad.\xbc\xb8\xa9\xf2\x8cU~\xe6%\x9c\xde5}\x10\xb0\x0f\xa2\x90r\xeb\x1f\xbc\xc0\x9fzi\x14?\xf3\xa6s\xd2\xf4)&t\xe8\x06\x917\xf5\xc3\xf9i\xea\xa5Y\xa2F\xb2\x97\x9f\x05z/S~\x89\xdd\x9f7\xb0\xf7\x94GZP\x04\xb1\xad%I\x12oN\x90+\xb24J\x01(6A\"P\x9d;T\xf2\xdcQ\xb6o\xf2\x94\xa4\xcf$\xf0\x92\xe4\xb5\xb7$C\xb0\x92+o>'\xf1v\xe6[\xda\xfa7.L\xe0\xc0\xd8\xcf\xc4\xc5$l\x0eO\xc6\xe6\x82\xc5\xe1c!_\xb4b|\xaa\xfe[\xcc\xed\xddv\x9c~8\x8b\x8c#\xbc\x93\x1e\xf8\xc0\xb7'\xf9\xee\xf8=\xba3t\xe2`\xf8\xb7\x99\xe7\x07d\xfa\xaf\x12\x94\x8b\xdd\xd6\xbd\xa5~\x1a\x10c\x0f\xd6\x0b\x04\"\xa4\x11\xd0a\xc1\xe1\xdb\x97\x80l\x88Oi{\xd7r\xcc\x83\xf08rKkq\x84\xae\x95_dE\xcc\xe4\x013A\x9b\x18>\xf1,\xbd\x8f\xdf\xfa\xd3t1\x04\xeb\xe1\xc3\xde\xeacM{\xacz<\xf7\xc3o\xc8,\x1d\x82\xe5ei]\xffE\xfd\x13\x7f\xbeh\xf9AJ>\xa6\x87\x81?\x0f\x87`M\xd0\xdf_\xbfDP9\xdf\xf3\xb7\xff\n\xb01&\xcb(%\x85\xc7n#NZ+\xcb\xe5\xa4v\x8a\x88\xb9\xb5B\xe5_\x92MD,\x8c\x06\xcc\x9cq\xac6\xf7\x11\x89\x1eL\x15\xb2\xa6\nA\xbes\xaa:\x0dE\xea8+\x85H\xba\xb1\x8b&sNIb\xa9\x89(m\x1bl\x8a\x8a\x90;\x15\x8f\xa5\x81\xd3\xd5\xe6Am\xd3\xa2d\xdc\xa7\xcf\xff\xd6\xdf\x91\xad\x96\xa9p\xf2\xc8\xb1\xadrGV\xb3\xf4g\xe6\xd4\xa5J\xbe\x92\x86\x14\xe06\x17o\x83\x87{\x1a\xc1J\x02\x93^\x1ely\x01\x12\xabb\x9f\xa8^\x8c\xb3\xcd0\x8ba\xf5U\xeb\xce\xc2\xabk\x8b\na\x94\\\xb3qWvmy$C\\\x1d\xa7;\xdb\x10b2\x10*\xed3\x89\x8c\x02U\xbd\x8d($\xbaas\x0e\xb6\xca\"=b\x0ey\x0f\xf7\xaa\xfew\xbd}\xa7;\x93\xfd\xe8\xdb\xb4\xd8r\x12\xaa\x01\xeb\xe7Mb\xf0\x88\xbb!>\xe2n\x86|V\x83G\x0ft\x9b\xf4\xf4zy\x11\x05m\x9an\xb2\xf34\xd8\xe1\xaa;\x98\xdby\x1a\xbc\xad\x0d\xce\xd6\x03\xb5q>\xfeG}\xa7\xfb\xf5\xf1\xf7\xe5\xb2 /S>\xe1\xa9\xe5\xd4\x1eXj\xb9G\xeaxXn\xb9=\xf55\xcf-\xa7\xbc\x9d\xe6HR~\xbf\xe6\xefU4\xbd\xe6#T=\xe4\xe6\xfc\xbd:F\x9eV\xae\x82\xed\xec\xb5\x1a\xfe\x92\xa5\x94\x1b\xe83\xcaU\xb0\xed#\x9b\xa8\x1a\xfb\xee\x94\x81E\x95\xd6\x8e\xf9\x08\xd5\xea\x87|U\xd5N\xdf\xb0\xf7j\xf5\x9f\xf0u\xc5\x0d\xf5\x12Fp\xa8\xe6\x90{ #x\xa3\xbe|\x85i\xe1\x94\x97\xefP\x1ed\x18].9\xc2\x92\xbf\x9c\xbey]~\xff\x16FpD\x8f\xf2\xa3n\x82\xaaW\x7fv]\xaeqB\x05G\xdb:_\xf8\xd3) U\x11\xfc5+M\xa3\xb7\xb1\xbf\xf4\x99\xadv\xb9\xc67\xe8\x00\xa6\xcd\xb9_\xae\xf8\x9c\x92{\xdbJp\xf4\xdb1\x99\xfbI\x1a_\xab\xcd\xfd\"\xd7\xaa\xa4\xb9|\xc1J\xa3\xd5\xb6\xa1\xc2{M\x12\xf3r\x8dg\xa6\xf8\x01\xef\xca\xf5~F\x88\xfe\x955V.\xfa\x1eF\xb0\xf53F\x0e\xffY\xca\x08\xa0\xfc\xdd\x9d\xf9\xe1\xf4h\xe1\x07\xd3\xf2\xd7\xdf\x02\x8f\xf18\xa9w\x8d\xe3G\xdf\x03\xd8\x1a\xc1\xa9\xfd\xd2\xfe\xfb\x0d7\x0f\xd33\x91\xed\xe2\xb1@\xd1\xf0K\xd9\xe4\xac^0\xe0\xda\xac\x07\xc6J7N\xd7\xd3\x16V\xd9\xf2\x1bG\xad{\xe3\xc8\xd1\x0f\x0c\x8c\x00H\xa4\xf8\xd2~\xaf\xbf\x9dE\xd7\xd5) HJ\xe0\xfd\x98\x9c\xb9t\x92\xbc=\x1e8,\xc5;\x8a\xf7\xf4\xe7Kl\xa6\x12 \xf9\x06\x86\xf0\xb2\xbcd\x1fj\xb5\x9e \xd9\xd0\xff\xc2|\x0dO\xedw\x05\"\x98\x0d\xd8 K\xa5\x9bV\"|\x96\xbb\xff\x1aF\xf0\x8c\x8e\x98o\x8b\x12\xd6v\xc5\x91]\x02b\x0dBi\x1aI+\x00h\xd5R)\n\xf3\xbb\xba\x19|\xd5\x82\xd5+5<\x12\x8b\xf4\x95\xfd\"_\xc0%\x8b\xf2\x0f#\xb8\xe2\x19\x8d\xe8;Z\xe2\xdb\xbf\xe0\x9d\xdb\x01\xc6c\xc8 \x10f\xe4\xa3\xfd\x9d\xb0\xbc\x93\xe3\x93\xb31a\xb7\xa6\xe2\xf7\x88\xe7\xa8\xc0E\x0bM\x1b\xa1hr\x08\x1f\xed\x1e&\xb6\xd0a6\x0c\x8b\x0e?}b\xd8w\xe2\xc2G\xbb\x8fyv)\x7fR\xf4K\x87\xffm\x0e\x0d\xfa\xed\xcb*_\x0bU`\xfe\xa1\xcd]\xe3R\xeb8\x91;\x93\x87\xcca\xfc\x9a'\x82#th>K}\xc2\xa21\x8a|\xdf\x11<\x05\xff\xb1\x03_\xd9)\x83R<\xf61n\x00\x19\x87\xba\x10\x96b\x05\xeb&\xf0\xe7\xd6\xdb\xe9\x9b\xd2](.|\xcaRY\x19{\xde\xc2\xda\x05\x02!j\xb0\xbc\xa3[>E\xa6\x94\x19\x04\xd8[6#\xd9\x85\x0b'\xff\xf3\x17\xf1[\x94p\xecY\xf8 ]\xbc\xf4\x0c\x0b\xd5k\xd9\xf2\x14\xff\xd2f\x8d\xfc\x19s\xdc\xbd\xd0\xe0\xb5\xa0S\xf9\x90\x08\x1f\xd2\x0b\x16bY\x8f\xa7\xc2n\xe6\xd2\xae\xb1_\x11\x80\n\xab\x8dW\xb6\xca\xa7O\xca\x8e\xe2x[\x8d$sS\x07\x8e\xbf5\xae\xb8\x1a\xee\xe2\x95}\xc1\x9c\xa0c\x1e\xc1 \xe2\x11\x0c\xba\xa5\xdc\x8fl\xf4\x94\xd9b) qe(e;\xc9\x7f%,T#\x0bDa\xc6\x9b\xb8n\xfc\xdfm<~N\xc2\xd8\xf8_a\xe0\xa1\x170\x04>\xa9\x88OJ\x84\xee(&\x95=v\xc4\x9a\xe0f\xcb\xc4\xacB\x8e\xc1\xef\xc5jElJ\xbf\x8cI\xcd>\x8c\xca\xb3*\xea=\xc3\xa5\xf5l\xfb]]\x14,\xc4P\xba\x9ddB_\x0d\x99n1\x96\xb4\x88\x0f\"\xe5(\xaeDN\x17W^+\x9d\xcfX\xaf\xe43\xd6\x93\xbc:\xdd\xca\x14\x89\x94\xd3\x01\xc9\x19\xa9\xac4\xca=\x04\x9b\xf4E)K\xc4\xffOr\xd3\x87\x98\xb4\xe8/.\x15Q`\x04_a\xc4\xa1\xbd]\x07\xff:\xc6\xff\xff\x8d\xbe\xdb\xe7\xaf\xfe\x8c\x15z\x0f\xd9_\xdf\xf1\xf4\x97[\xa1\xfd\xf0!\x02\xd5\xa3\xb3\xb7t\xe2\x82\xe5\xd2\x8f\x91\xbcL\xbb\xf5\x17\xcd|\xbc\x1f\xecEIuE\xc7\x9b\xd9\x19&B\xca0\x11R\xc6T:\xcfTh3\x84\x1dJ\\\x8bl\x17\x90o\xe6\xbfRaa\xe1%/9\xfa\xbb~r\x14\x85\x13/=]\xc5\xc4\x9b\xa2\x90#\xf8/\x17\xcd\xce]n\n\xe623_\x97\x87rt\xd1x\xc8\x95\xe4(W\xac\xcb;o\xee\xca\x99\xfd\xb9\x9d\x91\xe5Z\xf4\x18H\x19\x85\xf8k\xb1E\xd2\xf4\xb1\x03\x0b\xfb\xaf\xe34-'\xbd-HP\x8a\xd9J\x16\xdd$\x8dbB\xa95o\x85\xa4E3!mfm\x93t\x1c*\xedP\x08\x9e\x96`\xc7\xf7w5\xa0Q\x14\xb7d\x15}\xfb9=\xd3:#4^<\x80\xe7tO\x0d\xd9?\xa3j\xea]\x85\xfc^\x92\xeb\x17\xcd]\xa19\xe7\xd7h\xceY\x9b\xd3\xc1\x03\xc6\x01W(\x13\x94\xc3\xed\xf8!<\xd7\xdb\xd3\xd1\x9e\x9e#\x177\x92\xe3\xbb\xd72\xf1YBNI\x9a\x92\xb8AJ\xfb^\x17I\xb2\xd2\x92\xbf\\\x05M\xf6\x05\xdf\x97\xb3\xd7\x01\x94\xf5\xba\xaen\xa1\x0d:O\xa6\x9ao\x91\xca\xaej\xe2F\x99\xf0S\x1b\x93\x96\xfd\xc1>e\x9cN\xedb\xab\xfa\xd5\xafj\x8a}\x92\x0c\xe1\x0f\xe5\ns\x92\xbe\xb9\n\xc5\xf7\xcfI2\x89\xfdUJ\xd1\xe7/u\x15_{K\xda\xd8\xdf\xea\xea\xb0m\x90\x0c\xe1\xbb\x12\x1cQ\xc1R\x06\xa6\xbd\x85\x07l\x8d\x88/\x8e\xc1wjxL!\xa6\x8d\xc3,\x08\xce0\xfe\xcd[[p\x9d\xd6\xdfo\xf8\x9b*\xec\xbd\x8a\x11\x8f\xf2 [\\\x85b:.X\x7f9}\xf3Z\xe3@\xce\xf5EM\xfb\xae\xc4\xfap\x86-=\xe3Y\xe4\x1f\xebb7P\x81\x82sd\xc5a\xef\xebSx\xf3<\xaf\x9c\x1d\xea\x9f\xb9`\x9f\xdb\x95\x94?\x9c\xc1\xffZ6\xe6\x9e\xf3j6i\xc3\x8c\x8b\xbe\xb4\xba!\x16\x1a\x08\xf9\xcc\x8au\xa6\xe3\xd2~\x89c \x03\xc0\x91\x84\x8e\x9dN\xc3\x85\xb7\xdc`\xe9\xa8\xaaz(\xa1\x95\xa4B\x18\xbfFV<\xb4\x07\xfb\x8e\xacZp\xe1u\xa9\x1eK\xc2\xf2f\x86\xd9\xe4\xde\x15\x84\x1b\xff~\xe5\xa5\x0b\x17,\xfa\x0f\xb7S\x81\xc0\xe6J\xc3\x1c\x07\xb6z\xad4\xff\xd2\x0d\xd6\x9ec[K\x92z\xba\xd0\xbb\x1a\xe5m\xa4\xd7\x9a\x8b`\xa4\x8e\xaa\xf3\xf4\xaav\xebI\xa1\xe4\xf3\x93\xe3\x8f) \x13\x9f\xca&\x9f>\xd5\x13D!\xf8\xd4R\xd7 \xa5\x9a\xa8]o\xa5\x9eK\xec\\\xddH\xd6$L\xf9p\xa20\xb1\xa9\xc0\xaf\xec\xc7rW\xf5<\x0e\xe0Q\x9c\xa2\xf7\x91I\xdaC\xb5\x9c\xbe\x90>\xfe\x10\xac7\x16t\xa0\xd3\xf1\xaa\xbc\xa4x\xae\x86j\xb0Z\xf1\xe8\xb4wu\xb0\x0b\x94\x1cR\xd5\x91}}\xfc\xbd68\xf9\xeb\xe3\xe3\xe7C\xd8\xeaWKf^\x92~M\xae[\x9c=\xa0u\xe9\xd0\xa9\xbb\xb85$s$e\x86Fr\x99u\x8a\xde\x14o\xd1\xcd\xc2\x90C\x81e\x01\xc0\xe51J\xe3y\xbd\xa44\xa0\x17\x06{\xac\xbcz\xe1\xb9b\x1d\xd7\xd4\x9d\xa9\\\x93x\xf4\x8b)x\xfcq|\xd6\xad\xe6\xce\xd7\x84p\x9b\x93\xf4[\xe2]n\x02\xf9[\x01dK\x1f\xe3\xa5\xa8M\x8c\x11\xab\xe5\xe73\xc0q\xd5\x06\x1cQ\xf8\"&\xe4\x97\xc6d\x82P4>\xa1\xc7F\xd0\xa5\xc8\x8d\xe6\x146?\xa68\x98\xe8\xef\x19rD\xed\x0c\xab[\xd3\xe4\xca\xbd\x93\x08\x19\xa4'\xc6\xfb\xa6\xe4G\xe6\x89\n\x05]\xac\xcd\xd4\x16\xb2\xc0\xba\xe5\xb5\xc2\x83\xbc\xbaB9\xf7\x90\xb9\xfc2\x94\x02\x84\xf6\x1eug,\xa1J\xef1x\x05\xf30y\xec@\x92g.\xa7\xe7\x867\x9e\xa0\x96\x04\xe5{\xe4*2=O%\x19\x89l\x06\xd0\x87\xfb\x06\x08\xb1\x08\xef~\xc2RY\xc9\x07\x90If\xb5\xb0*\x92\x9c\xd8\xbe}\xa6\xab\xca\xed'_\xe2\xbd\xea \x1a\xb1\x1b:!oV\xcf]+b\\\xbfD\x06\xaf\xfcp\x1a]Q\x88\x16\xbf\ns\x17\x95m\x86\x83\x9aB\x9b\xb5@\x05\x80\xb1\xce+\xa0\x9d\xa8\x8f\x81v\xad1\x1b)|\x8bM\x9e\xe1\x88\xf3Di\x8d\x17 \xe6\xbc7\xb9\x94\xaa!!\xcd\xf9\xe3\xc5\x10\xb9kQ\xa3\xbd\x92\xcdS8\x97\xedn\xf4\x08\xe0\xc0\xdf\x1b-\"\xfa\xbd\x07\x8emy\xc9u8y\xb9\x91\xfd\x86\xf8\x94%GA\x1dL\xab\xef\xda\xd9}<\xba[\xbb\x8f\x9d^\xaf\xc6\x08+\xf9\x0c#\xac\xaa1\x90Y\x12.\xf73\xc4q\xf51\xa7U1\x9fV0\x94\xb6\xb2J\x95}\xbd5D\xd4F\x8c\xa1T\xd6G\x12\xba\x15S\xf9\xe7\xde=4\xa3+\x07v.\x14#\x84eCe\x11\xd9\x12\x92\x82\x97@.Ml\xa9\xe1\x18\xf44\xb0\x02\xa0!h\x17\x05e1+w\xe6\xb0\xc0\x0f\xe1\xef7\xd5\xbb_m\xca\x1b\xf3\xde\xb5\xf9\"R\xd1\xe8\x05o I\x82\xcb\x0d6\xba3\xbbb\x12\x00\xd28XF2\x188\x0e\x1d\xc0\xf8\x8c\xdf\xc5(Yf\x91l\xdf\x86:\x10}f\x8a*W\xc2\xc9\x88\x0c\x0d\xa3V[(\x95Y%\x96\x0f5\x95\x1ceF\x10\xc2\x90\xe5\xc0 \xdb\xf0\x17h]\xb0\xd5wL\xfa\xf6\xc9\x82L.\x87\xd2uB\xabM\xdb\x8aN\xecT\"\xe2}.\x9d\xd8\xfdlKD\xc3!\x14s\x1bUVg\xb3\x81\xdd\x8e\xdc\x08\xc5\x1bZ*\x15\x1d\xb6\xa20M\xf6l\xbb\x06\xdb\xd3==\x97\xb8S\xb1\xf2b2\xfbN_\xb5\xf2bl\xdc\x8e\xfa:\xe1\xd5u\xe9\x89\xe9{\xb5\xf9\x19\x7f\xaf\x0e'\xe0\xcd\xab8\xba\xc2Li%+\xe2r\x85\x85T\xe1\x857I\xa3X\xb1\x85\x9a\xb2\nA\x14\xea\x1bXW\xe3@\\7\xca\xf0mn\xc4\xe7Za\x19\x8d\x87b\x12\x9aD\xfc\xa5\xb7\x1aB\xd4]z+\xbdp?\x8b\xe2co\xb2\xa0u\xf8O}\xbdI\x94\x85):\x1e\xd3\x1f\xfa:i\x84\x04\x90\xd6\xe2?\xf5\xf5\xa20\xb8\x1e\x82&\xe7Y\xb5zn\x9c=\x04\xbf[\xe3\xd3\xf66\x8bI\xa9n\xe9E\xb5~ \x03\x86\xa0\x01\x8e\xbc\xc2C\x98V+\xf8 \xfau\xe5U\xbcn\xf9\x8df\x90q\xb4\xa2\xc7j2\x04\x8d\xf7\x1c\x1b\xd2Q\xe0%\xc9\x10f\xa6r\x8e\x93C\xd0\xac\x13\xab\xf1\xca\xff\xe8\x87C\xd0\xc0\xfe\xf9\x9bWC\xc8\xaa\xef\xd7$N\xfc(\x1c\xc2\xa4Zv~\x9e\xe05\xd6\x10\xd6e\xe4\xd4S\xc8V\xa99\xea\x89\x8e\xacQ3\xf4\x12\x7f~/\x94V\xe9y\xaa\nM\xe2\x02\xb0\x81\xb2\xf5T\x0e\x96\xa5\x13M\xaf\xa2C\xae\xb6~\x1bE\x81\x9a\x8e\x14g\xd1\x9dEY\\W\x8bR\xbd\xfb?\xdc\xef\xdc\x9f\xeb\\{gFA\xc8\xb6,\xe8@\xea\x94\x82\xbd\xff\xe1\xde}K>\x8f\xaa\x0d\x06\xdas\x0d/|i\x1df\x85\x86\x7fN\xa20e\xb9\xb9H\xfe&c7\x88\xb5=\xact\x0b\x05\xd2\xb2\xa4\xd8\x93f\xb3a\x19\xefV\x91\xdb\x99l\xe7c\xc3)\x1b\x88\x9c?]7\x8e\x85\x18\x87\x86\x93\xc4\xe9\xc4$a\xde\x1fb\xc6\x97\xe4\xfamLf\xfeGi\xce\x1c(a\x05(\xf1F@\x996\x03\x85\x0d\xa7\n\x96\x0cK\xf3\xb1U+x50Md\x98j\xa8 ;\xe8(l\x13\x05\xb6\xe5\x05(\xe97\xec \x95\xb1\xd7\x14\xe3b\x84o\xd4M\x17^z\x82\x88\x99\x08d\x17\x8e\x9c\xb05b\n0\xdbW\xa8'm\x87\xbe\x9f\xa0\x9a\x08\x89\xf1a8=a\xf8\xfc5\xb9\xa6\x1dd\xd0\x01{kB\xe7\xcf,yP\xb9C\xff\xc2\xe4\xf2\xf8\xeb\x00,\x0b\x860\xb3\xf1O\x87\x8a2\xf7Qg\x1b\xa2\xe1\x10S\x05M\x9cztYK\xe8\xe2V#g\xacy\xd4\x0c\xd5\x89V\xcc\x90\xdd\x0c\xa1hf\x87b\x08U\x83\x17\xbaV\xe8\x9a\x8b\xa4`j\x13\x8c\x8c\x81\x1d\x96+\xa3\xc6\x7f\xea\x82\xe7\xb8\xb0\xe8\xc6$ ^Bl\xaf~\x0e\xd7&,\xe34\x83\x0eVj@\xfc\n\xa4\x8b\xa3)\x11\x06;u\xf6@\xa5\xad\x81\xee[\xca\xee(\xbd\xacl\x10\xba(\xdetJa\xe0\x87\xf3w\x91\x1d\x88\x89\xdej \xf9F\x96z\x95\xf7\xb2\xf4\xfa\x0e\xc7\xbcp!Q\x04\x8c*\xfb\x96\xb3^u\xa7\x98xP3J\xf1\xa9dM\xa0\xb9x\x10D#(c\x92.\xc9:\xe2\xd1\nS\x17@\x90\xe3\x91z\xdfX\xa6\x0c\xc8O~\x91\x01\xeb\"p S\x01\x9b]q\xb1U\x10\xa6\xda\x0d\xc3|\x19\xa6\xd1\xb7~\xba\xf8Z\xac\xf6\xcb0%q\xe8\x05CX+\xc7,\xe3m\x1b\xf5&B\x87G+\\s\xd7\xc3\xbaA\xe4\xfcp=\xf3/\xf4\xe4M\x00 \x02\x00z\x92Z1\x10/\xf0\xf3\x8b\xf1j\xa1\xbd\xaf\xd31\xdb\xa1M%\xaf\x86y\x0b\xc3\xc1\xae\xd0\xa0Pl\xad (\x07\x12\xac\xaa\xdf\xad\xa2\x95)\xf3\xb5\xc0=\xdc\xbd<\x12|\x15^P\xa7p \xc9\x15~_1B\xaa\xd5\xbfi\x95T\xb2\xc2\x08\x0d\x0f?}\x82\xd8\xb6\x06{h\xcb%\xd16\xdbq5\xf3\xe4w\x1cOx8\x90(\nN\xfd_\x880>V`B\x0f\xb7z\xb3\xa9\x0c\x934\x97^yZAS\xa6o-\xf6\nH\x96\xc6\x86\xebQ\x01\xda\xd2\x98\xb9\xd1kXP/\xb4\xeb\xf8\xf4 2\xfa6\x9f/3:\xce\xff\x1c\xb1\x8cp\xa1\xa0b0\xa2g\xa7\xc6\x02\xb9\xca\xe7P\xce\xa2\xc4\x83\x0fU\x80\xd0\xa7\xc2\xcf\xb7\x84\xc1m\x90\x1cd\xd8m\x82\xe8\xa0Cv\x11\xa8P\x07\x0e\xd0\xe2<\xe8\xf0\xbeb\x92\x05zp\xa6\x8b\x98T\x00\xda\xe6\xc0\x80\xcf\x84V|'\xd0\x8a\x19\xb4tG\x8cx\xda\x03\xac\xe2\xa5\x01z\x98U\xe5\xc0*\xc8\x0c:o\xf8L\xa8\xf9w\x025?\x87\x1a\xe3&\xaa\xb6\x03\xb0)\xe0*\x86O\xd5\x16\x0c\xe7\xdag\xc4\x0fk>\xd7\xfa\x05\x1f\x15?f${\x1f^\xd7\n\xb3\xe5\x05\x89\xe57\x05Ty\x17\xa4\xfb\x87?\xf0\x91\xd1wE\xfe\xf4\x99\xcd8V\xcb\xca\x93\x87y\xd0\x81 \x9dp\x0f\xc5`\xc7\x05\x8d\xc5\n\x9dqM8\xd65\x8a\x9bR\x93CLd\x93\xe8\xa1R\x96\xd0\x89\xc6\x1f\x01d+\x8bkfOq\x0dO\xf2$<\x8f\xe1\xba\xd3q`\n\x9d\x11\xa4\xf6\x8a\x9e\xc9\xe3\xeb3\x17\xd68\x97\x95\x0b\xd7\x0e_\xbd\xea\x0808\xa6\x99C\x98\xb3,\xa5\x06rC\x87?o\"bK\x17\xdd\xc0\xe7\x9c\xbb\xab\xa1\\\xd8\x1c\xbb\xe8\xec\x920\x8d}\x92\xe8\x81!\x9e\x1c(\x17\x0c([\xf6\x12Fp\x8e\xa9\xe9m\xc7\xe9N\xa3\x90<.\x01f\xc9\x0c,%\xd8\\t:f\xe8\x88\x87B\xa9y$\xc6\x01\x98\x01$\x1e:\x89\xabb|\xe6\x91\x88\x07\x0d:lifWhZ\xbbF\x03fN.\xae\xc6\xbd3\x87\"\x9e\x98kO\xcc\xb4\x1e\xac\x06[B\x86+\xb8\x91K[\xac \x01>\x1a\x92\x91\xc9\xcfi\x11+\xba\x0eCb\xdb\xda\xe9[naG\xc2n\xdd\xce\xd8HN\xe1@\xec~\xb8\xf2\xd3\x05\\\x92\xeb\x04\xfenAG\xdcg\xd3\x176qx\x9a[\x17P\xd9d\xddX0\x84S\x17>\xb65?3J\"\xd3R\xc1\x0d\xa5\xb8\x96\xa5\xf2\x1a\xadn\x1b\xeb\x8f@\xad\x8d3\xf7\xe1\xbaw\x8f\xff\xca\x1d\x8b\xabg\xa5\xf5/\xff\x92\x07\n\xd1\x9f\xd3f9)\x97\xf2\x80\xc5\xcdEg\xc3\x18\xcd\x9b\xd3\xb1\xafZ\x80\x1b-\xb2\x89\xc6\xdc\xfa\x0e S\x1e+\xdb\x08me|=\x1a[#k\x08\xd6\xa8g\xc0`k\x88\xc5\x83j\xb8\xa7\x1b\xa3\xc6\xc0\xfa\x03\xc5\xc9\xcaE\xc0\xfd\xf1hxv\x7f\xde$\x9aK\x0d\x91qzV\xed\xb7^\xa6\x0c\xef\x06(=\x9c\xb6 (\xa3\x01-\x1en\x02\x14\x06\x0e\xdb\xea\xb2\xcd\x9c\x8e{\xe8\xe8Ma\xc5\xfe\xee\x9f\xa1\x8dD\x92]0.\xc0\x1e\xd0#Z~\xd1w\x1c \x9a\xf6\xa8\xf7i4p\xee\x1e\xa0\x05\xbe\xea\xf7\xce\xdd\xdc\x80\x0d\x9c\xba\x9bn_\xaf\x07\x18R\x12Y\xb1\xe4\xc7\xa2\x8b\x8b\x98\x95^\\h\x83~z\xd3iL\x92\x84\xd5a\xbf\xb5\xd5b\xc2{\x89\x89\xbe\xa38\xf5'\x01\xe1u\xf0\xb7\xb6Z\xe2Oy%\xfaK[%\x9b\xfa\x11\xabB\x7f\xe9\xaa\\`\xf1\x85\xb6\xc8KX\xfb\xf4\x87\xb6\xc2\xd4g\xe5S__\x1c\xf1b}\xcf\xfe\x9c\x15\xfbsmq\x10M.\x7f\xce\xa2\x94\x8f!\xffS[9\x9a^\xb3j\xd1\xb4\x12P\x05+\xb0\xa5\xd3/\xdcE\x96\xa6Q\xc8*\xe0O]\xa5\x89\x17\xae=\xb6\xb8\xec\xa7\xbe\xd2*\xf5yS\xfc\xb7\xb6\x9a\xcfgE\x7fh+D|i\xe9\x0f}\x85\x80\x97kc\xc6N\xa2`\x1eG\xd9J\xd4\xc1?t\x15\xa7^\xca\x90\x91\xfe0U\x08\xfc$\xcd+\xd1?\xb4\x15\xa7\xac\xcaT[H\xd8p\xa7D;\xdc)I=?Hx\x15\xfc\xad\xad6c\x90\x9d\xce\xb4P\x9d\xfa^\x101\x9cb?\xf5\x95\xd6\xbc\xc6Z[\xcc\xc7\xa9\x1f&\x87\x82v\xfed\x89\x85d\xa9/\xbc S^~A\xb4 \x9a\xf9$\x98\xa2\xe9`l[\xe2\x0f}\xc5\xb9\x8cf\xc5\x9f\x86\xcaYLD\xc5,\xd6\"\xd3,\x8a\xd0+\x93V\xc2\x9f\xfaJ\xf1\x92W\x89\xb5s\\\xf4\xb1x\xd1\xd7\x16\x0eX\xe1@[\xb8\xc3\nw\xb4\x85\xbb\xacpW[\xb8\xc7\n\xf7\xb4\x85\xfb\xacp_[\x88V\x1f\xb4\x98x\xda\xf5\xa0\xef9P\xd8Om\xa5b\x97-\x8c{l\xc1[\xd1\xb7\x90.\x19\xca\xd1\x1f\xba\n\x8c\xc4j \xac?\x8b1\\&-\xc7\x9f\xdaJK\xb6%\xfc\xa5v?\xf8\xe1*c8\x87\xbf\xf4U\x12^A\xbb+//\x18 //\xb4p\xbc$\xd7s\xc2P\x95\xfd\xd4U\n\xbc\x0bN!\xf0\x97\xb6\n\x99\x93\x90\xf5\xc4~j+1h\x05Zp\x05~x\xc9\x8b\xc3K]\x85\xa5\xe7\xb3\x81\xd2\x1f\xfa\n+^\xae]\xe8\xa5\x17_\xf2\xf2X\xdf\x01 3V\x81\x84\x99\xa9\x82\x9frR\"\xfe\xd0W\xe4t[\xe7w\xc8+p\xec\xc5_\xba*\xa1\xc7Ha\xe8iIa\x181\xbfaV\x87\xff\xa1\xab\xc8\x04F\xac\xc6\xc5Z]%\xb6\xbc\xfa\xe3*Z\xa5\xc5F\x12\x7f\x18*\n\xba\x17\x19i^\x94\xa5\x02\xa7\xd9O]%\xd6\x97\xb6\x93\x95\x17{l\x05\xf0\x97\xb6\x8a?I\x05]\xe5\xbf\xb5\xd5D\x15Sq4\xcf9F\xf1\x87\xae\xe2\xcfX\xe3g]Q\xcc&\x12kg\x123(\xc4Z\x08\xc4\xd9\x05\xe3\x99\xe8\x0f]\x056.\xed\x80\x12o\xc9\xfa\xa5?\xb4\x15\n\xd41#NB&\xf9r\xf2\xdf\xfaj\x81\xc0/\xf6S[i\xe9\x05\x0c\xc5X\nN]\x15L\xa3\xc4\xea\xe0Om\xa5\x95\xc7\x07\xb4\xf2\xf4\xa3I\xe3(d$\x95\xfd\xd4W\xba\xe6\x0c<\xfe\xd2V\xc9\x18\xeb\x9ddZ\xe6;\xc9\x96K/\xbe\xe6U\xf0\xb7\xbe\x1a_\x07\xfd~IY\x1c\x95\xd8\xb6R\xe6\xdb\xa2\xa9\x92\xf3\xce\xa9\x89yN\x19\xd9M\xb5$7%\x1f\xd3\\\xa4\x11\x7fh+R\xde\x82\xd5\xa2\xbf\xb4U\x16\xac\\\x9br=\xcd\x8f\xec\xd4tf\xa7>?\x0e\xe9\x0f}\x85T\xc0\x03#L\xeb\xaa0\xaa\x99jIf\x1a{\x93K^\xeeM\xb44\x9e\x11x-u\xcf\x18\x82fZ\xec\\{\xac\xe3\xb5\xa7\xedy\xedO \x13\xa7\xf0\x97\xae\xca\x15\x17r\xae\xf4R\xce\xc4\x8f\x85T\xc9~j+\x05\xfe\xea\xad\xc7\xd7A\xfc\xa1\xab8%3\xc1\xaf\xcf\xb4$\x82\x04\x81\xbf\xe2\x02$\xff\xad\xab\xc6v\x92\x9e5Yzs\xce\xdd,1\x93C\xb5J\xe0\x87\xac\x06\xfda\xaa\xe0\xc5_\xc5\xde\xd4G3f^\xb5x\xa5\xfbh\xe9%\xe2\x1cO\xb4k\xbc\x12\x10Z\x19\xa0\xb3\xf2\xd2\x94\xc4\xa1\xa8C\x7fk\xabE\xc1\xf5\x9c\x13@\xfe\xdbT-\x9f\xa9\xf8CW\x91\xce\xc9\x0bJ\xb3-\xbf\xd2~$\x88kl\"\xadi\xc4\x89L\x1a\xe9\x89\xfd\x9a\xd3\xc3\xb5v\x1d)Q\xc8\xa9\x83\xb6BNtSFuK5\x0c:\"v {\x07:\xa2:\xbbvn3\xdd7\xb9\x07\xfb\xc2\x9e\xecs\xc7\xd1\xdf\xdb\xd8\x01Yx\xe4\xd0\xfe\xe4`\x8cw\xa0\x03\xd6\xd8\x83s\x8f<\xf5\xf6\x97[\x8f\xebcYT\xdckx\xa8\xe7}5V\xb0\xf0\x8b1\xf9\x18\xd7\xda\xa2\x08[\x92\xcfQ\xe9\x03\xb7\x08\xd6\xab\xf5E/3Z\xe3\xc9\x13/\x8c\xc2\xebe\x94%O\x9fj\xb4\xb7\x81Q\xe5\xeb1s\xb9\xb5m\xe1/\xddN\x00\xd4eQ^ym\xe7\xf7\xba\x86zt\xbaX/\x9f\xb7\xa1\"\xbb\xe0\xc5\xaa\xfc\xae\xd7PQ0\xf2\xeb:F\x1e\xf2\xc08X\x91\xdf'\x9b*\xf2 ck\x11\xcf\xd8T\xd1\x0b\xaf\x870\xb5c\xd9\xf6\xef5^`\x9bA\xf9f\xd6\xa4\x82\x17\x8f\xb8\\*\xe2\x99\x14\xe6\xce.DM\xf7\x8b\xca\x15\xccVal\xe0\xc8\xf6\x1d\x0b\xdb\x12n\xdf\xf0\xa3\x05\x1d\x88\xa0\x03\xd6\x8f\x10\xcd\x8a\x94s\xac f\x05\x0b/\x01?\\S\xea\x93{\xcf@\x18\xa5\x98\xc0\x82\x8a\xdd\xfe\x94\x88\xa9vM\xe9C\xc5C\x11\x14\x13I\x8dCC\xb2W\xf1`D\x89\xf2\xa5yV\x1b\xb0B<\xb4\x0b4\xad\xacD\x17\xd0=e\xc8\xbc\xe4\xf3\xa4\xd3\xf71\x16\x99\x02\"\x0c \x8d\xef\x12\xf6.\xc9V\xab\xc0gi>$\xa8\xb9@>\xae\xc8$%S\xf0B\x06\x9d\xaeu\x9b\xebX\xf1\xe4w\xe0<\xd0\xc2\x04\x9e@\x96\x1b\x06L:\x9d\xb6\xa0\x99aj\xc9\x0c\x93\xe2r\xcc\xa2#\x1e\xd3\xb1O\xe8\xaf3\xcb\x05\xaf\x05\xe4\xe8\x02\xcddCJ\xf4T.\x8c.>c\xb2:sx\xf5\xb91\xdc\xe2\xea\xb7\"\x11\x1eb\xf9\xde\xfa\x82;qC$O7@l\xef\xcb#\xb6\xd7\x1a\xb1!\xf1\xc3y@\xe0\x84x\x93\x94s&\x9f\x87\xe5\x9f\xb3\xf0\xa6\xack\x02C\x7fWB\xbce\xd3\xc5/\x99\x19\xb7^c\xe6P\x14zK\x16)K?+\xf5\xf1\x1a\x8d\x9eM\x0f\xc3\xc1\xae\x14\n\x16\xe3\x0d\x97\xde\xe0h\x8a\xad\xdd\x8c}\xe2\x11vp\x95\xc6Z\xb5pc\x1b\xa2W\xab\xcf\x97Gv\xb1\x92\xf4s\xac\x91a\x8d\x7f\x1c\xba\x1b\xb8(\xbc\x92\xbb%\x91\xabu\xb0R\x1fD\x9bk;\x1d\x933Ge0\xe4\x05\x88\x8b\x05\xf0\x0d\xc0\x0e\xab\x94\x05I\xca\xebhJ\x1a9\x8a\xcf\x81\xa1\x89d0\xbe\xf2w%\x18\xff0\xceM\xcc\xb5\x11\xd0\xf2\xa9\xd6L\x93\xdaq`%+\xb3\xad\xd1\x08\x92:T\xbaC\x8e\x8c\xf5\xd98g\x89\xeb\xf2C\xc8\xea\xf7:\xf0 e\xdd\x85\x97H\xd1\x95\xecI+\xd2\x0f\xf5\x0cZ\x17\x19\xb4v\xac\x19|.{\x06\xff\x00\xd2\x15\x85\x1b\x1c\xd1\x1a\xe9@\x8aTW\x11\xd0jL\x0d?o\xeb\x16Q\xd1\xc4\xce`\x810\x1f\x83\x07O \xcd\x19tO\xf6\x866=tR+\xba\xf2\xe9\xd8\x93\x89j\xed\x04@\x12y\xfer\xfa\xe6u\x91?H\x9bYB~6\xdcih\xb2*\x1f~-\xb6Z\x14\xe2\x89\x99o\xcf\xba\xf3\xf2\x16\xe8B)\xda\xef\x8e2R\xe8i\x16\xad\xbb\xb4\xd2\xa4Y\x14\x13\xba\xa0T\x9b\xa9_~\x8c'C\x98\x0f<\xb2\xb7\xfa.\xe4\xab'\xe2\xf4\x96\xd6&\x87U\x17\x8eU\xb1\x14\x8f\x8f\x05\x99\\\xe6`L\\\xb8\xc8R\x88\xc9\x84\xf8k2\x85?&\xe0\xa5\xe0\x87S\xf2\x11\xfe\x98t-\x17\xce1\x99\x0bA\xe7m\x05l\xe6\xd5\xfd]\xb6`\xef1d\xa5\xe5\xc8\x9a\x97\x03\xa4\x1d\x94\x8e\xb3\x86%\x01(\xfb\xd5&\xe5\xd1R\x02\xed\xb4\xa2\x8e\xd0\x9a\xc6\xb6\xd9\x9f\x86\xadxw\xfb-Y\xb4\xb0&\x15\xcfg.\xe9\x7f=\xac\xc6\x8f\xac\xc7\x1f7\xe44Z p9\xb30\x9e\xb4\xc4\xd9Y\x9bf\x817\x1d`\xac\x84;\xe1C\x82\x1c\xd4\xf5\xdb\x01\x1a\xb7D\xbb\x0dswL \xf9\xe8M\xd2\xdf\x11\xeb\x93\xd6X?A\xacO6\xc5\xfa\xc9g`\xfd\xe4\xce\xb1^\xa0p\x86q\xed\x18\xff\xd4\xc4\xb5\xe4;%\xa0;\xa5\x15J\xd3\xda+\xdc)A\xcb\x9d\xb2\xb5\xda\x0cN\x97\x84\xcbdA=9\xfe!|\xe6M\xf3+\x0cZ\xa0\xf0l\x0c\x06,\xc6\x80\x05\xdcs\xe5\x87\x10/\xff\xd0\xd1E\xfb\x95\xec\xf7\x92:\xa5\xef[l\xd35\xf7s[\xd9\x89\x0bAu\xb7\x07\xedv;\x85\xdb4\x07\xdb\xf4\x1f\xb4\x8f+oo$\xafM\xa8\x06B\xd2\xe1\x8f\xd0Z\xe5\x891x\xf2\x02\xf8\xf4 \xfap\x1f\x0b\xf0\x07\x81!f\x00c^2\x84\xfeR\x03@\xe8\xfb^\x18\x02\x13,\xfc\xa4\xbb$I\xe2\xcd\x89\x14\xf8(I\xbd\xc9%\xbaW\xb5j|j\xc8\xff \xcaC\x9b\x11\xa5\xc8\x85\xcc\x85\x04)\xbc\xd6\xe5\x93>6=\x883\xa6\x89D\xa23\xc1\xa4V.\xb0X\xa5\x9e\xc3S.`b&dE\x8f\xbc \xf0\xc3y\x11j\x0dp\xe7xi\x14'0\xf5c2I\x83k\x91\xe4\x85n\x94(\xa6D\xe3\xe2\x1a\xd2\x05\x81\x1fWq\xb4\xda\xa6D'\xf9\x11V\xde\xe4\xd2\x9b\x93.\xbcO\x08\xfc\x987\xd8E\x865\xff\xd3v~\xa4\xfbl\xe2\x05\x01mb\xd9\x85\x13\xe2Ma\x19\xc5\x84r\xae\x8b4]\x0d\xef\xdf\x9f]t\x97\xe4~\x96\x90m\xfcz\xbb\xe8\xc7\xb8I$<\xc48\xd0\xe3\xe8\x0c\x0e\xd0\xd93\xf7W\x15\xef\x18\x91x\xb7 \x85\xacS\"\x9a~\x82\x86\x97\x94\xf1N &?g~\x8cZEY\x9eb|\xb7\x9f&\\\xd4\xf2\x13\xf8\x91vD\xe9(\x0c\xbf\\\x1f\xb9\xbf\xae\xe8\x88Nn\x08\xa9]\xc2\x91&Op\x90\xaf\xe6\xbb\x17~8\xb5\x19\x19\xda\xeak\xc0\x9b\x8b]~r\"F\xaa~\xd7\xabF\x981`\xfc\xba6\xa4\xa3\xe9@v!3a\xbd\xb8k1_\xe1\xf0\xb6\xe7\xb6\xe7p\xe2p\xd0\xee\xa8(\x1d\xa9K\xfay\xdbS\x95\xbeM\x05[\xcf\xd7\xa9\xba(\xaa\x17\x93\x1eb\xd7\xb6\x96\xf2%W>\x8b\x92\x9b{\xef\xe9\xe13\xf1\x12\x92;e\x0fk\xaa\xf0\x9b\xf7\xba*\x85\xbb\xb8\xbe\x16\x14\xd06\xa5 `\x0d S\x84\xe6f\x0c\x9e\xb7\xac\x19\xce.\x99[\xd1\xbas\x8b\xb6I\x97\xacI|m_7x@\x97=\xdeS\xb9\x89\xbaD\x0bk5Bc\xa3\xa8\xb0.9r\x86\xcc\x913\xe4\x8e\x9c\x93\xa6\xdb\x95\x8d\x1c;\xd5\xe7\xa6\xd1\x0f|+n\x953\x82\xce\xc1\x17)O[9\x98\xc7\x8a\x83y\x1b%\xc2c\xd8\xb2}LhPv\xec\xae\xfd\x12\x8a\xbb\x10\x9fyuK\x0b\xd97\x83f\x03gs\xdd\x98Zr\xbd\x18Z\xa8\xad\xb39*\xaf1\xf1\xc5\xb5\x9d\x8d\xfbg\xad&\x02mt;&\x8c\x16\xe1\xa5\x1b\xbf\xaf\xf6\x7f\xd3\x8a\xcc\xcd\xeb\xbd^\xc5=\x8b\xf1|R\xf5\x85p\x00\xdc.\n9?I\xbd~B\xe6\xc7\x1fW\x85k\xba\x05-\xa3\x13\xf1\x9e\xa4\xfc7\x9c\xd3\x14I\xa1\x18\x95\x18[\xff\xf2/R*B\x0b7p\x835\x19\x91\x07\xc8^W\xe1\xc8\"q\xd1\x81\x8b\x11T2W\x1a\x80\xbb4\xc7\x14\x93\x12\xcb\xe1\\rjW\\i1\xb7\xe8*\xe4\xc5\xda\xcc\xb5\xfa\xebJ\\\x82\xfa\xa8O2\x00\x9e{\xa9\x94\xb1g\xea\xa5\xc4\x90\xb4\xa7\xf2%[\xdb\xe2\xdb\x98\xcc\xc9\xc7\x95\xc6\xeb\xd9\x84F\xed\xe0y^\x8f\xac\xfaT\xd1\xe2\xc4n8\xaa\x19\xd2\xd6\x1d\xc3\x8d\xc7\x9e\x98\xbd\x17\"gS{\x86\xd6\x1f\xc5\xac\x0e\xae@]\x05\x0e\xe6\x16#\xaa\x1bP[\x1a\xd3\x14\x89\xae\xfc\x17\xffH\x8a\x88 #v\xc5&g/\x08\x14I\x05F\x94\x95\x0e\xba\xf2\x8b\xc0\x055\xe8\xe7\xad\xccb\xebb\x01\xe5W\xfaw\xd4\xbe\xd5\xdf\xeb\xeewy0\x84[\xb5\xb6.\xc2\xec\xef=tLa\xc5\xfdV\xf6\xcf>\x7fu\xf8\xfa{C\xbc\x87$\xf5R\x7f\xd2\xae\xee\xaa\x08\xb4\xde\xa26\x8f\xf2\xba\xc1\x07\x0b?\x98\x1em\xfa\xd5\x9c\xa4\xcf\x199\xa0;P\xf9\xe6\xfc\xd5\xf1\xc9W\xc7\xcf\xcd\x9f\xbe\x0c\xfd\xd4\xf7\x82\xd3\x14S=l\xf4\xe9\x914\xdcM>\x8dI\x88\xfe\xbd\xe2\x8b7\xaf\x8f\x8e\x8d \xe4[\xe8[?\x08^\xb1p\xaa-@\x92\x7f\xf6\xdc\x9f\xde\xe2+\xda\xd9 \xbb)\xd4\x80\xd4\x84G\x8b(\xa3\xe0\xe0m\xbc_MK\x10m;I\xf5\xbb6\xe3}\xeeOo\xf3\x19v\x17.[\xc3\xe7\xfd\xeb\xd3\xc3\x17\xc7\xe7\xb7\\\x13\xdd\xd7\x1b\x03Y\xd7\xc8\x06S\xcf\xb0\xaa\x94\xcf\xc1z\xf3\xe1\xf8\xe4\xe4\xe5\xf3\xe3\xf3g\x87\xa7\xc7\x1a\xe6\xa7\xda\xce\xc4Htp#\xc6\xfe\x9aLq7\xbd\x88\xa3e\xcd\x8el\xd3\xd7\xcc\xd8\xd7\xd4OV\x81\x87I\xceZ\xb2\xe4\x80\x84W\xfa\x0eT\xbd\xaex\x0c\xd7F\x82\xa6\xb6\xee\x8d\xb2\x9c\x9a\xd8\x9e\xf2\x93\xdf{\x84\xec\x9e;,\x85\x86\x0b;\x1d\x87k\xb4\xc7\xe1\xd9Fw\\\x1aR\xdaz\xdci\xb7\xf25f\x1b\xfc\xfb\x8d\xab+\xd3\x060\x85\x9a\xa1\xddzT\x86\x01}\xc6X*g\xc7\x06\xc3Q\xbe\xc5\x00G\xea\xbb\x11L\xed\xca[ly\xa8\xad\xbd\x11BJ\xa7\xf1\x06\xc3^Il\xaa\x00a\xfenS\xf8\xe5\xccC\xeb\x01l\xb5\xaf\n\xed\xf6\x10\x94\xf7\x91\x1f6\xb7*\x1e\xc1\xe85\x1b\xf5\x8b\x07\xc7\xa3\xda\x02\x86\xadm\x01A\xe8\xbd(\xbb\x88W\x9d\xed\xba\xa5Odo\xf9.\xfc \xadhy6\x9b\xef\xa3\x0c<\xbc\x10I\xc9r\x95\xfa\xe1\x1c\xd2\x88gi\x07\x0fb\x92\x90xM\xa6\x88)t\xa4.\xfc\xf8\xc7\xe4G\x17\xd2\x85\x97\xf2\x03;\xfc\xe1O)\\\x10\x88B\xbc\xa9\xb1\xf8\x8aZpI\xae\xbb\xf0\x9c5\xe5cn:/,,\xa6E\x8b\xf8\x86x\xd3\xc7\xb4\xce\x95\x1f\x04\x90\xa4\xf4\xff\x17\x04\xbc\xc9\x84$,94o\\\xb6\x17\xff\x93>t\xbe\xe9\x11z/\x04\x9a!\xee\xb5\xeeA\xf5\xd7&\xab\x03\x12\xcf=\xa9.4\x1c\xc0d\x1c\x9eqE}\xfbq@!^F\xb6\xee8D\xbd\x87\xe7\x82\xd5z}\xe9RR\xc8^GY,\x19\x0b\xe3\x0dY\xba\xf0B\x88\xc2 \xe9\xc2\xbb\x85\x9fP\xc8\xcf\x02\x7f\x92\xc2\xd2\xbb\xa6k3\xcd\x08m\xc9c\x87Z\xd7ba\x99\xd7\x91?\xb5Q\x8f\x8ct\x0bo\xad\xe3\x86\x80\x93\xf2S\x7f\x01,?\xbc\x13}\x1ch\xf5in\xd6\\\xe3\x86Q\x99Mh\x9a\x97\xa5\xd1\x85\x1fN\xcb&\xf7\x1b\xdcA\xeb\xd3\xfd\x80d$\x98\xa8\x88E(b%cbF\xacs\xcd'\xf7\xeeQd*\xb3p,tm \x8f0?\xc3\xcc\x9b\x10\x13BEk\x12\xc7\xfe\x94\xa3\xd4,\x8e\x96\x1c\xa9\xe8\xd7\x90\xac\xc8\xc4\x9f\xf9\x13\xb40\xef\xc2q\x98d\x0c\xc3RVkI\xd2E4\x85\x10\x93\xd1N#\xbc\x01\xa6-\x06\xde\x8a\x85\xf2\xc4\x91\xf0jhjH\x1c\x97\xdd\\\x94\xb7\x82\x08\xbb\xfb\xe9\x93\x96a\xbc\xcd\xcc\xbe\xc8V!\xedn\xe3\x90q3\xa7\xf00\x11\xa5\xc8`\x1cZ%\x0d\x7f\xaaL7K(\xd9/&\xc8\x160\x8a\x8bAQ2\xceg\x02/\x19\xe9v\xe1\xa7,I\xf9\xb71\x99g\x81\x17\x17\xb6\xf4.=w\x08\xda\x86n\xde\xff\xc6\xbd\xe9 \xea:\xcf\xd7T\xa8\xe1\x8c;\xde\xc7\xfb\xa4\xf3\xf3\x98\x0e\xf60K\xa3g~8}\xeb\xf9\xb1&\x863\xc8\xac\x83G\x8f\x96P\xddf\x19\xcb\x14\xdee\xdc?.)\xff\xedh\xa3\xd0\x8b\x07\xd7Xm\x8c\x19Vxx\x8d\xd5x*\xad\xb9ch8\xf6Z\x98\x8e\xadp\xda\x95\xfe\x9a/\x02\x03{\xc5\x12\x01\xcd\xaa_;0\x1b{gt\xd2\x93\x86\x96jbQ\xcb\x0f\x9d\xd3BG\x00\x9bF\nu\x86\xd3h\xbd\x82\x01\xc4W\xe8\xe6\xd6g\xa4\xa2+(y\xbb\x13\x0c-\xf5\x9b\x16E~\xd6<\xa4w2\xf6Zr\x8f\x80\xfb\x1b\x03\x9b\x9b\x99\x80k\x95\x00\xf2\xd7\xea\x0e|\x1f\xe6V\x04\x94D\xc3*\n\xfc\xc95\xfc1A\x94\xbe$\xf8\xf3jAB\xb6\x03\xe7\x14\xbd\x8b\xadI?Ab|\xcdV\xbff8\x07\x10\x8f=\xc6\x13\xd0\x1f\x14\x19`\xa8\x1b!\x8b*\xcc\xea\xae\xf3\xba\xed\xa0\xcfCT\xf3\xaf'\xcd\xf0d\x11\xadY*\x16\x8f\xf6\xe3\xe6\x1f\xd7~[\xc3+T\x8f\xf8V\x84~a<\xef\xcbbIds\x8b\xb2\x9a\xfc\x01\x9a\xf7\xc4\x05kI\xe29\x11\x89\x97^G\xcf\xb3U@\x0fd\xf25\xb9Nlg\x08G^H\x8f]\xac\x06a\x14n\xb3f\x12$\xe0\xc4\x01\x8d\xc8\xc2r\xa7\x95.\xf5\x90\xe1k\xec\xeb]\xcc-ZXo\xe9U\xc4\xe9w\xc2\x8e{\xca\xe9'\xde\x92P\x14\x1c\xe2\xd1\xdb\xead}LA\xb4\xc2\xa8\xb3\xf4L`Vr\xa2\xea\xc4\xcb\x12nNv\x15\xa9j[\xdb\xa1G\x9c\"L\xdb\x8e\xe088\xdfMw@i\x9c\xf4p\\\xd0\xb7\x97\xe4:\x11,0gL\x0d.\xaa\xc2\x86\xb0\x15ZL\x9bL\x11e\xf6\xd2x\xee\xa1OI\xd7[\xad\x82k\xccE\xe2\xe6\xde \x89\xc1\xd1\x91>(\xd4\x1a\xbe2\xdf\x8f\n\x9b\xb8\xc2\x11%n\xae\\\x18{\x84\xe6\xd3\x1bC\x1ek\xe2G\x83t\xebf\xfbl \xf0\x87>\xd9I\xbb\xfd\xb8\xfel\xc0\x1b\x01n\x04\xea-\x87z\xdd(*\x10f=\xa7\xbb%\x16`WzR[\xd1\xe77\x06\xfd5A#h@X\xb4\x9e\x9f\xfb ~\x84F~\x9a$\xeb\xa0'\xa9U\xa4]6\x0f\xb0\xa4\xaa\xbf\xf5\x18\xf5\x06/\xad\xc6xn\x1c#\x8fY\xce/\x90Z+\xb7p|L\x1f\x1fwI\xf8sF2r\"5\xc51lc\xe95\x9fpK8 c\x9c-\x15`\xb7\x87\xd5\x859\xd90HV\xa2\xf6\x85|\xab.\xf3\xf6p\xae!m\x05d\xeb\xc8%Q\xaeT\xe3\x1a{P(\xd0\xa4*,\x88|p\x94\xf9o\xecY<%/\xc2T\xdb\xaekP\xf5Cg\x04\x83\xa6\xf6A\xd1Y6\x8b\x05\xc0%\"2\x0e\xa1\x03\xfd\x16|*&\x84\x181\xca\xe4\xdf6\x10\xc2\x0d\xa2\xaf\xc8\xb3\xb7\xe2\xda\xedj\x96c\x91\xd07&3\x0cj\xe6\x96\xf6\x850R\x0f\x0b\x93\xf9T\xe4\x172ODh\xef\xf0\x13\x85U\x80\x03\xedk\xdbiT\xe8E\xb6\x865\xf3\xd0\xb0\xaelO\x86\xcc\xf4\x1f5]\x0caI%_\x8e\xfe\xb9\xbf:\xe5]h\xd7\x16=\\\xe4\xeb)*\x050~\x9fR\xc1\xc4\x97.\xee,G\x81\x88\xa7\xdf\xad\x0d\x12o\x8c\xca\xf2\x92\xb5KH\xae\xe0\xc2\x95_\x96\x82\x88`\x8ef\xb9P\x87\xe2<\xd5\xa0'\x12\xdf\xdb+\xd9\x02\x9c8\x8e\x0b+\x9b\xb80\x17?R\xf1c\x89'\xacz-\x82\xbe\x08\xdd\xa9rS\xa2V\xb3\x1d\xd4U\xc8\x83c\x17\xed.XR\nx\xbb\xdb\xedR\x86\xb9\xaa\xdab\xcb\xe3/W\xcc\x1c\x05<\xf8\x915\xf0#\xe7$\x91\x99N\x1cy\xfe\xd3E\xa64'\x13\x8fJ\xb4\xfc\x83A\x14\x92\xffJ\xcb~ \xca\xad\x8d`p5\x80e\xd1\n5\xa9\xd3Y\x80BM\xc1\x0c#\x12j\nD\x04BM\x91p\xd8\xd3\x14\x89(\x83\xba\"\x1eWPS\x84\x91\x04u\xefE\xc8@\x8d\xd62\x8fa\xa6\xf9N\x0er\xa5\xf9\x94\x85\x052N\xcc\xf0\x15\x8f\xc8a*a\xc1\x174\xa5\xdcU\\7\x05\xe6N\xab\x98\xc3jy\xbe\xb0j:\x19\xbb\x10\x96L'C9\x9f\xeag\x10\x0e\xee>\xc9n\x00\x8a[\x13\x17\xac\xf3s\x92\xbc\x8a\xa6Y@,WA?4\xaa\x1f\xca\xd2\xcc\x0d\x1eI\xfc\xf0\xa9\xa3\x1e|\x8aUt\xce\x85\x98dh`\xef\xdeE\xab\x0b/\x1eB$\xfa\xa9\xd42Y\xad\xde(\x84\xd2\xcd\x89\xfc\x8e\x86*\xda\x94\x90\xfa\xa8\xf9\x89\xbb\x05\x14\xe0\x00b\xd0\x8dMX\xd9V\x1c\xb6\xe0\x1f\xbe(\xd5\x03be\x87v\x7f\xf7\xa1\x9a\x03\xd4\x17E{=]^QVT\xc9\x1c\x9a\xe5E\x95l\xa4^^\xb4\xaf\x16%\xdcfU=\xa8&\xcc\x0fWy;\xa3+\x82-\xed\xef1\x9e\x88\xae\xdb\xae\xa3\xb6\x1a\xf0\xf3l\xdf\xd1\xa5*]\x19\xcfg\xd4'\xa6\xe5uN\xeb\xd7\xd9D\xcdoJ\xd0^\xd4r\x07\xd2\xb9a\xba\xff\xb2{.\xf8\x02\xd7\x1d.\xe9\xea\x9c\x7fho\x88\xb8=\x172\xf5\x03\x9br\x9f\xc8v\x9d\x9f#\x13\xd6s!.*\x11\xc7a^E\xb9 \x1d\xea\\B\xc5\xa5|7\n\xdf\xc7\xc1\xd1\xc2\x0b\xe7\xa4\x95+V!\xe6\xa5^<'i\x9dCN\xd4MH\xca\xc4\x00\xb3\x80\x97\xc5\x81JE\xc5\xa3\xf1\x8b\xbeq!\xea\x06\x917=]\x91I\xab\x01GL\x0e\xebR\xa6\xf7\x10\xeb\nA\xeb}\x1c\xa0\x87\xb9\xae\xc64\xba\ni7j\xba\xf3|\x0c\x08\xb7S\xcc\x8e\xd0j\x18z\xb8\xa1\xe7\x9ax\xb3\x88\x89\xc1.\xa6\x98\xb2Mp\xc0\x14\xae\xd87\x99\xd2Y\xe0\xcdrw\x15\x935 \x85t`\x1b\x06.f\xf6>\x0eZ\x0d\\\xea;b\x82W7\x8b\x83\x0d:\xc4\xb1z\xf1\xa4~\xff\x88G\xc0\x89\xa2u\xd0]yqB\xd8\xd7\x8e)\x834\x19[Y\x1cPq\xdb_z1\n\x91\xd6Y\x1ew\xd2\xac\x9c\xa5\\\xd8\x95\x1fN\xa3\xabn\x10\xf1k~\xdcW\x93\x08#\x1f\xdc\xbfoA\xa7Rc\x11%\xa9\xe6\xf5\xcaK\x17\xe6\xeeXmJ\x98\xf8w\x0b?I\xa3\xf8\xba\xfa\x06/v\x98\xcc^-\x93un\\\xac\xb4,\x97\xc5\x1c<\xa0\x83e@KH\xec{\x81\xffK\x0e8]\x86\xde\x9b*\x1am\xb4>b\xd3\xccIz\x14\x853\x7f\x9e\xd8\x0eE\x8c\x84\xa2\xf4\xd8\xa0p\xc1I\x11I\xc7\xc4n\x86r\x899\xef^\xe7\x12Pj\x88v\xc5]\xb2\xf0B\xa7\x0d\xa5\x81<\xb5 \x99\xbe\x0c\xa7\xe4\xe3\xd0\x90\xc2\x1e8\x03$\xe1\xae1\xcb\xb1\x89FE\xe1\x0b?HI\xfc\xc5H+\x03\x7f\xe0]GYZ\xa6k\xacc\x9d\xfd [t\xae<\xd1\x0f\x02\xc9q\x8a\xb4\x90\xa1F\x14'\x14\xd8\xa6\xf8\x92\n@\xab\xfap\xdag\xe9\xa5\xd6\xf9\x88b\xae'\x9dbL;B\xdfF\xa5\xb7\xe3\xea\xa8\xf1\xbe\xcd2\x1a\x98kl\xc29g\xd5\xbc\"L\xd9\xd4\x8cYf\xa0\xb5\xc6\x992\x88T^\x10\xf4\xf3D\x9du\x8b \xd6a\\\xcau\x86f\xa5*\x11Z\xc5\xea\x8e7\x7f\xc4.q\x9a\x08\x02\xde\xa8\xd1\x1d\x1cr\xa2P\xb7\xe9\x0b\x15\xb0\x86\xe0\x9bU\x981k\x7fc\x1a\x03Hg0v1F\xc7`|e\x0bl\x10OkZ\x03z\x9ch(j\xbc\xb7o\x81D\xe2\x06\xec\x8ep\xe86g\x02\xe7\xd7\xa53\x816\x94\xf3\x1c\xe9\xb8\xd0\xf8vK\x10=C>\xe4\xf6@`Z\xce;\x9dy\xc3\x1eb\x80\xd1z\x07\xca\x0f\xbb\xfb.\x11\x13s\xe5\xb8h\x18!n\xae\x89\xf7!\xb6\xf5\xcc\x98pU<\x11\xab\xf8\x8d!i\x9fx\xd0\xc9\x8f\xae\x93\x1f\xce\xb9\x95b\x97\xffIwHVK\x1e\xbc\x9a\x9bqk\xe6\xf9\x01\x99\x1a\xda\xc4\xf3\xde\xebN\xa2\x00\x15\xf3V\x8c\xd9=!S\xdf\xff\xff<\xcf\xab\xb3\xac\x0b\xd0\x11\x80\xe1\xa7y\x9c+\x83\x0f\xa2x\x16\xb5\xf72<`\\=I\x9bb\x17f\xfa\x15TIW\xd3-+}\xa6\xccFh\"\x8eO\x9e\x9aYh\xadE:?\xdd\xfeP\x1f\xdc/5\xb6\x87\xe2\xe1\x1b'\xa50\xad'v.\xe7\xcek\xac\xa4(\x03\xb6j\x98\x03\xcb]\xd94\x054\x07e.S<\x9f\xdd6\xff\xb0\xf6\xb3E\xba\x0c^Dq\xfeQ\xd5uK<7.\x18\x87\x88\xf9\x95\xf2(f\\`\xf4\xf0\n\x86\xa2\xad\xf9;\xd6g\xd3\xdc\xfci1\xbe\xfa\xe9L\xfd\xc4\xbb\x08\xc8t\x08Y}\xc5(d<\xeb\x90\x116I\xd0\xad\xff\x8e\xaf~PO\xb0\xeb\x808uLL63{[\x08b+\xc9\xb0\xcdH\xc2\xd2\xac\xd6\x01RF\x10\xd1\xf4v\x16\x07\xdb\xfcS\xe3\x87)\xaa\x8dY\x9a\xad\x1az\xaa\x01({c\xfeFl\xa5\x02\x94Y\x1c\x98\xab\xb7Z\\\x9e#\xd1pi\xea4\xef7\xffV@\xe4\x19\xbek\xe1\x13\xf8\x93\xcbaem\xf5\x03u\xc1:\xfe\xb8\n\xa2\x984\x05;3\xa2\xc4\xd4_\xb7F\x88\x14\xb5\xd4\xfa\xcd_\xb7\xf17\xe9\xe3*\xf6V+\xf2\x85;a\x13\xd9\xbem_\x91 b\xe6\x8d\xb6\x9c\xd7\x0efA\xfc\xf9\"\x1d\x82\xb5\xd3\xab\xc1\x86+\x7f\x9a.\x9a*%\xf1d\x0831\x90\x1a6#\xa0\xfd\x9d^y\xf39\x89\xe1\xfdK\xc3\xack q\x89\x80'\xac)\xcb\xa9\xfb\x04\x13v\xb7]\x96\xd2^\x11\x8bS\xb7YN\xb3\x8b\xa5\x9f\x0eaaZ\xc1Uw\xe9\xad\xda3\x0b\x92\x04\x9et'A\x14\x8a\x898\xf4\xd3\xfa\xe3\x87q\x06f\x9an\x92\x7f\x1d\x1d\xa5W8\xf73\xc7\x95\x9a\xbe\x91\xa8R\xceCK\xdb_\xbe\xacb\x90Qojd\x18\x94\x02\x80`J~\xccxy\x7f\x15\xce\x1f_x \xd9\xdfu\xfd\x0f\xcf\xde\x9c\\\xf5\xbe\xfej\x1e\x1d\x1e\x1e\x1e\xbe>}\xbf8~??<<|\xb6K\xff&G\x87\xaf\xe8\xbf\xaf\x1e\x04\xfb\x7f\xa5?\xbe\x7f\xf1\xec\xd5\x87\xe3\xf7\xb4\xc2\xfb\xd9\xd5\xad\xfe\xeb\x05\xbf<\xbb\x1f\xf6\x9e\xcd\x16\x1f\x9f\xad~\xba>\xea}\xdc\xbd\x7f\xff\xfe\xfd\xce\xcf\xeb\xdd\xa3\xbf\xac\xfa\xcf{\x8f:\x9dY\xbast\xff\x97\xbd\xfb_\xf7\xf7\xef\xbf\xdfy\xf0\xe8\xfd\xec\xea\xf9l\xef\xe1\xfd\x9f\x1f<\xea\xbc\x8f\x07\xcf\x07'G\x97\x8f\xe8x\xfe\xfc\xdd\xc9\xe9\xbb\xe0\xd5\xe1\xf1\xf1\xe1U\xf8\xe8\xfe\xfd_v\x0e\xe7\xeb\xdd\xfb\xeb\xef_>\xbf\xaf>\xef_\x91\x9f\xfc\xfe\xe5\xe1\xe1\xe1\xf3\x87\xa7\xefO\x9e}\xf8\xf3\xfcY\xf0\xb7W/\x0e\xa3\xbf^=?|w\xf2\xf1\xe2\xbbg\x0ff\x9d\xf5\xdb\xaf\xc3\xe0\xbb\xc3\xbf\x85\xfb\x97\x83\xc9l\xe7\xf0\xd1/\xf7\xdf\xce\xde\x1c=|\xf9\xf2\xfb\xd0\xdf{\xb1\\\x1e>{\xf5\xf0\xc5\xab\xc5\xd5\xbb\xfe\x83\xc9\xa3E\xb8\xf0\xff\xf6M\xff\xe8j}\xfcM?]\xbe}\xde\xfb\xf9\xf4\xeb\x9f\xf7\xe7\xdei\xfa\xed\xfd\xcbW\xdfy\xe1\x87\xe5\xe1\x87\x93\xe7\xef\x83?\xf7\xdf\xac\xb3\xec\xdd\xcb\xd7\xd1\xfe\xe5\xa3\xde\xe9\xc7\xd9\xc3\x9f\x937\xe9\x8b\xfd\xf9\xeel\xd6\x8f\x92\xb7;o\xc2W\x93\x0f\x0f\xa6\xbb\xab_\xa6/\xdf\xa7Y?:\xdc\xfd\xd0{\xfe\xb7\xe8\xeb\xe5\xc7ep\xfc\xfd:}\xfe\xfe\xa7\x9fNw\xd2\xe5\xd7\xcb\x9f\x9fuV\xdf_?\\=\xef\x7fx;{\xf0\xd3\xdb\xe3\xde\xcb\xdd\xde\x9f\xff<\xf1\x9e]\x85\x19\xd9\x9f}\xf5\xcb\xfc\xfat/\xfd\xee\xe5\xfbG\xfbo?<\x88/\x9f\x7f\xfb\xe7\xd7\xdf|\xe8=\xffz\xf7\xc5e\xf4\xf5\xf2\xc5\xea\xf5^\xf4>\\\xfb\x0f\xbf\x8e\xc8\xe1\xe0\xfe_\xbeK\x96\xdf\xfd5\x8b.?\xf6\x12\xff\xa4\xff\xd5\xc3\xf4\x9b\xcb\xd7\xfb\xe4\xd9\xa3\xe4\x9b\xab\xbf\xac\xee__/'\xd7\xde\xdb\xfb\xef\xe2\xb7\x9d\x93\xb7\xcb\x8bW\xaf\xfc\x8f\x93\xbf|\x98\xbf;\xe9{\xef\xff\xf6h'\xfa\xea\xbbd\xfe\xdd_\x0f\xbd\xaf\xf6\x8f\xaf\xe8\xb2\x1c\x9e\xbe\xff\xf0\xe6\xe4\xeb\xbd\xa3\xef_\xbe\x1c}F\xd0\x19\xd2\xbd\xb8N\xc97Lj\xae\xd3.\n\xad\xe2\xc4N5\xf2\x18\xaai\xc6=\x8d\x84\xc34-\xaa\xe9\x1c'\x16;\xf0\xcf`\x87\xd0\x81\xd8\x81\xfb\xb0\x0b\xdb\xd2]\xe9\x8d\x0b\xa4\x9bF\xcf\xaeS\x82\xa6a\xf5\xd7f\xb9\xe9 \xb3\x10\xc4Q2\xcb\x17:*\xe6\xfc:\xee\xf3\\\x14!\xb9\x82\xa8\x92\xe4\xa7\xc6N\x03\xc7I\xa0C+\xb1q*f\xc3x{\xe6BF\xe99%\x06=\x97\x05q\x86\xa7\xd0\xc3\x0b\xe2m\xd8\x85!\xad\x120\xfb\xc5\x00\x9e\xc0\x8c\xfe\xd3\x19\xc1\xae\x83\x90\xf5\xc7iw\xb2\xf0\xe2\xa3hJ\x0eS;p\xce\xe0\xc9\x13\xe8?\x84O\x95\"\xe8@\x9f\x17\x0f\xf4\xc5\x03V\xbc\xaf/\xddq($\xc6I\xa7\x83\xe6\xfa\xf0\xf4)\xf4\xf7\xe1\x1e\x0c\xf6\xf6\xd4\xf7\x0f+\xaf\x07{{pO\x0d-5@)\x9bI\xcf\xe6\xc9\x18\x06K\xe7\xf2\xf4)\xecV;Q\x18\xb3~\xab^\xfa\xbdZ\x90\xed\x9a!\xf6\xf4)\x0cZ\x03\xc0\xd1\xa2\xb4WF\xe0Y\x1c-o\x87\xc2B\x97\xc5\x8d\x12\xe0\x8f\xb0\xc3\xc2=\x8e9>\xf782\xc36\xf8,\xc7\x83G\xff\xe9\x8c\xa0\xbf\xbf\xf3p\xc7\x81\x88\xb1\xe13\x8a\xe0\x99\x8b\xd1n\xb1\x04\x9e\x82\x07\x07\xe0\xc1\xb0x\xa7\xb2\xc0\x0c\xd2>\x1c0@\xa7c\xda\x0d\xdd?\xbc\xd1x\x8c\xc0\x19\x9c\xd1\xcd;&\x0c\xae\xf7`\x7f\x87\xbe\xb0F#\xcbq`\xc8\xb1\xc2\xcf\xd7\xcbf\xed\x0cp\x1d\x1e:\xd016\xdc\xef\x89\x96)b\xe4-\xf3\xae\x06RW\x15\xee=\xbf\x93\xfe)\xf2C\xdb\x92\xec\xb4$E\x91d\xc5\xc9 \xea\xf3\x7f)\x84\xa5\xf8\xab\x92\x9f\xdc{?L\x1f\xb2u<\x90\xff\x18\xb2\x90\x88lQ\xac\xc3gG\xcf\x8f_|\xf5\xe7\x97\x7f\xf9\xfa\x9bW\xaf\xdf\xbc\xfd\xeb\xc9\xe9\xbb\xf7\x1f\xbe\xfd\xee\xfb\xbfy\x17\x93)\x99\xcd\x17\xfeO\x97\xc12\x8cV?\xc7I\x9a\xad\xaf\xfe_\xea\xde\xb4\xc9\x91d9\x0c\xb4\xdd/k\xf6\xfe\xc2~q\xa4\x86\xdd\x99\x83\x04\n@\xdd\xa8F\xd7\xeb\xd7\xd3#55\xd3\xfdl\xaa\x1f\x9fH\x00S\xcaJ\x04\n9\x0dd\x82yTW\xcdT\xafQ\xd2R\xa2H]\xdc\x95(R\x07\x0f\x1d\xe4.IQ\xa4\xb4\x07wy\x99\xed\x9b\xf9#\xfa\x03\xfb\x17\xd6\xc2#\"32#\"\x13\xa8\xaay\xd4\xc2\xac\xbb\x00\xcf\xc88=\xdc=\xdc=\xdc\xafo\xbe\xec\xf5\x07\xbb{\xfb\x07\x87G\xc7\xed\x1d\x8b\xa7\xcbat\xa4\xc8g\xe9\xc1\x13HN\xa0\xdd\xf6\x1cqS+\xc3+b\xc18\x93Q\xd9s\xe8#O\xe7\xec\xe0\x9b\xa9z\x9e\x1d\xa4\xf4\x14\xc35\xc0O\xc0\x1e%c\x0e\xa4\x8b8z\x87\xc4\x13\xa3\xba\x15Q}\x99\xc3W\x178\x1bAO\xd0\x0b\x02\x1e\xac\xb2e\x1a\xac\x97\x98\xf0f\xaf\xaaE\xbb\xca\xef\xe7`\"\x95\xd7s\x9b.\xa6v-;\xfcN\"\xb0x\xad#\xbc\x03=\x0eq\xa3\xe4\xf1\xc8\x87\x8c0\xd3\xfeN\x8b%\xd7\xcc\xc3\xdcD\xf1s\xa4\xe0\xa1\x90\x85+.m\x90\xad@H\xff\xb4G\xb0\xeb \xc2\xd8)] Jr(\xf5\xec\x1f\x1c\xf6\xfb\x07G=\x8a\xd7\xf4 \xba\x8c#\xa6St\xdd\x1f\xf0'\x8c|\xb0\xe7\x03*\x9df\x02\xf3\xed\x88y\x18Q\xfc?\x92p>B\xc8\xa0\n9\x90\x00\x07\xbb\xf0\x08\xa2\xea\xad+>}\x99f+\xe4\xdf\x82\xb1\xd5\xb1d\x0c\xea!\x06\x1d\x0c(jY\xe7\xbaG\xbbZyC\x9eM\xd2\x8d\x897\xab\x0b\xbb\xa7\xa0\x02\x0b\xabM\xe7\xfa\x08>\x84\x80\xca\x02\x942\xa8\x12\x05\xdd\x17v\x9f\xce\xab\xe7\xe8K\xf80\x82\x04\xe7L}F\xd9r\xe7P\x85\xa3\x9f\x10\x9cb\xc3}\x18BO-\xb2\xe6E:\xf4\xb9\xa6\xea\x05K`\x04m\xa8\xe6T@\xc4B^\xbff\x14f\x01\x8f\xf8\x18:s6\x08X\xc0\xd3\xa7#\xe8\xcc\xa9\xe4\xd0\xa6;\x18\xe6t\xdb\x9d`\xf9\xc1\xfe\x01|\x88\xe1\xb2E\x03.\x88\xfa\xe6\xd0\x19\xc1\x91\xa3i\x91\"p\xa4\xb6\x14\x95[\x8a\xf3\x96\xb2\xbc\xa5l\xf3\x96(\x91`7 #\x07\xfb\xda\x87N\xf5\x06\xaa\xe1~3}5\xc2W\x8b\xcc3\x19\x9c\xc2+\xef\x15\x9da\xd8\x81\x1e\x15\xbc\x16\xf9\x9ck\xf44\xc8\xf0>\xf5\xd2Ew\x1d\xbd\xb3\x07\xec\xee[D;Z\xbe\xc8\xaa7\x17KU\xe3\xa8?,U\x15Q$\x94\xf6\x0ce\xe8\xef\xe2 \xad^\x93\xa9\xcdiBq\x9b\"6\x0b\x19\xcf\xd1\x9b\xd6\x1c\xe8\x91w\x9e\xa3\xb7o@o\xf4\xb00\xa07\xc5\xd1\xc1n\xce\xbc\xe5\xd1t\x06{\xb4\xc2\x12\xe8\xf0\xd0\xd1\xe3:\xc5\xe5\x98\x93\xd5H\xdf\x8d\x19/B\xa7\xaf\xa3y~\x85\x12\xd4\x13\xe8\xc1\xed-\xbf#\x8b\x8e\x1b,K\xc4\x13\x14\x8cq\xa7i0\x97\xce0v\xd4\xbbH\xd0-)H^y\xafl\x82>\xf2\xcc\x90\xca\xd0\xe3\x14lJ2\xf2\xc7\xbcJF\xbc\xe7tp\xb8\x0b\xb0\xae\xf92\x8ab\x1b\xbf.\xa3KZz\x87=\xf8\xe4\xd5\xc0q\x81P\\K\xa0\x8cM\x9d\xccq\xe0 \xf4\x91\xf3d\x9d\x0ee\xcb\x1f\x8e\x80\x96\xa7\x07\x82\x11\xee\x94%<\xa5\xfd9\x855\xec@\x02CXW\x10\x89n\x89\xa5CQ,\xa1E\x07\xac\xb6v\x9b\xd6\xb6\xc3j\xcb\xeb\x99\x8b1\xc9\x83(\xb5\x82Om\x82\xb5u\x18\xe6\xca\x8d\x05\xac\xb6\x11,q\xf8\xc8\xbd*E\x96\xe6\xf7F\xd0s\x9c\x13\x08hcG'(\x9f\xb5aQ\x88\xbd\x1e\xa5T\xed\x11\xcc(\xad\xdeAzA\x85\xa7:\x12\x94Qd\x0e\xe0\x96\xbe\xeb\xd3w\x83\x13\xf0\x19\xc5Q\xaa\xcf\x8a\xea\xb3\xbcz_W=\x7f\x15:0\x9b\xc2\xed\x08\xfa\x03\xba\xb1\xae*\x1c\xae\xe1P,+p\xca\xdb6\xf7\xea\x0c\xed\xdd\xc1Q\xe5\xc8[x\x85\x96\x1dk7i\xb2\xb8\x921\xd08\xdb\xc6\xdd\x9f<{\xfd\n\x1d2\xf9W\x9d\x87M\x9e\xe6fXI{S&yMW8\xccwS\xf2\n\xf9\x85\xdd@{[w\xa3\xf1\x9a\xf4\x0e\x92g\xed\xa8\x14\x0d]LPd\x87\xf6\xee\xae\xe2w\x1c\xf0GG{\x8e\xd6\xa57\xfa\xf1\xba\xf4n\xe3\xdd\xde\xa8KU\xd3(H\xf9\x185q\xbbh\xf9\x8a\xe3.\xf3\x11\xa7\xef9\x1b7\x0b\x924^g\xa5\x8eq\xa5j\x94\xcaxM\xd8\xfc\x9c\x12\x03\x161\xc1\xe0\xc3\x11\xdf\xd4(\x8a\x8bP3\xeclT\xf5\x83vN\xa0\x85>\xfaH\xf2\x92Rv\x00f\xee\x0fy\xbc\x0b\x9e\x94\xc0\x85\x16z\xce\n\xa7!\x96\x1f\xc19\xe1\xe34\x18\x85\xde\x83\xef\xb1\x84 u\xda\xf0\x88M\x15\xcb\\n\xa8g\x1e\x84\xderY7\xe4\xfa \xa1\x9f\x16\xfa\x13%]\xbe\xd4\xd2w\x83\xd3\x18l\xd84\x08\xf9L\x9c\xfb2su\xfa\xf1i\xa1\xda[\xf7X\x9ca\xa7:\xe7\xc5\xa9\xf3\xcd\xcd\x9aTN\x9e<\x80\x12\x0bV\xc5\xeeYf1\x8b\xe1\x11\xa4$\xf6.\x96E\xc0\x7f\xe5\xc2V\xd14{\xf2 \xbcb\xb7\x1a\xdb\xfa>\xbc\"\xb4\x8f\xf6\x1d\x17B\xfb\xf8\x00=\xa5\x8b\x0e\xd0\x96\x06\x1bu\xbb\xe07\xfd]\x1d\xc7 \xed\x03\xc7\xb6p\xb6\xd2(\xaez\xea\xb0\xeb\x80\xbb\xa6x\xe1\x94\x89u\x83\xe4\xa5\x98\xebM4\xc89\x85\xd2\x9eUyD\x15\xdc\x8a\xe3\x80\xa5t\xf8\xeew\xf3\xee\xe1\x9d[L\xb7U\x8d\xc9\x12\x97|k7\x9a\xde\x0dWt\xefAWtww_Y\xcb\x81\xd3\xe5w{\xbc$ .\xc3Mj\x92\xd7U\x9a\xca\xd8\x8e\xbbg\xd0\x86\xb8\xfb\xb1\x0b\x16\xabU1\"\xb2V\xd8\xe8\x0e\xa4I\xdb\x08\xa1\x9an\x9a\xeeU\xaf\x94\xf2\xa8\xef\xbd\xaa\x14\xc5p\xeb\xa0:\xbd,F\xfd~5v\xbc\xc7j\x19T\x8b'9J\xf1\xc9\xd3cj\x0b\xbd\x07C{p\xec\xd8F>-\\\xf1\xbe\xd2\xc4e \x068e\x9a,\x91\x88\xceQ\x0d}\xc8t\x9a?K\x8b\xfd<\x80\xce!e\xe9\xc9z\x19\xa4\xb6e9\x1a\xc7-\x1d\xeb!\xe3t\xaap\x9b\xf7\x8e\x0b\x87\xd0\x1aA\xc2\x82\xd5:<\xcf\x91\x9c\x1e\x91=\"\x8e\x93\xab\x89\xe8\x0b\x92%\x86\x1e\xabj\x85\x88R \xe6\x0cm/t\xces\x911We\xd3\xf3o\x9f\xd9F\x82\xee\x9cYC\xa2\xee\xfc\x84\x9e\x8b\xc0\xd7\xe4\x15\xcak^\xbbx&\xf5\xec\xbc\xd2\xb1\xdfnO\x1d\x17\xcf\xa1\xf4\xd0\x14\xdb\x0b\xa7\xebG\xa1\xef\xa5\xf6\xdc^\xa0\x02\x9a\xc2\\<\x89\xce\xf2>\xdc0\x0b\xcc\x15<\x85\x9b\x13\x07\x96\xec\x9e\xd3\xc2\xc5\xb3\xf3l|Cke\xe2\xc2xM't1^\x1b\xf4j\xd2MK\x18B\xb2\xc9\xe6\xd9\x90\xe4<\xe4\x81\x83\xd6w\\Cr(\x0elRO\xb1\xc3\x95\xbd\x19\x88\x8d\x7f\"\xb5\xda\xdf;vl\x8b\xd6n\xb9[\x88\xc65f\xb8\xc0\x8e\xa9`[Fp M7\x19E=\xf5\xda\xf9\xdc\xfe\x89A\xefv\x928\x1f\xda_xW^\xe2\xc7\xc1:\xbd\x9dy\xa9\xe7\xec\x04+u\xd4;\xe3\xcf'\xd7\x83^gr}\xf8b\xbasY-\x12\xb1:\xc7\x9f\x0f\xa7mg\xb8s\xb9RI\xdd\xd8\xeaZ.X;\xb2\xef\xb9\x19K\x12/\x0c\xd2\xe0K\xf2\x83x\xd9t\xf3@\xd8\x92\x98R5\x15\xd7~\xe8Y\xce\xd2y\xb4n\xb4\x12 k\x95\x85\xde>\x1d\xf7\xa6\x0e<\x85\x8e&'\x95\xed9\xdc\xd6\x84\x8a{\xaf\xbb\xa2\xd2\xb3\x1d9\x8e\xb0-1\x0bm\xdcMI\x922\x15\x8e\xe5]DY:\xbcXz\xe1[\x0b\x86\xe0a\xc4<\x19hB\x81M0\xa0\xc0\xe3\xdd=\xbd@\xb4\xbb\xbf\xeblc\x1e\xc6`\xf8\xdd4\xfa$zG\xe2\xe7^Bl\x0c\xd1\xda\xa6C\xa6t \x03\x96W\xe3\x9e\x1a$\xaa`\xbb!\xec\xe9\xc3:\xf4\x0f\xef\x1e\x98\x027Yy4[\xcaUE\xf7\x0e\xaa h\xf8\x04\xefU\xb98\x93\x05\xaad\x8f\x89\x02\x87U\x81\xc2\x03\xae\xfeS%\x81\x98N\xb8\x14\x93e\xc8\x05\xcarIf 8\x85\xa4+\xf2\x87\xe5\x05\xebg\x0d\xb3\x12V\xe6\x0d\x03k\xf2\xa4\x8e\xfal\x80\xaa\xc2<\x92\x93\x1b\x06<\xdfX\x1b,K-\x9a\xc9E}8\x05_\xa4\xfb\xa3\x9b\xa2\xf2\x82\xe0\xc1DS\x19\xaf\xc2\xeaa/\xc3B\x15;\x1aA\xc7\xa3\xdb\xae\xd3\xa3\xbb\xad)~\x80\x89\x9dm.!t\xfa\xdc7\x83\x07\xc1K\xb9\xa2\xb9l\xf2f\n\x90\xd89\x81v;\x84'\x10\x9f8\x10\xf0\x00\x83<\xbcv\xa8\xe6\xc6\x16s\xfa\xa0\x18\xcb9\xa5!~.Z\xed*\xc7\x11\x15\x8f\x83\x1c\xd7TdfX+\xe5\xb2\xdb\x10\x1d\xcd\x87\xac\x88\xdf\xde\xc6\xf0\xa4\xa5\x12 \xae\x86(qW\xf5\xda\x86\x94G$5\xe8m\xc4\xccUB\xd8\x95\xb4$\xef\x95.\x06h\xdbf]\xd4/`\xcc\x9d\x06NE\x07B\x18\xc2\x8c,IJ\x10R\x8ap\xd8\x8c\xa8\x02\xf5\xaa+\x99O\xfa\xb6\x13-D@1\x88\xbb\xe2\xdb\xee^\x95\xe8 \n\xaeO\x92\xb5\xbb\xaf\xcb\x92\x85\x8c\xe0\x8eC\xc8\x0bhu\x83\x04%zSx\x01:\xa5\x01c\xda\x11\xa3H:r+>\xcc]\xe5\x149>\xe5\x88hZF\xb3\xb2\xbe|\xc2\xcb\xc7v\xe8B_:\x9e\xd0w\x93e\xe0\x13\xbb&\x91\xb27N\xa76\xa5\xaaI\x193\xef\xbeR&-H\x93\xa8 0^\xefe!0)\xdfd\xdc\xd7\xe1\x14\x02J\x8dQK\xf9\xe8\x11\x84\xf0\x94\xd9\xf4R<\xd7\x88\xa6\xb6\xd8\x03\xdbv9f\xa4Z\x99_\xf3P\x98YOx\xfbt\x08<\xc5\x1eS\xda\x1e@\x1b\xbd6P\n\x0c\xf9\x03\x1c\xa0\x93\xbf\x84a\xfc\x02\x87\x91\x7f\xfar\xc8_\x0e\xa1\x83\xceXO\xa1\xe7\xb2/#\xad\xd9\xf0\x8aG\xbc`\xac#@\xd6\x11\xc3\x13\x08N\x1c\x88Xh\xb1t\x1c\xd3\x9e\xe8\xfd\x11\xa3;\xe3\xc6~u\xb76\xed\xe2A#.\x19\xe5\xb3\x94m\xb7\x94\x1dp\x1bIO3\n\x18ZJ\x0b\x15\xc4\x16M\x08\xb2`\x8d'\x93lv\xd4\xebu\xe8\xdf\xf9|>\xad\xb8\xa3\xc7\xa2Po\x97\x15\xea\xed\x1e\xcc'\x93lN\x06\xf8sN\x06\xf4\xe7\xa07\xc3\x9f\x83\x9eZ\x05\x9dd\x0b\x9b\xd9\xf5\xc7\xac\x99\x0bSs\xe8\xd85\xfe\xbc\xa1S\xe8\xc3e\x9f\x0e\xe5Jg\xe4\x00\x8b\xcf\xe6\xf3\xa9\xf3\xd5\xe0\xbd\xa52\xf0\xf2`/\xe6\xf3)\x02|sC o(\xcfk~\x9b\xe7Fw,\x16\x89A\x95Y\xb1\x999\xe9\x11\xf6g>=\x15i\xefm\xde\xe9A\xaf7\xe3\xb5\x8e\xb9G\xcd\x94\xd3\xcd[\x0bEL\xc7X\x87\xe5|XU\xff\xce\xa5^\x8e#\xd1\xd5S+\x0f\xed\xe6BX\xad\xbf\xd2\xef%\x8cx\xb6X\x1bGg\x9f\x8e\x8a\x91\xe2\xa0\xe7\xd0\x06\xdf\x05\xeb\xd2\xba\xeb\x9eH\xf9\xa9r\xe9\xb0+\xc2w\xdf\xc6\xd5s\x898\x10V\xa3\x01\x8am\xac;\xb1\xf0\xd1Z\xe3\xc7\xff\xe5\xe7~mj\xddkd\xf5\xccY\xc8JvdS.\x9c\x1f\xf13<\xe2;\x18\xb7\xc72\xdb=\x1a\xf7rC\x02U\x13\x9f\xd31\x8d\xa8F\xde\xd7Pr\x14\xff\xa2\xdc\xdf/\x1d\xb7\xdb\xc1\x14\xe9y\x00O :q\xd81\x87\n\x06\xe98\x98\xa2\xeb\x8dA\x92l:\xcf\xd4`\x83A\xcfU=s\xa3\x96g<\xb9\xf6{\x9d\xc9\xf5\xec`r=;\xeaL\xae\xe7\x07\x93\xeb9~\x99O\xb2^\x9f\x92\x82\xac\xd7?\x9cOw.kpf[zx\x1f\xe4\xb2S\x14\xdfR\xc7a\x96q\x81>\x11]\xdb\n2\xdd}\x12\x0f\x9dJ\x90\x03\xebG?g\x0d\xc1zV!\x14\xd6\x8f\xfe\x96\x1e\xfc\xb7\xf5\xe0\xbf\xa3\x07\xff\x8fz\xf0\xcf\xeb\xc1\xbfI\xc1\x9e\x02\xfe-=\xf8\xdf\xe8\xc1\xffV\x0f\xfewz\xf0\xbf\xd7\x83\xff\x1e\x05?W\xc0\xbfC\xc1\xbe\x02\xfe'\x14\\M\x91j\xfd\xe8\x0f)x\xa6\x80\x7f\x81\x82\xab D\xad\x1f\xfd}=\xf8\x17\xf5\xe0_\xd2\x83\xff\x17\n&\n\xf8\x7f\xd5\x83\x7fW\x0f\xfe==\xf8\x1fP\xf0K\x05\xfc\x0f\xf5\xe0\x7f\xa4\x07\xffc=\xf8\xf7)8P\xc0\xffA\x0f\xfe\x03=\xf8?\xea\xc1\xbfL\xc1\xaf\x14\xf0\x1fQp\xf5\n\xab\xf5\xa3\xff\x89\x82_+\xe0\xffY\x0f\xfe\xa7z\xf0?\xd3\x83\x7fE\x0f\xfeU=\xf8?Qp\xa4\x80\xff\xb3\x1e\xfc\xbf\xe9\xc1\xff\xbb\x1e\xfc\x7f\xe8\xc1\x7f\xac\x07\xff\x1a\x05\xff@\x01\xff\x0b=\xf8_\xea\xc1\xffJ\x0f\xfe\xbf(8S\xc0\xff\xb7\x1e\xfc'z\xf0\x9f\xea\xc1\xff\x9a\x82\xab d\xad\x1f\xfd\x19\x05\xdf(\xe0\xbf\xd0\x83\xff.\x05?S\xb7\xc3oS\xb8\xa7\xc2\x7f\x9d\xc2\xdf,\x14\xf8\x9fSx\xaa\xc2\x7f\x83\xc2\x93jH#\xebk=Y\xfeZO\x7f\xbf\xd6\x13\xda\xaf\x91\x88+\xe4\xed\xeb\xbf\xa3\x07\xff\xbc\x1e\x8c3\xa0\x10\xc3\xaf\x7fA\x0f\xfeE=\xf8\x1f\xe8\xc1Hh\x15\x8a\xfa\xf5\xdf\xd7\x83\x7fI\x0f\xfe\x87z0\x92 \x85,\x7f\xad\xa7\xd6_#eR\xa8\xf5\xd7\xbf\xac\x07#\x99P\xe8\xef\xd7\xffT\x0f\xfe\x15=\xf8W\xf5\xe0\x7f\xa1\x07# R\xf0\xed\xeb\x7f\xa6\x07\xffs=\xf8\xd7\xf4\xe0\x7f\xa9\x07\xe3\x9e\xfd\xab\n\xf8\xd7\xf5\xe0\xdf\xd4\x83\xff\x8d\x1e\x8c\x9b\xf3R\x01\xff\x86\x1e\xfc[z\xf0\xbf\xd5\x83\x91\xd9\xff5\x05\xfc\xdbz0\xca\x00\xca\xc6\xfc\xfaw\xf4`d\xb1\n\x07\xfb\xfaw\xf5\xe0\xdf\xd7\x83\xff@\x0f\xfeC=\x18\xd9\xb7\xc2\xd8\xbe\xfe==X\xcf4\xbf\xd6s\xc7\xaf\xffH\x0fFv\xf2\x93\n\x18\xd9\xc9\x17\n\x18\xd9\xc9_W\xc0\xff'\x05\xbfU\xc0\x7f\xac\x07#'\xf8D\x01\xff\x89\x1e\xfcgz\xf0_h\xc1\xdf\xfc-}i\xe42\xd5\x981\xd6\xd7\x7f\xaa\x07\xff\xb9\x16\xfc\xcd\xcf\xe9\xc1\x7f[\x0fF\xd2\xabH#\xdf\xfc\xbc\x1e\xfc\xf7\xf4\xe0_\xd4\x83\x91 (\"\xcd7\x7fW\x0f\xfe\x05=\xf8\x97\xf4`\xa4\xdf\x8a\x90\xf2\xcd?\xd2\x83\xff\x89\x1e\x8c\x84Z\x91/\xbe\xf9\xc7z\xf0/\xeb\xc1Hc?S\xc0\xbf\xa2\x07\xff\xaa\x1e\x8cT\xb3\x1a\x93\xc1\xfa\xe6\x9f\xeb\xc1\xbf\xa6\x07#\xa1>S\xc0\xffJ\x0f\xfeu=\xf87\xf5`\xa4\xc8\x8aT\xf0\xcd\xbf\xd6\x83\x7fC\x0f\xfe-=\x18)\xf2\x1b\x05\xfc\xef\xf4\xe0\xdf\xd6\x83\x91\xf4VC\xe4X\xdf\xfc{=\xf8w\xf4`$\xa6\x8aP\xf8\xcd\xef\xea\xc1\xbf\xaf\x07\xff\x81\x1e\xfc\x87z\xf0\x7f\xd2\x83\x91\xc6*\"\xe47\xbf\xa7\x07\xff\x07=\xf8?\xea\xc1\x7f\xa4\x07\xffg=\x18I\xef\x0f\x150\x92\xdew\n\x18I\xaf\"\xe3~\x83\xa4W\x11f\xbf\xf9c}i$\xbd?\xa3\x80\xffD\x0f\xfe3=\x18\x89\xe9\x97\n\xf8O\xf5\xe0?\xd7\x82\xbf\xc6\xd5y\xa92\x1e\x9c\xab@\xe1<\xdf\xb0\xe3\x9a\"\xb9|\x83\xc2R\xa4\xc2Q\xb0|\xac\x927\xe4\x1bI\xe1\xcab\xf2\x08a\x8ex\xdb\xab\xe9\xee\xa3Q\x945u\xdc(5\x84tL\xa6\xa5\x17\x9aT\x895J!\x83_\xc8\x81>\x1d\x89\xa2q\xcbx\xf1~\xa3\xeaKo\xde\x12zc\xbcK\x92\xf2\xe4\xdd\xdc\xf2\xc6\x9c\x92\xe4\x81\xa3}\x93\xdb]\xb2\xc2\xee\x82\x1aL\xa6x&\x9b)\x9euv\x12\xf4 \xeb\xf5:\x93\xeb\xc1|r\xbd\xebu&\xd7{\xbd\xc9\xf5\xfeEgr}\xd0\x9b\\\x1f\xd2/\x87\xf3i{\xe7\xae6j\xd1\xc9\xf0>\x9d\xf4:_N\xc7\xcf:?3\xbd\xc5\xff\xbf\x1a\xb8\xef\x11v;\xeeu\x8e\xa7\xf4+{\xc8\xbf \xf4v\xfc9\xfb\xd9\xeb\x1c\xc3t\xe7\x8e\xdd\x0f\x99g\xd8Vv\xae\xdc\x085\x99\\{\xfedr}\xd1\x9fL\xaeg\x87\x93\xc9\xf5\x9c\xfe\x87\nV:\xe1l\xc6q\xca\xd9\x9c\xe3\xa4\xb3Y\x9f\\_0\x85k\x8f+\\\x0f\xe60\x99\xa4\xf4\xf5\x8b\xc9\x84\xbe\xeb\xf5P/;\x9fO&\xe1d\x12c\xa1\xc1\x11\xfbs<\x99d\xfd\x83#Z\xa2\x7f\x84\xd6\x16Z\x11\xfb\xd3g\x7f\x06\xec\xcf.\xfb\xb3\xc7\xfe\xec\xb3?\x07\xec\xcf!\xfb\xc3\xea\xec\x1d\xb3?\x1ek\x81un\x9f\xfe\xd9\xed\xf5\xaaq\xae\x98y\xcd\x826\x0b\xecm0\x9d\xcd\xda\x96\xba\xe1P\x0b=8\xe4\xc3>\xbc\xd0[\xc9\xe8R\xd3I\x9d\xd3\x99\x9a\x1fL\x98\xb6{r\xad\xda\xba<\xad\xe9Mt\x0d-A\x95\x06\x8dU?\xeb\xfc\xcc\x84)\xdaQ\xd3\xceT\xed\x93\xeb\x191\xd9\xd7\xb60\xe4\xf9w2\xe4\xa1\x89l\xbcq\xbf\x96\x92E-\xcb\xed~\x9e\xcer\xb6\x96\x8a\xce\xeb\x8b.x\xd1-\xcd\x07\xb7&\xdb\xa9S\xb5>\xce\x8c\xd6\xc7\x85\xc1\xfa\xa8\xb5\xb5\xe2\x1d\xe8\x8d\x0c\x92\x0b\xbdA\xf2\xaad\x90\xd4\xd7G\x9f\xcd\xca\xaf\xdd\x14&\x96\xf1<\x8fs\x8f\xf3\xdf\xa6\xd3\x86\x96:\xfbt8\xbb].oW\xb71\xb9Mn\xd3\xdb+\xe28\xa7\xdc^9\x8e]\x98\xbb`}`\xa9\xf6NX+\x15}t\xfb\xc9'\xb7\x9f\xde~\xf6\xe2\xf6\xec\xf6\xcd\xedO\xbd\xa8T\x04mX\x9a*+\xfa\xb7\xdc\xa4\x7f\xe2\x8d\xa6\xe6-\x17\xf7\xfb\x87\xf6\xe9\xb0\x7f\xf6\xe6v\xf0\xea\xa3\xdb\xdd\xcf>\xba\xb5O[\xe3\xfe`w\xeaL&\xb37\x7f\xcd\xb1OG\x93\xc9\x05\x92\xf1\xf3\xa9#\xbf\x93\xa4\xb7\x83pv\xbb\x1b\xcfJ\xef\xa4\x8b\xfc\x9dg\x9d\x9fa\xef\x04.\\I\x03\xbb\x97\x8dJ0\xaf\x9b\xcd\x98\x97Y\xe48\xa8\xe6\xf4a\"\xc7a\xd5\x05\x98'@\xeb7:\xd0V;\xcc\x82l\x06_\x12vw\x9b\xe7\xc6\x9cy\xa9w\xae\xcf\x7f\xba\xf0\x92\xc5\x10o\xb6\xc5\xae\xf2p\xe5\xad\xf1\x99\x1d\xd1q\x07\x1a\x0f)\x91f\x0b+(=\xbd\xbb\\\xa6\\\xc6\x11rYU^\xe3\xf6o\xc55\x97\x0bf\x8a\xdb\x8b\xc7\xe1\x03\xed\x9d\xdd\xc4\xec\xc8\xa8\xb3%\x87\xdb\xd9\x92Y\xd6\xcc%\xf1b\x1b-\xc8\x04\x03\xb9\xe8\xa4_1\x13T\xd2U\xfd\xcaD\x18\x7f;f\x1e\xeb\xe3\xfe\xb4\xde\xb4N?\x89\x9c\x0b\x92\xf6\x81e\xed\x92\xc1\xdc\xab\x11\x13x\xca\xf0K\x82\xf2i\x19\xb8\xf0(\x12fe`\x82%\xbd\xf2\x1d\x8f-/u\x1c6\xca\xd2Z\x84\x970\xb5\x9d\xf1d\xfa\xd5\xfb\xdb\xe9\xce%\xd2\xf1\x0f\x1eYR\xb1r3\xb7\xf9}\x07\xa7\xfb\xe1)R\xf4\x89\xed\xdc\xe2\x06\xea\xb69`\xea`M\x1f\xf4\xbb\x1f\x9e2~\xf5\xc1\x9d\xe9z\xcbn\xa1\x0b\x1b%n\xc2\x03\x01o\x1e`\x18\x8d!x\x0e\x13\xfb\xb3\xd2\x8d\x9f\xcdQ'\xcf\xe5\xa6$\xbe\xccs\xb9\xed\x8c?\xefN\xdb\x1f\xect\xc95\xf1m\x8cR\x16\xe0m\xa8\xe2[\xf7\xe5\x8b\xf3\xef\x7f\xf6\xfa\xcdk\xbc\x87j\xe1\xa5\x15\x8b\xdf\xf6Kb\xdf9\xefw\x99\x03W\xd9\x15\x7f\xbb\x99hE\xcc\xd9%\x08\xb7M\xfa)\xed^gl\x9d\x9f\xfbQL:_$\xe7\xc9\xc2\x8b\xc9\xec\xfc\xdct\xa7\xe8\xae*\x05\x8dc\xff\xc6\n\x83\xe6C\xdbf\xb3&\x18\x03\xd2\x96\x85\x87\xac\xe3\xd1\xa3\xdc5\\\xa6I\xe3T\xef\xe6Y\x90\xa5\x0e\x0b\x1e\xc6c\xc6\x90;\xcf\xbe\xce\xfb\xd3:?_F3/Y\x9cSF\x7f\x9e\xc7\x94;?\xd7\x1c\xb9\x14\xbf\xf4\xf2\xf6\xdc\x16\xb5J\x93$\xa6\xa3<\x17\xc1\x1cl\xc5\x83\x0b\xa4\xb33Q\xa6\x0fJ\xde\xca<\xc4P\xbe\xdau\x99\xf4\x85\x7f-\xbf\xba\x82\xd7]N\xd9\x8dU\xe12\xfe\xa0s\xff\xe3\x9f\xce\xfc\xda\xc2i\xf9\n;\x8e0\x90\xc6\xfd\xa0\xe3\xac\xc1\xb1\xa61j\xf6\xb2X\xf9\xe6a\x16;\xa8]\xde\x89L\x18\xeb\xbb\x10\xb2\xdb\xc8\xe8\xc7')\xd7\x08\xf7\xfa&L8\xb8/uh\x12I\xc6\xd3\x07\x12B\xb42\x08\x0b\xd5\"\x89a\xebe\xe0\x93\xa6\x89\xdf\x08\xb9\xf4Bo\xccPH\xbb$-;\x14\xc1\xb6l\xba;\x8b\x04i\x1d\x8c\x1aE\xba\xebh\x8d\xa9\xda\x0bl\xc4k\x15.t:\xf9\x1c\xb9\xd0\xbb\x13\xbb\x15\x93\xf4\x974\xf8\x90\xc7\x13+T\xb6\xe3p:\xee7q\x9f\x87\x1cI\xee\x8b[\x1e\n\xa5t\xa5\x9b\xb1\x0f\xdf\x93Mw\xb2:\xad\x18q\xca\xae\xb9E\xc7\xa7\xd5n\xb7%\x0c\xe1at\xc6\xb4\xe1)^\xb3\x0f\xc7\x01\x9dm\x96\xe0~\x83}m\x1e\xed~\xe3hM\x18\x14\x8bT\xa5\x0e?P\x99n\x96\xdd\x95\xfb7\x12#3r\xb3\x1b\xa1\xa9\xb6;\xf2\xd5Q\x8clb\xb1\xac\xdb\x12\x80e\xcd\x96\x00\x17Q\xb4$^\xc8!\xa7\x94\x0d\xf0T\xae\x16\xb2\x9d\x94\xae \x93\xc8F\xf7\x90)\xb7_\x8c\xd2&\xc0\xb5\xb8$\x1b\xa8\xee\xbf\xdd.0\xd6\xf4-v\xa1f\x03\x16\xdd\xd0\xef\xbe\x101QO\xd3P\xd7\x80\x95\xbbe\x86\x1brv6\xcaoW\xf5\xef\xb7\xedv\x8f\xf6\x1c;\xb4\xf7v\x0f\x9c\xad\x8c\x90\xe63{_\x7f\x1f\xeaPw\x18\x0b\xed\xc3\x83\xc696,s^\x80q\xb3\xcc$\xd0zE\xe0!\xdd]F*\x0c\xb7\x02\xbci\xad\xbe/\xeaH\x04\xb5\xdc\xd5\xd4\x00\xfc\xaed\x84\xe1*\xc3\xda\xbe\xcb\x1f>\x8e\xc4\xf6\xc6\xe9\x14/lx\x86l\x17\nT\x85\xd0^\xfa\x94\xe0\xe4\xd3a\x14\xe0}\xe4Jp\n\xde8AQ\xdc\xa7\x82\xaa\xaf\x91\xc7\x01\xee\xa3Q<2\xdc\xa1P\xe2\xf8p\xbd\xeb\xd1\xde\xd6\xa8 \xc8l`\xa2\xf8\xfd\x928\xf4\xe8\x11\xa6*\x18\x0f\xa6\xec\xd6*\xfd\xde\x9b\xba\x0c\xd8\x9fR~\x96\xb7\xa5\x18\x8e\xa1z\x04J)Af<\xd4Ub<\xdcu\xd6\xfa\x87\xd5\xfbF\xe2:\xa1N\xe5\xd5W\xd5]\x83\xa69\x14wx<\xddd&H\x98\xf8]|e\xf8\x18\xba+`i3b=\xe5\xa3\x0d{\x0e\x96\xbc\xc1(M\x0b\x17f.\xac\xd9\xaep\xe1\xca@1\x91\xee\xca]\xbeAO\x8b\x99\x0b\x0b\x17\"\xb8\xe5w\x0c\xaf\xe8\xa6\xbc\xa9\x1fA\xcd\n\x8a\xb7\xee~\xfak\xbc\xad[]\x91\xeaA\x94Yy\xb6:\x8b\xdeC\xdel>L\x91\x8d\x85dZ\x96\xcb\xfd\x0f\xdea\xb91\xd1\xdf\xcd$\xc6\x07j\xeb\x9e\xa2\xa1>|P\xbf\xaf\xf7b\xea\xf7\xaaV4$\xd5\xbd\xc6 \x1f\x9b\x1e\xf04\xc4\x17D\xf4\xcbh\xae\xde\xd7\x04I8\n\x0d\xb5@.\x1dQF\xe7 &\xfa\x042\x16C\x9aO\xabW:\x13\x96\x11\xbd\xdd\x0e9\x06Q\xa8Z\xbd2\x0e\x10)z<\x13?\x85F1YH\xc9\xf7\x13\x8c\xcd\x8cX/\xc8\xee\x1e\xeb=\xd5\xf6zz\x83\xe8^\xbf\x8a\x12\xc8{\x95@H>\x17\x8e\xaa\x885\xe7\xf0*\".U\xb1\x00\xbdI\x84\xad\xeb\x99\x08\xa2WuOY\x94K\xc5\xdeM\xb5\xc4L.\xc18v\xb5\xc8\xd5\xfd5\xb0B>\xb9q\xe1\xd2\x85\x95\x0e\xfd)\x9a$\xdalT\x17\xf8\x84h\x9e\xbc\x83\x11\x9c\xc3),`\x08\x9e\xf6\xddk\x18\xc1E^BW\xc7\x19e\xf4\xb4\xa2wT\xacY\xc3)\xcc`\x08\xef\x1c\xfak\xa6\x16\x7fA\x8b\xd3Z\xaf\xe5\xe2\xd7\xa6\xe2\xcfD\xc5\xd7\xean~F\xf9\xb9\x8f\xd62u#\xe3&\xf5\xe5`Q\xad\xbe\xba\xd7\xcey\\\xe23\x0c\xd5\\\xb3\xbb\xf2\xf6Zgy\x85+T.\xae\x04;s\\8\xa7\x909S\xfc\x06\x9aU\x1bB\xc4\xa1\xefJ\x0f\xd4\xb1\xb5\xec\x10\x1ea\x90|=\x8dz\x0d#8Cer\x1e\xd9\xc8:?g\x89\x0eg\xe7\xe7\xa6\x0c\xd3_\xc0\x08^H\xaf\x91\xeakzj\x87\xf6\xbe/\xea\x0e\x83o)\x8e\xc3)\xa4,\x984*Vk2H\xbe\x84\x11|\x81Z\xd8\xa28\xd1\xcbD\xc6\xc9\xbe\xb4\xdf\xba\xf0R\xcc\xe3J=&n\"\x03\xb5pQm\xb5\xf6L]\xbe;3F\x95\xd3qc\xec\xb1\xfe\xd4\xb7{\xbc\xaf\xf5\x0b\xc9\xbe}\xbf\x90\xaa\x8c&;\x88`\x01o6\xb3\xd31\x99V'\x83~2\x89\xbey\xb3\x19\x06\xb5* \x94#2\xaf\x8eLq\xe0\x88\xca\xbe\x1a\x99v~\xab\x93\x1b\xde\xcf\xe2\xb3\x91D\xc4\x99i\xe8l\xc48\x7f\x9cbXs[f\xf3t\x8aM\x90\xa6&\x8c\x08m\x8acx\xac\x8fi\xac\xb8\x9ad\x06\xa9\x81\xbbE\x1d\xeb\xa5\x80\xbd^\x95\xdf\xfb*_\xa7\"\xc0@\xe5\xfe9\x8b\xfe\x1e\xd3\x15WytI\x1c\xf8\xc8K\x15G\xd5\x92$\x80a\xd7k%\x81O\xbd\xb5N\x0c\xc8\x9f\xbfB\xa5v\xb5\xc8\x8d\\\x849\xb6T\x8b\\\xcaE\xce\x88\"l\xacJ\xcfQ\x97^-r^*\x82\xca\xf4j\x91\x0bE\xee\xf9^6\x9f\xab\x1d~W\x996\xef\xa7\x02\xf2\xaeZ\xe8z\xe3@\x94g(\x17\x9c\xc25c\x0b\xaf\xe7\x1b\x07\xfe\x13\xb4:v\xe1\xda\x85\x17.<\xab\xa2~\xf2.\xc0\x08|Z\x1d\x96\xef%\x04\xde\x0d\x158p\x06\x98\xcayA[\xa3r\x9e\xd0\xdb[`\xcf_\xcf\xe7 I\x8b\xe7\xecw\xad\x00B?)\x06\x10\xbb\xc0 vy\xf4T\xf6K-\x8f\x1d\xbd\xd0w4\xb7|6\xf5\xb6\xf5\xc2\xa6\xc4=\xc0\xab\x1e\xec\x1bqtY\xbf\xb1\xb5\xa5\xda\x1a\xc2\xd7\x06\xf8Um\xef\"\xbb\x9d\xba\xd0\xd6i\x9d\xf1\xedE\xed\xdbi7\xf4V\x84\xe9/\xf1\x1b\x06jY\x91$\xf1.9\x98\xff0T\x7fc\xe8\xf4\xaa\xbeYfYR\x83\x88\xe6\xef\xcf\xf4\xef\x0bQ\xcd3\xbcvi~\xed\x0b\xe6.P\xcd\x1d&>\xb9Xf\xd3\xfa\x13\x0ch\x8d'\xbd\x96\xd0P\xa0\xb4\xfaE#\xf6 \xe9\xed\x19\xd74\x98\x9b{\x9b\xd7\xf5\x16\xe7\xc3 \xaf\xc1\xed\x08\xe6.<+\x0e\xa2\xe6\x86_b8\xc5\xd7\x88\x88\xaf\xd1T m\xe0Zy\xf0Y\xa1\xb1q\xe1\xa5az\xcf\xcd;\xba\x10\xe3\xcfD\xccJ:\xa83\x11M\xb6\xf4\xa2^v\xbc\xbb\x11\xdb\xe9\x16 3\xf5\x94\xed\xae.i\xdb\xca\x87<\xad\x0e\"\x8cA\xf5\xa5\x89\xb7\xaf v\x85\x15\x8e\xdbm2\x85\x11:\xf5\xa7\x95\xcbq\xce\xb7\xa11\xfbv\x86W;65\xa1@\xd3\xb0\x8cx\xb0\xd7\xd3i\xcc\xfa\xaa\x08\xf5@\xda\x03\x9ewO7\x89\xa8Q\x81G\x10\xa8\xf38gv[\xcd\x89\x123\xef\x19S\xa5.1m\x82M\x1c\xc9\xd2\xd4\xf2\x8d\xf4\xa8Hm\x00#X\x9e\xc0\xba\xc6\xe4\x81\xb9\xb9\xc7k\x83]\xa0e\xfb\xa8\xb1\xc0\xdc(C\xc9\xcbn\xe1lh\xe3\xa0m\xcc\xd03YG\x13i\x1b3\x96[\x88>\x96T\x0c3\x0d]\x14\xe6\x82V%Bg\"+\xea\xd8\x0f\x8dCO>+T4\xf4\xe9il\x0dO`i\x9c\x99K\xb4\xa7\x88\xf91\x98UV\xe8\xce\xb80L_\xe6\xe4\xfa$\x1fox\xae\xf0\xfc\xbb@,J\x11\x7f\x86\x90\xd9\xf4H\x8cP\x86^\x89\xc9\x8c,\x9b3\xce\xe1\x94\xf6p4b\xc7y\x8fW\xc2P\x13\xeb=7\x9b\x9cQE\xa3\xe7 \x171\xf1\xde*OT\x83\xf0\x0d2L\x94\xb2\xfd\xc2\xb7\x1d\xfdF\x16u\x14\x1f\x0dI\x88\xbf7\xa6\x89\xbf@!N\xaaU?\xf5\xefP\xba\x93\x8a\xa9\x03\xba\xa0\xfb\xe6\x1dm\xad\xdc\xc9\x80\xa7lS\xa0\x8c\xd3\xdb\x96\xd8\xf0r\xd8\xf5\x0b\xfa\xecBV{#D[\x16\xdb|'\x97}\xc7\xfc\xd0\xd9\xd4o\xc0\x12\x13\x99)\xe7?(\x82o\x99\x88P\xa6\x91\xfa\xeb\x0e{=}\x0c\xca\xbb\xfbN`\x10\xe1\xc8\x85\xe0\xce\xc7\xe2\xbd\x9e\xfe\xbe\xd0Qc\x97\xd4ZE\xcd\x11\x8b\xefnpHc\xaa\xc6\x08o`G.\x84\x1b\xdc\x0ehf\xb2\x1a\xbd\x816^=)\xc5\xa7\xcf5KR|\xfat\x1c@\x1bX\x8c\xfaqh\xf0>\xbf\xfbl\x9b\xf2\xae\xe8\x8c\x11\n\x0b]s\xe6\xf92y\x11f+\x96\xb0K\xd5R\xf0\xd7.I*\xf1[vfNT\xddEV\xca\x0c\xa4#\x15\xc2J#\xa9\xe5\xc6S\x18V\x0c\xfe.\xc46\xcb\x1b\x94\xd7\xa6\x0dO \xd5XD\xb8'\x1aMh5K\x0c\x0c!\xd0\xe3\xa4\xf7-#M}\x92\x83\x9e\xc8\xe9/c\x91\x9e\xe0f,\x0f\xbf\x86\x89a\x8cN\xf4\xe2D\xea\x15\x8d\x83v\x1b\x13\xc4o@\xc1\x9aB^7N\x84\x81\xb8\xdc\xfd\xa6\xe6\x9eAy\xdc?\xd4_B\xd4'\x0dQme<\x81X\xbf*\x82&\x06\x1b\x9a\xee.\xd7\xf6r\xa8\x8e\xc4\x85\"\xec\x84\xb2\x92\xe8D\x83\xa99\x02\xa3\x00\xca\x9e\xb7\xd0\x19$\xd3\x96ZWJ\xb5\x96(\xbci\xcb.P\x0e\xbe\xbd\x859\xfdoI\xff[\xab\xa5f\x98\xb3\xfc\x94\xb2\x8c\x1c}\x99\xae\x8d\xca0\xba\x9c\xa1r\xce-\xa3\x84\x87~)<\xbe}\xcb\xcf74\xbb\xeb\x8b\xf2\xb3m\xb1*\x90m\xdf\xb0.\"8BUS\x01\xb6\xd6^LB\x0e\xc0\xf7\xd7\xac S,I\x05\x0b\xd5P\x05\xf8Z\xaa\xd2a\xe2\xda\x8d\x0bW\x0e~\x9f1\x03\xf7\x8d\x9e/\xcd\xee\xbb\x8b6&'\"-\xac\xa0\x17\xe9\x89\x03\xb1\xc8\x8a\x12\xea{\x17\xdfy+\xeasS\xec\xe96\xa2\xce\xb6\xdc\xb4?\x0c\xb4#\xe0w\xbab\xae\xa3\xf8\xb6h\xd4\xdd\x15\x1a\xa6\xa4\x1d\xfd\xaa\xec\x16\xe9',\xc3d\x82\xc5\xf4d\xe3|\xfa>^F^\xba;\xe0\xb6w$\xe3\x95\x87\x07{\xfa\x87/\x85\x86E\xf7\xa4\x7f`|dj\xacP\xd9\xe8\x1f=_z\xab5\x99\x99K\x98\xda\xa4\xcfJ\x8db\xa6\xdc\xb1\x0e\x83*o\xea\xeb+\xe9\xeb+\xcfr\xf3G\x05^\xe8\xee\xd5\x07D\x01r\xfbGu58\xae(\x0f\xd0\x18R\x81 \x03H\x05,<(*`a\x0b\xa9\x80\xd1\xfeQ\x85q\x9bG\x05\xfcC\xe2\xbd\xcd\xfb\xd1\xea\xbb\xdbm\xc1\x88o\xc1 '\xf8\xf8\xb3\xd5\xca\xc6tW61\xf7\xc6\x1d\xd9\xec\xcf]#L\xa6fu\xe5F\xfb\xb8F\xf3Ul\xf1\xbeb\xf3\x03\xbe\xcf-6\xc3\xa5d_tr\x18\x1b#\xdd0\x9a\x9177k\x06S\xab\xc0tQx&U\xeba)\xca\xb1\x9e\xb4T\x8f\xc6\xb5\x80\xd2\x10vs\xb8\x98\xe0\x11\xaf\x1a-O>I4~\xba^\x1da\x14\x9f\xfa\xc4\xd3W\xb6+\\Q\x95\xfe\xb1\x98S\\\x8b\xb3\xfbG}'?Zn\xce\x15\xfa\x86\x03Z\x7f\xa3\x03\xdav\xb2eu\xe9P\xf7\x14\xcb \xe3U\x7fx\xa1=\x1eO\x0d\"YHE\xb2\"\x85\xbct\xc8\nq\xff\x97U1-\x9eF\x8e\xb9:\x98\xa4\x8fm\xeeU]\x19\xd2tm;\x19b\xa0<\xe5\xbfQ\xfd$\x99\xbbF\xa0W(\x11>\xc2\xdc\x92{{\xdb\x9cv\xa9\x06E\x8eD\x8e~\x0c0\xe0\xf2\xa1nu\xed\xa6\x99\xba\x9a=!\xf22uW\x1bR\x9b\xca\x92\xf7\xa2\xb1\xd2\x90\x07\x86\x84\xd0\x067\xd9\xbdA\xd5W\x92\xfbP\x0e\xaa'4\xeeC9\xa8\n]\x89^F\xe3N\x94\x8as\x06=t\xf9v\\\x81b0\x0e\xbb\x1axg\x8d\xd0\xa8\x02] 4\xab@g\x08\xad\xe6\xdf\xa3\x07#\x89 \xb2L'\x1a\xb1\x84\xee\xae+4[\xc7\xf8\xbf$\xe4\xd8}\x87\x1dJ\x82\xd2\xbb\xc8\xed\x8b\xd7\x02,\x12\x95\x8a|?\x8eVABD1J\xae\x93hyElV_V*\x8c\xc2FQ_\xc6\xceD\xa5\"\xb9\x90Q\x14\xf3\x9cB\x87\xda\xbcA\xf5\x87\xd2P\xe7c*.;\x96\xb6sM\xc69\xc4>8\x05\x9f\xa2\xba\x9a*\x93\xc7?\x10^\x12Z\xfb\x1e\xdaT\xe7\xb5\x96r\xcd\xca\xa9\xdc\xce\xe4V\xa0\xab\x07\xa7\xd3P\x85\xc6\x03AWE\xbe\xca\x86j\xea]\x0e\xca\xebo\xa8\xc2`\xfe\xafV\x91\xe3\x87\x81\x94\x80\x96MT\x92U_mGovw\x1d;\xb4\x0f\x1d\x17,\xb1&\xa6(5[\xdej\x94j\xe6S\xfc\xf0\x15\x9f\x91\xf4\xe1+\xe5\xcb\xf0@\x15\xf7\x8f\x0c\xa1\xd4\xb6\xb7D\xe4\x82\x87\xb8\xbf\xe7\xf2\xdb)B\xb5\x1e\xd6\x18E#\xaeeW\xb7>p\xa6\x91\x8e#\x9d\xba\x94\xa9Kx~\xb4\xd8\xce\x1cSX[\xd8\\\x8a\xa9\xb9B`\xba\x01\xa9\x0f_\xb57\xd0)\x0b(\xbb\xd4\xc5\xaf\xd2\xad\x86PhV\xcb3\xfewXe\x8bs\xd5\x04\xbf\xdc\xf0\n\xa1A\xc6\xc8\xf8\xe1\xd1c\x99A\x13\xdb\xc7\x95%\xcdW+\x85\x9e;\xd0\x05%\x90Z\x90L\xac\xec\xd4\x90\x07\x17\x89\xd8\x9bh \"\xb8\xc0s\xb8\x85\xe5\x03\xc92\xfd\xa3\x8dn\x83\x1bL[\xb8\xf0\xba@I,\x9d\xa7^|\x96\x86\x1a\xc0)\xa6\xc1mJ|k\xe8\xfe\xce\xf8\xf3\xeex2\x9d\xb6o'c\xfbthwN'\xb3\xb6}:\x9ct'\xb3\xb6s\xea\xdc\xdac\xeb\xf1\xd4\xb1\xe9\xb3\xd3\xd6d\xe0\x8c?\x9fL\xa6\xb7\x93I\xd7\xf9\xf0\xd4\x99\x0c\x9c\xc9\xf4\xd6>\x1d\xe1\x1b\xb7\x93\xf1d\xea\x14_o?p\x9cj^3:\xdc\x9d\xc9\xc4\x9eL\x9c\xd3\xea3\x81\xebGN\x83\x1b\x8a\xe9\xc8\x02\xc5\x0c\xed\x1d\xb0\x9b\xb8\x98N\xf6y4#\x98RV:\x98X\x16r\x14\x11\xfa,.O\x17s\xa2\x8cLGa^GLq\xab\x94C\xff\x83>f\xa2E\xe5y\xaa3A\xc9!%\x18D\x8f:\xd16\x8bH \x8a\xce\x89f\xbf\xf9\x1a\x99I\x06C\xec\xab_\x05\x90,y\"\xf8\x00W5\x84\"\xb4\xa2[\xf1\x14\x026 \n\x8c\x11x\xdf\xf3\x17\xfa\xb8\x07w\xa6\xb4{\xbb\xfa\x83\xc6\xdench\xc3\x1ab\x86\x1b\xb6\xc5\x8f\x92\xe2\x8eK\xdct\x00\xbc\xcf\x11\xad\xd4\")\x9d\xc8\xef:5}\xc35\xfc-mj\x8a\xedL\xd8\xd4\xf4,\xe8\xf0\xae~\x00\xb9X\xe0s\xcb\x07\xe5Q6)\x82\x009\xb9\x15j\xc9\xbcd\xa0\xdd\xf6\xe1 \xcck\xafg'6\x19\xfbS\xa3\xdf\xceR\x90g1\xf7\xd8\xbf5=k\xa1\xbf\x8d\xfa^\xca/s\x97\x1eh\xc5\x074\xac\xd1>\xb6F0\x87SX\xc2\x10Z-{\x0ef\x031g\xa1s\xfc\x9b\xd9k\x17\xe6\xdc\xbekKq\x13\xef\x8d\x87\x06$\xbc\xbb\x97\xc2\xae\xde'doW\xef\xbf\xa2\xca5\xd9\xa6\xc8c\xe8z\xc4\x9cD\x98G\x01\x06\xbcj\xde9w\x9e\xa7\xbc@\x9d\xc2Z,1)\x87\xa8\xaaz\x8c\xdeu\xca7\x91J\xee\xd3\xfd\xb8\x12\xb9\x0e\xee\xd3\xd9\xbd\xdd\xaa2T\xa8\x83\xf4\xa9\xb2\xf7vu\xc4\xe8S/]tW\xdeu\xd3\xb0\xcd\xc2\x98W\xb3\xf5TMA\xcb\xcb\xd5\xaa\x9d\x8aO\xde\x95\x88\x98\xc1+\x13I\xcb#\x93B4\xc9\x13\x9e'\xe8\x0d\xeeA\x1b\x12\x0c\xbc\xe62^\x1c\xd0\xf9\xdeu\\H\xee\x8f\xb6\xc2\x15V\xd1o\xe44V\xf6eb\xde(!\xb4\x01\x05\x9e>\x0c\xa1\xd3wN\xf06K\xd4\xe9\xc0\x10\xda\xed\x88%TW\x90\x85N\x13\xb1\xe9\x91\x0b\xbd\xca$Et\xa4\x9d\x86\xbb\xc7D\xdb\xdbm\xce\xc4_#\xec\x98d\x12\xf8 \xe8\xeb%\x12\xb1w\xe9\xd2\x12\xe8\xa0\x10N`\xd8\x18\xc2\xc1<\x82=\x9d\xa8\xd2\x87\x9d\xaa\"\x0b\xe3\xbbt\x0f\x8f\x0f\x0f\x8ew\xfb\xbb{G\x07\x83\xdd\xfe\xfe!\xd9\xed\x1dm;\x01\xb9\xaa\xfb\x94\xf9^1S\x01\x13\xe3\xa8\x04\x8b_;\x01{\xcc\xc2\xbeu\xe8\xfa\xf7\x1d\xf8\x10\x1d\xeeR\xb1SR:r\xfc7\x92!w\x9d\x0b%^3\xd7&\xe8\xb4\xc3\xaf\xbcW*-\xd8\xf9|\x92\xb4o'I\xfb\x83\xea)\x83Ex\x1ew\xda\xd3\xde\xf5\xb8\xd79\xf6:\xf3i\xfb\x83\x9d@\x15Vv>\xef]\x8c{}\xcdS\x9f=\x8d\xc6\xbd\xce\xa1\xe61\xe5\xe0k/N\xc8\xcb0\xddvI\xe8\x8e\x91\xa3\xbd #`\xbeqR\x95\x10\x05\xb6yc\xa1J\xd3p=\\\xe0\xbf\xd6\xc6\x91\xe6\xd7\xcfN\x8b\xef\xecJ\xb3^\xe8\x89\xd9\xc9\x9e\xdd\x10\xa2\x9b\xa1T\xea\xbd:J\x11\xe4\xae\xa5\x19e\x19\x8f\xda\x95&\xd9e\xb1r2j\x95\x00\x87,\xac6K\x14\xa3\xdd\xc4xN\xf3E\x118\x85\xb9\x9dv\x93e\xe0\x13{\x80j\xa7S\x18\xc0\x10\x8e\xe8\xa8=\xa9X\x84}\xba+r\xf7\x15uK\x03\xb7\xdb\xab\x8a\xd8\x99V \xe7\xa6\x8f\xbdf!\xc9\xcc\x01\x19\xf7a\xb2\x12\xe5W\x86iC)4\xaf\x86\xb2-\x8aGL\x8c\xa1VE\xf1\xfcc\xd3\x172.\xdaf\xf0\x04\"\xe6\xe8\xd4\xc7\xb8q\x81\xed\x8d\xb3)\xbbH\xe6\x9c\x98\xf5\xd1\xa6\xd8\xe7\xdb\xae\x84\x9eN\x18\x82\x0d\xa9\xea\x98L\x08T\x1b\xac\xa7\x86)\xe0\nd\xf2\nT\xef\x1f\x89\x83\x93\xf0\x8d\xd0\xd2\xdeV\xab$\xd5x\x18\x1b\x86\xb1\x8e\x08\xf7e\xae\xe0\x18\x96\xa2\xdfz\xb9\xbe+\xe4\xee\x9f\xe1\x98L\xb7\x8f\x99ne \xc1\xec8~*\x99/\xb9\xd3\x05\x0b\x97!\x9clx<\x18\x92|\x1a\xcd\xb2%\xb1\\\x85\xc1,32,E\x8es\\\xbcs\xbd\x8a\x82/\xc9\xec\xcc[\xad\x97\xe4\xe38Z\x9d\xf9\x0b\xb2\xf2`$=|\x1e\x13/%\x7f\xe3\xd3O^\\c1\x16J\x0d\xbf\xfe\x8d\xd5\xb2\xf2R\x10\xceI,\xfdN\xd4\x9a\xb9\xa1\x1bH\xd7Wk^\x9eh\xf0\xa9\xaf\xa4H \x90\xe7\x87\xf6\xde>=n*H\x85\x8f\x0ev\x9dM\xa3\xb1\xc8|\"\xed\x16\x13\xc9e9\x95\x1a\xcc\xc8\xdc\xcb\x96\xe9\xb0z\xab\xf4;\xea7\x81kj%\"\xf3Q\x8e\x04&\xaa\xcc\xbb'\x90L)\xf3^= \xb2\xa2\xe7d\xe5\x05\xcb-Z\xc8\x12\x12\x7f\x97\xb0\xd5\xe8\xfa\xd1j\xa3\xb6x\xbf\xceg^J:i\xb0\"\xd6\xe6-\xa2\xaf\xc5G^J\x9cn\x1a\xbd<{\xcd\xbc@m\x8d\x1dBs\xda\xc5\xcd\xb9y[\xbd\xcd+=\x9f/#/}\xe0\xaa\x830%\x97\x0f\xdea\x1eD{X#T\x88\x8fX\xe5<\xee\xb6t\x8c\xe9r\x94fQ1\xf8\x0f\xb5\xfd2\xba\xab\x07\xd0\xfaN\\\xe5\xfel#\xb0{.\xc4]\xe6`\x11\xcco\x1c\xadB\x03rC\x8b\x9a\x82H|\x02|>\x8f\xe2\x95g\x88\\EI\x827\xc6\xfc\x91\xe7\x16\xb4!\x98\xa2\x0b\x90\xf6\x12\x92\xc0K\xec]\x90|\x9c\x85\xbecGx\x82\xb2\xd1\x1ek\xfd |\x1bF\xefBxs\xb3&C\xa0\xf5\xa5\xd8\xbb\xba\xa9\xf1M\xc40\xa7J\xa9^u)\x0e\x85\x9e\xf0%\x17\x97\xb2\x9fB\x1f\x8a\x9c\x14\x94\xc9\xe7E\xc6\xfd)\x15\xde\xe4\x9f\x98\xc7\xca8{\xcaR\xe8\xe2\xc5\x81\xf0\xf9\xadY\n\xb4yw9\xfd\xd0\x17\xf1\xb0\x08\xbf\xc4\x17\x10\x8dg/\xf0\xf9\n\xba\xdel\x16\xd0\xc9\xf1\x96\xdfo(?\xc7\xf2AJV\x86\x02h\x14\xe9\x06\xa1\xbf\xccf\xe43\xe2\xcd^\x87\xcb\x1b}\xd1\xb5\\\xf4\x87q\x90\x12ZV/\xe8I\xd3\x9f9e\xdc\x99\x11\xb2^\xdePz\xb6\xfe\xeb\xe4\xc6\xc1#\xff\x07\x1f\xc4dnma\xa5\x94\xe5\x8a\x92ou7\x08g\xe4\xfa\xf5\xdc\xb6\xfe\x8aU\xc9\xcc >\xefM\x16\xa2H\xef\x7f\x1c\xb0\xe0\xb7\x91\xe4\x1a\xae\x176kb\xec\x82hc.f\xc3 \xaf\x8a\xdb6^\x1c{7*\x97\x01\xedy\x01U0\x85\xb7\xf9\xc8l\xed\xbe\xe2\xc1\x06\x14\xcc\xae\xba1\xca\x9fY\xe56\x8b\xfc\xc9E\xf5+*\xd8-\x1cX\x8c\xaf\xa6t%\xe8\xdf\xee\x8c\xacc\xe2{)\x99\xe1\x8d/\xf9Q\xccq\x0d\xd8\x05\xb6\xea\xe3w\x02\xbf\xf0\xf9\x1a\xef\xb9\xcfh\x81\x11\xa46-A\x85B\x83\xd0\x8f\x13\xcd\xb4N\xbe\x03\xb3\xcav\xe9\xd7\x8c\x06W\x90\xbe\xee\xebQ\x01\xaa\x11\x0c\x94y\xf4\x1d\x97\xc5,\xb0o\\\x8c\xb2\xb6\x82\x11\xf4O`\x05O`\xef\x04V\xed\xb6\x03\xb3\xb1U\xee\x12\xa5\x95+:\xb4K}\xb78\xd2\xcfTT6\x91i\x8e?\x0c\x19\xe0\x94\xa7\xb2 \x12v\xbdl\xde\xf5\xc2\x9b\xd7s\xd4\x92\xb1\xaf\xdd\x95\xb7.<5\x9a\xee\xe6\xb2\xf8\xf3:\x9f\x08\x18*ME!\x11M\xe1\xd7\x07lj\x9c\xdas\xfa\x94\xd2q\xd2%a\xb6\xc2\x10\x8c\x82c\xcb\xdf\x87|\xa9B\xca\x0e\x97\xc1\x97\x04\xbb\xe7\xd8\xec5g\xdc\xa3uX\xf3`IX\x8a\x8d\x08\x1d\x9b\xd0\xa5I\x17/_U\x12\xdbU\x19\xbf\x9e\x96\x89\xe1u\x13V\xfe\xd1#\xa6\xb6\x17\x00\xf4h)\xb8\x01{\x8e\x1cF\"C\x8aO\xc6{\xd7x\x04\xd9\x88\xa1\xb2K\xcb\xdf\x1aO\x8d\xb6\xe1\xa9x\xff\xa5\x86\xa7z\xf8|\x13\x86\x19m\xc90\xa3&\x86\x19\xd5\xb3\xf25c\xba\x9b\xf0\xd4\x85\\4\xe7\xa9\xfa\xb23l\x99#\xb4\xbe\xc8\x15\xd26\xfd\xb3\x9b\x9ag\x97(\x86]\xaf\x96\xfa\xc7\x94\x86]b|2\xfd\xf3s|\xbe\x8e\xc9<\xb8\xd6\x97\xb8\xc8kH\xd6\x9eo\xa8\xe6\x1d\x9b\xda0[\xe9\x9f_\xe7\x87d\x03\x03\xcfj\x188\x9a\x07\x1c\x96\xda\xfc\xc7\xc1\xc5\xb3&.\x8e\xd1Y1l\x8c\x15F\xa9wI'\xc7b\xfe\xb1\xf69\x9c\xc29\x15\xcb\x87\x16\xba\xb6;\x94A\xb8p\xc1\xf4\xf37c\xfa\xdc\xba^-\xc3\x043e\x9f\xd3B\xf8\x13o\x03^\x18\x04\x1c\x99)\xa0[\xe5\xdcD|i\xe99\xc5\x07J8\xf0\xef\xed-\\\xd2\xff\xbez\xef2\x08\x0f\\'\xff\xa0e\x18\x96\xc0e\x97\xc7\xe0\xcd\x85\xbf+\xee\x95;u+\x1cbIy\xc3R\x8dZe\xe4\x0c\xf43\x17;\x90\xe5\xa4\xa2\x953?>\xe4\x08U\xfd\xbe\xf8h\xf8\xd3\x8c\xb6>\xdb\xbau\xc1V\xb6n]L\x03/9u\x01%\x9c\xa2\ns\xab\xe7^\x9a\xc6C\xb81T\xee\xc2\x95\x1e\x1b)e?3\xb8XB\xc1\x8a4\xabb\xdfsY\xce6\x9a\x15\x17\xce\x0c\xebb\xdfsa\xb6j\x9f\x97R\nm nk\xd3\x12\x01\x9f\xfa\x17zq\xbbA\x9c~F\xc5ii\xcf\xd0\x9d\xb8\x14\x1b\xf0\x85Y:\xa5}{Q\xb9jh?ct\xa3\xf5b\xfcL\x12\xbcooa-?(Dn*\x8c\x1b\xa6\xab\xd4\x0e}\x8b\x11\x89\xfc\xab\xe8!\xff\xdd\xa58\x1b\\di\xed\xb2\x89\xcf\x15\x8f.YF\x05\xac\x0b\xa54\xda\xd9\xfc\x971\x05K\xf5\xf3\x85\xe8_-\xd3\xae~\xde\x8a\xb78F\x99)\xbd\xf8\xdc\x8c\xf3Q\x0br\xf8l\x9a\xb3,\x14\x9b\xbe\xa0#\xf8\x82>\x91\x80\xcb\xf13<\xf7\xe0\xdf\xf2\xa3\xb7\x14\xfe\x96\x0214f\x82sQ\xbf0\xb5\xa9^\xe4O\xb9\xb3#P;\xef\xca\xce\xe9\xf2\x0cV\x84A1\x00\xbbT\x86\xc1Mv\x19\xe9s\xc5\xe3f\xa6lt\xcd/\x94\xd1\xe3%\xa5\x14|\xa7 \x19\xf5\xa3\xd0\xf7R\n\x1fJt\xf5e\xc3\xb4\xd5\x91Fq\x98\xe4\x0d5\x11\xea\xb2\xb49\x04\xebYx\x93.\x82\xf0\x12|/\x84\x0b\x02\x0b\x12\x13\x83T@;\xedo\xca\x11\xaa\x0d%\xa6s+%r\x0f\xc8g6\xa0\x91|\xe6\xae\xcb\xf8\xbf\xe4\xae\xb1\x12h\xc63&\x94\x17\xf5\x1d]\xd4w\xecT\x96\xb0\x80kl\x85o\xe0\x14\xc6\xfa\xbe\x1b\xfb\xfd\xde\x85kZ\xd1u\xb5\xeb\xef\xb5v\x90\xa5\xd9\x17\x81\xca;\xeci\x19K\xd1\x08Z\xd2s\x05\x82n8vX\xb5:\x01\x1aJ\xfc\xa5\x17{\xb4\xc1!\xb44\xd7\x1b\x83pF\xc2t\x08\xd6$\xad\xdc\xae\xab\x9a\xcb\x00o1\xd4X\xa5h\x7f\xa2\xa2?\xcb&\x13W\xa5<\xc7\xa9\x06\xab\\\x0d\x87\x96<\x05\xf6\xabn1PxK\xec\x0f\x9c\xeeY\x1a\x13O#\xfe\xa3N\x8c~\xb1\xa4\x15\x83\x8a\xf5Jo\xf5\x04\x919\x80\xd24\xcd\xc9\x01=\x05\xd0\xa5\x11\xc7\x1e0\xd1!\xbf\x92k\xb3\xf7\x9c\xee\x17Q\x10\xda\xe8KgYU\xdb\x9a\xf8$\x94\x8c\x19\x84oC4\x08\x1b\xbdD\xd3\xb1\x142\xe0-\xb9I\xec\xd4\x19\xf7\xa6SdyI\xf7\x9c,\xc9\xaa0\xdbr\x80\xa0\xdc\x91\x9bC\x02?\xcaB*\xfd\x84\x12\x0c1\x89\x0d\xab\x0c\xa3-{20%q\x9c\xadS\xcc\x00'\xc0\xfa\x19\xf3\x99\xd3\xbe.4\x14\xf0S2\x957\x95\x87\xf9z\xad\xcd:\xde\xf24l-\x02\"y\xab\xf5m\xa8~r3g\x1b\x1e\x8f\xac\xc7\xd0f\x0epmxl=6\xbe\xf8\x1e\xbd\xa6\xc7dj\x14,7 \x93\xe2z2\xc7\x08%\x94\xad\xf8\xe0\xa5\\\x81B\xfa\xbb\xb9Pv\xc6\x18\xd1\xca\x0c\xf7\x1a\xc4'\xe9\"\xcd\xa48\xb6\xb6\xf9\x0f\x0cty\xee\xcf\xbc\x14\x95RK6\x9d\xb6\xf5\xa45~\xfe\xd1\xb37\xcf\xc6\xf4\xc0)J8\xb9\xe3\xde\xced:\x99>\xdd\xb9t\xc1\x9aN\xa7\xd3\xa7y\xf1\xa7xx\xb5\xa6\xd3\xa7\x16V\xcdW\x13Q\xdf\xe7\xa1k\x96\xd2=\xaed\xc3\xf8\xc5\xf2G\xbb\xb7N\xc1\xc2\x01!T\xd9YpJ1\x90\x0f\x19\x86\xa2\x0b9\x15\x816\xf4\xf1r\x81\xbdd\x89\xb5]T%\xb5zyo\xd1\x13\xd3,T\xbc\xc77no\xa5\xc1\xd5\x8865\x0b%L\xea\xc6w\xf3\xfe$\x9a\xee\x189\xb3~F)E\x19B\xa4\xdf\xd49}\x18\xd2U\xd3\x16\xc9\xc5\xfdd\x08s\x83F.\nS\xe4l\x06e\x13#aC\x08M\x9d@\xca5\x04\xaf\xeey\xd5e\x15\x94\xa9xo\xe0#^\x1d\x1f)\x11\xf2\xc2HL$\x97&\x8a\xcf\xba\x08\xf1\x82 \x12\x89\xcc2\x0f|\x0c\x9fK\xa7$\xbf\x9d`\xa6\x9a\x81\xd14\xce\xd3X*\x95\xd5\xed\x1d\xe1$W\xbc\x94,\x82yZ\x0d\xa8#\x7f*\xc6=\xadKX\xb5|d\x07N\xb3\xc2\x8c~p\xf25gp\xf1\xd1K\xe9z([\n;F\xed\xf5)\xce;\xe3yB\xa1f\xf3\x94\x0b\xa7`=\xd9\xa1T\x8d\xffn\x83\xf5\xd4\x92Kq\x06\xfa\xe8\x11\xb4BZz\x12\xf2\xc7\xe8W\x8c\x17\xc9t\x1b\xcf\xbc\x8aQ\xa3\xd9\xa3\xd5\x92\xf1\x04\x9dr\x8b\xdf]o\xbd&\xe1\x8c\x8a\x0d\xae\x8cO]\x06\x0cJ@\x11\x1d\xccn\xf5\x1c\x17Z\xbdMH\x04]4\x8e\xc9\xf9\xac\x95\xe7K\x9a.i\xa2\x8a\xdd/,\x07\xa7`\x01++=CI\xca\x02\xcb)\xde\x8dq\x85D\xf5|\xfaqo\x08\xd8\x8eiM\xc4\x02\x97\x96\xa5\x15W\xb7\xa4xC.\xa8\"#\xae\x0c\xde\xbd3]\x87\x82\x1a\xa7;-\xcd\xd0\xd0\x0bD\x1a\xf4H6\xa8_9\x0d\x0b\xd5\xb52Q\x16\xf41\xc5\x08\x00\xdd\x04eh8e\x99Px\xaax\xb3\xb5\xc3\xb2\xcc\"\x9c\x89\xcc\x0bW\x00>\xa3\xfc|,A\"\xda\xac\xf894\xb6\xb1\xe0q\xe4\xcd[ef\xe6\xfe\x0b\x863\xe4:}\x13\xf8o\x99\x13J\xba\xe5N\xbc\xaa\x95\x0f+\xc4\x0e\xf5\x1e\xf6\x1c\xda#\x96\x8c\x12\xf2\xd8\xab(\xc9 \xb7\xc79\xe7\xd7V{\xa2\xd0\xb2\x89\x08\xe3\xc1\xd2L\x1agv\xa3g\x94\xf8\xf8]\xb2\nR\xdb\xa2\xd2\x99\xa5\xb5\x9c\x8a\x0f\x15P\xd8\xfaoHT\xeb\xe6\xf1\xa6v\x1e=\xfb\x8a'\xa0[\xbb\x98\"\x91\xb2\xbd\x9e\xa3\x0f\xed\\\xd3\xca\xa5q\xf8\xccf\xdf0\xcb\xe9\xb75\xcb)\x95\xf58\x88\x843\x0b\x7f\xc6\xc4\x9by\x17x\x00\xa7\x04H<\xf7\x97QB\x0c\x91\xee@\x7fl\x00\xc3rT!\xc2M\xa0y\x1c\x0b5=$p\x94\x08\xbb\x92j\x02q\x1b\x8f\xee2\xd4\xc5s\xae\xbe\xe6+\x12'\xa8\xd3\xb0\xfa\xdd\x9ea\xd7\x93\xd0\x8ff\xe8\xe1\x19w\xc5wFr)\xbd\xfa^\x8a\xd9\xd4%K\xb2b*\x85\x02\xf6\"\x87\xd5b\x9f\xd8\x87\xfa\xe1\xa2\xc2a\x08\x99\xcd\xb4\x81E\xecD\xbc\xc8\xc5\x82\x15\xe6\xbe\x06&%\x0c=\x0dm\xe2\xf5 \xc2\x9a\xcb\xf2@\xa2L\xe5@\xba\x88\xa3wH\xc61(\xacm\x85Q\n^\x92\x04\x97!\x99A\x1a\x81\x07,\x14uK'?\x88\xcf\x95\x94\xaa\xbb\xde\xdePdG\x96\x143\xe6\x8a=[\xea-'\xaa\xa1[\xaa\x81\xa9\x80\xdaT\xc0\x10\x94V\x0e\xbc\xdfD\xdb\x08\xaf\xdc\xd6\xc9\x8a\xe2c\xa2R\x86#\x1f\xa5y\x9b.\x89\xc4p\xd9\xee\xa1Ccv<\x91\x01\x9a\xca\xb9\xe2 \xed\xe9\xc6$S\x9dW!$\x96\x91=\xffU\x8a\x1a\xba\xbbg\x88\x18*\x0fG\xb0\xf3\xf2\x00\xadG\xd6\x10\xacG\xdej}R!\x8a\x8f\xad\xc7\xf4\xc9\xcffQZ}d=f/\xad\xa3Dy\xf4\x04\x1f-\xd5w\x9e\xe2\x83\xcb\xf4\xa4\xa0\xa3\xd2\xb0\xb7\xbal\xc5\x89\x17\xa7lH\xbcru\x8f=~d=y\xfax\xea\xec\\\xd6LF\xa5\xc2pL\xaaI\xb4`\xb8m(\x8a\xd2%\xba\x93\xd2\xbc\xf3[\x11\xfd}\xa7\xfb\xe2\x8a\x84\xe9\x8bU\x90\xa6$\xd6)\xf9\xd5\x83t\xccc\xa1.\x02\xe5Z>\xfd\x84\xf6\xee\xbec\x07.&\xd3\x0d\xba\x9f\x15\x14\x93\xb6x\x80\xc0\x1f\xc6A\x9a\x03\xf7\xf6\x8f\x11\xf8Q\xb6^\x92k\x06:\xe8!\xe8M\xec\x85\xc9<\x8aW\x1c\xdaG\xe8\xf7\xbd$y\xb3\x88\xa3\xecr\xc1\xe1\x03\x843\x9d8;\xd8\x05r\xc2\x8f\x00\x9d\xc1j'\xffJ\xca#o\xd2\x9c\x07\xfa\xd3h\x8a\x06a\x1c\x0e\xbb0\xc5X\x0dZ\x89\xe9\x1b\x18\x1bh\xede \x91\xbe*\xc7&}\x93\x91\x96\n\x85\x05\x1f\xc2\x1ac\x92d\xab\xd2\xf7\xdaSY\xd8\x8d\xc2\\$\x0b\xd0\x81\x0e\x01\xb1\x17\x84\x96\x0b\x11B\xce\x83\xe4,\x9d\x05\x11\x957\xe4\x81\x11$*\xb7\xb7`\xb3j\xa8\x18\xe7\x82\x87\x02\x11\xfd\xcd\xc46\x17\x92\xaa\x16\xef\x8a\x874k\xf5M\xf3\xebi\x07\x9bac\x19\xe7\xb8)\xa3c\x9b\xcd^\xb2A\x85\x86{\xe03\x92\xa4qt\xc366\xff\xb1i\xb3\xbe\x9en\xa3\xaf\x90\xed\xb8\xdcN\x1cw\x97A\x92\x92\x90\xc4\xcf)\x1f\xc2\xfd\xe4\x82E(3\xb5\x1c\xc1_\xab\xf4V\xdf\xe2\xdc\x88&\xab\xe8\x8a|\xc2\xdb\xa9\xac\xb9\xf2PZ\x7f\xf5Uy\x9d\xab\xcf\x8a5\xd7\xbe\x89#\xa2\xc2\x92\xaeU\xf9\xa9\xa9\xd5ym\xabsm\xbd\xc5\xd3\x9a\x9d \xc8-\xc3\xe4R?\xab\x10\x19\xdb\xe7\n\xb6\xcf\xf3w\xca\x10v\x94\xa1\x04\xc8b^\xceM4\xdca\x8ec5d]\x7f\xab\xaf\xa0\xeaG=\xa7\xcb\xc2\xe3\x96\x19\x9e0\x1e6\x86\xc8\xa9\xa2R\x8ee\xa9\x16\xcbZ\xcd\\\x0d\x84\x00i\xa7 %\x19#\x8e,E\xbe\xb9Y\x13.I>\xf7B*LR6\x03\x1e\xf8K/I\xc0K\xc0\xcb[\xd2\x1c\x0b\xdf\xf3\x0d\x94\xcb>\x0b\xe2\xcd\x80E\xa3\xe1\x90\xd4\x0b\x96e\x08?\x0e\x8c\xaa^\xcb:$I\xd5\x8c\xe6\xf5r\x9a\x10m\xf5\xf3A\xb7\xa21S~H\xaeS\xa6\x8eR\xc7\xa9\x8af\xf2P\x9eb\xc0\x92|\xb8\xa8\xf5\xc1\xdb\xc0\xc3\xd2\xac\x90\xf2\x94\x10\x17\xdam\xa9\x9a\xf2l\xb8\xa5\xb1g!\xea\xbe\xbf\xfd\xe1\xe7\xfd\xddd\x0ex\xec\x0ci&\xd0\x11\\\x1ec\x051\xb6\x19\xb32b\x13}\xe7\xe2xQk\xddy5\x15'\x1a\xda\xa3.\x9d\x91Z\xbf\xc3\xbe2\xc4\xd3\xd2\x80\xaa8^Y\xf2\xa2%:\xbd.t:RU\xda\x98\x85u3\x82\xb1\x0e\x9bf\xa4\xaew\x0d;\xb0\xdc\xda\x17Q\x106\"\x1c\x9b\xffQu\xfe\xc5E\x0f\x8d\x17s)\xean\xdeY\xe6Zl1m<\xae\nO\xcdM\xe7\xed\xc4\x81\x10\xda#4\x81\x13\xc3\x9a \xaeR;\x7f\xe8{u\xcf1\xc5]o\xb9\x8c|\xbbg\xf0cV0\xa6\xd0\xf57\xa0]13xj\x0eXl\x08\xde\xde\x0f\xc2\xc4\x9b\x13;\x85\xa7O\x9f\xa2v2+O\x9fG\x97\xf3\x04\xb2\x13\x07'.\xc36\xd8\xacF\xfc\xe2\x04^\xde\x8e\xd67,\xb0\x01}\xa5-\n\x96\xa2\x18dl\xd2MS\x1c)S\x9c\x03\xdeSI\x0b\x03s\x06\xdd L\xd6\xc4OK?\xba~\x96\xa4\xd1\x8a\x91\x89\\9\x93/\xd0\xb8ZpZ\x87\xecb7\xe7/i\xd4jlXC0\x92\x1c}\xb8\x1e,.\x05z\xcfMo\xec\xe2h1^\xe3\x89{c\x7f$\x1d\xfb.sw\xbd\xddF+\x90\x88\x0fS\x1cu\x13\x92\xbe\\\xad\xc8,\xf0\xcc\x1e\xae\xdc>\xc3|\x8cx\xcab5&\xb3\xfc\xf1k\xaej\x007\xdb\x98L3\xc0M7iw\x16\xf9\xa8(3\x97[\x97\x12B~_ \xc9k\xcc*\xa7}`\xcc\xa7N\xab\xc2\x8clk:'o\x82\x15\x89\xb2\x14NaM\xc9\xb5[D\x8c\xe7yk\xa6\xccq\xfa\xab\xf7\xdd4bW\xdb\xf9\xe9[$\xb6aQ\x8b\x9a\xe8\x88\xf8Hf\xa0Z\xca-\x7ff\xb6&\xaa\xaf\xf8\x98\xf4[0\x94Q\xa7\xae \xb4\xa1v\xd7Q\x92~\xca\xb3\xf9\xb3\xac?\xc1\x8an\xc93?\x0e\xd6\xa9\xd1\xddG|\x04\x11\xd79\x08V?x\xcc\xefF\xe1\x8a5Woh\xcf\x85\xbf\xbc|\x13\xd3\xab~\x88\xde\x84 \x7f\x18o(f\xc0\xb6,\x17\xac\x0f-~\xa8(\x1a\x0e\xab\xa1\x94K\xb5\xe8W\xc2vP!\xc5\xab~\xbe\xf0\xc2\x90,\xe1\x14l\x1b\xa3\xa7\x90wP~\xe4t\xe9\xbc\xf7\xf5\x03\xaeE\xae\x99\x9d\"\x057\xa9<\xb7\xc0\xd3\x08;1(M\x8a\x01\x0bQ5\x86\xc6E+\nc\xe2\xcdn\x92\xd4K\x89\xbf\xf0\xc2K\x82i\x92\x97\xa3\xddvD\xbe\x8b\xe2\x0e.Z\x06\x0d\x97\xbd@r\xfb\xaa\xdf\x85\x94\x1f_x\xfe[\xe3qV|\xbc\xf82\xd1\xf9\xdb\x89\x8f\xe1\xae=\x14l\xc8\x1f'S\xa6\xdf\x8e\xed\xc4q!i\xb7M\x08\xb7fG4y\xed\x16J\xd9:\x1f\x82\x85y\x89Yzw\xf0\xab\x81\x9b\xa1\xa1\xca\x1a\x1f\x15T\x8e::\"\xa1\x9f\x94\x86\xbb;\x02[h\x17\xeb}\xf4\x1a}\x9e\xe7\xdc\xf5\xa6\xaeL}\x9a@\xf1im\xb8{\xe4O~:\xed\n4k\x16p\xc4'\xc6\xf7(\xd6\xd5\xf7^|\xf2\x14P\x0d\xba\x0b\xdd\x07\xfd\xae{f\xdf[\xdd\x87\xd4\xf9O\xea>\x0d^\xda\xd5\x0f\xf6\xa9\xbfm\x9f\xe2qo\x93\xbbU\xf2\xe7.\xfd\x1a\xdc\xa5_.\xc4\xe3\xfe\x8f\xa3w\xbbw\xef\x1d\xfd\x7f\xf0-\xf7\xb1\xd1\xd5[\xf7A{\xfd\x12U\x0e\x1aw\x0f\xddG/Q\x97J\x98\x84\xa3\xbc\x00\xcc\x83\xd0[.7\xa1\x0f\xccp?\xdf\xe0\xbc`|\xba\xa9\xdfoE\xb7g[Y\xc8\x02\x02\xcedY(!\xcby\x11\xa9?\x0fN\xbc\x08\x12\x0c\x83=\xc4\x02\x92\x0d\xb8\x949\x14y\xb1\xd9\x15`\xf3[Q9\xfb0\x90M3\xf1E\xdd\x03\xe9.#\xdf[\x9e\xa5Q\xec]\x12)\xa2\xa3:)r\xfeTm\x855\xef*\x10aQ.\xb7\xaf\xe5GBa\xc8sn\xa07\x99\x95\xc6\x19a\x87\x7f\x1e\xd2.t\xbai\xf4I\xf4\x8e\xc4\xcf=\x8d\x01Y\xfe\xb5q\xf0R\x10wal+\x8c>\xe2A\x88\xd0\xc0b\x8a\xbd\x0d\x92\xb1\xa9\x1a\x15\x13\x8a\xb14\x9eapm\xb4ai\xe5\x12\xa1m\xa1\x85\xa8\xd2\xb5\xaa\xef\x91\xee\x1e\x81\xf8\xd0*b\xcf'\xa5*\xe0\x14\xfc(L\xa2%\xe9\xe2C\x16\xc0F\x80\xdeyq\x88g%\x1c\xa4\x1aD\x0f\x8c;-W\x170R\x93\xa2I\xaap\xc4j\xda\x87\xc6\xad\xb4\xd1\x1e\xd2+\xe2J\x19\x96\n\xb0\xe4\x06r\xac\xcb\xa3\x14\xda\xfb}\xed\xad\xcfH\xdd\x1e\xdc\xb6G\xe9\x82d\xde\x8b\n\x1c\xa2+\x15\xa9\x01\xc9\x0bG\x12MpS\xac\xb8\x1b\x84\x0b\x12\x07\xd8yt,q%\x98\x1d1'\x93H\xd2\xab\x9f\xa7\x92\xcbH\xddd\x01\xa2\x06\xb7DT\xdb\xde\xc2\xb3\x86.\xcf\xe1F\xcbS~k\xd0\xbf\xc3K\xfd\xfe\x81S8\xc5\xdc\xf1}\xc9}f\x93\x1a\x9a\xec\xcd\xfdc}\x16\xc4\xfe\xb1>\xcf\xcd\xdeAs\xac\xf6\xeaBqK\x04\x0bH-\xc7P\xd2\xeb\xcc\xb3\"zU\x8c\x97R\xd1*g\x13)\x8a5\xe6\xd6\xcb\n\xebWau\xe8z\xc9M\xe8\xf3\xe4\xadYw\x1d\x07\xab \x0d\xae\x08\x9c\xe6.0pZn\x02\x87u\xbc\xef`6\x0c\x1e\x03\xca\xd6\x948pl\x82w\xe5*\xcf\xa4zi\xb1C\x07S\x0e\xc8\xc0\xfd^\x9f\x01\xe9\xd7\x01V\x93w\x15\xfd~\xec\xfd\xde.\x82\xd6,!\xa7\x00\xee!p\x16$\xeb(\x07\xf6\xd1f\xd3]y\xd7\xcf.sX_\xc0\x04\x80\xbd\x19\x939\xba\xa7\x90X\xc0\x0f\xe8\x8e\xa3\x88\x92m\xb9k\x9a\x10i\xef@\x17\xb9\x1du>\xdeE\xa2\xa2\x12>\x99/#9\x97\xf5f\xe8\xc4\xd1$H^y\xafl\x8c\xfb\xcf\xd2x \x96\xa40\x82W\x18\xc3\x153H\x0d\xd8\x9e\x92\x07\xc6\xcb\xc9l\xfd\xe4\xe8\x02\xd9]\xb1 v\x89\x0b~y\x81\x03L\x9dBe\x1f\xbb\xc8?_&\xb9\x8eDv\x04\xb9\xd1\xb8\x83\xbf^\xd3\xc6\x13x\x8c\xa5\x1f\x83\x17\xce\xe01/\xfe\x18|\xe6\xe2sA K\xd0]\xfc\x92\xa4\x0b\x12W\xb5\xe5|\x19\xcbazr\xd1\xc8:?\x17\xd1\x19\xce\xcf-\x16\xaf>\xec\xce\xa3\x18\x9dp \x0cYf)\xcf.B\xe3\x93\xfc[X\x0c#\xe24\x9f]\x0c\xcbh\xd5 s\xd7\n\xa8\x8c\xd1(A\x87c\x82q]R\x1e\xa8\xddW\xee\x13\xb1T\xce\xe7\xe7\xeb8\x9a\x07K\x12\x9f\x9f\x03\x8f\x14^@0$\xa6\xdf\xcd\xd63/%/\xc2+\xbcJ\x9d\x87\x9fx\x90\xbd\xd3\x88\x93\xbb\xba\\\xbcBU+\x89Y\x17A8S\xb1TS\x90.\x95\x8a\xb6r\xe2\xff\xd2\xc3\xa4x(y[\xf1u\x7f\x99\xbc\x08\xb3\x15\x89\xbd\x8b%i\xa2\x07\x9b%j\xd0\xde\x84\xa2\x934g7\xd3\n\xbc\x1f\x18\xe27\xacK\xa5vk\x0ew\xc5n\n\xec\x90\xa58\xf3\xf9q\xdf\xb3)\xae\xa1Ux\xdeM\xa28\xb5\xb5\x04v\x8d\xa9W\x11\xf9\xd7\xb8\xdc\xc3\"\xfbL\x83\xc6}>N\xa7\xc8\xcf\x99\xc4\xed\xd2\x01\xca\x93e<\x88\xf1\xde'\xecE\x96R\xf8T\xd4\xe3\xbb\xb0t!\x1c\xa7S\x17R\x91gD{\xa3\xdctX}\x10\\\xde;\xacRR!\x81\xea\xf3E\x1c\xe9\xd3E\xec\x1d\xf5\x9d\xee\x8a\xa4\x8bh\x96\xe8(\xed\x9e\xf2\x1eg\xd6\xc7\xba\x04\xd3\x9a\xbd\x80g\xc2r\xc9\xf9\xa6\xbbfYl\x0cff,?\x96\x1c\x14J\x89\x1d\x94\xf0\x9d\x0b\x94\x81\xa3J\xcc\x80\x19B\xc9*hL\xdd\xa5?H\xa1o\xb7\x0bW.\xdc\xb8p\xe9\xc2\xca\x85s\x17.\\x\xe7\xc2\xb5\x0bg.\xbcp\xe1\x99\x0b\xaf]\xf8\xc2\x85\xb7.\x86\xb1Z\xe2\xe9KO\xf0\xaf\x98T\xdc\xe2\x020%\xe5\x9cw\xe7\xbai\xc6\xabS\x89\x9eK25\xc5\xfb3\xcct*\x831\xb8\xd3\x08\xce\xba\x97$e\xd1\x87\xcf\xba \xfd\xba\xc2\xaf\xcc\xac\xe1b\x94\xce3f>q\xdcB+\xd3\x8dI\x12-\xafH\xcc\x82\xcc\xbe\xe5\x9c%\x87\xd2=\xfd\x05\x8f\xbc\x144\x04a\xe1\xfc\x97\xfbU\xe5\x04D\xa5\x1e\x94\x1fcp3\xb4\xd6\xbf\xb5#\xa7\xe8\xd2\x88\xf1\xe8\x1b\n\xa4Et\\\xf2%]\xad\xfc\x1c\xfe\x82\x16\xcb\xb8W\xf2%I-\xdc\xb4\x11\xf3\xc5s\\x\xa9\x8dhO\xfb\xc0\xd2\xf2a\x94\xe4\xc2\xfbp\x9e\x93\x13v\x86\x8f\xc6\xbd)\xeaQ\xaap\xd1\xe7\x11\xcb}c\xd6\x08iF&D\x8b\xd8\xb6\x9e\x07\xb1\x9f-\xbd\x18\x82\xf0*\xe2\xaa\x1c\x17\xac\xe7/?{\xfe\x83O\x9e}v\xfe\xf2\xd5O\xbd~\xfe\xec\xcd\xcb\xd7\xafLVwZ\xeb\xa5\xad\x89_\xfe\xbe\x08i]3\x8d\x0f\xd4\x13\xbe\x1a/\x99=2p\xe1\x99\xbc.\x89X\x17n\xc1\xa7bH\x99|\xbap\xe5\xe4y\x07\xe9\xfe\xa8\xd5\xb6\xe1\xe1Y\xbf\xaa\x86\xa1\xb2{\x02\xb5h#\xae\x12\xe4\xa8[\xe0\x90\xc1\xa5\x10\x8dm\xba\xa0\xc9\xa7\n\xbe\x14\n3\x18V\x90\xccqMh\x9ew\xfa\x81\x17\x89\xf9\x03\xa0\xbf\xb0f\x99\xf2\xfb\xe3\xb8VD\xcdu.\xa7\xfa\x7fXR \xdf\xefD\x8e\xc7\xf5\xc4\xb8\x0b\x8d\xd3\x14\xd4.kP\xa6\x06\xba\xcc]\xb8M\xefK\x0dj:\xf7\xc0\xcb7\x0e\xe8\x1e\x0b\xb5\x8b\x17\x88u\xa3\xe2\x97\xe2\xae\x9bi-\xffQ\x1c\\\x06\xa1\xb7\xd4Z\xfb\x85\xb0>\x84/\xd4\x87\\\xd2\x7f\x85\x91\x83\x90\xdb\x8b\x9fj\xd9K\x92nr\x0d\x94\x0f\xf2m.\xe7\xbd\xb5S\x07\xb9\xdc)\xdc\xb0@\x0f\x1c)R\xba\x18*\xd5S[^x\xc9\x16-\x1b\xd6Q\xe3\xda\xa3i\x8a\xf1\xdbMZ3\x900`\xfd\xd5\xf7\x00\xe7\x04\xfd{W\xccM\nF\xf0\x12EU\xee\xbe\xc0~\xbc\x96\xd1\x82=\xb1P\x9a%\xba Q\xea PL\xd8 #\x8fP\xac\xbc\xd4\x0f\x03\xcf\x83\xe7\xf4\xc8'\x89Fn\xde1l\xc5\xdatb\xa3R2\x9f\x9aK9B\x9dC7\x7f\xae\x0ey\x81F\x0f\xccI&\x83\x9f\xe5`>K\x85\x1b\x95\xfdZD\xf1X\x94T\xfa\xfa\xb8\x15j\x7f\xe9\x18\x870S\x1f\xe4g\xe1\x0d&8e\x92-\xdf\x9ej\xb3\xd5\xed}\xa1\x8aj\xe6{,n9\x87\x8e\xba\x86l\x0b\x86\xb8\x05\xc3\xb2\x8cFP\x92 \x99\x8c\x96q)\xb3j7\xde\x92\xa7\xe7\x8an^\x1bg~\xe5*\xa1iki\xc8G\xc1T\x18\x17\xc9[\xa8\xa6=w1\n}P\xefF\x8cH\xdf8w\xbc\x1b\xc5\xd09\xcf\x1d\n~'Mk\xcaW\x8dNhA\xddB\xd6Y\xba\xa3U\xbd\xcb\xf5\xb7\xd6\xcf\xac\xbb\xf0\x121\xf7\xda\xee\x16XP\xd3q\x8e\x18\xb4\xaeT\x93pum\x7f\xa1\x0b\x8c*\xeb\xbe\x86\x10a\xd8*#\x89\x8d\xec\x0b\xcdSN\xbb\";\x13\xa7\x1d\xb5\x15\xe4D\x91\xfdN\xf7\x0cyEd_\xab}\xcer\xc8\x83\x9c\xf0\xfb\xc7\xba\xfc}\xf4\xe4\xaf?\xe1\x0ft'|\xd4Kv}o\x9df19K=\xff\xed\x9b\xd8\xf3%\xb6B\xe48\x1d\x8d\xf6\xa8\x90;#2u\xa7.\xf7\x98\x07\xe5\xfc\x1fj\x89\xa4\xa2c\xd2\x9e\x85#;\xe1\xa1\xb6<\xc6\xd4x4R\x91\xb8\x1f\xed1\x89\xc8\x14\xc9n\xe1F\xa2l\xd8\xf5\xa3\x19\x8a\xddxO\x87\"\x1a-CJ\x02\xcf=\xd6hs\xa3\x02\xe3\xc0\\I\xc1\xe2\x84ln[`\xb1l\x88\xad\x8f\x882\x8f\xa2!X\xb1\xf7\xa5U\xa5Qj\xd9\x0b\x8a\xf1\xd6\xec\x9d\xb7A\xd94\xfe\xf2f\x08\x16\xfdS\x0d-\xecb\x80\x9a\x08s\xb7]x1\xcb\xe1\x16\x7fy\x83\xb4\x81ve\xf6\xce\xc3\xf7\x1eXo\xbbgH\x8d\xaaU\xdc\xa2\x11g\xe5]o\xa0\xd41\x18\x08\x8a[8\x91\xe2o\xeb\xc2\xa0\"w\xa3\xa3n*+:Q\x1a-yhk5\x8df\x17\x9et\x1cS\xf9\x9d\x8cc\x8d\xabi\xa3\xbfN\xc8\x02\x15\xd0}\xdd\xe8{\xc1\x04\xfe\xfe d\xf0\x04\x92\x13h\xb73v\x7f\xad\xd8\xa0\xd9\xd4\xc5\x80\xb7yh\xa2jv\x82J\x1c\xb407\x8bh1\xfd\xdb0\x1c\x1e\xee3\xc3\xa1\xa4ag\xa6\xc3\xc3\x83o\xdbt\xa8_D>V9\xae\xac\x95\xdb\xd4-\x8c\xb4X^\x87\xdaE\xd5;`=\xb0>Y\xe1\x1eA\xd9d\xd1\xb4\x9d\xaa\x1d\x17\xe6f\x8c\x84\x9b\xaf\x0d;\x9em\xebzr\xa7\xbek(&oB\x1fR\x9d]A\x1b*Ks\xc7\x81\xe3\xb0\x1f=\x82`,\xec\x12\x98\xbe\xa1\xf5 f\xd6*\xfe\x1f3\xfc\xe7w\xe5J\x17nS/\x08\xf9n8\xea\xddc7\x88\xd9\x96\xc9\xfc\x96{\xa5\x8e\xd7\xc5E_1\xe7\x88\x08\x17\"\xa06r/\x91\x9d\xbb\xfal\x1eE\xd6\xc3\x18\xda\xc50\x95\xa9\xe4wa\xee\x8a\x0d\x95#b\xc9\xb6\\NDy\xdf\xceW\xee\x92\xba\"\x18\xbb\xc6\x04\xb4\xd4[E\xd7\x1b[r\x16\x9bZrf\xf5\x96\x9c+\x83%\xa7\xd2\xdc\xcd\xa6\x06\x9fK\x9dE\xb5\xac4)\xbf\xb0\xd2\x12\x0c?\n\xe7\xc1e\x86\xb6W=\xd1 \xb9mV\x1f\xf5Z\x04I\xaa#+j\x9akJ\xa2\xe2&a\x05\x84\xc0b<\xb3-\xd1\xa5\xe1RF=\xeb\xfc\x9c\x10t\x1b8\x95b\xcb!\x8c\x1e\xe5(h\xd5\xc5\xbc\xe70\x82\x99P\xc8\\U\xdeva\xe5\xb8RA^,\x1c\xa7S8\xd5\xc5[\xe7O\xe8\x1f\x16\xac\x0d=O\x11:\x821\xb3\xa5\x92i\x01\xe2\x91:\xca3V\x11\xf5B\x9f\x0c\x91\xd0o6K\xae\x1c\x0eL|J\x13\x15\x88\x88|\xcan\x0d7\xb9\x9f\xc8\x8d\xd4\x01{\x03\xaf\x91 \x97\x8df\x8fX\x8c\xadCg\xf7u\xe8\xe7\xf1|\xce\xcf7\x9c\x8a\xf9|\x88\xa2\xef\xa63\xc1i\x84^\xcd\xcd&\xa3\xa5G\x9bR,\x05\xfd\xfb-\xbb\x82X\xce8\x9dn\xf0\x9e\x8a6,\xb6(}[\x9d1\x10\x92w\xc4n\xbe\xd1\xc5\x8b\xc7\xd1\x94\x8a\xb0\x91\x03A\x11\x927\xd0\xcd+{J\xe5\xe4\x81\x88K%4\xfa\x1c\x05\xe3q\xc4]\xe40ie\xdcM\xd6x\xeb1r\xa1\xaf\xbb\xb7\x87\x96\xb4\xb8h6\xaem\x96kc\xc3:\xcf\xf8\xa6eg\n\xc4\xac\xf1~\xe2U\x1e\xd1\xa2v\xdd\x0dt\x82r\xe3\xa0\xbc\xa0\xe6\x15\xd1\xafc}\x1cx\\\xc5Pc#c\xb6!9\xd5\n\xbb\xebH\xd8\x89\x85\xc0\x13\x08\xe9r\x13\x07\xa21\xa1\x0f\xcb\x17\x1dI\xcd%8l4\xc0\xe0\x15\xec2+\xaf\xb7w\x82\x847\xa0/\xb3\xaa\xf9.\x8e\x0bC\x8e\xb6RnJ\x15\xb7\xc9\xaac\xa9\x9b\x80Mnl-\n\xe2\xb2\x08\x92\x86{F\x0d\xf7\x8a6\xb9\x89Un\xaf\"\xaf\xdc\xbf\xf5\x86\x9bVu\xad\xbb%\xdd\xd1\xfd\xfa\xb2\xd1\x8d\xaa\xbf\x14\xfc\xa4\x9fue\x16L\x98\xf7\x1d\xfd\xaf\xf7\xba@\xcch$\xb1\xab:O\xc6K\xe7vP\x85S\xc62\xb7#GGx\xe6\xb6\xec\x0b\xcd\xbc\x08o\xec\xaf\xde3]\x9c,\x1d\xd7_\xa1\x16\xaeb\xccU\x02\xad.3\xdbgq\x88\xf3C#\xadTn\x8c\x08\x9f%:\xa3\xdf\x81\xfb\n\xcc\xdc\xd5\xa9\xea\xd3_\xa3W\xd5\x88\xcd^\x9e\x9b\xb0\x12\x99\xb8h\xaf>p\x80D\xf7+i\xb05\xdeG\xd2\x0b\xe8,d\xa7\xe3\x10-\xcf\xf4o\x19%\x1c\x91\xf4\xce+\x19\xa5\xd5\xeb\xfb\xef\xdd\xedN5\xa8\xf6B}\xd7\x86iy\"~(\xce\x14\xcb\x8aC\xa5\xae\x8b ,\xc5]\xb9\xefQ\x88\xadS\xffX\xa3\x1d(%\x94\xbb\xe3\xa1.`\x9a\x8d\x94\x8a\x07\x0f\xd4\xed\x8d\xce\xd1B\xb3\xcc\x04S6\x92y\x1cUrq\xd5\x9d\xb6Y\xe8v\x14\xddq\x0d\xc7\xa8Gv\x99\x8ax\xea\xb8\xf0\xbd(Z\x12/\xb4Q\x94!E\xb8e,\xc0LA\xe8\x15\xfd\x10c\x96\xf4\xbcG\x07N7HI\xec\xa5\x91>\x90\xe3\xb1\xde}|O\xb9\xcd\xc5\xf6\xe8\xa0\xba\xa3=\xfd\xd6M\xf4\xead_\xbf\xff\xe7\xbc\xcdj\xe5\xcb*^mt\xacV\x0f\xcb\x8b\x878\x8cj\x9e\xcb\x87Q\xf5)\x1e\xe64\xf1\x17\xdf\x1bO\xf2\xe5\xa3\xfa\xb6\x9b\xa8\x10K\x8d\x1e\x94\x8d\xa6\xa4\x17\xb5\xa6$\x0c\xb2T(\xe6\x13\xa6\x98\xf7\xed3\xa4A\x9e}\xc6\x83#\x02\x8f\x16\x8eh\x8e\x0bG!\x11\x0b\xf6\xec\xe4q\xf2\xca\x95\x1bb1\xe0 \xe8\xcc$\xee\xa1S!\xde\xa0\xe1\xbb\x93y{\xda\x97P\xc4\xe9\xa7$\x85a\x11\xbf\xb9\xcdo\xeb\xd1\xf3\xb9}S\x928\xfa\x0e&+\x1bA\x8a\x17\xd1o\x0c\xd2\x10;\xd5\xd1V\x1b\xa4\xf0r\xed\xa5N\x95B\x8c\\R\xb1&t\xe0\x86\xf9\xf2\xa5Z\x07J\xf1\xe1#5$\x0cU\xa0*\xe4\x06\xb3\x05~\xc7\\\x08\xe7|\xa9\x98\x91A\xb5M\xd8\xef\xb0\xbb\xf1\xd48\x178\x0f\xe7\xe8\xe5\xfa\x8e_Ge~4\x94`\x8a\xf9\xa1\x07\xe4\x0b\x18\xc19\x06\x16\xb3\x8b\xc9i]tgQHN\x1c\xb4\xbf\x9f\xc1\xa9\x10\xe2\x983\xf0\x05\xd3\x98p7\xf6\xfc\x17\xe5\xdf\xf6\"\xd7\xa6\\\xbb0\xb3opg,\xf0\xae\x15\x9f\xe6\xebj\xa3\xed\xb6!a\x16]9Mv\xa0\xc2\xdbs^\x83\x0d8\x03\xf2\xda\xebF\x8f\xe3uQoW\xc1\x89k\x8e\x10\xbfz7\xa4\x82]#\x05\xbb*\xc7\x92\x1c\xa9\xb6\xc0\xa2\xd8vx0\xdb:\x9bt\xd5\xd8\x0c| f\x8c\x07\xd8\xb3\xa2\xfbn\x8d\xccW\x89\xb0\x1b3\n8\x1b\xa7,\xcb\x1f\xcb\x9e<=q\xa0\xdd\x8e\xb5\xd4\x0b\x8b\x8e\x80\x17\x9d\x8a\x9c\xab\xf6\x9a\xa9]\xac\xef~\x17\x03\xab\xb9\xe0u/\x13.:\xd5\x1fI\x0bo V\x13\xd3\xb5\x10\x17<&.\xe2\x93~\xf5\xb4Zry\x97\x83\xd8F\xb52/J\xa4J\xc4\x08}y\xfa\xf9\xf9\x8c\xb00\x94A\x14\x9e\x9f\x0f\xc1\xc3\xd0\xa2D\xe7\xccw\x1ez+R\x94\xb9\xb2\xab\x0e\xd0\xef\xcb\xea\x91\xb9\x1dT\x9b\x9cG1}\xbd\x1e\xcb\xf8\xa0\x17\xcc\x0e\x86\x7f\x86\xec\xcf\x08\x02;'\xe8\x8aR\xa4\xf4\xfb-\xb9\xf9x\x93\xc6\x0c\x8e\xe3\xb8\xf9\x08\x04!$(\xd3.\xcc:\xfc\xc5\x98L\x99\xa7s\xce\xc1Hm\xd7\x16^\xf2\x92c\x89\x98\xcb\x98YA\xa4'\xcc\x9f\xcf\x92 J\xaa\xf4 y\x8e\xaa\xaa\xb3\xb5H\xf6R\xa9N-\xc0kU\x1f\xa8\x95s6V\xad\x92\x83EE\xfc\xa7\xf2\xfa\x8a\x92\xc3\xca\xbb\x08\xe3/\xe2w\xe5-\x9e\x13\xa9\xf2\x9e\xc8\x9a\xc4\xde\xe4\xbf\x94w\x13\xe2\xc5J\x93\x0c\xc8\xdfd?\xd4\x17\xd7\xc4\x0fHR}\x93A\xc5\xab\xec\x97\xe6\xdde\x90*o.\x834\x7fo\x19\xa4\xca[\x92\x08PyWz\xc2k\x90 \x9azrAA\xa9'\x7f\x92\xd7\x93C\x94z\xb20\xf1\xa35E\x83\xea,HOx=\x12\xa4\xe4E\x82$F\xa2J\xd5\x9d/\x119\xdaFU{.\xba'\xda\xaf\xb5 \xcb\xba_A\x95*;\xae\xd2\xb1\xc0\xdc1\xb9\xe5MZ\x15\xe4\xdb\xc6\xec\xedL\xef\xd1\xad\x90Qh\x83\xe5(\x0e\xa1\xa5\xdfx\xa4x=\xdf\xb4\xd5\xa4\x92M\x0b\xd4Q.\xcb\xa3\x0cddr\x9b\xa6U\\>\xe1\xed\xe8\xb5\xa3\\\xee\xae\xe4\x86\xc7\xe0\x189\xc6\xd9r\xa7\xf4\xbd\xca\x11\x11{\xe5[\xae\x98S\x8b\xbd\x105\xbf\x10\x94\xe2\xf0\x97\x04f}\x15\xe5\x99\xd0UQH\xe5\xf7\x89\xa5%\xe9g\x8f{[G1b!\xcfP\xdf\xa0\x93\x1cR\x8c\xea\x9f\xcb\x0d\xfac\x90\xd8\x1c\xc52\xdc}4\x9b\xf5:?\n\xb1\xab>Z4\xb9\xbd\xa5\xcf\xe54\x05\xac\xecY^\x16#\x98V\xb3\x18\x9e\xf2\x8b{\xb4\x1d~'\x8ecj\x87\x87\xfe\xb0\xa3b\xd1=\\\xf4\x80\xa2=\xf3\x93\xc5X&\xe3\x1e\xf7q\xc7\x07\xf4E\x17\xbcq\x9f\x03\xbf\xc5\xae\xe7}\xefO\xc7\x11\xe2xvr\xaf~;\xae\xa8\x8c-\xe0\x1d\xf0\x97k8\xb5\x99\x16\xd5\xa1n\x17\x1b\x83\x07\x8f\xa9\xc1\xe4\xac\x1e\x93=\xee^^\x8f\xebyn>c)\x1f\xd9\xc1\x06{\x81\x0b[\x19\xc5.\xf3f\xa0\xaf`\x1a\xc0q\xb2 =\x8d$,\xdd\x9c\x9eJ\xd2\x7f\x86\xe8\xe0\x8d#\x89\x9e\xd6\x93R\x9f!J\xc6\xe24\xb1\xbe\xf6\xa7\xe3\x00\x91.\xba\x03a}\x90\x9e\xe5\x17q\xf3\xce\xd0\xf7\x85\xdf~\xe0\"B\xd3g%\xd0 \xb4\xb0\x18\xb7\x7f?z\x04\xbe n\x0e2\\\xbf\xbb\x8e\xd6\xb6\xe3\xb2E\xe1\xbf\x9c\x0dj\xdeb\xbbH\xd7\x016\xd9'\x9b\x86_\xe1r\x8a,\x97\xa8\xd5\x7fG\xff\xeb\x1eRY\xc5\xf0\x7f\xcco'\xb2\x90\xb4]\x0ci\xc7\x83:\xdf\xe7B\xe2VB\x9c\xdc\xf66G9\xb4w\xa7\xf6W\xef\x91P\xa6\xf6+\xef\x15\xbb\x83\x98\x16I\x1e\xe0\xe1fk\x03\xa9\xbf5z\x18=XYt\xbe\xe3\xb4n)\x1bW\x89\xe4C\x88\xc5\x12\xb9 .:\xc2\x19\xbc\xe0\xca\xc2[PHi\xe18\xd8h\xd7\x95\x85\xac\xa6\xe0\xa1,_6K\xac\xe3B\xc8~\xb5\xdb\xa9\xf3\xed\xf0BIc\x85\xf9\xa3\x90\xf1\xb7p\xa0\xec\x0c_&Va\xe9\xb7\x86*<\x0c\xd1\xd1\xc8+\xdf\x02\xbdy\xc8S\xa0^\xc9\xa0G\xf5\xd0(\x8a\x9a\xe48\xcd|hJF\xf7\n\xc7\x15\xcd\xe09\x82\xb8\x10\xa1\x7f\x01ECM\xd8\xe4\x0dh\xe1F\x18\xce\x8e\xb9L\xcag\x83\xa5d\xc9G5\x00\xe1\xc7\xbb;\xe3<;C\xf9x\x86j\x16M\x136#\x9e\xcb\xf3~\xf3S\x1aC\xfel\x0b\xe4\xe7\xbdi\xd5\xf6\xa6\xe1\xc8@\xe4\xe6=U\x90\xf54\"\xb2W\x16\x91\x93\xb2\x88\x9c\xe4\"\xb2W\xfc\xd2\x88\xc8j\xcd\xc6\x9er\x89\x98\xae\xd4\x86\xd3s\x0f\x96e&\xe4p\xc7\xed\xe5\xcaD\\\xed\xeaw\xf4\xbf\x1e\x86\x07j\xef;\x85v\xff\xb8\n\x8f8\xfcH\x7f\xbfM $..\xcfT\xef\xe0$\xa6\x8bo\xe5b\xdb\x05\x0870mL\x15\xc1\x93\x184\\x\xe7J\xd3\xa5\x0bk\x17\xfd+\xe7\xdcAQ\xa5/u\x0f\xaf\xd0\xba!\xc2\xce\xa9\xcfo\xf0\xb9\x08\xc1X\xc6\xe8\xe2=\xf4\x08\xaf\x97\xe5\x84\xa4QD\x17\xd6\xe2V\x8c\x91\xa1DJ\x07\xbcVj\xd4\xd4\xebC\xad\x80\x88\xd7\x1737\xbb$\x17\x9f{.t\xfa\x945\\\xf1\xcb'\xcb<&\xc2\x9a6\xab\xda\x9c6rX\x8eli\x02\xe1\xaa\xc6o\xf9}e\xfa\xa2P\x04\xe9m\x9e\xbb\xda\xdb\xed\xda\xfb\x93\x90\xbb\xbbI\x11\n\xb4s&;\xee\x8d`\xbc\xc0\x88\x15\xa1p\xe2c\xd4=t\x98\x0d\x0e\xa7V#\xbd\x89O\xcc\x18\x12\xdd\x95KF'\xd6LZ^b\x96|\xe1\x92\xdf\xe0D#>(\x7f\x98\xe9\xa8.R\xec\x8c'4@~=c\xc17\x8a\x80\xc8\xb8\xb7X4\xd8\x88\xf1+\x1e\xcb8\xc6T\nQ\x98\x92\xeb\x14\xf30\xc5\x97\x89\x93\xfbo\xc6,yD\xc00%*P\x88\xae\x89)Et#id\x99\xbe\xf9\xdej\x8a\xc2q\xc5\xeeEr\x9fp\xe3\xa6\x08\xe9\xd0\xd3rV-\x1e\xfeCT\x0f\xa9\x19a\x84\xfc\xccD\x8a\xb4\x1b\xcc\xcc\x9a?\x1e \x13jS\xf9\xd3\x82\x9c\xdd\xd1\xdaXO\x16\xe3\xa4\x08\xda\xcb~\x04\x85MF\xe9>\xbf3\x86X\xa1\xf4\x8a\xffX\xe2\x8f\x9cq\xc5\xdb\xf5e\x81\x0eZZ\x94\xc6\x1b 6-\xc0\x88\x8e\xc3\xa9\x0es*^8\x90u\xe9\xcf\x0dD\xa1\xc4\x9esa\x85\x8b\x14Z \xa5qJ\x12{\xad\xe3\x0fj\xefs\x1a\xc2\xa8\xa2\xe8\xaf\xf9x\xa6\xbd`\x9b\xe1M\xfb\x0d6\xc5g$\x8d\x03rE\n\x8a3\x8b\x08#D\xc1j\xbd$T(\x12h(\x90\xf8\xb1\x96*\x89\x0fk\xda\x9e\xbb\xa0\x1bqe|9\xb5\xff\xafq\x9c\xe5\xcdj\x1aoM\xdf\xf8\xfb\x0f\xd6\xbd\xbc?\xdb\xf5P\xac\x08\xe6n\xe0oh\xd1\xb1\x04)\x04\xaf\xaa\x8a\x81\x85\xca3q\x1a\x93\x8a\x01\xf9`\xbb\xad\x0f\xeaW\xe3\xe7D\x19\xc0R\xfb\x12\x88\x03\xfe\xa64I\x7f\x8e\xc7\xc1\xe8\xe9\x8e\xbeM\xcf\x8e\x1c\x93\x8c\x1f\xe1\\cVF\x9ct\x84x\xb3\x03I\x1elH\xf2\x7f\xd5\xefa\xe9\"\x1asj*\xee\x84y\xccO\xb1\xd5\xe9x\xe2\xe4R:\xac\xb4z\x98\x9fP{]L\xc3\xbf.I\xfa\x19G\xd0\x1f\xd38z\xc5 <\x16LV\xb3\xfd\xef\xa7\xd4\x92\xd2\x0f\xe96X\xe8B%DsXD\xecm\xf1\x88\xbd\x04\x86\"\xa5b#s@\xaf\xb2\xee\xf3\xb33\xba\x1c\xf8\xa5K\x12\xdf[\x17\xfaT\x19\xa8N\x95`,\xcd,H\xc4dP2z\x19\xbc\xd8\xfef\xd1\xec\xdf\x84\x98\xfcl\x16\xc4$\x01\xaf\x08}g\xf4X*\xc5\xbb\x96\x82L\xf1\x10La\x9ea\x81\x12\xcfN\x9f\x1d\x83)ya\xa2t)[\xc2 \xb4\xdb\x01<\x81\xf8\xc4\xc1\x19\xe6\xf9{\xe4B\x01\xde{\x8c\xa0Mg\xff\xe9\x08\xfa(\x05S\x01d\xb7\x8ftgp\x08\"\x03!N@\xc0\n<\x1d\xc1\xdeQ^v\xff\x10\xcb\xd6=\x7f\xf4\x08\xf6\xf6i\x81\x8c\x12\xc6\xc9\x04\x83F\x15\x96\x89\xfe\x01Zr\x80\x12K\x1b\xfb\x1a\xb0*[\xfdJ\xd8\x01\x82uup\xc4\x1f\x88\x0e\x1e\x17_\xf5=D\xe8\xc1~\x0e=\xee\xe5\xd0\xe3\xc3\x1c\xda\x1f\x0c\xf02(\xce\x13\xce\x11\xa5\xe0\xac\xcbe \xce\x9b\xf5\xff\xfe\xc5\x9fY\xb5\xfbPuz\xd78Q\xc8\x18\x8b\x1a\x18\xf6\x0dO\xdan \x91Y\x8a\xcfJt\xe5r\xec\xeeX\xd6\x1b\xbew\xf2\xdb:\xa1\xdd\xef\xdf'\xb0\xa76p=\xad\xd8:?'\xc9\xa7\xd1,[\x12\xabJ\xb5y\x9a 9\x8d\x82\xc3T=\x98K\xaf\xceQ\xc5x}9I\xbd\x94|\x7f\x99]\x06a24l\xdadM|\xd33\xfa\xf1\xb0\xcdd\x08\x99Y\xc8O\xc8\x92\xf8i\x14'C0\x04c\xd2\xbf\xcbR/\x19\xbb\x068\xb6Y\xe6\x13Zs\"\xa6\xc2\xdc\x8f\xbc\xaf\xd1F}\xf5\xf4}U\xf1\xf0;\xfa_\xefU\xf9mn\x87\xf6~\xffX\x89\x90\xcd\xed\x0c:\xbb\x84o\xd3'{J\xa0e\xfeh\x7f\xaf_}\xe4\xe5\x8f\x06J\x90i\xd1\x87\xbd]\xc79\xf9N\xfeL\xe0\x0e\xf8z\xc5O\xca\x98C\x81\x9f\x05s8\xa9\xa0)\xe3\x06_U6\xa7|+G\xa3\x10\x93b\xe6\x05!=\xb65\x1c\xac\x0bC\x1d\xa7eEF$\x93\x19\xbc\xd8(i\xd9\x8fC\x9d\x84\xb9\xd1\xbdB\x99\x07\x1e\xb4X'a\xb1\x1c\x97\xd5 \x93\xdfQ\xbf\xd1q/\x95[B\x97$\xfd$\xf2\xbd\xe5s\xdc\x04\x9b\xc5\xfa\xb3{\x18\x8c\xd8\x8b\x13\xf2\xd3\xde\x8a\xbf\xea\xd8\xb1\x18\xfcv^\x0erC2]|\xdc\xe9t&a\x16/\x87`-\xd2t\x9d\x0cwv\xd6$M\xd2(&\xdd\xe4\x9dwyI\xe2n\x10\xed\\\x0dv\xc4\xaf/\x92(\xb4&\xe1,Z\x9d\x07\xb3!X\x7f\x85?\xe8d\x815 \xd11\xddK\xa3\xf8\x07\xa5:\xa3p\x19\x84\xe5\x1aEAk\x12F^\x96.\x06\x9f\x91Y\x10\x13?-\xde\x1c\xee\xec,\xe9\xbc-\xa2$\x1d\xee\x0ez\xbd\x1dV\xb2\x13\xf3\xa2\xddE\xbaZZ\x93\xf0\xb1v\xd0\x1bQp\xc9\xb5c\xd07hR\xe3\x87\xa9^\x7f\xdc\xdb\xdf\xebi\xb7od\xc4\xdcZ\xf4Q\xbcH\x85\xb5\x120\xfe\xa6\x88\x15=#\xeb\x98\xf8^Jf\xe0\x853\xc9\x91&K\xc8\xac\xdb\xe0C\x03\xf2\xfct\xa9\x98\x87#\xe9\xc9IK\xbbg\xfe\x82\xac\x98uu\xf7\xa8\xf4\xe4\xe3g/?9{\xf6\xf1\x8b\xf3\xb3\xe7\x7f\xed\xc5\xa7\xcf\xb8\xc1vP*\xf3\x93g\xaf_\xc9\xcf\x07\xbd\xdd\xd2\xf3\xe7\xaf?{Q~^~\xff\xa3\x17\x1f?\xfb\xc1'o\xce\xab\xed\xec\xefj\x8b}\xfc\x83O>\x91\x8b\x1d\x95\x8b-#o\x86\xa1\x02\xe8\x97\xea\x83g\xf4P\xc1\x9f=c\x17\xce\xc4\xe3\xc4\x9b\x93O\xc4\xbb\xe2\x87\xae\x80\xa8C\xfa-\x17\x9be\xab5\xc6\x0c\xa4_\xaa\xef\x7f$\x1e\x8a\x1fr\x81\x9f~\xf6\xe9'/\xae}\x82!\xe89\x1e\x96\x86\xf6\xe9\xcbW/?}\xf6I\xddZl8\x87\xe6\xe9K|/D\xd5\x81E\xbfY\xa5gH\xe1\xd8C\xfcZ~\xeaG+\xee{\x12\xd9\x16\xffQ.\xe1\xcdf\xcf\xa5\xf0\xe1X\xb0\x0c\xb3\xee!\xdfI\xfe}\xd5\xab\xfcA>\x9b%0\xbfD\xa5h\xa0\xb3|\xeaJ`/\x9f\xaf\x128iVH\x97_\xf0U\x85\xf2\x1cF0(\x83(\x92\xed\x96A\x14u\xf6\xca\xa0\x85Z\xd7L\xad\xebJ\xad\xeb\x86\xb9\xc2]\xf7z\x9d\xc9u\xefhr\xdd\xfb\xde\xe4\xba\xf7|r\xdd{\xd1\x99\\\xf7?\x9e\\\x1f~\xdc\x99\\\x1f\xedM\xae\x8f\x0e:\x93\xeb\xe3\x8f'\xd9\xc7\x1f\x7f\xfc\x02\xff\xffxz;\x9ed\x1f\x1d\xd1\x97\xb3\x8f\xbe\xf7\xf1\xc7S\xfb\xb4E!\xcf\x19\x84\x96pn\xed\xd3\xe1\xf8\xf3r\xb1\xdb\xcf\x9dJ\xb1\x9dr\xb7.y\xb7\x8e\xf6\xcb\x1ez\xe5R+,\xe5N\xc6\x93\xe9\xe4\xab\xc9\xfb\xea\xe3s\xfa\xf8s\xfbt\xd8\xbam\xb5n[c\xaf\xf3\xe5\xa43m\xb7\x9c\x0fv\x82r\xc9\x8b\xa2\xe4\xf8\xf3\xa2>\xc7>\x1d\xfe\xc4\xb8\xd79\xf6:\xf3\xe9W\x83\xf7\xb7\xec\xfb\x97\x93\xce_9\x99\xecLN\x87\xdf}4\x9a\xb4'\x1f\xb8\xe7\x93n\xeb\x7f\x98|\xf8xbO\x1c\xfa\xf6\xd4\xf9\xf0\x83\x9d@\xc7\"\xde\x19YD\x9f_B\xc33\xe3.\xfb.\x11q\xb5\xaakcU\xc7EM\xbb\x83\x0dj:\xdb\xa6&\xec\xdf\xb6}}alao\xaf\xa8\xea\xb8/}\xdf\x95\x9a\x18\x94~\xeco\xd0\xe03\x83yG+\x9e\xee\x1d\xa1\xb9\x02\xa5K~\xd2>\xc5 9{G0\xa4\xc7\xea'\\\xef\xb0;\x80[`\xc9\x9c\xd91\xbb7@}O\x87\x16j\xd3i\x19B\xa7_\xdb\xb1\xd7\xe6\x998\xca\x15]\xd6\xa4g\xb1\x96s\xc8\x7f\x87\x00\xb9\xc8\x05\x85\xf4\xfb\x07\x12(\xc5BU@?_.\n\n\x19H\xae\xe9\nA\xbd\x81\x04\x9a\xb3R{\x12(f\xa5\xfa\x05\xe8\xbf\xa7\x90]\xe95\xd4}\xec\x16/=\xb6\x1e\xc3\x10\xf6\xa4a\xec`\x0f\xe5\x96&\x14r(u\xe7\xff\xf9y,\xb3/A~\x13\xcb\xc8#E\xaa@\xa1G\xbd\n\xf4\x98)\xabk\x17\xe1\x8b\x9a#\xc6\x93\x11\x1c\xec\xef\xef\xee\xc3)W\\a\x96\xe9\xe7\\\xdfd\xa7\x85\x03j\xf9\x01K\xe9\xd9\xa6\xa7\xb5\x0e\xd6p\x00O\x9fB\x9fJX\xfb\x07\xbb\x83^\xf9\xd1#:\xdf\xbb\x8a\x11\x15\xe4\xd3\xd8[\x90\x13\xd3\x0e\xf6\x0f\x1c\x17^j`\x9f\xb2\x84r\x9f\xc2\x13\x18\xec\x1f\x9c\xc0\xa7\xed\xb6\x03o\xc7\x9f\xd23\xd9k\xfbS\x87\xc7\x19\xe8\xb9\xf0\xb2\x00\xea\x88\xd3\x1b\xad\x1e_hb\xc9;\x08P\x01C\xdeQI\xb7;\x0f\x96$\xf4V\x84\xb2\xf6 \\g)\xde\xdb\x8f\x92 \xc5;\x96i\x97\x9e\x1fd\x18t8\xf0,\xf5\xe2\xb2\x9b\xbc\xda\x97\xe7\xda\xbe0Q\x99\xf7\xb3\xf6\xfd\xef\xeb\xdf\xefF\xe1\x0f\xbd8\x0c\xc2Kv\x96\xcc\x7f\xf2\xeb\xea\xe8y\xca\xeb\xd7-\x0e]\x97\xcf\x94\xd3\"\x15\xd9\x86\x8d\x16\x1a\xf1\xbe1d\x0b?\xa2\x8f \xed^\x918\xa1\xc3x\xf4\x88\xcd\x845\xcb\xd6\xcb\xc0\xf7R~3\xf5'h\x93\xc0\x8eT\x98Q\xca\xe5\x91\x0fC)`\x15{\xb3\\\x12<\x9f\x8a\x96 \x90k\xcfO\xf1b*\xc9U\xba\xb4\x9a\\\xe3n\xc7\x8c+R\xa67m;\x93\xae\xf8\xf6\xc1N\x97\\\x13\xdf\x0e\xc7=\x1e\x03\x8d5\x14,\x97\x9dy\x14\xafdw\xffh\x0e\xe9\x82\x80\xda[*\x8b\xa1\xf4\xf82L\xedx\xdc\x9f\xbal\xafDe\xf8@\xc0\xa5\xb8\x8e\xac\xb5,d#\xc1lhX\xbf\x983\xde\xe6,\xf2\xf3A\x15\x13:\x82\x90E-\xef\xfa\x0b\xe2\xbf\xfd$\x08\xc9\xf7b\xe2\xbd\xa5\xe2[Dw\x90h\n\xef\xdc\x0e\x8a\xaf\xdf\xe7\xad&\xd9\x9a\x8a\xb1d\xd6\xd0hiu+*\xb67\xcf\xfe\xeav\xe8\xa2\xe2\xca\xc0\xb0\xdao\x9e\xfd\xd5\x9a\xc5N\xdfE\x85\xfe\xdf\x12\ny\x16\xd1\x0e\xbf\xd1u8\xef\xa6$I\xed\x18\x03@(K\x9bz\x97\xb0\xf0\xc2\xd9\x92\x80=\x0f\xe2$\xcd+t\xc4$\x94\xfa@[\xc9C*\xa4\xde\xe5\xa7\xde\xda\x85\xb8@\x9b\xc7\xe9\x82\xc4\x84\x1ep=X\xc7\xe4*\x88\xb2dy\x033\xe2/\xbd\x98\xcc \xc9\xe6\xf3\xe0\x1a\xa9\xa2\xf5\x18\xda\x10C\x1b\x1e[R7\x1e;.\\\xb0.\x07\xe6.\xafcB\xab\xb1\x13\xe2G\xe1l\x83>\x8b\xce2\xbf\x87r\xe0\xfc\x92\x96Q\xa5=\xaf\xc4\x92\xe2@U)\xa4\xc8\xdf\xaa\xaa\xe9\x08<\xd1\xa3\x02\xbac\xb0\xd8;\x94\xd8\xf2+\x1e\x888\xb4\x19\xa5<\x08V\x120sz$E\xf5f\xf9\x08\"\xfa\xa7=\x82\xbe\xc3e\x06t\x0e\xf0\xaa\xb6\x15&\xfb=\x19AF\xd7,C\xb9\xa7\xdf\xdf\xeb\xf7\xfb\xc5d\x93\xeb5\xbb\x83\xcf\xa2\x1c\xfc\xe4\xd9\xebW@\xab\xf1\xfc\x94(\xb90A\xdc4\xbca\xab\xe6I4\x84.E\x92\xc6\xc4[\xa1\xc3\x81\x17\x84 \x84Q\xd8Y\xc7A\xc8\xb6z^m\xa2\xab7\xed\xc6$\xc9\x96\x98/\xd53\xad\x99f\xc9>)\x96Lqo\xb9\xe2 \x04\xd0-\xac\xe2,\x833\x1cw\x83\x84\xa7\xdb\x0f%\x0c\xe4\x1a\x9a\x15\x89/ \xac\xbc\xf5:\x08/\x93\x13\xc4\xb6u\x1c]\x053\x8a\xddQ\x16\xfb\x84\xe7o\xa6\x9b@&k\x96\x93\x87\xd8\xa4\x87E[\xf2*xKn\x12;t\x9c|A=x\x02>\xfd\xc3\x164\xc3\x80\x8f\xde\xd4\x95\xe2\x9ce\xd87\x9b\xb0\x90\x94!\xfa\xdb\x04\xecG\xabW\xcfM?\x920Z\xce?\xac\x9b*\xdf\x85\xb9\x8a\xd7Aa\x08\x0cd.\xc3S\xf2\x08#\x91\x95z\x97\xc3\x1bo\xb5\xecF\xf1\xa5;\xe8\xf5\x06C\x9c?\xe6q\xabAsZ7\xbb\xeb\x18$L(2E>\xc0\xa5\xe2\xae0\xf4\xa0\x1d\xe5s\xe7\xc3\x13\x98\xd3?l\xee\x04.Dc\x1fS\x90\x1b\xb07/\xa6\x96\xc1\xe7)\xea]\xe9\x94'y\x8cb\x9e\xde\xa9X\x13\x06\xb0\x99\\\x04t\x8f\xdd\xde\xeaD\xa7\x11x\xecI!`\x95\xe5\x022\x13(\x06o\xc9\x0d&\xe0#\xe3`\xcaB$\xe5\x97~\x83\xe6D>\xea\xe2\x7f\xb9\xd1Y\x8a\x1f2p)\x05\x8d\x92(I\xd1s\x87\xdd\xe8\x12?\xdbmz\xac\xd8\xe5\xc8p\n\xb6\xfc\xc8\xcd\x8f\x9a\xb552Y\xaex\x8d\xca\xe8lz<\xc0\x89\xbd\xa0,\x9en/A\xa8\x18\x85\xc7gmt3\x92$S\x1c\x80\xa8\xacvf>6\xf1\xee\\\x86\x97s\x0e\xd5\x0e\xe1\x84;\x10\x04\xda\xb8\xac\xdc+\xeb\xda\x0e\x1c\x1e}TS[\xbb-\xd7\xa7\xdd)\xb8\xdbv\xd9\xd1\xca\xe0!7\x8bj\x0c~\x9b\xb4\xac}\xf9=\xbc[\x04Td\xe8\xf7\nA\xae\xbf[|\xe7`C\xbf[\xef\x90\x15\xe12\xaa%pv\xbeD\x07\x83\xe6\x89v!\xa6x\xc5\xd6\xfbe8\xa3R*\x9e\x9f\xf8A\x96.\x80\xfc\x90\x16\xdez\xd8\xefu\xbb\x8c\x87\xb0\x0d\x8b\xe1\xc6\x0cq\xa5\x9e\xcd\x0c\x99\x06\x8f{\xc16\x08\xe3\xbe?\xc5\x89\xfb\xd2\x85V\x1f\xbd\xe3\\\xd1\x94@\x0e\xa7\xdc\xbfM\x1aw\x0bf\x8f\xb4 g\xf7|HO\xb9\x83\x10\x9f`\x87\xf3\xb1\x0bo&\x13\x01zj\xf1 !?\x9b\x91\xd0'@\xc24\xbe1\x8a\xd9\xcc\xc7\xacDd\x88\x96\x96\n\x12\xd0\xf28\x8e\xd0\x83\x13Kd$p\x07\xc5\x89\xb4\xfb6\x08g0\x02K\xf4\xc0r\x8b\xcd\x841\xc6\x9a\x04\xca\x9f6\xd3\xa8\\\xc4D\x8c\xd6\xef\x80*\xa6\xd3!\xee\xee\x16\x11\xc2\x1b\x04\x90\xdc\x7fBW\x8f\xb4a\xe8\xf8M\x1a\x18\x8f\x1f+\x99i\x87R\xe5\x03.\x01m\xc2-0\x12m\xc41~\xb3\x17\x86\xb0\xcb\xa4\xa4@D\xb1\xc58\\t\x19Z-k\xf3Z\xd8\x1b\x16\x0b6 \x0b\x94\x91N\xf20\x8a\x03\x9b4\xa7\xbc\x98\x8b\x01\x92\x14p00\xb2~\x89r<\xc9\xb3\xf8\xd1\xd1\xc7\xba\x83pi\x97m\xd2\xbdBL\xcc\xc2\xfc\x04K\xc2\x99\xd0 \xf0\x83\xe8\xbb ]\x04!xpE\xe2\x0b/\x0dVt\xe5\xab\n\x1eS\xa8#.\xb9I\xe3m\x9d1)._M\x96D\xe0T\x9c\x80\xbdK\xa1\xf3\xe0\x07H~\x10\x06r\xed/\xbd\x15C\xc0\x95\x17\xbfM\xac<\x0eqe.X\x16\x85\n\xdd\xcd\x15;\xf2\x195\xf4*:\x9dJ\x9bI\xe6/JGn\xe6\xa5I1\xaf\x8c>\x8c\xb4o6\xef\xeaB7\xaf\xe7*WJ\x15\xba\x02\xe3L\xcd\x97\xd1;J.\xe9v\x8d\xe2R\xff\xcb\xab\xa6#\x7f\xc8\xc8Z\x17\xfa\xf60\x99u\xfd\x1c\x0d\xd1m#F]\xe6)\x08\"\x1a\xc3PU\x83\x85\x8eT\"W8\x85STs\x0d\xe9.\xe5\\\xa2(Ea\xe2\xa9\xee\xb1z~\x16\xe5\x99\xb6-\x0bs\xcd\x9a\xb4\xea\xa8Y\x0bQ\xb3\xf6\x18=\xc1k\x89\xf7\x0f\xcd\xc4[C\x96\x8f\x18Y\x0e\xefA\x96\xcd\x82\x8c\x9e4\x87\xc0K\xc8\xe4\xd9\xd0\x81\x12fV\xb1Zl\xdc\x90o\\v\xd4l\xbd\xb0C\x07\x93\xc76\xd7\xa8\xe5\xb0\xd2\xb6\xc9u \xc5~,\x0f!\x8cf\x04VYR\xe0\x9b\x97\xc2\x92xI\x8a\xaa{I\xcbVb\xd3\xf5\xbb\xa9a\x81\x7fJ\xd2\x86i\xf8\xc2U~I\xf2\xc6\x85K\x17V.\x9c\xbbp\xe1\xc2kf\x8c\xd20\xed7\x06f\xfe}\x033\x97\x16{\x19$) I~Vb\xbfl+Zc\xd4\xd9T\xe8j\xa1\x88\x1e\x9d\xcf\x82\x00pyE\xfc\xcc%\x15\x06@\xb5'\x8c\xd0\x19b]\xc8eLA\x85A\xeb\x1f=R\x04Q\xfbM.\xaf\x96\xc578e\x93\x00\xc3\xca!\x93\x9f:\xd0\\W}\xf8\x84+\xc2>E\x97x\x07\x0d\x1e\xf4\x85O\x0d\xde\x9a'L\x82\xba\xbd\xc5\xcdx\xe2\x94\xbbwZ\xf4\xee\x86\xc9c\xdfJ'a\x88\xd5\xeb\xd6\x8f\x07j\x80\x11\xbc\xa1\x9d\x8cr\x0b\xce\xa7\xf4\xc1\x9ao*z\xea\xbb\x80\x11\xf8\xc5\xa4\xcfs\x92F\xf0<\xd6\xa6\x9c\xecu\x99\xd5\x94\xec\x88\xf9L\xc1)\xbf:\x8eg\xaf\xd789\xdb\xd8X\xdcB\xc9\x9b\x98Og\xc0=w\xcc'4\xe0^;_\xd5\x8475=\xcb\x91T\xfb\xf4\xaa\xf6\xe9M\xed\xd3K\xc3\x06\x04\xeeG\xa3\x0b\"|\x87\xf3\xe3\x92\xab\xac7;?z\xc6$D\x18\x84\xa8\xa9\x1e.\xd6D\xd2\xa1-\xab\xc8\xb4\x07\xecP\x80\x07\x9a\xfd#\xfe\xfd\xf6\x96\xd2\xf2\xb8\xf9\n%\xd2\xc1\xd0\xc5[\xaf\xec\x08h\xd4A\xc9\xefI\x07<\xadL-\x7fX\xaa\xdf\xa6\x91:'pm{t\x9f\x1b\x8a6\xc8W\xf2\x87\xf6p\x9f\xf9[x\x0e\x9c\x99\x1a\xafH\xca\xb9\xc4\xe8Q\x11\xfe\xffc\xee[\xbb\xdb\xb6\x95E\xbf\xf7W\x8cx{\x1c2\x92\x15I~$Qlk\xa5i\xd2z7ur\x9a\xa4\xfbt\xcbj\x16-A6\x1b\x89T\xf9\x88\xed\xbd\xdd\xf3\xed\xfe\xb1\xfb\xcb\xee\xc2\x0c\x00\x82$@\xd2N\xd2\xd6k\xb5\xa1@\x10\xcf\xc1`\xde\x93\xb2d\xe3\xcf\xb5\xdbG\x97\xad\x82\xbf\xe4%\x9c\x82\xfe\xc0\xae\xb7\xd1w\x02\x12\xb6\xf1c\xa4\xc6\x149}\xb6\x8a\xe6\x1f\xa4\xd4\x9a__\xc8l\xb9\xa8kX\xf5\xf2\xa88Z\xc4\x9b\x8f\x02K\x8b\xa2\xb5@r\x02\xb8\x91\xf8\xe4\xff.\xd4\xf9\xc5/$\xc2\xaf_\x97\x86\x9c\xcc\xf2\x0f\x01c\xad\xb9g\xd1\xd5\x93\x14\xee\x9d9\x07\x96\xfa\xee\xf8\x9f\xd2\x13aD\xd8\x98\xf9\x0b~\xf1\x07kN\xcd\x04\xa9\x12\xe8o\xfc ~\x02>\xcc\xa3U\x14\xf2\x95^\x07IR \x9bW\xfe3\xbbKC\x1d\xb3\xa2\xff}\xaey\x9a\xe6X\xdcz\x12_\xf0 \xae\xb3U\x1a\xe0\xd9\xf9\xc0\xaea\xed_\x830q\xd6W\x05\xd5\x1b\xf6\xb9\x19\xdf\x88\x19\xef\x13\xcb\xe5\xf3\x0b\xf2\xd3\x80Mp\xed\xe42yN\xedi08\xc8Y\xcb \x9cG\xeb\x0d\xea_\xd8\x95ec\xf9l\x91\xceS{\xfb\x04\xa2\x18\x96\xd1j\x15]\xb2\x05\x9c]\x83\x8fj\xd0\xd4?\xcbV\xa8\xeca\xebMz\x8d\xca\x0d\"\xfcr\x9c\xa8\xbc\xa6c\xf3\xc6P(\x11\x0dEYeP\xae\xa4\x037DZ\x04T\xca\xa7\xab\x1f+A\x06hB\xb1s\xbc\xd9+k{-b\xd9\x1b\x97\xb7(Hk\xc6\x88\x9e\x81\xa8Qr3\xbfVnV\x80;\x9b\x17c\x93\xe8\xac\xf2Q\x15\xf2\xc4\xd1AH\xb3\x01\xda\xba j\xab\x9c\xae\\\xd4&\xf1d\x81~\xc5\x16\n\xfd\xfe\x81\xc4O\x0f\xce\xbc*\x01d\xa3~\xcaZ]\xccY\xb3\xd4\x93\x88u,\xf9\xc6\x17\xf5\x84\xd2\xc7FB\xe9\xda\xe0\xad\x04\x02H\x859\xa8\xbbi\x86\x05\xd2\x89=\xde\xe9 98IbM\xe9\xc9k0\x1f\xefs8\"\x82ac\xe5EUmN>\x8f\xf6D\x8f\x03\xea\xf1?M\xfeip7\xb2*\xf6(\xc3T\xd3=- \xabM-a\xa5\x8e\x1a\xf3z\xad\x96W\xe8\x0b\xab\xec+i\xd2\x08v\x17\x05\xd8\xfd\xa8\xc1.\xc7\xb7\n~al\x13\x1b\xc7\xf6\xcb\xe4\"\xa7?\x08?\xc2>9\xc5\x9f\x04\xe1\xf9\x8a\xc1\xefY\xc4\xab\x8a\xbdGZ\xa2n\x96\x86\x83t\x1b6\xc3\xdc\xe9\xe78):\x83a95\xbb\x04\x1e-\xc4t\x9f\xff\xd4`\xe2m\xf3\xa9i1\x9eZ\xc9\x88\xf0]\xf5\xd5\xa0\x8d\x18m\xe0\x95\x87d\x03|\x14c\x8dd\x9b-\xce\xa2\xa9\xab\xcbv*\x1aO\x87~\xfb9TrM\x9f\xfcE9\xd0\x7f\x98\xfa3\xafp\xc1\x1c\xa3\xef\x88>\xc9\x16-Rp\xd1\x910\x83\xe3\x1c\x8b\xcf\xcf\xd2\x08]\x89\x1f*Vf\x17\xc6\xf0hO\xfd\xe4l\xc3\xc0\x83#\xfe\xbf\x16\xba\xb2\x80\x14\xda\x11\x19m\x07\xfc\xbb'\x10lo{\xd8\xfb\xd3\xb6k\xc5\x99\x14\x0c\x1b\x87~5\x07\x07\xb0\xebA\x172\xc5R\xa9\x13x\xc1\xae\xfc\x05\x9b\x07k\x7fU\xef\xd2\xa4\xff\xe9K\xf9\x9b\x1b\x95\xe0\xc5N\xb7\xd0ZJ,\xf0!\x8c.C\x10\x11\xd3\x94\xcc\xac\xa6\xeb\xea\xc9\xa8\xc7\xa4~\x8eI\xe9\xe8\xdb0i\xb5\xe1/\x84I\x17Qv\xd6\x06\x93\x96\x06\xd3\x82\x96\xb8\x0dj5\x8f\xc2\x88Z51NGC\xb26\x0c+\x0c\\\xcdXu\x97d\x18\xcd\x8a\xef6X\xd5\xd2H+s'2\x81{#\xac\xdf:\xcf\xdd\x98\xa3\xcd6-V\x07s+\x93\xa7U\xe0'\xb7\xb2x2\x18?\xf6\x8a\xa6N\x9aH\xbd\x14\x8eE7\x84\xbc\x97\x85J\x0c\xb0\x10\xe3(\x19\xc5iw\x92.\xa6\x0fge\xddU\x95\\\xe5`rWS\x14\x94\xba.\xa5\xbc\x95\xdf\x94v\xe1\x9c]\xd1\xcd\xc1\xeb\x8d\xbbl\x06,\xbe\"\xcf\xdd%\xb9}\x12\x92F\xa6w\xe7Q\xfe\xbc;\xd2\xcaw\xf2g)\xe8\xc3\x1f\xfbz\xa5\xc7\xda\xb3Vg\xe7\xa1V_+\x7fL\xa1\x1e\x96\xb5P\x8e7\xce\xbe\xd6\xbd\x10\x9b-IF\xff\xa6\xf9\x18 \xee\xec\xe6\x86\xec\xfb8\x98\xb78X\xcd\xe4J\x80\xbe\xe4ErWX\xad\x8b\x03\xb6\xac\xa5B\x84u\xc6\xb2\x89b\xb8\xe3\x14k\x98g-\x8f\xef\xce^\xdbA\xd4\x0f\x00}eZ\xf4\xd9$\x95h\xbcj\xf29.\x9b\xa5\x8f\xbc\xcdK\xac\xd8l\x05\xe1+1\x8bT\xd3h\xc6gsU@\"\x13\xed\xe6DdP\x14\xdc\x1c\xda\xb3t\xe9\x7f\x99\xc6\xbf\xdfYZ%\xfej\xe3\xb6\xcb?\xbb\xc0\x04\x8af\xf8\xc2\xff\x83\x8c\x078~\xd2wB\xe8\xaf\x0b27Kr\x01\xf9w\x179\x8e\xb9\x14\x15`D\xcb\x10\xfe\xec\x0c%-#\xc6\xbb\x0d\xbeWw8\xbd\x1e\\ \xcc\xe7\x16k\x08C3\xcbv4\xb8<\xd8n\xc4\xf2P;\x1d\x85F\xc8%X\xa0\x99\xa2\xc5\xea\xa6*Q!R\xa4'\xad( \xfd\xbd\x16 \x94\x07\xd0\x96\xde,\xca\xd8\xc0\x998(\x9b\xaa\xa9\xab\x95\x08\xcdnn\x07\x96\xdf\xd5\xc9E\x94\xad\x16h\xabs\xe1\x7fd\xe0\x87\xd7\xd2\xf2\x1a\x95\xb0\xd2\xdf\xbb\xb5\xba[\xe9\x15s\xd1\xd9\x8fjVh\xe4)l\xe1h\xf5\x91\xb9\xda\xd4\xeb\xf1\x84\x06\x13\xef\xfbs\x19;OwM\x93\xfb\xfc\x9e4\xccw\xdc\x82\xcf{~\x05\xb2\xcf=!\xae7\x8c\xbaFh\xbf\xb9\x01g\xe9\xafVg\xfe\xfc\x833\xeb\xc9\xed\x99\x80X\xb7\xda\xeaS\xac=+\xccT\xac\xd1\xd6\x16\xbc\xa7O\xa8\x18\x1f\xcd\xa1d\x10\xa2\xf1=\xdf\xfe\xce\x01\xc6\xe0\xc4\x95\xec\xc2\xbd#H\xfds\xd4< \x98?\x13\xbe\x13\xa2uN+\xf6\xf0 `i\x9a\x97\xdeC\xff\x9b\xca.\x93\xc3{\xd3N\xdeq\xebr#4\xa1'\x13\xdd\xa31\xd9\x82!\xbfS\x9a\xa1s\x94+\xe1\xd0\xcbI\xf7\x91\"~\x94W,\x7fdI(\xd5\xc2\x8a\x7f\xbe\x8a\x12&\xcc\xf8K'\x99_\xe8\x95\x89\xdf\xdc\xc0\xeb\xafr\xf8R\x8f\xcaw\xe1\x87v\x9e\x85\x1a\xfa\xaf\x00\xa9\xc9\xc3P\x90~Z\x18!\xe1KP\x0d#\x94\xf6W\xec\xdc\x9f_\xf7\x94K\x8f\xc8l\xa6m\x18\x99=I\xb1U\x0b\x97E\xdc\xf1\"\x9f\xd1\xfcU\x0f:nIs4\x10tw\x07-z\xcc\xd20\x9ck\x06\xed\x9d\x13m|d\xc1\xdf\xadMC5\xbc\xect\xd63\xfa\xba\x15\xd8=\x19\x0f\x05\x0e\xc8\x8d[\xb8\x07\xa9xH\xc8k\"kiR\x1b\xeb\xe6\xcc!PKNCd\x06\xf8L\xd1\x19\xa0\xa8\xa1\xad\xcd\xb1\xd4\xa8\xa3m3\x04;\xd26\xf8hR\xfc\x05\xfbUPC\xdd[gZ\x1b\xd2\x01\xe4\xb2~1\xc0\xe2\x7f\xb1t\xe7\xae\x81\xa8\x16\x04\x9d6&\xd2;\x8b\xeb\xed'\xe1\xe1\xf7\xd34\x9cI\x19\x1b\xc7\xa7\xaf\x85\xc4\x81\xf0\xa9\x12\x82\xe5`Z\x90<|e\xef\xbc\x88\x0f\x06\x1ak$\xce{\xee\x9e_\x8f(\xdaV\xa4x\x0e\xed+\x8f\xbcbD\x17\x11\xe1A\x1f7_\x90\xccpV\x13\x14\xd0\xad\xfd\xb8\x12\xb7\xe5\xe7\x9c\xa6\x17\xd3D;\x8d\x8df\x9cV\\\x98*\x92\xde\xda\x82sr\xf0,\xee}T\xdc{P\xa18\xc2(\xdc~\xfa\xe6\xd9\xf1\xb1\x16O&\x01?f\x10\x84)\x8b71C\xc7\x87\x04\xd9-\x15tNnmR \x1b\xd0\x82\x9f\x9d\xc0\xee~\xf3\"{\x82\x14hXa\xad\x82\xe6I\xbd\xadc\xc9\xaa<4\x8aQ\x16*\xc03\xf7\xe0(\xecG\xede\xfc\x9dk\x8c\xc2XL\n\xc3d\x86(~G\x0e$\xbd\xa0\xe2\xda\xc9\x901\xa5\x05\xc8\xa7\x80K b\xc9\xd4Wrs\xf3\x82\x1e\xec\xef\x8d\x1e\x8aX\xa9\xfaG\x03Y\x93\x97\x8b<\xfa^\x19\xf7Q\xb2\x04\n\xc5\xd9\xa8YK/\x82\x84\xb6\x100\xfd\x01\xfe\x96\xd131!\x92\xfa!H\x1eQ'\x91\xf1\xd8\x99|\xbc\xb9A\x9e\x9b\xbf\xcc\x03Y\x1eb\xda*\xf9\xab\xd8\x04Q\"XE<\xde\xdc\x90\xd5\x02\x7f\x8b\x01\xaa\xf8;\x19\xa9J\xbdQ\xe4\x1a~)\x7f\x14\xdb.01|j\xf9\x981\nx\xb0b\x8bcQG|\"\xe8wK\xe5\xb7\xf4V\x0d\x1d\xf7.\x07\x06Q\xae\xc9\"\x06j\xb4(\x8e\xd0\x7fJ\x89\x84^\xa6\x1b\x02a\xa1:\x9fH_\x14\x11-m\xa7\x81\x08\x0c\xc5^\"$\x0d\x1c\x158(\xac\x1e\xd3P\xbb\x80<\x08\xf5A\x90\x9bFX8\xb7&\x92\xf3\x89^\xe7 \x0f\xf8\xb8\x0d\xc3'\x1e\xfc\xe0Z<\x8c\xc3|n\xb5\x07\xf4k\x9b8Z\x13E\xc3!\x9d\xe3rW\xc8G\xcb\x96\x1c\xcc-B\xf9\x88\xf3\xfc$\x91aFZH\xac<\x04[\x0c\x07\x10\xf0\x7f(\x04\x1bs\xa3i<\xab\xc7-\xdf\x1b\x0f\x9c<\x99\xdf\x99\xf6/XJ\xaa&T\xc9\xaf\xaa\xe7\x95\xd7\x1a\x8a-\x95\xb5\xe4\xb2N\x07\x06\x9f\x82<\x81C\xe0\xe6\x8aC\xa5\xa1W\x184\x085\xec\xda\x83\xb3,\x85e\x94\xf1[.\x8a\xd9\xad\x128\xe4I\x0c\xbe\xeeU\x93\x1e|\xdf\xb3\xe6+h\xd2B\xb4\xd8S\x04\x99\xb8\xcf\xaeR\x16.\xdc\xea\xf2\xd1\xa1\x1eCV\x9c\x0f\xef\xac\xb4\x1d\x12\xf8\xee\xd8\xd8W\xdaOc\x02\x87Z\xcc,f\xf3\xfd]gS\x8d\x0f\xfc\xe9\xe9\nL\xc1D\x03\xb7\x10z\xb1r\x97r<&.\x12\x89e\xcf\xb2\xe5\x92Pw\x15e\x86E\x94\x19\x8b\x9f\xf3h\x95\xad\xc3B\xa0\xd3\x1c\xee\x02-\xa3\xc19K\xdf\x84\xc1f\xc3\xd2\xa6\x05\xae\x98\xabW\xcfbG\x1b\xae\xa7\x0b\x0dL\xbc7\x88\x00\xf0\xbb\x1a\xc5\xf0pOD\xc0\x91\xf1o\xf4\xd9\n\xeb\x00~\x9do\xd3yvN\x07\xa7\xf1i\xf8\xff\xfe\xaf\x9eU\xc0\xe9\x07\xe1\x82]\xbdZ\xba\xdah\x10\x8b?M\xdd\x80\xf4\x17\x96\x90U\x01lS\xf0\xc0\xc2\"oc\xbf\x0c\x1e\xc0\x88(\x0f3\xb3\x86\xe3\x86~\xbf\x0f8\xf8\xee!\xec\x99\xb9\x946\xeef\xb8Dz\x1e\xbd\xd2Jd\x9c\xec\xd3\xa6\x97\x93Ww^\x9a\xcc\xba,n&\xd0\xf8vieZ\xacJ\xa4\xafJ\xc6\xd7\xf7\x13VE@\x94/\xd7CL\x80\xa8\xba\x80\\\x11sSJ@1\x94\xe0\xbc|4\x00\xefR\xc0\xfcn\xb9\x16t\x0d{\xde\xd5\xee\x8b.8\xbf::\x82\xd2\xcf\x90L\x19\xd86\x1b\xb5\xe3\x18\xef\xf8\xfc\xe8s\x82\x15)\x88{A($\x8f\xea\x1dFK\xbe\x87\xaarN\xb1\xf8)q0\x0e\xc6\xa3W\x98\x00\xf9\xba.\x9f\x9b\xc0\x04\xf9{Q@*\x10\xd2M0\xb9\xa096p\x85\x88\x8az\x19\xd3\xaa1\xde\xad\x11M+L\xf3\x89Hs\xa0])z\xe3\xfc2\x8e]C4\x9c$\x8d+\xd9\xfd>\x04\xe1b\x9c\xabs\x0b\xef\x94\xf7\xd7lu\xdb\xc6\xcd#\xaf\xdb\x17\x91\xe7\xf1Mz\xbdbcp\xd4z9\x7f\xf5q?\x8b\xa2?\xf5\xb8\x1bL\xa7Z\x1f\xf7\xc2\xb1N\xe3\x8c\xe9\xc7\xf8m\xf9\xf7O\xef\x9e\xcbc\xcd\x0b\xf6\xf4\x8f\x97\xfe*)\xd4~Q)x\xfa\xf2\xcd\xf3\xbb\xa2\x85\xbas|\x9b\x81\x7fN\xfc\xe1LE&\x81o\xa2h\xc5\xfcpF}T\xf2\xd2I\nT\xa8\xe1k\xe7^\x8bmL8\xc1\x9a\x82\\\xd2\xad0\x91\x0b4\x06\xb1KmN\xb1 E\xb4\xea\x8b\x16{,\xf7\xbbM_&\x8c\xd1\xae/9\xaf\x17\x96y\xfd\x1d\x10\x88%3\xe2m\xb3\x9aV\xf2\xa6\xed\xe5\xe344\x94\xb5o\xe8\xa1\xd6\x90|*c\xba\xc0\x84\xe9\x820\xfd; :\x12\xd7\xe8\xb2k#\xe0\x04v\x87zS\xc3\xca\"\x17\xee\xe4FU\xe8\x1a_\xe7\xbfD3\xeed\\\xbc\xc7\xf3\x1e\xa8\xf2\xe9i\xdf\x9d\x8c\x83pys\xcc\xff;y\xe1\xddPQ\xe8\x877'\xfe\xc9\xcd\xc9\xd3\x13\xcf\xfbZ7\xb9\xc7\x80\xfc\x98\xadW\xeb\x9c=\xb0K \x8d\xbc\xf3r\x15\xf9_\x84{\xd6\x85\xdb\xa4\x15\xe1\x88\xd6\xedD\x82\x80\xf1t\xda'\x9d\xeaf{\xb3\xcfN\xd2\x18#\xc1\xc8\x11\xc2!H2BX\x1eW\xa8\x91~\x1a\xbd\x8c.\xe5\x89\xe6\xa4\x04L\xf8=>\x06\x11\xfcw:\xeb\x81\xd3\xdd\xceu\xe7\x0c\xe9\x95#q\xc1\xb8d\xf2\xa7h\x91\x1e\xf0\x9a\xcb\x9c\xf4\x10\xa6G0\x11wY\xff\xf5\xab7\xc7o\x8f\x7f~\xfe\xfe\xf8\xe4\xc5\xf1\xc9\xf1\xdb_`,_\x9d<\xff\xeei\xf9\x95\xd3\x0f\xfd0o\xee\xc4?\x811\xb0\"\x85!0\x9b\xcb\xeeFf\x04E2\xe3\x05\x07\x9cZBCX\xe7\xc5Dh\x04\xb7\xe8\x8aIB#\xe6\x9f\xdb \x8d\x10\xees\xb2y\x8c\x0f\xda\xa8\xd8\xdf\x89\xd4p\x89\xd6\xe8\x1c\x92\x1b\x86\x81\xd4hKk\x14\xf0\xa4\x0d\xe2C\xb3l(HN\xfc\x13\xde\x17$\x97A:\xbf\x00\xd7*;\x98\xfb \xd3\xe5\x90cc-\xd0\x16\x07\x81\xcf\xcc\x1dQcJ\x8a\xdb\xa6\xb1\x93\xa7'\xb5\x8d)1m\xab\xc6\xfc\x13\x83<6\xf7x\xb6\x1e7!\xf4\xfb\x12\xab\xc5O\xfeg[\xad\xe3\x93\x17\x9fo\xb5\x8e\xc3e\x9b\xd5\xaab\xa0/\xb7Z\xdb\x9fu\xb9\xb6?\xebzm7.\x98\xe9\xb4\xe7\x9f\x0f\xfa\x03\xc3X\xb4{\xa9H\xf6\xf6 S\xc9\xbc&\x10\xaak\xcaa\x0e\xbfP(\x02fX\x87L\xfe,]C\x99\xfc\n*\xe4\x97\xa2\x8e\xb4\xffy\xdb\xae\xed\xc7\xd7N#A\xd7\xd8\xe2\xa4\xf4\x8b\x93no\xd3\xd9\xcd\x14NO\xd3Y\xd7+\xbc\x1c\xeb\xbd\x17~\x10}H%\xf7=\"\x10\xb1\x85\xfb\xee\xbfn\\N\x8by\xe5n\n\xdf{\x13\xcf\x9b\x14(\xb9V\xea\xdc4X\xb3$\xf5\xd7V+\x96\xcfN\xac\xe5\xe1\xca\x83>\xbbbsA\xb3\xa9\xd2H\x96~\x01r\xcd\x10\x07\xc5\xa23\xd9\x08\xb7L\xf3\xb5\xa7\xf47H\x81\xa9yx\x8a(\xcb'\xa1\xe7'\xf74\xf3\xee\xe7q\x1c\xc5\xae\xf3\xad\x9f2\xe5K\xcbx\x99)(S \xf2\x89v\xd9t8#\xda\xa7\xcb\xa6\xa3\x19y+e\xf4sg\xd6\x83\x0e\x9b\xee\xcer\xf3Wv \xbc\x03\x97\xff\xaf\xff\xee\xed3W,\x83\xc9\xff.\x10\xe1)\xba\xbc \x8aN\xd1e\xd3\xbd\x19\xc5\xa5\xe8\xb2\xe9\xfe\xac\x07l\xfapfC\xc2(p\xc5\x80\xb7\xd3\x873A\x94\x0ez\xb0\xe3=\x81U\xeeK\xb9\xf3\xc4\x83\x15\x1a\xf6\x99\x90\x14\x88\xa8\xd1\xddU\x15\xfd\xd9\xc0\x8bM\x1f\xcfp\xe1\xf9\x9e\xed\xb3]\xb8\x0f\xee\xfe\x00\xee\xe3j\x0df\xd0\x85\xae\xcb\xa6\xc3\xe1\x8c\x83\xd9@\x8a\x00qC\xf4/\xb77\x9e\x88\xcb`]6\x0dzV\x1eFS\xdf\xda\x82e?a\xe9\xdb`\xcd\xdce\xff\\\x93?\n\x0d\xda\xa5\x0b\xce\xd3o\x9e}\xfb\xfc\xc5w\xdf\x1f\xff\xe3\x87\x97?\x9e\xbcz\xfd\xdf?\xbdy\xfb\xee\xe7\x7f\xfe\xcf/\xff\xf2\xcf\xe6\x0b\xb6<\xbf\x08~\xfb\xb0Z\x87\xd1\xe6\xf78I\xb3\x8f\x97W\xd7\xff\x1e\x0cG;\xbb{\xfb\x0f\x1f=\xee>8<\x0dOc\xe7\x96\xec; x\xbe\xc4\x86\xddY\xfbm\xc1\xd3A\xa3b\x9cc\xc7\xc8\xa2\x1e\n)\xf2_H\x1eCa\x9d\x8e\xa8\xe3\"b\xcfr3vi\xbcN1\x00a\x7f\xb7Qk\xc4\xe0\x00\x06\xad4?(\x13\xdf7\xbe\xb6\xe2\xc1\x18\xfe\x0b\x1e\xa1\xf0\xb9\x08\xf6\x9f|q\x06E\xe9\xc5\xf44>\x0d\x0fgB\x86a_\xf4\xa0v[|\x8c\xffc|\x95\xd8\xb7{n\xd1\x07)\xff\xee\xc1\x13\xe0\xab\x9c=\x01\xd6\xedz\xc0\xe0\xbf\xd0\n\x8c\xe4%\xa4\xce\x99\x8b\xfc\x10pt\x04\xc3}\xd8\x82\xd1\xde\x9e\xd7\x03\xbd\xf8Q\xb9t\xb4\xb7\x07[\x90p\xa4\x9f`\x12\x90\x83\x03\xd8\x87\x1b\xf0\x158\x04\x12\x1c\x98\xe9r\x15[4\x00\x19\x087\xc3\x81\xdd\x87}T\xd1|\xd2\x90`\x0c\xc3GJ\xd0Slk`lk$J\xf1S\xe1q\xc8\x97F\xaf\xb3\xab\xbe\x8c1\xe9\xc62\x8e\xd6\xea\xc1\x9d#O\x80\xe8\x1e\x1f\xe7u w[\xa9\x08\x06\xf6\xe0,\x0e!\xd0\xf6Z\x93\xb6\x00\x1d\x93s\x8b\x15\xa1X\x80/k\xc45~\x0d\xae\xb1@\xe7N :\xf1\xe4\xfb\xd3\x00\xb7\x8fo\xfa\xfe\x0eR|Z\xe9\xc8T\xba_*\xdc\xdf\x81-@s\x1c>#7\xe0\x10\xfb\xc8\x83.\xa4SfW\xa8\x16\x01t\x87\xf4\x87\x9fyD0\x86Q\x0e\xae\x85v\x06\xa6vv+\x85\x07\x07P\xeeq\x7f\x17\x1b\x1e\xe6\xc0\\h\xb9:\xc0\x83\x83J\xc3\xfb\xbb\xc5\xf6z\x10\x17\x01O\xfd\xfad\x02\xc2\xca\xceVd\x7f\xc58\x93U\x02\xc1*,\xbc%\x89\x16\xd5x2X\x9c9>\xf1\xca\xb7\x19\xf2\x97\x985\x12\x83[o\x03C\x80\xca\xfc\xb8\x91>z\xae\\\x83\xf9\xe1\x0b\x9f\x90 \xd8\xea6\x16\x88|\xa1\xf3)\x9b\xe5I\xc0\x94\xa8\x96\x16|\xe6\x08f\x15E\xb2q\xb3=\x87\x08\x84\x13\x84\x10\xd7\x1b\xf0\x04\xa2Id\xd3j\x08\nY\xdfo\xecZ\xfe\xdd\xc9P\x07i\x9f\xe6>x5a\x81\x90\xa8;1k^\x16\x11\xce\xa2U\xd2\x0e\x058\xc5SyG\xfa\xa6*\x9c\xf8\x93<\x8cZ\x1c\xfa;\x9e\xe1\x8d\x1f\xc4\xc9\xdf\xeb\x10\x0b\x7f\xdd\x9a\x83\x9a\x89\x19=\x8dc\xff\xda\xf5\xa5\xdb\xa3R\xf4\xf0\x13\xec\xdf\xed\x04\xfbx\x82\xcd'7h}r\x03\xf4\xe1G\x93!\x0d\xe1~`\xd7 \xff\xba\xec\xd6ok%\x9b\xb2\x19Ge\xd1t\xc0o\x19\xfcw6\xfb\xd3\xa1\xde\xb2\x8f&\x9a\xfac9\xd4\x99\xf0\x06\xb6\xeccT\xd8\xc7\xcc\xb8\x8f\x99m\x1f\xf9ne\xb8[Ae\x89{\x10\x89\xb5\x0b\xc4\xda\x05\xb8vV\"&\xfa\xeb\x0fp\xf1\xd6\xbe\xe51N\x98Uun\xf6)\xfcrg\xb8\xf6\x82\x0dB\xb0\xc4\xfe\xd2\xee\xb1\xb0'L\x10\x15\xa2\x0d\xa7lV{\\>/\xc4\xdb\xf0\xfc\xdf\xcd\x8f\xf2\xb7\xe4A\x16.\xd82\x08\xd9\xe2\x13%/5\xcbp\xfbE\xf5*\x19\xe6o\xcb\xcf}\x8c\x82\x85\x8c(V\xd7\xbb\x89\x93\xab\x13\xfa\xfd\xcd\xbc\xa1\x7fK\x1e\xc4\xec\x9c]}\x11U\xca-\xe4f\x01F\xa6\xc1zm.'\xe5Mg\xa6\xb19\nxp\xfa\xc0\x9d\x9e\x07\xeb\xd9}\xef\xeb\x07R\xb3a\xae\x1e\x1bb\x0c\x80\x18\x94\xf3@\x8a\xdd\x07V%\x02i:\xa4\x05o8\x1d\"\x1b&\xd5\x07G\x9c%mq]\xf3\x9e\xd0\x9aw\xcar\x03\xa0\xb8`\x0b\x947Si\xe5K\xdf\xc1\x7f\xce\x8a\xcbS\xa2-:\xa9\xdf\xca\xab[0\"\xea\x81e\xc5P\x93\x95kFY\xaf\xcc\xc7|\"\x92PT\x1au\xd0\xd6\x14\xe6\xb6\xf8\xa4vC\xf8Zu!\xed'Q\x16\xcf\x19ty\x81ua\xd3\xfe\xf9*:\xf3WB\xe7\xd7=\x04\xe7\x9cB\xf5\xe5\xa9\xe7\xf3Wkz\x15\x9c\x87Q\xcc\x9e\xf9\x89\xfe.\xe0\xef\xd8\x97BfO\xb4J\xea~\xd1\xa21]\x06\xe1\"\xbaT@A?\xfb,\xd9\xc4\xc1\xda/\x19\x06\x06\x8d\x98\xd1\xa8N\xf8-y \x07\xff\x17\xe3\xc6\xaa\xbaF\xfe)\x18p\x11\x06\xf8\xe6{\x16\x11!\xc8\xf48}4\x0e\xe3g\xa1\x9eM\x8f\xfd\xf0\x9c\x8dkyo[TQq8^\xc7\xd1y\xec\xaf\xe9P\x84\x18\xfb\x8e\xef\x98\x0c-v\x16-\xae\xb58<\xce\xf3+\x0e\xf9I\x10\x85oR?ek\x16\xa6\x8eVu:\x98\xa9&\\\xe7i\x1cG\x97/\xc4\n\xe7_\x96?`\xea\x0d}\x8bN\xcf\xb7\xfd\xca\xc0\xe6\xebZ\xb1\xba5hD\xd4\x9f\x84\x8eEt\x9c\xe6\xcd\x0f\xb4\x8d\x0f\xeb6\xbe~\xd3\xff\xb0`s\x9b\xc3\x0b\xdej\n\n\x88\x81\x95\xdb0\x14\xbfu(\xe0\xbbc\x84\x82\xbc\xaa\x82\x02^\xd7\n\x04\xc5\xfae \xe0\xc0v\xeb\xaf\x0cf\x10/\xfc`\xc5\x16\x90F\xca\x16B!\x0c\xbb6\xc5\xd8\xc1\xc6\x8f\xfdur\x0b\xab\xd0H\x06T\x0d\xfd\xb5 >\xc5\x0di\xec\x0cW\x1c7\xba\x07\xce7\xabh\xfe\xa1t\xde\xec_\xe1\xf2Mp\x0d\xe4\x02\xbaQ\x0fB\x199x\x8a\x96\x0b\xfc>\x9e\x0egt\x01\x0b\x95\x8b^\xdd\x91\x08\x02#F\xe5\x9f\xd2g\xf5&4w\xbe\xa1\xe5\x00\xfe\xd4;Z\xdd\xba\xcat\xed\xcb\xda8X<\x00\xf6F&\x8b1\xf7\xd1N\xa98\xa3\xda\xe5b\xbfN\xdaW\xac\x9a4\xcb\x15J\x08\x0f\x0e\xe1q\xb1h \x870,i\xb3Vp\x08;\xa3\x12(\xf0\xb2\x9db\xd9\x05/\xdb-\x96-x\xd9^\xb1\xec#/{X,\xbb\xe6e\x8f\x8ae\xe7\xbc\xac4\xbe5\x1c\xc2ni,\xefyY\xa9\xdf3^V\xea\xf7\x12\x0ea\xaf\xd4\xc7\x15\x1c\xc2~\xa9\xbd7\xbc\xac4\xb7\xe7\xbc\xac\xd4\xc7S\xbe|%7\xc4W\xbc\xac\xf4\xedo\xbcl\xbfX\xf6\x01\x93\x15\x96*\x1eca\xa9\x97\x1f\xb1\xb04\x95\xb7ph\x80\xf8\xc1\x18\x9c\xd3\xd3\x81\xe1\x1ez\x88o|\xc3\x9bG\xf8\xe6\xcc\xf0\xe61\xbeI\x0do\x86\xd4Qhz5\xc4W\x1fM\xafF\xf8jiz\xb5\x83\xaf\xca\xd4\x1c\xff\x1b\xd1\xd0\xcbBh\xfe\xb7\xb3;\x86{\xa7\xa7\xce=\xc3\xd8\xa9\xaf\xd3Scg\xd4\xdb\x89\xe9\xdd>M\xed\xbdi\xa5F;\xd4\xeaK\xf3Kj\xf5uI\xc6P\xac\xfa\x8c_\xd6\xce\xb5\xd3\x03\xe7\x17\xfe\xbfk\x96\xe0\xb3\xf8\xe7\xf9\x1b\xfe\x0f\xd2\xbc\xce+\xfa\xff \xff?>\xd2S\x84\x8f\xf4\xffWX{\xb9\xc4\x8a\xe2\x9f\x17/\x9c\x99)\x90\xc6\xeb*\x92\xcc\xc5\xb5%\x0d4Y\x9e\x1c\xd6z\x93\xf5(X\xc6ho\xcf#B\xe8\xca\xa1h\xbd\xa3b[\xca\x02\x19\xab\xef\xef\xed\xed\xc8\x0f2\xf1\xc1\xae\xe1\x033\xc9\xde\xa1FvG\x8fw\x1f\xef?\x1c=\xde\xf3\xbcb\xf8\xdby\xb4`\xb0\x89\x82Bz\\\x8av\xb8\xf6\xafe\xda\x85\xf3\x98\xf9)\x8b)\xf3\xc2\xe0\xea\x85\xf83\xd1\x0d8\xd0wb\xa0\x8f\x8a;[\xf8%o\xbc\xd3SG\xc4p\xcc\x836\x0e\xf0\xfbm\xc5'{\xd0\xd5\x987S\xb0\x92\x9f\xaa\x9b\xa5\x85\xac\xc6\x9d\xc9crG2\"\xb6\x0c0\xfd\xa3\x9f^\xf4\xd7\xfe\x95\x8b\xf9\xc1E\xf1\xcd\x0d\x8c<\x19\xda\xfbC\xb09\x0e?\xfa\xab`Ami\xbf\xf58\xdc\xcbUt\xf9\x92}d+\xa4`\x83\xe4$\xe2kz\xee\xa6\xf9\x1bO\xfa\x1fie\xb2\x97\xf4z%\xe2m\x17\xaeU\x1bE]\xcd\xffkH\xdfU\xe0\xdcrw\xfe\xff\xfca\x919\x87\"\xfb \x19iP\xc6\xd5\xb8\xa40`J'C\xce\xff\xd1\x13\x8a\x88:\xa4\x8c\xe4\xf14\x10Z]q\x16\xd84C\x0f\xeeN\x87\xc8\x99,7]\x1d\x91A/\xff\xcc\xc0\xd5r\xd0\xc8\x94\xff\xb6\xd7\x03\x97\x12\xb8\x95B\x90\xf7eV!\xde\x0foOdt\x98\xf7u7\xcb\x1e\xf8\xd4\x99\x8f\nk\xfd\xd5\xd4\xe7\xe3\x0b\xa7\xd9\x0c\x0e\xcb\x91oA\x13p\x17\xe1\xd9\xd5@\x8c\x03\x0e\xb6\x98H\xf3H\x05;Q\x9c\xfe\xc0\xae)\xd5\x8c\xfaQ\x8c\xde\x1e\xb2\x7f\x06\x0b\x19=]\xfd\xba\xb9\x81G2\xf6y\x18\xfd\xc4\x96\xd4\x86x\xd4[\x08\xa3g\xd1z\xe3\xa7?\xf2\xe3Lu\xb4\x02\xbd\xe6<\xe2\xd0\x8d\xeeV\x97b)\xb5\x02\xbd\xe6\x1d\xe2\xc5\xcb\\Du\x9f<\xbf*\x86\x98\xc7\x9cWa\x1e\xa6\xbe\x98I\x9a\x97,2\xfe\x85\x9f2a\xa7@\xa5Y\xc2\x16\xdf\xeao\n\xc1\xfdL8\xe2\xc4x\x98\x10\xe8\xc5i\n\xe0\xb0\x14:\x96y\"w1)\xe6\xb6\x87\x04\xd7|l\x89f\xaa\xf4\x04\"8\x80\xe4\x89\x879\x1a\xd0j]\xa6\xe6\x17n|\x98\xf8?\xf2\xd0\xda\x87\xfcCD\n\x0b\xd1A\x82\xa9\xdd\nox\x97\x14\xc65Bc!z\x0eu!\xc4\xa9\xe0\x03C\x01\xd7\xddC\x08<>\xc4\xeea\xd9\x9dL\x80\xb0_\xbbD/\xebbo\x9bc\xebJty\x1f4\xce\xce\xd4\xf6\xb7U\x14-\x19\x0e\\\xb1\x15\x87>z\x9c\xd76\xf4okC;\xa3b`\xaa\xe1h\x1f\x99\xf7\xfda9\xf2\xd5\xe8\xf1\x1e\xff\xc5)\x94\xdcm\x82\x93$\xe2\xd7\xcd\x0d\xec=\xdc\xd9\xdd-~\xc7/\xe3\x1d\xfe\x8b\x92Q\xa8\xaa\xbc|\xbf\xd4\xf5p\xb8;\x1c\x0ek'\xf2\xc2:\x11\x9cb\xa9\x1fl\x99?\xbe\xcf\x1f\x9f\xe6\x8f\xaf\xf2\xc7\x0f\xf9\xe3\x8f\xf9\xe3e\xfe\xb8\xa8\x1d\xd6;\xeb\xb0\x1e\xfcz\x1a\xde\x07\x19\xc8D\xdfn\xf9\xc4\x0f\xd27\xd5X#\xbfs2\xa7X\xf4\x0b\xe7U\x8aE\xff\xe4\xb4M\xb1\xe8g\xc0\x88\xd2\xd5A\xfeP\x1fg\x9d\x8f#\xd2\xed\x9b:\x86\xe8'sK\xf9\nO:\x85\xfa\xa8\xbe}Kx\xa0R\xce)\xd5\x7f\x8b\xec\xa3\x85\x04%\xa5\x9d\xc4x<\x9do]\xba\x8c|,;\xcb\x1f\xdf\xe4\x8f\x97\xf9\xe3\xfb\xfc\xf1i\xfe\xf8*\x7f\xfc\x90?\xfe\x98?.\xf2\xc7\xeb\xfcq\x9d?n\xf2\xc7\xe3\xfc\xf1*\x7f<\xcf\x1f/\xf2\xc7\x8f\xf9\xe3\xf3\xfc\xf1713{V\x17C\x82\x07\x839\x8a\x97\xbf\xed\x10\x0bb\xf2\x06\x0e[\xff\x13a\x05c\xdd\xef\xd7\x9a\xcdS\xff\xe3m'@\x91\xdd\x9a'\x02\xe2\xe6\x8a\xa7\xa3\x861\x83\xca\xffB\xb3\x9c\xa3\xfa'\xe2'=\x81.\xe7\xf50\x9b=_\x07Q\x01&\xfcqL\xc9\xeb\xa0\x0b\xffp\xe7\xc4L\xa2\xd2\xa2\xb63{\x98K\xc8A1\xb2V\xfa\x83\x83g\xe65A\xfb\xcf\x8d\xd0~\x0f3\x934+\xf7\xe4\x9fb\xa4s\xaa\\p\xcaV\x1aI\xc8LK\x84\xd0\x111h\xfb\x80\x0e;\x9c]\xdb\xdf\x19\"\x11P\x8dO\x1a!WL\xdf\xec\xef\x8c\x06\x90\x07+\xdd\xd9\xdd\xe1\xcc6\n\xa6^\xbb\xc3\xc1\x08\xbd\x96\x19lS\xeb\x949f[|\xd6%\x1e\x8e/\x1b\xa7\xdd\xc6$\xf3z+\xcce\xbb\x87\xd0AJ\xe6\xdf\xfc\xe2\x99@:\x8df0\xa6[\xee\xb5\xd9\x1bM\xff\x93\xba\xd4\xba=\xf3(}\xa8\xb9!\x11\xfc\xc1\xbee\x05\x99n\xb0\xdeDI\x12\x9c\xad\x84\xb7\xfb\x18\x02!\xaa$\x0b\x10\x8a=\xe64\x11v\x7f\xb8\xf5\xfc\xfc\xd7\xf64Rp(\xe95)\x00\xc4\x90k\x06-@\\D&\x85XRF\xf9E\xc8\xcf\x1b%\xd46\x7f7\"|\xa4\xde\xf1Q8]\x07\xb7K\x1e\xcam\xbalNC\xa7v\x86\xdf[\x19a\xdb\x909l\xe4(u{\x88\xb9/\xa9\xf4\x85a,\x8a\xf8\x99\xb2\xf1/E6\xfe{G\x98\xa2_\xd0\xfe1\xf8\xf39\xdb\xa4 \xaa\xde\xf0\x06^QN0\\\x81{M7MqZ\xd3\xd5\x8cff\xbfy\xecW\x8ad\x87cc\x95\xda\x90\xd3\x06\x83,#\x9b\xdf\xa9\x97\x8f\xfeOA\xc6G\x87\xbe\xcc\xb3\x17\xf4\x07r\xc8a\x8f\x8er\xd8\x83\xce\x10C\xdf\xa8\x9f\x03Cj\xe0\x04\x14\x94P\x13\xe5$\xad\n\xf9\xe9,\xed\x01E\x85+r\xb9\xe5\x14\xa6\xbc\xf9y\x0fV=\xb4\xff\xa8\xbaIq\x00Ea\x87z\x85\xbe=\xf2MU\\\x86\x02;W\x93P\n\x8dX\xae$Q\xbbM\"@-al~\x13\x18\xda\xd1\x8a\x1aZ\xd4?.\xa0:\xa5\xee\\g Z\x12\xf8pF\xa9n([y\x9d\x05\"\x14D\xacDB,\n\xfa\xb6\xec \xf1`C\x0fE\xf6\x9c\xd5\x10\x1b\xceW&\xe2@\xedb\x1c$\xa1\xd6\x12\x91%\xc2)'p\x16\xd3h6\xeb \x1cCf\x80>\xe5`\xa7\xff\x08\xee\xf1t\xb58A\x02\xf8\xf1l\xf0\xa7\xdc\x9b\x823\x1e2\xeb\xbb\xac\xb3\x14[\x875\x8b\xc9\xcc'\"r\xd3\x84\x13\xaa\xe2\x11\x1c\xe5\xf1MS-\x1d{?\xf1\x97\xec\xdb\x92\xb5B\x8d\xe5\x1eM1\xee\xb3\xab\x94\x85\x0b\xb7z\x8e\xc8Fs\x0cYq\xb7\xf0\xc6/\x8d\xeeN>?\x02\x90\xc85V\xba\xd6\xf0\x83\xed\xbc\x7f\xcf\x92\x1f\xa3E\xb6\xaa\xc6.\xfd\xe8\xaf\xb2\xa2w\x1f:\x8a\xf5\xcfY\xfa,\n\x97\xc1\xf97\xd7\xefb\x0c\x86\xdb_D\x97\xe1*\xf2\x17T\x0e\x87\"\x1eB>\x80\xdc\xe9h4\x18j;h\xf8\xd4\xae\xf1*\xdb\x16\x18\x15\xbd\xa2\x92;\xe0C]\x86\xfd%K\xe7\x17^\xc5E+\x9f\x93qJmvU\xd51\x92-\xca\x97\xb8\x9fl\xd8\xfc)\xd6L\xccH2\xf7\xe7\x0dJ\xcb\xe1\xa6^?\xbd`\xe8\x07\x17\xe9\xe9F\xe5\x9f:E\x91y\x14\x80\x9aSM\xbe\x8c\xce\x88\xa8.\xed'\xa9\x9ff \x1c\x1d\xc2\xee\x00\xd3[\x04\xfdl\xb3\xf0S\xf62\xf2\x17Ax\xfe\x06\xdf\xbb\xce\x12\x1d\x17i@\x9c\xb3\xb8e\xb5w\xf1\xcaux\xc1<\n\x93h\xc5\xfa\xa8\x14se\xffo\xd9U\xaa\x91'Y\xbc\xe2@\x86\x17\x07R\x89\xcc\xe5[)\xdcQ\x7f\xf1\xd7+\xea\xc1s\xc3~\xca\xae\xca!\xb4\xa1\xaaF\xfb[\x9d\x1f\x1d\xf2\xcfY\xda\x12\xd2R^\xf78t\xcbw\x15L\x80\xc1\x18\xa6l\xf6\xf7\xc2\x12\xa5s\xaf\x08w~\xfa\xf7\x0c^\x84H\x91\xcb\x1b<\xef\x0b&\x10\x83)9\x93\xd4\xc7\x96\x83\x17\x16[F5\x9a;\xdc\x7fT\xea1\x11#\xd9-\xe2!j\x93\x02I\x92\x0b\x06\x07\xbcL\xbe\xf0\xdc\xa0\x07I\xff\xdd\xebo\x9f\xbe}\xfe\xfe\xd9\xab\x93\x17\xc7\xdf\xbd\xe9\xb5\xdc>\x0c\x0e\x8d\x80\xeccp\xd1\x7f\xbc\xf1\\\xd6\xdf\xf8\xd7\xfc\xa8\xeb(\xde3\xf7\xfa\xf6\xd5w\xdf\xbdl\xdb\xab\xbc9U\x07f\xb5/\x02UEt\xa2\x86\x9c\xf0\x97=\xe8\xc4\xc5\xd1\x05\xc2\xf3t\xe6}\xc5\xf7\xf9\xc1\x83\xff\x03\x14J\xe2G\n\xdb\xf4\xee\xa7\x97\x87\xc9\xa5\x7f~\xce\xe2\xed,\xd8\xe6xg\xe1\xaf\xa2\x90m\xa3N$\xed\xff\x96\xf4\xd7\xfe\xe6\xff\x07\x00\x00\xff\xffPK\x07\x08v\xf2\x8aA\x86\xba\x01\x00\xc5\x87\x08\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00 \x00swagger-ui.cssUT\x05\x00\x01\x80Cm8\xec\xfd{s\xdb8\xb27\x8e\xff\xff\xbc\n=\xbb\x95\x9a\x99\x1dS!EQ\x17\xabf\xeb\xc8\xb1\x93q6r\xc6\xcem\x92\xad\xad)\x8a\x84$\xda\xe0\xe5\x90\xd4\xcdz\xf6\xbd\xff\x8aw\\\x1a $;s\xf6\xf7\xad\xb3\xd9dl\xe2\xd3\x8dFw\x03h4\x00\xb2\x9bl\xed\xe5\x12\xc5\xda\xda;\xfc\x9fN\xe7\xe5\xdf\xfeo'\x08c\xdf\xc6\xde#\xea:I\xd2\xd9\x0c\xbbzW\xef\xfc\xbf\xce\xec\xfac\xe7\x9d\xe7\xa0 A\x9d\xff\xd7Yz\xe9j=\xef:\xa1\xff2@N\x88\xed\xe4%M\xf7\xb7\x97\x8b0H\xb5\x85\xed{x\x7f\x9e\xd8A\xa2%(\xf6\x16\x13'\xc4a|\xfeWs\xde7,\xe3\xdfD\xfd\x9dU\xea\xe3\x03\xf6\x02\xa4\xad\x90\xb7\\\xa5\xe7F\xd7\xb0&\x9a\x9fh)\xda\xa5Z\xe2=\"\xcdv\xef\xd7Izn\xe8\xfa\x8b\x89\xb6E\xf3\x07/\x85K)\xce\xf3\xd0\xdd\x1f|;^z\xc1\xb9N\x95\xd8q\xea9\x18\x9dQ\xcf\x12\xcf\xa5\x9f,\xc20E1\xf5h\x85l\x97y\x14\xd8\x1b\xea\xf7\x049\xa9\x17\x06\x07\xd7K\"l\xef\xcf\xe78t\x1e\xe8\x16\x1b\x87\\K\x99\xf0\xe7=\xe4OJ\x19\xbb\x83!\xf2;\xb4\xa4\x0bo\xe9\xd8Q\xc6\xf0\x8cy\xbc\x8eii}\xdb\x93UZPT\xea0\x90\xdf\xe9\xeb\xd1\x8e\x96+>T\xca\x9d\x87\xbbL\xe4\xdd2\x1f:\x16a\xec\xf3\xca\xfbg\xba\x8f\xd0/1JP\xfa\xaf3\xbe Y\xcf}\x8f)\x01*\xcbf\xb5\x92\xa2(\xfdW=\xb6\xdaQ\x84\xec\xd8\x0e\x1ct^\x14\x01\xd5\x974\xe7\xe7\x9a\x1f>j\x8b\xd0Y'\x9a\x17\x04\xcc\xd4C\x8a\xaa\x04-\x85o\xc1\x16\x95\xf3 \xde\xeb&\x91\xed\xba\xd9l\xa0K\xda\xd0\xb0\x89\xbd`)n@+\xae\x92^\x02,E\xa7\x11\x87p\x9df\xbevnD\xbbr\xec\xed\\\xe4\xc0\x8fh\x972\xb3$\xc2n\x82\xd2C\xd5\xb0\xaei!\xbf\xd3\x1d\xe6\xff\x0e\xb8a\x01\xa3%\n\\h\xda\xac\xe7\x14j\xd6$\x9e\x16\x83a5\xacW\xdd>\xb5\xe7\x18M|{\xa7m=7]\x15\x1d\xa5\xd6\xf2d\xbb\xf2R\xa4\xe5\x83\xf4y\x11y1Sl\xb8\x8cQ\x92\x80\x83\x8f\xd2(Xw\xe1\xbaw\xd9\xeb4\x04\xac\xeb\xac\x90\xf30\x0fwP\x1f\x89m\xd7\x0b\xffu\x92Vd\x0e\x15\xac\xfd9\x8a3\xef-\x19\xe7^\xa9%\x91\x17h@\x17\x14\x10\x85\xeb\x94&:\x94C\x90\xa0\xa1 \xb2cg\x05v\xdfLY\xb9\xc7LJ\x0f\xd3\xc2\xc5\"A\xe9\xb9\xd6cB+\x8aU#K\xf1@s2nX\xdc\x06\x11]\x13\\@\xd2q#[C\xbf\xf00\xd2\xd6\x11\x0em\xb7R\x82pt\xcaG\xed\xcaO\xe9X\x00\xa5\xb6\x87\x13:\nE\xc1Z\x12\x85&k\xdf\xb7\xe3}\x8d\xc0^\x92j^\xca\xf4*\xc7\x0e66\xec\xc4\xb4V\x8b \xed_\xcc$\xe4G\xd8N\x115\x93Rd]\x17\xcd\xd7\xcb\xce\xdf\xa8q! \xb1\xe7v\x96!v\x01\xac\x96\xf7;\x90\xe2\xaf\x8b\xc5\x02\xa2\x98c\xdby\x80)\xd8\xf8\xa7\xa4X\xc6\x9eK\x04Ndx\xdbY\xc7\xf8G\xd7N\xeds\xcf\xb7\x97\xe8e\x14,'Y\xf7\x1d\xf4\xcf\xbc\xcf\x17\xef\xef\xb6\xfa?\xde,\xc3\xe9t:\xbd\xf9\xf0iu\xf5i\x99\xfd\x98\xffs\xfdj\xfau:\x9d^^]\x0e\x07\xef\xb2\x07o~\xbf{\xfd\xe5\xd7\xbb\x8f\xf3\xde7\xdd\xed\xbd\xde\x7f\xbb\xbd\xb8\xf8\xf6f\xec}\xfbp\xf1v\xfe\xe5u\xf0\xed\xf3[\xfc\xf5\xcb\x9d\xe58\x18\xff\x96\x11\xecW\xd1\xe7\xd7+\xfd\xcb\x951{\xef\xdfl\xe6\x1f\xacU\x81\xb7\xfa\xf3\xdf\xa7\xc5\xff.\xb7/\xd1\xaf\x17\xab\xaf\xbd\x14\xbb\xaf.\xbco_\xdch~\xaf{\xc3\xe1\xfa\xe5\xb5w\x11}\xbb\xd4\xbd\xcf\x8f\x9fofW\xc6\xf6\xb6\xf79\xb4?\xad\x06\x8e\xff\xf9#z\xb0>}5\xa3\xf8\xeb#~\xb8\xbe\x1f\xfd|}\xb9\xeb\xbf\x0fV\xa9\xf3\xc6\xc0\xee\x9b\xab%zc$\xf3`6@\x97\xba\xf7\xf5\xcb\xdd\xe6\xab\xffi\x90\xfd>\xff\xf2Y\xff\xfaa\xe4]\xff\xba\x1c\xa07\xc6\xd6}\x93\x8c\xaf\x1f^?\xcc{o\xf1\xf5\xeb\xd5\xcd\xa7W\x17\x97s\xf3-\xbe\xbe\xfc\xb4\xbe\xf1\x8c\xfb\xd9\xc7\xab\xdd\xf5\xa5c\xbd\xbb\xbf2\xde_\xce\xf67\x1f\xb6\xcb\xd9\xfdtw\xf3a\xb4}\xffa\xb4\x9b\xbd\xd2\xb7\xb3\x8f\xe1nv\x19\xeeg\xaf\xa6\xcb\xeb\xea\xef}\x7f\xf9\xdb\xafo\x1f\xbe\xddG\x1f\xee\xae\xbe\xd6\xf28\xfe\x9d\xff\xdb\x87\xb7\xa1\xfb\xeb\xdd\xf6\xbd7\xda\xb8\xa6k\xbe\x0b\x9c\xc7w\xfex\xffm?\xda\xbd\xff\xf8`\xbd{\x9c\xee\xdf=^\xef\xdf\xfd\xfe\xf6\xe1\x9bg<\xa2/\x96\xfe\xf5\xf7e:\x0ff\xf7\x04\xdf\xabo\xbf\xdf\xdc;>\xde\xbao\xf0f\xee]\xec\xbf\xbd\xf9:\xf8\xfa\xe5\xed\xc6\xfd\xfdv|\xed]7:xcl?~\xd2\xc7\xd7\xfeJw\x7f\x9d\x0e\xde\xed\xc7kg_\xdb\xe2~\xde\xd37\xe8\xcd\xeb\xed\xbb\xc7\xab\xf5\xec\xd58\x9d\xe7\xfaY\xa5\xf37\xd6\xe3\xfb\xe0F\xff\xe4\x7f\xa6d\x9e\x07\xb3u\xa9\xd3\xf5\xd7\xde8}g\xaeV\xce\xab\xd1\xee\xdd\xfdt\xe3\x18w\x96\xf3\xe6\xd3\xe6\x93\xff\xf9qn~\xde\x7f\xed}\xfe\xf0\xed\xcb\xd7\xfbk\xef\xa2?\xff\xb2[;\x8fQf{EY\n9\x9c+\xe3\xe6\xfd\xc3\xdd\xe6\xab\xf99\xfd\xf6\xc5\xd2?|\xba\x1d_g\xb6~e=\xd8_n\x07\xb3\x8fw\x97\xef?~\xed\xdf\xe8\x9fz7\xfa\xe7\xd7\xb3\x8f\xaf_\xdf\xdc/{\xb3\xc7o\x97\xb7\xf7\x0f\xdb\x9b\x87\xdb\xfe\xec~\xb9\x9d]]\x13\xfc\xf0\xda1\xefVs\xff\x06\x13\xfc\"\x9a\xdf\xad\x1a\xbf\xcb\xe8\xd2\xf1?\xaf\xdc7\xe3\xfd\xe77\xe3\xcd\xfcR\xf7n\x0b\xfd,?\xbdYm\xdc7\xe3G\xfb\xcdx{}usy}y\xbd\x9d}\xfc\xb4\xfc\xc7\x95\xb1\xfa\xda\xc3\xeb\xbc\xec\xd5\x83\xf7\x9b7\x1d\x95v\x1a\xdc\xbd\xf9\xbc\xb7\x7f\xff\x86\xbf]}\xdb\xcf{\xfa\xd21\xef2\x1d\x0e\xec/\xd6\xa3\xfb\xe6\xf5\xfak\xef\xf3\xdb\xbbK\xdd\xcb\xf0\xef|\x1c}\xbb\x0c\xcd\x9b{g\x7f\xfbpk\xde\xdc\x7f5o\x1f?\xedf\x9f>\xf5n\xef\xdf\xbe\xba\xd5?\xedo.\xa7\xfd\xd9\xc7\xe9vv\x7fe\xce>\\\xd7\xfc\xbe\xbd\x19\xdf\xbb_\x0c<\x0f\xee\x08~w4\xbf\xc7V~\x9bL\xf6w&\xe0\x93\x99\xaf\xbe\x1a\xe7~\xf9\xe9\xe1\xeeM\x81+\xfa]\xde\x0f?\xf6\x97\xbf]\x8e\xfb\xce\x9b\xd7\xf7v\xef\xb3~\xfd\xe6\xf3:\xeb\xef\x8ew\xfd\xf2\xb7\xe4\xe2\xc3\xcfof\xd9\x08q\xff\xe1\xd3\xdd\xc5\xe7_\xef\xed\xaf\x9b\xc7\x97/\x1fG\x97\xef\x92\xcb\xfe\xd2y\xf3\xbb\xf7\xf5j\xfa\xe6\xe2\xfa\x1fo.\x02\xf4\xf2\xe5\xe2u\xb4\x9d.\xb7\xd3\x8b\xf1hj\xbf\xeeE\xf7\xf8\xd3mF~\xf1\xf6\xee\x93u\x15?\xbc].\x97\xbf\xfc\xf2S'F\x11\xb2\xd3\x8e\xde\x11\x8e\xa4\x9a1x\xc6\xc1\xf4\"\x1f\xe6n\x8b\xc1t\xba\x18\xbd\x1c\xaf\xfew0\xfd\xdf\xc1\xf4?u0}\x7f\xf9u\x7fw\xbf\xba\xba\xbb\xcc\x06\xd3\xaf\xfb\xd6\xc1\xafe0m\xf8\xdd\xaa\xf1\xfb\x0f\x1aLo?\xb6\x0e~G\x0d\xa6\xb7\xed\x83\xf3\xf7\x19L7\xaf>\xe8\xc6u6\x18\xcd\xea\xc1\xd4\xbf\xeb\xbf\xb4~\xbex\xfd\xdb\xc5b:{\xed\xbf\x9c],w\xa3\xbb\xe9\x9b/\xaf\x02c:\xf5?,\xcd\xfe\xed\xe0\xe1\xe2\xf2\x1f\xb37\xb3\xcbW\xdb\xebWhv\x8d\xfc\xd7/\xad[{{\xe5E\xd3/\xdbO\xab\xed\xd5\xfd\xecr3\x9f~\xc1_\x1e6\x9f/\xb6\xeb\xd1\xe6\xf6zz1\xbd\xda^\xbc\x8aV\xa3O\x03G\xcf\xc7\xa5+\xfc\xfa\xe3\xc3\x87\xf5\xad\xff\xea\x95\xd2\x00<\xd2\xf2x\x97\x1c\x85\xb3`\x99\x1d~\xef#T\x8f\xbf/\xc7\xf7/\xfb\xb7\xd3\xafw\xbf\xaf\xa2o\xcb\xe9\xf4\xc3\xa7\x87\xff.\x03\xd9\xe6\x7f\xbf\xbdL\xa6\x17\xaf\xaf\xdc/71\xba\xcdF\xe6\xdbj\xe0|\xd9\xbf\x9d\xed\xec_\xeft\xe72\xdc\xbc\xebY\x8f\xef\xfcb\x1c{\x97\x8f\xb5\xe3\xfe\xd7\xdf\xa7\x9b\xd9\x87\xfe\xf6\xddv:\xfa\xcd\\m\xbf~\xb9\x89\xbf\xfd~\xbb\xfc\xea\x7f\x0e\xec/\xfd\xf1\xf5\xfa\xe7\xe1f\x7f\xbd\xb4\xbf\xdc\x8e\xaf\xb1c|\xfcxq\xe3\\\xdd`\xfb\x0d\xbeF\xc1[\xfc\xc9\x8c\xde\x7f~s3\xb0{3\xeb\xdb\xab\xeb\x97\xb9\x8f^f\xfd\xf7\"\xfd\xf6\xfb\xdd\xaa\x19#\x96\xe3\xeb\xb2\xee\xf7\xbe\xf5\xf8\xde\xcf\xc7\xe0M\xd6\xe7\xf31\xf9\xd7\xbb\xf8\xb7\x0fo\xab\xb9\xe2\xeb\xc7\xcf\xd3\xe5mo\xbc\xff\xf6aj\xbc\xbb\xff\x9a~}\xbc\xda\xcd>L\xcd\xf7\x1f\xfa\xbb\x9b\x8f\xcb\xc7\xd9\xfd\xa7\xa4\xec'\x9b\xd9\xe5\xc3f\xf6q\x9a\xce.\xaf\x06\xb3\x8f\xd3\xc1\xec\x9e\x18c_]g\xe3~\xed_\x8d<\x99/\xea^\xad\x1b\xd35\xdd\xbde\xce\xf6\xd6\xc6\xf1\x9d\xcd\xec\xe3\x83\xf5\xfe\xc3h;\xf3F\xfb\x99gd\xf4\xa9cf}\xf1u\xff\xdd\x17\xeb\xf1z\xdf\xf0\xbd{\xf3\xf9\xf1\xab\xf96r~\xbd\x8b\xe6\xbd\xfe2\x1b\xbf\xdf\xfb\xaf\xbd\xb9\xf9Y\xff\xed\xc351Nf\xe3\x00Q\xa7\xcc\x1e\xfb\xff\xc0\xb1\xf9\xf7\xe9\xe0\xd6|\x8b\xbf\xfe~\xb7q\xf0\xddf\xde\xdb\x12\xf3\xe2E87\xef6No\xb5q^]\\\xde\xee\xa7\xfb\xd9\xe5\x95q\xfdju\xf3\xf5\xcbM4\x0f\xb2\xb2eT\xf0\xb9\xb8\xf9\xf81z;\x0fn\xf4\xaf_\xac\xfbo\x9f\xf0\xd5o\x1f\xdef\xfc\xd7\xf6\x17\xfc\xf0\xfe\xe1z7\xbb\xbf\xd6\xdf\x7ft\x1eo\xee\xddW\xb3\xc7\xab\xdd\xdd\xc7o\xaff\x0fo/\xef>^\xeb\xb3\xcb\xe5nv9\xdd\xcf>:;\x82\xdf\xd5\xbcwc\xcc\xbf|^\xbbW\x0d\xbfoo(~z+\xbf|\xee\xac\xe7\x13\xec\xf8\xb8\xf7\xed\xcb\xdd\x1b\xc7\x1f\xa7\xd7\xbf\x16\xba|\xef\x8b\xe7\x85\xdb\xfb\xab\xfd\xec\xfe\xd6\xbay\xbc\xea\xdd\xe8\xd7\x8f\xf9\xbc\xf0p\xbd\xbf}\xb8y=\xbb\xbf\xdd\xbe\xbf\xbc\xda\xce.\xafw7\x8fW^\xc3O\xde\xfa7\x97\xa3\xf0\x1f\x97\xe3_\x7f{\xfc\xf4\xb2\x8d\xa6\xfd\xef\xe2\xe5v:\xbd{5\x9d^O\xa7\xcb\xcb\xe9\x87\xeb\xe9tuu1\xdd]]\xbc\x1c\xddN\xbfd\xe3\xe6\xed\x14\xf8\xdf\xd7\x8b\xe9\xed\x15\xf0\xfc\xfa\xeajzu1\x9d\xce.\x98\x82\x8b\xe9\xe5\xd5\xab\xa9~u7\x9d^]^\xf0<\xef\xae?\xbe\xbe\xf8\xf4\xe5\xea\xc3\xf5\xe6\xa5=\x9dn/\xa7\xb7\xd3WW\xb7\xb3\xbb\xe9\xe5h\x1a\xbe\x0f>~6n?^\x0e\xdf\xbeMV\xbf\x99\x9b\x0f3\xf3\xb7\x97/\xbf)\xcd/\xc6@m\x829*\xbe\xcf\xe6\xd7W\xb7\x0f_\x96\xbd\xe9\xff\xc6\xf7\xff\x7f\x1d\xdf\xab\xce\x01t\x1c\x9e\x8d\xad\x8asV\xcfH\xc9y\xab\x8c!U\xe7\xad\xc7\xcf\xbf\xe2\xed\xb7\x0f\xe3\x0f\xdf~\xbf\xd9\xb8\xbf\xbf\xbd\xcf|\xe9\x9b7{\xb6\xf8Y%\xae\xbfy\xfcj\xce\x1e\xde^\x15I\x97\x99!\x1f\xbf\xdb\xd7\x1d\x0d\xbf\xaf\xad\xfc\x9e-\xbeoOn\x1c\x15\xdf\xdf]\xb6\xf2\xfbN\xf1=\x1a\xbc5\x1f\xb2\x11\xe2\x91M\x96\xe8\x9f.\x93\xd9vv\xff\xe1.\xfc\xfa\x9b\xf5\xe6\xbf\xfb\x1f~\xbb\x99\xdf\xdd\x7f\x9e]\xdd\x1a\x8bWw\x97\xcb\x9f\xbd\xe0\xe5\xe0\xe7\xb7\xc6\xf4\xed\xa7]\xb2\x9c^\xbd\x99NM\xe3b\xfav\xf6A\x7f\xf3\xb5\x18\xcf?|\xfa\xfc\xfe\xee\x1f\xd6\xab\xaf\xd7\xd7\x92\x04J\xb3\x15C\x1f\x8e\xa1\x7f\x03\x8e\xcf\xccCwO=\xe0N\"\xb8\xf4A\x04\xd7\xa3\xcf\xcd\xb8\x98\xfe\x95\xdeZ\xae6\xe6\xe8\x87\xfc\x01\x9dE\x18\xfb\xf4F\xacA\xff\xda\xa3\x7f5\xe9_\xfb\xf4\xaf\x16\xfd\xeb\x80\xfe\x95?\x0b\xb4J}\xba\x15\xf9Nu\xb1\x89\x83|\xdb\xc3\xff\x12\x95\x96\xdbT\xa2\xe2\xc8N\x92m\x18\xbbB@\x8a\xc4\xbcS\xb4K\x85\x85\xeb\x98!,\xb64\xe9G\x1e\xbd\xc7c{\xf4.UH7\x9a>'\x101\xe7\x94\xca\xf3Q\xd4\xb3|\xd7\x93~BKPmK\xd2\x0fW\xf4\xaf\xb4-\xd6\xf8\x94\x0dH\xba7\xd8I\x84\x9cT\xcb\xf7\xd8\x0e\xe2\xf3%b\"M3\x06\xbbq\xb5\x9b\\\x9d0\xb2\x06\xdd\x9e\xf5BF5\xde\x19\x03\x96\xca\x18\x0e\xbb\xc3\xa1\x94\xac\xbf3Y\xaa\xa1\xbc\"s\xd7\xe7\xea1\xcd\xaeiJ\xa9\x06<\xd5`\xd0\x1d\xb4\xc8\xc6\xb7\xc8\xd2\xa5$\xa3\x9d\xc5U\xd3\xeb\xca\x1bd\xedF\\5\x03y5C\xbe\x9a\xa1\xd1\xed\xf7Z\xea\x19r\xf5\xf4\xe5\xf5\x18;\x83#a\xcf,2$\xc5\xc9\xb5C\xedq\xf6< \xf1:E\x934\x8c\xce\xf5I\\zd\xc9M\x9f`\xb4\xc8~'\xce\x0eT\xe7k\xb2\x9f\x1f5/p\xd1.\xfb\xe5\xdf\xff\xe5#\xd7\xb3;\x89\x13#\x14t\xec\xc0\xed\xfc\xe8{Ay\xea\xc0\xd4\x91\xff\xd3A,W\x90<\xa17d\xd4'u\x08\x80P\xadO\x00\x84\xed\xdd\x02\xaaM\xa9g\x00\x84*\x9d\x03\xaa\xaf\xbd\x7f@\x95)t\x11\xa8\xb2\xf6^\x02\xe9Q\xa5\xa3@\xb5\xb5\xf7\x15\x88J\xa9\xbb\xe4\x84\xcf\xdfc\x14\xbaL\xf9\xb0>\xbd3h\xe9G\xfeS\xba\x91\x7fb/\xe2\xe8\x14;\x11G\xa7\xd0\x87\xf8\xba\xd4\xba\x10G\xa7\xd4\x83\xf8\xda\x14:\x10_\x95J\xff\xe1\xabR\xe8>\xbc\x06\x95z\x0f_\x97B\xe7\xe1\x89\xd4\xfa\x8e\xff\xe7w\x9d\xb6^\x82\x9f\xd2K\xf0\x89\xbd\x84\xa3S\xec%\x1c\x9dB/\xe1\xebR\xeb%\x1c\x9dR/\xe1kS\xe8%|U*\xbd\x84\xafJ\xa1\x97\xf0\x1aT\xea%|]\n\xbd\x84'R\xeb%\xf8\xbb\xf4\x12\xb2^\xcf_\x1e\xe8c\xa0\xb4XN\xb8A1y\xce>?W\x9d?\xfd\xbf\x9e\x1f\x85qj\x07)K\x12\xa4\xb6\x17\x00D\xf9s\x82\xac}\xa6;\xf0\xc2d\xd3\xee)\xf2\xc0t\xacH\n2)\xcc\xbe\x85\xa0\xfeirBd\xc7\x89)\x94\x08\x9f&\x11D\xc6IDQ\xce\x97\x9a\x83\x82\x94v\x9d\"\x19t\x1e\x84\xe5O\x13\xa2\xac\xf6sn\x90\x98/\xb54\x8c\x8e\xe6\x93\x86\x11\xc7'\xef4Gs\xe2;\xc5\xbc\xea\xc7G\xf3*\xc88nY\xe7=\x9a\xd7\xf1\x8b\xab\xda*L_P\xaaN`\x98SX ms\n3\x89yNa'\xb1\xd0)\xec\xda\x82\x12\xd5\x11\xa51\xdd\xf1N'\xb2\xdc\xf1\x9c\xc4\x86;\x9e\x97\xccn\xc7s\x93\x99\xedxnmV\x93\x1a\x08\x1f]\x9d\xc8@\xc7s\x12\x1b\xe8x^2\x03\x1d\xcfMf\xa0\xe3\xb91QL\xb7<\xfe\xce\x1f\x83\x07a\x1aqL\x1389O\x94\xc2\xe4zMt\xfc\x18\\\xf1\x08\x92\x13\x84\x05\xa9\x14\xe4%\xe9\xda|[uD\xaa\x98\xfb\xa7\xb4\x03 Ri\x86\xaf\xdc\n\x89\xc0\xf8\x14\x81\x01\"\x15\x811)0\xed\xfb6}\xcf-g9)\x1f\x95\xd18s\xbb\xa7;O+\x9alt\x00\xe8\xb2\xc7\"\xda\xfa^]1\x1e\x00\xd4E\x81\x88~N\xdf_\x86\x18\x94%\"\x0e\xb8\xe2\x90wz\x80>\x7f.\xa2\x0e\x80{\x81\x94\xba\x8e\xef\x8bs;\x9f\xd2\x8f7\x03Av\x8a%\x08\xf2S\x8dA\xb08\xdd\x1e\x04\x93\xd3L\xc2\xa9\x0f\xb2\x8a\x82Y\x14\x86\x9b\xb9\x9d\xcd\xe3'\x98\xca\x7f\x92\xa5\xfc'\x1b\xca\x7f\x06;\xf9O4\x93\xffT+\xc1\x06\xc1'\x19\x04?\xc9 \xf8\xc9\x06\xc1\xcf`\x90'\x0ee\xac\xe6@\x83\xd04Zq\xd5\xaf\xa2\x13\xbc\xe3 \xc3\x05\xc8\x8eA\xb0a\x18\x1c\xd8\xb5\xe3\x07m\x19\xdb{\x06k\x9a&\x87\xf5=\x17\x82Z\x96\xc5A\x01\xd8p8\xe4`\x89\x877\xcd\x85\xef\x128\x1e\x8f9 .\x8c\x0d\xc1m\xdb\xe6%\x0d\xc3\x00\x92\xc1q\x1c\x01k\x00\x8c\x10\x82u\x9b\xdf\xd2d\xc0\x8b~\xf6\x87\xc3\x83P\xf6&g\x85\xd3\xc6:\x0d]%\xd8\xfeQ?\xd3_\x9ce\xb1\xf8Yw\xfc\x93\x80p\xd4B8\x12\x11\x0e[\x08\x87\"\xc2A\x0b\xe1@Dh\xb5\x10Z\"\xc2~\x0ba_Dh\xb6\x10\x9a\"\xc2^\x0baODh\xb4\x10\x1a\"B\xdd\x92\x13\xeaB\xed\xe8\xbd6\xd2\x9e\x98\xd6h%6 \xea|\x8c\xe1\x9c6^\xces\xda3\x1dt\xd8\x82\x88uX\x92\x08p\xd6\x82\x88uV\x92\x08p\xd4\x82\x88uT\x92\x08p\xd2\x82\x88uR\x92H\xa8\x08\xd6AI\"\xc09\x0b\"\xd69I\"\xc01\x0b\"\xd61I\"\xc0)\x0b\"\xd6)I\"\xc0!\x0b\"\xd6!I\"\xc8\x19K*\xd6\x9f(2\xb1+\xf1\x8eH\x11\x82N\x98O`1r\xd9\xc1{\xa8\xf7u~\x9c\xe5\x81\x8bE\xdf0\x07\x82Y\x01\x82\x0f{\x16?\x89\x84\xb1\x1d,\xf9\x81~`\x02\xf3\xf32\xc4<\xd7\xf9\x10@\xee\x11\xc6\xe1\x96\xc6\xf2\xaf\x0e\xa8\xa5\x85\xe0\x7f]\xcc\x17\x86\xcdO\xa8\xd1:\x8e0+\xb0\x85z\x8e\xcdO\xe6\x05w\x90\xc2\xee\x0f\xccE\x0f6J\xe4\x05l\x04\xe2Z\xba>\xe2\xad\xb2\nS\x08\x9d\x99f\xce\xcf\xa9 r\xa4\x0b\xa7v\x10o\x9b.\x1f\x8e\x94\xc1\x10B\x01\x837\xcc\xe1\xd0\xe2\x9b B\xc7\xf6x\xc8\x0b]E\x19<\xc1\x18\xa1\xb9\xc3\xeb$\xb07l@\xa2\xeb\xc6\xbc\xcf\xb3\xce\xa5\x9e\xe35k\x1b]\xef\xf7\xc7|\x08\x03 Mk\x88\\\x91W\x01\xf8\xf1\xc0q\x80 &\xc7\xa3\x04$q\\\x04\x91l\xedd\x85\\\x88`1X,\x16\xbc\xf4%\x01\xa4H4Z\xb8\x0b\xde{K\n\xb8s,\x16\x0e\x9a\x8bH\xa0\xde\xef.\\\xbe\x15d:\x91\"\x10f\x88\xe6\x9aV\xbe\xea\x84&\x80\xde\x7f\xd2\x9d\xc7\xf5\xd0\x1d\xdb\xae\xb7N\xce\xd9\xa1\"6\x18@\xd7\xe8Y1b\xd3\xadq\x8f\x85\x81(\x93EA\xa0>\x032\x00\x8cf\xe8\xac\xe4@R9\xd6\"\x0fc\x067\x1e\x8f\xc7\xc0\xea\xaf\xdew+\xc0y\x92<[iUz!\xd7\x90\xc5:P\xa41\xad\xd8U,\xe0UV\x1bbU\x96\xb5q+\xf7\x16[\xe4\x82*\xe2y\x15\xdb\x81\xa2\x96\xc8\x05kO\xb6\x1cX\xe7\"\xd3Q\"\xff\xe21\"\x17\x03\x90\xb0\x97\x01@\xd0\xd1x\x9c\xc8\xd7\x00\xa4\xc8\xddx\xa8\xdc\xe3\x98\x8c\xdfS\x9c\x8eO\xdd=\xd9\xefT\xa4Sw=\x86\xdb1\xde\xa7\xe0~*\xb9\xbeX'\x12oB\x97d!B\x8f\xe4\x80\x02\x87\xe4p\xb0?\xb20\xa1;r@\xa17\xb2\xc8\x16g|\xb6\x01\x90\xcbN>\xdd\x15\xdbe;\xc2\x13\xfd\xef\xe3\x88\x02\x9fc'!\xc0\xe7X\x88\xd0\xe78\xa0\xc0\xe78\x1c\xecs,L\xe8s\x1cP\xe8s\xc7M\xb9,\xbc6oc \xa2\xa0<\x9e\x06\xfb\x1c\x9b\x80}\xba\xcf\xe1\xe7\xf49|\xb2\xcf\xd1\xfc4\xadx d\xc5\xaeH\xf5\x02/\xe5-\x82\xf8,\xe4d\xa0\xf93\x0eZ\xdeF&\x91\xc0&f\xb6\x84\x08\x03D\xe3\xf2w\xd4\xb5\x0f\xd1\x07\xb8!\xdcn\x8f\xb4-\xd8\x92a\xb5\xc8(\x1cDd\x17\x1e\x08\x9b\x86\xc7\x81\xd6\xe1`\xa0\x818\x14l#&\xee\x15\x9a\x89\xdb\xbe\x17Z\x8a\x0f\xf5\x85\xc6b\xf7\xe2\xebm\xc0v\x83\xa9\x0cl[\"\x1a\x15\x1a\xd1W\xb4!\x8b\x13\x98\x90\x85\xc1\x16\xf4U\x0c\xe8+\xd9\xcfW3\x9f\xafj=68\x16\x1b\xcf?\xc1v\x023\xe1V3aE3\xb18\x81\x99X\x18l&\xacb&\xacd&\xacf&\xacj&6\x9e\x14\x9b \xc3f\xa2\x80\xc9\xcav\xc3\xadf\xd0\xd7\xba\xf3\x87\xe7zG\xef\xf4\xa3]\xa7\x17\xed:\xf4\xa6\xcbD \x05\xd6\xd4\x13\xd54R\xaa F\x815\x99PM\xbd\x92\xbe\xbd]r$Xc_Vc&\xb9\xaeP\x1f\x84\x03k\xb3\xa0\xda\xfa\xa5\xc4m\xb5\xc9p\n\x83\xf0\x01t\xa2lT\xff\xd3\xfcHR\xd9\xf3\xbb\x92\xa0\xb2\xef\xebM-\x95\xb6\x99\xf8x\x87\x12T\xf8,>\xa5\xe0T\n3{\xedi\xfe\x9f\xe8h\xc2\xba\xbe\x83\x9f\x81u}g7\x93\xd6\xd9f\xf4\x13\xbc\x0c\xac\xefOp2\x99?\xe1?\xd1\x9f\x84u}\x07\x7f\x02\xeb\xfa\xce\xfe$\xad\xb3\xcd\xbe'\xf8\x13X\xdf\xf3\xf8\x13Ua\x14\xa3\xfa\x0b\x1e\xda.\xff\xb4E\xfdq.m_~\x08\xa8\xf9\\W\xe2\xc4!\xa6?%\xd2\xcdb@=\xff\xe6\x11\x13\xb0\x15Q\x9f~\x80S\x89E\xa4\xa7W\x9fRb\x8a\xf3\xf0N?\x14\xe9I\xbe>#\xaf\x8f\x0fa\x8b*\x8d\xb2J \xc4-j5\xaaZyD^\xb1QT\xcc\x97fu\xf7\xf2\xba\xf9\xc8\xb8\xa8\xbbW\xd6\x0dD\xceE\xdd\xbd\xaan\x1e\x91\xd7\xdd+\xea\xe6K\xb3\xba\xcb\x86k\xa2\x96\xd7M\x07\x10e\xfdM\xe3\x01L.A\xd5|\xa0<\x97\xa1P\x80&\xd2@\xad\x02\x00Q\xc9P+\x01\xc0\x142\x94j\x00\xca\xab{\xd4\x9a\xb6\xf00>HoS+\xcc\xd0\x07\xde\x99\xb3\x98\x01\xf0\xe7\xc2'\xb3B\xc8-Ko\xcf\x8a\xa5\x0e_\xa4 \x9f\xcf\x1d\xbb\xaa[\xe4\x99u\xf5B\xe7o$\x10\xfb?!\x84\xc0\xc9+9D^Z\xcb!\xec\x08\x8d\x1c\xe2\xbe@\xc8!r\xf8J\x10\x89\xcf75\xc9\xdc\x9e\xa8K\xec\xf9u\xb3\x84\xce_\xcb#\xf6\x7fB\x1eI\x17 \xe5\x11\xf6\x82F\x9e\xb6\x8eP;\xad\xb0/(t\x06\x85p\xb5\xe8!\xbe\xa4\x83\xf8\xd2\xfe\xe1\xb7t\x0f_\xda;|y\xe7\xf0\xdb\xfa\x86\xdf\xde5\xfc\xb6\x9e\xe1\xcb;\x86\xdf\xd6/\xfc\xf6n\xe1\xb7\xf6\n\xbf\xb5S\xf8*}\xc2W\xe8\x12~[\x8f\xf0[;\x84\xaf\xd2\x1f|\x85\xee\xe0\xab\xf6\x06\xffI\x9dA\xe8\xf7X\xe2\xf7X\xea\xf7\xb8\xc5\xef\xb1\xd4\xef\xb1\xdc\xefq\x9b\xdf\xe3v\xbf\xc7m~\x8f\xe5~\x8f\xdb\xfc\x1e\xb7\xfb=n\xf5{\xdc\xea\xf7X\xc5\xef\xb1\x82\xdf\xe36\xbf\xc7\xad~\x8fU\xfc\x1e+\xf8=V\xf5\xfb\xb6\x80\x88&v\x16\xe7\xf6\x82}5j\xf6t\x8e\x16a\x8c\x0e\xe5\xc7{\xcf\xff\xd2\xf9\x0b\xfd\xe5A\x98\xcd\xc1\xc1\xc8\x8e\xcf\xe7a\xbab\x01\x87\xbf=\x86\x99o1\xcfqI\x92I\xc7\x14U\xdc\xf2\x960esqMAYt\xd2N\xb9\x93O\xa3b\x91\x9aRP\xaa\xa6\x18\x12\xac)U\xd8 V\x9d\x8e\x9dl\xa8\x93\x08\xecK\xe5\xf5e\xe2\xfa\xea\xd2\xc2\x82\xc9\x8c[\x17\xc2\x82a\x99`\x98\x12\x8c*u\x03\xd9\xe7\xfc<\xe6S\x81L\xf1\\\xf2A\xc2\xae\xeb\xcd\xdb?4\xd8u\xbd\x94E\x01\xfd\xc5m@`\xa9C\x17k\x0eb\x17\xddn\xaa\xc5\xe1\x96\x81\xc5\xe1\x16Bi\xcb8\\G<\xb6x\xceQ8!^\xfb\x01+A\xfeP\x80\x05+ \x8b8:m\xe1\xed\x90{(\x90\xd8\xde\x87\xeb\xf4<\x7fD\xbc\xfeJ\xa1\x7f\x1c\x18\xdbg=Lf~\xb2\x1c\xf6\x00\x12\x01;\x01\xcfC\xe0\x07\x00\x1046\x89\x83\xbd\x81C\x08\x1d\x82GJ}\x02\x84K\xdd\x02\x10\xa5\xdd3DDR\xe7\xc8\xd73R\xffPp\x10\x85\x01\xd4\xcd\x06:\xa9\xd3\xf8m>\xe3\xb7\xb9\x0c\xcbA\xe41\x1c\x0ev\x18\xbf\xcd_|Uwa\x81ro\x01\xd0rg\xe1\xe4P\xf0\x15\x98F\xee*\xfe\x93<\x05v\n,w\n\xdc\xe6\x14\xb8\xcd)X\x0e\"\xa7\xe0p\xb0S\xe06\xa7\xc0\xaaN\xc1\x02\xe5N\x01\xa0\xe5N\xc1\xc9\xa1\xe0\x140\x8d\xdc)p\x9bSPt\x0b\x8cvu%D\xee\xbd\x0e{5?\xd12\x10\xf9,\xfb\x9dfS\x9a\x08\xe4V\x99\x99aJ\x90\x90E\xc4c^R\xcd^\xa7!\xb5E\x90==7&\x95\x94\xe7F\xc7\xe8\xe4\xd9|\xfa\xb7\xc6\xeb\xf5\xfc\xe7\xea\x85\xa9@\x15\xf9\xe1S\xae\n\xbd\xa9\"\x7f\xe7A\xfd\x13\xc0\xa1\x8c$H\x1ea\xece\xeb\x89\xea\x0b\xe3\x13\xb2\xcc\xf5\xe2\xe2\x95\xff\xe5\x17\xcb\xeb\x9a\x88\x92\x82\xe5\x04|\nH\x90\xc5H@\xf5\xab0\xf6\x1e\xc3 =A\x808\xdc\xb2\xb5s\xfd#/\xdf\xc6vt\xa8\x19d\xbf\x9dg\xffL\xe8_A\xbd\x03\xa4\xc5\xc3 \xfb@P\xaf\x16\xa3\x0d\x8a\x13\x04\xd4_\x15M\xe0\xc7B+6,\x8f\xb6fU\xa3\xd0\x9c\xb4L\xa2R\xd8\xbc2\xb9Z\xcd,\x91\x8c`\x0d\xd8\x1b\x96\xc9K\x91\x9fhIj\xc7)%N\xf1\x19\xfd\xfcyS\x15\xf90\xff9\xff\xbcy\x92\x8f)\x05\x0f\x889\n\\\x805\n\\\x96q\xf6\x88c\x8b\x02\x17bZ\xbe\xe8\x93\xe7[\x14\xb0\xac\xcb\xa7$\xf7\xe2\x11\xc4{n'(\x1b\xc8\x00\xeeU\x11\xcb\xbf~N\xd6P=\x845\x1e\xa3\xd4Y\x81:\xcfKx\xad\x17\x8f\xc9\n\xcag4\xff\x04\xe1Ee\xd0\x8aE\x06\x07\xac\x97A\x85\xc6\xcb\xf9\xe4\xb6\x03\xb84\xa6jxp\x96\xca9T\x86\x02\x98PF\xc9\xf9@6\xc9\xb94&\x01\xf80\xca\xcf9\xc1\xba/uS\xaa\x1e\xd4\x0e\xa9\xe5\x9c\x13\xa8\xe4\xfbu\x92z\x8b=\xd0q\"\xdby`\xfb\x0d\xf1\xac\"\xac\xb2T\"\xedW8\xb6\xf3\xe4\xac\xa8\xbeS?\x01YsF\xa9Q|\x07\xca9\xb1\xfd\x87|\xc8\xd6\x00\x99\xab\xc2\xccQ\xbaE(\xe0+(\x01L\x0d\xd5S\xb6\x8a$\xb2\x1dT1\x83k\xb2\xf3\xd74\x1eh~\xae\x97\xa4\xb17_\xa7H\xc0\xb2\xa0\xa29\x96\x08\xb6\xf7\xe4A\x0da\xc3\xc29\xda,X1\xa3\xbaP\xc3\xaa\xe9Ar{Ul\xd8~\xd4p\xa2\xba\x91\xcc4\x15\xab\xda4<\xaf\xca\x0c43\x89\x11*\x9e\xac\x11\x1a\x96\x84% \xaer;0=\x95\xb4\x04\xd9Qk\x96P_-\x0e\xdf\xea\xccl\xebz\x81\x8d\x8bh\x9c\x88A\xb5\x1c|\xaeO\xca\xffB\x9c\x0c \xa7\x1e\xcb\xc9(9\x19\x10\xa7\x9e\x84\x93\xc9r\xea\x95\x9cz\x10'S\xc2\xa9\xcfr2KN&\xc4\xa9/\xe1d\xb1\x9c\xfa%\xa7>\xc4\xc9\x92p\x1a\xb0\x9c\xac\x92\x93\x05q\x1aH8\x0dYN\x83\x92\xd3\x00\xe24\x94p\x1a\xb1\x9c\x86%\xa7!\xc4i$\xe14f9\x8dJN#\x88\x13\xb6\x93T\xe6\x9cz\xf6?\x96\xe38\xfb\xdf\x84\xf8\x19\x085\x97Y\xd4\xa7\xcb\xd6C\xe5\xbbm7\xe8\\\x9f\xd4$\xe0\xca*\xe7e\xc8\x96o\x0d/\x83\xe0e\x00\xbc\x92U\xec\x05\x0f\x99d\x15i\x80\x966)F\x81\x00\x05)\x89\x0d\x80\xd8\xa0\x88\x0d\x85\\\xdb\x81\xe7O\xe4\xfd\x88\xc6\x9e\xbe\xa4\x86\x18>\xf7\xaaZc\x0e\x0c/\xbe\xcb\xc2\x1a\xac\xe5\xf8\xb55\xcbFmA\xf6\x9c\xcbk\x81\x04\xadK\xafgZa\xe7\xd5W<\x8e^d\xf3\xd4\xa7\xad\xb3a)\x9e\xba\xd4>\xcd\xb8\x7f\xcaj\xfbT\xab\x7f\xbf\x057+\xd1\xf3\xae\xb9a\xee\xcf\xb2\xec\x86Y?\xe3\xca\x1b\xae\xe0\xb9\x17\xdf\"\xfd?\xd7\xfa\x9b\xeabOY\x82\x8b\x18\x1d\xbb\n\x17\xf19a!.bu\xdaZ\\\xac\xa9\x13\x96\xe3\xacY\x9f\x7fE\x0e\xd6\xf0|\x8br\x90\xfd3\xaf\xcb\xc1:\xbe\xd3\xd2\x9c\xb2\xee3\xad\xce)\x9eO^\xa0\x0b\xb8\x9d\xb6F\x170;u\x99.`\xf7\xc4\x95\xba\x80\xeb\xd3\x17\xebB\xc3\x1c\xbb^\xe7\xe7\xeb',\xd9\xe5\xcc\x8e\\\xb5\xcb\x99\x1d\xb9p\x973;r\xed.gv\xe4\xf2]\xce\xec\xc8\x15\xbc\x9c\xd9\x91\x8bx9\xb3#\xd7\xf1rf\xc7/\xe5[\xfc\xf6\x89\xaby\x96\xfb\xe2i\x0bz\x90\xddS\xd6\xf4T\xf7?aY\x0f\xd3\xb3+{\x85\xa5\xbd\xc21\x9a\x9c\xa7\xff\xcc\xcb}\x9e\xdf\xb3\xaf\xf6\xfd?c\xb1\x0fTr\xc2Z\xdf?a5\xf8\xacK}P\x80\xd65\xdfs\xad\xf4\xfd\xa7,\xf4Y\xe2\x13\xd7\xf9\x90\x0cO^\xe6\x9fb\xd7?g\x95\x7f\x9a\xc1\xbf\xe3\"\xdf\xff\x9ek|\x88\xf9\xf3,\xf1!\xce\xcf\xb9\xc2\x87\xf8?\xfb\x02\x1f\xd6\xfd\xb3\xad\xef\xfdgZ\xde\xc3|\x8e^\xdd\xc3lNY\xdc\xc3\x9cN\\\xdb\x8b\xb4t\xca\xd2\xde\xff\xde+{\xa0\x82g\\\xd8\x03\xdc\x9f{]\x0fT\xf1\xbd\x96\xf5\xfe\xf3\xaf\xea\xfd\xe7\\\xd4\x83\xccN\\\xd3\x83\xbcN^\xd2\x83\xdc\x9e\xba\xa2\x07\x99>\xc3\x82^`\x93\xa3\xd7\xf3\xec\xcc\xfc\x94\xe5\xbc\x8c\xd7\xb1\xaby\x19\xafc\x17\xf32^\xc7\xae\xe5e\xbc\x8e]\xca\xcbx\x1d\xbb\x92\x97\xf1:v!/\xe3u\xec:^\xc6\xeb\x84e\xbc\xd4]\x9f\xba\x8a\x97\xae\xae\x8e^\xc4K\x17\x84'\xac\xe1\xfd\xa7-\xe1!\xf2\xe3V\xf0\xa2\xc5:~\xe6\xc5:\xcf\xef\xd9\x17\xeb\xf8\xcfX\xac\x03\x95\x9c\xb0X\xc7',\xea\x9eu\xb1\x0e\n\xd0\xbav{\xae\xc5:~\xcab\x9d%>q\xb1\x0e\xc9\xf0\xe4\xc5\xfa)v\xfds\x16\xeb\xa7\x19\xfc;.\xd6\xf1\xf7\\\xacC\xcc\x9fg\xb1\x0eq~\xce\xc5:\xc4\xff\xd9\x17\xeb\xb0\xee\x9fm\xb1\x8e\x9fi\xb1\x0e\xf39z\xb1\x0e\xb39e\xb1\x0es:q\xb1.\xd2\xd2)\x8bu\xfc\xbd\x17\xeb@\x05\xcf\xb8X\x07\xb8?\xf7b\x1d\xa8\xe2{-\xd6\xf1\xf3/\xd6\xf1s.\xd6Af'.\xd6A^'/\xd6AnO]\xac\x83L\x9fa\xb1.\xb0\xc9\xd1\x8buvf~\xcab]\xc6\xeb\xd8\xc5\xba\x8c\xd7\xb1\x8bu\x19\xafc\x17\xeb2^\xc7.\xd6e\xbc\x8e]\xac\xcbx\x1d\xbbX\x97\xf1:v\xb1.\xe3u\xc2b]\xea\xaeO]\xacKWWG/\xd6\xa5\x0b\xc2\x13\x16\xeb\xf8i\x8bu\x88\x9c[\xac3\xf4\x87\x05\x0e\xed4\x7fG\xce\xe4\x0fz-\xcc@\xe3\x12\x9a\xbf1\xa7\x05\x1b\x94\xd8\x93\xde\x82\xb4\xc8\xdf\x82\xa4.W\x83V\x12\xad\x81+\xbcYH\xfd\xfc\x81\xe6\x1f#\xb2\x7f\x94\xc4\xbe\xba\xc0\xb0l\xc7\x98\xb9\x06\xab\xc9\x86)\xd9\xa8\xd2\xc4\x0e\x12-A\xb1\xb78,\xc2 \xd5\x16\xb6\xef\xe1\xfd\xb9fG\x11FZ\xb2OR\xe4\x9f]`/x\x98\xd9\xce\x87\xfc\xd7\xd7a\x90\x9e\xd9\x1b\x14xq'@\xbb\xea\xe7\xb3\x15\xc2\x1b\x94-r\x9b\x9f:\x01Z\xa3\xb3\xf5|\x1d\xa4\xeb\xb38\x9c\x87ix\x16d\xff$h\x19\xa2\xce\xda;\xb3c\xcf\xc6g\x8d\x14\x8ct\x9c`K\x14\xc6K\xcf>\x83\xc0\xb9t\x9a\xa0E\xc2*J*\x9e\x80\xc7:\xa1\x8b\xa8\xf7\xa0e\x0f(\xa2Wa\x90\x84\xd8N\xce\xfc0\xb0\x9d0\xfbO\x98G\x13,\xa3u\xec\xa1\x98!\xcd\x9fun2\x95\x96\x00\x11}\xad`\x8a\x03\xa3\xf6\xc6\x1e\xa2\xb6\x17\x86\xa3x\x00v\x15R\xa7+\x84\xed\x84&/\x9e\x9dI\xccT\x16\xa9Z5\xf5|D\xd7\x91?\x81\xa0\xf3\xd0\x0d\x03\x8f\xc2^\xe4\x8f:\xb3\x8f\x10\xde\xb1\xb1\x97\xa4!m\x85\xe2\x99\x80bi\xc7\xb6\x1f\x06.-|\xf9\x10\x14\xc9N\x1eP\xbc\xf10\xa6\xfd\x84x\x0e\x91\x95\x8d(>\xa1\xe5\xa56\xf6\x98\x0f_/\x12\xad\xc8\xc3\x91\xc0\xe2\x89\xc2`I\x8f=\xf9;\xafT\xebc\xb0e\x95\nu*\x0c\xd0^6\x88\xaa\xca\xe1\x1f-\x06X#V\xaf\x11\xd25\x8d%M\xb2-r\xc8}\xee\x93\xefT1\xf7E\xf8\xc5\xd6\xa0\x00\x06\x0f\xe8Q\x80\x1e\x0f0)\x00\xf7y\xfa\xc5\xb6/\x17q\xb1\xb5(\x80\xc5\x03\x06\x14`\xc0\x03\x86m\xcd\x1cQ\x80\x11\x0f\x18S\x80\xb1~\xfc\x9b\xba\x19\x8f\x15Z\x84E@Fa1\x90]X\x0cd\x1a\x16\x03Y\xa7U\xe2E\xf1\xb9\xb36\x1b\xb1\x18\xc8L\nm\x1f\xb1\x18\xc8X,&\xb3\x97\x82\xc1\x14F\x05\xba\xbf\x8b\x8d\xe8\xb7\xb5\xc3` \xa0 \xfdv\x0b\xfa\xed\x06l\x11v\x91\x7f\xed\xac\xd5|~\xbb\xf5Z\x1b=b \xa0\xed\xfc#M'\xb6R\xdb\xe0\xc7\x00@+\xe1v+\xe1v+\xe1v+\xb5\x08\xbb\xc8?v\xd6j%\xdcn\xa5\xd6F\x8f\x18\x08h%\xcc[\x89\xc2xA\xb4N\xb5\x18%\xa8\xb9\xdfnG\x11\xb2c;p\x8a/qN4?|d\x1f2&Z\xa7i\x18\x14l\xce\xcfs\xfc\"t\xd6\x89\xe6\x05\x01\xfb\x16`\xa2F\x1eZ~\x86\xed\\\x9fD\xb6\xebz\xc1\x92]\x18\xaf\x8cC\xb9\xd1\xca\xbf>y\xd5\xab\xca\xf8\xd7\x19\xaf\xcc\xaa\xac\xcf\x97\xf5\xab\xb2\x11_f\xd5\xf5\x0d\xf8B\xadW\x17\xf7\xac\x17l\xa1\xa5W\x85\x16\xfb\xa9\xe5\x956\xac)\x87<\xa5\xa1\xd7\xa4\xfcg\x9a\xf3\xcd\xe6\x1cBl;\xf3\xb0\x0d-\xddf\xc5\x15\x93\xf2\x01\xc5\xa4\x84@1-#\x0b\xc8D\xdb@R\xb2\xc0U\xf1\xce\xb9\x12\x90\xfd\xcc\x96{\xc1\n\xc5^ZA\xca_\x15\xe6\x89\x03\xe39\xd9t#q\x1e\xa2\x18\xf2\x1f\xa2\x18r!\xa2\x18\xf2\"\xb2n\xd8\x91\xc8\xea!_\"\xcaAw\"\xcaa\x8f\"E\x10;U\x86j\xf7+JX\xd0\xb5(qA\xef\xa2\x04\x86\x1d\x8c\x16Y\xecc\xbc\xd0\xb0\x9b\x11\xfc$\x9eF\xa0*gS\xf06\x85\xa8d\x95E\x132\x0f\xf4\xa5\x0e\xe8K\xfd\xcf\x97\xba\x9f\xdf\xe6}\xbe\xdc\xf9|\xb9\xef\xf9-\xae\xe7\xabx\x9e\xaf\xe2x~\x9b\xdf\xf9mn\xe7\xb7z\x9d\xaf\xe6t\xac\xbc\x02\x9f\xf3U\\\xce?\xce\xe3`\xe7\xc2R\xe7\xc2R\xe7\xc2R\xe7\xc2R\xe7\xc2m\xce\x85\xe5\xce\x85\xe5\xce\x85[\x9c\x0b\xab8\x17Vq.\xdc\xe6\\\xb8\xcd\xb9p\xabsa5\xe7b\xe5\x158\x17Vq.\xcc9\x17\x05Lc\xdby@\xee\x01\xa34E\xb1\x96D\xb6\x93E^]\x83\xfb>E\x01\xd4\xd2\x8c\x19\x0b\xd7\xba\xba%\"\xf0\xd1\xd2\xe6\xd8\xf72x\xfb\xb8z\x009\xe6\xdf/:F\\\x80\xa2Mb\xa8\x92\\h\x05\xa9\x15f\x83\xba\xaac[\xc2\x11\xb46\x84\xafB\xa1\x1d\x12\x91\xf1\xb1\"s\x04\xad\"\xf3U\x14\"S\x14x\xa5%!\xf6\xdcC\xbe\x8f^u\x16\x0e\x93z)F4\xa6\xdb\xb38\x98\x13F{\x06e)\x98\xfa\x00\x8a\x94;O\xbbT\x1cL$\x18\x0f\xb4\x9e\xc9\x0fk\x89}%\x81}EyY\\\x9b\xb82\xc9\xb0\x92dXQ2\x16g\xb1^\xe5\x05\x0f\x87\x14\xedR\xcdEN\x18\xdb\xe5 Vv\xd1\x9b\xc1\xce\xb8'\xe7\xb6\x93z\x1b\x04\x14\xe4\xcb\\\xe0\xf9*\xdc\xb0k\xe4\xfc\xb9\x80\xff\xc6K\xbc\x145o\x1cMc;H\xbc\xea\\g\x18w\xba\x86\x95t\x90\x9d \xcd\x0b&\xd2R\xbe=\x85\x90\x87p\x9df*:7\xa2]\xc7\x0d\xd3\x14\xb9\x1dg\x1d\xc7(H_eLX\xba$=d\xff\x14Yn-\xddGP\x8e\xc0\xdf\x16\xab\xc1\xda\x15\x81\xd9zk\x90\xe5\\,\xe1o{D9\x1f\xc6\xf8[\x93(\xe7\x03\x19\x7f\xdb'\xca\xf9P\xc6\xdfZd\xfd|0\xe3o\x07\x04\xc0\x84$\x18\x92\x12@U\x8c\x08\xc0\x00\x92qL\x00\xc6\x90\x0c\xc5+\xd4\x1b\xd0I\x9b\xf1\x859\xf2\x85\x93\xdc\"\x0c\x042\n\x0d\x01\xedBC@\xd3\xd0\x10\xd0:\x8c,\xa0\x81h\x0cl#F\x1a\xd0L4\x06\xb6\x14\x8d\x11\x1b\x8b\xc6)\xec\xf6\xab\x8e\xdd\xa5\x15\xfdV#\xfa\xad6\xf4[M\xe8\xb7Z\xd0o5\xa0\xdfn?\xbf\xdd|~\xbb\xf5\xfcv\xe3\xf9j\xb6\xf3\x8f3\x9d\xd8J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xddJ\xb8\xddJ\xb8\xddJ\xb8\xddJX\xcdJ\x98\xb3\x12\x05\xdb\x1a\x07\x91Z\xb7\xbd\x83H\x9f[\xf3 R\xe4\xb6\x7f\x10ipk\x1d\x84\xaa\xcb<\xa1*e=`\xab\xf5\xaa\xb2\x1ePVq\xe5\xd6\xd0[\xcd\xac\xe8L\x9e\xce\xac\xda`\x9a|Y\xd5\x08\xb3\xcf\x95\xf5+\x9e}\x9e\xa7U\x95q\x0b\xf6\xad6\xa8\xca\x06|\xd9\xb0*\x1b\x02eU\xfb\xb8U\xfeV\x1bUt#\x9en\\\x95\x8d\xf9\xb2,\xe0\x10\xf5\xb7\xad\x96\xae\xbc\xd8\xad\x95\xd35\xb3\xff\xf1\xa0mX\x00\x93\xaaY\x83\xee`0\x18\x0c9d\x9e\xc7.0\xf9b\xbc}\x80?0.\x9aM\x13b/mJ!GmJ!_mJ!w%\xea\x85=\x96\x00@NKH\x06\xf9-Q\x0c\xb9nS\x0cz/Q\x0c90Q\x0c\xf90\xa1\x16\xc8\x8d\x9bb\xd0\x93\x9bb\xd0\x99\x9bb\xd0\x9f\x89b\xc8\xa5 \x9b@^\xdd\x14\xc3\x8eM\xdaD\xe0\xdb\xa4\xeaZ\xdd\x9bh\xab\xcc\xc3\x1bX\xee\xe4\n^\xae\x10\xc6\xe4\x01\x8a\xc4\xf3}\x99\xe3\xfb2\xbf\xf7en\xef\xb7x\xbd/uz_\xea\xf3\xbe\xd4\xe5}\xa9\xc7\xfbR\x87\xf7\xa5\xfe\xeeK\xdd\xdd\x97z\xbb/uv_\xea\xeb\xbe\xd4\xd5}\xa9\xa7\xfbrG\xf7[\xfd\xdc?\xc2\xcd}%/\xf7\xd5\x9d\x1c\xf6g,\xf3g,\xf3g,\xf3g,\xf3g\xdc\xe2\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xee\xcf\xb8\xd5\x9f\xf1\x11\xfe\x8c\x95\xfc\x19S\xfeL!\xc2\x0d\x8a\x178\xdcj\x1b/\xf1\xe6\x18\x1d\xaa\x07\xe7\xe5\x03\x01|\xe5\xb9.\n\x1at\xf1\xbb\x00\x9c8q\x88q\x03.~\x17\x80\xf3H\xaa\x86\xf2;\x1b5p\xc7\xc9\xac\xedZ\xa4\xde\xb1rk;\xb9\xe4;Vvm'\x97~G\xcb\xaf\xedd-\xd8\xf3-\xd8\xb7\xb4`\xcf\xb5`/o\xc1\x9ek\xc1^\xde\x82=\xd3\x82\xfdi\x01-\xebXY\xe8p\x94oQ\x04\n\xeeE\xe1[=\x8cB\xab8\x19I\xa0\xecg\x0c\x91\x92\xab14\n\xde\xc6P\xa88\x1cE\xa2\xeas\x0c\x91\x92\xdb14\n\x9e\xc7P(\xcc\xc1\xaa\x81&\xe7\x92\xfe\x91\x1e\xe9\x1f\xe7\x90\xfe1\xfe\xe8\x1f\xe9\x8e\xfe \xde\xe8\x1f\xef\x8c\xfe\xb1\xbe\xe8\x1f\xed\x8a\xfe \x9e\xe8\x1f\xef\x88\xfe\xb1~\xe8\x1f\xe9\x86*\x1e\x87\x8f\xf48|\x9c\xc7\x1d3\xc7\x92`%\x8f\xc3'x\x1c>\xde\xe3\x8e\x9dki\x02%\x8f\xc3'x\x1c>\xde\xe3\x8e\x9dsi\x02 XKR;\xf5\x9cCq\x055\xcc\xdf\x8d\x91\xb2\xb7Ob\x84\xf3;\xa2\x0d\xaazB\xe3\xecy\x12\xe2uJ\xe0\xaa'4\xae\xf8\xa8~\x0d\xca\x7fU\x18\x8e\x0f\x80\xe0\xd9\xc8\xae$;\x05\x94\x8bOA%-\xa0pE#\x14Z\xa10\xa9\x94M\xf3\x15[\xe6+7\xccWk\x97\x7f\\\xb3\xc4-\xc0\x8a-\xc0\xca-\xc0j-\xc0\\\x0b\xe8N\x92'r\xc3\xc8v\xbct\xcf\xbdu@\x1b7e\xdd1[8\"\n\xd9\xbb\xe9\xda\x90(d/\xc1k\x03\xa2\x90\xbdm\xafYD!{\xad_\xeb\x13\x85\xec\xfb\x034\x93(d_T\xa0\xf5\x88B\xf6\x8d\x08\x9aA\x14rJ\xd0\xad\xa6P\xe7$\xd2{d1{0\"\xd4\x1a\xce\xccy\xfb8L\xed\x14i}\x8b>o\xb0\x08c\xff\xbc(\xfb\xb1o\xb9h\xf9\xd3D\xf0\x1cd7\xd6\xc5\xec\xc6:\xcc\xaex\x0e\xb23L\x89x\x86)\x90\xaf,\x809\x8e$\x12\x1a#\x81\x88e\x01\xc8\xb1\xd7\x93\xc8\xd8\xeb d,\x0b`\x8eC\x89\x8c\xbd\xa1@\xc6\xb2\x00\xe4h\x1a\x12\x19MC cY\xa00\x96\x1e`\xd7\xd2\x88\x0f\x1c<\x8fwI9\x9e\xe6`R\x96\xa7\xfa\x98\x9c\xe9\x89n&ez\xaa\xa7\xc9\x99\x9e\xe8lR\xa6\xad\xfe\xa6\xe0p\n\x93w\xe3\x85\xfes;\xa1\x84\xe1\x89>(\xe1x\xb2\x0b\xcax\x9e\xea\x81\x12\x9e';\xa0\x8c\xe7\xa9\xfe'\xe1\xf9D\xf7\x93z\x1a~nO\x930<\xd1\xd3$\x1cO\xf64\x19\xcfS=M\xc2\xf3dO\x93\xf1<\xd5\xd3$<\xdb=\x8db:\xc7\xb6\xf3\x90EP\xf9y\xce\xf3x9\xb7\x7f\xd4\xcf\xb2?\xdd\xf1O\x10t\x04AG t\x08A\x87 t\x00A\x07 \xd4\x82\xa0\x16\x08\xedC\xd0>\x085!\xa8 B{\x10\xb4\x07B\x0d\x08j\x80P\xdd\x02\xa0:\xdb\xae\xed\xca+\x02\xde\x02\xbbJp\x8e}qf\xe8\xfa\x0b\xded\x05|$\x82\xb3f+\xe0C\x11\x9c5]\x01\x1f\x88\xe0\xac\xf9\n\xb8%\x82\xc3M\xed\x8b\xe0\xac\x19\x0b\xb8)\x82\xb3\xa6,\xe0=\x11\x9c5g\x017Dp\xd0\xa4%\xf6\xaf:{\x93:@v\xacQ\x10\xc3`V`\xae\x1d?h\xcb\xd8\xdeW\x08\xd3dVw\xbe\xe7R\x00\xcbb\x96ad\xe1p\xc8\xacG\x13\x0foP\\\x15s\xefB\xc3\xf95\x0b\x1ad\xdb6#A\x18\x06\x94\x08\x8e\xe3@lH\x08B\x08\xd0E\xae\xdd\n\xb2\xe8g\x7f\x00\xf5\xd7\x80\xc5\x02PV\x8c\xdc\xba\x92\xa1\xde\xd7\x19\x0cQ\xbcX\xf4\x0ds\x00IJ\x81\x86=\x8biN\x18\xdb\xc1\x92\x10c\xc0]\xe9_\x86\x98\xe00\xe7\xae\xd9\xef\x11\xc6\xe1\xb6Dd`H\n\n\xf4\xd7\xc5|a\xd8\x8cy\xa2u\x1c\xe1Z\x10\x0b\xf5\x1c\x9b\xbd\x9c\x90s\xa2qv\x7f`.z\x80\xea\"/\xa8=\xd1\xb5t}\xc4\xe8n\x15\xa6\x14&S\xe0\x9c\xb1\x10]>\xd2aW\xa0Q\xb6\xe9\x0eA\xb7G(\xa8{\x869\x1cZ=\xd6\xb3I\xc0\xd8\x1e\x0f\xfb\xb0\xdf\x11\xb01Bs\x87iW`o\xf6M'5\xe6\xfd> \xcd\x1c\xafQ\x03\xea\xf7\xc7\xec\xcb\n\x88r\xd3\x1a\"\x17\xb4)\x89\x1a\x0f\x1c\x87u\xe1\x1c\x85\x12\x1a\xe8\xb8\x88\x03n\xedd\x85\\\n\xb6\x18,\x16\x0b\x04\xc2(\x15\xa0\xd1\xc2]X \x8eq\xb9\xc5\xc2As\x10H\xf5\x10w\xe1ro'\xc3a\\_\xb1/\x80\xd5-AZkK\xad\x8e<\xe6\xb6\xf3\xb0,\xde\x91ZPH\x83\x90\x8ap\xd4B\xc8\x85$\x15\xe1\xb0\x85\x90\x0bP*\xc2A\x0b!\x17\xaeT\x84V\x0b!\x17\xbcT\x84\xfd\x16B.\x94\xa9\x08\xcd\x16B.\xb0\xa9\x08{-\x84\\\x98S\x11\x1a-\x84\xdc\x0cY\x11\xea\x96\x9c\x90\x0b\x81\xe6K\xad\x8e\x828\xca\xb6\x80\xa8&\x86\xdc\xa7-<\xaa\x89!\x17j\x0b\x96jb\xc8\x8d\xdaB\xa7\x9a\x18r\xa5\xb6@\xaa&\x86\xdc\xa9-\xac\xaa\x89!\x97j\x0b\xb2jb\xc8\xad\xdaB\xae\x9a\x18r\xad\xd6\x00\xact/\x9e\x92\x0f\xc7\xe6K\x8d\x88\xc8x\x02.8\x9b/\xb5&>\xe3\xf1\\\xa86_ju\xb4\xc6\xc3\xb9\xc0m\xbe\x14A\xb90n\xbe\xac\x824\x1e\xcc\x05u\xf3\xa5F\xc5u< \x17\xe2e\x92\xd7Q\x1e\x8f\xe7\x02\xbe\xba\n\x01\x01\x17\xfeU\xba/\x02<\x9e\x00\n\x06+\xc7\x80\xe0\xect9_\x16+\xe4\xc8\x8eQ\x90\xf2\x14D!l\xe3l\xc2\x03\xda\x01D\x98\xf3\xa5\x00\x0c\xc5\x9b\xb5\xa2D$|\xf49_je\x00\n\xe1\xf9X4s\xa3,\x1c\x85\xd0|d:_VA\x00\x87\xe7\xe3\xd4Zz\x11 \x18\xb5\xce\x97U@\nt\x02 \x86\xadk\x11RA\x11me\xb8<\xd4\xe4I\xa0\xf8v\xbe\xd4\xea\x10\x176\x1f\x1b\xedfM\x11\xa1\xf9\xd8\xb7i\x88\x88\x86\x8f\x84\x9b1&\x8b\xe0\x80A \x88\x8b\xf3\x81C\x00\x07\xa2d\xa2\xb3\xc2DP\xcc\x9cu\xd8,l\x86\xc6U>\x82\xaeZ\x91\x87\xab\x10 \x10O/Eh(\xba\xae\xdb \xa0\x81b\xed\x8a\xa6\x0e\xb7\x81\x81\x0d\x88\xbc\xb3a\x87\x08\xbe\x013\x02qxC$R2\x14\x957T\xe2\x0e\x06\xc4\xe8\x0d\x99hT\xe1#\xf6\xf9\xb2\x0e\xd79\x020r\xcf\xef\x97\x17s%t\x07\x9d,\xce\x7fn\xd6N\xec\xbb\xd7rd3\xf3\x8a\xb9\x11\x18\x8a%71\x17\xf0zn\x16sl \x14Cn\xe6.\xd0\xd5\xe4-\xe6W#(v\xdc\xcc^\x80\xe5\xacx6\xdc\xac_\x00\x8bY\\\xcc\xa8,\xa7Xq1A\x01%\xc3\x021C\nE\xb1\xe5\xe2\x86R+U\xe8 Q\\\x0d\xa1\x18r\x81\x05)\x81\x9c#\x81\xa1Xr\xa1\x07\xe1[y8\xd1\xe2\x7f\x05\x86b \x05'\x05E\x0bC\x88\x17;\xdc\x10\x1dI\x1b\xeb-]-C\x90\xecd+h\x92l\xd4\xcax$f\xcc.\x8fH\xb2a+\xe3\xa1\x981\xbbt\"\xc9\x06\xad\x8c\x07b\xc6\xec\xb2\x8a$\xb3Z\x19[b\xc6\xec\x92\x8b$\xeb\xb72\xee\x8b\x19\xb3\xcb1\x92\xcclel\x8a\x19\xb3K5\x92\xac\xd7\xca\xb8'f\xcc.\xe3H2\xa3\x95\xb1!f\xcc.\xf1\x88\xae$\xed 5\x82d\xdc\x96' Ie\x9d\xa4F\xc8\x98\xc3\x1d\xa5J%\xb41\x1f\xca\x99\xc3\x9d\xa5J5\xb41\x1f\xc8\x99\xc3\x1d\xa6JE\xb41\xb7\xe4\xcc\xe1NS\xa5*\xda\x98\xf7\xe5\xcc\xe1\x8eS\xa52\xda\x98\x9br\xe6p\xe7\xa9R\x1dm\xcc{r\xe6p\x07\xaaR!m\xcc\x0d9s\xb8\x13\x95\x81\x9e\x98w\x05 Y\xcb\xa2\xc3e[HW#\n\x8e\xd0\xd2\x00\x0c\x17\xa9\\\x8d\x94=\x174\x02\x8b\"8~$\xd3;\xd2*\xd8(\x12X\xb2\xc0\x01%\x91\x10\x92V\xc0\x84\x95\xc0\xb2\x19\x8e0\xcb\x0c\x92\x94\xb7\x94\xaf \xe4\xac\xd3MR\xceT\x84\x08,\xc9\xe0\x18\x94\xc9NIk\x00\"Q 9\x00\x07\xa5dJK\xae|&4\x05V\x89p\x94J%\xc1\x14\xda!\xadC\x10\xb6Ry\xb3\xf6~@\x06\x9c\xc0\xbaP\x18\xc7V\xa96i\x0d-\xcc\x05\x81-\x95\x98\x93\xf2'q\x82Z\x84i\xbc\x9a\x89B \xbddci\xae\x1a\x85\xb0z\xa9\x12Y/\xd9\xe0ZZ\x93 \xce^\xaa\x84\xdaK6\xda\x96\xd6$\x08\xbc\x97*\xb1\xf7\x92\x0d\xbf\xa55 \"\xf1\xa5J0\xbed\xe3qiM\x82\xd0|\xa9\x12\x9d/\xd9\x00]Z\x93 V_\xaa\x84\xebK6b\x97\xd6$\x08\xde\x97*\xf1\xfb\x92\x0d\xe1\xa55 \xa2\xf9\xa5J@\xbfdcziMpdBl\xf6\xb5\x8fA\x92\x9e\xab\x16\xef\x13\xbb\x83\n\xb5\x89{\xaf\xda\x02\x80\xd8NT\xa8M\xdc\x83\xd5V\x04\xc4\xfe\xa3Bm\xe2^\xac\xb6D 6,\x15j\x13\xf7d\xb55\x03\xb1\xc3\xa9P\x9b\xb87\xab-\"\x88-Q\x85\xda\xc4=ZmUA\xec\xa1*\xd4&\xee\xd5j\xcb\x0cb\xd3U\xa16q\xcfV[wT;l\xe2\xaajDQO\x15\x14\x01\xdbo\x05^\xca\x8c\xe3\x03\xed\xcc\x15\xd0zsN\xcc\xad\x810<\xf9\xad\xbb\x82\xa0\xd8\xbd\x133,\xcb\x19n\xfc\xc6^\x81^\x86X\"\\^\xcap\xe27\xfd\nl\xb1\xc7 \xe6U\x96\x93\xdc\xf8-AR'm\x0c)\x14-$\xb0mX\xd0\x14{\x80b\x9ee9\xc5\x0d\xdaT$%h\xe3I\xa1(\xce\xd0\xc6#\xe1\xb0\x91\xe0\x05\xbd,\x84\xe2 \x9f\xbc\xcb\x08\xaa\xcdI1\xcb\x1a\xc1\xb97\xbbsYjK\xca\x0d\xe2\xc4\xefjR:\x92\xf2#0\x0cW~\xdf\x93PQ\xbec\xd6\xa2\xc6\x02Cq\x85vF\xcbN!g\x08\xf1\x02\xb6M\xc96\xb5p$A\x14_hg\xb5 \xec\x8dd\xcd\x98\x97R\x9c\xa0]WB?s\xbc\x968x\x03ax\xf2\xdb\xb2\x05\x81\x9c\x1d\xcf \xda\xb2%U#\xe7G`h\xed\x01\x9b\xba\x04E\xb5\xaf\xdb\xc2\xb8\x86Q\xbc\xa1\x9d\xdf\x82\x88\xd8\xfc\x15s&A\xb4\xaf\x03\x9b\xc3\x14I\x8b+Q(\x8a3\xb4\x81L\xd1\xb4\x0d\xc74\x8c\x96\x1a\xd8e\xa6\x88\xa43$\x81a\xb8\xf2\xfb\xd0\xa5\x07-\x15b\x02\x12T\xf0\x05\xd2&\xc2\x08\xa18\xa6#\xe5.c,\x0e\x19\xc8#=R\xf6l\xe0\x00U\"\x8a!\xeaC@\xd2\x1a\xa8H\x02b/\n*\xca3CR\xe6Dh\x01\xb1\x16E\x19\xf5\x01#)s\xca 9\xf6\xa2\xb0\x839\x8f\xa4\xa0}y=\x928\xa4>\xc4$\xad\x84\x8a\x19x\xf6\xe2\xc0\x849\xf3\xa4\xd0\x92\x96\xaa\xc4\x91\nyP\xaa\xbd\xb3\x11\xb37_\x898t!\x8eVI\xeb`\x02\x18\xb8\xdf\xc1\xb1Ly\x16Kn\x0f9kQpC\x1d\xdcR\xb1\x85\xbc\x1aQ\xb4C\x9d\xf5j7\x059\x07\xf0\xd5\x88\xc3\x9f\xeax\x98\xbcw\xcb\x99\x0b\xe3!\xfa0\x99\x82\xae\xe4\x15\x89\x03\xa4\xf2\x00\x9a\xb4\x06\"L\xe2Y\x8b#&\xf2\xb4Z\xbb\x19\x889\x1e\xaaD\x18B-\xdb\xf9KY\x8bc*\xea0\x9c\x82 \xa4\xd5\x88\x83,\xf6\xfc\\{ML\xa8\xc5W&\x8e\xba\xe8Sw\xd2\xaa\xf8\xd8\x0b\xe8\x84\xc20\x8c9\xa9\xa7R\x93\xdc\x85\xc5q\x19{\xbcO\xa5\xae\xb6 K\x18\xa8Q\x87\x02Uj\x92\x07&\x92\xc8\xadu\x17\x99\xc0\x08*\x00\xf7\x94#[?\x08\xbe\xdf\x1a\xd9F]\xd4\xedY\xdc{j#\xbb\xd7\x94C\xc5f]\xcc\xbfY7\xb2\xfbu)\xffj\xdd\xc8\xb6\xeaR\xfe\xdd\xba\x91=\xa8K\xf9\x97\xebF\xf6\xb0\xa9\x97\x7f\xbbn\x84\xeb\x06k\x18-R\xae\xd5\xd8\xa0\xcb\xc1\xa6\xe3\x1e\x03\x820&\x8d\x01\x94\x80\xfb4\x04\xd0\x04\xb6h\x08\xa0\x0e<\xa0!\x80N\xf0\x90\x91\x05PL\xdc(&\xce\x06\x16N3\xb1\xc1\x00@\xd5\xc4=\x16\x05\x81L\x06\x04('\xee3\x18@;\xb1\xc5`\x00\xf5\xc4\x03\x06\x03\xe8'\x1e\xb2\xf2\x00\n\x9a7\n\x9a\x87i\x1a\xfa\x9c\x86\xe6\x06\x8b\x00U4\xefq0\x08e\xb2(@I\xf3>\x0b\x02\xb44\xb7X\x10\xa0\xa6\xf9\x80\x05\x01z\x9a\x0f9\x99\x00E\xa5\x8d\xa2\xd20\xe2\xb4\x94\x1aT1\xa8\xa2\xb4Gc \x88IA\x00\xe5\xa4}\n\x01h&\xb5(\x04\xa0\x96t@!\x00\x9d\xa4CZ\x0e@!\x1bF!\x93\x16?\xda@\x1ab\x89@\xbdm\x00\xbdq\x84\x10\x1d\xafL\x96\x0cP\xf0\x86W0K\x05(}\xc3+\x9d\xa5\x02\x0c\xb1\xe1\x0d\xc1R\x01\xc6\xd9\x00\xc6\xe1\x1a\x06Xl\xc5\xce\x125\x11<6\xae\xc0Y\x83!\x02-\xb6\x82\xa6\x12\x96\x10\xa2\x03\xa6\x17\x86\x0c\xb0\xd8\n\x98q\x18*\xc0b+`\x12b\xa8\x00\x8b\xad\x80y\x89\xa1\x02,\xb6\x82\xa6*\xb6a\xc0\xc7\x85l\xfd\xe0\xdb\xf1\xd2\x0bX\xdb\xf8\xb6Q\x95@\x06\xf0\xed^]\x0c\x95\x9aU)\xf0\x95'\xbb_\x15\x02\x9fU\xb2\xad\xaa\x10\xf8Z\x92=\xa8\n\x81\xaf-\xd9\xc3\xbaN\xa0\xa1\xb8j(\x18\xbf\xf8\xd8\xa0\x8a\xc1&\xe3\x1e\x8d\x81 &\x05\x01\x1a\x8f\xfb\x14\x02\xd0\x00\xb6(\x04\xa0\x06<\xa0\x10\x80.\xf0\x90\x96\x03PH\\+\x04\xec\x9b~l\xd0\xe5\xa0J\xe2\x1e\x03\x820&\x8d\x01\x94\x12\xf7i\x08\xa0\x95\xd8\xa2!\x80Z\xe2\x01\x0d\x01\xf4\x12\x0f\x19Y\x00\xc5\xcck\xc5\xc0\xf3\x8c?7\x18\x00\xa8\x9ay\x8fEA \x93\x01\x01\xca\x99\xf7\x19\x0c\xa0\x9d\xb9\xc5`\x00\xf5\xcc\x07\x0c\x06\xd0\xcf|\xc8\xca\x03((\xad\x15\x04\xc4)~j\x90\xa5\xa0j\xd2\x1e\x05\x81\x10&\x89\x00\x94\x92\xf6I\x00\xa0\x91\xd4\"\x01\x80:\xd2\x01 \x00t\x91\x0e)\x19\x00ElhEL\xe4n\xb3\x01\x143Qp\xa4\x0d\xaf-\x96\x0c\xa2\xe248i\xf5\xb4\x0d\xa7\xd4I\xab\xe7m8=OZ=q\xc3\xa9~\xd2\xea\x99\x1b\xde\x1al\x83\x00\x0b\xad\x98Q\xbf\"\x81\x87\xbc\x154 \xd0$\xa0\x85V\xc0\xc4\xc0\x90AT\xfc\\A\x13\x01\x16Z\xf1\xb3\x07M\x03Xh\xc5\xcf'4\x0d`\xa1\x15?\xc3\xd04\x80\x85V\xc0\x9c\xc34(\xb7P\xfb[-\xe9\xd7\nFv\xfer\xce2\x96\x01\xf2-d\xa9 \xe5BA \x84I\"\xc0\xc4\x0b \x00s/$\x00L\xbf\x90\x000\x03C\xc9\x00&a\x08\x84(\x0f\xc3A\x04\xa9\x18\x1e\x07\xc1L\x0e\x06&d8\x14\x98\x93\xe1P`Z\x86C\x81\x99\x19^.09C\xc2D\xf9\x19\x1e#H\xd1\x00@\x08g\xf280Q\xc3\xc3\xc0\\\x0d\x0f\x03\xd35<\x0c\xcc\xd8\x00\xb2\x81I\x1b\x12'\xcc\xdb\x00 A\xea\x06BB@\x13\x00\x82 \x1c\x00\x07\xe6p\x00\x1c\x98\xc6\x01p`&\x07\x92\x0fL\xe6\x90@8\x9f\xc3\"\x04)\x1d\x0e\x06\xa1L\x16\x05&vX\x10\x98\xdbaA`z\x87\x05\x81\x19\x1eN&0\xc9\xc3)\xaa=\xcf\x03kN1\xd5\x03\xeaS-\xdb\x03)Y)\xe1\x03)^)\xe7\x03\x19C)\xed\x03\x19H)\xf3\x03\x1aM-\xf9C\x92*\xe6\x7f8\x92cR@<1D\x0b\x91\xc2\xd3\x9aJ\"\x88#T\xcd\x05q\x84\xaa\xe9 \x8eP5#\xc4\xb7Q9)\xa4\xe5\xdfs\x8f\xe1\xbc\x10Q(H\x0d\x91\x08\x08`\x12\x000AD\x94\x839\"\xa2\x1cL\x13\x11\xe5`\xa6\x88\xac\x1fL\x165\x00Q\xbe\x88E\x08RF\x1c\x0cB\x99,\nL\x1c\xb1 0w\xc4\x82\xc0\xf4\x11\x0b\x023H\x9cL`\x12\x89@\x89\xf2H\x1cD\x90J\xe2q\x10\xcc\xe4``B\x89C\x819%\x0e\x05\xa6\x958\x14\x98Y\xe2\xe5\x02\x93K\x04L\x98_\xe21\x82\x14\x13\x00\x84p&\x8f\x03\x13M<\x0c\xcc5\xf100\xdd\xc4\xc3\xc0\x8c\x13 \x1b\x98t\"pp\xde\x89\x01\x08RO,\n\x02\x99\x0c\x08L@1\x180\x07\xc5`\xc04\x14\x83\x013Q\xac<`2\x8aUPk>\nT\x98ZJ\n\xd2\xa2RV\n\xd0\xacJb\nP\xb6Jn\n\xd0\xbfJz\n0\x89J\x86\n\xb2\x92R\x92\x8a T\xcbS\xb1\x04G\xa4\xaa8R\x80\x12\"\x04\xe7(\x85\x84\x15K\xa6\x98\xb3b\xc9\x14\xd3V,\x99b\xe6\x8ak\x9b(y\xa5\x90\xbdR\xf8&Kd\xeb\x9a_\xc5fPF\xab)\x14%\xb4\x08\x04\x040 \x00\x9c\xcej\xca\xe1lVS\x0e'\xb3\x9ar8\x97E\xd4\x0f\xa7\xb2|f\xad\xc0\"\x0c\x16!Jd\xb10\x08e\xb2(8\x8d\xe5\xf3\xb1=\x0b\xb2X\x10\x9c\xc4\xf2\xf9\x98\x9d\x05\x0d9\x99\xe0\x14V\x83\x12f\xb0X\x88(\x81\xc5\xe1 \x98\xc9\xc1\xe0\xf4\x15\x8b\x82\xb3W,\nN^\xb1(8w\xc5\xc9\x05\xa7\xae\x1a\x988s\xc5aD\x89+\x1e\x08\xe1L\x1e\x07\xa7\xad8\x18\x9c\xb5\xe2`p\xd2\x8a\x83\xc19+^68e\xd5\xe0\x04\x19+\x1a JX1(\x08d2 8]Ec\xe0l\x15\x8d\x81\x93U4\x06\xceU1\xf2\xc0\xa9*FA\n\x99*Hc\xaa\x89*@\x8f\x8ay*^\xb9ji*^\xe1jY*\xde\x08jI*\xde0j9*\xc0X\x8a)\xaa\x86R5C\xc5P\x1c\x95\xa0bi!R\x88\x12\x9c\xae\x94\xd2S\x0c\x9drv\x8a\xa1SNN1t\xca\xb9)\xb6}\xea\xa9)\xbf\x8c\xd4\xa0\xccT]&JL5\x00\xa8\xdcl\xca\xe1\xb4T]\x0cg\xa5\xeab8)U\x17\xc39\xa9\xa6n8%\xe5\xd3k\x04\x16`0\x00QB\xca\xe7\xc3\x7f\x16d2 8\x1d\xe5sq=\x8b\xb1\x18\x0c\x9c\x8c\xf2\xb9\x88\x9d\xc5\x0cYy\xe0TT\x0d\x12f\xa2\x18\x84(\x11\xc5\xc2 \x94\xc9\xa2\xe04\x14\x03\x82\xb3P\x0c\x08NB1 8\x07\xc5\xca\x04\xa7\xa0j\x948\x03\xc5BD (\x0e\x07\xc1L\x0e\x06\xa7\x9fX\x14\x9c}bQp\xf2\x89E\xc1\xb9'N.8\xf5T\xc3\x04\x99'\xaa\\\x94x\xa2A\x10\xc6\xa41p\xda\x89\x82\xc0Y'\n\x02'\x9d(\x08\x9cs\xa2e\x81SN\xb4b\xda3N\x80\xa2\x14\x13N\xbc\xf6\xd4\xf2M\x9cF\x95\xd2M\x9c\x92\x95\xb2M\x9c\xde\x95\x92M\x9c)\x94rM\xbcu\xd4RM5\x9db\xa6\x89\xc6\x1f\x93hb(\x01B\x88\x0e\x9a{T\xd2L4\x95j\x96\x89\xa6RM2\xd1T\xaa9&\xa6]\xa7\xa5\x98\x04\xd9$\\\x85SP6\xa9)\x14e\x93\x08\x04\x040 \x00\x9cMj\xca\xe1lRS\x0eg\x93\x9ar8\x9bD\xd4\x0fg\x930\x13\xd7\xb3\x08\x83E\x88\xb2I,\x0cB\x99,\n\xce&a>\x16gA\x16\x0b\x82\xb3I\x98\x8f\xb2Y\xd0\x90\x93 \xce&5(a6\x89\x85\x88\xb2I\x1c\x0e\x82\x99\x1c\x0c\xce&\xb1(8\x9b\xc4\xa2\xe0l\x12\x8b\x82\xb3I\x9c\\p6\xa9\x81\x89\xb3I\x1cF\x94M\xe2\x81\x10\xce\xe4qp6\x89\x83\xc1\xd9$\x0e\x06g\x938\x18\x9cM\xe2e\x83\xb3I\x0dN\x90M\xa2\x01\xa2l\x12\x83\x82@&\x03\x82\xb3I4\x06\xce&\xd1\x188\x9bDc\xe0l\x12#\x0f\x9cMb\x14\xa4\x90M\x824\xa6\x9aM\x02\xf4\xa8\x98M\xe2\x95\xab\x96M\xe2\x15\xae\x96M\xe2\x8d\xa0\x96M\xe2\x0d\xa3\x96M\x02\x8c\xa5\x98Mj(U\xb3I\x0c\xc5Q\xd9$\x96\x16\"\x85(\xc1\xe9J)\x9b\xc4\xd0)g\x93\x18:\xe5l\x12C\xa7\x9cMb\xdb\xa7\x9eM\xc2eP\x06e\x93\xea2Q6\xa9\x01@\xe5fS\x0eg\x93\xeab8\x9bT\x17\xc3\xd9\xa4\xba\x18\xce&5u\xc3\xd9$L\xaf\x03X\x80\xc1\x00D\xd9$\xcc\x07\xf9,\xc8d@p6 s\xf1;\x8b\xb1\x18\x0c\x9cM\xc2\\l\xceb\x86\xac{U\x1fl?w\x15\x1fV\x00w\x17\x1f\xd4\x00w\x19\x1fR\x01w\x1b\x1f\xd2\x01w\x1d\x1fR\x02w\x1f\x1f\xd2\x02w!\x1fT\x03}\xe7\x1e\xd6\x01}\xe9\x1eT\x00}\xeb\x1ej=}\xed\x1ej:}\xef\x1ej7}\xf1\x1ej4}\xf3\xbelq\xfb\xc1\xcb\x033f\x90\x17UD\xa3\x1d\x05\x01\x07<\x12\x01\x8ey$\x00\x1c\xf6H\x008\xf2\x91\x00p\xf0\xa3d\x00\xc7?\xf6\x00\xabh\x08\xe4q\xe0(\xc8\xc1\xc0\x81\x90C\x81c!\x87\x02\x87C\x0e\x05\x8e\x88\xbc\\\xe0\xa0H\xc0\xe4\xe3\"\x00\x04\x87F\x1e\x07\x8e\x8e<\x0c\x1c y\x188F\xf20p\x98\x04d\x03GJ\x02\xd72XBHp\xbc\x04\x80\xe0\x90 \xe0\xc0Q\x13\xc0\x81\x03'\x80\x03\xc7NH>p\xf8$\x80\xb2\x11\x94\x83\x81\x83(\x8b\x02\xc7Q\x16\x04\x0e\xa5,\x08\x1cMY\x108\xa0r2)l5\xaa\x9ef\x0f\xc8\x83W\xc2\x81\x96@\xc0\xe3l\x03\x80\x87\xd9\xa6\x1c\x1ee\x9brx\x90m\xca\xe11\x96\xa8\x1f\x1eb\xe9\xfd[\xe1\x08\xcb\xc2\xe0\x01\x96A\xc1\xe3+\x03\x82\x87W\x06\x04\x8f\xae\x0c\x08\x1e\\Y\x99\xe0\xb1\xd5gF\x1b\xd1\xd0\xca\xe1\xe0\x91\x95\x85\xc1\x03+\x8b\x82\xc7U\x16\x05\x0f\xab,\n\x1eU9\xb9\xe0A\xd5g\x07\x18\xd1\x98\xca\x03\xe1!\x95\xc3\xc1#*\x07\x83\x07T\x0e\x06\x8f\xa7\x1c\x0c\x1eNy\xd9\xe0\xd1\xd4\xa7\xc6\x1a\xd1`\xca\xa0\xe0\xb1\x94\x06\xc1C)\x8d\x81GR\x1a\x03\x0f\xa44\x06\x1eG\x19y\x14\x86Q\xc1\x88\x89\xeb\xe1F4b\x12\x08x\xc4l\x00\xf0\x88\xd9\x94\xc3#fS\x0e\x8f\x98M9\x96\xdc\xca\x05\xfajr\xc1\xa8\x10\xa6\x95C\xdb7\x12Kf\xae\x1d?\xb4\xf2\x92}I5\xe3\xf3\x80\x0e)\xda\xa5\x9a\x8b\x9c0\xb6S/\x0c\xce\xb1\x17 -]\xc5\xe1z\xb9\xa2 \xd6\x81\x8b\xe2\xac\x98\xa3\xa9K\x18\xc7\x0b51M\x10\x06Ha\xe9s\x00d\xce\xd6Q'\x88\x0d\x91)H\x0e\x91\xe5\xc2+H\xaf\xb0p+\x9b\xe4\x9f\xd4\"\x9eJ\xa5A<\x95B{\xc4\xa2\xe3\x93D\xe7\xa9TD\xe7\xa9\n\xd1)\x8a\xb4D\xd9\xd8[\x06\xe7YT\xc0\x94\xc7dy>Q2\x00\x87\x048(HQ\xac`\xed\x03#E\xed9bA\x18\x08(\x0b\x83)\xc5Q\x90G\xc1\xfbR\\y\x83DF\xbf]D\xffh aaZ-G#`a0$\x0c\x0d\xaa,\x9c\x7f!~\x11\xc6\xfe\xb9cG^jc\xef\x11\xb1P\xccBq\xb8E\xb1c'\x1cr\xcd\"\xd7Q\x04#\x03\x16y\xd2p\x98\x12\xce\xa1\xd4\x12\x00-n\x0c\x00\x16\xb7\x07\x00+\x0c*\xcan\xda\xb8\x98Z;9\xb0\xa4\x99\x1cV\xd2J\x0e\xab\xd0HA{8\xb7\x92\xb5\xe7\x08\x1f\xe4\xb1\x92\xf6pX`8]h\x833\xe6\xc1\n\xd9n>\xab/\xc2 \x8b\xf5\x1e\xd19\x1fR/4\x8b\xa5K\xd6s\x80\x94\x0f\xa1\x17\x06Ql\xf2\xc5=\xa2\xb8\x07\x05\xea\x0b\x93@\x18@\x90\xbe\xe8S\x00\x88\x85E\"\xf8\xe2\x01Q\xdc\x1d\x0d\x01\x06C\x12Q\x00\xda{\xc3\x81\xd5\xbd\x16$\"\xf5g\x9d\xae\xc5\x02\x005a\x04\x9a\x01d\x07\x1a\x01\x99\x82F\x08\xacA\x83`\x83\xb0\x18\xd0&\x0c\x080\x0b\x8d\x10X\x86\x01\x15\x18\x05\xeb(\x8cU\x99\xc9|\xa1\xc5\xfcV\x83q\xb4\xa4\xbd\xfc6s\xf9m\xd6\xf2\x15\x8c\xe5\xb7\xdb\xcaW0\x95\xdff)_\xc1P\xfe\xb1v\x12\x98\x04\x0bM\x82[M\xc2\xd1\x92&\xc1m&\xc1m&\xc1\n&\xc1\xed&\xc1\n&\xc1m&\xc1\n&\xc1\x80I(\x8c\x8f\xecd\x1d\xa3C\xd3O\xb2\xce\x03b\xb2r\n\xd8\x17\x01\x03;\x8e\xc3-\x01\xedq<\xbd\xc0EAZLi\xc5\xcf\xe7Fs\"+m?\xcf\x98\xf86\xc6\x9acG\xe5\xe8\xb0\xb1c\xcf\x0e\xd2\xf3\xe69\x8dO\xe3u\xe0\xd8):\xe4\xc9\x81<5\x82\xce\x83p\x1b\xdb\xd1$\xdc\xa0x\x91\x7f\x9c\xcfs]\x14Lr\xa9\xea\x87\x08c/J\xbcDa\xcc9\xc0\xeaH\x94\xd5\xcb`[4L\xa3EJ\xae\xe3\xbd'\xea\xb9\x1e\x88UU\x9d\x11\x9c\xaem\x05u+\x0c\xf1\x95\xc2|u\x13\xf8\xc7X\xc0W1\x80\xff<\xfa\xf7\x8fT\xbf\xff\xdd\xb4/Q4VW4>F\xd1XE\xd1\xf8y\x14\x8d\x8fT4~\x8a\xa2)\x96U\xb9\xe6\x84Aj{\x01\x8a\x0f\xf5\xa3\xfdy\xe2\xc4!\xc64E\xb1h\xa6\xb7\x12\xecu\x1aN\xc8\x9d\x96\xec\x01\xa3\xddX\xcb\x1e\xf2t\x0c\x0cS\xb0\x86Y{\xe7<\x00bj\xec\xd9\x1buIARPX\x8d9\xf4\x94\x03\x15\x04V\x18M\xcaV\xf8'7\x02\xa0\x84\xdb\xe0\x1f\xdb\x04\xb1\xb4\xf8di\x01JXZ\x0cHK\x8b\x82\xbd\xe8\x10\x85\x89\x97'\x02\x17\xde\x0e\xb9\xff\xd7\xf3\xa30N\xed \x9d\xfcQ\x97\xd8\xf3$\xc4\xeb\x14\x11\x85\x19\xe9y\x8c\x9c\xf4G#\xdau\x88\xbf?\xd1Eg\xc4\xdf\x9f\x14\xcc}\xe0\x04\xcc\x1c\xe7\xcf\x94QAH\x15\x9f\xcc$\xf7\xff\x83\x04\x17\xc9\x88\xff\\\x19)\x01\xb6\x89\x16\x84\xb1o\xb3#u\xf6\x88F\x16\xa370\xa0\xd3\xb0(\xa6#\xc9(>>'X\x0b\xc5\x07J\"\xb9\xe0\x90\x8a\x13\x8d\x85e\xd2)\x88\xa7\xe0m\x8d\xcclt!\x14\x19\nCx\x89\xfd#\x05\x96\xca\xa6jfp\xe6\xe6e\xc3\xbcl\x14f\xa3\xcd\xed\x04\x1d6(N=\xc7\xc6e:;{\xc6\xef\x91l4\xdfsY\xa8\xef\xb9.\xe6\x80i\x18\xb1\xc04\x8c\xb8\xaaS\x9f\xab9\x0fp\x14\x0c~\x00\x9a\x91\xf9\x8ezK\x00\xb4\xb01\x00\x16n\x0f$B\xd1$\x856)8q\xd9P^o\x92vr`q39\xa8\xa0\x95\"\xbb\x1d\xed\xf8e{\xf01\xed\xe1\xc0\xe2\xf6pPA{\xf8\xfa\xcb\xf6PX\xd7\xf3\x0fad;^\xba?7\xb8\xa23\xf6\x01\xf41\xfa\xecq\xf1\xfdym\x8b\xe6\x0f^\x99\x15/f\x90\x92w\xa7kXI\x07ez\xf1\x82IK9'\x86\xbc\xd6J\xfc\xae\xc5\x13\xdaN\xeamP\x03\x19M\x94d\x0c\xd7\xa9\\\xc8p\xcd\xec\x9e-q\xb8=\xe3\x9e@\x82\xe7\xcf\xbf\xa3\xbe\x14\xea\x15\x18|\x95-\x03\xf3S\x11\x9dn\xfe\x9f\x1a\xa8\xab\xa9\xedXQ\x9b\nKC\x95\xf5\x9e\x89Py\xb3\xda@y\x1b\xd9\x16\x18\xdf\xa7\x05\xcd\x06{^+\xa4w\x16R\x98 _\x7f\xb6\xef\xe1/\xe3p{\xd0\xfc\xf0Q\x0b\x93\x9dVd\x0f\xfd0LW^\xb0<_\xc6\xf6>ql\x8c\xea\xb6\xcdm\xe7aa;H\xdbx\x897\xf7p\xd6\xf2r\xc1+)\xa24\x93of\xe5?a;E\xdf~\xd4\x7f\x9a\x88\x9e\x03\x1a\xe5Xu\xba=A\xa7:\x02z:\xe4\xac\xa5\x16^\xdb`\xd7\x89\xe1.\x9b\xeb$\xb7\xc0\x8fFW\xb7HM\x11O\x81:\xcaaI\xc4\xac;\xe6Yu\xc7\x00#\x0d\xdb\xf1\x12\xfd\x7f\xc5A\xbc\xe0\x18\x1f\xe1\xd1OEI\x9d\xa5\x80\x88L \xf2\x9a\xb2\xb4\xcdwz\x90\xeb\xf4\x84\x06o\xf7\x1f\xc0\x17\xb3\x87L0\x1dzAZ\x8fH\xce:N\xc2\xf8\xbc|H#\x93\x95\xed\x86[\x0d\x02N\xea\xc5b\x8c\xb0\x9d\x89\x05\x99\xdd\xc6\xb8\xd3\xb5\x92\x8e\xb3\x9e{\x8e6G\x8f\x1e\x8a\x7f\xec\x1a\x03\xeb\xac;\xea\x9fu\xfb\xfd3\xe3\xa7\xc9\x91x\xb1\x88\xe7\xf6\"\xcd\x04\x0d\x83\x14\x05\xe9\xf9_\xfe\xd2\xf8\x7f\xb8\xd3\n\xe4\xb9\xde\xd1;\xc6 \xdauz\xd1\xaeC\x9e\xf7\xeb\xfd4Q\x86\xe5\x07;c\xdb\xf5\xd6\xc9\xb9\x17\xacP\xec\xa5\x93f\xd2\xe4\xd6\xd1\x93\"\xf3\x99\xe7e\xf4I\x11A\x1a\xba\xfeb\xb2ByN'\xff\xf91\xcf\x98\xee\xce5\xf9\x9cu\x846Ui$\x1a\xcd\xfd\xbb\xd0\xeb\x99\x18Ej_\x10d\xcc\x97\x9a\x1dx\xbe\x9d\xa23\xc1s\xa8/\x11\xa5\xc2\xd0\x89=\xc4IM\xdb\xec(\xd0\n\xa6\xa5~\xd4\xf4Ce\x17\x9d-2\xea\"\x83-\xea\xd5E=\xb6\xc8\xac\x8bL\xb6\xa8_\x17\xf5\xd9\"\xab.\xb2\xd8\xa2\xf1x\\\x17\x8e\xc7c\xa0\x98*\xe7\x00\xbe\xbdk\xa45\xfa\xc3\xfe\xc8\x1c\xf4\x87,\xaa\xf4\xf2\x1aY\xfe\xce\xc3\xbc\xd4\xb3q\x0d\xe3\xb3\x95\x8f\xda:HP\xc3(\xff\x8d\x86\x04(IQf\xa0h\xaf\x15\x11T\xdeM:!\xb3\xaf,\xc2Ej\xb05>\x10\xbf\x9e\x1b\xecB\xa2\xa4k6\xae \xda\x95\x01\xd6\x01c{G`\xcd#\xb0\xfd#\xb0\xd6\x11\xd8\x01\xa3\x17\xe8`\x7fA\x8f\xbd$\xd5b\x94 \xa1q\x08\xc4\x9a{\xf1\x1c\x99\xaf\xd6'94I\xf7\x18i\xe9>B\xc5\xd1*\xa1%\x8b\xed\xa5N\xf4sDm7u\x8f\xdbo\"9&(B\xb1\x9d\x86q\xce\x94\xe0at-A\xfb=\x7f\xd9\xf1\xfc\xe5\x81\x18\xd2\x9b\x9cG\xfe\xab\xeb%\x11\xb6\xf7\xe7s\x1c:\x0f\x02\x1d\x06\x0fI\xc7>\x94\xe7\xe1Mk\x88\\\x17\x9a\x02\xf8\x01k\"-\x95\xd5\x06\x0d\xb6\x0c\xa2\x9c\xf5\x0b\xa9\xc6\x03\xc7Y,\x9e_\xaamlG\x11\x8a\x05\n\xec\x0f\xf4hW\x1a\xf0\\\xef\xe4\x9b&\xa5\x0b\x9d\xeb\x9d^VH\xcd\xf0\xdecVRN\xcf\xf3p7\x01\x9f\xd2\x12\x84Qn\x1a-\xb5\x97Z\x82\x9cL\xeaCe4\x82ymH\xcdO\xb4\x05F;\xf2Y\xf6;%I\x18{\x993V\x99\x18\xaa\xcc\xf5\xe2\xa2\x9a2%:\xa98\x12%N\x88\xd7~0\x01\x9f\n\xc5\x7f\xba\xd8\xe4 \xe0F,\xeai\xfe\x8b\xe6\xa5\xc8O\xaaG\x95E\x0c=\x0b\x97\xb2\x7f\x8c\xea\x9f \x134\x8aB\xc4^\xc2E\x81\xbddR\x9b,\xef\xb9F\xb4\xeb$!\xf6\xdc\"\x1c\xb3\xc6g\x03\xebld\x9cu\xcd\x9f\x84*)\x9d\xb8\x99\xf5\xa9\x1b\x1e:\x1bj\x93\xca$\x8e\x18\xf5I'\xd4;V\xb4\x9b\xe4\xa5\x0b\xdb\xf7\xf0\xfe<\xb1\x83DKP\xec-&U\x1f\x9e\xf7\x0d\xcb\x10\xf2\xee\x06\xa1\xe6\xa2\xc4\xe9$\x91\x1d\x1cH\x03d\xfa>7j\xd5\x9f\x1b\x93\xe2?BV\x9dd\xb3\x84\x82\xa2\\\x85}^\xab\xfdD\xc2\xca\xb71u\xde\xa9_5t[\xcc\x04}]\x9f\xa8HK\xf4\xd1\xdc \x8eWVd\xc7\xb6\x8fR\x14\xff\xf1G6\x15\x90B\xf5\xa2]\xcd\xdf\x8av\x1d\x9db\xef\x87A\x98o\x10P\x82\x0ft]V\xdb\xc6C[\xad\x9a\x06\x1f\x0e\xfc\xca&\x9b\x04\xcch7\xa9\x0e>\x90\xfe`\xa9{\xb9\xc5\xdb\xc3\x82\xedq \xdc\xcd\xc8j(\xba\x02\xd1\x07\xfe\xaa\xeb:\xb3\x10\xe9\xb3\xc3a\xb3\x921\x99E\x8c1\xe6\x16;\x00\x04\x14\xad\xd3M\xedy\x1e8\xa0\xf8\xe9#\xceQ\x0eOV]\xfc\x9c\x8dC\x87\xc6\xdb\xfa\xfc\x90s\x04\xa3\xf3\x85\x17'\xa9\x16.\xf2\xf0\x83a\xdb\xd1;\xfa\x11\xbc\xbaebs\xd5/:9\xe7S\xa7\xf3*\xd7Y\xfc\"\xb3\xbe\xad\x999L\x1eSY\xfa\x8bj\xb5\xd9kV\x9b\x99\x9f\x00kd \x9b\xf3\xfb\x8f\x9a\xa5\xbf\x00\x13=U\x111\xb4.c{\x0f6\xab\xeb%Z\x18\xa1\xa0\x19n\x92\xb5\xef\xdb\xf1\xfe \x1a\xe13\xef\x16h\xa8fQL\x8a\x95'V\xd6\x1a\x95s\xd0\xc4\xf7\x82*\x82\xb5\xb2\xdf A\xd9\x1b\x83\xa3\x9f\xe0~c\x00\xcb\x7f\x83\xe980\xe6(\xd9\xcf\x8e\x01w\xb0=G\xf8\xe9\x1d\xef\xa4\xa9\xfe\xa8f\x95\x922C79,\x0fu\xbd\x1eG\xb9\xc30'\xcc\x1aJ\x02\x95\xfd\x91\x9a\xa1$\x9d[\xc0j\xd5g'J\x95Q\xadi\xeds4\xae\xe8C\x9a\x8f\xd2U\xe8\xca\xe6\xed\\\xcf\xf5\xd6\xe5H'f\xd0A\x16\xa8e\xe3\x05w\x03\x8c\x99\\L\xba\x0b\xe5\xd3ONC\xf5\x04\x9d\xed+\xf2v.\x16\x0b\xc5F\x86\xf9\xd2,3\x80\xe7\xb6\xf5\x97\x92$\xb2\xd3\xd5\x11\xd0?\xfepQ\x14#\xc7N\x11\xa5\xccAD\xf4\xacS{[n~\xbdq\x08\xbdc\x16\xab\x19\xfa\xb7'w\xd0\xc96\x8c]m\x1e#\xfb\xe1<\xffW\xb31\x96\x85c\xaa\xf1R\xb9\x19N\xec\xe8\x0f\x07\xa3h\xc7l\x81\xff\x07\x9a\xaf\x17\xed\xd8\xd3\x9d\xcal\xd8\xcd:,\xbc\xa6\xab\xd4p\xa6\x8b*r\xc8\x16\n\xb1\x17\xe5\xebR\x82\x81\xa9:\xe4<\xdfH\xf3?4\xe9\x90\xd1\xbeZp\xc7\xc8\xad\x18\xe0\xf7\xea\x00\x9f\x98\x95\x9e=\xb2\xe7\xa4\xab\xf6\xad\x19\x19\xcb\xb0m\xc4,5\xe0\xf8\xaab\x19\x85IJ\xbc\x8f\"3p\x7f\xec8c}\xc2\xae\x80\x87\xe6YO\xef\x9f\x19\xfd\xbe0\\\xa1\xb8\n\xa7\x1drN(\xea:\x81\x19(\xb3\n\x1f\xf5p\xf9h9\xd7\xac&\x17\x8em\x98\xbc&{V\xef\xcc\x18\x18g\xfd\x91\x82&\xd7j\x8a,\xaa:\x9e\x17(\xb1\x02\x9b\xd3\xd4\xa8\xc2\xdeE\x18\xa5\x88\x95kl\"\x13\xf1\x9a\xec\x8f\xcf\x06\xbd\xec\xff\xad\x8a,\xd8\xaa\xe92\xaf\xec$v\xa0\xd8j\x9cN\xd4\xa8B\x0dK\xc4:\xe6\xc0\xb0\x17\x0b^\x9d\xe3\xe1\x991\xb4\xcez\x96B\x17_\"5\xc7,\xaa:\x9e\x17(\xb1\x02\x9b\xd3\xd4\xa8\xc2>\xb2Sg\xc5\x88e\xe9\xc8tz\x9c\"G\xfaY\xaf7<3\xc6\n\x8a\xcc\xd9*\xa9\xb2\xa8\xec\x14n\xa0\xd4J\x8cNS\xa7J\x05\x19WF\xae\xb1n\xf4\x00\xb7\xcc\xa6\x1cc\xa4\xe6\x96\x19W%e\x16u\x9d\xc0\x0c\x94Y\x85\xcfi\xaaT\xe1\x1f\xe6\xb1^\xc2H\xa6\xbb\x96m\x0fym\x9agc\xfd\xcc\x18\x0c\xdb\x95Y\xf2U\xd2gQ\xdbi\xfc@\xc1\x15Y\x9d\xa6U\x95*\x88\xb0\xbe>\x15:\x98\xd0\xa2\xa2y\xf6\x07\xce\x14\x8d{\xc0\xab\xa5\xc4\x95(i\xb9\xa8\xefd\x96\x07Hzun\xa7\xe9ZR\x0b!\xa0\xb3B>J\xb8\xa4\x9c\x1aY\xa7[\xfe\xa0\xa5^\x8aQk\xaef\xe1\xe14kD\xb3\xd6*\x9eh^\x90Eq\xd4\xd6b\x1eI\xe7{T:\xb5oU%\xd8{M\n\xd2\x1d\xb9.b\xbc*\xb5\xe7\xa7\xad\x82\xa8\x9a\x8bex\xdd,b\xe3\x1b\xd8\xf3N\xedy\x07{l\x1a\x8d<\x89N\xf1b\x16,\xc7\xaf\xfe\x8a\xfa\xd8\\8\xb7bbv\xf2\x99\xcf\x96\xf5X[C\\\x85\x89\xecb\xdf\xbe`5\xa8WeF\xb4\xa3\xceK\x11)l\xc1\xfe\x1e\xbb\xbdW\x08Q\xfa\xf8\x81\xc9\x90\x81\xbeI\xae\xbe\xb5r\xaf\x1aLJhh\x97\xa28\xb0\xb1\xe6\x86N\"\x87\xe6^\xfdGy\x13\x8a\xb5+\xbd\xcdX\xbb\xa8U\xa5\xb5\x8f7\xa8\xa4)\xdc\x11\x12ik\x84h\xb2ALf\x14h\xd3\xf3\xb6 :\xa6\x01\x020%\x7f\xc4fR\x9f\x9e\xb3\x15\xaa\x939\x0fC\x13\xa3\x1dr\xd6)\xaa\xe0\xf50\x98\xbb\x81\xfc\x9d^\x0ci\xa7;O\x03r\x1c$\xc7\xe5>7.\xcfCw\xaf\xe5;\xb0u,r\xd2\x98\xf7?s \x82\x97\x9ez\x86\\/=P'\x16\xf4V\xfab#\x83T\x9a\"M'A\x189i\xb5\x9bkB\xb3W\x8c\x92(\x0c\x12\x94h^\x100f\x96\"\xb9\xee\xc8\x95[\x82\x9eXN\xa3\xa7u\xc6\xaa\x96,\xec\xf8#I\xedt\x9d\x80{\x0fOeJ<\\\x07n\xe8\xac}\x140\xb9]\xe3\xd8d\xf6X\xcf\xfeH\xaa\xce\xcf>1\x9f\x0f\xcd\xcf\x93UY\xef\xbe\x8e\xfc\xc9\xf36\xb78o\xf5?\xd1Zb<\xfd\xe3\x8f\xc2g\\o\xd3\xf5\xed\xf8\xc1\x0d\xb7\x01\xec]2\xca\x18\x05.\x8a\x91;+9\x80\x9b\x7fE\xa0\x93\xbf\xb9\xcd\xa1\x8f\xc75C-\x10\x9a\x91\xa7\x1c\xa8d\x9e\xd1\xef\xf7\xd1q\x9a\xe1\xf6\x9dT\x1aW\xa9\x85\x9dEThY\xc5t\xa2\x038\xad|g\xc9\xedg\x90\xdc>\x1c%\xf0h<_\xe8\xfd\x89\xe2\xbd'\x15\x89\x9a\xd6\x14\xa9\xf3\xe7h\x13}\xd8qd\xcc\x0d\xddy\x82d\xec\xce\x95\n1'T\xba:N\xd3\x8b\xc5BxbN\xb8\xd3\xaaeSW\xf3\x1b\x0e\xed|\xe4+\x0e\xdd\x93G!\xa9\x0ej6gl\x9b\xfd\xfa\x96\xb7TP\x15F1w\xa6\x0b\xee\xfb\xcc\x95\xef<\xa2)69\xb3\x9f\xca=\xce\xecwx\xe7\x93{\x98C\xab\xe0c\xb5\x8fV(H\n\xf1\xb3\xa0\x83z@\xfd\xa24\x06\xd5/\x89ae;\xd6\x8er\xcd\x15'\x18\x1at\xf3\x96\x86\x16\xban\xb1\xdc\xcf\xba\xddAr.y\xe5-W\xc5{\xc0\x9d\xd0\x05\xd6~2\xf4\xdf\xbb\xbe\xe7\xc4a\xfe\x80|iN\xe9!\xbb\xeaHN_g\xce\xe8\x0c\xd8\x13\xd6Y\x1f\xc8\xdcQ+\xd7y\x89\xf8\xc4S\xee)\xe5\xca\x138tJZj\xe8\x8ezc\x138\xed@n2\xf2\xc6&\x0d\xf8\xd1K=\x8c\xbd\xb5\xdf\xf9\x82\xe6g\xc4\x84/\xe9\x97L\xc4P\xb6\xd9\xd4\xeb\xc5\xed\x90\xdb\xdb+r \xc4+\x88\x88eT\x8f\\\xf3\x9bE6\x83\xdaG \x8ej\x83\xa7\x95\x98s\x1a\x96\xe0P\x13\x07\x93\x8bX'n\x9e\xbe^8i\xa7XQ\xba\xbf+\x1dLzr\x13\xbe\xe7\x92\xa7\x1a-\xb5\xe2\xb8\xb5U,,N\x88D[\x94T/`\xeat\x93a\xd6\xcb\xcf\xe6T\xa0\xe0\x85\xb9\xd5l\xd2\xf8p\xe5\xb3\xe5\x89J\xe2x\x7fq\xd1\"\x9bW\x9a1\xc1x\x8e\xa37\x91\xed\xbc_'\xa9\xb7\xd8W\xe3L\x8d}\xaa7\xfei\xce\xd0\xa2\xf4\xfaQ\xdbH.\xa6,3uD\x8f\xd1\x81\x1e\x03'\xf2,\xfdEs\x18\xb5\xce\xd9\x95\x8c\xa5\xa7O\xf3\x13\xa6g\xc2\x13\xa8T\xb1\xc0\x1fO\xe8\x11\x12-\xcc\xd1\"\x8c\x91 aI\xb5\x93\x8e\x9a\x88Dm5\xdb\x11G\xc8\xb5\xbcG\x01\x07r\xeb \xec<\x0e\xd3\xfc\x87\x8e\x91t\xbc`\xe1\x05^\x8a:\xd94n\xc7g\xc4%\xcf\xc9\xf1\x14\xcd{\x12\xb8\x04x\xb1\xf7i\x9d\x15\xff/\x0e\xbe\xe6\xf3b\x1aF\xe5\x9e\x039;\x0c\xd8{\xb1y\xa6\xa9\xf6\xf3S.\xa0\xff\xfb\xbf*\xf2\x07\xb4_\xc4\xb6\x8f\x92N\xd5\xb0C\x1a\x02\xf7\xa0\xf3R\xf4\xa3\x91\xae\xe3\x80t\x1a\xea\xf9\xbf\xff\xfd_\xcf\xccO\x14\xec\xe7&\xa5N\x93W\xc3\x9c\x02I7\xfb%\x0eq\xa2\xd9\x8e\x83\xa2\xb4\xda\xac)\x87dj\xf3g\x19#\x14<\x85g~\xf5\x83\xe0ED,\xdd!\xf2!K\xcc\xb1\x17<\xa0\xf8`\xe9/\x9a\x17\x86P\xba\x15 H1\xcbc\xb5\x9d\x95y8\xba\xab\xda\xdd \xcc\x93 u\xb8\xe1\x05\xdc\x92\xb2\x06\x9d\x81O\xcf3\xa7\x83\xce\xfaU\xb7\xba\x8b\xea\xeb\xdf$\xc7\xcf6(N\xbc0\xd0\xa2\xd8^\xfa\xf6\x81\xdc\xaa\xa8\x83K\xe4\xb3\xe9?\x9a\xea\x8f?|\x94$\xf6\x12==\x82:u\xde#\xe5&\x06\xfcn\x0f\xf9@\xd8\xcc\\\xa0E>q\xd8\xb4\xcb\xc5\xf4\x82\xc6\xfe\xdd\xf56\xc4\x8bE-\xcbY)\x9dmTb\xde\xc9\x171Mt\\m\x97\xba(\xfbS\x8b\xdb\x8fv\x9d~\x11\xf6\xb2\x8bN\xba\x9ay\x1a\xb4\x9d\xb5&\xaf'\xf5\xc8\x83\x9a\xec\x19A\x93?6h&\xfcH\xbc\x8c\xed\xbd|\x05\x9as\x89\xec\x18\x05\xe9s_e8a\n\x9d\xa7A\xf6WK|\xd1\xc5\xad~\xa9\x19\x8e\xee\x9f\xae\x97\xd8s\x8c\xdc\x7fU\xef\x9b\x08\xc2\xcc\xe5p\xb8En=[uM\x8e\x90y?\x00s\xb9\xc9b\x9aer\xd7\x9fx\x04\xdf&\xc7\x0e\x1c\x84\xd9Sa\x8b\x81> \x97_e\x01i\x12\xb9\n\x0b\x0e|u\xf6:]\x85\xb1\xf7\x88\xe8\xeb\xd8\x13z\xb4\xab\xb8T\x07=\xe5\xa7?y\xe1$\xf5\x16\x89\x86\x05\x0e\xed4\xff\xb6\x0cm>p/\x9e\xa1\xdf,\x0f\x0b\x0fc\xf8\xc8e\x86-w\xaa\x80\xfe\xd9\x1f\x8fu\xd4\x03\x92[T9\xc7Q\xcb\xb8D\xa7\x0d\x9f\xe4\x8aZ\xc0\xb8\xe8\xff\xc7\x0fN4\x83r\x1f\xbcxU\x15\xd7\xb13\xadv\xb8\x03\xe2\x0c\x07l\x0b\x18\xe4\xa4\xf9_F\xdd\x95Y\xec\"\xf3\x98\xb5\x83\xb9\x18P\x0e\x0e\xca\xa2\xd3\\3\x0f\x95s\xce}\x98\xb8\xf7Y\xf6B~w\x8ef\xcc\xa8V\x06-\x0f\x80\x13}E\xcf\xfe\xb4\x89-\xbc\xf5\x0bO*\x05\xeb\xa1\x9e\xfd\xa1X\xcf\xd7i\x1a\x06\xec\xdb}\xc2u\x9a\x0d.\xbc\x02\x0bx\xd7\x0b66\xf6\xdc\x03\xbfVIV\xf6\x03\xeat\xfbI\xc7\x98\xc0O\xdb\x0e\x03\xffu\x81\xb83Fe\xd0{\xc4\xc4\x9b\xa7\x18\xac\xea\x1e:\x7f\xbc\xa7\xcc\xd9\xca\x13\xbb\x8ba\xf6\xa7\xb3\x8e\xf1\x8f\xae\x9d\xda\xe7\x9eo/\xd1\xcbd\xb3\xfcy\xe7\xe3\xc9\xdcN\xd0\xa0\x7f\xf6\xdb\xaf7\xbdo\xfb\x8b\xfe\xfc\xcbn\xed<\xea\x9e\xfd\xeb\x9d\xee\\\x86\x9bw\xa6k\xba{\xcb\x9c\xed\xad\x8d\xe3;\x9b\xd9\xfdt;{5~t}\xc7\xbb\xfe\xf5[\xf4\xedw\xf7\xd5\xdc\\\x8e\xaf\xef\xa7\xcb\xd9\xab\xe9\xbe\xf8{\xfd\xf3\xf5\xab\xe9\xf2\xfar\xb7\xfd\xfa\xfb]x\xfd\xe6v|\xfd\xa0\xeff\xfb\xbe>\xfb\xb8\\\xde\xec\xfb\xfd\x9b\x8f\xf8\xfe\xdd\xfd\xb59\xfb\xa0\xafg\xf7_\xfb\xef\xee\x9d\xed\xfb\xfa\xe7\x07\xf3\xfd\xab\xe9\xf6\xfaU\x7f\x7f\xb3\xef\xefo\xee\x97\xeb\xd9\xbd\xb3\xcf0\xb3\x0f\xf9s\xeb\xe6\x1e'\xef>\xce\xd6\xef?N\xfb\xd7\x97\xb3\xf5\xfb\xcb\x9b\xfbw\x1fj|\x9aa\x9b\x9f\x1f\xcc\xf7\x1f\xa6\xdb\xf9+\xfd\xf1\xdd\xfd\xc3\xf6}\xfe\xdf\xe5\xe3\xd7}V\x9f\x93\xbe\xbb\xbf\xee\xdd\xd4?\x17u\xbc\xfb\x90\xd5\xf1\x90=\xdb\xe5|\xef\x97\xeb\x9b\xc7\xa9U\xfd\xfc\xfe\xa3\xd3\xbf\xbe\xbc\x98\xcd>N\x97\xb3\x8f\xaf\x93\xb2m\xe9l\xdf\xdf\xdd\\\xbe\x1e\\{\xa3\x9f\x7f+\xf4\xf4\xf3O\x9d<\xaf[\x9c\xfc*b\xceN\x10j1\x8a\x90\x9d\x92\xf3ZqS\x9f{#\x84<\xa3\xd9SK|f0\x95(\xa8Y\xb9G\x11\xb2\xe3,Z(F\xa4\xfcEm\xecC\xe6w\xc0\xdd\xff\xe9\xafq\xeaE\x18\xfd\xabJ\xfeZ\xd4\xc15\x0b\xf4V\x80\xd1\x9f\xde]\xe9\xbd\x07.\x89\xd8\xcbg\xd8\xa3\xee\x94 8\x19#\x9d\xbd\xe0\xa5\x94\xdd}\xea\x99\xa4\xfch\xe1?\xb3%\xf5/\xc8\xb7=\xfc\xaf3A\xe9\xc2\xc3HX\x18\xd9I\xb2\x0dcW\x08H\x90\x1d;+aq\xb6\x1e\xa3\x0b\xb3'v\x8clRE:\x91l\xa2\x1dh\xc4\x0c\x8f\xc4\x86\xa1;\xce\xfe\xb4\x0d\x8f\x8b\x85\x9a\x15\xff\xf3\xd5\xd5\xbct&\xdf\x8a\x91\x1b\xbb\xeaO\xd2V\xb4\x81\xea\xd6\xb4\x01\xcbV\xb5\xc1\xf2\xd6\x81\xa0\xaa\x95\x7f\xca0\x00d\x8ar6\x07C\x7fq6\xd6_\x00Y\xb6:\xa5k\xba?jF\xb4\xcbF]0\xe5K\x96\xff\xbb\xa7\xbf8\x1b\xb5\xf2\xeb\xc9\xd9U\xc5\xff6\xf5\x17g\x96\xfe\xe2l\xd8\xcaQ\xeb\xb7HX\x95\xff\xbb\xaf\xbf8\x1b\xb4\xf2kaWs#3k\xff\xab\xd1g\xd1(8\x1403\x07y|\xbc\xd9\x9a\xeaQ\xb7\xe8\xf9\xd5\x137l\x92\x01u\xcb\xbb(\x8e:-\x00\xccMUK\x8aw|\x1d\xf8\xd0\x17\xb8\x1fU\x0f\x11\xce:\xe6\x0f%\x13[r\xe4d\xc2\x9c\xd5\x88QN\"P\xc0\xb3\x9f\xd9rV\xc8y\x98\x87\xbb\x03\x19\xf5\x97+Y`mD\xeez\x08\x1eW*\xd5\xb3?peOx\xfd\x86\x80aD\x1dD\xef\xeb:\xf1\xd1\x8d\xc2\x0e\xe4y\xb9J\xf3,HU\x8bP\xba\xae\x16\x85\x98L\xaag\xff\xaa\x9b\xca/\xa5\xa5t?\xe7\x8a\xfa{\xb7xC\x8f\xf0\x8dJt.K#\xf7\xcb\xf27/Tn7 \xcf\x91\x8f\xca\xedn2\x0ef\xcf|\xd0[Q\x8c\xff\xa1Q\xf6G\xf4\xb2$=_\x02T i!\x97\x08\"\xde\xf1\x90\xf7\x83\xfa\xa7\x13U\xd7\xfe\xca_\x85WFKk;\xcf\x7fB.e0^Y\xf9\x1a\xf8/\xc0\"\xd8Y\xd9q\x82\xd2_\xd6\xe9B\x1b\x9d\xbd0_%\x9be'\xb7\xe0/?\x18\xfa\x0f\x9d\xc2\x82\xbf\xfc0\xfa\xa1\xb3\xf1\xd0\xf6\"\xdc\xfd\xf2\x83\xd9\x19v\x0c\xbd3\xfa\xa1\xb3\xf3q\x90\xfc\xf2\xc3*M\xa3\xf3\x97/\xb7\xdbmwkv\xc3x\xf9\xb2\xa7\xebzV\xc7\x0f/\xcc\xab\x17\xe6\xab\xc8NW\x9d\x85\x87\xf1/?\xbc\xe8\x99}\xa3?\xec_\xfd\x90?\xd0\xe25F\xbf\xfc\x806(\x08]\xf7\x87\x8e\xfb\xcb\x0f\xb3A\xd74\xcd\x8ea\xbd3;\x86\xd1\x1d\x0c\x86\xd8\xc8\x9eh\xd9\xbf\xfdN\xaf\xd3{W<\xce\xc40;\xa3\xac\xec\xf1\x87\x97EMY\xa5/\xcc\xab\xbf\xfc\xd4\xb1\xf4\x17\xcdZ\x93\xd6\xa8\xeb\xd98\\j\xeb\x1d\xf35\x9d \xf9\xa2U\xea\x1e\x8b^\x1dV\xaa^\x03,`\xd8\xe9f\xbaw\xe30\x02\xb8K\x19\x8an\xc1\x8c~\x12V\xe5\x87\xae\x8d\xa9z\xea-m\xae!\xd4\xfe63)\x16\xbf\x9a\xe5\xdcP\x7f\xf3\xc3\xe2\x86\xe2\x937\xf8\xf9\x05JuY\xafm\x81\"\xc8\x07\xe8\xd1\xaeS\x9c\x9c\x92\xbe\x04Z\x8ckUj\xb5\xb1&;\x06g\xf5\xc90\x82O*J\xd8\xd2\x17U\x80{6U\x9e\x9c\x9fk\x95V\xb8\xd2\xba\xe9K>#f\x81=h\x16\xd8O8\x9a\x04\xd5\xff\x94\xd7\xce\xd5\xb1J\xaf8/':*[:\x16\xe96'\x9d\xffQmM\xa7\xeb\xe00AZ\xfe\xf8\x88\x94\xfc\xf3e\x9bd\xc2\xad\xc8\x0f\x83\xf7\xd8c?\x03\xf2\x0d^\x8d\xe8\\\x1eN\xb4Ir\x82[\xf8\xa1+O\xef\x98\xfa\x91g\xea\x85\xb5t\xba\xc4}\xd9$\xb2\x99\x1b\x11<&u\xabc\xb9\xb6\x9e\xfd\x11\x9d\xcc\xe5(\xff\x9e\xba\xcc\x8dK\xf5w\x0f\xe5\xcc\xb44\\.1b\x8fh\xc1\x81\xd7@\x14x\x95\xa6\xccF\xa9N\xd7D\xbe\xc2\xebo\xb8\xe1]\xf8*`u\xe4\xa9\x08\xe8C\x0e$\x03~**\xcf\xf1\x8cu\x17-\x81\xf3=\xe5s\x8eN\x0bc/\xcf\xa6\xe9/\xb2(a\"*\x10\x1b\xaa\xeb\x84\x18\xdbQ\x82\\\xf1\xa9#\x81P\xf9c1\xe7\xf2\xac\x1et\x02\x8d\xdd\xc0\x12\\\xa1=*\xd2k\x0f\xe0\xaa`\xb0\xd7o\x82\xc1\xec\xe7:\x1a\xcc\x83\xea~\xa7\xd7'c\xbd,\x8c3\xf4\xce\xe0\xdd\xa8k\x8d;\xc3n\xdf\xe8\x18f\xd7\x18v\x8c\x1e\xd6\xfa]k\xd4\xe9w\xad\xf1;C\xef\x18#<\xd0\x06m\xf1\x1b\xb7W\x90\x05/\x90\x16\xef\xd7~\xa4\xa5a\xfe60`\xe1\";\x01\xc43\x10\xbfz\x8a:;\xa8u\xfb\\g\x03-\\\xdc\x87\x97\x1f\xe3$\xa0\xd5\xbb\xa5\x8aG+/H\x0f\xc4!\xbb\xfcG\xf6cc\x04T \xab\xd1\x1d!\x7f\xc2\x9f\xe3\xab\x86\xff\xae\x81\xfcN~\x14\x08\xf8\x1eo9<\xaa\x04od\xb85\x84\x1c\x9e\xb8D\x95\xad\xfb\x99\xc3F\xe5\xc9\xb2\x02\x9a\xd4W0ub\xf2\x97\xbdR\x9a\x97M\xc2\xbdz\xc1)1{\xeb\xfc\x0b\x0f`\x9a,\x96b\"7Qh\"\x7f\xef5\xcd\x9e \xd1\x9e\xe5-\x86'\x85Ap\xb2\xe8Y\xdf\x13.\x0f\"\x06:w\xbc\x86S\xd5\x13_\xa3\x0d\xf0;\xe9\xcd\xde\x1c\x9f\xe3\xde_\xce\x92[\xac\x07\x90\xddEo\xdd\xf6\x02\x0e\x0b05\xa8\x0d\x99\xf9\xeaQ\xda\x17*F\xc0e\x97\xfa\x82\xc3Q\x1f\x1c\x02\xde\xc6\xa7>\xd8\xb0\xdf\xeej\x91\xb5\xc5F\xc3\xe3\x98\xd1Q \xf1\xda\x90\xa3\xb8\xe4\xa7\x83\x18&\xad#\x12\xc7\xa6|\x90\x08\x0cLM\x0b\xa3\xfa\nVf\xab\xe6\x15;\x96B\x85\xf3pw\x90\x1e\xdai`T\xc2\x19\x8ca\x95\xcd\xcc\xbe\xcc\xa7\xae\xe4\x08\xb7\xe6Ni\xd5L\xba\xd0\x0b\x87,\xf1\xa4\xce\xf4Ty\xcf\xb4\xf4\xec\x0f\xc4\xac\xa9U\xdb\xdaq\xe0\x05K\x903\xb7|\xab^\xdcR\xddn\x17\x1fV\xe4_Q\x97\x8du\x7f\xcf\xfe)\xa7\xe5\xee<\xb6\x1d\xa4\xe5\xabZjF\x84\xceBEq\x18i\x81\xed\xb3\x87\xb8\xa9\x15I#\x1d@\x9c\xfbx\xa5\x18\xcb\x06\x10(X\xfb\xb2\x0b\x8f9(\x0b\xb1\xed\xf4 \x9e4\xba \x8a7(\x16\\\x1f{\xb6\x0bYd%\xa2\xebW\xf47f@\x06\x9dU\xbf[\x9d%\xaf\xee\x1e\x94\x01E\x8fUcE\x92\xdas\x8c:i\xf55\x16So\x01\xba\"\x9b\xd5\xd2eQ \xf8\x85\xdb u\x1f\x82H\x82i\xc4\x9dNy\xe5\xf0\xeb\xfaKWik\xa3\xdb\xe1^\x0eE\x1c|\x87I\xbbN\xe8G\xeb\xack\xadc\\\x0f\xcd\xfc\x91~\x10_\x1cC\x07\xf5E\x9c\xaa\x9d\x88&l\xce\xf5\x978\x9c\xdbX+\xea\xfa\x8f\xbe%*\x90\xb4\xd6S9\x00\x92g\x9c{\xd50$~=S\xf5\xaa/\xc0\xdd\xcb1C\xe0\xed\xb9\x03@/\xc3\xa12nZ\xb5>?\xaf~\xe0\x99\x94\xc3]\x9a\x9fLJ\xe3\xac?\xd4\xbcX\xafg?\xd6,`\xc0\xf8tu\"\xa5O\xbe\xe2\xab\xd8\x84\x82ZU\xde\xefN2IZ\x12dp\xa7|j\xda\xac\xec\\\x80B\xaa7\xb7)\xe9E\xa2\x91fl\xe9Q{\x0f\x03\xe2\xe6 \xf0V\x9f\x92m\xfe\xea\xc6\x9c\xed\x99\xact\xd5vz\x8cI%\x13\xd7b\xf2c\xf2\x8a\xeb\xb7\x9e\xda\xa9Bf\xae\xaa\xbe\x8c\x93\xb0/\x93\xe0\xce\x02\xc1\x1f\xd52\xf9\x17>Ix\xd2\x97\xcdJ\x86B\xfa?\xfe\xc8grI\xc4\xd1\xd7O\x99\x14\x99\n\xba1\xfa\xef\xb5\x17W\xaf\xc7\x11\x0d\x12\"*\xf86+\x1c\xe0i\x03\xfasCM\xca\xac\xe2\xf6\x97R\xf0\xf2e\xd0V1\n\x0e\xd8o\xae6\xb2\xa0]\x8a\x82\xc4\x0b\x99l2\x81\xf0\x14^\x9csLW\xe5?\xccBT&|m\xfe\x13+\x8d\x91+V\x81\x1f\xa5\xfb?66^\xa3?\xf8\xc4\xb5ID\x03\xe5\xda\x91\x8b\x0e\xb8\x17\x0cJ\xb9\x97\x93=\x15L\x0e\x8f\xe2\xd0\xad\xee%5\xc1<\xffjH\x8c\x80\xab\xee\xfc\xa6^\x1aFs\x9b\xfeb\x0dpE\xa7|s\x0eDZ\xfd\x17~\xcd`\x89\xb1O\xdb%{r\xbe\x07\x14\x98:U\x95\xe7\x06\xd9!U%WB\x8eb\xf9^3\xbbIR\x1c\xb9\x90\xaf_\xd8cD\x95\x84E\xca\x06\xd8\xcc\xe2#\xd1\xca\n\xf5+J\xd61\xae_\xd3\xf7d\xad\xe7m5\x9b\xd6\x9b\x93\xea \x01\xca/r\xa2\xc0e\xaevfO\xd8{\x9dy)\n\\\xf56\xb4\xcc$\xa5\x86\xf8seV\x7f\xb8\x80\xbeJV]h\x12\xdf*\x91\x8b\xd3-f!\xed\xf4\xb3WOw\xeb 8\x99\x0e\xa8\xe3p\xa76\xa9\xbcgG\xcf\x9aJ\x1d\x82\xf6\xd2<\xc0\x92\xbf\x19\xf2\x18\xa1\x8a\xa9\x9f\x93\xa3\xd7\xc8\xd1\x9b\x94\xff!\x94#t\x0b\xea\x04$\xb0\xee(\xcf\x0dR\xbf\x1f#<\xf5\xb4\xbc\xd5$\x89D\xc88\xae_\x1e\xf2\x90\x9c\xe1$\xae\xd5Q\x8b\xa8\xb2qG\x0e:^\xb0\x08\xeb;\x1d\xc0K(\xb3\xf2\xce*\xbf\xee\xd7\xf5m/`\x97urt\x87=\xc4\n\xc0\xb1w\xc6?\x8c\x80g\xc5z\x89\xe0w\xda+\x0f\x0b\x19\x0d\xa0\x02\xf6\xf3\xc8\xc5C\x13z\xd8\x87\x1eZ\xc7\xbf9\xa0\xa0,\xdenU\xad\x8f\x8b\xdbb\xea\xe9C\xdd:\xf2\xa4.\xf4\xee\xf7\\\x0e\x9b\xd5\xeeQ\x1b\x11-\xb6\x80\xae\xc9\x16\xb5\xd2\xef\xbc3\x16\x83\xb1\x03xay7\x9f\xdc\x9f\x02\x98u\xe7v\x824\xe0\xe80\xa9\x0b\x93:\xdbZ\xcf#G)Qh\xcc.\x9bF5\x07O{w/\xc1\x95\xff2\xaad\xc1`\xb5\x1c\xae(\xd6\xef\xe4\xcb\x9d{\xc5\xc0\xc2.\x8d\x93u\xc4\x1dd\xb5\x86\xcc\x01\xb7\xa1;\xea\x8f!\xf3\x92\x92\xe7\xaf\xdbST\x057T\xd9\xebt\xa5\xcd\xd3\xe0i\x01\x0e\xbd6\x7f\x8e\x17U\xc8\xa5,\xeeK\xbba\x80\x0e\xf2\x14rN\xf8\xa4\xa6)M\xd4\xcf\x1a\xbb\x912w\x88\xd7\x040)\xd0&4\xd1\x9a\x97\xe3\x01\x9c\xc0\xe4\xa1\xc1\xdeo(\xd2\x89-\xa7\xe6d\xdc\xe1M)a\x1dl8E3#v\xcd\xcbc\xffV\xb4\x13\x1d\xb7bH\xeb\x8f\x8e\xf3\xc1\xbe\x94\xae\xf5&\x9a\x84\xa0\x08\xa3\xd9\x1b\x90R)Q\x1c\x87q\xc2\x0e\xa8\xd4\x06\x18?Y=y0M\x9c0BIg\xd5{\xfa\x94\x9f\xb3\xd2\\\xb4\x90\x1f\x8b(\x1b\xaa1V\xe9\xc1\x0eXu$\xe2\x92\x9acc\xf4)b^\x80E>\xe5C\xd2\xea\xfaZ\xebd/\xf9&\x15-v\xf9;\xdb\nx\xd3\x0b$e\x8fl\x08\xdf=\x7f\x92]\x05U&\xc4\x8b\x9f\xc0M/\x86\xae\x882\x9f>P\x9e\xb4\x06S\x90\x8c\xd6a\x8f\xba\xac\xa44P+\xb99t\xc7\xb1\xf0\xb7\x03x9\xad\xbc\x971\x02\xeej\x8c~\x9a4\xaf\xc6\x02\xdfAV\x00\x0d\x9e\xd6hH\x0d\xfav\xe0\xff\xb4,\x94\x9d\xee\xf2kaq\xb7\no\x9aTZ\xe5\x1d\xf9J\xef\xff\xbc\xfc\xdb_;I\xb8\x8e\x1d4\xb3\xa3\xc8\x0b\x96\x9f\xee\xde\xfd\xd20\xea:I\xd2\xf5\xed\xe8o/\xff\x7f\x01\x00\x00\xff\xffPK\x07\x08_;\x94/\xe8Y\x00\x00\xa8X\x02\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00 \x00swagger.yamlUT\x05\x00\x01\x80Cm8\xec}\xe9r\xe3\xb6\xd6\xe0\x7f?\x05J\x99\x9aN*\xb1-\xc9\x92l\xb9&3\xe5\xb5\xdb\xe9\xf1\x8d\xd3v:\xf7\xe6\x8f\x1a\"!\n\x16 \xd0\x04\xa8\xc5\xa9T\xcds\xcc\x9fy\xc5y\x84\xaf\x08p\x01I\x90\")\xc9q/\xfa\xbe\xcauK8\x07\xc0\xd9\xcf\xc1\xb6\xbf\xbf\xbf\xc7\x16\xd0\xb2\x90w\nZ\xdd\x83vk\x0f\x93 =\xdd\x03`\x8e<\x86)9\x05\xad\xa3\xe0k\x008\xe66:\x05o!\x86\xfb\xff\x1bs\x04&\xd4\x03\x17\x949\x94\xed\x01`\"fx\xd8\xe5\x02\xe4\x0c|\xb8\xba\x7f\x00\x98p\xe4M\xa0!\x9b2\x0e9\x02O>\xf20b?\x01\xeeA\xc2\xa0\x11\x00\x00\x0b\x11\xe4A\xf1'$&\x18{\x14\x9a\x06d\x1c\x13\xeb`\x8fC\x8b\x05\x03\xda\x07\x04:\xe8\x14<$\x80A\xc7\x99\xae\xef\x11\xf4\x8c\xe9O\x00\x11\x83\x9a\xe8'@\xbd\x04\x9d\xda';PQ\"b\"\xcf\xc1\x84\x83\x0fw\x17y\xa4\xca\xefgw7\xec'\xc0|c\n \x13\xb3Y\x81\xb1M\x8dYzJLLd\x0emlBN=\x86\xb8\xd2\xdd\x99\xcf\xa7\xf9N\x82o\x11\xe1\xd8\x08\xc8\x04\x0d\x83\xfa\x843\x05\xea\x1c\x92Y\x1e\xea\xc2C\xa2\xbdJ\xb6\xd4@\x14\x0c\xf7\x1c\xce0\xb14D\xe3p\x86\x80CM\xdfFb\x86\n\xd0[:G\x1e\x81\xc4@y\xb8\xe4\xb7\x02\xe0{\x1b\xb2\xa9\xbe\xcb\xf0\x97\x02\xc0K\xcc\xb8\x87\xc7~\xd08\x0f|\x8d\x100\x95\x16E\xbd\xfb\xaek\xaf4}\x8b\xef\x0b\x80B\xb9W\xbe\xb9\xc5\x84\xe7\x91\x04\xdf\x16\x8f\xff\x163#\x0f\xf3\x9b\x10\x17\xe8\xbaq/\xcc\x98\"\x07\x85\xf2=\xe5\xdce{S\xca\xf8i\xa0-\x9e\x059:0\x84\x86\x1d\x10\xc4\x17\xd4\x9b\xed1d\xf8\x1e\xe6\xabK4\xc1\x04\x0b\x0e\x07\xc03G\xfc\x0f\x00|\xe5\xa2S0\x86\x0c\x1b{.\xe4S\xf1\xf5!\xa1&\x1aE\x9a\x0d\x80\x85\xb8\xfc#3\xbe\x1b2\xa1\x9e\x13*\xe2\x98\xfa\x1c\xf0)\x02\x06%\x04\x19\x1c\x99 @\x13\xc21\xdfq\xa0\xb7:\x05\x0fS\x04\\\x8f\xba\xc8\xe3\x181@'\xc50\x91&\xcb\xcf\xbeN\xed@\x80\xcb\xf4\x0d\x94j\x08]\xd7\x0e\xf4\x02Sr\xf8\xc8B\x89\x00\xc0C\xcc\xa5\x84\xa9m\xbb\xedv\xf2\x8f\xcc\xec\xfeEM$\xac\x90\xcf\x94&\x82\x03P\x05\x8a\x88H\xc7\x8f\xc8\xe0\xa9\x1f\x92\x89\xa6\x01\x80:\xc4Qd:3M\xca\xc0\x83\xcf\xd8\xc7\xb69J\x13I\xfd\xc8Q\x05R\x1f*T\xfac\xd8\x18\x11>\x12\xf2\xd7\x08\x9e:\x0e\xe6\x8d@-\xda\x08\xac\xf1P\x19\xf2\xe6\xc8k>\xd5B\x06\xad\x81\xcd\xa8\x91\xfa)g-6k\xf7\x15|\x1cJ\xf0\x0cy\x8d`\x01@K\xe8\xb8\x81\xcb\x8e\xdd\xd0~@1M[\xd7\xa3\x9c\x1a\xd4.\x96\\\xb0v\x8a\xa2E\xd7-\xfa\xa9\xc2x\x81:\xe6\xe3\x82&\xc2\xd7n\xab\x93N\xbb\xa0\x0dt\xb76\x11]\x17\xa11\xdf\x94\xafV\x10\x8auu\xaa<\x85\x84 \xbb\x99\x1d\xb11\xe3\x88\x8c\xa0in,x\x9da\xf7\xa0389\xe8\x0f\x0e:\xa7\xdd\xc1\xa0?\xa8\xab\x8cEaX\xe2\xa5\xf3\x9f\xea\xe3k\x1ft\xfa\x07:\x06Q>-R\xbb\xd4\x88\x1c\xea!\x80\x15\xafII44V26\x8dg\x89>\xeb\x95\x8c/G\x98\x98h\xb9-\x01-\xa0\"\x00\x9ek\x08)@\xacp,u\xfb\xe2\x86{zx\xd8>\x10\xff'$\"\xd1\xf3~\x89\xeb\xbe\x86\xd8F&\xe04\x8c\xb8I\xca\x95\x1f\xb2\x1510\xb1$\xb8\x12\xdc\xc4A\xca\xbdl\x10\xe6 tR;*I\x87\xbd\x88\x03,\xe3\x1c1\x10\xcc\x80\xe1{\x1e\"\xdc^\x01\xb6\"AO\x0b\xcc\xa7R\x8cD\x9bH\x1av\x1d\xdd(\xf3\xdcE\x94\x93\"\xb4\xfa \xc3NJm\x04I%\x96\xde\x0b\x1f.sD\x02m\x80<\x8fz\x013e6uhC\x8e\x18/fi\xc0\x84\x80\x03\xb2\x9d\xf4\x0bu8\xba;N<\xe8G\x05\n\xd8\xf0\xdf<49\x05\xad\xef\x0e\xcd$\xa4?<\x0f\x00E\xba\xd0\xda\n5\xff\x9a\"lM\xf9\xdf\xe5\xf4\x84r\xc0\x00\x06\x7f\x1a\xc8\xe3\x10\x13 !wDZ\x17z\xd0A\x1cy\xa9\xc6\x98\x9c\x82 yQf+\xd3\xaa\xd4X@\x96\x08\x82h\xf96\x1ez\xf2\xb1\x87\xccS\xc0=_\x0d\x7f\xa4\xd0\x12\xdf\x19#O\xf9z\xb9\x9f8\xb0\xe6\x12\xa0P\x92\xb9\xc8\xc0\x13l\xe4\x87\xb6\x91<\xf4\xda\xbd\xc2\x11|@O~,\x80a\xbf\xc0\xa4\x88\x917\\AP<\x85\x1b\"\xa2\xc6\xec\x90\x1b\xc9\xa0Z\x06\xa9\xad\xd810\x90E\x14\xb0\x03)l\xc0\xde\xd4\xb0\x026gmQ5f7\xb0\xc1\x02\xfbHb/2\xc4Z\x7f\x9c\xb0\xa1\x08\x0cz\x1e\\\xe5~\xc3\x1c9\xda\x08@+\xa9 />F\xfdmh\xc2\xd2\xe2S\xd5\x92e\x18\xf4\xcd\x9cmf\xcer\xf2\xae\x98\xb5o\xf2^$\xefe&\xfa,\xb3?\xaf\xd1\xba\x9c\x00*Zw~q~\xd5m_\x9d\\\xf6\x06\xc7\xfd\x93\xf3\xe1\xe0\xec\xaa\x7frrt~<\xec\x9e\xf4O\xba\xc3\xc1\xd9E{p\xd5\xef\xf4\x8e\xfa\xbda\xfb\xfa\xfc\xf2\xe2\xec\xaa\xdb?;\xee\x9e\x1f]\\\x1c\x0f\xce\x1b*\xedR\xe6 \\\xd6g\xe7\xd8DfvR\x95\xc3\x8f\x87e\x8dX\xf4&\x12\xaeP\xd8\xae\x14\x19\xcb W\x05\xe1I\xb28\xb1\xb6\x93]\xdd\xc8\xf5\xafi\x16H,\x9a#\xc2\xd9V\xe5J$\xa39\xc1r\x10c\xd0B\x07\xb2\xef\xf5\xa2\x92\x1a|KU 9\xe4x\xb5\xe9M\x1a\xf3\xcf\x0c\x11\xf3\x0dXL\xb11\x0d\xa4\xc3\xb79\x03\x98\x08\x8eO\xa8m\xd3E\xa0P\x88\x98.\xc5\x84\x9f\x827o\xaf\x1e\x04\x13\xfe\x97\x0eOK/\xbc\xad\xe0\xc7V\xady3a\x117\x99w \x14Rz%\xae5c\xff\xef\xe9\x9e\x7f\x96K&\x9d\xc1r\x85\x1c\x179\xae;\xec.\x87\xd3\xd5\xf3\xf3p\xe1Y\x93a\xcf\x1b<\x0e\xa7\xfdI{\xe0.\x97\xf3\xc2\x89\xd7\xc2R\x8dB.\xb4P\x11\x01\xee\xa0\x85\xf2\xce[\x92.0\xd7\xd6:\xa7^\xde\xb5\x8d\x1d\\\x18i\xdc\xc2%v|'\xec\x1e\xd0\x89\xf4\x81\xc0E^v\xcc5\x06T\xd3`\x9d\xd96\xe0K\x06\x1c\xc8\x0d\xb12\x98\xb2\\R\x15\x14\xd8\xca\xb6\xeb\x0eZ\x98@\x8eLa\xc2\x1e\x96Lu\xcf\xeb\x9d+\x93\xd6$\xd3\x7f\x13\xfb\x07\x80KY#\xc3w\x1e\xaf\xecB\xc0\xb0E\x90 \xf8rO\xd3\xb5\xb6!\xe0\x14@0\xf1m[-{\x19\x940\xdf\xa9f\x00\xb7a+\xc7\xd4\xccK%_\xc6#.\xa2f\x10|\xf2%p\xfc \xb1B\xc9\xbc\xee\xb9\xf9\xb0<\x10?3\xdfu\xa9\xc7\x91\xba\x04\xeeP\x13\x05\xd6\xd0\xb0}\x13\x81O-\x11E\xb6>}\xef!\xee{\x04\xc0 G^\x80W\xaez\xfd\xf0\x13\xf8\xd4b+b\xa8-\x90\x07.\xa6\xc8\x98=,\x7f\x10\xeb\xeb\x9fZ0\xdd\xc4\x13q\x1b\\\xc0\xd5\x0f\x07\xca\xf0\x0bC\x85-\x05\xc4\\S\xfa\xd5J\xbe Q+\xd36 LQ<\\P\xc6\x8d5[-g\xd5\xd4\xee jT\xb6u\x84\xfe\xaa\x89>\xc7\x12\xf3\xb0\xbc\x10\xcc\xfb Pm\x1e\x9b\x1c\xca=#\xa7\x1b\xa9\xea\x95\xc0\x91 m9\x15\xc6\xec\xcc\xc1\x84\x82\x05\xf6\xc4\x86\x18\x07r\x9d\nk\x11|\x1f\n=\xf5\x824\xe1\x070\xf1\xa8\x03~\xb9\xff\xf5_\x01\xea1dh\xd0\xdb\x97\xa37\xc3^\x18\xf20\xb4\xf1s\xa0\x14+\x1e\xd7\x9f_\x89\xd6\xafQvN\xc3\xfd;\xaf^\xab\xeaj\x81\x9c\xdf\x02\x8a\xa0\xce@\x8c\x05fy\x05L$y\x17\x98\x19\x0fE\xac|\x99IVS}Q\xd2\xd4\x08\xda~V\xd0\xc4^/.\xe6\x19c+\xf3\xb3\nI\x1chK\xbdP\xa6\xde8\x99\x95$\xddL\x99/\x91F\x17\x85\xeeUVg-\n\xad:WR\xe3@5\x02\xbd\xff\xdc\xd4Yr\xe3\x1fV\xe7j\x92~??\xc7\xffF\xbd\xf7wO\xf8\xf1?\x7f\xd2\xf7\xd7\xd7\xef\xae\x9e\x7f91\xba\xef\xee\xce&\xf3\xee\xd5\xf5\xef\xc6\xcdt\xd9^\xddAkq5}X\xb5\xe7wg?\xbe};\xbd\xb8b\xf6\xfb\x7f\xc3\xde\xd9\xa4\xed\x9f\xff\xe8L\xee\xa7\xf4\xf6\xc2\xfa\xf8l\xbe\xbd\xf6\xfe\xfcpsy\xfbp\xb6\xb8\xb2~\xfbm\xf1\x0b\xbd\x0d{\xdf\xae\xf5XC\xc4\xf5\xc6\xec\xe5\x15u\x0c\xc9\xecp\x0cmH\x0c\xc4\x0e\xff\nW\x9b\xd7\x94\xa0\x02\xdd\x0b\xf7G\x82\x08\xb6@\xb9\xe3=\x93[\x92\x7fm!)\x1cu\xd1\xe4\xcf\xc2\xa1\x86\xcd\x82\x0c}\x8c\x8c\xe9Q7m5\xc0fE\xa6Z\xd9j3\xf1;\xd3\xd3\x1c\x94*m\xbe\xc4\xaa-\xafj\x85\xf3\x82bR-\xac+\x17\xb0h3m\"`\x87\xc2\x1aOb\x0e\xab\x0eB)7\x11\x13\x18\x14\x13&\x0d4%\x89\xdc\x05)\x15\x11\xcb\xfb\xeb%\xef\xa5\x8d\xf4\x97%\xa4\xa5\xae'dG\xd1\xacDr(jB\"\xb2\xe2Ku\xafN\x95)m\xc9\x19\x05\xae}\xe4\xa1\xa7\xbcK\xd2g8\x90\xa1\x0f\xe8)\x9b\xb9A'\x98k\x91[\xdb\xc6Z\x86\xaapZ\xe3\xd0-\xf6\x0e\xaa_\x92n)\xdc\xd5\xbfs\xc7\x14Uj<\xb9\xe6\x1d7kd0\xa0\xcf\xa7\x1a\x83Q\xdd#ev\x83\x89\x94\xd9\x98B\x1c\xc9[\xd6P\xc4\x87\x01^\x8f\xf6W\xd1\x8c\xdd({C\x8f\x94\xa19\x8f\xb6_\xa8t\x07\xdbSg\x01R\xa0\x86E+\x91~!D\xc1f\xc0\xf2\x8d\x80\xa1\xb4\x8dd\xc5V\xd7bM\xb8\x0b@\xe9\xd6\xbe5\xb0\xc2+\x96A\xea\xad\x11(\xb3H\xa0\x8aUR?\xae?\xb6\xb11\x9a\xa1\x95\x1e\x9d\xbe\x1a,\x80\xde\xa3\x95\x0e#\x0b,\x081\xeal*\xafld\x90bd\x98<\x88sh\"\x1bYb\x85\xfa\xf0\xaf\xf8\xef3\xd3\xf4\xfe\x8e~\x8a\xcew\xe84^\xa3\xefR\xdbS\xa8\xf6\xb4C;\x97\xce\xfd\xcc0\xceB\x8fO'\xe02\x82\x8ba\n\xd4_K\x89\x8dT\xbfp\xb9\xd9\xb6\x81B\n\x19\x88\xc1d\x86!L\xd6\xa8\xaa'\x9dj\xd9\xd5\x9a\x06\xe8\xd7\xf7\xca/\xbb \x82/\xe3\xd9\xd7\xf3\x861\x89rV\xbdI}\xb4(D\xf6\xc7\x0e\xe6\n\x87\"\x8a\xd7\xab \xe4\xe0s\xe3\x12\xa7\x8c c\x0b\xea\x99\xd1\x19#%\x16\xf7\x90C\xe7()\xcd\xbc\xbf\xbd\xaf\xc4\x98Zf\x7f;Q\\\xcc\x97\xe2\xbd\xd5Zt\xa1\x9ef\xd1\xc5\x9b\\j\xa2\x8b7\xab\x14\xe0MXR\x11\xa1j\xa5\xcb\xd5q7\xf9\xd0\xb65\xb7\xd9\xdaC#\xcd\x04\xd4S\xe8\x1d\xc5\xb1iU\xe9\xb5;\x85\x88\xdf\xa3U\xa2\x1c\x98\x81\x85G+z\xa8\xc2\xe5\x90z\x1e\xea\xf0\xaf\xb9*N\x7f\x7f\x0d\x1e\xabd6)b\x94\xce\xe6W7\xc8\x90b%\x0c\xa6\x14\x03ogJsh\x07\xf6l\xed\xcc\xba\x8b\x1e\xe9\xda\x02\x8f\xce\x17\xcb\x93\xab\xe2d\xa7<\xe9\xa0\n\xec\x18\xf1\x05BD\xf5\xcb\"\xdf\x86\xb9\xc9\xbcZ?\xbd[\xd7\x1b(x\xb2\x81r\x1b\xfe\xb8\x8a\x82\xfadL\x89\x89\x895\xfa\x16L\xc6\xc1dL\x94\xaf<\xac\xfc=\xa2\xc3\xd6\x84|#y.\x8f/!\xd1\xf2-\xe2\xc3\xb7`\xf33\x0f6\xd9\x14z\xba:G\xb5\x05\xbbV\xa7\xdd\xfe\x16y6\xd2\xd9\xc01\xe94\xebs\x89A\xb5.\xee[4\x9a\x9a\xcd\x17\x1b\x8d\x16\xbb\xf3/5 \xd58\xed;\x88\xbd-\x18\x81\x1dE\xa7\x1e\xaa\x1cz\xa6\xb7-g\x14qKJ8\x816+\x15\xd9\xe2\xa1$\xae/\xf0\xfb\xa5\xe3\xf9\x08me<\xf7\x9e\xf1\xb1D\x89\xb62$Nk\x0c\xe8\x92\xf1\x0d\x06T\x16[\xa7\xb8\x0d\xbe\x9f`\x9b#\x0f\x8cW\xe1\xa1}\xc1y\xf6\xc3k\xd7\xbc\xcdc\xeb\x0f\n\x1d\xaa\xed_X\xabH%>\xb0\x86\x8e}\x19\xbe\xae4SH a$L\xbbH\x10\xaa\xec+\xf8:r\x01\xe6\xc5\xf7\x84T\xc7\xba.%H\xd0\x9b\x8c\xd7\x1c\xf1:\xdc_U\xba\xf1\n6fh#\x0eUO\xf5\xe9\xc6\xae\x0cf\xf6\\\xf0\x97m-\xcb\xe3\xe7\x84\x16\x80O\xc5\xa9\xee\x84Y\x98\x81 \xdc\x14\xf7\xeeT\x92\xf7\xdd \xf1\x0b8m\xed\xe9\xed\x06\xb2\xfd\x82\xe2\xfb-\xd1M\xcd\xa6z\xa2\x9b \x88\xb7;\x9b\xed\xe6\xb8Jf\xf6Y+\xe8Nun\x87\x19l\xd6Y\x94\xe5?\xc9\x10\x0cH\xcc\xe0O\xc4\x0e\xc0\xf9\n\x98h\x02}\x9b\x03\xcc\x81<:\xc8\x00%\xb6\\O\x0b9\x98\xf4\x13\x9fP\xafy\xec\xb3\xd2h`X\xd4M\xb1\xe1\xfa&\xc3\xc4\xb2\xd1g^\x04m\xe84v\xee\x1f\xb2\xd2\xb8\xd1\x16\xce/P2K\xb6s~6\x02\xb9\xb95l\xba\xdc\xfe\xf2\xe2\xbb\x9d\xed#_\xb0 \x97n%\xf9\x8aDz\xe3\xad$;\x92m\x97R\xfb\xb4\x94\x8b\xea~\xb6\xf8j\xe0\xe0\xcb\x10\x05\x08P|\x1e\x0c\xacUP\xb6)eh\xc4\xe9\x0c\xe9Nq\x94\x94Ae$\xdf\x04\x12\x93\x89-H1\xb2!\xe3#\x8euW\xf7W\x81\xaf\x05\x15\xa4`\xb2Cq\xcf\x0bc\xc1\x00<\xc4P\xbd\x9b\x04]\x0f\xcdG\xe1\xdck\x15\x8f7\x93\xdf\x8c\x95\xad(\xc5Rp#X \xce\x1e\x15\x9d\x8f\xfe\x9c\x858\x91(/\xe0\xb21\x85\xc4j(S#\x07\xd6\xbb.@\x81\xc4\xf5$\xd2\xa2\xd0\x0eE\xa9\x16\\\xe2\x8dk\xab\x8e\x03\x97\xa3l\x19#\x0f\x9aOSA\xa8\xf0#\x13\x11\xeaT\xec\xb2\x89\xc4\x7f\x07\x1e~\xbd\xfc\xf5\x14\xfc\x81\x00A\xf2\x9a\xf7\xb0\xe80\xc1K\xc0\xa7\x98\x01\x8f\xfa\x1c\x81\xc5\x14\xc9\xd3}\x89\xc7\xc0L\\\x9c9\xa1>\x11\xf7i@\xd3\x0c\x12\x1d\x1b\xb2\xa9ZU\x89\xee\xc53(\xe1\x1e48\xe0\x88\x89\xeb\xbc\xbe\x0b\x14.|\x8bH\x1f\x0d\xdd\xf9\xe3\xf7h\xf5\xf7!\xc3\x16 \xe8\x1f\xbd\xff\xf1\x1dHt\xf2;9\xdb\x94Z\x06\xedE\x12\x168\x15\x0b\xcf\x11I\x05\x05\xdfi\x08T\x1dLU\xd5\xef\"bk\xb55\xfc5\xd2|\xa5\xb1\xf28S\x845eq\x94\xa6\x19V\xc7\xbf\xe8#\xb9\x84\xea\xf2\x88\x1e\x98\xa1U\x1a*\x13\x1bJ\x12\xa7\x9b\xe4\"=\xe57%\xd6T\xbe\xd5\xc5{\x06%\xcc\xf5\xc7\x9dg\xe3\xd1\xf4\x91\xfb\xd4\x9e\xfb\xddgkf\xcdzC4\x81m\xf2\xb4x&&$O}\xa7g\x1c\xbb\xf0\xc8\xefA\xf7\xb9gu\xbd\xa1\xc5\xdc'k`\x0d\x0dv4\x1b\x1a\xfe$\xe9+e\xfb\xe2\xfeC\xf3WD\x1aa\x01\x95\x1f\x13#\xa8|Y\xb4\xe4&%\xef\x86LhK\x05\xe8\x95w\x99\x0f\xaf\xf4\xec\xe8\xafCS\xe4\xa7\"\xb5Q5c\x8d\xaf\xd2Hwz\x19jO3\x82\x1c\xa0\x16\xa4\x86\xf7\xca\xb9A\xf5\x99\xb2\xfa\x95\xd7\xed]\xebXx\xdcz\xbb\x85\xcc-\xdc\xf7Xe\xa4\xfd\xbd\xa8\xed.\x82\x85MR\x96\x8cF\xc9O\xbdT%\xd1%q\xe3\x15%q\xf2\x90\x93\xccf^q\x8d[\x8a\x92\xf4G\x88\xc3,G\xbb/\xe6w\xd1\x00@\xf0(\x9fP\xc9\xe6\xa5\xa9\xa1\x88\x1bO2\x17\xd7\xf9k\x10\xecf\x93C#\x0d\xad\xb2\xe0\x91sQ\xf9;\x0f\xca\n\x17%\x82\xaf\xb9|a\x1b\x15\x08 \xa6\x96\x9aC\xab\x95\x1b\xadd\xf3yz;\x93f\x87\xd3+\xbb\xe9d\xa3\xbb\xf4\xb6\xbc\xb1e+;\xecsr%\x1e \x0d\x89\x12\x03of\x0e\x1a\xe5\x85\xd1s\x9b pEM\xab\xae\xb35\xf9W\xd1\xcc\xd7\x12\xbf \xd5Asl\"b\xa0\x11\xac\x99\x0e\xcaK\xf9F\xf2\xc5\x9c\xd1\x02\x13\x93.j!p0\x19\x85H\\\xe45\xc1`R\x7fl#\x81d$3\xbe\x91\xe9{\x0d\xea\x1etA\x82\n\xc8\xde\xfa\x04\x0cH\xc0\x18\x81O-\x8e\x96\xbc\xf5\xe9\xa7\xa0I\x846,\xae\xc8o\x19\x9d\xf0\x05\xf4\xd0\xc8w-\x0f\x9a\xa8\xf5I\xe1O\x18\x10S\xc6Gq\x07\xe3\xcf\xcd+\x15l\xa0\x95\x0f`W\x13[\xf9Q9P\x07.\xc5\x9bZ\x90\xea>U\xc1H-f\xdd\x8dAu\xf6\xfe\x8a\xdf\xa1=2\x91K\x99\xee\xcd\xd8\xa2\x08\x1dl\xffJ\xb2\x97\x0b\x10\x1a\xec|\x8d\x18\xb9\xf9\xc6\xd6\xb2\xd5\xfe\xd8\xd4\xedi\x10f\x9a\xa4\xb6\x05\x88'\x16r\x11\xc1\xee-Sq\xda:\xa7<\x95f\xa6mX\xf0c\xe9%e\xe9\xc3+\x05\x9aR\xd6\x7f(\xd1\xb4p\x0cq\x83\xdd\x8e#\xb7\x99+5\x88X\xacd\xb3\x9fT\xeb\xce\x12K\x1e\x8e5\x08F05\xa5\xf5\x9eS\x8e\x89\x95\xfa\xca\x85\x8c\xa1\xf0o\x0f=\x8ag\xbbSF\xbd\xd6\xbcj*i\xc5(p\x93d\xff\x01-\xf9]H\xb1z\xea\xab\x9c[R\x15\xa4\x99\x06\xa7\xa3\x12\x19\xc5\xa7V-\xb4!\xca\xdb\xd0b\x05\xb1F\xbc\xa6#\xa1\x121P\xa2\x93=\xcd\x88\x1a\xe2x\xbd\xc1\x8c\xdc X4\x93\xc0\xd6\xca\xcd\xb2\x06%\x1cb\xc2D\xc10\x0b\x90O\xf9\xbf\x85-\xd1G}\x07\xe7.\xa0\x1b\xb8\x90\x11`\xa6e\xd3\x00'\xdd\xc3\xef\xae\x19H\xa7\x03\x97J\xedl7\x91\xcb\x0bG,\xd1'\x94\xb8]v+\xd8\x94\xe6RMS,.\xf8V\xf2\x9c/'x\xca\x98\xde\xbf\xa2?o\xcc\x92\x8b]\xa3\x0d\xf8e\xb9a\xb6\x0d\x18\xaf\x00\x8e\xe8\xb3{\xa3X\xa0a\xa15\x8b'\xa9\xfc\xd4\xb0z\xd9\xea6\x94\xa9\xb5\xee}\xcb\x1e;f\x04\xaev3}\x03\x899L[\xa2ua9\xd2V\xdae\x8b\xe8\xa9\x8c\xa8\xa5\xf8\"'q\xdf\xe4\xa8\xa9\x1c\xdd\x85tm(C7\x97;\x93\xa1\xd0\x0f\xb1u2\x14\xb5+\x96\xa1\xa8E`zr\xac\xfa&:\x15Dg\xf3\x0c\xe3R\xf2\xa0\xa1\x98mh\xaa\n\x12\x87pL@\xee\xd5\x93o\xc0\x95\xb92]\x99\xd3\\\x8f\xe3U% U\x16\x00ud\xdf\xad\xbcVY\xbf\x13\xa9G\x94\xaf\x7f)\x99G\\+\xa9\x88\xa6 f\x7f\x05\xef\x1el`]v\xb7\xd6\xa8H\xb2\xbcAV*\xeb?yeW\x05\x8fw\xf8W,\x16k\x83\xef\xb0\xe5\x9ef\x08\xa9\x06i\xdf'\xee\xe4(\xaa\xd3}\xcdF\xa8\xca\xc8\xc2\xfd\x11ee\xce\xe2Ji\xc3Q69\x05\xfe\"j\xba\xa9_W\xd4RC\xc9\xb2\xc7\xe1\xaf\xc5~VB3*\xb0}\xb5\x9cS\x8e\xd6F\xa1\xa2\xf0^\x12\x83\xca\xdfSK\x0b\xaf*\x1a\xfd\x87uo\xdb\xb2\xbay\xc0\xfa\x91r\xd4X\xaa7\x92\xc5\x82h5\x18P\x83\x00u\xae\x05\xfb\x16\x93\xae\x15\xc9\\L\x9a\xdb\x1f@\xc5\x0f\xadO`\x82\x91m&\x8bJ+\xc4\xe4R\x11\xa1\xd1\xff\x8e\x16\x98OGs\xc4i\xebS\xf4R\xf2\x98q\x88I\xd1\xde\x80\x80o_L\x98+\xac_E\x14\x05!\xae$v\x1eG\xc5\x95\xfe\x80'\xe1\xcf\xdb\xb65/\x16\xbe\nU~\xa5\xb1\xabp\x92\x87\x7f F\xaf\x0dZ\x83V{\x9a\x8e\x93_\x8b\x1c%\x08cW\xdd:\xf7\xd7l\xa8\xaa\x8c,\xda\xd7[\xb0E@\xbf\xbb\xa0\xe1\xe8^m\xbc\xba\x91[\x8f\x94\xb0a\xa0\xaa\x88\xfd\xf6\x15\x90C\xdb^\x15+\x9e8\x91\x1d\xcf\xe5\x0d\x03\xa2=\x90o\xcc\x03\x98\xde\n\xcb\xb1\xa3\xd5\xcf\xb7\x88\xb3zX\x0e\xc0\xcdD\xa9\xdf\x07Td\xc0E\xd1\x99\xf0\xb0.\xfb=>@\xe1F\x0d\xf0&\xcc(\xee\xc4\xf6\x8b7?\xa87\x02A\x02\x90\xe3\xf2U\xaa\xdb\x83\xaf\\\xfd_Dm\x1e\x02\x82o\xe8\xc2\xb6 \xfa1[\x0eS\xab\xd4\xc5\x9e\xc6\x8a9\x1b\x17Br{U4.\xa8\x14\xec \xba\xe5h\x94\xde=\x04|\x12\x083\xf4\x02\xef\x05\x08$\x94!\x83\x12\x93\xedBB\xb7\xcd\xf5\x06\xa1\xa1\x83\xc9Koo\x8c>y\xe2\x17\x8d`m`x2\xe8\xb5\x93O5\xe1\xfe\x1f\xe2Y\xe3Q\xa0\x9d\xff3:^\x1b\xdeg\x11n\x88\x8an\xebL)p%'Q(\xa6\xdb\xd1\x1ba91\xb1j(\x8e4\xb65\xd5\xa6\x00\xe85\xab@\xb1\xa4\xf3\xa9\x87\xd8\x94\xda\xcd\xa5\xac}\xd0\xd7\xc8\x98\xfc\x04Y\xe1\x06\x88\x8f\x8ez\x05\x88\x13v\x8c\\D\xa0\xcd5\xaf\x80V\xee\xa6\xddy=:R \\\xdb\xd1\x10\xb9\xfd\xb3\x86~H\x80\xba\n\x92\x83\x92n%\xb5\xf9\xf4\xb3\xf6(\xc5\xea\x94\x9acc\x91|m\x86\xbbH\x0c\x1aJ\xa5\x89\x03\n\x8c}\xc1\xc7\xd2\xbb\xed\x17\xd03C\x1a\xe7\xe3\xd6\xd7\x7f\xb1\xed\xf1b8\xe0\xe6\xdc\x81\xcfpf.f\x8b\xae\xdf?\xeev\x8f\x91\xe9\xfb6\xec\x1a\xab\xfeq\xd7\x9e\x14jct\x8a\x8fS\x0em\x10\x12\x03\x8c\xa1-\x94L\xde4\x95\xbeQM\xa7\x9d\x11\x16\xe6;\xd1\xe1\xf9\xe0\x9f\x11:\x04=\x82L0^\xa5\x9fPY%\xf7\x05f\x9f\xe1\xd8@1/\x15\xc6\xefH5\xcb\xae]\xa3\xdeC@\xca\x0fr\xea\xd5\xd4j77=\x17\xd4\xc1\xff\xc0|jzp\x11s)\xee\xf5\x0dK\xbf\xcf$f\xa0cw3\x14\x15\x18\xb5\x9b\xb2z\xf1 \x11\xed\xe3\x0c\xf1\xec<\xdd\x95\xf1u\x8d\xf5f\x05\xe0\x17\x91\xdc\xad\xd4Z\x8be\xf7\x85\x8b\xac5\x0d\xff\xc67\xbc\xbe\x1aGP\xa7V\xf85]\xa6\x18\xed\xa0\xce\x19\xa6=\xcd\xe4\xa2\xc6i\xbf\x94\xc0H\xaf\x95uW\x15L[\x0d{\xb5m\xa5\xdf|17]C\xd8\xcc\x1c4Q\xea\xb5\xae\xac\x1as\xf3\xed\xf5\x1e\xab\xe6e\xc6\xdf\x1c\xd9\x17\xed\xc82o\xa7\xff\x93\x0b\x88U}\xdb\"\xe4|\xfaU\xa3\xcf\xd1\xa9m'\xbb\x89\x12\x91\x88.\xd0\xce\x98%m6\xa3$+oJP\x1c\x80\x87)f\x01\x87\xc5+\xbe!10\x01\x8b)6\xa6\xe2K\x9f!\x0f,\xb0x\xc0\xce@x\x8e\x94Q\x81\x89O\xea\xc4\xc85\xec\xc5\x8b(]n\xbfA#%\xdbH/\n\xdc\xc3\x07\xe4\xda\xd0@\x0d$@\x85\xac(\x05\xe1\xc1\x1a\x82\x16\x80\x92\xf8\x8d\x86\n\xfc\xfc\xe6*\n6\xbd\xe8\x8d\xd8Zl\x19y|\x11\x1d\xd8\xb2\xe3\xa1^<\xf9W\x95M%Gg7\xce\x9a\xbe\xc0<#~5\x02\xa8D\xd3\xbc\xdb\xa8I8\x84\xa1)\x80\x12\x15\xb5\x0db\xd1\x1aV\xe3E\x94%\xa6S0\xd6M\xeeG\xdc\x86\xeb\xa8*\xe0\x87\xd4\xe7\x8cCy?r\xd3\x9a\xf1\x17(\xf4\xd7(#\xb8\n\x9dbo\xf9\xf9\n\xf0\xb6S\xe7\x9d\x8a\xe87\xb1\x8c\xc5\xf2\"\xbe\x8b_lwd\xc8\x9e\xec\xe7\x0b\xd3\xa5\x82Y`\xa5\x8d\xca\x98c\x845\x82\xc1/H\xd4_\xde\x96\xaf\xab\x12\xa5n\xce}\xc3*\xadpda\xb2\xfc\x0ed \x11\x89,\xce\n\x1c\xff\x16\xfe\x7f\xb6\x95\xa2b\xe9\xfd'\x83\xf4@\x1a}\x82\xf9jT\xfe:\xcdE\xd4NS\xdd\xa0\x0eM\xd0j\x01 _\xd7.z\xdf\xac\xb0;\x9bZ\xa5\xbf\xa7\x85F\x97\x0b\xe4\xf2\x00\xad>\xbf\xffx\x07qxw[$\xe0*\xd1@[%\x90\xf8\xaf2\xc2\xe0?Y\xfa\x04\x1dVMK4\x08S\x8a\xddz\xe8\x8c|F\xf0S\xc8\xa6k \xdfA6\x8d\x9b#lMy\xb1\x00I\x9eU\x9e\xf9\x0c\xadJEIDm\x85-n\x99\xa5\xf6\x14\x7f\x7f\xa6\xaeF\xe7\xb0\xa6l\xfaXV\xcd\x11 $\xcaLU\x89\xb2\x1b]L\xe4\xce\xfa=\xc3\x87\x8f\xd6\xec\x19\xc1\xc1\xb3k\xcd\x9e\x8e\x06\x9c<.\xcc\xe7y\x0fN\x8c#\xb3{\xbc\x07\x92U\xc6\x9d\x8c\xa3v\xf9=\x08/*3$\x937j=l< \xc6\xe1,\x8aJ\xb2\xf7\xb3\x95C\xb6\xfa\xe28\xcb\xbbX\xf8r\xcd\xe3\xa6WW\xfd\xeb\xa3^\xbb\xd7>\xea]\xf4\xbb\xbd~\xbb3\xe8\x0e\xcf\xfb\x83\xab\xf6\xe5\xe5\xc5\xd1\xc9\xf5\xd9\xe5\xa0\xdf\xb9n\xf7\xf6\x00xX\x8aE\x80\xca\x93M\xcb\xfe\x9a\x11_\xb6O\xfa\x9d\xa3\x93\xcba\xe7h8<\x1av\x86\xdda\xff\xfa\xbaw\xde>\x1bv\xda\xc7\xd7\x9d\xeb\xee\xc5\xe5U\xfb\xf2\xe8\xf8\xec\xe4\xf8\xe2\xaa=\xe8\xf5\xae\xba\x9d\xe3\x8b\xf3\xeb\xa3\xf3\xdep\xd0\x1f\x94kP\xe6q\xc0\xb8\xdb\xa3\xc1I\xf8\xe5Z\x05\xcf>\xa3\x15[ \xa0\xa3\x06(\xac!\xa4\xcc;(\"\x8c\xde\x9f\x944Wi\xd9\xcd\x1d\xe6\xcb\xbb\xb0\xaa\xa8\x06G\xfd\x9e\x8a)m\xaeA\x81\x07\x02\xb5\n\x91\x89'\xba\x83V\x102\"SH\xda\xc3\x92U\x166\x91L\x8c\x0c\x9d\x96\x141?z\xe4\xb1\x11\x90\x0b-4\x92\x8d\x1a\x81*\xd9cuH\xf1\xe0dU\xa0\xa3\xc8\xe5\xf2\xe5V\xe2\x85P\xfd\x036 ]\xa8\xcc\x1a\x87\xe5\x02\x9a&\xfd\xdf2+\x12\xc4 \xcay\xadJ\xbagA\xad\xec\xe64@w\x1b\xe6\xe6b\xae\xd6\xdb\x1d\xe4\x94G\x81\x0c[\x04r\xdfk6Q\x0dtA?\xf2\x13\x0b\xcd\xed\xd5\xef\x177\xbf]\xb6\xbb\x13vy\xe7\xc1\x93[>\xfe\xc0V\xe7\x9d\xc5\xf1\xf8\xe9\xe1\xb6\xdf\xff\xc3\xef\x1c\x9d<\xff6\xbe6\xfeX\xf6~\xbc\xb8^\x9d\xddX\xa8\xff\xc7\xbf\xee&\xefo\xfc\xf9\xf3\xf9\x9f\x83\xe1\xed\xea\xe9\x1d{\xba<\xb9\xef\xdc,\xf0\x95\xfb#\xfe}<\xf8xor\xdb\xb5\xfe\xf3\xb3\xd2\xab\xeb\x8fG\xa9\x00\x05\x14\xcd\x11\x94\x16d\x05H\xe6\xbb\x92\xa9\x82\xcc\xfbM\xc4D\x9e\x83 ?\x94\x0f$\xdf#\xc3\xed\xf6\x07\xb3Nv3^&V\x8a>\x15\xfb9\x9b?\xb7{\x1f\xa7\xfc\xfd/\xd3\x93\xb3\x8b\x8b\x8f\xcf\xf6\xcd |\xa0\xec\xed\xaa\x8dg\xd7\xff~\x7f\xf3\xf1\xddoG\x8f\xefo=\xca\xde\xa9=CCX\xa7\x9c\xa5)\xedZ9u\xad\xe2b\xe8\xc9G\xc4\xa8-\x13\x12\xcb\xb9M\x8d\xd9\xcdee\xad\xaf\x19\xf9\xba\xd0\xe393UI\xd63\x96\x14\x14\x19F\xa0\xce\xa9\xad|\x9d\x1e)X7ZA\x88w\x08\x9a\xa8z .\xea}#\x9cK\x0d\x8b\xc2!\x19\x8bN\xfd\xf1~7\"g\xad\xb8&r\x18\xe9G\x00\xcb\xfblu\xdb\x9d\xe3\xfdNw\xff\xa8\xfd\xd0\xee\x9f\xf6\x8fN\xdb\xc3\x83\xee\xc9\xf1\x8f\xed\xcei\x12M\x10\xdf\x19i\x1cJ\xd1@\":\xdb\x90q\xf9\xeac\x8a\n\xfa\xa5i)iQ\x8f\xd2\xb3\xd7\xe8\xf3\xa8\xafv*\xf6&\xf0QMq\x0c\xb2\xdd\xba0\xc9\xc6\xa4\xba\x90\x04-\xf9\xa89\xb8A C\x84\xf9\xb5\x01\xa1\xeb\xd6\x05\x114\x95\xe1o\xed\xee\xe2WCk\xc2\xc5k\xa2\xb9}\xd0U\xf6?\xcf\x91\xc7\xb0z\xf1_\x0d\xdb\"$\xb6\xae\xbd\xec\xa8\xc6\x05\xban]\xf8vdd*\x9b\x97\xa9b\x8d@\xa9ZI\xbb\x15\xabV\xed\xc8P3\xfa\x88\xab\x9bcR\xf4\xb59\xb7R\xf6\x05T\xb41\x12'\x92}o\x92\xdf\x14\xc6/e\x11\x8cb:\x8a\xb7\xfa\xaf 5\x12\x0c\x98\x98H\xb3>\xbc\x06\xbe0j\x90\x9f\xac\xfbI>\x9b`\xf5\xa8O4\x0b\xcb\x9b!\x0d|\x1e\xe3\xd0q7B\\\xc9\x19f\xf0\x16\xf6\xa7\x89D\xe4'\xee\xaf\x9b\xfbQ/\xcc\xf2SU\xa4\xe5\xa7 \x19\x90\x9f\xca\x049\xf6\x1f.\x8e{\xbf\xd93\xf2\xf4\x9f?\xae\x16\xd6\xf1G2\xb8=\xf9\xd59\xbe\xf6\xffl_\xfd\xda\x1b?\xce\xfd\xc7\x81\xb7x\xd7q\x1e~\xff\xc5\xfb\xe0\xdf\xde\xfe9?;{z\x18~|\xfc\x97u\xd7\xfepv\xf8p\xe9\x0e\xfc\xc3a\xf7\xec\xc9\xfbs\xf2\xef_\xee\xdd\xf3\xdf~\xfe9\x0e\xa9\xea\x15\x97$y\x1c\x94\xaf\xddW2\x15Y\x8b jXM\xb0\x91\xa9\xc9\xb8\x94b\x90\x96\\\xf5\x08\xf7Y\xc6\xe7\n?(\xfb\x82*\xd0\xa9\xc4\xb2h\xbb\xceVW\xa3ag\xb7#U\xb2\xf1\xa5i\xb0\xf6\xba\x90\xca\xf3Jm\xf5\xdel@\x85DNE\xa0\xdb\xe8)\x9az\xb8\xe1\xb3\xf2d'^\xf5\xaaq+\xac\xa7[C8\xf5\x06\xcb\xe9\x94\xf7=\xe7i\x8e\xc8\xa0{Bf\xf6\xd2\xf6\x9fW\xf3\x93\xe7\xe1\xe3\xd3\xa3\xe1\x18\x89L\xa7\xea\xe5\xf7\"-V\xcf\xff\xbeG\xab1dH\xac\xba\x03N\xe3\x87\xea\x00\xd4\xbcj\xb9\xb6\xba\xa1\x8e\xf7\x1e\x11\x0e\xe6\x18\x82\x0b1p\xf0\x91\xae\xa0\x85<\xf0\xff\xff\xdf\xff\xfd?q\x84[3\x7fjI\\\xfb\xef\xfcq\x1c\xeb\x16d\xd2k\x10\xc5\xb6>\x9f=\xaf\x81\x8c+\x08\xa9\xaa\xd3\x1a\xa0t\xe9\xd6\x82l\x04\xcdG\x9fq\x07\xd5\xa8\xfew\x0e\xe2\xbb='\x08mEG\xd4\xda\x15\xc3\x8eoC\x9e\xa3\xc4\x98R\x1bA\x92\x1fP\xfaE\xdb\x94\xa0]1\x8e\x9d@\x8c,\x18\x1d U\xaf\x9f\xff\xde\x80\x84P\x0e\xc6\xe2\x04\xb1 0 \x92\x9dG\x9f\x84\xaf'b>\x8d%qD\x89\xbd\xfaa\x0f\x80\x87\xb8\xa6\x13\x1b\xb3\xca\x9a\xb6\x99\x91\xcc\x95\xb4\xca\x19\x15\xaf8\x05 \x9c\xeb\x8f;\xcf\xc6\xa3\xe9#\xf7\xa9=\xf7\xbb\xcf\xd6\xcc\x9a\xf5\x86h\x02\xdb\xe4i\xf1LLH\x9e\xfaN\xcf8v\xe1\x91\xdf\x83\xees\xcf\xeazC\x8b\xb9O\xd6\xc0\x1a\x1a\xech64\xfcI\xd8ItA\x1a]\xd4\x10\xf5\x8e\"yq\xca\xe5z\x98z\x98W\x9eS\x8cE}_\xb02\xf9\xdd\x10@\xa3\xea\xe9U\xf4\xcc\x83\xab\x9a1\xa9bV\xd6.\xee2\x1d\xc2\x95\xb5\x94\x17\x0d\x97\xb6\x9d`\x12\xa0\x84\xb6\xbd\x1ae\x17\x8b\xf4\xd5\xf5\xfc\xfd\xb8\xcc\x1f;\x98\x8f\xd6\xd6pd\x81$w\x91\xeav\x94=\x94$\xc6\xa1\xb7f(\xd1C\x80\xdb`\xb6\x86\xee%\x82|\xa9N\xbdB\xc7\xfa\xc5\xd4M)Uu:\x9a\x17\xbb\xd6\x951\x14\xe1\xa8<\xc9U\xde\xf0\x17;\xb9\x83\xfc=\x88\xe1\xeb\x12\x1b\xe1 \xd5\xa3\x00=x\xf2\xeaEcD\x1fi\xe4\xa9*\x10-\xf3\xccD\x99\x11X\xc3\xe5\xeck\x13\x99&\xf5=\x13\x0dO\x1en\x18\xc7'\xb5B\xd7\x1f\xbf\n_\xf5\x08\xb1\x9d\xdf4\x95\x0e&\xf4\x167\xe3\x12\xc4\x03\x8akT/\x8c\xefGl\n\xbd5\nR\xe2@*\xa5\x98\x0e%xVq\xcd\x06\x9b\x88p\x9c\xbd^\xb7\xa0\xf1\x02\x8d\x19\xe6\xd5\x96q\x182\xfc\xc0}\x8f\xc43\xed\x86vM3\x07d\"\x0e\xb1\xcd\xd6\xb6\x1dSb\x8e\xf4\x0b\x13\xeb\xe3i\x01\x8c \xf7\xe0\x88/\xe5\xc2}^\xf5\xd2\x1c\xd6\xac+\xf8$\xc0\x13x\xa8\xa6\xe3H0\xacu\xb4\xa90gx\xdc\xdeow\xf6\xdb\x9d\x87v\xfbT\xfc\xff\x9f\x89\x8eE\xc7!\x1b \x8e\x07+2\xb7\xb0\x10\xe6\xc0\xe5h;X\xe49\x95- \xf3\xc5\xfb\xf3\x19\x1aWDTD\xeb$q\xaflE\x13\x0b\x903\xa3\x9a\x81\x94\x14O4\xad+\xd8\x94\xf0Z\xd95\xb6;\x8a*~\x8fD3\x99h\xad\xed\x7f\xbb\x9c,\"\xdc\xc3\xdb\xc9-\xe3i^I\x9c\xa9\xa9_\xa9\xfdT\x98\xb3\xc0\n\xedQ\x8e\xd2U\xb8\xa1icxH\x1e\x9d\xaa`_\x1cL\xca\x8d\x88\x86\xa1\x95'\xb6Kf\xbe0\xd1\xd2V\xbd\x88jI\xab\x0f\xc8|9z1\xcf\xa8 a2^ b\x8b*\xa3R\xa4\x95\xa1P\xa01\xd5\xeb\xe8\xb5Xe\xd0\xc0\"\x8b\xe6\xe5\x1c\x03;\x10*i^\x03j\x176\xcb]\xacS\x99\x0c[\x8a\xae\x19\xb2'\xe2\xbc\xe4h\x8b\xf5\xe9T:.69\x16\x85\x17\x9b`\xbf\xf3\xc766\xde\xa3\xea\xa2#\x9a\x94q\xac|{\xf9=\xb6\x08&V-6\xc92D\x05S,\x16AGt2a\xa8\xbc\xa1\xcc>F>\xe18W\xe2\xcf\x18w\xc6\x909\nO\xb6\x16\xc4\xab1\xc4\x1d\xf4\xa0s\xa1\x1c\xf2\xad29\x7f\xcc\\X\xa3\xc2\xcc8\x9ca\x12\xef\x8a\xac\x91\xcd\xb5n\xe12\x96a\xa6\x14\x9c\xea\xe0h\x95\xb19\x9e\xa9<\xceV\x99\x08[^k\xf9\xaf\x00\x00\x00\xff\xffPK\x07\x08\xa7j\"\x13n \x00\x00}\x0d\x01\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xd4`4t\xc7\x01\x00\x00\xbd\x01\x00\x00\x11\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00favicon-16x16.pngUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(6B\xc8\xd7\x7f\x04\x00\x00u\x04\x00\x00\x11\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x0f\x02\x00\x00favicon-32x32.pngUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xb9\xb1\xf1mT\x02\x00\x008\x05\x00\x00\n\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd6\x06\x00\x00index.htmlUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(]\x12r 9\x03\x00\x00T \x00\x00\x14\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81k \x00\x00oauth2-redirect.htmlUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(-\xe3\xb5\x97=9\x05\x00\xf7\x0c\x1b\x00\x14\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xef\x0c\x00\x00swagger-ui-bundle.jsUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(v\xf2\x8aA\x86\xba\x01\x00\xc5\x87\x08\x00\x1f\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81wF\x05\x00swagger-ui-standalone-preset.jsUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(_;\x94/\xe8Y\x00\x00\xa8X\x02\x00\x0e\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81S\x01\x07\x00swagger-ui.cssUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xa7j\"\x13n \x00\x00}\x0d\x01\x00\x0c\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x80[\x07\x00swagger.yamlUT\x05\x00\x01\x80Cm8PK\x05\x06\x00\x00\x00\x00\x08\x00\x08\x00E\x02\x00\x001|\x07\x00\x00\x00" + data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00 \x00favicon-16x16.pngUT\x05\x00\x01\x80Cm8\x00\xbd\x01B\xfe\x89PNG\x0d\n\x1a\n\x00\x00\x00\x0dIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x01\x84IDATx\x01\x95S\x03Luq\x1c\xfd\x8c\xf1\xc3\xec0\xa7)\xcda\xb6k6\xb2\x9b\xf9\xb2k\xc85/\xdb\x8dqx\xc6\x94m\xcc{\xef\x7fO\xff\xf3l\xdc\xed\xf2\xe0\xfe\xf8\xc9\xffP\x14\x11/\x14[\xa3P\xc4\xa1\xbc?\xf1t>7\x12s\x13\x03\x85\xca7IR a\xb5j\x8f\xa71\xbe]\x88\xf6\xb9L\xf0\x1c\x93\xcf\xda\xe3)\x10\x93f\x8d\xe4\x06\x13\xcf\xde<\x9b\xd14\x95\x8a\x92\x81OA\xcfF\x89\xdd<\x9b M\xe6}L\xe4\x07\x15\xc5\xf5\xe3\xffI\x0c{\xd6\x8d\xffs\x994\xbasfh\xae?\xafk\x1aprw\x10 <\xb9\xdb\xc7\x86\xa6\xd1\x19I\n\xa8\xb1\xd7\x84y3g\x171T$\xb5c\x7fq\xfbbq\xbfk\x8e'\x1dQ\xb0\xc2,\x92\x0bx|;F\xe5\xf0\xef\x00\x83\xf2\xa1\x1fx|?q\xbd\xcb\xc2\x16\x80ZF\xf0\xc4J\xf3\xe3\xe4n1\xcc\x17k`:}\xcby\xe8\x98\xcbB\xc7|6z\x97r\xd14\x9d\x06\xd3\xf9\x8a\xe4\x94\x90\x8b\xb6\xd9\x0cP\xebc@\xd0|\xbe*\xc94\xc8\xa7\x98'\xcdh\x00\xe3\xd92\xa6vK}\x0cB\xa4\xf0+D\n\xc7\x81)\xb0\x10\x9a\xe3\xa9\xd8\x8bx\xe4(\xa2\xbb\x8dl\x0d\x01\xb6\x8a-\xf378\xbe\xdd\xc7\xa6\xb6\xc9\xd9\xc6d\xd8\\m\xf4\x0c\x92 uQ\x0e\xd2\xf5\xb3\xd1\xf1w\xdfQ\x16\xb34a$\xa1\xc4\xc4(V\xbcF\xd9\xdf\xa4\x91\xe9\xb0&,\x12+\xcd\x93\xcf\x1c\x1cb\xdc\xca\x00qt\xeb\xcc-\x14\x89\xfe\xfc\x0fm2j\x88\xec\xccs\x18\x00\x00\x00\x00IEND\xaeB`\x82\x01\x00\x00\xff\xffPK\x07\x08\xd4`4t\xc7\x01\x00\x00\xbd\x01\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00 \x00favicon-32x32.pngUT\x05\x00\x01\x80Cm8\x00u\x04\x8a\xfb\x89PNG\x0d\n\x1a\n\x00\x00\x00\x0dIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\x00\x00\x04|ID\xc4\xcf\xd0@\x04&%\xad\x1e\x16\x0f\xf7\x8d\x97AR\xfa\xca\xe7l\x87\x05\xf8\xd2\xfb\x0c\x84\x1d\x0dLVY\xdc/ju\x13\x1a\x88\xd2\xa0\xaaa\x82|nzp_\xf4\x03\xc8 \xd4;^\x8a9}\xeeu\x9a\x91 `\x04\x14s\xec\xe1\x0c\xc6]\xa3\x05``\xd1w\x12*~ \x00\xf3\xae\xd3\xa0\x9cb\x82\xa2bx(\xb3n\x1fqx\xd2\xf2\xda4\x1d\x8a}\x1ck\xd4>\x9cI+\xeb\xb3\xf4k\xc8u`L\x93\xf3]4\xb5\xd0\xc3\xe33\xd9\xee\xd7\xf2\xd9\x19\xea\x18\xc9\xc1Y:\x18\xfb(-\xadN\x82\x06e\xd5\x1f0\xa2\x1dV\xf8\xbe0\xc1\x985\x01\xf8\xd2~\\\xa6\xa5\xb5)&\xf6\x98V\x80l\xe4\x03\xf8\x03\x04\x00s\x9a^\xec\x85\x00\xf4+\x0b\x00\xe1:G\xf2p\x96\x0e\xc4,\xe46\x1e5\xbbP\xdd\x15J\x80}\xce\xa4\xe2\xc8{m\xa4\xe2\xc3\xc2\x01\x07\xc0\xdb\xa4\x18-\xa1\x931\xba\x10S\xfa%\xb6P`\x10\x19v\x99#|Gg\x9b \x10W\xf6\x8dI1\xba\x92\xd66\x17E\x12\xfa\xd9\xa8\xf3UTe\n\x1b\x95\x9d\x81f\xe5\x18\xa5umc\x81\x86\xa6\xeb\xec \x804\xcbg\x17\xa19\xfa\xc6\xf7<\xa3\xbd\xf2\x0e\x7f\x02\x80\x97Y\xc7\xac\x184$h\xa3v\xba! \xcc{\xcd\xb4!\xb1\xd8\x92%h\xe3\x93\xdc\xd3_\xda1\xe6\xaei\xcf\x83\xa6p\xbc$\xf0\xb2\xda\x94\xa2q\x14B@\x13\xdb\xff\xf3\xd7\x0d\xfaA\xb9\xc5n{\x8e\xd6Y\x08\x01u\xc1'~\x16\x8e\xe9\x04\xa2\xfbA+\xc74\x0c\x98\xab\xd7:\xfc0\xd1v\xaf$\xa2#\xb7\xf1\x08\xfdm!OXh8\x10j|g\xd1\xe0a\xb2\x99\x04\x9a[y\x9a\xbdk\xf24C$\xa0\x9e#\x9f\xa3\xa8\x001\xc6\x1a\"\xc0\xe4i\xa6\xcc0\xf3\xf7\xb7\xf5XE\xb8\xe0\xa1\xc9\xc2\x0c\x90\x83\x80$\x838\xdf\xd6\xe3\xd4\x82FNG\x0f\x876\x8a\xbf1\xa8d(\xa7@\x8cQX\x90\xdb\x19\x9f\xc5YG\xe9\x9e\x00\xa5y3]\x9aJ\xe1\"\x00\x00\x00\x00IEND\xaeB`\x82\x01\x00\x00\xff\xffPK\x07\x086B\xc8\xd7\x7f\x04\x00\x00u\x04\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00 \x00index.htmlUT\x05\x00\x01\x80Cm8\x9cT]k\xdc:\x10}\xdf_1Q\x1e\x92\\\"\xfb&\x81p\xf1\xb5\xfd\x90\xa6\xa5\x81\x94\x06\x92}(\xa5\x14\xd9\x1a{\xa7\x91\xa5E\x92\xf7#!\xff\xbdX\xf6\xae\xb7\xdd\x90BYX\x8f\xe7\x9c9\x1a\x1d\x8d\x9c\x1ep\x0e\x1f\x1f>\xddBe,8/<\x95 \xc9yKE\xeb\xc9h(Z-\x15B\xd1\x92\x92\xc0y>I\x0f\xae?\xbf{\xf8r\xf7\x1ef\xbeQ\xf9$\xed\x1e\xa0\x84\xae3\x86\x9a\xe5\x13\x80t\x86Bv\x01@\xda\xa0\x17P\xce\x84u\xe836}\xf8\xc0\xffc\x03\xe4\xc9+\xcc\xef\x97\xa2\xae\xd1\xc2\xf4&\x8d\xfbL\x8f*\xd2\x8f`Qe\xcc\xf9\xb5B7C\xf4\x0c\xfcz\x8e\x19\xf3\xb8\xf2q\xe9\x1c\x83\x99\xc5*c\xae\xd7\xe0-E!\xbb'A\xa5\xd1\x9bbjD\x8d\xf1\\\xd7\x9b\xeaJ,:\x9c_\x9c\xaf.\xce\xa3\x008zB\x97\xb1\x90a\x10\xff\x9d\xde\xd9\xe5\xea\xec\xf2\x17\xbd\x90\x19\xf5\xc2\xc6\xfa\x18\x82\x9bC\xf8<<\x01\n\xb3\xe2\x8e\x9eH\xd7 \x14\xc6J\xb4\xbc0\xab\xff\xb7\xb8Y\xa0\xad\x94Y&\xc0\x1b\xf3\xc4]i\x8dR\x85\xb0\x8e/\xd0z*\x85\xda\xe7\xf2u\x02=q\x83\xbdL\x86\xe0\x9f\xd3M\x90\x14X\x19\x8b\xe3\xbb\xa8<\xda7\xfb#=CK~O\xb40r\xbdW\xd8\x08[\x93N\xfe\x1d\xdb+D\xf9X[\xd3j\x99\xc0a%\xba\xdf(\xd5\xfd\xa7\xf1\xd6\xaf4\xee'\xac\x0b;\xf9\xc1OI\x0b \xb9;\x0e,OcI\x8b|2\x18^Z\x9a{p\xb6\xdc%\xf1~\xc6\xa3\x1f\x8e\xe5\xdd*\x81\x94\xbfY\xe1\xbc\xd0R(\xa3\x91\xcf-:\xf4o\x14\xf7/K\xd2\xd2,#\xa3\x95\x11\x122\xa8Z]v\x17\xec\xf8\x04\x9e7N\xc51\\\x85{&\xc0\xad\x9d\xc7f\xc8\x97F;\x0f-A\x06\xc3m\x99\xde\\\x85\x9e\x8fGG[\xab\x12`Q\xeb\x8c\xd8v\xfb_}K7\xd3F\xfe]\xb1\xa1\x82h%q{\x8b\x9b6\x88/\xc4i }\xc07u~}\xe5\xad\xfd\xc9\x98\xe7q\xd8_}o\xf1\x92%\x9dx\x15\x9f\xd3yO\xbdX]\x1aA\xc9>t\xd6o\x93\xd3\x92\xf2\x04l\xc5\x8d\x92jz\xc1jN\xd6\xf2\xa9\x87\xfa\xb5]\x05\xcc\xf9\x1acB\xa9,\x9f\xd0\x08\x05\xb7\x962\xec\xdb\xb6\xe2\x16b\xc6\xd5\x942H\x05KfI\x06\x7f\x9c\x98\xa8\xc0\xd5\x9c\xa2\x0c\x13\xa3\xe7U\x8e\xb55;'Nk\xe6\xd0\x9d;\xd4%^\x14\xbd\xd5\xf7\x92QN\x8e.\x1c`\x079m\xe3\x9e\x8a\xfe\xed\xa2\xad\xe0y>\xe6\xe23\xdc\xf8u\xa7=\xa3\xf6\xa1\x98\xb4\x17g\xa9\xf4\x1dA\xa8Z\xe4\xf6\x88_\xfc)\xf8\xd5N\xcf,\xea\xb4\xabS\xf2\xd2\xe0v\x10\x90\x82\xbd\xb3\xe1\xc1g\xc8>\x120\x0c{\x1d\xbd\x1c\xd1\x7fd\xb4\xbf\x82|\xf7\x9f\xd0\xa7\x1e\x82\xc5`H\xc0\x94F3p0$H.\x0f]v3\xaa\x9b\x1c\x83EW}\xba4\x12O`_\xb5!H5\xd1 \x9a\x0c\xaa\xcd\x04\x8cE\xe7M:\xe1\x08\xfe\xefQ\xab\x02\xfe\xb7A\xeb\xb6k\xbb\x05{\xef\x8e\xde\x84\xcb\x9c\xb2\x8f\x04\xd7U\xf9\x9aQ:\xbe\xf51\xf1\x1a\xaaW\x97uR\xdd\xe7\xf59\x974\xb7\xfc5s\xd0\xc4P\xdf\xdd\"\xd7\x96\xc2\xdab7x\xb8;\xfc\x01\xfa'\x00\x00\xff\xffPK\x07\x08]\x12r 9\x03\x00\x00T \x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00 \x00swagger-ui-bundle.jsUT\x05\x00\x01\x80Cm8\xec\xfdyw\xdb6\xf68\x8c\xff\xffy\x15\xd7\xfa\xf6\x9b!kZ\xb1\x9d\xa5\xad\x13\xc5\x93\xc5m\xb3g\xe2\xa4\xcb\xa8\x1a\x1fZ\x82,6\x14\xa8\x90\x90m\xb5\xf2\xef\xb5\xff\x0e.\x00\x12$\x01\x10r\xdc\x99\xf9<\xcf\xc3s\xdaX\\\xb0\\\\\\\xdc\xfdn\xc1tI\xc7,\xc9h@\"`!\xfc\xf9?\x00\x00\xbd\xec\xf4w2f=\x18\x0c\x80\xad\x16$\x9b\x02\xb9\\d9+\xe0\xd6-\xd3\xd3y6Y\xa6\x04\x0e\xe5\x1f}\xf5\xf6\x00X\x10\xc2\x01\xf4T7\xfaG\x132M(\xe1-\x8a\xbf\xfa\xf1|\x02\x87\xf2G0\x1c\xe1\x80\x0e\\\x839T\x7f\xf5\x8f/\xe2\xb33\x92\x7f|\xfedI'));&\xe6'\xffs\x15\xb0YRD\xd5\xf4\xd5\xd4s\xc2\x969\xd5\xc0\xa2\x1e\xf0\xeb<\xce\x81\xc1\x00\xfe\xbcz\xf0?\xe5M\xf5*\xd0 \xd7_\xe6W2\x85\x80\x0d\xf3Q\xa8\xda\xe5?\x14t\x1e\xd4^\xe5mg|t\xc3|\xc4\xbb\xa8=\xc4\xb6\x0e \x8fZw\xd3\x03\xd8\xdak\xdf\x96]\x1c\xc0\x9fW\xb5gW\xf5N\xe5\xa8\x08\x1f\xd58N\xd3 S\x83\x8b \x8b@\xfbEC\xfe3\x85\x01l\xedj\x0f\xca\xd6\xaand\x9b\xb4?\x87\x01\x90\x08h\x7f\xcc\xa7\xc5\xff\x98\xc0\xa0\x8ep\x11\xb4@F\xfb\x99\xc4\xc5\xf5\x1a\xde\xe2\xd2\xf7\x05J\xbc\xcb\xb3\x05\xc9\xd9J~\xd9\x86\xd08\xa3\xd3\xe4l\x99\xc7\xa7)\xb1\x80\x85.\xe7D=\xdfm??#\xec\x00\xf2:\xc4\xc2j\x8e|\x0e\xb46\x87\xe6\xe8\x15\x86 Z\x93\xfe\xc9 )^\xab\xbd\xd1\xc25\xfdR+\xc1\xe7\x1a/SV\x1f\x03\x1c\xf8}\xed\xb1\xd6\xb4? X\x04\xbd\xb8\xc7\x81\x1c\x01\xabO/k.Q\xb3;\xd9\x8c\\\x99E\x9e\xb1\x8c\xef\xca\xfe,.\xde^P\xb5F\x02\x9b\xf0\xfbz\xfb\x0b\x18@\xef\xf6$)X/\x02\x1a\xd0>'\x12w\xef\xde\x13\xaf]\x05\xc3\x06~P\xbd\xff\xde\xb2 P\xb0<\x19\xb3^59\x9d\xdc\xd0\xe0\x1b\xd5T\xd4D\xb5ZS\xf5\x8f\xbe\xbdw'\x0c\xbc\xbe3\x0f\x81\xe9+-\xb6\x08S+\xd9\x05PN#\xb6\x02\x02 -XL\xc7\x9c\xbe\xb10\x046\xcb\xb3\x0b\xa0\xe4\x02>\xac\x16\xe4(\xcf\xb3<\xe8=\x8d)\xcd\x18p\xe0B\x0c\xe34.\n\x88\x0b\x88\xcb\x1ezacG\xde\xcct\xaaG\x1c\xc1\xf3\x08)\x15\x0d\xf6\xef\xef\x87\xf5M\x94\xc0\x00\x82\x1c\x06\x90\x85|\x07\xe4\xf5\x1d\x90\xc3\x81\x01y%\x9cZ\x1bO\x1f\x8f\x01\x96M8\x96t\x98\x18\xc1\x8c\xafd9\x04|\x06|\x13\xef>\x00\n\x0f\x81\xf5SB\xcf\xd8\xec\x01\xd0\xedm\xd3G\xa0f\x8d\xc4\x99\x8e\x1e\x18\xdf\xc8\xfb\x15m\x81A\xfd\xe7z\xcd\x89\x11\xe4}\x9d@I4\xe9\x9d\xc7\xe9\x92\xf4 \xa1\x90s\x88\x05y\xff\"OX\xf9F\x18A\xb0\x1bA\xa2 \x10\xf2\xc9\xe5\xfdOd\xc5igk(\x0djo\xda\xb9%\x009.\x18\x08\xb0\xf6*E*\x16h\xdb\\\x1c\x04\xb9\xbc\xcf\xbf\xd6)H\xbd\xcf+\xbf\x1d\xa5\xef\xc4\xfaHJ\xc4\xa0\xc17\xf7\xef70\xadB,N\xca\xff\x9dX\x7f\xf7\xde\x7f\x0e\xe9\xad\x04\x84\xe8\x14\xe3=\x99\x92\x9c\xd0\xb1\"\x1b\x9c\xd7\x81Y\\\xd0\xbf18%\x84BB\x13\x96\xc4iR\x90 \xec@\xb1\\\x90<\x08kop\x12C&\xbd\xd0x\x86l1\x8e\xd3%c\xb65\x18@p\x9e%\x13\xd8\x85\x01\xe7\xd2\xe0\x10zK*N\xedI\x0f\x0e\x9a(\xcc\xe9\x1bg$+\xaep\xab\xe4\xed\xf8\xc7\x04\x0e\xf4s\xe9\xaf[R\x18@\x1cp\xec\xfa6l\xaci&\x1f\xdd\xb9\xfb]\xf3Q\"\x1f\xdd\xbd\x17\x86&>0n\xb3\x05\xea|6p\x05\xc4\x8d\x1e\xc4\xb6\xb9\xae\x87'\x16\x90\xdf\xba\x05t\x99\xa6\xb8\x92\xccr\xf6\x1cs,\xe1\x8ceN\x8a\x82\xcfs\xbe,\x18\x90\x84\xcdH\x0e\xa7D4\x90\xe5\xdaa\x14\x01?\xacz\xb0\xbd1v4\xd0\x8eT\x04\x88o5d@\xab\xd7\xf9\xe8k$\xca\xc8\x19\x16,_\x8eY\x96\x9b\xa0\x0d\x88\x0f\xe9\x92\x1c\x00i3\x85\xd0d\x1c\x0d\x8c%\xbf\x14\xdd6\xb3\x96\xd0fPw[/5\xc87'\xae\xf2PPk|\x88\xd3\xcfk\xc7\x01\x13\x92\xce\xc9 \xc2\xe0\xe4\x84\x1fT\x1b\xf2\x01\xb8\x1b*\xa0\xe7\xae\x83\xd6\xbc\xd5T+|\x85\x1e\xe7y\xbc\xd2x\xc3\"M\xc6D\xdb*\xa0o\x17f=\xae\xc5\xdc\xeb\x8b/\xf9\xceqNbV;\x99\xc20\xd2\xf1\xa4\xaf-9\xe7\xc7\x1b\xdb\xc8<\x14\x03C\x0f\xd5\xee\xc5}-6\xec\x8b\x80\x84^-\xe6\xce\x16\x97U\x8b\xbf\xfa\xb6\x989[,\xaa\x16_\xfa\xb6\x98t\xcf\xfa\xd6-\xd8J\xab\xa6\x7f\xf0m\xda@\n\xb5\xa6\xb7\x82-\xc1\x1c\x91\xe1t\xe4\xd7\xe0\xd2\xb7\xc1\x85g\x83\x85o\x83\x13\xcf\x06\xd3\xee\x15_\xaf\xb1[\xaf\xe6\xc6\xbe\xe3\x9b\xb5\xc6\xa7\xffbA.X7\x16d\xea\x8fD\xfcA\xfbI\xf1\x9c\x95\x9ck,\xee\xbc$+\xc2\xc5\xf5\xa5|\x81N\xc8%\xde(\xc4\x8d\xc7E\x91\x8d\x93\x98%\xe7\xfc\xa3T\xdc|\x9bOH\x8eo\x8d\xf9\x0d\xd5\x06\xef\xba_\xb5\xc0\x07\xd0?&\xfc\xbcJ\xda\xf4c\xca\x05\xc4\xbf\xff\xfd\xe4\xe4\xf9\xeb\xd7\x1f?<~\xf2\xea\xe8\xe4\xf9\x87\xa3\xf7\xf8\xc7\xc9\xdf\xff\xdekS\xd6E\xfb\x8b\x97G\xbf\x1e=\xb3\xbc>1t\xf0\xe6\xd9\xd1/\xd6\x0ff\xed\x0f\xde\xbe\x7fv\xf4\xde\xfa\xc19\x0c\xe0^\xfb\xf6\x1c\x06\xb0\x07\x0f\x1f\xc2\xb9A\xf1\x00\x03\x98\xc3\x0e\x18\x8e\x96\x15*\x9c\xda\xf7O\x8dZ\"\xa8\x8e\xb2\xad\xbd\xd6SC3'\xd7i\xc6F\xcb/\x9c\xd8J\xfa\xd8$g\xc4\xf6\"O\x92|dn\x91\xc8\xa3\xa1lp\xd7o;]\xf2\xd3\xcc\xf6\xf0\xd8q\x12q\xbee\xbd\x86\xdd\xb6\xf4W\x13*_\xc7l\xd6\x9f\xc7\x97\xfc\x90&R\xb2\x84\x1dT\xb4\xf0c\x88\xb3Tx8\x06\xa8O\x13Rh\x06\x0f\x81>\x80\x8c\x8b\x9f\xf90\x1b\xf1\xe3j\x98\xc160\x83\xac)A\x99{\xcd\xf6\xa9s94\x9e\x8c\xf4\x8b\xe4\x0f\x05S\xfcs\x80\x0cE\xc2\xe9\x02#\xc1cq\xba\xf2'^\x1d\x7f\xb2B\x12\x99P\xba\x9c\x9f\x92\xbc\xc6\x82\xba$o\x8a\xd0\x7f\xf4\xe8\x91 \xfc\xa0\x1a\xe5|&\x15\x1c,_\xa9\xbb\xfb\xdf\xdd\xfd\xee\xfe7\xfb\xdf\xdd\xc3\x19\xd2R\x05\xfb&~cn\x85/2m\xe3\xba\x0d|\x0c\x1e\xc2.\x1c\n o\x03\xab\xc9,\xe0\x00\xcec\x97\n\xaf\xc1\x14\xda\xdaxkb\xe2\x1aM\x05rm94\xe4Zs\xe8\x08\xa1\x1e\x1e\x0e`\x87\xe2\xc9^g\xce\x0d/3x\xc4\x01\xe85\xb0w\xd6\x95\x97\xa3z-G\xee\xb9a?\xf8\xb6\xc7\xfc\xda{\xed\x018}c\xc0!P\xce]\xcb\xc5\xd6\xf77\x83m \x9c\xf5n\x087\x9cC\x12\xef%\xa8di\x9d\xf4\xfa/\x8e\xdf\xcf9\x1dhS\xe6\xdf\xf9y\xd1\xbe\xfd\x06\x06\xb0\xdf\xbe\xfd\x9e\x9fR\x95tW\x19K\x8eW\xf3\xd3,\xe5\xeb(\xfe\xea\x8bM\x9d\x19\x8c \xcf\xc4I\xa7^0\x1cm\xaf`\x00\xef9\x8e<\xb3\x1d\x01\x1f\xcd4\x87\xcd\x92\xa2O\xc9%\xf3f\xc6?\xab\x95\xb2\xe8\xa8\x94\xc1\xa4Z(\xbe\x05\xf7j\xcb6\xe4\xdf;\xa8(\x1cB^\x9e!\x19\x1c \x91v\x9e\x86\x99Y\xb2\x9bd\xd4v\xe2z\xd2\xea\xef]T\xc19$\x81~\xcequJ\x9a\x96A\xfd\xe1\xe6>\xb7~\xf4ec\x9f\xb8\x19\x83\x866H\xb3\xf4!\xcexu\xf1\x93\xb9\x0be\x91\xe1C\xb5\"\x82\xd4!\x08\xa3\x85\xdf\x8c~tw'\x0e\xd3\xf7Hk\x87\xefG|\xcb\x90\xe1\xb3\x91a\x08\x0d\xb5\xcc@?\x13\xd5\xf0\xbcF\xf4\xb3\x07\x8c\xd5\xc9\xabCXp)^]\xbcpv\x81\x1a\xa0\xe6\x91\xa3\xb6cB\xd0 \xab\x84\xe8>\xcb\x8e\xc9g\xbc\xa5Z7\xb7\x0d\x1aP\x0b\"\xc5'\x93M\x18\x95X\xe4\x02\x181\xae4(M\xa9M\xbfut\xb9 cF&\x82A\x83,\x87DIE\xa27\xc8\xa6b\xcb\x15\x11\x7f\xfa \xa5\x1b\xf1\xe8\x00\xb5\\\xb6n\x8d\xab\xc8\xaf+_d\xfb\xf5\xcb\xe0\xdeg\x19\xcab\n\xe2r\x11\x96\xed\xb5 \xfdi\x9e\xcd\x8f(\xcbW\xe5\xcb\xc4w\x94/\xbfl\x94\x86\x81\x11} |\x9cR\x8aT\xb7\x96\xdec\xfb\xc19\xb6\xe0\xcb\x07\xa7F\x13\"4\x19\xdeo\x8cL\xff\xf5QSU\xb1\xec\x98\xe5 =s)\xdd\xb4\xc1\xf6\x86\xcf\xe5\x01=\xea\xd5{\x88\xe0c\xff\xe5\xd1\xaf\xc70\x80\xe7\xfc\xef\x9f\x1e\xbf\xfax\xc4\x7f\xfd\xce\x7f\x1d\xbd\xf9\xf0\xfe9\xfe|\x13\xd5\xfaOh\xc1Q\x1f\x06\xcdQe\xcb|Le\xf2\xd9\xb3M\xd3\xd8^\\\x7fQ\x11|''%\x00{|$\x7f\xf6\"\xe8]\xf5\x9cc\x1e\xc7\xe3\x19yO\x8a\x0e\xeb\xa8\xd6\xd5\x96\xe8\x0b?\xc4sOt-e\xbd\x8f\x14\x1fL\xf0\xfc\xd2\xdf\x1c\x88\x17+\xac\xef\xb3L\xc8\xb2a$\x1eI\xc1Q\xfbH\x9e-\xf2\x05\xd74\xca\xfe\xbb\xac\x18\xdaDR\"\xbdx\x04\xa3\xd8\xd2\x01\x98{\xc8\xf2\x0d\xba\x18wv\xc1\x82_#x\x11F\xf0km\xf1\x15\xbd\xf5\\\x133\xa6\xbf\x14-\xbf\xf4\xc7\xf4\x97\x0eL\x7fY\x1b`EI=\x9b6\x0d\xf1\xe5\x0d#\xfc\x90#\xfc\xa8\x8d\xf0/o\x18S\xf6\xbcz\xf8\"Liw\xc1\x82\x1f\xc4z\xfe\xe0\xbf\x9e?8\xd6\xf3\x87\x06\xe5b_\xb6\x96/\xfaI!Z\xc8\x08\xff\xa5\xb4\xb7\x1c\xbd\xa5\xba\x96\x8f_S\xe4\xbelko\xbf\x8a\xe0\x9f\x11\xfc\x12\xc1?\xdaJ\xd3\xe3\xa3\x7f\xa0\xc2\xd4&9\x12\xe2\x10\x1dOb\xe4\xca\xd0\xa3L'6\x1b\xb1\xaf\xcc\xd2\x83\xe2/\xa5q\xe9\x13Y\x15F\x1eR\x8cDr\x83\xd5PN\xf8\x07\xc2\xc7\xadF\x077\x19\x1auN>\xa9\xf4\xf3\x96\xf9\xa3\x80\xe1\xaf\xa0\xcb\xbb\xbb\x93\x86\xb3\xa8q\xef\xa9<\x0c\x86#\xaf\x8e2KG\xea,\xaa\x0c\x18\xff\xf04\xb0 7fm\xf0+\xdeZ\xf0\x95\xd4\xb5\x12\x12\x0cG\xa1_\xbbq\x07r\x08\xa3fR\x883\x0fy@\xd9\x05 \xdb\\\xf3\x93\xea\x8d\xdc\xfc\xc6\x1f\xd5\x1b\xd4\xfc\x86Q\xca9\xac\x84\x9cR\xf5d\x16*\xbfL\xd2\x19~\x8a\xe0|\x04\xfc\xb8O6\x92x6\x92Y\x97\x1d@/\xcc\xc2\xdc\x97OO\x08r74\x8b\xc2\x8d\xe4?7\xb0\xc5\x80\x1e\x06|(W\xd7k\x08)\xf1T\x97\x11\xc9\x9a\x99\x81\x9a\xd9D\xf0\xd2\xca\x91\xf0\x03\xa2\xb2l\xecE\x10\x0b3F\x0c\x0f\x07\x90<\x80\xd8\xeeF\x07r\x1cK\xde\xc6\x90r\xd1\nv \xe6\xb2\x95\xc5\xad\x0e\xd4b\x0b\xbd\x1e\x0b\x96\xc3\xbdQ\x84\x8a\xbb\xe5pw\xc4\xbf\x8c\x80\x84\xa5\xa6$\x86mh+\xe1\xa0%~\xa9K}\xd6zhU\xfb\x936\xab\x8c\x9et~Df\xfc\x17/\x93q\x85\xac\x90\x15+\xe7\x02\x0c\xc7\xc6\x8f\x81\x93\xa5P\x97r\xfe\xf0_X\x05\xfc\xedmx\x04 \x1c:\x1a\x07?u\xa7\xba\xacjOu]\xc1\x01|F\x07F.\xcaKL\x12\xe8L\x86{\x8d\x93\xa8\xfc\xa8}\xdb\x03M\xb2\xfc\x1ax2\xb5;\xb1*\xca\xa4y\x94\x0b_L\x8eR\x11XQ\x83\xe3M\xfd\x0c\xa3\xd5\xbe\x91\xba\xcf\x0c\x9bx\x19\xd0\xb0?\x8f\x17\xd5\xba\xbb\xda\x05m\xd2\x08Q\x0c\x1d\xa06\x10:Ts\x13b\x1d\xd2\xaf\xff\x81!\xa9-\xd0^t\xb4\xeaD\xd0\xeb\x99|\xcd\xf8\xd5\xeb5=\xf7\xf0;N\xd3\x17\xde*\xab\x85\xfbT1\xf0#/9\x1b\xc1\xa1\xb4 \\:\x7f\x95\x14\"\nfB\xc4\xf3_\xeb\xcf_\xc7\x0b\xa1\xbb\xf2\x1a\xce\xc4=\x1ce=\xae\xf9]\x0d\x14O\xdd\xd4\xaa\xe9\xaf\xf9Acf\xdf\x11\x1cwHe\xbe$\xb0%\xf5\xef\x0c-\xcc%Fm\xd9\x18%\xc1\x82j/\xeem\xa0\xa6\x97N\x08o\xa7V#\x06So\xb8\xb6f \xb8y\xf9f\x10\x868\xa1\x00=\x0f\xf4\xbb\x9bN\x10\xec\x93\xf4\xa7f[f\xc7Q\xd2'\x9f\x97qZ\xa0J\xde\xf4\x02\xd3^\xd8Ro\x07\xcc\x93#?\xf7Z\xf2\xee\xe5\x8d\x03\x11M\xa4\xd9\xb5+\x87\x07\xed&+o\xca\xc7\xda\xcd\xe6\xe7''\xb3\xb8\x98\xb5\x1a\xa8n\x97\xaf\xd4\x1e\xac\xd7B\x7f\xcco.\xe5\xb0\nu\xa3\x907\xc6\xea\xc6\x18=\xa5;\x90\xb2\xe9\xc1!\x0d\xd1\xf8\xdb \x1b\xe5Z\x81\x9e}\xe6\xb6\xf9H\\\xac\x06J\x88})#\x04\x1d\xe6\x8f>9'\xf9*\xe8T\xa8\xa8K\xb1B9\xda\x00\x83P\xec\x82Nv\"\xe3@\x98\x91 CNQ8/\x06\x94\xc3\x15o\xeeb\\\xa1\xed(\x00\xf4\xdf\x97\xfdq.\xc2c\x8f\xa8q\xda\x16\xa8\xe5gc\xee\xbc\xf1\xaaZ@\x0b\xcd\xd1\xd5\xbe\x88m\xda\x0d\xdbB\x90\xb4 \x0exg\x0d\x0f\xf9\xe6\xa5xK\xc7\x12\x10\xa9\x05\x81\x01$f\x08\x1b\xa17\x15\xc10\xc6/\x16 \xb6\x8frE*\xd1\xc7\x14<\xa8_\x1c\x9e\x9c\x13\xdd\xc2\xd8\xb4\x00\x9d\xa43\xfe{\x86<\x01\xe9\x9f\x11\xf4\x8a\\\x85\xfc \xbf\xab\xddB\x1cQ\x185\x95\x1ek\x06\x8a \x885V\xf1q\xaa\x11\x13\xbe\xa8\x0b/\xba7w\xd3\xbd-T4\xea\xf1bsM\x02\xe2\x1c\xbbj\xc0\x8c\x8fB\x9f\xa3\xbc\x1e\x1a\xfa\xa4\x86/\xcb\x1e\xdc\x86\xdd\xd2\x9fE\xfa\xbd\x84\x91zC}\xe8:\xd8\xfeY\x0e\xed\x9ff\xc4\xf9\xa7\xb4\x19tl5\x1b\xb4\xce:\xa0U\x8b\x8c\x11*\x02O_\xa1\x15q9\x0b\x99\x97b\xd5X\n\xad\x0d\xf3j\x9c\x91@\xbaZE\xa0\xe2\xfb\nF\x16\x10\xc3\xfb\x98\x9e\x118]\xc1n/\x8cpo\xe19\xb4\x1b\xd5W \x0d5\xe8[z\x1bv\xc3\x08i\xba\xf6\x02\xc5e\x94K\x18\x9f\x16\xe8z\xc8\xe0\xa1\xe4\xd8\xf8\xdb;T\x99pN\n\x16\xe75\xdd&\xa1\x13M\xb5y\x82C\xc3\xc1\xeaX\xa3\xa3\x07\xfe=&I\x1a\x04\x0cv8\x01\xbe\x0d\x94\x8bV!\x97\xcd7\xc3\x9d_JX\xfeb\xc6\x9d_\xbe\x0cwN\xcd\xbaD\x81/\x9aJ\xe9\xf1i\xc1\xf2x\xcc\x9a\x96 K\xb3'\xc4\xe5fz\xe1|z$\x9f\xea\x0f53\xd6\xf0\x1f#\x15`\x1a\x10\x12\xc1K\x8e\x19z\xdc\xc3\x19\xe9\x0c\x04\x82\x86\x15\x86\x93G\x94\x0f4M\xfb\xf0\x932g\x84\xa3\xb6gc\xa3\xcf\x8dL25\x7fY\xadG\xe9![S-U\x1e\xb2\x03\xc8\x85\x8b\xac\x15W\xa4\x8a\x88\x04t\xc80\xecn\x07=\xba\xb2\x11\n\x7f\xbc\xa3jgf\x1c\x15\xadT;\xf3\x9a\xac\x9fu\xc84Q\xe3\x14Z\x937\xbe\x95\x9956\x9bikJ \xaa7\xbd\\M\xa8/\xf4\xc3CbD\xf9Z\xdf\xb3\xb8p&\x02\x80\xa6\xa5S4\xdd\x08\x93o\xa9\x02\x1a\xbd|\xe9\xc6\x12\x9d\x8a\x9dU\x99\xaa\"\xc9V\xeb;-\x11;-\xe1;-{\x00\x89;\x16:\xe6\xdf\xe3bf\xb0\x03 \x1c@b\xd1\xf35vf<\x8a n\xee\xc6\xc4\xa8\xb4\xb5\n\xa3\x89\x17\xc8\xae\xb3=%\xb8\xac\xfbS\x03\xa1uw\xe6\x9d{8\xb9\x89=\xbc\xd9*(\xc8\xa1\xa65\xfb\xf7\xed\xf9\x98\xef\xf9\xd8o\x8fk\x8b8\x9cU\x87\x1c\x95\x87\x1c5\xee\x8b\xd2[\xc5c\xad\x91\xf7\x0dk\xbb\xb2&4iB\x86\x85{V\xd8\xf2SP7\xcb\x86v\x94\xb1\xe8$\x9e\x04\xd4\"\x83\x96\xbb8{\x00[\x01F\x9cKyT\x08\xa4\x18\x8b\xb7'\xb4\x10A&d\xe2\x08\xf2\xedm\xb9\xab\x1e\xd8\xa5\x91\xbc s#L+}\xf5\x8d\x025\xcb7\x86\xaaE\x9d\xf3D\xd7\x12\x8b\xed\xf2\xbd\xa5Y\xcb\nl\xbe\xd5\x98\xb6\x0e\x1dZ\x0e\\$\xe1\x8c\x8e{@,\x8dX(\xaf\x8d\x10\xe4\x12\xe5\xf3\xff\x02\x94\xaf\x0e\x15\xfd\x14)C\x08D\xca\xa2\xb6\x83\x80~\xa0\x94\xc6\xa8\x07\x1e\xcc[6LF\x11'T\xadC\xc226\xbeK\xa8\xa6%\x12\xbb\xe4A\x17\xdd\xa4.m\x12\x9a\xd8\x86\xc9H\x84C\x96c\x8b\xeb\x03;\xcdI\xfc\xa9\xbd\xa06lk\x1d[\xc6\xe5\xfd\x8f\xed\xbe\xc6\xc2Z \x9ai\xb1\x8d/\xdf\x08\xab\x8a+\x01\x8f\xaac\xb5Ka\xd8\xbdQA\xc1\x0d\x11\xa5\x02\x9eC\xb1(\x82\xf2\xe4\x1e6\xbe\xe6\xb4.+\xf67\x1f\xfa3\xbcsI\x03\xe6\xe4\xfa.v\x0dA\x1b\x0e\xa1\xf7\x9e,H\xcc`8\xea\xc1A\xf5\x0b\xbd \x98\xa6\x16\xda\x86^u\x0f\xbf\xe5wX2'\x05\xb4\x9d\x8e\xe7\xd7g\xcaML\xb8\x18\x82\x81\x01\xaf\xf5\x93\xd0q\xba\x9c\x10o.|Ft\xc5W;*\xab\xd1<\xa6,\xf0\x99Hm\xffpPYQ^\x8b\xd9\x13S\x85\x03\xa5\xad\xab\x8d\xec\x83\xb0\x13\xc3\x8e\x08\xa6k2\n\xcd\x91\xe6\xe4\x9c\xe4\xc5&n\xda\x1dp\x9d\x90\xcb\xb7\xd3\xeb\x83\x15\x0eQc\xb8\xb3\xe7\xec&\x8d\x0b\xf6\xfc\x06\xba\xaa0\xb4\xb3\xcb\xeb\x0bS*UT\xb9\xc4\x98+\xcaJ\xb0\xca\x03\xa36\\\xda<\xd1\xa8S A\xbd\xe6\xb2\xb9\x94\xb3\x11\xab\xba\x19\xb1Vl&<\x04\xaa(N\xc5\x02Q \x89\xd0\x98\xf0F]7\"~xP\xd8\x1a4\xa5\x91\xd2\x13\x0fI]\xf5\x0e\x87m\xcc\xd4\xa6z\xde\xb6\xf7s\xfa\xbe\x92\xf4}u\xc3\xf4\x1dU\xc6\x8a\xbc\x8b\x1f\x1au\x17\xda\xddm\xe8\xf5\xfb\xfd\xea.\xa1\x13\xd8\x86@\x08\x15\xeaE\xb2\xe0\xed\xc1\xe9\xaa\xf69Y\xf0\x86{!\x9e\x07\xed\x93`u\xb3'\x81\x1an\xa5\x8b\x84\xaf\xebCi\x9d\x11\xabk\x9d\x11\x8as\x08\x08\xec\xe8}\x87p[\xeb\xcf\xba?0@zW\x18\xe452!n\xf05B\x9d\xf84\xcd\x0c\xb6\x87\xc6\x90\xbd\xcf\x9d\xc6\xa1Rv\xaa\x1d.\xe8R \x02\xb2\xcb\xa7\x91\xb0\x15\xe0\x19S\xdd\x0d\xe1\xe1\xa0\xf4-]\x91`7\x82\xddP\x1eO+\x89\xdcg\x84\x05\xbaU@\x99\x0c\xf8}f\xb8\x8f k\x9f]\xab\xeb\x1c6\xe7eTemy,\xf6-\xf8\xbf:\x92\x0c\x06|.vi@d\x17p\xaf3\x94\xf6D\xb5\xd0\xb5\xf3 4\x13mp\x89\x03\xed\xc3j\xf5\x85\xe7#\x0eGB\xd4@sV7s\x16V\xd8\x8dz\xc3J$\xe0\x90\x93\xf2`k\x03S\xf8\x1a\xf3\xe0iw\xeb*G\xeaT9\xd6%\xc4\x08\x12\xa3\x06\xd1\xbcl\x19l\x8b\x11\xed\xf0\x01\xe4\xfe\x0b\xd4\x92\xd7\x8c\x00\xdc\xfc\x00\xae\x80g\x1co\x03\xa0\x969\xf9\x02\xd9\x0c\xce\x9b8\xec\x95 \x9d9\xd5!\x0d\xe8\xf3E\x7f\x84\x16\xc9\xbf\x98\x03P\xca\x17\x94\xd7c\x1f\x91kuC\x0c\xc1\x8a4\x16F\xf8}\xc8\x1fe\xb8\x1d\x9aU\xc5\x13\xfegy_\x92,\xf9 \x9eq\xe7ed\x91\x81\x8f8%*\x9d\xd3 \x89\xe0\x94\xe0\x9f\x17\xd5\x9fG\xea\xcfSRF\xf4\x887\xb5@\x1e\xf1\xbe\x0c\xf29jH0|\xa1/\x89-\xbb\x04\x9el\xc9|\x89 &v\xf6\xab\xd3\x8e\xdf\x0b\xaa$,\x11\xec\x87*\x7f\x06\xbe~\xe0\xbfk\xee\xdf\xbbw\xe7\x1e\xdc\xe2\xe7\xd9\x9a\x13s\xfb\xc6)\xdfd\xe2M;\x92\xe3^\xd9F\xb7\xbbG\x8f\x1e\xc1\xde\xfdP\xde\xe1O\x02V\xde|\xf8\x10\xf6\xee\x8b\xdc3!\xac\x9b\xce\xf8\xb6P\xa6\xe3._Il\x1en\xc1\xde\xee7w\xbe\xb9\xbb\xf7\xed\xfe]X\xc3\x9d\xfd\xfd\xbd\xfd\xfd{w\xbf\xe1O\xfc\x9c2\x9fZ:\xd2)&\xac\xd7\x8e\xe0\xeb\x92\x86Z4\xd5\xdd>\x8f\xaa\xa3\xb6\x07\xa3\xbb\xe3\xae\x9e\xb7\x9a#4Px\xc5\x18\xa8qY\xe6P\xa5=\x18\xd8}\xce\x12\xf4)\xdc\x92C\x15\x0e;\xc2\xa7\xc21P\xd0\xf0t\x17\xd66\xe7(q\xec\x8d\xe0\xbd\x80\xf5\x1b\x993\x83`:\x1cxF0\xf1\x19>\xe7T\x1c\x1b\xe7K}\x9d,\x0bp :\xdb\x08\xc7gq1{\x9aM\x88\x06\x19u\xcb\xa4\\\xc4\x96\xaa\x90-\x1d\xa4\x9e \xb43\x9e\x1f\x9a\xbe\xaa\x08\xbfw\xc2c\x8d\x84a\x97\x1a3\xa9\x9c\x0b\xcb\xaf\xc9\xf09\x19y}\xb9\xf5\xd6:n\xb05\xceOS\xb4q?/\x8e\xaaT\xd8\xe8\x0egz\xe25\x16[g\xdd\xe0\xd5\xbf\x96\xa3\xa0\xd9\x84|X-\xf8\x96\xdb\x0d\xa1\xb8H\xd8x\x06Au\xbf\xab)~\x8d\xe3\x82\xc0\xdeA\xe7{\xa0\xd1\xfe\xfe\x92&\x9f\x97\xe4\xf93\xfb\x1c\xd5\x85\xcd\x7f\xb7a\xf3\x93l\x8c\x01\xc3G)\xe1\xff\x88\xc96n\x96cp6mVj\x83\xdcR\xdaj\x19\xdf3\x7f\xcd\x97k{\xfb5\x89\xf4\xa3\xef\x16\xbc\x16{\xff5\xee}G\x88\xc8\x07\x12r\xac/\xa4,z=G\xd7\x06\n=V6\xd5\x01\xfe@\x97\xe7\xa6\xc7`\xefMFw\xc8%#\xb4H\xaa@\xc2\x02\xe2\x9c`\x92\xe38M\xb3\x0b2\x81\xb8\x80OdU\xf4\x9b\x89\xb3\x9b\xdd\xf3\x0de-n\xf1\xdc\x98\xc3X\xbf|\xd2\x11\xab\xab\xbb*\x86~iI\x8c;\xde\x94|\xbay\xf1\x01\xcc~\xb1\xea\xc2\x15j\xac\xc3\xa6$C\xb2\xc9Z$\x89\xc6\xc1\x9b>\x08\xad\x0d\xb9\xd5m\xfa\xa5\xcb\xda\xfe=\xf7\xe3\xc5\"]I6\xde\x12\xd1\xaf_W\x91\x83L\xf23\xb0\x03\xb2\xddD\xb0\xe6\x94^\x91\xbc\x16\xde\x7f\xa4\x08!\x96AA\x18\xc4@\xf9>\xa8 \xa7\xc6\x08\x19\x95{\xc2\x89\xfa\xfc*\xe7`\x9f\xfd\x06\xf4\xc4y\xeaot\xda+\xe5kI\xd68\xc3\xa0e\xb41\xe6\x03h@\xeb'4]\xf1&\x85\xd6\x14\xd5\xa4c\xe1\xd4{J\x80s\x0fd\xd2\xf7\xf4\"\xfdd\xe1\xedKu\x0c\x13\x8c\x92f\xa1 \xf5b\x16\xfc\x85;{\xf0\xb5HU\xd8\x1f\xcf\xe2\x9c3/\x8fY@Q\x98\xb1\x8aG\xc7\xa4\xed#\xad\xff\xe2\xbd?&U\xc6\x84\xa48*ic\x9bj\xbc\xf5\xdaa,_9\xf0V\xa9;\x8d4\xf3\xcf\xab\x08z\x7f\xefE\x82]\xb4\xea\x04\xc6\xb18\xe2]{\\\xf6cs\xf57\xa0Y\xd8\x16\x97\xdf\x91\x08>XE\xe6\x9fI\xfc\xe9u\xdc\xd02\n\x06/xGd\xe6\x02\xf9\x92\xa1qqF\xb6\xa1\xfc\x1c;<9I\xe6\xf3%\x92p\x8em''\x8d\x14\xed\x1d)\"\x03lE\xfc\x0e\x9e\x93&\xd2\xf3\xfe\x7f\xe7o\xec\xdd7$\xa6\xe4\x0f\xf6\xef\x192\x1f\xbf\xb7\x0cY\xb2\xf86)\xfa\x95e\x03\x9c\x91@\xc4f\xa1tV\xb9\xcd/H>\xcd\xf2\xb9P\x7f\xc7\xa2\x8d\x8b\x84\xcd \xa6\x90\xd0iB\x13F\xa0H\xfe \xbe;\xf0\xa3[\x8cw&\x0d\xfbE$\x0d\xfb\x8cMp\xfeb\x1c\x94\xf9\xd3\xf9\xb3>\x1f\xd9\xeb%\x8byO\x85\x16\xd6\xd2\xa5\xab\xce\xad\xe9\xed^\x91\x80*-?\xedO\xb3\xfc(\x1e\xcfj\xf1V\xc6@\x06u)R\x8a\xdc\x15m\xa9\x9b\xd4e\x8a\x82\xf6\x03\xe7g\xef\\ \x7f\x90\x8el\xe6\x1fI\x04'|\x9e\x1f\x89G2\x9d\xd2| B\x8a\xcb\x038r\xa9\x88\\\x8bd%!\x1d\x15\x86`{\x00\xfb]\xa2\x14\xda\x85\xe1Q\x95@\xc6p,\xbfN\x8a\"\xa1g\x82 \xc3^?\x91\x95\xc8f\xc1\x86\xd4\x94fR]\x82y\xe6/E\xfcU\xde\x97-\xdc\xbds\x9d\x11\xfc\xd76_\n\x85\xa7\x96\x01\xeau\xbc\xb0\xa6<\xfb\xf8\x85\x96\xc5\x93<\xcb*\x959\xff\x81\xa2s\x19K#\xf26\x85&\x93b\xad\xebb\xa3\xae\xff\xa1'\x85r\xcf\xa9 \xec9\xdd\xa0i\x9c\xc8r1\x89\x19y\x8e/\xaf\x0c\xd5\x0cm\xdfn\xba\xb29\x99g\xe7\xa4S\xd26\xccz\xe5nxBR\xc2'\xe0\xdbtk\xd6\xbeS^m:e\xd1IsA\xdc\x89\xa3\x85\x08Y\x92\x17\xa5G;\x94\xae \xa12\xce\x94\x13\x18\x92\x91l\xd4c,m\xf4\xb0\x8c\x06\x83]\xd1)R\xc6b\n\x14w\xf8\xc8\x96$\xda'\x91\xc4\xb9\x8c\x03\x15\xa6\x8d\x95]'\x1aw\xfa\xe2qr\x17K?<;Q<\x97)c\x12YM\xcbb\xd6RW\x01\x03\xc8\x82\xa5\x83\x06\xca\xe5*p\x02K\xe9\xac\xdb\x8e!\x03\xab\xd4qF\x82\x04cH\xd0p\xc3\xf7n\x04\xbd\x84\x9e\xc7i2\xe1\x94\xf8]\xccf69\x88\xcf&\x85\x01\xc4.\x0fT\xfe\xd2XNy\xc5\xa7\x8c\xd4*\xe5\xfb\xc9\xfe\x01?\x07I0\xae\x16\xd0\xa9(\x9d\xe2\xec\xc7r\xf6\xe2\xd7\x8a\xff\x92\xbb=H9\xbe\x06I\xc5\xcb\xb0\x10\xcf\x8e4\x82\xa9\x81\x07\x90{\x9eR\xd4\xe9Z\"\x1ee\xdfy\xd9\x9b\xe4\x9aZu\xd0\x1a;`\x9c\x92\xd8Y\x94Hk\xbc\xed\x16\xc3\x84?\x84Ym\xc0:\xea\x8d\xb3\xee\xf6k2P\xe7\x04J\x8b,_\xa9\xb8x-t\x11&\x06@\x8e\x86 b\xb1\xfeE\\<\x16\xf44@\x1f\xb6\xfe\xc9 \xa1\xc52'o9\xbd\x0e\xea\xc4[\xb1R\xce\x81\x97\xbd{\xee\xc1\xd6\xf9P?7\xf4\xd1pQ\xec\xd2\x0d\xb6\xb8x\xae41\x9b\xf5\xaf\xf7\xd3\xb12%\xc86\xebA\x9e[\xce\xb67spR\x1a\x11r\x01/\xfde\x9e\x8d\xbc\xd0\xbe\xd4\x89Y;\xdcKo\x1b\x94\x03\xdb\x99E:\x88\x08\xba3\x93\x80a\x82\x19\x86\x19eL6\xf7H\x94}\xea\x80\x80\xb6\xda\x9d{K\xed\x98\x8a\xc11`+?\xd2\xfeI*\xd6Fgk\xa2*\xaf\x03\xb24\xc8\xe15\x1a\xd2r?\xe8\x0c\xce\x9edp\x0c\xd3I\n.\xb9\x0f\xe0\xb3\xc1s\xe8{\x12\x01\xb2W\x8dd\xc0\xaf\x1f\xbf\xb3TO{\xc2\xdf\xd6\x81dS\x0f\xfedO\xfc\x81\xc3oOH&*j\x19\x1f\xac5>\x9c @,\x9d\x9c&l\x8e\xe0PN\xb14\x13.\xc8\xd4\xab\xcf\x9f\xaf\xd3\xe78[Rv\xed._\\\xa7\xcbOd\xf5\xa3`\x8aY\x0b\xba~\xdd\xfezs\xdd\xae\xbc;}\xd9\xdd\xe9 \x13\xa5FK\xa7\xe6*\xc2\x86V\xbe\xcd\xf1\xf8\x93H\xd3\xa9(\xcaW$\x90\xbf\xfc\xb4\xa1?t\xa6x\x14\x15\x90D\xc6\xaaVRJ[\xb3_u6k\xa6m\x1ce\xac\xe5o\xd1\xab\xf8\xc0\xe6\x8eyr\xb2\xc8\xc9\xb9\xc9\x14\xec\x97\x85\xe5\x9f\xbeIQ\xeb\xc5_\x9f8\xf2\xf6fJ\xaa#\x11d\xa5H\xc7\xf0\x87F\xe9\xa8\xb8!\xa5\xbb\\\xfc\xaa\x13\xbd\xcck\n\xbf8\x93R\x7f\x8fz\xed\xe0{>\xa0\x7f\x92`\xd73\xff\xdd?\x9c\xb8z.k\x92\x9b\x8d\x9c\n\x15-\xab\xadt8\x17\xc1\xa9\xc5\x9d\x12d~\xd8\x8b\xe0\xc4\xa1\xbc\xc1\x04pL\xf5\x86\x91/\n\xbc\x11h\xcaU\xb1\xb8I\x04q\x18\xc1\x96T}T~U\xe6\x0eD\x1e\\\x19~\x18$\xb2P\xd7!\xe7\x02\xa4\xf6`g\x0fK~\x1d4\xab\xc9\xf1\xeb\xcae\n\x17zvl\xc6g\x14{U\xf9\xc6\x9fp\x9bW\x93\x1cZ\xa1'\x8a\x8f\x19\x1f\x9b\x82@m\xc8C\xea*\x8b\xb2>c\x16\x95\xd4\x07Q\x97\xb4\xd5\x14\xa4\xa5\xa3@O\xb8\\p\x08\x19\xee6\x93\xbe\xc2\x82\x8f\xd2\xe9\xa6\xd4/\x89\x05\x8d`\xe9\xe4U\xb8D%$\xb6\xc0\xf8\xe9\x01GD\xb9\x9e\x84\xf3#G\xc12\x8c\xe0(\x881\xeb\xc3\x05?'D\x0e\xd7!\xff\xcc7\x9d;cn\x1e\xaa\x95\xa8\xf4W\xe1\xf6\xd9\xba\xff\xc2\xcf\x13\x976\x80c\xea[l\xcc\xf2\x08\x1b\x0c\xf8\x02h\xac\xf3\x8br\xa6\xb2\xbaP\x04\x99\xc9\x96\x83\xbbW$\xde\x0e\xaa$_U\xcb\x07\xda\xdf\x8f\x1e=\xe2\xf4\xe3\x16\x9c\x99\xf7\xf9\xb2\xde\x08\xba\xe9k\x1fY),\x1f\xef\x8f8^\xaci\x1b\xc3Z\xfc\xb1\xc4qI\xbd\xea\xb0\x82\nl\xc3\xb9\x84\xccH\xe8\x15\x07\xf5\xd5\xcdB\xfe\xe5C\xf1\x1d\xe1+\x0d\x070L\" \xbeK\x9e3\x17\xbd\xac\x12k`\xf5\x82Z\x86\x02Z\x9a\xe8:\x12\xdfph\xd1a2\xb2\xd3\xcc\x02M\xb46\xeds\x1c,\xd1-:\xe0\xaf\x15\xf5\x8c\xc6>~ \xd3V4\xa1\xba\xae\xc2\x90\x1f_\x8be1\x0b\x0c\x9eEV\xf2\x12+\xa0e~@\xce\x9c@.w=zmUj\x95[\xb7\x00\xb3\xb0\xd6\xd4+\"'c\x99\xd8Wl\x7f?\xce\x12\xc1S\x82\xc9h\x87\xbc\xa3QX\xe3\xc8\x98\x0fG\xa6.\xe5l\xc0\x86\xb6\x04x\xea\xca\x10\xab%\xf9'5\x115FEKl\xad\xfe\x01F.J]\n\xd9\xcd\xb4\x99wU8\x8d\xf2|\n\x0b\x90\xd1a\x9a\x82W\xc9\x99\xd6\x8e\xb9d\xb7\xe0\xb8\x85\x14\xa9\xe8\xb2\xf9\x1f\"\x7f\x9dJ\xdb\xff\x0e\xec\xc1!L\xfa\x8bLT\x82\x98\x0cSN\x8dZ7\x86|\xe4\x9c\x1f\x9f\x08\x06S\xfc\x0e#\xec9hh\xff&\x95)\\ \xcc\x11L\xbaX\xd2\xab\x08~\xbc693F\x97!vY6+\n\xf5\\\\ \x82z\xfdp\x11\xf9IP\xf6\xb1hF\x12EC\x84\xa6\xd7J\xd8x\xc3\\\xce\xb9%\xb8\xbb24\x1b\x95\xb3\xc3%\x13\x8f03\xf2H\xc4q \x19\x89\x99\xd8\x89&x\xaeM\x17k\x99\xa1U\x02\xe8\xa7$\xc8m\xa0\xd2\x04D&Y\x1e\x8a@b\x0e\xa9\xb2P\xf0]\x9a\x9f\xa7u\x18\x9a_\x1acL\xe5\xd6\x00\x82\x14n\x81 \xb5\x91\xae!\xa1\xce\x1a\xca\x1c3AUtz\xc9D\x93\x08|s\xe7\x0b5B\\.\xf3;|\xef\x8d\xe1\x10\x16\xc3\xe9\x08\xdc!\xeb3\xa1(\x9b\x08\x0b\x8cX\xe8\xfaZ\x99g'\xd4\x04\x13\x8f\x83B\xc0\x01E\x97\x85F\xde\xc7N\xf2\xeep\xf3\xaaU\xfc\x92\x0c\x01\xdf\xcf\xa2\xde\xcc<\x8c\x103v\x1fHV\x9f>\x80%\xa6\xf9\xe1\xb81\x80\xbd\x10\xe2\xe1r\x84hp\x0b5\x0bl\x98lo\x8f\x1c5\xeb@\x13J\x87\xf9H\xa8\xb8\x84/|\x80 \x05\xb7\xb1\xda\x98\x81\x90\xf0\xc7\x8b\x08\xd2\x08\x96\x11\xcc,\x90\x94\xe79\xff\xbf\x08S/\xa1\xc4\xe5?\x16,\x86{\xf0/\x98j\x9c\x8b\xba\xe3h\x0f?\xde357\xab\xda\x99\x99\x11\xf1tSr\x7f\"\xd1m\x86\x14\xfc\x00R\xf8\x17\x92\xfd\x14\xd6`\xc1\xd0\x0b\xed\x93\x82\x05\x8b\x08\xa6\x11\xcc\"8\x0d\x9b\x01\xf8\x1d\xe2\xc7yY\xed\xa3\xf2\x80\xb0\x1f\xb5B\xbdZ\xa6\xbf\xc9\xb5\x08Z!\xc5P\x80O\xb9\xa7\x1eb\x99=Q\xf3\xacslz\x97\x88\xf6\xf5\x0e\xdd*\x8d\xa4\xfa\xcc1\x06\xb7\xa2#\xe9\x92\x16\xf0%\xb5L5\x00\xa8\xbbn\x19\xa2\x81_0\x80\xafH\x90X\xed\xe7\xe0\x14\x17\xc6\x19e \xdd\xa8\xf8C\xbb\x7f\xedW_\xf8\xccv\xecj\xa8\xb6\xa7mct\xe6J\xb5\xe6Im\x10\x90:0\xf9*\xa7|\x06s\xb8\x0dw\xdb-\x8f\xd5\xb3\xfd\xf6\xb3i\xf9\x9d\xcds\x7fa\xf1\x188\x97\xb1CG\xc6\x80a\xe4\x9b\xbb\xf3XZ\xe4\xea \xe6\xc9+\xa9\x9d\x99/\xa4\x18:\xec\xaa\xe7D\xdd5\x1e\xc4`r\xa9\x03\n^\x89\xe3:\x87G\"kt\x0e\x0fa\x0e\x87p\x81\x99\x07\xf2\x08U\x0c\x18g\x8a\x85 X@\xfb,\x13\xf2w\x88ei\xd9\xc6n1\xe8'r\x9c\xfc!z6\xa4\x01\xe9\xd2\xf4\x96\x9a\xda\x0e\x7f\x13\x93\x17\x89\x9f\xa7\xc5\xc4\xed0\xa2\xe5\x01\x99\xb1\x8e< \x0b\x16\xc1\x05\xe1l2\xf3\xc8\x03\xa2 \x1f\x81=\xc6r\xc1\xb4#\xeeKsZ\xbcJ\n\x06\xc3^\x04\xbdQ;\xa9E\xad'\xcf\xa4\x16\x89\xaa\x15_%\xc5\x0f\xcb\xac\xe4\xa4\x9e\x95\xdcq\x9ar\x01\xb6d-1I3\x8e<\xcb\x93\xb3\xc4\xe6\xd9\xa6d.\xde\x13\xed\x8b2\xa1\x04n\xc1\x99!\x14\xd2\n '\x0c6\xcb\xae\xe1k\xbf@\x901\x04\x99d\xabjU\xf3\x1dE\xa00\xb1\x7f\xe5\xc4\xc6\xe0\xa1\x96\x0dvs\x975\xc0c\xe1!\xec\xc2!|\x92\x19\x0cq\x9b\xed\xca\x08SqsW\xa8\x1f\xf7\xc43f\x8c.\x03\xb0'\xd8c\xe8\xfb\xa4\x16\xd3\xfcNe\xcf9aq\x92\xba\x19*\xe5\xdeo})q\x06\n \x14\xdfb\x94\xc08^\xc4\xe3\x84\xad\x84A|\x00\x97Xo\xbb\x195 \xe4A\x14\xb12\xf1R\xd6x\x89\xf4ORrN\xd2\xea]\xfb\"n%~\xe1\x06\x89\x08\x9b\xa8BL\xcbuV^\xf6b\x14\x1c^\x9b\xb8\xdc;7\xd3\x05\x82E\xac\x14~\xad \xa4\xcf13z\x17^\xb9\xe2,k\xdbj\xb3\xf4-H \xcaJ\x1c\x9aU\x03 \xcb,\x992T\\h2\xaf\xcah\xaf^R\xba\x0d\xf1p\x91&c\xe4\xdb\xf6lQ\xbb\xb5\xc1&\xb4 \xf9&d\xa0\xd1\xcbn'8\xfe\x0d\xc9$tjZ\xfeTK\xab'\x9b\xc0\x15\xe6\xf8\xd3\xc8>!%%\x81j\xd7NE\xc1\x19)'(\x16\xcbb\xd6\x05 %\xbcU\x11\xfa\x96]\xae\xc1\xc9\xca \xe1\x1b\x16\xbai%\xe0\x9f\x90\x11\x91dQ\xd9R-;\xbe\xe6\x16\xbc\x8b2\xbb\x96\x16\x11%w*\xe8*l\xe3\x1e\x1e\xe6^%\xd9\xea`\xcb|\xf3:|R\x87\xecn\x04;{\xeeV\x97\x14wWW\xcb\xad\xf5\xb8\x16\xb0\xad\xa1a\x9f\xf0\xc8\xd9\xf1\x05\xb3#\xfbd\x99HnH7\x07\xb1\x17(\x9a@\xee\x00\xf0&\x89W\x1e\xfb'^i\xf7\xe1\x95\x90\xa3\xd9\x91o\xe2\x95vw\x1b\xe4\x19y\xec\x97g\xc4\xdc\x87\xd7\xb4\xce\xaf\x93\xd7\xe3qg\x9e\x91&\x9fx,\x08\xad\xd7\x89\xa6o\xc2v\x11\x8dz\xcb\xbe\xf5\x97\xce\xbf\xa8\xee_9\"Y\xe2\xaf\xac\xfa\xe7\x1e\xddfI\x19\xca\xedi\x17gOJ\xe4\xb3\xaf\xcd\x06\x05a0\x14\xb1\xabB.\x9e\xa8\xa7\xec\xdfW\x04\x86b\xd1\xd6\x8d)\xd0F\xd9)\x9aur\xa5\xfe\xd8 _\xbc\x02\xa1s@\xa1\x04\xc1\xa2\xd7w\xa6\xd7\xad\xec\xdc\x98\xc8_\x92d\xe2\x82\x05:\x9b\x135\xb8\x9c\x1a\x87\xa3s7\x91\xc6\xdcl\x94\x90\xc2\xb4\\I\x81\x12\xf6\x00&\xac\xad\xc1\x9a\xb1v\xe2\x89W\xcf\x8f?X2O\x9c\xa3\x05]\x83\x9cM\x7f5gV<\xc0\xb1\xa3h\xac%-\xa8f\xd2\x8cn\xd3\x7f\x9d\xb3\xe1\x8c\xa9`\x90sV\x05\x83\x9c\xb32\x18\xe4\x9c\x95\x89\"\x9f\xc8\x9c\x91\xda\xbbx\xbf|[\xbd\xa5~\xe1\x8b\xa5\xfd\xed\x89\xb2\xc5i\xb7\xd5\x17\xea\x17>\xaaR{=)\xf3|U\x0f\xcadOOj\xd9\x9f\xf0\x85f\xe2\xa0'\x0d\x89\x19_\xd2\x93\xf4<\xd1r\xf6\xc8\x87z\x0e\x9d'\xb5\xa4:\xa2\x0b=\x03\xce\x13=#N\x04\xf3\xb6\x08\xf4\x84L\xb3\xdcd}\xb4iZh\xe9\xd0\x84\xde\xcc\x0c#\xdb\xca\x8d\x81\xeb\\\x86^hL\x97Y\xbb\x88\xfaC\xe1\x13e\x0e\xad\x15\x0e\x80\x8f\\\xadK=\xe1p\xc4O2s7\x99\xf4\xbb\x10\xaaHs/LT\xbd\xb0S\xf2\x18\xf4Q\x0c]\x06,,R\x1fs\xba\x15\xd7\xc0\x8c\xb0\x85\x1d\xd4q\x86!\x8e\x06\xdfJj\xa0jSe\xe3\x80\x85\x95,\xf3\x80\xf2\x12\x06p\\\xe5\xce2\xcf\x7f+1\xabTj\x8e\x13\xbb\x0f\xa0\x10.\xa6\x05\xfaIJX\x14\xa3R\xfc\xb2\x12\xe4\x0c\xddD\x96%\xf48\x8d\x0f#X6)\x98\x01G\x1fO\x19i\x1d\xef\x9d(\x1a\xd4q\x14\x83\x8c\xbf\x00S\xa5\xf5\x13\x85\xfa\x0e\x84\xcd\xdc\x08k\xee\xc4\x0b\x07\x93:\x0e\xda,J\x88\x839&\xcb\xe4\xd8\xa5\x83\xd1\x80\x82\xf8Rf\x86\x0c\x1a\xbf6DN\xb5Y\x9c('\x9b\x8ceoRY\x91\xa1\x92/\x92~mq9M\xceD\x85\x11\xc4udi\x1fog,\x82\x15\x8b8\xd3\xe0J\xa3~b?\xad*^]\x1d\xe2F\x08KEay\xb2\x1b_\xc2\x04-,\xc8\x1dQ3Ryf\x87O-\x91\x88d\x1cv\xc3\xc6\xc4\xa0\x16\xf7\xcc\xe7\xb6\x8c\xc0jc\xad\xe9q\x96\xb5rV\x16O\x13u)b\x12K\xff\xa5C\x85`\xe2x?PQ\xee\xf8\xd3\xce\xa3\x82\xf4K\x89e\xe5\xc3]\xf4\x8c\xdd\x81\xd8\xfd \xaa\x18\xf9k\x16\xbe\x11_y\x04s\xc4\x1d\xfe\xf2\xdca\x0f\x95@\xe8\xe4\xe1\xd5\x95\xa0\xe3,\x9fvZ\xee\x87SG\xd1\x11\xd0\xd4\x12X\xedq'\x85\x03N5\xdd\x9f\xc8\x96\xd1\xb3k9$\xe6\\)`\xdcvx\x97/a\xd1t\xcb\xcfPs\xdc\xb1\xac\xc2\xa9\xd5\x7f\x01S$/\xf5\x05L\xe0\xd1#\xc8\xdc\xdf\x8d1\x00f\x9b\x1f\xeb\xea\x03\xc72\x8d\xcb\x05\x1d\xdf\xf0\x82\xe2\xb9\xf6\xc0\xea`\xa1_|\xed\x8d\x19]L\x97Z\xf4\xa5M\xe8k^\x89,\xb2\xc7E\x9d.\x85|\xf3ZJUh\xe7\xcbv;\xbe\xba\xf80\xd2\x86/a\x17\x82\x83.\xf5#\x92\x8f\xe1\x00\xd2.$\x079\xf2X\xb8\xa2\x17\x98y?\x13\x87R\xc2Q\x83\xf2S;\x0b\xedn \xe0\x9c\x92co ]l=\xf6K(qaL\xf6c;D\x96\xad\xec\\\xe7\x0e\x8d\xc2\xb2T\x93\xc3\x0e\x17\x92\x96\x9a\xaa\\\xfc\xd4T\xe5\x0co(=9\xc5_U\xd6\xa3e\xa9$\xcf\xf0\x87&5&\xe2\x86\xd4\x97\xc7\xe2W=\xb9\xd7\xd2\x0b\x14G\xcc\xa5Q;c\x18\x06}\xc6\x07$\xec\xfa\\|\xf34\x85_\xb6\xa1l\x03q,\xfc\xf1er\x1ewL\x05\x11N\xf3\x0f\x15qS\x8a\xd9\xd6\x07\xc8\x0b#^j\xbe\x14\x99kc\n\x96\xb3\x83sK\x1b\xc4u\xb8td\xcc\x19\x0b\x13\x9f\xb4\xe5\x89\x8d\xa1`\xe1\xd4$\x8d\xc5 \xa5\xf2F\x05\x92\x0d\x136\xde\xb2c\x18\xc0\xd8\x1c6h[\xd1\xa2>\xf2\xf2\xf8'\x95[\xa6\xdeUT\x83\x9d\x80<\n;-\xde\x12\x0e\xcb\x9b\xcaD\x16\xeb\xe3l\xc7 \xd8\xf0\xe6\xd8\xce\xd3\x95j6\xf4\x07(c\xf0\x88\xe6\x99J\xa4\x07\xea\x9c\x05\"?\x97dK\x91+\xe5\xa3\xe2\xe2\xa5g\x1a\xc3\xa7\xf6\x91\x94\x16\xf4\x86\xedW\xb7\xac\x9a\xf9A\xf1\xe5C!\xd0(V\x10\xb6\xe1\xdc\x86t5sD\xc9DJ\xbe\x15\xbf~ \xfc\x16\xd0\x15\x07\x0b\xab\x0eJ\x1f\x06\x11\xaa\x95\xa3'\x03\xffhg\x00\xe7N\xc4\xeb*\xf3n\xad\xe8\xe5L\xd2\xa3\x05\xbd\xa8\xa83Q\xeeX\x7f\xa2\xe2\x0f,\xe5\x8d5\xb3\xbe\x9en\x07\xf33\xd8\xd9\xf6\x0e\xf6?\xf1a\xff1\xc6\x03\xb6m\xc5\x19\x96\xa5\xcc\x8c\xd8H\x91\x9b>@\xb3\xd1.\xfe\xbd\x8d!c\xbc\x05\x83\xc7\x02\xc7\x87\xb8\xb9\xbf\x92.2\x15s\xdc[j\xd8\x86\x86_\x13\xa7R\x13\xfb+\xd1#\xd5\x91i\xac\x82N\xb7a\xccG\xfd \xc4\xe7r\x1fa\xf5\xac\xb4\xbe\xe3\x0fa\xa8\x8cG\xe9H\xee*.\xd8\x8da[e\x1f(\xf8\x9f\xe7\x86\x11\x8d\x85L\xc8\x1f\x8f#QF}\xcc\x0f\x00\xf1o\x82\xff\xba&2\x15\xd2X\x82\x11\x04\xf8\xe72|\x00\x0b\x0e\x11\xec\xb9\xe0\xbb\xc9k\n\xb5\xa1\x8b\xf1\x9a\xf1n\xd2\xe5N2\xc3 \x8a\x87\x18#!\xc8\xc6RH\xdc\x07|`x[Soat\xe3\xc4\xbc\xb2X0]|s\xeb\x16\xc6\x01\xa3h6i\xa8 :h\xc5\x1c#X\x90\x90\xa7bz\x9c\xdf(\x1e\xc0\n\x1e\xc19\xff\x87S\x82.Y\xe2\x14\x060E\n\xb22+I\xd4\xc5\xbb\x9bK\x92s:\x12\xfdV\xbf\xad \xa4\xcc\xfc\x9d\xfaP\xf4|\x8e\xb4\x0b\x060\xe9\xa0L\xa0\x18|\x05\xb2\x80/\n\xc6\xac\xcfj\x8a\x93\x1c\xd9\x98e\x88g\xdd\xa3\x01,B\x8898\x16\xb8h\xf8o!\xdc\x16*\x07\x85VSR\x0f(\xda2\x85O\x96\xee\xc8\\8\xce8\xa5B\xfcp\xae\x9c\xdc\x87\xa9S\x98\xe1\x0bs\"\x84\xeeG\x8f\xf8\x81\xeeZ\x18>\x80\x13\xa4\xae\x8b\xea\xf5\x10Ns\x12\x7f\xb2\x7fu\"\x05\xb5\xed\x01\x04bK\x85\xf05\x9c\xe0&\xd9)!#\xf7\xd3\xf0\xc4,\xdc\x9a\x177\x15X\xfdH\xaa\x11E;M\x90\x16|ev`\xcc\x97(\x15\xfb\xe1\xa1\xd8\x0f\xb5\x0f\xca\xe5,8%\x90\xef+\xea\xb2#\xa9\xca\x8e1\x8ar\xe3\x94\xa4KTkT\xc7\x89`\xbbI\x8d\x9d_V\xba\x1d\xc08\xce\xca\xbd*\xd5\xdd\xabf\xbe\xeeU\x9cL\\\xb0 \x16\xe2\x0eFj6\xa3\x1b-\xc7\xf1c\xbf|\x91\xb9\x9e/\xb2\x16A_eY[\xba#B0)\xb6\x93 F \xc6\x9a\xbe'\x15\x10~$\xf7l\x82\xeb++\xfd\xc5A!RJ\x8aU\xbf\xe9\x94\x92\xb9\x88GK7@\x8f\x04\x1e)\xa7\xc9[\xb7D\x82\xa8\xca+9A\x92\xa2 \xdf\xccrcY\xa9\xb7])\xe6\x84[\xf5.*\xe5\x94\xce\xfa\x9co\xcas\xaf\xf6\xdf\xb9\xdbw\x16z|.\xdc\xe1>\xb0\xaa\xbe#\xbf\xb5\xb1\xdf\xcd\xf9\xff\xfa\xfa\x8e\x1f\xdcP,Ka\x8e\x9b\x08gk\xf0\xb5oJ\xbe\xba\xea\xe1\x9dfT\xb1+!\xaa\x14\xe1(\x02\xe1\x8f\x03\xb4\xdb\xf7OD\xea \x91;<\x15\xf6e\x8f\xdc\xe1^sz\xeeT&\xac\x842a\xc5{|\xcd\x02Q\xdd\xe6\x88\x05\xadP?K\xeb\xbf\xbb%\x0ci\xda\x89\x14KoM\xbd\x14K>8)\x1c\xfc\xbcHI\xc1,\n\xff\xa2\xe2\xf8\xf9\xd1\xba\xb4\xa9\x12\x06\"o\x93\x19o\x85~\xa2KQ\x18K\xf28\x10\xda\xd3\xea\xe7>|\x0d\x89r\xdcD\x1b\x910V\xb6\x93\x9fZDXu\xc9\xfe\xb5\xf9H\x15\x0bJk\x96}\x14\xf6Y\xf6\x92\xac\xc8\xe4\x98|\x0e\xc2\xcd)3\x19\xeeZ\xb8\x86\xb0?M\x93E\xc0;x\x1d\x8b|:\x1anr\xa2\x9b\xd7p\xb5\x8e\xb9\xba\x933:\\\xa0\xf1L\x95}c\xa10\xfe)%\x86\xe6\xdc\x1bkj\x0bND\x96J45(/\xb5X3\xabm\xa6B\x80\x18Qi\x19\x0e\xf7F]\x8b\x9d\x0b\xd5\x9eXG9\n\x91j\xdd:\x081?\xe9L\x1f+\x12Z\xb5\x10\xcbB)\xb2\x19+\xc9\xb0\xf1=\xb9\xfc\x9e(\xca!|\xc3%\xe5\xc8\xcc\x9c\x0c\x07\xe3kt\x7f\xf7\xcc\xbc\xfc\xa6\xc3\xeb\x04\xdd\x954\xaf\x93\x93eA^\x92U\x01U)\x0bE\xf1\xdaI|m\x9d\xbe\xb7\xd0tc\x8f\x9b7\xff\xec\xafm\xfe\xd5_\xdb\xfc\xc7\x8e8\xb6\x7f0W\x8aXV\x1bA\xbd{~\x83o\xf1.\xafN\xad9CR\xe6\x08\x8b9\xaa\xe2%\x9d\x0d\x9d\x97e\x92\xe5G\xb2\xfe\x19\xfa^9\x15b\xfe\x83\x05}7\xc9n\x02\x0b#\x12\x99*\x8a\xf09\xcd\xe2\xa2\xd3\x0d\x15\xf4\x8e\x12:N\x97\x13R4\xab\xda\x97-\xaa\x176kv\x16\xdb[\x1c\xc7\xe3\x19yO\x8a%\x86Q\x12\x1aaE3\xe9Q\xf8\x91\xe2\xe3Z\xd9.W\x04\x93\x12C\xcc\xce\x14P\xa7P\xadzV\x9e\x8c\xa1\xf4:\x14\xbc\xa1]\x1da-v\xa5y\xa7n:?\xa1\xef\xe5\x07\xc1\x9b.\xa9^i7UW\xa2]\xbb\x98\xaeXx?'Vu)\xbbf\xee,_\xab.\xe4RHg\x1d[uU\xfb\x0c\xdd\\\x87\xbb\x1d\xd9\x90\x00\xc3:\xd5\xbb\xda\x87{\xa3H\xfb\xbb\xe5^\xd8\xbc\xdcfQ+\x19Q\x97-\x8b\xb9\x1f>\xf2\x95\xc2\x15\xfe\x9d\xcbLp\x00\xbf[\x11\xa9v\xd3F{?ws\xba\x9d\x148o\x12\xdd|s\xd2b\xa7\x01y3\xa4\xd3\xa7\xa82\xc6\x81bbz7\xc5\xadj\xa6d\x18&\x8c\xbe\xf6\xa2\xc4Nn\x14\xedp@N\x02\xe43\xbck\x13\xa0\xac\xc3\xd9\xa6N\x83\xf2\xa0\x9a\x91\xfaXZ\x04mD)\xeb\x98\xb2\x99(\xf9\xcc\xb9\x86\xc3o:\xeb*o@i\x94\xf8\x9atR\x19t\xb4\x93\x04F\xc9\xaf\xf6\xb7\xcf\xa5OZ&h\x83\xdbE\x05}\x13\x9c4H\xc9\xef\x1cZ\xcbHC\xb6\x18)\xd0\x92\xe3\x9bq\x01\xc0\xa2NhUE\xb4\xec\xf1\xef\xbb=\xd7\xdc\x1b\x9c\xea,\x16m\xeev\xba s\xe4\xe2\xb2\x88`\x7f\xd02\xe7\xcd \xa9S\xe0\xa3y\x06\xa0sW\x1b\x8c\x13\xf4\xbd(\xa4D\xdb\x961pW\xa8Yj\x90-W:\xc1\xb2'\xd4\x04\xc8\xbc\x8f;{\xb0cHa\x0d\x92{h\xd2X+WP\xa7\xb1\xb5\xc6--_\x8f\x8d\xeb\xe0\x0e\xa9\x81\x97\xa3\xe6\xe8\x90\xff8\x0f\xd7Q\x8c\xe4*\x82-\x1b\xec\xcc\xb1E\xae\x19\x19\xcfx{\x0f^[\xfe\x0f_\x95_\xc7\xc9\x8e\x9b1k\xa2\x9a\x15\x8f\xcf\xcbD\xbd~\xc7o\x86\xc7\xd4\x8a\xf7\xb2\xb5U\x11\xc4\xccq\xfaf\x7f-;P\x8e\xa7\xcd\x0bH[\xbb\xa1\xb4P(t\x98\x0e\xa6\xc0\xe5My\xae\xc5 \xd8\xcf\x98\xa5\xb9*/t#|\xe2p\xeb\x05%5\xe8|\x02~P%R\xdc\xde\x8e \xe3\x0d\xe5\x12\x02hn\xb6\xe7\xf9\xe4Sm\xfa\x84\x81Z<7\x1f\xe1\x03\xa6&\x1f\x918*/v\x03m\x036\xc3\xd3\xf9S\xe1\\\xdc\xc9\x8d\x80\n\xca\xa8s$\x89\xfb\x0be\x08K|\xb8\x12\x906\xb1b\xb8\xeb\xb0\x9a\xa9\x0b\xb3Y\x1a\x13\x83\xeaW\x1d_\xc6h*\xd4r\x02}\xc6\x8a\x882\xb7:\"\xcf\xd8\xcap\x82U\xf01\xf3;~\xb6\x81'\xbe\xc4\x8fX\"N\xf9\x0c7r#\xe2B\xc4\x1e\xdcF\x1f\x1c\x0cDD\x9f\x1c\xf9\xfe[Y\xc1,\xeb\xcc\x9b\xc4\xd1\xe6\x9d\xa8cf\xb7'|@\ni \xc8\xe1\x04\x0c\x12X\xaf!\xe6\x7f\xc5e\x8f\x1c&}\x96 \x15\xbav\x10\x07a\x05)\xf3\xa0\xa4\x93w\x0c;&\xcc,`0\x10\x9e~\x01\xdfl\x85tD\xda\x85\x03c\xa5\x89s\xe9\xd5\xe8>vR\xc5bV\xe1\x06K\xac\xac\xa5\x8c\xa1\xcb\xca\x80\x18\xc1\x16\x9eR\x992\x8b-\xcb4>A\xda<+<\x8ea\x99\xe1\x86\xc9p\xd3*)\x10\x93E\x15\x15\x93\xb6\xcd\xe9$\xa6\x9b1\xf8\xb1\x85\x11\xa4_\xa6\xa7\xca\x9c\xe09\x96!\xda\xa4\xc2\xbcf!F\x11\xb4\xdd\xe5\xaf\xf45\xbe\x9e\xb2N\xda\xf4x\xff^K\xe4\xd6\xd3)\xb4\xd1Zm\xab\xf8\xec\xeb\xe3\xb1\xbc7|\x96\xaa\xb5z\x10B\xd6yZrxmo\x17\xf0HC\xf9\xae\x93\xd8+\xfa\x1d\xba\"\xe0\xf9u\xe5V\x13\x10T\x13tM\xa1\xe4\xaa1 \x96\xd2\xe2\x11\x0c\xb0g\x91\xa8\xa3\x13\xc9'\xcfU\x92\\\xf4\xc6\xd05\x95\x9b(\x08\xeaXk;0\x7f\xf2=0\xddd\xfb\x86x`;\x19K|\xf6\x08 \x1c.\xef\xe72\xc8\xc2E\xa7\xba\x11\xdd\xc1i\xa7\x9d\xa4J\xa4\xe4\xc6\xd3\xb2\xc9u\xa7aE\xb5\x8a\x16\xdb]\xb8\xd9\xee0\x02C\xa0\xe5\xcd\xf0\xdc7\xb0,Y\xee\xb3.\x9b0\xf7_~\xdel@\xb0p\x93\xe3\"\x19\x12\xb5\xabk\x92uP\xa4De\x1d\\JZ\x11\xd6Y\x7f\xa4\x0cY\x832d\x918\xc2\xb2.\xba\xd0-7L+\xabG\x07\x8f\xcf1\x04+\xf9\x8d\xf1/\xde\x81\xe0\xf2\x8a\x1a\xde\x8ee<\x93\x83\xbd\x87\x8bY\x92\x12\xb0:\xe5\x81\xae\x0e@\xdb\x95>\xf3\x04\xfb\xd8\x88\xe6\xf9 ?\xde\x88\xe1\xe3\x8b-\x01\x0e\xfcE:e\xa9s$\x07P\xce\x86\x04E\x07\xed9WUC\xac[\x99_\x85\x89\xb2e\x1d\n\x04\xd0\xb8\xe7-\xf4\xbcJ\xe1!\x16\xac\xb9\x05q\x80U\xfb\x90(\xa7\x18\xa8\x0d\x07*M7R\x04*\xcb\x01$()\x86\xa5$\xb1\xb5\x8b\xc59\xedxeW\x95\xf3\x85\xe5_\xb7K(\xfd\x15\xa6\x8c\xdc.\xae\x81\\\xc5aG\xa1\xf3\x1b\xa3R\x92\xadJ\xbc\x94\x14\xc4\xcbd\x02\xea\xdc\x92\xa9\xe672\xcf\xa6\xbe\xf4\x06d/\xb9\xa4\x00\xa5\xfb\xf5po\xc4%T\xd4\x10\x06K\x15O\x81\xd8\xc5\x8f\xd18H\xab#\x93\x96\x84#\x8f\xc4\xf9\x99v\x93E~-\x85sn\"K\xa3\xa5\xad\xe5u\xb6\xa0\\\xb4\x90\xac\xa3g\x97\x1di\xbb(`\xd7\xaa\xdd C\xbb\x01E\xf533\xfd\xec\xa4\xa8\xc2#\x13]@M\xf2\x8b\"\xb8Kk\xda\xe8\xccN-\xc5\x9eT\xda\x8d\x9a\x83 \xeb(\xe2$\xe1>\xccq\xe4\x99(\xbdx\x08\xe2C\xe9^\xc6\xac\xee\x83e\x96i\xeb\x11\x91\xf4\x8b,g~\xd2\xacb\xa2\x022\xbc3\x8a\x80\x0e\xef\x8c\x10\xcb\xc9p\x7f\x04;@\x87\xfb\x86\x0c\xc1aU\x90\xbc\x91\x95\xc1j\xb1I\x86l\xa4v\xd2\x00\xf6\xdbm6+\xf4\xb9\x1a\xe2\xa0\x1f\xee\x99\x06&8\xd7_e\x8d\x0f\xe1\xd6\xfdR\xfc\xfa!h(\x04m8\xf5\xc2\x89S\xc2\xdfE\xc3+\x0f\xbb\xd1\x17\xe2 \x1fJ\x89\x1bV\xbc\xc8\xc9d9\xde@\x87![\xff\x15=+\x05;G\xd1\x87S(*,\xf9\xf2\xdd\xb6\x0c\xd4\x8a\xe5&\xdfWG@\xca&\x03\xaf\x0f:\x12\x89\xf9\xcc\xc3\xf5\xf4|\xff\xd5\x8b'\x13\xf5s\xec[N%\x8f\xbfu\x0b\xa8\xa6\xbf\xad\x85M\xae\xd7U4\x82\xf8\x05[\x03\xde\xedz-b[\xbd\xc6\xfb\xb2\x8a\xbf\xf8\x02\xa1Y\xea:\xf91OH\x90\xfbz8\x97k\xd6\xf2\xb3\x04\x81\x84\xf3\x84\x06u\xcb\x14\x0c\xfc\xf6u3\x0b\x9f\xf0\xf3\xac\xce\xc4\xdfE\xbcv&Bx\xb6T\xfd\x0bM\xa2\x81Z\xfa=i\xa9\x10\xe4\x95\xd9\x92\xf0\x81\x06\x94\xf6|\xba\x05Y\xe2\xc1\xb9\xe5\x9e\xc0U\x97\x022_\x1f~2\xc1O\x01\x86\xb0W>\x97\x1c\xdf\x1d\x07\xfe\xf5\xf5m\x1e\xec\xff\x06\x9c!\xaef\xa7\x00\x86\xba \\\xce\xe4\x9a\x80\x92X\xe0\x02\x88H@\xd2/\xb29\xb9N\x07\x1c\xbd\x1c\xcd\xcb\xfaR\xffFFJ\xe5\xc7\x8c\x11\xbb\xa5\xb3\xaf,Gq](\xe2\x00]\xb3\xbcy\x81\xf8\x87\xce\\\x08\xc2\xc4\"jr\x90\xfe8\xa3\x05\xcb\x97c\xd4,\xfb\xd1\xf7\xaf,\x8e\xdeI\x99\xcdFD a\x89\x116\xcb\xb3\x0bD\xf1\x0f\xab\x059\xca\xf3,\x0fzG\x97\x0b2fd\x02\xc3\x97\x11\xfc4\x02\xb6\\\xa4\xe4\x00z\xb0\xdd\xcaHk\x19\xc3?\xdd\xd1U\xaf\x88\x8cG\x08#x\xea\x1b`\xf5\x8b\xbb\xcd\xa5\x00[^\xb1A\x19\x17x\xbd\x9a\xfe\x87\xbb\xe9z\xc4V {\xfaUc\xb88\xb7\x15j\x81\\^\xbd\x12\x8f\xea\x1c\x9c\x14\xd7\\zT\xee\xf6\xd6\x13\xb41\xce\x9aY\xdd\xf1-\xe9\xa4/\xf3\xac\xbf\xd0\xb3\xcbW\xdf\x0bm\x13k\xa7.\xb5\x8c\x9eu\xe6\xba'\xf0Hf\xa3<\x10\xc5>\xe0\x10v\xf8\x0f\xbfs\x9fZ\xb6\xf2\xb9\xf4E\xfb\xc9x\xe0\xa3\x14m\xe7\xa5\xf9\xd3\x9f=0\x1f\x8f\xc0\xd3\x94@\x96\x03\x06E\xef\xa4\xc9\xa7r\x0f\x98I\xbc\x18\x14\x1f\xb5\x81@X\x97\xd9\x0b\x16yG\xe2d\xc1A\x94$\xd0\x99SLX\xb0\x13Z\xb0\x98\x8eI6\xd5*\x9e;\x9c\"\x10r\x88\x1e\xf5Ok\xc9>\xf3\xc0\xa6z.\x9bpr\xe8\xfc\xa2\xa8\x96\xea\xd6\xb2\xc6U(\xe5'\xb2*\xac~\x89\xea\xda\xf2\xe3\xca\xf4\x8b\xe5+\x8f\xb7\xf8\xc5\x8c\x11\xae^\x9d\xa8K\xceeB\xa6 %\xef\xf2lAr\xb6\x92\x9c\xaf\x7f+\xfc:#L\x13-7\x19\x83\xbat\x12$\xc2&7j\xe2\xaa\xdb F\xbf\x8a\xdax;\x8fo\xd3uF\x1a\x89\x98#\xe8=\x8d)\xcd\x18o\x1d2\n1\x85\xa4L\xcf\x9b\x93q\x96O\xfa\xbd\x92d\x8ah;\x07\x8bi\xba\xba3\xb7\xa9\xcb\x12\x8d\xd0\xbc\xae\xfa\xa7 \x9d\x04U\xd4]\xf7gW0\x8e\xd9x\x06\x086\xf7\x80\xae\x02\xe5\x9a\xae\x8e\x88X\xea'\x90\xeb\xa7\xf1\x9c\x94\xa1\xc3\x9fD(^\x8c?&d\x1a/S\xf6\x13\xe7\x960\xe7\x8c\xb5\x1b\xfb\x00\xc4\xea\x88\x80\xc3\x8f\xa4\xa9\x98P\x97\x05q2\x94)\xcaS\xab\x15C\x9d\x99t]\xa5\xe4\xa7\xb1P\"\xda\xb1\xa9h\xd3\x7f\xb1\xe0\x1d\x8b\xe0#gL\xde\xdd\\\x95\xaew7Y\xa5\xebm>!9\x99\xbc\x8e\x17\xf0g/\x82\xdeU\xbbV\xd7\xbbk\xd4\xea:\xd7k\x04\xf0\x95\x125\xfc\xed\x90\xadyh\xc9b:\x18F\x8a\x1f\xd2PT\xa6m\xd5\xd0z\xf7o\xaenS\x96\x9d\xe1S\x92I\x95\"}\xb4\xb5{\xa1\xcc\x88\xe0\x1c\xf5f\x95\xbf~g\xae\xdaG\xef\xae_\xfbHo\xb8]\x06\xb5\xd6p-\xf5\xb8\x0f\xb0+\x90U\x9f\x06\xa8\xb8\xd1 \xa7?rv\xbf\x91nDGD+\xf2i\xa30\xd8\xd2\xba\xdc\xe8E\xbe\xb9\x80\xa1\x0e\x90\xa1\x05\xd6\x12\xde\xe57/\xbf\x12\x17\xed\xa1O\xf3l~DY\xbe\x12\xbaRM\xf9\xd3\x8d+\x9b\x15J\x10\xc2\xdf\xa0U%\xc1#\xbf6\xab\x11\x85Z\xb7V3BEH\xe4\x12\xd5?\xb2.+\xdf\xd5\xaf\x99t\xe5$\xfe\xd5\x16\xd4\xd1\xc2\xf4\x9d-\xf2^\x18$\x1a\x84dRh\x84t\x00\x1fX\x1d\xbe\xc3\x99\xaanP\x83zY\xe7\xc0\xb0o#`\xc1\x1b\x16\xc1\xafa\x04o\xaeA\x81\xdb\x82\x1fR`\x13&\xd4\x9ao\xc4\x0dt\x96K\x13m\x8b\xa2i\xce\x86Q?rL>oD3\xb0q\xf5e\x9b.\xbc\xa9\xc3\xcd+T\xe8\\\xab\xc8l\xc67\x0e\xdf\xef\x159\xdc2%\x1b\xac\x8dQ%\x1b@\xa3\x86\xf74A\xd7\x1d\x89y*+\x87=8\xfc*l\x05\x896\x80 0\xb7\x13;t\xb2h\x06\x02\xa7\x02\x9fk\x87\xcd\x06`\xc8\xaf\x03\x06\xda\x00\xc3<^\x18\xf0\x15$\x18Z\x85_\xde|\xd9\x19\x119B\x94\xda(\xa99\xe0\xd6&\xaf\x99\xf3<\x1c\x97I\xc0l1KW\x9c@\xa9|\xcb\xff\x14\xeb\x10\x8a,=e\x0fV\xd5y\xd9|\x16\xc9|\xcd\x14\x0eD1 SWa'Q\xd8\xechB\x1b\x9f\x0e\x96\xd0\x01Au<\x99\x8f\x0bZ\xd7=\xb5\x0c\x1aV\xd4m\x82\xcd\xba\xa8\x9e\nye\x19\xa2N\xef\x8bRL@\x83\x8aP\x1a\xa2\xa2Y\xac\x02\x16\xc4G\xbf\xb0\xd2\xbcbZ\x0e\xd7RT' \x0b\xde\xb3\x08^\x86\x11\xbc\xd7\x97\xca\x14\x08\xe8I\xc4\xcbh\xc06%\x7f\xffe\x9b\xab\x93\xd2\xd8\xd7\xc7\xb8\xe9\xbcy3\xdca\x08r_\x96\xcc8S?\xbc\xff\"\x84\xbd\x11\x0ce\xbe\x18\xca\x14\x862\x85\xa1\xa2\xda\x96\xc2K\xaf\x9aa,x\xc6\"\xf8!\x8c\xe0\xd9\x97s\x10\x0e\xe4{v#\xc8\xf7Wb\x18\xf3\xc7/\xe3dn\x0c\xbf\xfe\xc3HT\xe1\xcf\x86\x88\xf4Jr\xba\xaft\xe8\x10)\xcct\xf1\x10\xedu\x94,D\xb3\x9fW\xff\x95\x88\x84\xc7\xa5\xed!\xbf\xbeb\x81\xb5\x88\x9e\xe6d\x11;\xdf*\xd1\x15K\xf4\xa30 \xaa\x12\xa3\xd8Z\xdd\xdc\x157-R,\xbf\xdaz9#\xa2\x1b\x81\xfd_\x83\xe8\x1e\x91\xa1~{\x01\xca\xf0\xca\x9a[\xb8\xa3\xa2\x86Z/\xd6\xe5e\x89\xde\x95\xae\x11\x82@\x0eS\x18\xa0~)\xde%\xee|S\x0e\x1e\xf7r\x06\x87\"\x91\x8b@\x89\x1cQ\xa2\xba\xb9'n\xee\xb5\xf3\xe5\xeb\x97\xc5e\xd1\x83&\xd4\xce\xe1z\x1a\x827\xf6G\xcf\xec\x8f^\xd9\x1fa\x8e\xaa \xa7\x11\x9c\x10.ZP\xed\xcd/T\xb0.\xa9\xe4A\xb7\xa1g\xd5\xb0\xd6:\xdc\xf8\xf8\xaci\xd4\xf9\xe7o/he\xf2qw\xe6\xa9L\x10v\xd0YY\x1d\xdd\x85\xe6\xf5\xcd[\x1b\xdc\x90\x18\xe2\x94ks\xe1\xe2\xeba\xf5\xb7\xd2Y\x18b6\x9b3\xf1R\xfeV\x92\x89Qe%\xfa\xbfuK\x1b@M\x9fk\x9eli\x1f\xd7l\x03v\x9dT\xff\x84\xcc\x17l\x85br\xf9c\x001\x95\xa2\xf6/\xa4\x9d\xf2\xb41UO\x8dq{\xd1*+\xb5\xb0P\xffM\xb3j-\xe9'\x9a]P\xf8DV\xd0\xfb\x1bl\x03\x81m\xf8[\x0f2\n\xfc\x97\xc2c\x8b\x91\xbc\x06\xbd\xad\n|\xb2\x98~Y\x8b\xc3\x8c\x14\x1ez\xc3\x9a1\xa1\xbeD\x85\xd2ku\xe0V\xad,\x846\x9a\n\xe7\xe0\xa0Z\x87v\x1d\xe6\xda\x1ax*\xd7\xed\x1b\xc7OCZ\x9f\xa9\xccS\xea\xca\xac\xd8\x9a)\xeb\x9ci\xfb\xe8\xae\xcd\xf4\x86\xb4\xfd\xce>\xae\xcf\x1eX!\x91\x07\x06\\k:jZ:\x00])e1Y_uk\xd8\x8dS\xbc9v\xf3\xdf8C\xe25\xc1\xff\x84 \xa1\xbeA62\x0dT\x1b@\x06\x0d\xf8\x1a\x04\x1ap\xa8w\x82\xcc\x16z\xd7j\xc0\xb1\x15\xa8\x8c\xc5\nuxO\xd7\xed\xd3\xf2\xd7\x19a\xefT\xf3o\xa7\x9c\xb4\xd8\x11E\x1b\x7f\xde\xcc\xe4\xed\x17(\xb2\xec(\x99--\xfe\xebu\xdd\xcb\xb0\xaf\xee\xf6\xde\xa3\x93D\xcf\xab\xb3\xc2\xdd\x993'\xfd9E\xff\xde\x94\xcacgk\x1c\x94\xc9\xe9\xf9\xb3k'\xa7O\xae\x9d\x9c\xde\xc5\xc1\x97\x92t<\x99\xd8\x8b\x11\x18\xb6\xa6\x17 S7 \xb7\x82-\x04\xe1\x16\x19N\x9b9\xa4\xeb,zF+[UFK\x0bUy\x1b\xeb`\x97\x0f\xda\xe5\xb73*Jdk\xd5\xb2\xab\x9b?'\x18\xd4\xa2\x1e\xf0\x9f\xd5\xc3V\xf9m\xf5\xe0\x19!\x8bF\xf1\xed\xfa\xc3F\xb3\xeaV\xfd%c\x01\xef\x8c\x1aJ\x8dg\xd4XA\xbc\xbc\xdd\xae \x9eQ\x8f:\xe0\x19\xed\xdb\xeb\x80\xe3CW\x1dp\x16\x144\x82#\x8ey\x05\xbd1\x07\x93\x82\xa2-Yf\xd0\xf6\x96D\x02Nq\xfb\x9f\x88\xb0?\x9bZ\xbd1\xa9\xaawL\x98U\x9a*\xbeH\x9a\xaa\xb8Vg\xbb\xf1d\xe2\xdb\xee\xa4\xc0\x9aq\xac\xac\xbcC\xb7\xb7CH\x026\xa4\xa3\xb0}\xec85\x8a\xe5\xb1\xcd\x8f\x1d\x8b\xfa\xc6x\xec(\x07\xa9Z$\xc1p\xb7yx4\x96>\xa1\x8c\xe4\x05\x19\xb3\x9b]\xfe*\xa3\x12\xf3\xab\xbd.0\xc4/\xbeC6\x94\x98NeS\x18\x9f\x17\xcb~-,0\xf0\x14N\xbfg\xd6'\xe7$_y\xb4\xac\xae\x12\x1dJ#\x8cE\xf5\x0b\x02 \x90\xcd\x93\xa4\xc5\xa6$\xeefZ\x1aHR,OY\x1e\xff\x7f8\xf2o\xc2\x91\xeb\xc6ry\xa2\x08&\xb2\xbai\x14Q<\xa4\xcf1\x85`\xc43G\xab\xe5\x10\x81\x93\xebi\xf4$9H7I=/K\xaf6\xd1q\xafCM\xd3\x1e\\[\xe7T\xdf!Y\xce|y\x819\x0d~.\xbdw:Nf\xde\xee\x93\x95\x8f^\xc2\xd08\xebn\xff/\xd2 \x15\x7f\xadz\x85iZ\x85\xb61\xcf#3t\x90c\xcc\xb9\xafa\xd88\x1d?\x85Xk\xc4\x9b\xea\x80L\xf9\xb0;\xd5[\xc5\x7f^\xfb\xb3\x99\xc2G\xf65\x8f?\x91\xe0\x0bu>8\xfb\xa48FM|J\xdb*\xa01\x8d`\xcaq\xac\xf7\xf7\xbf\x9f\x9c<\x7f\xfd\xfa\xe3\x87\xc7O^\x1d\x9d\x1c\x1f}89\xf9\xfb\xdf{mG\x90\x05\x7f\xbb\xf0P\x1aM:\x11\x81X\xaa5\xb1f\xb5&\x05\x05U([j\x88\xb1\x1c\x9c<4\xa5w<\xae\xf0|\xc1V\"|\xba\x04\xa3\x9f\"b\xd6\xbd\x17\xebJ\xae\x85#\x08\xa3\xcaf\xdf(_G\xd5\xb4\x88\xc8\xea]\xad)\xf3M\xc2}\xee\xa4Kc\xcc;\x10\x8c\xf9xg40\x99j,\xed\xce\xbf@\xa5u!TZg\xb4\xd2d]\xfc\xbfM\x93u\xe6\x86_\xa9\xee3\x14X\xd4\x7f-\xe8pJ\x95\x03\xddBSj-*\xa5\xd6\xa2\xae`R?\xeb\x0f$k\xb0\xa0\xba\xcej\xe1\xa3\xf0Y\xb8\x14>\x8b.\x85\xcf\x82\xaa}\x08\x038\xa7\xf2\x06\xdf\x8a\x88\x92\x11\xb0`N9q\n#\x98\xdf\x9cFh\xfe\x97h\x84\xe67\xa9\x11\x92\xfe\xf7.\xc5\xd0\x9cV~\xfa\x82r\x9f\x19(\xf7\x8aFp\xca\xf7\xc9\xdc\x83\x16\x9flJ\xd8N\xffC\x84\xed\xc2 \xcd\x95 l+>\xde\x13\x1a<\xf7/\xbby\xf4\x05\x84\xed\xad l\x97\x1aa\xe3\xb7\xfaKZ\xcc\x92){\x9c\xa6\xbe\xd1\xfc\x97\xde\x8a\xee\xa7nE\xf7)\xad\x1clO\xf5\xbdvA\xe5\x0d\xb9\xd7Np\xaf\x1d\xd1\x08.8\xb5<\xba\xb9\xbdvt\x93\xbb\xe2\x98\xc5\xe3O0\xe4\x1bb\xd4\xde\x10G\xd7p\x05\xa9\x1b\xe3g$6\x14\xaaG\xbd\x15\xd1\x92r\x93\xf0\x81H\xbcNvv\x1e\x84\xf8\xbd\xf0\xaa\xb2\xef\x058\x04\x99\x84\xc6\x14\xf7W\x1b\xf9\x82\x90O\x1b\x01\x88\x8f\xba2\x1c\xf2_\x86\xec\x1d\xad^\x96\xc5\xac\xab\x97J\xdbP\xae\xaf\x9f\xd6\xa1\xd4\xf4\x95\xce$\xb8\xfb\xb7[\xedD\x1a\x03\xcc\x07\x1e!0\x9bo\xc1\x0e\xecq\x88?\x12j\xc3\x9d\x9d\x10?\xb3\xf1\x05\x98Y\xa5lcH-\xb9\x0f\xf9\x825\xd7\x82_\x86D\xcbu|\xb4\x04S\x96\x9c6\xae\x87\x16o\xd5\xac\x18*\xef\xd6\xcb\x9f3\xe9\xda\xff\x98\x9a\xc5\x93\xd6\xe2=\xe6\xa4\xc8C0\x91\xead\xb4u\x05$\x0c\x05G\xe4^\xbf*\x07I\x87\xd4\x82\x0c\xb8\x19\xba\x1d\x9b\xaa\xe4\xed\xcb\xf0\xa0\x0d84&\xb2\xe4\xd9P\x00*4pT\xa7\x10\xeb\xdfN\x9d\x0f-2\x8aw\xca\xc0X\xdb\xfa\xb3\xc6\xfa\xd3\xeb\xae\x7f\xdb\xfd\xba\xb5\xfeYge*\x1de\x8b4\x19\x93`\xcf\xdd\xa6<\xa66i\x97\xa3\xa1\xa7:\xca\xd4\x95\x0f\x067\xbb3\x9d\xa2\x8d\xd67\x9fF\xb6\xb8\xce,6\xb12}i|\xb6D\xa9\x06\x06m\x82W\x9c\x15q\x83\x8d#\x89\xcf\x91\xc9\x89\xca[\xe9\xe8Q\x0e\xd6\xc7\x15\x8cbq\x11\xa2\x7fe\xd6p\x7f\x08jM\xd7-TeG\x17\xa49\xfa*M\x8f5\xc6\xaf<\x99\xf2\xda\xc9\x84e\xce\xb2:\xc9\xe2\x07\xcd\x83\x10\xeff\xee\xd3\xdd\xbd\x88yc\x11\xb3k\xad\xdfcj\xaa0\xddX\xc3\xcd\xd4V\xa5.\xa9\xad\xb9\xaa\x10\x94\xe3\xeacZMH\x9f\xcc\x86a\xc8\xfa\xcc\xf6,z\xa8\xa3kkAe\xdc\x81\xbe$\xd5\xd1\xa2y~\xb9\x90\x82\x8a=\x977\x10!\xaf%\x13\xccU0\x08\xd5\x92 \xe27y\x07\x13\xe85Y?\x1d\xa9\xd7l3\xb3\x0e\xb1\x9a\xa9\xf1\xec\xcb\xfdNn\xcf\xc8\x84N\xaf\x7f\xc5O\xe4]\xf1\x03\xb2\xdf\n\xd0\x91\xf0\xec\x17\xcb`Q\xd1\x98g(Z\xead\x1e\xba\xb2\xf393\xf3\xf9D\x05\x1c\xa1\xd6\x15\x85\x9a\x01\\\x1a\xa4\xf7c\x1a\xc1S\x93\xde\xf5\xc3\xe3\xa7/-\x9a\xd7O\xfc\xfd#\x0fi\xffq\xe9\xae\xd7\x91?\xb4.\xf3\x7frf\x94\xa9\x98\xe1L\xe7\x84\xb3\xa6\xa3^V\xd1\xbf\\\xfc\xaaS\x07\xbf\x94\x81o\x9d\xa7\xee\xb1\xd0\x03\x1cs\x80<\xa6A\xcb=\xc5\xd2\xe8\xbbnq\xb1D{\xabYR;\x9c\x86\xa8\xa3cCjH\x84k\x85\xa4\x9e\xbe\x8bU\xbc1\x0d#\xa8\\&\xb5\xd0\x88\xe3\xd5\xfc4K\xb1B\x82\xeby\xb3\xadf}|\xfd\xd7':|Z\xaa\x17?\xf9h\x03?\xb9\xb4\x81\x9f\xba\xb4\x81\xbc\x0b\xdd\xb6\xf6D\xb7\xb5E@\xfb\xcf+\x02\xf91\xe2\xcbDM\xe9\xbfdJl\x8f4_\xafH\xe0bE@.8\x91\xb9qE\xa6\xed\xeah_\xaf\x8d6zh0\x06U\xbe\x07\x8b\xe9\xcdi\xdaV\xd8c\xa61\xad\x15\xc4\xbbm\x9a\xc0\xb2\xe7tB.\xc9\xe4\x98|\xf6\x00\x8cF\xe2\xdf\xcb\xa8s\xbf^^\x1c\xfb\xb7\x8e\xc01\xa6\xc2\xf6\xd1\xccc\x82\xdf\x9e\xfa\xa4\x07\x9c\x85Y-H6\xc5\xfc\xda/\x8eQ\xe7\xc8\xff\x10\x16\x1e\x0b\xf8P\xbb\xc4\xdf\xf1\x9d\xde\xdb7\xff-\x13|\xfb\xa6\x9c\xe2\xdb779\xc9\x97du\x0dAC\xf8\x13\xd8\xfa\xa4\x93F\x8f\x1eU\xa3\x10\x98\xfcS\xcc\x89\x1aX\xcc\x1b\xa0\xebI\x0f1\xa1\x89\xb9<\xb8aXB+\xb4\x19,j\xc8\x125W\x9c\xa1\x84\x8ay\xbbYh.Sc\x18\x08\xe7@|6o\xa3oRZR\x04=\x84C\xe8aE\x028\x80^\xd4\xb3c2\x83\x01\xf4\x0czTu} \xa6\xbbp\x9c\xcaR\xfd[{\xe8\xb2\xba-,%\xfc_t3\xdaR%\xa4\xb4I\xe1\x9a\x96^4x\xe6\xf4\xda\x9c%\xc8\x1d\xe0\xc5\xb7}\"\xab/ ?\xcf\xbdVt^\x93C=\xd0\xaa\xdcb\xf5\x94\x9d^\x9d\x89\xb3t\xc3\x0d\x16A\xe6\\\xe0\x06\xae\xb5\x1cT\x1e\xc2>\xe6G\xe4\x98\x02\x07b\xc3\xb6\xb6\x83\xae\x06\xc0\x9a\xb5\x0e\xe4\xc8\xe0\x10\x82LR9l.\x94\xed\x92\xb2\xf4\xad\xa8\x18\x988\x0b2\xe7\xfe {\x9f\x9c\xcd\xd8\x86pS\x84Ig\x84*C\x94\x9b>I\xaeG\x9a\xdes\xab\xdd\x1dl\x83\xc6^\xfcq\xb7D*=\x19\xaeWWh\\\xbe&\x06?\xb9\xde!\xc1\xb9\x91\xcdz\x14yYD\xac\xdc\x1b\x8a\xa5\xc2LY0L]\xe5^5&\x9a3\xb3\x06\xe4\x80\xb9\x1f\x94\xba\xbf\x80\xd6\xfc\xee\xd5\xcb\xe9\x92\xbd\x8a7Q\x0f\x88}\x8d\x1e2\xbb\x11\xec\xecy\xf5\x92\x14G\xf3\x05\xf3\xb11\xc8^4\"\xae\xcb\xe9M\xc9\xfd@.c\x9d\x19\xf5\xe0EmFH\xaf\xd9\x8c\xb3%m\xee\xfc\x8e\xf9<\x0dH\xa5J\x12\xdb^\n\xb0\xe2\xe3\x0d\xf4*\xd8\xfb\x13_\xf6T\xf6\xefK\xa5@\xa3T\x1fI\x10V\x06)W\x06<%\xe5\x98\x88w\x17\xeb\x8a\xdf\xcb\xbc AU\xa7\\T\x12\xe7\xbbR\xcfy\xec%\xb5i2\x97\x99\xddU\x97\xa3\x94\n\x9e\x05\xba\xb9\xcdR!\xefJ?o}V\x8f|^\xc6\xe9&\xc2\xd69)\xc9\x86W\xfb2k\xa6\xc7V\xd3\x1dN\xcdk\x8b\x81Z\xfd\x13L\x97W+\xceDHu\xdf\xcd)\xd6\xab\xb7\xfeN\xc3\x86\xaa\xd5\xcd'\xd6\xaa\x1at\xf9\x8e5>&\xc6<\xa0\xea\xba\xf2\xe4\xf7\xc4.}\x93m\xb8\xdf\xa5\xf8\x81;|\xa3\xd3\xa5\x14Y6\xe7,,\xd5\";xn\xea']V\xc2%m\n\x97\xbc\xefa\x16\x01\x1d9\x05L/\xd6\x8aO\xff%\xf1%n5o\xf4M\x84=T\x8dQc\xa9]\xf3\x98\x1agd\xc7\x8a\xe8 7\xb3z8\xda\xb2\x99MF\xb1!rx\x0e\xa5\x02\xdc\xa6\xe3\xf1_-\xcf\xa1\xbc$r\x05\xfdF\x91o\xcc\xbc \xe8\x1f\xfb5\x9f\xc6\xec\xf5\xb5\xa51\xdf5\x02m\x13\xffb\xae\x93\xa4\xae&m\xabk\xea\xbb6\xb2\xd6Bn8k]\xc7\xa1\xae\x895o\xf1\x8d%O\xd9\xe2\x06ga \xd9\x1f5)\xc1WD\xd0\x8f\x12\x7f\x8c\xe1\xa7\xdd\xab\x0d\xcc\x90\xf5\x82y\x1e\xd8R\xa1\xa4.\xef\xfa\x14\x1f\x9fa]m\x9b>5\xaa\xfcd}\x07\xfe\x9cz\x0e\xddTnZ\xf8\x03c\xa1MUa:\xabU\x98\xee\xcc\xb6\x9c`\\\x90GV\xe4\x00}\x1a\xb1Z:\xc6-\xa9\xa4\xc4I\x04+\xceJ\xafB\x14\x13V\x95\xbf\xa7\x19D\xaee\xf1:\xad\xce\xf2l\xb9\xf8w\xb0\xe2~6\xbc@f\xbb{\xc7P\xd5\xc5\xf9wO\x06\xde\xc8\xb9w\xe9\\\xf8\x95\xb59w\xfe\x99\xe0\xdc\xbb\xf7\xb5~I\xf0\x04\"\x04r\xbd\x86\xe1(\xc4\x18\x06\xccY>\x8c#HFp\x00\x89\x87q\xd0A\xc7\xec0P(\xe8G\x81\xb3:\xe5\xed4?U\x14\x8cD\x90\x04&\x12\xa9.\xcb\xf87\x165f\xf1&r\x06\xd2!\x99py%b\x08V\x9e\xbd<\xdf\x84\x86\xab~\x9e\xd3M{J\x8a\xe3\xe5\xa9g\x81\xcfR\x06\x1c\xd8|\xc2\xcaJ)\xc2\xea,y\xf4J'\xe4\xb7\xb4\xe5y\\&\xc6\xd9 \x9f\x96y\x8a\x0b\xce\x0bm2\xc9\xc05K 3m\x96ay\xd3\xffT\xfbDVo\xa7\x1b\x0c\xa9<\xd483\xb7\x11$o\xc0H(\"\xce\xfd\x8f\xf8\x9aV\x86\xef\xea\xe7-)\xd5\xa7\xdbts5Z\xab\xe4W\x1f\xf9Y\xff\xfe^^g],\xbc7\xae\xb11\x97U\xbb\xefy|\xb9A\xaf/\xd8F*\x8cy|\xb9\xe9\x99\xfa\xa2\x96\x8f\xc8\xab\x13?\xa3Yk\x06p\x08\xef\xa9pa\xf9\xe8'(\xcd\x13z\xfd\xe9\x88\xee\x98\xe8\xcewn9\xd9\x18\x13\x8d!\x8f`n\xbe\xf8\x94,6\x80\x9d\xd6\xfe\xeb\x98\xcd\xfa\xf3\xf82\xb0T$\xb6t\xd6\x14\xbe}\xa5\x04\xcb\x1e\xe3M\x06D\xbb\xe3=\x90\x9fgI\xba\xa1\x99\xa1\x1c\xccO\xd74l|J\x16\x1f)K\xd2\xcd\xba\x15@WC\xdeL\x05%\x12\x82m\xd6_\xdb\xcaa\xc8\x0c\x06\xe6\xfeX\xfc\x89l\xb0\xbc\xacf\x80\xb8\x06J\xf1\xfen\x18\xa5x\x93\x9b\xa3\x14\xff\xeaKP\xea:\x92\xc4?\xbc\xb8[\xad\x84\xd1G\x8aj\xdeZ\xf26\x8c\xac\xec`x\x15;\xcd\xac\xdaeuq\x91.\xab\xc7\xe6i\x05Zja \xd8\xb1\xbb\xb5sY\xcf\xbf\xa3\xec\x7f\xc9\xb8\x19\x04\x1f\x82*\x91e\xd7\x0c\xb5f*\xe9\xa7\xfc\xf6\xd6-\xd8\xde\x8eQH\x95\x0dZ\n\x95\xab\xeb*\x8c \xb6\xbeq\x15\x81^\x06\xe9\xbfhU\xb2|\x93e!5o,\xfe\x9d[\xae\xe5\xd7\xd2\xe1Q\xa2.9N\xcf(K\xfdB\xdf\xa9e9\xd3\xee\x0f\xc0?\xe2Q\xbf\x9c\xd1\x8f\xfae\x89\x95\xd0/e\xba\x89;\x8bS\xa9K\xe8\xf0kE\xaa<\x1c\x1aUD\xa3\xac\xdf\xeb7\xd1B:\xab\xfa\xbd\x9d\xe2\xdb{\x1d\xae\xad`\xdaki\x04\x05j<\x0f9i\x1b\x0c\xe0\x8d\x14s>s\x8c,\xf0\x05\x91\xe6o)=C\xfe\x0b\x16\xb7\x8b\x088)\x80\xf1\xe1\xe6\x9aW~\xf0\\\x97\xa9(\x0f\xad\xcd\x98\n\x15C\xb0!_\xba\xb9\x186\x8b\x8b\xd9\xd3l\xb2\x81\xa3\x0b\x9bU\xd9\x05\xb0\x8a\xf3L\xcf6\xd0\xcd#@\xb9\xbd\x84\x83\xf2`\x00{p\x1bv\xcb\x8d\xe6 ]\xcaL:\xeeT\xf0\xf9\xb9\xf2\xa36\x16\x0ea\xcf\\\xf5\xb6|M\x0c\xcck\xf1\x1b\xdf\xf0\xd1^\xa2\x90~\xe7\xee\x9d\xfd\xef\xf6\xbe\xbds\xefN\x18\x95\xb7\xe1\xe1C\xd8\xbb\x07k`\xf0\xe8\xd1#\xd8\xd9\xbb\x17\xc1\xdd\xfb{\xdf\xde\xbd\xf7\xdd\xee7\xcd\xf7\xeeh\xef\xdd\x89\xe0^\xf5\x1c\xd3\xb9\x07\x0c\xb6\xe1\xce\xb7\xf7\xef\xee\x7f\xb7\xbf\xf7\xdd}Xs\x98\xfe\x8bo\xe9\x7f\xc9\xcf\xf6\xeeG\xb0\xbf\x7f\xf7\xfe\xb7\xfb\xfb\xf7\xca\xe6\x8f\xe5\xe7\xd8M\xf9\xe6\x9d\x08\xee\xec\xdf\xbf\x7f\xf7\xdb\xef\xbe\xdb\xfd.\xd4\x9bpl\xb9@\xe7\x0f(\xd6\xba<\xdc\x10j0\x80;{\xf05\xe4\xb0\x0d\x9fi\xf0\x94\xe0\xa6yJ\x02\x16\x86|F\xf6\xce\xc1sw\xaaKh\xc5\xaf\xd1K}R>\xdd\x943\xc2\x8e:;\xd8\xacq\xcfvCc9k( \xa2\x89\x14\xd6\xee4\x95\xc1|/~\x10\xc9\xc9\xb4\\\x00\xfa\x1b\x1f\xe8p\xaa\x02\xbc?\xd0\xe1+\xfe\xf7\x07i\xb2(\xf8-\x19:*n\xcb\xc0\xea\xf2\xbe\x1e8\x04\x03xF\xf1IB\x8b\x85\xc8\x8d\x8f\x9f\x1cg\xcb\xbc\x9eW\xc6\x04\xb2\x86\x12I\xba\xb7\xd6g\x87\xad\x8fgqBE\xdb\xd2\x96)ng\x94\xc5 F\xa5\xe3\x10\x84\xee\x12c\xc4s\xd3)9M\x93\x0dB#K\x01\xe5#\xb3\xae\x84I\xed\xb38j\xb9\xf7\xfbZ\xff\xedT1\xb7\xcb\x02N\xe1n#\xc3j)M('\x89a\x12A6\xb2\x17\x9f\x06\x10FU\xcd&\xe9)4\xce\xe3\xc5\xcb\xba\x0f\xb2/\x8c\xae\x01\x04\xbe\xeeMXt\x89\x19-X\x88h\x04\x07\x10\xb0\x93\xeb\xec\xd6\xd7\x14\x93\x9btf\xeexn\x07\x92\xdaI\xf5\xbe,\xed\xfc\xde\xd9\xce\x90E@F^\x8d\xbd\xb1\x90\xc3\xe6\xd9\xdc\xb1\xd9\xb6\x88O2.h\xc3\xd32\xac\xf773\xac\x9d\x1b\x1e\xd63\xf7\xb0z\x05\xd2\xc0\x9a\xf1\x03\x0e\xe1\xc5\xf1\xdb7}\xf1(\x99\xae\x84\xdaVRK\xcf\xdc\xa2\xaf\x9c\x04\xf8\xd8\x9a\xc9\xd3\xd2\xdc\xc7N\x0c\"\xf0\xb0\xe4\xe0\x08<\xc2\xbfw\x90\x9d\xf3\xea\xe0\xb3G\x07\x9c\xf5\xd9\x86\xfd\xfb\xf7\xee\xde\xbds\xef\x9b\xfb\xdf\xc16\x04\x843d\xf7C\xf1\xe7\xa3G\xb0\xdf>}\xeb\x0b%[{M\x87\x0bu$\xbe\xae\x8eD\x19\xa8\xc5\xef5\xceD\x91^\xa0|\xd08\x14;\x89\x9a\xec\xb6\xb1\xb0\x0c\xa3o\x0f0\xfc\x161\xa5>p<\xd82s\xf2\x93/M\xdf\xe0\xa73\xbf\xd1\xc0\xa9=\xbf\x93b\x9a\xd0 JO\x9e\xdd~\x817\xdd!:\xd3\xc1\x01\xec\xb4\xfd\xffLfN>*?\xc3\xd5\xb9\x9e>S\x99\xa8\x9c\xa3\xd1\xd2\x0c\x97{\xc7\xcb\xd53\x8d\x0b\xf6\xfc\x9a#+\x8dq\x7f\xd9\xe8n\"~\xc3\x13qn2~\xc3\xb7\xcb\xc5\x06}*Dm\x86\x15\xd9\x9d\x98\xf9:U\x96\x02.u\x8a\xa0Z\xb1\x10\x98\xf6j_\xfe\x89\x15\x8c;\xb23\xf2\x8b\xa8\xec\x8c\x9c`\xef*\xe7~t\xce\xafRDt\x04\x85VI\x15\x959\xa3\x03{J0\xef\xc9\xd1\x1eB\x0e\x07\x90\xab\xd0\xfdc=\x02x_94\x88\xd61\xc7\x81gP\xb0r\xee\xfc\"\xf2Qz\xab\xfe\x15$\xe4:\x8e\x9f\xa2\x9a\xbdW\xeb7\xe4\x9a\xe8\x89\xfd\x1b;\x0d6\xd2k\x87\x88\x82\xaa\x14]]\x0b\xa5e^\xafG\xd3\xdc\xba%\xf8\x8b\x99\x96dU\xe1\xed\xb5\xfc\x11EUmKV\xa5M\xdd\x117s^j\xc1\xe3\xd1\x00v1\x07\x85%\x90\xc8\x02(d\xbefUt\xd1\xce^\xf5\xa5<\xb4Z\xd5\x14\xc1v\xc61\x92/\xb2b\x13\xd3\xe6\xf5\x93|\xf8\x99\xf5\xaa\x12\x03%\n\xec\xc3\xd7\xea\xd7\x0e\xec\x89\x02\x03\x0e\xcb\x9f-\xf5\xa1~)\xa3\x01s\xca\xe5\xeaJ\xbe\xd8V\xd79 \xad\x8d`+\xc1R\x00b]Eh)\x17\xd1\xb30\xd4\x92\x96b\xb3\xf2\xbe\xb3\xe5+\xde{\xe4\xca\xa3\xa1C\xd4l\xb6\xf3\x06i\x84\xb0\xaa\x19\xd0~\xc7\xfe;'\xefo\x0f\xbd\x86\xfd\xac\x84l\xc6!\x1b\xc3\xff\xe5\xb2\x03\xdfz\x1c\x07\x92\x9a\x0b0\xc6\xfc\x1e\x88w\xe0\x10>\xf3\xb9\xc7\"\x1d)Zm\xd4\xcfL\xa5\x8c\xed\x02\xbf\xd3ZbIU^Q \xefm\x9c\x92\xf8\xdc\x87\xf3Rf\xb9!\xefbd8\x94C\xc7bq\x1e\xe5\xa5 \x00J\xff\x12\xc1\xcb~6EgZ\xebg\"?\x89\xe6\x9d\xef}\\\xc3\xbf\x8e\x1f\xf8\x9e\x11\xaa7\xed\xde\xe3y\xf2\xffq-\xbd\xeaK\xf5\xc7+\x1a\xb9\x90\xcd{\x0c?'l\xe6sN)\x99G\xef\xc5\x8do\x9c\xa7S\x01\x02\xed\xf1\xdbL\x96\xb5;W!\xa7\x08Uz\xd8\x89\xd27\xe87\xcb\xba-\xef\xd0q\xbd=\xfc\x8dy,\xc4 Q\x0bZ\x9a\x95\xbd\xe4\xb4\xeb\xe6\xd31T\x9d\x86\x9b\xd9l\xd8|\x95\xc3\xcd\x03\xda\x89\x96g[\x94\xd0\xaeY \xf4\xc7\x9a%A\xbf]3)\xfc\x1a\xe9J\xda\x10\xef\xbd\xac-\x9f\xb8\xf7C\xadiq\xef\x84\x18>\xbe \x86\xaf\x8fH\xf3\xf36TT~\xb9\x03\xa0m\xb8\"P_\xb4\xef?\xcd\xd2\x94 \xa4\x0f\xe0\xd4\xe0\x03\x81\x01b\x1f\x0d\x0f\xf4\xb4\x92\xefX\xfb\xb9\xc8\xcb\xb70<\x91\xa9\x02\x8f\x8c\xa3d\x07P\x18\x1e\xe8Y%\xe7\x86\xe7\xef\xc98\xcb'\x07\x90\x9b\x9e\xc5\xf4\x8c\x1c\xc0\xca0\x89\xf7dAb\xde\xa4\xe1YR\x1c\xc0\xccp\x7f\x9agsLmkK\x97|\x15\x01\xe9\x93\xcbE\x96\xb3\x02\x93\xc4 \xac\xbcr\xfb\xb4\xf5\x96\x05\x81\x82\xe5\xc9\x98i\xf9i\x94 ]\xdbn\x9a\x0f\x8d\xdeQ\xb3u\x15\xfb\x16G\xb0\x8c\xa0hn$L\xc6\x1e\xb00\x82-\xe3\x1e\xe6]\xa7m\xfa\xa7\xa5\x01C=OX&L;\xca\xf3,\x0fz\xaf\x13\x9aL\x132\x01r9&\x0b> \xc8\xc6\xe3e\x9e\x93\xc9\x03\xe0\x93d3\x024\xa3;s\xf5\xe2\x84\x9c\x03\xa1\xe7I\x9eQNu1\x02\x8b\xbf4]\xa6)\x10\xde*\xccIQ\xc4g\x04b:\x81x2Ix\xb3q\n3\x92.\xa6\xcb\x14.\xe2\x9c&\xf4\xac\xe8\xf7\x0c\x14\x9b\xa4\x05q\x90\xfc1\xe7i\x9a\xc0r\xf8\xf7L\xed\xfcfP\x07\x05\xeb\xe7d\x91\xc6c\x12\xdc\xfe\xbf\xc5\xed\xb3\xa8\x9b\xa8AE\xd8\xc6\xc3\xe9\xf6v;\x84\x17\x90\x8a\x85a\x9f\xc6s\x0c\x8dxN\xcf\xe3<\x89)\x83\x9f\x92,\xc5\xe4\xdb\x86\xfc\x92\xad;l\x96g\x17\x90\xf6\xa7y<'\xc5\x87\xec\x1dV\x91\xd9k\xa6b\xd3\xb0\xfa\xcb\x91\x98\x06w\xee\x86f\xdc\xcd\xaf\xdf\xba#K\xa2L~>!\xd3\x84\x12\x95\xfc\x9c\x8bE\xbd\x93\x13R\xbc\xce&\xcb\x94\xf4L\xa4T:I5\\\x9e0\x8f\x12\xe7\xbb\x9ef\xf3yF\x8f.\x19\xa1\x85\xcc\x7f\x8e\xf7\x1bwH1\x8e\x17XS\xf1UB?\xbd\x8b\xb1\xae\xa2J\x9d\xdf\xba]\xcc\xe24\xcd.\x8e>/\xe3TV#d\xfd\xd3e\x92N\xbe\xcf\xf2\xf9\xb3\x98\xc5\xe2\xb5,g$\x97OY&o\x92<\x89\xd3\xe4\x0frL\xe2|,\xda[\xc4y\xa1\xff>#\xec8\x9e/Rr<\x9e\x91\xb9\xf8\xee\xaf\x17\xc7o\xdf\x88\x9d\xd1\xe9\x01\xc6\xf2U\x07\xb3\x8c\xb6*D5\xab\x8eF\xe8\xa8o\xdd\x82^\x86\xbd\xf6D\x11\xb2\x86\xb1\xa0\xb7\xa4b\x9fNzp\x00\\\x82*\xf8\xc6\x8d\x97)\x0b\x03\x16\x86\x8ex\xd7+\x18\xc7l<\x03q8\xb6\x1e\xcb\xef\x1a\xd9\x1b\xae\xf8^\x16\x03J\xa6\xabNH\xc8F\x8e\x05\xc3|$\xf9f-\xa9<\x1c4\xfb\xc6\x1e\xe2<\x8fW\x1bt@d\xb3\xe8]\xa3\xff-\xeaI\n+\xefp\xd4\xeeH\xb0%\x92O\xd2z\x03b\x0eM\xe3\xabr\x84\x1eT\n\xae\xe6\xb3\x9eAB\x0b\x16\xd31\xc9\xa6\xb0RK\xd2\xe7[\xd2\xf5i /\xc6\x01U\xcf\x86\x8b\xb7\xd2\xb2)\xce\xb8\xcb\xb4\xbc$\xec\x8b\x8c\xce8\xdb\xea\x95\x8a\xd9\xac\xde4\xd5Nd\x98`\xf0Cv\xcc<\x0b\x05)\x15\xa3)\x87\xbb\xd2\xfd\xecF\xb0\xacP\x91\xb4\xb3\xf3v [\xe6\xf0\xc5!3$\xe80\x14\xbe\xeb*\xc6N\x879\x17\x0f\xc90\x1f\x89\xf4\x8at\x99\xa6fMt+\x13&\x82\x8cf\xf9\x1c\x0f\x0f\x81s\x03\xb8\x8c\x90N|O}\x91\xd6<\xc1vOIQ\xd2\x9dc\xd9\xc7\x92\x8eo\xbe\x175\x11\xaff\x9b\x99\x9a\x8dT\xe2u\xbc\xf0A'+\xca4\x93\xfa\xba\xf4\xa2\xf5ue\x01_Y\xa1\x8a5\xe5\xee\x84?\xdb\xa5\x84p\xc8\xef\xb1\xcb\x7f\xdb\xa8K\xc5x9^\xa7\xee$s\x1e\x08Y\xd7\x81 U\xda\xfcn\\\xdd\xa5\x18r\xb1\x01\x98\x8aU\xc1\xc8\xfc\xc3lI?\xbdN&\x93\x94\\\xc49\xf1E\x9c\xee\xfd\xcf\xfa\x93\xa4X\xf0\xb3I2\x8eH\x97\x9cp\xe9n\xd4\xf4\xb2\xd3\x82\x05\x1d[\x08\xcd\x93\x01 0\x959\x0b,\xbel`\x14#\xccw\x0d\xe7\xa0\\#\x0e\x80e\xf14\x9btC\xf9\xbcL\xb2\xa5\xaal[I4+55\xc1\x05?[.\xf8D\xfc\x93\xa8+\xe0\xec\xf7Ty\xd4m\xe8\xf5Bc\x06\xa5\x10\x19pK0\xf3\x95\\f~\x82\xf9l<\x8c\xce\xa9N9\xa5\xc0\xe1\xbc\xa7\xfc3\xd0\x8a)V/\x8a\x13\xb2\x0d\x0eu\x9a\x11\x99\x83\xc0p\xec2\xce>\xb0\x91\x1d\x96\xf5^\xfaI\x81\x9dQ\x91\xf8\xfe\xa05\x88\xf6\xfcg\xc9\xd9,M\xcef\xdd\xdc\xa5Z\xe1I6Fu\xab\x99\x01\xd9\xaa\xf8\x8c\x9e!s\xaf\x08N`\xe4\x92=\xcd(#\x94\xa94\xac\x8f\xe0\x1e\xb9S\xc5\x03\xe9\xafX'\xdf\x8d+\xb5\xec0\xba\xd2@\xa4\x83\xab\xfa\x88\x90\x0b\xdf\x8dP=\xb2\x1c\xee\x8e\"\xd44\xecE\xa8@ \xfd\x84R\x92\xff\xf8\xe1\xf5+\x91q\x18\x16\xa8V\x10r\xb2\xa8g\xbb\x80\x87\xf0\x0d\x92\xc9\xdf~\xc3\xfdJ\xa5\xe7\xdc\xd8\x99m\x86\x03\x84\xf7\x94\xaa\xae\xb7\xb7\x8b\x910\xafM+\xd8\xecE\xb05\x86\xf5\x1a\x16\xf0\x08\xbe\x15\xbd\x08\xaa\x80w\x87\xb7\x7f;\xbe\xddg\xa4`\xc18\x8c\xf8\xdb\xfc\x83\xdb\xc3\xaf~\xbb\x18i\xf7\x83\xdem9\xb2\xf5\xbal\x80\"iN\"\xf8[\xefo\xa0\xdcN\x92\x08z\x7f\xeb\xe9?\x97\xc3\x02v\xe0\xee\x08\xb6\xd1)\x9e\xf2g\xbd\x9d\x9d\xdf.\xefp\x99\xbc\xba\xf5\xf5\xed\xdeh\xb8\x18\xb9\x8de\xb8,SQ\x98\xa1\x1f/\x16\x84N\x9e\xce\x92t\x12\xc4\x9a\xc8}\x94\x12\x8efA\xafX\xc4\xb4\x17\x86\xfd\x82\xb0\xc7\x8c\xe5\xc9\xe9\x92\x91\xa0W\xb0\x15\xaa\x03\x86\xbdq\x96f\xf9\x01\xfc\x9f{\xf7\xee=\x80iF\xd9\xce\x05\x11 qO\xb3t\xf2\xa0\x17\xe1\x8a\xe1\x7f\xfa\xabxo4\\\xc0!\xae\xdd\x1d8\x84}8@\x08\xdf\x87C\xb8+\xff\xe6\xf7\xef\xc0\x01l\xdf\xfeW\x10\x07\xa7\x05\xcb\xe31[\xa7I\\\xac\xe9d\xadL\x0fk\xbeg\xd7E0_\x17$g\xe1\xe1z\xc9\xb2p}\x1a\xc4\x05Y\x93\xb3\x84\xae\xb3,\x0dHL\xc3\xc3uN\xe2O\xeb\x15#\xe1z\x8c\x8f\xf9\x81\xb3\x9e\xc5\xf9\x1aE\xdb\xc9:\x8d\x8bb\x9df\x94\xac\xb3\xf9\"]g\xb4`\xeb\x8c\xb2\x84.I\xb8\x9e\x90\xe0tyvF\xf2\xf58\x99\xc7\xe9z\x9c\xc69YO\x03\xbe\xc7\xd7$\x0f\x0f\xd7 M\xd8:\x0d\xc8Y\xcc\xc8\x9a0\x12\x1e\x86\xebI\xb6\x9ed\xcb\xd3\x94\xacI0\x9ee\xeb\xb48L\xa6\xeb\xb4 A2\x0d\x0f\xf9<\xb0\xf6\xe8\x9a.\xe7\xebsB\xd9\xfa2\x18\x93\x05[\x93\xf1z\x11\xa4\xc98a\xeb,g\xe1\x9a\x91\x80N\x8a5*M\xd69\x0d\xc3\x90w\x9d\xa6l\x96g\xcb\xb3\xd9:N\x0b\xb2Nh\x9c\x06\xe9\x8a\x0f\xe5\x92O'\x8b\xf9\xd7\x01\x89\xc73>\xfb\x84p\xb0e\xf3\xf5\x92\x8e\x03\xbe{\xf9\x00\xcf\xd2\xec4N\xd7g\x19\xcb\xd6g\xcb8\x9f\xac\x93`\xba\x9e/\x02\x81\x03\xc5Z\x1b\x04\x0d\x12\xb6F\x95~p\x92\xd11 \x0f\xd7i\xc2\xa1\xb5dk%\xfa\xacY@\xf2i<&k\x92\xd38\x0d\x0f\xc3\xc3u\x11\xae\xd3 \x9e\x9fN\xe25a\xebl\xfci\x9d\xd1\xb3p=\x0f\x92q\x9e! \\\xa3\x8ai-\xd4\x08\xe1\xfaM\xfcfM\x83xN\x8a\x05o)f\xc99Y\x93K\xb6&\x17\xeb$]gl\xbdL\xd3p\x9d\x05\xc8\x16\xad\x17\xc2\x10\xbe\xce\xd7K\xb6>'y\x9eLH\xb8^\x04\xf1\xf8S|F\xd6q\x1e\xcf\x8bu\x9e\x9c\xf3u\xc93F\xc6\x8cp@\xb0l\x9c\xa5\xeb\xe5i\x9a\x8c\xc3u\x1e\xc4 \xc7\x98 \x9ed4]\xf1\x85\x9b\xae\xcf\x92\x82\x91|\xbd 1[\x7f^&y5\xefb\xbc$k\xa1b[\xb3|\xb5\xe6T1\x0c\xd7Ep\xba\xe2\x8b\x1f\xa7d\xb2&\xe9t=\xcbr\xb6N\xce(\x99\xac\x93?\x10<1K\xc6kT\xe7\xacY\xbe\x1c\xb3\xf5\xf2\xb4\x18\xe7\xc9\x82\xad\x97\x0b\x92\xafWt<\xcb3\x9a\xfcA&\xeb\x8b\x84\x8dg!\x87\xe8|\x91\xf2\xc1\xcf\x08]\xcf\x92b=\xcb\xb3\x8b\xe2p\x9d\xc7\xb4H8\xd2\xe4K\xb2\xceW\xeb\xd5\x82\x041\xee\x8f \x99\xae\x93\xc9\x9a\xc6s\xb2\xce\xa6a\xb8^\x064\x18K4\x9f\x90i\xc0\xd9E\x8e'\x19]\xa7\xa4(\xd6\x85\x18#K\xd2p]\x90u\x91\xf0\x05:\x0f\xe2|\x9d\xe4l\x19\xa7\xeb,\x99\xacQm\xca\xd7\xe7\"\x18\xcf\xe2\xfc\x84\x89\x01\x91\x9c\xacgIJ\xd6 \x9b\x85\xeb\xcb,_\xaf\x12\x92N\xc2\xaf$\x01\x9cr~iw\x14r\x16T'9\x8a\xdc| \x97\xecM6!\xc14\x0cC\x91Al\xc1)\x94\xa0\xeb\x9cF\x1c\xf0\xf3c\xaa\x1d\x00{{\x0f`k\xb8\x17\xc1\xed\xe1o\xb7\xff\xbc\x1a\x06\xbf\xedl\x7f=x\xf8\xe8\xe0\xc1\xfa\xb7\xdf\xfa\xd1\xe1\xd6\xad\xbf\xff\xfft\xfa{{\xf8\xdb(\xac\xdfhPhI\xa0\xc7\xbc\xe3\x0cS\x93sR\xff\xb0\x07[x\xceH\x12=.\xa9\xf3\x98\x1fS\xdb\x90\xc26\x12\xe8m\xd8\x1b\x95\x7f\xee\x8f\x90 \xffvyg\xbc\xb5\xb3\xd3So\xf2{\xb7\xbf\xae\xff\xbc\xcdi\xe1\xff\x11-\x8e\x86;;\x8b\xd1\x03\x87\x07\xcf\x14\xb6\x070\xf6e.\x8d2\xda<^|\xc8\x1a|\x97M\xf5as\xb1\xe4\xc7b#\xc9~\xf9\xcapo\x04\x87\xf5\x9f\x07\xd0\xfbDV\x06\x96D)\x06\x0d\xed\xef[\xdb\xdf\xaf\xb7\xbf?\xaa1[\xaf\xe3\x85\x89\xe1k0\x90\xaf\xe3E?)\x84\x96\x04=\x81\x84\xf7\xc3\x06\x1cd\x9dc\xa4\xa2\x82\x0dE\x0b\x89\x89g\xe4\xfd\xd3*\xef\xfd^\xa5\x11\xea\xcfI~F\x02\x93\x14x.\xa3\xe5\xbbG\xc3\xdf\xe4\x8c\x155V\x07\xe2O\x0bK\xf4\xbc2\xecl\xed\x99\x9fM-:]p*=K\xe6o\x11\xc1\x04\x06(~&\x9a\x96RE\x06\x04!\xa6 \xe4\x83\x0b\xf8\xb6\x9e\xd4\x1c\x85\xc2\x07r\xd8..\x8e\xf72\xe3\x14\xc3'8\xfd\\\x8e%\xab\xc62C\x17Y\xe7Ws\x0e\x83\xceP\xf63|k\xaf\xe3\xad\x15\xe7i\x83\xb3\x08h\x99m'\x82\x9c3X\xc12\x82yS\x0d\xad_mTPB\xc7\x8a\x0b\x1d\xb1r\xfe\xc0\xec\x87\xb1H\x9a\xb72s\x83\x06b\xa1\xab\x86\x8d\xdf\x8c\xa5k\x05r\xe5\x86\xef\xa7\x9c\xfbHm\x18a\xc7\x15~ma \xdeI_n\n\xedo[\xe2\xe6\x8e\xee@\xf1\xf7\xa14\xe0M}\xe1\xd0\xba#\xc7\x14\xb7I)\xb9D\x8e\xf4\xfb$%o\xe29\xf9>\xcf\xe6R\xa6y\x96\x14\x8b\xac@\xe3\xeb\x8f$\x9ex\x94\x95W\"\xde\xedi\x92\x12~l\x0fz\xc1\xf0_\x0fF_\x87\x0f\x0e{\xb7\x93>\xb9$c\xa3\xe1\x00\xcb\x9e\x08\xdb\x00g\xea\xebm\x94MT-\xd8\x88\x93\xaa\x9e\x82\xcdh\xb2\xa1F\xaa\x8c\xf9\x19\x94\x12n\x99\xa6m\x08-\xe2b\x1c\xa7O\xe3\x82\xc0\x00\x9e\xd6\xef|/\x07\xd9 \x1a\xd9\xc3\xd3\x80Tf\xe2\xdf\xfa\xc3\x7f\xf5o\x8f\xbe\xfe\xea6\x17%B\x93\xc6*\xa6 K\xfe \x1f\xf3\xb4\xb3\x07\x0e\x802vlK\x8b\x1d\xe3\xc2\x9a\xd0u\xb8ekM18\xd6{\x0e\x8dG\xf0\x19a\x8f\xc7\x9c\xcb\xe7\xd8\x92gi\x9a\xd0\xb3\xf7\xa4Xd\xb4\xe8\x86F\xe3$\xab\x14\xfe\xfd\xa4\xd0\xb4\xff\x9a:\x84/\x8dMcP?\xf6\xccoV\xfa\xa5\xbaCx\x97Wry\xc2\x15,\xceY\xf1s\xc2fAo\xbfW\xea#u\x15*:\xe9\xf5\xc6b\xf7\xf4\xf04\xfd\xf3*\xac\xb0\xd0V\xa8\xc1LlK\xd5N\xd0\x93]\x88&\x8dv\x12K\x1b|\xcb\x06\xd40.s#a\xa9|\x93\xa6.5v\xa1\x0d2CVA\x887\x9b\xb7\xf1dB\xc8\"]\x1d\xb3\x8e\xbaLmJ\xf3\xdeP\x86\xffye\x0eLi\xe0hf09\xd9\x15\xdaU\x1cQ\x1edC6\xc2\xbdr\x08\x13\x92\x12F\x80\xdf\xe1B\x0d\xff\x87\xf3\x03\xe2\x0dj\xcce`\xcaV\xabl\x03\x06\xb2\xa7\xa2!\xbd\x08\x89)`\xd6\x95\x19HV We=\x95Y\xd7r\xa6X\xad\x16\xa4k\xc1\x89\xb0Z\x94\x87\x12 \x1d\x0c\x84F|s\xad\x89\x08\x84}o\xdf\x00R\xc5\xect\x19$\xcdQ\xc2\xe0\xe2\x13\x88#\x15\x03\xebS\xf4\xbd\xf8\x90\x95\xfe\x1c\x1ek$\xbe\xb1\xac\x91\xd6\x9b\x15M\x1a\xa6\xbf\xfa{\xe7\xb2\x92\xe7I@\x83oL>\x12ctH\xba\xf7\xcd\x9e\xe1\xd9T~x\xef\x1b\xa3{\xc5B\xb9f|\xbbkz<)\x1f\xdf5=\x9e\x95\x8f\x8d\xe3:\x97\x8f\xef\xdf36>W.%\xbb\xf7L\x8f\xcfpV{\xdf\x99x\xff\x95\xfc\xf4\x8eqR\xa7\nX\xfbw8\xe2\xd7\x9e\x97\x04\xfa\xa4\xc3w\xe1\xd6-\x0c\xe1P\xbeU\xd2\xb5\xd8\x8c\x8b\x12\xa5M\xa5\xea\x9bQ\xf3\xfa/\xbe\xb0\x170\x80\xf2\x08lO\xe5\xc8\xe0\xc0\xd3\xad\xd9o\xc9\xc8fsL{\xb06`]ndv\xae\n\x047&on\xfc\xd8\xd9\xf8\xd6\x16q\xdaW}(\x95c\x0dtO\xa9\x89\xfa\xc8\x06\x86\xa7\xce\x91\xf2~\x17U\xbf\xfc\xe7\xd4\x7f\x18u\x07\xaeN\x16\xce\xa1\xf8\xd9\x8c\x8b\x18Z\xc4a\x0b\x8br\xc7\xda\xf8\x9dz\xe3wD\xe3NN\xbcn\xa2\x97} \xefQ\x7f\xc8\xca\x87\xeb5 `\xcfk\xc7\x88\x0e-\xab\xfd\x18\x9d\x84\xab\xfc\xdf\xb4b\xbfM\x9a\x15\xd0\xfd\x00\x86\xd4\x92\xf6\xces\xa3\xc1!h\x02AR\x04\x182\xc5Q\xd5\xcaq\xf9\xa05\n?\xb6\x06|\xfc\x0e\xf0\x08'\xf8i\xd6&\x06\x82{k\xd4l\xeb*`\xb3\xc5{\x99k\xc3\x1cR\xceY\x0d\xa9\xc1\xeau\xd5\xdc\x12\xeds\xef\x93\xc5\xe1\xb1s\x7f\x80\xb2\xa7\xc2#\xa8\xc2\xc4{?\xc5\xe9\x92\xc0|Y08%\x90\x92\xa2\x006\x8b)\xc8\x96\xbd\xca\xd9?\xb68fn0\xa6\x87\xf61\x9d\xa1\xc2=\x97\xc3\x12\x8d{\x0d\xeb\xad\xd9\x85\xb4\xfb\xb4@9\xf3\xf6\xbfv\x0e\x7f\x9bl\x07\xbf\xf5\xf9?\xe1\xa1\xb2\x0chRjc\xa01H\xb6\xc7gp\xef,>\xaf\x9b\x8d\xcecP\x14#\x01\xcf<\x87\xf5\xc1\xe4\x9b\xeb7&<\x95\xb6\x02\xe2\xf0)\xb4Cn\x9a\xa4\xc4k\x80\xaf-\x0e\xc5~c\xec\xb1|Iz\xb2n0?D\xa7qZ\xe87\xb6v\xb5\xbf\xf7\x14#o\x1b\xf5\xa9\xe8\xdek\xe0\xcf\xcd\xce\xd1~\xe3\x16\x835\xa8{\xecc\x93/\xfb\x0c\xedw\x9b3\xb7\xdf\xe0\x92\xe2M\xfc&\xe0\x9f\x95\xce\xc2\x8e\x95V\xcd{\x8d\xec\x8d\xc9\xef\xdcoTJ\xd8S\xa2F\x9fe\xaf\xb2\x0b\x92?\x8d\x0b\x12\x84\x11l\xdd\xfe\xd7\xf0\xcf`t8\xdc\xdd\xf9.\xde\x99\x8e\xfe\xfc\xf6j\xa7\xfc\xfb\xae\xc7\xdf{\xfbW\xc3\xf0j\xe4E\x18\xf8\xc8\xbd&\xfc\xde\xea~\xefOL+\xde\xc4\x8f\xce\x8b.\xbc\x86\xf7\xcc\x1a3\xb0\xf9\xf06 \xf9\x1b\x8c\xf0\x95%\xd2\xc1{|[\x94\\\xc0{rvt\x89\xfe\xc8\xae\xa5\x9dfi\x9a]\xc0Bv\xd2\x83m\x93\x03{\xfd\x0co\xc7et\x8e\xec\xba\x9c\xed\xad[\xb5\xdfv\xae\xd6\xc6\xf1\"\xab\x87\x94\xe74\x9b\xac\xa4RY\xa8\x17\x13\xda\x13N\xf2\xf8\x0b\xcdX'\x97\xf3\xb4\x87\xee\xf2\xda\xcd\x9eEU\x99T\xea\xce\x9c\xa0\x9b\xc2\xc4\xf6j\x0c\xc2;J\xbe^`\x84\x8b\xe8\xc8\xa2\"\x8e\xcb\xd5\xca\xedv\xc7X47\x97|\x8e\xa5\xf3\xb1\xf6\xa6d=,oN\xab79q\xb6\xbd\xb6\xa8^\x9bf\xf9\x8f\xe0,\x82\xd3\x08N\"\xb8\x88\xe0(\x82\xcb\x08\x8eG\x0d\xe1\xd59\xf6J\xdfd|\xc5V\x92\x0eYB\xe4\x9f\x9f\x86\xcd\xb9\xbf\x97\xb4\x1e\xa6 I'\x90\x14@3\x06\x8b<;O&x\x02\x98(\xb6j\xf4\xdc5X>\xf1\x8f0\x80WA\x16\xc1\xb9\xc3%\xe1#\x1a8\xc4x>\xfa\xba\x1a\x80\x1c\xc2\xa4\xda:\x93\xae\xd1|\x86\x01\xbc\xe7\xa3\x998F\xf3Y\x1b\xcd\xe7MG3\xeb\x1a\xc2\xf70\x80g|\x083\xc7\x10\xbe\xd7\x86\xf0\xfd\xa6CXV\x00q\x96\x1d\xe1\xa3\xf9\x03S]a\x91\x11\xfbh\xfe\xd0F\xf3\xc7\xa6\xa3\x19W\xa3\x19w\x8d\xe6 \x0c\xe01\x1f\xcd\xd81\x9a'\xdah\x9el:\x9a\xfa\x91\xd85\x9e\x9f\x1c^K\xeaB\xee&\xf8 5\xe41#;\x8c\xcbQ\xd8\xfc\x02\x0e\xe1\xf7\x00Uh\xbd%\x176\xca\xbbo\xc4\xdd\xe7\x82\x88\xda\xf9\"u\xc9\xd9\xfedsb\xa9\xc8l\xfd`\xeb\x9a\xdf\x8f0\x80\xd7\x81\xab\xda\n\xce\xee\xc7\x0d\xc6\xf8c\xf7\x18k\x87g\xd7\x10\x7f\x86\x01\xbc\xed\x1e\xe2\xcf\x1b\x0c\xf1\xe7\xee!\xd6O\xe8\xae1\xbe\xc0\xec\x8d\x9dc|\xb1\xc1\x18_t\x8fQg\xb0\xbaF\xf8k\xc7\xd0N\x91\xf9)\xd90\x9f\x81\xfe\xaax\xd6\xe74\x18\xf6\x12F\xe6E/\x02\xc1g\x8f0\xc9N\xcb\xcc\xdd\xe5\xe9\x01\x9a`\xd5\xb5\xed\xf8U\xc3\xa4_\xd1E\x82#\x0b\x86\xaa\xd6\x97P=|'\x1f\xeaT\xe0Wd\xc0\xf8\xd3\xe7\\\xa8\x8c\xa4\xb9]\xac\x83{\xb0\xfcJDVKC\xde\x95\xe6\x85\x995\x0e,\x99\xc4\xd4\xe5\xac7\xdb\x89\x13\x1a\x83\xdc\x85\x12/a\x00\x1f\xba\x91\xf6\xa5\x0f.H`\xbd\xf4\xa5\xc6V\xab\xb7\xc1{\xa5\x9dF\xc1\xcd))7\xa3/w66X:Az\x05m*\xf6\xb7\x0cZ\xa6\xf8g\x0e\xef\xdb\x97\xf3T\xea\xae\x98U\xbeK\x84\xcf\xd5\xe5<\xc5m\x8b\x7fa~\x12\xd7\x9a\x0b=\x0f\xff\x86K\xf9\xf2\xdb?\xaf\"\xfe\xfdW_\xe5d\xaa;\x03\xac\x16\xe8\xb4F\xfa\xb8\xaf\xc5\x9f\x0b\x91\xcf#!\xf2w\x95\x16\xe6]\xf5\xe4\x10\xfe\xf6\xf0\x907~N\xf2\"\xc9\xe8\xa0\xb7\xd7\xdf\xed\x01\xa1\xe3l\x92\xd0\xb3A\xef\xe3\x87\xefw\xbe\xed\x1d>\xfa\x8dJ\xb7v\xf8\xe5\xf5+ \x97\xb8\xc40\x8e)g>O \x9c\x11\x8a\xc9\x19' B\x94\xfef\xf5~R\xd7yY^\n\xa7\xd3\x9fsQ \xb8\xfd\xdb\xf1\xd7\xbf\xdd\x0e~;\xde\x0e\xbf\xba\xed@\xf6\n\x88\xb2\x84\x94'*C\xddXx\xa6,\xb5\x93\xa7\xa8/\xfb\xe5\xf5\xab#17\xe1J\xe2\xe3\x01r.\xcb\xaa\xd5\xdb\x13\x9b\xe0\xfb<\x9b\x8b\x8d \xdbk\xcfH)\xc5l\x92]\xd2%\xd9%a\x08\x87M?\x98\xa4\xf2\x83\x81\x83F\x8eJ\xe9\xa3\xa9\xa7?q\xba}\x9d\xcb\xcc\x86\x7f\x1at\x85 \x93\x17V\xe2|\x9a\x8d1\xcbN\xbf\xc0\xc6-\xfa\xa5Joi\xdbZ=\xa1\xa4w)MD\x16\x94byZ\xb0<\xd8\x0b\xfb\xc5\"MX\xd0\xbbe\xd2\xc6\x80\xee\x9f\x9eCB\x81\x86@\xfb\xb3\xb8x{A\xcb\xdc7\xb9pS\xc4(\xc3a>R-\x0e\xb8XE\x86\x132\xce&\xe4\xe3\xfb\xe7O\xb3\xf9\"\xa3\x84\xb2 \x1f\xee\x8e\xc2\x11\x0c \xe7T\xe8\xd6-0\xbe\xb37\x12v\xd5\x9e\x0f>\xa9m\xdd^\xb3v\x1a\x1b7m\xb5Z\xc5\xfd\xca\x97\xab\x81\xd0\xd6\x8cD\xca\xfdA\x0f\xb6MO\xc9\x90\x19\x0d\xb3\xfd\xdf\xb3\x84\xe2\xf2\xb4\xa7&S\xf5\xb8\x07\xa5\xe6S\xcb\xb9\xa1r\x17Sr\x01$`\x9a\xb9\"\x82\xde\x92Mw\xbe\xed\x85au\xb7w\x1a\x17\xe4\xfe]\xd3\x18\xaa\xd4A\xed\xae3\x0c6K2Z\x1c\xe3[6\xaf\x9d8]\xccb\xcf\\\x83\xa0\xbb\x8f)m\xe2\xac\x17\xe2\x16J \x07h\x9c\xf3)i\xcf,G\xb6yc\xce \x9be\x93k\x8fF|n\x1b\x8fz\xea\xcdD\xb4\xc7\xc8\xe2\xb3\xbf\n\x9c\x8d!{\x0f\xd2\x80\x99\x8d\x14S~\xec\x8c\xc9I\xa5\x8a\x8d\xe6\xe4\xc7z\xfa+_^b\xf5\x10\xd1\xd8\x96\x1c5\x88\xbd\xeao&x\xbb!\x8d\xf8\x06\x8dL\xfb3\x0f\xb5\xc4k\xfb\xbb\xb7\xcf\"\xe8m\xf7\xc2\x91\xdc\x9f\xa6%\xb5R)\xe6\xda\xd4\x86\x94]\xb5\x95\xb48\xd6\x94J3N\xb8f\x15\xe1\xa2\x9aSN\x97\xcb\xc8F\x1e#\xf5\x91\xd7a\xae\x94b\x96\xbcd^\x04\xd8X\xa0\x063\x8ektL\x9a\xb31\xa5Q\x9e\xcc\x03m\x91~\xc3\xecx\xbd\x13\xb4\xd8\xf4z\xae\xe1Z\xb2\xaay\x0d\x93\xc3\xec\xb4\x82\xd9\xc7\xb6{Yd\xc8\xe3\xe6\xd54ig\x9b\xe8N\xc2z\xfb_\x97;%s\xdd\xb9l\x915\xf7\xdc_9Bi\xffY\x97\xf6\xa5ui=ZK\xbb\xd8ZZ\xbd\xfc\xa7\xf2?\xd5\x83\xb2\x90\x16\x0d\xee\xdd\x0d\xfbO\x96\xd3)\x91\xde\xe2\xd7\xca\x06hN\x88\xd9\x9cfI\xa9\x8c\x92\x99\xc8\x15\x0f\xff\x7f\xf2\xde\xbc\xbbm\x1cK\x14\xff\xbf?\xc55\xa7_\x8a,\xd3\xb4$\xaf\x91\xedx\xb28\xdd\x99\xc9\xf6b\xa7\xea\xd7\xa3\xf2xh\n\x92\xd8\xa1H\x15\x17;\xae\xb2\xe7\xb3\xff\x0e.\x00\x12\x04\x01\x92rR\xd3\xfd\xde\xe3\xc9\x89E\x12\xc4r\x01\\\xdc\xfd\x9e@\x15\xcb\xf2\x13\xf1\x83\x9c\xc7\xa2\xfc\x17$\x0b(\x81p\x047a\x16\xe6\xb0\xc8\xf3\xd5x{{\xe6\x07\xe4:I\xbex\xf30_\x14\xd7^\x98l\xa7\xf4\xbb\xedi\x12d\xdb\xf8\xf1\x16#\x9fRo\x91/\xa3\xd3P\xc4nd\x94\x86\xcb\xf3\xb9A\n\xc7\x90\x1fA\xba\xb9\xe9@\x0c\x9b'`=\xf1\xd3y6\xb94Q$\x157\x97\xa2\xcb\xaeB\x1f\xb2:\xeaq5ED\xcd$\xed\x1f\x94\xb3\n\xc8\x99uG\xe2l\xa2\x99\xa4\x16\x1dS\xe5\x15\x98C[\xd2\x1a\xd8\x12\xc58j\xc4\xca\xca\n\xef\xbb\xc4\xa8'\x14\xd8\xe7\xa4\x1f\xac\x932\x1a\xf1#\x9a\xacB\x19\xcbcf\x1d\xa8nz\xf5#\xcb\xfd\xe0\xcb#\xba\x80\x11\x98\xd9\xb8\xe9/:r\xfa\xb7W\x9b!\xb7\xd0}D\xb3\xc2\xb8\x17[\xd6\x18\xfd\xf6j?\xc5H\xcfk\xb5^\xd4\xb3\xbd\x88\xa8=\xad\xca\xa8\xf2\x84\xc84'\x04\x8b\xac\xc3\x8c\x102x\x06{p\n\x19l\xc1\x1e\x8c1\xf3R\x00'\xb0w\x04\x01\x1cCv\x04\x01E\xe3\xd1$\xa0\x05.\xe5\xda&AKb\xf0\x1b\xee\xa5n\xb6\xa3\x86R\xdb3\x93\xe9\xac\xd4c\xc1\xb0\x8d\xe2:q\xd1\x16\xd0\xd4\xc4\x9eux\x8a\x03\xb75 \xdb\xe5\xdf\x1c\xdcR,h\x8a\xc3\xa3p\x8afOSzb\xc2\x7f\xd1\x9f\x05\xfd\xf9_\x90\xcc\x90Zd\xcfV\xecYV\xacV\x11=\x7f\xf2\x84=O\xf0\xb9\x0b\xe4\xeb\n\x03\x9c\x80\x1fC\xe9\xd8\xe1\xfd=\xe3\xa1\xbf=\x8d\xe8A\\z)\x19\xc8\xb3\xbch\xe5X\xc4EK\xde \xe7\xb2\xe8H\xe9\xde\xa9\x8b\x16\x97\xb0\x8d\x99\x95\xd9\x03\xdb\xacN\xe4\x0b\x1d\xf3y\x1eJ\x91~h\xb2taQ\xaeo\n9\x8f\xc2pQfP\x88\xda<\xf1\xc5E;?/\xe5W\xf3\xd6\xf2f\xd8\x1a\x82\xc5\xf5\xda\xe4\xd9\xc2_\x911\xac\x9aoD\xa07\xed\xcb\xa5\xbfzY\xbe\xef\x8d\x1ef\x88\x9c\x1ew\x06F\x18\xe5>\xb3\xf5\xe7\xb6\xb6\x87X\xbc\xd9Z\xdb\xf9\x8a\x9f\xf4<+\xb5'#V\xd0<\xeb\xdaN6\xb9\xcd\xae\xb3\xcap2\xb1V\x0dg\x8d\xae\x9f\xbf\xf2~\xfe\xca\xfb\xf9+\xf6\xf3WM\xd9\x94\xc7\xfb\xcfl\x8b\xed\x7f\xcb\xed?\xe1D\x87.\x9b\xb3\xadi6,S,d\xf6\x9a\xc7\x99\xec&&z\n~\xb3\xaf\x82+\x11|t}\xbb\xf2\x11h\x9c\xc7\x84\xfeu\\\x1f\x1e\xb3R\xa5\xef\x85\xfc}\xac\x8e_\xf4\x97\x16\xaa0+r\x1ae\xcen\xbb\x14>\x03\x06F\xac\x05\xdf}\xd0\x8c\xac\xd00]\xe2]\xce\x8f\xe1\xb4\x0c\x9e\xa7\x9b\xb0\xb5N\xe0}~\x02\xefK'\xf0\xbe\xee\x04\xde\xef>\x81\x05\xd5\x00'\x80\xa6+)\x0b\x9e\xc7\x8c\x1c]\xe1\xbd\xcb\xe2\xb3\x9e\x02QQpm`2\xe2\xe5\xc9\xe8\xa5\xe3\xb14u\xa2\xc0\xf6\x1b\xe7\xe3\xad\xcfl\x9f\xb2\x15 \x18S\x16\xc6\xac@\x88\x05<\x94\x97\xb0\x86\xebk\xad\xb1\xa2\x98&A\n\x0f\xbc1t\xb4++\xf6\xc2\xac\xec\x96\xfa\xcd\xa0\x16\\U7\xed\x99\x96\xfco\xd2ar\xf4D\xed\xec\x8b\x89\xa7P6\xa9X\xec\xac\xd5\xe44B\xda\xa6#\x87\x8f\x81X \xdb\x89\x95\xa8/\xb1\xf2_\xa5\xac\xe0\xbft\x14\x8aQ\xec\xd8\x8c;\xe2\xb4\xc2=2\xc9\x1b\x9b\xa0\xaf\xe0\xaeI\n\x02\xf2\xc6\x8b\xb4\x1b/(7^\xc4I\xdfH\"}g\x8c\xf4\x9d\xc11DG0\xa3\x1b/\x98\xcc\x9a\xa4\xef\xcc\x10\xd0i\x85\xaa\xa6\xc44\xe7\xb1\xbdj\x9ds\xbaf\x0b3\xfd\x84F\xd0\xf6\xeaQKB\xa2_3\xcd\x92X\x18\x96D\xd8E\xbf\xa2K\x00#\xd5\xfa,\x10fW\xc1'S\xef\xe7\xa3\x19\x00-#\x1ce\x0d]\xc4y_\xa5\xc9\xea\xa2\x1cS\xd6\xe8{\xb9\xe2\xb4\x99V\xca\x95s\x83\x91\xab\xca\xc8\xf5.\x92\xb8\x03\x97\xd3\xac<\xa1-,\xe1\x18\xe6G\xb0\xa4\x8b\xc4<\xa5\x18ZJE\xb27.,\xcbEL{9\xa1\xfd]\xd2_\x97V\x89t\x03\x13\xb5K\x81x'\x9f\x82\x08\xae\x12\x80w\x1d\xf3\xd0\xb1\x19\x85xC\x17.\xbb\xb9\x1f[\xb7`\xa2\xdd\x82a\xb9\x05\x13\xc7\xe5 \x10\xc1\x87cH\x8e\xc0\xa7\xd0\x0c'~}\xbb\xf9\xe6s\x0eQ\x07vU\x01r\x88:]\x16\x7f \xf3\x8d\xb8r\xb7\xab!\xa2[\xae~\xfe\xcaq\x84\xdaq\xf8\xe58B\x8eJB \x95\x14\x0c\x95\x14p\x0c\xe1\x11\x14t\\\xfe\xa4h\xa2\x92\xc2\xa4E\xe2(\x8cLrC \xe3^\xca\xda\xf6\xd2\x17r\x97]H\xfb\xc9NV\\\x08\x9a\x91 \x89\xa7e\xd7\x9c\xe6V\x8bM[\xad\xc9\xe6\xb6o5\x90\xa1\x8b\xe1~\xe5H=\xe5\xbe\x9b\xb1}G\xb1jP\xee;\x8a\x9cW\x1c9\x9b9T\x81N3u\xef\x05.\xcc\xca\x99G\xa4\xb8\xf5\x8c\x02\xc5\xa6\xe3\x08&\xb3K\xfa\xcc\xa9v\xa1\xdf\xc6s2\x8bi\xe3Nl\x92\xe5\xa0\xc5\x8a\x0fNs\xf5\xea\x0f\x98l\x9d\x9d<3\xd3\xe7\x92\x05\x8bb\xb7U1\x060\xae\xbdk\x9eK\xb1\xa9\"\xb4\xd1\xd2r\x15\xb5:G\x97Z\"\xee\xff\xa5\xd3\xfe\xb1\xc7y\xd1~\x9cO\xff\x87\x8e\xf3\x9b2\xcec%\xffi=X\xbb4\xebK\xc4x7-\x18o\xd9\xb5\xeb\xe9)\xbdTw\xfd\xc2\x85\x9b\xda\x89\x8b\x1c\xe2M\xf7Y\x0b=%J\x9d\xc6\n\xed[u\xd5\xdc\xaa\x95|G\xfeT\xfc\x925\x85\xcc~\xecQ\x8a\xa3\xed\x1f\xcb\x9f\x8c\xc3\xde\xf2\xb3,\x9cWl\x92\x1d8p\x1e\xc6\xd3\x94\xc0y\x92.\x8a\n\x01\xfdk\x14\x06$\xce\x08\xbc{sQ>\xfcq\xbb\xfc)tR<\x8d\xd9\x9c\xe4\x92)\xd7\xf9\xdd\xf2:\x89\xb2\xa6\xae\x8a\x97\xae%\xb9\x94\xbek\xea\xae\x1a\x1fp\xcb\xca\xbb7\xd9Y\\,\x19\xda9\xd2\xc2\xcdH\xc4\xe8=\xa9pS\xf3\xe6\x18\x94Z\xc3\x89\xdcp\xbb<\xba\x83\x85u\x93\x7f\x1d\x98|\x11\xc9\x04\xb1\x8e5%\x96\x0b\xd6\x1e\xb34\xd4\xc2\xee\xbd\xbf$\x99M\x9c\xc9\xe0\xb2\xb5\x0355\xf1\xef\x0fL)<8\x82\x18\x8eaH\xffR\x84\x97O\xac+\xba\x15X\x0f1\x0f\xd3\xcb\x85\x9f\xbeL\xa6\xc4\x8e\xd1t.\xd6\xf7\xd7\x1a\x0cG;\xbb{\xfb\x07\x87O\x99}KK_s\xc5\xa6\xadK\xc4\x95\xabq\x84\x00$\x0b5\xab=\x8c\x8bXw-I\x91\xe8\xc9p3\xb4\xb6\xb2\xd2\xb6\xc2\x94\xd7\xc4\xbb\x9aE\xfe<\x83'PPZ\xe5\xa5\x1f,\x08K\xa5@[\xd1\xcbxo\xcaLG\x154\xe8\x17)\xd1$\x80\x06\x11\xa7\x82%m\xc2\x82M\x9c@\xc6\xb2\xb8\x02\xed\xe7\xb55!zV\xed\xea\xc3Vm\xfb\x0d\x8fx\x1fO\xc2\x8e8\xea\x19\x02\xddw\xbc\xabi\xb2|\xf3\xaa\x9d\xa2f\x16\xb2Z\xaeN\xbepTGU\xd4\xd1\xe4\x08\xa1\x91`P\xfa\xf3\xf0:\n\xe3\xb9Yy..\xda`d'\x94\x8b\xecjP\\3\xdbw\xa1\xcd\xa3K\xbe\x02\x9e\x91FC\x08\xa8\x97Y\xe7L\xaf\xd4\xb6vF\x16\xed\xa7\xb1\x98A5\xdd\\\x12bi\xde\x9f\xe8\xd7\xe6\x9f\xf4\xdf\xeb\xb6\xc0\xb4\xb9\xb5\x19\xd1\x9aU4(\xbd92\xec~&qa\x96\xd7\xb0\x81%M\xc4\x03w\x7f#\x98\xda\xdb[\xf9)\x89q\xc3:\xb2vA\xb3\x01p?U\xc5\x0d\x83\x83jI\x91\xd2U\x11\x87q\x84U\xa4\xde*Y\xd9\x8e\x83\xd8\x8a\xf6Y\x98U>y\x02+z\x96\xaa(E\x90\xac\x7fj\xb6%\xb8\xe3\xfa8\xe7$\x7f\x19%\x19\xc9rq\xc6\xbcN\x93%\xed\xf2\x18\xa6\xaeZ\xb4Y\xa6\x9d\xfc\x12\xf4\xfeT\x1b\x97^\x82 \xca\x0b\x99I\xba\x84\x13y\x18\xc2\x9c\xfb\x87\xd5\x81\xd8\xe8\x1c\xfd\x86vLt\xb2\xabsa=\xfb:\x91Z\xc6\x98\xcc\xd6\xce\x0e\xba\xf2T\xcf%7\xba\xf2Y\x07\xa7\xc3V\x98T\xdc\x11V\xf7\xa4\xaa\xfb#\xae\x13\xd4\x8f\xda\xd6\xce.\xb6\n'\xf5\xb7\x86v\x8e\xca@\xfcl\xc5\xe4b\xc5\xe01!\xf7\xdd\x08\x7f\xa9P\x1b\x84W) \xe8\x96\xadvl\xc3nD\x14\xe1KC!ub\xf9]\xafe\xd3\nf&L\xe7\xd1\xb2\xe9\xc9Y\x1b.\xdd/E\x14\x19\x8d\xa5\xf5<\xf8\x02\x9f\xaa\x04\xa4\xdc\xc5\xea\xb0\xac\xbeR\xce{\xe6\x1d9\x06k\xe4\xedy{\x96\xaeMM\xc0\xe6\xab+\x86\x01\xe8\xdf\x13q^~+);\xd0\x19\xe0N\xac/a<\xa5|}J\xb2$\xba!,\xf7Z\x9ca\xae)z#D\xc8\x1ff\xf4n\x95\x92i\x18\xf89a\x9f\xacR\x92\x91\x18\xcbq\xf3\xffs\x9e\xec\x8de}{\x1e\x85~F2\xeb\xb2I.O\xac,\xf0#?\xc5\xb2\xe4\xd7\x82\xc4\x01~\xb7\xf4W\xab0\x9e[\x97\x1d\x92\x11#y\xe5\x82__ \xe1\x8c\xe5\xb9\xc8\x85'\xac\xcc\xe1\xe6}\xc3\xb4\xd3Z\xb6x\xd8 \x0f\x9d\xc1?\xcc\xd0w\xb7b\x1bS\xfb\x87\xcf\xf1\x978\xb9\x8d\x81\xa9.\xc0\xfa\x81\x13\xa8?X\x10f\xb0$9%\x80\x90KD\x03oHf\xac\x0cae\xfe\xf6\xfc\xdd[\\\x04\xde\x0f\xcaju\\\xc8\x17a\xe6\xe5\xfe\x9c\xae8~G'\x0f7:\xfe\xe0\xf1\xed\xf9;>\xa1\xf8Z\xfc\xbe\xbf7\x8b\x96@b\xd3\x15\xb3\x07^c\xb9.\x98[Ky'\xd7\xda\xea*\xa1\xad\xb5Z`,\xbctu[\x1fO\xb9\xf4\x18f+\xef\xd4Q\xf35\xc9\xc7-\xee\xea\xa5\xe4\xc5\x8a\x05k\x0f\xeae\xe5\x85\x8c\xec\x1cs\x1e\x95\x9f\x96\x1f\xf8B\x9e%hB\x8c1 \xaf\xb7\xb8\xaf\x08'\x9e\x90\xcb\x9eK\x93^\xfe\xa4d\xc6LR\x9f\xc6\x82\xf2\x1d\x17\xf8\x92\x0e\xab%-\xd6\x95ii\xe3Rc\x0b\xbb\\\x82b\x81W\x165\xf4@\xea\\\xd9\xbdx\xf4\n\x85\x8dvG\x8em\xdd~\xc9\xd4\xf8j\x8c+\x1f\xee\x1b\xd8\xf2\x1d\xc7cR\xdd&s\xaeM\xdc+\x99\xe3\xda\xfd\xfc^\xf8\x02G\x91\xdb\xfd=\xd8\\\xf6\xe6\xd3\xd9\x0f\xc5C\x1f\xf5\xb0cH\x1c\xdbb\xfda\xc6`\x92\xb3\xd4\x83\xe3ey\x82\xa9\x92\xd3>\xb0\xd1#\xfd\\\x0e\x15_\x0f\xdc%\x80\x19\xda\xb1\xbd\xb7\x7f\xa8\x06\xacO\xf8\xab\xa7CG+7\x08\x8dC\xef\x1f\xa3\xde\x10\x9f\xfe\xe1O\xcd_\xe5\xbel\x13\x89\x0bmD\xdb\xc1\x00\x1c\x81\xab\xf6}\x15\x11\xa7\x17\x81)\xce\xf1\xa5\xf0\xae\xfa\xb0\xb3Y\x90\x08\x05S\xb0Gz\xa5,_\x96\xf1}\x88!\xe1\xcc\xef\xfd\x8e`*\xed1\xd8J:\xb5`bH%\xeb\x19\xc1\xbck\x98\xe3\xa6@\xd5u-\xef\x1a\xe3V\x18%[\xb0\xbcj\x94EbHW\x8e\xa4\x9e;G|\x9c\x06\xe6\xb5_`\xb7\x90\xa7\x16\xf3\xb5\x88\x0e\xa0_\xbe\xaf\xee\xa0t\x1b\xe8\x18\x9bIi\xc6\xb2\xf64c\xd0\xb3i\xe0\xcb+\x14(\xd67W\xa7\x1f\x9f\xf6\xa9\xe0\xa1\x1a/\x1f\xd8\xea\xd4\xd0\xcd:\x91\xb7\xd0\xe6\xfayN\x96\xab\x1c\xf2\x04\xa6\x84\x1d\xf5E\xca\xbc\xd9\x84\xbdni`\xa0*\x03\xaa\xcdl\xf7\xa2^%:u\xbf\x1d\xc9\x0f\xf7\xb5H~4\xfc\xbf\x16\xc9K\x07\xa0^\x1c=\xdc\xd3\x82d\xf7\xa9F\x1a\x1d\xdb\x0d!u\xc1\x1e\xab\xa9M\xfaz]\xa3\xf2\xc1\x05f\xbd\xb2\x02\x0c\xe0\x0d\x99\xf7Z\x8f\xaa\xa6e\x81\xbf\xe8\x0b,\xca\x02\xe7\xfa\x027e\x81\x8f\xfa\x02\xcb\xb2\xc0\x0b}\x81yY\xe0g}\x81;8\x81)\x9cB\"\x92.\xd1\x99\xe5\xd9\x97~7e\x11\xbb\xc6h&\xa5\xb6W_\xe8\x8a\xd7\x9c\xc2\x18\x16\xf4/\xcb\xecd\xa7\xbc\x95\xdf\x1f\x9c\xaa\n\x03\x9b\x8f\x9a\x9ei)\"\xca\x1d:1\x98\x9a|\x03\xf3\xe0^)\x11\x8a\xae&\x11\xd3\xb1\x14\xf6\x1d\xaa\x7f\xe8h(\xb1\x1d\xc0)\xbe\x841\xaa\x81\\\xb8c:!\xac[k\xbf\x85\xa5O\xb14\x8caI\xcb\xd1JB{\x86&yc\x98c\x07\xb0\x9a\x13\x98\xc1i\x07c\x00\x12\x83_\xd1\xb8z\x0b?\xf9B\x96n\x11f\xb5x\x1e]\xe2\xd3\x0c\xf3#\x83\xad\xea\xd6\xba\xbe\xa3W\xe0g\x04\x06\xe3\xcerP\xb7\x8f\xd1L\xa1za\xcd\xc3\xf5k\xb6u\xf8\\\xbd\xb0\xf2\xd1c*\xd7\xc60\x92\xaf\x0ea\xb1Z\x996W\x99\xb8\xccu\x95b)f5C\xe7\xdc\xad\x94\xa3\xfa\x1a5\xdau\x90\xc4\xa1\xd5\xfebr\xd9r\xc3\xea\x02\x88\xb3d\xd47\xca\x86\xa8N\x91\x19\xae\xfe\xd7\xfc\x0d\xaa5]\xc0of.\xfb\xcc\xb6\xef\xbc\x1b\x96\x14\x1b7^u\x87\xb8\xc4a[n\xe6r\x8c\xf4\x89~sM\xff\xdb\xb8\xa6\xaf\x9e<\x01\xdf\xbev\x01\xab5\xa7(\xc9\xbc\xd7\xcci;\xf3\xfe\x02'0\xa2?\xce\xe1\x04v\xe9\x8f\x8fp\x02\x87\xf4\xc7\x0bZf\x9f\xfe\xfa\x19N`\x07K}\x86\x13\xd8\xc7b\x9f\xe8\xdb\xd1\xa1[\x93\xb70Q\xfc\xbaR09\xeeT\x85=n\xc3x\x9a\xdc\xd2!\xb1_\xde;\x0c2q\x82ZL8\x15\xef\xc7\x86\xcf3\x12a\x10e\xfaW\xfd\x14\xdf\x8dAL\x84m\x89\xd9^\x84\x99\xe5\xc8\xa6_Zq\xdb\x9c\x8b\xdb\xe6\xdf(n\xeb\xe2\xbc\\~b\x8f\xf6\xd5\xd3\x16\x03\x81\xd1S\x9eE\xcaN\xeb\x9cT\xda\xceI\xa5\xa6e\xa1e\xa0\xda=\x1aPBEx`\xb0\xb0\x96\xd9(w\xb5\xc7\x7fT\x901h\xd4\x83\xa44r\x1ak9\x9b \x89g\xe1\xbch)q\x9b\x86\xb9x[\x1f\"\x86\xa0g\x07r\xec\xd6T\xb1\xd0=wfym \xd1\xd8\xde\xdb\xd9Q\xa6\xa8\x9a\x91Z\x7f\xf4M\xeavH\x8d\xfb\xd4\x8b7\xe3>\xfd\xff\xc6\xb5\xa7\x8e\xeb\x8f_z\xe52j\x17\x15\xd6\x94%\xc3#\xc8\xb5\x860\xb9\xde\x10\xe6F\xcd\xd4\xa0\xb5NoDr\xeb\xb0\xea+\x0dUx\x8072I/\xb9\xf7\x94\x89\xe3\x01\xbd\x89\x00=\xa8\xde\xef\xef\x0d\x06\x07\xec\xfd\xfe\xde\xde\xce\x1e]I\xfc\xd7\x13`\xf2&z\xb7\xaby.*\x1c\x94\x95\x1d\xb2\xe7\xc3a\x95]J\x14\x1a\xee\x96\xa5v\x86\xb5\xcf\x87\xa3\x83\xf2\xd5p\xef\xa9\x03<\xbf\xd63\x18\x0e\x87\xbb\xc3\xe1\xd0a\x97\x04\xd3&T4\xbe\xba!\xcf\x02\x87\x9d6\xa11\x8a\xfe\x18\xc06\xc1\xb6 l\x9d`\xf9}\x07\x9e=\x83\xa1\xca\xbe\x8b\x8b\"\xbf\xbd\xfd\x9d\xd1\x80~5\x1c\x8cv\x10&FM\xaf\xce\xac\xb6I\xf5k\xd1\x9a\xeeS\xad)\xf8\x0dw6\xdd~bO\xfc\xad\xdf\xfe\xe5\x92\xfe?\xd8zz\xf9\xfb\xd0\xdd\x19>8G\xdbs\xc5\xe0\x8dR\xc5\xdb\xff\xf9/\xb6}:\xfe:\xf1\xb7f\xbc\xf0\xe1\xc3\xfd\xa4\xfc\xe98\xdb\xcaW,\xe7\xec\xeep_+\xb4n7\xc5R\xc4\xa5|\x88\x89\x1d\xf0\x14\xcc\x01\xe3\xd0w\xf6PO\x92{\x01\x1f\xf1\xf3\xdc\x1e\xe0\xb2\x88Dx.F\xabc|\xab\xaf\xcc\x946\x9f\x0c/\xeb\xb9\xaf\xe0\x140\x80\xea\x9b8\xb7\xf3\xd2D\xcf\x85\xe1>\xa5h\x1a\xaf\x86\xf4\xd5\x00\xe3\xb4\x16v\x8cD\x8f\x01\xcc+\n\xb8\xc9\x93\xe3g\xd6\xe5v\x1d8S\xe9\xcd\xbc\xfe\xaai\x02B/\xeb\x895\x06\xeb\x89\xbf\\\x1diB#[\xc7\xf86\xca\xb5/\x9f\xe1\xcb\xb9\xf6\xe5\x0f\xd6\x0f\xf4\xe5\xafE\x92\x1f5b\xd15\xa7\xed\xc6\x88S\x16\xb2\x11\xb6\xac-\xe0V\xba=\x84x\x93K\x06a\x86\x1eK\x9a\xc1\x85\xe1:\xfa\xe0\xd6dVR2Lq\x0c\xe6z#c\xb4`\x149H\xf8W\x06\xe6\xbeKum\x0coH/2\x89/y\xe4\x1bm\x19]\x0c\x91\xfa<95Z\xdb\xc5l\xc0=\xd2\xe9q\xa0[\x1368\x8e@.y\x04\xf3V \x11\xff\xb4q<\nSW~\xbe5\xcd\xa9\xeb\xdd\\\xf8xN\xd3\x9fE\xcc\"\x1d\xbek\xcfgWJ\x1e\x84b\xd4\xfa\xe5\x17\xcb\x81c\x18p\xcd\x16)\xe3,\x86.X\x7f\x1eZ\x8e\n\x99\x9f\xfc(\x9c\x9e\xc5y\x98\xdf\xbddf(>}\x81x3\x99\x92\x8fI\x88j\xea\xc2e\x9ajZ\x17\x96\x0eI/A\xb4\xd4\xb5'\x86\x9ee\xae\x9c\x18\x08\xbb\xc5\x06\xff\xd7\x1c\x03\x84w\xb6\xb1\x12I\xd80\"\x83\xa8v\xea\xc2\x8d\x0e\x19\xb51Ak\xc9\xd8\xa5\xa0\xd6U\xe0\xcbS)\xc1;\x8c\xf5\xf2\x98\xae\x1e\x19E\xeb\x0dn\x8f1K\xfb\xeai\xcbD\xeb{\x87Z\xd1\xfa\x81Z \x13\xad\x0fGj-\x8f\x93\xad\xbb\x92\xf4\xdc ^_t\x89\xd7o\xba\xc4\xeb\xcb.\xf1\xfa\xbcK\xbc~\x07'L\xb6\x8d\x923.\xe3f\n\x13!A7\x8a\xbc\xcd\xa2\xf5\xc5\xba\xf2\xf8+8\x81kI\xd8G\xbf\xb9\xae \xff~\xd7\xa5Q\xaaD\xechY)\x89\xd8\xd1+\xd3f\x82v\x14\x91\xdfA]\xd0~\x87\x82\xf6S\xb8\x831\xc4\x0eJ\xd4\xe9\xb1\x8c\xc2\xa5\x00\x8fp!&G\xc9\xb9Q\xa0X\x98\x04\x8aw\x8c\xc4\xb8c\xe2@!2\xfc\xec\xb8\x80\xb2\xc2\x0d\x9ee,\xe4\x02\xc3\x15\x06\x08\x10\x02y\xf1\xd6\xbe\xe2\"G\xa301\xf5\x02\xa6\x9eJ\xdc\xffi\xc1\xa2Y\xf5\xa5*\xb3\xb8\xeak\xa0\xaa\xc4\xf8\x06Uw\"\xdd\xa0\xdb\x96J\x00\x15\x9a}hP=\xdc\xf0\xa8\x01\xdc\xcc&\xc4\x1c\"\xda\x85W``KtM0R\xdf<\xf22*\x95\xed\x82\x85\x11\x15~\xec?\x9c\xa0\xe1\x0coH\n\xba\xec\xbb%\xf9\xe4\xa0U\xcd\x0f\x0e\x8fF\xf6\xactu?\xde.}\"\x9e\x19\x03\xfe\xaegP\xa7\xf1X\x8b\x99\xea3\xb7\x0b\xc7\x85\xd4N\xbd\x8f\xb0 \xa9\xf7\x1a~\x84\xa4=\x02\x83\xe0o,\x0b&\xe4\xd2\xa6c0\x02)gF\x03\n\x05}\x7f\x0f9w\x88\xa3_K\xd9\xe0\xeb\xc3u0 #\xc6O\xae\xb15\xddG\x15\x8e\xba\xeaU\xdc\xc3\xfa$_\x84\x95\xd1\xfa\x83,on\x9a\x19\xd0\xfab:\x0c\xa3\xb4\x1aq\xd5\xc0\x05r\xe3G\x8em\xb1\xc7U\xf5F# \xcd\xb1Y\xc9\xdc\x11\x93\xb1[\x1d\xaf\xf6\x9d\xa4\x905Q\xe3S\xdd\xe6\xfc\xfe\xa2\xc6^\x9e\xb37\"\x19E\xa3\x01\x91xb\xacMT\xb1\x08\xb3SV\x160\xf1\xf0j\xb9\xd0\x84\xe7C\x91\xd89\xf6\xb2\x15 \xceIDh/2\xcd#\xbc\xfb\xb7,i\x15\xf7\x89\xa3\xcc\xf4\xad. \x8e\xb8x\xa7}\xbb\xa0\x0cmi \\\xd7\x1e\xd25\xa8XH\xff\xfe\x80\xb1lb\x9d\xa5\x80|}H\xc3\xb1\xc6\xdeF\\\x0f\x18\xd5\xd3\xd4l\xeeB\xd8\xf7x\x85j0\xe2\xd4\xb8\xf5\xd3\xd8\xb6p\x95\xde\xa6\xfejE\xd21\x04I\x11M\xe3\x1fr\x98\x13\x16\x17\xd4r\xdc\xa6\x9fa\xb3 \xad\x17\x99@dt{\x0c\xfe\xa1\x86\xf4\xcd\x86[\"\xe3\xf2\xcdGiZ\x7f\x15\xaa\x9bO0\xae\xcd\x944\xcc\xf9\xae\xbe\xc9v\xbc\x81g!\x8d\x9fW\x0c\xdan\x17\x13f\xe6\xfe\x0f\x9d.\xeeU\x1d\x15:\xc1\xa7h\xe3\xcf\x08\x91J\xde\x8eqCE\x02l?\xe6\"\xf7\x0d\xc3\x88\x1f-R\x1c\x1d\xa8RBLy\xd1\xe4\xd1d*\xa0\xa4\x06\x18\xda\x96\"\xb2\x887M\x8e*\xa5\xfcb\xd2\xcaQ\xea\xa1\xa7\x0f\xcf$\x8f\xa6\x1f\xaco\xfa\xc4V\x16\xae\xbdL\x03[\x03\x03\xed\xba\"\x0d[s\xa9tx?\xd6\xfc\xb2\xdb\xcc\x7f\xae\x8b\xf9E\x92D2\xb3\xd9\xab}I\x90\xac\xda\xa7\x0b\xab\x1bu1\x84\xdcv[uZ\xf2+k\x80\xfa\x99-\x9f\xb23\xa6\xf1\xdc\x95\xa2\xe6\xd4\x0b\xab\xd1s4\x87\x13\xba\xb4\xa3\xeb1\xda\xe8P\xb4\x8a\xe4Qj\xc7\x8ekN\xdb_\x1e\x0d\xa2\xdaZ\x89\x1a\xe1\xfe\xd0h\xcf\x9a\x93\xdcb\x91j\xe8\x9cg\xe2\xae\xb9I\xad\xe7A@\xb2\x8c\x9e\x7f\x18\xab\xb9X\xd19#S\xd36\xb5\x90d\xe1u3\x86\x8c\x99\x87\x95\x0e)kn\xe4~Vb\x0dw\x84\xb5\xac\xc4\x1e\xd7\xa4\xbab\xbe\xa5\xc9N\xb7a\x83\xcb\x81\xce\x88,\xb6w\xf6v\xb5\x8a\x91}Uz[\xf0\xe2\xaa\xe7\x02J\x9f\xecCu\xafD\xac\xd1]u\xe4L\xf1\xaf\x96\x9ei\\\xadV\x18\xb0\xb3\x0eS\xb4L\x9b\x93\xfcc\x92Dd\xaa\xe6\x87Xh\xe4\x1a7%2)\x1f\x97'\xeb\xb2\xc1\x1d\x9cy\x98\xde\xea\x13 \x928\x08#r\x91\xfaq\xe6\xb3\xd2O\x9e\xc0\x0d0'\xff\xe1h\xc72YOP\xeem\xa2l\xdb8\xccY6\xcfq;\xe3\xc5<]\xc34\xbf+i\xdb\x8ce\x18\xc3\xbc\x18\xecX\xae}\xa5\x88\xa54\x82\xabu\x1a\xd98\xa9\x9a\x81S\xb0g(\xb5\x0d\x08%\x19\xcd\x9f9.\xdc\xdaH\xfe\x95\xdf\x9e\x18\xc3\xb0?\xa8t\xe6z\xc0 \xfc(\xba\xf6\x83/\xff\xbb \x05\xf1R\x92\x91\\\x11{<\x16\"\xf5\x9a\xe3$\x0fgw\xcf\xa3H\xad\xbd\x1a\xc8\xa5nI\xdd5\xe3\xff1\x1f\xe7j\x98\xd2\x9a\xb2\x9d6\xb8\xf2\x95\xebj\xfa\xd7\xd8\x07\xa2\x19\xcd\xba=i[\xd5R%\x1b\x83v\xdb\xa8\xeb6\xe35\xe2]-\x93\"\xce1\x15\x06lA.\xdf\xb7V{\xd5F\xdej\xe1\xa2\x88G\xeb\xab\x96\xc5\xfe\x18\x8ev-\xc4\x9c\xe2\xb9C\x7ffI\x9a\xdb\xd7\x8e\x0b\xab\xcd\xcdz%Ud\xba*\xaca\xce\xa3\x1a6\xd7\x0b\x17tR\x04:\x9b\xc4\x06\x0fQ\x1f\xe7\xe8jE\xe2i\x18\xcf_\xf2\xd9\xcb\x9a\x0c\x1c\xba\x156\x0b\x96\xb3_xQ2\xbfHVo\xc9\x0d\x89>a\x88'c\xa0\xa3\x1b\x1e\xbd\xd6\x90\x9e(\xf4\xae\x82\"MI\x9cs\xc6\x0c\xf3\x89c\x9e\x03?\xc8E\x1b?3\x16\x0b\x8f\xe4\x88\x8d\xa2\x11g\xcba\n\x03\x8be\x03,VS?',\xb8WD\x97\xd4{\x7fI\xe8\xaa\x14\x0c\\\x1e.\x89\x9dt\x19\xab\x00\x87F\xe6\xadH:K\xd2\xe5g\xac\xf7\xcd\xec=\xa1\x84\x85\x9f\xde\xd9\xa1\x8bF\x0d\xcd\x85\xcct\xa7 *n\xa5F\xcf\xe2)\x8b\x0c\xae\xe7>{D\xbe#\nf \xf1\xaf\xf4\xaf\xedO\x82K\x97\xef\xc2\xe2:\n\x03\x11\xb8\xc6V}>\xfe\xd4\xfc\x95\xd8\xb2\xdf\x19D*R\x9c\x93\\\x1a\x1b\x9f\x90\xac\x03\x8d\xf1\xad8oC\x87\xc2-4I\xfb\xe0\xc4v\xb4\x14z)\x89\x88\x9f\x11\xbb\x89\xa0\x1c\x03\xd6b_\xb6!\xa4Z\x9d\xba\x99\xee@v]\xa1\x86\xf8\xd2\xea&\xb6\xa1\x02i$\x16$\xcf\xd1\x89>M\xc6N\x88\xc2-E\\\xd0\x93\xe2\xd5R\xa1k\xd6\xf3\xa7S\x8a\x9c\xc3x~\x91\xd8w\x8a8\xef\xb6M\xcc\xc9\xa3\x0b\x95h\xf1\xfe\x1e\x16\xc6(Y\xb3\x0e\xb7:\xa1\x88\xbb\x93\x8f\x1c=\x86!b\xf0\xf6\x95HKO\xd7\xc2]9\xad\xba\xd4v\xdaN\x19{\xc3\xa8<}\xf3\xe2\xe4\xd0\x04\xb5\x03-\xfd\x08\xb9|\xd4\xd7\xd6tWG\x8d\x82\xa4\xb3\x06/`\\\xed,2V}\x81^Sn\x8cL\x19\xee\xcb\x9a\xeb\xb4\xcc\x17\xd3\xb2`\x97t,7^\xbd\xaaf\x05m\xfb\x84\xe3\xb9\xcf\x1c\xb5\x97\xe75\xd1\xdbP\xf2\x16\xc3\xec\x05m3\x8c\xe7\xbcQFFb\xa0\x81\x9c\x0b\xe8PZ\xe0]\xb1C\x03\x8b\xbfGm\x08\x17Ji^\x9c`N\xbc!\xd2\x98\xdaQ\xb5\x8ed\x16\x15\xd9\xe2\x85\x02\xd5[\x85\x19\x8a)G\xceT\xca\xcd\xe5\x88/\xf5\xf3g\x16\xb1\x88\x8b\x94L\xc3\xbe\xe5\xb4\xe2>\xbd\xb6\xb0I^\xb0\xfe\x08@\x9f\xe7\xa9\x9f\x93\xf9\xddz}9\xa0}\xd1gOQ\x00\\\x92T\x87\xf8\xc95\xdd:\xbe\xf2Es\xda\xc5GO\xe9G7\xfa\x91\xb5M\x9a\x9f\xf9\xab\x1e\xa9T\x03[\xb3\xe6\\N\x97\xf0[\x8f\xd5\xf5\xd2\x8f\x7f\xc8\xc5\xb2\x06?\xc6&@\x1cP\x10\xc6\xe0c\xe8E\xf25\x87\xdb\x05II\xc1\x87\xe2c\x08\x85\x1c\xaeI\x18\xcf\xc5\xf6\xf4\xe8\xb8\xa6%5\x80\xfds\x19n2\xb2>z\x81\xd6\x19>]C\xce\xb0\x11\xdb{C\xc7l\xb4\xc3q\xc0\x01\x9d!\xbd*\xe9\xf7\x07\x17,\xbf\xa1B\x02FytP\x06r\x13]s\xeaxU\x9c\x8c\x87G\xa84\xc5\xd3.O9\xcc~@\xc1\xf2T\x17\x1f\x07_\x8d\x86\xea\xab\xd0\x14h\xa2\xd4b\xa0\xcd_\x861!\xe4\xf7\xa5\xf6\xa4\xd3[^\xc8tUSWz=@\xd7\x8e\x95\xf5\x0b\xdd\x1d%U|\xaf$\xe5Q\xcf\xe4\xd7,\xe2i\xa9\xa0\xa9\xcc*O\xab1\x8e\x0d]]\xcf\x83\xe8\xbb*D\xc4/\xd9;\xb1\x1b\x18\xd2\xac\x9d@hW\xfa\xae\xd6)\xe3\xfd\x97\xc3JR\xe8H\x86\x00c\xd4\x03U\xddk\x9d\xc3\x7f\xc4\xfc\xad\xd1\xf7\xc7oG\xb3\xd4\x93\xb3\x97J\xc4O}S&\xfc\xd6 \xd0\x9a^Bgx\xfe=\xc6( T\x0d\x86\xe6\xaa\x84\x94\x0bTu\xf2T;\xb6\x9f:.L\xaci\x98\xad\xe8\x01\xf2\x12=\xa9-\x17\xac\xab\xdcOylVz\x1b\xfbyx\xc3\xfc+1\x96c\xf6\x8a\xcd\xf7\xc7\x94\xd0gd\xca\x9eRT\xee\xcf\xd1\x08\xee\xa5\xa94B\x1f\xca\xdd%j\xd8p\xdf\x18K\xdb\x10\x1d\xad4\xfb\xd3ft\x03\\\xd4\xa7\xd8i\x96\x01\x8e{\xe3Y\x0c\x00\xec`\xf0y \x8f=D\xc5\xecX\xfa&\x9e\xf8\x9a\xdc!\x0d\xe8\x08Y\x1d\xe6B\xf5\xd4Y\x87S\xdd\xc31l\xb08\x8e1\xb7\xde\xfb\xa9i\xbc(i\x84\xbd&\"\x80\x13\xa0\xdcU\xd8\xb0\x9aR\xf6\x1bZY\x89\xc8\x9d\x1a\xc4\x81<\xb1\xbe\xfc\x9f\x9acN\xedL\x96\\\xd5\xa7l\xc5\xfa\xf6J\x9c\xea=$L\xcdAmh&\\H \xd4\xd5\xda,\xc9t\xd5\xc4\xabw\x05}\xa1\xea\x8fl\x87\xd9\xf8a\x88\xcc:7#M\x08\xafM~r\x02h\xadf\x9e\x95\xc6\x8c\xb4r\xa7Y\x9e\xac\xa4I\xe9\x00\xda\xfa\x80P\xeaGH(\xcfZ@\xc1\xb0\xea\x0bD\xbd\xbc\xc2\xda\xa3\x13\xa6\x80\xee\xbd\xb8:\xc1\xb1\"i\x86\x99\xc4\xbb\xd7N\x98}d\x85\x19\xdaj\xb4\xd3\xd6\x8c\xfc\xadv\xbf\xd4J\xf7\x96\x9a\xd6\xa6\xa7\x07\xae\x84z\x0c\x0d\x96\xd1\x0c\xf1\x0f\xd3\x84k\xa3\xd3\xeb\x94\x15\x95\xd0\x9aebB\x146\x89//\xb5\x12\xd1j_;.dU\xe7\x98kc\xe6\xf9\xc5|I\xe2\xfce\xe4g\xbd\x1dNd\xb8\xa8\xbe'5\x1f.\x84\x8d!b\xda\x0d\x8fn\x10\x93[\xf5\x18J\x99\xec\xbf\xfc\xd0\xa9\xdda\"\x16\xf9A\x9d\x98\x06\x8c\xa6.\x8f3E&\x18\xfbR>f<\x9e\x8b\x98\xa4\x19\x908H\xa6a<\xafgD\xc8\x17$\xc6\x8d\x87\xc9\xd2\xca\xc3\x0fD\xe0\x17\x1fx\x03\x06e\xb88c\xb9\xc1@/\xd57\xffF\x18\x19\x18\xcc\x04\xf4S\x13\xb5\x88\x85\xc0\x0cCC\x8c\x9b\x1f\x84}n}\xdc<\x9b\xa6\x0f\xac\xa2\x16gp\xbd\x03\x1d\xae\xdb\x17\x0c\xdb=y\x82LO\xb9\x1e\xe4w\xcdC\xbe\x85P\xc3\xd0>\xde\xf5]N\xde\xf2l\xdd1FWA\xcf\xf3\xea1\x1cWv\xcb\xeaV\xfd!\x99\xcd2\x92\xff@\x97@R\xe4\x90\xcc\xe0:)\xe2if\x9a]\xb5MZ9l\x82\x8d\xb6\xfd\x03\xc7\xd8\x0e\xdbs\xfd\xdb\xc9\xeb\x99\xd1\x99!juO!\xd5@\nuE\x80\xae\x08n\xe0\xb1\xee1\x05\xb3\xbe'\xad\x88)oCD\xb4\x00\xcf|\xd8\xbaU4J\xe2\xda\xec\x8f\xf5\xde,\xdd\x04\xa1\xb84\x9f#@\xcb\xe8\x0e\xf7\xf7\xcc\xed\xde*\xf2\xd9a\xdb\xd4od^\x98\x9dq\xbca\xc7\x8ei\x13 \xd4bIh\x83\x1d\n\xac+%\xee\xd1\xed$\x90\xce\xd3\x01\xdc\xc3\x82M\x9c\xde\xe2\x10\xf8\xe1\x8a\xd3\x81\xc7V\xea8\xdem\x1a\xe63/HX\xa7\xdcL\x8d\xe1\x98\x11\x91\x84rZ$\xb9)\x1bUJi\x08\xfag\xf3\x04\x86t`\x18\xbax\xb4\xb7\x07O \x9f\xa4\x1a=\xd7Z#\xd4$^\x85r\xdd<;\xa1\xbc\x95\x89jy^e\x96\xf1#\x0c\xbfB\xf8\xce\x82\xc8O\xe7\x842\xa8~\x0cK\xffk\xb8,\x96\x90\xa1;\xc7\xe0+\xe5\xb3}9\xcd\xf5p\xdfAWNJ6i)\x9e\x12a\xdf\xf7\x1c\xd4\xa2u%J'\x8b\x9c;JH\xcb\xf5\xdb\xb4\x0f\x92\xd6\xdasHe\xbc0\xfb)$,\xd0H\xf31\x9d\x88\xfb{ \x06\x14/\xf7\xb4\"0\x9b\xbd\xd5\xb8\xd6W\x8c\x9e\xa5\x13r\x80\xb4\x9c\xdb\xa1\xc0\xa9\xcd\xb2'\x9a\xedU[\xbe\x1b\xc3\xa3#\xa7\x14\x0d\x1bOB\x14\x88Z~\x16\x84\xa1\xa5\x17\x8b\xb2\x12\x91\x9f\x87\xf1\xb0\xb5\xc8u\x18\xfb\xe9\x9d\xa1\x08H\x12(\xfdq\xc2*A2\xaf\xad\x95\"\x9fm\xb5\x96`\x84vg/^\xdb\xc41\x02\x1c\xaa\xe6\x82l\xd4\xde\x9f \xdb\xea(\x91\xcf\x86\xfb\x11\xe9*\xb3\xd5R\x08\xaa~\x8f\xe0\xc7v\x08.\xc8\xd7\xeeZbx\xf6\xec\x19\x18\xac\xb6\xf9t\xfa\x19\xd9\xdf\xed\xae\xea\xb7.@\n\xa32cE\xa8\xedpzO\x0cp&\xcc\xc6\x1d\x95;\xf5\xe8f.\xcf\x8f\xd6\xf8T\x95\xbe\xeb\xd1\xd7M\x1b\xc7\"\xf6\x16\xd1F\xc6\xe7riz\xfc\xb9\xe2\x10L{5\xba\x94\x98*\x83\xc6\xa1B\x01\xa4\xa4\x189\xc0\xb64\xd3h\x10\xb7\xc4\x94;L\x99\xf0\x1cOn\xe49\xe1\x99,\x91;\xc575\x11\x1d=\xdd\xb7\xca'\x87 b\xa1I\xcf\x1cV\xe1f\xecB\x98\xbd\xf7\xdf\xdb\xb1S\x16K\xf8\xe1\\\xca\xb7\xb6`\xe8\x08\x91\x80(T\xbe\xdcDZ?\xa6\x07 \xe9p\x84@\xcb\x95V8\x00\x8f\xfe$7\xdd\\\x19@\xa2\x8c`m1\xa3\xd7\xcc\xcdm\xf4k\xafk\xf9A\x8bH\x8c\xd9\xdd#\xcf>K\x93%\xe5\x15S\x07\x15\xc35\xae\xac\xc6J\xe5\x15\xfb\xb45\x841\xcc\x95\x15eX!Z\xe1\x13\xaf8\x87'H\xeb\xb8\x069\x83\xe9\xd0\xad\xc4\x17\x92\xf6\x97\xc7\xd9\xc5\x08\xa4\xa7\xadE*\xf5\x04\xe7Z\xb5\x85#?\xcb\xdf\x18>\xc0\xb1O\xf2\xcb\xb6\xd1ky\x97\x1b?* {\xc1\xae0\x08Q\xce\x843Z\xfd\xe8q\x15\xfe\x06d\x12\xb2\xf0l\x86\xd8o\x85\xb4p\xf5%2\x89\n\xd6O\xb1\x14\\\x95\x89\x14\xd8\x89\xc6\xf8\xef\xb4\x8a\xc6\x99*h\x14\xe9!~\xb8q\xa1\x15>\xe0gY\xfd\xd1\x96\xf4\xcc(/@\xb2\xb6\xa2\xd8GL\x18X\xddw\xee+\x9fEO-`\x9bEQ\xe5\x7fc\xfc\xab\xd9o\x8dG\x8a`\xd6\xd4Q\xde\x8dai\x92FX\x00{\xe2\xa5\xc4\x9f~~\x13\xe7\xc3\xfd\x17gv\x0e?\xea\xdc\x18\xf5\xfb\xdc\xa8E\x16\xce\x8e\xa6A#M\x87j\x98#\x08\xe1\x18\x8a#\x0877\xf5L\x19\xf0\xc6px\xa1\x83\xfdG\xad4OQ\x1cp<\x1c\xc2\x16\x04\xadr\x1dQS\xf9!]9\xb4\x9b\xa1\xe3\xb2\xcfa\x93\x03(+\xe7-\xa0\x001V\xc9\x91\xec\x16K\"\xc1j\x0ca\xeb\x84\xf7\xc6\xe5P0 g3lb\xd8\x84\x0c\x9eAQ\x9e$\x05lA\xe60\x7f`\x84\xda3d\xe6\xc2\xad\xad\xb6!\x97\xc4\xf3\x8c\x07\x0b\\1\x1ep\x05\xc7\x90\x1d\xc1\xaa\x0d\xe8P\x03[{>\x1cCz\x04\x9b\x9b~\x1b\xfa\xa0\xc7\x84\x9c\xf7\xa2\xb8\xce\xf2\xd4\xa6|\x82\xef\x02O\x8d\xa1_X8H\xa4\xd6\x8a\x8a\xa0\xf0\xf5e\xc9\x84\xee4f\xba\xdb\x03\xe9\x89\xcaz-\x9a\xeb\x8eE\xc3+{a\xbf\xa6\x1bJ^\x16\x0e\xaa\xe4\x9a&@\xa6\x96\xae\xfa\xb6d6\x18(\xeb\x94smM.]Y\x14V\xb2\xf2L\"\x963\x87K&8\"r\x02\x94\xb8C\xa2\xafK\xa8\x98\xaf;\xe8\xdb~\x83\xae\xc1\xa6W\xc5g\xfd*~a\xff\xb6~\xa7\xbf\xf6\xad\xbb\x97V\xa3\x92W\x96\xde\xb6|\xd6\xa4\xadF\xa4\xa0\x15\x1b\xb6\x9d\xd3\xd3i\x84i!\x1c\xbe \x19+!\xcd\x9f\xcf\xf9M\xcaO\xc3!\x8f\xdaL\xd1\xc6\xde\xbe\x0b!\x9b\xf6\xc4)\x7f\x9a4yF\x94\xfc\xf0\xad\x0b\xfe\xbc\x8d\x9f\xad\xb3\x10t\xd8q\x8d\xc5\x84SH\x91\x07yq\x97\x13\x91\xf1\x9dbU\xf5!WQ\xe5u\x9b\xae\xb6~\xbdl\xeb\x17\x05\xf3;?_x\xcb0.i\xc6\x1e\"[:\x9f\xe8\x1aq\x04 \x8an\xdb\xd0&\xa5\xbd]\xb4\xafu1F\x07\x99$-\xc9\xe5\x03\x11,\xc1X\x82\x9e\xe0\x11e\xa5w\x9e\xc2)\xec\xc2\x98\xdd\x8dv\xe0\x14v\xf8\xdd\xf0\xe9\x10Na\x04c\x93\xe8\x05iE\xd8\x84\x19\x1c\xa3\xb0O\xc8\xeffm4D\x9f\x04\xb8\x11\x1c\xc3ptX\x12rQ\x8b^ \x04\x9da.\xd2'-.m\x8er\x19\xc3\xa7#x\xc2\x88X2\xa1\x83\x1b^:L8@\xd9\x17{g\x08O r\xe0\xf8\x18\xf6\xe1\x1e\xf6w\xe0 %^\x9f\x89\x0cb\xd8\xdd\xec;t\xd7`\xf6).\xb9\x7f<3>\xde\x8d.]e(!\xf6\xbe\xfe\xcc\x97F4\xdc+G4\x1c\xc1=\xd8bL\xf2\x10}:\xc4\xd1`\xf7\x80\x7fw\xcc\x13\x96\xdd\xdf#9+%x\xfb^\xe3\xdf}\xfc\xf8\x8b\xf2ng\x0dh\xd4\x9f\x15\x06\x08\x1d*\x10\x92@\xe6\xd7AV8\"\xef\x1b\xad\x89\x82\x8c\xa5\x92\x1bI`\xd2\x0eQO\x12\x97\xc6X\x94/\xc2\xcfi\xdd;.\xee\xe4!\xc5s\x81\xdc\x9e\x1d\x94i\xe4\\H\x19>\x0f\x98\x18u\x00O\x00\xf3\xc5\xdd\xb3I\xe4\xdc\x0c\xcb%w\x0f<\x95\x1cer\xc4w\x18\x1bg\xf3\x04fM\x8co\xc2\xd2\xdd\x14\xc9M\x19\xa7\xa9M|\x8a\x8aq\x8a^\xbe\x94$\x9f&\x1d\x1d\xb71>\xe7b\x10\x9d\xde\x02$\xdd\x85\xa5\xc9V&\xaeT\xaf\x0c\x04(\xc3\xa2\xa4\xa8=\xa4\xc7\xeb\xe6I\x9f\xce\xf0\xe3&u\x99j\xeeK\x07\x11\x157\x81l7\x8eO\xf9.\xf7\xb8b\xe9\x84\x1e\x0e\xb9w\x1e%\xb7\xe5\x93\xf6y\xd8$U\x84N\x82\x12V\x0dC\xc0\xba\x95y\xa8\xba\xb37\x1b\x1e8\x90{o\xde\x9f\x7f<{yq\xf5\xee\xf9\xffw\xf5\xe2o\x17g\xe7t=\x0dL\xb2\xb8\x139\x89\x0e1\x98\x05\xe9\x9fwy\xf6\x18\x83\xdf\x0b\xdf\x1a\xc5di\xd8a\xa2R\xb3J2\x9fie)\xbd\x00\xb0\xe5\x18N\x92\x1e\x01\x13\xc4\xc5{\xb5\xdb\x94\x1f\x89K\x8f;\x1e\\\xd8\x1dqZi\x96$\xb6c\x14\x87\x12\xca\x901K\xd3'O\x84'x\xf9\xcc\x1eb\xc2\xbcJ\xa9\xd8\\\xaa\x9d\xd9\x0d\xf8\x1864\xb2\x93\xfa\xbab\xf1u\xbe\xbc\xf3\xbf\x96\x91\xa3|\x1b\x05\xcb\xab$\x89\xce\xc3\xdf\xe8t\x1e\x0e\x9fb\xf2\xa1+\xeea\xd3\xb9\xe2\xb5\x13[sJT=\xbf\xb8`\xbb\x87\x1f\x8cT\x7fd\xf3\xf0EZ\x0b\xcc\x16!\xb5\xec Y\xeb\xa3v]\xd1\x91k\xcb\xb8\x06\xfb\xc9st\xf5\xa7\x0d\xb1_\x18\x1cJ+!\x13\xdetY\xa9Xa_hmM\x98\xe1K\xdd\xd5\xad\xcd\xccAV\xec16\x08\x02ZGc\xdf\xd43\xd0\xc9\xb5\xd5\\j\xb5\xd0B\x0c\x933\x0c\xd2\"\xd5\xa5\xbc\x07\x99\xc4\x97FvK\xc8\xa5j\xc7\x83\xad\xcb\xb3\x0f\xdcV\xdc\x84\xee\xcc\xbd0\x13\xe7>7F1\xb3\x812\n\xf7\xff\xa0\xf9\xa3\x97\xcf\x8c\xb9Q\x13\xce\x19_\xe1 \xdf\xb1\x16\xa1Z\xb7is\x91J\xce\x1e'\xb0p\xa1F\xe9I\xc7\xe7\xc6\xa0\xfe.\xbb\xf5W\xc3\xfd\xb6x\x9d\xa0\x06\x0fh\xd3\x13\x11\xad\x9eH6\xd7\xe4=\xc9(\x89]\x99\x0e/\x8b(\x0fW\x11\xa1\x10\x1c\xeeo]\x87\xb9\xf6X\xac)\x1a\x06Gh\xbeK\x8e\xd8\xf2\x1b9p#\xe2\x9f\xba\x98\xb4R\xc7\x7f e\x82\x1cB\x04\x04\x10\xeb`\xd9\x19}W\xb0\xec~#XvF\x8f\x02\xcbn\x03,;\x8e[=\xa2`b\x7ftZ\xb85\xa0\xb5\xbf\xfb]\xa1u\xf8\x8d\xd0\xda\xdf}\x14\xb4\x0e\x1b\xd0:\xd0Ck_y\x9d\xe8\xda\xf9\x83F0\xcc\xe6LX}a\xfc\x16x&\x8f\xa7\xf2(\xb1\xfa\xd5\x8b~S\xb1Z\x890\x90\x90\x1f\xa2\x19\x1e.\xba>M\xa0\xd9(\x96>>\xa1\xbd\xe5w\x9d\x1f\xe3\xeac \xa4\x89\xe4\xcc%\x19(\x1b\xa5\x1b\xd0\x83\xee\x14\x17\xef\xc5\xc7j1\x9b\x9c\xac\xa0\x0f\xb5\n\xbd(Vq\xf1\xc6_\xae\xd3x\x1b\x9d+.^\xef\xf3u\xeam\xa5\x8e\xa1\x1f\x85,.\xde\xfe\x87u\xda\xef\xb4\x1d\x86\xaa\xe2\xf3u*n\xa1\xc6\xa1\x17E\x0e=\xa9rX\x872\x87j4\x17\xfdF\xd3I\xac\x03\x94v\xd1Z\xc6\xfa3\x8b\x0eUz+\x8e\xb51\x14\xd4\x8b0w\xc4M\xb0\xac\xbef\xd3\xa0\xa5\xc9\x1eD\x0c\x12\x1c\xac)\x0cI\x1d\xa9\x93_\x0b?j\x8f\x1f\x01ZiC\x87lA:\x0c\x85\x8df\xeb\xc1\xc3\xcf\x80\xfb{\x8e,KY\x88\xde/\\\x19E\x18g+L+\xd6\xefd2)F\x98\xffRC\xca\xdf\xdaqq>=\xe3f\xd3%]Q\xba\xf3 \x8e\xe4\xfe\x92\xde\xd2\xcf\x83\x85\xbd\xed\xfd>z\xd8\x9e;\xde\xdf\x930\xb6-\xb0Dx\xb0\xb22\x9e\xec\x89\xa5P\xf7<\x0f,\xc7q\xc1:\xe6\xf4\x06\xae+]6\xf4:\\\x0c\xf2\xa4N\xa3\xf6\xef?\xd5*\x8fW;YU\xcfmf{\x8e\xda\x11\x0e\x90\xb1Z.-\xed\xb6\x94\x17\xcc\xd6,i\x9c\xa8\xb9\xf0u\xa7'pY\xef\xfd=\np\x06,\xd5\x9cr4\xeb)>\xee\x8f\x9e\xd2G\x80\xf6\xd1\xa6\xf1\xa6\xf0\x8c\xf7'\xa7\xbfZ\xdd\x84\xaa\xf2\x9d.\x04Je\xe6RH\x07\xb8\x10\x97\xbf\xd2\xf2WR\xfe\xaa6_/\xf1^\x88\xae\x03[t\xf5`\x0e,\xd8\xa2\xcb\xa9\x90%z\xa1\x0b\xbe\xc3\xcc7\x10\x9c\xa5^0\xe1*\xd8\x9ae\n\xd3\xec\x0e\x8e`\xc6\x0ci77gf `4\x991 `0\x99\xb5J\x00i7ia\xd6KZ\xda\x8c\x83\x1f!\x01\x0c\xe1\x18\x8d\x90Q\x02\xe8\xc31\x84f \xa0\x8c\xa5\x82\xa8\x98\x92>\xb1\xc6\xa4\xb6\xb8q.\x82\x92\x9b\xe3\xdbf z\xd3\xba\x7f\xad\xc6\x96\xf5\x90\x1a\x98:\xaf\xad\x11\xc9\xe4\xff[\x1b\x1a\xb66\x84\x1e\xfaz\x0cf=\xbdp\xdf\xd4E\x10\x86\x1cm}\xa5\x10?X\xac\x0f\xda0@\\X\"\xe2\x87\x984\xd99\xba\xa8\xf1\xe5\x1f\x1a\x03\x03\xa9\x91\xfe\xd4\xd8t\xa6\xeacz&IB\x07s\x1c\xcc)\xf9\n\xb2x\xa1'D\xff\xde\xc1\x0c\xe5\xa5O\x7f\xce\xed\xa9\xf7p\xc2\xf5z\xc9\xda\xeeU\xadud\xaf\x17\x17Fu\xc3\x1d\xee\x8e\x96\\\x02\xea!\x9e`P\x9e\xe3c8\x84\x1f)\xfd{\n \x8ca\x08[\x908\x0e\xdahk^\xf4\x1a\xf0\xfb\xb5\x06\xbc;z\xba\xfbt\xff`\xf4\xf4;\x8dz\xd7<\xea\xbc9\xac\x1d\x1c\x16\x03F\xaf\xc1}\xea\xbd?\xbeea\x99\x96j\x0b>y\xf4\xfa|U\x1bQ[J\xc6\x90\xeeB\x04\xc0\xc0e\xa0v!\xe1<\xae\\\xc7h\x87\xbd\xa3\x10\xd8\xed\xd5\x87\xb7\x8f\xee\xc3\xa1\xa1\x0f{#\xf6\x8e\xf6\xe1P\xe9\x83|\x97\xa9t]\x1f\xfb\x1d\xe1\x15\xd7OI}\x02\xff\xfd\xdf\xc4U\x83`\xe6p\x8a\xa9Z\xfe\xfb\xbfs\x97\x9d\x14,\x0c\xe5&=\xb5\xcb\x1dBD\xc4\x11B\x0f\xf6\xf2Q\xeaT!\xc9\xec\\\xf9&\x17\xdf\xe4\xe57\xb9\xf4\x0d)\x9f\x10\xc7`\x03\xecT:\xcf\xd2\xea\x1aaa\x0c\x90\xb9\x96\xfc\xa4\xa4\xc0`K\x8d\xcb/\xae\xb8\x0c\xf3\x9b\x08q\x86\x81\xbb\xa81\xe7\x9cNH8\x19\x13S\"\x80\x0d\x04)\x00\xd2\x95\n\x07\xaa\x85V\xf7\x80P\xd8\x0f\x11\xd5\xe0\xedYO\xb9\x1a\xe1\x92\x19!\xb8A\xaaM\x90\x13\xb2|\xa3\x05\xf7\x89\xe56!\xdcgoX\x12G\x9b\x9bt\xd89\x17\xae\xffxB\xe9\x1e\xe7\x88\x13\xb5\xec\x1b\xd8\x84\xf0\x12~\xd4\xb9v\xebIY\xfd\x88_\xfccF\x0c\x9b\xb0\xb5\x95\x8bq\x1f\xe1\xd2\x1et\x0c\x97~\xf0\xed\x03>\xec\x83\x10\x84\xc6\xa9\x1c\xe3\xd0U\x15\x1cl\xe2\xfa\xb48\xdco.\xab^\x8d\x8e\x0c\x8drK\x0f\x04\xca\xf0\x12\xcf\xfc~\xfdhN\xf6\xb7\xf5\x03\xa9\x8dZg\xfa\xf4cg\xf4Hx\xec\xaa\xfd\xb0\xcd\x00\x91\x1f\x8d\xf0\x11\x8b\xf37\xdc?88\x18\x0d)\x17Q\xbe\xdf\xe9\xd9\xedG\x82\xaf\xd1\xedF\x1f(gc+#\x18\xee7\x87P\x1b\xd5\xcee\xab\x08\x9fv\xfb\xff:\x8c\x06\xcfN\xf8\xe7\xc3\xd1\xa1\xc3E\xe1[\x9cv\\%\xb76\xa5\x12(X\x1d\xc7\xedF\x07\xff\x10\xf4W\x03\x8c\x84\xdb\xd2\xcb#$/\x9bX0T\xb0`\xda\x0e\xa4P\x03\xa4\xd0\x08\xa4\xb0\x07\x90\xbe\x13\xcaD\xdf\xebr\xc5\xa3:\xefG\xc0\x88\x10[\xd2>@\xaf\xd3\x9e\xd8u\x0d\xe4j\xc4fM8\xde\x88\xd8\xaaF\xe4b\x84\xfd\xce\xe8`\x9f\x0e2\x86S\xc6\x08\x0d\x86\x07\xfb\x03\xb8\x87\x18\xc6\xdd\x14\xc8\x1a8\xfa\xd1\xc3a\x83\xb8\xaf\xa1\xf0?n8\xdf\x0f\xd5\xaf\x87\xe9\xebx\x92>\x1b\xed\xf6\xean?\xe8\xf7\xef.\xb6\xdc\xect\x0f\xe4\xde\xd5\xdd\xd7Q\xe2k\xb0\xfb\xe3\xba\x9b`\x95\x95\xa2ac \xb8\xbe^\xdd\xf8^Pktc\xd8\xb7\x1b\xaf\x92\xe2:\"\x8f\x04\xc7ag?\x06\x82\x01\xed\xd7\x8fG\xc2\xa3\xbb\x1f\xc3>\xfd@\xe6\xd9\xc8\xcd\x18\x848\xc8\x86n\x92\xda\x01\xc7\xacXPm\xfbF5 P\x0f\x93\xd8\x81-\x8a\xf2M\x8e(\x899\xc6_\xd8\xe2\xf4\x81\x1b\"\xafBN\x13AI\xc4\x8dc\x92\x15eD\xc4 \x10\xd8\x86\x84\xc9\x81\x8c\xe8\x8d\x16n\xc5b%$\xb5d\xc2?\x10\x921\x161BSc\xa4$AS\x88\xcfJ\x88nm%\x18 \x8e\x93\n\x1a\x90&\x02\xa4\xe1w\x03i\x83\xa8h\xb7`\xd1\x00U\x85%E\x16{{.\xeaQ\x8c\xf9~pv\x10\xe4\xb3(IP\xd2\xcd\xb1\xb5\xbc\xca\xb8\xc9\x7f\xaf\x81\xe8(\x90o\x1e\xcb\xc8e\x92\xe3\xb6\xd1\x9cj\xb6\x87[\xcd\xd9\x90\xcd\x19\x8aH)M\xf5\xf7Z\x03,G*=|z\x0e\xb27\xa5\xfc\x07\x0e\x92\x8fF\x1d$\x1f\xbbf\x90\xc3\xb5\x06\xa9\xa3V\xbey\x90\xbb\xae$\x12\xef5RF\xb3\x88\xd1\x8ev\xa5\xe1\x8e\xaa\xe7\xc3}\xc3\\k\x963\x85\xcc{\xfd\xf4\xb7\x92E\x12d\xfe\x80\xe9_\x1f2\x06\xa8\x0c\x0dP\x19\xe9\xd7\xccN;d\x86\xbd!\xb3\xe6\x11+\xa4\xc72X6\x8c\x06G\x02\xd57\x8e\x07\x0c\x1d\xad\x97\x9d6\xce\x96\x84\x1d%[\x1a7o\xbd=\x18\x9e\xc5\xfa\x83\xa5#J\xef#Op_:n\x88\x10y3\x89z\xc1~\nsLv\xb6\xd3\x01]\xe2\x97\x05\x86(r\x95s\xdf\xa6\xa7\x94\x0f\xcf\x9e\xc1\x80\x9e\xa3\xc5w9\xaf\xd6\xa4\x00\xfeO\x99\xe8\x16*\xe2\x9b&[\xcc\x85D`\x84\x15\x81\xb1\xf6\x8co\xfecf\xfc\x0f!P\x86\xa3\x03\x17\xb6\x86\xa3\xc3\xb5i\x14R\xd3!Q\xd02\x9f\x84\xe1\xb7\xd0/\x7f \xf9\xb23:\xd8\xa7cE\x19B?\xd4\xfe\x07\xd20\x7f \xf3\x88\x81\xfe\x81t\xcc\x1fH\xc6T\xf9\x10\\%\xedA\x8f!\xb7\xcfm\x0f\x12\xa7F\x12}\x13A\xf3\x07\xd23f\x10\xd5\xb7o\xcdHB\xec\xe2\x1eP\xfc'\"~\x0c\xf2\xa7v(\xbeR\xe6\xac\xcb\xab\xa2ji\xdd\xf9RZ\x1a\xf6j\xc9$Ejo\xea\xedc\x06e\x12\x14\xad\xd5T\xe7\xa8\x82du\xb7\x1e\xddR\xa5\x9b\x1c\xa0Cd\xe9\"X\xd9\xd5\xe7\x8a\xa7\x97\x94\xa5\xa42E\x90\x0b\xd0\x0f\xf3\xb2F\xae\xe2HK\x12\x10\x9d\x17\x98\xf7eWz\xa7\xb0\x11 \xa5\xea\xa0\xdc\xad\x8e*\xf26\xc3\x9b\xdcO\xe7$?\xcf\xfd4\xef\xce\x86Z\x9a\xf1\x003\xd6T\xba\xa1o!K\x8a4 k\xb4\x90\xb6\xf5\x97\xd5v\x16O\xbb\xebJ\xeb\xce\x17%\xf4\xeb3*\xd9_\xe5\x18{iK\x9a\xa8\xda\xcbM\xadU.\x12\xb4L\xbf\x95\xea\xe3\xd6\xe3\x1cTn\xa8\x18t\x99+\x07\xb1\xc5\x96\x904 \xb0t \xc3#HxV\x83\xad-4\x0bK`\x13\x10I\"\xae\xa3w\xba\xb8/\xa5\x93\x11eA\x86d\x07X\x18\xaf\xf5\xb2\xfe\xb105\x8aY\xda\x1a\xedk\xf3\xb9d$\xaf\xf2\xb8\xd4Lubf\xf6\x14:\xfa\\\x98B\xef\xd7\x86\x08fa\x14\xad\x87\x084NWkg\xb6\x16\xe9 0\xa4\x06?6\x95\x1d\xa2M\x9f+\xe1\x85\xe6'.\xcf\xba\xd1\x95\x19 $\xde\xaa\x16\xb0\xdcdy\x04\x18\x80\xe8\x18m\x8c\xc5Am\x88\x8ff\xce\xb7\xaa&\x9b\xd1\xe4\xc33\xf9\xb3\x97\x19\xbf\xfb&\xf36\x80\x1d\xdb\xad\xe7\x02NM^\xc5&\xcf\x8fF{\x95\x12`:-\xc9\x9b)\xcb-\xe2T\xe9\x17a9\x00n\xab\x87>\xca\xb5A\x08\xbc\xe8OB\xf8_P\xaca\xb3\x977b\xe4\xd4\xfb@\x07\xfb\x19N`{\xf2\x9f\x9b\xbfl\x0f\xb6\x9e>\xdf\xfa\x0f\x7f\xeb\xb7\xad\xab\xcb\xed\xb9\xc9\xf5\xe6\xd7\xf6\x10\xae\x80\xca\xd9S\xb0\x06\xe8\xf4_O\x13:V\x1e\xd4\xfbfh\xf0\xb5Q\x01x\xa3\x0f\xd0\x96\x03\x8f\x8a3\x84\xed\xce\x1c\x97\x95\x83L\"\xc2\xf3\xeb\xf2:\xb4\xa7P Y`\x9bFb\x07\x07\x9ea4\xef=qD\xef\x1d\xec\xec\xee\xb6!\xdc\x90\xe7\x873\x97\x80r\x93>\x83\xbd\xfd\x9d\xe1\xd3\xae\xc2\xf4b\x89(vh\x7f\xb6\x86\xb43<\x99\xc4h\xe7\xa9\x0b\xc3\xa7C\x17\x86\x87O[\xd0\xba\xb8\x82$\xce\xc3\xb8\xd0\xe7R\x12\x979{\x10\xf0\xbe\xfb R?\x19\xa5z\xf2\xf5O\xd4{\\$\xed-u\xb6\xd2\x9e] \x97\xc9\xfe\xce\xc8\x98BP\\\xfd\xa0\xe2\xfe\xc1]\x8e\xb9\x8f\xc6>lR\xban\x8b\xa7 8>\x86!3t\xd9\xe2\xa3\xd1\xd6\xc0O\xc5\x84\xf3==\xc6c>\xc9\xab\xfd\x1b\xb3D\x15]\xfb\x8c58d\xd9Y\xba\xd2\x1f\xf0\xce\xc4\xad\xe3\x10\xf37\x1a\xec\xf6l}\xb4^\xeb\xf0\xec\x19\xe62\xc0\x00\xdb\x98\xd0 \xa6w\xa3\xc3^\xdd\xc2y\xea\xd7\xaf\x9d\xf5\xfb\x85I\x17F\xa3]\x16\xc2\x03\xf6\xe1 \xed!\xf6n\x8d\xbev\xa0F\x1c\x07O\xd9\xa0\x8b3 \xd2i\x05\xc9\x94\xc0*1x\x91\xc9U\xb2\xf1\xee>b\xbc\x87t\xbc\xbb\xe4\xeb*I\xf3\x0cN\xe0\xf7\x07\x89v,\xc1\x106<\xd2\x1b\x9b7#\xf9E\xb8$I\x91\xc3\xc2g~\xa0\xd7\x84\xc4 B\xe6W\xf0~\xd04\xe0w7\x10D\xc4O\xbf\xa1\x89\xa2\xb9\xe0\x19n\xc5\x18`e\xef\xab\xe8\xc2\xe5#\n>\x95o\x16T\xe3\xc9 \xf3\xe2\xda`\xf9\x8e5\xf5\xd0C\xb6z\xecv\xd4\xab\xcf\xb7!\xaab_\xd4\x97\x81\xc8\x0f\xa17\x955\xa6\xef\x10U\xb2\xa5SF\xcb\xd79\xfc\xb7\xb6\xd0\xac\xab\x94\xd2v\x07\x0f\xa8&l\xa3Z\xac\x8d\x95\xa0\x1d\x03f\x9d\x11\xdf\xc8\xbc\xa6\xb4\x10O\xe5\x9b\xb1\x8av[\x13k\xd0\xeaU4-\xdf\x19\xe6\xc9\xd4\xa9\xda\xe2=\xad\xdf\x8e\xd5,\x89\xad\x1d\xa3M\xa8Y\x15\xcb_\xb6\xb4\x9a\xe8\x1e\xe7\xa9\xcd&Jb\xb3\x00C\xbf\xd4\x9f\xcdx\x12\xda\xe6\xc6Y5f\x04\xb3\xb7b\x1a\x0b\x9bW\x05\xa5X\xe0\x14[\x14\x01\xc4\xed\x08\xc3\xa7b\xdd.D\x92\xecuj;\xed\xfbu\xdah\x16\x89\x88\xc0\xc4L\xd2\xb3\xad\xb0W\x1a\x8a\x01\xfb\xd8\xc6KR\xa6S\xf4\xed\x083\x11\xe9\xd79~@\xb1d$\xe0\x8aA\xc4x\xf6\"\x9e\xf2cv\xe9\xa5El\x9b<\xfc8(\xe4&;v \xf0D\xcfl\x8f\xea\xe6N\\\xfd\x8ev&T\xa7\x98K^\x86U\x1a_\xe9\xa1\xdd\x16P\x12Q \xab\xc8G\x14\xc8b5h+\xa5\xabV~\xe1\xf6o\xc6\x8c\xc2\xc4\x95\xda\x06\xf9\x12\xf4\xc2^\xe2\xean\x08d\xf2K\xc6\x9b\xe6\xe6a\xad.@\xa3\x01\x8eL;\x1a0\x8f^\xfb\xe6A\x05\xd8C\xebN\\h\x858(\x0b\x9c\x15(9\xe1B{\x96\xe6\xe8D\xcaZ\xaa\xab\xee\x86n\xec\xaa\xc5\xc4\x8b\xc9\xd7\xfc\"\x0c\xbe\xb4\x12\xa7b\x9fR\x8a\x80\xd1\xbc\x8d\xb8\xcdM\x93!\x94W\xa8\xc5\x9e\xc1\xb0 \xce\x12\x17\xc4\xcc'\x93\xb2*\xea\x97G\x10onRr-f\x86XR\xe8\xe8F\x98\xfd\x883\x1b\xe4V\x80\x0fe\xf7\x98\x15Z\xa2\x07\x03\xfa_aO%T\xe8\xc2B\xb6\xabG\x00\x9b\xcfF> <\x1c+[\x8e\xd5\\\xd4\xaaM\xbc<\xcc#\x0cJz\x9d&\xb7\x19I-\xfa\x90\xff\xe6a\xf2\x13\x8f\xc47H\x07\xd2\xdf~:\xbf\x11y5\xbd\x1b\x92ft\xfeX$\x93\xf2>+K\xe3\xbb\x1b\xfcn:}\x1bf9\x89\xb1\xde\x1b\xf6\x12\xdd\xd1\xd9\xef\xd9L\xfcL\xc92\xb9!ja\xf6\xf4y\x14\x89\x17\x99xC\x96a.~\xafR\xb2\"q\xa3%\xfe\xf8C\x1c4\xea\x8d\xa4\xea\xccK\x8d\xef\xc0\xc9e\x1dz\xd7a\xdc\x99\\\xa5A\xb5\xae\xd2$ YV~\xccC\xa4HA\xf1\xea\x8d\x04\xb7\xd3\xb6\xf9\x16\xac\xd2\xb6\xa5|\xb6\x98\x86\xe9\xe3z\xc6>\xed\xeaW\xb1\xf4\xb3/=z6\x90\xb6>h\xb8\x10E\xc5o\x15\x19AEO\x90KL\x9c\xcc\x90\x98G\x84\x1a\xa0\x8a\xd8\xda\x90Uu:}\x0f\x06\xb1\x15\x03\xf5\xcb\x8aU\x19C\x83k|\xc4@\x9aH/\xd5\xe2\xd0\xca\xbe\xe6\xa4\x0bk&f\x94\xd8\xc0p\xc7'0\xa4\x88E\xd2\xdeT\x98jx\xc9\x835\xc8\x8f\x9a\xf4DlLx+duZ\xb0\x19\xd7\x07\xa8\xc2{\xb5\xd7Lt\xcfP{\xea\xa8\x02|\x9fb\xdep\xe2\xd7\xb1\xaeof\x961\x17\xd6\x86\x88\xa2\x19\x0b\xd0 \xc3&\x91\xa1\xa1GnHzW\xcb\"\xdd\x95\xda\x0c\x19\xb7x\x92^j\xf8\x1bts\xb1\x19W\xcdp2\x9b\x04\x17B\xc7a:\xb5\xd05s\xf2Z\xde\xbb1\xf15\xc2\xb5 \xc7\xb8\x84cN\x0f;8\xc5\xe0\x14C\x1e\xd98e\x07\x1c\xcb\xb9 )\x85k3\xa9\x9d\xe4-\xa0\x16\x97\x00]\xfb\xa6\xef\x03}6\xc4Y\x9a,[Yv;4\xcc\xc3\x83\xf1\xb8\x8f\xbc\x94dE\x94\xbf.\xe2\x80\xae%\x17\x9f\x04\xc9rU\xe4~\xce\xd9\x94\xce\xcd&6Z\xe3\xe5\x03\xab/#\xf9\xa7GWJgH[q\xed\xa1L\x0c\x88_\xb9wuE\xb2w\xc9\xb4@\xf6\x8d\xf2i\x98:\xd6/\xa2\xfc\x1dY&,soB\x9f\"\xda$\x02\x8b\xbedH\x94\x11\x1d\xe5\xcb<-\x82\xbcH\xc9\xb4D\xb6}\x18\xefGP\x99\xbeBe6\x99s+\xc1<\xb8F\xea]\xc8\xfeM\x1dg\x87C\x06\xb30\xcd\xf2*^\";\x18\xfc\x18X\xf5p\xbb )\x01\xe2\x07\x0bX\xf1\\\xbb\x94\x11\xf0A\x9c%\x9a\xa3\xc3Gk\xb0\xb2SG\x0d\xa0\xd0\xbd\xc6\xd3\xf8~!wYC\x88UR\x8bq\x1dU\xb5\xf9\xc3\xd3\x0dY_\x0e\x8e\xdb\x93\xe4\"Z\x84\x9cW\x08\x81\xd3~\x03F\xfb\x11N\xfb\xe5\x93\xb4\x9d\xee\x03i(^J\xa6E@l\x85\x13\xea\"\x98\xc9\x84R\xcb\x97\xcc\x18R\xa3\x8es\xe1\xf7\x07E %\xb1\x9fu\x91\xb6\x8f\x04L}\x99\xd3\xf5m'z\xb5\x97\xc2\xa7 \xee#\xb6\x87\xc3\x03\xe5@D\xc6\xc6\x1e\xed\xee8zV4\xb6\x87\x83\x01\xa5\xfc\xda\x1a\x00Y\x84'\xd2'$6Z\xabK\x83\xea\x91TLZ\x12\xcc\x18tM\x96\xb4\x1a\xea\xc1\xaeaD\xed\xcc\xf5\x86\x1c\x0b\xd5\xc4G\x8b=\xb6\xf1H>Z\xedq\xac*$\xeb\xfb\x8e\xc9\x9c\xc6`\x8d\xbc=o\xcf\xd2\xad\x12\x8d\xfd\xe1\xd5\x153\xd4\xa4\x7fO\x84\xdb@o\xf0\x8d\x0e\x0e\xd6\x86\x9f\xcc\x85\xca)\xe7j\xb2\xeau\xa7Q\xbf`\xf7\x0ev\x95\xe7!\x7f\xbe\xa7<\xa7{\xc7\x9ap\x9c\xf8\xbe\x88\xa2K%Tx!\x17\xf8,\xd2\x9d\xab\xa524n?E\x13\x04f\x0fx\xe1\xcf\xcb\xcc\xde\xdf\x01R\xd2\x89Bo\x0b\xcc|2\xe6\n\x16\x08c\x8ev\x99q'\nF\xc6\xc8&?\x16\xb0{OGz\xc8>\xdd\xeb\x9cx\x0d\xbd,\x96q\xc2\xdej\xb7E\xca\xb2\\\xc4%\xd8\x1e\xdb\xf7\xd1Su\x96Y\xdf\xf7w\xd41\xb1Uqp\xd89$\xc3\x0c\x85\x0c\xde)\x83w\xb26\xbc\xf5\xb2> !\xef\x0e4#\x91NXJl\xb4\x93\xd4\x82V\x99h\xce0\x89s c\xa42\x84U\x98\xf9\xbc\xab\xbdx0\xc0\xad>\x96\x90\x1f\x14\xfbR\xb5\xa1\x17\xc6\x0b\x92\x86\xfc\x149\x1c:\xcd3-\xb6w\x06\xeaL\x16\xac\xae\xda*\xac\xea\xb2g.\xf8\xd2\x9br\x80\x19\xae\xbd\xa2\xd2\"\xf0\x14I\x83#\x88\xe0\x18*uFD \x80\xe6\xda\xa5\x04t6\x89\x14\x18\xce\xaa\xfa&\xc1%\x8a\xb9\x94G\x94)\x93\x1f\xb4\xebwg\x86C\x879\xc7\x88@\xda\xc9\x0cfU~IJ\x12\xce\x1a\x84\x96_W\x95\xb9P\xa8\x0f\x10\xfbo\x08\xd7\x89\x94\xf8S\xff:\xe2\xb1c\x17aV=9a^\x80\xf5\xf2\xb7i\x98\xd7\xcb\x97Oxy\xa6q\x89\xa2\xe4\xf6\xaf~4\xfb\xb0\"1'\xd3\xeb\x15\xd5K\x94\xb55>,\xabL\xe2\x80\xd8\x16\x89\xa7\x96\x0b\xabvp6\xb5\xf4\x9a\xba\x85\xc3\xc1\x95\x18\xc0y\xee\xe7\xc4#\xf1\x94L\xe9\xcb\xb4\xd4\xc5\xd9S\xd6\x85.\x1d}c\x0e\xb16[E\x0d\xf4\xe2;\x99\x1d*\x1f9\x19.\xaf!\x17,\xd1\xaf\xbf\x86\xf3\xc5\xcf~N\xd2w~\xfa\xc5r\xd56\xe2bIRZn\xdc\xd0\x85\xcfI>n\xa7\x98\xc5\xe6\xd6\x00b!7[\xdf\xfc\xd5\x80\x1c\xb7\xd7P\xa6$\xcb\xd3\xe4\x8eL\x1b\xdd\xef\xddE\xc9\x9f\x86\xf5V\xacS\xec-]@\x8d\x12\xb5\xf1TK\xac\xfe\xa5W\xf6\x0d\xbd\xce4\x80(\x0b(d\xb9B\x08\xd4\x06\xa2\xc7\xc8\x7f\xfc\x10*\xfd\xb3i\x10\xb4\x88Q\xe1M\x19,I\xe1z\xc5\xbf\xea:\xe4\xb1Av\x80\x14Q$6,\xae}W\xdeGyM{\xff]\x0e\xca\x9d\xe1\xc8\xb1\x1f{\x8a\x93\xca=\xabT\x91t\xd1\xe8k\xf6o\xff@w\x90\xb3\x10\xf7\xfe\xd7G\xf6;\xb1\x07.\xd2\x1e\xdf\x00\xccu\xcbk\xa9\x94\xa1flvl\x1f:]\xf2\xbe\x90;~z\xe2l\xfb\x98$\xc2\x16\xc0\xc4@\x0b\x82\xa6\xf9\x1d*8\xf4\xb2;\x19\xc1 \xc3Pz\n6\x05\xd6F\x0bez\xd0\xd2\xef\x1b\x86\"\x1a\x9a\xb2}\xd4D>\xca\xf1h\xa7\xe7\x8cm\x8d\xf6,t\xb7\xc5\xedVP.\xde\x16\x9bH\x03\x1f8\xe6\x1b.I\xa2\xf3\xf07R\xe2\xad:L\xe8vl\xa4o\xad\xdd\xfa((\xab=*\x1a\\&\x16\x9cNi\x9d\x94\xb9I\xc6\xed\xa8@\\%\xfb\xda:-q\xad\xcf\xdc\xba\"\xf6\xe6$\xa7\xf7\x88\xac\xd0\x01\xca\xa7O\xcb\xf1\xa2czu{\x02\xc3\x81C\x0b\xa4$\"~F\x98\x84\xaf)\xa1}\xd0\xa8oc\"\xd2\xa9b\x83\xe9X\x05\x08\xbd\xf2\xdbD-\xd5\x0b\x06\x8fY\xe4 \xeb\xa6\xd6Y\xe8\xa0[\xec1\x8b\x10\xe0\xe8\xc0\x01\xda5\x0f\xbauO\xab\xe8\x03\xce|\x91\x92\x06@\xbbD;\xe2\xfa\x16h\xa5\xdf\x05Zi\x19G\xa9\x114Z\\\xfd\x01\xd6\x88\xc8\x00z\x98\xcd\x92\"\xed\x02Y\x8bT\xf1[\xa0\x96|\x17\xa8%R\xf4\xa9\xd4Q\xf5\xf9\xe2Z\x0bp\xae\xd6\xf1\xb8\x8e\xca\xf4Gg\x81O\xdb\xe4ju\x03\x7fmq\xb3\x98tO\x95.%\xfcy\xb7l\xc4p\x94\xa7v\xb2\xfe9.\xf7\xe8\xd1-s\xb9\xd1#\xc8\x08\x89\xfa\xda\xd1\xcb\x8a\x0e\xb5\xe2\x96\xe1P}\xce\x98\xfd\xe1\xfe\x81c[Y\x1aX\x1a\x9e\xff5\xefH)_k\xca\xdfX\xfe\xc1\xc2\xf1\xb2U\x14\xe6\xb6%J\xcaR\xd8\xd8\xde\x1f8\"a\xf99F\xca\xe8\x03$\xce=\x93\x9a\x05\x98m\x94~\xe1\xda-tr\x84\xc8d\x0d\xafx4FH\xe4\x87\x14s[\xb1\xbf$\x16\x1a\xd1$\xd5=7\x9fDIxi\xd2cK\x9f\xf9\xd5\x17>/\x87\xf2\xd6M\xf6{\x0c\x19\xb3H\xe0\xde\xcb\xb9\xe3\xb0\xa8b,\xb6\xcbi)c\x871\x14\xe2\xb6\xf64\xa9\xd6\xc4\x18\xec)\x89HN\xf0\xbd+\xbd\x92\xd7\x94c\x97\x93(3\x85\xe54\xb5hu\xf84h!\x87\x04\x14\xa7}&>Ja$a\x87\xdc\xfeZH\xa1sM\x94z:9\xf4\xc1\xa9\xc4A\xc0\xb8\xcb^\xa5\xd76\xeb\xa4\xbe\xf5\x9bo\xb4o\x10\x81\xef\xeckw\xdf\xde\xaeJ\xc53Q\xdb\x81Z<\xe3\xc5UYj\xc4\x9f\xab\x12\xbb\x80?W\xeb\x99\xf1\xe7*2X\xa1\xd0\x8ci\xb3\xce\"B\x0f\xc4z\x81\xa9T\xe0\xb5O\xc9\xe4\xbbz\x81\x05+\x10%\xb1\xbe\x82\x1b8\x81\xb4\xfeh\xd9I\xb47t7\xd0<\xc8\xe7Z\xb2\xf9\xe5\"\x8c\xa6)\x89\xc7\x86sx\xe9\xaf\xc6\x10zK\x7f\xd5$\x0b\x80 1\xcf\xfc`A\xcb\xf0\x9f\xfarAR\xc49-\x85?\xf4e\xf2\x045\x9f\xb4\x14\xff\xa9/\x97\xc4\xd1\xdd\x18f\x8dw\x1a\xca\xe5e\xb2\\%1\xa1M'^y\xd3,\xf7\xb1HI\xadl\xedA\xb3|m\x05\x8cA\x03\x1cy\x86\xc7\xa0\x81J\x98\xfd\xe4G\xe1\xb4,Rx\xf5'\x9aN\xa6\xc9\xea\x82\x99De\xa6.\xbd\x8c\xfc,\x1bC`z\xcf\xd7\xe4\x18\xa6\xa6\x12\xef\xc2\xafa<\x86e\xf3\xfd\xab\x0f\xef\xc6\xe07\x9f\x97J>\x8d\xf1\xe9\xd5U\xb6J\x89?\x1d\xc3M}q\xea)\x829>\xfdc\x90Nc\x93\x87L\x12\xf0\x94\xb2\x1e\xf6h\x7f\xbf\x12\x14V\xe2\xa5\x85\x9f}\xb8\x8d\x85\xc8P\x8b\x9cF\xfb\xaa\x9eO\xcf\xa1~!wc\xd8\xd0XA\xa6d\xa6\x7fqu\x95\x91\xc8\xfc\x0e)\x84\xb1\x9a\xbeX\xeb\x10\x9a\x19O\nI\x9cG\xbc\x94T\xbbJ'?\x8e\xfaU\xf3\x85\xdcI\xd5\x88_BU\xa1\xe1\x1cX2C\x03Y\xd2\xd4*\xd3\xeb\xcf\x7ff'\x96vE\xe6\x98^\x994_\xe0\x1ch\xb6\x16NA\xdc|\xbeJ\x93U6\x86B\x03\xff\xe46\xa6|PhZ\xd6P\x01\xa7\x8a\x0b#\xbd\x0f\xea\xc7\x88\x060:`\xa4\xcc\xd0\xfaw\x1d\x97\x06&\x0b\xf0\x15\xe8,\xc0\xd1\x9b\x96\x11\x04:\xde\x19\xd5S)\x84t\xf1\xe4,3\xcf\nm9R2s\\\x88\xc4\xc3\x19:\x98\xc0&\xa0\xd2\xcfqky\x06=\xb6\x84\x05\xe91.\x9f4\x8b1z\xb7^\x10\x9f!\x1d\x14\x96\x921\xe6\xb5\xb6Q([\xd3\xe6\x99\x87}f\x1f\x93OR5\xe3.\x05\xdfTg\x18\xb5\x05\xa3&d\x98\x0eh\xea\x80\xef\x05\xfc\x8c\x84Fl\x8f2\xe2\xc3\x14\xbd\x944\xcb\xb4T\xf2-J\xc3\x9e)\x85\x11S\xef\xdd\xc01L\x8f\xe0fs\xd3\x81\xc5\xe4\xa6n\xd8s\x83\x811\x9b\\\xee\xc0\xad\xf7\xa9\xee\x8f\xf8\xd0\x18 \n\xdf\x88\xb0?\xa3\xf0\xcat=\xa5\x9d\\\xa21\x87\\\xb2\xd9|\xb5.\x96N\xcd\x96\x8c\x02^\x9a\x81e\xc3\xe0\xfeA\xb77\x02\xba\xdag.\xac0\xa9&z4\x05E\x9a\xd2\x03\x10\xfc\x1aK\x13\xd4\xc9\xaa^Fp\xca&C\xb7\x9e\xd2 P\xbbWs\x8f\"\x0f\xae\xa4P\x9a\xa7G\xfa\xf3x\xfa\x89\xc5F\xf8w\xd2\xa9t\xa8\xc6\xe81\x86\"w\x19\x96\xa5\x7f\xf8>\xa0?\xf8:'\x1e\xc3*\xf4\x17b\x1eu\xfc\x12M\xd1\x13_\xf8\x0c\xb8\x94\xa8\xb4\x7f\x7f\xa8*n\" \xd4\xba\xd0-\xdc|\xb5\x00~8h\xce~\x0cj\xdd2\x16\x8d\x87_\x17\xd2\xf1kHg!\x90\x0e\xdb5\xe5\xf2\x90q\xd0T\xc5A\x0c\xdel\xe1\xe39.\xaf\xe9\x12mi\xde9\n\xb6\xf1\x0d\xd8\x86=\xb7e$F\xf9\xbb\xba~\x8c\xe2\xbd\x15\xf3\x81\x99\xd1?cqG\xcbj\xb0\xd3rM\xec\xb4t`\xd5\x07;-;\xb1\xd3\xbc\xc4NK\xc7\x85;\x86\x9d\xee\xe0\x18\x96GpG\xb1\xd3|rW\xc7Nw\x06\xecT\xeb\xd0\xbc\xd7\xfe\xe7{c\xea\xc2B \x81\x9b\xba\xfe\x9c.\xfe:u\xfch&\xb8\xa6Gc\x0bD\x90\x12\x0c\x8d\xc9\xad\xca\xa4i\xf0'\xe8&M%\xb1\xd3\x81\xe3\x9d\xdf-\xaf\x93HO\xe9\xa6\xebU7:\xd4\x9b\x0d\x0d\x0f\xbf\xcd\xd6m\x83C!\xa9\x0c\xd0q\xc1\x7f\x8b\xdd\xdb\xc8 \x81|\xaa\xaa\x19\x19\xd3\xbf\xdf\xb0#bt\xf5\xfe\xb0sdf\x94+E\x12\xe4f]p\n\x13r\x89\x96g\xfe\xb7\xc8\x131\x1e~cxJ\xf8\xbb~\x13\x11\x1aB\x972\x95\x1b\xa9\xechH\x13W`\xe0b\xd8lD\xe1\x11k\x7f\xc0j\xa4\x93I\xfbF\xe8\xddV\x02\xa7`m\x0d,J_u\x8c\xbf\xc6p\xe9$E\x9cUb\xe7+F\x1c\xea9C\xc4\xcb\x8a\x15I\xaf\xb8yq\xc5lU\xd6c\xacR;\x97eqM\xec\x15$\xb1\xd0E\x9a\xc4\x17\x98\x98_\xcb @\x87]\x8a\xb8\x84\x89\x82\x9e\x0b\x03\xd6\x8dY8/D=\x1a\x9f\x81\xda\x93\x87\xbaU\xf1\xa3\xc0\xd6\\\x0e\xaa\xd7\xb9\xc2\x88\xc45(\xd7\xe0Z\x9f\x80\x98\xdc\xa2\xe9r-.w f\xf8\xfe\xb6\x07\xfb\x9d\x9b\\\xb7kj\xa6\xceJ\x98\xd8\x97~\x1c'9\xd0\x86\x11\xc5%)\x14q\x19sH\xbb[\xbe\xcb\xa0\x1a^\x1f\xcaxyt@\xfb\xa0\x81@P\x10\x91b\x04_\xba_S\xb9\"\xe6\xfb\xdb\\\xdd\x9ch\x19\xab\x99c\xe5\xfe\xf02\x9d\xd0\xec\xe3\xc9\xf4\x87x.\x89\x93\xa8>\x04\xdd\x0c\xd9\x03\x17B1 g\xed\xc3\xa9\xe7\x8c\xb9\x06\xa0\xb5\x18\x0d\xab;M\xf2\x99\x16f\xab\x18\xff\xf7\xc3\x8cr\xa8\x98X\xe6\xfe\xbeK\xceT\xc6\xd6\xe6Lm\xccX*\xd2dj\x1b\x10|\x048\xca\xc7\xa5\x9c'\xed\x92\xf30S\xef\xfb{a\x06\xde\xc4\x0b \xefg/\xcc\xde'\xf9\x82EcH\xdd\xda\x0b\x06\x8a>\x04K7=W\xf5An\x83\x0b\x93\xfb4\xa1\xee\x04NBpjbB\xc9\x079\xd5o\xad\x99\x94\xac\x88\xdfo\xdd0\xcf\x1e\xf5\xe8\xc6\xa5\x133\xda;f^\xd61lb\xd4L\xccP\x85\xc5\\\xefL\xcf\xc1\xe6F\xf4[e\x81\x1a\xcby1\x18/\x8c\x83\xa8\x98\x12\xa1\x95\xe9p\x1fG\xef\xe0\xb2\xad\xda\xeb\x07\xae\xc9\xed[S\xb3\\\x9bEM\xee\xe5\xfe\x9c\x9b[\xd3_O\x9eP\x1e>\xa4\x8b\x88\x89\x92\xe9O<\x13M!a\x1f\xd0\xaeJkJ\x86ofa\x94\x93\xd4n]\x91PAn\x8b\xc7J.\xb1v\xaeV*\xad\x93\xe6\x84i\xa2\x16r\xf3\x15\x9c\x0e\x14:\x88\xdf\xf7\xf7hK\xc6\xde/WQ\x18\x84,\x1dIy#\x97 _\xa5\x12\xe5\x8d\xae\x8e\x9e3\x85\xb2A/J\xfc\xe9\xbfs [Y\xe0G~jq1\xbex%\xd3Y\x89m]\xa0s&\xbac\xc6I\xbc\xc5\xbeA\x84LO\xbc|A\xa0\xec\x7f\x14f\x18\x07\xdf\x87,X\x90\xa5\xef\xc1\x1b\xf1*%Y\x12\xdd\xd0\x13!\x99AV\x04\x0b\xe6\xed\xdf\x08l\xe3Y\xcdIe\x86=\xc9r\x15Fd\xfa\xa6\x82\x9c\xcf]\x08,\xd1\x01\xcb\x85\xc9\xa5\xfa\xc1\xd9\xd7\xe6\x07\x02\x9e\xda\x0f(m\xf9\xce_)\x14v\x03\x9etK\xf2\x1d\xa4\xd5X\xd0\x8b\x01k\xac\x95\xdf\xe3{\xf2kA\xe2\x80\x98K,\xfd\xd5\ns\x1f\x98\n\xcc\xfc(\xba\xf6\x83/c9h\x97\xb8\x1e\x94H\xf3\xd0q\xea\x8b+\x9e\xb0\xadx9\xc1m\x8af\x16\x9eh\xa9z\xa6\xf1\x15m6GQ9a\xa8\\\xe7\xa7|\x84q\xed\xf3#\x16,v\xe8H2'R!!U\xae\x08Fj\xd2\xd6\xae\x16\xc3\x9aP\xc9Jz\x15\xde\xab\xb3\xd7\xcf?\xbf\xbd\x10\xfa\x95R\xc1\xdf\xb6\"\xc4j\xa8w3\xbb\x0d1\xb2\x9c:h\x1d\xdc\x03?#0\x1ck\xe7\x03\x83'\x8a~)p\x9c\x0c\x0c1\x02\x0c\xf1\x96\xb1\x9d\x91\xb9\x1d\xb9b\xb5)\xd5G\\\\\x86\xa6\x04\xd3\xa2\xfd\xa6\x86d~N\x93x\x0e\xcc3\x141\x88h\x12\xd7\xcf9\xc3&|\x16J\xe9D\x9b\xba!\xe4y.SA\x0e\xa2\x83u^{\x92;.l\x90^\xf1_\xc49+[K\x17\n\xa2R\xf0\xe6\xf9\x8a\x04\xe1,$\xd3\x12-\"C\xcfQc\x06v\x92RD\x19\xc6\xf3\x88\xf0\x11r_]\x07\x83\xc6\xfba,pn\xed\xad\xa72\xb5k\x84\xb1\xd1\x0d#\\w\x18\x7f{\xfe\xee-\xc7\xde\xb51P\xbci\x1a\x81\xf4\xae\xd1\x7f\xb1\x8f\xc9-\x14\xb6\xe6\xdcb\xc7\xa7V\xaa#\xf0\xf8X\xf5\x05\xac \x93\xbb\xad1\xd7$\xf6\x86\xc3\x9a\x19\xdf\xa1\x96\x96K\xda\xe4\x956\x81'\xf4\xa5\x1aXLn+\xd4\x1e+\xef>\x9f_\\}>?\xbb\xfa\xf8\xe9\xc3\xc7\xb3O\x17\x7f\x1b\xeb\x92\xa1\xfe\xf5\xf9\xf9\xd5\x8b\x0f\x1f\xde\x9e=\x7f\x7f\xf5\xd3\xf3\xb7\x9f\xcf\xc6\xb0\xab/\xf5\xfe\xf3\xbb\xb3Oo^\x8aR\x87\xfaR\x1f?\x9c\xbfA\xd6@)>2\xd4\xfa\xe1\xa7\xb3Oo?<\x7fu\xf6J\xed\xc6\xce\xa8\xf9E\x18\xd3\x85\xf1\xea\xc3;\xc1\x10\xbfD\x19[\x97\xf3\x12H\xb2\xd1P\x7f:\x02'v\x89\xc7\xab\x0e z8\x98NS\xe0\xe2h\xe2\xbd\xfa\xf0\xeey\x9e\xa7\xe1u\x91\x93\xf7\xfe\x92d+?\xe8\xfe6\xd3\x7f\xdb\xf5Y$>\x13\x00\xe8\xf5U \xbez\xc7\xe3\x9d\xbc#\xf9\"\x99\xf2\xef\xf4\x98\xba\x94W\xccP^\xe1\x85\xd9\xcb\"\xcb\x93e\xd9_J\x18\x16\xdeU\xe3\xb9\xb0\x97\xe4^U\x9a/\x9d\x16\xba\x1f\xf0`]\x95s\xa0\xea\xd7fL\x12f[\xbb\x87\x96\x0b\xb3\x16co\xdaw\xa4\xcd\xbc&Y\x98\x877\xc4X\xa7\x1e\xcb\xf5\xab\xfc\xc3\x0dI)\x07E\xa6\xc6\xe1\x9b\x90b\x93\xc9\x95/\xc3F\x06~\xf2/<\x05\xe2\xb0 \xf8L\x1e\xa5x\xa6\xefd\x19*(\xb5\xad\xbd\x01\xee?\x174[\xb4ms\x03\xdf\x9a7\xe8\x9c>\xeb\x08[\xb5\xf0j{\x02N\x14sA\xf9\xd2\xbbi\x00:\x96k\xb1\x88\xad\xd4\x8e;\x0es|\xcd(\xaf\x17\x19\xbf\x92w\x1b\x9c@\xc4\xca\x07\xc6\xf2\xf5\xcd\x06'\x10\xb0/dD7\x99]6lv\xc4\xa5\xe1\xd7jO4\xbeq\xd6\xf8\xf9\xd6\x7f\\\xf9[\xbf\xfd\xf2K1\x18\xbc\x1cl\xe1\xdfW\xfb\xec\xcf!\xbb}\xcdn_\xb3\xdb\xd1\xeb\xd7\xf4\xcf\xce\x01+\xbcs\xf0\x8a\xfdyMo\x87\xaf\xf1\xedh0x\xb9\xc5\xfe\xbe\xc2?\xac\xf0hx\x88o_\x0e\xd8\xed\xeb3z\xbb3\x18\x0c\xe9\xed\xab\x03\xfc\xf6\xf5S\xf6\xf6\xf5\xab\x97x\xfb\xea5\xbb}\xfd\xfa\x95&|Is\x05\xbdyu\xf5\xfc\xe2\xe2\xd3\x9b\x17\x9f/\xce\xae\xde?\x7fw6\x06k\xea\xe7\xfeVJ\xfc \x0f\xa7Vs\xfb}\xfa\xf0\xe1\xa2\xed\xa34Ir\xcdg\xf5/\xae\xce/\x9e\x7f\xba\xb8z\xf9\xd7\xe7\x9f\xb4F\x85Ji^\x0e6\xc1\xfa\xe5\x97-o\xb0\xf5\x14\x81\xfc\xe2\x00\xa19\xe0\xc0\xddg\xd0\xdcy\xcd\xa0\xb9;\xd0t\xa3Z\x1cz\xae\x1e]\x0d\xb3,d\x8e\xd2\xf1\xd4O\xa7\x0c\xff\xeb\x91y\xcbQ=n\xa4\x16\x00\xb4DV\xca\xf7\xa1\xb3\xea\xfa \xa6\xfai'\x13jj!3\xe2\xc00\xf5\x03\xb7\xbd\xb2I~\xe9\xc8\nr\x8d\xd6\x15\x8c\xa8B|3ln7\x13)\x8a\xe6\xcdFS\xcf\xef\xceO\x1c\x1c\xee\xd4\x18\x8a\x1df\xa3\xfc\xd4\xc0W4x\n\x8a\xef\xfc`\xf1\x89\xcc2.\xe1Bi\xc7\x157\x9d\xe264:a\x87\x9e\xcfX&E\x9cK\xf6\xf1\xea\xd8P\x98\x1f\xa2\xb5\x94^.V eZ\xaf\xc6\xae\x7fi\x94\xe7\x10\xb5\xdf\x92\xce\xa7\xf9\xd2K\xc9\x8cI\x91\xe7$\xffD7\xff;\xda\xea'\xe2O\xefl\xc7#\xf1\xaf\x05)\x08z\x04R\xcc\xdc\x86_\xe7$\xffk\x92\xe5\xef\x93i\xe7\x8e(\xbb*}c\xb7:6\x17q+P\xb5\x8dxSRN+3\xb1S&\x94>S+n\x08\xb0\xeb\xfd\xe0\xf1\xf3Z'74M+\xe3\x8c\x94^4'\x12\x95:(T\xc6\xc4\x13!\x97/_\x05I\x9c\x93\xafF\xdfdM\n\x10\x90\xd6S\xeae\x8b\xa4\x88\xa6\x9fWS?'\x08\x14_\x9ft\x18\xf0\xacA-B\x1d\x82\xbe\xc3\xec1\xeb \xb0\xc5\xa8]\xf6\xd5\xe3\x16`\xdcc\x016\x11P\xdbT\xadH:K\xd2%\x1b\xef\x9b\xd9{\x12\x90,\xf3\xd3\xbb~\xfe\xcb\xc4\xbb*\xf0\xcb\x17~\x1e,\x98\x86\x8f'\x8a\xc51\x9ajo\xac\x9f\nk\xe81`\xf8=0\xe0\xc8\x10\xedo\xb8\xfbT\xab?\x1b\x19\xfc6w\xf6\xd4\xf2\x183\xad2\x08\x91\"YN\x93\xa0\x10\xd3\xab J'^{\xe2\xc7\xbb\x84)q\xf4\xb5\xc5\xfeM8\xc7h\x9erf\xe5\x93\xe6{\xaf\xc8H\xfa|\xce\x1b\xde\xfe\xe5\xfal:'\xbfl\xff2\xdd\xf6r\x92\xe5\xb6\xa6\xa0\xf6\x1c\xd0\xf8x\xd0\x8d\xd7\xf0\xa9\x00\xd9\x82\xcc\x8b\x93\xa9\xc1:*\xe69V\x995\xa7~W\x8b8\xedz\x8e\xa5\x16?\x9e\xc7\xb1\x8cK:\x00\xc3Y\xb2,h\x93\xf4\xd2\xc5\x1d\xa5\xd9\xbch\xc5Z\xed\xb6E\xbe\x8c0\x8a\x1c\xda\x8e\xd1;\x07\xc6\xd2{\x8aP(\x1c}V\x00\xf1\x8bi\xfd\xd6\xd6]\x84Q)\xbbv\xd2p\xc8=\x16(\xdc\xf0?\x94db\x02\\\xdd\x0b:\xf7\x95\xd9B\xed=\xa5\xe1\xea2\x0bf\xeb\xc1\x03\xeb\x89\x92\x82a\xf9\xfc\xe9\x0d\xc6\x83\xd2C\xe1\x1c+\x10\x85\x84\xd2\x94A\x8e\xb7\xaf>\xbc\x93\x7f\xb3\xca\xc5\xddE\xf2\x85\xc4\xec\xc6\xcf\xfd\x8b\xd4\x8f\xb3\x19I\xdf\xe4d\x89\x0f_\x87\xbcQ\xba\x9d\x9fG\xd1\xcb$\x8a\x18\xc7\x8bO\x94\xdb\xd7I\xba\x14\x0e\xca\xf4\x9e\x85t\x16O\xde\x91i\xe8ce\xef\xc2%\x1e\x80\xcc\x8d\x9b\x9e\x03S\x8a\xce\xde\xf9+\x97\xfe\xc52\x1f\xfd\x90\x8e\xe1\xd7\x82d\xac\xeb\x1f\xa3b\x1e\xc6\xfc\x0f\xfb\xf2\xfc\xa7\xbf\xbc\xc5\xb5\x8e\x05\xce\x7f\xfa\x0b#\\\xc5\xddG?_\x9c\x93yy\x9b\x84q.n$(\x9c\xff\xf4\x176\xee$e\x83f\xd15^\x14\xb3\x99\xa8\x8b\x82\xfb|A\x08\xfb\x9c\xa2\xa1\x8b\xd4\x0f\xbe\xbc\xe4\x00/\x1f\xb0\xbb\xa4\x08\xb0G\x96\x88\xe7\xe1\xd2y\xcc\x18\x99\x93\xa1(Dl\xd1L\x1f\xb4\x93\xee\xccb\x92iv&\xddK)\xdd\x89\x8d73\xe0\xfb-\xa8,G\x15t\x81\xce\x1b3\xee\x8a\x94`\xc8Q\x17\"\xba\x10'\xd1%\xdd\xee\x1e\xc2\xb5c\xcd\xab8\x91\xa1\xa62\xbcI\x17\x024\x1c\xe9\xb1\x08T\xe2eQ\x18\x10\xfb\xd0\x85\xada\x97!\xafi\xbb\x9b[\xeb\xce3\xd5\x99c\xea{\x04\xc7\xeem\xd8o$xj\xee \xf6\x10\x9e\xd0s\xbf\xb9\\\xea\xee\x07\xf6\xc8PNrd\xb0w\x0de\xb8\xbb\x84\xa2;_\x0fAJ\xb8pG\xe5\xbd8\x0f\xb7o\x8a\xd8\xde;xp\xe5\xe5\xe3B\xd2\xb5\x84\x8c\x1d\xdc\x1d8\xdeL\xd7\xc3=},\xe6&\xee\xee\xda z&\x82E\x99M\xd0\x1e%\xe6&\xc6D\xf6\xc9\x08\xb9\xf6\x93\xa0l\xac\xb92T\x97\x93\xbe3\xb9&\xa4\xba\x98\xf4\xdd\xbd=\xc7\xde\x18\xd4D\x95\xa3\x9d\x03\x87\xc7\xedq\xc1jF\xcf\xd1\x9bG^QR\x8eG\xfb!\xc2\xfe\xee\xaa\x9e\x82\xe3\xa1%\x06\x8f\xb0\xb6\x12\xd1\xc2\xae4>\xfee\xb8\xba\xabPooRK\xfe}\xaa\xa5\xa8\x10\xa8<]L\xe3\xf54\x895\xe1\x18\x90\xdbB\xff\xdb\x9c\xf1Wbl\x9b'\xa5\xaf\x84n\x8e\xcd\xaeK\xbc\x9d\xa1qn\x1d\xed\xe4\xfe\x13!\xf5\x162n#\xb6\x87\x83\xa1c\x1b\xa7\x9a\xb7{@\x11\xbb>\xae\xef\xef\x0f.X~#\x8c/\xf4\n\xe5+7\xd1x\xa9\x88\xe7\x1c\xcf_\x07\xe8\xfd\xe0\xda\x9aQ|c\xa3!Vn\xcf>\xadU\x8ftat#\x89\xddk6e\xb3(\xdd\x01\xc0\x02\xcb\x86\xf1#\x17\x1c\x81g0@\x1e#ET\xf1t08\x18>}:\xda\xdb=\xd8\x1d<}:\xa4,\xc7\x9a4\xfd\xb7d\xb5lM\xa1\x07[0d\xe6\xc0\xd6\xbb0fVs(\x12\x06B\xc9\x0f\xf8\x17\x0cyFi\x90#\xb8 \xb30\x87E\x9e\xaf\xc6\xdb\xdb3? \xd7I\xf2\xc5\x9b\x87\xf9\xa2\xb8\xf6\xc2d\x1b\x15\x99\xdb\xd3$\xc8\xb6\xf1\xe3\xad) \x92)ar\x9f\xd30\xbe\xf1\xd3\xd0\x8f\xf3\x13\xac\xb2\x96:\xa6L\x1bHQ\x8e\xf5\xc4O\xe7\xd9\xe4\x92\x95\x8bi\x15\x9f?\xbd\xa9d\xdfRb\x19\xd8\x84\xa1\xeao\xc4\xea\xc0Qc\xae\xb6\"\x8a`I\xb2\xcc\x9f\x13t\xb4\xcb\x08>\x8f\x93xk)F<%7@\xe2\x9b0Mb\x14\xaf\xd2\x8f\xf1C\x1cG\x06~<\x05\x7f:\x0d)\x80\xfd\x08\x16$Z\xcd\x8a\x08n\xfd4\x0e\xe3y\xe6)n27<,d\x95oHM \xc0\xa8\xbc\x04\x85d\x14\xf6o\x04p\xe0\xa70\x89\x90\x9d\xc2\x8c\xb8\xb3\xd4_\x92\xec\"\xf9\x98\xac\xe0\x84\xceT\xf2\xc8\x8d\xd1\x87\xbe\xe3IC)]CJ\xb7\xeb\x1c\xc9\xd3\xf5Vk\x8bI\xa7x\x03\xedj\xaa\x86\xf7\x998\x03\x1a\x91\x04\xa1\x81\xf4r\xe1\x1d\xd5\xba+\xa4\xc6j.Up\xdat\xb1\x1aW)L\xf0\xd9%\x93\x94\xc6\xcd\xc8\xc0\xd887T\xe9\xdb\xbcu\xcd\xca\x9b\x932\xf2z\xdf\xa3\xdc\xb5_\xa5\x1a\xaf7\xa5\xa6\x0fi\x99\x8ee\xcdJMu2}M\xbf\xaa4\xda\x0bm\xadl\xd6{\xd7\xaaqU\xd7\xd6\x8aa\x0f\xfa\xd7\x8a\xc5;k]\x1b\x9e\xb2\xab\xa2\xae\xc2Od~\xf6u\xd5\xb7\xb6r\x8d\xb2\xcf:\x16i\x0f\xa7F\xb9\xee\xfe\x8e\x8dR\x1b\xaf\x14\x0f\x84^\xbd\xa7\x1fu\xf4\x1dq\xea\xda\x15\xe3WR\xcd\x0c\xcfIf\xe5X@\xd7\x9e0\xea\xe8\xdd\xa4(\xd5\xb9d>\xa6\xe1\x12\x0d\xfc\xfaV]\xedk\xd4\xeb\xe9P\x07\xbe\xd0l/|n\x88\xe5\xa0[\xe2P\xcf\xc4\xa7\xed?\x93O1\x970~S\x16{p\xca\x185\xb1\xbd\xb7\xebx\xec\xbd\x9e\n]\xdf\xfdWs\x8e\xe1\x04J\xc1K9'#\x0e\xd9\xbf=\x7f\xf7\xf6\xeck@V\xfcx\xc5\x97)\xf13\x9cY\xc2\x1f,\xfd\xf4\x0b\x0b\xfc\xc0n9\xe9pR%v\xa1\xe5)\xcc\xec\"\xfe\x12'\xb71\xb0g\x8e\xe5\xc0&/\x85\x95\x9c\x82\xc52\xfe\x89'\xe5)f\xe3\x99b9n\xd9\xe5U^\xa4\xe4<\xf7\x83/\x17\xa9\x8fQ\xc6\x0codk\x19)\xee\x01\xad\x10\x9fe\xb4$\x86\x0d\x14\xc4\x87\xc3\x9f\xd1.K\xe9\xcd\xca_iK|\x0b\xd6 9\xedOj\x8c\xbb\x90\xd6_\x8a\xb1\xb6\xae\xec\x1b9\x1b\x01\xce\xd3&Xc\xd0G\x0c\xc9)e\xd79 .lT\xc1\xfcq\x1e0\xe1\x07\xa3\nM\xd3\xe1(\xa1\xb4\xd6\x8e\x83\xd3%\x8884E\x91\xa0\xd3\x94*>$\xa5\xff\xc8$\xb6wv\x07\x8e\"h\x15\xbe\x83\xf8\xfe`o\x88\x96W\x07{#\xb5\\\xe5j\x82\xe5vx\xb9]\xfew\x8f\xff\xddw$w\xf1G\xecN\xf1T\xe6\xaat\xe9:b{\xd4Hu\x11r\x13\x08\xf5\xb90\x8dP\xa5\\E\x15\x103\xf5\xe6L\x14NX\x0c\xaf&\x92\xc8L\xd2-\xd1\xd3\xb61\xaaeso\x1af+\xca\xc82O\x0fo\xb5\xf032\xfdD\xe6a\x963\x05\x08Z\xeeNbs\x14\x89\xc2&\x8d\xa0\xec\x0f\xf4Y\xdc\xb4\nJ\x99\xaa\xdd\xbb\x12\xcd\x8a\xa1\xa2\x01\x8b\xf6\x05\x8b\x1c/\xbdy\xc3\xcf\xb6\xc6'\xe5\x0b\x17\xeaq\x86\x9a@\xd4\x04\xd4\x14\xe1\xfaz\xc1\x03\xa5\xfc^\x9e\xfa7$\xcd\xc8\xc5m\xf2\x91\x96\xb3\x89w\x95\xfb\xe9\x9c\xe4\xb4+.dJN\x9bf?\x02\xbd\x18}\xad\xbe\x98\xe6\x97\xd9\x99\xc8\x1dj\x14\x03!\x9e\xa3|=\xa6\xd6@\x05\xb8\x00$\xd3M7#X\xd2K3\xfaX\x1d1@]\xe6\xd1\x1c\xff\xcc\xb4H\xd1\xc8\x85\x99s)PH\x95\xf1\xb7-\xef\xce\x8f\xf5 \xa1\xfb\x9a\xafj\xcd\xc0\x1f\xb3\x84\x93o[\xc2\xd0 \xc8U\xdf\x05\xadB\x80\x16\x9a\xa9\x0bw\xa0I\xc6\x04\x1c\xae\xd3\x86\xce\xd7\x0f\x82bYD~^.\x85W\xbcM\x92u\x19pb\xf0\x83\xa8\xd5R\xb2\xad\xfa\xf3/\xe1\xea\x02;\xde\xab!U\x15nj\xe8U\x98\x92 _s\x14\xab\x9e\x95\x9f\xc59I\xdf\x12\xff\xc6\x00\xa6\xd2\xb4W\xd7R\xb5\xed\xaajlf\xcd;\xe3 ]L\xabF\x7fRO\xf1\xe97\x1f\x8d\x86\x93Q\x1fy\xaeyb\xf2\x88\xceC\xdd\xc9\xa8;I3\xc3I\x1aUI\xa6~Ws0a\xcc\xf9\x86\xc9\xd1\xacK\x8c\x04b+\xd9\xa1G\xbe\x92\xa0\xc8\xa5y{\x13\x7fH\xa7\x84\xd3\xedh\xfb\x95}$i\x86\x1b?\xb7\x193&\x13\x94\"\x0f\x91\xdd\xd8\xdd\xf5^\xf5f\x8f\x11\x81n\x0cZ+\xeb\xcd\xb9\xb3\xca\x86\xad\x95-\xfaVfy(\xe9\xf4\xae\xd2$A\x93\xaa7\xaf\xea\xf5\xd6\x17\xd2M\x03\xadH\x1e\x00\xcdF\xd8\xcb\xb3\x1b\x12\xe7\xccl\x01\xe7a\x0c\x89\xa7\x7f\xd3D\xf4\x8dr\xd9\x0b\xee\xde\xa7\xa9\x83\xbfk\x9d\xb2\xa2\xa4\xdb\xfa\x19\x06ku\xe51S@ZOw-\xfcR<\xd6\x1cD7\xdce`\xd1H\xf4I/;\x9a\xe4,\xfbh\xc4\"\x81\xfd\xfe\xe08\x93\x10#H\xe8\xeb\xc2\x94_\x8d\xf3\x81\xd9\xebd\xda0b>\x1a|z\xd3p\xfa\xb1\x1a\xbc\xeeY \x866\x00J\x84o\x0f\xa3|\xa1I\x8b\xb4=\xa3\xe4C\x9f9\x00)6\x84v1\x8b\x0b\x835XI\xfc2\n\x83/\x96>\x90B\xa3\xdcK\xc6\xe6\xf6(\xfe*)\xae#\xd2\xb7r\xa9t\xff&\xde%EF^%\xb7\xf1:e\xd7\xac\xfe]r\xb3V\xd95\xab\xff\xbc\xea_\xb2\xbbj\x90\xf4t\xf6\x06\x92\x8a\xfeu\xc4\x12\xbcbT\xc0\xdc\x05\xeb\xba\xc8s\xb6Cy2H+\x8cWE.?\xc8\xd0\x14K~\x92\x93\xaf\xb9\x9f\x12\x9f?sZ\xbc\xa8[#s\x88K\xf4\xb2\xe98\x05\xa0\xea \xc4\x85\x87s\xe3\xcd\x03\xb3\xceV]'DDJ\xf59\x8bY\xed\xc8b:=\xeeH\x8dx\xa8T\xf2SZ~\x92^\xb6a\x00\x96/\xe8\x11H`=\xb4\xc5\xf9\x8a\xdb0\x8a^\xd5Z4=g\xed\x9bG\xae\xc7AX\x1dO\x81\x94N(tz\x0c\xfey\x14\x95lC\x17\xd5)\x98<=\xe0\xeby\xbc\x15\x12[\\\x14O6\xfcpc\xb4\x82\x89&\xf1\xe5$\xbflC\x8ab\xfcf\xf0\xeb\xc4\x06\xe2B\xf8\xa4\x86i\xd0=\xb7\xb9\xa1<\x87)\xef`\x8f=\xf1\xa0J\x90\xf2\xd4\xe7\xc7{\x7f\xca\xbb\x84g\xe8\xf2\xa3r\xc5H\x83\x9a\xfd\xa1\xdff\x7f(.a\x87\xe8O2\x03|p^\xba@O \xda\xc8\xab\x8dF\x1e\x83\x19\xf2\xccv8D.7\xa4\\\x91~q4\x11K\xf3 \xdf\xdea+\xbc\x99\xebU\x13\xdefR;\xc0\xbe\x05\x1a.X!\xba\xd2$ Y\x86U\xffo\xdaHW\xf5b\xcf\x04M\xe8\x94\xfc\x01d\x88%\xe1\x14V0\x86\xa9\xe32\x80Q\xaa\x0c\x93\xb1\xfa^JP\xd5\xfd\xd2/\xe6\x8b\x9c\xe9\xc2[\xbbyu\xb5*\xd29\xe90\x81\x89*S\x0fc=\x12\x91\xf4\xc2\x8f\xbf\xf4\xcb\x8f\x1d\xd5\xeb,\xef\x0c,!\x0b\x01\xf0\x8d,a#\x85\x97` \xd5$A\xfa\xe8:7!\xb9\xed\x9aK(\x83\xe9\xd1\xd2U\xd0n\xbc\xd5\xaf~1\xfd\x89\x16e\x82\xf0\x99\xf4n\xc3x\x9a\xdc2\xcb\x81\xb2b\x8d\x87%H\x87P\xeea\xe2\x85W\xdcKM_\xb8<\x0eO!\x16!o\x7f\n\xc9-\xc6t\xe5\xfe'?\xb3\xc6\xc7\xc0z\xd1\xdc\x85MffJr?\x8c\xfa\x00\xac\x04\x12\xfb\x84\xb6\xdb\x199\xbb5B\xa6\x0b\x89\xda\x16oCRZIy@\x1bf\xa3\xf8\x85\xe7\x17s\n5\xcc\xa3e\xfb\xcc\x0bT^\x94\xfe\xb7/J\xb5\x93\xcb\xe4\xa6\x13_\x10\xcc\xa7\x1e\xe4o\xe2\x9c\xa4\xb1\x1f \x01\x1d\xdd&\xa8El\xdb\xae=\xc4R\xe5t\xe8\x9bi\xab}\xe1w\"\xd3\xbaF\x9e{\xff\xae\xdd\x90\x92\xbe\xde$#1C\xcah\xd7\xac\xc7?\xbdTS8\xa9\xd5\xf7\xdb?nH\x8d\xbcLVwi8_\xe4`\x07\x0e\x8c\x06\xc3}\xf872\x85\x9f\xfd\xdcT\xec\xefdz\xcb\xea\xabl\xc5\x02\xbaz\xd1E\xb0,\xff\xe3\xf6\xffQ}\xdc0\x1f(\xfa\xcd\x05u\xab\xd6:)\xa9D\xbd,\x91G3t\x02\xc8\x14\x16\xe1\xd9\xbe\xa5\x10\x17\xcdh\x95-\xe1,\xc4\x86\xafl\xeat\xf49plo\xcc\x9f\x0c\x92\x90\x85\xcbaR3Q\xa5$\x958\x81P1Y8\x81\xd0\x01\xc2\x9c\xfe\xda\xa8\xb32}L\xddb+u\xca\xaf\x13\xcf_\xad\xa2;\x9eP\xa9\x95\xbf,+\xaby\xc3\x86z\x82O\\\xe5D`F\xa0\xd4\x11\xc6\xc6\xa9\xc8\xcb\x93rG\x17\xde\x1f\xff\x9b\xe9G\xc2\xf2\xceZ\xd0\x1aKR\xc6c\xacy\x814\xeai0\x92\xd2\x85\x0eGk\xd7\xb4\xa2-x\xb2\x9e\x9e\xfa\x81C9\xc7\xd8\xb4(\xcb\xade\xf7\x95T\x9e\x0f\xf6zV\xc8\xdc.\xb8\x0f\x8a\xe3\x9e\x1b:\xd5\xf3?\x81A\xaf\xda]\x16*\xbc\xde\x9a\xe8i\xea\xc7\xd3diw\xfan\x18\xbak1\xf36\xdb\xf2\x82$\x0e\xfc\xdc\xae\x85\xc4\xc74\xc6cJeX\xce\x95\xe5\x82\xbd\xb9\x19\xc3&\xa4Ne\x0e\xb1\xb3\xff\xf8\xe43\x8dh\x06<\xb5e\xe39Sp\xec6\xe6\xcb\x07\x83\xd5|\x05\x8d\xdcc\xd9o\x87\x83\x81\x03\xa7\xfa\xd2\xd0-ZF\x94V\x06Y\x0d\xe9\xf2\xdd\x188.\xa46\xe5\x9d\x13\xa7\xdd\xd0\xdd\x14\x8c\\\xb6v\x7fh\xb4g\xcdInQ\\\xc1\xacW2q\xd7t\xfc\xb2\x9e\x07\x94aKR%\xdc\xb4\xc9\xf3\xcbBw\x0c^7\xe5\x0cE\xb2i\x0f_P\"\xf1\x11KTsP\x89\"\xeb\x9a\x17\xc7e\xce\x88F\\\x9f>=\xc1\x9d\x11\x9002l\x9aY\x94$iW\xef\x0c]\x0b\xb3\xf7\xfe{\xf4\x81\xd9\xc44\n\x03\xe6\x12\xc3v}\nc\x88\xd7O\xe8!\xe1\xa4Q\xaf\x87J\xe3>\xc3\x99\xa6\x91\x1b\xb4\xc4qn\xf4\xc1 \\R\xcaK\xddh\x98\xd6\x88\xcb\xd4\x93\x9d\xfe=\xd1\xb0n\x9aO\xea\x9d\xa91p\xf2\xa5\xf0\x8c\xba\x05\xd9\xe7\x0c&\xd5\xa9[\x92ofC\x08X\xe3\xd05\xef\x97\x7f\xa0\xe7\xaa\xd9Gr_\x9f\xc8b\xcf\xe4\xc3\xd9\x89\x0eR;Y?\xffZ\x97\x98gO/\xe69\xd0Iy\x98\x87Y\xf3\\\xc4A\xd5\x1f3\xbd\xff\xb0;\xc7\x9e\xd9\x14.cF<\x1ao[\x96\x94\xdeGk%\xcb\x82 \xb9\xd4\xb9\xf7\xa2\\\x7f`\xf0\x06\x8f\x1a\x11\xd8C\xb3\xe7\x1cH\x82']8`!^\x9ad\x97]\x84\xaaT\\\xe3%\xe72\xef<6\xa6f\x02\x0ds\xc21X\x1f,\xd8\x84\xcdMM\xf2oq\xddj\x93l@\xe3\xdc\xc1'\xad\x92\xf9\x99H\xeb\xa2\x8dfB\xaf\x7f?\xfb\xdb\x184\xf6#\xef\xcf\xce^\xe9\xd3\x17\xce\xfc,\xffw\xa2\x86\x873mg\xcc\x1a\x90\xc8A5\xb5n\x0b\xcc[]\x9f\xb6\xf2\x14\xacs\xca\xfdX\x1f\xd1X\x9f\x98e\x1d\x1b!NOk\x04a,\x97\xd5:\xf4\xdaj\x97{lT\xd4\x9bu\xd6R6P]_\xc4\xa5\x9fLq\x86N\xd2K/lNl\x13\xf2s\x92\xffL\xfc/\xeb@\xfeQ\x00\xd90\x84H\x84&<6\x86\x7f\x088zi\x05\x92\xf8uJ\xc8o\x9dBn\xa8*\x8f\xd0\x1e\xd4\xa3\x8b\x9b\xfe\xc2\xd8vO\x9e\x80\x00\x13\xfd\x1d\xd8u\xb6K\\:\x02\xb0\x8d6c\xfc\xee\xef\x0fe\xb8\xe77\xd9Y\x19yC\xfb\xf5Z\xb4\xc9\xef\xdf\"]\xd6W\xadw{\xcf]\xb0\xaa\xc8F\x0d\xf7w\x8e\xf2\xe4xG\x947\xf7^\xbe={\xfe\xe9\xea\xc5\xdfPs\x847\xf8\xeb\xfd\xd9\xcfW\xcf?_\xfc\xf5\xea\xecS\xf5\xe0\xfc\xe3\xd9K\xfa\xe0\xea\xc5\xf3\x8b\x97\x7fm<.\x1f\\\xfc\xf5\xd3\x87\x9f\xdfkJV/J\xc5\x05\xedCLn/(}\x1b\x9f\xa5\xed\x9eg|u4\x97\x0e\xc5A\xda\xa8\xcd+\xff.J\xfc\xe9\xb8%\x83$\xd4\x89y\xb5C\x18/\xf3[z\xa59@\xca^\x91\x8e^\x9c\xafH\xf0\x8d@\xc9\xbe\xbd\xf9o\x06\x81&\xbe^\xef>\xbf\xba\xa6;\xd7j2\x01\x0d\xc4]~\x9c\xadH\xa0i92\x1f\x02\x8dO\xb5\xad\x06\xbac\xa5\xfc\xd4/\xf2\x85\xa6\xd5Y\xedT\xc2\xd2\xb8\x80\x95b\xab\xaa\x18;\xc9\xaa\x92W\xd7w\xcc-\xb37_\xb6\xaf2X\\\xc6\xaeK\xdcY\xba?3\xa5\xc0\xe5\xda\xe1C\xdaH\xed\xfb{\xb4\x0fa6?\xc4\xa1\xef*\xeasMfs\x7f\xc7\xe1\xec\x96\x0b\x16s?5E\xaf\xeaE\x98H5\x0f\xf4\xee\x88\xfb\x0d\x19\x0bO\xf7?\xd03\xb0\xfb\x03\xbd\xf0e\x7f\xb0\xdb7\xdc\xb1\x10nli\x98\xa1\x98[U\x01W\xd3\x0c0\xe6\x16W\xe2\xd6\xd7\\\x92r?c\\@\xb6s\x04\x9b\x9b9\x1cCl\x0c\xb3\x99\x1a3\\3\xafa\x92\xdb)f\xcfK'\xc3\xcbv)\"\xbd2\xd9\x0b\x98\x9f@\xa9[{\xccm\x0fO \xa9?\x9f\x13\x96\xfc\xaa\xf6p\xe1\xa3\xe5J\xfda\x86%\x8b\xbauK\xb6\xde\xdc\x0f\x07{}$c*\xd8$\x93\xd0\x13)_x\xbc\xb5u\xd4\xe4C\xb8\x94~\x12_\xb2\xfc\x83\x92\x19\xb0\xf6\xac\xd8\x1a>z\x8f\x0c\xba\x93\xd1kFS\x0d\xe4\xeaj\xea\xe7\xfe\xd5\x95\xb6_\xa9\x9d;p\n\xf1D\xc3:\xe7\x94u\x16\x8f\xc7`-\xfcla\xd1\x134\xf6\x96\xfe\xea\xd1\xe31\xb8C\xed7\xe2\xf2\x89\xf0v\x06w\xa8]\xfd\xc6\xec\x11\n\xd7\x84\xeeD \x9dlA\xde\xa5!\x85\x86.:\xc6)\xf86*\x93\x12\x9b\xe0\xba tg\x89T\xddc\x94\xb8v\xc0M\xee\xdbZ\xbd'\xde-\xb9^\xf9\xc1\x97\x8fIt7\x0b\xa3\x88\xab\xe4\xa7d\x95\x92\xa0\x99\x17\x14=\xdeW~\xbe\xc8\xb8=I\x15z\x99\x7fY\xde\x9e\xb0\xf4\xb3z\x06\x8f\xb8`\xb1dM\xda\xd8f\xb5p\x91\x9a\xf0tk\xc5>#^\xd4x\xad0\xd6\xad\xfd\x0c\xffG\xfa\xa8\x11\xc64\xfa\xd8\x9c\xad\x13\x18>R_\xab\x9a&\xd4\x07@w\xdd\xf6\x7f\xda\xa7\xe3\xc1\xfdd\xb8\xf5\xf4\xf2\x97\xe9\x8f\xce\x9f\xb7\xbb\xb6\x88\x01\xa3$\x95\xb1\x8f>\xef\xfb\xc6\x86\xfd\xff\xb3\xf7\xef}q\xe3\xc8\xe20\xfe\xff\xbe\x8a\xc2\xe7\x9c\xac=\x18\x03I&\x97\xce\xb0,\x03\x9d\x1d\xce\x06\xc8\x0f\xc8\xcc\xce\xaf\xc3\x971\xb6\xba\xdb\x1b\xb7\xddk\xab\x9b\xb0\x9b<\xaf\xfd\xf9\xa8$\xd9\xb2,\xd9\x86\xb0{.\xcf\xd7\x7f@[\xd6]\xa5RU\xa9.T9\xd3\x18\n\xc9`\xc4*{\xf2\x04\\\xd5EI\xde\xf0A\xb2\xb1\xc7M\x87\x0b\x1e]\x80xX\x80\xc0\x1f`k\x97\xff\xfa\x0f\xf4e\xcfi}\x8c\xc5\xfb\x80\x99\xd2]L\xf5\xcd\x82\xed(\x17\xfa5\x8a\xe9\xa2\xf9z\x8b+\xd8\x18\xf1\n\x86\x03P\xba\x82*\xae}\xc8\xa1\x83\x90\xd2\xb1\xa1`\x1f^Y\xc8\x9dg\xfa\xfd\x99 w\x9e\xe9\x0e\xc6\x05V}\xa6\xd3\x99\xa5\x99*M\xc5%\x81^\x0d^\x18\xb9\x85\xd7&\xa4S7\xf7\xdats\xea&Zj\x8c\xa9\xa1\x96:\xc7\xd4\x95\x96\x8a\xe1\xdd\xea%q\xb9\xe1\x91\xe2m(\xfc9!\xb7W\x08vk\x97\xbb\xe3`\x7fQ\x97\x8c\xbb\xacqw=\xae\xd5\x947\xca\x9e\x84K\xb5X\xee\xf1\xd01j\x96\xf7E\xbeHJ\"\xb3%\x01\x0f*N\\^_\xd8\xc8|A\xa8Z_\x88YV\x8d,\xbf\x90\xf0\x93\xd6\xec\x8ao\x0fw=\x08ZK\xe3=_\xa62\n|c\\9r\xcf6\xfd\xbc\xd8\x9d\x8b\"\xf4\xc1>\xa4n\xc6\xdd\xdbh\xd7~\\\x81P*)\x18/\xf7\xf1Z>\xea\xbc\x967\xac\\\x9b\xa6\xc5z\xa6\xc3\xea\xc1\xe9\xb4T\xb1\x1cVE\xb5\xca\x96j\xe2a\xd5\xe0\xfa[\xaa\x98\x0f\xab\xa2\x82\x8fFn\xa3\x8a\x81\x8235\x05\xf2AV\x0d\n\x89\xfd\xecu/\x95e\xbf|\xce5\xaeG\x88nF`\xb4%\x13}W\xb4arq\xaa\xf49F\xb4v\xbf%T\xe1\xd8\xf2\xd5\xce\x90Au\xf2\x0d;\xdc\xb9>\x1e\x82\xe8[\x97x^\xcdJ\xc8x0l\xf3f\xf0\x03$o<\x94i\x91I\xee\xd2I\xb6\xb9y\xe5]\x19\x07\xcf\x8d\xf2\x90\xd7\x16\xf4\xa8\xa6_?h\x02\xccr\xfb\xfaZ\xb45\xb4\x0d\x1a\xacIQ&\xdc\xef\x92PE\x92IA\x92\xc5\xe4\xf3\xd9\xd4u\xd6;\x81\xe3u\xe7\xd8e9\x9e<\x11\x02:s\x8eW,\xcf~\xcf\x85cF>\xd3\xcb$\xd2n\xb1z\xf4u\xfaUX\x18V\xad\xd5X~\xefDa\x9a\xde\x84\xd1'\xa7\x92\x1eb\xf8Y\xb8!\x8aZ\xcb\xef-\xaa\xc5ka\x07\xc7c(\xb4\x94\xb3\x8de$\x8e4\x06F\x92\x0f\xa2\x85\x9d\x1e+_\x8b\xc2\x97|$*\x08\xe4LZ\x8d}\xa0G}K>\xed\x1a{ie\xf5\x11\x1aT\\]\xdb\xa2X&\x1f=\x10\x89\xfat\xe9w\xc9\xe7Q\xbbjU>\x93Ooo\x9f\xffk{k\xd5N\x93OW\x87\x07\xd9b#.D\x12SRS\xee\n\xb6\x90\xb3 \xb9\xb9B\xc8\xd0\x9e\xdc \x1e$\x93ps\xf3\xaaa\x8d\x10\xf6D\xe5\xfd\xe6YQ\xcd\x03zt\xfd\xbf\x0e\xbd\x81\xd68<\x14\xe3\xd5hL=wU\x07\x89\xdf{f\xcdx\xbb\xa6\xb5\x89\xcc/\x84\x97E\x93<2\xe9;\xb2\x92\x0c\x91\xe0$\xbb\xc2s(S\xfc\xc2u\xd9\xb5Y\x84\x10y\xf5]\xa9F\xfe\xca\x83i\x91/\x00\x9d\x83\x85i\x9aG\xca\xcf\x0fY\x19NI+\xe1\"\xcdo\xb5#\x81\x91\xa3n\xe2\x16\xdc\xa7\x0c\x0d*w\x94\xa1\xe7C\xe2\xe6<~b\xc8\xdb\xea\xa7G\xf0h0x\xce4\x1f\x0c\xceA\xe34\xc8rq\"\x88\n\xcc\x94\x8biRX\x0f\xf9\x1c\xdc\xb3\x8b\xbdg\x97\xd6\xc5\x8e\xeeI\xb0j\x9b{6I\xae\x0d\xc1\x14\x98\xc2\x05\xc2>\x14\xc14\x91Z\xc1\x8c\x86\x13\xaf\xcaoT\xb07\x8c],z\xaf\xf2\xe9?a\xec\xf5\xd2\x98\x16E\x01\xbe\xff\xc2\xce\x15\x01\xeb\x81`G{\x05\x87\x83h=u#e\xee\x8b\x97\xdf{\xae3\xcd\x8bq\x18\xcd\x9dA\xa8\xa8O\xe3\xf5\xd9\xaeY\x10\xf1\xcc\xe2\x06r\xf7\xb5.)\x10\x82\x88W\xaa\x18\xd7\x1dL\x8c#R\xc3\xf8$+T\xcfL\x8d3\xdb\xbaC\xfe\x01\x9e6\\\xe5n4\x84\xban)\x9c\xc3r\x97\xb1D\xb0/\x0c\xc2\xcb\xc6\xd1\xf5T\x04\x8c\x94\x8c\x0dFO[\xa1I\x13\xe7\x0b6\xd0n\x08\x93\xc3J\x7f\xd3\x89\x1c\x11\x93KI#2\x04\x97\x92v\xebx\x9e\xcf\x0d\xe1\x1b\xa3\x82Z\x91\xc6\xe0\xc6\xb0\x19\x96%kgP\xc5\x9fI\xfbs\x1d\xa2G\x8fK\x0c%\xdb\xfen\xee\x96\xac[ld\xb5x\xf6\xab\x17\xcc\x86\xf2\x83b\xa9|\xdd\xef@u\x0di^\x15\x945\xf1@\x06\xe6\xc5I\x1b\x8b\xf3LY\x1c\x86\xceh\xa5\xec\x03#H\xc4=\x88\xf8\x8e\x16\xe8\xcd\xef\x19\xb7qS\x1a\xe5\x1fqA\xd3\xba\x0f\xca\x17\x0d\x18$ \x945 \xac\x0c\x80P\xb6\x00\x01},\x98\x16\x1d\x05\xd3\x86%G\x9bd\xc3J7A\xc1\xa0\x01\xa4\x82B\xa9\xafv*V;\xf5D\x0c\xbd\xe8~(\xa9\xc6\x12\xadp\xb9\x02I<5_\x01={f2\x18\xcb\\\x8b\xb0rwW\x17nrt\xb7\xfbB\xc7M\xdc\xa7D[R\xa9\xaa\xbd\xb8TS\x82\xd5\x87\x88\xbe\x05\x97&\xb8\x8e}\x98\xfb\xb0\xf6a\xe1\xc3\x0c\xf6`\xa9\xaa\x89\xdbhU);n}dD\xa5Y\x94w\x87\xc2\x06\xde\x11\x06\xd9Oa\x04:\xbae\xcf\x0d\x92\xe0\xcd \xb6q\xc6\xb3\x1e\xe3\x8e\x84r8i\x99v\xb0\x1a\x13wf\xd4\x19E\xba3\xe6\xa6\x072F\xef\x1b\x88\xe1\x0fp\xf3\x06n67\xcd\xd46\xab\xd1]\x08G\xacwn\xe8\xce\x91T\xbd\xb9\xf2\xf0\x8em.\xee\xd8\xee\\L\xf3P\x06\x81\xb7_\x0b\x1e\x0b\xb2\xba\x9a]4!\x1a\xcd\x7f\xcd}\\\xc3\x1eTq'\xde\xc0\x066\xb9F\x8e\xc3\xf5\xbc \xce3b\xb8\x14\x06\xb5\xb3\xb9\xbb\xf6\xe1\xce\x879\xb7\xc5\xe3w\xc4\x03\xba\xf6\xd5\x0b~<\x1f\x1f\xfc\x99\xc7j\xa5\xc1\xf9\xf8\xf2\xc3\xf9)\xec\x89\xdd\xf6\x8d\xe7\xb3\xd5'u\x11\x1c\x8d\xdf\x1e|xw \xfd\xfe\xa9ww^\xf5\xf8\x9d~)\xfcL\xbf\x12\xff_\xdf\xdb\xdf\xb4BR<\xb7\xdcm\xec\xe8\xdb<1\\\xf1\xdc\xdf\x94\xd1rH\x85Fm\x8aD1pD\xee\xc5\x0d\xb1\x18\xddd\x83\x00\xad6a&\x1f\xec\x96\xd6+W\xa8\x869O_\xeaGCU\xcchc]}\xb5-\xdc\x0e\xa7}\xd9\x7f\xdep\x05\xa7\x07\x82\xc9\x8cxp\xf8\xda \xb39FQ\xde\xe2(\x10\xa6I\x16\xa6ig\xd7:;\x0eP\xb9&\xeb\xcf\x08r\xa4Q\x9a\x97b\x00\x9d\x05\x9aF\xe6\xdcu\xc5\xe0\n\x86\x0c\x0e\xba\xe6\xde\x93\xa8\x15{\x1a@\xba\xd2\xb0\xd9)\x81d-\xb0\x11s\x03a\xdbu\x8b|V\xed\xab\x05\x90\xd8\x81\xfb\x83GM?\xae\xff\x93U\xbcNh\xe7u*\xcffA$\xa0\xf8\x80\xbaa\xa7+\n\xae\x01\xd6\xa3T\xc5\x88,\xe7\xc9\xdfV9}\xd3\xe1\x8b\x83=7\x05 ?\xd9\xb3\xf0\xd6^\x0di-\\,\x1f\xa5\xb1\xd7C\x1a\xfb\xb7\xcfO_>Fk/:\x14\x0d\xa1j-}\x94i|\xd1\xa3b\xc8\xdb\x9a}k[\x83t\xd8\xa2<\xa3I\xb6j\xdf\x0c\x81\x95\xc5\xe3|0j\xf6\xbb l2\xfcX\xaen\xf8\xb5\xb5\xbb\xf2!\xf4\xe4e>\xe3@\x19+\xbc\xa9#:s\xe5b\xaf\xca\xfa\xf7Y\xc9v\xe50\xd2C\x0c<\x92\xbaH\x83\xea2\xfa\xa67\x851\x0b\x852\xb5\xd9@\xaf\xcd\\\x96\"\xbf\xce@ [\x92\x96FId\xb8\xb5\x9d\xa2p\xa1\x99\xb6l\xa3\xabvx>\xf6\xd0|yp\x93\x17t\x04N\xc8\xfe\x1b\xd0\x1f\xcb\x92%\x0b\x0c\xe11\xce\xe2\x11\x94\xae\x13\xca\x04\x92\xc5\\\xff\xb9\x99\xd4]\xcb1%<\"H\xb3\xaeD&\xeb5\xd6\x1f\xba\xeb\xbd\xa0!\x1b\x89Zg\xc9\x92\xf4\xfax\xa2\xb1\xae\x1f\xd3U1\x02\xe7&]\xe9&\xed\"\xc3a\x98\xbdO\xc3\xbb\x118Q\x98-\xd3\xf0\xae3\xdb\xe5\xbc\xc8W\xb3y\x9d\x9b\xf2\x04K\xa1y\x98\xcd\x08\xcb\x8c?,\x99RT\x01w\"\x8c e\xce\x92/\x96y\x99T\x0b\xe6Du\x82uu\x94Bb\x1e\xd5b\x1dS\xa6\x14\xfc\xb0\x8cQ&\xa0\x96\\a\x9a\xadhF\xc9gzB\xb2\x15\x16\xc2\xb7\x05\xc9V\xb6\xecK\x9c\xf8|i\x9b\xf5\x15v{e\xe9\xa9\x12\x1ek\x04N|\x93v\xcc\xe1Q\x11\xceX\xa6\"\x9c\xd93\xf0\xd9ey\xac\xd3\xca\xb3QRT\x19)\xb1\x80\x16f\xfd\x9cP\x99\xf3sb\x1bG\x11\xce0\xc0\xa3\xc8\x99\xb2\xdf\xf6\xacg\xeb\xaa\xf5|\xdd\xd5\xb8\\w\x96\xb3c\xc1\x8f\x8a|\x89\xb9\xf2\xa5%\xc3\x8ao\xd7\n\x9ec\x91\xd0\x05\xd7\xe3\xc5\x92&\x84\xcd'\xe1\xbf,\xd9\xb2\xa8\xb8[R\x9eQ\xfe\xb6e\x8dE\xb6\xd8\x9a\xa5(r67\x84\xfd7gy\x9bG\xabr\x04\xce\x94\xfd7g9\xce\x96\x08x<\x02\x981\xcb\x9f\xc9\xddQ~\x9b\x8d\xc0\xf9D\xee\xe2\xfc\xd6\x82\xca\xfeL\xee\xde\x17\xa4,y\xbe%\xfbi\xcd\xf8a\xc9s\xad,\xab\xf0\x0e-\x93\x19\x0f2\x92f\xca\x8cs\xe9\xca|Bh\x18\xab\x05\x16\"\xc1^H\xc2\x0c\xcb\xdf\x013U\xe0\xb8\x118\x0b\xf6\xdb>\x07U\x108\x99\x95qW\x1dY\xcfp\xee1gn\x9b~\x9e\x91\xef\x03\x9e\xd3\xba\x11D\x988\x99\xd16\xbb\xef\xc3\x121\xdd\x92\xfd\xb7eY\x95<\xcb\xaa\xb4e\xe1G\x89\xfd\x1ca\x19\x92l&\xf2$\x99\x05\x19\xbd/\xf2\x99\x80\x9b\xa5\xf8i\xcex\x1eRRm\xcb\"\xa4\xa4kKr \xdb\x08\x9c\x12\x7fX2\x11\xf2 \xb7Y\x89?\xec\x99\xf80J\xfe\xcb\x96-\xe5\x91=\xab.\x962\xa5\xb3\x9f4LS\xde\x07\xfe\xcb\x92mU. b\xec\x92\xff2g\xbb$\x9f\xa9\xdc\xd1T\xfe\xb6dM\x16\xa4:\xf3h\xb2 ]\x87\xdde\xbe\x8a\xe6\x87a\x16\x116\xa5\x94\xbdE\xf8\xd6\x91\x9d\x1f0\x98\xd7\xde_\xf6U\xec\x17\xcci\xdf/\x98U\xeeX\xcc\xdb\xb1e\xf1\xda/Q\xa9>Z\xa5\xd4d_3\xcdX\xd1\xcfy\xbaZ\xd4P\xb7\xc6\xd7\xae\xf5\xfc%L(\x87\x96[\xfe\xcb\x92mNp*o\xd9\x7f\xcd\x04\xb4Y`\xcex(\x1e\x85\xa6\n\xa2w|\xe4\xc0\xa6\x90\x18\xb9\x8d8\x04^P\xa6ID\xdc\xa7^\x93\x1dX\xa3j\xdb?\xbe\xa2VE\x93\x94>'2\xd2Z\x1d\xa4\xb0}\x990 p\xad\xa9\xa2~\xf99:\x8f\xf9)\xcc\xe2\x94\\\xe6\xcbwdMRw\x1d\xcc\x1b \x9e\x0f\xeb\xa0]=\xec\xf5{ll\x8e\xa2$t\x9ca@\xcc\xbe\xae\x19\xdb{\xf2\xc4\x98\x1e\xd4\xd5\xb6\\\x01j\xb3X\xb6\x9b7\xb5.5\x88\xdc\x0dc?\xbe|\x01\xe3\x87\xa0\xaa\xdf\xed\x0e1\x97b\x81\xcb|\x80S\xd1\x86\xa4\x98\xfa\xd0\xed;O>b\x00=j}\x95\x16\xde\\D\"\x99\xcc\xaf`\x0f\x96\x9b\x9b>D\x13\xf6&\x82\xfcV\xaf\xed\xe5\xe6\x11 `\x0f\x92V\xc0\xc6#\xc20%\xc9\xa2\x84\x94\x13r\xd50f\xcb\x87\x08\xb3P\xcb\x9d\xed\x1c\xabu[\xa1\xc7\x99\\\x89X2+\x1e\xa7\xd8\x91{\x9d\xcb\x86Wht/v\xbd\x07\xfbfp\xa2E\xb8\xfcqu\xc3\xd6\x11?(\xb5\xf8\x12e\x08\xb3\x9d\xd4\xe5G\xfd7\xd5\xa8\xd4 \xaa}@%Gg'H~\\\x88\xf3\x96W\xe4TGqc\x02\xe4\xa1\x0c\x1b;\x9d}\x16\x01o\x95\xf6\xaa\xea\xeb:\xee\xd9cC\x0d\xc6\xc2\xbf\x1c\x9f\x1e\x9d\xfdr\xfd\xd3\xc1\xe9\xd1\xbb\xb1\x1c\x0bR\xd4r(x\x86p\xbe\xbb\x1e\x9d\x9b\xba\x92\xde\x16\xa3s\xef1\xbc\xb7\xa2dUEf\xc1}\x96\xf2\xd8\x17_\n\x01 \xf3\x04\x90`uI\xe6\x08\x15\xd7\xc1\x93\xd5\xecO\x92\xf5\xf5\xa8U\x81\xec\x10\x96G\x1a\x97u\xca\x87\"\x10\x1f\x85N\n\xbeck\x98\xc0\xba\x1d\x9b\xf7\xd6\xb0\xb6W>\xc4\x93\xd5\x15\xef.n\xc7\xbdVHy\xe8;.\xf4Z\xfb\x03\xd5\x80b\x867\xa8\x9f-\x85bK7\x1aK\xfd8\xfdhB\xcf\x90\x8e\x88\xc86<4\xe9\xfbpF\xfe\xf2k\xcfA\x86\xb7\x17\xfa\xad\x1e+\xdd\xe9Kz-\x9c\x86\x9a\n\xba\x0e\xa2\x19\xfcm\xd2\xe3\x92\xf7$\xaa\xd3\x06UQ\xa0k|$+W\x85\xc0`?\x87\xe9\x8a\x9c\xe4YB\xf3\x02 \xba\xdeq*\xae.\x90T\xc0K\xdcu`\x984\x97\xed\x80\x0d\xcc\xb41\xed:|\xd8$\xac\x82\x82L\x0bR\xce\x95~\x95\x96\xfb@\xd3R/\xf8\x18\x94\xd2\xe8\xebzZ\x87\xecR\x1fm?To_-\x06\x08\x83<\x904\xc5\xd4Ur\xa5\xd1P\xb4\xe6\x94k\xb4^\x17\xab\x94\x94\xd7\xd7\x0d\xdd\xf0\xeb(\x8c\xe6\x04\x13-\xd7\x8b\x85Bp\\_O\x93,\xc6\xdcv\xaa\xa5\xad\xf7W5-\xc8\x04~\x8d\xb7\xb5\xfb\x06\xa8\xd5\xb1`\xb3\xe0ds3\xbbB\x85\x01\xae*s\x0fO\x83\xbe6\x82(_,\x93\x944\x07a\xbaB'\xa2\xfb\x06\x96\x83M\xa1\xe3hT\x0cQ\xc6)\xecI\xddn\xda\x8e\x04\x84\x13\x98\xfc~\xe3\xf5\x18\x07\xa8\x95\xa2\xae\xfe?\xd0\x07q\xaby[ OY\x92\xc7\xda\xe2\xae\xf3:\x86oD\xa9\xec\xc9\xd4)p\xd1!X\x86\x13!\x07G\xf9\xe0\xbe|\xd1Z\xe5#\xcd\x82if\x88M\xdd\x1a\xad\x0d\x1cB:\xd0\xf2\xa5\xa8a\x99o\x01\xa3\x11\x1a^\x12\xb1\xbe\xea>\xa3\x19Doq\xb5\x81B\xb5\x8c\x16V\xd1\xef\xc3\xa2$\x05\xb0\xe9C\xc3\xb2i\xbeB~\x1f6A7K\xd7\xf6Eq\x15L\xa5\xf1g\xebK\x98b$c\xfc\xff\xe5\xcb\x90]\xdf\x9c\x9d\x1b2\xcd\x0bb4\xf7k\xb9\xb1ZK\xcfx\xbd\x93\x94Hm\x9c\x8eI\xca\x1fs\x92\x82r\x89l|\xee\xc3\x8e\xc9\xf5!C+F\x13R\"\xd9K\x93C\xc4if4/\x0dS:\x82\xa4\x9e\xf2\xd6\xb6\xbb\xd7\n\x84SJ\x8a\xff=\x0b\xc0o~\xff\xa7-\x02\xc34\xf7@\x13F\x04\xa0M\x08\"/\xdb$\x18T[z'\xc10q8 \xc5cM\x02\xefA\x9f\xf2\x17\xcb\xd0\x0cJ\x8b\xae` \x8c\x00e\x06\xdc\xe3cs.\x86\x1dy\xf5Y\xd9\xd2\xa0\xe7\x87\xd9\xb0j4\xba\xa4\xda%fU!\xca\xce\x1e\xc3N8g]\x87E\x98\x853R\x8c \xc9\xd6a\x9a\xc4bg0\"\xc5\xb4'\xa0\x8d\xbd\xe9\x95:*=\x84\x13\xe6\xbe\xef:\xc5I\xd9Z(}\"\xdc\xeee\xf2\xfe\x17\xcc\xe5\xeec\xcc\xe5\x8cP\xde\xbb\x01jo\xc2\xcb\xc1\x9e\xdeB\x0d\xef\x15\xe1\xe9\xb6\xfa1!W\xda\x1e\xfd\xea\xdf\xdf\xf3{\xbf\xbb\x93\xce\xbd\xbb\xe6nC\nn1hq\xd6\x8e\x16\xc0\xc12/O\xc2\xcf\xed\xaf+\xf9\xb5\xfd\xa9\xc4OIy\x9c\xbd\x0boH\xda>x\x94\x8f^M\xc7\x9b\xf2\xa5,\xcf\x87l\x11\xd2hN\xe2\x8b(_\x92\xb2\x8e\x0dj\xfc\xbc\xb5\xe5\xb7*C>\x05{\x8bf\xf5x4)\x9d\x10\xa2\x14F\\\xed\xbe\xe1\xa3\x82\x1f 4z\x9ag\xfdz\xcd\x0fN7\x07\xa1\xca\xaf\xea\xecaq\xcf\xf3 \xdb\xdclCr\x15\x82\xfb\xf53\xe1\xdb\x11\xbd\x04\xb2\x9f[[V\xd2\x99\x0b{\xcc\xbc+\xea\x80\xb5\xbe\xb4u\xabP)\xb7$EP~J\x96\x97\xf9'\x92\xd9\xc3\xef\x80\xa2\x11\x0f\xfb\xdc\xc5\x19_l\xcb\xa4\xc3\x1e\xf7\x0cb\xfd\x9a\xc1\x16\x9ft\xbe\x06+}\xfeK\xff\xe1a\x15^\xdb\xa2`r)\xba\xeb\xfc\xdd\xf1\x8cq\xa5\\%\xb6r\xa7V\xaa\xd4w\xbd\xa8=B\x15\x02\x8f\"\xc1C]\xc7a\xc3\x17\x0d\xf6j\xa3\xa9\xf5\x0f\xd3\xb8m\xc8IL\xa1H\x9d\xc30\xfb=\x85(LSX\x10:\xcfc\xc830b\xd4\x96\xcb\x8d{\xcew+&\xa20S\xd8\xf5\x02)x\xd2no\xd0a\x87\x08\xe0\xe2\xe6M%\xf5^\x1f\xa4\x96\xc5H`\x1f\xb4\xaa\\\xf4:\xaf\xd8\xb1\xdd\x7f`}\x9d1 S\x14\xd5\x15jD8\xcdW\xb8\xc0\xb6y\x1b\xc1!\x8dd\xf2\x97\xedr\xedt\x19\xae\x9c\x87]+\x10\xe1\xc8\x18\xd3^\xdd\x9e\xa1\xe6\x8eJ\xd1?\xc7\xd9\xf4\xfeun\xfcs\xbak\x83\xe4<[\x93\x82\x82p\xfbKsX\x16\xc9\"\xa1\xc9\x9ap\xefON\xdf.\xd3\xd6\xb9\xe9\x0c\xec\xfb\x9d\xfb\xfa\xe5\xd0\xadpd\xd4w\xdd'\xb8\xf0\xf4\xf5B\xd7\x1f\x0dE\xfa\xae\xe7:\xc7\xe3\xeb\xf7\xe7g\x97gz\xd0\xd1U+jA\xe3s\xd9%\xc8\x02)\xcc\x12\x8e\x99\xdc\xdd\xef_x\xae\x93L\x8bpA\xf4\x86\xe4S\xe0\x05\xa0\xcdS+\x8f\xc2\x12\xa0I\x10#7\x97ix\x07{\xe0dyF\x1c\x1f\xa3R\xecx\x0d;\x17\xee\xa4\xb0,\"\x96\xed\xaf\xe1:\xe4VE#\xc7\xe7\xa4(\x0dP\xe3/\xa3\xbf$Y\x9c\xdfV\x08\xc3\x0b\xf2%\xc9\\\x1e*\xa0H(q\x9d\x1fx\xd1?T\xc2\xec\xb7{\x1c\xbf\xfe\xf0q[|r0?\x1a\xbc\xba\xc2\x95\x14 \xde\xbe\x81bk\xeb\x8d\x07\"<\x8b\x12oe\x92L\x8a+\xc3\x8d\xa4\x00\xcc\xd2\xd5\x0e\xc4\xaecE\xa0\x1eP\xa3\xb6Zi-#\x02\x16\xa2v\xe9.Kq\x8e\xcf\x8f\x17N\x91\xa0\x03t\x1f\x9a\x9f\x85\x93\xd3I\x88n,\xd1\xfe\x04=\x9fka\xd4\xa5\xe3h7\xfb\xff^D\xfa\x17O=\xd7\xf9D\xeeJs`\xdf\xdd\xdd\xfe83\x96\x8e\x17\x82\x86w\xf1\x07w(\xf9\xe0~>5\xd9$\x17\x13\x871\x11\x05\xd9\xfaky]\xce\xc3\x82\xc4\xd7\xd7\x8el\xd4\xfc\x0d\xef\xfb\x1f8\xa2\\\x8e(\xe7#\xfa\xc7\xd7\xbe\xf1\xd8\x10\xab\xa38\xd2\xf7\x9b\xd7\x90~R\xbe\x97 |6\xf5M\x04\x99O\xf3wy\x14\xa6\x84\x9f#\xbe\xe4\x9e'\xb0u\x82~\x07\xd1\xa1\xacsVG]B\xbb\xb2\x02\xcd\"-T\x18;\\\xc34%8be\xe9F\xc2\x12\x19\x1e\x008\xde5#8773\xd8\x84\xc2\xab\x18\x13F\xc4\xf7\x9dl\xd6\xbd\xf0\xd2\xe2\xea\xf7\xd9\xffx\xb6\xf7y\x0f\xa9\xf4\xe2\xe5C{\xfb\xa8\xa4\xd2\xee\xeeK/\x98\x9a\x899\x93\x07\x17\x13\x9e\xea\x1b\x87\xf9\xbe\x07\x95a6r$V3!='5A\xeeC\"\x03\x84\xa2\x03\xb6\xf6foz\xa25\xdd\xecH\x87\xc6\xcd\x8d~\xcf\xb9\xea\xf5\x80\xf3t\xd74\x03\x18{\xbdw-\x19#b\xcf\x04\n\xcem3X(\x03_\xf2\x18B\x82\xa7!\x0d\xdf\x11\xc6XI\xa0\x13L\x8c\xa5\xf9\xf2Eu\xd4\x9e\x19$a?\x86\xb1\x8cW\x04\n9ju\xcf\xc7=)g\x95\xec]}\xaa\xcb3\x11\xd5J\xa0\xd1*\x11e\x13\xe8\x8eVc\x1d\xbf\x81uy\xfa\xbdY\xd4\xf0\xbdM\xce\xd9\x07\xbe F\xefd\xc8\xbf5W|k\xfc\x9b\x03\x9b\x90\xa1\xbf\xdb8'e\xf6{\na\x14\x91%\x85\x82\xcc\xc8\xe7\x96\xd3[\x01\x11\x02\xa9~\xdb\xa6f[\x14\xa5\xc5\xfd\x9b\xd3x\xc6\xc3\x1el\x07\xdb\x9aH\xc9x\xe2:\xdb\xc1\xb6\x03\x13r\xe5jnu\xaa\xa3\xd6(\x80\xef=\xbe\xe9\xa4\xb8\xe2\xf6\xb8\xb0am\x03z\x8et\xd3\xfcn\xdc3\xe0\x11\xc5\x8d\x8c\xb4\xfd\x90\xec=L(\xb27F\xac\xda2Q\x16\xa2\xad\xd6 \xc9M\xa0\x9f\xefx\xc1\xf4\xa1k\x9b\x07\xfc\xcc\xe7\xec\xa9|\xe1\x81\xa1\xfe\xf1\x15\x83.\xd4\x19\xfe\xa1Gtq\xae\x91\xc4!xAs@\xdd\x1d\xd4\x97'\x90d\x1c\x93\xac0f\x95 c\x0b|\x1c\x06\xd3\xd65I\x1f\xac\xb7\x97DH\x8cf\x84*\xfc0\xef\xb6\xd9\x8d\x07\x0fXz\x7fT\xdf\xa1\xcd\xb5\xfd\xddFs\x90\xdf\xc1\x1fc\xc2\x05iI\x9e\xc19\x89VE\x99\xac\x89\x94\xb8\x92\xcf\x94dq\x92\xcdZ\xc5\xc2\x15\x9d\xe7\x05\xfc\x9c\x84\xd1\x9c\x94i\xb8\x86w9-\x17a\x96\xaf\xe1\x87T\xfe|\xf5\xfa\x8f\xb3E\x98\xa4A\x94/\xfe\xd0\xaa#M\"\x92\x95\x04N\x8e/\xb5oz\xd6\xcb9\xe6\x82w\xa2\x84{r|\xe9\xf5\x949\xcc\x97wE2\x9bSp#\x0f\x9e\xee\xec>\xdbz\xba\xb3\xfb\xca\xd8\xe5\x9e\xaa\xde\x93b\x91\x94\x18\x14,)aN\nrs\x07\xb3\"\xcc(\x89}\x98\x16\x84@>\x05\x06_3\xb6L9\x84\xd9\x1d,IQ\xe6\x19\xe474L\xb2$\x9bA\x08Q\xbe\xbc\x83|\xaaW\xcf\xce\x11(\xf3)\xbd\x0d\x0b\x02a\x16CX\x96y\x94\x84\x94\xc4\x95\x1e/Zf\xc04II .\x9d\x13p.D \xc7\xc36c\x12\xa6\x90d\xed\xca \xc8\x9cp\x9b\xd0y\xbeb(\x9d\x83M\x92g\xbe\xf0s\xcdz(?\xa7\xc9\"\x11\x0d\xb2\xe28\x8b%\xd0\\\xaf{U\x12\x1f\x07\xe5\xc3\"\x8f\x93)\xfbOp\x0e\x96\xab\x9b4)\xe7>\xc4 k\xe9fE\x89\x0f%K\xc4\x05\xf4\xd9(\xb7\xf3\x02J\x92\xa6\xac\x86\x84\x94\xc6\x89\xa9\xfb\x8eE\xf0\n\x80-\x06\x15\xd3\xcbz\x05\xb7\xf3|\xd1\x1cgR\xc2tUdI9'X&\xce\xa1\xcc}\xbd\xfarU\xdd+\xb0\xd2\xd3>\x1a\x1f\x81sp\x01\xc7\x17\x8e\x0f\xbf\x1c_\xfet\xf6\xe1\x12~98??8\xbd\xfc\x15\xce\xde\xc2\xc1\xe9\xaf\xf0\xe7\xe3\xd3#\x1f\xc6\x7fy\x7f>\xbe\xb8\x80\xb3s\xbd\xe6\xe3\x93\xf7\xef\x8e\xc7G>\x1c\x9f\x1e\xbe\xfbpt|\xfa'\xf8\xf1\xc3%\x9c\x9e]\xc2\xbb\xe3\x93\xe3\xcb\xf1\x11\\\x9ea\xfb\xa2\xe6\xe3\xf1\x05\xab\xfbd|~\xf8\xd3\xc1\xe9\xe5\xc1\x8f\xc7\xef\x8e/\x7f\xf5\xe1\xed\xf1\xe5\xe9\xf8\xe2B\xaf\xff\xed\xd99\x1c\xc0\xfb\x83\xf3\xcb\xe3\xc3\x0f\xef\x0e\xce\xe1\xfd\x87\xf3\xf7g\x17c88=\x82\xd3\xb3\xd3\xe3\xd3\xb7\xe7\xc7\xa7\x7f\x1a\x9f\x8cO/\x038>\x85\xd33\x18\xff<>\xbd\x84\x8b\x9f\x0e\xde\xbd\xc3\x96\x0f>\\\xfetvn\xea\xfd\xe1\xd9\xfb_\xcf\x8f\xff\xf4\xd3%\xfct\xf6\xeeh|~\x01?\x8e\xe1\xdd\xf1\xc1\x8f\xef\xc6\xbc\xe5\xd3_\xe1\xf0\xdd\xc1\xf1\x89\x0fG\x07'\x07\x7fb}?\x87\xb3\xcb\x9f\xc6\xe7\x98M\xf4\xfd\x97\x9f\xc6,\xa957\xa7pp\n\x07\x87\x97\xc7g\xa7l\xcc\x87g\xa7\x97\xe7\x07\x87\x97>\\\x9e\x9d_V5\xfdr|1\xf6\xe1\xe0\xfc\xf8\x82\xcd\xde\xdb\xf3\xb3\x13\x1f\xd8R\x9c\xbdeY\x8eO\xdb\x9d>=\x1d\xf3J\xd9\xaa5\x17\xf7\xec\x1c\xdf?\\\x8c\xeb\x9e\x1e\x8d\x0f\xde\x1d\x9f\xfe\xe9\x82uH\xcd\xacC\xcdv\xe3]\x9e%`!\xf7\xa5\xf4\x02\x92\x8c\xc1g\xc4\xe3\xfc\x8a\xf3\xb5J9\x12\x97$\x8d\xc4s2\x1b\x7fn:\xf1S\xe2oAS\xc7\xdd\xd88\xea\x874Z\xb6q\x10R&AE\x04\xaa}\xf9\xab\x0e\xca\x00#dI\xa8\x12\xa6\xc1XU\xa5x\xc26<\x1a\xd0\x19\xbc\x92\xf7w\x95M\x89\xa7\xb2U,\xc1E%\xa4\xcbdA\x1a\xd2.k%|\n\x1b\xd5\xf0$\xa3ZVK\x17\xebCF>/I\xc4N\x992\xa1+\xe1\x83e\xd0\x8a\xe4VI\x97\x14\xd3\\_#o|}\xedT\xf7PUh\x99\x96\xb0\xab9ak\xe1\x94\xcbH%\xda\x00\xc1\x10\xe0h\x17\xad\xccd\xd4\xfa:\xd0G\x1d g\xe7\xaa\xd3\x96\xc6R\xefS\xaf%\xab\x9c\xec\x18\xae\x14\xe5M,7\x9e\xec\xce+*\xe4jz\xb5N\x1aZ$\xf3\xeb\xf3\xaa\xbc\x0f\xbb\x06\x9d=k\x14M\xc3\x04\xa0\xf9]%\xe0\xc4\xb7\xa6~\xe0\nidA\xb2~\"w\xa5\xbb24iu\xa1\x0f\nc\x84\x12\x9f\x90\xfb\xa2G\xe1I\xee\xa2gz\x1e\x19$T\xc1\xc2\xd0S\xd2\xe8\xa9\x8c\x9c\xeb\x86\x93\xb2\xba\xf54h6\xaay*\x90%f\xeb\x06\xf5Y\x0b\xa5\xea\xc9\xd0x\x8cm\x03\ntN\xd5\xdd\n\xa8\x8b\xa2\x85G\xaf\xee\x83\xd9~i\x8e\x0c\xa35\xe5\xe2\xba\x97\x8bw\xb3F\xa2\x90\xf9\x8a\xb7\x04-\xd6\xd5\x94\xb6\xf7-\xf5\xf9\xea\xf9\x90[s|E\xdd\x96\x11?\x06\x9a\x13\\\x88O\x86\xd5\xa3\x8d\xd5\xa3m8\xa3ze\xbc\xd7\xbc\xc2f:\x0f,l\xec\xa0!d%\x1bMhA1\xcd\x80\x94\xcf=\x11Oq\x10\xbf|\x1f\xa5K\x9b\x00\xbb\xbd\xf4D\x89\x92\xc4\xd6\xd6b\x94\x88\xcc\xba\x01u\xb4\xd4{qZ'W(\x11n\xe7\xcf\xb8>\xba\x1et\x9a=\xea\x8e\xa7\x86\x1do\x0d7,Q6\x9d\xe4\x96\xbdc\x0c\xb9\x94\x08\xffqO\x9e\x98\xa6\x85\xf1\xf7[\xbb\\\xc6W[\x08M\xf2+6\xbcb\x92_a<\xf7\xc3\xa4\x88ViX\\90\x92\xa9\x04\xb3\xf9\x90 \x97\x0e;\x08P\xe2\xa3!\x00\xaa)\n\xac!\xf6#\xe56ih\x9f(\xcc\xd3D\xda\xd0\xf2\x0bR\x96\xe1LV!\xdf\xf6\xea/C+*i\x18}\x12\xd5\xf0\xdf{2\xd5P\x85\x14\xc57w\x04\x03\xf0 \x06\x922\xde\x06\xe1m\xca\xe4\xad\xf8\xc2-?\x84\x1f_\xe0~\xd5\xf2\xecn\x91\xafJ\xc7\x83Mpp\xfe\x1f\xacP\xf8\xfd+\xf35\xe3\x0bc\xc8#\x96n\xf2|\xcc\xd2\xf5k\x80\x95H\x7f\xed\x99\xcc'K\xbb\xd8\xc9\xa4\x10\x8d\xda8J\x84\xbb\x1d\xae\xf0j\xd0\x9d\xe2zS\xdc\x19? \x0b\xd7{\x03\x9b\x9b\x14~\x80\xcc\xa8S,g\xa2\x1do \xa4\xec\xbc$\xd4-0\xfeW1\xd9\xbd\xb2\xe9\xed\xd6\xbf\x14\xa5'\xde\x07\x86\xac\xfdF\xb2P\x8f\xc2`\x1ceS\x15\x9em\x94f\xe2{\xe9\xf9\xe0\x9c\x84K\x9b\x10x\x90V\xbc\"Un\x85\xd0\x13\x10e\xf1\xea\xf8\xc2\"\xd2|\xd1\x12\x81\n\x88\xda\xd5E\xf4\xa5H\x7fi\x84\xb4\xd4\x0ei\xc2< \x0ei\xc8\xad\x140\x1a\x99\xd1\xca\xaaL\xfe\xce\xf1\x05\xfbaX\xf4\xd4\xb0\xe8\xb9\xdfH\xae\x16=i\xa6\xf3E\x0f\x9b\x89|\xd1W\xcdD\xbe\xe8es\xd1S\xe3\xf2\xa8C\x1e\xacN\xdb\xf0\x9b\xb2\xb5\xcb\x1d\xa7\xd0\xca\x9c\x98\xeb\xdcK\x1f$\x9b\x9b\x19\xfc\x00\xc5\x1b\x0f\xc8$\x87M\xc0\xf81\xed\xb05\x92o\xd3\xe6l08\xbdx\xaa#\x1c\xa1\xf2\xfcZ\x07\x1bcL6\xa3\xaaS\x0b\xda\xba\x84\xc4m\x18\x0c\xd5\xe0\x8a]\xec\xb9\x8a\xb1\x90,@B\\Q\x1e(\xdc\x90\x1b\xb6[E\xc7Z\x8dj\x10\xb8V\xbe\xaf\xba\x03\x1dF\x83\x9a\xf7\xf4\xea\xbe\x8b`>%\x9e\xebkcZ\x83\xf6t'\x9a\x97\x8c\xf6\x14'\x03\x16\x0eq\xd37\xaa\xb6\x08u\xc7A\xab\x99\xb3\xaf<\xe8L\x15E\x15\xd56\xb8\x87\x92\x8dU;\xbd\xd9\x9ey)\x06!\xed\x0e\x1b\xb1z\x95\x9e\xe9\xab\x015\xf2m!e\x90\xbaB\x16\x8e\x08\xffl\xd0 \xcbcry\xb7D\xd2\xc9d\xfe\x88\xf7Af:\x92;\xa4\xc7zH\xa3\x1e\x83\xe9%\xdfW8\xbb\xd5\xd4\xec\xf1\xab&\x19t^\xb0&&\xbf\xe0l\x1e\xdd\x15\xec\xc3*HJ-7\xb2\xd4\x9a\xde{{\xfeAgPv\x9f=\xf7\xaa\xcb\xd5!z7\xafwv^\xee\xbe~\xfd\xf4\xfb\xe7/\x9f\xef\xbc~\xbd\xfbP6\xc5\xe4\xbf\x1d\xe7\xf1\x0f\x8c(\xc7_\xff\x81\xbe\xf1\xb93\x02\x02?\xec)\xa2\xb0\xfek\xb1{\xf5\xa6\x1b1I\xdc\xde\xba\xd4\xed\xe9\xceC\x80\xfb\xe9K\x9d\xc0\x04\x01\xdd\xdf\x08\xc1l\x13\xe4\x8f\x00\xc1\xd5NH\x1a\x10\x8cU\xa3\xb9cDJ\x83\xc5\x9env\xd0\xca\x00\x9d\xf7\xe0 \xe5]u\xeb\x05\xf9\xdb*)H\xe3\xc5uV4I\x1d/`\x03\xb3xb\x01U\xae\xfc\xe5\x8b\xdc\x8e7 \xdeD6^du\xc6zz\x02[}u=\xfbf\\=`3v(W\x99\xaf\xd6[FT\x0c\x04\xb6?\x06_>N\xdc\xfd\xd1\xe4\xffL>^]}\xf7\xc5\x9d8\xbf\xbf\xf2\xdc\xfd\x91\xbb\xbf\xf1q\xd7\x9b\xfc\x9f\x8f\x1f\xaf\xbe|\xfc\x18x\xdf\xed\x7f\xdc\xf5>\xea\x81Yx\x00\x98\x8f\xb7\xdf\xfd{oH\x07\x8b!S\xc3\x8eI\x17\x8bV\x92t\x01\x98F\"k\xc3\xad\xb0\xc7\xc6\x1ed\x08\xd4%R1JB\x158B\xa64\xdc\x0em\xa0F .?\x8f\x05\xc2\xa3\xc8n$\xea\x9b,A\xf9\xf6H\xa4\xd3<\xf7^\x86\x0e\xf7BD\xf7\xa4\x1f\xcd\xf2\"A\x99pm\xd3\xcaE\x17\xf5\xc1\xb9\xbe&\xe5I\x1e\xafR\xe2\xe8\x1a B\x1bAU\x08AC\x9b\x05Y\xe4\xc9\xdfI|\x11.\x96)y[\xe4\x8b\x8bhN\x16\xa1\x90*\xf0\x8f\x87\xa8,\xf8\x97\x93w\xe3\xcf\x98\x8d\xb3\x10\xf8\xf3/\x8bT+\x94dSR(\xefe\xbbfq\x00\x824\x81i\xd4\xac(z(\xec\x98\x89\x1b\x0b\xdd\xcc}\xf1\xfd\x0b\xcf\xb0\x0f\xf0\xd3\x8b\xd7\x9e\x91\x97\n\xed\xeb\x83\xa0\x10\xd4\xf3(T\xf5\xdaXKFF\xd0\xddZ\xfd\xae\xfdk-|\x19\xb6+\xe1\xa2\x99\xe1qm\xa5,\xa7\x95\xc7\x10F\x8bg\xbd&\x8b0I\xef\xd1\xc2\xaa$\xc5\x1f _\x8c \xca\x17\x83\xda\x12\xfdb,(\xd9\xa2\xc9\x828\xc3[t\xe5\xf5\x95\x17\xd0\xfc\xf8\xe2L\xa8\x84\x19\xf8\x02\x83<\x05\xd1\xc4\xf0\xb6\x06\xc5u\xe3\x95^O\xd3<\xa4\x8f\\u\x92Q2{\xf4\x0e\x0bT\xd8G\xff\x83\xb2\xca*\xf6\x94\xb88\x10 \x8dW\xad\xf2\xa5\xdd~\x13\xdc\xdb\xbcLw'\xa4\xcc\x82mt\x17\x9d\x0frr%\x99\xdeyF\xff3 \xc4f4h3a\xf2AO6\xc14/\x16\xa1\x812\x02\x81\x12V\x13\xd4O\xbcv`\x13\xb8\xa9\xcc\xca\x18\xd5S\xc2%\xf6.)\xdf\xae\xb2\xc8s\x13\xc6c%\\O\xda\xf9\x90}\xca\xf2\xdb\x0c\xb5 \x85K\x1b\xec]\xd7\xd4\xa46\\Xa%\xcb\x0d\x93<2[7\x89\x7f\x00\xa4\xa3\x15U\xd6\xfa\x8ep\xf7\n\xf6\x9b\xaf\xa3\x96)\xa8|r\xd3RP\xcbR \x99\xd9\xb1\x14\xca\x97\"P\xe1\x8035V\xb3Vg\xaa9\xef\x1c[\x16\x00m\xce\xb26\x844\x93\xcf\xa2\xe3\xdb\x0c\xc9\xb0\xcf\x0bC\xc0f\xf60\x1c6\xc3;j\xf3\xf7\x1b\xfc\xbe,\xc841x\xb4b\xcfuU\x03F\xab5g\xba\xe5S\x9b\xad\x16\xe6\xef\xe3\x8aG\xb6\x1c\xe0a\xc7\x01\xceN\x90\xd4C\xa8\xfa\x97\x9c\xe2a\xdf)\xee\xb2Y\xbd\xc3K\xff,\xa7\xe1\x8cM\x8e\xc3\xcd\xa5\xdc\x1b\xd8\x87\x1bF\x96\x8f\xd0>\x16u\x01\xee|\xb8\xe6\xde\xd2\x17\x13\xf6\xdd\xf9\xbcH\xb3r\xc4\xce\x8e\x1b\x96 _\xd1_\xc1\xb5\x85\xc0Q\x0f\x05\xc48\x91\x0d\xf9\xb2\xdc\x11\x83\x07\xd8\x03\xfe\xff\xcb\x17\x98qK\x10\x9f\xa7HU\x0d\xe5\x85\xe5\xe1P\x023\x11\xa9>\xae\x88\xbf\xf5$\x93nn\x9b'\x04\x9e\x0d\xd3\x81ns\xe5\x13\xc9\x1d\xc8\xfd\xb6\xb2\xca\x85\xdf^v\"\xe4V\x9d\xa6\xd6\xf94g\xad\xcf\xef\xdd\xba|\xb6\xac\x8b\xfb\x8d\x0bs\xaf\xf6E\xaeV\xa6\x01\xe4\xb6U;\x91M\xfd\x85\x99\xdc\xee!\xa7\x0f\x199\xad\xec\x19\xb4$\x95\x1b\xf0\xc2N\x9d\xb2\xbe]\xe8q\n\x0e9\xde\xd8\xb8\x98\x1c*\x84\xf7\x97/\xb0T?\xd4$7#\xc6-\xd3\xd5h\x87\x95\xe2H\xa2\xfa){(\xde\x03\x06\xb3h\xa9\xd2\xb5l\xf2a\x03\xff\xd4R\xbc\xc3\xba\x90Jc\x9d\xad\xde&;Wv\x96E}\x0ed\xff:\x0fm\xfd9\x93\xa5\x04D\xd91\xbd|\x16\x93j\xd4\x12\x1d\x1e^UG\x16\x92M\x07l\x04\x07\xd04\xb5\x9dN\x0e\x91\xef\xc1\xff\xcdOg,\xfd\x8c%~b\x7fJ\x9c\x8b\xee\x85\xf9\xdaw\x80\xc9\xa7\xd9\xd9=hw\xbe\xe1\xf3H\x9dA\x8d\x18\x94\x03p\x1byx\xba\x05\xce\xd5\x87\xad\xfa{d\x99.\x86\x15h\x82\xc7{Tw\xe5;\x05\xd1\xa8pa\xf0^\xa2[\x8e\x04\xde\xf7L[\x17j\x94\xcc\xa4h\xa8\x0fQ7\xa9\xcd\x118\x07\xd9\x1d\x9d\xa3\x0dT\x98\xc1\x0dAc7\x0bU\x80\xe1Q\x86\x9e\x08zC\xa5\x8doeH\xee\x11\xcf\x99\x018R\xcc\xdc\xb8 \xffSv\xd4W,\x15&\xcd\xd9\xf9\xdbB\xff\xb7lQo9WV\xa2]\xb8Xa\xc6\xe1M\xcc}\xb7\xf6\xfb\xab\x0fcV\xd1X\xef\xfaW\xe3=\xc8\xd4x\x89'\x05\x8e\x11\xff\xda\x84R\x86\x0d\xb3\x86\x9c+\x97x\xc3s3\x93\x19lL\xa24\x94\x81{M~\x0b\x92,\xc6\xc0*\xceG\xaa\x85c\xd3\xaf\xe1\x00\xcda;.\xa5X\x7f\x92\xba?\xd3\xbe\x1b.-\x7f\xda\xaf&Q\xcd][t\xcf\xd5\xf0\xc8\x9aq\x87\x95V\x9ex\x15\x87\x05O[\x84\x9f\xabxrU\xc6Fb\x85\x1b\x95 hw\xc1`\xd7$\x85\"2OCl\xd8YY~?\x8ds\xd5\xd8\xa0\xbb\xe2\xc4Z\xb1\xeaz\xc5\xb0\xd2\x0dGY>d\x01\x06W\x19/\x12\xca\xdd\xdcc\x9a\x12\xac\xa3\x9ayy\xbb\xd8\xf8\xaaMz\x9dG\xac\xfeI\xf3\xfb\xaeV\xbe$z\x0e\xbb\xd4\x03\xa9&\xe5\x06\x9b*\xc6(D\x06\xa8\x10\xbe\xebL\x1e\x152X\xacJ\xca\xd0g\x08<\x1e\xf2\x9a\x88[)\x8b\x1b\x05#\\\x11\x0eo\xf5\xcc6GD\x16 \xed\xb7\x9f\xe7\xfe\x8f|X\xf9P\xfa`\xf0\xc4\xac\x83\xb9\xabm\x03\x0c!'\"\xe5\n+\x1c$\xc4\xd4l\x01~F\x05'\xb7\x9d\xce\xd5\xd2\xda\xe9\xd2\xd0\xceDo\xb1\x9e\xa1\x8b#U^\xe3\xa9\xc6oc^5\x9f|\x03\xcd\xc3F\x1f eZ\xbe.\xbf\xff\x90E\xe1j6\xa7>\xac\xb2rI\xa2d\x9a\x90\xb8\x1a\x1bv-\x00\xf7\xf7\xb0\x89\x0e\xa2\x1d\xcf\xe4.\x84\xb7\x17\x05\"j5\xa7\xde\xa3&\xdak\xcdq\x82^\xa2\xd4\x19\x98\x90+\xbb\x92\x05\xd7\xc2\xc8<\x0f\xca\xdb\x04UXt9\x97i\xca\xa2\xb0$\xb0k\x8e\xf4/\\\xb0\xa2[t3\xd5\x82>\xa4\xdb\x9f\xb0\xd2\xa7\xbd\x95\xfa\xcdu\xba\x7f\x13\xcf\xee\xd9\x84\xfa\xf6\xf4\x9e\x0d\xca\x9b\x7fc\x99UE\xd4\xf7[\xe1\xb1\xfd\x18.\x97\xe9\x9d\xe8\xe0J\xd7{\xad\x84\xf4\xb9k\n\\\x83,\xd4\xfd\x1a\xc4C/\xc5\xeb-n\xda\xe2y\x95^t\xc9C4r\xc7\xe5Pnnz\x90N\xca+\xad\x8bF\xfc\xa3j\x954\xb1L\x18\xc7J\xcc\xd0N\xe5!\xb6\xe3\xc26$oX\xfc\xce\xa4\xb2\xda\x1aYV\xa7^\x17\x96\xecAU\x0d<\x93\x91[5\x02)~cx\xd3u\x94/\x0e\xfa\xff(\\\x1a\xc8.y(\x90\xaf:8\x02\xaaU\x94\x04\x08/\xa5\x9f\xf6\xae\x074\x87$\x8b\n\xc2\x90\x0d\xfa\xb7\x08\x9c\xd6\x92J\xe4\xea\x9b\xe9/\xd9\x7fZ\x84\x11\x1e\x82\x8d\x04\x0cL\xd7u^\xe7h\xe6\x00\x1b`\x15\xb9&<\xfa\x8du5\xd9\xc3\x03\x88d\x12\x83\xee\x83[\xfd\xdec\x8c\x8dyU\xd0\x08[F\xd8J8M\xf0\xad\xeb\xd4\xbf\x13\xfb\xb7\xdaA\x9a\x0e\xe3\xad\xd6F\x07\x81\xad\xed\xd1\xb3\x156:\xc6\\\x15\xe5\x9ci\xeb\x8ax_g\xf4\xd1\x87\x98~\xe6>y\xd2\xb9/\xda]2\xb7f\x05t\x8a\x0e\xc8\x1a#\xd6\x97G8\x02\x90K\xd8\x9eh\xa3\x0d\xb7J+\x19\x8a\xe8\x8dh\xf0#cC\xaa\x0b\x0eF\x9e\xa6\xb0\xf04\x96\x93!\xb3\xa1\x03\x83\xc6\x04N\xd0\x9bjo\xbc\xb1W:\xa9\xf6\xcc\x16\xb4\xf8\x0e1\x13]\xcbh\x03\xeat\x10,\x9b\xc8\xd26\x8d\xc4\xdd\xf1\xea\xdbx\xbfE\xfc\x19(?I\xe3\xc3H\x8b\x16e\xea\xeba\xbe\xca\xba\x05\x02:\xbboS\xae\xa0\xed\x85m\xc3YRy\x94\x14\xd3`q\xa0R\x87+\x96\x16\x9c\xfd\xf8F\xe3F\xec#4\x1c\xe6\x95\xbaJ\xa3T\xbfI\x80n\x0cD5\x0f4\x99\xfbl\xe7{\xcf\x0b.hA\xc2\x85\xa0H\x82s\x12\xc6\"\x02\x1b\xbe\xffR$T\xbcg\xee\xee\xeb\xefQ\x80y\xb4Z\xa6\xe437\x80\xe3)\x97E\x98\x95\xd3\xbcX\xf0\x8aww0\xf5}X\x96\x97\xf3\"_\xcd\xe6<\xf3\x8b\xe7\x83LMz\x1d\x01\xf28_&T,\xdc9>\xdf\xf1l\xf4\x9fA\xd7\x1e481II\x12\xc6|\xa1|\x84\x07\xaa\xe0\xa7PF\x8b\xbbf\xd24\xc9\x92f\xc0E\xdb9\xbd\xd19\x07\xfa#-\x0f\x08o\xd4~\xb6\x93F\xaf\xec\xf9\x04R*\x8c\xe6\xfb\xea\xb3\x16^d\nd\xe0o\xc2\xc8 \x82P\x1f\x1a,\xb9\x93\xc5\xe8fk\x8b\xf1y\x18v\x1d+`3h-k\xbe\x07\x02\xac1\xca\x8bO$>'\x7f[\x91\x92\x96o\x0b\xf4\xe9mJ\x96\x8bDP/\xcdPlO\xd3\xdb\x92\xcfW\xee\x91\xa5\xf5\xedk\xc7\xeeV\xb7\xd3]\x9b\x0fYq\x11\xc6\x06\x0dn\x8a\xfc\xb6\xe4\xd4\xcb\xc4Y\xef\x04\xbb;\x8e\x0f\xec\xc7\xeb\xc0\xb9\xaa]\x81\x04kR\x94I^y\xf9\xf0\xe1{\x8fk\xd2\n{\xda\x04\x87w\x99\xe8KpW\xed\xd3\x0b\x1a\xa2-\xfc\xac\xdd\x9dT\xd8\xad\xbc\xd0\x8e\x954H\xb29)\x12\x81\x15^\xed\x1aX\xaa\xc8h-\x02(|\x12z\xa6#\xdc\xe0\xcf\x06\x99IL\x05\xfe\xd1=\x0e\x80\xd4uvw\x9f\xefJG6\xed,\\u\xebC\x92\xd1W(i\x025`\x8d\xd7R1e\x03\x98\xfb\xa8\xa1\xc5\x1a}iE\x0d\x0b,l\xf983bg\x10\"6\xee\x82\x8a\xa3C\x0420\x84Q\x05e\x1fSU\xf6k \xd5\x11\x99\xf0\x8b\x8e\x93\xd9\x15\xfc\xeaz\x7f\xea/\x10\x19z\xb7\x0f\xbb/`\x04\xbb/\x9e\xbdzn\x99\x85FW\xd0\xaa\xf4\xcb\x17A\x0c\xe7\xb0\x0f9\x8c\xc4\\\xa4\xf5\x87\x94Q$)\x8c \xf2\xcd\x95\xd4\xb1~\xdc\xf6w\xafF\xe6az\x18\xa62,\xa7/\x0f\x02\x12\x1f\x15a\x92\xa9\x89\x1c\xe7i)\xcdr\xfclh\xa6\xc5\xa4\xa4E~'\x12\xcd+\x82\xf1\xf99\x7fE\x82\x98Dy,\xa2\xc9\xd8N\xaaF\x1eVxZ\xb5\x86B\xb2q\x16\xe5\xa2\xb7\xa4\x95\xf6\xe5\x0b8+:}%\xe5I*\x13\x87 l\xc5\xb5\xa1rD\xab\xe4)\xef\xb2HJL\xd8\xfb\x0dn\xe5\xf7\xdcZW+\x9cg\xa8\xff\xd2\xab\xb8\x0b\xedC\xb3\xef\xc4\xe4A\xdc\xaeoU\xec\xd8\xad\x84RpY\xf4]\x16u\xe7\xe3\x81\xe0\xb0\xe3\xd1\x8d\xfd@d\x14c\xff\xa8\xe4C\xb4\xb9%\xb2\x81\x8a\xc6 \x15\x7f \xf7\x1eII\xe6+\xbf\xd9\"X\x1b\xf9\x8a\x871\xf5\x0c\xc4\x87\x99\xa6\xd2\x9f\xad-\xe5x\xf71r\x80[\x9fJn\xeeC\xe1\xf9\xca9\xe5^\x08\xa6\xdco\xad\x03\x97\x9br\xb9\xa8\x14\xa9\x12\xc1\xd8\xf3+,V\x19\xe3\x15\xdc\xdc-\x1e\\\x81\x0f\x17\x1cT\xecZ(\xe89\x8aO\x00es\xd0A\\\xf5+\xf8\xe0\xad\x01\xec\xc1\xd8\xd5YD\xfd \xf1\xcc\x90{\x07\x7f\xb7\xb6 C\xde2\xb9\xa2dX\xea-gB}\x8cfZ\xba\xd78\xcd\xfcj4gsv\xed*\xef\xf6\x91\x1b\xbfXi!\x05\x01\xa8@Y'\n\xf8kl\xfa\xba\xdb\x8d\xfciX\xd2\x1f\xbb2T`\xa6\xd4\x88\x8a\xcem$\xaa\x03\xc2\xae\xb9\x03\x92\xdf\xdai`-\x8d<\xcc\xc8-\x84\xfcf\xb11\x016\xba\xe0\xce\xbc\xad\xb9\xe6s\x930\xd8p\xe7\xfc\x12\xec\x8ew\x00\x8d\xbe\xd9\x8f\x06-\xe05\x1c\xa0\xdeY|\x9f2n\xf6V#\xfaX~N\xa6(\xe1\xa2ok\x0e\x0e7\x08\x9e\x94f}\x0c\xbe\x86\xca\xc5\x87\xc4\xcb\xe2\x8b\xed\"A|^\xeb%\xd7u\xd1\xb5\xbd\xac8\x01\x95\xc22e\xaf\xfej/\x8eg\xb4R\x98\xbf\xef\xc9/\x9e\xe7\xc3T\xb9-\x1e\xb4\xa67M\xa4\xc8E\xe9\xc6k\x03\x15\xec\x19\xfaP\xf6F(_\x05>\xc7\xcb\x03\xe5\\\xc4\xa8+r\xa6\x18\xe6\xa4\xf2$\xe4a\x87\xf9\x17\x97\xb7^\x7fSk\xd9\x1d4\x9ake4\xa6Ad\xd0\x17\xf0Q>\"\x06\xa3<\x83\x9e<\x01\xaa\x10C\xb8\x06-\xe2Hb\xe4\x98\xa59\x06,\xfc\xd5\x15\x07\x84\xc68\x16n\x8d\xbb\x07\x8d\xf3\xd6\xdawj\xa4?\x0c\xb6\x0c\xeb\xca\xb1\xb2\x86:\xcc\xb2\xa0j\xf9PD\xcfo#\xd8\xc9g\x9b\xbf\x8a\xf87b&;\xc1\x91\x8b\xcd\xcd5\xf4\x8a\x0e\x83AtZi@l\xe6\x93(\xa9e\x05\xe6\x0c\x95R\xf4\x8a\xa3\xcd\x92\xcf\x1b:\xfd\xcb\xf1\xc6\x82k=\xa1w \xbc'\xc3\x1c\xbb2\xd0'\xce\x86\x0f+\xd8\xdc3\xc9\xd3\xd8\x93\x07a\x9a\xf2\x83\xa0\xe4^\xd8\xe4\xee\xe3;\xa6\xf2\x92\xe6\x83\xe30\xd2\x82\x1f\x00Mx\xd9\xdc\xc4\xac\x1dG\n'I\x18\xb9b\x11\x0b$\xa2\xaf\x89*\xe7\xf1\xecb\x04qN`?l\xe7L\x1b\xd6\xbb(\x08)&\xee\x94\xc8T\x9c|\x10\xcdW\x99\x85\xd1\x92\x0f\xea\x0b\x05DP\xf6\xddy\xb99r\xbf\x88\x87\xc1}\xb5B\xbb\x88\x99\x1a\xdc\x1c\x8c \xad\x16-\xf5\x19\x036\xd5\xc0\xc1\x0b\xae\n\xb9\xa3\x81S\xdau\xf4\xca\x83\xbd\xa6\xb9\xf9\x1e\xb2\xd4ZW\xa9\x87\x0bhn\xa4Z\xb4\xc8H^\x86\x06fM\x07\x9d\xc2\xa7\\\x8f\xb4\xbc:\x85*\xf1\x96\xb6\x07xx\xf0\xc9\xd5\x1b o<6\x0c\xb4=\x92\xa28\x9c6\xebJk\xe1\xe9\x0c\xc2\xca>A~\xb7\x171\xb3s$e\x1e|p\xf8pZ.\x92\xf4gF\xe8\x08\x0d\xad\x84\xc8\xb5\xdbI\xa3\xfe\xa8\xb7{\xd5\xd4\x1b\xdc\xda\xa8\xcfW\x1f\x1c\x8d\xe9\xe6}\x85\xa4\xacE\xbfBYI\xcbX//\xe3nH\x18\x07\x8e\x0f\xce\xd1\xf8\xfd\xce\xce\xce3\x8b\x8f3ho\xf0*\xb9\xd7\xfd\x99\x85E\x10\xb1\xb4\x9e<\x11\xbf\x82yX\x1e\x0b~\x0bl\xa1C\xa5\x9b\xe8z\x99&\xed\xd2Wh(\x07{\x03s\xfb\x16X\xb8\xf3\x0d=\xeb\x08\xe0\xd5/O\x92Z\x90\x1bsU\xdf\x94\xd4\xfc&\xdb\xed\x9c\xe3\x92\x0e\xa6\x9a\xbc\xa4\xc2\x8f\xce\xfaN\xcb\xaf\x88\x85\xe6\xbd\xe2;y\xce5\"\x9c\xb4\xee\xe5}P\x15G\x97\xc9\x92\xf4a\x07.\x01h\x1e4uP\x90\xc30\xcbr\n\xac\"\x1f\xd8\xafB\xdcp\xea\xac\x88\xd6r[$i\xbf\xa3C\xb2\x9e\x1b\xf0\x1b\x18s\xbb\x8d\xfd\x86\xc1#7\x88\x0b\x85\x8d\\\xa5\xab\xd01:W\xa1_V\xae8\xdd\x02\x17\xb4P'4\xb6\x1fi+$\x0d\x94\xe2\xdc\xed\xaa;L\xf0**Y\x06\xd3\"_\xe8\xf1\xe3\x00DH\x05\xcb\x16D\"\x85\xebWpT\x8dT\x18\xe3\x0b\xf6\xf1U\"@FmsEX\xbc\xe1\xd1$\xd3\xcd\xdak;\x86\xac\xaa}\xe1\xf9\x90\x0b\xb9\xfb\xfe\xb0\xb3[R\x03\n\xc8\xf0\xa5\x0f\xa7\x94\x14@\xb2\xd8\x16d\xd3D\xdd(G\xb4\xc5y\x86\xd8\x8b\x19\x9e\xdc\xab\x16\xe7m\xe7\xd2A\xb9\x9e1Y-\xc9'\xb4\\$\x80B\xdc\xd4\xa4\xf2>\xf7\nN\x1az\x80'\xe1\x1dn\x15>\x11\x98\x1bQ\x0fF'+Q_\xc0\xf1\x8c\xd1\xa3\xb9,A\xb1\xa3\xc989\xd4\xbc\x8er\x0dm\x1eg\xeb0Mb\xc8\xf2l\x8bW\xbb-N\x1a\xe4s\x1c\x0f\x95\xc5\xb9/\x8e\xe6\xbc\x87\xcdy/xJ.\xf9\xd0v\x10\x10\xb9\x069\x97\x99\xf2\x00\xd2n\xde$\xc0B\xc3\xde\xaf\xa4A\xb6\xf5AU\xae\xdek|S\xd5}\x078\xd1o\xf4\x8c\xd7Axw#\x17E\x8b[\x82{Jl_\xda\xe1\xc2G>F\xf2H}\xbeVz\x18\xf6\x8a\n\xee\xb2\xa4\xda\xa0\x8c\x88\xcc\x95\x0d\xcf\x15\x03,\xce#\xcc|\x9e\x94F\x18\xf8\xce\xc2\x18\xb9@>\x95\xd8j\xd3\xaa\x1b\xc9\xeaF\x0b\xb8:8\x12m\xde\x0c\x9a\xcb \xed\xfd\xa6\xeck\xa7\xc3GR-\x18\xc4\xed\xc1\x05\x0c}p\xc3=\xb6\x19\xd8Z\xfb\xfc\xdb\xb8\xe0n`\xc3\x1d7\x02\xc3\xcd\xbb\xfaH\xb1\xc2\x08\xf4P\x84\xda\x83\x07\xce\x08\xb2\x1eY\x85\x90<\x8c \xe9\xce\xc8v:\x8fgo\x07M\x1f-\x86S)\xca1O\xc3\xc8\xc8\xe4\x1b\xf3Z\x85<\x9b{\xd0vs\x06\xb5\xa4G\x95\x94\xacj\xfc\xd1\x89\x9e\xcb.\x8c\xb5\xf2A\xa2\x8cvL\xa0& \xc3\xa0j\x10\xf1\xa4\x11\xee\x1c\x1a77\xbb\xea^eCjo\xf0l\xcdV\xda3 \x1b\x16H\x9e\xbflm\xf9\xca\xad(:\x82\xac\xef\xcb\x14\xa9\x07\xbe\x19o\xcf\xda\x02\x13\xbc=\x93$q'\x11X\x12z\xd4\xba1\xef\xa6\x95\xd0\xd6\xd2\xe2\"O\xb8\x99\xa2\xf9\xbb\xfc\x96\x14\x87a\xc9\x8d,6\xdc\x893'\x9f\x19w$\xee\xdd\xd9\xff-\xfc\x11\x96Q\x92\xb0\x1f7I\x16\x16w\xf8+,\xc9\x8b\xe7\x98+*\x9f\x8a\xff[OE\xb1\xdd\x17\xe8k\x17k\x90\xbf\x8b\xf0VQ3r l\x82\xe3xZ?P\xcf\xa8\xb2\n\xd0Ng\xe9`\xb2\xde\xf3\xe8d\xb2G]W\x83+\x83\xf2\x81I3\xd7\xca&5X\xe6[\x93\xda\x89\x91\x83&U\x9c\x83\x91\x91\xe2F\xae\xba\x97\x93\xee\x18W\xe3\x80h\xef\xdd\xe6\xe8\xbc&\x84]\xdf\x87\xcf\xc8\\\x85J\x15\xd7C\x1e\xe3\xc4\x19\xb1\x96,\x96)Y\x90\x8c\x92\xb8\x87\xb5\xa9/\xe7\xb8h\\\xfdF\xb2x`g\xaa\xbb\x8c!{\xdb\x1a\x90 \xa9\x02\xc2\x055\xe2\xeeW\x11\xbd\xdf\x8b\x99\xa8\xcd\xbf\xa1\xe9$\x83{\xa8\xaf\xee\xa8\xa5\xcc\xabP\xf1MQ\xab\xb0\xc8\xcbc\x8e\xe2p\x87\x16R6\xcb\xd8\xad\x06\xd2\x192S\x80\x07q\xad\x1f\xb4S 7\xfdJX]\xd5\xb9\xaf\xd2\xb2\x19\xbf \xcc\xb3\x88TB\xb7\x0e\xd2\x8d\xd6*G;\xbe\xa2\x9a\xd5\x16Q\x83r\xa8\x14-Fe\xe0\x16\xacT\x97\x8c\xdb\xee^\xdbJY-\xd3\xd5v\xa5\x84\xae#\x14\xd1\x81\xf6\xd8\xda\xdb\xbcl\xf4\xc7\xca\xe7Z\x9aw;\xdb\xc7\xd8\x8d\xf7\xdc\xf9\xf5%\xf7Z\xfe\xd6\xb6\xe9*S\xf3ToZ\xae:O/\xbf\xcb%%Y\xecz>\xd0V\x0c\xf8\xdf\xd5=U\x03\n~\xcf\xa0\xd4}\xb6\xf3\xcac\xc7\xe1\xf1bA\xe2$\xa4\x04\x13w\x87\x85\x0ex\x8c(\x83F\x04\xf2\xbbf\xe7\xbf\xb9\x1b\x99\xfb\xe2\xf5\x8e\xe7z\x95\xdbN\xc6-a\x98\xc8\x17\xafw\xbfa\xa8\xeb\xcam\xfc\xcb\x1ds\xf0\x84\x17\xa6\x88?\x99\xfb\xea\xa9!\x86\x97n]-\x0e\xf6f\xc6\x95)jSWx\xa0R*E\x867\x9a\xff\xc5\xb4\xa1.y\xdf\x05\\W^\x1b\"_u\xa5\x0f\xb51\xa2\x12\x9f!\xb4\x98W6\xcb\xe1\x85@\x86\xc1W\xb9A\xb0W\x9b\xbaF\x9a\x93\x05~F\xa0sI\xf4p\x11y\"\xce]\x04\x7f\xd8\x83\x1d\xc6&\xb0\xb4\x914H\x96vN[\x90\xba\xa5\x1by\xde\x1b\xe0a\xee`s\xd3p\x1d\x85z>\xaa\x94\x95rq\xc2T\x1c\x8d\x13z\xe5C\xe1N\xbdz\x8c\x1a\xbf&R\x15w\xc9\xdf\x00\xcd\x0d#\x89\xd6i$\x05\x95Z\x07\x86\x11\xb5&\xd1\x1b1\xd3\x8bHaJ\xc2\xc4nD\n\x8aT\xb8\xf1\xe1+\x97\x12tw\xaa\x06,\x967\xce#\\r\x11\xc0\xe1\x92|\xa6\xa7yL\\\xc7\xe9p\x1cn\xd0\x00QT\xaf\x06\xdc\xaf \x83\xd3\xc1\xe6{\xf2\x80\xe7\x97\xeb\xdc=\x16\xb5\x9d\xdfC\xfc_f\xfd\xfe/\xb11\xe3W\xb3D\x05\xad\xd6\x9a\xe4\x94E\x8e[;Z\"B\xf3\xa3\xca\x8f'8\xd1c\xd0\xc8\x077l\x1e\xc4!\xe5\xe1|\xf6`s3\x81\xff\x80\xa7\\\xdd\x01k\x0b\xcay2\xa5.z\xa1\x10\xe2\x17ix-(\\6\x82 \xad\x96qH\xc9\xbb\xf0\x8e\xcd\xf3\x00*\xd7@\xb2cD\x0f\x83\x80u\x19\xde\xa5y\x18w\x84\xfb\xa9;\xf06I)\xe9>\xe5{:`\x10\xc9\x0e\xeb@9\xcfo\xfb\xc9C\xc6\xa0\xb6|B\xf5\xf8>\xe7\xc1\xb4\x94\x04#UE*\x17\xb0\xba\xfby\x06\xc5\xb6\xe1\xae:\x86ke\x1b\xb3\xd9\xc8\x14\xbf\x8e=l\x16\xb2\x91\xe1.\xc5f]\x88s\x17\xcd\xc3lF\x84UW\xff\x0c\xdes\xfe\xda\xbe\xe3\x1d\xe7\x11\xa70|\xe4)\\\xe41\xb9\xd7\x0c\x9a\xb8/c\xd0\xae\xf6\x06vR\xdc\xb1\xd7|\xf7\\\xf37\xa7\xcd\x9f\xb5\x91\x81Vr\x8a\x1b\xcfi\xb3p:Z\xd1\xca\xb1\xc1:m~\xae\xc2J2;\x83+\xee\xa2\xf2\xbf\x1ea\xe2\xf5mH\xc9\x8fd\x9a\x17d\xfc\x99D+\x14l\xd2 \n3\xf1\x8a~.y\"k\x0cOR%m\x1e\x96?\xe5\xe2\x12\xa6\xfa\xfeKB\xe7'\x84\xf2Y[\x86E\xb8 \x94\x14\xe6\xd4\xe3,JW%\xab\x94P\x9ad\xb3\xb7ya.\xf6\xe3\xddqL2\x9a\xd0;\xfc\x1e\xa6i~{Y\xdc\x1d\xd3\xb3\x15\x95\x85\x16\xec\xa8\xafn\x0ddj\xa1\xbf\x96\xcb<+\x89\xb9P\xa9\x16)\x1b\x05\xf8\x1b\x0dg3\x12\x9f\xc9\xb1\x96\xcd\xa1\x97\xac\xbb\x97\xe1\xac\xca{Dh\x98\xa4\xd5\xab)\xfby\x9e\xd3c\xaet\x87r)\xca\xa3Z\x88\xf6\xe6rzo\xc2\x92\xbc\x0f\xd1\xacO\x00@Rw`\x9ad\xf1Q\x95\xc6+!\xd1\xaaH\xe8\xdd\x91\x96U\xa6\xf3i.\xf2x\x15\x89\xa6\xa2<+W\xb2\xdd\xbc9\xc2eH\xe7\xb2\xfcb\xcd\xfd!I\xe3g\xfcM>SRdaz\x94G<_\x92M\xf9^M\xca\xb3\x83\x8bg\xbc\xec\x92D\xd5\x8f\xff,9\xa8\x9c\x932O\xd7$\xbeX\xdd\xd0\x82\x88\xe6Y\x06\xedC+\xbdQS\xf5r\x91\xaf\x8a\xa8\xce|Ay_WE}\x19\x8b,\xaf!>\x82\xa2\x15\x94\xb9\xafLA\xdaQ\xa5'GyA\xd1\x0c\xf1Wt\x87\xf8+\x9aH\xafn\x13cm\xbf\x97\xd0nVa\xb0\x1c\xfd\x08\x17\xecL\x9d\\1\x96bF\xe8q\xe6N\x9c\x05\xa1\xa1\xe3\x83\x83K\xe6T.\x9e5G\xb5\xd4\xf3a\xe2T\xdb\xact\xae<\x1f\x0f\x8d\x12Eh\xffy\xe1\xb9\x93+\xcfC\xc8\xea\xb1\x87\x94\x97\xa0\xc1I\xb8\x0c\x92\xf2$\\\nE%\xec\x93\xeb`\xb0\x06\xaf\xd6\xf4\x16\xc9I&\x12\xb5\xb9A2\x81\xf7\xe4$\\z*9\xea\xab\x98\xe1g\xae\xe0\xd2\x7f\xf7a\x9a\xae\xf7Bj%)\xbf \xb1O\x94\xe7\xf1\x0e+\x93%\xa7\xea]RR\xcf\xf5\xbc\xa0 l\x1f\xb9\x8d\xaet\xdd\xc1\xc8\x08\xa4\xb1\x081A\x959\xd9\x97o\x88\xb8\xaf?/R\x87[5\xd4\x89]r\x19F\x9c\xbbj}\x9b\xe0\x04\x0el\xca\n\xf8r0\xb0j\xce\xbb\xbe\xfc\xffP\xa3\xa87\xa7\xbe<\xe6AX\x8e\xb3\xff\x1a:\x87\xf1\x84|\xf2\x83\xa4d\xffT\x81$ \xca|A\xbe\x11f+\xe0\xd4\x94\x8d\xfbf\xe4\x92\x07\x1d\xba\xf49>\xa5$\xa3,\xc9\x0c\xabz\xc7\x14\x08}\xd3\x9aH6\xd5\xb1K\xbcj\x9f\xf7\xed\xef\xd6~f\x0b\xda&\xd5\xb8\x8b\x92\xfb\"\x8f\x81\x953Tz\"n\xceZ\x1fQ\xa7\xac\xb5\xb5x\\]r+vW\xbb\xd8\n\x1d\x93`1yb]\x8bM\x811\xd2\xcd_Fp\x89\xd1\xf30j\x15\xcb\xe8,V)M\x96aA\xb7\xa7y\xb1\xd8\x8aC\x1a:u\xb6\xbcX\x1c\xb1\x14\xcc\xcapE\x12\xe1q\xb8\xfdy\xeb\xf6\xf6v\x0b\x8b\xac\x8a\x14\xaf\xd7I\xecT~\xda\x8d\x04\xb96U\x06h\x14\n*\x15\xc0\x189\x1aI\x894\xf2\xe5\x9d\x00Z\x1d\xe3\x87\xf5\xe1\xde \x83&dy/\xb0c\xc7\x8a\x9c}\xc3\xa1\xd2\xc6*\xd1\xaa(HF\xdf\x0bR\x84\xd3e'\xcdS\x19A\xc5\xfd^\xbfrY\x99y\x04~1\xf4\xd2k\xd6\xc1\xce\xff\x893#\x14\xe1{\xc5\xff\xe5%\xfe\xe7\x1e\xba\xd8\xaf|\x89D\x0f\xfb9'a,\xf6B4g?\xd0\xcb\xa6\xa3E\xd2\x88z\xc5\xde\x15Wf;\xd7\x00Z\xf7\x9fS\x1e%M\xa5VX\xd1P\x08\xcb/HJ\"\x9a\x17\x9e\x1b\xf5\x05\x82\xac\xb0\"\xee\x8b\xaaBM\x9d\x9fs\x04\x9cHz\x94\x86V\x85\x1e\x15\x9d7Q\xd3d\x8f\xd2\x0c\xab\x8e\xa3\x0cG\xf7\xfc\xef\xeb\x04\xe1\xa35\xc8k\x14\xcdf9\xdd\"qB\xf3\xc2\xd6\x01A\x9e>J\xf3\x7f-\xf3\xac\xa2>8\x18\xe9\xb3\xacm\x86%\x87$\x8dp~\x94\xce\x14\xa2\xbe\x9e\x0e\xf9Vz\xbe\x97\\R\xdbC\xecSh\xccB\xf7\x11\xc5Qr\x8b\xce\x91\xcd\xca\x80\x89\xc3\xe8\x03~M\xa8\xa6d\xdc\x8f1\xce\x05\x8f\xca\x8a \"~b\x19\x9c\x151)H\xccg%X\x90bF\x18\xc3S\xd3\xa9#\xdd\x16K[\xbbx\x08\xb3\xf4mK\xd9\xdd\xd3\xa5\xdf\x00<\xcf\xd7\x97\xbeZ\x87\xf6\xaa7\xde\xe7*\xff7\xa8c\xd3\x96\xbaC\xb3\xc6\xb5\x88#)\xb9K\xf34\xcc\xfd\xee\x0b\x16\xd1\x98n\x0f\x8a0+8\xd8\xfe\x8a\xbb\x86\xf1Wi\xaf#\xc8\xcai\xde\x9e*m\xae\x16|d\x1aG\xfd\x98\xddP\xab6\xac\\\x83\xb57\xb7\xbb\x1e\xd8\xae\xda\xaa\xa8\xb3u,h\xc3\x9f \x84%\xe5\x0c\xe6\x0e,\x06v`{\xbd\xefNv\xb6^_}\xe7}\x0c\xda\xbf\xb6\x93\x80|&\x11#p\xb8\x0b\xb7]\xd3lH\xe9\x87\xb9+\xf1\xc0\xae\x10I\xeb2\x02\xaag\x12\xee\xdaB\x18s\xe3\xb3\xbe\xc6\xf1\x0e\x9a\x07\x0e \xca\xe4\xef\x04~\x80]\xaf\xb9\xfb\x05\x17\xdbf)%\x03\xd7\x93\xad\xb9\xd6\"\n\x1d\xec\x83K\xda!\xe9H\x87\xca]\xdd\xd5\x8d\xaad\xd5Uk\x18bc\x1bV\x83\x1c\x10F\xae\\\xb3\xb6\xf0d0\x15\x97K\xd9\xf0\x9a\xb7\x8f\\W\x1f\xb6\x9a\xbd\x9a\xf2\x0bB\xe7y\xdc\xab\x9f_-\xb7U\xa6.\x9f\x84U\xc6\x18\xfb-\xc6\xd8\x9bU\x07\x80\xc3\x95\xe5J\xdat/\x8f\x87\xf0\xa8\xb9\xda\xfanh\xbc\xdf\xe8r\xc3oCR\xbc\xe1\x0bB=\x974\xd9\xb8\xbe\xe3\xe5Z\x97f>vGd\xd5}\x1d\xb9\x95\xc8\xab\x12\xb2~[O$\xd5)\xeak \x9e\x0c\xc8\xca,\xf8}\xd4n(U\x1b\x89\xfc\x968\xba\x97\xd0\xab]\xbfY)=d\xd3\xeav}\xa0W\xbe\xd031\x82xS\xb0!\x08g[\x15v\xb5\"\xd4 F\x99D\xeb\xa6\xdcoI\xe2\x1fe\x96\xd5.\xda\x85\xa1P\xcd\xb6r3\xf0(\xed\xcb\xfa\x8cK+\xee#\x1e\xa5!V\x97\x99I\xac.@\x1e\xa5\x1dQ\xdd\x006\xa5\xfbf\xc6\xdc\x99;\x1fn|\xb8\xee\xbe\xceku\xac\x11\xd8\xdd\xaa\xc5Qe\xe7\xd7\x8c\xaeSu\xd0\xe9\x9b\x02\xf9\xa0\xd7\xa3\xae\x0c2\xd3FS\x18\xda\xaf\xb5\x06j\x07o\x13:\x97\xaa6\xe5\x80\x91\x19+\xd1p>'Z\xe4\xd0\xab\xf4\xa1#W\x1f\x03b\x17|\x8ekP\x11\xd5\x9f\xaf5\xe3S\x1f\x04\xcd\xdeU\xe9\x8f\xdc;\x83E\xb2\xfe|m\x85\xb6o\xe7\xb0~\xb6\xfbpnt\xca\x80|\xe4c$%\xb4\xbd\xa5\xa1h\xae\x97#\xeeC\x1fe\x8b\xb3\xbaz\x0f\xc7\xc6\xfbg\xd9\x87\xfa\x8a\xb6\xf7\x94\x92S\x82~\x81*\xc4\\]\x02q\xe5\x01W\xd9G\x83\xee\xcf\xa05\x1a\xe5\xc6\xcc\xa0?\xd1\x89\xc6\x9a\x83\xbc\xd0\xd8\x08\xe5z\xda<\xed\xb7>\x8c\xfd\xc1\x13A\x06\xdf{\x81r\xc6+`N\xab\xf3YEl|5\xaflJ\xb7\xf2d\x0e\"\xf4\xab\xcfH\xf8]\xf4\xcc'\xf7\xa2\x10\x02\xe9\xf0\xd0\x07QZ\xfdD\x06\xce\xb2@=\xc6A1\x8c\xbf\xd32\\G\xe8\xd9\x03\xfb\x08C\xfb \xf6\xed\xff\xd5\xea2\xf4^\xcbZuC\xb9w\x94w\x8c\x1d\xfb\x11TPn\xc8\x9fz6\xee!'\xb1\x0d\x8a\x18\x83\x10F\x95i\x10\x9c\xe2x\x0e\xf3l\x9a\xccJ\xb6<\xf6\x85\xc5\xcb,\x06\xb8\x17yAM>\xd0\xe5\xc3\xfd\x10\xd7{\x92\xe7\xef\x04\xf5\x0b\x94O\xe4\x05\xfd\xf1n\xd8\x9a(e\xcd\xee\x00\xba\x02\xd4\xea\x8f\x9c\x0f\xa3\xdej!t\x1fV\xd8?R\x94\xca\x1cL\nK\x14}P\xe9\xeb}\x90]\xe8\xb0\x11\xff\xea5)\xa6>\x0f\x0c\xf2\x9e\xdd\xd8g\xe9\x83\xbc\xee\xb3\xbe\x1a\x93\xbc'^z\x02{8t\x8aU\xb8\x05^\xd0\xf7\x0eV\xc1\xdb\xdd[\xbb>\x96F\xdc\xd9[\xd6\x01z\xa0\x8a\x0e\xca\x11$\xf7F\x04\x86\x9d\xd9\xdc\x82\xbe\xa6\x07e><\x86\xca\x9ck\x192\xaf\xf0~\x17\x1a\x9f\xf0LST\xb4\x1e\xa93\xbc\xbe>&\xa1\xf1~\x80]ik\x90=J\x8f\xb4j\xef\xd5\xb13\x8e#\x9b\xban\xf7\xe0O\x0e\x95\x1b_\x96U\xb2\xc9&\xa8P\xb4\xeb\xee\xd1\xc2\xa7\xc1-\x98\xb4\xfa\xee\xd1\xd0\xc1\xe0\x86\x0c:\x85U;\x1d\x0dh\xc6)M\xbd\x10\xa3\xfa\xe2\x90\xdeK\x04v\xef\xbbw\xa3JW\xf3|5\xa3\x92\xfcA\x8a \x03\x9b\xb4\xcaW\x8a\x81\x9c\xb0\x14E\xe7\xb89\xb2\x06\x9d,\x15\x9c2y\xc9\xe2\xd8\xc6\x08\xe2\xa4\x1eX\x0b\xa6\xcd\xc3r\xce\xc5\xac\xf8\xf30\x8f\x89q@\xa0\xe3y\xc3\xa5\x9aXq\x93\x11\xca\x03Y\x85JQI\xed\xb6Y\xf7NMi\xb7o^\xb7N,\xf3\x9ec\x99\x1ee^\x1d\xda-\xc2y\xe9)+\xab\x16\xc2@\x13\xa9c\x7f8\x98^'\xb2\xa3\x0c\xab\xe6\x0cf7\xf4{\x1f\xe3.\xbe\xffh\xfe\x19\xdb\xf7\x1b\x01\xa5\xb0\x80\xc7P\x90\xb0\xae\xca\x99\x98\x93\xdc0\x95&\xe5\xf0oD\x83\xbc\xd0\xd5c\xa1\xb8\x07T\x97\xd4\x9ah]\xba\xa1\x0d\x04\xd7y1\xa5N\xa4<\xac\x0c\xb8\x02p/Z\xd7\xc1\x8e}\xd0\xf7\x17\xf2i\xcd\x0e'\xfa>W\xf5\x93k\x1d\xff\x07Hj$\xdanH|\x8d:r\x06\x17<\xdc\xcc\xb1V\x1a\xc5\xf8\xcf\xce\xb6\x08K9\xd9Q\x02\x12\xaa\x11\xa2do\xe0\xd2\xde\x9f\xff\x81*\xa9lRz\x95R\x0d\xb3p\xf2\xaf\xd155\\\xa3\xa0\x99\xb2\xf4\xf1\xd2\xb9\xbd\x1f\x88\xd0\x85\xccU(y^y\x9d\xf7A\xb9T7\xe5#\xaa\xe5\xb5;\xbd\x97@x\xff\x83A\xac\x1a\xaa\xa0x\xa7\xd4\\\x8a\xdf\xb5\x7f\xb11\x1e7\xe5p\x95\x05M\x1f\nl\xcc\x8fP\xaa\x0b\x16!\x8d\xe6\xee\xf6\xffq'\xe1\xd6\xdf\xaf\xd8\x9f\x9d\xad\xd7\x9b\x1f\xb7\x82\xab\xef\xbc\xd1\xb6E\x0b\x97\xbb\xa0HJ\x19\x90\x80\xb1\xed\x1c\x92\xb3V\xd0\xc1\xd6)\xcb/P$\x8a\x14\x92\xef\xd6G\xe7Z\xac\x0f\x1f\x9e\xc33\xe6\x9ar^\xc3\xf6\xc1`h\xd47%\xa2s\x13gN\xe9\x12\xd54)]\x96\x8a\xb7\xac\xe3\xaa$\xf7\x90U\xb7\xdce\xf4\xd4)\x0d\xe9\xdd,zd\x8a\xc7\xa1S\xecF\x19-\x8d\x07\xdb\xe6Rp/z\xdf,M\x96\x03\x02\xcfJqj\xe5\xfa\xd1\xa0\x0b\x93\xa9\xeb\xd8\xc65\x7fm\xf7\xc4\x8c\xd6\xf61\xde#W\xf3> \x97\xda\xb6\xf9\xaf\xb7\x8d#\x8a5\x9c\xf8\xddp8\x98\xcf\xd4\xd7\x92p3\xf3\xa6W\xc2\x92\xd0\xd6+\xe7\xc7\xb9E\x12J\x80\xc7\x8b%\xbdC\xfb\x9f\x8az\xc6\xaf\x12N\xf1\x93\xb4\xa8\x92\x89\x9a\x16\xe0a\x18\xcd\xd5:M\x86S\x82O7\x7f\xc2\xb4\x0bi\x9c\xb5\x0c\x8b\x92\\\xe6\x95U\xd5\xc5\xf8\xf2\xfa\xe2\xf0\xa7\xf1I\xc3\x9c\xfa||q\xf6\xee\xe7\xf1\xd1\xf5\xc5\x87\x1f/\xcf\xc7\xc6oj\xda\xd9\xfb\xf1\xf9\xc1\xe5\xf1\xd9\xe9\xf5\xc9\xf8\xf2\xe0\xfa\xe7\x83w\x1fx\x99\xc3w\xe3\x83s\xf6~\x8c\xf9\xde\x1f\x9c\x1f\x9c\\(_\xce\xc7\xff\xbf\x0f\xe3\x8b\xcbF\xca\xc5\xfb\xb3\xd3\x0b^\xfc\xdd\xd9\x9f\x1aYXoO>\\\x1e\\\x8e\x8fZ\xe9\xedw\xa5\"S\x0fD\xdf\xc7'\xef/\x7f\xe5\xe9\xd7\xc7\xa7\x87\xef>\\\x1c\x9f\x9d\xaa\x19\xf0\x93\x9a\xf0\x9f\x17\xcd\x0c\x1f\xce\xdf\xa9\xaf\x17\xef\xc7\x876\x034\xd8\x83\x1b7s\x9f~\xaf\x93\x9d\xb9\xf8\xf2\xea\xb9\xfe%\x91e\x9e\xe9_B\xf1\xe5\xf9S\xfd\xcbJ\x96\xd9i\x15*\xc5\xa7g\xcf^\xe9\x9f\xd2\xea\xd3k\xfdS$\x9b\xfa\xdek\xd0\x8f\x1c&/\xfaT?%\xb6z\xc7\xe8\x8e\x82,\xd30\"\xee\xf6G\xba=\xf3\xc1\x01\xd0\xf1\x96\xcdkc\xad/\xd6Fsh/q\xdd>\x1f+3g\x8d\xaej\x9e\x1c\xcd\xbd\xf5-\xb6\xf9\xa7\x1d]\x18\xe0\x1c\xe0\x03j\xe9?\xb8\xf5\xdbok\x9d\xa1\x85\xde\xc5\xec\xe9\xc2\xf8\xa1]\xe0\x06\xf6\x88\x13\xcd\xbc\xb8! bO_>w\xf4\xc5\xcc\xa9q\x95?\x8b\x86\x9e8P,\xf7?x\xb4\x9f\x86\x0b2\x02K\xf0\xa8%?\n\xac*\x85I\xf9\x97E\xaa[\xfd\x00\x0crL\x80\xf3\xd6)\x89\xb4\x1b\x9b\xfe\x8b\xa6\x0f\x87o\x9d\x1c1\xb9\xddSS\xdcsjR\x12\x16?\xeb\xa7\xed\x83A\xfb\xf8A\xf3q\"\x14D\xdbj\x1c\x03\x96U\x9av\xa1\x91a\x1f)\xdb\xd3\xfd\xbf>\xa8\xfb}\xbb\xc1\xb2\x9c\x9f\xc8\xdd\x08tS\xbd\x87\xcc\x80\xb4\x1d\xfb\x1f:\x03\x1a\x1f{\xcf\x19`\xf0\xab\x10\x96\xdf2\xf6\xcb\xc7\x1d\xbbT{\xbe\x87\x0f\x10eD\x92r\xfe\x96\x01\x9d\xfc\xb7\x18PI\xe8}\xd9[\xdb\x80\x8e\xee= \xce\x9ew \\6^\x0bx\xca\xf1\x1ad\xc3\xb6\xf16\x89\xd9iEd\xbe4\xd9\xa5e\xaen\xd1\x19W\x05Z\xf4\xe5\\|\xda}\xd9\xfa\xb4\x96Ti\x9b\xcc]\x88O/_\xb4\xc8\xdcY\xf5\xa9Ej\xdfI\xc3R\x13\x93{c=\x14dh\x1e\xd51\x04\xe9v\x0ca%w\x1a\xf3xm`\x1e\xd0\x14Q\xfa\x9fA;\xc8\xe6\x18n\xdb\xfcG\xa3\xc8\xaaH\xb5\x12c\x03\x07\xd3(\xc2\x95\xa8\x1be>\x9b\xd8\xa0F!<\xd2\xb5R\x83\xb8\xabF-\x84\xf1\xc9\xbc\xae\xfa\xfaF\xab\xf5\xd0\xc2\xc7\xf1\x8a$\xf3l\xec\xd0'\x13O\xc8\xcb\x95\x84^\xcb\x8bt\xad\xd4\x81\x81\xb3T\x0b!\n\xd3\xca\x9cup\xa9uYq\xe9m\xa9\xe3\xbd\x81\xf3\xe5e\xd3|f)ca\xa0y1D\xb9\xb6Q\x9e\x18\x99\xf1fAS\x8b\xc7\x9d\xec\xbdZ\xbesi\xfe:@\x8a\xd0\x00\x95J\xccz\xbd 4\x14\x87j\xb3\xceS\x8b\xb4\xa2QOm\xde\xda({\xde#\x051\xd6q]r\x81\x8bV\xd7Q\x05\x0c\x95\x80\xc5a\xcb/e\xaa\x8d\xcc\xef\x86\xaa\xb8\xb9;>\xba\xa8\x16R\xc5J\xdc\xa6\x9bH\xab\\zS\xe8\xd3K\xfeV\x19:\xad9\xb8\xc5\xe7\x01\xe6,\xcdGLQe\x937J\x96\x8c\xdc\x99\x10)\x8a\xce\xea\xf8\x95\x9c027g \x85{R\x83\x1c\xd4\x1a\x16\x10\xc3@\xc0\x97/\x90\xb8\x18\xb0\n\xc1\xb6C\x87\xabD\x0bqF\xda\xb1i-\xda$\x1d{\xbez\"h\x91\\\xaa\xa0\x0c\xa7\xe4]\x1e\xc6\xc6h]j4=\xf3T\xf2\xa5a\xf4t\x9e\x8aX\xfb\xe8\xf1-\x0f2r\xcbx\xf6qq\x9fN\x9b\xa7\x8f=)Y\x93t\x042\xa0\x935\xdf\x82\x94e8c\xc4GP\x90\xb0\xcc;\xcc\xe4\xd2$\xc3|\x8b\xb0\xf8\xc4OQ\xf6+`\xc9\xa8\xdb[\xbfmb\xe4 .:\xb3\xcck{\xf2l[\x05\x03\x1d)\xde6\xf7\xc0Uba\x85\xb0\x0f\xce*\xe3\"et\xf2\xc1\xb6VTo\xad\xd0\xe3&\xe0M\xd1\x88\x1bz\xec\xd0\x1fH#}0\xc4\x95\xfb[\xa5\xbf\xa5Hf; a0\xecM\xab\x86d\xe5\x85\xa8\x7f\x7fBus6`\x8f\x82t\x83\xde\xbbO\xa1\xf2\xff2\xed\x00\x8a\x15\xecA\x18L \x8d\xe6\xf6L%f\x12S\xd5\x01`\x98\xed\xe0\xc2\xc0\xe3\xc8'\xaaD\xb2\xb8\xfa)\xec\xc3?\xbe\xc2\x08R{\x91\xa9\xbcT\x14:\xc2f\xb5\xa0\x0fh, 7\xe6mXd\xdc\x91\x84\x98\xa2\xc6:7\xc2tB\x99d\x11\x81\xf5\xb3`w'\xd8\x810\x8b\xe16IS\xb8!P\x90E\xbe&1$\x19\xac\x9f\x07;\xc1\xce\x1bX\x95\x04,r~\x11\xd0s\xc3\xf1|\x0ep\xb6XW\x0c4\x18i>\xedRv\x8e10\xd9\"\x8fI*/ZN\xc2\xa8\xe8\x88*5\xc7\x12\xd5\xcdVO\xee5\xe6\x16C9\xce()\"\xb2\xa4y\x87R\xf5B\x94\xe0\x04\x8cR\xc42\xcaz\x95\xeb8?y\xe5i\xc1\xad\x9dG\xf0\xfb\xf6\xca%x\x1e\xac\x8a\xd4\xaa\xfe\xc5&\x8fq\x15\x11\x83\x88wIFNW\x8b\x1bR\xbc\xcd\x0b\xb4\xcf\xdb\xb7}h\x86\xdd0\x84\xc2\x90\xcf]\xd5\xcd\x0bZ\xd8\\w\xcb\x1b\xb7\x0eT\x8f[\xca\xe8cH>\xac\x8dN3\xe4\x9b\xb0$Gyd\xe5\x1dA\xb8\x00mB\xc8\x08b{\xf6&x\x8c\xa0c\xd3\xb7ac\x04\xeb\xae\xec-\xc0\x18\xc1\xc2\x98\xfd\xab\x17\xd09\xc9\x06\xe8WA\xe3\x8e\x95M\x98\xbd\x03\xec\xe1\xf6\xad\xfc\x1a\xd6\xae*\x9eL\xc1Mz \x0c\xa8$\x02\x0e\xba\xf3\xcf\xcc$\x06\x082\xa3y\xfb\x9f\xe1\x1do\xa6(\xd6t\x0d\x11T\xe5\xbc\x81\xda\x9a\xeac%K\x08?\xcf\xd9\xa4LWi*\xb6\xc8\xcc\xbd\xf3\x95\x14i\x15\xc0\xd2\x96\xdc\xc8\xb5\x91\xbd~ \xfe\x9a'\x99\xeb\x04\x8eZ\x04)\x15FU\xcb\xd8\x93$\xa0\xdcE\x9b\x9c7\x1f\xb5s\x84\x8b iu\xccr\x9a\xef\x93\x89\x0f\x8e kz\xa3?\xcb\xa7\x11\xcf\xaa#\x10\xa8\xfa\x08\xb9! Dc\xbd\x85\x86X\x01\xda\xa1\x8e= #\x13/qV\xc6E\xf1#j\x99\xe4\xdf`9XhWfvS\xaaVr\xcb\xfc`r\xa5\x1dGo\x85>\xda\xa2&\xc6\xd8kZ\xbf\x96\x15Y\xcdh\xc7\nh\x81X\x03\xdfQ5b\xa8\x0f!\x0f\x80\xe2C\xec\xc3\xdc\x87\xb5\x0f\x0b\x1f*k\xdf[\x1f\xc6V\x85\xa1\xba\xed\xdbb\xd0\x86\xc1p\x0bo\xdexP\xde&\x9c\xca\x0f\x96\x05F\xfc\xe2\xc1\xd0\xbb6Z\x14\x96\x04vF\xddk;\xe5\xe7\xd7\xdf\x82\xf2\xae\xa4d1d\xe3\x12\x19\x8c\xf1y7\xdc\xb0\xe7\xa6 a;\x92\x9a\xfa\xd8\xc1\x05lH\xc2\x89\xc9\x8d\x00\x1e\xe9\x05`\x04q\x9e\xfd\x9e\xc2<\\\x13\x08\x81\x0f\x06h.\x0c`\x08\xe4\x99\x0f\xe1M^\xd0$\x9b\x05\xdcaQxS\xac\x96h\xe2\xc1\xda\xb0\x05\x07\x069\x93\xcf\xfbg2\xd3yQ\xc1\xc6\x92\xa2\xa8)d\xc1\xb1N3\x1fi\xe2\xbc\xa2\xf2\xf8P8\xef\x97#E\xaaS\x9e\xa1\xa4\xfc\xade\xee9\x04\x94\xd6\"R\xe8`\xacK\x0dw\xf3\xb6\x87U\x1eb\xe8\xd4\x14\x91\xf0\x12\x91\xf0\xa2\x1fh\xe1\x1bp\xb0\xe9\xf9\x16\xbclz\x86\xe0j\xd3S)\x14\x8au{\xeaw\x99\x1b\x9a\x1el\xf9\xe9\x83[\x0e9\x91K2\xea\x0b\xb6\xbc \xe5*\xa5'\xe1\xd2\x17\xbc5\x83\xf2_\x12:?\xe4\x0e=%\xcaV\xa0\xed\xa5\x0f\x89\x9b\xe2\xf9z\xbfi\x93O\xc5tL9\x1f6\x8c\x96\xd2\x1f\x13[r\xf7\xb0\xaat\x96\xe5\xe6a\xd5\x98\xd8\x19\x83\xa2\xd2\x90\xc7\xc8\xea\xdc\xde\xbb\xaa>bQ\x7f\x10\xbc^>\x18\xbc\"\x05\xbc\x96\x88x9\x9f\xc4\x8f\xba\x88sWP\x04a\x9a\xe2 R\xba\x1e\xf7f\x86\x8c\xcc\x10n\xc9\xf6\x0c\xe4\xa2lO\x9b\xbbZ\"w\xb5\xd4\xcc\x16\\.\xa1\xb8?\xfbdz*l`b\xa0\xe6\xee\xfa\x7f\x1b\x03ez\x1e\xc2T\x99\x9e{3Z\xa6\xa7\x9f\xf92=\xa8Pm`\xba\x16\xd2\xbd\xf6\xac>WW\x885\xe3\xf6\x87\xb4\xfa\xd0\xa2\x83\x1e:\xbd\x15f\xef\x94\x10u=\x96\xa3`\x04\xf6\x08\xf0\xb6\xe7A\x88h\xf7\xfb\xfba\",\xe4\x90,v\xeeW\x0e\xd4\xcdX\xd2|i\xf1\x91cz\xba\xa9g\xf9|\xc5\xe8\xf1&G\xb6\xc6\xdc6\xc9\xa4\xfa\xb4\xae\xf0z|)\xa8O5Xs\xd0\xcf\xde:\xba\x07\xfd\x95Q\xc3\xab\x8an\x13\xb8d\x00bW \xd6\x9d\x9a\x9c\x0d\xbb\x93\xab\xcac\xcfR\x9a\xd0\x074\xff\xcf\x8b!D\x84\x15\x9c\xa7\x8a\xc8X\xd4\xd6=\xc0\xae\xf5\xe1\x90\xdb\xc3~\x8e\x95\x83\x92{-\xafxz\x1f\xaf\x8dx0\x10I&>\xed\x06\x07\xe4\xf1\xfaz\xf4\xba\xbbG5c\xf1\x1aO\x87\x1d\xec!^V\xba\xbb\xbb\x9e\xafK\xfe\x02j\xbb{\x80\x8aL\xed\xa1Sc\xb3\xa1\x83\xcb\xc6>\xae \xd3\xdef\x9e\xd9\x9b\x19\x8a\x11\x86\xec\xfe6\xd0\xab\xbb\xda\x87\x89\xb1\xd4\x841j\xbb\xaf\xafZ\x1f\xaf\xda\x0e2\xe0\xd9\xf7\x0d\x9d{\xab\xb5\xc77^\xec\xffM\xc6\xc1\xf4+\xa8\x03\x0cC\xfaV\xf7LX\xbd}m\xdb\x02\xdc\xd3\x11x\x8fJ\xdcy{\xff~\x8b\x8e\x9fT\xd8l\xaf\x99m\x80\xfe\x10\xdb\x1c+o\xfdO\x1a\xdd\xc4\xe2\xc0F\x0cO\xc5\x83\xf7\x1bi\xcb0\xe9[\xd6\xee\xf0A\xa3\xab\xb4\xa5\xcdC\xe4.\xc1\xef\xbd\x84]\xf6X\xdf\xae'\x7f\xf1\xcf\x18\xe9#\x98\x13\xf0\xb058\xea\x9f\x85\xe9\xc2\xf0iS\xb7v\xd3\xbc\xed\xc1j\xae\x03&\xa5_=\xd7\xfc\xb9`'\xb6\xc9\xcd\x81e\xc9>uAK\xc3\xb8\xef\xbf\xe7h\xffv\xaf\xd1\x1e\xf4\x8c\xb6e\xe0\xf8\xbfa\xd0g]\x83n\x18y\xf6\x1e\x9c\x1d\xe34\x8c\x857\xff\xbe\xab\xf9\x96\xd9io\x17\x86*\xe5\xd9Tn\x8aa*{\xf9P\x95\xbd\x95&\xeb6\xe7\x12\xf1\x06\xc3\xf2YOu)\x12\x96\x0c<\x18\xca3\xe7\xe1r$qW`\xcc1\xc5\x1c\x95\x8e\xa8\x05m\xc2\x1e\xacl\x9c\xc1\xfd\xb4S\xac\x9a)\xe6\xec3\xbc0\xe0\xacD\x9b|M\xa6\xe0\xce\xe0\xc9\x13\x98)\xa1\xc7\xf4w)y\xd2\x93\x85{\xd2~\xf1\x93\xa4iY\x0d\x1bBK\x86{\xc7\xaa\xcf\x89\xf6\x1e3\x98\xa5w\xc6\x0b\xcf;\x1d\x07\xb9\x93\xd4\x87\xe8\x8am\x84\x8c\xad6\xd2X^\x17\x9bJ\xd4)\xd9k\xbe~\xf9b\x8d\x1f\x00\xca\xd6P\xcbLx\xc3\x1d\x1e\x0c\xdd\x0dt\x0e\x8e\xa1\xfcv\x84\x8b\xa52\xf9;w\xda\xe1\x9a\xea\x82=p\x0c\xbe\x97\xc0\xcc#\xa0H\x07\x83\xc8}\xa6\x1f\xaa\xc8Lq-\xfa\x91\xcaH\x01\xcd/\xd0\x12\x96\xb1\xcf\x02<*\x00?\x8eQ\xc8\xa7\xbe\xefi\xdfG\xbcP\xca\xfeD\xa2\xf3\xcd\xfcY\x90/\x8fcw\xc6\xefc<\xd4)\xe5d\x96k]\x136\xa97\xb0\x07)l\x823r`\x13\"\xf3\\2v\xb6\xe0\xb1>\xca\xa0D\x1c@\xe2\x0bLro\x90ko%w\xe8_]\x8bjX\xbe\x9f\xc3\" oR\xd2\xa5\n\x05\x18,\x9d\xe5\x1eU=\xe9\x96\x08\xb0\xa5,\x97aDFpc\xcd\xf8\xb5_\xbap\xfb\x08=\xedo\xbf{\xce\xabv+\xf7>\x15t]{\x12\x91\xec\xc35\x8c\xe0\xd6G5^=R\x1d\x0e\xa2\x9d\xec\"\xa0\xf0\"\xad\xa8u\xa2L+\x9d\x17B\x87!\xdfm\x7f\xe7\xd8\x17y\xac\xb6\xfac\x1es\x9c\xc4\x8b\x9bK\xb1\xc1\xdd\x05I\xf9\x9f\x17g\xa7\\0\xed\xb9cT\x8cW\xab\x81=`\x19\xb86\xbc;\xf6F0f\xfba\x8csi\xc8<\x16\x93\x0c\xa3\xf6\xa7\xf6\x86n\xa5\xb0\xa1|\x163\xaf\xb8\x01\xf9\x07z\xe6m\x8f\xe33\xee\xc4\x9bU\x92J2\xcc\xfd\xec\xf9P(\xc4\xa8\xab\x1c\x90\xf5A\x08\x9f\x0d\xb5\x11\xc3\x11\xa6R\x19\xbd\xfeq\xd7\x0d!\xe0\x84\xea*:\xea\x93\x9bG\x99u\xab0\x16m\xc2\xd32\xc0\xbc\xe1\x9bD>_U\xf8k\x0e\xd3p\x97\xcc\xc6u\x01{p\x14R\x12d\xf9mG\xa8\x9bLRg.\xd1\xd5\x05\xad\xd3F\x83x\xc5Qj\xa3\x0d\xd8\x82\x8bj\x0dyO-c4\xa8O}\xf5\x84\xa0\xad\xbfyuJ{\x1a\xea8c\xb9\xf6F\xd7}\x0b)\n.^\x98\xab~m\xccg\x9ei@\x8d$\x0b\xafI\xdan{\xf4aK\xf5\x04\x83\xa3\xaf\x1d\xab\xa3\xaf\x9d\xa6\xa3\xaf\x9d+T\xe37P\xef\x15%\xda\xfe\x96uR\xa0\x89\xd8\x07\xb9b\x9e\xc3}\xfeP\x0c1\xc9\xcb9Wf\x1fi\xdd\xa4\x9bT\xd2$\xc14\xebR\x9a\x0f+}\xd5\x01\xf4;\xe9\xe7\x07\xca\xea\xf6\xdf\x16\xa5\xce\xed>\x0c\xb9\xfa\x80\xe6\x1d\x8b_K\xd8\xa9\xfc\xb0\x1d_W8x\xednl\x8a\xf7\xc9\xed\x03\xcb\xce\x08D\xa6\xa3\xca\x9c\x9d\xd1J\xdb\x9f\x17\xe9v\x12P\x86\xac\xa6\x96N\xccq\x00\x15\x81\xd8\xe8\xbe\x0f\xb1\xfd\xec\x16\x80\xb0\xd2\xb8C\xd4},\x9a\xb85\xb1md\xa1\xfcm\xd1\xbf\xe7\x8a\xdf\x96\xa5\x96\xd8\xa2\xdfb\xd8V^\x92\xc4V\xednS,\xdc\xa9\xa5\xab\xc2\xb4\xd9b\x9fa\x0c\x97\xbb4\xa0\x1c+\xce\xc1_=\xce\xa8H@>/\xf3\x02\xfd>7\xe7\xbb\xb2\xf1\xcd\xdc\x97\xcf\x9ej\x90P\xdb\x087\xbdO\x19\x9b\xb4\xb57@,\x89\x91]\\n\x00\x12f\x11\xbaUD\nKA\x80\xe8\x11\xb4\x80$\x03\xe2\x01\xde\xea\x03\x9b,T\xb4p\xd1\x1f\xeb\x08\x92,\xca\x8b\x82D\x14\x92l\x9ds\x07x\x1b\x16W\x8e\xe4~3hv\xe7U\xd9(\xb9\xaf\x9f+\xcdT\xc3\x0f\xa6CD\"\x19\xb9\x1d\x805Y\x8f\xda{\x8d\xd15\xc1\xb2\xc8\x17 \x8a4YUdX\x9096\xe9\xca\xfcRm\xbe\xb3\xf6,;?\x861\xbc\x17mEyV\xd2b\xc50\xb3M\x97\x11O \x1f\x0f\x1b\x83\xbc\xd6\xf3y\xe7\xc5\x05*\xcb\x84\xbe\xe5D\"\xa3~1M\x0b.\xf3U\xb5;\x1c\xb4t\xf5\"}\xbfcZ\xa4\x01bB\xd4\xb0\xe3GW\x921\xd8D~\x9aLrv\x16\xe3\xbf=\xa0\xec\xdf\x08\nVG\xee\xe3\xeb\xbf\x04\xf2^>\xdf\xb5\x8c\xaax\x8c\xea_\xbd\xb0\xd4\xce@M\xd7g\"\x9f\x97i\x12%t\x04\x13\xd6\xb1\xe7\x8c\xe0u_>\xff^\xfc\x7f\xe1\xa9\xdeP\x1f\xde\xbb\x0eJR\x99\x97\x17\xbb\x167\x93\xec\x9b\x8e\xea@\xd0=\x9a\xc7\xca`s\xeb\xea\xbb\x91\xb7\xef~\xdc\xfe\xb8\xed\xed\xbb\x93\x8f\x17\x1fK\x0c\xc9\xd9.\x1eb\xf1\xc9\xc1\xd6\xff\x1f+\xe0\xffw\xb6^on\x05W\xdf\x8dX\x05\xdb\xedB\x8c|\xb1\\\xad:\xff\x86\x9e#\xc3r\xae\x87\xf3\xae\xb3\xec\xb3,\x7f[\x91\xe2\xce\x9eg[\xfatDG\xca\xd6l\x7fd\xd9\xc2\x15\x92x\xbb\xb6\\\xa7\xe1)\xeb\x13\x8fH.\xaf\x86w;\nl\x8f\xdc\x8f\xf1\xa6\xf7\xef\xdb\x18\xc8\xbch\x14\xebo\x04{\xac5\xd4*c\xa8\xa6}\xce\xc9\x87M\xe7\x08v\xcd-\xe3D\x8e`\xb7\xf5Q\xf5# \xaa\x9b\x8d\xd4\x8e\xaf3\xaepo\xb3\x94C\x015\xfa\x83s+\xc3m\x1a\xa4\xe2\xd4\xe2\xc2@\x8bp\xd5\xb9I\xf3\x9b\x91#d\x9e\xcb\"\xa7y\x94\xa7\x1e\x87{v\x96\xb8\xab\x8c\x94Q\xb8\x94\xbc\x13\x9bF\xcf7WH\xd2\x92\xe8\x8e\xea\xf6t\xf7\xd8\xf2A<\x981\x1cX\xb7E\xb0b\x1fJO\xeaz\x14\x93\xcc \x91\xac\x1bR-\x99\xad\xda\xd6uS\x84\xa1\xdb$\x03\x94\x90\xba\xacr6_\x93LG\xaf\xf2Ql\x14\x8a\xa0L\xc3rNP\xfc\xec\xd6o\x8c\xb0\xa5\x9cQ\x9f\x17dj\x8a\xfa\xd3J\x91\xbc\xe9\xef\x9a\xd9\xccp\x11u{;\xad\x02\xfaZ\x89g\xf3\xa4\xc8\xb5\x1e\x01\xe5\x0e\x9f\xd9\xbf\x80\xe6\xef\xf2[R\x1c\x86%A)\x8fc\xb1v\x17\xa3\x1f\xc1\xc6\x06\x9d<\xb5\xec\xbe\x82\x94\x94U\xff\xac\xbd\xd1\xf4+V\xf3\xd0\xa7\xb6C\x14*J\x8f\x1d\xf1*\xb17\xad\xbdPW0E\xcd\x82\x176\x83\xdc\xec\xa9\x94\x1a\xf7sn\xc1\xb0\x12\xc1\x91-\xdc\xcc\x02j\x97\xdd\xe6\x1c3\x96c\x9eX\xb8\x8a;\xd8\x83\x9dv\x7f\x10L+\x88f\x84\xd3\x02\xad\xf5\xe5f\xaaR\xb8=\x8e\x8f\xcb\xcf\x1d@s\"B \xfe\xb3Q\xf50\xabJ\xe4\\\xcc\xe7\xf1\x82)RH\xec\x9c\xdap\xd9q\x13\xb9\x84{.\xf6\xbc\n\x0f\xe0\x85H(A\xdd\x87Y\x03\xea\xe5\xef/_ \xe1\x1eu\x95\x8cU\x15\xc8\xf8\xc9\x17DL\xea\x9b\xe3\xf8\\l\xc1h7\xea7ku\xd7\x93\xa7l\x83N\xb6\xdd\xe0;o\xbbq\xf4xo\xe0\x0e~\x80\xb5\x10s\xbc\x81\xbb\xcdM\x0f\x91\xb5\xcbx\xd8\xf5\xe4\xee\xca\x9b\xec\\\xf9\xdc\x12{\xb2{\xe5C\xc9f\xa5\x84}\x98M\xe6\xb8\xef\x19|\xb7]j\xb2\x1c\xff\x8f\x1b\xa3,@\xfaX.=~\xc9\xe1dh\xfe\xa2f_\xb2>\xee\x83++\x15\xa0\xb3#tT\x95\xa4\x1861\xb7\x87A\x87\xb5\xfczf,\xcfs\xc6(\xfc\x15\xbb\x9c\xf7C\x14\x8eq\\z1\xdek\xcf\xf3\xe5@\xf1\x9f\\\xa5\xe5\xe4\xd9\x15\xae\x96Hd+\xb0\x9c<\xbfR\xebe\xff\x9a\xa8\xc0\xb0}8`\xcd\x02<\xe9\x90\x14\x12\xbf=\x84+\x15 @\xf1c?\xab\x8e\x91 \x9a\x87\xc5\x01uw\xc4\xdc\xea\xdfy\xef8GQ\x9f=\xa2\xd5*\xd3\x00?\x11\xa0\x92\xdd\x18\xe9\x0c9\x14g\xdb\xf1\x82r\x99&\xd4\xe5?\xe5\x0cn\xedz\xd2a5Q2x\xbep\"\xc1A\x8e\x1b\xbce\x93\x02\xb6\x18\xfd\xc1\xb7\xd2.7s\xdby\x03\xc5\xd6\xd6\x1b\x0f#{\xe0M\xd9\xa4\xb8B\xcf\x19\xac\xba\x08#\x13\xec\"~\x0d\x9a\x19\xdcf\x0e\x1fB\x06\xd6#\xee\xb7\xc3\xdd\xa9\x03Z\xb8 \xf7j\xe0C\xab\xc4\xd6V\xb7\x94\x19\xd7&\x0bVY9O\xa6\xd4u\x1c\xcf\xc7~\xb2\x89\xceq\xa9\x82\xea\xed\xcb\x17\xc8\xb8\x0e\x1cf\xcb\x84\xce\xfc\xb6)\xa2\x8a\xb2*\xbe\xbabl\xde\xd8\xb7\xbc\xa0*f\xe0\xfa\xa93\x19a\x97\xff\xe0\x85yf~{\xc8\xdeV%)\xc4b\xb36\xca\xf26/b\xfc\xcc\xbe2B\x13\xa7d\x89\xdf\xd9\xab\\\xb5Q\xab\xfcr\xb2S\x81}\xa3.\x86#\x04\x02d_\xf2\"\x99%\x19oP\xc1\x86\xa2\xbb\x88l\x93\x94\x8c*\x98\x95y\xf6\xd5\x97Mp\xb6\xb7\x1d\xd8\x94\xc5F\xe00|\x8dM3b\x01\xab\xaf/3\xb53Q}\x9b\xf2J\x85)B\x1b\xc4KBG\xbd\xac\xa7|\xf0\xe0\x13'\x94\x19R*\xeb\xaf\xae\x0bh\xae2\xca9\x86n\xa5\xd1\xdeX\x17\xd2\xdd\x84\x8b\xd4\xaa<\xa8x\xa0\x85d\x82\x17\xc9=\xe6_C4{9\xd7\xd0c\xee*Zc0K}H\x14p\xdd\x17~1\x12 \xb2I\x05\xb2\xd5\x95/\x0f(o\xc8Q\x8d\xc3\xe92\xd7\x84\xa1#\xa98\x9a\xa1\xa3I\xf8\x96\xe2\x13\xbd\xb9'\xba\xcbS\xd9$\xcb\x1e?\xc64#O7\xb4c\xdb\xa3\x8f\xf1\xe6\xbfos\x1a\x9a\xb2Yv\x85\xffxe\x0b'\x12!\xd0`\x99/\xdd\xaa\xc3bSS\x81\x96F\x8e\xa7\xcc\xbf\xfc\xa8\x14\x7f\x9c\xc9\x97 \xd17F\x95\x08\xa2\xcd\xf3\x94\xf5\xa9\xa6\xa56z\xa2N\x0f\xeb\x95\xa4\x8d\xfa\x94\xbcQ\x0c\xd0o\xf4=\xc8\xd6\x13\x0dW\xd9\xc4V\xad\x0b'3\xfbx\xe0\x8f\xc0\xf97\xcb\xb5\xb6\xfaHhP(\x82\x0da\x16\x1e\xb2M\x05&\xe5V\xf5\xf9*X\xc2\xc7@\x15R\x8c=\x08~\x8d\x99\xccF\x1f\x15\x05Rr\x02\xa1\x84\x1f`U\x91\xaf%;\xe7\xed\xf3\xcd\xca10ZM\xca\x0e\x0d\x9dT\xd2q\xc9$\x9d\xec^\xb1\x1e\x8a_\x1a5w\x8fnK\xa2\xa1>\x11\x93\xc6\x89\x98\x18O\xc4D=\x11\x13\xc3\x89\x98\xe8'b\"O\xc4\xa4\xa1\xde\xd3\x0e\xeei\xba\x9f\x14\x05F=\xb2o@\xd7vMNI\xf1\xa5\x8f\x04\x89\xf0\x8c\x84\xf5%\xd3\xbb\x0e\xcd\x1b\xca\xe5\xd1v>\x0f@\xc6\xc9\x95\xe3\xb7\xd0e\xd8%1s\x85\xdc\x04\x85<\x1c\xb7\x18\xa9\x88B\x07\x81\xb8;\xfa\xc4\xe3\xb4n\"\x1d)\xd0\xcb>\x9f\xf2\x91\x1d\xf9U\x97\xfc\x15\x9d\xc4 \xcc\xcd=%\x8d\x11\x7f\x15\xb9T}\xe7\xc7H\xfd\x05I\x7f\x96\xfeGG\xfe\xcc\xf8J\xf3\\\x92\x10\xcf\x87\x8d4X\xa6\xabY\x92\x95\x93\xec\xaa\x0biR\xb9\x86\xe35\xc9h)\xeby)\xeaQ\xab\xe9>5\xe4)G\x03\xb2\x167\xab\x1d\x1e\xad\x14D\x9fd\x10z\xb0r\xc3Iy\x85\xeb\\z\xb2\x17\xaf\x1c\x94;\x19<_\x82\x11\x17\xab\xd7\xb4\xed\x95\\\xd9h\xfe\x94w\xf94\\\x90\xa3\xa4\\\x864\x9a\x0b\xedd\xb6\x19\xcen\xb3\xcaP\x99{\xc9b]{\xed\xa0*BGY!8m\xceA\xad\x8f\xb1\x9c\x87%\x89\xcf\xc9,))\xd7q`uhS\xc6A\xcd\xb0|\xd5\xfc%l\xfe\xacR]\xaeS\xab\x0d\"\xf1<(\xdd|\x92\\\x89\xe9\xe8\xd9\xe9P\xa3?=\xae\xed\xefLy6HPh\xc3B\xfcR\xba\xed\x0f\xa2\x07>c\xd3;\x17\xaf\xb4/\x9e^'\xbfB/\x19\xf5\xc1\x17kwg\xa7\x02\xe7\x8e\xccH\x06\xb7s\x1c\x91%\xc9b\x92EI\x95M\x01\xf1Iv\x15\xc4J\x0ee\x10\xf2\x97\xa4K\x9a\xfd\x16\xfb\xaam\x95e\x83\xa7\xb6\xda\x91e,\xfd\x19\xd5!\xb5s/\xf3\xb2LnR\xd2\x82M\xe1\x01\xa0 \xa1\x19;\x9e\x10y\xbc\xc7\x11a\x8c\xc9>\"#\xafVf\x97\x9d\x81u0\xba\x8a\x83\xe7\x92&~0\xb0\x95\x0bu\xd6\xbf\xa7\x1b\xe5\x8fw\\)e\xc0M?\n\xa5,\xb2f.\x0e\xc3k\x11\xeb\x0e#m4\xd1G\xa7\xe6\xe2N\xc5\x8e!\x133\xeeI\x10\xadH\xb9\x93\x8b\xafr.\x9f\n\x9c\xc4\xf3\xe0\xad8\x17\x80\x0dD\x9fH\xa1\xf6L\xf4\x8c\x88 \xe6\xc0\xf66/p\xd2\x87\xce3 \xe2\x06T\xb7\xc7\x8flUk\x13V\x17\x16\xf6\x1d\xdc.\x84\xb2*\xb3[g]\x1b\xc3\x86\x8e\xbbNqn83\x08\x8f\xcb\xa7\x02)\xd4\xac1`^\xf9\xe0\xc9\xaeC@\xd1 V\xa0\x80\x96}\x96\xb2Iq\xd5\x01uP\x1f:b\xc2\xdbQ\x85\xe4\xd3u\xfe\xcaG\x92\xcd\xab4\xed\x82\xaa\xeb\x82\x94\xa4\xb1}Gv5Nh\x11[\xb9\xb8\xe4A\x8fg\xad\x8d\xc3\xe5\xe1\xe2\xb2\x94\x91]\xed\xe1Wd\x8e\xe4'\x8c\x97O\x12\x88\xedg~\x1f\x12\xa1\x1e\x0f\x9e\xdb\xde\xd7\xa2{\xd4\x88\x13$Yk]\xd6\x8evC\xbc>\xf6\xa0\xd0\xdb\x0d\xd5v\x8bI\xd8\xbc\x804j\xd9\xaa\xf4;_\xcf\x87S\xe9\xdc\xa3\xa2\x99VG/\xd0\xee\xd3\xdd\xa7\n\xdd+Hw\xf7\xb51\xfe\xc6\xaaC\xdd\xad\xa6\xb9P4\xfc\xe5\x0b8\xab\xecS\x96\xdff[\xb8\x8e\x9a\xf0\x85\x04\x11w\xe9p\x19\x163B\xf1biF\xe8i\x1e\x93\xb7E\xbe8\x16\xf7\xa8n\x81\x97\x84\xfb\x10\x06I\xb6\xce?\x91?\xad\xc2\"&\xf1a\x98\xa67a\xf4 }Cp\x7f\x99\xd8-\x82W\x14\xe6\xbcU\x16\xdf\xd0zc\xef4\xa9\x8a\xb6\xdeER\x8e\xb38)\xe7}\xf8X\xecK\x87\xe6\xcb\x93|U\x92\x0fK)\x94b\xd3C\xf3\xe5e\xbe\x8a\xe6\xe3,6%\x1f\xb2\xf1\xa7\xe2K\xd7\xb6N\xca\x93|M\x1e\xd0\x1dV\xcc\xd4\xb2\x92\xde\xdd\xee\x05\x0d\x0b\xfa\x80\x86\x8f\xf2\xdb\xcc\xd40\xd67\xa0e\xa1\x82{\x94\x14$\xa2\x129\xf4u\xa2>\x1c\xaf\xe5\xe9\xf8.))\xc9\x88M\x0b;k\xe6\x960i\xc0\x03M?T\x94\xd3\x10\x8cXx\xe6\x18\xa1\x8dA\xb4\x19\xde3\xcf\x18\x18\x18\x14\xfc\xc4\nS\x97\xd83J\x95<#\x90\xfb\xc6 0}\xac\xc6[},\x06-\n/M\xca\xe36\x95j\xb9\x16]WV\x80C\x97\xa6\x18\xbc4\xec\x9c\xd5\x9d0w\xe8\x01I4\xb6\xf3\x06r\xf8\xa1v\xd5\xfc\xe4 l\x90 )\x19b\x0fg\\[\x9e\xe6\xcb%\x89]\xef\x0d\xe4\x9b\x9b^\x8d\x1d'\xf9\x95\x0fE[U\x12\xa4\xc2\x10^X7\x90\xa9!\xe3\x03W\xe9!K\xc4Fr@/\x8b\xd5`J\xbe_\xbay\xff\xed\x06\xf7\xdar`\\[\xdaI\xbc)\x84!\xbf\x19\x87\x1f\x1a7\x7f\x1d+\\lnv;\x18B\x8azR\\\xb1Ue\xe4\x9f\xa2\xfd3)\xdajG\xa0\xdc\x15\xa0\x87\xe0'O\xd8\xa6\xe6\xc1\xb3e\xc1n!\xa9\xbe\xd8Xe\x97\xfaU\xe7\xde\xee\x847\xda\x05U\xf3\xb0\xac!\xaa\x0f\x80\x14\xf1E\xbb\xbd\xaeV0\x9e7\xef4C\x98\x0cq\x0el\xab\x08\x0ce\xf5@/\xed\xd6t\xd4|\x9f\xd6Zh\xbd\xbb\xb5\xa4<`k\x81\x0e#{\x91\xa5\xe4\x18\x82\xba\x14\xcf\xdb3\x9ew\xf9-Zw,\x16y\xf6\x90\xe6,U\x0cj\xfb}\xc8\xce\xa1{\xce$6\xd9,\xd93\x8f\xb4\x08\xd7\xa4(\xc9\xe5m\xfe\x9e1\x8c\xc3\x14\x11\xaa\xe6\xf4\xe2U\xa1!m\x8e3J\x8aw$\\\x1bZE\xd7\xe6FYu\xab\xed\xba\x1a\xadp'\xfc\xa0\\&\xc93\x93g\x0f\xfe\xf10_,\xf3\x8c\x11\x03\x05\xe9]\x00\x90'l\x1b\xbf\xb4Q7\xaf\x9fU{\xc9\xc7\x10\xa6C\xea\xcf\xcd\xf5\xff\xce\xfcfa\x8f8\xc6x8{\x042 U\x95\\\xf1:\xb9\x0dd\xcc\xb1\xaah\xcb\xa4\xa33j\x14kUQ\xa1\xc2\xc9\xee6\x86\x02\xe5^M\xe3FL\xccN\xcb\xca\xac\x9b}je/\x08\x1a\xca\x1c\x86\xab\xd9\x9c\n\xd7\xe1\x9d\xb2\x02v\x8aY\xcdr\xd6\xc2&\xd4\x12\x14\x86\xdb\xe4\x14\xf5Y\xf4\xadp\x91<\x1c.\xcc\x164&n\x97S7\x94\x13\xd7_\xbe\x00 \xca\"\x1a\xa7dA2|\xbfM\xb28\xbf}\xa3O+\xdb\xef4@\x9b\xaer\x99gq\x92\xcd>\x94D\x96\x93\xfaG\xd6\x1c\x9e\x0f\xcfxh\x9c \xcbc\x82F\xfd\xfb<\x8c\x1c\xc9\xf0\xe0i\xe8(|\xab5\x8e\xd0-t\x9f\xaa\x163y\x10\x85\xd9\x87\x92\x1c\x9d\x9dT\xe0\x1b\xe7\x11\x1a\xef\x06\xc9b\xc9{\xca/'\x9f<\xb1}\n\xe6a\xf9\x96\x84tUH\x7f'\x1b{\xd6z\x94\xcc\xae\xe3\xf8\xa8\x1d\xdc\x98\xd9\xed\xef\xbekB\xcdwp8'\xd1\xa7\x92Af\x98q\x81?$%\x94\xab%[_\x1e\xc0\x89\xce \x08.IP\xc7\xe82=['E\x9ea7\xb4J\xf56N\xcf.\xc7#\xb8\x9c'%\x8f\x0f\x95\xe5\x14n\xf3\xe2\x13\x08\xa3\xbd\xf4\x0e\xa9\xce,\xcf\xb6f\x8c\xc6I\"\xde\x13\xd6\x8fh\x0ea \xbf\xf1H\xca\xbf\xf9z\xd5\xbf\xa1\xb8\xee7\x1f~K\xf30f\xff\xd1\x08\xfc7\x1f\xa3Q\xfd\xc6\x1ds\xfc\xd6\xd7\xc1\x1f\xf3\xa2\xc8oK\x98\x16\xf9\x02N\xf2\x98\x14Y\xf2\xf7\xa2\xaf\xd4\x1f\xd1^\x14\xfe\xc1\xb5\x0f\xbe\xd6\xd7%\x17\xab\xe94\xf9\x0c(D\x84L\x98\xaf\xcf\x02p\xa24\x89>9z\xbdUE\xfb7y\x9e\x920chq\x89K\x8e\xab\xc3\x16\x07\xd7@$\xa2\x9c\xb7\xb1J\xed\x1a\xa51AU#c\\dE\xedenW\x90\xb036\x0b\xd3\xd6\x874\x89HV\x92z\x9a\xe0Y\xb0\x13\xec,\x0b\x02\xee\xe1\xaa\xa4\xf9\x02~\\%i\xec\xc1\x1789\xbe\xd4\xcao7\xde}\xbb-\x9e\x8eL\xd0~@\xddS_\xbe\xf0[\x82\x0d\xd7 \xe3\x18\xe7Z\xd2\xc8\x0e\x83Z\xb9GjVA\xbfY\x91\x1c\xb5\x93g\x0el\x9a\xfc`\xa1PP\xad\xecM\xbbOF\x92e-\xae\xa0\xab\x8d\x1a\x15$\xa4\x12=\xb9N\x9c\xacM\xea\x1daP\x12z@i\x91\xdc\xac(q3\x1f\x84\xb3\xe47\x8e\xd0\xfe7\xaa\xc2\x84\x93\xcc&2\x05\x85\x9d@Mb\xae\xbdr;'\x95\xd8\x0c\xa4~\xf2\x10\xac\xc2\xef\xe6\x03^\xde\x07\xe7Y\xb0\x83\xaa\xd6\xc9\xa3!\xd3\xd6\xd1}\x90\xd2\x118aJ\xffL\xee\xf4\x90\xbayF\x8b<\x1d\x81\x13\xd1\"m\x7f?!4\x1c\xa1\xdb\x82\xb0\xfd\xf1b\x9eLY\xcd\xa8W\xcd>\xd7C\xb0\xd0:\xb6\x03\x0e\x0dW\xb3\x90&k\x82\xf3\xd3\x86\x12\xf43v\x92\xc7\xc94!\xc5\x05\x0di}\x8d\xd4\xfe\xd4bO%\xa0\x16\xad\x1b\x83\x8aS\xc43dc\x83\xaa\x90PC\xc1\xb0\xf3\xbau\xcd\xf2\x08K\x99\xb9\xaf^\x1b\xd4_2\xf7e+=\xe1j1\xbb\xdcv\xf4\xd9k\xfc\xf7t\xf7\x95\x1e\xfd\x9a\x8b\xe4w\x9f\xeb\xe5W\x98\xfe\xec{\xb3X\xbe4b\x151d\x93h\x92S\x18\x93\xdd+!\\\xa7\xe8\xb5\xf8\"\xb9I\x93l\x86\x1eu\xa6IQ\xd2\xc3y\x92\xc6\x86)_\x8b\xab\xf6\xc4\xedc\xafH\x90d%)\xe8\x8fd\x9a\x17\xc2\xb1D]\xa1q0\x91\xad\xaeB\xd4\xc58\x0dQ_\x8b?3\xe94XM\xb7Z3\xb3ob\xdcl(07+\xeaTaK\xec\x840\x8fI\xa4\xcc\xb8]\xb8\x95\xba\xdc\xee\xba\xe0\xd7\xf7\xdc\x82\xbdCk4\xafh_\xf5\xd1\x88g\x1c\x1cZ$Q\xb4\xdaA\x91s:l2\x97\xd6\x03l\x88\x1c\xae\xba\xcf\x9d\xec\x1a\xee\xdfb\xac\x1b?\xef\\\xf1;v\x12\xf0`\x9b\x08\x89-\x0eK\x0355+\xed\x1eFl\x83\x89\x8e\xe5\xab\xc4\xef\xddK\x87|P\xcfR5\xfbZ\x0cc\xfc\xe6\x0861\xa3\x15\x8b|U\xa6w\xe7d\x99\x86\x11a$?\xe3\xe3N\xc2\xe2\xd3j\xd9DS\xeb\xb6k\x8c\x9e\xf2-\xef \x05\xcfuD\xd2d\x91P\x12_\x92\xcf\x03\x0d<\xe4\x84\x11\x8571K~\xf9\xbda\xe7\xb4\xe6\"\x1c\xe8>\x17\x9e\xa7n\xe1\xeb\x14\x08\xeb\x19\x8a\xf6\x18\xe4\xe4x=\x02\xfb\xe0\xae\xf0\xde\xcf\xf3!v\xf9u(E\xd5||\xeb\x95]-\x8b<\"e\xf9\x01=\x14\x97\x03\xc4e\x0d\xeb\xae\x9d7\x90)\"\xe67\x90\xd9u\xab+\xf0\xb2\xea\xabHS\x98\x02oXm\xf5@\xa5]\x7f|z1>\xbf\xbc>98\xff\xf3\x87\xf7=j\xf6\x88u\x0b\xe9\xd8\xc7\xe7GJ\x11\x84SJ\n6\xa7}\xd1\x0d\x06\xd9\x05\x9c\x9c\xfd<\xbe\x1e\xff\xe5\xf8\xe2\xf2\xf8\xf4O=\x1d\x9a\xf2\x0eL\x85\xb8\xf6\x9f\xd4\xa3\x8b\xf1\xc0\xf9 \x1b\xf3\xf3\x18M_\x8e\xffry}xvz9>\xbd\xeci|\xf5\xe8\x8d\x9f\x8fq-N\xcf\x8e\xc6=m/\x9b\xeb0T\xc9\xe9\x9e\xf2\x9a5\xa6>\x88\x1a\xb3{\x01\x9a\xd3\x05#\x9f\xe7\x94.G\xdb\xdb\xb7\xb7\xb7\xc1\xed\xb3 /f\xdb\xbb\xaf_\xbf\xde\xfe\xcc>kd\xf3\"\xa4s{\x99W\xdb'!\x9d\xe3\x9f\x93wZ\xc9r=3\x16{\xba\xb3\xb3\xb3]\xaeg\n\x01\xfe8C\xed%u\xd5\xe8\xe9\xb5\x0d\xf6\xc9\xc5\xc1r\xc9\x10(\xfe@S\xde\x0f\x19\x0f~\x1f\x85\xe9[y>*\x94P%\x826\xaa\xbfvV\xd3\x1f\xd6N^L\xa9\xad\xb4aI\x17\xac\x8e\x1e\xdb\xdb\x8cQ\x8d=s_\xed\xbc4\xd0\xf1\x99\xfb\xf4\xc5+\xcf\xcd\xdc\x97\xdf{AR\xfe\x1c\xa6I\\\xc9\xe6\x1a\xb9CE\x19\xdee4\x7f{\x12nV\x94\xe6\x99\xd9\xaf_4'\xd1\xa7\x9b\xfc\xb3\xf9k\xb2\xc0\xf8\xfe\xa6O\xf3$\x8e\x89\xa5\xd2\"\x8c\x93\xdc\xf2\x89\xa0\xed\xa6\xe9S\xb9\xbaY$t\xd4\xd2L\xb6i \xe9\xeb\x8d\xe2\xee\x0dv\xc8\xe3\xa0H\xfc.\xc9>10\xac?`x\x04\x99\\\xb8\xce\xab\x97N\xaf\xae\xb2\xde\xcc\n\x95X]\xadR\xa9\x9f\xc8\x93\xf2\xec\x10\xe5mR\xc7\xfc\xd5\xab\x9ev\x0c\xdePZ\xed\x88Q\xf5\xb4\xf4\xba\xd1\x92\xfc\xc5\xc002\x9a\xd2\x8a\x88\x11Ch-P\x18f2\xa1\xa8\x93\x19N\xb8.\xd6\x15\x17N\xcb\xee\xf0\xb7\x82\x84\xf1Y\x96\xde\xf1\xb78)\xc3\x9b\x94\xc4\x8c\xbcb\xfd\x1f\xa1\xcb\n\xe1 \xeb\xd7|%\xc3\x83\xc6\x10\xc2o\xd8\xad\xdfX\xd2\x12h\x0e!\xa3y\x160MH\x1a\xc3mB\xe7\xf9\x8aB\x98\xc1o\xb2\xc1\xdf`\x1efqJ\x8a@\x91\x93\x16$\x8bI\x01!\xb0\x8el\xe5\xac'XC\x00\xc7\\\x90\xc7\xeb+\xe7\xf9*\x8d\xe1\x86\xc0bEY\x171\xd4\xfeo\xc22\x0e\xbd\xf7\xfd\x16\xc0\x19\x9d\x93\xe26)\x19\x99@(\x90\x84\xbd\xab\x1d\xc8\x0b\xf8M\x8e\xf8\xb7\xc0d2n\xd9~$~\xf8\xfc?\xe2\x94\x8b\xbe\xfc\xb7\x98\xf4C\xd1\x97\x7f\xd2\xb4\xcb\xd2#H\x026\xf3\xbf\xeb\xc8?\xb5\xda\x13-\xdb\x9b\x16u\xc8m|\n\xbf\xcb\x99\x11\x94q\xdb\xfc\xbf\xd3J\xb0\xe5\x08\xe95\x9b31\xa9\xdc\xff\"\xe4S\xf8\x8d[~m\x82\xf3[\xd0\x0ckh\x94]::m\x00\xa2Oq\x0b) \x18\xbc/\xf2%\x1aE\x0c\x83\xcc\xa62td\x03^6\xbe\xc8\xa4\n-%\x16\xd1\xa4\xb8b\xc74\xe7\x9a\x1c\x06\x88\x8e/\xee\xeb\xf2\x0e\xcb\xa9D\xf5\x89\x83\xe0\xcd%\xdb\x89\x0c\xfb\xc7\xba5\xedV\xdb\x99T\x99\xafP\xd5\xdeN\xde.u!\x81|zI\xd4&d\xcd\x08\xfdY\xc7\xbe\xa6.V\x9a5\xf5\xf1\xb5\x8f68(\xbc\xa8\x12\xff_\xf6\xfew\xbdm\x1cY\x18\xc4\xbf\xf7U\x94\xf9;\xa7\x0f9\xa6\x15\xc9v\x9cD\x89\xe3\xe3v\xdc\xd3\x997\x89sbg\xfa\x9d\x9f\xc6G\x0f-A\x16'\x12\xa9CRv<\x93\x9c\xeb\xd8o{\x0d{\x01\xfb\xec%\xed^\xc2>(\x00$\x08\x14H\xcaq\xf7\xf4\xec;\xfc\x90X\x04\x88?\x85B\xa1\xaaP\x7f\xc4_\"X\xf5\x8d\x15\xc4\xdf\xee\xfb\xc4\xa6=\x8d\xbd\xeb\xa7\xea\x11\xaa\x8d\x84\xd9a\xf5Z\x1f\x81|\xdd4\x06i)vVn\xc6V\xc1\xb7+$T\x94Ql\xd7/\xe4\xfd\xa9\x1c^m|M\xb3q\xb4\"\xab\xc8vJ\xf2{\xa4\xfd\x10\xce.*\xf8\x1aFI\x10?\x1c;\xd5!\xb1\x08\xe8\xfd\x12|\xa7\xe4\x18\xb7\xcc2\xfb\xe2\x1f*\xf5\x8c\xa9\xc4\xb1]\x88\xa0\xd2f\xa0\xda)cI\xa9\xd5\xa0k7Z\x95T\x15N\xab\xcb\xd26|UO\xe5\x98\xb4/b*\x90\xb3@\x92L\x96\xc8h\x18\xc4\\@\x06\x8f#\x8a\xc4M\xb6\xc1\xc1\xaa\xa7\x95<\xd0X\xf0\x0dv\x06\n\x0bd\xae\xd6\xca%\xabN\x83\xdd\xa6)\x0e\xb9\x8f\x95\x8a2q\x9f\x8e\xcc\x87\x16\x0du\x00\x8f\xb0\x0e\xfeQ\xf0}\x82\xdc*\xda\x1f\xa2\xa0Xa>9\xe5FB\x80N-\xa2\xa4\xba\x9a\xec\xdbwFZl\xb1\x9a\xcf{i\x16#\xec\xc2\xedZE\xadV\xd1z\xff)\xa1\xfb\x89\xdd!%\xb2q\xdc\xa8cjW\x84\x87\x90\xb4\x10\x15\xe1\x04\xc4\x0fg\xcf\x9aK\x08*\x00#\xcd\x8a\xf89\x06Q\xb2\x071\x03\x7f+\xab\xdc\xb3G\x91H\x99\xb9\x95\xfal\xc4\x7f\xa1\xaa\x1e\xffp\xdf\xf8\x96\xd06\xd6\xef^\xc8\xd9y\xc1\x15\x9c\xeb\x0b\xb75\x10\x7f\x132\xa6^\xb7\xd0\xea\x12\x17\x8b\x18\x81'\xab\xaca\x85\xbd\x94\xbd\xceU\xd0I\xd7=\xb7B\x1e\x12b\xf5\x10\x91\x88wUl5\xfe\xe6\xa8^%\xb6\xaa\xc40\x84Z\xfcG\xbc\x8dV\xe9\x9a\xd1T\x07\xff\xc4\x97\x9f\xd8\x9d|\xf7\x89\xdd=\xc4Z\xd17\xcb\"Tf\x1bAV\xac/M\xaa\xbdCo\x08\xdea\xdf\x11y\xd1\x1bb\xf1\xae\x9d\xba\x9bH\xf8\xa3\x80\xfd/\x9c9\xf6=4J\x08\x14u\xf7\x1f\x8d\x0e\x87\x97\x8f\xae\xc3\x0e\xe7\x87\xbaZ\x1e1\"\x96c\xa3._\xc5\x0f\xfdV\xa0\xf4q\xda.\xa0\x1c\xee\xf2\xe2\xe1&@\x11\xe0\xf0U\x8466\xea\xa3\xb7)\x87\x95\xf8\x8dQ1Y/__ D\xf4w\x05\x83S\xbd\x18\x04\x81\x06M\xff\xb0\xff\xe5p7xx\x80V\xf8J\xd3\x8a\x07 \xce\xec\xe2\x8a\xf6\x0fP\x916\x18\xec\x9a\xd7\xe6\xf2z]\xde\xab\xef\xef\x05\x9d=\xda\"BN\xec\xb1\xe4\xbf\xd6l\xcd\x04\xdfP\x8f\xccm\xb7@h\xbbJ\xdb I\x94\x1a\xcf?\xfd\x14+\xe8C\x0csQ\xa9\xb8\xe4\x82\x8ah/z*B!\x11\x014\xb3\x8e@\x92\x04fF\x8a\x8e\xf2\xf7\x0b\xd8\xed\xe3\x95\xdb6x\xe0\xf3&\x86\xc0q5\x93a\xaeB\xf0\x02^\x16x\xa0g\xffs\x87\x16p\x9d\x1fh\xeb\xed\x1a^\xa2\x0e}\xad\x03\xbd\x01\xdb\xed?\xce\xdf\xa6\xeb\xa4h\x97\xa0\xd4R\xd1\xfd\x83n\x86RH3\x94\xdeXH\xfclZ\xdaT\xd77\x89!I d\xaa\xecr\xbb\x08\xed\x8b2\xd9k\xe9\xbc\x88U\xed\xe1\xa9mc\xaf-\x94\x9cEu\x84\xd2\xeeb\xbd\xf1\x8a\xa1\x95\xa9\xea,\x87#\xea\xad\x08\xbf\x88\"\x13\xf5\xcd!\x8c\x8a\xcb\x10\"\xebB\xbb\x11 \xaf\xa51^\x07\x11\x93\x91\x03%\xdej\x03\xa5\xbe)\x07\xda\xecM \x07\xfac\x9aM$-\xe8\x8aM\xf4bH\xe3\xder@Z\xc3(\x98\xf0\x11\x15fJ\x0crH\xf2\xe6\x1e-\xaa\xba!T3\x9aH#\xf4rd\xd8\xf0\x7f\xf0\x9e\x14\xac\xaa2\xbdo9l=\xc1\x82\xa6\xd4\x97\xbf|\x02\x99\x85\xf5_\xd5\x90\x17\x84\x9b\xa2a\xd2\x80\x86\xc9e \xf0\xb0\x0b0\xcfYA\x01\xd2\x05\xc5\xc4 E1[?\xa1\xc0\xf8\xe5\x0b\xd0\x05\x870\xba\x0c\x02\x85\xb0|\xd4\xa6{\"=jy\xe3\xe4\xd8=\x0e,\xa86\x8327\xc7h,\xac7\x96\xc9\x0e\xf9\xf9\xdb\xbe1\xcc\xe5\xec\x0093\xd6\x99.\xf7I]\xc0\xee\xae\x87#\xe7\x07\xea\x86l\xc77x\xc9'\xfe`/\xa0\xb8\x90\xbd}\x9a\x0b\xe1<\x86\xee\xaf\xa9\x8f#\xbd\xff8\xba\xdd\xed\xdeT\xc1\xdeP\x928I\xa7\x8c\x16j&\xf3(\xe3\xa5h/\xccP\x1b\xc0yI_(\xbaU)^M\x0d\x84?ARZ\x06\x0e\xf6\xf8\xde\x92\xc8P\xc0\xcbC\xd8\xdbE\xd5\xc1^\xa9[(`\x08\x1bJ\x9a\x15h\xad<\x15\xd2\xc5`\xf7)y\xdd\xbao\xde\xc2b\x98\xc7\x91`\xa1${si\xb0\xe3k8\x04u\x0d]\xe9V\xeaurB\xfbR\xaf\x81q\x0e\xcb \x80\xf5\xb2 \x86,\xa8+k\xec\xdb\x89\x85\x90\xeae\xde\xc3M\x97[\x18a\xf3\xf7\x18\xaa\x8b\x05|\xdfD\x8dJ\x0fdf,\xf2\x84\xe24\xa15\xe9\xd3\x0c\xe7\xa4\xd4Ex\xb5\x8c8\xa8$\xd2yO\x1a\xf7\xaam~X\x0f\xfe\x9e\xe8w\x01\xc2\x8eK\xf4\x94\x04\xbc\xea\xec\xbe\x08\xb5\xfb\xecI a\x8c>\x83j5\xcff!4\x82\xbe\x93\xbc\xa2\xf7\xe3\xcaJ\xd3\xb2eA&1\xd2a\xe7\xb3\xde\xd5]\xc1\xde\x08u\x12\xcd\xf8b6\x9a\"\xe8\xe5\xac\xf0\xc5\x0f\x0cb\xdd\xe6\xdec\x8e^\x05\x87\xc4\xf5\x9b\xc7yo*\xe6\xa5R \x0e!\xe2EJmm\x16\xba\xc1\xa0\x00\xaam\xfc\x01n\xf2G\xfa\xc6\xff\xef\xbe\xd8\xf8\xfa\xbeG\x94\xc4\xa8\x0b\xc5\xfc\x03\x9b\xac\xb3<\xc6$\x86\xebP\xf8r\xf1\xf7mWB\xb8w\x8d\x8dk\xedX\xc5\x95H\xaabs\xab\x9e\xa7|(\x84s\xb8f\x1c%\xe84z\xda\xce\xd2u\x82~\xbcY\x9a\x16\x8e\x9c\x98\xe6~\xc6I\xce\xa3\xfc\xa3BhmB\xc0\xec`\xf3q\x15\xc4\xb0\x99{\x16&B$fuq\x8e\x01\xcb{ \x94\xfe&u\xec\xc5c\x90\xfc\x1a\x14\xf4}\xe4\xc0\x02\x02\xd9\xd4\xf3\x95\xcc\\V^\x94\xb9\xc6\xa7\xae\xdbb\xdf\xb4u\xd5\x9f\x08\x15\xaar\xd4\xeeyjg|\xd4qV\xe9(\xb9l\x99\x18\xb9\xdb\xaa\xe4w_\xeb\xb2~3\xef^\xa2E\xa1\x19(;\"yH\xc3\x12\x91\x92\xbdL\xf9\xa9l\x9cD\x96,\xe1K\x89\xb9 \x12\xf9\x13\x0fl.\x89\xc8\xdfe.fyh\xf0wE\xc6\x98\xe5\xd8EN\x14\xcd\xb5Y]B\xf0q\xdbh{\xa3\xe8!w)l\xb1:\xc6\xd0\xa8d \xcb7Q\x08\xef\x83\xc7\xa6\xbeD\x08\xefOLY_\xba8\x0e\x1e\x93.\x8e\xcf\x06OZ%\xac\x86k\x04\xce\x06Q\x97\xc0\xbc\x81]G\x19\x17\xf2\xf7\x1ce\\\xc8\xdfw\x94q\xf1\xfe\xc0Q\xb6\x82Cx\x0c\xea:\x9cH\xa2<\x05y\xfd\xbd&iV9\xd9\"\xe4\xb4w\xde\xc8D\xdf\x84\xb0\x0c1\xd1\x1bnKL\xea\x96\xfa\xd7A\x08W\x98kv\x8d\xd9\xe4\xf6\x82\x10\xc6\xfcL\xf1\xef*6\xfbV\x90\x99S\xf4\x05?\x82)\xefo\xccE\xa4\\\xfd\xeaW\x06R\xcfa\x0c/\xe1\xf69\xdc\xba\xb6*\xdf\xa6\xfe\nc_p\xa2,\xa3\xe4/\xe1\x10\xae\xfc\x1b8\x84\xbb\xd1\xede\x08\xb7!\xf0\xc1\x99Z>\xb3\xa1$\x80\xd3\xd1-\xe7\xf5\x974\x11\xe1OI\xc5\x96A\xb7TA\xa0\x18\x9a\xbdf\xbf\x17\xd0\xcfjw\xff\xa0\x9a{\xdc\xb9\xb9\x9b\x0e\xad\x1dtn\xed\xb6Ck\xbb\xed\xad\x9d\ny\xe5\xc6\xbd$\xda\x891i\xe4\x7f\x14\n\xc3\x11\x17K\x86\x80\xd9\xf5&p\x04\x13\x18\xc2i\xad\xba\xe9\xeax/\xcd\xa9\x14\xdb\xc4a^j$\x8a\x10\xbc*\xd3\xb7g\xfa^H\xd3z\x9d\x0d\xe3T\x13Sv\xa5Y\xfcW\x95\xde\x1d\xcf\xdf\xf2\xe5\xf1\x04\xed\xca\xa4-\xda\x0fQ\x1eO\x8e\xd7\xc5\x9c%E\\\xa6bpV\xff1\xcd\x96\xef\xa3,Z\xe6F\xad\xd5jA~\xfe\xbeJ V\xf4V\x19;V\x05\xaf\x97\"!1\x16\x9c\x9c\xbd\xfb\xf1\xf5\xef?~8\x1d\x1f\x7f\xbc\xf8 _\xfd\xf1\xf8\xcd\xebW\xc7\x17\xa7\xf8\x83\xbf=\xfb\xf0\xfa\xff\x7f:>\xe3\x7f\xee\xe2\xcb\xf7\xb2\xbaU\xf0\xe6\xec\xf7g\x1f/\xea\x1f\xe2\xaf\xf3\x9f\xce~\xc6O\xc6\xef\xcf\xde\x7f|\x0f\x87\x8a(|W\x81T\x86\xcf\xf5\x13\x7f\xff\xb1yE\x9f\xca\x92\xdd=\xea\xf2\x1e\xbf\x19\x04\xb5C*\x9f\xa7\xb7\xaf\xf8\xa2\xc6\x1c4\x9d|\x9e\xecm_`\xea\xf9 A\xa1\xa3\xbbE\x1aM\x87\xcdbG\xb9\x16\xdf\xd2;A\xfe\xbb\xf5\xbeH\xaf\xd3u'V\xdf\xd5\xf5\xea\xbe]\x97\x13?\xe3\x7f\xed~\xcb\x18\xa6\xf7\x1d\xc3\x04\xa3=\xaf\x05\xe2\x7f\xcb\x08\xe6\xf7\x19A\x1d\xb1#\x85\xbe\xfdg&\xfe\xaee\xd1\x9ee\x96\x92\x0bV\xa7OZ\x9e\x10nEJn\x13&\x1e\x15\xf5\x92\x8a\x1c{zJ\xacv\xcf\xa26\x89\x89c'{|\xab\x8dW\xe9j\xbd\xf2\xec+\x8c:%\xf0J\xcc0\xaa\xae\xea\xf4\xc3\x13\xc8kT\x9ab\xcaK\x17\xf9\xf1V\x19\x1b\x97\xed\x8fSD=/\xa4\x89\x98gU4\xa0?\x17}i\xc4\xd0S\x17\x97\xd8\xa6E8\xbd\x12\xe1p\x10^\x8d\x1a9\xe8o+NV\x9c\x1c\xc5\x95\x94\xcay\xdcp\xc7X\xb3!\xe2m\xd1cY\xd6XKx\xd2\xf3\xc6\xe8\xf2H\xc4,K?\xb1\x84\xae ,\xa8\xa5[#]e!\xf2RM\xe6l\x19\xd15&\"\xc2E\xb4t\xf8\xfb\x8b\x9b\xb1kV\xf8\xdel\x91\xdeR\xe1\x82d\xc4\xf4uO\xe2x/\xbf\x8d\xae\xafY\xf6\xf1\xf5\x076\xc5\xb8\xcf\x822\x85\xe0E\xe51+t\x063\xcep\x88\x1c;\xbd\x84\xdd\xf2e;\xcd\xcc\xa4\xfe\xea\xe1\x8d\xbc\x9e\x92G\x04\x7f\xf2t\x9dM\xd8P\xe5\x90\xa7\xe1\xc1n\xd8b\x08\xdem\x94%qr\xed\xa8%%\xc1!x\n\x8f\xc4\x91\xbf\x8c\xee\xe0\x8a\xc1\x1a\xddgCXEy\xce\xa6\x90\xa3y\xc5m\x94\x83\x88\x0e\x86J\x8e\x9ce7,\x83\xf7F\x95\xe4\xdf\n\x89ml*\xc2|a\x1eRQ\x9b\xb0C\x0cB\x88z\x18J\x0c\xed+~M\x10a\xafm\x00\xf2\xfb!\xc4j\xdd\x03?\xa2<\x821\x13\x97qH5\x0c\xdf\no\xa8\x1e\xdc C\x88\x88.\\$U\xa7\n\x14\xaf\xf6\xeb\x92\x04\xd6\xb8\x11c\x11X\xc3\xb9\x11\x059(\x13\xab\x91u\xd62\x84\x87\x98\xa0\x9b$Tu.\xac\x8bt\xf5L\x84zu\x11\xb3\xa4x\xedhk\xa6\xd59g\x93\x8c92\x9b\xaf\x9c&\xba\xfc\xb9\xce\xa2\xa4\x18\x8b\xf3\xdfS\x03s`\x1e\x7f\xf2I\xca\xabrp\xa6+\x96K\xfbF |\x16\x01\xac+A\xf5\xa0\xc7\x9e\xa3l.}\x15\xcd\xf7JKy\xc5\xa5 A\xc0\x16p\x04\xf3^\x9dL\x1c\x82\x87\xf2\x06\x9a_\xf2\x1d\x92\xf7\xae\x8a4\n\xfc\xa8\xcc\xf8\xba\xc6\xbbM^\x96V\xbbgEy\x9d\xf3G-:\x89\xfc\xae\x8f\x14 \x87\xb0&\xe9\x8a\xcc\xc1[\xce\xc2\x9f\xa0\x06`*\x97s\x1cs\x08M\x82\x10f\xf5\xf79\xae3\xdf<\xe8\xba\xd5y\xf2\x93r\xf2\xb3\x00\xd3\xec\x99\xf2\x9b\x83&\\\xa5\xd3\xbb\xa1ji\x1d/\xa6\\8{\x15\x15Q\xe0\xaf\x1c\x8a\xcdu\xb6\x18\x8a\xe0\xce\xbe\x87T\xe3c\xb60Y\x0e\xf5\x08\xb8\xc6\x0eD`\xd1\x94e9\xc9\x96\xf2\x07AH\xb2\xcdPR3\xe2N\xdcI\xafB\xb7\xb0\xf9[\"U\xa9\xac\xc1w\xdf\xb7\x10\xb3f\xe2\xb2\xeeH\\l\x93b\xfd\xa9a\xe7\xb0\xcb\xce\xdc\x84\x8a\xd0\xc1\x00\xd4S#lr\xfbL26eI\x11G\x8b\xbc\x9d\xc4\xa5m\xb4\xcdI\xa3\x1eb{M\xee\xb3e6\xd9{r\x83\xb4\xec=\"r~\xc7\x0d\xe4\xd6\xe9\xb4\xdb\x00\xb98\xf3D\xba:\n\xc6\xf6c\xb6hV\n;m\x8f\xb3\xb2\x8fV!\xa1h\xe5\x1b\x8a\x96\xadVt\xd8j\xc57o\xb5\x1a\xbaG\xfa\xbe\x1bO8\xc7\xefF\xf7 f\x08(z\x13g\xd81\xac\xa5\x0e\xa6!8`\xa1\xd5\x12\xc7\xd4\x10\xd6\xee\x9aj\x11\xc7\xeb,\x1e\x12V\x04\xd0\xb8\xc3\xb2\x07\xd8af\xd2U\xf5\xb4\xef\xb0t\x93\x1df'\x9c\xbe\xd7\x0e\xa2\x95\xa8\xff\xdcJ\xb5\xe7a\xb6\xd2o\xe6\xd4\xfa\xbbm\xe3\xbf\xff\xe6\xbc\xff\xf1\xb7\xd9\xe6\xfc\xa5\x8e\xbf\xeaZ\xe4\xc1x\xc7\x99C\x13%\x90\xfe\x9a\x152\xeb\x1f]+\xef\xc6\x7f.:i\xcf\x84\x824\x8d\xf2\xbds\x0c\xae\x9e\xbaR\x15 \xbdh\xbeb\x93\x96\x8a\xabrx-\x15\xa7Ho8\xe68\x96\x0e\xcbQ6\xa0+\xdc\x94W2(}\xcd\xe1\x08\xfe\xf6\x15\x9cR\xc6\x12\xdb\x93\x08AW\xb9\xae\xb7\xb8T-.\xe9\xeaw-\xec\xf9\x95\xd05dD\xa4 \xfe\x8c[4\x97\xb7p\x08\xfeJ\xc3\x07\x1f\xad\xe2\xff\xf65\xe8E\xd3)\xde\x11E\x8b\xff\xe0\xf0\x11\xd6\xfa\x82-\xa3\xdb:%\xae\xaf\xf4\xb2Y/\xce\xcf\x8e\xcf\xf7\xfc\x80\xcb\xb0\xfd\x10\xa2J\xa0\xbe\na\xd2\x13\xb1\xf7\xd9\xf4\x1cul\xbe\xc8\xac\x0cC\xa2\xee\x8c\xcfXV\x08\xeb^\xe2\xbaU\xd1-\x1c\xd5\"\xf6\x89\xa6\xb2\xaa\xa9\xdb@\\\xa6\x9f\xca\xb4\xf4\x87`\x08\xfa\x7f\xfb\x1a\x82,\x0c\xe1\x96\xb2\xe3\xe3[\xee3\x1c\xc2i\xe9\xd1\xe0;\x88\xc89\xd1\xbc\x93\xa8\xf2\xf3|\x85a\xcc+\xd9\xf2\xd1_\xf24 \xa1`\x9f\x8bG\xabE\x14'!\xfc\xee\xd1\xef\x1a\xa8\xbcw\"\x82[\xee\\\xdc\xad\x98g4\xf6y\xe7\xf6\xf6vg\x96f\xcb\x9du\xb6` ?\n\xa6\xb6b\x13\x04\xb5\xba\xa6\\\xb3z3VL\xe6\x8eY }\xfd\xec\xd8'\x18\xd6i\x08\xde*\xcd\xcd\xdb\x0c\xf5\x94d\xf5\x9c.\x97\x12\xfd\x8dc_\xe0i\xe18\xf9e\x9c\x1bt\xf3\xe2`N\xb3!\xac\xfd\xa0g\xbfw}\x9f\xaf\xd2$gD\x03V\x81\xd5\xc0\xd7\xa0\xc7\xf92\xbf\x99[\x02\x8d+\xd3,KYo\xcaO<\xf7\x92#\xf5\x97.\x91B\x1b\xfd\xe5\x0bx\xaes\x0d\xd4\x15\x88\xfc\x02;9\xd5>\xa3\xed X/\xfd\x84\x0e\xcc_\xbe@\x06G\xb0hWw\x83\xa6\xf2v\xd0Z\xe8\xa8\xd2\x86\x8e\xeaqhP\x7f\x13\x16\x85\xa0T\xe0yG\x158\x94\x8c\xc1\xd8=\x00\xa9\n\xb7\xf9zP\xdd\xfd\x03\x00\x8f\xf5\xf2\"*\xd6\xf9\x05\xfb\xec\x9a\x08\x85\xe6\x98\xaai\x03<\xaf\xacQY\xa0l\xfch\x04D\xcb\xc5r\xb7\x89\x9b]\xf5K\xec\x90\x06\xae\xf9\xa6\x0c\x00P\xfb\xc4m\xf2C\xe7\xa6\xd2\x1f%\xdbh!M*\x17\xad#}\x03\x8bL\xa4\xcd\xe6E\x99\xdc\xb9\xc2sp\xfb\x10\xbc\x10\x98H\x16%\xc2\x04\xe0\x0ft\xee\xc5\xbf\xc6S\x96O\xb2x\x85b\x9e\xfe\x91\xf6\xbe\xf6\xa9\xfeA\x93m\x92\x96k\xcb\xf6\x0e\x02\xa0|\x86\x00\xfd\xec\x7f\xf3\x18\xbd\x01\x1a\xd7^\xfd\xf6l\xab\x10\xad\xfe\x14-\x17\x82\x81s\x99\x10\x95\x19\xa7\xc8\xe8\xbb\x98k*\x15!U\xeb&\x12Y\xb3\x89\x84\x91\xbb\xb6v\xb7o\x0d\xac\xd1\xd8\x94\xdedR\xea\x89\xab\x0bk\x0c\x87\x1cM-g\xea\xc6\xc4p\xb2\x19\x91\x0fT\x13X8\xa2^\xcc\xb3\xf46\xe1\xa8\xaa\xd3\x9f 4q\xfe\xb7\xb7\xf4\x8b4\x9a2a\xc8vq\xf6\xfb\xdf\xbf9\x1d\x0b\xeb\x8bs|\xf5\xf1\xfd\xab\xe3\x0b\xfdU3^\x98\x16\xc5\xbf\x14Z\xacUh\x86Flh\xb1=\"\xb4\x11\xa5\xed\x91q\xd2s\x0e\x9e\xd9 *PrH\x16\xe9\xf5\xf5\xe2\x9b\xcc\xd1\x08\xe5\xe5}\xac\xa1\x88e\x93\x064\xf9X@\x8ep\xc9&\x96\xbf\xfcH\xcc\xcc\xd3W\xa0D\x9br\xb2m\xba\x86\x1a\xfd\xbf\x07\xf6\x97\xafK;\xadL}D\x07AG\x03\xfd<\xc3\x8bmi\xae\xcf\x92\x9b\x9aA\x7f!\xcd\x17\x95\xc9?\x92\x1b\xe4e\x95}?\xe7\xbcr\xcd\xe0\x7f\x95\xe6\xc20[\xfdz\x1bq\xc1M\xf5%\xed\xb7e1\x9e\x9e\xd6Z\x90j\xe3\xf1U:\xbd\x1b#\xf6y\xb6,e5&\xb3T\x8d/\xfe\xf4\x9enN2Vx\xbfk4\x18\xd5\x1b<\x7f\x7f\xf6\xee\xfc\xb4\xa9E\xb1\xd3\x9b\x9a\\\xd7\xe1\xc5\xc14\xfe\xe3\xf1\x87\xd7\xc7?\xbc9%\xe6,\xa06\xbe\x91\x08/\xa7\x8d-\xde\xeb\xd8\xbf\xd1\x02\x95R1\xc2\x12\x7f\xb7O\xba\xc2\x0e\x1e\x9b\xf1\xad\x84/\xecc\xb3\xbap\x85}b\xbe\x16\xee$\xfb\x8f\xcd\xf0\xa8\x0b\xe19kjK&b,\xfbf\xf5\x99\x18\xcc\xb3\xc0\xf7\xe2\x82e\x11Fv\xaaWYq\xfe\xdf\x1f]b,\x14\x8c\x9c\x91p\x8e\x1a\xe2\x04\xe4K\xdf\xf4ui\x94\xd2@Sl\xcc\xe3\xbc\xbe-*\xc8:\xdd}Q\xfa\x9a\x87\xca\xd3\xd5l>\xf7\x13\xacdFQ\xe2+u\x17\xc2U\x08c\xe1\xea\xda\xae\xe0\xc50\x10\x98 \x0b\xf3R\x9c\x94\x9e\x8e'V~Z\xf5tr;\x15148\xe4\x1a\xf2\xad\x89J\x88\x9fM\xd5\x80\x96{\x1b\xebk\xdf$\xec\x16\x12\xe9\xa7\xee\xc8\xe7\xa6\x9eMT\xa9\x9b\x8c\xa8\xfbH\xec\xbe\x08\xf3\x13\xf4P\xc4\x10\xb5\xaf\x15B\xdb\x95>K\x07 \x0e[8<\xa4n\xe3\xce\x85\xd8k\xbd?\x11\xdc\x02\x1d#\x8e?\x9f\xe0\x10NF3\xcc\xfas2\xf2\xfe\xfd\xdf\xcb\x8d\x85\xafn8>\x9d\x8cn.\xed/\x8f\xe1\x10>\xa1\xc3\xb4\x7fC\xdc|\x9d\xc1!\xdc\xc0\x11|\x86#\xb8\xf5=\x96\x14Y\xccr/\x80!\x1c\x97~\xd9\xf6g\xe8\xd4\x85\xb1&\x84~\x1f\xfb\xef\xc9\xafyoF\x82@\x8e\xf5\xefQ\x1f?\x86C\x98\xf8\xefeT6v\x0b,\x08\x02\x8c\xe5i\x86\xbc\xe2\xd5\xc7\x98\xb3\x13?\\\xf8\xe3\x10N\xe55\xb7\xb8\x93S\xa8\xa0\xdf1\x8c%\x94\"^}\x16\xc24\x08B\xf8\xcc[\xc0\xbc_\xe5\x02\xf1\x1e?\x89X \xbc\xf5s\x19i\xf4\xb8#\x95\xf9T\x05c0\xb4i8\xba\xef\xbf\x87\xadk\x0c>\x8f[}\xeb\\,\x90\x1a\xda \x0e\xed8\x08a=*\xb8\xa8z\xcc\xff:\xe5\x7fMC |\xa49\xfc\xee\x9c\xf6ObNC\\D\xbej\xb7\xbe\x9a\xa6\xe3\xaeS\xc4Y^V\xd5\x91n8*\xcbU\x1d\xc2\x19\xb1U\xe0\x9a\xdeV(\xd8_I\x1f}\xfc\xff\x84O=\xe6S\xbf\n\xe1ntuI\\\xa8\xa2\x03x\xea\xa7\xbd\xf7\xb0\x0di\xefG\xf8\x1d\x08o\xff\xf3\x00\xe9\xef\x1d\x1d\x80e\xc3(\xf7\xfa)\xb0\x95\xf8\xfb\xfb\xa8\xd5\xddJ\xfc\xc7\x83\xc0\x9dQP\xf6\xf5\x04\xb6\x0e\x1d\x829?\x80\x0f\x02\x99\x9f>\x04/\xb2ds\x10\xc9w\x86\xedDL\xf5f\x83\xdc\xc0\xb6^\xe5\\!\xefg:\x07\xdaxLG\xc9|B\xe5\x85\xe1l\xc1^\xe0[9cd\xb0\x8d\x83A\xe0{\xafO\xc7\xef?\x9c]\x9cy\xf7\x0e\xb0\x11\"g\x92\x92\x894\x84\xc2\xd2z\xbdp\xc5M\xc3P\x82\xeb\x00\x12\x0ci\x89z{\x7f\x8d\xb0\xc0\xa8\x902\xc4/\xf1\xe1\xf32 \x0e\xbc\x84\xfcy \xbf\xe3G\xc0(\xdf\xde\xbe\x14f2\xff\x1d\xfb\x0bl\xed\xcb\x97\xaa5\x1a=\xcd\xa8\xe2\x9d\x17hw\x10\xf4T\nb\x1a\xa4\x99\xb8\x8fP\x95d\xd0\xdd\xcdzq\xa1\x01u\x0bb/\xb5\x8d\x0e&\x1d\xa7GN\x06\xd3\xac\x07\x8btj\xe4$\x8a\x08\xcdy\x8ca\xe8F\xf1%\x0c\xe9\x13\xc1\x0en\xaf\x07 \xad\x97\x1e\x19\x91\xef\xab\xc3hX\xffL\x86\x88:\x82\x08\x86T\xe4\xf8\xce\xd0\xdf\xdb#\xa0\x9f\x8d\xbc\xf1x\x92fl\xe7/\xf98\x9fG\x19\x9b\x8e\xc7\xe2\xa8\xf7]e\x87\xf0\xb7\xaf\xad\x1b\xcf\x01\xd2t$r8\xfa\xa9\xd0\x9c\xfe\xedk\xd02\x1f\x17=\xbd\x9fF\x91%\xeb%\xcb\xb8\xf04\x84-\x7f\x00\xdf\x03E\x01\x94\xf7\xb4\xaa\xb7\xeb\xa8w\x9b\xc5\x85\xaa\xb3\xef\xa8\xa3\x14#\xb5\x82o\xba\xd8\xa9Z.\xb7\xef\xfe\xe3\xc0\xdf\xd2\xb5\xd4\xfc\xddA\xe0\xcbh\xbf\xe0\x89?\xbc\xa6$\x1a\xa8g\x1e\x17p\x08\xd2\xa2\xaeT\xca\x8f\xe3\xfa\xcdG\xe8>U\xf8\x98\x98L}/\xda\xb3!Rj\xe0\xc71I\xc5\x12xyXQ\xc6#b\x15%L]<\xe34M\x98\x9d\xe0\x15\x86\x18\xcc\x0d2\x91\x7f\xa0\x9a\xdb\xf6a\x19V\x8f:Feg\x04\xaf,\xfb\x19\xd4\xfb\xd1\x10z\xc3cr0\xa0\x03R=\xde\xbb\xefv++4\x05\xd3\x8fC\x88\xc4y(\x17>\xf5\x0bS&V\x0f\x1e\x05~\xe2(\x15A\xa6]\xd1\xd2\xe4\x98rx\x01}\xe1\xd7\xfeR\xb8V28\x02\xcf+\x85\x00\xbeP1\xb6\xa4\x05/\xcc\x83\x00^\xc0\xe3\xc7\xbb\xcf\x0e\x90\xbd\x83\x97\xf0\xf8`o\xf0L4\xb4\x0d\x03\xe9\xa8\xc9iKd}\xcc+\x88\x06\x0e\xf6v\xb1\xf3\x887\xf0do\x7fO\xf6/\xeacG0\xc44H\xe2m\xbe\x88'\xcc\xcfC\xec\x04s\xd5D\xb0#\x9b\xd9\xe6\xe3\xdc\x91\x83z\xf1\x02\x06\xfd\x00\xb6\xe1\xe0\xf1\xe3\xbd\x83_v\xb7\x9b\xfa\x11\xa9\xab1\xb1G\x86-3\xe9\xbeT\xd5\x98\x1a\x9c\xb5\x0c\xf1a\x9e\xc6RWs@\xebj\x06\x96ng\"\xeb\x9b\x83\x94\xca\x9a'\xffT\xd6\x10\xcf?\x955\xfa\xf3Oe\x0d>\xffT\xd6\xfcSY\xf3Oe\xcd/\xa6\xacqjj\x06duw\x18\xd1\x03\xc7\xdd\xc9\xe3\xbe\x83o\xd3\xc2\xb3w\x12DQ\xfcL\xdb$\xa5\x0d\xf9\xca\xb7Q1\xef-\xa3\xcf6\xcf J\xe2\xa4\xc3 \xe9\x18\xb0d\xb4\x19\xf2\\}8\xe2b4l\x83\n\xc2\x19\xfb\xcc\x88\xc9\x0f\x1b\xac\x8f\x9e\xc8#4\xb2\x96\xc4\xb9\x9e1c%_\xbf\xceOK\xb9/,\xd27\xe9$Z0)\x1b\x95)Qpo\x9c\xcd\xbc^\xbeZ\xc4\x85\xef\x85\xde\x86\xec\xfb\xde\xde\xaf\xa2Dq\x04\xad\xdd\xa5\x95i\xc8o\xe5+6A\xfa}\x8f\x15\x95\xea\xb2H.hk\xca\x14\xcd\x13,\xc2CH\xfd\x16Q\x923?\nF\xf1e \x13\xef\xa4z\x92\xf3\xeeh-b\x17\x87J)h\xddR\n^v\xff\x89 \xab\\nL\x07/{`\xf2\xc4\x13Zs\xc2Y\xd9\x89\xca\xcdl\xb3\xb0\x93^\xce\x8a\xd7\xcb%\x9b\xc6Q\xc1l~u\xd2\x9b,X\x949j\xcc\xb1\xc6[a4\x7f2\x8f\x92\x84\x19~\x867X\xe3U\x9c\xaf\xa2bb\x98},m\xe5\xe55\x11\xca\xe7\xae\xed@CA\x1e\x0ea\x9b\x9fe6I\xe6'\xcf\xb5\x99:\x85\xce\x90\x01\x9a\xe1\xc5\xb5\x93\x9b\x95A\xd2x\x85\x10\n\x9f\xf0 \xa8\xbd1\xa6s\xd5\xcad\xdf\xc9\\ \xc2Q\xa5\xdeV5\"<\x96\xa7(D\xae\x1a\x9b\xac\xa5\xfd\x18]\n\xad\xed\xe09D\xd95n\xed\xbcR\xec&\xcf\x03\x95C\xa3,\x1d%\xdb\xdb\xe6I'\xf7\xcf\xf5h{{y\xd9\xb6\xd0\x02(\x7f\xe5\x0c&_\x87\x9b^\x92\xde\xb6\xb6\x86\xb5\x9c\x0d\xcd\xe1H(\x13|$\x93\xec\x16\xe6A\x8f\xd3\xbd\xdd\x10R\xfcc\xd0K\x93*\xb4\xf9\x95\x08T\x1f\xf9qo\x95\xe6\x85\xdc\x85Hk\x06\x18\xcfi\xd2\x8b\xa6\xd3\xd3\x1b\x96\x14o\xe2\xbc` C\x9aN.\x86\xd6\x00r{\x93^\xbc\xe4=\x9e\xa3\x17P\xceG\xd6<\xb5\x89>\x06<@=/\x04\xefw\xf54\x07\xf6\x88|ON\xc8C\xaejK\x8c\x1c]\xa5\xd2$c\xd1\xf4\x0e\x03\xee\x89p|(]/|O\xf8&a\xaa\x15\xf7\x88\xf2^\xb4Z\xb1d\x8a\xf9\xe8}\xed\xab\xa0g\xb7\xdc\x86\xc3y/c\xcb\xf4\x86\x89\xc6\x90g\x0e\xcb}\xea\xf4\x1c\x80\xa6\xcc\x959+.\xe2%K\xd7\x85\x86\x11\x9c\xe9\xa8\xbe\x0f\xeaF\xb3\xd6\xf7V\xa4Y\xa4\xd5C\x98VM\xe0_]\xb9\x15\xf7`\x1b\x9doh:\x8a\xeaF\x9a\x1f\xbf\x19\x02k'\x9b]\x1cv\xdc]\x13\"\x1f\xc8\xae\xdb:n\x81\xde\xa6\xec\xce\x13:D\xff\xe0I{V3G\x9e\x8f\x0cie\xea\x17vj8\x91\x90\xa8-\xb5q\xdc\x9b\xb9\xb2\xfe\xfa\xfd\x10\x92^\xc6\xf2tq\xc3\x02\x8cl\x8f\xa9\xfc\x96\xb1\x96\xdfjC\xc0X\x10\x10\x80yF+\x01\x91\x0dDg\x86v&\x90\xe2\x00\xe9|\xf3\x98\xc7\x8f\xcb\xc9Z\xdaT\x91wF\xb2x[[\x9c\xc9\xf3>\xb0\xeb\xd3\xcf+\xa4\x8di-%\xe6\x86s\xb6\xf8<\x95\xb0\x81\x9c\xf3\xe3{\xe1\x82ZN?\xed\xc9\xab7\x11\x9aA^\\\x89w\x9cK\xb10>\"\xc2\"F\xd2A\xc0O\xf0\x161\xeb\x9d\xa3C(\x17ac\xb7\x05\x00\x88l\x9e\xb6\nA&\x8c\xf1B\x88\xee\x0d\xc4g\xae\xdb\x84Zf\x97Nr\xa9\xa6\xeb\xc9\xea\xc9\xc57\x1a\xd1\xee\x9eC\xa69\xd8Cyc\x12\x15\xbe'\xf8)O0\x1dB\xc2\xab\x875\x9e\xd5\xeez5\xbe\xf4]\xb4d\xbf\x8e\x9c\xbdk\"\xa2\xdc\x934~Z\xe6\x0fR\x9aylj\xce\x854c\xdd\x9eKaf\xcf\x14Z\x16.@\xbc\x92\x0e\xc8\xba\xe4&\xe0&lS\x8e`\x01- peF$\xcc\x98'\xae\xf9\"\xbf\x90\xda\xb7\xd2\xccL|`\x1eH_\xad\xaedN\xa5\x92\xf4\xa6\xfeV\xd6\x9bii\xfdB`\xa3\xe2\xb2m\xc5\xcc\xe5Jp\xa7\x96\xb1C\x1el;\xa8D\xae\xf8\xc9\xa5\xe0\x8a-~\xa6\x13R\xb9Y\x94\xd2\xdd3\xf1\x1f\xef\x99\x18Ty\xeb\xd4\xfdr\xbat\xd9v\xed\xf4\xec\x80\xde\xa4O\xcc\xf7\xb1c3\x08\xf4\xb6\xac=\xe4\xbd\x93\x95tGS\x94Ey\x1e_;\xd4Q[\xb8\xb5[L\xaa\x944KE\xb4-\x1c\xef9\x92\x9c\xdf-\xaf\xd2\x05\x15[\x06\xb9\xe9\xe8j2e\xb3\xeby\xfc\x97O\x8be\x92\xae\xfe+\xcb\x0b\x8f<)e:\xd1'!dJ\xbf\xe4\x05\xbdY\x9a\x9dF\xad\xd1\x1a\nq\x86\x18\x0e\xadA(,\xc4r\xe1l\x1b\xf0\x0e\xca\xf3I\xdc\x95\x89\xa2\"\x08d\x98L\x0f\x93\xeeVn\x16_\xeb\xcc~\x9b\xd7\\\x84{\x9e\xc3\xdc\x94rC\xa49\x83PFK\x9f\x85\xa8!\x89{\xb3\xe7\x90\xc3KX<\xb7\xf9\xd2\xb2\xe5\x95\x90=\xd7\x9ap\xbc\xe0\xc2q(\x14!\\\xfe\xf3\xa7\xe510\xf1\xa7B\x98\xf1\xa7A\x88\x8a\x90y9\x86\xa5H\xc2u\x03/a\xf9<\x00I&\xa6!\xead\xe6\xa3eiQ\x95\x8cV\xa8S\x1f\xad\x1c2\xb8\x96a\x0d\x86\xdd\xb2J\xb5\xed\x9eA\x9f\xe6\xd7\x06\xa6nI\xec\x9e\xdd\x03j\xf7\xf8\xbc\xe0\x80s\x8f\xfe`\xf7 \xa8\xd9{<\xc5\xd7\x8f\xf7\x1e\x93)\x1a\xd6\xd4\x98\xa1t\xd7\xcc\xd2U\xae\xb9\xfdV)\xd4\x95_o\xc6f\xb9\xcc\xe2\xc7\x7f\n\xafh\x9c\x19\xea\xef5Jc\xf7\x9d\xff\x1d\xfb^\xd4\xdd\xa8\xd7\x9aof\x9c\x7f`\xd1\xa4\xd0\xf3\x10\xf2\xed\xa2W\xc9e>\xfd6\x9e\xb1\x8c\x85e\xe4\x82wg\x89\xc7\xbc\xbe[\x87e\xca\xf8\xa7\x8f\xbd\xa0>\xbf\x9e\x91\xd3\xbf\xbc\xaf\x0ceD\x05\xa2\xae\xcab\xafR\xb7\x85\xe0\xa9)\xd4u\x06\xfa$gi6a\x1f\xed\x00\x01\xe4j\x19\x1d\xfeX}\xab\x04x\xd6qp,\x04O\xeb\xba>\xbeE-\xab\xf1Z\xcfj\x9c\xd7\xf3#\xb3[X\xd4^\x1a)\x97s.\xd3\xe5z\x03ZkA\xfd\xcb8\x7f\xbf\xce\x98\x85\x15[\xfd&\x95AY\xd3r\xe5\xe2\x8di\xa5\xb9\x86\xa8p_\x82\x92\xf8\xcf\x02\x9b\xbc\x18\x0bc\xf5l\xfe\x90\xae\xafa\x861\x0c\xba\xfe\x07\x91\xcb\x13q\xb5k\x1fjk\x10\xf5+X;nb\xee\xbf\x04\n\xe8z\xc2\xb0\x07n\x9aT'\n^\x84\xef.\xf1\x17\xdf\xb8\xf5_\xbe\x97q\xdc\xed1q\xaf\xe4\xa1\xc9\xf0A\x7f\xd0\xdf\xfb\xc5F\x9a\xf8\x8f\xf7\xefm\x9d\x86\xe2\xd6\xd6`C\xd6\x98\x1eP\xed\x82\xf0\xfc\xf4\xe4\xc3\xe9\xc5\xf8\xd5\xd9\xf8\xdd\xd9\xc5\xf8\xfd\xf1\xf9\xf9\xf8\xe2\xa7\xd7\xe7\xe3\xb3\x0f\xe3?\x9d}\x1c\xff\xfc\xfa\xcd\x9b\xf1\x0f\xa7\xe3\x1f_\x7f8}\xf5\x0d\xees\x0f\xe65O\xc1u\xd7\x12\x0f\xa51\xe0\x01\xed\x92\xf7\xd82\xd0\x92v^\x074\xc3\xbd\xfb\xe4q\xdd^\xf4\xc9\xbe\xfe\xbb\x87)\x13=\x91k\xfe\xbcH3\xe65\x98}\xaa\x05\xed]i\xb3\n\xabV\xd2\xe5U\x9c\xb0\x0fl\xba\x9e\xa0\xd7gkKi\xcd\xdb\xa0j\xe9*N\xa6\"\x8c\xd0 \x1fY\xda\xa9\xb1\xd8\xd1X\xb4Z-\xee\xde\xc6\xd3\xe9\x82\xddF\x9d&\x189Z\x9ap2\x9fwia\xbd\xb1\x1b\x85\xe3 Ps\xe8\xd0g\\\x1bs\xd1\xd3o\xcb\x80\xc9|\xb0V\xf46\x8e\x8aFJO\x92.a\xf4\xb3\xda\xad/\xe7\xb1\x11\xf9\xc4\xb5\x98(38m-\x15\xf1\x16\xff\x88:\x9f0\xa5/\xc5BED*\xe5\xd3\xcf+\x8c\xf9\x00\xc5\x9c\x01K\xe6Q2a\x19\x14)\\1\x88\xca\xe9\xf6\xa8\xe8\x8ajq}\x16\x08C\xd9Z\x0d[+A\x8e\xa9h\x1bS&\xb0\xbf}H72\x99/\xa1g\xc6{j\xfb\xf5\x84pM\xe1\xef\xf1\x9e\xda~\xbd\x92\xa7W\xad\xa0D\x88)\xa9\x8e\x9c\xe1\xda\x8a\x1c(\xe2\xfa[X\xc6\x06&\xb0\xe8F\xe7MVS\x8bNM\xdc\xd0L\x8csAX\xd3\x82,\xd4\xe5]\xebj\x80v}M\xa5O\x95s\x98\xfaA\x08\xb32\x9a\x8dU\x0d\xb4\xa94\xda(\x8a\xd4\xdb\x0d\x15@\xea,\xb6\x06!\xef\xd5\x1e\x91\xfe(\xd9}&\xb23\x9f\xd9W\x14\xe63C\xfd\xc4\x84\xf9I\x08\x03\xda\x8a\x0b\xac]A\xbfu\xad\xe4\xd2\xbd\x92[Y/B;\x02k\xe9d\xf08X\xae\xf3\x82/\x19\xc6\xe2\x05!x\xe5=\xf8\x983\x98\xac\xf3\"]\xc2\xb2\xa4\xe8\xa8e\x88\xf2\xbbd\x02\x91\xf8\x9c\\^#-:\xeb\xa1l`\x0d\xe1\xdf\xca!Dw\x98\xb2}\x1e\xdd0\x88\x12(\x83\x1d\x83\x87jiPvG=\xf8\x89W\xb9K\xd7\xb0\x8c\xf3|\xc5\x16\x0b6\x85\x08PD\x89\x92\xe2\xe8\xdf\x1c\xa3Y\x11\x00P\xa7g\xd9\xfdT\x1a\x804\xce\xcd\x1dFs%E\x1bNSr\x7fA\x9a\xc2~\x85Y\x9cD\x8bEc\x1b\x03\xfb3\x9b|\xe8\xf6\x12\x9c\\\xcd\xc4\xd9 \x93\xa6k\x89\xe1\xb7\xb7]\xc8\x7f#3\xb6\x17\xa3\xc4aD\x92\xb6^\x80\x82\xa6\x92\xfb\xce]m\xe9\x0c\xc8\x15\xf7^\xbf{}Q\xff\x94V\"\xadI\xc3L\xb5hd\xec\xf1|}\x95O\xb2\xf8\x8a\x91\x11\x96\xafKq\x87\n\xf5\"\xe4'\x89$m\x92\x1f\xdc\x9bp\xf2\x93,a\x9f\x8b\x0f]O3\xf5H\x1d\x0f\x05Y\xf58!\xac\x1e*Th})BX\x8f\xd2^\xd4j?sS\xf9)\x11I\xacu+Fz\xb8\xdaJ\xb5C\x1a\x14\xb4 5\x91\x0e\xeb\x8b\xbb\x15\xa3\xe0\x9d^\xc9t\x89\x12\xd8\x8a\xec!\xac\x9d=\x96\xe4\xb6\xddJ\x9f\x95\xf6\xd4\xe2/\x7fn\x9e\xeb\xfaC\x93~@)\xa2\xe1pQ\xa2Ma9\xc3\xeaO\xa3\x0d\x82z\xd6\x89\x06\x7f;l\x90z\xba\x9cQ\xf8&\xe8\x843P\x0d\xcf\xf2&\x01\x81|\xcc\xc2\xc6\xf2\x05\x11)\x87\x0b]\xb4K\xecc\xeb\x0e0&Q\x91\xef\x94!x\xff\xfe\xef\x9c\xb9\xfc\xfc\x88\xff\xac\x07\x93\xff\x06\x89Z\x17\xf1\x1d~i\xd6\x9d\x8d\x14E\x1f\x9bWB\\\x1a(o\xc7\x84\xd8|I\x84\xc2Qfk.\x9f\x87\x9cp\xfa\xad\xd7\x10\x1eh\xa5Mo\xad\x8c\x1f;\xb9a\xb3X\xaf!\x92\xb9\xe2\xb5\x81\xe8\xa6v\xc1\x1c5\xea4\x90{\x89\x91{\x01\xcc\xd7\x8a\x7fm\xa1hS*\xdal^\xbc\xc0\x1b\x93\xc8b\xcbxs\xa8$\xe6\x1cIQ5\xd1\xb7\x9bH\x90\x1d\x17\x8e\x07a\xcd:\xda\xb3mY\xc8\xa3\xca-\xd7%\xba+2\xbe\x91\xf0I\x02^uV\xa1\xf7\x83 \xda\xe3~\xd0\x8bzB\xa3e\x82~cm\xd5\xa6\xf5\x9dkm.u\xc9\xcc0\xf2.\xacP\x97\xc7x_\xa6q9exIq\x19\xa8Y\x83^\xda\x8b/xQ\xc5\x18\x95\x08\xd0|\xda\xd0\xac\x8d\xdd\xf8\x80n\xbc\x18\xf5/I\x04)zBz\xf5k\xb0l\x18AWB\xca\xfc\xa2\x87j\x18\xc9\x80\x87\x15T\x88\x13\xc88\xec\x1fDq\xf8`J\xbc\x10\n\x15\x00\xb9\x8b\xf2S\\\x10\xd5(\xb7&}\xc0\x11xq\x12\x17q\xb4\x107P\n,*\xabr\x91\x82\xae\x9b\x83!\xa6\x1c\xbf\x89\xd3u.\xd3)gl\xc2\xe2\x1b6\x85\xab;]\xffP\x8b\xec\xaakM\xcb\xd1w\x81e\xb5g\x9f8\x9cQ-\xdb{y\xb1i\x1e\x19\xca\x84\x9frG\x1d\xc0#\xd3\x98]\xb8Q\x1cA=b\x02\xe5\x90\x86r\x0d\x1cA^\x1e\x07e\xc5j\xf5)}5GJ\x8a\xba\x13y\x06\n\x97Q \xaf\x1f\xfb5\xcb\x95\x82KXh\xc3kW\x8d\xf4\xaa\x0bL\xee!\xe8y\xc0\x17\xd6\xa3i~A4\xa6\x08z_\x18\x9fp\x1c\xe3@,\xf8\xaf\x9d5\xc7\xaa\x9d>G\x96d\xb3\xadS\xed{\xa7\xbd\x9c\x96\x0f\xa8\x84\x0e\x9e>\xe2\x08\x92\xb6t\x87\xa5G\x1f\xbe\xae\x0f^_\x0cm\x80Ay\xb6%\xfe\x9e2\xf0\xde\xdc\xfc\xb6\xcd\xbcag l\xbf\xe5\xa9\x8b\xb6\xf4}\x18j\xb1\x01\xd2\x92\xb0g\xc1s\xd8\xde\xe64={\x1e@*\xe8y\xe1\xb3Qr\x89\xcaT\x87\x1dh\xba\x19\xd4\xb5\x83\xf1\xc9A\xe0{E\xfaq\xb5b\xd9I\x943\x97\x15'}Hv\x02\x0eqA\xaf\x06\xb0C\xd8\x1c\x8bh\x97\x94\xaf\x7f\x81>_\"%\xc6!\xec\x14\xf0\x12R \xcb\x14\xb6\xd1h\x0b]\x81\x12Y\x90r|\x0c\xca\x8f\x12\xd8>\x844\x10\xe0\xe6\x1f'\xf2\xe3\x04v\xf8\xef\x97/1v7\xff\xe3\xd0\xcczU.h\\.U\x8aK\x95\xc1\x0bH\x9f\x07\x10\x8f2\xb4\xa5\x19e|$\xf4a\x17\xb7\xac\x92\xb9D|.\xc2\xc2\xd5\xf7F\x7f\xfe\xf3z\xb7\xdf\x9f\xfe\xf9\xcf\xeb\xe9\xd3~\x7f\x87\xff?\x9b\xcd\xfe\xfc\xe7u\x7fO\xfc\xec\xef\x1d\xf0\x9f3\xb6\x8b?glw\x86\xdfL\xf1\xe7n\x7f&J\xfbL\xfc7\xbb\xdc\xdc`W\xce#\xe9\x15,/\xdaM\xcf\xbabG\x08\x19\x85 \xa9\x03A\xe2\x86\xbdD\xac\x1a\xdee\xc6\x12\x03\xf8\nmo\xa7\x97\xb8v)\xbc\x80\xf8y h\x9e\xcfw\xd7(\xbdD\x0f0\xc76\xdb\x90\xb8U\xdbl\xf0\x9420\xae\x84\xf1J\xcdA\xc6\xd7\x8fI\"\xe3\xd6\xb3\xa0\xe1\x9a4\x04)\x9c\xf6\"\x05\xad\"H\x89[\x83\xa4M\x84US-\x99,ZQ-v\xde\x11(\xdeLXldhx5\xea\x13\xa6\xcf\xa0\xd6[\x04*\xb7\xc5{<\x0f\xb9\xec\xe5\xa7\xd5A\x17c\x1eHs\" \xc7)r`\xd7\x07`\xd7,q]e\x00\x88{9o\x14/\xb4\xbe|A'\xc1\xdaG_i\x94)\xbfO\xd8\xad\x1f\xf7N\xf0\x17\x97\xe38\x0bo\xe0\x13\x7fT\x15\xcc\x8e\xa0\xef\x9ax3\x94\xb3ng\x05\xfbd\x19\xf5\xc6\xba\x04}\x9c\xdf%\x13%,\x9b\x82tM\xd6vUZ\xeb\x95~\xcf\x12\x116\xc0U;\xd7k\xbf\xcf\xd2\xcfw\x97\x8e\xab\xf7\x16\xf9\x18\xad\xff\xdb\xc4\xe1\xcc\xe5F\x81\\\x0c:\x95\xe2_\xeb\xf2\xaf\xb8\xfc\xab\xcd\xc8\x86\xa2\xdd\xb6\xd6\xa1\xc52\xb8y\x92\xa5i\x17\xb5\x01\xdd\xeax\x0d\x11m\xff'\xfe\xb4d\x86jmY\xf8\x8fm\xd2\xecWj\x11\xf4\xd4\x10\x1b\xa2\xfa\xa0\x1f\xf8\x89\x7f\xb0\xff$\xd8\x88{ih\xd0\xdc%b\xf3\xec?i92\xcbKo\x19\xfa\xc8q\x80\nv\x15\xad\x0c\x95.\x06\x8a\x92h\xab\xa2-\xe53\xb4\x95\xfa\x89\xf0kV\xf4\x1c#\x02&h\xae\xaa\xf7\xc7x\x97m\xa7r\xc3\xacim\xdc\xee3\xda0\xe4\xc0\xca2\x14\xa1\xb1n\xed\x15\xa7\x07\xbbm\xd8\xae\xd8\x80<\x84E\x08\x13\x8a\x19@g\x02\xf8\x9e\x0c \xaf1\x8cv\xa9\xc8\xa8Dq\x07x\x1f\xc6\x019E \xfb3@\x1f\xdd\x97\xb0j&%\xc2\x8f\x9a\x9f0\x94nm\xce[\x11\xc5\x9a\xe85\xc7%\xb6\xdb\xbaq\xf08Kq\x87f\xbd\xbf\x96`\xe0\x12\x17?\xb63B\xf4\x04\xc5\xf9\xa0\xbb\xb8\xa0N\"!k!dE\xce\xfb\xdc\xc0\x0bX=w\x1d\xe5\x98\xa7\x96\x8c\xef\x02\xd2)\xba\x18\xdd\x10we\x1c\x00y\x80M\x8c\xf9\ns)\xd9\xbf\n\xe1\x0eC\x1d\x15\x88\xa1\x13\xcc\xca\xe8\x8b8F7\"\x9d\x13\x7fK\xb7\xa6\x99r\x8c]*\x1f^o\x1c`\xea\x9a8Y;\x92\x0c.\x0d\xcb:\xfd\xb9\xcaX\xf4\xc9*\xb1I!:\xa77\x8db\x0b\xa5\xf1V]V\xed\x93\xd8\xbf\xc6j\x9cA\xbd\x13\x9a\x1a\xbe\xfb\x17\xd2\xcdTl\x8bIP\xe1\xd2\xb50\x06p&\xbdl\xea\xb1 \n\xe0\x84\x04\x90\xd0\xf8*\xe2\xa7\xc4\x18+\x86/\xd0\x15\xee\xa3\x85\\\xdar\xe0\x8e\xe1|\xeb\x82\x90\x87\xc8\xa4'<\xcaQCZ\xfe(\xeaN\xe9\xf8\xd7\xbd\x84\x95o\x92\xf35\xc9\x9e\xc4\xac\x9a\x98\xefT\xcc\x97\x84\xa9e>N2\xbf\xf7$\xe8}\x8c\x93\xe2)\x8a\xb1\x0fr^\xee>\xa3B\x80r\xb1\x87\xbe\xc79\xd8\xbf\xaf\xe8)\xe2\xa5~\x93/\xddSz\xac\xbb\xedcr\xeb2b\xa1\xa5q(g\xf8l\x8e0\xf4_\xe6\xc7!$\x1dp\xa4D8x\xfc8\xf03\xc7\xd6M7\xebc\xd0\xa7\xa3RqN\xcd\xbf\n!'&v\x0d\x870\xf2X\x96\xa5\x99\x17\x827Y\x08\x7f5o\xca\xf2\"K\xef0\xb0N\xb4\x16\xef2\x96\xaf\x97\xcc\xbbt\xb9\x08\xdd9\x11&\x06y\x1b\xc3a\x88\xde\xe0ROf\xce\x154\x1aU\xe8F\x86\xb1]\x0f\xbd\xc9\xc5\xed\xd3\xdbt\xca\x9b\xdc\xdab\xda\x0b\x19Z\xd9\xb7\xeb\x99o\xbe|\xc1O3\xb9\x7f\xce\xca\x12\xc7\x1d\xa40r\x98\xc7\xd7\xf3\x9f\xa3\x82eo\xa3\xec\x93\xbd& id\xd5\xeeO\xed\x1f\xac\x89\xd1\x1d\xc1\xe0\x00\x8608\xd8{\xba\xef\x80Bm(\xfc,\xe0S\x12'\xa42\xa5\x10\xb0\x88\xaa\x82(\x90\xd9c\xd6!\xdd\x08\xc6\xfb\x9d-\xd24\xf3\xedr\x15\x96@\x08\x8a \\\xeeo\xca\x84\xed\x18\xe4R\xcb\xd8\x1e\x8b<\xe9\x9c\x8f\xd5_\x9d\xa4k\xf4\xa5W\xf5f\x8b\xf4V\xa4\x1a\xd7j\xb2D\xa4\xc8/\xf3\xb5\xb3d*\xe8W\xed-\x87\xb2\xf8\xb6|\x85.>\xc2\x9d\x05\x7f'\x8cM\x15\x91\xac5(Z\xa3\x8a\xd4\xda\x89 \x8aF\xfbbC\x9cO\xe6l\xba^\xd4G#\xf7\x8f\xf9\x12-\xe9N\x93I*\x87\xca\xacw\\\xae^\x17\xb3\xa7*\xe3|t\x1b\xc5\xc5\xab,\x8a\x13\x0dNr\xaeo\xd3\x8c\xd5\xdb\x9f\xa4S\x96\x99\xe0+{\x13oY\xf5\x8a\xa3\xc4\x1c/\xb2\xe6\x92\x82<\x0bzBE\xf1J\xb4\x15\xd8M\xb3[\x98\xfbU#\x81\xdd\x8fVX\xc3W\x97\xe7\xd7\x95\xdb\xf3\xcb\xa4\x1c[\x88\x8b:e\xb8\xaa8\x08>\xb4+\xd2\x95\x0dG8\xce\x8c\x03\x92\xd7\x17DK\x04\xa9\xa8\xad\xb8\n\xf1 \x14\"4\x03\xcc\xebV4\x06\xdb/w|\x10\xba\xd8f\x89\x1b\xda\x87\xea\xcdaU\x1a`\x14\nW\xdcx\x07 \xc7\xd5m\\\x16B\xeab\xe9%\x17\xc1\x0c\x88\xd8`\xabL\xcd\xe1\x08\xfc\xc8\xd8c\x9d\xf8\x04\xd4\x8d\x8b=\xac\xd6\xc9\xee\xa7\xaa(\xf1\xcc\xd5\x1ah\x9c{Y\x99\xb7\xde\xe4b\"\x94\x01\x8a*!\xd4%\xddRy\xd3\xc2*\xb1\xd06o\xb8N}aX\xb1\x91d'\xf6\xed\n\xa0\xb9xI\xb9\xfa!\x9c\x93\x97\xf7\x1ct\x11\x86.\xf2\x91f#\xbew\x82+B\x81\x9es&\xa2\xe4,zq.\xd8'?\x13\xce\x07\xfa\xb6A\xcd%e\xbb\nztn\xa5*1NKa\xa8W\xf7Mz\x9d\xdcD\x8bx\nI\x9a\xec\x88f\x1f\xc9\xc3a2_'\x9f<39\x9dz\xf0\xb8wLDnk\x02n\x11F\xb0\n!F\xe1\x93\x13p\xbf\xe4bb\xcc\xc7c\x0cY\x1a\x9c\x96\xf1\x97\xfb\x1c\xa3]\xf37?&\x93\xc5qi\x16\xb3\x0bi6\xc7\x1c6\xcdv\xde\xc6\xdc\x16\xbdY\x96.i\xdc\xc0 f\xfc\x94\xd6\x8f<{\xbe\x9aC\x9e\xe0({\xeb$\x9f\xc7\xb3\xc2\x0f \x9a\x15,\x03\x96L\x81\xdd`\xf0\x8f\x00s80\xb48\x10!\xfa\x10X\x02U\xbb\xb4\x8d[F5|z\xf6\xa3h\xd2\"\x0eQyd`nK\x0em\x8c\x0bXn\xda\xdb,\x96\x97{&\xb4\xa5\x8e\xaeJ\xf5\xa5\x8fw\xc0{\xfbT\xed\x9bz\x99\x0ci\x8c\xe9\x9ej\x03\xa2\xb0\xcfT,\xb6\xad\xd5\x16\x93`\xe2$\x84\xd5\xb9 \xdc$r\xc0/L\xe6\xb0b\xba\x98\x93\x8e|\xf5\xcd\xf8\xe3\x0e\x1a\x7f\xab\xd1xj\xc0E\xc9E}\xff=\xd4\xddEp)\n\xc1\x16\x1d\xf1)\x88\xb5\x9eFE\xc4\x97\x1ac s\xa0\xf9}\xb1\xa6\x1d\x89\xa2@\xd2\x92\xa6*\xe4Kx\x1b\x14\xa5\xad\x01\xee\xfb\xef\x914\x06\xa1XT3\x10d\xed\x17\xed\x94q\xa5\x87q\xf2J\xc6\xeb\xdb\x93\x9f\xea\nc\x82\x7fP\x01\xad\xea\xaf+\xce\xcf^bB\n\xae\x8d\xc7\x89\x80\x8e\xee\xfd\xc6\xfe\xf9 \xdf\xee,\x13\x82\x06\xbf^\xc5\x88,\xd5\xdf\xf5\n\xe3u\xa2\xd7)\x7f\x19\xb5\xaa:\xad\x87\x99\x90\x06\x10;\xd6\x8b\x05G\x10+\xccw\xbdq^\xb7K\xc37\"EE\x06\xe4\xf29\xc9AVG\xf4\x04\xcfoC{Th1\xdb|\xa4kxld&7/r\x15eu\x86\x9b\xa1;\xa1 \xfb\xc2\xba\x07U\xac\x9e\xf4\n\xc3\xa0\xa9\xe3*\x1c\x1a\x126;\xfcH\x1d&r\xcf\xb5\x9e\xe4\x97/_\xc2\xa0\xf6k\xb7\xf6k\xbf\xf6\xebi\xfd\xbb\x83\x10\xd8\xf6v`:]\x83\xe0\xb6\x03T>\xbd\xa8q\x17\x0c\xe7\xab\xa0\xa9\xcf\xbc\xb04\x06\xfd\x10\xfa\x1dc\xdb\x9c\xd3PPW*\xed\xc2\x97\xdd;\x97\xf3-e\x05\xc7\xfa\xa9\xef\xf1\xd7\xea\x9d\x17V\x8b\x1eP\xdfH\x9d\x88\xe2\x04\xd2*\xf5\xc6 \xba\xa3\x0d\xe1\xa4f\xe6\x02\x0d\xf3<\xa1\xe7)\x87\x04j\x92\x9e\xc8\xb0\x80\x0c\x87\xfe\xee\xc2N\xea@\xf7\xf3\xc9}\x82\xd4\xf4!\xc8\x82\x9b\x1a\x92~\xa8O\xf2X\x10\xd6\x8e\x13\xbb\xca!\x864\"\x01\x0bXV\x9c\x16\x17\x10\xce\x9c\xab\\\xeaK8x\x8bx\xf2\x89\x1ag\xa7>\xde\xb7\xaf\xb0\xc2v\xa1y\xa3zB|w(\xe6,eZ\x85\x90\xa8\xd9\x96\xe8\x18\x82\xb9d\xdarn6\xa5\x8bo%\x02\x88bS\xdf\xe3\xe3\xa9m\xeb\xe7\xf5AJ\x0b\x01\xa5|\xf2\x83\xe7\x86\xc0\xe3\x1a\xe1\xdb\xb6C\xc88z\x8eDWH\x1d-F\xa9{\xaf\xe3\x98\xdeu\x13I\xfaB\xfbU\xb9\xb0\x08\x07\x16\x0c7D\xe2\x15_$\x91\x93\xa4\x16^\x8a\xb8g\x92%;\xa6\xf4\xa0\xff\xd2\x15:\x99\xd8\x93\xcd\x1a\x02)Mx\xe2\xecd\x9a\x91$\x9f\xef\xc0\xb4\x95\x02\x0d\x01 \xa5\x0dM 1\x8a\x00\x8d\x9er\xfd\xa4r\x832\n(\xa9\x9b\xd0\xfeZ\x9al\x0d\xc3\x0f-\x99\xee\xcb\x17\xa5f\xa8n\xac\xe5\x8c\x87`\x89\xef\xa2\x9d\xb0\xfc$l\xd4\x01\xbd\x16\x97\xc40\x84s\x95q\x81\x13D\xd7<%\x81>T*\xa8@k-p0\xfe\xdf\x7f\xafzq\xb5\x8d|\xb2\x0c\xd0Q\x03\x8d\x13}\xa6\xbe\xc7\xebUJ\x82\x10C|\x18Q\xae\x04\xe4\xaa\x93\xc6\x96\x97q\xfcS\xe5\xf6\x00\x0b\x96\xe7P\xcc\xa3\x04ny\x8de\x94}\xf2\xc4\xb8P\xb9\xaa\xc0\x86\xcd*\xd1\xeeH\xad\x05\xff\x91\xe2\x95\x19\xde!\xa4b\xe1\x91\xbf\x93R\xf94\xc5\x01{A\xa8}_S\xa9HM\x91\x05@J\xa3T\xd38\x9aJ\xb5@or\x10\x1a\x82\xb0X\xc1\x04WP\xae\x8aX\xdaL\x1e\xf1}8*\x05\xbc\xa1<\"\x8f\x1cz-\xfe\x7f?\xd0u\x7f;\xa8\xec$gQ\x02\xd01\xa3\xa4\xdaJ\x9a\xc2C\xe2\x8f\x1a*\xea\xc6\xcbk\x94\xda]\x14?\xb0\xea\xa7\x9b\xa1 \x1ew\"(Z\xc3\xc4\x85\xa6\x80x\x00q\x8e\x81s\xe3\xe5JdH`6\x1d6n b\xcc2\xd2\xca\x8c\x96\x82\xd6\xf7B\xb8#\x8b\xa7Y\x14'^\x083\xb2T\xed\xcf%Y*g\x17\xc2\"\x109S\x8d\x8f\x13N\xaa'\x0deWd\x99\xa467AX\xc6\xbd\xde\x8au-!^\xeb\x8fo\xb3\xb8\xa8]\xbcn\x99/\x91\x08\x96\x9f\xcc\xa88\xb9_\x1b\xd6w\xe2\xbc\x8a\xc6\xb5E\xceP\x18\xeeM;\xc5\xb2\x8e\xeb\x06#\x1a\xef\x8b\x04\xf2\x8c\xab\x8cQ9^\\X\x17\"\xea!|\xeb\xc9X\xc6\x02\xc6\xd5.\xa0A\xac\xb20Pes 24\x00\xd4\xb2!8O\x05\xc4$1\xc1P\xb6\x14*j\xc5Jk\x1c\x8e\xbeBt\x91\xd1@k\xe4\x12\x1d&%qW\xa1\x0ej\x15^\xc2\x80W\xda\x11\xcd\xbe\xf3+\xfa/x\xcc\xad\x95b\xa2f\xd1\"g\x80\xddB\xc6\xf2U\x9a\xe4,\x04ek\x9e\x98\x17\xb0\xb5%n(\xdd\xde\x96\x93\xeb\x8bl\xca\xbc\xbdMw\xe3\xb2\x05\x88\x8aT\x15A\x08W~+5\x13\x08'\x10L\xbc\x17\xe7\x82\xc1\x98\x10\x11!\x9a\x06y\xed\xdcV-\x84\xf9\x8a\xa4 \xee\x8e\xee\x9ai\x93l\xbb\xf5\xb8\xd8\xb4\xdb\xab\xa6n\xab\xc3.\xe9\x89\xbf\xbb\x9d\xfdJ\x9e\x15;\xb1$\xfed7]o\x07\x00\xac`n\xba\xb1\xef*c+\x96L\x15P*/=\xb3D\xe4\x98iP\xa1\xf7\xc6h\xc2\x97\x0b\xe4\x91?F\xc5%\x1cA\xe4\xeb/\x02\xb4\xe3\xab~\xd7-\xb2j\x9f\x1e\xc2( k\xaf.\xb1\x8a\xf0\\J\x1c\x04OCeu`\x8b\x03\xa5\xce\x1f\x88w\x06W \x90^\x9e3|3\xc7%\xa1\x95w{\xc8\x8aU7r\x89\xbc\xcd\xf3\x03\xebR\xdf2\x82\xb1\x18\xf3&\x9d\xd5F*\x03\xf7\xdaWL\xd4\x90Jz\xc1\x1f\xc2\xc9%\xd6b9\xeb\x1c\xbdR\x11\xce\xe3\x9c\xfeh\xe0\xfe\x88U\xcc\xa5,\x87#lIXq(\x89Q\x96\xe1Qi8f\xd8^\x19\xfa)8\x90\xd6\xf0j\x11KvA\x18\x13%R\x92%p\x18\x9d\xfd\x9c\xfcB\xe9\xf0#\x0f\x0b'\xa8S\xa8\xcf\x9c\xde,\x9b\xce\x8an\xa5\x163\xb4\xff\x1cb\x0c\x15\n\xf1\xf6v\x00\xd9(\xbet\xc1\xa0Qak\x19\x0e\x01I\xa6nd\x9c\xc3w~Q\x9d\x9f\x0d:8D\x89H[l\xf9\x99\xca\xd9\x13\x850\x08\x0c@\xec\xa0\xe4cc\x93d~\x14\x08\xe5_\xa3\xfe\xa5\xb6{]\x0b\xdf\xb49S\xeb\xc6\xb5Ib\xcek_Vn\x10\xd2p\x83\xc60A\xd1\x05g\x12\x94\x82\x98\xdb\x00\xadT=(\x02C\xf0l*FRe\xb3\xa2\xdao\xc1\xe5.B=\xe0]Q]\x89\x9c\x11.G|\xe7R\xef\xc5\x85\x88\xa5\xc9\xc9\x1c\x0eM\x99\xa6\xec\xca4}\xcey\xa9<\xd4\x04\x853\xb9\xa6\x9b\x1c\xabM\xeb\x1fM\xcb\x93\x0e\x0e\x0d\xcc\x08\x0dU1\xdav\xb4\x98\x19\xde\xc8@\xfb\x9d\x00]\x9e\xb9\xc6QS\x9d2\xcc`\xf7[1\x15\xa4YJ\xdd\xd0D\x19\x1fY\xe6'\xf5\x1b\x88\xf7\xa4\x01\x12\xe0\xd9*\xd1<\x08(;CC\x0f\xc5\xb9\xdb6@U\xaaV\xbe\x8b\x04\x87\x0dr\xb2B\xc7\xd1\xb0E\x82\xb0\xe3>\xc2\x83\x1b\x99w\x87\x05e\xfd\x1c\xd1\x14s\xf2\xab\x0e\xd3\xbd\xcd\xa2\xd5F\xa7\xbb\xfb8\xef|\xf6g\x8e#\xa2<\x1eR\x8c\xc7\x83\x0c\xa5\x10\xa7[\xc5^NN\xa6\xbe\xc7g\xb3bS\x90\xc2}R\xf7\x97P\xba\xf8f\xc9\x99 \xcb\x87nnP\xf2\xec\xd6\xaf\x0f\\Z3p^c\x16\x9a\xa9\xb6\x8d\xbc\xa5&A\xf2\xd6%,HW4\xfe\xe8\x90P\xc2i\x0d\x14~Z\x9b\xa3\x90SS\x8e.[\x89\xe17R*\x95QS\xafY\xef\xa7B\xa4\xf7\xcd\x0f\xb0\x9e\xb2JQb?\xce/\x0d\x04\xd1U\xba\xf1R\x90\xa4\xb6l\x806\x93\xba\xcf\xd4<\xceG\xe9%\xd4c7kR\x81,\xf4UE\x0d\xa9\xdb\x1c\xee[\xd1K\xab\xcb8\xf3/B%3=\x85F\xc7\xf5\xfe\xca\xe1\xdc\x80\xfa\x1agt]^1\"\x83\x84Hp=\x8a/\xb5\x9d\xde\xbb\x8a\x93\xa9\xa4n\xbc\xa8\xc1#\xa7\xd0\xbd)\xdb!\xa3\xa1\xd0X\xde\x1f\x16\x81\xf2\xfe\xce\x14\xe7Z\x89\x11\xf6Di\xda\xd3\xc5\xddD\x91\x90\x9ao7\xe9z\xc2\x92\xf5\x92e\xbc.\x97\x13lj\xb3\x91k\nEak\x17G\xf6\x1c\xeb\xb3C\xbf\x8f\xf1,K\x97\xfcT\x86Cx\xfb]UV\xcf\xac\x10b\n\x1eG\x82\x05C0\xae\xe5j\xb0\xe3Mti\xa2-\x1b\x90\x88\x99Q\x16\x94\n\x83\x94<\xaa\x1b\xb4,_\xc9Q\xd7?\x97~,\x1d\x0c\x8f\xee}\xd7\x03m~D\xee\xd0\x02\xe23K;M\xbc\xaeZsn:\xf4\xb2\x8e\x84\x9f\xde\x11:\xe1\x94\xd6\x9b\x1b\xf4\x83p\xae\xb1\xb3%\xd3\x93*yA9Y\x08s\x9d{\xba6i\x17\xa7\xd6\xc0\xfcF\x08\xd4?\x96\xaf\xfd\xf2\x04 ;h\xb8\xb7\xe4=\xce\x11\xe7\xcb\xf5 &bv 5(\xf3e\x1dV8(\xbc~E\xd0\x92\xfa,\x87\x9cU\xfbYzd\xb5\x10\x93{\xc3}@\xf3w\x99\x1d~\xc1\xf2\xa1\x996\xb6`\x84u\xf8\x96\xe5\x1d\x90\xdf\x12#\xb0\xca\xcd)\xd4+\x08]Vs\x1b\xc6\xa2\x9aNU\x06\xf9\xe9\x9ca\x87\x0c\xc8\x96\x95\xa1g\xaa\xfbvDd\xafL>\xabG\xcf\xca\xd9B\x04\xb5\xe4\xff\x7f\xf9\x02\xb7q2Mom\xfa\x92\xd2\xe1\xef\x91\x93p93\xd1Y.\xa0\xc4\xb4xZ\xf9N\xf5\xc6h\x89\xfd#\xd2K\x07x\xf0\xcb^\xce\x8a\x8bx\xc9\xd2u\xd1Q\xccI\xd8-\xc4~*N\xb0\xeak\x8c\x87P1@!\xe0\x00d\xa1\xa5\xb7\xc0~_'\x05\xcbn\xa2\xc5=;V\x9f\xd3=\xabR\xa2k}d\xa8\x80\xa9}\xd0*\xffH.\x1f5\xb1\xbe\xd5|\\S\x97fl\x86\xb6\x91\xba\xec=3\xe6k|\x84\xed\xb6\x81\xa4\xb6\xc6\x02\"YX\xe2\x011g\x96d\xe9b\xd1EA\xa4C\xc7g\xbc\xb9\x05\x93?_OQ\xfc\xd0_\xd9\xf8\xc5{['D\x7f\x0f\xd2\x99i\x0e\xc7{\x1b#\x9c\x8f'E|#\xb4\xaf\x91\xfa\xf3[:\xa7/\x08\xe5M\xaaV\xd5\xaeW\xc0\xcbC\x99S\xc9l\x15\x0e\xa1\xda2~+/\xcaz\xe34Q\x93\x17\x97\x12\xe5o\xea\xb6\x87p\xb9\n1\xa4\xd5n\xa0\xf6\xdcr\xc9\xa6\xb1\x08\xce\xd2N\xc2\xea_Ta+*Rh\xd5\xe08X\xb2.za\xb9\xf36\x1c\x82\xf1\x0d9\x08\xbbNm\x18\xf5\xe2\xea|\xe8\x94\xe0lc\xe6\xd9\x11S-Eeb\x9c\xebq\x88\x9a\xf1SY$\xe1\x9d\x82\xe7\xc16\x17\x82q\xbeE\xfa&\xbd\x15 \xc9|\xa7\xfd7\x1a\x11ys\xf6\xd9\xa3\x8d{D9FBj\xa9\xb0\xd3\\#\xca'q\xdcX\xe3*N\xa2\xec\xae\xb9J\x94\xb3\x83\xfd\xe6\x91L\xf2\xdd\xb6\n;-5\x8a\xd9\xe0`\xc1\xda\xea\xec\xb4V\xca\xa2[G9h\x1e\xda\xfd{\xda\\\x95\x1e\xde\xf6\x16\xaf\xefnG6,\x8a\x931\x08\x95B.\xdc \xac\xab'\xb8\"\x81\xed\x0c\xbc\xba\x90\x92S\x11x\xd6r\x11T<\x7f\x1e\x94\x03s\xb6\x0c]p\x17:\xe1\xafz:\x0c\x12\xba\xa0!tBE\xe8\x88\x8e\xd0\x15%\xd5\xa3M\x03k\xb7\xcdd\x11\x15q2h\xed\xbdq\xf7\xaaG\xf5-\xdbl\xeb\xbaq\xbbC'\xd2\x02\x1dh\x9cz\x94\xba\xae\xc1\xe8\xa9mO\x82r\xb1h\x0e\xb2\xa5\x1eN\xb3}I\xb4\xeb\xf4ZD\xa3\xd0R\xd8\xea\x0f\xa5#\xa4n&\x1d\xd1{\xc5\xe5b\xed\x989<\x94\xd1\nE\x120\xdb+\xc4\xfb\x98|J\xd2\xdb\x04\x14\x15\x18\x82\x18\xb6[{\x88V{uJT\x05v(#\xd3Q,W\x07\xb4\xc7F\n\xf6\x99C)/\xdb\xe4\xac\xd3B\x80\x8e\x88\xd1\x08n#\xd7VR\x81\x1d\xcc\xe2\xc5\xe2M\x84z\xba\xf5\xfd{i\xc4j}^\x93\xda\xbcf\xa2\xc7\xbd\x8dzlDX]\x89),\xc0\x0ea\x15\"\xe7\xe4k\x1d\x9b\x92B\xed\x17\xd6[Dy\xf1\x8e\xa1\xa0\xadB#\xf2W\x17i\x81\x92\x92\xfe\xeed\x1e \x9f:\xdd\x1f\xb0\xa6\x0d,\xff,\xcf\xaa\xc8&\xf3\xa5\xa9\xc5\x8bC\x18\xec>QIb\xe0\xe5Kx\x0c\x87\x87p #B\xe3\x9b}\xfef\xb0\x0fG\xb0\xa7^\xed\xf1W{}8\x82}\xf5\xea\x80\xbf\xda\x85#\xd8\x19\xc0\x10vv\x1b\x87\xb4v\x1c\x9fJ\x1bXM\x7f\xa7\x0e\"[\xca\xdf\xc4\x05\x1a-Ov\x9f\xf2\xbd\xec\x0f\x9e\xed\xc2\xf7\x98\x14<\xd0\xac\x99\xeaK\xe1\xfd\xdf\xff\xd7\xff\xe9\xa0\xb2\xe8cTU\x97\x16\x83\x9ak\xd8\xa0\xe9h\xa5\x062p\x0dd\xd08\x10\xa0\x06\xb3k\x0c\x06\x7f\x9b\x1d\xee\xba:\xdc\x95\x1dv&\x9e\x85T\x88>\xa7\x90L\x93$\x12t\xb0\x1f\x1aX\xffB\xf36\xc3x^\xe8\x97YCy\\V}\x1f\xf0\x0f\x03c_\x94\x89\x0d\xeb\xfcVho*\x11\x17\xac\xa9\xa32\xc2\x99\xbe\x9f\xcb\x11\xefh!\xd0\x9a\xf7^N\xaa\x00\xf8z\x95\xd9T8\x8a\x07\xf0\xaf\xb0\xcb7P\xbfI)_\xa5n\xf4K\xf2\xee\xb6#i\x0e\x04\x80\xd7\x91\x93y\x94\x9d\xa4Sv\\\xf8\x9a\x0f\xac\x199Z=\x18b\x9f\x8b\xdd\x8f\x1f\xef>;\x004\xcc\x7fq\x08\x8f\x0f\xf6\x06\xcfj&_\x06.Y\x04m\xdfX\xb8Q_\xa4-\xd6 \xb2{i\xd6\x19Xu\x06\x97!$\x95\xa3\xfa\xce\xe0\xfeF\x1e\x14\xde\x9a3\x19\x103\xd9m\x9f \x1f\xa5c\xe1*4C\xa87\"\xd2\xc2M1\xeb7\xe2G\xda\x81$n?\xa8\x9c\xec\xf5\x8d\xd4r\x11\xe4&\xc7\x0d\xdc\xcb\xb6ksj\x10\xe8\xdb\x01\xc1\xc8\x95h\x84\xcc\x84\xdcbj\xfc\xd66\xdb#\x89T_z\x9b\x1c\xd5\xd6J\xb2\x1a\xd2\xf1\xcc71b\x0fv !\xb0bOY\xa4%j5\x1a\xf1\xa3\xd6\xf47\xed\x87 t\x0c\xbf\x86iI\x0b\xcd\x9a=\x1c\xaa\x91[\xe9\xa8\x11;\xcaA\xf7C\x04\xb0\x81\xa9\xc3\x16lX\xb9\x99\x1d\xc7\xf9\xd0\x0c\x8ci\x03\xf3\xd4\x06\x0b\xada\xf5WQ\x8f\xe7\x06\x87\x10\xd75\xd3\x8a\x91t\x0b\xff\x95\xcdmy\x06\x95\x82\xa1\x01~\\\xb6\xd0t|\xee\xb4\xff\xe3*\xef%\xfab\x96\xac\x99b\xe2\x85\x9c\xe3\xe8\x18t\x03%\xd5Mhs\xbb\xf5\xbd/\xec\x14\xd1\xe5\x9bD\xa3\x04c\x92V\x00\xd71\x89\xf3\xfc\x9c\x10$\x81\xe2/\xeao\xf0:I[\x91:\xd4\xa5\x88\xd0xK\xf5\xc0\xf8\x8f\x1cV\x1d\x9d\xebc\x92RL\xe3]\xc2\x8d\x99\x17\xbd\x81\x01\xae\xec\x93+\x8aAs\x0e\x19\xbc\xe0M(\xd2hW\xba\x91\xd9\x03\"\xbf\x18e\x97\x0e\xfe#E\x0d}\xd9L\x8a\x8e\xbcB_\xaf\xa1@\x8aG_\x08)\xdd\xc8\xce\x0e\x0e\x86\xaf\xde\xce\xae\x10\xb3\x9b\x06\x86\x8c\x956\xb2\xa0\xf3\x18v\x7f\xfd1\xc8\xb60\xf8\xce\xa1\xca\xd2Y\x1f\xd5\x1e=*\xd5y}\xfb\xb8M\x8bQOhly\x9b*\x96\x01\xfb\x8d\xaf\xad\xf3-\xb1\xa9\x8c\x1e\xa0\x01v\xc0O,\xcaMn\x0c\x9a\x05\xef\x0b\xcfijh\xf5|a\xf5\x0d\xa3\xa9\x17\x9a\xa9g};\xbe \x08\xa9C4h\xe4\x85\x1eT@\xa9C\xeb\xde\xc3\xd1\xc4\x98\xfa\xa45 \xc68\xa5\xeeu5\xa3\x9b\x1ei9Nn\xb4\\Pt\xa63LcS\x164\xa9\xd7\x11\x87\x11\x04\xb5\x84*\xf5\xb4 \xb1\x9d\x01\xabfu_Zc\x14Y\x94\xe4\xb34[\ns\x0c\xca3\x06C\x83_\xa8z\x1dl\xa7\xc0d\x9b\x8d^h\xa9*\xe9\x95\xb5\x9a]9*\xb1\x0d\x0f\x9c\xc9\x95[J\xdb\xca\xea\xf2\x983v\x80\xe068\x84\xae\xa2\xc9'\x15\xaaf\xb9^\x14\xf1j\xc1\xa0\x88\x97,w\x86\xbcW\x03\x99\xaf\x93O\xa5\x9bJ9\xba\xea\x8d\xcc\xfaW\x94W\x852ut\x88Y\xf8\xdc\x93M\xbb\xda\xc5\xf3'5Lw\xfc\xd4\x8al\xaeLd\xe1\x05\xa4D\xe0\x8d\xaa+\xdf,\xb6z\xfcZ\x99\x81Ri\x04\x19\x9bj\x88C\x99I\xeakN\xd7\x90`\x14\xf1.\\\xc5\x1c\xf4\x8d5*u3\xafT?/h\xfb%\xc2\x13\x83\xaa\xa6E\xf3h\xcc-RNT3y\xaa\xde\x1d\xea5\xdc\xa9Ff\x8bu>\xd7\x1a\x10\xbf\x0fU\x89\xb2\xbaG\x9b\xedU\xc6J_\xbd\xa8M1J\xf1S\xca\x1d\xa3\x8eg\xe4\xc8\xf4\xd1\x1c\xe9\xbfj\x99\xd3Hnl]\x12\xd7\xfa\xa2p.r-\xc9U\xb5\x7f\x9a\xe7\xb1v\xb1}\xb5\xab\x14\xc2\x88\xd4\xe6\x12j\x99GY\x15\xee\xde\x8a\x14\xa0\x0eL\xeb\xa2\xe3$Z,\xf86\xac\x16y\x9a&\x0cn\xe7,\x81\xdb2\xa9\xd2\xd6!\xf4\xcd\\\x86B\x8bi\x10\xcd\x1au\xdc\xb0\xbb\xbc\x88\x17\x8b\xdaV3\xbb,!C\xb8\x03TB[j\xa5V\x0b\xb5w~,\xd8\x95x\xc3\xe0\xee:\x816']\xa3 \xa5\xdfS\xbd}\xcb\x9d\xac\x1ay}0\xb5\xfd\xd6&)X\x00\xae\xbev\xc4\x98qvk\x8b\xb2t\x97ug\xb3\xa63\x13\x85\x13\xfd\x80\xe1P\xa9\x1dB\xac|\xa3]\xb7\x17!le\x06\"\xd1\xf2Q\xe7#\xc7\xcf\x8c5\xc2\xf3\xe5\x17:q\xbe:Al:\x174\xdf\xaa4\xc2\xb6t;)t\x88\xe25\x82\x02\xb8\x88\"\\cW0\x0c\x93\xc9\xc0\xf4-.\xcb\xd7\x1b\x0dU\x93\x15\x03\\\xf4\xea\xdc\x960!\xb6\xb7A\xdf \x89\x8e\xa9\x1at\xfe\xccd\x14\xed\xd6\x8c-\xd6l\x90Q\xf8\xc2fZ\x10Y\xe1Cn\x12w\x83\xb8\xdc\x8b\xd7\xd6\x98j3\xeb$G_\xcc#\xa9KEiv\x1aM\xe6\xf5\x8aq\x95\xdf~\x92\xb1\x1a.tK\xdf\xab\xf0*\x16D\x93\xa4\xaa\xd2\x8a\xb4\xb4\x1am\x03 \xe7\x069\x8eug\xb4iV\x10M]\x12\x99`\xbe\xc08\x80\xc0F\xc9\xa5U\xf9\xab/\xf3f\xa3\\`\xaeUX\xd34\xc2}\x97\x8b\x84g\x00\x7f\xfb\x86&5\x0c\xd0Sen\x92\xb7\x16\x89\x1d\xb9jq\xfe.z\xe7c\xfa_\xd4b\x14B\x7f\x817w\xdf\x7f/\xd5\x15;\x98\x9b!\xc5\xe8\xd6\xc32\xfc\n^ \xb5\xa7O\xef4\xc7\xba\x0b\xce\xc1\x93\xa7\x81\xcf\x87$\x916\xca\xf3\xf8:\x81!\x16=\xfbV\x9b\xc2\x10\xd2\x10\xb3\xc9\x85\xb0\x0eA\xf5h\xec\xadNv\xbd\xd6\x85\x05\x7f\xb4\xb8 Evg|E{g-B\x90Q\x00I'\xacI\x9a\xcc\xe2\xeb\xb5r\xc3\xea\xd3\xcc\x7f\xe4t\xd2js\xe2\xc2,\xd8C0\xcc\x80\xb5u\x85IT\xda\x8fU\xa7\x93\xb8\xf4Xhw\xb9\x99%Y7\x0f\xdd=\xec\xfa\x90\xab\x91\x88\xd0\x86$\x14\xc3\x8d\x13\xd4\xa35\x0cJ\xa6\xa5.\x0b\x1d!ez\x0d?\x13\xf9\xc1\x05K\x81\x9eZ\xd5*e\xfa\xad\n^\x17\xc9\xd4\xd2\x83\x83 \xc4\x8c\xa8\xa3\xcb\x10\xe2v\xaa\x1aR\x1ap\xce\xf9\xacG\xec\xb2d\xe6\xf9\x8fz\x15${\x05\xf6\xf3\x1c\xd8\xce\xce\xf3@\xb9\xb9z\x91\x07\xdb\xe0oo'A\xa5\x82\xda;0\xe5zM\x8f\xa2\xdc&|o\x96\x88\x9c\xb9XTJ\x1c>o\xb0\x90Q\xeeC\xf0\x02\xd8\xe6\xff\xfcM\xb51K\xa4\xc3\xa68;+\xc7\x81\xe7\xf0\xf5y\x9de\xec\xbcF\x04\xc5G\xf9\xc6\xb1f\xaeD\xf2 \x9eZE`\xa9\x1e\xec\xbd\xc9\x9f\xc8OB3\x01\x95\x03\xfd\x81\xba^\xfe\xfa\xad\xc4I\x88\x1cT&u\x1a\xe9\xeb\x00\xaa\xaa]\xb3\xe2\xec6Q\xd5^\xb1|\x92\xc5\xab\"5\x0c\xa8#\xd7\x07\xef\xa2\xa5\x19\xd3d\xed\xaa{~\xb7\xbcJ\x17y\x87\x93\x89\\cA\x82\xe5\xd1\x9c\xf9\x85\x89\xa7('\xea50\xca@\xe4\xe7\x81bv*\xf1\x9b\xce-G\xae4\x7fpOg\xa1H\xba\x9eQ>\xb6\xfa\xd2\x93M\xa0\xa1\x86\xfd]\x1d\x81\\\xaa\x0e\xcc\xe7\xbe\xfe\x07\x9b\x89n\xe0SJ\xe8\xb4\x9c\xfd]\xbd\x95o\xdc\x15\x8f)\xfe7\xf1\x07\xfb\xe6n\x89iO0\xce\x9e\xde\x17I\xf9\xc1Fd\xc2\xe3\xfb\xa7\xa4v\xa3\xddK\x12\x0c\x19\x92+\\!\xbd#\xc1\x87\xac\xa9\xe5HF\xd9%\xfa8)_\x8a\x08\x05\x12\xf5\x85\xb5$I\x0b\xa0\xf5>\xba1\xfcr\xe8[[R\xdb'B\x10\xd4\xd3\xc8}\xf9\xe2P\xe0![\xefR\x10\xceY\xdbh;\xa1\x05\xcdH\x15!x\xe31\xcb\xdf\xa6\xd35\x9a\x9c\x98K\x89\x8c\x8e.W\x06\"\xde<\xda}v\x81\x88\xbdX9\x17\xae\xdf/\xd6\xd7q\x92\x0f\x1d{\x8be\x99\xab\x08\xb0\xed\xe9z\xc2\xb2|\x08~\x9f\x0b\xbar\xe9\xcd\xe2E\xc1\xb2\xee\xc4\x80\xf5>\xb1\xbbs\xf6_~\xd0c7,\xd3\xc8\xb4\x13\xb4`u_\xb4d\x0bD\xa9mT4d6Q\xb2?z\xb8f\"\x16aw\xb2\xefDg\xd6[\xb2\xec\x9a\xf9N \x19\xc5T\";\xdc\x06X0\xfe\xe1O\x0f\x8d\x08\x9a\x1e\xa3\xf2 N~\x0dtH\xe8pZ\xbf\x06\x805)\xb2.\xc2\xc5B\xe5\xb6k^\x97\x89\xcb\x0f\xf3m%\x94\x0f:\x0b\xe5j2\xa6\\./e\xec\xc9\x95\xaa\x03\xc3{\xfa;\xfb/>\x83\x85uG\xc5\x19\x9b!\x18WS\x0bv\xc3\x16\xc32`|\xadl\xc9\xf2<\xba\xe6Go\xe9\xe6\x8d\xb5\x8c\x1e\xff\xbe\xa2\xb7K\xaf\xd5\xa4\xe1\xb4`\xfb\x97\xfc|\xc5&C(z\x9c\xc98W\xda$\xfc\xf5\x87\x04\xd6\x91\xb28f\xf35\xe8\xc0\xb1\xaaok\xa2\x80\xd8\xa1\xf8b\x15 \xbe\xc4l\xba\xc2G\x87\xf6\xf0\xc9\xae\xa9\xd4\x7fH\xed!Er\x08\xf7\xf8\xff\x15\xf4\x80 \x87\x8e7\xd3\x11\xd2\xe4]q\x8f\xc6\xff\xdc\xab\xfe\xdc\x0f\x02a:\xf3\xf7'_\xb4!\xa3\xeb\xc0\xe8\x80\xc67e\xb41\xc4ZI\xc7\xbd\xa0\x17'S\xf6\xf9l\xe6{\xd2\xe21\x9dA\x84g\xbd\x9f\x07\xa6\x11)\x947\xd1/a\xc7\xe9\xf6\x7fS:q\x1b] \x07ft \xa3:S\x96\xb6\x98\x05\xa1\xf0\xbd\x90\xea\x1e\xf4i\xe7z\xfb\xa1\xab\xc3>\x92\xd8\xed\x0ebB\xadqq3\xe1\x9b\x88\xd0\x90\xd7\xcdh\"\x91i\xdc*'4\xb1\xab\xe5\xef\x970\xc0\x83}\x1b\xbc4\xc3\x18)\x05\x0c!\x1b%\xb0\x0d\x83K\xa3\xea\xae\xac\x8a\xc0\x0b\xc1\xd3kj%X\x80\xbf\x9c\x03\xfc\x1a\x82\x97\xcf\xd3\xf5b\nW\x0c\"\x97Z\xc3O6\xc9$\xe0&~\xbf\xe9\xfdD\x9c\xbdEO\x1c\xfc$\xa1\xd1nu\x1dD}\xb0\xf7TCZ\x071\x0f\x91_\xfcMC\xe6\x1b(\x8dkw\xfa\x14\xf9\x11&@\x9e\xf2s\xeay\"e\xeaj\x11M\x98\x9f\xb0[\xf8\xc0\xaeO?\xaf\xfc$\x04\xef\x9aW\xf7\xbc\x80\xd2\x1b({\xa2\xdf:\x1e.\xa2\xbc@ss\x11Yr\xb1\xc0\x1fy\x19\x16\xd6@+R\xb4\x10\x98\xf6\xd8|\x1d[M\n\xa5\x8b0{U\x0cl\xd0q\xf5\xea\x80l\xd3\xb1\x94k\xae\x8b}JXU\x9a\x16cm\xaa\xa9\xd6\xc1B\x8f:n\x1aB\xd9=oG\xe3\xc8\xbf\xc5$\xe9A\x97\x9d\x90F\x1cs\xb0a\xdb\xe5\x92}\x11\xdd\xa5\xeb\xa2\xdb={)\x88\xfc\x03\xdc\xafS8\xfeP\x1c2}\xbf\xbe\xdb\xef\xbb\xef\xd7\x9fv\x16\xe5\xffW\xe0\xab\xff\xbe\xdb\xca\xc6\x99P\xaahvM\xa3\xa8HaM\xfc\xd0X\xb3& \xb4\xb0\xab\xe6\x98\xa4\xd3\xb8\n\x96hm\xaen\xe7\xa3J/\x90\x86\x90\xf7>\xbe\x7fu|q:~s\xfc\xa7\xb3\x8f\x17-\x8a\x82\xfaQ+\x88\x00\x9e\xa0R\xb9\xa7S\xc2\xc6\xde~|\xfd\xe6\xe2\xb4M\x91\\\xefM\x08\xde\x9b\xf5v\xfe\xd3\xd9\xcf-\x9dX\n\xca^>Oo\x13\x9b\x0e\xa9\xa3b]j\xed\xabO\x8ay\x9c\\\xbb\x1c\xe0\x94\x16\x1f\xdb\x95\x87T\xd5\xc8\xdf\xf8\xd8;\x1ev\x1c\x0e\x19\xe1\xd8\xd8\n\x07 \xf5\xb7g\xafN7\x06\x07\xce\x8d\x06GUi\x99N\x99c\xfa\x18\xea\xdc\x1fy\xbcJ\xee]\xaa\xfb\xab\x84\x0f5\x13\xb1C\xd0\xc6\xd9\xabO#\xfd\xad\x1c\xa5|\xd9\xce\xd7\xcbe\x94\xdd\xe1\x94o\xe7\x91\xc8\x0f\xc4\x7f\xc4\xf99_U\x11\x86}\x9de,)~D<\xd5\xdf\xb8\x98-u\xec<\xdd\xfbUO\x1d\x82\x95\x13de`Z\x97\xe5\x92\xda\xe8T\xa5\x9aS\x07\xf6\xe8Z#\x13\xda\xf2\x86\x04\xb4\xba\xb6&\xc9\x80S\xdd\xb50\xd6\xa5 {\xb4\xd6\x8brw'i\xb6\x8c\x16\xf1_\x19\xba{\x05\xd2\xfe\x1d\xfb\xd6wp\xae\xef\xe0\x00\xcb\xeb\xaf\xf9w 9\xcc\x1a\x0eu\xda\x8d\xa5\xdd\xab.\xa0\xd7SX\xe9\xa6\xb1pT\xff\xe9\x8e\x9e\xd3>kj\xef\x1a\xea\xe5\"0\xa6jo\x1bA\x94\xbaK\x06\xb6\xfc\xdb\x81\x1d\xdfBf\xc3c\xd3\xb8Hk\x18\xd2\x89\x94T\xf2\xcf\xdeAG\xd7/N\xa5\x8c\xa1\xd0jt9\xc0\x14\xf3\xe6d~\x12\x8c\xfa\x97!$\xa3\xc1%zc\xfa&EoTm\xab\xbb!\xd6\x13\xcd\xda\xc2\xa90\x14\xd7\x90#\x16\xfec\xd2\xc8Y\xa4\x0e\xac\xf7\xf8]\xfd\xaf\xce\xb0zb\xd2\x0c\xa9\x96x\x16\xf8^\\\xb0,\xc2\xa5\xb0\xc9\x9b\xe1K\xd9\x06o\xc7\x8a\x9b\xa1\xf4\xfd\xac\x87\x0dk\xc9\xc71{\xdaa\x8d\x9f\xddp\x8a\x8dsI\x8d\xb0\"\xf6\xfa\xab\xe5\x1a=\xb9\x1ce\x97f\xfe\xbdX.b\x93\xa4\x06\xaa\x1f#*Q(\xa1\xc8)NM^\xa5\x1a\x108\xb1[oA\x83 \xedx\xd3\xd9r_\xc4AB?\xe6*\x84\x93\x19oE\x913\xf3=\xbdi4\xc0\xd1R!?\xccb\x02\xa6X\x86Y\x97\xda\xa0\nMr\xb0z\xa6i\xc2\x86b\xdc\x9d\x83^\x878\xb0\x0d\xba\x8f\xa86\x98\x1f;\x08\x03\xeb\xe0\x1e\xd5\x05\xcb\x7f\x05\xfe\xe9\x97VE\xe4xk\xea^\xbe\xdb,Z\x1d+\xfdBC\xee\xe8\x7fH\x85\xc5\xde\xaf\xcb:.Paa\x99\x94\xaf\xcb\xa2\x81Y\x94\xcb\xa2\xbd\xfd\x03Z\x97AD_\xfd\xa7.\xe3\x97\xde\x97$:\xadHw\x81X\x95\xec\x99%\x91,yj\x954i),!c!\x9b\xd9\xb3\xba\x9eH\xb5\xc6\xc0x?\x93\xefwI\x84j\x08S\xfaK\xd8\xb9\xd4\xf4,\x99\xa6g\xd1\xac\x0f\xb3\x10fJ\x06?\x7f\x7fz\xd2M\xefQ\xe6G\xd0\xa2\")\x81\x1b\xa3\xe9\xa2Z\x04-Ru\xa5\x08\xe8\xa3V\n\x01\xc7`>~x\xd3m,\xb2\xb3u\xb6\xd0\xfb\"\xc4\xf6\x86\xce\xfep~\xf6n\xa3\xde\xfe\x92\xa7\xa6\xb4u\x96MY\xc6\xa6\x9a\xee%\xe8\xdc\xff\x87\xd3\xf3\xb37\x7f<}\xb5\xc1\x18P\xf8\xc9X\x9e.n\xd8\xd4\xbb|\xf8\xb1\x8c\xcf?\xfep\xf1\xe1tc\xad\x0c\xad\x8fI\x84\x13\xbd]\x98J\x13\xdab\xde\xa2\xa4Qs=__\x15\x193e>]\xad\x14\x04\x0ehd\xdd\xa1\xf0\xfe\xf8\xc3\xf1\xdb\x87\x9a:\x9f\x9d{\xe6Y\xb4|\x17- \xd0\xc4U\x85\xd7\x84\xd6o]\x15\xdb\x85y\x13\xcc1\x9cg/\xce\xff\xe7\x92\x88 7!tB\xea\xbd\xf0T\xe6\xe7\xcf\xfc$\x9d\"\xd1\xda\x8a\x05g\x0dG\xb0\x16\xaa\x88$Z2\xa17\xeby\xb0\xad\xde\xc6\x89|\xc7?\xde\x11\x05\xaa\x1d\x1f\xf3\xf7\x97_\xc4\xf61\xca\xe9\xea\x02\x8e\xc0\xc3\x19\x8d?/\x17\x1e\x0c\xe5/Z\x7f\xa0i\xf7\x18\xe6\xf3F\xeb$7\xd6dA\x08#\x0f\xa1\xc9\n\x86Wv\x93\x10f\x97A\x08yg\xac9}\xfb\xfe\xe2O\x02w\xc6\xaf\xdf\x9d\xbc\xf9x\xfe\xba\x95\xb0l\x84EoY1O\x89\x1a\x0f\x83Kq2Y\xac\xa7\xect\xb9*\xee\xfe\xc8Ak\xf3-\xc2\x1cx+.y\x1ee\xc2v\x1be\x89\xef\xfd\x1ce \x06\x1el\x02\x08L\xd0\xe4\"I\x0b\xb8f \x17^\x19D\x80c\xfb\x1f\xec\xae\x87\x16d6\n\xe4\x18\x1d\xd7\x81#\x0f\xb3\xe8c\x04@\xce\xd9g/\x84\x9c\xaf\xfd\xba}\xed\xffx\xfc\xe6uE3\xce\x7f\xbd\xe5\x8e\xf3\xb3\xe3\xf3=z\xad5\x05YGH\x04\x84\xfa\x9f0\"\xe7\xb4\xe3\xd1\xe7\xe5\xe2Q\xdc+X^\xf8\xb1\xd8\xde\x1c\x0d\xd6K\x96\x8f\xc5\x96\xa4\xbe\xe4{x\xd2\xe3\x9ca\xc4\xa1\xf3s\x8c\xf3\x8bd\xcc\x10ArB\x18\xb1\x86!6\xdfcl4]c\xb7_R\xd3\xefx\xfb1S\xd6\x8f\x1a\xed\x10m\x95\x8e\x15\x94\x01\x95K\xecV\x18\"\x8e\xb0\x9bh\x11\xf3\xc9\xbd\xe7\xad\xa3\x91\xfb\"\x84\xb4\x835\x18\x87FAR\xe4\xa2\xa2\xc8!(\x0b\x85Ks\xfe\xa4\xd1\x93\x1d\x15\xa5}\x7f\x08\x93\xfco\xdc%\xdavx(\x1cH\xdaq`t\xd9\x15\x07\xbaX\x03\x81\xc5F\xd6\xacCj\xdd\x12\xb0\xdf\x18\xf0\xe7\xa7\x17\x9c\x9b{\x7f\xf6\xee\xfc\xc1\xb8\xb8\xcc\x8c\x07\x035\x1e\xce.\xc3k\x9d\xde\xd2A\xc8\xd6\x0ef\xc3_\xa3\x13\x1d\xc2\x07\x8e\xc0\xd0\xea\xdb\xa0\x15\xd6\xd2dP,\x8e\xfcC\xd1V/!\xcf\xc6\xd2\x90_T\x92? \x9e\xaa\x88\x8au\xce\x19\x16U\xb5zS_\x9bP\x96g,_\xa5I\x8eY\x02\xb2\xa07g\xd1\x94\xa19\xd2\xba\xfc\xfb\xcb\x17K?\xc0\x17c\x824\\\xe3}\xb1\x1d\x8e*i\x08\x91\x8b\xdd_;(\xe4B\xc1\xae\xf7\xc3\"\xbd\x12\xda\x97iTDzPm\xbb\x8e?A\x8a\xed\x1aD\x08^\xc1>\x17\x9cr\x88\xd6\xf8\x112\xe9\x88\x95\xff\xf1\xf1\xf4\xbc\xedJ\x7f\x03\xa4\xfc\xaf\xcd\x902\xd6\x90\xb2U\xec\xf8\xaf5\xcb\x0b9\xe9\xd8\x05\xf9.\xa2\x05\x9f\xf9\xdb\x8f\x17\xc7\x17\xa7\xaf\xfe\x91 \xb0\\\x17Q\xc1\xa6\x1f\x1e\x0e\x10\x929<{\x7f\xfa\xe1\xf8\xe2\xf5\xd9\xbb\xf1\xdb\xd3\x8bc~B||0:\xd5$r9\xa4\"\x01\x92O\xec\x8e\x96\xa6F\xad,\x85\x83[\xeaz\x1eYN\xa0\xe5J(V\x0e\xb5\x0e\xae\xcf\xf3 \x080{dY\xbd\xd2\x0el\xfcI\xab\x90\x8d\x9f\x1eUX\xe2\xaa\xb7\xe0\x87ll\x9f\xaci\xd0M\x1b$\x98\x87\x87>\xc5\x9a\xb0\xa3qOL\xd9\x82I&C'\x87Y\x08\xe9e;\xde\xab\xc9<\xe8\xd6\x7f\x98\xb9\x94{\xbb\xe3T8-;?\xf9\xe9\xf4\xed\x83\xadI>\x993\xeat\xfe&*\x96\xf2s,\xd6\x11\xd5\x13\xfdTT,\x13\xca\x87/_\xb0\x9e\xbc\xb6\x1dR\x1fxc \x83s\xf1\xe6\xb2\x9e\x97$(\x7fv\xbe\xbf\xdd\xa3c\x99=\xdb'4\xdd\xf2\xb67_\xb1I\xccr\xaf\x8b\x1d\x00\xb9\x16!\xb2d\x99\xcf\xd0_?/\xb2\xf5\xa4H3\x12zZ*\xa8HK\x0f\x7fx\x08~\x82mD\x01\xdf\xdb\x98\xdbh\x08\xa9n+\xd0\xe9*\xe1\xa6\x16\x87\x15\xe7\xb8\xff\x8cV\xd8\xef\x99 \x91\x86\x85\xfb\x94\xce>\xf1\x07V\x948\xa9\xb1\xa7\x14\xf6\x93\xde*K',78\xdbU\xc9\xfd\x94\x89\xf6k\xe5S,\xafg\xc0\xaf\xd7\x98c\x8d\xb7\x82\x9f<\x99GI\xc2\x0c\x85\xdb\x0d\xd6x\x15\xe7\xab\xa80\xc35/1\x1di\xed\xd55\x11\x80\xee\xae\xed*\xf7F\xa67\xd8\xb6\xc3_\x83\xd4\xea\\\x1bWJ>s\xe6\xbeW\x97Z\xd7V(R\xf5\x08\xba\x82\x15B(|B\x92\xa9\xbd1\xa6s\xd5h\\\xc1\x1fu\xe1%x\xcez[\xd5\x88V|\xe7O1\xc6\xc1\xaa\xb1\xc9*G\xba\x8c\xd6\xcaQ{\xf0\x9c2lJ\xaa\xe8\xaa\x95\x11S\xb2\xbd\xed\xb8g\xbb\x1emo/[o\xda\xd7\x8e$\x1a\xf2\x06\xe8\xc7j\xe0\xa1\x15\xae:\x84\xcc_\x06!,\xbf\xd3^5\xc7\x86\xd7VG\xff\xc8\x93[\x00\x87\x90\xf8\xcf\xf6\x02\x7f\x16\xe0\xb5l#\xec\xd0\x94\xe1\"\x9e|\xf2#\xff\x0e\xe3\x94\x0ct\xfe\x0f\x86p\x83\xc6`\xbd$\xbdmm\x0dk9\x1b\xc2\xd0\xc2\xb12\x19N\xd8-\xcc\x83\x1e'{\xbb\xfct\xe2\x7f\x0czi\"\x8578\x84\xab\x10\xbb\x8b\xfc\xb8\xb7J\xf3B\xeeB$5\x03d>&\xbdh:=\xbdaI\xf1&\xce\x0b\x96\xb0\x0c\\\x01\x0b\xb5\x06P\xdb=\xe9\xc5K\xde\xe39\x86S\xcdU\xd0c\xf7\xd4&\xfa\x18|tt\xe3\x07\xca\xef\xea\xa6\x87\xf6\x88t\xa7\xa1\xab\x10\xb6\xc4\xc8y_^\x9ad,\x9a\xde\xa1\x1d\xc2d\x1e%\xd7\xcc\x838\x81\x85\xef\x89 \xaf\x1e_>\xf7\x88\xf2^\xb4Z\xb1dz2\x8f\x17S_\xfb*\xe8\xd9-\xb7\xe1p\xde\xcb\xd82\xbda\xa21\x91 \xa7\xdc\xa7\x06\xce\xd6\x16\xb5a|\xac\xb8\x88\x97,]\x17\x1aF\x84\xd0\xaf\x1f\xb8\xfa\xd1g}?\x84\x95q\x06pZ=\x84i\xd5\x04\xfe\xf5\xedq2\x1bM\xebh:\xea\x08\xc2\xcd\x9f\x9b!\xb0v\xb2\xd9\x18\xc9\xb5\xb5kBQ\x02\xb2\xeb\xb6\x8e[\xa0\xb7)\xb3\xb3\xfb\x94dvv\xfb\x8f\xef\xc3\xe2`\xb2\x10\xa4\x95\xa9_\x88|\x1b:\x9b#\xed\xedJK\x08[\xf1\x82\x91\xa2{3;\xa5\x98\xf8\x82\xf3\xc2\xa8\x05\xe3b\x92\xb4\xa4\xe5\xec\xc32\xce7\x8cs[\x8fu\xffd\xef[\x02\xda\x17\xba\xe5\xc0!l\xb9\xcc\xb9w\xfb\xbf\xa4Q\x8e>\x1eY\xa7\x8b\xa5d+\xf3\"\x9c%\x1d\xa1\xc5]\xa8\x8f\x89\xe1\xd40j\x8aw2\x9a\x13\xd8\xe3\x81\xccOC\x88\\\xb5\xa112\x85zn\xa4\xb3}1J/\xfd\x88\xd0\x10\x98\x8f\xd0\x0e\xa2\x8a\xc2Y\xb7=\x8a\xb3ztF\x9e\x0c$\xa3\x1e\xdb\xe0K=x\xeb\xb7\xeeM\xd3\xa4\xda7%`\xd5N\xf0\xf3\x00c\xfav\xd0\x80\xab'\xf3=\xce\x15\xcb\xc8\x1b\x89\x88\xd7 \xd2'\\\xb6exq\x918\xc2^\nM\xc0\xb7R_\x84\xc9\x8e\xe5\xff\x98\x0d\x87\x8b\xdb\x9b\xa1Q5\xe9\xc1>}\xca>1\xe5j\xa9R\xd83St\xca\xfc\x15\xe6\xa1,\xc4\xf0\xa7\xfd.g2\xba\x1f\xe4\xd4\xc9\xbc\x15\xa1d\xa9TP\xf5\x8dX\nb\\\x84\xdf\x19\x84(\xb2\xa3\xa7|\x8aQ\xe2\x82@Jb\xa1\x90\xdaa\x07\x06!J\xe9\xecy\x99o\x12\xc5\xbe\xed\xed\x05\xbc\x80\xc9s\xd7\x81\xc2%\xa4\xb5_\x8c\x16\x97\x0e\x82\xcc\x05w\xc2y\x81O\x01{\x995I\xc7\\\xa6_\x8d\xa6\x0e\xe9XO\xaf\xcd\xbb\xe1\xc2C\xee\xdf\x840\x0da\xc5\x99{QA\x98r\xceQ\x80\xb9\xe1\x9c\xfc\x0d\x0c!\xe6c\xc6@\x17\xfc\xcd\xe8\x92\x9f\xceT\xf8!\xebM\xe6\xaf\xb0\x83y \x00\xc6\x87\xf7\x9d\xfb\x13\xb5>\xf7E\xc2\xbd\xfdN\xbc\x1bq\x14{\xe31\x9a\xb9\x8e\xc7b\xaf\xe0\x9e\xe0\x8c\x88\xfc\xc0\x86z{V\x9cZ\x12\x19\xa2\\Z\xa1\x12V1Zb\x1a\xc3\xbf\x01\x95\xd7\xa3\x82\x0b\xf7\x1b\x9a\xb5k\xf4\xc9\xe4\xc5\xd261\xab9\x10\x16C\x95\x9c0\xc4\x0d\xc1\xab\x9b\xe2\xb6\xc5\x8f\xc10\x94\\&E\xb3\x07B\x06p\x9b\xf7\x7f\xf5\x1d\x8b\x9dv\x81\xc7/lN\x1cBQ7\xa1\xc8Q\x17\xcd>\xb3\xc9\xba`\xf2N\x0b_ \xfb\x81?\xe4ir\xbeb\x13\xed\x95\xfc\xe9\nJ\x11\xfb\x89\xbfO\x862\xe7%\x83=\x87\xa3<\x91\xecX\xad\xc5/c\x0b\\\x9bL\xa3\x0cU\xa9\xec\xf3\x15\x9bH\x07\x05R\x1aj\xc4VfX\xf6TL{(L\xd1rv\x91rx\xcbz\x89^\xc55\xa1\x90Z\xa9_c655\xa1\xa9\x1b\x0c+\xc71\x14 #\xcc\xe5\x04\x11\xbc\x80\xe29D\xdb\xdb\x01\xc4\xa3\xe8\xb2\x96&$\"\x0e\x08\x13d1\x82*N\x14\x06\x7f\xa8_\xcf\x9dD\x939\xa3\\\x8c\x94\xd4\x11\x8f\xfa\x0e\x07\xa5\xdc\x0eP\xbf\x0e\xab;\xce\x80\xb2K\xe0\x8f_\x8f\xb9I\xe5\xacq\xf2\xe9F\x7f9\x1a{\x05\xbd\x7f\xc9\xd8\x8c\xa3<\xdeb\xf3\xedh\xcc\xd2W\xa3\n\x81]n\xc2\x80\x87\xd4F\x7fh\\!\xcd\xb8\x94\x0c\xda[\xa4\xd7\xb2k\xe1\xb6\xea\x9b\x1a\xdc\xfah-J\xb5\xc1h\xcb\xb0\x8c\xf7\x1f/\xc3`\xc7\xd2\xae\xd0\x8aRcP\x95\xbf?]\xef\xa2c\xb8\xd1c\xbd\x9d\xa4\xcbU\x9a`VJ\x0b\x04e\x94\xb6\xf3\"\xcd\x1c\xd6\x01Z\xa0b\xbb\x02\xde\xaa\xd5z\xb1\xeb\x08\xab\xa6\x8c%S\x96\xd9\xa5\xb9\x0c\x1c\xfe\x89\xbd\x8dV+6=I\x93\"\x8a\x13\xaa\xea\xa2\xdc\xbeK\xb6L\xe3\xbf\xb2\xc0\x8fDvr\x91>:F\x1e\xdcJ\xa2\xe5T\x0bfiZ\xbcN\xf8\xda8\x9d\xd9\xf4\x99\x0d\x810\x1c\xe7\x0f1\xf8\xa19\xd0\xdc\x1e\xe8\x02\xc7J7)\xa05\x84\xb5\xfdYd\xdd\x88\x80\xc5\xcb\xba=\xd5Z/\x9a6r\xf6\x02\x0d\xd9(\xc2\xd9\xe2\xf4\x05\xbf\xa8\xe3\x17Tk\xeft\xfe\x02d\xe58\xf3\xfe\x94bf\xd0=\xea7\xb2\xf1uTD\xfa'p\x04\xff$0\xb0\x81y\xbb\xe6\xcc\xdbcj\xbe\xd7$[\x17\xcb\x12\xda\xe5\x0cK\xac\xd6\xd6\xaa5\xca\x01\x11?1\x0b\x16\xb2\xc0\xead\"\x0b\xac>f\xb2\xe0\xc0,X\xe1\xd2\x99\x97\xe4S\xac\xbe2\xde\xcee#O\x9eXC\xbd\x11\xe2\xffc\xf3\xfa|)?y\xfa\xf8\x19\xcd\xe6^\xff\xbal._W+\x1d\xb4C\xe5k\x13\x81\x06\xa3l \x8eR\xa7\"Y=\x9a&\xb9\xad*\xd4\xaf\x18\xf2\x8aM\x12\x1a\xefL\xda\xe1L\xcc\x02?\xeb\x952\xb3\x8a\xe8\xbf\xae\x19\x9594\xe7n\x0d)\x90:\x04\xfd\xd1F:\xab\x19\x06%r\x98\x8b\xda\xdbQ\xfb\xdc?\xb1\xbb!xb\x1f{\xf4A\xa0?\x9224r\xec\xd4#\x07>-\xf5\xd7\"\xee\xc7\xa9Hl\xcf\xe9\x91a\xbf\xf67\xf4u\x0fdn\xf3U\x96\xaer\xf9\xf7$M\n\xf6\xb9h\x81#\xb4\xc2\xf2\xebe\x10\x12\xe1\xd8\xcbb\x7f\xd5+\x89\x9dK9\x8d\x98KC-\x95\x9c\xc2\x0d\x1fp\xc2&\x85\x16\xdb\xa4-\x80\xeb\x8dL\x8eo\x9a_\x7fE31\xe6S\xd1'\xd5\xa3PD?\xbe\x96\xd1\ns\xd0_\xa4\xfc\x04@\xdb\xe7v\xa9\xc1h\xb0}\x9d\xf1\xde\x9a\xba\xc7\xd4\x1f\xf7\x9a|\x0d\xfc\xa4\x8c\xf1D\x146d\xf6Ij7\xee\x0d\xd4d#J\xb2\x01\x15\xf9\xadP\x107t\x1f\x96rl@5\xeeC1Z\xa8\xc5M\xef}\x96\xde\xc4\x9c\x97\xef\xd0\x18 j\xa6Y+j\x82\xe0\xb16\xa3Qn\xf2t_:\xdf@\x97Zh\xd2W\xb1\x81`h$\x0ci\xb4\xf4j\x8c(]r\xc6)\xe7\x8c\x1b=\xa7by\xd9JS&\xd2\xba'\x1670\xc9(\xbd\x0c!\xc3\x7f\x19\x99\x88\xa6i6c\xbc\xacp\xb0\x9f\xc44\x85\xcdc\x830\xde,\xb1C\x9d0\xb8x\x1c\xf58(\x82\x9b|\xeb\xa4\xff>\x14C\xa4\xac\xc5\xda8\xb6\xf6\x93\xe2\x8a\x03'\x12Z~\x8c\xb2G\xa3^\x13=\xb5\xa9J\xb1)U\x11\x14e\xa2\x90\xfb\xe7x\xb1\xf8\xc0&,\xbeA\xa1%o 2&\x81id%\xf9\xa3M\xb8\xda\xbd\x9b\xd2\xd4\xafM\xa4\xa7#y\xdc\x944\xaa\xcb\x06\x0e\xd8e\x1d7\x14 \x8a\xa4\xd3\x96\xa6\xee\x8b8A\x18\xb9n\xdc\xf4\xa7@a#\x0e\xc1\xcb\xd2\xb4p\xdd\\\xa8\xa7\x9d\xa5\xdb\xd8\xec\xc1A\xfa\x1a\xc8\xde\xd7P\x97B\xc9\xedn\xc5c\x03\x8db\xa9\xaaY\x08\xde\xf1j\xe55\xcc}\xde\xabl/x\x7f\xbek\xe6q\x88\xb7\xa2\x81\xc5\xcc\xb4\x1aUTJ\xb3$Z\x12z\x8e\x16\x90{\xd3\xf8\xc6\x92\xe5\xd5\x93\x17w\x0b\xd6\x14\x14i\x15M\xa7\xe8B\xee\x0d\xd8\xb2\x01k'\xe9\"\xcd\x86\xe0\xfd\xff\xa2(r\xe4\xbd\xb3W0\x04\xef\xff\xf9\xdf\xff\xb7\xff\x03<\xf7\xf9\xea\xc5\x9e\x00\\\x08\xdeI\xe9\xa8.\xd7\x96/\x0c\xe6\xbf>\x84\x02\x8e\xc0\xe38\x0f%\xb5\xf0`\xc8\x17\xd1\x0b!g\x0c\x8a9+\xbd\xe3=+\xe4w}b\xb7\xad\xca(\xb5&\xdd\x18f\xb9B[>\xab\xd8o!oW\xdcx\x9c\x7f`\xd1\xa4h\x17.\x9a\x0dI\xf5\xa7\xf3\xd1\xa5\x9e\xf2\x08k\xa7:\xd0\xc2\xdf&N\xfe6i<\xad\x92{\xf0\xb7\xd0*\xd5\xd1'RB\x9eHI+\x9f\x0b\xdd\x89\xb9z6%\xea\xea\xa9\xae\x02:\x9cI\xea\xe9 \xe1&n\x1a\xdcI\xc2\xc5\x1bwz\xda\xd2\xbd\xa8Dl\x01\xa3\x06\x0d\xa8Y\xb5\xed\xde\x1dZM\xfdJ\x06\x95\x91\xb7\x83Yy;\x88\x96\xa9\xe2v0\x85\x17\xc0\x9eC\xba\xbd\x1d \xd7Y\xbb\x1dt1\xb0\xa0\xdf.\xe9h\x9b9 \xd7\xc9TP\xb6XOG\xc5\x87\xea\"\x92\xe36\x89G:d;VL=\xc27\xbb\xc0c\xc6\x8d\x1f\x8e\x99Q\xd4\xddPgW0\xb4\x94\xc6\xf6\x19\x9d\x86\x10\x9b@\x8ag\xe0\x97\xc6[U\xe2\xbf4\x90A+\x13v\x0b\x17w+v*\x12x\xbdcl\n\x11\x88\x0fB(R\x981\x0e\xfd\xa8:#z\xf0s\x94\xc3u|\xc3\x12\x880\xd5\x8d\xaf\x99\x04\xa5\xfcPY'BM>\xe5\xe7\x89q\xe1\x9aZA08\xd6 \xa3-3*\x84\\U\xce\x8b\xc5\xbc]\xe4(\xb0\x1b\xfe\xf3N\xb1\x9f>\xfa\x14\xe0\xcf[?\xc2\x1f\xb7\x82[\xf3\x99\x1f\xf4\x16\xe9\xb5\x0c\xeeR\x9d\x86\xb38\x99j\xc7\x1e\xe70$\xb3Q\x0e\xa0\xd3%\xa1\xdb|_Nx\x08\x89\xff\xe4\x89i\xc8W\xe9\x8c\xeb\x97\x03]\xba\xa4\xaf'\xdc\x03\x99G9^\xb3\x0bG\x89w\xe9\x94\xe5C\x18\xddX\x12\xc2:\x04\xe1V\xa4\x90\xd5w\x10T4\xdb\x16\xb1\x93\x1c'\x838\x94\xd7x\n$x\np\xc4Jz\xf2,\x80\xa1\x8a_\x87\xb1\x89\x9d:\xee\x05\xca\x11\x92\xfd\xec)\xa4\xc6hl[\xfd\xc6\x03\xd0\x81\x8e\x8dwR4,\x0b\xa1U\xd1\x1b4\xb8@\xd26[g\xd0\x84\x1b\xec7\xf1\\\xf5Q\xcbKC\x93\xceO\xd1b\x8cz[\xc4K\xa2\xc4SE;\x8bt\x12-<\xbb\x06[F\xf1\xc2~\xbdL\x93bn\xbfN\xd6\xcb+F\x8ck\x15\xe5\xf9m\x9aM\xed\x92\x8c\xef\x07\xfbu\xce\xa2lBtP0b0\x9c\xef'\xde\x923^gD\x03\xb7\x8c}\xaak`\xdb\x94tN.W\\N*v\xb6\xfe\xab\xce\xb5\x92\xac\xae\xce\xe5\x16p\x04[[\xd9Hp\xce\x98b\x8e\xcf4\xcaX$+T\xe3}p\xfc\x12\xa9\x03\xcf'\\\x8c|\xc3f\xc5\xd0\x0c\xe1U\xabq\x91\xae\xac\n\x19\x9be,\x9f\x8b\n\xb8m\xf3\xb6}\x98\xf5\xac~Q:\xf8\x1c\x9aE\x17)\xfaK\xf7\xeejm\xb4\xee\xc3\xec\xdb\xe1\xe4R\x83\xfa\x83\xc7\xa6u\xbatM\xb7B\xc1E]\xd4W\x9c\x82\xb7\x86\xd6f\xbdY\x9c\xe5\x05\xaa\xf4\xddZ\x1b\x94\x9f\x12\x112\x06\xd3ic}\xferO\x8aS\x1cC/\xeeV\xd5\x89s\x93\xc6S_\xbc\xc7\xa5\x83\xc3v\x0f\x15@`k\xeaX\x8bU\xd2V\xc5T\xfbvW\xf9r\xae\xba\x15\x82{\"a]918\xe2\xc4]\x04\xd3AMy}j\x15\xde\x04F0\xa6o\xa0\xdc\xdd(\x07}\x1f\xcbz\xb3t\xb2\xce\xcds\x86v^~\xf0\xdd\x1f%\xf1\x12c\xdb\xbf.d\x90\xfb\x93t\x9d\x104\xf6*\xcd\xa6,{\xbd\x8c\xae\xd9\xd9\xba@\x06\xbf\xa1\xca\xf9\"\x9e\x10$Y\xab\xf1s<\xa5\x8e\x95\xab\xf4\xf3\x8f\x0b\xf6\xd9Y\xf0\xfb,]\xaf\xc8\xd2\xb3l\x1a'\xd1\xc2Qa\x92.\xd6K\xd7\xdcDan\x17\xcc\xc8\xa1\xcc\xc48n\xe9\x92\xf7i\x1e\x17\xf1\x0d1{^z>\xcf\xe2\xe4\x13]\xf6\x8e]G\xee/1\\\xb1]t\x9d\xc5\xd3\x0f\xd4Xd\xc1iB\x1c\xc5\xb2\xec|\x15%\xee\xc2\"\xca\x08X\xf1\xd2\x13\x84WS\x99\xb3WQ\xec\xeeX\x96\xd3}\xcf\xd2\xa4\xf8\x99\xc5\xd7s\xa2l\x11'\xecd\x11-\x89\xb5\xe7E?9>KW\xd1$.\xee\x88\x02\x1a\xdci\xb6\x9aG\x14\xaa\x14\xd1\xd5y\xfcWb\xedn\xe3izK|\xf0\xd7\xd7\xc9\x94\xc2\xae\xbf\xa6\xe9\x92\x98z\xbcX\x9c\xb9\xc6:[\xa4\xe9\xd4Y\xca\xb9\xd9\x86\xc2,\xfd\xc4^E\xf9<\xca\xb2\xa8\xb1B:\x9b\x91\xdb^\xd4x\x1b\x17,[\xc4\xcb\xd8Y\xa3e\x0c%A(\xcb\xbe\xda\x17p#\xefgv\xf5).\xbc\x10\xbce\xce\xff}\x9b\xfe\x95\xffw\xe6i\x9a\x1e\xa9\x89\xf9\xc4\xeer?\xeb\xe2\xee\x9d\xdauh\xa7\xe3Q\xeba\x0e\x9a:\x11\x13WL\xe6Qv\\\xf8\xfd\xa0W\xa4\x1f\xb90+5\x99\xbc,__ \xc3\x0b\x7f@\xd9\xa4\xa3!\xe8%gf\xf4\xd0\x97X\xa6\xa98\x8d{\xca\xd8\xa2\xf1q\xfe1\x89\x8b\x05\xcb\xf3w\x92i7\xdcs\xf3y\x9a\x15\xf3(\x99*\xad\xd5\xe9\xe7U\x94\xe4\"'\xa3=\xc5\xabh\xf2\xe9:K\xd7|\x8f\xd3\x00\xa8j\x1c\x17E4\x99/\x19Ev\xed\xda'\xb4\xaccW\xc4#\xa4KEA\x8d\xd3\xe4\x7fnR\xf9O]*\x7f`+\x16\x15C*\x8d)\xa1:\xb1;i\x87\xdd\xfd\xc7\xdeiD\x92\xc29F\x81\xa5\x8eC\xba^\xe9\\\x98\xc76W*W\xb6\xfb\xd0~H\x8b\x82\x93\xc2\xa6\x01\x8a:\x9d\x86)\xaav\x1a\xac\xa8z\x8f!\x0b\xf1\xa9i\xc0\xbcF\xa7\xe1\xf2\x8a\x9d\x06\xcb+\xdec\xa8\x1f\xc4y\xd84V\xac\xd2i\xb0X\xb3\xd3h\xb1\xe6=\x86\x8bbg\xd3`/\xd2U\xa7\xa1^\xa4\xabN\x03\xbdHW\x1b\x0d\x93\xf3&\xae\x11\xf2\xb2\x96Ny\x95?FY\x1c5\x11\xca&\xfeG\xafC3\"\xeaib\x87\xd4\xc3[\xf91Z\xc6\x8b\xbb\xae\xf3O\xd7\x05o\xd8\x05\x02Y\xdc\xb2D\xb2V\x0b\xacd\xad\x86\xe5\xf9\x8e\xfe\xe5P\x15\xc4\xf8\xf6\x9b\x84\xaa\xc4\x7fj\x06\xe3K\x85a\xd0`\x1f\xe3\x02\xee\x89\xf0\x80O\xfb\x96\x83\xbc4 \xc2rv\x0b\x1f\xd8\xf5\xe9\xe7\x95\xef\xfd\xe7\xc8\x83m\xc8z\xc7\x17\x17\x1f^\xff\xf0\xf1\xe2t\xfc\xee\xf8\xed\xe9\xf8\xfc\xe2\xf8\xc3\xc5\xf8\xe4\xa7\xe3\x0f\xb0\x0d\xde%]\xa9,\xfe\xdd\xbfXi\xcd\"\"\x1e\xfbZ\x06\x80(_\x96w\xa5\xb9\xf3\xaetkkmG`\xc7\x00\x81\x11\xf1\x9e\xcb\xfd2\xfb\x1a\x1a\xb4\xf9\xeb\x11\xbb\xc4\xb0\xaf\xa8\xdd\x85!\xf8\x91\xf6\xa6\x16H\x9bNs\xdc\xc5\x9e\x10\xf3\x84\xcc\xa3\xfc\x874]\xb0(\x11:\x80\xef\xbf\x87\xad\xaa\xe8\xddz\xc9\xb2xR\x16\xc5\xf9\xbb\xe8\x1dg\xfeT\x05%\xce\x99\x15\x0bx\x01\x83\xb2\xd6\xd9\x0d\xcb\x16i4eS\xab\xaf\x01\xa9\xc0\x03\x89<\x13[\x1f\x87V\xcbo\xa3\xec\xd3z\xf5c\x9a\xbd~\xd5\xaaJ\x13\xd3\xcez\xaf_\x8d\xeb\x88\xc0q\xe0\x90cHj\x85\xb4\xae#@\xce\x8a\xe3\xa2\xc8\xe2\xabu\xc1\xac>\x1d\x8c.f\x9b(\xbf\xf2\x89\xee\x89\xe0\xefM3\xfd\x90\xa6m\xd7\x95\xe5T?\x9c\x9d]\xd8\x93\xfd\xb7C\xcf\xfb\xb7\x0d\xe6i\xf4HB\xd7\x9a&\xd1uXK\xdcK\xf4k\xccT\xed\x8c\x0ePV\xea?\xbc\xfc\xe6\x1f\xc5,'\xf6\xd7Q\xad\xc2\x08U\xc8\xb4Q\x15j ]\x82\x0bF\x8b\x14.\x1f\xa5~\xd0\xf3huc\xe9\x07\xd6\x8b\x14tl\xb3\x0e\xf5\x94\xf6\xff\xe6n\xfc\xf2E\xbcl\xd8@\xfdRE\x1e\xab5\x86!\xfe\xad\x90\xbb\x93\xbe\xb2\xc4\x9d8?Y\xe7E\xba\xac\x16\x15\x01X\x91\x0d\xbc\xc1\x1a\xa2\xf8V\xf5 \x01\xba\xc1*\x1b\xbdtXl9\xc4\\RL\x15{\xa7\xc00#\xc6`<\xaf\x05\xd1\x11\x80ndk\x880\x92\xb6\xe0[a\xe1[\xd1\x8co\xa4\x1f!h8\x94\xf60cW\x9c&T\xbeD\xf5\xf0\xa6\xe2@hw]\x06~l\x913GgP\"x\x8a\xee\xbd\xba\x02\\\x98}\x89\xabb\x13pb\xb9\xe8\xeeT\x9b|\x02y\xf11/\xed>\xd0$Q\x81\xe8\x8eo\x8cK:@\xabzZ\x06\x0e\x9a\xbdQZ\xdfq4\x93\xa4?k\xfb\xa3|\x15M\x1c{\xb5\xfa\xea\xc8\xa0~\xef\xce\xfd\xb5\xc8\xa2\x877\xbc\xe8.O\xed\xe8\xb4\xd3\x8eN\xac\xf6}l:P\xa9\x8c\x8c\xf7\xd8\xa5s\xc4\x8e+|\x9b0\x08Hc\xd0}\x82\x14\x14\x06^Lz\xdaV\xd2(\x86\xdcA\x1d\xf7\xa0\x8b\x0886a.\xf3\x00\xf8\x8a& P\x89\x84\x15\xfaXmH\x15%\xa4\x1a\xc7V\xc7\xf4Mh\x145\x8c\xee==\xf0\xc9\xb71%r\x9e|\xa5\x85\x7fgJ\x94\x06\x9c\xad\nU\xf0\xe3\x06r\x84\x1d\xdb\x04\xc2\xbd\xd9\xab\xa3U' \xee\xddj\x1f\xabG\xc0F1\xb2\xd3\x03\x0c\xfb\x8b\x7f{\x0e\x9fc1J{a\x8d\x93\x9d8d\xc5\x97\xf4>\x12\x17\xe2m\xc8R\xfer\xc8f\"9\xe77\xcaf\x03*lq\xe2\xef\x0e\x1c\x11\xc6\xcdp\xeb2\xcf\x97\xd9\xca\xba\x92\xdc\xb6\x06\xa4\x91lnq\xb1x\xd7\x8bV\xccY\x9a\xa25\xcd\xebW\x95\x0dv\xcd\xdci\xc5\x92i\x9c\\\x7fD\xa3\"\n]\xda\xbe\xc1\xe5\xb7\xb1\xc6\xf0.\x10w\xed\xf2\xcaU\x06C \xf1\x04\xc3\x9aW\xf6B\x94\xfdL\xc5\xb1|\xff=(\x03>\x89\x98>\xeb-\xd7\x8b\"^-\xa8\xb4P\x15\x1e8\xc5=\x82X\xde\x94\xd9\xd8\"\xcc\x81B\x1b(\xf5\xd2UaGEu\xde\xba\xa3\xbbA&\xc4d\xdd\xe5 \xa9\xbb\x1cd#AhG\xe9\xe5\xff\xcb\xde\xbbv\xc7\x8d\x1b\x0d\xc2\xdf\xf3+J\xcc\xacCF4\xad\x8b\xc7c\xb7G\xd1\xeb\xb1\xe5\x8d\xb3\xe3\xcbZ\x9e\xe4\xeci+Z\xaa\x1b\xdd\xcd\x11\x9bdH\xb6de\xac\xe7\xb7\xbf\x07\x85\x0bA\x12 \xc0\xb6<\x93d\x1f|\xb0\xd5$\x88K\xa1P\xa8*\xd4\xe5\xac\x93\xc0\xa4\xd5\x92\xd2B\xdcn\xc1L\x89X\xd0\xcd\x0e\xb1\x8b\xa7\xf9\x197\xa4\xd2\x93\x02\xacPaLU2\xc7[\xf1\x0d\x9e\"\xed\xe7Gj\x82xQ:\x1a\x13\x137\"A\xc3\xa6\xde\x02O{r\xda\x01R\x907\xb3@&\xa0l\xdb!t\x87\xba\xa3#\xac\xb1\xe2k\xe2\xc7\xd3\xbd\xee\x17F\xcc\x12\x7f\xe9\x05\xef%\xa9\xff\x9cW5\x06Mq8\x9f\x84<\xc1b\x19\x99\xecA\xf3\x8c\xd9\x01Nz\xd6\x8c\xe2\x8d~\xb3q_xv\xb8\xf4\x97k\xf0\xc8]\xe7\x9b\xac\xfe\x1b\xeb\xcba\"\xe2\xa0U\xf6\xb6\x8e\xdd\xed\x8c\xbf\x07>QZ$\xc8\x9c1*\xc9\x92:\x89Sn\xb9*\x08\x07et2\x984!?\xf1\xbdI\x8f\xc9\x12\x8eU\xecs\x83\xaeP\xc2\x7fX\xcc\x17EXw\x8d%\x8e\xa20@\xf2\x10\xceoy\xe7\xec\"\xcf|~\xeb\x0e\x04\xdf\x85\xba\x9b\xd8\x0eP\xcd\xb9\xe3*.|\x1ec\xcb\x18\xd5\xe0\x96\x85\xaa5\xd9\xf9_\xc7\xd5kN\xbc'\x92\xa0\xd7\x0dA\xefch\xa8\xa6\x8d\xa8\xf9\x8eW\x13r\x1eu\x16\x99\xbe\xdc\xa0\xc9\xcfF\xb7\x8d\xc3\xee^e\xc1\xa3\xf1\xd3\xe7\xcc!\xc8\xb6\xc6\x06/\x0f\x15\x13\x87\xfa,\xf2\xaaf\xa0\xd7\xec-\xd3\xc6bVmZD\xb2n\xb1\xd6\xc8\x0cY\xe7\xa1e\"\xd6\xfe\\Y4{_Je8\xd2-\xb1\xbe\xdf\xd2N8\xc4\xde.\x99\x7f\xb6\x8da \xd9q\xaf\x19A\x08%Ztex\xb6i*42\xd3N\x0f\xbb\x8e\x07\x9amW\xa5]\x0c\xd5\x15?D>\x13\xaf\x17)G\xfe\xfa\xaaLm7\xb0m\xae\xe7u\x19O\xfbx\xbf\x1b\x91\x80g\xcdy\xd45q\xdc\xf0\xe7\xdd\xfb\x8c\x8a;:\xd3\x0e\x809<3\xdewx\x13 \x19\x93N<==\xb4\x96m\xd6\xab\xf7\x11\xcd\xfb<\x1c\x97\x91\x8fxz\xa2}\x91/\x8f\xee\x88\x98\xc7\x00\xf1\xd3\x0e^J\xb9\xccc\xd9\x92Zi\x8e\x86\xf4b\x86\xb3\x88)\xb1h\x03z\xb9S\xeb:\x84A\xfc4\xa1:z!=D\x11|\x8bI%\xbb\x17\xc2\x0cv]\xbc@Ax\xf9\x0eU\x80\x16\x0d\xa3\xbcu\xbc\xd6\xe6nP\x0bg\xab\x85\xf2\x18\x9e\xaf\xc8\xec\x12\x03K\xf1\xc05,\xf55\xe4\x0b\xf8\xbf\xe8\xa3\x05\xbb\xe0\xfd\xdfH/\x9a\x82Q\xb1\x03\x8a!\xb5A\xac\xf5\xf3\xe8<\xbf\xceHI \x87\xef\xed\x1f\xeeyMX\x89\x04\xd5\xc9\x13 \xf2\x10f6\xae\x98\x16MV,\xb6\xec\xc8\xb7\x1c\xc1\x86#\xdc\xab\xac&e\x16\xa72|\x8b\x8f\xc1%]<`\xc4\xac\x1a\x8cQ3p\xdd\xbb'NPf\xf5\xda\n\x95\xa5\xffF\x8dfK9\xc3&\xa4\x8c\xcb'%\x0b%(?\xea\x03\xc9g\x10\x088\x082r\x0d\x15\x9b\xae/~\xb3\x1a~\x1e\x04\x11\xe7\xb2)\xa3\x83\x87}\xd6zr\x04\x19C4\xbcr\xcb\xe7]r\xc16\xae)7\x99\xc7\x9c\x12\xba9\x89\xdb\x0b\xc3\x9d+s\x0c\x1c\xe1#\xb5G\xec\xd8\xf7\xc2\x86\x02\xb4q\\\xde^\x9c#\x00\xd1p\x8fy\x8f\xcbGk\x96\xc1\x97\xb9)w\xf3+\xd1\x92\xfb\x95\xea\xbf\x98t\x05\x86s\x16\xc9\xa1N0g\x8a\x1a\xe4l\x02\xcd\xadC7\x81,{\xf3uN\x92\xef\xbay\xd6\x94P\x17}\xd4\xfd\xf3\xdb\xd3\x0f=\xc7\x00Z\x9e\xbf}\xfd\xee\xed\xe9\xab\x0f'\x13\xd0\x88\x02'\xaf\xdf}\xf8?\x138\xe8\xbfY\x92\xfa\xc3M\xe1\xc4\xb8\xb7/~;'\x01\xdd\xe8\x11v\x83\xea\xea\xa4\xfak\x9c&s\x11\x15\n\xd1\xd6\xb0 \xf8\xbeN\"9\x05\x98@\x12\xd1\x99\x8a\xa4g\xa5\xef\x1d<\xd2'o\xec\x88\xd4\x067\xf1/\xb5=`\"x\x1f, f\xc68Y\x17\xf5\x8dD\xa4\x97\xf1\xac\xce\xcb\x1b'\x88R\x92o\x9bR\x1f;\xfa\x8d\xb1]\xe7\xd4\xa5\x90\xa7\xed\xb0l`\x90Dl\xa2\x94k8\x82<\xbcS\xd8\x9a7\x07\xdf\x05,Ve\x0f\nm\xf5\xf3\x95\xd6K\xdcpL\xd8\x00\xc5\x81\x94S\x04\xa7Tk\x9fR-\x86\xa9\xdc~\xc4v\xd5\xaf%\x83\x8e\xddb\x82ZK\xfbI\xf5\x01\xdd;\xc6M\xa8\x15\xc8&\x19l_\xac\xb7\xce\xd2\x88\xbd\xfc\x9f$#e2\x93cx\x9e\xc6\x95\xd5! \xf8\xd2j\xb0\xbeO\x9bX?\xad\x89:w\x92\xb8l-\xf9\xeb\xeby\x19\x9aQ\xfb\xe1#\xc6\xe1\xef\xf7rj\x08YB\x97\x81S\xec \xff\xa0\x9fiD\xd1\x94{\x91\xa7\x11,\xbc\x89\xe7.\x08H\x9c\xa1\xfc\x8b\x86\x7fW\xef\xceItIn\xe0\x18\xe2\x88T\xb3\xb8 >>\x08P\xc5T\xe7,G\xaa\x7f\xf8H57\x12\x7f\x8d\x89\xd9\xd51=\xa2\xc7\xc6\x9e\x92+\x9e\xa7\xa9\na\x16\xea\x13q\xd2E)BLr\xc2gQ\x1b\x04 %\xd2\x1e\xe5\x00\xd1\xb7\xcb\xbb`\x92\xaaxD\xf9\xaa\x9a\x13\xa2&\x94\x9a\x88\x94\xd10O\xbc\xae\xc26\x89'\x0dTy\x17u\xf4\xcd7|d\x18\xf4Or\xf83\x7f\x81 \xf1\x85p\xa2\x07\x8b\xc6\x0e\xa3\xf7\x84\x13\x94U\xeb\x05\x86\xda\xf0\xbc\xae\xb9\xc5\x97\xfaA\xb2\xd0\xa9h\xcb\xb2 \xa1\xc2tn3v(\xeeuo\x7f\x17\xec\xf6\xf7Q'\xe0%S\x7f\xe9N\xad\xc2\xec4\xfe\x92\xd7Q\x04lq\n\xf5\x177k\x02\xe4\x98\xf2\xa9\xf5?\xa2G\xbb\xb4!\xf6\x98\x07\x12\x06\x89\x0c\xa2\x92\x14i<#\xfe\x83\xe9\xc7\x8f\x7f\xff&\xfa\xe3\xee\xb1\x1fL?\x9e\xfdr\xfb\xf9\xec\xc12\x04\xef\xe3\xc7o\xeeyJ\xb5vW\x9f\xa5oT\x10\xfd\xf1\xd8?>\xfa\xf8\xf1\xa3\x1f|\xc6m\x1b\xed\xf2\x07g\x01\xb6\xf4\xcd~\xf4\xc7c\x86\x18\xdft\x03\xc2\xeb\xbd`\x85~\x8d\x8fV\xa7n\x96\x06|hF\xdc\x0d\x10?\x184X\xd8,\xef\xb7\xbf\xf9]\xff\xaf\x8e\xb2\xae\xe1*\xd8\x11\xb3(\xf3\xb5Qm\xf2:\xc6T\xde\x85\xff:.Z\x06|\xaf\xe3\xc2AQ\xd3\xaa\x85\xdbL\xb6\xd6y\x1e\x18\xdb8%5\xfb\xe8\x94\xd4\xad!\x9c\x92\xdaa\x08\xadZ\xca\x10\xfa\xcf{q\xa4\xaex\x92r*#\xbc\x8e\x8b>b\xae\xf8\xcbS\xd2am\x9c\x12\x9a\xcd\xa3\x8a\xd4\xecm{\x0d\xc3v\x0e\xea\xa1\xe5\x9fGK\xd2\xd7@\xb3D\xb8\xc3\x0d\xcc\xb9i\xa0\xe6\xe3\xd8\x16T\x8ew\xde\xe0\x8f?g4\xb4g\xa1\x85l\xf2\xf0@VQ<\x9fkF1\xecx\x0e<\x07\x83a\n\xd6\x98\x94\xfd)\xac\xf4Sh6\x94\x8e)\xba\xe2\x99\xe6\xbb\xee\x07\xc0\xb3\xf2\xe9\x9e/\xad\x13\x03Eg\x1a\xe9C\x1ai\xda\xbd\x19\xd3.&~~\x95\xd5>\xe1\x1e\x9b\xfe>ej\xf74\x8a\x8a-P[\\\xdf-\xb5T\xef\x8ae\xc8\xac\xc7c\xbd8s\xf4\xed\n\xab\x8bi}6~?\x0c7\xcd#.\xe9\x9av\xdd-*\xafq\x15D\xeb\xb8\xf0o\xb6\xd8.\xc3\xe3\\\xb3l\xf8\xddD\xf9.\xbb\xc9 \x00k\x0d\x00\\\xf7\x9a\n\x80\xb5\x1e\x00\xbf\xeb\xffE\x87E\x05\x85\xe9\x99\x8e/97\xf3%yo\x1eF\xf3\xa8+\x99\xc2y\xb6J\xd2\xf9\xab\x17:\x99\x0c\xc3Oe\xd2\xab\xfa|\x8c\xb5\xd7\xb5E\xc8\xf6>f\xd8G\xc6B\xd13\xcd\xffO\xd9e\x96_g\xc8s\xf8h\xc2\x0f~\\\x03c\x80\x16I\xca\xa2\xf2H\xd6\xe6\xef\xd1\x1f\xa7\x1f?~|p\xf6\x80Y\x1c\xef\x827au\xd3$#\xccM\x9a>\x0c<\x14<\xb19\xa69\x9b\xc3\xc5\x0d6\x9b\xc9\xf7\xaa\xf3\x87nB'}\xb8k\xf4\x05\xde\xef\xc9\xba\xa8o\xb0\xc1q\xf7\x1b\xde\xefk\xf2\xa96}(\xd4\xd8\xfc\x8f \xff#\x9a'U\x91\xc6hY\xca\xdc\x98\xf0i\xc6\x7fJ\x80\x0e\xce\xec\x93\x01\xa3B\xc4\x90Sz\xde\xbeh\xba\xd1Z\x97\x94\xa2b\xa3\x91\xefW\xcaE\xa5\xb7\xd7\x19)_\xbd\xe8a\xab\xd4\x8b\xa2\xe5\x8c\xae\xef<\x08B\xb8\xc6\xfc\x91\x80\xb1\xc8\xcf\xab|S\xce\xda\x1cE{'\x9d\xf6\xb4\xb6yvJXH\x9d\x92dcL\xab\xf4\xd6\x92\x14\xd03\xdf\xdb\x7f\x88\xd1\x923\xb9\xa1\xe8\xee\xeaW\x97\x92z\xc9$\xf5\xb2\xa5\xbe(\x87-\nY\x8e\xb9\xd2\x90Z\x1f\xb8\x0e/\xf7\x13\x93m\xa1\x1ck+:\x7f\xdc\x8cY\xaf\x8c\x8b#\xc2\x83\xf9(\xcch\xeb!6\xbaO\x1b\x8d\xa3\xa4z\x9do2\xba\xc9Xo\xdf\xed\xb7;+\xe2\x92d57\x90R~\x1ea\x8cr\xe5\x01^\x8e\xca\xd6\x0f<&\xec\xc9\xf7.\x176\x1d\xd5h\xf6\x03Y\xe4%y\xdd\xbaAu3\xe7/}c\xb8H\x0e\x87 h2\xaf\x03FSc\x03\x9e@\xa6\xaf\xc0\xec\x9e\xcc\xf6oby&05\xac\xbd\x84\xb9\xd9V\x8f\xc55\xe4\xc1s\xc6Z#\n\xc8\xfd\xc4\x1b\xd1\x83n\x9b\xddC1JA\x194\xfe\x91\x98\xd5\x8bb\xd5\x1b\x96y)\x87N|\xfd`\xea\xf6V\xae\x95a1\x97Va\xf1\xa6b\xf0\xc6r\x95\x92g\x030\xdbf\x8c\xa8\xc7m\x01\xac\x8e\x94\xb5\xdd\xdd\xb5\x8c&[\xdf)\xc8X\xa4\xc7\x16\xa4\xf6\xf5\x90\xaa|\xa2K\xc7x!\x82\xf7\x0f\x8d\xbb\xd8\x94K\xc2\x87N\xe6r\xf0\x95\xc5\xd5\x14\xc3j\x9eF\xe7EI\xaeHV\xbf\xdb\x94\xcb$3*j[\xc9\x94\xf6\x9e\x02\x81\xef\xe1B\xd2fb\xa6\xcd\xb4\x9c\xfb\x17Sr\xe6\xaa8\x03\x9c\xf8@\xd0\xfa\xe1[\xdaf\xb7\x7f\xc9\xe2 \x85\xcaN\x17\xa9\x86\xfa^\x92\xfa9\x8f\xecW\xc7\xb3\xcbg\xf39\xc9\xe6\x9b\xb5\xebHtVO\x836L\x82~\x9c\x0c\x86\xaf.\x99\xe5$Z\n\xe9\xcf\xbe\x1av\x8f\x18\xeb@\x1a\xae\x81s\x11\xd2*\xcav\x9e\x80\xa2\xe4Z\x88\x08\x87\x06\x8aL\xc1N\x9b\xcf\xa3\xf39\xb9\xd8,_\xbd0\xae\x00\x8e\x0d\x99\x9d\x16L\x7f\xb8y\xf5B\xc4\x9c\x17EcB\xdb\xfd\xc4\xb6\x14\x12\xcd\xf9z\x00y\x1a\xb0!|B\x8e\x9f\x08\xce\xeb\x1d\xdf\xbcC\xc8\xd3\x15i{\xb8\"\x8f.7\xfc\x18\xc4T*\x124\x12\x0b\xa6\xf5\xb4t\xaf0\x8f\xae#\xe8\xf0\xb1\x83\x839q\xf3)n\x1at\x1d\x84\x03\x18\xc4\x19\xe9\xd4=g\xb9]\xbbw\x87\x01\x12\x0e\xb6\xefpT\xecO\x89\xf2n\xa3{'\x19$\xb7\xe19@G\x1e\xcfk$Gi\xff\x15Y&UMJ\xc2\xe8U\xdc\xe5@\xaa\xd5\x9b<;\xad\xe3l\x1e\x97\xf3\xbf\xc5e\x96dK$\xbe\x0e\\\xb0\xf1FB\xa4>,I(\xf2\xc2N\xaat\xd8\xecH\xa2N2\x94;\xb5/\xc6\x86\xda?\xc5\xa7\xdb\x1b\x010G\x97\xeeu\xbf\xde\x9e\x969\x1b\xba\xe9{\xa09gH\x14\xcf\xe7'T\x80\xfc\x91{+2'\xa8\xeeSn\x1e\xb6\xb3\xaf\xb5\xadn\x1a]\xe7Wc\xd2\x8a\x08\xff{C_c1\x90\xc5\x9b\x881\xa4'6\xc9'\xd3<\xf0=\x8a\x00\xbb\x0c4w<\x959\xd1w\xb3\xcd,L~\xb5\xfd\xed?\x8b\x8bzS:\x06\xee\x80\xedW~\xef\xae\xc15\xb0\xf2\x9a\x8bKQ\x06`f\x1f]\xa9\xff\xd8\x05\xcc%\xe7\xa0^\x88$\xba\xeaL\x8d\xe6\xdf\xad\x84kwA\x0d\x1e\x1f\xe8\xc2\xf8\xd1\xe7\xfaP\x11\x87\x8f\xba\x99\x00\xb8[\xddw\x07A\xbb\xfd\x8d.M/\xf3aM\xf2\xecy\\\xc4\x17I\x9a\xd4\x89=u\xc2\xd5\x97&\xa0\x80\x8e\x14\xe6\xb7SQ\xdc\xbb\xc7\xb2Ox<\x8d\x00^\x1b}\xfe\xdcKI\xc1\x9e\x95\x1b\"*\xceXL\xff\x93yR\xc7\x17]\xa7`\x93\x03o\x92g\xaf\xb2E^\xb2(\xf4\x16\x0c\x17\x1a\xb6x`Jz4\xc5\x18\xfb\x04\xdd>\x8c)\xbe+1\xa0\xf7\xccc\x1c\x03\x1cj\x97\xc8G\xb7\x91M\xa4\xce\xc2'Zy\x1el'nI\xaa:/\x89l\xc7i\xf9\xd9\x05[lJ\xda\xc3tZ\xca\x9c\x0d\x13\xc6j\xedi\xeb\x14\xed;G\x9c\xe9\xc7\xab\xb52\x84\xdc7\xe5l`\xa1\xe30!\x90\x19z%\xd6\xd8D\x95\n\xbe2\x84*\x08!\xf1\xcb\xe1\xd0E*\xcc\x9d`\xa5\xd7\x1azr\xda\x18l\x1e\x13Q\x90\x007\x96\x1e\x83*\x16\x93^\x81\x17~\xa8\x87,\xc9\xe6\xad\xaa'\xd9\xbc\x8f\x15\xfd\x81I\xebP ^\xd9B\x7f\xb3\xab\xbb\xd6\xb4\xf1m\x12a\xbf\x1f\xee'\x87\xb8`\xf2\xf5\xcc\xb8\x8eD\x08*\x01\xf7\xb4\x12\x18b>)8\x10\xefg\x11=1\x10\x80\xbe7[\xc5e<\xabI\xe9\x85p\x9f\xa7\xf9\xe2\n\xee\x01\xb1\x04A\xcc\x1b\xa2\xcc\xe3`3\xdaV4Y\xfa\xb9\xddR-\xd2]\xbd\xc5\x98\xf7\xd5\xb0*\xe1\xf3\xe7a\x941\x98\xb8\xe3\x04F\xaa\xef+\x03\xf2[n\xd0\xea\xa82\xe3*3\xbb$\x99&\xd6\x15E\xc5V\xaa\x7f\x91\xb6\x9b2w\x86\x1d\xd4\xdd \xb4v\xd8\xd9\x0bp\x04\xaf\xe3z\x15\xad\x93\xccG\xa7\xad\xd6b\xfd\xc6\xfb\x02\x1dt\xf86\xf8@>\xd5\x83[!\x89fy\x9a\xc6EE|d\xe1\x12\x13bg\xf2e\x0fYs\xb8\xcf_\xb3Y\xe9\x12\xcf\x8aH[\x95\x82\x93CQ\x94\xf4<\x12\xcb/\xb8\x15\x8f\xe4\x96\xe2\xa6\x830>\x01\xee\x8d\xd9q\\\x11\x02\xa2XO8n\xfe\x14\xdcy\xd0\x84\xe2\xeb+B\xf5\xea\xa5\x86\xf7\x9e\xd5\xc9\x15Q\xf2\x08\x91\xe8\"\x9fwRH \x81z(\xbc\x8f\xee\xbb\xdf\xb5\xff\xda\n\x9cW6\xef\xdb\xc7z\x86\xb3\x17f:\xd6\xfb\xea\xb2(\x0e\xfb\xdfv\x1b\xafZ.^}\x0f\xaf\x94\xf5\xf2\xb0+\x15\xcf\xf8\xf3n?\xcc8\xfe\xf0\xdb\xee\xf3\x82\xcf\xad\x1bub\xce\xfa\x17\xe1\xb0\x1f>\xea\x0e`\xc5:z\xdcy|\x85\x8f\x0f\x0e\xba\xe3Z\x8364\xdb\x92u\xdf\xcb\xdfu\xc3\xb9\xf6n3\x17\xaa\x03\xdb\xfe\xc3'\xddQ\x9d\xf3\xee\xbb\xd3\xb9n\x1c\xdb\x92~\x00\xe4N\xe5\x13\x8cQ\xa6\x8b\x1f\xdc\xaa\xf6 \x8e\xba\x9e\xd2\xa7p\x04O\xda\x8f\x9e\xd3Z\x9dj\x97\xc68\xde\xcf\x8c&h\xcc4L&\xcf\xa2\xbb\xf6\x14\x1fu\x93qMZ)\xc8\xba\xac\xae\xce:\xec\xad\xb9Sz\xb6\xca\xa0\x80\x8c\x84\xabO\xfck\x96\x8ew\xd8\xfa\xec\x9d\xd8n!\xf2\xa4\xdd\xbe\x90\x96\xb7\xa9\x06%O\x8b\xa8\x9f5\xdbtv\xc6\xe6\xe8=\xec.\xd1\x14\xf2\x03\x8e\xc0C/~\x16\x8ck\xc2L\x155w$1\x1cC\x0c\x13\x88\xbb\xf6x1\x9a\xe2\x05\xa1T\x95\xd5\xc9\x9a\xf4\xaet{\x13\xa6\xfb~\xd5\x89\xf3@\xc1\x94\x85<6\x01w\xa9D\x07\x98n\xf8\xa8DU\xcd\xd1\xfe\xe8Q\x95`\xc8\x81s\x16\xbdC1\xa0\x88\xcek\x0eD\x1e\x0e\x89e\x87\xffQ\x8d\x88\xf0*\xabsLa\xbd\xc1\x85\"\xb8P\xd9\xb0\xb5\xe4\x07eUuKJ\xc9\xe3:B\xe0\xbe'\xb3<\x9b%)\xf9P\xc6Y\x153\xfeuI\xeawy\x9e\x92\xb9\xbf\x83\xcc\xc1,\xdaT\xe49\x9e\xe6|\x01;\xb3\xce\xa3\x82\x94T\x02\xf5\xdf \xb1\x11\xe4|\x10\xe1`\x7f%I \xe5)\xf2\xe1i\xbd6\xe9\x8d\xf0*d/\x84U\xb4\xc94\xeb\x86\xd6D\x9d\xed)\xf8\xec\x9e\xf4\x15<\x85\xbaI\xfb\xf74\x80\x9a\xab\x81\xf0\xb7\xaf\xbc\x1b\x1e\xec+\xb3\xa5\xf0\xb3\xf1\x96\xc2U\xa4\xcbj\xae\xf3Q\x13f%t\xe9>\x7f\x86\x9d,:_\xe5\x15\xbf\xdb\x18cC\xfc\xb3\x91\xf4\xec\xf8;\xdc\xdeU\x02u\x07\xfd\xde$\x1f)\x9f\x9dj\x9e=\x1f\x06\xdc\x1b3\xe0\x1c$U\x0e^=\x9b\xce.\x88\xef\xdd\x1b\x0fN\xdc\x06mX\xf20{\xfd\x9bW\x93e-\xbb\xf6\xc2\x16\x9e\xe7Y\x1d'\x19)_e\x8b\xbcO\x05z\x07\x83\xf8\x8bN\xf1}\xffl{a\xb3\x88\xc7\x08R%^\xbe\xc2\x11\xbc\xefZ\xa95\xc3}\xa1\xf8(%U;\x88\n\x0f\xe7\xf9\xa2\x15\xd9\x06\xe3\x11\x0d\xf4.\xe6N\x07\xa0\x10\xfdfn\xb4A\xde\xd3\x87\x1e1T#\x82\xd2\xb9\xff\xd8\x93\x8c;\xdfL\xe0E\x87\xeb\x10A\x11\xaa\x1fn\x18\x01B(L\xe0\xb2\xc3\xd4a\xa2\xd4\xd7y\x96\xd4\xb9K\xc4\xc7\xae\x84\xd1\x112\xcf\xd9\xbd8\xedl\xc0\xd2U\x7f\xe8B\x03\xb6\x1f\xa3\xd6\xb8\xfc2\xb4\xab\xaf\xaf\"\x92\xfdcC6\x82T\x8b\x00\x19\x92x\x86L\x08\x95\xf5\x9e\xc7iz\x11\xcf.\xd5\x8a\xb9F~\xa2\x87\xd8\xe0\x9c\x196\xbc!\xd7\xd6ik\xe7\xfc3\xcf\x19R\xfa\xde\xe1w^\x10\xc2&\"Y\xb5)\x89\x92\x14\x97\x03\x02\x93J\xf77\xab\x10=1\xde<\xc6\x13\xee\xd6XG\x17T`!sf\x0dQ\xf9\x1f\xd0\xacY\x8cJ\xdf$\x0b\x8c+1\x89o$#\xad\xb8\x9c\xc6g\xf4\x8bp8\n\x07\x83\xd6\xe9\xe6\xa2. \x9e\xf2\x92(8C\xacc\xc6\x82\\`\x11\xadbT\xaerH>\xa6\x90\xfcQ0\x1f\xba\xee\xd4N\x1c\xd6\xf7\x8bF|\x15]\xc5i\x82&#\x1c\xeb\xfc<\xe4|\xde\x8b\xb7\xaf9A\x11\x96\xec\xad0C\x0dr<\xf1B\x93\xad\x8c\x07\x94\xaa\x93\x18\x83\xa3\x15qU%\xd9\x12b`\x95!M. \xfca\x9e\\\xfd!\xc4\x97\x80\xfdr=\x85\xe8\x07\xdf\x07\x90\x97\xf0\xfd<\xb9\x82\x07\x7f\x8a\xd0-DL\xd0\xb1\xc7YJ\xdb\xc7\x0e_\xe6\xf9@w/\xf3\x9cu\xf62\xcfEg\x99\x1a\x03Z\x89U\xc6\xf9f\xec\xf5\xc3*\xa9`\x1d\xdf\xc0\x05\x81Y\xbc\xa9\x98W\xcd&K\xf0\x02!\xc9\xb38Mo \xcd\xe39\x1dP}\x9dC\x92\xcdIA\xe1\x9b\xd50\xcb\x8b\x84Tt\xc8lL\xdc\x07\xc7\xb0\xa5\x98\x9fX\xdc\x19\xf9\x0b\xd3m\x1bR\xf8 h\xe2\x9ci:\xb0\x9a\x9fRq\xbb\xe0n\xa7\x06\x05\x122H\xe7E\x99\xcfHU!o\xc6\xc3\x99\xfaUt>c\x7f\x1a\x15B\xf4\xeb\xa5~\xe2T\x92\x7f\xe3\xeb\xf2d`\x12\x8c\xa1QSa?\x1d\x12{\x0cSY\x80\x7f\xee\xcf\xd8\x15\x80Y\x07L{X\xb0\x1e\xfaB\x05\xe5\xde7\x17i2\x93\xf1\xbb-\x96)sa,k=[\xd4\x9237\xf3\x85\xf9\"\x14@\xab\xa1\x17E\x9eq\xba\xc3\xd2O1\xac@\x82\xa4d\x1e\x84\xb0\xd0\xb6\xa3\xbfk\xfd\xb1'\x07<\xc3\xd8xvS\x0e\xe0\xc0]!\x1f\x99\x19\x00\xb7\xa6\x12\"r\x84;o}\x93\x82\xfd\x06\x8e\xe0\x95\xb1\x89\x0b*\x82a\x13)\xfe\xab C\x00\\9\"\x89w\xf7d\xa5\"a\x16\xc2E\x08I\xe0\x88\x08\xc6C\x8b\x1bK\xe3\x92^\x07!\\\xdb\x8f.\xb7\xfb\xfcf\x95\x07N Ud\x1c\xce\x08\xa2_X\xdb%\xd6\xcf\xcd\x81\xf8p\xcfD\xe6j\xdc\xed:\"\x83\x8e\x0c\xc6T\xb5\xaf\xd0n{_Q\x96\x7f\xe0\x01\x020\xd4D\xa3\x9191\xd0/!V\xed; '\xaf\xcb\xddc/\xa7u\x8f/9\x0b\xfb\\\xcek\xa1;@\xeb\x98\x9e\xb7n\xeb\xa7F\xf7\xa0;\xde\x93\x10b\x1dD(\xac\x14N\x8e\xb9\xa5\x0d\x86c\xdd\xe0^\x1b\n\xee3\x8ffq\xf6\x9el*\x9e\x19\x8a\x8eb\xd3\xc92C\xc5\x0b2\x8bg+\xc2v:\xad\xa1oQP\xf6M[_6\x8f\x9e\xff\xf9\xe4\xf9\xff:\xfd\xe95\xaa\x16\x99\xf6Q\xdf\xc2\xa6\x97\x93c\xc4\xc7\xe2t\xd8D\xf9\xa6&\xe5\x9f?\xbc\xfe\xd1\xd4Ke\x1b_\x08\xdd\xa8\xbc\xa2\x88\x13b \xb5Q\xe1\xe2Y\xaf\x16\xe9\xba\x90\xa9\x97O\xe2\xce)\x94\x9e\x94A\xa8\xfaWf\xcc\xb1r\xb0e\x10\x8c\x80H\xf5\\\x06\x9c\xe1\x91\xbf\xe5j\x1b\x1c\xec\x85P\xc0.\x1c\xec\xa1S\xf4\xc7\x0c\xfc\x8a\x94W\xa4d\xd5g\xe6\xea\xfa\x99\xe9tWtg\x1dx!h\xaee\xfb4\x03\xb5K\x86F\x0e\x19\xaf\xdd\xd3\xef\x19P\x81\x07\x98r\xd5\x90\xe9'\x94GIV\x91\xb2\xfeP\x12\xc2\x1c\x1b}F\x9d\xe81`\xe4\xd3.X\n\x80P\xb3\xd3kE\xab>\xf2:\xefG|\xfa\x85\xf7O\x87\x8f\xbe\x0d\xf4\xcd\x9b\x8f\xa5\xc6\x0fH\x03$TM*\x1a\xe37|\xed\x98\x95@\xd9DS}\x1a\xa01\x8fN\xb9l\xd0A\xb1\x060\x00\xeb\xb1\xf6;\x98\xc8Z,\xe4+\xcf\xeb\xd7\xb3\xf8\xfb\x82\xab\xbb::?'\xd5\xeb|\xbeI\x89F\xcd\xc3C\xb2f~\xf7\xea\x0d\xc3\xe7b\xbc|4\x7f)\xd5f\x8e\xa1\xd4Z\xd8\xcd\x859\\\xdb\xb4\xeeV\x1d\x0d\xaf\x83r>\xff;\xaaVqA:f\xd3t\xe7\xce\xca\xe4\x82L\x94\x8at\xfa\xa8\xc2\xfa\xc7&)\xc9\xbc=\xe2yR\x15\xf4,v\xfe\x80\xf9\x94\xd5C=4+\x10\xdc\xe1\x12\x84-8\x98\x11W\x7f\x0b\xcd\xaf<\xc0\x14\x16I\\\x89\x90\xb2\xccK\xf5\x8e\x04\x1f\xf4\xb8.\xfd\xddt\xbd*\xf3k\x8c\x80t\xc2\xbfj/\xa9\xde\xbc\xdb O\x95\xcb\xe4\xc7\xdd\x1bJ~\x9b\xdc\xb3S\x14\xa9\xae\xba7\xa41\xaf\xdf\xc5\xde\x0d\x7f\xdem\xbf\xe2\xcf\xbb\x17\xc0\xfc\"\xb9\x97^\x80_$\xf7\xd2\x0b,\xf8\xf3\xee\xc5/\xbbH>x\xa2\xbbH\xce\xfc\xc3\xc7\xddy\xb1\xfb\xe3\xfd\xc3n\xfbW\xbc\xfd\xee\xb5\xfa\x9a_\xabw\xdbY\xf2\xe7\xddy\xb1\x1b\xe4\xde=\xf4\x05\x07\x7fw\xba\xe7\xbc\x99\xeep\xae\xf9\xf05W\xc4\xb4zw\x94\x9f\xf0y\xef\xda\xfa\xb4\xafN\x7f\x0eG\xddh\xda\x97p\x04\x0f\xdb\x8f\x9eQN@\x04\x00|V.\xf1\x12\xa9:\xebD\x18|\xab\xd6\x12\xa1\xeb\xba\x95\xde\xa9\x950\xf4n\\\xe7\xa5\xa9\xf6\x07\xb5\xb6\x88<\xd8\xae\xf2\x9a\xdfb\xcb\xdf\xd3gg\x94g\x9b*\x03.\xe3\x9b3O\xf7\xf4\x87\xcdbA\xca\xde\xbb\x17q\x1d\xff5!\xd7\xbd\x17<\xc7\x87\xee\x03\xd2{\xf82\xcd\xe3\xfa\xf0@\xdf=\xbe|\xf4P\xff\xf2UV?6\xbe\xd9\x7fd|e\xea\xecu\\\xf4\x9e1\x17\x14\xf1\xf8C\xe7-\x8b \xd8\xfb\xe8\x94\xd4\xfdg\xc8\xdf\xf5\x1f\xdf\xac/\xf2\xb4\xf7\xf8\xa7\xc487|\xf5<\x8d\xd7\x05\x99\x9bk\x98\xa6O\xdf\xb5\xe6O\xc9\xbc\xf2\x1e\xc9\xa8\xf8\xeam\xe7\xe3\xbf\x91\xf8R\x02ig?\xd4262,\xef\xab\x10~\x0e\xe1M\x08\xefu\xb7w/B\xbc\xbb\xc9\xe0\x1e\x9c\xf6\x99\xeb\x9f\xf8\xab\xe7\xfdW\xff\xe0\xaf.\xdb\xe7\x03ei_\xe1%\xee\x0b*\xb5\xc31\xbc\xa2\xe3\x90#\x98\xd0\xdfA\x10\xaa\xda\xd3\x17R\x84x\xd1ol\xe7Z\xcd[\xdaa\x9e\xe8\x0c^\xe2\xbdBWJ\xa5\x9f\xbe4\x89\xc1thW~M%\xee\x1fe\xd3\x18\xd5\xf7E\xf7\xe02\xc4\xbf\xa5\x1d\xff\x13\x8e`E[\xe9\xbd\xa5\xe5\x078\xa25\x8e\xe0-\x15\xb8\xf1\xafwz\x05\xc6\x85:\xc1\x8a\x8e\xe2G\x83\xaa\x03[\xf9 \xdb{F\xff\xfa\x01\xb5ToLr\x81\x98\xeeO\xac\xee1\xfcr\x0b\x13Xv'\xff\x13\x1c\xc3\x82v\xbd\xf1_0\x1d\xe7\x04f\xf4w\xcc\x7f\xf7\x1a7\x82F\xf4\xba\xf3z\xfa\xcf3\xd9\xc1\x1b\xee/\xfb\x8bA\xefH\xc7\xb8\xa6\x1d\xfe\x93N\xbf\xdf\xdb\xef\xcc\xbf\xde\xa3\x0d\xde{`!\x18\xcb\xa0\x8f\"\x7f\x85#x\x8f\x9aj\x1d\x9a\xfcU\x0e\xf2\xaf\xfd\x97\xef16#bF\x88~\xed\x0d*\xca\x08`\x92}\xe9\xd9t\x00\xde\xdcbXC\xbf\x14\xbb\xb1D&\xe7}\xd7\x12<\x08u\xe8\x7fn\xeb\xd2p\x9f\xf3\x02\xc7\x9d\x87\xa0t\x9c\xbbvLa\xf6g8\x82\x7f\xc01b\xc6\x1c&P\xc0\x04\xff\xbe$7\xd5\xab\x0c\x03\xe2\xf6:\xfd\x1b\x1c\xc1K8\x16{{\x02\x7f\xee\x01\\h5\xfd\xbf\xd1U\xab\x15\xde\xcf4\x93\xbf!5)1\xc6\x13z\xe8\x9e\xa1%\xfd\x0b\x9c\x8f\xdb\xec\xe4\x93\x91\x1c\xe7\xc1\x93.\x87$8N}\"\xaa\xef\x1e\x8f\x9669<\x12\xe6u\x81W~;\x18Z\xbc\x95\xeb`\xe4\xb8\xf7\x1f\x1b\x92\xc2\x1ety2\xce)?\xd6g\x85=x\xd2}\xbei\xc2\xf62\x0f[\x11A\x97\x1d\xa0\x15%#\x83\n\xdfV\x94\x8d\xe9\x19\x8b\xb2\x81\xce[\x14\x04<\xcc\xc6\xb0{{{}a\x02\xb1\x1e\xe8N\x06\xc1\xeab\xeb\x81v\xd8cX\xb9{\xd4\xf6\xab\x8d\xcb\x9c\xb4\xaeuG\xae\xf0\xe3\xc7z\xcc<\xec\xc9H|\xb0\x8f\x0f\xb7\x1dl\xe2+\xa9\xa0\x99\xc9\x18&\xec\xf7\xbe`\xf0]4\xcc\xa5\xde2\xfed\x1b\xa6\xfeF\xa3Q\xa3@\xaeZi\xd7\xa8L\xe1Z\xc6\xfb\xb0\x0f\x13\xc0\xe0\xfd}\xe2e\xbdc\x93\xa8KA\x1a\x0b\xb9\x82\xc5\xfd\xbc\xbf\xcf\xaebs?i:c\x1d\xa1\x14\xc9\x82\xf7o\x82\xa7\xb0\xbb\x1b\xc3\xf7\xb0y\x1a@\xc5\xcd\x11\xa65\xecB|\xa6?\x17Y\xe3\xfawr@\xa9\xec\x816\xb5/{\xa9\x9f\x06\x90\x8a^L=\x08\xf6\x87\x05\x0c\xcd\xfc\nS\x8a\x11\x96S3\x04\x9d\xdeo\xfb\x85\xefn%a\x0f\xbe\x1f\xf8\xa5\x01A\xbf\xc0\xf7\x91S*\xa6\x15i\x12\xab\x87\xe05*\x16\xaf{Y\xce\xb3\xd3*w1\xb7\x81A\x05c@B\x0d\xd5\xcbzZ\xae\xa6\xf5\xa7=H\x99\xf7$\xea\xe2\xd9\x0dV3\x05\xc9\x1f\x90\xfe1^w\x04N\xd1\x884M\xe9/\xafr\x9b\xc0\xbc^,q\xdayTs\\\x11\xb4\xdedQ}\xc94;3\xd8\xdb)\xb0\xa4k\xd9\x80\xc2\xcf\xfc\xfd'\x07\xc1\x17h\xcf\xbe\xf6\x92\x1bM \xf54\x03\xc3\x88\x18\xbd\xa4\x92l\x91k3\x87\xd1\x92\xe6Km\xee0\xc0\x94\xb5e6\x81C\xfdKT\xdcM\xe0a\xef\xa5\xc659\xb3\x1ao\x82\xb2nSrF\xb9\xb6\xfb\x9a\xfb\xd0~\xd3\xccOs\x96g\x8bdYEi\xbeDs\xc0~=F\x02J5\xdb\x00\xa8f\xa7\x89\x8d\x91`\x97Z\x92 \xcb[\xafDR\xc5\x12\xfe\x04\xfb\xa8\x87f'\x00\xa5\xca\x94\xb0\xee?\x05J&\xcb\xa7\x10\xef\xee\x06\x94F\xd2\ngjkZ\xb2\x89\xa0\xfa\xd3\x91\x12\x92\x95+M\x83)9\x8b\xe2\xa2H\x11\xe5\x06\x0d\xda\xc5\xe9\x1a\xd1\xb5D\xfd6&)f\x17\xee\x1e}\x88\xf7\xb3\\/\xdb}\x8fOY\x05\x8aD\xbd\xf7\xf4!{\x8d\x18\xd8{\x8fO=\xad[>^Vc\x0e\xa8\xca\xe4\x17\x8f\xa8\x99\xf4\x91\xc00]\xa7S\xc2\x9a\x07\x8e21]M\xe3\xd7\xb9vpc\x8f\xc4\xc6\x978\xae\xa5u\xfa\xb3\xc0\xc0`\x90\xce}\xc4:\xbe$\x7f\xae\xeb\xc2\xa7\xc4\x97\xbc\xa4\xaf)Y*\xf2\xaa\xc6\x1f\x06\xd5\xc3\xc5&I\xe7\xef\xc9?6\xa4\xaa\xd5\xe6\xd4\xe7\x06\xd2\xc1r{\xab\x1f\xf1G\xfa\xfa%\xa9\xf2\xf4\xaaU\x9f?\x1a\xac\xcfMM4\x9f\xf17\xfa\xaf+R&q\x9a\xfc\x93\xbc'\x95\xfa\xad\xfa\\\xffe^\xbc\x9a\xab_\xacHZ\x90\xb2\x8a\xe8\xf3\xbbEc7\xdc\x91\xc4\xad\xd6\xeb\x0c\xf0\x84\x9e\x96\x8d\xfa\x84\xfe\x10-\xf7\xe9\xd1\x15w\x1d\xa1\xb5\x8cGQ2\x81\xd2p\xd2\x98\xa3\xe3\xf2.'\xba\xa8<\x1aM\x8e\xe0C\xe8h\x91+\xc8\xc5\xa0Q>W~\xa1\x97N\x94r\xcd\xa7|a\x00=\xf0If\x1anF2\x15k\xceNDx\x0d\x83\xe7wGp\xd0\xb9\xdd\x00^\xb9\xe5\x9c\x7f\xf9\xfc\xd9\xc0A\xb0\xaf\xf5\x90e\xfb\x7fS\xc6\x17)\x19\x00e\xb6Y\x13Q\xc7\xc0\x10,I\x8f.\x01h\x82\x10C\x1d\xd9On\x01\xb0\x1e\xbf\xa8\n\xe9\x96#\x9f\x88-\xd3\x1f\x138Dl\x11\xad\x8c\xc0\x9d:\x9a\xfbY\x08^\xcc\xfd\x8a\xb3\xfe\xd4s\x17\xfb\x18\xde\x9c+\xef\xdaO\xbdRG\x05KL\x05\xb5_Gt?\x1f\x1c*\"\xaf?\x1d\x1c\x82J\x072\xff\xe1\x81\xf2e8<\xf8\xce\x97\xdfn\xfbek\xb4\xe3\xbe\xdc\xba\xcf\xc3\xc3\xc7\xe6O5R{\xfb\xd0o\xbd\x92$\xb2\xd4c\xb7@-\x0dr\x13c@\x1fy\xf6\xdb\x93T\xea\x07\x93\x1b\xf1M\xec\xb6.\x1f\n\x7f\x82\x83\x8e\xb5x\xc3\\\x1e\x9c\xc1q\xfb\xe7\xc4\x98\n\x8d\xb29\xbe\xa6\xf5Cc\xeb\x87\xed\xd6\x0f\xcfP\xff\x1eDW\x07o\x0bRbL\x9aWh^\x12\xd7 \xc6/\xb9y\x9d\xcf5\x1e\x9f*\xa8[\xa9\xddTE\x0b&kP,\x10&\xe8\xf87\x13\xf4#\xf0I\x10\xb0(Qy\xd39s\x84U\xd2r}\xac0\xc7\x96\x174\x86a\xab\xf6'\x01L \xe1W[\xfaE\x1e\x9e\x9e\x9e\xbej\xfd\xc5\xcc\x02\xc9@8K\xdd\x12\x8dC\x00\xfb\x12\x99\xc8\xad\xc0A\xbfnG\x84\x80]\xf0\xce1}P+QZ\xb5\xf3\xff\xfd\xfe\x9b\xff\xf1\xf7{\x7f\xf4\x83\xf3\xdd\xa3\xe9/\x1f\xcfn\x9fN\xbe\xff\xd3\xe7\xe8\xe3\x83\xe3\xf0\xe3\xc7?x\xde}\x96<\xed\\g\x99\x0b\x0df\xb0\\\xe8\xcc\xf3\xb0\xb1\xa1\xdbo\xfa\xad\x95~}\xff<\xf8\xe5 \xbc\x0dD\xd3J\xe6\x12\xff<\xf8\xa3@\x80\xe6\x83\xe9\xf9Y\xf0\xc7o\xf8s\xcb\xc6UF\x851X\xe7~M\x87\xd1\x0f\xa4nX\xdc\xd8v\xa0\xf0\x06\xbd\xfb\xfdtL\xa667\xb66+N\x1fw\xf6\x90\x03q\xc6\xc4\xcaDWA\xdc\xc1\xb1\xe0Vb\xcf\xeel\xb3g?\x7f\x86\x1d\x12\x15q\xbd\xaa\xfa\x8du\xaa\xb3jC\xb1-@Qs\xf1\xea\xfd\nR\xb6\xcf!\xc9\xa0\xd4\x9b\xa8*\xeaXZi\x9a\x1b\xa2\xcc\x03\x87\x85\xf7\xee\xd9\xfbg\xafO>\x9c\xbc?e\x83O\xa2:\xff\xa9(laSD\xb9\xe2\x0eg\xb4\xa7ibP\xa6\x8aB;\x8c\x07\xe9el\x83}\x1cX\x87\x04\xd0\x18j\xdbk\x8aR\x15df\x8c\x13\xa6+t\x95XX\xd1\xdc\xfd\xa35\xa9W9\n]-(\xbb7 i\xfed \x9c\xa8Z4:(]\xc1\x0c4\xbe\xc9\x06]-(\x85\xa1W\xb2D\xe8\xcd\xe0Gz\xa7\x97\xfe\x9b\xf6\xaf\xadT\x96\xa0U[b\xe3\x9a\x0bp*g\x95~\xe6\xef?\xee\x06\xff\x00n\xb6\x86o\xbby(\xea(\xa9\xde>;=t\x125\x98.$/H\x16\x17\x89\x91\x89\xe0Y\x15(\xae\x17\x0d\xae\xd3\xc9\x1ez\x1a\x16<\xa9N\xaf\xe3\xe5\x92\x94\x07#\xc6P\xb1O\xb6\x18\xc3\x81n\x0cy\xf1j\xce\x12\xf0\xd7Q2\x7fY\xe6\xebwq\xbdz\x8d\xf8\xcd\xdcI\xeb(%\xcbxv\xf3\xaa\xff6\xa6o\x97\xa4\x96\xc7\xf9\xfb\xf8z\x84\xf8\xc2\xd9[F}\x8f\xd9Ib\xd7\xd7J\xc9/\x12[\xd7\xbc5\x18!f\xbb\xd5\\+\x11\x8b\xcb&\xa1\xdf;x\xe2$\x83'Nb\xa3z\x89\x12\x19i\xc7p\xef%H^\xa2\xf2\x85\x83\x0c\xca4\xf7\x13\x19\xf0\"\xf6\xf9\x1f\x9b\xb3\xa8\xca\xd7\xc4\xb7\x03\x14\xba+\xc2\xee\x16\xb5uu\x91\xd7\x0c\xd9\x10\xd0>>\x9bK\xdc\x80#\xd8\xd0\x87$\x9e\xad\xd4\x87\x15\x8b\x93Q\xaeQ\xcb\xc5w\xc4\x98\x0dQ\x90\x99~mY\x005D/\xb3\xd4\xa1\xb3\xd9\xc1\xb5F\x96\xaf\x8e\xbe\xf9F\x8emn\xba\x8b\x82\xde\x89m\x0c2+\x0e\xda\xccx\xca\"\x9f\xbd\x17\xc2\xa2uZ\x0e\xac\x9d\xc0\x18\xcc\x92\x15\xafIMJ\x0d\xdb!\x8a\x1cgE\xc7\x19\x07\xb0\xe3\xb0\xe7D\x91r\xe0\x948\xf0\x08;\x9did\x0d\xf6{\xb3<\xab\x93lC4\xa9a\xd4r\xc5]qs\x9f9\x7f\x99\x9cqE\xa1\xddj\x83\x02uK9\xad\xa8tB\xffc\x91\xca3\x8a\xc6\xf8\xf4\x08\xa6\x99ev\xc0\x87\x86\x87\xcb\xb4r\xa8M\x076k\x84\xa6\xfd\x00f}{'\x13\xbd\xd4\x15\x12\x9d\x9f\xe7e\xb2L\xb28U\xc4)\xe6\x96\xa1}\x83\x12\x8cBT\xc2\xf6O\x96\xb7\x9f%L\xe7W\xed\xd6\x81\xe8\\\xab\xbbE\x86\x00Td\xc4\xac-\xf4\xba\xcd\x98\x02\xbc\x80#\x98M\xf7\x1c\x00NKa\x84\x91\xe9\x0d\x15P\xda0*:0\xaa\xac=\x9b\x19%\xfb[\xe4\xe5\x9bm\xcc\xce\x18\xeb\xb6\x04\x0e\x9d\xb9%U\x84ZV\x06\xda\xd7-\x92^\\QzQ\x07\xe0\x15e>\xdf\xcc\x08\x1f\xdc\x15\n\x02\xb3<\xab6\xeb\xf6\xb3\x8a\xcc6eR\xdf\x88g\x9f?\x83\xbf\x9a^\x9d\xa1\xb1\xdb\xd5Y\x08s\xb6\xf3V\xba\x0ca\xddB\x01\xb3A\xc6f\xa5\x909v\xa64\xed\xd0\xbf\xb97\xa0\x03\xc8\x80\x83m\xcd\x14\xf5N\xf5\x81{\x18\x98\x14\xe1\xbar\x03G\\Ab\x9f'X3pt\x8b\\\xa0\x8b\x10\x9d\x16(\xd1M\x1b\xa2;\x0f\x9e\xc2\x8eO\xa7\xe8_\xc0\x11\x9cG\x19\xf9T\xfbA\x10\xcd\xf3\x8c\x04O\xf9\xe4]\xc1%\n\xed\x8f\xb2z\x17,\x00\xa8\xdb\xbcD\x91#>\xa1(um'3\xdd\xc2n\x90N\xce\xc6\x8eZ\x94\xde.\xa3\x0c\xcf\xc9\xb6\xad\x01\x87\xc7\xa7\x91h\xa4+\xa7#QKW\x9e\x8fD7]\x19\x87\x82\xba\"\x17\xf92D\xa7\x95\x0eZ^\xd3\xe5\xa3\x98I\xa1\xe6_\xc2\x11<\xebb\xe6'\x8e\x99;\xf6\xab\x981\xe5\x8a\x87\"\xbf\xdc\x06uu\x85bb\x87\xd7v>\xc5mE\xde\x1be\x1e\x81\xb7\x19*p\xc4\\\n\xc4\xbcq\xfe\xd4q\x9d\xac\xb5\xb6\x150n\xfdJ\x0f\x1b\x8d\xf9K\xef\x89<\x89T\x85\x08G\x8e\xceMQ_E\xbb\xe0J\xd8\x87\xdf\xe9T\xb4\x85P\xd1\xf6\x82Z\x03\xf7\x17\xb6k(\xf8\xf0\x98\x07\xa4b\x11\xa1\\\x15rs\x08\x8d\x06\xab\xdf\xe9jL\xa7D\xb9w\xfc\xfb\xc7\xeb\xb3\x07\xcb\x84]\xfe\x0d\x80u\x9c\xe9\xc1\xe3'\x036\x16\xffo\x98\x1e\xdc\xcd\xd5s\x9a\xc7\xf3S\xa3\xc2\xb0\x94\x9c3\xd3R\xd0\xe6\x0d\xe9\xdb\xf5\xc9\xc6\xe4\xdb\xcb \x90(\xbf43\xf2\x9b2\xa5U6e\xca\\\xc5\x8c\x15\xab:\xae7\x15\xe6$\xc1\xbfl5Y\x8aPQ\x9b\xfe2\x7f\xb1\"\xf1\x9c\x94\xd5\x04\x12\x9fD\xfc\x87\x81B\xe8\x1b\x89\xe1\x08r\xf1\xe5\xd4\xe3y\x84\xee\xd3\x9d\xe7\x19\xf4\x10\x1b\xccC\xf9\xf93\x9c\xfb\xb1\xd9\x0f\xca\xdf\xa0kKM>\xb1\xf8\xe5\x17i~\xc1\x14X\x17\xe8'\x1e\x88\xcd\x1c\xd5+\x929(\xb9)\xc9\xceY{hH\x97G\xf3\xb8\x8e\xd9\xdf\x9b\xc0r\x00]\xf5\"\x01;(\xea\x84\xa63.\x8a4\x99\xa1\x02\xe9\xc1\xcf\x15\x8bO\xc1\\w\xfer\xfa\xf6MT\xc4eE|LA\xb4l\x8c>\xe3\x05\xf91\x8f\xe7C\x0c\xf4-\x1d\x85\x0e\x84\xa2\xe4\x98\x01\x01\x8e(\x85\xc8\xa3\xfc\xe2g0j\xf5\x9dX\x83\x9c\x8d\xf5\x84\xdbl\xeb\xb9\x01\xfd\xe9\xc3a\x91\xf7\xa9\x83\x9b\xe1B2\x9cT\xaaO\x19\xf6\x8c\x94a\xafM\x19\xf6\x18e\xd0\xe3\xaa\xce\xbf\x04\x94\xa5\x15\xe3SC\x8e\x10\xa1\xd6e\xf6@:\x1d\xaf\xf9r@ \xba9\xcd\xe8@\x85\xbf \x9a\xfaGI\xc5\x1d\xa1\xa6\xd9Y\x00\xc7\xac\xd2\x04\xa6\xf4\xff\xb3\x10\x7f\n\xb9\x8b\xe2\x93\xf0U\xd1@\x1d\xf1\xb7\x1b,s\xc0ld\xe0\xa4\xd0Gfy\x99\xf0#C\xc4\x89\x13\xcfd\x9c\xd1\xa3\xadl\xaeVm\xfb\x0dS\xe0\x17\x12\x15I\xf1\xa5\x06,\xcdM\xe3,Oy\xd6\x9a\x97\x98\xf0\xcc||\x90(N\xd3\xfc\xfad]\xd47\x18;\xd8|||\xd9\xcc\x8fE\xf2\x1dJ\x1f\xf5WX\xdd\x04@es\xfdb\xc8\xc8\x1f\xfb9\xcb\xdfp\xc1\xa2k\xa8 \xcd\xe5\xd7y\xff\xe3+\x91~'\x9b\xe5s\xf2\xd3\xfbW\x86\x80P\xa0p\x92\xa8\xcdM\xb8j\xe8\xa6\x99]\x1eX\x1dma\xd0\xfc\x16l\x81\x19\x95\xcf;\xf7\xe4:\xee0\x08\xcdW\xbe\xb9m\xa9rfd\xd4\xde\xbf8C\x97G\x18\xfe\x1d\x8e!\x8f\xd6q\xe1'A\xf4s\x9ed\xbe\x17zt\xf3z\xebMZ'\x0c}\xd4J0\xe9\xd4\xd7\x03`V]M\xc0\x0b\x0d\x06\x99\x15\xbe\xfd\x1f\x07{\x86\xf75{\xbf\xf7\xc4\xf0\x9en\xbfj\x02\xdeg\xaf\x0fP\xa4^\x94\xe9\xc0\x14\xd0\x9e\xe7\xb4M\xab\xe1{\xe0\xceU#\xda\x02\xce73U'7Dx\x85\xd1\xd64\x1b\xb8>\xa1\x9bvg\xa7\x8c\xaa\xcb\xa48\xa1\x88\x9ed\xcba\xab\x82\x9c\x87\xeb\xefo\x0bc\x88V\xe0l\x95\x1d\x83EQ9\xf6/\xa2)\xc6^ny\xe2\xbf\x9d6\x82v\xa3Q\x88\"6\xf84\xa1\xc7\xcf\xc6\x8f\x8d\xeeJ\xa2pc\x1fC\x1a\xd2\x10\xf2 \xd4\x05v\x0e)Oo$0\xeb\x86\x9dB\xa90Y\xa0\xe1\x91~\x14l\x85\xcc\x0e\x0eI6Of\x14\xa3u\xf1R\xbb9o`\x00\x8f\xd3\xdf\x8e\x95Aq\xc3*\xf9\x08\xee\xd4\xf3\xd0\x9d\\[=\xc7\xd6\xfe\xb1!\xa5!\x8203\xa9Y\xe4\xe5Z\x7f\xd0\x0c\x86fM\xfb\xfb9 \xc6X\xb3@\x83\x04\xb1\x9fL\xc9\x19;)\x07\x10|`3\x168\x15\x83\x8c\xc3d\x12\xf9\xf29\x7f\xf9\x01_\x9a\xed;P\xe8{\x80\xf4\xbb\x88\xcb\xfa\xe3\x03\n\xa9\xfbT\"y\x90D5\xa9j\xbf\xb0\x9a|\xf08j\xa6\xf8\x9d\x80J\x04.\x01d\xe4\x1a\xe6\xa1\x06\xa8=\xf6\xd4*\xd6\xb06\xa3\xb8(H6gAu\x92i}\x86\xf6\xbdC\x00\xd6om\xa6\xf4\x94\xe3\xac\xfc\xc40\x1d\x1ez\x98\xe1T\x7f\x07j\x91L\x1bq\x058\xf8V\x98)\xb2*\xd2\xa4\xf6\xbdco\x00\x01\xae\xa0g\x0b\xbc\n\xa1\x1b\x8aB-K\xba\x9b\xa6{\x03G ^ O\xf7\x07j\\\xa0=\x86\x19\x85nl\xf8q\x8e\xe9\x96\x04 db\xe6\xcd\x00\xb2t\x90#\xd7 \x87\xeb\xa6\xe3\x8bu>%f%6e\xab.ZCl\xa8\xf4\xf9PFmP\xa9u?\x0b\xa7(&\x8c3\"\xc4\xb5-\x9d\x8d(\xf2fSG\xb0C\x96\x0c\x08\xcfG\x12\xb0l\xbf{O!\x83\xef\x81<\x85lw7\x10bYC\xb8\x87\xac\x8d\x04gRG\x8b$\xadI9~1\xccZ\xfb[\xc1O\xde3\xb9@@\xd3LI\x8f\x84c\x0fv\xf1(\xf7\xfal\x1d \xa3p\x11BE\x99^}{L\xe1u\x04K\xd8\x85\xeb\xb0\xd9\xd4x\x928\xecj\xed\x94\xbe\xb2\xc1q\x08uT\xad\xf2M:\x7f\x91_gi\x1e\xcf\x9f\xa1Z\x8deg%\xe9\xc2p\xdd.\xed\xc3\xfc\xcc?\xe8eK\xa4Eh\xc5\xf7\x86\x94\xe2Z\xa3\xe6\xb9\xd0\xa7\xeb^\xae\x1a\x8b\xe7\xfe\xcb+\xf1Rc\x0f\xad\xba\x1a\x0b\x9b`\xf9\xec\xcf\xec\x8c\x136\xc1l\x07Ri\xf8m\xf9\xbf\xe9\xea K\xce5)\x97\xe4U\x86\xcf\xde\x96\xb4\x02\x1cA\x8ao\xb8\xc3\xb7C\xc0\x1bh\xd6Zz\xdf\xd8\x11\xdf,\x11\xb2]Y\x7fq3\xda\xfa\xb2E\xad\xfb\xad(B\xf2\xeeg\x90a \xbaK\xab\x9b\x03\xaa\x8c\xf5,2\x08\x82\xaa\x01\xbf_\xf2\xc8\xe85\xfe\x95\xf9\xa4\x97\xa8[6\xd1F}Z\xf9\xe0;\x8d\xc5\xfdZ\xa0\xb5\x169\x97\x02\xc5\xbe\xd5\xbd\xbd\x11\xdf\xf6Ru\x02?\xf5\xe4\xae\xd2\x83\xa3\xed(op\xda\xe8\x83a\x02\x9a\xf4\xee\xdd\x1d\xc0\x8f\"\xdbI \x88?=2\xaf\x14S+y\x94\xad\xe3\xf2RRj f\xae\nUL,!\x17Kn\xa0\x97\x01\xf6\x8d2\xc0~[\x06\xd8?\x1b\x08C(Ng9\xcc\xeb2.\x1c\x0f\x14\x16\x82\xfdi\x00\xd5u\xc2T\xc5QQ\x92+\xe4\x8d3\xf2\xc9\xca6\xce\xe2\x8a\xc0\xded\xb0\x0e\x08\xd3,\x93\x10[\xdb\x84X\x91\xc2\x1e5\x02\x14\x96u@O\x1c\x0c6\xbf\x92\x04\xac\xf9\xfb\xf3gL.\xa7\xdd6q\x10\xc2N\x1c\x95,\xa4\x04\xa6)\x9b\x91\xa2\xce\x07w\xb9Z\x18`\xe0\x08\xf6\x1d\x0d\xb1.J\x12_Zk\xda\xef\x87\xe5\xb5$\xef\xff\x11\x9d~\x7f\x1e\xda\xfb\x17\xb5\xe0\x9a=r[3\x12\xd5{\xcc\x1c\x9fdu\x08\xf4\xe7h8=\xf9u\xc1\xc4\x87\x1c;\x00\xe1\x89\x1d\x08,\xe3lmYjlm\xdfa\x1f(\xa7_<$|\xc6&\xe13\x1c\x96/y8+\xce\x81\x19\xbb\x90<\x9a\xb1\x1f~\xb8\x88\x08z\x92,\xec\x1f\x86\xca\x0ex\x14\x82\x8f\xf9\x1eJ\x8c\xed\x82\x071\x06y\xa1O\xcbt\xf8\"\x0b$\xe0\x1c\x90Q\xb2\xab*2\x8aa<\xa1{]=@|\x16\xaf\xd4\xadw\x07,\xa0[A\xed\x1a HU\xe4YE\xbe\x84\x82\x1c|\xf7\xebn\x8d.\x0598d$\xa47\x13\xa3\x0eP\x14\x84\xdc\xc1\xa1\x1b\xe4HT\xef\xb7\x89\xc8\xfexP=\xfauA\xc5\xc7l\xc9\x0f\xc3\xc0\xe0\x82\xbe\x8c\x8c\x18\x9c\xc3Da\xcd}goN\x82\xe5\xd0\x01\x83\x10$.\x1d;n\x04I\x0b\x0e\x9e\xe0b\x1e\xb0\xbb\xb4\xb8\x9e\xad\xfc\xfd\xc3\xc0\x10\xafFW\x9ai\x1c\xda\xa7\x01w\xb8\xba\xcc\xc4\x8b\x8e\xdd\x01.\x87\x0eh\xce\x1a\xf4s\xae\x94c\x19%J\xc5Z#\x08\xf8\x8f\xe7\xf9\x1c\xc3\xc5\xf2\x9fL]\xc5L@ \x97{Q\xde\xc6G\xf5A\xa8\xbb\x99S\x0b\x1b\xa5\x03\xda \x19\x8b\xf2\xcb\xd1\xeb\xf3\xd0\x02'Q\xeev}\xf0\x16\xd1\x0d\x9c\x89\x0e\x9c\x89\x04'}\x1cv\x93\xcfw\x0b\x82\xf1\xe1\x81\x1d\x8c\x92\x8c\xc6\x17\xe5\xa6\xa8}\x8f=\xf0\xc2^ \xefna]X\xf0 +y$\x9b{#\x86R\xd5y1`\"\xa9\x07\xf9-K\x93\x871S\xa7\xc6o\xa7\xf4\xcc?x\xa2\xd7\xf9i\x02\x18\xdc\xea\xd4D|\xa0v\x85t\x03\\\x16\x92\x10\x07'%![(\x8d\xdbnVB\xa125*{\x06%B>\x98\x07\xfe\xcfU\x9e}\xfe\xb4N?\xdf\xc4\xeb\xf43\xa6\x00\xfdx\xf1\x80\xf1\\_|\xb9\xd3\x8d\x10\xb2\xad9\xe1\xc3\xfd\xffxk\xc2\x81\xc1\xb4/1I\xa0\x06Q\xfe\x1eCi\xe2\xd5\x97\xf7\x00\x83\xa0\xe0M\xba]F\x16\xe6\x04\x99`\x02\xddkTS\xe3\xb3\x01\x13)#\xa3\x85\xbaR\xba9\xd8\xbc\x9b\x00\xcfti\xce\x95\xa5\x19GZ5S\x991+g\x9d9\xaa#i]\x0c3\x19\xeeW\xa4\xfc\x0b\x85\xf1\xd2\x8d\xcaiL\x85\x9d\xf1\x19i\x94ua6\xca2\x0db\xee0\x08Q\xb9e&\xeb\xd4\xfaJ\xdf:zAY\xf6\xb8\x88\x9b4x!\xe1\xc5\xf3\xb9\xb0\x8a\xff\xfc\x99\xb2#\xeb\xfc\x8a\xb4\x9f0\x06\xc5\x10\x99\xc6\xb8/;\xc6Z\xa6 ^\x0d\x82\x0f\xa7\xff\xf93\xd0\xb9\"$\xd7\x9b:\x16\x90D\xc9\xfb\xc6\xd1\xd4x=\xd8\xcf\x15o\xdfo\xe0AA\xd7\x07\x80|\x8a\xb7\x16\xbag/\x08)\x9a\xe7n8\xb4t\xc0\xa1\xaf\x8e\xc87Fcl\xb3\x87\x06\x1f\xe1\xa9\xbc\xd6Z\x92\x1aM\xaf\x7f\xb8y\x97'\x19\xa5\x08\xfd\x18\xb8\x00.n\x0f\x82\xbcw\xb2\x86\x86\xda\x88\xd1\xbf3\xff\xbas\xa3\x84\xbe\xecz1t\xeb\x7f\xce_\x1ej\x0d\x06\xae\x87\xec\x10N\xc4\xa7\xda\xdb\xdcO\xe26W\xf7\xf2T|\xaa\xb5~x>d\xc3p)>\xd5:\x0c>\x13o\x1f\xf7\x8d\x18\x9a+\xdc>4\xe3\xf9|2,'\x8b2(3\x81\x90\x9b\xe8>\x1d0\x1c\x1c\x92\x9b@\x91\x9d\xb4\x154\x08\xd6o\x89\x93\x85 $\xbaw\x94\x8a\xde\xe9|9a\xb6Ny\xfb !\xf5\xba\xab1S\xba\xe8\x1a'\x8a8\x899\x19\xca\x86\xa3\xe5\xdc\x06\xdd %\xad\xb7!L\x87\xb6\xa3\x89\x9a\x9b\x0e\x1ae=\xdb\x8a\x0b\xdd\x9a\xdaV\xf1\xaa!\xb6\xe6\x11f\xcc\xeb\xf85\xa9c\x1c\x1d\xa9\x00\x83}\xadI\x8d\xaa\xcd\xb5_3\xd5B\xc7\x8f\\\xd0\xfc\xcf\x9f[xEk^\xe9)\xd7U\xc8\x9b\x15\xe9l\xafl00\x9e\x85\xf5Y\x10\xde\xf1\xc8m\xc0\\v\x0e\xc7a<\xbb\xd0\x83`)A0\x1ee\x14\x06\xe0\xc2\xc8\x00h\x9f\x8a\xdd\xd7{\xa9a\xcf\x8a\xb8$Y\x8d\xa1\xba5<\xda\x10\x83\xd6\xf1\xf0\xac\xed\xf1\xaa\x95\x84\x9aG\x98B\x17\xf1\x95]\x9b0\xbf\x97\x92\xf9\xbd\x18aE\xfbE\x9f\x18\xd4\xc3\xa2s\xb0\xa5O\xf1\xba\xef\xfd\xa3\x01\xc6\"\x8d\xeb\x9ad\x13\xd0\x04}Yl\xd2\xf4\xe6\x8d\x08g\x84s\x1e\xe1;\xbe\xf0g~\xea\x93\xae\xf6\x1a\xf4\xe3\xc8:\xddh<1\x93\xea]\x99\xaf\x93\x8a\x8c\x18D\xc1\xb5\x86s\x9f`,\x14\xa7\xb1p\xcf\xae7\xe4\xda\x117\x86\xe3\xa3\xf0\xa1\xe0}m\xa5U\xb5\x01\xb8\xa8\xdb`\x08\xcf\xc1U\xc4j&\xf7\xaeL\xd6I\x9d8kA\xdcg\xb9\xf9\xcdg\x99T\x7f\xa9\xf2\x8c\xcb`+\xdd\xfb\xe7L\xde\xed\x89i\x16\x84\x92jn!/\x9b\xb4\xdc`\x1a\x18\xefQ\xe3\x1b\x9fT\xaf\xb9&b\x02W\xba\xd7\xcf\xe6s\\\xb0\xa6\xdaZW\xed\x7f\x92\x8c\x94q\x9d\x97#\xe6\xf5\\\x92d\xe5\xfb\x97\xcd\xd7ns\x13\x1fL@\x93P \xa9\x18\xdb=\x81B\xf7\xf2\x84\xe5\xaeu\x1eq+x\n~\xdc\x1fc\xeb \x95\xdf\x15C\x1f\xa9\x0c\xfd\x9dRap#t\xa3\x8e}A\xae\xb4'\xdb~\xba?\x94fm\xf8\xd3'{\x03\x86M\xb6O\xb7\xcebw\xb0\xf7\x9d\xf9\xd3\xff`s*q\xbfw\x07\xfeJz>\x8c\xe5o\xe8;\xae\xe8k\x97\xbcv\xcfF]_\x9d\x850\xb8N\xea\xd5\xf3\x92\xccIV'qZ\xc11xI6K7s\x82&`U\xbc&\xf7Y\x9cx\x8d+\xb6`\x03\xc4z\xdb\x14yd@hB\xe7\xbe\x81Pm\"p\x9d9\xbd&`G]XML\x01\xecX\xf5\x1e\xb0\x8cyTA\x8d\x177,\xfc=\x9b\xd1\xb6&\x9a\xd0g\xc6\xcf\x06\xd2\x1b\xcd\x9a\xe5\x99h\"\x88\x01\x8aw\xaea\xe0@\x95c/\xf2\xb9>x\xa7.\xcb\xc9\xef\xcc\xbf~\x85\xdb\xbdd\xe8\xb2,\x1e\xf0\xe9]\xc7\x97,\xb7\xf2_N\xdf\xbe\x11N\xbd\xb3\x94\xc4\xe5\xf3x\xb6\"6\xbb\xd6**\xd2\xcd2\xc9\xaa\xa8$\x8bJ\xf9\xb0cB|\xeb\x9aQ\x1eT\xc2R\x9b\x17J\x10\x97z\x95\x18\x92\x99\x9c\xa0X\xd8\x19\xe0<\x9f\xe1\xf0X\x14]\x12\x84\xdd\x19,TX\xf8\xd7C\xeae\xddf2\x84;\x01\xd3f\xba0\xe0\x97~JB\x8c\x9a\xb6\x07m\xd0i\n\xeb \x01N\xd5\xb0cI\x81\x931MM\xd3X\x13\xf2>\x08\xf5\xdf\xad\xf5\xdf1\x9cN\x08~\xc7\x8f.$\xec\x85\xb6~\x9c\xa6o\x17A\xd8\x8d\xf9n\x06\xb55k\x9b\xbc\x11\x1a\xa6<\x17qE^\xe4\xb3 \x9clCi\xf8\xf0\x07IfW[\xa1\xe5\xbdE\xa1\x82\xfe\x8b\xa4\x9aQ1$c\xec\xaa\x86\xebmj\xf3\xd5y\x1d\xcf\xca\\\xcb?\x8b\xb2\xce\xe7$\x15\x94\x86W\xefGE\x01\x854\x9e\xbb\xe4E\x86\x8eos\xdc\xac]b\xf4mv\xd5\x1b&\xdb\xb8\x1d\x8b\xf2\xa5\xee\xc7\xa2\xb8\xba!\x8b\"\xcf\x8a\x9e\x07\x87\xc9\x16\xb4[\x98\xeb\xa0[\x8fc\x1c:D\x91#\xb48v\x882\xac\xf2\xe6\x8e\x1e\xe6f\xb4>\x1b\xa283D\x9d\x0f\x9c}8D1(\xd2\xfd\x00&0\xeb%\x13\xb3\x9d\xe6\xa0\x90^\xc2N\x083\x8b9\x94pl1\x1cd\x8bE\x92\xa2{W\xff~\xde\xc4\x8fT(\x8c\xbe\xee\xaa\x1d\xb0\x0b3\x17\x19R\xdc\xb1]\xd2\xa3E\xfa\xcak9\xc66}\xd1\xd7^\xf2\xa6U\xc2\xa5\xaf\x89\xf1\xe3\x9dy\xf9\x0b^\xdb\x91\x97?g\xebr\x99\x14B\x97\x87<\xa7\xbe\xf25\x8b\xe7U\xd7\x1a\x19\x1d\xb8\xc1\x13\x89\xf8Ibd\xfai\xad\x13tc\x0e\xb1E\xbc\xd5\xbe\xa6\xffl\x04\x9d\x0b1fN\xed\x97\x18\x91\xd1\xcck\x8c\xe03\x1cy\x8c\xdb\xc0?\xe1t\xbf\x9b\xfa\xbd\xcfZn8\xf7\xa8\xb5\xb4\xe2\xd2\xfc\xbe\xe6\x15K\xbbY\x19Rnf\xfe\xd6\xba\x83\x83\xbd\xad\x93\xbb?\xd9Z\xfe\xdfZ\xfa\x1f\x18\xabU\xf6W\xdf\xdc\xb9\x10a\xe2\xc8\x0d\xfaOy\xa2\x9b\xd9\x03TAE\xb3\xb8\xa87%9\xad\xe3\xd9\xe5\x872\x9e\x1186\xbd\xe1\x04\x9d\xfe\x1b\xcd\xf2\xac\xaa\xcb\xcd\x0c\xdd\xdf'\xecYEkR^C\xfan\x06\xec\x99\xe5\xaaA\x1fx+k\x05\xde*Y\xe0\xad\x92\x05\xde*ww\x03\xc8\xa6e;\xf0Vi\xe0\xacqpkRU\xf1\x92`\xae\xc6\xbd\xb3\x90\x99\xd0\xd4\xad\x93J\xa7l7\x11\x8c\xac\xb9\x8bW\x9dUC\xf5\x05\xcf\xedC\x8f`\xf5\xa9\x02:\xfai\xd8q\xa8\x1a\xad\xf5\xfb\xed\xf12\xa9^\x96\x84\xa47o\xe25\xb1\xe7w\x90\x86\xe4S\xd2\xf2\xc7\xd1\xae\x1d;\xc4\xa5\x0b\x9d\x91\x80\x97Q\x92\xcd\xc9\xa7\xb7\x0b\xca\xa5\xfc \xee\xefS\xda\x9d\xcb\x87Y\xf30q\x0d=)WZ4BX#}$\xb1\x12e\xf4i\xf2\x1a\xb9K\x17M?\xc7:\xb80 \x1dX\xe5\x85\xa0f5\x0b\xc1\x13\xe7\x05\xfe\x10\xf9\xf8^\xb4\xbf\x98\x89\x90\xb4\xd5\x83j\xb6\"\xeb\xb8\xfb\xb4\xd5\x88\xf2\xbc\xdd\x95\xda\x0c\xef\xe8\x946\xa7\x1f{\x82cg\xfd= \x9f\xe2u\x91\x12\xefl\x0c\xc6v\xc8\xf7\xc3/ \xc3\xadW\xff\x96*X$G\xc6\xedp\x07\n\xda\xfe6B\xf3\x86~03\n\x87\x8cG\xf9\xc3`\xef\x8c\x9c\xed \xc5T\xef3r%\x91>\xb9F\xab\x8f~'\x1d!TP\xdd~E\xb1g\x90r\x97\xa4\xca\xd3+\xe2w\xb5\x82\x96}[G\xf3\xa4\x8a/R\xc6]-\xe2\x19\xc1\x00Q\xdd1\x84\x18]\xfb\x92<+\x92\xeaC\xbc\x94\xd9C\xfd:\xd0G)\x1e\xa2A\xb34!\x99\\\xc1Nt\xb7\xdfL\xcbxh\xd62\xfah\xed\xffm\x80\x91\xe4\x1e\x05\xba\x8a\x82\xa1\xd4\xa7\xf3\xa9\xc4[\xad\xb7A\x8a\xbb\xf9;\x03SY\xfa\xa9!\x8cb\xe6\xef?2\x06Q\\\x0cEP\xd4\x86\xb0[17\xf9'\x86\x00\x8a\x99\xff\xad\x8e#^s\xbe\xb7\x0d\xd8\x1ce\x0d48\x94\x82A\xae\x06CL\xe5\x8f\xe8\"\xc9\xe6~\xb6I\xd3\x90\x7f\x16\xf0X\x1f\x14\x9f1m\xad\xd2\x04\x7f|\xba\xb9\xa8KB\xdf\xce\xd5\xb7\xe4\x13\x99mj\xb4\xd0\x11\x7f\xd3\xc7\x9d\x18\x8fi\xebA\xabB\x13\xf01\xed=\xa4\x15\xdbJd\xe5g\xc82\x85\xb0\xb3\xe1\x87M\x92\xf2f\xae\xa2w\xcf\xde?{}\xf2\xe1\xe4\xfd\xf9\x0f?\xbd\xfa\xf1\xc5\xc9\xfbS\xd3f\x82#Xi_\xd0\x0f.h\x9b\xef\x99\xd4\x84\xed\xaa\x0f\x10r$-X\x9f\xfd\xdd\x90\x17\xaf\xe6\x13Xc\xe2\xfb\xf6\x86\xc0q+-\xc8\xac\xd1\xe2\xf1\xffY\xd8\x17\xfe\x00\x9d\xfc\x98 \xc5\xfe4\x99\x8e\xdao [\x14\xa5\xbd\xcbm\x17o*n\x0d \x84`\x1d(.\xe8y4\x96fe/l\xf4R\xc8\xc3xt\xef{\x83\xbe\xbb\x94\x08WRi\xcf\x02\x88\xd7\x06\xed/\x89Vy\x85\xbe\xba>\xff\xf3\x082\xfc#@ 3I\x80\xbf\x17\xbf\x8e`\xca\xc5\xdcY\x9e\xca\xe8(\xde\x84\x8a\x13^p\x86_^\xc4\x15y\x17\xd7+\xfe\xa9\xfcy\x04T\xba\xb3/\x80\xaa\x03\xc9\xc7\n\xca\x16e\xd3\xde\x80\xd01\xfc\xe9\xfe\x17\x98\xb8l\xadW{\xb2\xf7h\xdbO\x0f\x1fn\xad\x1f{\xb27` \xf4\xef%\x9a\xa9\xbf\xee\x9c\x1bG\x9bdv\x01\x89\xb8I \xd5\xeb\xb8\x18\x08.\x9e\xc3@\x84\xf0d\xc8\x1dX\x1a\x0chu\xbe\x9b![\x83j\xc8W8\x15\xedj\x87$\x82\xa1\x1fj\x9d\x85\x17C\x9e\xc42C\xa86h\xb4\xe0\xe5\x0f\xf6\x86\xdc\x81\x87Y2E\x14\xbd\xf6I@E\xc1\x02\x8d\xb6\xad\xaa\x1a\x11n\xfdP+5\x89x\xeb\xda\x81\x8b8\xda\x87\xda\xb7\"\x8e\xf6Cm\xc3\"\x8e\xf6C\xed2 o\xf0\x87Z\xafm\xe1\x0e\xfeP\xeb\x98\xed\x94\x08A\xb9\x00\x1e<\x80;\xf9\xb5\x98\x98K\x82^.\x12\xf6b\x98\xcdd,\x92g\xf1'\x99\x93\x8b\xcd\xf2GrE(\xe7\x98d\x8b\xdcR_\xde\xfaO-\xael\xac\xe2\x9f\x93\xaa\xce\xcb\x1b\xb3\xd5\x9a(\x8cy\xb07+|s\x1d\xaa\x16\xcc:|.Y:\xdb\x07U\x1dSi\xc46\xd4\xc2\xb5\xbd\xc6\x0c\xc3\xd2\"\xaf\xf8\xa1$d\x82\x9b\xea\xdc,4\xa9\xa5Z\xe5\xd7/\xe8\x02\x9a31\x89\x12\xa7\xa93\x1c\xd8\xd2Q2M\xa5 FY-h\x91&\x17\xafI\xbd\xca\xe7\xd5\xa4\x8b\xab\x9dd0\x14u\x035\x10\xbcu\xdc\x1d\xc6\\\x93RJ\x14\xca\xc1\x04\xfc\x06eI$\xb7w\xbe$5S\x16\xf0\xceE\x05n\xf3\xad\xd6\xe3\x8f\xfa\xd5Wq\xf5~\x93\xc9\xaa\xecg\xbf\xdau\x19\x17\x05\x99\xbfk\xce&\xfaT\x98\xfa\xac\xe3\xc2\x97\xd5X\x1d\xa5\x89@\x84\xe4\x91\xc0\x89\x1a\x13j\xd1\x01\xc7>fD\xd4T\x8c\xe7s\x7fz\x166\x1cp`\xf9\x80\xe3\\\xf3\x11\x7f \xbf\xdb\x14\xf3\xb8&\x1c\xec\xbe\xda\x94\xde\xd2`\xd0\x11\x87\"\xc1\xbcA\x02\x12\xc2\xd4L\xbd.\xc9\xcd\x04<\xa4L\x03h\xc7Y\x03\xbb\xee@\x14\xe4\xef\xe94\x1a\x9a\xc7\x8c\xf5m\x1f\x82z\x9bV\x87Z-1\xbbBc\x17j\x19\xaa\x8c\x8f!\x83\xfb\xb0\x0f\x13\xd8\x0bBd?\xf6\x9fB\x0e\xdfC\xf6\x14\xf2\xdd\xdd\x00\xcai\x8e73\xadK\xb6\xdc\xc1%\x17\xdd\xbfy\x94\x95 J\xf3e\x13\x86Jc\xbd\xa1\x16\xb39\x8b\xc1Fd\xe8\x90a\xcbtE\xca\x8b\xbc\x1a\x8a\x04\xb1\xd5B\xc9v\x99\xf3_{\xd9l\x0d\xc0\xbf\xcf\x82M\xbd)\x06\xce\x84]\xf0\xce(C\x7ff\x8b\xca&\xcaWX\xcb\x86*\x8dYNKx\x05P\x04dAE\\lk\xd4\x827\xb9\x83*\x13Qr\x83\x08\xd0-B\xfa\x99*\xf4\x99\x9ex\x98F\xb8d\xd70h\xf4\xde\xab\x10\xc0\x04t\x04\xda\xc7\xb0m9\xbf\xc9Qk0\xe9G\xc4\xab\xca\xad\xdcu\xb7\\m\x93P[\x14>\xd1\x9d^\x889\xcc\xc5G\xaeHy3\xce\xb1Y-R\x86<\xe2I\x98\x9d\xbe4$\x1bkU\xb1o*\xde\xb7T\xd4tL-K?\x0f\xc1\x988\xb1[0\x16D\x08\xb3\x10\x16!\x14\xe8\x14\xbf\na\x8d\xee\xab7\xf6\xb1\x80n\x85p\x1a\xc2\xf3\x10.Cx\x16\xc2\xdb\x10\xde\xb9A\xbe[,+\x11o;~\xd0\xadL,V&\xdeje\xbae\xdb\x95\xea\x16\xcch\xdd\xa7A\xf9\xa8\x00\x16C%\x96\xf9r\xb6[\xa4nq\x0fk1T\xec!*l\x85\xa5b\xb8$7x\xd3\xbf\x98.T#\x9a;\x07\xde\xc3\xff,\xe0\xf1\x9d\xd7L\x0f\xe3D\xe3\xd9\xe9\xa3>\xf9\x92\xdc \x0d1%.u-,\xe2\xff\x97o\x93f\xa4\x8f\xbfl@\xe0\x96\x11\xc4V\\\x93H\xd9\n\x9a\x89)\x98\x1b\xa2\xe2m1\x9d\x9f\x85\xa8G[H\xab+\xd5l*\x08Q\x8d\xa6>\xc2\x93\x1dC\xa9\xcc\xf1\xcfu\x88\x87B\xa2\x0dD1\x9b\xe6\xd17\xdf\x94dq\xc6\xb2\x95\xee\xec\x85\xa8=\xdb\xd9gf\xbf\"\xed\x91\xa4\x99\xfb\x0fC\xb4\x0d\xee\xb8\xbe\xd0\x9fU\xf3\xd3\x98 \xd3\xb58\xa7C\xb2\x15J\x1c0\xce\xc5'8\x82\x13\xc4\x1d?\x08\xa2y\x9e91r.Eb\xe4\xe1\x7f\x18m\xc0\xe8&p\x04\x9fD\x10\xf9\xe7p\x04\xf9\xf4\xf4,\xc4\xf8\x95\x0b!\xf7\x9c\x06!\x86\xac\xd4\x9c^\xcf\x83\x10\xdeb\x96\x17\xc4\xb2\x10\x06\xd3\xfa\x8e)\xf1\xd8\x84H\xb6\xf2\xaf\x04\xf5\x9dg\xff\x0d&K\x91^W:\xb2\xf6\x16\xe5\xb6\xd9\xf4\xed\x19\xd2\xb4\x80Y\xb8\xa5d\x19\xd7\xe4\xff$$\x9d\xfb\xa5\xcf\xd8\xd6\"\x08\xc1\xab\xf7\xbc\x10\x0e\x1e\xdd\x05\xcdr\xc9\x81e+\x18x\x9aJ{\xa7,d\x0c=\x83\xef\x1c\x1f\x0e-)\xb8\\\xcb\xbf\n>P\xa0\xbd\xc3\xcc\x06\x19\x8b\xd0\x96a$\xbbw\xff\x0d8K\xe9r\x80\x87\xfb\n\x0b\xf8\x1c%\xbcK\xcc\xddZ\xdc\xc5\xfe8tt\x15\x1c*\x82Q\x89\x9b\xf4\x8b_62\xb8CV\xf0\xf0Ny\\\xc7\xcc\xaaC\xe5\xce&v\x07\x94M\xb2\x91\x87\x98\xb3\x153\x0b\xc6\"c\xde\xc3\x80\xf3\x9e{\x8c\xf7\x8c\xadi\x02m\x85\xc9\x1cw \x9b\xcbq?Ty\xe1\x87\xfb!\xec\\P2s\x12\xf1]\xa4\xfc\xddM\xc05\xb68\xa5Hs)\x9426c>\x0ca\xe7\xfc\xce\x89\xe2\xc3;\xd8\x81\xf0/D\x14Y\xde\xbd\xeb/\x9b\x14[\xc1;\xd86\x92D/\x92,\xa9V\xfe\xc3\xc3;\xc1-\x87D\x89\xb6\xd2\x1b\xd9\xde\x9d\x8c\xec\xf1\x97\x8dl\x1b?sS\x913t\xf4?7\x95\xedp\xf26\x84\xd8\x9e\x98\xd0V\xa6Tj\xa7$\x97\x92\xaf\x87\x8f\x1dB\x1a\x9b\xca\x94\xd2\xbc\x10\xa9\xc8\xc3\xef\xdc\xee\x0e\xba\xc5\x10\x15r\xa8\xdc\xb2\xc4\xf1\x9d\x8b\x83\x9b D\x9b+\x0c\xc9\xcb\xcf\x8d\x82\xeb.\xe6\x8a\xeeBj\xe2\x1f\x852f\xac\xa2\xba\xc8uw\xf8\xdd8mc\xf5\x19\x88\x81[`1\xa5\xd5\x18\x84x\x8d\x1e\x02w\xa1\xae(%\x97\xb4\xa5zb;\x9a<\x1e\xdf\xf9N[\xc2\x11\xac\x85\xc6\xa1\xec\x88m7\xfeR\xbcZ\xf28\xa3K)\xc1\xed\xefo\xb3J\xfb[p\xa4\x02\xdd$l\xb7\xd0En\xc1\x97\xb1\xf1n\xc1`\xcaq\x1el\xc1Pn=\xd0-N>\xb9W\xf7\x1fQ\xe8\xb2\xd4\xd3\x9cA|\x14\xf0\xfd\xbd\xc7\xf6w9\x9a?d\x12\xfa\x16\xfc\xa0\x1c\xd6\x81JO\x0e(\xff\xb7\xa0<\xdfJ\xe1\xffV[\xf2\x7f\xce\x99\xc4\xbb\x85%3\x16c\xa2\xfc\xdd\xd6\xf7}\xe5\x97j\x8b~-Z\xc1\xf8\xb3\xf9\xb8An\xad\xa0\x91\xee\x8c\x9c\xcb9\x18\xcb\x7f9\xe73\xef\x96^\xcfc\xf9+\xd6\xf3\xc8\x93\xe8K\xf8'9\xe2\x91\xfc\x92\x1b\x0e\xdc\x86P\x8e\xe7\x87\xa6\x8fB$(t\xf7\x1e\x8ca\x7f\xa6\x07\xc8\xee\xd0Mu\xe0\xc8\xee8\xb07\x16k\x8a[\x9f\x04}\x03\xe2\x9c\x99\x1d\x96\x81\xcd\x8a\x18\xa4=\xe8\x9bxM&\xc0\xa3.|\xfe<\x14~Q\x94V\xe8Y\x95!\x92\x8f\xfd\xdc2\xfa\xd1Q\x8d\xecVN\x94(\x8d\xb6r\xb2\xd1@\xbbw\x9b(\x8aE\xe4\xaam\x16\xdb1\x1eU\xbc?\x9c\xcc\n\xa4\xf7\xd6\x92\xd4\x82\xd3\xac^\xe6%k\xce\xaf\xd5\x8c\xae\xbf\x0d\xd0U\x83\xec;\x84\xbd4\xec\xecX|\xb72\xd8J\xc9K`\xa1\x0c\xb9\xd2\xfb\xcc-u\xa7Z$\xe8q\xe8\x16\xe0~\x05\xe8. \xc7hno?\x02\xb8\xd6\xf9\xa9Q\x13\"\xd9\x11\xa5\x06>\xb1\x1c\x1f\xaa\xd7n\xcb\x1f`Z\xf3\xfc3_\x11\x14\xef7\xd9\xf3|\x93\x0de\xb0\x1a\x0d\x0buB]\x98\xfbDl\xb0\xaf8)\xde\xd7\x87d\xc8 \x7f\xf4\xb4\xf4K\xdc\xcc\xcbm\x951\xe2\xcf\xb4V\xedeX\xf2\xaa\xaf\x08\x0fA\xe7^es\xf2\xe9W\x03\xc9\x87\xa4\xc0\xe4\xcbj\xe7N0\xf2\xb2\xcd\xfa\x82\x94\x1e\xec4\xbe\xd9p\x0c\xf7\xf7\xc1\x94&\x0d\xee\x04Lt\xb7\xde%t$\xbdkX\x83\xbb\x1f=w@\xd8\x96\xae9\xd8\xc8\xb6\xcc\x92\xc7\x916_C\xd4\xb2\xb3\xb6\xbf\x87\xf2\x9c\xa7TG\x1f\x8c\xa1x\x91_\x08+v\x80}E(\x0d\x03\xa5a\xf1\xda\xe9;\xe8f\xe1y&F\x1e\xach\x8d\xd7\x0b\xec\x1f@\xc6\xbd\xcd\x19Dm\x8bE\x0bf\xd8\x19NY\xa1\x16\xb4\x9b\xd0\x1aqKV\x025\x82\x19sK\xf0\xbb+\x00\xde\xff\xcck\x88!\xcb\xb3\xfb,\x0f0\xf3\x1b\xf3Bp\x19-\xf0!d\x91\xf4\xf1b\xb1\x83\x1b?.1\xf5\xb0\xc5Ys\x1e\xcb'2=\x91\xf0\xd5\xec\xb19\xcd\xf7l\"\xad\xf7\x1fV$s\x82+h\x8cM\xd5\\\x1a\x1a\x88U\xd2\xcd\xca'\\\xed&\x86\xbb]\x7f\xe2\x14\xd0\xf4\xc5\x96E\xb2\xc3\xba\xcc\x15\xdd\xe2\x96\x93D-\xfd\x8c\xc7]\xfc\xb463,\xb0~\x0d\x8e\xbc\x03\x991D\xc3\x06\x97v\xe6\xebvL\x16\xb1\xd2hO\xd1qJP^!\x19\xd5\x19\xe3\x88Z\\\xf5\xae\xc8\xb4\xbf\xdc6xdA$q\xba+\xfesM\xe2)\xe6BW\xc75\xc1\xf0\xbev\x14p\x0c\x1ebY\xe1\xe1\x11\xb3\xc0\x14\xd8\xaet\x81mvp3dJ\xa7\xbf\x02\xb2\xb0\\\xc6\xdb\npV\x84iq[]:\xd5\xc4\x07\xb4\x81\xe8{\xd8\x13!n8U\xfeP&d\x0eu\xce\xf3;C\xdc\xf6\n\x86z\x15\xd7\x90T\xd9\x1fj\xa8W\xa4$;\x9e\x0c\xb7\xd9\x1dFU\xa4 \x95\x18C\xd8\xff\n\x00\xee\x11\xdf\xaf\x05^'>\xb5\xd9c\xfc\xafN\x14\x19''!\x11eN\xb7M]\xb6\x154S\xcd\xac\x95m\xfb\x070\xbe\x81\x06\x8d\xd9\xfe\xe9x\xbb\xda\xdc(\x03~\x890\x0e \xee\xfdkB\xa5\xaa\xe5k\x1c\x07\xaa\xd2h\x0c\xee90\x90\x8d\x97\x18\xa0\xe6p/\xd4\x0bBH\xe1\x04\x15h\xa8\x1c\x93'\x05\x95k\x9eW\xb8\x1f-\x01\xd8\xbf\x00\x1c\xcf7eI\xb2\xad\xa0\xe2\x08\x11!w\xe8\xb4u\xfc\x15\x1f\x04\x7f\xfa\x95tG\xfd\xfeG\xccu\x14\xf5\x89\xf4\x92\xbb\x95\xb6\x9b\x00\xe6\xd7\xb0\xfbU\xe8q\x17\xf4#\x00b\x83\x87:\x97\x99\xda\xc7W\x99\x05')o\x17\x1fn\x8aQ:\x80\x11\x1b[\xd8<|\xa5\x8d\xf8cr1b\xe0\x8e\x83F\xf07a+\xee~\xe0\xe7K\xf25t\x8f\x0d\xcb\x8a\xc9\xf1\xdb\xdc\xeaW\x80\xbf\x12\x14\xe3+\xcc\x86m\x82&\xfc \x9d\xd4\x90\xb8\xb4\xf54\xaa\xadf\xe1\xbe\x07z\x13\xa9\xe8D\xbe\xce\xd9\xc4\x83\x8f\x8c\x99\xc8\x98Y\xf44\xe8\xc6\xc3\x08\xfe\x04>;\xd1\xbf\xc6,gi\x9e\x8d\xa2X\x8e\x93\xfc\xcb\xe9\xdb7<@\x1feMsE6\xfd\x1a\xe7\xab\x88\x8d5b&\xb6\x89H\x97lb\x9f4-\x84 \xce-\x81W\x93\xcc\x97k.\xda\xac( a\xfbH\x14\xd09\xfe\xedW\xc6\x99sM\x19\xc0\xba\xb9\xcf\xb5\x19\xc9\xa0R\xcf\xc9\x11_D\x8ck:h\xf1\xec\x0e\xc2\x06\xed+\x97\xda\xa8\xdc1\xb8v\xb7\x88}i\x8a\xb0\xa6+}\xe9\xe4\xeb\xf6f\x87\x85\x88\x96\xed6\n5\xb6+\x9ekN_\x89\x00b\xf8\x1d\xfba\xfd\xce=\xca\x04\x1b\x8d\xaa\x8a\xf5\x13\x11\x0eI\xa0I\xa3\x9a\x0dB\xf5\x9e\x99\x07\xb3M\xbed\x131]0\xbbV@\x9a\x8c\x11C\xd5\xdfx\xd3\x16\xb6\x1f\xb2\x0c\x1e~\xef\x19Rl\xca8k\xea\xff \xf6\xf7\xb4\xd7\xe5\xd6\x98\xbc\xa2\xb0\xf5\xcb\\\x17O,\x9cT\x99r?P\x99\xf4\xc3\xf7\xfeF\xfepE\xa0$\xf1lE\xe6\x10\xc3*.\xe7\x90&\xeb\xa4\x86|A\xc7\xcbMT\xa0\xdcd\x95g\xa3V\x0eD\xa2DW\xb9>\x87.5\x93zK\x03\x97}&\x92\x08i\x9b\x19oy\x00\xe3\xac\x0f\xc0\x01\x00\x00\xd0_\xfe8M\xfd\xcd\x97\x8e\x0fi\xa0\x88\x97\x13\x82\x0cmfm\xe56p\xcdN\xd0-\xdb\x91\xb4/\xd8\xa9\xbc\xc3Q\x03\xcd:Xv\x04\xa5}\x89\xc4\xb9\x9aE\x1a]\x85o \xab'J\x8e\x0dtu-p\x1f\x1cla\xc7]\xa6\x95\xaa\xd9\x97\x0bPD\x11\x87\xc7P&_]\x89\x99\xf1\xfe\xa8o6\x8e\xd1\xa3\xd4\xe2\x0e\x06Qdh\xb2\x8a\x99 w\\\x08J\xbf\x0e\xd9\xaa\xfe\x98\\\xf8A\x10<\x85\x1d\x9fB\xc0\xaf0\xa9A\xcb\x8c\xff)\x87M\x00\xc4\xaf\xf8\xe5\x87\xf3`\xc6\xdft\x89\x12s\xcbi\n0;\xc5\x11\xe5\x16\x16I\x16\xa7\xe9X\x80\x8d\x071-; %\xd7\x85bL]Hc\xeaQ\x8dm;l\x10\xeer\x01\xb70\xde\x8c\xfa\xdc\xcd\x86\x15\x9ck\xde\xb2;p\xd2G0\xeb\xe7\x12Q\xac\xe2\xb0(\xed+Q\x8ck\xeeO-\x91A\x9d\x8cQEa'\xfe\x04\xfaY\xfeu\xe56p\xb1\xa4\x1d\xb9\xceRTj\x99K\x95cf\xd12!2%\xec\xee\x16\x97\xf8i\xd6\x1a\xd2,\xc0\xf1`\xbc\x1dxo\x90\x8d1&}\xef\xd5\xad\xeel:1J\x07%YT\x13X\x0b4\xd1\xd3sL\xa1<\x81\xe5p\xad&\x05\xd7\x04n,Ue\x04\x9c \\\x88\xaa\xfd\xa9\xb4O 5\x0c\xf9u;By\x93ay\\<\xf8\xc3\x87\x03\xf1\xe0\x87?=x\xfc\xdd\xb6\x9f>\xde:\xa5\xe4\xc1\xf6\x91\xef\xf7\xf7\xb6\xfdt\xff\xbb\xed\x13\x04\xec\x7fIF\xca\xd6+\xa9\x94\xf9\x8d\xe2\xed\xeb\x07\x93\x1b\x95\x98,2LT\x93\x8aY5\xe9\x07\x80\xb5jq\x80Q\x99\xecm\xebV\x9d\xe5Z\x8a\xa1$i\\'W\x04~z\xffc\x08\xd7I\xbd\xca75\xac\xe2\xab$[B\x0c\"\x13E\x84Y\xbe'\xf0\x07\x19\xf4\xf4\x0f\xf2\x1d\x7fZ\xe3S].Bh\xa0\xf8\xa9'\x97\xd6Z\xf5w\x9f2\x89ep\x82^b\x84\x9e \x9f\x0c \xcf\xf3M:\x87,\xaf%DJ\xb2 %\xc9f\x04.\xc8,\xa6X\x93/&\x80\xb3\x16\xb92\x11\xc3:c6\x0d$\x1e\xc4)\x1f!\xe9\x05h\xa3P\xfb\xde\xef=\xb7V7\xc6\xe9 \x9b\xbfwS\xa2\x89o\x8b\xda\x084\xe09\xd5\x98\x9eeA0\xc0\xb1 \xab\x80\x14\x99\x90\xe1U\xa6\x0c\xc2E\xc3 ,{\x8b>\xec\xbfr~\xce\x15\xabz\x1eA\x97\x91\xc6\xca\x10\xf3\x91\xa9C\xe1v\x81\xee\xb8W\xf9\xa4+\xce\xda\xfaKM\xf8\xed\xb6\xd0\x95\xbe\x03!B\xeaWY\x88\xcep\x0c\xbae\xae\x038\x86\x1a&\xd0_\x96:\x80 \xf8\xb4U8\x82W,G\xf8_N\xdf\xbe\xe9\xcf\xdb\xc8O\xf2\xcey\x1b\xb5>U`\x88\xef\xdd@\x90Zq}\xa6\xbd\x85f\x9a7.\x17\x7f\x0f\xfbR5V\xf7\xeb\n\xdc>\xed\xde\xd1\xe91\x1d\xcd\x18\x9b\xac\xe4e\x87\xca\xf6\x89J\x91'YMJNG\xe8\x9e\x87yN*\xacC>%U\x0dI\x06\xf3|\x86\xa1\xa9\xb5\xf9Th\x91\xadh\xce\x14\xcd(\xf9t\xbb\xc9\x16\xf5P\x9e\xe9\x11\xad\x95\xfe\xb21\xf9 \xea\x8c?\xdc\x14\x84\xeb\xfbN>\x15dV\xa3\xaa\x8f}\x14\xc2\x12\xadi\xe9\xbcU\x90\xd1\xc3\xd3\xdbd,\xaf\xcc\xdc\x03\x96|\xe0\xaau\xa3c\x9e\x92\xf7\x80Y(\x92\xe9\xde\x99\xbc!!Q\xb5\xb9\xa8\xea\x12s\xc1\x80\xe7\xc9~\xa6g0\xc1\x0cXHb\x1fx\x01\xd3\x86\xb9a\xdfb\x90~\xeb@\xc3\xd9\x82\x13\x89J\x9b\x8cT\xb3\xb8 >\x91\xc9\x9f\x1e\xfc\xd7\xfe\x83e\x88\xb9\x9d\x94g{\xf8\xec\xbf\xbazP\xd3\xd0\x8a\xc1\xa15\xfdkzg\x1d\xed\xa9\xbd\x7f|\xc0\x1e\xee\xbbv?\x1fdP~\xf6\xeb\xc6\xa4wG\xa3\x95\x11\x9b\x97D\xb3U\\>\xab\xfdZ\xda\x0b\xe9\xe9\n\xcb^\x86\xa6C\xf7u\x1e\xfe\xbc/\x8e_j\xdac\x8a!;\x98\xb9^ \x0e\xfb\xf1{\xfe\x03k\xd0_;t3;M~%\xf8\xcc\x10\xb4:1q\x0d\xf5\x01\xef\xc5K\xcdpsL\xf5\x95\xf3\xc0\x15\x1f\xf0\xda\xb9\x0cA\x1b2Sh\xd2\xec\xa7\x0e\xf4\x01\xc1)\xe01\xdd\x12\x13\x84\x00\xb22q\xe1\x17A\x93@Z\xdb\xda\xad\x9f\x19V#\x86#\xf0\xf1\xee\xc2\xfb\xbe*\xc8l\x1d\x17\xf7);\xf8'/\xa0\xd4\xed\xf7\xd8\x89\x9ep\xd6p\x84\xce\xfc\x1d\xdb\x81\xe9Y\x80i\xcf^\xe43\x0cZ\xea'\x98\xca\xd0\x86B\x1b8\x02\xcf3Q\xffq\x19\xadi[\x1b:|\x84Q\x81\xb7\xaa\xf9t\x83$\x86\xfe\xef\xda\x9c\xd2$n\x92\x18c\xb6\xcf\xfd\xd8h\xe8\xa1\xe3h\x86\xe7\x9eO\x13\xbc\"\xc2\xff\xb9\x93\n\xbf\x7f\x89\xbb\xfbW\xfdu\xe7 \xbd\xdaC\xa3Kr5\x94\x93k=\x94Xk9\x98\xb0K\xa6\x82\xd2~{1\x94X\xeb\x9c%\xba\xd5e\xb3\xbd\x16}jSH\x9d\x88>\xb5\xcd~\x1aL\xf2{:\x94\x13\xeb\xb9\x18\xae\x16J\x97B&\xef\xbfz\xc6\xd3\xea\xbf'\xcb\x93O\x85\xef\xfd\xdd\x9f\xc6\xf7\xffy\xb6;y\xf0\xe0\xf3\x83\x07\x81\x17\x82\x97x\x9a\xef\xder}\xf5\xf3\xe6\x8c\xf5(k\xf7\x9e,\xf0\xf0\xf6\xec2\xb4(x\x03&2M\xe2\xc7,_\x7f\x87\xebGk\x00\xe0\x17\x9c:\x04\xef\x0f\xf2\x1d#\x87\xbd\xe7\x1f\xf8\xa4\x07\x94?\xaf\x8d\x8a(f\xcd\xf1MI\x16\x06K\x0e\xa1\x91\xec\xce\xdf@\xdbE\xc1\x8b\x00\xbc\x86a\xa7\xd2^\x08\xda\x83I\x14\x94\xc8i\xad\xcb(\xa9^\x96\x84\xa47o\xe25\x99\x07~e\x0d\xeeN\xfb\xc2\xb4sJ\xf6#?\x93\x14\xd3~1\xaag\xe2\xda\xc20\x05\xd1\x04\xd6\x9b\xaa\x86\x0b\"Y8\xf0)\x9a\xdc\x7fO\x16\x81\x913U\x0bk\xc5\xe1\xfe\x98\x8f}\x02\x0e\xd9A\x16\x1b\xbc\xa3_\xd9,\xcamW\xa4\x14\x8e\x0b8B\xb1\xdc\xdek\x81\xa1\xb7\xf7\x1c\"E`\xd8\xee)\xf3\x9b\xb5en\xa3\xe5\xca\xf1\xbe\xca\xed\x02\x85\xb6\x96\xd2\xae\x0b8\x86\xdc/BH\xa9 gL.+\xca\xb8\xdb\x01\x8e, =-\xec\xb5A\x15X\xe6v\x88\xc0\x18\xd4\x01\x8e>\x0c%\xae\xdc>p\xc5!\xd0\x1f\xc8\xad\xd7V$[6\x91\xc7\xac\x9d\xdd8\"\x03\x12\x90\x95?\x0f\xe1*\x84\n\xcd\xbb\x1c\x16\x029\xa1M\x9aR\xb6\xeb\n\x8e\xc1\xbfA\x91y.\xfc\x07\x19\x9f\xe8/\x05u\xf1o\x02\xc62/9\xd1\x1dV\x93q\x99\xf6_\x06%\\)\n\x8c\xc6\x88\x80\xee\xa9%OhD\xe9(Bh\xe3_\x850\x0f\x82\x88+\xad\xe0\x18\x96\xf2\xef ,\xbb&]N[\x0ddl\xa3\x11\xbb\x0d\xb6\x00/\x8c\x051l\x01f\x18 j\xb0o@\xe0j\xa4\xa5\xc6\xc5\x98\xd3\xa9\xe9\xa9\xa2\xdeZ\xe7W\x84\n3\xb0t\xc8\xfaE\xf7\xefEK\x1b$\xa4\xe4\n\xd3\xdf\xb8-\xc77\x1c\xae\xd6\xca\xb63\x0b\x84\xc6\x89\xee\xca+\x14R\xd3f\x96\x17\xa12N\x91\x1b\xd0\x9acT\x14\xb9\x94W\xd6\xea\xb7\x81\x03\xe8\xdc\xce+\x10\xc4l\x9c\xc5\xb6Z\x84\xfa@\xab\x005\x15iST\xc4\xf5**\xc9|3#\xfe\xd6C\x00\xf52\x96ytNk\xbc:\x9d\xd6nA\xa2h\xc1\x8c\xfd\xee\xfb\x08F$\xa55\x15>hU7\xcc\x9d\xe4\xb9\xb2$S\xb5'\x7f:\x82=\xd4U\xec\x85\xcdmn\xe0\xd7AG\x1cv\xf2\xa4\xd3\x15q\xb1\xe3\xd7\xd3\xcc\xe1\xb2\xbf[\x86\xe2\xf2\xe8\xca\xad_\x8f1\xb7\xb9\xf5K\xe1\xa5q\xd1\x88\xe4\x17\xd6o\xed7\x12\xdd\"p\xc9\xc6\xb5\x81\x95\x011\xbf5\\\xf8\xf7\x9ejd\xb0W\\\x80T$\xbc\xd7&23\xcfg\xcf\xe3\xd9\x8aL\xe0\x9d\x1e\xb5\xe3\x8b*O75I\x167\x13\xc8\xf5uf)\x89K\xde\x8c\x9b\xd2\x85\xf33;\\\xf1;')\xa9 \xbb\x8a\x98t\xf1\xf7\xdd6\x91-\x94\x16\xcd 6\xa8x\xf4\x93TE\xf0 \xbc\xd5W\xba.\xe3\x82\xd7H\xf45\x96\xa4F2n0\xbfG\xdd\xf7\x04b\xfd[\xf2\xa9.\xe3Y\xfd\xb2\xcc\xd7\xd8\xc8F_M\xde\x06\xb9.\x87r\x19x\xce\xee\x920\x81\xec0\x88W$\x9e\xa3\xa1\x87}\xd3<\x9b\xcdHQO\xc0\x8b\x8b\"Mfh\x8f\xf3\xe0\xe7*\xcfBP\x9f\xdc\xc4\xeb\xd4\x1b\xde/\xc3\xf47\xcd\xe3\xf9)\xdaF\xef\x98\xe3\xaf\xdd:\xdf\x0c\x8a\"\xe8^\x84G\xf6\x80\x91\xce\xb6-_K\x02_\xc5\x0b\xf2c\x1e\xcf\x07=\xb4F\xe1-\xc7\x19#\x0fH\x97\xe1\x1dcF?\xe4\xe8\xa42\x81\x99\xbe\xaa\xb8\x1f\xf9\x8b\xfa\xc9%\xc9&\xb0\xe8\xd3\xa5\xa0k\xb9\xc3\xa7\x08G\xf0\xaa\xaf\x8a\xfc\xd9\xaa4\x17*V\xa2^\x0f\x10\xf5z\xa0cp\xd0\xeeD5J\xa9{\xe6FcMZ\x1enm\x0ds\xf0\xed\xf6\x9f>\xfa\x02C\x1a\xf5\xcd\xaf\xa0Z.\xad\xeb \xdb\x1a\xec\xc0\xb0\xd1\x0e\xe8\x8fI\x93\xc29\x17\n\\3\xba\xf6\x87\xc1\x14\x95h\x12\xa7Q!\x99\xb5\x94 ^1\xe8\xa7\x85lv\x1c\xadI\x1dS\xa4\xe6\x7f\xb24\\6\xe5\xe6f\x1b\xe5f\xdeUnn\xacZ\nf\xd0\xd4Isk\xfb\x08T\x0dl\xfb\x16\x1a!\xd8\xe813\x88i\x9b&\xc3$\xb5\x08;\x8fH\x88\xabL\xb1m\x89\x003\xf8Vhn],\xdag\x98\xee\x04\xb7\xc3\xf0X7[\xf0.\x80\x1d`B,8\x82Y\xcf\xfe\xa2[\xa8x\xcd\xf8\x1d\xfc\xc0\xdfca\xd89\xfb\xf4\xcbm\x08\xb3 \x88\x10\xd6n:\xd7i\"\xe5\xe8M\x08\xbf\xdc\x062c6\xe9\xf8\xa78\nb\x887I;\xc4\x97\xfd+\xe0_624\xe5\xb8\xed\xb8A\x0b.\xa4\xa3\x8b\x81\xa0W]\x13\x89\x94`\xfeqH2h#*\x8b\xbdT\xb9\xe0)(\xe6\x1d\x1d\\\xb5\x9bU;\x9b\x18'\xd1\x9a\x94K\xf2\x82\x90\x82\xae\x98E`\xba\xb5\xc5n\xe2\xad.\x98\xac\xdci|\x16\x04!\xcc\x18]\xa2\x84J\xd6\xe2\xba\x9b\xa9D\x96M\x08\x1eV\xf3\x02\xfaM\x9fG\x10\xc5Y\xd6i=\xc1XTc\x0eu\xeb\x19\xd9z%e\xf7\xdf\xc8\xd8T\xfd\xf5+\x1c\xd8\xf9\xd0\xadl\xd2\\\x90\x8e?&\x1b\x9b\xf0Qgei9+{\xd9\xd6q\x1d\xec^\x82\xe2\xbc\xec8\xa6O\xcf\xec\xea\x9d\xfe\x1d\xa2E\x1c\xe9wC\xa9q\xd2\xb1]+\xa3\xaa \xb3\x10\xaa\xa1})e\x90\xfey\xe2@\x84\xdd\xb4}\x9bi}\xa6,h\x19\xc9\xa5{\x1d\xcf\xca\xdcO\xed\xa4e\x94.E\xe0]\xe3\x87j\x0bR\x03\x0d$\xf2\x0e9\x1dv\xec\x18P\xb4\x04\xea\x8a\x88s/\x0bac\x10\xb3\xb4O%!\xd64d5\\\xfdoJ\xf6oB\xc9\x9a\xa4\xcd\xa3(\x99i/\xd0\xd1\xc6z\x1aa\xda\x08\xd2\xb1qC\xd9\x122d\x06NK<\xdd\xb4w\xf4:\x9f\x93T\xc0\x9d\xedjZ\xc7\x80\xeaN\xbbY\xe5\xed\xed\xbbx\x14\xe3>~\xaf\xc5\xff\x8f\xef5\xfd`\xcc.*\xd2T@\xdf\xf3l\x95\xa4\xf3\x92d\x13]\x8cq\x16e\xb0v3BM\x86l\x95\xe4\xe1&b\"\xca`\x0b$*\xca\xbc\xce\xff\xca\x9fgp\x8c\xbbe\xd3\xde-\x99R\xab\x89P\x8a\xc6\xc4W\xec\x99\xbf\xa7\x04\x8c\x08|\x12\x89\x99i\x94\xcb\xc6\xd3T\xb5\x84e_Ok\xc3\xa5V\xab\n\x1cAB\x913\x13\xa3\xd1\xba\x19t=\xf9~u\xc2\x19\x0fY\xfcm\xf8\xcbC\xdd\xcbJ\x98\xd7i-\xe8RA\x90\xb5\x0d\xcfTM\x91 \xf2\xae\x17i\x9d\xb4\xf6\xcc\xb0M\x86o-\xf3\x9cR\xc1\xdc7\x9a\xba\x81\x8d\xe8t\x1c\xc9I\x08S\xf3hd\\\xac\x11\x81\x89\\\xb8\xb9\xabnP\xf5\xb8$\x19\xc6\xc2\xda\xb1\xa5\x1bB\x1b\x13[\xfb\xa0\x08\xc5dJ\xd4t\x03v\xd5\x08p\xa3\xe3L\xee\x00;K\x17O\xcb38\x86\xc4\xa7\x7f\x0821a\x8fq\xbd\xe8\x83\xc1V\xb8\xe7u\xe2\xcb\x85f\xcdl\xd2t@\x91\xae_\x7f{\xc0\xa9;\x8e;G\x17\xc5\x97\xb1;\xa7g\x81\xd6\x19FL\xccE\xed$\xd9\x04\x19\x15\x92\x81$S\xd3,*\x7fS\x9ei\xef)\xe4\xf0}c\x87~\xef\x1e\xf8\x0c\x03\xf2\xb3\x10|D\xb8\x86lN\xcb\xb3\xe0)\xe4\xbb\xbb\x01\x0b\x911--\xd7\xfbb\x1a\x18\xe0E\xa1\xd7_eu\xd8\x8e\x18\xb3F\x0e\xdb\xaeu\x03A\x945\x82cfi4Q\x9f\x1e\x888\xc9Hu\xd0\xafE\x11\x1cu6\x0dN\xfb\x12Ui\x8dA\xa8\x05\x0f@\xdd\xc9#6\xa4\x98j9\xcd\xd0\xa8\x9eE\x8e-Y\xfe\x85\x1c\xad\xd4\xd0\xe8?\x04\xfalxg*\xc4w\xf4V4\xfa\xb7\x9b\x99\xf7\xd9X\x06o\xf8\xd6\xe5p\xc0\xf1\xf9\xdf\x8b5T\x7f\xfd\n\xdc\x84\x10\xc3\x1e\x0e\x89aZnB\xf0!\xfbZ\x8b{\xc1\x88\xeck\xe5;\xc9\x89<2q\"\x99\xff\xed\x00\xf6\x0cr\"W<\x03Y\x87\x99\x94\xa2\x1bKs\xab\xf2*\x03\x9b\x1a\xb7%f\x0b\x9e\x85\xb0\x08\xa1\x08a\x1e\xc2\nMF\xd7h\xbdv\x03G\x10\x97Kt5T2m\x1d\xa0uYc@!\xabL\x0f\xe8!\xda\xfaI\xf9v\xfdn\x97Z\x141\xf6\xeb\xd29\xf2\x14\x9e.O\x9f\x06P]'L>\x14\xd9, \x86\xce\xb1\xd11LW\xe8\x90\xd5S(\xce\xe1\x08nx\\\x99\x93\xacNJ\xf2\xa1$\x84\xa5\x18\xbe\x11\x86\xf5,\xb50\xad\xf6\x8f\x0d\xa9\xeaWYM\xca\x19)\xea\xbcd\xc9\x86\xe9\x9b\xaa\xc8\xb3\x8a\xb4^\x15\xf8\xaa\xad\xe7b\xd9Jo4\xb22\xcbGl'\xd2\x80\xa10\xea\xd5\x8b\xa4\x9a\x95\xc9:\xc9X~\xbe\xcc\x8d{\x92\xa6~\x06+\x90n\xe9O\xd9x\x83\xdf-\x1a\x98L`\xe1\xf6m\x1bh\x13(\xdc>\xebCu\x02s\xeb\x97\xb7!\xda\xce3\xf6[\xa6\xbe9\xbd\x8e\x97KR\x06\x0e!\xf3\xa0 {h\xadKe\xb15\x86\xf2d\x8aY\"\xb2\xac~\x1bv%\x8cN\xea\x0d*\x8c\xael\x863\xa2\xb0\xe1\xac\xdd\xc0\xd6\xcf\x80\xe1\x1a\xad\xab\xbaL\n\x11\x85\x14\xedl\x06\xadcD\xb1^\x12\xe1&\xfe\xd6y\x13/\x99\xe3/\xc9\xea\x10vJJ\xc2\xda\n|\xe6\xdb\x99\xa9\xcc\xe7\x12\xc1\xcfW]\x91\xf8\x97|Y2\xf4\xd6C\x16\x9f\xaeQ|Qn\x8a\xda\xf7X\x87^\x08K\x97\x19X2\xad\x8e\xc9\xac*\xb5\x18\x96L\xaaF\xc6\x960VI\xebb\xd8\x9f\x8a\xb8\xa5\x93j\x8b\x81\xc3F\x0e\x0d\x93\xb0p\xb9X\x9e\x14V\x9d\x99\x1f\x8ce\xaa\xfe\xbdX#\xfd`\xf2A&@s2\xef\x19O\xe6\xbd\xf6\xc9\xbcg:\x99{kjSE1\x0b\xe97\xf1z\xc0+\x809d\xaf1\n\xbb\xb9\x16\xc6\xe2\x8d(Yf\xe1\xb2\x0c\xb9\x9a\x9dG\x08|\x94\x89\x1eV\xfbFX\xed\xb7a\xb5?\xc4\xc5\x80\x8a\xdb\xe4\x13\x99mj\x16rZa\xcf\x86\x891#\xc2\x04I\x8ay\xc7\x86]\x1aDB\xf0\xfa\xe7\xae\x87O{G*}\xbc\xa9H\xf9\x92\xd4\xb3\x95g\x8d\xc1&V\xd4\xca0\xb0%\x9d@9\\M\x0d\xcaeI)\xac,\xffP\xa8\xb4\xdb\x10\x12\x831\xb7\xf5\xd6\xde\xac\x1f6\xed\xb6\x9a\x1d\x1d\x94\xe6k\xbb\xe4*\xd9\x0b\xfd\xdbF\xcd\xc1\x03\n\x1c\x03\x95\xd4\x0d\xa0\xcd\xb1-\xbe\xcc\x1f\xe2\xa5\xbeV\xd2n3\x87c\xf0\xf87\x1e\x18\xcd\xa4c\x96\xec\xe7\xe0m\x03\xe4\xe7\xf9\xba\x88\xeb\xe4\"I\x93\xfa\xe6u>7\xec\xe2\x8d\xc1\xdb\x96\x96\x05\xbe3\x92\x12\xc6\xaf\x90x\xb6\x92\xdd\x06\xf4\xa8\xb0s\xfa\x8d\xb6\xdbNb\x18\xd8l$&\xc5Z\x12\xc7\xf4[\xdaO\xa3:^Vp\x0c3\xfeg\x00\x13\x98&gc\xcd\xc0[\xce\xb4G\xaa3\xad]\xbb\x8a1\x1cX`\x1c\xfc\x8f\xddF\x0c~\x06\\\x97\xcd\x00\x9e\x17\xaf\xe6\x81\x9f\xe2\xfd_n\xdb\xf0\xa2\x0c\xa3\xc6\x04bk+:W\xedn)PDv\x1b\x11\xe7\x98\xed\x8d\xc2\x18\xba%\x8a\xa0_\x86\xfd\xd2-\x12q\x9c\xfd\xd9Z\xe4\xccL\xdeE\xb1\xf9wQ\x8c\xdaLgg\x01\xd0\x7fwwCH\xa6\x9e\x07\xbb0\x83]|D\xf1\xa5\x18n\x83\xa9\xa9\x9b\xb0D\xf4\xecK\xb0M\xfb\x8aP\xcc\xa4\xa2)\xed\x8a\xa2\xa4C\x04a\xacz\x04s\x16\x8a|\xfcp\x81wK\xe5^:L{m\xeeyA+\xb7:\x9c\xd3\xde\xcc\x89\x9bAQ\xe2\xb31\x17\xc6\xba\x06\x06Z\x7f\xa9\xd66;\xfb\xcaj\xb0\x10\xea\xa8\"\xe9\xc2\xe0'\xac\xde\xb2\x1d\xf6-\x10\xd6\xf1%9aL\x0c\x1cQ\xb2\xc1\x1e=+\x92\xeaC\xbc\x94\xb4\xa1\x92\x7f5\x95\x9d\xf4Vw\xc0\xb2\xea\xf7\x1dj\xce\xd4\xe1\x1b\x9d\xf63^\xb3hMh\x80\x1a\xd9h\xe2v\x07*t8?s\xad\xd9\x85Ic`\xa2\xb5\xa5\xe1@\x96w29$\x99\xe9>KVJh\xa5r\x9a\x9f\x0d*\x9c$\x81\xab\xb47\xf4\xc0x\xb5l\x9a\x9f\x05\xd8Xs\xf8V,,\x8d\xb9i\xceMO\xf0\xebi\xa2W\xf2\x9b\xf9\x0e}\xc3q\x91T\xba`\x81=\x1b\x0d=\xe6\xffK\"\xfaV \xf8\x8f\xd9\x03nK\xd9\x9e*=K\xfa\x84Q(\xf6\xbf\xd5\x9a T\\u\xdf\x7f\x93\xda\xb0\x02\x9a%\xd1\xbalj\xd6z6\xc6}\xa5g\x89\xca\xb4\x12:\xd7CMW\x0b\x16.\x8d\x1d\x1a\xfa~\xba\xf03:\x17*\x88\xa9\x13\xdf\x9a\xa5\x19w\x07\xf6\xe4` \xce\xf1\x7f\x86\xa6\xe7\x0b\x85O\x85\xd14\x1f\n>\x89*2\xdb\x94I\x9d\x90*\x04\"\xee*0JPV\x7f\xb8)\x08{\xca\x14\x08\xcac\xc3I\xc3\xa4\xaej\xb6\"&\xd9\x8c\x89\x9c\x9a;\x11m\xed\x8a\xd7\xee\xdf\x93h\xab\xcf\x98\xdc\xcd\"\x19\xfcT\x1ax\xf2\x05\xd6\x92\xea\x0f}\xa5\x82\x81\x87\x0f\xf4\x87|~\x13\xa2\xb6\xb8\xbc\"\xa5a\xf2s\xaeP\xa6U\xfe\x1a\x97I|\x91\x12\x83S\xed\n\xab\xae\xea\xdapE\xb1\xe4R\xaeP\x93\xe8k\xdd\xb4k\xfd\xb0I\xd2\xb9\xb1\xb2\x08\xe2\xf5)J\xaa\xb7\xcfN\x0f\x03\xbf\xd6\x1c\x147\xe8\xaeO\x1b~\x0b\xc7p.\xef!\x95\x88\xe8\x86 \x83\xef\x8c\xc4bS\xa6\x13cd\xa3YI\xe6$\xab\x938\xad&\x80Z\xf6Ut\x9d\xd4\xab\xe7\xcds8\x06/\xc9f\xe9fN0\x0ca\x15\xaf\xc9}\x16C\xcc\xd0h\xe3\x08l85gy~\x89q\xdeuF\x84\xfd\xf9\xc5\xa8\xfd\x7f\xa7A[z\xb4\x07!T\xb2B\x0fS\xe1\x08*\xca\xf4\xf3\x1a\x12\xed(=7\x80\xf2\x83\\\xaa%\xa9%\x91}\x1f_\x07CQew>\xa8\x91U\x9f\xfb^\xc3\xa4P\x89'\xc3\xd0\xb1Y^\xc3\"\xdfds\x9d\xab\x10\xed\xfb5F\x9e\x94\xd4C\x0f\xbeWmm\xd3k8\x86_na\x02\xaf\xf5\xd5\x7f\xc66\x87t1o\xb0\x86\x10\xd7\xf5\xf3{\x17m\xca\x14v\x8f\x8c\xa6\xa1\x83\xaa\x01F\x93\xcc\x01\x03$\xcd0\xdeT\xb2\x8dm\xbcU\xec\xec{c\x18\x9dF'\xf1\xc6pdr\x1d\xc4\xcf}\xcc\x0cB\xd8\xc9\xa4\xa5\x8d\x88(\x10ql\x0e\xe1]\x1fr\x12joBx\xc7\xd7\x80\xa2\x17J\xc1?\x07Q\x9d\xffT\x14\xa4|\x1eW\xc4\xc7\xa08G\xb0d\xca%=~\xbc\x97*\xfej\xfa\xe6\xccT\xb3\xe4\xd8\xce7b\x14\xa3\xbb=e\xa7\x0ch\xf7\x02\x8e\xe0\x99\xe2\xa9u\xea\xbfR\xc8_\x104\xcf\xdf\xb7\x9ek\x9a{1B+'4\x8a7S\x12%\xd9\x80-ai\x89\xb3\x85\xaa\xbd\x8b|~\xe3\xc9\x18\xb2\x8ca@\xbc\x8b\xd5\xbf\xa3\xc6h_Z\xb4-;\x11\xb5\xd0:\x8a}\x94\xc5k\xfck9e\x7f\x9fQn\xce\xf0>\xc1M\x1e\xb10\xadX\x19&p\xe9\xb3\xbfCx\x11tn;D\xc2\x96\xeb\xb8\xcc|\xef\x9d\x80+\x8f\xd4\xcf\x9a\xc6p\xfdI\x05\xf1\xfa\"Yn\xf2M%\x83\xdb\xd7+\x02<\n3\xee=X\xc5\x15\xac\xf3\x92\xbe\x893\xc83\xd2(\xfa1;\x00~\x91!\xee\xf7z\x88\xb39\xbe.\xe2\xaa\"\xf3\xfbI\xa6|\x8b\xba\x8d\n\xe6 \x8b#\xc6\xfa\x848\x83?$\xd9\x1f\xd8\xdb\xc8\x0bB\x11\\\xebh8\xf6bG\xd5%u\xeb\x8a8\x86\x91\xb9\x1bsCy\xf2\x85\xbd\n\x8cCHJ2\xa7\xbfvH\x84\xb7\xe2'\xeb\xa2\xbe\xf9+3\xf9nH2\xf7\xe2|/>h&\xd8\x06\x06\x856\x9dgQ\xe6W\xc9\x9chI\xb5:\x99\xb7]L\xf3\x98;\xa8@E\x8ev\xf5M\x81\x88\xa2\xd1@\x976\xaf\x0d\xe0[@I\xa3:\x90.\xdf\xcdK\x03d\xa02\x058M\xb48\xec\x85;\xb6vqA\x84\x97\x8c+\x1c\x91!\x041\x18\x15s\x80l\xf2\xbd{\x90Y\xb4\xce%\xf9\x871\x0e\x8d(rl\xd6@h\"3\xc1p-E\xa9\xfcj\xb8\xa6\xcdz\xc4\xd9\x9c\\\xa7f\xa6\xa4\xf1\xc7\xbe\xa9\xc3/\xcc*@\x0f6u\xe8N\x9d\xa0\x9d\xf1;\xcem\xd2\x9e\xae\x9b\x9e~\x0c\xe1]\xc0\x83\xef\x9ct\x1e\x07\xe2\xcc\xc3M\xda\xb6\x80\x97\xe7a`\xf1\xbd\xa43\xfc\xa9\x9f\x8aM\xf9~l\x98/q\x9c\xc8&\x8c\xde\x18\xa0J\x96\xbb\xe0cP\xfb{\xc8\xdeb\x18\xec&goE\xca\x04M\x8b\x06l\xceoC\xfa\x99\xbe\xa7\xe6\x10~\x8ec\x82#\xf8\xa9\xbf6\xfd\x13\x9c\x0d\xee\x9d\n\xe8>\xc3\xc1\x02#\xa17\xf6\xab\xec\x7foHy\xf3\xb6|\x99\x97\xeb\xc0\x7f\x17\x84\xf0\xeew\xed>Z?m\xf7\xac\xcama#\xb20\xb9\x97\x9e\x80ng\xbbMV\x06)/\xdbo\x14K\xa7\x1b\xc5\\\x11\x02\xcd\xb5\x12'A\x15\xa4\xbc\xec$TB+\x99!\x12\xffXp\xe6\x03\x86{\x15\xdf\x02J\x92\xb6:\x84\xa9\x87<\x9e\x87\xf7\x85~\xc9\x82\xd3Rv\xf1\xc7\xfc\xbaa\x17=6\xb0\xca;\x0bD\x9c\xb7\x81f\x1cj75\xcc\x03N1n\xbb\xf9\xfd\x8c\xc7\xd94sj9\xc5fDi\x97,\xae\x14\x91\n*\xc6\x8dL\x85*\xcd@6\xa59*\xdb\xd0\x0d_!c\xe9\xe5\x01\xfc \xee#\xcf\xe6\xa7\xec&\x86\xce\xb2\x9a\xaaUL>\x93;io\xba\xb2\xa1j\xbawF\xc7'\xda\xdb;\x0b(1\x14\x8dz\xbfxM\xcfn3o9zL\xcf\x98\x87\xc7\x83_\xfc\xe9\xdfo\xcfv\x83\xdb\x07K\xd5\xcf\xe3)\x0bs\x81\x862> \x9e\x06T\xb6\xd8T+\xbf\x9c\xee\x9f\xd9}6\x0d*`?\xdd\xe6f~\x16]\x89\xfd\x85\xbcq\xf3sJ\xac\x97\xa1b\xc2\xed\xaf\x86\x8fo\xe0\xc4g\xc3\xef\xf3\xa5\x0d\x9b\xfd\xb3\xb2\x13\xc9\xfd\x17\x99\x1c\xe6\xd6\x0b\xc1[\xda\x02\x81\xd0\xa5O\xa5\x97j9\xe8\xccd\xba\xdb\xd4\xf7\xd0\xb5\xc6\xb2m\xac;\xb9\x1c\xb1\x85\xcd\xae\xef\xc2\xe2\xcb\xd6 ]\xca\x95<\xb6\x19\x93l\x8b\xdfPj\xbe\xa9-\xdf\xd0\x13\xe6\x9d\xcf\x1dLgy\x8a\xb4\xf4\x9d_\xb6\x1f\xd8F\x9b\xe0\xbe[\xe5\x15z\x1e\x96\xf8\xd7\xf0\x17\xcc\x85\x8e\x92s\x14T\x1c\xfap\xc9\xac\xcb\xf1E\x84O\xf3\xe97H\x9e\x138\x86\x9cb\xf4\xe4\x01\xe6\xd4\xf0\x13\xd8\x85\x18\x9d\xf0\x82\xe9F\xf5\x00\x84c\xd8\xb4\\\x99`b\xc8\xbaz\xeb\xa7!hr\xb2\xdf\xfa\xe8\x9bk\xa7\x15\xe3x\x8a!=8H\x8e\xc2\x85\x0b\xc8\xdb\xc7z)R\xb2XX\x8c.j\xe5\x03\xa8E\x97\xb7}oT\xf3 T\x98\xf4K\xfc`;\x0e\xfd\xad\x8cma\xf4/\x8a!1\xc3\xcd\xa4\x83\x9b\xab\xba.\x06p\x87\x19\xf4\n\xdcL\xe4_C\xf8\x96\xe27\"\xb0\xbb\xad\xf6\xcc\x82\x99]\xac\x9caz\x17>\xc9\xae\x99+\x96\xf6\x89\xf0\x1b\x17&\xc6\xf2\xbfy\xf80E\xdd\xc4n\x98e\x8di&i\xa2\xe6nU\x03\x82\x7flH\xf9\x95V\xc86{ &\xb3\x8e\xbd\x8ep|\x08\x03\xf6\x17\x87\xc0\xce>w{\xbbw\x0f\xbc\x8b'?\xbd\x7f\xf5<_\x17yF\xb2\xda\xcf4\xbe\xa7:\xcb\xea\xbc\\\xbf\x88\xeb\xf8_\x12\x00~\xc64\xc1=\x0b\x16F\xa5\xe8\xd8\x11<\xf8\x87D\x13\xfa\xcbiC\x89-a\x1ee\xa7\xe3I\x7f,\xe6o]\xb6\xab\x1ei\x1d\xfc\x05\xfe\x93\x03\x0d\xa8\xbf\xee\x9c\xc5\xe8\xcb\xf9\xf9\x90\x12P\xc4`\xd2\x8a\xc8B-\xf9\xed\xe3q\x81r\xff\x05\x08\x8e\xb9bC\xa9\xcdu\x10*QU\xdf\xa4\x03\x95P/K\xd14\x1d\xf6\xae\xe9\xabr\x86%\x18\x8c_g\x1b!8moZp\x16\x13HP?_%\xeb\x82\"\xd4\xe0\x17|J\x13\xd8\xd0ol\x990X6\xa0 \xec\xec\x1b\xab\x99$\xcb!\xfa\x9f\x0b\xd2\xaf\x0bL\xf2\x1f\xc9\x98\x99\x19\xb06K5\xcc\x88l\xfa\x91\x0e\xbcM\xc6mF=n\xdb\xa5\x04+\xd2\x99\xb6\x8b\xe2\xcd )\xde*\x86\x8d|Op\xc3\xb1\\me\xa4\xb4\x0f\nq\xca\xacY!\xdb\\$\xc5\x8c\xa9\xbc}?\xf3\x86\x0fAQ\xf8n\x19\xb5\x15E\xc1-\xe9\x98r\x95\xf7\xe3\xe8\xce\xcew\xa7\ni\xb7\x0f\xc5\xb6\xe3\x07\xf6{\x82f\xb4\xf0\xd0IP\xcd\xc6\x1dJ\xee;e\xf4\xa1\xd0\xdf\x1e\xad'\xb7}U\x0b]\xdf\xa9\xc7S(K\xe6\x8c\x12\x9e\x9a\xbf\xec\x9ad\x11\x14\xbb\xa6g\xae\xdd\x81\xeat!\xc1\xb0\xff\xa8\xe3\xe5\xac\xdf`[t\xe2\xfd\x0f\x14\xfcM\xed\xfd\x9c'\x99\xefi\x9c\x13\x95w\xd0E\xd8_]#\x9b\x0cid\xe3F#\xdb\xd5\xb9\xb2[\x90\x17I\x85\\!\x99S\xfc\x88g5;\x01\xf3P\x1f\xc3\xdeb\xb8i8_\xb5VF\xf5X/\xb0Krcc\x04\x9cTl\x16M,3\xfd\xb42D\xcc\xafk\x88\x1e\x00W\xeb\xda\xe7(\n\x87\x13\xe6\xd6\xb2Ku\xe2(\x1c\x8e\xe1h8\x8f\xa0\x7f\xe6\x88\xc2\xa2\\2\xa6\x92\xb15M\xb6\xdc\xf1{lc\xca;/7Qhrv\xc1\x81\xa4\xf1\x05I\xbb\xe3`.\xf2_e4\xd1\xe0h\xd6q]&\x9f\xbe2X\xc6&r\xe1M\xb2,2 \x1c\xd3\x83\x84\xb9\xfbQ\x06\xef)\x05U\xcdX=\x0c#2a\xaa\xce\x10\x7f\xe9\xc70\xe0\x8e\x8a``\x8a\xb4#\x9b\xa7\xbe\x90`\x13\xee\x1c\xdb\x8ccB\xfb73\x9e[\xc0\x15\x1c`\x0b\xcaBkn\x02\xc0(\xed\xb3-Q\xc43\xf2\x82\xa4\xc9:\xa9)\x93\xee4\xfd\x94O_\x99\xf8o;o\x0f\x83\x15\x18RX\x0d\xcc\xbeH\x8a\xd1\x93\x9f\xfd\xcbM\xfe3\xc6\x0eu\x9dh\xde\x0d H\xeb\xa1AE\xc7\x1d\x92\xbe}\xc2\x1c\x92\x1e\xe9\x1d\x92\x985\xf9#]~\xff\xd4i%\x05\xec&\x0f\x8e\x7f?=\xfb\xffv\xbe\xb9\xf7\x07?\xf8\xe3n\xf8\xf4\xc8\x93\xf7\x19\xdcp\xb6?\x15\x8d&~L\xa7\x0f\xfe>\x8d\xef\xffs\xef\xfe\x93\x8f\xf7\xa3\xf3\xff:\xdb\xfd\xe6A\x12\xd5\xa4\xaau,\xd7\xb6~\x01O\x0e\xf7\xb7\xb7\xd1?\xd8\xfe\xd3\xc3/0\xefo\xbd\xfa\xb7\xd4\x8a\xca\x00\xa9f\x95\xa6\xdd5\xb5\xec[ a\xcc\x9a\xc1\x84(\x96\x08\x95\x9a|(\xd8\xe6`\"\x14\xb3\xdb\xef\xa2\xef=\x8bw\xa3\x86\xcbbtR\x8c\x84\xc2\x9d\x18\xdc{\xe7\xed1\x16b\x8c\x06\xdfeLx \x80\x89F[q\xeb\xd7\xd4\x10n\xe4\n\xb3-\xdc\xbb\x07;;\x1d\xfd\xea\\D\xc8\xd2\x7f\xb8\xee\xc7\xc6\x8aC\x98z3a\xf6\xac:\xfd\xde\x9c\xb2\xf0\x00<\xb6\xcfP*)\xe5\xa6l\xd1\xbd\\]H\xe3\xb4E\xdb8\xad3\xf42P\x14\xd8W\xf4\x1f\x16\xd3\xa6s}\xd5\xc0\x0bG\xd5\xfc\x94a\x7f\x8e\xc1_il4\x06X\x13\x19\xe0&\x83$\x1bN\xde\"8\x98\xf9t(\xb6$p\xa4^O\xb3\x01{\x0f\xb4\x07\xb0\x9d\xd3R\xa1\xcb\xf3\xd6\x7f\xfel\xbb\x10\x03\x8e\xfd9zN\x0c\x9b\x9b\xb0!X\x9bCy?.\x92\xffEx4\xcc8\x00\x0f\x17\x93\xdf3\xf2\xe0\x98\xfeB8\x19\xc8\xeb\xf0$\x08\xc1c(\xd1\xab+.\xcf;\xb5\xd9\x9dp\xaf\xb6\x08\xc0\xa6\xd6\x1e\x9e\x1d\xa8>\x18\xcc/^\x8c\xde\xce\xf2\x80\x8c\x01\x1aW\xc9L\x8c\x86\x85\xccp\xfd\x1e\x14\xae \xc1@\xc1\xf6[\xcfnAuYT\xc4Uu\x9d\x97\x03a\xcatE\xc8\xb3\x8a\x7f,\x0buA\xd9\xa3\xca\x01z\xa2\xc8\xb5\x8a\x9e\xa9w\x8ep\x04\xde\x0f\x14\xfcN\xf1\xbf\xbc\xe5\x81*-R\xae>R\xa1\xe0r\xf9\xb9\x87a\xdf\xe9\x06\x8eVq\xf5\xf6:\x13'`{x\xb9-_\xb2d\xb3 \xcf)Bi\xfa\xdeS\xa8\xe1{8\xf8\xf6\xd1S\xd8\xdd\xad\x03 ,\xda&\xf3\xca\xa1t\xff{\xd8\x7fD\xb9\xb1=\xc5\xf2\xb1\xe5\x17\xd4q\x0c2\xab\xef:>:\xbeR\xb3\x8ebJ:?\xe4l\xca\xb6\xb3V\x91\x18\x8e\x00s\xce\xd5Q\x91\xc6I\xc6>\xa7\x9c\x1a\x87\xdd\xac$qM\xfcl\x93b|y\xca\x0b\x96l\xda%|/\x1d\xb8\xe8\xdc\xcb@UV\x91iy\x86\xf8\x98\xd1?\xd8\xef\xee\x92sS\xe9f\xcd1)6)\x97\xa43\xfe,\xec;\x92\xa2\xba\xb6IC\xd9\xe1\xc3\xd9\x0d\x99T\x7f \x9d\x9b\xd6\x03\x81\xd6\xed\xc6\x0e\x96\xeb\xa8\xb3\xa5E*gVDk\xfa%r\x9cS:\x1d\x83\xe8\xe5\xe7\xedE\xf8\xfc\x99\x8a(i\x9a_\xbf\x13\x18\x8c\x0fw\xcah\x16\xa7\xa9\xdfEo\xba7\x18\x11 S\x0cv\xbb\xb37b\xc3\x0fy\x809LK&\xcd\xecBLp\x87D\xbb\xfa\xbd\xa0\xcd}\xef\xdf\x8c\xcd)A'\xd0\x16\x9aS\xdc@m\xa7\xae\x95^#\xc7\xe0g}\xc1:\x0b!\xd1*\xc0\x18\x8c \xbe>\x062M\x10\x9f\x15\xad\xb6\x84\x02}\xc5k\xfc\xff\xec\xbdk\x97\x1c\xc7\x95 \xf6]\xbf\"P3KU\x0d\n\x8d\xee\x06@\x11MAt\xa3\xbb\x014\xd4\xe8n\xf6\x03 \x00a\xa0\xac\xcc\xa8\xaaDge&\xf2Q\xdd\x8d\x11\xe6\x90#\x8a\xc2\x83;\xb3\xde\x91\xa8\x91=cy\xd6$H\x00\xb3^\xdb\xeb\xb5\xd7\xf6\x8e\xf7\x1c>\xd6>Gs\xa8\x99\xbf\x80?\xb0\xfe >\x117\"2\xf3\xde\xc8\xac\x02 R\x9c\x1d\xd59\x12\x1by\xe3\x1d7\xee+\xee\xbdqFcp[\xfcSc\xeeB\x81M\xe2o(X%\xf9B\x8e\x97\xbe\x9cjS\xf7\xf8a\xda\x0e\xada4\xd6\xe1j\xd2\x1b^\xf7\xebc6ms\xc2#v\xf4\x88\x01\xe8t1bT\xde.\x01\xbe\x90\xa6\xfe \x9cDs\xd4\x18\xca\xf3\xcb\xa6\x0f\x13\xd2H\n\x88\x9d]\x0foX\x06\xc6\xd1\xc0<.$\x95F'A\xfb\x8b\x93\xaa7\xa8_\xc9\xb1X\xce.|Tf\x17f-\x946\xc0<e\xbe\x9e\x9e5_O\x7f\xc7|\x9d\x9b\x9f\x97q\xc5G\xf5\xc0\xe4\xa0\xd8\x82\x80\xb2\xb9\xf9W40\x12\xd8\x0e_\xe7gO\x96>\xcf\x9d\x9eg\xb2\xd9\xef\xb1\x97o\xb0\xa3\xe2\xcb\xfc+\xecG\xec\xe5\x13\xec%f\xea\x9c:5\x7f\xfae\xd3\xff\xa9\xef\x9c8y\xb2hb~\xfe\xa4nbn\xbe\xdc\x06\xb4\xca^b/\x9f\xb07\xddND\x0bs]\xb9\xb0/\x9f:u\xe2e)S\xcc\xcd\xce\xcb\"\x1d\xf6\xdd\xef\xb2\xb9Y\xf6#\xa6\xbe\xa0\xb5\x97; C89k\x86\xf0\n\x19\xc2\xdc<\x19C\xf3\xd0:\x0d\xac\xc2\xce\xd5\xddh\x14;ns\x14n\xf5\xcd6\x8aaQ\xefV\xdd\xc5Cd\xbdr\xa0\xe2g\x9cD\xf1\x02kE\xd5\x0c{\x96fI\xeef\x91zH\xbb\xf4\xa1\xe8\xab\x16\"4\x85b|\xdfb_VaU3/\x16C \x1bTS=\xfe\xcf\xe6g\x8f\x0f\x8a\x16\xca\xf7\xc4\xd5\xc50\x97\xb2\xad\xadsK'N\xbf\xf22J\x1f\xd3\x97i\x89\xe1m \x8a\xbd[\xe7\x96\xe6\xbes\xe2\x95ib\x8c\x88\x90\x19uY\xeb\xa8-\xf3\x04\xa5\x13jh\xcf\xd1\xcd\xc4+\xe6j'f\x1e-\xf5W\x8b\xc0a\x00f\x95\x9eo_\xf5\x0e\x02E(6P\xbe\xbdF\xb7/l\x9f\x9e\xc3a4\xbe\xfa>\x8f\xbe\x9b0W\xb5\xbd\x93n\xfdY\xe9\x04H\xef\xc8P\xbf{\x02O\xb9H\xc7\xac6/;\x9b,;\x99<\x13\x19\xf9\xf8\x1a\xe33\x03\x9e\xed\xf8#\xde\xee@\xf5\xd2\xbf\x17T\xbc\xfe\x11x\x19\xcf\xa2!Vt\xa6\xe2\xbb\xcc\xf62\x03\xe7@\xca\x9f0\xb0\x05\xf9\x97\xfcc\x9aY2\xb5\xf0A\x97\xb9\xf5t;oC\n\x97\\\x12h\xb52G,~f\xba\x02/\xf6\x0fhp\xf1\xef\xa9\xea\xfb\xd2\x80\xa0\x0b\x1e\xf1\x85\"\xa03\xe3\xe8\xd3\xd1\x01\xf3\x91\xfag\xd6\xe92\xc7\xcc\xb4\x81\x07\xa5\xb2\xe9z&#\xad\"\xe94\x13ef\xb2\xca\xbc\x083E\xbaDSm\xc9\xd0\x02`bA\xc5\x18\x14\x1c=\xda|\xe7);\xbe\x1e\xdcP,.\xb81U\x87\xba\xc8\xb4\xe9\xfeX\xad~\xa7\x7fc\xf5\xe8W4\xf1\x8d\xd4X\x96\xcaj\\\xf6\xb4\xc67M\xd2\x8c\xba\xe4s\xb5{\xde/v\x88\xc5\xd3n\x90\xdc\x9c\xfeL\x1a%Y\xbb\xd3e\xb1\xf9K\x06\xea\x95\x9e\x88\x14{\xf7=\xd8\xc3c\xc7\xeawM\x0e\x04v\x8c\xc5\xd3l\x98\xc1\x8e/\xd8\x99\x8c\xed\xbb\x1e\xdc\xe8\xb2#N\x9b_wotY&\xff?\x9c\x8c\xdbZx\xd14\xa8\x90yi\xfa\xfd\xbb\xc5\xb1\xab\xc0\xee\x96\x1c\xa6\x8c\x7fR\xde,kHu\x9c\x15Y\x17\xcfT\x1e\xce\xbaki0\xadm\xf0H\x1bH\xab\x95\xa8\x8a\xef:\xffV\xe9\xbbA\x0e\xe9\xcc\xa9;\xa9(\xfb3n\x14\xcb\xb7\xf8j\xc0\x92_I\xf1\xa8\xa0\x0c\xea!d[\x8f\xd7go<\xaf\x04\xa49%=(\xc0\x0e\xe8u\xb3\x8d}\x9e8=ka\x9f\x13/\x98\xd5\xe2Fj`H\xad\xbbK\x19o\xd8\x9e?1[1\xb4_L\xa3pS\x1cw\xfd\xa0\x9b3S\xfc\x13\xacN<^\n\xa2P>*=s\xd3\xfc\xb3*\xee\xe5\xd6%p#\xfe[G\xc8s\xa9+\xd4\x11\xa2\\&O\xa9;\xdc\xf9\x8c\xf8o\xf5@\xd9\x14\xaa\xc0*\xa9Kw\x03\xd0K\xean5\xb5\xd5\x9e.\xa7d\x02\xa2w\x0b\x17P\xd4\x1f\x8f\xab\xfcO\xc3i\xe4Mt\x97\x85\xb0q\xa6\x8cM\x8bs\x95\x93JR\xe3\xa7R ~\xd3\xd2\xcf\x91\xb9\"\xbc\xeb\x8cN|.\x1f\x98?2\xdb\xe9\xaa\x82V--a\xaf\xb1Dp\xc2\xd9.\xe3\xf2\xeeDH[l\x81\xc5\xf2\xa3\xcc\xb8\xdcR\x179\x00\xa2\xab4V\x99\x0d\xed\xe8XAE\x8b\xa5\x95\"=x\xb0{\x9e\xee7\x8a\xcd\xce\xb93\xa5\xe6\xe4\x1d\x8a:\n\x16\x9b\x9dlF\x9d\xc7\xe7jJ\x8bl\xe2T\xd6\xb7,\xa5C\xd3\xacT\xa3\x05\x8eO\xd1\x93D\xd4\x10D\x94.\xc3\x0d\x89\xad\xaa\x0c\xa1S?\x06ql\xca\x1d\xdaw@\x9a@\xe4\x11cg\x04\xf75\x88\xd81Od\x01\xb8\xc3\xb2a\x12\xed\x8b-#\xcai\xbb\xb5#\x1a0\xce\xc1\xac\xef\xf8\x01\xf7Z]\xd6\xdaY\xd9\xde\xb9\xb9\xb1\xb9\xb2\xb5\xb8\xb3\xba\xb1~\xf3\xdc\xe2\xea\xda\xcarK\xa2T\xd8e|\x82\x18\x86\x16G\xac8E\x92\xba\xcd\xad\xae]i\xc5\xab[\x88\xb7:\x0f\xecf^\xd9\xaa<\xef\xb4\xcd\xb0\x90\x18j\xeb&\xcd+h\x1e\x81g?\x8c\xe2\x1f\xca\x8bL\x9ed\x87\xccOY\x18eL\xa8\xf9Q\xbfX\xe2\x94\xa9\xa8J\xe6\x87l\xeb\xdc\xd2\xb1\x97O\xcf\xce\x8b\x05/\xd6zc\xf3\xe6\xea\xfa\xe5\xc5\xb5\xd5\xe6\xf5\xd6\xcbR%V\x95\x7fE\xca\x92\x8fT)\x8eU)m\xe6l\x03=`\x90WW2\xd0\xac\xdd:\xde\xb2\xd8>a\x17\xc8\xe7!;\xc3,\x8f\x16\x8cKv>\x0b\xb31!b\x146h\x80\x1d\xd6\x84\xe3J\xd3\xe2\xa1|\x1a\xae\x8e:\nb\xf8\xaa\xf5\xcaWl\xf9@\xda\x16\x877\x14\x95-\x11a\x08\xde.\xc7\xb3]\x1f\xdc`\xaf\xc9)\xf4\xc18\xd6\x9e\xed\xb2\xa1N\xc5z\\f\xe7\x1b\x8a\xee\xc7\xec\x18\xe4\xe2o\x8f\x98\xa1\xbc\x95\x00^\xd9\xf8aA\xb8G\x82R\x0f\x8f\x1e\xc5\xf7\xc8^\xad\x89_\xe2\xfa1@\xf4AG.\x9e\xa7\xad\xee\xd6\n\x0d\xae\x8aL\xe3\xbf\xb4\xf6\x95\xa5\xd2A\xa7\xf9H\xac\x1c\xc4\xdc\xcd\xb8\xc7\x9c\x90\xe5a\xea\x0f\x04\xba\xf7\x9c\x94\x1f\x9b\x9be\xea9d\xa6\x08\xf3\xc8\xd9\xf3\xc3\x01\xcb\x86\\6\x96\xf0>Ox\xe8r\x0f\nH\x80\xf4\xe9c<\xe0\xf2\xa8\xef\xfb\xd9P~\xbe\xc3\x93\xe8\x98h\xd6\x03\x81\xb5z\x8a6\x17w.\xdc\\][[9\xbf\xb8vsqkk\xf1\xea\xcd\xd5\xf5\xe5\x957\xd4\x99\x02\xed\x8e5\xbd\xe5W\x9d\xb2\xdc9\xb1\xa0\x7f\xfc\xc7\x83iu\x1b\xa6\x96p\xc8\xbew\x86\x8d'\xdd\xcb\xc8\x85\xae\xf2H\xf1e\xc0\xbeg6q\x021\x1fr\x19\xc6\xe1\xf7}\xbd&\xec\xd2\xee\xf6\x0e[\xdf\xd8a=\xce\x06\xd2W7a\xd9\xd0 a\xc5\xa5\xc1V\xd0'\xb5\xb8\xa9\xa0Jf\xc9\xab\x0bzyqmw\xe5\xe6\xc6\xee\xce\xcd\x8ds7\xcfn\xec\xae/oO\xbf\x96\xf2\xde \xd8\x92\xb4\xdc\xa7\xd7\xc5\xf4n\xc0\xedV\xd8e^\x97\x0d\x04\x99\xeb|\xfd<\x8b\xd5\xd1R\xfd\xb3\x08\xccE \xc3@\xb9\xc5\x1c9\xc3\x06E\xaa\x83?n\x15\xf8\xe2\xcc\xe4!\xe4\x9a\xdct\xb2a\xe1)8\x90\xa7\xbb\x113\xf0\xaa\xe5\xdf\x9cU\xab]1\xbaZ\x1e\x032Y\xc3\xa8l\x02s\x7fz\x81\xd9&\x16\x13\x07\xe1\xe6\xa5\x91\x7f\xb3\x94\xdf\xce\x05\xe5a\xa3<\xcd\xc4qq\xc2\xe2\x18l\xaf\xbc\xbe\xbb\xb2\xbe\xb4rs}c\xe7\xe6\xe2:\x10\x14\x1c\xe12-\xbb5\x9e>\xf2F\x9f\xef3\x1d\xd6\xa4\x0e\xb9\xf2\x00\xebB>Msk\x9a\xb3\xef\xb2\xf4U\x96\x1f=\xdaa\xfe\xf5\\\x86`\xcau\xba\x9e\x0bN\x05\xf7\xf7\x12R\x16\x8d\xac\xda\x8bO\x054\xbfqC\xe2 \x1bRw\x0bU\xbd\xf6\xa2^\xf4\xd3IVJ\x96rB\xa6\xba\xa9\x10&\xb5%\x1bg/\xae,\xed\xb4\x00k\xc5z\xbcJFy$\xbf\xce\xc5\x01\x9a\xb6\xdf\xafD\xa2\xab\x1f\x9eq\xbe-_\xd9\x81\x826\xe5xEa:b\x87\xa9\x86-\x0cr\x8aa)\x9f(9\x92\x82\xc4\x1d\x07\x12\xa7>\x177\x81\x8dc\xfdv\xfdX\xe5\xa9K3'Q\x1c\xbeu\xbc\xf5\xed/6\xde\xb2\x1a\xc7\xa9\x1a\xc7\xa5\x02 X\xadm\xb9\xa5\x027\xedr\x8b\xc2t\xb9\xe3\x84\xa7\xe2X\xb5U\x88\\/\xe0\x025~(F\xf5C\xe6\x84\x1e\xfb\xa1\x18\xcd\x0fK(\xd4\xa9n\xcd\xb9\xad\x8dK7\xb7V^\xdf]\xddZ\x994W#/\x98\xa9V\xd4c\xf3\xb5P+\xcd\x02\x94o\xa1\xb5Eq\xca\x99\xcb\xd2\xd3O\xdd\xf1\xbc\x1fv\xd9\x0f\xd5\xc8\xd4\"\x88\x115,\x02\xc8\x1b_\xfd*83C'\xdd\xd5\xc9n\xdaz%\xbeyK\xb1\xb4\xb8.H\xdd\xd2\xc6\xfa\xce\xe2\xea\xfa\xcd\xdd\xf5\xe5\x95s\xab\xeb\x13\x96\xc6r%Q6\xc5\xa8e\xa87cB\xa0\xb4<\xe3\x85:\xd8\x98_\x83)kxD+\xd8E 1\x1e_\xd2\x98\x94\x1d\x05\x15I\xfd\xb3y\x0f\x96\x9cP.4OdT\xb2\xa3\x16\xb7$\xe48\x99\x14f=\x9e\xfa \xf7\xa4u\xcfB\x03\xd5\xba..\x97W\xb2I\xe6\xab\xc1\xad\xb2\xe5\xc2|,\x0c\x0fM+\xed\x83W\x99\xa3\xdc\xac\xa2\xe7\x9a\xb8\x98be\xce\x8e\x9c\xa9\x10\xf33\xe6E\x1c\xf0\x91\x1f\xf8if\x99\xfd\xee\xfa\xd6\xca\xf6\xc6\xda\xe5\xc5\xb3k+\xd3\xce\x7f\n\xfaZ\x8fQ\x81\x10\x07\xdb\x16\xff}\xfdk2\xd0\xea\x1f\x18j\x81\\O\xbc\xa3\xab\xc9}.~wo\xd0c\xa3\x7fb\xaa\xd2\xeb\xbdq\xc9\xe4\x9c\x03\x99\xf9\xe2K\xec\x9a\x98\xc7\xd4\xfb&\xd9\xc3\xd4\xfb\xd6(\xd7yZ\xae\xc3;f\xf7\x8b\x93B\xd4\xf3Iq/J\xb8\xd6\xdd\x87\x1d\xd6oW\xe4\xeb\xb0\xd3\xc5\x02\xb7\xd0\x03~\xf4#\xa1\x11\xd0F\x1aL\x1e\x89L\x19\xf6\xa3\x1f\xd5\xe5\x01\xac\x84t(\xd7\xfc\xc2\xab1\x12\x82y\xd2\xe6\xd7\xa3\x1b\xd2\xb79\xd4\xc6\x9dI1\x0b\xcd\xee\x81\x926\x94\xfdn\xf1\x1a\xd7]\x81\x88\x1f\xecLm0\x99\xf9K:\xed\xca\xf7\x92\xcf\x1enF~\x98I\x0f\xfa\xc0Du\x17\xfc\xee\x0cs\xcdW\xd8\xdb3\xaco\xbel\xc9p\xbd\x04\xc7\xe7\xe2y\xe9\x0b2u\x8bb\x91\xd4A\xebM\xbe>\xc5V\xadaR\xd6\x8c\x8a\x85\x12\x13\x1c;\x81\xef9\x99\xf4\xe9\x8aK\x1f\x84\xd6\xe5}K\x15\x9b\xc6\xb3-l\xcf\xbfR\xea\xbd\xd6w\xdb\xa6h\x1dI\x94\xb72\x9f\xb9\x99\x81{\xac^\x9e\x9d\xc3\x98\xab5Y\x0de@U\xe6\x0b\xa9#\xe1.\xf7\xc7<\xe92\xf3\x96\x84L)\"x\xe2\x11|\xcc4*!\x1c\xf9BQ\x0b_(\xad\x0cM)SN'Sr\ni\xcf\xcfw*\x8ew\x96<25\xbe\x93\xf4\x909\xfd\x8c'k\x91\xe3M\x13a \xafk\x93(\xcaVC\x08\xc4>C?\xe9w\xc9\xd1\xf7\x19?\xf4\xb3\x8d\xc5<\x1bB\xb2\x98<\x1b.\xca\xde\xd2\x197\n\xfb\xfe O\xb8\x80Zj\xc6 7)\xdc\x16e*(is\xee\xf9\xa1\xd7\x86\xcb\x0f\xe94\xdeT\x0d\xf2\x1a\x9dan\xb5\x16%O\x94\xa5\xa6\x99\x93\xf1\xcd \x1f\xf8\xa15\x0eD\xfcD?u0&W_\x12\x87t\x81Ez\xb3\xeay\xb7\x03\xcb\xd2\x185\x96\xf2\x80\xbbY$Z\xb4\xbf\x0fY\x93\x95\x16r\xdd\xd4\x0ft?q\xe2E\xdd\xbf\xfdQ\xae\x89\xee!U\xdaa\xdd\x05\x0c(v\xb5\x8a\xf0\x91B\xf8\x13\xa7O\xe2\x9c\x19>\xbc<\xd4\x9e?A\xb2M:\nt\xe2\xf4)\x0c\xca\x0dH\xe6\xd90\xb0&\xb7c`C(\xdbc\xd3\xed{&\xa3J(iWQW6\xbc#\x89\xea&$\xe80\x91D*\x05@\x06\xd1\xdf\xfczX\x93K\xa2L$x9\xff\xa7M6\nj}\xaf\xa7\xcfzY\x93\xf1\xb2Y(s5\x89\xb5\x18\xdb\n\x9d\xacL;\x0c\nQ|/\x1e\x0d\xd9\xd6\xa7\x85\x16\xca\xa5\xcdR\x14\x12\xdc\xd5r\xfaMz5?\xddX\xdc>\xd1\x91 \xcd&>\xb2\xc1\x16\xd8\xf5\x96%\xd3b\xcb\x12\xa6*\xd4\x82\xbc\xdd\x11r\xc8j\xd8\xben\xd2E\xa4]v=\xbbA\xd2\xc1\xc0F\x04\xec5\xe6\xcb\x07\x99\x13\x94\n\xb3![\x99\xfd\xdc\xebdq\xb5\xae5:u\x9c\xcd\xcf\xd2F0\xc5\"8\x0b,\x98\xc9\xa2\x8b\xdb\xe8=gHS+NB#\"\xf4\xeb\x1c\x8d4U\x98\x1a\x0b\xfci\xb0\xc0\x81\xb7[j\xb1 7O ~eX \xc3\x98-X\x907aA\xca^c\xd1\xf3b\x81\x0d\xcb\xd5\x96\xa5So\x19\xfb\xa6\x89F]\xed\n-\xa5#\xca+$\x84d^r\x14d\x8e<\x00\x90Kq\xf5;\xe8+$\x1b\x9e\xc3\x11\x16\x81\x8a\x87\x98\xb7\xf2\x14\xf7\xeb!\xa7\xfa\xaf2\xa9\x97\xfeT:'kT\xca\xc9\xdae\xc1\xcc\xf6\x85\x8d+7\x17ww.\xdc\xdc\xdc\xd8\xdc\xdd\x9c\x90oY\xfb\x95e3\xb1-\x9f\x9f\x9e\xd1L\xca\xb3v+\x1dF\xfbe\x84\x17\xa8Q\xda;\xfbx\xc4P6\xb6V\xaf\xad<\xefH(B'&Op?\x89F\x17\xb7;BW&\xa5\x80\x90\x0c\xc4\x80\x8b\x1c\xc1-x8CV\xbe\xe4\xc4\x1d\x1c\xf8n\xd4%\x1ef\xc9\xe16\xbf\xdd\x9e6\xe3\xba\x96\x0dP\xbaN\xdee8\xb0U\xff\xe4,\xaf\xcf\xd6\xe46H$t\xae\x06\nIe\x159i\xc1 \x17T*\x939\xcfjl\x0c\x95T\xab2\xc7H\xe9\xa5\x1d\xbf#W,\x92[\x1c\xda\xcdG\x85\xa9\xac\x94\xdf\xd4\x9a\x97\x87\x95\xc2}\x8aq\xca\x93.\x86\xa9\xb9R\xebFC\xfca`\xaf\xab\x19\x96u\x9aLm|\xdb\xccET\x0e\xbbL\xd5ot\x9f.xe^?*H3\xb7P\xce\xa6\n\x8f\x93\xf5\xb2\xc8)?\xdaS\xf7Ls\xa7S\x1e\x96\xda\xba\x1b]\x98j[\x7f\x98\x98\x11B\x066\xc3y,\xa1\xb7\x10\xad\xa6?\x8a77\xc4\x9f\xf3/\xe6D\x86\x92Q\xdb\xcfaX\x97,\xd9\xa9\xf1u2\xe7\x10\xde\xeb!o\xfd\n\xaa\x17u \xcfH\x95\x14$z]$\xd6T\x96\xc6\x81\x15\x96\x88\xd7\xb9\xd1-\xe7\x05\xac[\xaa\xb5\x8d\xf3\x1b\xbb;/f\x81,\xc4hf\xdf\xcf\x86\x97\xf2\x0c\xaeG\xa6\xc8\xa8h\xc9\xe4\xd5\xf8\x8c+\x9f\x81\xc0\xb2\xda\x10^\x0b\x9a\xd5\x98N,\xb8\x96L^\xc0\xa5\x8d\xf5s\xab\xe7w\xb7V$/z\xde\x85l\x1a \x18\x16,\xdcG\x8d\xea\xb7+\xc0t\xc1\xf6\xb8\x04\x83\x94s\xf2\xd3E\xb3x\x90\xd4\xad\xfaO\xaf`\xa9\xe7\xa2d\x0bLY\xe0\xbe\xa4\xd2\x0f\x94\x98\xee\xd9\xc3ug\xc4S\\q'2}H\x90`\xd5a\xa9\x9a\xe5\xb8i\xdbS\xde\x0e\xdb'\x89t\x15)\x08\x95\xa1 o\xc3),D9J\xb4z\xbe8\xe2\xafDV\x1a\xab\x04B\xf5\xc7\x8a\x9a\x05\xcb\x967\xcb\xe2\x01\x19\x82\xec\x90Z\xe5\xe8\x08enr\x1f\x8a\xbc#\xd9\xa9\x83p\xa6v/'\xf7\\\xd3\xf1tb\x0b\xd2\xa2l\x0f \xb4\x8d\xec\xe4\x80\xecT\xfb\xcaQh\xe4\xa05?\xcd\x88\x90\xc5\xca\x96\x8b\xe7\x16\xb4\x18\x12\xb6\xa2\xa9\x84-fD\xaa:\x81\x8b)\x9c\xae\x17\xbaXIYt\xac\xe2c\xb9T.\xc9T\xd2\x95/%\x86\xe0\x1b\x9b\xa7\xc3vn#\xb9]\x9c\x17\x91\x92\x12\xeb\xe1o$\xa7S#@H\x11\x80\xce\xcb\x8d\xc24\n\xf8\xcc\xbe\x93\x84\xed\xd6\x95\xc5\xad\xf5\xd5\xf5\xf3\x0b\xcc>2?e\x1e\x8f\x13\xee:\xe00\xeb\xb1}?\x08X\x8f\xeb0\x1e\xed\x91\x19\xf2\x83\x8c\x8d\x9c[Q\xc2\xc6\\g\x9aB7\xe2;\xd3\x04\xbb\x11\xe7\x99\xce`,I\x98?\xa1W\x1b\x8f\xc1\xbf\xca\x9b\x039PF\xa9\xba(\xd7\x95T\xd0\xbc\x97^b\xed6\xbcp\xa1$\xe3(\xe6i\xab\xd3\x99\xd9\xe3_h%\x99\xf4~v\xa30s\xfc0U\x17N\xb2\x87T\x8bI\xdc\"w\xeb\xdf]\xe5\xc1\x98+I(\x08\xa2}\xeem\xc3\xa8\xba,\xed\xa8\xe46\x99\x84\xfb]f9\xe9\xba\x1d\x1f\x9e\n\x95\xb9\xcd\xec\xf4\xc0\xaf\xa3\x07\xddI\xa2B\xfdbh|u\x92\x81\xbc\x08L\x0b\x07\xb79V\xcd\x15f\x8a\\\x9f\xbb\xc1^\xab\xfes\xa1\xe9TMEtT\xa16\x18\xfa\n\xaec\xe7~e\xc6\xa3\xfa\xecL\x9f\x84\xdc\x1c\xf14\x1a\xf1)\xc5fSG \x1e/\xe1\x9b\x9f\xa4Y\xbb\x06G\xac\xb2t\xd3.V\xe4\xbf\xc9\xfc}\x82da3rh\xa2\x84\xb8 \x92D_$\x13\xa9\xeeg1\xa6\x06\xe2\x0b\x9b:\xe3\xa7\xe2?\x10\x1b|\xe4H\xa6\x8c\x95\xcf\xbd\xcf*\x97#2\x9b\xf2\xce\xcc\xc8\x89\xa7h\xa5\xd4\xd2\x91#!\xec\x7f\xddv\x1b\xaf\xd1#s\xb6\xad\xd7\x87\x0b\x99W\x19E\x84\x8a\xa2\xf0\xa5\x11A+F\xe5]\xff\x16\xfbFhD\xfc\x80\xbb\xb9\xf4,\xb0j!]\x95\xe5f\xfe\x94E\xd7\x90\xd6\xceH2\x88\xa4\xaa($\xcd\x8aB5^\xb8\"\xe1\x17\xe3\x99R/\xad\xa0\xb7]\xcd\xcf\x9a\x04)|\x9aj\x9f\x83\x89\x94\x1a\\\xe7\x8e\xe8\xa8\x0c\xd6\xd90\xaayr,\x97%\xa6x\xc1M,C\x968\x0d\xcf\xc9\xd6\x1f\x95\xe2\x80/(\x03\x90>\xeeb\x9f\xaa_\xd4\x89\xae\x97\x1eJ\xd4\x7f\x81%5*\x88\xdc~+hb\xfb\xe5W\xdd\xca\x1d\xe0VMS\xf6s_K\xc8x\x1b[\xa9\xac\x0d\x80\x93_\xcd\x1by\xb0\xa3\x0b\xcc\xb1\x83K\x0f\xde\xd4\xd8(\xcb\xaf\xe6X^\xbf\x95rJ\x1d-\xfa\x86P\x89/\xe3\xf1\xd2\x0f\xebnB\xd3\xa1\x94\xd8Vn\xe7N\xf0}~\x08(\x86\xbe\xd1\xf5\xaa[*j?\x917G\xdf\x80\x15\xa4#K\xdba\xfb$y\xe7:2>\x16\x13\xfd\x8dj\x05I>\xd3\xb7\x10\x16{\x82\x02\xf1\xf3\xa2\xfd0\x98\xd2\x1d\x89Y\xc8emj\n\xfd+\xf4D\x9e$\xea\x02\xb9Y]aZQ\x9at\x8d\x8c\x7f\x8e\xa94u?\x10\xf8Tp\xfb\xc95\x02I\x9f\xfb\xa0\xc4v\xcc\xddv6\x93 ~'\xf4\x8a< \xda\x9d\"\x93\xbf.\xb6\x9b\x04u6\n\xfdk\x1e\xbbL\x14#8\xac\xea\xa2[7\xc6\x00\xfe ,\xdc\x0d\xb8\x934\xbc\x8d\xa1\x7f\xcf\x83dB\xfe\x0f\xa6h3O\x82\x05[\x9e\x16\xfc\x13\x03\xde\x96^\xd1G\x1a\x1e<\xd4?\xf5 \xe9j\x98\xf1\xc4\xe5q\x16%\x0b2=\x0f\xfe*\x96j:\xf9\xb5\xfc#w\x8du\xbf\x1a\xef\xee\xf2/\xe1i\x1c\x85)'C%\x9f\x7f\xfbcu\x13\xee\xf10\xf3\x9d ]`\xad\xd4\x19qEg\x1b\xe2\xe0\xf4O\x91\xb7&\xa7\xf6\xf2OP\xc98[\xa8\xbe\xe2y+\x8d\xc2\xee\x1f\x1c\xff\x83\xc9\xe4\xad\xf9\x94\xdc\xed\xccdC\x1e\xb6\xfb]\xd6o\xb8$\xb0Bj\x96\xc9r\xc8\xa6\xd5\x8c\xb4@x\x1d\xa2\x1d\xcc\xd1\xec\xb2V\x11*\xa4i\x8a\xf9\x08zG\xab\xe1\x0d\xf4\xaa\x1553&Nx\\N\xdf\x01r\x95\x11G\xfcg\x01\xc4p)\x90Ws h\xdf\xa8\x92\x1d6\xebLdT\xd9a,\xa8\x85\x90\xb5n\xc2\x02\xddT\x93\xbb B\xf8\x04\xbcQ\xae#\xb6\x04n\xfaW\xb3I\xe4\xab\xcd\xff\xb9V\xb7\x0d\xaa\xdbh7\xe3N\xb7\xb9\xc6)\xa2\xce\x8c_\xfe\xddm\xb2\x0c\x97\x7fU+qe\xb8pc@\xcc\xd4\xfag\xbb\xd9\xb0\xda5i\xe7\xd3\x04\xd8L\x8a[113\x8d\xd9!u\x10N3v\xd5\xa3\xd5B\xb3\x0d\xd8\xf6S\xb3\xb6\xbc.g<\x98 \xd1)]\xf0nQD\xe6;m&=\xf5\x98\xdc`\xed,\xa2\x88j\x1e\xa0\xa2\x9b\xfa-\xfb\xbf\x90\xb5k\x82\xe7O\xf5\xab \xca\x99\x9f:&\xe7\xab\xf2 \xfa\xed\xda\xe5\xbe\xace\xf3\x85\x9e\xa4\x1a\xf32\xab\xe2M\xdf\x8e7\xf6\xba\xea\xdai\xbaH\xb9t\xe6EG\xca}\xe9x6j7u\xdba\xfb\xf4 \x12\x9c\xa6\xee\xa8N\x9c\xb0\\R\xc9\x00NZ\xc5Q\xa0\x93\xb3\xb3\xb6P\x04\x00\x11\x0bm\xaa\xc6pr\xb6\xe6\xecXB\xb9\xfe\xe9\xc5\xb3}\xcd\x01\x18c\x95T\xb2\xda\xc8\x80gk\x91\xeb\x04 `-4\x9b\x03\xb5\xf7\x834K\xc4N\x92\xf2\xab\xceHU\xed\xb4\x0bi\xa9q,\xbf}bf\xec\xd8g\x0fw\x130Tk\xfb>|op6\x85\xf3S\xb9v\xc0U'^w7_\xa2\x96\x169\x9b\xe9\x87`C\xef`E\xb9\xee\"^O\xe9\xb9\\#\xac\x06*}\x99[\xb9*\xa0\xf2\xb7<\xb7\xe6\x9cFh9\xda\\)\x1f~\x97\xf96\x03\xbf9\x0d~\xfd\x1dIh5\xe2\x87U#>{\x8d\xb5\xa3&\xfb\xbdR!:\x02w\x9f\xab\xd8n\x12\xb4[\xe2CU\x89\x08KV\xfd\xc2\xa8?\x93'\x81@2x\x81]HH\x99\x8a\x84#\xe7%\x04\x03\x89ED\xfd\x06\x9f\x9f2\xe6\x0fx6%\xa6q\x15\x0d\x83\xdf\xdf\x94\xf6\xfc\x05\x19J\xf8\x0d\x9d\xa5v\xef\xe8*\xe1q\xde\xf6\xda\x9f\xf4\xf0\xf0\xbf\xbc\x87\x07e\xb0u\xb1~\x82U\xdb\xef>e\x00\x91\x8e\xad+\xc5sE]\x96\xce\xecn./\xee\xac\xdc\x84\xd8\x86\xed A\x0df\xef\xe0\xb9\xf1j\xb4J\xa1\x04\xd0P\n\xdc\xeb\xce\xc6\xf9\xf3k\xd3\xf6\xfa\\1)8U\x89\x19\xb2\x8a\x05;\x82\x02=\xa2o\xc2=\xf7\xf3\xc9\xd3\xd7\x0d[\xb5\xd9\x1f\xa6\x91\xad\xa7\x90o+ \x16\xea\x8b1e-\xe0\xf8\x15\x8d\xe7\xd09\x9f\xfb\xbe\x91C&\x1b\x95c\xb4[xtNa\xb2f%\x84\xda\xf7C/\xda/.3\x86NZ\x93\x00\x0d\xff\xb2\x99\xc09\x8c\xf2L\xc7uKJ\xbe\xccy\xbc\xe6\x87{\x17\x9ct8\xcd\xfd\xd2\x04\x1b]-\xf4K\x98|\xc4\xae\x9a\xfc\xb6\xb5\x1b[\xf2\xcc\x99\x90\x06\xc4$\x1d\xdaq\x06\x0b\x85\xbb\x10\x1dJ\xe5\xcb\xdd\"\xd1\xacEUq\xa4\x9a`UU\x00\xf4\xb2-|\x07@\xdf\xb1+\x17\xce\xd7'W\xff\xf6 \x89\xbc\xcc\xd8v\x93(\x08v\xc0\xf5.U\xffPw\xe0\xf2[\xc2\x1d\xefp'\x82r\x8a\xb8\"\x1c\xae\xd45!X\xcd\x0e\x8f\xfd\xda\xb8\xf6\xbe5\xf2\n\x0c-'g\xb1\x97d\xaej\x9c>AR\xa34\x86\xb6c\xde(\xdf\xa0l\x07V\xac\xe8\x7f}X\xc1\xd4*\xc5\xe5e\x9cH/\x0b\xc67\xc9\xcf\x06\x9c5\x81&5\xc4\xbdLKp+\xef\xf8c\x0f{\xd8h-\xafU\xde\xc2\xcfT\xee\xe3\x08r\x1f\x17\x9e\xf6y\x8d\x99\x1e\xb2*V\xa9y\xd4\xe9\xb2\xb0\xdd\x91\x8f0\nT\xf4\xc3Ag\x8aG`\xc5\xfeG\x13#D\\Yj\xae\xe1\xd6 0O@k\xa14\x10Bi \x84\xd2\xa0\xa1\x9eV\xa6\x13!\xef\x8b\xe3#+\x9fK\xa2\xd1j\xba=\x8c\xf6\xc3\xef\xf3C\x89\x88u\x0d\xc8\xdca}\xf4:ls\x7f1\x8d&\xeeO\x8e\xa5\xf1\xd8\x19\x16O\\\xa9\xa1,\xd5\xb4Rr\xc0n\xa7\xac\x9e:B\xcc\x12\x93\xef\xc8\xa4\xa2\xf5u\xe7\xe5\x9d\x8cyX\xf65\\\xbb-\xe3\xd0\xe1\xcaA\xd3\xa4M'\x83v\xd9Q\xe6Iw\x16\xf1\xd7P\xaaTs\xd5\xf6^z\xe9\xb9\x1b\xac\x8b\x84\x98\xea.\xbe\xaa\x07N\xff\xb2Z\x95hT7\xc4\xc3\xf4\xb7\xf9j\xa4\xd6\xd8\xca\x8a\x8b( \x107\xa1\xcd\x9bYTs\xfdd\xae\x9dp\x1eIE\x06\xafs\xfaTW\xe3T\x86\xb5\x0cf\xaa95[GX\x85RV\xe4\xb2z\x0c\x9f\x92`2\x85\xe6`z)\xa8p\xa7J\x9f$\xbbh\xc2\x8f\xb1\xc9\x06\x04\x0f\x90\xcc5\x1c\x8d\xd6\x11\xf08\x13\xc4\x8c\xe9\xcc\xf9\x91\xa9\xd8\xe9J\xc4o*\xd1L4|\x9c\xf9w\xfah\x12\xfd\xd3'\x9e\xebwhT\xba\xdd\xf6\xf1\x9b\xc7\x07]\xd6b\xad >\x1c\x13(\x94#\xe9\xa8o\xe8\xa6\xa0\xa2\xbb%\xaa\xda\xf6\x1b\xe6\x18J\xfe\xdav\xba\xf0\xdc@h\x8eP\xdby!\xe7rl\x95\x9f&2\xf3\xa9,l\xac\xe2\xf7\x8b\xd0S\xe0\x9f\x96\xeb\x043\xa9Y\x03\xd7xi\xf9i;\x01\xfd;0Z:\xef\x80\xe1:D\x1a\x0c\x92\x11%g\xc7e*\x92\xa5-t\xacq\xddF5\xb2\xe8\x8b[\xb9f!A\xca\xbd`&\xec\x87\xc5Zn:\x89\x98/\x17\x92\x8cY9u\xd7-\x0b\xc8G\x1eg\xb2\xa8\x96\xac\xff\xd68\xc4@\xae(\x96\xf7\xa7\xb1\xd7O\xc3%d\xbb\x8aWP\x87\x1340\xbb\xe5\xa9\xda\x8d=\x9e\x01m\xc4\x94f\x04M\xf0\x8d\x97\xaf\xfeC\xe1U3\xe5\x97\x84|\x14\xe7\x19\xf7\xb6\xb3\xc3@\xe6#\xae\xad \xd6\xb4\xe5\xf4\xd2(\xc83\x95S;\x99\x89\xa3T\xc6\xea\xd4W\x93\xf1\xf7\xec5v\xbc\xed\xe4Y\xf4#X\xc7\x1f\x0d}\xcf\xe3a\xe78[\xa8\x02:\xc7\xeb\x99O\xab\xef\x1fp\x0f\xf7\\\xbc\x90f\xafidx\x99^\xf0U\xf9\x1fG\xf0\xe0b\x91^\xad\xa7\xd221\xbdm\xa5\x9cN\x97\xb5\x8f\xc8wTZi\xe6d\xbe\x0b\xae\xd3\xe5\x81\xbd\xf4\x12\xf3eZ\xe0v2\x13\x8dy\xd2\x0f\xa2}v\x94\x15\xff\xb8Z\xf9\xd7\x1b\x9d\xc2\xdd\xde>\x17=\xd3IX\x88\x14\xc5 \x960\xc0\xf3\xdaT\xa9\x93\x8d_\x88\x96-\xb0\x86D\xe7\xba\xec\x02\xab\x89q\x13\xbf\xcaQ^`\x83\x06,.\xb3\x9f\x056\xae/I\xa4\xae\x056\xb4\x13\x1f{\x1b\xa5{\xe9\xfa\x95\xa8r\xa6i\x1d\xbf\x18\xc3\x9e\xccM\xef$\xf5UZ\xac\xed\x01\xb4_\xd4{\xa44\x8b&\xa9\x1e^;\xf1\xbb,\xb7SgDX\xb2\xa1\x9fvY\x9d]\xd5\x08\xc1\xa9\xd5\x90\xed\x1aCv\xda\xe9J\xeb\xed\xec\xab\xac\x0f\x8f\xf8\xf5\x8f\x1e\xed0\xf7z\xbfj\xc8\xee7\xbf\x16/\xd8\x9cO3\xa7\xc2 \xe5\xbb\x83\xc1\xcc\xcd\x9b\xd2\xb9\xec\xe6M\xed\x12]\xf2)\x0f:\x1d\xe9a\xa6L\xe2\xbc\xcb\xae\x8b\xba&\xc9\xb2\xdb\xe9\xc8\xf0\x99(\\\x8b\x1co\xa2\xfdL\xff4\x07\xf6g\xe2$\x8a\xd3\"\x93\xc2L\x16\xc1\xc1j\xca5\xc0\x14\x17F\x92G8\x939\x83\xae|\x04U}]\xf5\x1a8*\xbe2\xadH\xb0\x82?\xd4\xe9\xc4p\xc3\x10\x12G\x02{V\"J\x96K\xe6\xe9\xbc\xb4\xd2\xf06<\x92I\x82.\xaby\xf6hO\x88=\xad\x84\x87\x1eOj\xcc\xa6\x8a\xdaL\xbc]a\xc5\xa0Rdq0Q\xaai\xec\x84\x84\x9c\xd1F\xfa\x0b\xf0\x9c\x04\xe0Cm\xe1\xbb\xdd\xda\x9e\xb8z\x90B\"F\x1d?\xa7\xab|\xa3\xd3E)\x19\xee\xb6\x8b.\xcc\x15\xf37\xda\x87\xe7\x1bG\xfaCi\x176\xff\xfc\x1d\xd9/\xfd~G\xf6\xbf8\xd9\xb7\xe8\x85\x9a\x13d\xce\xe0\x0b\xd3\xec\xf0w4\xfbw4\xfb\xab\xa6\xd9\xcf\xe7\x1ag!?\xb5It\xa28='\x13\xb2=\x87\xe3R10\xc4Kt\xba\xaf\x93\xb3\xa7-L\xe3E\xe5\xfb\xfa\xe6\xeeG\xa3\xb7(\xc9{gy/\xa5TA\xbe\xd5~\x86\x85&`\x13\x87\x0f\xfc\x97\x85\xa1\x93\xcc\xd4l\x8a`\xa8)\xed\x19\xcc\x04\xeaB$\xf9tlD\xff\xa6\xf5\x1e\xc2?U/\x91\x0f\xc0w\x1b\xbc7'\xb6f7\x9a\x19h\xb3\n\x03\x13\xbf\x98F!\x9e\xfc\x146L\xf6%\xe6os\xe3jwf\xa2P\x90\xdc\x80g\x96G!m?\xb3\x8c/\xbd\xc4Zz\x10\xe5@\xcdP^\xec\xa6<\xdb\xf1G<\xca\xa5\xbb3<\xb8\x7f\x86\x1d\x99\xeb|\x95+_\x0b\xad1s\x92\xaf\xd3\xd2Y9\x15\xeb\xa1/\xefF\xf9\xbd\xc6\x96\xe7d\xce\x82?r\x06\xfcx:\x1e\x1c=\x18\x05\xaf\xf6\x9c\x94\xbf|\xb2\xbbya}\xfe\xda\xe1\xd9\x13\xce\x95\xadYgy\xd6\xbftkq\xdf\xbd0\xf0W\x97\xceF\xd7\xae\x04\xa1s\xe1\xf5\xd3\xab\xb7V\xf7/]8{r\xd5_\x1c\xf0\xf3si/\xbctzu4\x9c\xf5.,\xbe\xbcvx\xfa\x84w\xc2\xcd\xbd;\x97\xf2\xde\x89\x8b\xe1\xda\x9d\xd5\xfdK\xcb\x8bc\xf7\xc4\xb5p\xd5?;\xef\\\xb9|\xe2\xf5\xd1\xe9\x93\x9b\xdb\xab\xfb\xab\xcb\x8b\x83K;\x8b\xfb\xab\xcb+\xfb\x97\x96V\x07\xee\x85\x8b\x81;\x7f\xf9\xd0\x1b]>\xeb\x9e8\x1b\\=\xb1\xb5}\xf5\x8d\xad\xb8wg\xd6\xe7+s\xf1\xb5s\xc1\xbas\xe5u\x7f\xf5\xfczz\xf5\x8d\xf5;\x9b\xdb\x17\xd3k\x17.e\xee\xe8t\xda;\x1f\xe4\xd7\x0eW\x07\xee\x89\xadS\xbd\xf3\xbb\xa7WG\x17\x87W\xe7\xb3\xd0\x1d\x9d\x9e\xeb\x8d^\xcf\x9c+s\xc3k\xf3\xbb/\xaf\x9e?5\xee\x8dv\xbf\xb3z\xbe\nw\xcf\x9f\xbe\xe3\x88\xbe\xe6O\xbe\xbcz>\xc8\xc5\xdfW\xaf\xec\x0f\x9c+\xa7b\xef|0\xec-\xa7\x83\xab\xa3s\xb7\x9cy\xef\xb0w\xe2r~mi\xee\xf0\xda\x1bg\x83\xabo\xbc^W\xde\xdf\xbcup\xcby\xe3\xe2\xad\xde\xf9\xdd\xc1\xd5\x13\x83\xd3\xab\xb7v\xf7W\xfd\xb3\xb7\xf8\xce\xac\xbf\xbe\xb3\xe8\xaf\x9e\xbf\x16\xf7\xce\xef\x9f^\x1d\xc91\xf9\xab\xe7O\x85kW\xce\xcdz\x17V3\xf7\xc4\xd6ao>\x0b6\xb7/~\x87\xcf\xaf\x8f{\xa3k\xf1\xb5\xc3S\xb7z\xf3\x07c7\x9c;\xbd\xea\x9f\xcd\xaf\x1d\xce\x0d\xbd\x0b[\x87ko\xac\xcf\xba\xa3\xd3\xc9\xb5\xed9\xb3o\xfcDv\xab7\x7fj\xe4\\qso>\xd8\xf3\xce\x0fO\xf7\xb7W\x07\xbd\x91\x9b]}ck\xd6\xf5\xe7\x0eQ\xdb\x87W\xafl\xc5\xde\x1b\xeb\xb8\xdc\x1d\xef\xc2\xc5\xb13\xbf\x9b];\x7f\xee\x8es\xfe\xdc\xa1;:w\n\xd5\xdd\xbb\xfa\xc6zt\xf5\x8d\x8b\x87W\xdf\x08d\xfdb\xfc\xab\xb7\xd6wv\xe7\xc4\xffV\xfd\xb3\xa6-\x18\x93X\x93\x15\xb1&\x87\x9b\xdb\xabw\xd6K\xf5\xd6\xael\x0d\xdd\xf9\xe1\xd0\x0d/\x0e\xc5z]\xda\xb9:\xbbvk\xef\xce\xa5;W\x0f\xd6\x97/\x1d\\\xba\xf3\xfa\xfc\xfa\xf2\xca\xdc\xea\xf2\xee\xfc\xda\xad\xbd\x13\xebw\x06'.\xed\xbc~g\xfd\xce\xe0\xf0\xd2\xce\xa5\x93\xab\xb7N\xber\xf5\xca\xa9\xb8w\xe5\xdc\xec\xb5\xcb[\x87W\xaf\x9c\xbasmt\xfa\xb0\xb7}V\xae\x99s\xe5\xe2\x9cw\xfe\xf2\xc6\xd5+sb\x8dg\xdd\xd1\xb9\xdc\x9d\xbf6vG\xb3\xfe\xea\x85\xadS\xae\xc0\xa1\xf0\xe2\xd8;\x7fn\xf6\xda\xf6\xea\xe0\xea\xfc\xb9\xf4\xea\xec\xdc\xf8\x9a\xc4\xad\x83\xb87\xbau\xf9|\x90]{\xe3\xd2\xe9\xd5[\x8b\xdf\xb9\xb4\xbd:\xb8v\xe1\xb2\x98\xf3\x81{\xb8:\xb8:\xba\x1c:WN\x9e^\xbdu\xf6\x8eX\x0b\xc0\xab\xade\x81g\xde\xf2\xac\xef\\9\xb5w\xed\xca\xb5\xb87\n\xc4X\x8en.\x9d\x1e\xf6F\x81\xd8\x9f\xe0\xf2\x85\x8b\xc3^\xb8>\xea\x9d\xb8\x98m\xde\xda\x1f_\x9d\x0f\x0e\xaf\xce\x1f\x04\xe2oq\xe66\x07\xd1\x99\xd67D\"X\x8a\x82\xc0\x89Sx\xbab\xcd\x0f\xf7\xe4\x1f\xe0\xcb#\xff\\\x0d\xe3\x1c\xfe\xda\xe1\x07\xd9b\xc2!\x0d\xea\xd9<\xcb\"\xe0\x16[\xd2KX6\xa5\xfe+\xb3}\xcb\xb7{\xeb\x82\x11\xa5\xff51Ch\xcf\xecW\xac\xafS\xf6mF\x10G7f3i\xf4mF\x90T\x01H\xef\x81\x02\x10#\x88\xab\x00\x15#\x88\xf4\x13\xb7\x9b\xbf\xbf&\x87m\xdaqLx\xbd\xb10p\xab\x85!3\x16\x06\xae^L\x98}\x95\x85\xec\xbb\x8c\xbf\xca\xc2\xa3G;L\xc5\x0d\x17\x16\x86\x10\xa9\xe1jb\xd9tI\xa3U\xe9#G\xd0\xac:3\xb7\"?l\xb7X\xab3\x93%\xfe\xa8\x8dEg&\xb5\xfc2f\xd5wd\x96#\x9b\x14\nLl \x99R\xdbSb\x1c\xc9\xa8a\xa4|G\xdc\xe9(\x99\x05\x8a\x17\x12K]\xec+\x1aIPj\x0b\x9e\xdfE6\x85\xccj=\x98`9\x98\xd6j\xa0\x11\xa4\xd0\xd6\xebET\x95\x834\x0f\x82\xd4M\xb8\xed\x81)\xfd\x0bM\xc9\xfa2\x96\\q\xbc\xcb\xae\xb7\x8a\xf6e&\x9d<\x08j\xdf\x1e\x93\xc9\xec\x8cg\x8e[k\xf5\xe0 \x88B4\xaf\xad!\xed\x84\xd4J\xf7\x9d\xc1\x80'\xc7\\\x8dn2\xabN\xc8^c\xadcr(l\x81\xb5\xea\xbc\xc6\xa7\x1fG\x9b>3\xe97\x99e\xdc\xc0I\xd3u\xf9XZ\xdc\xf6g\xcc?+\xafj\x95\x7fw'\xbb>\xde\xe8Tb\xfd\xdb\xae\xc5\xceR\xa5\xde\x1e\xf1\x97\x1bE=?\xe0bI\xaa\xfb\x9c9\xbd\x80g\x0b\xacu\x0c\xfeB`\x8f\xa7{Y\x14\x0b\xb8\xfa\x13\x15\x08\x9cd \x9a=6\xf4JW\xb3\xafV\xe8A\xf0;J\x00\xbf\xdf\x1a%\x18\xfa^CV8\xa0\x01{\x9c\xc7K\x90\x8d\xb3\xa1=I\x0b\xf8\x0c\xa0\x93\xd0\x02\x01m\xba\xd2\x9bB\"\x88\xf8Sb\x05\xf1\xdb\x90DC\x0cE\x90\x8brw\xe2\xdf\xd0\xa2|\xabQ!\"k\x19\x94c-\xd9b\x8b< k\x86%\x93\xf1\xbe\xf4\x12;\x12NAe\xc0\xb6*C\xe8\x9b\xa9\xcc\xf5\x1a{\xb6\xe1\xd89\xf3C\xe65\xbb>z(\xedG;\xefL\xd2\xf6\xf5u\x83W\x1b\xec\xa4\x7f\xa2\x83\x1c\x1e\x0d2F\xdc)L :\xc8\xa9\xa85\xb1'\xa6z\x0b\xd8w\xd9\xdc4}0\x99\xd4Q\xbe\xe5\xd2\n\xa3\x90\x0b\x02=mT\xad\xa0\xea~\x98O\x91hob =\x84^\x10\xb9{0\x86\xae\xf9\xe8F\xc11\xf9(\xa5\xfc\xde\xd8\xd6\xf3\xda%t\x0cW\x8c\x0c%\xd7K\\\xc1\\\xca8u\x88=\x11\x97\xbf0\xa7J\xb3\xc3\xa0\xf6yl\xfd\xf3\xfc4\x0e\x9c\xc3\x05\xe9}\xacv\xd1\xf2nG\xf9\xd7`9+1\xc7\x9a\x14J/\x86\x19v\x8d\xc2\xf3;\xb6\xf3\xe2\xd8\xce$T\xf4\xfc\xb1\x1d\x0dK|jZ\xc9\xa9\xa8R\x16\xa1Z\xfb\x89\x13\xc7<\xa9u\xd2{!\xd8S\x1c\xc4vI\x85\xfe\x1d&}}\x98\xd4\x93\x8b\xfeU#\x93\xea\xe5+\xc5\xa5\x8e\xfe&\x98?\xcd\x91Y\x1af\xabF|.\x19t\xeaQp\xd2\x82f\xfc s\x12\xee\xb4*\xb7\xec2\xb5\x936\x1d}\xf1\xc6}\xd1\x02j\xb9r\x86\x8c\xa1j\xaa3Tw\xa1Ws\x80(\xdb\xd4\xe6\xab/z\xb0dV6(-\xc7b\xe9b\x08\x85lo\x81\xeb\xe8\xcc\xba\x17 \xd4jB\x00\xa7<02\x15&\xfc\xb5\xc0\xf8\xcc(\x0f2?\x96V\xa7\xeb\xad\x96\xf4\x0bo\x89S \xaf\xf6j\xb3\xac\xaa\xa3\x17Q\xa4\xedZ/~\xf5\xef\x1bC\x13\x9e_\xa9Q\x0f\x0d^\x16\x1d4\x14\x06\xedF\xafj}\xb9\xa4hte\x14g\x87\xb2\xdd\xfa\xe2\x91\x1e\xab\xdc\x17\xd8?\xf9<\x12{\xcd\xfe\xbd-\xb3u!\xc8\x17\x15\xfa\xc4\x81jt\x0f)Q\x16+\xf9\xab\xad\xa8\x17\xaa1\xab\xac\xc6\xb6\x86\xe5 \x97\x86N8\xe0\xc6?\x05\xfei-/P\x94\xbdV?\xdd(V\"n\xfdt\xd5\x80Z\xf6d\xd6w\xbb\xacu\xecX\xab\xa3DWA\xf6\xaaq\xca\xd3\x054|\x99\x012}R\x1a\xa2 Y1\x91m\x999\xb7)}\xfd\xddnQ\xe8\xb7\xc9\xc2\n|92\x87\xac\xfe\xd5\xa3T\xbd\xd7\xa8\xda\xab\x86\x93BM\xcb\xd4\x81\x9e\x99\n\x8a\x95\x9b\x9a\x18\xf2\xc9'\x91\x1a\x08\x9e\xd6m7\x93\x83p\n*\xe3K\xab\x02\x84\xd7+N3\x939\xc9\x80g3\x80Ei\x83\xf3\xb43\xe1\xa5\x1b\x01\x8f\xd8k\xcc\x9f\xce\xd0\xaf\x7f\xc6\xb7\x06\xe8\n\xb7\xfb\x91\xdd}\x9e\xe0~\xd3\xa4\xc4\xe7\x9a\xf6\x04=\xd4\x93\x97\xe5\xba\x103\x04\x81!\x13\x0f\xbbS\xd3l\x17\xdc\x1a\x12[\x88>\xc2\xff\xeaR\x8f\x85\xd0`.\xd8\x9a':A\xe8g\xbfe\xc1\x9f\x91\xb9\xb2\x17\xc2\xec\xd9d\x86\xcf\x9e\x83\xe9\xb3)\x88\xab\xf3e\xf4\x00\xe8 X`\xad0\x8ab\x1e\xf2\x84\x85Q\xc2\xfb\x9fCe\xd5e\xb0\xce\xb6\xd1\x8c\x98c\xf3\x04\x9d;\xf4\x03/\xe1\x96\x90\xeeIK\x0e\x9a\xbc}U'\x9a\x8d\x86\xdc\x1f\x0c\xe5c\x13ymR\x18\xf1\xebE\x89\xc7\x93\x05eUj\x10H\x9cd\xe0\x87\x0b\xac\xe1\xa1\x92\xd8\xf1\x95\xfa\xf2O\xc9\x04\xb0\x1ee\x8b\xa1?r2\xee} \xc9_\xdfN\x17'\xccO7\xc4Y\xf5\x1a\x84\xc2\xb1\x8e\x19,\x1fL\x85\xf0\x82\xb1\xd4\xe2v\x18\xa5n\xe2\xc7\x99\xbe\x00\x98@6\xef\xda\xce\xc1oO\xe5Q\xab=I\xdb\xd1\x0b8I\xdb\xa9'\x11\xac\xb41\xec5p:\x0e\x95\x8f1,\xfc\xc4\x9dI:F\xe3!\xe8by\xb3\xe3\xc5\x8b\xa6z\x15,\xa2\xa9\x1a\xc6\x82v\x00d\xec\x9b\xe1\xffK\x9dp\xbcZ'\x1c\xcf\xe6j\xe3\xeb*6\x1f\x1c\xcf\xe6j\x93+\x8057\xa2gs\xb5 \x14\x80\xe4\xecw\x15\xe0\xf4+\xa71\xa8\xaf@sd`\xb1\x86\xd8\xfdt\xbc\xaf\xc7OG\xffE\xb4\x91\xe7\xa5\xf5E\xfcQ\xd2\xb5\xa5 \xc1d\xbc\xd6\x8c5!\xee(\xa8\xc4\x1d\xb9\xe0\x15\xe4B\xdc\x91{\xf4h\x87\x05\xd7\xdd\xaaW\x90k\xb9\xe0SK)\xa8\x866\x99\xe5\x84\x11\x81\xdf\x19aF\x115\x9b\xd5\xc5\x1c\x052\xe6(\x99\x19\xf0\xecR\xe4\xf1@HO\x13E\xec\xd2\xf8\x94\x17?7^\xfc\xad\xdf;^z\x15\xfbxKf\x93+2\x87\xfd\xe1\xcc\x1f\xfc\xde\x0f\xca%~p\xfcx\x97\xb5\xa4\x05\xc0\xd6\x96k\xd2\xd8\x1eO\xdd!\x1f9\xa4\xc9\x9aB\xbaQ\xd0\xca\xc8\x14\xee\xaaIo\xf1\xfe\xb6\xac\xf2<\x93N\x14[\xab\xbc\xbf;\xd3\xf7C\xafx\xde\xdbf!\xb8\xdb\x85\x9c\x14\x84\xa1'\xc4 \xa5V8H\xad\xc2\x81\xf3<\xc2\xc1\xd7\xca\x18Uj!\xb9=\xcdJ:\x9f\x98\xff\x94)2\xca\xa7}\xf9\xd8\x81\xc2r\x83\xebK\xe5\xb2T\xc2o\xe7~\xd2\xc4\x99SY.l4\xd2\xb9\x8a\xcbo\xf1~}\xa1\xbe\x99\xc3f\xeds\xf9L\x11`>\xa3nz\x9b\x8d\x832\x8dd\xbb\x05\xecN\x9e\xe4V\x83\xb9b\x08\xa5%\x95\x9aXx\x0c\x857\x13\x7f\xe4g\xfe\x98O\xac0bgX+\x92#i\xd0\x1e\x06\x82\x04\xc2\xab\x902)\xd0\xef\xff~\xc2\xfbuna2 \xa9|\xccx\x00\xe1\x0f\x1a\x07\xcbt\xab=\x10\xb4\xec\x88S\x14sJ\xc5\xccIo\xa7P\xcc\xb8\xa3\x04\xb5\xd6\xdcI\xa1~\xe5[\xa2\x91\x18\x06\x93\xff\x7f,\xf3\xb3\x80\xd7Z<_`\x7f\xd0\xd3\xcd\x9b\x19?\xc8j\xfb\x8b\x05_\x10\xbc\xa8\xb6c\x7f4h\xec7M\xdc\x05\x16\xb6O\xce\xcd5!\x95V/\xe7g\xe3\x83\x86\x8d\xdf\xf7\xbdl8\xb9\xd8Du\x96\x19\x15t\x8d\xf7E\xbfs|4\xe9\xa5=\x95\xbcL\x92\xc2\xc0\x11\xd8<\xa1F/\xca\xb2h\xb4\xc0Zb\xb0\xb5%k\xe2_\xea\\G\x04\x15=\x94\x89\x1a\xfctcq\xfbD\xbbS:\x07\x1e\x8f\x13\xeeJ\xcd\xad\xa6z\xba\xef\xcbL\x84\xae1:J\xbe\xe9\n\xa5\x8c-\xb0#G\x06]y\x06\xcb\xa7+;\x8c9\xbc\x997j2\xf9\xb8N\xca\xcd\xd9]h\\\x99 \x87\xc7\xa3\xb6\xa1\xc6\xe6\x18Bo5\x86\xc6:\xcfelb*\xc0N\x90\xdc\x05\xd6@\x9d\xf5\xaf\xe0F\x8d\xf7)\xfa\x07\\\xa6\xf1\xa12\xfd\x0b\xe5\x14\xa7xL\xbf\xc0\x85\x05v8\xb9\xb8d;\x0b\xccm^\xb4\xa6\xcc\xb1\xb0\xff\x8e\xe0\x0b_n\xfb\x87_r\xfba\x08/v\xf7\xff\xf1m\xa8\x96I\xea\x1e\x8b\xd3\xbf)\xf6T\xbd\xf8X\xbf\xa9P,\xccG=\x9eL,\xe6\x87\x19\x1fLQ\xae\x17E\x01w\xc2\x86rZ\x03\xfc2\xc86\xfe\x92vh\xa6\x91C\xc9\xa9\x13\xef\x02\xd9\x7f\xe9\xd8d\x85O\x8c\xe7\xac\xb5\x0c\x95\xb0s(\xb7d\xe70\xe6\xd4,\xa4\xd7\xa8o\xf6YZ\xa2\xb9w\xc9\x89\xa5Lm\x93\xd0\xab\x1b\x17\x9b\xaaB\x97i\xae\xa46o\xca*\x15\x95\xa3\\\x0b8Um=\xd8\xcd\xa28\x1c\xc4j\x99\x92\x88?\xa9\xa8\xa2\xf1E!q\xc4\xaaE\x8a}n*\xc5\x0fbG(\xac\xb1`\x87EA \x00hx\xd3\x14*\xf1VS.\xf0\xd3\xf2\xc2\x14\xa8Q\x8d\xa6\x87L\xa5\xbf]\xfb\x9e\x18Q\xea\x08\xdd\xfd\x8e\x0c\x90\n\xa8\xc1/\xb7Y\xd6\x84\xe6\xda\xce\xc1J\xd6\x95EN\xce\x9d\xea\xd8\x8c\x7f\xb2\xd0\xec)\xab\xfdO\xc2\xe6N\xd8\x0dm\xf9\xd7kh36\xb0\x19\xc7\xf3.D\xd1^\xbb\xd5\xe3\xfd(\xe1\xdbjy\x14\xd9M\x1b\xd3:\x9a{\xe6a\xc2\xfb0\xcc\x94g\x8bY\x96\xf8\xbd<\xe3m!\x80\xb7\xba\xf6\xdb\xbfN\xb74LlzM\xa7q\x89;\xfe\x87\xd7\x17\x8f]\xfbA:{\xec\xf4\x91\xd7~0s\xe3\xe8\xef\x1f\x1f\xa8d\xc5Ug8\xba\xda\xf5i\x98\x8a\x85\xd1\x88\"\xf0\x94\xae\xf5\xe2\xf2\xf2\xcd\xc5\x9d\x9d\xad\x05v\xbd\x05\x97\xe8\xadj\x86P\x92\xda\x82\xd5\xe6c\xc2C).\x11\xd3(O\\\x8bE\x00\xee\x19\x1a\xfc\x89\xfcBm8s\x06\xee\x0eZ\xd2w\xbc*B\x08\x95;mgE\xd6\xe6\xa4N{\xac\xbb\x94\xach\xabN\xb2\xe7E\xfbaU\xa4\xbbK\x0d\xac\x10\xbbq\x86\x85|\xbf\xb0c\xd6\x08\x8f\xc3l\x14\x88clg}\xd9a\x1c\x0d\x12'\x1e\xf2\xa4\xbeP/\xe1\xce^Z\x0f\x0f\xfcp\xcf\xef\x1f6\x17\xd8\x91\x9b\xbc\xc0Z7{\x81\x13\xeeY\xd2\xa8w\xd4EK;\xb3(\xd0\xae\xcc\x12\x96\xa3\x850w\xff\xafI\x15\x05\xf8\x9fq\x8d\x91\xe3\x8aa\x7fJ\x86\xa6\x01\x04\xb1FN \xd6\xeb\xd9Gx\xd7\x17/m.\xb0\xd6K\xa4|l\xf9\xba\x18J\xccy\xfc\xe7\xb84|\xbf\xf7!\xfd\xae@\x8f\x7fNA\x00\xf8K\nH\x83H>)\xf1\xec\xf1_P\xe0X\x02\xfe\x1b\x02\x90\xb3\xbbGvDz\xa6\xb6\x9e=z\x9f\x02d\x94\xac\xb5\xca(\x85\xf9`,\x02\x90\xe3\xc8\x16?\xb2\x03{\x12\xf8\xd8\x0e\x94\x07\xf2\xd1\x13;P\xf6\xf9\xe8\xa9\x1d\x08\xb3\xf8\x1b;P\xe2\xfc\xa3\x7fm\x07\xca\x85y\xf4?\xda\x81\x12#\x1f\xfd\x1b\nL2\xb9\x02\xbf\xb2A\xc6r\x8e\x0f\x08]\x01\x18L\xe3\xaf(0\x05\xfc\xbfGhE8HEo\x9f\xfc\x84\x02\xee8\x89\xc0\xe7g\xff\xfc?`T\x8c\x06\xd2\xee\xfa)9\xd0\x1a\x80[[\x8c\xe2>\x1c\xf5\x7fO\xaa(\xc8\xcf\xff%\x86\x88S\xf0\xec\xfe=\xf2Y\x10>\x89\x88d\xe9bID\x1fcJ\xe6\x00F\xdf\x7f@\xbe\xfbr\xc1\xee?$\x80(]`\xado\xe3Y\xc4qpxN1#+\xa9s\xe28\x89\x0ej\xc6-@\xfc\xb6u$\x8b\x89\xf4\xac\xb2l\x83\x06|\x80k\xa4.\x10\xcf\x7fI\x0e\xb1\x81\xfco\xa4N\xea\x0f\xe4\xc0\xef\xff\x8cT\x12X\xf0\x07\xe4\xeb\xe1\xa8f\x17\x04DM\xe6\x9f\xe3n2?\xf0$\x8d&L\xd1@\xfe\x07\\'\x17\x02G\xeb\x13\x82Q\xea;!!\xfbn\x14\xfa!\x1c\x14\xcc2\x9d}\x05\xf9\x08S\xf5\x9e\xe3\xee\xb9\x11\xd0\xab\xfb\xefZ\x80Z\xcf\xee\xbdG\xa0\x89\xa4\xbaO1}\xef9\xc9\x98\xcb\xb1<\xc0\xfd\x9du\x92}.1\xfb]\xcc\xbb{\x05\x08\xa3\x1a\x80\x80dS`/\xd9\x13\x80?%\xf3\xee%{\x99\x06\x92%\xab]\xeb\xb3 s\x90\xfd\x81\xcf\x98\xe7\xf6\xbc\xdby$\x97\x1dK\n=\xee:y*W\x0e\x8f\xec\xac\x04q+\xac\xd7\x08\x1b\xc5\xd9\xa1\\\xf4G\x98\x92\xf4\x04~X\x91\x83'a\x94\x8b:oc>qV\x82\x82\xc0Ok\xc0\x99\x9430\xf9\xeb\xa9\xef\xff\x0b\xfd\x0e\xa2\x0c\x1dB\xb6\xcf9\x1co\xd2\x89\x96\xb4\xc8\xbej\x00f6=\x7f\xe0\x02\x05~\x88\x05O\x01\x02\xd1\xf3\xd9/0 \x16\xb0\x1c\xaa\xe1\xc3\xdf\xf3\x07\x91\x17\xc1\xb9\xc4\xb2\x93\x80\xc5\x01l\xe4GX~\x12\xc0\xcc\x1fq\x80ZF\x93\xdeV}~D\xd0\xdd\x1f\xa4\x99#\xb9\xc5_\x90\xa9\xfb\x83,\xf1\xa5,\"\xf4&Q\xe6=rr\x8b2\xd0\xc3{\x98\xd6\xf4\xfcAnF\x8e\xa9W\xcf\x1f\xa83\xfa\xd02)s\xda\x1e\x92\xe5\xd8s\x92h_\x80\xde\xc7\xd4\xa2\x178\xee^\x10\xdd\xe1J\xb8\xfa\x10\xcb,\xb2@z;w\x12 \x7f\x0f\x0b<\x12\xae'%K`5\xa1R\xc2,\x0d\x968*\xa5\x02\xb8\xb5}\xf6\x0b\xb2;\xe5R\x89\xbaT~\xf6\x1e\x96\x02\xa4\xae- \xff\x023\x86^\xb077/\xeb\x90\x03\x12\xec\xcd\x9d\x94\x10BE\x82\xbd\x13\x00\xc1\xc2\xb2LO !\x98\xa1\xf5B\xb1\x18g\x9e\xfd\x183\xda^\xc8o\xe7\xbe$\x07\xf7\xff\xda\x02^\x07\x94~\x8a%\xc0^\x08\x80w\xb1\xbau\xd6\xc8B\xff\x07\xaebd!2nh\xeb\x01\xe9]_i\xdb@\xfb\x99\x0f\xe8E\xe6\x1a\x1d\xf4@J\xf9\xf0>\x05-\xaf \xc8\xcf\x7fa\x81\x04\x12\x82YT/:\xf0\xa0\x0eV4\x04D\xd6\xf9\x19^\x04\xd1\xda\x96\xac\x83%\x11\x01\x91\x07\xd6\xb2\x08\x07\x1e\xd4!\xa8\x10\x1dx\xb2\xce\xcf\x08O\x8f\x0e.\xc8*\x96\x01H2\xfa3r\xf6\xa2\x83\x0b\xcb\xb2\nVo\x05D\xb2\xce\x9fciD4\x06u\xe8.\x1c\x0ce\x9d\x9fa\x92,Z\xdb\x95u\xb0\xbe\" \x92\x95\xfc\x9c\xf0\xfc\xe8`\x08u\xb0\x02$ \xb2\xce\xcf\xc8i\x8e\x0eF~\x08\x04\xea\x01\xa1\xf2\xd1\x81&^\x0f\x08k\x8d\x0e\x0c\xd5}\x80\x15\xb5^t\xb0\x0b{\x8e\x95\x0d\x01\x01<\xc1\x82i/:\xc8\xa1\xce\x7fk\x81\x00\x9e`\xa5S\xb4\x06{\x8e\xb5N\x01\x01<\xf9\xa5\xa55\xa8ci-\x07<\xb1`\xddeY\x85\xd0\x92\xe8@\x9e\xfd\x9f\x11\xca\x16\x1d\\\x06\xd4\xb2\xec\xece\x89[?'\xb49:\x18C\x1dB\x95\xa3\x831\xe0#V\xb6Dk\xb0j\x844F\x07\x97a\xa5\xb1V'Z\x83:XA\x11\x10Xi\x0b\x0e_\x86U\xb3\xec\xf5eXi\x0b\xfa\x8c\xa1\x8e\x05y\xc6\xb0\xd2\x04\x0b\xeae\xe8\xb3\xca\x98\xf6k\xb2o\xf5\x80qO\xb2\xf7\x8f\xf1a=\x0bZ\x10\x95\xb7zF=\xfa\xdf \x84\x8f\x84p\xf7\xec\xad?#\x90:\xc9>Us!R}/\x8d\xc4:\xff\xe0\x07\x96\xefR\x85\xff\x90\xc8#i\x14\x0c\xd3\\\x02\x7fEHv\x1e\xc8m{\x93lu\x1e@j1\x1bH)o\x7fj\x01HM\xf9 \xb6L\x08\x08\xe8\xcax \xce\xe6F\xdf\xb35\xa7@\xb8\xd6\x92\xb6E~\x8a%3\xd7@~J\xea\x80\xfc\x88\x89\xbc\x12G\xefar\xe9:\xb16ta\xf9\xcbu\xe2^\xa2d\xc3\xc7\x98\xd5\xb9N\xac\x9a|\x8c\xf5\x7f\x01R\xb5\xf0\xe8\\'VB\xecc\xcc9\x96\x9c\xd8\xcf\x9c`\xd9\xef\xf7y\xc2\xc3\xccw\x02\xc9\x14~\x82w\xdaubPY\x1e\xff\xe7\x7f\x8f\x1bq\x9d\x04\xb6\xf3-,1\xbaN\"\x15\xd3_\xd3\x05;\x0c\xf8!h\x17X\nqu_\x8f1\x82.\xe9\xf6>\xc5<\xd35\x10Z\x87{\xbe\xd4\xc7\xc9\xb2\x18\x08\xe6YKJW\xf8\x14\xa3\xb4\xab\x01xc\x96J\xaa=V\xc0\\7W\xf3\xa1\xa3\xce\xe34\x95\xc7\xf41f\xf6K\xb0e\x9fb\xb3\x8b\xab\xbe\x93\xfdW\x93\xf9\x18\xcb\xa9K\x02\x1086\x90[R\x1b\xb1\xce\xe6J\x7f\x86\xd6\xc7\xf8\x84.\xf10\xe3\xc9\xb2\x1c\xc4\xc7\x98\x1c\xb9\x12\xe8\xd9\x81K\xfd\xc4\xbe\xdfZ\x9f\xc3D|\xe9\x02\xa8\xd6x{\xdc\xa1\xfc\xfe\x0fdC\x87\x1c$\xe5\xbf\xc4b\x98\x84\x8c\x9c\xc4\x0e]\x1a\n\x12\xfa9\xedF\xaa\xcd\xa4\x17\xb0\xe4\xfd\x82l\x00\xa0\xc6\xaf \xd5\xf0\x13W\x91\x1a,\x9f\nP\xc0\x9d$\x89\xf6\xb56\xf2\xce\xffY_\xc6\xe8\"\xef\xfc_\xd6B\x1eX\xc4\x9e=\xc0\xb2\x8a\x02k\x0d\xf8\x01\x96K\x14\xdcS\x06\x9d\x07X>Z\x92\xf0e%\xd0c\xd9E\xd5\x16L\xf5cL\x9c\x15l[T\xfcs|\x9a\xa0\xd9KF\xd2\xc3B:\xc07\xb5\xb0\x87%u\x00\xef\x18y\xcf\xb2\xba\x92c|\x88\xb5z\xd7\x07=\xd3\xb6\x1f}}\x8c?\xc2\x07\xd2\xf5\x93\x11\xd8^\x9fb\x0b\x82\xeb'\xa9B\x8b\x0f\xb1\xcc\xb5$\xd4\xb7}?\xe5KQ\x98Ey\xb2\x1af|\x908\x923\xde\xc3\x87n)\x88R\xbe\x94'\xc1\xe1r\x94\xf7\x02\xfez\x1ee w\x90-1%\x8b2dc\x82\xbc'\x97\xe6\x97X\x0c\x93\x90\xdc\xcf\xac\xc0\xa5\x08\xac\x89\xcf\xee\x91\xe3\xad \x0b\xb6\x1ap\x03\x83Ey\xd7\x80\x88\xfd\x16@\xb7k`\xa3\x91 Y]\xdbw1\xec\xff\x8a\x02\x80\xd5\x12\x16\x14\x8d\xe2>L\x07Kb\xae|\x19a\xc4\x15\xdd\xb6\xd5\x0c\xf8\x01`\xd7\xdbx_\x8d\x99\x90p\xca(\x1chv\x8bI\xddR\x14\x0e\x92\\ux\x1f\x0b\xbaK\x05\x0f!\x18V\x80\xf0\x11\xb3\xe1\x15-#\xb5t\xdb,\xb4\xfaNw N\"\xb8\xd6\"\xacI\x82r7\xb3C76\xaf\nR@d\x9e(>\xac\xfb\x9e\x02g\xc0\xe7q)\xca\x05?i%\xa2e\xa6\x90\xec!\x99M\xee9I\"W\xe7}26 \x93\xeb\xf3>^\x1f7\xe7\xb1\x84<$s\xcdy*9\xc7C\xacM\xb9y\xa0\x97\x1b\xdbv\x01$\xa7\xf5>\xd6A\x96\x94\xbd\x95\xf0i\xf8~\x0f\xab\x9an.\x84b%\xf9\x126\x92\xc7J\xfe&\xd7:nn\xe4e\xc2\x96s#/\x13\x11+\xd7\xf2\xf2\x03K\x83\x11\\\xe4\x91c\xaf\x84\xbc{O,\x02rn\x90\x92\x90T \x92\"\xe0\xfbX\x8dv\x05y\xe7\xb7\xe3\x84\xbb5\xdb\"\xe1i\xee\xd6mN\x12\x1cjc.\xd6\x80$\xb00\xe7\x12\\\xcd\x93D\x1a\xe6?\xc6J\xb7\x9b'c$\xb3\xd0\xad\xd7E\n\x91\x85N\xbc~d\xea\xba\x87\x0e\xaa|\x83F\x04V}\x83v\x0f_\xc5\xb8\x87\x81\x9b \xda\xf3\xec]L\x90\x97e\xaep\x01z\x13Sc\xaf\x00a\xc1\xd4s\x02}\xa3\x81\x0f\xd8\xb2\xdeh\xd2\xdc\"\x00~\x8aq\xde\xd35(\x00\xc4\xb171QXv\xd2!\\\xb0\xe1\xbd\xf14\xe4\x01f\xea^\xc9>\x8f\x97\xd5\xeb\x05\xd2\xd3\xe0\xd7X\xc8X6Z\x15\xde#\xcf@pc\xcb \xb3cv\xe2\xc1g,\x1e,\xdb\xb5M\xf0\xf5\xf8 >\xb3\x9e\xd7\xb0]z\x1d\x7f\x8a\x8f\xf3\xf2r\x94%\x0e\x984\xdf\xc7\x94\xd7\xf3\xa2,\x05!\xe41FQ\x8f\x0b\x0e\xff1\xd6\xe7\x969p\x1e\xac\x18,\xf3\x00\xae\xbf\xc8\xdc5\x00\xcf\xde+\xe9_\x18i\xbd\xbe\x9f\xc2\xd1\xf9\x00\xbb\xe0,k\x85 \x8f\xc0\xd3\x00\xb28\x17\xe0B\xe9\x03l\xeb\xf5\x86\x0ep\x8a\x9fb!Y@`=\xb1\xcc\xb0\xec;n\xe2g\xbe\xeb\x04\x8bun[\xa52\xa06\xfc\x1a\x0b\xa7\x95\x12B\xd6\xd5mQ,,J\x9eW\x9eT?\xac/\xb2\xa3\xae\xeb\x7f\x8d\x8dx\x9e\xefH2\xfb\x10[\\\x96}g\x14\x815\x86\xc0\xbc\xc90#Gcs\x9e\x80\xa75\x10\xb9h\xd8 N\xad0\xe4\x00\xf8\x03\x07\x04\xe3\xdf\xe0U\xf2\xfc\xd4\x97b\xeeCL\x18=y\x13\xf4 \xc1n\x7f\xec\x83c\x83\x1d\x12\x85\xc6\x94\xfe\x90 \x9a?\x8e\xc2\x03+h\xf9\"\x9ct\x8c5\xde-P\xda\xb1\x1c\xe3\x05n\x94\xc8\x81\xbf\x8b\xf9\x9b\x17\xb8\x89|b\xe0\xd9\xbb\x98\x0f{Q\x10H\x94\xfe}\xdc\xbd\xb9\xa9\xc2:\xb2gD]\xacH*c\x06\xde\x0e\xaf\x06q\xa3Li\xc2?&(\x16eJ\x9f\xc1$[B\x94Pq\x1f\xd3\xa0\xe5([\xb9\x9d\x83>8+:f\x01S\x0c\xae\x01\xd8Z\xc1\xb5\x9d\xf4\xd9}\x8c\x1f+\xb0hX\x0d\xe5\xb0fX\xca\xe1\xcbJ\xd2 \xaa\xc9\x8a\xba\x05\xc2\x83\xd5Fz\"cpU\x01\x1fR8\x9f?\xc1R\x1c\xef\xeb\x860cZ\xd1:\x066\xc3p\x0d\xc07FR\x8bz\xf6\x04o\xc5\x8a \x8b -\x19\x08fy| \x89\xf7\x132\xedA\xaa\x8e\xca\x13l\xe4\x05e\xed \x96\xe2VJ\x86_\xd2\x7f\xe0\x87\x19OdW\x7f\x86 \x13\x87K\xed\xb71\x93\xe2\x01\x0c\x0d\xef8\x0f\xcc\xd0\xf0\xda\xaf\xe8\xe8\x0b\xbc\xc6\\\x03H'B_\x94c\xc6\x04IBR\xb8\x86%@\x99ky{\xe4\x04\xc1\xb6\x91\x08\x7f\x81\xe5\xe3B\x17\xb5\xd7\xbf\xcc\x13\xdc\xc6{\xd8Y\x84\x8fRI{\xdf\xc4\x9cS\x00\xe6NH\x10V\xa3$H\xba\xbe\xbdI\xfa]?\xbf\xc0Z\x9f\x91\x83'-\xef\x9f\xe1\x0b8\x1e\xaa\xce1G^\xd1.\xfe\x0474\x80`\x87\xd1\"\xb0M\x8e\x1b-\x82\xe0`\x0cT\xf4!\xc1\x80\xd8IR\xe0\n\xd8*\xc3\xb5\xf4\xfe\x18Sx\xe5\xb4\xfb9&\xd6+\xc6\xd9\xfbs\xda\x8f\x01\xe1Z\x02$\xb6\xf67\x04p[_\n\x12\xba\xc7o\xd7\x931~[y\x97\xdc\xc7k\xcdo\xa7\x81\x13f\x83,\xb1\x1fT\x00\x07<\xb5\x9f\x16\xa3\x07=\xa6#\xcd\x1dy\xc4\xce\xd8\xaah\xad\xdf6\xa0\x9c\xc3\xb5\xe8}\xcc\x92Vn\xe7~\xe0\xf7\x12?\x97s\xf9)\x16\x18JN\x946\x08\xd8\xae\x1ec\xa5\x81\xdf\x1e\x17\x1b\x8e\xa5h\xaeY\xe0\x07d\xc3\x13Mq\xf1\xa1_\xd1nA\xd8\x10\xc55\x00\xf3m\xaeI\x0e\xd1&W\xd4\xbe=\xc6\xd7&\xbcnCW\xc0tE\xf8\x06|&|i\xe7\x82\xa0\xdb\xb8[\xb0\x96~\x82'\xb0\xa2\"%\xc8IV\xdf y\xc9\x13\xe9R\xff'\xd8A\x8a\x1f\xb8\xa2\xc2\x11\xf2\xd9\x87\xad\xbf\x87\xe9\xd1\x8a\x80\xa4V\x10?\x88\xb9\x9b9:^\x86\xac\xfa\xca\x01${\xf0\x9d@^/S\xdeY\x14\xb03\xd7\xbe\x13\x04\xbe\xbc$T\x96G\xc2d\xcf\x81\x98\x80\xa5\xe6>\x88 \x98\x82\xf6\xf9Hu\xf5K|\xf3\xd0\xef\xfb\x10\xf8\xf8\x9f\xff\x06\xcf\xb3\xdf\xd7\x10Z)\xd0 \xdc\xd59\xcd\xe4\xb1\x9c\xd6\xd7\x00L\xe2\x8a\x01`5\xe2\x9c\x1f\x04\xdc\xc3l \x13\\(ec>X\xec\xea\xdf\x82\x9e\xfa\xb70 p\xc0B\x87\xc5\xaeb\x9e\x18\xeb\xfbA\x16J\xf4x\x0f\x9f\xd3~\x18 \x06\xf0\x9f\xc8\x96\x19\x96\x81\xf5\xb3\xbea\x19\xf8\x10\x9d\x8b\x92E\x10'\xee\x91=\x88\x12\xa7\x1e$\xfdX\x1eb\xc3\x87\x00\xc0\xbd\x00\xe6g\xe7\xa2<\xf1y\x92%p\x0bL\xe6\x14;I\xa6\xfd\x1e\xb0\x10\xdaO\x1cW\xba\xb3\x7fL&& \x92\xa9\xff\x04\xd3, \x12L\xfdc\xbc\x9f\x12rJV\xc2\xc4_\x82^\x96 <\x01 zE\x82\xb0\xe0.@\xf30\n\xb2 \x02\x04}aF$@\xd2\xe1\xfec\xac(I\x08T\xc2\xfb%A0\nl\xfa\x13\xa0\x93P\x0bK\x19\x02t\n\xa6\x85e` \x82\x06\xb1=W\x80\xbe\x03 l\x13\xe8'\x0e\xb0\x97\xb7\x08%HT\xe8\xc3\xbbX\x08?\xa7y\x05\xd9{\xa3\xfbb\x81p\xa0U\xaf\xff\x07\xf3\xe2\xf3\xca\x08\xfd9\xdevm\x9d\xfe\x1c\xb3\x17Y\xc3\x13\x12\x08^\xb8\x81\x81\xe0\x15\x18\xc0\xcd\xed\x13l\x970\xa2\xc9\x13L\xd6\x00$\xf9\xfb\x13L\x8e\x15\x0c\xe6\x8a\x91~\xc0S5Yz\xf3.`0\xc8'\x988\x9c\xd7\x1c\x0b\xab\x17\x03\x0d\xc0\xec\xf7\xbcTd\x1fb\xda4\x00? ,\xac\x0c\x065\xc5\xfd\x11l\xce\xdbXx:\xaf\xaeN0\xa7\x1e\xa8\xab\x13\x82qpc\x80\x9b\x19Hg\xcfgO\xc8\x1e\x83\xbc\xf2\x04s\xaeApK~\xc7\xd3\x1d\x84\xea\x00\x92\x05\n\x8b\x98a\x0b\x10\x10\x98\xec\xc5\x9ckud]\x96U}\xaf\x82\xcf\xb4\xaf\x01X\xc6\xf0G\x0eh^\xb6\xb6\x06~\xe8$\x87\xab\xf6\xd5\x199\x83@\x9d\xe8\xb71j\x0b`\xec@\xca$\xbaw#\x99\xc5\xb4\xf5)\xd6\xd4\xfd\x91\xb4<={\x80Y\xb8?\x8a\xa5\xc3\xec\x7f\xc2\xf8\xb4:\x8a\x03\x1f\xd4\x1f\xe2`\xe2\x87l\xc1v\xf9\xe5\x87\xae2\xb0\xbd\x8d\xafc\xcc\xde\xdd\xc3\x8a\xb7\x84\xa8\xd0\xfd\x0f\xb1\xbe\xec\x87*\x87\x06\x99\xd1\xaa\xc2\x12\x82q\xea;\xd9\x8d0s\x81\xc6<\xc0B\x9c\xca\x08\x0d\xb1\x1a\x98\x81V\x9c\x97,\x8d\xf2\xa4\xae\xd9Uy\x11\xc8M\xf6$\x92X\xc4\x0f\xb3\xc0I\x86\xd2 \xf7\x11\x16\xda\xfc0\xd3A\x14\x1fa!q5\x1c\xfb\xa9/\x1d\xac\xc0fb![\xba\x88\x89qz\x0bK\xe5\xab\x1b@I\xb0m\xd5\x8f@\xf4!X\xabo\xbc0\xc1\xf35\x00\xdf%\xac\x1a\xae\x86\xf9\x92o \xd8\xac\xb5\n'\xf9s\xcc\x07\xd5 \xff\x1c\x0b\x16~\xed*\xf9Z\xca\xfe\x18\xb3\xf9U\xcd\x15\xc9\xe12\\\x11k?\xdaC\x92\xe2|\xea\x87Z\xf0&49\xf5A\xc8}HF\x9d\xfa`#~\x88\xbd_%DZb\x1fb\xca$@c\xfb 2\xfb\x0e\xeb\xfcS\x9f\xe2\xcbp\xdf@\x08\xc1\xcc\xf7\x00-\xb0\xee\xe1+\xc0?`s\xe8\xaa\xbaq\xc1\xac\xdbW\xdf1V\\\xd4\")\x9e\xfa-\x0d\xc0\xeb\xa8l\x1b\x18%\xc0\xb4\xf1\xf7xm/j\x06\x86y\xff-\x0d\xc02\xca-E6\xff_L\x1d/\x1a4\xc5\x87\xe4\x96\x81`}\xea\xa2\xc1!,\x94\xde2\x10\x8c\x90\x17S\x9e\xc0d\xf0\xce\xde\xd2\x90\x7f\xc0\xf2\xc4E\xbdQ\xd8\xa6uKo\x14\xe6\xf8\xdfw\xe2X\x9e!|\xe6\xf64\x00\x930 \x90\x97\xbfX<\xf9\xbe1\x8abo\xa5=\x03\xc1\xab\xf9}\x18/\xe9\x1d>\xe3\xbe\xbf\xafw\x0b\x0b^{\x1a\x80\x91zo\x90@B\xa8O\xb1\x90\xf5}\x15\x0d\x8cwdOE\x03cn\xf5}\x85qX8\xd9S\xd64,\x7f|\xdf`\x03\xa6\xf1{\x06B\xea\x18l\xc0\x82\xd6\x9e\x86\xfc9&\x9b\xc1\xa2\xd6\\\xf0\"\xae\x99\xfc\x02\xf88\x04\x06\x82W8pJ1\x04\xf80\x06\xce q\xe0\x16\x13\xb3\xff5g\xd4\xf3$\xbe`\xdc\x0f\x0c\x04\xabOk*k\xe6\xaf\xb0\xf8\x14h\x00\xdeM\x01\x80\xfc\x8e\x98\x11\x05\xc6\xb3\xccR \xcc\x8exC\xd7\x1c\xf9\xe2\x9a\xbe\xc4\xc23\n\x1cH\xb8\xf61f\xf0kZ\xab\xc7RK\xa0\xed\x00\x98\x85\x98\x986\x1b@\xc6\xf6\xfd\x14\x8b\x18\x12\xd2\x97\xec\xe0}|\xf9 `\n\x84e#\x01\x02\xe1\x81\xa8\xa2\x02\x14\xc8\x95x\x07\xcfH\x06\xd6I\x81\xe5}\x8a)\x89\xb6\xe7|\x80y\x8f\x80e\xb2\xda;\x98\xcb\xa8\x1b\xd2'\xa4\xa7\xc5\xcc\xf1\xa1'\x8a'\x06\x84\x89z\xe0@D\xf2\x13,\xfe\x0b\x00\x98\xa8\xfe5\xb5\x18\x05g\xd5\xb2\xbf\x8f\xa9E\xd0\xd3\x10|\x98\x03\x9d\xe4\xef\xaf\xb0n\x10\xf4\x12\xb0:\xfc\x91\x0d \xea\\\xa7\x80=9\xecGX\xd1\x16\x904\x00D\xc6\x1c\x12`2\x8f\xd1#\xcc\xac\xd6\x8c\xb7!V\xd0\x03\x03\xc1B\xca\x9a!\xbd\xf8\xf8\x05\x06\x82\xa5\xa4\xc0\xe5\xb0\x13\xefb\xd6\x13\xb82\x16\x15\xaf\xc1\x1a\x90F\xb2\xa5\xf0\x99t\xec\xb9R@}\x1f\xb3\x89\xc0\xe48\xc4\x84QB\xc0\xe2AN\x9d\x97x\xda\xe1\x143\xf1\xc0K\xf2T\x03\xc9.x`\xd2x\x87l5\x18!1 \x06\xf2r\x1f\x9fT\xe9\xf2/\x88\xcfY\x81\x07\xe01GhP%.\x80\x90\x81\xb5\xb2\x0d\x89R\x8f\x8a\x85\xc9V\xb7\xec\xedN(\x89)\x80\"\x04\xb0,g\xba\xd1\xc7\x90\x1cj\xd1\xd2\x12\xf7\x03H\xc7J\x91C\xc0\xc1\xf9\xbf\xbc\x14x\x19\xa1\x94t\xd7.\xf9\x8dc\x0b\x85.Ur\x1b\xc7\xb6\x9ej\x11\xed5\x8ei\x87(u.\x88\xa0\x8dw\xb1\xe9VLZy\xe0\xeb,\x7f\xc4\x1f\xbeT\x06\x02|\xdf!\xe7\x85\xf73\xb3|\xa0\x1ec+5\x0d\xf8 FaQ\xa4j+$\xf6\x99\x80\x14!\xadT\x8b\xa4\xb5[-\xcb\xa8iA)r>t\xa9\xf4v\xee\x0f\x8a\x1e1\x11\xb6\x05'`\x8a[\x8a\x9e!\xa1\xa4\nV,\x8c\x0d\x83\xab\xd8\x82%\x1d1\xd4l\x98p^\x84\x98\xe1\xd9\xc8FJ)\x1f\x1f\xe0S_.\xa0\x90\xe9CL\x9c\xcbe\x8c}\xf2\x01\x16\x93D)\x08\x92)\x0d\x19\x0b,P\xa8:-|\xa7\x0feJ\xa1\x1aXG(\x17\xd0\x07\x00\xeb\x04(\xda\x03\xe3.\x8d\xf4 \x82\xd0\n8\\S\xfc\x80\x0bi\xba\x19p\xc1CD\x1a}\xf3C k\xc9'\x80\x9e\xbe\xb4\xee\xbb\xba\x99#\xf2\x9e\xf1 x\x8c\xd7+(\xf9\x04`\xedM\xc1\xe4\x1a<\xc1\xb4&\xe0\xa9\x9a\xacE\xce\xe0\xa9r\\x\x82o\xd4\x03\x9e\xa6\xa5\xab;,\x81\n\xb0\xb6\x13`\x0dZ\xc0\xf8m\xe5\xf7jYc\x01\xd5`\xb25kO\xaa*\x14\xa1U\xa2\x08\x12\xb0 \xe1\x8a\xeeHrA\x94\x80\"\x95\xb8\x0d&\xcdC$\xc7x\x00k\xd9\xb6|\x06\xd7\x92GD\x18\xd0~:T\x1eOJ\x04\x92X{\x12\xa5\xc0R\x01=1\xb4\x91\xec\x00\xa4\x00z\x93X>\x12E3\x1f\x10\xca\x98:Z\xf9\xc6\xf8\xb9\xa6\xafF\x88dh\x8c\x92X\x98ZS\xaa5\xa1\x95\xb5\xdfk\xa4\x81\xc08}ac\x88\x80\x80`J8vz\xbbg\xb3\xc7\xa4z\x82\x041Rc] B\x92vb\xf8\x8c\xc8\x8b\x06\x82\xed\xbbk;\x0b\xac\xf5]\xfcQ\"\x05\xe5\x9a\x99\xa5l\xa0\x9d\xce\x08\xdd6Ng\x84\x86d\xb5\x82\xa4T\x8c\x16l:QP\xa8K\x84=e\x9a\x9d\x7f@hQ\xc9U\x8d\x98v4K&t$K\xe0:\x97hK\x81\x0e1&\x89\xf3\x83,\xd1\xeerdRy\xe2\x19\xc3\x0e9\xb3ybB\x90\xc9\nV|\xd0>\xb2H\xf3\xda\x07\xcd\x02S\xb7\xfa\x1f\xe3\xdb+\x13.\x83g0r\x80\x16\xfc%\xd6\xec\x04\x80\xc3\xe3\x1b\x04v \xc4\x89\xf71\x91\x1e\xc1\xf7w\xf0\x94\n\xfeT\x032\x96\x0dl\x1e\x03\xb0a)Xa\x03\xb0\xb2y\xe0k\x92\x91\x93\xec\x01\xc5z\x0f\xdf\xfd\x8et\xb6\xc5g\x1fa\x99\xf9\x12H\xa0\xd8\xbc7\x82\xcf\x98\xbd\x8eL\xca*l\xe5\x18\xe9H\xe6{\x98\xb1\x8f\xb8\x93\xe6 \xf7\x8a\x07\xb6\xb0\xf2q\x89{~>2Ndoa\x82{\x89\x07\x81\x1f\xeak\x01l\xf4\xbe\xa4\xd5\x01l\x88\x1bi\x00>\xe2\xa3\xa1\xdc\x9c\xb7\xc9\xea\xfb\xae\x0c?\xfb\x18K:*-\xe8=l(\x19\xf9\x9e\xfd\x8d\xa2\x91\xef)\xba\xf0\x14\x13\xd6\x91\xef\xd5\xa4\xcf-\xb2\xc0`\xb2.!\xf0\xc6\x16^\x1b \x82\xd1a \x0e@R]\xf9\x08/\x81\xcc\xc9\xaa\x13\xaf\xde\xc3\x8cq\x14\xb8\x90\xad\x10\xdb\x8fG\x01\xb3\xb4g\x1e\x1a\xa3\xb0\x0c\x1e9\xf8%\xa6M\x12\x02f\x85:\x18\xf8\xfc`\x1f\xbb\xb0'\x9d\x8c?\xc6\xd4:,R\xcc\xd3\xb1\x97r\xc9S\xa0\xce$\x89\x97}]\xdf\xe5|\x86\xb7*4\x10lz_\xd7w9\x9fa\xae\x11\x1a\x08\x96:C\x93r\x96\xf6S\xce9k\x19\xb9Jt\x89Q|\x1d\xc88\xd6\x14B\xf8\x8c\x15\xca\xd0Pw|\xbaT\x82_\xb2\xd4\\{F\xbd\x8fYU\xc8\xf5\xdd+V*D% y\xc7\nQ\xaa\x02\x85\x99\x88g2\xfdu>p2\x7f\xcc\x11\x1fy\x13KW\xba\xdc\xce\xd0w\xf7\xa6*\x16N.u\x99'\x87\xcd%Ko\xf5`KS\xc8S\xaer\"a[AX\x04l[&\x9cf\xdc\xa3A%$\x82\x02\n\x96-\x7fD\xde]\xe7\xfb\xca1\xf9\x07!\x19\x82 \xaf&\xf4\x86\x17\xf1\xd5\x18\xb6\xae\xf9.6\xb8\x85\x1a\x80\x87\x19\xea\x988\x8a\xd9*,\x0e;\x16\x86:\xce\xcd\x06\xb8]\xdfX9\xd6\xcd\x06O\xeb@:4\xccRI\xef\x13\x96\x1aB\x1d\xd6b!\xc9\x03\x00a\xb95\xd4\xc6[\x028\x9f\x01\x06=\xa5\x030\xd1\x0eX\xb7\x0cM\xb8\x03!\xacCexx\x8a\xd5\xbbPj\x0b\xf7\x08\x0e\xc3Cq\x0f1\xf3\x0b}\x10>\x1eb\xa9/\x04\x8c'\x0d\xad+\x93'V\x11Be\xf2\xc4\xea^h|8\xb0\xba\x19\x1a'\x0eZGI)XD\x0e\xf5E2]Du\x97\x8c\xa5\xb5\xb0z\x13L\xc7P\xb9\n&\x03\xb1\xdc \x92M\xb2\\!\x92\xed\xd278dx\xc5\x15\x8emJ\xe5[\x1c\x1b\x19jM\xdbr\x0e@\x1b\xa3\xddh\xb5\xf5!&W\xa1\xd1[\x1fbkZ\xb8\xa6\xce\xc8\x13:8-\xc1c6\xb5\x1e\x9dM\xb8#Y\xd8[\x98\xbb\xadG\xa1\x04\xfa\xe1@\x13w\"l\xac\xebX\x11\"\x9d\x18\x01\x16K\xec\xfam62|\xd0\n\xf0\xe7\xf5(\xab&\x95\xc7\x86\xc9_\x01.\x06\x81)\x7fQ\x06\xc5b\xda\x86b\xe3\x9d\x0d\xe5\x0c\xf7\xc4V\x9e\xa2\x08\x0e\xcclh\xadX&\xcc2\xd6\xa3\x8c\x86\xe2\xd8ZB\xf18\x14\xe1\xa3L\xb9B\x13I\\@\x8c/\xb4\xbd\xa2r\x87\xb6\x03\xc7N}\xbb\xf0\x10\xf4C\xac\xd9\x02\x0cr\x98c\xe3\xd5z\x94aO\x00r\xe8Q\x19\xe3\x0c`[\x19\xabG\x00\xa1\x15\xb2`\x0d\x8dS\xb0by1\xd5U\x05\xca\xc8c\x1dHY\xea\xb2\x0f\x95^\xac\xd6\x95+p\x06\x93\xd7\xf5(\xab\x93\x07\x9f\xfc+[sT(|\xf2\xd7\xb6\xadV\xa2\x00\xf6\xc8\x93\x10\x85\x04v\x18 \x01\xd6\xa9\x01\x06H\x805\x8f\xf5(\xdbL\xb8\xcb=\xf5\xd2\x0b\xb6\xf3\x95\xe0f\xad\x9e\xfc\x1b\xdb\xe4t\xb1\xea\xba>\xb4P\xac->\xe6I\xca\xcbD\x0fOG\x94\x92\x195\xcb\xc8IdlTHc\xa7EOA%\x8b\xe1Y\xa86\xe4\xc1\xd9\xce{*\xe7\xdb\x03+\xb6\x97K\x15\xcdYX\x84.\x18\x8b9C\x83\xd6\x01V\xcb\x15Mb\xd3\x97(Z\x8c\xedO(k7\x05\n\xb7\x1c\xa2#\x8b\"\xae\xcb\xb9\x07\xbb\x8e\x0d\xfa%x\xb1\xeb\xd4XQ*\x86v\x1d\x1b\x1aK%\x8b\xf3\xf4\x1f\xed\x0d\x96\x16\xea\xc75\xb3Ck\xf4\xc0\xc23\x8bn,\x93\x93\xc0\x82\xccXx\xa2,Qeg\xc4Z\xa4J\x15=Y\x86\x81\x99?\xd1\xd6\xe3\x1a\xa9@\x00\x9c P \xf1mPH\xcd\xf1\xf4o\xe9+\xb4\xa1\x8e\x80\xbbG\xa5\x810\x8e\x02\x1d\\\x88M\xc9!?}\xc7Z &Id\xcc4\x8f\x1b\x88\xb2\x02\xabI\xd6T\xd6\x93\xb4\xf4\x9b\xa9|;D\xc8\xd7qx\x9f\x10\x8b\x96\x81\x10;T\xa6\xbc\xd1h/\xe8yr\xaa\xe2\x96K\xc0d\xa8\xaeK\x9e/\xa7\x07\xbfRD\xb5C\x04\x0dy\xa5A\xec\xc3\xf2+1\x0f\xcb,\x9a\xbfG\xbfrH\xda\xf86\xbe\x13\x0es\x9d-\x96\xd8\xb3\xc7\xfa='\xcb.^^\xd6\xcf\x14\x12+\xd8e\xf3\x82!\xb1\x18\x8cM-B\xe6\xc6\xa6\x16Y\xc6\xb1N\xbbe\x19\xc7\x18\xf2\xcf\xd8 \x17t\xb8\n9\xbc\xe3\"\xfe\x1d\xdf\\\x85cm\xcbz\x1f\xdb\xe9\xc3\xb1\x8ee\xb0\xf5\x06. v\x88\xb9\xc4\xb7\x815\x0b{\x9f\xd0\xdd\xb1\xe1\n\x0f\xfe\x9d\xad\xa6~[\xf8?X\x80\xfb\xc6\xe8Oh\xda\xbe\xe6\x99\x04\x15\xf65\xcf\xb4B\x14W\xa3\xb0P\x9b\xc7\xf1\xd5\xe1\x86I\x11\x81\xef*\"\x03\xc1W\x81Q\xdd\xf3\x99\x91\xba\xac%\xeffn\xe8\xf4\x11XF\x894\x00kc*\\\x1b\xef=Dk\xff=\xd6\x89\xa2\xda\x1797\xf4\x9bM\x9f\xe1k\xed\xc8@05\x8a\xe0!\x98g\x1fa\x9a\x13\xe9\xd7\xce\xb0\x93V\xe4\xa5\x91\n{\xc2\x96\xdd\x8d\x15H\xbd\xf0\x19\xde\xff\x88+\x00Y\xf8\xbeZ\xc6G\xd8\x95iC\x1b\xfeI[\x1a\x80\x0f\xa6\nV\xff5\xde\xa9\x0d\x93\xc4\x824e \xd8\xa4\x1d\x81\xb1\xfdC\xcc\xba\"\x9d\xa8\xe7\x116\xc3DC\x81\xfd\x9fc9&\xaa{\xa112\xa6hl\x06\x8f\x02\xbd&d\xeb\x03\xf3(\xe1#\xec\xb4\x13\xe9\xc4\x12o\xd2Z0\x17,\xcbn(O\x98\xcf\xb0\n\x1bi\x006]o\x8c\xf8\xc0\xb1\xceR\x01~\x83\x19\xe8\x86\xf4\x8f\x90\xe9\xa7\xb1M3*@x\xef#%R=\xc2\x86\x9fhT\xfb.\xec\x861\x9e\xe2+\xd2\xc8@\xb0\n`\\)\xb1\xf1i#\xe6\xa1\xf5\xc5U|\xbdo\n\x16E\xb0_Z\x14sx\xf0\xf0\x11\x96\x11\x8c\xef%y\xc5vC\x0e\xeb1\xa1 N\xe2k\xbf\xc8(\x17\x04)\xc0\xb3\xf01\xa6\x14Q\xe2\x81\xb5\xe7mL\x8b$\x04R\x8a\xd8`2\x13\x17\x16>\xa2\xc4\x13\xb8\xff1A\xe4\xc4\x1f\xa8\xec$d#\x13\xf5b\"\xde\xc6(I\x83\x08D\xb9\xc7\xf8>7J$\xa9zLH\xb1\xfd%\xe1\x0d\xa3\\\x90\x01k\xc7\x0fB\x89u\x8a\xa4O\xc8.\x1a\x08!\x94\xeau\x8f\x07\xb8\xca\x86\x11\xf4\xf0\xf6F\x06\x82\xa9\xc8F\xe1s\x8bq\xb2p\xc7%\x8f\x1a\x03\xc8\x81zx\xa97T\xb6\x06\xb2\xd2\xea;\xd9\x9a\xb1\"q\xefbanc\xccu|\x11!2\x12\xa6\x82k\x9f\xfd\x19fe\x1a\xaa\xc2 \xff\x94\xac\xfb\x98'\x9bN\xc2\xc3l\xc8S\xb86\xfc3|\xd4\xb42\x85M\x06B\xd7\x13\xd8\x87\xe7Q\xd1\x01-\x95\x94\xb8\xf2\x14s\xfc\x92}\x82B\x94m\x02\x016\x9d\xc4<\xcfF\x81\xc0\xc61\xf9\x8b\xe13&}1O\\\xc91\xfe\x19\x05\xf82\x1f\xca\x0c\x05\x8c \xd6\xf3Mlt\xd6\x94\xe7\x01\x99>O2\x1eJ\x81\xecM\xac\x85lj\xfe\x8ayu\xac\x01XX\xde\x84\xa7\xd2\xb1\x96\x1b\xc3S\xe9\x98\x1c\xc7Cxu\x00\x1f\x8ax\xa8^q\xa6\xfeX\xf1P=\x17\xfd\x17\xf8&tS\xf6\x8c\xe9z,;\xc6\xfc.\xf63wX\x9b';\x86Q\xe1S\x12\x07N\x08\xef\xc7\x93\xa4i\x00\x82\x84jx\\\x02\x06i\xb7-\xd5$\xd1?j\xf9\xec(\xc6\xff\x11\x16\x92\x05\x104\x7f|\xb2\x04D\xd7\xc2\xa6\x04\x01\xf3\xa4\x9aE\xde\x81\x93 p\xf3#\xb8\x11\xe4\xe0\xd3\xfa\x18\x0bE\x9bA\x9e\xea\x87\xd9?\xc6h#\xaa\x8d\xc2:\x88:l\x1f\x11\x1c \xf24\xdb\x97c\xfc\x08\x8b\xeb\xf1\xc8\xd6\xdaf\x04\xc9\xa8\xc4\n\xcba\x92\xcc\x83\xb1\x90\xb9\xb4\xa1\x10c\xd9\xa6\xbe|\xc5bml\xa4\x04l\xbf\x8a\xa3\\>\xf6\xf81\xde\x95M\xb9\xecO0\xd3\x05S\xe4}\xcc\x0d\xe3DE\x18a\xc2nL\x94\xf7\xb1<\x1d\xc3[\xf5O\xc8y\xd0\x96K\xfa\xdd\xad\xe9\x9b\xbb\xa50&:\x02\xee\xaaw\x83\xad\xe3(\xdf\xb3\x90\xb6-\x97,5%\xaa\x96\xf6\xda^\n\xab4f2e\xe3\xab\x05T\x8e\xd4\xc2\xb2\x96\x84+;\xce\x13\xccu%P\x87Ya\xe9J\x00\xb5\xc5\x10\x0fh3Q\x16\xc37\xe9\x16i\x08>E\x12\x92\xdaq0\xd1Qht\xf8p\xc1j\x19z\xc3\xc0\xd5S\xed\x98\x02m\x96\x1ej'\xd4)\x89\xfaN\xa0\x04\x00\xac\xb3\x08\xa0V3\xde\xc5\xca\x94\x00\xa698\\\xbfKx\x87z\x7f\xed\x1e\x96D7\x93(\x8e\x12\x9dI\xed\x1e\xc6\xcc\x02\xac\x12\xb5\xe1\xfa\xa2a\xf0\x9b\xb7\x80\xea\xb6-N\xf2\x04\x04\x83\x07\x98en\x1a\xa1\x11\xdb\xc6bc\x91\xc6\x86\xc9Mx\x95\x87\xac\xbf\xfc\xfc\x1b,\x96\xc6y\xe8*\x13\x17\x06\xbd\xae9,&\xd7\xb75\x00\xef\xc8\xed\xbal\x8b\xafk:\x87\xcd\x13\xb7\x0d\x9d\xc3\xec\xe2\xb6\xc1\xd9\xb7\xb0\x80\xf9\xbaY\x15\xact\xdf6\xab\x82\xf9\xfc\xed\xdc\xc9x\x12\xfa*3\x01\xc9\x8c*\xe0z\xf4\x98\xeb\xea\xd8\x94\xd7l\xdf\x15\x91\xc2\x02\xd5\xeb\xbb\x1b;\x0b\xec\xdb\xado\xe3*Qf\xf9\x9c\x98\x84KX\x9b\xd0B\xec\xbd\xbf\xfd;\xcc{\xb6\x8c/5\xde\xa0\xc4@0\xc3I\x1c\x0f\x12\x90\xde\xc3;\x91\x94\xb34a\xfa\xb1\xa5c;1\x1a&\x1a\x80u\xf0\xc4\xa4U\xc2'S@\xe4\x94\x1ea^\x9f\x14 \x97hs*s\x12fo[Z\xd9\xc4R\x97\xb9\xfc\xa2\xfd\xab\x1a6\x00\x10\xbc\x0f0]KLR%:\xe6\"\xa9\x12\x19Bq\x97f\x81\xa8JX\x84J\x8atKXQL\x8atK\x18\xf1\x13\x93n\xe9\x03L\x0f\x92R\xba%\xac\xe9l\x99tK\xefc\xa4O\x8aLLX\xd2(]\x03\x92E7 \x97\xb0\xc2\x94\x14\xb9\x98(\xeae>\x10M\xac5IH\xa8\xfd\xe7q\xbd-\x93\x8d [\x18\x13\x03\xc1\x1c%1y\x9a0\x05HL\x9e&\xb2[:O\xd3]\x1b@\xd4\xb9A\x01*O\x13\xa6\x84I)O\x13\x16\xd3\x93R\x9e&<\xa3-\xe3\xa7\x8f\x15\xfb\xc4@0\x03\xdf2~\xfads\x0d\x04\xd3\xd6\xc4\xe4i\xc2\xc6\xb3\x04\xf24\xe15\xd8\x02\xcd\x91\xe0>8\xc3b\xad'\xd1y\x9a0kM\xbc\xc0\xa4\\\"\x87\xdf\xe4p\"\xf8V\xe4p\xa2 \x15\x17Jh\x19\xc8\xe9\x04?9\xf0t+@g\xc9%\xd4\x99;\x81\xc9\x92k\xab\x08\x88K\xc6\xc6A\xdey\x0f\xeb\xae[+\xe7\x05\x91\xc3|5\x81W\xfe\xf1g\x8b\xff\x0fvV\xd6E\xd03r5\xc5vcT\x90<\xb7\x9a\x14\x890\xb0=\")\x12a\x90\xe6U\x0eh\xb2BZ\x90 \xdd\xe8\xc4\x16\xf8\x16\xdb\x84'\x93\x17\x7f\x13\x9d\xd8\xe2\xa7\x04\xe7\x8a\xc4\x16\x98ln\xc98\xba\xcf\xb1\x8e\x95\xc8\xcf\xbf\xa1]DR+'\x8cX\xc6\x88\xe3|]\x18\x8bQ$9\xe6>\xc8}\x820\xa7\xaa\xf7\x84\xb5v%g\x17fTE\x89J\xd4\xfbO\xf1\xfd_\xd1\x91I\xda\x85\xe9\xbfl\xaa\x9c\xb5\x0b\x93\nY\x80\xa6\xed\xc2*\xb5*\x86\xf3v\xe1\xd3b\x8a\x95\x12wa\xb3\x16*\xa3\xf3\x0ea\xf1G\x16;W\x8b\xa7\xe5\x04V:\xc2\x95\"Z\xa9\x10\xf8\x06P\x8c\x13EP\xf6.\xeb:\x97\xf2\x80A)\xc2.D)\x9c{\x8bPf\x9ff\xd4\xb2.\xa2N\x97\x85em\x0d,\xb0\x13[F,\xcfr\x13Z(\x8a\xa0\x8cYx:\xc4\x17\xf1\x01\xa1\xceVG\xc4\xa6B\x85\xf7\x1a\x96\xdad1\x925\x0bK\x04\xaaTur\x98R\xa9B\xa5\xa4WX\x8b\xab\x94\xd0\xf8\x87\x05s\x94\xd3\x8c N \xae\x9b\xc0\xbak\x02\x87\xee\xd7D\x88\xf2\xd3\xea\x83\x8d\xa4\xa2I\xa6CP1\xd0\xe9 \x08\xfa\x05\x90\xf3\x81HQEf\x1bL\x0c\x93jf\x1b\x02\xd6\x81\x0cO \x933 d0WLL\x02\x19\xbc\xe8\x89I \x83iKbn\xd3\xb0&\xb8\xa5uQ\xc2\x95\x8d.J\x04\xde\"/ \x1duqGB\xf0/\xcaC\xaf\x94\xe0\xfe\x03\xac\xde'0\xc6\x8e\xe53\xdc\xf8>\"\x9a]\\r;$<\xc2d\x03!\x04\x19\x85\xf0\x90\xb3[d\xea\xc0\x06\xb5-};E\xebh]\x1b\xfb\xc6l)\xc9\x8b\xec}\xedw\x99\\\x83\x08\xd1&\xb9\x06\x16l\x93\"\xb9\x06\x01\x15\xa9)\x082\x17t \xc7ni\xdf\xc3\xf7\xb0\xa5\xab\xe4db\x81H\xc2zE:\xe2\xc5\x93\xf7d\xbc\xb5\xe8:\xf2a0\xefR\x88\xdc\xc9'd'G*\xaf<65\x08\x00\x84\xaa\xfd\x0d\xcd\x02\xb5\xbdqn\x07\xce*\xa9\x16\xf538\xadX\x9c\x01G\x9f\xe3\xf4\xab$\xe3\x1fb!_\x00\xd4E\x1aa!F\xf0\xc5rQj d\xc9bG]\xc1\xfe\x92\xa0\x99\x04\xe9w\xfd,\xd0\xc4z\xf0\xd3\xdbJ\x96x@\x98\x9f\x80\x80\xaf\xd1\x9f\xd3\xb5Ko\xab\xdc!\x0f\xb0\xb0,!P\xefg\x965\xbf\xad\xfcg\x88\xd4t[\x076`\xb5\xa7\x08\x94x@(\xce\xedR\xf8\x82\xb5^\xe1\xd7o\xab\x0b3 \xb4\xd4D_<\xc04P\x82L \\\x0dPuH\xebJK\xd9{\x98\xd5\x97^\xae'R@=\x08j\xe1g\xa8\xc8.\xd2p\xc0\x86\x02\x85R\x8f\x17\xcb\x16\x06\xd8X\xa4h\x8a\xb0\x11Yn7\xd4#\xa6\xf8\x93;p\x83L\x1e\xf2Oo\xe75\x80\xda\xeb\xa5msk\x89u\xc8\xd4hR\x98#\xa7\x0d\x02I\x03mJ35\xee\x87\x98jogp\xfa\x08 U\x80\xbf\xb0\x01d[\x7fAD\xc6,q\x04\x9f\xe6q\xea\x07r \x7f\x83\x95$]D9_as\\\x9a%\xd2\xeeE\xb2\xdfm\xc3\x01|H\xf0Z\x1dL\xc2r\xf3\x9e~\xb3\x9b\xa8\x0e&\x16\x89\x02\xe0d\x91\x19\xe7=\x9d\xaa\xe7)\xe1\xbayo\x94\x83\x07\xf3S\"[\xe7=\x90\xfa\x9fb\xbb\xa2\x80@_\x84\xc0\xe6=\xcdE\x9f`\xb2\x9c\xe6=\xc3E\xb1^Z\x1c#\xdb\x1a\x990*+H\x11\x05\xcb\xb4\xcb\x11T\xd6\x0e\x8b\xb3d\xaf\xad\x12\n\xdb\xa6 \xd0\xdbu\xeb\xa3\xfd\x1f\xb1-A\x80`\xd3\x9f\x12\xec\x11 \xc8\xf2F8\x86\n\xf6\xa2\xfaj\xee\x96]\x8f\xb0\xd6*\xc0e\xd7#\x8cL\xe5`_\xd2\xb6%\xd2\xb7\xa6\x04r=\xaa\xeb\xa5\x14\xe1k\x19\xa7\x0eY\xb3\x80\xca\xaeGD5\x15p\xedzD\xd4S\x01\xacUPs\xb7^\x0b\xcd\xdd\xe1\xce\xd0\xb1_Bm\xc3e\xd2=\xc2\xf7j\xbf\x83!\xf0\x97\x98\xb8n\xc3v?\xa4\x15\x80}\xd2\xd3\x1a\xcf \xf2\x82OO\x9a\xc7\xf3\xe2;\x91M\xf3\xf8\x84\xf8N\x84\xc7<\xd6\xe4\x05[ \x05H#(\x11XM\x84 \x05\x009\xa0\xd8\x1e\x1b\xd2\x83\x05\xb8j@w\x0d\xb08\xa0\x96\xa6\x87\xca7\xfcWXQ\x9405 |!\x9c\xe6\xb1I\xdbJOSl\xa8!\xa55\xb1\xa2\x86Dp\xcdcE\x0d)\x1d\x8855|J\xc45#\xed\xd8\xb6\xbfn]*b\x90eI\xca\xe1\x94V\xa8\xa6h\x96\xa1\x96)\x9ae\x8e\x9a\xa2\x11\x9e\x9e\xc7z\xad\x89\xc0!@@\xd1\x08\xbb/b\xd6\x88\x19\xc6\xc4\xacachjb\xd6\xac\x90\x9a\xbc\xd7\xe9~\xa8\x8d'D\xba\xb9\x03\x91S\x9f`=q\xc7\x113\xfaA\x86>gN2\x80\x9dy\x17Oh\xc7\x91!\x9aX\xaf\xc8\xe4\xe7\xdf`\xe4\xcf\x94\x9d\x9f\xf8\xea\xef\x18k\"i\xc9@\xb0\xa6\xb1cl\x80\xd8\xfe\x92\x19\x08\x96\xa9\x94zF+H\xdd\x0c#\xbf\xce\x9c\xfcclw\xcdx\xa0\xbcb\xdf\xc5\xeclG\xdb\x8b\xf0 \xcc4\x00\xdb\xcd\xb3!O\xf8I\xd1\xd8=\xb2,\x02\xd4\x8f@b'\xd0\xac\x11\xba3\xe4\xf0\x06*\xa6g\x99\x06`\xb6)\x01\xe9\xa1\xc0\xf7\xdf\xe0\xc3)ac;\xc4w\xf7J\x197\xf1A\x91\xf0:cJ5\x03\xe2[\xbf\xa2/\xf5gC?T\x9e\x8d\x98\xdeU\xb3\x1dbh6\xdcS\xb1\xbdtD\xf5\xe3\xb9\xb0\xb1\xb5.N\x066\xc7d\xc3(\x11X\xf8 \xe6\x1c\x86\xbb\x93\xb6t<\xce\xaf\xb1%\x1a\xa5\xdb\xc0\xc4\xce\x92k\x03\x8bq(\xd1\x06\x99\xa0\xba!\xf9\x84\xe0\xa0\x00\x80\xec\x8d\x15z\x00\x01\xc1\xf8\x88\xa0\xa8\x00\xc2\xbb\xb9XP\xc9\xea\x1e\xe0\xce\"\x0e>B\xd8n\x99\x81\xd7\xee\x03r\xd2\xa3\xb8\x07\xe7\xed],\xd0dQ\xac\xd3\x18\xe3\xa1\xed\x18\xdb\x06\xa6\xed\x99\x81`\xca! *d\xe3)6\x1bdQ\n\xc3\xc6rSVx_\x93\xa3\xb6\xb5\xb8,\x99\xe4\xdb\x84\xb0$\x0e\xec\x91\x05R\\\x9f\xbf\x87\x15.\x0d\xd4\xde\x0b\xefaA\x0d\xc7\xee\x93\xac\xea4t\x9f\xa4W\xd7E@F\xc6HJ\xe2\xfa\xc9\xa5\x9a%\xac\x9f\\\xafe\x89zU\xe5\xd9/\xb0IL_\xc9\xd9z6\xb6\xc1\x8f\xb0\xdc\xbb\x93\xf8q\xc0\x97\xeb\xe8\xb2\x80\xaa\x9a\x96\xe1\x02\xea\x7f\x88]\x06\xb3\xc4\xcf\xd4\xd6~\x84e\xa3,\x89\xf9\x1d\xe5F\xf5gx\x0fw\x8c-\x00k\xbe\x99\xb1\x05\x10\xa2\xa5nz0\xfb\xcf\xd4U\x0f\x96_v\xb4\xf9\x9f\xa0\xb7\xb6\xff\xe3E\xd81\xcf\x0f\xd0>4\x04_\xc0d\xfb>\\\x8c\xdc'\xdb\xb4\x1f\x0d\xb9\xe3U\xf3K\x12\xea\x08\x85\x90w\x13&1\xbb& \x1e\x1f\xba\xdc@\xf0~\xefj\xd1\x07\x8b*\xb9\x96\x960?\xcau\x0d\x0c\x10M\xe9\x00\xfb\x0f\xf0\xb6\xec\xf6\xd4\x93\xca\xf8\xa67W\x80\x7f\xc0s\xde\xed%\\\xc6y\x7f\x86\x97,7\x10L\x13wu\xb4>\xde\xb3\\\x030\xfe\xed\xc2\xa8\xb0\x1c\x93\xc3\x98\xf0\xa9\xcf=\xed:\x809\xc6\xae \xd6\xc7\x04<7\x10LZs\xe3\xca\x89M]y\xe1?\x88\xf9\xe1\xae\x16s\xb0\xd8\x91k\x00V\xd7vM\xc0<\x16as\x03\xc1\x879\xd7\x9e\x85da\x86N\x02\xeen\x98d\xe6& -\x1ern\xde\xc5\xc2\xdaJ.\xdf\xa7\x12\xa0w1\x95\xca\xcbOWY\x80*6\xe5]l\x1e\xcd\xcdC\x18X\xfc\xda\xd5\x11\xf2X\\\xcf5\x00\xbb\xedC\xb0\xed\xc7\x98\xc1\xee\x86\x9e\x8e\xa9\xc5\xef\xe5\x00\xc8\x84\xd4\xe2Ce\xc0:\xa6\x16\xd3sY\x00\x07\xd5\xe2{(c\x8a}\x88\xf1SBt\xb6\xff\x07\xf8\xa8\xed\xaad\x0b\x9fa\x0c\xc95\x00k\xf4\xbb\x86\xc5c\xcd-7\x10L\x04\x9b.\x1cw\xe3\xc2\xb9\x86\xd0\x95\x02f\xa9Wv\xda|\x1f\xdb\x8c\x15\xb8r'KOh\\\xbd\xb3\xc5\x8a\xc5n,\xa4\x81b|\x18\x9eW\xe1\x96\xfa\xd8+\x98\x9c\xeaX91\x9aw?\xc8\x19\xd2%\x8a\xa7\xa4\xc8a\x8ak\xb77\x8e\xf1[MX\x9b\x94E\xd0\xad1\x96awU\x08\x14^\xe4\\}\xc7\xeb*\xbe\x0fm\x15v\x8d\xc1\xfbs, \xe6\x85-\x9cn\x93v\xbf\xc4\x95$\xa4\x187mSa\x10x\x7fb\x99=O\x0c\xa9\xc1\xe7)/?\x02e\x01jRC\x16\\9\x19~F6Z\x03\xb0\xd8\x92k\x0f\xaa_`\x82\xbbkD\x1d\xc2?\x8c\xa8\x83U\xb7\xdc\xbc<\x84\xeb\xecj\xdd\xe83L\xbbr\x03\xc1\xf2w\xae\x9d\xbb0M\xca\x8d\x0b\x17\x96ps-\x0b\x90\xd5\xdeUy\n\x08\xe1V\xdf\xb1.\x97\xef\x1ba\xfd\x11\x96\x9d\xc6N8\x80;\xc8G\xb8\xb9\xb1\x934\\\xab\x8c\x9dD(\xce\xd2c\x01\xaf\xd0\xd8I\xc2H\xe8\xbe\xf0\x9a\x06\xc6\xc2\xb1\x93\xd4\\\xc6\x08\x88o\x0b:\x17\x80\xfa\xb8\xc6\xb1\x16\xa7,\xed%Vz\"\x00\xe0`\x8f\xe5\x86\xb1\x93\x18O\x0clR\x11\xb0\xea\x1d\x03\xbd\xd2-\x97Q7\x0d5\x85*\xa6\xbd\xe62\xca\xc0g-\xa4-\"\xc4\xb6!`H\xd3\"\xaf\x03\x97\xca\x18\xaaH\xfc\xa1/+\xcd\xfa)f\xe1c\xc53\x9e\xe2\x83 \x002\x8a\xef)>\x08\x97A$\xc4\xe4l\x0c\x9f\xf1\xf0\x8a$f\xb8\xeb\"\x87\x19\xee\xa1HaFFe\xea`]H\xb6&%\xaf\xa7\x98\xe3^V\x9e\x9c\xf8\xa6m\x0c\xdfI\xea\x991\xe7j\xb9\x1e`qx\xcc\xb9\xd2W\xb1\n1\xe6A\xe0\xc3\xbd\x02&w\x97y\xa2\xda{\x93\x1c\n\x0d\xfa\x11\xad\x93\xd5\xd5\xc8j\xca\x97\x13\x9bb\xb9T\xc3\xd5\x13\x17u\xd5\xb7y\xec$\x8e\xf2+\xff+,B\xebR\x85\xe5\x07#3}\x04\x04\x13\xe5\xcbZ\x0c\xc7\xc2\xf6X\x030\xee\x8e\xb5\xc4JQ\xdf\xe4\x8e\xb4dz\x1c\x9b\x9c\x8b\x96\x0c\x89\x97\x8dx\x86\x95\xf1\xb1\x81\x10:[\x1b\xef=6o\x17\x92sg\xd8\x16!R\x86ma\xc5z\\\xba\x01\xb6\x90\x8b\xd2-\xb0\x15j\xeeKj\xa0\xbc\x8eZ].\x0e\x17\xd6\x00\xc6w\xfc\xc1\x1dG\xb2\x82G\x18\xf1\xafh\xbfV\xcc\xfd\xf65\x00\xf3\x9d}\xee\xa9\xf3\xf0\x18+\x00W\xb8\x07Q\xbd\x0f\xf1\xe8\xf65\xe4\x1e\xde\x17 \x81C\x89qj\x9f\xfb*[\xcc\xdb\x18\x97\xafht\xc3\xf3\xd9\xd7\x00<\x9f+\x063\xb0\xa0\xb3o \x98\x94\xec\xdb;\xdfO\xac\xa7g?\xe1N6\xb4\x82\xae\x18D\xc2\x87`\xdf \x12\xd6A\x0e\x94'\xd4C\xcc\x04\x0f\xd4\xce<\xfb\x05\x16\xc0\x0e\x94\x13\x14\xd1\x9c\x0e<-\xfe\xe0k\xe67\xf4za\x9b\xc2\x81\x06\xe0\xfd?\xd0\x0f\xb5\x90\xb7o\x0f\xb4\x8eL\x9e\xbb}Cf#\xc06\x90\x03\xf9\x15\xab\x00\x07:\xbd$y\xcb\xf7@\xdfA\x927|\x0f\xd4\xf3d\xe4!\xdd\x03\xfd\xe2\x0bf\x05\x07:\x99\xe0Gx\xaf\xde0\xe8\x80\x95\xef\x03\x03\xc1,\xef\xa0\x88\x0d\xc1l\xea 2\xd6A\xb2\x91:<\x9d\xbc\xdc{\xa0}>\xc8\x83\xbdo\x18L\xc2\xc4\xea\xc0`\x12&\x8a\x07\xc6;\xee#l\x1f<0\n\xd7G\xf8\xb6\xed\xc0\x88\xcc\xa4\xa7q\x0dK>\xd8\xaf%\x00W\x8d\x8d\x0e\x93\xdfC\x03\xc1\xb8yu\x11\x84\x12\x8c\xe6\x87\x0e\xd8\xaf\xf0\xfe\\\xd5$\x0b/\xda\xa1\x06`\xbc\xbc\n\x1d`\xd9\xe6\x10\xda\xc7\xa4\xfd\x90\xcbdBX5\xbb\xaaO\n\x96\xdf\x0f5\x00\x8f\xe7\xea*\xf4\x8b\xef\xa2\x0f}\xe8\x18+\xadW\x0d\xe2a?\x9fC\x03\xc1D\xff\xaaA\x14L \x0f\x0d\xa2`JxU\xd9\x0b\xb1\x08t\xa8\x0c\x86\xa4<\xe8;\x9f\xe1\x83z\xa8\xf4 l\x00\xb8fBQ0\xc2\xdf1\x10LT\xae\x99\x1b\\\x8c\x1ew\x0c\x04\x93\x90k0\x0d\xbc\x8cw\xe03F\x82k\xea\xe5vL\"\xee\xa8\xef\x98\xa6\xdc\xe1\\?\xe2\x89\x19\xc65\x9eDW|/\x1b\xd6?\xa3vM]\x9fb\xc9\xf0\x8e\xfa\x8eq\xe5\x9a\n\x9b\xc6]\xdd\xd1\xc8E\xa6\xa3,\xfe\xa4\x030\xf8\xff=\xee\xe0\x8e?0!c\xf8l^\xd3ar\xf8\xb6\xed\x8e\xc1;|v\xae\x19\xbc\xc3D\xfa\x8e\xc1;|p\xef\xec\xdf\x92k\x85 \xd7\x9d\xfd\x10\x00\xef\xb6\xcc\xf7\xbb\xf2\xaf\xbb]\xd6\xcfC\xe9g\xda\xe6]\x96uY\xd8a\x7fd\n\xb5\xf2\x94\xb34K|7k\xbdj\xbe\x8e\x9d\x84%\xec\x0c\x0b\xdb'\xe7^\xe9T\xbb\x8a\xe4\xf7\xf9\xeftf\xf2\x90\xa7\xae\x13\xf3K^Q\x93\xcf\xf0\x838J\xb2\x94\x9d\xa9\xf6[\xeeTw\x11v\x99\xdfeN\x97\xe5\xec\x0c\xcb\xaa\xdd\x88\x9fh\x84\xcf\xc4Qz\xc99x\xb5\x02\xf5\xfb\xac\xfd\xf2,;sF\x14H\x13w\xc6\x1d:\xc9R\xe4\xf1\xc5\xac\x9dup_\xe2\xd7\x8f\x12\xd6\xce\x8e\x1e}\x95e\xec\xbb,}\xd5VF\xb7<\x07-\xb7Cfo\xbe\xc3\x12\x9e\xe5I\xc8\x8e\xcc\xbdZ\xdb\xc8\xcb\xf3\xb2\x91\xd0\x14v\xd8\x19\x96\xb4\xa36\xb4\x98\x06\xbe\xcb\xdb9;\xca\xe6\xc4\xeat:]v\xe4\x08\x9f\x89\x9d$\xe5\xc9\xcc\xd8 |\xcf\xc9\xf8\x9a\x1f\xee\xb5\x9d\x0e{\xe9%\xd6\x96+!\x16\n\xea\xf0\x99\xc0\x0f\xf7\x96\xa20\xe3a\xc6\xce\x88e<2\xdb\xb1\x8f\xe7\xb4\x1a\x8bhGV\x17K\xc0^\x13\x7f\x9fa\xf3l\x81eG\x8f\x92\x8aw\xc9\x173\xebo\xd5\x97\x93\xeb\xec\xb33lV\xad\xb4\xe8\xf3\xc4<;\xd2\xb4\xa0\xa2\xcc\x91v\xc8\xbe\xc7^\x11\x7f\x86\xec\xbbl\xeed\xe7\xd5\x0e\x19\x81XX\xebd:j.t\xfe\xfe\x83\xf4\xe8\xf1A\x97\xb5X\xab3\x93E\xf2\x0eg\xc9Iy\xfb\x85\xe0\xf0F\xef\x16w\xb3\x19\x8f\xf7\xfd\x90o&Q\xcc\x93\xec\xb0\x9duY\xeb\xe6M\x9e^\x8a\xbc<\xe0\xad.\xc1\xd6 \xe7\x0b\xec\xc8l1\x82N\x97\xc9V\x9c<\xc8\xca\xd3\xac\x99%\xc5\x147\x1a\xc5Q\xc8\xc3,]`\x8en\x89\"\xfb~\xe2\xc4K\xa5\xa2y}\xd14s2\xbe\x19\xe4\x03?L\x17jXA\x1as\xb7\x0e\xc6Tw\xdb<\x90\xb9&\xd2\x05\x96\xd0^\xf4/-J\xf9\xd6Bw\xedu\x9d<\x1b>\xc7\x08\xa2\xe7i;r\xd2\x13Mm;r\x8f\xd2\x05\x96\xd6\xcf+\xe1^\xeer\xd1\xb5[\xbf\xd4\xfaWZ\x84\xc0>P\xf2\xf5n\xcd)\xbcK\xe9l\xdc\x0e\xdb'\xe7\xe7;\x16\xc9\x14@'0\xc87\xa0\x93\x18$\x88W_\x82NaP\xaeA'H\xadT58\x7f\xe2e\x0c\nt_'\xc9\x08]\xdd\xe0\xc9\x13\x9d\xce\xab\xdf20}JX\xbf\x9e\x1c\x08\x02\xc6g\x8a\xc3\xc8^c\x9c\xd96Um\xce\x02\xe3u+j\xe98\xa6\x1d\x0b\x92Mz-\x88t\x95\xd4j\x0e\xfeGw)\xbb \xf3 `G\xce0N\xe59\xc9P$\xcfc~\xc8xG\x93\xa18\x89\xb2(;\x8c\xf9\xcc\xd0I7\xf6CM\x90f\\'\x08\x04Q\x0bA\xd6\xc9\xae\x877\x04S\xb9\x1e\xde@|N\x0d\xb3L\x8b\x04-,-\x02\xfbF\x90J?\xdd\xdew\x06\x03\x9e\xcc\x0b\x8e7\xe3\xa7\x1b\x8b\xdb'\xe4\x9f)O\xc6\xb7\x1b(\x82\x103y\x91\x942\xc5#KtY.\xddJ\xa4\xec\xaa\x93\xe6\xc7\x03&\"\x99\xb0\x90\x00\n\x17^l\xb1\x97{fz\xaek\xcd\x03\xcc\x9f9o0\xefp\xde\xa4=/2+vD\x00\x01 \"\x80$)Y\xd5}\xb0\x96\xad$\"\x10\xd7\x1d;\xf6}'a\x00\x9b*\xfaf\xe7\xbe\x92\x1bl\xbf\x0d\xf1\xed\xd6\x8e\x12\xc6}-\x8cW[\xd1\xde\x07]=\x1d\x13W\x0d\xd8;#\xc5\xe1U^\x10z\x91R\x1c_aP\xfc\xeb\xbb\x9c6\xa2&\xday_\xf6\xa6\x0b!\xdf\x16\xc7\xce\x1cz\xec\xcb\x85\xcdc\xa7\x851\xd5\xf8\xec\xa3\xcc\x94\xf7t\xc8\xb0/\x9fq\x03\xf4\xc5L\xd94s\xb7\x89\x85\xf1o E\xe3\xdf\x12\xfe\xc6\xbfk\xdc\xce\xfe\xac\xd0\xfe\xddLI,e\xffvUw\x8f\x91C\x1d\x82\x83)\x84\x13\xbcXn\x86\x7f\x95\xb8\x17\x87\xed\x85\xf9K\x1f\x89\x15F\xfe\x18\xcee=\xbd\xce=\xfb\xb9MP\x0c\xed6\x93\xc4_\xbf?=#\xe1\x9f\xa3\xe4IY,\x92,\xfc\x99\x18\x88\x8a\x9cR\xd1JZ\x9e\x96\x8c\x1e\xa8Hy\x05!\xe2+ \x91\xd2D\x88\xe4\x9f\x86\xd8\x16\xbf\xe8\x84#\x0d\xaan.\x95-\xee\xceP\x7f7k\x87.\x83}\x7f\xed6\xccvq\xab\x8c'\xdc\x01\xc2+>t\xdf{\x11\xe6\x85\xd3\x06\xfe\xeav#q\x91]\x1d\x92\xbf\xdb\x8e7O\xb2\x03\x7f\xb60\xcc\x0d\xa4[\x93\x1d\x06\xbe\xee\x0e\x1d\xc7\xd8Q3\xa2\x14R\x8a\xe9\xe6\xb1\xba\x14u\x0e\xd3\x91\xa6\x94\xe2\xdf\x92Q\x01\x94\x0d\xb1\x14g\xd8J(\xcb>\xb6P\xbe\x84bn\xfe\xc1c\x7f\xf6}D\xf7|\xd2\x04\x00m\xfdk\x0d\x03\x11#\x03\x92\x96\xf9\xc2\x8e\xc9\x05\xf8\x14\x81\xf3\x1b\xbd\xda\xd6_\xaeQ\x056\xf3\xe6aT\x90l\x00|@}\x88\x18FE\x91-Q\xd6\xbdv\x1cG\xc1v8.X\x8b\xa2H-\xfc\x14!\xd7\xf2\xd3\xf0\xcf\xe4J\xbc\xa1\x84\xc2\n\xc3/;\xfd\xd0>\xe2?\xc8\x7f\xadt\xe5*\x99\xbfJV@o\x8d\x8a\xad\xf2\"\x12\x9f\x15\x0b&2\x7f\x92e\xfe\x95\x9d\xc1c\x18\xc1>d\xb0\x01#\x98\xc0\xa6\xe3\".\x18=\x82\x10\xbe\x82\xec\x11\x84\xeb\xeb\x0e$\xd3\x90V8\x96[\x9b\x86\xc7\xdd\xcd\xa4}\xfaws\xd9\x97\x155\xe3\xd3\xcb=j1\x8b\xd3\xe2\x98\x92\x8b3\xbf\xb0\x13\x87r\x93mV3\xd1^\xff\xac\xe0\xf7\xbf\xff[\xf2\x8c\x9a\x9a\xbdK\xa1\x82\xdc\x06W\x1f\x0f\xe3\xebVe\x91\xef\x84\x8d\\\x99\x81\xbd3\xd6y \x03+\x13%\xf5\x86\xa1Z\xa7GB\xa0\xd5\xe4E\x1d\xde\xd6\xc8\xd7\xe6m\xbev\x18\xf1\xb2\x12\x8f\xe3\xf6*#\xccK[\xe1\x9fB\x89\x7f\xe2\n\xff\x14\x1c\xff\x14\x12\xfe\xc9\x18\xfe\xc9\xe0+(\x1eAF\xf1O<\xcd\xba\xf8'\xd3\xe0\x9f\x04Ug\xb7\xc6?\x127E\xf1\x8f\xdfB/1\xc59]\xd1\x8e\xe9\x88\xaf\x84\xd7?)+E>gV\xa9\x8b\x07\x99\x0e\xa2\xa3MH\xaa\xa2\xfb*N\x88\x15u\x98\xa4Z\xa9\xf1P\xaf\xd4\xd8T)5X\xd1H%\xcdcEz\xa5\xc6\xd6\xef\xab\xd4\x10\xbfd\x91\x7f\xb3\xa1\xa7~\x14\x9d\xfa\xb3\xf7\xf9\xa4&b\x9as\xf9\xb6(\xd2'\xa8\x88\x8b\xd4\x15\xde\x12Lc\xf5u\x12\\Mj\xfa\xbcY\xe7\x90a#\xad\xfa\x92\x97?M\xe2\xc2\x0f\xd1\xdfL\xa3\xbc\x94:;\x08B\xf4V\xc8\xd55_\xa7\x84%\xff\xa9\xfa\xd6(\xe9\x12Q\xf1E\x18\xbf\x9f@(j}\xe6\x87\xc3\xb7c\xbb\xab\x9fKxI\x07\x90C\xbc\xbe\xec\xd8\xa6p\x8cUF\x14l\x91\xa8XQ'\xf1\xd1A\xb4\xff.%\xa8\xf5B\xc0\xedr-\xb1\xb8\x18*ex\xb7\x0e7\x0cI\xc9\xec\x8d_,\xba\xe5LJbU@TA\xa6\xa5\xb0)\x0b\xe7`\xaf\x15\x95\x1e\xb0:\x03\x9cH\xe0\xe9ul+O}J\xf5\xd0\xdb\xc4\x05\xebU\x02\xd5$\xda\xcc4\x9d'SI-\xfd\xb4\xa6-z\x94@\xda\x8e\x83\xf0\xbc\x03e\xe2yO\xae&\x12c\"\x9ekW\xdf\xdcb\\\xcd\"\xc6\xeb\xaf=\xc8\\\xc7\xaa\xf1\x81Z_|\x91\x91\xb9\x10\x13\xecc[0\xb9\xd9\xf8A\xcc!W\x16_\xab\xc6\x17\x99XI\xba\x9b\xf2\x00\xa3jc\xe90\xd5\x8c-\xf0=\x9bUR\xaaa\x02\x83\n\xf7LZ\n\x0c\xf9\xd1q\xd3\xd0\xbf\xf3\xa5\x0b\n\xfe\x94\x98\xd6\x12pX\x13\x98\x99\xc5\x01\xb8\xe4Q\x8f\xc8\x00\xfd\x86,s\xa5%)\x16I\xd0\xdbV\x8a\xee1=\xa2\x15q\x9e\xe9=\xc3\xd8t\x17r\xba\xdd=\x12\x99(J.\x8e\xb2\xab\xe7\xc5\xeb\xb2\x98\xb4\x8d9\xe5\xe7Z!<\xd0\xbdo\xbfko\xe3\xb0C\xcb\x8eY\xfey\x194uo\xa3Pu\xe7\xd0\xcb\xc8\x0e\xc5\x9d\x13\xf6\xdf9\xe1\xe7}\xe7d5\xf1\xa1\xbbu\xa4*\xdf\xd3\x85\xeb\xd6\x0b\x07\xdfNX'\x9e\x87g\n\xa8/\xab\xfb\xabb \xba\x95\x98\xb1\xf8<\xee\x96D\xec\x0ee\x06\x84GW\xa9b\x9c3\xac\x12\xe6\x07\x97dV\x16\x8a\n\xf3\x9e+4\xc5\xf2$~\xba\xf0\xe33\xc5\xf7\x01\x82\x8d\xf5\xd2\xcf\xde\x07\xc9E\xac\x92?.X\x95e\x12\x90\xe8\xe0\xd2_\xa6\x11QU;g\xd5:\xb4\xa1\xaa\xee\x12\xb85q\xc1\xe4\x01\x01\xc9gY\x98\xd2\xad\xb7*]f\xf7\xb3\xb3\xd6g|\xe9\xf8'\xe4\x02\x12\xefu\x16\x90\x8c\x04/\xfd\xb4y\xce\xe9ZG\xb4\xda\x99\xf7\x9e\x08\xe1w\x98\xe5E\x9bu\xa3\x80v\x05{p\x86]\xa8\x90\xd6)\xec\x81\x95\xe0)fw\xd3U\xcd\xef\xa3\n\xdar\x81\xc9f\xdb\xb6?H\xa2\\\x19n2\xbc\xf5(\xeb\x1b\xce\xf0B\xba\x97\xcc\nRl\xe4EF\xfc%\xbf\x08\xe9$\x98\x91k\xe4\x85q@._\xcfm+\\\xfag\xe4\x1e[\x88N\xa1_\x06a\xa2+<\x0f\x03B\x0bu,\xf0 \xdb\xd6\xe7qZ\x16*m\x03\x9f\xcb\x0c\xf6\xeb\x0b\xae\x85DOt7\x1d\x93f[\xf3\x90b\xecK\xf3;\xc1\x0e\xa1\x82V\x98t\n\xb5\xa3)\\lL;(.'\xd0\x8f*/\xae\"b\xb2^\x07\xf4\x1a\x880\x98\x07\x1d\x9d\xb6b\xf72\x026F\xeb\xdf\xfe\xf5\x8f\x96\x90}\xdf\x14\x07\x81\x0e:NN\xf0p\xea:/]\x88(\xc0\xdf|\x85\x1a\xbdfI\xba\xc1O\xb8v\xba\xf6\x17\xfc^p,\xe7#L7 iFf~\xa1\xdb\x0b\xca\x95\x0b\xbcQ\xd5\xa4\x97\x82\xfc\xb7\xd8\x0d\xd3\xf8nw\x88dj\xb8w\x9c\x12\xe1\xec\x1a\xa9\xb0\x06+\xab\xabta\x1a\xf6<6\xf2\xfeA\x98\xa7~1[<\x8f\xc3\"\xf4\xa3\xef9\xcb\xaa`J\xc4\xc3n\xff (\xf8\x12\xf1H\x13\x9c\xa0\x9f\x94\x05\x1b`\xc1\xbaz\x01\xb4\xcd\xc8\x9c\xde\x04B}E\xcehs\x13\x06\x8a\xcf\xe7\xb0\x0f\x01L`\xae\xffhU*\x15\x18\xa5\x8azu\x83\xfd\x86z\xef\x9d\n\x1f(\xa5\x1dZC<\x18p\x07\xc9 \xb24\x9d\xfd@\x05'yRf32\x81es\x04\x86\x83\xb2P5\xd3\xbbW5K>\x01_\xc1p\xcb\xfc\xf8\x04\xcan\x0dr\x99\xfaq\xf0\x8c\xa4\xc5b\x02#\x85t@\xf0\xdbJ\x01\x9c\x80\xda+a\xb8\x83$\xac\x02\xf8jA\xd8\x9c \xc2d\xe2WQ\x9f\x13&z.\xe4\\w:3Y\xfb\xa3!\x12j M\xd5\x15\x90\xd58B\x96L#\x06\xec\xdd\x19\xe8]\xe9 \xefz\x8c\xa7\x15\xe9\xa2\xad\xd2\x90\xbc\xc5\x14\xeb\x95\xb0\xaf\xad\x9e\x18g\xcc\x89\x9d\xee\xed\x05B\x98\xc8\x996\xedh\xd2L\x12\x03VJn\xf8\x17\x0b\x8dW-\xfa\xaf~\xb2\x19\xff\xd4\xd4\x81\\\xc9zS\x818X=f\xaf\xf2\x83\"i!\x04Y\xdbCQd2\x87Z\xd1nY\xbd\x8a\xd1\xc2\xcb\xd3(,l\xeb\xc7\xd8r\x86)\xd3\x15\xad\xc4\xf0\x186a\x9f\x1b\xb3\x11X\x87\x91\xe3\xfd\x94\x84\xb1m\x81\xe5\xc0:\x14`V\xe0\xf2\xcat\x10\xeaM\xa3\xb8\xaa\xa5\xa9\xf5\xc5\x06\x8d\x1d&/\xfa\xe5z\xd8\xb6\xa8\xa8\xf3\xe6=q\xdc4,\xb4#\xafF\x91\xb2\xe5#\xef\n\xf6 \xc5\xb7\x9f\x1b\xf13S\x918 /\xe8\x908!/\xe8\x908>/Pz\xbb\xcfT$N\xce\x0b:*\xcf\x88\xdb\xe9\xd6c\x9d *gf\xa0rf\x9f\x9e\xca1;e\xf6P9x\xa5\xbb=\xc2\x90U\xa1'L\xce\x18\xd3\xd3k\x88M\x9f\xd0\xcbI\xc1\xbe\xaa\xd5Hx\x06\x14gY\xee\xe3{?\x0b\xfd\xd3\x88\xa0\xc8c\x85\x0e\x85R;\xec#\xc8bn\xb3^(\xfa\xd3\x7f\x951O\xfc2\xcbH\xcc\xbf4\xd3j\xd5\xa4\xcfH\xf1\xa4(\xb2\xf0\xb4,\x88m\x05~\xe1o\x9c\xf3>\xfb\xe8\xac\xe6\xc2\xa9\xaf\x06K,\x8d\x05{\xd5\x8d\x82\x91pb\x83\xa9\x0e3\xa66\xc68AZ9\xd1\x97\x9f\xfb\xd1\x04|e\xf1\xb5f\x8f\xabE\x1f\xb4\xa3\x8c\xe3\xc0\xddd_R.\x97\x04\xac\x85\x8e\xe9/\xef\x04\xcd\xdc:\xdc\x00\xfa\xafh\x90\x08\xb4\xbd7T\x9cE8\x8c\xb3\xa8\\\x8b\x9f\x85\xc1\xcb\xa4\x8c\xdb\xc9\xff\xe0\xa32\x19\xdcB^\x0d'\xa4 \xbcH\xf9\xd3\x96\xebcZ\x08%>#\xc7\xcb,\xb2\xfa/^\x15Y\xd7Z\x8b\x1f\xc2(zKf$<\xc7\xcb2\x1f\xb0&\xbd\xa7|\xc8\xa2\xc4\xb2sJ\xdf\xc9^\x15\x1f$\x955{\xe3+\xf5\xdaS\xba\xaf\x1eqk#\xd0\xb5\xab\xf9\xceD\xc4\xd1\x15@/\x19o\x1e\xc6\x81D\xfc\x0d\xa4\xfc\niwyl\xc5F\xdf\xda6LF{h\x8c\x11Vdl\x0b\xb0b\x15`\xe9\x1b\xb3CVO`\xc9\xdc\xaa<>\xa2\x96:zu\xfa7\xb1[\xf3\xc5o>|\x80\xac\xc7\xb0\x11$\xac\xd9n\xa2\xf7Cf\x92\xda_\x0fqj\xa1P\xb7Zz\xe6\x0e\xd4\x08\xb7\xa7Ha\xb31\xf4`\xdf\xa9\xf8\xc4\x8c\xd3\xee\xfc\x98\x0f\xdc7\xcd\xe9\x1e `9\x98\xcf\xc9\xac\x08\xcf\x89\xf8\xd2\x88E\xd0\xfb\xaa}\x92{\xd5\x1d\xb2k\x94|\x92MgW{\x82\x06\x1e5\xb3\x04\x87\xc7\x14\xf4\xf2\xf0g\x0d\n\xe4c\xceo*\x14\x91\xd5|\xc2\x13L\x0d\xd8\xae\xbe\x93\xc8?%\x91\xb1\x9bE\xb1\x8c\xbeA%\xf3\x8d;aa\xd1\x8c\xbd\xd4\xea\x03\x04\xf0&y\xad\xeb0fT 3\xb7k\xda\xa2\x98\x00\xa6o\xe1\x13&p\xeb3\xa0\xe6g[\x8693:C\\!W\xd7\x03\xa7\xdb\xa8\xa7\xb3G\xf6\x8a\x841N\x8e\x905\xf5\x00\x1374\xbe\x0b\x88\xa3\xb4LY\x90`\x83\x8eP\xb7A\xd6S^\x0b\xde\xbd}1\xb1\x0c]7Dg\xa1\x9d\xe1\x8c\xb4\xb5\x17\xdb\xb5d\x8b\xd3\x0c\xd2y5|\xd8\xb4s\xd2Wk\xd89\xf9\xab\xdd\xa9}\xe0\xd5c\x89\x03z\x7f\x0d\xf1\x98\xce\x1a\xda\x06\xd4~\x1bC\xea\xf1\xdb\x95\xc4\xe5\x12\xcd\x11ns\x8e\xe9\xd3\xe2\xe8z\xaf\xf9\xfa\xec\x13\x13\xcfkZ\x8e\xc6\x14V@\x050`\xbf\x06\xa2\x03\xa8\xe2?\x92`B/\xf3\xbd=Hl$\xa6\xfa\xa9\x1c\x86\x1a\xfa\xeb \x9cc\xacH\xb1\x87\x89\xfaq`\xa2\x9fm\x88\x96\xb8}\x93\xe5\xa6\xb5\x05\xb9T\xf1s\xf2\xc3G\xccW\xa2\xcf&\x0e\x86\x83\x83\xb9\x91.\x0c\x9a\x16D\xeb\xf0Q[Ctj\xf4\x88[\xeb\x05\xee\x13\xbb\xce\xf1\xed\xe7&v\x8dtb\xd7H'v\x8dtb\xd7H'v\x8dtb\xd7\x88\x89]\xebQEL\xc0\xaa\x12\xabF\x9f^\xac:\xbb\x8dXU\x12\xac(\xa4\xa7]\xad\xadVy\xdc\x92Z\xdeJy|+\x11\xcf\x9dr?}\xbcM1\xc4)F\x19\xe9\xa3\xa6Q4\xb7\xa5\xeb\xb5\x10\xb2\xa5\x98\x81I\xdbMk\x1f\xa1w\xee1+\xa4p~\xe5\xd8\xed:\x15\xd2\x17\xb0>GI8\x962\x0fE4\xe5a\xf3\xe8\xe3\x9d\xb9\x8b\xdb\x0fYX\x90\xd7qt\xd5\xc0\xbc\xedG\xa7\xabp%\xb0\x1f\x0c\x08\x83\xa1\xb7W\xcc\xc0\x80\x96\xe9\xee\xaa\xd3g\x02\xd9\x85\x1f\x07\x11y\xbd\xea\x88[\xa0;\x14\xd0(\x10\xdf\xfb)O\xe2{\xa1W\x90\xbc\xb0\x0b\x16\xc0^\xb6\x1d\xe0yf`2\xc8\xa6\x00VY\xbe\xf6\xe17m\xaf\xbc\x91vlX\xc1\"9;\x8b\xc8\xf3\xfc \x08\x8b\xaf\x93K0$\x99\x91\x1f\x19\xbf\xb2\xb1\x0f[y\xe9\xdb~\xb9W(F5\x815\x8c'\xc0\xfe2~\xa7\xb6\xc0\x84\x1e\x98\xc7\xa46\x9d\x08W\xf2#\x8fE\xe1|!\x9e\x0e\x82\xd6W\xe5\xa7A\xa3p\xa4\xc3\xea\x14t'w{f\x1bV\xb2\xa9\x80\x15\xf8o\xfa\x08\x05u\xe3\x16\xaa/\xf1\xc1*S\x1d\xf6[\xdd\x02\x02V\xb1\x82\x001\x85\x16\x9e\xe0\xb6\x04\xf5\xdf_~\xa9\x9e\xaa-Ur\\X\x93\x1a\xab\\N\x18\x11\xd8\xf8\xb3\xd2\xeb\x0f@\x0b2d\xae\x8e\xf1o\xbc\xd4\xcf\xc2\xe0]\x1a\xf8\x85.\x08\xc2M\xd7X\xa2\x11\xf8*\xcbo\xb4\xeb\xac\xda\xa5;\x9a\xb2V\x10\x05+\x1e\x86a\xeaxXA%\x0f\x15ie\x88\xb6\"?\x99P\x9f\x0f\x101A\xa5\x9f\x1fx?\x86\x98O\xce\xfa\xba,\n\xb3c#p\xba+\xb3\xad#rY<\xc9\x88\xd2\x15M~JV}\x11\x9e-\xa2\xf0lQ0\xb0\x9a\xf4T\xe1\xee\xab\x97\x9ef\\zz\x13W\xe0\x81\xd2\xd3\x94U\xcc\x0c\xa3@\xf2\xad\x8f\"\x1f\xaa\xf0\xd5SK\x91M\xcer!9\xee\xd9'\xc7\x85s\x13\xa3a-vk\xab\xe7*o^`\x19XS\xbfo\x99fC\xe6%b\x11\xa8\x82R\xf4\xcf\xe9\xc6c\xab|\x13\xf8\x94\xdfqH\x9bX\xb8Rz\xfe\xb4\x15\x01\x15,\x17\xce\xf1_\n\xa2\x06 \x83y8\xbd|\x1e\xacd\x17\x0b\x9ck 3\x12\xe0\xed&\"b\xf6~\xc5\x08\xa2\xfa\xe0\xf5\x7f\xd1q\xae\xe8\x91\xc7\x00\xdb\xbb\xbb\xdc\xbc7~\x9e_$Y\xb0\xf2\xe6\xfd\x11\x9fO\xb1w7\xdb\x0d\xbf,\x12z\xddG\xa4\xa0\xbb\x12\x93\x8b\x8d\x94\xcfu\xc0\xd7\xb1\x08\"8\xf8\x0b\x0ea+|q\xf3\xdd_\xe8\xfdkz\xc2z\x88\xa7\x07\xdd\xe7C\xf6\x85>\x84^\x9e\x83,\xe4\xa1\nf\xda[\xd5\xe0\"\xc8\x8a\x0dF\xf4\xda\x12\x11\xb6\xe4\x94\xf8\x19\xc9\xf8\xbdj\x82\xf7\xdf\xe9\xc6\xc3\xe1\xdd\xea\xca\xbb\xf1u\x87\xd7B\xf0\xd9]u7\xba\xe6\xee\xf6\x8ac\x16\x89\x16.\xcf\xe7\x86\"\x87_m\xab\"\x9c\xbb@6w\x81h\x86#\x99\x01\x08\xc6\xe8\x7fl\xda\xa9a\x08\x81,\xfb\xeb\xd4\x11\xab\x12\x0c\xf6\xfe\xed\xd1\xd1\x1b\xccLK\xe2\x82\xcbR'P\xc6y\x99\xa6IV\x90\x80IR\x08\xa5\x97\xac\xffh\xc1:\xa4\xb0N\x7f\xddN\xfc[\x0f\xaf\x16\x017W8\xed\xb3e\x919\xf6.{\xd1\x002\xb9)c4r\xc6\xab7-\x98\xf4\x1b\xcf\xb4\xab\xccLH_+D\x0b\xb5\x1e\xd5$3c33\xf1e\x95\x82\x92\xaf\x1d\xcf\xe9\xc3\xc4e\xfd\x02$w\xb3\x00\x9d\x99\xa8\xb2\x92\x1b\xb3\xbe\xd1;'O}J\xe3\xd6\xab\xa7\x96\x1e*s\x9d\xd1\x01\x9d\x99\x00\xca\xb4\x9cd\xc8r2Q\xbby9\xd9\xc5=h9\xd9\xeau\x86l\x17\xd5\xec\x15\x06\xb7\xf54\xe5\x15\x87\x9e\x94\xbf\xe2\x11\xa4E\xefT3\x96g\xbe\x17r\xe2\x95\xa7*\x0f\xdbp\xdbK\xd0\x90\xd5\xd0\xa0\x1fL\x15\xe9G\x0d0tM\xb4k\xa9r\xbc\xfa\xf4\x07q\x05LT-\xa7j\xe4\x03\x82\xc8\x19h;\xe5)T\xc7\xa9Q\x07\x8d\xcb\xebxn\xd2\xd5\xe17\x12\x08B\x87\xa0\xba\xbd\xfa\xf2ws\xf6MZY~\xfbp\x03\x85\x82\xde\xaaYGW\xa7\x06 \x96\xf7\x95R>k\xf1\x80$\xa1\xe7\xbc\x8d+u\xe5;pKo\xea\xa2\x11[p\xb8;t\xdb\xa1\xba\x9eT6(\xc2\x9b\xd6\xa3Z4\xa4*U\xef\xfe\x8d\xe2Yw\xe5J\xffhB\x83\xed-\xbd\xd4`\xab\xc3\xd3\x87UQ\xc7\xad\xd9\xaf\x8a\x1e\xe8d\x07\xdb[\x0fu\xd2\x83\xedme\x8ckV\xf4yX\xf2\xc9\xfb\xd9lHX\x8dHym\x9aSyR\x16\x8b\xe7\x05YJ\xb9\xc7\x9b\x15\xea\xec\x0c\x93ZR\xd0\xacR\xa7\xa26\xa6<%3\x1e\xb6\xd0\x9ba?\x98\x90\xeb\xeb\xab\xe7\x01\x89\x8b\xb0\xc0\xa06b\x08\x7f&W\xa8*\xc2\xbe;\x8db`mQ\xf5i\x12\xe7\xe5\x92\xe4?0\x01\xd1JB\xfb\xdea\x17\x8aa\x8b\x0eQX\xe0\xd8Ek\xd0\x9a\xe12_\xcf#\xfft\xd0\x00\x05\n\x97\xd2\xf2\xb1\xbc\x0f\xb0\x8f\xd1\xe0z-%\xea\x0f\xbf\x0f\xf3\x10\x85'k\x9bj*\x8d>\x14FN\xfd\xd9\xfb\xba\xb2:\x1c\x14\xa2QK\xd4^uP\xdd^\x0cCR\xcd\xc00(FO\xab\xd7\xde\xec\xc2\xa5\x98\xbbzT\xca5U\xf6\xa8A\x1f\xf0\xb9j9\xf4\xbb04z\x04\xd3n%\xf1Qv\x95\x94\x05:\x07\xeb+'\xbc2\xf3g\xee\xa9\x1cr\xbd\x99X{}M\x96\xe5\xd2\x8f\xa2\xe4\xe2(\xbbz^\xbc.\x0d\x96P,\x87e\xc1\xeb\x1d\xc4\xfei\xa4\"\xd5\xc4\x83\xf1\x1f\xbc\xb9A\x0b\x12\xad\x10\x0e#\xa8\xebb\x1ag}\xcd\x05\xd6\x1c\x18L\xf6\xbc\xaa\xdc\x1b\x1fv\xc9\xb6`H(\xd9\xb3\xaa\xea\x80!\\UZ\xce\x97\xa8\xc5\xd4\xd7<\xad\x06\xfb\xc6\xa8\x13=a\xdd\x0b\xad\x8e\xbe\xe2\x05\x86e\xaeQf\x8f\xc3\xd8\x01\xab. \xa5?\xd2\xc8%\xfb\x80\x07\x85;BZZ_\xfb\x90\xd5~Z\xa1\xca\x1e\x0f\xb0\xa7\xac\xfe\xdb\xdaM\xbc\xef\x8b\xf7\xb0\x07%\xa5m\x0c>\x7fO(Q\xe5\x859e\xbe\xf4\xb5^\xc3\x1e\x9c0\x16ArS7\xcd\xee\x0d\xec\xc1\xa9\x97G\xe1\x8cP\x9c\xb51rx\x82\xef\xc6\xf7F\xe5\xdf\x8dS\xad\x1a\xb4oZ\xcd\xcd\xc7\xe8\xacO\x05w'}\x0eP\xf5\xdd\xb8\x9f\xd5\x838T>~\x155\xd3\xcc\x1c\xac\xfdX# \x02\xc5l\xc3\x82,\xc1\x82u\x9e}\x8b\xd9\x93v\xae^\n\xf7\x96\x8f\xaa\x1b]2S\xc3\xca\xac\xa0\x13\x1c\xa6\x04\xd5\xf6\xc4#2W>F\xf5ZQv\x86\x1f\xba\x9a\x9er\x0c\xd9x?\xd1~J\x83\xf9h\xdb\xd9\"\xb9\xfe17\xb3F\xedR\xcce\x17\xcd\x9bu-\x1c\x98\x06J\x18\x0d\xa2\x14\x8b\x88\xa7A3\x193=6H1]r 9K\xb3\xf1\xb4\xdd\x02*\xe5\xf5\xaf\x1b\x1e\x10r=\xf4fI\x19\x17\xf6\xad\xceD\x0b\x1c#2\xa0cmg\"7\xcf\xb0\xee$\xc4\xb8zO\x14\xe7W\xa0\xa6\xaf\x96\x0d\xa8\xb3\x18<\xe2Y\x12\xc1,\x89N\xd8\x85\x03\x8d\xdd\x8aN\xd0IK7\x13\xeb\x15\xbap}\x8aq\xc8nO\xda\xe1<\x93}\xa3\x1c\xe3\xb8\x1a\x99\x94\x06\x99P\x82\x8c:%\x9f \xee7\x9fV]\xbd\xf4S/\xcc_\xfa)\xf3\x17R\xd8\x1f\xd2\xe7\xda\x0e\xa5\x8e\x07&o\xd2\xcd\xe7\xa2\xcf\x8fh\x1e\x1bc\x95@G\xcaj\x88ZB\x1fA\xc1O\xe0\x94\xd1\x80}\xd9\x84j\xb6g\x02\x06\xfe\x80>\x99\x7f\x81W\xe6\x04z\xe2T\xa4\xac\xd6\xa2F]?\x84\xc8\x82\xf8\xb5|\xc9\xbe\xc2\xf4%\xc6v\x98\xdb\x94\xec\x94h\xae\xdf\xcc\x04\xd4\xe7\xa3#\x7f!\xa4H\xf2\x97-QV\xff\xbaK\xb2t\x03\x07%jsNo\x02\xe7}\x8b)\xb8\xb7 \xf4\x04\xd7\xaeBEN\xe0\xbd\xb6\xa2.^h#;\x1c\x06\xd8\xbb\x0b,\x7f\x13\xe31m\xc7i}\xdd\xbfJ m\x90o0\x01\xcbj\xdc\x9bm\xb2\xe6\x8e\xee\xad\x8a\"\xab\xef.\xb8\xcbY\x1e\x1a\x07\":\x9f\xf0\xb0\xe2\x98Z\xb2K\xb8\x1a\x0e\x8a\x8c!\x14,c\x1f\xc1y]-\xf5\x13\xdb\xa1\xa4\xe2\xeb:t\xab\x9e9\xb8\x93\x95\xff\x87d/oJ\x0f\xd7\xe0}\x82w=\xa3\xda_\xd7r\x01\x8c7\x80; \xfd\xa9\xbd\x81\xb9$\x03#%\x1a \x83\xa6\x87\xb1\xae\xda\xa5iN\\\xe6y&\xe2\xfb>\xade4\xdc\xff\xe8\xccmk\x8a\xafL + y\xf2 \xf05\x10\xe9\x00\x1c\xef=\xb9\xc2\x1b\xdfH\xa8\xf3\x8b\xa1_\xd8/\x9e\xa5\x97\x93\xe2mg\x06\x03r\x1c\x8bh\xf8fd\x0dm\xdcn\xacmr\x0f\x1e\xc6\xfeI\xd1<\xf9\xd2m\xa0\x06Zw\xcaM@r\x93\x83t\x17\xb8\xf1\xa9\xd1,\xb7Blo\xf4+\xd2\x08\xfc\xf8zP\xbd\xef[\xe0\\\xbd3\x01s\x9d\xf8\xa1/\xf9\xaf|i\xaf\x06\xc1\x03\xdc\xdc\xb5\xa6T\xedG\xa85W\x9be?\x84\x03W0\xcck\xea\xdb\x8e)\x0f\x19C\xe3\n3D\x9d\x12\x0f'\xb5\xe5sY\x0dr\xc0\xa9\x84\xd5h)\xf1\xf0\xc3\x9c\xd0^\x9f\xc7L5\xd4\xfba_\xa4\x90\xc1\x88g\x95 ~Fh\xa7F\x97\xab_\x03Z|t\x03\x8bo\x95\xa5\xf7\xb9\xe8M\x1dD\xb6%\xa9\xe9\xcb\xb5\xd4\x12\x01\xf5Uoi\xb8\xba\xda\xcd\x86\xbe\xac\xab\x92\x95\x94\xdb\x13\x98\xd6!SZ\xf1h\xe9\xaa\x06\x06\x1b\xaf\xf3\xcf\xd0\xa8\xc6e\xa6\x0b\x1d\x03\x16\xcc)\x95\xc1\x1e$H\xecdM\xd3\x91\xccl:\xd2\xf4\x93k\x81\xac_[\xe8\x89W\xab\x98)\x0e4\x94SZ\x83\x85\x83\x84\x9a\xbaZ\\?\xadod\xe9G\xea$\xedyq\x15\x11\x9de)%\xfb\xcf\xb2\xa4\x8c\x83\xa7I\x84\x19\xdc\xff\x7f\x0f\x1e\x9e\xce7\xb7\xbb\xf7t\xeb\xe4\x19\xc6\x92fj\x19\x9dL\"\x9c3\x1bx\xab\xdd\xa8E\x17\xdf\x92O\xfegj\x0d\xd6\x03E\xd9\x10(\xd2\xd8K5\x0dj?\xcf\xe9\x07\xdax\x16\x81\xce\x18.\xd0\x19\xc3\x05:c\xb8@g\x0c\x17\xacf\x0c\x17\xa8\x8d\xe1\x82\xda\x18\xae\xebd\x93r\x0f\x81-\xa5\xb1[\xf0\xe9\x8d\xdd\xcc)\xfe$c7\x15\xed'\x19\xbd(L\xde:\x9e\xc2\x83M\xdbn\x95Q\xf8\xf31\xbf\xe93\xae)jO\xe0\x1es\x11JPO-t\xde\xd98M.\xadc\x03}O!L\xeb%\xcc\xd7i\x8d\xf9M\x88\xe0\xc2\"\xeeX\x9a\x91\x99_\x08i\x80\x1dsI\x8e\\\xc0.\xd7>U\xda0\x86\x8e\xcd\xa7n}\xe3\xc2\xcf\xe20>3\x89\xffE\xdd\x89uW|e\xec\xfd\x94\x84\xb1m\x81^\xe8\x91\xe8{J\xbd\x97t\x16\x1d\xfa\xf3\x97kW\x86\x01\xc3Pd\xb9\xb9\xc9\xb6\x88\xa4\x94#5d\x0b#\x97\xa9\x1f\x07\xcfX\xbd\xbaoOzO\xcf\x9b:\x01\xd4\xcd\x1c!\xfb\x1c \x19_\xa6\xbf\xb3\x16\x9f\xe75\xf4\xef\x0e\x1a\x9f\xad\x83\x86\xc15C\xaf\xa8\x890\x91c\x97\x89\x02~\x93\x87\xde<\xc9\x96\xbe\xa2_\xee\x92\xc1\x03\x9a\xab\xfd1\x84K\xd7\xda\xde\x1eD\x18\xd9\xfb4\x8c\xfd\xec\x8a\xbd\xc1\xecB\xd6\xa9\x9f\x93\xddm\xf1F\xef\xa9\xc1@_\xef\xd2\xa0\xf4\xe4\xe0\x01\x12\xe7\xa12\xdd\x90\x84\xeaJ\x1eS\n\xf6\xc1\n\xe3s?\n\x03\x8b\xc9\xe0\xbbm\x86E\xd4\xfc\xa2\xd4\xd4\\E$\x9a\xdbU\xcaK:\xda|\xba\xa9\x08\xd2\xaf\x90\x07\x04a\xce\xd9\xdc\xc2\x0b\xf3g\xfc\xaf\xe6a\xf8\xcch{\xb7\xca\xbd\xdfL\xef\x0duR~\xe1\xe8\x9e+\xde\xd5u3\x92\xa7I\x9c\x13I\xea\x01R\xa6\\\xcd\xebJ\xde\xc3\xdbnEN\xd2\xb9\xcb\xc6\xf6}\x05\xd6\xd3\"\xb7P\x8b\xdc\x8c\x84R\x15\xf0\xacP\x06<\x8b\xab\x80g\x94\x88\xccX\xc0\xb3\x0c\xbe\x82\xe2\x11d\xeb\xeb\x0e\xc4\xd3\xac\x19\xf0,\xd3\x07<\xab\x15\xf0&\x92\xadJzwx\x95\x17di;M\xdb\\\xfc\xeb\xbb\x9cN\xc7HW1Z\x96\xd9e:v\xc6r\xbf2j\x96\xad8?\xde\x0d^L<\xad\xdb\xf6\x0f\xdd_\x8a\x8d\x0c\xcd\xd1J\x854\xb6\x80}\xc0\xd4\x18\xcd\x06\xacc`\x81t\x9b/\x95x\x0e)\xd5\xe7\xb1\x1d\xf3\xec\x05-XW\xc0]kl\n\x03\x88V\xd3Sag\xfa\xcc/|\x8b}\xe22\x85\x03\xcbZr\x8c}\xb78YWw\x18\xee\xaa\xffn\xe3\xa6\x81\xa8N\xeb\xdd\x8d\xa4\xd3\xba~(j\x84\xd2?\x14q\x1eT\xae\xcc\x98\xb8\xa1\xbe\xf0\x84\x0f\xb3\xd6\xc9:\x91P\x9b\x9are~\x00Ul*\xc59\xc6\x80\xa2\xfb0\x0d\x11|;s\xc2\x98\xcf.\xc4\x02\x94\xf5\x15\x9a\xe7\x0bH\x94\x13\x15S\x8b\xbc\x96\xa6\x9d\xa2\xdb\x8ei\x1b\xb3a{\x93\x0f?\xc8\x9f\xc9\xa6\xc4C6\xc5\xbc#\x03\xb7#6n\xc7\n{\x11W\xaa\xb4\xcc{\x9dq\x17\xf5\xd4\xb1\x1d\xe5\xd6t.\xed!\xfb\xe3Br\xbb\x9d {w\xc6\xef\xdb\x99\x84\xc5\xddeq>\xf7k\x84\xe2\x9b6\x8a%#\x17\xa8G_M\xb5e\x08Mn\x9d\x82\xa8\xa7\x89G\x9de\xa3\xb4}\xa2\xbcrl\xdah\xac\xd9\xb6\x81\xb1\xbai\xeb\xa5\x97\x914\xf2g\xc4\x8e\xc9\x05\xbc%g\x07\x97\xa9m\xfdb\xc1:`D\xc6k\xcb\x05\xeb\xccr:*9\n\x11\xa5\x04\x1f\xf8\xf3\xf7\xa5+\x95\xca\x8e\xd2\x8e\xedqG\n\x1a\xf2\x92Q'4\x0fSX\x8c\xb7v\x95T]\xf9;\xb2\xac\x14\xfb\xfer\xed\xb6\xa5\x82\x99\x0b\xbe\xf7\xee\xcd\xb3'G\x07'\x87\x07/\x0e\x9e\x1e\x1d<;9}\xfd\xea\xe8\xe0\xd5\xd1\xc9\xd1\xdf\xde\xfc\xfbZ\xaa\x88\xe0\xd5\x16\xf5\xf0\xcd\xebW\x87\x07\xbf\xcf\xaa\xeadR\xaa\x98\xac=\xeb\x91\xb8\x10\xeaH\xf1U\x16\x84a\xaf\x93\xef\x9f\xbc}\xfe\xe4\xeb\x17\x07w{du$\xc4 \x0c\x16{\xef\x89\xc2\xa8\xc5\x17K\xad\x069 \xef)\xef\xfe\xcc\x85\xd0H\x11b\x05\xe3V\x94.\xf8\xcd\xf5\xcdnq%\xd72\x8fQ[\xbd\x97\xf0\xd7;\x0f\xa4\xfb6\xa1\xcb\x82y\xf4\x92\xec\xc0\x9f-l\xbdh\x01\xe9>\xef^\x18\x07\xe4\xd2\xfb)gr?-\xd5Gw4\xb1U1\"\x88G.\xd3$+\xf2)#\x80R?\x9f\xf9\xd1S?'\xdf\x84\x11\xa1\xdb\xe8\xd8\x85s\x8c\x1b#.\xd1}\xe9w\xdbAH\xba~\x07-\\loo\xefR\xb2H\x8c\x03\xd7eg\xb43\xe8k\xc3\xb2\x0b\x1b\x8d\xad\xb1L\xd0\xd4\x11\xbd\xecU\x0c5*Z#\x93\xa6W P\xdfd\xc92\xcc\x91r\x89\xed\xed\x9d\xfb\x8e\x0b\x87H\x91\xd7\xa65^^\xf8Y\x91\xff\x102\x0dIlo?\xd8\x1d4\xc3\xd8~8FM\xef\xc3\x07\x9dU\xda\xde\x19\xd6F\x1fpno?TB\xe7\xf6\x8e\xca\xc0%\xb6\xef\xb7_3b\xef\xfeHZ\xe9\xe6H\xc7[\xf7\x1d\x1b\x05n.X\xf8\xaf\xd5\x83\x87P\xbbt\x82\xd2;\x9b\x08'\xb3\x13\xda\xff\xa6\xf8\xe3=ES\xf5~\x18\x92x4T\xa6'\n!|\x15\xac\xe0Da\xd7\x18W\x85\xe1\xfa\xba\x12{\xac\x11\xdcTxL\x19\x94J\x9cm\xd7s\x10\xa2\xb9\xc4\x1e\xa1MzB\x0f\x9bE\x0f;\x8b\xd3\xc6\x8d\x0cYZ\xd9\xfa\x1d\x992\x99C\xec\xe2O\x89;\xbav\xab\xcah]\xf3D\x08*Q\xd7\xc0W:\xb3Y\x17\x0e\xfe\xac\xabg\xb6E\xe2\"\x0b\x890\x9co\xc3\x8f\xbc~\xf2F\xca\x0b\xac\x8e\xd0\xd8\xfb\xa5j\xaf\xf9*\xaaP\x17\x8b\xb9\xda\xdd\x93 \x89)\xdb\xb2f\xa6\xfdoy.F;\xeas\xf1\xb0\x1d\x95\x91\x1d\x8b\x87m\xc1\xb6\x8f\x9c\xc6#\xe9,\xeflb4\xf3\xd8\x1e=tl+,H\xe6\x17\x98CV\x0f\xbb|q(,\xd5\xb3k\xa1\x82>y\x1b\xa9\x11\x11\xc6\xef\xf6U:\x9e\x98\\\x16\x142Gn;u\x00\xed.\xc4\xb6)+\x0b\xcf\xaba\xaf\xb6\xdc\x12\xc2Q\xdf\x86[\xbb\xeau\xdd\xd5\xe2\x95\xedm\x07\xf6\x95\x9coHr\xe81@N\xecv\xa2\xa1Jk\x10\xbb\xb8y!\xaa\x07\x90\xda\xadT\x079S\x16\x94\xf0\x18\xf2G\x0ed\xde\xdc&\\\x182\xcd\xd7\xd7\x8f](\xa6q[\x08!\xa8\x8c\x9b.\xd8\xfd\x91\x9a|\x18\xa9!q{g[\xb3duw\x1a8\xab)\x0e\x96wFGQ\x94l%\xf4q-#$9\x84\xcaES U\xa3\x14\x1c#\x05iBI\x1cv\xa9\xc2\xda\x9e\xde\xb5\x117\xed\x11D\xf0\x18f\x8f\xf46\xc0\xb45\x9bne>\x9d\xad\xaf\x1f;\xb4\xcd\xd2\xa9\xcdU:\x1f2\xe1S\x7f\x970[_\xef\xe9\x16\xaf\x87\x19\x841\xe4Ho\xe4\xd3\xd91\x0b+\xea\xd4r\x0f\xac\xf2\xe1\x03j\xa2\xaak\xe5\xcb/a\xa3\x19\xbbhE\x1c'a\xb3]\xd5\xa9{\xe9\x17\x0bo\xe9_v\xc1\x88\x95\x84q\x1f \xe9\x11\xba\xcd\xb0\x0dq\x1c\xf8\n6a\x9f\x9e8X\xa7C\xdc\xa4\x97 C)7F\"\xea\xf9P\xac\xbds'\xc0\xaf\x83\xfc\x10\x83\xb8SHbD\x9eM k\x0d|\xb3#\xa2\xf3k\x8dPp\xc8\x0e\x88B+\xc1\xc6\x94\xe3\xda}\xf8\x009%/\"\x14\x87\xf1X\xb4\x9c\x9a\x9d\x80\x8dr8o\xb6\xf0\xb3\xa7I@\x9e\x14v\x8ek\xbe\xb33~\xb8K\xbf\x0d\xe11\xec\xecn\x8d\x1e\xb2\x86\xd6a\x84\xe0\x87\xb6\x04\xb6\xdf\xf9\x98V`\x0d\xecn\x8d\xb1s\x9f6p\x7fk{\x8b\xf7\xcf\xeacGt'a\xc2\xdf2/\xbd\xdc\xc5N\xc6\xb4\xcc\x87\x0d\xde\xcc:\x1d\xe7\x06\x1f\xd4W_\xc1h\xd3\x81u\xd8\xdd\xd9\xd9\xda\xbd\x1b\x08\xef\xdc\x1f\x1c vu\xd8\x90\x02\x8b\x83\x12e~\xa5\x0d\x8a*\xdc\xbd7\x90\x19\x13\x1f\xb6\xc4\xf0\xc5\"K.\x802\xef\x98%\x1dO\x80\x05a\x0eqR\x00R\x00\xa7\x11Y\xd3X~dv\xc1\xa2\xf0\x11g\xc5sB/\x81\x07\xc88\x8c\xb7\xb7\xf1\xdf\xed\xdd\x87\xec\xdf\xfb[\xec\xdf\x07\xfc\xfd\x83\x9d\x0eg\xb1\xbb\xe9\x08\xaefHg\xbd\x84\xd4\xaejgd\xd2(\x99\xc6\xf6\xe8\xbec[E\xc2N\xd5\x91\x7ff!\xdbi\xfdlQVn\x9d\x82\xfc\xda\x1eX\xd3\x04o{\xf8\xf9\xd8b\x0c\xd7\xfd-\xc7\xe6\x14@\xed\xc9\x00UCV?mU\xb5\x89\xe9j\x90l\xa7\x90i\x1dK\x1ah\x0c\xa94d-\xe4\x85\\\xa3\x1c\xfe\xa6\xc32\xac\xd8\xa3\xcdQ\xbf\x0d\xf5}:I\xb5(\x9f\xae\xe3\x03\x87Y\x1e:.X\xbe\xd2\xfe\x10\x83ik{i\xf7\xd6)l\x99\x088\x9e_\xaf\xc1\xa0\xf9KDK?\x11\xa2\xb8;0)\x0d\xbb4\xc4\xd5\xf8\xa8s\x0c\xd5z0Le#\x9d\xc3*\x02\xb6\xcdTG\x02$\xd8\x86d6\x13U\x89\xf3U\xf5\xa7\xd2\xb0\xe9\x1bE\x1e\xe5\xf5|\xf56\xd7>\xcep\xdb\xf8\xc6z\xea\xc7\xff\xb1\x80Y\x12\x9f\x93\xac\x00\x0e\xe9E\x02i\x16.\xc3\"<'\x8c\xcdZ\x95\x9a\xef;\xf3\xdb\xbbm\xc91\xc3\xc6\xe3\xed-%\xcd:RJ\x15Z\xec\xd3\x03\xc1>\xdd\xff\xef\x99}\xd2\xb0\xa5\xdb\xbb\xea\x95\x1dw\xc48>\xc7\xca\x94 }~p\xf2\xe6\xed\xeb\xa3\xd7\xed\x80\x15e\x9b\xdfo\x16\xb7\xc5\x01\x9d\xf58g\xb9+\x0b\xde\x15E\\\xe1<3D\xc6@+\x0c-5\x84$w\xe1\xa1S\x90\x17\x84y\x1a\xf9W\xf4v\x88\x93\x18\xf3E\xdb\xe3\x9d\x11\x9a\xf5\x938x\xba\x08\xa3\x00Y\xb7\xc2\xcb3\xcacX?\xf9\xe7>\xf3\xe9\x9dXU\x16J\xee\xfb\xf7C\x18\x07\xc9\x85\x17$3\x14\xa18^\x92\x92\xd8F\x18\xb9\xc8\xc2\x82\xd8\xd6W\xec\xd3\xc7\xa2\x8a\xf7\xcd\x1eC\xd1_\xfdx\x8f\x17\xa1j\xd7\x9bEI\x8e\xe9\x0ds<\xc1\xdf<\x82lc\xe3\x91\x03\x01\x89HA \xaf\x01i\x1aN\xb3c\xbdMYn\xb7`H\x8dI\xf9E\xc1,8)\x9dfD\xad\x889\x95tF\\F\x11J\x90)\x15g\x97-x'\x0ecpcrA\xf9\xbef1s\xff\x8aYZ^\x82\xa6g\x98\xd5\xc2qei\xab\x90p%v|+\x9a\x7f\xa46\x1e\xec\x9c\x08\x0e\xf9\xdb\x0f\xf4\x94\x1f\xbd\x98\xff{\x90\x1d\x8cF\x0f\xd4d\xf1\xb8\x8d\xa0\xb9\xf0`w\xd7\xb1\xd7\xda\x02\x075\xca\xb8\xc1\xfd\xce\x97\xa8\xe4\x84t\x17\x17\xe0\"u_Sfiz\xacX\xf3\x98\xf2\xd5\xa5\xc3\xa4\x04>\x8a\xf31%<^\x9b\x91\x88,\xa4\xf8\xf0\x11\x14BX\xcb\xf7\x03\xbf\xa3\xa8\x01w\x83\xb9\xa8\xfc\xa7\xd0\x8e\xb0\xb5\x0f\x1f\xea\xd6\xd4[\x14\xddt\x8b\x1e>\xd4\xac$\x83N\xdb\xfa\xd9r\xd0\xd5\x82\xd2\x81\xcf\xf3\x83\xb8\\2\xbe\xc1\x96`\x18L\xe6\xd1\x82\xd2=\xac\x93\x83\xd0s\x8d\xe6;y\x1a\x85\x85ma\x8e}\xde!\xb9\xf9 \xed@\x95\xd0ti.\xa7m\xdd\xdc{'\xd3\xe0\xd6\xff]T\xf5\xdf\x92\xa8J\x83\xb2\xb6w\xdb\xef\xc3\x01\x94\x8c__\x94\xd5\xc5e\xbcN\xcfH\xf1FT|=o^\xab\x1aX$\x02\x9d\x01fp\x0e\xf1dMQ\x1b\xad\xa2\xf0)\xa9\x90\xc4y\x91\x95\xb3\"\xc9\xd0\xe4 \xc28/\xfcx\xd6-\xddo\xfe-\xdd\xbe\x93\xe6g\x1c\x0f\xec\x83\xdf6\x00_q\xfdw\xb6nz&9\xfe\xc8V\x17XT\xf7'g\x1f(;P\xb1\x0c\x0f( \xcd\x98\xca-\xc7\x15\xde\xf0[\xfc\x82E\xc6\x80'\x8f\xb5G\x9bc\xc7\xe5>\xb5\x94Z\xc0\x83\x1b\xb5\xb8\x05\xf6\xaa!kp\xd1s6\x17\xba\xb3\xa0\x13m\xe1\xe9\xe1\xe1\xdb2\"/\xc2\\\x11\xec\xe0\xe9\xe1\xe1!%M\x9f\x91Y\xe4\xb3x\xd3\xdd\x80 O\x0f\x0f\xd1\x14\x817\xd1.\x8dB\x12\x17o\xc9\xacP\x97?{\xfd\xd2X\xc8\xe6\xa2->J\xde\x93X=\xf8g~\xe1\x1fe~\x9c\xcfI\xf6\xbc Ku\x1b\xdf\x84\x91f\xe4\xdf\x1e\xbd|\xf1$\x8a\x9e&Q\xc4\"P\xa9\xab\xf4\x95\x7f\x93dK\xee\x85\xa4\xae\xc0\x9c%\xb4U^\x92 \xf4\xd53|\x19. e\x89qs\xbb_\xbe\xf2\x97$x\x95\x04\xe4\xa5\x9f*J\x93@\xb3\xebo\xfc0\x16\xe1O\xd4K\xf3&*\xcfB\xc5|\xd9{\xcdp\x0e\xbf\xff\xd3\x0b\xbc\x8a\xd4m\x1e~\xff\xa7W\xe5\xf2\x94d\xda\xe27\x98%X\x03\x0b\xb4< c\xcd\x80\x0f\xbf\xff\x93 \x90\x0e\xbf\xff\x13\x83\x94$\xd3\x80\xc9!f\\\xfb\xba\x9c\xcf\xb5\x03\xa4\x07\xe5pAH\xa1^\xd5#rY\x1ce\xfe\xec\xfdS\xddQ\xa9jh\x8a\x93rV\xad]Ur\xed\xa2+zb\x07\x945a\x94\xf89|\x05\x0b\xc1s\xc2\xf9\xfa\xba\x8aZ]\xba\x18\xc9~1=W\x18\xbcQ&4\x98\x9e)JN\x91\xacW\x95\x9c\xc0\x1e\x9cR\xa4\x7f\xaa\xba\x90\x80_\xc5'H~\x9e\xd0\xfb\xf7\xc3\x07(\xed\x13\x17f.\xa4\x8e\x0b'\xd3y\xfdn\xee\xc2\x19E~\xd33\xca\x80\xa5.\xa8\xe2\xd2 r]\xd2[=s\xe0d\xba\xc4\xcfC\xfa\xf9\xd2\x85l\xba<\xae\xc5\x9b0\x14a\xf7\n\x804J\xcb\xed\xfbj\xbe\x03\x11w\xe3\xbd_Q\x94:&n\xbc\xbd\xfb\xefv%\xff8v%z\x82\xef\xbec[e\x9c\xcf\x92\x14\xbdU\xda$\\\"\xfc\xf5T\x07\xa6\x123@2\xcd\x8e\x99R`\xe7\x01\x1a\xaff.\xfc\xa2\x97\xf6u\x98\xfaiv<%\xf4\x18\xc9\xf6\xf0\xca\x99\xe8$\xfeF\xd8\xfb\x0c\xed\\\x84\xb1\xa9/(\xa9\xf1v[\xc2\x92W\xc4V\xe35\xa7\xb0\xc6\xaa\xb8%*\x8d\xcf\x9c5\xdf\x16\xd4\xb0p%\xf7\xb7[\xaf\x03\xdez\x1b\x85,8\ni\xd7?\xe7\xef\xdb\xf6\x10K\xd6\xebN\x1b\xb5\x9c\xf1\xf7[\x8e\x97\x93\xd6\xba_\xb1\xb6\x1elvb\xe1\x9dr`m\x8f\xea\x84\xb7\xd6\x1e\xd5\x05\x7f\xdf\x1e\xd5\x01R\x9a\x95\x8c\xbeYx\x89\x85i\x96\xccH\xde\xf2D?\xc4\"\xae\x98k\x16=\x85=\xb0\xf8Gx\xceg\xf6e\xab\xd7\xf7f\x89\xee\x13\xb4\xb0\xdd\x83So\xde,xM\x0f\xc4\x9aY\xda[dW\x1a\x9eW\xe0\xc8C/#y\x12\x9d\x13\xbb\xbdz\xf2\x83\x1e\x1aM\xf6g\x8f\x1ea\xa1\x1e\xccS2C\xfcr<(\x1b\x96x\x88\xfd\xde\x85\xf7z\xd6\xf7\xba\xcb\xd2\x83d\xc7\xf0\x14\xfdQU|\x1c\xdf\x8b\xb7\xe4'F\xd9\x1e\x9c\x93\xb8p\x98\x0fK\xb1 \xb1\xfd\xde\x919\xb4\xa2\xd3\xcd5\xcc\xfcb\xb6\x00\x9cCK\xf9\xd6\x06\xbf7\xbdsF\x15\xb5V\xa8\xbcf\xaf\xa5\xf4\xbb\xe6d*m\xb5\xcd\xe21\xd0a;8\x85\xe6h[\xe0r\xd4\x87\xed@\xe8\xb9\x88w\xa2\x95\x88\xd02\xc4\xb7\xea\x0d8\xe7\xb6\xcb\xc4;\x99\xa9k\\\xe95\xaa\xf2\xd3\xe0.\x89wr\xcex\xcb\x11`\x8c\x9a\x93\x9c\xb1\x97\x9b\x8c\xb5\xac\x05K}p\xc5\x85\x995\x02M`\x1f\n/y\x0f\x13(\xbc\xb9\x1f\xf6\x84@\x87*A\x14?\x1c\xfd\xd5#^\x9d\x02\\\x7fm\x9649H\x96~\x18\xab\x17P<\xfa\x13,?%\xa5?\x124\x1b\x19\xf3\xb5[PP\xf9 \x89)\xfck\x0fF\x8e+\xe2\xff\x94H\x81\xec\xa1I\xb5\x8d\x81*f\x1e\x89\x0b\x92\xd9\\\xa7P\xda\x19\xf2\xe8\x98\xa1\xd8#\x97aas\x06\x7fm\xd3au\xf6\xd0\x1b\x81\xdbX\xefCd\x1f\xd8\x16?w\x1b\xb3\x85\x1f\xc60\xbb\x9aE\xc4B\n\x08Ma\xde\xd8\x14\x82\xf7!d\xda\xd2\x18\xfdK\"Z\x9cc\xc9\x04\"[\x91\x1dP~\x1a\xe7\xb2wYp\xfck>\x9f\x1f\x9fDd\xf7\x84\xdf\xbc6\xe0#\x88k\xd9t\xf8\xc8\x01\xdf\x8e\xa7\xe1\xfaz[9 ?\xf4\x90\xa0\x90\xdc\xad\x8e\xd5\xc8\x05\xd42\xaf\x89}z\xa9\x1b\x93\"z\xe6\xb5\xe9\xf8\xbf\xec\xc5Egl\xf1s\x03\xfd,\x1eD[(\xc4\xe5f\xfbxB\xb5\x13\xa5[\xfc\xbc\xa3\x80\xa9J\xe7\x14\x08(|\xc0C\xe0\xf0\xa3c\xea\xed\xa7\xde\xdeV\x85_54\xca\x80U-\xfa\xb7l7,\x01S\x05\x87\xa9\xaa\x02\xdf.v\x0b\x9b\x92u\x0e\x00'\x01J\xf4L\x0d>\xfa\xc6\x9dz\xd5\xbbv\xc2T\x8er\xaa\xddu)\xbc\x93\x00\xaf\x10\xfcA1\xbd\xcb\xd6\xa0\xf0N.hA\xe1x'\x94\xa2\xa7d\x85wB/\xc81\xfe\xf2\xc5W\xccG\xfdd\xc6\xed\x0d\xe9Eqd\x17(\xc40\x8e\xfc\xed\xb0\x91\xbb\x15o\xaeV\xf5\xac\xc5\xdeI\xa0\x03\x86\xb8\x9e\x14*\xcd\xf9\x9c4\xd7\xaf\xf9\xda\xa5\x9d\xb1\x1b\xb0:X\xf5\xe5\x073\xb4\xec9\xa5\xa7\x19\x89\x87\x00\xc2\"'\xd1\\\x97?\x8f>\xb8\xceo\xd0\xbcj\x7f(\xf1\x04\x12\xaf\xde\x7f\x17\x9e\\L\xc0\x90l\xb1\xaa\x16h\xd3\xb2\x8aGC\x95\x8bg\x18\xc5\"\x0c(\xe9}\xfc\x16/\x98\x11\xde\xcd\xaf\xf8\xef\xbb$\x03^\xb1\xbe\xb2\xde\xc0\xdb\x86\x9b\xdf\xa1wL\x05\xfe1\x03\xff\x11\x85\xef\xd8\x855\xddx\x87\x8d\x93\x8f\xcf<\x91\x01\xfb\xd7\xb3w\xd7\xda\xf9w\xe7\xdd\"2\xea\x1d\x7f\x8dg\xfd\xd0x`\x17<\x82\xe7\xa1\x0b\xe2PX.X'\x0b\xcbq1\xd4\xa9\x0bY\x9d\xc5\xbau*\xd4\xe0Cl\x04\x13\xd6n\x05)\xe2\xcf\x16r1.\xfa\xabf\xfe\xec\xe6\x97\xd5_\xd7.\xbb\xc4\xf5\x93d\xd2>A\xd9\xb1\xbf\xe4\x9b\x97\xbd\xc9e f h?\xfc\xeb\xbcSy!Wf\x84b= \xa7i\xdeco?\x189\xf6\xa1l[\xdb\x1e\x1f\x89\x07\x84\xfa\x17\xac\xdc\x13{)v\xcd\x9cS\xfc=\xec)\xd9T\xa6\x7f\xc6\xb3A\x19\xacf\xad\x9a3G\xba\x97br\xce\xfd \x19C\xefb\xfe\xe7\xa4\xb5&\xb3*\x07U\xb5\xc6\"Y\xcc\x89\xdf.\xcbi\xd9\x11\x9f\xc7\x1a\x05\x93Xp(\xcd}n\x9e#\x04\x97\xbe(v\x92\xc5\"\x13!\x88q\xeaa\x88kG{\xe5\xd41\xb9\x80\xecQ\x17\xba\x04U\xc8n\\\xfa\x86\xdf(\xa8'}\x8b \xd5GNU\x84Z\xe6=v2\xb0D\x86\xe6SoNwy\x88\xb2\x98\xe0\xcdv\x88\xdb\x89?}JA\x93\x0b\x16\xf4m\x82\n\xf5\xc6$\xe7\xf6\xdc\xfb\x13\xac\xc3\xdc\xfb\x01\xff\xff\x0d\xfc\x11\xd6^\xb7\x01\xf2\x8d \x8a\x0e\x1b\x1f3\x13S[\xc6\x15\xdc\xfe}\xec\xd8\xf2+\xa6v\x90L\xe0Y\xc7\x87\x8d.%|\xd3\x9e\x1b]\x9e\xbeM\x16\x04\xd2\x13\x15f\x02I\xf4\xb4\xe9V\xdc\xbe\xc3\x14\x16j@\xeb\xacS=\\\xbb\xa4+\xbc\xf6\xda1\x8e\x1a\xf7\xbbo\xd8|T\x17v)\x0eG\xb5o\x870\x81>\\\xd7\x19\xda\x9a\xfd\x9a\xc9\xeb\xb7\x1fl\x99\xa2\x85\x1ez\xcc\xea\xd9\xc3\x13d\xbf\x97\xc1\xc24-?\x8a\xfa\xa6$\x93\xaa\xea[\x8fa-\x9d\xf1\x10\x8b\x86`\x14\xdf$\xbc\x8a^d\x13\x0e\xe7T\x05\x1e\x9d\x1a\"4\x03o\xd2\x90$\x1f\xb8~m\xa4\xa7\xb1\xce).\xa7\xd7\xc8p9\xeb9\x0f\xb6\x14\xae\xaf\xf7S\x80\xe8!a\xe8\x1f\x90\x98F\xcc\xcbP =\x9b\xeb\xebn--\xa3\x10\x81(r\xf8\x08\x01;\xa6\xa4E.\x88\xf4iy\xcc0\xdf\xc6\x062\x18\x99\x1d\xf7Q\x85Z\xa6\x198\x98KM)\xeb]\xeb\x8f|\xe8\xa1-Ub\x87\xde\xf9\xd0\x8b%\xf3g\xbdg\xf7\xae\x00]\x0f\xc5\xc9\nP\xbc:luw\xbd>v`\x90\xe6i\x93\x08jw a;\x90\xd9\x89i\x07$\x14\x84?o\xa4\"dB\xaf\xf6\xd4\x91\xc7\xb4\x1b\xb6]\x05\x8a\xed\xb9\xaasmo\x0f\x98\x84\x07\xc2\xb8f\x0dk\xa7\x8f\x18\xd6\xc1\x9a@\x18\xcf\x92,\xa3\xb7u\x18\x9f'34K\xd2\xb9\x9a\xdd\xdc\xbe\xb8\xa3\x02\x14z~\xb5;\xf7\xf6}\x95\x9f\xbc\xc2\x86\xbb\xe4f\x01m\xcdc\xce\x9bi\xdb\x02F,\xb0W\xe3\xdd\xac\xe5C\xc2u\x1c\xa6\xdd\x98\xbb\x90\xaa\x08\xa8\xc0\x85\x85\x0b\xe7\xae\xb0\x07Ia\xbf_2\xd4Y\\\xf1\\\xa30Ze\xff|\xc5|Fq E-p\xeb\xd4;E\x13\x96\x0e\xdc(I\xe6\xb3\x9b\xfa!\xa20\xd5>sT\xf3C\x9dJ\x802|a\x9d\xe0<\x82\x00\x1e\xc3\xe9#8\xd5Y\x9a\xa2\x95\xe9\x92\x07\x8c\xbd\xb2}\x9b2#dzz\xecL7\x8f]XLG\x18+\xf0\xca\xc6wN\xed\xa7\xba\xc4\x9f\xb3\xca\x0cu\xd9<\x8ej\x13X\xa6\xf7\xc1da\xdcq\xea\x11\xaca\x97\xe7^L.\x0b\xdbq\xbc \x89\x89\xc6\x1a\xb7\x1alb\x9f\xbbp\xe5\xc2\x82\x07\x82\x82b\xd8\xd0\xae\x1d\xef\xeb\xb7\x07O\xfeL\xc9ezq\xbd=8z\xf7\xf6\x15\xec\xc1l\xb5C\xb6\xd3o%-\xe07\xe90\x90JFW\xe0:\xd8\x87\xc2\xa6\xf7\x14.\x7f\xcc\x97\xbfh_\\\x15\xafk\x8c,I<\xd6\xacB\xe6\x87\xe0'\xe1\xaf\x90\xa1\xd8\xb0rhs\xdb\xfa\xc6?4\x7f\x0d^\xab\xae!QR\x1b\x99Hf\xa0M@7Y\x98\x0c3\x1f\xe1+*\xcd\x11\xaf\x11;cv3L\x8c\x87\x86W\xd3\xe4\x98\x0b\xf5n&:\x8d\x1c/a\x98\xc3NuY\xa1f\x0b?\xf3g\x05\xc9\x9e\xf9\x85?Q\xba\x94q\xfb\x9c\xde\x85H\xbd\xc0/\xd0j\x8aNe\xde\x03\xdfJ$\\\xf5\xa1\x9a\x85'\xde\xdc.\xd0TOA\xf0a\x82\xb4\x12\xb9\xe0\xaeK\n\xac\x1aX\xa5\x90\xe3M\x88\xa7u\x14nLo\x18\x89\xfc\xa4%U\xed\xde\x7f\x82Y\x9b\xde?\x9ef\xc7m,\x1br\x16\xae\xef\xec'M3y`\x13`,\xd4\xac\xd3q H\x04\xe3\xaaB:\x1d\x1c\xc5\xd3\x12t\xfc\x01\xb8\xf3C#t\\fg\xde\x1bX\x87\xcc{kP1\xcd\xc3\xd8\x8f\xa2\xab\xa1\xd2w\x9f+\x8d\x93*j0\xe5\x88\xc5\x1f\x1a\xd1{\xacSr\xab\x92\xd9\xb4\xd5\xc7\xb1,\xa7\xd4\x1ab\xf3\xcfJ\xcchj;m\xbd\x8a\x89\xcc\xeal\xb4\xfc\xa8\x8c\xcb(\xebF\xa9\x8b\x8f<.\x86`V\x1b\x96^u\xf9\x11\x81\xb7\xebP\"\x02\xf7l\xb7\xc0\xf1\xd0\x00\x88E6\x18\x08\xf1\"\\\x84\xb9\x01\xdcB\xa5}\xad\xd0J\xc7\x1eACwn\x0b0\xa9\x953\x8e\x1d\xa3\xd2\xa4_M=dAc{\xfb\xc1}\xae\xa5\x7f\xc0\xff}\xd8\x8cj\xc7\xc3co?\xe4Q\xed\x1e\x8a\xf7;\xfc_\xfe\xfdC\xfe\xfdC\xf6\xfd\x0e%G\xf0\xdf\x11\xffw\xcc\xff\xdd\xe2\xffn\xf3\x7fw\xf8\xbf\xbb\xfc\xdf\xfb\xfc\xdf\x07\xfc_\xde\xde\x88\xb77\xe2\xed\x8dx{#\xde\xdeh[\x19e\x8f9\xdb\x0eY\x8b^0\x1aw\xc2x\x87U\x90J\xbc\x92\x9f\xf2\x10\x8f]\x94(WJ\x02\x82\xfe\xc1-\xc8CD\x88\xe6\x04k\xcc\xd0}\x84\xf1V\xaa\xa0\x19Ul\x91\x0e\x82\x94\x1b\xed\x83\xd0:o\x9f+\xb4\xdc8\xe9n\n?_$\xed{\x0c\xbeVL\xc0\xa2\xc2\xed\xc1z\x9d\xc8\xcf\xc78; \xc5'\xa3\xd1h{4\x1a9\"v>C\x18o\xfd\xf8\x8c\xebH\nYG\xe2\x03\xa6\xb3\x84Y\x12\x10H\xe9dtv\x96\\i]\xc0W,\xba%\xecc4 \x0cy\xca\xa2_\xae\x83m\x17\xb0\xb1\xc7\xca\x1dx\xfc\x18\x10~\n\xf8\x0f0\xda\x1co\xc3:\x8b\x99\xd9\x9b1\x17$\xfc\xcb\xb3\x0c[\xb7\xc3a\xbd`\xa6\x8b\x1b4\xda\xdcR`+\x0dPd\xfe\xc5pP`\xb15\xbc\xcc\xbf\xe0LiX\xcbnM\xe0A\x81\xa7d`\x12\xc3c(\x1f9\xc0-\xb9x\xe4\xd6bZ\xae\xaf\x1f;\x18F\xe2+&kiV\xa8\xc1\xa6<6X\xab\xf9w\xb3\xf4\xea\xeb\x83\xe2\xacM\xc7\xb6\x8a,\\Z&\x85y\x9b\x9bV-\xaa`\x059\x15\xb2u\xbb\x01\xf7\xc2\xca\x8e&\xd6\xdf\xa6:\xbc\xd4\xf6\xc3\xf6{\xba}\xd6\xd4\x82u\xf0YD\xce\xaeXS$\xdb\xfa\xff\xd3Z%\xff\xcf\xfac\x9b/\x8a\xea\xaau\xa5/\xda\xb5f\x03\xb8o\x90\x85\x12\x8aT\xb2\xc0\xc7\x1d\x0e#S\x04k\xb2\xe6O\xc9\xb1\xcd\xbc\xf3~\xfb\xf5\xff\xf8\xb7\xff\xc2\xe2\x9d\xf2\x9fX\xa6l\xe3Zs\x8b\xd3\xb5I\x98;s\x89J\xbe9\x86\xe3\xed0\xca\x807\xfe\x97_\x82\x9dLcZ;GWnA\xfbR\x94_\xca\x07\xb9e\xf9\xd2Z\x809\xec\xc1\xcc\xa3\xb0\xda\xc7\xa0\x81\x04\x8er0eT\x05\x8e\x803\xef6\xe1jE\x96]-w\xc1\xc2\xbc\xeccM\x85HTh\x11\x1ej\xc1\x82Z\x0b+\x8fT\xaem\xfdX\xfc\x18\xffx\xfe\xe3\xfc\xc7\x0c\xfe\xed_\xff\xeb\xff\xf5\xeb\x7f\xfd\xd7\xff\xf3\xb7_\x7f\xfd\xed\xd7\xff\xfc\xdb\xaf\xff\xc3o\xbf\xfe\x8f\xbf\xfd\xfa?\xfd\xf6\xeb\x7f\xf9\xed\xd7\xff\xf9\xb7_\xff\x97\xdf~\xfd_\x7f\xfb\xf5\x7f\xfb\xed\xd7\xff\xfd\xb7_\xff\x9f\xdf\xfe\xf3\xff\xfd\xff\xfe\xfa\xeb\x8f\xe5xs\xfc\x00\xff\xff\xf0\xc7rN\xe6sk\xc8\x19\xbb!M9\xde\xde\xc1(n-vF\x8f\x91g\xe2\x8a~\xd2{I\x0b\xd5q\xafm\xf3 $r\xc3 \xea\x02\x8a\x8d:\xe1%(n\xb1,\x8f\xc4\x01\xe6_Q1x\x14\xc8\xe9\xa7[\x8em\x89z\x96\x81\xa6\x11u\xfaVJ\\_\xa1X*\x17\xe4\xf6\x95\xe76V\xdcg\xf0\x18F\xb0/\xa5#\x1e\x1d\xd7\x06\xcc\xcaV2\x96\xf1\xc7\x1c\xd3\xacl\xe9Iy\xee\x1b\x11\xf9\xddN\xd0\xe493 \x18~j\x0d\xbc\x82O\xc7\xcdM\xe1\xd1\x0f\xb3DM \xf7\xdc)a\x03\xeaK\xbbd6\x15\xf9\xef\x02O\xf7\xc7J\xde_\x06\x8d0\x9eEe\xc0\x82]\xe8@C\xd4\xe9\x03\x8d\n\xed\xff\xa7D\x02\x8e\xba\x07\x0fS;\xbd\xc6\x08\x91\xab\x80\xc3\xed\x0ecc\x99\x06\xe3\x8e\x8c\xa4\xc4/&x\x83\xef:+v\xd9\xb7_\xa3\x91\x96\xb6\xb8\xa9\xb4\xb8\x0e\xdcO\x99`\x05x\xa3\xc0E\x91\x89>\xe4\xf1P[\"S\xf48\xe5a\xfaC\xd8\xdb\x83\x11\xdc\x83M\x05Ca=M\xca\xb8\xa8\x1d\xb7br\xe6\x17\xe19is\x12\x0f/\xc9\xdd\x0f\xbd(>\xc9\xd8\x93\xb8\x98%\xd1\xc78\xb2\xb4i:|\xd1\xfc\xc7<\xb6\xb4\xaf<\xfc\x99|\xbcY\xf0\xd6?\xe6$\xc2\xc2\x8f\xc2Y\xbe\xd2\x1c\x86L!\xfc\x14\x80\xb42\xf2\x19\xb4\xfa\x88\xf6\x17\x19\x99\x7f\xe4\xa5\xcf\x97~\x14\xad4\xfc!\xa3\x17\xad~\xf4\xc5\xa7\xef\xdf\xaf\x06\xfc\x83\xc6/\x9a\xfd\xf8\x13(O\xef~\xf4\xe5'\xc1\xfey\x99~\x84\xa1\xa7w4\xf4\xd8\x1e\x8d)\xb9\xbc\xf4\x8b\xd9\xc2rad\xae.\x0dfZ\xd5S\x8a?\xd5k\"\x1e\xc1\x19\x10\x93\x921\x91e\x0f(z\xa8\xd2\x99\xc5\xd3B\x9f\x19C2\xafO`_\xd8\xe11/\xaa \x9a\xc0q)o\xecL\x8bc!\xc8\xcf:qA >\xbe\xe1jrQ\xa3\xe5\xc2\xf8\x06\xeb\x99)<4`\xd0\x92\x86}K\xea7\x964\x93\x974\x1b\xb8\xa4\x12?\x91a\\\xb3\x04W\x95\xbd\xe1k\x19:,N\xd3\xdd\xadhN\xfc\xec\xdf\x01\xf4\xee\x963\x8d\xc2B \x9e\x1d\x03K\xfd: \x0dGl\x8fw\xda\xbe& D!\xdd\xd7L\xef\x86J\xb4\xae\x90\xc4\x9a\xa1\xf1\x8a\xe5\x9f\x9e\xce,\x9ew\xe2\x9e}\xea\xfc\xf1\x9eC\x99\xe3\x0f\x1f`\x1bu\x1e\x05\xc9\x8b\xba|\x7f\xe2\xdcsac$\xc2:\xd1zc\xac\xe7\x9f\xca\xb5|lH\xaa\xc4\x1a\xf3\xea:\xde\xbeC\xffkT\x92\xcb\x1d[*\xa3\xdc;-\xaf\x8a\xbd\xfd\xaaP\x05r\xe7\xdc\xf7Y\x12\xa8\xde\xb3\x9d\xfd\xfd{\x1e\xb9$3\xdb\xb2\xe8\x1c\x15P3DO\x02\x92\xad\x9a\xd0]\xaa\xe3\x06@\xd3'gOx!\xf14<\x95%\\;\x95\x8a\xfc\xedZ\"\xa7_\xab\x83\xe8\xe1\xe8\xd4\x9f\x9d3K\xff\xdc\x85\x08\xc3T\xcfY8}\x93\x93z\xc0B}\x86gq\x92\x91\xa7>\xc6\xf6\xb3B\x0b&\xf4\xda\x83uZ\xb6,\xa3\"\x8c\xc2\x18\x8b\x96\x8d\xa22\x0eQ\x11\xbf\x0fV\xd9(\xc8\x8bp\xf6\xfe\x8a\xbe\xbf\xe2\xef\xf5CX\x98}\xe4\xcf\x9b\xbbY\xc0>l\x8f\x1fn?\xdc\xbd?~\xb8\x83\xe6\xfe\x8f\x1f?65\x80\xd1g\xeb\x03O\xbc\x1c\x83\xa3\xbb\x10\xc0:Xg:\xfb\x01\x94\xfea\xd0\x06t\x8e\x90Z`J\xce%o\x876\xf2\x85\xbd\xbf\xf6\xe3\x8f\xb9c\xb9\x10\xa84\xd4\xd5\x83\xfe\xeeK\x06\x8b<\xbe\xe7\x9amG\x18y\x0cE\xcd\xb0\x0e\xf9t\xf3\xb8\x82\xf0\xc7\x80\xf1\xd5\xec\x94\x07?\xe12\xa5\x85+>p\x1c\x17\xd6\xd0\xb6\xbf!\xf1\xc2\xa4!\x9b\xc7\x95F.s\xcd\xe4O\xe3\xc1\xa9\xcf1.\x01\xcc\xe1\xab\xae\xe4{\x03\xc6\x8f`\xbe\xbe\xee\xc8;S\x8b\xd8\xe6h\xe8k\xe3\x8f=\xa5D\xbc\xf1\\;nw\xf0|9\xbe\xaaC0\xa2]\x00s\x14J\xe9\x07l%F\x0e\xcf.!-\x1b\x8b1\x1f\xb9\x90V\xad\xee\xc1\xb9\xe3|\x00\xbec,\xa3O{\xfb\xe8\xa0\xeb\xc1\xc19\xecC\xca\xcb6]8\xc7O:#hY.3\x8f\x06kS\xa0F!\xd3\xdct\xa4\x15\xb3\x07a\xb6\xe6\xa5\xd9FW\xb0\x0f\xd3c\x98\x08\x1cT g\xdb\xdc\xa0Z\xcc-\xd1\x08\x1a\xa2\xeb\x06d\xd5\x8d\x08\x01\x89\xac\x8ak\xb2*\xeb\x90U\xb1\x8a\xac\xcaV\xa5\x03\xcc\xf2\xfa\xd4\x8e\xed\xedQ[\xec\x9c\x88\x92q\xbb$\x14%;\xed\x12\x9f\x97\x8c\xee?h\x17\x95\xbchgk\xb3]\x94\xf3\xa2\xadNO\x11/\xb9?\xden\x17\xcdz\x03\xf7U)\x98\x88wrB\xf2\x97IPFD\x97C\x14$\x99\xff/\nW\x10\x8c\xbb\xc7r\xe2\xe9B\x99\xd5\xf9\xdex\x0c\x86v\x8a!o\xe1\xe7\xaf/b\x91\xbe\xb5\nC\x17s\x95\x0d3\xb6 \xdd\x84oP\x83\x10&\xa6\xf3\xcb\xa8\xe0\xa1\x99\x9a\xa0A7e\xbb\xb3Ts\xae|q\x1e\xfd\xa1z/\x96\x0eR-\x8b\xdaY;\xcc\xf4<\x18Y\xa3.E\x92\xd6Y0\xde\xdd\xd9\xdd\x1c\x05-E\x1b\xbdv\xad-o\xf4\xc0\x1b\xb7J\xe8}j\x9d\xfa\xf1OI\xab\xe0\x8c\x16\x1c\xfa\x85\x0b\xe3\x1dxR\x9e\xc1xs\xf4\x006\xefOv\xc6\x93\xf1.\xfc\xe9\xe5\x91t\x10\x86\xe9\ns\xb1\xf4\xde9\xc9\xf20\x89s\xbc*;/?|\x80_\xae]E\x89\x97_\xf8gg${\x17*\x9d\x97x\xb5 (\x02\xdd\x9e\x85\xc5[r\x1e\xb2\xf2\x85\xb2\xfcY\x98\x15W\x13\x08\xba\x85\xa7e\x18\x05G\xe1\x92\xe4\x85\xbfL'p\xd6\xad\xb2\xf4g\x8b0&\x93v\x0c\x85.\x07Ph\x1d\xaf\x82dy\x12\x06,\xcf\x94\x1ao\x06\xc9\xf2U\x12\x10S\x95<%\xb3\x89\xde\x88*\x8b&J5,/\xccMMG\xfeUR\x16\x13\xb0\xbe\xf6s\xf2\x02\xff\xd0\xb4\x14$\xb3\x83\xcb\xd4\x8f\xd9r[Q\x98\xebj.\xfd\xcbg,\xf5( \x8e\xfc3c\xff\xf30*Hf\xaa\x81\xe6\xa4~\x91d\xefp\x9e\x8b\xa2H\xf3\xc9\xbd{IL)^\x01=^\x98\xdc\xab*j\x86\xc5|\x97r\xfdB\xce\xca\xbcH\x96\xfar\x9eO\xf5uJX\xea\xaa\xe7A7\xa9N\xab.\xcfz\xf4\xac\xd4%\xbb\xaa\xea\x13\x92\xbe\x08\xe3\xf7a|\xa6\xaf\x94\xb1\xd6\x9e\xc7\x05\xc9f$-\x92\xacOc[\x7f\xc9\xb0\x97\xb2\x82f\xba\x19\xc9\xd3$\xce\xc9'\xea._$\x17\xe8\xd3M\x02\xbejj\x073\xa8q\xeb\xcb$ \xd1[\x12\x07$\xc3u\xb3\xc8\xa5\xbfL#\xa2\x83`\xe9+\x04\xe5\xe0\x19I\x8b\xc5\x04\xb4{R\xd7\xcf\x87|@\xa7ppY\x10<#\xb9~\x1fi\xbd\xa7\xc9r\x99\xc4\x83j\x97)\xc5\xc3$8,O\x97a\xc1\xa2M\xe4\x13\x98Zg\x04\xd5.i\xc9\xfeIr\xfc\x97e\xd1\xa5\xbf\x92\x94nU\x8e\xfa\x01\xe2\x07X\x89\xcb8\xad\"\xf3g\xc4\xd20\x9eiFrR\xd0>\"\x81\xb0u51C\x17\xad\xa9\xa9\x10\xc6a\x11\xfa\xd1!\xddX\xfd\xd1\x9a\xc7\x86c\x99,\xd3$\xa6|\xcb\xa4\xed<\x05jp\xa2\xfc?%\xd3\xe7^\xeag99D\xb9Y'M p\x82\x89x\x1c\x057\xf1:OF\xac)\xa5X?\xe5\xdd\xf8b\x8d\x1c\x9b\xdeq\x05\xd2\xde\xb1\xa2\xb7+\xed5\x91_\xe5\x05Y\xaa\xc8\x08\xf1T\xd8+\xf5\xf8\xcfU\x0eW\xb5M\xa9\xc7\xf7V\x03kl\x9b\xda\xb3\xd2\x8eJ\\\x1ff~U\xd4J=\xf6K\xdd\xb7x\xc4\x95\x90z\xec\x97\xb6\xb2f\xaeP\xdf\x98\xc6~X\x1d\xdd\xc5)\x1e\xbc]S\xaf\xcc\"\xfd84;\x01\xa9'C\x7f\x97@V\xc4&\xe8\xfb\xa4\xa2\xa7O)=\xdd\xaa\xdd\xfa\xbbEZ\xdb\xa7HRK\xfdS\x15\x9a\x078`\xb2\xdc#\xa5\xc0\x86\xb0\x073\xc7\x85\x13/'\x05\x1bCn\x97\x8e\x0b\x17\x02;=\xc1\x99\xe7^\x94\xf8\x01 0\x8fI\x9d=\x9d6\xb5\x16\xd3CE\x7fZ \xf2\x84\x16KQ\xb0\xe9BX\x8f\xb2\xc4y3^p\xd3\x85\xa4S\"%|ck$:.\xd3\xc0/\xc8\xbb,\xb2-\x0b\x07\xd6-|\x91\xf8A\x18\x9fQ\xe8/s\xdb\xca\xcb\x19\x06~\xd1\xd4>L\xc9\xcc\xa6\x83\xc8:\x83\xc0d)\xcdo\x82\xe4\"\xa6s\x07\x0c\xea\xc1g\xaa\x1d\"\xd6\xe8\xf4+\xda\xe0\xc5\xe8\x81#6\xc0\x81\x0b/C\xd2\xa7\xde\x14\x17\xac'i\xaa\x93\x97V\x91J\xb0\xfeI\xa8\x0d\xcd\x0f\x1c0s9\xb2\xc6\xdfK\x92] \xf8\xab\x9b\xd0\x8bR\xab\xe1\xe5bXj4\xc9\xa3\x89P\xe0\xc0T8\xbceL\x06\xd0x\x89`\xf7\xe1\x03\xf04\x1e\"k\xc7\xe1\xfb0MI\x00YM\x07\xc6 \xfc\x0bk\xe5_ \xc9\xf07\xfd\xf8_\xe0\xc2\xcf\x11\xed\x87\xf3\x90\x04\xbau\xe2x\xe8\xa2\x8b\x18\xba\xe7\xeb\x92bB\x0e\xf2L\xa6\xc8~\xbf\xcb\"\xa5\xac\x0d\xe5\x98\x8dM\xee\xbc\xa0G\x9b\x9d\xa8\xaf\xaf\xdeq\xb0Y3\xd6\xf8\xf0\xc1\xd8\x82\xe2\xfa\xc6K\xed\xb2;\x1d\nlo\xc92)\x08\xfb^M\x81\xab\xd8\x90\xd4\xeb\xbeU}\xa9`)\xe8\xa7\x9d\xd7M\x1c\xec\xc2\x01fb\xb0\x8d\xf3\xbc\xa4\xd5\\\xb8\xa0\x87\xf1@r\x03\xba\x96\x91,\xe9\xa5E\x1c2\xe1\xd8\xde\x19=\xe88\xf0\x8ev\x1c\x8f\x8b\xfd\xde\x93\xab|HC\xf5\xcau\xac\xa0\x99\xb6\xf5\xe1\xae4\xe1\xd8\x1e\xef\xdcwx\xbaM\x03\x95\xd1631\xbb\xed4\xb3s\x03\xacnX\"/C\xb3\xa3J8\x18\xdb;\x9d\xc0\xb0\xb5pq\xd2\x9fb\xb3\xb3\x03\xdc\x83\x1b\x1d\xbe[\xfbp\x7f\xdb\xf1\xe6rL\x94!-\x0e\x9cD{\x9bn7\x89\x9d1\xf3\x07\x1f\xdd\xe7~\xe4c\xeeW>\xbe\xaf\x04\xaf\xc3\xab\xe5i\x12\x0di\xbb\xd7J_\x9d\x8e\xb7\x13\n\x83G\xe9m\xe7\xb2\xe4\x913\xda[\xca\x83\xf4\xee\xb4\x83\xf1\xf2\x19\x8c\xb7\x1d\xef\xcf\x07\x7fk\x96\xb1\xd4\xa1;\xed\xf1\x88\xcc\xa1\xed\x011\x81\xf6\xc3vX\xa1\x94{\x87\xb4\x8d\x13x\xea\xd0\xb6O\xc2\xa2\x82\x94\xe6\xfbs\xfe^\x9d9tg\xdc\xae/2\x87\xb6'\xcc\xb2\x86n\xb5G\xc3R\x86\x8e\xdb\xb5Y\xc6\xd0N\xdc\x87\x0b\xbe\x9a\xed\xb9\x1e\xb0%h\x8f\xf1\x92Wo\xcf\xf5\x90\x8f\xbd]\xff)\x1bL'X\xca{\xb6\xe5\xed\xd7O\x04Bj\xbe~\x0d{\xf0\xb4\x9d$\xf4\x0d\xec\xc1\xfb\xf6\xcb#\xcc\xfb\xd9z\xf9\x12/\x08\x06\xd7\xcd\x92\xe7\xd5\xd5\xd1|\xff\x13\xec\xc1sJ.<\xafQz\xb3\x06\xbd`\x02\xdb:Y\x84A@\xe2\xb6\xca\xff-+-\x927Y\xb8\x0c\x99\xbfM\xb3\xc63\xd4\x03y)g(\x9f\xe7\x07q\xb9d!\x91\x9b\x15_\xd0\x1b\xd2\xb6r\x1c\xfd\x06c\x05\xb3\xabvs\xef\xe4Z\x9dd\xc6\x7fg\xa5I\xba\xa1\xa9\xf0\x0d\xecu\xb4I\xcd\x1a?\xeb\x02\xc2\xbcl\xd6\xfb\x1aW\xf4/\xac\xb1f\xd1\xf7\xb0\x07k_cf\x88\xaf\xa5\x8c/\xad\xbf\xbdy\x18\x07O\x17a\xd4R4|\x0b<\x82odvr\xe6w\xce}X\xdb\x83K\xfb\x0d\xf2fh\xd7\xab&\xd0\x87\xc5\xd8\x82\xba\xe17\xb2\xad\xb0Y*\xc2\x93,\xdf\xd7V\xbav\xbcn\xd0#P\x8aA\xae\x9dv\xddkG\x0eg\xa3\xb1]\x03 !\xbf\xb6\xbfQ\x9b\xd3d\x92\xac\xe2\x9biq\xec\xc2\x9b\xaa=\x1e\x10\x92 \xb7\xf9\x0d\xfd\xf9\x06\x9b\xe9\x04\xc0\xbf\x86 \xbcin\xd9\x0f\xbd|\xbb\xe0\xd9\xdf1\xaf\xf1K\xfbe\x0d\x08&\x1d%fL\xef\xaa'\x9b\xdd\x7f\x07{\xf032\xc5\x0c\xea\x1bP\xeb\x89\x9b\xbb\xb1\x88\x06\x80R4B:\x0b0\xa8\xa5F\x94\xfd\x97\xa6\x19\xfcm`l\x80\xaa\xe1=\xb1I\x7f\xb3\xff^m\xe0\x15\xcb\xe2\x02{p\xc13\xd6\xd1w\xb4$\xb1\xdf\xa1\x91\xc4>\xc6\xd7\xa9\x10\x10f\\\xa5\xfd\xbdby\x85\xa7\xaf\x8e\xa7\x053s\x11\xbf\xf7x\x0e\"\xdc\xb4Xw\x10\xea&)\x17\xb1\x89\x89\x8bT\x90\x0d\x93\xba\xc3\x0f\x1f\x18\xf4\xbdr\xe1\xc0\x1ea6uJ\xa6\xd4\xfd\xd2\xe1\x7f[\xad\x06\xfd\xb6\x86V\xd3b\xfey\x88q\xc8\x95\xd2\xf5\xad\xd6\xbc\xb3\xe0\x1fK\x9e\xe8\xb3\xa0CKXj+\x16e\x97IP\x98\x1fe\xf2\xc8\x81\xbf\xa1\xfe\x1d\xc3\x05&\x18\x06\xa60j\xdf\x8d)7\xfe4\xf88=k\x18\xaf\xe0\xc6\x13\x96\xaaP\xdb\xf3\x1a\xd6\xae\x01\x08A\x83\xe5\xf7\\K(0\x11f\xc1e\xaf\xd9\x05\xa2\xec\xda\x17\x9f\xff\xf9N\xfc\x16%\x0cz\xe8o\xbay\xe4\x18\x0b\xdbv4\xcd)~1d\x8f\x98\xdd\x05]\xff.\\\x0b)\x11\x89\xa9\x9e\x94\xff\xc8\x11{\x82\x87\xcd\x17\xb3\x8a9\x04\x7f#v+dSz7-\x0c\xe70l\xce\xaa\xae\xf73nmi\xdb/M\x81\x0d1\x08\x14=N2\xa2\xef&\xc4\xb0\x18IZ\x87{\x92\x92\xd0w\xf2b\x9c\xf3\x8cj\xa9\xca\xebw\xb3\xe1\xf5\xbb)\xf9\xe6\xbb\x9d)6\"B*\xaf\x13\xe0Y\xdajl\xc0SZ\xfe\x9d](\xcd\x03\xce\xfe\x9a\xbe:\x16\xf8\xc2\xae\x8f\xbc\xb8'\xbe\xad\x0d\xe9\x10\xa9\xab\xd2\x1d]+\xa5|H\xf2}O\xff\xf7-\xdd\xc3N.@\x18\x14I5\xa7T^\x8bXp\\\xf8\xa1\x99\xeeM\xce8h\x15I\xe5\xe3\xdd'\x04)0C\xdf\xfb?\xc8M?\xc5\xa4t_\xb8\x94E\x81=\xf8\x1bF\x90\xdby\xe8\xe0_\x87\xf8\xff\x7fF\xae|\xbc\xc3\xde\xfd\x89\xf1\xe8\xbb\xec\xaf\xbf\xf2\xfc\xc6k\x94\xdf\xdc\xc6e-\xe9\xfc-\x15\xc3`\xb9\xf4kD0\x0b\xfc\xbaWR\xf5\x83\x1d4$2t\xc4\xbe\xedc\xaa;\x1fS\xdd\xf9,[\xda\xcf\xed\xf5f ;\x91\xe8\x16Y\\V\x1d\xe7\xbfPva\xe1\xe7\xcf\xf9\x01p\xc3\xfci\x12\xcf\xfc\xe20\xcd\x88\x1f \x9b#(0\x17\x9d\x85\\n\xbd\xeb2\xd7\x0c\x97\x07\xe8u\xd1\xde\xd3\x958)W\xec\xcc\x91\x7f\xe6\x96q>KR\xda\\.LC-\xd7\xa2\x17\x01a8\xe2/\xf5!!\xe4\x91\x03\x81\xfd\x97)!\xcd\xb4\xe65\x12\"\x98\x8f*\xf0\xf2\"\xc9\xe8\xe5\x12\xf3V\nR7\x13\xd3f\xce\xed\x82L\xe3V;t\x05\x0f\x1bk\xc7Ox7B]\xbf\xfdG%;{Ao\xb5\xf5=\xb47\xdf\x87\x17\xf4TM\xd8?{\xdd\xe4\xea-\x04\xfc\x9e\\}\xd3\xdf\x15Z\xe0\x7f\x87\x16\xf8\xc6\x9c=>0\x1a\xb8\x83\x9b\xa0\x19<-\x8c\xe1\x85ZCA{z\x81t\xdc\x9e\x9c\xba\xc3H\xc6\x9799$\x05\xaa\xb1\x8d|\xda\xf7\xaa\xf0\xc0\x9d\x96\xc2e\x1a\x91!-5\x93\xcd^w\x8eJk\xa3\x19\xc3\xdb\x8dq\x84A\xd4\x07$+\xedZ%\x17\xb0\x0f\x976\xa6\xa5\xfc\xb3}\xc9h\x1d\xe3f\x07d\x1e\xc6D\xa8\xa8'\xf07CqH\xf2 \xfc\xb9Y\xe1\x8c\x14\x92\x8a\xfb\x19\xc9gY\xc8\xd4\n_\x98*\xbe\xf2\x97\xb4\xb1\x7f6\xd5a\xc7 \x9f\xc0_\x1b\xeb\x88\"\x96\xe6b\xdakx\xc5\x1a\x98|q\x11\xbel\xc7<\x16\x8c\xda4.\xa3\xe8\x18c\x99\xfdd\x0b\xba\xd3\xfa\xe5\x9a\xbf\xe9\xae\xbd\xdf1,m}\xc26\xb7\x851\x1d\x17\xac\xef\x0e_\xbfR\x04\x01\xa9\xb4\x0c+\x10?\x9cd#\xc7\x8c\xa3\x18=R\xc5\xe0\xa1,\x05\xa7\xc9\xea\xeb>ib!\xf1\xf0L\xde\x9c \x1a\x1d\xbb`\x9f\xda\x9d\xa4n\x9c\xc4\xffN\xf6\xbf9\xe3\xd5\xecb\x089.\xfaRJ\x87X\x987\xa44;\x06\xf5\x8eK\xfb-\x1c\x0d\x1a\x00\x0e$t\xect\x1a.\xfc\xc4\xb5*\xcf\xbb\xc2\x87\x06XIB\x84\xe9[$\xc6c{g\xd3\x91\x85\x0b.\xbcm\xd4cI\xb6^\xcf1_\xe8\xcb\x1aq\xb3\xbf\xfdb\xe1\x82E\xff\xb1\xf8=;\xe7j\xa6\x1a\x06\xd66\x07\xa9\x00j\xe9xG\xca)\xa2B\xa9\x93\xd8QBaU\xbd\x94\xe0\x073e\xda\xb7\x98\xc5\xe5\xed\x1a\xce(2HV\xa0\xea\xbb\\\x00O\xf1\x11\xed=\xf4\xe6,/\xcb\xe6#(kH\x8d\x1e9\x90W\x16\xe8\x94`/\xa7\x11\x12\xe5HN2\x10V\x1f`Ia\xb8\xda\x8av\x84\xdb\xc2\x9b\x90\x92]\xdd5\xfd\xe5\xda\x13\xa4D\xb3\x10\x83\x03\xd5\x86\x14\x02\x96/\xc28H.P\xc9\\\xfd\xe2BS\x05F\x84}C\xa1\xcdZ\xa0\xb8]v\x8b\xab\xb5\xa3\x83\xa88\x0c\x8akM\xd9H\xe1\x07l\xf2\x18G\\\xe58\xeb\x95n\xe9\x93\xd5T\x04\x88\xca\xda\xaa7\xf9\xbb\x18\"w\xf4Q4\xd1<\xc06\xcf\xbf\xdc\xd4\x14\x0e\x02\x00\xa6K\xb1-?\xbf\x8ag\xcfWR\xc8\x89OY\xfa\x12\xa4\xa5\x07}\xa7\xd6|\x15\xde\xe9UA^\xb0#0\xe4\\F\xdas\x89\xe9\xa5:%\x19\x96\xb4}:\xf9Ro\xd1\xdb\x13\x83/9p\x0f\xb6aC\xe2\xcd\xaf](\xbc\"\xf9\xfa\xaa <3\x9catm\x9e\xfd\xa4\xb0\xe7\xce1|\xf5\x15\x8c\x1e\xc0\x87N\x11\xac\xc3\x88\x17\x8f\xd5\xc5cV\xbc\xab.\xddr\xe8JL\xf3\xf5u\xbc\xa60\xb2\xf2.| \xe3\x9d\x9d\xf6\xfb\x07\x9d\xd7\xe3\x9d\x1d\xf8\x12Z\x89\xa4\xc6<\xc5\xb5\xb8:\xd5\x93\xd1\x0c\x96\xce\xe5\xf1c\xd8\xeev\xd2\xc2\xb6\xa3A\xbd\x8c6\x8dK\xb6\xad_\xb1\xc7\x8fa\xa6\x87wZ\xb0u\xfd\x12v\xb7\xe8\x0bko\xcfB)\xf7\x98\xb7\"\xf6\xcbf\xed\x8cq\x1f\x1e8\xb0\xaemx\xb4)Z\xa6\x80Q\xb5\xcc\xbb\x1aK]Y\xed\xa1\x0b)L7\xdc\xf4\xb5\x82\x7f\x16B\xc7D\x12>Ze\xcc8\x8f@N\x0f\xfb.\x8c\x8b\x07l\x1f\xf7\xe5?&,\x9f\x0b\xdb\x14\xeb\xc9\xd7O\x9f\x1d|\xf3\xa7o\x9f\x7f\xf7\xe7\x17/_\xbd~\xf3\x97\xb7\x87G\xef\xbe\xff\xe1\xaf\x7f\xfbg\xfft\x16\x90\xf9\xd9\"\xfc\xe9}\xb4\x8c\x93\xf4\xefY^\x94\xe7\x17\x97W?o\x8e\xc6[\xdb;\xbb\xf7\x1f<\\\xbfg\xf1h\xdc\x0c\x8f\xf8\x95t\xbe\x84\xaf \x7f\x04\xeb\xeb\xa5\x03\x19K\xc6\xedOK:\xf0\xa9/\x83r\xe9`,c\x95[[\xa4\xc7\xea\x02\xd8\xba\x84U\x01\xff\x01\xb6)\x1a\x13\x8c6E\x9e\\\x16\xf8\xc1vn\xc2\x84!f:^9mfw\x1df:\x8c_g\x8cB\xf7S9:z\xc1v \xa6\xff\xac\xef\xc1\x96\x83\x00c\x13\xba\x13\x14\xe5P\xec9\xda\xbd?\x1a\xed>\xd8d>\xf6\xd3\x92\x9e-\x06\xe9\x14\\w\xc6\xbc\x84\xa1\x0fV>>\xa6\xac\xb9\x80|;\xc4\x8cZ\x08\xff\x0f$\x98\x0f\xf1\xcd\xb8\xfdfWz\xb1\xbb\x05_B\xd8\xe6\xa9*\x8a\xa6{\x14\xaa_\xc9\xd4\xda\xb0d\x08\xdaD\x08\xda\x1dS\xd0\xb2NTE[JzC^\xcd\xc2\xcb\x88\x1f(T\x81<(\x8a\x02\x0cCW\x10\xea\x0f\xe0\x8f\x90PZ\x80b\x06\x85`\x94.\xfc\x88\xaek\xe9\xa8k\xa0\xbf>\xaeY\xb7\x8c^\xcb\x1b\xf7\xbb\xef\xd1~\x06\xf6\xb1\xe3\x11LT\x01\x0bR^e\x83\x96+\x9a\x0e\x10QR2a\xde\"w\xb8\xc3\xfe\xfa\x1e\xa4\x0c\xc3\x04\xf0%\x9f\xc3\xc6\x8cM\x02\x02x\xfcx\x0f6f\x94rX\xa7'\x18f\x18\xd8\x14\xeb\x8fwv\xe1\x8f\x10\"\xc2d\x1d\xb8 \xda\x9b\xc1\xc6\x1e\xcc_\xf9\xaf\xb8\x8c\xa7\xc0\xb6\x18x\xec\x83\x8dY\x04D1o\x92!\xef\x19j\xe9}\xd1\xd6R5\xcf?\x85\x0dX\x1c\xc3\x87=\x18\x8d\xe9\xc1:o\xddp7b\x8a\xb9\x10\xa4)\x9c\xb6\x0b\x17\xac\xda\xac\xb5#B\xe5\x96S\xb2\xb1\xab4bAj^)\xa3G$\xbcd\xac\x8c+\x81%[\xaa\xb8\x12X\xa2\x8a*A\x0b:_\xe4\xbc\xa0\x13l\x82\x99\x9a\x8e\xef\xb7U\xaf\xcc\xd6\xb4mf9\xc7ff\xad\xb7)o\\\x11\xe6\x82\xd9\x9a\xee\xec\xb6\x03]/\xaaO\x1e\xb6?\xe1\xf6\xa6\xe3v\xdfK1\xb7\xce\xac\x99\xc5\xa9&\xa0\xc3\xd5\xa7\x0f\xe8p:D\x1a&%\x1bm\x82\xca\x89IU_M\x8b(UA\x92t\x9e\xb15J\xe5{\xed\n\xb8\xd6\x88\x0d\xb4y\xdc\xd5\xcb\xab\x82\x7f\xb4\xdc\xc9\x84a\x8d\x8b\x05i\xbb@-p\xcb\xcd^\xc1\xbd\xce\xc5+\xb8\xcd\x9a\xbc\xe3L\xde\xc7\xd0\xf1@\xd6\xd7\xcb\x92\xa4x\x1eS\xd4\xd1S\x11\xe7\xfdF\xccN\xe1\xd4\x0c]M\x99xN\x932\x0e\x0e\xc5\xc45\x95\x8a$\x89N\x93K\x8d\xc34bz4\x00\xa8\\\x18\xe9\x1d\x81\x16\x01\xd5\x1b\xef4\x8c\x03\x1e\xf0\x87\x95\xa1\x82\x99\xdd<{p\xeaVn\xd63\x14r|w\xc8\xf6\x9ayUr\xe1[\xb3\x93\xfe\xb0\x85\xe2\xa9\x18s\xda\xfe\x99\xc7\xf6\xf9hQ\xc6\xef_\x86A\x10\x91\x0b?#\x8e\x1d;\x86\xc0i \x06\xf2\x12\xe1FNN\xde\x1e<{\xf7\xd7\x93g\x07\xdf\x1f\xbd~\xfd\xe2\xf0\xe4\xe0\xafG\x07\xaf\x0e\x9f\xbf~u\xf2\xf4\xf5\xcb7\xaf\x0f\x0fNNP\x87\xc7\xbcGsE$\x1c\x90\xc8\xc6M\x97\xd6D=\xe9!\xaa\xdd\xf9\x84\x12;b\xfa\x9ez\x98\\\xffS\xa5*wTf$6?\xaf\x8eXk\x0cO\xc2\xbdK\xd1\x1a\x05\xdfVN\xb5\xf8\x17?\x1e:\xadRk\xbce}$\x89\x0b\xd3\xee\xba\xbf'W\x13\xb0\xe8f\xd1\x19)\xdc\xa2\xf9\x05gTCC\xcb\xc2\x04a\xa6;\xdf\xe6\x90U\xe8\x81\x8dFLx\xc0hz}l\xd7\xd4\xa9\x07txp\xc4t\xb0\xf2\x0b=\xb0\xc9y\x80\x81\xd8&\xd0\x16\x0f\xe5}\x18t\x879\xa37\x1cJ\x91b\xc09\xfe\x1a\xc5JNC\xdb\xa8\x06KU\x9b\xdf\x94\xf1\xac\xf1-\xb1\x0b4\xa0\xd5y\xf9\xaa\x1aQ\x8c\xc0[\xfai-:\xd7jW\xe5\xa7\x1e@\xc7\xde\xb5\xfd\\;^F\x82rF\xec\x0b4\xa35\x0f\x957\xacA\xa0\xc0t4mTg\xeb\x02\x00^p\xfc\xc5qU\x8c,\x01\xb7\x06m\x1cH\x85\xfe\x03\x9a\xd7r\x1f\x00\x08\xfcF\x9b\xd6O\xf1\x9c\x07\x17U\xc0\xedX\x0b\xb7\xe3\xe6\xfd=>\xeeq\x0d\x07Nd&\xde\xc2\xcf_\xa0\xb7\xb6yD(T\xd0W\x19\n\xd3\xa8\x07T\xa9\xdf\x0b\xcf\x9f\x17${\xc1\x9d\xa7\x91\x83X\xdbt\xe1\xc0\x96J\x1cY3\x1f\x9bB:\x9a\xcf\x84\xdc\x0c?\x1e}\x1e\x12\xd52M\x14\xd9\x9f\xc5c\x82\xdc\xbb=`\xcd\x99dB\x18\xd1\x7f*\x07\xcd\x03\x00TY\x80\xeb\"\xfd4\x85\x95\x18\xb0z\xd3\xc5\xbb\xa1\xad\xf0\x18T\xba\xe3\xd13\x02\xceG\x16\x82K\xe2o\x06u\xfe|9\x81\xb9XZ}\xb5\xb7\xc4\x9f\x15\x93:H\xa2\x1as\nn\x8cqi\x12\xcf \x18\xc6\xe5\x96p\xce\xa7u{p\x92\x07\xa9\x8bX5xdw9\xb0\x01\xc2\x82!c\x87\xce\xf8\xbbo\x0c3\xcaW\x99\x91\x96\xb7Q\x0c\x14\xf6\x14q\xf7\x06\x0f\xab\x894\x07\x0c\xcdxE2b\xc4p\xef {(b`\x0bLmW\x97\x18\x9f\x99,.a\xbea\x8c|JN\x7fz\xe9\xa7\x0e\xbdA\xfa\x97\ndZ\x89\xf1\x18\x99fW\xb9\x87V+\xd6\x0f\xa9X\x93\x9a8\x1bB\xe6\xf7RH<\xc6-F\x82&\xd3\xf8x\x85H\xe0\x82\x10Y\x91\x0c\xe9J\xf8br\x013\xef\xa5\x9f\x9a\x19\x05\xe0\x84\x89\xcc\x15\xf7s\x93k\x99)\xc2\xb0\xfc\x08\x93\x80lZx\x94\x1d\x18\xd0x/\xa3\x0d\x12'u`\xc7\x8e\xc9_N~\xf8\x88\xab D \x97\x0c'\xc6/\xf5\xac(\xa8\xc4\xbe\xed\x07aO\x0d\x95\xc8\x0f\xbbm\xa8,\xe4\x08X\x9b.\x04\xde,Y\x9e\x86\xb18M\xb9\xc3r\xea\x9f\xf6&\xc97\xa3\xdf\xa3\xabt\x88L\xa8W\nC\xa6\x9b\xc7^\x91\xbcKS\x92=\xf5sb\xa3\x11P\x15+\xbeW\xec\x86\xa7\x9e\xcd\xcd\xb1\xf5H\xa2\x1aP\xacH\xe7!?\xe7<\xb6y\xac\xcc\xf8-\x1eTT;\xf28\x92&}\x9c\xc1:\xc5u\xa1\x9aU\xba\xcd\xa5L\xc9\x13A+\x0f\xd8\x80!\xb72\xdfN\xdb\xca\xab\x86o7@N\xef\xdfbx\x02\x915\xc7\xe7\xf3v\x07\x82\x05^\x06d\xc5\xcb\xa0\x03T\xc4`\xd6\xa2z\x1a\x02\x06\x8a^\x1c\x13\xa0\x14\x9dL\xe0\xf2\xa3a\xb5o ?j\xeel\xc0n\xf5\x9ef\xba]\xc3\x98\xd1\x06_\xa8\xf2W\x07\xdd\x86\xc6\xcd\xfd\xe8\xbfpi\xaf*\xac0\x8d\xeb\x0c\x0e\x1b\xf7\x9dc\xef\"\xf3S>\xa4\xdeK:\xe3\xf8U\x03h\x03\x04\xbe\xe2\x0e\xca\xa6q\xcf\xb5\xc6\xbbD\xe3K\x14\x10 A\x91\x9d0\x1f\x17\xb4UL\x8e\x1d\n]m\x9ad\xc8P@Z\xaa\xde\xa3\xd9~\xc4\xbd\x88\x87\xa3!\xaci\xa9:\x14Q\xc4t\x8fB\xbf\xd8~\x90\x90\x90\xcfY\xe6\xc8\x16\x89\x92\x87\xb2\xb4\xad\x10\x13\x12\xe4P$\x954\xaa\x96\xd2\x16\x0b\xbf\xe0\xafs\xf0\xb1\x91\xaa\xcc\x0e \x14\x0b\x02\x17\xec\xe4\x00CD\x8e\x0e\x11\xc9\x0f\xef\xe8\xc0\xcez$\xdd<\xf0\xe67\xbcO)\x88\x08\xbd\xafM$\x82\xb6\xf8n\xf1\xc4*\xd7\x8e Q\n\xa2\xce\x8c,\xb26\xb2\xa8%D\xfd\x01\x0e\x9a'S\xce\xa5\xa3J\xe7%?\xe2TN3 9<4)\x16A\xb87)qL\xc2\xd0J5\xf8^\xc4\x12v\x10K\xb1\xc2\xf0A\x16\xcaO\xb3a\x88\xc5\xef\"\x16\x9f!\x16\xb4x\xf5\x99M\xaa\x82\xd9\xe9\x1d\nH\x14\xd5\xca\x88\xa5\xb2\xbe\x0d\x15\x1c\x0d3Mb\x83\x0d\x1dn#\xcdlr\xc3GP\xae\xaf;h\x0e\xdd\xe0M\xca\x9e\xe5\x10\x8f@\xf1\xc8\xcf\x990\xda\x94\xcb\x8b\x9e\xc7v\xe2\x1cS\x8e{\xe6\x17\xb6\xaf \xad\xdb\xcfM\x10\\hBp\x02\xc0~?\x0c\x17\xf6\xa1\xb7\xc2\x80\xde\xd4<\x0e\x08\xf4\xa6a\x81n\x87\xdeP\xca7\x08\x99\x0d\x90\x94fM\x0b\x17\x15.X]^\xd0\x14\x08\x10\njL\xec\xad^\x0e\xf7v\xe2\xbe\xa6|\xfd\x1fg]\x06#\x16\xc1m\xb3C\xabr\x11\x15\xcf\xf5G\\\xe3o\xe2\x01K{c\x99\xe5\xc4+\x93\xc7z\xeaV\x83\x92\xaa\xb05<\xb6\xf9\xbe~\xf4\xd0\x96,\x8b\xb2[m\xce\x9d\xd2jJz\xaa\xd2\x98T\x14\x99\xb3\xa2\x84EEa\xf5RFz6\xb0\x97\xc1\xe1-\xf4\x1e/\xf9ix\x84u\xc9\x8f\xb0\"?2\xa7\x8a\xe6\xe4\xc3W\x90=\x02\x9f\x92\x1f\xe1\xd4o\x92\x1f\xfe\x00\xf2\xe3\x9c\xa7C=\xb0cAl`*$\x0d\xa9\x11\x1a\x93W\xf2\x87O^i\\\x81\x89(m\xd6c\xe9\xd8\x85\xcd\xa2\xca\x1b\xdb4X\xd7|\x14q\xc5] )\x08\xc6\xe6\xfa\xf0\xa1\xa3\xf1\x13jt\xf5R\xcah\xca\xab\x85[\xed\xc8\x1d\xe2Q\x9f\x18\x99\x84\x1f\x80nl4(<\x0d\xc5\xbc\x9ff\xc4\xa7\x07\xcd\xa9\x10\x17\x90\xc1\xa6 \xd2\xc6\xd7\xce\x8b\x85\x99\xcd\xe8k\x1a\xe4\xeb\xb4\xe8\xb3\xe1\x82\x017\x9b\xfc\x08\xe9\x1f\x05\xfd~\xf8\xd6\xbb\xff\xb7\x1f\x94(\xdeB*!\"\x06\x0cZ\x1e\xe0\x1d\x0e\xabI\x1f\xba5\x138\xf7^\x1d\xfcpr\xf4\xed\xdb\xd7?\xbc:9x\xfb\xb6_\x03#\x1e\xcc\x80\xa0\xcf\x92\xa5zR\xff*J\xfc\x80\xa5\xf8Y\xc8j\x84AM\x98\xb5\x1bX\x03\xe6a\xecG\xd1\xd0-\x12@\xd5[\xd9\xdc\xb5\xc9\x02\xb0p\xb42\xd7[b\xaa\x97~\xca(\xe8\xe4M\x96\xa4C\x90\xd5\x10\xf9\xb7\x11\xcf\xf4\xb6\x04M\xac\xd2\xb2\xe3!\x03H\x9a\xdb.\xc93\x8e^\x87\xaf\xca \x92q\xd8\xb2\x0c!\xee\xec\xa6\x87\x02\x8a\xe5\x0dVL\xc8\x81\xd5VG:P\xea[\xb6c\xfam\xf5\xea\xdaV:\xaa\\hCG\xddZ\xc5\xab2\x02-\xd4\x0d\x9b\xac\xa2\x1b\x0d\x8fT\xde!\x0dA\x860\x03\x95\xb4\"\x83\xea\xcbF\x9a\xcd\xea\x05\n\xd8j\x96\x04)\x9a\xd6\xd5\xd6\xaa2\x80Z\x15T*\x91\xc8r\xe6\x1a$\x91\xf0*\xf9\x1a\x067\xe8H\xe9\xf7\xc1n}\x89&\xb6\x9c\x8c\x9b\xc6\x14\x18x\xf4\xea\xf6`\xa7\xd91\x86\x95\xc1yu\x1b\x99&.\xc4\xc7\xc6\xaf\x9bp\xa7\xd0\x19\xb7\xbe\x91\x13\xfdk\x9a\xd5\xba\xee\xcb\x8c}w[\xdb\xbb\xaa\x8a\xa1Y;\xddC\x18\x9b]B\x98\xa261$\xe5ow\x18V\xa9\xa3\x1aoe\xd5\x8f6\xc2.\xc8\xb2\xd5a\xca\xa2j.%\x9d\x8b\xdfG6\x9c\xf3,K~\xaf\xa8\xb2 `9\x93\xd6\xd2O\xa7\xf9\xb1+$\x9fye\xb1\xde\xd8\x96\xee\x9bir\xac|)O\xb2\xb7\x02\xed\x13\xe3z\xf4Ub\xf3\x13\xb0\xdfW\xdd LU_\xf2}\x88W\x8d\xf4I#2\xa1*J\xc4\x81>Z\xc6\xaa\x9e$*\x9c\xe9xQr\x86\x02]\x850$\x96\x93\xa9\xef1Ij\xcb\xf7\xc3D\xec\x0b'F#\xb1\xa0'\xa3\xa5\xb0\x98*N8\xab8\xe1B\x84\x12\x7f\x04 |\x05\xc5#H('\x9cQ\xf8\x92W@wb\x05\x82GcpN\xa7\x13\x17\xa6\xf4\xba\xaf\x00&SY\xae\x0c\x8d\xe5\x85\x11C\x9a\x19\xc3\x08\xcfE\xd7\x036\xd7\x7f\xe8\xfe\x92\x13\x8d\x9f\xe0\xdb\xdeX];[c\x85\x17\xb0\x9c\x14\xa9.U\x07\xc8S{\xca \x9dE\xdbI\x99\xb4\xa3\xca_\x0f\x19g=\xae\xf1\xa64\xdc\xcc\xce0\xcce\xc6b\x86\xb2|7\xda\xb8\xa1\xedX\x9e\x98+\xc5\x9b\xd7#q\x86\x0c\x85.\xd9\xb6)\x87\x94\x9f\xe7\xe1Y<\xa4\xa9\xfeY\xe9'\xc3z\x99`\"\x98-g\xc59\x98\x93\x0c\xc9\xa7\xf2Z\xbd\xfb\xd9\xed{\xa1\xeb\xd8\xf6\x9ef\xb1\x055\xc1\x1a\xb7\xd4\xb9\x8cv\xb6\xdaYyJ\xcc\x1aP\\$O\xf8\x01\x7f\x93$\x11i\xa5{\xc3Yx\xf3\xa4\xccL\xb5\"\xd8\x83{?\xde[\xbfw\xa6\"\x86gZ\xbfi\xdb\xb2`\x1d\xd0\"\x13MG\xed\xc8\x05\xeb\x8b/\xefYf\x94>W\xca>Q\xd0C\xeb\xf0\xfc\x1c\xf4\xcfY\x12\x17\xe4\xb2`1<\xf9\x9b2\xa6\x7fo\x1a{Hu\xe7Ul\x0b\xc1\x9e\xba\x18_\xd0\x9e\xd8m\x0b\xd33_\x99\x84\x19\x0f\xb1\x81\xac\xaf\x9bg\x1aHaI\x94\xf3\xcdH\xce\xf0\x98\x98\xf1{r\xf5&#\xf3\xf0R\x9a3_\x94\xb8\xb3(\xd9J\x8b\xb2\xe8_\x146\x9c\xee\xb2\xf8XZ\x8d\xad[\xa14\xaci.\xafi\xb7\x98\x02_\xc9\xd66o\xadms\x03\x9a\xc4WD\xa9\xfbs\nq\x19\xaeo\xe8\x15\x0b\xbfx\xcb\xd4\xac\x02\xd8)\x05\xcf\x13\x9e\x02\xcb\xe1\x98xa\xfe\xbd\x1f\x85\xc1ADh\x0d\xda\x0e}\x1f1\xc6 Jb\xf2$\x0e\xde2x\xfe3\xb9\xa2\x1d\xf8\xb0\x0e\xf6ZD\xe7\xcf\xe2\x9e MF\xff\xa2T\x01{\xbf\x0f\x96\x05\x13\x98\xd9\xf8\xa7\x03\xeb`\xdd\xb3\x1c\x0cU\xe8\xb8\"\xf0n\xe4\x98\xc1\xe5\xdc\xee\x0f\xcf\x04{`Y\xcd\x85\x113dq\xb9h\x8d\x19e\xc0\xd9\x10\xba\x1c\x03\xdd\xab\x802\xd2\x88\n\x02\xbb\xc0([\xd8a\xb3\xb2O\x87\xb3p\xa1\xa4\\\x92\x97\x91\x88\xf89\xb1K\xf3\x1c\x96=We\xe3\xce\xaf\xef\xf4\xb9\x14P7 \"\x95\x81I\xcd\xd88\x1a(\xaco\x9d\x8e\xc6\xcb\xce\x01\xa1\x9b\xe2\x07\x01]\x830>;J\xec\xb9\x98\xe8\x8d\x06R\x1dd\xa9W\xf9,K\xaf\xefp\xcc\x81\x0by\x8b\xae9\xeb\xc8>\xe7Iv\xe0\xcf\x16\x93^b\x06\x84-7\xb3\xb5\x96\xa2\xac+\xec\xc5\xabk\xb4 I*\xb7f\x84\xa3\x94\x85\x84\x9aWp\xd4\x8e\xc3\xdc\xc4\x0cK?\xfdH\x03\x9e*\xa8`\xfe\x15\x9e\xbf\xcc\x15\xbb\xc0\x9c\x8f\x8diJ\x96~\xfa<.\x92\x1f\xc2b\xf1g\xb1\xdb\x98?5\xf6\xa3 \x9c7+\xe3\x8e\x0e\xd0\x00\xf2\xd1\xe0\xb2-\xd9h\x8ckU$\x88\x12\xfb$y\x82\x95\xe8[\x80B,\x80\x1a\xa5vRg\xd5\xf0\xa9\xa6\xa2\xce\xf0\xed-\xa9\xa8\xd1f\x9b.\xc2\xc0\x7f\xb1\xfd\xc0\xe9\xb34\x16)U<\x91R\x85B+g\xa3\x86H<\x9b\xdf\xa5I\xda\xa3\x83b\xa7\x17\xfdjY(\x16Epr\xdd\x06\xc4\xe4\x02\xbf\xef$gP\xd0\x8a\xe6Y7R\x85\xd1&1)\x8fm\x8dw0\xc7\x85\x84\xdb*\x1fN\xc5\xfaPv\x92\x16\xa5I\x12\x1d\x86?\xd7n\x9d\xcd5\xa1\x97\x9b9\x9d\x04\xa5 \x92.\x01\xdb\x1d\xb7\x8c\xdf\x06\x9c\x15\x90\xc5`\xc6m\x89\x1bc\xe61%\xe3\x1a{\x01g\xf0}\xfa\xb6\x9a/K\xc7T\xfd\xb9\x07#L\xc6$\xb0\x18\xec\xd1\xbbS\x91\x9bIAZ\xc6\xa4I\x83O\xda\x0bB\x9f\x0e=?p\x0dn\x02\xe4 \xad\xddJ\x80\x0e*`\x8fyl~\xd5r\x80\x12\xe6A\x05\xf7\x9dT\x15\xa0^\xceb\x91\x91\xce\x82\x0e\xb90\xe0\x96\xab\x95\xdd\xc9je\xae\xf0\xcb\xeb\\1\xe2\x19\xbe`\xcax\x1e\x8a5\xeb\xf2\x81\xdd%3\x98\x91\xdcf\xd5\x92;Y\xb5\xa4Z5FM\xa8\x9d\xc0VZ\xb8NB\x88n\x0b\x9a{\x8d\x99k|\xac{m\x9b\xa5Z\x1e\xef\xdeW\xc5\xa2\x8b\xed\x9d\xadv\"]\xbf\xbe\x10c{g\xbb\x13^\xaed\xe5\x0f\x1d\x17,\xaf\x9d\xc6\x95N\xc8\x9aX\x9ax\xc5\n\xc4#\x08-\x0c \xd2\xcdx\x80\xef\x05cB8\x8b\xe4{$\x9f\xf9)\xb1 c\x92&\x18Z\x9e\xe5Q\xb0\xb7v\xdb\xd22\xb8\x990\xae\xa2\x06y\xdc\xccj\"\x84\xc7w\x9a\xb90\xd7\x11H\xa9\x8bq\xf2\x84\xb9F\x1761_I#05\x86\x91\xfd\x12\xacSz\xa2\xfcX\xbc\x12YP\x90|sk\x07F\xbcd,\x16\xab\xd9\xc27X\xd7\x8a\xcb\xe5)\xc9\xe47\xf5\xaa\xf2.\n\xef\x8b/\xf8\xc8\xd0\x15\xb2\"wg\x94{)\\\xca\x83\xb2\x00\xcd\xfbP\xc2: \x05\xb2\x89L\xb0\xe3\xc2HM\x13/0\xc6\xa5\xf2\xc8\x9c#\xb3)59\x81\x18\xd6A\xa1y\xa1\xab\xd2\xe4\xcf\x0b\x8d\x06\xa1\x92j/\x99\xc4zII\x8c*\xbc\xf6r}\xdd\x81\x05\xac\xef\x01\xb1S\xba\x0f\xd3\xe5\xb1\x0b\xe78\x97\xd4\x85\xa5\xc3w\xaf;\x02Ml[\x90\xd8\xa2P\x99\x8d\x10\xf8\xf0\xcf\xfaP\xd8\x95\x8b\xd1\x04\xcf8m\xd7\x13Z\xe6\x0c\xc1\xa0\xf0H\\d!\xe91s\xa9\x16\xe5\x84-\xca\x9a}\x05{p\xea\xc5\xe4\xb2\xb0\x1d\xc7\x0b\x12L\x1d&-\xcc\x15K;#\xad\xcd\xc9\xfa\xba~u\xc4CW\xa9\x7f$\xda\x01\xe8\x17H\x91i\xd2\x8e\xe1\xae\xcdSU(\x92P\xdd\xc1\xca4\xc7\xca\x0e\xc2P\x0e_\x0d\xc6\xd6\x9e5\x01koS\x03\xc1\xd6\x04\x8b\xc7V\x17J\xb4\xf2\x02\xeb\x0b\n\x93\x1d5\xc0\xbd\xe9\xde\xe4\xf8\xdeY\x1fc.5TL\xc9q\xb7_#GY\xc6w\xb3(\x9b8m\xdd\xa2\xec\x8di\xf1d\x95Ea\xcba[\x1e;\xccd\xba\x89\x1az\xbaV\xeco\xd4D\x13//O\x19\x15`\x8f\xd1\x97Pz1r\x1ci5\xed\xbd\xcd\x0f{c\xe7\xee\x17\xb4\x86W\xf5\xd9\xb9\x13\xfd\xd7\xfd]\x87\xc7\xe8\xfc\xc6\x9f\x15Iv\xd5=\xc5\n)\xc0\x84\xa2H\xbfM\xa5b\xd1\xe9i\xc6JOO3e\x85 \xc8H\x9e\xb3:\xec\xb7\xb2ZFx/\x19Qw\x94\x15\xe1,\"\xbc\x0e\xfeVV\xcb\xc3\x80W\xa2\xbf\x94U\xca LX\x15\xfaKU\xe5\x14\x8bO\x95E~\xce\xda\xa7?\x94\x15\x82\x90\x95\x07\xa1\xba8\xe1\xc5\xea\x9e\xc33V\x1c\x9e)\x8b\xa3d\xf6\xfe\xefeR\xf01T\x7f*+'\xc1\x15\xab\x96\x04W\xca\nl\xeb\xd4\x1bwZ\x16E\x12\xb3\n\xf8SUi\xe6\xc7\xe7>\xdb\\\xf6S])\xa5\xe0\xcak\xe1oe\xb5\x90\xcf\x8a\xfePVH\xf8\xd6\xd2\x1f\xea\n\x11/\x8f4\xc5gYR\xa6\xa2\x0e\xfe\xa1\xaa\x18\xf8\x05\x03F\xfaCW!\n\xf3\xa2\xaaD\xffPV\x0cX\x95@YH\xd8p\x03\xa2\x1cn@\n?\x8cr^\x05\x7f+\xab\xcd\xd9\xca\x06s\xe5\xaa\x06\xa1\x1f%\x0c\xa6\xd8Ou\xa5s^\xe3\\Y\xcc\xc7\xa9\x1e&_\x05\xe5\xfc\xc9\x12\x0b\xc9R]xJ\x02^~J\x94K4\x0fI\x14`\xd2\xe7\xcc\xb6\xc4\x1f\xea\x8ag2\x98\xd5\x7fj*\x97\x19\x11\x15\xcbL L\xf3$\xc1\\\xb5\xff\x1f{o\xda\x1d7\x92$\x08\xbe\xdd\x8f\xf5+\x9c\xf1\xaa% \x03\x0c1H\x89\x94B\xa2\xd8J%\xb3[\xdd\x99\x92FRVMw0\x8a Fx0PB\x00Q8xdQ\xef\xf5\xcc\xec\xdc\xf7\xee\\=\xf7\xd9\xb3;\xf7\xb1\xc7\xec\xce\xf4\xf4\x87\xce\xfc#\xf3\x07\xf6/\xecs3w\xc0\x017\x07\x10$\x95U\xbbo\xf1\x81D\xf8\x05wssss3s3Q\x08^\xe9B\xc9R\x16I\xc81.\x86\x90\xbd\x18\x92\x99\xdb\x98\xb9Mf\xee`\xe6\x0e\x99y\x1f3\xef\x93\x99\x0f0\xf3\x01\x99\xb9\x8b\x99\xbbd&\xf7qB\xc4\x8b\xad\x80\x04\n\xbe\x92\x85\xcaU\xb6\xb0\xae\xb1\x85l\x85n![\"\xca\x89\x17\xaa\x00\x92X\x92\xc0\x06\xf3\xc4_\xe2\xe4\xe2+Yh\x89K\"X\x92\xeb!\x88V9\xe2\x1c\xbc\xd1ERY\x80\\\x95\xefO\x10\x90\xefOH8\xbe\xe7\x97\xa7\x1cQ\x15_\xa9B\xa1\x7f\")\x04\xbc\x91E\xf8)\x8f\xf0K\xf8J\x16Bh\x85$\xb8\xc2 z/\xb3\xa3\xf7T\x81\xa5\x1f`G\xc5\x0b]`%\xf3\xc9\x89^\xfa\xc9{\x99\x9f\xd0\x1f\xe0Q\x8e\x05x\x94\xdb\n\x04\x99$%\xea\x07]P\xd2m\xf1b) \xb1\x17\xde\xa8\"\x91\x8f\xa40\xf2IR\x18\xc5\x18M\x19\xcb\xc8\x1fTA<0B1y\xac\xa5\n\xe1\xf4\xd2\xdbU\xbc\xca\xca\x85\xa4~X\n*\xba\x17[i^\x9cg\n\xa7\xf1\x95*\x84\xdf\"?\xb2\xf2\x13\x1fg\x00\xde\xc8\"\xc14StU\xbe\x93\xc5T\x11[v|Zp\x8c\xea\x07U\xf0gP\xe2gTV\x82\x03I\xc8\x91$\x08\x85\x84\x84@\x92\x9f \xcf$^\xa8\x02\xd8/\xb2C\xa9\xbf\xc4\xef\x8a\x17\xb2@\x89:v\xc4I\xf9\xb4\x98N\xf9N\x17\x0b\x15~\xe1+Yh\xe9\x87\x88b\xf0F\x16\x89\xf3d\x8a\x13\x82\xafd\xa1\x95/;\xb4\xf2\xe9\xdedI\x1c!I\xc5W\xba\xd0\xa5d\xe0\xe1\x8d,\x92#\xeb\x9d\xe6$\xf3\x9d\xe6\xcb\xa5\x9f\\\xca\"\xf0N\x17\x93\xf3@\xaf\x97\xcc?\x91\xfd\xc80R,Q\xa4\xe0\x9d3\x1b\xf3\x9c!\xd9\xcdH\x92\x9b\xf1\x8b\xac8\xd2\xa8\x1fdA\xc1[`)\xf1F\x16Y`\xfe\x82\xceT[vf\xdb\xb3\xb3@n\x87\xe2\x85.\x90)x\x887\xb2\x08R\xcd\x8c$\x99Y\xe2O\xdf\xcb|\x7fJ\xd2x$\xf0$u\xcf\x11As\x12;\xcf|\xfc\xf0\x99O~\xf9,\x98qW\xfc\xfa\x9c$\x11<\x0c\x83\x95<@\xcaw\xaa\x18\xae$\x9a5Y\xfa\xa7\x92\xbb\x11oT\x910\x88\xb0\x84x\xb1\x15\xf0\x93_K\xfcY\xc0\xa3\xac(Z&Q\x95\x96~\xaa\xf6\xf1\x94\x9c\xe3\x95\x82\xd0\xca\x02\x9d\x95\x9fe<\x89T\x19\xf1N\x16\x8b\xc3\xcbSI\x00\xe5\xbb\xadX1R\xf5\x83*(\xc6\xe4\x87\x95\xd1V\x93\xc8J\x8a\xb8&6\xd2\x9a\xc5\x92\xc8d1M\xec\xcf$=<#\xe7Q\x10\x85\x82:\x90\x05\n\xa2\x9b!\xd5\xad\x94\xb0\xc8\x88P\x05{\x0b2\xa2\xaa]f\xb5w2\x1a\xfb\xae\x1e|\xac\xd2 eMv\xc3~\x18\xc6\xd7\xf8\xe1\xba\xe95j`)\xfdk\xe4\x0c\xeb\xe1\xb5r\xd9\xf7zq\xb4\xa8\x7fp\xff\xbeeL\x8df\x1f\xcal\xe3&\xf2s&\x8doi\x19\xba\xfa\xcaT\x94x\xf2\xc4\x8f\xe2\xe8r\x19\xe7\xe9\xd3\xa7\x84\xa8tn\x95\xaf\xfah\x99v\xe6\xf4\xe0\x8dB;\x06\x82#\xc1\x98\x9e9\x85\x12\xd5RN\x0c\x17\xca\x15\xe3\xb6\x14Dm*\x14\x95\x8aUKA\xc55\x9f5q\xcd\x0c\x19\x8e@0\x1cg\x8eR\xde\xda\n\x02\xd0\xb1 \xbc\xda\n\xfa\xd1\xe5\x88-\x9cD7\xb3{ \xdab;(_\xcd\xdb\xe4\xdd\xeaQ\x9a\x9c\xaa\x7f\x1fk|\xcc\xfaS\xd3wh\xb7\x9a\\\xdd\x94b\xe6\xf4\xd4U\x13\xf6u\x8f\xf5!8j\xefk\x16\xcf\xcbx]\x98\x91`\xc6\xc2OY \x03\x16\x8b\x9a\xef.W\x9cEq\xe6\x83\x8a>\x88\xd2`\xc6\xd5P\x07m~\xb0\xce\xe4\xbd\xc0\xac\xd5\x99#\xdcn\xad;[k\x83\x01\x93\x9f\x00+F\xc7\xef\xee\xf4CBF\x05f\x16\xc3\x8f\xc5\xf0\xeb \x12 \xc5\xb4\x14\xd3\xd2|\xb5\n\x03>cY\xacC\xcdc\xfcb\xc5\xa7\x19\x9f1?B\xe8\x0c\x08g\xb1\xfa\xd3|Q\xbfP8\x87\xa8p\x0e\xd9\x13-\xc8u\xd8\xefw\x05\x0d\xdc\xd6p|\x8f\x85\x05f\x89\x1e\x8fE\xdfC\xf16\xe9y,\xef\x0091AS\xddf\x11.\xe5\x95\x16\x0e7\x18,ey^\x7fl>T\xe8\xa5\xc8q\x93\xea\xe0Q\x80\xdd|%\xae\x89\xe4|\x0d\xc4\xce?>b\xe7\x9d\x11\x9b\xa5At\x1ar\x8c\xbf \xd9\x80\x9ba\xf9M&\xde\x16^Ja\xe8\xf7J\x887\x1cp\xba\xa6\xad\x0e\xdey\x8e\xf1\xeeN\xe4/\xc1\x98\x95\xb8\x9fC=y\xab}\xb1\xedA\x1c\x1cL\xe3\xa8\xb8;qu\xc5\xaa)\xd0\x9bri\xb7c\x9fz\x94\xd1\x99\xd1X\xa7\x16>\x00\x14\x7f)\x90]\xcd\xa4\xa8\x0e%|(\xf1\x8bCw\x0b\x17\x05\xfa\xafk\x12\xb9\xc6\xbbL\xf5\x07\xd0f\xe9\xf0q6q\xeb\x0c\x86>\x01I9\x01\xb1\x05\xd8\x91IY\x80\xa4\xbc\x8cg\xbc\x95\xa3\xb8 \x0cm$\x03\xf9\xca\xef\x95`\xfc\xc2875\xd6V@\xeb\xbbZ;M\xea\xc6\x81UL\xba6*\xf1\xec\xd7_\xcb\xebpd\xf8\xcd\xd61k\\\x17\xf8\xa5h\x1d\xb6\x18\x90?X\xf8\xe9\xab\xf3\xa8\xb8[\x1ev\"\xfd\xac\x99A\x1b\x00\x83\xd6\x8d5c7e\xcf\xd8/\x80t\xc5\xd1\x1a[4q:\xd0<\xe5\x18\x07\xb4\x06\xbb\xbe\x9b-\xdd\x02A\x8a\x95\xa1{X\xe6\x05\x83\x9e\xeb\x17\x8fm\x8f\x18\xd4J\xcc<\x07\x7f\x1e:\x8c\xdb\x97\xa6Xp\xbf\xf1\xf6\xd5\xcb\x01\x9eu\x83\xf9\xa55\\\x80z\xd6\\i`\x1f\xaao~\x1d\x96Z\x1c\xc1\x8eY,\xcf\xa6\xfd\xf2\x1a\xe8\xf2\xee\xb2\xdd\x9cL=\xb7\x862\x157\x1f[\x8fYV\x99\xe9\xac\xfd(\xa6dAb\xef\xec@\x1f\xa9\x9d!*:\x1e8\x1bC\x8f\x15\xb3\xa7\x9c\x87T\xe6\xa6\x80\xd5\x80\x1d\xd6\x8f\xa5\xb0},\xf8\xf4}\x01\xc6\xd4c'y\xc6\x12>\xe5\xc1\x19\x9f\xb1_I\x99\x9f\xb1 \x9a\xf1\x0b\xf6+\xe9\xa0\xe7\xb1\x13\xf4\xed\x05\xf7\xa4k`\xb3\xcf\xee\xf7\xb2\x04\xa5o\xd1r:\xfc\xf6\xe9`\xda\n\xe2\x9d\xbc\x8f\xeaWX\xd3jo\x05\x81v;QG\xd6\x99\xc6vY\x9f\x96\xa5x{\xeb-]t0\xddT\xcf\x0d\xa7\xf4\xff;\xac\xc6\xd7\xf8\xc5\xaf\xd7\xe44:\x1d\xe0\nfa\x1cv\xc4\xd9i\x97f\x99lz\x0en n\x85\x0f\x99\x17\xa0\x9e\xb7\xd6i^\x12\xdd\x16\xcc\xed1%\xfc\x02BK~oX\x9fv\xc6\xfa\x10\xb0\xbe\xee`\xae\xfe\x18X\x1f\xde\x00\xeb\xc3[\xc7z\x85\xc2>:\x93\x04\xfe\xa9\x8dk)V\xca\\\xac\x94N(-J\xaf`\xa5\xcc;\xae\x94\x8d\xd5zpz\xcf\xe5\x99l\xdeL\x8e\x8f\xa2O\xfdY\xa1\xc2\x10\x195\x9e\x0da\x80\xd7\xf9{L^\x139\x8a@\xd3\x06\xb7J\xc8Z\xfa%\x13\xe5\xa7K\xd6\xef\xb0L\xcf\xe4\xa5\xb2\x95\x93zln\xae\xf6y\xb7\xd5.\xe0\xb6(\xc0\xb6\xf8\x05\xadc#\xf5\x83vE\x92\x99>\x87(\xfcQR+y\xfd\xef\xa0pR\x7fu\xc5\x86\xec\x1ed\xc0K\xc6F\x8c\xc3\x85I\xb8\xed\x07\x0cZ\xa5\xb5\x0f\x96o\xcfhJ\x02\x17g\x97J\"\x81\xe8\x84\xe2=\xf0\xd8\x1c`\x92\xa37\x1ep\xb1\x13#+\xfa\xdc\x0f\xc3 :-D\x0e)\x83\x95\x03\x8e\xb9\xd9,H\xf84\x0b/Y\x90\xb2(F65N\x04\xd18\xb9\x84\xc0*_\xaf\x92x\xb5)\x88N\xfa5[\xf9\xd3\xf7\xfe)\x1f\xb0\xafR\xce\xbe.\x1a\x1c\x00\xc3Z\xfct\xdc\xaf\xc5:\x9b\xfaa(\x9aX\x0e\xd8\x1b\xee\xcf\xd82N\xb8\xe0\\\x17Y\xb6\x1a\xdd\xbb7?\x19,\xf9\xbd<\xe5\x9bP{\xb3\xfc\x8eu\x91hx(f<\x19\x07\x13v\x007+\x8b\xcb\xa1*\x0d\x89\xc4\xbb\x05/\xcf:\x15\xa2\x19\xa4`\xe5(\x18\xef\x94%\xfcgy\x90\x80TQ?O!\xdf\x1dd\xa9$\x067b\xdc\xa9\xe0H\xdb\xa5k\xa6+\xe61\xbc3\x92\xa1\x0d*\xb4^\xba\xd6B\x1co\x10\xd7\xdd\xd5#\xc6\x10c,\x91\xa4\xdbm\xee\xa4v\x9b\xbb\x8b\x10\xe11\xdb\x80\x10\x91A\xed\x16ucMV\xeaBb\xbcB\xadM\xe4\xd0\x0e\x9a5nvS}\xea\xc8\xf5\x82\x17\x9f\xae7\xbbAx-\xf0cc\xe9\xf8\xe3\xe1\xa4\xd3@X\x17\xd9\x8e\x0d\xa3\xa5[\xd8\xf6\x05k~\xbf\xeeu\x96&s\xa7\xcdWL\x95\x9e\xc5\xba?\xd5\xe5\x85\xec\x80I\xbb(\xe0\xfc4\xf1\xfa\x1b~zx\xb1*\xef\x81\xf7XGG@\xf2K\xca\xf4\x08\xaf\x9c\x82;\x89\xb7ZJ6\xee\xfd\xea\xaf*\xd7\x1b\xef\xfc\xd3\x1e,\xe0\x16k\xb2L\xef &\x9bpD\xa7W\xa2\xe3\xaa\x07\xf58r6\xe0^\xda\xddwiN\x98a,\x05\xb5+UZx\x07\xd9\x84\xbc\x9a\x9bSR~m8\x01ht\xb0T\x99\xa1\xcf\xfcL\xfb\xfa\xcc\xcfx\x8f\xc6J\xa3&\xcemY7\xe1\xa7\xfcbE\\1\xb6\xa1Q7x\x9e4#+-\xd0/v\xec\xe6\xad\x1a\x91\xb6i\x1bn\xdd\xf6\xd4\xe8\xfd\x088\x9b\xc6=\xb4y+\xc620\x03M\x05$\x98;\xf4\xa8\xa9C]iL\x9b\xd3\xb7\xea/YIs>\xc9\xf6Q\xc5V\xa6xl^;\xa9\xb0}\xc1J\xcf\x07z\xc2\xdc\xd3\xa4b7\xf0C\xd0\xe4x\xa7P\xe9\xdfR\xfb\xbd\xe1\x83\xc1\xee@z\x1e\xb8Vkg\xa5\x8f\xe9\xdd\xfb\xee\xa0\x88\x98@Y\xf3\xb6\x19\x1b\x07\xb2\x9d\x07\xa4}\xef\x83\xfb{\x16\x83]\xdfQ\x92\xb9\xdb\x18\x87aG\x8c\x9d\x1fn\xd3n\xa3\xeb&\xca\xa2\xb3\xbdep\x11Di\xc7I\xad/xuf\x19\x13\xd2\xc3\xd4j\xef\x8b\x9f\x1c\xb1\xdeg\x87\x9f\xbfxyx\xfc\xe5\xb3\x97\xbfe\xf1\xad\x90f~\x16L\xbb\x95])\x0c\xefTZ\xfaS]\xa3\xc2\"\x08g\xcf\xd7\xadu\xca\xb3\xcf\x90\x1a@\x84\x9dj\x9d\xe3/\x0f\xdf\xfc\xda\xe1g\xf6\xaa/\xa2 \x0b\xfc\x10\"\x17\xadY\xf5\xb9\xd6\xddu\xaa&<\x82\xbb\xb4\xaa\xc6\xab\x97\xcf\x0f\xad \x94+\xe8\xc7A\x18~\x89\x8eK;\x80\xa4\xa8\xf6Y0\xbbF-\xf1\xb17\xa8($@j\xc3\xa3E\x9c\x0bp\xc86\xbeZ\xcd*\x10\xed:\xc8z\xbd.\xfd\xfd,\x98]\xa7\x1a|.Zv\x86\xcfW/\xdf>\xfb\xfc\xf0\xf8\x9asB\xd5^\x1b\xc8T#k\x0c=\x87\xa2\xc5\x1c\x8dX\xef\xd5\x8f\x0e\xdf\xbcy\xf1\xd9\xe1\xf1\xa7\xcf\xde\x1e\x12\xbc\x8f\xd9Nh%:\xb0\x10\x93\xe0\x8c\xcf`5}\x9e\xc4\xcb\x86\x15\xd9\xe5[S\xeb\xb7fA\xba\n\xfd\xcb\x97p\xe3\xbb\x13G\xce\x80\xf0j\xf5X]\xac\xab\x1e\x8b\xd6H\xd1\xd4\xce_\x13\x1cgK(\xb9B\xed\x11\xa1\x9a;\xaa\xb8a\x8b\xfa}W\n\xb4\xc7\xd1d-\x15\x17AJ;\xf7\x9b\x0f\x8c\xda\xe2\x88.C\xa6\x19y\xa4\xabP\xd6\xd0\xb5k\xf7\xca\xd2\xa1\x1b\xf4\xc5\xd8;\xd6\xe8N\xad.8\x13\xaa\xa7\xed\xb3\x85c\xa4B\xcb#\xb2\xf4Z\x08\xa9\xed\xc6kt{\xa5q\xa9\n\x84E\xda\xba\xf0+\x98\x87\xce\x1d\xd8\xe8^\x94u[C\xac\xba\x8e\x82\xa8\xbdU\xf5(>\xaf\xdd\xa6_=\xd0\x9f\xba)`\xd4\xd9\x14\x90)\xb1\x97\xe0\x16A\xd3\xd9\xed\xb3\xe2 \x9c\x8d\xd8cw\xc1\x88\xf6y\xe8\xa7\xe9\x88\xfdV\x9c3\x1f\xf4!\x19_\xae\xb2 :eY,C\xcf0\x9f%<\xe5\xc9\x19\x9f\x01\xa6\x88\x9ez\xec\xeb_I\xbf\xf60\x16>n\xd8\xd1\xd1\xdd\x8c\x9dp\x06\x11\xf2A\xb4\x0b3\xdac\xef\xf9\xe5\x80}\x86M\x05\x19\xf3S\xe6G\xa5\xc1\xb4j\x11R\xb8?{,\xca\x9c\x07a\xc8\xd2L\xfc=\xe1\xcc\x9fNy\x9a\x06'a\xd1\xb8n.~\x97vRo{\x94\xd8\x0b\x80\xd6A\xea\xa5\x1e\x90~\xad3;L\xe3\xb9Cs\xa2\xd9\x01\x0b\xc7\xd1D\xca\xe9\xbb\xf7\x83\x95\xa7\xcb\xc0\xa1\xb6C\x10{\xe4\x1e\xebu\x9e_1\x95\x02\xb2\x97q\x9eh\xb6\xc2\xa0 \xcb\x16~\xc4\xe2h\xca\x07\xec\xdd\"H\x05\xe4\xe7a0\xcd\xd8\xd2\xbf\x14s3\xcb\xb9h\xc9\xc7Mm\xd0C\x07\xc8gq0s8\xc6\x95_\xc0\x8b\xc7\xa8\x80S\xb6\xa7Y\xff\xab?\xf2#\xb4\xc7\xe5\xfa\xd3\xde\xac\xbd\xc4\x07\xa42\xeb\xd04?\xcf\xe2\x93 \x9aU-\xee\xd7PA\xd3\x81u\x98f#\x98\xd6\x11+\x13\x88\x95\x8e3;b\x9d\x10U\xee\xdc\x11\xc8Te\xe1\xd0Ml\x05\x8f \x12\xc2\xdc\x9fr\x1bB\xc5g`\x87Q\x9a#\x86eXj\xc9\xb3ENDg\x9f\xe5Y\xfci\x10\xcd^\xfbAb\x89TY\x8dR\x19\xd5\x97\x99\x0f\xcbl:@\xee\x1f\xa6T\xbe\xbb\xa4\xbfw\xf5\xc0\x1c\xd7\x1bC\xbb\x8a\x1cC\"\xb6\xedJg\xf2^h4\xce;X\x8e\xad`\xd8\xc6\xf7\xda\xf5\x80sg\x85!w\xa6fm\x97M\xc7\xf9D\x0c:li\xa9\xc1\xef\xb3\xfe\x881\xcd(\x02\xd8\xd6S\xd6d7\x0d\xc6+\xe0\xac{\x05\xb7\xdc\x86H*\x06\x8a\x92w\xdb\xc1\xc0P\xbfmR\xf4\xe7L\xba\xcfN[\x03\x96\xeaO\xe0\x80\x13q;\x13\xb0\xac\x13@\x99\\_\x81_E\x85\x11\x81 \xd1l\x15\x87\xc1\xf4\x92\xfdJ\n(\xfd\x9e\xc3\xeb\xf9\x82G\xb8\x02O\x81\xdd,\x96\xa6\xa8\x02\xc4x\x89\xb3\xdf\xd0\x9d\x03\x96`\xe4\xd2\x85#^\x042\xb0\x11\xd5C\xf4\xe0\x8be\xcf\x8a\xb2\xdd\xa0/\xddA\xcb\xda\x1d8+(\x1ec\xd0\x93\\|\xc7+*7\xd6m\xe0\x15\xcc-\xbe\x13\xa1\x9fY\xf7\xfb\xea\xb1$p\xa4AY\x83\xaf~\"=\xf3Xo\xc9\x93S\xaeB\x1c\xbd\x8c?\xcbW\xa1\xd8\x90\xf9o\xf2\xcb\xd4qG\xec\xb9\x1f\x89m\x17\x8a\xb1(\x8e6\xb1\x99\x14\x08x\xe62\xe2\xc8\x82Q\xca*:=`\xf8Z\xbf\xf5.\x91\x06-\xf8\xb5\xec<\x96\xf4;\xc5\xed^p\xfa\xa9\xbf\xe4\x18\x06]l\xbd\x9dv\xd6\xc7\x02D+\xf0\xf0*\xf6\x044\x92SE\xa7~\x9eJk\xb2\xf3\xb8.\xb6u\\\xb1\xc5\xd5\x0e\xd3\x8e\xab8\x0e\xc9w\x8b\x15P\xe9\xa7\xd8\x1c\x17\"\xf5=\xbfL\x15\x0b,\x19S\xcb\x0dUeB\xd8 -\x16m\x96\x88:{i\xdd\xf70\xb04F\x83\x15\x10\xf1\xcaH\xb2\x96{\x8e\xe2\x81C\xad\xa5\x96]=\xaaL\xe2\xca{(I{\xe1\xd2\xd6#\xb2\xef\xde\xe0^\x98\xf0\xd5\xcc4\xa5\x9b\x13\xe3\x14\xc0\x0b\x1dV\xa4\xdbz<\xbb1\xe0\xad\x00\xb7\x02\xf5\x9a]]\xb6\x1e\x1524\x9e\xa3\x94\xc4\n\xec\xb5/\xd5[1C\xd1\xa9\x87P\x13\xb4\x82\x86)\x83\xd6\xe3\xe3 \x85J`\xe3\xb7\xb1E\x96&H\xaa\x89\xb4\x97\xed\x1d\xac\x88\xea\xaf\xddG\xda\xde\xa5S\x1fO\xac}\x94\xfe\xc1\xa5\x02\xa9\xb3p\x0b\xfa\x87\xf2\xf8d\xc0\xa3\x9f\xe5<\xe7o\xb4\xa6$\x86\xad}z-\x06\xdc\x11N\xca\x16g\xa3\x0e\xb0\xeb\xc3\xea\xd8\x1e\xd6\x97iF\xa2\xce\xb1\xaeT\xd7y{vB\x90\xb6\x12\xb2M\xe42\xab\xa9T\x93\x06sPV\xa2\x89yXP\x91\xd7\xee\xdc\xe9\xf0e\xf5T.\x11r\xb2]\xcf\"\xeag\xfd}\xb6\xdd\xd6>\xab\xc9,\xdb\x8f\x05L\x9e\x88\xb2q\xc4\xfal\xd8\x81O\x85\xe0\x0b\xfbH\x99\xe2\xeb\xfaA\xf8\x00\xe8\xab\"\xda\xad\xa4t\x9b[C\xe7&|\x0e\x0e\xc4\xbc\xca\xbaP6\xeaQi1\x9fq\x19\xcb\xc7>\x90\xc2\xcaWT\xa9\xb1\n\xec\x80Lv\xdcV\x81^\xe0\x10\xacY\x0evuUs2`\xa6\x7f\x85\xf8\xc4\x88-\xc5\xc9W\xa2\x7fq]]\xf0.\xe2\xd3=\xb1\xb9\xe8\xea)q\n@~_P\xc14\xd0\x14w=\xb7\x06\x91\x9c^\xad-'\xde\x04\x84\xe5\x15c\x97\x88\x9f\xb3cOO\xac\xf8\x10\xc1h\xc8Z&\x85\xe22\xa8_>\x90!O\x9d\x95n\x00\x9e\xb9\xae\xc7VN\xe6\xb1S\xf5\xc2\xd5\xcb%\xec\xb0u\xb5\x08\\EP\xc1\xe6\x0bMI\xbd\x98\xe3\x82\xacB\xef\x1c*\xda=\xd6\xc3\xc0\x07pnr\x06\x83\x81`\x98M\xd1\x16NO\xb0\\\xa15\n\xf3\xd9\xd7\xd8\xc0\xd7\x92\x93\x04f:u\xf5\xf1\xcb@%N-I\x86\x9bj\xe4w\x9a,\x93n`\xd0s\xd6\x12\xd3\x0c\x0co\xca\xe2\x91cs\xe6g\xa7zr\x00F\x0cg\xee\xca\xe0\x96\xc3\xfb;\x10\xdd\xf2v\xc7\xb3\xbdG\xdb\xe2)\x1b\x00\xb1\xd5\xc5.Ek\xfd\x12*5Z\x0b\xc1X\x1f\xeby\x96#$\x8f\xf2%O\xd0\x01\xfe\x86%\xd0\xe8)\xef*]Q[\xf3\x80\x96\xb5\x13b\x82\xc6\xbe\x07\xdf{\xbf\x83[\xe9\xb7D\x93\x8e\x9d'\x1b\xcf\xea\x08\xc4\xf6\xd9\xd0Bv\x18uz\xb8\xc1\xfao\xa3E\x80\xb7\x9e\x14A\xe3M\xa3*\xca\x927\x95\xe0&\xf5 >Iyr&\x86.\xce\xdcp\x0bXK\x1a\xc9\xa0\xbc\xe2P\xad\x12{\x10\xd1]+\xb4\x8fvr\x19:\xc7\xd6\n\x92;\xf0\xf7\x02\x91\x8a\x80\xc7\xf0\xcf\x00Bn\xa4\x98[\x8fYP\x11\xf0\x04\xb4\xcb\xa2\xb3\xc2)N@\xc8f\xb6<\x1a\xc4|\xecO\xf0\xe2\xa7xA\x07G\xb6\xbd\x8ai\"\x11\xbd\xc7u\xeb\xab-\x93\xd8\xa6\x16F\x8a\xe6\xbc6:\x08\xca\xaa +\x04\x04E\xc5F\x91\xe9\x99\xe6a\xabY\xf2\x85\x07C\xec\xbamm\xeaO\x06\x1e\xc7\x04;\xfb\xe2\xe5\x8bw\x8d\xc5?\xb4\\Q\xd5No\xb1\xcb\xb2E\x12\x9f\x83P\x05n\x119w\xdf\xf0Y>\xe5 \xeb\xdde}\x96\x81\x1b\x90\x9e\xc4`>c\xc5V\xc9fy\x82*[\x90 \x05\xdfH\xe3\x9b\x17sT\xaf\x81\xd8g\xe5\xa7)j\xe2DZ\"[\x0e\xd2\xb2\x19\x8f]\xc69\xca5\xf8\xc5*\x0c\xa6A\x16^\x16\x0bf\xc1U\xfb\xd8\xe0\x80\xbd\xab'\x81\xfe-\x8a\xc1B\xb0h\x15\xba!\x1a\x9e\xc5\xd1\xdd\x8c\x9d\xfbQ&:\x91\xf2\x8c\xf9\xd2\x01\x81X'\xa0\xbf\x93\xbd\xc2\x8eL\xfd\x08\x0c?\x80\xb9\x91\x86\x83,\x9ek-7\xb9\x96\x11\xd3\x1f -\x10\xad^\xdc{\xfd\xe6\xd5\xa7\x87\xc7_\xbd\xfc\xcd\x97\xaf~\xfc\xf2\xf8\xd9\xf3w/^\xbd<\xee\xb1>\xfb\xd2\xcf\x16\x83\xc4\x8ff\xf1\xd2q+\xa1\xcd\xb5\xe0\x9e{\xee ]\x85A\xe6\xf4z*\x80o\xe3\xe7k\x93\xdb\x15\xbd\x10\xb5\xe8\xed\x86\x01>\xdd\x00K@\xbb\xbfJ\xe2\x13\xf1\x1ed\x0b\xe63\x1c6|v\xc0>\x83 \x12\xcb5\x8b\xd9\xc2\x8ff!z\x99P\x98\xce\xfa\xec.\x8b\x13\x16g\x0b\x9e0\x1f\xd6 \x88\x18z\x08\xe1Ozh\xd6\xb5\xf2\xd1<\x8a_\x82\x8d\xd54\x06/\xa3 X\x96\x06g\x80:\x85yO\x81q\x1a\x9aM\xf3$\x01\xa3\x03\xc0)\x81\x1c~t\xc9\xf2\xe8}\x14\x9fG\xea\xbb\x1e\xcb\xa3\x90\xa7)\x0b\xb2\x1a\x12\x07\x11;_\x04\xd3\x05\xde \xa4>PAZ\x8f%\xfc\xd4Of\xd0X\x8c+\x06\xbf!\xc1\xd2\x0d\xcd\xd1\xa9\x86\xc0\xd9\x13D\xd9\xc1]\x8b&\x86\xd0\xfe95\xd3\xa0\xca\x01\xd3(\x0e\xc2\xf1\x06\xfa\xddEo)\x96\x87\xd83\x0b\x9d\xa4\xd2`\xc6\xb2\x12\x14\xc9\x80\x8f\xb2\xf8*/\xbd\xbc\x88\xceb4\xdcz\xed'>\x84u\xff\xb2\xf0\xb1\x9b\x15\xac\x84\xf4\xf4@\x124\xf0\x16$\xb6\xae]\x97\xd8\xbbD\xd6\x83]#+(\xb2\xf6\\\xf2X\xeb[\x95\xba\xd2v\xa4\xb2\xfey\xf3\xfa\xb7\x1e\xc0\xb5\x05_\x1bj\xa2\xe6\xd8[\x0bd\xb1^\x8d\x82\xff/1\xe9\x15\xbds\x04\xe5%\xa61P3L\xcdU\xf0}\xcf\x15E\x9c\xed\x8e\x9f\x82\x1a\x89\xa6\x0e\xb5\x1b\x81\xa4\xb9\xa5'\xbb\xb7Y\x9cp6\x8b9zc^\xf8g\x1c%\xf3\xc1L\xc9\x1c\x06\xecK\xff=g\xf2*//#\x8c\x94J\x85\xfa\xe6\x1b\xa4\xday\xf7|\x11\xa7\x1c\xa7&\x05\x99\xb0l7\x1d\x10\xc1k}I'\x0b\x14s\x0d\xed\x13\xba\x0d-\xb6\x84\x17\x19\xaaM\x07A\xaa^\xf5\xb8.\x85\xbbd\x1f$\xd8A\x8aB\x91\xe2\\\x9e\xd5\xa2\xa2\xa8\xc1e18&\x88*\x81\xdf^,\x979\xc4\x83/\xbeZ\xdec\x9a\xc7a\x18\x9f\x07\xd1\xa9rx\x10\x80S\xaa\xbb\xac\xcf\x02T\x1a\xdc\xedy\xacw\x17eL\x83\xbb\xe6\xd8\xe1\xc0%f\xef-\xff\x19(#\xf0\\\xe8\x0e\xe6A\x98\xf1\xa4\xe5\xa8 \xc7\xbba\xdc\xdf\xaa\x1da\xeaZ)Y/\xd7e\xc0\x07\xac\xa7]\x19\x04\x81\x04^\x94,J\x1d\xb0\x9e\xf2\xeb\xd0c\xa3\xe2G\xc0S\x14\x97\xe1\xc0ss\xe0l\x1e\xe7\x118\xa5\xbe\xab&E\x03\x7f\x16\xb3y\x10\x15a\x83\x04\\Q\xf0\xaf\xe4_\x853 \xbcC.\xc5\x1a\x0dp\xd6\xef>\x96\x9dD\xff\x13'\\J\xeaf\x83\xbbuw\xca\xb7\xbf\x1b\xde\x1aE\xf3\xd6\"\x0euo\x9c]tH\xa4d\x13UH\xa0\x1a\x12X\xaed\xa7\x97+)\x0bEQ\xe7\xad\xc8?\xeb\x02(M\xb6y+\x13\xa4W\xacB\xab\xa0\xd0b\xd7\xae\x07\x00/\xe7\xa9:#]>\x199\x8fP\xc4\xfd\xe8\xa1[\xedy\xe4<\xd8\xdb\xead\xe0Y\x1e\xa1\x87\x86\xafC\xe9l\xf0\x91\xeb\xf4\x8a\xd8\xe0\xa4\xad\xf3\xde\x96\xc5\x8a;r\x86\x0f\\\x8d\x8a\xaeq*\xb0\x1d\x084ER6\x8e\xd1c\xad\x16\xbb\x1c\xee\x14@4\x81:\xcdJ\x1c]~\xd7 \xc0\xcdV\x86\xf7~\xe2\xfc\xca\xf6\xd6\xd5Q\xea~\xe2\xfc\xd4?\xf3\xd3i\x12\xac\xb2\xab\x99\x9f\xf9\xee\xbd`i\xc2\xf2\xde\xf8'G\x17\xdb[\x9bG\x17{\x87\x93{\xa7\xf5\"\x01\xb69\xfe\xc9h\xd2wG\xf7N\x97\xe6qk\xdc\x1b\x08Bt\xaf7\xa1\xe1]\x05h\xeaGA\x16|\xc3\xbfJ\xc26a\xd5\x99\xb4\xb5\xf1\xe4\x8e!\xaf\x95\x89cA\x8fRKw\x12\x10j\x05\xfd\x010\xec\xaf\xe6\x0e\x1foM\\\xf6\x94m\x12\xee\x97\x9d\xdc\x95&\xe7N\x04\x12\xc0\xa5\x9fM\x17N\xe0\x8ad4\xd9\x11\x873\x96\x0c2\x9ef\xe8\xb6\xa4\xe7\x9f\xc4y6: \xfd\xe8\xbd\xd86r\xb8\x1d\xae'V\xbe\xb3\xa6\x15e\xb9<\x1e\xd8\xec\xff\x1f\x0e]#\xdci\xc3f\n.\xa2\x07Y\xfcE|\xce\x93\xe7~\xca\x1dpG\x02\xfa\xa3\x03&\x90\x94\x8d\x0c\x1f\x1f\x96\xe5\x15\xaf7\x84]\xca\x9e>r\xb6\x1f\xda\x96\xaf}z\x95\xb0\xdbI\x1c\xeeVG\xb3\xe6\x1a+\xbb\xb7W\x17]|/\xa6\xe4`H\xdelF\xde\x0d$g\xff\xbf1y1\xc7\xf5 \x8e\xba\xd9\x8cw\x03t!d\xb9\x96\xe5\xb8\xbe\xa2)\x84\x13\xeb\xc1r\xa3g\x8f\xf2\xaf\x0b\xcb\xea\x9aCh\x96\xf5\x80\xc5\x03\x19\x94@\x814F\x12\x18 \xd1\x90\xe2y\xa34\x93\xa8\x0e\x96\x91hd\x91\x0d\xa6\x0b?y\x969[\x16%L*\xcb'N\xe4\xb1\xa1\xb2P\x82\x08!\xd9 \x0d\x83)w\x1a\"\xb0\xe4c>\x01\xc5wU\xd8\x7fm\xda\xbb\xfd\xb0\x1d\xc4\xf6cl\x0c;\x9a\x14\xdf\x93\x98T,2\xe9\x02\xea\x80\xc5\x82w\xf7\xd8\x06\x98\x01D\xec\xe9>\x8b\x95Ux\xf1\xa9\xeb\x8e\xe6\xc1^\x9d l\xc1\xbb\x9b\xd0g\x8e\x08\x02\x97\xb4\x92\xf6\xc5b\xe3h[\xbf\xc4Ks\xb65>\xa1\x10\xb97>:\xcag\x0f\xb7\xb66\xc5\xff\xf9|^\xbf\xf4\x96\xa8B[;Xhkgw~t\x94\xcf\xf96\xfc\x9c\xf3m\xf1s{k\x06?\xb7\xb7\xcc&\xe0\xc6\x00|fg:\xc6\xcf\x9c\xd8>\x07\x86~\xe3\x9f\xb4t\n.\xf49\x07#\xbd\xd1\x19\xdf\x85\xe2\xb3\xf9|\xe2\xfe|\xfb\x03y\xc5Oo\xf7d>\x9f@\xc2\xd4\xfe\xa1T~\xa8\x08\xe1sU\x84\x01r\xc5[\xef\xa0V!T\x9f\x99\xf3-\x8e\xff\xe6\x93\x03\x15\xe1\xc9\x91\x9d\xde\xde\xda\x9a\xc9V\xc7\x18\x93)\x9f\xc8\x95~\x85A\xe2\\k\x1b=\xf7\x93\xfaY`\xaa\xf5r\x1c\xa8\xae\x1e\xf4\xf0\x1a<(\x08\xa3z\xfb\xb5~\xcf\xd9\xbe\x0c\x8c\xe0\xc0\xe8\x9c\x83\xfdr\xa40\xe8)F\x8a\xec\x9d\xf6\xae\xbb&\xb8\xe4*\xe7p_t<\xb9\xee2\xde~hc\x08m\xcb\x98\xf2%/G\xdb\x1b\xdf\xfdo\xbf\xf3\xbb\x93\xde\x8dF\xd6\xbc\x9d\xa8\xdd\xdd \x1c\xb1o\x14,\xbe\x0f,\xbe\x0b\xce\x1ez\xbd\x1b\xdd9\xd2h\x9c\x058\x06\x0b\n\x87\x9e\xf1\xd1\xc5T\x1c\x8bf\xbbG\x17\xb3\x87\x9bG\x17\xf3\xdd\xa3\x8b9\xbc\xcc\x8f\xf2\xad\xa1X\x19\xf9\xd6po>\xb9w\xda\x00\xc2u\xc9\xc3M`\xed\x80\xd0\x1a\xa4\x82 \xa9U\xd0\x0c<\x96\xd4a{} \xdew\x9d\xea\xd7{\x7f\xf8;\xbd\x11\xeb=\xab\xad\x9b\xde\x1f\xfe1:\xf9\x8f\xd3\xc9\x7f\x82N\xfe\x1f\xe8\xe4?I'\xffC\x91\xec\x1b\xc9\xff\x88N\xfe\xc7t\xf2?\xa1\x93\xff)\x9d\xfc\xcf\xe8\xe4?-\x92\x9f\x1b\xc9\xff\\$O\x8d\xe4\xbf\"\x92\xeb\xde\xf1{\x7f\xf8\xefD\xf2\xccH\xfe3\"\xb9\xee;\xbe\xf7\x87\x7f\x96N\xfest\xf2\x9f\xa7\x93\xffg\x91\xcc\x8d\xe4\xff\x85N\xfe\x17t\xf2\xbf\xa4\x93\xff\x82H~a$\xffE:\xf9/\xd1\xc9\x7f\x99N\xfeW\"90\x92\xff5\x9d\xfco\xe8\xe4\x7fK'\xffU\x91\xfc\xd2H\xfe\xf7\"92\x92\xffG\x91\xfc\xcaH\xfe\x9f\xe8\xe4\xbfF'\xffu:\xf9o\xd0\xc9\x7f\x8bN\xfe\x0f\"96\x92\xff#\x9d\xfc\xbf\xd2\xc9\xff\x1b\x9d\xfc\xbf\xd3\xc9\xff\x89N\xfe]\x91\xfc\x95\x91\xfc\xb7\xe9\xe4\xbfC'\xff]:\xf9\xff\x14\xc9\xb9\x91\xfc\x7f\xd1\xc9\xff\x99N\xfe/t\xf2\xdf\x13\xc9\xf5\xd8\x01\xbd?\xfc}\x91|i$\xff\x01\x9d\xfc\xa7D\xf23s9\xfc\x9eH\xf7\xcd\xf4\xbf/\xd2\xdf-\x8c\xf4\xff*\xd233\xfd\x1f\x88\xf44\xad\xa7\x7fK\x93\xe5oi\xfa\xfb-Mh\xbf\x05\"n\x90\xb7o\xff\x04\x9d\xfc'\xe9d\x80\x80A\x0c\xbf\xfd3t\xf2\x9f\xa3\x93\xff\x02\x9d\x0c\x84\xd6\xa0\xa8\xdf\xfeY:\xf9\xcf\xd3\xc9\x7f\x91N\x06\x12d\x90\xe5oij\xfd-P&\x83Z\x7f\xfbW\xe9d \x13\x06\xfd\xfd\xf6\xaf\xd1\xc9\x7f\x83N\xfe[t\xf2\xdf\xa6\x93\x81\x04\x19\xf8\xf6\xed_\xa7\x93\xff&\x9d\xfc\xbbt\xf2\xdf\xa1\x93a\xcd\xfe\x9a\x91\xfc\xf7\xe9\xe4\x7fH'\xffc:\x19\x16\xe7\xa9\x91\xfc\x0f\xe8\xe4\x7fD'\xff\x13:\x196\xfb_7\x92\x7f\x8fN\x06\x1e\xc0X\x98\xdf\xfes:\x19\xb6Xc\x07\xfb\xf6_\xd0\xc9\xff\x8aN\xfe7t\xf2\xbf\xa3\x93a\xfb66\xb6o\xff%\x9dLo\x9a\xdf\xd2\xbb\xe3\xb7\xff\x9eN\x86\xed\xe47\x8cd\xd8N~j$\xc3v\xf2\x9bF\xf2\xff!\x92\xdf\x1b\xc9\xff\x89N\x86\x9d\xe0\x0b#\xf9?\xd3\xc9\xbfO'\xff\x01\x99\xfc\xdd\x1f\xa3K\xc3.\x13\x1a\xc9\xff\x85N\xfe\xafd\xf2w\xbfC'\xffq:\x19H\xaf\xc1\x8d|\xf7'\xe9\xe4?M'\xff9:\x196\x01\x83\xa5\xf9\xeeO\xd1\xc9\x7f\x86N\xfe\xf3t2\xd0o\x83I\xf9\xee/\xd1\xc9\x7f\x85N\x06Bm\xf0\x17\xdf\xfde:\xf9\xaf\xd2\xc9@c\xdf\x18\xc9\x7f\x83N\xfe[t2P\xcd\xc4H\xfe\x9bt\xf2\xef\xd2\xc9@\xa8\xdf\x1a\xc9\x7f\x97N\xfe\xfbt\xf2?\xa4\x93\x81\"\x1b\\\xc1w\x7f\x8fN\xfe\x07t\xf2?\xa2\x93\x81\"\xbf3\x92\xff)\x9d\xfc{t2\x90\xde\xccH\xfegt\xf2?\xa7\x93\x81\x98\x1aL\xe1w\xff\x82N\xfeWt\xf2\xbf\xa1\x93\xff\x1d\x9d\xfc\x1f\xe8d\xa0\xb1\x06\x0b\xf9\xdd\xbf\xa4\x93\xff5\x9d\xfco\xe9\xe4\x7fO'\xffG:\x19H\xef\x8f\x8dd \xbd\xe7F2\x90^\x83\xc7\xfd\x0eH\xaf\xc1\xcc~\xf7\x9f\xe8\xd2@z\x7f\xdbH\xfe\xcft\xf2\xef\xd3\xc9@L\xbf1\x92\xff\x0b\x9d\xfc_\xc9\xe4oav^\x98\x1b\x0f\xc0*0v\x9e\xef\xf0\xb8fp.\xdf\x01\xb3\x14\x9b\xe9\xc0X\xde5\xc9\x1b\xec\x1bi\xa9\xd9\xb5)Hi\x8f>\xd7\x16rw\x12\xb0\x11\xce\xd4F`\xa3[\xa9p\x03\xc9Z=\xf6\xa3\x12;R\x96\xdf\x84\xc4M\x9am?l\xf7\xbcG\xabT\n\x0b\xc5}\xd0+x\xba\xea\x04u\xf4\xfa\xc0AA%\xd5\x10~\xa9\x86\x80\x00T(\x87\xcd\xba\xc9a)\xb5\x01\x18Tlmm\x1e]l\xcf\x8f.v\xfc\xcd\xa3\x8b\xfb[G\x17\x0fN6\x8f.v\xb7\x8e.\xf6\xc4\xcb\xde|\xd2\xbfw]%\xa3\xeadt\x93N\xfa\x9b\xdfL\xc6\xcf6\x7f{r\x05\x7f\x7f\xbe\xed}\x80\xb4\xab\xf1\xd6\xe6\xa3\x89x\xc5L\xf9\x02\xa9W\xe3\x9f\xe0\xcf\xad\xcdGlr\xef\x9a\xdd\x8f\xd0Pb-\xb5O\xa1\x939:\xba\xf0\xa7GG\x17'\xc3\xa3\xa3\x8b\xd9\xde\xd1\xd1\xc5\\\xfc\x01\x01\xab\x008B\x1c@\x8e0\x07\xa0#\xd4\x8f.NP\xe0\xba%\x05\xae\xbbsvt\x94\x89\xea'GG\xa2\xae\xbf\x05r\xd9\xf9\xfc\xe8(::J\xa0\xd0\xf6C\xfc\xf7\xe8\xe8(\x1f\xee>\x14%\x86\x0fA\xf9 \x1a\xc2\x7fC\xfc\xb7\x8d\xffv\xf0\xdf}\xfc\xf7\x00\xff\xed\xe2\xbf=\xfc\x87mn=\xc2\x7f>~\x01;\xf7@\xfc\xdb\xd9\xda\xda\xaa\x11\x18\xd46\xf5X\x9fE\xac\xcfz\x16M\xd2\xac\xdf3\x17\x1cH\xa1\xb7\xf7\xe4\xb0\xf7Nh\xa5\x91\x98j\x01\xd4\xb9\x80\xd4|\xf7\x08\xa5\xddG\x17\xa6\xea''5Q\xaak\xa0\x18\xa9}\xd0\xda\xf4\xb3\xcd\xdf>BA;H\xdaQ\xd4~t1\xe36u\xd3\x1az\xad\xf0Zz-\xd0\x18\x8d;\xf7k\xae)\x98\xfcB\x0d\x96S\x8a\xa4\x95Vt\xda\\t&\x8b\xae\xa9>\xb8\xb2\xa9\x12\xdd\xba2naU\xc6\xcd,\xca8R\xf5\xc8R\x8f\x85\x9d\xf4s3Z?wV\xd1\xcf\xd1\xed\x89\xbc\xda}\xcbe\xa9b\x19OQ\xa3\xa7\xe0\xdf\x17`\x03\xc5\x95s0\x9a]\x85\xe1\xd5\xf2*\xe1W\xe9Uvu\xc6]\xf7@\xaa\xef\xc6\x89\xc7\xa6\x1e\xeb\xfd\xb0g\xaa\xff\xd8\xcah\xe8\xb3\xab/\xbe\xb8\xfa\xf2\xea\xcd\xe1\xd5\xdb\xabwW?:\xac5\xc4\xfalnk\xac\xec\xdf\xbcK\xffT\x8d\xb6\xcf\xf79\xc0\x1d\xeb\x87\xd7\xa6\xec\x1b\xce\x06\xd8t \xea\xa6l\x10\xc0\x14\x97\x1d\xb0\x15\x18A#\xe3\xef\x17\x0eG\xd9Z\xa8S\xdc\xb5~d\xbdk}o\xfc\x93\xc1\xa4\xff\xc3{\x03~\xc1\xa7N,z\x10\xc35\xb1\xf2m\xf0\xe2\xf0\xf8\xf5\x9bW\xef^\x81\x91~\x0f\xac\xb8{\xe8\xc8\xd1I\x93\xa9{<\x1c\xa0E\xd3\x88\xf5z\xd7\x85\xc4F >\x18@`\xd6k\x8c\x14\x91~\xcf\x1d\xf7\x8e\x8f\xa7q\xc27\x7f\x9a\x1e\xa7\x0b?\xe1\xb3\xe3c\x9b\x95\xfdu\xa5\nv\xdf6\xed2\x83\xf6s[7\xb0\xa9\xad\x01\x88\xcb\xc2\x87\xcd\xe3\xce\x1de\xde[!JcN{\x05)\xe9\xd2\xe6>\xcb\xd8\x01\x1b\xb2\x11l\xda\xd7\x05\xbf\xa0\x9e\xc4 \xeb\xf88\x8cg~\xba8\x16{\xfdqqg\xe8\xf8\x988v\xb5\xb8OX\x17\xb9*PR\xf0\xa8\x02#\x983\xc7pZ\xcc\xb4\xf3sf\xc0\x8fULN\xf7\xd1\xa6\xb4\x98\xee\xa6@J\xb2VPx\x15\x86\x95.\xbeP\xd8\xfd\xde.\xf0\xbf\x7fx\x16\xc6\xe7\x07\xd5+>0\xc4X\x1b\xf8\xed\x0e\xb4\x01\xcb\xda\x06\xd9\xe4=\xacu\x9c\xe5\"\xeaW\x17#rdC\x8fEb\xe8\xfbh\x8d\xaf\x89\xd82i\x9d\x9c!\x83pS\x02\xd1\xc6\x96\x8c'\xb7\xc4\x88\x0cw(\xf6\x18\x83\xd7h\xcc\xd8*\x0c\xa6\xbc\x0d\xf2\x9d\xd0\x8bf}\x13D\"rN6\x9c\x88=A\xc7\x11N\x04\x9e\xa0\xd4\xd5\xd4M6\x14\xebm\xb0\x8a\xd1WD\x89\x8f`\x1e\xef\xb1\xcd\xcd\x02H\x1e\xdb\xba\xd6\x9e[@\xe9\x174z\x1c\xbb.\xba\x1dG\x93\xf1\xb0m\x0b\xba\xd5\xa1\x146\xaa\xd5\xb1\x08rW\xb91\xf6\x11\xba\xd2u5\x9b\x80\x8d\x01\xb0\x91\x15\xb0\xb1\x04\xac\xd3\xefkH\x12a\xec\xd0\xb1\xf8\xf0\xc4\x85\x08P\xe3X\xc0[F9j_\xdb\x0d\xc3\xddn\x1d\xae\x0d\x89\x12\x15\xf9\xcd\x95G+\xdb-\xa1\xebr\x01\xad\x14\xc9\x8e\xdf\xd2S\x1d\xd9\x9d\x1e\x9e\xe8\xd1\x81\x1b\xf0\x9bQ\xbe<\xe1\x89\x96\x90\x02\xe7\xa9%\x9c\xc4q\xc8}\xe9\xf4M\xf0\xa6\xc7\xc7@\x89\x8e\x8f{2\x10\xc0Hs\xce\xf7}\xceFe\x1d\xc0d\x9c\xf2\x0eb\xfc\x8f\xdc\x07\xdc\xa1>f\x1f\x1a\x16a\xd9\x0fz\x05F\x80\x8c4e\x03\xc1\x034\xeeU7\xdeHnk\xc8\x8a\xc9\x8d\xf7fK\x8f\xb6{7\xae\x8eI\xe5\xdc\xfdV\x90X\xa6\xa5(\x80{\x10\xe9u\xef\xac\xe2w\x9d\xbcI\x06\x8e/b's\xa9\xfa\xaa\x8dT\x11\xb8\x1d\xa2\x05&o\xaa\x05\xe0{(j\xec\xbb\xfe\xc8q\xa4N>\xe6\x13\xb8|\x90wu3k\xa6\x9cI\x8f\xbc\xbc\x00\x87\x95\xf3\x0ea'a\x07,\x1f\xa7\xc0C\x87\x82\xc1\x0c F\x9a\xb1\x1bH\x03w\x87\xf5[ \xf2\x02\x84!`AL\xd8~\xd4*A\xb2\x12\xc6\xd8F\xa3\x87\x15&\xe6\xce\x1d\x96\x8d\xb7&\xe3\xed \xde\x19\x14\xef[\x82\xbd\x13/\xc3\x89\xd8\x82\x8ao5\xdd`\x8e\xa4\x13Q\x88\xb6\x16QAB\xaf\x0d\xb5\xa1qwF]\x8d\xa3\xa064%U\xdbm0\xc4\xaf\x0bd#\x80\x99\x02\x1d\x91n4\x8d\xe1\x0b\x04K\xcd\xe4)\xdbg\x1b\xb9y8,\xce\xf4\x85\xdf\x98\x8dZ\xfc\n\x10\xb0\xf2\x8a\xc7\x03\x96nnZ\xa5\xabs\xd1\xbdqjq}=\x85`\xa18\xbbs\xc1G\xc0\x166\x9e\x8f\xb7&\x02\xb97\x1c\xf1\x06b\x92\xd2\x93\xcdFS\xac\x0f\xe8\xdec\xd6\xef\xa7\xec \x0b\xad\xbdZ\xb1}\xe6\xa8\xae\xb9V\xe7i3\x10\x0d\xaf,\xb9\x0b1IV\xaf\xde\xc5\xd0l\x04\xa5\xe6\x90\x04B\xdco8\xab\xe6\xd1\x8aG\xc6}\xb7\xd3\xbe3\x86Q)\x1bBQ\xe7.\x94\\\xb2}\x96;3\x8f-<\xb6\xc2U\xe1\xb13\x0b\xc5\x04\xba\xabwy f\x12\x0b\x8f\xcd<\x16\xb0+y_\xeeL,\xcae\xf3\x08\x1afP\xd5\xba\xc1\xa1\xad\xf5\xeai}J\xea\x07HT\xd1\xacu\x86\xbc\x01\x8b\xd8~\x04\xca:\xf3\xb5\xa2\xac\xe4\xd5o\xbd\xc3\xfa\xc7T\x7f\xbb\xf1x\xb7\xf4\xad\x9b\xf2r\x16\x8d\xe0C\xea~\x9fH\xaf\x97\x07b\xbd\xd5\xead\xa1\xeb\xa9\x8c \xbfLy\xd9\x8a\xe7ft1\xa6\xb1G\x91\xa5\x15V\xf0Gb\xab+\xdcT=a>\xdbd\xc3bM\xe6\x95\x83\\\x15\xd3\xfb\xfdH\xa2\x90H5\x9b7\xc6!\x17L\xe0\xe4\x1d\\M[\xf8Z\xc5\xd6\xde\x90\x93\xb5n\xc5u1\x9ade\xb7\xa9x\xa7\"\x9d\xd2\x1c \x14\xaa\xab?Sl\xbf\xaeq\x08ew\xea\xcdL%\xdfTO\x9f\x9b\x9c\xc1J\x0f\xac\xfaLy\xf0\xac\x9b\x97\xcc\xaa\xa5\x12\xff\xb2^b\xa1\x97\xc0M\xbb^\xe4\xec\xe6\xc2S\xc5\xa2,=v\xea\xb1K\n\xffO\x04+\xe2PG\xa1c\xc8\xc9\x88\x9cs\xb6\xcfN\xd8\x01\x9b\xb1\x11\xcb\xc9\xba\x87l\x9f\x1d\x17%\xa86.\xc4^/\x1a:\x17\x9c\xcd\x8a\x1d\xb0\x05\x1b\xb1sW\xfc\"8\xa6\xb7\xa2\xb8h\xf5P/~h+\xfe\\5|h.\xe7\xe7bK\x0fA\xd7e\xaedX\xa5!\x9cb\x8a\x8d\xd2\\l'\xe0+\xc5\x83A42>\xc5\xf76.\x8a\x06/A*x\xa964\xd7c'\"e\x8a\"\xdb\x98\x98\xb5\x11\x0bd\xeay%\xc3\x1c\xdb\x86\x13\xb1;lN\x0eM\xcc\xf6{\xb6\xcf.@\x0c\\\xb8\x96\xe9\x1d\x1f\x9f'\xfej\x05\x82jb\xa2\xc4\xf3\x8c\xed\xb3\xb7Z\xb5\xac^\x8d&w\xef\xc5\xb8\x9e5\x9d\x07_\xb1}\xf6\x9e\x1d0>\x00Wr \x11mp\x9a\xfe\x9a\xed\xb3g >-\x8bg4[d\x05\xf6\xa9\xf3\xcac\xaf\x15\x1c/\xdb|^\xd3l\xd0\x06L\xaac\xb6\xee\x9b\xd3w\xfd\xad\xd1\xd8\xea\xe4\xc1o\x9b6\x96\xd9\xdd\x1ev\xf5\xe3zv\xcbf\x1du.M\xb7\xef\x80\x02\xfel\xe6\x80w\xe1\x1a0\xc4\xe3k\xf4\xcd\x9f\xcd\xc0\xabP\x99\"\xb6D4\xca\xf0\x0d\xfb\x8b\xa0jj\xe1\x93\xf0\xad\x037\xba\x99\xae\xa6\x13O$w\xd3\xc8\xed\xb4s~\x9f\x8cX\xfb\xb7\xec\xbae\x00\xbb\x93\xb5}\xc2\x8a\xd06/I\x86\xb9\x93d\xf5\xb6(7\x17\x14\xdf\x90K\xfc\xafo\xf8\xa9L\xaf\xb7\x13\x9a\x1b\xbb\xe0\x01\xb6\xcd\xed\xbf\xd8\xa3?E o}\x93\xae\xf0\x03\x9f\xf9\x99aiZa\x05\xc0\xa3e#+\xf0\xa5\xbf\xa2\xf8\x00-\xd8\xfb\xf2\x84\x1bM,\xf5\"h\x97R/r\xaa\x17y\xcb\x0dn\xe3\xb2\x92\x0f\x12\xf0z\x91\x93J\x11\x10\x81\xd7\x8b\x1c\x1b\x8c\xcf\xa7\xf9|nv\xf8\xbc\x066\xffG\x01?\xaf\x17:,\x9c\xaa\x15\xeb\xde\xe2\x9b\xea\x02\x18\x83\x03v\x88\xfb\xc2\xabyg\xd7k\x8aX'\x1e;\xf4\xd8[\x8f=\xaf\xe3~z\x1e\x80\x0f4R\x8e\x05q\xdc\xceGF:\x93; \x1f\x9c\\f\xfc\x0bd\xf77\xc41P\xfb}u\xc50\xff\xd5|\x9e\xf2\xac\xcc\xc7\xdf\x8d\x1c\x88x8x\xa3:\x01\x00{\xd2\x1b \xfe2\xcbCG\x8f\xe9\x8e\x16:\xcb\xb6\xden\xbcu\x04u\x8f1\x18\x0c\xbce\xaeKl\xfe\xf0\xb5\xb9\xf95H_Y\xd2\xcf\x1a{\x178}\xee\xb1>%y\x86\xda\xb3\xc6\xda|\x10\x81Oq1&x\x03O+K\xe53\x1c\xc2\x9d\xe0\x0fK\xf3KK\xa7/\x9b?\x8b\xfa\xa0~\xc5(\xa9R\x7fA\xd7W\xbcZn\xa9vj\xaf\xf6\x0c5\xfd,\xb4\x8b\x8b\x80/sD\xfb)x{\x85\xb3\xde\x86\x12R\x00\xbb\xfa\xac\x15\xfb\x14\xfb\xf6\\\n\x1b\xec\x9f{U\xb4\xf5\n\xe0aa\xd8\xd8\xd5>\x9bz\xecyy\x14\xb5\x7f\xf858\xb4{\x0f\x88\xf8\x1eC\x15\x94\x0b\xb8\x91!|^\nm<\xf6\xda\x02\xde\x13\xfb\x8a.\xf9\xf8\x0b\xe55P\x0cJ\xfe\xb0J\xaf\x99\xb6\xce\xda\x94\xcf\xed[\xf4\xba\xec\x9c\x0c\xe1\x04\xd3K\xcb\xaa\xb8\x195\x82\n\xa5\x0e\x0d\x8e\xfb\xfdl\xc2\xf6\xc1\x86\x9e\xd7\xee\xa2\xb9\x1fC\xc4\xf5q\x86\xd786\xbe\xf6\xb0\xecv\xb3\x8f(\xf1\xc7\xd0\xe4xn\xe9\xb0\x8f\xf2\xde\x94\x02\"\x08@\xd8\x1d\x16\x9bp\x9c\x82f\x8e:\xcb\x0b6hJ\xf2\xffb=\xcc\x05\xe1H\x9c\xcc\xd5tC\x1b\xa1\x95z\x14\xd1\x8a\x04\xe34\x7f\xccV\x0dJ\n\xc1:M\xc7+\x8b$\x7f\xc3 A\xc0\x00^\x9aG\x9aA\xdb\xcc\xed\xa8\x95\x10\xdfX\x80\x190E\xc1\xc47`4\xa9\x0c\x87R4\xba \xa8\x98\x12\xf0o\xd4\xbc\xab\xa6\xba`-U\xf1P\xea\xdf*\xa0\"\x18\xb9P\x1c\x9eV\xec \x9b[!s\n\x1a\x10\x05\x1f\x8b\"\xe4\x12,\x07g\x16\xf0\xf9n!\xfe \xe1B\xe5%\x1cWg\x80E\x1c\xf0g\xc4|G\x9c`!\x15\xd1+\xb5)~u\x05\xc4 ;\x10=\xdc\xdf\xc7\xd3w.\x1bA\xd4\x84vO\xecJb\x90\xa8\xd0\x14\xfc$\xe1\xfe{#\xc7T\xe1.a{\x03\x9exZ\x1a\x92\x83m\xc6\xac\x89>\x83\xea\x07\xf0wi\x03\xfc1\xb0\\Z\xab4\xe8\xcf\x81\x17\xd3\x8a\x99\x03:\x16\xeb\xe6\\|\xad\xda\xc9@F\xec0R3\xd4D\x91\x01\x06\x8fE\xde\xb1.\xa6\x86\x14\xb2,|\xf3\\/{\x8eF\xdf\x08\xfa\x0e\x1bX\xaao\xa1\xc5\x0f\x81\xe0g?\xa8V\\\x9f\xf4\x13\x87\xcfJ|\xc7\xcd!F\x83\xb5 (\xd0\xdc|\x0b\x03>\x8e'b)E\xec K\xacK\xc9\x87\xa5T\x8fZ(\x9e\xcc\xf1\x01i\xd1\xac\xd9 \xc6q\xbf\x0f\xb1\x0e;\x80(\xf8\xde\x00\xa1\xa23\xaa\x91\xf2\xc7.K0(cf\x04'\x91\xbdKZzg7E\xa0\x05\xf9\xf7\xa9\xfb\xe2\x94\x94\xbcm\x0b\xb3\xc8\x1dbiZ\x9eHf\xeb\xc6\xd0\xb5|\xa7\x953[\x170C\xcbMz\x03`>\x84)-\xc1\xe3\x8f\x0b\xf0}\x1e\xc6~\xb6\xb3-\xb5\x08\x80\x80\xb5\xcc\xdd\xfbt\xe6\x8b({h\xcd\x19\xeeZ\xb3l\x1f\xfb*\xb06\x08Y\xcfC\x7f\xb9\xe23{ \xdb7E^\xe5\xa3\x1b[\x9e\x9e\xafaP\xad&\xdd^E\xf0P\xcb+\xe48\xb5\xf4R\x08afp#Q\nr\xea\xb3!q\xc5\xc8\x00\xa9N-MIrj\xc9J\x17TKVB\x9dZ2\x08r\xeaiRxSK\xfe1\xf7\xdf\x17\xfd\xd8\x18z\xeb-\xc1@.\xc1\xd8\xe1E\x94&\xb1\x1fm\xf8c\xb1*o`\xdaK\xfb\xa0\xd85\xac\xdfn\x81C\xae\x8f\x0dc5\xe9\xf1\x98L\xfb'u\xf6\x18O,,[$6\xe7\xc2\xec\xc6\xd5\x9c\xf6G\xae\xb9\x91o\x00\x03~\x87e\xa8\xea\xb5\x10\xe86\xcb\xd7\x86\xb3\xc6\x9e\xebh\x81\xb6<\xd93\x8b\xe9\x05}\xfd\xc8N\xe5v\\\x07\xae8y\xac\xa7\xd6\x8b\xed\xe2\xd9\x0d\x9a~\x9d\xc4\xcb \xe5\x1f\xa1\xe5\xb7<\xfb\x08\xad\xca\x95uK-o\x1b\x97v\xe5\x8aX\xdf\xc0\xb3\x12\x856.B8gE\x00\xda\xa8\xe1\xf4\x15\xc0\xf1!\xb2\x1c.\x90m\n(\xb6 \x99\x0f\xe9\x06\x96\x95\xd2E0\xcf\x9c\x06D\xd5.\xfe\x03k\xd1\xb64E\xf9\xc0\x89\x8b\xbd\xcb\xde\xb2x\x00\xf8q\xc3\xa2\xa2)-\x99\x8aS\xe1$\xec\xa9\xf4%\xa6\xf6\xbc\x91\xd8\xc0Y\x9f9\xd2\xc8\xfd\x80\xf5\x9e\xdc\x13TM\xfe\xee\xb3\xde\xd3\x9e^Jn\xa0\x82\xa1\x8aD\xe9\xa3Hf\x83\xa6\x10\xe4\xa0\xd4\xc2\xb3\xcfb`\xdf\xc2\xd4)kC\xc7\x138J\x96\xbf\x07\xfej\xc5#\xf0\xef\xe0\xe9\xf84\xc0\xc4\xb8\x92\xa8\xcc\x18\x9c\x0dq\x06\xdd\xd8\xeaB\"\xe0N\x06br\x01\xb5*\xbc4pi\x80*W\xbf2s=`=\x86e\xb5\x072\x0e\xd6\xabN/\x8a3\xe6\xa7ip\x1a\xf1\x19\xcbb\xe6\xb3\x95\x9f\xf0(\xdb\xa0\xf8\x07\xf5\x9ci\xfe\x91\xe8^\xaa\xa7\xf4H\xa3 f\xec\x0d\xe7\x8e\xd6[IT#\xaf\xd2\x02\x8a\x80\xfa\x82\xc1P\x94\xd6\xf5\x9agE\x7f\x14{\xe9P\xbc\xa2zlT\xca\xc2f\x08\x9a\xd7uJ\xb4\x0d\x17\x0d<\xc4\xd0\xe0\x84\xcb\x95\xd7\x1d\xc1\xe7\xaa\x1c\xd1\xd3\xce$\xd3*\xfa\xac]d+~}pK\xc7\xc3\xce\x83\x07\xf2\x80\xdd$\xe8W\xdbyu\x80\xbd;\xbd\x11\xeb\xdd\xf1\x97\xab\xc75\xa2x\xb7wW\xe4\xfc,\x8f\xb3zV\xef.VZ\xc5\xa9\x91\xf5\x04\xb2B\xb3\xceS\xc88\xcd\x1ek\xc1\xfa\xda\x04\xe3\x16\xa9\xb8$^\x92\xb2\x01\xf1*\xc4=\xce\xf8N\xef\xc9\xd3\xbb\x18c\xa1U\xd8\xa6\x04\xccFP>\xe0\xd9\xca\x8e\x92\xd0\xad\x91G}\x08\xf1\xe3\n\xdc\xa5\x19\xc1\xa3\x1dwpx\xc6\xa3\xecp\x19d\x19O(o\x1f\xe6A:\x913\xbd\x08\x0cu\xb5x\"\xe7\xe1\xd0ub\x0f\xfc\x97\xc4\x837%\xc5\x14_\xbc\x0f\x89?N\x82\xacH\xdc\xdd}\x00\x89\x9f\xe5\xab\x90_\xc8\xa4]Hz\x97\xf8Q:\x8f\x93\xa5L\xdd\x83\xd4\xd7~\x9a\xbe[$q~\xba\x90\xe9\x0f!\x1de\xe2x\xb0\x8bu\x97\x1f\xc1\x8a\xb7\xe97\xce4\xdf]6\xc9yL\x9fF\xf9\xe0\\\x0d\x07U \xb8\xd5\x88D.j\x80\xd5\xd8\xca\xcfS\xae\xbd\x1a\xc7&\xfa\x93\x01I\x85\xa2r\x1f\x82\x16\x13\x9e\xe6\xcb\xca{\xe3\xa9,\x1a\xc4Q\xc1\x92\xc5`,\x08 \x89\x1fD=\x8f\x05\x90r\x1c\xa4o\xb3Y\x00r\xfcL\x1b\x18\x1e\x9e\xc1\x119\xd4\x12l\x9c\xc7r`\x88\xc4od\xdb<\x96\xd6\xa5xg\xd2Ztch\x83oN\x0e\xd6\x87\x8f\xf9r\xc7\xe5H\xc7\xbaA/\xed\xd0 y\xa9\x8d\x0ff<\xcd\x92\xf8\x12\x17\xb6\xfc\xd1\xf5\xb3!M\xb7\xc5\x16:u\\OZ\x02$\x830H3\x1e\xf1\xe4\xb9\xd8\x87\xa4\x13\xe1\x1e\x17\x9bi\xcfU\xfbk\x9d\xde\xd2_\x9cZ\xd1d\x19\x9f\xf1/\xe4wjsndj\xf3oV\xd5\xe7\xb9\x9eW\xce9Y\x13F$\x98%\xea\xabz\xae\xed\xab\xd3\xc6\xafN\xc9v\xcb\xdc\x86\x95\xa0\xc8-br\xa5\x9f\xf5\x14\x1d\xdb\xa7\x06\xb6O\x8b:\xd5\x14<\xca\x08\x02\x04gL\xaf\x95\x86\xbb\x10`\xa9\x89\xac\xf7\x04!I\xb3$\x98f=\x92\xaa\xdf\x1f\xba\x03\xbc\xadDZ\x08\xec\xb6z\x9c\xaf\xe3R\x81f\x9cD\xb3\x8d\xf6m\x8d\x15\xa6\x91\x9ci7E3Wg#\xdf]\xae\xb8d%\x9f\xfb\x91\xe0&\xc5>\xc3|6\x0d\xfd4e~\xca\xfc\xe2K\xc4\xb9\xf0C\xe9\x86\x1b\x19\x9e\x05\xf7g\xd2LK\xa6d~\x10VS\xe4y`\xdf\xea\\\x99i\xbb\xbc\xe9E\xaa\x99QS\xbc\xad\xe5h\xe9g\xbe\xd5;Y\xc4/2\x94G\x99\xe34y3}(O\xc1\x16\xa9\x18.\x88}@Q>\xaa@%\xab\x82$\xf3\x98\x8c\x01\x80\xcdT\xa1\xe1U\xc6\x9eG \xfc\xfe\xf8\xc3/\xfa\xdb\x05\x062\x06\x89\x06 \x10\x06\xebc\xac!\xc6:c6Fl#\xf0R\x00V\xb6\xdat`\xe5\xeaH#z4\x10\x10\xa1\xcf3\x12\x01\x87\xc6\x10\x0f\xaa\x03\xaa\xe1x}\xca\x8b/ \xf0\x16\x91A\x949\x05a\xce\xde\x04\x11\x15\xf5\xae\x11\"M\xbdkY\x81\xd5\xaf\xfd4\x0e\xda\x1d\xb8#\xfc\xf7\xeb\xf0\x97\xd0\xa3|\xe6Tn4\x15\x9d\xc5kM=\x14\xc7\xc3\xacHoH\x02n\x8f]\x16\xb1\xfe>\xe8\xc03\xcb\x9c\xd1f\"5\xf8\xc5\xd1\xd4o_D\xcdcJ\x06~\x18\xc6Sg\xcbb\x8an`LQ\xb3\x0d\xedJ\xc8\xc0\xb19F\xb3)\xf9\xbd\xaf\xa2\xd4\x9fs\x87\xb3\xa7O\x9f\x82x\xd2\xaf\x82/\x17\xd3\xf9\x98\xf9\x8f]\x00\x9c\x0f\xdf@\xa8\x06x\xa3>\xf7@\x97\xb6\xbaD\x9b\x1fQ\xa5\xaf\nV\x0c||\x04\xba\x0d\xc4\x81\x01\xe2\"\xe1\x83`\xb5d\xf4\xb7 JW|\x9aU~\x0c\xa6y\x9a\xc5K \x13\xa5t\xa6\x98\xa0q\xbd\xe0\xa4 \xd9\xd5j.*\x11r5\x1c\xd6\x88YI\x8e\xe5\xf2\xa6(\xae]\xfa,to\xa0/\xd2\xc6k=rw6H\xa2\xb6\xef\xea\xeeN+nH\x8eD=\xb0\xefC0\xcb\x17\xcb%\x9f\x05~f\x95jH\x05\x0d\x1a\x19I\xbf3\xe6}7\xfd \xe1\xa2\xbb=\x7f\xda\xa0\x9baRw\xc3\x07\xb3x\n\x922{\xb9Uitt\xca\xb3\xd7\nI^\x81R\x83\xcc\xb0\xba\xb0\x12M\xad\xc0\x92D\xc0\xe4]\xb0\xe4q\x9e\xc9\xe8\x88\xdc+\xfd\x1c\xac\x92x\xca\xd3t\xd2\x835\xfc\xf3\x0fEpIy!x \x0b\xa0\xb1m\x1b\x1dQ\x8f\xa6\x07j\xa4\xdc\xfa\xb3p\x88\x0b_\xea\xb1 \xb8\xd8HG\x9d\xa6O\x80\x12u\xb0\x8a\xd3\xecK\xe9@M\x9c6\xf9 X\x8a%\xf9v\x9a\x04\xab\xccj\xef\xa3\x1eE\xc47\xb6\x9a\xa5\x88LJ\x12\x05\xb3nu\xd1\xa6?\x05\xf3W\x94o\xdb\xf4\xeaOF\xeb\x10\xf4\x07\xf7\x86\x12\x02N\xaf\xe7\xb1\xde'=y\xaa(?\x1c\xd5o\xd9UZ\xa1g\xc2qA\"%\x9b~\xbe\xf0\xa3\x88\x838\xdb\x01{J~\xce\xaaY\xee@\xc0}H\x0f\xb8\x11\xb9\x16\x0e\x07\nn\x93y\xae\x81\xa7\x01tb\xbb\x02\x14\x0b\x16\x82l\x0c\x16b/\x8e\x12\xee\xcf.\xd3\xcc\xcf\xf8t\xe1G\xa7\x1c|\xdd\xcc\x07\xd3\x84\xfb\x19\x97\xa2w\xa7\x97\x02R\xf5\x04`\xc0\x8eq^\x90\x00Yd\x9d\xae*\xd4\xb3~\xc5\x8e`\xd9\xc0\xec\xf1:\xe8%E\xbdt+\xc8d\xc5\xf2d\xfc|\x11\x8430s\xced\x9e\x1d\x8fD-\x94m\xabZv\xc0w\x87SI\xed\x9c\x85\xc7\xb6\x8c\x1bF\xea\x11\xa4\x03\xc43=}\xcf\xf8\xa1\xd8\xed\xe0\x16P\xe2G\xb3x\xe9\xc8@\xb5\xc8m\x14=h4a\xcc\x06i\x9c'S.ob\x08\x8c\xd1\x83sI\x1b\xa5\x812\xe9\x93|\x172%A4\xe3\x17\xaf\xe6\x8e\x0f\x02\xbd\x85\xd3\x97\xe9\xa0pq\x14\xd3b3q\x14\xeb\xd8\x9f\xcd@\xd8\xaad\x14\xb0*\xeb\x89NO.\xba\x1el\x7f\x1bC\x10\xfc\x0e\xfc,\xf3\xa7\x0b(\xe9\xf4\x8a\x85)\x052Ig\x00T\x89\x8c/XX\xa43\x96\xf9\xf5p\x93*&\xa1\xf3\\kR\xb5\x8d\x9a\x19/\x97DGy7q\x80\xd1\xe6MF\x7f\x156\xbd48.\x14\\\xea\x10\xb1 \x11\x0f#\xe4>#\xf6DwM\xd0\xef\xbb\xca\x97@Qo\x0c\xaaA\x8b\xdd>\xd3\xec\xbe\x9aW\xa1\xd8\x8fO\xfc\xe9\xfbF_\xe3\xe2\xf1\x93\xd3\x942\xb8S\x0fq\xacU\x8f\xdc\x86\xc2q:A\x01w\xe2\xa4\xae\xc7\xd2~\xdf\x86p+<\xa2\xe9sG\x1c\xa4\x1b\x8c\x08f\x0d\x16%\x18\x947\xac\xdfhd-M6\x18\xa9\x80t\xd4\xa5\x88\x04\x0d\x94\x86\xe88L#\xca!\x19\xebV=p\x85\xad\x8d\xc8N ?|\xf5'K.;p\x02\x1b\x1dW\x8f\xfe\xa8\x81\xa0RW\xa0Y;\x83\xa3\x9e\x04\xea \xack\xee\xbdz\x94\x91u\xd2\"\xbb\xa0\x1e0\xbc\xde\xb2\x1b\xdfRO\xa3\x01%\xf5\xb4\x98i\xd7\x1f\xe8\xd3p\xdd>%\xe3-\xeajw\xd3s\x9d~m_\xa7_\x1eK\xc6\xc3\xef\xa3w;\xd7\xef\x9d\xf8\xbb\xfd\x91\xfb\xd8j\xebM=\xa0\xb0\x0fA\xe4@\xd8{P\x0f\xcdQWJ\xd8\x98\xa3\xa2\x00\x9b\x07\x91\x1f\x86]\xe8\xc3\x0c\xd8\xb9i\x87\xf3\x825\xb7\xab\xe1oM\xb6\xe7\xf4\x8a\x98\x05:/\x94\xf2p^^aW\xf7W\xb3E\x90\xc2\x0d\xd7\x11\x14\xd0\x94\xc0\xba\x11\xc0\x0e\xec\xc5v[\x80\xee\xd7\xa2\x8a\xed\xc3B6\xed\xc4\x17\xadV\x06a<\xf5\xc3\xb7Y\x9c\xf8\xa7\xbc9\xe6\xda\xd4\x07\x02\xd8\xe6\x15\xa45\xda\x19\xd3U\xca\x95\xef7\xc6^\x97>#\xc0\x9c\xac\x97%9\xc7\xc3?\x9e\xfb\x9d\xc8\x1dd\xf1\x17\xf19O\x9e\xfb\x84\x06Y\xff\xd5\xf9^\x1fS\x97a\x9c^\x14\x7f\xc6W \x9f\x82\xe9ZO\xbb\x97g\xf6Wi\x9b(\xd7\xaa\xf5\x9b\x82M\x1b\xfe\x06ycS/\x119=\xd0\x10\xd5\xbaV7>\xb29\xf7f`\x90\xd0\xcb\x12\x7f\xca+M\xb0\x036\x8d\xa34\x0e\xf9\x002\x1d\xf0w\xa4\x92\xce\xfd$B7\xe0\xb0\xf7w\\SL\x17\x17 \xa9\xc9@%UZb\xb5\xadC\xebR\xea\xb4\x86hA\\\xc5\xf9N\x99\\j\x0cw\x86\x96+\xe5[\xbbd\x00\x98\xc0\\\x1f\xa8\xdc\x03\xc2\xa0\xe9\xf7\x82\x12\x890v\x98\xe1N\xbb4%!\x02\xe8\x8b'\x1e\x04\xd1\x82'A&\x1d\xc1\x0c\xc1\xd2C\xa59\x01\x9a\x99\x04\x9a`\xfd8\xd3\x8cF\x9a\xa0\xc5\x007\xf0\x94\xdc\xea/\xa4\xc1\xb6&r\x86\x8f\x1et\x9a\x9fj\xad\xdd\xebT\x1a>\xba\xef\x96f1\xd7\xac\xaf\x19\xd0ti\xa1M\xe3\xbc3\xa4\x02\xe8\x8bt\x8bK\x82\xbd\xf6[\xea\xf5\x89\x92\xaa\x08\xbc\xac]\x1e\xe0\x0c^H\xa2\x9b?\x88\xe2d\xe9\x87\xc17<\x81k\xa9\xa0\x96s2\xed\x8678.+\x95\x0d\xa5G\x0c\x7f\xe0\xa7\x97\xd1\xd4E\xcf\x04\xfe`\x95\x04\xcb \x0b\xce\xc4\xd6\xa7\x8c`\xd8A\xf5\x13p\xb1z\x0b\x0e\xeb\x19\\\xb3\xc0\xaaF\x89m\x17<\x7f\x8f\xea\xb5\xb5vE\xb1\x1d\x17bQU\x13\xf70Q\xbc>\x84f\x8a\xae\x82\xe5\x8f\xb3\xb7\xf5\xc8\x95Q\x8d\x96\x8146r\xf6\x86\xa0\x9f\x19\xcc\x82t\x15\x97\x89\xbb\x90\xb8\xf4/\x9e\x9d\x16i{*M&lc\xcd\x84\xcf\xc1@\x85'*}[\xac8\x81(\xfe\x9a\xab\xa6\x0d\x91v\xf7(D\x02\xa1\x8f\x7f\x92\x9a\xa8\x049\xf30\xd6\x1dbwC'\xa5>J_\xfa/\xd1_\x05\xba\xe8\x00,\x11Get\xa7\nN?\xee\xdcaA\xfay\x10\x05\xe0\xa2\x1a\x1c\x0dq\xf0\xf2\xe1\xc4\xd2\xdfP\x9bQG'0\xd4\x88\xc3\xde\xb6\x0b\x82[\x18c\x1a\x9cF0\xf5\xbb{;\x9d\x88F\xfb'\xac\xfb\xb3Re\x15\x1f&\x17\x18m6\x05h/\x0d\xe0\x9c!z\xa5\xdbT\xbf7\xb7\xb7\xd6u\xe7\xb1\xc60\xec\xb6\x99\xdadz\xe5\x8c\x03Q\xd0=\xb2pi:\x81>pn\xa3\x9f%b?\xa0\xbd\xd2\x0e\xef\xd7\xfd\xdaH\x02Y\xf7\x98$\x03V\xee\xd1\x01+\x05\x9dm\x86\x0e\xe3\xb4\xb3\x81\x08oCUgX\xec\xe5\xe8\x10\x03n^I\x97\n\x15\x9a\xebjtG\xd1\x1b\xc2\"\xfc\xd5J|\x1d\xf3 l\xe8\xca\x9f\xf4\xb4\xe6\xce\xa8\xe5\xcc\x9bbEt\xd8z\xa0\xda =6\xf7X4\xe6\x13\x88\xe9\x81Nx\xc8K\xe5\xb6\xe3\xea\xad\xe0\xf2\xae%\x16\xe0\xce\x90\xf6K9\xbco\x89 \xfcp\xcf\x1d,y\xb6\x88g)Ejw\x0d\xff\xc0\xa9\xe4\xec\xeaG\xa8\x90^\x0cp,\xac\x96\x9cv]6\xf3re\xa0\xa6\xb1\x9a\xad\xd9(\xa0(G\x12\xcb\x80\xd7\x86\x82!1\xe3\x9a\xdf\x80\x05\xa4\xf2e\x90uXX\xc4Q\n\xec\xbb=vVD*\xf5\xd8\x89\xc7\x8e!\xc8\xec\xa1\xc7.0\x9a\x96\xc7\xde{\xec\x99\xc7^y\x10tk\x0e\xe7/\x9a\xe2c\x00\x11y\xa1\x14i\xb9\xdc\xbd\x0b\xf14\xee\xd6\\#\xe8\x1aW-\x10\xff\x02\x9cu\xea\xc9\xae\x07Qq.\x06\xa7<\xf3 \xf2\xcd\xc5 \x15\xaf\x97\xf0\x8a\x9a\x0d\x0f\x02\xd9\\\xa0\x06\xc5\xf5J\xc1\xcc \xe1i\x1c\x9e\xf1$\x85\xe6_\xc9\xad\xa5H\x15\x8b\xfa\x19SA\xf3\xed\"-Vn\xc0\xd2\xb4\xaa\xa0 &\xf9\x10\x1b\xf2+\xf8\x1e\xf8\xbeq\x02\xb7\xec\xd2>n\xd2K\x91\x08\x8aIb\x9b|-f\xab8\x89C\xe0]_Z&\x9f\xf2\xac\x07\xab6@s<\xd7c\xaf\xc9\xe8%\xa2\x0f\xe8tO\xf0LAi\x808-\xe8 \x9e\xe2\x83\xf1\xd6DP\x80\xb0\x9e\xae\xfa\xbc\x8f\x9e\xa1\xecB!bd\x8a\xb7H\x9c\xde\xf3 \x99\xe6\xa1\x9f\xb0 :\x8b\xa54\xc7c\xbd\xe7/\xde<\xff\xea\x8bgo\x8e_\xbc\xfc\xd1\xab\xe7\xcf\xde\xbdx\xf5\xd2\xa6x\x17\xad\x9e:\x01!\x8bA\xa5\x92\xe8C\x03\x18o\xa9'r6^\xa3J2\xf6\xd8s}^R5/R\x89/\xf8\x90*\xfd\xf4\xd8\x99[x\x15\x14\xeb\xa3Q\xe0\x06\xc7gzV-C\xc5\xbb\x02\x8dh\xa3\xae\x13\x14\xa8[\xe2\x90\xc5\xaa\x10\xf4m:\xb2\x97xT\xc7\x97Rf\xc6F5$s=\x1b\x9a\x17\x9d\xbe\xe5IB\x93\x000\x19&\xa6\xa9\xb8C\x8eV\xad\xa6'l\xdd\x93\xfa\xed\x92\x02\xfd\x8e'lyRT\x0c\xab\xd0\n\xa6\xb8qZ\xe3*5\xa0\xfc\xda\xc12\xbd)5h\xe8\xdc-O\xdf8\x16k,\"'/V\xf3\x16U\x82\xf21\\c>\xa9\xfc\x8f\x93\xe04\x88\xfc\x90T\xf8+n}\xc4\x9e\x99\x99\x92\xd5\x7f \xde\x83`\xb7W?\xcd\xb2\xa7<\xebr\x15T\x0e\xf2U\xc1\xe8\xbdr\xb8\x0b\xbb\xdc\x01[\xa2\xb3\x07\x89\x14\\L\x86I\xf5\xcc//\xfct\x8d/[\xe6\x91r\x12o~\n\xf7\xdb._\xb3\x900\x86\xfd\xa5{\xc00\xaa\xfa\x9d;\xec\x12-\xa5\xd8>{\x0d\xbc\xaa\xb4`\xc0\x1f\xefu\xb4\xc0\x9c\x1e\x86\xa8\xa3\x1cE\x99\x83\x006a\xd4\xae\xf2P\xa2\x15\"N(\x83\x80\xc8w\xee\xb0\x13q\xe6\xd3X#\xaf\xe8\x18|\xa5\xd7\x15\xb0q4j?\xb52M\xa0#\x16\x7f!\x10y\x0bz\x0f6\x02\x1b\xac2\xf9y\x91,\xa1TZRA\xfcW\xf0\xe41\xab\x08\xf5i\xdf\x15f\x7f\xc5\x18Glaf\x14\x87\xe1\x0e\x00\xe6\xc8\xd9\xca\xe5i~\xb6\xbe\xbc\x8fMV\xcd~\x95\x05-\x8b\x1a\x883.A8\xe5\xe1\xf1\xae\xe4d2\xe0d\"\xe4\xd1\xfc2\xc6]\xbdC\xeb\xec\xe9\x85\xa8[\xb6&7\xbfj\x93\xacmi\x11\xe4\xa3\xdcTp\x17\xf1\xcb\x00}\xf5\xfe\x9e\x83\x14\xbd\x95\xf5\xe0\xad\xb0\x93\xdd(\x87.\xf7\xdc\x91\xda\xef4\xb0r9k\x02\xa0%u\x8b\xb0\xb3bE\x9b\x82\x97\xc3\x8f\xd6O\x1f\x82\xd8K\xd8\x93\xdd-\xb1\xa0\xa1\xe3\x1210\xe6\xbe\xd9\xff\x95\xf3\xcc#\xfa\xac\x0b\xbfF,\x00\xd7UV\x12\x1b8\xc7D\xae\xa4]\x81\xe3\xab\xd3\x8e\xf9\x15\xd8\x89\x02\xe7\x9c\xca\x83\xbd\"p\x0e\xcd>\xfbE\xca\xad\x1c\xf1w\x86T \x10q$\xb7h\x99\xea\xe2-\xb1\x97\x83`r0\xf5WY\x9e\xf0\xb7\x99?}\xff.\xf1\xa7\x9a(\xa9\xe2\xab\xa3U#\x15I{D\x94wR\xd1n\xf3\x8aphH\x88\x90\xd2\x9a\x90\x89<\x0b\x07N*\xddm\xe5\xb8\xa9I\x8f\xa4\xca\xa9=hdR\x19\xd50\xc2\x9b\xb8\x81*\x1b\x0d\xa6\xf1L\xe0^\x0eWu \x08D\x84\x8c\xea\x9a\x0e\xa8\xd7\x90\xc7\x93j\x05\xdc\x81\xa5\x90\x02}\x85t\xd7.H\xf7n\x0e\xed\x15e\x1e\xc7#\xd6K\xfcozu\x1ae\x96=\x11\x18\xdf\x9b\x9d\xfb\x1d\xcaf\xc97\x97#\xd6\x13\xffz\x06\x8a\xf3\xc1<\x8eY\x9f\xf1\xc1\x89\x9f\xc0\x7fQ\x0eh\x83\xe8\xca\xec\xdc\x87z\xb7,\xb8\xdd5\xa2B5Hn\xd7\x08\x9c`\xd1\x10\x94\x17q\x02\xc3\xe4\xd6c\xdb5\xbe\x1blu\xb9.\xe9\x04n\xb4b\xa4M\x8a\x1a\xedV<|\x9c@\xfc\xd1qBX\x9b\xb6\x9a\xecD\xe8\xac@\xac\xebV\xf3\x0bd\xf8\x87\x8f\x99\xcf\x9e\xb0\xf41\xeb\xf7}y\x85\xadX\xa0\xfe\xc4\xc3\xf8\xd4\xca=Q\xee\x9a\xea\x13\xcd5KT\xe8EHL\xff\x18\xaa\xc3\x87CT\x1dj\"vT\x1e>\xdc\xfe\xd8\xcaCz\x12\x15\x8f\xa1\xf9\x96\xed\x15Z\xf5\x1ex[\xac\xceC\xe3\xa4\xd26X\xb7-P\xa6\x94#\xda\x00\xda\x96S\xbd\xe3\xb2\xd31x\xc3-\xe6\x06\x8fg\xeb\x1a\x9f\\\xab\xef\x04\xc5\x94\x9f\x18\x91\x97\xa6\xf0\x16\xda\xc8\x98\x9ak\x0e\x1c\x86}\xe7\x0e\x8b\xc7J11\x11\xebr\xdd\x10\xb9\xed\xa8)\xd0\xfc\x01\xe2\xbf\xbc.W\xb9s\x9b\xf9A\xa4V\xc3\xee\x0dV\x83\x82\xb6N\xe6\xd7\\+M{]R\xf6Ulz\x1b\xcae\x88Ju`\xf7R\xbe\xeb\xeby\xf38\xee\xdd\x8e\xaa]\x0d\xd3\x00\xa5\xbc\x0es]l\xa8\x1d\x11+\xcae\xf6\xf46\xf5\xef\xb5\xeb\xa4\x9er\xc8N\xe9\x80\xe6\xb4^t\xd5Y\x953\xeb\xaa\xcaY4\xabr\xce,\xaa\x9c\xda\xe7\x96]5>\xa7\xed\xc1n\xab\x15.I\x8a1\x8d\xa3yp\x9a\x83\xf6\x95\xa6\x1a\xbc\xd0\xce\xd2\xae\xaf\x95\xa7\xa4&\xba\x92\x1b\xdf\x164*i\xe3V\x98\xe2X\xac\x87\xb69\x185\x9c\xea\xb8\xd7;>\xe6\x1c\x0c\x07\x0e4\x07s\x90&\xcer\"\xe9rp\xe6\x87\xb9\xe0h\x16J\"sV\xab\xed\xb1K\xd7\xd3\n\xcab\xd1\x98O\xd8\x01\xe5t]\xe6\x88\x7f\xe8\xb1\x0d\xacO!u\x9f\x8dQ\x9b\x9aM\xca$\xe9\xad\xa3\n\xb1\x1a\x8d\x8f\xa6|\x04\x94\xbe\x1b\x94<\xdd'\x98z*\x80\x8a\x95[>c\xb9F]\xee(J5u\x8c5\xe0*\x992\xdah\xb7\x8a\x05\x07;\x02\xba\xaf\xa2i\xe1\xd4\xe7\xf8\xb8#(\xe6\xf3\x11\xf0\xbe]!!\x89\x04-\xe7F`l\xd0hS\xf1\xa7@\xd7\x97q\x80J\xc4r\xc7|\xd2\xa1\x9e\x896\xe8`T\xd46!\xc6\x14\xeb\x1d\xe0\xed71y\xc98\x98\x08\x1e6pY\\\xfa\xe5\x8d)\xb8b\xae`\x94\xb7\x95s*%\xd2\x97(\x98\x8c\x03i%7\x14\x88\x99\x0c\xd2\x15\xdc|\x0c<6\xa4\xee\xee\x81*-)?\x9b4~V\x8ac\xa3&\xeb\xf8\xb6iG \xa2\xdfzG\xf1\xac\xf0j\xd18\xef\x16:!\xb6\xe3\xb8:\xa1\xf6\x19\xa1\xe7\xb1\xd9\x19<\xccbD(\xc9d\xac6-\xde\n\xdew\xcc\xf0\xc8\x92\xb1',\x12\xd3\x9d\xb9,\x18g\"\xb3z\xd91k\xb8\x08\x07\x1f\x8d\xc1\x81\x05^h\x95\xedn=\x06\xc2\x1b\x8b\xca\xd8\xb4\\\xc5I\xa9\xc9!\x1b\x95\xbaTu\xa3\xac>\x96&\x00t\xb9\xb55+\x88\x0b\xe8\xa9\xec\x03c\xedw\x8b\xba\xdc\xc6\xaa~\xaf\xc6\xb0\xdc\xfc\xeb-\xb7\xad\x9a\xbe\xeeU\x84G7\xebK\xa7[U\xbf\x10\xfc\x14\xcf\xaa\x06\x05\x1b\xe6\xfd\x80\xfe\xf5\x81\xf2\xc6,8\x8b\xa9S\x17z\xe2^:u\xe2z\xba\xd8X\xa6N\xe0R\x84g\xea\xe8\xe6\xd0hG\xb8t~\xfe\x01\x85q:{\xdc\xec\xf5G\x19\x8bi\xa1*\x17N\x88\xce\x88\x8bSc5T\xa4\xc72e\xb4\xc4\xf6Y\xfe\x03vS\x8eY\x9e\xa3\xea\xb1~\x1b\x04\xab\x04\xdb,\xf88\xd2=q\xf9\xbdf\xe7\x01\x1a\xdd\x1f,\xfdU\xbb#hU\x81\x1d\xb0\xcc\xe1\xe3\x08T\xcf\xe2\x7f\x15%\\\xe9|\xc9\xc9+Zi\xf3\n\xff\x07o\xbdc\x0d\xc8\xbd@\xe0\xd516O O\xc5\xbe\xa1Zq\x05\xd7u\x12D\xb3\xf6P\xb6\xddg\x16\x8f=\x8f(S9\x9c\xa8 \x85\xff\xd7<\xd5\xc5(\xda\xe0\x10\xce\xfdv\xba\xdd\xe9 \xadD\xcb\xc8\x98\xe2H\xe6I\\\x0b\xc8\xd5t\xdcF\xff\xed\xe0]\x00\xe6p\x0c\x82d\x0fe\xc4\x13\xd7c\x9f\xc6q\xc8\xfd\xc8\x01V&+}.C\x01\xd4\x05\x81]\xf4m\x8cY\x13\xe4<\xdav\x07A\xc6\x13?\x8big\x8e\xc6\\\xca%\xfa\xc8fAN\x1a\x90\x1bK7\xa5\xe5\xc9!\xbd\xfe\xa7\xf2\x9bur1\xaf\xe3U\xa7c\xb5yX\x9e\xdd\xc6a\x94\xc8\xd7\x0f\xa3f.\x1c\xe6\x08\x1f\x8c\x1f\xac'\xf9\xeaQ}\xddET\xb2\xa5V\x13\xcaV]\xd2\xdbF]\x128Z*%\xf3)J\xe6C\xe7B\x06\x08\xbf\x90\x0e\x12\x99t\x19\x0eh\x0e\x13'R\x02\xf4\xf8\xec\x16\xbe\xf2\xaa\x8d[\xfc1\xc0 \xe8\xc2zF\x9c3y\x89F\xaeN4\xf7tN\xb5\x10\xc5\x82\xa4 \x16\xc9\xdb\xdb\xf2\xc2\x9e8\x9f;\xcb\n\xc71t!b\xd9>\xe3p\x19}i\xe1\x86\xf0T'\xbe\xda\xc2\x85W[\xaft\xaa\xe2f\xe4T\xb05\x91\xcb\x96h\xcc\xc7I\x0bJ\xf5\xc8\x91.\xc9\x02\xe6\xa5R3e !\x03\x7f`/\x040\x9f\x1bzdf*'\x9cs\xe8n2\xb1\xc2\x02\xe0p\x02f\xae\xe7\xf2J*\x1a\xd2\x08\x82\xa9\xe0#\x0e\xc8\xe2l~\x02\xce\xc5\x9c\x128\x1b\xc7\x83Y\x1c\xf1\xc7.(\xe0/\xd8\x81b\xe2\xd0\x1a\xf8\x18%&\xd2\x90\xbd\xf8%\xf6ogVHS\x0e=\xb6p\x96\xb02fp\xddJ\x82\xf9\xb0\xfe\xd1~\xdf\x125K\xcc\x1c\x11\"\xa84\xf7\x9c6`\x03@\xe0\xb4\x123\xdb\x1c=\x8c\xd7\x03\xb9]\x0d'\x0e%B\xc8Py\"GZ%\xed\xb3\xc3\xc1t\xe1'\xcf\xe3\x19\x7f\x969[\xae\xcb\x9e\xee\xb3\x07\x0f\xb6\x1f\xed\x82\xc5\x12{\xb2\xcf\x1e\xec\xee\x0c\x1fA\xf9Cp:9\xee\xf7\xa3\x89\xb4g0\xc0y(\xedG\x0e\xad <+Ax&A\xd8\xef\x9f\xd9\x81v\xd6\x82\x8e\x1a:\x89=\xf0\xd4D\xb8\x02z\xbe\xa3\xad\x9d\x1a\x00\x9dS\x97^P\xe40%4\x15o\xd7\x1d_H~\x00\xbb2\xab\xc8\xee<\xb6,/\x89B\x8c\x90\xa2\xe6\x0d\xf6\xf5\x9a\x96\xe2\xd1\x8e\xd4R\\.O\xe2\x10U\x12\x8f\xee\xdf\x82J\xa2v\xc2)\xf48\xb5-\x1e>[\x91\xc3\xb6\xe9vH\xbe\xcb\xdcb\xc8{(8J\xcd\xf9Bm\xf7`\xfb\xb2\x88\xd3\xcbx\x9a\xc9\xee\xd5\x8d:i\xf5\xa22o\xac\x9b>\xddD\x89\xa8\x97\xd9H\xc6\x95Q\x14,\xd9\x04\x953F~\x16\xbfV\xdaM(B\x95\xc0N\xbf\xf3O'\xb7\xc74\xea\xba\x0e\x8b\x8aC!_\xfdZL\xd8\xac\x90\x98v\xd54\xcc\xbbi.V\x84B\xc2d\xfa\xc2\xfa\xed\x90\x1az\xed\x1b\xe8U;\x97\x14X\xb5\x06\x1a%\x8e+=\xda6i\xa5\xeb\xeaf&\xe7`\x81\x9b\x80\xb3(\xbb\xef50}57\xbb \x92\xc0\xc5\x98c\xac?\x8c\xa1q-wF\xe3\xca)\xb4z\x98\x8f\xbb\\\x8f5\x89[\xbd\xb3\xfc\xd6:\xeb\xc3\xcdrP\x04\x01\xf4CG\xf3j!\xc5h\xda^\x0b\x01\x1a{\xa5\x15\xa1\xe0B\xa6ND[ \xce8\xfa\xa2\x0c\xe2\xe8\xf8x\xc4r\xf0/\x9aQ\xe6|\xc7\x91\xbf\xe4e\x993\xa7n\x02\xfd\xa1*\x1f\x99:q\xfd\x93\xf38\x11\xd5\x9b\xb1L\x0ez\x86\x8a0\xf87\xc2\x7f\xfb,v\n\x8anHE*\xbf\xdf\xf3\xcb\xcf\xbb|\xccb:\x0e\x8b/cA\xc4R`jgv!\xfel\x9cM\xd0\xd6\xb9\xd4\xdc4vm\xe1\xa7/$\x96(X&\xa8\x06\xd1r\xd0\xa2\xaf\xa7\xa5\x18\x01\xd3\x83\xf49\xc8\xaa\xde\xaeT\xc8\x97Zsf\x01\xd9\xaa\x99a6.\xf7\xb1z\x932Y5$\x7f\x1a\xd5\x97\x82\x1c\xd6\xeaB\x9a\xac\x08\xefF-\x19\x19\xa9VO\xc5N\xc2\x9a\xf2\x97Q7\xe5~b|\x12\x13eM\xfcaV\\\xf1i\xc0\xd3zMLUU\xf1\x17Q7\x0c2\xa3f\x18dE\xbd0\xc8\x8cZ\x1a\x0fP\xab\xab\xe5\xc8\x16\xb4\x14\xa2\x9d\x82S0\xda)r\x8av\x8a\x14\xa3\x9dW\xddS\xdfoT!\xeb\xc2_E\x95j+\xae\xd6\xb1\xd8\xde1\xfd\xcb]\xbe\xaa\xc8\xb7\x031\xdcQ\xf01\xa8\x91Q\xd6g=\xd70 \xad\xfc\x863\xc5\xaby\xd7\xaf\xa6\xb5\x98Z\xcc\x1c\xe5\xbc:\xcaXG&\xaf\x0d\xac\xea\xfa\x89\xfc\x0e-\x1e\x95\x8cw-B<8\xc8(0\xce\xd1;E\xf7\xaa@D\xe8\xd5\xb4\xe7)\x98\xf6\xb0B\xd0^!\xae8\xe3\xafp\xcct\x13UHPM\x94l\xf9M\x1cj\xe9\x02\xda\xdd\xb5=\x19\xa1\xdf3\x108P\x9c\x03\xba\xf6/\xf8\x06\xfa\x1c$'\xeb\xd6\x8dG[E\xfc\x1b\x1bx\xd9\x87D\x93\xab+\x91\xaf\xc7*\xc0\xb2o\x8b\xb2\xe0\xc6\xb4\x1e\xca\xe0\xce\x1dV-2\xae\x16\xaa\xce\xfcm\x0cYM\xa0a\x12\xa5>U]\xc6`K\x81\x12\x88.\xcb\xb8\x10\xc0V\x17\xb2\xe3\xae\x8d*Uk9\xee\x02x\xe2_,\x04\"gg\xb8}\xed\xa1\xd8\xdd\x06\xfdR\x0d\xb2\x12\xf2|\xbd\x01\xa6\x86CqX\x18\x88\xe6\xa6)\x88\xf2\xcf\xa1\x1d)\xb0o\xa2R\x0d&\xee\xedY\xcc\x9e\xe9^`\xd6\x1d*\xc1N7O\xef\x01\xb1XR\x9e\x91\xd7g\xe1\xaeQ-\xea\x9d8\x12\xd1\x91\xa4\xa0t\xe2\xf0\xc1)'.\xd3i\x01R\x07)\x071a\x06/\xfbP'\xe5\x10\x9d\\\xdenC\x15\xa0\xfa\x81%\xf0\x07\xdc9\x93\x01\x8f\xb0\x90\n~$\xca\xe0\xad)\x88\xd1\x0d\xfd\x94\x1f\xc8\xd0\xc1Dv;\x14k\x8d\x89)\x04 J\xdej\x1eb\xb5\xa0\xff\xbd\xff\xbeW\xcd\x97\x87\xa2\xfd\xf2\xd20\xc8e'\xeec\xb6\xb9\x99@D\x9f\xfe>\xeb\xfdw V\x00q4\x89 \xd9\xf77j\xb5\x19\xea\xf7%Ik\xbfB\xd8\x12\x95\xc3\xcb\xf0\xd6`\x82\xf2{A\x02\xb8\x18h\xac\xc2<\xe1@\xb3q\xbf\x9f48\xf61\xd0\xb5\xcb>Q\x8b'\x7f\xcb\x17\x18\x86\x86\n8\xae\x8b\xf8Z\x00mc\x1f ]i\x06*)3=\x82\xd3\xbc\xdd\xc5\x8beA7\x9f\xe6\x99f\xc2JwG=\x01\xd8\x8bZ\xb3}\xeb\"QOPD\xdf\xf2\x8b\x15\x13\x8c}\xb8\xba Fe\xaf%>-J\xda\x06\xc0\x14>>f1{\xc2|\xb6\xc9\x86\x8f\x9b\n3\xd9\xb0t\xa7\x07\"\"\xb9?\x04\xa0\xed\xe4\xe3x\xe2j\x0eW\xad\xdd+Z\x83.\x0e'\xa0C\xe9\xf7ckaS\x05\xa9\x1e\xf9\xad\x96>\xb1\x03\x15\x8eN~N\x81\x8fl\x97\xfe\x9a6*#\x9f\xb8M\x9eV\xd0\xc8jo)\xd0(@ao\x03\x1a\xe5\xcdh\x04\xd2\xc4\x8eh\x94\xba,\xc7\x10\x0e\xfd\xbe%\xf0PK`\x03@\x1ah\xe3\xeaJ\xbe\xec\xb3q\xe3DS+\xb3\x9ao\xcd\x9e\xc8\xab{\xe2;\xf2V\x9c\xc4\xd4M\xe9\xfc\xc3 \xcaI\xcfa\xd2c\x81\xf6h(\x1b@\xd5-i\xe4\x0e\x19\xa2\xa2\xc7\xf2\xf1P&~\xc4\xae\x17}\x1fN\xc6\x01\xe0\xb8\xff\xf8F\xfdv=\xd5\x18N\xe05\xf0WJ8\xc9p\x8b\xe6P\xd7\xf3\x8e!\xdd\xc74`\xb2\xdf\x8c\xc9\xb9\xb4/o\xc6\xf5\\\xe9\xc1\xad\xa5B\xd8\x0e:\xac\x05\xc9l\xf9\x02\xbb\xec\x8bAT\x81X\x80\xe3\xb4\x0b=\x0d4,\xedNO5\xee\xdf\x07t\xc8\xc7\x81FO\x9bIi\x88\x88\xe2\xa3\xa7&\xec\xebp2\x8e\x01\xe9\x82k\x10\xd6[\xe9Yq\x15\xb7\xe8\x8c\xa8\xaf\x0c\xf7c\x0f\x10Z\xe4U\x92\x1e\xb3\x0d(&\x15\xe0w\xee\xb0P\x117\x176\xdcp\xb0\x8aW\x8e\xeb\xe1\xa4\xc8_n\x87\x96\xd7X.\xda}\x80.\xeb\xa4\xab\x03\x16\xc9\xa7\xe8|\x89\xd9\xfc\x0f\xe8_7\xe0\xca\xaa\x9a\xff\xbd-y?\x11\xdd\xd2\x0e\xc0\xa9\x9dt\xec|\x93+\x89k1q\xfa\xb7\xd79\xca\x81\xc2\x9b;?\xff\x00\x84\x92;/\xfd\x97x\x0b\x91;;\xf7\xbf\xcf\xb3N\xc1\xf5o\xec\xdf\x8e\x1c\xac\xca:_\x13\xack\xf2\xc6u\"y\x1bl\xb1F.2\x0f,\xe1,fpU\xe6-.\xb9\xb4h\x1cwZuU&\xab\xcd\x7fh\x8642\xc1\x03W\x84\xbf\xfa}\xee~\x9c\xbdP\x93XA\x10)\xd8\xf87`\xa0x\x86\xaf\x12\xab\xa8\xf2\x9b\xa0\n\xb7Ct\x08~\xe5#\xd0\x9b\xdb<\x05\xd2B\x06\x1a\xd5#++j\xe3\xe3\x08x\x10%\x83\x1b\x1e#\xad\xbe\xaf\n\x89@\xc1:\xa1\xa142\x11\xbc\x95\x89h\xdc\xa6\xb3\xca6\xddr \xeb\xc434\xb2\x96-\xfd(\x97\xb7\xfc\x8c\xf5\x10\xd6\xba\xd2\xad\xc7\xa9\x02\x9c\xd2\x00i\x0b\xaf\xdcD\x8fY\xae\x81\xb3\xe0\xc0\xfd\xb2\xa7\xa9\xe4\xc0s\xc5\x81\x8b\xbcT\xe3\xc0surH;\x9c\x1c\x9aN\x0d\x96\x13\x03\x9c\x16R\xf8\xe8p\x02N>\xfa\xfd\xbc\x0b\xdd\xbc\xce(\\O}\x06\xce\x11\x99\xc7\x02\xb0/\x10hHxN\xee@\x0b;a8\x1es\x91\xcb\xc7\xc1\n\xb2\x14\x82\x18 \x93\xc7\xbbk\xe3<\x9e\xa1B8C\xb5\xb3\xa6)B$W\xc1\xbf\xe5)\x0d\x91\xdf_\x03\xf9eo6\x1a{\xd3rd\xc8\xf4\xcf\xe7&#\x9b\x13,r^e\x91\xd3*\x8b\x9c\x16,r^\xfe\"Xd\xb3ekO%G,f\xaa#xn\xb0e\xd9 9\xbb\xe6\xf2\xf2t\"nv\xf5\x07\xf4\xaf[\xda\x03m\xbe\xc1\xe9\xcb3;C\xfa\x82\x9b\xe9K\\\x1aY\x1a\x17_R\xdb\xcd\xb7j\xb1\xf5\\\x84[6m\x88\x16!\xe3\x18\xb4\xdcx\x97B\xd3\xb9\xc7V\x1e\xd8WN\xa5\x81\xa21\x1f\x8b\xa6\xcc3\xd0n(\xc7sf\xfe\x12\xf2\x95\x13\xc6*F\x97\xf5\xc0$\xbc\x99\x97S\x9cF\xe9_\x98\xc4\xad\x04|C\xa9\xa8\x0ep\xaf\xd4*\xa9\xa7\x9d\xad0\xe5\xb1/A3\xbb\xb4`\x9f\xb7<\xb69\x14[\xc3\x99\xbc}2/\x9c\"\xac\xc4\x9b\xa9s\xead\xb1\x1c8\x1a\x00\xd9Y\x83\xe1\xf2\x87\x1a\xf8\xe2H\xb9\xe9m\x87]\xe3\xf5v\xf2\x02%+\xcc\xdd4\x17\x05$\xcct\xc3\xbd}6\x9e\x81\xcb\x8aH\x19\xf1!u\x8f\\\xd4\xc1\x01h \xeeM= nH`\x91\x89tb%}L@\xa8|e\x93\xdfbD\xa3\x1e\xe0?\xect\x94\xf2\x15\xbb\x901\x0d`\xbf^\xa0\xf7\x8d\xd2%2\xac-\xf4\x07\x1b\xe0~%\xbd\x19'\x10M!\x8e2~\x91A,\xa6\xe44u\x0b\xfb\xcd\x04\xe3G\xc4\x88)A\x89BbNlq\xa2[I#\x86\xfb\x96k\xab\xcd\x0d\xc7\x19^\x8c\x94F\xe1\xd6E\x11\x89\xa1\xf3jd-\xe9\xffC5\xcf\xb8\x1da\x14\xff\x8c,\x05\x1f\x043\xbb\xe4O\xfa\xc2d\x8d\xf1\xfc\x01\x03q\xbb\x13\xadaOf\xe3\xb4t\xdb\x8b?\xe2R'ct>\x03W\x9a\xa9t\x80\xc8\x0e\x98\xd2\xec:\xe0P\xdcY\xa0\xe0\xdc\xde \x86\xf6lbnG\xb8\xe2\x1b\x8bbh\xe7\x06Q_\x89Ri\x89R\xa9G\xaf\xaeXF6\x88\x8b;\xc9nCI\x14\xc3\xd5/\xc7C\xf5n\xd7\x90\xf5Gk\x8c\xb7\xdc\xb4gr\\\xe8)\xdc\xc2\xb5\xa1\x087wBy\x9b\xd9\xf4\xfeB\x1d\xb6q+\xa6\xa8\x00\x97\xbc\xb4\x94\xb3\xca\xae.U\xb3\x1c\xe2\x03NOp\xc9E\xb8\x00}\xcd\x05\xf9\xb2\xc5\xfd\xcc\x07OR\xd9\xb4\x03\x95\x85\x95#I\xe1\x1adr0=\xa9Q\xca\xc1\xf4\xc4-\x0d\xa0\xc5\xcf\x02\xd7\xf1G4\x08\xc4\x96)\x9d\xef\x001e\xa3\x12\xa9\x89\xeb\xe38\x8a\xc2\x9bu\xfbvA\xb0\xeb\x14\xb1\x9c\x01\xb1\xbc\xba\x02BY\xec\x9c\x0b\xdd\xabv\x95\x84b\xa2FEU$\x19 \x98 n\xb1\xf5^\xb9\xbcn\xa7r\xa2\x0bD\xff5>\xa6\xe8\x0f4\xaa\xba\x13\x0b\x8cl_\x1d\x92\xce\xc8\x9e\xf3\xa2\xe7&\xea\x1ac)~\xde\n3k2\xad\xc8\xcc\xee\x191\x18\x03\x99^\xbf\xc4\xed\xcb\xf4\xba7]\x15K\x8c\x0epc2\xb9\x1dn\x0c\xc5N/[p\xf0\xd8/\xfe\x8fd$d\xb8X\x1fG\\\xfd/\xd2\xdd:[\xabB\x19val\xb5\x0b7\xc6\xac\xc4M\x99s\xea\xa6\x11S\xa62[\xca\xec_]\x0e\xac\x96)\x14T\x1c\xfc\xa3\n\xf2\xb3\x01\x91\x96\xe8k!w{\xac\x0f\xde\x1eX\x9f\xf5\xee*3\xcf3?\x0cfL\x0dv\x19\xcf\xb8q\xf1\x8d\"I \xee\xeb\xb65\x11Z\x02\xf4\xc2\xb0r\xc7/ES1:X\xf5\xa5\xc9\x14\xb1Q%\xf4\xe14\xc2\x8aC\x8f\xcde\x13f\x19\xd1\x95i\xabS&\xbd4`\xee\x98\xb2\xb7Q\x8f\x18BH\x04\x9c\xfb\x12yj\xce\xb8\xf8=b\x9f\xf1\x8cO3>cy\x14'3\x9e\xf0\x19\x13\x88x%\xb0\x8e\xdd)\"sC\xf8\x9e\\t\xcec\xe7\x8b`\xba`A\xc4\x002K\xff=O\x19F\x1fc3hMpC\xf1\x9c\xa5\xf9t\xca\xd3\xf4\xde\xdc\x0f\xc2<\xe1,X\xae\xe24\x0dNB\xce\x9c\xf3\x05\x8fD\x13wu\xec\xbe\x0b\x13\xeb\x1eE\xcf\xe3(\x0df\x80N\x04m3*?\x1c7\x1f\x1b\xc6 \x15\xbd\xc8\x02\x89\xb5N\x0e\x84'T\x9dc\xac\xf0\x96:\xbbh9S$k\x9d)H\x13\x97\x8fz\x8a\xa8\x8b\xa6\xa5\x90\xe0#\xe9\x89\x9b\x14\xb7JOY\x06\x90k\x06[\x86\xe7\xe3\xfa\xc5\xfc\xea\xe5\xf3\x9b\x03\x88p}\xa5NYm\x91\x96\xad\x86*\xe8\xf9\xfdV\xe7Q\x9c\xca\xd6\xbf\xbd\xd1\xe8\xa2\x1f\xaf\xe28\xe5\x15\x19p\xe8\xa6]\xfc\xd3\xa2\x895H\xad\xcd\x89\xa3\x0eC\xaf\xfd4\xe5\xb3B\x10\xa3\x05\x84\xc6K4\xc1\x9c\xcf\xea\xf1\x8cn\x17~{\x86JG\xcc\xf3\xbd\xf1Qt\x94\x1c\xe5\xdb[\xdb\x0f\xe1\xef\xa3\xc9\xbd\xd3u\xc1\xac\xd0_\xcc:\x89\xfb\x85\xc2\xe2)\x1bnm1\xe5\x80.\x93\x0eX\xb7<\xf6\xe8\x11\x1c\x13\xff\xdb\xef\xfc^O\xde\xff\xcf\xd4=iAq\x9b\x97\x8a\xfc\xcao\xbc}\xf5r\xa0\xc0y\xe9pW6?\x04\xc5Fm\x19\xdd.p\xff_\x83\x9cJ\xcf1~\x19G\x9b\xd3\x98'S<\xc6e\xb1DD\x17o\xf2N>\xea\x85\x8d\xdb\x88\x11o\xd3&\x96\xdf\x0b\x06\xb3 ]\xc5\xa6L\x85p\xa9)\xfaV\xb3\x81\x08 6\xa5\xa2\x9dg\xa7]W\xe0\xcc\x03\xa7B\x1e\xab\xf93\x05\x89#\xf8\xe4AY\x0b\xdbg+\xc5\x96.@\x89P,\xd0\xd4\xb2@\xd3\xe2\xc7\x01\xeb\xe1za#\x06\xbea\ny#\xeb\x8b\xcf\x17\x1d%\xf1u\x86\x0e\xd6R\x9e\xbd\x0b\x96<\xce\xb3\xf6sO!\x00\x8aH\xe1\n\xb7\xe9\xbb\xc4\xa7\x06y\x94\xf0\xb9\x18@\xf9\xcb\x81\x88\xa7\xe0UNt\xe6\xce\x1d\xd6\x8b\xf8E\xf6.\x98\xbe\xef\x81u\x90J\x86\x05\xa4\xba)\x12E\xc5\xf5\xfb/\x8f,\xcb\xbasa\xd9\xff3[\xff\x97\x95\xfe/\xb5\xfe\xb7hpj\xf3@.\xfb\xca\xd8f\x18\xef\xbf\xd0\x98\x8a\xb3\x15B\xc8\x80\x0c\xa7 \xa3\xd7^\x92A\x15\x05.\xf1\xcf\xb9\xd8XE\xb3g\x18\x1ct\x7f\x7f_\xcf\xb9\xba\x92Q\xdb\xcb4\xb1m\x0fvvv\xd8\x88M\x9d\xb9\x83\xa6\xe8z>\x1aGmI\xcc^\xb2}\xf6\xf3\x0f\xd2\xaf\xd6\x90m\xb23\x97}\x82\xd2M%\xaa\xa8\x03\x07t\xde9\x05\"\x18\xec\xd5\x15\x83\x01\xb2}\x0dK<\x16\xb4O\xbbE\xda!\x1e\x0d\xaa\xfb\x1aT\x1d\x0d\x84\x9e\xae\xb0\xabl\xa1h\xbb\xe6\xc4\xae\x8b\nA\x08\xe8W\xb1\xb3\x91\xc6\x03\xd2b\xae\xb2\x8c}'@Hu\x12O\x84\x1e\x0b5 \x05\xfc\xa4$\x9c\xa6\xdf\xa7\xea\x1eT\x839\xbd\x0d\xcd\xdaP\x96\xd5\xd1\x96\xdc\x8b\xd0\\I \x01bp\xec,\xbb4\\Ctn`\xb9\xe5c\x88q\xc6\xf8\x8b\xdf\xb7\xb2\x05\x1a\xbe\x98\xd5\x11\xf3\xd1\xda\\\xb3\xe0\xca\xa4\x01\x87\xd8\x0e\x9e\xb2\xb8\xc9\xb7\x08\xbf\x98r>K\xd9\xd2\xbf\x08\x96\xf9\x92\x15z\x8b\x0c\xa1\xf2}9\x1b\xd9\x1e\xde\xdf\xbb\xffpg\xf7\xfe\xde\xf5\xdbk\x07\xe76\xad\x17\xdd\xd5\xafx\x04bG\xee\xb8\x1d\xcb8R\xc4^\x9c\x14{q.\xdd\xc0Kk\xf258\xe5\xe6\x8d\xd8G\x13\x9bf\xc4\xd7\xdd\xfb\x02\x8b0X\x04\x99\xeaZ\xbb\xc1\xc0i\xf9)b\x0b\x12\xa3W^\x11\x0cr\x00\x99\xd2\x1d\xc2m K\xcb\xe46(\x9f\x83\xf6xW\xeb\xae\xb1\xb32\x044q\xf3\x01\xc2F\x9a\xc9y)\xff23\xd3\xa6\xcc\x10\xda*R\x1f\xed\x15\xa9\xc3\xedm\xb8\x0f\np\x02\x18 \n\x8e]\xae&\x02\xdcz\xff\xf7\x1f\xfc~\xafq\x1d\x9av\xef\x84\x1d\x85\x8e\xb1 \x82\xc178j{\x15D\x96a>\xabK\xb5\xea\xbe;\xd1\x05\x87\x1f\xdc\xe2\xc2N\xe4\xec\x0co\xe2\xdb\x93\xf4]/\x1a\xee\x1d\x1f\xf3\xf4\xcbx\x96\x87\xbcW\xa7\xda2T\x90\x1eJ\xc1EY\x0f\xc4\xd3k\xb2UQF\x00\x89*\xec\xb1X\xbd\x96\x1b\xd0\x07\x93\xdd\x08\x1cq\xb8}Pw\xf3\x1b\xcb\xac\xfb\xdb\x10\x95\xb3\xc8S\x1d\xc0\x90cd\x1f8\x12\x99r\x9c\xd2\xef+\xb5Ca\x9c\xc0\xba\x9f\xbe\xf5\x88\xe9/\xc7\x04\xa8}\x87&\x8b\xd3x\xb9\x8a#A\x0e)8\xa8\xe7\xd9j5b\x97\xc5\x0cZ\xcb\xf9y\xb6\x88\x93\xe0\x1b_\xf4\xe4u\xbc\xcaW#v\xd2\xbd\x1a\xff4\x8bF\xecx\x8d\n\xafV<\x81\x8fA\xcd\xf3n5\xd3\x11;l/\xf9,\xcf\x16/2\xbe\x1c\xb1\x8b\xf6\xc2\xa2\xd9C4{{\xdb^:\x16\xc5\xb7G\xecY{Q\x7f\x15\xfc&\xbf\x14}\x19\xb1\xe7\xed\xc5O\xfc4\x98b\xe9\xf7\xed\xa5\xe5\x91\xe4U{\xc908\xe3ox\xba\x8a\xa3\x94\x8f\xd8\xeb\xf6\nA4\x8fG\xec\x8f\xb4\x17|\x11\xcd\xe3\xe7\x18\xd8\x9d'#\xc6y{\x95\xdf\xc8\x97\xabw\xf1k_\x8c2\xebP>\x8e\xc2 \xe2?\xf2\xc3`\xe6gq\xf2\xa9?;\xe5#\xf6\xaeCE\x85]\xe9\x88}\xb9F\xf1\x11\xfbi{\xe9\x02u\xdf\xe6\xcb\xa5\x9f\\\x8e\xd8\xcb\xf5+} A1G\xec\xcd\xfaU\x11~\x9f\xb5W\\\x04\xa7\x8b08]d\x82\xe1\x18\xb1\x9f\xb5\xd7H$\xa6\xa4#\xf6y\xf7\xd2#\xf6M\xf7\xc2\x9f\xc6\xb3\xcb\x11\xfb\xb4\xbd\xc2\xcaO\xfc%\xcfx\x92\x8e\xd8\x8f\xd6(\xfe&>\x1f\xb1\xdfh\xaf\xc0/\xf84\xcf\xf8\x88\xfdV{\xd9\x05\xf7g\xd0\x91\xdfl/\x0bF\xb4\xe9\x88\xfdZ{Q\xb8\xc5\x17e\x82y\x1d\xb1\x1f\xb6\x97\x8f\xcfxr\x16\xf0\xf3\x11\xfb\xed\xf6\xc2\xf38\xce\xc4\xc2\x8c:,\xb4\xcf\x830\xe3\x89\xb6\x9a\x93\x0e\x95^\x0b\x88\xe3t\xc6\x1d\x8aO\xf3$\x1c\xb1\xa0C\xc9t\xba\xe0K\x81\x83~\x87\xc2o\xb1\xb0\xd6\xf7\xbcC\xade<\xe3\xe1\xe1\x85\xbf\\\x85|\xc4\xc2\x0e5\xbe\x145~\x9c\xf8\xab\x95\xf8\xc6\xb4k\x8d\xe7q\x18\xfa+\xb1F\xd2\xaeUFl\xde\xb5h:b\xab\x0ee\x0f\xa3|)\x9b\x9eu(\x8e\x8c\x8e\xac\xb0\xe8P\x01\xcc6e\xf9\xb3\x0e\xe5\x0bg\xf7\xb2\xce\xb2S\x1dd\xb8F\xec\xb4C\xe9w\xc9\xe5\x8b\xecU\x9e}\x9ag\x99 \xeb\x97\x1d\xea|\xe9'\xefg\xf1y4b\x17\x1dJ\x7f\xea\xa7\xfc\x0b\xff2\xce\xb3\x11{\xdb\xa1\xfc\x8fx\x92\n\xde*\xf1O\x97>\xae\xb7\x11;\xe9^\xf1m\xe6/W#v\xdc\xa1F\xb1a\x1c^d#\xf6\xc5z\x15\x80|~\xd5^\xe7\xb5\xa2\xb7\xf0\x91__\xa3\xc2\x8bh\x1a\xe63~\xb8\\\x89\xd9\xfcq{\xcd\xa2{\x10i\xe4\xc5\x1a\x154\xaap\xda^\xed3\xceW_\x04\xd1\xfb\x11;\xef\x00e\xc1\xff|%H\xda\x1f\x1d\xc8\xd7\xe6\xb2\x02ap\xeb\xc6\n\xeaw\x03i;;}\x96\xa6\\p\xf8\x87E\x87\xc8\xd2\x9d\xe4\xd8\xb4\x9frV;K<\xef\xa4F\x88:\xb5\xf5\x9eh\x8b\xd4\x1c\x8dg\x05\xbc\xd9\xbc|M\xcbW\xbf|\x0d\xcaW\xeal\x8az@\xf9\x8a\x87\xbb\xb0L\x88<6-\x7f\xad\xca\xd7E\xf9zV\xbe.\xd5k\xe3\x89\xf7\x15\x87\xe0\x03\x8f\xa8#/\xe6m\xef\x1a\x11\x8e\x8a\xbc\x9d\xedz\x9e_\xe4\xdd\xdf3\xa2\xe5\x14y\x0f\xef\x1b\xf1\x80\xca<\xe3\xf8\x1d\x96yF_\xa6E\xde\xa3\x9dz\xde\xbc\xcc3\xfa\xb2*\xf3\x1e\xd6\xf3fe\x9e\x01\x97\x85\xca\xbb\xbfe|\xef\xac\xcc3\xda\\\x16y\xc3\xadz\xde\xa9\xca{\xb4c\x8c\xef\xb2\xcc3\xc6pR\xe6\x19\xdf;.\xf3\x8c1\x9c\x17y\xf7\x8d\xbe\x1c\x96y\xc3z\xdeE\x99g\xcc\xfb\xdb2\xcf\x80\xcb\xf32\xcf\x98\xf7\xf7e\x9e1\xef\xcf\xca<\x03.\xaf\xca\xdaq\x07\xdc\xebv\x11G\xab6\xcd5\xd9\x1amW\xc7\xceQzs\xa8\xc5\xe8=}\x10\xa0\xad\x1a\x04D\x10\xa0\xadj3b\x1a5w\xc9\x807\xbfU5\xb2\xf5x\xfd]ugDN48\x81\x1eD\x837\xf0\x03tX7#\xd7\x12\x8e\xa3\x00X)\x8d\xb3\xdb\x87.>\xaa\xdd\x02\xb2\xaaM\xf1\xc1\xaf\xf3\x14Y\x11\x8f\x84)\xc3\xf6\xd4j\x82\x10\xaf\xb4F\xf5\x98\x06z\xc2\xff\x8c\xf9H\xf5-\\j6\xaf\xbe&\x13\xc9\xd0\x19\x14&\xc5\x1b\xd3\xd1\x0c\xc6\xc2\x82D\xff\xda\xaalar\xad\xaf\xb54\xe7\x05ab\x9b\xe7\xac5\xd6\x1a\xec\xe4Y\xe5\xae\x1d\xb1s\xdd\xc7\x01n\x96\x06\xb8\xa9\x0c\x106]\xb7_$\xa9\x86;\xb8\xbfg0\x14.\xe7\xac\xa9\xcc\xb93D|\xc1\x83\x0c\x83\x9b\xd1\x1b\x98\xa3!G\xe2\xac\xf3\x00x\xcf!\x85\x97\xb0|\x0e\xcb^\xcf\x05\x8c\xea\xbe\xec\xc3\n&p\xed\xac\xa7\xcbY\x1f\x96\x8c\x8c\xb0\xaf\x86\x10+\xe6^\x99\xf4-\x0e\xc6\xb5p\xf7\xc7A<\x87\x0e:f,\x06!\xbdM\x1d\xd7E\x0f\n\xcd\x10\x88\xb3@\x17\xadi4\xc0\xab\xe8>\xb0\x01q\x8b)Q\xa4\x19\x944b\x924}\x9f5W\xc9%\xa6\xe0\xfd7!\x1b\xd5\x8d\xcd\xc9\xc6\xb3\x9d/<\xc10{6;\xc9\xe3\xc1B\xd4\x89\x9c!\xab\xc8\xa6NyT\xeb\x07\x12\xef\xd0\x19\xed\xed!)\x15\x14\xf5\xd9\xa6 \xac[\xe2\xef\x9e\xf8\xfbTKh?p\xf3\xc46]Y\xc0\x95\x87\xcd\xec\xcb0\xbf\xb5\x88i\xbc\xcb\x9a\x83A\xa0'\xd0\x92$VI\xe8BO\xb8\xd7\x82u\xa9\x14\xcf\xf9zU\x87r)\x1a\xa9\x96_\xf3N\xb7\xab\xe5+A\xe7\xab\xe5KQ\xbe\xe3\x0e\x12ZQ\xcb\xde Z\xbf\xe3:U^_\xf4^\x9d\xda\xb9h\xad*Y\xde\x88\xf2*;u\x88\xb1ws+\xb3\xf2\xc3[\x1eI;\x8e<\x9aT\x82q\x9e\xe0#\xb1\xee\xe5G\xaf\x18\x05\x17/!\x01\xf7\x9c\xdb*w_1\x0f\xa9(b\x0f`\x1fw\xc9\xc5`Q~p\xcc\xd8\x97\x8e\xdd\x04T\xef\xcf\x0e\x8a\xdd\xc9\xc9\x00\xa3\x8f]S\xa7\x8aG\xea\x87QC\xa7\x9cZ\x17\xed\xa6\xa6\xa13z\xe6*\xb9\xcbg\xad\xac\xfd\xe4\x87:W}\xb82\x1b\xc3\x1b\xa2\xe1\x08\xc2\xe5\xbcb\xf4]{>\x8a\xb5\xf8H\xff\xe0\x11\xd3\x0e\xafi\xc8M\xdb(w;\xbbr\xd5\x94\xa7\x9a\xa0\xf7\xe6 \xc8\x9f\xab\xe8\xf7\xa1q\xce\xd7\xf5\x8c\xa5P\xcc\xa3\xe3t\xd6\x0e\x8fi\xa9\x8b\xea\x84G\x11\x1f\xb6p\xa2)\x0f\xa7<\x98\xd3\xa6`\x85 M\xf0\xe9\xe0\\\xebM\x0bH\x83\xcfCt\xa7\xd4/\xc0\xb5\x08xH\x07\xe7\x9e\xbe\xc6]\xb3\xc5-\xa8\xd2#O\x18z~\xcd\xcd.\xd1\xd0\x91\x0e\xce\x93RZ\x8c\xbcE\xa37\xb9\xfc\x08c\xd8\x82|F\x18\x817\xba\xc2\x98\xa5\x0b\xe2[nq\xe4'\x11\xf1.ps4W\x0fDu\x86p\xcd\xb5=\xac=\x8fV\xc4oH\xede\xde\xc1\xea'c\xf2\x0c\x1at:\x9b\x02v\xe8\x14\xfb\x07\xda\xb5\xe2\xaf}tj\x15\x0e\xb2\xac>\x97\x83\xc6\xe0\xa0\xb9\xbd7\xa0aJcG\xf0\x1f\x19\xba\xbap\xdfPo@o\xfd\xd4\x11\xeed\x9d\xa1\xcb\xeb\xb0\xdd\xa6\xd8\xe2\x07\xce\xa1\xd3\x15\xfbn\xc3\xbb$~\x08\xde\x9d\x17\xd0.\x0fI\xcd\xd6\xf1\x83\x13rk\xd8<1N\"\x9cA\x13\x87\x9f\xd8\x81\x13\x9b\xa9\x01T\xf7e#Xp\xfc\x1d\"\xe6'&\x11\xe8\xdc.\xd5\x8f\xde\x95\x07\x9f\xd4\xf8\x8d\xc8\xb7\x08\xaf\xec\x89 O\xec\xa08uR\x94D\xad#\xff\xd8n\xe4\xfch\xd2\x0f\x9e{\x15\x0e\xce\x8d\x01=\xc3bR(`\x8b9\x19\x8e_\xfb\xb1\x8b:q\x19\x98\x99o\xac\xe2\xf0\x03\x8f\x84\x8f1\x8c\x98`\x1e\xe6\xe0\xa7 \x0d\x16\xb60\xba\x08\xe7\x0f\xe8&=i\xcb<\x81\"Z7\x9f\x85\xe77c\x08\x9b9\x93\xf3\xf9X\xcd\xf1\xaf\xfb\x18\xb8r\xf9i\xc7\xb1\xa4\xf9E@\xe0|\x14\x01\x9e\xd9\xf7#\xf1\xfd[\xb2\x01Gy\xbe\x8c/?\xf9]v\xc6\xe4\xe8\x1fr\xf4\x1f1\xfc\x0e\xfb\xd01\x8d\xb7\xdd8\xc5\xf8\xec\x13i\xb1~\x0dk\xf7\xd98\x7f\x8deQy\xbb*\xfe\x11\xb8\xd7O\xac\x1b\xf6RD.>\xe9\x83\xdc\x14\xdd>t\xcf/\xbbn\x1f\xe6\xdc\xd5Jx\xcc\\\xfaU\x17;=\xfaP\x07\xd1\x84\xb7\x9bc\x8a\xfcY!.V\xa0\x1f\x15=\xd7\xe0\xa1\xa8\xbb\xfa\xfc\x107O\x925Ppv\xfc\x97z\xf2\xf2\x92\x84\x8b/\xfc\xc7\\\xf2~\xf8\xeb\xbaV\xf9R\xad\xcc\x19\xc5b@nq\xa5&\xd4\x1d\xbb\xaes\xa2\xc4\x8c\xaa\x8d\x8f\x86\xe3fQP\x8ar\x07\xceJ\xae\x9ak\xd3\x15FWe\x9dtGI\xce\xca\xcey\xb67\x98\x80e\xd4\\\xe3\xd9\xc9jq\xe9\x07\xd9\x18v\x16\x8b\x9f\xe3\nL\xbc\"\x97\x8f\x841k\x80\x7f\xad>K\xd8\xb3S1\x8f\xceH\x0dTS^\xe7\xf2>Bti\xd2\xdc\xcb\xebH\xd6\x11\xaa\x10\xe48\xcd8$\x82\xe8\x18\x89\xb9\xd4\xc1\x84\xf4\xa6\xea\xb8\x89\xdd\x14\xe9\x07\xa8\x98\xa18Q0\x04\xecG\xbc\xaf\x1a\xb9\xf9#\xc6\xa4\xe0\x93#\xf1D\xc5\xe6\x8b\xc1\x82\xad\xb2\x15\xa5\x8b\x08\x0f\xfb\xfb\x80>r\xfc+a\x1c4\xbd\xe1\xbe[c\x0c-R\x9a\xe4\xc2Y\x0c~\x82\x1e,\x06\xbf\xe1\xffx\xbfr\\E\xc8\x0f\x92):)\xbd\x1c:\xcf\xf6\\G%\x15B\xbb\xba\xeb:j\x11\xa9*Xy\xbf'\xa5\x1e\x15rS\x9d\x1a\x83N\xd3\x1aK\xfe\xe8@G\x98@\xd1<1\xf4\x14\x10w\x1d\x1e\x8aD\x8bg50\x15\xc3u2\x06\xe0\xce\xb1k\x1d5.w\xd3\xb0\xc5\xa8n\x9cL\xee\x8d|\xd9Nro_+\x9aV \xe9\x1c\xb3\x86\x1ao\xc8N\x06x\x84\xbb\x03\xdc@\xce\x95\x8a\x15\xb6i\x91 h\x9a\x92\xca\xa9\xea\x0f=N\xb4R\x83\xd2\x92\xbb\xf2Z\xb57\x91\xa8b\xd6\xd8\xf8\xed\x05UIFm\xb9 A4iI\x90\x0f2\x96\x8b\x99\xc5\xbaf\xa4\x9c\x9d\"\xed\xd5\xac\x18|\x01\xf6\xc1\xef\xf5\x9a\x19\xc0\xc4\x90\xb6C\xfd\x88\xec\xc9\x9c\x02\xb2\xbd\xd9\xeb\xf5\x0be\x19\xc3\x88\x96\xa9\x0e\xd4O\x82\x9cE\x92'q\xc8D\x12\x89\x8d\x0d\x94/b'lb\n\x8d23\x084W\x9a\xd2\xd6\xd3eG\x90.\xc6\x03\x1e}\xc2\xf1\x07\xd7m\xcf\x95\x98x\x8d{\xf7[!\xba\x19\x8b\xa3\x07`\xf1\xc3q\xab\xbe\xea\xc5\xb6\x03\x8b2O#\xdd\x82}\x05\xa2\x81\x08\xc0\x1b\xd9V@!A\xf8\xf5KmMtgu\\\xdcuc\x94\xc1\xf2P\x93\x1b\x1f\xb9\xce4\x8f\\P\x87\x9cG\x12\n\xc3\xb1~%e\xb8\xa1 P\x8c%L\x85\x9aT\x03\x12lg\xd4\xa2\x9dt:\x9c\xa9m\xf5!\xd5gd\xc7\x167[\xb6\xc8Z\x19i\xda\x15\xe5\x86\xd6\xb7\x1e\xd4:\xfb\x7f\xd3\xd8\x87xj\xe8i\xfb\x0bzb\xffo5\xf4'\xea\x180N\xe9B\xc4=\xc66\x94SQ\x8b\x91f\xbb\xb1\xea\x8d\\d\xb9\x1d\xc5\x14\x84\x83\xf7Y\x8a.1\xc7\x17 \x8d\xaf)\x06v\x88\x07\xbf\xd1\x8b_\xfc\xb4\xfa\xac\xfc>O#\xad\xbd\xde\xcc\xf0\x91\xf6z3\xa9^o\x86\xce\xb3-\xd7!M\xd7\xf9ZNX\x1ay\xb5\xca+\x19\xf7ui\x13\xf0> \xa5\x00\x94\xde\x88\x90*\xa4\x06\x16o\x00\x9e\x035&\x98\xe6J\xeeE\xd8G\xbe\x9c\xa2\xdd\xc5\x97(\x88\"M\xd2\x0cPEScl4\xc8\xa3\xd5cl\x1c$\x04\xa9\")\xb6\x8d>V/)\xb5\"\x00\xc2\xaf|\xca\xf8\\\x9e\xaf\xbf\x00'qy\"D\xdb\x9a\x90\x81\x0cv\xe9\x04\xd6\x06\xf3D\x1e\x1d\x9fcgH\xae\xfd%I\xa5n<\xff9HR\x12\xceI\x10\x85\x1a\xad\x05\xc6\x7fC\x83\x1ey\xda\x98\x00z-\xf2\x7f\xe5\x15\x1d\x83\x1a\xaeq\x8a\xf2\xe3\x89\xc8\xa5\xadu)|\xce\xad\xda\x8frU\x95.M\xb5\x06\x92\xfa\xdd\xb1\xe0\\\x94\xb6\x8b5\xec\xc3<\xf2x\x94\x1c\x1e\xff\xeb\x94\xde\xa6G\xd1\x9c:]\x9d\x8e\x92\x8b~\x81;\x888\xe5p\xd6\xba\xb0Q\xec\xe3]\x92\x98x)\x8d_\x93\x94\x8c\xaby2@J|m\x00\xb1\x1e\xccI\x8a\xb7\xbel*\x8b\x06\xfc\xd6\x12\xe1\xbc\x0f\xedf\xbb\x16A\x08\xf5\xdd/\xc21\xc4\x06~\x0cS\xb2\xf2\x9d\xd4\xb4D\x80\xfb\x8e\xc7\xb2b\xef\xc1>\x86\xcf\xa5<\xfe\x0c\xcf\x0e\x1a\xa2\x9e\x1c\x1f\x19\xe6\xd4\xea\xdch2\xbd2\x9c&5\x93J_o\xa8\xc5\xc5\xef\x9a!\x8fLA\xae\xda\x804\xd0\xfe\xdaN\x95,\xb0>\xc1,\x8f\xa8\x15\xf1\x88Zq-D!W\x07\xe1ej\xcaD\x06\x8cf\xbapR\x0c\x93\xaaa\xc0\xa2p\xe1/\xb3\x98\\p#\xdb\xfa\x12/i\xda\"\x0c\xa0\xa2\x0djB\xcd\x07\x9e\xff\x8d\xeb\xa87\xa13\xaccm\xd5\x89\xc1\xf2*\xcbm\xa2\x8aNc'\x1e|\x80\x1e\xc4\x83\x8f\x16i^\xa4\xf7j+\xe8\x10\xa1\x9e\x8b$G\xc1\xf6\x82/\x7f\x18\xa4\x9c\xd0\x84\x1e\x9a\xa0c5E]\x08\x93blF\x93\x17\xf1\x1aOH\xe0\xb8U\x11\xd6v H\xe5\xa8\xb6\x82\xee\x1a\x8f1\x99}\xf8\xee\xe3\x12\x91\xd3\x1e4,\xb3\x96\xe8;\"o\xddt\xcf\xcfM\xf7\xca\xe8xbA\xc44n\x8d\x84\x11#\x11\x987\xda\x88n\xbe\xd6\x92A*\x00\xc3\x01E\x93\"\xa1u\x1d\x17r\xb0\xeb\x84(\x9f6k\x04\xdb\x00T\x82\xce\xba\xde&b\xf4\xd9A\xa32\x99_\xc2\xe9*\x15\xbb5+J\x0c\x01?\x88\xe9\x92\x864f\x0c\xd8\xc7,L\xfd\x15\n\xdd\xc2\xa9gIS\xc5\x95\xe7\x88\xach\xe2\xc4\xee\xc0\x0f\xe7\xf4\xf6x\xc1\xda\xaf\xbe\xdcu\xe1eM\xe3\xe5\x83\x08c\xa7\xeb\xae\x809&{\xd1\x0d\xa8\xe0c\xcb\xd6\xb7{\xec\xd4\xc2\xb4\xec\xfa\xb7\x94\xc8\xf9\xc8;\xd5yx\x11}S\xf7~\xb1p\xc6\xeb%\xeb`\x8b\xf7\xb5\xeb\xae\xb6\xa5\x18u\xd6\xeel\xf4;\x0c\n\xa37tU\xaf\xf8`\xd5\xb1\x9c/v\xd95\xab^\xcb7\x91\xdd\x93\xbb\xd5E\x14\xc0D~\x19\xd7\xccVA\x9c5\xfe\xc0O9@\xd0\xbe\xf1?\xffS\xfe\xec\xd6\xeb\xa3\x8e\x92\x87}}[~\xa9T\xa6y3\xc17e\xb0\xc3S\xb2\x14\xef)%\x9a\xb7\xf0\x92*BX\x95\xce\x94zMOX\xf7\x99\x91\x15\x04\xc2z.\x04\xc8\xf0\xa9\xa8\xe9\xb9\xad8w\xc7\xd4\x0d\xecC\x80\xb9\xa6d\x93\x0c\xde\xee\xe0&&\x8c\x99?\xaf\x93))\x03t\x93,Y\xd3pN\xe7')\x89S\x0d\x0c@H\x04E\xcd\xbf\xfa4\x98\x1bj\xa2C\n\x8f\xa9\xe4\x87:\x90\x820\x06\xefz\xd1j\xcd\xf6\x92\xa9\xa5k\x9ePA\xfbl\xa5qC\xc4\xf2)\x995\xd1Bhb\xce\xf4\xc0Z\x16\xbbfI\xd3\x0fr\xe3\x1c/\xf4#\xbc\x83}X\xb2e^:K\xe7\xbd3\x9d\xb9\xbaKS\xf48\xb9C\xb3(\x14n\x85pw\x87I\xb3ej\x91;\xcd\x8blD\x17h\x9c\xad\xde\xf9\x1e\x96~\x95\x028;+M+\xb7\xa5\xfa\x17\x15\xeb\xed\x93>\x9cT\x8an\xfbp2M\x18\x88o1MW@\x90\xc6\xb3\xe5\xfcIb\xa4(\xbf\xf8\xa5\xcf\xd7mp6\xc3\x83\xd2\x19\xb2\x0fW8m\x8c'\xaeu+\xb5!j$n\xe8\xaf\x9cs\xf5\x0d{dh\xed\xde`\xa7\xf9\x04\"t\xca\xe2\x1e]\x0f\xb9'\xcbU\xcb\"\x9f\x0e\xe5\x8e]Jk\xfa%\xd0\"\xf7+\xc4\x8f\x8b*vuY\xd97 \xb2}\xb8\xc8O\xe3\x074\xd6\x9d\xf2\xd3\x18\xf2\x01Ur\x1e\x82\\\xe0+z\xd7\x9c\x8a\x04\x14R35\xa46\xa8\xf9\xaf\xa7\xd2\xa8\xc4\xba\xbe\xec\x94\xbe\xa6qB\xab\\\xb4\xfa\x91\xa3\x83f;>\x91\xd9@\xde\x1d\x19\x15\xd4\xeaG\xca\x06\xe9`\x1d\xadMZM\xf5\x83\x0c\xb5\x98fn\xd0\xc3\x91\x08\xd3h\x84\x1c\xb5\xb8\x91\x92^l\x94\x1f\xb3\xa5\x1c(\x02q\xde\xde\xd0\xd6\x9e\x96Hx|`l\x91\xdf\xf7\xe1\xb4D\xe8\xf4\xa0Q\x0e\x8c1\x9c\xeaW%\xa6 m\xb4\x02\x91\x1f\xccz\xc1\xedp\xe8\xb5b\x9a%\x14y\xf2gBCy\x81;8\x17?B\xf1L\x81'\xffM\x03\xba$\x18\xa5\x84'\x92\xc4\xd2\x15\x86 \x95\xd9\xc0\xba\xa2\x94\xc4K\xa5\xa54\xbe;\x0c\xd3\xd8\xa7\x89\xcc\x97\xec|p\xfb\xd0i\xb0h,\xa2\x9d\xb3uG\x91\x17\xbaiWxo\x88P\xdbCW\xe1N\xb8v\x86;Kux\xea\xb4\x9eL\n;\x12 \x86X\x1d\xe1[i :z\xf0'i\xb4n\xa1\\\x03i\x00\x95\xa3\x8f\x19\xb7\xa5\x0dU\x05H\xd3\xe1l XP?\xb2\xb8\xd8`*}\xd4\x93p\x98\xd0\x01\x1eJ\xf2\n\x86-\x82\xf9eU\xd3\x14_\x93zb\x020\x83\x821\"L\x8c<\xbc\xf5\xe8:\xc5\xa8\xb4\x0f\xc4J\x06\x9c|\xa0v\x00\x156\xdf\xcd\xb4*vL\xa9\xf6\xd5\x8f\xd4J\x0d\xc4\x96\x140\xecC&\xf0\x16m\xc4\xc5NA\xef\x11\xae\x04\xaf\xa3\xba\xc4s\x86\xcc\x1d\x8b_\x85y\xe4\x12\xc5\xfd:\x1aHg\x9d\x0d\x18=\x07\x1fU\x11\xcfacC\x1b\x17B\xfd\\\x8b\x1c\xffU\xac\xf2\x1b\xcc{@H\xb1\xa4\x15\xf2\x81D\xc08\x8a\xc4\x9e$\xac\xb7w\x91\x97\x13\xe8\xd8\xe9\xd2pn3\x1d\x97\xad\xc8W\xe1\xc5>\xe4d\xabi\xa2 &\x8b\xb9kD6\xf4>tQ\xc3\xf1.\xf2\xba\x96\xd3M\xfd\x04\xe5\xd7\x85J\x18\x1bhw,\xe1\x9dm\xd0f\xb4P\xa3\xcc/0=/\x1f\xb0\x02\xb7\xa2\x10\x1d\x10\x9a\xc7\x01\xda\x96\x8b\xb9\x94\xdaV\x8a\x1b\x1b\xfe\\\\z&\xdfs\x8a\x8d\x0d\x7f6i\x1et\x1f\xbc\xa3\x0d\xd4\xfc\x1b\"\xf7F\x1a\xdfA\x92\x92\x94b\xd6\xf4\x1b?\xbd\x8c\xb2T(\xc5\xa2X\xde\x07\xb4Yy\xf8n\x10\xb7\xd6\xb0\x98\xf9?\x84\x84\x93\x8b8[\xa7-l\xac\xe5G\xe15\xed\x94*\xcc)\x95\xf1Z@~r&\xb0B\xa9B\x03\xbf+?\\\xb9\xaa\xa1\x18\n+\x10W\xb6rny-\x96*.-U3VI\"m\x10\xe8\xd5\xcfEL\xc9\xd57]D@}&\xa6)\xc5\xc6\xc5y\x8f\xfa\x02\x99>\xac+}z\xf0\x16Q\x01\x0e\xc8\xd4%\xbe2el\xcc\x17\xac\x9c\x05\xdb\xe5a\xe2s\xd7\xd7\xfc`@-^#wA\xe4\x11K\xfb@\xc4a\x99\xf6\xb11\xc7\xc2=\x8a\xa3W\x1do\x1f\xae]a\x0e,GA\x1d\xf2 \x06N\xbe\xf6\x00\xa4\xff\x16\x1cVi\xc58<4\xcb\xc6\x1fLJ\xf3\xc7\xf6a\x0c\xe2\xea\xa3R\xd3\xc9Y7\xb9\x83\x04\xf3\xc2\xfe\xd6\x98s\xd1D\x19\xc0\xfctf=\x84Q\xbc\"A\xa9\x07y5\xed\xa8o\xa4n\x1f\x0c\x1e\x7fz\xa0/\xfc\xd0O\x1a\xfd\x13\xf2\xda\x05\xc7o'2iNd\xda\xf9\xd3k\x88L\xda\x82\xc8\x84\xea\x8e\x11\xdbKe\x9csL\x0c\x95\xad\x81\xc9\x89\x17)\x8d\x19e\xe9\xa3\xe3\xb8 h\xf0P\xb2\xdd\xca\xdbC~\xfe\xfd\xa0)\xa8\x92\x80d;\xa2\xcb\x8d\x84\xdb\xb2\xa4\xa0\xd9\xb5\xb1\xd8\xb5\xcd\xfd\x81\xa26\x8b\xed\xbb[\xfd|0\xd9d\xab\x1f\xfb\xb1\x0e\x05\xc10\xcb\x11\xf0\x85GG\x8d\x0b\xf2\x03&\xca\x07\x82\xef!iJW\xeb\xb4\xfb j*\xb5\x01x\xe32\xae\xea%\xad&\x82\xea\x0eR\x94\n\xf6\xe5\x91Woc\x8c7`\xe7\xecc\x9adAzDVt\x0c\x0d\x01-\x18]{\x17yc\x83m\"p\x85\x0e?\x9d\xb8\xe2A\xa1\xab9u,\xc4@\x03q\xac\x95VM\xc0J?sy\xf6\xbcA\xcd+q\x95\x9f\xf1\x8a\x9eI\x89\x0fs(\xf2\xe6\x1d\xea\x01Q\xcb\xa7\xe9D\xaa\x82[\xfb\x0e\x11Z\xe5S\x07\xef8\xa7:[f\xb1\xc8\xfe\xe0\xdc\x0f\xaf#\x8c\x02j\xb3\x15P?\xb9\xdd\x80U\x8b\x99\xb7f\x8a\x95(?\\s\xc8\xd6n\xae\x11\x08rm-\xf8 \x90 \xa6d~\x07q\x16\x86~\xb8\xb4\x89\x01E\xabZc\xf9jU\x95\x1e\xe5\x19\xc6\x0d\xd9\xf0\xe5GL\xf4\xadA9\x0e\xcd\x9a\x85\xb0\xe0\x00\"<\x96\x10O\xfd\xe7\x8d*Z\xc9\xf6\x85\xf9\x06m&\xef\xa4\xa9Q\x10\x0dg\xe8\x14B\x18\x064\xd3W4\x96m\xd32\xc8\xca\x08\xe3\xeb\"\xafns\x1f\xa0(\x85\x1a+\x7f\xa9x\x06\x12\x13\nZ\"\x97\xc7\x85Pjb\xc3B\x0d\xdb|\xfe\xe4\x92\xb9\x8a]E\xa3\xcd0+\x90x!q\x92m\xbc\xcb~\x9b\xde\x01\x9d\xa9j\xba@\x07_m\xf0v\xe2C/1\xb6\xa1BU\xc3\x01\x97O\x9d\x82o\xe5\xad6l\x18\xd8\x87\xb9\xbd\x8a\xd4\x17\xdd\xe4D\xa8\x19\xb1K\xdcq\xd2\x9a\x99\x10\xc0\x957 \x13\xb8\x841\xac\xfb \x8e\x8b\x87\"i\xe3u\xa6\xfa\x11I\xfd\xb0\xabvZ06\xc6\xb1\x18k\xe3\x0b_\xb3\x07T\\MrQ\xc3\xc9\xf1\xae\x90Y\xa4ZV\xd2\xad\xc4\x8eX\x06F\xbaV\xfa\x99-}\xd8\x07\xe2\xf6+\xc97M\xc7\xf0\x8d\xed\xc42;S4\xaeX\x8ai\xb5$z\x99\xd7\x89\xc4\xcb\xdc\xb3\x07\x87\xd1v\xa6\x8d\x11\x1c\xda\x0eQ,E\xc3\x08\xdb\x0e\xab\x15\xd0\x0f1\x9e\xa0\xe1\xe1\xad\xed\xe1\x89\xed\xe1+=0\xa6R\x01\x91c\x9d$=\xb3\xfc\xce\xcal\xd8&?\"hg;\xf1Le\x83\x05\x93\x84v\xb2\xadW\xb7j\xee\xaa\x9f\xf0\x95\xc5\x9a\xb4Nu\xd4\xd1\xa83\xb1\x19\x1a\xe4]\xf9\xad,\x8d\xe9\x8dt\xa7W \xda\xc0\xc3A\xc9\xb2\x90\x07\xbc\x8ey\x90\xbc\xa6\xd7@\xe1:n\x1c:\x0dg\x18a n\xc9{Hr\xd5\xd9\xdf\x177Fm:\x04\xe5\xa8\xc9\xda\x13a\x10\xd7\x11 \xbf@n\x1e!\x14pE\xcb=\x8dE`\xa0(E\x03L\x05\x8bV/]\x17&r\x1dr\xef\xa2` \x9e>\xc8\xb8\xa3\xfaI\x1d\xb9\x99\xa8X\xa2V\xaf~~\x88\xeb\xae\xfaI\x9d|\xd3>\xacC\x17\xc6u\x10|\xd5\xd4\x93\xdc$\x01C\xc9'-\x07\xd2j\xc8\xcd\n\x04\xe2d-x/\xb1w\xd2Z\xb0\xf8R\xad\xb6T\x08\x14J\x06\"K;\x87\xa0\x8f{z\xcc\xa8B\x9dv\xb5\"]\x07\xd6\xc8/<\xec\xa6\xd4\x0bL\xe5\xfd\xacF\x11U\xb0\xb9F\x99\x13or\xea&\x0e*\xb3\x92\xb6`\xac}L:/\xc74\x10\x80\xa9^\x1f\x17\xca\xd8\xc2PB\xcc\xd5\xd0e\xaev\xbc6\xd3\x84T\xc3:\xe5\x1d\x943\xd0\x9f^\xd2\\\xa1\x02\xf3\x88&\x10F)\xac\xe3\xe8\xda\x9fS \xf0\x18\xdf\x7f\x0c\xbcA\x93b\xc8\x86\x0b\x9aH}\xdaE\x8c\x90*\xc7}e%\xc5\xa85\xf4\xb9&H\x0bz,\xf1\xcf\x02\x80Hh\xc5\xebK\xac\x81\xa8\xbc\xeb\x89\xf4B\x90Tm\xe0\x95\x88\xe0\xed\x9dt\x8a4D\xe8\x9dfx}!\xe2\x99\xa7\x85B_\xa8\x9b\n\xee\x02\xcf\x95\xb4\xa4P\xb2\xdb\x19\xe8f\xc0\xb3\xcd\x8f\xcb\xef6\xa0@\xbe\xfc|\xd0\xe0s\x1c !\x88#\xc4\xd4W\xab\x9d{lwa\xd1o \xae\x1d\x1e\x03\x9d\x0egu\xf4\xa9\xaf\xc3\x88\x9b\x9ar\xa0\xc9\xcbd\xcc\xc72\x9a\xb9}\xd8T\x1f\xabz|\xa0\xdc\x1d>\xd7\xd2c\xd1\xd6\xcc\xad\x9b+\xa19]\xdan\xce\x1f\xecs\xa6\xea\xed\xd9\xfd\xbd\xf6\xfa,\xcdMR\xa4L \xbd:R\x8e\xbf\xa5F\xf6\xab\xd1\x94\x0d\x03;\xd5\x0f\xac2W\xd8\x87\xa9}]\xb8\xa9G}e08\xacd\x92\x8f9\x10\x8b\xc8N M\x9d\xea\xfd\xbei\xa4\xef\xf5#E\xaaj\xd3\x16\"|\xa7\xc4p\x07\x81\xb4]\xa1\x12|\x7f R\x9fom\x8fJ\xcf_\x1d\x7f<,?/eU\x1a\xbc>|s\xf0\xe9\xdd\xe9y\xb5\x9fQ\xa5\x1fY\xef\xcd\xa7w\xefJ\xf5\xb6wJ\xf5\x82\x88\xcc\xf1\xc2\x94}\xa9>8\x08\x82\xfc\xd9\x01\xe3 \x8a\xc7 Y\xd0w\xf2]\xf9CWA\xb6\xa1\xfcV\xab\xcd\xb3\xd5\x1a\xb95\xf6\xa5\xfa\xfek\xf9P\xfeP+\xfc\xf5\xe0\xfd\xbb\\q-`\xb0W\x9a\xdb\xfb\xb7Go\xdf\x1f\xbc\xb3-G[0Z \x98x\x84\xbb\xedv\xd9\xb7n\xe9\xd9\x9a\xc4\x18F\xd1w\xba\xf8\xb5\xfc\x14\x93\x19\xcb\xe7\xe2G\xb9\x06\x99\xcf_\x95<\xa5|\xa7[.\xeb~\x93M\xfc\xb4\xea\x06\x1d\x15\x00-\x95\x8b\xb4Z\xdb\xfaDq\x08\xbdRyV\x80\xacT\x9eh\x9cE\xad^\xa1\x01F\xbd-\x15y\x18\x07\xbaL\xaba\x1f\xb6\xcaE\x0c\x81\xb6\xcbE\xf3z[\x97\xf5\xb6\xae\xebm\xad`\x1f\x9eL\xcfn\x87\xc3\x8d\xb3\xdb\xe1\xd3\xb3\xdb\xe1\x8fg\xb7\xc3Wg\xb7\xc3\xc3\x8d\xb3\xdb\xd1\x9b\xb3\xdb\xbd7\x1bg\xb7O\xb7\xcfn\x9f\xeen\x9c\xdd>{s\x96\xbdy\xf3\xe6\x10\xff\x7f3\xbb\x9f\x9ee\xaf\x9f\xb2\x97\xb3\xd7?\xbey3s&\x1dV\xf2\x8a\x97\xb0\x1a\xee\xbd3\x19O\x7f/W\xbb\xff\xdd\xadT{R\x1e\xd6R\x0c\xeb\xe9\xceY\xb69\xdc|\x8a\xff?\xab\xd6\xba\xc3Z\xfd\xb3\xe9\xd9\xec\xec\x1fg\x9f\xab\x8f/\xd8\xe3\xdf\x9d\xc9\xb8s\xdf\xe9\xdcw\xa6d\xe3\xefg\x1b\xb3^\xc7\xfd\xf3\x13\xbf\\\xf3\xbc\xa89\xfd\xbdh\xcfu&\xe3\xff\x98\x0e7\x9e\x91\x8d\xc5\xec\x1f\x9b\x9f\xef\xf9\xf7\xbf\x9fm\xfc_\xcf\xcf\x9e\x9cM\xc6\xff\xf9h\xff\xacw\xf6\xe7\xfe\xf9\xd9\xa0\xf3?g?<>s\xce\\\xf6\xf6\xcc\xfd\xe1\xcfO|\xddYqc<+F\xc3\xc2\x8an\xb4\xc5\xbf+\xd4\xbc\xde\xd4\xa1\xb1\xa9gEK[\x9b-Z\xba}HK8\xbe\x87\x8e\xf5\xc4\xd8\xc3\xf6v\xd1\xd4\xb3\x91\xf2}K\xe9b\xb3\xf4c\xa7E\x87\x1a\xbd\xbaF\xc5,\xc7\xf0\x14^\xec\x0bgI\xf6mg\x0f\x13Zn\xb0\x07cx\xb6\xc7\xca0\xaa\xf8\xd6&\xdc\x0b\x9bF4a\x1c\x0d7\xd1\x9ca\x83U\xea1\xb0\x8cacd\x1d\x98F\xff]\x8c\x82Or\x02\xdd\xb3a\x97\xf7\x9c\x97\xfc\xff\xb0@\xadr\xc1JF\xa3]\xa5(\xc5J\xd5\x82Q\xbe\\\xac(\xe4EjK\xd7X4\xdcT\x8a\x16\xbc\xd6\xb6R\x14\xf3Z\xa3\xa2\xe8\xff\xcfJ\xb6\x94\xd7\x00\x0b\x8a\x97\x1ew\x1f\xc3\x18\xb6\x95i<\xc1\x11\xaa=\x9d\xb1\x92=e8\xff\xe7\x7fc\x9d\x1d\xa5\xe4\xff\xc6:\xeaL\x91*\xb0\xd2\xa7\xc3J\xe93V\xda\xedZ\x17\xe1\xc0\xb8\x08\xb8\xfe\xbb;;[;0\x01\xeet\x87y\x0b_]\x92\xf8U4\xc7\x9c\xa8c\xed\x83\x9d\x9d\xcdg\xbb\xd0\x03\x87!\x0eka\x17^\xbe\x84\x11\xe3uvv\xb76\x87\xe5G\x8f\x18\xbc\xb7\x14o\xd9\x82_\xcb\xed\xe4\x8e\x85\x9a\x043\xee9\x9b;\x8c5\xfb\xa0);\x054\x97;\x85\x17\xb0\xb9\xb3\xfb\x1cN{=\x17\x8e\xa7\xa73\xd8\x87+\xe7\xd4\x85 \x8c`\x0c\xc3>|(\nu\xc4\xe9\xbdV\xc1\xa9\\\x94Dx\xdf\xc7\xc3\x17\x0f\x16~@C\xb2\xa2\xa8,\x0b\xd7Y\x8aN\xb4Q\xe2\xa7huH\x07\x81\x1fR\xb5\x0c6D!:\xd0\x97\xe6^\x1f\xcb[\xedX8\xcf,\xc6i}\xff\x0f\xed\xfbt\x10\x85\xbf\x918\xf4\xc3%w\x8d\xce\x7f\x8a@\x85\xa8U\x12\xed\xeb\x16\x87\xad\xcbQMe\xc4\x18\xb7\x9a\xd1\x99V\xb9{]$\xa4\xab\xcb\x8e\"7\xf0>\xd0\xc15\x8d\x136\x8dG\x8f8$\xba\xf3l\x1d\xf8\x1eF\x1d\x84h\x01\xff\xc1\xba\x84\xb9\x1fS/\xf5\xaf\x91\xc7\xe2IC\xf2\xa4:\xf9\x9b\xe5\x9a@<\xc6`&@o\x89\x97\x06w\xc0d]\x99\x03\x12\xe3E\xb3A\xb0-\x85w\xe0O~w\xd8\xa17\xeb\xb9g\x03\xf9\xed\xcfO\x06\xf4\x96zN8\x1d\xce\xb8\x17\x1b\xef\xc8\x0f\x82\x8dE\x14\xaf\x98\xa4\"\x1a\x04L\xb0I\xa1>Z\xc6\x8e!\x03\xf96L\x9d\x18\xc3B\xe2^\xf1\xcb\xe5\x9b\xb2\x9c\xcf.*z\xcbB>\x13r\x11\x88\xf6%\xccD\x9f20\x1b\xe7?\xe5\xc3}\x081\x12%\x1dx\x97\xd4\xbbz\xe7\x87\xf4\xc7\x98\x92+\x0c{\xc1v\x90\xec\n\x0d\xdc7\x8b\xaf\x7f\x88^\x93l\xcd8Y:o\xe8\xb4\xb4\xba\xd5\xccb\x07?=\x0c]\xea\xb8\xb2iX\xed\xd3\x83\x9f,\x8b\x9d\xdeDE\xc2O\x06\x988\x07\x08\xf2\xc7\xb8\x0e\x17\x83\x94&\xa9\x13\xa3\xa8][\xda\x94,\x81'o\x01g\xe1\xc7I\x9a7\xe8J \x94\xc6\xc0zI\x84\xeef\x90\x92\xe5{\xb2\xc6\xcb[9\xe2\xc7\xe9%\x8d)\x9a\xbb\xc1:\xa6\xd7~\x94%\xc1\x1d\xcc\xa9\x17\x90\x98\xce!\xc9\x16\x0b\xff\x16\xa9b\xf71\xf4 \x86\x1e<\xee*\xc3x\xec\xf6\xe1\x9c\x0f92\x0fy\x1dS\xd6\x8c\x93P/\n\xe7-\xc6,\x07;\x8dg\xb6xr::\xfa\xd1b'\x89\xb7\x0cy>\xb5\xf2\xba\xa2f\x10^\xe8QA\x18\x93Ib+\xdcH\x11q\x8c\xd1\x81\xf1(\x89\xb8\x83\xad\x8fw\xbfB\xed\x06\x11\xbc\x00\x9f\xfd\xe9\xed\xc3\xc8\x15<\x83C\xb0\x8e'\x8e\xb4\x03\x06PW\xf0~/\xf6y|8\x82|\xcfh\xb4=\x1a\x8d\n`\xd3\xdb5\xf5\xd8\x9e\xb8&\x81?\x87\xbf\x9c\x1c\x1f\x15\x11\x0cuv\x8bhp\xb5\xe2\xab\x96)4\x84-E\x92\xc6\x94\xac\xd0\x16\x89\xf8a\x02a\x14n\xacc?\xe4[=o6\xd1\xb6+n=\xd8\xbc2\xd3\x9ai\x96\xecu\xb1d5\x87M\xbc\x7f\xe1\xeb\xd5\x87\xa0\xdc'B8\x1e\xf8 \x17\xfd\x9cP\xc1@\xa1\xaaY\xd1xIaE\xd6k?\\&\xcf\x11\xdb\xc4\xdd\xd6\x1c\x92(\x8b=*.9\xd8&P\xc9\x1aC\xc3\x8c\xaf\x1e\x13\x16\x1d\xc58\xf6\x8a\xdea\xa2\xb7|A3x\x01\x01\xfb\xc3\x17\x14\x9dd\xa6\xd9,\xdf{)\xda&`r!\x1e\x95 \x9c\x12\xb6\xeb\xf9\x0fU#\xae\x03\xcf;\x05\xa3\xd5t\xaa:P\x05}\xf0\xeax\xcd\xb0\x90\xb3MN\xa4\x9e2y\xc4\x11\xf8\x07\xe6\x83N\xc9r|GV\xc1 \x8a\x97\xfd\xcd\xe1ps\x8c\xf0\x13\xa6\xf3u4gm\xf3\xf4\xd2~\xc2\x99\"\xdf\x96\x958\xe0\xe0\xf4\xf0BL\xc2.\x80\x17\xe0\xb1?\x1cv\x12\x17\xfci0\xd3\x9b\xe4!\xf6\xe6\xd5\xeau\xf09\x1d\xfc\x91\xf0\xbb\x95$\x8f\x82\xcc T\xa7X\x13^\xe0p\xbe\x08\xd8\x1e\xc3\x0c_5\xd6i\x1f2\xfe\xa4`\xb0\xca|\x01\x9dK\x14\x83+z\x87!M\xd2i\x84\x17\x7f\xf9\xadM8\x8dfZ\x01(\xb5.\xfe\xa7V\xb2\x94\x102D\x8aMN\xa3\x14JR\x8c\x1c\xf32\x15?{=&Vl d\x98\x80\xa3>\xea\xe7\xa2\xa6\xb5E\xce\xcb\x15\xaf1\x1e\x9d\x83\x87\x00\x02\x16\x9d\x9e\xd8\xf6\x92\x84\x8aSx|\xd6\xc3\xe4C\ng\x8a\x13\x90\x8dY!\xf37\xd3\xd9]J\xc69\x94\x19\xfflSx.\xb2~GZchqyr\xe8D\xees\xd7\xd4Z\xaf\xa7\xb6\xa7\xdd)\xb8\xdb\xb6\xb8he\x08\xf0?\x8f,\x979mz\xd6\xbe\xfc\x19n.}\xc62\x8c\x86\x05#7\xda*\xbe\x8bb\xc3\xb8;7x\x14\xe12\xd6k t>a\xf2\x90f@\xf7!fx\xc5\xd7\xfbm8\xe7\xe6\xcd\xc3\xe7R\x90e\x0b\xa0>d\x95\x1f<\xed\xcf\xba]\xb6!8\xf4b\xba1G\\e$/\xf8c\xcel\xce\xe9\xc2\xf7|V\xec\xe3S\xe4\xfe\x91k\xb3b\xe5\x1b\xc3~\xed\x8bD\xb3r\xc8ZR\xd0q\xb6wpl\xa6\x8d,2\xe7n\xefr[\x01\x0c\xfd$\x84\x96z]\xe81\x82\xdaTe\x93\x13\xc1\x90m\xc5\xad\xbe\x80MC\xff\x9d['u\x1bd\xc8\xbfke\xc0QNjTf\x81\xeb.R\xcc\xda\xcfc\xce\x15\xcf\xe2AL\xd7\x94\xa4N\xf7\x0c\xcdd`\xa3\x94(K\xd7\xf5\x8f\xda\xae\xafE\\A\x89Q)\xd1X\xe2\xf9\xdck2\xf4.\xaby\xb3A\xa8\xa5u\x99Q2M\xae\x11\xeetQ\x08\x95\xbcM1=\xfe\x831\xb8\xf2;;,\x88\x90 \xda\x11+lk\x9b\x93\x13\xfc~\xebX_Dtp5\x97\xbe\x92\xb9\xed\x0c\xfbP\xa6\xffHbY\xf1\xc6\xc8\xad\xef\x96}\x06c\x99\xbb*\x0b\x82v\xa3\xafu\x9f{.\xf0\x0d\xc2O\xdf\xdf\x04q_\xf0<\x1e\x1d\xcc\xce\xc2\xbb\x92\xc8\xe1\x96\xc7\xd7\xa6\xf3~q\xd8#-\xc8\x8f{1\xa5\x97\"^\x8c\x00\xb0+\xce\xb1\x0b2W\x89\x00\x93Z\x08$\xf4o\x19\x0d=\n4Lcm\x94\x80|b\x15\"\x93ji\xa9$\x01\x9dL\xe0\x08\x13\x9c\xd0W'\xc7\x1dd'\xe8\xe0\xca\x0f\xd1\xaaG\x8e\xa0\xdb/6\xd3>\xe3\x0c\x9b\x18\xca_\xcd4*g1\xf95\xbev\x07T1\x9dMq\x8b\x9f&N\xf3\x11P\xd8\x0f\xe8\xdaQ6\x0c\x9b\xbfI\x03C\x84X\xc9\xafv\x18U\xde\x15\x1cP\x9b\xd3\x82\xf1@\xc8\xcfw\xcc\xdcA\xe5\x851lq.)b\xef\x12%\x01g\xb7\xd3\xe9\xb6o\x85\xbf\xd1\xedC\x99\xd11\x98<\x1b\xd9\x816\xdd\xd5^\xcc\xd9\x00\x85\x0b\xd8\xdd4\x1e\xfd\n\xe5(lF\xd8\xecc\x9d \\\xdaem\x86W\xb0\x89Y\x98K\xb04\x9cK\x9d\x80\x10Do\xfc\xf4\xd2\x0f\x81\xc05\x8d/H\xea\xaf\xd8\xcaW\x15<\xa6p \x82sS\xe6\xdb\xb9\xe5\\\\\xbe\x9al\xaf\x11\x98H \x98,\xa5\xceC\x08\x90B\x10\x06z\xeb\x05d\xc5\x11pE\xe2\xab\xa4\x9b\xa7k\xae\xc0\x82\x1dP%\xf1\xa1\x87\xc9\xed\x84bG\x95QCR\xd1\xe9T\xfaL2\xef\xb2$r\xcb\xcc\xe5U\xf4\xe1\xa4\xbd\x1d\xdc\xeb\x0b\xdd\xbc\x9ew\xb9R\xaa\xd0\x15\x18!\xb5\x08\xa2\x1bF.\xd9v\x8d\xe2\xd2\xf8\xcb\xab\xa6#\x7fx\x90u\xce\xf5\xfd1x5\xc0h\x8c\xf6\x1b\xb1\xcb\x03KH\"\x1a\xc3\xb8\xae\x06\x0b]\xa5F\xaep\ng\xa8\xe6\x1a\xb3]*N\x89\xa2\x16+\x93Ou\x8f\xeb\xf2\xb3\xac\xcf\xb5mY\x98k\xd6\x94UG\xcdZ\x88\x9a\xb5\xc7\x98\xda\xdeJ\xbc\x7f6\x13o\x0dY~\xca\xc9r\xf8\x15d\xd9\xcc\xc8\xe8Is\x08\xa2\x86J\x9e\x0d\x03(af\x15\xab\xe5\xc6\x0d\xc5\xc6\xe5\xa2f\xe7\xc4 \xd9\x0en\xd3\xa2\xf6\x84U\xb6M\xae\x03)\xf6cy\na4\xa7\xb0\xca\x92\x02\xdfH\n\x01%I\x8a\xaa{E\xcbV:\xa6\xed\xbb\xa9a\x81\x7fS\xb4a\x9as\x01\xddqQ\x1b\xb6\xea\xc3\xb2\x0fw}\xb8\xe8\xc3y\x1f\xae\xf8e\x94\xe6\xd0~o8\xcc\xff0\x1c\xe6\xcab\x07~\x92\xd2\x90\xe6\xb2\x12\xff\xe5t\xa35\x0d1\xbfx?\xc7~~}\xa3@A\x16\x08~E\xfe\xcc9\x15^\x80jO\xd8Gc\x88u\xc1\x97-\xf8W\x11q\xad\xca\x88:\xefs~\xb5\xcc\xbe\xc1\x84\x03\x01\xd3_\xa9B\xa6\x90:\xf0\xba\xae\xfa\xf0\x85P\x84\x9d\xa2\xf1\xa5\x8b\x17\x1e\xec\x85\xd3\xfa\x19*N\x14\xe4\xa0\xee\xefq3>w\xcb\xc3\x9b\x14\xa3[q~\xec\xbb\x0c\x12\xc6\xd8\xbcn\xfdV \x832\xbfg\x83\xf4\xf3\x1b\x9cS\xf6`-6\x15\x93\xfa\xce1\"w\x0et/'i\x98\n\x80\x1d+}\xb8*\x1f5\xa5{\xc4\x1cR0\x01\xde+\xca^W\x08\x9c\x87\xdc\xb1\xf4\x0b%ob\x96\xce@X\xee\x98%4\xf6YXBr\xcf-\xcf.%Nj\x9f^[\x9f\xae\xacO\x97\x86\x0d\x08\xc2\x8eF\x97\xa7\xf2\x0b\xe4\xc7\x85PY\xb7\x93\x1f3\xa3\xe7\xbf\xf4Vn\x16'\xfbB`\xe6B\x1b\xa9\xf0\xb4\xbb\\(@\x81f\xe7\xa9\xf8~\x7f\xcfhyl\xb5\x84F\xad\x13\xd2\xc1\xb0\x0f^.\x02\x1auP\xea{\x8a\x80\xd7\xe8F\x880n\x03\xb1C'c\xfb\xdcP\xb5\x81\xbfR?l\x84;\xdc\xde\"s\xe1\xd6\xd4y\x85S\xce9F\xc2X\xf8\x94&k\xe2)\xa7\x8f\xaa[\x05td@\x0e\xfa\x8a\xdemp\xd3\xea\x84\xae \xf7\xf0\xc8\xd9\xe9\x8b \xf2\xae\xa4\xd6\x9a\x1d_(l9x\xd7\xb0\xe8\xc3\xbc\x0f\x97}\xb8\xe6w\x05n\x1f\xf7\xc6\xb5\xa0\xd2\xa2\xe8N\x109\x81\xdc\xc8|\xb2\xbf\x97\xf9\xfe\xc57$\xc1\xb7\xc3\xa5e\xf2+\xa6\x04\x88\x97vF\xe9\xba\x91Q2\xe5'a\x80\x17\xe6\xa0\xce\xba\x19\x17\xf8\x9d\xd8\xb3\xad\xbe\xd0\x83sM\xac.P\xbd\x85\xf2\xb1>G\x9b\x9caX\x1beQ\xf9a\x1d\x8e6wD\x8fC\xde\xe3?\xda8\xf4|\x01[\x15\xbb}0\x80\xa1|\xf2\x0b\xfc_[\x19\xab|\xab\xb1\xbd\xda\x06\xbc\xe2\xbe\xb0.\xbe\xf2\x9b4\x8e\xbb\x97%\xdc\xbdVp\x97\xd1\xdb\x1c\x7falR\x1b\xc7\xe6\xc3d^\xf0\x1f\x9c>\x82\x17\xadV\x04.hzC\xa9P\xf8xQ\x10P.\xc0R\xeeD\xc8H\xa3\xc7\xb6\x95H~\xc9\xc5=\x1f\xef\xd99\x9a\x88\x13a\x0dm//@F*%\xf6\xeb\x8a\xd4\xcdU\x0e\xe5\xeb\x84@\xb9N\xf0\n>%Q(h\xa9\x19\xe3\xc2\x97\x05z\x02\xf9\xe5H!\\ \x8ew\x8d\xe4Xj\x9b\xdb\xe0Qe\x04\xba\xb1/\xca$\x9f\xad1\xd2\xb8\x18\xe9\xbc\x874d\xc1]\x81'\x10\xf3{\x13\xac\xc0\x17A\xa9\xc3*\x89\nI\xb5ga\x1e\xde\nI'\xe0\xcc\x1f0G\xd6-\xd6\x1f\xb5\xd8\xb3\x0fQ\x13W\x90\xb1\xaasd-\x9d\xb3\xd1\xa2\xee\x83 \xd9<\xfdn[R]\x15T\xe7f!\xd5$\xf0y\x96g\x0b\x0c\x8a\xab}\xb4\x86Z\xfe9\xf9\xd1\xe9\x01 \xa7\xa9b\x11I\xf3\"\xba\x82\x87\x7f0\xe1\x16\xb7\x08\xa4\x15\xddntP\x04I\xa6\x95\xab.\x8f\x04$.S\xacnW\x12\\b\xf0deC\xdb\xde\xb2N\xbf.h\x89\x1bU\xe22\xfc\xdcg\xe4k\x82+-\x1a\"\xc8\x7f\x8d1\x80\x17\xc7K~=\xcd\x99\x1b\xef2Z!w\xb3B\x86\x92q-\xfe\xc2\xd7[\xe1A\xb3\xd8\x83b\x80\x83\xc4\x83\xbbI\xa0\xbc\xc8\x93ne\xb9\xb3D&\x9d%6F\xbfF\xf1`\xdf\x18\x11\xbe\x8e5\x0c^\x87\x0e1\xea\x16\xac\xe65m0D?\x0ey\xaf\x86]\x9b\xf9\xfe-\x89Y\xc6!X\xc7\x07_3FP\xc7\xd9\xb9q\x88r\xcf\xad\x19\x90aC*\x1b\xce0P\xc5\x1a\xa8j\xe4\xd37\x8d\xbe\x9d\xf2\xc4\xe9x5Y\xe9\x05;\xe4\x1e=\x92\xd6CDc=\xd4\x06b\xe6%\xebxP5{x \x0bdC\x169{\xc1\x1f\xb8}\xb8A\xd4[\xf7z_\xbc\xd9\xeb\xb3\xb3\xe3C\x82\xf3\xbe\xae\x98\xd3TLf\x02\xf4A\xe9\xc1\x1a\xc6\x8c\xb5\x1e\x8b\xb70\xc4\x88\xcc\xf1\xa8\xd8\xe2\x9c\x85M)\x0f\xecA\xed\xcd\xaa\x0fa\x11=\x01\xb6Q\x18\xc7\xb0\xca\xd9\xb8\x96\x83\xe7Zo\xf9\xe6\xc8\xfa\xe6Z\xf0\x8ccA\xed\xd60\xd1M\x17\x90\xee\xd8\xdaix^\x1e!\xb7\x16\xee\x0c%\xe9\xea\x8b\x83\xbbj\xfe\x05\xd5M\xf8\xdc\xfd\n\\e\x9f\x8fB_\xaaj`;\xa3\xb6\xa4\xd3(@W\x8ek\xc9A=P\xbc\xd53'[\xcf\xbe\xfez\x12\xdar\x0bUi!\xc6\xec\xbd\xfb\x9a\x0b\xc76\xe3\xb1\xb0\x1c[\xdc\xa0\xdf\x9a\xf2\x82\xd5\xfb(8\xf6\xd2\x821\xee\xbe\x01,e\x9e\xa5\x00\x8cE\x17\x18\x97\xe6Y\x85D\x19\n\x863\x0e\xa9\xd7\x8d\x83\xb7\xe6\xf9\xd0#1b4\xf6\xe3\xb2\xc3H\x88_u\xf0\xf2}\x94Kt\xfb\xfb\xfb%\xc3\xdfG\x8f\xb8\xf1\xe4\xc4\xca\xefK\x1f\x9f\x82\xe3O\xfcp\x19P\xf8[\x16\xb1\xaab\xedEBJ\xf3,5\x1b\xe9!b\x86\xbe\xd3o\xb1ST\x01\xc3\xb0k\xb69z\xb4P\xd3}\xfb]\x13\xa29\x85v\xd7\xb4\x18\x8fU3\"|W\xb3|\xd0Z\x8a6t\xabC2!>\xaa\xb16e\x9b-\xf6\xa2\xae\xab\x9bvW4\xae\x8a\xfd\xe6}\x98\xeb53\xee/\xca\x90\xfex\x9a\xcd\xdc\xd2\x01\xf3\x01}G\xd4I\xb6h\x11%\x9c\xd1\xa60\x83\xc3`\x93l/m\xa2+\xf1^.\xcal\xc3\x18\x9e\xee\xe4?\x99\xd80t\xe1%\xfb\xaf\xc5]Y\xc4/\xb4}n\xb4\x1d\xb1\xf7\x9eC\xb4\xb1\xe1b\xef\xaf\xda\xc2\x8a )0\xc1f\x1c\x1f^\xbc\x80m\x17z@r\x91*\xdf\x81\x97\xf4\x96\xcc\xa9\xe7\xafH`wiR?*(\x0f\x1c\xbf\x82/f\xbe\x85\xc3RR\x81\xab0\xba \x81&\x1eY\xd3\xdc\xd8\xd3\xd6u}g\xd8)iVPR\xbe\xf5M\x94\xb4\xde\xf0w\xa2\xa4\xf3(\xbbhCI+\x83i\xc1K<\x84\xb4\xeaG\xa1%\xad\x8a\x1aG\xc95o\x0e\xbd\xc6!\xad\xa7\xaa\xdb\\\x87\xd1|\xf1\xdd\x86\xaa\x1a\x1aie\xee\xc4M\xe0n\x85\xf5[\xe7\xc4\x89\x19\xd9l\xd3b}0\x0f2y\n|\x92<\xc8\xe2Ic\xfc\xd8/\x9b:)*\xf5J8\x16\xd5\x10\xf2q\x16\xe6j\x80\xb9\x18G\xc5(N9\x93T5}8\xab\xde]\xd5\xd9U\x86&_j\x8a\x82ZWO\xea[\xd9IiV\xce\x99/\xba\x19z\xdd:^3b1\x88\x9c8\x1ew\xfb\xe4D\x1a\x85\xde\xad\xa7\xc5\xf7\xedM\xa5|\xab\xf8.\x15}\xf8cW\xad\xf4L\xf9\xae\xd4\xd9\xdaS\xea+\xe5\xcfx\xa8\x07\xcf\x8a\xe5x\xe2\xec*\xdd\x0b\xb5\x99\xc7u\xf4\xb7\xcd\xdbHHg\xf7\xf7\xdc\xbe\x8f\xa1y\x8b\x8d\xd5\xcc\xaeD\xe8K^fw\x85\xd5\xba\xd8`\x9e\x95\x0b\x11\xd6\x19\xd6Dp|A\xbfh\x8a\x16\xe1YI\xaf\xb8\xb5\xd3v\x10\xf6\x01\xa0\xafL\x8b>\x9b\xb4\x12\x8dGM1G\xafY\xfb\xc8\xda\xbc\xc1\x8a\xcdV\x10Y\xaef\x91\xd74\x8a\xf1Y\x90\x17p\x95\x89rrn\x8cjw\xd4\xfb\xf6\x04o\xf2C\x14\xf9\xfd\x8b\xb5U\xe2#S:X+\xda\x839\xab\xc0\xe7\xfe\x1f\xdcx\x80\xd1'u%\xc4\xfduI\xe7\x16|{=\x8e\xbe\x14/\xc08/\xc3\xe9gg$y\x191\xde\x0d\xc8\\\xdb\xe6t\xfbp((\x9fS\xae!\x0c\xcd\x0c\xcb\xd1\xe0\xf2`:\x11\xabC\xedtr2\xc2]\x82\x05\x99Y\x94\xe8\xcb\xba\xaeQ\xe1\xacH_ZQr\xf2\xf7\x87@\xa1\xdc\xd1:\xf7f\xc9\x8d\x0d\xba\x93.\xea\xa6,u\x95\x12q\xb3[\xd8\x81\x15gur\x19e\xc1\x1cmu.\xc95\x05\x12\xdeI\xcbk\xbc\x84\x95\xfe\xde\xad\xaf\xbb\xf3{\xc5Buv\x9a\xcf\n\x8d<\x85\x8dg\xa5i1\xean\xa7[\x14\xe8\x9d\xcd\xba\x93n1S\xab&y\xc9ugw|\xed\x85\x11\xd2\xe9\xdd:OZ\xf7\x1c\x96\xf0\x02\xee\xd8\x1f\xf4\x1f\xb7\xd2\x1c\xe7\xa2\xde\xcet9s\x072\xe0\xbb2u;\x9dPp\xe2b\x90'lW]\xd3\xe4:_\xf0\x1b\xe6/\\\x82o\xbb\x7f\x05\xb1/\xb1t\xe7\xb6`T\x0b\x86N\x19\x13\xbfw\x16\xc7\xdb\x91\xf0\xf0;\x9a\x863\xa9cc\xf4\xf4\x0f\xa1q\xe0\xf44W\x82\x15hZ\xd2<\xfc\xc9\xdcy\x99\x1e\x0c\x15\xd1H\xec\xf7\xc2=\xdfN(\xdaV\xe4\xf1\x1c\xdaW\xdet\xcb\x11]D\x84\x07u\xdc\x0c D\xb3W\x13T\xd0\xadH\\\x8b\xdb\xf2[\xc1\xd3\x8bi\xa2\x9d\xc6Z1N+\x03\xa6N\xa4\x1f=\x82%w\xf0,\xaf\xbd_^{\xc8Cq\x84Q\xb8qp\xf2\xea\xed[%\x9eL\x02$\xa6\xe0\x87)\x8d\xd71E\xc7\x87\x04\xc5\xad<\xe8\x9c\\\xda\xa4\x166\xa0\x85<;\x81\xed\xddf \xbb\x82\x15h\x80\xb0RA\xf1\xa4\xdeP\xa9d]\x1f\x1a\xc5\xa8\x0b\x15\xe8Yxp\x94\xd6\xc3z\x18\xff\xd5\xd1Fa,bAQqv\xa0\xcc\xc3\xce\xc8\xa1\xe4\x17\xf2\xb8v2d\x0c-\x03\xa0\x98\x02\x82@\xc4\x92\xb1Wrhn^\xd0\x87\xdd\x9d\xcd=\x11+U}i(k\xb2r\x8e\x15#\xb7J\xfb\xaeE\xde\xe9\x90\xde4\xdf\xaca\xe6 \\B\xc0DL\xf8[F\xcfds/~\x08\x96G\xd4Id\\\xf6T~\xbd\xbfg27>,\x02Y\xb2\xe7\xc5\xafr\x13\x9c\x13\xc1*\xe2\xeb\xfd=W\xeb\xb3\xa7\x18\xa0\x8a=\x93\x91\xaa\xf2'9\xbb\x86o\xca\x1f\xe5\xb6KB\x8cL\xc2\xcd\x07\x8a\x81\xc0\xfd\x80\xce\xdf\x8a:2\x97 \xe7\xdf\x0d\x95O\xf9\xd3|\xe8\xb8v\x052\x88rE\x171\xccG\x8b\xea\x08\xf5\xa7\xd4H\xa8e\xaa!\x10O\xf7,\xf7'\xf2\x17eB\xcb\x97S\xc3\x04\x86b-\x11\x93\x86\xdd\xaev\xe5\x97s\x93t\xf2\xdc$EZ\x12_3#%$V\x11\x82-\x86\x17\x10\xb1?<\x04[\xea\xf8\xd3xf\xa7-?i7\x9c\xdc\x99\x7f\xd5\xad\x1f\x1b\xb1p\xe8\x96\xd9P4\xfb\x95\xd5\x1a\x89%\x95\xb5$X\xa7C\x8dOA\x91\xc9!r\x8a\x8b\xc3\xfc\x86>\xa7\xa0~\xa8P\xd7>\\d),\xa2\x8c\x9drQL\x1f\x94\xc9\xa1He\xf0K\xbf\x9e\xfa\xe0\xa7\xbe1kA\xd3-D\x8b5E\x94\x89\x07\xf46\xa5\xe1\xdc\xa9\x83\x8fo\xea1\x90\xf2|Xg\x95\xe5\x90\xc8\xf7\x85\x8d\xfdI\xf9\xa9M\xe3`\xa5\xccb6?}\xe9l\xea\xf1\x81\xbf>c\x81.\x98h\xe4\x94B/V\xa7\x81tL\x1c$\xf2l\xb9\xc8\x16\x0bN\xba\xeb$3,\x93\xccX\xfc\xf4\xa2 [\x85\xa5@\xa7\x05\xde))\xd8\x07K\x9a\x9e\x84\xfezM\xd3&\x00\xd7\xcc\xd5\xeb{\xb1\xa3\x0c\xd7U\x95\x06:\xd9\x1bD\x00\xf8m\x85c\xd8\xdb\x11\x11p\xc4\xadKi\xb6\xc2:\x80\x1d\xe7\x1b|?w\xcf\x86g\xf1Y\xf8\x7f\xfe\xb7\x9aU\xa0;\xf0\xc39\xbd=^8\xcah\x90\x8a\x1f\xa4N\xc4\xef/\x0c!\xab\"\xd8@2^\x06\xf2\x06\xf6\x9b\xc2\x13\xd8\xe4\x9c\x87^X\xc3q\xc3`0\x00\x1c|o\x1fv\xf4RJ\x1bw3\x04\x91/ A\xea\x90 \xf0B\xc5\x0d\x85\xbd\xfab\xd0\x10#X\x1c\"\xc8\xf8F\x052-\xa0\xe2\xabP!\x0c\xbe_\x01\x15\x81Q\x99\x84\x87\x98\x00\xe7\xea\"\xee\x8aX\x98R\x02\xaa\xa1\x84\xe4\x95\xa1\x01x\x8f\x07\xcc\xefUkAO\xb3\xe6=\xe5\xbc\xe8A\xf7\xf7\xaeJ\xa0\xd4=\x94F\x9c\xfb\xb5\xe6\xe6UB\xf6u\xbb\xda3\xbe\xd8\xfa\x8caE\x0e\xe2\xb1\x1fr\xe1\xb1x\x86\xd1\x92\x1f\xe3U9\xe3XH\xca%\x186)\xa7\xa0\x04(\xd7\xf5\xd8\xdc\x04%(\x9e\x8b\x02~\x05\x82;\x10\x85r|VP\x03G\xa8\xa8x/c\x0e5\xd4]j\xc9tNi\xbe\x92h\x8ev\x953Em\x9d\x9d\xc6\xb1\xa3 \x87\x93\xa4q\xb7_\x81\xf5\x95\x1f\xce\xc7\xc5}n\xe9Y\xae\x90\x1d7\x98w\xd4t\x9e\x98D\xa2\x94\x8b\x00\xca\x07\xbb\xfb/\x82\x00\xfd\x9b\x11\x02\xb9c\xde\xb7\x85A\x95\xb9\xfe\x97\xc3`E\xd6&\x18\xe4\x8e\xb6\xdf\x16\x04\x15\xd7\xd0\x7f=\x08\xd8\x08\x1f\xb4\x13\xc4\xedA\x13\x00|\x19\xbe\x07Ek\xabm\xf0u\x9e\x8cR\xc8\x01&h\xca\x98\x9d\x8f\x1eA\xf7\x7f\xc4\xcd\x1d\xf2\x02E\xb9\xd3\xc5 \x15\xcf\xbaG\xd5\xdf\x9f\xde\xbd\x13\xbf+\xbcv\xf3R7\xac\xb4\xad\xb9uL1\x10Y#\xe0T\xcc\xc1Q\xdaZ\x8d\xe9:\xa6 \x0d\xd3\xb1\xa6%\x8f\x84Q\xe8{$h\x98\x01\x14\xbdv\xffG\x93J\xb3~5\x12D74\xf6HB\x1f\xd02\xaeK\x9b\xc6\xb3\xf5\xfa\xc1\x8d\xe3\xa2\xb6i\xdc#+\x1a<\xb4q\xfd\xc8m\xeb2\xa7\x0b\x92\x05\xe9Iz\x17\xd01tsxu\xff\xe5\xfb\xfd\"\x8a\xfe\xa9\xfb]c?\xd5z\xbf\x97\xf6u\x1agT\xdd\xc7\xa7\xd5\xdf\x1f?\x1d\xca}\xcd\nv\xd4\x97\x17$HJ\xb5\xdf\xd4\n\x0e\xde\x9d\x1c~)]\xb0m\xe4\x87\x0c\xfc[\x12\x90\xeeT\xa4\x13\xf81\x8a\x02J\xc2\x19\xef\xa3\x96\x9cN\xb2\xa12\x03\xed\x17\x93\x1b\x1dQ0&\xc8\x95\xf6\xa00\x91\x00\x1a\x83X\xa56\xdbXG#Z\xf5\xc5\x81=\x96\xeb\xdd\xa6/\x1d\xc9h\xd7\x97\x9c\xd7\x1b\xc3\xbc\xfe\x1d(\x88)C\xe2\xee\x03\x93\x9c\xd6\xb2\xa7\xed\x14\x03\xd54D\xda7\xb4\xa74$\xbfUI]\xa4#u~\x98\xfe;P:\xae\xb4Q5\xd8Z\xcc\x89\xccn\xf5\xba\xa8\xde \x95'q\xa3ylw\x83\x1bB\xf1[\xd4i4C\x19\xad\xdb\x13y\xdesY\x8eN{\xbdh\xe6\xf6\xa1;\x14\x99\xfe\x8d\xe29j=z\x82!\x8b\x1b=\xbfp\x14\x17\xbcQ\xb5+S\xfb\x90\xbby\xf4z\xa4\x9fb\xe6\xb7\x959\x8ev\xddA\x1a}b\x02\xe9+\x92PG@\xa2\xb1\x9a\x0526\x1c\xab\xc8\x85b*\x15I&aO\x0f\x02\x9f$4\xb1\xe1\xe2t\xb3\x0f\xdd\x0b?\xecjR \xe4\x98>\xedC7\xf2R]\x95\x1c\x8e\xd3\xd1\x10\x13Uy\xbaZ%\x88OG\xbb}\xe8^\xd2\xdb\xee\xf7\xbd\x0b0\x8b\xb5\xe5b_\x08\x90\x1f\xe9\xf2\xf0v\xedt\x7fw&\xe3\xe9Fo6q&\xe3\xe1\xfdt\xb4\xf1l\xc6\x8e\xd8\xf3\xd9\x0f\xae3\x19\x9f\x9d\x0d\xe4/VaJ\x0fgXY\xa4\xc4\x9d\xdc\xe7\x15z\xda\xc7\xc5/\xd1\x8c3\x19\x97\x0f\xf2\xa2\x07^\xf9\xecl\xe0L\xc6~\xb8\xb8\x7f\xcb\xfe\x1d\xbdq\xefyQH\xc2\xfb#rt\x7ftp\xe4\xba\x7fV-\xef1.?&\xedU:\xa7O\xcczB\xad\xf0\xbc\x08\"\xf2]\xc4gU\xbf\xcdoF\x18\xa5u:\xbe\xe0`\\\x95\xf9\xa1S\xd5zo\xf6\xcdy\x1am@\x189B\xd8\x07\xc9G\x08\x03\xe4\x1a;2H\xa3w\xd1\x8d\xdc\xd2\x8c\x97\x80 ;\xc8\xc7 b\x00Og}\xe8\xf66\x94+tdX^\x8a\x13\x86\xdf\xa1\x16\xccH\x1fX\xcdE\xc1{\x08\x0b$\x98\x88\xc3l\xf0\xe1\xf8\xe4\xed\xe9\xdb_\x0f\xcf\xdf\x1e\xbdy{\xf4\xf6\xf4\xaf0\x96\x8f\x8e\x0e\x7f:\xa8>\xea\x0eB\x12\x16\xcd\x1d\x91#\x18CZf1\x04is\xd2/\xe33\xa22\x9f\xf1\x86!\x8e\x95\xd3\x10\xb6w1\xe74\xa2\x07t\x95JN#f\xaf\x9b9\x8d\x10~`|\xf3\x18\xbf(\xa3J\xff\x9dx\x0d\x873\x1b\x9d}\xee\x8d\xa1\xe15\xda2\x1b%Bi\xc2\xf8P\xaf\x1c\xf2\x93#r\xc4\xfa\x82\xe4\xc6O\xbdKp\x8c\xca\x03\x8f$T\xd5D\x8e\xb5\xb5@\x01\x0e\"\x9f^<\xe2\x8d\xe5z\xdc6\x8d\x1d\x1d\x1cY\x1b\xcb\x15\xb5\xad\x1a#G\x1a\x8dl\xe1\xf8l\xdcnB\xeb\xf7=\xa0\xc5v\xfe7\x83\xd6\xdb\xa37\xdf\x0eZo\xc3E\x1bh\xd5)\xd0\xf7\x83\xd6\xc67\x05\xd7\xc67\x85\xd7F#\xc0t\xbb\xbdx}8\x18j\xc6\xa2\x9cKe\xbe\xb7\x0f$\xcf\xe95\x810?\xa6\xba\xb4\xcb\x0e\x14\x1e\x083\xb4\x11\x93\x7f\xd6mC\x8d\xff\x8aj\xfcW\xce\x1e)\xff\xb9\x1b\x8e\xe9\xc7\x9f\xbb\x8d\x1c]c\x8b\x93\xca/\xc6\xbb\x9d\xa6\xb3\xfb)\x9c\x9d\xa5\xb3\x9e[z8V{/\xfd\xe0\x0c\"/\xf9\xc1\xe5\x1c\"\xb6\xf0\x83\xf3\xdf\xf7\x0ec\xc6\xdcj7\xa5\xf7\xdd\x89\xebNJ\xac\\\xab\x1b\xdd\xd4_\xd1$%+\xa3)\xcb7\xe7\xd6\x8a\xb0\xe5\xd1\x80\xdeRO0my\xa9/K\xbf\x03\xbf\xa6\x89\x87b\xb85Y\x0b\xf7L\xfd\xb9\x97\xdf\xe0 \x0b\x96\xcf\xc3\xcd\xb9\xb2b\x12j\x9erW1\xf3>\x8c\xe3(v\xba\xafIJs\x9fZ\xca\xcat\xc1\x99|\x91W\xb4\x97NG3\xce\xfc\xf4\xd2\xe9\xe6\x8c{-\x11\xfesk\xd6\x87N:\xdd\x9e\x15f\xb0\xf4\x06X\x07\x0e\xfbo\xf0\xe9\xf4\x95#\xc0\xa0\xf3\xc3\xf3E\x98\x8a\x1ek\x82G\xa9\xe8\xa5\xd3\x9d\x19\x8fO\xd1K\xa7\xbb\xb3>\xa4\xd3\xbd\x99\x89\n\xa3\xca\x15\x03\xdfN\xf7f\x82+\x1d\xf6a\xcb}\x0e\x8b\xc2\xa7r\xeb\xb9\x0b\x0b4\xf0\xd3Q)l\x87u\xb7\xa8\xd3?\x13z\xa5\xd3g3\x04<[\xb3]\xba\x0d?\x80\xb3;\x84\x1f\x10Z\xc3\x19\xf4\xa0\xe7\xa4\xd3\xd1h\xc6\xd0l(\x95\x80\xb8 \xea\x9b\x1bkW\xc4g0\x82M\xc1\x9e\x85\x8bQ\xd5\x1f=\x02o\x90\xd0\xf4\xd4_Q\xc7\x1b,\xc57\x1760\x88\xa6gCa?LR\x12z\xf4x1\xc6\xeeZph\x96M\xc6\x88\xfa\xdb\x93cA\xd7\x8d\x8e\x00\xdf\x8a\x10?\x90\xcc\xf0\x04\xfc\xdf\x8f\xc4t_\xbcP\xac\"L\xe6O\xdf\x0e\x0c\xc5\xcf4\xbe\xab\x0c\x8b\xc3hg\xdb\x1d\xfc\x88\xb6\xc2E\xaf\xe0\x11dd\xd8L>\x97\x1a\xb4(\x18\xba\x07?\xbez}\xf8\xe6\xa7\x9f\xdf\xfe\xe5\x97w\xef\x8f\x8e?\xfc\xd7\xc7\x93\xd3O\xbf\xfe\xf6\xbf\xfe\xfa\xdf\xe4\xc2\x9b\xd3\xc5\xf2\xd2\xff\xe3*X\x85\xd1\xfaoq\x92f\xd77\xb7w\x7f\x1f\x8e6\xb7\xb6wv\xf7\x9e>\xeb=\xd9?\x0b\xcf\xe2\xee\x03%x\xae\xe4\xf9\x1e+\xf6\xc57\xe0\x06J\x1d5^\x8e3\xfa\xe8\x1b\xae\x88B\x1e\x030\xe4\xbeC\xa1\xed\x9e\xa8\xe3 i'\xb9\xfcK\xa5\x19;\x8f\x06\x08\xbb\xdb\x8d7G)\xbc\x80a\xab\xdb\x1f\xd4\x8b\xefj\x1f\x1b)a\x0c\xff\x01OQ\x01]\xc6\xfb\xaf>:\xa3\xb2\x02cz\x16\x9f\x85\xfb3\xa1\xc60\x03=\xb2.K\x86\x91\x80\xb4\x8f\x12\xf3r\x07\x86;\xa1\xdc\xd3{\xf8\x1c\x18\x94\xc9sH{=\x17R\xf8\x0f4\x05\xe3*\x13~\xa5\x13\x88L\x11\xf0\xf2%\x8cv\xe1\x11l\xee\xec\xb8}P\x8b\x9fVK7wv\xe0\x11$\x8c\xec'\x98\x0e\xe4\xc5\x0b\xd8\x85{\xc8rt\x88$:\xa4\xba\xe3U,\xd1\x10dH\\\x82\x03\xfb\x01v\xf1\x9a\xe6\xab\x86\x04c\x18=\xcdu=\xe5\xb6\x86\xda\xb66E)\xbe*|\x0f\x19h\xd4:\xdb\xf9\x9b1\xa6\xdfX\xc4\xd1*\xff\xe2\x04(\x16 \xbd\xc7\xaf\xdf\xd4~\x15C|0)\x87S\xd0\xf67'm\x11:\xe6n.F\x82b@>\xd2Hk2\x0b\xad1`\xe7V\x05;q\xe7g\xd3\x08\x97\x8f-\xfa\xee\x16\xf2|J\xe9\xa6\xaet\xb7R\xb8\xbb\x05\x8f\x00Mr\xd8\x8c\x9c\x88a\xecS\x17z@\xa7\xa9\xf9R\xb5\x8c\xa0[\xfc\x0e\xf1\x1b\x8f\x08\xc6\xb0Y\xa0k\xa9\x9d\xa1\xae\x9d\xedZ\xe1\x8b\x17P\xedqw\x1b\x1b\x1e\x15\xc8\\j\xb9>\xc0\x17/j\x0d\xefn\x97\xdb\xebC\\F\xbc\xfc\xd7Ws\x10f\x89\xb6\xa6\xff+\x87\x9c\xacs\x08F\x85\xe1\x03\x99\xb4\xc8\xe2\xd1`\xf0\xea\xf8\xca3\xdfd\xcf_\x91\xd7\xb8*\xdcx\x1cP\xdb~\xe3\x97\xd2A\xee%\xccv_\xf8\x9c+\x83\xcd\x1ed\"uh0MgE>\xb0\\]\xcb\x01>\xeb\ny\x15\xd5\xb2q\xb3Q\x87\x88\x89\xe3\x87\x10\xdb\xadx\"\xd1$Jj\x16\x8eB\xd6\xcf\x1a\xbb\x96\x9f/\xb2\xd6A\xe6\xa7\xb9\x0fVM\x98!$\xf9\xa1H\x9a\xc1\"\"[\xb4\xca\xdf\x91#Ny[~!\x83S\xd7O\xfc\xb3\\\x8dZ\xec\xfa/\xdc\xc4k\xe2\xc7\xc9\xbf\xd7.\x16\xbe\xbb\x96\x9dJ\xc4\x8c\x0e\xe2\x98\xdc9\x99t\x81\xcco{\xd8\x16\xce\xbel\x0bg\xb8\x85\xf5[7j\xbdu}\xf4\xe7G\xc3!\x85\xe2^\xd1\xbb\x84\xbd]u\xf17\xb5B\xa6\xe9\x8c\xd12\x7f:d\xe7\x0c\xfe\x9d\xcd\xfe\xe9hoXG\x1dW}]\x0d{&R\xd1\x18\xd6\xd1/\xad#\xd1\xae#1\xad#[-\x82\xab\x15\xd5@\xdc\x07_\xc0.\x12\xb0\x8b\x10vF6\xc6\xff7\xd8\xc1\xe5s\xfb\x81\xfb8\xa1\xc6\x0bt\xbdw\xe1\xf7\xdb\xc4\xd6#\xd6\x0f\xc1\x10\x08L9\xc9\xc2\xbe\xb0D\xccIm8Mg\xd6\xfd\xf2mQ\xdeD\xe9\xff\xed<*\xffH\x9ed\xe1\x9c.\xfc\x90\xce\xbfR\xfbb\x81\xc3\xc3\xa1\xea\xd6\xf2\xcd?T\xa6\xbb\x8e\xfc\xb9\x8c/f\xeb]'\xcd\xd94\x7f\xffn\xae\xd1\x7f$Ob\xba\xa4\xb7\xdf\xe5F\xe5\x01\xca3\x1f\x03\xd5`\xbd6\xe7S\xeeW\xa7\xe7\xb3\x19\x11xr\xf6\xc4\x99.\xfd\xd5\xec\x07\xf7\xcfO\xe4\x05\x87\xbez\xac 9\x00\xd2z\xfa\x89\xd4\xbe\x0f\x8dw \xfc\xc2C\x9a\xf2\x86\xd3\x11\xcab\xf2\x16\xe1%\x93K[\x9c\xd8\xac'4\xeb\x9d\xa6\x85!P\\\xb2 *\x9a\xa9\xb5\xf2\xbd\x8f\xe1\x7f\x0e\xc4\xe56Q\x80\xceo\xe1\xaa\xd0-\x19\x13\xf5\xc1\x001\xbc\xd0*.H\xd3~U\x96\xf9J*\x913j\xbc\x83\xb6&1\x0f%(\xd6\x05a\xb0\xea\x01\x1d$Q\x16{\x14z\xac\xc0\x08X:X\x06\xd1\x05 \xc4\xd5_o\x1f\xbaK\x1e\xb9\xaf\xc8D_\x11\xf5\x9fV\xca3\x9b\xd2\xaf\\5i\xd6.\x94_\x08`\x1f\x9eU\xc8 \xec\xc3\xa8r\xad\xb5\x80}\xd8\xda\xac`\x03+\xdb*\x97\xcdY\xd9v\xb9\xec\x92\x95\xed\x94\xcb\xaeY\xd9^\xb9l\xc5\xca\x9e\x96\xcb\x96\xac\xac2\xbe;\xd8\x87\xed\xcaX.XY\xa5\xdfsVV\xe9\xf7\x06\xf6a\xa7\xd2\xc7!\xec\xc3n\xa5\xbd[VV\x99\xdb +\xab\xf4\xf1\x8a\x81\xaf\xe2\x93x\xc5\xca*\xef\x1e\xb0\xb2\xddr\xd91\xe6/\xacT\xfc\x80\x85\x95^N\xb1\xb02\x95\xf7\xb0\xafA\xfa\xe1\x18\xbaggC\xcdQ\xb4\x87O\x88\xe6\xc9S|r\xa1y\xf2\x0c\x9f\xa4\x9a'#\xdeQ\xa8{4\xc2G\xd7\xbaG\x9b\xf8h\xa1{\xb4\x85\x8f\xaa\x0c\x1d\xfbl\xf2\xa1Wu\xd1\xec\xb3\xb5=\x86\xc7gg\xdd\xc7\x9a\xb1\xf3\xbe\xce\xce\xb4\x9d\xf1\xde\x8et\xcfv\xf9\xd4\xceu\x90\xda\xdc\xe2\xad\xbe\xd3?\xe4\xad~\xa8(\x1a\xcaU\xdf\xb2\xf3\xba{\xd7\xedC\xf7\xaf\xec\xbf;\x9a\xe0w\xf1\xe7\xf0\x84\xfdA\xb6\xb7{\xcc\xff?b\xff\xe3W\xfe-\xc2\xaf\xfc\xffc\xac\xbdX`E\xf1\xe7\xcd\x9b\xeeL\x17U\xe3\x8f:\x9d,\xb4\xb6\x95\xabhn\x82\xb2ou-\xeb\xf3\xc8\x19\x9b;;.\xe7\x85n\xbb<\x80\xeff\xb9\xad\xdc\x1a\x19\xab\xef\xee\xecl\xc9\x172\xf1\xc2\xb6\xe6\x05=\xd7\xde\xe1\x8dlo>\xdb~\xb6\xbb\xb7\xf9l\xc7u\xcb\x11q\xbdhNa\x1d\xf9\xa5\x8c\xb9<\x00\xe2\x8a\xdc\xc9L\x0c\xcb\x98\x92\x94\xc6<\x19\xc3\xf0\xf6\x8d\xf8\xe8X\x07\x1c\xe8'1\xd0\xa7\xe5\x95-\xfd\x92\x87\xde\xd9YW\x84u,\xe28\x0e\xf1\xfd\x8d\\Vv\xa1\xa7\x08p\xba\xc8%G\xf5\xc5R\xa2X\xf3x\xe1y\x98n_\x06\xc9\x961\xa7\xdf\x93\xf4r\xb0\"\xb7\x0e\xa6\x0c\x17\xc5\xf7\xf7\xb0\xe9\xcah\xdfW\xfe\xfamxM\x02\x7f\xce\xdbR~\xab\xa1\xb9\x17At\xf3\x8e^\xd3\x00\x99X?9\x8a\x18L\x97\x0e-\x9e\xb8\xd2\x17I)\x93\xbd\xa4w\x81\x08\xc1]:YMLu=%p\x93Ym\xe1\xdb\xff\x8f\xcf\x06\xcds(\x12\xa2pk\x0d\x9e\x845\xae\xdc\x1b\xa4\xf9\xd5\x0c\x8f\x04\xe0?\xe7ARG\x90\x89\x86X?\xac=\x91\xe4!\x18\xa8>\x97}\xc8xg\x19^\\\xab\x8f\xa6\x19\x1b_8%3\xd8\xaf\x06\xc3\x05E\xcd]\xc6gGA1\x868\xd8b\"\x0d%s\xdc\x89\xe2\xf4\x17z\xc7\xb3\xcf\xe4?\xca\x01\xddC\xfa\x9b?\x97\x01\xd5\xf3_\xf7\xf7\xf0T\x86C\x0f\xa3\x8ft\xc1\xdb\x10_\xd5\x16\xc2\xe8U\xb4Z\x93\xf4=\xdb\xce\xbc\x8eR\xa0\xd6\xf4\"\x86\xdd\xe8zu#@\xa9\x14\xa85\xbf \x84\xbcLOd{\xe5\xf0\xb6\x1cu\x1e\xd3`\x85E\xe4\xfaR\xb6F,\x99g\xec\x0d\x92Ra\xaf\xc0K\xb3\x84\xce_\xabOJ\xb1\xfet4\xe2\xa3v3!\xd2\x8b\xdd\x14\xc1~%\x9al\xea\x8at\xc6\xfc~nc\xc4\xf1\x9a\x8d-Q\x83\xa5\x81\x0f/ y\xeeb\xda\x064`\x97\xd9\xfa\x85K\x1f;\xfb\xc1w\xd1\xec\x87\xfb\x8a\x88\xac\x16\xa2\x83\x04\xb3\xbd\x95\x9e\xb0.ydW\x1f\xad\x86\xf8\xf7P\xd5C\x9c Q0\x14x\xdd\xdb\x87\xc8eC\xec\xedW]\xcb\x04\ngV\x10\xbd\xb6\x85\xe3\xd6\x87\xdb\x95\xe4\xf2\x07H]k\xdb\xef\xea$Z\xca\x1c\x08\xb1\x05\xc3>\xfe\xd5\xbe\x8e\x9f\x8c\x0dmm\x96\xa3T\x8d6wQ~\xdf\x1dU\xc3`m>\xdba\xbf\x18\x87RxP0\x96D\xfc\xba\xbf\x87\x9d\xbd\xad\xed\xed\xf2{\xec0\xdeb\xbfx~\x8a\xbc*+\xdf\xadt=\x1am\x8fF#\xebD\xfef\x9c\x08N\xb1\xd2\x0f\xb6\xcc\xbe^\x14__\x15_\xaf\x8a\xaf\xc7\xc5\xd7\xd3\xe2\xebM\xf1\xf5\xd2:\xac7\xc6a=\xf9\xfd,\xfc\x01dT\x13u\xb9\xe57\xb6\x91\xfe^\x0f<\xf2#cs\xcaE\xbf2Y\xa5\\\xf43\xe3m\xcaE\xbf\x01\x06\x99\xae\x0f\xf2/\xf6\xd0\xebl\x1c\xbej\xe7\xd4\xd1\x84B \x0c\xe5\x0b\xdc\xe9<\xeeG\xfd\xe9{N\x07j\xe5\x8cS\xfd$\x12\x92\x96r\x96TV\x12\x83\xf3t\xde9\xfc0\xca\xb0\xec\xbc\xf8z[|\xbd)\xbe^\x14__\x15_\xaf\x8a\xaf\xc7\xc5\xd7\xd3\xe2\xebe\xf1uU|\xbd+\xbe\xae\x8b\xaf\x1f\x8a\xaf\x87\xc5\xd7e\xf1u^|\xbd.\xbe\x9e\x14_\x0f\xc4\xcc\xcc\x89^49\x1f\xd2\xbaJ(7y\x18r\xba\xaaP\xd9^\xcfv\xb3\xd5\xf9$\xc8\xae\xd2\xbf\xafD\x05\xfaM\xaf\x04f+\xf7\x96\x8d\xfdoZc)\x13\x83\xfd\xc5\xc3\xd4\x0e\x12 \x9f\xe7rd\x1d\xf6a\x01hQ\xcdX\x15\xe4Ya\x03\xde\xe3\xe9\xf2\x92[\xf1vA$\xd2\x9c\xbeg'\xc3\xac\x8f\x88\xe9\x1b\xf4\xdc\xb9P\xc1@\xf4\xb5\x00\xd1n$\x1c%\x0e\xbaq\xa8\x7f2\xb7&\xc6\x85\xdcM\x00\x13\x08\xe1%<\x83\"\xed\xd2o0\xc6\xf2\x9fa\x0c\xbf\xc2\x98\x8f\xb2\x13\xf1\x87\x7f\x871\xfch%m\x7fU\xa8Fu\x85\xe8`\x9e\xadJ\xbc\xb7\xe9.\x84\xdf\xfe\xa6\xd5\xdb\xdf\xee\xe3\xc7\x86\x9b\xd9N\x85!\xe3\xa1\xfd\x19H\xde\x16!\x08\x14W\xd3\xc7\x18\xa0\x1dz\xec\x9b\xfeF\xd9\xcf\xb9\x0b;\xe9\x94\xfc\x17'\xed\xf3$\xc6\xbeH\xdeL\x14\x85\xa3\xd1eY\x80\xb0Q~\x92\x1f)G\xe97\x02\x94\xdcYd\xc0H}\xa6\xd9\x90\x87D\xe3\xd9\x82\xccv\xa8 p\xa2\x9ah6\x9c\xe5\x19H\x15T0\xc5n\x04\xeb\xbd\x0d@\x9e$\xa9\xbe{\x8d\x96\xaf\xe8Q\xfd\xf7F?jM\x06{\x90o\xff\xd8\xf8\xb6\xc0\xed\xc2\xe7\xe51z\xbb<~\xdcuM\xf8\x0e\xb2\xf5_\x9b[\xbfg\xad\xff\xc2\xf3\x04r\xbca\xcd\xfe\xe4|dE\xbe)M\"\xb6\xfess\xeb/\x8d\xad\xb7\xc67(\xcb\xee\xb0\x0fO\x9c\xb3\xb0\xe7:\xd3\xdf\xcf\xc2\xd9\x0f\xee\x93\xa5~W\xa9\x1f\x94\xc9\xb3\x9a|\xe1r\xd9DP\x96\x0c&\x90\xa1\x9aA\xb8U@4\x08H\x92\xbeeo\xf0\xfc\xe0\x7f\xce#\xd3\x0d\xfb\x98\x7f;u\x0d{Z\xfd\xa0\xa8~\x16\xcaP0Ct\xffd$^\xfe6c,\x88\xc9k$l\xf5#b\x0c\xc6\xaa\x0b\xb01\xc1\xa7\xfaam'\xc0\xc3\xbc5O\x04\xc4\xc9\x15O7\x1b\xc6\x0cyJ\x18>\xcb\x00o\x80|\xb6\xd3\x13\xe81Y\x0f\x13\xdc38\x88\n0a_\xc7<\x9f\x1d\xf4\xe0\xcfN\xc0\x85I\xbc\xb5\xb0vf\x8ey \x05*\xfa\xc6J\x9f\x19z\x12\xb7 \xdb\x7fk\xc4\xf6\xc7\x98\xac\xa4\xf9~O~rA\xba\xe0\xca\x85\xa4l\xe4\x91\x84\xce\xb4\xc2\x08\xbd\xe4\x02\xda.\xa0\xe7\x0e\x13\xd7v\xb7F\xc8\x04\xd4\x83\x95\xfa(\x15\xf3wv\xb76\x87PD.\xdd\xda\xdeb\xc26*\xa6\xfepF\xc3Mt`Na\x83\xb7\xce\x93\xc9l\x88\xd7z\\\x86c`c\xbc\xdb\x98\xeb\xbc\xde\x0b\xab\xd9\xde>t\x90\x93\xf9\xe4`Zh:\xf5g0\xe6\xa7\xdc\x1fz\xb74\xf5#\xafSmk\xe6\xf2\x8c\xa2\xfa\x86D \x08\xf3\x92\x95t\xba\xfej\x1d%\x89\x7f\x11\x08\xc7\xf71\xf8BU\xc9\x8d@x \xb2n\x13c\xf7\xd9\xb1\xcb\xf3\xbf\x983K\xc1\xbe\xe4\xd7\xa4\x02\x10\xe3\xafin\x01\xe221)\xc5\x95\xd2\xea/B\xb6\xdfx\x8em\xfd{\x9b\x9c\x1e\xe5\xcf\xd8(\xba\xbd..\x97\xdc\x94\x1b\xfc\xb09\x0b\xbb\xd6\x19\xfed\x14\x84MCf\xb8Q\x90\xd4\x8d\x11\xa6\xf7\xb4\xf6\xf1g-\x14\xd1\x1aAq\xbcV\xc9k\xce\x1bTl\x87UE\x96\xe2CY+:\xae2\x90\x85*\x9d\xc0\x0b\x08\xd8\x1f=\x07\x89\xa2\xa3\xe31)oJf\xee\xa0\x88s\xc0P\xc4\x1b\xe4\xf6\x06\\\xcb\xdd\xf1*5\xba\xdc\xbc\x80aR\x9e9\x90\xd3XY/Z\x80\xfaR\xdeN\xder\xa5#F\xfal\x82.\x95\xea]\x98\x80\x87\xdf\xc7\xd0\x9dt\xfb\xe0\x0dr\xbb\x04\xdb\xb1\xc2\xdaXp\x95\xa8\xb8\x1a\x99b33>\x0e5>N\xdfh>\x91\xf1\xbb\x00\xb5K\xee\x13\xa1\x94\xb03sa\xa1\xe2\x06\x0d\x80\xfaA9/\xa9\xf5\x85\x11-\xca\xf4\x99'\xe8\xf7D\x82\xfe\xc7/1k\xbf\xe0\xfdc \x9eG\xd7i\x82Wo\xfc\x04\xe6i\xc2\x10\x02\x8f\x9bN\x9a\xf2\xb4\xa6\x8b\x19\x9f\x99\xf9\xe41OY\x8a\xc3\xb1\xb6\x8a5\xfe\xb4\xc6&K+\xe6w\xec\xfa\xd1\xffU\xd2\xf1\xf1M_\x95\xd9\xd5\xfb\x83|\xc8a\x9fo\xe5\xb0\x0f\x9d\x11F\xc1\xc9\x7f\x0e5\xd9\x82\x13\xc8\xb1\x847Q\xcd\xdb\x9a\x13?U\xa4}\xc1#\xc4\x95\xa5\xdcjVS\xd6|\xd0\x87E\x1f\xed?\xea\xdeR\x0cAQ\xd9\x91?B\x17\x1f\xf9\xa4\xae.C\x85\x9d\xa3h(\xc5\x8dXqI\x92\xcb\x04\xa1\x8b7f\x85o\x06\x02\xeb\xd1#\xb6\x05\x95\x02T\xdb\xdc\xdf\x83P\x84K\xa5\x02\x12\x86\x97 R.\xfb\xa8*u\x85Z\x8aVn_\xa6\xc1\xcc-\xa0\xdf\xfd!\xa6\x8bs\x86\xe3\x15\xf1\xderQ\x8d\xd3\xc2\xb6;\x9a\xc6q\x08\xba\xf2}\x9eR\xdc\x00W\x97\xaf\x1c\xcf*\xab\xde_\x8aU\x96\xc7\xcd\x04\x9cN\xcd\x96I\xa3!\x92\x9f\xb2r\xb9\xaf.\xb0\xc5\xa2\x95\xdf\x1c\xa7\xc4\"\xe0]V\xeeYM\xb9\xf1\x91\xd6H\x1f\x04y\xa5\xe8\xc2%~w\x9aT\x80J\x0e\xd9\xe2$\xd0\xb4\xa3\x145\xb4\xa8\xbe\\\"u\xf9u\xe7*K\xd0\x92\x80\xc0\x05O|\xc3\x13\x98\xdb\x8c\x10\xa1\xa4b\xe5,\xc4e\xe9\xbe\x8d<\xe72\xd8\xc8E\x95=\x135\xc4\x823\xc8\xf8\x0c\xa9\x1d\x0c\x89$\xae\xb5D\x88\x89p\xca\x18\x9c\xcb\xa9?\x9b\xf5\x05\x8d\xe1\x96\x80\x19O\xcb\xce\xffq\xbc\xc7\xdd\xd5b\x07 \xe4\xc7\xbd\xc1\xbe\x15\x1e\x15L\xf0\x90\x89\xe0e\x1dO,\x1d\xd6,\xe77\x9f\x88 N\x13\xc6\xa8\x8a\xaf\xd0\xc5\x8d\xd7\x93\xaf0\x0e\x83S\x81\xd2\xdc\xd4\xa9$|\x1a\xc1\x17\xf4<.z\x1eC\x97\xe1uo_\xed\xdd$\xedHZk\xa2\xee\x89}&g\xe4K\xda\xe2\x14t\xe4QNG\x90\xc9\xe3\x9d3\xd9\xac\xbe[m[\xb5b#\x914\xec\xd3\xa0y\x9fz-\xf7i5\xa7\xb6\x97\xa3o%\xa7vV\xbf\x8a\x9f\xa0\x00\x8eR\x93\xa0`\xfc\x18\xc2\xbb\xddn\x1fq\x02\x95 S\xb6?\xbci\\`3N\xb63\xe2\x87_\x01\xd22N*\x8dq\x04\xcb\x8a%f2\x96q8\xc8x\xa3eF\xbd\x0e\x17\xaf\xb099\x14R\x1e\n\xb2\xe6Y{lR\x8f\xf5\xee?X\xaf \xeb\xbf\x11\xa3\x9a\xd0\xa9\x0b]\x05\xa9\xeac(\xa8\xa5\xf6`.\x1d-e\xf0~\xc9iRx\x00\xdb03\x93\x98i\xc16\xc5l'4\xd9\xe8\xa8\x84\"D[\x1d\x95\xe4)$4B\x12J\xcad\xa6%1\xc1\xb7\xba\x1b\x0c!\xc4W\x9e5\xb8Xy\xfb\xc2g\xca\xc2\x13\xce!\xcd\x9a\x16\xfd\x9fAF\x1a\xd6\x88\xb4X#\x85\"\x84&\x8a\x90\xf3\xbe\xd3xV\xdeA*1\xf091h\xd8\x8c\xae\xd0U\xb6\x82;Q7\xdc\xb4+S-7\xc2\xbe \xf0\xad6\x9cY\x94\xcc\xb7!\xd7(\x89@\x03I\x93\xf4X2\xd5k\xf4m\x84\xaa*-\x0b\xb98F.\x02\x8a\x9eT\x10-\x801/|,i\x048W$Kz!K/'\x95\xf9\x87G\x8f\xf8\xc5\xa4DbT\xe0\xd6\xc1]+i\xe2K\xca\xab\xc1\xc5N*\xc4\xce\xeeKu=\xfed\xee\xa8.\xd2\xe9D\xb5\xff2+\x03sm\x94.\xd4\x8c\xce\x1d\x87\xc7\xbb\x94-\xa3\xfb\x97\x89~*\xb4\xb3\xbe\xa2\xb9\xe5c'O \xa6\xd1\x80\x98}\xec7\x94\xc0\x14\xa1zO[Xy\x15ia|\xdc\x9c1\xf7ui\xbc\x85\x0fy\xbd\xd4\xed\xf3ce\xe0'<\xb4C\xaa\x89\xce.?Uf851\xc3\xd4I\xa7\xfeL@\xcd<\x12{G\xd5X\x11\x15K\xb8\xc8\xd6y\xc4y\xeb\xb0\xee\xc4\xca\xd0$\xe2dZ\xb9R\xf5\x0d\x97\xa8\x90\xaar-\x82,\x9a\xfa\xd3p6\xabL+\xd5\x98\x03\xe6\xe12b\xbb\xd2\x8fR\xab\"\x9b\xb5s\xc43\x02\xb0S\xe8\x1fUOB\xa9\x97V\xcc2q3\x84\xc8\x03\x85}6GZ\x9c\xb0\x13\x08%\x8b\x85\xda\xcbR\x0e\xf2b\xe7\xe5n\x9fr\xfbR\xaadh\x1f$dA_W\xac\x15,\x96{|\x8a\xf1\x80\xde\xa64\x9c;\xf5}\xc4m4\xc7@\xca\xab\x85'~et_\xe4\xf6\xa3z\xb1Z\x07,\x0d\xe9\xd5\xac\x07x\xd9\xd6q(\xecC\x8f\x9aC\xcaX\xa3\x99\xf3h\xe1\x97i\xba\xd6\x04\n\xe7\x0fo\x12C\x0cq\xd1\xdfS\xc1\xec\xd57T\xd1\xb8\xae \xd9zC\xf3\xdb\xdb[\xf6\xf6\x17\xda\xb1+-l\x8e\xec\x0d,\xa3\xf5%\x8d\xedm\xec5Lr\xe1\x07\xa6P\xebzs\x04\xeda\":\xf9\x16\x98%\x1d\xca\x1a\x83\xc4\xd47~d\xbc\xde\x99S/\x9a\xd3O\x1f\xdf\xbe\x8aV\xeb(\xa4a\xea(Q:\xcfzh\xb2\xc0\x18+\xcd\xceM\x07\xdc\x7f\xc2_\xdc5!{NT\xaa\xf1\x05$\xed\xd1\x9e\x8c\xdcQ\xdc\x0f\xa1\xcb;R\x9d\xcd\xf95\x0dZOO\xd0#\xde\x85X(6\xd1H\xf2\xd1#\x10G\x0f\x0dkS\x8cP\xb2\xdbG\xb6\xa0\xfe\x94'\xf03\xd0\xbe\\\xf4I\xd1O\xf2\x8f\xc8\x0f\x9d\xee\xa3\xae[!o}H\xb9go 2U\xb0\x94.\x92\xd1@b\xfa\xfb\xfe\xe4\xd1\xac\xe7\xeeO\x9c\xe9\xef\x8f\xb8\x95\x04\xae\xfa?>?G(\x86V3\x01i0\x159\xe8\xb4i6\x8fb\x156\xabg\x0b \x9b\xe2\x87\xfc\xba\xd7\x89\xa7\xfe\x8c\xb1\xc9-x\xa6\xf8a\x08^\xf8FnU}\x1a\xb9o\xe4\xde\xee\xb6\xd67rk\xb8\xa9\xf1\x8d\xec\x1e\xde\xae\xa9\x97\xd2\xb9\xaag+W\xcb\x14\xdf\x97\xf2\x93$\x7f\xe2\x87-\xc8\xb8\xe1\xcaL\xdc\x94\xf5a\xdd\x87y\x1f.\xfb\xe8\xc9\xa8\x89\x01\xba2X\xe2.\x0d\xe5w\xa8\xf9-\xafSE\xb5Yl\x8a\x92?\xf4\xe9\xdd\x9ar\x9fh\xa2\xe6R\x06\x950\\\xe8\xcf\x10\xb9+\x03=\x02\xe1\xddK\x1du\x04.\x04\xec)\xec\x8bh=\x1c\x10)W\x1a\xd3\x01Y\xaf\x83;'\xeeW#>}6\x0c\xf0\xdc\xech\x8f\x16\x12\xb0\x01\xe6\xfc\xedJ\xbc\xa0Kn\xb7\xf2R\x90\xa1P\xdei\xa0\xe8\xc0Z\xb9f\xcf\x16\xad\xc6t\xa35\x97dC\xa2\xb8\xb3t\xbbj\x01\xce\xb9\x9ac\xe3\x90\xed\xe0Z\xb59\xec\x83\x08\x05\x1fe\xa9s\xd3oa\x94\"A\x91\xc2\x068\x08\x0f{\x00\x88%L a\xdc\xdaB\xbep\xed\xd6\xf3s\x00ga\xabn\xdf\x06\x88\x1cZ\x1d\xad\xe7\n2\xa0Av\x00\x13\xb8`\xaf\x8c\xf9\x9d\x8e\x8a-5 M\xdf\xe3m\xd3\x1a\xe81\x97\x01\xea\\\x0bz\xb6Bl,$^f+\x1a\xa6 \x0f\xe4\x9f^\xfaI\x1fo+\xa8Ei\xc2^V\x90\xad\x10\xbf\x9b\x97\x0f\x14t\xe5\xbd\xd4\x91\x80 $\xab\x02fkmC\x9f\x1d\xd3\xc2\xb3\xd1-]u5\xea\xcd_8\x97m\xe4\xf0\xfa\xc6BSyG\xd7\xa8\xdb\xaf\x8cT{r`\xaa\x0bF\x85\xee\xefQFrB\xae\xfbA:\xd9a\xe7-\x99\xfb\xe1\x92g\xdap\x18\x95\xec\xae\xc8\xedo\xc4O\xbbty\xbb\xb5PS\xe5~p\xa2{#\x97u\xff@ *\xdd\xeb9\xe1-]B\x0f\xab\xac\x05\x82\xe43\xa1\xaf\x0f\x9d\xd8\xa9\xc4\xcd\xccs\x08\x15\x0c\":`\x8c\xc1#\xe1\xe3\x94\xcd\x0dH\x02\xb9|\xd9\xa9\xd8O~\xd6\xef\xd0\x1a\x80\xc6\xa0]\x14\x14-\xba\xe7\xe7\xd8\xfe\xf99R\xe4\x7f|\x86I\x15LZ-\xa89\xe8\x16\x8fC\xe7l?s\x1di\x15\x85\xe2`\x9f\x81vw\xe8\x0e\x16NUp\xee\x832\x0c\\\xbc>l\xba.\xeb\x7f*\xc3\xd9u\x1c\xaa\xda\x8c\xa1\x9aM\xe78\xd5\x14y*\xd5G\xcd6\x9e\xb0*0\x8cl\x87\xa8\xebK%\\\x8aFx\xf9\x9c\xd0\x1cM\xd0@\xf6\xb8\xae\x06\xad\x9a\xc1\xfe\xe33\xbf|\x19\x8b\x83\xa6\x82z\xde%\xf5\xae\xc6\x8aEv\xebM\xab\x92\xf5\x02\xe5\x8b\x8d\xdb\x82\xe8\x1b\x8f\x1d\x0fC6\xf0:\x0f\x1b\xd9\x97\xed}\xde\xdf\x18\xc7\xff\xcc}\xe0~oV\x1a2p\xed|E[\nx\xab2\xb4\x90\xad\xf7\xb4I\x88\x9d\xad\xbd-m\xdc\xa1\xa7\xba\xb0C\xa1\xb3]\xad\xcd\x07\xfft\xbbZ=\x10\xe5\xd5\x83\xc0\x13\xbdVG\xb9\xe0\xf5w\x86\xa5\xd3\xf0\x99\xf2+\x1a\xf8![\x1a\xa7\x82U\xeb\x1a\x19Z\xf8\xe1\xfc\xf5\xf1\xfb\xa3hN\xc7Ui6\xa6\xe1\x9c\xc6c\xf0\x07\xfc[e\x92\xe1*\xca\xc24\xd7\n\x1d\xa4\xbc\x11\x7f\xa0\x7fR~\xfb\x9a\xc6\x89\x1f\x85cH\xaa\xad&x\xc3v~\xc1\xe8\x05\x9d\x7fZ\xcfIJ\x931d\x83r\x89\xe15>\xd2\x93\xec\"\x8d)}\x1b\xa6\xd1\xab(L\x89\x1f\xb2y\x14\xc2\xabB\xa1\xf5\x91\x1a\xcf\xcf?\x1e\x1e\xbc:=\x7f}\xf8\xeb\xe9\xf1\xf1\xbb\x93\xf3\x9f\xde\x1d\xffx\xf0\xee\xfc\xe7\xe3\xe3_\xce\xd1CWk9e\x7fM,\n{\xbbU\xc5\x8ar>\x87\xe7iL\xa9.i\xf8\x92\xa6\xaf\x82(\xa1I\xfaV\x10\xe47q\xb4\xe2\xab\x12\x0f\xccO5\xba\x16\x8aK\xc6*\xc8\xcaM1\xc3@\xb9b\x18\x88e\xa0\xf3|\xcc\xfc\x02\x921\xfbR/\n=?`\xcb_\\h|\xaepH\xeboAL\xf6\xf6\xaa\xd1\xca$5\xa9\xeewNM\xf6\x9e\xea4u\xac\xbc\x1a\xdd,\x13\xe5U\xaa$\x88\xe1\xd3j\xbf\x81(\xaf\xf6\xcb\xe9\xc9\xde3==\xa9\x11\xc35'3\xa3*Y\x9a\xf3\xf2\xcd\xea\xe1w)\xcaG\x95\xf2kQ^\x9d\xeeJ\x94W\xc9\xe4R\x94W\xc1p'\xca\xab`\xb8\xe0\xe5[\xd5\xf6\xcfEy\xb5\xfd\x1bQ^\x9d\xef!*\x18\xdb\xf0n|{6\xc4\xce>D>\xeeP\xb8p/\x07\x87\xd74L\x0fW~\x9a\xd2Xl\xf0\x8f\x94x)\x96\xbf\xf3\x93\x94\x864vVn^\xf7C\x90-\xfd\xf0\xe7\xecB\xd4V\n\x8f\xe39\x8d\x1dR\xad\xfb)\xf5\x83D\xd4.Q\x0bga\xab\xcaj\x9c\xc6\x84\x91d\x12\xa0\x80\xde<\x82\xe4\xc7\xbb#\xb2\xa2\x9a\xfbC\xf69\xf1W\xeb\x80*\xd5\xc7pS\xa72\xecs\x18\xa64~G\xc9u\xb9v\xa6\xaf\xfd\xea\x92\x84\xcbrMCv\xb3\x13\x1a\x94\x07<\x86s}\xcd\x1f\xe9\"\x8a\xe9\xdbp\x9d\x95\xab\xd7]\xb4>#d~\x8e\x92\x02\xb8\x020?\xb1\xb5\xf3\xbd\xbc\xf8U@\x92\xc4\xf1\x8c\xf5O\xe9mZ\xa9|\x89\x95_\x1f\xbf\x97\xd7T\xa2\xaaR\xf2*\n\x17\xfe\x1235\xb4\xab\x99\xb4\xaey\xc1\x17}\xb5f%\xe5\xb1\x96\x0b\xdf\x10/\x8d\xe2\xbb\x16\xb1>\xa5\xc2\x81\xde\xc0\xba\x1a\x98\xb2\x80\xa68\xcd\xf3\x0d!\xc8\xf5iL\xc2\x84\xf0\x1e\xee4\x15\x7fd\xbc\x80\x1f.O\xd2\x98\xa4ty\xe7\\c\xa5\xda\xd8\xc3k?\x8e\xc2\x15\x0dS'0K\xf3\xf8\xed\x8b\xc8\xbf\x99F\x08\x00\xfb\x8cw\xa9\x03\xa8Kb\x9flxY\x1c\xd30\xed\x8eu\xf7 \xbc\xca\x9c\xa6\xc4\x0f\x12k\x15?a\xac\xcf\xdcV\xe7\xd2\x9f\xcfih\xab!\xfc\x02mU\xae\xe8]r\x19\xc5\xa9\x97\xa5\xd6\x01\x05\xe4\x82\x06\xb6\nq\x14\xd09M\xbc\xd8_#\x07e\xa9J\xb24\xf2\"FMRj\xab\x87\x92\x97\x1d\x06\xf4vM\xc2y\x03\x9cH\xb2\x8e\xd6\xd9\xda:=zm\x9f\xde*\x9a\x13{\x05\x19\xb5\xbc\xb1R\x82d\x8c-\xaf\xadj\x14\xfb4LI\x13,\xf1\xce\xfa2\n\xe64\xb6V\x8bi\x92\xd8\xc1\x14S2\x8f\xc2\xe0\xce^\xe7o\x99\x1f\xdb\xdb\xe1\xd3k\xa8\x13\xc5\xd6\x1drM\x82\x8c\xae\xc8ms\x1d\xdf\n\x1d\xac\x13F7\x8duRzk\x1d\x10I\xa3\x95\xef\xd9j\\d\x89\x15t\x81\x7fm]\xef\x98\x06\xf4\x9a4\x10\x0eF\x7f\x16\x0b&\x9f[j-crqa\x87?\xa3\xc2\xd7\xb8]i8o\xe8\xd4\x8b\x02\x8f\xf1\xe1\x0du\xd0P\xae\xa1N\xb2&\xd6\xe5\xf2\xa20\x8d\xa3\x06\xca\x884\xe6\x82\xce/\xac\xe0F\xcf\xe8\x15M\x12\xb2\xb4\x82}\x11D7id]8F\xf9\x82\xa6\xfe\xa2\x9b\xd0:\xecu\x94\xf8aB\xadP\x8c\xa3\x9bFH\xc7\xd1M#\xa4\xe3\xe8\xa6 \xd2 M\x13\xff\xef\x08\x99R\x8d\x8a\x00\xf6\xfa\xf8\xfdA\x9a\xc6\xfeE\x96R\xc6\x1a\xb2s\xaf^E\xf2\x1dy\x8d\xbc\xc2W\x9c\xc2\x8aFgX\x95V\xc4\xd5\x81^\xa3\xb3\xb7W\xad.e\xb0\xaap#e\xb0\xaap\x83q\x08\x9f\xf5a\xb4\xd5\x87\xcd\xbd>lmV,[\x990\xb6\xb9\xa9 \x14\x1d\x0d<\x12~J\xe8\xeb\xe3\xf7\xa8O@\xde%\xf1\xd9\xcc\x91\x0fE\xbd/O\x11Q~\x19\xc5\xb5R\xda\xfcjS\xf3\xc8\xc3+\xda\xf7\xd1\x9cb3\xb2\x00\xa4\xc3\xa0,\x18\xa8U\xab\xca\"~\xd3Zm\x9c\xf1\xae\xd5\x01\xb2\x07\x1d\xee\xb2\xe7\xd4\x0dk1\xf5\xbbHv\xc1V\x9f\xb8F\x05\xcaz \x14C\xac\x06\x9a\x07\xbd\x0dS'/u\xdc>\x8c\x86.\x8f\xe7\xa7\x11?+cu:\x1e\xc8HT\x0b\xc0\xec\xbe\xec\x0b\x86\xe4\xabL\xf6Z\x13\xa6{\x95G-\xc5t\xbc\xaf\x84W\x03\xe35K\xf5\x96\xdax\xd2\x17\x85\\\xa1\xe3\x00\xd9g}I\x12:\xffH\x97~\xc2\xf8X?\n\xe5\xb6\xd0Vg\x9f\x8b\xec\x82\xf1zc\xe8F\xa1\"\xb9X\xbc\x10<\xb2N\xb3\xb8\xfe\xca+^^\xb7\xe5\x87\xfa\xde\x96\x9f9]\xd3pNC\x0f\xd9\xdai7\x8d\xd6*\xda\x86\xf3n\x1fX\xe1/\xf4\xee\x03\xe3\"\xc4O\x862b\x98\xf8\xfb\x03IR\xda\xd5$\xe5\xab\xf7\xea\x95\x9a\xffN\x80\xac\xce\xa1\x1d,\xcbo}#p\xfe\x18d\xb1\x80\x92 \xb2\xaf\xa3\x9bP\x0f\xe7_\xe8\xdd\xa7\xb5\xf8\xfe>\xca\x12\x8aU\x1f\n\xe7\x93\x94\xc4\xdf\x0be_U\xba\xf9\x02X\xe3{\xdf\x15\xdabd\xff,xs\xc9\xf6\xfb\x03\x9c\xf7\xf3\x05\x10\xe7/~W\x90\xcb\xb1}C\x98\x97J*\xe3\xbb\x13\xaa\xbe\xbc07\x9b\xba\xd0^\xa5I{r\xad\xb2\x83[C\xe7C\xb3ZD\xd7r\xf7\xa2G\xc5\xab\xf2\xe1\xabk\x18gim:o {\xd0D\xd3S\x9b\xe3\x105\x19\xa8\x97@k\xa9\x84ki\xb7\x00\xd7\xc4\xac\xb3F0j\xb2\x1c\xd7ymhL \xafe\xde\xb7\x01W\xa0\x94G!:1\x05A\xe9\xceIJ\x90\xbbIa\x02\xe9\x80\xfd\xac\xdeI\x14#b]\xdd\xe4,Y}t\x87\x92\x8f5\x84\xa6\xcd\xfa\xba\xd8\x0e\x1e\x86l\xb3\x99FC\x13^\x82\xbaT5\xf2\xd6\x18\xf3k9\xa8\x9e z\xe39]\x17\xec\xbczX\x07\x87\xe1\xbc}\xf3\x82Z<\xac\x07\xfeR\x13\x9d\xe0\xd7O7\xdc\x96\x10\x85\x8fG\"J|u\xb8h=\xd7df\"1M\xd9\xc4\"\x92\xd3\xa3G\xca\x8e-\x07\xba\x16\x031\xf7\x8e\xab\xe1\xf6AI\x18^\x16\x08\x00\xf9a\xf6.\xc6q\x17\xe1{kMp\x1c\xab>:\x0c\xd1j\x8f\xe7\xa9c\xf2\xcd\xcd`I\xd3\xd7$%\x8e\xcb\x81\xb3\x0f>\xdawEQ@\xe7NTu\x05`X\xbd\xc0,\xc4E\xa5\xac\xd8\x03udO\\X\xf0]V\x8bsbp\x05\x95\x97\xd9\xe7Z\x7f\xfb\xdc\x92GDH\x91m\xb7qn\x8c\x07\xc4\xf3\xb2U\x16\x90\x94\x9e\xdeD\x1f\xd8\xf1\xfb\xdaO\xd6x\xf9\x9c\xe0E\xca\xc2J\x8dn\x1b\xf6;\xa9\xcf\xbf\x83\xd1\xa2\xe6U\x13\x9fo\xb6\xe3[m\xc7s\xa7\x1a\xb0F~\xda\x1c\x1c\xf2\x93\x1fF7\x97\xbew\x89\x8bp\x0d\x13\xbe\"cp\xee\xc4u\xd8\xaa\xa9\xabBd0\xf7\x95\x1bv\xe3\xfa\xea\x1b\x04\xe5&\x02Q\x1dc_\xdf\x15C\n\xf5\xef5\x86\xd9S\xf6]3M\xc1\xad\xdc\x82\\0d\xb81\xad,:5\xd4\x17\xb6\x88\x0c\xd7\xf1\xd8\xdc\x04\x07cj\x05\x14\xc0)\x1b\xbb\x11z\xfe \xa6\x01% un\xdc~~\xe0\xf5\x0d\x01,\xf5\xae\xce\xeda\x06\x0fBu.O\xb6Z\xabo\x8e\xe1\x8f\x1eA\xa7\x85iD\xe5m\x87\x0e\xbc4\x0e~\xa1w\xb8\x1ayJ~\xd8\xd0\xd1\xa2\xcf\xd1s\x80\xf2\x83\xf7\xba\xf9\xbe\xb9t<]XD\xa8\xb1\xa8\xf8*\x1b \xba1\x8b\xdcQ\x1a\xda\xd6HX\x01J\x810\xc1\xaa\xac\x96\xbc\x0d\x1d\x9c\xdf\xc4d\xbd\xa6\xf1I*\xb2~\xa4\xe5\"\xf3\xd5\x01gT0\xd0\x980\xd7\x0d8\xaf\xd3\x0d\xb3\xd5\x05\x8d\xf3\x95c\x0b`\x19\x0b(\xacw\x97\xe7\x8c\xc3\x03\xcc\xdc3`\xf4\xb5%Ms\x93TG\x9cyn\x112\x17\x1d\xefk\x15\xb4+\"?\xfa{\x8dz)\x9eB\x81\xd1\xe1D\xafp}\x8f\xa5_)*\xef=\xd595\xab)\xde#q\xa4\x8a$\xe2V\xb4i\x197\xd5@\xe0\xf8\xe5\\L\x17\xf5\x85\x928\x18\xd60\xd7\xe2\xce\xaf\xcfV\x00\x13\xa0\x0e\x0f8\x92]\x04\xbe\x97SMd\x02\xe2\x01\x99\x17n\xa8\x07\xc9G\xba8\x8d0m_\xbf\x1ab\x0bp\xe1B.\xc8\x0d\xce\xa3\x9b\x90Vc\x96\x16K\xc8\xc4\xb7\xe42\xca\x02!\x06\xb5\x81\xa6\x84I]r\x03\xa9\xae\xac]a\xe4\xd0\xa7\x06\xe8c\xb9\xc8\x86\x16\xd3\x85LL)\x86_\xbf\x0f\x89\x8c\x03\xf0\xb5\x03P.W\xecX\x90\x13\xcb\x94\x8f\xc3\xc7\xafb\x1c}\x08\xf1m\x0c#\x9eG+,\xde\x8e\x90\xc0\xf1\xbdY\x062g\x89\xdb\x80\xf7\xff5\xc8\x8a<;\xe2fLW\xd15-\xa3';\xf9\xbf \x82~\x075\\)\xe2\x80Q\x03iP\x8a\xfc\xe6\xc1^\x0b\x13G\xedR\xa7\x91Xh\xf3\xfb\x1e\xe6\\\x9a@d\x89\xfc\xe2\xac\x8d\xc1V\xd8\xe73_\x81 W8z\xe6!\x8b\xf0\xa0\xfb\xfb\xe0\xb5\xc4\x94\xb9h\x16D\x92\xe4\x04\xc6|\xb05\xf5G`\xb8\x96\x07\x19uD\xb4\xe2Y[\xf1,\xad\\WlZ\xc9\xa0 P\x88\xd0\xb8S\x0ds\xc9ov\xf0\x9d\x80S'V\xcc\x17\x0c\xd3`]WVq_\x17\x95\x17\x04dV\xfa\xd1 \x81\xc60\xca\x96\xd1\x08\xd0\xaf\xca\x83\xa2\x9c\xb6\xb3\xe2\xbc\x7f\xf6\xab:\xa8y\xd9\xce\xa98D\x95{\xa9\xeb>\xac\xf8&w\xfb0e\xbf\x1a \xa9\xfe\x8c\xcf\xb0\xf4+\x0f\xd2Z\xf4\x1bv\x8e\xca\x00+~\x14\x0e\xde\x7f:9=\xfftrx\xfe\xe1\xe3\xf1\x87\xc3\x8f\xa7\x7f\xad\x9f\xafj\xf5\x9f\x0fN\xce\x7f<>~wxpt\xfe\xeb\xc1\xbbO\x87\xf5c\xb7Z\xfd\xe8\xd3\xfb\xc3\x8fo_\xe9\xaag\x9a\xea\x1f\x8eO\xde\x9e\xbe\xfd\xf5\xd0\xf6^\xa2y\xef\xf8\xd7\xc3\x8f\xef\x8e\x0f^\x1f\xbe\xb6\x0d0\xd0\x9eR~\xf2*K\xd2h\x95k;\xc6\xf0\x91.\x0fo\xd7J\x94\xfc\x94&\xe9\xe0\xc2\x0f\xe7NHo\xc4c\xa7\xfb\xbb3')\xb9'\xb1O\xdc\x0d\xcc\x01\x14\x0f\x0eNO?\xbe\xfd\xf1\xd3\xe9\xe1\xf9\xd1\xc1\xfb\xc3\xf3W?\x1f|\xc4\xbc@?\xfc\xb9\xab\xcb\x1ao\x0f\x85\xc1><\xb3\x8e\xd6\x07\xb9x\xfc\xea\x92\xc4\x185\xd1R+I~\xa1w\x96\x1a)\xc6\x1c3=\x0e\x82\xe8\xe6M\x16\x04'^L\xa99\xb6\x0c\xd6\xc3\x08%xjx\x96\x0e\x03\xcbp\x13\xcb\xa3\xbb\xd03w\x9f\xa5\xd1+\x11\x12\xc3\xdcD\x96F\x1f\x02rglE\\\xec\x9b\x9f\xd3 \xf8@\xe6s?\\\x1a;auN\xd6\xc4\xb3\xd6\xb9$\xf1\x89e\xd5\xbcK\x12\x04\x14-\x1c\x8c50\xb4\xc7\x18\"\xb87\x8e\xd6\xb7\xc0\xc2\x0bH\x92\xbc}m\x7f\xceYLS\x8d(H\x8cA\x89\xbc\x88\x01\xc1\x8cV^\x14\xa64\xb4@\x80??\x9c\xfb\x18\xe8\xc3^\xef6}O\xc3\xccZ'\xc6\xc1\x9a\x00%*\xbc\xf3\x13\xdb\x88\xa2xnFO/\x8e\x92\xe48\xf61L\x92\xa1\x0e\xb7\x0c2?\xa4\xa7\xbe\x05\xdey|\\\xc3,\xe6t\x81\x81 \x0dO\xfd\xd8\xdc\xb2\x08\x96c~9\xba \x83\x88\xcck\x91 \xf3\n1Y.\xad\x0bEC\x8f \x04\xc6\xe7\x8b(^Y\x1f\x1e\xd8\xe9\x14\xabr\xd8\xa2\x8f\xf74\xbd\x8c\xe6\xd6*G\xd1\xaf$\xf0\xb9\xff\xa9\x01 \xac\x1a\xe7\x0f\xcc-\xc5dE\x7f\x8cb\x8c\x16i\xa8sI\xc9\x9c\xc6f\xa4\xba\xa4\xfe\xf2\xd2\xdc\x05\x0f`d\x1c\xe4\xa5\xbf\xbc4\xbf\x1b\xd3\x85\xf5\xe1;b!`\x97\xe9*x\x13Y&\x96\xa6\xeb\xc3\xbfe\xfe\xb5\xb1\x86\xefY\x16\xd37/\x10\xden\xbd\xc7\xf0\x8d\xc6\x1a)]\xc6~j>\x81|3\xc4\xaf\xe8\xdd\x07\x12\x93\x95\xb5\x86\x15\xc9\xae\xfc\xd0d\xeet83ov*nd\xd9$e\xba]D(4\x7f2\xec\"~]\x19\x95\xea3\x08a\x08|\xda\xd7\xed\xbe\xca>3$WK\xbe\x052\xd5\xd0C\xe4\x87xVE2\x11\x9b\xf4\x99>?\x84.\xd9L\xac\xac\xe8\xa40\x9d\xe7\x89x\x04\x85r\xbas\xff\xfa\xffa\xefM\xdb\xdb\xc6\x91E\xe1\xef\xf3+`\xde9ij,)\x96\x9d\xc5Q\xe2\xf6u;\xce\xe9\xdc\xc9\xf6\xc6N/\xa3\xf6\xf8\xc0$$\xf1\x84\"8\\d\xbb;\xf9\xef\xef\x83\x02@\x82d\x81\xa4lgf\xeey.?\xd8\"P\x00\xb1\x16\xaa\n\xb58\xfa\xbe\xb7\xb9\xf2\x1e\xfe\xfd\xb7\xf4//\xdc\xdf\xae\xb6\x07\x0f\xf1Q\xe8\xa5\xdbX\xbb\xca\xcf\xc5\x9a\xa2\xee\xd6\x04\xd1DL:\xfd[\x91\x8ab\xf8\x8af\xde\xd2M\xdb/>\x01Ug\xb3\xc9yU\x1f\xbc9\xf1\xa8yVH\x94np\xe0\xd6u'\xe1\x82\x1bkd4\x0e\xa2\x88%b\xbb\x08\x9c<\x9b\x9c\x93m\xc2\xc86 g\xbb\xc8\n/B\x1a{\x00\xbds\xfe\x9cx\xa3\xd1\xf3\x81\xd4\x0c\x1d\x874\xcd`\xe1V\x17\xa6\\\xda\xd5O\xb1\xe6\x90\xce\xb5B\x98\x9a\xf4\xf4\x87\x9b3\xba\x80H\x0d\x8e\xf4\xb7^?a\xe7:`\xb3\x8c\x16\xadgkH\xb8;\x1f\x8c\xe7<9\xa1\xde\xd2\xcd\xeaF\x80E/br \x83~\x81\xfa\x89\x1b\x8d=\xd1x\xb1m\xd3\xc1s\xb3?\xa2\x87Z\xdfQn\xe42\x0f7\x99,\xf1\xfc\xd7\xfb\xd8\x7f\xfb\x96\xcdm_\x82\xaa\x1d\xedkT+7nI\xcd\x1cTC\xb7\xaa\xd0x`\x86#~\xf0\x808r\x06\xc05\x03T\xb2\xe5:)\xcb^G\x19K\xd64\x94\xe9\x83\x8a\xde\xbc\xa9\x13)p\xb3 \xcd\xe1\xf3r*\x82\x14\xfe\x8b\x06\x8bO{4\x0c\x19S\xf5\x83\xa9G\xc6V\xaa\xda\xea2\x13%\x0eI\xa3\x12 \xa2\xc0\xf6\xbf\xdb\x98\xa3\xdc\xaf6\x7f b'\xe1\x0d\xd5c\xb7U\xd5n\xb6\x85r\x86\xc3\x08\x16+20\x99\x91\xad\x0c.\xc1x\x81\x8c\xc8\xa4\x18 ]\x1c\x9d\x9c\xb1\x1c7\xa3\x9ez(\xf9AK\xbc=\xb5.d?\xcb[v\x18F\x15\x87\x1d\xc1Jf\x9c\xbc&UX\xec\xbaH\xef:7\x13[U\xfa\x9e\xe0\xe4\x05\xc9\x9e\x13\xbe\xbd= \xd1\x8c\x9f\x8bI\x98q\x04\x05i\xf5\x9c\xe6\xdcO\xc9\x8c\x9d\xdf\xef\xb6\xb3\x1c{XP\xa4\xbb\x1ec\xa0\x13\x89h\xed\xcd&C\xf2\xdd\x0b\xc9\x1f\x16\x02\xec\x03'Kr\xe6|\xff\xdd\x908/\x1e\xca\xcc\xef\x9d\xf3\xe6\xc1(J;/\x80\xb1\xfc\xde\x01`\xf5\x1b\xf1\xf4=\xdb+a_d\x97\xdc\xbf\xf9\xfeE\x96\xe8b\xc9\xf7/\x1e\xaaDK\x1d^\xd9\xda\xf5\x82\\\xaf\xc2(=\x00\x8eo\xfa\xf0\xe1\xd5\xd5\xd5\xf8jo\xcc\x93\xc5\xc3\xdd\x9d\x9d\x9d\x87\xe9zQ\xb4~\xbdhT5G\xa9x\xe7/\xceT\xf6\xe8\xf0\x85\x1f\xacU\xcb\xe0\xd7y\xf38\xa4 \xa3\n\xfc\xc5\x8a\xc6\n\x1a~!\xd0\x1e\x0f\xa7d\xb6\xdb\x1c\x01\xddi\x8f\x87\x8b\x84\xe7\xba\x9e\xe2\xd56\x1a\xe2 \xd9\x82E\xben\xc4<`\xa1\x9f\xb2L\xd5P\xbe\"%c\x9a\xd0\x95.(1\x8b*\xa6_\x90BY\x82vAM`\xeb\xdc\x11y\xb7\xb0\x90\"wDn\xcacy\xad\x8bdyT\xe5!l\x92\x1e&4\x13\x9a\x84\xe7\xcc9\xcf\xf0\x9c%\xb3\xdcog~#\x08\xa0,0\xad\xbb\xa7,w\xfa\xcc\xf1\x82\xc4\x0b\x81\xc5\xf5\xc2 \xfe@\xb3\xa5\xf8\xed\xb39\xb8n`a\x18\xc4)d/\xc4\x9f`E\xa5\xaf\x07\x08\x80\xa2\xfe\xd3\xe4?\x13\xea\x07,\x02-\xdd\x15M\xc1\x03D\xac\xaaR72\xf0\x93\x877\x0b^\xfc\xd4u\x88\xc244\xebHddJ'\xcd\xb8\xf4\x0d\xc1\xae\xa5\x060\x84;8/(\x1b\xfba6\x07\x0f>\xc4\x1b\x12*\x7f\x99\xc1xk^N:i\x88@\x9c6\\\x9e\"\xf3\xda)\xa2N?p!\xe4\xfcEpV\xd4\x02\x11T\xe8?\xe7/\xa5m\xb5\xf3\"\x0c\xa2\xcf\xe4\xe1\xf7\x0e\x99\x12\xe7\x85\xa3HP\xe7\xfb\x17\x0f\xcb\xdfN\xd9\x95`<\x0f\x12M}\xa9\xe4C\xd9e\xd4\xd3\xed]\x0f\x01T\xc8`Qwoe~q\xe1BO\xeeW\x1f\x9d\xb8\x82(\xe6\x83\x99\x80\xab\n%\xfb\xd0\x0e/\xa2>\xac$Nl\xde\xc1<\xa2S,\xd1p@\xa3\x19\xc9z$=-\x97\xa8\xcfI\x8eK7R5\x85x\x9c\xc1\x86\x02\xa6\n[\xfa\xa4\xce\xbe\xaa0\x83\x0dW>\xb1\xaa\xbe\x9e.\xe3\x0cN\x1e\xd7;+\xe3\x0c\xee=\xae\xc3\xaf\xf1\x15\xa5\xc2\x0c\xee\xd4;\xab\xc2\x0c\xee\xd4 \x91\x1b\xd5\xfc\xfa`\xaa0\x83\x0d\xbb\x8d\x0b)\xb5\xd9{6\x18B\xb8\xc4\x9d\xba\n\xa4\x8a7\xd8\x18\xbe\x13U\xf0\x11\x14\x9c\xf8\xeb\xebB\xa2`r\x0b\xa2\x85\x16{\xf7\xa8\x10\xf9;\xe4l\x19\xa4D\xd0\xf6\x82c%W4%:L,\xb9\xbc!\xff%\xce\xa9H\x9cS\xff5Fn6\xfed\x7f\xd3\x1f(Ka./\xde\xa1'\x83\xb4Z\xfd?36\xbe\xc8\xe8\xe2\\\x1a\xd7(s\xcfl\xac\x97\x85\x1e)\x99jY\x0c\x8a\x1fu&{O\x1dA\x1d\x88\n\x87\xf6\xc1?$\x0e\x81\x0btA\x8f\xa9\x91P\xaa;\x84\xcf \x9c\xda\x96\xb2\xe5\xc0\x8b\xe1\x1a\xc3\x91\x0f\xf6\x89]M\xb4uO6\xfc\xc9\x0eHu\x11\x9b\xd9\xb6\xfa\xce\xc0\xa3\xa4\x15B\x8a\x94\x9fL\x9cA\xa5\x81p\xcf^1\xd158\xf72W\x14\xddu\x86\xb0\xec\x07\xed.M>\xb6x\xdc\x90N\xb6\x133P\xfd\x15\xea!\x19\xf1\x88\xa8m\xa6\xd9\xf8b \xa1!\xda[\xe4\x05\xac\xf2\x07\x0f\xf4\xcfRN#h\xb6\xd7`\x99#a\xa6\xe2W\x87 \xd3\x91\x9b\x0dI\x00>\xb2\x16L\x06\x8e\x85\x88\xc7\x1f\x19\xf5o\xdc\x81v\xa6\xe5\xbe\xc4\xee\x0e\xa0QQ\x9aM \x12\xeb\x99\xa0\xb6v\x16\x97\x9a\xa1:3\xa6\x88\xdf\xe7\xafVKQd\xb6^6\\ \xcd\xc7q^\xc6\xc1\x05\xe7\x92\xa2\xcd\xca\xcfd\xbd\x85*Y\xb7\xa7}i\xbci|l5\x8ey*G\xf0g\xe9\xca\x02\xbe\xd8^\xcd\xa7F5\x97\xb7\xa9\xe6\x1f\x8dj\x16\xdd\xd5\xe8_b5\xbej\x1ca\x19\x8f\x8f.y\x02w\xd3\xe2\x7f\xed\xcc\xcbx|L#i\x0e\xe0x4\x8aCzc\x05)\xfc\xe1h\xc8L&4\x0b\xbc\xcc\xe5|\x1c+\x0f\x85\x8e\xaf\x12<\xcc\xab`\xc6\xe3\x93U\x9c\x05\xe0K\x90\xc9_\x08H\xe4%7q&\x81\xf4o\x0c\xccW >\x9a\x9d$p\xa3\x0e\x91\xfd\x9a\xd9o8\xf5\x99/\xfd\xd6:!\xbc@\xc8\x0f\x0b\xe0[\x96Q\xdf\x04^\xa9\x04\xbc\x80\x8a\x9f\x04\xb0)\x12\xe4\x08\x1c\x96\xe7\xa9\x18\xb0X\xfcG\xb2\xe5L\xe1\xd3$2\x81\x88\x80\xfc Z _$\xa0X\xe6\xc4\xeag\x13\xe8#\xcdX1s \xcd\x98m\xd6N\x19\x03\xf3\x0b'\x85\x1f8\x80lQ*\x7f! \x19\x0d\xa5\xcf\xc9T\xfeB@\xf24\x06I\x8f\x93\xca_M\x90\xb3`\xc5t\xb4$'\x0bV,\xc7B\x1ae<\xfe\x89\x87\xf9\xaa\xec\xdd\x1a^m\xfd\xfb\x99\x06\x99l\xfe\x95\xfce\xd0\x11\x18 \xf6{c\xff^\x8f\xb3\x84z\x9f{\xec\xfd\x1f\x1aeK_\xcb\x82\xe0~\xfdR\x1f\x98{\xf5\x8b\x1a\xb1\xf3\x199 \xea3\xd5\xcc\xc2W\xbe.\xfe\xc8)<\xf4ft\x81\x1du\xd2\xd3{\x00\xba\xfb\xd6 ?\xeap\xc6\xdd\xb5\xcb\xeaMW@\x05>\x06\xb9\xa9/\x86%\xfeA\xba\x1bU\x0e\xdc\xd4\x1e\x01\xb9\x8f\xfc\xcf\x06\x96k\xe0\xcb\x84\xd1\xcf\xcd,\xd9\xb0u\xe03nm6\xcd\xfd\x00\xcb%\xa6\x0c=+]a\xdb\xfbp>$\xaf\x06\xe4U]\x1e\x93\x01\xb1\xd7Vx\x1c\xe7\xe9\xd2E\x86 \x1b\x92W\xb3\xec\\t\xdcB7\xb7v\\j\xac\xdd\xef\x8c\x9cH4Y\xe0\xcb[\xceI\xb0Z|\xf3v\x0d\xc9\xb7\\Us\x9e\xac\xee\xb7\x0b\x1f\x19h\x88\x11'Q?Z\xbap\x9a_\xae\x02)\xb4\xd4\xbfn\xd7\x8d\xc0\x128E\xad \xe9*\xce\x1a\xd7\x8b]g4a\xf4~\xc7\xe1\xb5\n/>\x14\xad\xd3?\x99=$\x01\x82;\x7fj\xe0\xce\x1b\xa0\x9b\xe4\x89\xd0\x87p\xfa\x11\xe5\xfd\xe5%\x07&k\xb8\xa4\xe2\x94Fs\x12<\x1d\xae@\xb0\x0c\xb6\xba\x14\xc7\x1f\x96\xb5\xb4\xd4\x15\xac,\"\x90@\xc6\x14\xc5\xb2>\xb3\x9b\x05\x8b\xf0\xbc0\x88>\xe39\x82\x9e\xc1s\xd4\x1d\n\x96\xa5Ug\xb1<8\x0e\xf1\xac\xab\xcbN\xe1\xcd\xcf\xe84\x89Uf\x95\n\xc5\x89\xad%j5w}\xf3\xff\x80\xff\xbe\xe6WW,\xca\x83\x8c\xad\x90\xf2\xe4\xc7\x9ap\xedW\xd0\xa2\x99\xd1\xd1\xefG\xa3\xbf\x9d\xab\xff\xd3\x8b\xdf\xc6\xbf\x8d~\xf3\xcf\xff\xf2\xe7\x87U\xf0\xbf\"\xb7\x95\xff i\xb5\xd3\x06#B\xfe\x8cJ3\n\xedJ\x1d^\xd0\x199\x03\xf2\xfd\x01\xd9\xa9J0\x02[\xa4\x92\xbfA\xb0\x01\xe4{\xbf\xb4\xc5\xd8\x13|{\x15\x17u\x85\xc4\xf9Oy\x03\xfeW\xf03\xfb\xe5\x0bq\x7f\x05\xf3su\xcf!\x08\x98\xc7\nW\xfeU\xdf\xbd4\xdc\xbc\x16\x04NUFb\x86\x03\xc9\xe8\x824\\C\xea\xcc\x88\xaeX\x1aS\x8f}\xfa\xf8\x9aT\xe3ph\xb9\x94\xbee\xa8e\xc7 [\x07r\x9e\xb9e\x9dRZ[\x1a\xa4\x05,u%\xa99\x17\xb4\xbe\xa5\x9d*\xbcv\xee\xc6\x16\x08\xd5s\x18\x92\xd7Q\x90\x054\xd4t\xbb\xa0%\xe7C\x92\x0c\xc9\xd5@\xfa\xd8o\xfa\xf4\xfb\xda\xe6fP|\xfd\xa4\\\x98\xf0\x8d\xf71\x8b\xce\xe8B\x9a\xdd\x1cE\xfe\x87\xf2\xda*\x85\x0f\xb6,\xf6\xebZ]JA@\xd6\xa5[k\xe9\xa7h\xfe\xd6\xb5@)?\xce\x8a]yN\x0e\xc9\x89X\xdeR\xf3\xebD\xaet\xb2M\xae\xc5/\xb9\xfc\xadKC\x02\xf7@\xe0\x1b\x92\xaf]\x14O\xc7\xc9\xf2\xa68\x82\xe6c\x9ag\x1c\xc2\x88H\xd3\xba\xd6r\xc1x. M\xfe\xe3\x9fr\x14w4\xeb\xd3\xbfSwZ\xa9\" r\x99gY+-\xf7o\xd0\x8dNz\xb3\xa3Q\xff\xe8O\xbc(\x99J\xab\xbeN\x0f\xcc\xd0CCQ+\xd6\xc8\x03l\x83\xb3\xb0\xb8\xd2H\xe0J\x03?\xc7@\xa7\xa7~\x8f\x91t\xc6\x89\x06/\xee\xb3\xa4\xc5T\xcf\x0c)\x11\xd8\xcfP\x0d\xfa\x1ek\x03x\xa7\xfe\xa8N\xa1\x04\xe2\xa2\xd8\x0e\x04\xfdt8\x87\xd5\x8f\x03\xba$\x92\x96\x01\xcb.7P\x7f5&\xc6$6\xdc\xfd\xe3\xebP+\xa2\x08\xa2-\x80x\xf6r\x9a\xe5\xfc\xbe\xe2 \x94H\xdd@-\xa6\x8e\x06\x135\xa29\xc1\xdc\xeccOA'\x9b\xf4\xe4\x9fK,\x0c\xeb\xe8\x90\xbcm\x8e(\xc8\xd4\xc4\x87\xbcz\x9bk~ ]1\xd8\x10(\x01\x85.\xab\x94\xda'\xb9\xd4 \"\xdb\x07\xc4\x01\x15\xa5\xbc}\xc2\xfb\xc6\xcb0\xcc\xc2#\x9f%g\\\xf0\xf9\x81'\xdbA\x0eID\xa6\xfa\xf4\xa9\xd2\x1cf[\x1a\xad\x07\xfa\x03\xf4\x8eZ\x80^\xbfT\x15\x83\xech\xd0\xea\xd3\x1d;\xb5\xfb\xf9s_\x17\xe1Kp\xe2\x80\x93\x16\xb5\xad\xe6J1\xf7\x1c\x1f\x14\x0b\x85\x8f\xa5\xce#\xccRB\xca\x04divP=b\xc1\x7f\x98\x15\x1aYZUL\xd0\x1b\x86\xe2\x98M\x01R?T\xadu\xc0\x0df\x84p]\x83\x9d_)Q\n\x0c\xdc\x89\x1b\xb4\xd1\xc5f \xda\x86\xd3\x12\xbd\xef\xa5\xfcQ\x13\x8aT\xc5[\x18\xff7\x0f\"\xd7qng\xa7O\xca\xa5\xfc\xb3I\xa3 \xce\xf37\x15\x02,\x19{K\x9a\x1ce\xee\x8e\xd8\xbb\x90\xbcM\x1225\xe2^\x10\xeb\xca\xab\xd1\xb7\xbd\xa5\xa6Z\x89\xed~\x97X>\x86\xd3T\x94\x17\x08\xe2\x7f\xc6bs\xa4\x83\x89\xc0\xe8 \x84\x86\x06\x0c\xd8{\x05Z\x1bY\x9c\xd5i\xfbB\x94\xec\xca\xces\x12\x92\x17$\xd5\xb6\x94$\xdc\xde\x1e\xe8fI\x0e6\x19\x92t\x16\x9ew\x912\x8d\xe8\x14\x1e\x0b\x8c\xf0\x14\x9ba1\x8c6i\x0e\x0d\x06e\xdc\xceHv\xb0h\x81\x9b\xc1\xc9\xdf\x8czR7\xe8\xab\x16\xbb\xc5\x16\x00\x19=\xbe\x8c\x82o+\xd7\xefb\x8c\xb8M\xdc\xcb\x15 \x82f\xda\x96%\xb9\x17J\x9a\xdb\xa4\xb3\xbaMh\xe6\x9d\xda\xd4)\xba\xe56\xf1\xacn\x13\x9ay\xa76\xf5\xe0\x03\xb9M\xec\xaa[\x85f\"$\xb3\x9d\x01\x7fW\x14j\x13\xaapE@7`\n,\xa3 \xc4V\x19v\x8b\xf8\xfa-\xde\x95\xda\xd1\x15M\x8c!\xb9\xc6\x83\xe3\xde\x95\x03\xec1\x1f\x97X\x83\xee\xf0\xc9\xcee\xd9\xc1t\xfe\xd4\x8f\xe9\xac\x9f\xfc\xc8\x0co\x80\xade\x8cI\x0b\xcf\x98 >\x00\xf4\x03:\xf3\x08\xc3(Y~4Y\x1f\x7fl\x96 \xe7\x91Yq\x85+\xeb#YN\xed\xecZ;\x1f\x05\xfd\x0cD?\xd3\x01I\xeb\xed\x0e\xa4\xec\x1fX%pU\xf2\xc7\xd7\xc1,8\x07B\xbd\x83\x9d\xb33\x8f\xedW\x8e\x92Z@\xb8`r\x08\x03G L\xad\xdc\xe6\x89`\xcc*\x0c\x1fka\xf8f\xd8A\xecB\x11\xd1\xed9\x90\x81q\xc5dfn\xaa\xd1\xc4\x83M\xd6x\xebZ\x12\xe0\x10\x98\xa6\x87Pb.\xa6\xb0}\xf1\x0dI\xdc\xb5\xa7Hek\xc4\x03\xb2\x15#{\xe3\xcb\x172\x87\xb1\xc0\xf3n\xb5o\xaa_\x9e\x0f\xd0\xca\x1f< \xb1\xa8OL\xc1\\\xfc\xb0\xecR\x91\xd7!\x81\x90\xfbM\x14E\"\xfb\xe9\xa7\xa0\xe0Q\xe9\x94\x98\x1aC85\x07|;\x95k\xa3\xdc\xaa=j\xaf\xc9n\x06\xf6\x9d\x9c\xb2\xacm\x1b\xb7\xdf\x8d\x17\xdf\xdb`\xa3w\xa3`\xdf\xa6|^\x7f\xca\xddrX\xedI\xd1K_u\x81L\xed\xd8\xc5\xdf0\x10k3\x05\x84U\xd4l\x80\x12\xd8\x15\xe3\x98c'\xb2\xf5\xfc\xbd5\xd7]\xb0\xb6\xac\xc2\xda\xb2~\xac\xed\xdd\x99c\nZz-6|\xd6L\xc5\xd1\xe3\xd5\xe6m\x02\x05\xd0\x8f\xbfU\xb5\xa9\xc1\xc6\xf3\x92\x8d/G\x0b/\x16vq\xffx1\xaf\xf25\x03\xbd[\xbc\x07\xcf+\x9f1\xe0\x11\x1aKg\xa5\x05q\xa4B]e\x06\xff\xabIr\x89\xb8#uF{\xa2\xc8\x16 _\x03\xf8\x8c]gJ\xf8\xe8V,>\x03PF(\xe4\x16\xd6\"d\x9b\x04\x03\xe3\x98\xcc\xc9!\xa1P.\xaf\x95SW\x92\x8e\x14\xf2\x1aE\xc2\x1a`\xd1\x81\x10\x0bg]\xdbL\x8a\xffy\x07\x0e\x85\x8b]\x84\xed\x1d%F\xab\x1b\xd5 u\xe6\x91]\x95\x10\xabyC\x9e\xfd\xff\xe9\xe2\x19\x8f\xd6\xf9\x95c\x87[\x01\xd8\x0f\x07iV\xdezvT<\\\xed<'\x11yA\xb2B\xfa\x15mo\x0fH6\x8b\xce\x95\x0e\x87\xcd\xf2\x9c\xf4a\xe7\xda\xf8\xd9\xde<\xe6\xf58\xcdx|\x96P\xefs\x10-\xbaN\xc7\xce6\x81\xc3\x82\xb6&-\x19\xf5\xdboo\xb9\x7f\xd3\xd2\xde\xc4u\x9e6\x1f\xe93\\\xf6\xd9i*C\xea\xa7\x8f&\x8bA6\xe0\x07\xa2\xf4h|\xc7\x03\xf1\xe9\xb3\xba\xcb2\x0e\x86\x87\xa3U:\xea\xf4\xdc]_\xeaj\xeb&n\xe1e\xdd\xe5C\xe2\xac\xd2\x913\xa8\xe3\xda;\xb5\xfb\xe1\xc8\x1d\x0f\x1e.n\xd9\xbe\xb2u\xc9\xb0\x1b\x85kW\xe0\xe3\x8c\x7f\x12\x14$\xe2\x02\xfc\xeb\xbdv\xceF\xa5(\xaa!\x19\x07\xe9\xa7(\xc8B\x96\xa6\xef\xc0\x7f\xd9\xa0k\x1cZ]\x19iQ\x02h@9\x97\x9c\x87\x8cV\\\x17\xcb\x0c\xa5\xc0_z\xe0\xaa\xed\x04\xady\x11\xa4\xef\xe8;7\xab\xa1\x07\xbd2DU \xe80\x9c(s\xc4?\xe5\x83\x07\x84K/\x922\xd2\x05\x99\x82\x08\xbc\x11!\x80HG\xe3`\x96\x99\x04+\xd0\xcf\xca\xc4y\x13_7N\xf7;N\xca\xfe\x0e6)\x0f\xff~\xb7\x8d2\xa8\xec\x94\x11l\x95\xfbl\xf7Cwv4\xfa\xdb\xf9=m\x16g\xf4\xe7\x893\xb08\xc3\xbfCk\xfb\xb5H\xcb\x0b\xfe\xf8\x8a.\xae\xa2 z\xe6\x17\xdb\xb8\xb6\xd8\"y\xf9\x90\xcd\"pq-M\x89\xa5\x14>\x82\xd54\x8b\xec~\x05\xc8m;lpg\x8fw:\xf7\xafej\xbes\xbe#\xdb\xb0\x88\xc8\xb6x\xb9\xe7\x86M\xcc\x86i\x92\xa9\xda\x10q\x08\x87\xecL\xd9\xfcb\xa2l\x8e\xcdE\x97A7\x01?\xa9\xea\xa6\x1b\xdc>\xa4 !(|\xa7B\xda\xff\x07\xf7\xe0[\x13\x84\x9ft\x931\xbb\xce\x12\xeae\xbat\xd9\x1e+s\x8e\xcf\xc2\xbd\x84~\xd9}2\xc0\xec\xe09z\xe8h\x9e\xc1\xb2\xcc\xa3\x19\xabn\xc0s\xcc*=\x9a9?\xb3\xcb\xcfA\x06\xae\xff\x80\x1c\xb9*\xde3\xc8\x7f\xcb\x7f/3W\xf2E\xe6\xac\xd22\xe3\xedi\x99\xfe\xbeL\xe6\x90\xda\xf8jm \x12\xe3`hN3\x8d\x82\x15\xb8\xf8\x02OM\xdcu\x8et\x823$\xe5\xcbI\xe4c|KQ:\xc8\x98\xf4\x14\xd6R\xc7k\x0d\xd3Z\x93\n\xf5g\xad\x05\x9cqa5d\x89\xa0?\xcd\xae\x9c\x15)\xa2\x86\xf2\x0d:S]\x81My\x02\xe6v\xde\\\x0d\xa6k{q\x00\xe6\xfd\x18\xf6\xca\xa0\x8a}\x01Q\x1b\xae\x82\xc8\xe7W\x80\x04\xa5\xa8\x8d\x04csf\xca\x97!i\x02\x14\x83\xdf\x0e\x06#[\xbe\x0e\xaac\x82\xb4\xa5\xa8\xa22\xb4\xc6[o\x9f\xd9\x82\xc6\xa13v^P.\xe2\xe5y\x03d+0a\x90h(\xe2\xe4 \x1aE\x0d\x113\xce)\xa2\\b$5\\D\x91\xbc\xd2.P`\x88\xce\xd1\x8d_qIJ\xee\x8e\x946s\xfc\xdct\xc1,%_\xbb\x93\xba\x0f\xe3\x1c\x97:J\xc7\xcf\x8f\xf6\x8cCE\xbb#~\x86b\xc7\xb0\xdb\xbd\x19h\x13 zY\xc6@5\xeb\xf5\xac\x07\xaa\xe3-\x99\xf7\xf9\x92_\xebHU:,\x1c\xb8\x84\xe7\x95\xd4\xc3R;d\x0c\xc5\x98oj\x8c\x8c!R\x9b\x05\x1d6\xa3)\x98\xaa|\x1b\x88\x95\xe8x\xa1$ nf\x11\xed$\x1a\xecX6\xb2A\x9a\x93\xb2\xff\x98\xcf\x1a\xf1\xc8\xb0\x9aR\xe8f\xb9f\x850\xa8m\x10\x10(\xba\x15\x80^k\x80F\xfeWX\xddx\xe3Tx\x7f\xd5\xbd\xf6o(\xd8\x9fd\xd8\xc16H\x15\x99P\xcfg\xa4\xccFX\xed\x9e*\x90*\xf4P!^\x91\xa7\xdb\xa5\xabJ\xc8!h\xe8[\xaaR\xfd\xc0++\xddc\xd6K\xeb\x9c\xe6\xd0\xb5\x9e6\xa6\xd9\xff\x06\xeb.\x1b\x9b#\xd9\\O\xac\xa7\x8b\x8dj\x9f\xcb1\xca\x8a-uh\xfc\x9e\x96\xdfm\x1d%sR\xcc:aN\xa1F\xf9kJl\xb7\xffU\x8f\x1f]s\xd1M\xcc\x92\xc6m'\xa6\x11\xde.\x9b\x95\xfb\x9d]3/\xcf\xd8{\xf5q7k\xb7mK\xc74\xa5\xb1\x1bv\x1aI\xae\x0b\x85\xf6\x88\xaeZ,\xe4Azh`Ce\xfbk\xe8k\xa2\x14\xbf\xf9\x14G\xa68Xr\xfb=\xd1\x10\xee0\x82\xe7\xc43\xc2\xf7=\x1f@j%\xa9\xdf\xd7\xe6P\xec\x1f9KnNA\xf7\x96'Ga\xe8\xca\x9b\xdb\x99\xe8\xf5\x81\xa0i\xff\xcf\xe9\xfbwc)i\x08\xe67Re\x01D\xd8\xdf\x9d\x83\xda\xcc\x81\xea\xfd\xf9w\x03\xe9\x02`\xe79\x89\xc9\x8b\"\xf4\xd9s\x12oow\x0d\x01Q#\xee\x83\xd6Y\xdc!\xb3$j\xdc\xfdR'\xc3\x1f\xcfy\xb2\x82\x19\x08\xe0g\x9f/\x12\xf5\xd5\xa5\x1ew=\xdeb\xec\xe1\xd2\xb5\x1e;\xcd\xf6,\x95c\xadg\xe0\xe4\xbb\\d\xcbn\xc9*.\xfa\xec\xce\xb5\xe7\xa0\x01\xa8\xf4\xf3u|\x19D>\x1a\x9eO<\x1e\x8f\xb2\x84Ko\xb2\x1e\xa6N\xd0\xaaM]\xa1<\xba\xf0\xc0\xda\xea@\xbfe\xf3Kd\xab\x10`sn\xca\xe3\xe9\xc1\x03\x12\xa0\xdaq\xf8\x06\x13\xdc\xb4\xa3\xaa\x85;\x1b\x88}\x8b\xcc\xbe&\x17\xad\xd5\xe0\xb8\xb1N\x9b4+\xaeZ\x84\xe1x|N\\)'\xe4pG\xa1M\xde\x00{\x0f\xf4\x0f\xc1\x8d\xeeX\xc4\xf2\xc5MD\x11\xd2\xad\xc4Y]\xb8\x1aD\xec4I\xe5]\xa1\xab\xbe6$\x93\x1d\x90\x18\xb5\xdc\xc9\xb8\\\xeai)\x8f1RcK\xb7VbH0\xa9,\xdb/\x91\x0c\xbe\x80e'\xca\xe2\x1a\x1c\xaf\x039\x8b!\xd6\xa3\x16\xf2*x\x03_W\xcfr\xd9\xd4JJ\xf1\xc9&\xa4[\x03E\x01\xb5f\xd9\x81y\xaec\x0d8.\xf3\xca\x8au\xe2\x01\xd9\xda\xaaC\xb6\x926u/\xe8\xdfl\x7f\xda\xb6Fs*\ne\xb1\xd6\x05\xa8\xf4\xab\xa4\xd7\xd66\xed\x1c\xe9\x05\xb6\xc5d\xa5KA\x08\x02\xbd\xb7~\x02\x9a\x06\x1a\x85\xdc\xa3\xed*I+\x1ee\xcbv=\xaa\xae\xaf]1f\xd3n#\x10a\xb5\xdc2C\xe3-\xea\xa0i\xf5\xd32\xaa\xaa\x82>\xdf\x8ej\x0c\xa2~\x9a\xc7\\\xc1\xb0[(3eb*\xdd\x11H \xa99?,\xbbdl\xa2zZ_(\xfc3u\x05\xcd\xe2\xcd\"M\x9dC\xea\xad\x04\x17f5\xce\xe9\xc9\xf1\xc7\x93\xb3\x8b\x97\xef/\xde\xbd?\xbb\xf8ptzzq\xf6\xe3\xeb\xd3\x8b\xf7\x1f/~}\xff\xe9\xe2\xe7\xd7o\xde\\\xfcpr\xf1\xea\xf5\xc7\x93\x97\xce\xed\xbfi\x08K\xeaR\x11\x15o\xb9\x1e\x0d+\xc0\x85\x1f\x94\xe0q\xa0\xf2\xf2^\x0f\x8e\xdf\"\xb3\x90V\xa4\xf6{\x90\xfa\x15\x9c\xe6\xe2\xc7Z\xad\xae\x88K\xc7\x86\x1d\xc8\xaf\x90[\x10\xe9\x9f\xacq\xd3&\xc5 \xe5)Z\xa6\x1f\x92\x8cl\x8b\x92SiN\x01\xd2\xc8\xad\x9d\xba\x9c}0$Y\xb9:*#\x1c\xe2\xee\xd9\xb8\xe9K\xc2\xd0\xa5\x96\x94\x8b2\xf6\xab\x17,d3\x92!\x01\xc4\x03\xea\xd5\xd7\x99[\xbf\xa8 V\xe4\x10\x0c[\xbc\x80\x98=\xb7X@\x08\x90\xc0PDo2\xca\xdbb\xf7OI\xea\x96\xfa\xef\x03\xf9\xd1\xad\xc9\xb0\x16\xe0\xb7]7\xa9\xe0\xc6\x0c{\xf4\xa4b\x8fn-J4\xf7 .\x0ef\xe1\xb9\xe4~\xfa0>rEv\xb36\x80\xda[\xa1,\x8a\x1b\xa5Y\x90l\x9dl\xda\xed\xe5\"r\xbd\x08\xa6$\xefX\x04\xdf\x96\xe8\xb1s\x1c\x06!\x19X\xe8\x9f\x8a\x037\xd7\x01xg\xa8K\xb6\xd2n\xb7\x14\x87&\x16\xf9e9\x9cm\"\xbf2l[\x8b\x14\x12\xa1\xeaJ\x99oU$\xa7\xbf\xaaN\xcc\xe2\xd5\x0ei\xe1\xbf\xc0\xe7\xa3\xb9\xf7\xec\x02\\\xf5-\xaft5\xcd+\xd7r\xa4\xcf!-U\xee\xeez`nt\xbb\xd0\xbcE\xa0\xf8A\x9aoz\x8b\x90\xf6\xbaE\x08;n\x11\xf4/\xfc\xb8\xdap\xb9j\x81E\xc9\xff\xd8\xad\x9e\x12\xd7y6q \x82\xfe\x1fmRp%\xaf\xbe\x1f\xe1w\xb9\x13\x1c\x159nC\xa1\xf7\xbf\x8b\x9c:\xe8\xbe\x1f\xb1\x9c\xf8\xa6fT+\xc5@\x1b\xe2p\xbb\x187$\x07\x9d\x0ed*\x96QnE\xd7V\xac\x85]\xb1\x16\xaa'n(\xc5 \xa1:F\xc9\x8b\x032\xd1\xf2\xb9=G\xf9~ g;\xe7\x03\xe9\xdc\x16\xe644\xb8r\xa9\xc8K5\xd7\x00\xc2\x9b\xe6\xfc4R\xfa\x1efUq\xbc\x94S\xfc_&w\x0f6\x95\xbb\xab-\x9eK\xc9hZ8m\xec\x10Rv\x8c\xfa\xbfD\xfcH7\x92\xfc%\xf5]\xd7E\x92v\x10\xe3\x92\x9e\xc2\x07Z\xda(F%%\xe2\x96\xfc5\xafH\x9d\x1ar\xab\xa8.\xb7B\xa4o\xcd\x15o\x17\x995+\xac\xc9\xc0\xda\xe6\xf1\xb6D\xdbf3#E\xc9Yi\xc1\x89P2\xea\x82\xdb\x8e\xee\xa1\xafY)\xc5\xd8\x90\xfd\xff\x96\x94\xc5\xee.f\xcf\xe4\n\xf8]\x19\xe4X\xda\xf2l\xaeg\xa3A\x9f*v\xc3\xa85\xfd\x90\xf0\xa1\x9dQ\x04Y\xbfv\x90\xd6\xd6\xec\x14\x1cGgC8;i\xdd`\x99\x0dE-\xc5\xe7\xa4\x06\xa9\xbd\x86\xf28B\x17V\xc7\xaa\xe0bU\xd0\x86\x05q\x04\x12T\xd8\x0fQ}M\xf0\"\x9a\xf6d\xdffg\xa5\x95\xbeg\xaer+h_DR\x1d\xca9;\xf9\xe5\xec\xe2\xf8\xfd\xbb\xb3\x93wg\x16G\xacD]1\xc3\xd0X\xa2 \x8bg\x0e\x07\xb8\xcf\xae\xbb\xbcR\xce\xd5M}\x17\\\xc6{UG\xe7\x19K\xca\xfaP\xb8\xaf\x03\xcc\x1d\xa4m14\xdd\xd8\xfe\x8f_\x07\xa7'g\x17o\x8f>\xfe\xf5\xd3\x87\xff\xb7\nH\xdeq\x1c\xdbVCf\xf8\x16\xbc\x1dIp\xdb/\xd7\xcf\xc9\xea\"\xb4\x8f\x1aG\x14\xb5\xcd\x87v\x9c\x809r6W\x89\x19Wz0\xa5\x92\xa0\xb0\x9f\xcf\xe2\x1c\x84\xab\x97V\xe7wp\x0c\x0d\x0b\x973\xed'\x1f(6\xb5\x83\xf8\xdd \xcbn\x90\xb5\xf5\xe6B?\xb0\xe1=\xa9*\xddZ\x15\x0cC}\xcb{\x9d\xe4\x00Qc\xb3\"\xeav3\x99y=\xe8\x02\xf1,\x04E8\xf3z\xa8oIU\xad\x059$\xee\x1c\xa4\xb9su\xe4\x97\xc1cVC\xb2\x1eB$\x9e\xc1@\x86\xe3yK\xb3\xe5xE\xaf\xdd\x95y\xc0\x0b\x80!Y\xd5\xce\xfc\x18|\xf1\xad\x80\xb1h/\xabB:\x95M\xb8(\x11\xe8\x91\x04s\x17CBg\xcbs\xdd\xa2L\xd9B-\xb7\xb7\x07C\x12\x0b\xf2b\xad\xf9|\xed\x81\xc7E\x9c\x7f\x98\x8f]\x7f\xab\x9c`>h\x1a\x03zR\xbaUk\xb2\x89\xf5]\x980\xc2g\xde\xf9\xa0\xcdm>\xf8?\xd2\xe8}^\xfa\x0fi\xd2\xb5\xcdK\x17\x82\xf6\x00\xc3\x7f\x91\x95\\o=\x087<\x05\x9b\xe7^f\xfah\xb5\x84\x9c\xec\xd3\x81bA\xf6vLF\n7\x05\xe6\x92|!\x80\xeb\x96y\x1d\xa8\x98\x94\xf4g\xfb\x9eU'\xef\xdb\xf7?\x9d\\\x9c\xfc\xf2\xfa\xf4\xec\xf5\xbb\xffl9|\x89y\x00w#?\xe3\x1c\xae\xf4\xa9\xbb\x94{\xcd\xae\x11\xaf\xac\xc7E\n\xb1L\xed}\xcd\xeb\xc7\x13\xd8\xc3\xef\xde\xbf<\xe9;\xab\xdd\xe3\x7f\xd7\xfd\xdbB\xa2\x93\xfeT5\xe9IY\x93\x8em\xdbkV\x9bg\xf8-$a\x85\xc5w\x95\xb4H\xd4\xa9b\xe0\x05Qe\xd4\xbbm\xe6Q\xd5s\xcd\xe9\x0b<\xf8\xb0\x19b\x8f\xe1w\xf0\xc4\xde\xfcH\xbaBl\xb6\xf4O\xf8\x9bEt\xedA\xea\xadD\xd7\xa5\x9b'\xd4\xd6W\xb9\x17\xa8\xfb\xe1 \x86\xa7\xae\xfa-8)\xa5\xdb\xbb\xbb{ \x97\xde\xdd\xdd\xad\x0b\xb4\x89\xa1x\xb6_\x1b\xb4\xdau91\x85\xccy\xc7\x81\xbfV\xb6\x1b\x86\x17&\xd60Z$\xe6} \xa8\x89H\xa1\xb7\xb4\xb3\xe7\x82^i*\x89U\xc7FV\xbfu\xa0*x\x0fN \x11\x15\x0f\x81=.N\xde\xfd4%N\x9cp?\x87^ \xe8\xe4\xe7\x93\x1f>\x1c\x1d\xff\xf5\xe2\xf5\xbb7\xaf\xdf\x9d\\\x9c\x9e\xfd\xfa\xe6\xe4tJ\xb6&\xd5F\xd4FJ\x8b\x0b\x9b\xdfE\xa4\xd8\x1b\x13M\xfa\x8e\x8a\x0dL\xb5\x80v\xb9j\xdd0\\?Z\xbc.>\x9d\xcb@\x01\x1b\x88\xf1\xda\xba@\xa1\xc2\x14\xa2U{\xe0k\xd7\xde#\xf0\xe9\xd1y#+\xf8\x9c\x0e\x9e/n\xf1\xbd\xa4\x1f\xd4\xba6\xee\xcd\xf3 \x06\x15\xd8%\xb8\xd8b\xb3\xf8\x1c\xb8\x0d\xbf~G\xda\x8f\x1d\\\x83\xf5n_k\x1e\xbd9@?(p\x97C\xb2\x1e\x0cH2\xae\x07Sq}`\xc3\xf2!\xf8b\xca\xa4\x1f\xa2\x96\xb1\xd3O\x0f\xbfJ\xfa\x91*JTV\x9dT\xa8W\x1f\xdc.\xd4\xbd\xa2\x8a6mM\xfa\xc4(#\x06w\xcd\xdd5l\xfa~\xa5TOW\xfd\xa0\xc57\x16\xd0\xfaZKW\xf5\xa5\xdb\xaf\xbeH\x8a\xcf;\x98Z\xd2\xca\xd8\xb6\xe7\x96k\x9c\x0d\xc8V\xc3\xc7[\x0cV&\x80\xf8\x90\x05.\xcd\xf5\xc1[[|.\x98\xf5\x8d\xa7\x0em\xd7]Y\xdc\x96\x13\xbdj(o\xf1vG\x88\xc5\xe3]\xd4\xb9\xa55r\xc4O\"\xf3A\xc6\x84\xa3\xb4\x8c~\x90Q\xa9\xa4\xd4\xd0\xb1I5\x94\x17|_\x07\xca\xb5\x8c8\xac\x1f?V\x13p+z\xa2\xf3*\xdc\xa2d\xd7PV\xa7\x96\x8bs\xa5dW\xf7\x89\x99*U\xbd\xba#\x80P\xb5\xa5\x9e\xeeU|h\xee=y\\'P\xe68\xe5\x13\xcb\xfa\x1a>9}Y\xdf\xbe\xa2w&\xf5\xea\x96\xaa;\xf5v\xacK%\xfbzO\x05Z\xaa9\xce\x14Xd\x17\xbb\xd2\x07\xc7T\x7f`\xb7\xf2\x97\xe8\xca/\x15H\xcb\xe5rS:\x7fU\xd1 M\xdf\x15\x18u\xc8\xc8\x01 \xc5\xbe\x96:\x89xX\xe8\xc6\x02\x85\xbb\x0b\xe9\x94Z\xaa\xf7(\x12^*\x97Wbf\xd5c\x0d(*B\xf5\xa9\xa2\xb5_]\x82\x17\xcd\xb1\xbbB\xe9$\x8fGi\x96\xe4^\xaf\xebALM\xcb\x88\xf3eq\xf7\xeb\x89\xad\x9c\x06\x19;\xbb\x89YA\xf4\xcb\xbc@i\xc6\xd4\x92\x8d\xd0\x8f\xcd\x8c\xca%l-_\x0e\xdb\x0f4\xf3\x96\xd2\xffZ-?f\x91\x1fD\x8b\xb2\xedH&h\xd6\x80\x03#<\xff\xa3\xf4\xb9\xa5\x15\xeb\xb6&\xb5\xfcW<\xf1\x98\xbc-\xa8dk\xc1\x9f\x18!d(\n\xb9\xa0\xc6|\xb5|\xb5>j\xa9\x80,\xdf'r\xb1\x16C\x9e)\xafOJi \xef\xc71\x0d\xc3K\xea}N\xeb\x1f\xa2ah4\xe3\xe7 \x0c?I\xa4\x0c\xddi\xac\x0c\xabZD[\xe46\xab%z\xbd\xb3\x1c\xed\xe9\xc5\xf66\xbaV\xb2\xd6\x85b'\xdd\xe9\xd0\xb8\xf3\xe9\xaf\x83G\x14\xe6U\xe3\xaa\x14}\n+\x11{!\xcf\xf61\x1ce\xe8g\x0eJ\x82\x0b\x96\xc9\xe5%\xbdl\xb5|\xc6o\xf5\xbeS\x7f\x14v\xd9r\xb7X\x89\n\xc1\xfa\xd8x\x1f\x07)\x04\xbe*f\xb7\xe5lv\xbd\x96\xb6-\xcb!\xd08\xa8B\x08I\xca\xd0F\x13\xfafD\x86%1LV\x97\x1ay\x1f\xf6\xf2eF6\xe8\xf8\x87\x9d\xe9\xb3tl\xb2\xeb\xb6N\x05\xd2\xb8!\x91\x1e\x06b\x1eD\x99-\xa0\x07\xee\xaa^?E\xd4Vl\xa5V\x9b\x83#f\xed\xda>o=\x0e\xc6 \x97\xa4\x91K\x07u\x1c\x86\xee=7o\xd9\xf9\xa0\x96]\xadC#\xa7\n\xdd\xf0\xc1(Y/`2\ne\xaa\xc2\xc2\x83\x016\xbeV\xba\xb2\xc9bo\xed\x808\xa2\xd2\xeb;\x0fu\xdbZ\x0dn\xb9\x1ao\xb5\xf8\x8aq\xd6\xe3f\xa7IZ4_\x83\x12\x83 \x8a\xb8@|.\x96\xe1v,\x87\xa0\xc7\n\x08\xf4\xa4\x07\xe5<\x0f\x86\x15\xc1~\xa1\xaan\xce4\x90\x0543&\xdc\xb5 \x03\xd7\xca\xe5\xbd'\x90\xb78\xecQ\xcf\x18\xa4\xa1flp0H0,b\x08\xe6\xcd\x81\x07a|\x95|\x02i8\xdc\"x\xe3\x93\xb7\x1f\xce~m\xbf>\xb2,hI\x85\xcc\x11\x15\xdeD/\x92*\x81\xbe\x0cB\xdf\xa0\xd2\xb1(\xde\xc8z\xec\x1f\xd2\x8a\x187\xb3\x15\xb1\x9f\xa5\x03\xbd>\xbfi\xf4+\xa2E\xf0\x96ov\\\x02d\x8dmc\x97\xdcII\xbf\x87q\x8c\x0f\x1e\x90\xad\xac\x8d\xa7\xecs\x87\xd0\xc1\x92\xee\x0c\xdb\xef4\xf4S\xb9\xb8, \xbam\xe2\xa0mw\x07\x1d\x01\x05\x08\xe8w\x07\xd1\x9a\x7ff\xff\x99\xd3\xc4g\xbe\xe6\xa9A\x05\x00\xadU\x9a\x93e-!E )\xac\xd6\xf1*\xda\x82a\xd9\xb6\x08\xe8i51\xbf\x05\x1c\xd3W\xba\xa5\xd8\xa2&\xe1\xf9\xf6\x14r%\xdb&\xe3h\x95\x03\xe1\x92\x16\\\xb8e\x93\xb4\x84:p\x99\x8dE\xec\xb3\xe5/V4\xfd\xac\x10U\x9f\xed\xben3\xa7\x04\x1eVuM\xcc\xa3%\xec\x07\xf8\xdb-C \xc4v\xfc\x8e\xf9\xc1\xd6O5~N6 \xd1,9o\x0d`c\xf5\x14\x87\x8dKU\xd2\xb2\xf9\xd0\x18\xe3j=\xf2\xf4\x99\xb3Q\x83\x8c\x93\xa5w\xabL=\xfb\x8d\xa4AM\xca\xc6>\xa5\x81t3[6\x8f\xe8\xe8\x0c\x8d\x1c\x19\xa8\xa1\x0d\xa1VC\xf0 \\\xb5\xf2rpl\xac\xb6\x82\xa5~\xba9K=\x90\x1f\xc2j\xd5B\x8f\xfd\xcdj\x15g\xbe\x1d\x89\x96.w\xbf\x02\xdf\xdb{\x0f\x13\x83\x1d\xeb\xb5n\x80`7;\xd4_\xab\x0f\xf3\x81\xd1H\xaa_X\xf7\xaf~]Q\xbd\xef{\xe5\xceM\xa1\x9e\xe8T\x1b9\xd9\x86\x84\x95\xdeCyP\x011\xc7@I\xaa\x9f\xaa\xa4b\x1f\xe4\xd9\xf0z\xfe\x8e\x89\x0dJ\x93\x9b>\xfb\xb2P\x8e\xc1\xdayH\xe6ME\x80\xcc\xb0\x14\xab\xc2\x0f\xcb\xfb\x11M\xc7\x97\xce\xa8\x0f\xac\xa7\xe1\x97/\xf6\x83\xee\x10\x1f\xa3\xf2;\xd5\xd9jO\xad\\;\x99M\x94 \xb6\x1b\x95>SPk z\x0f\xd0a\xfdI{\xe2\xb8\xc8\xf4\x97 0\xc2\xde\xa6\xa2\xbb\x16\x16i\x08\xbc\xcc\xd6\xa4m1\x17D\xc3\x81\x0c\xd2\x9b\x83\x11\xb8N\x9dJ\xd7[jF\xab\xf7\x04\xc1@\xd5o\xd3\xbeX+\xc7&\x9dW\x11\x10\xe2\xd8\xe6\x1d\x88\xc0\xd5#X\xe5\x03\xeeW\x9f\x1cJ\x17\x98\xb4Ji~\x94\xeb\x1b\xbc\xa6td\xbb\x9e=\xa6\xd9Z\x07\xfe7\xfb]\xe1r\xa1\xb0\xbdGq\x8bw(\xeb\xf6\x80\xf8h\xe3t\xc9\xf3\xb0$K\x8b\xad\x13\xc3\xc4\xa0\xb9\xa25\xf3\xa1\x8c\x82\xacg\xb5\"\n?8 \xd2\x8c\x03\xda\xe5\xbb\xe1\x90x\xb0\xac\xb6|\xf1E\xd1\xa3!\x99\x03\x9f\xde\xbe{\x86$&\x87\x9a7\xeb$e\x01\x91\xd5\xdb\x1aI\x9d\x19\xb8(ab\x17\x81\x95 \xb6\xd5\xc57\x9b\xb4m0$\xb4\x10\xea{\xe2E\xcb$\xe6Cc\xe5\x1e`\xa6=-$\x909\xbb=\xd5O*|Y\x0f)My,5\xd0f\x1fb \xe1,\xect\x93\xb5\x08\xc6m \xcc\xccVii\x11\xb5]dHGo\x0f\x1e\x90\x89r\xa4+\x1d\xc6\x14\x85\x93\xd9\x8e\x85p6\x88\xb1\x03E\xb2\x08\xfc#\n\x88sF~T\xb9\x84\x13\x19\x132%;\xcfI^\xf1\xee\x96\xb7\xfb\xc5^\x1bf\xd9v\xb2\x89\xbbtH\x1c=\xe5\xa6'\xc2\x94\x1c\x92T\xea\xd8H\x8dE\xb9\x1c\xa6$\xbd\x05e\x85\xf8\xbf\xc1\x96#\xbakn\xa1y\xad\xaf\x87\x87\xda\x13A\xdfe*\xb0\xf1\x0f2d\x9b\x1bV\xee?d[,8\xd3#\xda\xe3O\xa8%\x809\xbc(\xf4\x02\xbe:\n\x91\xe0\x90\x845\x19\x81D \xe07\x0b\xc9(\xee\x03p\xaa\xc0\xd4\xe6\xa8\xa0\x8a\xb0@\x15\xd9P\xb7E\xe2\x95\xd0@\x15I\x15\xef}\xac\xcb\x06\\\x18\xe8\xa1\xec#o\xbf2\xc2\x86L\nO\xc2B\xe9Ut\xbf\x1fv\xb24\xe8V\x18\xaa).iEU\xd1m\xc8g\xbb,\xb7\x1d\xc5\xd9\xa4\xd7s\xe2.]\x10\x95\x0f0\xf2URb\xacMP\x9a\xd9\xa4\xc8\x1d\xca\xac\x1a5U%\xa16{Y\xf1 r\xaah\x88\xbb@\xd7OS\x92\x8d\xb9\xdb\xd6Ou\x1a\xbb\xa5\xd9d\x03\x896\xef'\xd1&-\xb2\xba\xd6\x90\xac\x9a\x18\xc4\xc4\xdd\xc5\xfc\x95:1fJ\xcd{E\xdbT\x8bm\xda\xddp8\x0d\xc5\xf0\xfd\x1cdK\xe9]@\x1c\x01!\xca\xa2\x91\xdeR/\xb4\xe2\xfe\x9c+\x1d\xe3-c\x1b\xd8\xd9Y\xf7\x9fy\xb9\xfb>i\x8az\xda0\x08\xeb\xc9\xcb\x14\xc62\xb2\x11\xee\xddZ\xdc\xb7q]4P\x95\x14\x16+|\xd1F2\xe4c\x85\xf4T\xa7[VS\xeb\x95\xafx\xba\xaf\xb8\xd0iA\x06N?_\xc9<\x88h\x18v}\xd9\xec\x05\xca\xf5\xea\xa7\xd5\xf9\xec\xad\xdb\xdf.*\xd5\xdaA\xcc\xd0\x0eb\xa8v\x10+\xb5\x83\x9em\xc8\x16\x0f\xfbI\xb2h\x96Qo\xf9\x91\xcdos\xa2.X\xf6!\xbf\x0c\x03\xafp\x94f\xe9\xb9\xe6\xf2#\xcd\xe5Ov\xda\x18w\x194\xa7w\xedn\xa4\x14\x99\x0e\x0e\x80=\xd3\xaf\xe4\x8f\xaf@I\x8b\xb7\x81\x0c\x04\xd7\xcbv\xc7g\xc8\x98\xd8\x06D\x05\xd5\xb3\x8d\x07||\xc6\xce\xfb|W\xcdl\xdf\x8d\x7f;\xe1s\xf3~\x10\xcc!*)\xe3B9\x86[\xdcQ\x15\xa8\xae\xa6\xae\xa6l+j\xa9\xacPbS\xf9\xfa\xb5\xaf@\xaa1\xb0\x1b\x8fQ/\xcc\x8d!L\xedc\x02\x96\xf0\xb4\xdf\xa6\xb2\x93\x19\x88\xcd\xaa\xc56R*X\xdd\xc9\x96a\x82\xd7l\x1d9\xcd\xb2no\x17\xc9_\xef\xde\n\x94\xb1<\xbdY]rp\xc7*\x7f\x8d\x057\\ys\x9dD\x8c\xdc\x98\xc9U\xed\x00\xba{\xb23\xd9\xd9\xc3{\x95\xfc\xb3Z*\xa3s\xf2\xa4:\xed\xe0W\xf3\x7f\xffo\x9dy\xeb8\xcc*\x04\x0c\xa8\xe6\xcd\x92s\xd8=3~^\xc3|\xe0\xb3\x1dkmy\x01X\x0f\x0cp\xab\x91i\xb1\xb2\x95V\xb2\xcf\x1b\x9d\x90F4\x9b\x19\xc7\xf2\x0e%;0_\x12CR\\Y\x19\xc1\x12\xda\xf6?\x18/\xb53^\x86^\x0e\xb7\x9a9\xed\x0c\xa5\xa9md\x1a\xdf\xba\\\xda\xddvG\xb8\xaa\x0e\xd2\xbf\xca\x04\xd7\x16\xdc\xd5r\xda\xe3\x96\xb4\x08\x02m\xbbS\xd6(\xc5\xd57@-\x8e\xd3\xbf\x891\x17\x1eb\xe4I\xdd3\xba\x0e1\xf2\x14\xb1\xe6*\xcd\xad\xf6'\x0d\x07\xa79x\xa4\xaa~\xbai\xd9\xacd#\xd5S\xabb\x1e_\xfc.6E\xd8D\x12p>%L9\x8f\x0d~g\x10\xef\x97\xaa\x1a\x87:_\x90\xaag\xfc4\xa3Y\xe0I\x1e\xca\x10\x0f\xe5);6\xa3\x19\x9b\xf2\xd0\xbc\xb4NP\xea\xe5\xb4\xd5k{\xd3\xdd\xa9\xe0\xe2\xcb6)\xe5\x8a\xb4\xe3\xb4V\x8b\xa4\xea!\xa8v\xac6EN\xfd*M;*5\x0c2\xfaUX\x1f\xa8\xb6\xfa}\xa6\xa9\xa8\xda\xccW\xc1J\xed\xcfV0\xad\xe6\xd9\xb2\x8a\nP7,\x0d \xc03\xaa7\x18\x12>\xa6\xbe\xff\x81\xf30\x88\x16g\xdc\x0dk\x18\xe1^\x1c \xef\xee>2\x10\xbfD\xfa&\x14o#@\x8a\xb5\xcf\x9a\xe7\x0d\xa9\xc5\xb8o\xe1Q@\x15\xc6eD\xd3|p.\x0eH\xb6L\xf8\x15\xacjA\xd8I\xfd_\xe7\x98F\x11\xcf\x88\xc0<\x84\x12/\xa4iJhJh\xf1%\x07\xc1\xee\xea\xd6\xb8\xd0\xb5\xca\xca%/\xce\x83\xea\x92\xa8\xce\xa1\xa6\x9bM\xf3\x14X\xd3\xac\xdb\xe6G\x9b\xbb\xd4\x10\xfb\xb0R\x9dB5Z\x81\xaa\x8e\xe9-\xf2\x97z7\xc6A\xfa:\xaa`\x17\xe0\xdc\xea\xb5\xe3\xb2\x19\xbcE\xd5k\xb2\xf6\x9en\xd8\x1c\xa3\xea\xba\xc3w\xbc-\xb5\x0b\xa1\xceU\xb5a{\xcc\xea\xdd\xa6\x1e\n\xde\xa6S\x96}\xab\xf6\xe8\xaa-m)1\x88\xc9a\x9b\xa8\x81\xdf\x07j\xb0\x9c\xc5\xfb\xb6\xb3\x189\x8a{\xac\x1a\xe4\x0e\xb5f\x87\xfa\x8e\xfbu\xa5\xc5[\xdb\xad\xfa|%\xf5\n\xab\x83jbbjb\xe2j\xa3\xbb\xcd-\xad\xbeb\xa8\xbc\xa0\x08\xfcc@\x1e\xc9\xf6v\x93\xf8\xaa6\x91\xa2\x9d\xdd\xd4\xf0R\x0b\xec\x1d\x02\xec\xd9\x88\xad\xe2\xecfJ B\xa5\xf1\xb9m\xe2\x10D\x0bW\xfa!\xa8\x93 m\x14|*\xfb\xc9\xaf\"\x96\xbc\xe4^\x0e\x12\x0e\xe55\x89\xaf@HfSb\xd06\x0b\xe38a\x1e\xf5\x96\xacP\xe5\x967P\xdcEn1\x9b\xf2\xc0\x9aT\xb7FX\x1d\xca0^\xceo\xd7{\xde\xd6h$\xc6!\x17\xbd\x1f\x8d~\xbb\xdecNm\xaf\xd5\xce\x02\xab\x8eW\xf3\xf0\xef\xaf\xc4^t\xdb\x1a\x04\xba\xadQ-\xda\xea(\x930\xce\xa3\xea\xd8\xd6j/qK\x8d\xda\xa0\xf7\x82R&\x15b\x03\x0f\x1b\xc0Q4\xea\x14\xb8\xc0\x01\xe7\x19J\xd0\xba\x07\xd1]j\x99\x99\x91Y]k\x86\x07\x0eP.\x06\x86\xf39\xe1\xcfI3\x80\x1d\x89\xea\x9b\xb4\x12\xb5{G\x1a\x03e\xcf }\x0e\xbfh\xb5t\x80\x96~N\"2\"\x01\xf9\x9e\xec<\x1f\x80\xbc\x8bU\xaf\x91\xa2\xd1\x08-\x16\x90\x11\x89T1@\x04\xd5b\x01ZL\xef\xfe\xe89\xc9G\xa3\xe7v^\x1dB\x02\xb71\x8dHK\x1b\xad\xb0\xac$R\x15\xa5\xff\xa9 a\xae\xb3j\x0b\x83\xf4(\xf2XZ\xa5\xc8m\xa7\xacm\x89$\xc9lr\xbe\x89\x96W\xdb\xdc\xf5gIk\xea\n\x06\xea\xb5\x88\x08\xda8\x07i\xe8\x88\xec\x0e\xbcS\x05\xd1\x01*\xf1v\xa6x\x1c\xb1\xeb\xec4\xb8\x0c\x83h\xf1\xdcJ\xa7\x93\xda\xc5X\xa6\x14Z\x9e\x14\xd6q\x12\xe9\x0e\x86d_2A\xe3H\xab)>x@j\xf8\xcc\x80\x90\x11\x0d[\xbeJ\xcaE\\\xc7 \x16c-\xfd\xb4G\xe0\xb6;\xd3\x94\x04\x981,=\x17\x8d\x9e:A\xe1U\x0fx\x1c\xab\x9d[\xcedVWa\xba\x9b\xa8\xe2vD\x81\xc0\xd0\xb7\x15q\xdc\xcb\x85\x8aEj\xfa\x08'\x07\xf1\x1bL\x19h\xb1:x\x16\xef\xcb\xfafqJh\xf3\xb0\x15\x83\xd7\xb5\xd7 (\x02\x07)\xd8\xce\x04\xd1B\x85M\xb4\xb8\xa0k\x9b_Qfv\xdb6\xf2\xf1<\xcc\xd3%\xb4\x82)-\xf4T\xaa\xa1\xf3\x86\x04Gv%+\xbb!e0\xc9`\x08\x85A\x17m\xee\xd6<\x91}%W\xcb d\xc4\xadKT\x8cX\x82 \x97\xe1\xe4E\xa5n-b\xe1 \xa1\x81\xc5Qd\xce\xf8\xf9\x90,\xc7\xcaC\xd7\x99\x9a\x03\x97U\xa6C:\xb53\x87j\xd8\x18;\x1c\x17\xc7v.\xde\xa6\xa9\xd1\x18&lu\x18$Du\x81\x18\x19\xf5\x01h\xde\x19\x96M\x06n\xb1\xa2\xaa!\xf8\xc5qv\xc5\x8f\x92\x05\xf0\xb5\"\xa7\xe2dx\xad\x1c\xefW\x1b|\xc1\"z\x192\x7f*0d5\xa7:\xc4X\xdc\x95\x9f_\xbf{\xf9\xfe\xe7\x8b\x1f\x8f\xde\xbd|s2%\xc1\xd8\xa3\xd1\xa7\x94\xbd|\xff\x96\x1c\x92\xab \xf2\xf9\x15\xc1\xca\xa5,\xfb\xb1Vy\xbb\xe4\xa81\xe1bQT\xc7\xa6\xf1\x85\x13\xdd\xb1\xce\xaa\xd5\x10\x88Sb\xab\xb5\xd6 mV\xdar\xfc\x96U\xb7U\x9a%4\xfeAJ\x1faQ\xf4\x13V\xeb\xdb\x0drH\xf8X\x06\xf0W\xb1\x89\x96\xa0Z-\x0e@\xa8N\x124r\x99\xb1\x81\x16\xd7v5\xe8X\x892o\xdb\"%\n\xbd\xaf&\xadx\x14d<9\xf5\x12\x1e\xca\x88\xe8]\xd3\xaaQf;\x94x\x98\xeb\xb9r\xad\"\x8e\x9b\xbeV\xdb\xda$<\x8a\xc1\x97U\x0c\x89\x93B#\x1dD\x8d\xa2\x8aN\xcc\x11\xe9)\xd3(\x17T\x1b\xd1$0f\x0c\x86\x06\x02\x05\xb4\xc6\xeei\xb7\xcfI\xc7U\"\xce\xf5\xedr\x81\x1eF7\xf18a!\xa3)so+\\(\xde,$\xd7\x12RoEr\xf5S\xc1.\xc4`?K\xe4\x067\x1d\x86\x0eY\x91q\x88\x8c\x03\xc4\xc5\x8a\xe9\x82\xfd\xf2~>O\x99\x0c\xd82\xf6\xb5\xc6\x82\xfe\xa1m4\xe4:z\xc3\xe6\x88\x00\xf5FW\xf5\xeb\x06U\x9d\xf1\xaaX\xf0+\xc1\x82\xceC+;\xbfm\xa9\xf1O\xd5_\xb7\x9a\x89\x92\xf8\xdd\xaf3\xaa\xea\x9acb!~\x1b\xd7\"\xed\x81\x16\xf6\x9e\xe0\x91\x16&\x8f\xeb\xf5\x84\n\xbe\xde\x1e\x0f\xa7\x97q\xbe\xc9\x10B\xd0q\x10\xfd7\x83qi\x8e\xef\xcb\xf7ou\xfc\x8d)I\xda OVqvcT\x9b\xb7\x02\x0b<\xf3!\xcc\x17A\xf4c~)\xb8\xdf~\xc0\x9f\xb2 L\xc5\xd9\xde\x05~\xb2\n\xb2\x8c%S\xf0\x9bg\x05\xfd\x11t\x88\x8a&\x87m\xb0\x05\xef\xe8\x95P\xd5\xf5\xf6/\xe0\xbc\x1e\xd7\x99\xa6\x00g\xb1\xa8e-\xa9\xb5\xf7\xb4\x9e\x9eV\xd4\xc8'\x8f\x9e\xd6\xd5\xc8\x15\x17\xb6[\xff\xbe\xd7-\x03\x01\x8e\xe0\x94\x85r\x08_G\x82\xd9\xa5\xf8\x98+\xd9H>N\x80\x16eE\xa9\xea\xc0c\xf1\xb9\xcd/v\xca\x7f\xb4\xbc\x97\x8e\x0b\xa2\xaa\xc3&\x92\x8eK\xa2\xce\x85X\xe3\xbd\x0c\xad\xea\x02)+\x1dP\xa9\x1f \x94S\x17D\xddu\x04\x94\xa4\xa8\xa2\xb0.F\x9da\xc6\xad=:\xb6\xd1w\"\x9e\x05\xf3\x9b\xa30\xc4\xbeU\xed(*\xf8B\x98\xfbv\xc9W\xbb\xe5Aa^Pk'\xa8Q\x94\x94Ldx\x99D\x8c\x14\x0c-\xd5\xca\x86\x8e\xef\xd5\x06\xc1\xab\xad\x83z\xc5\xb7\xb2A\xc0:\xdf\xf1\x9d\x8d\xcd\x12Z)l\x9b\x81\xc1&\x0d\xae\xf8\xa8n\xfb\x18b\xa6`W\x18hl\x11\xed\xca\xba\xa1\xc6]y\xed\xcd\xae\xf3\x82,\xc5>7\xb0.\xcc&\xcfR.\xbf\x12\x91%\xee\xdc\x14)\xa4C\x12\x0f\x86$\xa8\xf2\xee\xf3\xba\xe1\x15\x14\xbf\xe3\x01\xd6\x90\x05*]\xea\xddz\xdc\xa7@\x1dl{\xa8\x18\x8f\xb6h)\x94\xd78\xdap[*\xa8%\x96\x8d\x98KO\xe6\x85\x90\xe0\xc1\x03\xe2\xa4\xfa\x80\x01\x85/M\xb9\x8a\xac-\xd71\x8f-\xc8W\x8cZ\xf3\xe8l\xce\xeb\x82e\x928N\xa7$'\x87=N\x00\xcd3\x16tt\xd16u}\xff\x91F\x8b\xd6\xa0,`\xdb1\xce\xd8u\xa6d8vP\xb8\xb3\x1d\xfby\x1c\x06\x1e\xcd\xac\xd7\xb5 \x84\xaa?\xe3\n\xcb\x9dI\xb7\xa6C\x92\xc8\xd3\xca\xff\x00\xbb\xcd9\x89|@\xaaI\xe6\xd8\xb9=-rK\xcc\x16\xb6\x9e\xb9-\xbc\xa1\xf8VC\xed\xcf|X\xe4OA\x03\xa5\xe9\xf7\x95\xe0\xcc\x1e\xe9\xc2\x07\xc4\x98$\xb9\x12*\x84\x8dX4H\xb2mh\xe5-\xb1`\x9dv\xd4-k\"\xe6\x174mz\x86\x05\x95\xf3M#o\xc9!\xdep\xd7tKH\xb9,\xed\xb0\xd2\xb7\xc1\x9c{y\xda^iP\x02v\xd5\x99k\x7f \xb0\x86\x8f2\xd7\xe6\x91\xb0]$\x90\x8fa\xe2\x0b+\x80\xe2\xeazH\xf21\x8b\xfcf\x06>\xf9:XC\x9f\xd8=\xa8\x07\x00\x82.!b\x98\x04P\xb723\xf5\xd1\xaf\x8cpu\x14\x07\xe4\x90\xec\x10A\x04g\xfc\x14\xd40\xdcA\xe7~\x0eA\xf2\xee\x85<\xd2h\x02\x1f\xdfPa\x15\xf1]p\x06\x12e)\xec\xe8P\xedh\xb7>\xc6C=\xea\xaau\xf6\xe5\xe8)\x0d\xa7z\xf9\xd0,/^\xcd\x99R\xef\xd5\xae\x87\x9bt]\xf0\xbb\x1e\xd9&-\xee+c\x13\xadV\x90)\xde\x9bX\x0c\x06\xe03W\xb94\x8b\xf5\xf0p\xbb\x03#\xad\xd2\x14\x8f=\x1e\x864N\x99%`k_\xf4\xe6\x8bs\x83L\x89\xd7\x81\xe6\x04\x9c'\xd0W\xcfu\x8a\x90\xf3\xa9\xf5\xb8\xear\xb52\xd4\n\xcb]\xe7V\xf7icX\xbagbQ\x90CIL\x00\xf2\x801!\xd3\xe2\xd7\xf7\x05\x8c+\x01X\xe4\x0f\x15\xa2\x03\x08\xf0Zi\x94\xd5\x99,\xf2\xc1\xd4\x14?\xd9d\xba\x9c{\xc7[\xd2\x84z\x19K\x1ci\x19\xce[\x8e=^\x14\x16\xcb\xa4R4!\xa3\xa2\xb8\x18\x1a\x8c\xeb!=\x84\xb0D\x1d\x1b\xc8)\xd3\x86\xc8\xf4Q\x81\x1eN\xf6\xa5E\xd4\xb9\xc1f\x81;8\xef\xdc\x86DI\x1d\xde\xd2l9^\x05\x91[\x0e{\xc7G\xf2\xaa\x93\x03=\xad\x94L\xcd\xca\xe4\xf4\xb6\xa9\x95\x89\x035\x1a\xb3\xebL\x94\x7f\xf0\x80P\xf2=i\x0d\xc7C\x0c|\xdd\xe2\xa0\x8d\xa86Ri\xff\x92Z\x01\xed\x9aJZ9\x15\xb4\xd6i\xc7xx\x1a\xd0f7FTo\xc1\xe9\x87\xd7\xa7\x87\xf3\x0d\x11\xa0~\xe6%\"\x0c\xe1L\x15\xe8\x9aK\\=\x04\xc7Eb\xc1\x1f\x85!\xd4\x96\xba\x10/\xe8{\xc0 n$\xb8\x0c\xf9\x959\x00\xcb\x99q=U\x91\xa7+\x82\x8d:\xd7\x08\xb6\x91-\x8a\x1a5\xe1\xc2{b\x1d\xfeN\xb1>.\xc5\x93\xb3\xbc\x11\x13T$\x17\xdcKbWB\x00\xe1\xfdx\x1e$\xa9t\x91_(\"\x18I\x95\x82\x9a\xdb)\x12\xb1\xdb{n\xff\xa0\xdd\x16\xca\xd4\xa0+\xf5\x1a+\xea\x86\x8d\x82\xb2\xad\xa5\xeaCuH\xff\xd4\xfc\xd5\xdb\xb3G\xc5`-\x01\x9cl\x18\x9f\xed<'\x91\xb5'{\x92\x13,\x88\xbf6\x1cJ\xc1i\xed6\x89\x80\x1bQ\xa4\x90Fr$ /\x94\xea$%\xdf\x9b\x86b\xf6\xad\x16\x81\x96)\"\xd3\xd4\x8f\\\xceS\x92\x91\x11\x12\xa6\x8a\x90FHi\xfd\x04\x851b\x05\xb8\x91\"\x07\x8c\xbb\xd1\xe0\x9b\x9a\x7f\xec\xef\xedX\x8c\xb0\x8be(\xd5\x9c,\xfc\xfa\x96b{\xb6\"\xb0\x01WVe\x11$%n&\x13\x137\x1a\x14\xfaR\xc6:\x13\xb8\xc2\xf1$\xf1\x98*\xbb\xb6C\x88f#\x93D\xb1)\xd9\xda\x92\xf1mhR(\xda\x7f\xe0i\xa0\xb9\xb4\xad-w\xf2\x84< V 1\x84\x0d\x15\x8d;\x0f\xdb\xa4c\xd8\xac\x17~\x80F\x1e< {\xe0\xe9\xa6\xc9\xdb\xdc\xa1}\xfd\xda\xa1\xb9^\x97\x899\x19W\xec+\xe0\xf2\x8fL\x8b\xe3e0\xf6\xd9\x9c\xe6a\xf6S\xc0\xaeD\xa6$;Pd\xb6\xe5nI\x17\x83\x16_Qc0\xba9\xac\xder\xaa\xd4)\xeak \x84:\x118D\xaf\xa4W\x95\x9c\xa5v{\x13\xe0\x1d]\xb1\xfb\x9dwg\x99e\xf1\xf4\xe1\xc3\xab\xab\xab\xf1\xd5\xde\x98'\x8b\x87\x93g\xcf\x9e=\xbc\x0e\x83\xe8\xb3\xd3\x94\x90!\xf0\xbf\xbc}#\xca\xec?\x8c\xe8\x8a\xa51\xf5\x98\xd3\x94\xa05\xf1\x12\xf5<\x16e?\xb2`\xb1\xcc\xa6\xc4\x91\xaf\xa3%\xbc#>\x9a\xa8\xe7\xe5\xab<\x04O\xd6;H\xb6\xef\x07Y\xb0\xb6d\x86\xc1\"\x12s\xff\x03MY\x18DL|O\xa7\x8d.U\"\xf6\xd10\xe4W\x1f\x19O|\x96@\x99\xf2\x15\x85\x8e\x97\xf4\x92e\x81\x87\xb7b\x15\x87A\x96\xfb\x966&\xf42\xf0^\xf1d%>\x04/\xa39OV\xd8wR\x0fn\x07\xb1Z\xb2, .\xf3\x8cI7\x88N\xe5\x1d\xabJ\xe7\x8b\xa5g\xc2\x8bw\x0c>\xcf\xf8G\x06\xc6\x92\x02\xba|\xc3`\x7f\x0fVy\xb6D\xdb)\xc6\xfcU\xc2\xfe\x91\xb3\xc8\xbb\x99\x12\xa7\xf2\x8e\xd4%\xf2?$|\x1e\x84LA\xab7\x0b\xac\x98\xcf\xd3e0\xcf\x14\xb4x\x1f\xa5\"\x01+p\xc9\xaf\xf1V\xb2E\x10\xe19\x01M\xf1\x8c\x1b4\xd9\xa3\xa1\xf7\x16\x0e`G\xffD\x1a\xe2\xd1\xb8\xd8\x0f\x1e\x8d\xed\x9b\xc1\x0b\x83\x18\xffN\x18\xc4\x1f\xa8\x18tG\xfc\x1c\xc54[Z\xca\x7f\xcca,\x01,\xc9\xd1\x91\xd4\xb5}\x8a\x02\xc1w;\x95w\x0c\x9e\x87\xb3#\x1b?\x98\xcf\xf3\x94\x1ds\xe9\xabsJ\x9cZ\n\xd2\x1b?H$go\xa9\x11\xbc\x9eZ\xf2\xd6\x81m |\xbe\n\"Z\xc1\xef:\xa9\x0d\xbd\xfb\xb9\xa5:|\\}\xbca\xcc_0\xb5\xb7\xf5O\xe4[,dkj\xed\xb8\xd4[\xfb\x81z\x9f\x17 \xcf#_\xd4\x05I\xa3\xcb\"\x0d\xab4\xc2'U\xd0L\x91m\xda\x04\x9b\x9bD4\xfc\xc8R\x9e'\x1eK?\xb2\x7f\xe4A\xc2\xe0\xa3\xb6<\xe4\xe3\xf3 \x0c\xd1\x0f\x88\x8c\xf71\xf5\x02\xf0k#\xdeF\\\xbeZjQ\xa8\x08 -\xa8H\xeew\xdb\xe72\x96|d\xa9\xacB\xfe\xb6V\xa1q\x99\xf1\x86\xc1\x86\x9c\xfb\xc7\x02\x13\x08P\xf12\x02\xbc`\x035\xba\x0b\xc0-\xfd\xe5^\x9e\x8a\x99\xc5\xfb\xc2\xa3\xec\x15]\x05!T\xc5\xa3l4\x877\xb4\xa2(;\x05]\n \x98\x06\xbf\xa3\x03\xa7\xc0\x8e\xfc\xff\xce\xd3\xcc\x04\x1eQH\xb2\x95\xc9\x12\x96y\xcb\xa2\x80|\xb5\x02\xdf\x84eC\xc4\x8b\x05\xf0'\x9a\x04\x12U\x00\xe8Z\xbeZ\x80\x7f\xd6g!\xc0^\xd9\x0eC\xa9\xae\x83\x0fg\xc2Wx\x06\xbe\xc3\xe7\xf8\x0e_L\xf0\xe4]<9\xbc\x89\x97\x8a\xfe\x82\xdf\xa3\x08'\xbe \xf3}\x12\xb0(\x03\xcc\xf0#O\x82\xdf\x05\x9f\x18\x16%y\x99;Z\x16\xd9=\xea\xfa\x89%Y\xe0YjZ\xabL[=\xe0\xb8\xdb\xd1?1\xa8\x84\xfa\xa2:\xd0\x12\x99K\x9a\xb5\x91\xd6RNo\xc2\xca;\x02\xbf\xa4\xd1\x02Ned\x98a8\x8e\xfc\xf5/S\xe2\xc0\xef\x11\xf5\xd7\xa3k\xac\x16\x91\xfb> \x16AT\x02sxG\xe1\x03\x9f\xf1EB\xe3\xa5\x85\x90\x0fVt\xc1L\x92\x01\x12ZI\x86 \"xU\x11\xbe\x86\x80\xd8\xf1X\x8c/\xeb\xcfx*\xbeJ?\xe3_\xf8\xbc\x87'?\xc2\x93Y\x12\xb1\xf0-\xcd\x92\xe0zJ\x1c\xf3\x15\xe9\xad\xcc\x16\x93\xfa\x06\xe4UE\x892\xc9R\xca6\xd9\x9f\xd9\x0d\xdci\xa4P\x95\xfa\x8d\xd6qs\x1a\x8b\xd3^\x01\xaa\x17\x1c\xf2,Xi8\xf8\x89@Iy[\x81;\xcdW\x14:\xcbXr*p?\xac\x0b\xf9>Je\x02V@\xa040\xa6\x95'\x8d~\xb7\x1e6`\x8f\x0e\x05\"v\x14-\x00\xe96\xd2\xb0r\x1cp\x012\xb2+\x9a|f\xc9 \x90\x1c\xf2\xf7\x88\xa1\xb4\x86\xcc|\x1b\x18\x80\xab\xc0\x0ex*\xaf\x085h*o\xa1,\xc0\x05\xd7c\xbeZ\xa15\xf60\xde\xac\xb0?\x07>\xac?\xe3\x0d\x85M\xf1=U\x84\xcb-qV=\xc9R\x9d n\x87\xcb\x96lE\x15\xa2\xc6>\xcf-\xd2\x82(_\xbd\xf72\xba\x86\xf5[\xbe \xdf\xd0R]\xa4\x12\xae\x89\x164O\xbaa\xc73\xa5<\x04\xcd ld\xa7q\x00\xd9\xf2m\xdc6_\xb3d\x1e\xf2+k\xa6\xd8\xe4Z6:%\x8eN\x1a\xc5*\x0d\x1b\x17\x05s\xb6\x0c\xbc\xcf\x11KS\xb3\\\xa6\x13\x91\x821\x0d\xa2\xec\xbd\x92\x08\xc1\xcb\xc8&\x10\x8ai\xc4S6\x018\xf1k4A\x81\xb2e\x81&\xcb\x17\x1cRP\xe7\xb5\xf5\x88\xa4\xda\xcb\x9a\x07v=\xc9^\xaa\xf6)\xeb78\x1c[\xa0\xee\x0e\xe0\xf2}\xc4 \xc1V\x00\x97\xa3\xc8\xac\xa3\xec\x17]\x8f\xf8m\xad\xe2(\xfb\xd5\x80\xfb\xb5\x05\xeeo\x06\xdc\xdf0\xb8\x84\xa5,Y\xb3\xa30^R\xf0\x1bo\xbc\xb7\xc1\xa71\xf3\xb2\x8fby\x9b\xa5\xcaT\xb4,`\xee5+\xc6\xb7\x92\x80\x94\xc07\x9d \xa2r|\x18\x136\x17#(\xfea\xd5\xb1\xf9\xaf2\x17\x1b\xb2\x82\x9ey\x0d+\x0b\x00U\n\x08cP\xba=a1\xa3\x19(\x89A\x81\xe2\xcd\n\xfbR0\xe1N\xf1\x1b\x85\x93<\xe8\xc9u\xc6\xa24\xe0Q\n\x05\xea\x89-%_1\x9a\xe5 3\xcb\xe9$\xb4\x94\xd2oA\x074\xcdCK\x16\xcflR\x94\x04g7\x12\x1c\xf7\xa6\x1e\xb5\xb0\x87)c8\xc3\x9f.i\\!I!\xa1\x95$MC\x1e[\xbe\xa2 \x184\x8fyyH\x13C\xe8SO\xc2\xbe\xa5@N\n\xb9\x84SO\xc2K\xd9\xba\x1b'\x8c\xfaoY\xb6\xe4>\xd4U\xbeb\xf5\x94\xda]\x02\xb8|Ca\xfd\x97l\x1dh\xe1\xa5\xf9\x8aB\xb3\x15.\xe0\x169kKN\x90y\xcb\xb3 \x84\xe5h\xbc\xa1\xf5\xf3X\xd3\x86\xe2\xb7\x95.\x14\x99\xa5\x0c\x02@\xed\"\x884K\x82\xcf,[&<_,\x8dc\xb3\x92\xdevvV\x00\xcd\x03\xb4ZC\xdb)*o\xb8,\x03\x94\xf0\xcf\x96\x95 Y/i\xba\xa4IBeWE\xca\xc8\xd7I\xf8\xa7T!^\xae\x81\xa2\x14\xb7\xaf\x04\x01\xf3&\x88\x98G\xe3\xb2L(\x13Z\x0b\xfc7\x0f\xa2j \x91b-\xf26\xc8\x04\xdd\xb1\n\x8c\xa6\xad\x8a4k1s\xbe\xa1L\xeb\x8c\xf3\xcfL\xd3\xc2\n\xfc\xcaB\x0c\xa7y2\xa7\x1e;\x95X\xc81_1\xe8\x1b\xb1\xd4\xdf\xd0h\x91\xd3\x05\xc0W\x12\x90\x12\x19\xbd\x0c\xa5\xb7&\xb1d\x8c7\x146Y0 \x02\xd4/+\xcc\xaf\x05\x0cv\x96e\xec:;\x02\xfdV\x01\xc6\xae\xb3\x91\xd4v\xb5\x80\xbed\x1eO4\x0e\x00p\xbfH\xb1\x141\x91/\x94h\xc3\xbd\x02\xa0\xa0\xf9\xca\x17\x0c\x92\xa3\x1b!+\xe98$7\xc7%\x019. \xc8E;k\x14t\x91\xd6\x86\x06\n \x13\x05\x94%\xdb\xb6\x7f\x1e\x05\x9e\x8d\xb7Qy?\x04~\x00\xf5\xc1\xdb\xe82\xf0\x03{E\xa0|e@\x83\xaa:\x0e\x9e\xa5\x1fXr\xb2\x92\xc0Y:\x8a\x05\x85\x8a\x11\xbf\xeb#\xe3>\xd7Y\x8f\xca\xeb]\x0c\xf8G-\xaar\xd6#%\xb6\xc2\xc0^\x9b\xb2%g=2dM\x18\xf8\xdb\n\x87\xe8\xacG&\xcb\x88\x15P\xdb\n\x19\xd65\xf32\x9e\x9c\xcc\xe7\xcc\x13xF\xbe\x8e\x18\xbcc5\xb1$\xb5\xb1jk\x96dG\xfe\xfaW\xa8&\xc9@\xf0\x86\xa1\x1d\x91Y\xca\xdd\x00\xb4E\xecVB\xffZ\x83F\xeb\x0e\xd8\xd5\x0f\xfcZ@\xca_\x16\x983\xc0 \nL\xbe\xa0\x90ip\x19\x846n\x18P%>\xacW<\xf1K\x89\x8fxk\x91\xf7\\% \xa9Q\xb7E\xeam\xb4\xc2o\x8cp\x9a\xf1\xba\x90\x95\\\xdb\xef\x87\xafq\x04p\x8d#\x80\xeb\xe3%\x8d\"\x16J\xad[@\x91\xf5$\xec\x1ba\x10}>\xf2\xb2\x1c\x88^\x07^\xa7T\xbe[\xc1\x13/\xe1\xa1\x01.\xdfm\xe0?& \x88\x96\xb0\xcb\x04\x15EC\xe6G\xb3\xd2\xb6\x1aO\x97\xfc\xaa\x00L\x97\xfc\xca\x06x\x16dF\x95\x99x\xb3\x82\xca\xab\\\x05\x89_\xe2^\xaf\xc2\x1f\xc0\xd3\xb6s\xbd\n\xa7\x97\x14U\x98\xb8^\x85\x11\xbe\xc8 \xe7\x17\xf8\x00\xd4\x10\xa5SLAG\x81\x8a\xb3W})\xa4\xe8:\xbc^\x85b\xcd\xea\xf6`J;D\xfa2@\x1as\x83/\xae\x1b|q\xdd4\x17W= \xf9\xf2\xefh]\xbfs\xbe:\x8a\xfc\x0fT\x1cQ\xe5K\xab\x7fT\x8a*\x1f)\x17\x02\x81\xc0\x95\xf5@\x11Dz\x1982Ug`\x84R\xcc!\x04il\x85\xa4Y\x1dil\x806 \xb9\xec\xdb >v\xd6!\x17z\x1b\x84Z\xe1\xad \xb0\xb2m\x10zI[\x8c\xdc\x8a\x85h\xcfWk\xb0WH\xd9\xc6\x8cL\xcd\xc8]\xa4\xaa\x9d*#\x02\x8e?\xb3\x9b\xd4\x0d\x06\xe39ON\xa8\xb7t\xed\n\x84t\\\xae\x08\x19\xe7vgH\x02\xf1\xeb\xc1\x03\xe2\xd2q\xe3\xeb\x12H@\x18\xeax\xdf$@\xc7N\xddu\x02\xc7\xedW[\x82\xfe`\x0e\x15\xa4\xa3\x85Guk\xd7T\x81\xef\xe2>>\x1e\xe3>>vw\xeb\xd5\xcf\xc16\xbdj\xcb\xaa50\xdf\xea\xf8\x05\xa69k\xc3;\x8b\x80\"/\x0e\xc8\xa4\xe6=\xb1i\xaeN@2\x12\x02]\x83o\xd0xIS\xe6\x7fd\x8b \xcd$\x15\xaf\x97\x10\n.\x1e\xe5\xf1~J\x1c\x1eID\x85\xa0)\xfdh\xd7\xf6\x06\xb4r\x11\xe5\xa0e\x90\xf5M@\xd9&\x16LC\xe4\x01^\x9a9\x19\x8f\x7f\x08\xf3\xc4\x19\x12\x07\x04\x01\x10\x1b\xfb-\x8br\x95\xf2\x8a{y\xaa~\xff\x95\xdd\xbc\xe4WQ\xf9\xf6)V\xbf\xdf\xf2\x06\xe8I\xe47'\xab\xa9\xa2\xbf\xa1EV\x8b\x05q\x87\x0b\x12\xfbf*\x0dM\xa7=\x0d\x82Mc\xd4io\xd3\xe0\xc2du\xda\xcfB\xd8\xb0j\x9dV\x8d\\\xf1m\xdb\xb17\x88\x1a\xed\xa6\xa5a\xab\x85b\x0f\xdb\xc4[\x8e\xbb\xb4KP&\x84\xd3\xc2PA\x07\xc7o\xb1\xf3\x92Q\x12\xa4\xf1I\x0b\x14\x8f\x05\xd0%\xcf#\x1f|5\xc4v\xd8\x90\xcd3\x13\xf8\x0d\x9b\xdfn\x94\xbf\xba~m<\xc0\xb2n\x0d\x8a\xfa\x9e\xbb\x16\x07,6\xde\x80~\x9a\x03\xa9\xcd\xfes\xc3\x93J\xac\xe6aH\x96Cbq\x10\xa7\x06\x9fC\xb4xr\xa0]58C\x91\x04|\xa6\x98\xd7!I\xc6\xa5\xea\xba\x8e\xb8\xf3Ry\xb7c\xa9\x0bf\x99\xd5\xfe\xfd \xf9\x8c%N\x93h\xfce3X\xee\x9aE\xa0\x84\x9aNImF\xd8u\x96P/\xd3wtu\xca\xa4%|\xf4\xd6\xa2\xc3\xea_\x0fdF\x0em\xb1\xd3\x06d\x8a\x9a[\x88'\xbd\n\xdam\xde=\x9a2\xe3\xd8\x9bZW\x9a\x1b\xba\x1c\x82\x9d;Y\x923\xe9#\x9e\x8f\x95\xaa\xed\x89\x1f\x80\xc8Q\x9a\xf1\xf82\xb6\xc7R\xfa\xa2\xd5\x07T\x8b\xd1!\xb8\x82\xc7\xb3\x8b\xf6\xc1\x99mo^qd\x96\xc7d\xf1\xe5\xbb}\xb8<\xe9\xed_\x87\xe3\xd6\x12\x17\x8b\xf4\xfc\x8eI\x89\xe0_\xaa6\xe9S\xdc\xd2 \xb5\xa6\x14\x19@n\xa4E{G\x0b\xeaT\x8b\xbdz\xb1t\xe7\x83^\xdd\xd2$TG\x97$m\xd5\xd9!\xd5\x91\x0edFZ\x1c94\\b\xfa\x1f\xf2\xec\x0d\xf8\xd3d\xf5\xe8k\x16\xaf\xa3%\xf1*M\x97a\xd1\x03u\xb5c\xb5\xc1\xc3\x8d\xaf.!\xf5\xae\xcc\x0c\x1e\x99\xc9\xe6\xaf\xbb\xc9\xfbP\x9c\xc9\xc9\x95\x05\xdbc\x94\x9b\xd9\xdf\xab\xf3J!\xce\xfc(\x8f\xdd{u&g\xae\xd2\xeb\xf0\xb1jM=\xdd\x97\xf0\x8f\xea\xbdZ\xaa\xf4\xfa(\xacUz\x9d\xe9Z\xa9A\xab\xc3/\x14|\xdd\x07\xdf\x8d\x1c\xcd\xfa\xe8\\*\x1e\xad>\n\x17e\x84\xaa?\xbe\xd6\xf2\xaej\xe1\xe8g\x0e\xbd\xe4\xe0G\xc0\xa1Q \xdd\xe3\x9dD~\xe5\xfdu\xc6\xf4\x15\x89\x91\xaa\xfd\x0f8\x97\x8a\x95\xf1h\xf4!\xa47\xc6\xcf3ya\x08)a\xe0}\x86\x1fUn\xc7\xe3\xb1,\x91C]>\xcf/Cv\xac\x81\xfd\x84.\xf4\x7f\xd5*\xf9S\xfa7\x90/\xd7A\xa6\x7fC\x8c7\xfd\xf2~]\x02\x15\x8d\xf5\x13\x0e\x1c\x92\x9f\xcb.)<3$\x0e[\xc5Y\x00Q\xcc\x1c\x16y\xc9M\x9c\xe9\x17_\xfdH\x12\x0e\x15\xce5{\x16D\xb1lv\x10\xadi\x18\x00\xd4\xe7\x92_\xfb\xccn>$pO\x02\xbf%k\x16r\xea\xeb\xff\xcc\x7fI3Z\xbe\xbde\x19\xf5\x8d\x94\xa2\xd5+\x93\xd5\x83\x97\xb7\\v\x14^\xde\xe7%\x94\xee\xf5\xaa\xe4\x06c\x9afL\xfe\xc8S\xf9C\xcd\x93\xf8\x0f\x12m\xe2\xc4 _\xe8\xc6&4c\xe5\xc0\x80s>\xc7t\xf1\xeb\xa4\x8c}\x96\x83\"~\xa9\x1a\xd2\x8c\x86\xa1J\xcd/WrV\xd2<\x8d\x99\x9c\xb9,X\xa9P\xd4\xf0\xc6soy,\xc8\x87\xb0xUS\x0c\xbfu\x07\xe1\xa5\x18\x08\xb8\x1f\x0b\x8cE\xba\xe6a\xbe2\x1a{EA\xf6\x0e?\x97\x8c\x85\xcey\x0f)\x91f\x8d\xd8l\xe7|\x9c\xf1Oq\xcc\x92c\x9a2w@\xb6\x05c\x16\x06\x1es\xeb\x9b\x95(\xcbg\x87G\x10\xe3\xb7\x99\x0bv\x98\x19\x8f-\xd9\x1c\x15x\x90;\x8a5Z\x0c\xc1KiFD\xb6\x89s\x0f\x92\x8c\x04\x91*T\x0f\xe3\x0b)P\xe3Cr5K\xce\x8b\x80\xd9\x00Y\xf3\xd2~\xa2PS\x91X\x08\x07\xae\xad\x16\xca\xce\x18\xe2P\x8d/\x12\xce\x81.}\xfd\xb2\xac\x1f\xa9\xe9\xd4^\xd3e\x9ee\xd2\x0c\xf8@\x06\xe0T\xdb\xdbHH\x8d#W\xa6\x08TF\x13FU\x9a\xf1m\xfdK\xf4\xec\xb8\x95\x92\xbf\xd8\x90\x92\xe7(\x13D\x13B\x87pR\\\xcd\xd89.-\xd8\xba\xe9 \xf5\xfb\xd3\xeaGpjtPT\xc7\xeaD\xe8\x07\xa6O\x8b\x0e\xe8\x97U\xcc\xdd\x01}\xa2\xb0z\x17X\x81\xf1;\x01\xfd\x1e@pRt\x00\xbd\x86\xd5\xd5 $\x0f\x96\x0e\xb07\xe2P\xe9\x01\xa3\x0e\x9c^\x90\xc5a\xd4\x03Z\xe2\xe7\x0e\xc0\x0fp\xfat\x01\xf5X/\x1f\xd4\xa9\xd5\x05\xa6O\xb4\x0e\xb8\x8f\xe5i\xd7\x05 'a\x07\xd0\xa9<\x1b{@\xf5\xe8\xc3\xa9:S\xbb\xc0\xe4y\xdb %\xcf\xe2\x0e\xb0\xb3\xf2\x9c\xee\x80\xfc\xc9<|;`\x7fV\x07\xb3\x9d\xbf\x12<\xc0\x1d\x19\xe5\xbfj\x8a\xab\x9do\x94\xfe\x9e.\xdd\xa8M\x82\xac\x9f\xfbf#!\xb8\xd3\xdd\xba\xd9\"\x88(`\xba\x84)\xa2\x19\xde\xdd\x9a!\xc9\xf4\xf6\xa1\xdeU\xaeq\xe4\xe9\xba\xc9p\xbf4X\x81\x8e\xbev\xc9G\xaa\x80@Y\xf6\x01\xb4Nc\x15\xec}7\x1a\x7f[P\xe6\x1d\x80\xdd\x12\x18\xa2\xe6.\xbe\xdb\xdc\xbd\x14\x9cUGc^*\xae\xab\x17X\xd6\xdd\xb9\x97\x9a[\xeb\x01'9\xb9\x1e\x80}F\xf5e\xc1\x01v\x02\xf2\xae\xadkq\xadHz\x8e\xfb\x99\xc1\xf6t\xe1a\xcd\x12\xf5\x81\xeb\xb3\xa8\xcfJV\xaa\xbd\x8f\x16\xef\xb8\xa4g\x1f\x8fLABG\x9b\x8e\x9aB\x86\xbe%\xfa\xf4\xa4\xc5\xbb^\x9f\x9e\x9cU\xd8\xcd\xf6O\xad\xef\xf6)\x19\xe4\xa7\xe3\x1b\xab\xbb}\xe3g\xe0\x88\xdb?\x81\xf8\\\xd3O\x9fO\x1c\xf3\xb8\x93~;\xeeF\x98\x1f@d\xd1\xde\xd2\xa6?\xc4\xa6\x08\x96\n.-q\x9d\xfd'\x0e\x1e\xc8H\xf0M\x17\x10\x90\xa1\xbc%\xba)9\xadf\x01u\x80\x05\xed\xb7?\x17\x83!\xb9\xa8\x94\xbd\x07\xa1/\xdcV\xf3H\x1e\x89\xa5\xdcw\xeb\xd4e\xe3\x8b\x8c.\xd0\xdb1b\x08j\x05\x1fm\x17\x0f\x04z\x18\x90`\x83\xf8\xac\x9f\x08\x96\xfe\xcb\x17\xe2\x9e(\xde^G\x85\n\x0c\x89\xdf\x0d\x16_\xaamh\xae\x820|\xc9B\x961\xcb\xf0\xdc\xfb\xd8Djll\xbd\x8c\xce\x95\xc3Iw0$>4\x0dR\xbb\xfaU\xbcYd\xef\xc7\x90zG\xd9\xfb\xa3}\xd4\x81=o\x11\x18h\xf7nc\x8f\x86\xa1\x8a\xacn@\x97\xcd.~%c\x9aC\xbc\xf8\xe3\x90\xa6\xa9\xcb\xeba@\n\xa9\xb0\xf4\x8f\xd0\xd4\x06a\xd2/\xb1\xe0-\xb0\xec8e\xb9\xcf\xcb\x0b\xed\xca\xadhM\xfd\x8a\xdf\xd3\xa85o,\x9a+\xc4\x0b\x83\xf8\x92\xd3\x04\xf8\xe6>~\xda\xb54\xa9RP\xe9\x94\x1c\x126\xae\xa4\x17\xb7\xa6\xd5\xe4\xaee\x85Mw\xf0-\xa7;\x90^\x86\xcdI\x08\xeec\x12&\x93\xc9\xbf\xc1\xdaM\x98@\xe2\xbeV(\xff\xf6k\xafy\xf1\xc3-79\xb8\x87\xbd\xcf\xecf\n\xf7V\xf5[4\xa2<\x02d\xa0\xe0\xdf\xdce\xe2\xf1\xb2$\xfc+T\x80f\x83/\xb5\x96|\x1a\xb6\xe5\xaeXF[\xb2\xa51\xa8-\x17|\x19\xa0\xd8\x81\xc8\xb8\x16o\xb9\x1f\xcc\x03pA\x90 8wwR\xbf\x18\x14\x8f\xb7\xa4\xc9q5\xf4~\xe7v\xfd\xccnb\x10\x1cH9\xae\xd4\xfd8\x94nm\xa7\xb5x\xa4\x04\x17\x8f\x7ff7\xb7\xf8\xaa/\xb8V\xf3\xa3_\xbe@z\x1e\xd7\x9a\xc2\xc6\xea\x03}\xdbs\xb5\x0c\xbc\xe5\x86\xadi\x19\x83\xfbll%\x05Eg\xf4[b\x00:$\xc1\xb7P\xe9m\xee_\xfcP9I\xbd)qNR\x8f\xa26\x05\xa0=}I\x93)q\x08\x92\xfd\x06\xf4\xad\x9c\xa3$\xe1W\xe27\x02\xf2)\xd6\x00\x9f0\x83\xc6\x8f\xca\xd0\x04 >ZLM^\xf2\xabH\xc3\xc8\x9b\xc7&\x08\x0b\xa7\xc4\x91\xa4\x1a\x92\xfd3\x18K\xbe?E\xb2\xde\xb2(\x9f\x12\xa7\xa2\xf9\xda\x00:\x8a\xe3\xb4\x13H\xb2MS\xe2\xc8\x1fo\xb8\x87\x19O\xbc\xe5\xbf\x7fH\x82\x08\x14\x84\x00?9\x9f\xa2\xc0gQ&\xf0\x89\xdfjg\x80\xa3\xe0\xfd)q~\xa0\xdeg\x9b\x85\xc5\xb3)q\xce\xe8%\x923\xd9\x15}\n\x19\xc5\xcc#&{ba\xc8\xdb\xedf\xe6\x13\xd1M\x8b\xaf\xcb\xc9S5T \xc7\xec\xc7&\xa2\xc1G!ZR\xb4U\xca\xe6\x9b\x99\xbb;S\xb8(L-\x03\xbb\xfb\xb4m%\xef\xedZ\xd6\xf0\xde\x1e|s\xc1\xd0\xf5\xb9\xf7H\xe5Z\xd6\xdd\xdec\x18%\xcc$|O\x8c\xd1\x8f\x1cu\xcb\xb5\xf7\xb4c\xdb\xec\xed\xb7n\x9b\xbdg]{\xe6\xd1N\xc7\x8ey$Z\xfe:J\x19\xea3\xe7\xd1\x93\xb6\xed4\x81\x95\xf3\ns52\x81u\xf3j\x17\xcd\x12\x83\xf9j\x0f\xcd\x12\xady\xf5\x08\xcd\x12My\xf5\x18\xcd\x12\xc3\xf8\xea \x9a%\x06\xf0\xd5S4K\x0c\xde\xab}tC\x88Q{\xf5\x0c\xcd\x9a@\x97w\xd0<9\x1c\xe8x\xec\xc2xL\xd0\x01y$\x06\xe4]\xbe\xb2\xac\xe8 \xccQ+6\xd9\xdd\x15U\xbce\x19\xada\x0e\x9c\xcb\xb3\x9f\xc0\xd2\x0b\xfegvc\xbb\xd1\xcd\x04\xc99\x03\x90s\x19\xec\xf63\xbbir\xa9\xc0\xfcV0\x1ah\xc8\x97\xde\xe3\xab\n\xb9_\x1b\x8d@\xcf~[\xa3\xb4\x7f|\xabld\xa2\xfc\xe1\x93C\x8d\xcc\xc8\x94\xc8\xb0:\xe3y\xc2W\xc7\x8a@\xab\x07DF\x15d7\xa2;\x82YAy\xc0x\xd5\x06eJ\x9cr\xc6\xee\xc1\xc9\xb6\xd4\x11\xfb\xd7s0>\xcd\xa8t\xf7\xc3\x92\x7f\x1d\x03\xd3\\-\xa0\xbb\xc3R\x1bI/\xb5\xa9\xcf\xda\x81<\xb8]\xf4;\xa0\xee\xc4\x96\xdc\x91%\xb2q&\xd5\xb5\xfd?\x86i\xff\xb7X\xf1\xb1\n\x15\xfd\x7f\x8b\xb8\xe9\xdf\x04O\xb00\xa3\xbft\xf1\x84\x1a\xf1JhCv%\x13\x04\x16\x05\xd5\xba\x97\xd5\xfc\x11\x1b\x1b\xc9\x0d\xc6\xaf\x11\xa74\xcc\xe8\xaf\x1b5\xe5\xd7zS~\xad6\xe5W\xbc)5(\x1c\xa8Ws\xff\x86-%\xc8\x91\x86\xff\xdfj\x19 \xce\xf2\xf1\xa0\xb9\xac\x9eu\xd1\x1b\x88\xac\\\x1f\xe0\xcd\xb1\xbe\xc8x\xfc\x86\xadY\xa8\xe2\x02O b`u\x11\xf8\xe0\xf5KdO\x90\xecJ\x84\x8e\xa9\x8a\x91R\x84\xc0\x80 \xa9\" \xc2\xa9U\xa3y\xd8\xb0\xeb\x85\x8co\x83\xe8O^dta~B\xe0\x82q\xc6\xdf\xf0\xabB{\xd3^\xa9\xb6\xfd\xfe\xf4\xf1uQ\x87\x91F\xa6\x88\xda\xfesl{F\xb5}x\xab\x196\xa7\xaf:3\xf5x\xcfS\xb2U3\xa0\xcfS\xf6*\xb8\x14\x13\xb25\xb9\x8f\xb6\x18\x91c\x1e\xd5\x15\xe6\xc51\xff\xf0\xb7\x87\x87\xdf?\xac\xa6\x0b&\xf9\xe1\xdf_\xfc\xb6\xf5\xdb\xe8\xb7Q-\x0f7\xd4?\xfe\xf1\xe4\xf8\xaf\xa7\x9f\xde^\x1c\x9d\x9d}\xbcxw\xf4\xf6dJ\x1cA\xc7\x8c \xe4\xf0\x08b*\xa79\x1a&\xc3\xf7\x8fU\xee\x19\x97\xb1\xb4\xbb\xf0\x081\xe8i\x9ct%\xe6\xd5^\xc6\xd2LTt\x08\x01f\xd88aqH=&\x10\xaaC\x1c\xb2M\xe8\xb8\xd9~\xb2M\xbe;p\xbe#\xdb$\x13?\x9d??\xf8\xae_@s\x1a}dy\xca\x9a=\xe9\x8a\x80\xa8c\x9b\x16\x16\xec.\xd6\xae\xf6\xce\x8aJ 6QL\x93\x94\xbd\x8e \xf0\xe4dg0\x94\xc1\x7f\x80\x8eo\xf6\xc2\xb6/\xeeY\xa4\xf6\xe4\xf1\xe3\xddI\x17\x92\xab\x0fQ\x11\xc7KL\xf6d\x08=\xdc\x91\x91\"wdH/V\x84\xdb\x12ks\xf4\x88< \xc1s\xc2\xc9\x0bB\xd1\x10_E\x8d\xb9\x19f\x90\x93m\xf2h\xe7\xd9\x93!\xa1\x03Y:\x17\xff\xb6\x0f\xc8\xa3\x01\x89\xc4\x7f7\x13\x7f\xd9X\x0b\xa4\x8f2\x97\x0f\x06d\x1b\xcd \xdbd\xd2\x96\xb9\xdb\x96\xb97@f9#\xffq@\x121\x00\xffa\xc6\xa6&\x8d T\x91\xdaD\x17\xc48lo\xab\xf6c\xcdGq\xa0+?5 _\x88\x1b\xa9\x9f/^\x90\xc9\x93\xfb\xc0G\xe6\xac;\x93\xc7\xe3'\xe3]\xe7\xf6\xb5u\xd8,\xb9\x91\xfb\xe8\xc9`(m\x91p\xdb\xa5I\xdd\x9aG{bx40\x8f\xec}\xa8\xe5\xd9\xc6\xa1\xb7\x04;\x1e)kw\xd6\xa2/'\xe0&\x8a\xfb-\xe3\xce)pV\x85\xd5\xbb\x01\xac7\x1b\xe8O\xd4T\x8a\n\xdcL\x06\x11\x1e\x08\xf4\xc7\xed\xe6\x9e\xcd\x16\xa1\xa1\xb4\x04\xf2\x8c|&N\xfd\xc4u\x1e=rDY\xf1\xeb\xb13\xac\xb8\xf3\xb8\xe7\xf8WbB\xf6,\x83\x9f\xa86\x9d\xe6\x97Y\xc2\x04\xd2\xe3EX\xe0\xdb\x7f9\x1b_\\\xb0\xf4-\xf7\xf3\x90\x81!\xdeP\x86\x87\x8b\x98\x97\x01\xa6\xfe\x90\xf0u \x86BG\x1dm\xb6:p#w\xff\xf1n}\xe5\xf1\"\xeb\xd1\x00e#\x02\xabY\x83\x8a\xf7h4M\x1ejM,\xa7\xa2\xa7MIwL\xc5J_\x12\x1dw\xad\xda_\xae\x93\xefyDU\xad-\x83\x18\xb9u\xfb<\x0eK:r'\xd8\x96\x16\x19{O\x1f\x9b\x18T&=\xc1\xc7\x9a\xfes\xc7Z\x9f;-\x07\x9en\x99\n\x1a\x8d|o\xab\x1fU\x016\"n5\xe8\xdd`@\xb2e\xc2\xafH\xc4\xae\x88@2`\xdc\xe0:\xc74\x8axF\x04oJ(\xf1\x04\xc3IhJh\xf1%\x07\xa1~\x14\x17\x8b\x99\xdd\xaf\x95\x95y\xff\x862\xb3e\x1f\xd9\x9c%,\xf2t\xf3\xc4\x87\xc8\x92\xa6\xd1w\x19\xb9d,\"A\x14d\x01\x0d\x83\x94\xf9dD\xd2\xd3\x05\x1b\x93O)+\xeb\x1b\x83\xb4\xa2xu\x07$\xe3\xf2d\xcc\x96l5&\x1f\x19\xf5\xc9J`m\x9a\x11\x15hu~9^\xb1\x87y\xca\xa4\xa8cT~\xc5\xa9\xdf\x8a\xe1\xa3\x91\xb5-~\x1b]A`\xd0\xcb\x95 \xb8\xe1&\xaf\x80\x0b\x08\x95kn\x04C^r\x1e\xa2\x19\xa2\xb1h\x86\x8c\x94\x8bf\xc9\xa3\x15\xcd\xd2\xce\xc5\xb1\xac\x9b\xd5\xa5\xa5\x114\xc2[\x0d\xfdy?Ge\x8bLK\xdb\x90r\x9a:\xb2\x14\x95\xf2Jk\xc7,\xa5xd\xab\x0fr\xa4\xc7F$\x17\xe2\x01\xe0]\xb8\xa6b\x18kW\xbf(\xff\x1e\xd5\x160\x91r\x83\xb1\x99 \x0e\xec\xa2\xec\x1d\xf0F\x83\xa8o\xa2\x14u\x82\xd14\x0d\x16\x10\x9e\xbb\xaf\xb0\xe79\xc9\xc8\x0bB\x93\x05\x88\x94S%\xe6yN\xb2\xedml\xaf\xe8\xa5^\x14\x98e\x88\xe1t\xf1\x89\x84\x04\x91\xe8\xa1j^y,-i\xfa\xfe*R\x8e&o$-')qqN3\xa9\x1b\x1f\xcd\x92\xf3\x1e\xd7\xdd\x86 9~\xe8\xb4\x8d8Q\x9d\xf2\xccN\xa9Q \xdf\x93=\xd1\x1e\xc95\x01\x8e,\xfb\xbdwN\x0e\xab\xaf\xb8\xfb\xd4\x159 ?p\x1e2\x1a\xa1\xa6\x04\x0b\xa2\x0c\xe3\xe7\xcd\xbc\x1b\x84e\xd3\xe9x\x14n}S@\x0e\x89\xbb#\x0e=5\n\x03)\x81\x88\x9b\x88\x0b<\xa2\x80\x8b\xc0\xe6\xf7\x05\xbd\xe3\x8d\xe3H\xf2z\x1dNb\xdc\x99^u\xcd]Y\x8a\xe6\xd58\x00\xe5\xdb\xbdp\xd4\xeeJ\xcb\xd3\xe8\xcb\x17\xb2%\xe8oZ\xd2\xdf\xba\xce\x12j e$\xf5\xb2\x07\x82\x0d\xa8\xbb\xb2\xd5\x0f: \x95\x11\xbd\x8f1\xa9N\xd1\x1d\x87\xc5\xaf\xe0\xad\x96\x91\xa9\x00\x9a\x83\xe3\xd70\xdf\xa6\xe3\xf3\x96%\x0b\xe6\xdfit\xba$OX9\xb1_/\x8b\x02\xed\xacf\x8b\xf3j\xd2\x85\xa1H\xc1N\x1a\xcb\x08\x1b\xd3\xcd\xa6oKV\xb9*\x07O\xcc\xc8)L\x0b>\x81\x06\xa89}f\x0d\x9bL^\x90\x9e\xe6\x97\xa9\x97\x04\x97\xfd\xe7K\xb5\x1d\x97\xa9\x89\xc6\xe4Q\xaa+\xed\xd3\x86,\xb9)\x1a\xd1\xb7\x0d+p\xbeQ\xffZ9\x1ef\xe2\x81q\x1f8.\x92%\xdc\x92F~\xa8\xa8\xe2\xf1e\x10\xf9\x90<\x18\x0cI#\xdbE\xfc\x8c\x10\xb47\x9f*\x1f\xef\xd5\x9f^=qu\xb3\xaa\xbd\x13\xecd\xaf\xa6\x15\x92\x83\x97\x81\xff\x96\xe7Q\xe7]\xab~\xe0\xa3\xe64\xb9\x9b}\xef\xe7 \x0c?2\x8f\x05k\x84\x93h\xfb\xf0U\xcbN\x90[\x0c\xdc\xc3\xa8\xb9j\xf2@M\x7f\xe5\xfaik\xea\xa7hu\x9b\xd1\xf9\x84\xcc\x94)\xb3\xe8\xd5\x8e\x02~\xa3\xaf\xd7\xb17h\xa5\xd7\xcf\xc2jz\x15c\x18\x19\xb6q,\xb2\x9b\xecd5\x7fm\x9c\xf7?0\x16}H\x98GC\x0f\\\x19\xf9\xca[\x7f\xadi\x06H\xc0#\x10\xa3T\x1b%o\xe6\x99\xaf\xb4\xd4\xab\x99v\xa2\x0b\x01\xaa\xf1%\x0d-|\xfd\xd4&\xc6\xc4\x04}\xa7\x06\x14\x1fk\xfb\xb5\xcf\xa1VCY}\xf9[\x02:\xb9\x07\xc6\xd8\x8eK\xe9Z\xfb\xd9\x07\xec\x8b\x14'\x00\xd1\xd9\xd9L]\xe8\xaa\xc4\xc3m\x1c]\x9f\xea\x08&\xcd\xef\xa2\xf2\xebO\x96\xdcl\x00M\xcc\xab \x1a\xc7\xe1\x8dk\x11\xe2`\xcfW\xe2\xd1vo\xc6\xb6G}s9\x06y\x9a<\xb0\x97\xbdk\xb0\xcb\xb3\xccGQ+6r^\xee\x8a\x0e\x8aI?\xb0<\n\xe7\x9a\xfd\xcaDp\xd3\xb5\xc4\xc8o|\xb7\xab\xd1\x18\xf4\xc7#\xedb?\xd2k\xa8z\xe1\xb4T\xef\xc0~\xd3l\xca\xb4q\n\xc8|\xbe\xb6\xaf\xb8\x16\xe9e\x1f\xbc\xb5`\x99\xb4\xb7\xf2\xb5zu_\xec\xa59\x8c\xea\x15\xc7\xf5\x908g\x9cP\xcfci\n\x97\x12W\xb2\xfa\xe2\xf6kHnxN\"\xc6|\x92q\x88\xe0\x1f\xcco\xc8\x1fD]kNI\x96\xe4\x8c|%T\x16\x9f\xf3<\xc9\x96\xc5\xe50\x01\"\x12\xeeF\xe0~q\x00\xf7HcgP\x1c\x04\xf3t|U\xedQ\x9fq\xe8\xa7\xda\xa5\x1f}\xcdi;\x10\xdb\x11qT\x96l\xae\xab\xf6\xa2\x81\xf9\xd1\x96\xe5\xdf^\x0b\xad\x9c\x02\xb6=\xd7^G\xae\xeb\xa8\x1d\xbd\xf6\xdd_\x1cw\x16\nb\xd2AAL\xfa\xef\xfc\xcd(\x08\xaa\xefih\xbb`-\x95{\xbeuX\xc2\x8e0Hp \xe6\x80\xf5R\xad, /e\xba\xce\xc8!\xd4m\xc2\xb6\n\x88:\x84\x84\x1e\x12\x1d\xb1\xfe\xccU\xb4D[~@\x0ee=;dJ\x803u=\xbd*l\xe7\x8a+x\xa7\x10`\xe7UXT\x82\xe2\xb6]\xc5\x16L\xf2\xd6\x96\xeb\x81\xd6\x07\x8c\xe6\xa0\x18\"\xab\xe8\xc1\x95\xbcqN\x0eIN\xa6jY6i\xc8k\xa5\xf9\xc1\xd5\xf5\x99\xca\x01\x1e#q\xff\xf8\xda$\x95\xbb\xee\xd3d\xe0\xe9\x1a~\xc2#`\x10\xc0\xfd\x03\xd1\x88TX\xc7j\xc5\xd5U\xb4l\xac^um^\xb5\xdf\xaf\x16Z\x93\x03\xe5!\xe0~\xb4\x1e\x87v\xa5\xbez'\xc1K\x90ti[\xdcR\xd5\x8f8\xcd\x98U-\xea\x9a\xc7KR\x83\xa9#\x19\xb0>\xd4\x1a\x83\x82\xd3L\xd4K\xf9\xe5\xda\x81T\xa8G\xf2\xb2j\x9bj\xa44\xbf\xddyN\x02\xf2\x82D\x85zf\xb0\xbd\xdd\xc4\x91\xc0\xd3p\xa5\x194$\xd1,8\x07a\x12\x9b\x89\x9f\xe7\xf2\xeeE\xfe\xb6\xb6\xad\x18\xac\xda\x0e\xf9\xb6Sh\xd9\xe7\x05\x00\xca0\x1b\xd4|\x02\x82\xce#\x00\x06\xdb\x7f\x9e\xa4\xf2\xbc\xe9\x89&\x957\xc2\xa7J\xb4\xd6\xd1[(QV\xd0J\x83\xe3#C\x0c\xb9\x08\x8e\x04\x1a\xd6\nv5\x12\xaf\x17\x94\x1aw8v[\xa0\xcaS\xd2\x0e\xb4`\xd9\xcb^\xb5\x01`\x12\xac\x99\x0fd\xd5\xab\x84\xaf:J\xac\x82\xeb j\xc9/\xceS;H\x06\x8a\xdf\x08+\x8dh\xe7f\xd6\xf1\x8fZG@\xee\xc3\xd6f\xca\xed\xdc2k4\x0c\xc1\x05E[~K\xf9B\xf7\xb8\x0d$\xc8n\xfa\x0e\x85\x81\x0b}6\x0f\"V\xa0\xa0\xe6\xce+A\x17,3\xb0\x15\xc4\\k\xc2s\x1b\xfc)\x98 %\x02[\x89\x97,\xf5\x92 \xce0^\x8fV\n\x19\xdaMMPA\xcaPAEP\xa5'\x85[\xe9\x17\xb4H\xea\x86C\xe2\x0d\xc9\x1cCD\xa0['\x0d-L\xcd:\xcf\xc6\x8e\x0bx\xd4\x0eG?\x023\xc4`g\xeb\xb5\xf0\x12\xb1h\x7f\x0cX\x1d\xb83hc,\xda\x88\x16\xc1e+\xe2S>\xb8\xf8\xb0}\x8a\x13\x1d\x1d\xd8\x17\x84\xb1G3\x97\xbb\xde\xc0\xc6\xe5\x14\x87\xdbR\x9e[K\xf2\x82\xf8\xc5\xb9\xb5\xbd\xbd\xec\xea\xb8 \x1b\xfc\xd9\x121+\xd0\x8fRN\x9e\xad\xc1a]\xa6\xfe\xcfE;\xe7\xb3\xf5\xb9\xd5o\xbd~\xc4WV`\x1f\xee\x0d\xc9\xbaC`\xd8O\xfc\x1a\x89\xb1_\x0f\xc9\xaaC\xf2e\xcaW7\x16\x83\xa1\xa9j\xa56%\xfeMp\x14\xd48\x12\xab\xde\x97\x12\xb7\xd7Y\xd8\xed\x81\xa2^\x1aL\xd1\xf8\x90\x04\xb8A\x9a\xd6\xdcn\x0e:\x084\x9a\xb3%\n\x18\x96\x08\xd9@\xc6\xbaeWD)\xaf\xbe\x0d\"\xf0fH\xd8\xb5\xc7b\xd8\xcf\xdc\xf3\xf2$a\xfes\"\x9a\x9f-\x19\x89x4Zi@\x9f\xad \x8b\xd6A\xc2#\xe0\xab\xc5\xa2\x06\xc9^\x1e\x86\x04\x82\x9a\x92\x15KS\xba`\x84F>\xa1\xbe\x0f\x11OhH\x96,\x8c\xe7yH\xaeh\x12\x05\xd1\"\x1dc\xda\xe2,L\x99eQ\x89>\n\xcehV\x1f\xa6s\xbb\xe0\xc3\x83\x9d\x86f\xbb\xd5\xa1\xc8\n\xbf<\x0f\xff#}\xb8\x18\xf6\x13\x1d\xeau3\xf3\xb6\xb7\x9b\x01\x1c\x88d\xfa\x07\xd2\xee\xe1\x808\xaf\xa35M\x02\x1ae\xe4\xa7\x80K\xe1\x15b\x00\xd1H\x91\xf2\xact\xd2\xec\xcc\x1f_\xf1\x1d\x828Hi\x02\xea\xd5\x87\x89\xd0\xa4#\xa8l\xd8A\x95\x13C}L\xbaE\x91\xf6\xd1!\\k\x83<\xb04\xaf\x9a\x0c\x86\x98\x8d\xff`Hr\xd1QO0d\xa0h,\xc5o\xa2\x7f\xdc\x8d\x86\xe4\xe9\x90\xa4\xd8\x01T\x1c>s\xe3;\xcf\xc9|4z> \x01\xa8\xfc\xcd\xe6\xe7-R\xa2\xeaR\xb3\x99\xdd\xa2\x0b\xcf\x1c\x8c\xde\xbe\xe5\x8a\x06\x8b\xae\x8d&C\xa2E\xbc0U\xe4\x90\xec\x80Nvy|F\xe4\x05I\xe0\x86R\xe9\xd2\xb9l\x16\x9dK.~\xf0\x1c\xa7b\xea1V{o\x99\xc6\x9a\x96;\xe6\xc9\xa3.{d\xac\xab\xa6\xec\x06\xd6\x11w\xb3AE\x90u?\xad\xdb{\xba\xffo\xd1\xbcF\x88t\xd9\xbcI#\x02\xbbB7O\xea\x88\x82vK\x07\xba\xfa\x89\x9e\xad\x89\xcb\xca \x8eA\xc3\xb7\x91\xbe(\xe2\xa84D\xac\xd3\xd9\xb9E\x9e\x91\x835\xd0\xc0u\x0c\x1b\x0c\xa0\x88sP\xe0\x83\x8b\x00*\xe5\x13L\x9c\xfc \xd1\x8e\xc6q\x9e.\xdd\x1c_\xbb]\x06\xb4\xdd\xbb\xae>\x06\xba\x7f\xf5^\x14Hr\xeb\xa0.]%\xd5\x9d\x1aDj^` 3\xd9\xfe\xba\xaa\x9e\xc6\x81\x9b-\x9f\x8e\x88\xdb\xdaM\x1321\x1c\xe2j+c\xb3\x83\xaay\x8f\x8c\xebdx\x95\x14i8\xd3\x05\xd4>R\x8f\x14\xb9B=\xacR\x0ff%N\x943\x81\xa0\x9c\x90\x03Q\xf5!I\xc6?\xe4\xf39K\xc8T\x99}\xdaX\xb3CB\xc74\x0c\xb9\xf7)J\xe9\x9c\x15\xf0\xd5A\xee\xbd\xbb \xa9;\xed\xd21\xca\x91\xc3`]h\xa4+e\xe4\x06\x04QL0\xdc\xc6\xb8\x11h\"\xb3+\x02z\xdez\xe1\xa3\xba\xe3\xc5\xc7=\x1e\xdf\xb8\xc9`h\xf52\xf7uP\n\xf2\xdc\xc9\xde\xa3A\xe1\xeek\xf3-\x80\x0c\x88q\xe64\x1bi\xf4\x1d\xd9\xe9\x99TP#\x07\xe4(I\xa8\xe8\xc5\xa08\x99\x9e\x0fH6\x8b\xce!0|t~\x1f;\xa2\x13\xdfO\xf6\xefr\x1c%\"\x13P\x9d)+\xbc\x9f\x96\xed=\xedt\xdcqO-\xab7+\xba\xff\xa3C\xa3M\xfb\xa6H\x14\xabQ\xdd\x05\x16\xc9\x8a4\x82\xd5B\x13\x03\xcf\xccv\xce\xe5\xa9\xa0\x8f '\x88|v\xedH\xcd\xe0d\x0co\xd0\x0e\xf85$\")\xce3\x95\x14\xe7YeSm8\x93\xbb\xbb8\x93\xb0\xff\xb4N\xae\xabS\xfb)\xee\xdap\xff\xe9\x1e\xca%\xec?\xad\x9f\xf2b\xd4\x9d\x99D\xb8\xdaQ\xc0\xb9\xd3d\x19\n\x98\x974cu\x00\xcf\x04xK\xe3z\xfe\xdc\xcc\x7f\x07\x8eD\xea \xb1 \xf2\x91-N\xae\x1b\xb5\xf8&\xc8)\xcb\xea\xf9\xcbJ>Lm\x1dd]\x01\x01\xe9_\x1dde\x82\x00\x86\x91GF\x1dnQ\x1b\x14\xfaS\xc0\xae\xea@7&\xd0\xab\x90\xd3lo\x17\xea\xac\x03^6\x00\x9f\x01\xd4\xb1\xbbA\x1d\xe2\xef\xc4Z\xd3\xde\xc65\x89\xbf\xbb\xbd\xbc\xe7j+a1\xd6\xb7]\xa9\xfb\xb6\x1b\x90G\xf8R\x9d<\xc3tk\x04\x1b\xdbzH\x90\x9aL\xcd\xc9\xb8\x143;-\x91\x0c*^\xf5\x9aHH<}<\xfb)\x83\x07\xc1~\xe0\x00\xa6\xbb\xbf\x06@\xcd\"V\xb0i\x01\xbe\xf3\xf0\x18`\xdd\xbb\xc5\xb2O[93\xbd\x04,\xab\xa4{\xe3j\xd6h\x7f\xa76\xb2bYL\x9e4\x97\xc4K\x9a\xb1q\xc4\xaf6\xc5:\x9a\xdeA&0hj\xbf\xf5\xe9\xfbZ;\x02\xb5\xf9 \xc8\x01{\x8e\x88K\xc9\x08\xf5O+\x98L\x88\x86#\x0e\xa7\xef\xc9\x0e\xf6\x15\x0d\xb7\xbd\x9d\x91\xef\x0fHapnx\x8e\xdei\xaa\xd4}\x95\x1a\x82\x19\xae\xd7W\xdb\xb8\x9a\xcd,j\xbc'\x89\xe1\xe4\x11.\xe3hluEn?\xc3\xc9\xed\x06S\x9a\x93\x03T\x0d&\x85\xf4\x86\x16L\xd8}\x95Y-\xe0\x011\xde\x89G@ \xdb\xcd\xe0\xf0\x92\xb1\xbb\x80\xc6L\x95\xd6Os\xd8\xc5\x94\xa0\xf3[\xd5\x0c\xc9\x06$,\xf1\xb1\xe6|\x80D\xcafQ\x1d#[\xa8+o\xb3\xa9\xda\x7f\x86\xc7\x93\xd8\xdb\xe9\xbe\x1a\xb7R\xbc\x05\x08v\n\x13\xe3\xfb\x18iG\xf4\xbahU\xa1\x90\xfc\xaf$\xbf\xa2YPeL\xec\xbbR\x14\xd9\x85\"\xbb\xe7\x16\xc5\x10\xa2\xe7\x85\x1aW\xd6\xda\x9f;\xea\xe6Ip\xdan0\x1a\x81mu\xd1\x06\xa9Y\xcf]\xf3`\xcd\xe5U\xb4l\xfc\x0b\xb2g2\x06T\xdak\x81^c\xb1p\x05\x95A\xb6\xb7\x13\x08\x16h\xc3\x12\x9aP\x8ef\x89E\xf5\x1d\xcc\x95\x81\xdcNe4\x8f\xa6\x92\x92U\xb8V\x0bip\xeb\x83\xbeyp\xab\x95fa\xc2\xf7\xf6m\x11\xe5\xfap\x83\x81\xab\x83='bS\x92m\xe28\x1b6\xbd+\x12\xcb\xfe3\x1c\xcb\xed?{j \x1bWo+\xd8/\x03j\xf2xH\xaa\x8e\x8aB\x9a.e(\x882\x91\xe6\xd9\xb2\x9a\xb2\xe4i\xcd\xfd\x8f\x18\xa4&\x8cR\xb0\xae86Jku\xa5\x8c&^-\xed\x1f9Knj\x1f\xa0\xd9\xb2Y\x9dH\xad} asRs)T.\xb2l\x0c!P\xc9\x01\xb9\x1c\x92l\x9c\xb0\x94\x87\xebN\x97\xaejr\xc1\xc7\xdd\xd6\x04\xfc\xba\xe9\xa2\xa6\xaf\x9a\xafF\x95r\x1f\xf5\xac\x98\x91C\xb4\xf2b3V<\xac\xc3g\xe6\x0eRIl*y\x16H}.\xad\xd7D\x15\xdf\xf9\x01D\xe0\x96_\x81\x18\xcb\xa6\x1f\x0f\x99\xac\xafZ\xaa\x0d\xfb\x94\x88%\x15TW.\x85\xd0\xc1\xee\x8c\x8e~\xdf\x19=\x1bo\x8f\xce\xb7\xa7\x83\x87A\xf3\x98}8\x9d\xed\x8c\x9e\x9d\xff\xe5\xcf\x0f\x9bG\xed\xc3\xbf\xbb\xbf=\xfc\xed\xe1\xa1{\xb8\xf5\xdb\xc3\xc1\xec\xef\xbf\x1d\xfe\x96\x9e\xffe\xe0\xfev8\xfb;\xfc:\xac\x97\x02\xb3\x04\xe7\x0fgH\x9c\xaf\xe2\xcf\x17\xf1\xe7\xb7\xdf\xc4\xdf\xbf\x8b?\xff\xe5\x9ck\x03\xa1\x99\xf3B\xa4|\xef\x0c\xc9w\xcew\x90\x07q\x80E\x81\x04\xfeF\xf07s\xce\x07\xcd\xd3{\xe6|WV\x15\xd6\x00\xe6\x00\xf0\x1f\xa2\xf8C\xf1\xe7P\xfcy.\xfe\xfc\xaf\xb2\x90W+\x14C\xa1\x12\xfe\x7f95s\n\x1fFd\xb6-\x87\xf4h\xf4\xb7\x8b\xd1\xf9\x1f;\xc3'{_\xeb\xa3\xb0T\x83\x8f\x80\x0e\xdc\xf1_\x06u\xf85ja\xf8\xdftM\xa5!\x1b\xce\x958\x06\x80\xd3\xe0(j\xd6{\xabo\xff\x89\x05\xfa \x88\xcb\x84V.r,\x86\x89s[\x99\x05\x8f\x976\x83\xc8y`\xe3\xdf\x1ch\x84\xd3\x92\x99Zs\xe7-%Uk\xacEE\x83:\x87\xedF\x9d%\xfb\xe8Yri\x93q\xfc\xff\xec\xbd\xeb~\xdbF\x928\xfa}\x9e\xa2\x84\xec8@\x08R\xa4\xe4+mZ\xeb\xc8\xcaF3\x89\xedc\xd93\xbb\x87V\xf4\x87\xc8&\x89\x18\x048\x00\xa8K\xc6\xdeg9\xcfr\x9e\xec\xff\xeb\xaa\xeeF\x03\xe8\x06@\xdb\xc9dv\x07\x1fl\x11\xe8{\xd7\xbd\xab\xab\xe8\xfa:\x17<\x06a\xa6\\\x8d\xc9\xbc\xa2S\x95\xa6\xe4\xb5\xd2\x1b/4R\xa7\x94(\xb7\x1a@\xdde\x0e\xc7\xa1Q)I\xe9\xdb\xec3\xe2\x12\xbaF,-)\x05^\x05i\xb0f9K\xe1\xebm\x1a}M\x19\x05.\x19\x04\"gU-\x81\x80\xc9Q=,<\x01_.\\\xe7\xc81(s[\x94Q\x8b\x14g\\h\xd3\xea|\xe5xp\xc4\xe9\x02\x8c9a\xa8\xd7\x8f(S\xc6&\n\xf3\x9a\x97z4\x1d\x9e\xc3\x04\xff+\xaeV\xbd{\xb7\xbfD\xf2d\x18\xf0%\xa6\xfb\x99@4\xf89 \xe3Z{|\xf5x\x91\xcbA\x9e\x86k\xd7\xf3a\x0fS\x8d\xcb\xb4\xc54\n>\xe6\x06\xf3\x17\xef\xe7\x02&\x90\x91#\xc3\xa5Ew\xbd(\x07\xf0\x16\xcc\xff\xb2\xcc\xf9/\xeb\x02\xc3\x05J\xc1\x17\\\xf8>\x92\x81\xd0\xa4\xd4\xc1\xdfV\xa4\x8e\x1c\x8e\xe0V\x80\x9bV\x18\xc3\x96\xe6\xa9;\xf2T\x10n\xe3\x07(\xa2\xad\xc9N\x1c\xa7\xd2\xc5\xdf?\x8a82e\\\xac-\xfe5\xd7\xd6\xcd\x8b\x82\x91\xffl\x8by\x02\x13py\xe5\xeb\xe9\xf0\xdc\x1b\xe4\xc9\x0f\xc95K\x8f\x83\xcc\xe8>^\x15\x08O|\xa0-\x15\x13\xbb\xaey\x1f@m\xb4x\x19\x81\xab\xa6\x18\xc1\xf0r\xb0\xc6H\xea\xfb?q\x96=\xfd\xe9\xdf\xdf\xed\x9f\xf7\xfe]\xfc\xbfo\xbc\xef\xca\x87\x8dn\x83\xfb\xfb\x0e\xc2\x8e\xea~\xe8\xc3\x81a\xd4{7\xd4\xdd\x9d;\xb0\x9e^\xe3\x8dZ\xb74\xec\x03\xaf&\xd5V#\x91\xd6\xe7\xb0\x87m\xf1-,\x9a\xdf[N\xaf\xcd\x97t\x95&}\xe6\xc3\xb1\x8f\x9e\x87\xfd\x91\x8f\xde\x82\xc3\xc7\xf0\x0c\x9e\xc0F]\x85zfNP\xc6\x1f\x81\xec\xeeK\x1c\xbeD\xf4\xcd\xf4\xd9\xb9\x88/\xdc'tz\xcf\x87\xf4\x12\x9e\xc0{z\xcd\xfb{iP\xaa\xb8^J-\x1e\x13)\xa1\xcaGpY8\xffpJ\xf2\xef\x98\xa9\xbb\xf6\xd2\x87\xf7\xa2\xdf3ZO\xbcw0\xf4\xe1\xd8S\x90\x81\xaf\x8e1\xa1}YM\x98\xb3Y2go_\x9f\xaa E\xee\x99\xe7\xc9\xb5\xb1(\xbd\xda\x82-\xba,\x18_\xf2\x97\x8f\x8bi\x96\x17n\xf1y\x0bG\x15d\xb1K \xfce\xddG[\x95\xf7\x95Uy\xef)\x12\x94f\xec\xfb$\xcb]\xaf\xae\x14\x95\x7f\x7f\xf8\x00\x8e%\xb3\xd6+<\xd7&\x9c(U\x12\x8e\xe7\xce\xb9\xe9[\xe9\x974'\xf4adP\xd5\x11\xec_\x99\xef\x81+\x00\x7fS\x1d\xb2\xa0\xec\xfb\xef\x06\xfb\x9e\x0f?r\x82\x83\xbb\xe8\xc3\x1b\xb9b\xb4\xa1?6\xee$\x88Y\x9e\xc2\x04\xdeL\x9f\xb5\\\xa2?Et<\x15\xd4e\xdezq^\x0d\xffgA\x85_\xd0\x10_\xc3\x04N\x15\xa0\xbd\x80'\xf0\xfa1\xbc\xe0\xa3<\x1d\xccVAz\x9c\xcc\xd9\xb3\xdc}\xe1\xc1S\x18\x1d<\x80#\xf8\x19z\x13pn8\xcf\xc5?O\xa7/\x1a\xc6\nrY\x7f\xee\x97\x8b~ \x19\xc2\x198\x1e\xf4\xe0\xd2\x80\x15\xcf\x8b\x12\xedc\xb9LY\xf0\xbe\xb1T\xdd\xbc\xd4\xfc\xa5\xfe\xd6\x88GO\xe1\xe0\xde=\x99\xeeA\x1b\xbd\xe3H\xc9\xc0\x86\xe8eV\xec\xc3+-vvQ%\x1d\xe4\xc9\xb3\xb3\xe3\xd3\xd3\xf2\x17\xd3\x05b\x0e2\x7f\x93\xbd\xa0\x15\xe6\x08\x9c1\n\xa1\xea\xcd\x98\x83\xbeq\xbe\xdfu%D:\xe9\xfb\x0ez\xf07]\xe8\xeai\x8d\xf0))\x01\xc8\xba\nRb\xf2\xcd\xeb\xdb\x07\xce\xbb9\xccp\xea~)\x08\x9d\x06H\x97^+\x1f\xbf\x9a\x9e\x9c[.E\n:\xc5i\xd6\xac\xe06\xad\xa4\x8a/\xf5/\xbc\x8e\x95L\xf1\x8e\x05//\xb8\xd1/\x8d\xa8\xcf\x1b\xfd\x96\x8b\xd8q\x8dm\xfe\xd2\x80\x02\xdf\"\xc9\xff\x05\x97\x05\xabg\xb3`\xc3x_\x8a\x17!y\xfe\xc5#\x84\xfa\xd6L\xde\xeb\xf0^\x97A\xffR\xe2\xad\\\x92/\x18\xef_\xb4\xbd&\xcb\x9e\x92\xbe\xfeR\xe1\x8aC\x1f\xfeR\x05`\xde\xfc\xf7\xe5\xe6\x8f\xaa\x88\xaf\xad\xe9\xf7u\xf1]u\xf7\xbdW\x11\xb1\x8b/RH)\xc6*\xcb\x94\xa4||\xe9\xd5G\xfd\xfd\x8eb\xfdeQR\xd3A8\xb1[NO\x10\x90\xcb\xb8\xa1\x82w\xab\xd2\xa6\xfa\\9\xabj62\xbb\x18\x0d\xc8\x04e\x05e\xd0\xea\xd8\x04\x8d\xbf\xaa\x88\xb54\xc1&R t\xaf\xbfA\x0f\xfe\xda\x80\x89\xba\xba&\xf43\xfc[\x1a\x16+JP%^p\xdd\xc8i:eU\xd4\x05\x05P\xc3\xa0\x992~\xe2?\x06Lc\x9e\xa7\xc5\x199|\xb6\x1f\xfa\x9c\x88\x92 \x7f\x02\\N\xae\x03\xae\x8aM\xac4'\xec\xbbNhc\xf3&\xd4\x0b\xa6Z\xcc\xe2\x95\xadPh *\x1b @\x96\x87YP\xed#2\xcb\xdd!\xf5\x14+\xe6\x18#\xc1*\x9c\xd1\xb0.\x86\xe0p\xberD\xc0\xc7r]\x0ex\xfc[\x0f\x8f\xad\xb6r\xe2\x18\xa8\xabR\x94/\x14-\xca\x16ij\x0fB>Ht7/phz\xf4\xd5y)ZOSLQ#B\x96\x89\x8a\xc7\xe5E\xec{\xab:q\xber|p\xfexp\xe8\xe0\xd7\xd4FEL\x87<\x96\x83\x18\xdc\xa2\xf2\xe1\x8b~.\xe3)\xba\xd5\xd2\x97\xe1\xf4\xc7du\xac\x18\x1d\xcd6\x91\xdcl\x16\x85\xe24K\x1b\xa1O\xd4\xb0\x81\"\x97\xe2\xb7`\xbb\x14\xc2\xa5\x8aQ\x9e\x8f\x14e\xf8\x18\x02x\xa2\"\x84>\x86\xc0\x9ef\x1d\xfdO\xa6\x81\xc9\x83q\xba=\x17\x086\xdd\x9e7\x8c\x8eB\x93\nQ\x02\xbd&V>\x97\xaa\xc9\x96\xc89H\x11\x0cH\x1d\xf5i\xdc$\xae\xcb\x0eL\xe1\x1c\x85\x82\x90\xd4\xba\xd1\x9c\x93\xd5\xc3\xac\xa2Uu\xf8\x18\"x\x02E\xd6\xf9\xa8Y\\\x9c\xc1\x04\xb2id\x11\x17\x1d9\x16B\xb5\x19\xe1\xf1tF\xd1\x08f\x06\xf1\xd5z\\\xbe\x9c\xc6jf\xe2:zI\xc0\x88\xcb\xd2E\xacNN\xeb2\x86ya[6\xadXW@g_\xf5\x8bHU\xd3\xa2\xa3\xb4\xbe\x9c\x16u\xcem+Z\n\x96T\xdd\x9e\x0dm\xcf\xa6dB\xda\xb4\x1b\x1e0\x04\xf1t\xd3\xa0\xcc\xc7\xd39\xed\xc8\xdc\x12K\xcc\xf8\xb6\x11L;l,\xa1\x82f\x95-\x16\xc8\xe7\xb8\xc09\xf8\x87\x0f\xb0./\\i?\x99\xfaQ\x9f\\CD\xb7R@D\x97U\xc4\x16O\x9a\xf4\xf7\xb9\"\xb0\xd2X\xee\x9e\xcb\xa4\x8a\xb8\x1a\x90=\xc0\xabEx\x92O1\x83\xa2\x162*V\xd2E]V\xd6\xaf=$\x07\x1c\xa8VB+\\)\xe3\x03~]\xe9\xfe\xf8\xf5\xcf\xa5\xf5Y c\xc3\xbe!\xdf\xbbmC\x94\xf0\xcf\xc4\x9f\xbcM)\xff3\xfa\xcb\x17\xd8G4LL\x93+\x0b\xb14\x922\xfc\xc3\xd7\xb1tR\x999\x13\xeat,}+\x18\xfeQ\x9a\xc2\x87\x0f\x107H\xff @\xfc\xaa\x8c\xe8\x16\xc1R>x\x04\xd8\xa2\x03\xf0G\xd1\x90+\xe8\xc1m\x87\x05T\x18\xa1y\x99\xe8\x02\x91\xa2\xd4\x9f@\x83\xe4IU\x99\xce9\xe2(\xa1x[H3\xf5\x05\xb8(\xed\x173\xb6\xc4:\xb5t\x0d\x13\xb8\xe0\x8d\\\xd2\x16a\x9bD\x17E\xedz\x9d\x13\x98\xc0u\xfd\xf5MmR\xdad\nL\xe4\xfdL\x0d\x11\x17\xcf8\n\xafJ\xb4\xa0<\x90z\x1b\x1a\xb9\x06:\xfc\xd0X\x8bA9?\x13\x1c\xa5\x84\xa7\x1a\xdc\x92sN\xb1\x08\xae\xe0\xe77\x1c\x81\x8f\xe8\xbf\x89\xfc>\x86\x1b\x85\xb0\xf4\xca\xf34t\xe2\x0d\x97YM\x99@P_\xac\xdc5\xabu\xbd\xa2\xaeW\xd45\x93]\x17\xb4\x82\xa9\xae\x15q\xc2\x0c\x7f>n\xedu\xad-D\x135+^\xef\xc23\x13\x01)\xca\x90R\xa6\xba\x8e\x15\xb6[ B\xa9.\xbe<\xd2\x7f\x8c\xb5\xba>t%T\x1c\xbc*WY\x903\xf0\x8d]\xa9\x13[<\nso\xe8*\x8b\x0f7\x83M\xb2\xe1\x18\xc9\xdf\xdcH\x17\x96\x95\xd7\xb5[K\x7fx\x08\xffb\x1bE/\xd3\xb71Et\x9e\xbb\xb2\x19\xa3|\x8c\xe0\xe7\x95\x17M\xad\xfa\x8d\xe4A>\xb8\xaf\xb8\xd2\xbc\xe7\x16@H\x7f\x15\n\xed\xbf;\x1eyD\x17\xdf\x04b\xfc\xbb#\x8e\x92\x14\xf1~U4\xac:+\x0d\xe1U\xc1\xfd\x1a\x88`\x87\x85\xf2A.\x89[`=\x8eF{/\xe9?\xdf\"E\x93\xb5\xf2p\xa4\x13\x901g\xa2\xa8\xb1\xc9\x11\x1c\x15\x83\xc1\x8f\x9f*\x02\xee\xdd(xQ\x93\xdcT\xbd\xf6J\xbd\x8a\xb1\n\xad\xb5\x18D!\x9dJ\xd2\xd1*\xe9+\x99\xe5\x98v\x1e\x8dw\xfd\x91\x87^\xb0\xefiA\n\xca.\xff\xba)\x0c\xfaB_w\x06\x84e\xc7\x88q\x03\xf9\xcb\xd3\x10\xf0X\x9c\xef\xfa\xf0\x12\xfb\x92\xb2\xe6Kx\x8a\x12\xe8\xcb~\xdf\x03\xd9\x0e\x1e\xc0\xdeL_\x9e{\x9c\xd4!L\xcd\x98\xfbR\xdc\x7f+:\xe0J\x7f\xf9\xb3O\xa6\xe81<\xc3\x81\xd5>\xf6\xfb\x06Z\xbcG\xe7\xd5'\x16\xc3\xf7c^\xed1<\xf34*\xcb\xc7Pi\x89\xb2\x10\xead\x9a\xaf\x95\xb8\xfb\xf0\xf0\xfe\xdd\x07fM\x8ck\xfc\x87\xf7\xcd\xdff\x18f\xdc\xf8\x89\x83\xf9\x81\xa5\xda\x867\xf9\xd0\xfcm\x0e\x13xP\xbd\x13'\x1f\x8ez\x0f\x0e\xcc\xdf\xb8n9:\xb0\xb4\x8a\x91\xf1\xfa\x16]s\x89~\xc97q\xbf\xbfo.\xc0\x05\xa1\xfd\xe9O\xefn\x0e\x86\xfdw7\x0fN\xce-\xe5.\xb1\xdc\xbb\x9b\x83\x93w\xdb\xc3\xe1\xf0\xe0\xdd\xf6\xbb\xef\x86'\xfc\xdf\xfb\xa3\xf3\xfd\xa5\xb9\xd2\x855\x8f\n\x7f\x92+\x96.\xa2\xe4z\x0c\xceK\xf5'Em\x8c\x19\x9bgp\x1d\xceY\na\x9c\xb3%K3\xc8\x13\xd8\xa4\xc9\x8ceY\x83b\xed\xc4I\xde\xbf\x0c\xb2p\xe6\x8c\xc19\x8d\"\xb6\x0c\"\xd1*\x17\x1dn\x1e\x0e\xc1\x8d\x93\x1c\x02\xc0R\x80h\xb4I\xc28\xf7\x9a\x9a\x0d\xe3\xab \n\xe7}l \x9b\xa6\x17\xd4\xb49\xf1\x9d!\x9d\n\x08\xc55\x82>\xcc\xcc\x9f\xb9\x8e\xfac\x90\xaf\x06\x8b(\xb1\xe5\xae\xe4:\x01\x19\xb5\x07\x8b4Y\x1f\x0bo\x1a\xcd\x9dX>\xca\xad\xf8\xcc|<\x00*\xc6\xfe\xeb ^\n/\xdc\x8b)3\xdaE\xed\xad\x1f[o\xd4A\xd5\x1e\xaeB\x85\xa2I|z\xfe\x18b\x0c\xc4\x9eR\x84X\n]n1hI?\xe5\x9d\xc6\xf6\xbeql\xc5\xb0\n\x89\xc2\x0e\x07\xa9\xe1\x00P}\x93\x02y!\xef\x82<\xf8\x89\xb98\xd5\x03\xf4\xfbC\xceON=)\xf4\xe0\xd8\xa5\x13Su\xe6r\xe9s\xc9\xd6S6@\xca \xeb\x15N;;\xcd\xfe\x99}\xdf\xd5\xb6P\xac\x06\xda\x0e\x1f\xaf:\x0d}\xe1D-\x05\xef\x84\xae\xa9\xb9\xa4jk\xee[I\xaf\xe7y\x1c\xb5\xee\xdd;xt\x9f8\xc7\x93 \xdc\xbb\x7f8z\x84R\x0b\xaf\x08G\xfc\xc5\xc1\x10\xe3\xa2\xdc\xbf{ot\x00\xe24\xad\xde\x96G\x01\xce\xb8\xbc\xea\xba\xa3\xe1\xc1!\xdc\xe1\xbb\xf7\xe4 \x8c\x86(\xc5\x88w1\xffq\xff\xde\xbd\xc3\xfb(X\x89*9\x17\xa0\xb8r0\x06\xf5\xe6\x0b\xc2\xd2K\xfbj\x8a\xf6\x10\x13\x9a\x8f\xe4\xe4#O\x9el\x00\x05\xfa\xbd\xa1\xa78\xd7{\xa0\x0e}\n\xa3!\xdc\x01\\\x9e\x0f\xb4\x1dB\xa0\xa1\xb5\xff\x00b\xe5\x18\x1d*\xf2&\x0c!\xcd\x01\xcf\x02\x05\xb4\xed\x08l\xaf\x1aQM\xcd\xa5\x07\x07\x07\xd0\x83\x07\xf7\xe0\x1bp\x19<\x81\x83\xfb\x1e\xf4\xc1u\x87\x18\xcd\x0c7\xfb\xden=\xbf\xb1\xdd<\x90\xcf\x95\xb8\xfd`I\x89\x82\xb8\x80\x98 Gp\xe22\xd8\x879\x06\x95\x03\xbe\xae\xc2G\x81\xde\xe7\xdec\xdc\x8fk\xf8\x06\x16\xf8\xf91G\xe4 D\x1e\xae6\x95\xban\x06\xbb\x13\x97\xe3\xbe{\x8d~3\xf0\x0d\xf0*._\x99\x8d\xb7\xdb\xc4\x7f\xb4\xc3\x98\x86\xdaz\xce\x18L\x075\xf7a\xe9\xc3-9\xe2\x98\x8c\x9a\xf2\xb9\xd0I\xb6\xb5\xd4\xb5\xf9\x16\xbe|8\xbf\xba\xb2\x7f>\xae\x1b\xc8\xe4\x83\xfb\"(\x85\xeeA\xbd\xf6f\x82\x82\xd0\xf3\xe1\xc4\xbdF<\x86\xa7\xc0'xc\xe8\xea\x86\xf0\x9d\xca\xf1\x89\xfe\x11\xb3\x03_J\x0b\xd1u\xaf\x87\xa1\xa7n\xba\xfa\xfcA\x81\xfb/\xdd\xcb\xddp\xfc\xf4sq\xdc\x87\x0b\x9fC\x9b\xb8>QMr!\x1f\x04\xccK\xe9\xc3\xf5\x0c]\xb6\xa4\xb0\x96#\n\xa3\xa8$\x84\x83U\xc9{\xe1\x92c\\\xe0\x11tN\x83s\x8e\x9e\x02\xd5\xde\x13j\xdd\xb85\xaf\xa0R\xc7)\x06{\x99\xc0{\xd5g\xa2\xd5^{\x84\xd9\x97\xed\xa8\xc5\x91)k\x19\xdcS\x91\x81\xfc\x16\x9e\x88,\xe6\xbc\xd6m\x837\xa8h\xba\x0fy\x81\x1a1G\x0d\xf7\x02c\x82pBn\x02\xda\x98C\x12U\xe4\x84\xfe\x82\x96rk\x1a\x9f\xb5o\x10\xa6\xc7\xd2\xea\xe2\xf8{\xbd\x18\xa1\xb8\xde\xef-P\xda3\xfbb\xc9\x07g\xc6IK\xec\xa3\x8e\x1a=\x96\xc8\xcc\xd1q\xce\x919\x14\xc8<\xe7\x0b\x17j\xc8<\xc70(\xdec\x98\x0bd\xe68\xb8\x81>\x87<\xa9\xe8,\xfd\x02\x04^\xb9K.\xf3\xc2\x1f98\x0e=O8\x15\x9c\xb8\xc7\x0dF(O\xf9\xb4\x13OAj\xafW\x97\xf0\xf4\xe7c\xaf\x17\xf3R\xf5\x84S\xd0\x86\xc7\xef\x9b\x84\xa4\xea\x9b\xadU\x17\xbebi\x16&\xf1\x18\x1c4\xe6X\xb4\xd0\xed,;0\xe5\xb2\x96\x0f] \x1a\xc33;\x9b%\x1f\xb01\xbc4O\xd5b\xb4\x10\xed\xfeh\xfe,\xdb<5\x7f\x16.\xf6\xe3\x8e\x12\xb1\\\xd8\xee2\xb4V\xebv\x90\xb3,\xa7\x98|\xceM\xdc\xef;\xd0#\xd2iJ\x99-\x9f\x8f\x16\x02n\x9b\xcf\xdb8\xa4\x19w\x1b\xdfg\xcdh\xa9\xcd\xe8GW\xe6\xa6\xb9[\xb9k\xf8i\xf3\xab\x83\xac\x0fZ\xbeD\x94n\xac\xa6Y\xf9\x88qn\xeb\x8d\x15\xc1nP,g\x14\x02\xd3\xd5c}$\x15\xffC\xdd\xe3\xcf\x90\xe6\x86\xffy8\xb2d\xbb\xe9\x14\xdfC\xef\xbc<\x1f\xe9\"\xd8\xb6\xabb\xbe\xa6\x0c%\xe5\xb9\xf8\x95\xe6\xc9\x91\xaak\xf3\x16K\xab\x88\xf58i\xeb\xec\xc56\x8a:v%\"\x85vjR;1\xde\xad\xf5\x1dC\x89u\xda\xcb|@\x84 \x0d\xf8\xf2\x16z\xec>|\xf4\x88+\xb7\x03\"Kd\xdd\x97\xde\xc9@q\xaa\xba%\xf3.\xf7\xaa^+\x91,m\x8a5\xd2\x12\x99J%\xb1\xa9e\xf0\x81\x96\xb0\x87>\xd4l\xf8x\x84\x81G\x89w\x1cbzxC\xd8\x99\x18\xf2\x8a\x07\x86L\x90\xa19M1zC\x0c\x853D\xe5\xc89\xa8\xb7\x8cqE\xde\xf5\xf6+\xc29\xd3\x0ckU;\x8ct\x01\x1d\xb1\xc3\xca\x888\xac;1\xe6\xa3\xd1q \x1c\xac\x83\x9b?\xb3[\x14v0\x85\xa9zch:\xd2\xcdW\xa5\xaf\x99\x0c\xf5\x19I\xc9 \x13PV\x1bQ\xd61J\xa4\n3\x8c,\n\xbd\x9e1\x833zLJ\xa9{\xe5\xa3\xc9\x9eMg\xc5\xfd\xff-\xfaQ\x0fm\xc6\xc55\x17\xaf\xd5\x81\xa7)5\xc6\x1a\xed\xd7p\x04\xee\x02\xcb\x16gTk!D\xa9wk!\x8c\x8eEY\xfa\x8c\xc7\x94s\xf3\xed\xe1\x85\xe7\x83\xe5b\xf1\x86k\xd6n\xe0\xc3\xdc\xa3\xb0\xd3\xd39\x1e\xb4\xf3\xffI\x16[a\x1cTr\xe0\x9c\xf2\xff}X\x9d\x17\xafV\x16\xec\x87\x02a\x82\x02\x0f\x8a\x89\xe3\xf9\x97\xcc'6\x083\xfc\x9f\x83e\xab\x8by9Q\x90\xb8\xba[CJ\x19&\xb2\x1ecgw\x02\xa1\x8f9m\xf4IWYld\xf8\n\x030atO\x89\x94\xcdA>\xebpB\x95/)gTKm.)\xe5\xe9\x96a\x94\x8bE\x10e\xcc`\x8a\xa4\x06\x05>6\xe7B\xc9\xbe\x0b\xe30g$\xb1\xd0\xc1s\xbd\xbd9[\x04\xdb(ol\xc9q,@\xf3\xd1\xcc\xce\xeb\x84\xb2\x16sX\xb4l\xa7\x97\xbe\xc6\x0dA\xdef\"\x91\xc8\xb3\x1c\x7f\x1eA\xe8\x06(\x9b\xa8\x01\x046\xea\xc0I\xa4\xe1\x16F\xea\x06x\xb5\xc2\x90wW\x8c8qI\xe3\xe3\x9d\xf1\xbf\xba\x08\x92R0\x83\x9e\xb9Of\xb22\n\xa3/\x86\xc2\xb2\xd7\xe4c\xa9\xde\x1c)U<2W\xdc\xd24\x1bF\x84\xf0\xf2\xfb\xa2\x04\xe6`o&\xd6O\x0e\xfa\xeb`\xa3\xe5\x92\\\x07\x9b\x1a\xdb+\x9d\x85M\xcfKV\xcb\xe2\xb8%\xed\xf5<\x99\x035w\xd94\xe5\x05-\xfe*\xd5d\xa8\xa0q{\xcd\x81\xbfy\xbd\xae,\xf9O\xcba,\x99\xd7Y\xb6\xa1 \x97\xbfR\x1a\xd4\xda\xea\xef5\xeb*fb-\x9fn!0\xe5#\xc6\xee\x96\x82.\xe5\x82\xde\xc5\xec\x1ar\xb7\x80(\x97S\x8e\xcb0\x0e\xd2[\xc7\xf3\x8a\xd7\xcee\x90\xb1\xfbw[-\x07V\xa5\xe8\xde]O$M\xed$\xce^iY)\xcdA\xdd\x0f, \xcf\x0f\x87\xe6\x84\xe7\xf7;\x05\xf47\x1c\xc8(\xde3\x01\"\x9d1\x14\x19\x0bb\x91\xb1 uC7\xf6\xd0\xc2\xaa\xc4O_$ \xc6P\xacB\x17\x8e\xd1\xbeV\xb8\xe6 un\x81*}@\x9f6p\xc9 \x84\xbe\x8c\xd7o\x14\xc7`\xf0\x84\xe6\x81\xf0\xe0)\xad\x1a\xaf.j\xa5\x9eN\x14\xd4\x90\x13\xf4n\xc8p\xa5%\xfe5E\x84\x1f\xd57\xf3n\xdb\x86YfL\xb9\x16\xe0\x03\x84m2\x92\xde\xc0^C\xc3\x16\xed\nt2\x9b\x9bQ\xd0\xaa\xaf\xc8\x95-.\xfb\xf9\xb0?\xfd\x89\x02\xf2\xbd\xeb\x7f\xf5o\x7f\xbc\xf3\xf57\xbd\xc1\xbb\x9f.\xfe\xcf\x87\xff>\xdf\x0f\xa5m\xc5\x12\x88L\xfaw\xccVA\x1a\xccrtD\x81\x15\x0b\xe6,\x85E\xc8\xa29\xc4\xc1\x9a\x99\"h(\xf2_\xb2\xd2\x94\xd1\xda2\xe7\x8ef\x87\xb6iW\xf5msg\xa9\xb93\xc9 \xcc\xd4/f7\xba\x19\xc3F$Ak\x88I\x7fK\xbbqWL\xd0\xde\x16\x7f\xe6I\xcc\xc6\xba\x8d\xca\xe0\x10\xa8?\"6\xbb\xd9\xb0\x0b5Rk\x7fkH'%\x06\xbc\x1a\x849\x85\x88\xa7s\xf9)%/\xa5\xb7y\x92\x9e\xef`D\xab\x8f\x13\xe3\x97u\xda\xca\xc4\xbc\x95\xe8\x9f\xb8\x0e6\xa8\xf6\xfb\xe50\x81\x89\x0c>z\x12\xccV\xed\x81\xb1Us\xc1f\xc3\xe29%\xbb\xa9\x8f\x98n`\xa3G\xb5.\xab \x85\xc0\xd0]\x97\xbe\x18:\x98\xb3\xe9\xc8\xe4\x94T\xf4\x88{ \xc4\x93%\xcb5\xa1\xe4E\xb0f\x99\xcb\xbcz\xff\x9d\xe7:\xcd\x1b:\xef\xb4G\xa1\x9d\x9e\xb1\xc1e2\xbf}\x9b\xb1\xb9\x12\x1e_\xa5\xc9:\xcc\xd8 exC\xbaB\x9c\x9eE)\x0b\xe6\xb7\xc0\xffuL\x87jE\x8b\x18\x90\xad\xd3\x00\x83f[\x1e\xbb\x96\x83j\x0f\x02\x0e8\x84$\x8e\x92`\xde\x05\x05\xf8\xc3\xc5\xa6\x94e\xdb(\xb7Y\xe4\xb1I\xc6W\xa0k\x9b\xb1\xcb\x06X\xa1\xb3\x11\xbc\xdb^n\x9bI'_\xab\xef\xc2\x88\xbdFva\xa6R1\xca?&\xe7$I\x0f\x06|w\x9feZ\xb2c\x12\x97:\x8d0k\x826\x94\x9dj9\xef\xabn\xfdP\x99Q\x91b\xd8-\xa5\xe9l\x98A\xc6\x08t\xf5\xaa\x18\x82B\xa4j\xec4\x95\xa8)K\x05\xe2\xa9\x0e\xeb2\xdc\xd1E\x18\x87\xf9\xb7\xc9\xfc\xb6\x93P\xcf\xd7\x85\xaa\xf1\xb6N\xe3\x10\x19\x97\x91\xc6\xe9UL\x07\x01\x1e\x14\x0d\xbda7\xd8\x90\x9d\xf3i\x17\xc1.\xa3\x04\xc3\xda|\x1b%\x97\x9a~\x15f\xaf\xe4\xdf/\x17B^\x91\xed\xf3\xa2\x9d\xdb_$\xe9\xfay\x90\xa3\xf3\xf4w\xe2\xef\x8e\xfd\xc8\xe2\x9d\xfb\xa2\xcb\x05\x18\xcc\x15-\xaco_\xffp\xa6\xbd\xea\xd8\xad\\>M\x9d\xea\xd4{P\xa0\x0c\xe0\xf5d\xb9\xb4\xebJ\x07\x1an\xc1\x84\xe3\x8cL'\xeaC\x0d\x1a8\x1c\xf3\xf5v\xa7\xc6\xfa6\x97Uh\xbe\x07.\x1f\xbcXT\x1e\xf9\x87\x0f\xb0\xa7u\xd0\xb0f\x80WH+\xb2\xac`\x15\xdb8\xdbn\xb8\xa8\xcf\xe6\xf0\xad\x9c\x0d\xaf\xd9\x16\xfc\xada\x95\xecH!s\x94T\xb7\xd0\xe6\xe2H7(\x90Lf\x9ci\xbb\xce,\x89s\x16\xe7}\x1a\"\x1e\x1a\x9a\xb0LE\xc6\x11u\xb3Z]\x1f\x9c\x9c\xdd\xe4\xfb\x9b(\x08\xe3\xc7\\\x8c\xcfX>y\xfb\xe6\xbb\xfeCG\x05\x97-\xb0H\x86\x8cRo\x06\xbc\x95.\xdd\x18\xaayx\xd1\xf5\xd3\x91@\x8d\xa6qz\xc1f\x13\x85\xb3\x80S\xb6\xfd\x9b\xfe\xf5\xf5u\x9f\xa3x\x7f\x9bFda\x9bWgm\x94`\n\xec \nxI4\xa5\x95\xbf\xca\xeb9!\x8521\xef/\xf2\x1b[@j\xbdPy\x11\x0db\x90\xc8\x04P.\xd6\xa5=\x0dz\xad\xcd\xb6\xe2v\xa7\x9e$\x954`\xe1,\xd9r\x8d1\xc9QdS\xe4\x17x5\x082\xe0\x8bnC\xc8\x1d\xc6\xcc\xb1\xadj\x9d\x85BP-\x91\x97\x0e[\xac\xf3\xd8\x1a%8\x92;\xcfq\xd4\xbeO\xa5\xe5\x17X\xc7g\xebz\x83|\xc5bwk2D\x8b\xe1\xe6D\xfeZh\xd2m \x8ak\x05\x06\xc1Q\xda\xfb\xd85i\x88n^\x98\xf74Kx^\xb1\x84OQ\x956\\yq\xf3i#\xeb\x95\xda\x8b\xddU\x0b*+\xa6/D\xa7\x95\xfb\x0c\xb4\xe7\x00\xbe#\xda\x97\x91\xddB\xd1uQ\x8fj,\n \xae\x15\x9dt\xb4\xe7#\x94\xa8\xbah@\xd5\x9f\xb3$\xfe\x9c\xb6\xfft\xf6\xf2\x05\xf9qX\xa9W\xe9\xbdMY\x98Y-\x18\xf2\xcc\xc5U'\x80\x7f\xff\xe8\xa1\xeaP_\x7f\xa4\x15\xba\xb5\xc4x\xe6\x0f\x06\xf5\xddhK,\xab\xeb\x0d\x92\xd06%\xb7\x85m*S\xed\xccR6gq\x1e\x06QFn\xdf\xc5o\xaeF \xf9\x00\x8a\x00\xb7\xe2\x05\xa1X\xe22\xf9FE\xfe[\xb3|\x95\xcc\xb11\xfaS\xbe'\x87\x19\x86\x7f\xf8t*\xaa\x1cx4I\x18\xef\x1cC\xe9\x9d_\xb57\x18\xf6P\x13\x0ci\x96\xca`i^~\xc3\xec\xf3\xd2o\x19\x98\xb3\xf2\xceI\xd6a\xee\xf8\xb0W,NE\x98\xb2/Vn_\xacv\xd2W\x98;\xf3\xe4\xedfc\xcf\x04\x00\x05\x1a\xdc*\x8f\x0ftF\xef\x8f\xb8\xbcit\xe7\xfb\xe8\xe6r0r\xe2\xc5O\xe7?N\xde\xa8\xe8\x87k\xe9\xf8\x84\x7f\xa8\xc2\xe2\x87\x96\xc5)e\x0b\x96\xa6( \xd0[\x17\xdb)BRj\x1d|\x7f\xf2\xecy\xed\x0b]\xc7\xb7\xc0<\xaa\xdex\xd12\x8a\x92k6G\xb6\xf0\x1f'o I\x81\xb7\x06)\xfb\xdb\x96eyfB\x08\"rR\x83w\xe3nV\x99E\x07\xab\x8c \x83MV{L\xb1!/\xdf\xddq\x0cV\xc3F3B\xabxP\xbam8i\xbam\xc8\x9f\x94.\xdd\x93\x05]\xcb&\xd2\xc3l\"\xd0V\x1d\x0f\xf7\x04\xf3\x9b8\xc6\x06\xec\xcc3\x97\x16P\x83[\x10\xd7\x91\x0d\xaf\x13\x83\xf4 \x16S[W\xeb\xf6\xa6}_\x93\x86\x0d\x951\xf4\xd3\xa3w\xf1\xfe.\xbbY\xdb\xacq\xdb\xd5\xd0b\xa3\x08\x8a\xec\xe2C\xed\xb6\xbf\xfeH\x7f\x07\xb9qc\xa7\xb9A\xd0\xf7*\xf5\xab\x9e\xb5\xf2\xf9\x9c=\x98[\xf9*q\x84\\O\xb8B\xaa\xf3\x04\x1c\xe1\xea#\x95\xe4,\x0f\xf2-'\xb7\x0e\xfd\xe5`jLN\xf3\xe4\xa71\x1c\x0c\x87\xa2t\xf2^\xc5\x8b\xa5\x8fO'\xfc\xab\"\xe7\xe2\xed\x138TU\xe8\x95\xb49\x14\xbfj\x1da\x9118/\xff,\xc7f\xe7\x05\xbe\xce\xb5r\xfc_\x84\x9a\xab\x90\xa9j@\xd5\xd2/4\xf0\xb0\xc1\x82\xe5\xe68rW\"\x16\xa0\x19*tS\xc2\x18\x9c\x8a%\x01\xa7g\x08w\xc6\x1fy@5\x06\x87\x0e\xa7\xa80\xfaX\xcac*|E_\xcd\x8dp\x85m\x0cN\xa1\xd0h\x8dp\x0d\xa3\xf8\xd9*\x00\xf2'Oo[\xcca\xda\xa1\x03o\xdf7eO\x96\xcfG\x98\x05\xe8R\xd7\xd5\xad~odo\xcb\x8c8\xb6l\xc0R\xaa\xe6k#\xfel\xda\x0bM\xfd\x1e\x83\xa3)\x1aT\xa9\x8e\x9ef\xd1\xa8d&\xf4\x10r\xae0\x95\x9dtv:\x95\xfa\xd6\xb9\xe3\x17.P\x85\x1aV\x7f}\x1c\x05\xeb\x0d\x9b\xd7\xbf\x9e\xc6\xf9\xe8\xbe\xb9\x92\xe9\xfdi\x9c\x1f\x1e\x98\x8b\x9b\xde\x7f\x17%\x81\xfd\xc3\xfd\xbb\xe2\x83\xe5z\xea\xba\x93\\\x06\xba\xeb\xc6\x9d;\xc07\xe9/!\xbbn0\xbf\x99\x81\xc0<\x88\xa5\xf4K\x13V\xda0\xe3\x8d7;[\xe9\x8f>\xb4\xc2\x01\xb8\xd5E\x8d\xc4E\xf3@\xebP\x93h-\x11\x9b\xa8\xf8\xbbX\xd9\x11\xa3\x90\x0cB;\x8f\xdd\xd4\xc2\x82$\xcb\"\xf10\xd8L\x99\xe5\x8e\xa1V@$wO\xa0\x07\x8e\x8f\x81\xb1al\xba\x8f\xef\x97\xc6?g\x11\xcbY\xa7\xad\x17EU\x97|\"\x86\xbc\xda\xe5\xf6\x97,\xef\xd4\xb8\xda8\xb9@\xc4F\x82\x8c\x0e\xbb\xf5y\x8e\xcb\xa9R-\x1d\xaf\x82\x9d\x1c\xd0d\x07\x15\x07<77;w\x96\xfb\xca*\x93l\x80\x80\xf2\xea hk_\x08Ym\xb9Y\xe5SI\x96-z\xf4\xacs$\xe7B\xa6\xfc\xe1\xd4\x18\xe3s\xbaqT;\x957\x8c\x11\x9d\";\x98,\xa4u\xd1vkV\xdf\x8f\xba\x83A\xc3 9\xe0)\xb9p\x904\xa32\xfa\xde\x9bM\"\xfaT\xd0\xd5\xe57\x98L\x87\x99\xd8N\xef;\xce\x84\xc5y\x1a\xfe\x16S\xe9\xb6/S\x0eL\x06\xcf\x0fh\x99R\xc51H\x9b\xa1\xc9E\xc8\xb0\x00\x96\xb3\xf8[\xe4\xf3\xcfO~8ys\xc2\xf9%W\xd8}\xa1\x9e\xfb\xe0\xbc|\xf5\xe6\xf4\xe5\x8b3\xfe\xe7\xab\x97g\xf8\xe9\xd5\xdb7\x8ea\x81fZ\x97\xb3(\x89Y\x97\x15\xd7\xa4\xb2\x19ZP\xfc\x86\x15\xbcL\xe6\xb7\xfa)\xdbi\x1cZ\xee\xd8\x1aWP\xa4\xcb\xd7\xc6\xe9\xa9\x97\xf3\xd2\xcb\xf9gNe^9\xf9o\x9a\x14i\x0fc]\xdb\xb0k\x84\x85\xaa1\xae\xaa'\xf6JB\xeb\x18K5D\xd3M\x1a\x94\xcfm\x1a\x8d\x95\x9a\xb2\xc3*\xcf\x07\x9d\xfdi$\xba\xd1\x92\x91\xc5\xa8}\xa1\x1a\x82\x82\xe8\xcb\xe3X\"h5\x9b\xcf\x98R4q\x16N\xd5\xf3\x11\xcc\xd2\xd0\x95\x88c==\x1c\x8e|8\x1c\x1e\xf0\x7f\x0e\xf9?\x0f\xf8?\x0f\x0d\xe82\x1f\xa4l\x1e\xa6\x1d\xd2\x8d\xcb'\\\xa8\xfc.\x97\x9a\x95O\xb7\x96i\x11\xb7\x94\xbb\xa9Pjg\xc9\xdcz@_\x02\xdd\xae\xfb\xd0\x05\xe2\x9a\x95\xa7(\xa1\xa3\xe6\xc6\xcb\xc6;\x80\x1e\x1b|\xafT\xee\x84\xff|M\x06A\x98\xc0\x8c~f\x9b$\xc6{\x9ds\xfe\x1b5\xe7\xae\xab\xaf\xadQ\xcdi-n\x10v@\xb7\xbe \x99\xc3^\x9aml\xa1(\xfc\x9f?\xfe\xf0}\x9eo\xc4<\xec\xa6\x9apG\xcf8\xd0\xb0\xaf\xb9\x14h;\x1e\xb6\xd2\xa7r\x0dB\xc4\xb0\x13\x91\x92\x8f\x02\x9d\x8d\x1br\xc1\xf9Y\x14\xc9m\x13\x9b\xeb\x8a\xa8\xbev\x97\x110#\xa9\xfe0a|qR\xd1\xf8\xdb\xd7?\xa0\xca\x1c\xc2\x11\x84\x03\xed-\x8c\x81\x95\xfdI\xfe\xb3/\xf6\xa3\xcf+\xb5\xf8\xbcH\x93\xa2\xea\xc8\xd0\x0b\xe6\xe9\x97?\xf8257\x19\xbb\x82\xc7\xe0%x;\xe6\xf8\x08\x16\x9d\xa9\xb1|\xd2\xaak\xe8\x0b\x96_'\xe9{i^\x87E\x10Fln\xf2\xfd\x90\x8f\xe8:\x0f\xd7,\xd9v:o\x97\xcf\x17\xeb|\xc3b7Q\xc7Q \x9d\x7fa\xaa\x1d'\x8cg\xd1v\xce\xe8\xf0!)\x9d\xf6p\xc9*\x1c\\\x87\xf9\xea\xb8tND\x15\xd5\x16\xddn\xe46\x96|\xc1\\m\x17\x05\x17!/\x0c>\x00 B;\xf9G\xcb'\xe4\xea\x95\x80:B\x03\x8b\xbb\xb4|\xb8$\xc9+\xc5sWsoO\xb4C\xb7#:\x8a\x1b\xeb/mR\xa9\x99\xd8\"\xf9\x1cl\x92\xe8v\x11F\x91\xc9+X\xfd\xe5:[y\xd1_\xbfk\x90\xb1h\x01G\xf4\xdfXS\xb1>\xeb\xa2l\xec>\x1a\x9a\xae\xaf\xf0\xf7\x0f\xcd\x17\x92\x1e>\xb2\xdc<*\xef\n\x85!\xe6\x84\xb0\xdc\n\x1e2\x8f!)\xbfUQ\x02\xc6\xb5\x9c\xf7\x9f9\xbf\xc3\x87\xd5y$j\x1e\xf5\xf9\xd5!\xeb2\x0df\xef\x19\x9fHg\xd3\x00f\x84\x9b\x9e\xd7e*\x83\x0d+\x8c\xe7\xe1\x8c\x95Zo\xe7\xab\xd4\x01f\x96\xa3\xe4s]zJ\xd9\x86\x05\xad10@\xeb\xa5\xdej\x19d\xeb\xf7\xd2\x9e\x079+Y\xcdN\xcf^\x92\xe1\xac\\\xd6\x1c\x8dg\xce\xa2p\xcd\x15\xb31\xde\x0e\xae}\x97\xc1n\xf6\x0cR-}K\xc7\x90\x8a\xe0\x13\xb6\"\x7fA]\xfde\x1c\xdd\x8e\x8d9\x063\x96\x86A\x14\xfe\xc2\xf8\\vX\xad\xa0v{U>\x86\xbd\xc8\xde\x87\x9b\x17\xdb(\xca,c@p\xe6\x05\xbe\x0f\xe2y\x84\x91Q*V\xf3J\xa3\xba\xc6\x0eL\x04~Q\xf1\xc82\x1f\"\x9f\x8buE\x88\x04\xd3l\xa4%\xdb\xc0R\xd1\xdbZv\xa0{\x82F\x1eV\x89\xb8Xwe\xba !\xdd\x82\xaft\x7f\x0e\xbe\xb6Tq\xe36\xd6RW\xc2\xaf\x9a\x04\xfdP\xb9LQ\x06\xb4\x15\xa7\x93|D[\x01\x0c\xe8\xfbf\xb8\xe2\xcd\x9f+\xf4\x8fm\x81u\xb0{\x9c_\xa1\x84U\x8f\x97A\xefe \x80\xea\x87t\x10f\xe2V\xc1\x95\xa7\x0d\xff\x08\xa6s\x17#\xc4\xc3\xb8:\x07\x8f#\xfb\x84\xa3\xfd\xdc\xcd\xdc\xab\xd2\xa7s\x18\xf3\x9a\xb1^F\xb8x\\y\x9eA\xa5\xe2\x9b\xbd\xf6\xd1~n\xb2\xe0\xe0\x96\x15\xcc\xf0J\x0d\xd1\x10\xff\x8f\x97-\xdf7\x8a<\x0f\x8f\x07\"\xcb\xd6\xdaU\xdc\xdbJ\xda3\x13t\x808|\x98\xc1\x11\xdc\x0e\xb2$\xcd\xdd\x19\xdf\xe0. \x9a\x94\xa9\xf3\x92\xbc\xdd.\xe1 \xac\x95\xb7[\xafw\xd9\xa4\x7f_\xc0\x04\xd6\xd3K\x8b\xc1\x0b\xdd\xbd\n\x80\x9d^`&\x07wY\xbd9\xef^yp\x04K\x99S\x86\xb9\xbc\xa8\x0f FP\xf3Z\xd0\x96\xcf\xb3V5\x86\x1e\xb8\\8p\x06|\xe7/T\x9e\xd2\x0b\x95\x9b\xb4\xb9Q\x03\xd1\xaa\xbd\x91\xfb_&CfQ\xa0\x91\x99\xa9s\xfd:\xe1\x0b\x80n\xe5\xa6\x83 \xcb\xc2e\xec\xfe\xfd#606\xc6\xcdQ\x01\x99\x02\x89\x07x\x8aS\xdc\xf7-\xbd\xd7\xc8W!T\x05\x05\x810\xba\xd1\x9c\x88\xfa\xab\x00\x03\xa0_2\x08\xd4\xe4j9E\xaeD\xdc\x1b\x0do\x82\x81bjp\x04[\xed\xd7X\xffV_\x89\x19\n\xc4u\xe2\x11\x0c\xea\xcc\x01\x8e\xcc\xaf\xc7\xb05\xbc\xae\xf7\xb5\xb0\xf7%\xf9\x14u\xa1~a\xcb\xf2W\xbd\xc1\x8d\xb5A\x11\x18\xea\xa8\xf8s\xac\xa8X\xbd\x1d\xae\xa2\x1b\xb9N\xb1\xb1G\xda\xdfES\x86\x05]\xd9\xdb\xca(\xa5\xbc\xf8\x83N\x8b\xea\x0d\\\x15;K\xb0\x85\x9eU\xcf\x93\x1cy\x8e\xf6\xb3^u\xdd\xd0\xb7.n\xd0 Jop\xa5\xf57\xf5\xd6\x97-\xab]H<\xdaji/\x8be+^\xd6\x91\xad\x04\xd4$\xdc{\xea/4\xa2\x0bo\x93r\xd5\"\xf3U\xa7\xc8\x15\x89h0gi\xe6\x17\x1dY\xb0\xf3m\xfc>N\xaec\xa1k@\xb2A\xf1g\x93&W\xe1\x9c\xcd\x8d\xf8)\xc2\xb1\xe2\x80\x8b\xae\xa6\xb2\xa7\ni\xb7l\xda\"\x8c\x08\xa1\xd1\xa1\x95s\x12\xf9\xces1/\\\xfd\x06\xae*\x80\xba/&o\xd7\xab\xd5\x07z\xedc*\x82*oF!D\xc6\xc2)\xe8\x98\xee.:\xe1\xfd\x0bj]\xbd\xf8s\x8d\x9d\xa2\xff\xc2w\xb4h\xc2\xc0R~9\xe6\x8a?*&\xa8\xba\x07X@\xbc\xe1lF}\x1csE\x9f\xeb\x15\x8e^\xa7>\x9b\x1b\x98@8\xbd\xaeL\x06\x83\xc8\xb8U\x96\x1f{\x18\x0d\xeb\xce\x1d\xc9\xdc\xabw\x1c\x15\x0f?#\x1e~\x06O\xe0V\xe3\xe1g6\xe1\xf6\x18&p;=3\xf0\xefE\x89w\xc7\xd3c\xe2\xdd|\x07N$\xb7\xcd\\\xfe\x1e\xa3\xf8\xde(\x0e\nG0\x97$\x83C\xd6\xca\x87+\x9f\x0bV\x17>,\xab\x8c\xf5cm]\xdec\x07\xe8f\x16\x19\xcc\x9c\xcf\xd0P \x90.\x98\xcf\xff\x9f-Ko_\xa5l\x11\xde\xf0m8r\x0c1\x9e\xc4\xce\xbf/\xf2 \x0c\xe1\x08\x9eA\x0f\xdeW\"\xfc\xe0_\xbf\x8az\xdd\x82\xeb]\xf4nEN\xcd*\x12~Vn#\xb6B\x1c\xa4\x7f\xe0,v\x0c\x07\x06\xa5\x91\x1c(Qi\xa4?ME\x9au\xd29\xdb\xe4\xab1\xdc30\xc1 \x0d\xd6,g\xa9\x18\xc0\x88\x1d\x1a\nEA\x18\xd3j}1]0\xe8\x10L\x05\xda\xbce\xd5\x0ekl\xeeH\xcb\x92\xb1\xffn\xe0N\x7f\x1aL\xcf{\x1e:\xb2N\xffmt\x8e\xf7\xfa,\xbeW 6z\xdf}7\x9d\xfe4}w~\xfe\xcd\xb9gK\\\x03b\x16\xe5\xc2\x94h*m:\x86\xe3\xd4\x0d\xc5Gq\xa5\xda'\xb2\xc5n0!\x85\xbdb\xd6p\x8e\xcd\x97\xa9\x16\xcd\xacZ`/\x1e\xe8[ \x98/\x0c9Z\x15\x1504\x1a\xa5\xab\xae\xc0\xb0$\xdav\x83vF\xa7\xe2\x86;[`=\xfdQ\xc4R\xe4\xf6VB\xb3\x1b`\x08G\xb1\xa88\xa6\x08\x9e@<@\x90n\x0c\xf3\xcdg\x1cA\x0fC\xe7\xef2\xf3`::\x17[3\xf2\xa1/\x02v\x7f\xc6J\x04\xc6\xa0\x14`]\x0ci\xab\xe1\xdd\x8a&HQ\x92\x10\xa3\xc0E\xe8M\xd6\x01tA\xb0Ry\xb9\x0d\x1c\xa9r\xca\xf2\xa2%7\x1b\x89\xe4\x03\xc3\xc7\xd0\xef'm\x8d\x81@\xd0\x90\xa2\x98\xb3i\xd2\x90\xda[>(9LE\x0c\xb6\xc0Cl\xc44\x08\xd3sO\xb28\x9b{\x99\xfet\xb8M-\x1f\xb4\x18\x97\xc1\xe3H\xf2\x86Y\xca\x82\x9c\xa1\x0eg\xd2\xefl\xcf\x95\x08\xe5\xc7\xb7\x8d\xd8b\x91\x9f\x91+y\xe7\x95\xd7\x81\xb6\xc6\x1e\xc9\xd7\x1a\xfcq-\xcc\xbe\xc7\xd5\x87S 4_\x9f\xc6\xb9\xbb\xf5ad\n\xd9`z\xf6\xc2\xecE\xf0\xc2\xcdp\x88\x01b\x1f\x06\xbd\x17\x06\x9a\xcc\xc31\xe3\xab\x8c\xc2\x8c\x8a\x1c\xc8i\xc6P|\xcc\xe8\xd3\x13\xa4\xc7\x8a\xa9\xc1\x91\xda\xc0iv\x8eQ\xf0\xc7\x10N\xb7\xf8g\xeb\xc0\xcc\x18\xa2?\x1cT\xc3\xc6R\xcdm\x08l\xb3\x0f\xe5\xa3\x9b \xec\xa9\x15\xa9\x98\x9a?\xc3\xcc\xf0 \xf6\x84X\x88\x03U{B\xe9\xbd\xd1\x9e\xa0JX4\x96\xe7l\x07{\x02\x8ei\x10.\xe3$e\xba\xe4\xa7dB\xc3G\x1f\x87 \x8d\x0c\x13S\xacl\xbd\x80\xb0D\xbef\xcb\x93\x9b\x8d\xab}\xf10I\xa5n\xae\x085s\x85\xe4\x12\xbc\x83\xba\xe5S~\xc3?eI\x8c\x83=\x11\x9eZ\xc1\xa0\xf8\xe9#f\xb1\xcd\xb1\xf0B\x0e\x06\x17\xea'f\xa5\xc8f\xc1\x86\xbd\n\xf2\x95\xba0\x8b\xa5\x0c\xefy\xf1ml\xab`\xfcR\x1e\xfe\xd6\x90\xd7\xaf\xd5\xad^\xc0c\xbb\xcf\x01]\xd0\xbc\xccXzE\x1e\x9c\xd3syk\xf3\xf2g\xa8f\xfc\x80\xba<]\xbdQ\x17\xed<\xb4\xb6@\x95\x9cv]\x06\xb3\xf7\x14\xc8\xad4`\x98\x98\xa2mV\x07h\x8a\xfd=\xab/I)\x8b*\xe5\x9cJ1-\xb9\xa471<\x81\xf41\xc4\xbd^]\xcb@\xdb\xce4>\xa7e\xc3H\x0bd[\xb7N\x0d\x19VlQ\xb7/S\x16\xbco\x99\xd9\xc2\xcd\xe9\xbe\x88\xaf:\xe3\x7fm8\x14s\x11\x0b\xd3D\xa8\xdfR{E\xabJ\x81\xaaz\x1b\xa2\xa4\xe1\x08\x81R\xc8\x8a\xefF#q\xa8\x1b\x891\x94\xad,.`\x8a\x15\xfb\xa8n\xfc\xf0_n\x88\x89\xbf4jY\xdf\xac\x85\xab\xb2\x01\xd4,\x1a\x18b\x82\x92\xe9\x98\x96\xda(\xa4\xe7\x83<\xf9\xd3\xd9\xcb\x17@9X'\xea\x85k\n\x14\xa3\xe0\"D\x9epAK\xfdg\xce\x9ar\x8f\x84\xa1\xf2[\xe6\x91\x98\xb37\"\xde\x17\x94\xac3\x99\xb0\xced\xfd~\xa3X\x83\xe6\x18\xe4T\xd3\xec\xbc\xc1\xa2\xb8\x97\xd6.\x8e\xf9\xb0\xf1*\xd2g>\xdd\x9cWt\xd0\x08Mf$\xc0\x94\x8f\x98rO\xc5\xac\xb7\x9bg\x92\x0d\x1e\xd9\xac\x93+\xd6\x90o{\x13\xe4\xab1\xdd\x0c\xdc'\xf3\x98\x81\xe0\xb9\x1b\xfb\xc5\x1c\\HK\xae\xd7\x16\x03\xd2\x95\xc8\xf9\xc2\xe7n7\xaf\x18\xf2ADP$i\xa2\x1f\x86B3\xbd\xd0\x8c\x0b\x89.\x89\xa2\x1cJ[\xe7\xcb\x85\x1d2\x11`;\xee\xde\xd0o_r(\x96\x1d\x05\xf3\x86u\x87\x1d\xd6\xbe\xb9\x15\x11}9\xd5X\xa0;kr\x81\xedjF5\xfbEm9\xe0*j\xb2W`\x8f\xb9YDNMm\x08\x15\xb5\xcez\xbd&\xeb'\x07\x8e\x0d\x9e%f\x0d\xc0Q\xc3-f\xc3-\xae\xfau\xde\xbf`>\xff\x87\xed\x1d\x1fm\xd3\xf6u\xd8=\xcd\xc5X\xfd\xc5\xa5\x1c\xc1\x96\xdb\xeciZQ=+\x02\x97\x94:\xb6\x80\n,\x99\xbe\x9bE\x9cR\x08\xb3!\xf1\xf5\x82\xa1\xe7\x94`871tPL=\xd7\x98\xba\xd2\xe1\xf9\xeb\xf2\x9a\xd4\x02 \xf1\xda\x898\xdao\x95vJz\xb9\x90?\xb9bq\xfeC\x98\xe5,F\xfb\xa3\xed\x93\xeb\xac\x93m\xc6\xb6\x1b\x87\xac.\xd6b\xef\xd9m{!lk\x9e\\\xc7m\x05\xdf\xb3\xdb.\xc5f\xab ^2,\x85\x807Of\xdb5\x8b\xf3\x81\xfc\xe3$b\xf8;\xc8\xf3`\xb6\xc2\xda\xae\x93\xc4\xe59u\xad\xa5O\xb1k\x9d\xea\x8c\xbb\xd6+/@\xd7Z\xfazt0A\xc4\x15\xb9;\x16\xaa\x01iO\xb1\x99J\x9b\x80z\x86y[\x8c m\x84\xddV\x12\xa7\n~!R'\x1f\x03\xc9+\xf4\xc3\x12\xc9C\x9e\xadw%r\x80\xc7>\x8c,\x08\xc9 _\x87\xaehH\x02\xb1\x0d\x13\x0d_-\xc8h,i\xc0G{\x8bu\\\xb3\xb5\xa9J6\xe3\xdb\x9c}\n\xbeUju\xc27SO]0\xa7\xdeW1\xb5\n\xeap\x8eT\xc0\x01\x85n`\xd7@I\x99\xbcRD\xd6\x8fd\xad\x8aYJ&\xa8\x19\xff\x8dv\xbe\xb4\x9b\xa0bp \x91F\x90B\xb1Em\xbd\x9a\x01\xac\xc9h\xa8\xb4\xe3\xcfI\x02\xd69\xadW)\xe1\xafQ\xa9\xd63\x94\x1d\x95~\x8d!\xf6\x06\xd9*\\s\xf6\xdd:/\xb9dZ\xc6\xb7%\xeer\x86'\xf2v\xa2%\x06\xdd\x12q'\x90\xadi\x92\xa7\xd9DdH\xab#}!-Ck\x0d\xf6\xa3mo\xbd?C\xee\x17uK\xcb\xac\x82\xd2\xfb\xfa\xb1\x19\xd3\x8c=\x9d\x9ce\x99\x0f\x0e\xff\x831\x87\x1cij\xb56\xa2\xfciv\x12o\xd7\x14\x11\xc3P\xf7\xc3\x07\xdd\xa5\xec\xa3Kq4\x0b\xc8\x89\xe1\x08}\x0b\x12oPD\xb3\x9f@JVR\xfdUb\x04\x94\x9d|\n\x8d`JQ;p\xe12\x11F\xad\xfaQ\x85\xf4(\x1d\xa8Y\xf6F.y1ih\xba\xebU\xda\xd1\xe6\xf1\xb1\xc1,\x89\xb3<\xdd\xce\xd0\xc0=\x99\xe8\xdf\xd0t \x86\xabv \x8e\x8aI\x8d\x0d#3A\xb9\x1d\xea\xb4\x93\xcc#\x0ee\x11\xb6\xaa\x9fh\xf2\xf7\x1a_\x1c\xeb0:)9z\xd7\x8bR\xa2\xc8#Sz!\x07\xcf\xe5K\xed\xb5\xf4\x9b\xb6\xe1\x96!g\x8f\xc4e}\xc8 \x0d\x00\xb3\xc2\x8c\xd58\xb4/\x81[\xc9Bo\xea\xcc\x90\x7fG\xe9\\\xeb`\xe3\x86\xcdc5\xe4\xa4\x91\xf4\xdcz$,\xe9y\x15\xbdE\x80%7\x9f\xc6\xe7\x18W\x9dM\xe3Z\x10\xfc:\xb57\x8c\xca\x90\x87\xa6\xa4\\+\xbaZ\x18\x82G\x15\x83\xa3*2\x1d\x9d\xf3\xb5\xd4\x7f\x8eIX5;\xf0bT6\xb6\n\xae\xc2d\x9b\x8e\xc15\xf4u`\xed\xeb\xa0\xdc\xd7\xc19\x1e3z\x83r\xabx\xc5N\x9a\xd5J#Pg\xe4|\xeb\x9a\xad\x0d\n\xb91&u\xb9\x15\xcf'+:}\xf3\xa5\x13e\xc4\x85\\%\xf2F&Y\xb7\x94\xbf:\x9dF\xe7t\xda\xad\x1f\x91\xceD\xe2\xe8\xe1c\xd8\xc0\x13X\xa8\x067v#\x18o\x11#WL7\x0d\xa7\xe6+.\xf0L\xe7\x0d%\xae0\x97\xe3\xaa\xc1\x12\xb5\xc6\x12\xe1tn\x8b\xef^\xba\x8a\x80W\xde\xec\x12?\x96- \xe3\x13X7\xa9\x1b \xe6\x8a\x0e z'k8\x02>\xa8\x0e>\x83!%\xc0\xce\xd0\xebk\xba\xf4a\xeb\xae\xbcs\xa3\xbb\x99|D\x9clQs[\xbbz \x1fu\xadE\xa76m\xf3\xd7\x8av\x9a\xfb-\x1ex\xdb\x86 \x1f1V\x07O\xbd\x1d\xe1\x17VA\x13Z2\xe9+pk\xbe,)\x9f\xf2\x1a\xd8\x07\xa0\x97Z\xd5J\x18\xd5\\\xfd\xc0H5\xd3)\x17f#\xd5\"\x12$NA\x90\x84\x1dA\x8en\x1ecL\x1e\xcd)\xc1Hd6(R\x1a\xf0\x02\xe7zk\xd3\xd4,\xefg\xe4\x16Q\x8c\xdd/\x06=\x88\x93\x1f\xb7y\x907*\xe6j\xf0\xcc8\xf8\\\x0d^\xe6g\x18\x92\x1e\xcdH\x8f\x06\xc1\x07\x8a\x81V\x0f \xd5@\xc9\xbf\xd1<\xd2\xeb0_\xbd\xc4+R5\xdfI{\xba\xd5L}\xafl]\x8b\x8cg\x0f\x0c!\xf3\x8fC\xec>\x1a\xdd\xab\x10\xa0\x8b\x0b\x96\xfd\x98\xcc\xb7\x11^\xf3\xdf\xad\xcb\xd8\x1d=x\xc0\x17\xd0}t@\xff\x8d\xee\x8b\x9f#\xf1\xff\xa1\xe7\x97\x05[wt\xcf\x1b\xfc\x95\x05\xef\x7f\x0c6]\xfah\x10]}\x99\xc9\xf7p\xe4\xb9U?\x8ePtV\xbd,C^\x0e\xa3\x83\xbb\x95\xf7[j\xea~5Y0\x0d\xfa\xd1\xa8\x1a\xbb\"\xa2\xf2\xd5\xe6g\xf8\xfa^\xd5{d!\xbcG\x0e*\xef\xf1\xdcr\xb0d9_\x91\xf2\xa7y\xc1\xbb\xc2\xec\xe4&gq\x16^F\x95\xcb\x1e\x9c\xedd\x83\xed\"\xcb\x93\xb4\xf2\xe9\x8a,\xca\xa5w\xed\x01d\xab^\x076\xaa)Y\xb8\x88\x8ag\x904\x86%qbx\xaed\xd3V\xd7\xe3\xf2\x98\x97FYg\xc9:\x05\xd6\xc0{\x13(A\xdb\x89\xbf\xa4q\x1bcj\x06\xf9\x88 \x0b?\xe0\x1c\x8e`\xe5.\xc4\xec\x1d\x01\xcf\x8e\xe7a\x0c&\x94}1\xfa\xb6HU\x14\x16\xb37v`8\xf4\xab\x8b Yy\xca\xedAK\xb2\xc1\x9c-\x0c\x83\xf4\xd1?d\xc7m\xb8\xadj\xa8\xee\xa3\x83\xa1\xe7\xaaV\xf1\n\xde\x12o\xbb\xef\x0d1\x96Q\xb1\x963\xb7\xcd\x18\xf1\x00\xf6&\x80\x96\xa5[\x0fs\x7f\xc9\xbb,\x8b\x94\xb1_P\x18\xa4\x17\x9e{\xe5\xf9\xf0\x80\xd6Yc\xff\x1fI~\xdf\xba.\xa6l\xe3\x9f\x8f\x0b\xad\xd0]\x977I\xbb!\xb3\xf4|\x08\x06/NN\x9e\xe3\x01\xba\x0f\x89;u(\x8e\xae\xe3\x83\xb3\n2\xfe\xdf\x92\xe5\xfc\xbf\x8c\xe5\xce\xb9\xdf\x00w\x12\x96n\xb5.j\xeb\x8c>\xf2\xb5x\xc1!\xc6L\xd2\x1a\xcf\x0d^\x1c\xa0`:'\x03\xc4\x1c\x9d\x10\xcc`@\xb0\xb7(\xd2\x7f\\,\xc4\xe1TSP\xe3P\x065\xbeXL\xd99\x8d\xc2\\Zj\x86|U@\xe8\x9b\xbc&\x8c\x0d\x97\x18\xec\x0e\x91\"\xa8-\x02i^\x8b\xe5\xffQ\xdfc\xfa\xbbs\xa2\xf0G\xa3\x87\x96\xc8I\x8dh$\x07\xc6\xae]\xd4\xbe\xf5\x10\xaf\x9d\xf8b1\x82\x1a\x7f\x10\x1c\xab\xc6\x96\x04\xbbz\xe4\xb9N\xb6a\xb3\x90\x95\xd2\x84t\x93\xd8\x10\xf8\x8cb\nj\xe5\x1c?LW(\x84\xf1I3\xa2\xa0}\x8a\x9c\x85PJBHK\\\xcd\xce\xe5\xa9\x1c\x08\x82\xa6\xfb\x90\n\x90T\xe6\x10\xf2\x18\x9a\x86\xe7\x9e\xf2\x1f\x12\x85\x8b\x1c\xf1\x92\x96R7\xe3\xd6T\xf6\xdd\x85\x03Z\xe7\xe1}\xe3\xfas\xf6o\xe6\xba\xc2\xcd\xb3Z-0\xef\xa6\x10\x1a\x86UaBH:w\xab\xef#%\xaf\x18\xa5\x86\xaat\xd0$5DnU\x92\x9b\xe3\xdb\xea\xc8WxxT\x86\x93\xaeR\x00\x1b\\`\xea\x07\x17\xff \xd2\xb1\xae\x1e\x10\x94~\xae\xdbN\xcb\x90\xb2\x04hrojg\xd9\x86\xa3P\x8cr\xe3\xb2A\xd0D\x94+\xe5\x19\x17F\x10\xf0j\xa5\xaa\xd9\x90\x0b\x98Zk\xd6\xc3\xaa<\xd2A\x16\x91|a)\xe8\x9c5 \x94:\x83\xcb\xa7\xa3\xc6\x15Z\x05\xad\x01\xd2\xa4\xc8\xb2W\xf4\xda\xd4b7\xf9B\x1e;4\xcd$F\xe7yT\xf5r\x99\x021\x10\xf1\xa5Y=\xbete\x1c\xc4|\xdb&'WT\x043\xd6\x01\xa0M.\xca%\x00\x18\x9cv\x0d\xb3\x11\xb5\xfe;\x07\x99\x88%\x90\x07\xa2\xb9\x8f\x97\x08\xf6\xf6\xfe\xbb\x9aTF\xfd\xe57(fe!e\\#u>\x84\xb6\xa9\xa3\xdbc)J\xa35\xc4\xeb\x96\x7f\x8d\xb0E\xe7\"$g\xd7\x8b\x9c\xdcE\xd8\xe0\x82S\xbcU\xaf\xe7\x83@r\xa2\xcc~a$\x04\xbc|\x97\xb9)\x8e\x88M\xc3ss*|\xfb\xd2\xa5n\xa4\x8b\\\xe6av\xdbv\xf9\xa0Gg\x80\x92\xbd\x04\xf3\x91]x\x97@\x9b\xec \xe2s \xbeR\xd2s\xeey\"\x11\x03I\xf71_\x93\x99\x1b\xab\x9c8\xc8\xe4D\xfe\x85X\x89\xfd\xc6\xbe,\xee3\x1d0Z>\xff\x88\xd9\x8bD\x0f\xa6\xa9\x9bgi\x80\x10\x1f\xa2f\xcc_\xd4\x91\xc0\x86\x01)YK\xd1\xb7x\xcft/\xb8<\xa1\x14'\xc4H\xbb\xc8\xc5\xa5\x9bt\xcaP9\x9b d7\x0dM\xa8\xd8c\xb8*P\xfb\x0f\xf0\x05$\x94\xaa( \x04D\x8b9\xa3f\xb6\x08\xcc\xf6\x06\x12L\xeeU[\xc9,RQd\x91Wf\x16\xf9fa\x16\x876$uW\xc3\x9b\xce\xf1\xf5\xdd\xa17X\xd4e\x13\x8b\xf9\xe6\x8a\xea\xdcm\x15\x82%\xa5$\xed\xf3\xd6$\x13_\xe2y\x003\xd8\xe6/`\x02\x97\xf5\xd7\xd7\x9c\xbf\xe1!!\xa30;f?\xd4\x13\x98\xc0\x05G\x86\x8b&m\xef\xc6p\x1e%@\xf3\xcaz\xba\x89\xcd\xba\x18\xad\xe7D\xe5\x16\xe1Rx`W\xa5\xf9\x83*\xf4\x85'\x93*\xb8\x1ez\"\xb9U\x95\xca\x83#p/0\x91\x8b\xaen\x1aqm\xc6\xbf\\\xa0j\xea\\\xcc0\xeb\xe2\xe0b&\xa4\xc1K\x9dO a\xc0\xebsK\x1f\xf2\xe9\xf5y\xcd\xca\xc0)\xc0\xca\xe5\xcb\xe9\xa3\xc3\x94O\x04\xd3\x173\xf4\x97,\xf7WA\xe6g,\xf7\xdf\xb3\xdb\xcc\xa7<\x1f\xbe\x98\x8eO\xb7\x0f\x1c\x99\x9e\xce\xe7\xa3\xe9&&\xe0\x16\x82\xbcnZ\xa8\xacu\xb2\xc1 \x8c\xe1\x84\x9c\xcdq\x03\x1c\x1c**L\xa4Em]}\xc3K:{S\xa8uN\xb4e\x16 \xbe\x9e\x9cn\xa1LA\xfa\xd5\xc2\x8d\x0br\x8e\x06\x07\x1a\xae:\xaf\xb3\xab\xec*\x0f\xd1\xc5\x8c\xab\xec\x05\x05\x1frr\xed[\xd5})\x0f\x15z{R+W\x15\x89=\x9f\x82H\xcd\xcb\x8b\xe0d\xe1/\xcc1\xf1\xf6\xb2t\xdc&\x9a\xd1,\x06\xbc\xb5\xfaPjP<&(^W\xcd=dIY\xfap\xed\xf9\x90\x95G\x1a\xe3\xadOe\xf0\xf1|\xd8\xb8b;n(G\xd3\x85\x0f\x89\x9b\x0c\xfe\x03z\x90\x0c\xfe\x8a\xff~\xe7\xc3\x8d\x9c\xf9\x9a\xb3\x90\xb3\xc9J\x98\xa4\xcd\xb0\x16\xa1\x1eTy\xaf\xec#\xe72=O\xb5\xe7\xc3\xfe\xf4\xa7\xa0\xff\xcb\xb0\xff\xe8]\xff\xab\x7f\xfb\xe3\x9d\xaf\xbf\xe9\x0d\xde\xfdt\xf1\x7f>\xfc\xf7\xf9~8\xc8Y\x86\xb9\xd7\xcc\x81Wd\x82\x97\xd9*H\x83Y\xceR\xceW)\xcd\x00,B\x16\xcd!\x0e\xd6\xc6\x9c/\xca\xfa\x94'?$\xd72\xaftyq-sn\xb6\x84t\x9e6\xeb\xd4\x99\xc1\xf1\x11t'$#p\xc5\x98u\xa4\x95\xac\x82\xd6\x10\x93Iv[\x957{[\xfc\x99'1+9\x88\xb5$<\x11\xb7\xa2\xccI\xac\xc0\xa8\xe2\x99\xdf\x1a\xbcF\xc4\x80+i\xc3rS\xb2\xb0\xd6\xb5\x92\xb2C\xbd\xdf\xce\xd9~\x0d\xde}\xa0\xa5\x02\x14\x97sJ\x19\xf2\x13\x0c\xfd\xb1S\xbe\x0c2\x1eQ\xd6bs\x82\x0c\x91\xf9\xbf\x1e\xcd\x14\xbd\xeaL\xddu\xe9\x8bM\x87\xe7>0c\xe86\xadG\xdc\x03q\xee\xb6d\xb9\xe6\x1e\xf7\"X3\xae\xfd\xef\x90!\xaf:\xd7\xa9)\xab\xdcGS\xe6B\xdb\x1e\x19|\x13A]k\x90\xd9\xf8\x95\x04-\xb2 \x0dR\xc6\xe7S\xcd\xdb\xf2,JY0\xbf\x05\xfe\xafc\xba\xcc\\\xc9\xef\xdfi\x80\x06\x7fF(K0\xb5\xd4LM\x81\xec\xd8\x8eY\x93r\x97\xcf6\xdbF\xb6D)x\xff}\xb7\x8c;\xb1\xcb(aZw\x1bO\xa7\xa52\xf8n\x82F\xf1\xf8Z\x15\xb9\x97\xcdT*FW\xa9\xdc\xce?\xf2\x01\xdf\xddg\x99\x96\xac\x96\xdc}:\x8d\xd0\xe0\xc7 \n\xda0\x86\x8cvCP\x04\x9f1\x8cE\x9fQ\x91\x8f\x98\x03\xecm\xce~\xa0\x0b\xbb\x0d3\xc8\x18\x81\xae^\xd5C\x15\xfc\x12'\xd4i*QS| \xc4S\x1d\xd6G\xd54\xdf\xad\xa7E \x0f/JY\x05\xe9\"UC\x12\xa0\xd0\x9c\xdd\x81yZ\x0eE\x91\xd9\xdc\xa0\xa6\xcbG\xf9\x05\x16\x89\x8e\xbe\x8d\x92K\xcd%\xbf\x9a\xecXo\x9f\x17\xed\xdc\xbeL~\xcd\xfb\x90\xe1g:\xf6#\x8bw\xeeK\xcf\x7f\xce\xfb\xab$@\xef\xd8\xad\\>u\xc1\xa2I\x86\xd0z\xd7\xd2mC)\x87\xd4\xba\xd2\x81\x86[\xe8\xf7\xc9\x04\\\xca\xec\xc0:4\xc4\"\xb7\xb9;5\xd6\xb79\xbdB{\x00\x03\x90&\xf1\xf2\xc8?|\x80==S\xb5}\xcd\xd0\x00\xb3\xac\xc8\xb2\x82U\xe8\xd7-\xbe\x95\xb3\xe15\xdbr\xab5\xac\x92\x1d)\x84+hm\x0b\xab1\xa7\xe5\x83\x05K\xf9\xdffI\x9c\xb38\xef\xd3\x10\xf1\xf8\xd6\x12\x04\xadT7\xab\xd5\xf5\xc1\xc9\xd9M\xbe\x8f\x01\xa9\x1es1>c\xf9\xe4\xed\x9b\xef\xfa\x0f1\x04W\x05\x8b\xe4\xe1\x98z3\x10W-Z\xbb1T\xe3\xed\x7f\x0e\x12\xa8\xd14N/\xd8l\xa2\x90\x92<\xee\xdf\xf4\xaf\xaf\xaf\xfb\x1c\xc5\xfb\xdb4\xa2\xe8\xfc\xf3\xea\xac\x8d\x12\x8c\x96a\x8d\x88)\xd1\x94V\xfe*\x8d&!i\xcc\xe6\xfd\x0d)d\xb4\xe44\xf6B\xe5E4\x88AY\x12]\xb1j\xb1.\xedi\xd0km\xb6\x15\xb7;\xf5$\xa9\xa4\x01\x0bg\xc9\x96k\x8cI\x8e\"\x9b\"\xbf\x98t\x17\x82\x0c(\x93]\xa3e\xa2\xcb\x989\xb6\x9d\x9b\xb7\x99\x04\xda\x12&\xb7nq\xc9\xaaY\xa5\x04Gr\xe79\x8e\xda\xf7\xa9\xb4\xfc\x02\xeb\xf8l]o\x90\xafXl\x8aM\xfdQ\x92\xdf\x9c\x88G\xeb8\x7f\x13Pl\x17\"`G\x11P>vQP>\x15\x91\x90o\xb3A\x16\x94\xcf\xc7_\x0bM\xba-A\xc9\xf3\xbe&\xfd\x91\xbfzaS\xcde\xdc\x17\xf2\xba\x1f\n\xaf{u\xb5E:\xdf\x9f+\x1b\xc7`\x91&\xeb\xe3U\x90\x1e's\xe6\xe6\xd3F\xd6+\xb5\x17J\x99`\xcbk\xfa\xd1\xb2\x10\x9dV\xee3\xd0\x9e\x03\xf8\x8eh_Fv\x0bE\xd7E=\xaa\xb1($\xb8Vt\xd2\xd1>\xc7\xf37B\xd5E\x03\xaa\xfe\x9c%\xf1\xe7\xb4\xfd\xa7\xb3\x97/(\x06\xaf\x95z\x95\xde\xdb\x94\x85Y\xab\xe7\x0f\xf9\xf5\xd1\xfd,\x0fU\x87\xfa\xfa#\xad\xd0\xad%\xc6\x08\x94`P\xdf\x8d\xb6\xc4\xb2\xba\xde Q\xda\\F\xf9T\xf1\xcd\xac\x94)\x95\xe9\xbf\xb9\x1a%\xe4\x83\xc2Gv\xa5r4\xc7\x98\x8f\\e\xd7\xf5\xe4NQ\xd6VlL&p\xa5\xf7\xc9\x9c\xd1\xdbd\xce\xfcR\x82\x18`\x9a$\xcc\xbb\xc2l\\z\x06\xf6\x8a\xbd\xc1\xb0\x87\x9a`H\xb3T\x06K\xf3\xf2\x1bf\x9f\x97~\x7f\xf8P_\xa1\x0f\x1f\xc0I\xd6a\xee\xf8\xb0W,NE\x98\xb2/Vn_\xacv\xd2W\x98;\xf3\xe4\xedf#\xed\xbe\x8d\xc8}\xabe\x1a\x87\xa7\xd0\xa7{H\xa6\x8c\xdd\x1f\xdd\\\x0eFN\xbc\xf8\xe9\xfc\xc7\xc9\x1b\xc7+\xefcN\x7f\xa8\xc2\xe2\x07\xe5\x9d\xc1W)[\xb04EI\x80\xde\xba\xd8\x0e\x99V+\x1d|\x7f\xf2\xecy\xed\x0b\xf9\xcbZ`\x1eUoN\xf90&4\x9b#[\xf8\x8f\x937\x90\xa4\xc0[\x939\x873\x13B\x10\x91\x93\x1a|5\x8e\x8f\x0d\xf7\x17\x1d\xac2\x82\x0c6Y\xed\xd3p\xedz\xf2\x8c\xfe\x8ec\xb0\x1a6\x9a\x11Z\xc5\x03B\x1e\xd1~cxb\xfe\xe0\xf6H\x0b\xba\x96M\xa5\x87YT\xa0\xad:\x1e\xdc \xe67q\x8c\x0d\xd8\x99g.-\xa0\x14d\xf8\xed\xeb\xd3\"&\x19\xd7\x91\x0d\xaf\x93\xeeq\xe1:[\xb77\xed\xfb\x9a4l(\xad\xf4\xfe\xbb\xf4\xe8]\xbc\xbf\xcbn\xd66k\xdc\xb4\xda\xe5\x8d\"(\xb2\x8b\x0f\xdd2\xda\x8b\x8d\x1b;\xcd\x0d\x82\xbeWi\xed\x0e\x82|>g\x0f\xe6V\xbe\x9a+_\xfa\xbf\x17\x82\xbbH\xd0-\xae\xeeI%\x99R\xd5SXs\xfe\x17\xe6\nC\xf7\x0d\xf9i\x0c\x07\xc3\xa1\x8c\xfe\xfa^\xfa\x85\x88\x8fO'\xfc\xab\"\xe7\xe2\xed\x138TU\x8a\\\xf8E'\xfcW\xad#,2\x06\xe7\xe5\x9f\xe5\xd8\xec\xbc\xc0\xd7\xb9V\x8e\xffc\x8a\xfc\xaa\xa1\xb1j\x17)/7\x1axDZo\x1b4\xaf\xac\xc7n\xba)a\x0cN\xc5\x92\x80\xd3\xb3\xe4Q\x92\x07Tcp\xceD\xcc\x88P\x06\xa6\x90\xc7T\xf8\x8a\xbe\x9a\x1b\xe1\n\xdb\x18\x9cB\xa1\xd1\x1a\xe1\x1aF\xf1\xb3U\x00\xe4O\x9e\xde\xb6\x98\xc3\xb4C\x07\xde\xbe_=\xc3\xd0\x9f\x8f0\xc3\xe0\xd4\xcd\x94\x174\x97\xca\x91\xbd-3\xe2T\xa3\x1f\xcbGJ\xd5|m\xc4\x9fM{\xa1\xa9\xdfcp4E\x83*\xd5\xd1\xd3,\x1a\x95\xcc\x84\x1eB\xce\x15L`\xaa\xe2\xd5\x9cJ}\xeb\xdc\xf1\x8b(6\x85\x1aV\x7f}\x1c\x05\xeb\x0d\x9b\xd7\xbf\x9e\xc6\xf9\xe8\xbe\xb9\x92\xe9\xfdi\x9c\x1f\x1e\x98\x8b\x9b\xde\x7f\x17%\x81\xfd\xc3\xfd\xbb\xe2\x83%,A\xfbuP\xf9H^\xc0!\x94o\xd2_Bv\xdd`~3\x03\x81y\x10*[\xaf\xb0\xd2\x86\x19o\x9cS\x88\xdd\x87v\xa5\xc4\xc1\xd6\x10C$.\x9a\x07Z\x87\x9aDk\x89\xd8D\xc5 \xd5\xca\x8eP\x94D\xb5\x9d<\x83\x9a\xae\xde)?\xbeu\xb0\xb1:Di\x05`\x82\xa7\xd0\x18\xfd\xd4\xc7\xe8\xa706$\xff\xc1 ^\xc5\xf8\x85\x93z\x97\xad\x17EU\x97|\"u\x9f\xf6J\xfbK\x96wj\\m\x9c\\ b#\xe4f~T\x9a'\xa5{l\xebx\x154\xfbFU:\x96\x1d\xd4\xc2Bs\xe8h\xeb+\xabL\xb2\x01\x02\xca\xab'\x80\xa0\xad}\xe9\xf3\xdb\xe1\x1a\x14\xd4\x02\xdc\xc8\x1e=\xeb\x1c)\xdc\x8d\x88L\x95\xfb\xc5\x18\xe3st\xfc\xcak\xa7\xf2\x861b\xd0\xb2\x0e&\x0bi]\xb4\xe5\xfb\xd3\xf7\xa3\xee`\xd0\x92\xea\x8d\xc9\xc8lfT\xc6\x8b\x89f\x93\x88>\x15\xf23\xfe\xf5'\xd3a&\xb6\xd3\xfb\x8e3\x11\xae\xd2\xbf\xfeT\xba\xed\xcb4\xae\xdf\xf7\x92O\xd3\x94*\x8eA\xda\x0cM.B\x86\x05\xb0\x9c\xc5\xdf\"\x9f\x7f~\xf2\xc3\xc9\x9b\x13\xce/\xb9\xc2\xee\x0b\xf5\xdc\x07\xe7\xe5\xab7\xa7/_\x9c\xf1?_\xbd<\xc3O\xaf\xde\xbeq\x0c\x0b4\xd3\xba\x9c\x89\xf4\x17\xad+\xaeIe\xd2\x13\xdc\xbe\x82\x97\xc9\xfcV?e;\x8dC\xb3+\x96!\x16\xf5G\x1f\"Bnm\x9c\x9ez9/\xbd\x9c\x7f\xe6T\xe6\x95\x93\xff\xa6I\x91\xf60\xd6\xb5\x0d\xbbFX\xa8\x1a\xe3\xaazb\xaf$\xb4\x8e\xb1TC4\xdd\xa4A\xf9\xdc\xa6\xd1X\xa9);\xac\xf2|\xd0\xd9\x9fF\xa2\x1b-\x19Y\x8c\xda\x17\xca\x90D\xb7\\\x84\x96\xc7q,\x83nDm\xa6\x14M\x9c\x85S\xf5|\x04\xb34$/\xd5L\x0f\x87#\x1f\x0e\x87\x07\xfc\x9fC\xfe\xcf\x03\xfe\xcfC\x03\xba\xcc\x07)\x9b\x87)\x05\xd8\xed\xc4\xd2\xb8\xa0.RK]jV>\xddZ\xf6:\x88\x97UwS\xa1\xd4\xce\x92\xb9\xf5\x80\xbe\x04\xba]\xf7\xa1\x0b\xc45+OQBG\xcd&\xeb\xa4|,\xea\x93\x11\xf4\xd8\xe0{\xa5r'\xfc\xe7k2\x08\x02\x86^\xe5?\xb3M\x12g|{\xe7\xfc7j\xce]W_[\xa3\x9a\xd3Z\xd3%\x17\xd0\xad/H\xe6\xb0\x97f\x1b[(\n\xff\xe7\x8f?|\x9f\xe7\x1b1\x0f\xbb\xa9&\xdc\xd13\x0e4\xeck.\x05\xda\x8e\x87\xad\xf4\xa9\\\x83\x101\xecD\xa4\xe4\xa3@g\xe3bN\xa7gQ$\xb7Ml\xae\xeb\x91\xb1\xc4\xee2\x02f$\xd5\x1f&\x8c/N*\x1a\x7f\xfb\xfa\x07G&\xa2\x0f\x07\xda[\x18\x03+\xfb\x93\xfcg_\xecG\x9fWj\xf1y\x91&E\xd5\x91\xa1\x17L\x0f(\x7f\xf0ejn2v\x05\x8f\xf1\xc1$\x97\xcb\xe7\xa3\x8f`\xd1\x99\x1a\xcb'\xad\xba\x86\xbe`\xf9u\x92\xbe\x97\xe6uX\x04a\xc4\xe6&\xdf\x0f\xf9\x88\xaes\x8a\xfe\xfd\x0f\xe9|\xc3b7Q\xc7Q \x9d\x7f\xe1\xe5&'\x8cg\xd1v.\xe2\xd4%\xa5\xd3\x1e.Y\x85\x18\xa5\xec\xb8tND\x15\xd5\x16\xddn\xe46\x96|\xc1\\m\x17\x05\x17!/\x0c>\x00 B;\xf9G\xcb'\xe4\xea\x95\x80:B\x03\x8b\xbb\xb4|0j\xe4 c\xf1\\\x0f\xa6\x9ah\x87n*}\xa0\xf6\xd2&\x95\x9a\x89-\x92\xcf\xc1&\x89n\x17a\x14\x99\xbc\x82\xd5_\xae\x9e\xc1\x163[\x90lQ\x8d\x85\xf6\x07\xd1xiqv\xbai\x94\x9bn\x19\xdd\xbb\xeb\x0d\xc8\x98b\nd\x1b\x1a\xb7\xc0lQ\x14\\\xc0pLQ5\xd5J\x13\xa2Q'\x10\xcd\xa4*\x8d\x9b\xf4\xc6\xe5\x03\xd1|\x13m\xeb\xa9\xfe\xaa\xb6\xd0\xc6\xcd\n\xb5\x18\xef2\x89\xec\xdd\xf2`W\xf9Ml\xe9\x9eQF\xffE*KN\x910\xdc\x9a&\xe7J\xc4\x1b\xcd\xe0I\x11N\xfa\x88k\xd6\xc2\xbf\xe2Y\xee\xa2s\xfd\x8b\xe0E\x9d\xcee\xd7!\xae\x9a5\xdb\xfd,\xc8\x18\x0c\xc7V\xc0\x97\x0dX\x8f\xd7\xe5\x83\x0d\x1d>\xb0\xb7$\x1f-\xd9\x80\xb8z\xd5\x10Y@>\x98\x86\xad\xb9\x18\x0e\xe0\xeea\xfb\x00\xf0J\xac\xcb\xd7\xf4\xf0\xa0\x85\xdb\xc8\xc0\x86\xadm\x06\xd3\xa8\xd73'\xea\x94\x8fY\xf2\x82\xe6\xc9\xe1\xa4F\xf6\xfe\xb9\x0c\x1b\x92<6\x83\xa7\x13\xb8\xfb\x90On\xc6!\xeb\xde\x03\x0f\xd7z\x06}\xb8\xfb\xd0>O\xe5\x95\x8b\x0d\xdc\xbf\xa7\x1ax0,\x1a\xb8\x7f\x0fz0\xb2\xdc\x10\x86\x1d\x1ch\xa9\x97G\x0fT/\xa3\xe1Ac\xf0<\xf9\xa8\x15>|\xe0k\xcb-p\xab#\x045\x96\xb2o\x10\x08\xb0\xe5+\xf1\xe8\x01\xae\xc4'l3\x1f\xe8\x81}\xa0mPp\xd0\x0c\x05\x82\xc4\x98\xa0 \xfd\\(H\x7f\xe7P\x10\xea\x10\xf1\xeb\x83B\xfa\xd9\xa0\xa0F;\xba\x0f\xdf@\x0c=\x93Q\xfd\x0f\xf6_\x82\xdf\x05ER\xe2\x08\xfaz\xea\x94\x8f\xbe\xc6\xca\xf8\n\x15\xab\xa2XVP\xf2\xf2;\xb8w_2\xaa\xc7\xb0\x85'pp\xef\xfec\xe8\xf5\xb6\x1e\x04\xd3-\x86#\xfe\xa3\x03=p]\xfeqt\x1f\x8e\xc0\x19:\"]r\x0f\xb6\x05\x97\x1d\xdd\xf7<\x9b\x87\x8d\xcc\x9e\xd6hFo\xb8E\xd9\x9b\xf0\xfe\xca[\\\xf2ft\x9cR\xceP\xe1\xac\xc8\xb4T\xc5F\xcdRj\x94%\xb6j:I!\xf0=<$\xf9\x8fkNw\xefi\x7f\xdf/\xfe~\xa4\xbd\x1f\x1dh\x1f\x12\x0e\xfb\x87\x8f\xf8\x8c\x12\x0e\xfbw\x0f\xd4[B\xdc\x84\x10W\xbd%l\xc4\xb7\x8f\x86\xea-a\x0f\xbe\x1d\x1d\x1cX\x04xtd\x80>\xc4*\x1dh\xce\xd7P^(BE\x9b\x8b\xd3|K\x0f\x1e\x12\xbdO9T\xfb\x80\x05\x83ib\xb1\xdd*\x82\xc1\xeb\x1e\x0c\xef\x1a+\x8f\x1e\x1d\x00\x0e\xf7)\xdc?\x87\x1e\x7fs\xf0\x10>\xc0\xfdC\xb8\x03\x9dZ\xbew\xef\xe0\xd1}5\xe7{\x0f\x0e\xef\xde5utppWv4:\xd0{\xa2\xbe\xe1\x0e\xdc?\xdcm\x00\xcd\xd6\x87\xb0\xc1v\x80\x10\xd2\xeb\xe9pW2*\xbd}}*\x94\xb1\xb7\xafOa\x1dD\x8b$]3\xab\xdb!\x08\xfb\xc5hx\xc0\x07]\x81P\xdf\xb4\x18w\x87\xf0\x81\x12\xc5\xdd\xbfw\xef\xf0>b\xad\xa8\x9ex\xf0\xe4 \x8cx\x81\xd0\xf3p\xbd\x1e\xd6\xd6ktP[\xb0\xe6u4\x0e\xbc\x03\x01+\x02\x890\x8c\xfbT\x12qs\xe8\x15\x80\xea\x95c7\x96\x15\x95\x96\x88\x05\xd4\x97\xe5\x8e\n\xef\xd8\x94\xb9\x85#K\x98}\x17\xc6!E\xe4:\x02\x87\x93?,~\x99$\x11\x0b\xe2zSG\xe0\xe4\xe9\x96!Y\\\x04QF\x7f9\xfa\xb8\x0b:,\xf5\xa5hw}\xc9\xae\x1e5\xc51,8\x02F\x1e\x18vQ\x87h\xd1\xc2\xc5-&\x0c\xa4[+U\xa5\xc8\x9c\x0fX9\xf1:w\x04MF\x87UgR\xb9ht\xa5\x12\xfa\xd2\xd8\xca_\x89\x0e\xd8\xa2\x18%bD\xba\xe6H\x96\x03<\xb3\xa9\x7f\xe4\xf8B\x99b'\xf6d>\xa6%,qM=\xe3\x83\xcc1\x1c\xa8\x88$\\\xbd\xdbrvL\xd9\xf29GZ\x10+Z\xc0\x13\xd8r\x1e\xb4h2\xe1S\xaa\xe1EC\xa6\x879\xa5$n\xc9\x16\x11\xba\x19\xe6\xb7\xedU\xd3A\xca\x87\xafm\xf9\x12\xf8\xbcQ\x08Skp\x05\x13\x98\xab\xf9\xaea\x02W4\xdf%\xcds O\xe0\x8a\xcfs\xe9\xc1\x8c\xd3\xa4\x15\xf4p8\xf3\xe9\xf2\x9c\xf3\x1b^`-\xd4\xb0\xde\x04\x9a.V`\x08+\xbep\x91^\xdeLp\x88r\x97{\xe4\xdd\xb5W\xaf\x8bj\x02gf\xedDL\xc7o.v\xa1\x8f<\x024\x995\xbe<\xba\x04\x86\x88_\xa1-\xea\xc6\x87\x0f2[\x8fdFJ|,\xb7`\xa8\x9d\x17\"CM\xec\xba\x12)\xf1c \x08\xb5%$\x8fp\xdbW\x8e\x1b#vXn\x94P\xbdN\x8e\x93\xc1:\xb8\xf93\xbb\xcd\x94\xee\xae\xde\x18\x86\xc5\xd1m\x04\xfbU\xb5p\xa6\x84 ^`f\xa8\xb8\xc1m\x93T\xd2443\x15\xaa\xdb\xaf\xb0\x9b\x0d\x8e\xb3\xfe\xd1&\xc0r\xbc\xde m\n}D\xe1\xe9\xb9\x8f\xc86$,\x1b\n\x0c\xf3\xf1\x94\x99\x13\x96K\xf1\xff\x05\x9d\xc1\\\xd3\x7f'T\xe8\x86\xb0\xf1\xa6\"\x00\xdf\xd8\x04\xe0\xb3\xaa\x00|c\x11\x80\xcfp\x8c\xb9^tm\xa5\x1c\xbc\x82\x18<:]\xb9\x87\x0f\x10\x1c\xcf\xe0\x08\x07:\x821\x9c\xa8\x9d9+\xc4\xe0\xb3B\x0c>+\xc4\xe03RJ\xd5[\x12\x83\xcf\xa4\x12 G\xc0es\xe8\xf5(\xc2\xda5Y\x9b\xb1\x8f \x86\x91\xe6\xb4\xc7j\x0e\x035CJ\xba\xa2\xcdp\xd9\xaa\xa0\xf2\x8a\xbd\xde\x12\xabn=\xb8\x82'\xe0\xbe\x87 \xdc@\x1f\x96\\B\xa38\xd5\xb7\xba\x04~\xe5\xc3{N\xa2\xc4\x96]a\xf1^\x9bIl\x96\xc4y\x18ow=\xe6\x03\xe1\x0d7\xe4\x00\xf3\x9bo\xc5Ee+\xcc4\xdc\xf8\xf6\xee\xa1\x18'o\x077\x10\x8e\xc0\xe5\xebz\xa5\x86[]\xd6\x1b\x0f\xe3\xa9q\xd2\xf5\xc7\x83\xa1\xc0\x11\xea\xbfR\xf3\xd2T\xf3R\xaby-\x8f,\xd4\xf6\x188H\xa1\xb7\xf4zk\x1cn\xd6\xc4\xe5\x8f}\x90\xb0\xb1\xb6o8oN\xce\x97\xc3\xd3{\x1b\x04\xc1X\xfb^\x9d\x10B\x98\x8c\xf88\x81\xc8\xbd\xf5a\xc3\xdf]\x8b\xe2\xfc\xdd\xa5x'\x8e\xc4W\xeaH\xfc\xd6\xf3 \x98\xde\x9ec(KXMW\x82\x96\xf0\x17\x86\x9bY 4(\xf7\x18\xe5\x98\xdbsO\xbf\xa6\x85r\x06\x1c\xc1\xf1\xf4Xk\xe6\x12\xc6\xb2\x8b\xe9\xb1\x0f\x97\x16\xc5\x8c\xaf\x06\x06\xf5\xea\xf7\x17^\x93\xc1\x8cou\x99\x16\xdeb/D,\xd5.\x12UE\x8c\xa8\xef\xe7\x1f\xec\xbf\x16\nt\xaet\x95\xe5\xc3\x07X\xf2/^\xfd\x93\x0e\xb7\xe5\xdd\xe3;\xb7\x86'\x90\x19v\xce\xfb\xcc}\xe3Hb\xdd9D\x84\xcf\xd9\xa3\ns\x90B\xc5\x1f\xcak\xd69\x93\xc1#K*\x83\xc3\x87#\xaf\xfdtO\xba\x13\xc8\xebpp\x04\x7f\xffH \x0dAB\x8b\x91\xeb\xc7e\x9d2]\xea\x03\xaeF\xd5\x13\x03\x1e\xb6GI\xb4'\x85HE\xa7\xad~p\xa2|\xe2\xb2Z\xfa\xb3\xd6\xc8p\xd69\x8d\x0e-s\xba[M[D\x81\x05\x1f<\xea2U\xc3\x0cJ\xfaT\x7fD:\x94\x12\x16Qt\xfc\xfbG.\xad\x04\xa83\xd9D\x16\xbc\xf01\x0d,\x9a\x10\xe6\xe9\xe3#\x88\x0c\x82L\xec\xce\xf8\x07\xa0\x98\x81>\x84nDA:g6\xbd\x18\x8aU\xcfv[`\xf3\x19\xeb\xfe7{E\xdb\xdf\xc0,I\xde\x87L\x7fs\x9cln\xd3p\xb9\xca\xdd\x99\x07\x07\xc3\xd1A\xff`8\xba\x0b\xaf\x93u\x10\xc3\xd9*\xbf\x8d\xd6A\xdcT\xe1\x1e\x1d\x9e#\x0f\x99\xa3*O\xfcf\xc4\x99H)w\n\xc4\xd3\x0d\x95\xc3?&\xb0u\xe7>d\xed\xa1)M8SI\xe4\x9d\xb14\x0c\xa2\xf0\x17\x93~\\],E\xa0\xc4v\xd7WZ7O}\xf8P\xbdm\x88pY\xa8n\x05d\x86\x16\xc8L0\xa9\x1e\x88\x06\xc3\x0cB\xf2\xfe\xab\xee2\xeep\xd0\x12\xa8R\x81y\x1c\xac\x9b\x1a\x93\x1auX\x8b4A\x07|\x18\x9e\x9b\xfa\xda\xb6\xf6u\x15D-]\xe1uu\xe8\x813q\xa0\x07\xdbz\x8f\xc2R\x06)W\xb5\x9f-\xadW<#(\xca@\xdft\x18\x8b\xc7\xd4\xd9\x8b\xe0\x85\x1b\x99\" \x89\xaa\xd9\n\x831 \x0dxA&\x00\x03\x14g(\x98?\x86\x1f\x83\x9b\xfe\xb3%\xc3\xc1\xff\x18\xe4\xab\xc1\"J\x92\xd4\x8d\x9a\xa87\x1e\x87\x0c\xe6\xc9:\x08\x8d=\xe8o\xb0\xd7\xe4\x15$'(\xfa\x98\x9cUe\x9b\xea\xd3\xe6\xdd\xe0D\xc1\x8d\xb3C\x87?\x047\x9f\xd3\x9b\x90\xc5v\xe8\xf0sf\xd8\xeaF\xd4\x04\xf4j\xbfu\xa8\xaf\xb5\xd4\x81\xffj2k1L\xc9Y\xebF\xca\xba\x1aP?N\xa9\xab\x04\xfb\x8f\xe1\x9b\xfd\xf2k.\x9a\xed\xff4}\xb7\x1d\x0e\x87\x8f\xf8\xbf\x07\xc3>\xff\xef\x01\xe3\xff>\xa4\x1f\x8b\xc5y\xef\xdf\xf6M\xc7c\xdb\xdf\xeax\xac\x1a\x93\xb9\xfc\xd7'I\xf8\x1dC\xaa\x8b\xfek\xcb\xeb2-\x1c\xc4t\xefk\xd7\xfb\xe6|\x7f\xd9\x16\x8b\\\x1eK\xa0\xbbF\xc9\x9e;\xf4J^\x1ae'\x8d\xf2\xec\xdb4H\xbd\xe3n\xb3,\xb9i\xc8\x1c\xf32+\xb2\x92\xc7c\xbb<\x9eV\xcd\xd3\xb1E\xe4N\xd1U\x00\x1d\x07\xee\xdc\x81\x14m\x97\xf7\x0fG\xe8q\x11C\x0fF\xfa\xc9|\x83X^s\x08\xc1\xca\x16\xc1\x9a\x0e*\x9fbW\x07h\x1c\x12n\x1c\\un0\x1c\xcb\xe3\xcf\xd1\xf0\xe0.|C\xde\x1a8v\x0fz\x90\xf0\x1f\xd8^\x8f\x8e\xf2\xed\xe4'\xa7\xebp\x07w\x87ey(\x84}\xb8\x7f\xb7\xf8\xc7\xf3at\xf0\xd0Z\xc6\x83?\xc2\xfd\xbb\xd62\xe5\xcf!\xfeB\x1f\x84^\xa3\x1bg\xa3\xbd\xban\xf25\x9c\xc6Qh\x89\xbb\x0f1B\x04\xcd\xf4\xe0ny\x84i\xf3$S\xc3\x04R\x9a\x00\xe7\x97\xbc\x03\xfeR\xb5?zt`l\xa0^WTH;\xd8\x0d\xda\xd2O\xea\x90\xb2gw\xf3\xe7@\xc3la\xf9\xedF\xb2J\x91\x86\x0b\x96(\\\xa6z\xfe/\xcb\x19\xb2\xc4\x93\x86[d\xa1\xddAs\x9e\xb4`F\x80V!v\xc3f\x8d\xa9\xc5\x94\xb62\x99L h4\x0d\x83\xd2\xcbCx\x02\\\xbao)\x9c\x90S\xcd\xf0\\\x19\xa7\xc2^\xcf\x0c\xc8p\xbd\n#\xa6\x14'>\x14s\xbb\xd2v\xc7\x81N\xf3x\xe9\x8f\xcc\x19r\xfe`\xdfIK\x8a\x00\xd0\x9d\x04\x85v\xbaS\xbb\xc2\xach\xa3\x8eZz\x8d;\"\xbd\xc1\xd4\x99\xfet\xee\x9c\x97\xcd\x07d;\xe0\xa2l\xcd\x9e\xa3\xda\x12\xa4\xbd\xed\x92\xf0\x0ea\x81\xb0\x1a!%\x1bd\xc96\x9d\xd9\"Fx\xbe,\x18\xca\x82\xe48\x98\x0efI<\x0bD\x10Gv\x0d\xaf\xd9\xf2\xe4f\xe3\xa6\"\xe0\xcf\x07\xc7\xab\x99]\xc1H\xba\xd8`\x11\xc6\xf3\xe3U\x90\x9e\xc6sv\xd3fB\x93\x0f\x87\xd1\\\x87\x0f\x85\x89\xfd\x86\xb3\xa22\xceZ.>\x95,i\x89\xeb\xf9\x02E\x0b\xd7\x98X\xa2\x1c\xda\x1c\xdcx\x10\x05YN\xc3\x7f\n\xb9\xf7\xd8\xe38\xd0\xb8]\x86\xfc\xcc\xbeX\x8aoos\xb6\xd3R\xc8\xd9\xf0\xd5\xc0\x1b\xb4\xb4 \xe4\x95\x858\x83\xf5q&\xe6x\x8b\xc4\xc5\x9fu\xbe\x1a*\x17\x87n\xa6\xebc\xa6j\xf6\x0d\xe0\xd2\x0c\x9e\x88\xc6\xc6\xbd\xb3EY.\xe4\x1b\xe5\x98\xc9\x85\x8d\xea\x89\x88\xfe$\xe8t\x84\xfb\xd4\x92~KQ\xc6\x84\xeb\x8c\x94)?\x99\x0e\x8dq6tyg\x97\xd5j\xbd)\xa3?r\\Hc\n\xdc\x92(\xe8#\xb50\xee%\x7f>\xb6\xedA\x8a\x06W\xd9\x8b\xf1^\x0c\xd8D\xbc\x96\xa5$\xa9\xf2\xc9\x84\xbcA\x92B\xb4+\xcd\x89\x8f\x15}?\x87\x9e\xafdN\xe95\xca<\xa7\xd0=\xa8\x07\xee\xa2Q\xe0\x10\xde$\x9c\xf4\xbdJ\xc2\xb8\xc5\xe6!\x9f.\xb6\x0f\\\xdb\x99lW\xae\xb1\xc6=DjIU\xc4\x13\xd6\x12\xa1~j\xef\x1b\xa7o\xe1\xfajBo\x84\x85\xe8\x8bM\xac?\xb9\xcf\xd7\xf2\xf9w\xdf\x9d\x1b_\xeek\xbb\xfeQ\x1c\x16t=\x13\xf8\xba\xdf\xef\xbf\x8b1\x00\x96\xb3\xca\xf3M6\xde\xdf\xdf\xb0\x1c\xf3\xdd\x0f\xb2\xeb`\xb9d\xe9 L\xf6\xaf\x0e\xf6\xe5\xaf\x9f\xb3$v\xde\xc5\xf3d}\x11\xce\xc7\xe0|%>\xf4\xb7\xa1\xf3\x8e\x0e\xc1\x82\xd2>\xab\xa60\xf2\xc15-\x07\xf4a\xe6\xc1>$\x1dg\xa5?ie{\xb4\xa3\xc0\x0cz\x10\xc17d\xee\x1d\xdc\x83#8\xc08\x0e\xdf`$&\xfe\xbf{\x17\xfa\xf4\xd2C\x95\xd2\xa6\xe0\xd8\x9e\x02Py\x17#\x0e\xac\x08\\\xdf3t\xef\xf5\xf0\x00\xf2 \x10`\x0f\x88L\xd37.\xb1\xa0\x0b\x90\xbe\xd2\x81\x0f\x8f\x1eiPo\xc7\xce\xea\xf3\xd1\x87G\x1d\x8b\x7ft\x9b\xcb\xd9/%5\x90\x84h\x07S\x85|2wK\xf1\x9e\x8dG4\xf2\xb1\x84\xb4\x93\x8c\xc8N\xa4X\xbe\xdd\x8c\xbb[\xbb\xa1h\xd4\x1571\x91*y\xeap\x8c\x8fU|B\x87\xe6\xdcS\xc6\x9d\xdck\x8a\x1d)\x1f\xe1`\xf4|\x9b\x8a\x00\x90q;\xb8\xb3\xf9\x92\xbd\\,2\x96\x9bBz\xeb\xcf'\xed[\x9e\x8c\xc1\x92\xab\x80>\xff\xd7\xb8\x89\xd6\x85q\x9e\xfc%d\xd7\xe5u6]\x9c\xad>\x92Wc\x9c\xf0o\x93m<\x0f\xe3\xe5q\x14\xb28\x7f\xcdf\xb9\xeb\x0dV\x88'\xed+\x14H\x8a\xae\xf8Z\x0f\xc2\xf6j3YM\xe2j{\x95\xc5N\xbcc\xc3Q\x02zm\xa1n0\x05\xf2\x13Xp\x88\n\x91^<\x85\x19\x1cQ\xbc\x01Z\xc91\x04\xe2\xc3\x06\x8e s\x03N/\xf9\x9b\xa2\x00\xb1\xd2\x06\xccn\x80\x81\x19\x8bs\x96\xd6\xb60\xed\xb0\x8b\x99\xdb$]\x94I\xe1>\x1c@\x8f\xa3\x0b\xc7\xaa\x96]\xe7\x85=OL\xefS\xe6\x94\xe5\xc9f\x0c\x81\xbd\xc0:\xb9\n\xe3e\xc7\x0c\xfcP\xd0\x86\xbd\xbd\xfa!\x90|\x1a\xc6\xc3\x81f,\x80\xa7\xb1\x14.\xdfX[Jca\x833N\xbdUN\xb3\xa4\x14?\x90\x7f\x9cDl]s \x04\xc1G[\x17C,\x82\xd0E\x88\x9f\xfd\x17\x1a\x91\xc5\x8f7\xc9\xa6\xcb\xd0\xd0j\xef\x9a\xfb\xa0x\xd7j\xe0\xd4n\x18/\xc5\xc8yo\xea#/k^N\xa4\\\xddd\xe5\xd2l\xde$\x1c\x92wL]\x81\x9bkIN\xa9P\xa0#\xac\x95\x978\x8cc\x96\n\x89\x01\x97y\x86\xc8Bov\x1c\xa3\x00\xadn\x8b\"\xf5T+\xa2\xe6\xc9\x86\x93 \x14\xde\xe2A\x82,\xca\xb4\xfb`\x06W\x83\xb75\x06%\x0drv\x86\x1bQ\x8b\xeah\xa3G\xd2N\xd5\x08N\x96D2e(i \xcb\xaf \x9c\x03\xef\x8ek\xff_\xbb\xed>k@'h\xec\xe8S`M\xc9\xe7\xac\x04^~' \xdc\x15S>\x0d\nw\x86/\x01/\x7f\xa8\xbct\x82\xf9\xfc\xe4\x8a\xc5\xf9\x0fa\x96\xb3Xd\x0c*L.{b\xcaq\xf2\xff\xb2\x98\xcc/\xf8\x9a\xb9%\x9ac\xbc'&E\x1ag\x15fy\x92\xdeV\xad9\x9bm\xb6:\xcb\x83\x9c\xcc<\xa2\x90y\x9d\xb8L\x13\x92 \x08\xe1\xe05\xe3\x85Qj\xd4+\xd7%\x0b\xcaT*>\x0fj\x95\xf9\xe8\x82m\x9e8\x9e\xda\xdc\xea\x82\xb8N\x94\x04s\xc7o\x87 \xeakWE\xb1ql\xeb \xde\x06\x91%\x86=Wq\x1a\x86\xbdI6\x19\xaen\x9b\xe7\xb5|\x18\x86\xe8&K\xdc/,\x16\xdc\x8cRH\x15\x9f\x12T\xf1\xc4\x8bAQ\xce\x06\xf7\xb0\x87\x97\xf3\xc40e\xb0\xf7\xc1*\xc8\x10\x92v].iUL\x06\xa8\xd0\xb8\xde\xa0\xd0\x08\x9aO\x0dZ\xedC\xd2h\xa7 {\xc9\xa4x\xf0\xed\xed\xe9\xdc\xadM!e\x0b\x99\xc1\xef+\xc7\x9b\x8e\x9a\xf2\x05\x83t\x8ek\x1b\x05\xd4\x0c\x05$L&\x850\x99s\x1e\xc3:\x88\xdc \xe4\x98D\x08\xe9\x9c5\xb5+\xf4Cx2\x81\x14\xc8 \x1d\xd0\xff\xdc \x124\xa8\xa8\xd0\xac}\xd9\xa1\xd9D\xb6\xf6L\xae\xebW2\x8aO\xe1\x86\xe5\xb8?}x\xf7.\xf34J\xe5\xbe{\x97}\xf87\xcf\xe4\xc2i\xc5\x9aY\x14\xce\xdewB\x99\xd2\xb1!\x1b\xe4A\xbad\xf9c:\x89q\x9e9\"\xd8L\x1e,_\x04k\xf6\xd8\x13G\x9f\x9b eq\xfe\"\x997$\n\xdfs\xf7\x90\xb1\x8c(\xe0\xd7\xe0z\x15\xceV\xa4&`\x1a\xc8?\xb3[\xfa\xb5fy\xa0~\xcc\xf24R?\x82\x88\x97j\x8c\xfd\x82\x16\xc86h\x94\x90\xa8\xa8\x94\xa2\x10\xf5\x08d\xe52G\x95\xdf\xe3\x9a\x91\xbc\xfa\xc4\x1a5\xd1\x80\xb6\xb9R{\xca?\xd0\x88\xac\xb8\x96\x82\\\xc7\x8d\xeb\xe7k\xd5\xa7\x94\x02pW\x90\x06\xdd\xc5\x0b\xb3\x18\xe4y\x1a^ns\xe6:\x9cv8\"\x85A3\xd9\x12\xc6\xfe\xe2\xce\xf6W\x0e\xf9\xb7n\xc9C:\x1f\xcc\xa2 \xcb8\x90\xb5\x86\xfa\x91\x06\xdf\x06\xb7w\xf9D\x0d\x840-\xdcZ\xdcQ\x9b\x89\x10\x8fW\xber\xc4\xd1j\x87\xbdB\x0c\x88\xe4\xd1J;\xb9\xca$\xac\x10q\x8c>\x95.\x01egJ\x19'\x08\xcf\xc94\xd5\x06}W\xe2\xcac'\xd6\xa5?\x15^\x02\x93\x16c\x164\xab\xd3\xf2Y\xec\xcc\x19\xa9\x16]\xff,3\x9c\x0c\xfa\xb0@/\xeb;\"x\xd9N\xb3\x94(\xa7\xa4<\xf7\xef\\\xdet\x8c>^\xfa\xf3\x11C\xbb\xa2\x94\x91\xf9\"\x83\xf4\xac\xc1\xe8af'\x16V\xf2\x07{!\xe9\x07\xa7^~t\xcb\xdea\x18\x9e\xd1\x18J-\xc5[\xad\xc1f\x13\xdd\x92\xa7 \x8c9\xac\x7f\xf8\x00\xae~\xa2\x1c\x9a\x0f\xa0;\xdd\xc9\x13\xc1\x1b\xe9\x94\xb2\xc8\xc9\xe7\x83sq\xc1\xb2\x1f\x93\xf96\xe2\x92^y_0}\xdbX\xcf\xc8\xa0\xeb\x99\x926m\xdc\xd8\xbd\xeb\x19\x02\xa8\xf0\x0f\x07\xd5\x0f\xa1\xf8pX\xfd\x10\x88\x0f\xf7\xaa\x1f\xb6\xe2\xc3\xfd\xea\x07L\xf6\xe0\x0e+o#,^MJ\x85'G\xbc\x15\x94&\xf1\x0f\xb2\x88\xb9\x87\x0f\x1fT\x1b^P\x94\x17\xcft1\xd3\x90\xf4Y?\x83f\x83b=E\x9c\xd5:\xac\xcb\x9b\xb1-\x97/A,2E\xbdX\xb1h\xc3\xd2l\x90lN\xe7\xe5\xe1\xb6;\x02\xaa\xd1\x0b\x7f:\x0b\xfe\x91\x9c(F\xe7\x89Lj6\xcf:\xa9\x9e\xf1JA\xb5\x92\x9b\x0f..0\xfd\xd9\x05\xc5\\\x1b\xfa\x18\x19R\x16\xf2<\x91#\x11K\x93{g\xe3\xc1D8\xc8\x93\xe52bg\xab\xe4:\xeeJK\xa4\xb0\x1f\x0e6i\xb2i9c\xcc\x85\xd3\xeem\xb2\xcd\x9fa\xdb-\x15b!\xb7-\x9b\x8b\x91\x97\x1cG8$\xd5\xd5\xcd\xab>\xc25;\xc3\x896\x17E\xad\x96s\xae\xd7,K\xa2+6?\xdb^\xe6)k<\x0f\xc53P\xcd?'@;\xf9@$\xc6\xa95\x84!KV\xc9\xb5;u\xd4\x0c2\x87\xec\xd9\xe7>\xec\xd9\x9c\x9a)u\xcfq\x10\xcfXt\xccE\xe2\xae[\x869j\x04\xbdo\xde\xae\xf4\xf64\x7f\xb9\xcdO\xe2\xe02b\xf31\xec\x85B\xa7\xac|\xb1\xb6b\xc8H\x03\xc5\xd8\xdf\xa4\x1c\x10v\x1a\xfb'\x80[\xb6a\xb3\x1d\x80m\x13\x98b\x8a\xea\x0fA\x1be,j\x10\x0c\x7f\xcbU\xe60\x84.\x1b\x7f!\xbf$F\xc9\xc11\x87ejs\xab\xa3M8\xb9a\xb3m\xde)q\"\xec2-F\xed\x9e\xc6\xaf\xd2d\x99\xb2,\x1b7&\xf2n\x18c\x1d\xfb\xba\x0e\xf6\x13\xa1\xe5\x8cEl\x96'\xe9\xaf\x00/]\x08\x13\x1f\xc2\xab _\xd9aK\xdd\x07\xc0\xac\xf6\x1b6\xab\x12\x15.\x9b\xfd\xe9\xcc\xf5\xe8\x12\xb1\xa9\xc4\xd4\xe1\x03Wt\xa6a\xf9\xcdt\xebW\xde\x82_\x0da\x7f\x85\x0d\xb0\x10\xf6\xf2\x1eX\nu\xdf\x06R\xd1\x9b\xb2\x00\xd6 \xc9\xc8>[\x13zZr\x8a\xfb\xa6;\x97\xb57\xca\x11\xc1\x87\xad&\x85\xf8\xc2\x07\x81OA\x7f;5\xcf\xe3=\xbb\x1d\x83\xb3\x0e6Hb\xde$\\\x8c\xce\x1c\xf34\x84\xe8\xdc\xd9]B\x1aJ\xf2A\xb2i\x07\x98\\\xc8)\x1d\x89A\"\xc4\xb4\x9c\xdc\x1d\xe3E\xb8\xcc\xbc\xb63w\n&?Of'7\x9b \xce\xc2\xa4\x834\xc2\x85G\xb6\xf9!\x8c\xdf\x87q\x8bX\xb4\xa5\xe2a\xb6\x89\x82\xdb\x97]\xa5\xa3L\xaf%R\xd9I\xff\x8f\xe6\x9a\x11\xa9\xb6\xdb\x0d\xd7\xa6\x10\xc6\xd7a\xfe#\xa2]\xcb\xeaa'OO\x16\x83\x1f\x83M\xab\xd2\xfe\xb3\xd0\xf4\x17x\x13\xfcOg^\x0b\x8b\x03T4\xc6p\xda\xdc,\x7f\xf2`\xd9\xe9\x86\x05\xa7\xdfV\xef]\xfd\xc9\xa4\xee\x91[\x14-\xfa.\xf4,\xc7\xc2\xdd\xf4g\xce6)\x9b\x059\x17\xf1OI\xf3-^9B]3\xf6\xa5\x15\xa3\xee\x9a\xccS\xf2!\x0e4\x86\xa4\xbdh\xa1\xa7t\xb8JQ\xd6UZTi\xa8\xaa\x8a-j\x19\x96\xaf\xdb \xc4\x82u\xb7X\xb4\xf7R\xd2/;\\\xf0SzU\x8b.\ne\x15\xaaE\xf6\x80\xbaN\xd9B\xf2AW\x81Z\xf4O\xb0\xe8\xc6-\xda(4\xe8\xc7-B\x12X\xd5\xfd\x16\xce\x0ff\x89\x96\x04b<\xd2\xa9}mo\xb0f\xd6\xd5\x9a\xebzB\x04P\xf7_\xd7\x1fa-\x89\xa4\x89V\xb8\xb5\x0b\x8f\"\xf7\xc7\xb6\xabb\n\x9c\xc7\xf0s\xf3\x8c\nm\xba\xcdh\xdf\x11<\xba\x82\xb4v\xb6-\x96P{\xd3\\\xb5tR)*\x97\xde\xb5U\xd7\x0eiUu\xed][uqD\xa7\xaa\x8a\xdf\xcd\xd5\xa4<5\x86\xcb\xf6\x82\x82\x95\x8f\xe1\xba\xbd\xac\xe2\xe3c\xb8h\x19y!$\x8c\xe1e{Y\xad\xe5W\xcd\xa5K\xf2\xd0\x18\x8e\xbb\x94\xd6Z?k.\xaf Och\xd9\x9d\x92\xe44\x86g\xcd\xa5u\xc1r\x0c'\x1d\n\xa3T9\x86\x9b\xe6\xa2\x8bx\x0co\xac%l\x87\xab\xb5\xb7\x1f\xcf=\xbfrO\xe4\xa3\x9b\x0d^mSfJ1\xb9\x92\xe4\x02-\x1d\xb5\xb3\xa9\x12s\xda\xab84\x16t\x00\xdd\xc7J\xdf*\xbc\xa4Z\xd5\xc4\x0c\xaa\xb2\x84\x8d\xf2k\xc6\x05\xcc\x15#&\x00\x13\xa0\\\x14\xbf7\xc7\xaf\xc8\xe6\xf8\x15\xd9\x1c\xbf\"\x9b\xe3Wds\xfc\x8al\x8e_\xfc\xc3Pw\x1a\x8a\xc8\xb9\xcb\x92k\xfa\xb7\xf6\xd9\x9a5\xfadi\xfeX&k\x8cv\\ip\xc7\xf2?\xd9\xe5Jx\x18bq\x992\xa7\x9a\xd6\xc8\xe8\xd4\xf8\x19\x07\xa7d\xa0Z\xb2\xfc\x07$t\x06)\xbe\xab}j\x17\xdbT\xbe\x83\xaa\x1c\x9b\x14\xdf\xc1l\x9b\xa6\\\xbch\x10t\xd1>\xe9\xc6\x98T\xbc\xd1y\x0d\xef\xe8\xb6\xceO\xab\x90Yd\x1dg5r\xa4O\xeb\xd7\xf0\"\x11\xdc\x03D\xf0\x19\xbcS\xe0|\x8d\xe7\xf5_;\xf0ug\xd2Z\x86\x00\x93@\xd5bg\xfc\xa4=T@a\xb3\xe6\xb6\xac\x06\xa3\xa50\\\xfb(\xcf\xa7\xcc88\xd3\x90\xed\x99\x18\x87Nwg>\xccj|\x84Z\xff\x171\x16\xcf\xfftb\x8c \x8b(\x15\xfa\xd5|a\xb0\x8b\xd3\xac\xba\xf0\xc3WL\x91_\x15_?\x82 \xe5 u3\x8fr\xe8\x0f\x1f\xc3\x0c\x9e@\xf6\x18f\xbd\x9e\x07\xd1tv\xae\xd7\x9c\xce\x0ca\x01\xc5R\xc6x\xe1\xd1\xe6\x9c\x8b\x18\xd8\xca-fA\x14 \x96\xc1|\x98\xf2\xba\xe72\xf4b\x84IZ\xc3\xc1,J\xb2N\xeeV\xc2\xc5J\xb7\xfd\xa11\xfc9G\x85\x10\x7f\xbbU\xffz 4\xc3\x8bZ5\xa6\xc77\xe3\xb7\xe0\\_\x96\xe4ub[\x1d\x0d\x9eqwcj\xba\x03;\xa4\xd3\x15\x96\xa6\x1d\x86\x10\xeeb\xf1\x0e\x84\xf1t\xf0\xec\xec\x8d\xbd\x14\xdfm\xed\x04-\x90)m\x1b\xcc`\x98\x0e\x15\xa1)\xd6\xc1\xa9\x81sS\x8aT\x87\xaf]f\xcb\xd0\xd0\xc6\x8a\xe7\xe1U\x8dT\xeb\x8f\xbaV5\x06g\x1e\x06Q\xb2\xecoo\xacWq\xbfH7\x97\xc1\xec\xfd\x1f\xea\xe57Z<9\xa5>^\xcf\xff\x8d\xfaZ\xb1`\xfe)\x9d\xad\x0e\x95\x1c\xe8<\xbb\n\xc2(\xb8\x8c\x18\xea\xfbI\x1a\xfe\"\\\xb8\x9a6\xfbr\x9b\xe7h\xe0\xb5\x0f8\xbf\xdd P\x89\x92\x9d&\x86\xfc\xa0\x8f\xd3k\xa8\x91\xc4\xba\xb9 \xeb\xec\xbc\x02\xd9\xd5\xb2q\xf4\xd7\xe1<_\x8d\xc19\x186\x0cd%\xa2;\xf0R;\x8f`\x9b\xd5e5\xfdY\xa5l1\x06\xe7+\x9c_\xc3 n\xa20~\xff}\xa9\xb0\x05y\x91\xe9~Y\x00\x9c%q\xce\xe2\xdc:\xfbh\x80|\xee\x8c\xfd\xcd\xf5\x06\xeb`S\xcaI\xdex\xfd\xb7\x85~\xce\xda\xcc\xb6\xc8~[\x0e?\x9e\x9d\xbdi=\xf0\x98\x17,\xc1\x1a\xb7D>e\x13X\xcb\x19\x96\xce\"[\x0f\x81*\xa6\xb8\x96\x93\xdb\x92\x91\xaf\xc5\x00\\1{\xd6\xdd\xa1\xe5c\xb3\xb4y\xf8\xd4\xbe}9%\n\xdf\xfeK_\x12\xcf\xbf\xf4\xa5\xff\xc5\xfa\x92\xe0|]4\xa6\xce\x97S\xf2\xeez@\\\xd7/\x06\x1a}|\x93\xa8\x83g\x9bI&\xafim\xe6\xd4\x15\xffR\xda\xccO,\x80\xac\xac\x8dy\xa4\x8b(\xd9\xedU\xb2\xd9n\x1c4,6+u{{\xbb)>\x89\xa8\x13\x14\xee\xce\xde \x0b\x7f\xb1D\x13\xf9\x92:\x10\xef\xb2\x7f\x9d\x06\x9b\xcd\xa7\x08\xbc\x1d\xe4U\xad\xb3\x04\x8e\xc0\xb9\xccc%\x113\x88\x92\xd9{6w`\\\xfd\xb0\x8d\xc5\xa7\xae\xf2\xaa\xf8\xb5\xf3\x14\xb2M\x10kR\xbb\x1c@\xa3\x98\xfe\xcf\"\xe5\xe2\x82\x7f\xa5\xad\xf1W\x1d\x96U\x13|\x1b\xea\x9bG\x8c\xf4\x14\xddkm#\x8f\x85u\xf8_\x92\x0d\xfcK\xb2\x81\x7fI6\xbf\xbddc\xbd7\xc0\x06Y\x9el8\xd4\x07\xcb\x80\xf8\xb0\x99\xff\xc8\xcb\x05\xd2z,:\xb1\x88&\xe8lop\xa9\xff\x9f(\x8e\x94\x1c\xd5?\x8dy\xef\xc6R9\n\x96\x85\x94\x8b\x0b\xceH5\x9am\xf8\xda\x81\x0b8A\x1a\x06\xfd(\xb8d\x91c\xea\x06h\x9c\xd6\x8e\xe4\xf7\x0e]}!>\xfeO\xc2\x93\xd9g\xf2\xe4\x86\xfa\xe6\x11\xff/\xb4\"\xcc8K\xad\xf1\xd4D|\xa9q\xe1PV11\xdb\x99\x89\x0bo\xc5\x87\x1a\x17\xce\xc4\x87\x1a\x17\x8e\xc4\x87\x12\x17\x9e\xc9\xc8G3\x11\xf9\xc8\xc4\x8fg\xbf=?^t\xe5\xc7\xb6\xb0EU*l\xe5\xb9W\"\xafz\x95\x98[}g\x92:\x0fl W$\x16+\x18$1\xa7\xcd\xc7\xab ^\xb6g0\x02\x8d\xcf\xb1A\x1c\xac-\xbaXP\\[\xab\xb0\xe8\xbf\x7fDL`&\xf4\xe3\xfc.\xc3\xbb\xee|H\x9d\x06S\x0fb\xc7\x1b\xa9\x1f\xdf*\x15\xca\x0d\xc8\xe3\xd7\xd2}\x94,M\x91tv\xe8\xbfY8\x08\xda\x14t\x8a\xab\xd0\xc9@B\xc1\x154\x93H\xcd\xe6\xdd\x1a\x80U@\x819\xa25 \x1d\x19\xe4 \xc9w\x96\x99\xc5b\xcd\\s:\xd3\xa0~\xec\xbe\xc3b\x9a7\xb3\xe3Y|P\x84\xfa\xe0\xbf,8\x0ee\xd9)3\xcaN\xc1?@vj6\xe2t1\xf6\xc4U\x00i\x83\xa5\xee\x87\xeeyW\x1bR\x88\x85\xbb\x9d\xd0\x07t\xd2\xcd\x91\xff4g\xeb\xa6\xabH[*Jy\xe0\xda\x8cO\x19\x15\xfe\x96d\xc8\x96\xa3\xf6\xa4do\xb2\x97\xa5\xc0\x19\x8b0\xcaY\xfaIH\xb7\xb77\xc3k?\x96(\xea\x80\xd8g\xef\x7fc\xee\xbfc\xe7r\xe5D\xd4]\xbc~\x94\xdfnXC\x8c\xd8\xa6\xc1\xcc\xbf\xcc`&;\x0c\xa6Q\x8f\xb0\xdd\xbf\xd8\xdd\x088K\xe2<\x08\x9b\x0e\xd9\xf7\xf66h\x95\xe4b\x87\xb5\xdfE\x92\xae\x1b;Nb\x8a\xf2\"o\xa5(6h\xebvS\xa6\xf6mI\x97Z\x16&\xe8t\xc2\xd9v\xba7[\xb1u\xd0z`\x18\xe3\xf2\xb6\xb4\xb5\xd3\xe9\xa6.\xc3\x8c\x81\x95d\x9a\xe6\x9a\x81vy\xad\xe5\xdeK\xf9\x08\xf5\x13\x8e.\x0bN\xea\x7fA\x00\xbd\xcc\xe3VK\xb5\x00P\x8e^\x0b\xfa\xf3\xc8:\x82\xack\xef\\e\xa6\xa3yi\xa3\xee\xac\xcdjR\x96m\xc8\xce\x0fX\xc6\xf1`\xfciC\x15\x1e!\x84H\x1d=B\xeaS*\x00\xc4\xba\xb8e\xeb\xf8'\x8d\xb5e\x0c|\x8b\xe7I\xdc\xe4\x97\xb1\x83\x97\x8as\x8cn\x1bh\n\x9bs\xa25o\x03 \x01\x94t\x18\xf0E 7\x9b%\x1b\xd6\x9f\xb3E\x83/\x87\xa5\x9bMq,q\xc6[\xc9 H\x19l36\x87<\x81e\x1a\xc49\x041\x04\x9bM\x14\x8a\x80\xd3\xf3p\xb1`)\x8bs\x88\xd8\x15\x8b2H\x16\x10\xccf,\xcbx\x95y\x90\x07\x90\xc4p\xc9VA\xb4\xe0\xdf\xf2\x15\x03\x16\xcfy\xa3\xe9\x00N\x82\xd9\n\x9e\xbd:\x85up\x0bs6\x8bx\x7fI\xcc Ia\x9d\xa4\x0cp2\xd9\xa0i\xf7\xf5Q\xf3\xa6R\xf6\xb7m\x98\xb2\x0c\xbbZ$Q\x94\\\x87\xf1R\xb6\x04Dg\x80b\xe1'1\xcb\xe06\xd9\xc25\x9f\x9a\x9ac\x9e\xc0\x19\xa5\xd1\x85\xb7\xa7\x03\x07\xe3\x03\xef\xc6\x81?\x8d\xfb~\xac\xbb\xd64J<\x9f\xcb\x91A2\x9f\x06%\xc5\xbe\xf0\xdb\xb6\xa6w`\x00\x92\xbd\xb5\x05\x8dA\x10oR\xa9\xda\x19\x04\xa7z\x9ft] \xeal\xa3\xa2\xe4b\xbf7\x1b\xd5\xef\xf2<\xc8\xa7?,\x96\xa8\x7f\xb6\x93\xa1\xffy\x17\xb6\xbe\xa8\xda\xdd\xa6T\x8b\xd0\xaaH\x0b\x9aUo2\x905\xeb\xdc\xbb9\xbaw\x93kC\xe5\xe3\xd1\x16\x1a(\xd8\xc1}^h\xdc\xc1&\xfc3\xbb\xe5\xc3hR\xa4#*|\x19d\xe1\xac\xad\xecL9\xd17+\xdb\xb9\xce\x9a\xcc\xda_v\x1db\x06\x93E\x13C\x9a\x05\x19\x031\x0fgl-\x06bh\xb6\x83\x8dV\xce\x02\x1d\xb5&\xe8\xae9AW\xed j\xfaJ\x87\xc8\x1c:+\xec\x10\xf9c'\x0d\x0dHF\x15\x1a\x9a=\x8d&4\xe8\xf6\xf2\xb9LY`9V\x05\xb5\xbf\x08z\x9f\xb1\xbd\xd1\xbf\xb6\xf7\xf7\xb9\xbd\x92U~\xf2\xcev\x928A\xedn\xf3\\|p\xde\xc6\xef\xe3\xe4:Vas4'nTB\xc1\xf1a\xd1\xf5v+t8\x0bo\x1b?\x8d\x1bz\xe0\xf4\x7f\xde\xae7V\x15\xcb\x90h\xe6\x7f\xf8 \xe8\xefR\xba\xfc\x97L\xf9\xbfD\xa6\xe4\x82V\xd2@HU\x1c\x00\xd7A;E\x93\xd0\x14\x17e\xd7,\xcb\x82%k*\x9d\x16\xa5\xb3d\x9b\xce\xac\x02\xd4\xe7\x92\x1e\xdd\xc6\x83\xb3\xb5\x85m\x05\xcc\xd3}\x1b1\x13\xe4\xea\xcfe0{\xbfL\x93m\xd4)\xd5\xe7\xfbm\x80\x1e\xf5\x07\x97\xe7\x1f\x16\x98\xbay\xa7\xa1t#\xaa\xc9\x95\x16t\x7f\xea;w\x8a\xd4\x10\x9c\xe0\xe14\x1c[z\x9c\xfa\x92\xdbX\xd8\xef\"\x94w\x1b\xdc\x83.(u0\xb2\x81\x12\x95\xba\x99\xc4@\x19\xe6\xda\xf7.\xc44\x8d\xcei\xbc\xd9\xe6m1v\x03*\xfb:\xb9n+\xb9\xa5\x92\xc7I\xa3\xb0\x08*\xff$\x1e\x19\x9fp\xc1\xac\xad\xfc\x8c\xca\xff\x18\xa4\xef\xe7\xc9ukX`\xcaB\xe9\xfc C\x9d\xbe\n\xf2U\x9bO\x0e\x08\x17\x96\\\x04W\x12\xa4\xa9\xb9\xc2\x1c Y\x10E8\x85\xcc\xf5v;\xf0\x92\x8fdo$\x11\xf3%9\x9d;\x1e\x9e\x7f}\xba\xe9\xa2\xdb9W\xcb\x19\xea\xean{\x99Y2g\xaaT\xa2\xe2\x04\xbb\x0e\x07B<\x07t\xfe\xff\xff\x0f\\2pz\x8e\xbd\xa5E\x9b\x11\x84\xa2#OU\x16\x19\xcd\xe7\xce\xf1!9\xb7V\xc6\xb4\xb6\x9bF\x87\x98\xd5}\xc3\xf5\xb2y\xd3\x19j\xd0\xb62\xad\xb7\xf4I\xf7\x19\xcb\xf5\x9a\xb3l\x96\x86\x9b\x1c\xa3^7\xcf\xe5\x93\xc7\xa4\x1f\xfc\n\xbd\xa8\xeb\xd6\x96w\xf5\x8b\x8d\xe24\xde}\x0ca\xfc\xd9#\xa0;\x13j\x14\x88\xeec\x07\xc1\xa4\xc1\xf1\xa04\x18\x07\xbe\xc1\x07\x1a\x9dB\xb6mC \xdb\xc0Dx\x8ep\xe5\xabE\xcd*L\x9e\xf2\x92\x06\xfel\x82%\xcf\x87yS\x98\x8a\xae\xde\x83\x9f\xe4g\"\x1fT\xcd[\x0f\xb2\xa1\xfd\xe4\x1d\xc0\xea\xefD\x9f:\x0b\x1a\xa6\x80\xa9\xa6\xc3\xec\xf2\x907m\x97\xd3u\xc1\xa2N\xbbK\xbb\xa67e\xdd\x85+\x91\xfa\x8e\x15\x97\xbcZN\xe3\xc8[6\x0f\xd2%\xcbi\xe3\xede\xe5\xdd\xb7\x8a\xbf<#\x91\xbcmg\x85\xc0ega6\xf6\xc5\no\xfd\x10\xd3L\x87\xadz\xfc\xbf|\n\x8a\xe7\x93\xac\xbe\xffd>\x05\xb0\x9bN\xde\xe9f)\x88\x9e\x7f\x83\xc4\xdc\x0b*\x186\x8cb\xdb%|\x05\xdf\xd1m\xab\xde\x11a\xa9f\x9d`&\xf3a\x0b\xc1w\xb0\xcdXj\xbfP#v\xbfK\xf6RR\xce\x1b4o\xa9\x9c7\xccS*\xe7p\xd4Bs\xe4\xa8m\x8a<\x7f>r\xf0\xb4\x9a\x19\x7f\xeb\x94\xa8\xffp=\xbf\x8bc\x06\x94\\HZ\x95\x0e\xbaM,\xf5\xfcX\xd3\xf39\xda\xd8\xd6\xbe\xbe\xf0\xffK\xb5\xfdv\xed}\x978\x93\xf0;\xd0\xf6\xa3O\xd3\xf6wS\xdf\x17\xbb\x99\x08\x0c\xda\xbe\"z\xedj\x7f\xf2\xab\xaa\xfduc\xa3\xfetP\xfb[N\xccH#\xb1GH,\xd4~\xe7\xdb \x0bg\xe5\xe8\x88\x8e\xbdj\xab\xce\xdb\xac\xc3\xa7]tx\xfb\xb0\xad:\xbc\xadJ\xd0\xb6\x14\xad6\x89O\xd7\xe1?yLU\xdd\xf5\xad\xe4yR}\xb5V\xac\xa8\xaf\x8e\x0f\x1b\xfc\x9f\xeb\xaf\x0d~e\xcd\xc3\xf9\x82\xfa\xabpC\x9f#q\xa7?[j\x10\xafw$\xde\xfe*\xfa\xf1\x17\xdb\xa8WA\x96]'\xe9|\xe7\x8d\xd2\xed\x0c\xbf\xde>\xed\xbe\xfa\xc16O8g\x8bX\xcew!f\xd7\xfd\x8d\x98c\xb7}\xebXZ@P\xc7\xd2\x9f\xb6\xcb_\xc4\n\xf2Y\xde{\xff$V\x10\xd3\x11yy\xc8\x8b\xdf\xbf\x15$\xd5\xac \xf6R \xda\xf7;\x18I\xd2\x16\x99\x8d\x1c\x9b)\xb5\x176gf\xe0\xc14<\xe7\xb2\x85\xaf\x9b@\x9a\xe4V\x94q\x03\xf3n\xa2\xe5\x84Y\xa3\x0b\x94w\xf5\x9f\xc9\xc7aa\x8d\x1b\xb2\xb0\xf98,l>\x0e\x0b\x9b\x8f\xc3\xc2\xe6\xe3\xb0\xb0\xf98,\xc8\xb2R\xfe\xc0\x05Yw!M,\xfc\x8fGw\x1fxf#\xcb\xe2\xb77\xb2l\xbe\xa4\x91\xe5\xf7\xe6\xf80\xff]:>\x04\x9d\x14\xee\x85*\xd9A\xc3\xe3\xbb8\xe3 B\x17\xf8\xb3\x06\xc5\x07\xa3\x98\x0c\x8a\x04d\xae\xd0\xc8\xed5\xae`Bb\xf7\x86$\\%j\xb5f\x16]Wj\xce\xa2\x90\xc5\xf9\xa9H&\xba\x1a\xc8\xdfm\xed,\x8d\xed\x9c\xb1Y\xca\xf2r[\xf4\xae\xad\xbd\xdbJ{R\xacx\x8379\xb0\xb6\xc8Q\xd8\xbfL\xe6\xb7\xceg\xbb\xa7\x04\x9b\x0d\x9d\xb5\xad\x06\xe2O\xfb\xe0\xbe\x84+\x0b]\xdb\x1c\xc3\xf4\xbc\x01\x14\xc5\xe27\xa6\xdb\xd4W\xb51\xb9favkH\xea(\xd7y\xdc\xb8;\xfan\x8c\xe1\xd6X\xee\x1f\xe0\x8e\xf3\xab\x18\x9b\x9a%\xbd\xaeaU@\x85Vi\xa3?\x00\xbbEV\x81]\xa3\xab\xc0\x8e\x11V@\xb0\xe1\xbc\x83\xcdkKS\xec\x96/\x05\x8a0+\x9d\x8c^\"\xa9I\x07\xa3\xd7\x82Jv0zm\xba\x86y\x01\xe9J\xb2\x83\x85lE\xe5w\xb3\x90]Q\xa5\xae\x16\xb25\x9e\x1b\x84\xd9\xcbgg\x87\xcd%9\x89^\xbb^-\xfe\xe01\xd7c1\xea ^o\xc7\x9f\xcd-\xdd\x16-\x11\xf59N\xd9\x9c\xc5y\x18D\x19\xb5T\\\xa4oi\xea\xff\xb2\xf7\xef\xebm\x1b\xc9\xa28\xfa\xffz\x8a\x12fN\x06\x1c\x93\xb0(\xdf\x99(>\x89-\xef8c\xc7\xde\x96\x9d\xcc\xda\x1ao} \xd0$\x11\x83\x00\x02\x80\x944\x89\xdfe?\xcbz\xb2\xdf\xd7\xd5\xdd\xb8\xf6\x0d\x94l\xcb\x19c\xd6r(\xa0\x80\xbeUW\xd7\xbd\xe6\x98\x04\x06I\xfc\"6/\xeci\x0d\x8eu*I\xc8\xe2\xf9\xd9\x91\xc0\x9f\x14\xfc\x96\xfeSg\x98)\xba\x9d\xb9\x07\xdf\xf7\x0d/\x1e\xa1\x15\xe6Cj\x16\xe5\xc2\x82\xb8t9u\x80W\xc5\xdf;\xbaT\xa7\x9c\xad\x1fG![\xbff\x88\xbf\x08\x040\xf4\x0fsC\xe8;y\\/dK\x1dgT\x9a^\x99\xaf\x94?\x06\x07\xdc\x17\xdfm\xca\xd5\xc1\x18\xe8\xed\x16\x1a\x823\xd2\xb9\xbc\xacL\xca\x02\xbd\x0e\xd57\xe8P\xcb\xba\xca4\xe7Ft\x1e/\xab;\x0d\x9dj\xbd\xf5\xd0g\xa7\xff\xa5J\x9b\xc8\xde8\xd6\xb9\\mM\xc3\x14\xaaU\xd9Zj\x868\x86\xb3\x1d=\xbd\\'Z\xd3\x11F%\xc3\xcc9\xdd\xf8s\xfc\xb9\x1ci\xbf\x99\xf5?\xc9R}\xbcy\xf5l\x80{SRo\xd8\xea\x13o\xf2\x98\xe5F\xa9\x19\xd5~\xef\xea\x9f\x17\xd6\x1d}\x9d\xbe#\xac\x83\xd6\xfds\x1a\xb8\\\xd2\xd7\xab\xcei\x1b\xd4/s3F\x077\x88zm\xc7\xe0<\x89\xd3\xb3\xe13\xca6\x1e\xfa\"\xd6\x93\xb8\x87\x93\xf8\x10!5\x0e\\\x81i\xe7\x1b\x01*=\xb0~\"V\xe5:~\x82AB\x98\x01\xe5\xb4\x92\xb4\xb4\x13\xb2ij\xff\xcf\x068\xaf\xb57pe\xf9\x12;X\xf5\x19\xa3E\xa4\xf4\xe71\x15\x17\xa6\x9a\xf8y@UE\xf1\xaeL3\n\xa8\x1b\xa0r8\x11\xf2u\xa6\xdeDa\x7f>\x0dl\xb7\xb5\xb9\xc2 \xfd\xd2\x9f\xe0'/a\x83@\xfe\xd4JE\xfd\xb1\x11\xb0\xda*Z\x04\xcc\x9aV\x8d!\x08h\xe3=\xf9\xf9b\x9b\xa5\xb1b\x98i\xa3\x8dq\x96/}\x16\x18'\xc6r\x8a\xf94\xb4\x08\x87S6\x14\xd9\xda\xd4\xae\xa9d\xf8|(^\x81r\xafqR\x11 \xdb\xf3\xb9\x0bV\xbd6\xbf\xb8\x1bfiF\x98f\xdc\xbf@?B\xaeoi\xab\xe9\xb48\xf3\x8aA\x02B\xea\xf8\x95\x81=`i=\xb4M\xd7\x0e\x14W\xd9\xf0o\x1b\x92\x1b\xc6\xfc\xbf)\x08d~\xee\xafII\xf2\x02}\xe6)#\xc99E\xd4t\xaa9^|\xdce9\xbf\xfaJ\x8c\x19\xd9'\xc5\x96B\x1e\xd4\xdd;\xa3\x9f@f\xbc\x01'\x14\x8fZ>\xf5\xea\xe9\x0bk\xf642\x1cf\x15\xd8`\x02\xf3g=\xcd\xea\x89\xb3:\xc8,\xd8\xa6\x86\x9fA\x07\xbd\x0c\xda+\x86\xfa\x12\\\x1aB\xde*+\xc4\x87 m\xbd\xfduE{\xe9\xa3\xef\x93\x82YWl\xf6\n\x03\xfd\xb2_\xda\xfb\x85O\xe0n\x18\xcd,.W\xb5\xdfd\xf8\x7fl\xd3\xbdK\xec\x81=$\xfb\xa7\xf8\x8fe:W{-\x01W\xc2\xee\xb4\x92\x98\x9d\x9d\xe3 \xd3\xef\"\xe6\x9e\x0e\xcb^\x0df\xa5\xa1\xd1\x13\x12\xacS:]j\xe2\xa03y\xc1\x8a\x04\xef\xe6\xa9\xa2 \xb8\xb84\xadZEt1\x9cc^\xdfV\xe9\xc3\xe8\xdea9\xa2\x1c\xb8\x01s\xfc%\xba\x8a\xb7\x84\xfb\x8c\xd9PD\xaf0*(i\x08gpf\x06\xe6[\xa9\x9a\x19\xf3\x1b\xf5\xce ^\x9a \x1e\x19\xb6\x05p\xdd\xe4% 54\x89\xb5\xf5|\xed\xba\xd4\"\x9d\x8a\xb9OM\x0c\x8bJ]~\x170M\xc4.H\x8dTp\xe7Q\x9au\x94\xd0iO\xaf\x96\x03\xd6^r9\xbd(t\xdal\xea\xbfMM\x97\xf2\xb2\xd4\x15\x84$\xb5\xef\x18\x8e\xae\xc2\x03R5\xe0\xd0f\xb8\x1f\xcf\x03\xf2\x92\xf87<\xeb=\xb0\x859G\xc9H\xc7'eC\xda\xd6&\x887\x1e\xee\xbd\x0c\xf8\xba\x9e\xdb$\xc0\xff4}\xaf\xde\xd2v\xbf\x91\x15_\xb3\xfa\x97\x1d\x81Ej|\x18\x90\x1e\x1fx\xe7\xab\x14\xf9R(K\xc7\xddz\xcc*\xc7\xdd\xf0\n\x1cw{\xe5\x95\x94\x94\xa3\x94\x94W\"\xbb\x97Wj\xe3\x82i$\xc0GS\xd6n\xc3\xea%\x1b\\\x04\x8b\xe4\xb9\x112\xad\x1dq\xd0\x15O\x0d\x19\x0dq\xc1\xf1\xe1\x10R]\xe2\x92\x8d\x88\xf4\xac\\\x00\x15\x0en^\x10\x13?\xd7\xf8\x1f3\xc7\x82\x19\xe8Y2\xce]\xf9\xfa\x82\x1c\xc2\xd8\xcb\xe0\xe4h\xce\xbd\xb6\x02\x81\xc7#C\xdffU\xa4\xba\x16\x8c\xaf\x94\x96M\xad\x17T\x9b{6`S\xaa\xcd\x7fK\x9b|$\xe06\x8a\x91*\x11\xbc\xc5mZm3\xe1\x1covw\xcf\xd1q\x02\xb9H\x9doj\x8a`\x94\xc1/D\n\x019\x06E\x0bp\xb1\xcc\xf4d\xca==\x18K\xca\xcbJDIH\xce_,\xdctd\xf2\x97\x8b\xa0\xf72\xaf\xa0{\x92\xbe\xd5\xf8uXy\xd1C\xc3crx\x15\x1d qA`/g\x1e\xda\x8a\xf1\xc1\xb7t\n\x18\x84\xb9C\xa23\x9d\xcf\x0dv\xba\xa9\x9c\xc7\xf7\xb4\x89\x84\x94\xf5\x8148\xd8P\x04\\1\x0e\xb6\x91KOY0\xaa\xd5\x14\x9e\xe1\xcbsX\xa4cPE\xdf7\x16\xc9WO\x02\xe3\x98\xacF\xdf?\xe8\xd4\x1e\xe9\x89\xcdy\xc46\xaa\xd5y\xc4\xe6\xd3\xe6_\xfb\xe7\xca\xbf\xbe\xf2\xb2M\xb1r\x9d\x9c\x14Y\x9a\x14\x04\xed\xca\x87\xa8\xd3WP3E\xde|\xd6^ev\x1c\xd2\x1a\xba\x9c\xed\xd4\\\xdf\x95\xf8C\xcca\xcf\xf3y\xc8\xe0\xd8T\xb6^hS0\x87R\xa0d\xe9\xc0\xe1!\x92\xd1t\xc1\xa2X\xc4\xe7*C\xdd!\xaa\xff\x12\xfa\xc17\xaf\x9eV\xb2\x9e\x9bu\x03\xa5(A\xd9b.\x03Vr\xeb\x15 \xa3\x9c\x04\xe5\x9bZ\x9f\xd1\x13\xe8t\x0c+\xfe\xd1\xaf\x9c\xd1[\xf6\x93\x8bS\xa7\x95\x84\xe1\x8b\"9\xa6@\xb09\x8b\xe5\xd4\x19\x89\xba\x06\xa2y\x99Lp\xee \xcd\xe6q\x1a\xbc\xc3\x12\xeey\x1a\x9f\x9e\xceK]\x08c\xdbF\xc4\xff\x92B3\x0b\x11\xf1sI\\\x94\xb1\xde\x89\xa9\xce\xc9\xf5\xcc\xa1\x8aD_\x9a\x03\xe4Z\xd69\x19\xb3\x1f\x07X\x15\xd9\xbd\xf7y\x9c\x05\xd0\xd29\xad\x88\x1f\x92\\b\xf53\xed\x19\xbb\xe0\xc9F\x98\xa1\xa0=\xc0\x9b\xd4\x17\xb2\xce\x1b\xd9\xc1\xbb\x12L{\x81\xcc\xc9N\xea\xd1\x86\\d\xfc(\xc3e\xae\xe9\xa2I\xfb\xe1\x8e\xc1\x81u\xe1\xe8G\x1d\x1aGm8\xf3\xa1M\xa0%Y^\xc6;gr\xb1\xa9\xa7\x06=*\x06W\x9c\xdb\xa1X\xa5\x9b8\xac\x08\xe1\x9b,\xf4K\xdb|\xac6\x15\xcd\xeb$\x0e\x9e\xd0\xf9\xa0tI\xea?\xff\xf8\xa3 E\x0fq\x0e\x81?\xdbO\xd9\xf1\xcd\x9f\xf3?\xda\x10aTd\xb1\x7f\xc11\xeb\xb1P\x7f\xb07\xe4\x0f\xa5c\xf8\xdcR\xb2\x8a\xe9\xd4\xc3\x0eM\xca\x9a\xd6\xf0\x06C=T\xd5\x8e\xe5\x93\xac\x7f\xd3\xafx=\x0b3?T\xcax=\xc7\x07\xfc\xc8\x12\x98\xa2\x87\x0c\x98\xf3\x00\xba\\<\xdfPi8\x14\xe4\xe9!\xf8\xde\xbau\xebI\x9a\xbb\x9b1\x14#\x98\x81\xef\xe5\x9d\x9b\xfa\x86B\xa8\n(S\xa1{cL\xa9\xb0\xa2\xa7+\xcf@$\xd7\x974\xafm\xfd\xf9\xea\x10\xf1\xca\xf4\xc7cSE\x97u\xfdb\x92\x96\x8f\xd3\x00I\x12\x86\x87k\xdf[\xd6\xef\x11\x9b\xf4\x1d\x175<\xfa.\x1a\xc0\xe75x\xe3\x98\xd0\xber\xda\xb7{n-\xd2VlO\x1c\xca\x9f\x92\xa4\x9c`\xe4\xd8[JZ\xb6'\xce#~\x13\xa3\xc24y\x85\x80\xeb\x94\x12\xd7 ,\x16\xea\x9c\x81\x8a\x8d\xfb=\x0b\xcf\xd2\xber\x0c\x87]wm\xa3)\x1c,\x0enk_W\xe8p\xf9\x0c\xc3\xe2\xc8\xe8\xf5%.\xa4\x95z\xa7\\\xe0l=8\x98\xe3\xcc\xc1\x90\xf7\xed y\xcb\xa2\x15\xb5\xef\x9a\x92x<\xa2\xe24\x1e\x06\xc7\\\xe0\x96\x8b\x82`1iMn'\xd0E\xaa\x1c\x99f\x96\xd3\x0fm\xe2\xf6\xd1\x18V\xda\xf4\x06v\xcc\xd7\xed>\xf3\xf5\xe6\xd53-\xdf5\xd4)TD&\xd2-\xa0\x1e\x8f%\xa3\xb7\xd2\xa7Xh\x8e\xe7\x98\xe4[\x92\x83\xd8O\xda1a\xf0\xcc\xc0Q\xb1\xcf\x16\x13\xf6\xeeN#+\xe9~1\xafR\x99\xef\xd85\xb6\x1dw\xec[8\xa8\xd1 \x8d!H\xe3S\xd6d5\xeb\x13z\x8f\x1fk\xban8h$\xd4.\xd1\xd5\xf5\xc7\xca}\x9cv\xea1)\xfd(.\x0cy=J\x8c\xa4\xfdP\xab\xf8\xd1Vo\xe8\x92\x85cX_e(S\xd5\xfe& kfc\xa7\xd1G\x8d\xe0\xba7\x8d\xaf\x81S\xf9\xf8_1\xaa\xed\x84_K\xdd\xf4\xb5\xca\xf7\xb6\n\x8e\xc1\x0d<\x04\xe1\x86\xb8]\x95\x99\xae\x03\x18.4\x9f>7\x0e\x8e183\xb80\xb0\xc8\x0c\x8e\xa5'4\x04\x17m\xf2x\x06\x06\xe6\x9c\xf3\xa7\xda\xcc\x89\xf4j\xca+\xba\x98\xb1\xf7\xf5|<\xd2\xcc\x871\xb4\xb2\xea\xd7\xb1MS\x11=\x96\xe7\x97 k\x10|\xed\x0c\xe6\xe6\x06\xd5\xe1-\x97\xf0\x85\x97\xeb?C\xbc{\xdd\xf4\x9f+\xa5\xfe\x13\x9f\xf4\xb4\x96\x91x\"S\x80\xaed\x9a\xd1\x0d\x7f\xd0\xd3\x8c\x16\xfcA\xaf\x8d\x98?\xe8iF\x03\xfe\xa0\x97\x1dy!\x1a\xdf\x7f\xd0}\x94Q\xf1e%\xb4\xa7h}\xec@\x84\xa2\x83\x8a\x9aU\xab\x8f\xafO\xdd\xda\xda\xd6T\xa9\x94\xa5&*\x99\xfd\xac\x99B\xb9\xb0Q\xbcEm\xc5\x9bE\ne\xac\xd0\\\xc7]\xbc\xc9\xe3!\x96-\x9eU\xb9\xad\xce\x90\xcb\x19\xc2LG\xce`!z\xe9\x12o\x93\xc7.\xe6\xe5\x17;5N\x99\xa3\x00\x95\xe4\x99;\x87+\xd1\x14\xca\xe7*\xe5s\xd5\xd4\xe3\x8c\xdc\x91\xc7\x1d\x8f\xd2\xbc\xe7\xf3\x04`\x9d\xe3\x17\xc9|\x7f\xbaT\xba\x86f\x9b\xb3\xa6\xabd\n\x0f\xc1Y\x95eV\xccn\xdeL\x13*Q\n\xbf\x06/JoV\xef9 \xab\xaa\xd7K\x8a\xab\xb4\xb1\xc5\x0d\\\xa8\x15\xa6m\xcb\x9b\xd2\xc6\x16\x08z\xf9K\x14\xc7\xafH@\xa2-\xd2\xb6\xc2\xc2\xec\xa6\x94\xd3\x85\xe2}\xf8\x12\x81\x88;\xb2p\xac\xc7uB`\xdb\xa5\x02\xddr\x95\x03\x96K\x1eZ'\xf3\xb1o/\xa1\xec\xd4\xbc\"[\xa7\xd8\xa9t\xce\x1b\xba\xe3\xf6\xe4\xd3\xed\xab\x9e\x1a\xb1d\x99W\xf8t.\xffM\xde\xe41\xa3Bu\xb1\x83j\xf2TqF^\xb0\xc9s\x92\x94OXj\x08s\x85\x93-%I{\xcc\xf9\x03\x7f\xbb\x1b,4\x97f\x05\xff\xc6f\x0c\x18\x9f\x88~\x16{Q\xf1\x93\xff\x93\xbbB\xfd\xca\x8a)0\xc4K\x1b\xaf\x88\xa3\x80\xd0M\xb2\xd2U\xc9m\xf9dlzy\xc5|\x13\x9fDw\xc3F \x87\xeb\xa4\xd5:\xea\n\xba@=dU\xbf\xac\x12\x92\xb1\x9d]\xb5\x89\x89\xf5\x0c\xf5\xb5\x00\xb5 \xcb\x17\xf3_\xad\x12\x99\x95\xfeR\x9b-F\\\x9d\xdd\xa7\xcdB\xd3~\xa7\xca[\x93\x9a\xdf\xa8\xf7\x9f6\x8bC\x0b\xdc\xc2& \x8c\xe7\xe8\xae\xbei\xe9\xa1!,\xf0\xe5\xcf|L\xa3m|\x0d*\xb2\xc5\x8d\xc5\xe5*5:\xf1\x89+\xc5@M\x816\xcf\xa2\x82\x9e\x8b\xb4ez\x98&c\xc8u9g\xc4\xc5\xd1\x8f\xc7j\xba%\xaf\xa3\x85\xa5\xad2\x98\xc1bTi \xf3Q\xad\x16\xdc\xb9\xb0\xba\xb8XJ\xd1*3\xa4\x05\x9a\xd0\x8b\x9e\x1e/\xb1\xac\x90\x05\x96\xd0+\xcd\xac\xd0\x1b\xaarE\x169@\x01\x83\xb9\xe9JY\xa17T\xdb\xc7\x08\xaa\x91\x8c\xd8\xe3F>D%d\x13\x8a\"3\xa6\xb5\xfd\x06\xa6\xbaB\xde\xab[\x0d\xaf\x8c\x9fR\xa8\xc9\x17p\x856D \xce\xfe^]8\xe9R\x96mYy\xe6\xcf\xc9\xb2-\xad\xe1\x9b\xaaj\xf8F\xaa\x1a\xbe\xbe\xaa\x86\xefFU\xc3\xb7P\xd5\xf0\x8d{5|Y \xcf\x82K\x05m\xe8@\x04\xcb~\x16%~\x0d\\\xfb\xa7\xe4\xd8\xafi\x88\xe0\x10\xee\x9cq\xe6\x8c\x1bPC%\x02J\x0d\xc2\x8e\xb2`\x15\xc5aN4\x944\x1d\xc6\xa9GC\xb8t\xdf\x9aC\xdf\x0c\x90/\xb0p\xb2\x8e%_\xb0\xc38\x0d\x8e\xce3?)\xb4Q\x14\x19?\xb8I\xf6,J\xdeE\x89fFCQ\x04\xd8Y\xf8qAX\n\xfeL\x0dO\xb9\xf4\x0d\x96\xfd\x8c\xfd\x0c\x1dk\x95\xa0[\x06jSes\xcd@\x1f\xf3\x1e\xeb@\x97\x0c\xd4\x04V\x05\x164\xa1\x1aJ1\x9cb\xab\xb7\x15\xb5r\xc8\xe7yz\xa6\x19\xdcY\x14R\xd2\xe0\x1c\xec\xeb\xbccH\xb4\\\x95\x0cjpo7\x85>\x14\x88\xed\x08\\\xab\xbf\xc4\x14\xcf&\xd8\xe7 r8t\xa9\x9aw5\x9d<\x8f\xa3\xe4\xdd\x0f\x83>\xa6\"6:\xad\xa3\xb6\x86rT\xbc\xc8HB \xf6\x91j\x9er\xa3\xf9@\x92JC'xg\xe2)\x1a\xe6{\xce'BcX\xab\x9d\x16y\xba\xfe\xf1\xd8\xfd\xbd\x1b\xcd\x87\x1a\x0f\xa7\x9e\x94\xf7\xe3k\x97\xd0\xb4/\xd4g*\xa1>S \xf5\x99J\xa8\xcfTB}6,GS\xe6vc\x94\xa9\xe4\xeef:\x97\xf3\x05~\xed^sY\xb96@&\xecg\x1f_\xd8\xd7\x9b\xe9\xbe\x08\xfb\xe2\xfap\xc2\xbeP\xa4\xaa\xe1r\xcbT\x05)\x87\xc3@R\x0dc\xc9\xb4\x07\xe9r\x19\x13d1\xd5\xa0L\x82O\x93\xd79\x15\xf8\xf1\xb8T\x03o8\xf0#? Hl\x00.8\xf0\xd19 6\xba|\xfb\x0b\xa3\xe1.\x1b\xa0<\x08\xadU\x12\xabjq\x8cz\x8e\xed\x10s\xea\x1a\x81\xad2q/+P\x8b\xef^\xb0 \xf5\x8b[\xc6\xef\xce+P\x8b\xef\x9e\xb6\xdd\xce*\xc6J\xc3z`\xb8\xbd)w\x02\x15\x9f\xcf\xbc\x90d9 \xfcRW=\xe0\x1c!\xb98\xa4\x06;F0}n\x8bG\x08c\xcak\xf1\x0e\xa1R\x8dn\xe7;\x84\xd0*\xe0^\xf0\x8f\xf0\xe9\xd2\x95\x9c|\x89\xa0~\x1c\xa7g\xaf\xf3\x8b\xa7\xe5\x8b\x8d\x06\x83_\xb3y\x1b\x98-\xe49\xeb0\xff\xfa\x11\x13?\xd5\xe0O\x11\x9c\xb0\xbd\xf94y\x99\xa7\xcb\x9c\x14\x1a,\xf9\x15\x0e\xe1\x9d\xd7P\xea\xa8A\x7fB\xd0\xa6\xeeF\x0d\xfb\na1\xdd\xb7,\xa3\xb7\xb8\x1e#\xc6 %Q\x9ai\xb5@\xcf\xe0\x10\x1e3#_\x15\x02\xae\xd3\x8f\xbd\xa9\xe1\xb3<\x0d7\x81\x1e\xfc7\xee\x8f\x8c\xa9G\x9eEE9r\x1f\x8f\xe1\xc4iT\xd5\xd5\xf5\xee \x1c\xc2\xb6F\x9bc\x1c\xba{<\x86G\x9a\x97\xfe\xddQl9c\xf8n\x0c/4\xca\xab\xef\x9b\xbd<:/ \xeaI\x8b\x91\xfbX\xd3\xcc\xcf\xc8\x04\xd9\xcd\xda\x0f\x0c\xb6YKX\x0d\xfc\x0b\x03\xe6\xf8\xa6\x83\xfc\x91A\x06,w\x9d\x1a\xee\xbf\x19\x9c\x8d\xf2\xf5\x1f\x0c\xd4F\xf9\xfa\xbf\x18(\xc7G\x1d\xe4_\x19d\xe5\xd5\xc1\xb2,h_\xf9?\x9dW\x8e\xf4I^\xfe\xd9ma\xb3^\xfb\xb96\x17\xca\xfff\xaf\x98\x14\xc2\x84\xf2/!\xcf\xe9S\xe3\x86\xda\xa5\xf7\x19f\x8fe)d\xd1\xc4\xf9-\xec\x9b\xdc\x95\xd0\x9d~\xef\x19\xee+\x1e\x9a\x97{\xad\xec>,F\x87\x838\x9c{\xd3\xb9p\xe4\xe8\xe0R\xf43\xf1\x8c\xa1$\xb6\x16R\x10\x1e\x04\xb4\x7f't\xdfI\xd2\x84\x02\xd8\xe69\xb1\x12\xe6\x9b\xaa\xdb*\xe7c}2R\xf9\xf6\\\x06\xe2\xc0\x0dx\x047\xc0\x91\xe9x\xdbP\xea\xd5\x8e\xc2\x99F\x03\xfe\xefZ\x01\xaa\xd4\x80\xaa\xa6\xe0\x9fZ-\xb1\xc0[\x94ngp\xaa\xeea\x83S\xd5\xfa\x98\xb4}K4\xa7w\xab\x84\xd3Z\x0f\xd7\xf0\x9f\xd1\x1c\xf6\xb53\x84\xca!W=M\xffm\xa7x8\x1f:\xfdC0\xb0R\x8d\xab\xeb\xe2\xbf\x1f\xc3c\xba!\x1f\xb3-\xfe\xc7\x1f\xcc\xff\xe4\xf0\xf0\x10\x1e\xd7\xce(\xea\\\x13\x06?\xe8J\x15u\xeb \xd3\xd5S\x15z-\x03\x18\xbaU'\xee\xed\xe9TC\xe8d\x13\x10\xa7~\x18%\xcb\x89\x9fDk_c\x1f\x19\x8d\xe1H\x9bX\xc8`%\x91\xb5\x8d\xea\xcd\xd3$\xcd\xd7\xbe\"\x07\x10&x\xfa\xc5\xcf\x93(Y\xce\xe0qM\"Fc\xf8\xd5\"\xcf\xd1\xb0\xfe4\xd89}\xa9\xca\xab\xc6Bcf\x10M\x83\xff\xb01G\xfc\xaaX\xd4\xd1h\x0c?\xd1y\xfc \xc3=/\x91\xb6E6,\xc1\xf3N\xc24(v\x9f\xd1\x0f\x86YO\xa2$\x84u\x9a\x13\x08EF\x9f+^\xd8\xd6\x0c\x0c\x1f\xb91\xd0\xd5\xd8\xe6\xa99\xeb\xcceq\xeb\xa7\xa6\x18\xa4\xc23u\x1b\xff[\xd7\x86}\xb0\xac\xc5L\xc4\x91\xf6\x0bJ\x8b\xd6O\xda\xe8X\xf6\xb4\x91c\xa7yj\xa87\xd4\x0f\xbaa\xd7R\xc4\x0c~\xb3:\x85yA\x10;\xf1\xa3\xe2Ef\xf0X\x03\xc5+x\xff\x03\xdd%uj\xb8\xa6\xbaL\xeb\xaa\xdb\xd2\x95I\xeb]\x89\xab#\xb9\xcf\xe0\xb9\x86mi*\x12f\xf0R\x0d\xb9H\xa4Ev\xc4e\xcdP5\xb4d\xda\xecE-\x15\x996\x7fQ\xe6\x97\xab\xe7\xdc\xb1\x93q\xe1\x86nr\x17\xe4P\xb1\xe1*l|\xae\xc1\xc1\xbf\xeap\xd0z2\x98M\xfeX\x0d \x1cV5Ly\xda\x91\x1bgB\x03Q\x98\xe5H\xda~\xf5\xda\x16\x15b\x85;\x12\xda\x91\xe31T\x1f\xd1\xe9!\x96\x84\xbb\x83\x91\x90}l\x06s\xafh\xdd\xd1\xacs\xff\xe5\x0b\xafw\xd3\xf0>\x05\xf9\xd9\xcf#\x8a\xf0?3\xed;\xffH\xef\x89a\x18Mx6\x8ca_8Z,HPF[\">\x85\x9d\x11\xdf\xa9\x9e\xe2}3\xfe}\xf5\x15\xbc\xa4\xff\xbc\xc2\x7fLtq\xa7cV((T4Z\xd5\xd8\xff\xd2\x9eo\xec\xa33x\xf5aq\xdf\x96\x98\xf0H\x16\xa6!\x9b\xc1\x13\xc5\xcc\xd7S\x7f\x15S\xfc\xbcRu\xbc\xa4\x12\xf9\xbcL&\xcb<\xddd(ys\xfd\x95\x91\xb3{.\xdeW\xf5\xe8\x17+\xc9Y{Z\xd9\xce\xe20\x92|\xd9\xb5\xad\xec=3(\xacvJn\x9a\xaa\x1f\xb5(k9 \xf6C\xd3wz4\x86\xa7W\xb5\x97\x85 \x1aT\xc1dCw\xf3.\xcd)]'\xaaey\xa6\x19\xe0\xcf\xba\xd6*\xb5\xf1\x0c\x9e\xa9g\xbaJ\xea\xab\x89*\x11\xcc\x90(\xfb\xa0\x8d\xfd\xb0>\xb7[l\xc4Ul\x98\x86-N\x9b#\xd2\x1aK\xb9\xf5a\x06o\xcc@\xfc\x90\xda\x8a\x80\xbf\x97\xfc\xfe\x934w\x19C\xa59\xfc\xfb\x8c\xb4\x95\xce\xdf~\x1b\xa9A\xe4\x86\xad\x19\xbcV\xbf\x82\\\xac\x89\x9a\x10\xf4\xa0\xf8\xdet\xdc\xfe\x1f\x1d\x06\x93J\x17>\x83\xef\xad1\xce@2vq\x1bz\xb9\xc9\x89\xcce\xa8\xca|'w\x19j\x9c\x1c8)\xad\x87y\xb5\x99d\xcf\xf8\xa6\xec?\xaaQ\x85J\x8a\x0b\x8fY\xbc\xba>5\xcc6\xa1\xf3B\xfa\x12Z\xd4\x9e1\xa5\x17\xd2B\xee\x85\xb4\xa8\xbd\x90\xee5S\x19-4\xeeF_b\x8b\xfe\x03\xdd\x8d\xac\xfc~\x86\xc4\xfb\xe7\xf6\x0e-\xe9\x10\x87\x16\xe6\xa6\xd4\xb6\x13\xa9\xa1}K_\xaa\x0d\xd6\xd039\xa7\x14,\\\x9d\x91-5X\x80`QQ\x95=\xd5\xf0\x0d\x0b\x845\xb9\x9ed\x08\xa5s= Y\xd7V\xe9\xd9\xb1\xa9{+\xfe1\x0b\x17\x94-\x03\xcd\xa3e\x94\xf8\xf1\x0b\x9bW0\x12I8\xa2X\xbd\xb1\x84C\xc8\xcc\xb3z\x81K\xc4\xd5\x1d\xc1&\x8fJ\xadU{\xce\x12(Tu`\xab\xae|_j\x8d\xf9\xa7\x9d\xc4\x0b|:\x9f\x1b\x03\xbf\xcf\xe4/\xbe4\x04\x9a\xf3\x1a'?n\xd6\xd9\xeb\x14\x811;\xc4\x07\xb7.\xd7Z\x01\xd6O\xe8\xfc\x8d\x06b\x8d\x16\xb0\xae*(\x05\xd1\x08 \xa7\xba\x1e\n^P\xc5\xb9\xa9?{f\xaf\xa6\xd3\x05>v\x0c\xd0\x1a\xc3r\xcd\xe3\xc8\xe3\xc6ig\xc3\xab\x92\xfb\xba\xabcc\xafX\xd2\x83\xad\xa8\x99],\x8a\xedn\xe9\xdd\xd5\xc8\"{\xfen=\xab\x93\\D\x8a\x02\x04\xef\xc7 :Qg\xdc\xff\xea+\xb8\xf0\x82t\x93\x94\xae\xaeos\xbdY\xbc&\xb93\xd0d\xcc\x1a\x1e\xe3!N\xd4\x941\x94\x98\xef\x97JMT\"\x89r\xec[\xe1^\x982\x89 \x81\xae\x13\x06\x17\xae\xc2\x01\x05z\xacEu\xd7\xac\xb8\xd2V\xc8\xc9\xb4\x08{\x85B\x87!N\xa1\xbb\xcfL\"D\xb0\xb3\x08q=\x03\x19>i\xa6\xb2\x01\xc5\xa6?\xa32\xa3_\xc4\x04q\xed.&hK:\x9b\xb8\x8fK\x1d\x1b<\xb3\x8e\xf4\xdd\xf7c\x94P\xded\x19\xc9\x1f\xf9\x05\x91%W\xd9\x99P-\x86\x13\xaa\xfa\xbb\xe3\xcf\xa0\xc4\xf1g\xaa\xad\x10\x91S_\x94\x16\xff\xb1\xd4H\xcd\xc0\x95\x034\x11\x89Dc`\x14\xf5\xe9\xc6I\xac\xe2PR\x844\xc6\xa1D\x08\xa6\x8fC\xf1\x11F\x1b?\x82u\xf1\xed\x84\xf7\x82w\xecq\x9d\xc6\xc4\x18\xe1AO\xd8\xb2\x99G\xe4\xc3\x9f\x04y3'\x838\x0d\xe8<\x9d\x9e\xb6\x9d\x9d\xa5@\x83\xcd_\xdazUU\x02\x06\x9d\x02J$`\xd0\x98\xa2\xb2\x06\xdf\xca\x9ao\xfbO\xfbXy\x80J\xd8\x1b\x0d\x0e\xb2,\x0d\x91|\x84Wy\x04^7v\x99\x9e\xaa\xcd\x80\x078\xe4\xe5R\xfa\x87[D\xcf\x84\xfb\xb2\xd3-\xea\x96\xd0\x8f\xd8\xe9\";=\xa2\x8f\x7fz\xf8\x98\xc1\xa63J\xf5q\xb2\xad*\xca\xd7\xe6\xa6>\xe6$\xed\xd27b\xa5\xdb\xe1#\xaf\xd2\xb3\xee\xbe\xe6\x83M\x87j*\xa4\x0c\x9d,\x81\xcc\xfb\xf1\x95~\\Z\x9bS\xd7F\xb3\xb4i\x1d\xbb\xe2P^\xe3R\xfd\xc2\xf2\xa5*c\xbc\xaeC\xa2f*\xeb\x93\x1a\xacU\xe3T\x0d\x96[\xc0\xc8\xeb2\xaa\xcb~\xf6\x06\xe3<\x89H\x8cN\xe5\x1f\xb2\x114Q\xb3\xa2\xa1\xeafZECK\x8f$e~qL~\xc3\xec\xb7\xa6\xcc\xa0\xdbF\x8d\xa8f\x9d\x9f1\x1c(\x881=\xbb\xcb\x93}\x85\xb3!\xee\xe4\x93\xa9$ \xc8\xb0\xad\x12\xd5Q\x84\x0cUT\xa5\xdeT\xb8\x8a\x9e\xa3\xcb\xa9BAy\xfe\xb3\x1f\xcb\xf4<\x9d\x04\x96\xef\xdb\x05\x10\xdf\xcb\xcf\x04\xf6\x99\xebu&\xbcJ\xcf\x0c\xc7\xc2\xed\xe9\x9f\xe2X`\x03\xb59\x19(B\xc8\xcf\x04\xe2Q|\xe8?C\xa6\x14\x1eR\xa63\xfd\xf1\xb8\xfa\xe1\xa2\x92\x91+\x1a\x87\x9d\x14\xd6\x94\x88o]#1ap\x9d\xbd\x1a}&H\xdbG\xcc?Q\x02\x13\n\xf0\xe0\xee\xfe\x9f#g \n\x9f\x98\x949\x1a\xc3\xa6O\xca\x15\x82z\x1fp\x91\xe6\xe0\xd2\xaf\xd1 \xaf$p^Bn\x8c\x13\xceR\xff\x16\xa31N\xf4\xfe\xd7\x10\xc07P|\x0d\xc1\x8d\x1b#\x88O\x82\xb7\xcd7O\x02\xf5\xc1B\xb7v\xc4O\xb2\xbe\xb2\x00ei\xa3\xc2 \xf0\xe3\x98k\x0d\xc8\x18N\xe8\xbboE\x11\x87\x18O\xe1\xc8Cs\x85\x1fG\xff\xae\xa5\x07c\x19\x07zE\x1e\xa1\xe3\xed{?\xbfG\xadBz\x865y^\x936\xef\xab\xfa\x1a\xf3$\xaai\x00\xd7X\xe2\xbe\xa3\xdfc\x7f.\xa2\x98PN\x03S-\n\xef%\xaf|\x0b)Z\x0dY E\xac\xce\x9c\xc07\xacVa\n7 \x82o\x0f\x99;n\xc2\xe2\xbbqs\xf39}\xcc\xd6JV]u\xcc4\x19=E\x17\xdd}\x1fC[u\x95\xb5\xcf\x98\x9c\xbf\x8a\x96\xab\x98\xce9\xaf[I$\xc1P\x1d ]\xc6\xff\xf5\xbb\xf7&\x0b\xfd\x92\\\xaf\xfe}\x02e\xdfV\x1f\x90\xc1vV%h\xe87\x14\xa9\x88\x0f\x15\xc3\xb4:.,0\x86\xc4\xc4\xb9\"\x9f\xeaj!&A\x1a\xaa\xca2\x8eQ/v%\xed\x89\xa1Nx\xc5yY57q\xd5^\x1dt]\x9a\x14Z\xd5M\xe71\x07r\xcc\x96i'\xcb\xf5\xc9\x01YYN\xda\xb4\xe4\xc8\xd1\xf5\xfa\x97\x15!qU\x04KG\xd0\xd5_i\xcc\x19\x96=\x80uD\xbf\xa0\xae{\xfa\x9er\x00\xc6M\xd4W\xc3\x99Tpr\xa7\xd7\xe6N\"\x1e9\xcf\xd2\xbc,Z\xc7S\x9f\xbd\x85\x06\xe7\x99\x903\xf8>N\xe7\xee y+[\x83\xf2\"\xc3\x91ST\xa7\xfc@\xc4\x8ad\xdfL\x83\x92\x94\x93\xa2\xcc\x89\xbf\xeeH\xeb\x1d\xf6'ZT\xf5v\xf7\x0e\x0f\xe1,J\xc2\xf4\xccK\xfcm\xb4\xf4\xcb4\xf7\xd6\xc5\xb1\xbf%\xb4\x0f#\xddC7\xefsV$.\x88\x82k\xa3\x87\x1e\xff\xda\x9bW\xcf8\xc61\x0e\xfe\xcd\xabgn\xae\x91\xe9C\x9e\x0c\xa4\x8b\xa6\xbeL\xef\x1dyX/W\xb8\xb6\xc1!8I\x9aP|\x8e\xbcUN(G\x9c\xd2\xdf\x05)\xbf+\xcb<\x9aoJ\xe2V\x9b\xcfa\xb2N\xa3\x1cq\xcd\x00\xd13\xb3\xfb\x1ec$\x9cq\x15\xd3;\x1a\xd7\xdd\x9d\xa7\xe1\x05\xe5\xd9H\x12>ZEq\xe8F\xc8\xa6\x05t\xeb\xba=\xc0\x9c\xac\xd3-\xa9\x01\x1b\x93\x95\x93m\xfa\xae1Y\xa9\xea\xe8}/E\xc9\xeb L\xc9\x95\xbfR1+R\x89Y\xbeJ\xcc\xda\xa8\xc4\xacB%f\xc5\xfcAOb\nx\xca\xc7\xbe\x1cUKZYU\x12B\x98>+\xe0?\x81`\x95\x8f\xc1\x97\x0bV\xd1u\x14\xacr.Xml\x05\xabt\xa8`\x95{\"x\\\x84\xe1\xfc\xc2B\x04\xad\x84\x0e\xde\xd5\\T\x88\xac\xc3\x85\xbc\xa0\xf5QT\xa8\xba'\x02\x10M\x90\xd5k\xcc\xed\xe2-\xe5\x9f{\xad\xbcg]\x14\xf1T\x8f\x18\xfb\xf0\xfa\"#\xac\xd7V\xdd\xace#\xca~\xe4i\\|\x17\x04$+\x7f@\xf5\xaf\x89\x9f30})\xe6v2\xb0\x8f\x11\xba\xedY\xa5@\xf4\x11To\xa4\xdd \x8c\xceO\xa6\xac\x08\xbad\xea4EZ9\xd1\xd3\xe5\xb4d\xde{j\x00\xe1>\xbb\x91BH\xaa\x17\xbd\x1f3\xabs\xafp4\xdd\xad\x96\x82X!\x15\xc4|;A\xacX\xa5\x9b8\xacX\"ka\xc7\xb4/\x1a>M\xdd\xc0@\xe4NH\xff\xb6(\xbf\xcf\xde\xaab\xdb8x\xfdw\x1bN\x84\xd6q\xb0\xeaO9\x14n\xc6\x0e(\xbb\xd7\x86\x97\x07\xbc\xf1\x17\x15\x0f;-\xfa\xe5J4D\x7f\xb6\x9f2D\xe1\xcf\xd9\x1f}\xdch/\xffG\x92\x06\xf5$\xc1F^d\x1e\x19\xd5z\xe9)C\xd2\xc3\x03=yH,\xbdN65\xac!\xa5,\xf3\xd3\xb0\xcc\x13\x8bl\x841\xefm\xd2\xc6-5p\xc8\xdc\\\x06\xa6\x0d]U=\xd6G\xd5l\xf9\x11Zi\xed\x8e1\x89\xdf\xa34$#7\xd5x>\xac\xb1\x98\x8f\x13\xd4d\xd3T\xd1\xc6w\x9d8\xda\x12\xb1\x86\xa6\xca6~\x1d\xbbj\n\"\x91m\xf5\xaf\xbe\x92\xdd\x16Q\xa4\xb27f\xb5\x84\xf7\xb2\xf5D\xdd\xf8)\x1cB\xd1\xac\xf6\xc7\xa6rIJv\x82>b\xe7)\x95p\xc5\xb0\xe9\xacJ\xcd6\xe229\xee\x0c\xd1+T\x1b\xcc\x98\xd9\xe0J\x9a\xb3q\x01\x10\x971O\x16w\x05x\xd5\x88_n\xcf\xb5)q]\xec\xcfI]3\xc4\xe4\x08\xd5i\x0e8b\xa3\xcc\xad\xcb\xa6\xa5\xad\x16\xc3\x89\xab&(L\xb0\x97\\1\xa2\xe065\xc4\xa6\xde\x7f\xc5\x0c\xe6\x1a\xc0\xc6:\x89t\x17\xfc\xe5 \x8eQ\xbeJ#]\xc6\xabA\xc8Q\xe3b\x94\xe8\x92\"Df\xa5\x9a~E\xb5\xd5^\xea`i\xeb|\x94\x1a^\xae\x99y@\x93\x03\xaa\x93y@CP\x18\xf7\xd8a\x11\xcc\xbcd\x8fk\xd0\x1c'\x8a0}U\xfe\xa5\xe1\xdb\xd4B\xc9(\\k\x86b\x0e{o0=i\xbb\xe8\xa8\xc1\xf2\x1d\xba\xb4+\x8dS\xb8\xe1\x88K\xed\x8eS\xa1\xf0\x84\xde\xe39wU\xcd;\xf4 \xd7&\x03\xbc\xa2~\xd8\x04\xbb9\x8f\x1b@]j\xfe\xa1;\x18G\xc9;\xcd<=\xc3\xc7un\x07\xdd\x8c\xb5<\x9bR\xa5gS\xa9b\xa5\x81\xb3\xd3I\xdf\xc3\xa9T{8\x89\x0bYg\xa5\xa7\x93\xb8\xb0|\xc9\xc9\xd4\x00\x15\x027\x18F\xed\x0c\xcepx\x08)<\xac\xf1\xfc\x94'#A'_G\xce\xb8\x80\x99y\xb9\xd0\xad$\x08a\xc5P\x96\xb8\x8e:[\xb1\x1c':6\x15\xd0\x1d\xf8\xb1\xd0\xa6mQ\xafkh`\x91h#\x13\xa1\x8du\x1aZ\x8b\x90iH\x8cC\xaaO%M8/\x0c:I\x803\x07]u\xce\x8c\xa2\xc6\xe1\xa1.m30\xbe\xa4\xabK\x9aa\xd9\x0f\xa5\xaa\xc9\xdc\x15\x0e\xae\xe5\x87\xc0\xfeT\x85\xfeI\xad\x84U\x14\x85n\x15\x83\xde!\xa1K\x8d\xe7;$u\xe9'C\xeaGX\xd6\x99\x83\x98\x85\x98U\x8a\x1a\xb9'-\xfb\xcf\xaf\x85\xa4\x16\xa7\xea\xa0\xdf\x9b\xd6\x03\xf8\x1c2\xb9\x84*w\xacP\xe5\x8e\x15\xaa\xdc\xb1B\x95;V\xa8r\xc7\n\xa5\xe6\x8b\x98?\x91Z\x10\xdcP\xd8\n\xc2\xcaV\x80\xbf\xa6\xb7z\x05\xa4\x17R\x8b\x03\xaa\x07Te\xa5\xc3\x8fo\\X\xd9\x1a\x17\x88\xc4\xb6 C<\xb3hkjo);O)\x0e\x8d}\x914\xc1'+\xf2N%$n\x90\xba<2)\xb9\x12\xe6\xeb\xd3oF\xfd\ns%\x92\xd1m\xf9\x99\x8b*\xec\xe3\xd2/uJ\xeb\xbcO\xb2\xbbK/\xae\xf7h\xd82\n\xb4\x9a\x11\xc8\xcf\x9c\\\xd1Z\xef6\xfa{Q6\x84\xf4\xe8\xa5\xb8\xa4\xc3q\xfa\xac\x1d\xfd\x94\x02\xbf\xe1\n\xdd\x94\xaeF\xb3\xca\x08-Z\xe0RK\x1d*3\x9aP\xfeB\x0d\xc3\xac%\xe6\x02d\xccbb\xe1\x9a\x13\"\xa0Y\xaf\xb8B8\x9d\x12t\x8b\x10v\x9a\xdau\x0dk\xd0\xd4.\xab\xfeYhj/\xf8\x0cVx\xa4\x06\x9dW\xa0\xf6\xf6\xb1S8\x84\x95\x17%\x0b\x92c\xaeS\x8d\"\xe1\x0c\x0ea\xc9\xc5!5\xd4\x11\x1c\x82\xcf8u&\xe2h\x93\xfa\x9d\xd7\xd0\xe4\xdc_g\xb1>\x07\xe0q\x0d\xced%\x0d\xec#8\x84\xadU'\xdeqH\xe1P\xc5\xe5Q%\xfcw\x0c~\x9d\x86$>b\xbd\xd6\x81\xbf`\xe06%\x80^2\xd0*.\xd3TL\xe75\x83\xb7Tp?\x17\x9b\x16i\x97'\xa1Q\xf4\xc8\xbaPP\xf1\x05\xb8g\xee\xc8$/>\x15+\x84\xc5\xb2x\xc7\x9c1<\x7f;\xe6\x8a\xe7\xe7~6r\x7f\x7f\xdfe3\xba\xd7\xafp\x08O\xb9\xc4\x87\x88\xe9\xf4>\xa0\x16\xf1\xeaP?4M=ma\x98#\x94\xe0\x99W`m\xa0hq1r\xbb0T\xccf@KR\x1e\xe3M\xb6AF\xee\xaf\"\xec\xd70\x9b&A2J\x82x\x13\x92W\xc4\x0f_$\xf1E\x8b\xcb\xec^\xf4\xd0\xa3\xc7\xcd\xaf\xf0\x10\xcaJy\x95\xf0;\xa7U\x9fj\xc5V\xce\x9f\xb9\x8d\xcc\x89\xcd\x151\xf5]L\xfb[\xfaI\x85\xe6\x8d9T\xd1^\x9c\xba\xbe\xe8\x01k\xda\xf7V~Q\xad\x1d\x9d\xf2\x90g\xfb\xacnQ\xb9\x14\x07\x95T\x0b\xd2\x9b\xebd\x0c\xcfu\xf3(\x99C\xcdi\xc4\x80\x7f\xc9\xa3\x92hg\xfc\xbd\xde\xfcq\x8e\xbe\xcc\x94v\x9d[\x04\x8a\x89K\xb0\xc0\x94\x1d\xa2l/+&\xf5\xd7\xbf\xe6d\xe1\x08\x97.\xda\xae\x8a\xebQ\xe0;\xddu?Y8\xf05/a\xdcF\x0bTeo\x1a\x16\xff\xd6\xbc\x9a\xb1p\x0d3\xbe&\x16\xaey\xe5\xda\xb8\xb8\xe6\x95\xf2\x1893\xa4\xe0\xd0[{<5%V\xba\xa4YK\\\xc8t\xc9\xd9IqiMKw*\xcd]\xaeQ\xf2)\xe3\xfe\x9aW\xdb\xa4\xc2h\x9by\xf68[(\x8f\x19\x17\x97,v\xbc~V+-(J_\xd6^b\x1c\xeb\xf0q\n1A3\x06A\x05\xe4\x1b\x92\xa2\xf7\xf9\x18\xde\xed\x98\xdc`\x07M>8p\x03\xdc\x0ds#\xd7l,'\xf4K\x9f\xb9\x85+\x03\xff\xafN\xdd>D\xd7\x1f]\xa1\x9a\x7f\xb0n\x7f\xe7}-[\x8bn\xab\xa7\xa7z\x93\xa1\xaa\xf1\x17\xba\x86E\xd5\x1f_\x94)l\xd8&T\xa7\xc4\x18\xce\xcc\xbb\xcdj\xacL\x9dWQ\xf3\xe6\xd0\x1b6Y\xd3\xcet\x84@2\xf1Q\"\x11\xd6\xa8\x19\xcc5[o\xe84\xbe\xb60q\x1b8\x1e\xf5\x94\xb4\xec\xd7|-\x04#E9\x9b\xee-\xef\x1da\xc7(\x88\xc4\xd5\xc7\xe4\xb7^\xd2\xb9\xe6\xd51\xb1\xcb\xf4>\x8a\xf5\x1e\xc3\\\x9b\x83q\xed\xc7\xb5\x83\x81\xc3\x9d=\n\xd0E\xa1 \xe1\xa8^ar\xa43\x1a\x83\x03l\xe9\xbc\xda\x06Uq\x9b?i:\xf1\x9d\x16\xc5+K\x89u\x9a}MV\xfc\xa6Z^S{\xb1c\xa2\xd0\xd5^D>T\x88\x02L\xb5\xfd\"\x0fIN\xc2\x91\x9bhV\x94\x1fB3\xf8I\xb1p\xd5\xd4\x1di\xa6\xee\x91n\xea\xb8h;\x83#\xeb\x99\xd3\xf7e4\xae\x04\xfc+\xb5w\x0e0r\x1e\xc3C8\xf6\xcaT\xc6\x85v\xa2W\xba\x97\xe1\xc0}i\"T\xc8\xb5i\x14<\xf4JpP\x06 :B\xad\xfe\x11,\x17\x064\xa4p\xa4\xad\x87Yo\xdf\x9fR\xe0\xaa\x92j\x95{\x1f\xbc\x94\x05i\xa5\xb7 \xd5fCF \x85u\xe8\xf7\xf7]s\x89\xcc\x9a\xd7TL6T\xffm\x9b\xd0\xea\xbf\xf8\xcdke\x13Z)sG\xacTQ%+UT\xc9J\x15U\xb2RE\x95\xacTQ%+\xa5Mh%lB+\x8c\xc8\xbf-\xb5\x04\xb1g\xbd/W\xe6\xa0\xf6\xedP\xf4]\x91no\xf5\xf1\x0dE[[C\xd1\x97(\x94\x8e\xd1\xca\x14\x85\xa2\xb7\x88d~^\x90\x90oq\x85X\x85\x91\"\x1bt\xdd\x7f\xd9\x04\x1fd\xf2\x12!)\x9c\x1bSk3\x99\xff|\xa9\x16b)\x10S\x91@\x94\x14\xa5\x9f\x04$]\x00\x0b<4\xebC\x12\x1e,\xf9$\x8aQ=\xa52\x8f\x89+\xf1R\x16\xc6g\x91\xc3\xa0y\xe56\xe6\xb5\xe6\xd5] \xca\x0cobydn\xf3R\x9cD\xd5\xe31~\xca\x0f\xbf+^\x93\xf3\xd2\xd5L,\xd7\x1bZ\xf7\xbc\xd3\xe3\x92\xf2\x07\xac\xaa\xbbN\x03!C\xafO\x1b\xa4r\x95\xd9\x02PN\x90\xec\x15\xd7\xea\x88W\x07a\xec\x942@\xb9)\x95\xbd$b\x7f^\xa2\xabWc\xd5\xb4\xb4d\xd6\xc1g\x16YB\xad\xccu\xac^\xc9&\x97$T\x12\x17\xabR\xc2\xf9|5\x98_\x9b;Xz\x8d\x87\xf0\xfb{\xd0\xba\x0fo\x06d>-\xdav\xa3\xd6nT\xbf\x85\xf5A\x06X\xd5\xe8\xc1\\\xfb\xf2\xa1\xa6\x8b\x92\xcf\xc7~I\xb0\xbe\xe8\xebhMt\"\xf4\xba\x9a\x04\x8d4$\xc9\xf5\xd5\xbc(\xc5\xa7\xcb\x92\x8aL\x0d7\xffo\xc3\x87\xe9_\xad \xf6\x9b\x91W\x92\xa2t\x93\x11\x05\xf6O\x1c>#\x93\xc7Q\x91\xa5\x05f\xe6w\xde\xd2\xe3\xe3\xa6_\x96~\xb0\xa2\x07\xb5xI\x05.\xbe%4,\xa1\xdd\xb7\xa4\xe0\xbd~5\xb4G\xec[\xf4h\x82\xd7\xb9\x9f\x14\x0b\x92\xcb\xba\xd6|\xa3\xd75\xeb\xcfI\xdf\xd0(\x8f\xe9*8\xf4\x98u Jx\x9c\xb9\xe9$\xa4[\xf9\xa2\xca\xb1Q\x92\xf3\xf2\xe6\xaa\\\xc7\x16\xban\x0c\xce\xe9\x1e\xf0\xc2\xcaV%;(\xa5\xc9\x0ed\x17K\x80pa\x84\xed\xca?\xb2\xebT\x9f\x94`n\xf1\x8938\x84\x93\x0b\xca\xd0\x15\x9byQ\xe6n\xea\xc5~Q>MBr\xfeb\xe1:7\x9d\x11\xdc\x80\xe9h\x0c\xa7o\xbd_\xd3(q\x9d\x99n\x9b\x8a\x0b\xed\xfc*D\xd5l\x08=\x13\xd4\xc9\xfdpdZv\xe0K\x7f^\x99{\xc8y\x99\xfbA\xf9\x84\xe7oz\x92\xa7k\xde\x8fF7\x98W\xc4\xc8=2\x18\x84\xe8\x85!<\xb43\xcc\xeaG\xe7\xf3\xdc\xc0 i\x9fR\x1aTy]\xd6\x99+\xe8\xc7%\xb7yB\x8b\x17\xf9\x8b\x8c$\x1c3/eIq|\xa3\xc6\x16\xaa\xfa\xec\x06\x07\\\xd8\xa9\x06\x8a\xb88We3hw>\x863\xfd\xa4\x83q\xe2\x9bYf`\x11 #\xff\xb5\x9aM\x91\xcbc\x06g\x83\xc7\xa2|\x81\xb3\xdb\x14\xf1\x94\xe3`)u\xb8\xce\xa8\xfa2\xe7< $%\x96\xd6\x86\xf9\xa6\x84\x8bt\x93\xc3\xd7r/\xda\x99f\x96k\xda\xe7\x06'\x84\xa2\x81\xdbN~\xc8x\xd7\x9b\x14\xe8_7\xb3\xd8\x8f\x92\x9b\x8d\xd9\xff\xc8\x036\xf0k\xc2\x88\xa7\x181\xcc\xe0\xe6\xff\x8d\xd6\xfe\x92\xfc\xebf\x0b\x87\x12\x8f\xbb\xfd\x14\xaeSl\x97\x8e\xd6\xb0\xd1\xa4\xf9\x0e8\xa8Fv\xc0\xd1+\xdb\xd7K\xed!\x80\xf9\x9ed\x9a\xcb\xe6\xb5\xf6\xcf\x7f\x89\xc2r5\x03g\xba\xbf\xff\xff\x93c\" \xe5W7\x94\x073\x1d\xbb\xa8\xd0\xc8\xf0\xb9\xf37a\x94v\xe6\xce\xea\xb8P\x9f\x8d\xf4\x8bzC\x117G\xaa\x1d\xb1tA\xd1h\x1c\xd7O=\x9d\x11]\xado\x96\xacL\xb5\x89\xe8\xc48\xcc\x7f\x88n\x1f\x04O\x17P~\xfc\xbdQ\x9e\xcbtE\xe22o\x0d\xee\xe4\xf5-\xec\xc3C(lw\x80z\xf9\xad\xcd\x7f\x91:\x9c\xf1M\x92\x93 ]&\xd1\xbfIX\x99\x89p\x8e\xbf\x16\x81A\x94\x89\x10A\xee~\x81\xd4\xdd\xd3E\x8a~\xca\xd9/4\xa4\xf8\xd3M\xe4\x06K\x91@\x99\x8a)\xad\x8d\xf7Z\xb7\xa5\xe5\xa5q\xa4\xe1\xc5Vg,\xc0\xb0Tz\x9e*]\xab\xacm\x916UH\x98Yu'\xcb`\x95\xef\xd0}p\xf7\x8e\xc4\x88\xa7\xd7}\xd6\xbe\x9eY\x1c\x95\xeeM\xf7\x9b\x7f\xdd|x\xf2\x7f\xbf}{\xe3\xdb\xd1\xcd\xe5\xc8[DqIr\x0b\x0fK\xfe!\xc7\xa9\xb2\x0dEkY\"\xdc\x8e\xfa\xba\xdd\xdf\xc8\xb6\xbf7\xbf\xf9\xd7\xcd\x1b\xac\x9b\x9c\x11 \xda\x0f\xfb\xf6\x1f\xc6\xaf\xfe\xeb\xa6\xddw7\xb6\xdf\xb5\x9e@\xec\xc0\x9er\\\x80\xc8E0\xef\xf0^$~\xf8\xbdn\xd6\xf8!\xcf\x9d\xd9\xed\x850JuM|\xf0-Li\x13\x0d]Gm\xcb\x9b\xbe\x85\x87\xed?g\xf0\xbb\xe4\xdcg\xb1[\x82\x83\xed?G\xbd\xad'a\x89\xfb\xa01\x1c\xca\xf4\xa6\x01\x1c\xc2IGeSg\xb2\xa5\x7fu\xe2\xac\xe9x\x17c4\x07\xbb\x0b8\x042\x86\xd4]\xd8\xb8\x13\xf3uR)\xeau!]\xec\x14wK\xd6^\xe4\x96\x94uq\x1e\xc5i\x11%\xcb\xd7\xfe\xd2\x81\x19l\xf8\xdd\x17\x19I\xea\xbb>\xbf{L\xe2E\x1b\xdeyM\xe4\xb9\xbe\xe5\x01\x81\xed\xa3\xf7\xfdH\xe2\xba2\x86TeR\x8eLI\xeaX\xfdq\xa4\xe8\xbd\xe7\xad\x81R\x1e\xdf\xa7\x88\x15O&\xf2\x9e\xd2\xad\x95\xbb\xc9\x18b\x85\x92\x0fK\x89\xc3\x0d\x88\xfa\xef\xa3b\xb69\x83us7n\x8c\xa1\xd0\xd9Y(J\xa4'%L@\xe7\xbe\x1dVP\x07\nM\xa1|\xb8l\xb9\xf0\xef\x0c\xe7 ov\xbb\x1aV\x8f\x109\x1d\xac\x9c\x057 ds\x0f7 \xab~ET\xe8\xc4\x80\x05\xec\xcd\x18\xb0\xeb\xc6\xf0kh\xd0\xa6\x0eN\xb4\xc7\xc3\x81\x02o\x91\xe6G~\xb0\xb2\xdb\x1e\xd9 yK\xf7_\xf7\xe4\xa42jfw\xaa\xf0/\xed\xedu\xfc%F\\\xfb\xfb\xaf\xa6o\xe9%\x12\xb6\xde\xfc\xfb^\xdd\xc0\xdf!'\x19\xf1\xd1vB\x99\xbaoVe\x99\x15\xb3\x9b7\x97Q\xb9\xda\xcc\xbd ]\xdf\xfc5M\x8a`\x15G\xc9;\x92\x977[\xf0\xdf6\xbe\xd4\xfc\xe8\xa34\xbb\xc8\xa3\xe5\xaa\x047\x18\xc1\xc1\xfe\xf4\xf6\xe4`\x7fzg\x0c?\xa6 \x1cW\x1f\xf3\x9a\xef<\x8b\x02\x92\x14$\x84M\x12\x92\x1c\xca\x15\x81\xe7O_\x8b\xdbM\xd0\x9b\xd5od\x06X\xd4c3\xb3\x842\x7frw\xdeq\xe3\x08Ab\xaf\x12$\xc8\x08\xcaU\x9e\x9e\xa1\x9d\xe1\xf5EF\x8e\xf2<\xcd]\x87\x9cgL\xdd\xe6\x03\x7fI\x92\"y\x8a(]\x8e*^\xa3\x0fr\xd0\x05\x81\x1b]0\xe1\xa9@\xc4\xc1\xf4w(\xfb\x1f\xca\x19\xf7A\xa9~\xc3\xce\x98\x8fX\x16\xf4\xfe\xc4@S\x9d\x97Vg\xde!\xc5\x1b\xde\x97\xca\x1e\xb1O\xb1\xa9\xfd*z\xc7|\x8d\xa5\x00\xaa\x97\xd1\x0d\xe3[\x98~=\xa2''\x0b]qS\xb8q\x88F\xf8\x12\xbe\xfd\xf6\x10\xa6c:\xc4\xc3\xee\x18E\x8b\xf4P\xe2o\xb4\x1a\x1f\x86\xed5cxw:2\xe1\x82\xc2\xbb)w\xc9\xc8+\xd3g\xe9\x99\xa8D;\xac\x0f\x1f\xdd\x99\xed3,\xfe\xba\xa82\x1b\xd0_\xf7F\x7f\x8e\x82\xaf\xdb/\x05f\xd4\x05f\x84\x17\xfd\x80h8\x81\xe0\xb9\xaa\x8a\xf6\xa8\xe2\xa8\x8e\xceKM1\xef\xb4[\xb2;U\x97\xecN?\xbeZ\x88 t\x9d\xb1\x98-\x8b\xe6z\xddReh>t\xb7Jy\xa7\xd3Sr^\x92\xa4\xe8\x1d\xf6\xef\x99\xe7\xd4\x0c\x9c1\xf0\xa3)1\xd7\xda\x8e\xae\x1bB=e\x9ecG\xeb\xac\xbc0\x94\x89\xef\xc5\xd4\x8a*\xf1\x98S\xb5~'\x12\xfa\xc9\x88\xeb'\xafU\xc5x\xd5\xc8m\xf0\x10\xb1B\x85\x88Q\xc1\xbf(9\xea\x98\xf9S}\x02\xfb\xfc\x0b\x8f\xa3\x02)\x9d\x14\xa1\xf9\xb9\x8f4\x0f{\x8d\xda-\xf4\xf6\xbb\x0c\xaew\xf4\xa9-\xd4\xa7\xad\x9c\"\x0e\x9d\x96\xe9r\xa9\x11>B\xdesY\xfa\xe7\x9e\xeb\x86\xba\xbfQ\x92mJi#\xcc\x04\xee\x04+\x12\xbc\x9b\xa7\xe7\x12MY\xa3\x0b\xfd\x87\xf8\x1e\x1e!\xa8t\x90(tj^\xc9\xac\x9c\x8c\\Q\xc1\xda\xe3\x1f6\x1e\xb7\xa318\xc7$ \x01'\x95mL\xa7\xe7#\xf4Y\x95\xe8\xff\xa49\xa1\xe5&\x93Pj2Q\x94\x93T\xa4\x88\xbeu\xd0\xcb\x0b\xf0%\x17\xb4\xdc\xb0ag\xd4\xb0\xcd\x05-v\xe0.f\x82\xa1\xeeG_}\xd5\xfa[-F$&\x1bD\xc3\x02\x90TC\x18\xb9\x89'$\xc618\xcc9\x03\xad\xcb\x88\x13\xcc\xbaLD^\xc2\x84\xd5PB\x91\xbfOG\x9a\x96\x14\xebCK\\\xdbai\xb2\xad\x94\xc8y\xad\xc2W\x03\xa5\xd6\x9af\x1fS\x1aX\xc9\xb4\x9b\x1a\x94\x8a\xc4\xda\x05IxT6\xce\x15.\x04N\x1e\xe5\xe4\xdct\x0c\xfe\x186*S\x10\xe6\xf3\xe6\xd5*X\xcdA\x8b\x8c\x05\xc2\x00c\x9ci\xc6KX\xea\xf6\x13\x10u M\xd3\xc8\xca\xb5WHg\\\x18\xb5r\"\x19C\xae\x98\xdbF\xf4\"\x96\xf0`k!\x0e\xb3\xaf\xbe\x02\x07\xb5Y\xb8\xdf\xd2z\xa1t\xfa$\xc1\x9a\xe9\xa2\x96\x01\xcf\xc3\xa88>\xf3\x97K\x92\x1f\xa0N\xd6\x87\xaa\x8d\xf3I\x9d\xf9\xf6\x8f?\xd8]L\xcf\xcbi\x11\x8f\xed\xad\xefW w\xabT\x8aj\x88\xc67f\xd8\x0b\x9e=\xea\xab\xaf\xc0m\xf4A\xd1\x83\xddZ\xaa+`\xef \x07\xb0\x1e}tY8h\xb2Y\xcfI\xfe\x9a\xeb\xc7F\xae\xaf\x88\x93\xeb{q\xc90\xdd\x1d}\x9c|\xedU\x12\x86_\xa28~E\x02\x12m\x91;\x91\xd5\xdc\xb7\xce\xc5Ps\xea\x9fxw\x99R\x88G\x97\xda\x83Hd\xa2\x02 \x1b\xee\x84\x1cf*3\x9a\xcd\xeeJ\xab\xed\xe4F\xad|\xd4#q\xa8\x07,%\xf5h\xc4Q=\xd9\xac\x91w\xf5\x81\xe5b\x88:\xf7u\xad \x17\xcd\xc6{53lJoP\x18\x86\xd2\xd84\x1b\x8c\x03\xa1\xff\x9d\x893#'\xbfm\xa2\x9c\x84\x8cT\xe1\xae\xf2\xd9\x19L\xf72\xba\x89x\x8b(/J\xb7\xb3\x01\xb1\x90e\xc1?+jZ\xdam\xc7bTe\xd1\xee\xee\xb4\xfe\x86lo<\x99\x18\xf4\x01\xbc\x05\xec\xce+\xc3q\x9fX\xee\x8f|@V\x8e\xb4\x865\x98\xcb#.?sm\xaf\x9e\xd7 Z{\xfe\xa6%\xaa\x0b\x95\xb7\x1e#\xad\xe9M`Mo\xc2\xea\xb3\xe6\n\x0f\x85\x91\xde`\x95\x07cj\x11\xafX\xa5gGB\xdde(\xef\xc0\xa0\x1f\xa5\xebu\x9a\xd8\xbcs\x81^\xd9\xce\x8fE\x9a\xb0\xcc\xe7O\xd2|m*)\x9b\xbb\xcc\x98\xfc=\x0b\xaaQ\xc2\x9e\n\xc7\n\xc6n\xa8\x01\xcf\xe0\xb0\xc9\xa2\x9c\x9a\x0b\x98\xceM\xf6\xac\xb6\xc1\xc9`\x15Y$Zk6\xd4\xf6#\x83\x95)\xa8\xec3\x85W\x15S\x10\xd8\xea\x06\x06\xbbP\xd0\xf4\x8f\xa2\x9fh\xa4\xf3\xc1{\xf4\x135\xcd$E\xd9\xc8\\hot\x92\x91I\xbbwk\xf3\x93\xa1\xf4X\xc3\xc2\xa3\xc9\x05\x04\x83\x8b\xb65\x8dL\x81\x12R\x97\xe1\xe4\x88\xe1\xafm\x0d\x8ds\x06nSC\xe3\xb8\xb13\xb8\"\xddT&\xa4 \xde\x94!MEC\n-\x93\x12P\x89^\xfd\x81\xef\xea]\xb9H\xf3\xb5\xaf\xed\xe5\x0b8\x04\xf4\x81^!7Rv\x18\x11\xed\x86x \x87\xf0\x82\xbdP\x1a\x10\xf45%\x00\xb47\x8f\xfd\xd2wL5\xf8\x9eS\xe8'\x15t\x94\xd4\xa1\xe5\xea\x97\x9e\xd6\xc3\xae\x19\x0e5\xf8\xaf\xa2\xf3(\x0cD%Y\x17T\x16\xc0\x81t\xab\xc95\xaf\x9f\xe0\x10\xde\xc1Cx\xd7\xe5\xa1\x1cM$\xe7+8\xc4\xc0GW\xd4\xa2\xe8\x12\xf0\x91[Vy{\x95_y\x0c\x87\xb0n~e\xe0\xfb\xcf,\x12Y\xbd\xb1\x80\xf9\xcd\x02\xe6 \x1c\xc2\xdeT\xab)h0z\xcc\xe9\xfeY\x8dOl=:\xec\xe03:v\xda\xc1gM\xbew\x8c\xfd\xe1\xb7\x84(\x87\x86\xe37\xf5\xf7\x04h\xe3koh\x9bo\xea\xf0e\xda\x03\xec\xf5~\x1b\x8e\xf5\xed\xb7\xfa[U\x1b\xe3f\xccB\xd9\x15G\xb1\x02FWL\xd6z\xa4\xe8\xf3\xf6\xb3\xdc\xfbH\x17&\xa8\xb0\x99\xd9\xba$4\xdf\x8c\x12\xa7\xe5\xde }\xe9\ns\xf8\x0fq&\xba\nC\xffSx\xd82#\xd2\x06\xa1\xa2\x070\xeb=T\xf6\xa6=\xb9\xf8au\xc6\x00VF]\xddC\xabT\x0dA\x1ac\xbe\x10\xdaS\xf5\xd9\xa7\xea\xaf\xf3?\xff\xef\xefN\xc3\x8f\xee*f\xb39Y\x9a:\xe9cx9\x86_Q\x0fu\xe2\xc0\x0d\xf8\x15n\x80\xf3\xd6\x19\xc3w\x18\xc2\xb7\xf3\xac\xb5z\x92\xa7\xd9\x84\x9fg\xca)p\xffJ\x1b\x1d\x833\xd2o\xb5\x1d\xa7 $YN\x02\xbfT\xad\xcf\xfbq}\x96\xd6\xdb\xbf\xf1\x16\xc6\x846\xfe\xfep\xab\x15i\x9c\xe4\\g\xdcb\xdbq\xba\xc6\xb0\xa4}~%\x94\xe3\xaf\xae4G\xfa\xb1\x89\x9dgnW\x14o&\x14\x83\x0c\xeeR\xe7\xff\xb0H\xa9~\xfe\xb3\x1f\xeb\xcb\xb0\xc8g\xa8N\xa0\xbf\xa63\xf2X\xcc\xc8\xe3\xff\xf8\x19\xb9\xc2\x1a+;8wV\xdb\xa9\xe1\xe2\xa9!\xca\xe7Zz\xcc\xeb\x9f\xc8\xbei\xc2\x8a\xbd3\xd4\x0b\xc3\x1f\x7f\xc0\xde\x13\xb3$\xab\xed\x87\xca\xf9\x85\xb2+\xea\xb5\x14\xbdw\xbe\x89\xbe\xfdn\xebG1\xa6\xe2@V\xb4\xf8\xe6f\xf4-=\xe6\xe0\x06\xbc\xb1\x88\x8eo^\xc2|\xaa\xc1\x8f\xda7\x8f\x07\xf5\x8eU\xc9\xcd\xde\x8fZ3\xd5\xe0\x94~\xfb0s&\xd82\xbbi\xe3*A6i\x8d9\xfbM9\x98\xd7t,{\xcf\xb5'Z+\xcb\x13\xc6\xdc\xce\x0cY\xed*)\x07\xcb\xebP\x94\x8a\xcc\xd3\xa3\xad$o\xd0uX\xebM\xb8N\xf3'5\x84`\xabf\xf0T\x0d\xd4\xd8Z\xf2\xedVK\x9d\x8c\xd5\xa2\x14\x0f&\xd0p\xb9m\x83\xcfXx\xbd%\xef\xbb\xabV\x84\xd0\xc5+fB\xccc\x7f\xea\x1a\x12\xf5\\^(\x11\x087\xc3\x0b\x0d\xc5:\xd2-\xab\xf5\xba\xd5\x0e\x96\xdd\xba\x88\x06\xa4\xe0\x0e\xd9\x9a\xacVvZ\x1f{\x8d\x8f\x98\xb3\x8e\xd6A\xb3*\xa2\xf6\x8d<\x89\xa5\x84H\xefX\x01G\x816M\x1d\x8en\x9a\x84K\xda\xac\xa9\xc9\xa9\xec\xe0\xc7\xa4,\xa3d\xf9$\xcd\xdd\xa0'g4\x183\xcdD\xd4>k3\xf8\x89\xb96PY\xf5'\xe4U\xd4\xaf %\xa7~\xf6\xae\xca\x89\xf9\xfa\x97R T\xaeT\x81\xca\x95*P\xb9R\x05*W\xaa`\x98+U\xe0\x16\x8d\x8e\x06jO\xe2\xe0\xe3\xfb?-l\xfd\x9f\xbe\x04\x98\x0b@\xfb\x00\xf38\n\xde}j\x87\x17k?$R[?4goevS\xc30\xcb\xe0\x1aU\xferma\xe2m\xfd8\xe2\x85\x1e\xfcu\xe1\x9e\xa4c\xf0\x91\x02UO\xbe'\x8b4'\xfcp\x12\x00\xa8\xb7\xe3\xb3\xe4\xa5 \x7f\xca|::7\xdd\xd1\x18\x12\x8f\xf0?4\xc7\x82\x18\xb4\xf6\x04\xce\xf0\xf4\xd5\x9c\xa3kn\xe1\xe8\xfb\xec\x02\x12*\x837\xda\xcb<\x0d7\xc1\xb0\xb8\xfe\xca\xdb\x8f\x8d\\\x92r\x80\x7f\x94\x19\xc9O\x04 \xae^\xf5\x1a\xeb\xf8\xdb?i,\xbf)\xf6y\xce\xa2\xabme\x93y\x99\x00G)\x10\xe1G\xfc\xd8f\xa9\xa6\xae\xdb\xb1\x8d\x19X\xee\xab\xb2\xc6H+\xa0I\xd3\xc9\xf8\xaat2\x1bU:\x99B\x95N&\xe6\x0f\xe4\x15\xd0Z\xb9c\xaeY\xc6\x98\xfeG\x84\x1e\xfa/\x0f\x1e<\x90 \xe9\"M\xcac\xa6\xcfv\xa2\xd2\x8f\xa3\xa0\x1b\xa2\xd3\xfa34\xd2'\x03\xe3\x00m\x1a!)\x83\xd6\xab\xbb\xa4\xf6\x93\xee\x94\x1fc\xc72\x03\xaf\x18\x02#\xff\xdb\xe9\xd1\x8e\xa5\x9b\xc0L\xb9`\x00\xf5\x82\x81\xfeEP\xb1\x08\xc62@\xc0\x19\x04:\xac\xb6\x17\xd1\xc8u\xc4\xd6V\xf9\x05C#\x94\x06\x9ae\xe1wVyC\x87\xd0\xf2\xfe\xeb\xe39\x01\xf46&C>\x06\x90\xb7yz\xaaI\xca\x00\x9c>\xff\xc0\xcb\xa9\xea\xe3\xe4\x8dI\x06@\xde\x85\xdd\x86;$\xd3\xc0\xd0.M\xf2\xf4l\xd7^\xed\xd2\\\x90\xc6\xfa\x05\xb8l\x92\x02\xd8\xb1\xddV6\x82\x8f\xdf<\xf3\x1a\x1a\x90\x05\xa1\xf4HR\xe6\x17\xb2\x12\xb9&\xdd\xb1\xf0\x01\xee\xc8?d\x0c\x07\x06\xbf%\x10\xee\xbb'\xfb\x9ax\x10q\xa1\x0b\xef\xc9\xd4\xa2\xda\xcf\x9e$\x1f\x83\x1b\x8d\xaa<\x81\xeaL\xd5\xe2\x12N\xbc\x91\xd7\xf1\x19\x7f;\x12N\xb4\x1dOr\xee=\x02\xb3\xc6S\xa3G\x89\xb86\xb2\xa6Z\x0e\xec\xfa\xee\x9a\xd8W\x8b\xbd\x0c\xe2HJ\xb5`\x97\xf0\x0f\x10\xd7P|\x06\xd6lz \x13\x94\xb8vl:\x92(\xa3?]o|^Fb\xa39H\x13\x9b\xf6)\x97\x80\xb6CGx\xcb\x991\x95\xbe\x83\xa6D\x83\x97\xa0\x80\xe5\xdcb\xa6\x1f\x94F\xfdX\xc3t\x93CHS\xbd\x83\x94c\xeb\x88?x\xcbP\x82\xba)\n\x85x\xf7\xba\x89B\x9fT\x83\x19\xc8\x04\x1e* \xb9\x81\x10xP\xdc\xf93\xa8/\x1b\xfc\xbeDK\xd9g\xf9m#5m$\x90k\xaa/\x19\"m0I\x83\x84Q\x99\xe6F\x0d#SF\x92<\xb7P\\2md\xec_\xa4\x9b\xd2\x02\xbf\xb3p\xb9#\xcc \x884\xdcH\x18\xe55\xf8\xf3\xd5\x07\x84\xcaL\x04\x82gv\x8a\x8c\x04\xe6\xe1\x84W9\x9c+\xeb<\xf3\x0b\x93#\xc8h\xa7tj\xb6\xfc\xfc\xa2\xcdL\xeb\x93\xa7C+\xcc\x19gA>\x05\x0c?u\xc7;\x9e\x95\xa5\xe1h\x14\xec}\xd9<\xa2\x94V\xea\x9d\xf6jo\x9f\xaa\x8f\x9f\xf7c,Mgh\x86\xe9\x90\xf4\xa7\x87\xd031\x7f\x1fVg\xaf\xe9+\xcd\x99\x0fx\x08+\xb7\x03\xc5\x1c\xc3\x1a\xae_\x02\x16Co\xc4\xcd\xcc/W\xf8\xbe\xb2\x1f\xc5\xda\x8f\xe3F-F\xbf\x84\xee\xeb\x0d\x7fW\xf5gt\xce\xebFw\xff\xb3UT\x92\xe3\xcc\x0f\x98k;\x99\xe0\n\xabw\x95U\x15Gi\xaa\x01>\xb05)\n\x7fI\xb4\x07\x8b\x16]\x8cC\xc2\x8a\xa0\x93\x90\x04)3\x91;3p\xb0\x12\x8aah\xc1&/\xd0\xdc\x94\xa5QR*\xb9\x1f\xd9\xd8\xb0\xb6\xb5\x8e\xe6i\xaa(W\x07\x7f\xe2\xcd\xa3$t\x19:\xe4R\xbb\xb6\xf3\xe3f\x9dA\x99\x02\x1d\n\xc5\x96\xbc\xd6U\x88\x1fm\xb24\xd4\x04\xb6\x13m\x91C\xe5\xbc\x8c\x8f\x92ZtwJ\x8e%h\x9fEE\xe9E\x05\xfd\x8f\xdb\xd9\x0c\xf6\x9bI\xb2\x97\xb8\x9f\xb0\xc7v\xd5%>\xc4\xd2\x804\xc8!\xfa\xe3&\xe8\xe5\x91c\xcc\xa4\xdd\xa7\xd3\xa4Z\xc6\xd6\xe7v\xde\x19\x9f\x90\x90Z\x13I\x0c\x0fB\xc4\xfd\xc8$\xcd~3\xff\x99 \xd5\x95\xd2\xa86\xd6Z\xd1\xab\xf6+\x06\xda%\xd3\xd6\xad\x94\xda:\x17\xd3k9\xce\x88W\xa4t\xc0\xb1\xb1\x1d \x11\xfcd\xff\xadW\xa6o\xe8va\xf5\x8a\xe0\x06\x10\xaf\x88\xa3\x80\xb8\xd3N\xc7\x04-\x81^\x1d10\xa7\xccm\xf2\xa4-\xa51\xfb\xc2\x17\xbd.\xbf,\xf5\xbaA\x95\xbb\xefO\xa3\xe1\xfd\xe2\xa0jQ\x01\xe9\x12>\x87\xe2\x13u\x12O\xdc\n\xd7\xd0\x93\xb0\xca\x92\xf58\n\x9f\xa7\x9bD\x16Td\xab$\xaf\x95\xe3\xcdl\x1fE\x95\xce\xa837\n\xf0*?R\x7f\xb2\xda\xf3!;J>`\xea/\xd2\x1bT\xfbN\x9d\xe6\xa9s\xbf*\x9d\xcf+)0\x9dH\x13G\xa4\xc3\xbf\xc4\xf8?\x81\xb9\xa39\x04\x93\xb5\xa3\xe2\"M\xa6\x0e\xec\xaeV%\xddv\xb3\xda\x89\x89\x82^\xc8&\x8edR^dD\xb0\xb7\xc8f\xba ?\xfe\xa5\x9f\xd1\xe9\x11\x0b4\xd6\xec\xd4\x03s\xcd\xf4\x9c\xf5J\xab\xf7\xd5\xc4\x85\xa9\x06SZp6\xe22\xe9fR\xe6C`\xa5\x953\xe8\xdb\xf8\xa05\x81\x9bR\x8fm\x80\xaeE}\xc7\xda\xe9z\xa5\xdbB\xcf\x98I\x12@\x8fzU\xa9\xf9\x08\x93^~\x93\xe6\x16cI\xb5co\x91\xa7\xeb\x1f\x8fG\xee\x89C\x0f\xb5(@.\xff\xe6\xafE\x9a8o\x1b\x9c\xe3\xf8\xday:\xd3\x1e\xbd\x10!\x06\xcf\xa2\xe4\x9d&5\xfcug\x10\x13\xf7\xb6* \xfdg\xc9\x18^\x05?\x98H\xf9\xc1\xa8\xe2\x07\x93\x11\xe3|\xf6\xbf\x86\x0d|\x03\xc9\xd7\xb0\xa1\xfc`t\xb2i\xf3\x83\x1b ?(\xf8\xcd\x0f\xc5\x08F#M\x12i\xcc\xb2\xf8\xda_\xa2\x05\x17u1\xa7\x8d\x1bLx\xa5\xccn\xa1X,\xb8B\xe6\xad\xd9\xb2\xc5i\xaf3:5\x98\xb1\x96\xc7\x003\xfd)\xf2F\xb7\x87\xa8\xe6G\xe87^d\xd7\xb9\x87\x9f\x80c\x1a\x14\xadf\xed\xf4\x91\x0fq\xfaH\x07\xa4\xcad eK\x7f\xb9$aE\xb8\x0b]\xc6G\xcc\\lv 11\x0f\xf6\x8aB;\xee*\xdd\x92|\x1b\x913S\x8d\xc1\x17\x1c\xceA\xa1p\xb0\xf56\xad\xad\xb7U(\x9d6\xaa\x1e\xf8$\x9f4z\xe8/\x0bg\x0c\xa5\xc1Y\x98y\xcf\x08\xa7\x92\x08\x1dI\x8c\xb6\xe2\x9dye\xa86M\xd5OT\xc2*_\xb8\x84\x9f\x05\xec\xe4\xb6\x00\xf5(sF\x1d\xe8\x9cl\xd4\xee\n\x00=;F\xf7jbPL\xd9\x95\xe6\"\xe9}\xd3\x85\xef\xaa3A\xa7\x87\x1b\x0e\xf3\xa2S\xcd\x89o\x9a\x90\xda\xef\xc1\xe0\x93j\xf4}\x00\xd6\xc3t\x00\xab\x0f-\x0bN\x992\x86PG\x06\xc4U\xa7\xeb7\xc32b\xb36d\xb0\x15\x17\xf33\x8b, \xe9N1$G\x05\xce\xde%\x0d/\xad\xc6\x06\x1e\xc3\xc6\xd29}g_\x0b\x10\x1b\xcc\xa2\xa7\xc6\xf8[q\x898\\C\nSzE\xe1\x0c\xd2*\x19\x93\xc5\x0bt\x8b%Z/\x9c&\xe4\x8b\xec\xa9\x19u\x9b\xc0/s\xb2\x88\xce\xb1\xb0]\xbd\x0c\xc6\xb7W9Y\xcc\xc0\xf9K\xf5\x12\x8e\xc6\xa2\xd9\x8a\xde0\xda\xa1'\x1a\xb6\xfe\xdbR\xb0&\x08&\xca\x8f\xfeM\xe0\x1bVUDM1o5\x0c\xfa?\xa5u\x9cv\x01L*\x0b!J01\xc9\x1eHm&\xad;\x03\xe5[\x83SI_\xa4\xb3\x12D\xa4\x04\xc7Z\xe4\x10\xd2\xc6\xae^\xc9\xcd\xfa1\x1a\xbe?i$.H\xbcS\xfe\x077VQ!\xb0=\xaf\xff%\xf9\xc4\xe5\xf9}\xde\xea\xc7\xe5S\xf964\xb1\xa8\xed\xed*'\x91\xcc\xc3\x98\x8fb\xe4\x9e$\xc8\xdc\xc0\x1e{[V\xe4\xbf=\xab\xd7\x8a\x81\xd7\x1d8I#\xd7\x83\x89Y\xc7\xa1\x9b\x98tJ\xcev\xe2\x9fc\x8fnE\xdd\x99\xc3(\xa5\xe6\x0c1\x9a\x99\x81\x87J\xffB\xa2\xe5\xaa\x9cAN\xb9\x9dy\x1a\xb3,\xa4I\x9a\xaf}m\xfc\x9ez\xec\xb2\xe4\x00j\xf0\x96wl\x9c\x06\xef\xaad\x04\x94e\x1b\xee\x05l%z\x08\x9f\x0b;\xe9\x83\xce\xca$\xf6\xe7$\xc6\xf3HQ#|\x0cI\xdbT\xbc\xb3/\x03(\xdbW'\x1f\xb4\xb0=\xd8\x1c\x1b\xff\x05\xd7B\xcb\xf84Y\xa4o\xf2\x18\x8f'\xfa\xfb{\xbf /\xfdr\xa5Q8JS+\xa4\xaa\xd4\n\x91*\xb5\x82\xafJ\xad\xb0Q\xa5V(T\xa9\x15\xe2Vj\x05\xb4C\xb7\x01\xea\xdc\x0b\xdcR=\xdd\xbf\x16\xa9\x17zsn\xc5\x11h\xdc(\xbeD%5\xe1\x86\x9eY\xab\xb4\xd0\xe8x\xd8\xa95\xe7\x8b\xb5\xd3q3(\x16\x84\xb64\xd9\xe4jR\xe4\x9c\x00E\x1dx\xf3\xea\x19\x96\xc1-\xd1g\xc1\x81\xb7\xbb$\x80\xd11\xb6vn\xd1\x06\x0c\x85O\x8c\xa5\xd0\x9b\x05\xb8\x12l\x053\xc6\xc2\x00\xac\x85\x81\x98\x0b\x15\xf6\x86~i\x90\x89\x93\x01\x1aM\x00h:\x9e\xf3\x94\x9c\x7f\xfc\x01N\xb9\"\x10\x92-\x89\xe9\xc9c\x905\xd3\xfa\x0b\x14\x93-\x14|\x1c\x9a\xac\xfd\xc8\x08\xefc\xf2<\x87\xb2p\x16\xf1\x1fV\x8cL\xaa\x15/mX\x1e\xa3\x86\x8aq\x94.\x96\xf5*\xfc$*\xa3\x7f\x937y\x99%r\x90\xfb\xbb\x9d8\xc5\x14\x9e\x945\xd4\xb1\xf3L\xb5\xb9\xc9c\x1d\x10\xb3\xd3\x08\xee\xc4\xe4\xe5^\xa2\x0c\xa9\x83bR[S\xca\xd3A\xc7\xcc\xea\x83L\xee\x15x\xcdc\xee\x98\xbc\xcaV\xa8\xa6\xe1\xb1\x8e\x86\xd3\xdeh\xf99\xe4\x984\x829c\x085\x06\xbc\x9a\x19\xd4\x9cZ\xcd9\xd4\xba\x91\xb6\xcfA\x85\xa3\x8d\xfa\xa4\xb8\x949\xb9y8\xb0\xda\xfe\xd7\xedp(T\x87C\xa1:\x1c\n\xd5\xe1P\xa8\x0e\x87\x82\x1d\x0e2\x92_||\x92\xaf\xd7\xa0\x7f!\xf9\xe2\xb2%\xf9\xc2/v\x97 Z\xc6\x1cXo\xa1\xf8Zn\xa1\xeb\xc1_\xf5\xf7\xd6\x17v\xea\xcf\xb2\xb7v\xd6/4u\x0b\x8b4Ugp\xfa\x8f;\xf7\xae\xc7\xa6\x157\xffDB\xd1\x97\x94B\xda\x94BO0\x9f9K\xff`4\xe5\x03\x9fO\x1ed\xd7\xc8 $\x17\x06\"i\\\xf4&\x0b\xfd\x92\xb0\x86e\xc6\xdbO\x9e{\xe8\xd2d\xf2\x03K\x9d\x83\x82\xae\xa5\x96\xfdG\xa9\xd6\x90B\xe9\x8e\x13\xa7~\x18%K\x96\xd5\xb8\xf4\xf8\x9f\xc7\xa5_n\xb4B\"\xc5[g\xe1G1 \x07\xbf\x8bn\x85^\xb0\xc9s\x92\x94\x1cC\x0c\xd2\xeb\xef\xef\xb5\x82(\xba\xde\xb9\x1b\x0f\x0b\xea\xd1\x9e\xe5$tF\xdc\xdb\xb0y\xff/\xbe\xefk\xb3\xa07%W\xfa/\x8e\x0dmw{S\xfe\xbb\xaa\x1a\x7f5\x07$\x8e\x1f\xebU\xfaQ\xb2CN\xfa|XK rf\xaa'|\x9d\xce\xa3\x98\xcc`z0\xb4/N\x94d\x1b\xfbTCut$\x9f\x05\xfe\xba\xf2\xe5,\xf6\x03\xb2J\xe3\x90\xe43p\x18\xea\xc0\xfc\x02J\x7f\xa9y\xab\xbc\xc8\xd0\xbeE\xceu\xdf\xee%*j\x12M\xf5k\xd5\xc1_c\x8aS\xe6\x1b\xe2T\xd8\xe28\xa0U<\x84U\x81qs\x14\x94\xdcn\xf6\x81\x13x_O^*S\xf1R\x99\x8a\x97\xcaT\xbcT\xa6\xe2\xa5\xb2a%\xc53\xca\x15\xb4\xeeb`L\xa6\x89\x9cY\xe0\xc7\xa6\xfbR.,\xfb\xf8\\X\x08\x87\xf0\x84\xb7\xef!\xebAwO\xbb\xcf\xfa@\x1a\xe8\x84\xd7v\xf0\xa4yYse\xc0{\xa7\xe6\x96\xec8%\x11iK\xfb\xa4Wmn\x19|\xc4B\xa3K\xbf$\xd2\n\xae\xe2\x8a\x8a\xa30*\xbfO\xcfg\xb075\x12\x0bGI\xe4#\xc3.\x86+a\x80`P\x02F\x18\xc0\x13\x81H\x95\xc3\xd8?\xacq]4\xa7\xbef\x96\xac\xcdc\xaa\xd3dx\xb6E\x90\x8cD\x9boB;\x14U\xa2\xb7\xa1#\xf8d\xfel\x8c\xcf\x14\xe7\xde\xa34)6k]\xfeD\xa8\x9c\xd62?\xf7\xd7z@\xe6\xb5\x16\x15\xbcf\xb6\x1e8\x1a\xc2\x1eC\xe5\xb7\x96\xf9\xe5\xea\xb9E\x9a\x8e\xcd\x003\x0ep\n\xbfq\x9d\xefYE\x1c\x0dk\n\x9c\x82o\\\xe759/\xbf\xcb\x89o\x02\xcf\x18\xf8*Z\xae\xe2h\xb9*\x1f\xa5\xa1\xd1\x81,d\xef4R\xf0\x99\xde@\xef\xed\x08\x8bg\xe2Z\x91\x92\xe4\xbfD8[\xfe\xf7\x17OC\x92\x94Qy\xe1\xfa\xdc\xe7<\x1fyu\xd9\x94\xc2\x19s\xd3\xf7\xb3\xa8(Gn\xf7\xc8\xea^[,\xa7\xd9\xe8\x1c\xdb*\xae\xcf?\x9a\x93\xdf6\xa4(\x1f\xd9\xf7~\xddBb\xfai\xc4\xccN*Wq[\xf8,\xc8\xde\x98\xd5\x8c\x0c%\n\xd5\x03}\xfbK\xd1>\x12~=\xec\x05\x1c\xc2\x92\x89\xc7z\xc09\x02V\x07\x85\xd1[\xed\xca\xaa6\xcf\xd3\xf0b\x82X`\xf0zpB\xbf\xf4\x19\xe4\x04c6f\x907#8\xec\xdf\x8e\x92\xfa\xdd(\xd1\xd5\xfc\x1a\xc3\x9c.k\xaa\xa9\xae\xb9\xd8m\xb0\xa7\xa7\xc8\xf0\xc3\x0dpW\x0d\xeb\xa3\x03Q\xb2\xf5\xe3\x88e\x070\x0d\x8a\x93\xdf\x0b\x03\xadk\x8b\x0e+? c\xf2\x82\xdfT\x8f\x9d\xee\xbc\x0b:z\xd5\xc8\x8d\xce@\xaa\x91\x13\xab\n\xa3bp\x9a\x1ej\xca\xae\xee\x8e\x86\x13\x96\x91U_P[\x87\x11\x97i\x9b\x84Q\xa9mX\xd5h1\xa0\xc19\xa6\xa0(\x13\x08\xfc$ 1H\xd6\x86u\x04D%\xb50*\xd5PF\xeck\xa4\xa9(\xd3\xe52&O\x05\x99\xd1\xef\xbc\x87\xe0<\xc2\x1ebG\xe8+u\xd5\x02\xcd\xd2\xb3\x0c\x0e\xa6\xf9X\x95\xeb\xf8 \xd6q\xd8i\xbe\xdb\xf1N\xceKq\x8c\x89L\xb4\xc0\xca\x92\xa9?`\xf4U\xe3\xf8\xbf\xd5Oo;\xf1\xad\x89\xeb\xa9(\x81\xc1\xf9Z\x81\x9d\xad\xe4\xcb\x9a}\xa9L\xea\xd4\xbb\xab\xf0.k\xc7\x9c\xd4\x87\xd1\xaay\\\xf6D\x1eq|\n\xdf8m\x02\xe0\xf6\x04\xe0\xf8\xba\xef\xfd\xfe\xbe+\xbfW\xf3\x17\xca\x1f<\xaaz\x10V\xcf\xdf\xb7\x95\x03\xdb\xa6x\xda\xe5\x97\x9b\x98y\x05\x89\xd9\xfdY\xcdLDU\xde\x10T/\xa5B\xbd\xa4\xd0\x1cQ6\xf9\xe6\xf9:\xbe\x19y%)J*\xceJ\xe1(\x83\x8c\xcbf\x02D\xab\x08<\x84\x84\xc7\x80\xd0\x9e\x9e\x9e\xafYu\xb0\xe6M\x99\xe7P\xb4\x00\x97w~\xef\xf0\x10\n\x9db=\x86C\xd8C\x8e\x0f\x93\x17\xfe\xfe\x9e\x8e\xb2\x903M\xc4+HyLY5W'\x1c\xe1fW\xd4\xb0\x1e\x8d\x9b9\xf1\xf5\x9eH\xc5?\xd7\xb1V\xa1\xd7P\x06(\x12\x9cK\x94u@\xe2\x82\xe0\xdc\xb6\x92\xf3\x17x\x0c\xb8\x0e\xce\xb1\xaa[\xfa.i\xbb\x83L\x88\xacEMc\xda\xcf\xb5)\x0d\x17\xf8\xd97\xad7\x14\xd1I\xafXvK\xb7\xe3R\xae$J\xbcE\xe2E\xc9\x82\xe4\xc7X\xe2\x7f\xe4\xe6<\xdaF\x9dg\x8d\xbe\xb7\xa0h|\x8c=\x16/\xa6\xa8\xefT\xcc\x07+\xb0\xf0K\x1e\x95\xe4E\x12_H\xf3]*\xe6EL{kf\x14\n3\xa1\xf7Lj\x19B=~\n\xf4\xcf\xb5\xa44\x99q\xaf\xf0}\xa2\x90\x90\x0d\x8bOw\xd1i]bc\x0c\xa9|\xdc\xa7C\x06\xee\x92N\xed\x0e\xf8\xe3\x0f\x08G\x0c^\xfa\xf96\x03>\x14\xedl\xe8p\xde%\x98\x89\x82`\xa6\x1d\n\xac\x82\xa3\x84=\xa7Bl\xcb\xe0\xea\x95y\xb4vYA6\xbd!\xb6\xb1\x85\x95ek9\x99\xe8\xc7\xba(\xb0\xb3\xc3J\xea\x8eUh\xa8\xa6k\x0c3+\xd9\xf8;v\x8aURc\xbe\x14^\xc2\xfc\xa8\x0c\xc9\xef\xe5\x96\x8e\xeb\xe9J\x7f\xdd+\x10\xd0\x1f\x0f\xee\xdf\x1a\xfd9\x8a\x10\xfc\xf9\x1c\xc2\x189|\x92\x06\x9bK\x96 \xe2$\x88\x15\x94\xa1\x1cB\x98\x068\x0e\x8f\x9c\x93\xe0Q\xba^\xfbI\xe8:A\x9a]\x98Sd\xc9\xa8\xd4\x07\xf3\xcc\xf0\xb8\x12R\xcd\xb4\x95\x9ck\x88\xeb9%W\xe0\xfd\xae\x0e\xce\xac\x8bK:\x8fX\xee&\xd3\x17\xd5T\xb2]\xbf'\xa3\xd2dQ\xaa\xb3\xcb+\xdb)\xc9y\xe9\xe7D](\x11P\x14CTj)\xbb\xf0\x8ezrs\xe2\x87\x8c7b\xb6q5dk$tZ\xd4\xa0V\x89A[\xc52/\x91\x0bT\xb0E\xf2)\xfd\xa0\xe6\xf7\xebP0\xa7\x7f(m\xe8\xa14\x95\x9dJ\xf4\xc9\xf4\xbe\xecX\xa2O\x1eLUqlj\n$\xbc\xd1N$\xa5\x08(\xe3&\xab?U\xd9|\\gE\xfc\x90\xe4EW$\xa5\xe2h\xe9e\x9bb\xe52T\xc3\x84\x9d\xec\xef\xc9?\x9d\xb1x\x9d\xe5\xd1\xc5\x18N\xfe\xf8o\xce\xdf\xb0zf\x9d\xa1\x08n\xc0\xdf\x9c\xbf\x8dx|\xf4\x06M\x12*V\x93\x9e\xaa{\xfbrTC\xb1Wa@\x0e$9C\xc5U\xe6\x17\x8a\x8dP94.\xc6h{\xea\x9c\x1b\xdd)\xf2HR\xe6\x11)\xa8\x90\x04{.\x16\xba\xa1\xc7i\xe6%\xe4\xbctG#/L\x132\xfa\x9a\x8f\xc2d\x8e\xc4L`6\xd6\x91\x15\xefZ\xe3\xc8\x0d\xc7p`R\xcfS\x9e\xedd\xdfP\xa1b\x8dPS\x89#\xa6\xb8(\x12\xad\x1b\xab\xff\x038\xdd\xd5\xde\xc2\x0dpf\x98?m\xcdW[N\x0b\xfa\x84\x00\x02\xbf\x0cV\xa0>Yc\x86\x11\xb8\xc2}{\xc1{XD\x89\x1f\xc7\xaa\x15V\xaf=\xbd\x98\x12%\xf3\xf8\xa1\xd5\xf8\xed*\x06`h\x0e\xf8\xd6\x89GP\xae\xf2\xf4\x8c\xbb\x07u/\xc9<\xfc\x97\xfa/\xfaA\x8e\x8a\xf34\xbc\x90\xa5\xd6\xa1 \xcez\x13\x97Q\xe6\xe7\xe5\xcdE\x9a\xaf'\xa1_\xfa\xcc\xd1\nG\xe6\xbc|q\xfc\x9a\xfd\xdd\xdd\xbb\x1aNa\xa9\xd9\x8f\xc0-|:\xa7\x8e\xb9f_\x82q}\xaa\xfdy:\xc6\x8c\x1c\xf2\xfd\xc9&\x057\xe7\xc51\xf9\x8d\xefN\xdas\xf7\x14\x0e\xe1\xac\xbb;\x97\xc6\xdd |\xf4G\xfd\x8dw\xca7\xacq\xfb\x01\xcf\xf5qd\xdc\x82\xc0\xb7\xe1\x91v\x1b\x02\x9e\x08|\x0f>q0h>J\x8a\xd2O\x02\x92.j\xae\xdb{\x12\xa1\xb0\xd0\xda\xa0\xe7t\x83\x1e\xfe\xffq\x83z\x89\xbf&\xf4\xef\xaf\xcb\x8b\x8c\x1c\xb2{\xf4'\xdf\xb9(P\xf7\xde5\xeem\x90\xe25X\xedq\x10\x98\xb4?F\x8c\x91\xdb\x05m6\x9f\x1e\x9f\xe8\xb5\x87\xc1\xfcg\x8d=\x7f\xa6\xdf\xf3`\xd94\xf0}x!\xf6\xfe|\xe8\xabe\x0f\x1b\x94\xb7#E\xb5 \x84\x97\x13t\x07uo\xfe\xeb_\xc9\xcd\xe5\x18\x1c\xa7\xab\xd8\xe3\xe3/e\xe5\xac\xdb\x1c\x8d\xcf\xb9\x93[\x8aJz\x9b\x8f'\xc4^7F\xefK\xcc\xca\x97\x98\x95O\x11\xb32 Z%B\x95c\xb0\"k\xab\x9a\xd7\x0dp\xab\xcf\x0b\xf1#29\xd5 c\xa0.K\x1b\xb3\x072\xbeD\xc1/\xa0#\\U_\xb0\x1e\x19\xe2J~\x0dCiZ>\x98\x97\xad\xe3-Q\xde\x148\x01\n\xeb\x1f305\xd6\xff\x9aV\xf0n\xba\xa7\xb1\xd0\x17\x8e\x82H\x9b\xf8\x10\xebr\xdd*p\xcc\xa3\xdb\x1b\xb3x\xfd\xf2c\xff\x00\xca7\xbd\xd2\xad\xea\xbc~_\x91\xf64\xec\xa6\x993;\xae\xd4N+\xbcW\xc3\x95h\xc6\x94\xa3M\x1d\x17o\xc5T\x0e\xf2\x98wF[\x89\xc5\\\xe7[Q\x8c\xdb\xa8\xf6R\x16\x8a\xe1d\x16E\x92\x01u\xfcL\xebdY\xb2\x9b\xf7\xce\xa0Z`\x85\xbd\x95 \xb6%\xbbM[jw\x05\xdf\xf5\x8c\xaf\xf9\xc2\xf7} \xbe\xef\xcfg`\xfa\x14gF\xcd\"\x99\xce\x0d\xcb\xb0\x82|@\x90\x00s\xb1\xa8\xc2\x17\xf91\xac\xd1\x96D\xf8\x02'\xf6\xe6\xd8\xd8\x82\x04\x9b<*/\x1e\xd3}\x1d\x95\xa6Z\xc7t+\xe5\xc6x\xdf\x98A\xf9\x9br\x95\xe6\xd1\xbf\xc9\xf7%\xa5\xb0{\xdd@\xb6\xe6\x15\xb0W\xc4Qx\x05\xf60\x8c\xd4\xe5\xc5&\xff\xf8\x03\xfd\x9d\xae\xc4\xea\xc5\xbax\x890\xda\xcd\xb0\x96\x8a+\x89\xa3m\xce\x86z\"\x02m\xd7\x9a\\\x91>\x84\x94u\\\x9b\xdf\xaa\xb1\xad\xd4\xc6\xae\xcaAX\xb7z<~\xbaJq\xf5\x1f\x9b\xeb\xea\x93zo\xc8\xe3T\x03\xb7ht4P\x1f\xad\xd7\xd9wC\x15Xj\xad6\xd9~\xf8\x80\xd2\x88\xfbP\x89*\xf4\xa1\xc9\x87\n\x1a\xf94\xd2\xe45\xbe\xcchD\xfb\x9e+n\xac\xd3\x90\xc4\x942\x8da\x8f\x07\xaaz\xe4<\xf3\x93\x90\x84#\xa1\xea0\xb8\xc6\n\xf8Y\xff\x13\n\n\xd0\xdf\xc3\xf2\xe9\xdd\x98\xb4&\x18iW\xb5&\x87\x89\x11&\x10S\xc8\xe3\xc8\x94\x1a*S\xb8n=ZE\x9f\xba-\xcd F\x99[\xac\xfeK\xee$\xd8\x86\xeaOI7\x9a\xf7\xc3\xf0^6\x11\xbc\x1f\x8e\x0d[E!9&\xf1\xe2Er\x84\xd3j\xe2\xc5\xf4+\x0d\x15\x1bV\xa1\xb5B\xe7C\xf7D\xd2\x89\x07\xac\xf6F\xdes\x0c\x85!\x1a\x90\x0f\xad\xfd\x11s\x80N\xf0\xf5\x94T\xa3\x19\xb4cw\xd8\xaa\xb6\xf3\xf0 \xb8z\xd4\x82\x98p\x08\x991\x956P\x98|\xaa\xe8\xcd\xfe\xfc\xb2U\xe8b\xae.\xdcl\x88F'\xc1\x0c \xea\xf2\xb6\x0d\xb5\xde*\x8a\xc3\x9c$\x943\xfa(M\xebB\x0d\xcd\x0d\xc9\xc2\xcc\xaasM\xc3Q\xdaxi\x05\x9b\xbc@\xa5[\x96F\x892_\x1c\xf4\xb0\xb7\xba\xcb$\xe7?\xed\xe0v\x1fX\xab\x92\x04%\xaa\x1368\x8c\x8b\x95\xed\x12\x1eP\xe4\xd4\xc7\xa0\"|\x17S\xf6\xcb\xbf Ar\x985a\xbb\x87\xa7\x91J\xf5\x85\x02\x990\xb0h\x1d\xd1\x92\xe8\xb5\xee\xc1\xee\xfc\xeey\xde\xfb\x0e\x89k\xb0C\x1d\xaf\x0f$O\\\xf8i=\x10GO\x9b(v\xdc \xbb\x14\x87~\xbf\x1e\xd2\xf83\xf0\xf9\xbb\x96*\xc11\xfb\xa10\xdc_g\xe5\xe0\xe7!\xc1\xf8A\x19m\xc9k\x7f>\xc8VZ\x99aC\xbf\xf4\x0bR\xa2G\x8e\xfc\xc8\xb6\x92Q\xaa^\xa8\xd5\x12\xbd\xdb\x97\x13JP\x13\x98,\xa2\xa5\x02\x8a\x89%\x86\xc0\xce\x00\x13QW\xb9\x86\x9fS\n\xfc\n\xf9\xaa(Y*E\x18G\xc4\xef#\x8b\x18\xa0k\x1b\x12\xef\xc6\x0d\x97~\xba\x02\xb4HS\xd4\x98\xc1\x98R\xf9\xaa\x8d\x99\xc4\x83\xefc\x0b/W\xc9j7\xb2\xce\xb0-^\xffIg\xafq8\xb5\xe0ly\xef\xc6XG\xee\xc4\xd1\x90\xefG%Y#\x9fY\xd3\x9a\xc3\xc3ff\x9d\xc6\xd9\xf2\x10\x1c\xbe\xb3x^\x96\xc1}\xd3\x07\xadt\xba\x16G\xc9;U\x860\xa8\x92\xd9\xf0$8\x8e9\x9dJ[~\xa8\x86\xa5\x1aDD\xc7{\x14F%`\x8c)\xcb\xbe\xc1\x1a\xe1wX\x154\x8dqd\xd7\xa5\xe0\xe7\xc8\xf5Z\x08\xda\xb3\x88'\xe7i5n\xbbBlTW\xb6>l\xc7\xd6\xb9P\xcc\xb1Y<\x92\xcb\x8c\xe8_}\x05\xe9\x18\x8c\xcb\xa0\xa9\x84\xa65\x071b\xab\xad\x94\xd2.M\xa2\xa1\xf55 \xd5\xa6;h\x1d\x06\xda\xc4'\xa4\xa6\x993\xd0\x14\xb3\x14\x14Y\x97\xef\xb4\xf7\xc0(1~\xdef\xa4\x05\x15\xb1z\x12S\xca\x9f\xf4\xa4\xb2H\xbc\"\x13\xbe\x162\xa9l\xc3\x1f\xf4\xda(\xf8\x83\x9eT\x16K\x0dL(\xfe\xb8qS,W\x1b\x98\x16\x1f_<\xcbl\xc53\xbd\xcfn>\x06\xbf\x7f\x92wy\xdfk\xe3\xb3+\x92\x84ozb\xa2\xc2g7\xed\x8b\x8az\x9f\xdd\xbc6X\x1d\xb6\xb7\x8e\x8aG\xcde\x89\xe3\x01\xabE\xc92\xca\x17\xab\xf4\xcc=a\x94\xb3p\xc6@\xde\xd2o\xf7\xe9\xc0\x989Q\x8c\xbb\xe3\xa5+f\xe9\x0dSH\x85\x1a\xdfN\xa8\xb9\xe6\xbc\xbb\x0dc\x9c6\xf8V\xdd!\x1c\x19B\x9f\x9a\xda\xf8\xe6\x92V\xc7\x05J\xb2Q\xdb\xdb\xb7\x03\xe2E\xc5\xf1*=K\x9aK\xdf\x80\xa6\x1c\xc0[\xccB\xa0?\xa0\xed8\x12\xa6\"\x9d\xa7\xe7J\xdeX\xd5L:\xeejX~o\xa9\xfbu=h\x1e\xb4\xc6\xe3\x93\x84Z\x0f\x8e\x90\x9d\xae\x9ax\xb5ZYY2'P\xf6\xa7\xa9]~l\x97]C\x16\xde\xa7T\xa3\x9f\xf5\x06v<\xabc\xe3\x19\x9d\xe1]\xc3\x19\xed\xea\x1e\x82\xf2\x10\x07\xbe\xad\xd0^\xe2\xf06)g\n%\xc6\x9c\x89^\xcc\xa0c\x84\x16G5\xe7\x02\xfc\xa2\x88\x96h\x931\xeb,\xaa\xe3\x806<\xfd\x1aJ\xf8\xa6w*|\x0d%\xa5\xfcj4\xda\xf2<6\xf5\xa1Pj\x82\xed\xaa&s:\xb4d$\xba]%\xfd\xf6V~\xf1\xe2,\x11l\x0c\xd3\x16b\x04\x02\xeeZr\x92\xd3\x13(9\xc9\xdf\xdaF\xc2B\xe3x\xef\xe3D\x1f\x01S\x1bw\x89\xea\xc4&\xda\xc3\x06\x9aCN\xd8\x81\x9a\xc07PV\xb3\x9b\xe8g\x17\x1a+\\\x9e$\x860\xc6\xdc#\xc9fMr\x7f\x8e\xe7a\xebO,&1\xc6\x9a\x88t\xd3o\x04\xd0\xde\xfe\x18x\xf64\xba$X8\xd1\xcd\xbd\xb3<*+\x88\xd1X\xc1d\x12\xfa\xc1w\xe4B\x1a!\".\xdb\xa0<\xa8\x17\xaa\x9a\xff\x92\x87\x9fh\xa6\xa8\xe27(\xeb\xe66P\x89\xee=^ \x12\xd3B\xe5\xbd\x9c\x84\xe2\xea\xf7\xe5\xbd;\xeao\xb3\xc8\xa8\x8c\xae\xd0\"2\xd5\xb9\xb2\xe2U\x80G>\xee\xb9\xa4\x19\x92Z\x8eD$dB\xce\xe0\xf5EF\x8e\xf2<\xcd]\xe7\x91\x9f$i t\xcf\x80\xcf\x8e\x18\xf0\x0b\xf0\xab\xd6T\x825g\xcbT \xf8\xa014c\x87At\x9a4{\xf9\x8a,HN\x92@t\x956\x08+\xbfH\xfeV\xc2\x9c\x90\x04\xd0\xe5\xd4\x8f\xa3\x82\x840\x81b\x93\x91\xdc\x1d\xb5 \xe8\xb0H\xa8+\xb9\x0f\xf5\xfc\xee\x95h\x97N\x11m\x1d\xd8;\xc4\xcc\x9dt\xf2\x90\xc0V\x13\xd2z\xc2\x98}9\x8e@c\x9e\xdc\xa8\xcd\xba\xf2\xcd\xb1$\xe5K\x81|/\x16nd\xe9\x1e\x0dR\x0c\x1c\x82'\x18\xa5.\x1f\xd2W_\xb1\xc21\xa8\x84V\xa0\xcd1\x9dlz\xe0\xe6\xa4((\xf6\xae7E $*W$\x879a\x1fH\xf3\x06\x1e\x8d\x81\xe2\x99\x037\xaa\x86\x14\xabB\xea\xedX\x9fQ\x8c\x87q\xb1s\xad\xfd\xaaa\x97\xd2\xa4(\xf3\x0d\xe5\xcdL\x96o\xbb\xf8\x8c\x9a2\xea\x8b'\xd0K\xd0\xc2\x996b\x1fX7+\xda*M\xc9'.\x05M\x1cq\x87 \x97\xcfT\xd1\xc2(x\x08\xd2\xfb\x1c7f(\xb9\n\xb4<\x94\x8a)n4\x86\xa62b\x0c)\xbd\xa5-\xd7P\xac\xd2M\x1cV\xef\xbc\xc1l\xa5\x96\x95\x03\xb4\x019\x82\xf5\xc0\xed\xa1\x9d\xd7T\"\xaf\xc2\xb70\xa5s\xd5H\xeeY\xf3 \xd3\xb7\xf0\xb0\xfd\xe7\xacg\x1a\xef^Q+\x01;\xdd\xd7\xaa\x02P\xd0\xa03\xcc\x9f\x81\xa5p}\x910\x1f\x80\x9a$\xbc#\x17\x85\x9b#WNZu(F#\x8flI~Q\xb3\x8b\xdaC\xae\xd1b\xe2E\x05\xf2Ac\xb6y\xb2B\xc9\x0c\x01\xe2\x14\x1e\xfd\xedn\xa2\xb9I\xd1\xcf\x94\x9e\x03\xfd\xeeiW\x12:\xddKO\xa8\x9c\x1c\x9d\x10m\xc7\xe4{\xa0\x8f\xb4\x94S\xef\x18\x06\xbb\xc73\xf1\x9e\xae\xd7\x1b\xdc\xa5\xad$\xc3p\x08\xd1\x18H\x83\x89\x8f4\xbc\x8cNa\x06R\xa5\x19\xb4\x07\xf2\x9e%\x88t\xf7E\xdd\x1d|r\xdd\xb4z\xa14WR\xca\x9f\xdc\xef)\xe9\"\xfe\xa4\xa7\xef\xf3\xf9\x83\x9e\xbeo\xc3\x1f\xf4>U\xf0\x07=}_\xcc\x1f\xf4\xf4}\x81T\xdf\xb7@\xf0\xa0s7\xe3\x1f\xb9\xd7t*\x08\xd5\x8a\xc0\xf0\xe3+\x02\xf5e\x8c\x86(\x02\x15\xc1\xfb=\x97\x0c\xad\"0\x96*\x02\x83J\x11\x18\x8f\xc68\xd7\xfb_\xc3\x02\xbe\x81\xf8kXP\x81%8Y\xb4\x15\x81\x0b;E`a\xab\x08\x8c\xec\x15\x81\x01W\x04.yd\xb2\xff=\xaf\xa9n#\xc7\xf1>\n\xdd_\xcb\xaa\xe0E\xc5\x8b\xef\x8eoa\x01\x87\x93\xdak\xa0p\xc6<\x1e\xc7/\x1cz\xae\x9c8a\x1d1\xe5\xbc\xed\xb5\xf3\x9e\xf7\xeeQ\xc7\x13l@\xff\x1c\xe8\xab\x86\xf0\xb3,\x11\xde\x15h@\x15\x8aN\xce\x8f4\xe7G\xbc\xc0\x93\x1b\xbe\"E\x1aoIx\xbc\x99\x979!\xeeI\xb50\x1d\x85\xaed\x85\\\xbar\xf4\x900\xa5\x17(Z\nU\xdb\xf4\x02\xb1T\xa1\xba\xf9\x04\nU\xbd*\xd5F\xe5\xca\xb2\x1d:\xfaa3<\xcf\xfd\x80\xa0\x8d\x18\xb8#\xb9\xaa=F\xb8,\xa9\x90\x1dE\xb4\xebb\x94$$\x9f\x18z\xa7l\n\x1d&\xad\xdb\xda\x0d\xe1\x9c\x12k' z}\xa4\x99#\xa7\xcc\xb5\x9d\xb1\xcb|\x96\xc6\x98\xf8\xec/w\xef\xde5h\\\x17iR\x1e\xb3o:Q\xe9\xc7Q\xb0C\x9a4\xf5`\xc2\xfa\x90jp\x893GG\x99\x1a/\xa9`^h\xa7(\xdd\xe4\x01\x99\xc1\x91\xbc\xbb\xa3Q\x8d\x80\xe7\x94H\x9f\x8b<\xd0\xe7J\xc3\xb4\x95\x0fw\xc7i\xcf\xa2\x8e\x1b\x0bi2\xd9\xae\xd1=\xe9dj\x80\xa2\xf2\xe4\xa9\x8b\xa7\x8e/\xd8\xf2,'\x81_\xea\x99X\xe0\x02\xe6\nm\xa9^T\xa0I\xf5\x1d~\xe8\x9d\xc7\xad&\x85\x9b\x1b>\x91)\xf3\x1f5\xaf-\xe5\xdc\x03?\xfe.\x8e\x96\xc9\x0c\x9c2\xcd\x0c\xf8I\xaf\x8cr\xff\xc9\xf2\x15\xf7\x9c\xd8\xf7\x0e\xc8\xda\xc03\x1amQ,\x026\xf3(\xfe\xff\x82>\x19p\x08\xce<\x8dC=n\xeaw'\x08\xad\x84&\x0d\x04\xb4I\xca\x86G;Vk\xa5\xde~\xa6=\xa3\xef\x17\xa7\x1c\x99\xee\xfb9\xe7dv'\xcc`K\xa3\xa0A\xa7r\xdd\xb0AIy\x80\x1f<\x7f\xd7s:\xf6sc\xee\xb1\x0c\x81w\xef\xb9\xaa\xcb/\xc7\xddT\x00\x16(\xc7\x03\xbd\xd0V\x99\xc0\x0dp\xf0WN\x7f\x9d\xd2_\xbe\xae'F7\x07!\x0f\x1b-\xf1m\xbf\x00\x83\xd5\xab!\x9b\xf1:\x84\x0d\xcd\x00\x86+\x9a\xdb\xe2\x0e\x02\x81\xa1%\xeeIa\xf0 \xe0Q\xdc\x0b\xb8\xa1\xb3\xa8\x8dd\xd62\xf6\xa46\xa8U\x87\xcc\x99\xf1\xb8\xe7'\xe4\xff\xfc?\xa7\xfdV\xf9\xb1\x0f\xa4\xc4\xea@J\xf9\x81\xa4&\xb2\x18\x8dw>\xe1%b\xbd\"\x8e\x02B{s\xa0,\x08+\xae-/\n\x99\xc2CH\xbd2\xfd\xf1\xb8\xfa\x81S\x9a\xf2 \xb2\x8a\x80\xbc\x0c\x19\x07\xb1\xaf,\x1cU\xac\xc9\x074\x99\xb3{\xf7\xee\xe9i\x07h\xe9\x07\xd8\x1c \x0c\x97\x92K\x92G\x18:\xc6\xc1d\x12l\x86\xda\xf1\xfc\xf3U\xbb\x10\xd4\xbc\xaal\x7f\x1e\xd3\x13\xefX0\x816;\xd5f\xce\x9do\xe0\xef\xf0\xed\xa59]\xc9Q`\"\xd75\xa9\xd6EuZ\xd3\xe9>\x8d\x1e\xaa\x8c\xb5$\xd3\x82D\x1f\xabA\x8c\xe4\x19Is\xb5\xb2\xbf^\xe5z\xa2\x0e\x0c&\xdf\xda\xae\xe8\xaf\x1d\x8am\x88\x197\x91,\x1b\x1f)\xa4W\x9a\xd8\xed+E3\xb0F5\x18\x82n G9T@\xa2\x89\xd2\xdc\x8c\x19\xd5\xa0\x81n\x06\xa7 #\xca\x01(\x92\xad@W\xda\xfc\xe9*\xd1\x11U\xaa\x03\xd0\xf1\xa7/\xe8\xd8\xb8.\x89\x8eL\x9f\xfd\x99\xa3\xe3\xab\xabD\xc7$-\x07 \xa3\x01\xad>\xbf#\x11\x0d\x14Wv\x02\xbe\xba\xec XW\xff\xba\x94 \xa0\xaf\x08\x0e\xe2\xb4\xd0\x94K}\xef\xec\xe0G\x98\x19\xfd\x08\x99\xe1\xee\xba9Pe\xca\xcc\x90\x99\xd4M*\xe2O\xa41\xe4\x99*\x86^z\x971\xa8\xdc\xbc\xac\xdc\xc6\xa0\xf2\xf42\xbbR\x01W\xe1G\x83E\xffd&\xf4\xb7^\x94\x84\xe4\xfc\xc5\xc2\x95\xa4\x12j^\xa6\xd8\xa0%\xcf\xeci\xe1\xfa\x03\xdci\xac\x1c\xe0\xd6\x03\xdcw\xcc&y(p\xe7\xb1\xd2u\xc4\x81h\x02?\x83C\xd8R\xd2~\xb98\x17\xd8\xc5\xbb\x02\xe0\n\"l`wg\x06`\xedo/\x13\xe0d\xd5GK;3\xe8\xe7C\x1b\x9d\x0b\xb5\xeb\x82!\xc4\xaf\xf6L\xf0\xe1\x9bC\xd8\x18\xc8L\xbf\xc2\xd3\x89\xe7yo\xb5#pN\x9c1\xac\x85\xdem\xbd\x9b\xae\x1b:\xfa\xeef\x90\xa9Y\xdf\x0d\xd6:o\xa8\xcc\xb5:\xbd7\x98q\xc1\x18\x97\x05\x95\xe2\xb96\xe2\x98\xfbF\x8f\xd0\x7fX\xaa\xab)\xec\xcf~l\xb4R\nX\xceB\xc9+\x1d\x8aK\x91\xcb\x8a=\xaad\xce\x0c\x1e\xee\x1ej+\x0c\xfb\x1a\x13&m\xa9B\xa9K\xc5\x1b\xb6v\xa3\xa0\xda6C4\x11\x01=\xd4\xfc\x12\xe9\x8c\xc1>\xa51\xb4\xa4\xd8\x80K\xb1V\x078\x0bvN\xb4\x9ex\xd0\x10f\x0d\\\x87\x9dh\x0e\xb5\xe8\xeb\x1bU\x1fcpZ\xf17\xad\xe7\xbd\xbb\x1dy\x14o}\xb6\xb1mr\xc93UI\x9e\x91J\xf2\xf4U\x92\xe7F%y\x16*\xc9S]\xad \xeb\xc5qRy\xd4\xcd\xea0\x9c\xe9\xfe\xe7\"\x80\xde\x9d\xd3\xff]?\x19TR\x14\xa1/\xf4)e\xd0\xf4\x03\xc8\xa0;\xe6\xf8\x87\xeb\"\x83\xdaH\x89\xc9@i5\xddAZ5\xcb\x8a\xfe0Yqc+\xda\x16\x18D\xdb\x0d\x15\xd1{\x03\xb0d\xc4{\xe8\x9f\\E\xa4\x18J\x07\xa0\x06S\x9f\x0d$n\xc4yP\x81\xce\xc2K\x8d\x83/\xd2|\xedk\x95\xb6\xc0\xb7#\x7f\xe1|m\x94\xaa\xb654F\xaa\x1a\xc0\xd7\xd2 \x15\x9f\xfec\xc8\xa7\xb1\x1c\x1c|\x03\\\xa8d\xe1vKR\xd6\x0bG\xf7\xb6\xfeE\x94,\xafL\xf2\xc6\xa9\x19C%\x81\xf3\x95\xb8\x02\x11\x9cw\xf1\xa7\xb4\xdc\xb9\x97\x17\xde\xca/\xcc-\xe9\xe7\xeb\x14\x8fe\x18\x83i.)Y<_\xc7\xe8\xfa\xb7\xfa\x0f\xd9\x13vS\x07;m\x0c\xe3\x84\x83\x81\xf1h\xae\xbd\xf3?\xff\x8f\xfe\xcf\xc1\x14\xe2\xce\x0c\x9c1\x1c\x97y\x94,\xddT\xe7M\xdaL\x94T!\xe8Vw\xe6\x9e\x99&\x83K\xaa[\x03\xa7\xdf\xf2II4=\xbc\x9c\xc2\xcb\\\xfa\xeb:(\xbc\xc6Pz\xe2}I <}\x86\xa7k\x91\xe0I\x14Qj\x8d\xc3&\xd3\x13?\x1e\xfa\xd8\x92T\x8f\x7f\xf6%*\xd9\xb4z\x8c\x87\xc0\x15ef\xe2{\xb2\x97\x0d\xc9*\x05S\xd9\xd9yI3W\x92\x1c\xf9\xa2k\x80|}<\x8be:\xd5\x94?\xe8\xe9T#\xfe\xa0\xa7S\xf5\xf9\x83\x9eNu\xc3\x1f\xf4t\xaa\x05\x7f\xd0B\xf2X\x8d\xe4\xf1\xc7G\xf2\xe0\x8a\xb2\x14\xa5*\x05f\xcf\xbbF\xa6\xc0\xcc\x87+0\x95Y\x8a6R\xc5edR\\~\xb2,Ei\xf2:\xbfH7%\xa6\xdfV\x03'\x1c\xf8\x91\x9f\x04$6\x00\xe7\xcc\xab%\xf1\xe71 \xb5\x01\xfe\x86\xba\xdd\xea\xb3\xb1U\xa8<\xbf\x98\xa4\x1buT\xb7\xb6R\xfb|S\x96\xf6Y\xd1\x9dy\x99\x00o\xef\xf4\x94\xfe\x11\xe0\x84\xd8\x147\x97\x1f\xcb\x94\x0fd\x93\x8aa]\x1f\xaa\x9f6\x1dT\xd4\xfc\x1b\x83\xf3:\xbf\x80\xa8\x84tS\x82\xccdfp\xdd\xd4\x17\xf7\xaeX#V\x12\xaak?i\xe1\xe7\x0c\x9e\xf0\x1d\xd0\xa8\x86\xd6\x01o`\xa8\x19\x9c\xe3\xe8\x0c\xf6jc!&\xc8\xa8\x0f\x95\xebYp\xfc\xcb\xa1\xf2\xe5P\xb9\xbe\x87\xca\xfc\"\xf3\x0bC\x91\x16\xe2E\xc5\xf1\x99\xbf\\\x92\xfc\xc0t\x94\xb0\\?\x1a\x12\x86P~\\\xa4\xc7\xab\xf4L{\xe2\x94\xba\xc3\xa0\x19XP\x8f\xd6\x0bVQ\x1c\xe6$A\xa1\x0e\xcb\xfc\x98?bG\xa6\xb7$/\xa24\x99d\xb9\xbf\\\xfb\xca\x13,\x1d\x7f\x88\xe6NO\xd7\xa4(\xfc%\x01\xc5\xfd\xc9\xc4_\xcf\xa3\xe5&\xdd\xa8\x0b~X\xcd\xa5\x12hu\xab\x0e\x0ey\x83\xb4\x18\xca\x14\x18\xc6\xe2\n@]\xea\x06\x13\xc7\xa8>\x94\x99\xdb\n\xd2\x90\xd4\xad\x15\x0c\xf5X\"V? \xa9\xa4a\xf9j\x9a\x91\xc4\xcf\"\xf6\xea\"\"qXP6 IK\x98\x13\xc8rR\x90\xa4\xc4\x8a\xd4+\x02\x85\xbf&\xc0\xf1\x1c\xd2\x1c^d$\xf9\xee\xe5\xd3\xc6\xb8\xeeY\x8e\xdc9\xdedY\x9a\x97$\x14\x0b*z\xe7\xe7d\xc0\xf8\xf8\xd4\xa0\xf0\xf57\xe7\xc0\xdbw\xfeV\xcdR\xb9J\x0b\x02\xe5\xca/a\xed\x97\xc1j\xc0g\xf9\xb4\xcd\xe0\x96\xb7\xef%l\xf6\xdcE\x9a\x039\xf7\xd7YL\xc6\xbb~k\x1f\xbf5\xf2\x1c\x11\xd3BI\xb0\xc5\x16\xd5\xee\xf3\x0f\xb0\xdf\xae\xdf\xf6^GE\x11%\xcb\xcfgs;\xafWt\x87\xa5\xdb($a\xe3u\x08SR`\xad\xdd\"#A\xb4\xb8\x00\x9f\x1eoQg'X\xef$\xbe#\xa3$\x8c\x02\xbf$\xd5\xd7$\x1b\xb9\xdd\x00|\xd9\x83\x97\x11\x10Z5I\xed\x85\x04q\xf2\xcb<\x0e\xc5\xa6\x96=c|\xca\xe7\xc7\xfd_c\xd5\xe5\xe0\xdc\xf4l\x97\x0c\xd48\xae\xfd8\xae0Q \x96\xe5\xf2\x9cm\x12\x9a\xd9u\xb7\x03\x07\x13\xb6\xe3\x7f\xafY\x92v\x8a\xa0\x8f \xc9\x9eE\xc9\xbb\xcf]\xbd\xdd\x18\x87\x0d\xb2pq]\xa9\xde\x96F/1\xe1\xa0$\xe7\xe50$\xf3\x8d\xb8\x93\xa4\xa8\xe1\x96\x88V\xb5N\x05\x1e\x1a<5\xa11\xd9^\x96\x93-I\xca\xc7\xacG\xae\x84\x92*\xf3\x9b\xae\xb0\xa2[\x89\x15\xddn\xb2\xf4N\x0c\xb4\x8b\xd9&=>\xdbT\xe9g\xa9n\x1f\xe3j\xf7\x1d\x89)\xb6\xb9\xb8+F\xacLk\x0b\xa1s=B\xe7\xed\x19\x94O\x86R\x8a\xe6k\x1b\xd9\xb0RJ UU\xc1\xf3u\x9c\x143pVe\x99\xcdn\xde<;;\xf3\xcenyi\xbe\xbcy\xb0\xbf\xbf\x7f\x13_\x93\xbf\xf4\xcf8J\xdeI\xdf\x9c>x\xf0\xe0&\x16 \x94\xbc\xabM\xf0\x93\xa5\x05rc3p\xfcy\x91\xc6\x1be\xf9{^\x05QQ\xbcF\x94?\xdc\xef\xa3\x7f\x17\x99\xd5\xd3J\x16\x85\xc5\xbc^\xac\xe7i,\x9d\xdamD\xce\xbeO\xcfg\xe0\xec\xc3>\x1c\xd0\xff\x93\x0c\x06\x0bNm\x928\x0d\xdeu\xd3\xd3\xe9z\x97\xb1<\xe0\x12\xa4\x9b\x81\xf3|z\xc7\xbb\x0f\xf7\x7f\x98\xde\xfe\xf9\x8ew\xf7\xd1\xf46\x1cx\xf7\xf6o\xc1\xf4\xc0\xbb{\xf7\x0eLa\xba\x0fS\xb8\xe7\xdd\xbau\x1b\xa6p\x97?\xbd\x0bw\xbc\xbb?\xdf]\x1dl'\xde\xfd\xfd\xe9\xa3\xfbp\xcb\xbbw\xe76\xdc\xf7\xee=\xb8\x07\xb7\xe8K\xb7\x82\xa9w\xb0\x7f\x8b\x0e\x07\xf0\xd9\x01\x1cx\xd3\x07\x0f~\xbe\xff\xc3\xed`\xe2\xdd\xb9s\x0b\xf6'S\xf0\xee\xde\xbe;\x99\xc2\x14\x1fM\xef\x05\xfb\xe0\xdd\xb9\xfd\xc0\xbb}p\x9f\xde\xbb\xf5\xc0{p\x87>\xbd\xb5\x7f/\xa60\xf7\xbc[\xf7\xef=\xba\xe3\xdd\xbdw\x00\xd3\xfb\xde\xfd\xbbS\xb8\xeb\xdd\xb9\x03\xd3\x07p\xcf\x9b\xc2\xf4\xc1\xea\x8ew?\xa0\x9f\x80}\x98\xd2\xcfL\xe8W`J\xbf3\xa9>swB\xbf\x13xw\x0enO\xbc\xe9\xdd{\xde\x83;\xb7&\xde\xbd;\xec\x07m\xee\xee\xcf\x0fh\x97\x1eM\xef\xc1}\xdaG\x98\xde\xf5n\xdd9\x80\xfb\xc0&\xec\xdf\x9d\xf9\x1f\x8d>\xf8\xca_\x9bu\xff\x93\xac\xe0\xf3\xe9\x01\xdc\xff\xe1\xfe\xcfw\x10l\x10\n\x7f\x82\xd5\x97\xe4\xb9\xb8\xc4\xe2\xdf\xf6n\xdd\xbe\x0f\xd3\xdb\xde\xfd\xdb\x0f\x82\x89w\xfb\xee\x03\xfa\xff\x93\xa9wp ~\xdd}p\x0f\xf6\x9fQ4\x98z\xf7\xa7\x0f\xe2\xc9\x81w\xf7\xce\x94\n`\x07\xdaW\xf0Q\xe3\x1f\x04\xa0\x98B\x1f\xc7\x07\xde\xbd;\xf7'\xb7\xbc\xe9\x9d \xfd\xf9\x00\x7f\x1e\x04\xb2\x97\xee\x8b\x97\xaa\xdb\x80\xb7\xc5\xcf\xaa\x83\xf7\xbd\xe9\xfd[1vor\xcb\xdb\xbf5\x0dto\x80\xe8z\xf5\x9ca\x1a\xed\x1d\xf6\x89b\xc2\xf4\x0e]k\xf1;P\xbe\xf2)0AY,\xf7\x12\xf8p\xcb;\xb8\x03\xd3\xfdgw\xbd\xe9\xfe\x038\xf0\xee\xdc\x0f&\xde\xc1\xdd\xfb\x13\xef\xe0\x1e\xffqo\x1f\x17\xf7\xc1\xbd\x07\xe2\x81wo\x7f\x8a\xff}p\xf7\x01\xec\xc7\xf7\xbc\xfb\xb7\xe0\x9e\xf7`\xff~@!\xbc\x83{S\xfc\xef\xbd}:[\xf4\xc5x\xd2\x80\x99\x08 \xfa\xe9)\xb6\x83\xdf\x11\xed\xd2\x15\xec4\xfcL\xf4\xf3\xd3\xce\xfa\xa4\x1fyy\x89\xa9\xbf\xe7\xdd\x9e\xde\x07\x9c\xf8\xc0;\xb8w0\x11\x93\xc6~<\xb8\xf7\x00\xf6\x0b\x9c\xcc{\xfbS\x9c\xc8\xbb8\x91\x0f\xf6\xef\x03\x9d\xce\x00\x97@\xcc\x14\xfb\x81/q\xa0I\x05\xd4XQ\xfc\x14N8[\x81~\x93\xb8\xf3\xe9t\xc7\xd8\xc1\xc9=oz{\xfa\x81\xe6\xfd6\x1c\xdcV\xcd;/\xcbqe\xd3\xfd\x00\xeemo\xffp\xc7\xbb\x7f+\xbe\xe5!)\xba\xf3\xe0\xd9}\xb8\x1bO\xee\x02\xfb\xdf\xd4\xbb=\x9d\xd0\x7f\x9eQ(\x98\xde\xfa\xe1`\xfa\xf3\xbdO0t\x16\xf1~e#\xdf\x87\xe9\xfd\xd5\xed\xed\xe4`5\xb9\xbd=\xf8\xf7\xf3[pw{\xb0\x9a\xde\xff\xf9\xee\x0f\xb7\xfe\xbd\xbe\x05\xf7V\xd3\x83\xed\xe4\xe0\x87\xbb\xdb\xff\x8f\xbdw[r\xe4F\x16\x04\xdf\xfb+\x90l\x9d*\xb2x\xc9d\xd6E\x123\xb3\xb2\xd5j\xe9\xb4\xd6T\xdd2\xa9\xfa\xcc\xce\x90\xacj0\x08\x92\xa1\x8c\x9b\x10\x08ff 5\xd6\x0fk\xfb\x03\xbb\x0f;f\xbb/\xfb0k\xf3\xb2f\xfb\x0b\xf3)\xfd%kp\x07\x107D0\x98U\xea\xd3\xe7LS\xb2\xca\x08\x04.\x0e\xc0\xe1\xeep8\xdc\xcf\xeb\x9d\x1d|\x1c\xc5\x84Q\x18D\xfd\xf3O\x07\x13\x9a\xa6\xfe6\xaa\x9f+G\xfd\xe9\xd9Y\xd5\xa6\xd47\x1f\x9e9\xce\x95\xd5\x87\xe9s\xc7\xb9\xb2\xfa\xf0\xb4\xbaCK\xf1\xc3\xf3j\x13\x81\xf3F\xa5\xdd\x9b\xa9\xba\x9e}\xee0u\xdddA\x80\x9f\x9f\xbb\x82\xedxq\x18\xc6QH\xf9\x8d\xce4\xad\x1c\xc5\xba\xd4$\x9ekP\xd5\x0f\xce\x10R\xee\x91+\xf5\x19\xdeX\x04\xd1\xbb\xf5[\x0c\xd7\x95\xd0}\x8b~\xd6_D|\xc3\xe0\xc3|\xa9S\xfc(\xf0#\xf6*^3rEN\xa6\xa5T<\x0d\x85G\x9d\xbeR\"(\x1e\xba\xaa'\x9d\x8aJv\x86\xa7\xa7\xe6\xc5\xb4x\x9f\xc4[N\x93\x9d\xfe\\x/\xa0S\xbd\xf7\x1b\xe7-\xa9^\n\xe6y=rrE\xc4}\xc2\xe2\x0d\xea\x8c\xfa\xa0\xb1\x19\xc1\xc1qOOWoP\xedL\xc4nIV\xe9\x89J\xa3:\xcd\x8b\xb9\xc9\xe6\xd7\xbb\xa6\x92c\x93\x9c\x056-\xad\x8d\xba\xbd\x1e\xef\xc1\xd5\xc9\x8c\xb3~0gK\x03O\xcaD\x1f\xae\x1e\xfe\xfc\xbe\xba\xa4`\x08r\xf3\x11\x95\xb5UY\xc5\xfb\xc5\xa6G\x84\x15*\x1c\x95j\xb2\xa0tR~\xa9Z\xcb\xfa+\xb80\xc9\x06D\xecx|\x0b\xfd\xfe\x8a\xf3\x98\xf7{\xff\x81\xc7\xd1\x96\xfc\x993\x85\xdet\x15\xb0?\xe3\xa1\xa4\x18\x11o\xc7\xbc\x1b\xb8\x9c\x7f\xea\xa1\x13\x8e\xea\xbd0\x8b\x9f\x18\xabF\x8d\x8cM\x1a\x8c\x88\x02[\xab\xe7!\x87V\xe4\xdc\xb0\xfb\xb4_\xfc6\x98lb\xfe\x15\xf5v\xb9-{m\xd5`sy\x99y\xb4\x84i\xc4\xa6\xcd\x1b\xd7Z\xbf\xbe3+\xc4\xd2\xaa\x10\xc6\xa6\x01W\xd4\xef\x8a\xb4\xde\xf93\x8a\xb8\x82\xc1\x87zj\xaa1\xa1\xfcp\x9dj\x06#\x8d\x99\x9e\xae\x18\xf29\xd5\x91\x16\xedU3\x1eK\xd3~4\x18\x91H\xd3\x89&@\xf4\xa1Z\xb7\xde\x01:!\xb6W\xd6\x94~@\x14\x86\xcea=\xe5\xf5\xa4RZG\xe4\x1b\xb3\xbc?\xe2\xb8D\x15\xbax6\xfa\xa0\xa1\xea\x06\xe2\x03\x06\x0c+\xee2l\xe0\xf7+\xe6B\xd1\xa7M\xe1u\x92 ?H\x0dC\xfe\x15\xf9(|\xbd\x81\xa1?u\x1e\x07\xf85%\xa6%\xb1)D\xfeE!\x01\x9c\x8e\xc4\xa6\x97[&~\xcb\x19U\x14<\xb6/\x0ebZ\xec\xb6\xaf$\xa7nS\xe3\xe0\xba\x9b\x98\x93\xbe\xe9e\x0e\xe1Hk\xfc\x03\x16m\xc5n\x04B\xca\xd9\x08D\x92^\xef\x82\xc4\xe3\xf1\xc5\x80P2\xbc\"|\xce\xe6\xfeR1@\xb6T\x8d\xf8\xc3!\xb6\x84]r#\"-\xcea\x1d\xfa\x8f\x0b\xf7x\x9a\x03>\x1c\xfa\xe4\x92\xc4\x17\x03\xd2\xc3\xa5\x80\x8e\xf3m\x17\xc85\xf6\xaa\x80\xa0\x06\x19U\x16s\x0ej`\x9a5\x8c\xc1Q#\xf0\x91\xb0s\xb2\xa3\xa9\x0bC\xd5\xa7,b\xa9G\x13\xf6j\xed\x92=U\x0e\xce\x92\x80z\xec\xabH\xf8\xc2g\xa9K\x12U\xd9\xb0\x9a\xdf\x8b0\xa8\x8b\xa4?\x17\xb4\xfa\x19J\"?e\xb1`o!\xa6\xd5a\xed~\xef2/\xf3rQ\xd8\x88\xbe\x1f\x95\xeb\x03\x95QG\xb2\xd3\xbb<-\xd4\xda#C\x92b\xf6r\xed\x1eR\xc4.5\xb2\xb9Xj9\xeb\x9a\xf4.\x13\xce^^\xaa\xe2P9\xed\xc3g-\x17\xc0u\xe6\xcbS\xf8zy\xaar\x16\x00 3\xd2\xebR\xb02\x0e\x1b\x16y\xae\x85=R2`\xe0\xe2\x0f\xdeH\x91F\x08\x1d;\x17\x8ekjkX\x1b\x8e\xc305\xeb\x93\x80F\xdb\xef8\xdb\xf8wu\xc9)Q\xe4\x9a\x86\xa9K(Q\xdf\xc1\xc9\x0c\xf8\x9f\xd1\x19'i\x12\xf8\xa2\x7f\xbaH\x87\xa7\xdb\xc1@\x87\xf2\x86H\xde\xbc\x1f\xe0\x12\xc6\x1e\xbe\xf5\xb2T\xc4\xe1\x88x\xf3\xb3\xe5\xc0\xfa\xb1p\xe5\x99\xab,\xcb\xca8\xd4\xed\x17U7\x1f\xe3\xd1\xe3U\xef1\x19\x92\x1d\x0c\xbb\xdf\x8f\xfb\x9b\xc1@\x8d\xf8\xe3\xde\xe3R)\xa7)ia\xc6\xd5\xbc\xad\xd5L\xc1\x0c\xf6\xa3\xc9\xce\xdf\xee\x02\x88p\xf4\xe8\x11)\xbcj\xc3\xd5B\xca\x88\xcc\x133\xd90\xeb\x1e\x15}o\x80n)\xfa\xf6\xd3\xa0\x15\x83\x1c\x88\xa1\x87DK\xeb\xd9d\xc7\xe8\xda\x8f\xb6\xb5%\xd8\xbabv\xaa\x0d@\xc7\xdd\xb7l\xcf\x02\xecb\xb95S\xf1\x91k\xd1Yum\xad\xef\xbap\x00c\xda\x1bM\xeev\"\x0c\xfe\x98\xc1\xb1\xed\xe5\x8e\x93\xd3\x97=X\\;\xfe\x12<\n8\x87k\x95\x05\x01\x13o\x03?\x15\xdd T\x168\x08S\xa1\xa2#G#\x0b\x9a\xa7\x13\xea\xf3\x05\x0b\xbbC\x17\xf8\xd5Y\xca+\xa9A\xd6\x0cU\xe0\xd7;\x19s%\xaa\xad\xdd\xc3\xd5&\x98\xaa\xb9v2\xc0\xdee\x1c\xe8e\x03\x95\x93\x97dJ\xae\xc9c\x92\n\xca\x05\xaeP\xf3 \x96&FTu#L \xbc#'!n\x99\x04E\xb5`[\xdf\xa9\xcfE\x06!\x80\x0c\\\x93\x1e\xa2bR\x9d\x99\xbc\xe6N\xe0\x9a\xe1<\xe9\x17jW;\xe659\x07\xe1\xf1%\x05\x1b\x10\x03\x07R*\xce6\x06\x06\x0c\xf3\x15\xbb(\"\x8c\xc1\x11\xcb\x8cV+\xf0C\xba\xed\"\xb2\x9b\x01|LR\xee\x95 M\xb9\xa7\x01\xad\x8fS\xf6\xd0!oX\xbd~\xb85Q\xcf\xfa\x8f \x0d\xf4hc-4P\xf3\x80\xcc\xd5$\xa0]1.\xe1\xc7\xbd\xc7\xeaO\x86\xeb\xbfH\xbf\xc9i\xaf\xb0\xd0+#\x04\x11D\xbb\xd3C\xc8^'\x16X\xcb\x113\xd5T\x8f\xe2\x81G@\xa3\xb27\xd5r\x0c4\x0d\xf5\xac\xe2\xf5\xfd\x11\xd0\xa8\xecM\xb5\x1c\x03MC=\xfc\x08Pxm\x9e\xf9Q p\xd7\xa8v\xa2\xd8\x1d\xb8\x94\xd8i.E\x03\x7f\x1bi\x0eu\xaf\xd6\x8d`wb\x0c\xa93\xa43\x98\xa3\xca\xac\xea\x90\x1d\xd3\xb7]\xad|\x1d\xe5\x1e\xda\xb3\xf5G\xee\xd9qh\xbc\xae\x96O\x05\x8f\x1d\xa2jc\x15\x98\xbf\xa1\x96# q\xd7s\x8c\xe0\xc5BG\xe9# \xa8\x97_\xb3\xa0{\xf3k\x16\xb8\xca\x1f\x01\x80\xa3\x06?J\xbbC\xe0G\xa9\xab\xfc\x11\x108j\x08)\xaf\x0b\x15\x8d5\xa8\xdc\xce\x1a\x8e\x00\xc2UG\x9a\xad\x0e\xad\xb5\x1c#\xb3U\xf3f\x1e>V\xebN\x8e\xa8;i\xab\xbb&`\xee(_\xaf\xb4.\xf1\x90D\xa1\x1b\xa9\xec\xa4Vj'\xb5\x88P\x12\\9\x88l\x1ao\xc4\xd1M@\x81\x94\\whM=\xd6);\xbb\x13\x1d\x07\xad2T\x95\xf1\x11a`N\xcb\xbaTV\xac\xaa^\x93\xa0\xdb\x0f\xae\x87\xaeVu\xae\xd9R\xd3\xe3KU\xe2\xa0\x14\xf7\xf2\xb1\xa3\x99#\x16\x85\xca_SB\xc5\xb1\x88b\xc1\xder\xb69\x04\xad\xe1D\x7f\xc8\xc2\x15\xe3\x08\x9f\xbf&C2\x1dLD\xac\x1d\x938N\x97\x95\x88\xdb\xdbD\x9cm\xc0\x10\xdb\xc9\xc4P\xea\xcdV\xdf\xac\xc9Kr\x06G\xa6\x9c\x0c\xafHof\xf5\x0c\xf0u0\"\x8f\xd5\n2\xea\x1f\x03\xffX\xd5\xfe\xd2\n\xfd\xbf\xdeD\x8fuL\xdf\xc7=\xe2\xaf\xaf\xac\xc4\xff\xb8\xf7rn>\xf5\x96Jxw.:;.\x80Y]wD\xba3eI\xf8\xf1\xe5\x8eW\xc1M\xc7)Kz\xb0N\x14\x1fn\xce\xa22\xc0\xec_\xa6\x0c\x9a\xaeeSY.\xe3\xa0^\\m\xa1\xa1|k\xcf\x8e\xc0\x9f8PM\x9dj@\xeaT\xc4\xd6|\x14\xea\x07>\xcc\x0fNX;j\xe1l\xd6\xa6\xde\x17,\xac-\x0e\x0b\xcc\x11\x1dt\xe9Kl=4\xf2v\xf1\xc1CE\xb3Fr|o\xefR\xd7\xc5\x105-\x06\x92\xe3|\x01\xe3\xabC\xb4\xa2\xde\x0d\xac\x90\xbf\xfe\xaf\xffM\xe1|e\xb0\xd6\xc7\xc8(\x0e\xcd\xd9\xfa\x08\xcd\xdbZ\xd4D\x9c#\xf6^\xeb\x9a\xb0\xb9>N>rC\x7fL\x0d\xc2Q\xc3Q\x02\xf3\xba\xb2\xe9+\x1f\x03\xa5\xe4\x8ad\xc5\xf3\xc3.\xcb\xa8_\xe4\xa4\x84\xf5]\xc4\xa9\x90}8\x8c\xc8\xcb+\"\xf4\xe9\x1a\x19\x93s\xc5\xc7\x15\x9b.+\xcaP\x13\x05\xd6\x07F\x0b\x85/FmU\xd2X\x89\xb9B\xbf\x82\xc6\xea\xac\x9c\xac\x99\xa5iU\x15\xafh\xcf\x8a\xf5\x9c\x97\xda\xd4 Z\xab\x85=Tip\xc5\xb9\xd4\xcf\xf78P\x03ri\x8f\x0f\xa1\xa9\x8a\n\xd5*\xd9\xecya\xaf.\xa7\xe4SS<\xa8\xcd \xf5\x03\x0f\xfa\xea\xc6]1\xb9\"\xf3\xda\x94\xcd{@\xa8{\xe8\xdb\xff\xec\xf9\xc0q\xf03\xef)\xden\xb2\xbcpg\xe1l\xc38\x8b<\x08\x13\x0f\x19?ug\xd4S\xaa3}\xe6\xced\xe9\xa2\xa0~`\xf2~\xde\x0c\xdc\xb9\xce3=k\x82\x0e\x8e-C\x16 \x03\xdft\xea\xce\x9a\x86\x94\x0b8\x06\xb49\xcf\xdd9\x03?\xba\xf17\xf7&\xd7\xd3\xc1\xb2\x94iy\xc4q\xbf\xc3z\xaahd\xc5\xcb\x84\xdc\x1ej+\x92pvA\x18\xb9$\xb1F\xc6\x0b\xc2\x86\xc3A\xa1\n\x8c$\x12\xcf\xd9r~\xb6\x1c\x11x\x98.]\xa6W\xc5\x03vm\xe5Q\"\x10.n\x84Gi.\xf8\x04\x9a\x02D\xe66X\x01\xa2-\x13\xdfg\x01K\xfb\xbd\xde``\xe1\x16\xe4\x92D\x17D(\xf0\xf9\\,\xfb\xac\xd1\x84\xe3\x03n\xc3\x95,A\x1a\xbb\xc6\x8a\x160\xd7\x84i;\x17\x1c\xcb:\xe1SC6\xb3\xd4\xcae\x01\xa9\x830\xb1I\xca=s\x88\xde?]D\xa7[\xbc\xf6:\x11\xdc\x0f]\xe2m\xc0\xf6,p\xde\xdeRm\xa532?\x1b\x91\xa9\x03?\xf3\xbb\xd8\xf32^\x82CWm\xc2h\x0c\x8f\x14X\xa3\xa2\xbd$\x9b\xb0h?\xb2\x1d\xff\xd8\xc6\xafO\xab\xb6\xaa\xdaJ\xe6y\x93\x91\x0c3\xa7\xb6\xbe\x0b\x0b)\x9c\xe6\xa6#\x12\x8c\xe0\x18\xbb~\x04\xfd\xec\x9c\x9c(\x82<\xf1v\x94\x7f\x19\xaf\xd9\x17\xa2\x7f\x96\x9f\x17\x8f\xa7\xf5\"\x9fO\xebE\xa6\xedE\xb4G}f\x1d\xe4\xf7\x96\xb3^{\x11j\x96x\xa1\x8b#2_\x0eF\xa4\x9f\xc1\xd5b:\"S\xe07gDJ\xf2\xfc\xb3:T\x19\xc8}\x8d\xcd\xc0r\x0c\xc8\x15\xa1\x93$N_\xd1\xbb\x11\x8a\x01\x8a\xc1]\x90\x94\\\x92@\xb1\xb0\xe9\x19\xd4L\x01E\x0b\xb5\xa7\x83\x0b\x92\x0e\x87naR\x873\x0c|\x8f\xf5\xcfG$\x1b\x8c4[\x86C}\xf3\x05\x9a\x1a\x91\xd4\xa0\xb9Y\xf4\xe4\x9a\x8c\xa7dF\xfa>l7\xd9\xde\xa7H\x07\xa5\xac\xa7)\xda8\x18\xe9;\xd8\xd0F%\xc7\x1c%Xo 2m\xe3\xc7+\xb2\x19(X\x1c\x14\xb0\x1bq(\xd0=\xf0'\x82Q=p\xa1\xb8\xccF\x0b\xb4\xa4~\xc9\xd8\xd2\xca)\xd2J\x9aKM\xd3\x12M\xac\x954\x0d8\x85*Z=\xde+\x89R\xd4\xca%\x8dR\x92\xaa\xc0J[.a\xcf\xfc\xa0\x03jY\xd3\x82\xc6\xe2\x82\xf0\x82pt\xd2\xef\xab\xf5\xed\xf7\xf9\xa8`R]\xa56\x88\xe3\x83\x8b\x01\x10 \xaeQ'68S\xb7\xd40\xbfb\xc3\xaa\xe4(o\\\xe1Q>\x14 \xde\xa1=c\xde=\x9bx\xc8[\xef/N\xf9\\6W\xcf\xa6U{B\xaa\xd3\xab\x86\xf8h\xed\xff\xec\xfc\xccIA\xd3\x9c\xbc\xd4\xccp\x14t\x9apB\xe4\x80\xf5\x88\xecFd?\"\xe1\x88l\xbb\xd1\xc5\x03\xa4\xf4\x01t1\xa8\xd3\xc5\xd4\xd0E\x0f\xe8b0\"g\xedt\xd1\xeb@\x17\x13rE\x02K\x17\x15\xd1\xf2\x90.n\xc8%\xc6p\xe8?=G\x8a\xb6\x86\xac\x15\xea\xb8Ac\x9c)R\xa4\xf5\xe0\x82lj\xb4\x12\xc8\x80\xaf\x00\xde\x1c\x80f\x0fM(\xc1R\xc7m\x1ca\xfc)\x03\xa4\x82px\xa5(\xc3G\x04\x0fZ\xb6\xf5\xed`\x1c7\xea\x91\"\xc8\xe4\x9a\xf4\xc3:`\x16(%O@\x86^\x0fSw\x83\x02|\x1a<\x07d\x17\x03\x05\x8c\x93\xad\xd8\xd2\x9a)9J[\xde\xb1U\xbc\xacoX\xcdtD\xbcA\x99M\xa4\x93|s2\xdf\"w\xa8\xa6\xb9.\xbe\xe8\xb8\x9c\xa1\xc3\xe4\x0d\xfc?\xecK\xe9\x8a7m>\x1eS\xf1[\x99\n\x10\xccB\x17\xb4\xc7\x8eR\x92\xb6\xa1>\x92\xff\xf8\xc7\xf3\x9f\"g\xf1\x1b8K\xce\x99\xfc\x1agr\xf2\x1f\xffh\xfe\xe3\x1f\xe2?\xe9/\xc4\x7f\xfcv\xfe\xe3\xbb\xf8\x8f\xff7\xe5?\x0fA\xc1F\xfc\x83\x01\x8fpw\x07n>\xec\x0e.\"\x97\x84_\x90H\xed\xe0JX\x01\x08\x16\xcf\xa3\xe5\xc0\xce\xba\x99\x07\xbd\x03\x11f\x00]\xbb\x10\x91{\x8b\xfb\xd7\x1a\x0d\x90\xcaK\xdb\x0c\x18\x80\xfar\xc2{d\xb5\xf4\xa4b\xf8LJ\x0b\xd9\xaa\xd5\x816\xb1\xfc\xa2\x9a\xddx\xd6B}\xb5\xe8\xdfz\xc5c\x17\xa4\x06\x85\xf5\xc7\x8cB\n$t\x85\x8b\xe6F\x1cF2\x0f\xe8\x8a\x05#r2\x053\x1cGUE\xfdV\xb9\xae\xe9\x88$Z\xce\x0e\x14IMM5}`'z\xfb\xcc\x06#r\xb2\xa9^$\xd2\x93\x9d\x0f\x05\x18%\x0e\\\xdd\x04\x04\xa4\x96\xe4\x95K\x8c\x0en\xd6I\xbeaw\x9c\xc348Q\xd1\xdbpo8\xac}\x06/Q\xb9\xb2\x83:\x15\x1an0\xa0']\xe0%\x0e\x98[\xa0%\xfa\nmK\x90\xc3\x96\x0e\x11\xdd)\xdc% *^\x93>lG\xe7\xcbAG8+\xb4\xbf\x19\x12\x81\x0eh\xda\x82\xcdv\x006\xeb\x08V\xa3\x8e\xc6\xfc\xac\xae\xc6eEh~\x06\xa0\x96j\xac\xfa\xa50\x8c\x1f\x0c}\x95U~\x8cQ\x1d\x8f\xbd\x06\xb8\xe0\xe2\x8a\x82\x1eh\x02\xd0&\x886\xab\xd7x\xfei9\xc8\x97]\x91ji\x83\xf5l\x80\xf2\x8c\x9b\xd3\x9b\xdcs[,\x97@\xac\xf6<_$q\xd2\xcf\x03\xbe\xc4\xf9\xbe3\x8b\x04\x9cg]\x17\x13fJ\xac\xe1\xa8%\xe5p\xa3\x87p\xb5\x1c\x1f\xba\xe6\xf0\x98\xee\xe1\xab\x0e\x0e\xd6Z\xc3|\x1b\xccj\x98\x12\xb7\x14\xe2#G-\xf6\xc9\x1ft\xa3\x84\xc4\xd1\xcbC\xb8u\x10q\xea4\xb2\x96\xd2\x0567\x95n\x83\xae\x05\xb2\nT\x1f$W\xd9d\xbb\xbf\xe6\xcd^\xfdruo\x7f>\xee\x0f\x16\xf3\xc5\xf2\xe7\xf7\xc3\xeb'\x93O\x16o\xe4h\xf6\xeb\xcb\x93\xc5b9\x00E\xf0b\xf1\xc9\xb4\xf71\xf6\x10\x0ey\xa5\xb8\xbb\xef\xb0\xb7()\xcf\x1a\xb6\x0dy\xce\xef\xd9\xf6\xab\xbb\x04\xc4]\xb8&\xd4\x7f#\xe7=\x08\xd2\xb8\x88\xfa\x83\xf9\xf2\xf1\xa27\x19\x9d\\\x8f{\xfafO\xaf\x87\xc1\xb7\xb8\xb9\xdb\x83\xa6\x82\xcbA_\x95*_t\xaeC\xd31n\x97\x9d\x804[\xa5\x82\xf7\xa7\x0e\xbc\x1cL\xd2\x98w\x0cN\xaa\xeb+\x9ck\x9a\x13@W\xbd\xa5\xeeI\xec\xdf\xa0\xff\xc9\x03\xc7\xa5g\xe4\xa3\xc2h\xa3\x82\x04_\xfa\xeb\x11\xe9m{j\xe7\xbb\xb1\x92Q\x9e\x17E\x933$\x98\xbb\x92\xc0\x1e\xa3\xc0\xee\xa6+\xd5\xed\xdd\xce\x9c\xd5\xba\xf3\x93\xe2\x86\xb2\xafH>\x14\xb0\xd2{eo\xf9\x12\xe8\xb2\x18\x8f\x9bk#\x06\n\xc1\xee\x84\xdeLP\xbd\xd9\x1b\x1c\xdc\x1b\x9a\x9f\xd5\x80\x9f\x8d@OF\xf3\xdd\xc6f\x12\xd0T|\x13\xad\xd9\x1d~\xf7\xb4\x0c\xb7g\x81\x11\x8d/@|\xdfL\xd8\x1d\xf3\xfa\x19\xe8-\n\xa5^\xa2\xfa\xfc \x95-\xfe4e\x83N5\xd3\xd9\xe2\xcf\x8a%\x99\xde\x98\x06#\x92\xa0>\x8d\x0cI2\x9f.\xf5\xe0v\x08EG\x0e\xf1\x99\xe2\xef=\xb8q>\xbeo\xd6L\xadc\x07\xb5\xb6\xc5\xb1\xde\xb5\xb8\x91\xcc\xcf\x97\x1d\xa2\xe7\x91\xc3\xf2b\xf1\xf7\xd0\xee=d\xeaT\x0f\xba\x15\xf9\xdb\xcc\xce!>_\xfc\x1d\xe0\xf9\xc5\x9f\x82)\x80\x05\x93/\x921I\xe6O\x0d\x8a6\xabR\xcc/-ho\xfa\x01\xb9$Y!\xe1!\xfd}\xc8t\xd9\x95\xf6K,\xa9\x12aT\x04\x0d(\x8d\x91\x98}\xdd\xf4\xd9\x08\\\x1b\xa4#bR\x04\xea\xb4\xdb)\xe6\x07 7&\xd5\x1cZ\x9c.\x86c\xb9\x98,&rq\x8d\xff\xc9\x93\x93\x93\x139\x1a\xc9\xf1\xf8\xb4~\x98q\xba\xe8\xf7=)B\xc9e2X\x0cN\xb7~\xfd`\xa3>w\xde\x8c\xf4\xfe\xfb\x7fsL\x11W\x1f\xfe_\xc7\x87D}\xf8\x7f\x1c\x1fD8#\xbd\xbf\xfe/\xffw\xaf\xf4\xa5\xc1\xda\xa6\x8b4\x95\xcbQ.iIk\xab\x8a\xbe}\x1a\xe4\xa5\xd2\xde\xa8\xc8\nS\xcd\n\xd3&VXc\xc4v\xd3\x94v\xe7\xc7\x19)\x97;\xcc\x96I\x91\xed*,\xcd,\xdb\x85\x95 gQ9/U\xafx\xd0<\xc8Oz\xfa=<\xa3\xb9&\x01\x99\x91\xc0J\xc3\xf1\xa8\xdd\xf6\xac\xfa\xd3\xd2\x97?\x17\x13\x11\x7f\x1b\xdf2\xfe%MY\xbfbtS\xfc\xa9e\xc6'\x82\xa5\xa2O\x07\x16^Z0\xbf\x18\x8eA\xec\xfe\xef\xff_oPH\x9d\xfc|>z\x0f\x1f\xfe\xfa\x97\xffZ\xfc\xd2\x9f_\x9f,\x07\x7f\xfd\xcb\x7f\x85\x8f\x9fL'\x93\xfa\xd7\x9f\x9f\xe9\xb2\x9fL\xd5\x7f\xc5\x0c#[\xef\xa8T\xee\x8d\x9c\xbf\x19/\x07\xe3\xf1\xb8\xaf\x1e\xe4'\x83\xd3m\x085\xfc\xf5/\xff\xfb'\xe7\x95\xbc\x8bt0\x1e\xf7\x17i)\xdb\xffV\xcb6\x7f3^\xa4\xaa\xd2>>\xd5\xb3\x83\xff\x96\\mM?\x8an\xd5\x12\x8d\xf9\xe3\xde\xd2E\x1c }[\xa7\x08\xa7\xf3\xf1\"\xc5\xdd\xd1\xf2\xd4\xb5\xc3\xa2m\x16\x8a'}a\x0e\x02\x01\x7f\x8d`\x0e\xd3~\xe2#\x120\x85\xbc\x85N\xd6\xdb\xc8\x0e\x98^\xdb\xad\x04\xd0em\x10k\x13\x914WF\x91<\x80\xde\xf8\xceM\x9b=\x92\x1d\x91\xfb\x11Y\x8d\xc8\xdb\x11\xb9\xfd0\x82t\xab5\xbf\xab&\xc2\xb4\xd2\xc4`u.\xc5\x9a\xccFaK\xaer\x88a\xe8\xb60tx\xfct;\xdf\xea\x9c\xe4\xf2\x8al\x06\x17d;\x1e\xb7\x9c(\x99_a\x0c\xb6\n\xb9P\xae\xd2\x9b\x14\xd8_\xd9\x15<\xe8,[\xb1\x19v\xe1\x82(\xc1\xca\x03\xc2\x18\x97vAz\xe3\x13\xe3\x86\xc7\x1f\x0c.\xda\x87\xd9\xfc\xc0\xd7\x07\xb9\"'\xb4\xafPX\xefN\xc6d\xaa\x05\xc2\xd4\xeeW\xa6#rO\xaeH\xef1NL\n\xa6\x89\xa0:\xc0\xb2\x01\x1e[']\xe6\xc3\xfcT\xeb{U\xc3zDB\xf57\xe9\x06\xb5\xf9\xc1\xa0\xb4\xcdc_\xcd\x83\x9a\xcaQeJ\xc9f\xa0\xa7\xf4\xa8\x06\x89\x06z7I\xfdh\x1b0\x18\x8a{\xd5R\xa1r\x95\xb69f\x18\x8a\xbf\x1c\xe0{rM\xfao\xe7;\\j\xc5\xe3\xca\xcc\x91<\";\xb46\xc8\x89 Z\xc4\xce\xcf\x97\x15\xb6\x91\xf5\x0b\x02\x80\x9e`G\xb9\xa7K\xd0&\x7f\x0c\x10\xce\x1e\x08\xc2t\xa9X^qI\x1d^+\xae\x9fj\xca\x8f2V \xbe\xd1\xe5WW\x836\xfd\xf6\xe4\x9a\xdc\x1e\xb3\xcf1?\x18\xc5V\x1d\xb4\xeb\x97\xc4\xe9\xcc\x0e\xddQ%\x11ug\xc4\x11\x07\xbb\xed\xa7\xf7J\x9b\xce\x85\xc0j5T\x8b\x03VH\xff0\x02\xf4\xfe\xfa\x97\xff\xe2\x8a\xa0\xea\xfa\xbd',H\xd9G\xad\xfa\xa3\xee\xc1\xc0\xc0\xbc\xea\xf8\x15\xe4\xa9\xdb\xdb[\xf9\x1b\xb9\x98-N\x17\xa7N\xb9\xc9o\xd4L\x9f\xbe\xb9\\\x9c\xd2E\xfa\xe4\xe5\xa9\x91\x90\xda\xc5#Z3^7F\xe8s\x87^CX\x0b.7\x06\xab\xce&\xe82\xaa\xf9\x9c*\xe3\xc1\x8c\x9c4\xc4\xae`!\xf5[>\x8b[_\x08\xc6\x9b+\xd7\xf2\xf2\xd7Q!0g\xd3\xdd\x16\xf3Ko}\xe1\xed\x14\x92l\x99x}\x9f\xb0\xfeA\xa1\xc1\xa3)#\xbd\x8c\x07\xbd\xd9Add\xc7\xacy%\xb2\xccH4\x81\xc8dl\xfd\x9a\xddu\\\xf60\xaa\xd0\x83?\xf1\xc0\x11\xf9\xa6\xfak:w*\xfe\xe0\xc2n{6\x1c\x08\x98\xb5\xbf\xaf\xa1\xe8)\x90D\x0cjF\x18\x96\xafTB\xbf\xb0\xa3z\xa3s\x9c\xfa\xa3\x92[\x9b\xa6\x9f\xe3\x0c\xcc~j\xfcb63Sg\x8ez\xb9\xea\xb4\xe8\xf2\xf5\x11\x0b\xfc\xe8&\x9d\x11V\x1f\x12\x9a\x89X}U\xcb\xa4\x1c\x93\xda\x15L\xea\xd8\x8d\x0co:\x80*\xeee\n;\x80:|jg\x12eA\xab\xe2E\xdf\xc3i\xd8\xe3\x14,\x95\xee]\x96J\xce\xb1\xaemk\xee;\x1e|\x14\xb6+\xa0o\xb9\xffX\xe7\x1f\xb9\xdb\xa0\x1eXD\x822);\xea\x14\x04\xea\xd1\xb7\xd0\xb5\xdc\x9d\xabr\xb6 \x9f[Vw\xfa\xe6\x92\xce_.\xd2\xa5a\x0d\xdb\x01\x1a\x87\xea+\xa3\xbb\xf1xD\xfc~\x9a;\x18P\x89\xc3\xe1@\xc9\xc6\x90\x0bR\n\x9b\xaf\xbc\xad\x18k\xcc\xcbv\x01\x9e\xe8\x0e\xac\xe0\x90Q\xc9\xf9}\x85\x1b\x14.\x13(\xf4F\xa1\x7f5\xc91\xda\xee:l\xaf\xf6\xa5=e\x08\x05\xfb\x81\x82yo\x15\x06F\xbc;L\xf1\x88\x99tOo\xa3\xd7\xd0\x9a\xde\x11np\xc7\xba!\x97\xb6Y4\xbe\xcdM\xdf \xce%\x15\xec[\x05\xc6~\xbeYN2\x1e\xa0\xa6J\xdb%\x1b-\x1a|\xd4;T\xf5Y\xb5\xb4\x1e\x11\xef\x18\x12I\x1e\xa4\x0d'E\x8dx\x90\xab\xa5\x93\x8eJq\x92\x0b{\xebN\x05 \xb2\xc0C;f\x1d\x8c\x1d\xd1;m\xcc\xab\x87\xbf{9}`\xd5f&T\xfd\x99\x81\xe8p.E\xb4\x02\xf3\xa1#\xf1\xd0)\xb6\x98\xd6\xbd\xec\x91\xd3\xfb\xf0>\x15h\xe0\xd1\xd0\x8d\xc7\xdd\xe1\x0b\xd0\x92\x1eP=!\xc3|L\x0c\x91\xe8 \x0e\xa9_P8\xb4zh\x9f\x1f:\x8fG \xf2\xd1\xf3w_9\xbb\xcaJgWY\xf9\xec\xca\x1b\xd9\x834}vu\xb0\x9d\xf6m2\xee\xd5\x0eV\x82\xe7\x1e\xe3\xf1\x05pI\xadM9\xb9\xb2\x14\x9a\xe0\xadmC/\xe0Sf\xac\xd7/\x06\x8a-\xdb6:\xed\xe0\xf6:(\xe2\x88\xf89z\xc4\xfa\xe6+\x1a\xc0\xd9\xe2U\x8ew\xfa\xe4\xa4\xdc\xa1'\xe4\x0b\xcb\xc7&?\xa6\xd5\x8fg\x93\xe9\xf3\xc9\xd3Jj5\xd3\x97qr\xcf\xfd\xedN\xf4\xbd\x019?\x9b>'\xff\xcc\xd96\xe6\xf7\xe4\x7f\xa2^\xbcJ\xc9\xe5\x96\xb3\xedo\xd4?\xe3\x1f!e\xe2\xc5\xe1\xcbj5\xaf\xbeyM\xbe\xf5=\x16\xa5l=!\x85\x18\x86j\xdc\xd28\xe3\x1e\x83X\x86\x01\xe6IOC_\x8c\xf5\xcb$\xd9%\x07\xa0T\x15\xa6\xb3\xd3\xd3\xad/v\xd9JAp\xaa B\x80N\xdbF\xe1\xb4\xf4\x0e[\xd1Q\xd9\x80\xbd\xddF(\x9e\xfcI\xf8\x81q\xb0\xae\x9d\xe2W\xac\xc4\x9c\x02v\x9c_\x94v\x9fe\xc6Q*x\xe6\x89\x98\xcfH\\_\x88\x19\x0fR\xf7\xb6\xb5eG\x9b\xeff\x1d\x1f#v\xfb\x1f\xfch\x1d\xdf\xba?\x97\xb7\xda\xae\xcay\xa6\xd6.\x9b\xe9{3\xf5\x1c\xc5X\xac.'\xd0\"\x0c\xbe\xa3\x14\x9d\xf8\xe9\x97A\x9c\xa2\x13\x9ck\x18\x89WT\xec&!\xbd\xebGj\xaf2R\xd2\xfc\x0cvK#\xa2\x1d\nT\xfd\xd5\x17\x7f\xa0KC0\"\xe1\x8b{\x0b\xc51e\xf1\xeeV\xab.\x86\x98\xcb\x8bfz\xf5N\xf0\x07\xc1[\xdbP?\x0dJ\xd0\xb2OGX,\xcc\xce\x8cnV\xa5\xe9\x04\xb7F|\xb5\\\xef\xddX\x8d\xc0w\xc1mc\x8c\xa8\xb1\xfaU\xbe\xb6\nj\x0bf\x02w@\xa0,\xc8\xf3=\x94\xfb\x17\x1a\xe8\xa8\x03] s\x15\xef\x02#,=\xf74\x14\xc1\xb7j8bb\x19\x95\x93'\x1e\x0d\x02\x13%FS\xe9\xc1(\x8f\x86te\xa3! rM\x04\x99\x91\x13\xbco\n\xbe\\\xec\xe8\xa0V\x08\x8c\xc7\x05\xf1\xa3T\xd0\xc8S\x85\xe2\x89\" \xaf\xe9V\x15.\xfa\x83\x9a\xd9\xd1}m\x89R\x7f0Y\xa9\xa7>+\xfaY\xea2\x88%\xd23k\x16\x05\xcc\xcf\xa8V\x01\x86\x9c\xbc\xb6\x0e'\x83\xcd\xb1\xa3\x94 \xe0TH\x9a\xe4\xd0\x0cF\x8e\xb3\x0cw\x17^\x15i\xf8q}(\x90\xffc:Q(f{QH\x9b\x141\xbf\x99T \xcb\x85\n\xd5c3\xa9\xd5\x1c\x18r\xc2ssV\xcb\x91!\xb3~k\xce^b\xc2P\xa4\x90\xe2&.\x83#f\xe6u\x81q\x1e719\xcb=f^\xf2RvZ\xbe\x80\xdb\x11\x85\xc5\xd2<\x1f\x05\x81\x05j\xb3\xef-\xc3me\x14l_\xbf6\x17(\x88,H\x05\xcd\xfbQ\x83]Jy?\"1p\x99C\x9e\xb3H>n06}\x81j\xaa~U\xc0\x1c\x19t\xd6\xbe\x7f\xe2\xf2\xaa\xfd9\xcfPIS\xb2\xabS\xfa\xa4\xabTp\xea\x89WL\xec\xe2u\x07d\xc0\xa0f=S\xae\xd7\x05\xe1Ph\x9e\x1d\x1e\x04R\x94\xc3\"\xe2G*\x9b\x98\xech\xfa\xc7\xdb\xc8F\xa3\x8fP\x14a\xf3hI\xd0#X\x03\xfb6\xb8\xd8\x05Fv'X\xb4\xee\x08#\x80\x87\xf2\x1f\xcb\xc5\xfbf\xe4\xaan\xe7\xde7\xdc\xcc)m\x15\x1a\x16\x98\x91\x18AW]\x1b\x9b^a;\xd1\x1b\x00\x93*\xa4\x90\x0e\x13L@\xde)\x14\xd2\x81F\x90\x99R\xbe\xcd\xc01V\x83\x843(u\x01\xc2\x03\xb6\xce\x0d-\x81\x07q\x19\xe9$\xcd\x12\xc6a\x01\xe2\x0d\xe95\x0b\x98`\xe5\xae\x8c*;2\x8a\n\x84\xa8\xd3\\\x07\x81\x9f\xa4~:k\xdd\xa2\x17\x7f\xd6\xa4K\xebh^b\x90\x04\x98\x83(\x0b\x02%VD\xe4\x9a\xf4&\x93\x9e\x12~1\xbc\xa21\xf6Rl\x1f\xf4\xfcc\x12Y\xd5\xf1\x90D] \xb6V\xecvDN%\x0f\x7f\xc19\xbd/x\xe8\xd25\x0c\xf2\x8e\x18eq5r\x83\xf9\x15\x96\xa1\xdd\xeb\xb0\xceG\"\xc4\x9c\xbb\xc0\x1aU\xd2\x95m:j\xc5\x87q\xfd8\xcb1 p\xff\xe5\x8bh\xfd%MD\xc6\xd9\x11\x03s\"&\xdb ^\xd1\xc0\x11\x9e\xf1\xcfP\xed\xf7l\xcb\xee\xfeL\xc2,\x15dG\xf7\x8c\x88\x1d#\x8f\xb7\x8f\xc9&\xa0[\x92\xb2Z`F\xf3\xcbG\xac\xb23\xbc \xb8T\xc1@\x8a\x81\xcf\x00}\xb9\xb9\x80\x1f\xf1\x08\"\xe9\xad\xd9\xdd \xdf7Eh\xbf\x82\xe1(\x8c9\x94Jl\xb5\xdf\xb2\x1b\x8az#Pw}\x84\xeb\\\xc6H\xb9Wf\x99!}\xec\xe3m+W\xdc\xdc\xdb\x9d/X\x9aP\x8f\xc1\x08\xce\x08\x04dr\xec\x0f\x8a\xfa\x8e\xc3\xdb\x02\xb7\xde\xc5\x86+\x8d\x18W\xa0\x1a9#O\x90\xb2\x98\xf2\xfa\xd5\xb7\x9d\xf0\xcanw\xbb\x80V\xdc\x96\x08,\x86\xa1UE12\xa5\xf95\nb\x95\xe6\x8eiMJ\xd2\xeb\xc4\x81S&\xbe\x10\xe5\xbdb\x87\xbbkzC\xa3J\xa6\xfd\xc1\x9c-\xf30\xba]\x1a\xdd\xd6\x1b=\xba\xc5.\xed\xe8\xce\xa5]\x1a\xaa*xtK\xad\x0b\xa9\x82\x829\xfeu\x01n[\x07\xae\xcb PU\x06d\xe8\xc2\xebU)\x0c\xae\xf9\xb9G\xe4K\xc5>\xbb\x8cH\xb1U=\x92\xfd\x1e0\xdf^M\xc3I\x1a\xe4\xbb\xf5\xbass\xb9\x9a\x0d\xd5hf\"\xa0\x82\xfe`\x94\xc7^\xac\x10\x14\xd4\xaf\xe9\xb9\xd0\xdc\x0bo\x11D\xe0\xf8\x1d\xefDr\xb5\x13W\x94\x17\xef/\x98\xc4\x0b\x98\xf4l\x92\xee\xfc\x8d\xe8+\x12<&\xb8\xed\xf7QrP\xdc\x9c\"\xc1l\xe2\x88n\x1c\x9d\x189\x85\x16\x03\xcfu\xc5\x0e\xce\xc2x\xcf\xfe\xee\x07\x8f\x16oX\x95FR\x0de\xbbv\x13\\p\xe2 _\xc0\xa8\xc3\xb1\n\x8e\xb7j\xc1c\xfdtD\x1c\xd7m\xc9!\x8d\xd9G\x9d\x89m}\xc9tY1\xb5\xe6;\x93\xe4\x1dM;\xcf\xbb\x15\x8e\xd0\x9a\xa3GzdX\x9d|\xb8(\xdc+\xdc\xa5\x81LL'w\x81(e\xe2\x1b\xc3?\x8f\x80\xaa\xc6\x89\x8f\xe3\x80\xae&\x8fk\xb1\xf3\x90\x1b\x1d\\\x87\x96J:\x8f\xa2\x16\xbcE\xe5`\xb2\x83\xce\x0f\xb0\xe2\x07\xc1\x0f\xf0\x96y\xef\xb2\x87\xd1\x95 \xaa \xf5\xdcb`2\xd2{\xd9\xcb\xa3\xf8\xda\x91R+\xbdwy\x8a\x05{/{\xcb\xa3T\xc7%\xf0:\x0c\x05\x8a\xcd\x96\x0bYA\xbe\x1a\xc5\xcb\xfc\xaaC\xa7\xd7G\xfb\xc0\xcd\x97\x87\x84j\xe2G\x84\x0d\x08sk\x03\x84\x16\x98\xc9\x90<\xc6\x08\x0b\xb0\xf5\xc0\xa8`\xed\xf4<\xa7\x16\xf5\xd1+\xa5\xbcW\xa2xMou\x84\x88\xfcQD\xdf\xceS\xdc\xa5\x89\xa2\xd6\xc9\xc8\xfcm\xbe?\x8c\xb4\xda\xa3-f\x06\x14\xe5\x1d\x98\x7f<\x0d@\x14`\x85\xd3+T\xb5\xe3X\xfe\x9e\xb3M\x7f\xd0\x82 ~N\"\xa0R\xedoZ\xcf\x04\xbb\x13\xfdBm\xa8\xb7oROt\x19\xbd\x02\xcc\x1d\x05f\xb3On\x1e9bm\x87Dc\x1e\x07(\xe6g\xf9:\xc2\xf6e\x8a\xbcC\xed&\xdb\xe6\x95\x1b\x13u\xa3K1\x1b'\xabA\xd5\x190\xb6!\xb9\"\xbd\xb7\xab\x80F7\xbd\xae\xaa\x942<]P\xae$\x81[-k\xfb\x12\x85\x93\x9a\xa1\xa5\x8dC\xd2\x1b#s\x9bu\xa4\xfc5\x8c\xe9\x02\xa9Uek`\xd7\xf1k\xadF\xae*f\x89\xbb\xd5\xbc\xc0\x11\xcd\x19b\xa2uT\xf6X\xce\xa8\xb0\x15\xbb\xc3@\x1e\x93\xef\xfe\xf8\xc37\xaf\xbf\xf9\x97\xaf\xde~\xf3\x87\xaf\xbf\xf9\xc37\xaf\xffc7\n\xe6<\xd69\x82\x8c\xa9\xf2z\x8f\x0f\x1a\xfe\xd3\xfe\xf5\xac7\x7f\xd3[>\xb9\xee\xc9\xc7\xf37\x8f\x97O\xae\x1f\xcb\xf9\x9b\xc7\xbd\xab\xcb\x97\x7f^\xa4\xcb\xe1\xe0\x14\x19\xdc\xe9\xfc\xcd\"]\x9c\xf5\x1e\xbf\\\x9c^-\xee\xce\xa6\xe3\xc5\xdd\xf4\xeb\xc5\xdd\xa7_/\x87\xa7\x134\x0fQ\xb3\xdb\xbf\x9e-\x16\xe9\x93+\xf5O\x0foM\xdao\x83\xeb\xde\xa8\xe8\xcbd\xaer+Vy\xd9?\xf9\xdd\x1f\xbf|\xfd\x1f\xbf\xfbj\xa0^u\xeab\x91\x0e\xf3W1\"= \xeeQ\n\x15\xaa\xcf\x83'\x86\xdb\xe2\xbb,Tq\xd9?\x85F{\xe0o\xe6t~6\xfe\x9c\x8e\xdf}1\xfeO\xcb\xfcq\xb6|rZ\xad\xb3\x0c\x81\xb0\xad\xa8^\x9d^\x17\xda\xcb\xf9\xf7\x88\xf4\xb6~\xcfE\x0b\xd5\xa0\x7f\xb9\xa3\x9cz\x82q\x13Q\xddhZ\xfa\x8f\xa2U\x9a\\\xc8G\xbf\x9e\xbe8\xbb\x90\x8f\x02\xa1\x9e\xe1q\x8b\x8f\xe7\x17\xf2\xd1OY\x0c/O\x9f\xc1\xbf\x9f_\xd4\xaf\xdb\xab\x1f\x989tA\xd8\xd2n\xa4\xb0\xf7\xb0\xf8Q\xb2\x8c\x98//PUzb|]\x82\xf2g\xfe\xf4@nE\x10ON\xc4A7\x1bAE\x93\x1b\x8f\x88\xd0\x9a\xbaf\xab\x81\xc0\xaa\x87\x91c\xa91Ut\xe7\x8bh\x0d\x93w\xff\x87x\xcdR0'\xf6At\xd1Zv\x7fD\xa2\x81M\xec\x17h\xfeWh\xa4\xa1\xca\xf5\xb5\x8f\x81\x81\xd6\x0d\n\xab\x1b\xa4M>\x86H\xe3fJ\x89wq!@\xc9\xa1\xa9\xf0\xaa\xc3\xd12\n^\xb7Q\xf0\xdc\xa3pD'4\xed\xf4\xbbP\xe5\x06(\x8e\xc3x\xad\xdf\x8dr\xb2Y\xd1I[\xba\xdd\xbcp\xf5~]\xaf\x8f\xc8*\xd79Z\x0eA\xd0\xb1\xf3C\xd3\x01{\xf89\xef\xb02\xa29\x07/\xb2\xcd\xd3E\x0b\x92t\x01\xf3\xd4X!\xda)\x84\xcb\xdc\x99\xf2\x91\xecg\x0f\x99\xba\xbaX\xd4(m\x14V\xc2\xd1'85\xc3\x86\xe2\xb2j\x11|Adh9\xe1\xb3\x92q\xc5\xe1Ds \x0f\xad\xa8\xaa!\x83\xcc\xef\x18Q5\x1f\xfb.H\xdc8\x12\xf9\x0c\x1e\x1c\x88\x0f\x06\xd9\xe0\xd4\x87\x00l\xf1\xf2\xe3\x81\xfb\xabr\x06\x87\xb4\xa4\x1a^\x9e\x8e\xb4S\xb0I\xffz\xe6G\x82\xf1\x08\xbc\xf4\xd1@Z\xf2\xe7\xc7\x91z\x01\x92\x14\xf3T2\x95-\xe1~\xcaR\x99\xecb\x81^i\xeee\xc2\xe35fO\xe5&\xce\xa25\xd4$\xfd0\x8cW~\xe0\xb3H\xfa\xd1:S}`\xa9\x0ciD\xb7\xb0VU\xb9\x84q%tI\xc1\xbc]\x14\x07\xf1\xf6^z;\xee\xa7\"\xa4\xa9\xf4\xe20\xcc\"_\xdc\xcb\xb5\xcf\x99\x82\xe1^\xb2u\xe6a\xf5\xec\xa7\xccO\xa0\x1e?J\x85/2\xc1dH\xf9\x0d\x13~\xb4\x95i\x1cd\x08\xd1\x9eb\x81T\xae(\xdfR_=\xc4\x99\xf0\x7f\xca\x98\\\xa1\xa20\x95j\xfb\xaedf\xe9\x05\x8cF\xf8\x10\x8b\x1d<\xc4a\x92 \xc6\xe5\x9a\x85\xb1\xc7\xa9\x90k\x9f\x86q\xb4N%\xf4\xdf\xf7R\xb9\x8b\x83\xb5\x1fmS\x19\xf8\xdb\x1d\xb4\x9fP.\"Us\x12d\xe1\n \xca\x92$\x80\xber\xeaC\x13{\x16)y4\x95\xd4\xa3k\x16\xdeK\x8fr\x06\xd0\xc4aB\xa3{\xe9\xf1\x0c\x06{\x1d\x87\x007\xbbK\xe2\x94\xad\xe5\x06\x9aI\xe5&\x88\xd5X\xc9-\x0d\x02\xc6\xef\xe56\xf3\x05\xe5\x00\x8e\xbf\xa6\xf7\xf2\xc6WX\x11\xc9\x88e\xa9\xa0\\\xc67~Do\xa9\xe4\xcc\xf3\x13\x96J\xce\"A\x03\xf5w\xef\xb3\xdbT\xa6;\xff&\xddQ\x89\xce R\x009\xe6B\xa6\xf7\xa9`a*\xe9\x96E\xde\xbd\\1\x1e\xf8\x91\xf4h\xc88\x95\x1e\xa0\x85\xf4\xe2\xcd\x861\x85/\xeb8\x95\n\x05\xa2\xadd\xa9\xa0\x82I\xa6z\n\xe03.\xe4&\x13\xab8\x9074\xdb\xb0H\x06\xd9]\xc6\xefeH\xfd4\x8ed\x18G4\xdd\xc90KY\x16\xca\x88n\xe3{\x8a\xb8\xa6\xa0L\xa8\xcf\xd5\x1f\x80)\xf6|\x1a\xe0\xa8\xdeKA\x85\x88c)|\x16\xad\xa9\x1a\xe1=\x0b\xe4\xde\xa7?\xb2T\xee\xfd \xa0\xeaO\xaa\xd0f\x1f\x03d\xfb\xf8\x9en\x99\x04\xccF4P\xa3\xbfN\xa5\xb7c4\x91\x9e\xdaw\xc85\x8d<&a\xd1\xcam@S5\xb2Y\xaa\xd0,\xda\xc62\xf2\xa3\x1f)L\xb4^\x0e2\xdd\xc5j\xd4\xe2\x80r)b5\x03\"\xbe\xb9\x8f\xa5\x88\xe3 \x95\xb7j\x8d\xca\xdb\x98\xdf\xa4\x922\x1eK\xca\x13*i\xeaS\xb9b\xa9\x90+\xff\x86\xc9U\x00h\xf9\xee\x9d\x1a\xdeDzA\xb6\x92^\x1c\xabU\x19'rCy(7~\xba\x93[\x7f#\xe46\xe3\x99\xf4\xa3M,\x7f\x8cW\xa9\xbc\xf1o}y\xc3\xd9Z\x064Z\xcb\xc0\x0fc\x19\xf8\xd1\x8d\x0cY\x94I\xb5\x18e\x18\xaf\xa9\x8ch\xc8d\xa2\xf06Q_\x938\x15\xf2\xa7$\x8e$\xf7\xbd\x9d\xe4\xd9\x8e\xcb\x94\xdd\xddK\xe1'\xa9\x1a/\xa6\xfe\x89\xe5-\x8d\xb6\xf2V-\xe7[\xff\xc6\x97\xef\xe2\x88\xa9%%W\xfeZ\xae|\x05\xf0J\xad#\xe9\xb1Xa\xb0Z\xaar\x1b\xef\xa5\x1f y\xe3\x872\xf4\x03\x191!\xe3(\x901\xdf\xaa\xe5/\x93l%\x15\xc0\x82\x052\x8bby\xcb\xd6\xf2\xee\xeeN\xde\xdd\xbf\x93\xd4\x93t-)\x93t#\xe9VR_\xd2@\xd2P\xd2H\xd2X\xd2\x9f$\xe5\x92\xa6\x92\nI3Io%\xbd\x93\xf4\x9d\\Q\xb9Z\xc9\xd5Z\xae\x98\\m\xe4j+W;\xb9\xf2\xe5\xeaG\xb9\n\xe5*\x92\xabX\xae\xb8\\\xa5r%\xe4j/W\xb7ru/W\n|\xe9y\xd2[Ko#\xbd\xad\xf4v\xd2\xf3\xa5w#\xbd@z\xa1\xf4\x14)\x94\x1e\x97^&\xbd\xbd\xf4n\xa5w'\xbd{\xe9\xbd\x93k&\xd7?\xca\xf5\x8d\\\x87r\x1d\xcb\xf5;\xc9<\xc9\x98d[\xc9\xb8d\xa9dB\xb2Ln|\xb9\xf9Qnn\xe4&\x94\x9bXn\xb8\xdcR\xb9]\xc9\xedZn\x99\xdcn\xe4v+\xb7jb\xe56\x90\xdbPn#\xb9M\xe4\xf6'\xb9\xe5r\x9b\xca\xad\x9an\xb9\xbd\x95\xdb{\xb9\xbb\x91\xbbP\xee\"\xb9\xe3r'\xe4.\x93\xfeZ\xfaL\xfa\x81\xf4C\xe9G\xd2\x8f\xa5\xff\x93\xf4\xb9\xf4S\xe9\x0b\xf9#\x93?\x86\xf2\xc7X\xfe\x98\xc8\x1b&o\xb6\xf2f'o|y\x13\xca\x9bH\xde$\xf2\x86\xcb\x9b[ys/o\xde\xc9\x80\xca`%\x03O\x06\xbe\x0cnd\xc0e\x90\xca@\xc8 \x93\xc1^\x06j\xa9\xca\xd0\x93\xe1Z\x86L\x86[\x19\xeedx#\xc3@\x86\xa1\x0c\xd5\n\x96a\"\xc3\x9fd\xc8e\x98\xcaP\xc80\x93\xe1^\x86\xb72\xbc\x93\xe1\xbd\x0c\xdf\xc9\x88\xca\xc8\x93\x11\x93\xd1FF[\x19\xf92\nd\x14\xcb(\x91\x11\x97Q&\xa3w2\x0eeBe\xc2d\xb2\x91\xc9V&;\x99\xdc\xc8$\x90I(\x93H&\\&\xa9L\x84Lner/\x7fR4M\xf2X\xf2T\xf2L\xf2[\x99R\x99\xaed\xea\xc9t-S&\xd3\xadLw2\xf5e\xfa\xa3Lod\x1a\xc84\x94i$\xd3X\xa6\\\xa6B\xa6\x99L\xf72\xbd\x93\xe9\xbdL\xdfI\xe1I\xb1\x96b#\xc5V\x8a\x9d\x14?Jq#E E(E$E,E\"\x05\x97BH\xb1\x97\xe2V\x8aw2\xa32\xdb\xca\xecFf\xa9\xcc\xeee\xf6N\xee\xa9\xdc{r\xcf\xe4~+\xf7\xbe\xdcGr\x9f\xc9\xdb\x8d\xbcM\xe5=\x93\xf7B\xbe\xa3\xf2](\xdf\xdd\x0e\x16\xab\xd3\xaa\xe6\xb47\"\xe8\xffoq\xbb\x1c\xfc\xa6\xbf\xb8\xfdy:\x9a>\x7f?0\xba\xcc\xb2:\x14r_\xcf\xe6\x8b\xf1\xc5\xec\xd1\xd5b\xb8\xf8d\xb4\xb8]L\x96\xc3\xdf\x14\nD\xf6\x897Ub4\xa3\xb6B\x94\x19\x96\xf3\xf1dh\xc5\x87\xe5p\xd6\xbf>i\xfa\xb48]\x9c\x0e\xfa\xd7'\x8b\xf5pqz=\xe8_c\xca\xb5\x13\x90\xbaJ\xb7?\xb9>E\xa5\xaej\xff\xf6\xf6v19\xbadsG\xad\xf6\x17\xd4\xc5\x8b\xb1\x05|\xf8\xe87\xbf^\x9c\xfe\xd3\xd5\x7f~\xdb\x1f\xc8\xc7\x9f\x80@Tg\xe1O\xbc\x0du\xc8\x11\xb3@\x8c\x0f\xaf\x03y\x12=\x1a\x7f\xe2\x81&-''Y\xb7\"\xdf\xb3\x80\n\x7f\xcfl\xb9\xcd\x81S\xc8\xa3/\xfa\x117\x99$\x87NX\x9a\x87\xd0\xd2\xf7\x19I\x9a\xa1\xb54\x7fF\x1cZc\xf3\x0b\xb1\xdf\x0d\xc1~\xba\x10\xf7vj\xd4E\x08\x81\xdb\xe4\x03\xe3bX!\xf9\x17\xa2_\"W\x87\xf8\xb4\x00$\xc6\x95r\xba\xe8\x9fn\x0f\xdc\xb7\x8fJ\xf9\x07\xa7\xdb\x03<\x1b\xb9\x80\x0d\x0e#%9\x1b\x90K\xd2\x07\xf2\x14\x95\x92-!?9\xeb8\xa6$\x9fs\x87w8\x976\xf2UU0\xeb\xaa\x84\xf4#pK\xd5(X\xce\x17\xb7\xcb\x06\xc1rG\xd3\xaf\xb3 \xc8\x8b\x9a\"-\x12\xbf\xa3\x9a\x8c\xfb?x;\x16\xb2\x83\x15\xb8a\xf8\x0f1_\x7f\xa90d#\x18\xaf\x023\x9b\xbfY\xa4\xcb'\xd7\xa6JG\x15E\xe6\xdb]\x1e5\xd3S\x94\x06tM\x7f2\x1dR\xec\xca\xdcb\xc94!\xfa]\xcc\xd2?\xc4\xe2\xf7to)\xf6\x1f\xf9\xefb\xa1\xad\xd3Z\xb2\x7f!\xbee4\x15\x7f\x8c\x98\xe9q\xa5\x8c\x9f~S\x9b\xcc\x9c\x92\xf5]\xe7\xf1\xce\x13\x89r'\xba,\xd7\xea\x82\xd3](\xce\xeb`~\xb6,\x1f\xac\xb6J\xf1\xbd\x1f\xe9\x9e\xa6\x1e\xf7\x131Cg=0\xce\xbd\xfd\xaa\x9c\xd8\xa5G\x87\x86\xbe\xa3\x89\xa0\x9d\xf1\x13\x86\x8e\xe7\xd5\xfa\x07\xfb\x00\xc7:@\x9fw89c\x13A\xdb\x1avO\\\xded\xbbA^\xc7\x82\x87\x81\x7f\x827&NL\x0f\x9aWQ\xcdW\xac\xf99\x91\xa7\x0d\x05\xbb\xa0\x92\x01\xf3\x84\xd9\xf1m#Q\xcd\xc09\x88$\n#P\xf8\x08\n\xf9Q\xf6\xcf]\x06\xef\x01\xc7\xbc\xaf\x8abS\xd7C\xae\xc2\xbe\x18Jv\x84-7\xf5=\x06\xc2\xa2\xc1\xa6\xb3T\xe3<\xc1\x8e\xc3q\xf6W\x98\xc5\x8fs\xe6\x87\x1ej;\x8e\xc2W\xb8\x7f\xe9Zy\xbe\x1f\xecX\x7fq\x94\xbb6R\xf4g\xfb\xc0\x06\x1f\x80A\x0d\x8d4\xce\xa7\xde\x8a\xfd-fT\xef\xd5\xba\xce\xe9\xeb\xf2\xd6\xaek3E\x0d\x00\x96\xed\xd8\xde\x83\xe6\xd88N\xd3\x0d\x82\xe74;\xe1\x0f\x87\xe2\xb8\x89\xef\xfd\xa6k\x93\x8dh\xf0'\xfe\x80E\x9d\xf1\x00\xf7S\xb9\xc2\x13\xc6\xc3(\x8d\xfb\xa8\x00\xbe>uY\xc3VX\x91\xad\xa2A\x1e5\xf9\xbf\xe3,a\xd1\x9a\xad?\x96\xedI\xc6;S\x99?\xf1.4\xa6tO'\xe3\x0dJ\xa2\"\xb6:\xf7\xb8V\x80\xacn\x9ak\x1f\xec\x90\x94}\xc3d0\xa5=\xed+\x10\xcc\xbdGM\x05!\xf4}G\xaf \x0f\\*\xd0\xb2qv\x9e\xfb\xf4~D\xc3\xe4\x02\xe21=\xeav\xcd\xea\xd85R\xbd6\x05\xed?tN\x8c\xbe\xae\xa8P(\xe7\xc3\x05\xd1\x07\xe7XU\xb5\x83\xa3\xf8\x9f\xcc\x12\xc2\x12\xf6#^`}\xcd\xa9\x1f\xf8\xd1\xf6\x87\x80B\xcc\xf6.\xe3S\xae\xb6\x8bl\xe4V\xd1\x97\x17\xb7\xdb\xe1zS\xf3\xeeAy8,Nb\xd1\x19$\xc7X\x1e\x01J\xef\xb4M\xe1Q\xd4\xe0\x1a\x87\xab\xe3i'/F\x8a\xfa\xda\x94\xf7#\xedh\x11c$\xf16?\xa5\x1a\xb0x\x92\xfb\xe5\x84\xbb\xc0\xf9`\xbc7\xbeeFd\xbe\xc4(>\xfd\xa2\xdbx\x1d\x8a\xeaC\xa3a\x1b\x8c\xc8<\x0fa\xde\x1b\x91\x1e\x04\xa4\x86\xf02\xea-\xf0S\xd1s\x85(\x9d\x973Bm\x9f\x7f@m;\xaek9?\xfb\x80Z\xe0\x93\xaeg\xdaZ\x8f\xbb\xbc \xcbm\xea8\xaf\xd4\xd1\x00;\xa3k?\xda\x9aBO\x1f\xd0pP\xa9\xe3\x99{\xf6v\"\x0c\xa0.\x93\xef\xf9\x03\xda\x12t\x15\xd8\x1e~\xda\xa9\x87k\xb6)\x0em\x15m\xdc\x85\x8aPA\xb1\xcf+\x81\x0d\x97\xee\x98x\xd5\x05\x8a\x14<\x0b\xacW\xb6\x8a\xcb){\xdd\x81\xa1\x1b\x1bF.\x89o\xaf)\xb0\xe1pP\xa8BG\x92\x9f\xb3%\xc4\xe7\x82\x87\xe9\xd2%\x8e\xd1@\xcc\x08\xe6<\x87\xf3\x85\xf9r\xa0\xa9\xd2\xa0BzrJa\x9fh\xc1\xad\x11\x04\x82\xf0\xdf\xb1\xaa\x835\x87\xe6\xcd\xf6E{\xfb-\x00\xbee\xe2\xfb,`)\x1e\xa3\xa3\xa3\x04\xec$\xbaH\x10\xe8\x10\xe1dzA(\xb9\xd4GHl\x12\xf8\x91j\x98\"Q\xbd\xf1\x93\xaf\xc2D\xdc\x7f\xebG,\xedS\x08m@\xc9\xcb+\x12\xa1\x17\xfe\x93>\x9b\x88\x1fv\xfeF\xcc\xe9\x12\xae\xdb\xac\x82\x9bo\xa25\x8b\x84\xfb\xfa\x13\x00\xccq\xe0\xe1F\x08\xd4\x12\xcf\xf9Ru\x91\xc2\xf1\xe6\xc9tpA\xf8p\xe8\x90\x130\xea\x85\xf0\xb7;\xa1`\xcfF\x84M\xfc\x14@4\xb0[\xbe\x90\x19\xb9\xaa\x8f\x9dQ_\x07\xa6\xa7y1\xda\xa86W\x8da%#2\x1c\xdaAB\xaa\xa1\xb9RB9\x8b@\xe8\xad\xd7\xda\x12\x0e&\x1f\xe7\xda\xe7\n\x9f\xcaq\xa5\xcc\x0420S]D\x0bQ\x8b%\x99\x82q*W\x1f\xb3\xb3\xb3\xcf\x9e/\xe5|\x91\x9d?;\x7f\xb6\xc8\xce\xcf\xce?\xd3\x89\xd5R\x01\x94\xca\xce\xce\xe8\xd9i!,X\x111\xe1\x8e\x91\x03+G\x84W\xc7P\x81\xe8#\xa2\xb9<)\x03\x02\x94\x92\xe1>>\xb3\xc7\x02\xd5\x9b\xf3\xc0\xe55\xab7\xc2I0\x02'\x10\xb98\x9b\x8eHo\x11\xa9\x14\xabU\\\x88\xde \x8f^W.\x9f\x15\x18p\x93Z\x1b\xd6V}\x0e5\x94\xd3\xb3\x82p\xf2e\xbcf_\x88~4 \xd7:,,F\xf9\xf3t<\x14\x08\xfe\xa6P\xbf\xa7j\xe8i\xda\x00\xee\x85)\x19\x13o@\xfe\x89<3\xc7\xb5\x90\x08\xc5y\x95z\xe8\xd5\x8c>\x15\x99\xf1\x07k\xe6\xc1\xdc\xab\xd54\xa4\xef\x8f\x14q\xf3#f\xfe\xbe\xa2w\x05\x024*\x05\xb4Al\x1fz\x1epZ\x86U?@e\x18kM\x9a\xeb\xae\xae\x96\xab\xdf\x8a\x00\x9c\x0dj\xa8X\xac;\xdf7\xfd\xaa\x0e\x08/\xbaUD\x1e\xd6\x1a<\xa0\xb8Y\xc7\xfa\xe7li\xd5`(\x11\xb0\xa5\xa2\xbc\x85.\x14=\x9f\xbd\x1f\x95\xda,K\x1a\xadM\xd7]\xda\xeb\xfe\xa2(\x87g\x8f\xfdC\x90]V\x00\x1b\xa0\xe8w\xe1\xea%k\x83\xfa\x87\x84zGC\x9cr/\x978\x0d\xd0z\x15\xd9\x0c\x85%\xc8\x1e\x0c\xde\x97;\xca\xd3C\xaezKn1\x9d\x00F\xf6\xe4\xa9\x06\x19\x02\xfdA\xf0\xfd\x96z5w\xc2\x0e\x86\x0c\xd2\x1f\xb9\x04\x97\xf8\xa6n\x07\xdfP\x10\xbf$\x91#b/Z\xaa\x9d4\x0c\xf2x\xccr\xbb\x04\xa6\x96\xedq\xdd\xd92Q\xc7\xdeV \xa9j\x19\xa98]],b\xb0\x8c\x1a=\x14\xa9,\x81\x82\xb6\xe2\x92\xd4/\xaf\xffy\xa0V\x01F5\xf0\xf1\x10\xce,\x87`9\x02\xb7\xad\x8acpr]Z\x19Pjj\x1c\xc1\xdb\xc4Q>\x82(\xc7\xa8~\x0c\x1c\x93\x91iQ\x05|\xb7\xf6\x05\x19\x83\xe1\xac\xf6 \x1a(\xd4\xbf \x81\xa2\xbc\xf1p8\x80\x88ne\xc8\x06j*Ax\x03&?\x18\x01\x07;\xb3)gZ\x1c\xaa\xf54\xc5\xfe\xe0\xc8\xa8\x15&e\xf7\xcee\xf3xY\\\n\x8d}\xd4c\x9d\xd5}UUD+\xb4\x8d;J\xb42\xa9\xee\x90\x83\xee%b\xf6\x82\x0e,2c*\x96j\x12\n\"\xcd%y\x96\x9b\xe3L\x1ds\x18\x03^\\\x81\x8f\x9a)\xee\xdb\x9aVW\xbe\x03\xe2j-\xb9x~\x8b\xdd\x1fl\x02rHy\x15\xd2\x97W\xe4Y\xfb\xc6J\x81:\x1c\x1er\x06k\xf5\x9cZ\x86\xe3\xa3<\xf6{C\x8c*\x1d\x8b\nUf\xb5\xaf6\xe6TN\x05\xd4\x96\"\x1e\x91g\xe0\xe8\xc5va\x04[\xd2ZyP\xc2\xb8\xaf'*\x10\xd3\x19\x99\x8b\x91\x86\xd7\xa1<\xd1\xe1\xab\x18\xca\x8c\xa5\xcf\xef\x95\xf0\x96\x8bI\xef\x7f\x194\xecN\xdf\\\xc7F\xe8|C/^\xb1\x84\x11\xb3\xc8Z\xcf\xbe\x81\xec\xccd\xaf\xa3\xbaG\x86\xe4)yI6\x8dh\xadrM\xcf_\xa0\xd7\x96\x18u\x1def\xe0\xa1\x82\xe3s\xcc\x13\xb7\xd6\x04\x92\xf7\x08%\xe7\xbeg5'\xc0\xda\xfa\x9e\xda\x03\x0d\xc8\x98\xa4\x03rI\x9e\xb6V\xa45\x159\xc5\x01C\xf9\x89\xe0~\xd8/\xeej\xff\xac7\xb5\xad\x95\xf1\x82\x8d]\x03a\x16\x17\xe4\xa4?\x1cf\xa8\xd1A\xc1 :\x90\x16g$+\xcdH\xb6\x04\x9b\xbe\xd2$\xa84P\x7f\xd8<5]P\x03\xb5\xa8\x8d:0\xb1\xb8\xa2[\xca\\\x84\x00\x04\xf8\xe6\xd1\x06\xe5R9\x0b\x8aj0\xb5\x10\xb0\xbe\x81\n\x01\x9a\x9e\xb9\xe9\x0b\x90\x9en\xd4\xc5\x87vs<\xce\xc9MF\x86\x8ae_\x03\xeb\x81\x93\xbfn\xc4\x07\x94\xf1\x0e\xea\x93PN\xc3tFhG\xc2\x84\x8a\x85\x0c\x16\xa7\x93\x1c\xfd{\xa29\xf5\xb0\xbb\xc7Q\x9b\xf0\x10\xb5\xd9\x93\x97$l]\x89/\xce\xb5\xb1[\x05\xdb\xf7\xc3\xe1\xa0\xb5\xa0\x1e\\\x85\xeey\xac\xdf\x90\xde\xfd\x81\xa5\xc2\x8f\xb6\x1f\xb2\xfc\xf5f\xa3\x0e\x13\xac\xe4\xbd\x92\xc84\x11\xc8Y\x17\xab\xeaA \xeaaa,\x01\xc9\xf3\x91\xbd\"{\x14\xce X\xed\x9e\\\x92\x10\xc2\x11\x15\xd6\xe2~@fd\x0f\xd4,D\x81m^\x98\x0d\xa8/\x17[T\x1d\xe3b\x0b#\xcd\x0bP-TS|\x17\x8e6\x8cO)\x94`b\xb3\xa39\xe9\xf7K\xe8\x10\x97\xd0!^\x02`\xfd\x12\n\xc4\xcb\xc1\x00\x03\xa09IZ\xfb\\7\x8b=~\xabXc\x03+\x9fLGpW\xe7\x0c\xaf\xa6l\xec&-!\x97d}A\x92C\xb1\x0b6\xf3d\xa9/eE\xb0\xfa\xdbt6\x04\xaeA4SC\xf3sSE\xf3k\xf6\xd0\xb5k\xedtf\\\xfd\xdb\xc9Q{\x14\x93\x98\xcf\xd1\xa88c\xa0A{\xfa\xf4\xd3:\x8dF\xc1\xb3\x03\xde;\xdb-\xa2\xc8\xf1x}\x18\xe8\x12f\xc7K\xc7\x8a\x0dH\xf9\xc0aT>~\xb8\xaa\x9c{v\xe4)y\x99\xa6\xa0\xc1\x9a\x19@\x84g1\".wue^P \xed\xfb~0\xca\x97\xa8\xd5K#\x11\x8f\xbb3\xbf\x02\xa0M\xf1om\x9c\xdb&\xa6T\x190\xc5\x1b\xe6\xd3\xa5=\x1d\xd2K\x0b\x17\x13\xcd\x97\x16F\xac\xd6s\x93\x90!\x01Z\x94\xcd\x93\"}\xb2\xe9t\x9e,\xdd\x8a\x83\x12\xf9L\xff.xd\x99\x17:\x0cJ\x0eq\xbf~F\x86%9Gm\xd8\xd3V\xce\xf4\xec\xbcE\xee\xce\x80N>zD\x9e=G\xc9\x1b\xa4\xf0\xe7\x07\xa4pX jEN/HF.I\xea<|\xac\x88\xd8\xb5Vm{O\x11B\xda\xd8\x1e\x01\xbfrVT\xf5\xab(\xef\x9a\xfe\x93\xbe\x8f\x1b\x80G\x8fH\xff\xe4\x84k\xbb\x10-\x13j\xa1\xac\xe3b\xd8\xf1\xe6\x85\xfaaR\xdb\xa0z:}\x14N\xda\xe4\xcai\x90\x0b \xf5\xf9\x90s\xa9\xf4y\x9b\x90\x86\\9.\xa3\xe6\x80\\\x93\xb1\x12\xa8\x0dzE\xae\x89\xe6\x15\xf4\x02)\xe0\xd9S\xfd\xack\xe0\xe4\xb2\x84\x07\xf5Zlc\xbc0Z\xf5\xce\xc7\xad\x9d?N\x0e\x8d\x0f\xadD\xf0\x83\xa8F&_&c\xd7\x1e\xb3e\\.\xc9\xb3\xcf\x14ZF\xe4%y\xfeic5\xa8em\\b\xbc\x1d\x08b\x15=m\xa0\xa8\x1d\xdegj\x0e\"ry\xa5\x80i\x13\x9e\x9e\xa1\xee3R\xb0?{a\xa2\xa6\xb6\x88\x16\x16\xb4\xda\xd7\xa6\xe3\xf7B\xa9\x07\xa2\x87yj\xa7\xd7\xb534p\x87\xd9\xb2\x9b\x19)\x01c;\"\xf7#\xb2\x1a\x91\xb7#r;\"_\x8d\xc8\xdd\x88\xfc0\"_\x8e\xc8\xcd\x88|\xe1\x10\xe1\x00\x15\x94\x08\xa9q\xd4(\x14\xb6\x8e\xbc\x0d\x1a;=\x89\xaa\x12^\xaa\xa4\x95lB\x03\xd3\x96Q\xfe\xd0\x8dO\xe8B\xaa\xb5\xbe\xcf\xed\xb7\xef\x8aV\xb8gG\x12l\xace\xb6\xe4\x1a\xef\x017\xafV\xd8T\xa2\xffj\xad\xd4\xd07\xca\xd5<\x911I\xf0~fg\xfa\x1e\xf35\xe3l\xfd6\xf0S\xd1$\x97A\x9e\x19\xd972\x82\xdb\x87KlJz\xed\x08\xea*\x0b\x02&Z!\xfdpx\xac\xc9\xd2[\xbd\x07\xbak\xdb\xf7\x81\x81\xce\xe0\x82\x9c\xf4O\xfa`\xb6\x836\x98\xb0\x81\xea\xdfW\xd5AkD[K[\xe9Rkf\xee\xc9\x98\xac\x958\xf3\x0cX\xb6*\xadPhG.\xc9\xb4\x94\xa2\xa4\xa8uQ~\xa7\n?v\x9dg\x1b\xc6\xce\x17,<0\x80_}\xc8\x00\x06\xd5\xdd<\xea\xc5\xc0H\xc1\xec\xf5\x0b\x08\xbdq\xec6\x8a;\xf1\xfb\xeaN\xbc,\xdd\x82e\x965\x808\xab\xefU\xb4}`\xd3\xc6\x00\xf7\xa6y%j\xaf\xfe\x16f\x11\x88\x99\x1a\xf5\xb7Vn'c\"\xc8K\x9c\x14\xa7=X\x15\xba\xa0\xda\x9b\xb4\x08\xaeW\x83v\xf3\x80\xa9|\xf0&\x050\xbd\xb0'\xf9\n\xb7(tD\xee+\xd2:\xd1\xa6xj\\\x8a\xa6g\xf8~\xbc]\xde\x8d^\\?\xa0\x82\xe1KrE\xee\xec.\xe8\x07rI\xbe\xbc ?4)\x18\x14\xe9\xbd\x9b\xffP\xb4\xe3kW.\xdc\x1cP,4+\x15\xea\n\x05\xd5\xf8M#\xc7W_\xb7m\xf2C\xce\x08)HAg\x83&Eo\xeev#\xe7{\xe52\xee\xe6C\xb7\xa4\xb0\xd6\xf7\xf6\xeb\xad5\x1cXuAB\xc5\xaf\xca\x1c\x04q\x91T\xa8\xf5\x831\xf4\xd6bdn\xc7\xa8\xa4\x8cG\x8f\xda\xcd\x0cHY\xf2G\x1c\x07>?$\xe7\xf5q\x03\x9c\x8c\xf4\xde\xe8\xdc\x08\xcc%\xe6L\xc6\xe4\xbc\x14\xb7\xd3f\x98GKcAevi\xb9\x851\xd2Y\xad\x08\xca\xf3\x0bm\xc6\xd9\xcf\x13U\xcb\xcb\n!+\x14(\xa4G\xe8\xd8\xbc1k\x97\x82\xa1\x7fO\x9b\x8bv$\x08\x99\xb6g\x1b\x92sT+\xf43\xb3\x0b\xf4\x14\x17x\xfe\x99{\x08\x87\xc3lPVDd\xc3\xa1\xc2m\x16\xed'\xe6VCjn\xae\x94\xd2 \\c-\xeb\x84\xb3\x8d3?~\xd0\x85R+\x9a\xe3\xf1f\x80\x0b;S\xcb\xb8\xa1\xcey\x0f\xae\xf0\xa6Km\x1a\xd9\x8d\x04\xda\x9b\x19o9\xdb0\xce\"\xafY\xbdIW\x8a\xda9\xe2\xe1\x1f\x14\xa9\xe2*?\xae\x1d\xf9\xd1\x03RTI\x10\xcd\x06d\x8c\x82S\xf1\x08%+\x0b/\xc3+\xf2\xac.M\x15.\xa2\x14\x1b(1~C\xd9\xec\xd7\xe1U\xedx\xc7\xb6;.}k\xd1\xe0\xe6\x82Z \"Z\x86z\xac\xa1.\xf6\xdd\xaf\xf64\xfe\x90\xd9}03SR\xca\x07\xe9\xbcL\xea\x07Q\xe7\xe3\xe8\xf2A\xad,\x9c\xe8\xb7ka\x9f>o\xd3\xc2\xe2\xb5\xb5\x03\xd5\xe4ZW\xb3\x16\x1cd\xe6\x82<}\x9e\xf3`P\xce\x82\xca\x94\\^\x91\x17\x17\x03\xe2\x83\xf1Wci\x17\xd5;\xe9\xfb\xe4%y\x81\x10\xea\xfa\xb4.&.S\xb5\xd4\xae1kg\xd8OG\xe4\xa9\":\xf9\xcd\x90\xfa\xf7\xe7\xea\xbb\xda\xfae$7\xcc\xac\x01H\xf3\xcb&`=?(\x08DG\xeas\xf1:W\x13\x8d\xda}\x8bX\xec\xb8\xc9\xfd\x11\x94\xbev\x0c;\x02\xebG\xaa\x9dv+\xa8\x9c\xc6CH\x1fm\xc2r\x084\x18\xb3\x07u\xd1\xdb\xf9\xc1\x1a\x1ci\xcd\x97\xb5\x0ev\xec\x97\x99\x84&R\xd26\x0b\xbf\xacZ\xdd\xa4>\xc4\x12pd\xee\xe1\x88F\x8bV{\xa7K\xcb\x10\xcd{GG\x86\x8aa\x8e=\xe0\xe8\xf7K\xec\x91\x96\x88\x1a\xd5:|\xbfH\xc8\xe8R\xcb$\xfdg\xcf\xf3\x8b\xb8\xb5U\x17#mz\x81:_\x8eE\xe2\xf2B\xee\xc7x\x17\xc6BQ`\xb31l\xd7\xfcb\xb9F\xb5^\xe1>\xdc/\xb0\x9cM\x17\xb4\xbe\xe9\xfca\xa8\x7f\x00\xf7:\x82|\xdc\xa2\x06V\x9d\x1f\xbd|\xdc\xe5\xad\xa8\xea\xbf\xf2\x12\xef03\x87W\xfc\xe0# \x16\x85;\xdfg\xe7\xd5\xbb\xdd\n\x81O\xdf\\\xf6\xe7:x\x9fvu=_\xa4\x8b\xd3\x97U\xd7n>f^\x9c:\xb2\xbf\\\x9ev#4#B]\xb4&?\xa0\xa8H\xc5\xb5\xa1\xab\xd8o\xd63$e1\xba.\xbbxJvMF\xe4$\xdf\xdc\xedD\x18\xb4\xca;\x89\xa2M\x8apx\xb0[zyu\xc0<\xf4\xc5\x99{\xeb\xe4\xb5\xef<\x9f\xe2\xa6\xae\x9f\xb9H\x97\xa7w\xae\x8a|a\xbe\xaci_Y8{._rz\xdfv\x1c\xf3\xecS\x00\x1a\xa4\x96\x93\x96\x1b)\xe6g.\xa5<='\xb2z\xf5\xc0\xfc4\x18`t\xf9\xf9\xa7\xaaf\xa1d\xb7\xe9\xf9y-\xfb\xfb.\xdb\xdeg\x9f6\xf7\x9c\xd8c\xa5\xeaV\x11-a\xd1\x95\x9e?(\xb6R\x87\"W\xd2\xb5\xd7\x13\x0f\x0eC{\x82h\xc0\xe7\xe9|Zq\xd6\xb7o\x0b\xd5m\xfcm\xc6\xa1U\xb5\xb3e\x1c\x9fx\xa8\xfe\xee\xa6\xf0\xef9\xfc\xfb\x14\xfe}\x06\xff>\x87\x7f_\xc0\xbf\x8c\xae\xb1\xd4\xce\xc2\x03\x1e2z\xfe\x86\xd3P\xbb\xc1P\xff\x86\x14>\xc6\xe0\xd9\x0f\x9e\x00\xd28\x13I\x06\xef\xf09A`\x12\x1eo9K\xa1\xf3\xe8b\x12\x9e\x98g\xe0N\xc5=\x8e\xa6\xf1\x11\xd1\x13f\xd8\x04tY\xb0;A9\xa3\xf0\xbc\xc1\x0b\xaf=\x01~'\x04\xc7gF!g\x06p\xec\xfd5\x8b{\xcb\xc9&\xe6_Qo\xd7o\xb9\x808g\xcb\xf2\x0dP\xad\x95\xfa\x90\x1b76\xb9\x8b\xf9\x8aCr\xcc\x95)\xb5u\xc0\xdb\xb6\xecv\xf9\x16N\x8e\xc1BdL\"\x97\xb7\x88v\xf6\xdc\xf5\xcau\xd1\x8a\xa0\xce\xc8\x04\xb2\xc9\xc2];\x17\xbb\x0bJ[]\xe4\xd8Am\xd7\xd0RA\xbf\xa4\xfa\x08J\x12x\xb0,\x9f\xcc\x06\xcd\x14\xd7\x87\x0b\x1d\xa80\xd6\xbb\n\x87J#\xb7\xfb\x81\x1b\xbfZ;\xea\xb7\xd6J\xady\x030\xef\x1199}3\x1f\xcf$Y\x0e?9EW\x9b\xb4]$\x80\x1b\x08\x14C\xa9\xf6{\xb2\xa7\xf6\x1f\x10\x03\xb5M\xad\x92\xe8\xeb\xe7)Z$\xa6\xe4\x92\xe472[no\x9f\xc0\xb9\x947O\x97\xe6\xdaH\x1b\x9fE\xff\x05\xa0\xb8M\xe1\xd1+\xb9W2\xd7\xb2[\x05\x83\x83\xde\x98\x89\x01\xed\xf4\xcd\xecz<\x9c]\x9bq[\xb7\xb3\xdf\xe7\x9f\x01H\xeb\xd2\x81Y \xbek\x92 {se=S\xdf{\x18b\x0b\xce\xbe\xb8\xbf\xdd\x89\xde\x80\xcc\x9c5\x9f\x15\xaa\xeb\x05l\x839MB\xaf\xed\x06\xb7\xea\xdc\x18w\x0c\x05tq\xdc\xdb\x81\xb9o\xc1\x14D\x14\xeb\x9d\xed\xcdB\xca\x85\xfc\x04\xfc\xb3\xf5\x06\x05\x04\x1a\x91\xc4\x8c\xc3Ia\xd2Z\xeb\x8e\xdb-_:\x8a\x0b@\xe8\x0f\x98)\xec>\xc4L\xa1+\x1c\x8ao\x1c\x80C\xc1\x00\x8b\xf6\x97\x84\x83\xff\x92@4/\xfe\xae\xe0\xed\x9a\xc0\xa3\x81\xbf\x8df$\x99\xa7.\xc0>\x02\xec\x1d!<\xacw(\xd0\xb2\x8f\x00\xe9/\xa3W\x10\xbb\x87\x1e@|\xc0R\xe4\x0fm\xf3\x88n\xa9U\xf6\x8b\xb7\xa2d\xc6\x03\xcbh\x0f4\x05\x8f\x0b\x1fDW\x8c\xa0r\x8e\xdb+}\xfb\xa7Efy\xf4\xc88)\xcfiz\xe0\xa6\xe9p\x83\xbd\xd1\xaa\xa6;Q?4^\xa4\x0b\xdd!\x87F\x83|0q!\x058\x1a\x8909DdHW@7F\xa0\xc9\xc3\xf3+Q\x0f\xc4\x15\x95\\e\xe2p\xabrD\x9a\xf2\xc0{Y\x8a\xa8$\x91Y1\xc5j7\x8f\x19\x97F\xb2F\x8a\xa4\xad!\x8a\xca!\x8aE\xda\xa8\x16\xe9\xb8\xf8Hi\x12\x9b\xd689\xb4\xce\x89\x83\x8a\x11\xd8\xa2to\xbe\x99\x90\x91n\xcd\x97W{\xe9\xcdn\xad\x8e E\xbf8\xc1\x03!\xea\xc1\xad\xec\xd0\xfcj\x8f\x7f\x82QI\xed\xf3a\xea\x13\x9b\xdce\x03\\\xb0\xe2\xea|r\xedw\xd8\x06\xc7j\xd3\xe7\x1b\x13z{M\xdf}\x18d\xees\xe8\xbd\x1c7\xc5b\x14\xc7#\xd7\xe9\x8f\xce\x12\x95\xda\x89*\xe3F~\x91}\xb6\xb5\xd6o\x15\xd0\xfb,\xf7\x08\x06\x96\x85\x8f\x1e\xd9\x89x\xe9t\x9d\xb7)\xee\xc3\x8d\xaep\x03\x05\x87\xc3\xcd\xc1m\xbc\x9d\xb3\xcdQ{w\xdf0\xc6\x8d1\x81lm\x03\xd0\xf9h\x9b,m\xa7\\4\xfb\xeb\xbc\xd2\xd6\xc1\x01\xb9\"\xf8\x90\xbdJ\x866\xe9J<\xa8\xf8\xafc\xb3\xb6K2\xf0\xe9^\xdb\x0dn\xb5\xd1\xed\xa1\x1e\x91B\xaf\x1a-\xedIA$\xceF$\xfb\x10\xb6{\x04@\xdd\xb8]A\x03\xac`3\xd8Z\xf4\x8d2m>J$\x1d\x8f\x13I\xb7!\xf8\x98\xfcs\xddlKK\x0e\x11t\x82\xfc\xd3\x89'$_\x9d\x07A!\x05pZe2\x92\x8f\x8f\"k\xf3\x8d\x1b\xf9m\xd6C\xa8B\xf4x\xe1\xb5\x1b}\x9d`\x0d/\x86\x86\x8d\xf4\x89^a\xa6\xf7\xc5#>\xba\x1c\x81\xd2\xa0j)W4\xd9gE\x1f\x89E\xfb\x03\xd8\x12\x14\x13\x14M/\xdd\xc5\x18\x91\xf6\xab\x08\xb9\xb7b\xa7\x91\x1bu\xdfF\xd8\x82\x81\xd1\xbd\xb9\x8d\xb0\x05\xb0\xf4\xf15=x\x1b\xa1\x08\xee\xbe\x08`X\x83oW\x1d\x8adT\x1e\x8du7d%%\x0ciCX\xd2\x05i\x89\xd9F\xa0\x18\xb2\xb1\xfdW\x02\xfb\xcb\xfc\x02^\xd3\xb1\xe2\x01\xb6s\xb0\xac\x83\xf9\xb4\\\xf8\x03\x1a]_x\xb5\x14\xe4\xa5/\xdb\xee\x0f\xfa\xda-\xf0\xa6\xc8j\xb3f\xb7T\xa5\x8e\xd6<\xe3\xb4\x95\x82\x8d'\xd0\xc9\xc1a\x90J\x17@\x1e=\"t8\xcc/\x88t\x01\xadn\xec\xd3\x06\x9a\xef\xbe\xfdP\xca\xfc!\x92\xf8:x\xb8\x80\x1ch\x94,H\xc6\x9b\x11\xb9\xff\xc7\xfd\x04\xe7\xfd\x04\xef\xa3\x1d\xba6\x8a\xcb-\xdb\x87\xe2\xfd\x04\xb7\x91\x9a\x0f\x1e\xb6.\x8d,\xaf\x8f\xc5\x07\x95s\xf1\xd4\x11=\xceZ\xf37\xde\x14\xcc}\xce\x0fP\x13\x12\xd5\xaaE\x9dH#\x19*\xe8\x90R\x971\\\xdb\x0d(\xeb\\O\xc9\x7f>^\xba\x82%o\xd51>\xb9$\xf4\x82\xf8m^]\x88\xa1Is\x1f._\xa5]._\x99_\xdc\xc1\xbb\x0b9\xe8\xe1\x858i\xa9\xf9\xe9\xcdM\xd7\xfb\\\x9aN\xe0j*\xda\x0c\xa4\xcd\xd2b\xbe\xd0\xd3\x11\xe1f\xf1\x15\x97\xca\x01rSYzu\xa2\x03K\xc9\x1d\xf5\xa8\x8b\x19DY\x8c\xaaQ\xac\x8eP\x1eV\x96\xf3CMw\xb4\xc1\xfb\x85\xec\xef\xf2an\"\xeem\xe3\xdc6\x86\x1f\x8d\x88\x1d\x8e\xb0r\xfe\xf4\xb9#\xc0J\xd4?\xff\xb4\x92L\x1b\xe2\xae\x08vgbc<\x9d\xba#wD\xec\x16\xa7\x1as\x9d\xbbs\xb1\xd4\xa3\x89\xcd\xf4\xd4\x9diE\xbd\x1b\xe1{7&\x8a\xcb\xd3\x86`!k\x16\x98\x1c\xcf\xdd9\xfc\xc8\xd6\xf1\xc2\x9d#\xa4\xdc\xc4\x1ay\xda\x10Q\x86\x85\xc9\x8e\xa6\xbe\xad\xe93w\xb64[\x99\x1c\x9f7\xe5Ht\x8egg\xee\x1c\x81\x1f\xd9^?k\x18h{\x95\xc4\xac-\xcc\xdd0\xe0\xc5\x8b'&k\xc3\xb0S\x1d\x1e\xc8dk \xd1\"\xa8 \xe4\xf2\xaca\\Y$|qo2}\xd6%0J\xf6Q\x02\xa3\xe4^\x90\x9c\x81Q\xa8 \x8cB10JE\x11\x0c\xd9\xf7\x18\x81\x99}\xebG7\x8a@\x17\x16i\x1d\xea\xb4n\xe9\xb3\xb7\x81t\x91\xd8\xb7E\xcc\xd5\xbc\xc3\x1c\xc6\xabb\xbe9z\xf9J\x8d\xa1\xafXI\xf1\xf8f\xd63\xf1hU\x89\xb9\x0d\xa6\xdb\x1b\x15\xe3\xed\xf6\xc0H\x0bM\x9c\xd6T\xd0\xde\xd2\xd6 \xcc\x11\xce\xac7\x98\x9f-]\xe6:Y\xc5\xe7\xf5kE*[=\x86C\x9fG\xc6KLa\xd4KQ]j\x88\x02\x8ez\x8d\x8e\xac\xf6\x15u\xafI\x9c:4y([y\xd4\xdb\xb1\x7ff\xa2\xef\xc3\xe5\x97\xb3\x01\xe6W\xe8R\xd1o\xb9MP1l\x03b\x8f \x97$\xbe \xa2Mx\xe2s\x01\"\xcbI\xc1g\x08\x04\xe2\xd2\xa0\xfc\xa0@\x19!\x10\xce3\x86$N\xf1\xdeb={)w>\x17\xefG\xa5\xe90\x1b\xfd\x8e\xfe\xdb\x0fNIy\n\xf2!G\xf7\xf40\x98\x97\xc4o\xd6\nF8x\x91q1s\x02\xc3\xc9\xe7\x11\x8e\xd3t0\xc0}\x84{W\xd6\x18\xe8\x187z\xaa\xf5\x97`\xef\xd4z\xbb\x9dM\x12\x16\xad\xfdh\x8b7\x04S\xee\xcd\xf5H/\x1b\x06\x95\xe0d\xe8R\xa0\xf7P\xe4\xe1;L\xe8\x0f\x9aF\xff\xd8\x802\xcdaO\x1ct\xc7\xeap\xfcF\xa7\xdc\xd9\xaf\xc8\xb1bB\x9dd\xf1:\xc2\xa4\xb7\xbe\xf0v\xc4mw\xed\xd1\x94\x91\xe9\xd9\xcc\xfd\xe1\xf3\xf3\xa6\x0f/\x1a>m\x1a\xad\xa7\x9f65\xdf4(\xd3\xf3\xc6\x91o\x82\xebE\xd38>w\x8c\n)\x98\xd29vbk\xb6\xa1Y \xda\xcb5\xf9S\xeap\x94\xd5H\xec\"\xcb.\x80\x1c\x192\x06T\x89\xd7]7G\x83\xc1\xc5@\xd1&'G\x8e\xf4e\nE\x82\xd4\xb6L\xe8\xbb\xe2UJ\xa3\xad\xf4!\xa3Z\x87\x83Q\xce\x82\xca\xf6\xe2\x1f \xe2w\x1e\x8b\xaa2\xc8\xc9;\xa7\x0d\x17E\xe2v[?=\xbc\xd8\xff\x82\xf1\x81\xd1#\xe1h\x8f\xc8\x89p;\x9a\x85\xd3\xcb\xb3\xd2\xf5TSYyV\x9c\x88ck\x98\x1e\xacA\xbb(9\xa0\xc6\xb0\xf4\x19U^>\x9eS\x12\x7f<>\xac\xb9\xb0~\xd4\x1c\xcd\xfb\x9d\xd4\x189\"\x15\xab\xc9\xedE\xce\x14+\x1e\x92iC\xe8\xd9\xe2\xefC4\x1d\xec\x90\xfe\x9d\xe4[\xe1\x1d\xe5kh\xabE O\xdaw\xbd\xc5\xdf{\xf70\xd7Xzi|\n1SG\x87\x81\xd7\x80\xa7\xf1F\x1c\x02\xbc\x03\xd0N\xa3\x11\x0d\xeb\xc1\x13\xb7C0\x1ch\xdfiv\x17\x0f\x87\xe8\x19\x9a\x93\x96;\xdf\xb1\xa2rq\xe3\xfd\x1b$U\xf1\xc7RF\xd8\xa5\xc5\xb59\xb8\x0e\x9c\xa2\xc0<\x7f\xfe\x02\xfdP\x13\xbd\x19;+\xf4\xaa\xb7X\x9c,z\xbf\xfe\xe4\x9f\x1e=\xee\x0f\x9e\x0cG\x93\xd3\xd9\xc5\xe5\xd5\xcb\xeb\xdf\xcc\x97o\xde\xfe\xf9g\xf9\xfe?\x8f{f\xe3\xd2\x1bt\xbboQ6\xb4Z\x92\xabb$\xa9\xca\xe5\x8b.d\xd5\xd2\xd4\x96\xad\x8a\x92\x9bk\xa4\xf3\xf3\x06\xbf\x8b\x07(\xeep\x18\xe3\xc5\xdf:j\xf9\x8d\x8e1\xf1\xb6\xf0\xf9\xf3\x17\n)\xcc]\xb0(\xbf\x88\xd0\xc4\xc8\x8c\x8fg\x85\x10\xc3+r>r2w\xcd?\xb4\xc3J7\xca\xebM\x15\xf8\xf4\xea\xb6B\xbb\x90\x96N+\x14\xa2\xf2 \xb6\xf9\xc7/\n\xf3k]\x1c\xb6\xb1_5\xbf5\x0fuo\xb1\xe8\x99aV\x1b\xc1\x8f\xb3\xea\x8eE\xe4\xd29F\xb3\xa0\xa0c\x89\x1c\xe3*\xc8\xee \xb3\x11\x01\x0f=\xbc\xb4\xa1\xcc\x0c\xb5\xfa\xfcE\x93+\xa1\x8b\x81*\xe8\"w\xa4,rE\xe8\x12\xc3\xd7\xc1_\xb3\x0b\xb0\x84\xac\xdc\xa7)D \x81\x93\xbf\xe6\x8d,\x85sx\xb8\xceH\x0fAIU=\xd4\x85>>\\\xc0\x19+\xa8\xae\xf2\x00\xb6\xe5\xc5\xd7\x85_4\x84\xed!\xa4\xd9i\x85_\x08\x93?'\x8bh9\x04\x93]\xd2k7Q1\x91|\x9a,S\x0e1\xa6\\\xde\xa5\xb5u\xd2uU\xc4E\xca\x93G\xfd\xfd;Z\x1cJ\xb2\xadu>m\x91\xb1\xcf\x1b\xd6N\xdaN\xf2\xdb\xed\xd7R\xf4^\x06w\x91[\xb257\xfe\xcb9\"\xf3u \xce\x94\xbc$g\x18\\\xa0\xda6\xd8.\xcf\xc0)\x96\xd3\xa7\xb9\x82\xee|0\x02\x03\xca\xab\x83\xd7\xdcL\xaef\x9f\xe7~\xee\xed\x8c*\x9c\xd3|\xab\xb9\x00\xd0\x01\xaeC`\x9ec\xdc0\xb8\x99n\xda\xaa\x81\xcc\x15!\xa8\x05\x0d\xf3\xd1\xa74T\x93\xc7O\xb2\x08\xce\xc9\x98\xa4\xa3FF\xacWt:\"\x1c\x0f\x89\x1c@\x9a%\x97\xe2A~\x8c\x8e\xe4u\x0b\x10>.k\xf4v\xdd\xd8\x19TC\xb6\xf6\xd7\xb6\x80\xceH\x9c\xf7\x161\x0f\xda\x0dY[Xj\x96\n\\\xd2T\xc3\xea@\x11\x9b\x01\xd1\xc4\x82b\xef?\x9a\x8d\x17\xbc\xd8P\xa8\xd7$\x1e\x8f\xc9\xcc:\xc1/|\x84\xe7\x18\x1d6]\x82\xa7\xe7&\xa1%\xfa\xc0\x18J\x04wSxjou\xe6}\xd6\xc1\xd4;\"\xd7zF1\x06\xaa\xd6%T\xe6\xd8\xa2K\xbb\x15\nk6 m3\x8c{\xef\xf6\x98\xd6\xb6\xcb*\xb4\xf8@\xc3\x97\x02\xef\xb0\xdd\xd7\xd6qv02P\xa2\x90Y\x01\xe7A\xad\xfco\x963h\xdf\xfd\xff*\x8c\xa1\xb1\xed\x7f\x13|\xe1\xd9\xd3\x0elAg\xfa[p\x85g\x0d\xee0\xdb\x98\xc2\xc9\x95\xae\xe7\xef\x8e-4\xf5&\xe7\n\xad9\x8e`\n\x1a\x0b\x1f\xce\x13t\x05\xff` \x9dX\x82\x1f\xa5\x7fc\x96\xa0Z\xfc\x07K\xa8\xfcZX\xc2\x8b\x06w\xc3\x7f\x0b\x96\xd0\xd8\xf6\xbf \x96\xa0\xdd\x9e\xb5\xb3\x04\x9d\xe9o\xc1\x12tS\xffNXBSor\x96\xd0\x9a\xe3\x08\x96\xf0b\xfa\x81,AW\xf0\x0f\x96\xd0\x89%\x84\x94\xdf\xfc\x8dy\x024\xf9o\x8c)\xd8\xe46\xd3 \xb3f\x89\x0d\x00\xc50\x00\x14\xa8\xfaT\xea\x8b\xe76\xf5\xf33\x9b\x8a\x9e\xe9X\xd53\xdd\xd1Q\xb9\n\xfeR\xeb\x03\x9b\xa1-}-=mH\x0fZY\x98\xe7Z\xc6\xc2u4\x85\x97\x0c\x1a\xc8\xbb\xc8\xc9;\xeaZ\x03\x18\x89j6\x8a\xa1\x95=\x97\xaaU\x0f:\xdc\x16\x81\xd2`5\x0f\xf7\x9a\xfa\xa8\x10\x1e\xeb\xab\xa7\xcf\xc85\x8c\x02\xf4x\xaa\xf0\xe3i!\x9a\x1f\xb6\xee\x80\x91\x16U\x10H%bt;o\xda\xd1\xd5D\x85\x1c\x91u\xe1\x0c9>G\xa7\xb0\x1e\xc0\xc7\xfb\xda[\xad\xad\x80\xf7\xe3\xdc\x15\xf3\xc9t\xa0\xd0\xbc\xbe|<\x1a\xc1J\x9d\x91\xcc1!4\xc25\xe5t\x07\xbff\x81\x1f\xa63\xe27\x10\x97\x07\xd8Z\xe4RO\xf5\xdap+\xe2l\x9a\x0f\xce\x12\x17Nm\x06uF\xa9C*&\xb0\x01\xc0\xb1O>@\\\xfb\xbb\xdcW>z\x84\xfd\xd3s\xa4\xbax]7\xb7\xb0\x01\x05\x90\xad\xa3C\xea\xd3\xfe\x1b9\x7f\xb3X,\x07\xfd\xc5b\xb1\x18\x00\x83>9\xcc\xf9U\xb6(?K\xd5\xb1\xf8\x80\xcc\x18s\x08\xe3\xdc\xd4\xde\x07}p\xfc\xe1\xc0O\x9du\xe0\x87+2_\x0e\xcc\xee\xac\xfe\xbd\xe0V\xd4E\x0e\xe2\xc3\xe8Xv\x0cR\xa7\xcb\xeb\x87\x84\x8d\xac\xac\x1b\xdc=\xd6\x1c\xa1\xba\x17S\xbd\x93s\x7f\xa9\x06\xaf\xde\x03\xa8p\x96W\x9d&\xb8\x9d\xa9H\xfe\x95%ZXCqm\x07\x90\xd9\x08x\x1fc1\x1d\xbbhJa/\x9b\x17M\xcbU\x1d\xc5\xba\x9e\x92\x97\x07\x8c\\N\x1c\xf8ZM\x83 \xd6\xad\xb54EGo\xb9\x16\xd4\xa60\xc8~9K#k\xa7\x93\xe5v:\xf4\x82\xf0\xe3\xa3\xa3\xf3\xc3\x81\xd7\xa6\x0d\x02}\x87\xa2M\x81\xd5y\xf7\xc0\xeahG\x04\xfd\xd4\xe4\x8e\xab\xe1B\xd7\x8a}\xae\x96cT\x11k2\xe3\x05\x10\x05#-\x12\xe1\x1c5\xc65\x8f\x96\xcd\xe4\xaf\x1bMk\xaf\xfc\x12D9\xad\xaah%|\x0e\x82\x11\xbb \x86\x8e\x98\x1e\xb9\xb4\x08Y$f\xe4\xacN8\xda`\x84\xa8\xcd3\xe2\x82\xb1\x94\xb1\x99~\xcf\xe3\xe5\x04\xdan\xec\x08~\xd6\xd2\xc7\x87R\xf2\xd8\xc1\x80\xb3\xd57\x0f\xa0\xf1\x05\"\xcaK\x04\x94~\xc4\xc0\xe4\x05Y\xe4\xecY\xd5u\x99\xd1\x99|\xe6\xd0\x99\x14\xe2\x8a\x9e\x8d?\x9f\x9c\x80\xf2\xf4\xc9pqzum\x15\xa6\xc3\xdf\xe49\x96\xfd\xebY\xfe6^\xfe|6z1}_\xf8>\xb8\xee_\xcf\x16\x93\xa3J\x0c\x9e\x0c^\x9e\xd6\xf56\x05\xd8&\x8b\xf1\xf2\xe7\xe9\xe8\xfc\xf9\xfb\xc1\xac?\x7fs\xf9rqwv6^\xdc\x9d\x9f-U\xd9\x87\xf3\x91\x92n\xa7U\xc2z\xd1\xa8}\xd0\xd4\xa3_\xa5\x16\x9b\xa2\x13\xaa\x97\xbd\x82(\x04\xaa\x90H\xab\x0f)\xb8\xab?\xe9s\x9b9\xab\xc5\xa1,\x94U\xbb\xa1l~\xb6\xd4\x8dL\xf5\xd5~\x0f\xac\x08\x02\xb5\xe7:\xb1\x02C\xd1/W?(\x8ba\x1dd\xef\xd6\xfd\xc3\xc1]Be\x1d\x1c^\x96\x02|\xe69(\x8e\xd6[\xba\xc2S\xb2\xaa\xe3\xc3\xa3[\xed\xb2\xcb8\xb0\xb2\x87zF\xf2[\x98\x03E\xedN04i\x94\x874\xb5\x13\x986M`/\xa4~ b \x87m\x93\xe9\xfdc2K\xbf\x8f:\x99iu2?\x0e\x91.\xd2\xa6y\xcf\x8b1N\xe7:\xf6\xeb\x8e\xe8(\xa5\xfa\x0fD\xe6\xa4\xab\x18CwR\x0f\x0b\x99?>\x04\xd6\xf48\xfe\x05\xb7u\xf0\x17#\x94\xfa\x18\xffs\x0d>\x1d\xads\xbb\x8d\x80\xb2[\x16\xc3\x1f\xfdo\xb2\xd3\xd1E\x9f\x9ec\x04R\x81\xd9\xd4_(\xee\xd3;\xf8\xa3\x9b\xf6C\xfcW\xbfE\x1b\xa8\xc7O\xf0\x95\xfb\xa9\xf9;Y1f\x13'w\x89W|\xces\x05\xb7\xef\xd4s\xb0\xc6\nq\x19\xc0\x13\xf6-Lyb\xfeB\xa9P\xfc\x84 Y\xa2V\x85z\x8c\xd8-|\x8a6\xf8\xc7\xc7\x7f!\x16i\x14a\x7f\xe2\x84\xfe\x94\xb1 \xf6n`+\xa4\x92\x92\xd8DD\x85b\\\xa4\xf0\x9e2\xbe\xf7=\x86\x8fij\xe2\xa1\x9a\x81I}\xb6\xc7\x8f\xbe~G\xb8\xd2\x10\xffD!&\xc74\xb1C`_ \x0b\xfa\x84\xec p\xca\xa9\xfeD\x188V\xe8\x19\x12;?\x0dY\x9a\x82\x06\x8a\xf4D\xf4\xf4\xfc\xd33x\xc2\x16\x05\xccr\xc6\x01\xae=\x0bC\xe8/\x0e\xc1-\x86t\xbd\xf3\x10j\xf5w\x9c\xa5L#\xca]\x18\xf0\xc4\xb3`\x15^\xb1T\x88\xd3\xf8\xee\xe9\xe7\x93\xe7g<\x7fDd\\\xfbYx'8b\xe8&\xc1?\xf8 \xb1\x82j$\x16\x82z\xbb\x90E\xf8v\xab\xfe]\xb1tG1\xf4\xec\xca\x17^\xeccX\xde8\x80\xb9\xf6h\xa0g\xdd\xdb\xf1\x18\x83\xda\xe2\xd3\x98\xdd \x16\xa566o8f{\x16\x89\x15\xf7\x05\x1bS!X\xb4f\x98\x1d \x0c<\xee\x01\xa8u\x10\xd1q\x12\xd0\xfb\xd4\x8f\xb6\xda\xbf\xa3IR\xb9\xa9\x1f!\xea\xaf\x05T\xbe\xde\xaf\xd4\x1f\xb6>\xbfQ\x7f7\xd4c\xc2GX6\xcc\x84\xf9\x8d\xb6:\x84\xaf\x9f\x02zma*\xb7\xbe\xc0?\xef\xc28\xe1\xb1 \xc0\xbb\x154\x80\xbav\x1e\xae\x04=+~\x82\x7f\xb8^\x13\xde\x0b\xfd\x17\x97\x85@L\xfa\x91BK?\xe2\xdb\x0d\xbbO(\x16\x08h*60\xe0j\xd5\xe0\xa2\xa0[\x8dD\xa1M\xe17:%G\xa5\x10\xeb\n\xd3\xf1\x8e\x05zYE8wa\x16\xea8\xbf\xe1\x1e\xa0\x03\x19[=\xc4\x88; \x0dB\xfc\x9bPN\xdf\xbd\x03\xa4K\x02*L4\xe3\x84\xc7w\x10\x1f8I\xef\x01\xce\x9f2\xc6!\xc1,0\x96\xc6\x19\xc7\x95\xc5\x11iyz\x1fA^.\xf4\xb2a^\x1c\xad\x03\x7f\x83KL\xaf\x88t\x8bk\xf0\xe6>\xc1\xf4\x10\xa6*\x8d\x835\xc5\xc0\xc5I,\xfc\x0d4\x96\xe2\xc4\xa4\x82Q\x00+\xc5\xee\xa8\xd74\x01\xc7)\xb0\xc2\xa2-\xc0\x94\xad\xa1\x81,\xe2\x8c\xc2r\xcc\xc4\xf9\xd9\x19DaVx\xc6}D\xd0\xbd\xcfn\xc79\xf4\xb7l\xe5a\xf6[Aq\xf5\xdd{\xfe\xed= \xc3\xdd\xc6GD\xbf\xe3\xf0\xe9>L\xb7\xbc\xb7|8\xff( \xf9\x9f\x0e&\xbf\x7f\xfd\xea\xdb\xb7\xaf\xbf\xf8\xe7\xb7\xdf\x7f\xf5p\x01\xb8\xa2Eq+\x17+A\xf8I~CE+^\xc8Ic0}\n\xc7\x1aE3\x05\x14\x97\x9f\xea;\x8dN\x97\x0e\x06\x17\xa7\x15\x8d\\\x8a\xe5@u\x04\x98\xac3?\x9d\xbeW\x99\x1f\xce*\x8b\x97v\x1c\x04\xab\xc0\x0f\xeb\xfa\xf8\xa7\x9f\xb9\xb9\xa3w(Z8\xde8\xdd\xb8/\xa9<}\xee\xd6Iy\x9a}\xbai\xa6\xbf1f(9\x93\xf1\x0c'+\x1cI\xa0rA\xf1\xe7\xde\x1dF\xaa \xe6\xd3\xa5b %\xdd\x14\xb9&\xa0\xa1\xf8&\x12}\x95\xc1\xe85\x06#2}\x01\x01\xd6\x8b_Gd\x8aa\xb6\n\x97\x81\xfc~\xa4j\xa1}\xa0\xcc\xb4\xff\xe2\xf9\xf3\xa7OK;\xf2\xa0\xcc\xb6\xea\xc4\x1am6\xc0p\xa8\xb1k)2\xe9X\xf1\x01\x05J\xb5\xa7%\x98\xf8\\eY\xb6\x00\xe1\x14\x95\\\x0e\xec\x1e\xfd\xc2\xfe\xeb\xca\xb3\xac\x05\xb5\x99c\xf2\x95\xe0\xe1\xf6[v\xa7>\xfd1k\x88\xca\x01\x07*iC\xc4\x0e\x1am\xbf\xe3l\xe3\xdf\xcd\xd4\x8e$\xdaft\xcb\xc6.\xed\x8b\x1f\xdd\xf8\x9b\xfb\xc6\xf8*7\xaf)\xdf21sJ\x03\xe2>\x89!\xa8\x08\xe3\xee\n\x809\xa63\xd2\xfb\xeb_\xfe\xcf\xbf\xfe\xe5\xff\xfa\xeb_\xfe\x8f\xbf\xfe\xe5\xbf\xb8\xd4]\xfev\x17`\xfc\x91(\x0b\x1cJ\xa8\xfc\x8clF\xce\xab\xa7\x1c\xa5W/\x0e\x938b\x91p\x8e\xb5\x17s\xe6JW?\x9e\x05\x10\x8a\xa5\x07\x9e\xe4z\xa3<\xea\x8b\xda\x1c\x19+\x19|\x03\xc9E1\"x\xd7\x83\x88{\x1f\xca\x05v\xbb^\x8e\xaeV\xfc\\=\xd8\xa3\x0eA\xfd\xa0\xe7\x08\x83\xe8\x98mto\xd7\x05th\xbe72\xce\xf7\xd4\x06\xd9@`\x1aV\xcf;F\xd7\xc8 {;T2\x890\xb0}\x0f\n\x9fu\x90\xbeB\xd0\xa6\x91\x8e\xa5\xdb\x0dv\x1c\xc7\x83\xc0\x17\x02w\x94b\xa7\xe8\x00)\xc5\x00&y\\\x8e<\x14K5FH!\xc2\x87\x0dHR\x08\xef\x82\xbaP\x07\xfc\xbfr\xbf\xfd\x83,\x14?\xfe\xbb$\x0b-\xcb\xae\x0d\xab\xff\xce0\xc6q\x1d\xbe\x801\x8e\xaf\xff\xc0\x18\xf8=\x04cj\xe9\xe4(F\x82\x0c\xa1\x13\x0d\xfd8\xf4\xffCh~'0?\x94\xd4\x1f\xa2\xf1\xff\n4\x1d\xb6]\xf9\xd2\xe4\xc5}IU\x98w\xaffS\x0b\x83#&jf\x1e\xfez<\x8e\xeeQ?\xbf^s\x86\x07\x04\x943\xcc\xc5\x85\xef\xa1\xde\x97\xa6>N&\xcd\xd6>h=A\xc9\xbaZ\xfb\xf8\x07\x93|\x18\x99\x95\x1d\xda\x12:\xac\xe25\x8c&\xb6\xbc\xca\x84\xd0z{\x1a\xed\xf1D\xcb\xa3\x890\xca|\x16 T\xa6{~\x19\x9b\xbc8\xd0\x7f\xb6<\xce\xf0\xc4+W\xef\xe7\xa7]\x82\x1a\x1cZ\xe39\x18\xf3bNE\x8cZ}d\xe9k\xa6$ d\xf2\x1b\xd4\xf3\xfb\xf8\xdd\xc7\xc32\xcc\x05\xb5\xb0\x80\x99S\x0b\x06\x03\xb6\xf1Y\xb0N\x99\x8e\x11\xb5-\x00\xbf\xf1\xb7\x19\xd72\x01\x96P\xb2\x81>\x1b\xd0\n\xf1\xdd\x14\xfe\x05yl\x87\x87k\xa0X\xde=\x87\x7fA\xe9\xaf\xd6\x83\xf9\xab\x0f\xe2l\x9f\xf3\xf5\xa3\xfe\xc2,\xf8!\x0c\xbf\x1f%x.\x88a\xdbz7+\xa8\x04\xacw\xe0\x81mY\x84IP,\xa4x\xde\x12\x9aC6\x08\xe5\xa6\xfe\xfe\x94\xe1\xf1I\xc8\xa2\xcc\xfc\xf5\x05\xf6>d\xbaC\x11\x9e+F1\xce+\xceN\x9c\x08\x0bil\xc7%\xce\x84\x06\xcd\x9c\xad\xe1\x9fxk0\xef'\xf5\x0f\x9e\xe9q\xc8\xc8\xb3\x15\n\xb6\xf0\x0f\xb5\xe7\x00\xa6\xca\x94\x05\xfa<%\xdd\xd1u\x0c\xc7IiH\x03\x80\"\xd7\xc9\xa7 \xf5\x10\xdc4\xa1XPp\xff\x86\xe9\xa7\x18\x89N*\xee\x11\xdb1\x08]/\xcd\xc2\x90\xe2)\x05\x06\x9d\xd3R\xa7z0\xd8,`$\x05\x0b\x93@\x1f8*\"`V\x90P\x13\x0f\x0f(\xb4\x9a\x195gG\x82\xe3\xbf\x14)\xa0\x80\xbc0\xd6\x19\xf4`\x8f\xc7<{\x7f\x8d\x07\xb3\xb7+\xdes\x04\x8a\x03\xa3\xb0^\xba\x87^\xe0\xd2\x0d\xc46\xb8GQ\xd9<\xafQ.5\xaff&i\xe4\x87T0/\x0epm\xe8\xf706c\xac\x13\x04\xa7Qj\xd0\xd7\x92\x81\xc2\xea\xf5\xb9&\x16^\xe0' \xc5.\xaf\xd9F\x0b\xd1)\x9c\xe5\xb0 \xf0\x93\x14\x17\x87\x1f\xd8E\x81\xcb\x04\xcf\xcb\x0c\xdc\xf0`\x84\xe9\x1b\x86G\x9a\xda\xf6\x1e\xe8\xaf\xfdK\xf9\x96\xd3\xb5\xaf\x97'\x9cnq|J\x11\x97\x99\xa0\x862\x84\x06\xb2\xc2_\xa1+O\xe2\xe0~\x1b\xdbG\xcb5\xe9\xda\xa7A\xb1 n\x90N\xe01q\x8e9\x10\x01\n\x9e\xee\xc3U\xac\x0fq\xef\x84\xf9k\x1a\x05\xabzx\xd0\x1d\x14\x061\xed\\\xef}\x06\xe8\xbc\x87\xae;f=\x82Y\xdf\xb0\xdf\x06z=o\xd8\x97j\x12_Q\xc1\xfd;\x93\xa0\xc5\x88\xd70{z\xb819\xd5\x94U\xbdF\xfb8\xd8\xb3b\xc9\xdf\xf9\x9bM\x96\xb2o\x958\xa3\x99\xb2JL\xed\xde\xf3\x15\xd2\x0bH\x144\x12\x90\x13S\xbe\x0e\xe2XC\xf4u\x16y_\xe4\x8f\xbf\xcd\x1f\xff9\x7f\xfc\x1e\x1f\xff\x99fi\xea\xd3\xe8\xb7A\xa6\xe1|\xc5\xf8\x96\x15\x1e\xff`E\x8aW1Ovq\x10o\xef\xf1\xfd\x8f\x9b\x8d\xa1\xc5\xa87,\x80\xf3C\xc2\xbc,\xa0\xbc\xdc\x97\x1f\x92\xb8\x98\xe9\xb5\xb1\x84`\xaf3\xbe\xca\x02%\xb4\xb8F\x1d\"r\xf4B=\x8f!\x8b\xb4e\x89z\xe6\x1c\x97P\x08\"\x0f\x9a(l8\x05\xc4\x0f-^\xe3\xe9f\x08\x04\x99\xad\x91\x04\x84a\x16\xf8h\xea\x81\xa7\xb0H\x92\xd1\xd8!\xdektN\xe8z\xad\xabMv4\x121\x92b\xae\x89L\xc8\x91\x00\xea\x83\xdc\x04\xa8\x1e&\xfc\x84\xe44\xbc\xb7\x98\x1aj\"\x17j\xd2\xa6\xde\xcd\xa3%s!\x92\xb7\xd0\xa0p\xa8\xa1\xcd\"\xcd\x90\xf0 \x00t\x8cU\x0cc\xf5k\x14\x8b\x1c\xd2\x1a\n$\x9e\xc7\xb4m\x80%\xeb4\xf0\xb7\xfa\x01\xbfd\"V\x12q\xc0\xb4,A\xbd\x1b\xc5`\x10\xefW[K\xbcV1\xd7\x90y,\x08\xd4x\xe9\xf9V\xafj<\xcc\xeb\x8ey78\x94V\xc0\x08(2!/`Hvm\xad^\x8cB\x82\xfa\xab\x97\xa9\x17\xc7|\x8d\x89\x9a:A3\x8a!\x8cW4e\x86g\xd2\xd436>\xe6L\xcf \x84M00\xd3w~\x98!`\xaa\x8a\x8d\x9a \x16y\xf7&A\xd59Nw\xfe\x06\xea[1\xbd\xd2V>\n\x1e(!\x16\x96/ZB\xa9\xbfc\xc3o\xe1E\xed\xffz\x95u\x1d\xf3\xb1Z <\x89\x03j7\x1f\xf5\xe41\n+i\xfe9\xe1\xb11\x9e\xc3\x04\xce\x14)4\xf4\x05f\x07\xbb\x80\x8b\x1d\x12Pf\\#k\xf5\xe2\x08\x18'&\xf1\\\xa8]\x03\x97\xd5Y\xf7~\xaa\xf7,\xc8\x14\xd9z\xcbB\xcd\x06Y\xc0\xf6\x16j#\x04\xf8(\xfc\xaa\xbf\xe3XQ<\\\xf9\xf0nF\xa0 z)V=\xb6#\x82\xaf\xc5bq$\xc6\x1b\x1a\xfaA\xfejP\xdb\xbe\x8c\xe9\xfa\xc7,\x15y\x9a\xe0L\x8bA\xfa]c1\xbc\xed)\xf7i\x94\xe7\xbe\xb5h\xb6A\xd9\x03Z\xda\xc2\x06i\x0b\x1b$`\x9dc\x83?E\xb9\xd0\x08eY\xe4#\xe34 %i\xb5@8u9M\x1a\x950Y\x9e8D-?\x82va\x99\xdf\x00 7\x98\x00;\xb5\x1b\xd8\xa9)\xb1L\x17\xbaa\xf7\x89\x929R\xfd\x92&\x10X]\xbf)n\x00\xcf\x96\xd4\x02%\xcd\xc7,`\x8a\xd6\x8d\x0b\xecI\xd5\xcd\x82\xd0\x8ac\xf8\xae:\x99S\xe1@K3\xf9\xe4\x05\xb16P\x1c\xb3\x84\xef\xbc\x1d\x8d\"\x16\xa0\x00\x84=\xbdw\xa4Asw\xd0\x8f;\xe8\x07\xca\x1f*7\xfc\x03_\xee\xe1\x0b\x18|\xbf\x8b\xe3\x90Fk%09d\x94\xac \xa3\xf4P8\x81U\xaa\x97\xb4\x15{Vl\xcf\x02-k\xdbM\x9a\x17\x07Y\x18\xa56\x13\xbe[r\xad?kQm\xcd\xa28\xb4Y\xd7,\xd1:\x0d+\xcb\xe7l\x1a\x1es>\x07\xbbG\xf5\xc05ykbA\x81\xc2\x1f-q\x17H{\xc4\xc4\xce\xf7n\"\xad\x17\x0b\xecV.\xb0\xfaT\xb5\x05-\xef\x83T\x8a]g\xea\xc50j\xf5\\\xe0\xba!\xbd\xb3_\xfc\xc8>\xc6{\xb55\x81U\x03\x8dFqNL\xa3,\x1f\x07#\xad\xf3\xf8\xd6\xa6\xf1\xf8\xd6\x8e!\n\xcc\x06w\n\xe23\xb7\xbd\xe0\xb6\x17\xb8\xe7\x05\x03\xc5\xfc\xb5\x00\x95\xde\x13\xfb\xef\x98\xde[\xf8Z\x8f\x07\xe8e\xb5\x80 \xb5L\xc2\xbeh\xe2\x03\xa2\x88V\xe2\xe9 \xffV\x96L\xb3\xa4\x9ar\x1f\x86Lp\x1f\xe4\xf1}N}\x0e\x8b\xcex\x83\xe3.\xf0\xa3\x9b\x99\x99\xe3\xbb0\x98i\xebzH\xb7\xe2\xba\xfa`G\x03\xaa\x9cA\x8e\xde\xb2`?I\x8a&\x8f\x81\xd3\n\x89T#7\x9b\xab\x9d\x17$\x1a\x8f/\x06\xa8\xe8\x8c\xb6=ru\x05\xa6\xa6\xf1\x86\x88\xb9\xb9}:\x87[\x98\xeaO\xe5f\xd9\x88\xb0\xb9J^6x\xdf2\xa6\x9b\x95\x83\x0d7\xe4^\xbb-\xae\xebp\x93h\xf5\x16^\xa6\xad\xb7\xaf\xbdc\xfb\x11a\x03\xf2\xc7\xd5\x8f\xcc\x13\x85\xf0\xf2;\x9a\xfe\xf16\xfa\x8e+\xd1A\xdcO<\x1a\xc0\xe0i\xcf\xd1\xba\xd7l\x1e-\x1d\x9eT\x8c\xc9N\xc3\x91\x0d\xd1\x80o\xc0\xbb\xdc\xcf\x8b\x9f\xe7\x8bt\xf1\xc3\xf2\x89\xd4\x7f\x17\xef\x17\xefO\xb7a\xbdG\x89*p\xf9O\x95\xec\xff\xf4\xd2\x99y\x0d\xd6jk*\xe8x\xbe\x18/n'\x8b\xec\xec\xec\xb7\x9f\x8e\x17\xd9\xd7_\x7f\xfd\xf5\xf2\xd4q\xf2\x08%\xd4\x12\xc7\x12\xcb\xe1'\x8e\\{\xc8\xd5\xbf\x9e\xe1\xff\x1b\xb9\x13\x03\x91\xa4\xd7\x12o\xd6H\xc1\x02\x89\xd7-\xa4\xe7\xaf\xe5]\x98$\x83\x99\x9c\xbf\xa1\xe3wK9\xa7\xe3w\xc3\xc9b\xbc\x1c\xf6\xafg\x90\xa6\xdefK\xf9\xc9`P5\xb7#\xda\xb3\x154\xb6\xb8\x1d\xe2\"\x93`\x829se\xde\xaa\xccs\xd5\xcd\xb3\xb3\xb1\xfas~\xa6\xfe\xfd\xe2l\x91M_|\xa6\xfe\xfd\xec\xec\xabEv\x8e\x9f\xcf\xcf\xce?W\xff>\xdf,\xb2\xa7ggg\xcb\xd3m\xbd\xca{rEz\x06 \x8b\xf8\xff\x03hf\x15.\x18%m\xed\xe3D\xc9\x0f\x8a\x86\x90\xeb\x03\x16\xe5\xa4\x803XC\xdd\xa9\xee{2\xeb^\x0b\x03\xc0\xda\xe1f\x13\x10\xd1x\xa6\x18,\x18\xe1\x15\xbe\x81M\xa1\xee\x86]\x13\xe4:\xef\xec\xac\x05\xd2&\xea\xb3r\xc3\xedoH\xff\x0b%\xb5M\xfc\x14\xfe\xf6Y\xa3\x85\xa1%Sj\xd1\x9f\xe1=z]\xc6\x98\xb0_\x10\x01\x11\xe7\x0d \x13\xc3\xe1\x80Ds\x81\xebU,\xeb\xcb\x95\x14\xdc\xf5\xd5{\xd3\xb4\xba\x11\xe4\x0d\x8f\xc3vG\x80\n\xda\xb7m\x07\xae\x85:{J\x00\xd9\xf8\x11[\x17\xe7\xec\xd6\x8f\xd6\xf1-\xb9\x06{\x002\xd3\xef\xe5&\x9d6\x83v\xe4o\x9d\x8d*\xc8\xbe\"W\x84\xf2m\x06\x86`&\x92\xfcK\x8c\x0d_\xf0B`\xb3\xcc\xcf\x96\xe4\xba\xfc:#o\x9b\x02\x9a\xde\x95\x0c`\x9b&\x95\xe4\x10\xdfV\xc7\xd2\xfc\xde\xbb\xbd5\xdcM\xf6\x8c\xa7\xaa\x8bW\xa47\x9d\x9cM\xd4\xae\xfan\xc2Y\x18\xef\xd9Z\xc7\xbd>\xf9\n\x9ck|5Y\xc7\x1e\x80\xad^?\x87~\xe5i\x93(^\xb3\xd7\xf7 \xb3\xb6\x9bw\x13?\xfd!K\x92\x98\x0b\xa8\xead:\"wu0\xd4(\xfe@\x8aU\xb9\xc7\xe2\xcb\x06\xbf~\xeaw\xd3\xf2\xed\x8b\x0eu\xff\x11\xf2\xfcN\xe7\xf9\x9a\xd3ms\xde\xef \xef\xef_\xbf\xfa\xf6\xb5>p\xfc\nO\xa5\xdd\xd9_C\xf6?\xd4,\xad\xcd\xef\x95\xfd\xfe5\xe8\x83\xdc\xb9\xbe\xc1\\4dk\x95\xf5\x15M\xdc\xf9~\xb4\xfc\x1a(\xd27\xe4\xbaRLM\xddW\x93W\xf1;H\xfcB\x08\xae\x12g\xe4\x1bw}\x7f\x80v_\xb3\xbb\x86\xde}\x0f\xdf\xbfD\x8b|w\x96\xdf\xe1\xd8\xfe\xf1\xd5wp[\xda\x9d\xe9[\xc8\xf4?\xbf\xfa\xf6\xf7B$\xdf\xb3\x9f2\x966T\xf7\xa7r\x0f\xbf\x85\x1e\x96\x0b\x92\x19\xf9\xd6]\xf8'h\x86Ej\xff\xf6\xa7\xef\x1b\xfa\xfcu\xb9\x85\x9f\xa0\x05[\x86\xcc\xc8O\xee\xb5\xe4\xe4\x17\xdf5-Z\x85\xf6\xef\x14\xf5\xfd\xff\xd9\xfb\xda\xae\xb8m%\xe0\xef\xf7W\x0c~zR\xfb\xe05\x90\xa4\xb7\xed\x06\xc2!\xb0ii\x03\xe4\x02i\xdaK\xf3p\xcc\xaev\xd7\xc1k\xed\xe3\x17^z\xcb\x7f\x7f\x8eF\x92-\xdb\x92\xec%iz?\\\x7fHXk$K\xa3\x91\xe6E\xa3\x99`\x9c\x92\x8a\x88\xdc\xea\x18\xdb\x10\xc4\xff\x8f@\x98D\xd8\x16S\xfe\x08\xe8mBRI\xc1(c1\xc27\x94\xdb.\xd5\xc8\x87u\xf0\x15\xeb\xa0\x1eK\xbf\xc0\x0e\xbc\n\xa2\xc5\x92\xf7\x1b\x95\x14=\xe4\x8f\x08\xc9G\xc9\xa8\xf0P\xb0u=\xf4{\x84\x9e\x91\\ ${u\x7f\x1e\xce\x18\xb5\xea\xe1\x7fRZ\xef\xb7\x80\x7f\x83\x1d8c=\xa7in^\x97?\xa3T\xdc\x9e\x82\xe6\xae\xf6Kc\xa7\xffE\xf4\x85m\x10\xeat\xf0\xfdr\xaf\xdc\x88\x8e\xe8Ds\xf7\x8d!\xfd\x07\x8c\x8c\xa6\xed\xd4W\xb0\x03\x86\x95\xffo\xd8\x81\x89\xbe\xe8W\xd8\x81\xb9\xbe\xe8_\x18wM[D\x08\xec\x80F\xa4cON0(\xa0\xb6,aez\xcf;@F\x05;\x10\xbb\xffy\xf0\xe1\xe2\x03\xa3\xceq\x98\xbbW\x188\xeb\xca\xcd\xf1\xdf\x04\xffM\xf1_\xeay\x06\xdeH\xed\xdf\x89\xf4\xdf\x89\xb0\xd5\x10\xff-\xf0\xdf\xcc\xf8\x85\xd0\xfe\x85\xc2^\x9c\x11Cb\"\xc0[\x81\x96\xc21\xb1\xb0\xb3\xa9\xadpi+\x9c\xd8\n\xe7\xb6\xc2\x1b[\xe1\xc2V8\xb3\x15\xde\xdb\n\xafl\x18\xba\xb4\x15\xde\x12\x8bB;R\xc8\xa2r\xa0\x91.A\xd2\xa3\xa0\x8a\xf7PZ\x93T\xef\"\xe1\xe4\xc3\xbdD>\x98d7\xed\x97J\xcf\x12\xe1(V\xb9Gq\xa7\x1aSkg\xb5\xd6\xb8a\xb99}uh\xf8\x98R\xc6*\xb1\x97\x85ZI\xfb)\xa5LVB\xfaw\xde\x9d\x8d.\xdf\x9e\x9e\xbc>|3\x92\x9fz\xf2\x04\xa6\x81\xfa\xde\x17\x9b\x14\x0f\x82'\xfa}\xb9wz\xb8\x87\x0d\xfab\x9b\xaa\x17\x1f\xec\x9d\xcbb\xdc\xa8\xe4\xfbw\xc7?\x1f\x9f\xbc?f\x8d\x9f\x9f\xec\x9f\xbc9C\xa5a\xcb\xe7;\xd648\xdb{=\xba|}rz\xf9\xd3\xbf\xde\x8dN\x7f\x93\xa5\xcbF\xe9\xf9\xe8\xe8\xed\x9b\xbd\xf3QY}\xc2\x01\xde\xffx\xf2ftyp\xb2\xff\xeeht|.\x0b\x17\xbc\xf0tt\xfe\xee\xf4\xf8\xf2\xe0\xe4H\x16\xcc\x9a\x05\x97\xafO\xf7~P\xab\xde\xb7 \x0e\x8f\xde\x9e\x9c\x96\xe57\xbc\xfc\xf5\xc9\xe9\xfe\xe8\xf2\xd5\xc9A\xd9\xe3\xab\x1aR\xce\xf6\x8e\x0f\xcf\x0f\xff\xcd\xbav\xe4\x8b\x8dI\x96\xfd<\x1a\xbd\xbd\xdc?9>\x1f\x1d\x9f\xfb\x9ciV\xc4\xf1\xee\xf4\xf0\xf2t\xf4\xc3\xe8\xd7\xb7\xac\xe1\x9c *0\x0c\x11\x91i\xd5f\xfc\x05\xdfa7=\x9cZ\x0c\xecI\xb4\xbc\x0dy%\xa7OT\xdb\xf8Z\xb8%Uh\x80\xd8M\x88\x0f\x8c\xd7\xc6.%>D<\xb3\x97\x84\xcbnf\nX^\x82\x85\xe5_Y\xab\x02\xd7Z2\xa5^\xd2]\x8f\xed\xb3Gj\x97\xd2\x12\xb2P\xebx\xb8\x9a\x0e\xf8\xa2(\x87\xbe\xb3\xc3\xa4\x88\x12\x11c7!\x1e\xd6b-U\xf0UmF\xad\x08Oy\xed\x88\x94\xbf`\xecRQ\x9b\x12\x15\xbe\xaa\xcd&\n\xc9S6\x13\xbbgD[\xe8!\x01\xf0\x8e\x95.Wr\xee\xb8\x85\x94\x1b\x96RB\xfe \xb8*\xab\xb7\xc2\x82\xca\xcb\xdc\xa9\xe7\xf3\xadu\xaa\xdd\xfd\x0c\xdc\xed\x84\xf46\x18\x94J\xbe)&\x82\xfa\x08\xbf\xeb\xa1\xc6Z%\x9f\x07K\xce\xb1<\xbd\xb7\xf4\x04dv\x08\x92\xa0<.:\xb6?\x8f\xe2\x89\xc9\x9c\x01h\xd1\x1b\x87\xf9x\x8ey8\xbaZ\xa7ENR&\x92c\xe8rs\x93\xab \xfb-\xe9\xba\x9e\xac>\xdd8XiF\xd8S\xfa\xf0\x0c!g\x1a\xd3\x9e\xfc\xcd\xb0\xc8$\xea\xce\x16\xa6)]\x0c\x1bv\xf6\xe6\xf3\xd0c\x06\xac\x94\x06\x9f86\xb3p\xa1>\x9f:\x14\xf3\xc4\x89\xae\x97\xd85\x9a\xd8\xf4\x9d<\xef\xbf&\xa5a\x96K2\xf61\xdbNf\xe4\x13M\xc1\xbd\xe1\x1b\x12\xca\x04\xdb|$/\xb77\xc4\x1f\x0e\xac#7\xb8\xee\x9a\xbfn\xeae\x0f\xfb\xc8k\xdb\x92\x85&\xd1\x98\xd1\x0ej\xb4\x03r\x0b\xef\xcc\xc3dO\x1a\xa4$[\xd2$C\x1b$\x1b\xacT\xb4\x1d\x1f\xd2\x80.I\xe2:?\x8c\xce\x1dq/e\xc86\xe7\x0d\xc6\x18_\x8c\xe7a\x9a\x91|\xa7\xc8\xa7\x83\xef|D\x89/\xd2\x9a\x06\x19I&.#@\x8fGE\xa9>\xf3\x08Jb\xd3\xb1\xef\xf5\xc0%\xfb\x92\xcb\x06}\xe0\xf1\x18\x83\xafS\xba8\xc33D\xb6\xcf8e\xdf\x9d\x9ek\xd3\xdc\xa7\xf2v\xfc\x93'\x90\x97\xc6 !\xa8\xe3\x95y\x9e^\x94uIg\xdap\x1d\xc7\xf3\x82+:\xb9\xf7L[x\xa2\x16L\xa34\x93\xcdc1\x13\xc4k\xdb3\xa3\xc7\xf7\xfc\xbc0G\xe9oW\\\xb1\x81\xa1\xb8\xbf\xe4]l\xb6\xefw\x81\xde\xc8]7\xd70 \xd8v\x8c\x00\xca-\xads\xe2~\xbd\x9d\xdd\xcc^n\xcf\x80\xa2\x8f\xf0\x0e\x06~k\x0f\xd3\xf5\x9c\x97\xdb\x1b\xb3\x97\xdb\x1b\x0c\xfck\x03#$\x01\x86\xdb:\x13.\x19.j\x91\x18\x82\xc9\xbd\xe62\x82\xbe\x9e\x9d\\\xdczW\x97/\xb7Qo{\xb9\x1d-f\x90\xa5\xe3\x1dg{\xa3\xf1\xe6\x0eh\x82^\xf2;aL\xd2\xdc\xdd\xf266\x9c\x97_{\x9e\xa6\x83\xc0\xd4T\xae7\xed\xf3N\xea\x11o'\xb6\x07W36\x86\xe7\xa3\xfe{\xa3 \xd4\x1f\xc5Ir\xc3\xde\xf9\xe7\x9fl\xd1\x12\x1f\x8e\x82\xb3\x1fO\xde_\x8e\xde\x8c\xb8\xac/_\xec\x9f\x1c\xd5_\x9c\x8f~=\xf7\xbb\xa9\xa1\xf1\xf9\xa3\xe0\xf5\xe1\x9b\xf3\xd1\xe9\xe5\xde\xfe\xfe\xe8\xed\xb9y\xf5\xd5s.\xd5\x8b\xb4\xaf\x0fWFE\xa9\xfd\xee4\xb4\xdfs\x8d\xf6{\x8e\xb1l D\xe8U6&t\n\xe70\x14\x07\x9d\xa6\x86\x88\xa6!\xc2\xd5h')\x16W$UM\xdd\xa4<\x02\xe2\xc7\xba-\x9f\x07\x0ep\x1c.\x0c)O\xf5\x88\xf9\xd8\x12\xb3\x1a\x973\x9b\xcf\xcf\x17\x04]+\xd8\xff\xc1\x94\xa6\xa3pN<\x95\x0c\x8eQ\xfdT\xdf\x9cb\xe8/\x8d\xcfJ9\x7f\x86 \xce\x03\xc6\x99\xf6\xab\xe3 \xed\x91H\xaer\x07\xcewJi/S\xfb\xf1\xb1\xb3\x89R&\xb3@f\x8a`\\\x05\x969\xe1\xb9\x1al\xf9\x7f\xa5\xf4Q\x91m\xddA\xa7{J\x8a%M\x1a\x13\xc2\xe7\xa3\x83\xfd\xf3\xf3\x8e!\x18\x8eH\xe4\x13\xc61\xbd%\x93\xf3p\x96\x0d!\xb1\xa9f>\xac%\xe4\"\xfd\x80\x01\xff\xd8\x1f]\x8b\x80\x8d\x80\xab\xb2k#\xach\xc2/ \xa2$#i\xbe7\xf9\x18\x8eI\x923&\xdeG\xc4\x01\\i\xed\xba\xae\xb37\xcdI:Bg:\x06\x90p\xc1\xe0\xb3\xc9\x94\xcd\xf97c\xadk\xff]\x9b\x12\x1eT\xb0%\xd3\xf0\xd7\xca1]\xf9C\x0f\xbb\xb6\xb1\xbd1\x0br\x92\xe5.Q\x97\x10\x97\x0eV\xd2\x9d*M=\x18\xc74\xe1\xaa\xa0m\x03\xaba\x99'9\xa9:P\x06\xe8c\x1d\xf4\xc1y\x12\xe7/\x1c\xcf\x93\xa6*\x99\xeaA\xdd\xf7\xb9\xb8X\xfeS\x1fO\xd9\xde\x0f>8\xc0$G\xf9\xe2+\xfe\xc2\xafW\xa8\x82J~\x01,\xa8\xdf\xdd\x81\x84\x0d\x93-\xe2\x90\xd1\xa3}[\xddZ\x85\x0b\x9c\xae\xc8\x05V\xd6\x07\xedpiO8\xda\x13.\xea \x17\xf6\x84+\x1e\xcd\xf2\xca]\xbe>;<\x82j\xc5a\xba\xb6>\x86\xf4v\xcc\x15\xdd\xc3\xda\xe4\x1b\xb5.\xa0\x89\x0e\xfa\x970.z\x82_\x13\xb2d#\xd2\xc7ki>\x82\x15T(\x18\x0253\x04\xd0\xebJ\xea\x83\x8ebl.\xc2\xd2\x11\xac@_\xd6n\xb4\xc8\xec\x92(k\x84\x17\xc5\x07/H\xc2\x05\xf1\x91\xf4\xf2\x00\x0f\x98\x82<\x8d\x16\xae\xe7\xf3\xa0\x85u\xbe\xeaC\x16H\xd4\xf2\x04P\xfc7\"\x8f'\xeb\xc8\x02\x89\x1e\x91J\xb3\xc9m\xf7\x94\x18\x96hJ\xe6_W\x1a\x92\x07d\xb8\x85Q\xe4o\x87G?8\xca\x8e&\x05\x9d0\x88&\x1e\xd29\xfb\x8b\x13\x14w^\xab\xbc]1\xa0]\x10.\x97\xf1=\x1e.\xbf%.?\x8e#\xfcG\xc2\xff\n\xcbL\x12\x91\x07/\xa1\xe0\xbcA\x95PD\xb5\x88\xa3\xc9\"c\xc8\xc7\x90\x12Q\xf7\xa0\x93\xca\xe1\xf1\xdbw\xe7\xbaa\xf2\xbb\x0e\n:\xf0f\x1d\xb7\xb6\x0bs\xf9\x05E b\xad`\x7fy\x1eF\xc5\x8d\x92B\xe3\xc7\xa0{\xd8\xc8\xb0\xb9D3\xec\xc4\x07\xc7Qp\xd5\xd9\xa2\x9d\xcb\x83\x18\xaeB(\x18)\xf8\nY6\xf6d\xad\x1c(\xa7\x03\xfe\x9b\x0d\xcfM!J`\x8f\xfd\x8d\x7f]\x13\xcf\xe8P\xd9|\xd8G\x05#d\x04\x87\xff\xa4\x9dl\xcf\xc3\xa3\xb6'O\xe0\xdf\\\n\xa0^\x8f\x99\x079\xfb8P\xac\xfe\xebc\xaa\xf7\x1b\x18\x88\xc1\xad\x95d\xc0\xa9`E\"\x00\xd1\xcc\x19V\xee_\xa7\x1chN\xf8\x18+\xa4\x12\x82\xb4\xd3w\xcc\xa0\xb6\x86\x97~\x15RPn\x0eT\x04\xc1\x1d{\xaa,0\xdc\x80\xc8m7kw\xe4\xc2\xa4 |\xe8\xa6b\xf5\xc1\xb0\xa2\\\xe6\xfe\xd7g\x18#\xa8\xe3L\xaby\xea\xd5@\xf7\xea\x82N\xd3T\xf3i\xaf\xf8\xd4\xf3\xd5\x93\x01\xba\xb4\xc8h\xea\xb3\x82\xb8\x0f\x9d\x83\xb1\x97\xb6$@\xad\x94alb\xa5\x03\xa5\x03U2\x04b?\xd7\x92wM\xfa\xc8Tl\x13:b\xed\x99\xa9\x07\xf9}[\xa6:\xc3\x80>\x07'G\x0e7\x87\xb0\xc1\xbe\xc0\xef\xa6AB\xeer.X\xbf\xf0Z\x0c\x98W\x14\xa1B\x92R\x18;&n\xc2\xb5\x9a\xa4\xd4\x8f\x14\x8d\xff\x049CU\xe6\xf9p\xcajX:\xde\x9a ]\x97\xf5\xb3`\xbcxr\x17d\xa2\xb1\xbe'|}g\xa3\x8f\xf4\xddG\xf2\xee#u\x87\x1d\x924f#\xe4Qqa\x07\x9c\xdf\xef\x9e\x8d\xd7\x06\x83\xdf\xef\x9e\x11\xc6\x88K\xf3\xceZ\xa5\xeb\xe3\xdetH,\xf7\x0b\xa0\xed\x0b\xab\xd4\x0fr\xcaO1<\xc8\xe7)\xbd\xc5\x83\x1d\xa68\x8e\xd2\x94\xa6\xae#\x8b!\xca \xa19\x84%\xf2M\xce\xb0\xe5\xf7Z\xbd\xc5AU_t\x19\x0b\xd7~t\x12\xa5\xf9}\xf5E\xde\x90\x0f\xe1\x15M1N\x8d\x81x\x8c(]\xab\x1d9t\"J\xb5\xbd\xde\xbb#\xecp\x98GcnHa\xc2\x8a\xce\xec\xd2\x84\xeb\xb6\xe6\xe8\xec\xb1\xa55\xac\xde\x9c\xdb%w\xb2\xf6\x04\x19\x18\x1a\xa8NtV\xdd\x1b\xc1t\xb3M>f\xcc\xcf\x91\x9a\xf7\x08\xba\x916/1\xd4M\xdf\x1e\xf0,\xbb\\HK\xf8\x19J} x\xf5#\x06\xc5a\x98\xed\x04k\x9b\x9eW\xb7w\xbf:9\xf8M\x88\xcb\x95\\\xbd\xcb\xf7J\x18B\xc2\xb4\x03\x92L\xf8\x99Xj:$\xb2\x0bdH_\\\\_\x9b\xe0\x7f\x03\x99-\xb8\x14N\xb6\x1d%\x7f\xb7}\xd5\xac\xc9\x91\xa3\x80+\xea\xf0^\xf3\x9b2\x06W \xfd\x14\xf0\x93\xe6\x13\xb6}\xa3\x95\x8b\x1f\xef\xe9{P\xdeC*8kJ\xbc\x17\xb8\xef\x15u\xae\xc2\x0dL\xb4\x86h\xca]x\xd8T\x1f\x13\x97rnB\x8d\xdc\xe4\x80T\x85\x9c\x9dP\x91\x8c\x98\x1a\xfa\xc60\xb3\xb0\xdae\x18\xc4\xacCG\xc1\x11\xb2-\xf8'~\x9e\x904<\xf0_\x80\x8a\xa6\x17\x1e\x845\x02\xe9\x81C\x90\xf4\x82A\xfb\xcd0b^\xef\xb9V\xc2\x80\x7f\xe3]:\xf3e\xaaK\x1f\xc2\x15&Z4\x88G\xb3\xea\xd9-#\xf2\xd2\x94\xd8\xaa\xf9\xc0\xd6dF\xf2}\x9aL\xa3Y/\x1b\xd8\x1e7\xd2r\xdfdMly\xd6\"\x06\x8aj\xb7ij\xb2rW\x95.\xcf\xfaf\xc3\xc9\xe4GJ\xaf\xfb\xf2\x7f\xfd\xd9\x03\"\x1c\x8f\xa3v\xf8\xa9\xd4\x9f\x7f\xe2^\x84'Sh\xc6\xcc=\xcdU\x8cj\xf3ju\xc1\xf4\xfd\xda\x99\x97^\x90n4\x9b\xad\xd4\xae\x1c\xc5\x85F\xa7Q\x1a\xde\x8b\xe3V\xdb\xc6\xa6\xd1\x0fW\xdbZ\xed\xe5\x832\x16\x9e\xce\xb6\x0c\x8b\x9c\x8a\xa2G\xc5W\x16\xfev\xfcpS\xdeSvs\x1f\x9c\xcbK\x92\x1d\xd1 \x0f\xd3S\xef\xfc\x0d7\xe0\xa9\xa9\x02\x94\xd5)O\x8cb7q\x9f7o\x15PQ\xf0\xb4Y\x10\x89\x82g\xcd\x82P\x14|\xd3,(D\xc1?\x9b\x05\x99(\xd8T%f\xf6b\x8b\xbd(\xdf\x94:F\xdc\x9ey\xf5\x06, *T\xe0\xe9\xb1.\xa8\xaf\x88\xaf\xd6\xf4\x0dlF\xd8\x05\x81\x9f\xb1\x95\xee\xca\x9e\xe5\xb6k\x9e\xee\xa6\x0f4\x10\x1f\xf6\xdc|\x1ee\xdc]\x95\x15\x84\xcd\x027\x0f./\xd1Twy\x89\xccb\xd3\x87T\x01\xf2;\xd3\x88P\xd0%\xbb>\xba\xaf\xab\xe0\xc5\x82\x93\xb4\xb4\x88\x99 \"[/\xaa\x8554]\xc3\xe4`lM\x0dM7<\x01\x0f\x0e3z6\xa7\xb7f\x92[Zmh\xe6\x01,;\x87\x18\xf7Et\x94Li\xba\xe01 ;\x88\xc2\xd2\xa1\xb1\xeds\x0bz\x15\xc5d\x08[OWm\x96\x8aqz\x96\x91N:q1\xed\x84\x98wB\xc4rg\xf8D\x0cXx\x08\xc9\xaes\xba|\x0c\x9a\xc2\x1eh\xfa\xaf\x1e@Q\x0e@\xa7\xb3\xd5\xde<|\xf0|\xe5*\xc2\x83[\xb5Y\nS\n\xa3\xcbe)\xec\xc0\x18\xdf\xfe\xbd\n\x8d\x0fy\xf0SF\x13\x14\x15\xc2Kn\xa1D&\xad\xbc\xbd\xa24&a\xd2|\x8d\xe1\x03\x9b/\xb9\xe9\xb1\xf1\xf65M\x17\x1a.-u\xa8{\xa6*\xb5T\"*KZ:Q$JZzW(\xab\xe8\xb4\xa8{\x9d\xde\x95\x89\x82\xd67bQ\xd0\xd2\xbb\xb8\x94\xd7\x14\x88\xa6\x08>n\xbc]\x8aF\xb6\x9a\x8dp\x01\xed\xdb\xc6\xdb\xb9\x04\xdfj\xf5\xf3F\x16\xb5\x86\xb6\x90%\x9b\xdf\xb4\x061\x13\x89\x8a\xb5\n\xe1\xfd\x97U\x08\x97\xe5\xba`=\x08\xa2\xecT\x84\x85\xf6\x95\xa20\xb9\xf7\x1b\x90\x96bN\xad\x86\xa6x\xa1\x0f7\xe5\x9b8\xcar\x15\x82\x91\xb5\xedw\x98\xdc\xd7i\xf5\xaa\xe5*t\xa3w\xf2\xa1\xc9\xfe\xf9\x86\xb6]\xcd:\xff\x1c:\x7fK\xb5\x97:\x7f\xd6,\xd0\xe9\xfc\xaaF\xfe\xa9:\x7f\xac\xb4U\xe9\xfcuK\x80Q\xe7/\xd3J\x1dD\x93#\x1eG\xb6\x05\xf9\xd7\xa9\xff\x93([\x86\xf9x~\xc8t\x860\xe6\xceP\xc6:\xdc\npc\x07\xe2^\xd2\x92\xc0\xf5\x1a\x17\x1aCS7\xe9\xe4\x9d:\x16\xff\xf7\xd9J\x90\x84\xbb\xd0\xc3\x97Z\x17~:\x90\x18\xd5\x90h\x91\xd8W\xb0\xcb\x14\x08;5\x1c\x0e\xe4AN\x7f\xe2\xd7\xaa9{g?]\xd3a\xbb\xf4\x8b\xb4|.F\x17\xbb\xfc~i\xe9\xfe\x18a\xb8\x9a\xbf\xe0\xa6\x80>*\xa9\x0f\xb4=\xe3\x06\xc6\xd3\x06\xac\x9di6c\x02\xfa\xb88x\xa8\xc5\xc2\xe3\xf9\xaa7_\xc0\x18\xb6\xa1x\x01\xe3\xf5u\x0f\xe2\x8b\xf1\x07\xb5\xe6\xc5X\x13kQ\xc6Y\xc4S\xe5\x1d\x03\xf3\xc3=\xae\x93\x01\x8e\xc38\x16\\\x90\xf8p\xc1\xea\x96\xc1$\xb8\x9e\x96\x96\xdbQ\xaf\xc3\"\xe9\xae\xaez\x8er\x92\x17\xfbh \xa2`\x92\x80G\xec\x0e\x18\xa0\x88\x81X\xbeC\xba4,<\xd1\x9a\xec\x15\xe3\xb2\xf2\x9d\x90\x90\xb4\xc7Sl\x1c\xa3\xa4X\xac0\x16\x81\xe7\xd6\x17\xf5\x1f@\x9bvK\x14a\xf4\xf4%\xe4\x89\xbf\x81/\xf6c?+\x08\x0f]\x8c\x96\xf6b\xb4\x9c\x87J\x99\xb8\x8b\x87N\x08\x8f\xf3d\x8c\\\x07\x82\x85\xa6\x01I\x8a\x85\xd92\xcd:G93\xdd\x15\x7f\xb8\x1e\x0c\xf1\xac\xb7\xe82U#Ou\x1d~\"c\xf3s\xea`;V\xbe\x02u\x8b\x1a\x95\x91Jw\xc1\x89\x12\xcc\x07\x84\xd7\xab;\xee%`\x90\xa8Zm\xda\xa3\x96\xb8\x9b\x80\x82ff\xe5]P\xd1\xaceF@\xb69Z,\xf3{q\xa5b\xcd\xc2\xa2\xa0\xc6\xcb\x90\xc8\xd5\xfd\xc0X\xcft\xbb\xd3\xb8\x86b\xdc\xfch\xba8\x08\xf3Pn\x80\x11\xba\xbb\xaf\xb9\xce\xeb\xb2 JD\x0c\xda\x8e\x83\xa3\xdcu\x0e1\x91\xa4]\x10\xa9\xed\xb7b\x8b5Q\x89\xd5\x82\xc6\xea\x0eEs\x96\x9e}\x12\x1d\xadNC\xad\xa9\xeb\x92\x90e~\xaf!\xc4\xfa dk\xd3\x84\xa0\x85|\xdf\x03Q\xcb0\xcbni:\x91\xb8\xe7R-CFU2\x94\xb9\x07\xffk\xf0\xd9\xbd\xc2\x16Q\xf2\x06[\x1b\xda\xfcK'\xe4\x8a\x16\xc9\x98\x9cG\x0bB\x8b|\x08\xcf\xbe\xb1@+\xa1\xe7\xacb\xe9_0\xdb\xad\xd7\x9fU\x02\x95\x16\xcf^\x02(1\xdc]\xef-dJ\xf3\xe8c\xad\x1e<\xae\x06Bc_\xcc\xd1\xf7\xf5\xc2\xdf\xaa\xf2R\x1ady\x98\x0b!\xc0(\x9c\x1d\xe6D'\x9cY\x1c\xae\xd2 #\xf9\x19k\xba\xba\xdao\x8d\n :hg\x91ri\x88Kj\x19\xc9\xb98f\xacd\xf2\xefW\xb0g\x184w\x98b\x03\xef'\x8fj\xc6k\xbd\x1f\xb0\xcax\xe5\xa5<\x11\xce\xe4/\x19o8\x994\x07\xbb\xcaX\xfb\x04\xc4\x10T\x06;p\xe9J\x8a\xeb\x12\x8a\x04\x06\x048w\xcaslau\x1e\x8d\x80\xd5U\x10\x0d\x1az`\xa1\xdfx\xff\x82\x01\xe2B7^\x9c\x15\x1f\xaefF\xdbH\xed\xe5_\xa3-\x95\xd6\xd7\xf7Q\x1c\x9f\x921\x89n\xf0\xb4,\xeb\xa1@\x19\xe7J\x92\xde\xda\x8e\xd0\xa2\x94]\x8f\x89\x7f\xfc\x9d\x9cN\x9bB\xa0\x92\xa3~*:\xf9\xd9\x17\xb2\xa0\xdau\xc4>\xba$?=\xec\xa7KR\x84\xedV\xed\"\x84\xebR'C\x84\xeaR'\x0b\x842\x99OC\xbc\x11,\xb4\xbeP\xd5\xfa\xec\x06\xd4\"\x88\x92)I\xb9\xf8\xe0FA\x94\x93E\xd6\xedhV?Q\xe9\xe1s\xf6\x8ag\xf7\xef\xf0\x1f\xcbP\xb7\xb5\x88W\xd0\xa6h\xb3&\xbc\xec\xd2v\xe7\xd2\xd3\xed\x13\xb5\xddy\xd7\xc6\xaeH\xd5\xe1\xeaR5T\x92\xb5R;\xecQKf\xdf\xed\xbe\xb7/\xd6\x9c\x85\x96\xa1\xad=\x1b\xa2\xbf\xd7\xa0kz1\xfd\x9b\xf5\xe2\x8ey\x14\x0eW\xdc\xedc\x8dGC\x99\x04\x98]\x91\xfd-\xfet=\xd8\x86\xad\xea^\xca$X\x84KE\x10\xf2\x81v\x11^$\x84\xe6\xb4n\x96\xcf:.\x96\xc9\xd9\xb75\x0f\xe2\x13K\xdc\x10xZ\xd7\x9e\x92\x8b|J \x06\xaf\xf1\xf0[/\xd6J\xb6p\xab\x80'\xeb\x82j\xe5\x9d\x8f\x8b\xe5\xc5\xe6\x07\xbe\xe3\xc1:P\xcb\xdd\xe4\xce{Y\x1dsi\x1f-2\xa2\x0e\xa2T}\xbf>f4\x19\xf0\xed|\xc0\xf4\xeb\x01\xdb.\xad\x0e\x81\xa6\xeeY\xdd\xcd\xa0\xfbd\x05Z\xa7+\x1dF*)]\xf7]\x81\xfd\x04{\xf9\x94$\xa3\xaaO|)\xd8)\xc7\xde\x1dy\x9e\x13Y\x96\xbf\x19\xc7V\xf3\x124\xa6\xf6*O\xe0*O\x06\xd9\x02\xb4\xb3<\xe0\xfaH\xc7\x86K\x93\xfd8\x1a_\xf7\x10^\xd4\xa7\xc4^\xa5\x87\xb9]\x88\xb3\x11\x9d\x03\x03pL\x9e\xa8^\x90S~\xf4\xf3X\xd4\xad\x84\xb6p2\x01\x07\xd6\xab\xcd\xab\xc1\xf8\xb8\x1b\xa1\xf1[%B\x91#\x08\xbdM?06\xee\xbd\xc9\x04\xd8g\xb5\xc3\xef\xb4\xb4\xbc-R\xb2\x8a\xb5\xa5r;\xebeo\xf9\xdf\x81\xdf\xca\x07~\xabj\xa9\xff;(\xd3?\x7f\xd1AY\x97\xceB{\x1d\xa7\xd5\x0f\xca\x0c\xa7\x0bx\xf2%\xf4\x9b\xb4\x9f~\x13\xf69\xcc\xea\x10#\xc2\x9e\x1ba\xba\xbaX/Dz\xa5f\xda\xcfX.\x82\x08$\xb6\xdbFuA\x9d\xbb\xc6MS\xba\xf8\xe9\xccs)jYx\xff\xd3\xc9S\x9e`e\x1a\xc6\x999\xe1\x0b\xe8\xa5\xf9\xb2\x1d\xdb\x81\xd7\xaaB}\xb7I\xe1\xd3L\xe4\xa5\x07\xf1\xa3\xf7\xec\xde{\xb2\\\xa1\x9fl\x1f\xb7X\xc6\xd9\xc2\xc9H\x8esrN\xcf\xc2\xc52\xeee#\xaf\xbc\xbb\\\xf6\xe5\x19\xdb\x1cxm\x8e'\xcf%5w \xfd\xdd`\xa2\xb5\xcb\x1bEF\xd2\xf2\x990\xb4:\x0f\x93ILNVi\xfb\xa6\xccw\xdc\xed\xbb\xa1\x0c^\xe7\x03\xe8\x1b\xbd\x85\xe132\x80\xcf\xe9y\xb9V1\x81\x86\x9dO\x9d\xc3\xf2e\x9bdtw\xb4\xeb8\xf8B\x86\xbc\xffbN\x96\xbb\xce9\xb9\xcb\xf7R\x12>\x92\x9b\xd4\x0c\x0c& \xda\x93\xe50R\x9b+\x06\x04c\x1d\xf6\x08\x9e\xc4\xd8M\x16\xfda\x0d\xcfkF\xbddX\xac\x05d\xc3\x1fi\x94\xb8\x8c}x\xfd8\x97EGm\xb0\x89\xfa\x06\xa0\xad\xf5(w\xbe.\x11\x1f\x81\x1fu\xe3E\x1e\x86\xe2E\x87\x7fz\xc1\x818\x91F\xa7\x89\n,\xad\x17\xf0\x10\x92\xb58\x02\x8f\xef\xc2g\xbdt\xd3\xec\xa6\xe9n\x8c\xf8h\x98e\xd1,a\x8c\xcc.\xa6\xd7\x92>o\xf1\xfc\xceMuE\xe4y\xb6\xef\xf3\x95\xa6bJ\x03]~\n\x03'&=\xf3\xc2c(8\xb4Ta\xac\xe9\x1dH.R]\xa0\x89\xd6\x1b\xc9\x90\xeb$X\xa7x\xda\xc5\x9aK\xd1\x83XO\x9ck\x19\xfe7_@\x02\xdbj\xa2\x7f3\xf6@\x99\xb9\xfc\"1`\x0e\x90P\x99tG\xd2\xf0\n\x05\x8a\xdaO\x91|,e\n\xdb4\x9a\x15\x12hm\xb3L\xda\xc7P\xce\xe3\\\xa6\xc1m\x1a\xe5%D\x99}\xaaI\xa7\x845xM\xee\x19\xfe\xf5\x0b\xbe\xff$\xa8\xd6X>\xa1V\x85\x91\x07\x01u\x15\xd2\xe0\x99\xc3R\xf1\x9eG\x07l{\x157\xb6\x9b\xe6\xc5r\xa6\xd8\x14<\x02F\xbd \x14\x05[\x9b\xdf|\xab\x0f\x86Q|\x91\xbbOn{\x99\xf7\x92\x8a\xb5+{\xad\x9f\xb3\x04\x8f\xf5T\x8b\x80\x95\x9b\xc2\xa1\xed\x87IBs`\xeb\x12B\xce\xfb \xccj\xa1\xd8\xdas\xd2!\x90'}\xbd:\xb0\xa3D\xed\xd9)\x99\x92\x94$\xe32D\xdc<\xca`\x1ef\xc9\xd79\\\x11\x92@\xc4\xaf\xb1D\x19\x99\xc0\x00\xb2bIR\xd7\xabA\xb0\xa1\x90I\x87\xf8\xb0\x86\xc7\x0dJB\xc9Z\x10\x1fm8\xbb\\P\x81\x86F\x0d\xfa\x86X\x843\xc2\x98\x1f'\xfa\x93i\xcb-\xc7\xa2y$\xab9d\x93`I\xd2,\xcarSX\x05\xc9\x14\x92\xee\xd3\xbdd\xa5\xe3kU\x1f\xd0o,=s\xaf\xb0\x1e\xd2~=dO\xe9\x06\xf7\x92U\xe1\x82x\xe9\xcd\x86\xe1\xaa\x12\x9aGS\xbc\xe68,\xb7oxYU|\xf2\xa4\x02J\xf1\x88\xa8G\xbe\x066\xd8!\x08p1\xf8\xaeZP\xe1\xcb\x92\x91\x0e\xf4\xeayUd29\xb7\x89\x12\x13-%?\x93\xfb\x03zk7\xa0\xca\xa7\"\x0f\xa9C\x8a\xda\xfa pFI\xceS\xc20\xf1\xfe\x9a\xdcsdNi:&\xc7\x12\xed\xbe\xc85e0\x10\xb2.\xbe\x8a\x8b\xf4\x91\xfdcUM\xf4\xbbb?\xb8\x86\x80\xf0\x11\xe9\xd7\x1f\x1eQs\x1b6\xbd\x92\x86\xba\x84\x0f\xf9\xc8\x05^\xc4\x06/F\x83V-\x03\xfc\x8a\x84=\xb5\x0f'\xc1\x84\xf2\xf1Z*\xdb\x97^.L)\x8a\xed\xa5\x1b\x0d\xf2I\x82(\x13\xbc\x8e\xdf\xd1a\x02L\xd5)\xab\x9f\x19\xdb\x07\xcd\xcb\\\x87\xddGtg\xd3\xd7\xcf\xbf|\x90\x0e\xa6q\x91\xcd\xfbN#TS\x99\xf3\x9a\xb6\xb4\x13Hf\x8c!\xc7\xab\xb4\xafEk.\x1a\xb2}NOXz\xea\x97\x93\xd4\xa7cI\xc3\xc4$\xce\x18D|Z\xe5r\xad\xfeS\xca\xba\xec5\x9f\x98_\xa0\x86\x03\x1b\xc6J\x0c\xe3^$\x91d&--K\xec8\x81\x04\x0d\xb31\x7f!Wx\x14E\x9e\xa4\xac\x08\x0c\xa2X\xfe\xfeR\x0c\xe8\xf1i3{\x07\xdf\xc1\xa9\xee\xe5\"(\xdd\xe6\x98<\xd6f\x8c\xd8\x8en_\xa9Aj\xcd\x87\x9d\"\xa81r1\xb2\n\xf4=A\x07?\x83\xe8|\xc6\x84O w\xcb\x94d\x19\x93\xda\x17E\x96\x03\x89\xf29I\xe1\x8a\xf0\x06h\xaa\xc8\xd2>\x06\x1dv`\xbd\xfc\x90\x862I\xa5\"U\xba?\xe7N\xae\xc8\xdb\xa8\xe8Pz\xd4\x8ei\x92\xe5i1\xcei\xaaS[\xe4#g\xc0L\xef\x95F\xda\x8e8\xa0>R\xff\xb4\xbbA\xa9\xba\xec\xd0\x94\x8cICK\x92{\xbb\x02\x1bYM\xa2\x86]\xd0\xbe\x17\xf3>DUN\x8a\xe5l:\xeb\xa4\xc3t\xcf\xf2T\xa0a\xbd\xf2\x81\xf630\xbf\x8f\xe2\xf8S-\xcch\x95\xab\x8b!\xaeb`n\xdc\xbf\xe8\xb2\x97X\xac\xc9\x7f\x89K\xac\xdcH;\xb7\xd0D\\\xc6\xab\x8dF\xbf}\xe2\xe8k\x8b\xff\xcf?\xcb\x8c\x85\xb84+g[\xc5\x01\xb7Q\xd2[\x8f1\xddi\xf6!\xa9<}\xb5\x93Q~\xac1}I\xb7\x01\xb5\xe74\xbdK\x16\x9f\x83\xbc\xb8t#{k\x92Xzw\xf1o8\x97\x10\xb9\xbe\xec\xf4\xe5*\x91\x15J\x8a\x04R\xb1k\xbfM\x82\xec\x95\"\x9b\xbc\xbaG\xf5\xc6\xe68\xc3\xa3-TUNP\x1f\xb1\x9c\xef\x8a\x90\x0fB\xab2\x03\x16\x02\xd0\xde\\\x86PQ\xb2,\xf2S25\xc3\xc5}\xcd1\xf2\x916\x9c\xff\xf4I\x1aUZ\x7f\x89\x07y\x19\x96<\xf5\x98\xb8\xb3\xa9XA\xec&aR\x9a\x84\x13n\x12\xc6\xac\x85\xf6\xcfK\x1d\xca\x08\xf4\x80~/\x8e\xa0\x18\xc7\x07G\x12\x85S\x1aQ}pJ\xa2\xc0d\xd1u\xa2\xc0\x83\xfb\x16Q4\xde\xf2y\xe7\xed\x8b\xb9\xe5?\xe4k9G\xd6\xd3\xffqG\x0cKt\xf3\x86]\xcb\xdc\x95_/\x1d\x01\xc4o\xfd\xbe\x06C\x08\xfb\xb6g\x88\x17\x0eC#\x910\xba\x98v\x0c\x89\x95\xd3\x8e.0\x1c\x96\xe3a?\x8c=)z\xb5T\xadB\x99\xba\xb4(r\xaeueb\xe8\xba\"\xf3=\xd8\xd6\xdd\xd7\xad\xcd\x06D{\x93h\x8b\xc2\xad-\xa3\x0d\"w\n\xd9\xc1\n\x97\xf8W\xc7\x99\xa5\xe5\xae\xa0\xdc\xd3\x9d\xd1\xdd\x92\x8cs2QM\xfcmBIa\x07\x8e\xc3\xe3v\x01cz\xce\x85\xf0\xf09\xbb_\\\xd1\xf8\x83\xa6~\x04;\xb0\xf1\x7f\x7f\xcf\xd6\xff\xfc=[\xffjc\xd6\x86\x08\x11\xe2b\xb0\xfea\xf3\xeebs\xf0}8\x98~X\xffjC\xe3\xe6T \xe4\xe6\xd5\xc5\xe6\x96\x01\"\xe3\x10\xf4bs\xf0\xad\x01\x841A\xcc\xad\x7f\xa8\x93\x1d\xd8\xde\xaa\xa4f\xa9\xe9\x81B\xe7:\x11NM;R'\xc3\xd7\xed\xa6\xa6\xfa\xa62\x12OY\x0d\xf5\x7f}\x9b\xac\xa4\xdd,\xdb\x80\xc6x\xf6\xcb\xfey-\xe7\xd9\x91\xd6\xa7y\x949\x9e.\xec\xf2\xa4R\"+\x16,\xd3\xe4\xb4\xc1\xe7\xb0\x03Ga>\x0f\x16\xe1\x9dF\xac+K#\x8d\xf8\xd2\xef\xb6'\xef\xf028`\xdbNBou\xf2\xa7r^\x07\xea\xb9\xd8L\xaf\x7fH\xddC&\xba1\x1e\xa8\xac\xad\xf1\xac\x18\xb5 \xd2d\xddiz\xa7\xea{\xa3\x89\x9e\x08\xd2\xac\xa0\xc9\x97nK\xd3\xc2\xeat\xebX\xa2\xbe\x93\xe1\xba\xab5\xde\xed\x16\xd0hD\xa0BC\xaa\x066\xc0Z}\xf2\x04&B`\xf3@{i\xe5AM\x13\xa4\xb1\xcdc.\x15KF\xa9\x9b2\xa8PmBdF)\xdc\xbdQ\xe5/\xffF'U\x93\x17\x1a\xec\xc0\x8cm\x86\xbb\x90\xc3:\x8f)\xd6u\xc6\x0c\xcd\x0cJk\x9a)\xac\x12\xe6\x13\x18\xc2\xba\xe6\xf3D\xb8\xdc\xf2\x84~\x11\xe6\xf33\x1f\x97\x16\"\x1d\xb4\xe5,\x90\xcdp&\xc1`\x17bW\xe4!u\x9f\xa2\x86\xba\x0bOa\x08\xdf1l\x84\nX\x8a\xfdk\xd0\xb3\xfaK\xf5\x8ci0\x17\xed\xa1>\x1e\xd1\xf9\x10a6\x99\xc2\x87\x0c\x85\x13\xf4w\xd7\x0b\x1cSn\xb2\xd3\x96--e\x13\xb4\xd9\xebIH\x9fpLo\xa8K\xbc\xc6v\x02\xea\"\xbe\xea\xf6w\xb4\\_b|2\xb2Jv\x8ca*\xe9\xdbx\xa0\x17_\xa8x\xdcr\x9e26\xae\xa1Js\xa75\x91;\xe5#;M`\x00\xb1\xb5gJ\xc0\xbd\x98\x11W\xc2T\xb6\x9c\xff\xb5\xcdu\xb7%zB\xc0\x00\xc6\xac\xac\xad\x04\xd8\xfax\xdb\xa9\xf4/l\xe1\xff/k\xf9\xc6\x8c9\xca\x18\xd5f$\x17\x82\x99{\xeb\xf7\xdc\x05K_V\x18\x80\x8b\xb8\xea\xbe\x9c\xba\x84]\xb8q\x13\x1fBYi\xec\xa1\x05\xdf\xb8a\xae6\xab\xa3\xce\x9d?S\x08i\x02\x98\x1dk\x17\xae\xf89\x82\xdb\xa4\xb4b\xb5\xaf\xdf\xf5\x99/\xf3JHx\x1c\x06\xcb\x8cR\xd5\xa5\x8c\xe7\xe4\xe2.\x10L63EJQ\x1bP\x086\xf3\xdaV\xfe.\xb3\x86\xa80\xe6_k\x13N\xee\xf90\xad\xf0\xa9W\x14\x01g\xd6F,\xe2^\xb42c\xed\xcf\\\xb9\xa6\x00\xfb=\x17l\x86b\x8c\xaeq\xcf\xd7\xf4\xdc\xe8\xc5\x95c\xe4\xe8\x1ccbn\xfa0s\x85\x15\x06\xf7\xec\xb54\x88 \xe6f\xe0Y\xb0]\xb6[;\x8b\xf0\xee}\x18\xe5\xdc\xfd\x8cq\x98\xb9{\xef\xa6\x81x-[B\xc3{\xe8\xe3&\xee\xe4i\x18\xc5\xc8K\xd1em\x17\x9b\x96/a\x08\x13L\xe0\xd7\xffhT\xb1\x00#\"0)\x98\xc4B&o_\xf1\xebG\xb1X\x15\xd5\xd2ic\x87}\xbd\xf7\xb9\xafn2v\xa1\x80!\x8c\xdc\x85kH\xf0U{\xa9\xb8\x87IW \x1f\x12\xf7\xd9\x96\xa8\xdc\xa1\xe5I\xe7\xc2z\xf7\x9c`#\x8c\xe3\xe0c\xe6\x0c\xe1\xf9\xf3\xe7~\xab\xb0\xc8\xe7\x1b!6\x9aq\xa8\xa7\xcf\x9e\xea\xa1\xd0\x88\xc7a\x9e}\xffL\x0f\x93\x92I1&i&\xc1\x0c\x1f\xccd\xe2! \xf7\x8d\x01nI\xc6\x83\xdb4\\\x0ej]|\xf6\xfd?[\xf0\xfc\x10)k\x8e\xa5\xdd\x01 8'\xf1\xb2\xec\xe9\xd3g\xed\x01I\xc0\xda\xb8\xbf7\x82\xd5\x87\xfe|\xb3\x8dE \xd9\x18\xfd\xf3\xcd-3(C@mH\xcf\x9b&\x06'\xd8\x98\x10\xb2\x1c\xc4Qr\x1d%\xb3\xfa\xb8\x9eo\xb61[\x83V\x06\xf7|\xb3\x8d\x83\x1al\x1c\xde\xd3\"\x97\xc0m\xcc\xd6\x80\xcb|K\x83<\x9c\xe1\x1c.I\x1a|\xcc\xee\xb0\xf2\xb7}+7+\xb6'~Bo\x93\x98\x86\x93A\x91\xc6r\x96\xbekA\x914\xad\x93\xc6\xd6\xd3v\x1f\x18\x10\xdeG\x18\xe4i\x98dS\x9a.H\x9am\xcc)\xbd\x16-?mO\x95\xa1R\xedGB\xf3\x01\x9d\x0eP\xc9\x16\x0d\xb5\xc9\xa3OC\xcb0\x0d\x17$'\xe9\x80&\x84Nec\xed\x89\xeb\xd3\x18\xd3d\x96\x03\xe9\x0e*\xdbj\xcf+kK]\x04[\xedE\xc0@\x1ak\xffi\x9bN\x19Ts\xe9?m\x13(\x8f\x9dP'\xcd\xf6\x8c\n(\xba\xccxV* \xd9\xee\x1c\xa7\xdb\xc6\xce\xa0YF\x02N\x1d\xea\xd36\xbd \xa8\xe6h\xdb\xd4$\x00[\x03n\x0f%\xa6\x8dm\xe6\xbb6Rh\x98=knn\xed\xceq\xa8\"\x9f\x0f\xc8]N\x92\x8cAo\xe0\x06\xda\xdct44\x83\x95\xcb\xe3\xc5l\x83\xf1\xa0\xabp|\x9d\xc9\xd5\xa7\xc1F\xb3\xce<\xcf\x97\x03\xd6\x01YG\xc3M\x9au\xd4\x89\xd6\x90C\x13\xbc\xda\x1c\xd8vQ\xf6\xad\x8dVs\xc5\x8c\xa7X+\xfb\xd8\x8d\x8b\x94\xfc\xbf\x82d\xf9\xe0\x8aN\xee\x07d\x12\xe5\xb4\xdc\x93\x9e\xb5\xf7\x04[\xed\xb2\xc3m\x8aiV\x13\xdd\xac\xb2\x1d\x95\x9fl\x13\xaf\xa1n\xf9\xb5\xf6\xb2\xc0\x1a5n\xf1\xcc\x80\xfc\xda\x04\x19F\xdb`\x7f\xcf\x0d(m\x92\xe1s\x03y \xe3Sh\xb8E\xbe\xedmJ[OO\xfb\x86\x8f\"\xb0\x82C\\HQN\x16%\xde\x0d\x0b\xa0YQE\x98F\x04\xd1\xd6Q\xa38p\x1b\x93D\x91\x01\xe3\xcd\x06\x16az\xcd\x98\xa1\xfc\xaea2[\xd5\xe8\x84\xc4r\x80\xcf\x0d\x84\xd5\xacD\x938J\xc8\x00\xaf\xb6\x859M\x07W\xe1dF\xe4\x97\x0d\xb4\xd6l\xa4df\xd5B4\xac\x89f\xcd\x1b\x9e\x02r\x90\xe5\xe1bYV\xd6\xec\x00 \xd6\x8aINjs\xb2\xd5\x1ef\x86\xb71\xb3\x8d\xa9\xc0\xdf\xd6\xf7m\"\x910\xb5\xad\xba=\xbd\x8c\x06\x9b\xdcF\xd3\x18\x83R[\xd2\xec\x94\x08\xd3\xe04\x9a\xcd\n\xc1\x1aD\xfeT#U\"\x9cF\x9c~\xde&k\x99\xd5\xeecc\xb4m\xc8\"\x8f\xe2\xba\x8c\xdc\x9e\xc4\x9b\x88\xdc\xd6`\x9e\x1b`RJ\xf3A\x94|$\xe3\xbc\xec\xdcw%\xa46]\x0d5^\xd8I\xdc\xa8fly\xd0\xd4\x8e\xda\xb5\xa5\xad9\xbd \x8d[Z\xfc\x06M\x0e\xeb\xb0U\xbb8S\xbf43\x8d\x92 ,\xf8\x0d\xa1\xaf\x1dX\x07\x02\xeb\xe0|\x1d4\x0d\xbdR\xd7V\xfa'\xff\xa2\xc15\xb9\xb7\xe6O\x16\x95\xc5\x11\x0e\x83v\x95\xcb[\x0f>\xd0 %\x19\x8do\x08St\xeb\x17\x1d)+\x8d\x98\n\xbe\xb5\xf9\x0d\xc7\xee\xc3\x07\xef\x1f\x0f\xde\x8b\x7fll\xfc\x1f\xc8h\x91\x8e\xc9Q\xb8\\F\xc9\xec\xdd\xe9\x9b\x9d*\xc3\xe1\xe0\xaaH&1[\xe7\xc1\"\\\xfe\xff\x00\x00\x00\xff\xffPK\x07\x08-\xe3\xb5\x97=9\x05\x00\xf7\x0c\x1b\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00 \x00swagger-ui-standalone-preset.jsUT\x05\x00\x01\x80Cm8\xec\xbdys\xdc6\x9a0\xfe\xff|\x8aG|w\x152M\xd1\xdd\xad\xc3:,k\x1d\xc7\x9e\xf5\xbb\xf1Q\x963\xf3\x9b\xb7\xa3UQl\xb4\x9a1\x9b\xec\xe1!Y\x13i?\xfb\xaf\xf0\x00 \x01\x10 \xd9\xb2\xb33\xbb5\xacT\xac\x06A\xdcx\xeec\x0b\x16U\x1a\x95q\x96\xba\xa5\x0f\xc4\x83\xdf\xfe\x00\x00\xe0dW\xbf\x92\xa8t\xe0\xf4\x14\xca\xbb5\xc9\x16@\xbe\xac\xb3\xbc,`{\xdb\xf4v\x95\xcd\xab\x84\xc0\x19\xff#\x10\xb5O\x81\xb8\x1e\x1c\x83#\xba\x91?\x9a\x93E\x9c\x12\xda\"\xfb+\x08Ws8\xe3?\xdc\xd9\x05\x0e\xe8\xb8k0g\xe2\xaf\xe0\xfc6\xbc\xbe&\xf9\xcfo\xce\xcb0\x9d\x87I\x96\x92\x0f9)HY\x0f\xa1\xec\xab\xf3\x87\x07\xb7\\\xc6\x85\xdf,\x89X\x8e\x9c\x94U\x9eJK%^\xd0\xe7&\xcc\x81\xc0)\xfc\xf6p\xf2\x87\xbaPT\x85\xd4\xcd\xe5\xca\xf4\x89\x17\xe0\x92Y~\xe1\x89v\xe9\x0f\xb1b'JU\xdavLG7\xcb/h\x17\xcaKl\xeb\x18r\xbfU\x9a\x1c\xc3\xd6\xa4]\xcc\xbb8\x86\xdf\x1e\x94w\x0fj\xa7|T%\x1dU\x14&\x89\x1b\x8b\xc1\xf9\x10\xfb \xfdJ=\xfa3\x81S\xd8\x1aK/\xea\xd6\x9anx\x9bi\xb0\x82S(}H\x83\x88N\x8b\xfe1\x87S\xf5\x10\xfa\xd0Z\xb24\xc8\xf8\xf9\xbc\xbf\x87\xf7x\x1c\x02vL>\xe4\xd9\x9a\xe4\xe5\x1d\xff\xb2\xbdBQ\x96.\xe2\xeb*\x0f\xaf\x12bY\x96\xb4Z\x11\xf1~\xdc~\x7fM\xcac\xc8\xd5\x15\xf3\x9a9\xd29\xa4\xca\x1c\xf4\xd1\x8b\x13R\xd2\xa3^\x06\x97\x97\xa4x+\xeeK\xeb\xac\xc9\x8f\xd8 :\xd7\xb0JJu\x0cp<\xec\xeb\x01{\x9d\x06s\x97\xf8\xe0\x84\x0e]d\x1f\x88:\xbdL\xdf\"\xbd;\xde\x0c\xdf\x99u\x9e\x95\x19\xbd\xa9\xc12,\xde\xdf\xa6b\x8f\xd8i\xc2\xef\xd5\xf6\xd7p\n\xce\x93y\\\x94\x8e\x0f\xa9\x9b\x06\x14pL\xc7\x07\xac\xda\x83;\xd3\xceG*\xf7\xefT\x05\x81\xa2\xcc\xe3\xa8tN\x94[\x99\xc3)\xa4\xee\xfe\xd4S\xf7\x94^\xa8\x99\xf39N\xe7\x8e\x0fNN\x8a,\xb9!\xf4\xcf(K\x8b2\xaf\":\n'N\x8b2L#\xf2~A\x7f\xads2\x8f\xa3\xb0$\xec\x935\x05\x1b)\xd6\xe3[s^\xde%\xf8\xb2\xa0\x7f\xbcH\xe2\xb0 \x85s\xa1\xf6\x9ca\xcfE\x14&a\x8eu\xc9_+\x92F\xf8\xdd*\\\xaf\xe3\xf4\xda\xb9h\xe6PJ`\xb4s\xf9\xe9dS\x1f\xaa\x936\x9c\xa1\xb7\x8c^\x9a\xdf\x1e|\xb1=\x9f\xc9]\xe1\x12/Xd\xf9\xab0Z\xbau\xd3\xadvE+;\x138==\x858\x88\xd39\xf9\xf2~\xe1\x12\xcf\x83r\x99g\xb7\x90\x92[\xc8\xdd\xef~N?\xa7\xd9m\n\xd9\x1a\xa1\x9e\xf3\x1d\x8c\x80\xc0\x08\xbes .`EJ\x88S\x06\xd8c\xac\x90-X\x9d\x92\xd5\xf9\xcb\x8b\xb7?!l\x0f\xbe\xf3\xb4\x8b\xe6\x03\x05\xcaA\x19^3\xc8\x81\xbf\xe8\xe6\xd1\x99\xb1?\xee\xef!\xad\x92\x84\xbf\xe3\x1b\x8a\xaf\xc5\xdf\xf7\xf7\x83\xae\xca\xd6X\xed\x9c\xb7X\x9f\x0bl\xb3\xf9%\xb7\xda\xba\xf4`\xbd\x81\xbc\xd5\xe6\x80a\xb3\xd2Ou>\xf5\xd1\xc3j\xcd/}\xd6\xfcL\xf2y\x8b_j-\xf9\xb0bE\xa5@\xad+\x1fd8\x057\xc5\x0f\x94\xd2\xfa\x83\n\xf1\x9f\x8f\xbf`\xeb\xf4\x14R\n\xea\xe4\xf3\x96\x1a\xce\x9bq\xcd\xd2Yy1\xf0h\xd2\xa7\x9a\x9d\x97y\x9c^\xbb\xc4\xa3\x18\xb2lUzh\x1f\xa8\xca\xf3\x81\x1f\xe9\xac>\xd2\xf5\xb9\xb2\x1dm\xd0F%\x1e:\xba\xc8\x87\x85\x0f\x89\x0fk\x1f\x96\x8c\x06\x81\"x\xdd\xa6r\xe83\xaf+\xfc\xd1\\\xe1\xa6\xaepn\xaepWW\xf8`\xaep]W\xf8\xc1\\\x81\x12\x88\x94\x0b\xc8\xe1\x18n\xe8\xbf3\"N\x17A\x1a\xf8\x81\x12\xf3\xae(\xfe\xed\xc1k\xe8\x0ds\x8b\x97\xbc\xc5\x98\x9eB\xd1Z\\\xb7f\xfe\xe8\nN\xe1\xb2i\x19\xbf\x91\x7f\xe3\xa7'\xadO\xe9\xf5w#Dvx\x98\x10hz\xb8?\x94Lv]\n\xec\xb7\x96\xf4\xdd\x8a\xfe\xef&\x8b\xe70F\x90\xb9\x9aE\x17\x1e\xe5\xa0\xe0\x18Ro\x16]\xf8@\xe9\xa2kZm\x01g\x10\xba R\xc6\xc7p\x87L\x98\xe9\x0e'X\xef5\x7f\x83\xf4\x96\x0f \xfd&\xf1Y\x87\x95\xbb\xf2\xe9\xa1\xa0P\x1e\xb7\xe1g\xcf\x87\xcbYt\x01[\xa7\x90\xe0\xcdu/\xb1\xc6\xda\xf3YOW\xf2[\x17\x7f\x9dB\xa2\x81\xd5f)\xf2 bw9\xf6\xe9I\x83S\x98\xd0?\xfeHI:\xfa\xc79\x9c\xc2\x1e\xfd\xe3\x03\x9c\xc2!\xfd\xe3\x07Z\xe7\x80\xfe\xf5g8\x85]\xac\xf53\x9c\xc2\x01V\xfbH\xdfN\x0f}\xe5\xc6\x17\x9b\xdd\xce]\xe3\xed\xdc\xd3\x8b\xf9\xed\xd4\xef\x1b\xbd\x9dO\x9c'\xd7\xed\xcb\xa9\xf7n`]@b\xe38\xaa\xca\xdc\xd2\xb3\x1c;\xda\xa8\xf3\x8c\x02H\xd2>\\\x1c\xde:N\x83b\xdd\x10F\xa7\xe0\x00\xfd\"\xa5\x18\xe7\x14\x91\x0f\xef(\xf7(%\x90\x84\x11q+\x1f\x9c\xed\xbfVYy\xe2x\x88\x99\xbe\xf3|\x08a\x04\xces\xfamL\xffz\xf6\xc4\xe1d\x9b\xf3\xdc\xb1m\xeffD)\xe7\x8b\xe5\xf2\x94a \xe2\x86\x9e\x0f\xb9\x9b\x07\x1f`\x04y\xf0\x1a\xbe\x87\xd8\xed\xa4\xd2\x04\x1f\xe580+/\\:\x07\xeb\"\x11\\#\x12\x94\xd9O\xd9-\xc9_\x86\x05q\x91{$A\xb1N\xe2\x12\xbf\x0e\x12\x92^\x97Kx\x0e\xbb\xeat=\x1f\x1c\xb6\x86\x94!\xe9C\xdc}\xe8\xc9\xa9R\xc6\xac\xce\xe9\xce\x89\xbbz\x1b\xa7\xf3\xec\x96n\"\xfb+x\x1b\x96Kz\x97\xf1\xdf3\xf1\xfe\xd8\xf2yA\x92\x05\xfd\x98\xfe\xab\x7f\x8a\xef\x8eA\xc0\x01\xd7\x11\x84\xe82.\x1c\xcf\xf5z\xf0\xe05\xc7\x83\xd7\x8f\xc0\x83G\x9d\xa4\xca\xbe\x8e&\xd9\x8d;\xfa\xdfC\xaa\xd8\x89\xb8\x03\x9d\x16\xa0Kb\x90m\xc9\x1b[o0#\xa5\x91d\xe5\x7f\xf27\xed\xe5\xcc\xe9\\b\xfa\xbf\x01\xfb/\xaf^6\xf8p\xbf\xc8\xf3\xf0.\x88\x0b\xfc\xd7\xdcX:\xb8\xb1\xff\xe57E\x9e\xf2\xb0\xb3J9nN\x17\xd0\xbe\x04;\xf2\xe9nM^\xe5y\x96\xbb\xce\xcb0\xfd\xae\x04\x8a\xdd)k\xbd\xcc\xe6\x90\xa5\x00\xec\xac\x9aey\x9bB\xb0\xa6\x15E\xb4e\xb9Vt\xb5\x9a\x1e\x94\xf3\x95\xdfi\x9f\xd0\xf6\xd2\xce\xd3\x89wq\xec\x03\xb9 \x13\xcfuXq\xd3\xfee\xd9\xc7\xbf\xcc\xfb\xf8\x97\x9b>\xfe\xe5\xae\x8f\x7fi\x18\x9c?\xdb\x19\x9c\xe5\xa6\xec\x08\xe5aV}\x8c\xce\x15o\x99\xb2Ns\xc1:\xd9x\xa5.\xdee\xa9\xf1.\x8ckY#3\xa0q-W\xc8\xb5loC\x88\x8c\x05\xbb\xbc\x94\xd5\xa1,\x0b\xf2\n\xc7\x90\"3\xb3b\x8c\xc3Rc^\x9a\xd3\x8f\xb5\xcf\xb0\xb6`rh#Y\xcd\xf7\\\xd7\xdc\xc8\xe9)\xb2:\xdd\x92$\x90H\xc6F\x90d\xa7\xd2\xc5C\xaf'\x05: Dr\xecf\xda?\xa0Oq\x1b#T\n\xf3\xebjE\xd2\xb2\xe0\xb4e\xdfw\xf4\x89\xc2\x82\xc0\xf8\xb8\xb7\x1eH\x02{r\x0be{\x0b\xf5\x07[\x9el\xde\xb2K\x0c\x94\xb5\xfe`\xe3\xd3\xc74\xae\xd0\xd4\xa6\xe7\xa1\xf3m\xab1\xba\xa1\xd6/\xecm\xd5\xea\x95p\xbdN\xee\xb8\xf2\xaf\xde@s\x8b\x0f\xe6u\x11\\\x87\"!\x904!\xb2J\xa5n\xcaE\xce\xfc\xa6\x93\x9b\xcfl\xdc<~\xe6\xba\xab\xe0&\xce\xcb*L\xf0\xe25\xbf\x10\x96x\x9cW\x17\xbc\xfeG\xfa\xcd%\xfd\xdf\x16\xb2\xfc(\x0f`\xdc~\xe2yV\x8e\xfe\x1f\x85\x8b\x9f\xeab3.dk\x953\x1cu\xa8#4\x8a\xa2\x8c\xca\xc3f\xaa$X\xb06\xf7=83W\x96\xd5n\x16\xccE!H\xee\x96\x9e\x8f\xb0'\xa3gtk\x8c\xdc.jL=\x03Y\x04\xcd!\xaa\xeaf\xd5\x0d\x91 \x9f\x87V\x7f\xce5)\x1d\n\xbc\x91\xb8r\n\xf1\xcb@>\xbe\x88\"R\x14Y\xce\x08\x8a\xa2Z\xd3\xfd \xf3-\x0bA\xe1\xdc\x84IEx\xdb\xf4\xd0\x95\x0cY\xa5\x01\xbe\xf0\xfcMI\x0e\xf9\x08l\xa5\xee\xf4\xc8\xb3\xf3\xfd|\x0cO)\x9e0+~\x7f{\xe0\x8a\xcb\xf6\x82\xa2\xe6\xb6S\xa4 w\xd1\xbe\xa0\xea\xfa{A\xd8\xcc\xb3\x9f\xd8o\xe4\x1f\x9a\x1a\xb4\x8f\\\xb4\xebWS\xa3\x06u\xc8\x92K\x82j\xcb%\xda\xdd\xb3\xb0\x85\xa9\xbb7\xf5\x14dk>\xf4\x82\xc5\x0e\x16\xbcF\xecNh5\x99t\xef\xbf:\xb5\xf1\x01;b\x1b\x9f-I\xe67\xb1L\xa8\x9b0\xdf\xa2\x17\xb7}iT\x1a<\x05\xc6k\xd8\xaeL\xdf\xa0\xfb\xf8`uX\xff\x8d\n\x8dne\xba\xb2rCd\x82\x88\x9bc\x1f2\x1f*\x1fB\x1f\n3\xa8\xa4@d\xcbHc!\x03\xd0\xc6\xb9\n\x8fL\xc9T\x88\xe8\x1c\xc9-p\x18\xf76N\x99B\x8e|\x89\x08SJgQT\xe59\x99\x9f\x00\x9dd\xb9$\x90f\xe9\xceJT\x9c\x93\x1b \xe9M\x9cg)\xc5\xffH\x0e\xd3J\x8b*I\x80\xd0VaE\x8a\"\xbc&\x10\xa6s\x08\xe7sTe\x87 ,I\xb2^T \xdc\x86y\x1a\xa7\xd7E\xa0\x9f\n\xfa\x90\xa4 \x1dD*E;3}\xb1.\xcct>}(\x86\x1f\x9bi\x11W]\nR\xcb\x80\x9f\xfck\xf1\xe4\xda`\xdedz\xf8A^\xcc\x92\xd1\xe8\xc2X\xeb\xc1\xf3\xbc \x0dW(\x91}\x93\xde\x84y\x1c\xa6%\xfc)\xce\x92\x10)\x99\xd6WmJ\x8c\xdd\xb2(X\xe4\xe1\x8a\x14\x9f\xb2\x0f\xd9\x9aQ\x1a\xd1\x1f\xcc\x1f\x0e\x82\x01}\x16!OM\x9c\xae\xa4\xac\xeeW\xec\x0b\xb6bvaa\xa3\xd8\xa5\x8eS\xca8\x90`]\x15K7\xed\x10V\xab\xb35_\xacD\x9d\nW\xf2\xca@.\x0b\xe2tI\xf2\x98\x83\xed\xdd}O\xfd\x84\xb1\xe8\x93C\x1d\x03p\x1e}\xf2\xd4\xd8\x16e\xbf*\xe9M=?\xdaK\xec\x86\x0d\x91\xeb\xf9x\x0b\xc7'\x10\xc13\x10\x1c\xd0 D\xa3\x91\xbe\x88\xe2\xc8\x17\xb3H[\xc2\xa4io\xb6`\xcc\xb1Vt\n\xa1R \xa3\xc2f\x94|\xff \xb1\x80\xf9\x16\x8b\x97x\x9e\xccY\xd0\xef\xd4\x91U\x1c\xfb\"\x9b@\x89\xbbP/@\xa9\xec\x16\xb3,(\x83\x9c\x84\xf3\xf0*a@\x98\x1bi\xf0\x92S\xd8\x9a\xb4\xea\xdf\xe6q\xa9\xd6\xafKD}Z\x18&Iv\xfb\xefa\xb2x\xbf&)7\xbdS\x1bRk\xd4\xad\xb5>\xac\x9b\xcc\xd2\x88\xb8\x0eA\x83\xa8u\xf7r\xae[P\xc3\xd0\xf6\xfd=+\xbd\x14\x138/\xc3\x92\x04$\x9d\x13\xb4\xd6\xc9\x83\x94|)?\xc5\xd1gw\xc9\x86\xd0\xdd\xe9\xb2\xbd\x87%m\xcd5\x89\xf2\xccTb\"\xf3b\x8e\x18\xd7\xbf\xc7\xd7\xcb?\x87%\xc9\xdf\x86\xf9\xe7\x16 \xa9\x18\x06j\x86\x83\xfd\xa4\xa5$\xd5\xd4\x17b)w\xab\xde\xfdfB\x9e?h*sR\x94yvG\xe6\xad\xe1\x0f\x1e\xa2$\xcea\xa3\x15\xe7\x14G\xab |\x0c\xf3i\x8e\x98\xfaeP\x8f\x8d\xd60-D]Acu4a\xa12\x113@\xfe\xfd\xa7\xd0X\x9f\xd9&A\xabx\x1d\xdb)m\\p\xc9\xbf\xea\xa3\xfc\xb1C\x86?\xaa$\x11\x17\x16\xcf\xbe/\xdf#\xe2\xcb}\x7f\x13499\xda\xb3\xea\x8a\xec\xbb!\x8e=\xaetN\xd7\xb56\n\xeb\xa3\x8a7\x1c\xdf\xde\xc1\x9e\x01\x8f\xbf\x0d\xcbe\xb0\n\xbfv\xeds7\xde|\x02\xd2\x80\xcc\xe3\xd9\xb73\x88LZ2\x90\xb5\xfb\x87a\x10\xa7\x87\x1b/\xf0\xdf\x85A\x1c64!\xaci+\xc1J8\x93\xee\xa0\xcd\x19\xe3\xdb\x8f\xa8S\xc8\xb5\xb5U\xba\x1d\xf2-\xebg\x9a\x85\xeec\xf7\xdeb\xaeg\x16$\xee\xeb\x06\x96\x8c\x90>:\xf4\\\xa7\xc8#\xdd\xd4\x81\x92\xd3\xb5\xd0\xb6\xcc\x98\x1dI[\xfd\xe5:\x0e\x8c \xf4\xb8=\x8a#j\xca'\x06-\x08\x838-\xd6$*\xcf\xb3*\x8f\xc8\x90C \x08S\xe9f\xf96K \xc1\xa5\x87&\x12=\xb2Y`\xa4\xea\xa9\x8e\x10\x7ffn\xea\x83CYB\x07\xf5@q\xf3\x9b\x1e \x8a\xbc\xe8\xadm\x8c\x97\xa4\xcf\xaa\xe6\x8b\x8a\xd7;\x03\\\xa1\x92i\xb1\x8a\xe0\xd7,N\xdd\xda\xda\xd7\xc3\xf6\x90\xe2\xcd\xe1\xac\x86\x07p\x0c\xa1\xf8\xa9\x94\xc6\xcd\x818\x06wN\x12R\x12|\xefK\xaf\x14K\x8fF\xf2.\xd3[\xf56u0\xd2\xe2.\x1a\xef\x19e;894\xab\x90\xc1\x91\xf8\x08\xb9\xffot\x0d\x7fo\xc0\xb01\xd66_\xbd\x03\x93\xa2\xd9M\xdd\x83\x03\xcf\xc7\xf7\xe3\x86 \xb69\x98\x18\xaf\xe9\xe4@7\xf3\x0b\x8d\xaeT\x9f\xc9\x9d\xd9\xff''\x0b\xf3\x8b\xcb\xcb\x82$\xf6wx]\x8f[ \xcb\xe4%VX\xb7M&[\x83\x9c,\xa4\xcdh7\x13\x0dk\xe63\xb9\xd3\xf6\x14$\x96\xbc\x0d\x1ar!\x962\xc2\x88\xb6\xbc\x92>\xff\xf2/\xec\xf8\x1cC\xd5^\x1c\xfa\xea\x18\xca\xf6\x0b\xdc\x03\x83v\x1b\xb7 m\x97\xaf\xf3l]\x1cChX\xff\xec6%\xf917j\x12\x8f\xd9\xfbI\xb2]\x91\xc4\x1cA\x94\x93\xb0$\xaf\x12\xb2bn\x15}\x94 \x9e\xf1\xda\x17\xa25\xa2\x84\x9e\xc6*I\x0c\xb3\xe0o\xd4\xc1QZ\x83\xdfNY\xdc/\x1e\x14\xc3\xe4\x10\xd3\xc3CP\x03\xef\xae\xb9\xef\xc7\xc2\xf3!\x12\x85 3\x98\x1c\x01\xa1\xfb\xee\xf9 \x8bM\x03v\x84\x05\x1c8\xaeK\xda\xd5\x18\xf2Q+b\x19\x02\xa5\x8c\x810\xe6\xbb\xb7\xbd\x0d[\xa1v5]V\xeeV\xcc\x93\x11\xfd\x1fOZ\xcb\xb7\x84S\xd05\xe8\xb0\x03\xd3\xf6\xca0Y\xc7\xd2\x83*\x88\x96q2\xcfQ\xa4\xa1\xa1%\x94\xb9\xd2\xdaKx\x0e\x13\x13YQ\x0b\xb3\xe6\xc2\xac\xcd]\xd25bb\xac\x1bx\x06\xcb\x13\xb8\x19\x8d<\x98\xcfn.\xe4\xd1\xcdn`\x04S\x83\xfco\xec\xabc\x9a\xab'\xb05\x13\xee\x15\xc8=q\xe8z\xb5\x84\xe4\xc0\x97\x07\x8dO\x94\x9a\x16\xf1#\x9e\x8b;O\xdeD\\xi\x07\xee\xe8\x0et\x0cM\x08\x80\xe9ig\xee\x03c\xfc/\x0eP\x8a\x9e\x96\x14g7\x17\xc7\xaf/\xcc\xeb0*\xb3\xfcn\x90G\xa4v\xc9\x82\xab8\x9d\xbb\xdc\x07\xc9L8\x93@(\xd75/\xc5E\x10%YJ^\xa4\xf3\x8fL\xdc\xfd\x1f\xa4\x97\xb9n\xe6\x18p%\xbd\xcf\xa0,\xfd\x87\xdf\x03\xfa\x07?\xe7e\xc0\xa0\x8a\xcf4\xfb\xebB\x9f?\x1d\xc0f\xf0\xa2\xaa\x0d\x9brTd\x8a\x86\xdb@\x02m\x9b\xe8\x15n\xbfB\xc1\x03\x0e\xbb}j(\x12\xed\x9a\x8b\xb79\xd0\xa9\x14\xa03\x17@\x87\xdd\x9a\xfax\xc80h\xa9\xc3 \xb6\xde\xec\xe0#\x1e\x97\xcft\x0d\xb6\x0c\xef<\x0d\xdaT\x16h\xc3\xca\x15\x15\x11%\xb6T9P\x02g\xb0\xa6\xc5\xa7\x90\xd0\x7f\x8e\xc5/Z\xd7\x00\x9d\xee6\x84Nw\x1e\xac\x87@\xa7\xbb^\xe8t]C'\xbaz+\x06\x9dV\xf0\x0c\xeeN`E\xa1\xd3\xf5l\xa5B\xa7\x95\x05:)\x03\xba\x1et\xff\xf9\xddX\xfa0\x17@\xe0F\x95\x13\xd3\xc3\x1f\x17\x7f\n\x93xn:\xfe\x9bP\xa4\x8a\xbc\x88\x1d\x10AJ00&\xf7\xaa\x10\xc0\x7f\x80~\xe2T\xd2\x0e\x1f\x98Y\xc0\xdd\x83~\xa9@\x87\xb3\x03c%\xcc\xa0+wS\x8f\"P8\xe6\x87\xb0\x99\x8aq\xec\xfa\xc09%\xa6\xab\x8a\x8d\x04ef\x10\xd3\x0b\xc3R\xae!-H\xf9)^\x91\xac*a\x192\xb1\xc5\x15!\xdcK\x97\xcc\x9dn\x91|\xd5\xdfA\x94\x900\xff\x8a.B\xb3\xfc%\xc5s\xd0\x8c\xbe\xd6\xda4Et\xf9\xc6\x06\xc8\xc6\xbf\xcd(\xd3\xb5\x95\"\x880\xb4C\xf7\xb1)\xf6{\xda\xed\x94r\xa4\xec\x0b\xf5\x9a 9\x87\xd1\xa7\xd5\xdc\x1c\xb4l@8\x92l\xb5\x0e\xbd=\xb4\xdb\xe2\n,s[\x16\x10\xf1\xb0eg\x7f\xcdsHm\xb2\x04\xe9 \x9e\xc9?Z\xc4{\xa7\x80(\xad=\x18\xea\xfa\x03\x06\x95\xdb\x06\xa5\x1c\xde3\xf5\xe7\xb1\x04\x85\xa0w`\xb4\x8b\xca\xb6\x8a\xae\xa6\xa2-\x98\nu\xa6i\xfe\xd1\xfeV\xd3@Q\x0c\xb931]\xfe\xb6\x8e\x8e\xf9? J\xe4M\xd5\xeaY:9z\xe0\x83(K\xa3\xb0t#\xb4/\xc4\xb6}\x88D\xa5\xedmX\xba^\x9f\x96\xcet]\xb7\x166j\x96\"\x89\xd0]\x1b\xd4\xe28F\x83uC\x8d\x0f)\x01\x18\xd5\xfaerb;\xe7\xf8\x01\x85\x92\x91X\xd7\x13\x18\x8d\x12x\x86\xdf\xe0\x82\x14\xb3\xe4\"\xc8\xab\xd4\xb5X\xbc\x8a\xa5\x90\xbb\xec\xb9%\xc0%|\xec\x8e\x9a\xf6N\x865\xbc\x92\x0b[Jk\xbd\x1d\xdeP\x85 \x90\xf1d\xc6F\xe9\xa9\x95_\xf8\xc3\xbb\xb1\x830\xf1\xe4n\xd9\x864\xe2\xe9\x87^\xe2\xe9\xef\x08d\xb5\x83\x0c7\xed\xdd\xc3FC\x80V\x07\xc2\x1a\xa0\xbb\x03\xfb\xec\x8do\x1e\xf4\x05{\xe8\xbc\x89s\xbb*qQ\xa5\x92&3\xa44%%x;\x9b\xbbq\x15\x8b\xd3\xb8\xd6:\x0e\xe2\xf1(E\xc0hW\x03\xed<1`\xe9V5J\x1d\xdba\x01\x9d\xcf\xe4\x04Rx\xd6\"\xceO \xa5\xc41\x99\xa5\xb4+\x95@N5\xe28\xe2ZVr+\x96\xcf\xf3a\x82th\x0d\x05\xef\xef\x01\xa3s\x84\xeeR\xa1~\xe7\x92D2\xaf:=\xa6\xc4&p\x9bs)\xde\x06\xee\x85\xd2l\x1c\x94q\x89\xd6\x1f\xceU\x9e\xdd\x16$wh!\xff\xbb\x89\xba\x94\xde\xf0\xf0\x1bq\x10\xe6\xd77\x0c\x7f@\x1cp\xbbAd\xbe\xa4\xdfE]\x1b\xdf\xdd\xe0w\xf3\xf9OqQ\x92\x14\xdb\xbda/Q\xd9\xc0\xfe^,\xc4\x9f9Ye7D\xaf\xccJ_$\x89xQ\x887d\x15\x97\xe2\xefuN\xd6$m\xf5\xc4\x8b\xdf\xa7Q\xab\xddDj\xae\x97\xa1\x98]\xa8\xabw\x15\xa7\xf38\xbd\xeeVR\xe9T\xeb:\xcf\"R\x14\xf5\xc7\xb1f%\xedh[\x14\xdd\xce\x07x\xc89O\x1c\xed\xb3\xe5\x0f\x18\xd9&\\\x88\x91R\xe22y&\xc8\x81\xb3\xe1\xbd\xf9\xd3\xab\xcb7\xef^\xbfy\xf7\xe6\xd3_\xb0\xc6\x04\x9e\xd8V\x9a|)I\xda\x8a\x8bh[\x02\xa6\x9dk\xd3Q6\xf9-.\x0d[:7S-\x9f]\xe2y\x0d\xed\x04\xcf o\xd6\xae\x9c\xc5\x94\xc5\x9e\xa5\x17LD\x1a_|\xfb+$J%9\x9d\xd9]\xa5\x15\xd4\x8fYj\x8c=\xd35\xac:5v\x063n1\x95 N\xa3\xa4\x9a\x93\xa1\xa1\xcb(\xa7_\xf7\xa5\xbc~\xe0\xc6\x0fC[2D@3\x8c_<\x84\x85\xc7C\xe5.\xfdk{[\x84\xc6ce\xf8\xe7\xf66\xe4\xc2\x12\xbd\xd5\n\x1d_\xca\xde\xea\x9c\x06\xbeY\xc4IIr\xb7\xf3-IN(\x11\x17\xa2\x17\n\xfb\x06\xc11z\x0d, \xd4\xe3\xa740d\x0b\x08\xa1\x88\x96d\x15\x06\xf0F\xbcb\xf1\x0d)>\xc8\x16PT\xd1\x12[(Z\xc4a\xe0\x18\x8e\xe3\x12C\x1b\xae\xd6qB\xe6o\x9a\x95\xab8\x0b\xeb\x88\x018>\xcc.\xf4\x0f^}i\x7f \xd6\xd3\xf8\x01E\xcco\xc3u\x17E\nB0\xc4n\x90\xd1\xae\x80>l\xb1\x8e\x8dZv|\xcf\xc3j\xdak\xf0`\x9b\xf6\n\x8b0I\xae\xc2\xe8s+V.}d\x89{\xfdA\x07\xce\x17O:cW\xf1b\x86\xd7\x94\xf9P\x8a\x9e\x9a2C\x0c\xc3vw\x14\x90\x97\x0c\x90\x13\x83Z\xea\x04J\x86\xf9J\x0e\xbd\x1b\xc6W\n\xaf\xa8k\xff@\x12\x0d\xab\xe7\xc55\x9e\x16\xcb\x99\x90/\xb7\xf8+\x0c~|\xf5\xfa\xc5\xcf?}\xaa\xe5b\xa1`\x19:N\x848\x0d\xea07\xf1\xb5\xef\xf2\x80G\x01\xa4\x18\x97\xb6\x8e\xb3\xb1AyF\x9f\xab\x9c\x84\x9f\xdb\xaf\xba\x9c\xe1K\xada\xbd\xab\xc9f]q}\xa8\xa5/\x19\xc8\xfc9\xcf\xd2k`\x9e\x81\x08AD\x97x~\xce\x194\xe1\xbbP\xb3v]F\x01\xcc^\x81\x02vN\x0c\xd6N\xceM \xf3\xe5\x0b\xc8\x0d\xc9\xefz\x80\xa7\xc0\xb3\xb2\x1bN\xa8\x01*\x0dn\x9e\xd7\x916\x05XDn\x88\x83\xc6\x02\xdc,\xa7\x802N\xaf\x13\xc2g\xc8Mq=\xca\xa0\x95a\x9c\n\x98\xab\xbcm\xf9\xec!wA\x1e=\x8dl\xd3i\xd4\x81B\xb59P\xb8i\x9b\x81\xf4\xae5~q\x8f\xc9-\x84\xae\x01o1\xf4id\x89\x05\x1c?\xd6\x1d\xd3\x14\x11\x83\xcc\xa4\xb1M\x1bj\xab\xf8\xdb \xcaP2Ho\x05\xc6\xe4\x81Om\x16\xe9\x83}\xf9j\xcdl\xe9C\xac\x83\xad^},s\xee\x16\x06\xa1\x9b\xb2\xaf\x9a\x0e\xce\x0b\x8a$\x8e\x88{\xe8\xc3\xce\xa4o(\xdd\x0e\xf5{\xbb\xff+\x1d\xea\x87-\xeb?\x80\xd5\xf9\xb7:\xf7\xfb&?U\xe6\xdf\x12\xa7\x8f\xa3\xec\xb3\x9eC:@/+\xb7=\\7+\xf5\xf1\xa3&F\x1d4z\xfaQ\xcf\xd8\x91\x86\xda\xb8a\xfcJj\x19\xc3\xc1\xc8\xb21\xac`\xeaO8\xdc\x0e\xeeR\x81\x9e]G\xe6C\x1e\xaf\xe22\xbe\x19\xbcL*\xa1i\x04\x1d\xf8\xc2p\xbdX\xfc\xc5\xf6\x05a\xe5\xed#\xaeS\xb2FPW-\x16x\xe9\xcb\xfaG]\xed\xc1\xab\xddaR\xf7\xe0\xd0\x0b\xd8{\xb3@es\x0b\x06\x03\xe9\x8e\x1b(9-s=\x80\x08\x06\xf6\x97\x17o\x7fz%\xc2\xae9u\x82\xaa\xb0\xc8d\xdb\xc3U\x98\x7f\xe6\xa6?\xf8\x93\xc7V;mb%\xd1\xfat\xcd\xdc\x8a\xa7`be\x1ef\xb0p\x9bF\xcex\x02\x8c\xba\xa4\xc6b,\xf7\xa4\xe3\xf9\xf5\x90\xd7e\x95\x93\xf32\x8c>\x7f\xcaCth\xb4\xbc\x11\x86\x9cK9\x01X\x86q\x88\xb1\xac\xa05\xd1EYXhy\xbc\x8c\x0eY\xb2\xf6\xaa\xff\xca;,\x9c\xd8 \xe4HZ\xb9\xd5\xf2&W_\x8a\xb9\x0e\xa3U\xea}\x1a\x81s\x0c\x8e\x91f!h%\xd1\xb7 >l1\x07\x9dz\x1f(\x85C\x9a|$\xa6\xed\xd0s\x0b\xca\x94\xd6\xa0\x84\n\xbd\xf6\x026\xf7\x1d\x96\xcdK]\x95Z\x08>K\xdd\xe9x\xeaiV\xf7B\x01\x8a\xef\xf7w'\xe8\x88\xbe\xbf\xdb\xaa\xd7\xc8\xcb\xb1\xde.\xaf\xb7\xc7\xff\xdd\xe7\xff\x1ex\x92\xc5\xcbc\xc5\x9dv/\xc66(S\xcc\xda\xdc lCip,\xd4\xcc\xd6\xdc\xa9\xa5\x9ed\x00\xe7\xeeY\xeap3;Mm\xa0\xdd\x85!ru\xcd\xc4.\x17\x82\xcf\xb8\xa3Q\n#\xc8\xbd\xe6\x00\xef\x1e<>\xae\xce\xe3\x03\xfapV\xea\x11a\x89$%\x8a\x1e\xc4\x84\x87\xf7oE\x1f\xcax\xb9\xce\xb0n\x10=\x99\x05\x8c\xfdg\xf4\xe4\xea\x9bDO6\xdd\x8f\xbfOPa\xd3H\xf0ZF$N,7v\x91dY\xde7:\xcb\xd0\xe2\xe2]\xf8\x0e\x15\xce#\x14#\x8c\xe1\x18\\\xa1\xc1\xc81OZ\xbfD\xc1.\xaa\xe9\x0f\x10\xdcw@\xd5\x10\xb4|\xd4\x9a @X+\x18\xad\xb7\xba\xcc\x13xs\xf5h\xac\xe6_R\xe5\xb2!\x05\xdb\xf27\xfa\x18D\xd7]\xa6\x0b\xad1\xf4\xe4Nh\x0f\xc3\x1a\x9b\xdf6\x92\xdd\xe1#Ah\xb0\xe1`\x14E\xaf\xfc\x0c\x90N\xd6\x9dw0\x0e\"\x9b\x00\xb1\xa6\x12\xd8\x04\x1f\x0e\xbb.qoB\x99\xded2\x8f\x0dTf\x8f\xaefQ\xdaO\xc6\xbd\xb7\xce\x02\x0d\x1e\x15\xd6\xae\x8f^l\x85\xfc\xe2\xf2Z}\xf0\x0c+\xb62\x06VbNm\x19m\xea>\x16\xbe\xdc\xf0\xa8:\xa1k\xa4\xd7\xb0\xed\xca\x87\xc2\xe7\x99\xf0\x0c\x95(\x1e\x8efcC\x00\xe9\x04\xdf\xe8&G\xd9\xb0\xcc{\x1d\x9a/2+.\xba4\x9fZu\x83q\x80\xcf\x8c\x12xv\xbf\x96\xc5(\"\xcf\x98\x07\x00S\x1c\x17|X y\xc0\xe41\xf2\xab\xc2\x87)\x93\xb5\x9eu\xe3BhF\x96\xd4\xf8\x90q\x80\xfa@\xa0/\x16\xa9\xb1\x1d}6}\xc7Xn\x98\x91U\xbf=\x18\x15\xd0\x8f\xbf\x04\xc3.\x9f\xa2\xeb5y\xf01\xedo\x13p\xfd# \xa3\x92\x07L\xff?\x0e\xcf\x84\xec\x9c\xc0M\\\xc4%,\xcbr}\xfc\xe4\xc9\"\x8c\xc8U\x96}\x0e\xae\xe3rY]\x05q\xf6$\xa7\xdf=\x99gQ\xf1\x04?\xde\x99\x93(\x9b\x93>\x81\x9c\x999\xe6\xa3\x91\xc7,\xd5\x9d\xed0\xbf.f\x17X\x8f\xa4\xb4\x89\x9f?\xbey\x99\xad\xd6YJRY\xaf\x96\xc3\x08&\xba\xf2\x8c\xb5\xa1\x06\x7f\x17\xa2\x89,\x1f\x1e9\xbe\x89\x1a_\xf4\x87\x8b?i]\xff\x18\xe4\x10\xee\xba\xaa\x8e\xc1\xf4\xb83\xfa\xba\x0fq;\xacz\xdcs\xea\x06\x9d\x1b\x89\x82\xb2q4\x8f`\xe5\xebb\xf1I\x87\xf7\xcc <\xac^\xb8?\xb4\xff\x12\xeb,\xb7&\xc1\xb78(\x97a\xf9\x11[+\x98\xd8E)z\x1d&\x05Z>\xba\x18H[y\xf7)\xaf\xf8\xab\xb1\xfe\x8a+\x17r\x11\xcfW\xfdn\x19w\x9a\x8f\x88\xb9)\xf9\xf6\xb46^\xf0\x03>\x04\xa5\x9a\xfdO\xe0\x94\x1f\x94\x8d6P\x94v(\xa5\x9e|\xbf\xa5n\xd7\xf7\xf0iI\xe0\x8a 7W\xd9\xbcJ\x08,\xf2l\x05i6'\xc1\xaf\x85__D\xee\xf4\x1ah\xdf\xeb\xcd\xfd[X\x95\xcb,\x07\x80\xd7$\xcf\x8a\x02^\\e\xd5\xe7e8\x8f\x7f%Kx\xb6\xc0\xc2\x7fc\xff\x04Y~\xfd\x1c\x9e \x88\xd4\x94\xb5\x1a\x15\xf6H\x8aA\x12{\xf9\xa4uu\xb9\x1c\xaa\xc5?CC\\\xb4\xb2\xe4A\x93X\x0f\xef\x94\xf2\xb2\xbe\x10\xed\x98+\xd0le\x11|\xfa\xcb\x87W?^\xbe\xf8\xf8\xf1\xc5_.\xcf\x7f\xfe\xf0\xe1\xfd\xc7Op\x06\xd3\xc9\xde\xd3\xbd\xc3\xdd\x83\xbd\xa7p\x0c\x93\xf1\xd3\xdd\xa7{\x93\xc3\xa9\x96\xef\xd6\xd2ah\xc5\x95\x94\xe2\xa4\xc3yF_7\x86\x17\x1f\xc3\xf4Z\xf0\xc9\x14(%\xf1\x1cI\xd190Os\x865:\xcc+l\xb3p\x85\xbd\xd3\xcfqZ\x1e\nCc/\xb8\xbcDl\x7fy\x89!,\x1a\xf9\xea\xb1b*\x82l7o\x00}\x9c\xe8a\xe7\x18\x8c\xe5\xb8\xd3\xa1\x85y=\n\x1b\xc5\x06\xc2\x88\xcb5O\x80\x07\xc4\x97\x95 \x85\x9an\xa0i\xba\xbd6H\xde\x1b\x14\x0d6\x12\x0b\xeb\xb7\x15\x10\xcaN\x89MZ0\x1c\xc9=\x9d\x8b\xda,\xb9\\\x12\xe6\x86\xb2\x88\xf3\xa2\xac\x11?\xac\xaa\x02\xedgB(Z\xd1j\xe5G\x10A\xf6x\x08\x0f\xb63\x105\x01i\x0cr\x1c\xcb\xd6Db\xfd,\x0c\xaae\x0d\x89\xd9l\xe8;!\xb5Q\xe7\xcdm\x87BnR\xdf\x91~\xda\x9c\x89\x16\xcf-W\xe5lo\x03\x91\xcf\x83\xfc\xae\x1dK\xbb\x83\xedFW\xbf\xe0\xea\xae$?\xe1\x89\xf6\xd1\x0co\x0c\x98\xeb\xba)\x86g\x8d4K\xbf\xaa\xdfe\x8bEA\xca\xef\xe8\x11\xc8*4G\xbf\xca\xaat^\xd8vW\xef\x936\x0e#p1\xf7\xf0\xd8\xb3\xf6\xc3\xee\xdc\xf0~0\x00A#cI\xa5\x00n\xa7<\xf0o\x0b(\xd4F.\xd6*x\x81\x8fM\xc5t\x99\xcd#\xe9\x04L\xa4\x0b\x10\xd1\nk\x06H;\xaf\x8a\xc1\xd0O\xd9\xfdc\x93R\xb1\xc5\xd8tx \x1a>\xc7\x05\xad\xf3\xc9\xdf\xdf3\xe7P\xa7*\x17\x87][\xbfU\x04q\xf1\x8a\xc3\x0d7\xb58`\x7f\xe7\x08\xd0\xe2H`\x83!\x056\x94\x1a\xf6\x98n\x12H\xf8t\x0c\xf70g\x1bg\xf6\xd7\x02\x8e\\]\x16T\xa8d\x86\x8e\xb7y\\\x12\xd7\x02U\xd9'u\x96\x02\x97\xf9\x042#\xfc\xb1\x0f\xb1\xf7\xe8\xed\xf2\xfaL\x1f\xc5C\xd7\xb2\xa8\x15\xba\x141uH\xb3j\xd5\x08\xdc\xc3\xd2%\xc2\xe7\xc9\x166c\x08\x906\x9a]Iu\x82\xb8\xf8SLX\xda\xfdv\xb1\xc9\"L\xaa%\x8f\xb4!0\xdb\xa3\xad\xa9\x99-\xd5R\x0e\x11\x1dK\x1caX\xe2\x9b:\xd9f\xd7*pj\xb3\x1eIW(\xc2\x1c\xc3\xfb\x9d\x9cx\xb5\xa2\xcf\x8a Q\xbd\xe5\x84E\x14\xc7\x8eY\xc9\xc5j$a\x19\xa7\x93\xce*Wq\x1a\xe6w\x96* )w\xcd\xe8\x845\x82d^W/U\xb9\xd8\xe9\xac\xc1\x08\xed\xdeQ\xfc\xec\x96\x9eu\xc1\xa1\xe9.*\xa6\xdd\xe3\x89\x8a\x9d\x9e\x1a\xe5br\x90\x90\xbe:;\x1d\x95\xa0\x19\xf7\x14\xbe\xef^\xc1%\xf9\xd2\xdfJ\n\xcf\x9f?\x07\x83?\x114\xdb\x19\x16\xe4`\xaf\xbf\xa9\x1f\xfa\x16\xb2\xd37\x1c\xa0v\x0c\x19\xba1\xc0\x990\x96\xac\x86Ph\xf6SvK\xf2\x97aA0\x03\x19F\xa1k}\xaa\xebR\xcd\xe0\xeb\xa6\x8bc\x11w\xab\x9c\x11\x03\xec\xe7F\x14\x14\xfd\xf9\x02 \xe6\x83:\xbd\x93\x98*\x8b\xfe\xb8\x01\x01eM1\xf2\x05\xdb1l\xa3E\xdc\x92R\xee\x10\x85\x81\xdc?\x0eyNx.K\xe4\xce\xf0\x8d\"\xa2\xa3\xd8}\xa7.9D\x90F+Ie\x1ekp\x94\xfa\xdcB\x82\x852\xc6j1G\xce\xa5\x1ccQ\x88\x04D\xa5\xfa\xe5\x08i\xfd\x94\"\xc0\xb2#\x88\x82\x98e\xdc\xb9\x0e\xc0C\xe0\xc8]\xb7OF\x13\xf6h\\\x99\xc2J\x91\x86}\xda\x99\xc01\\k'\xcarB\x8c\xc2'\xde0\x81m\xa4u|\x8b\x9c\xc1\x86t\x1b\xf1\x85d\x10\xcac\xee\xc0\x19\x1e\x86\xae*\x8d\xe5\x0f\xe7Z\x8d\x95\x93\xb0(\xdfX>\xc0\xb9c\x12%\xfb\xec\x8d\xbc\xcbM\x98\xd4\x84\xbd`WD\xa0\x8a\x9c\x93W\xadP\x14\xe6\x1b\xad\xaf\xbf\x05\x98d,5\x8b%\xbc_(\x1d\\s\x8dB\xa2\x82\xcd[,\xa5\x16`\"\x05\x86\xd1\x18\xffM!\x01'\x04s\x0d\x8c\"=\xc4\x91\x1b\x17Za\x01\xc7ej\xd1\x8eTf\x95\x17\xc4,*\x91\xa0\xd8\xa7L\x18\xd8\xfc\xee\xbdWt\xa5\xa6>\x84\xf0\x04\xff-\xf8\xbf)\xfek\xb8o\xad\"M0k\x1b(\x1f\x06\x0b\x17U\x89\x8c]\xc7<{\xee\xcfo\xd2rr\xf0\xc3+\x97\xc0\xf7r\xb6\x11\xf1\x98\xef\xb9\xd5&H85\xda&\x8d4\x1d\xaaaN \x83g\x10\x9e@6\x1a\x99\x992\xe0\x9d\xe1\xf42\x0f\xc7\x1fQ\xf0\xc1C_-8\x1c\xce`\x07\x16\x9dr\x1d\xd1R\xfd\xa1\x88\xd2\x9dy>\xfb\x1cF|\x81\x8az\xdf\x16tA\xacMr \xbb\xc3\xc2\xd7\xb2\x163\xd89\xe5\xa3\xf1\xf9*X\x80\xb3}mR\x18A\x01\xcf!\xac1I\x08;P\xe08\xf9\xaa=Gf.\xdb\xd9\xe9\x9arM<'<\x88\xed\x9a\xf1\x80kx\x06\xc5 \xac\xbb\x16\x1d\x94\x85\x87\x11\xac=\x16\xa4\x97.\xfe\xbaw\xa5\x81\x9b\xc0\x98\xfc\xbb\xf5\x07\xe3\xeft\xd62\xcbq\x80\x0f1\xa9\xb7+3\xd6\xb3j@vt7k3\xe0[\xf5h\x07\xe8\x061o1J!\xdc\xdf\x9b\xf8\x18\xa1\x04\x97\x90\xb6\x81\xe2\xcd\x05-\xc3\x9b\xa3\x90\xe79\xc4x\x0chqLq\x01\xfea\xee!\xeb\x85\x9d\x19\xfc+L)/7\xb68r\x0bu\xe2\x92|\xe9P=\xe5\xf0\x1c2x\x02\xd3zh\xf8\xabK\xfeP\xb1\xb3W\xb1h\x87\xa3Q\xd5\x05>(\x9aX\x87yA\xde\xa4\xa5K\x82\xa2\xba*\xca\xdc\xa5|B\xe5\xc3\xd4\xf3ar\xd0!7g\xd4\x9a$(\xac\xccu\xcb\x19\xbdi\x98\x8a&\x1c\x00\xf4Dc\x83\x0e\xcde\xcf\xa1\xe1\x8d\xfd\xd5\xfd\x19s\nK\xc7\xc2C\x95\\\xdb\xa0\xd3\xd6\xd3\xd5\xd0\x9e\xec\x06\x03u\x9b\xb2\x11\xd2\xecB 8Q\xb3\xf2L\"\xc6\xb3\xed3\xc1Q\x19D<\xe4\xc4\x8b\xd2M{$\xfam\xc0\xf7\xc0dy\x9bL\xfav\xd8\xa4\x95\xb5\x19\xd4\xf0\x97a\x0d\xff\xd5\xfda\xf3A\x9f\x0fm{\x90VC\x0e\xec\xc0\x83\x93\xf2]\x93\xaeZ}\xb0\xb6\xb7a\xcbu \xc5NS\x0f9\x02~ \x19+!\xed_\xc5\xf9M\xcaO\xc3!\xcb\x84\x93R\xb0\xb1\x7f\xe0C\xc6\xb6=\xf6\xea?m\x9a<+H~\xf8\xda\x03\xff\xaa\x8b\x9fUY\x08\xf4\xe9TXL\xf4\xd5\xa7<\xc8\x0fw%\x91<\xa2[\x85\\E\x85\xfd\x0c\x1b\xd7\x8b\xaeq\xa5RL\xa1\x9af\x1c \xb2\xc5\x10\xf3\x18\x83\x1ab\x14\xddv\x81\xcd\x8c\x85\xf8\xf0E~\x93r\x16\x1bLS\xc5\x83N$\xc6L\x89\xe2A#V\xcaJ\xef\x1e\xc1\x19\xec\xc11\xfb5\xdd\x853\xd8\xe5\xbf&G\x138\x83)\x1c\xdbD/\x08\x91a\x04 \xad\x87[|\x83\xe1Z\x8c\xf8\xc5#\x8f\x8f\x81\x05\xf6kz\xe1kS\xc9p\xf4jY%\xcdh\xb2_\xcfh2\x85{p\xc5\x9c\xe4)Vt\x8a\xd3\xf1\xdeS\xfe\xdd3\xd8\xdf\x9f\x1e\x1dP\x92\x88\x92\xb3\xfbOw\xf7v\xbdo:\xff\xbd\xc7\xcf?\xac\x7f\xedn\xb0\x1ajYhY\xa1Cm\x85\xa4%\xab\xd4%\x0b\xe9\x92\x1d\xec\xef\xef\xee\x03\x06\xf4x\x06\x93\xc9do2\x99J\xcbd\x9c\xa2\x99$\xae\x8d\xb1(_\x84\x9f\xd3\xb6w}\xbc\xc9\x18tl!\xf7\xe7.(>\xa0?\x0f|\x11\xb5x\xc1\xc4\xa8c\xd8\x86\xc9x\xba\x0b\xf7l\x1397\xb3\x7f\xb0;\x1d\xc3={\xb5\xcd\x0c\xc2\xf9w\x1e\x05T\xa3SH\xda\x10\xdf\x06\xa5\xfb)\x12A\x8c\xd8\x15 \x14\xe3\x14\xbc\xbc\xafI>C8,\xee1\xc2\x13\x85\x1b\xf5\x16 \xe9.\x1c\xc7\x0e\x18s\xb32\x10\x04\xf4\x16\x06\xd3\xdcXz\xc0`8\xba\xc9}\xa6\x9a{\xdfCD\xa5\xedEv[\xe8S\xfeE\x82\xda\xb7\xbd\xf0\x81\x04\xe7Iv[\x97t\xef\xc3\xa8l\"\xab`,\xdc.\xbbBT\xdd\xb9#S\xa0\x837\xef\xce?\xbcz\xf9\xe9\xf2\xed\x8b\xff\xef\xf2\x87\xbf|zuN\xcf\xd3\xd8&\x8b;U\x93)\x9b\xcd\x82\xcc\xe5=\xb1\x13\xed\xf9\x8cn\xa4\x88o\x92\xc9\x92\x9e=G<\xb5\x02M\xb6J\xb2\xe3\xb4\xba\x96Y\x00\xd8\x81\xa8\xb3l@8H\xf1\xf0Q\xed\xb5\xe5G\xe21\xc3\x8e\x07\x1f\xf6\xa6\x9cVZd\x99\xebY\xc5\xa1%e\xc8\x98\xa5\xe9\xf6\xb6p\xeb\xad\xcb\xdc\x89\x0f\x13OR*\xb6\x8fjg\x0c4h\xe6\xb0e\x90\x9d\xa8\xe7\xca\xf5\xe8\xc9\xfa\xfc6\xfc\xc2-\xe4P\xc5L\xcf\xd4:\xcb\x92\xf3\xf8o\x14x\x1cN\x8e\xa6\xb4\xe82\xac\xae{M\xb6\xc1\xb6\xb1\x85\xe2\x0c\xa3\x1fo&\xd8\x1e\xe0u$\xb5\x1f5\xe9\x05\x0d\x16\x98\x1dBjW\x1a\x8b2F\xe3\xb9\xa237\xd6\xf1-\xf6\x93<\x9c\xcc\xf66\xff+@{U\xc2\xf3\xb8\xa9e\x17LbF_\x99\xc3\x9c\x16\xbe\xd6\x8a)\xe0)wh7S\xa3\x9d _\x1e\x98\x1a\x01\xc1\xcef\xab\xbf\x81\xed\xa7\xf8\x02Y>D4ca\xd6$\x1bB2\xf3\xbe3\x93\x05`\xde\xd4\x0f\x161\x0b\xea\x86\xc6\x86j\xa1Tb\x00\xf0}\xa7\x05\x17\xe1\xe7\xb4\x08\x17\x83\xe3\xafX2\xb5\xe9\xcdQl\xf1-\x9a\x94\"\xac\x0cjk\xcbmb\xa1\xdd\xdf\xc3V\x19\\\x8a&\x0c\xadG\xd9j\x1d\xe6\xa4\xcf!\x1bd\xf3\xca\xdar\x03\xdb\xd7\xf4QF \xd9\x8b:\xba\xb7P\xac\xb0/\x8c\xb6&\xcc\xf0Eu\\\xee2s\x90\x15{\x8c\x0d'\xf5\xaf\x98\xc5\xa1\xcfdN\x92\x99\xd2\"k\x98Q\x86\xde\xe2t\x8b\xc3\x98\xc5\x17xD\xc9,\xbe\xe8B\"\xa9\xe0\x1cY\xff\xad\x0c$\xf2c\x97\xddZ\x89>\xccw\"\x94zh\x8e\x04g0Q\xe2\xe1Bs^\x84\xf9k\xef\x89\x11l%W\xfe\x94-\xe5\x8fy\xc2}\x06\x06\xdf\xca\x84\xe3\xbf\xc1\x1ee\x80\x8d\xc3?\xa8\x01\x88) )\x0c1\xb3\x18L'\xf8u\xe6\xd5\xc1\xd0!\xb3\xa6\xbc\xfa\xceI\xe2\xa24\x99N\xf2\xe0{\x90-\x04P\xb0YQZ\x0c\x1f\x04\x01m\xa2\xb1\x11>\x98[S\x02$\x18W\x0b!\x0ca\x10\xa4C\xaa\x8b!\x89f\xe9\x85\x95\xdd\x12r)\x05=P\xbch\x86;f>IO\x1d\xa5\x8d\xc2N\x9cW\xdc\x18\xc5\xce\x06\xca \xbc\xfa\x9d\xf6\x8f>\x153\xe6FM8g|E\xf4\xd6\x9e\xb3\x08\xcd\xb9mEg+dg\x8fS\x98\xfb\xa0Pz\x12\xfa\xdc\x1a\xab\xef\x8a\xdbp=9\xe8\xf3\x0c\x17\x0c\x0e\xc6\x8c\xea\xd2\x13\x95F=\x91l\xae\xc9GRP\x12\xbb1\x1d^UI\x19\xaf\x13BWpr\xb0s\x15\x97F\xb4\xa8(\x1a\xc6'h\xbe[\x9e\xb0\xe37\xf5\xe0\x86\xbb&\x11Jm\x8dZ\xd9KA\"\xd1e\x17M\x10\x8b\xa8.\xcb\xee\xf4\x9b.\xcb\xdeW.\xcb\xee\xf4Q\xcb\xb2\xd7Z\x96]\xcfo\x8a\xe82\xb1\x7fLZ\xb8\x0dV\xeb`\xef\x9b\xae\xd6\xe1W\xae\xd6\xc1\xde\xa3V\xeb\xb0\xb5ZO\xcd\xabu\xa0\x15O\xd9?\xfbZ\xf1.\xfbg\xef\xf1kk\x8a\x1f\xd7\xb5\xbah\x9e\xdc\xb5\xc2\x8a\xa6\xa3\x8e\xaa\xc5~\xb6\x02\x08\x9c\xc1\x0b>\x9b1\xa5\xcc\x07\x84\x87\x92\xc7\x93wh\xf2\xe9F+\xf8\x07\x8d`\x98\xcd\x99\xb0\xfa\x1a#\xdb\xf4\\\x9eO\xe3Q\xe2\x0ck\x17\xfd\xa6R\xbd\x91\xda\xd4N*D3<\x8a7\xcda\xb69Y\xc1\x10j\x15\x06Q\xac\xe2\xe1\x9d\xbf\xd8\xa4\xf3.:W<\xbc\xdd_7i\xb7\x93:\x86a\x14\xb2xx\xff\x9f7\xe9\xbf\xd7v\x18\x9a\x86_m\xd2p\x075\x0e\x83(r\x18H\x95\xc3&\x9494\xb3y;l6\xbd\xc4:4v\xd1F\xc6\xfag\x1e\xf9Rx+\x1e\x83\xcd\xbd@~J\xe6\x8e8\x02\xc7\x19j6\x0dF\x9a\xec\x81\x8b\xe4\xd9dmA\xa5T\xa0N\xfeZ\x85Iw`\x170J\x1bzd\x0b\x122\x146\x9a\x9d\x88\x87\xe3\x80\xfb{\x0e,kY\x88\xd9/\\\x9bE\x9c\x16k-xr\x17f\xb2)F\x98\xffRK\xca\xdf9p\x81\x9f\x9es\xb3\xe9\x9a\xae\xa8\xddy\x10Fr\x7f\xc9`\x15\x96\xd1\xd2}\x12\xfc6}xr-2l\x80#\"\xe3\xd6\x8d\xf1\x10\x80,\xc8L\x10\x04\xe0x\x9e\x0f\xce3No\xd4\xe1r\x9e;]\xebb\x91'\xf5\x1a\xb5\x7f\xfb\xad\xd6y<\x05\xb3\xea\x9e\xdb\x0c!\xa2v\x84/\xc8\xb1^/\xaf\xed\xb6\xb4\x17\xcc\xd6,naT\"|\xdd\x11\x03\x8bv\xef\xefQ\x80\x83/b\x1d5\x9b)>\xee\x8f\x9e\xd3\"@\xfbh\xdb|sx\xce\xc7C\xe8_\x9dnBM\xfd^\x17\x02\xad1{-\xa4\x03|H\xeb\xbf\xf2\xfa\xaf\xb8\xfe\xab\xb9|\x83\xc4{\x19\xba\x0e\xec\xd0\xd3\x83!\xcd`\x87\x1e\xa7P\x96\xe8e>T\x1e7\xdf\xc0\x00\xc8B/\x18s\x15\xacb\x99\xc24\xbb\xe3\x13H\x98!\xedh\x94\xd8%\x80\xd1,a\x12\xc0\xc5,\xe9\x94\x00f\x18\xbc,\xe1:sZ\xdb\x0e\x83\x1f!\x01\xcc\xe0\x19\x1a!\xa3\x04\xb0\x82g\x90\xd9%\x802\x94\xc2(\xc2C\"\xbbI}q\xe3\\\\J\x91%\xd7.Ao[\xf7o\xd4\xd9\x9d\x1aR\x03\x03\xaavu\"\x99\xfc\x7fmG\x93\xce\x8e\xd0C\xdf\x0c\xc7l@L\x8b\xb9Y\x93\xb8L|$\xddt\x9f\xf3_\xadVj\x0f\x14\x1d@\x99\x83\xa6\xe4,J\xf9F\xad\x9b\x8f0\xc2\xe0\xb8x\x1d\xa7\x18\x97\xc03\x04d\xe1\xae\x92,r\x81p\x8c\x10\x84\x87\x0f,P\xc7\xcc\xe7\x91t.<\x16\xc9\x11\x92,\xbd\xa6\xfc\xaa\x88Fk\x0f\xa8q\xcf\x00\x85\x18D\xea\xc1\x19\x05\xcc\xac\xd8\x08\x899\x07Ay3\xd9\x9f\x89\xd5\x1db\x94_\xdb\x18K\xa8pGO\xea\n]\xacU,98\xc9\xc1{\x9e\xd7NM\"\xe2 \xe3\xef\xf0\xafA`_r\xeeeg1\xab\xca\"\x9e\xd7A\xa9\xec\xf1I\xf2:\xae\x805^\x86\x02^U'Q\xabJo\x08\xff\xc5/\xdbJ\x0b\x94c\xde\xf2^\xd6k\x18\xdb\xc5\xfb\xbc\xdc\xa0\xcf>\x8e\x8b7y\xb5A\x93_\xab\x8a\x80\xa6\xdb\xdb\x0d\xba\xed\xe5\xb1x\x9b_6h\xf3\x1fN\xd9q>h\xf0\xbd\xdc\x14Z\xf3o\xc4I\xd9,u\x01\x98A\x13s>\xd5\xbd\xa6\x98\xc2\xb1\xdf\xf9T\x97v\xfd\xdf\xf3\xf7\xef\xfa8\n\xbe\"\xe6\x1bJ\xdb9\x06\x11\x0c\xc4\xccr\xcc\xc32<\x06\xdd\x93\x0e\xe9\xa3&oFp\x19\xe6\xb9\x88\x0d\xe6\xf7\xc3R-\xf8*\x05,\xef\xe1\x14\xf6\xc6G\x07\xb6\x90q\xbfv\xe1l!A3I\x92\x1ec\x16\xac\x98\x03\xa3\xce\x97\xd9\x8c\x992@\xa2\xc1)js\xed\x0c\xe40\x87\xde\xcf\xff\xa8S\xfc\x16\x93{3drv\x1bDw\xcb&\xf5t\xb78r\x95\xd8\xa7\xbc\xc1\xb2\xa6+\xa9,\x82\xe3\xb0\xfbG\x98\xab\x1c.F\xe61}\xd3k\xb7\x9ce\x1dS\x8f\x07M\xfdm\xd7\xd4\x15St\x8d\xf1\x90\x877f\xc3\xcbk=^\xc659\xb1m\xd7\xf2Yv\x01#\x98\xee\x1f\xc0\xf7\x90\xcf2S\x90X\xd8t.\x9f\xba\xe6\"4\x12\x13\xd4H\xb0\xd8\x18\xf6H6\x0e#\x01E\x04\xef*NK\xbb}\xc7\x08\xc9 k\xdc\xb7O\xf9]\x9c^c`\x13Lj\x00W\xe4.K\xe7\x82\xf6ak6\xd0\x0b\xf7\xa5*\x82@\xa7\xc8\xc7K!\xbes\xd8\x18\x8ca\x80\xb8\xb0D\xc4\x0f\xb1i\xb2 \xba\xa8\xf1\xe3\x9fY\x03\x03\xe9\x91\xfe\xf4\xd8t\xb6\xe615\x88$t\xb0\xc7\xc1\x9c\x93/ \x8b\x17\x06\xae\xe8\x87\x1ef\x88\xd4>\xfd\x84\xdbS\xef\xe3\x86\x9b\xf5\x92\xca\xed\xd5\xadud\xaf\x17\x1f\xa6\xaa\xe1\x0ewG\x8b/\x00\xf5\x10\xdb\x18\x94\xe7\xd938\x84\xef)\xfd{\x061\x1c\xc3\x04v \xf6<\xb4\xd16\xbc\x184\xe1\x8f\x1bMxoz\xb4wt\xf0tz\xf4\x8df\xbdg\x9f5iOk\x17\xa7\xc5\x16c\xd0\xe4\xde\x0d\xbe\x1f_s\xb0lG\xb5\x03\x9e<\xfa|\xfe\xa4\xcc\xc88\x9dZ\xaer\x7f\xcf\x16`\xec\xb3\xa5\xf6!\xe6<\xae\xdc\xc6t\x97\xbd\xa3+\xb07h\x0c?>z\x0c\x87\x961\xecO\xd9;:\x86Cm\x0c\xf2\xafB\xa7\xeb\x86\xd8\xef\x08\xaf\xb8aJ\xeaS\xf8\xaf\xff*}=\x08&\xe1\xb9O\xfe\xeb\xbf\x88\xcf0\x05\x0bC9\xa2X\xbb\xbe!\xa5\x888RR\xc4^\x17\xe5^\x13\x92\x8c\xe5\xea\x92\xbe!\xe2\x1bR\x7fC\xa4o\xca\xba\x04\x93\x1d\x1b\x03\x985:\xcf\xda\xea\x1a\xd7\xc2\x1a s#\xf9IM\x81\xc1\x8e\x9eeE3\x86\x11\xec\xec\x101\xef\x13<\xda\xe3\x9e\xe9\xd2\x0f\xbe~\xc2\x87C\x00\x02o\x90\xd4s\x9c\xf8\x9a\x82\x83o\xdc\x90\x1e'\x07\xedc5\xa8\xd3\xa9\xa5Sn\xe9\x81\x8b2\xb9@\x9c?l\x1c\xed\xcd\xfe\xbaq \xb5\xa1\x0cf\xc88v\xa7\x8f\\\x8f=}\x1c\xae}A\xe4\xa2)\x16\xb18\x7f\x93\x83\xa7O\x9fN'\x94\x8b\xa8\xdf\xef\x0e\x1c\xf6#\x97\xaf5\xec\xd6\x18.D\xe2Li\x06\x93\x83\xf6\x14\x94Y\xed^t\x8a\xf0\xe9\xb0\xff\xd7A4x~\xca?\x9fL\x0f=.\n\xdf\xe1\xb4\xe3:\xbbu)\x95\x00\xdf\x03\x06\xf3\xec\x05\x07\x7f\x0f\xf0G\x94\x85\x91`[~q\x82\xe4e\x1b\nf\x1a\x14\xcc\xbb\x17)3,Rf]\xa4l\xc0\"}#\x90\x89\xbe\xd7\xf5\x89Gu\xde\xf7\x80\x11!v\xa4{0\x11\xa9\\\x07@\xd7\x0d\x80\xab\x15\x9a\xb5\xd7\xf1F\xf8UX\x81\x8bu\xedw\xa7O\x0f\xe8$S8c\x8c\xd0x\xf2\xf4`\x0c\xf7\x90\xc2q?\x05\xb2\x01\x8c~\xf4t\xd8$\xee\x15\x10\xfe\xfbM\xe7\xdb\x81\xfa\xcd \xbd\n'i\xd9to\xd0p\x87\xad\xfe\xf0\xe1b\xcf\xedA\x0f\x00\xee}\xc3}\x9dd\xa1\x01\xba?n\xb816\xd9(\x1a\xb6\xc6\x82\xeb\x1b4\x8co\xb5j\xadaL\x86\x0e\xe3\xc7\xac\xbaJ\xc8#\x97\xe3\xb0w\x1cc\xc1\x80\x0e\x1b\xc7#\xd7\xa3\x7f\x1c\x93!\xe3@\xe6\xd9\xca\xcdX\x848<\x9d\xa7\x82\xe0\x98\x15\x0b\xaam_\xea\x06\x04:2I=\x96t\xcc\xe6\x88\x12\xdbc\xfce\x1dN\x1fx!H\x13r\xba\x14\x94D\xdaB\x93\xac*#\"N\xa1\x84'\x1039\x90\x15\xbc\xd1\xca\x9dP\xac^I#\x99\xf0w\\\xc9\x14\xabXW\xd3`\xa4$\xad\xa6\x10\x9f\xd5+\xba\xb3\x13c\x808N*\x18\x964\x16K\x9a}\xb3%m\x11\x15\xdd\x16,\x86E\xd5\xd7\x92\x02\x8b\xfd}\x1f\xf5(\xd6|?\xb8;M\x06\\\xb7\xf4\x04\xb4\x96O\x197\xf9\x1f4\x11\x13\x05\xf2\xd5s\x99\xfaLr\xdc5\x9b3\xc3\xf5\xf0\x9b=\x9b\xb0=C\x11)\xa5\xa9>(\x1dl1\x1b\xfb\x91\x166\xd2>\xc9\xc1\x94\xf2\xef8I>\x1b}\x92|\xee\x86IN6\x9a\xa4\x89Z\xf9\xeaI\xee\xf9\x92H|\xd0L\x19\xcd\"f;\xdd\x93\xa6;m\xca'\x07\x96\xbd6\x1cg\xba2\x1f\xcd\xdb\xdfI\x16I+\xf3;l\xff\xe6+cY\x95\x89eU\xa6\xe63\xb3\xdb\xbd2\x93\xc1+\xb3!\x8a\x15\xd2cyY\xb6\xac\x06G\x02\xd4\xb7\xd0\x03\x86\x8e6\xcbN[\xb8%f\xa8d\xc7\xe0\xe6m\xb6\x07C\\lF,=Qz\x1f\x89\xc1+\x19\xdd\x08\x917wJb\x7f\nsL\x86\xdb\xe9\x84.\xf0\xcb\x10C\x14\xf9\x1a\xdew)\x96\xaa\xe0\xf9s\x18S<\x1a~\x13|\xb5!\x05\xf0?e\xa3;\xa8\x88\xaf\xdal\xb1\x17\x12\x81\x915\x04\xc6\xc6;>\xfa\xfb\xec\xf8\xefB\xa0L\xa6O}\xd8\x99L\x0f7\xa7Q\x14\x1d\x12]Z\xe6\x930\xf9\x1a\xfa\xe5w$_v\xa7O\x0f\xe8\\Q\x860\x0c\xb4\xff\x8e4\xcc\xefH\xc2\x04_K{0`\xca\xdd{;\x80\xc4QH\xa2\xaf\"h~Gz\xc6\xbeD\xea\xf5U\x8c$\xc4-\x1e\xb0\x8a\xff@\xc4\x8fE\xfe\xd4\xbd\x8a?i{\xd6\xe7U\xd1\xf4\xb4\xe9~i=M\x06\xf5d\x93\"uw\xf5\xe3c&e\x13\x14m\xd4U\xef\xac\xa2l}\xb7\x19\xdd\xd2\xa4\x9b\x1c\xa3Cd\xed\"\xd8\xd8\xd5\x97\x9a\xa7\x97\x94\xa5\xa41E\x90+\xd0\x0fI\xdd\"Wq\xe45 \x88\xce\x0b\xcc\xfb\xb2/\xbdS\xdc\x8a\x84\xd2\x0cP\x1eVO\x13\xa4\xcb\xf0\xa6\x0c\xf3kR\x9e\x97a^\xf6gC\xad\xcdx\x80\x19kj\xc30\xf7PdU\x1e\x91\x0dz\xc8\xbb\xc6\xcbZ{\x95\xce\xfb\xdb\xcaU\xe7\x8bz\xf5\xd5\x1d\x95\xec\xaf\x08\xc6^\xda\x916Jy92Z\xe5\"A\xcb\xf4[\xb99n=\x12\xc8\x8d\x1b*\x06]\xe6\xcaA\xec\xb1#$M\x0c,]\xc2\xe4\x04b\x9e\xd5`g\x07\xcd\xc2b\x18\x01\x03\x92\x14\xd6\xd1_\xa6\xb8/\xb5\x93\x11eA&d\x17X\x18\xaf\xcd\xb2\xfe\xb105\x9aY\xda\x06\xfd\x1b\xf3\xb9\x14\xa4\xac\xf3\xb8\x94\x8a\xa9N\xca\xcc\x9e2\xcf\x9c\x0bS\xe8\xfd\xba\x00\xc1\"\xc6\xf4\xf6\x1b\x00\x02\x83\xd3\xd5\xc6\x99\xadEz\x02\x0c\xa9\xc1\xd1\xa6vC\x8c\xe9s%\xb8\xd0\xfe\xc4\xe7Y7\xfa2#\x81\xec\xe2$\x07,\xb7Y\x1e\xd1\x87n\xe9t\xff\xa0F\xd4\x96\xf8h\xf6|\xabz\xb2\x19C><\x9b?{\x9d\xf1{h2o\xcb\xb2c\xbfj.\xe0\xdc\xe6Ul\xf3\xfch\xf5\xc7s\x97\x98\xf2\x9d\xf3\xc5b\xa9\x92\xacF\xbf\x1cF\xca\xe0\xe7\x19\xc3\x0dj\x91\xd5*\xfa\xfd`O`\x0c\xe7\xd1\xc4\xcf\xa3\xed\x9b\xa1Tf\x1bl\xe3\xcc\xab%\xba>SF{\xcc\x93\xc8\x8d}h\"{P,gL\x0bo\x87'\x06\x8b}\x04\"L\x93a\x01\"viB\x85\xb6|r\xacB\x96Q\xf8g7\x15)\xeds)\x01\xa6\xd7\x91\xbc\x99\xb2\xdc\"N\x95\xf9\x10\xd6\x13\xe0\xb6z\xe8\xa3\xacLB\xc0\xc5j\x96\xc1\xbfB\xb8\x81\xcd^\xd9\x8a\x91\xa3\x8e\x81N\xf6op\nOf\xff9\xfa\xe5\xc9x\xe7\xe8\xc5\xce\xff\x0bw\xfe\xb6sy\xf1\xe4\xda\xe6z\xf3\xba;\x84+\xa0r\xf6\x0c\x9c1:\xfd\xabiB\x8f\xb5\x02ul\x96\x0e\x7f\xb6*\x00o\xcc\x01\xda\x08\xf0\xa88\x13x\xd2\x9b\xe3\xb2q\x90\x89Ex~S^\x87\xee\x14*1\x0bl\xd3J\xec\xe0\xc1s\x8c\xe6\xbd/P\xf4\xfe\xd3\xdd\xbd\xbd.\x80\x1b\xf3\xfcp\xf6\x1aP_\xd2\xe7\xb0\x7f\xb0;9\xea\xabL\x1f\x96\x88b\x97\x8eggB\x07\xc3\x93ILw\x8f|\x98\x1cM|\x98\x1c\x1eu\x80u\xf1DYZ\xc6ie\xce\xa5$\x1e{\xf6 \xe0c\xaf@\xa4~\xb2J\xf5\xe4\xe7\x1fi\xf4\x98\x10\xaa\xb3Jo/\xdd\xd9\x95\xf0\x98\x1c\xecN\xad)\x04\xc53lU\xfc\xdfy\xc8)\xf7\xd18\x80\x11\xa5\xebvx\n\x82g\xcf`\xc2\x0c]v\xf8l\x8c-\x88\xb4\x89\x9c\xef\x190\x1f;&o\xeeo\xca\x12U\xf4\xdd3\xd6\xe1\x84eg\xe9K\x7f\xc0\x07\x93v\xcf\x83\xef\xdft\xbc7\xb0\xf7\xe9f\xbd\xc3\xf3\xe7\x98\xcb\x00\x03lcB\x83\x94\xfe\x9a\x1e\x0e\x1a\x16\xee\xd3\xb0q\xedn>.L\xba0\x9d\xee\xb1\x10\x1ep\x00\xdbt\x848\xba\x0d\xc6\xda\x03\x1aq\x1e(\x14!\x92\xb4&V\xd2\xdar\xf6\x99p\x86\x19X(i+\x93\xab\xfbu\xd6\x7fy\x8cw\xa6\xe3t'\x13>\xb5\x07\xbfS\xb8&h\xa8\xd4}\xea\x05,\xe8|\xd3q\x19\x90/\xeb,/\x8b:\x85\xf1\xe0\xd6\xf6\x0e5\x8a:f\xc5GZ1\xa5\xd3\x9cY\x86a\xf0y\xd0\xfb\x0b\xc7<\x02\xfb\x89\x15'\xa7\xc0\xefU\xc6\x8c\xae6\xfdb{\x1b\x90\x0d8=\x95\xee\xdd\xc3f\x93\xda\xdd\xf5\\\x16\xb1\xdf\x07'\xcaIX*~m_\xb1\\\xbbOw\x8d\xeb\xb5\xfbt\xcf\xb0`\xb4|_+\xafx\xf9\x81V\x1e\xf2\xf2\xa7\x9e\xc4\x0d\xd4\x07\xbbh/\xe6\x0d\x8f\x0e\xbac\xd0}\xa6\x1c?\x03\x0f\x9f)\xa7sV\xcfk\xad\n\x0d\xa2\x84\x84\xb9\x8b\x87\x9cX\xb3q\xddt\xa7\xd4FQ\x10)\xdd|6\xbe\xf0!\x9fMt\xbb\xff?\xb4\xffRd\xc0t\x0ctWT\x89\xd0\x9c$\x04c\xfc\xc4j\xf95\xa1\x102S\x0b\x97!\xdd\xd7J-,\xb0f\xe8+{_l\xb6\xf7O\xf7,gH\xf9\\_5c\xf8\xfb\x13HwvN\xda\xf0\x17\x05\xa8n9K/p\x01\xa5\xbc\xd1\x1aU\xc9K\xa5,\x9f\xe6+\"\x8ff\xf0\x90\x1b5\x92\x88y\xdad\xc9!\xf4/\xf2\xe8\x8b\xf9\xf4\xe81k\xd8,\xdf\xe5\xe5<,\xc3\xcbK\xe3j\xe4.\xf1\xe0\x0c\xd2\x99E\xbeW\x17\x1f\x83\xb3\x0c\x8b\xa5s\x01\xc7\x90\x06\xabp\xfd\xd8\xf9\xec\x8d-\xe0s\xa2_{\x06\x0e\xf0v\x8b\xa2\x8d`f\xc6D#9\xcb\xe8G!\xe5c\xc7<\xb1\x80\xb0\xc9d\xf7\xb1\x83CP#NH\xec6\xd2N\x8aY\xf3\xaf\x18\xeb\xd3\xb1a\xa8\x9a\xa8a\xd8Hmbbz\xbaY\x0c\x01q\xea\xdbb\x1bT\x12a\x14N\xe3\xb1s\xc6\xd8\"\xaa\x04\xe8\xd8\xe8\xbd\x81\x9d\x98\x1e\xb8\x9d1=l\x1b^\x17\xa7*XB\xf3\xa8\x94:lh\xc6\xd6\xf5\xd8\"\xc1\x0d\xc9\x0b\x8a'j\x0dS]TG\x86sn\xc6\x81\xe3u\xd7\x98\xd0\x1a\xb5]\x8b\xb9\xc6!\xads\xa6,{\x1bO\xa4\xe4K\xf9)\x8e>\xab\xb1\x98;bK\x82\xd8#Q_\x96B\x97\xb6\x08\x0f\x94\x8e\xba\n\xa3\xcf\xc6\x18\x0f\xa2%[\x98\xfb\x9b&\xab$\xb4\xc3J\x9b\xbf\x11\xb1\xb7\xc2.b\x1c\xa3&\x8d{\x02\xd5\xf6$\x80\x14\x16@\x81XI\xb7+X,\xb6\xd8\x93\xdf\xb1\xddb\xbd5}\xe2\x0f\xc0k\x86D+\xe7\xfa\xcd\xac\x83x\x1e\xfa\x86\xda\x93\xdb\xf1\x9b\x0e\xb5\x95{U\x7fzG\xdb\x93\x89\xf1[\x8f\xd6\xb7ir\xc4\xd35\xe0\xde\xd8Z \xcb\xc1\xe9}b\x1ci\x88\x16|\x8a\x1c6\x137\xc1\x83lV\x8dF\x17\xf2-\x99U\x1dq3\xe1[\xac\n\x8bX\xcc\xa5\xc4}\x0bb|\xdd\xc7\xe2? U\xdc\x801 N\xcb,\xda\xee\xde\xa6,\xda\x81\x89*\xc8y\x96B\x13y\x9f\xf5\x91\x8eqJ\x81 \x99q\xae3m\x14\x13\x0f\x86\xe6*\x9by\x86\xe0L\xeb\xf7R3\xe2\xaf\x98e{\xa3\x98\x9c\xa7\x1ek\xfe\xe4 \xb8\xf4\x02L\xa1\xa5\xa2\x84\x1c\x8e\xc1\xcd\xdc\x9cN\xcb\x9734V\x9e\x0f\x99\x1b\xb3H\xb0\xd5\xd0\xccr\x88\x1aL\x8a\xaa!\x01\x88\xd3\x8cc\x04\xde\x80gD\xe3\xa6E\xa1#\x1c\x9a~M\x19b/\xee2\xc5H6\x0fO\x1c\xab\xb8\x85\x01\xf8\xc0%5.1ghKYf\xe8\x98\x9fh\x9e\x13\x1a\x7fJ\x7f\x8f\x15?\xe4f\xee\x03\xb2\xae\xfd^so\xb6\xc6\xb4)\x03\xf3\xb7\xfd\xce\x83\xcb\xa5|\xa3\x1b\x93\xbafZO\xbeH\xa9\xbbwp\xe4\xb9\xce\"\xcb_\x85\x91\x08\xa5\xf5\xa8f%\x1e\xe0H\x17?p\x1e\xe0H\xe7\x0d2\xce\x1b\xe8\x10\x8d\x891\xf6\x9e\x1eJ\x8b\xe2n\xc6\xd0\xf9\x94\xfa\xe2 \xbd\x8d+\xdb\xca\xf4\xf1\x0c\xa6\x94~5\xd8)\x94p\xc6r\x15s\xf3\x8d\xd2g\xc9N\xab$\xa1'\xbcPP\xd7\xf4\xc2W\xa4#\xa8N\x0cy\xe2!\x16g\x15#\xd5\xa6\xa8P\x16v.N\xe4\xf0\x80\x91R\x19\xa1e\xa1Zv\x8b\x01\xd9##]\xcc\x93A\x1a\x12\xa2\xaa\x99 \xd3v\x05\x92V+\xc2_g\xed\xd7\xb7y\\\xb2\x97\xa1\xf2\xee\xc1\x87\x02\x19\xc7\xd8-\xe8\xb0\xe8\xcc\xa2\xe6\x90z\xc1\xf5\x90\xa8\xd3t\xc3\xf8V\xf9\xb00\xb3A\x96]\x89\x1a\xd3\x18\xf3\xe6D\xca\xe6\xecJ\x9bC\xc1\x99\x14\xba\xe8\x182\xce\xe1\xf3\xf7\x14\xae\xa5\xea\xfb\x149\x1c\xb9S\x1e\xc1\x87nh\xd4\x8cAz\xa3\x1d\x06q\x10\x8a\xe6 \x84\x86\x83P\xb4\x0e\x02\x8fa\xde\xde\xf4kR\x1a\xb7\xbc\xa0\xe5\x86\x9dV\x8fB\xd8}\x14Z\x89y\"\xbe\xdb\x11\x1d\x0ff\xc3\xf9\x16 I\x92\xe1\x1c\xdaD\xa9\xc1\x8f\xaf^\xbf\xf8\xf9\xa7O\x9c\xb0\xcc]\x0d\x0e\xb3 \xe7\xc70K\xdd\xfd]O\xcb\xdeO\xbe\xac\x938\x8aK\xfe\xfa)\xdd\x16w\x7f\xf7\x90\xff{\xe4I$\xcf \x18hgP\x05\x8d\x0c\xa9;m p./I\xf16\x9bWZ>\xd6AKG\xdb\x93\x05\\\x8a\xf5C\xea\xd6\x1abwz\xc0AI\xea\xee\x1eq\xaa;u\x0f<\xd7\x11&\x1b\x9f\xc2k\x01Z\x9c\x97\xe7\xe7\x1f\xab\x84\xfc\x14\x17\xa5\xff\xf2\xfc\xfc\xbc\xbcK\xc8\x8f$J\xc2<\xa4#\xa1e\x7f\xa2p\x85UHb\x92\x96\x1fIT\xe2\xcf\x1f\xdf\xbf\x95\xfff\x8d\x8b_\x9f\xb2\xcf$e?\xc22\xfc\x94\x87i\xb1 \xf9\x9b\x92\xac\xb0\xf0u\xcc;\xfd\xf7Oo\x7fz\x91$/\xb3$!8y,\xd1~\xbe\xce\xf2\xd5\xab\x84\xd0[\x8c\xbf\xcf }+J\xde\x92y\x1cbco\xe3\x15\xa1\xe8\x96\xa5\xe9}\x17\xae\xc8\xfc]6'o\xc3\xb5O\xff\xc5:\x1f\xc2\x98\xce\xe1\xaf\x15)\xd8\xd0?$\xd5u\x9c\xf2\x7f\xd8\x97\xe7\x7f\xfa#K&\x87\x15\xce\xff\xf4\xc7w\x88\xa5\xc5\xaf\x0fa\xb9<'\xd7\xf5\xcf,NK\xf1CZ\x85\xf3?\xfd\x91\xcd;\xcb\xd9\xa4\xcf\xd1D\x95\xa1sV@\x97\xfb|I\x08\xfb\xfc\x13eg\xf20\xfa\xfc\x92/x]\xc0~eU\x84#r\x82b\x9d\xc4\xa5\xeb\xf8\x02Z\x8cO0 ~X\xcb\x80\x8b\xd1\xc8\x04g\x11\x1e\xce\x8a\x8b\xf6\xbd\xa7\xe0%\x9fE\x867h0I\xe9\xf2E#\xf4V\xa14\xe6<\xdeJf\xd5\x05\x13\xd2%(\xf9\xa0@\"\x9bE\x94\xab\xc8\x02\\\xd7\x9e\x13\xaf3<\x14\x8e\xfe\xf6P[\x1am*\x96\x13\x02D\x0eH=\x1e\x86\xf5\xd0\x87\x9dI\x1f)e\xbb\xec\xdd\x94`m\"\xd7\x10\x80\x12\xf1\xf72L\xbf+\x81\x0e\x06V\xa4\\fs\xc8R0\xe6\xeaii+7\x1b$\x07-\x83Y\xca\xa9\x0d\xeav\xd2Y\xa8\xc7\xef\x13o\xa6\xbe\x1e\xa1\x87\x19\x16ZR\xa4s\xe3+\xb1\xe3B\xc8\x8b\x80Mlc\xd3\x9f\xa1\xe5\x8eF\x91\xbe\xff\xf4\xde1h\x1aeY\xcc\x83\xfa\xba\xd0^\xb7`\x0d\x1dl\xc9\xa9(w2=\xf4\\'^\xe4\xe1\x8a\xe8\x1d\x89'G\xe8b\x13\xab\"\x92$AA\xc1l0\x8f\x8bu\x12\xdeQ\xac\x97f)q|\x9c\xfb\xa1\x17\x84\xeb5I\xe7/\x97q2g\x99\xca\x83\"\xa7\x80\xd2\xf95\xbc \x8b(\x8f\xd7\xe5\xb1\xe33\xabV\x12DYZ\x92\xb4\xfcs\x9c\xce\xb3\xdb`\x9eEH\\zA\xb6&\xa9\x8bn\x03,j\xa7\xf3\x8c}\xfa\\T ^\x9f2\xc5\xf1\xb3_\x9e\xf0W\x98\x81)\x88\x92\x8cE\x8c/\xf08\xbd>\x81|g\xe7\xc4\x03\xae\x9a\x94t\x8d\xb3l\x96_\xd8\xad\x02\nWS\x89\x9a\xaf5O8\xcf\x94\xd7\x94\xa4\xed\xe7\xa7\x8c\xf0\x89\xabf\x04m\xdb\x0c\x93\xa2\x12\xb7\xf4\xfc:\xdce\xe8\x83\xfa\x9aK$)\xc68e\x0eX\xb4j\xe1\xaaY\x95\x08\xd2\xe0\xc7\x10\xbb\xa9/'\xe8\xed\x07\x87\x02}\xa0\xf7hDb-=~\xae8\x96\xf6\x01?\x9b\xa4\xabx\x17\xbe\xe3\x0e\xce\x1eW\x84\xbb%\xfa\xf5\xb0\x10\xa8\xa9\xb71\xcf.\x11t\xbb\x9e\xeb|&w\x85~\xf2\xd9\xa5U,\xcc7\x1av\x8e\xe1\xa3\xee\xc1\xc5?\x98\xec\xe7\xf1\xa34 #g\xce\xe5e\x94\xe5d\xe7\xd7\xe2\xb2X\x869\x99_^:\xa2O\xf3;\x8a\xe8\x1f;\xa1XL(f\x13\xfa\xed\xa1o:6\xc4\xe9DYZ\x94y\x15\x95Y\xee/\xc3\xe2\xfdm\xfa!\xcf\xd6$/\xef\xfc\xb8\xf8 \xce\xef\xfb\x85\xbf\xe6\xc5o\x8aW5\xbf\xe4\x97\xd9OY\x14&\x84a\x03_\xa0\x05\x9fc\x1e\x99j\xdbl\x95'{^\xb00\xcaTtQKf&\xf6\xfbV\xd6\xcc\x98\xa3\xcau+\xc6#\x9er\xdb\xf9\xb2\xb9\xc6\x18\xd0\x98\x99\xd4\xa0\xb8\xa5\x0d\xcdUfs\xcb\x10PA\xc8,\x94\x17\xbd\xfb\xb7!W9\x9d\x1cy\xee\x96\xec\xeeBq\xcb\xbe\xc7s\xde\xfb\xe0\xb0?\x1c\xbf\xe3\xb0\xa1\xfd\xc9%]\x8a:S>\xf7O\xbaD\x83\xaff\xc8\xbe\x1d\xc5I\xe8\x8d\xb7g\xb6\xaf\xe1\xed\x9a\xa1\xaebHvf\x17\x041@\xda\xee`\x9e\xa5*\xffI\x9f\x07\x06\xbc(\xe0\xc6\xe5m\xe66\x92\x8d\xeb\xad\x9d\x19&\xc2\xfb\x99X\xf7v\xc3[\xb071\xcb\x15[\x9cm\xebF\xd4r\xd7\x02\x89\xb7\xbc[]\xa4K\x08\xd5\xf1\xbb^\xefm2\xed:A\xfd[\xd5%d\xaf\xf3\x11\xff\x9c\xce\xc9\"N\xc9\xdc\xa1H\x84\xc9\x8f\xf8\xabwU\x928Fg1\xa4E;\x119\x0e8\xbf3\x94Jc)g\xc4\xe0\x98\x02QX\xa7\xe6\xd5\xf4\\\xe8\xd1\xca(\n\xbc\x12\xb1\xe7q\xac\x9d\xa1\xb0\x08\xb5\x00\x0e\xab\x80\xc3u+v\xca<\xcfFV\x03KBCP\xe3 m\xdd1T=\x80\xc1D\x02\x8c-\xa8?\x0f\xd3y\xb6r7\xdeM!\x92d\x86\x8a\xaeC \xc2(,]}\x17\xe9xK\x1f\x1c\xef\x92\xd2\x8e\xa3Q*\x92\x04q\xf8\xb1{\xf0x\xb4\xbbk\xbe\n\xfb^M\x8f\xb6/A\xee\xc6\x1c\\\xc7\x9c\xf4\xe3\xf2\x93\xc7\xae\x00\xdd_\xad)fA\xf4\x9bn\x8a7x^\x93\xddn\xaa\xe7\xa8\x9fS\xfd\xef\xa0z\xf6\x9fZ\xf0\xf1\xbe.\xf1\xcb\xcc \xaao\x12\xff\xbb\xf1\xf1\xc1\xc4\xb4\x00\xc1b\xc8>Rn\xc2^ $h\xdb\xe6\x92\x10\xa3\xad\xf3l\x15\x17\x843&\xa5+O\xc4\xea\xc5\xa4y\xb4\"\xd3$\xfdN\x0d\xd2\x9e\x1f\xc29|\xe0}Id\xa5=\xf3!\xea.\xd2\xdalX~\x1e\x04:\xceI\x91%7\x84\x03\xd0\xba\xf0W\x96\x858\xd7\xddZ\x1e\xbe\x82\xff\x98\xec\x99\xa5\x05\x93\xf1#O/\xb3?m\xb2JJk\xc5n\xc6\xffq\xd0L~\x04\x0e\xcc3R\xa4\xdf\x95\x98\xf7g]BN\xae\xc9\x97-\x8b\x8e\x94\x83\xd3\xaf\xba\xd0\xf4\x82b\x8e\xe4\xfe\xabiD\xeep\nO\x82'\x9a|\xc7\x88j\x9d'\xc1\x13\x07f\xe5\x85K\xb4\xbd\x128\xb6\xb5p0\x04o\x93Y~\x81J%\x1f\xb6\xac}@\x0f.7-\xef\xa6z\n\xf3\xe5'A\xa3\xfb@ e\x1b.Tn\xeaN\x0f\x0ft/\xdc\xb8~u\xa8\xbfB\xd2\xceD?\xc4\x01W\xc3 \x85\xd1\xf6\x08\xc8\xeb\xf7g=\xc0DPE\\\xe7\xa8\xed\xd8\xf1\xc0\xaf\xad\x84\x8e2\xd02\x90\xe0\x04\xcb*\xad\xbcFPS\x17I\xe2\x94\xb3f\x8e\xc7\x96\xa1\x9a\x0c\x83*+\x90\xe5\xc3\x91\xb6\x8c!\x9b\xf6\x0ckuWi9I\x0f\xd2\x11\x10\x93\xd9p\xd7N!s\xeb\x1d\xf3:\xb7\xccBPW2A\x9d)@\xb1s\x0f\xff\x1e\xfb\xb7\xc1\xd8\x87\\G\x82h5u\x0f6d\xb6L\x82\x9d\xd4\x9d\x1a\xc9\x9bC\xb3\x01\xc7dl\xf6CAi\xc6c\xc1l\xcc\x1d\x94\x98\xc0G\xfc8Eb\xf4\xb7\x0748j*\xfc\xa6[3:\x97l\xf7\xd0\xbd\x1bC`0\x0f\x84\x98\x87\x9f\x0e)\xf3[v\xb0\xb9U\xb0p\xb5\x08\x06\xbd\xd4Q{;\xb8\x00\xf6\x9a\x94\x92\x84\x89\x0d{C\xbf\x91\xdd\x03}K\x84\xcf\x90\x99\x12\xdd=\xd4\xad\xde\xb9\xcf\xd0\xa1\xceQp\x9f\xa1\xc3\xe9?}\x86\xfeA}\x86(\xaf\x94\xbaO=\x1f\x9c\xb7\xe1\xfa[9\xa1\x1d\xea\xde%\xdc\xebdj\xf6:\xd9\xdb\xd5\x0f ;P\xfa\xf1\x0by\xedG\xfb\x81\x18\xe1o\xc9\x11\x93|\xb628\x06'k\xe4\x0dR\xd5\x8a9\xba\xc4n\x89\xe7\xa1\xa4\xe7\x81\x82\x0c\xc6\xb6\x86\xfd\xc0U_3z\xae\x8f\xc6\xe3\xa7\x93\xa3\xa3\xe9\xfe\xde\xd3\xbd\xf1\xd1\xd1\xa4-nx\xf2\x9f\xee\xd9\xf1\xf8~6\xd99\xba\xf8e\xfe\xbd\xf7/O\xfa\xd6\xc0\xa2\x86\xc1\x10>|:FZxk\xcb%\xd2U\x13\xfa\x13\xc2\xb2\x9f\xc8F\xae13v\xe3hg\xeb\x94\xf9\xee\xe7AI\x8a\x12u\xba\x88\xb1\x84\x0b?\xcb\xffy\xcaC\x97\x96\xf0\xac\xd7\xefd\xc8J\xf5\xad\x82\xed$Xb\xeft\x0c\xf7T\nu:\x08m6\x17\xc2\xec\x84\xd5r\x1e\xa2\xb7\xe1\xc9/\xc1\xfd/3\xf7\xecx\xf6\x9f\xb3_..\xbe\xbfwg\xcew\x17\x9e{v\xec\x9em\xfd2\xf1f\xff\xf9\xcb/\x17\xf7\xbf\xfc\x12x\xdf\x9f\xfd2\xf1~\xb9x\xd2\xbe9O\xfe\xf3\x97\xdb\xef\x1fu@\xb8\x7f_\xa3o\xde\xd2\xc2\xdf\x8bm\xe8>A\x8a9k\xaa\x90bu\xc1U\x96%$L\x9b\x12\xc5Ik\x0bY1z\xbe*q\x9c0\xbaX&\xff\x12_\x10\xb6Cq*d\x88\x1b\xa9\xf9j|\xd4\x96\xe42\xf15\xb9!).\x9d\xf2\x13I\x03!\xe1^\x85_~\x8a\x8b\x92\xa4$o**\x855\xb3/\x8d\xac=\x84|C\xd0\xd5\xd9Xlo\xcc\x04\xda\x9a-8\xedi8\x1bD4k[\x00\xda9L}H\x83Wt-_\xad\xe2\xb2D\xdb{,k\x10\\\xb3\xf2\\\x0d\xa1\xbe\xd5\x16\xbd\xa9\xc3\xa9\xe3\xb7\xea\xfb\x89\xf6}A\xf4\x1av\xa8a3\xd1\x06\x91\xc9\x18\xdd\xc3\x99.\xd7$\x9cH%c\xeduV0K\x8cN\xabm\xf3\xb9\xf2\xd50N\x0f\xea\x8c\xc8*\xee\x8e\xc8 )\x11,\x96\xcd1\x8f&(\x1fsW\xbb\x06\xbf=Pr\x81\xd0\x999M\xd4AwK\xae\x16\xe0k\xee4\xdf*gF.\xedr\xe1\x97i\xa2\xd2x|\x0e\xd9\x14\x97b^\x91!9[\xb0\xb0\x1fb\xf1\x0dY7\xe9\xec\x17\\f\xc7\x1d\xf4~N\xa3\xb0\xba^\x96>Ti\xb1&Q\xbc\x88\xc9\xbc\x9e\x1b\x0e-\x00\xf7;\x9e}\xd7\xf1L\x927\xd6\xdf\x82\xd9t|)\x99 \xefB\xa9\xf6\xd0Z\xe3\xac\xc9\"\xcaW`V^\xd8\xc1.\x83\xcb\xa9\xe75\x0e~\x9a\xed\xb9i\xc9\xba\xfc\xf8\xd2&G\xbfE\x9ah \x7f\xd2\xe5\xca'5\xea\xab\xfb\xb4y\x17\x16\x17r\x82\xde\xb8\xaa}\x92\xb7,\"\xdcD4\xdb\xf6\x91\xed\x84\x92=\xa0J\x813)\xb9\xadG\xbf\xcd2\xe8!\xdct\x1d\xe9\x8d\x83\x0c|\xee\x92@\x0c\x89\x92\xfc\xcd/$\x87}\xfd\xfa2\xae@\xbb\xd2\"\xcaaS\xc4\xc2\x06\x11\x91\x9aOn\xe0\x14fZ\x91\x0f\xe4\xc2X\x91\xf8\xa6\xcet\xb0J\xbb\xbb\x0d\xf3\x94\xcc\x81\xa5\x0b8\xa5\xc8\xbb\x85ZP\xdbjD\x9b\xc7\x06D\x84\xddT\"\xf6\xb0\xde\x1d\xb7)x\x0e\x15vi\x19\x0dsa\x88\xb2\xb4\xc8\x12\xc2\x80\xbf\xeb\xb8i6'\x1e\xd0*\x18>s\x9d\x15E|\x95\x10P\xc8\x84\x15Ye\xf9\x1d$$\xfc\x0csR\x92\xa8$\xf3\x00\xfeu\x0eI=\xeap>\xa7e?\x17\x04\x08\xfbJ\xc7\xf6\xae\x07e\x06q\x1a\xe5\x84\x02\x9b$^\xc5e\xe0\xb4\xb6\xb4\x89\x93j\xa4\xbf\xc4\xf8\xcb<\x8c\x90\x08U\n\\\x91\x0e\xc9v\x932\x14i\x98\xaf\x96^\xb3?\xf9\xf67\xbaY\x82\xc2\xa7(Hy!\xd1\x95&dS25\xd2*\xbb!b\x0et\x98\xb1\xc7\xe3\xbb#\xc2\xa3\x9bNT\xf0#\xa0Y+\x82\x92\xfcKXi57\x10o\x00\xf6\xc9\x96#\xeeYkud}kyS\xfb\x7fQB\xe9w\x81`\xd8\x8c\x0e\xbf\xf4\xcb\xdb\x11w5^\xb0\xfbl$$j\x0c\x901a\x1a\xddQ\xa1s\xcc\xddT\x02k\x94\xea\x97V\xf5\x14\x83\xbdr\xd9T\x0b\x16)\x90T[Q\x15\x98\xaa/\x19<\xd5\xe3-\xab\xb8\xd0p\xa4jlX\x9d@\xb8\xb3C!\x8e!&\x0d\xf0\xc5Hg\xe1E3K\xfa\xab\x99\x17\x9d\xa5R\xc0'\xda\xeeS\xf5\xdf\xc4\xfe\xab\xf6\"I\x86\xf1Vf]{\xebz\xf4\\\x85\xad\x8e97!\xecYf\x1c\xddm\xf3Lg\xf4Q \xa0\xe3\xdc\xed\xed\xce{\xd1\x1e\x92\xb97\xebA'\xe8D\xaf\xccX\xdf\x1en8 \xb6\xb0\xbd\xd0nGLs\xdb'z'\xda\xf9\xc1\xe5\xd0`+\x18y\x9a\xdc\xc2\xd3X0\x83\x1e\xee\xbe Oi\xa1\x8bO\xea\xbbqbotV\xdf\x99\x1dh\xf1\x1d|%\xba\xb6\xd1v\xa8\x93Ag\xd9D\x96\xb6i$\x16'I\xbf\xc6g-\xe2\xcf@\xf9 \x1a\x1f\x8eav\xd17\xd6\x97Y\x95v\x0b\x04tv\xdf\xa6\x1e!\xed\x8dm\x9f\xb3\xc68\x83/\x83!u&z\xee\xd4\x15\x84\x05j?\xbc\xd1\xb8\x11\xfb\x0c;\xc2\x85\xa9_\xf5\x0b 5q.\xcf\xc5!{\xbeO\x0e\x9fz^p^\xe6$\\q\xd7\xdd\xe0# \xe7\xe1\x15Z(\xe0\xef?s\xbfg\xf6\xc1\xe4)\xfa\x86\xfcX\xad\x13\xf2\x85\xa9C1MLP;\xf9\xb1zGS,\xfd\x10\x16\xc5\xa7e\x9eU\xd7K\xa6\xfb\xd8?\x1c\xa4\x83\xed\x0d\xd1d\x0ett#\x92\x99\xb9\x18\x07MyW\x93\x7f\x06\x95?h\xc7\xc4$$\x89\x0b\x8c\xb4\x02\xc2o\x83!\xa1\xb4\xcc\xef\xd4\xa2E\x9c\xc6\xc5\xb2\xcf\xc7\x87>[\x9dK\xa0?\xb5\x96\x8fujG\xed\xa52*{=\x0e\x93r\xa3NQ~\x84\xd6%\x0fD8({\xa3\x80\xfa\xdd5I\xe7qz\x1d]\xed\xecP6\x8f't\x81\x1cW\xd0\xfam\x9b\xf2\x10\x0f \xa2,\xffL\xe6\xdcc\xb5x\x9d\xa3]\xac\xa9XlRIy\\\xd3g\xa7\x86\x00\xa8\xf4y@\xb5\xb7\xc1V\xa8\xe3r\xcb\xb7i\xd5fCB\xee\xe4N\x82\xab<\xbb-\x18\xf12sn\xc6\xc1d\xec\xf8@\xff8\n\x9c\x8b:\xfaW\x13\x0f\x8cA\xc9\xb1\x0f\xfb\x1e\x8f!\xcd\xbci\xb2:\xda\x8f\xda\xdb\xaa\xbe\xa6\xe7e\x88Z\xd9\xeb\xf6pP\xc8\xe2\xee\xeby\x04\xa3 N\x97$\x8f9L\xd8\xd5\xd36\x08\xb1\xa3\xf9\x90\xcc\xc9:'QX\x92c\xbc\xdeO\x0d\x0b\xd8V\x85'\x1c\xfa\xe8z%\xfa\xac\x99\xc6i\xec\xf1\x906\xed\x1aK4\x81h\xf2\xa6(\xde[\x1e\xfcfH\x0c0\xf7\xe1\x86\xf7i\x07\x0cw\xf8\xb1\xe5\xe5\xb5\x114\x03\x97\xaf\x85H\xb23X\xc8N\x1f\xaaW\xda\xf7D\xdcb\"\x0b~\x0dt:\x82\x12\xa6\xe5x\x9b\xcd\xd1\\l\xab\x94\n|\x16V\xd7m\xd7\xd3K(W\xb6\xc5\xfc\xf1\xe8\xf9x_\xbf1PZ\xb5~5X\xc6\xd7\xcb?\x87%\xc9\xdf\x86\xf9\xe7\xf6\x16\xd0'\xc2\x8a\xa2\xdd\x7f\xef\xff`a\x18\xdd\x19L\x0e\xe0\x18&\x07\xbb\x87{\x96UP\x86\x02\\k\xcbh\xd3\x18\xce \x86c\xbe\x16Q\xf3\"\xa2\xe4H\x04\xc7\xb0\xf0\xcd\x8d\xc8\x19\x15[\xef\xbd\x06\x94\x87\xc9\xcb0I\x98\xc0g\xe2\x0b4@\xe6?\xe6a\x9c\xca\x85\x0c\xe2i%\xeaw\x0c3\xa8esR\x94yv\xc7\x0b\xcd;\x92\xe0;\x9e\xe7fN\xa2l\xce\xbd\xablxJ\xa9C?N\xea\xdePB&R\xc1\x00kP-\xbb\xbf\x07\xa7*\x17\x87B\x98$spX@w\\\x9b*\x03\xb3R\x9d\xe2.\x8d\xb8\xb8\x04\x7f_\xe1U\xfe\x90g\x11)\n\xed\xe3,E_\xd1N:O<[\xdd\x94\x92\xfc\xdc41Moe\xd8h>\x9b\xe2\xc9\x99 \xfa.\x8d\xba\xeb1\xf7f\x1cxteG\x87\x94\\\xec\x9f\x95xJ}mE\x07\x0d\x85Q3\x07\xe2\xee\x91\x84\xa4\xbe\xf4\xb7\xe2\x86\xa5?\x0f\x88\x8a\x89g =\xba#G\x8aggGB\xee>\x1a\xe0\xbb\x0dNrc\x1fr\xcf\x97\xb0\x94\xfb\x8as\xe4~k\x1f\x98\xd0\x94 E\x85<\xb5\xe4\\=\xd3_\xd1\xc60f\xbfO\xc5\x1b\xcf\xf3!\x91T\xc5\x83\xf6\xf4R\x05\x8aL\x8en\xdae\"\x1f{\n>\xa4\xbbQ\x89\x9f\x1c\x9e\xa3\xe6@\xc2\x8b\xe8\xbc$V\x8aBN\"0!K*\xc1\xde\xb8\xac\xf7\xe6\x9d\xdc\xcad\xd0l\xae\xa4\xd9\x98&\x91B_\xf4\x03\xf1\x88\xb8\xc6\x1c\x07moc\xf4QA\x0ca\xda\x9b6q\xc4!\xf2\x9c\x969\x06(\xfc\xe0\x96\"\x86\xa5\xc26\xe6n\x03\xbb\x07\xcd\xf3\xd6:vb\xa4?\x0c\xd9\xb4\x04\xcd@t\xd0a\x16\x04\xd5\xdb\x87\xf2y\xa6\x8a\xa0\x98\xcf\xb6~5\xf1o\x84Lv\x82#\x069\x92ln\x89\x02\x02\\\xeao\xe2z\xcd\x98(k$\x05\xe6\nu|\xad\x90\x81\xcd\x82\xad\x1b\xda!\xc7\xa8\xae`&O\x98^\x0e\x95d\x05\x0b\xea\xc6\xa3^\xe0j\xf8\x10\xc2\xe8\xd4$L\xa3\x0f\xc69e\x88\x00\xcd\x7f\xfd\xfa\xf6\xb1\x1bSg4\xf3\xc1q(i\xc1\x10\x80z^F#\xac\xda\x81R\x18IB\xc9\x15\x8bP \xe3c\xcdd)\x8fg\x17\"0<\xc1\xce\xad\x0d\xcf\xb4\xcfz\x17\x05!d\xc4\x9d\xf2\x98\x9a\x8f\x0f\xa2e\x95Z\x18-\xf1\xa0\xb1P \xd29v\xd7M@\xc4\xeb\xe9\x16\xf0\xd0s_\xef\xd0\x04!\x93\xc2\xcd\xc11D\xf5\xa6E>e\xc0\x12\xed8\x98\x17\x8c\xde\xf9\x1a`z\x1b)\xa8\xe8S\xbb\x88\x0b@d?\x0d}2\x1e\x90@\x86\xf2\xado\x81$\xc3\xe0\xf0\x97n\xff(\xc1Abtx%\xab\xb10ld\x85\xfa\xb8\xd0d\xa2\xe1-\xd9O\xbe\x8c\x83\xc6un\x85\x9b%G\xa7\x0d\x0bc\x95Pj\xc0\x1b7A'\xc6SviU\x1aN\"\xda\xeb7\x8e\x05\xf2\xd3\xe7a\x182xe\x9d\x94\x80\xf1_\xbatM\xec\x10\x0d\xe46\xd59\xdd\xdf\x03Q$\x07\x14,Z\x88\x17N\xad T\xd2\x80\x99&{\x18+\\\xd59\xe7\xaa\x90;\x1a\xb8\xa4]\xa8W \xf6\x86\xe6fw\xc8\xd2j\xd3\xa4/\xd9\x94C\xeb\"5\x92EJ\xf2R0p\xad:\x8a\xd4A\xab;e\xe55\x16*\x85\x00I\xbb\x03,\x98\xc8\xec\xe2\x04\xca\x13\x8fN\xa3*\x96,4 \x12\x82t\xd9\xac;\xadyy\xb7\x81d\xaf\x18\xdf\xee\x96J\x1f\xee\xe6\xc4\xfc\xd7\x84\x9b\x93{-{\xac;l:\x8e\xc9\xe5J~0\xcc\xe9\"\xa8%\xae\x9b\x05|\x97U{\xf5\xd2\xbbv\xde\x10\x18\xc7\xe7hL7\x1b+\xc4E#\xf9\xe5\x96JZ\xc5f{)wC\xc2y\xe0\xf8\xe0\xfc\xf8\xea\xc3x<\xde\xb5\xa4F\x83\xf6\x05\xaf\x8b\xed.\xbb\xf8\xda\xb5\xb1\x08\xdc\x13n{\x9b\xff\x15,\xc3\xe2\x0d\xe7\xb7\xc0\xe6\xd3\xf8\x9a\x97IQ\xc7\xda__\xd0\x8bK\xef\xc6\xb0\xda\xbe\xe5,\xac|\xc3\xc8:\xdc\xef\xfa\xe5I\xb5#\xcc\\66-\x1b~\x93\xde\xf6\x15\xf0T\xcd\xdb-\xc9\x8a\xcc\x8f^\xf7a\xcb\x07\x84B\xf3^\xf1]\xedG*5^\xb6\x94\xf2>\xac$\x10\xb1\x8e\xd7\xa4\x0f:0 \x80\x8ah\x9a\x1c\x8a/\xc34\xcdJ\xa0\x0d\xf9\x18\xa7>\xe7\xeaM\x9d\x15\xd1zn\x8b$\xed\x1a:$\xebY\xe4Y\x03cn&\xbb*\xc6\x1e\x19\xdfa\x80\xe4X\xa6\xab\xea\x84\xfb>\xac\x9b\\\xce9nh./\xe8\xd2\x8e\xd2B$\x0d\xd6J*h\x91\xd9|\xf0\x91Zc>\x01\xdd\xfb\x13\x80\xe7\x10\xb4\\A6\x81T\n\x0eM\xa90\xca\x17\xb0\xf0\xd3\x02\x00Rj\x1b\xd1%sr\xd5$\xd3j\xeb[R\xf0}\xd1\xfa\x9d\xe7C\xcc\xe5\xeeg\xc3p\xb7\xa0\x06\xa4#\xc3\xb6>\\\x94$\x07\x92\xcem\xc1*L\xd4\x8d\x84\xa2\xf1\xb0\x98V \xefb\xca\xc3^\xeb\x9c\xb7\x9dK\x07I=c\nZ\"\x9e\xca\xa2H\x00\x89\xb8iH\xe53\xe6\xa9\xa8\x06\xe8\x7f\x1b\xde\xe1Ua\x0b\x81\xb5\x11\xf4\x14PfP\xa0\xb1\x80cM\xd6\xdf\x04\x05a= 9\xa4\xaa\xa3\\C\x9f\"\xd7i\x9a\xa5;\xac\xd9'\x1c\xd3 \x9f\x83\xc1\xbf\xb9A\xae\xb6\xee\x95\xba\xee9+\x89\x05\x1f\x1a[\xf7 f2S\xe6\xe6\xe7\xc6*\x01V\x19\xee~-\x0d\xb2\xed\x0f\xdaq\xf5*\xf1MM\xf7!\xf0R\xd7\xe8\x19\xd5A`\x8e\xdd\xdf\xdc)~}\xb1\xc7\x1e\xe9\xb4\x91<\x92\x9f\x87\xda\x08\xc3\xdeP\x8e\x06_U}A)\x11\x19K\x17\x9e\x99\x05T\x16\x8co\xbd\x03!J9Z|g\xde\x99Y\xaa\x16[\x8d\xac\x86\x91\xb4\xed\x02$ \xd73 \xaaf\xd0\xfc\x1d3\xdd\xd7d_c\xcb\xba\xa0\x05Q-\x18\xc4\xeb\xc1\x04\x0c}\xe7&b#k\xb3\xb5\x1d\xfa\n\x0b\x17\xdc}\xd8\xf0\xc6\x1d\x83A\xf3.?B\xacp\x0cq\x8f\xaa\x8c\"\x1cc\x1c~\xf9\x11\x92\x07c\xee\x05\xf9\xa17\x9d9;\xdb\x8f&\x0b\xd2\x1f Q\x8ey\x19\x8e\x8dL\xbe\xb1\xaeU\xc83:\x85\x89\xf9\xf02I\x8f,) \x1b\xf8\xd1 \x9e\x8b.\x88\x152\xce\x0f/\xb0/\x85\x82\x836 CO\xd5 \xe2I#\xdc\xd9i\x1c\x8d\xba\xda\xae\xd2!\xad+<\x9b\xda\x8bA\xa7!4a\x0c\xc8\xb3\x1f;;\xbe\xa4\x15\xa5\xe4\xab\xa4/\x93\xa4\x1e\xf8\xcb\xa8=k\x0bL\x98\xf6\x8c\x93\xc4\x9dD`A\xca\x1f[\x1a\xf3nZ)\xb6\xa5A\x14\xa4V\x19\x94\xd9O\xd9-\xc9_\x86\x05\xf3\xb0\xd8rg\xce\x92|\xa1\xdc\x11\xd7\xbb\xd3\x7fw\xf0\x8f\xb0\x88\xe2\x98\xfeq\x15\xa7a~\x87\x7f\x85\x059\xd8\xc3ZQ1\xe5\xff\xeeL\xf9g\x93\x83\x84\x88\x16\xc4\xdfyx+\x19\x19\xb9,\xd3\xa2\xa7\x8d\x03\xad\x8cp0\xb59\xe2\x90\xbbm\x8d[\xc1,\xae\x9bt5\x12{@ \xccM\x98 )\x10\xf7\xf6\xb6\x1c\x98\x8e\xb1\xb8\xb5\x8eZ\xc8\xbcr\x19\xde\xe4\x8d \x8bP\x1e3\x10\x8774\x17\xb2Y\xcan)@g\xc8J\x01\"\xe2\xc6>h\\\x0b7\xfdZX]\xb7y&\xd3\xb2)\xd3\x04fiDj\xa1[\x07\xe9F\x1a\x93\xa3\xb1/\x99f\xb5E\xd4 !\x95\xbc\xc5\xa8\x0c\xbc\x82\xb5\xe9\x92\xf1\xdamt\xad\xe4\xdd2\xa8\xb6k\x0bt\x1d\xa0\xf0\x01\xb4\xe7\xd6\xbe\xe6\x852\x1e+\x9fk\xe9\xde\xed\xec\x9f\x9e\xe1~1\x89z\xd3\x1a%\xf7\x8d\xf8[\xbb\xa6U*\xd7\xa9\x7fi\xb5\x9a:\xbd\xfc.\x93\x94\xa4s\xd7\xf3\x81\xb4\"8\xfd\xa1\x19\xa9\x9a\x9b\x11\xb3\xe8\x1f\x8d=\x8a\x0e\xdf\xacVd\x1e\x87%\xd9$\xb5~\x7f\x0e6\xfb\xbe\xf0\x03\xd2\x1b=\xe2\x9b\x0c#u\xf7\x0e\xf7<\xd7\x833\xee\xbf\x8c\xc9\x13\xd1\xb0\xf5p\xff+\xa6z\xd3\x84o>2\x87R\x99\x9a\xd3\xc2\xed\xea\xc1\xc3*\x83k5G\xec\xedPC\xfc\x1275\xb5h\xee\xca\x07\x850\x8a\x0c\xaf\n\xf5M\xf4Uy\x02n\xea\x90\x0d\x0b\x1f4k\xf4\xb8\x95=\xa5\xb2\xf8V\xaa\xdf\xa1B \xc5\x00\xb6\xcc\x1b\xd8k\xfc\\\x17Z\x84\x05\x86#h)\x0bo\xb1\x10Y\n\x16\xf0\xfc\x14\xb3\x14D\xee\x82\xa7\xfc^\xc6\x8d\x93\xd3\x0eDn\xe1.<\xef\x04X\xe4-\x18\x8d\x0c\xea(\xb4\xf3\x91\xa5\xac<\xccP\xc2Q\xe3\x8c\\\xf8\x90\xbb\x89\x94\x02E\xc3\x8f\xbc\xb47\xd3\xfc\xa0\x93\xa6xH\xb4\xb0\x91\x10Tj\x03\x18F\xd4\x9aDo\x96\x14\x8fHa\n\xc2\xc4\xeeA\n\x12]\xa5\xbcx`R\x82\xeeA5\x07\x8b\xd6\xad\xf3\x8b\xb0P\xcc\x9f\xc8\x97\xf2]6'\xaec\xcb\x99\x92ah\x01\xdbx\xb4\xb0\xb8]\x029\x0b\xfb\xcd\x1d\x858\x82g\xcau\x16#\x9bX\xf1w\xb7u\xa1\x90.\xb1!v0\xfdp\xaai\xe5\xc4c\x96\xa8\xa0\xcb\x9aJNY\xe4\xb8i\xe3\xc3\x08u\xfa?V\x1f1x\xe9Zf\x86\x176\x0e\xe6a\x19b\x98\xc2S\x18\x8d2\xf8W\x982s\x07l-(\x96\xf1\xa2t1\x04\x05\x17\xbf\x08\xafkN\xe1\x95\x06m\xd5\x83\x17dW\x05\xc9o\xd0R\xca\xbcx\xd12\xcc\xc3\xa8$\xf9\x8fa\x19\xb6\x82\xfe\xb3V,\x16\xeb\xbd\xf4\x02}X\x9a\x17\x0cai&X\x99\x94{F|(/P\xec\xc0\x15\x94\xa8\xbde\x04\xb0iq\x86\x88\xc5\x1e|3\x1c\xb6^\xe3v\xe4$$p\xec\xaa\xb0&\xc1\xb4\xe4\xf6f\xf6B\xe9\xe8D\xdcO\xdaM\x9d.\xa8C\x8cj\x1c\xca\xdb\xaa\xc4\x84|\xef\xd9\x8e7~\xb1\xb1\xdbze\xbf\x95\xc6\xa6\xffL\xae\xfe#.;:\xb0Th\x1f%\x1bH1\xdf\xa8\xde\xe0\xbb\x80\x8c_\xee\xea\xa2\n\x00\x16\xb8\xd5\xd8lA\xcaO\xf1\x8ad\x15J;\x0c\xdb!U\x182\x80\xa6\xba\xcb\x0e\xfb\xd8<\x98\x96T\xeeA\xba\xb2\x83\xe8\xcaoBeY3h\x9a\xb2f\xaay1\xa7l\\\xfb\xd3}\xfe\xef\xc1\xc6y1;F'\xd2S\x1e\x9a\x92\x8d\xa1\x86\x8f\xa7'P\xc3\x0e\xe7\xdda\x87\xd5X\xe9\x96|WV\xc8 \x84t\xed\x0e\x92,\xc2\xc3~\xdcJaF\x9fe\\\x94Y~g~\x99\xadI\xaa\xb2\x7f\x86J\x98\xf2\xab\xb7\xd6\xeb8\xd1+\xd9\xe6\x0b\xe2\x86K\xf1\x82\x9b3\x7f\x8b\xc9\xcal\x89\xfa\xccV\x1cta\xd8wmxr\xc3\x1dFm\xda\xb8\xb4C\xc5\x9b\xd7\xf1\xde\x0c\x82P\xab=Im\x08\x13\xf3\xb0Ih\x15$\x82B\xbb3\x87\xae\x95\xe3\x83\xf3C\x92]\xd1\x7f_g\xf9\x8a\"=\xe7\xc2;\x01\x16\x16\x13\x13\xf3U\x08\xc0]\xcf\x0b\xe6YJ\x90\xc4E\x8dE\x07\x92\x13z\x97\x98\xe5\x10\xb4\x93\x1f!\xc4)_3\xc693;QV2\x0b/\x86`5,\x91\x0d>\xec\x0b\x93;\x8c\xee\xe0P`\xe0\xd0k\xcb\x0b]=\xc9@\xaf;\xbb$\x1eW\xcf\\\x9f\xb8@h\xd6\xe7>\xdc\xf8p\xe7\xc3\xb5\xde|\x81y\x0f}\x98\x1b\xdc\x92W>\\\xfap\xe5\xc3m/\xbb\x08\x82\x83Z\x83\x08\xb6\xfa\xa2\xc6\x05/\x8c\xf1 \xe8#\xc2\x15v2\x00\x18\xef\x8fe\xec1\x87\xe0k*1C\x8a\x8ej\xd0\xacf/\xfbi\xf8\x86R8i\xad\xdd\xea\xfc\xca\xe2\xfce,\xdddD\xc3Gb\x00vmt\xf9\x05\xbd\xa5G\xe0\xc0\x1bq\xa0\xdb\x95\xce\xe1\xb4^[\n&n\xdaU^Y\xd0\xf1\x0bT\xca5\x82\xedV\x85\xf7p\n/f fNz1s\xfe\xed\xdf\xea\x8b\x85E\xe8\xfc\xf1bvcH\x1a\xfd+\x05\x86L\xdfxc\xe00?S\"\x00\xce\xe0\x1c\xce\xe0\xd6uHZ\xe61)\x10\xa2\xfd\n\xf6\xd4uoX2\xb7<\xbc\xc3\xa9\"\xa2z\x11\xf0\xafio\xef\xdb\x14\xd1\x1bD\xc5W\xf4\x96\xb8o\x18\x19\x8e\"\x0e\xcf\xf3P\xea\xae\x8b\ni\xf5+\xa6>G\xcfj\xf7\xca\x87/>%\x11(\xba\xa5<\x85\x89\xed\xb8\xe2\xabT\xd1\xea\x89\x0fK\xcf\xf3\xe1\x9c\xb6\xf0\x1e\xe1\x8c\xd8 \xec1H\xc3\x15\x93\xad\xbf\xe2x\xfc\xd7\x81P\xe6\xbd\xd5\x9f\xcb\xe3n\xf1[L\xf7\x8bW}\xeb\x15\xdb 1\xb4\x178\xb4_=\x1f\xc2\x19\xa1\x94\xc9\xaf\xf4\xaf/\xf4\xaf\xa5\x0f7f\x11\xdf\xcaj4\xc1\xe6t\x8c\x9bHw\xed\xd6\x15\xd3\xb4\xc8\x14(\x988\x86\xbb\xa6\xba)\xd3\x97x\xf8\xae\x1e\x83A\xb1\xe8\x9bl3A\x90\x89\x97\x14\xc2\xad<\xc0\x7f_\xd0\xa9gt\xea\x97>\xacf\x97\xa6\xf0\xa2,|\x91\x1b\x07\x1f`\x04q\xf0\x1a\xbe\x07wM\xbf{\xe5!\xfc]\x99c\x11\xad\xea\xc2A8\xf7FJH9\xb5\xd0\x0f]\xdfC\x1d\xa7\xa7\xd4\xd2\xe4\xda\x08{\x01\xc1\x8d\xba\xb9\xae\x08\xb3:\xcc\xeb4\xd2\x12}7,\xae\x05\xe4\xb5\x17\xbe+ mk\x0c\x1d\xd6\x81`\x1c\x06\xfd`\xa3\x91X\xe2\xd6\x9aF\xd2\xe30n\x1c\x8c\xd5\x1f\xb9+\xce\xca\x10\xf4S\xf7\xc64\x08DV\x1fX\x9a\x1etb\xe5\x93\xb9\x95\xba\x93}\x16\xa54u\xa7G\x9e]B\xccG\xf3\x14\xb6N-\xcaT\x91\xda{\x1e\xdf8\x9e\x0fN\xf8\xf5j\xd4\xa7m \xa1\xce\xdc\x0b\xc2f\xf2\x1b\x92\xfbS35|\xf4?3\xdd\xa2\xaa\xf6\x9bn\x9a\x19\xa8\x95s\x98\xab\xf1\xcc\xf9A\xa6\x93}\xcf\xdd\xd2)uc&\xf9\xbeu\xb1\xc7\xfa\x0cyB\xc76\")\xda @\x813\x163\x8d\xec\xe5\x9a\xb58\x85\xd0\x83\x94\x1e\xde\x8a\xed_\x88K\xb1\xbd\x0d\x11\x13^\xeb\xc1\x0d\xb8\xf3\"i\xc2\xe7\x16'\x1e\xff\x8e\x12p\xb3b4b\xf1}\xdd\xff\xca\xdc\x08[\xbb\xbfoZ3#\x97h\xb3M\xed\xdd\x9f}s\xaa\xe8\xcel\xfe\x95A\x93\xda\xc5\xf7\x06\xd7\xa4\x94\xb2d\xabV\"\x96c]\x8a\xbd\xe3y+\x91\xc5\x9de\x176\xf9\xae\x9ae\x8b\xf33\x8dW\x85\xf2\xf6L\xfd-\xd1x\xc7\xeag\x9c!?\x83J\x97\xe4n\xb8\xf8\x87\xe6\xc5o%\xe4no\xc5?s\x14\xd7\x03\xee\xcbu\xf8?;G\xb1\xf5\xec\x98\x12/\xfd\xcf\xcd\xa5\xdf\xb9\xcd\xbc\xb7\xf6.+\x16\x8b\xee\x04\xb6\xc1\x04\xd5\xb5<\xb6\xee\xd4RO\xd8,\xd1:{\x96:\xe6\x8c\xb7\x9b\xeda\x9f4m\xb2{\xd0N@\xbf\xfb\xf4\x9f \xe8\xa5\xe7\x7f@\x02\xfa}sR\xc4\x01\x19q-\xe7\xbf\xae`\xb3\x9f\xa4}\xf3@\xe6\xcd\xbe\xc7\x14.\x99y\xe6\x82g\x016\xbf\xa5TOhu\x14\xe1c*DJ\x9c\x82ns\x84 \xd6x6s\x8e\x03\x8e\xc1\xc5\x08\xdb\x98D\xf1e6'/J\xb7\xf0\xe4\xee\x9d\xe7\xc3\xdd\x1f\xa4\xa2e\xe7t\xa5\xdd\x91?r\xf8\x15\xc0!\xa4\xee\xde\xc4s\x13\x0f-i\xbb\x1aK\x1a\xd7\xcb\n\x83\xf4\xfa0\x91\xcc\xae\x1f(eI\xf7\xe1&H\xb3\xdb\xde\xd6\xb0\x96\xb5\xa19\x86\xce\x16\x06\x99\x94\xa2\x9c{\x01\x05zS\x1fb\xfcc\x12d\xe9\x8a]68\xa5\xd4\x07\xc6\xcap\xb3`\x9d\x15%\xbf\x85\x08h&\x18\x81i\x11\x84\xf39&\x1a\x94Se\x197Cj\x00\xc9\xbcE\x10\xafh\x8f\xe7Q\x1e\xaf\xcb\x82\x8e\xac{j\x0by\x0c\xdc\xa1\xdc\x07\xe7{)\xac\x17\x85\x94\xad\x11\xb9\x0e\x9f\x90\x83\xe4\xd4\x16\x1b9\xed\xcb\xc9\xd2\x9c\x84\xf3\xbb\xa2\x0cK\x12-\xc3\xf4\x9a [\x1d\xb9N\x81\xa3r\xbcNK\xf5\"\x08\xd7k\x92\xce_.\xe3d\xeeJ_yA\xbb\xe5\xbe3,\x123\xb1\xc6J\x16MY\xdcS\xab2\xb9\xd3\x94Q\xb2\xa0oN\x84bG\x8f\x99>%\xc4\xd7\xfa\xfe\x18\xd6\x1af\xa0\xb0\xfa\x18\x9a\xecC\x9b\xd1)\xf6\xc1\x9a\x95\x0fVy5},\xce\xf5\xf4\xb996{\xee\xa8\xeb\xd8i\xd7\xda\xdb\xb5\xc5\x04\x9bv\xdd\xd7q\xcf\xeamJ\xe9\xb4\x0c29\xa53\x1ed\xed\xa2O\xbe1u\x89]\xe6YH\x14\xe5\x1e\xea\x9bl\x9e\x857<\xb6U\x16,ZQ\xc4\x05!\x8c9\xc5sRd\xc9\x0d\xf10\x9c-F\xb1[\xc5\x05y\xec\xc2\xb4V\x80-\xcc\x9e\x9d\x04\\\xd1\xad\xef'\x00M\xd4\x9f\xd9\x99\xb2\x0en&9\x963O+N\xdemmQ\x02\xcf\xf9H\xae_}Y#h\x8c\x15\x0f\x9bAS\xb6\xdf\xd6\xda5#u\xa7\x87:A\xd7\xb8v(\xf2\xffA]\xca\x12V\xe3*\xeb\x9dq\x03\x84\xa3\xde\xc5\xb5Q\xd7\x88\xa1\x02\xae\x1b\xc6\xa46\x1eW\x8f\xb12J\x16\xb5\xaeX\x85\x84\x9d\xba5\x15\xcf\xfb\xcb\xb2A\xb9yp\x0e#\xc8\x91Y\xce\xba\xf5\xbc\xf4\x90(\x85\x98\xbf\x9dk*}9|\xd4\xa054\xcb\xae\x89\xecr#\xc2\xb5\xf3}\xec[(\x14\x8e\xba\x8a2\x9d\xd8B\xa9\xf0\x80\x84\x14\x97@\x08Q\x12\x16\x05\x84\x85\xe2%\xfb\xbbLG\x93\xd2\x0bO\xa4\xc9\xbe\xe9\xc4|{W$\xe3Z\xb6\xc8\n\xfe\x02J\xab^\xbc&oS\x96\x1a<\xc5\x18]\\\x9d\x03\xe9h\xd4E\xe8\xe7h\x89\x92Z\x08\xfd\"\xd2\x84\xac\xa0s\x01\x0f\xad\xaeB\xf6\x89\xe4\x95\xbd\x95\x07\x0b\xce\x97\xb1\x80J\xe5\x8c\\l\xb8_\x8f\x03%8WJY\x1d\xea\x1a\xdf\x98\xbf\xda\x1dO\xf5W\x19\x7fE\xe1\x8f\x9c\x86\xb0F|\x86\xdc\xa4\xb5\x89 \x0b\xd4,\x83\xa5\xb2\x1b,iA5\xfe\xd0\xfek#\xf8d\xb9\xea\";\xc1\x163\xc27\x12=\xe7\x14:\x01\xf9\xb2\xceIQ`\xd6\xa4\xaa(\x81\xc4\xe5\x92\xe4p\xc5c\xccf\xb9D\x05\xb1`\xcd\x0e\x8c6\x86J\x1a\xb8\x935s\xccc6\x96\xaa3\x8eJ\xc2\x8d\xed\xe5\x94\xd8-\xd3jC\xa7\xf5\x0d\x0c\x08@\x07\xaa\x91\x96\x85\x95\xd5\xcc\xbd\x0c1,\xd4\xdd\xc6\xfb\xc8\xa8\x11\xb1\xc7g8\xfd\\\xa1CD\xb2\xa1K\\\x83\xcbKJ!}\x93\xfb\xa3\x1aX\xef\x8e\xbfM\xfc\xa4\x03\x93}`\xea\xee\x99\xedz'-\xc5\x12zMS\xe09f\xe1\x07\x0e&\x9eb\x906e\xe5\xbb\xe3\x03\xe3\xf5\x0cMc\x06a\x97\xb6\xce\xb3u\xd1\x845\xa4\x98\xaa\xe4\x01HyIN\x16\x05K\x0d\xc5B\xcc\xad\xe7a\x89\xf9\x0f0Nr&\xad{\xbb\xef\xe2\xef\xd8w\xa4\xba\xdd\x87r\xf4\xa9\xe2# \xa3\xf2e\xb6Zg)\xc1\xbc7\xbf=\xf8J\x95\x82\x94\"EY'\x90\x91\x88\x11%n\xa69\xf4\x90\x04x\xd8\x8f\xdcu\x0e\xf7\xeb\xec\xef|~\x01I\xffZ\x91\x8a\x9c\xf31\xd4V\x15\xbe\x94\x87^\xab\xfb\x92\x87\xa2\x15\x11\x9d|p\xc4\x14T\x01\xa7<\xc9E\x96G\xe4gl\xa8[\xb6f\xe8\xf0u\xf3\xad\x906\x96\x03\x07W\xfa\xe0H]\xab\xe3\x8b\x14\xd8\x17\xcap\xaeP^Qp\x1d)\x85\xaa\x94 \n\x1fb\xb7\x90\x1b\x90Z\xf3\xd4/\xe3\xe2C\x95\x93\xd6\xa9\xe0 D,\x8cB]\xf3\x18B\xf5\xca\xd2\xc6\xa4\xb7\xc5\xb7\x00N\xa9{ ;\xaf\x0b\xf8\xa2\xe1\xbc\xe2mV\xa5%\x99\xf7\xc5\x0d\x14\x14\xb5fc\xa9NC\xdb\xbe6ae\xae/\x1d\x0dm\x18\xe6\xfa\x1f\xc9: #\x16\xa0ph\x1f\xe2n\x18\xea7\x8bm\x86\xec\xf9\xe3\xf7@,\xba\x1c\xac\xfe\x1b7\xfd\xdb\xb7\x1f\xb5\xfd\x04GU\x9e\xe3 \xdd\xdcu\xa2{\x16\xc3\xb2\x9a,\x98#H\xf3\xcburz\x05\x03\xc2\xd4\xf8\x0e\xfa\xdb\x1c\x8c'\xe3\xdd\xdfuQ\x9c\xf3W/?\xbe\xfat\xf9\xe3\xfb\xcbw\xef?]~xq~~\xf9\xe9\xdf\xdf\x9c_\xbe\xffx\xf9\x97\xf7?_\xfe\xf9\xcdO?]\xfe\xf0\xea\xf2\xf5\x9b\x8f\xaf~t\x86\xf4\xa9Q\x12\xd3\x897L*\xd1\x17!\xafu\x97\xcd~z\x14\xfc7T\xb7\xd1I\x8f\xd3\x7f\xba17\xa6\xbb\xba&\x14\n\xae\xb2\xf4\xd5\x97\x92\xa4\x94\xf8-0\xca\xf85)\xb5\x12RD\xe1\x9a\xfcH\xc8\xfa\xa78\xfd\xfc!\xc4\xa4\xcb\x84;\xbb\xb5\x8a\x8be\x98$\xd9\xed\xab\xbfVa\xf2\x1f\xe4\xae\xe0i\x05\xe3d.\x82\xbe\xb0jY^\xb2\xccz$\xb8*3^H\xf28L\xe2\xbf\x91s\x12\xe6\x11ko\x1d\xe6\x85\xfc\xfb\x9a\x94\xe7\xe1j\x9d\x90\xf3hIV\xec;L\xd1\x10\x96\xe4C\x98\x87+\xad\xa4,I\x9e*eo\xe3\xf4'\x91;Z*\x0d\xbf\x18J\xffX\xc5s\xa5\xe0\xc7\xb0$\x9f\xe2\x15Q\n\x99%\x8cR\xf4C\x96%$T;~\x1d'\xeawo\xd2\x92\\#\xad\xd3\x94\xbd\xabVWZ\xd1\xdb8\x8dW\xd5J\x1fn]Fi\xac\x97K\x12}\xe6\xdf\xad\xc8*\x8b\xff\xc6\xba\x8a\x8b7\xabU%\x84~\xa6\xd0>\xe2:_Q\xd6p\xfa\xd4d\xbd\x1e\xd7\xaf\x8fL\xaf3\xfe\xfap\xcf\xf4\xb6\x12\x1f\xef\xee\x9a^\x87\xf5kc\xd7\x05\x7f\xcd9S\xf9\x15\x9d\xdc\xff=\x7f\xff\x8e\xeb\x00\xfa\xec\x19\xec\x9eK\xc2*\x816\xc6\xce\x9b1\xb9-p~\x93\x85\xa4kb\x97\x0d\x11P\x15*+X+\xc6Z\x9d\xf4\xa4\x93\xb2\xa1\xf4:\xedD\xbc\xb8\xeb] \xde\xc8+\x17C\xd6|qy\xe4\x9a2\xfb\xbf\xe7.\xb2]\xaa\xdfj\xdd\xc3\xff\xcf\xde\x9fw\xb7\x8d#\x0f\xa3\xf0\xff\xcf\xa7(\xeb\xc9/C\xb6i\xc5r\x96N\x9c(\x9et\xe2\xa4\xdd\xd9z\xb2\xf42\x8a\xc6\x87\x96 \x8b\x1d\x89TH\xd0\xb62\xf2\xfb\xd9\xdf\x83\x02@\x82$\x00\x82\x8e\xbbg~\xf7^\x9e\xd3\x1d\x8b\x0b\x96B\xa1P{\x85i\x1a\xae;t@E\xb3\xe8\xd8\xaa\xfe\x8d\xbd\xbc\xf70@v4nv4K\x93\xe5O\xef\xdf\xa6S\x92\x125\xef7PO\xab|g\xabr\xe1\x11c*S(VN\xb1\x84,\xe5\x92\xf4\xd9\xbe\xb4}Z\xc0\x8b\x94\x19x\xa3\x8c\xcf\x04oM\x8a\xa6\xde\x93/\x1e\xf1\xfb\xcbp\xe5Q\xccd\x1fe\x14g[\xbe\"\xa6\xf5:\\\x95oB#\xc6 +;D\xf1\xf4C\xe2$\xa2\x80b\x16\xab\x1b\xb8\xa0jV\x0d\x159\xdb\xef\xcf\xa2\x05%J<\xa3\xb1 \x91hA\xefD\xa3\x8d\xf9\xf3\xd9i\x7f\x18N\xe6e\xeb\xc6\x1c\x01\xd2*0J\xc7h\x0dM\xc78{O\xe4^\xd7X#\x9a%\xfe\x18\xc8\xe2$]\xe2 \xc2qn\x08\xef\x03\xa4\x13\xcfcW\xa4m\xc9\xe8\\\xf4\x14e\x05\xdd9\x14}\xe4X\xfd\xf8\x9a{\x91\x13qj\xb6\x8a\x9bu\x97\x10A%^\x87+\x17t2\xa2LJ\xa6\xf9D)\xf2g\xcb\xfdP]W\xe2\xb1\x95\xe5\xa6\x9df&\xd8\xcb\xa0\x12\xd1\x08\xca\x90\xdfa\x97\x7f\xd9\xa8\xcfD=\xabr\xbc\x06\xcb\x9cP\xf7Z\x0f\x84\xa8\xed@\x88D\xa5\xa7\xdd\x00\xf2\xf2n\x1c@\xd4 L\xd9:\xa3d\xf9a\x9e\xc7\x9f_G\xd3\xe9\x82\x9c\x87\xa9]\xe4\x07\x9d\xe5\xce\x04\x13\xd2\x9fJ\xf7I\xc1\x85\xe9K*@\x97Fu/7\xf4H\x86\x0f\x8cyKc\x8fz\xe8\xbfE\x9c$\x8b\xe9\xc3\x1e/_\x8f\xff\xa9\xaf\xe2\xbd\xf1h\x05\x07\xb8v\xb7\xe1\x00\xf6`\x1f!|\x0f\x0e\xe0\x8e\xf8\x9b\xdd\xbf\x0d\xfb\xb0}\xeb_^\xe8\x9dd4\x0d't\xb3\x88\xc2l\x13O7\xd2y{\xc3\xf6\xec&\xf3\x96\x9b\x8c\xa4\xd4?\xd8\xe44\xf17'^\x98\x91\x0d9\x8d\xe2M\x92,<\x12\xc6\xfe\xc1&%\xe1\xe7\xcd\x9a\x12\x7f3\xc1\xc7\xec\xc0\xd9\xcc\xc3t\x83\xf2\xedt\xb3\x08\xb3l\xb3Hb\xb2I\x96\xab\xc5&\x893\xbaIb\x1a\xc59\xf17S\xe2\x9d\xe4\xa7\xa7$\xddL\xa2e\xb8\xd8L\x16aJ63\x8f\xed\xf1\x0dI\xfd\x83M\x14Gt\xb3\xf0\xc8iH\xc9\x86P\xe2\x1f\xf8\x9bi\xb2\x99&\xf9\xc9\x82l\x887\x99'\x9bEv\x10\xcd6\x8b\x8cx\xd1\xcc?`\xf3\x88\xb3<%\x9b8_n\xceHL7\x17\xde\x84\xac\xe8\x86L6+\x0fS4o\x92\x94\xfa\x1bJ\xbcx\x9amPs\xb2Ic\xdf\xf7Y\xd7\x8b\x05\x9d\xa7I~:\xdf\x84\x8b\x8cl\xb0l\xf9b\xcd\x86r\xc1\xa6\x93\x84\xeck\x8f\x84\x939\x9b}D\x18\xd8\x92\xe5&\x8f'\x1e\xdb\xbdl\x80\xa7\x8b\xe4$\\lN\x13\x9alN\xf30\x9dn\"o\xb6Y\xae<\x8e\x03\xd9F\x19D\xecEt3Y\xe4S\xe2\x1d'\xf1\x84\xf8\x07\x9bE\xc4\xa0\x95\xd3\x8d\x14}6\xd4#\xe9,\x9c\x90\x0dI\xe3p\xe1\x1f\xf8\x07\x9b\xcc\xdf,\xbcpy2\x0d7\x84n\x92\xc9\xe7M\x12\x9f\xfa\x9b\xa5\x17M\xd2\x04I\xe0\x06\xf5L\x1b\xaeK\xf07o\xc27\x9b\xd8\x0b\x97$[\xb1\x96B\x1a\x9d\x91\x0d\xb9\xa0\x1br\xbe\x89\x16\x9b\x84n\xf2\xc5\xc2\xdf$\x1e\xb2E\x9b\x15\x8f\xaf\xdc\xa4\x9b\x9cn\xceH\x9aFS\xe2oV^8\xf9\x1c\x9e\x92M\x98\x86\xcbl\x93Fgl]\xd2\x84\x92 %\x0c\x104\x99$\x8bM~\xb2\x88&\xfe&\xf5\xc2\x88a\x8c\x17N\x93x\xb1f\x0b7\xdb\x9cF\x19%\xe9fEB\xba\xf9\x92Gi9\xefl\x92\x93\x0d\xd7\xb3mh\xba\xde0\xaa\xe8\xfb\x9b\xcc;Y\xb3\xc5\x0f\x17d\xba!\x8b\xd9f\x9e\xa4t\x13\x9d\xc6d\xba\x89\xbe\"xB\x1aM6\xa8\xd3\xd9\xa0\xa9a\x93\x9fp\x97\x84M\xbe\"\xe9f\x1dO\xe6i\x12G_\xc9t\x83\xb1\xc4>\x83\xe8r\xb5`\x83\x9f\x93x3\x8f\xb2\xcd\xf7|L\xd1\xce\x06\x87\x11^\xf3z\x8a\xf6\xcc)E\xfb\x14\xab\xfc\xa2AB\xefGR\xbc\xdc\xf4\x86\x99\x06Pw\x06\xae_X\x8b\x8c1\xa6\xd6\xb7N\xf1\xadA\xcb[K\xc6\xd3z\xa7\x01\xc4\"\x83\xc9\x00K\xede\x84za\x00k[\x81\xe2&*H\xa1c\xc9\x84\x8e\\: .1\x19\n\x0fq[\xea\xb9A\x0d\xb1hMU\xdb(\x9a([0\x11\xa7\xc2\x9b\x8d{\x87\x95\x84\xbe$U\xa3\x81\x86\xb8H%\\\xa3\x08J\x80\xf6\xb5l\x12.\x9e\x86\x19\x1b\xd6\x93\xea\x9d\xe7b\x90\xad\xa0\x91\xeaG\x8f\xf6Sn\xe8\xf7n}\xea\x8f\xfe\xd5\xbf5\xfe\xee\xc6-&J4K\x7f\x92~\x16\xc6\x11\x8d\xbe\x92\x8f\xe9\xa2\xb5\x87H\xad_\xabz\xdb0a\xadW\x8b7\xd2\xc9\xd6\x8abp\xa6\xf6\xeck\x8f\xe0SB\x9fL\x18\x97\xcf\xb0%M\x16\x8b(>}G\xb2U\x12g\xed\xd0\xa8\x9dd\xa5\xc2\xbf\x1fe\x8a\xf6_Q\x87\xb0\xa51i\x0c\xaa\xc7\x9e\xfe\xcdR\xbf4\x8b\xe2\xa9\xd7\xaa\xac\x91Wq\xc2e4Li\xf6kD\xe7^o\xafW\xe8#U\x15*\x83\x89\xd7\x9b\xf0\xdd\xc3\xad\xf6\xff\xbe\xf4K,lz\xfe\x01\x98+X\x15\xaa\x1d\xaf'\xba\xe8\x89\xc4\x9b\x1a;\x89\xa1\x8d\x14\x9d\xe64\xe3\xd27\xe2\x17\xca7a\xea*\xb3\xa4\xc5\"O\xa2Y+\xc7\x9aM\x9bx2%d\xb5X\xbf\xa7i\xb4zI\xd65~\xcd\x927\xecZX\xaab\x99[\x94\x81:\xa7L=\xb6ut\xbb\xafZ51\x99N]K\xb7\xd9\xa8\xe4\x8f\xf1q\xb1\xcd\xd4&5\xef5e\xf8\xbf\x19\xb05d\xb1\x86\xa3\x91\xc6\xe4dVh\xe3\x98b\xee\xa1\x17a=D\xd4*\x8a\xc8mv\x87 5<\xa1\x0c\x15o\xe8\xd3V_\x9aU\x90\x91\x86\xec!\x15s\xb1\xa3F\x86\xa2\xdd\xa6\x94\xe2\x80^)\x0c\xb9A-\xeb\xcdp\xddp\xa6\x18\xad\x16\xb4m\xc1)\xb7Z\x94\xd5\x8dMn\xf5P%\xbeU7_n\xdf\xd3T\x94+\x98\x9d6\x83d\x91o\xb1\xd9\x84iM\x18L\xc4g\x1a\xd2\x1f\xa3\x03\xc6\x87\xa4p\xeapX#\xfe\x8da\x8d\x94\xde\x8chR3\xfdU\xdfc\x9bb\"\xfd \xee5\xfc\xfa\xa1\xc8\xbaq\xfbN=<\x05D\xee\x0d\xf4\xb0\xb83\xd0}\xba\x92-\x7f\xbf\xab{\xaa\x0f\x89\xaf\x16_e\x0f\xcf*\x07\x89\n-\xa3\x05\x19\xb3\x16\xf4\xa3\x18\xf5\xe3\x99\x17\x97\x0c\xb8N\xb7\x02\xaa'\x809:\xd7m\xa3\xc1\x01(\"A\x84A\x13\x11\x16Z5\xf2\\.hm\x8d\x95t\xf1<\xc0C\x9c\xe2\xa7Q\x93\x18p\xfe\xad\x9f%K\xd5s\xa2\x8d\xddd\xbd\xac\x95a\x8eb\xc6[\x8db\x8d\xdd\xeb\xb2\xbe%\x9a'\xdf[\x83\xdfc\xeb\xfe\x80\"\x10\xf01\x94\x02T\xef\x97p\x91\x13\x1e\xe8uB`A\xb2\x0c\xe8<\x8cA\xb4\xdck\x8e\xb1\xb9;\xfe0\xf8gv\x18\xd3#\xf3\x98NQ\xe5\x9e\x8aa\xf1\xc6\x9d\x86\xf5Y\xefI\xda~Z\xa0\xa4y\xeb_;\x07\x9f\xa6\xdb\xde\xa7>\xfb\xc7?\x90\xb6\x01EN\xad\x0d4\x04\xc1\xf8\xb8\x0c\xee\xc8\xe0\xfa\xdamt\x0e\x83\x8a!\xe2\x8d;\x0d\xeb\xb5\xceE\xd7mLx*\xd5\xf2+\xd4\xbc\n\xcd\x90\x9bE\x0b\xe24\xc0\x0f\x06\xbfb\xb71\xf6h\x9a\x13N\x1aD\xccR\xb8\xc8\xd4\x1b[\xbb\xca\xdf\x03\xc9\xca\x9bF}\xc2\xbbw\x1a\xf8S\xbd\x8f\xb4\xdb\xb8\xf9`5\n\x1f\xf3\xd8\xc4\xcb.C\xfb\xd9\xe4\xd3\xed68^\xb1\x9f}V\xb8\x0b[VZ6\xef4\xb2w:\xf7s\xb7QIqO\n\x1b}\x9a\xbcJ\xceI\xfa4\xcc\x88\xe7\x07\xb0u\xeb_\xa3\x7f{\xe3\x83\xd1\xee\xce\x83pg6\xfe\xf7\xfd\xcb\x9d\xe2\xef;\x0e\x7f\x0f\xf6.G\xfe\xe5\xd8\x890\xb0\x91;M\xf8\x8d\xd1\x0b\xdf\x9d\x98\x96\xbc\x89\x1b\x9d\xe7]8\x0d\xef\x951t\xa0\xfb\xf0:\x90\xfc\x0e#|f\x08xp\x1e\xdf\x16O\xebpzx\x81\x1e\xc9\xb6\xa5\x9d%\x8bEr\x0e+\xd1I\x0f\xb6u.\xec\xd53\xbc\x19\x9e\xd1:\xb2\xabr\xb67oV~\x9b\xb9Z\x13\xc7\x8b\xac\x1eR\x9e\x93d\xba\x16je\xae`\x8c\xe2\x1ew\x93\xc7_h\xc8:\xbeX.z\xc7\xd0\xf9LyS\xb0\x1e\x867\x17\xe5\x9b<\xc9\x85\xfe\xb5U\xf9\xda,I\x97!5\xbd8\xaf\x8cQ\xec\x00\xc3\xbb\xd3\xca(\xed\xef\x9e\x95\xef\n\xc4\xad\xa7\x1e\x01\x01G\xeet\x950\xa67\xb2f\xe6\\3\x91\xbdT\xcc\x0d\x01\xbf\x8c\xf4\xfd\x83Pe\xf4B\x99\xe0[\xbc_\x15\x9ay\x82\x97H\x16\xd306u\xackJot\x94MN\x92<\xa6&-:\xbbN0\x9c\x8fq$\xcal\xccl\x8d\xb9!\xd4eH&\xa1l\xcb\x8bx\xa6\".\x96X\x06r\xc1\xbe/\xb5i\x95\xcfw[\xbf\xc6\x94\xf1\x92\xf9\xeb\xfe\xf9\xa1\xc1\xc8\x0e\xd2\x00\xd7\xd0B,\xcc\x9e|V\xed\xaa\x9bdvhp\x08\x90\x17O\xef\xad\xd7\x11G6u\xac\xbc\x94\x80\xa7\xc8\x0fD\x7f\xc6/\xda\xed\xcf\xf2\x92\xb4\x88\x1b\xb8{H\xf7 ;\xde\xf88y\\bq\xf6\xe1\xf1\x80c\xe9\xf9\x81\xa1\xfc8h\xf5\xb9 \xb6\xe3\x13F\xd2\xd7\x01\x9c\x16\xb5#0\xb5\xfd\xfb\x00\x0e\xc75\xe1\xd5:\xf6R\xdf\xa4}E\xa7\xe6\x07\xb1\xd4 \xf2\xcfe\xf9 9\xf7w\x82\xd6\xc3,\"\x8b)D\x19\xe6\x0fY\xa5\xc9Y4\xc5\x13@G\xb1e\xa3g\xb6\xc1\xb2\x89\x7f\x85!<\xf3\xa2\x00\xce,N _\xd1\xc4\xc1\xc7\xf3\xd5\xd5\xd9\x00\xc4\x10\xe6\xe5\xd6\x99\xb7\x8d\xe69\x0c\xe1\x0d\x1b\xcd\xdc2\x9a\xe7\xcah\x9ew\x1d\xcd\xb4m\x08\x1fa\x08\xaf\xd8\x10\xea\xa5E\xd4\xeb\xa32\x84\x8f]\x87\x10\x96\x00 \xdbF\xf3\x03\x0c\xe1-\x1bMh\x19\xcd\x0f\xcah~\xe8:\x9aY9\x9aY\xdbh\xbe\xc0\x10\xfe`\xa3\x99YF\xf3E\x19\xcd\x97\xae\xa3\xa9\x1e\x89m\xe3\xf9\xdd\xe2\xb7$/\xe4n\xbc\xdfQC\x1eR\xb2C\x99\x1c\x85\xcd\xaf\xe0\x00~\xf6P\x85\xd6\xcb\x99\xb0Q\xdc}\xc7\xef>\xe5D\xd4\xcc\x17\xc9K\xcc\xf6w\x93\x1bKIf\xab\x07[\xdb\xfc~\x85!|\xf0\"\x0b\xb0qv\xbfv\x18\xe3\xaf\xedc\xac\x1c\x9emC\xfc\x05\x86\xf0\xb9}\x88\xbft\x18\xe2/\xedC\xac\x9e\xd0mc| C8j\x1f\xe3\xcb\x0ec|\xd9>F\x95\xc1j\x1b\xe1\x8b\x96\xa1\x1d#\xf3S\xb0a.\x03}!y\xd6\xa3\xd8\x1b\xf5\"J\x96Y/\x00\xceg\x8f\xfd\x00\xa2\xa6\xa1\xbb\xcd\xd7\x03\x14\xc1\xaam\xdb\xb1\xab\x82I/\xd0I\x82!\x0b\x06\xabV\x97P><\x12\x0fU*\xf0\x02\x190\xf6\xf4)\x13*\x03ap\xe7\xeb`\x1f,\xbb\xa2xJ.\xf6\xa1\xc5g\x90]$M\x93t_\x13/\xa7^\x97\x96x\xb0v\x9cP\x18\xe46\x94\xb8\x01Cx\xdd\x8e\xb47\\pA\x00\xeb\x86+56\xda\xbd5\xfe+\xcdl\nvNI:\x1a}\xbb\xbb\xb1\xc6\xd2 \xc2/\xa8\xab\xd8\xdf0h\xe9\"\xa0\x19\xbco],\x17BwE\x8c\xf2]\xc4\xbd\xae.\x96\x0b\xdc\xb6\xf8\x17\x166\xb2\xad9\xd7\xf3\xb0o\x98\x94/\xbe\xfd\xf7e\xc0\xbe\xbfq#%3\xd5\x1d`\xbdBO\x18\xda\xc7}\xcd\xff\x14%WD\xb9'\xda\x0f\xa7S\xf4M\x0c\x17?\x97O\x0e\xe0o\x8f\x0eX\xe3g$\xcd\xa2$\x1e\xf6\x06\xfd\xdd\x1e\x90x\x92L\xa3\xf8t\xd8\xfb\xf8\xe1\xf9\xce\xfd\xde\xc1\xe3O\xb1pl\x87\xdf^\xbf\x02r\x81K\x0c\x13\x9e\xe2\xf7\x84\xc0)\x89I\x1aR2\x05\x1e\xa4\xf47\xa3\xff\x93\xbc\xa4!LL\xa7\x8f\xa9\xb1\xbd[\x9f\xde\x7f\xf7\xe9\x96\xf7\xe9\xfd\xb6\x7f\xe3\x96\x05\xd9K \xc2\x10\xa2\xd1\xa0\x19\x8c\x08F\xc6B1\x16\x9eJK\xed\xf4)\xea\xcb~{\xfd\xea\x90\xcf\x8d;\x93\xb8\xf8\x80\xb0\x89$\xc2\xc3\xa8l\x8fo\x82\xe7i\xb2\xe4\x1bA\xb4\xd7\x9c\x91T\x8a\x99$\xbb\xa4M\xb2K\xb0\xbcm\xcd\x13&)=a`_\xc9y\x06Pxi\xaaYP\xac\x8e_g\xa2\x0eI=\xa9\x92\xbc\xd8\x12\x94\xe2\xfc\"\x99\x84\xac\xa9~\x86\x8d\x1b\xf4K\xa5\xde\xd2\xb4\xb5z\xa8\xa47\xee\x11y\xf0\x90~\x96\x9fd4\xf5\x06\xbe\xac\x17tS\xa7\x8d\x01\xd5C=\x85(\x86\xd8\x87\xb8^>%\xe5\x8e\x8a\x18g8J\xc7\xb2\xc5!&[\x1bM\xc9$\x99\x92\x8f\xef\x8e\x8a,]^:\xda\x1d\xfbc,\xdd;@u\xa1\xf6\x9d\xc1\x98\xdbU{.\xf8$\xb7us\xcd\x9a\xd9l\xec\xb4\xd5h\x15_\x86+\x07\x7f6\xf19\x12\x83\xea\x8c\x88\x0f\xdb\xd0\x1b\xa2\xb6\xb6\xf9\xb4\x9a\x99T^\x97~\xff\x8f$\x8aqy\x9aS\x13\x19{\xec\x83\x92\xf3\xa9d\xdd\xa0\"n\x17K\xd5yD1W\x04\xd0\xcb\xe9l\xe7~\xcf\xf7\xcb\xbb\xbd\x930#\xf7\xee\xe8\xc6Pf\x10jv\x9d`\xb8Y\x94\xc4\xd9{|\xcb\xe4\xb5\x13.V\xf3\xb0%\x97\xacz\x154\\j\x13\xe7=\x1f\xb7\xd0\x02S\xc1\x85)\xf1\x88\xfa\xccpd\xeb7\xe6\x92\xd0y2\xbd\xf2h\xf8\xe7\xa6\xf1\xc8\xa7\xceLDs\x8c4<\xfd\xb3\xc0Y\x1b\xb2\xf3 5\x98Y\xcb4\xe5\xc6\xce\xe8\x9cT\x94\x8c\xeeQ\x0cF\xbd\x91\xf4\xe6\xa5F\x0f\x11\x85m\xe1\xa5oz\xe5\xdf\xa2\xcc\xd1(\x0e\xd8\x06\x0dt\xfb3\xf5K\x9f\xfa\xff\xd9\xdb\xbdu\x1a@o\xbb\xe7\x8f\xc5\xfe\xd4-\xa9\x91J\x11\xdb\xa6\xd6d\xee\xaa\xac\xa4\xc1\xb1\xa6P\x9a1\xc25- W\xac8\xe5\xb4\xb9\x8ct\xf2\x18\xa9\x8e\xbc\ns\xa9\x143\xa4's\"\xc0:\x8f[d\xcaT:&\xcc\xd9\x98\xd4(\x8d\x96\x9e\xb2H\x9f2\\\xa3c\xb4\xd8\xf4z\xb6\xe1\x1a\x92\xab9\x0d\x93\xc1\xec\xb8\x84\xd9\xd7\xa6{Y\xa0I\xe7\xe6\xd44m\xe6\x9b\xb0\xecd\xf1\xd1\xad\x7f]\xec\x14\xccu\xeb\xb2\x05\xc6\x14t\x7f\xe6\x08\x85\xfdgS\xd8\x976\x85\xf5h#\xecb\x1ba\xf5r\x9f\xca\xff)\x1f\xf0\x94\xdfl\xa7x\xf7\xee\xfb\xfd\x1f\xf2\xd9\x8c\x08\x7fq[\xf5\xa3\xb3\"sSq\xf2\x95x\xa2\xa6\x19\xacX\x8c\xc0%S|o\xc49U\xfe\xe9\x18\x91:nT\x8cr\xca\x06\x89\x94\xae\x1cWjcD\xf59\x0eAaO\xf9T\x94d\xbc\x8bhBL^\x97\xc4\xb8\xbc<\xa4\xaa\x9aL[\xe4K\xe4\x14@-1\xe1c)+S.\xd9zZr\xfdP\xecx\x99\x97\xbe\xaf/\x9b%\xb9\xf4-\xa6\xd6\x16\xc3\xb2\xc5\x17\xae-F\xd6\x16\xb3\xb2\xc5\x1b\xae-&\xed\xb3\xbey\x13\xb6&e\xd3?\xba6\xadI-\xaf4\xbd\xe5mQ.\x87\x8f\x16c\xb7\x06C\xd7\x06\xeb\x898L\x0df\xae\x0d\xce\x1d\x1b\x9c\xb4\xaf\xf8f\x83\xdd:57s\x1d\xdf\xb41>\xf5\x17\xf1R^\x83\x85x\x91\xfc#\xe1\x7f\xc4\x8a3+\xcf\xd5\xcd\xee\xbc$kL\xcf\x17\x8a\x17\xe2)\xb9\xc0\x1b\x19\xbf\xf1$\xcb\x92I\x84\x99!\x00s\xb8\xc4e\x00\x1c`x~\xdc\x97m\xb0\xae\xfbe\x0bl\x00\xfd\xf7\x04k84\xe9\x07\xa6\x19\xf8\xfb\xdf\x8f\x8f\x8f^\xbf\xfe\xf8\xe1\xc9\x0f\xaf\x0e\x8f\x8f>\x1c\xbe\xc3?\x8e\xff\xfew\x8dji\xd5\xfc\xe2\xe5\xe1\xef\x87\xcf\x0c\xaf\xcf5\x1d\xbcyv\xf8\x9b\xf1\x83i\xf3\x83\xb7\xef\x9e\x1d\xbe3~p\x06C\xb8\xdb\xbc\xbd\x86!\x0c\xe0\xd1#]\xb5\xf3S\x18\xc2\x1av@\x93\xaa\x7fi\x90\xf7\x8f\xed5\xae\xf7\xeb\x89$A\xcf\xf9\x9f\\\xa5\x19\x13-?o9\xd8\xb9q\x18\x0b\xbb;\x92\xe4\x0b}\x8bT\x1c\x0dE\x83\xbbn\xdb\xe9=O*\xaf\x7fxh9\x89D\x84\x9bF\xaf^\xa9\x0e%\x0bH{\x98x\\\xa88w\xb0JH*r\x9e\xcb\x94\x05<\xd3\xc6\xeeCLw\x11?\x84h{\xdb\x87t\x14\xf1$\x89\x11\x13\xe8\xcd\xee\xf5\xa9\xd3l\xed\x01\x0d\xaa;:\x06\xa2\n\x98f<\\\x82\xf6\x8f\x8fy\xe9|\xe2\xfd\xc1OW\xf6\xc4\xa9\xe3\xb7\xd6Tb\x85\xf5A)\xe9a\x13\xc1P\xb9\x04\x8f\x1f?6\x995\x84\x92j\x1bb\x11C\xbd\xd9\xc0\x9d\xbd\x07w\x1e\xdc\xfb~\xef\xc1]\x9ca\x19\x99\xf8&|\xa3o\x85MZ\x93\x92\xcf\x04>\"\xcax#\x90\xb7Q\xf1\xe1\x06\x9c?l\xc5\xf2\xeb\xf9\x9c\x0dm|v\x90\xda<\x19jP\x16\x9d\xde\x92Q\x91\x14\x1e\x0da'\xae\x14,\x1cJ\xd0\xd5_&\xf0xXW\xc0\x9a\x06v\xd4\x96\xbd\xf1\x83\x18\xb9\xe3\x86}\xed\xda^\xbd\xaa\x8f\xa1\xbd\x0f\x0e\x80\xab\xc5i\xc4\x986\x97/\xb6\xba\xbf l\x03\x1a\xc5j\xb1\xb4\x8cC\x92\xe5\xe2\x99\xbc`\xac\xde\n\x02\xbf\x9f6\xabT\x83pd\xd6\x9c\x07\xef`\x08{\xcd\xdbo\x9c\xb3\xb6\xf3M\x9d\xa4\xcd6^\xf1\x93N\xbe\xa09\xda\x9e\xc1\x10\xde0\x1cye:\x02\xbe\x1a\x08\xf6<\xca0\xbb\x8833\xfe\\\xae\x94!\x99\xa7\xb4Z\x94\x0b\xc5\xb6\xe0\xa0\xb2l#\xf6\xbd\x85\x8a\xc2\x01\xa4\xc5\x19\x12\x89\xb2\xc0\xd6\xd3\xd0\xe0\x078Mb\xd3\x89\xebH\xab?\xda\xa8\x82uH\x1c\xfd\xac\xe3j\xad\xdcc\x18\xd4\x0fv\xees\xebWW6\xf6\x8b\x9d1\x00S\xd5h\x8a8\xe3\xd4\xc5\xefv5\xe0\xaf\xda\xf4\x1d\x05-\xe7Un\xb5\xc5\x96\xf5\xdd\xfdj\xef\x8e3(o\x90\xd6\x8e\xde`\xedR:ze\xcaM\xa4\x9d\xbb\x92\xb7\xdaiD\xbf8\xc0X\x13\xcc,\xb8\x14\xa7.^Z\xbb(\x92\x01\xa8G\x8e\xdc\x8e \xcf\x95-\x85\xe8>M0]\x83\xb5\x80\xb5\xbc$P\xd1y\xbd\x12\x167\xac\xd5\xe6!\xe7@\xa85\xc3\xfb\x96\xa9^\xd8\xe1\xc5\n3\xd3q\x06\x0d\x92\x14\")\x15 5K2\xe3[.\x0b\xd8\xd3\xcf(\xdd\xf0G\xfb\xe8.o\xeaV\xbb\x8a\xecj\xa6\x083\xc0\xfd\xc5\xb7\xc1\xbdO\x13\x94\xc5$\xc4\xc5\"\x84\xcd\xb5\xa0\x98\x9f\xfd0\xa6\xe9\xbax\x99\xba\x8e\xf2\xc6\xb7\x8dR30\xa2\x0e\x84\x8dSH\x91\xf2V\xe8<\xb6\x1f\xadc\xf3\xbe}pr4h\xe0\"\x14\xef\xd7F\xa6\xfe\xfa\xaa\xa8\xaa\xa8&\x1f\x81e\xb0\xbd\xd1\x918\xa0\xc75\x05t\x00_\xfb/\x0f\x7f\x7f\x0fCx\xca\xfe\xfe\xe5\xc9\xab\x8f\x87\xec\xd7\xcf\xec\xd7\xe1\x9b\x0f\xef\x8e\xf0\xe7\xbb\xa0\xd2\x7f\x14g+\x9e\xed\xbc6\xaa$O\xab\x99\xb9m\xf4\x85\x1d\xf0\xe6\xdc\x0bJ\xcb\xa3g\xe3\x0em\xd6\x1b\"\xdeK\xae\xb7x\xd9Of\x8e\xed\xbc\xf4\n'\x92\xc6\xc0^V\xa7L\xbe8\xb6\xa9\x1b\xdb\xcb\xab/*\x82\xef\xf8\xb84\x8e\xb2\x91\xfc\xbb\x17@\xef\xb2i\xcfQ\xfb\x99\x84\x939yG\xb2\x962\xc7JW[\xbc/\xfc\x10d\xc5\xafB\xd6\xfb\x18\xe3\x83)\x17\x06\x957\x87\xfc\xc5\x12\xeb\xcb\x8a\x0f\xa2\xfc\x99\x14\x1c\xcb\x8f\xc4\xd9\"^\xb0M\xa3\xe8\xdf%\x86HLdB\xcb\x82d\xbc\x02\xa8K\x0f\x89S\x00\xbe\xe8b\xd6\xda\x05\xf1^\x04\xf0\xd2\x0f\xe0Ee\xf1%\xbdu\\\x13=\xa6\xdf\xe0-\xdfp\xc7\xf4\x1b\x16L\xbfQ\x19`II\x1d\x9b\xd6\x0d\xf1\xc65#\xfc\x88!\xfc\xb8\x89\xf07\xae\x19S\xea\xb5\xdd\xf5=|\x13\xa64\xbb \xde\x8f|=\x7ft_\xcf\x1f-\xeb\xf9c\x8dr\xd1o[\xcb\x97\xfd(\xe3-D\x94\xfd\x92\xda[\x86\xdeB]\xcb\xc6\xaf(ro4\xb5\xb7?\x05\xf0\xcf\x00~\x0b\xe0\x1fM\xa5\xe9\xfb\xc3\x7f\xa0\xc2\xd4$9Rj\x11\x1d\x8fCQ+\x83\xd6\x88M\x17\xf6\x95\x18z\x90\xfc\xa50.}&\xebL\xcbC\xf2\x91$\xb26\x88\x1c\xca\xf1gQ\x0b\xab:4\xd2eh\xb1u\xf2Q\xa9\x9f7\xcc\x9f{\x16:+\xe8\xd2\xf6\xee\x84\xe1,\xa8\xdd{*\x0e\x83zm\x1fCG\x91\xa1#y\x16\x95\x06\x8c\x7f8\x1aX\x90\x1b36\xf8\x13k\xcd\xfbI\xe8Z)\xf5F\xe3Ff\x16}\xbby\x0brh\xd2\xe0\x88.\xa8\xdf\xe4\x9a\xbf\x94o\xa4\xfa7~(\xdf\x88\xf5oh\xa5\x9c\x83R\xc8)TOf\xcf\xbe\xabK:\xa3\xcf\x01\x9c\x8dAd\x8a\xed \xf1t\x92Y\xc3\x16\xa0gza\xee\xdb\xa7\xc7\x05\xb9k\x9aEfG\xf2_j\xd8\xa2A\x0f\x0d>\x14\xab\xeb4\x04v\xc29\xa9\xcb\xa8`\xcd\xf4@\x8dL\"xa\xe5H\xd8\x01QZ6\x06\x01\x864\xef>\x84\x1c\x1e\x0d!y\x08\xf9\xf6\xb6\xa9\x11\x10\xe3\x08\xd1S8f\xa2\x15\xec@\xced+\x83\x7f\x15\xc8\xc5\xe6z=\xe2\x85\xa3\xc18@\xc5]8\xda\x1d\xb3/\x03P\x02\xdas\xd8\x86\xa6\x12\x0e\x1a\xe2\x97\xbc\xe4g\x8d\x87\x96\x04s\x0dV\x99g\x83tZ\xa6\xd9\x9f\xbcL\xda\x152B\x96\xaf\x9c\x0d0\x0c\x1b\xbfzV\x96B^\xd2\xf9\xc3}a%\xf0\xb7\xb7\xe11:W\x9b\x1b\x077u\xa7\xbc\x8cjOy]\xc2>\xc7\xcc\xb9P\x1f\xa9i8s\xfbp\xa4E\xbe\xe2w5\x94r}\x8e\xf4z\xa8\xe9\x93j\xbe,\x03\xb8\x05\xbb\x85?\x8b\xf0{\xf1\x03\x89\xce\xf2C\xdb\xc1\xf6\xcfbh\xff\xd4#\xce?\x85\xcd\xa0e\xab\x99\xa0u\xda\x02-\xaa\xaa \xb8\x8a\xc0\xd1WhIm\xceB\xfa\xa5X\xd6\x96BiC\xbf\x1a\xa7\xd4\x13\xaeV\x01\xf4\x9e\xf2(\xde\x8c\x92\x15\x84\xf0.\x8cO \x9c\xaca\x17\x83\x1eAX'w\x83\xea*\xc9\xba#\xb8V~\xa0$\x01\xe0\x9eo\xa2\x1a#.ax\x92\xa1\xeb!\x81G\x82cco\xef\xc4\xd2\x84s\x8c\xc5\"T\xbd\x1f\x89\xa7\x8aj\xf3\x18\x87\x86\x83U\xb1FE\x0f\xfc{B\xa2\x85\xe7\x11\xd8a\x04\xf8\x16\xc4L\xb4\xf2\x99l\xde\x0dw~+`\xf9\x9b\x1ew~\xfb6\xdc9\xd6\xeb\x129\xbe(*\xa5'\xa2\xfaa\xdd2ah\xf6\x84\xda\xdcL\xcf\xadO/\xc4S\xf5\xa1b\xc6\x1a\xfdc,\n\x01\x11\x8f\xd2\x00n\xb0\x95S\xe3\x1eN\x89SIW\xc9\xb5\xb3U`\xe4\x91\xdb\xb4KM\xfb\xe8\xad4g\xf8c]\x05\xf3J\x9f\x9dL2\x15\x7fY\xa5G\xe1![Q-\x95\x1e\xb2CH\xb9\x8b\xac\x11W\x84\x8a\x88z\xf1\x88Q\xae\x14v\xd0\xa3+\x1a\xa3\xf0\xc7:*wf\xc4P\xd1H\xb5\x1bu\x1d\xb4\x93u\xb3\x0e\xe9&\xaa\x9dBc\xf2\xfa\x89\xea56\xdd\xb45\x05\x10\x1e\xa3\xfa\xc3\xc6\x819i\\\xac\xda\x16\xaei\xa1\\\x02/Wf{\x9b\xad\xcd\xf6\xb6C\x14 CuB\x03x\xc1\xe8\xd6\xd5Q\xbd\xee\xe5\xaaC}\xae\x1f\x1eQ-\xcaW\xfa\x9e\x87\xee\xf1lJ\xd3\xf5(wM}\xa2\xeb\xdcX\xbcS\xbe\xb3JSU \xd8ju\xa7%|\xa7%l\xa7E\x0f!1+q\xcfDY\xbc\x14\x173\x82\x1dH`\x1f\x12\x83\x9e\xaf\xb63\xf31V!\xae\xee\xc6D\xab\xb45\n\xa3\xcd\x14\n\xd7\xb5=\x05\xb8\x8c\xfbS\x01\xa1qw\xa6\xad{8\xb9\x8e=\xdcm\x15$\xe4P\xd3\x1a\xfdu{>g{>w\xdb\xe3\xca\"\x8e\xa6\xe5!\x17\x8bC.\xd6\xee\x8b\xc2[\xc5a\xad\x19*\x96\x121\xaeeEhR\x84\x0c\x03\xf7,\xb1\xe5w\xafj\x96\xb5\xd4\xb02\xe8$\xbex\xb1A\x06-vq\xf4\x10\xb6\xbc\x08O\x05\xb5*#(\xb9\xbc\xbdHT]\x84t{[\xec*]\xfdR1\xe5F\x8e -LK}\xf5\xb5\x025I;C\xd5\xa0\xce\xf9\xa2j\x89\xf9v\xf9hh\xd6\xb0\x02\xdd\xb7\x1aQ\xd6\xa1E\xcb\x81\x8b\xc4\x9d\xd1q\x0f\xe0\xd2\x08\x15\x9e\xd3F\xf0R\x81\xf2\xe9\x7f\x01\xcaW\xea\xc8\x17$\xb0\x08!\xe0\xb6\xaa\xa6\x83\x80z\xa0\x14\xc6\xa8\x87\x0e\xcc[4J\xc6\x01#T\x8dC\xc206\xb6KbEK\xc4w\x89\xb1\xf2\xbc\xa4\x9b\xb1M\x9b\x84&\xb6Q2\xe6\xe1\x90\xc5\xd8\xf2\xea\xc0NR\x12~n.\xa8 \xdb\x1a\xc7\x96vy\xffc\xbb\xaf\xb6\xb0F\x82\xa6[l=\x10\xafc\xef\xe1J\xc0\xe3\xf2XmS\x18\xb6oT\x90p\xe3En\x8b\x8dkQ,\xf2\xa0<\xb1\x87\xb5\xafY\xad\xcb\x92\xfdMG\xee\x0c\xefZ\xd0\x805\xbd\xba\x8b]M\xd0\x86\x03\xe8\xbd#+\x12R\x18\x8d{\xb0_\xfe\xe2^\x10\x8aZh\x1bz\xe5=\xfc\x96\xdd\xa1\xd1\x92d\xd0t:^_\x9d)\xd71\xe1|\x08\x1a\x06\xbc\xd2\x8f\xac\xf4\xe3\xca\x85O\xa9\xaa\xf8jFe\xd5\x9a\xc7\x94\x05.\x13\xa9\xec\x1f\x06*#\xca+1{|\xaa\"U\xd2\xba6\xb2\xd7\xa2\xba\xe4\x0e\x0f\xa6\xab3\n\xf5\x91\xa6\xe4\x8c\xa4Y\x177\xed\x16\xb8N\xc9\xc5\xdb\xd9\xd5\xc1\n\x07\xa81\xdc\x19X\xbbY\x84\x19=\xba\x86\xaeJ\x0cm\xed\xf2\xea\xc2\xd4\xeeC\x88\xe1\x91\xb2\xc4\x10;i\"*\xc3\x8d\xeb'ZlUB\xc4Ns\xe9.\xe5tbU\xbb\x11k\xc9f\xc2#\x88%\xc5)Y\xa0X@\xc27\xd6\xd9\x83\xeb\x12?\x1c(l\x05\x9a\xc2H\xe9\x88\x87\xb4\xaaz\x87\x83&f*S=k\xda\xfb\x19}_\n\xfa\xbe\xbcf\xfa\x8e*cI\xde\xf9\x0f\x85\xbas\xed\xee6\xf4\xfa\xfd~y\x97\xc4S\xd8\x06O\x08\x15\xf3B\xcd{\x00=8YW>'+\xcc{\x84I\xe74'\xc1\xf2zO\x029\xdcR\x17 \xdfU\x87\xd28#\x96W:#$\xe7\xe0Q\xd8Q\xfb\xf6\xe1\x96\xd2\x9fq\x7f`\x80\xf4.7\xc8+d\x82\xdf`k\x84:\xf1\xd9\"\xd1\xd8\x1ejCv>wj\x87J\xd1\xa9r\xb8\xa0K\x01\x9e!\xe5\xd3\x80\xdb\n\xf0\x8c)\xef\xfa\xf0hX\xf8\x96.\xa9\xb7\x1b\xc0\xae/\x8e\xa7\xa5@\xeeSB=\xd5* M\x06\xec>\xd1\xdcG\x905\xcf\xae\xe5U\x0e\x9b\xb3\"\xaa\xb2\xb2B\x0d\x85/\x18\x031.\xc3\x1c\xd4r\x07V\x87\x03\xe1Z\x89N\x96\xece\xeeSa\x19((x\xba\x0b\x1b\x93s\x14\x1e\xa1qY\x8d\xd3\x8b\xe1_C5G\xd1w@\xfd\x87\x0c1\x94\x9b\x0f}\xc0\xd7(\xdcR\xdf\xb5\x12\xdcC\xea9\xa5J\x8f\xea%]\x145b\x99\x9a\xffg\xaax\x99\xeb1\x0d\x94UxEG\xd4\x9e(\xb7\xea\xb1\xf2\x96ao\x00o8\xac\xdf\x89\x9c\x19\x14\xd3\xe1\xc0+\x9e\xe8\x1c\x9f3*\x8e\x8d\xb3\x83\xef*Y\x16`\x9fw\xd6 \xc7\xe7a6\x7f\x9aLU\xc8\xc8[:\xe5bT\xaf\nV~\xe8\x08B3\xe3\xf9\x9a\xd6\\M\x11~G\xdccM\xadPji\xa3\xfe5\x1d=\xa5c\xa7/\xb7>\x1b\xc7\x0d\xa6\xc6\xfb\xa2\xea\xc1\xfa(;\x8c\xf3\xa5\x08\xc0Bw8\xdd\x13\xa7\xb1\x98:k\x07\xaf\xfa\xb5p\x98\x8c\x93)\xf9\xb0^\x11@\xd2\x9e\x9dG\xbc\xfeYq\xbf\xad)vM\xc2\x8c\xc0`\xbf\xf5=Ph\x7f?\x8f\xa3/99zf\x9e\xa3\xbc\xb0\xf9\x07\x1d\x9b\x9f&\x13\x0c\x18>\\\x10\xf6\x0f\x9fl\xedf1\x06k\xd3z\xa56\x88-\xa5\xac\x96\xf6=\xfd\xd7l\xb9\xb6\xb7?\xd0@=\xfan\xc2\x07\xbe\xf7?\xe0\xde\xb7\x84\x88\xbc\xa6>\xc3\xfa\x8c\x18=\x1c\xc1\xc1\xd1\xb5\x8aB\x7f\xc8\xfa\xc8C\xfc\x81.\xcfu\x8f\xc1\xde\x9b$\xde!<\x95q\x19H\x98A\x98\x12,\xfa\x86\xd9\xb5\xc9\x14\xc2\x0c>\x93u\xd67\xd5=\x90\xdd\xb3\x0d%\xa2\x8dy9\x89\xd2#$\x80\xa7\xd4\x14W\"/R\xec\x9b}\xd8\xb2\x04x\xb1k\x92\xc4\xb3\xe84w|\xfb<\x8d\xa8\xdb\x9b\x82O\xd7/>\x80\xb9\xa4\x1e\xa8\xe5\x0d+N\xf5\xddH\x86`\x93\x95H\x12\x85\x83\xd7}\xe0\x1b\x1b\xb2\xab\xdb\xd4K\x95\xb5\xdd{\xee\x87\xab\xd5b-\xd8xCD\xbfz]\x06\x162\xc9\xce\xc0\x16\xc8\xb6\x13\xc1\x8aSzI\xf2\x1ax\xff1F\x08\xd1\x042B!\x84\x98\xed\x83\x12rr\x8c\x90\xc4bOXQ\x9f]T\xce\xc1<\xfb\x0e\xf4\xc4z\xeaw:\xed\xa5\xf2\xb5 k\x8caP2\xdah\xf3\x01\xd4\xa0\xc5\xcb)\xb3&y\xfddT\x93\x96\xa5y\x18\xf7@\xa6}G/\xd2\xb7\x06\xde\xbeP\xc7\x10\xce(\xa9\x16\niiG\x03\x05\xbep{\x00\xdf\xf1T\x85\xfd\xc9\x829\xf3Ld\x15\x16\xd6\x97)\xdc\xbdu\x9d\x11\xfcW6_r\x85\xa7\x92\x01\xeau\xb82\xa6<\xfb\xfa\x8d\x96\xc5\xe34IJ\xcd,\xfb\x81\xa2s\x11K\xc3\xf36\xf9:\x93b\xa5\xeb\xacS\xd7\xffP\x93B\xd9\xe7\x94\x11z\x14wh\x1a'\x92\xaf\xa6!%G\xf8\xf22h?c\xcd\xdc\x92}p)Y&g\xed\x92\xb6f\xd6K{\xc3S\xb2 l\x02\xaeM7f\xed:\xe5e\xd7)\xf3N\xea\x0bbO\x1c\xcdE\xc8F\x89\xcb\x03\xe1\n\xe2K\xe3L1\x81\x11\x1d\x8bF\x1d\xc6\xd2D\x0f\xc3h0\xd8\x15\x9d\"E,&Gq\x8b\x8flA\xa2]\x12I\x9c\x898P.\x80-\xcd:\xd1\xbc\xd5\x17\x8f\x91\xbb\\\xf8\xe1\x99\x89\xe2\x99H\x19\x93`\xf0Hk\xc5\xd8\x0c\x86\x10y\xb6\xb2\xdcb\xb92\xbe\\\xc2Y\xb7\x19C\x06F\xa9\xe3\x94z \x03\xb2\xc8\x1b\x9c\x11\x1a@/\x8ay\xb5\xfb\xcfd\xfd3V\x883Cf\x82%\x80-\x1e\xa8\xec\xa5\x99\x98\xf2\x92M\x19\xa9\xd5\x84\xed'\xf3\x07X\xa0\xd4\x9b\x95\x0bhU\x94r\xd6e&f\xcf\x7f-\xd9/\xb1\xdb\xbd \xc3W/)y\x19\xe2\xe3\xd91 `\xa1\xe1\x01\xc4\x9e\x8fc\xd4\xe9\x1a\"\x1eE\xdfi\xd1\x9b\xe0\x9a\xea\x96\xd9\xfa\x0e\x98,Hh-J\xa44\xdet\x8b\xa1\xdc\x1fB\x1c8\xc9yL\xd2\xa3gp BaE\x0c\xe3n\xa0\x9e\x14CQ\xb4S|\x83\xc1\xfb\xc3\xf2\xac\xe0w\xc3\x05\x15\xf5N\xb6\xc4M_pw\xd6\xc9,Iz\xda\xaat\x90\x90\"\x02\xae\xb2ks>\xc0f\x1f\xbfF\xd5\x92c\xb6\xf3\xa4\xe8\x08\xfd\x97\xea|\xd2\xa0\xe9\xc8\xd1\xec\xaeJ\xa0\xec\x86pM\x0fFl\xa9\xd2L\x12 \x84\x03\x07\xad\xaf\xf8\xde \xf0\xf3e8\x90\x7fI\x1d\x0d\x12\xd5}\x88Gj4^\xb3\xa8m\xcb\xf1\x81M>#\x18,\xdbi\x9d#\xd2m\x8dY\x1fN\xeb|%\xd0\x17\xc3J\x88\x87b\x85\xe3\x88\xfe7\xa2\x02\xae\xd6\x81\xfa\xebzQ\"KR\xea\xca\xe7\x1c\x11\xef\x17R\x98\xfd\xdb\xdb\xfda\xdd\x81uT\x1b'\xed\xedWd\xa0\xd6 \x14\xb2\x16[\xa90{\xcdu\x11:\x06@.)\"\x16\xe9\x9f\x87\xd9\x13NO=\x1f\x8f\xa1\xe3c\x12gyJ\xde2z\xedU\x89\xb7d\xa5\xac\x03/zw\xdc\x83\x8d\xf3\xa1zn\xa8\xa3a\xa2\xd8{;\xd8\xc2\xecHjb\xba\xf5\xaf\xf6\xd3\xb22\x05\xc8\xba\xf5 \xce-k\xdb\xdd\x1c\x9c\xa4F\x84\x9c\xc3\x0dw\x99\xa7\x93\x17\xda\xb7:1+\x87{\xe1m\x83r`3\xb3H\x0b\x11\xe1\xc1v\x1e\xc1\x043\x043\xca\xe8l\xee\x01/\xfb\xd4\x02\x01e\xb5[\xf7\x96\x9cI\xc9\xe0\xe8\xb0\x15\x0e\xe0\x9f\xb4dmT\xb6&(\xf3: K\x83\x1c^\xad!%\xf7\x83\xca\xe0\x0c\x04\x83\xa3\x99N\x941\xc9}\x08\xcf5\x9eC\x1fi\x00?\xd0f2\xe0\xd7O~6TO\xfb\xc2\xdeV\x81dR\x0f\xfenN\xfc\x81\xc3oNH$*j\x18\x1f\x8c5>\xac @\x0c\x9d\x9cDt\x89\xe0\x90\x90\x8f\x13\xee\x82\x1c;\xf5\xf9\xcbU\xfa\x9c$yL\xaf\xdc\xe5\xcb\xabt\xf9\x99\xac\x7f\xe4L1i@\xd7\xad\xdb\x17\xd7\xd7\xed\xda\xb9\xd3\x1b\xed\x9d\x1eS^j\xb4\xdc9E\x84M\\\xfa6\x87\x93\xcf\xc8\xbc\x14\x14\xe5'\xea\x89_n\xda\xd0\x1f[S<\xf2\nH\xa6}\xac\x0b\x025!\x0f\xad\xa9,$fGAA}\x10u\xa9FM\xd1\xd4Q\xf8X\xe4\x0c9\x84\x08w\x9bN_a\xc0G\x11%^\xe8\x97\xf8\x82\x06\x10Zy\x15&Qq\x89\xcd\xd3~\xba\xcf\x10Q\xac'e\xfc\xc8\x85\x17\xfa\x01\\x\x0cU\x18\xc4_\xc8\x1c\xae#\xf6\x99k:wB\xec;\xbeVy6\xf74\x9eEF\xf2\x92K\xa0En@\x8e\xac@.v=zm\x95j\x95\x9b7\x01\xb3\xb0V\xd4+<'c\x91\xd8\x97o\x7f7\xce<\xb1\xef\xeeR\x9433\x15\x002\\\x0cu\xf8Ue\x1a\x8e\xb7\x92\x8c\xba\xf2\x9c\xab\x84\xcc\x9ax<\xb9\x8a\xce\xadjx\x9e\x8d2\xf2\x85\x1e>jY9\x13@r\x97e\xe1\xdb\x1c-Cq\x7f\x16\xb1\x93\xc1\x01\xfd\x8a\x8f\xcb\xc4\xb9\xcdA\xfa\xbeb\xedb\x07\xb2\x9af\x17\xe9jy\x8am\x18\xa9\xc0\x94\x87\xca7W7\xb5\xa7\"\x1a\xaa\xf8\xc4\xb6\xe2\x80&pq\x1e\xa5U\xabi\xab\xf7pE\xfe^\x8a\x1a\xa3\x08x\xec\xd2\xf8\xad\xc6e\x02o\xabA0\xa6\xa5\x93\x17\x95n\x19\x86\xf4\xb1\x97\xd5z\xd2\x05A\xc3\xb2\xd2\xf1(\x1a\x17\x0e!\x9a\x81bf\xf2\xca\xd1\xe7\xc5\xa3]G\x89#l9iA\x84\x86x\xf7\xef\xde\x7f\xf0\xe0\xf6\x9d\xbb\x0fx,\xcf\xce\x10\x03ax\x1c\xcc\x9d\xdb\x83{w\xef~\x7f\xef\xae\xef3f\x0f\x1f\xec\xc1M(\xbeQ\xee\xdfa'\xd3\xde\xdd\xbd{w\xee\x0en\xdf\x0d\x80\xc2\xb6h\xea~\x00\x83\xbd\xefy\xf3\xf2\xde\xe0\x9e\xdb42\xe2(\x85\xa4\x02\xc5\x0fm\x15E\xa3\x11\x19\x0b\x01\xa3\xd6\xbb\xfa\xeb\x0b\xba\xba\x08\xde\xec\x0b\x15\xe6p\x18\xb2\xbf\xb9\x15.(\xffD\x9dz\xf1\xd2Q\x1c\xc0\xef-N\x11\xe6\xb9T\x0eCUz\x17\xc7\"g.\xa2\xf2X\x84G\x90\xf3\xd3\xd1HH\xa7\x88\x9e\xd1(\x193\xd4)s-\xb2\x1b\x03\xe7R\xe6\xb5Y\x19\xcd\xf0*\x1fi\x9d!\x16\x1b\xe1;6\xc0\xd3\xb9:\xdd \x9f\xee\x0c\xcfc9\xdd <\x02\x8cm\xda\x9abB\xe0l4\xc1I=\x84\xc9\xf6\xb6\x81![\xc0\x90\x7f\xa7\x17\xc8\x16p\xc0\x9b\x19\x8cq0\x11\xec3\xeeWQN\xea\xbf\xe3|\xb0\x17\xa2g\xd4\x02]\xc9.\xbc\x84IQaIH\xb3\x96\xec8\x18\xc4\x81\x0e~[!\xfb\x7f\xe1\x9a\xf0x\x08\x13]\x98\x8a\x15y\xe4\xc5\xa5Z\xe9\xb1\xf8\xdebp\xaf\xa0\x9b\xe0\xfah\x00\xe8\x88\x1a\xc0\x88u4\xf6+\x1c\x19q\xe1\xc8\xe4%\x9d\x0d\xc8\xc8\x94\x00O^\x11b\xb5 \xff\xb4\"\xa2\xe6\xa8h\xc9\x8d\xd5?@\xcbE\xc9K\"\xbb\x9e6\xb3\xae2\xabQ\x9eMa\x05\":LQ\xf0J9\xd3\xd81\x93\xf7V\x0c\xb7\x90\"em6\xff\x03\xe4\xaf'\xc2\xf6\xbf\x03\x038\x80y\x7f\x95\xf0J\x10\xf3\xd1\x84Q\xa3\xc6\x8d\x11\x1b9\xe3\xc7\xe7\x9c\xc1\xe4\xbf\xfd\x00{\xf6j\xda\xbfyi\n\x97\x02s\x00\xf36\x96\xf42\x80_\xafL\xce\xb4\xd1e\x88]\x86\xcd\x8aB=\x13W<\xafZ?\x9cG~R\x94}\x0c\x9a\x91D\xd2\x10\xae\xe95\x126\xd60\x93snr\xee\xae\x08\xcdF\xe5\xec($\xfc\x11fF\x1e\xf38..#\x11\x1d;Q\x07\xcf\x95\xe9b%3\xb4L\x00\xfd\x84z\xa9 T\x8a\x80H\x04\xcb\x13#\x90\x88E\xaa\xcc$|C\xfd\xf3I\x15\x86\xfa\x97f\x18S\xb95\x04o\x027A\x87\xdaH\xd7\x90PGue\x8e\x96\xa0J:\x1d\x12\xde$\x02_\xdf\xf9J\x8e\x10\x97K\xff\x0e\x1a\xdd\xe1\x00V\xa3\xc5\x18Z\n\xb1sE\xd9\x9c\x9b\xc5\xf8BW\xd7J?;\x1e%>w8(8\x1c0\x94|\xa5\x90\xf7\x99\x95\xbc[\xdc\xbc*\x15\xbf\x04C\xc0\xf63\xaf7\xb3\xf6\x03\xc4\x8c\xdd\x87\x82\xd5\x8f\x1fB\x88i~\x18n\x0ca\xe0C>\n\xc7\x88\x067Q\xb3@F\xc9\xf6\xf6\xd8R\xb3\x0e\x14\xa1t\x94\x8e\xb9\x8a\x8b\xf5\xc8M\"\x98\xe3A\x1f\xcc\xcf\x1e\xaf\x02\x98\x04\x10\x0605@R\x9c\xe7\xec\xffj\xb9z\xb5H\x7f\x93*\x11\xb4x\xb2\x04\xb6\"\x12\x0df\x81c\\\xeaWxS^q\x0eRQp.W\x88?{k\xe03V4\x1fc\x9ck\x0e\xdb\xc6\xd4\xb8\xd0~xs\xa8iA\xd6\xc2!\x15\x1c\xb6\x84\x9a1M \x14\nu\x84\xda\xb6@\xaa\xa8\x84\\!P\xb8\x80.\xa9\x80\x8e\xab\xd6\x10tb\xcf\x86\xf0\x08\"\xdc\xb1>\xbb%h\xbb\x97\xf0-\x1b\xf3\xd7w\x06\xa8\x9d\xe5\xf7\xe8(\x84m\x97rn\x86\xc2\x1f*\xee\x19\x8f\xcc\xe3\x82\x9d(\xac\xa8'5\x93\xe6y\x95\xbb\xe0&\xda\x93\x00\xce\x1b\xe7\xe5/\x7f-;aa$Z\xf8\x08\xce\x10Df\x11)\x81\x03Ht,\x82\xceo\xf2\x97\xffel\x82\x94\xcd\xb4/L\x1cNa\xc6&LF\xa1\x81Lg<\xf8\xc6\x911\xa0\xc4\x9bu=\xa2\x85#\xadC\x0f\x05O\x81\xf6z\xc3\xb1\xd2.\xc3\xed\xec\xac\xe0\x11,\xae,\xb7U\x08\xecn\xa0?\xe0cy\xc0s\xa1y\xc0%\xe5R,c\x14d\"\xce\xfc\x0c\x1e=\xc2#\xbf]L\x9b\xa1\x98\xa6[\xac\xca\x9beT0\x1e\xb3!\xfe\x89\xb4\xd1\x8b`3d\xc2T\xce\xf9 \x06yc[\xad\xf2ZIB\"-k\x01\x92\xbd\x98 \x87\x11\x1a\xcd\x8c\xab\xedm\xfd\x9a\xcf\xbb\x9e\xf2\x8cS\xcc\x88\xc7\x99\x99\x05\x93\x9c\x8cta^\x90K\xe9\x00\xb2\xaaQ\xcbi\x95ZrNj\xc5\x98\xa4:\xd9xyej\xf9\xdf\xacKz\xf9\x9f#\x86\x82\xae\xe9wy\\\xe6Z\x14\x86\xbab\x8e\xa1\x92\xc0\x8f+\x7f\xb8\xbe'&\x8a_\x1d\x0eZH\xe1\x9a1\x14K\xf2\xff }WXr\xee\xb3\x8a\xd5\xf4E\x99\x97P\xc0\x92M\x80\xb1\xee\x13\x93\xf1\xb4\xb3\xa6\xa5]\xcb\xf2\x1f\xd4\xb0\xbc\xd4\x00`\xde\xd8\xe0/\xae\xbc\xc1\xa5\x18\xc3\xa3B\x0b\x9f+\x86 2\xa2\x8e\xdf\x18\x8cu\x0c\xc9\x8b\xeb\xd9\x835U\xaev\x99\x90\xe4!\x06W\x87i\\./\xc3\xea\x19\x05\x12(\xf3\x08\xfd\xc6F\x0ce\xc0\n\xc3H\xd8\x87\x0c-\x01Z4\xaa\xac\x1a\xb68,\xca\x10\x89e\xd3\xe1\xadXv\xde\xa5f\xd7#\xd1)w~c\x91+\xba\xf3\xd2\xb9\xf6\xa5\xfeve\x0d\xac\xa4=n\xd0\x91\x94\xd3\x91\xa8V\xb6\xe8!\xa4\xa2\x84L\xea\x94\"9.\xea\x97\xa0\xe7\xc1X\xadwY\x9f\xdc\xaf\xfaY\xfcrm\x93\xe3L\xa6\xdb\xd4\x0c\xbcN!|\xd5\xe6\xa5\xe7w\x18(\x12(\xb3\xcf$\xfdJ9\x06\x13,@\xa7=}qE0H\x8a\xac\xa0k\x03\xad\x88w\x83\x06\xf0\xd5\x0f\xe0\x86\xdaKL.ZS;\x14P\xa6\x12\xca\xe8_\x19\x94A\x02\xdc\x99\xf2!\xd8\x8b6\x88\xfa\x13\x04\x17\xc9\xac\x0e\xc7\xd4\x98<\x0b\xaa\x8e#\x03)f\x8b\x89Z8\xd6\xa8\xa8\xadZ\n\xe1\xdcg3\xd5AI^\x97en\x9bT\xee\x96\xb6n\xb0\xbe\x99\xa8b!>Q\xf0\xce\xd7v\x1f\x91l\xc4\xc1'\xddS\x0f\xb0\xcc\x1e\xafy\xd6:6\xb5KD\xfbj\x87v\x95FR~f\x19\x83]\xd1\x91\xb4I\x0b\xf8\x92\\\xa6\n\x00\xe4]\xbb\x0cQ\xc3/\x18\xc2O\xd4K\x8c\xf6s\xb0\x8a\x0b\x93$\xa6Q\xdc\xa9\xf8C\xb3\x7f\xe5W\x9f\xfb\xcc\xb6\xecj(\xb7\xa7ic\xb4\xe6J5\xe6I\xad\x11\x90*0\xd9*c\x1e\xea5\xdc\x82;\xcd\x96g\xf2\xd9^\xf3\xd9\xa2\xf8\xce\xe4\xb9\xbf2x\x0c\x9c\x89\xd8\xa1\x0bc~=\x87<\x96\x9a\x88Z\xf6\xe5\x9cxJ\xcaI\x8d\xf0-O\x82\xc8\xa3\x96\x0c\xa3\xb1\xbd\xc6\x03\x1fL*t@\xde3~\\\xa7\xf0\x98g\x8dN\xe1\x11\xac\xe1\x00\xce\x89\xb7\x8b\x0c\xcfY \xe2L\xb1\x10\x04\xf1\xe2>M\xb8\xfc\xedcYZ\xd2\xd9-\x06\xfdD\xdeG_ \xf6\xacI\x03\xd2\xa6\xe9-4\xb5-\xfe&:/\x127O\x8b\xb9\xddaD\xc9\x032%-y@\xd8ArN\x19\x9bL\x1c\xf2\x80(\xc2\x87g\x8e\xb1\xe49\xbc\xc4\x11\xf7\xad9-^E\x19\x85Q/\x80\xde\xb8\x99\xd4\xa2\xd2\x93cR\x8bH\xd6\x8a/\x93\xe2\xfbEVrZ\xcdJn9M\x99\x00[\xb0\x96\xe8+\x83#O\xd2\xe842y\xb6I\x99\x8b\xf5\x14\xf7y\x99P\n7\xe1T\x13\ni\x02P#\xbbF\x05\x06\xdd\xb2k\xb8\xda/\x10d\x84\x83\x8c\xb3U\x95\xaa\xf9&\xbfo\xf4\x0d|\xac:\xb1\x11x\xa4d\x83\xed\xee\xb2\x06x,<\x82]8\x80\xb7\x82\xc7\xc3m\xb6+\"L\xdfJ\xa7\x04\xb4\x00\xf0gD\x1b]\x06`N\xb0Gp=\xe5b\xea\xdf)\xed9\xc74\x8c\x16v\x86J\xba\xf7\x1b_J\xac\x81\x02\x08\xc5\xcf\x18%0 W\xe1$\xa2kn\x10\x1f\xc2{t\xc2\xabG\x0dpy\x10E\xac\x88\xbf\x14\xd5^\xa2\xfd\xe3\x059#\x8b\xf2]\xf3\"n%\x8e\xe1\x06Q\xfa\xd0Z\xee\x00\xf8\xd8\xd6\xba\xd0\x13\x8e\xc6\xec$\xd3w\x13 \xbf\x0b\xae\x8a\xd4\xf7\"\xaa^\x98)y\x0e\xea(F6\x03\x16\x16\xa9\xcf\x19\xdd\xca+`F\xd8\xc2\x0e\xea8}\x1fG\x83o%\x15P5\xa9\xb2v\xc0\xdcJ\x169@9\x84!\x1c\x96\xb9\xb3\xf4\xf3\xdfJ\xf4*\x95\x8a\xe3\xc4\xeeC\xc8\xb8\x8bi\x86~\x92\x02\x16\xd9\xb8\x10\xbf\x8c\x049B7\x91\xb0\x80\x1e\xa3\xf1~\x00a\x9d\x82ip\xf4\xc9\x8c\x92\xc6\xf1\xde\x8a\xa2^\x15G1\xc8\xf8\x1b0UX?Q\xa8oA\xd8\xc8\x8e\xb0\xfaN\x9cp0\xa9\xe2\xa0\xc9\xa2\x848\x98b\xb2L\x86]*\x185(\x88/Ez\xc8\xa0\xf1\xab#r\xca\xcdbE9\xd1d.z\x13\xca\x8a\x08\x95|\x81\xf0k\xcb\x8bi2&\xca\x0f \xaf\"K\xf3x;%\x01,I\xc0\x98\x06[\x1a\xf5\x13\xf3iU\xf2\xea\xf2\x10\xd7BX(\n\x8b\x93]\xbf\x0c\x80J\xbe\xd4\x165\xc3\x0f}3|*\x89D\x04\xe3\xb0\xeb\xd7&\x06\x95\xb8g6\xb70\x00\xa3\x8d\xb5\xa2\xc7 +\xe5\xac\x0c\x9e&\xf2\x92\xc4$\x17\xfeK\x07\x12\xc1\xf8\xf1\xbe/\xa3\xdc\xf1\xa7\x99G\x05\xe1\x97\x92\x8b\xca\x87\xbb\xe8\x19\xbb\x03\xb9\xfd\x93 F\x9a\xee@n\xe0\x1b\xf1\x95\xc7\xb0F\xdca/\xdb\xec\xa1\x02\x08\xad<\xbc\xbc\"t\x9ce\xd3\x9e\x14\xfb\xe1\xd8Rt\x04\x14\xb5\x04V{\xdc\x99\xc0>\xa3\x9a\xf6OD\xcb\xe8\xd9\x15\x8e\xa8>W\nh\xb7\x1d\x80\x0c\xab\xab\xbb\xe5G\xa89nYV\x11 \xea\xbc\x80\x13$/\xd5\x05L\xe0\xf1c\x88\xec\xdf\xcd0\x00f\x9b\x1d\xeb\xf2\x03\xcb2\xcd\x8a\x05\x9d]\xf3\x82\xe2\xb9\xf6\xd0\xe8`\xa1^l\xed\xb5\x19]tW\xa1\x8b2 }\xf5+\x12E\xf6\x98\xa8\xd3\xa6\x90\xaf_\xa1P\x85\xb6\xbel\xb6\xe3\xcb\x8b\x0dcR\xf3%lCpP\x08&G\xf2\x19\xec\xc3\xa4\x0d\xc9A\x8c<\xe7\xae\xe8\x19f\xde\x8f\xf8\xa1\x940\xd4\x88\xd9\xa9\x1d\xf9f\xb7\x04\xb0N\xc9\xb27\x90.6\x1e\xbb%\x948\xd7&\xfb1\x1d\"a#;\xd7\x99E\xa3\x10J59;\x9b\xd98UU9\xfeTT\xe5\x04oH=y\x8c\xbf\xca\xacGa\xa1$\x8f\xf0\x87\"5&\xfc\x86\xd0\x97\xe7\xfcW5\xb9W\xe8\x04\x8a\x0bb\xd3\xa8\x9d\xa2i\xd0C\xc5\"\xb7\xeb3\xf1\xcd\xd1\x14\xfe\xbe e\x13\x88s\xee\x8f/\x92\xf3\xd8c*(w\x9a\x7f$\x89\x9bT\xcc6>@^\x18\xf1R\xf1\xa5\x88l\x1b\x93\xb3\x9c-\x9c\xdb\xa4F\\G\xa1%c\xce\x8c\x9b\xf8&\x1c\x0e|cHXX5I3~B\xc9\xbcQ\x9ed\xc3\xd0\xc6[t\xccXi}\xd8\xa0iE\xb3\xea\xc8\x8b\xe3\x9f\x96n\x99jWA\x05v\x1c\xf2(\xec4xK8(nJ\x13Y\xae\x8e\xb3\x19\x83`\xc2\x9bC3OW\xa8\xd9\xd0\x1f\xa0\x88\xc1\xa3\x8ag*\x15\x1e\xa8k\xe2\xf1\xfc\\\x82-E\xae\x94\x8d\x8a\x89\x97\x8d\x02P\xfa\x91<1\x8f\xa4\xb0\xa0\xd7l\xbf\xaaeU\xcf\x0f\xf2/\x1fq\x81F\xb2\x82\xb0\x0dg&\xa4\xab\xfarJ&R\xf0\xad\xf8\xf5C\xee\xb7\x80\xae8XXuX\xf80\xf0P\xad\x14=\x19\xd8G;C8\xb3\"^[\x99wcE/k\x92\x1e%\xe8EF\x9d\xf1r\xc7\xea\x13\x19\x7f`(o\xac\x98\xf5\xd5t;\x98\x9f\xc1\xcc\xb6\xb7\xb0\xff\x89\x0b\xfb\x8f1\x1e\xb0m*\xce\x10\x1623bc\x8c\xdc\xf4>\x9a\x8dv\xf1\xefm\x0c\x19c-h<\x16\x18>\xe4\xf5\xfd\x95\xb4\x91\xa9\x9c\xe1\x9e\x12s\xc0\x0d\xbf:N\xa5\x1a/Q\x88\x1e\x13\x15\x99f2\xe8t\x1bfl\xd4\x0f}|.\xf6\xd1\x84\x8dkR\xdd\xf1\x070\x92\xc6\xa3\xc9X\xec*&\xd8\xcd`[f\x1f\xc8\xd8\x9fg\xba\x11q\x99\x90=\x9e\x05\xbc\x8c\xfa\x8c\x1d\x00\xfc\xdf\x04\xff\xb5Md\xc1\xa5\xb1\x04#\x08\xf0\xcf\xd0\x7f\x08+\x06\x11\xec9c\xbb\xc9i\n\x95\xa1\xf3\xf1\xea\xf1n\xde\xe6N2\xc5 \x8aG\x18#\xc1\xc9F\xc8%\xee}60\xbc\xad\xa8\xb70\xba\xd1pda\x905\xff\xe6\xe6M\x8c\x03F\xd1l^SA\xb4\xd0\x8a5F\xb0 !\x9f\xf0\xe9-a\x08\xd9CX\xc2c8c\xff0J\xd0&K\x1c\xc3\x10\x16HA\x96z%\x89\xbcXwkAr\x8e\xc7\xbc\xdf\xf2\xb71\x81\x94\x9e\xbf\x93\x1f\xf2\x9e\xcf\x90v\xc1\x10\xe6-\x94 $\x83/A\xe6\xb1E\xc1(\xf6iEq\x92\"\x1b\x13\xfax\xd6=\x1e\xc2\xca\x87\x9c\x81c\x85\x8b\x86\xfff\xdcmaR8(4\x9a\x12z@\xde\x96.|\xb2pGf\xc2q\xc4(\x15\xe2\x87u\xe5\xc4>\x9cX\x85\x19\xb60'\\\xe8~\xfc\x98\x1d\xe8\xb6\x85a\x038A\xea\xba*_\xf7\xe1$%\xe1g\xf3W'BP\xdb\x1e\x82\xc7\xb7\x94\x0f\xdf\xc1 n\x92\x9d\x022b?\x8dN\xf4\xc2\xad~q'\x1c\xab\x1f\x0b5\"o\xa7\x0e\xd2\x8c\xad\xcc\x0e\xcc\xd8\x12M\xf8~x\xc4\xf7C\xe5\x83b93F \xc4\xfb\x92\xba\xec\x08\xaa\xb2\xa3\x8d\xa2\xec\x9c\x924D\xb5Fy\x9cp\xb6\x9bV\xd8\xf9\xb0\xd4\xed\x00\xc6q\x96\xeeU\x13\xd5\xbdj\xea\xea^\xc5\xc8\xc49\xf1r.\xee`\xa4f=\xba\xd1p\x1c\xff\xe1\x96/2U\xf3EV\"\xe8\xcb,k\xa1=\"\x04\x93b[\x99\xe0 Z\x01M\xe9{&\x1c\xc2\x8f\xc5\x9eMp}E\xa5\xbf\xdc\xcbxJI\xbe\xea\xd7\x9dR2\xe5\xf1h\x93\x0e\xe8\x91\xc0c\xe94y\xf3&O\x10Uz%'HR$\xe4\xebYn\x0c+\xf5\xb9-\xc5\x1cw\xab\xdeE\xa5\x9c\xd4Y\x9f\xb1My\xe6\xd4\xfe\x91\xbd}k\xa1\xc7\xa7\x9ce~M\xca\xfa\x8e\xecVg\xbf\x9b\xb3\xff\xf5\xf5\x1d_\xdb\xa1X\x94\xc2\x9c\xd5\x11\xce\xd4\xe0\x07\xd7\x94|U\xd5\xc3\x91bT1+!\xca\x14\xe1(\x02\xe1\x8f}\xb4\xdb\xf7\x8fy\xea \x9e;|\xc1\xed\xcb\x0e\xb9\xc3\x9d\xe6\xf4\xd4\xaaLXre\xc2\x92\x8d\xeb\x03\xf1xu\x9b\x0b\xe25B\xfd\x0c\xad\xffl\x970\x84i'\x90,\xbd1\xf5R.\xf8\xe0(3x\xfdb=6LIA\x0c\n\xff\xac\xe4\xf8\xd9\xd1\x1a\x9aT C\x9e\xb7I\x8f\xb7\\?\xd1\xa6(\xcc\x05y\x1cr\xedi\xf9s\x0f\xbe\x83D:n\xa2\x8d\x88\x1b+\x9b\xc9O\x0d\"\xac\xbcD\xff\xca|\x84\x8a\x05\xa55\xc3>\xf2\xfb4yI\xd6d\xfa\x9e|\xf1\xfc\xee\x94\x99\x8ev\x0d\\\x83\xdf\x9f-\xa2\x95\xc7:x\x1d\xf2|:\nn2\xa2\x9bVp\xb5\x8a\xb9\xaa\x933:\\\xa0\xf1L\x96}c\xd4%\xc2\xc3\x9c+1\x14\xe7\xde\\Q[0\"\x12J\xd1T\xa3\xbcTb\xcd\x8c\xb6\x99\x12\x01rD\xa5\xd0\x1f\x0d\xc6m\x8b\x9dr\xd5\x1e_G1\n\x9ej\xdd8\x08>?\xe1L\x9fK\x12Z\xb6\x90\x8bB)\xa2\x19#\xc90\xf1=\xa9,\xb4\")\x07\xf7\x0d\x17\x94#\xd2s2\x0c\x8c\x1f\x90\x93s\xcc\xbc\xfc\xae\xc5\xeb\x04\xdd\x95\x14\xaf\x93\xe3<#/\xc9:SJYH\x8a\xd7L\xe2k\xea\xf4\x8d\x81\xa6k{\xec\xde\xfc\xab?\xb7\xf9g\x7fn\xf3_[\xe2\xd8\xfeAl)b\x89:\x02R\xed\x9e\xdd`[\xbc\xcd\xabSi\x8e6\xb1?\xc0b\x8e\xb2xIkCgE\x99d\xf1\x91\xac\x7f\x86\xdeg\xb6\xbe\xdd\x07\x0b\xean\x12\xddx\x06F$\xd0U\x14as\x9a\x87Y\xab\x1b*\xa8\x1dE\xf1d\x91OIV\xafj_\xb4(_\xe8\xd6\xec<4\xb78 's\xf2\x8ed\xf9\x02\xf9\xdf8\x00\xc5\xa3\xf0c\x8c\x8f+e\xbbl\x11L\x85ZO\xebL\x01U\n\xd5\xa8g\xe5\xc8\x18\n\xafC\xf4\xb5\xa7fu\x84\xb1\xd8\x95\xe2\x9d\xdau~\\\xdf\xcb\x0e\x82wmR\xbd\xd4n\xca\xaex\xbbf1]\xb2\xf0nN\xac\xf2\x92v\xcd\xd4Z\xbeV^\xc8\xa5\xd0\xd6:\xb6\xf2*\xf7\x19\xba\xb9\x8ev[\xb2!\x01\x86u\xcaw\x95\x0f\x07\xe3@\xf9\xbb\xe1^X\xbf\xecfQ#\x19\x91\x97)\x8b\xb9\x1b>\xb2\x95\xc2\x15\xfe\x99\xc9L\xb0\x0f?\x1b\x11\xa9r\xd3D{\x9f\xb7s\xba\xad\x148\xad\x13\xdd\xb4;i1\xd3\x80\xb4\x1e\xd2\xe9RT\x99\x97%O\xcd\x85~\x0b\x19{(r\xd0G\x18&\x8c\xbe\xf6\xbc\xc4N\xaa\x15\xedp@V\x02\xe44\xbc\xab\x12\xa0\xa8\xc5\xd9\xa6J\x83R\xaf\x9c\x91\xfcXX\x04MD)j\x99\xb2\x9e(9\xcdY\xc5\xe1w\xe6\x14\xce\xdd)\x8d\x14_\x93V*\x83\x8ev\x82\xc0H\xf9\xd5\xfc\xf6\x99\xf0I\x8b8m\xb0\xbb\xa8\xa0o\x82\x95\x06I\xf9\x9dA+\x0c\x14d\xcb\x91\x02\x85\x0c\xdf\xb4\x0b\x00\x06uB\xa3*\xa2a\x8f\x7fl\xf7\\\xb3o\xf0Xe\xb1\xe2\xfan\x8f\xbb0G6.\x8br\xf6\x07-s\xce\x9c\x90<\x05\xbe\xeag\x00*w\xd5a\x9c\xa0\xeeE.%\x9a\xb6\x8c\xae\x8c\x07\x83J\x8dl\xd9\xd2 \x16=\xa1&@\xe4}\xdc\x19\xc0\x8e&\x855\x08\xee\xa1Nc\x8d\\A\x95\xc6V\x1a7\xb4|56\xae\x85;\x8c5\xbc\\\xac\x8f\x0e\xf9\x8f\xf3p-\xc5H.\x03\xd82\xc1N\x1f[d\x9b\x91\xf6\x8c7\xf7\xe0\xb4\xe5\x7fpU\xf9\xb5\x9c\xec\xb8\x19\xa3:\xaa\x19\xf1\xf8\xacH\xd4\xebv\xfcFxL-Y/[[%A\x8c,\xa7o\xf4\xe7\xb2\x03\xc5x\x9a\xbc\x80\xb0\xb5kJ\x0b\xf9\\\x87ia\nl\xde\x94gJ\x9c\x80\xf9\x8c \xf5Uy\xa1\x1d\xe1\x13\x8b[/H\xa9A\xe5\x13\xf0\x832\x91\xe2\xf6v\x00\x91\x87~ \x1c\x02hn6\xe7\xf9dS\xad\xfb\x84\x81\\<;\x1f\xe1\x04\xa6\x1a\x1f\x91X*/\xb6\x03\xad\x03\x9b\xe1\xe8\xfc)q.o\xe5F@\x06eT9\x92\xc4\xfe\x854\x84%.\\ \x08\x9bX6\xda\xb5X\xcd\xe4\x85\xd9,\xb5\x89A\xd5\xab\x8a/34\x15*9\x81\x9ecED\x91[\x1d\x91gfd8\xc1(\xf8\xe8\xf9\x1d7\xdb\xc0\x17W\xe2G\x0d\x11\xa7l\x86\x9d\xdc\x88\x98\x101\x80[\xe8\x83\x83\x81\x88\xe8\x93#\xde\xff,*\x98E\xady\x93\x18\xda\x1c\xf1:ff{\xc2k\xa4\x90\x86\x80\x1cF\xc0 \x81\xcd\x06r\xf6W^\xf4\xc8`\xd2\xa7 W\xa1+\x07\xb1\xe7\x97\x90\xd2\x0fJ8y\xe7\xb0\xa3\xc3\xcc\x0c\x86C\xee\xe9\xe7\xb1\xcd\x96 G\xa4]\xd8\xd7V\x9a8\x13^\x8d\xf6cg\"Y\xcc2\xdc \xc4\xcaZ\xd2\x18\x1a\x96\x06\xc4\x00\xb6\xf0\x94\x8a\xa4Y,,\xd2\xf8x\x93\xfaY\xe1p\x0c\xcb\x0c7\"\xdc\xb4L\nDDQE\xc9\xa4m3:\x89\xe9f4~l~\x00\x93o\xd3SEV\x1e'*\xb2\xea\x95\x8eY\x06B\x87\xd6\x81J8Nu\xfd\x95S\xc3\xa2\x03\x92\xd4\xd7\x12E\x9cqW\x02\xe3\xf3I+1\xbe\x12\xcb&|o7\x1b\xd8\xc2r\x90\xf9\xf66<\x82\xa4\xdcl\x13F\x83\n\xad\x9c8\xc7b,\xf8\x80\xe7X\x84h3\xe1\xe65\x031\n`\xa2\xa3G\x93oT\xd6 \x9b\x1e\xeb\xdfi\x89\xecz:\x896J\xabM\x15\x9fy}\x1c\x96\xf7\x9a\xcfR\xb9V\x0f}\x88ZOK\x06\xaf\xed\xed\x0c\x1e+(\xdfv\x12;E\xbfC[\x04<\xbb.\xedj\x024P\xb5N\xa1\xe0\xaa1 \x96\xd4\xe2Q\x0c\xb0'\x01\xaf\xa3\x13\x88'Oe\x92\\\xf4\xc6P5\x95]\x14\x04U\xac5\x1d\x98\xbf\xbb\x1e\x98v\xb2}M<\xb0\x99\x8c%.{\x84x\x16\x97\xf73\x11da\xa3S\xed\x88n\xe1\xb4'\xad\xa4\x8a\xa7\xe4\xc6\xd3\xb2\xceuO\xfc\x92je\x0d\xb6;\xb3\xb3\xdd~\x00\x9a@\xcbk\xe2\xb9\xbf}Y\x92\xd4e]\xba0\xf7\xdf~\xdet X\xb8\xc9q\x914\x89\xda\xe55MZ(R$\xb3\x0e\x86\x82V\xf8U\xd6\x1f)CT\xa3\x0cQ\xc0\x8f\xb0\xa8\x8d.\xb4\xcb\x0d\x8b\xd2\xeaa\x7f\x99q\xa2\x0b\xac\xe47\xc3\xbfX\x07\x9c\xcb\xcb*x;\x13\xf1L\x16\xf6\x1e\xce\xe7\xd1\x82\x80\xd1)\x0fTu\x00\xda\xae\xd4\x99'\xd8G'\x9a\xe7&$\xfcz-\x86\x8fo\xb6\x04X\xf0\x17\xe9\x94\xa1\xce\x91\x18@1\x1b\xeae-\xb4\xe7LT\x0d1oeve:\xca\x16\xb5(\x10@\xe1\x9e\xb7\xd0\xf3j\x02\x8f\xb0`\xcdM\xc8=\xac\xda\x87e\xf2'\x18\xa8\x0d\xfb2M7R\x84X\x94\x03HPR\xf4\x0bIbk\x17\x8bs\x9a\xf1\xca\xac*g\x0b\xcb\xben\x96P\xfa3L\x19\xa9Y\\\x03\xb1\x8a\xa3\x96B\xe7\xd7F\xa5\x04[\x958))\xa8\x93\xc9\x04\xe4\xb9%R\xcdw2\xcfN\\\xe9\x0d\x88^RA\x01\n\xf7\xeb\xd1`\xcc$T\xd4\x10z\xa1\x8c\xa7@\xecb\xc7h\xeeM\xca#3.\x08G\x1a\xf0\xf3s\xd2N\x16\xd9\x15r\xe7\xdcD\x94F\x9b4\x96\xd7\xda\x82\xf0\x8eJ\x90\xac\xa3g\x97\x19i\xdb(`\xdb\xaa]#C\xdb\x81\xa2\xba\x99\x99~\xb1RT\xee\x91\x89\xd1\xaa:\xf9E\x12\xdc\xd0\x986:2SK\xbe'\xa5v\xa3\xe2 HZ\x8a8 \xb8\x8fR\x1cy\xc4K/\x1e\x00\xffP\xb8\x97\x11\xa3\xfb`\x91e\xdaxD$\xfd,I\xa9\x9b4+>!\x1e\x1d\xdd\x1e\x07\x10\x8fn\x8f\x11\xcb\xe9ho\x0c;\x10\x8f\xf64\x19\x82\xfd\xb2 y-+\x83q\x97\x96;i\x08{\xcd6\xeb\x15\xfal\x0d1\xd0\x8f\x06\xba\x81q\xce\xf5\x85\xa8\xf1\xc1\xdd\xbao\xf0_?z5\x85\xa0 \xa7^Zq\x8a\xfb\xbb(x\xe5b7\xfa6\xed\x82,u\xe0\xdcRG\xe0\xcaK\x02\x99\xad\x0f;\x99\xe0w\x0fC\xd8K\x9fK\x86\xef\x96\x03\xff\xea\xfa6\x07\xf6\xbf\x03g\x88\xab\xd9*\x80\xa1n\x02\x973\xb9\"\xa0\x04\x16\xd8\x00\xc2\x13\x90\xf4\xb3dI\xae\xd2\x01C/K\xf3\xa2\xbe\xd4_\xc8H\xc9\xfc\x989\xe6\xc7\x14\xce\xbe\xa2\x1c\xc5U\xa1\x88\x03\xb4\xcd\xf2\xfa\x05\xe2\x1f[s!p\x13\x0b\xaf\xc9A\xfb\x93$\xceh\x9aOP\xb3\xecF\xdf\x7f28zGE6\x1b\x1e\x81\x84%F\xe8(6j\x0d\x810\x01\xc9\xcd\x818mI\x9c\xcc9\x88\x82\x04Zs\x8aq\x0bv\x14g4\x8c'$\x99)\x15\xcf-N\x11\x089D\x8f\xea\xa7\x95d\x9f\xa9gR=\x17MX9tv\xc5\xa8\x96j\xd7\xb2\xe6e(\xe5g\xb2\xce\x8c~\x89\xf2\xdar\xe3\xca\xd4\x8b\xa6k\x87\xb7\xd8E\xb4\x11\xaeN\x9d\xc8K\xcceJfQL~N\x93\x15I\xe9Zp\xbe\xee\xad\xb0\xeb\x94PE\xb4\xec2\x06y\xa9$\x88\x87Mvj\xe2\xb2\xdd F\xbd\xb2\xcax[\x8fo\xdduJk\x89\x98\x03\xe8=\x0d\xe38\xa1\xacuHb\x08c\x88\x8a\xf4\xbc)\x99$\xe9\xb4\xdf+H&\x8f\xb6\xb3\xb0\x98\xba\xab=s\x9b\xbc\x0c\xd1\x08\xf5\xeb\xb2\x7f\x12\xc5S\xaf\x8c\xbak\xff\xec\x12&!\x9d\xcc\x01\xc1f\x1f\xd0\xa5']\xd3\xe5\x11\x91\x0b\xfd\x04r\xfdq\x88\x81\xbcK\x93\xe5aL\xd35\xd7\x95*\xca\x9fv\\\xe9V(\x81\x0b\x7f\xc3F\x95\x04\x87\xfc\xda\xa4B\x14*\xdd\x1a\xcd\x08%!\x11KT\xfd\xc8\xbc\xacp\x00\x1f\x88p\xe5\xecPmA\x1e-D\xdd\xd9<\xef\x85F\xa2AHF\x99BH\x87\xf0\x9aT\xe1;\x9a\xca\xea\x06\x15\xa8\x17u\x0e4\xfb6\x00\xe2\xbd#\x01\xbc\xf0\x03xw\x05\n\xdc\x14\xfc\x90\x02\xeb0\xa1\xd2|-n\xa0\xb5\\\x1ao\x9b\x17M\xb36\x8c\xfa\x91\xf7\xe4K'\x9a\x81\x8d\xcb/\x9bt\xe1]\x15nN\xa1BgJEf=\xbe\xb1&>Jr\xb8\xa5K6X\x19\xa3L6\x80F\x0d\xe7i\xaa\xcd\x88yJ+\x8798\xfc\xd2o\x04\x89\xd6\x80\xc01\xb7\x15;T\xb2\xa8\x07\x02\xa3\x02\xcf+\x87M\x070\xa4W\x01C\\\x03\xc32\\i\xf0\x15\x04\x18\x1a\x85_\xde}\xdb\x19\x11XB\x94\x9a(Y\x1e\x13\xd5\xc9+\xe6<\x07\xc7e\xea\x11S\xcc\xd2%#P2\xdf\xf2?y7>\xcf\xd2S\xf4`T\x9d\x17\xcdG\x81\xc8\xd7\x1c\xc3>/\x06\xa4\xeb\xcao%\n\xdd\x8e&<\x1eT\xb0\xf8\x16\x08\xca\xe3I\x7f\\\xc4U\xddS\xc3\xa0aD\xdd:\xd8\x8c\x8b\xea\xa8\x90\x97\x96\xa1\xd8\xea}Q\x88 hP\xe1JCT4\xf3U\xc0\x82\xf8\xe8\x17V\x98Wt\xcba[\x8a\xf2$!\xde\x1b\x12\xc0\x0d?\x807\xeaR\xe9\x02\x01\x1d\x89x\x11\x0d\xd8\xa4\xe4o\xbems\xb5R\x1a\xf3\xfah7\x9d3o\x86;\x0cA\xee\xca\x92ig\xea\x86\xf7\xdf\x84\xb0\xd7\x82\xa1\xc4\x15C\x89\xc4P\"14\xe5\xa6\x10\x81\x97N5\xc3\x88\xf7\x8a\x04\xf0\xa3\x1f\xc0\xabo\xe7 ,\xc8\xf7\xeaZ\x90\xef\xcf\xc40\xe2\x8e_\xda\xc9\\\x1b~\xfd\x87\x91\xa8\xc4\x9f\x8e\x88\xf4Lp\xba\xcfT\xe8\x10!\xcc\xb4\xf1\x10\xcdu\x14,D\xbd\x9fg\xff\x95\x88\x84.1\xa6\x87\xec\xfa\x89x\xc6\"z\x8a\x93En}\xab@W,\xd1\x8f\xc2\x00:vr\xb1\xb5\xbc\xb9\xcbo\x1a\xa4Xv5\xf5rZD\xd7\x02\xfb\xbf\x06\xd1\x1d\"C\xdd\xf6\x02\x14\xe1\x95\x15\xb7p\x8b\xf3\xa4\\/\xd2\xe6e\x89\xde\x95\xb6\x11\x02G\x0e]\x18\xa0zI\xde%o}S\x0c\x1e\xf7r\x04\x07<\x91\x0bG\x89\x14Q\xa2\xbc9\xe07\x07\xcd|\xf9\xeaepYt\xa0 \x95s\xb8\x9a\x86\xe0\x9d\xf9\xd1+\xf3\xa3g\xe6G\x98\xa3\xcaK\xe3\x00N(\x13-b\xe5\xcdoT\xb0\x86\xb1\xe0A\xb7\xa1g\xd4\xb0V:\xec||V4\xea\xec\xf3\xb7\xe7qi\xf2\xb1w\xe6\xa8L\xe0i\x9e\xe6Eut\x1b\x9aW7oep#\xaa\x89S\xae\xcc\x85\x89\xaf\x07\xe5\xdfRg\xa1\x89\xd9\xac\xcf\xc4I\xf9[J&Z\x95\x15\xef\xff\xe6Me\x00\x15}\xae~\xb2R\x99\xa0\xda\x06\xcc\xd3\xec\x1f\x93\xe5\x8a\xaeQL.~\x0c!\x8f\x85\xa8\xfd\x1bm\xa6<\xadM\xd5Qc\xdc\\\xb4\xd2J\xcd-\xd4\x7fS\xacZy\xfc9N\xcec\xf8L\xd6\xd0\xfb\x1bl\x03\x85m\xf8[\x0f\x92\x18\xd8/\x89\xc7\x06#y\x05z[%\xf8D1\xfd\xb2\x16\x87\x16)\x1c\xf4\x86\x15cBu\x892\xa9\xd7j\xc1\xadJY\x08e4%\xce\xc1~\xb9\x0e\xcd:\xcc\x955pT\xae\x1b7\x8ey\xa6\xc48\xfb({\x8f\x9a\xf8I\xdcT\x01\xcd\xe2\x00\x16\x0c\xc7z\x7f\xff\xfb\xf1\xf1\xd1\xeb\xd7\x1f?<\xf9\xe1\xd5\xe1\xf1\xfb\xc3\x0f\xc7\xc7\x7f\xff{\xaf\xe9\x08\xb2bog\x0eJ\xa3y;\"\x18\xaa5\x91z\xb5& \x05Y([j\x88\x91\xcd\xe5\x87\xa6\xf4\x8eg\xa0^\xae\xe8\x9a\x87O\x17`tSDL\xdb\xf7bU\xc9\xb5\xb2\x04a\x94\xd9\xeck\xe5\xebb9-\xca\xb3z\x97kJ\\\x93p\x9fY\xe9\xd2\x0c\xf3\x0ex36\xdei\xec\xe9L5\x86v\xd7\xdf\xa0\xd2:\xe7*\xad\xd3\xb8\xd4d\x9d\xff\xbfM\x93uj\x87_\xa1\xee\xd3\x14XT\x7f\xad\xe2\xd1\"\x96\x0et+E\xa9\xb5*\x95Z\xab\xaa\x82I\xfe\xac>\x10\xac\xc1*VuV+\x17\x85\xcf\xca\xa6\xf0Y\xb5)|V\xb1\xdc\x870\x84\xb3X\xdc`[\x11Q2\x00\xe2\xadcF\x9c\xfc\x00\xd6\xd7\xa7\x11Z\xff)\x1a\xa1\xf5uj\x84\x84\xff\xbdM1\xb4\x8eK?}N\xb9O5\x94{\x19\x07p\xcc\xf6\xc9\xda\x81\x16\x9ft%l\xc7\xff!\xc2vn\x85\xe6\x92\x13\xb6%\x1b\xefI\xec=u/\xbby\xf1\x0d\x84\xed3'l\xef\x15\xc2\xc6n\xf5\xf38\x9bG3\xfad\xb1p\x8d\xe6\x7f\xef\xac\xe8~bWt\x1f\xc7\xa5\x83\xed\xb1\xba\xd7\xcecqC\xec\xb5\x13\xdck\x17q\x00\xe7\xd4\x0f\xe0\xe2\xfa\xf6\xda\xc5u\xee\x8a\xf74\x9c|\x86\x11\xdb\x10\xe3\xe6\x86\xb8\xb8\x82+H\xd5\x18?'\xe1\xb4\x89\xcf\xa8\xb7\xa2JRn\xea?\xe4\x89\xd7\xe9\xce\xceC\x1f\xbf\xe7^U\xe6\xbd\x00\x07 \x92\xd0\xe8\xe2\xfe*#_\x11\xf2\xb9\x13\x80\xd8\xa8K\xc3!\xfb\xa5\xc9\xde\xd1\xe8%\xcf\xe6m\xbd(9\xbe\xe5\xfa\xbai\x1d\nM_\xe1L\x82\xbb\x7f\xbb\xd1N\xa00\xc0l\xe0\x01\x02\xb3\xfe\x16\xec\xc0\x80A\xfc1W\x1b\xee\xec\xf8\xf8\x99\x89/\xc0\xcc*E\x1b\xa3\xd8\x90\xfb\x90-X}-\xd8\xa5I\xb4\\\xc5GC0e\xc1i\xe3z(\xf1V\x8d\x8a\xa1\xfcn\xad\xfc\xb9p\xed\xff#\xd6\x8b'\x8d\xc5{\xc2H\x91\x83`\"\xd4\xc9\x98\x1f\xda\xa3\xbe\xcf9\"\xfb\xfa\x959HZ\xa4\x16d\xc0\xf5\xd0m\xd9T\x05o_\x84\x07u\xe0\xd0\x08\xcf\x92gB\x01(\xd1\xc0P\xf5\x18\x8a\xf5o\xa6\xce\x87\x06\x19\xc5;E`\xaci\xfdIm\xfd\xe3\xab\xae\x7f\xd3\xfd\xba\xb1\xfeIke*\x15e\xb3E4!\xde\xc0\xde\xa68\xa6\xba\xb4\xcb\xd0\xd0Q\x1d\xa5\xeb\xca\x05\x83\xeb\xdd\xe9N\xd1Z\xeb\xdd\xa7\x91\xac\xae2\x8b.V\xa6o\x8d\xcf\x16(U\xc3\xa0.x\xc5X\x11;\xd8\x18\x92\xb8\x1c\x99\x8c\xa8|\x16\x8e\x1e\xc5`]\\\xc1b,.\xa2V\xe95h\xb8_{\x95\xa6\xab\x16\xaa\xa2\xa3sZ\x1f}\x99\xa6\xc7\x18\xe3W\x9cLi\xe5d\xc22gQ\x95d\xb1\x83\xe6\xa1\x8fw#\xfb\xe9n_\xc4\xb4\xb6\x88\xd1\x95\xd6\xef\x8fXWa\xba\xb6\x86\xdd\xd4V\x85.\xa9\xa9\xb9R\x10\x14\x0e\xf0L*\xa8\xbd2\x99\x8ea\xc8\xea\xcc\x06\x06=\xd4\xc5\x95\xb5\xa0\"\xee@]\x92\xf2hQ<\xbflH\x11\xf3=\x97\xd6\x10!\xad$\x13Le0H\xac$\x13\xc4o\xd2\x16&\xd0i\xb2n:R\xa7\xd9&z\x1db9S\xed\xd9\x97\xba\x9d\xdc\x8e\x91 \xad^\xff\x92\x9fH\xdb\xe2\x07D\xbf%\xa0\x03\xee\xd9\x8f\xcb`\xb2\xfa\xeag\xc8[je\x1e\xda\xb2\xf3Y3\xf3\xb9D\x05\\\xa0\xd6\x15\x85\x9a!\xbc\xd7H\xef\x87q\x00Otz\xd7\x0fO\x9e\xbe4h^\xdf\xb2\xf7/\x1c\xa4\xfd?\nw\xbd\x96\xfc\xa15\x8f=kF\x99\x92\x19\x8eTN8\xaa;\xeaE%\xfdK\xf9\xaf*upK\x19\xf8\xd9z\xea\x1er=\xc0!\x03\xc8\x1f\xb1\xd7pO14z\xd4..\x16ho4K*\x87\xd3\x08ut\xec\x9f&J\x18!\xa9\xa6\xef\"%o\x1c\xfb\x01\x94.\x93Jh\xc4\xfb\xf5\xf2$Y`\x85\x04\xdb\xf3z[\xb4\x06\x11\xf5\xd7\xdbx\xf4\xa4P/\xbeu\xd1\x06\xbe\xb5i\x03\xdf\xb6i\x03Y\x17\xaam\xed\x8b\x9aE%\x80\xb8\x7fT\x12\xc8\xaf\x01[\xa6X\x97\xfeK\xa4\xc4vH\xf3\xf5\x8cz6V\x04\xc4\x82S\x91\x1b\x97g\xda.\x8f\xf6\xcdFk\xa3\x87\x1acP\xe6{0\x98\xde\xac\xa6m*\xb0GOc\x1a+\x88w\x9b4\x81&G\xf1\x94\\\x90\xe9{\xf2\xc5\x010\n\x89\x7f#\xa2\xce\xddz\xf9\xe9\xbd{\xeb\x08\x1cm*l\x17\xcd\"W\x87pa\x84p\xefn\x1d{!\xa7,\xd2\x94]\xd2I!\x17;\xf6\xde\xa9\xdb\xec:\xbb\xed\xbcI^u\"\xa6\x9d\x9a\xcf\xaa\xb3R >\xce,\xac?/WY\xaa!\xe4\x9c\\ \x052\xae\xee#\xbc\xb86\xd0\xbf\x8a\xb2\x0eK\xbe\"\xd7\xd5/7C\xb8\xf7\xdc\x1b!\xc7r\xb2 \xe3\x9eK\x0f\xa5\xa9\xc3\xb1\xfc\x85Y\xbb\x04\xdb&\xc6\xf2\xba\x9f\xbe\xf2\x12\xc3\xcc\xb91\x8f\x97\xd9e\x94?\xc5\xb0\xc7}\xce\x14\xc2\x01\xe4\x98\x92|\x1fB\xea!\x7f\xd8\x8f2\xc1'J#\xe0\x88\x8e\xb5\x94[\xbd.}wOo\xf5*\x10\xc0\xe2\xf5\xad^\xa6\x8a\x1dP1\x16D\x0d+\x8f\xfd\xabA\xed+\xfb\xb8\xcfD%\x84h\xb4\xebP\xe79)\xed\xad\xb8\x08\xa1\x97\xa0\xc7\xae\x0c\xc4\xcd<\xa5\xd0j\xb3\xde\x96\xbc\xcc\xd9W\xcfD\x95(Q\xfdBW\xd7X^\x92\x92ci\xe9!L\xeaT\x14\xc7\xc4$N\xf9T\xd2S?\x90\xf7f\x8b\x90R\x12{[\xbb\xc2\x12\x83\xdaEM\xd1\x13\xebV\x00\x01\x1c%\xcd\xa8\x13\xba\xc8-\xc4\xfd\xa0\xec\xc0\x87f\x1fJ\x85X\xd86XN\xe4e\x06\xf8%\xaf\x8d\xd6,g\x8b\x0f\xa5\xfaV\xe3\x0e\xed\xc6\x8eH\x8f^\x97\xb4\xc9*\xbbV\xf5 v\x897\x98\xda\x12#k\x0b!4n\x91\x98\xa6Qe\xac.CU\xf4{\xef\xdc\xba9#\xe9\xda\xf1Lq\xe4\x82cK*\xf2\x16.8\x0d\xc0V\xf2\x13\x8a@s\x8e\x03\xbc\xd6\x11~\xa1\x14Z\xe3Z\xa2\xad\x81\x01\xf8uG\x12\xd0\x03\x86\x13]G\xc8\xd4O\xae\x1f\xd4|\x82\x9a\xf0'0\xf5\x19Ok=\xbaT\x8db\xc0d\x9fbNT\xcf`\xde\x00UOz\x80 M\xf4\xe5\xc15\xc3\xe2Z\xa1n\xb0\xa8 KP_q\xeei\x89y\xbb\x89\xaf/S\xa3\x19\x08\xe3@\\6o\xbd\xef\xc2\x92\xc2\xe9!\x1c@\x0f\x19\x1f\xd8\x87^\xd03c2#\xc1=\x8d\x1eU^\xdf\x82\xe96\x1c\x8fE\xa9\xfe\xad\x01\xba\xacn\xa3\xd2\x14\xffE7\xa3-YBJ\x99\x14\xaei\xe1E\x83gN\xaf\xc9Y\x82\xd8\x01N|\xdbg\xb2\xfe\x06\xf2\xf3\xd4iE\x97\x159\xd4\x01\xad\x8a-VM\xd9\xe9\xd4\x19?K;n\xb0\x00\"\xeb\x02\xd7p\xad\xe1\xa0\xf2\x08\xf60?\"\xc3\x14\xd8\xe7\xf9\x90\x1a\xdbAU\x03`\xcdZ\x1b\x01\x84\x03\xf0\"A\xe5\xb09_\xb4K\x8b\xd2\xb7\xbcb`b-\xc8\x9c\xba\x83\xec]t:\xa7\x1d\xe1& \x93\xca\x08\x95\x86(;}\x12\\\x8f0\xbd\xa7F\xbb;\x98\x06\x8d\xbd\xb8\xe3n\x81Tj2\\\xa7\xae\xd0\xb8|E\x0c\xfer\xb5C\x82q#\xddz\xe4yYx\xac\xdc\xbb\x18K\x85\xe9\xb2`\xe8\xbaJ\x9djL\xd4gf\x0c\xc8\x01}?(u\x7f\x03\xad\xf9\xd9\xa9\x97\x93\x9c\xbe\n\xbb\xa8\x07\xf8\xbeF\x0f\x99\xdd\x00v\x06N\xbdD\xd9\xe1rE]l\x0c\xa2\x17\xf5dR\xe4\xf4\xba\xe4\xbe/\x96\xb1\xca\x8c:\xf0\xa2&#\xa4\xd3l&I\x1e\xd7w~\xcb|\x9ex\xb4T%\xf1m/\x04X\xfeq\x07\xbd\n\xf6\xfe\x83+{*\xfaw\xa5R\xa0P\xaa\xaf\xd4\xf3K\x83\x94-\x03\x9eD\x0d\x1d\xf1nc]\xf1{\x917\xc1+\xeb\x94\xf3J\xe2lW\xaa9\x8f\x9d\xa46E\xe6\xd2\xb3\xbb\xf2\xb2\x94R\xc1\xb3@5\xb7\x19*\xe4]\xaa\xe7\xad\xcb\xea\x91/y\xb8\xe8\"l\x9d\xd1\x82l8\xb5/\xb2f:l5\xd5\xe1T\xbf\xb6\x18\xa8\xd5?\xc6ty\x95\xe2L\x94\x96\xf7\xed\x9cb\xb5z\xeb\xcf\xb1_S\xb5Z\xcf$\x0e\xc6A\x0b\x1d3\xc3@\xa2\xa0\x1b\x05\x8e\xaa\x94\xb7\xd5\xfc\xa4P\xb0\x00\x12OG\"\xe5e\x18\x7fgQc\x1ev\x913\x90\x0e\x89\x84\xcbK\x1eC\xb0t\xec\xe5\xa8\x0b\x0d\x97\xfdp\xaf\xd1.=E\xd9\xfb\xfc\xc4\xb1\xc0g!\x03\x0eM>aE\xa5\x14nu\xe6<\xba\xa2\x13r[\xda\xe2<.\x12\xe3t\xc8\xa7\xa5\x9f\xe2\x8a\xf1B]&\xe9\xd9f)`\xa6\xcc\xd2/n\xba\x9fj\x9f\xc9\xfa\xed\xac\xc3\x90\x8aC\x8d1s\x9d y\x0dFB\x1eq\xee~\xc4W\xb42lW?mH\xa9.\xdd.\xba\xab\xd1\x1a%\xbf\xfa\xc8\xcf\xba\xf7\xf7\xf2*\xebb\xe0\xbdq\x8d\xb5\xb9\xac\x9a}/\xc3\x8b\x0e\xbd\xbe$\x9dT\x18\xcb\xf0\xa2\xeb\x99\xfa\xb2\x92\x8f\xc8\xa9\x137\xa3Yc\x06p\x00ob\xee\xc2\xf2\xd5MPZF\xf1\xd5\xa7\xc3\xbb#\xbc;\xd7\xb9\xa5\xa43&jC\x1eA\xdf|\xf69Zu\x80\x9d\xd2\xfe\xeb\x90\xce\xfb\xcb\xf0\xc23T$6tV\x17\xbe]\xa5\x04\xc3\x1ecMzT\xb9\xe3<\x90_\xe7\xd1\xa2\xa3\x99\xa1\x18\xcc\xefW4l|\x8eV\x1fc\x1a-\xbau\xcb\x81.\x87\xdcM\x05\xc5\x13\x82u\xeb\xafi\xe5\xd0d\x06\x03}\x7f4\xfcL:,/\xad\x18 \xae\x80R\xac\xbfkF)\xd6dw\x94b_}\x0bJ]E\x92\xf8\x87\x13w\xab\x940\xfa\x18\xa3\x9a\xb7\x92\xbc\x0d#+[\x18^\xc9NS\xa3vY^L\xa4\x8b\xaa\xb1yJ\x81\x96J\x18\x08vlo\xedL\xd4\xf3o)\xfb_0n\x1a\xc1\x87\xa2J$l\x9b\xa1\xd2L)\xfd\x14\xdf\xde\xbc \xdb\xdb9\n\xa9\xa2AC\xa1ry]\xfa\x01\xe4\xc67.\x03P\xcb \xfd\x17\xadJ\x92vY\x16Z\xf1\xc6b\xdf\xd9\xe5Zv\x85\x16\x8f\x12y\x89q:FY\xaa\x17\xfaN\x85\xc5L\xdb?\x00\xf7\x88G\xf5\xb2F?\xaa\x97!VB\xbd\xa4\xe9&o-N%/\xae\xc3\xaf\x14\xa9\xb2x\xa9\xcaKF4R\x11\xc3\xdb\xfa\x01\xbb2\xe1\xac\xea\xf6\xf6\x04\xdf\x1e\xb4\xb8\xb6\x82n\xafM\x02\xc8P\xe3y\xc0H\xdbp\x08\xef\x84\x98\xf3\x9cad\x86/\xf04\x7f\xa1\xf0\x0c\xf9/X\xdc6\"`\xa5\x00\xda\x87\xdd5\xaf\xec\xe0\xb9*SQ\x1cZ\xdd\x98\n\x19C\xd0\x91/\xed.\x86\xcd\xc3l\xfe4\x99vpt\xa1\xf32\xbb\x00\xd6e\x9a\xab\xd9\x06\xday\x04(\xb6\x17wP\x1e\x0ea\x00\xb7`\xb7\xd8h\x16\xd2%\xcd\xa4\xb3V\x05\x9f\x9b+\x7f*\x8a\xdf\x0e\xf4Uo\x8b\xd7\xf8\xc0\x9c\x16\xbf\xf6\x0d\x1b\xed{\x14\xd2o\xdf\xb9\xbd\xf7`p\xff\xf6\xdd\xdb~P\xdc\x86G\x8f`p\x176@\xe0\xf1\xe3\xc7\xb03\xb8\x1b\xc0\x9d{\x83\xfbw\xee>\xd8\xfd\xbe\xfe\xdem\xe5\xbd\xdb\x01\xdc-\x9fc:w\x8f\xc06\xdc\xbe\x7f\xef\xce\xde\x83\xbd\xc1\x83{\xb0a0\xfd\x17\xdb\xd2\xff\x12\x9f\x0d\xee\x05\xb0\xb7w\xe7\xde\xfd\xbd\xbd\xbbE\xf3\x87\xe2s\xec\xa6x\xf3v\x00\xb7\xf7\xee\xdd\xbbs\xff\xc1\x83\xdd\x07\xbe\xda\x84e\xcby*\x7f\x10c\xad\xcb\x83\x8eP\x83!\xdc\x1e\xc0w\x90\xc26<\x8f\xbd'\x147\xcd\x13\xea\x11\xdfg32w\x0e\x8e\xbbS^\\+~\x85^\xaa\x93r\xe9\xa6\x98\x11v\xd4\xdaA\xb7\xc6\x1d\xdb\xf5\xb5\xe5\xac\xa1 \x88:RX\xb9SW\x06\xb3\xbd\xf8\x9a''Sr\x01\xa8o\xbc\x8eG\x0b\x19\xe0\xfd:\x1e=c\x7f\xbf\x16&\x8b\x8c\xdd\x12\xa1\xa3\xfc\xb6\x08\xac.\xee\xab\x81C0\x84W1>\x89\xe2l\xc5s\xe3\xe3'\xef\x93<\xad\xe6\x95\xd1\x81\xac\xa6D\x12\xee\xad\xd5\xd9a\xeb\x93y\x18\xc5\xbcma\xcb\xe4\xb7\x93\x98\x86\x11F\xa5\xe3\x10\xb8\xee\x12c\xc4S\xdd)9[D\x1dB#\x0b\x01\xe5+1\xae\x84N\xed\xb3:l\xb8\xf7\xbbZ\xff\xcdT15\xcb\x02V\xe1\xae\x93a\xb5\x90&\xa4\x93\xc4( \x1a\x9b\x8bO\x03p\xa3\xaab\x93t\x14\x1a\x97\xe1\xeae\xd5\x07\xd9\x15FW\x00\x02[\xf7:,\xda\xc4\x8c\x06,x4\x82\x05\x08\xd8\xc9Uv\xeb\x87\x18\x93\x9b\xb4f\xeexj\x06\x92<\xd5\xaa}\x19\xda\xf9\xb9\xb5\x9d\x11 \x80\x8e\x9d\x1a{g \x87\xf5\xb3\xb9e\xb3mQ\x97d\\\xd0\x84\xa7aXo\xaegX;\xd7<\xacW\xf6a\xf52\xa4\x81\x15\xe3\x07\x1c\xc0O\xef\xdf\xbe\xe9\xf3G\xd1l\xcd\xd5\xb6\x82Z:\xe6\x16}f%\xc0\x87\xc6L\x9e\x86\xe6\xbe\xb6b\x10\x85G\x05\x07G\xe11\xfe\xbd\x83\xec\x9cS\x07\xcf\x1d:`\xac\xcf6\xec\xdd\xbb{\xe7\xce\xed\xbb\xdf\xdf{\x00\xdb\xe0Q\xc6\x90\xdd\xf3\xf9\x9f\x8f\x1f\xc3^\xf3\xf4\xad.\x94h\xedCT\xaf\xc2h`\x95\xcb\xe5\x95|\xb3\xad\xaeu@J\x1b\xdeV\x82\xa5\x00\xf8\xba\xf2\xd0R&\xa2G\xbe\xaf$-\xc5f\xc5}k\xcb\x97\xac\xf7\xc0\x96GC\x85\xa8\xdel\xe7\x0c\xd2\x80[\xee*1~\xd8\x7f\xeb\xe4\xdd\xed\xa1W\xb0\x9f\x15\x90\x8d\x18ds\xf8\x1f&;\xb0\xad\xc7p \xa9\xb8\x00c\xcc\xef>\x7f\x07\x0e\xe09\x9b{\xce\xd3\x91\xa2\xd5F\xfe\x8cd\xca\xd86\xf0[\xad%\x86T\xe5%\x95p\xde\xc6\x0b\x12\x9e\xb9p^\xd2,7b]\x8c5\x87\xb2oY,\xb6/op\x02 \xf5/\x01\xdc\xe8'3t\xa65~\xc6\xf3\x93(\xde\xf9\xd6s\x96\x14\x1b\xdf+\x88\x81\xb8\xc7\xe8\x80\xc8H\x13\x94\x94\xc8\xcd\xc7\xa9\xab\xcb\xdd\x92z\xbbj\xcaj\x97>\xae\xe0_\xc7\x0e|\xc7\x08\xd5\xebv\xefq<\xf9\xbf^I\xafzC\xfe\xf1,\x0el\xc8\xe6<\x86_#:w9\xa7\xa4\xcc\xa3\xf6b\xc77\xc6\xd3\xc9\x00\x81\xe6\xf8M&\xcb\xca\x9dK\x9fQ\x842=\xec\\\xea\x1b\xd4\x9bE\xdd\x96#t\\o\x0e\xbf3\x8f\x85\x18\xc4kA\x0b\xb3\xb2\x93\x9cv\xd5|:\x9a\xaa\xd3p=\x9b\x0d\x9b/s\xb89@;Q\xf2l\xf3\x12\xda\x15+\x81\xfaX\xb1$\xa8\xb7+&\x85\x17\x81\xaa\xa4\xf5\xf1\xde\x8d\xca\xf2\xf1{?V\x9a\xe6\xf7N\xa8\xe6\xe3s\xaa\xf9\xfa\x82\xd6?oBE\xe6\x97\xdb\x87\xb8 W\x04\xea\xcb\xe6\xfd\xa7\xc9bA\x10\xd2\xfbp\xac)\x90\x81\x01b_5\x0f\xd4\xb4\x92G\x1a\xe7 \x9e\x97o\xa5y\"R\x05^hGI\xf7!\xd3\xe5{\xbb\xbb\xd3O\x9f\xf2\xe9\xfd\xdd\xdd\x1d\xf6\xefl6\xfb\xf4)\xdf\xbd\xcd\x7f\xee\xde\xbe\xc7~\xce\xc8\x1e\xfe\x9c\x91\xbd\x19~3\xc5\x9f{\xbb3\xfet\x97\xf0\x7ffc\xd3\xe0\xcc\x14\xad\x100(\xc9\xa8J\xc7.\xbb\xc1i\xb0\xfb\xa0\xc6\xeb0.\xb2wx\xb1\"\x13J\xa6\x10\x16\xed\xf4\x14c\x8f\xbc\x07\x89\x96\xb0G3\xf0\x94\xf8\x88-\xc5D\xb0\xd9\xc8\xecA\x1cE\xb4\xaf\x11\x1f\xe8\x9e\x864<>\x16\xd9F\x9bX\xa9h\xf1\x84\x14[\x83\x0c\xbb&\x9a\x1aTQP\xb9]\x14\x82M\xaa\xf7yQ\xc4\xbcz\x933\xc4a\xf5f\x86ofUB4\xe9\xb6:\xb7\x1f\xe8\x97\xe7\xce\x83\x96\xe3\x18\xa8\xc8\xcb\xc1Co\x1b\x8e\xeb\xca\xe6\x15\xc6\x0eOT\xe6\x04R\x9c\x80\xf2\xd1V\xc4\xb8\xab\x9b7\xd9\x1f\xb1\x8fJay8\xc6\xec\xaf\x98\x1dA\x95\xfe(\xeb\xf2\xca'\xfe\xed\x07\xb7\xb5\xb3\x1e|_G>\x81\x94\x0f\xeei\x90r\xd0\xc4\xc7\xbd6\xd2!k\xb9pG\xe1\x99\x0e\x15\x17\x98\xb5\xf8&\xe4\xcd\x03\x17\x0b\xb2\xca\xb2\x8c\x8d\xa7s\xc4H\x9dY\x8a\x11\xa8\x15\x03\xe4\x1c\x81\xec-\xd8?sx\x0c+;]F\x9d!\x0f\xd0\xf5\x9b-bAK\xfeX\xa9-6\xc5%n\xb6u\x06C\xd8\x194G\xbd\xe62t\xe3\xfe\xa9\x00C\x08\x07|'\x82\xf4\x8e\xae\xb6\x8dy\x01fx\xfc#\xa9\x0f\x80\xff \xbc\x06\xe8\xf6\xf6\x19<\x82\x956\x11\x00\x1b\xd6\x92\x81ttf\xe0n\x8e\xb1(\xcc\x99\xc6Q\x9c\x01 \xf3\xb1\x89\x13\x18\xc2\x02\x0e \xf3\x8e\x03X\x06p\xc6\x03\x91py\xf7!\xf3\x96\x01\x1c\xe3]\xbe\xfa3\x0d?SK\xe2{b\x92\xae\xd9{'>0\x018\x8aM)\x0b\x10\xa2\x03\xfd\xb3\x93\x94\x84\x9f\x1bO\x9a\xe7\n\xeb\xe8\xd46\n\xb6e;\xd8\x0c\xf0\x93\xc4;\xc5\xd7n\xde\x04oY\xe6\x8c\x9e0\x08Q\xb9-f~\x89K\xa7<\x16\xdf\x18\xdel\xeb\xd1\x06\x050B\x02\xb4\xd0\xb8\x04\xb2\xc8\x08Nb\x89\x0bt\x8c\xfbh\"\x96\xb6\x18\xb8a8\xdf\xba \xda\x13y&N\x10t\xba-~0\xfc_\xff\x9f\xea\x876n\xc8H\xa5\xeas\xa9\xd4_\xdb\x11 /%\x11\xa7\x98&o\xbf\xa0Ml\xdb\xc5\xf0\x08\xd2\x87\xcd\x95C\xd3\xb8GG\xf1\x18\x01\xa7r\x86\xbbZ\xfeOI\xef\xd4\x91\xcc\xdf\x19\xd4y\x83\xe2pkRyQ\x91\xa98^\x9b\xf4\x1e%\x19\xa5\\S\x93\xfc\xa3*\x08\x9f\x1de\x87q\xbe\xe4\x8a\x9f&{\x92\xda\xad\x1db\xe2\x85\xb8VE\x06\xcf\xf7\x85 \xde\xae\xec\x13\xad0\xe6\x9bak.X\xcc\x00z\xec\x0fBz\xfc\xc4\x0d\x9b\xf7\xab\xfd\xe9\x8f\xb4\xcce),\x99\xf2\x15\x06Qch\x10\xeb4\x18h\x9e%m*\x97-\xd2\x8f\x93)aB3\xdek6\x81\xab\x89\xa2w\xb3\x1d\xca\x8d\xd4\xac\x1dZiG\xa3sbk\x9es\xe0\x16\x90A\xc1\xe4\x00\xd2\xfe\x0f\xf9lF\xcaS\xab\xf95\x03\xa3\xc7\x8e\xb7\xb0\x1fe\xb5\xb7Q\x8a\x8d\xccJ\"E\xe2\xa9(\x89\xee\x0f\xfc\xc2X\xdc}\xdf\x1b\x988\xda?''\xabp\xf2\xf9\xe7d\xb1\x9eE\x8b\x05\x0fY\xe9O\xc9*%\x93Z\xedG&O0\x96t\x15\xd29k}4\xc6L\xf1\xf3h1MI,\xbe,~\xb2\xe7e\xb9\xb4)\x99E1\x91\xfb\x0bqr\x91\x84S2\xed\xe9\x14\xab\xa4\xd8a\xfbz\x0e\xa2K\xd1\x19\xda_4\x1e7\x95\xd4\xe6qF\x7f\xc9\x18#\x8716Wk\x08\x83J\x02\x9b\xced\xd4 #\x0c\xea\\t\"\xee\xdf\xd1p\xcb\xb8\xdf\x92~\x94\xb1\xfd4\xe5Q\n\x95\x97\xf8f:\x80\xc8\xcbQ\xe5\xa4\xa7;a\xb7\xb1\xdf\xdd\xbd\xaaZ\x91\xf2\x83\x8d\xd1\x81\xb4]\xb9\xd8\xbe\xb74g\xaa<\xc9\xe5;Z\x87\x17\xa9!\x10\xfa\x05\x91E\x90\x8e\x85;_\xcd\xdf\x84p\x8f\x92H\x16'\xf4\xe2\x9a\xa9\xeb\xf2\xaaX0\xb8_\x97\x818\x16|\x7f\xbf\x15\xc2m\xec\xc4.\xf72\xf0\xb8\x1a\x88\x07\xf1\x17\x9cD\xa1X\xe1\xd2\xe0#H\x1e\xfa<\x85\xe8(\xf2\xc8(\xde\xde\x1e\xfbc\xbdv\x8f\x7f!\x082-h\xebU!\xa0\xd7\xd9\x0d\x1a\xd8.v\xc1^\xfd`\xe3\x8a\x8c;\xdf_\x05^bJii\x18\x8c\xc4{\x07\xc0\x90a\x1f\x12/\xaf\xb8 9M\xae\x97g\x042\x9aF\x13\xaa\xa8\xf6*^X\x0d?\x11\xe9j\x13{\xdf?\xa8\xebF\x94\xe9\x1c7E@&\xbas\x98\xdd\xfb\xbe\xf6\xe5q\xff\x1d \xa7\x8cN\xbe\xa7\xfc@YV_`\x80\xbe\xeb\xf7\x0f\xcfHL\x0f\x97\x11\xa5$mv\x10\xb6\x81Q^%\xd1\x8f2Jb\x92b\xd1M\x8er\x8d\x0ft\x96{\xb1%\xea(\x01\"\xb88\xf6\xee\xef\xfa\x82\x03h\xbe1CA\xfdc\x14\xd3\xfbH\x07\xd9\x9e\xad\x9c\x9f\xcd\x99-85\x1b\xd4\xc0\xb6\xe8G\xf1\x9c\xa4\x11\x15J\xaf\xbb\x1a\xf3\xc0\x8a\xa3\xdd\xdd:\xb1\x06\xa12\xd0 \xd5\xec\xfe\x8am\x9fU\x7fJN\xf2\xd3Er\n\x07\xca\x0f\xaf\x97\xd1\x94\x84\xcb\x9e\x0f\xfbmC\x9f\x06(\xfb\xb3!\xd4w\n\x08\xe1\x88\x81\xb2\x8eK\xe5\xd4\x98X]7\xf9\xb3\x86O\x19\xf7\xd0#i\x9a\xa4=\xc6\xbd.\x92\x8c\xb0?\xa6$\xa3i\xb2f\x7f\xae\xc2\x9c\xdfKI\x96/Iol\x8a\xd6Y\x1a\xd1%\x01\xa1i\x8e\xbd\xbd\x81\xa8a\x81b\xab\xae\xbe\xa0$\x16\x04\xa28\xa3a\x94w\x86\xe5S\xdf\x0f \x13j\x85F\xb6?\x13 OJ\xe5\xb8)\xdaS\xe1!h\x0d\"M\xb0 \xdd\x147i{ym\x8f9q \xa8\xaa\xe2{X\xae\x93^\x89\xc7_\x14xfSJ\x9e\x15\xc5\xdd\xc4\xcb\xacu[*\x15\xce\xc3J\xaa\xc4\xa0N\x04\xdd\xe2\xaa\xd1\xd8\x0f\n\x9d?l\xb3\x86\xab\xd4\x17\xf6\x8b\xaf\x0dJT\xed]RR\xae\xdd\x00\x0e\xb5\x86I\x06\xba\x1c\xeb,zH\xb3\x11\xdf\x9d\xe0\x8aP\xd0\xcf9\xe5Uy&\x85F\xc4KQ\x15\x92\xaa\xdbf\x86\x94\xa6\x19}I\x94\xb8\x83a!\x0c\xd5NK\xcc\x12\\u\xaa\xe8\x1d\xc5g\xe1\"\x9aB\x9c\xc4;\xbc\xd9[\xe2p\x98\xcc\xf3\xf8s\xcf\xb7\xc5\xd3\x18&\"\xb6\xb5\x06n9: \x06\\*A\x02\xee\x15\\L\xc2\xe0\x99\xd7\x86,\x1c\x89\xc4*?\xc6\xc8\x1f\xcf4\xff\xfa\xc7e\xa5\xf9\x9f\xa5j\xf3\xed\xcc#<]\xb1bND\xd8\x10\xa7\xe4#bn\x13\x0c%\xd7\xe3\x06N0e\xa7\xb4z\xe45\xe7\xcb\x16B,\x02\xe7(\xfby\x9c\xcd\xa3\x19\xf5|\x08g\x94\xa4@\xe2)\x10\xc6\xf5\xf7\x10\xd7\xce\x11\xedd:;\x04\x16GU\x97\xb6q\xcb\xc8\x86\x0f\xdf>\xe7M6\x88C^\x1c\x19L\xfa\x8f\x19\xb4 &>\x92\x9b\xf6<\x8d\x84\xae\xbd\x0em!\x85\xcb\xb5:\xa8\x8cw\xc0z{[\xee\x9b\xea3\x9fW\x8fb\xcbP\x1d\x90\x0e\xfb\xea\xaa\x83\xb6\xb5\xda\xa2\x02LH\xb8\xab\xdc\x04n\x92\xa2HV\x8d9,\x99.j\xa4#\x97^\xeeF\xe3\xcf\x15\x1a\xaf\x1b0)\xb8\xa8\x9b7\xe5\x1eVh\xdf\x16\xe1l\xd1\x01\x9b\x02_\xebiHC\xb6\xd4\xa8\xf7b@\xf3v\xf9\x9a:\x12E\x8e\xa4\x05M\x95\xc8\x17\xb36t\x94\xb6\x02\xb8\xff?{\xff\xbe\xdc6\x924\n\xe2\xff\x7fO\x91\xc2o\xc6\x03|\x84h\x92\xba\xd8\xa6M\xeb\x93e\xb9\xc7\xd3\xed\xcbH\xb6\xbb{\xd8\xfa\xa9!\xb2H\xa2\x05\x02l\\(\xab\xc7:\xd1gw\xcf^#\xf6\x01\xf6\x9f=o\xb0O\xb0\xb1\x11\xe7MN\xef\x03\xec+lTV\x15P(T\x01\xa0,\xf7\xec9\xdf\x87\x88nS\xa8B]\xb2\xb2\xb22\xb3\xf2r\xef\x1e\x92F\xc7e\x8bJL\x9a\x16\xfa\xe85\x87\xe7\xd2}C.\xb8\x18\xd4\x9d\x1b\xa9\nU\x17$\x85\x7f\xb8wO\xf7\xba\xe0\xfc\xaaK\xac\x91\x81\xdb\x05\x0c6to\xd7\xf6OO\xf86F\xc3\xe7%\x83\n\xc1\x88\\\x8b\xdf\xe5\n\xe7Y(\xd7\xc9\xffRj\x15u\x1a\x0f3&\x0d vdA@\x11D\xe3\x06.7N\xeb\xb6ix]\x8es\xdf\xc8\xec\x08\xf5P\x19\xd1C\x91\xebN\x1b\xa9\x80.\x02\xd25f\xf1\xa6r\xf3,Hv\\f\xb8\xa9\xc0#\xc8>\xbbl'\x98\x99\xd1qyg\x8eK\x19\xb9\x92SB\xc5\x9fC\x81 \xdfs\x8d'\x0f\x9f\xa3\xd4<\x93 (\x87\xa2z\xc4+]\xf8\xc9[/K\xca.P5]l\xf5\x8b\x94_\n\x86r\xfaT\xd7YBd)\xa9\xd5\x9c\xda\xc91\x95\xcd\xa2\x885\x86z\xb2p\xc3j\x94G_U\xac|\x84\x11<\xdcy\xf8p\xbf\xf7\xd0\xa4/95\xa2n\xae>\x7f2b\xfe\x8dU:N\xf2#\xbb\x87d\xb6B\x9dS\xa6\xf0=(\x1f\x08\xd2\xa9\x9a\x93\xe6\x05\xf1\xa6]z\x08\x88\xb2aQm\x88a%\x80(\x07\x1ac\xa2U\x8dA3!\xcb'\xf6t\x04\x1fQ K\xff\xa5\x9dloSY\xeb\x13\x1d2F\xf7*\xfd5(\xfd\xb5[\xfa\xeba\xf9\xbb}\x17\xd2NG\x9bk\xe0\x86\x9d3\x08U \x0e\xe8!\x92CS\x9e9\xa9h\x0cz\x98\x9f\xb9\xd59}\xac\x87Bn(\xd7H\x8f\xaa\xbd\xf7\xe9\xe9\xa9*+(\xd6/l\x8b\xbe\x16\xef,\xb7XtG\xf7\x0d\x9bI\xce \xb0|\x1f\xef\xfc\xc9\xa5}\xc8#/\x1eV\xdceM\xf3<\xd4\xcf\x93\x0f \xc4$-\xe4.\x18\xc3!\xbf{\xd56\xa0\xcb\x1b\xe3n!%}\x08\xb2\xe0\xaa\x86\x04\x9d\x8e\xf2I\xfe\xa4u`2u\xfc\x93\xb1\xe3\xd2\x05Ln5FY,\xc1z2\x86K\xda\x7f[\xa4\xe0!I\xc10\xea\xf6\xd7\xc2\xb6\x96\xde\xf5\x05\xa1\xab\x86\xf3@\xf5B\xcf\x92\xd94\x17m\xfb\x8a\xce\x9d\xc7Ny0\x0d\xc0\x1a\xa9\x89\xbfL@\xb84\xaer\xae/\xa1\xe0M\xfd\xc9\xa5n\x9c\xad\xfax\xd9\xbc\xc2\x02\xdb\x99\xe6M\xd7\x13\xe2\xbb^1G\xaa\xca\xb4\x1c!Q\xb3\xcd\xd1\xd1\x05u\xc9\xa4\xe5\xdclJ\xaf>\x97\x08 \x8a-l\x8b\x8e\xa7\xb4\xad\x1f\x97\x07\x99\xa7R\xe6\xe3s\x1e+\x02\x8fi\x84\xef\x9a\x0e!\xe5\xe89`]!u\xac0J\xf9\x91\"\xc4\xcf!l\xa5\xec6\xf5i\xa9\x0d\xbb\xa4\xc0\x91\x0f\xa3\x9f\"?\xb4-\xbc\x13\xe9\xf3\x9eyI\xcd\xc1%\x0b\x1a\xdc\x9f\x92\x14>\xb1EQ@\xbc\xd8F\xd9&\xd4X\x94\xd6\xa9Z\x0c\x1a\x8a\x94\xed]\xf5\x00=\x00Lu$\x97H\x91B\\\xb9@[-u\xf2,\xc8\x1c\x06\x9a.\x88\x04\xe5p\x93\xf0\x96\x05\xc5\xa2\xad\xea/\"\xc4\x13Wmt\xd5\x07\xef1qlf\x15\\\n\xdb#\xf0\x8dDI<\x88\xed\x8f\x81\xc5r\xa4\xf4\xa46\xf7\x14\x08uf>\x80\xfa\x81\x82\xb8\x91\x81\xa7\x10\x15p\x8c\x8a\x13\xbf!\xb2\xb2?\x03;c\xd6I\xc5\xe7>\x95\x8e#\x18\xf2\x1f\xe5\x85f\x9b\xc7\xc6\xe9g\xb5\xa6\x96\xe2\xa9\xb4ow:\xb1\xcb\xc1\x81\xab\xbe`Zf\xfefX\xbc!\xdd\xd4\xf3\x03\xae\xe7\xe7\x02\xbc\xa8\xecr\x08A1\xc4\xcc\xa4\x91\x93\x1f\xb3\x85\xa7xn:\x1d}xc0jFA\xb2m\x17\x13\xddFw\xa0\xaam\x0e\x085)q6\x89\xab*p|\xd2\xf5\x82 \x9a\xbc\x0f\x13oF\xdaE\xe1m\xb1+(\xca\xd7\x98\xc5\xc6l\xa7N\xa2\xd55\xaa\xde\x04\xe7c\x97\x83\xe4\x8b\xe0\xbc\x1eSaS\x9c\xf7k\xc2]\xb8M\xc1\x974\xb9\xee\xf0+~\xde\xb9\xc5 K\x19E\xc3ev\xb9{\x13\x9bp\xf4\xb9\x8c\x0c\xbb\xde\xe1\x13\x7f\n=\xd95\x93)\x98\xffd\x910\x17Ql\xc7\x024\xa5\x9dB\x14\xe2\x9d\x02Y\xae\xd2k`J\xe8?i\xe6Bd%9\x13\x02\xe4\xfb\x17\x89\xfd\x7f\xabMrb\x8c\x1dj\xd6\\)=rU\xa1\x98$\xb3\xd2,_V\xf7\\\xce\xcbVD:\x9b\xce\xdej9\xa6\x93v\"I\x8fk\xbfr\xc9\x84\xd9\x93C\xd8\xe9\xe8/\xb20\x1a\xfa8\xe4vq\xc5\xbd\xaaQY\xb6\xadJ\x0f\xf2_\xb2B'f{\xb2^C\xc0\xa5 \x8b\x9d\x9d)\x8c`\xe5\xc5 y\x19\xa2[J_\x17\"e]\xf2;+\xe1\xa0\x9e\x12b\xa43=z\xf2\xf5\xe3\xca\x0d\x9dQ@N\xdd\x98\xffyE\x93-a\xf8\xa8\"\xd3}\xfa$\xd4\x0c\xc5\x8d5\x9f\xf1\x10*\xe2;k\xc7\xcd?qku@G\xec\x92\x18\x86pl\xf3\xcblJ\x10M\xf3\xe4\x04z$TP\x8e\xd4\x9ac`\xfc\xef\xdd\x13\xbd\x98\xdaF>\x99\xa5\x13-\x83\xc6\x88>\x0b\xdb\xa2\xf5\n%\x01\xe6\x15\x11#$\xd2N\"\xd2IS\x95\x97q\xfc\x0b\xdb\xe2u\x02\x92$\x90.\xbc\x10\xaeh\x8d\xa5\x17_Zl\\\xa8\\\x15`\xc3f\x85hw \xd6\x82\xfe\x11\xe1\x95\x19\xde!\xf8l\xe1\x91\xbf\xe3R\xf94\xc2\x01[\x8e+}_R\xa9pMQ\x05\x80:\x8dRI\xe3\xa8*\xd5\x1c\xb9\xc9\xbe\xab\x08\xc2l\x05C\\A\xbe*lic~\xc4\xf7\xe0 \x17\xf0\x86\xfc\x88<0\xe8\xb5\xd0\x0e\xc7\x91u\x7f\xdb\xa8\xec\xd4\xce\"\x07\xa0aFa\xb1\x95$\x85\x07\xc7\x1f1T\xd4\x8d\xe7\xd7(\xa5\xbb\xa8\xb8\x92w\\Q\x10\x9f\xb7\"(R\xc3\x9a\x0bM\x06q\x07\xfc\x04\xc2(\x05\x7f\xb9\n\xc8\x92\x84)\xa9\xd2a\xe5\x06\xc2_\x91\xd67\x10\xb5\x01\xd5\xa2\xb6\x97\x13\xc9\x95\x8f\xae\xc6\x91d8eb\xad&^B\xa07\xd4\x96\x01:\xe0\x0b{\xac\x1af\x0f\x99 }1\xb6\xdfo\xd3\xfe\x98\xfft!\xad\xc9\x13S\xd3\x15\xbfOi\xec\x8b] 5^wI_0\xd3\xb3\x0e\x95n\xe9\xce\xc7%\xc5 \xa0\xa3?N!Z\xa5\xc9\xe8\x8f?Yn\xa9\xb6\x9e\x1f\xa3\x8b\x8c^([\xcc\x90\xb0\xcf\x15r$\x9c\"YJ\xf9\x1dP\x92N\xa3,U\xde\x908\xa6\x92;\x0c\xe1\\\xb9%\x80\xb2\xc3\xb5\xce\x88X<\x0b\xdb\x8a\xc2,\xa4\x03\xb5\xd8m\x92\x08\x88\xca.\xdf\x99\x1e%\xee.\xbc\xe4=\xd6b7\xd8\xa5\x17\x8c\x06,lk\x12\x10/\xccVB\xa7\xb6\x8c\xd6\xdc\xf6\x8d\xc4vn\x1e:\xd7\x96\xce\xfc\xd0O\x16\x96\x0bKm\xf14\xf6\xfc\xd0r!\xd0\x96\x8a\xfdy\xad-\xe5\xb3saB\x89G\xf5\xe3\x90\x92\xeaYM\xd9\xb9\xb6\x8cS\x9b\xb5\xe3\xa2\x85/\xde\x82E\xb2\x96\x10\xaf\xf5\xcf\xafb?-]\xbcn\xa9/\x91\x08\xe6\x9f\x04\xfa\xa8\xf8\xe6\xf5\x9d\x19\xaf\xa2qm\x913d\x86{\xd3\xc68P\x808^2\x18\x91x_\xe4\x11\xc2n\x14N\x88\x00\x0dZ\xbeu\xa3\xb0\x04e=\x9e\x07\x8d\x14\x174v\x15Mrz;\x01B<|\xb3\xbe \x9fs|\x92\xd5\xba\x8e\xa2\xe5\xc5\xf3\xa7\xf8{{\xbb8\xcf\xca\xb58\xfc\x8c+\x8cQ1m\x886~(h\xc1\x7fc\xeb\x84-\x06\xe3b\x17\xe8A\x8cx\xa8\xd1-\xac\xb9+9-3#\xd2\xda\x9c\xab\x171\x89M\xd0\x05\xa1\x12\xe7\xd4*\xcd\xadq(\xfa\xb2\x83\xdd\xees\xa9\\\"\x97\xe8}\xc4\x89\xbb\xf0<.Ux\n}Z\x89\x87_=\xb1\x0b\xfa\xcf\xe3t\xae\x04\x135\xf3\x82\x84\x00v\x0b1IVQ\x98\x10\x17\x84\xady\xa8^\xc0\x96\x96\xb8\xa6\xb4\xd3\xe1\x93C.\xa4\x8b\xedm\xba\x1b\xaf\x1b\x80(H\x15q\\8\xb7\x1b\xa9\x19C8\x86`\xec=;\x17\x14\xc6D\x17L\xb1f\x90s\xe3\xb6j \xcc\xe7Z\nb\xeehYO\x9bx\xdb\x8d\xc7\xc5\xa6\xdd\x9e\xd7u[\x1cva\x97\xfdnw\xf6\x0by\x96\xed\xc4\x9c\xf8k\xbbi{;\x00P T%\x1b\xfb\xaeb\xb2\"\xe1T\x00\xa5\x08P\xae\x96\xb0h\xcd5*\xf4\xee9\x9a\xf0%\x0cy\xf8\x1fcr\x06\x07\x90\xd9\xf2\x0b\xf4n\x92\xfe.[d\x95>\x1d\xc18tK\xaf\xce\xb0\x8a\x08\x1e\xad'x\x12*\x8b\x03\x9b\x1d(e\xfe\x80\xbdS\xb8\x02\x86\xf4\xfc\x9c 1f\xa1 \xb4\xfcn\x0fY\xb1\xe2F.\xe4\xb7y\xb6S\xb9\xd4\xaf\x18\xc1T\x18\xf3Z\x9d\xd5&*\x03\xf3\xda\x17L\xd4P\xbdL\x15\x8f\xc6\xc9\xa5\x90\xc3I\x89\xa3\x17\xd8\xa1\x0d_O?\xea\xd7|T0\x97\xbc\x9c\x07\xccfV\x1cBb\xe4exT\x96\x1d3H\xc5+\xa3t\n\xf6\xb95\xbcX\xc4\x9c]Hy\xc4YnH\xaf\x1f\xf8Vmp\xd2\xb8\x18\x98Y\x83\xedCy\xe6\xfa\xcd\xb2\xe9\xac\xf4\xad\xe4\x8a4\x16\xe7\x1a\"x\x02\xfec\x88:\x1d\x07\xe2qtf\x82A\xad\xc2\xb6b8\x04Z2\xb5\xe61\xdcNlR\x9c\x9f5:8D\x89LZl\xfeY\x97eg\xb03\x17\x9d\x97K\x80\xd8F\xc9\xa7\x8aM\x9c\xf9\x11 \xe4\xbf\xc6\xbd3i\xf7\x9a\x16\xbensF\x95\x1b\xd7:\x899)}Y\xb8Ap\xc3\x0d=\x861\x8a\xce8\x13'gm\xcc\x06h\xb9\xeaA\x10\x18\x8dRY\x84,)lVD\xfb\xf5\xb8\xdcJ\xa8\x07\xbc+*+\x91c\x8d\xcb\x11\xdd\xb9\xba\xf7\xecB\xa4\xa2\xc9\x89\x0d\x0eM\xb1\xa4\xec\x8a%}\xceq\xae<\x94\x04\x85K\xbe\xa6\x9b\x1c\xabu\xeb\xefM\xf3\x93\x0eF\nf\xb8\x8a\xaa\x18m;Z\xc4cL\xdb\x02:?s\x95\xa3\xa68eR\x85\xddo\xc4T\xe0f)eC\x13a|T1?)\xdf@\xbc4GP.\xa2\x9c\xeb\xec\x0c\x15=\x14\xe5n\x9b\x00U\xa8Z\xe9.b\x1c6\xf0\xc92\x1dG\xcd\x16q\xdc\x96\xfb\x08\x0fnd\xde\x0d\x16\x94\xca9R(\xe6\xf8W-\xa6{\x15{\xab\x8dN\xf7\x9a\x1b\x80\xb6g\x7fl8\"\xf2\xe3\xc1\x07?\xe4\xa2\x1d\xd7B4\x89\xbd\x94\x9c,l\x8b\xcefE\xa6\xc0\x85\xfb\xb0\xec/!t\xf1\xf5\x92s\xca,\x1f\xda\xb9A\xf1\xb3[\xbe>0i\xcd\xc0x\x8dI$S\xed*\xf2\xe6\x9a\x04\xce[\xe7\xb00&\x1e\x94!!\x84\xd3\x12(l\xbf4G&\xa7\xfa\x14]\xb6B\xc5o$W*\xa3\xa6^\xb2\xde\xf7\x99Ho\xab\x1f`=a\x95\"\xc4~\x9c\x9f\xef0\xa2+t\xe3\xb9 \xa9\xdb\xb2\x0e\xdaLJ>S\x14\xbb\xc6\xfe\x19\x94\xe3\xd2JR\x01/\xb4EE \xa9\x9b\xdc\xed\x1b\xd1K\xaa\x9bR\xe6\x9f\x87\x81\xadM\xe5\x07\x065\x86\xaf\xbb.\xd7qF\xf3\xfc\x8a\x11\x19$D\x82\xf98:\x93vz\xf7\xc2\x0f\xa7\x9c\xba\xd1\xa2\x1a\x8f\x9cT\xf6\xa6l\x86\x8c\x84B\xe7\xfc\xfe\x908\xc2\xfb;\x16\x14\xa7\x10#\xaa\x13\xd5\xd3\x9e6\xee&\x82\x84\x94|\xbb\x9b\xa3\xd8hL\xaa6rM\xd1Q\xd8\xd2\xc5Qu\x8e\xe5\xd9\xa1\xdf\xc7\xf9,\x8e\x96\xf4T\x86\x11\xbc\xfb\xa7\xa2\xac\x1c1\xdb\xc50\xd8\xed\x02g\x97bpW\xa3M\xb4iB\x1fNc]\x84\xbaz\xa4\x8dI\xeakO\xea\x1a%\xcb\x8dv\xd0\xe5\xcf\xb9\x1bK\x0b\xbb\xa3[_\xf5@\x93\x1bQMd\x01\xfc\xac\xa2\x9c\xd6\xbc.Z3\xee9t\xb2\xce\x98\x9b\xde\x01\xfa\xe0\x14\xc6\x9b\xed\xfbA8\x97\xb8\xd9\x9c\xe7\xf1\x85\xb8 |,\xd0Z\xc7\x00\x91F\xcf&\xe9\xde\xb420\xbb\x16\x02\xe5\x8f\xf9k;\x8f(\xee\xb6Ppo\xf1$\\\x07\x94-\x97'\x18\xb2\xd9\x85\xbaA\xa9/\xcb\xb0\xc2A\xe1\xed+\x9e\xccZu\x96A\xcc*\xfd\x99;d5\xd0\x92[\xc3\xbd\xafg\xef\xe2j\xf4\x85\x8a\x0b\xcd\xb4\xb6\x05%\xaa\xc3\xe7,o_\xfb\xadf\x04\x95ru\n\xe5\nL\x95U\xdf\x86\xb2\xa8\xaaO\x95B~>?\xf6\x9f\xec\xa4\xc8\xb0\x12#H\x84\xec\xd4\x9a\xca\xe1\xf0\x13\x12\xcch\x15\xfc\xf7\xd3'\xb8\xf2\xc3itU\xa5/\xbe>\xb272\x12&_&}\x00\x7f\xc81\xcd\x9f\x16\xaeS\xdds4\xc4~\x816\xc8\x06\xf0\x00\xf2\x9a I\xdf\xf9K\x12eiK)'$W\x10\xd9>;\xc0\x8a\xaf1\x1cB\xc1\xff\xb8\x80\x03\xe0\x85\x15\xb5\x05\xf6\xfb2LI\xbc\xf6\x82[v,>\xd7\xf7,J5]\xcb#C\xfdK\xe9\x83F\xf1\x873\xf9\xa8\x88\xad&\x96\x8fJ\xda\xd2\x98\xcc\x94\xec/\xec\x8d<_\xe5#l\xb7 $\xa55f\x10\x89\xdd\x1c\x0f4s&a\x1c\x05A\x1b\xfd\x90\x0c\x1d;\xa5\xcd\x05\x84\xff\xf9r\x8a\xd2\x87\xfc\xaa\x8a_\xb4\xb7,\xd4\xf4w'\x9d\xa9\xd6p\xb4\xb7s\x84\xf3\xe1$\xf5\xd7\xe8'\xda\xf5\xc4\xcf\xcf\xe9\\\x7f?\xc8/R\xa5\xaa\x1a\x8dV\x91bQm\x15FPl\x99\xe6\\ri\xf7<\n\xc5\xe4\xd9\x9dD\xfe\xb7\xee\xb2G\xe3q\xe5bD\xab}G\xec\xb9\xe5\x92L}\x16\x9b\xa5\x99\x84\x95\xbfP\xb2e\xb2\x01\xa95(\x0e\xe6\xac\x8b\\\x98\xef\xbc\x0d\x87\xa0|\xa3\x1dD\xb5Ni\x18\xe5\xe2\xe2|\xb8M\xde\x9a&\xde\xd9\x14P\xcdGU\xa2\x9f\xc8Q\x88\xea\xd1S\xd8#\xe1\x8d\x82eA\x07R~\xab\x99F\xdfDW,W\x8em\xb4\xfeF\x13\"kA>Zz\xd3\x1eV\x8eq\x90\x1a*l\xd7\xd7\xf0\x92\x89\xef\xd7\xd6\xb8\xf0C/\xbe\xae\xaf\xe2%d\x7f\xb7~$\x93d\xd0Ta\xbb\xa1F:\xeb\xef\x07\xa4\xa9\xcevc\xa5\xd8\xbb2\x94\x83\xe4\x9fm\xc8+\xd9hq\x95\xfbwWwxys\x1b\xf2\xfc\xe8\x18\x19Ee+\x90\x0b\xf7\x07i\xeb\x07.(`3\xff.\xae\xa3\xf8T\x18\x9e5\\\x03\x91\xc7\x8f\x9db`u\xca\x97F\xdc\x85V\xf8+\x9e\x16\x83\x846h\x08\xadP\x11Z\xa2#\xb4EI\xf1H\xd3\xc0\xdaM3 \xbc\xd4\x0f\xfb\x8d\xbd\xd7\xee^\xf1\x88\xbey\x9bM]\xd7nwhEZ\xa0\x05\x8d\x13\x8fP\xe9\x98\x87\xd5\xb8'A8X\xd4\x87\xd8\x12\x0f\xa5\xd96'\xdaez\xcdbQl\xf5\xb4\x9f\xeb4\x84\xba{I\xbc/\x13\xd12\xb6\xca\xc1\xc5\xed\xd213\x1a\xf1X\x85,\xbdQ\xd5'\xc4z\x1f^\x86\xd1U\x08\x82\n\x0c\x81\x0d\xdb\xa8\xc7`\x07l\x99\x12\x15a\x1d\xf2\xb8t:\x8e\xab\x05\xdac#)\xf9(\x92\xc6\xb06)\xe74a\xa0\xd3Dh\x04\xb3\x89k#\xa9\xc0\x0ef~\x10|\xe3\xa1\x96\xce\xbb}/\xb5X-\xcfkV\x9aW\xc0z\xdc\xd9\xa8\xc7Z\x84\x95U\x98\xcc\xfek\x04+\x96f\xdc\x96:^\x98$g\x10\xe3\x0d\xbc$}MP\xce\x16\x81\x11\xe9\xabwQ\x8a\x82\x92\xfc\xeeh\xe11\x8f:\xd9\x1b\xb0\xa4\x0c\xcc\x7f\xe6gUV\x13\xd6\xfa\xc9\x08\xfa\x83\x07\"c\x03<}\n{0\x1a\xc1>\x1c\xc0@\xbc\xd9\xa5o\xfa\xbbp\x00;\xe2\xd5\x0e}\xb5\xd3\x83\x03\xd8\x15\xaf\xf6\xe9\xab\x01\x1c\xc0v\x1f\x86\xb0=\xa8\x1d\x92g8>\x852\xb0\x98\xfev\x19DU!\x7f\x13\x07h\xb4;\x19<\xa4{\xd9\xee?\x1a\xc0=L\x0f\xebH\xb6L\xe5\xa5\xb0\xfe\x9f\xff\xeb\xff4PY\xf40*\xaas{A\xc91\xac_w\xb4\xea\x06\xd27\x0d\xa4_;\x10\xd0\x0df\xa0\x0c\x06\xffV;\x1c\x98:\x1c\xf0\x0e\xdb\x13O\xae\x0f}\xacC2I\x90\x08\xd1\xbd~\xa8`\xfd\x13\xc9\xd7\x0c\xa3y\xa1Wf \xe5qY\xe5}@?t\x94}\x91\xa7l+\xf3[nuS\xb1\xa8`\xb5\x1d\x89\xcb4y?\xe7#\xde\x96\x02\xa0\xd5\xef\xbdD\xab\x01\xa0\xebe\xa7\x85'\x10q0!\xf9\x08\x1dWjt\xf2\xc5\x0cs\xf2n\xb6\"\xa9\x0f\x03\x80\x97\x91\x93\x85\x17\x1fESr\x98\xda\x92\x07\xac\x1aWZ<\xb4\xd1\x98J\xdd{{\x83G\xfb\x80f\xf9OF\xb0\xb7\xbf\xd3\x7fT2\xf8Rp\xa9B\xd0v\x95\x85\xe3)\x9a\xc7\x12D\x06gj\x9d~\xa5N\xff\xcc\x85\xb0pS\xd7\xe6\xd9\xae\xbc\xd1\x9bxh\x89\xa32\x93\xbef&\x83\xe6\x99\xf41\xe5\x85v\xe1\n4C\xa8\xd7\"R]\xaa:\x90\xef\xc3\x0f\xa4\x03\x89]~X\n\xe5@jQ\xdaH\x0d\xf7@fr\\\xc3\xbdtL\x9bS\x82@\xaf\x1a\x0eL\xb7\x12\xa4\x1623\xed\x16\x13\xe3\xafl\xb3\x1d-\x91\xeaq_\x93\x83\xd2ZqV\x83\xbb\x9d\xd9*F\xec\xc06\xde\x94\xa8X\xb1#\xec\xd1B\xb1\x1a\xb5\xf8Qj\xfa\xb3\xf6\x83\xe3\x1a\x86_\xc2\xb4\xb0\x81f\x05w\x87j\xda\xadtP\x8b\x1d\xf9\xa0{.\x02X\xc1\xd4a\x036\xac\xcc\xcc\x8e\xe1|\xa8\x07\xc6\xa2\x86yj\x82\x85\xd4\xb0\xf8E\xca\xd1\xdcX\xc6\xc7\xa8d\x1b\xe4\xa7\xf5\xc2\x7faq\x9b\x9fA\xb9`\xa8\x80\x1f\x97\xcdU\xdd\x9e[\xed\x7f\xbfHB\x87\x9e\x989k&\x98x&\xe7\x18:\x06\xd9\xba\xf12u\xbd\x84\x02>\x1e}\xae\x9a\xdeJ4\xb2\xbd\x8d\x83\xa1\xab\xb7=`bv\xdd\xc0\x90\xb1\x92F\xe6\xb4\x1e\xc3\xe0\xf7\x1f\x03o\x0bC\xef\x8cD\xca\xbc\xf2\xa8v\xf4\xa3\x12\x9d\x97\xb7\x8f\xd9\xb0\x98\xe9 \xcb[\xbeJ\x15E\xb8~\xf5\xeb\xca\xf9\x16V\xa9\x8c\x1c\x9e\x01\xb6\xc1\x0e+\x94[\xbf1\xb4,x\x8f\xf9M\xeb\x86FKL\x1bFR/\xd4S\xcf\xf2v|\xa2!\xa4\xfaq\xd5\xf3Bw*\xa0(+p\xeb\xe1\x14bLy\xd2\x92\x04\xa3\x9cR\xb7\xba\x99)e?/^\x17\x176\x035y\x1f\xcfq\xae\xcf\xcb\xac\xd1\xae#\n#\x04J\xd9T\xca9\x13\xa2j\xda\xf0\x92\xc9}n\x8b\x91\xc6^\x98\xcc\xa2x\xc9\x8c1tn1\x18\x17\xfc\x9d\xa8\xd7\xc2r\nT\xaeY\xe9E/T\x85\xdd\xbcV\xbd\x1fG!\xb5\xe1y3\xb90\x0bi[qY\x1c3\x06\x0e`\xcc\x06\x85\xd0\x857\xb9\x14qj\x96Y\x90\xfa\xab\x80@\xea/Ib\x8cw/\x06\xb2\xc8\xc2\xcb\xdcG%\x1f]\xf1\x86\xa7\xec*L\xadx\x1aWW\x93O[<\xe2\x80apl\xe1}\xe0+\x86;\xb6_ k.\xecc\xe1 \xf8\x9a\xa8\x1bEW\xb6Z\\\xe9\xf1\xa6\xb0\x01\xd58\xdd\xd1\x8e%\xc4\xd1\xd9H\xcak\xae\xaf\xc1\xc1\xc8\x82]\x98\x8a)\xe8kk\x14\xdafZ\xa9|\\\xe8\xad\x97t\x0154\xd5\xa4P\x1e\xb5\x89E\xf2\x89J\x06O\xc5\xbb\x91\\\xc3\x9cgd\x16d\xc9Bj\x80\xfd=\x12%\xc2\xe4\x1e\x0d\xb6W1\xc9\x1d\xf5\xb2&\xbd\xa8\x8e\x9d\x12\xbe\x18e<\xd3\x8fL\x1a\xcd\x81\xfcW)g\x9a\x96\x19\xf3r\xdaZ^\x14\xcaDz\x9c\\\x15\xfb\xa7~\x1e\x9e\x89\xeb+\xdd\xa4hLH\xabLB)\xb1`Z\xc4\xba\xaf\x84 \x10\xe7e\xe5\x9e\xe3\xc8\x0b\x02\xba\x0d\x8bE\x9eF!\x81\xab\x05 \xe1*\xcf\xa8\xb45\x82\x9e\xa5\xe9?U\x89f\x89:n\xd8]\x92\xfaAP\xdajj\x979d4\xbe\x00\x85\xcc\xe6W\xf2\xaa\xb9\xd2;;b\xdcJ\xb4adw\x99@\xab\x93.Q\x90\xdc\xe9\xa9\xdc~\xc5\x97\xac\x18yy0\xa5\xfd\xd6$(T\x00\\|m\x080c\xec\xb6*\xc9\xea\xbb,{\x9a\xd5\x9d\x99(\x9b\xc8\x07\x0c\x85J\xe9\x10J\xf37\xd2m;qa+V\x10I/\x1e\xb5>r\xecXY#<_\xbe\xd0\x89sc\x04\xb1\xeaYP\x7f\xa9R\x0b\xdb\xdc\xe7\x84\xc8\x10\xc5[\x04\x01p\x16B\xb8\xc4\xae`\x0c&\x95\x81\xe9U\xb8,[n\xd4\x15M\x16\xfc/\xe9\x96\xb9-f@\\\xdd\x06=#$Z\xe6i\x90\xf93\x95Q\xac\xb6\xa6l\xb1z{\x0c\x96{=\xe4D\x969\x90\xab\xc4]!.\xb7b\xb5%\x9eZ\x97\x89\x17sH\xcaBQ\x14\x1f{\x93E\xb9\xa2\x94\xe2|\x12\x93\x12.\xb4K\x8b+\xf0*bDSKU\xb9\x0din3\xda\x04@Lgz\xef\xde\x06\x8c\xb6\x9e\x15DK\x97\x10\xbd\xd9\x1c \x18\x04\x10\xd2qxV\xa9|c\xf3\xb4\xb8\x18\xc9X]+\xb7\xa4h\x84\xdb.\x97\x16\x9e\x0e\xfc\xfd3\x9a\x940`\xc7iZ93\xcd\xf5\xf5\xab\x96\xbc\xf6^\xdb\x98X\x16\x95\x18\x84\xa9/\xf0\xe2\xee\xde=\xae\xad\xd8\xc6\xc4\x0c>\x86\xb6\x1e\xe6\x8e\x95x#\xd4\x9c\x1d\xb9\xd5\x1c\xcb\xfe7\xbb\x0f\x06\x8eM\x87\xc4\x91\xd6K\x12\x7f\x1e\xc2\x10\x8bv>\xd7\xa2\xd0\x05\xdf\xc5Tr.x.\xcf\xe6:P\x13\xa4N\x9aH\x0b\xe8\xee+\xe8#\xe7\xcc\x8f\xaf\x95\xaf\xf4\xaeY\x13\x17x\x08@\xad\x07\xd6$\ng\xfe<\xab\xc9$.\x985\xbdl\xd1\xe4\xc1\xb5\xf6\x82\x8c\x0cA1\x02\x96\xd6\x15&^n>V\x9cN\xec\xcec\"]\xe5\xc6\x15\xc9\xba~\xe8\xe6a\x97\x87\\\x8c\x84\xc55\xd4B\xd1\xdd8\xa12\xa5h J\xa6\xb9*k\xc4s\x06\xa60\xa4\x87>B\x86\xb1\x14\xe8\xa7U\xacR,_\xaa\xe0m\x11\xcfn\xfc\xe8\xa1\xe3b:\xd4\xf1\x19\xcbl\xdd@U]\x9d\x02\x9cr>\xde8=\xcb\x99y\xfaG\xb9\n\x92=\x82\xfd<\x86t{\xfb\xb1#|\\-\xcf\x82\x0e\xd8\x9dN\xe8\x14\x1a\xa8\x9d}U\xae\x97\xf4(\xc2i\xc2\xb6f!K\x98\x8bE\xb9\xc4a\xd3\x06 \x0fq\xef\x82\xe5@\x87\xfe\xef\xef\xa2\x8dY(\xbc5\xf1\xec,\xdc\x06\x1e\xc3\xcd\xe32\xcb\xd8z\x8d4\x14\x1f\xe5\x1b\xc3\x9a\x15b\x8f\xc2\xe7\xe0\xa9E\x9c\x8a\xea\xa1\xba7\xe9\x93\xd9\xe8\nU\xde z\xf4\x07\xdd\xed\xf2\xcd\xe7\x12'&r\xe8\xb2\xad\xeb\x91\xbeTM:\xe7\xe7$}s\x15\x8aj\xcfI2\x89\xfdU\x1a)\xf6\xd3\x99\xe9\x83\xd7\xdeR\x0dh\xe2\x99\xea\x9e^//\xa2 iq2i\xd7\x98\x91`~4\xc76Q\xf1\x14\xe5D\xb9\x06\x86\x18\xc8\xec\xc4\x11\xccN!~kC\x0d\xeaW\x1a\x9b\xb6\x99\x87M\xc4\xc2\x14j\x14?\xf2\xd2k\x9b@\xee\xb2\xfa]\x19\x81L\xaa\x0e\x0f0\x82\xdb\x7fY3\x91\xed{r ]/g\xffS\xb9\x95\xcf\xdc\x15}\x1d\xff\x1b\xda\x0fUUs\xa4w\x03\xa3\xdc\xe9mq\x94\x9ek\x9a,xt\xfb\xe4\xc4n<8\xd3B!Fj\x85\x0b$w\xc4\xd8\x10O\xb7\x1a\xe18>C\x07'\xe1H\x91\xa1<\"\xbe\xa8\xacH\xd8\x00g\xb9\x8fv\xfc>\x1f\xfa\xd6\x16W\xf6\xb1\xf0\x03\xe5\x14r\x9f>\x19\xb4d\xc8\xd5\x9b\xf4\x83\x0b\xd24\xdaVX\xa1\xe7\xa3\x88\x0b\xd6\xf99I^E\xd3\x0c\x0dN\xd4\xa5D>G\x16+Yt!/N\xc8\xf7\xde28BnE\x93\x16\x7f]D\x88\x0e\xed\xbdAO\x83q\xc8\xfc\xb0\x80\x0dq\xb7\x18\x04\x1c@\x0cC\xcd\"\x0bSS5\\p\xd1\xa9n`\xb5\xa8\xaa'\x0f|-#\x91\xe3\xaf\x9bx3\xf2M\xe4M+ \xacjID\xce3\xb1\xd0\xc8q|\x88\x03I\xba!\xb9zG\x89@x\x1c\xc7v\xa1IB*\xad\x1c\x97\x1bz\x916\x11\x84\x9d\x87\x06q\x88\x8e\"\xb6\xcbs\xf0\xc3I\x90M\xc9\x10\xc6\xa1=\xe8\xed8g\x12\x12\xfcC\x07\xd3\x1f\x0c\x9c3\x85\xb0-W\x81?\xf1S,\xdf\x1b<\xc0P\x06{\x83\x87\xfc\xdfG\xec\xdf\x9d\xde\x1dM\xe2N7S\x10y\xcc[\x99t\xdf\xbd\xf9\xea\xabo\x8e\xcf\x8f\xde\xbc~\xf1\xf2\xabS|\xf5\xfe\xed\xf3\xc3w\xf2\xab\xda\x9d6\xe8\xed\xfdN;-[M\xbd\xaa\xf6\xd2@\x165\x07\xf3\xf5\x8a\x0c!\xab\x9e\x10+\xef\x9a\x02d\x08v\xcf-\xb6\xa0c\xff\xfdF\xd5\xe2\x02(\x9a?\xd2M\xa3\xf9<\xa87\x0ej\x18\x91&\xabJ>\xa2\xd4\xd4uy12\xfd\xbaYL\xb2K\xce\x19\xe4\xac*\xaf\xa8Y\xff\xfc#63K^\x81\x1cod\xad\x89n\xaeU\xad\n|\x1eA!2\x12\x8dJ\x0ef%l\xec\xef\xa9\x0c\xc8\x97\xc2F^\xa7\x85b'\xa7\xca~\xc8\xe2:\x94\xd1\x8c}U\x1d\x04\xdf\xbca\x83\xae@\xa3i\xd8H\x17\xa1\x18\xac\xa0\xa9\x16\x8b\xde\x19\xba\x9br\x87\x94\x1a\x10\xf9\x1c\x18\xdeQy\xa1\x8f\xb7\">\xdd\xd1\xd6%\xb9N\x90\x91&\xdc\xa3\xc2\xc2\x1d\\\xbc\xc3\xe47C\x16\x14w\x1c\x9e\x9d\x95t.\xa22\xdeZ\x1e\ny\x05%\x0c\x0e\xe9\xd8f]\xa0\x91\x86T\x1d\xc3\xd0\xa7\xb1O\xff\xd2\xe2O\xa3haT}7~\xb9\xd1\x01\xcc \x9a&\x18\xde4\n))\xda2\x1ew\xb7\x1c\x9d:4\xbf\x1cJyK\x96\x87\x98\x90\xfc\xeezE8o\x0c\x1d\xb0\xc4\xed\xaa\x977\xbae\xba\xafn\x18\xec\x86\x9b\xf8\x91~\x0f\xef\xedj\xb7\xf0#\x95\x05\xcbP\x18.\x1a\x0e\xed\xc1\xbecg\x94\xf2\xec;\xb6\xe5\xa7$\xf6\xd2(\xa6\xe8\xd3t\x94\xa7r\xf0\xb2\x1b\xa7F;\xa8\xbb\xba.h&\x8c \xa6#\xa8\xe2EH>\xa6t\x13i\x12\x91\xd3\xdd\x80m\xe3b\xbc\xcc\x87\xbd\x19\xb0%\xf5\x84\n?N\x1a\x1fh\xc1\xba\xdb3\x93\xc0=\xe9\xea\xa3\xc4\x94\xfb$i\xca%\xe8W\x14\x9dEf-\x17\xd7.B}\x04\xe5\xd02N\x81\x98\x06\xae\xf7\x18\x85\xbd\x07;\xbb;\xbc\x7fV\x1f;\xa2\xc8\x82\xce\xdf\xf4-\xf3\xc2L\\\xecd@\xcb2\xd8\xe6\xcdt\xe88\xb7\xf9\xa0\x9e<\x81~\xcf\x81\x0e\xec\xef\xed\xed\xec\xdf\xcd\xa6\xaf\x1c\xa9\xfc\xe0\x18\xf4\x8dg\xea\xc0\xe9\xceI*\x0e\xf9\xe6[Y\xa4\xf3\xeaIjd\xf1H\x03\x8b\x87<\xd1E@L\x0c^l\x13n{\xe4\xdcz'\xf6w\xf4\xd7#\nOV\xa10(\xa4\xb5\x03\xdb+\x92.\xa2z\x034\xc9\x8dl\x0b\xa3\xcd\x0b\x9a:\xf6\xcf0\xc0\xc5\xd8\xfa\x97\x7f\xc9\x87\x83\xaf\xa21\xa5Ng\x9b\xcd\x9b\xae\xf6\x0eJ\xbb\xfd\x1d&\xf5\x0evv\xf9\xbfLM:\xd8ej\xd2\xc1^\xaf\"\x0e\xf7\x1f9B\x14o\xd3Y#C\xad\xc3G\x99E\xf6\xc7\xa1\xddwlK\xdc\xc6\xbf\xf3\xe6\x96s\x06#\xb0~\xc1L\x8d\x1d\xba\xcf\xb7F`\x8d\xd9E\x0b\xfcrf1\x1d\xc1N\xcf\xe1VK\xa5\xe8\xbd\xa2\xa1\xba\xb0\xdd\x1c\xf2y\x9b\x16t\xe89\x80\x01L;`\x9d\x95\x9c\xe3\xb6\xda\xe9\x07d0n\x85\xf6\xee\x80%G\n\xed\xdd\x1d\xc7\x1cx\x8d\x8f\xe4\x01\x9d\xa2^\xd7\x1c\xda\x8f\x1e9\xb65\xf5\xd7Tl\xb0<\xad\x19\xccF\x81\x86\x1fT\n\xd5\x9b\xcc\xaeW\x00\xa0\xd5\xe4%]\xbf\x89\xd0\xd4\xb3\xe6\xe8\xaa\x81'\xb1\xdeV\x813\xe9~\x95\xea\x10\xd3\x95\x9a]\x8e\x13\xc0\x96#\xe6\xb1\xc7\x05I)|\xd1j\xe9\x99\xda(\xca\xd4of\x9b\xb7\xb9\xf5e\x86\xab\x92X\xeb\xc8\x0b\xff\x94\xc2$\n\xd7$N\x81\xa3y\x1a\xc1*\xf6\x97>\x06+\xc4)l*\xd25m\xf7\x81\xe1\xfc\xe9\xef\xe8%\xe8~O\xe5_\xaa\"t\xff\x01\x17\xa1\xfb\xff\xaaE\xe8\x87\x86\x83]}\xcf\x01\xbb\xab\x03,\x05x\xcf\xb1\xad\x97\xc7\xe7oO\xde\xbc{\xa3\x1ez\x9e\xaa\x9e*\x17\xab\xda\xab\n\x15U\xba/F\x8c>?\xf9\xe1>/b9FxXV&\x1e\xa7\xdd\x17\x8f!F\x8b\xb3) HJ\xe4\xac7\xe3h\x1c\x9fir\xa6\n.W\x8d\xed\xaa\xa7\xa3%c\xe5rP\xc7v\xa6b\xbc\xbb\xdc\xca\x1d\xefF<\x05\xdd\xd1\x80\x1b\xd8\x0d\xad\xe7B\xb9\x98{\xe3\x8c3\xb4'\xc6\xec\x93hzVX\xc0\x8c$}\xac\xcf\xb2\x19\xdf\x16\xf1\xf7\x0c\x14\xc5\x80\xf75\x1c\x1b=\x92\xff5(\x8f\xf6\xf4\xa4b_wEG\x99\xc2\xbeco\xb5\xa3\x16\xb78\xd99\x80<.5T\xe9\x00\x82\xa8\xfaz\xc2\xcc7\xab\x10Gsv\xcfaJ\xa2\x8c\x19Z{\x08\x8b{\xf7`\"\xfc\xb44\x1f>\x96\xa3@\xe1j\xe0w\x94,\xe0Z\xb0d!\xff.\xb2'\xd8\xda\xa7OEk\xfa\x05\x9a\xdcv\x81vM<\x12\xb7\xe3\xb3~\xb1\x1c\xba\xe1\x90\x01|\x99\x1c\xe7\xf7\x8ev\xaf\xc0\xe0\x12\xc2\x9a\x18\\\xce\nS.#f\x96\xec)&\x10Km\xcb\xa2\xfb6\xb7\xfa\xbf\xedT*H\xc5pmWg\x9c@ \xb6I\xb5\xdb8\x95\x92^\xe2\xdf\xf4\x94\xff\x15\xe9)\x0d\xe4j\xb0\xa3\xfa\x1dD-8\x18\xc9j7?\xb1j\xcf\xd19I\xdf\x8a\x8aof\xf5A\x92s\x90pZF\xf7\x94\x0b\x11n\xabqt\x06C\x93i\xdf$\n\x934\xce&i\xc4r\xe3\x83\xe4\xb7_.=(\xff-\x1d\xbb\xc3\xf2g\x9c\x08\x1c@\x06\x8aG\xf3\x86\xe0\xef\xdfzK\xcaV\xc7\x9b\xf5\x9e\x1f\x9d\xc2w\x07\xfdH\xf3\x03\xdc\x15\xda\x97\x9e\xe3\xf2\x93h\x8f\x1f\xad(\x0e\x08\xcf\x94\xdd]\xc7\xc5\xfdLe\x03\x177\xed\xa4,\"\x04\xecUI\xb9\xc0\xf2\x82'\xe2~wQq\xcc8:==\xc9XN\xbe\xaa\x19\xc7\xd1\xe9\xe9)eH\x9f\x93I\xe0\xc5\x1e\x9da\xd5E\xe3\xe8\xf4\xf4\x03\x15\xafx\x13ji\xe0\x930=!\x93T_\xfe\xfc\xcd\xab\xdaB6\x17c\xf1\xbb\xe8\x92\x84\xfa\xc1?\xf7R\x8fy\x11\x92\xf8eJ\x96\xfa6^\xf8\x81a\xe4\x7f~\xf7\xea\x9b\xc3 8\x8a\x82\x80L\xf4S\xa7U\x9a\xca_D\xf1\x92k\xbb\xf5\x15N \xfd\xdeX\xe5\x15\x99\xfa\x9e~\x86\xaf\xfc%\xa1b0.n\xf5\xcb\xd7\xde\x92L_GS\xf2\xca[iJ\xa3\xa9a\xd5\xdfz>]\xb1\x9f3\x92\x18\xd6\xe5m\x90\xcd}\xcd|\xd9{\xc3pN?|\xf5\x0d\x1eC\xfa6O?|\xf5:[^\x90\xd8X\xfc\xd6K\x17\xa7\xc4\x80\x0b\xb4<\xf2C\xc3\x80O?|U\x87H\xa7\x1f\xbe\xca\xfdM\x0d5\xa2,\x9e\x10\x16z\xdeP\x83n\x94\xd3\x05!\xa9\x1e\xaa\xef\xc8\xc7\xf4]\xecM.\x8fL[%\xafa(\x8e\xb2I\x0e\xbb\xbc\xe4\x86\xa5\x0b\xf7m\x0cY\xc98\xf05<\x81\xa9\x904a\xdd\xe9\xe8\xf8\xd4k\x17\xe60\x82\xe9x\xad\x18\x9d\xd2g #X\x8c\xe7\x9a\x92sd\xe7u%\x170\x82sJ\xf1\xcfu\xa7\x11\xf0c\x18\xdd\x89\xed\x0bz\xf6~\xfa\x04\x9e}\xe1\xc2\xcc\x85\x95\xe3\xc2\xc58(\xde\x05,\x07s2\x9e\x9f\xb1\xe8\xbaK\x8d/\x03R\xd6kz\xa2\xc7\x0e\\\x8c\xaf\x99\x1a\x99~~\xedB<\xbe>+\xf4\x99\xd0\x96Z7*}\xb4>9\xf4\xbd\xe1~_\xd5\x05e\x82\x954In\xfd\x9d\x07\xfff\xf9\xf4_\x8e\xe5\x93\x99\xd7pl+\x0b\x93I\xb4\xa2\xd2L\xa22o\x1a\xa7m \xdf\x84f\x01\xfcq|\xc6\xae\x00\xfa\x0f\x1c\xdbG\xef\x8f\xbf\x9b\xf5{\x15I~\x1c\x9f\x8d\xd33\xc5\x89^;\x11\x93~\xbf\x16\xf5\xf8\xa2\xea\xc4\x93\xbb5\xc4j\xbfMe\xb7^\xbe\xa1T\xa6;\x11lV\xe9-c\xae\xf6U\xab\xa8\x19\xbe\xae\xdc\xed\x04\x8ckS\xde\xae\xd8[U\xc3\xb0`M\xab\xaf\xa7\x9ct\xa8\xd6\x91k\xf6~W\x1d\xca5\x17,\xd5^\xe7\xfc\xfd\xae\xd3M\x88\xb2e\x97\xbc\xad=\xc7V\xbe:\xe7,\xb1*\xd5^\xf0\xd6T\xf8\\\xf1\xf7*\x01\xfc\x88\x1cf\xae\x8fW\x8eE\x91\x0c{B\x12\xc5\x91\xf0\x18\x8b\xf8\xfd[\xb9\xe8\x10F`\xf1\x8fp\x87\xcf\xecS\xa5\xd77\xf5\xea\xdb\x9f0\x92\xde\x08\xce\xbb\xb3r\x01\xa5\x84[[\xf5\xaa]\xb3\x7f\x9d\xa0\x8e\xc7\xdd\x98$Q\xb0&\xb6\xba\xa6\xf2CX ZY\xe6\x19\xd1\xdd\xcb\xaf\x01\x93\x15\x99 a9\xab\xdd\xc3\xea\x93\xdao\\xc\x96v5\xd9\xfaA\xb2\x0394zl\xf1\xa58!?1\x86\x163_\x8a\xac8\x0b\x12\xdao\x1cY*\xab\x8a\xe55\x1e\xb27*\xf6\xbdl\x9c\xf3\xba\x9aX\x05\xa4s\xc4\xde\xc2\x98\xaf\xe5\xc9\xe4w\xf1,p)\x0e\xdb\xc1)\xa8\x89\xb4J\x7f\xbej\xa2s \xae\xb4\xd2\xee\xb9Q B\xcb\x14\xc7\x01\xf9Y\xe7\xe1\xbc\xcf'\xfa\x1a\xcb\xe6\xa4U\xa0J\x94i\xf7|\xcd\xe4\xc9>.e\xf7\x1c\x00\xe9F\x97\x18\x94e\xe6\xf9\x9ahc\xea\x93\xe0\xc5\x03\xdf\x1b\xcd\xd5'\xbc:E\xb8\xe6\xda3\xac=\x8d\x96\x9e\xdf\x94 \xc4\xb8\x81\xe5\xc7c\xc1.>}b19)\xec0\xdc\xd8[\xc6E\xd1\xbfF\x18\xa4t\x8b)\xf9=d=Fh\xedoc\x0e\xadY\x97\x84)\x89m~\x81\xe0\xd91\x8a\xe6\x94\xc5\x9du\xc9G?\xb5\xb9P\xbf\xd5sX\x1d\x8c\xb4\xb3\xe2\xe6\xff\x070\xb1?\xda\x16\xdfw\xdb\x93\x85\xe7\x870\xb9\x9e\x04\xc4b\xa1\xea\xe9:\xbe\xb4)\x06\x1f\x087\xd0\xd0\x85\xc4\x85 -N\xb0d\x08\x13;6S\x03P\xf7e#Xp\xfc[\x19\x9f\x1f\x9f\xc4\xc4\x94f[<75\xf4\x08\xc2B\x19\x1d=v \xb3\xc3q\xd4\xe9\xe8\"\xc8\x8a\x87n\x12\x1e\xe1&p\xd4p\xad\x9a\xde\xde6\xf6\xb6)\xfe\xea\xb1QF\xac\x1c\xe8\x7ff\xaba \x9c\"\x1c\xa7\xf2\n|\xb9\xd8)\\\x83Rm\xd0I\xa0\x12\xddS\xad\xb7~\xedJ\x9d4\xc2n-\x05S\xab\xc2\x85t\xcf1S\xb4\x8d?X\x184\x84\x01\xe9\x9e_\xd1\x02\xe2t\xcf\xd7,F\x1d\xe9\x9e',{\x04\xe1+l\x13\x86y\xa4{>\xe1\xc6\x94\xf4\xa0xe\x13\xd4]\xd4\x8e\xfcu\xbb\x91\xbb\x86\xc8g X\x9a\xb0{\xae\x0d\x05\x0f\x18\xec5\x9f\x14\xde\x90\xf39\x19\x8e\xdf\xfac\x17\x03M\xb2\x00\xf6bc\x15\x87\x1fL\xd0\x88\xe7\x82\xeefd\x1e\xa6\xe0\xa7 f\xaa\xa9\xa4\xfc \x9c_\xa2%\xd5A[\xe6 $!\xbd\xf9,<\xbf\xd2zGV\xaaM\x87\xba\x84\x82\xf2c\xe0\xca\xc5\xd3\x8ec\x11\xe6\xa1\xf4<~\x8d\x07L\x1f\xcf\xe6\x13\xfe\xfb.\xd9\x80\x93\"\xf3\xed\xadO~g\x88y\xc39\xfa\x87\x0c\xfd\xfb\x14\xbfC\x17\xb6L\xe3m7N>\xbe\xfa\x89\xb4X\xbf\x86\xb5\xbb1\xce\xbf:o\x85\xc9(V\xfc\x12\xf7\xfaq\xed\x86\x9d\xf2\xa8I\xc7.\x88Ma\xb9`\x9d/,\xc7\xc5t\x14\xae\x1c\xd5\xbaU\x14\xa3\xd4F4a\xed\xe6\x98\"\xfeT\x88K-\xd0O\xca\xf1\xb4\xcb_\xe6\x7f\xdd\xb8\xec\x107O\x92\xa9\xf9r\xce\x0e\xff\x92O^\xf6&\x91U\x97\xe5l\xe5\xebJ\xe5\x85\\\x991\x8a\xc5\x80\x9c\xb2-\x8f=\xd8\xddw\xecc\xd9\x86V\x1d\x1f [\xc4\xfc\x16\xa2\xdcO\xb6\x88uu\xac\x0b\x97-\xac\x8f\xa8\x0c5\xd2\x8a\xa9\xec\xca\x19\xf7\x06\x15\xb0\xca\xb5F\xe5\xd4\x83\x94\x92s\xe9\x07\xd9\x18z\x16\xf3?\x87\nL&R\x08_\x0e\xe3<\xf0\xa8\xa7\x96a*\xdfW|\x1e\x98\xb8>\x14\x12Jy\x9d\xcb\xfb\x08\xd1\xa5\xce.\x03\xca\xd6\x89L\x85\x90\x8f\xd3\x88C\x8e\x12.\xcd\xa4\xa0\xc6x\x1a\x8f\xab\xd8%\xb8\xc2\"];?Q\xf0z\xf45\xc6[\xc8\xb3\xf33&\x05KNx\x89\x8c\xcd\xe7]*s\xfe\xd4\xe6\x828\xc5\x93\xed\x18\x97\x13\x7ff\x94\x83\xe6\xc1\xe9Q\x8d-\x1b\x9e8.\x04v\xd0\xfd\n:\x10t\xbf\xc5\xff\xbf\x80\x7f\x86\xadK\x15!\xdf\n\xa6\xe8\xb8\xf41\xb3&\xb5eZ\xc1\xad\xdd\x1f8\xb6\xfcJD\xa3\xcb\x0d\xddY\xc7\xa7\xa5.%z\xa3\xce\x8d\x82\xa7i\x91\x05\x83\xf4\x93\x8e2\x81\xa4z\xea\xb9\xb9\xb4\xef\xb0\xe8\x9bzD\xab\xc0\xa9\x18\xae\x8dl\xd3\xd6\xa5S;j\\\xef\xa6a\xf3Q]\xd9\xf9\xe6\xc8\xd7\xed\x98'\x93i\xc0S\x05\x92\xf6%\xd3\xd4\x0fv\x1fJV\xf0\x95\xbe\x8f\xbb\xcc\xc0\xb9\x8b;\xc8~#\xa3E\xdd\xb4\xbc h\x9a\x92\xcc\xaa\xeaO=F\xb5L\xf6BxsQ\xaf\xbe\xf1y\x15\xb3\xca&j/\xa9\n::\xd6\xdc'\xcaO\xa4\xb7\x9b\x93\x1f\x8a\xe8\x86\x14\n\xf4YSZN\x8f\x91\xf6zV\xb4\xb0\x82\x11D\x9dN3\x07\x98\xd4\xa4p\x10O\xc8(/#\x81tov:n\xa1-\xa3\x18\x81$\xb2\xfd\x08\x01;\xa6\xacE\"\x98\xf4\xb1w\xc6(\xdf\xf6vFKb;l\xe2\n\x8dB3p4\x97\x9a\xd2\xd6\xbb1o\xf9\xa8\x8bG\x97oG\xddu\xdb\x83%\xf6&\x8d{\xf7\xae\x10\xdd\x8c\xc5\xfe\x06X\xbc9nUW\xbd\xd8vP\xa3\xcd\xd3\x88\xb7P\xbf\x02>[\x81\xd8\xf6\xebV@\"A\xf8\xf3V\x97\x83L\xe9\xa5N\x9dgp)\xdd\x1c\xa0\xda^\n \xc84<S l\xc4\xe5\xb6\xa6m\xef\x97m\xe2\x81\x8d\x9fIN\xb38Z\xdaQ\x83\xad\x0c;7\x07F\x90\xe8ma[[\xd6\x17\x01T\xb6\x8a\xb4\xe3\xaa\x86Y\xe8\xcf\xd5\xf7z~A\x02\x9c\x9e\xd8\xa0g\xbf\x06\xa6\x90\x1f\xb9MP\x85:\x9f\x00\xf10\x0f\x80\xb0\xba\x00\xe2\xd1\x9cj.\x0el\x83\xee3]\x1b\xa9\x1d\xd5\xdczk\xe9\xfa\x9d\xa4\xa9\x90\xc8\xa5\x9e\xcbV=\x00\"-u\xe2\xf4\xa6\xa2.\xe4~\x0e\xbb\xfb\xd2\xba\xc5v\xdc}\x0b\x1d\x88\xbb'5wJ3?\xf4\x82\xe0\xba\xad\xba=\xe3\xb7\xc4~\x1e\xc1\x9aJ\xc2\xe2\x0f\x83\xae=4\xddjk\x98\xdd\xca}q(\xab&\x8d\x96\xd7\xfc3\x8fRGT\x84\x95/R\xea\xf8\xab\xca2\xcb\x8f\xce\x9a\x8c\x8al\x94\xad\xf8\xc2\xe3\xe2 u6\x1a\x96\xf9\xae\xf2\x0b\xa2n\xc5\x7fD\x84?\xd8S\xb0\xf1\xb4\x06\x0f\xd3\xb85\x0e\xd2C0\xd5g\xe0\x86<\xd1\x97\xce\x9eV\xdcB\x87]\x82\x86\xed\xfc\xee\x7fX\\\xc68v\x88\x97$\xcd\xd7\xd2m\xe0\x19\xda\x83\xbd\x01\x8f=\xb7\xc3\xff\xdd-\xc7\xaa\xdb{\xc0\xff\xe5\xb1\xea\xf6x\xac\xba\xfd\x1e\xff\x97\x7f\xbf\xcf\xbf\xdf\xe7\xb1\xed\xf6\xf9\xf7\xfb\xfb\xfc_\xde\xce>og\x9f\xb7\xf3\x80\xb7\xf3\xa0\xcf\xff\xe5\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=x\xa4\x8d\x9d\xc7|j\xdb\xc0\xa2\x11\x8b*\xbeNQ\x1ep\x13\x8f\xe3#\x1e\xae\xb2J\x10\xe5J\xd1\x94\xa0\x17\xb0\x82xH\x06\xd1z`\x8b\xd9\xb5\xf71\x9eJ\x1e\x16#\x8f\x1dR!\x8fr\xa3M\x08\x9a3\xb4\xdc\xe4r|\xe6\xe2\x9c\xf3\xccPy\xa4\x9c\x8c\xf9\xe9\xc6\xf0\x142\xb3v\x80g\xb9\xeb\x14\x99\xa52\x8c\xa2\xe3Sj\xd2\xef\xf7w\xfb\xfd\xbe\xc3r\xf7\x8a;\x91\x13/\x9c\xf3K\x11R\x8e-\xbe\xf6\x02\x7f\n\x93hJ`E'c2\xab\xe4w\xd4\x04\x9e\xb0H\x9dp\x80\xb1~0B,\x8b\xe4\xd9\x01\xdb&\xb0=b\xe5\x0e<}\n\xfd\x1e\xca\x14\x7f\x84~o\xb0\x0b\x1d\x16\xffS\x97|\xcc\xb4'C\x9eSP\xcd\x9c\xbb\xe1\x8ek\xc22CT -\xa52`D\xec]\xb5\xc7\x03\x16;\xa3\x1b{W\\\x10\x8d\num\x1dnP\xcc\xf1\x18\x8e\x84\xf0\x14\xbc\xc7\x0edl]x\x08Z2\xf6:\x9d3\x07\xe3D\xdc\x87\x9eF\x8a\xb0\x8e\xa2,L\x0b\xe7\xac\x90\xcc\xbd\xd4_\x13U|\xe0\xc1\xf8\"x\xaa\x1ar\xf1\xc7\x8e\xe0\xe9\xd3\xa7#\xe8;\xdc\x9b\xb53B\xc3#zb2\x07\xd7\x90\xbdz\xac\xac\xd3\xef\xa7\x84\xdb\x948\x17 \xda\x9a6aQ\xb3n\x1b\x16\xb5\x9a6\xa2\x8eD\x97\xfa\xd0\xad\x00\xe2\x88o\xe7\x84r\x93\x1d\xea\xe6\xe1DM\x99/\xe2[\x10\xd6\x18\x97\xad \xac!\x15\x92(\xec\x84E\x0b%\xac\xf1g\x11\x07\x93dBW\xc5\x0b'\x8b(\xdeH2\xa9\xe5\x06\xf9b`\xd4z+\xf4\x96\xc4\xaaK\xec\xf9\xd9\xc3\xbf\xf0\xe7\x1b\x8d\xbd\xcd\xd0Y\x9b\x16\xfe\xf7\x05G\x1e\xf8\xe1\xe5\xdd\x8f\x9d\xb7\xfa\xc5G\x1f\x05\xd3\xbb\x1f\xfc\xef0\xf0\x99\xff\x91\xdc\xfd\xc8\xd3\xf4\xf7\x18z\x14\xa6\x93(\xf8\x12\xbb\x956MG/\x9a\xff\x82;\x96v\x95\xf8\xbf\x90/7 \xde\xfa\x17\x9c\x83\x9fz\x81?I6\x9aB\x9b\x19\xf8\xbf\x03\x16mLvZ\xc1\x1e\xc9\xfd\"&\xb3/\x0b\xf8d\xe9\x05\xc1F\xa3o3x\xd1\xea\x97\x06=}}\xb9\x19\xe2\xb7\x1a\xbeh\xf6\x8b\x8f?\xbb\xb8\xfb\xc1g\xbf\x07\xd5O\xb2\xd5\x17\x18\xf9\xea\x8eF\x1e\xda\xfb;\x8em-\xbdt\xb2\xb0\\\xe8\xd7\xd7\x96\xc62\xce\xebi\x15\x9dz\x88\x88GH\x02i\xddE\xa2/+\x1aP\xcf\x90\xe7_\x0b\xc7\xc4\x9c\xdaB2\x9b\xf7\xe1@\xd8\xd81\xcf\xa8!\x9a\xb7q}n\xe8\x8c\xc9\x99P\xd8\xc7\x95X\x1f\x10n\x9a\xd5\x9f\x03\x93\xeb\x14-\x17\x06\xb7\x00g\xecV\xdd.\xa0\x15D\xa3&\x88f%\x88\xc62D\xe3\x96\x10\x95\x04\x88\x18C\x95\xf9\x08T\xf6\x86\x832rX\xe8\xa5;\x03hB\xbc\xf8\xdf\xd0\xf3\xce\xa0\xb9\n\xfcT\x8b\x9c\x15\xcbI3\x98\xc4EFh\xf7wUc=\x10z\x8f\xeakv\xb9\x867eU\x8d\x885A\xe3\x14\xcb\xbb\xb8\x98X\x92\x89mYt\x8e\x1a\xa4is\x1d\x02\x92%\x9a\xd0\x01\xe8\x03\x01@\xd9\xd7f$\\\x8bx\x12\x9d\xdc\xceMM\x86\"\x7f\xbb\xe5\xcb\xa9\xd3\x8a\xa8x8:\xfdgkf\xc2\x9f\xb80\xc1p\xd3\x01\x0b\x8b_\xe7u\xbe`\xa1;\xfdy\x18\xc5\xe4\xc8\xc3`}\x96o\xc1\x90\x1ey\xd0\xa1e\xcb,H\xfd\xc0\x0f\xb1hY*\xcaB\x1f\xaf\xda\x0f\xc0\xcaJ\x05I\xeaO.\xaf\xe9\xfbk\xfe\xde<\x84i\xbd\xd3\xfb\xba\xbc\x9a\xb4\xb3\xdd\xc1\xa3\xddG\xfb\x0f\x06\x8f\xf6\xd0\x8e\xff\xe9\xd3\xa7u\x0d`4\xd9b\xbf\xa7\xdd\x04\x83\x9c\xbb\xb0\x80\x0eXs\x93\x85\x00\xaa\xfaX\xf0\xaa\xb8\xdc\x02\xbb\xcb\xbc\xe6\xed\xd0F\xfe`\x1fl\xfd\xf0C\xe2X.,t\xd7\xd0\xf9\x83\x0e\xec\xd7\x0c\x17y\xc0\xce-\xdb\x9e`(1\xd4*C\x07\x92q\xef,\xc7\xf0\xa70E\xad\xe1\x8aG3\xe1*\xa4\xa9+>p\x1c\x17\xb6\xd0h\xbf\xa4\xe0\xc2\xc4\x1f\xbd\xb3\xfc\xe2-v\xebY\x9f\xd2\x83S\x0f0\xd0\x00\x04\xf0\xa4\xaa\xe4\xde\x86\xc1c\x08:\x1dG^\x99B\xa3\x16\xa0\x15\xaf\x8d?FZ\xe5w\xe9\xb9q\xdc\xea\xe098\x9e\x141\x15\xf1\xf2\x9f9\x00\xad\xe8\x07\x0c\x12}\x87g\x89\x90\xc0\xc6b\xc5O\\X\xe5\xad\x8e`\xed8\x8f\x1d\xb8\xee\x06^\x92\xbe\xc4\xb6\xf1>\x83\xf7s\xef\x9e\\\xa4\xc6\xf4\x16\x0f\xdf\x8cSv%S\x84\xf5\xde\x9a\xb1\x06(\xc9\xc4,<\x9f>\x01_1\x96\x93G]>:\xe8bp\xb0\x86\x03X\xf1\xb2\x9e\x0bk\xfc\xa42\x02\xc5,\x99\xb9*X=A\x1a\x85\n\xb3\xe7H\x10\xb3[Q\xb6\xf2\x99\xa9\x92+8\x80\xf1\x19\x0c\x05\x0d\xcau\xb1\xaa\x14\xa8\xd7iK,\x82\x81\xe5\xba\x05Su+>@b\xaa\xc2\x82\xa9\x8a+LU\xa8c\xaa\xe2M\xd9\x80z\xe5|f\x87\xf6\xe0a_U3\xfb\xbchg0P\x8b\"^\xb4\xd7\x7fHIL^&\xc6\x80A\xf1\xf5\\\x1a.f\xda=?'\xc9\xabh\x9a\x05\x18G\x1e\x86\x9a\xa5\x98\x92\x99\x97\x05\xe9P\xbd\x9f\xff\xa7\xea/q\xd2\x8e\xfd.\xff\xca\x85\xa8\xf8i\xa46|L\xd5\xbe'\xd1r\x15\x85\x94\x80\xe8F\x06\x98{B\xf8.}\xe3]GYJ\x17\x8fw\xd8\xb4Y\x8a H\xa8\"_Ny\xb7_S}\x8eW\xe2\x82U@\xbcr\x0b\xc2\x03\xc7\xcb\xe1\xea\x9d*\x9aLl\xca\xf9=\xd4\xa1 \x16\xed\xf5th\xc2\x8a*\xc8\x95\xe5E;j\x91\x97\x17\xed\xabEI^\xf4@>\xda\xf0\xd5\xfe\x9e\x1e\x15'\xbf?*\xcej/\x18\xf3\x91\x91:\xc1\x9f\xd2\xde\x1c\x9b\x1dN\xe8\x88\xe3bA\xa6\x16\xd8\xa4{~\x8e\xce\xe7\xe7\xe7\xc8&\xf4\xdc\x02\x1f\x1d\x9b8\x0e?\xadX\xf5\xfcxTE\x0c\x1d\x98h[\x9e\xd4\x96\x0b)\x1fFTz;\xae\xce\xe5\x92\\\x0f\xc1\x8aI8%\xb1\xe6\xa6\x94\xe3]#3\xb0\x96\xf3c\xac\xe2he\x88?\x03\"UFwN\xd2#\xb1\x85\xcduYd\xf0dE&,!P\x14\xd74\x1c\xb3\xd0\x1fq\xdc\xa2.\xdd\x13\xc4\xb6\x8e\xa20\xf5\xfc\x90T\x1cn\xe4'buO\xa2\xab\xbaZ\x99h1\xa8\xab\xe5\xb1Z\x18\xb57\xb10\x9c\xa9\xb9\xf2\x84U~\x17\xad.\xbc\xb8\xa9\xf2\x8cU~\xe6%\x9c\xde5}\x10\xb0\x0f\xa2\x90r\xeb\x1f\xbc\xc0\x9fzi\x14?\xf3\xa6s\xd2\xf4)&t\xe8\x06\x917\xf5\xc3\xf9i\xea\xa5Y\xa2F\xb2\x97\x9f\x05z/S~\x89\xdd\x9f7\xb0\xf7\x94GZP\x04\xb1\xad%I\x12oN\x90+\xb24J\x01(6A\"P\x9d;T\xf2\xdcQ\xb6o\xf2\x94\xa4\xcf$\xf0\x92\xe4\xb5\xb7$C\xb0\x92+o>'\xf1v\xe6[\xda\xfa7.L\xe0\xc0\xd8\xcf\xc4\xc5$l\x0eO\xc6\xe6\x82\xc5\xe1c!_\xb4b|\xaa\xfe[\xcc\xed\xddv\x9c~8\x8b\x8c#\xbc\x93\x1e\xf8\xc0\xb7'\xf9\xee\xf8=\xba3t\xe2`\xf8\xb7\x99\xe7\x07d\xfa\xaf\x12\x94\x8b\xdd\xd6\xbd\xa5~\x1a\x10c\x0f\xd6\x0b\x04\"\xa4\x11\xd0a\xc1\xe1\xdb\x97\x80l\x88Oi{\xd7r\xcc\x83\xf08rKkq\x84\xae\x95_dE\xcc\xe4\x013A\x9b\x18>\xf1,\xbd\x8f\xdf\xfa\xd3t1\x04\xeb\xe1\xc3\xde\xeacM{\xacz<\xf7\xc3o\xc8,\x1d\x82\xe5ei]\xffE\xfd\x13\x7f\xbeh\xf9AJ>\xa6\x87\x81?\x0f\x87`M\xd0\xdf_\xbfDP9\xdf\xf3\xb7\xff\n\xb01&\xcb(%\x85\xc7n#NZ+\xcb\xe5\xa4v\x8a\x88\xb9\xb5B\xe5_\x92MD,\x8c\x06\xcc\x9cq\xac6\xf7\x11\x89\x1eL\x15\xb2\xa6\nA\xbes\xaa:\x0dE\xea8+\x85H\xba\xb1\x8b&sNIb\xa9\x89(m\x1bl\x8a\x8a\x90;\x15\x8f\xa5\x81\xd3\xd5\xe6Am\xd3\xa2d\xdc\xa7\xcf\xff\xd6\xdf\x91\xad\x96\xa9p\xf2\xc8\xb1\xadrGV\xb3\xf4g\xe6\xd4\xa5J\xbe\x92\x86\x14\xe06\x17o\x83\x87{\x1a\xc1J\x02\x93^\x1ely\x01\x12\xabb\x9f\xa8^\x8c\xb3\xcd0\x8ba\xf5U\xeb\xce\xc2\xabk\x8b\na\x94\\\xb3qWvmy$C\\\x1d\xa7;\xdb\x10b2\x10*\xed3\x89\x8c\x02U\xbd\x8d($\xbaas\x0e\xb6\xca\"=b\x0ey\x0f\xf7\xaa\xfew\xbd}\xa7;\x93\xfd\xe8\xdb\xb4\xd8r\x12\xaa\x01\xeb\xe7Mb\xf0\x88\xbb!>\xe2n\x86|V\x83G\x0ft\x9b\xf4\xf4zy\x11\x05m\x9an\xb2\xf34\xd8\xe1\xaa;\x98\xdby\x1a\xbc\xad\x0d\xce\xd6\x03\xb5q>\xfeG}\xa7\xfb\xf5\xf1\xf7\xe5\xb2 /S>\xe1\xa9\xe5\xd4\x1eXj\xb9G\xeaxXn\xb9=\xf55\xcf-\xa7\xbc\x9d\xe6HR~\xbf\xe6\xefU4\xbd\xe6#T=\xe4\xe6\xfc\xbd:F\x9eV\xae\x82\xed\xec\xb5\x1a\xfe\x92\xa5\x94\x1b\xe83\xcaU\xb0\xed#\x9b\xa8\x1a\xfb\xee\x94\x81E\x95\xd6\x8e\xf9\x08\xd5\xea\x87|U\xd5N\xdf\xb0\xf7j\xf5\x9f\xf0u\xc5\x0d\xf5\x12Fp\xa8\xe6\x90{ #x\xa3\xbe|\x85i\xe1\x94\x97\xefP\x1ed\x18].9\xc2\x92\xbf\x9c\xbey]~\xff\x16FpD\x8f\xf2\xa3n\x82\xaaW\x7fv]\xaeqB\x05G\xdb:_\xf8\xd3) U\x11\xfc5+M\xa3\xb7\xb1\xbf\xf4\x99\xadv\xb9\xc67\xe8\x00\xa6\xcd\xb9_\xae\xf8\x9c\x92{\xdbJp\xf4\xdb1\x99\xfbI\x1a_\xab\xcd\xfd\"\xd7\xaa\xa4\xb9|\xc1J\xa3\xd5\xb6\xa1\xc2{M\x12\xf3r\x8dg\xa6\xf8\x01\xef\xca\xf5~F\x88\xfe\x955V.\xfa\x1eF\xb0\xf53F\x0e\xffY\xca\x08\xa0\xfc\xdd\x9d\xf9\xe1\xf4h\xe1\x07\xd3\xf2\xd7\xdf\x02\x8f\xf18\xa9w\x8d\xe3G\xdf\x03\xd8\x1a\xc1\xa9\xfd\xd2\xfe\xfb\x0d7\x0f\xd33\x91\xed\xe2\xb1@\xd1\xf0K\xd9\xe4\xac^0\xe0\xda\xac\x07\xc6J7N\xd7\xd3\x16V\xd9\xf2\x1bG\xad{\xe3\xc8\xd1\x0f\x0c\x8c\x00H\xa4\xf8\xd2~\xaf\xbf\x9dE\xd7\xd5) HJ\xe0\xfd\x98\x9c\xb9t\x92\xbc=\x1e8,\xc5;\x8a\xf7\xf4\xe7Kl\xa6\x12 \xf9\x06\x86\xf0\xb2\xbcd\x1fj\xb5\x9e \xd9\xd0\xff\xc2|\x0dO\xedw\x05\"\x98\x0d\xd8 K\xa5\x9bV\"|\x96\xbb\xff\x1aF\xf0\x8c\x8e\x98o\x8b\x12\xd6v\xc5\x91]\x02b\x0dBi\x1aI+\x00h\xd5R)\n\xf3\xbb\xba\x19|\xd5\x82\xd5+5<\x12\x8b\xf4\x95\xfd\"_\xc0%\x8b\xf2\x0f#\xb8\xe2\x19\x8d\xe8;Z\xe2\xdb\xbf\xe0\x9d\xdb\x01\xc6c\xc8 \x10f\xe4\xa3\xfd\x9d\xb0\xbc\x93\xe3\x93\xb31a\xb7\xa6\xe2\xf7\x88\xe7\xa8\xc0E\x0bM\x1b\xa1hr\x08\x1f\xed\x1e&\xb6\xd0a6\x0c\x8b\x0e?}b\xd8w\xe2\xc2G\xbb\x8fyv)\x7fR\xf4K\x87\xffm\x0e\x0d\xfa\xed\xcb*_\x0bU`\xfe\xa1\xcd]\xe3R\xeb8\x91;\x93\x87\xcca\xfc\x9a'\x82#th>K}\xc2\xa21\x8a|\xdf\x11<\x05\xff\xb1\x03_\xd9)\x83R<\xf61n\x00\x19\x87\xba\x10\x96b\x05\xeb&\xf0\xe7\xd6\xdb\xe9\x9b\xd2](.|\xcaRY\x19{\xde\xc2\xda\x05\x02!j\xb0\xbc\xa3[>E\xa6\x94\x19\x04\xd8[6#\xd9\x85\x0b'\xff\xf3\x17\xf1[\x94p\xecY\xf8 ]\xbc\xf4\x0c\x0b\xd5k\xd9\xf2\x14\xff\xd2f\x8d\xfc\x19s\xdc\xbd\xd0\xe0\xb5\xa0S\xf9\x90\x08\x1f\xd2\x0b\x16bY\x8f\xa7\xc2n\xe6\xd2\xae\xb1_\x11\x80\n\xab\x8dW\xb6\xca\xa7O\xca\x8e\xe2x[\x8d$sS\x07\x8e\xbf5\xae\xb8\x1a\xee\xe2\x95}\xc1\x9c\xa0c\x1e\xc1 \xe2\x11\x0c\xba\xa5\xdc\x8fl\xf4\x94\xd9b) qe(e;\xc9\x7f%,T#\x0bDa\xc6\x9b\xb8n\xfc\xdfm<~N\xc2\xd8\xf8_a\xe0\xa1\x170\x04>\xa9\x88OJ\x84\xee(&\x95=v\xc4\x9a\xe0f\xcb\xc4\xacB\x8e\xc1\xef\xc5jElJ\xbf\x8cI\xcd>\x8c\xca\xb3*\xea=\xc3\xa5\xf5l\xfb]]\x14,\xc4P\xba\x9ddB_\x0d\x99n1\x96\xb4\x88\x0f\"\xe5(\xaeDN\x17W^+\x9d\xcfX\xaf\xe43\xd6\x93\xbc:\xdd\xca\x14\x89\x94\xd3\x01\xc9\x19\xa9\xac4\xca=\x04\x9b\xf4E)K\xc4\xffOr\xd3\x87\x98\xb4\xe8/.\x15Q`\x04_a\xc4\xa1\xbd]\x07\xff:\xc6\xff\xff\x8d\xbe\xdb\xe7\xaf\xfe\x8c\x15z\x0f\xd9_\xdf\xf1\xf4\x97[\xa1\xfd\xf0!\x02\xd5\xa3\xb3\xb7t\xe2\x82\xe5\xd2\x8f\x91\xbcL\xbb\xf5\x17\xcd|\xbc\x1f\xecEIuE\xc7\x9b\xd9\x19&B\xca0\x11R\xc6T:\xcfTh3\x84\x1dJ\\\x8bl\x17\x90o\xe6\xbfRaa\xe1%/9\xfa\xbb~r\x14\x85\x13/=]\xc5\xc4\x9b\xa2\x90#\xf8/\x17\xcd\xce]n\n\xe623_\x97\x87rt\xd1x\xc8\x95\xe4(W\xac\xcb;o\xee\xca\x99\xfd\xb9\x9d\x91\xe5Z\xf4\x18H\x19\x85\xf8k\xb1E\xd2\xf4\xb1\x03\x0b\xfb\xaf\xe34-'\xbd-HP\x8a\xd9J\x16\xdd$\x8dbB\xa95o\x85\xa4E3!mfm\x93t\x1c*\xedP\x08\x9e\x96`\xc7\xf7w5\xa0Q\x14\xb7d\x15}\xfb9=\xd3:#4^<\x80\xe7tO\x0d\xd9?\xa3j\xea]\x85\xfc^\x92\xeb\x17\xcd]\xa19\xe7\xd7h\xceY\x9b\xd3\xc1\x03\xc6\x01W(\x13\x94\xc3\xed\xf8!<\xd7\xdb\xd3\xd1\x9e\x9e#\x177\x92\xe3\xbb\xd72\xf1YBNI\x9a\x92\xb8AJ\xfb^\x17I\xb2\xd2\x92\xbf\\\x05M\xf6\x05\xdf\x97\xb3\xd7\x01\x94\xf5\xba\xaen\xa1\x0d:O\xa6\x9ao\x91\xca\xaej\xe2F\x99\xf0S\x1b\x93\x96\xfd\xc1>e\x9cN\xedb\xab\xfa\xd5\xafj\x8a}\x92\x0c\xe1\x0f\xe5\ns\x92\xbe\xb9\n\xc5\xf7\xcfI2\x89\xfdUJ\xd1\xe7/u\x15_{K\xda\xd8\xdf\xea\xea\xb0m\x90\x0c\xe1\xbb\x12\x1cQ\xc1R\x06\xa6\xbd\x85\x07l\x8d\x88/\x8e\xc1wjxL!\xa6\x8d\xc3,\x08\xce0\xfe\xcd[[p\x9d\xd6\xdfo\xf8\x9b*\xec\xbd\x8a\x11\x8f\xf2 [\\\x85b:.X\x7f9}\xf3Z\xe3@\xce\xf5EM\xfb\xae\xc4\xfap\x86-=\xe3Y\xe4\x1f\xebb7P\x81\x82sd\xc5a\xef\xebSx\xf3<\xaf\x9c\x1d\xea\x9f\xb9`\x9f\xdb\x95\x94?\x9c\xc1\xffZ6\xe6\x9e\xf3j6i\xc3\x8c\x8b\xbe\xb4\xba!\x16\x1a\x08\xf9\xcc\x8au\xa6\xe3\xd2~\x89c \x03\xc0\x91\x84\x8e\x9dN\xc3\x85\xb7\xdc`\xe9\xa8\xaaz(\xa1\x95\xa4B\x18\xbfFV<\xb4\x07\xfb\x8e\xacZp\xe1u\xa9\x1eK\xc2\xf2f\x86\xd9\xe4\xde\x15\x84\x1b\xff~\xe5\xa5\x0b\x17,\xfa\x0f\xb7S\x81\xc0\xe6J\xc3\x1c\x07\xb6z\xad4\xff\xd2\x0d\xd6\x9ec[K\x92z\xba\xd0\xbb\x1a\xe5m\xa4\xd7\x9a\x8b`\xa4\x8e\xaa\xf3\xf4\xaav\xebI\xa1\xe4\xf3\x93\xe3\x8f) \x13\x9f\xca&\x9f>\xd5\x13D!\xf8\xd4R\xd7 \xa5\x9a\xa8]o\xa5\x9eK\xec\\\xddH\xd6$L\xf9p\xa20\xb1\xa9\xc0\xaf\xec\xc7rW\xf5<\x0e\xe0Q\x9c\xa2\xf7\x91I\xdaC\xb5\x9c\xbe\x90>\xfe\x10\xac7\x16t\xa0\xd3\xf1\xaa\xbc\xa4x\xae\x86j\xb0Z\xf1\xe8\xb4wu\xb0\x0b\x94\x1cR\xd5\x91}}\xfc\xbd68\xf9\xeb\xe3\xe3\xe7C\xd8\xeaWKf^\x92~M\xae[\x9c=\xa0u\xe9\xd0\xa9\xbb\xb85$s$e\x86Fr\x99u\x8a\xde\x14o\xd1\xcd\xc2\x90C\x81e\x01\xc0\xe51J\xe3y\xbd\xa44\xa0\x17\x06{\xac\xbcz\xe1\xb9b\x1d\xd7\xd4\x9d\xa9\\\x93x\xf4\x8b)x\xfcq|\xd6\xad\xe6\xce\xd7\x84p\x9b\x93\xf4[\xe2]n\x02\xf9[\x01dK\x1f\xe3\xa5\xa8M\x8c\x11\xab\xe5\xe73\xc0q\xd5\x06\x1cQ\xf8\"&\xe4\x97\xc6d\x82P4>\xa1\xc7F\xd0\xa5\xc8\x8d\xe6\x146?\xa68\x98\xe8\xef\x19rD\xed\x0c\xab[\xd3\xe4\xca\xbd\x93\x08\x19\xa4'\xc6\xfb\xa6\xe4G\xe6\x89\n\x05]\xac\xcd\xd4\x16\xb2\xc0\xba\xe5\xb5\xc2\x83\xbc\xbaB9\xf7\x90\xb9\xfc2\x94\x02\x84\xf6\x1eug,\xa1J\xef1x\x05\xf30y\xec@\x92g.\xa7\xe7\x867\x9e\xa0\x96\x04\xe5{\xe4*2=O%\x19\x89l\x06\xd0\x87\xfb\x06\x08\xb1\x08\xef~\xc2RY\xc9\x07\x90If\xb5\xb0*\x92\x9c\xd8\xbe}\xa6\xab\xca\xed'_\xe2\xbd\xea \x1a\xb1\x1b:!oV\xcf]+b\\\xbfD\x06\xaf\xfcp\x1a]Q\x88\x16\xbf\ns\x17\x95m\x86\x83\x9aB\x9b\xb5@\x05\x80\xb1\xce+\xa0\x9d\xa8\x8f\x81v\xad1\x1b)|\x8bM\x9e\xe1\x88\xf3Di\x8d\x17 \xe6\xbc7\xb9\x94\xaa!!\xcd\xf9\xe3\xc5\x10\xb9kQ\xa3\xbd\x92\xcdS8\x97\xedn\xf4\x08\xe0\xc0\xdf\x1b-\"\xfa\xbd\x07\x8emy\xc9u8y\xb9\x91\xfd\x86\xf8\x94%GA\x1dL\xab\xef\xda\xd9}<\xba[\xbb\x8f\x9d^\xaf\xc6\x08+\xf9\x0c#\xac\xaa1\x90Y\x12.\xf73\xc4q\xf51\xa7U1\x9fV0\x94\xb6\xb2J\x95}\xbd5D\xd4F\x8c\xa1T\xd6G\x12\xba\x15S\xf9\xe7\xde=4\xa3+\x07v.\x14#\x84eCe\x11\xd9\x12\x92\x82\x97@.Ml\xa9\xe1\x18\xf44\xb0\x02\xa0!h\x17\x05e1+w\xe6\xb0\xc0\x0f\xe1\xef7\xd5\xbb_m\xca\x1b\xf3\xde\xb5\xf9\"R\xd1\xe8\x05o I\x82\xcb\x0d6\xba3\xbbb\x12\x00\xd28XF2\x188\x0e\x1d\xc0\xf8\x8c\xdf\xc5(Yf\x91l\xdf\x86:\x10}f\x8a*W\xc2\xc9\x88\x0c\x0d\xa3V[(\x95Y%\x96\x0f5\x95\x1ceF\x10\xc2\x90\xe5\xc0 \xdb\xf0\x17h]\xb0\xd5wL\xfa\xf6\xc9\x82L.\x87\xd2uB\xabM\xdb\x8aN\xecT\"\xe2}.\x9d\xd8\xfdlKD\xc3!\x14s\x1bUVg\xb3\x81\xdd\x8e\xdc\x08\xc5\x1bZ*\x15\x1d\xb6\xa20M\xf6l\xbb\x06\xdb\xd3==\x97\xb8S\xb1\xf2b2\xfbN_\xb5\xf2bl\xdc\x8e\xfa:\xe1\xd5u\xe9\x89\xe9{\xb5\xf9\x19\x7f\xaf\x0e'\xe0\xcd\xab8\xba\xc2Li%+\xe2r\x85\x85T\xe1\x857I\xa3X\xb1\x85\x9a\xb2\nA\x14\xea\x1bXW\xe3@\\7\xca\xf0mn\xc4\xe7Za\x19\x8d\x87b\x12\x9aD\xfc\xa5\xb7\x1aB\xd4]z+\xbdp?\x8b\xe2co\xb2\xa0u\xf8O}\xbdI\x94\x85):\x1e\xd3\x1f\xfa:i\x84\x04\x90\xd6\xe2?\xf5\xf5\xa20\xb8\x1e\x82&\xe7Y\xb5zn\x9c=\x04\xbf[\xe3\xd3\xf66\x8bI\xa9n\xe9E\xb5~ \x03\x86\xa0\x01\x8e\xbc\xc2C\x98V+\xf8 \xfau\xe5U\xbcn\xf9\x8df\x90q\xb4\xa2\xc7j2\x04\x8d\xf7\x1c\x1b\xd2Q\xe0%\xc9\x10f\xa6r\x8e\x93C\xd0\xac\x13\xab\xf1\xca\xff\xe8\x87C\xd0\xc0\xfe\xf9\x9bWC\xc8\xaa\xef\xd7$N\xfc(\x1c\xc2\xa4Zv~\x9e\xe05\xd6\x10\xd6e\xe4\xd4S\xc8V\xa99\xea\x89\x8e\xacQ3\xf4\x12\x7f~/\x94V\xe9y\xaa\nM\xe2\x02\xb0\x81\xb2\xf5T\x0e\x96\xa5\x13M\xaf\xa2C\xae\xb6~\x1bE\x81\x9a\x8e\x14g\xd1\x9dEY\\W\x8bR\xbd\xfb?\xdc\xef\xdc\x9f\xeb\\{gFA\xc8\xb6,\xe8@\xea\x94\x82\xbd\xff\xe1\xde}K>\x8f\xaa\x0d\x06\xdas\x0d/|i\x1df\x85\x86\x7fN\xa20e\xb9\xb9H\xfe&c7\x88\xb5=\xact\x0b\x05\xd2\xb2\xa4\xd8\x93f\xb3a\x19\xefV\x91\xdb\x99l\xe7c\xc3)\x1b\x88\x9c?]7\x8e\x85\x18\x87\x86\x93\xc4\xe9\xc4$a\xde\x1fb\xc6\x97\xe4\xfamLf\xfeGi\xce\x1c(a\x05(\xf1F@\x996\x03\x85\x0d\xa7\n\x96\x0cK\xf3\xb1U+x50Md\x98j\xa8 ;\xe8(l\x13\x05\xb6\xe5\x05(\xe97\xec \x95\xb1\xd7\x14\xe3b\x84o\xd4M\x17^z\x82\x88\x99\x08d\x17\x8e\x9c\xb05b\n0\xdbW\xa8'm\x87\xbe\x9f\xa0\x9a\x08\x89\xf1a8=a\xf8\xfc5\xb9\xa6\x1dd\xd0\x01{kB\xe7\xcf,yP\xb9C\xff\xc2\xe4\xf2\xf8\xeb\x00,\x0b\x860\xb3\xf1O\x87\x8a2\xf7Qg\x1b\xa2\xe1\x10S\x05M\x9cztYK\xe8\xe2V#g\xacy\xd4\x0c\xd5\x89V\xcc\x90\xdd\x0c\xa1hf\x87b\x08U\x83\x17\xbaV\xe8\x9a\x8b\xa4`j\x13\x8c\x8c\x81\x1d\x96+\xa3\xc6\x7f\xea\x82\xe7\xb8\xb0\xe8\xc6$ ^Bl\xaf~\x0e\xd7&,\xe34\x83\x0eVj@\xfc\n\xa4\x8b\xa3)\x11\x06;u\xf6@\xa5\xad\x81\xee[\xca\xee(\xbd\xacl\x10\xba(\xdetJa\xe0\x87\xf3w\x91\x1d\x88\x89\xdej \xf9F\x96z\x95\xf7\xb2\xf4\xfa\x0e\xc7\xbcp!Q\x04\x8c*\xfb\x96\xb3^u\xa7\x98xP3J\xf1\xa9dM\xa0\xb9x\x10D#(c\x92.\xc9:\xe2\xd1\nS\x17@\x90\xe3\x91z\xdfX\xa6\x0c\xc8O~\x91\x01\xeb\"p S\x01\x9b]q\xb1U\x10\xa6\xda\x0d\xc3|\x19\xa6\xd1\xb7~\xba\xf8Z\xac\xf6\xcb0%q\xe8\x05CX+\xc7,\xe3m\x1b\xf5&B\x87G+\\s\xd7\xc3\xbaA\xe4\xfcp=\xf3/\xf4\xe4M\x00 \x02\x00z\x92Z1\x10/\xf0\xf3\x8b\xf1j\xa1\xbd\xaf\xd31\xdb\xa1M%\xaf\x86y\x0b\xc3\xc1\xae\xd0\xa0Pl\xad (\x07\x12\xac\xaa\xdf\xad\xa2\x95)\xf3\xb5\xc0=\xdc\xbd<\x12|\x15^P\xa7p \xc9\x15~_1B\xaa\xd5\xbfi\x95T\xb2\xc2\x08\x0d\x0f?}\x82\xd8\xb6\x06{h\xcb%\xd16\xdbq5\xf3\xe4w\x1cOx8\x90(\nN\xfd_\x880>V`B\x0f\xb7z\xb3\xa9\x0c\x934\x97^yZAS\xa6o-\xf6\nH\x96\xc6\x86\xebQ\x01\xda\xd2\x98\xb9\xd1kXP/\xb4\xeb\xf8\xf4 2\xfa6\x9f/3:\xce\xff\x1c\xb1\x8cp\xa1\xa0b0\xa2g\xa7\xc6\x02\xb9\xca\xe7P\xce\xa2\xc4\x83\x0fU\x80\xd0\xa7\xc2\xcf\xb7\x84\xc1m\x90\x1cd\xd8m\x82\xe8\xa0Cv\x11\xa8P\x07\x0e\xd0\xe2<\xe8\xf0\xbeb\x92\x05zp\xa6\x8b\x98T\x00\xda\xe6\xc0\x80\xcf\x84V|'\xd0\x8a\x19\xb4tG\x8cx\xda\x03\xac\xe2\xa5\x01z\x98U\xe5\xc0*\xc8\x0c:o\xf8L\xa8\xf9w\x025?\x87\x1a\xe3&\xaa\xb6\x03\xb0)\xe0*\x86O\xd5\x16\x0c\xe7\xdag\xc4\x0fk>\xd7\xfa\x05\x1f\x15?f${\x1f^\xd7\n\xb3\xe5\x05\x89\xe57\x05Ty\x17\xa4\xfb\x87?\xf0\x91\xd1wE\xfe\xf4\x99\xcd8V\xcb\xca\x93\x87y\xd0\x81 \x9dp\x0f\xc5`\xc7\x05\x8d\xc5\n\x9dqM8\xd65\x8a\x9bR\x93CLd\x93\xe8\xa1R\x96\xd0\x89\xc6\x1f\x01d+\x8bkfOq\x0dO\xf2$<\x8f\xe1\xba\xd3q`\n\x9d\x11\xa4\xf6\x8a\x9e\xc9\xe3\xeb3\x17\xd68\x97\x95\x0b\xd7\x0e_\xbd\xea\x0808\xa6\x99C\x98\xb3,\xa5\x06rC\x87?o\"bK\x17\xdd\xc0\xe7\x9c\xbb\xab\xa1\\\xd8\x1c\xbb\xe8\xec\x920\x8d}\x92\xe8\x81!\x9e\x1c(\x17\x0c([\xf6\x12Fp\x8e\xa9\xe9m\xc7\xe9N\xa3\x90<.\x01f\xc9\x0c,%\xd8\\t:f\xe8\x88\x87B\xa9y$\xc6\x01\x98\x01$\x1e:\x89\xabb|\xe6\x91\x88\x07\x0d:lifWhZ\xbbF\x03fN.\xae\xc6\xbd3\x87\"\x9e\x98kO\xcc\xb4\x1e\xac\x06[B\x86+\xb8\x91K[\xac \x01>\x1a\x92\x91\xc9\xcfi\x11+\xba\x0eCb\xdb\xda\xe9[naG\xc2n\xdd\xce\xd8HN\xe1@\xec~\xb8\xf2\xd3\x05\\\x92\xeb\x04\xfenAG\xdcg\xd3\x176qx\x9a[\x17P\xd9d\xddX0\x84S\x17>\xb65?3J\"\xd3R\xc1\x0d\xa5\xb8\x96\xa5\xf2\x1a\xadn\x1b\xeb\x8f@\xad\x8d3\xf7\xe1\xbaw\x8f\xff\xca\x1d\x8b\xabg\xa5\xf5/\xff\x92\x07\n\xd1\x9f\xd3f9)\x97\xf2\x80\xc5\xcdEg\xc3\x18\xcd\x9b\xd3\xb1\xafZ\x80\x1b-\xb2\x89\xc6\xdc\xfa\x0e S\x1e+\xdb\x08me|=\x1a[#k\x08\xd6\xa8g\xc0`k\x88\xc5\x83j\xb8\xa7\x1b\xa3\xc6\xc0\xfa\x03\xc5\xc9\xcaE\xc0\xfd\xf1hxv\x7f\xde$\x9aK\x0d\x91qzV\xed\xb7^\xa6\x0c\xef\x06(=\x9c\xb6 (\xa3\x01-\x1en\x02\x14\x06\x0e\xdb\xea\xb2\xcd\x9c\x8e{\xe8\xe8Ma\xc5\xfe\xee\x9f\xa1\x8dD\x92]0.\xc0\x1e\xd0#Z~\xd1w\x1c \x9a\xf6\xa8\xf7i4p\xee\x1e\xa0\x05\xbe\xea\xf7\xce\xdd\xdc\x80\x0d\x9c\xba\x9bn_\xaf\x07\x18R\x12Y\xb1\xe4\xc7\xa2\x8b\x8b\x98\x95^\\h\x83~z\xd3iL\x92\x84\xd5a\xbf\xb5\xd5b\xc2{\x89\x89\xbe\xa38\xf5'\x01\xe1u\xf0\xb7\xb6Z\xe2Oy%\xfaK[%\x9b\xfa\x11\xabB\x7f\xe9\xaa\\`\xf1\x85\xb6\xc8KX\xfb\xf4\x87\xb6\xc2\xd4g\xe5S__\x1c\xf1b}\xcf\xfe\x9c\x15\xfbsmq\x10M.\x7f\xce\xa2\x94\x8f!\xffS[9\x9a^\xb3j\xd1\xb4\x12P\x05+\xb0\xa5\xd3/\xdcE\x96\xa6Q\xc8*\xe0O]\xa5\x89\x17\xae=\xb6\xb8\xec\xa7\xbe\xd2*\xf5yS\xfc\xb7\xb6\x9a\xcfgE\x7fh+D|i\xe9\x0f}\x85\x80\x97kc\xc6N\xa2`\x1eG\xd9J\xd4\xc1?t\x15\xa7^\xca\x90\x91\xfe0U\x08\xfc$\xcd+\xd1?\xb4\x15\xa7\xac\xcaT[H\xd8p\xa7D;\xdc)I=?Hx\x15\xfc\xad\xad6c\x90\x9d\xce\xb4P\x9d\xfa^\x101\x9cb?\xf5\x95\xd6\xbc\xc6Z[\xcc\xc7\xa9\x1f&\x87\x82v\xfed\x89\x85d\xa9/\xbc S^~A\xb4 \x9a\xf9$\x98\xa2\xe9`l[\xe2\x0f}\xc5\xb9\x8cf\xc5\x9f\x86\xcaYLD\xc5,\xd6\"\xd3,\x8a\xd0+\x93V\xc2\x9f\xfaJ\xf1\x92W\x89\xb5s\\\xf4\xb1x\xd1\xd7\x16\x0eX\xe1@[\xb8\xc3\nw\xb4\x85\xbb\xacpW[\xb8\xc7\n\xf7\xb4\x85\xfb\xacp_[\x88V\x1f\xb4\x98x\xda\xf5\xa0\xef9P\xd8Om\xa5b\x97-\x8c{l\xc1[\xd1\xb7\x90.\x19\xca\xd1\x1f\xba\n\x8c\xc4j \xac?\x8b1\\&-\xc7\x9f\xdaJK\xb6%\xfc\xa5v?\xf8\xe1*c8\x87\xbf\xf4U\x12^A\xbb+//\x18 //\xb4p\xbc$\xd7s\xc2P\x95\xfd\xd4U\n\xbc\x0bN!\xf0\x97\xb6\n\x99\x93\x90\xf5\xc4~j+1h\x05Zp\x05~x\xc9\x8b\xc3K]\x85\xa5\xe7\xb3\x81\xd2\x1f\xfa\n+^\xae]\xe8\xa5\x17_\xf2\xf2X\xdf\x01 3V\x81\x84\x99\xa9\x82\x9frR\"\xfe\xd0W\xe4t[\xe7w\xc8+p\xec\xc5_\xba*\xa1\xc7Ha\xe8iIa\x181\xbfaV\x87\xff\xa1\xab\xc8\x04F\xac\xc6\xc5Z]%\xb6\xbc\xfa\xe3*Z\xa5\xc5F\x12\x7f\x18*\n\xba\x17\x19i^\x94\xa5\x02\xa7\xd9O]%\xd6\x97\xb6\x93\x95\x17{l\x05\xf0\x97\xb6\x8a?I\x05]\xe5\xbf\xb5\xd5D\x15Sq4\xcf9F\xf1\x87\xae\xe2\xcfX\xe3g]Q\xcc&\x12kg\x123(\xc4Z\x08\xc4\xd9\x05\xe3\x99\xe8\x0f]\x056.\xed\x80\x12o\xc9\xfa\xa5?\xb4\x15\n\xd41#NB&\xf9r\xf2\xdf\xfaj\x81\xc0/\xf6S[i\xe9\x05\x0c\xc5X\nN]\x15L\xa3\xc4\xea\xe0Om\xa5\x95\xc7\x07\xb4\xf2\xf4\xa3I\xe3(d$\x95\xfd\xd4W\xba\xe6\x0c<\xfe\xd2V\xc9\x18\xeb\x9ddZ\xe6;\xc9\x96K/\xbe\xe6U\xf0\xb7\xbe\x1a_\x07\xfd~IY\x1c\x95\xd8\xb6R\xe6\xdb\xa2\xa9\x92\xf3\xce\xa9\x89yN\x19\xd9M\xb5$7%\x1f\xd3\\\xa4\x11\x7fh+R\xde\x82\xd5\xa2\xbf\xb4U\x16\xac\\\x9br=\xcd\x8f\xec\xd4tf\xa7>?\x0e\xe9\x0f}\x85T\xc0\x03#L\xeb\xaa0\xaa\x99jIf\x1a{\x93K^\xeeM\xb44\x9e\x11x-u\xcf\x18\x82fZ\xec\\{\xac\xe3\xb5\xa7\xedy\xedO \x13\xa7\xf0\x97\xae\xca\x15\x17r\xae\xf4R\xce\xc4\x8f\x85T\xc9~j+\x05\xfe\xea\xad\xc7\xd7A\xfc\xa1\xab8%3\xc1\xaf\xcf\xb4$\x82\x04\x81\xbf\xe2\x02$\xff\xad\xab\xc6v\x92\x9e5Yzs\xce\xdd,1\x93C\xb5J\xe0\x87\xac\x06\xfda\xaa\xe0\xc5_\xc5\xde\xd4G3f^\xb5x\xa5\xfbh\xe9%\xe2\x1cO\xb4k\xbc\x12\x10Z\x19\xa0\xb3\xf2\xd2\x94\xc4\xa1\xa8C\x7fk\xabE\xc1\xf5\x9c\x13@\xfe\xdbT-\x9f\xa9\xf8CW\x91\xce\xc9\x0bJ\xb3-\xbf\xd2~$\x88kl\"\xadi\xc4\x89L\x1a\xe9\x89\xfd\x9a\xd3\xc3\xb5v\x1d)Q\xc8\xa9\x83\xb6BNtSFuK5\x0c:\"v {\x07:\xa2:\xbbvn3\xdd7\xb9\x07\xfb\xc2\x9e\xecs\xc7\xd1\xdf\xdb\xd8\x01Yx\xe4\xd0\xfe\xe4`\x8cw\xa0\x03\xd6\xd8\x83s\x8f<\xf5\xf6\x97[\x8f\xebcYT\xdckx\xa8\xe7}5V\xb0\xf0\x8b1\xf9\x18\xd7\xda\xa2\x08[\x92\xcfQ\xe9\x03\xb7\x08\xd6\xab\xf5E/3Z\xe3\xc9\x13/\x8c\xc2\xebe\x94%O\x9fj\xb4\xb7\x81Q\xe5\xeb1s\xb9\xb5m\xe1/\xddN\x00\xd4eQ^ym\xe7\xf7\xba\x86zt\xbaX/\x9f\xb7\xa1\"\xbb\xe0\xc5\xaa\xfc\xae\xd7PQ0\xf2\xeb:F\x1e\xf2\xc08X\x91\xdf'\x9b*\xf2 ck\x11\xcf\xd8T\xd1\x0b\xaf\x870\xb5c\xd9\xf6\xef5^`\x9bA\xf9f\xd6\xa4\x82\x17\x8f\xb8\\*\xe2\x99\x14\xe6\xce.DM\xf7\x8b\xca\x15\xccVal\xe0\xc8\xf6\x1d\x0b\xdb\x12n\xdf\xf0\xa3\x05\x1d\x88\xa0\x03\xd6\x8f\x10\xcd\x8a\x94s\xac f\x05\x0b/\x01?\\S\xea\x93{\xcf@\x18\xa5\x98\xc0\x82\x8a\xdd\xfe\x94\x88\xa9vM\xe9C\xc5C\x11\x14\x13I\x8dCC\xb2W\xf1`D\x89\xf2\xa5yV\x1b\xb0B<\xb4\x0b4\xad\xacD\x17\xd0=e\xc8\xbc\xe4\xf3\xa4\xd3\xf71\x16\x99\x02\"\x0c \x8d\xef\x12\xf6.\xc9V\xab\xc0gi>$\xa8\xb9@>\xae\xc8$%S\xf0B\x06\x9d\xaeu\x9b\xebX\xf1\xe4w\xe0<\xd0\xc2\x04\x9e@\x96\x1b\x06L:\x9d\xb6\xa0\x99aj\xc9\x0c\x93\xe2r\xcc\xa2#\x1e\xd3\xb1O\xe8\xaf3\xcb\x05\xaf\x05\xe4\xe8\x02\xcddCJ\xf4T.\x8c.>c\xb2:sx\xf5\xb91\xdc\xe2\xea\xb7\"\x11\x1eb\xf9\xde\xfa\x82;qC$O7@l\xef\xcb#\xb6\xd7\x1a\xb1!\xf1\xc3y@\xe0\x84x\x93\x94s&\x9f\x87\xe5\x9f\xb3\xf0\xa6\xack\x02C\x7fWB\xbce\xd3\xc5/\x99\x19\xb7^c\xe6P\x14zK\x16)K?+\xf5\xf1\x1a\x8d\x9eM\x0f\xc3\xc1\xae\x14\n\x16\xe3\x0d\x97\xde\xe0h\x8a\xad\xdd\x8c}\xe2\x11vp\x95\xc6Z\xb5pc\x1b\xa2W\xab\xcf\x97Gv\xb1\x92\xf4s\xac\x91a\x8d\x7f\x1c\xba\x1b\xb8(\xbc\x92\xbb%\x91\xabu\xb0R\x1fD\x9bk;\x1d\x933Ge0\xe4\x05\x88\x8b\x05\xf0\x0d\xc0\x0e\xab\x94\x05I\xca\xebhJ\x1a9\x8a\xcf\x81\xa1\x89d0\xbe\xf2w%\x18\xff0\xceM\xcc\xb5\x11\xd0\xf2\xa9\xd6L\x93\xdaq`%+\xb3\xad\xd1\x08\x92:T\xbaC\x8e\x8c\xf5\xd98g\x89\xeb\xf2C\xc8\xea\xf7:\xf0 e\xdd\x85\x97H\xd1\x95\xecI+\xd2\x0f\xf5\x0cZ\x17\x19\xb4v\xac\x19|.{\x06\xff\x00\xd2\x15\x85\x1b\x1c\xd1\x1a\xe9@\x8aTW\x11\xd0jL\x0d?o\xeb\x16Q\xd1\xc4\xce`\x810\x1f\x83\x07O \xcd\x19tO\xf6\x866=tR+\xba\xf2\xe9\xd8\x93\x89j\xed\x04@\x12y\xfer\xfa\xe6u\x91?H\x9bYB~6\xdcih\xb2*\x1f~-\xb6Z\x14\xe2\x89\x99o\xcf\xba\xf3\xf2\x16\xe8B)\xda\xef\x8e2R\xe8i\x16\xad\xbb\xb4\xd2\xa4Y\x14\x13\xba\xa0T\x9b\xa9_~\x8c'C\x98\x0f<\xb2\xb7\xfa.\xe4\xab'\xe2\xf4\x96\xd6&\x87U\x17\x8eU\xb1\x14\x8f\x8f\x05\x99\\\xe6`L\\\xb8\xc8R\x88\xc9\x84\xf8k2\x85?&\xe0\xa5\xe0\x87S\xf2\x11\xfe\x98t-\x17\xce1\x99\x0bA\xe7m\x05l\xe6\xd5\xfd]\xb6`\xef1d\xa5\xe5\xc8\x9a\x97\x03\xa4\x1d\x94\x8e\xb3\x86%\x01(\xfb\xd5&\xe5\xd1R\x02\xed\xb4\xa2\x8e\xd0\x9a\xc6\xb6\xd9\x9f\x86\xadxw\xfb-Y\xb4\xb0&\x15\xcfg.\xe9\x7f=\xac\xc6\x8f\xac\xc7\x1f7\xe44Z p9\xb30\x9e\xb4\xc4\xd9Y\x9bf\x817\x1d`\xac\x84;\xe1C\x82\x1c\xd4\xf5\xdb\x01\x1a\xb7D\xbb\x0dswL \xf9\xe8M\xd2\xdf\x11\xeb\x93\xd6X?A\xacO6\xc5\xfa\xc9g`\xfd\xe4\xce\xb1^\xa0p\x86q\xed\x18\xff\xd4\xc4\xb5\xe4;%\xa0;\xa5\x15J\xd3\xda+\xdc)A\xcb\x9d\xb2\xb5\xda\x0cN\x97\x84\xcbdA=9\xfe!|\xe6M\xf3+\x0cZ\xa0\xf0l\x0c\x06,\xc6\x80\x05\xdcs\xe5\x87\x10/\xff\xd0\xd1E\xfb\x95\xec\xf7\x92:\xa5\xef[l\xd35\xf7s[\xd9\x89\x0bAu\xb7\x07\xedv;\x85\xdb4\x07\xdb\xf4\x1f\xb4\x8f+oo$\xafM\xa8\x06B\xd2\xe1\x8f\xd0Z\xe5\x891x\xf2\x02\xf8\xf4 \xfap\x1f\x0b\xf0\x07\x81!f\x00c^2\x84\xfeR\x03@\xe8\xfb^\x18\x02\x13,\xfc\xa4\xbb$I\xe2\xcd\x89\x14\xf8(I\xbd\xc9%\xbaW\xb5j|j\xc8\xff \xcaC\x9b\x11\xa5\xc8\x85\xcc\x85\x04)\xbc\xd6\xe5\x93>6=\x883\xa6\x89D\xa23\xc1\xa4V.\xb0X\xa5\x9e\xc3S.`b&dE\x8f\xbc \xf0\xc3y\x11j\x0dp\xe7xi\x14'0\xf5c2I\x83k\x91\xe4\x85n\x94(\xa6D\xe3\xe2\x1a\xd2\x05\x81\x1fWq\xb4\xda\xa6D'\xf9\x11V\xde\xe4\xd2\x9b\x93.\xbcO\x08\xfc\x987\xd8E\x865\xff\xd3v~\xa4\xfbl\xe2\x05\x01mb\xd9\x85\x13\xe2Ma\x19\xc5\x84r\xae\x8b4]\x0d\xef\xdf\x9f]t\x97\xe4~\x96\x90m\xfcz\xbb\xe8\xc7\xb8I$<\xc48\xd0\xe3\xe8\x0c\x0e\xd0\xd93\xf7W\x15\xef\x18\x91x\xb7 \x85\xacS\"\x9a~\x82\x86\x97\x94\xf1N &?g~\x8cZEY\x9eb|\xb7\x9f&\\\xd4\xf2\x13\xf8\x91vD\xe9(\x0c\xbf\\\x1f\xb9\xbf\xae\xe8\x88Nn\x08\xa9]\xc2\x91&Op\x90\xaf\xe6\xbb\x17~8\xb5\x19\x19\xda\xeak\xc0\x9b\x8b]~r\"F\xaa~\xd7\xabF\x981`\xfc\xba6\xa4\xa3\xe9@v!3a\xbd\xb8k1_\xe1\xf0\xb6\xe7\xb6\xe7p\xe2p\xd0\xee\xa8(\x1d\xa9K\xfay\xdbS\x95\xbeM\x05[\xcf\xd7\xa9\xba(\xaa\x17\x93\x1eb\xd7\xb6\x96\xf2%W>\x8b\x92\x9b{\xef\xe9\xe13\xf1\x12\x92;e\x0fk\xaa\xf0\x9b\xf7\xba*\x85\xbb\xb8\xbe\x16\x14\xd06\xa5 `\x0d S\x84\xe6f\x0c\x9e\xb7\xac\x19\xce.\x99[\xd1\xbas\x8b\xb6I\x97\xacI|m_7x@\x97=\xdeS\xb9\x89\xbaD\x0bk5Bc\xa3\xa8\xb0.9r\x86\xcc\x913\xe4\x8e\x9c\x93\xa6\xdb\x95\x8d\x1c;\xd5\xe7\xa6\xd1\x0f|+n\x953\x82\xce\xc1\x17)O[9\x98\xc7\x8a\x83y\x1b%\xc2c\xd8\xb2}LhPv\xec\xae\xfd\x12\x8a\xbb\x10\x9fyuK\x0b\xd97\x83f\x03gs\xdd\x98Zr\xbd\x18Z\xa8\xad\xb39*\xaf1\xf1\xc5\xb5\x9d\x8d\xfbg\xad&\x02mt;&\x8c\x16\xe1\xa5\x1b\xbf\xaf\xf6\x7f\xd3\x8a\xcc\xcd\xeb\xbd^\xc5=\x8b\xf1|R\xf5\x85p\x00\xdc.\n9?I\xbd~B\xe6\xc7\x1fW\x85k\xba\x05-\xa3\x13\xf1\x9e\xa4\xfc7\x9c\xd3\x14I\xa1\x18\x95\x18[\xff\xf2/R*B\x0b7p\x835\x19\x91\x07\xc8^W\xe1\xc8\"q\xd1\x81\x8b\x11T2W\x1a\x80\xbb4\xc7\x14\x93\x12\xcb\xe1\\rjW\\i1\xb7\xe8*\xe4\xc5\xda\xcc\xb5\xfa\xebJ\\\x82\xfa\xa8O2\x00\x9e{\xa9\x94\xb1g\xea\xa5\xc4\x90\xb4\xa7\xf2%[\xdb\xe2\xdb\x98\xcc\xc9\xc7\x95\xc6\xeb\xd9\x84F\xed\xe0y^\x8f\xac\xfaT\xd1\xe2\xc4n8\xaa\x19\xd2\xd6\x1d\xc3\x8d\xc7\x9e\x98\xbd\x17\"gS{\x86\xd6\x1f\xc5\xac\x0e\xae@]\x05\x0e\xe6\x16#\xaa\x1bP[\x1a\xd3\x14\x89\xae\xfc\x17\xffH\x8a\x88 #v\xc5&g/\x08\x14I\x05F\x94\x95\x0e\xba\xf2\x8b\xc0\x055\xe8\xe7\xad\xccb\xebb\x01\xe5W\xfaw\xd4\xbe\xd5\xdf\xeb\xeewy0\x84[\xb5\xb6.\xc2\xec\xef=tLa\xc5\xfdV\xf6\xcf>\x7fu\xf8\xfa{C\xbc\x87$\xf5R\x7f\xd2\xae\xee\xaa\x08\xb4\xde\xa26\x8f\xf2\xba\xc1\x07\x0b?\x98\x1em\xfa\xd5\x9c\xa4\xcf\x199\xa0;P\xf9\xe6\xfc\xd5\xf1\xc9W\xc7\xcf\xcd\x9f\xbe\x0c\xfd\xd4\xf7\x82\xd3\x14S=l\xf4\xe9\x914\xdcM>\x8dI\x88\xfe\xbd\xe2\x8b7\xaf\x8f\x8e\x8d \xe4[\xe8[?\x08^\xb1p\xaa-@\x92\x7f\xf6\xdc\x9f\xde\xe2+\xda\xd9 \xbb)\xd4\x80\xd4\x84G\x8b(\xa3\xe0\xe0m\xbc_MK\x10m;I\xf5\xbb6\xe3}\xeeOo\xf3\x19v\x17.[\xc3\xe7\xfd\xeb\xd3\xc3\x17\xc7\xe7\xb7\\\x13\xdd\xd7\x1b\x03Y\xd7\xc8\x06S\xcf\xb0\xaa\x94\xcf\xc1z\xf3\xe1\xf8\xe4\xe4\xe5\xf3\xe3\xf3g\x87\xa7\xc7\x1a\xe6\xa7\xda\xce\xc4Htp#\xc6\xfe\x9aLq7\xbd\x88\xa3e\xcd\x8el\xd3\xd7\xcc\xd8\xd7\xd4OV\x81\x87I\xceZ\xb2\xe4\x80\x84W\xfa\x0eT\xbd\xaex\x0c\xd7F\x82\xa6\xb6\xee\x8d\xb2\x9c\x9a\xd8\x9e\xf2\x93\xdf{\x84\xec\x9e;,\x85\x86\x0b;\x1d\x87k\xb4\xc7\xe1\xd9Fw\\\x1aR\xdaz\xdci\xb7\xf25f\x1b\xfc\xfb\x8d\xab+\xd3\x060\x85\x9a\xa1\xddzT\x86\x01}\xc6X*g\xc7\x06\xc3Q\xbe\xc5\x00G\xea\xbb\x11L\xed\xca[ly\xa8\xad\xbd\x11BJ\xa7\xf1\x06\xc3^Il\xaa\x00a\xfenS\xf8\xe5\xccC\xeb\x01l\xb5\xaf\n\xed\xf6\x10\x94\xf7\x91\x1f6\xb7*\x1e\xc1\xe85\x1b\xf5\x8b\x07\xc7\xa3\xda\x02\x86\xadm\x01A\xe8\xbd(\xbb\x88W\x9d\xed\xba\xa5Odo\xf9.\xfc \xadhy6\x9b\xef\xa3\x0c<\xbc\x10I\xc9r\x95\xfa\xe1\x1c\xd2\x88gi\x07\x0fb\x92\x90xM\xa6\x88)t\xa4.\xfc\xf8\xc7\xe4G\x17\xd2\x85\x97\xf2\x03;\xfc\xe1O)\\\x10\x88B\xbc\xa9\xb1\xf8\x8aZpI\xae\xbb\xf0\x9c5\xe5cn:/,,\xa6E\x8b\xf8\x86x\xd3\xc7\xb4\xce\x95\x1f\x04\x90\xa4\xf4\xff\x17\x04\xbc\xc9\x84$,94o\\\xb6\x17\xff\x93>t\xbe\xe9\x11z/\x04\x9a!\xee\xb5\xeeA\xf5\xd7&\xab\x03\x12\xcf=\xa9.4\x1c\xc0d\x1c\x9eqE}\xfbq@!^F\xb6\xee8D\xbd\x87\xe7\x82\xd5z}\xe9RR\xc8^GY,\x19\x0b\xe3\x0dY\xba\xf0B\x88\xc2 \xe9\xc2\xbb\x85\x9fP\xc8\xcf\x02\x7f\x92\xc2\xd2\xbb\xa6k3\xcd\x08m\xc9c\x87Z\xd7ba\x99\xd7\x91?\xb5Q\x8f\x8ct\x0bo\xad\xe3\x86\x80\x93\xf2S\x7f\x01,?\xbc\x13}\x1ch\xf5in\xd6\\\xe3\x86Q\x99Mh\x9a\x97\xa5\xd1\x85\x1fN\xcb&\xf7\x1b\xdcA\xeb\xd3\xfd\x80d$\x98\xa8\x88E(b%cbF\xacs\xcd'\xf7\xeeQd*\xb3p,tm \x8f0?\xc3\xcc\x9b\x10\x13BEk\x12\xc7\xfe\x94\xa3\xd4,\x8e\x96\x1c\xa9\xe8\xd7\x90\xac\xc8\xc4\x9f\xf9\x13\xb40\xef\xc2q\x98d\x0c\xc3RVkI\xd2E4\x85\x10\x93\xd1N#\xbc\x01\xa6-\x06\xde\x8a\x85\xf2\xc4\x91\xf0jhjH\x1c\x97\xdd\\\x94\xb7\x82\x08\xbb\xfb\xe9\x93\x96a\xbc\xcd\xcc\xbe\xc8V!\xedn\xe3\x90q3\xa7\xf00\x11\xa5\xc8`\x1cZ%\x0d\x7f\xaaL7K(\xd9/&\xc8\x160\x8a\x8bAQ2\xceg\x02/\x19\xe9v\xe1\xa7,I\xf9\xb71\x99g\x81\x17\x17\xb6\xf4.=w\x08\xda\x86n\xde\xff\xc6\xbd\xe9 \xea:\xcf\xd7T\xa8\xe1\x8c;\xde\xc7\xfb\xa4\xf3\xf3\x98\x0e\xf60K\xa3g~8}\xeb\xf9\xb1&\x863\xc8\xac\x83G\x8f\x96P\xddf\x19\xcb\x14\xdee\xdc?.)\xff\xedh\xa3\xd0\x8b\x07\xd7Xm\x8c\x19Vxx\x8d\xd5x*\xad\xb9ch8\xf6Z\x98\x8e\xadp\xda\x95\xfe\x9a/\x02\x03{\xc5\x12\x01\xcd\xaa_;0\x1b{gt\xd2\x93\x86\x96jbQ\xcb\x0f\x9d\xd3BG\x00\x9bF\nu\x86\xd3h\xbd\x82\x01\xc4W\xe8\xe6\xd6g\xa4\xa2+(y\xbb\x13\x0c-\xf5\x9b\x16E~\xd6<\xa4w2\xf6Zr\x8f\x80\xfb\x1b\x03\x9b\x9b\x99\x80k\x95\x00\xf2\xd7\xea\x0e|\x1f\xe6V\x04\x94D\xc3*\n\xfc\xc95\xfc1A\x94\xbe$\xf8\xf3jAB\xb6\x03\xe7\x14\xbd\x8b\xadI?Ab|\xcdV\xbff8\x07\x10\x8f=\xc6\x13\xd0\x1f\x14\x19`\xa8\x1b!\x8b*\xcc\xea\xae\xf3\xba\xed\xa0\xcfCT\xf3\xaf'\xcd\xf0d\x11\xadY*\x16\x8f\xf6\xe3\xe6\x1f\xd7~[\xc3+T\x8f\xf8V\x84~a<\xef\xcbbIds\x8b\xb2\x9a\xfc\x01\x9a\xf7\xc4\x05kI\xe29\x11\x89\x97^G\xcf\xb3U@\x0fd\xf25\xb9Nlg\x08G^H\x8f]\xac\x06a\x14n\xb3f\x12$\xe0\xc4\x01\x8d\xc8\xc2r\xa7\x95.\xf5\x90\xe1k\xec\xeb]\xcc-ZXo\xe9U\xc4\xe9w\xc2\x8e{\xca\xe9'\xde\x92P\x14\x1c\xe2\xd1\xdb\xead}LA\xb4\xc2\xa8\xb3\xf4L`Vr\xa2\xea\xc4\xcb\x12nNv\x15\xa9j[\xdb\xa1G\x9c\"L\xdb\x8e\xe088\xdfMw@i\x9c\xf4p\\\xd0\xb7\x97\xe4:\x11,0gL\x0d.\xaa\xc2\x86\xb0\x15ZL\x9bL\x11e\xf6\xd2x\xee\xa1OI\xd7[\xad\x82k\xccE\xe2\xe6\xde \x89\xc1\xd1\x91>(\xd4\x1a\xbe2\xdf\x8f\n\x9b\xb8\xc2\x11%n\xae\\\x18{\x84\xe6\xd3\x1bC\x1ek\xe2G\x83t\xebf\xfbl \xf0\x87>\xd9I\xbb\xfd\xb8\xfel\xc0\x1b\x01n\x04\xea-\x87z\xdd(*\x10f=\xa7\xbb%\x16`WzR[\xd1\xe77\x06\xfd5A#h@X\xb4\x9e\x9f\xfb ~\x84F~\x9a$\xeb\xa0'\xa9U\xa4]6\x0f\xb0\xa4\xaa\xbf\xf5\x18\xf5\x06/\xad\xc6xn\x1c#\x8fY\xce/\x90Z+\xb7p|L\x1f\x1fwI\xf8sF2r\"5\xc51lc\xe95\x9fpK8 c\x9c-\x15`\xb7\x87\xd5\x859\xd90HV\xa2\xf6\x85|\xab.\xf3\xf6p\xae!m\x05d\xeb\xc8%Q\xaeT\xe3\x1a{P(\xd0\xa4*,\x88|p\x94\xf9o\xecY<%/\xc2T\xdb\xaekP\xf5Cg\x04\x83\xa6\xf6A\xd1Y6\x8b\x05\xc0%\"2\x0e\xa1\x03\xfd\x16|*&\x84\x181\xca\xe4\xdf6\x10\xc2\x0d\xa2\xaf\xc8\xb3\xb7\xe2\xda\xedj\x96c\x91\xd07&3\x0cj\xe6\x96\xf6\x850R\x0f\x0b\x93\xf9T\xe4\x172ODh\xef\xf0\x13\x85U\x80\x03\xedk\xdbiT\xe8E\xb6\x865\xf3\xd0\xb0\xaelO\x86\xcc\xf4\x1f5]\x0caI%_\x8e\xfe\xb9\xbf:\xe5]h\xd7\x16=\\\xe4\xeb)*\x050~\x9fR\xc1\xc4\x97.\xee,G\x81\x88\xa7\xdf\xad\x0d\x12o\x8c\xca\xf2\x92\xb5KH\xae\xe0\xc2\x95_\x96\x82\x88`\x8ef\xb9P\x87\xe2<\xd5\xa0'\x12\xdf\xdb+\xd9\x02\x9c8\x8e\x0b+\x9b\xb80\x17?R\xf1c\x89'\xacz-\x82\xbe\x08\xdd\xa9rS\xa2V\xb3\x1d\xd4U\xc8\x83c\x17\xed.XR\nx\xbb\xdb\xedR\x86\xb9\xaa\xdab\xcb\xe3/W\xcc\x1c\x05<\xf8\x915\xf0#\xe7$\x91\x99N\x1cy\xfe\xd3E\xa64'\x13\x8fJ\xb4\xfc\x83A\x14\x92\xffJ\xcb~ \xca\xad\x8d`p5\x80e\xd1\n5\xa9\xd3Y\x80BM\xc1\x0c#\x12j\nD\x04BM\x91p\xd8\xd3\x14\x89(\x83\xba\"\x1eWPS\x84\x91\x04u\xefE\xc8@\x8d\xd62\x8fa\xa6\xf9N\x0er\xa5\xf9\x94\x85\x052N\xcc\xf0\x15\x8f\xc8a*a\xc1\x174\xa5\xdcU\\7\x05\xe6N\xab\x98\xc3jy\xbe\xb0j:\x19\xbb\x10\x96L'C9\x9f\xeag\x10\x0e\xee>\xc9n\x00\x8a[\x13\x17\xac\xf3s\x92\xbc\x8a\xa6Y@,WA?4\xaa\x1f\xca\xd2\xcc\x0d\x1eI\xfc\xf0\xa9\xa3\x1e|\x8aUt\xce\x85\x98dh`\xef\xdeE\xab\x0b/\x1eB$\xfa\xa9\xd42Y\xad\xde(\x84\xd2\xcd\x89\xfc\x8e\x86*\xda\x94\x90\xfa\xa8\xf9\x89\xbb\x05\x14\xe0\x00b\xd0\x8dMX\xd9V\x1c\xb6\xe0\x1f\xbe(\xd5\x03be\x87v\x7f\xf7\xa1\x9a\x03\xd4\x17E{=]^QVT\xc9\x1c\x9a\xe5E\x95l\xa4^^\xb4\xaf\x16%\xdcfU=\xa8&\xcc\x0fWy;\xa3+\x82-\xed\xef1\x9e\x88\xae\xdb\xae\xa3\xb6\x1a\xf0\xf3l\xdf\xd1\xa5*]\x19\xcfg\xd4'\xa6\xe5uN\xeb\xd7\xd9D\xcdoJ\xd0^\xd4r\x07\xd2\xb9a\xba\xff\xb2{.\xf8\x02\xd7\x1d.\xe9\xea\x9c\x7fho\x88\xb8=\x172\xf5\x03\x9br\x9f\xc8v\x9d\x9f#\x13\xd6s!.*\x11\xc7a^E\xb9 \x1d\xea\\B\xc5\xa5|7\n\xdf\xc7\xc1\xd1\xc2\x0b\xe7\xa4\x95+V!\xe6\xa5^<'i\x9dCN\xd4MH\xca\xc4\x00\xb3\x80\x97\xc5\x81JE\xc5\xa3\xf1\x8b\xbeq!\xea\x06\x917=]\x91I\xab\x01GL\x0e\xebR\xa6\xf7\x10\xeb\nA\xeb}\x1c\xa0\x87\xb9\xae\xc64\xba\ni7j\xba\xf3|\x0c\x08\xb7S\xcc\x8e\xd0j\x18z\xb8\xa1\xe7\x9ax\xb3\x88\x89\xc1.\xa6\x98\xb2Mp\xc0\x14\xae\xd87\x99\xd2Y\xe0\xcdrw\x15\x935 \x85t`\x1b\x06.f\xf6>\x0eZ\x0d\\\xea;b\x82W7\x8b\x83\x0d:\xc4\xb1z\xf1\xa4~\xff\x88G\xc0\x89\xa2u\xd0]yqB\xd8\xd7\x8e)\x834\x19[Y\x1cPq\xdb_z1\n\x91\xd6Y\x1ew\xd2\xac\x9c\xa5\\\xd8\x95\x1fN\xa3\xabn\x10\xf1k~\xdcW\x93\x08#\x1f\xdc\xbfoA\xa7Rc\x11%\xa9\xe6\xf5\xcaK\x17\xe6\xeeXmJ\x98\xf8w\x0b?I\xa3\xf8\xba\xfa\x06/v\x98\xcc^-\x93un\\\xac\xb4,\x97\xc5\x1c<\xa0\x83e@KH\xec{\x81\xffK\x0e8]\x86\xde\x9b*\x1am\xb4>b\xd3\xccIz\x14\x853\x7f\x9e\xd8\x0eE\x8c\x84\xa2\xf4\xd8\xa0p\xc1I\x11I\xc7\xc4n\x86r\x899\xef^\xe7\x12Pj\x88v\xc5]\xb2\xf0B\xa7\x0d\xa5\x81<\xb5 \x99\xbe\x0c\xa7\xe4\xe3\xd0\x90\xc2\x1e8\x03$\xe1\xae1\xcb\xb1\x89FE\xe1\x0b?HI\xfc\xc5H+\x03\x7f\xe0]GYZ\xa6k\xacc\x9d\xfd [t\xae<\xd1\x0f\x02\xc9q\x8a\xb4\x90\xa1F\x14'\x14\xd8\xa6\xf8\x92\n@\xab\xfap\xdag\xe9\xa5\xd6\xf9\x88b\xae'\x9dbL;B\xdfF\xa5\xb7\xe3\xea\xa8\xf1\xbe\xcd2\x1a\x98kl\xc29g\xd5\xbc\"L\xd9\xd4\x8cYf\xa0\xb5\xc6\x992\x88T^\x10\xf4\xf3D\x9du\x8b \xd6a\\\xcau\x86f\xa5*\x11Z\xc5\xea\x8e7\x7f\xc4.q\x9a\x08\x02\xde\xa8\xd1\x1d\x1cr\xa2P\xb7\xe9\x0b\x15\xb0\x86\xe0\x9bU\x981k\x7fc\x1a\x03Hg0v1F\xc7`|e\x0bl\x10OkZ\x03z\x9ch(j\xbc\xb7o\x81D\xe2\x06\xec\x8ep\xe86g\x02\xe7\xd7\xa53\x816\x94\xf3\x1c\xe9\xb8\xd0\xf8vK\x10=C>\xe4\xf6@`Z\xce;\x9dy\xc3\x1eb\x80\xd1z\x07\xca\x0f\xbb\xfb.\x11\x13s\xe5\xb8h\x18!n\xae\x89\xf7!\xb6\xf5\xcc\x98pU<\x11\xab\xf8\x8d!i\x9fx\xd0\xc9\x8f\xae\x93\x1f\xce\xb9\x95b\x97\xffIwHVK\x1e\xbc\x9a\x9bqk\xe6\xf9\x01\x99\x1a\xda\xc4\xf3\xde\xebN\xa2\x00\x15\xf3V\x8c\xd9=!S\xdf\xff\xff<\xcf\xab\xb3\xac\x0b\xd0\x11\x80\xe1\xa7y\x9c+\x83\x0f\xa2x\x16\xb5\xf72<`\\=I\x9bb\x17f\xfa\x15TIW\xd3-+}\xa6\xccFh\"\x8eO\x9e\x9aYh\xadE:?\xdd\xfeP\x1f\xdc/5\xb6\x87\xe2\xe1\x1b'\xa50\xad'v.\xe7\xcek\xac\xa4(\x03\xb6j\x98\x03\xcb]\xd94\x054\x07e.S<\x9f\xdd6\xff\xb0\xf6\xb3E\xba\x0c^Dq\xfeQ\xd5uK<7.\x18\x87\x88\xf9\x95\xf2(f\\`\xf4\xf0\n\x86\xa2\xad\xf9;\xd6g\xd3\xdc\xfci1\xbe\xfa\xe9L\xfd\xc4\xbb\x08\xc8t\x08Y}\xc5(d<\xeb\x90\x116I\xd0\xad\xff\x8e\xaf~PO\xb0\xeb\x808uLL63{[\x08b+\xc9\xb0\xcdH\xc2\xd2\xac\xd6\x01RF\x10\xd1\xf4v\x16\x07\xdb\xfcS\xe3\x87)\xaa\x8dY\x9a\xad\x1az\xaa\x01({c\xfeFl\xa5\x02\x94Y\x1c\x98\xab\xb7Z\\\x9e#\xd1pi\xea4\xef7\xffV@\xe4\x19\xbek\xe1\x13\xf8\x93\xcbaem\xf5\x03u\xc1:\xfe\xb8\n\xa2\x984\x05;3\xa2\xc4\xd4_\xb7F\x88\x14\xb5\xd4\xfa\xcd_\xb7\xf17\xe9\xe3*\xf6V+\xf2\x85;a\x13\xd9\xbem_\x91 b\xe6\x8d\xb6\x9c\xd7\x0efA\xfc\xf9\"\x1d\x82\xb5\xd3\xab\xc1\x86+\x7f\x9a.\x9a*%\xf1d\x0831\x90\x1a6#\xa0\xfd\x9d^y\xf39\x89\xe1\xfdK\xc3\xack q\x89\x80'\xac)\xcb\xa9\xfb\x04\x13v\xb7]\x96\xd2^\x11\x8bS\xb7YN\xb3\x8b\xa5\x9f\x0eaaZ\xc1Uw\xe9\xad\xda3\x0b\x92\x04\x9et'A\x14\x8a\x898\xf4\xd3\xfa\xe3\x87q\x06f\x9an\x92\x7f\x1d\x1d\xa5W8\xf73\xc7\x95\x9a\xbe\x91\xa8R\xceCK\xdb_\xbe\xacb\x90Qojd\x18\x94\x02\x80`J~\xccxy\x7f\x15\xce\x1f_x \xd9\xdfu\xfd\x0f\xcf\xde\x9c\\\xf5\xbe\xfej\x1e\x1d\x1e\x1e\x1e\xbe>}\xbf8~??<<|\xb6K\xff&G\x87\xaf\xe8\xbf\xaf\x1e\x04\xfb\x7f\xa5?\xbe\x7f\xf1\xec\xd5\x87\xe3\xf7\xb4\xc2\xfb\xd9\xd5\xad\xfe\xeb\x05\xbf<\xbb\x1f\xf6\x9e\xcd\x16\x1f\x9f\xad~\xba>\xea}\xdc\xbd\x7f\xff\xfe\xfd\xce\xcf\xeb\xdd\xa3\xbf\xac\xfa\xcf{\x8f:\x9dY\xbast\xff\x97\xbd\xfb_\xf7\xf7\xef\xbf\xdfy\xf0\xe8\xfd\xec\xea\xf9l\xef\xe1\xfd\x9f\x1f<\xea\xbc\x8f\x07\xcf\x07'G\x97\x8f\xe8x\xfe\xfc\xdd\xc9\xe9\xbb\xe0\xd5\xe1\xf1\xf1\xe1U\xf8\xe8\xfe\xfd_v\x0e\xe7\xeb\xdd\xfb\xeb\xef_>\xbf\xaf>\xef_\x91\x9f\xfc\xfe\xe5\xe1\xe1\xe1\xf3\x87\xa7\xefO\x9e}\xf8\xf3\xfcY\xf0\xb7W/\x0e\xa3\xbf^=?|w\xf2\xf1\xe2\xbbg\x0ff\x9d\xf5\xdb\xaf\xc3\xe0\xbb\xc3\xbf\x85\xfb\x97\x83\xc9l\xe7\xf0\xd1/\xf7\xdf\xce\xde\x1c=|\xf9\xf2\xfb\xd0\xdf{\xb1\\\x1e>{\xf5\xf0\xc5\xab\xc5\xd5\xbb\xfe\x83\xc9\xa3E\xb8\xf0\xff\xf6M\xff\xe8j}\xfcM?]\xbe}\xde\xfb\xf9\xf4\xeb\x9f\xf7\xe7\xdei\xfa\xed\xfd\xcbW\xdfy\xe1\x87\xe5\xe1\x87\x93\xe7\xef\x83?\xf7\xdf\xac\xb3\xec\xdd\xcb\xd7\xd1\xfe\xe5\xa3\xde\xe9\xc7\xd9\xc3\x9f\x937\xe9\x8b\xfd\xf9\xeel\xd6\x8f\x92\xb7;o\xc2W\x93\x0f\x0f\xa6\xbb\xab_\xa6/\xdf\xa7Y?:\xdc\xfd\xd0{\xfe\xb7\xe8\xeb\xe5\xc7ep\xfc\xfd:}\xfe\xfe\xa7\x9fNw\xd2\xe5\xd7\xcb\x9f\x9fuV\xdf_?\\=\xef\x7fx;{\xf0\xd3\xdb\xe3\xde\xcb\xdd\xde\x9f\xff<\xf1\x9e]\x85\x19\xd9\x9f}\xf5\xcb\xfc\xfat/\xfd\xee\xe5\xfbG\xfbo?<\x88/\x9f\x7f\xfb\xe7\xd7\xdf|\xe8=\xffz\xf7\xc5e\xf4\xf5\xf2\xc5\xea\xf5^\xf4>\\\xfb\x0f\xbf\x8e\xc8\xe1\xe0\xfe_\xbeK\x96\xdf\xfd5\x8b.?\xf6\x12\xff\xa4\xff\xd5\xc3\xf4\x9b\xcb\xd7\xfb\xe4\xd9\xa3\xe4\x9b\xab\xbf\xac\xee__/'\xd7\xde\xdb\xfb\xef\xe2\xb7\x9d\x93\xb7\xcb\x8bW\xaf\xfc\x8f\x93\xbf|\x98\xbf;\xe9{\xef\xff\xf6h'\xfa\xea\xbbd\xfe\xdd_\x0f\xbd\xaf\xf6\x8f\xaf\xe8\xb2\x1c\x9e\xbe\xff\xf0\xe6\xe4\xeb\xbd\xa3\xef_\xbe\x1c}F\xd0\x19\xd2\xbd\xb8N\xc97Lj\xae\xd3.\n\xad\xe2\xc4N5\xf2\x18\xaai\xc6=\x8d\x84\xc34-\xaa\xe9\x1c'\x16;\xf0\xcf`\x87\xd0\x81\xd8\x81\xfb\xb0\x0b\xdb\xd2]\xe9\x8d\x0b\xa4\x9bF\xcf\xaeS\x82\xa6a\xf5\xd7f\xb9\xe9 \xb3\x10\xc4Q2\xcb\x17:*\xe6\xfc:\xee\xf3\\\x14!\xb9\x82\xa8\x92\xe4\xa7\xc6N\x03\xc7I\xa0C+\xb1q*f\xc3x{\xe6BF\xe99%\x06=\x97\x05q\x86\xa7\xd0\xc3\x0b\xe2m\xd8\x85!\xad\x120\xfb\xc5\x00\x9e\xc0\x8c\xfe\xd3\x19\xc1\xae\x83\x90\xf5\xc7iw\xb2\xf0\xe2\xa3hJ\x0eS;p\xce\xe0\xc9\x13\xe8?\x84O\x95\"\xe8@\x9f\x17\x0f\xf4\xc5\x03V\xbc\xaf/\xddq($\xc6I\xa7\x83\xe6\xfa\xf0\xf4)\xf4\xf7\xe1\x1e\x0c\xf6\xf6\xd4\xf7\x0f+\xaf\x07{{pO\x0d-5@)\x9bI\xcf\xe6\xc9\x18\x06K\xe7\xf2\xf4)\xecV;Q\x18\xb3~\xab^\xfa\xbdZ\x90\xed\x9a!\xf6\xf4)\x0cZ\x03\xc0\xd1\xa2\xb4WF\xe0Y\x1c-o\x87\xc2B\x97\xc5\x8d\x12\xe0\x8f\xb0\xc3\xc2=\x8e9>\xf782\xc36\xf8,\xc7\x83G\xff\xe9\x8c\xa0\xbf\xbf\xf3p\xc7\x81\x88\xb1\xe13\x8a\xe0\x99\x8b\xd1n\xb1\x04\x9e\x82\x07\x07\xe0\xc1\xb0x\xa7\xb2\xc0\x0c\xd2>\x1c0@\xa7c\xda\x0d\xdd?\xbc\xd1x\x8c\xc0\x19\x9c\xd1\xcd;&\x0c\xae\xf7`\x7f\x87\xbe\xb0F#\xcbq`\xc8\xb1\xc2\xcf\xd7\xcbf\xed\x0cp\x1d\x1e:\xd016\xdc\xef\x89\x96)b\xe4-\xf3\xae\x06RW\x15\xee=\xbf\x93\xfe)\xf2C\xdb\x92\xec\xb4$E\x91d\xc5\xc9 \xea\xf3\x7f)\x84\xa5\xf8\xab\x92\x9f\xdc{?L\x1f\xb2u<\x90\xff\x18\xb2\x90\x88lQ\xac\xc3gG\xcf\x8f_|\xf5\xe7\x97\x7f\xf9\xfa\x9bW\xaf\xdf\xbc\xfd\xeb\xc9\xe9\xbb\xf7\x1f\xbe\xfd\xee\xfb\xbfy\x17\x93)\x99\xcd\x17\xfeO\x97\xc12\x8cV?\xc7I\x9a\xad\xaf\xfe_\xea\xde\xb4\xc9\x91d9\x0c\xb4\xdd/k\xf6\xfe\xc2~q\xa4\x86\xdd\x99\x83\x04\n@\xdd\xa8F\xd7\xeb\xd7\xd3#55\xd3\xfdl\xaa\x1f\x9fH\x00S\xcaJ\x04\n9\x0dd\x82yTW\xcdT\xafQ\xd2R\xa2H]\xdc\x95(R\x07\x0f\x1d\xe4.IQ\xa4\xb4\x07wy\x99\xed\x9b\xf9#\xfa\x03\xfb\x17\xd6\xc2#\"32#\"\x13\xa8\xaay\xd4\xc2\xac\xbb\x00\xcf\xc88=\xdc=\xdc=\xdc\xafo\xbe\xec\xf5\x07\xbb{\xfb\x07\x87G\xc7\xed\x1d\x8b\xa7\xcbat\xa4\xc8g\xe9\xc1\x13HN\xa0\xdd\xf6\x1cqS+\xc3+b\xc18\x93Q\xd9s\xe8#O\xe7\xec\xe0\x9b\xa9z\x9e\x1d\xa4\xf4\x14\xc35\xc0O\xc0\x1e%c\x0e\xa4\x8b8z\x87\xc4\x13\xa3\xba\x15Q}\x99\xc3W\x178\x1bAO\xd0\x0b\x02\x1e\xac\xb2e\x1a\xac\x97\x98\xf0f\xaf\xaaE\xbb\xca\xef\xe7`\"\x95\xd7s\x9b.\xa6v-;\xfcN\"\xb0x\xad#\xbc\x03=\x0eq\xa3\xe4\xf1\xc8\x87\x8c0\xd3\xfeN\x8b%\xd7\xcc\xc3\xdcD\xf1s\xa4\xe0\xa1\x90\x85+.m\x90\xad@H\xff\xb4G\xb0\xeb \xc2\xd8)] Jr(\xf5\xec\x1f\x1c\xf6\xfb\x07G=\x8a\xd7\xf4 \xba\x8c#\xa6St\xdd\x1f\xf0'\x8c|\xb0\xe7\x03*\x9df\x02\xf3\xed\x88y\x18Q\xfc?\x92p>B\xc8\xa0\n9\x90\x00\x07\xbb\xf0\x08\xa2\xea\xad+>}\x99f+\xe4\xdf\x82\xb1\xd5\xb1d\x0c\xea!\x06\x1d\x0c(jY\xe7\xbaG\xbbZyC\x9eM\xd2\x8d\x897\xab\x0b\xbb\xa7\xa0\x02\x0b\xabM\xe7\xfa\x08>\x84\x80\xca\x02\x942\xa8\x12\x05\xdd\x17v\x9f\xce\xab\xe7\xe8K\xf80\x82\x04\xe7L}F\xd9r\xe7P\x85\xa3\x9f\x10\x9cb\xc3}\x18BO-\xb2\xe6E:\xf4\xb9\xa6\xea\x05K`\x04m\xa8\xe6T@\xc4B^\xbff\x14f\x01\x8f\xf8\x18:s6\x08X\xc0\xd3\xa7#\xe8\xcc\xa9\xe4\xd0\xa6;\x18\xe6t\xdb\x9d`\xf9\xc1\xfe\x01|\x88\xe1\xb2E\x03.\x88\xfa\xe6\xd0\x19\xc1\x91\xa3i\x91\"p\xa4\xb6\x14\x95[\x8a\xf3\x96\xb2\xbc\xa5l\xf3\x96(\x91`7 #\x07\xfb\xda\x87N\xf5\x06\xaa\xe1~3}5\xc2W\x8b\xcc3\x19\x9c\xc2+\xef\x15\x9da\xd8\x81\x1e\x15\xbc\x16\xf9\x9ck\xf44\xc8\xf0>\xf5\xd2Ew\x1d\xbd\xb3\x07\xec\xee[D;Z\xbe\xc8\xaa7\x17KU\xe3\xa8?,U\x15Q$\x94\xf6\x0ce\xe8\xef\xe2 \xad^\x93\xa9\xcdiBq\x9b\"6\x0b\x19\xcf\xd1\x9b\xd6\x1c\xe8\x91w\x9e\xa3\xb7o@o\xf4\xb00\xa07\xc5\xd1\xc1n\xce\xbc\xe5\xd1t\x06{\xb4\xc2\x12\xe8\xf0\xd0\xd1\xe3:\xc5\xe5\x98\x93\xd5H\xdf\x8d\x19/B\xa7\xaf\xa3y~\x85\x12\xd4\x13\xe8\xc1\xed-\xbf#\x8b\x8e\x1b,K\xc4\x13\x14\x8cq\xa7i0\x97\xce0v\xd4\xbbH\xd0-)H^y\xafl\x82>\xf2\xcc\x90\xca\xd0\xe3\x14lJ2\xf2\xc7\xbcJF\xbc\xe7tp\xb8\x0b\xb0\xae\xf92\x8ab\x1b\xbf.\xa3KZz\x87=\xf8\xe4\xd5\xc0q\x81P\\K\xa0\x8cM\x9d\xccq\xe0 \xf4\x91\xf3d\x9d\x0ee\xcb\x1f\x8e\x80\x96\xa7\x07\x82\x11\xee\x94%<\xa5\xfd9\x855\xec@\x02CXW\x10\x89n\x89\xa5CQ,\xa1E\x07\xac\xb6v\x9b\xd6\xb6\xc3j\xcb\xeb\x99\x8b1\xc9\x83(\xb5\x82Om\x82\xb5u\x18\xe6\xca\x8d\x05\xac\xb6\x11,q\xf8\xc8\xbd*E\x96\xe6\xf7F\xd0s\x9c\x13\x08hcG'(\x9f\xb5aQ\x88\xbd\x1e\xa5T\xed\x11\xcc(\xad\xdeAzA\x85\xa7:\x12\x94Qd\x0e\xe0\x96\xbe\xeb\xd3w\x83\x13\xf0\x19\xc5Q\xaa\xcf\x8a\xea\xb3\xbcz_W=\x7f\x15:0\x9b\xc2\xed\x08\xfa\x03\xba\xb1\xae*\x1c\xae\xe1P,+p\xca\xdb6\xf7\xea\x0c\xed\xdd\xc1Q\xe5\xc8[x\x85\x96\x1dk7i\xb2\xb8\x921\xd08\xdb\xc6\xdd\x9f<{\xfd\n\x1d2\xf9W\x9d\x87M\x9e\xe6fXI{S&yMW8\xccwS\xf2\n\xf9\x85\xdd@{[w\xa3\xf1\x9a\xf4\x0e\x92g\xed\xa8\x14\x0d]LPd\x87\xf6\xee\xae\xe2w\x1c\xf0GG{\x8e\xd6\xa57\xfa\xf1\xba\xf4n\xe3\xdd\xde\xa8KU\xd3(H\xf9\x185q\xbbh\xf9\x8a\xe3.\xf3\x11\xa7\xef9\x1b7\x0b\x924^g\xa5\x8eq\xa5j\x94\xcaxM\xd8\xfc\x9c\x12\x03\x161\xc1\xe0\xc3\x11\xdf\xd4(\x8a\x8bP3\xeclT\xf5\x83vN\xa0\x85>\xfaH\xf2\x92Rv\x00f\xee\x0fy\xbc\x0b\x9e\x94\xc0\x85\x16z\xce\n\xa7!\x96\x1f\xc19\xe1\xe34\x18\x85\xde\x83\xef\xb1\x84 u\xda\xf0\x88M\x15\xcb\\n\xa8g\x1e\x84\xderY7\xe4\xfa \xa1\x9f\x16\xfa\x13%]\xbe\xd4\xd2w\x83\xd3\x18l\xd84\x08\xf9L\x9c\xfb2su\xfa\xf1i\xa1\xda[\xf7X\x9ca\xa7:\xe7\xc5\xa9\xf3\xcd\xcd\x9aTN\x9e<\x80\x12\x0bV\xc5\xeeYf1\x8b\xe1\x11\xa4$\xf6.\x96E\xc0\x7f\xe5\xc2V\xd14{\xf2 \xbcb\xb7\x1a\xdb\xfa>\xbc\"\xb4\x8f\xf6\x1d\x17B\xfb\xf8\x00=\xa5\x8b\x0e\xd0\x96\x06\x1bu\xbb\xe07\xfd]\x1d\xc7 \xed\x03\xc7\xb6p\xb6\xd2(\xaez\xea\xb0\xeb\x80\xbb\xa6x\xe1\x94\x89u\x83\xe4\xa5\x98\xebM4\xc89\x85\xd2\x9eUyD\x15\xdc\x8a\xe3\x80\xa5t\xf8\xeew\xf3\xee\xe1\x9d[L\xb7U\x8d\xc9\x12\x97|k7\x9a\xde\x0dWt\xefAWtww_Y\xcb\x81\xd3\xe5w{\xbc$ .\xc3Mj\x92\xd7U\x9a\xca\xd8\x8e\xbbg\xd0\x86\xb8\xfb\xb1\x0b\x16\xabU1\"\xb2V\xd8\xe8\x0e\xa4I\xdb\x08\xa1\x9an\x9a\xeeU\xaf\x94\xf2\xa8\xef\xbd\xaa\x14\xc5p\xeb\xa0:\xbd,F\xfd~5v\xbc\xc7j\x19T\x8b'9J\xf1\xc9\xd3cj\x0b\xbd\x07C{p\xec\xd8F>-\\\xf1\xbe\xd2\xc4e \x068e\x9a,\x91\x88\xceQ\x0d}\xc8t\x9a?K\x8b\xfd<\x80\xce!e\xe9\xc9z\x19\xa4\xb6e9\x1a\xc7-\x1d\xeb!\xe3t\xaap\x9b\xf7\x8e\x0b\x87\xd0\x1aA\xc2\x82\xd5:<\xcf\x91\x9c\x1e\x91=\"\x8e\x93\xab\x89\xe8\x0b\x92%\x86\x1e\xabj\x85\x88R \xe6\x0cm/t\xces\x911We\xd3\xf3o\x9f\xd9F\x82\xee\x9cYC\xa2\xee\xfc\x84\x9e\x8b\xc0\xd7\xe4\x15\xcak^\xbbx&\xf5\xec\xbc\xd2\xb1\xdfnO\x1d\x17\xcf\xa1\xf4\xd0\x14\xdb\x0b\xa7\xebG\xa1\xef\xa5\xf6\xdc^\xa0\x02\x9a\xc2\\<\x89\xce\xf2>\xdc0\x0b\xcc\x15<\x85\x9b\x13\x07\x96\xec\x9e\xd3\xc2\xc5\xb3\xf3l|Cke\xe2\xc2xM't1^\x1b\xf4j\xd2MK\x18B\xb2\xc9\xe6\xd9\x90\xe4<\xe4\x81\x83\xd6w\\Cr(\x0elRO\xb1\xc3\x95\xbd\x19\x88\x8d\x7f\"\xb5\xda\xdf;vl\x8b\xd6n\xb9[\x88\xc65f\xb8\xc0\x8e\xa9`[Fp M7\x19E=\xf5\xda\xf9\xdc\xfe\x89A\xefv\x928\x1f\xda_xW^\xe2\xc7\xc1:\xbd\x9dy\xa9\xe7\xec\x04+u\xd4;\xe3\xcf'\xd7\x83^gr}\xf8b\xbasY-\x12\xb1:\xc7\x9f\x0f\xa7mg\xb8s\xb9RI\xdd\xd8\xeaZ.X;\xb2\xef\xb9\x19K\x12/\x0c\xd2\xe0K\xf2\x83x\xd9t\xf3@\xd8\x92\x98R5\x15\xd7~\xe8Y\xce\xd2y\xb4n\xb4\x12 k\x95\x85\xde>\x1d\xf7\xa6\x0e<\x85\x8e&'\x95\xed9\xdc\xd6\x84\x8a{\xaf\xbb\xa2\xd2\xb3\x1d9\x8e\xb0-1\x0bm\xdcMI\x922\x15\x8e\xe5]DY:\xbcXz\xe1[\x0b\x86\xe0a\xc4<\x19hB\x81M0\xa0\xc0\xe3\xdd=\xbd@\xb4\xbb\xbf\xeblc\x1e\xc6`\xf8\xdd4\xfa$zG\xe2\xe7^Bl\x0c\xd1\xda\xa6C\xa6t \x03\x96W\xe3\x9e\x1a$\xaa`\xbb!\xec\xe9\xc3:\xf4\x0f\xef\x1e\x98\x027Yy4[\xcaUE\xf7\x0e\xaa h\xf8\x04\xefU\xb98\x93\x05\xaad\x8f\x89\x02\x87U\x81\xc2\x03\xae\xfeS%\x81\x98N\xb8\x14\x93e\xc8\x05\xcarIf 8\x85\xa4+\xf2\x87\xe5\x05\xebg\x0d\xb3\x12V\xe6\x0d\x03k\xf2\xa4\x8e\xfal\x80\xaa\xc2<\x92\x93\x1b\x06<\xdfX\x1b,K-\x9a\xc9E}8\x05_\xa4\xfb\xa3\x9b\xa2\xf2\x82\xe0\xc1DS\x19\xaf\xc2\xeaa/\xc3B\x15;\x1aA\xc7\xa3\xdb\xae\xd3\xa3\xbb\xad)~\x80\x89\x9dm.!t\xfa\xdc7\x83\x07\xc1K\xb9\xa2\xb9l\xf2f\n\x90\xd89\x81v;\x84'\x10\x9f8\x10\xf0\x00\x83<\xbcv\xa8\xe6\xc6\x16s\xfa\xa0\x18\xcb9\xa5!~.Z\xed*\xc7\x11\x15\x8f\x83\x1c\xd7TdfX+\xe5\xb2\xdb\x10\x1d\xcd\x87\xac\x88\xdf\xde\xc6\xf0\xa4\xa5\x12 \xae\x86(qW\xf5\xda\x86\x94G$5\xe8m\xc4\xccUB\xd8\x95\xb4$\xef\x95.\x06h\xdbf]\xd4/`\xcc\x9d\x06NE\x07B\x18\xc2\x8c,IJ\x10R\x8ap\xd8\x8c\xa8\x02\xf5\xaa+\x99O\xfa\xb6\x13-D@1\x88\xbb\xe2\xdb\xee^\x95\xe8 \n\xaeO\x92\xb5\xbb\xaf\xcb\x92\x85\x8c\xe0\x8eC\xc8\x0bhu\x83\x04%zSx\x01:\xa5\x01c\xda\x11\xa3H:r+>\xcc]\xe5\x149>\xe5\x88hZF\xb3\xb2\xbe|\xc2\xcb\xc7v\xe8B_:\x9e\xd0w\x93e\xe0\x13\xbb&\x91\xb27N\xa76\xa5\xaaI\x193\xef\xbeR&-H\x93\xa8 0^\xefe!0)\xdfd\xdc\xd7\xe1\x14\x02J\x8dQK\xf9\xe8\x11\x84\xf0\x94\xd9\xf4R<\xd7\x88\xa6\xb6\xd8\x03\xdbv9f\xa4Z\x99_\xf3P\x98YOx\xfbt\x08<\xc5\x1eS\xda\x1e@\x1b\xbd6P\n\x0c\xf9\x03\x1c\xa0\x93\xbf\x84a\xfc\x02\x87\x91\x7f\xfar\xc8_\x0e\xa1\x83\xceXO\xa1\xe7\xb2/#\xad\xd9\xf0\x8aG\xbc`\xac#@\xd6\x11\xc3\x13\x08N\x1c\x88Xh\xb1t\x1c\xd3\x9e\xe8\xfd\x11\xa3;\xe3\xc6~u\xb76\xed\xe2A#.\x19\xe5\xb3\x94m\xb7\x94\x1dp\x1bIO3\n\x18ZJ\x0b\x15\xc4\x16M\x08\xb2`\x8d'\x93lv\xd4\xebu\xe8\xdf\xf9|>\xad\xb8\xa3\xc7\xa2Po\x97\x15\xea\xed\x1e\xcc'\x93lN\x06\xf8sN\x06\xf4\xe7\xa07\xc3\x9f\x83\x9eZ\x05\x9dd\x0b\x9b\xd9\xf5\xc7\xac\x99\x0bSs\xe8\xd85\xfe\xbc\xa1S\xe8\xc3e\x9f\x0e\xe5Jg\xe4\x00\x8b\xcf\xe6\xf3\xa9\xf3\xd5\xe0\xbd\xa52\xf0\xf2`/\xe6\xf3)\x02|sC o(\xcfk~\x9b\xe7Fw,\x16\x89A\x95Y\xb1\x999\xe9\x11\xf6g>=\x15i\xefm\xde\xe9A\xaf7\xe3\xb5\x8e\xb9G\xcd\x94\xd3\xcd[\x0bEL\xc7X\x87\xe5|XU\xff\xce\xa5^\x8e#\xd1\xd5S+\x0f\xed\xe6BX\xad\xbf\xd2\xef%\x8cx\xb6X\x1bGg\x9f\x8e\x8a\x91\xe2\xa0\xe7\xd0\x06\xdf\x05\xeb\xd2\xba\xeb\x9eH\xf9\xa9r\xe9\xb0+\xc2w\xdf\xc6\xd5s\x898\x10V\xa3\x01\x8am\xac;\xb1\xf0\xd1Z\xe3\xc7\xff\xe5\xe7~mj\xddkd\xf5\xccY\xc8JvdS.\x9c\x1f\xf13<\xe2;\x18\xb7\xc72\xdb=\x1a\xf7rC\x02U\x13\x9f\xd31\x8d\xa8F\xde\xd7Pr\x14\xff\xa2\xdc\xdf/\x1d\xb7\xdb\xc1\x14\xe9y\x00O :q\xd81\x87\n\x06\xe98\x98\xa2\xeb\x8dA\x92l:\xcf\xd4`\x83A\xcfU=s\xa3\x96g<\xb9\xf6{\x9d\xc9\xf5\xec`r=;\xeaL\xae\xe7\x07\x93\xeb9~\x99O\xb2^\x9f\x92\x82\xac\xd7?\x9cOw.kpf[zx\x1f\xe4\xb2S\x14\xdfR\xc7a\x96q\x81>\x11]\xdb\n2\xdd}\x12\x0f\x9dJ\x90\x03\xebG?g\x0d\xc1zV!\x14\xd6\x8f\xfe\x96\x1e\xfc\xb7\xf5\xe0\xbf\xa3\x07\xff\x8fz\xf0\xcf\xeb\xc1\xbfI\xc1\x9e\x02\xfe-=\xf8\xdf\xe8\xc1\xffV\x0f\xfewz\xf0\xbf\xd7\x83\xff\x1e\x05?W\xc0\xbfC\xc1\xbe\x02\xfe'\x14\\M\x91j\xfd\xe8\x0f)x\xa6\x80\x7f\x81\x82\xab D\xad\x1f\xfd}=\xf8\x17\xf5\xe0_\xd2\x83\xff\x17\n&\n\xf8\x7f\xd5\x83\x7fW\x0f\xfe==\xf8\x1fP\xf0K\x05\xfc\x0f\xf5\xe0\x7f\xa4\x07\xffc=\xf8\xf7)8P\xc0\xffA\x0f\xfe\x03=\xf8?\xea\xc1\xbfL\xc1\xaf\x14\xf0\x1fQp\xf5\n\xab\xf5\xa3\xff\x89\x82_+\xe0\xffY\x0f\xfe\xa7z\xf0?\xd3\x83\x7fE\x0f\xfeU=\xf8?Qp\xa4\x80\xff\xb3\x1e\xfc\xbf\xe9\xc1\xff\xbb\x1e\xfc\x7f\xe8\xc1\x7f\xac\x07\xff\x1a\x05\xff@\x01\xff\x0b=\xf8_\xea\xc1\xffJ\x0f\xfe\xbf(8S\xc0\xff\xb7\x1e\xfc'z\xf0\x9f\xea\xc1\xff\x9a\x82\xab d\xad\x1f\xfd\x19\x05\xdf(\xe0\xbf\xd0\x83\xff.\x05?S\xb7\xc3oS\xb8\xa7\xc2\x7f\x9d\xc2\xdf,\x14\xf8\x9fSx\xaa\xc2\x7f\x83\xc2\x93jH#\xebk=Y\xfeZO\x7f\xbf\xd6\x13\xda\xaf\x91\x88+\xe4\xed\xeb\xbf\xa3\x07\xff\xbc\x1e\x8c3\xa0\x10\xc3\xaf\x7fA\x0f\xfeE=\xf8\x1f\xe8\xc1Hh\x15\x8a\xfa\xf5\xdf\xd7\x83\x7fI\x0f\xfe\x87z0\x92 \x85,\x7f\xad\xa7\xd6_#eR\xa8\xf5\xd7\xbf\xac\x07#\x99P\xe8\xef\xd7\xffT\x0f\xfe\x15=\xf8W\xf5\xe0\x7f\xa1\x07# R\xf0\xed\xeb\x7f\xa6\x07\xffs=\xf8\xd7\xf4\xe0\x7f\xa9\x07\xe3\x9e\xfd\xab\n\xf8\xd7\xf5\xe0\xdf\xd4\x83\xff\x8d\x1e\x8c\x9b\xf3R\x01\xff\x86\x1e\xfc[z\xf0\xbf\xd5\x83\x91\xd9\xff5\x05\xfc\xdbz0\xca\x00\xca\xc6\xfc\xfaw\xf4`d\xb1\n\x07\xfb\xfaw\xf5\xe0\xdf\xd7\x83\xff@\x0f\xfeC=\x18\xd9\xb7\xc2\xd8\xbe\xfe==X\xcf4\xbf\xd6s\xc7\xaf\xffH\x0fFv\xf2\x93\n\x18\xd9\xc9\x17\n\x18\xd9\xc9_W\xc0\xff'\x05\xbfU\xc0\x7f\xac\x07#'\xf8D\x01\xff\x89\x1e\xfcgz\xf0_h\xc1\xdf\xfc-}i\xe42\xd5\x981\xd6\xd7\x7f\xaa\x07\xff\xb9\x16\xfc\xcd\xcf\xe9\xc1\x7f[\x0fF\xd2\xabH#\xdf\xfc\xbc\x1e\xfc\xf7\xf4\xe0_\xd4\x83\x91 (\"\xcd7\x7fW\x0f\xfe\x05=\xf8\x97\xf4`\xa4\xdf\x8a\x90\xf2\xcd?\xd2\x83\xff\x89\x1e\x8c\x84Z\x91/\xbe\xf9\xc7z\xf0/\xeb\xc1Hc?S\xc0\xbf\xa2\x07\xff\xaa\x1e\x8cT\xb3\x1a\x93\xc1\xfa\xe6\x9f\xeb\xc1\xbf\xa6\x07#\xa1>S\xc0\xffJ\x0f\xfeu=\xf87\xf5`\xa4\xc8\x8aT\xf0\xcd\xbf\xd6\x83\x7fC\x0f\xfe-=\x18)\xf2\x1b\x05\xfc\xef\xf4\xe0\xdf\xd6\x83\x91\xf4VC\xe4X\xdf\xfc{=\xf8w\xf4`$\xa6\x8aP\xf8\xcd\xef\xea\xc1\xbf\xaf\x07\xff\x81\x1e\xfc\x87z\xf0\x7f\xd2\x83\x91\xc6*\"\xe47\xbf\xa7\x07\xff\x07=\xf8?\xea\xc1\x7f\xa4\x07\xffg=\x18I\xef\x0f\x150\x92\xdew\n\x18I\xaf\"\xe3~\x83\xa4W\x11f\xbf\xf9c}i$\xbd?\xa3\x80\xffD\x0f\xfe3=\x18\x89\xe9\x97\n\xf8O\xf5\xe0?\xd7\x82\xbf\xc6\xd5y\xa92\x1e\x9c\xab@\xe1<\xdf\xb0\xe3\x9a\"\xb9|\x83\xc2R\xa4\xc2Q\xb0|\xac\x927\xe4\x1bI\xe1\xcab\xf2\x08a\x8ex\xdb\xab\xe9\xee\xa3Q\x945u\xdc(5\x84tL\xa6\xa5\x17\x9aT\x895J!\x83_\xc8\x81>\x1d\x89\xa2q\xcbx\xf1~\xa3\xeaKo\xde\x12zc\xbcK\x92\xf2\xe4\xdd\xdc\xf2\xc6\x9c\x92\xe4\x81\xa3}\x93\xdb]\xb2\xc2\xee\x82\x1aL\xa6x&\x9b)\x9euv\x12\xf4 \xeb\xf5:\x93\xeb\xc1|r\xbd\xebu&\xd7{\xbd\xc9\xf5\xfeEgr}\xd0\x9b\\\x1f\xd2/\x87\xf3i{\xe7\xae6j\xd1\xc9\xf0>\x9d\xf4:_N\xc7\xcf:?3\xbd\xc5\xff\xbf\x1a\xb8\xef\x11v;\xeeu\x8e\xa7\xf4+{\xc8\xbf \xf4v\xfc9\xfb\xd9\xeb\x1c\xc3t\xe7\x8e\xdd\x0f\x99g\xd8Vv\xae\xdc\x085\x99\\{\xfedr}\xd1\x9fL\xaeg\x87\x93\xc9\xf5\x9c\xfe\x87\nV:\xe1l\xc6q\xca\xd9\x9c\xe3\xa4\xb3Y\x9f\\_0\x85k\x8f+\\\x0f\xe60\x99\xa4\xf4\xf5\x8b\xc9\x84\xbe\xeb\xf5P/;\x9fO&\xe1d\x12c\xa1\xc1\x11\xfbs<\x99d\xfd\x83#Z\xa2\x7f\x84\xd6\x16Z\x11\xfb\xd3g\x7f\x06\xec\xcf.\xfb\xb3\xc7\xfe\xec\xb3?\x07\xec\xcf!\xfb\xc3\xea\xec\x1d\xb3?\x1ek\x81un\x9f\xfe\xd9\xed\xf5\xaaq\xae\x98y\xcd\x826\x0b\xecm0\x9d\xcd\xda\x96\xba\xe1P\x0b=8\xe4\xc3>\xbc\xd0[\xc9\xe8R\xd3I\x9d\xd3\x99\x9a\x1fL\x98\xb6{r\xad\xda\xba<\xad\xe9Mt\x0d-A\x95\x06\x8dU?\xeb\xfc\xcc\x84)\xdaQ\xd3\xceT\xed\x93\xeb\x191\xd9\xd7\xb60\xe4\xf9w2\xe4\xa1\x89l\xbcq\xbf\x96\x92E-\xcb\xed~\x9e\xcer\xb6\x96\x8a\xce\xeb\x8b.x\xd1-\xcd\x07\xb7&\xdb\xa9S\xb5>\xce\x8c\xd6\xc7\x85\xc1\xfa\xa8\xb5\xb5\xe2\x1d\xe8\x8d\x0c\x92\x0b\xbdA\xf2\xaad\x90\xd4\xd7G\x9f\xcd\xca\xaf\xdd\x14&\x96\xf1<\x8fs\x8f\xf3\xdf\xa6\xd3\x86\x96:\xfbt8\xbb].oW\xb71\xb9Mn\xd3\xdb+\xe28\xa7\xdc^9\x8e]\x98\xbb`}`\xa9\xf6NX+\x15}t\xfb\xc9'\xb7\x9f\xde~\xf6\xe2\xf6\xec\xf6\xcd\xedO\xbd\xa8T\x04mX\x9a*+\xfa\xb7\xdc\xa4\x7f\xe2\x8d\xa6\xe6-\x17\xf7\xfb\x87\xf6\xe9\xb0\x7f\xf6\xe6v\xf0\xea\xa3\xdb\xdd\xcf>\xba\xb5O[\xe3\xfe`w\xeaL&\xb37\x7f\xcd\xb1OG\x93\xc9\x05\x92\xf1\xf3\xa9#\xbf\x93\xa4\xb7\x83pv\xbb\x1b\xcfJ\xef\xa4\x8b\xfc\x9dg\x9d\x9fa\xef\x04.\\I\x03\xbb\x97\x8dJ0\xaf\x9b\xcd\x98\x97Y\xe48\xa8\xe6\xf4a\"\xc7a\xd5\x05\x98'@\xeb7:\xd0V;\xcc\x82l\x06_\x12vw\x9b\xe7\xc6\x9cy\xa9w\xae\xcf\x7f\xba\xf0\x92\xc5\x10o\xb6\xc5\xae\xf2p\xe5\xad\xf1\x99\x1d\xd1q\x07\x1a\x0f)\x91f\x0b+(=\xbd\xbb\\\xa6\\\xc6\x11rYU^\xe3\xf6o\xc55\x97\x0bf\x8a\xdb\x8b\xc7\xe1\x03\xed\x9d\xdd\xc4\xec\xc8\xa8\xb3%\x87\xdb\xd9\x92Y\xd6\xcc%\xf1b\x1b-\xc8\x04\x03\xb9\xe8\xa4_1\x13T\xd2U\xfd\xcaD\x18\x7f;f\x1e\xeb\xe3\xfe\xb4\xde\xb4N?\x89\x9c\x0b\x92\xf6\x81e\xed\x92\xc1\xdc\xab\x11\x13x\xca\xf0K\x82\xf2i\x19\xb8\xf0(\x12fe`\x82%\xbd\xf2\x1d\x8f-/u\x1c6\xca\xd2Z\x84\x970\xb5\x9d\xf1d\xfa\xd5\xfb\xdb\xe9\xce%\xd2\xf1\x0f\x1eYR\xb1r3\xb7\xf9}\x07\xa7\xfb\xe1)R\xf4\x89\xed\xdc\xe2\x06\xea\xb69`\xea`M\x1f\xf4\xbb\x1f\x9e2~\xf5\xc1\x9d\xe9z\xcbn\xa1\x0b\x1b%n\xc2\x03\x01o\x1e`\x18\x8d!x\x0e\x13\xfb\xb3\xd2\x8d\x9f\xcdQ'\xcf\xe5\xa6$\xbe\xccs\xb9\xed\x8c?\xefN\xdb\x1f\xect\xc95\xf1m\x8cR\x16\xe0m\xa8\xe2[\xf7\xe5\x8b\xf3\xef\x7f\xf6\xfa\xcdk\xbc\x87j\xe1\xa5\x15\x8b\xdf\xf6Kb\xdf9\xefw\x99\x03W\xd9\x15\x7f\xbb\x99hE\xcc\xd9%\x08\xb7M\xfa)\xed^gl\x9d\x9f\xfbQL:_$\xe7\xc9\xc2\x8b\xc9\xec\xfc\xdct\xa7\xe8\xae*\x05\x8dc\xff\xc6\n\x83\xe6C\xdbf\xb3&\x18\x03\xd2\x96\x85\x87\xac\xe3\xd1\xa3\xdc5\\\xa6I\xe3T\xef\xe6Y\x90\xa5\x0e\x0b\x1e\xc6c\xc6\x90;\xcf\xbe\xce\xfb\xd3:?_F3/Y\x9cSF\x7f\x9e\xc7\x94;?\xd7\x1c\xb9\x14\xbf\xf4\xf2\xf6\xdc\x16\xb5J\x93$\xa6\xa3<\x17\xc1\x1cl\xc5\x83\x0b\xa4\xb33Q\xa6\x0fJ\xde\xca<\xc4P\xbe\xdau\x99\xf4\x85\x7f-\xbf\xba\x82\xd7]N\xd9\x8dU\xe12\xfe\xa0s\xff\xe3\x9f\xce\xfc\xda\xc2i\xf9\n;\x8e0\x90\xc6\xfd\xa0\xe3\xac\xc1\xb1\xa61j\xf6\xb2X\xf9\xe6a\x16;\xa8]\xde\x89L\x18\xeb\xbb\x10\xb2\xdb\xc8\xe8\xc7')\xd7\x08\xf7\xfa&L8\xb8/uh\x12I\xc6\xd3\x07\x12B\xb42\x08\x0b\xd5\"\x89a\xebe\xe0\x93\xa6\x89\xdf\x08\xb9\xf4Bo\xccPH\xbb$-;\x14\xc1\xb6l\xba;\x8b\x04i\x1d\x8c\x1aE\xba\xebh\x8d\xa9\xda\x0bl\xc4k\x15.t:\xf9\x1c\xb9\xd0\xbb\x13\xbb\x15\x93\xf4\x974\xf8\x90\xc7\x13+T\xb6\xe3p:\xee7q\x9f\x87\x1cI\xee\x8b[\x1e\n\xa5t\xa5\x9b\xb1\x0f\xdf\x93Mw\xb2:\xad\x18q\xca\xae\xb9E\xc7\xa7\xd5n\xb7%\x0c\xe1at\xc6\xb4\xe1)^\xb3\x0f\xc7\x01\x9dm\x96\xe0~\x83}m\x1e\xed~\xe3hM\x18\x14\x8bT\xa5\x0e?P\x99n\x96\xdd\x95\xfb7\x12#3r\xb3\x1b\xa1\xa9\xb6;\xf2\xd5Q\x8clb\xb1\xac\xdb\x12\x80e\xcd\x96\x00\x17Q\xb4$^\xc8!\xa7\x94\x0d\xf0T\xae\x16\xb2\x9d\x94\xae \x93\xc8F\xf7\x90)\xb7_\x8c\xd2&\xc0\xb5\xb8$\x1b\xa8\xee\xbf\xdd.0\xd6\xf4-v\xa1f\x03\x16\xdd\xd0\xef\xbe\x101QO\xd3P\xd7\x80\x95\xbbe\x86\x1brv6\xcaoW\xf5\xef\xb7\xedv\x8f\xf6\x1c;\xb4\xf7v\x0f\x9c\xad\x8c\x90\xe63{_\x7f\x1f\xeaPw\x18\x0b\xed\xc3\x83\xc696,s^\x80q\xb3\xcc$\xd0zE\xe0!\xdd]F*\x0c\xb7\x02\xbci\xad\xbe/\xeaH\x04\xb5\xdc\xd5\xd4\x00\xfc\xaed\x84\xe1*\xc3\xda\xbe\xcb\x1f>\x8e\xc4\xf6\xc6\xe9\x14/lx\x86l\x17\nT\x85\xd0^\xfa\x94\xe0\xe4\xd3a\x14\xe0}\xe4Jp\n\xde8AQ\xdc\xa7\x82\xaa\xaf\x91\xc7\x01\xee\xa3Q<2\xdc\xa1P\xe2\xf8p\xbd\xeb\xd1\xde\xd6\xa8 \xc8l`\xa2\xf8\xfd\x928\xf4\xe8\x11\xa6*\x18\x0f\xa6\xec\xd6*\xfd\xde\x9b\xba\x0c\xd8\x9fR~\x96\xb7\xa5\x18\x8e\xa1z\x04J)Af<\xd4Ub<\xdcu\xd6\xfa\x87\xd5\xfbF\xe2:\xa1N\xe5\xd5W\xd5]\x83\xa69\x14wx<\xddd&H\x98\xf8]|e\xf8\x18\xba+`i3b=\xe5\xa3\x0d{\x0e\x96\xbc\xc1(M\x0b\x17f.\xac\xd9\xaep\xe1\xca@1\x91\xee\xca]\xbeAO\x8b\x99\x0b\x0b\x17\"\xb8\xe5w\x0c\xaf\xe8\xa6\xbc\xa9\x1fA\xcd\n\x8a\xb7\xee~\xfak\xbc\xad[]\x91\xeaA\x94Yy\xb6:\x8b\xdeC\xdel>L\x91\x8d\x85dZ\x96\xcb\xfd\x0f\xdea\xb91\xd1\xdf\xcd$\xc6\x07j\xeb\x9e\xa2\xa1>|P\xbf\xaf\xf7b\xea\xf7\xaaV4$\xd5\xbd\xc6 \x1f\x9b\x1e\xf04\xc4\x17D\xf4\xcbh\xae\xde\xd7\x04I8\n\x0d\xb5@.\x1dQF\xe7 &\xfa\x042\x16C\x9aO\xabW:\x13\x96\x11\xbd\xdd\x0e9\x06Q\xa8Z\xbd2\x0e\x10)z<\x13?\x85F1YH\xc9\xf7\x13\x8c\xcd\x8cX/\xc8\xee\x1e\xeb=\xd5\xf6zz\x83\xe8^\xbf\x8a\x12\xc8{\x95@H>\x17\x8e\xaa\x885\xe7\xf0*\".U\xb1\x00\xbdI\x84\xad\xeb\x99\x08\xa2WuOY\x94K\xc5\xdeM\xb5\xc4L.\xc18v\xb5\xc8\xd5\xfd5\xb0B>\xb9q\xe1\xd2\x85\x95\x0e\xfd)\x9a$\xdalT\x17\xf8\x84h\x9e\xbc\x83\x11\x9c\xc3),`\x08\x9e\xf6\xddk\x18\xc1E^BW\xc7\x19e\xf4\xb4\xa2wT\xacY\xc3)\xcc`\x08\xef\x1c\xfak\xa6\x16\x7fA\x8b\xd3Z\xaf\xe5\xe2\xd7\xa6\xe2\xcfD\xc5\xd7\xean~F\xf9\xb9\x8f\xd62u#\xe3&\xf5\xe5`Q\xad\xbe\xba\xd7\xcey\\\xe23\x0c\xd5\\\xb3\xbb\xf2\xf6Zgy\x85+T.\xae\x04;s\\8\xa7\x909S\xfc\x06\x9aU\x1bB\xc4\xa1\xefJ\x0f\xd4\xb1\xb5\xec\x10\x1ea\x90|=\x8dz\x0d#8Cer\x1e\xd9\xc8:?g\x89\x0eg\xe7\xe7\xa6\x0c\xd3_\xc0\x08^H\xaf\x91\xeakzj\x87\xf6\xbe/\xea\x0e\x83o)\x8e\xc3)\xa4,\x984*Vk2H\xbe\x84\x11|\x81Z\xd8\xa28\xd1\xcbD\xc6\xc9\xbe\xb4\xdf\xba\xf0R\xcc\xe3J=&n\"\x03\xb5pQm\xb5\xf6L]\xbe;3F\x95\xd3qc\xec\xb1\xfe\xd4\xb7{\xbc\xaf\xf5\x0b\xc9\xbe}\xbf\x90\xaa\x8c&;\x88`\x01o6\xb3\xd31\x99V'\x83~2\x89\xbey\xb3\x19\x06\xb5* \x94#2\xaf\x8eLq\xe0\x88\xca\xbe\x1a\x99v~\xab\x93\x1b\xde\xcf\xe2\xb3\x91D\xc4\x99i\xe8l\xc48\x7f\x9cbXs[f\xf3t\x8aM\x90\xa6&\x8c\x08m\x8acx\xac\x8fi\xac\xb8\x9ad\x06\xa9\x81\xbbE\x1d\xeb\xa5\x80\xbd^\x95\xdf\xfb*_\xa7\"\xc0@\xe5\xfe9\x8b\xfe\x1e\xd3\x15WytI\x1c\xf8\xc8K\x15G\xd5\x92$\x80a\xd7k%\x81O\xbd\xb5N\x0c\xc8\x9f\xbfB\xa5v\xb5\xc8\x8d\\\x849\xb6T\x8b\\\xcaE\xce\x88\"l\xacJ\xcfQ\x97^-r^*\x82\xca\xf4j\x91\x0bE\xee\xf9^6\x9f\xab\x1d~W\x996\xef\xa7\x02\xf2\xaeZ\xe8z\xe3@\x94g(\x17\x9c\xc25c\x0b\xaf\xe7\x1b\x07\xfe\x13\xb4:v\xe1\xda\x85\x17.<\xab\xa2~\xf2.\xc0\x08|Z\x1d\x96\xef%\x04\xde\x0d\x158p\x06\x98\xcayA[\xa3r\x9e\xd0\xdb[`\xcf_\xcf\xe7 I\x8b\xe7\xecw\xad\x00B?)\x06\x10\xbb\xc0 vy\xf4T\xf6K-\x8f\x1d\xbd\xd0w4\xb7|6\xf5\xb6\xf5\xc2\xa6\xc4=\xc0\xab\x1e\xec\x1bqtY\xbf\xb1\xb5\xa5\xda\x1a\xc2\xd7\x06\xf8Um\xef\"\xbb\x9d\xba\xd0\xd6i\x9d\xf1\xedE\xed\xdbi7\xf4V\x84\xe9/\xf1\x1b\x06jY\x91$\xf1.9\x98\xff0T\x7fc\xe8\xf4\xaa\xbeYfYR\x83\x88\xe6\xef\xcf\xf4\xef\x0bQ\xcd3\xbcvi~\xed\x0b\xe6.P\xcd\x1d&>\xb9Xf\xd3\xfa\x13\x0ch\x8d'\xbd\x96\xd0P\xa0\xb4\xfaE#\xf6 \xe9\xed\x19\xd74\x98\x9b{\x9b\xd7\xf5\x16\xe7\xc3 \xaf\xc1\xed\x08\xe6.<+\x0e\xa2\xe6\x86_b8\xc5\xd7\x88\x88\xaf\xd1T m\xe0Zy\xf0Y\xa1\xb1q\xe1\xa5az\xcf\xcd;\xba\x10\xe3\xcfD\xccJ:\xa83\x11M\xb6\xf4\xa2^v\xbc\xbb\x11\xdb\xe9\x16 3\xf5\x94\xed\xae.i\xdb\xca\x87<\xad\x0e\"\x8cA\xf5\xa5\x89\xb7\xaf v\x85\x15\x8e\xdbm2\x85\x11:\xf5\xa7\x95\xcbq\xce\xb7\xa11\xfbv\x86W;65\xa1@\xd3\xb0\x8cx\xb0\xd7\xd3i\xcc\xfa\xaa\x08\xf5@\xda\x03\x9ewO7\x89\xa8Q\x81G\x10\xa8\xf38gv[\xcd\x89\x123\xef\x19S\xa5.1m\x82M\x1c\xc9\xd2\xd4\xf2\x8d\xf4\xa8Hm\x00#X\x9e\xc0\xba\xc6\xe4\x81\xb9\xb9\xc7k\x83]\xa0e\xfb\xa8\xb1\xc0\xdc(C\xc9\xcbn\xe1lh\xe3\xa0m\xcc\xd03YG\x13i\x1b3\x96[\x88>\x96T\x0c3\x0d]\x14\xe6\x82V%Bg\"+\xea\xd8\x0f\x8dCO>+T4\xf4\xe9il\x0dO`i\x9c\x99K\xb4\xa7\x88\xf91\x98UV\xe8\xce\xb80L_\xe6\xe4\xfa$\x1fox\xae\xf0\xfc\xbb@,J\x11\x7f\x86\x90\xd9\xf4H\x8cP\x86^\x89\xc9\x8c,\x9b3\xce\xe1\x94\xf6p4b\xc7y\x8fW\xc2P\x13\xeb=7\x9b\x9cQE\xa3\xe7 \x171\xf1\xde*OT\x83\xf0\x0d2L\x94\xb2\xfd\xc2\xb7\x1d\xfdF\x16u\x14\x1f\x0dI\x88\xbf7\xa6\x89\xbf@!N\xaaU?\xf5\xefP\xba\x93\x8a\xa9\x03\xba\xa0\xfb\xe6\x1dm\xad\xdc\xc9\x80\xa7lS\xa0\x8c\xd3\xdb\x96\xd8\xf0r\xd8\xf5\x0b\xfa\xecBV{#D[\x16\xdb|'\x97}\xc7\xfc\xd0\xd9\xd4o\xc0\x12\x13\x99)\xe7?(\x82o\x99\x88P\xa6\x91\xfa\xeb\x0e{=}\x0c\xca\xbb\xfbN`\x10\xe1\xc8\x85\xe0\xce\xc7\xe2\xbd\x9e\xfe\xbe\xd0Qc\x97\xd4ZE\xcd\x11\x8b\xefnpHc\xaa\xc6\x08o`G.\x84\x1b\xdc\x0ehf\xb2\x1a\xbd\x816^=)\xc5\xa7\xcf5KR|\xfat\x1c@\x1bX\x8c\xfaqh\xf0>\xbf\xfbl\x9b\xf2\xae\xe8\x8c\x11\n\x0b]s\xe6\xf92y\x11f+\x96\xb0K\xd5R\xf0\xd7.I*\xf1[vfNT\xddEV\xca\x0c\xa4#\x15\xc2J#\xa9\xe5\xc6S\x18V\x0c\xfe.\xc46\xcb\x1b\x94\xd7\xa6\x0dO \xd5XD\xb8'\x1aMh5K\x0c\x0c!\xd0\xe3\xa4\xf7-#M}\x92\x83\x9e\xc8\xe9/c\x91\x9e\xe0f,\x0f\xbf\x86\x89a\x8cN\xf4\xe2D\xea\x15\x8d\x83v\x1b\x13\xc4o@\xc1\x9aB^7N\x84\x81\xb8\xdc\xfd\xa6\xe6\x9eAy\xdc?\xd4_B\xd4'\x0dQme<\x81X\xbf*\x82&\x06\x1b\x9a\xee.\xd7\xf6r\xa8\x8e\xc4\x85\"\xec\x84\xb2\x92\xe8D\x83\xa99\x02\xa3\x00\xca\x9e\xb7\xd0\x19$\xd3\x96ZWJ\xb5\x96(\xbci\xcb.P\x0e\xbe\xbd\x859\xfdoI\xff[\xab\xa5f\x98\xb3\xfc\x94\xb2\x8c\x1c}\x99\xae\x8d\xca0\xba\x9c\xa1r\xce-\xa3\x84\x87~)<\xbe}\xcb\xcf74\xbb\xeb\x8b\xf2\xb3m\xb1*\x90m\xdf\xb0.\"8BUS\x01\xb6\xd6^LB\x0e\xc0\xf7\xd7\xac S,I\x05\x0b\xd5P\x05\xf8Z\xaa\xd2a\xe2\xda\x8d\x0bW\x0e~\x9f1\x03\xf7\x8d\x9e/\xcd\xee\xbb\x8b6&'\"-\xac\xa0\x17\xe9\x89\x03\xb1\xc8\x8a\x12\xea{\x17\xdfy+\xeasS\xec\xe96\xa2\xce\xb6\xdc\xb4?\x0c\xb4#\xe0w\xbab\xae\xa3\xf8\xb6h\xd4\xdd\x15\x1a\xa6\xa4\x1d\xfd\xaa\xec\x16\xe9',\xc3d\x82\xc5\xf4d\xe3|\xfa>^F^\xba;\xe0\xb6w$\xe3\x95\x87\x07{\xfa\x87/\x85\x86E\xf7\xa4\x7f`|dj\xacP\xd9\xe8\x1f=_z\xab5\x99\x99K\x98\xda\xa4\xcfJ\x8db\xa6\xdc\xb1\x0e\x83*o\xea\xeb+\xe9\xeb+\xcfr\xf3G\x05^\xe8\xee\xd5\x07D\x01r\xfbGu58\xae(\x0f\xd0\x18R\x81 \x03H\x05,<(*`a\x0b\xa9\x80\xd1\xfeQ\x85q\x9bG\x05\xfcC\xe2\xbd\xcd\xfb\xd1\xea\xbb\xdbm\xc1\x88o\xc1 '\xf8\xf8\xb3\xd5\xca\xc6tW61\xf7\xc6\x1d\xd9\xec\xcf]#L\xa6fu\xe5F\xfb\xb8F\xf3Ul\xf1\xbeb\xf3\x03\xbe\xcf-6\xc3\xa5d_tr\x18\x1b#\xdd0\x9a\x9177k\x06S\xab\xc0tQx&U\xeba)\xca\xb1\x9e\xb4T\x8f\xc6\xb5\x80\xd2\x10vs\xb8\x98\xe0\x11\xaf\x1a-O>I4~\xba^\x1da\x14\x9f\xfa\xc4\xd3W\xb6+\\Q\x95\xfe\xb1\x98S\\\x8b\xb3\xfbG}'?Zn\xce\x15\xfa\x86\x03Z\x7f\xa3\x03\xdav\xb2eu\xe9P\xf7\x14\xcb \xe3U\x7fx\xa1=\x1eO\x0d\"YHE\xb2\"\x85\xbct\xc8\nq\xff\x97U1-\x9eF\x8e\xb9:\x98\xa4\x8fm\xeeU]\x19\xd2tm;\x19b\xa0<\xe5\xbfQ\xfd$\x99\xbbF\xa0W(\x11>\xc2\xdc\x92{{\xdb\x9cv\xa9\x06E\x8eD\x8e~\x0c0\xe0\xf2\xa1nu\xed\xa6\x99\xba\x9a=!\xf22uW\x1bR\x9b\xca\x92\xf7\xa2\xb1\xd2\x90\x07\x86\x84\xd0\x067\xd9\xbdA\xd5W\x92\xfbP\x0e\xaa'4\xeeC9\xa8\n]\x89^F\xe3N\x94\x8as\x06=t\xf9v\\\x81b0\x0e\xbb\x1axg\x8d\xd0\xa8\x02] 4\xab@g\x08\xad\xe6\xdf\xa3\x07#\x89 \xb2L'\x1a\xb1\x84\xee\xae+4[\xc7\xf8\xbf$\xe4\xd8}\x87\x1dJ\x82\xd2\xbb\xc8\xed\x8b\xd7\x02,\x12\x95\x8a|?\x8eVABD1J\xae\x93hyElV_V*\x8c\xc2FQ_\xc6\xceD\xa5\"\xb9\x90Q\x14\xf3\x9cB\x87\xda\xbcA\xf5\x87\xd2P\xe7c*.;\x96\xb6sM\xc69\xc4>8\x05\x9f\xa2\xba\x9a*\x93\xc7?\x10^\x12Z\xfb\x1e\xdaT\xe7\xb5\x96r\xcd\xca\xa9\xdc\xce\xe4V\xa0\xab\x07\xa7\xd3P\x85\xc6\x03AWE\xbe\xca\x86j\xea]\x0e\xca\xebo\xa8\xc2`\xfe\xafV\x91\xe3\x87\x81\x94\x80\x96MT\x92U_mGovw\x1d;\xb4\x0f\x1d\x17,\xb1&\xa6(5[\xdej\x94j\xe6S\xfc\xf0\x15\x9f\x91\xf4\xe1+\xe5\xcb\xf0@\x15\xf7\x8f\x0c\xa1\xd4\xb6\xb7D\xe4\x82\x87\xb8\xbf\xe7\xf2\xdb)B\xb5\x1e\xd6\x18E#\xaeeW\xb7>p\xa6\x91\x8e#\x9d\xba\x94\xa9Kx~\xb4\xd8\xce\x1cSX[\xd8\\\x8a\xa9\xb9B`\xba\x01\xa9\x0f_\xb57\xd0)\x0b(\xbb\xd4\xc5\xaf\xd2\xad\x86PhV\xcb3\xfewXe\x8bs\xd5\x04\xbf\xdc\xf0\n\xa1A\xc6\xc8\xf8\xe1\xd1c\x99A\x13\xdb\xc7\x95%\xcdW+\x85\x9e;\xd0\x05%\x90Z\x90L\xac\xec\xd4\x90\x07\x17\x89\xd8\x9bh \"\xb8\xc0s\xb8\x85\xe5\x03\xc92\xfd\xa3\x8dn\x83\x1bL[\xb8\xf0\xba@I,\x9d\xa7^|\x96\x86\x1a\xc0)\xa6\xc1mJ|k\xe8\xfe\xce\xf8\xf3\xeex2\x9d\xb6o'c\xfbthwN'\xb3\xb6}:\x9ct'\xb3\xb6s\xea\xdc\xdac\xeb\xf1\xd4\xb1\xe9\xb3\xd3\xd6d\xe0\x8c?\x9fL\xa6\xb7\x93I\xd7\xf9\xf0\xd4\x99\x0c\x9c\xc9\xf4\xd6>\x1d\xe1\x1b\xb7\x93\xf1d\xea\x14_o?p\x9cj^3:\xdc\x9d\xc9\xc4\x9eL\x9c\xd3\xea3\x81\xebGN\x83\x1b\x8a\xe9\xc8\x02\xc5\x0c\xed\x1d\xb0\x9b\xb8\x98N\xf6y4#\x98RV:\x98X\x16r\x14\x11\xfa,.O\x17s\xa2\x8cLGa^GLq\xab\x94C\xff\x83>f\xa2E\xe5y\xaa3A\xc9!%\x18D\x8f:\xd16\x8bH \x8a\xce\x89f\xbf\xf9\x1a\x99I\x06C\xec\xab_\x05\x90,y\"\xf8\x00W5\x84\"\xb4\xa2[\xf1\x14\x026 \n\x8c\x11x\xdf\xf3\x17\xfa\xb8\x07w\xa6\xb4{\xbb\xfa\x83\xc6\xdench\xc3\x1ab\x86\x1b\xb6\xc5\x8f\x92\xe2\x8eK\xdct\x00\xbc\xcf\x11\xad\xd4\")\x9d\xc8\xef:5}\xc35\xfc-mj\x8a\xedL\xd8\xd4\xf4,\xe8\xf0\xae~\x00\xb9X\xe0s\xcb\x07\xe5Q6)\x82\x009\xb9\x15j\xc9\xbcd\xa0\xdd\xf6\xe1 \xcck\xafg'6\x19\xfbS\xa3\xdf\xceR\x90g1\xf7\xd8\xbf5=k\xa1\xbf\x8d\xfa^\xca/s\x97\x1eh\xc5\x074\xac\xd1>\xb6F0\x87SX\xc2\x10Z-{\x0ef\x031g\xa1s\xfc\x9b\xd9k\x17\xe6\xdc\xbekKq\x13\xef\x8d\x87\x06$\xbc\xbb\x97\xc2\xae\xde'doW\xef\xbf\xa2\xca5\xd9\xa6\xc8c\xe8z\xc4\x9cD\x98G\x01\x06\xbcj\xde9w\x9e\xa7\xbc@\x9d\xc2Z,1)\x87\xa8\xaaz\x8c\xdeu\xca7\x91J\xee\xd3\xfd\xb8\x12\xb9\x0e\xee\xd3\xd9\xbd\xdd\xaa2T\xa8\x83\xf4\xa9\xb2\xf7vu\xc4\xe8S/]tW\xdeu\xd3\xb0\xcd\xc2\x98W\xb3\xf5TMA\xcb\xcb\xd5\xaa\x9d\x8aO\xde\x95\x88\x98\xc1+\x13I\xcb#\x93B4\xc9\x13\x9e'\xe8\x0d\xeeA\x1b\x12\x0c\xbc\xe62^\x1c\xd0\xf9\xdeu\\H\xee\x8f\xb6\xc2\x15V\xd1o\xe44V\xf6eb\xde(!\xb4\x01\x05\x9e>\x0c\xa1\xd3wN\xf06K\xd4\xe9\xc0\x10\xda\xed\x88%TW\x90\x85N\x13\xb1\xe9\x91\x0b\xbd\xca$Et\xa4\x9d\x86\xbb\xc7D\xdb\xdbm\xce\xc4_#\xec\x98d\x12\xf8 \xe8\xeb%\x12\xb1w\xe9\xd2\x12\xe8\xa0\x10N`\xd8\x18\xc2\xc1<\x82=\x9d\xa8\xd2\x87\x9d\xaa\"\x0b\xe3\xbbt\x0f\x8f\x0f\x0f\x8ew\xfb\xbb{G\x07\x83\xdd\xfe\xfe!\xd9\xed\x1dm;\x01\xb9\xaa\xfb\x94\xf9^1S\x01\x13\xe3\xa8\x04\x8b_;\x01{\xcc\xc2\xbeu\xe8\xfa\xf7\x1d\xf8\x10\x1d\xeeR\xb1SR:r\xfc7\x92!w\x9d\x0b%^3\xd7&\xe8\xb4\xc3\xaf\xbcW*-\xd8\xf9|\x92\xb4o'I\xfb\x83\xea)\x83Ex\x1ew\xda\xd3\xde\xf5\xb8\xd79\xf6:\xf3i\xfb\x83\x9d@\x15Vv>\xef]\x8c{}\xcdS\x9f=\x8d\xc6\xbd\xce\xa1\xe61\xe5\xe0k/N\xc8\xcb0\xddvI\xe8\x8e\x91\xa3\xbd #`\xbeqR\x95\x10\x05\xb6yc\xa1J\xd3p=\\\xe0\xbf\xd6\xc6\x91\xe6\xd7\xcfN\x8b\xef\xecJ\xb3^\xe8\x89\xd9\xc9\x9e\xdd\x10\xa2\x9b\xa1T\xea\xbd:J\x11\xe4\xae\xa5\x19e\x19\x8f\xda\x95&\xd9e\xb1r2j\x95\x00\x87,\xac6K\x14\xa3\xdd\xc4xN\xf3E\x118\x85\xb9\x9dv\x93e\xe0\x13{\x80j\xa7S\x18\xc0\x10\x8e\xe8\xa8=\xa9X\x84}\xba+r\xf7\x15uK\x03\xb7\xdb\xab\x8a\xd8\x99V \xe7\xa6\x8f\xbdf!\xc9\xcc\x01\x19\xf7a\xb2\x12\xe5W\x86iC)4\xaf\x86\xb2-\x8aGL\x8c\xa1VE\xf1\xfcc\xd3\x172.\xdaf\xf0\x04\"\xe6\xe8\xd4\xc7\xb8q\x81\xed\x8d\xb3)\xbbH\xe6\x9c\x98\xf5\xd1\xa6\xd8\xe7\xdb\xae\x84\x9eN\x18\x82\x0d\xa9\xea\x98L\x08T\x1b\xac\xa7\x86)\xe0\nd\xf2\nT\xef\x1f\x89\x83\x93\xf0\x8d\xd0\xd2\xdeV\xab$\xd5x\x18\x1b\x86\xb1\x8e\x08\xf7e\xae\xe0\x18\x96\xa2\xdfz\xb9\xbe+\xe4\xee\x9f\xe1\x98L\xb7\x8f\x99ne \xc1\xec8~*\x99/\xb9\xd3\x05\x0b\x97!\x9clx<\x18\x92|\x1a\xcd\xb2%\xb1\\\x85\xc1,32,E\x8es\\\xbcs\xbd\x8a\x82/\xc9\xec\xcc[\xad\x97\xe4\xe38Z\x9d\xf9\x0b\xb2\xf2`$=|\x1e\x13/%\x7f\xe3\xd3O^\\c1\x16J\x0d\xbf\xfe\x8d\xd5\xb2\xf2R\x10\xceI,\xfdN\xd4\x9a\xb9\xa1\x1bH\xd7Wk^\x9eh\xf0\xa9\xaf\xa4H \x90\xe7\x87\xf6\xde>=n*H\x85\x8f\x0ev\x9dM\xa3\xb1\xc8|\"\xed\x16\x13\xc9e9\x95\x1a\xcc\xc8\xdc\xcb\x96\xe9\xb0z\xab\xf4;\xea7\x81kj%\"\xf3Q\x8e\x04&\xaa\xcc\xbb'\x90L)\xf3^= \xb2\xa2\xe7d\xe5\x05\xcb-Z\xc8\x12\x12\x7f\x97\xb0\xd5\xe8\xfa\xd1j\xa3\xb6x\xbf\xceg^J:i\xb0\"\xd6\xe6-\xa2\xaf\xc5G^J\x9cn\x1a\xbd<{\xcd\xbc@m\x8d\x1dBs\xda\xc5\xcd\xb9y[\xbd\xcd+=\x9f/#/}\xe0\xaa\x830%\x97\x0f\xdea\x1eD{X#T\x88\x8fX\xe5<\xee\xb6t\x8c\xe9r\x94fQ1\xf8\x0f\xb5\xfd2\xba\xab\x07\xd0\xfaN\\\xe5\xfel#\xb0{.\xc4]\xe6`\x11\xcco\x1c\xadB\x03rC\x8b\x9a\x82H|\x02|>\x8f\xe2\x95g\x88\\EI\x827\xc6\xfc\x91\xe7\x16\xb4!\x98\xa2\x0b\x90\xf6\x12\x92\xc0K\xec]\x90|\x9c\x85\xbecGx\x82\xb2\xd1\x1ek\xfd |\x1bF\xefBxs\xb3&C\xa0\xf5\xa5\xd8\xbb\xba\xa9\xf1M\xc40\xa7J\xa9^u)\x0e\x85\x9e\xf0%\x17\x97\xb2\x9fB\x1f\x8a\x9c\x14\x94\xc9\xe7E\xc6\xfd)\x15\xde\xe4\x9f\x98\xc7\xca8{\xcaR\xe8\xe2\xc5\x81\xf0\xf9\xadY\n\xb4yw9\xfd\xd0\x17\xf1\xb0\x08\xbf\xc4\x17\x10\x8dg/\xf0\xf9\n\xba\xdel\x16\xd0\xc9\xf1\x96\xdfo(?\xc7\xf2AJV\x86\x02h\x14\xe9\x06\xa1\xbf\xccf\xe43\xe2\xcd^\x87\xcb\x1b}\xd1\xb5\\\xf4\x87q\x90\x12ZV/\xe8I\xd3\x9f9e\xdc\x99\x11\xb2^\xdePz\xb6\xfe\xeb\xe4\xc6\xc1#\xff\x07\x1f\xc4dnma\xa5\x94\xe5\x8a\x92ou7\x08g\xe4\xfa\xf5\xdc\xb6\xfe\x8aU\xc9\xcc >\xefM\x16\xa2H\xef\x7f\x1c\xb0\xe0\xb7\x91\xe4\x1a\xae\x176kb\xec\x82hc.f\xc3 \xaf\x8a\xdb6^\x1c{7*\x97\x01\xedy\x01U0\x85\xb7\xf9\xc8l\xed\xbe\xe2\xc1\x06\x14\xcc\xae\xba1\xca\x9fY\xe56\x8b\xfc\xc9E\xf5+*\xd8-\x1cX\x8c\xaf\xa6t%\xe8\xdf\xee\x8c\xacc\xe2{)\x99\xe1\x8d/\xf9Q\xccq\x0d\xd8\x05\xb6\xea\xe3w\x02\xbf\xf0\xf9\x1a\xef\xb9\xcfh\x81\x11\xa46-A\x85B\x83\xd0\x8f\x13\xcd\xb4N\xbe\x03\xb3\xcav\xe9\xd7\x8c\x06W\x90\xbe\xee\xebQ\x01\xaa\x11\x0c\x94y\xf4\x1d\x97\xc5,\xb0o\\\x8c\xb2\xb6\x82\x11\xf4O`\x05O`\xef\x04V\xed\xb6\x03\xb3\xb1U\xee\x12\xa5\x95+:\xb4K}\xb78\xd2\xcfTT6\x91i\x8e?\x0c\x19\xe0\x94\xa7\xb2 \x12v\xbdl\xde\xf5\xc2\x9b\xd7s\xd4\x92\xb1\xaf\xdd\x95\xb7.<5\x9a\xee\xe6\xb2\xf8\xf3:\x9f\x08\x18*ME!\x11M\xe1\xd7\x07lj\x9c\xdas\xfa\x94\xd2q\xd2%a\xb6\xc2\x10\x8c\x82c\xcb\xdf\x87|\xa9B\xca\x0e\x97\xc1\x97\x04\xbb\xe7\xd8\xec5g\xdc\xa3uX\xf3`IX\x8a\x8d\x08\x1d\x9b\xd0\xa5I\x17/_U\x12\xdbU\x19\xbf\x9e\x96\x89\xe1u\x13V\xfe\xd1#\xa6\xb6\x17\x00\xf4h)\xb8\x01{\x8e\x1cF\"C\x8aO\xc6{\xd7x\x04\xd9\x88\xa1\xb2K\xcb\xdf\x1aO\x8d\xb6\xe1\xa9x\xff\xa5\x86\xa7z\xf8|\x13\x86\x19m\xc90\xa3&\x86\x19\xd5\xb3\xf25c\xba\x9b\xf0\xd4\x85\\4\xe7\xa9\xfa\xb23l\x99#\xb4\xbe\xc8\x15\xd26\xfd\xb3\x9b\x9ag\x97(\x86]\xaf\x96\xfa\xc7\x94\x86]b|2\xfd\xf3s|\xbe\x8e\xc9<\xb8\xd6\x97\xb8\xc8kH\xd6\x9eo\xa8\xe6\x1d\x9b\xda0[\xe9\x9f_\xe7\x87d\x03\x03\xcfj\x188\x9a\x07\x1c\x96\xda\xfc\xc7\xc1\xc5\xb3&.\x8e\xd1Y1l\x8c\x15F\xa9wI'\xc7b\xfe\xb1\xf69\x9c\xc29\x15\xcb\x87\x16\xba\xb6;\x94A\xb8p\xc1\xf4\xf37c\xfa\xdc\xba^-\xc3\x043e\x9f\xd3B\xf8\x13o\x03^\x18\x04\x1c\x99)\xa0[\xe5\xdcD|i\xe99\xc5\x07J8\xf0\xef\xed-\\\xd2\xff\xbez\xef2\x08\x0f\\'\xff\xa0e\x18\x96\xc0e\x97\xc7\xe0\xcd\x85\xbf+\xee\x95;u+\x1cbIy\xc3R\x8dZe\xe4\x0c\xf43\x17;\x90\xe5\xa4\xa2\x953?>\xe4\x08U\xfd\xbe\xf8h\xf8\xd3\x8c\xb6>\xdb\xbau\xc1V\xb6n]L\x03/9u\x01%\x9c\xa2\ns\xab\xe7^\x9a\xc6C\xb81T\xee\xc2\x95\x1e\x1b)e?3\xb8XB\xc1\x8a4\xabb\xdfsY\xce6\x9a\x15\x17\xce\x0c\xebb\xdfsa\xb6j\x9f\x97R\nm nk\xd3\x12\x01\x9f\xfa\x17zq\xbbA\x9c~F\xc5ii\xcf\xd0\x9d\xb8\x14\x1b\xf0\x85Y:\xa5}{Q\xb9jh?ct\xa3\xf5b\xfcL\x12\xbcooa-?(Dn*\x8c\x1b\xa6\xab\xd4\x0e}\x8b\x11\x89\xfc\xab\xe8!\xff\xdd\xa58\x1b\\di\xed\xb2\x89\xcf\x15\x8f.YF\x05\xac\x0b\xa54\xda\xd9\xfc\x971\x05K\xf5\xf3\x85\xe8_-\xd3\xae~\xde\x8a\xb78F\x99)\xbd\xf8\xdc\x8c\xf3Q\x0br\xf8l\x9a\xb3,\x14\x9b\xbe\xa0#\xf8\x82>\x91\x80\xcb\xf13<\xf7\xe0\xdf\xf2\xa3\xb7\x14\xfe\x96\x0214f\x82sQ\xbf0\xb5\xa9^\xe4O\xb9\xb3#P;\xef\xca\xce\xe9\xf2\x0cV\x84A1\x00\xbbT\x86\xc1Mv\x19\xe9s\xc5\xe3f\xa6lt\xcd/\x94\xd1\xe3%\xa5\x14|\xa7 \x19\xf5\xa3\xd0\xf7R\n\x1fJt\xf5e\xc3\xb4\xd5\x91Fq\x98\xe4\x0d5\x11\xea\xb2\xb49\x04\xebYx\x93.\x82\xf0\x12|/\x84\x0b\x02\x0b\x12\x13\x83T@;\xedo\xca\x11\xaa\x0d%\xa6s+%r\x0f\xc8g6\xa0\x91|\xe6\xae\xcb\xf8\xbf\xe4\xae\xb1\x12h\xc63&\x94\x17\xf5\x1d]\xd4w\xecT\x96\xb0\x80kl\x85o\xe0\x14\xc6\xfa\xbe\x1b\xfb\xfd\xde\x85kZ\xd1u\xb5\xeb\xef\xb5v\x90\xa5\xd9\x17\x81\xca;\xeci\x19K\xd1\x08Z\xd2s\x05\x82n8vX\xb5:\x01\x1aJ\xfc\xa5\x17{\xb4\xc1!\xb44\xd7\x1b\x83pF\xc2t\x08\xd6$\xad\xdc\xae\xab\x9a\xcb\x00o1\xd4X\xa5h\x7f\xa2\xa2?\xcb&\x13W\xa5<\xc7\xa9\x06\xab\\\x0d\x87\x96<\x05\xf6\xabn1PxK\xec\x0f\x9c\xeeY\x1a\x13O#\xfe\xa3N\x8c~\xb1\xa4\x15\x83\x8a\xf5Jo\xf5\x04\x919\x80\xd24\xcd\xc9\x01=\x05\xd0\xa5\x11\xc7\x1e0\xd1!\xbf\x92k\xb3\xf7\x9c\xee\x17Q\x10\xda\xe8KgYU\xdb\x9a\xf8$\x94\x8c\x19\x84oC4\x08\x1b\xbdD\xd3\xb1\x142\xe0-\xb9I\xec\xd4\x19\xf7\xa6SdyI\xf7\x9c,\xc9\xaa0\xdbr\x80\xa0\xdc\x91\x9bC\x02?\xcaB*\xfd\x84\x12\x0c1\x89\x0d\xab\x0c\xa3-{20%q\x9c\xadS\xcc\x00'\xc0\xfa\x19\xf3\x99\xd3\xbe.4\x14\xf0S2\x957\x95\x87\xf9z\xad\xcd:\xde\xf24l-\x02\"y\xab\xf5m\xa8~r3g\x1b\x1e\x8f\xac\xc7\xd0f\x0epmxl=6\xbe\xf8\x1e\xbd\xa6\xc7dj\x14,7 \x93\xe2z2\xc7\x08%\x94\xad\xf8\xe0\xa5\\\x81B\xfa\xbb\xb9Pv\xc6\x18\xd1\xca\x0c\xf7\x1a\xc4'\xe9\"\xcd\xa48\xb6\xb6\xf9\x0f\x0cty\xee\xcf\xbc\x14\x95RK6\x9d\xb6\xf5\xa45~\xfe\xd1\xb37\xcf\xc6\xf4\xc0)J8\xb9\xe3\xde\xced:\x99>\xdd\xb9t\xc1\x9aN\xa7\xd3\xa7y\xf1\xa7xx\xb5\xa6\xd3\xa7\x16V\xcdW\x13Q\xdf\xe7\xa1k\x96\xd2=\xaed\xc3\xf8\xc5\xf2G\xbb\xb7N\xc1\xc2\x01!T\xd9YpJ1\x90\x0f\x19\x86\xa2\x0b9\x15\x816\xf4\xf1r\x81\xbdd\x89\xb5]T%\xb5zyo\xd1\x13\xd3,T\xbc\xc77no\xa5\xc1\xd5\x8865\x0b%L\xea\xc6w\xf3\xfe$\x9a\xee\x189\xb3~F)E\x19B\xa4\xdf\xd49}\x18\xd2U\xd3\x16\xc9\xc5\xfdd\x08s\x83F.\nS\xe4l\x06e\x13#aC\x08M\x9d@\xca5\x04\xaf\xeey\xd5e\x15\x94\xa9xo\xe0#^\x1d\x1f)\x11\xf2\xc2HL$\x97&\x8a\xcf\xba\x08\xf1\x82 \x12\x89\xcc2\x0f|\x0c\x9fK\xa7$\xbf\x9d`\xa6\x9a\x81\xd14\xce\xd3X*\x95\xd5\xed\x1d\xe1$W\xbc\x94,\x82yZ\x0d\xa8#\x7f*\xc6=\xadKX\xb5|d\x07N\xb3\xc2\x8c~p\xf25gp\xf1\xd1K\xe9z([\n;F\xed\xf5)\xce;\xe3yB\xa1f\xf3\x94\x0b\xa7`=\xd9\xa1T\x8d\xffn\x83\xf5\xd4\x92Kq\x06\xfa\xe8\x11\xb4BZz\x12\xf2\xc7\xe8W\x8c\x17\xc9t\x1b\xcf\xbc\x8aQ\xa3\xd9\xa3\xd5\x92\xf1\x04\x9dr\x8b\xdf]o\xbd&\xe1\x8c\x8a\x0d\xae\x8cO]\x06\x0cJ@\x11\x1d\xccn\xf5\x1c\x17Z\xbdMH\x04]4\x8e\xc9\xf9\xac\x95\xe7K\x9a.i\xa2\x8a\xdd/,\x07\xa7`\x01++=CI\xca\x02\xcb)\xde\x8dq\x85D\xf5|\xfaqo\x08\xd8\x8eiM\xc4\x02\x97\x96\xa5\x15W\xb7\xa4xC.\xa8\"#\xae\x0c\xde\xbd3]\x87\x82\x1a\xa7;-\xcd\xd0\xd0\x0bD\x1a\xf4H6\xa8_9\x0d\x0b\xd5\xb52Q\x16\xf41\xc5\x08\x00\xdd\x04eh8e\x99Px\xaax\xb3\xb5\xc3\xb2\xcc\"\x9c\x89\xcc\x0bW\x00>\xa3\xfc|,A\"\xda\xac\xf894\xb6\xb1\xe0q\xe4\xcd[ef\xe6\xfe\x0b\x863\xe4:}\x13\xf8o\x99\x13J\xba\xe5N\xbc\xaa\x95\x0f+\xc4\x0e\xf5\x1e\xf6\x1c\xda#\x96\x8c\x12\xf2\xd8\xab(\xc9 \xb7\xc79\xe7\xd7V{\xa2\xd0\xb2\x89\x08\xe3\xc1\xd2L\x1agv\xa3g\x94\xf8\xf8]\xb2\nR\xdb\xa2\xd2\x99\xa5\xb5\x9c\x8a\x0f\x15P\xd8\xfaoHT\xeb\xe6\xf1\xa6v\x1e=\xfb\x8a'\xa0[\xbb\x98\"\x91\xb2\xbd\x9e\xa3\x0f\xed\\\xd3\xca\xa5q\xf8\xccf\xdf0\xcb\xe9\xb75\xcb)\x95\xf58\x88\x843\x0b\x7f\xc6\xc4\x9by\x17x\x00\xa7\x04H<\xf7\x97QB\x0c\x91\xee@\x7fl\x00\xc3rT!\xc2M\xa0y\x1c\x0b5=$p\x94\x08\xbb\x92j\x02q\x1b\x8f\xee2\xd4\xc5s\xae\xbe\xe6+\x12'\xa8\xd3\xb0\xfa\xdd\x9ea\xd7\x93\xd0\x8ff\xe8\xe1\x19w\xc5wFr)\xbd\xfa^\x8a\xd9\xd4%K\xb2b*\x85\x02\xf6\"\x87\xd5b\x9f\xd8\x87\xfa\xe1\xa2\xc2a\x08\x99\xcd\xb4\x81E\xecD\xbc\xc8\xc5\x82\x15\xe6\xbe\x06&%\x0c=\x0dm\xe2\xf5 \xc2\x9a\xcb\xf2@\xa2L\xe5@\xba\x88\xa3wH\xc61(\xacm\x85Q\n^\x92\x04\x97!\x99A\x1a\x81\x07,\x14uK'?\x88\xcf\x95\x94\xaa\xbb\xde\xdePdG\x96\x143\xe6\x8a=[\xea-'\xaa\xa1[\xaa\x81\xa9\x80\xdaT\xc0\x10\x94V\x0e\xbc\xdfD\xdb\x08\xaf\xdc\xd6\xc9\x8a\xe2c\xa2R\x86#\x1f\xa5y\x9b.\x89\xc4p\xd9\xee\xa1Ccv<\x91\x01\x9a\xca\xb9\xe2 \xed\xe9\xc6$S\x9dW!$\x96\x91=\xffU\x8a\x1a\xba\xbbg\x88\x18*\x0fG\xb0\xf3\xf2\x00\xadG\xd6\x10\xacG\xdej}R!\x8a\x8f\xad\xc7\xf4\xc9\xcffQZ}d=f/\xad\xa3Dy\xf4\x04\x1f-\xd5w\x9e\xe2\x83\xcb\xf4\xa4\xa0\xa3\xd2\xb0\xb7\xbal\xc5\x89\x17\xa7lH\xbcru\x8f=~d=y\xfax\xea\xec\\\xd6LF\xa5\xc2pL\xaaI\xb4`\xb8m(\x8a\xd2%\xba\x93\xd2\xbc\xf3[\x11\xfd}\xa7\xfb\xe2\x8a\x84\xe9\x8bU\x90\xa6$\xd6)\xf9\xd5\x83t\xccc\xa1.\x02\xe5Z>\xfd\x84\xf6\xee\xbec\x07.&\xd3\x0d\xba\x9f\x15\x14\x93\xb6x\x80\xc0\x1f\xc6A\x9a\x03\xf7\xf6\x8f\x11\xf8Q\xb6^\x92k\x06:\xe8!\xe8M\xec\x85\xc9<\x8aW\x1c\xdaG\xe8\xf7\xbd$y\xb3\x88\xa3\xecr\xc1\xe1\x03\x843\x9d8;\xd8\x05r\xc2\x8f\x00\x9d\xc1j'\xffJ\xca#o\xd2\x9c\x07\xfa\xd3h\x8a\x06a\x1c\x0e\xbb0\xc5X\x0dZ\x89\xe9\x1b\x18\x1bh\xede \x91\xbe*\xc7&}\x93\x91\x96\n\x85\x05\x1f\xc2\x1ac\x92d\xab\xd2\xf7\xdaSY\xd8\x8d\xc2\\$\x0b\xd0\x81\x0e\x01\xb1\x17\x84\x96\x0b\x11B\xce\x83\xe4,\x9d\x05\x11\x957\xe4\x81\x11$*\xb7\xb7`\xb3j\xa8\x18\xe7\x82\x87\x02\x11\xfd\xcd\xc46\x17\x92\xaa\x16\xef\x8a\x874k\xf5M\xf3\xebi\x07\x9bac\x19\xe7\xb8)\xa3c\x9b\xcd^\xb2A\x85\x86{\xe03\x92\xa4qt\xc366\xff\xb1i\xb3\xbe\x9en\xa3\xaf\x90\xed\xb8\xdcN\x1cw\x97A\x92\x92\x90\xc4\xcf)\x1f\xc2\xfd\xe4\x82E(3\xb5\x1c\xc1_\xab\xf4V\xdf\xe2\xdc\x88&\xab\xe8\x8a|\xc2\xdb\xa9\xac\xb9\xf2PZ\x7f\xf5Uy\x9d\xab\xcf\x8a5\xd7\xbe\x89#\xa2\xc2\x92\xaeU\xf9\xa9\xa9\xd5ym\xabsm\xbd\xc5\xd3\x9a\x9d \xc8-\xc3\xe4R?\xab\x10\x19\xdb\xe7\n\xb6\xcf\xf3w\xca\x10v\x94\xa1\x04\xc8b^\xceM4\xdca\x8ec5d]\x7f\xab\xaf\xa0\xeaG=\xa7\xcb\xc2\xe3\x96\x19\x9e0\x1e6\x86\xc8\xa9\xa2R\x8ee\xa9\x16\xcbZ\xcd\\\x0d\x84\x00i\xa7 %\x19#\x8e,E\xbe\xb9Y\x13.I>\xf7B*LR6\x03\x1e\xf8K/I\xc0K\xc0\xcb[\xd2\x1c\x0b\xdf\xf3\x0d\x94\xcb>\x0b\xe2\xcd\x80E\xa3\xe1\x90\xd4\x0b\x96e\x08?\x0e\x8c\xaa^\xcb:$I\xd5\x8c\xe6\xf5r\x9a\x10m\xf5\xf3A\xb7\xa21S~H\xaeS\xa6\x8eR\xc7\xa9\x8af\xf2P\x9eb\xc0\x92|\xb8\xa8\xf5\xc1\xdb\xc0\xc3\xd2\xac\x90\xf2\x94\x10\x17\xdam\xa9\x9a\xf2l\xb8\xa5\xb1g!\xea\xbe\xbf\xfd\xe1\xe7\xfd\xddd\x0ex\xec\x0ci&\xd0\x11\\\x1ec\x051\xb6\x19\xb32b\x13}\xe7\xe2xQk\xddy5\x15'\x1a\xda\xa3.\x9d\x91Z\xbf\xc3\xbe2\xc4\xd3\xd2\x80\xaa8^Y\xf2\xa2%:\xbd.t:RU\xda\x98\x85u3\x82\xb1\x0e\x9bf\xa4\xaew\x0d;\xb0\xdc\xda\x17Q\x106\"\x1c\x9b\xffQu\xfe\xc5E\x0f\x8d\x17s)\xean\xdeY\xe6Zl1m<\xae\nO\xcdM\xe7\xed\xc4\x81\x10\xda#4\x81\x13\xc3\x9a \xaeR;\x7f\xe8{u\xcf1\xc5]o\xb9\x8c|\xbbg\xf0cV0\xa6\xd0\xf57\xa0]13xj\x0eXl\x08\xde\xde\x0f\xc2\xc4\x9b\x13;\x85\xa7O\x9f\xa2v2+O\x9fG\x97\xf3\x04\xb2\x13\x07'.\xc36\xd8\xacF\xfc\xe2\x04^\xde\x8e\xd67,\xb0\x01}\xa5-\n\x96\xa2\x18dl\xd2MS\x1c)S\x9c\x03\xdeSI\x0b\x03s\x06\xdd L\xd6\xc4OK?\xba~\x96\xa4\xd1\x8a\x91\x89\\9\x93/\xd0\xb8ZpZ\x87\xecb7\xe7/i\xd4jlXC0\x92\x1c}\xb8\x1e,.\x05z\xcfMo\xec\xe2h1^\xe3\x89{c\x7f$\x1d\xfb.sw\xbd\xddF+\x90\x88\x0fS\x1cu\x13\x92\xbe\\\xad\xc8,\xf0\xcc\x1e\xae\xdc>\xc3|\x8cx\xcab5&\xb3\xfc\xf1k\xaej\x007\xdb\x98L3\xc0M7iw\x16\xf9\xa8(3\x97[\x97\x12B~_ \xc9k\xcc*\xa7}`\xcc\xa7N\xab\xc2\x8clk:'o\x82\x15\x89\xb2\x14NaM\xc9\xb5[D\x8c\xe7yk\xa6\xccq\xfa\xab\xf7\xdd4bW\xdb\xf9\xe9[$\xb6aQ\x8b\x9a\xe8\x88\xf8Hf\xa0Z\xca-\x7ff\xb6&\xaa\xaf\xf8\x98\xf4[0\x94Q\xa7\xae \xb4\xa1v\xd7Q\x92~\xca\xb3\xf9\xb3\xac?\xc1\x8an\xc93?\x0e\xd6\xa9\xd1\xddG|\x04\x11\xd79\x08V?x\xcc\xefF\xe1\x8a5Woh\xcf\x85\xbf\xbc|\x13\xd3\xab~\x88\xde\x84 \x7f\x18o(f\xc0\xb6,\x17\xac\x0f-~\xa8(\x1a\x0e\xab\xa1\x94K\xb5\xe8W\xc2vP!\xc5\xab~\xbe\xf0\xc2\x90,\xe1\x14l\x1b\xa3\xa7\x90wP~\xe4t\xe9\xbc\xf7\xf5\x03\xaeE\xae\x99\x9d\"\x057\xa9<\xb7\xc0\xd3\x08;1(M\x8a\x01\x0bQ5\x86\xc6E+\nc\xe2\xcdn\x92\xd4K\x89\xbf\xf0\xc2K\x82i\x92\x97\xa3\xddvD\xbe\x8b\xe2\x0e.Z\x06\x0d\x97\xbd@r\xfb\xaa\xdf\x85\x94\x1f_x\xfe[\xe3qV|\xbc\xf82\xd1\xf9\xdb\x89\x8f\xe1\xae=\x14l\xc8\x1f'S\xa6\xdf\x8e\xed\xc4q!i\xb7M\x08\xb7fG4y\xed\x16J\xd9:\x1f\x82\x85y\x89Yzw\xf0\xab\x81\x9b\xa1\xa1\xca\x1a\x1f\x15T\x8e::\"\xa1\x9f\x94\x86\xbb;\x02[h\x17\xeb}\xf4\x1a}\x9e\xe7\xdc\xf5\xa6\xaeL}\x9a@\xf1im\xb8{\xe4O~:\xed\n4k\x16p\xc4'\xc6\xf7(\xd6\xd5\xf7^|\xf2\x14P\x0d\xba\x0b\xdd\x07\xfd\xae{f\xdf[\xdd\x87\xd4\xf9O\xea>\x0d^\xda\xd5\x0f\xf6\xa9\xbfm\x9f\xe2qo\x93\xbbU\xf2\xe7.\xfd\x1a\xdc\xa5_.\xc4\xe3\xfe\x8f\xa3w\xbbw\xef\x1d\xfd\x7f\xf0-\xf7\xb1\xd1\xd5[\xf7A{\xfd\x12U\x0e\x1aw\x0f\xddG/Q\x97J\x98\x84\xa3\xbc\x00\xcc\x83\xd0[.7\xa1\x0f\xccp?\xdf\xe0\xbc`|\xba\xa9\xdfoE\xb7g[Y\xc8\x02\x02\xcedY(!\xcby\x11\xa9?\x0fN\xbc\x08\x12\x0c\x83=\xc4\x02\x92\x0d\xb8\x949\x14y\xb1\xd9\x15`\xf3[Q9\xfb0\x90M3\xf1E\xdd\x03\xe9.#\xdf[\x9e\xa5Q\xec]\x12)\xa2\xa3:)r\xfeTm\x855\xef*\x10aQ.\xb7\xaf\xe5GBa\xc8sn\xa07\x99\x95\xc6\x19a\x87\x7f\x1e\xd2.t\xbai\xf4I\xf4\x8e\xc4\xcf=\x8d\x01Y\xfe\xb5q\xf0R\x10wal+\x8c>\xe2A\x88\xd0\xc0b\x8a\xbd\x0d\x92\xb1\xa9\x1a\x15\x13\x8a\xb14\x9eapm\xb4ai\xe5\x12\xa1m\xa1\x85\xa8\xd2\xb5\xaa\xef\x91\xee\x1e\x81\xf8\xd0*b\xcf'\xa5*\xe0\x14\xfc(L\xa2%\xe9\xe2C\x16\xc0F\x80\xdeyq\x88g%\x1c\xa4\x1aD\x0f\x8c;-W\x170R\x93\xa2I\xaap\xc4j\xda\x87\xc6\xad\xb4\xd1\x1e\xd2+\xe2J\x19\x96\n\xb0\xe4\x06r\xac\xcb\xa3\x14\xda\xfb}\xed\xad\xcfH\xdd\x1e\xdc\xb6G\xe9\x82d\xde\x8b\n\x1c\xa2+\x15\xa9\x01\xc9\x0bG\x12MpS\xac\xb8\x1b\x84\x0b\x12\x07\xd8yt,q%\x98\x1d1'\x93H\xd2\xab\x9f\xa7\x92\xcbH\xddd\x01\xa2\x06\xb7DT\xdb\xde\xc2\xb3\x86.\xcf\xe1F\xcbS~k\xd0\xbf\xc3K\xfd\xfe\x81S8\xc5\xdc\xf1}\xc9}f\x93\x1a\x9a\xec\xcd\xfdc}\x16\xc4\xfe\xb1>\xcf\xcd\xdeAs\xac\xf6\xeaBqK\x04\x0bH-\xc7P\xd2\xeb\xcc\xb3\"zU\x8c\x97R\xd1*g\x13)\x8a5\xe6\xd6\xcb\n\xebWau\xe8z\xc9M\xe8\xf3\xe4\xadYw\x1d\x07\xab \x0d\xae\x08\x9c\xe6.0pZn\x02\x87u\xbc\xef`6\x0c\x1e\x03\xca\xd6\x948pl\x82w\xe5*\xcf\xa4zi\xb1C\x07S\x0e\xc8\xc0\xfd^\x9f\x01\xe9\xd7\x01V\x93w\x15\xfd~\xec\xfd\xde.\x82\xd6,!\xa7\x00\xee!p\x16$\xeb(\x07\xf6\xd1f\xd3]y\xd7\xcf.sX_\xc0\x04\x80\xbd\x19\x939\xba\xa7\x90X\xc0\x0f\xe8\x8e\xa3\x88\x92m\xb9k\x9a\x10i\xef@\x17\xb9\x1du>\xdeE\xa2\xa2\x12>\x99/#9\x97\xf5f\xe8\xc4\xd1$H^y\xafl\x8c\xfb\xcf\xd2x \x96\xa40\x82W\x18\xc3\x153H\x0d\xd8\x9e\x92\x07\xc6\xcb\xc9l\xfd\xe4\xe8\x02\xd9]\xb1 v\x89\x0b~y\x81\x03L\x9dBe\x1f\xbb\xc8?_&\xb9\x8eDv\x04\xb9\xd1\xb8\x83\xbf^\xd3\xc6\x13x\x8c\xa5\x1f\x83\x17\xce\xe01/\xfe\x18|\xe6\xe2sA K\xd0]\xfc\x92\xa4\x0b\x12W\xb5\xe5|\x19\xcbazr\xd1\xc8:?\x17\xd1\x19\xce\xcf-\x16\xaf>\xec\xce\xa3\x18\x9dp \x0cYf)\xcf.B\xe3\x93\xfc[X\x0c#\xe24\x9f]\x0c\xcbh\xd5 s\xd7\n\xa8\x8c\xd1(A\x87c\x82q]R\x1e\xa8\xddW\xee\x13\xb1T\xce\xe7\xe7\xeb8\x9a\x07K\x12\x9f\x9f\x03\x8f\x14^@0$\xa6\xdf\xcd\xd63/%/\xc2+\xbcJ\x9d\x87\x9fx\x90\xbd\xd3\x88\x93\xbb\xba\\\xbcBU+\x89Y\x17A8S\xb1TS\x90.\x95\x8a\xb6r\xe2\xff\xd2\xc3\xa4x(y[\xf1u\x7f\x99\xbc\x08\xb3\x15\x89\xbd\x8b%i\xa2\x07\x9b%j\xd0\xde\x84\xa2\x934g7\xd3\n\xbc\x1f\x18\xe27\xacK\xa5vk\x0ew\xc5n\n\xec\x90\xa58\xf3\xf9q\xdf\xb3)\xae\xa1Ux\xdeM\xa28\xb5\xb5\x04v\x8d\xa9W\x11\xf9\xd7\xb8\xdc\xc3\"\xfbL\x83\xc6}>N\xa7\xc8\xcf\x99\xc4\xed\xd2\x01\xca\x93e<\x88\xf1\xde'\xecE\x96R\xf8T\xd4\xe3\xbb\xb0t!\x1c\xa7S\x17R\x91gD{\xa3\xdctX}\x10\\\xde;\xacRR!\x81\xea\xf3E\x1c\xe9\xd3E\xec\x1d\xf5\x9d\xee\x8a\xa4\x8bh\x96\xe8(\xed\x9e\xf2\x1eg\xd6\xc7\xba\x04\xd3\x9a\xbd\x80g\xc2r\xc9\xf9\xa6\xbbfYl\x0cff,?\x96\x1c\x14J\x89\x1d\x94\xf0\x9d\x0b\x94\x81\xa3J\xcc\x80\x19B\xc9*hL\xdd\xa5?H\xa1o\xb7\x0bW.\xdc\xb8p\xe9\xc2\xca\x85s\x17.\\x\xe7\xc2\xb5\x0bg.\xbcp\xe1\x99\x0b\xaf]\xf8\xc2\x85\xb7.\x86\xb1Z\xe2\xe9KO\xf0\xaf\x98T\xdc\xe2\x020%\xe5\x9cw\xe7\xbai\xc6\xabS\x89\x9eK25\xc5\xfb3\xcct*\x831\xb8\xd3\x08\xce\xba\x97$e\xd1\x87\xcf\xba \xfd\xba\xc2\xaf\xcc\xac\xe1b\x94\xce3f>q\xdcB+\xd3\x8dI\x12-\xafH\xcc\x82\xcc\xbe\xe5\x9c%\x87\xd2=\xfd\x05\x8f\xbc\x144\x04a\xe1\xfc\x97\xfbU\xe5\x04D\xa5\x1e\x94\x1fcp3\xb4\xd6\xbf\xb5#\xa7\xe8\xd2\x88\xf1\xe8\x1b\n\xa4Et\\\xf2%]\xad\xfc\x1c\xfe\x82\x16\xcb\xb8W\xf2%I-\xdc\xb4\x11\xf3\xc5s\\x\xa9\x8dhO\xfb\xc0\xd2\xf2a\x94\xe4\xc2\xfbp\x9e\x93\x13v\x86\x8f\xc6\xbd)\xeaQ\xaap\xd1\xe7\x11\xcb}c\xd6\x08iF&D\x8b\xd8\xb6\x9e\x07\xb1\x9f-\xbd\x18\x82\xf0*\xe2\xaa\x1c\x17\xac\xe7/?{\xfe\x83O\x9e}v\xfe\xf2\xd5O\xbd~\xfe\xec\xcd\xcb\xd7\xafLVwZ\xeb\xa5\xad\x89_\xfe\xbe\x08i]3\x8d\x0f\xd4\x13\xbe\x1a/\x99=2p\xe1\x99\xbc.\x89X\x17n\xc1\xa7bH\x99|\xbap\xe5\xe4y\x07\xe9\xfe\xa8\xd5\xb6\xe1\xe1Y\xbf\xaa\x86\xa1\xb2{\x02\xb5h#\xae\x12\xe4\xa8[\xe0\x90\xc1\xa5\x10\x8dm\xba\xa0\xc9\xa7\n\xbe\x14\n3\x18V\x90\xccqMh\x9ew\xfa\x81\x17\x89\xf9\x03\xa0\xbf\xb0f\x99\xf2\xfb\xe3\xb8VD\xcdu.\xa7\xfa\x7fXR \xdf\xefD\x8e\xc7\xf5\xc4\xb8\x0b\x8d\xd3\x14\xd4.kP\xa6\x06\xba\xcc]\xb8M\xefK\x0dj:\xf7\xc0\xcb7\x0e\xe8\x1e\x0b\xb5\x8b\x17\x88u\xa3\xe2\x97\xe2\xae\x9bi-\xffQ\x1c\\\x06\xa1\xb7\xd4Z\xfb\x85\xb0>\x84/\xd4\x87\\\xd2\x7f\x85\x91\x83\x90\xdb\x8b\x9fj\xd9K\x92nr\x0d\x94\x0f\xf2m.\xe7\xbd\xb5S\x07\xb9\xdc)\xdc\xb0@\x0f\x1c)R\xba\x18*\xd5S[^x\xc9\x16-\x1b\xd6Q\xe3\xda\xa3i\x8a\xf1\xdbMZ3\x900`\xfd\xd5\xf7\x00\xe7\x04\xfd{W\xccM\nF\xf0\x12EU\xee\xbe\xc0~\xbc\x96\xd1\x82=\xb1P\x9a%\xba Q\xea PL\xd8 #\x8fP\xac\xbc\xd4\x0f\x03\xcf\x83\xe7\xf4\xc8'\x89Fn\xde1l\xc5\xdatb\xa3R2\x9f\x9aK9B\x9dC7\x7f\xae\x0ey\x81F\x0f\xccI&\x83\x9f\xe5`>K\x85\x1b\x95\xfdZD\xf1X\x94T\xfa\xfa\xb8\x15j\x7f\xe9\x18\x870S\x1f\xe4g\xe1\x0d&8e\x92-\xdf\x9ej\xb3\xd5\xed}\xa1\x8aj\xe6{,n9\x87\x8e\xba\x86l\x0b\x86\xb8\x05\xc3\xb2\x8cFP\x92 \x99\x8c\x96q)\xb3j7\xde\x92\xa7\xe7\x8an^\x1bg~\xe5*\xa1iki\xc8G\xc1T\x18\x17\xc9[\xa8\xa6=w1\n}P\xefF\x8cH\xdf8w\xbc\x1b\xc5\xd09\xcf\x1d\n~'Mk\xcaW\x8dNhA\xddB\xd6Y\xba\xa3U\xbd\xcb\xf5\xb7\xd6\xcf\xac\xbb\xf0\x121\xf7\xda\xee\x16XP\xd3q\x8e\x18\xb4\xaeT\x93pum\x7f\xa1\x0b\x8c*\xeb\xbe\x86\x10a\xd8*#\x89\x8d\xec\x0b\xcdSN\xbb\";\x13\xa7\x1d\xb5\x15\xe4D\x91\xfdN\xf7\x0cyEd_\xab}\xcer\xc8\x83\x9c\xf0\xfb\xc7\xba\xfc}\xf4\xe4\xaf?\xe1\x0ft'|\xd4Kv}o\x9df19K=\xff\xed\x9b\xd8\xf3%\xb6B\xe48\x1d\x8d\xf6\xa8\x90;#2u\xa7.\xf7\x98\x07\xe5\xfc\x1fj\x89\xa4\xa2c\xd2\x9e\x85#;\xe1\xa1\xb6<\xc6\xd4x4R\x91\xb8\x1f\xed1\x89\xc8\x14\xc9n\xe1F\xa2l\xd8\xf5\xa3\x19\x8a\xddxO\x87\"\x1a-CJ\x02\xcf=\xd6hs\xa3\x02\xe3\xc0\\I\xc1\xe2\x84ln[`\xb1l\x88\xad\x8f\x882\x8f\xa2!X\xb1\xf7\xa5U\xa5Qj\xd9\x0b\x8a\xf1\xd6\xec\x9d\xb7A\xd94\xfe\xf2f\x08\x16\xfdS\x0d-\xecb\x80\x9a\x08s\xb7]x1\xcb\xe1\x16\x7fy\x83\xb4\x81ve\xf6\xce\xc3\xf7\x1eXo\xbbgH\x8d\xaaU\xdc\xa2\x11g\xe5]o\xa0\xd41\x18\x08\x8a[8\x91\xe2o\xeb\xc2\xa0\"w\xa3\xa3n*+:Q\x1a-yhk5\x8df\x17\x9et\x1cS\xf9\x9d\x8cc\x8d\xabi\xa3\xbfN\xc8\x02\x15\xd0}\xdd\xe8{\xc1\x04\xfe\xfe d\xf0\x04\x92\x13h\xb73v\x7f\xad\xd8\xa0\xd9\xd4\xc5\x80\xb7yh\xa2jv\x82J\x1c\xb407\x8bh1\xfd\xdb0\x1c\x1e\xee3\xc3\xa1\xa4ag\xa6\xc3\xc3\x83o\xdbt\xa8_D>V9\xae\xac\x95\xdb\xd4-\x8c\xb4X^\x87\xdaE\xd5;`=\xb0>Y\xe1\x1eA\xd9d\xd1\xb4\x9d\xaa\x1d\x17\xe6f\x8c\x84\x9b\xaf\x0d;\x9em\xebzr\xa7\xbek(&oB\x1fR\x9d]A\x1b*Ks\xc7\x81\xe3\xb0\x1f=\x82`,\xec\x12\x98\xbe\xa1\xf5 f\xd6*\xfe\x1f3\xfc\xe7w\xe5J\x17nS/\x08\xf9n8\xea\xddc7\x88\xd9\x96\xc9\xfc\x96{\xa5\x8e\xd7\xc5E_1\xe7\x88\x08\x17\"\xa06r/\x91\x9d\xbb\xfal\x1eE\xd6\xc3\x18\xda\xc50\x95\xa9\xe4wa\xee\x8a\x0d\x95#b\xc9\xb6\\NDy\xdf\xceW\xee\x92\xba\"\x18\xbb\xc6\x04\xb4\xd4[E\xd7\x1b[r\x16\x9bZrf\xf5\x96\x9c+\x83%\xa7\xd2\xdc\xcd\xa6\x06\x9fK\x9dE\xb5\xac4)\xbf\xb0\xd2\x12\x0c?\n\xe7\xc1e\x86\xb6W=\xd1 \xb9mV\x1f\xf5Z\x04I\xaa#+j\x9akJ\xa2\xe2&a\x05\x84\xc0b<\xb3-\xd1\xa5\xe1RF=\xeb\xfc\x9c\x10t\x1b8\x95b\xcb!\x8c\x1e\xe5(h\xd5\xc5\xbc\xe70\x82\x99P\xc8\\U\xdeva\xe5\xb8RA^,\x1c\xa7S8\xd5\xc5[\xe7O\xe8\x1f\x16\xac\x0d=O\x11:\x821\xb3\xa5\x92i\x01\xe2\x91:\xca3V\x11\xf5B\x9f\x0c\x91\xd0o6K\xae\x1c\x0eL|J\x13\x15\x88\x88|\xcan\x0d7\xb9\x9f\xc8\x8d\xd4\x01{\x03\xaf\x91 \x97\x8df\x8fX\x8c\xadCg\xf7u\xe8\xe7\xf1|\xce\xcf7\x9c\x8a\xf9|\x88\xa2\xef\xa63\xc1i\x84^\xcd\xcd&\xa3\xa5G\x9bR,\x05\xfd\xfb-\xbb\x82X\xce8\x9dn\xf0\x9e\x8a6,\xb6(}[\x9d1\x10\x92w\xc4n\xbe\xd1\xc5\x8b\xc7\xd1\x94\x8a\xb0\x91\x03A\x11\x927\xd0\xcd+{J\xe5\xe4\x81\x88K%4\xfa\x1c\x05\xe3q\xc4]\xe40ie\xdcM\xd6x\xeb1r\xa1\xaf\xbb\xb7\x87\x96\xb4\xb8h6\xaem\x96kc\xc3:\xcf\xf8\xa6eg\n\xc4\xac\xf1~\xe2U\x1e\xd1\xa2v\xdd\x0dt\x82r\xe3\xa0\xbc\xa0\xe6\x15\xd1\xafc}\x1cx\\\xc5Pc#c\xb6!9\xd5\n\xbb\xebH\xd8\x89\x85\xc0\x13\x08\xe9r\x13\x07\xa21\xa1\x0f\xcb\x17\x1dI\xcd%8l4\xc0\xe0\x15\xec2+\xaf\xb7w\x82\x847\xa0/\xb3\xaa\xf9.\x8e\x0bC\x8e\xb6RnJ\x15\xb7\xc9\xaac\xa9\x9b\x80Mnl-\n\xe2\xb2\x08\x92\x86{F\x0d\xf7\x8a6\xb9\x89Un\xaf\"\xaf\xdc\xbf\xf5\x86\x9bVu\xad\xbb%\xdd\xd1\xfd\xfa\xb2\xd1\x8d\xaa\xbf\x14\xfc\xa4\x9fue\x16L\x98\xf7\x1d\xfd\xaf\xf7\xba@\xcch$\xb1\xab:O\xc6K\xe7vP\x85S\xc62\xb7#GGx\xe6\xb6\xec\x0b\xcd\xbc\x08o\xec\xaf\xde3]\x9c,\x1d\xd7_\xa1\x16\xaeb\xccU\x02\xad.3\xdbgq\x88\xf3C#\xadTn\x8c\x08\x9f%:\xa3\xdf\x81\xfb\n\xcc\xdc\xd5\xa9\xea\xd3_\xa3W\xd5\x88\xcd^\x9e\x9b\xb0\x12\x99\xb8h\xaf>p\x80D\xf7+i\xb05\xdeG\xd2\x0b\xe8,d\xa7\xe3\x10-\xcf\xf4o\x19%\x1c\x91\xf4\xce+\x19\xa5\xd5\xeb\xfb\xef\xdd\xedN5\xa8\xf6B}\xd7\x86iy\"~(\xce\x14\xcb\x8aC\xa5\xae\x8b ,\xc5]\xb9\xefQ\x88\xadS\xffX\xa3\x1d(%\x94\xbb\xe3\xa1.`\x9a\x8d\x94\x8a\x07\x0f\xd4\xed\x8d\xce\xd1B\xb3\xcc\x04S6\x92y\x1cUrq\xd5\x9d\xb6Y\xe8v\x14\xddq\x0d\xc7\xa8Gv\x99\x8ax\xea\xb8\xf0\xbd(Z\x12/\xb4Q\x94!E\xb8e,\xc0LA\xe8\x15\xfd\x10c\x96\xf4\xbcG\x07N7HI\xec\xa5\x91>\x90\xe3\xb1\xde}|O\xb9\xcd\xc5\xf6\xe8\xa0\xba\xa3=\xfd\xd6M\xf4\xead_\xbf\xff\xe7\xbc\xcdj\xe5\xcb*^mt\xacV\x0f\xcb\x8b\x878\x8cj\x9e\xcb\x87Q\xf5)\x1e\xe64\xf1\x17\xdf\x1bO\xf2\xe5\xa3\xfa\xb6\x9b\xa8\x10K\x8d\x1e\x94\x8d\xa6\xa4\x17\xb5\xa6$\x0c\xb2T(\xe6\x13\xa6\x98\xf7\xed3\xa4A\x9e}\xc6\x83#\x02\x8f\x16\x8eh\x8e\x0bG!\x11\x0b\xf6\xec\xe4q\xf2\xca\x95\x1bb1\xe0 \xe8\xcc$\xee\xa1S!\xde\xa0\xe1\xbb\x93y{\xda\x97P\xc4\xe9\xa7$\x85a\x11\xbf\xb9\xcdo\xeb\xd1\xf3\xb9}S\x928\xfa\x0e&+\x1bA\x8a\x17\xd1o\x0c\xd2\x10;\xd5\xd1V\x1b\xa4\xf0r\xed\xa5N\x95B\x8c\\R\xb1&t\xe0\x86\xf9\xf2\xa5Z\x07J\xf1\xe1#5$\x0cU\xa0*\xe4\x06\xb3\x05~\xc7\\\x08\xe7|\xa9\x98\x91A\xb5M\xd8\xef\xb0\xbb\xf1\xd48\x178\x0f\xe7\xe8\xe5\xfa\x8e_Ge~4\x94`\x8a\xf9\xa1\x07\xe4\x0b\x18\xc19\x06\x16\xb3\x8b\xc9i]tgQHN\x1c\xb4\xbf\x9f\xc1\xa9\x10\xe2\x983\xf0\x05\xd3\x98p7\xf6\xfc\x17\xe5\xdf\xf6\"\xd7\xa6\\\xbb0\xb3opg,\xf0\xae\x15\x9f\xe6\xebj\xa3\xed\xb6!a\x16]9Mv\xa0\xc2\xdbs^\x83\x0d8\x03\xf2\xda\xebF\x8f\xe3uQoW\xc1\x89k\x8e\x10\xbfz7\xa4\x82]#\x05\xbb*\xc7\x92\x1c\xa9\xb6\xc0\xa2\xd8vx0\xdb:\x9bt\xd5\xd8\x0c| f\x8c\x07\xd8\xb3\xa2\xfbn\x8d\xccW\x89\xb0\x1b3\n8\x1b\xa7,\xcb\x1f\xcb\x9e<=q\xa0\xdd\x8e\xb5\xd4\x0b\x8b\x8e\x80\x17\x9d\x8a\x9c\xab\xf6\x9a\xa9]\xac\xef~\x17\x03\xab\xb9\xe0u/\x13.:\xd5\x1fI\x0bo V\x13\xd3\xb5\x10\x17<&.\xe2\x93~\xf5\xb4Zry\x97\x83\xd8F\xb52/J\xa4J\xc4\x08}y\xfa\xf9\xf9\x8c\xb00\x94A\x14\x9e\x9f\x0f\xc1\xc3\xd0\xa2D\xe7\xccw\x1ez+R\x94\xb9\xb2\xab\x0e\xd0\xef\xcb\xea\x91\xb9\x1dT\x9b\x9cG1}\xbd\x1e\xcb\xf8\xa0\x17\xcc\x0e\x86\x7f\x86\xec\xcf\x08\x02;'\xe8\x8aR\xa4\xf4\xfb-\xb9\xf9x\x93\xc6\x0c\x8e\xe3\xb8\xf9\x08\x04!$(\xd3.\xcc:\xfc\xc5\x98L\x99\xa7s\xce\xc1Hm\xd7\x16^\xf2\x92c\x89\x98\xcb\x98YA\xa4'\xcc\x9f\xcf\x92 J\xaa\xf4 y\x8e\xaa\xaa\xb3\xb5H\xf6R\xa9N-\xc0kU\x1f\xa8\x95s6V\xad\x92\x83EE\xfc\xa7\xf2\xfa\x8a\x92\xc3\xca\xbb\x08\xe3/\xe2w\xe5-\x9e\x13\xa9\xf2\x9e\xc8\x9a\xc4\xde\xe4\xbf\x94w\x13\xe2\xc5J\x93\x0c\xc8\xdfd?\xd4\x17\xd7\xc4\x0fHR}\x93A\xc5\xab\xec\x97\xe6\xdde\x90*o.\x834\x7fo\x19\xa4\xca[\x92\x08PyWz\xc2k\x90 \x9azrAA\xa9'\x7f\x92\xd7\x93C\x94z\xb20\xf1\xa35E\x83\xea,HOx=\x12\xa4\xe4E\x82$F\xa2J\xd5\x9d/\x119\xdaFU{.\xba'\xda\xaf\xb5 \xcb\xba_A\x95*;\xae\xd2\xb1\xc0\xdc1\xb9\xe5MZ\x15\xe4\xdb\xc6\xec\xedL\xef\xd1\xad\x90Qh\x83\xe5(\x0e\xa1\xa5\xdfx\xa4x=\xdf\xb4\xd5\xa4\x92M\x0b\xd4Q.\xcb\xa3\x0cddr\x9b\xa6U\\>\xe1\xed\xe8\xb5\xa3\\\xee\xae\xe4\x86\xc7\xe0\x189\xc6\xd9r\xa7\xf4\xbd\xca\x11\x11{\xe5[\xae\x98S\x8b\xbd\x105\xbf\x10\x94\xe2\xf0\x97\x04f}\x15\xe5\x99\xd0UQH\xe5\xf7\x89\xa5%\xe9g\x8f{[G1b!\xcfP\xdf\xa0\x93\x1cR\x8c\xea\x9f\xcb\x0d\xfac\x90\xd8\x1c\xc52\xdc}4\x9b\xf5:?\n\xb1\xab>Z4\xb9\xbd\xa5\xcf\xe54\x05\xac\xecY^\x16#\x98V\xb3\x18\x9e\xf2\x8b{\xb4\x1d~'\x8ecj\x87\x87\xfe\xb0\xa3b\xd1=\\\xf4\x80\xa2=\xf3\x93\xc5X&\xe3\x1e\xf7q\xc7\x07\xf4E\x17\xbcq\x9f\x03\xbf\xc5\xae\xe7}\xefO\xc7\x11\xe2xvr\xaf~;\xae\xa8\x8c-\xe0\x1d\xf0\x97k8\xb5\x99\x16\xd5\xa1n\x17\x1b\x83\x07\x8f\xa9\xc1\xe4\xac\x1e\x93=\xee^^\x8f\xebyn>c)\x1f\xd9\xc1\x06{\x81\x0b[\x19\xc5.\xf3f\xa0\xaf`\x1a\xc0q\xb2 =\x8d$,\xdd\x9c\x9eJ\xd2\x7f\x86\xe8\xe0\x8d#\x89\x9e\xd6\x93R\x9f!J\xc6\xe24\xb1\xbe\xf6\xa7\xe3\x00\x91.\xba\x03a}\x90\x9e\xe5\x17q\xf3\xce\xd0\xf7\x85\xdf~\xe0\"B\xd3g%\xd0 \xb4\xb0\x18\xb7\x7f?z\x04\xbe n\x0e2\\\xbf\xbb\x8e\xd6\xb6\xe3\xb2E\xe1\xbf\x9c\x0dj\xdeb\xbbH\xd7\x016\xd9'\x9b\x86_\xe1r\x8a,\x97\xa8\xd5\x7fG\xff\xeb\x1eRY\xc5\xf0\x7f\xcco'\xb2\x90\xb4]\x0ci\xc7\x83:\xdf\xe7B\xe2VB\x9c\xdc\xf66G9\xb4w\xa7\xf6W\xef\x91P\xa6\xf6+\xef\x15\xbb\x83\x98\x16I\x1e\xe0\xe1fk\x03\xa9\xbf5z\x18=XYt\xbe\xe3\xb4n)\x1bW\x89\xe4C\x88\xc5\x12\xb9 .:\xc2\x19\xbc\xe0\xca\xc2[PHi\xe18\xd8h\xd7\x95\x85\xac\xa6\xe0\xa1,_6K\xac\xe3B\xc8~\xb5\xdb\xa9\xf3\xed\xf0BIc\x85\xf9\xa3\x90\xf1\xb7p\xa0\xec\x0c_&Va\xe9\xb7\x86*<\x0c\xd1\xd1\xc8+\xdf\x02\xbdy\xc8S\xa0^\xc9\xa0G\xf5\xd0(\x8a\x9a\xe48\xcd|hJF\xf7\n\xc7\x15\xcd\xe09\x82\xb8\x10\xa1\x7f\x01ECM\xd8\xe4\x0dh\xe1F\x18\xce\x8e\xb9L\xcag\x83\xa5d\xc9G5\x00\xe1\xc7\xbb;\xe3<;C\xf9x\x86j\x16M\x136#\x9e\xcb\xf3~\xf3S\x1aC\xfel\x0b\xe4\xe7\xbdi\xd5\xf6\xa6\xe1\xc8@\xe4\xe6=U\x90\xf54\"\xb2W\x16\x91\x93\xb2\x88\x9c\xe4\"\xb2W\xfc\xd2\x88\xc8j\xcd\xc6\x9er\x89\x98\xae\xd4\x86\xd3s\x0f\x96e&\xe4p\xc7\xed\xe5\xcaD\\\xed\xeaw\xf4\xbf\x1e\x86\x07j\xef;\x85v\xff\xb8\n\x8f8\xfcH\x7f\xbfM $..\xcfT\xef\xe0$\xa6\x8bo\xe5b\xdb\x05\x0870mL\x15\xc1\x93\x184\\x\xe7J\xd3\xa5\x0bk\x17\xfd+\xe7\xdcAQ\xa5/u\x0f\xaf\xd0\xba!\xc2\xce\xa9\xcfo\xf0\xb9\x08\xc1X\xc6\xe8\xe2=\xf4\x08\xaf\x97\xe5\x84\xa4QD\x17\xd6\xe2V\x8c\x91\xa1DJ\x07\xbcVj\xd4\xd4\xebC\xad\x80\x88\xd7\x1737\xbb$\x17\x9f{.t\xfa\x945\\\xf1\xcb'\xcb<&\xc2\x9a6\xab\xda\x9c6rX\x8eli\x02\xe1\xaa\xc6o\xf9}e\xfa\xa2P\x04\xe9m\x9e\xbb\xda\xdb\xed\xda\xfb\x93\x90\xbb\xbbI\x11\n\xb4s&;\xee\x8d`\xbc\xc0\x88\x15\xa1p\xe2c\xd4=t\x98\x0d\x0e\xa7V#\xbd\x89O\xcc\x18\x12\xdd\x95KF'\xd6LZ^b\x96|\xe1\x92\xdf\xe0D#>(\x7f\x98\xe9\xa8.R\xec\x8c'4@~=c\xc17\x8a\x80\xc8\xb8\xb7X4\xd8\x88\xf1+\x1e\xcb8\xc6T\nQ\x98\x92\xeb\x14\xf30\xc5\x97\x89\x93\xfbo\xc6,yD\xc00%*P\x88\xae\x89)Et#id\x99\xbe\xf9\xdej\x8a\xc2q\xc5\xeeEr\x9fp\xe3\xa6\x08\xe9\xd0\xd3rV-\x1e\xfeCT\x0f\xa9\x19a\x84\xfc\xccD\x8a\xb4\x1b\xcc\xcc\x9a?\x1e \x13jS\xf9\xd3\x82\x9c\xdd\xd1\xdaXO\x16\xe3\xa4\x08\xda\xcb~\x04\x85MF\xe9>\xbf3\x86X\xa1\xf4\x8a\xffX\xe2\x8f\x9cq\xc5\xdb\xf5e\x81\x0eZZ\x94\xc6\x1b 6-\xc0\x88\x8e\xc3\xa9\x0es*^8\x90u\xe9\xcf\x0dD\xa1\xc4\x9esa\x85\x8b\x14Z \xa5qJ\x12{\xad\xe3\x0fj\xefs\x1a\xc2\xa8\xa2\xe8\xaf\xf9x\xa6\xbd`\x9b\xe1M\xfb\x0d6\xc5g$\x8d\x03rE\n\x8a3\x8b\x08#D\xc1j\xbd$T(\x12h(\x90\xf8\xb1\x96*\x89\x0fk\xda\x9e\xbb\xa0\x1bqe|9\xb5\xff\xafq\x9c\xe5\xcdj\x1aoM\xdf\xf8\xfb\x0f\xd6\xbd\xbc?\xdb\xf5P\xac\x08\xe6n\xe0oh\xd1\xb1\x04)\x04\xaf\xaa\x8a\x81\x85\xca3q\x1a\x93\x8a\x01\xf9`\xbb\xad\x0f\xeaW\xe3\xe7D\x19\xc0R\xfb\x12\x88\x03\xfe\xa64I\x7f\x8e\xc7\xc1\xe8\xe9\x8e\xbeM\xcf\x8e\x1c\x93\x8c\x1f\xe1\\cVF\x9ct\x84x\xb3\x03I\x1elH\xf2\x7f\xd5\xefa\xe9\"\x1asj*\xee\x84y\xccO\xb1\xd5\xe9x\xe2\xe4R:\xac\xb4z\x98\x9fP{]L\xc3\xbf.I\xfa\x19G\xd0\x1f\xd38z\xc5 <\x16LV\xb3\xfd\xef\xa7\xd4\x92\xd2\x0f\xe96X\xe8B%DsXD\xecm\xf1\x88\xbd\x04\x86\"\xa5b#s@\xaf\xb2\xee\xf3\xb33\xba\x1c\xf8\xa5K\x12\xdf[\x17\xfaT\x19\xa8N\x95`,\xcd,H\xc4dP2z\x19\xbc\xd8\xfef\xd1\xec\xdf\x84\x98\xfcl\x16\xc4$\x01\xaf\x08}g\xf4X*\xc5\xbb\x96\x82L\xf1\x10La\x9ea\x81\x12\xcfN\x9f\x1d\x83)ya\xa2t)[\xc2 \xb4\xdb\x01<\x81\xf8\xc4\xc1\x19\xe6\xf9{\xe4B\x01\xde{\x8c\xa0Mg\xff\xe9\x08\xfa(\x05S\x01d\xb7\x8ftgp\x08\"\x03!N@\xc0\n<\x1d\xc1\xdeQ^v\xff\x10\xcb\xd6=\x7f\xf4\x08\xf6\xf6i\x81\x8c\x12\xc6\xc9\x04\x83F\x15\x96\x89\xfe\x01Zr\x80\x12K\x1b\xfb\x1a\xb0*[\xfdJ\xd8\x01\x82uup\xc4\x1f\x88\x0e\x1e\x17_\xf5=D\xe8\xc1~\x0e=\xee\xe5\xd0\xe3\xc3\x1c\xda\x1f\x0c\xf02(\xce\x13\xce\x11\xa5\xe0\xac\xcbe \xce\x9b\xf5\xff\xfe\xc5\x9fY\xb5\xfbPuz\xd78Q\xc8\x18\x8b\x1a\x18\xf6\x0dO\xdan \x91Y\x8a\xcfJt\xe5r\xec\xeeX\xd6\x1b\xbew\xf2\xdb:\xa1\xdd\xef\xdf'\xb0\xa76p=\xad\xd8:?'\xc9\xa7\xd1,[\x12\xabJ\xb5y\x9a 9\x8d\x82\xc3T=\x98K\xaf\xceQ\xc5x}9I\xbd\x94|\x7f\x99]\x06a24l\xdadM|\xd33\xfa\xf1\xb0\xcdd\x08\x99Y\xc8O\xc8\x92\xf8i\x14'C0\x04c\xd2\xbf\xcbR/\x19\xbb\x068\xb6Y\xe6\x13Zs\"\xa6\xc2\xdc\x8f\xbc\xaf\xd1F}\xf5\xf4}U\xf1\xf0;\xfa_\xefU\xf9mn\x87\xf6~\xffX\x89\x90\xcd\xed\x0c:\xbb\x84o\xd3'{J\xa0e\xfeh\x7f\xaf_}\xe4\xe5\x8f\x06J\x90i\xd1\x87\xbd]\xc79\xf9N\xfeL\xe0\x0e\xf8z\xc5O\xca\x98C\x81\x9f\x05s8\xa9\xa0)\xe3\x06_U6\xa7|+G\xa3\x10\x93b\xe6\x05!=\xb65\x1c\xac\x0bC\x1d\xa7eEF$\x93\x19\xbc\xd8(i\xd9\x8fC\x9d\x84\xb9\xd1\xbdB\x99\x07\x1e\xb4X'a\xb1\x1c\x97\xd5 \x93\xdfQ\xbf\xd1q/\x95[B\x97$\xfd$\xf2\xbd\xe5s\xdc\x04\x9b\xc5\xfa\xb3{\x18\x8c\xd8\x8b\x13\xf2\xd3\xde\x8a\xbf\xea\xd8\xb1\x18\xfcv^\x0erC2]|\xdc\xe9t&a\x16/\x87`-\xd2t\x9d\x0cwv\xd6$M\xd2(&\xdd\xe4\x9dwyI\xe2n\x10\xed\\\x0dv\xc4\xaf/\x92(\xb4&\xe1,Z\x9d\x07\xb3!X\x7f\x85?\xe8d\x815 \xd11\xddK\xa3\xf8\x07\xa5:\xa3p\x19\x84\xe5\x1aEAk\x12F^\x96.\x06\x9f\x91Y\x10\x13?-\xde\x1c\xee\xec,\xe9\xbc-\xa2$\x1d\xee\x0ez\xbd\x1dV\xb2\x13\xf3\xa2\xddE\xbaZZ\x93\xf0\xb1v\xd0\x1bQp\xc9\xb5c\xd07hR\xe3\x87\xa9^\x7f\xdc\xdb\xdf\xebi\xb7od\xc4\xdcZ\xf4Q\xbcH\x85\xb5\x120\xfe\xa6\x88\x15=#\xeb\x98\xf8^Jf\xe0\x853\xc9\x91&K\xc8\xac\xdb\xe0C\x03\xf2\xfct\xa9\x98\x87#\xe9\xc9IK\xbbg\xfe\x82\xac\x98uu\xf7\xa8\xf4\xe4\xe3g/?9{\xf6\xf1\x8b\xf3\xb3\xe7\x7f\xed\xc5\xa7\xcf\xb8\xc1vP*\xf3\x93g\xaf_\xc9\xcf\x07\xbd\xdd\xd2\xf3\xe7\xaf?{Q~^~\xff\xa3\x17\x1f?\xfb\xc1'o\xce\xab\xed\xec\xefj\x8b}\xfc\x83O>\x91\x8b\x1d\x95\x8b-#o\x86\xa1\x02\xe8\x97\xea\x83g\xf4P\xc1\x9f=c\x17\xce\xc4\xe3\xc4\x9b\x93O\xc4\xbb\xe2\x87\xae\x80\xa8C\xfa-\x17\x9be\xab5\xc6\x0c\xa4_\xaa\xef\x7f$\x1e\x8a\x1fr\x81\x9f~\xf6\xe9'/\xae}\x82!\xe89\x1e\x96\x86\xf6\xe9\xcbW/?}\xf6I\xddZl8\x87\xe6\xe9K|/D\xd5\x81E\xbfY\xa5gH\xe1\xd8C\xfcZ~\xeaG+\xee{\x12\xd9\x16\xffQ.\xe1\xcdf\xcf\xa5\xf0\xe1X\xb0\x0c\xb3\xee!\xdfI\xfe}\xd5\xab\xfcA>\x9b%0\xbfD\xa5h\xa0\xb3|\xeaJ`/\x9f\xaf\x128iVH\x97_\xf0U\x85\xf2\x1cF0(\x83(\x92\xed\x96A\x14u\xf6\xca\xa0\x85Z\xd7L\xad\xebJ\xad\xeb\x86\xb9\xc2]\xf7z\x9d\xc9u\xefhr\xdd\xfb\xde\xe4\xba\xf7|r\xdd{\xd1\x99\\\xf7?\x9e\\\x1f~\xdc\x99\\\x1f\xedM\xae\x8f\x0e:\x93\xeb\xe3\x8f'\xd9\xc7\x1f\x7f\xfc\x02\xff\xffxz;\x9ed\x1f\x1d\xd1\x97\xb3\x8f\xbe\xf7\xf1\xc7S\xfb\xb4E!\xcf\x19\x84\x96pn\xed\xd3\xe1\xf8\xf3r\xb1\xdb\xcf\x9dJ\xb1\x9dr\xb7.y\xb7\x8e\xf6\xcb\x1ez\xe5R+,\xe5N\xc6\x93\xe9\xe4\xab\xc9\xfb\xea\xe3s\xfa\xf8s\xfbt\xd8\xbam\xb5n[c\xaf\xf3\xe5\xa43m\xb7\x9c\x0fv\x82r\xc9\x8b\xa2\xe4\xf8\xf3\xa2>\xc7>\x1d\xfe\xc4\xb8\xd79\xf6:\xf3\xe9W\x83\xf7\xb7\xec\xfb\x97\x93\xce_9\x99\xecLN\x87\xdf}4\x9a\xb4'\x1f\xb8\xe7\x93n\xeb\x7f\x98|\xf8xbO\x1c\xfa\xf6\xd4\xf9\xf0\x83\x9d@\xc7\"\xde\x19YD\x9f_B\xc33\xe3.\xfb.\x11q\xb5\xaakcU\xc7EM\xbb\x83\x0dj:\xdb\xa6&\xec\xdf\xb6}}alao\xaf\xa8\xea\xb8/}\xdf\x95\x9a\x18\x94~\xeco\xd0\xe03\x83yG+\x9e\xee\x1d\xa1\xb9\x02\xa5K~\xd2>\xc5 9{G0\xa4\xc7\xea'\\\xef\xb0;\x80[`\xc9\x9c\xd91\xbb7@}O\x87\x16j\xd3i\x19B\xa7_\xdb\xb1\xd7\xe6\x998\xca\x15]\xd6\xa4g\xb1\x96s\xc8\x7f\x87\x00\xb9\xc8\x05\x85\xf4\xfb\x07\x12(\xc5BU@?_.\n\n\x19H\xae\xe9\nA\xbd\x81\x04\x9a\xb3R{\x12(f\xa5\xfa\x05\xe8\xbf\xa7\x90]\xe95\xd4}\xec\x16/=\xb6\x1e\xc3\x10\xf6\xa4a\xec`\x0f\xe5\x96&\x14r(u\xe7\xff\xf9y,\xb3/A~\x13\xcb\xc8#E\xaa@\xa1G\xbd\n\xf4\x98)\xabk\x17\xe1\x8b\x9a#\xc6\x93\x11\x1c\xec\xef\xef\xee\xc3)W\\a\x96\xe9\xe7\\\xdfd\xa7\x85\x03j\xf9\x01K\xe9\xd9\xa6\xa7\xb5\x0e\xd6p\x00O\x9fB\x9fJX\xfb\x07\xbb\x83^\xf9\xd1#:\xdf\xbb\x8a\x11\x15\xe4\xd3\xd8[\x90\x13\xd3\x0e\xf6\x0f\x1c\x17^j`\x9f\xb2\x84r\x9f\xc2\x13\x18\xec\x1f\x9c\xc0\xa7\xed\xb6\x03o\xc7\x9f\xd23\xd9k\xfbS\x87\xc7\x19\xe8\xb9\xf0\xb2\x00\xea\x88\xd3\x1b\xad\x1e_hb\xc9;\x08P\x01C\xdeQI\xb7;\x0f\x96$\xf4V\x84\xb2\xf6 \\g)\xde\xdb\x8f\x92 \xc5;\x96i\x97\x9e\x1fd\x18t8\xf0,\xf5\xe2\xb2\x9b\xbc\xda\x97\xe7\xda\xbe0Q\x99\xf7\xb3\xf6\xfd\xef\xeb\xdf\xefF\xe1\x0f\xbd8\x0c\xc2Kv\x96\xcc\x7f\xf2\xeb\xea\xe8y\xca\xeb\xd7-\x0e]\x97\xcf\x94\xd3\"\x15\xd9\x86\x8d\x16\x1a\xf1\xbe1d\x0b?\xa2\x8f \xed^\x918\xa1\xc3x\xf4\x88\xcd\x845\xcb\xd6\xcb\xc0\xf7R~3\xf5'h\x93\xc0\x8eT\x98Q\xca\xe5\x91\x0fC)`\x15{\xb3\\\x12<\x9f\x8a\x96 \x90k\xcfO\xf1b*\xc9U\xba\xb4\x9a\\\xe3n\xc7\x8c+R\xa67m;\x93\xae\xf8\xf6\xc1N\x97\\\x13\xdf\x0e\xc7=\x1e\x03\x8d5\x14,\x97\x9dy\x14\xafdw\xffh\x0e\xe9\x82\x80\xda[*\x8b\xa1\xf4\xf82L\xedx\xdc\x9f\xbal\xafDe\xf8@\xc0\xa5\xb8\x8e\xac\xb5,d#\xc1lhX\xbf\x983\xde\xe6,\xf2\xf3A\x15\x13:\x82\x90E-\xef\xfa\x0b\xe2\xbf\xfd$\x08\xc9\xf7b\xe2\xbd\xa5\xe2[Dw\x90h\n\xef\xdc\x0e\x8a\xaf\xdf\xe7\xad&\xd9\x9a\x8a\xb1d\xd6\xd0hiu+*\xb67\xcf\xfe\xeav\xe8\xa2\xe2\xca\xc0\xb0\xdao\x9e\xfd\xd5\x9a\xc5N\xdfE\x85\xfe\xdf\x12\ny\x16\xd1\x0e\xbf\xd1u8\xef\xa6$I\xed\x18\x03@(K\x9bz\x97\xb0\xf0\xc2\xd9\x92\x80=\x0f\xe2$\xcd+t\xc4$\x94\xfa@[\xc9C*\xa4\xde\xe5\xa7\xde\xda\x85\xb8@\x9b\xc7\xe9\x82\xc4\x84\x1ep=X\xc7\xe4*\x88\xb2dy\x033\xe2/\xbd\x98\xcc \xc9\xe6\xf3\xe0\x1a\xa9\xa2\xf5\x18\xda\x10C\x1b\x1e[R7\x1e;.\\\xb0.\x07\xe6.\xafcB\xab\xb1\x13\xe2G\xe1l\x83>\x8b\xce2\xbf\x87r\xe0\xfc\x92\x96Q\xa5=\xaf\xc4\x92\xe2@U)\xa4\xc8\xdf\xaa\xaa\xe9\x08<\xd1\xa3\x02\xbac\xb0\xd8;\x94\xd8\xf2+\x1e\x888\xb4\x19\xa5<\x08V\x120sz$E\xf5f\xf9\x08\"\xfa\xa7=\x82\xbe\xc3e\x06t\x0e\xf0\xaa\xb6\x15&\xfb=\x19AF\xd7,C\xb9\xa7\xdf\xdf\xeb\xf7\xfb\xc5d\x93\xeb5\xbb\x83\xcf\xa2\x1c\xfc\xe4\xd9\xebW@\xab\xf1\xfc\x94(\xb90A\xdc4\xbca\xab\xe6I4\x84.E\x92\xc6\xc4[\xa1\xc3\x81\x17\x84 \x84Q\xd8Y\xc7A\xc8\xb6z^m\xa2\xab7\xed\xc6$\xc9\x96\x98/\xd53\xad\x99f\xc9>)\x96Lqo\xb9\xe2 \x04\xd0-\xac\xe2,\x833\x1cw\x83\x84\xa7\xdb\x0f%\x0c\xe4\x1a\x9a\x15\x89/ \xac\xbc\xf5:\x08/\x93\x13\xc4\xb6u\x1c]\x053\x8a\xddQ\x16\xfb\x84\xe7o\xa6\x9b@&k\x96\x93\x87\xd8\xa4\x87E[\xf2*xKn\x12;t\x9c|A=x\x02>\xfd\xc3\x164\xc3\x80\x8f\xde\xd4\x95\xe2\x9ce\xd87\x9b\xb0\x90\x94!\xfa\xdb\x04\xecG\xabW\xcfM?\x920Z\xce?\xac\x9b*\xdf\x85\xb9\x8a\xd7Aa\x08\x0cd.\xc3S\xf2\x08#\x91\x95z\x97\xc3\x1bo\xb5\xecF\xf1\xa5;\xe8\xf5\x06C\x9c?\xe6q\xabAsZ7\xbb\xeb\x18$L(2E>\xc0\xa5\xe2\xae0\xf4\xa0\x1d\xe5s\xe7\xc3\x13\x98\xd3?l\xee\x04.Dc\x1fS\x90\x1b\xb07/\xa6\x96\xc1\xe7)\xea]\xe9\x94'y\x8cb\x9e\xde\xa9X\x13\x06\xb0\x99\\\x04t\x8f\xdd\xde\xeaD\xa7\x11x\xecI!`\x95\xe5\x022\x13(\x06o\xc9\x0d&\xe0#\xe3`\xcaB$\xe5\x97~\x83\xe6D>\xea\xe2\x7f\xb9\xd1Y\x8a\x1f2p)\x05\x8d\x92(I\xd1s\x87\xdd\xe8\x12?\xdbmz\xac\xd8\xe5\xc8p\n\xb6\xfc\xc8\xcd\x8f\x9a\xb552Y\xaex\x8d\xca\xe8lz<\xc0\x89\xbd\xa0,\x9en/A\xa8\x18\x85\xc7gmt3\x92$S\x1c\x80\xa8\xacvf>6\xf1\xee\\\x86\x97s\x0e\xd5\x0e\xe1\x84;\x10\x04\xda\xb8\xac\xdc+\xeb\xda\x0e\x1c\x1e}TS[\xbb-\xd7\xa7\xdd)\xb8\xdbv\xd9\xd1\xca\xe0!7\x8bj\x0c~\x9b\xb4\xac}\xf9=\xbc[\x04Td\xe8\xf7\nA\xae\xbf[|\xe7`C\xbf[\xef\x90\x15\xe12\xaa%pv\xbeD\x07\x83\xe6\x89v!\xa6x\xc5\xd6\xfbe8\xa3R*\x9e\x9f\xf8A\x96.\x80\xfc\x90\x16\xdez\xd8\xefu\xbb\x8c\x87\xb0\x0d\x8b\xe1\xc6\x0cq\xa5\x9e\xcd\x0c\x99\x06\x8f{\xc16\x08\xe3\xbe?\xc5\x89\xfb\xd2\x85V\x1f\xbd\xe3\\\xd1\x94@\x0e\xa7\xdc\xbfM\x1aw\x0bf\x8f\xb4 g\xf7|HO\xb9\x83\x10\x9f`\x87\xf3\xb1\x0bo&\x13\x01zj\xf1 !?\x9b\x91\xd0'@\xc24\xbe1\x8a\xd9\xcc\xc7\xacDd\x88\x96\x96\n\x12\xd0\xf28\x8e\xd0\x83\x13Kd$p\x07\xc5\x89\xb4\xfb6\x08g0\x02K\xf4\xc0r\x8b\xcd\x841\xc6\x9a\x04\xca\x9f6\xd3\xa8\\\xc4D\x8c\xd6\xef\x80*\xa6\xd3!\xee\xee\x16\x11\xc2\x1b\x04\x90\xdc\x7fBW\x8f\xb4a\xe8\xf8M\x1a\x18\x8f\x1f+\x99i\x87R\xe5\x03.\x01m\xc2-0\x12m\xc41~\xb3\x17\x86\xb0\xcb\xa4\xa4@D\xb1\xc58\\t\x19Z-k\xf3Z\xd8\x1b\x16\x0b6 \x0b\x94\x91N\xf20\x8a\x03\x9b4\xa7\xbc\x98\x8b\x01\x92\x14p00\xb2~\x89r<\xc9\xb3\xf8\xd1\xd1\xc7\xba\x83pi\x97m\xd2\xbdBL\xcc\xc2\xfc\x04K\xc2\x99\xd0 \xf0\x83\xe8\xbb ]\x04!xpE\xe2\x0b/\x0dVt\xe5\xab\n\x1eS\xa8#.\xb9I\xe3m\x9d1)._M\x96D\xe0T\x9c\x80\xbdK\xa1\xf3\xe0\x07H~\x10\x06r\xed/\xbd\x15C\xc0\x95\x17\xbfM\xac<\x0eqe.X\x16\x85\n\xdd\xcd\x15;\xf2\x195\xf4*:\x9dJ\x9bI\xe6/JGn\xe6\xa5I1\xaf\x8c>\x8c\xb4o6\xef\xeaB7\xaf\xe7*WJ\x15\xba\x02\xe3L\xcd\x97\xd1;J.\xe9v\x8d\xe2R\xff\xcb\xab\xa6#\x7f\xc8\xc8Z\x17\xfa\xf60\x99u\xfd\x1c\x0d\xd1m#F]\xe6)\x08\"\x1a\xc3PU\x83\x85\x8eT\"W8\x85STs\x0d\xe9.\xe5\\\xa2(Ea\xe2\xa9\xee\xb1z~\x16\xe5\x99\xb6-\x0bs\xcd\x9a\xb4\xea\xa8Y\x0bQ\xb3\xf6\x18=\xc1k\x89\xf7\x0f\xcd\xc4[C\x96\x8f\x18Y\x0e\xefA\x96\xcd\x82\x8c\x9e4\x87\xc0K\xc8\xe4\xd9\xd0\x81\x12fV\xb1Zl\xdc\x90o\\v\xd4l\xbd\xb0C\x07\x93\xc76\xd7\xa8\xe5\xb0\xd2\xb6\xc9u \xc5~,\x0f!\x8cf\x04VYR\xe0\x9b\x97\xc2\x92xI\x8a\xaa{I\xcbVb\xd3\xf5\xbb\xa9a\x81\x7fJ\xd2\x86i\xf8\xc2U~I\xf2\xc6\x85K\x17V.\x9c\xbbp\xe1\xc2kf\x8c\xd20\xed7\x06f\xfe}\x033\x97\x16{\x19$) I~Vb\xbfl+Zc\xd4\xd9T\xe8j\xa1\x88\x1e\x9d\xcf\x82\x00pyE\xfc\xcc%\x15\x06@\xb5'\x8c\xd0\x19b]\xc8eLA\x85A\xeb\x1f=R\x04Q\xfbM.\xaf\x96\xc578e\x93\x00\xc3\xca!\x93\x9f:\xd0\\W}\xf8\x84+\xc2>E\x97x\x07\x0d\x1e\xf4\x85O\x0d\xde\x9a'L\x82\xba\xbd\xc5\xcdx\xe2\x94\xbbwZ\xf4\xee\x86\xc9c\xdfJ'a\x88\xd5\xeb\xd6\x8f\x07j\x80\x11\xbc\xa1\x9d\x8cr\x0b\xce\xa7\xf4\xc1\x9ao*z\xea\xbb\x80\x11\xf8\xc5\xa4\xcfs\x92F\xf0<\xd6\xa6\x9c\xecu\x99\xd5\x94\xec\x88\xf9L\xc1)\xbf:\x8eg\xaf\xd789\xdb\xd8X\xdcB\xc9\x9b\x98Og\xc0=w\xcc'4\xe0^;_\xd5\x8475=\xcb\x91T\xfb\xf4\xaa\xf6\xe9M\xed\xd3K\xc3\x06\x04\xeeG\xa3\x0b\"|\x87\xf3\xe3\x92\xab\xac7;?z\xc6$D\x18\x84\xa8\xa9\x1e.\xd6D\xd2\xa1-\xab\xc8\xb4\x07\xecP\x80\x07\x9a\xfd#\xfe\xfd\xf6\x96\xd2\xf2\xb8\xf9\n%\xd2\xc1\xd0\xc5[\xaf\xec\x08h\xd4A\xc9\xefI\x07<\xadL-\x7fX\xaa\xdf\xa6\x91:'pm{t\x9f\x1b\x8a6\xc8W\xf2\x87\xf6p\x9f\xf9[x\x0e\x9c\x99\x1a\xafH\xca\xb9\xc4\xe8Q\x11\xfe\xffc\xee[\xbb\xdb\xb6\x95E\xbf\xf7W\x8cx{\x1c2\x92\x15I~$Qlk\xa5i\xd2z7ur\x9a\xa4\xfbt\xcbj\x16-A6\x1b\x89T\xf9\x88\xed\xbd\xdd\xf3\xed\xfe\xb1\xfb\xcb\xee\xc2\x0c\x00\x82$@\xd2N\xd2\xd6k\xb5\xa1@\x10\xcf\xc1`\xde\x93\xb2d\xe3\xcf\xb5\xdbG\x97\xad\x82\xbf\xe4%\x9c\x82\xfe\xc0\xae\xb7\xd1w\x02\x12\xb6\xf1c\xa4\xc6\x149}\xb6\x8a\xe6\x1f\xa4\xd4\x9a__\xc8l\xb9\xa8kX\xf5\xf2\xa88Z\xc4\x9b\x8f\x02K\x8b\xa2\xb5@r\x02\xb8\x91\xf8\xe4\xff.\xd4\xf9\xc5/$\xc2\xaf_\x97\x86\x9c\xcc\xf2\x0f\x01c\xad\xb9g\xd1\xd5\x93\x14\xee\x9d9\x07\x96\xfa\xee\xf8\x9f\xd2\x13aD\xd8\x98\xf9\x0b~\xf1\x07kN\xcd\x04\xa9\x12\xe8o\xfc ~\x02>\xcc\xa3U\x14\xf2\x95^\x07IR \x9bW\xfe3\xbbKC\x1d\xb3\xa2\xff}\xaey\x9a\xe6X\xdcz\x12_\xf0 \xae\xb3U\x1a\xe0\xd9\xf9\xc0\xaea\xed_\x830q\xd6W\x05\xd5\x1b\xf6\xb9\x19\xdf\x88\x19\xef\x13\xcb\xe5\xf3\x0b\xf2\xd3\x80Mp\xed\xe42yN\xedi08\xc8Y\xcb \x9cG\xeb\x0d\xea_\xd8\x95ec\xf9l\x91\xceS{\xfb\x04\xa2\x18\x96\xd1j\x15]\xb2\x05\x9c]\x83\x8fj\xd0\xd4?\xcbV\xa8\xeca\xebMz\x8d\xca\x0d\"\xfcr\x9c\xa8\xbc\xa6c\xf3\xc6P(\x11\x0dEYeP\xae\xa4\x037DZ\x04T\xca\xa7\xab\x1f+A\x06hB\xb1s\xbc\xd9+k{-b\xd9\x1b\x97\xb7(Hk\xc6\x88\x9e\x81\xa8Qr3\xbfVnV\x80;\x9b\x17c\x93\xe8\xac\xf2Q\x15\xf2\xc4\xd1AH\xb3\x01\xda\xba j\xab\x9c\xae\\\xd4&\xf1d\x81~\xc5\x16\n\xfd\xfe\x81\xc4O\x0f\xce\xbc*\x01d\xa3~\xcaZ]\xccY\xb3\xd4\x93\x88u,\xf9\xc6\x17\xf5\x84\xd2\xc7FB\xe9\xda\xe0\xad\x04\x02H\x859\xa8\xbbi\x86\x05\xd2\x89=\xde\xe9 98IbM\xe9\xc9k0\x1f\xefs8\"\x82ac\xe5EUmN>\x8f\xf6D\x8f\x03\xea\xf1?M\xfeip7\xb2*\xf6(\xc3T\xd3=- \xabM-a\xa5\x8e\x1a\xf3z\xad\x96W\xe8\x0b\xab\xec+i\xd2\x08v\x17\x05\xd8\xfd\xa8\xc1.\xc7\xb7\n~al\x13\x1b\xc7\xf6\xcb\xe4\"\xa7?\x08?\xc2>9\xc5\x9f\x04\xe1\xf9\x8a\xc1\xefY\xc4\xab\x8a\xbdGZ\xa2n\x96\x86\x83t\x1b6\xc3\xdc\xe9\xe78):\x83a95\xbb\x04\x1e-\xc4t\x9f\xff\xd4`\xe2m\xf3\xa9i1\x9eZ\xc9\x88\xf0]\xf5\xd5\xa0\x8d\x18m\xe0\x95\x87d\x03|\x14c\x8dd\x9b-\xce\xa2\xa9\xab\xcbv*\x1aO\x87~\xfb9TrM\x9f\xfcE9\xd0\x7f\x98\xfa3\xafp\xc1\x1c\xa3\xef\x88>\xc9\x16-Rp\xd1\x910\x83\xe3\x1c\x8b\xcf\xcf\xd2\x08]\x89\x1f*Vf\x17\xc6\xf0hO\xfd\xe4l\xc3\xc0\x83#\xfe\xbf\x16\xba\xb2\x80\x14\xda\x11\x19m\x07\xfc\xbb'\x10lo{\xd8\xfb\xd3\xb6k\xc5\x99\x14\x0c\x1b\x87~5\x07\x07\xb0\xebA\x172\xc5R\xa9\x13x\xc1\xae\xfc\x05\x9b\x07k\x7fU\xef\xd2\xa4\xff\xe9K\xf9\x9b\x1b\x95\xe0\xc5N\xb7\xd0ZJ,\xf0!\x8c.C\x10\x11\xd3\x94\xcc\xac\xa6\xeb\xea\xc9\xa8\xc7\xa4~\x8eI\xe9\xe8\xdb0i\xb5\xe1/\x84I\x17Qv\xd6\x06\x93\x96\x06\xd3\x82\x96\xb8\x0dj5\x8f\xc2\x88Z51NGC\xb26\x0c+\x0c\\\xcdXu\x97d\x18\xcd\x8a\xef6X\xd5\xd2H+s'2\x81{#\xac\xdf:\xcf\xdd\x98\xa3\xcd6-V\x07s+\x93\xa7U\xe0'\xb7\xb2x2\x18?\xf6\x8a\xa6N\x9aH\xbd\x14\x8eE7\x84\xbc\x97\x85J\x0c\xb0\x10\xe3(\x19\xc5iw\x92.\xa6\x0fge\xddU\x95\\\xe5`rWS\x14\x94\xba.\xa5\xbc\x95\xdf\x94v\xe1\x9c]\xd1\xcd\xc1\xeb\x8d\xbbl\x06,\xbe\"\xcf\xdd%\xb9}\x12\x92F\xa6w\xe7Q\xfe\xbc;\xd2\xcaw\xf2g)\xe8\xc3\x1f\xfbz\xa5\xc7\xda\xb3Vg\xe7\xa1V_+\x7fL\xa1\x1e\x96\xb5P\x8e7\xce\xbe\xd6\xbd\x10\x9b-IF\xff\xa6\xf9\x18 \xee\xec\xe6\x86\xec\xfb8\x98\xb78X\xcd\xe4J\x80\xbe\xe4ErWX\xad\x8b\x03\xb6\xac\xa5B\x84u\xc6\xb2\x89b\xb8\xe3\x14k\x98g-\x8f\xef\xce^\xdbA\xd4\x0f\x00}eZ\xf4\xd9$\x95h\xbcj\xf29.\x9b\xa5\x8f\xbc\xcdK\xac\xd8l\x05\xe1+1\x8bT\xd3h\xc6gsU@\"\x13\xed\xe6DdP\x14\xdc\x1c\xda\xb3t\xe9\x7f\x99\xc6\xbf\xdfYZ%\xfej\xe3\xb6\xcb?\xbb\xc0\x04\x8af\xf8\xc2\xff\x83\x8c\x078~\xd2wB\xe8\xaf\x0b27Kr\x01\xf9w\x179\x8e\xb9\x14\x15`D\xcb\x10\xfe\xec\x0c%-#\xc6\xbb\x0d\xbeWw8\xbd\x1e\\ \xcc\xe7\x16k\x08C3\xcbv4\xb8<\xd8n\xc4\xf2P;\x1d\x85F\xc8%X\xa0\x99\xa2\xc5\xea\xa6*Q!R\xa4'\xad( \xfd\xbd\x16 \x94\x07\xd0\x96\xde,\xca\xd8\xc0\x998(\x9b\xaa\xa9\xab\x95\x08\xcdnn\x07\x96\xdf\xd5\xc9E\x94\xad\x16h\xabs\xe1\x7fd\xe0\x87\xd7\xd2\xf2\x1a\x95\xb0\xd2\xdf\xbb\xb5\xba[\xe9\x15s\xd1\xd9\x8fjVh\xe4)l\xe1h\xf5\x91\xb9\xda\xd4\xeb\xf1\x84\x06\x13\xef\xfbs\x19;OwM\x93\xfb\xfc\x9e4\xccw\xdc\x82\xcf{~\x05\xb2\xcf=!\xae7\x8c\xbaFh\xbf\xb9\x01g\xe9\xafVg\xfe\xfc\x833\xeb\xc9\xed\x99\x80X\xb7\xda\xeaS\xac=+\xccT\xac\xd1\xd6\x16\xbc\xa7O\xa8\x18\x1f\xcd\xa1d\x10\xa2\xf1=\xdf\xfe\xce\x01\xc6\xe0\xc4\x95\xec\xc2\xbd#H\xfds\xd4< \x98?\x13\xbe\x13\xa2uN+\xf6\xf0 `i\x9a\x97\xdeC\xff\x9b\xca.\x93\xc3{\xd3N\xdeq\xebr#4\xa1'\x13\xdd\xa31\xd9\x82!\xbfS\x9a\xa1s\x94+\xe1\xd0\xcbI\xf7\x91\"~\x94W,\x7fdI(\xd5\xc2\x8a\x7f\xbe\x8a\x12&\xcc\xf8K'\x99_\xe8\x95\x89\xdf\xdc\xc0\xeb\xafr\xf8R\x8f\xcaw\xe1\x87v\x9e\x85\x1a\xfa\xaf\x00\xa9\xc9\xc3P\x90~Z\x18!\xe1KP\x0d#\x94\xf6W\xec\xdc\x9f_\xf7\x94K\x8f\xc8l\xa6m\x18\x99=I\xb1U\x0b\x97E\xdc\xf1\"\x9f\xd1\xfcU\x0f:nIs4\x10tw\x07-z\xcc\xd20\x9ck\x06\xed\x9d\x13m|d\xc1\xdf\xadMC5\xbc\xect\xd63\xfa\xba\x15\xd8=\x19\x0f\x05\x0e\xc8\x8d[\xb8\x07\xa9xH\xc8k\"kiR\x1b\xeb\xe6\xcc!PKNCd\x06\xf8L\xd1\x19\xa0\xa8\xa1\xad\xcd\xb1\xd4\xa8\xa3m3\x04;\xd26\xf8hR\xfc\x05\xfbUPC\xdd[gZ\x1b\xd2\x01\xe4\xb2~1\xc0\xe2\x7f\xb1t\xe7\xae\x81\xa8\x16\x04\x9d6&\xd2;\x8b\xeb\xed'\xe1\xe1\xf7\xd34\x9cI\x19\x1b\xc7\xa7\xaf\x85\xc4\x81\xf0\xa9\x12\x82\xe5`Z\x90<|e\xef\xbc\x88\x0f\x06\x1ak$\xce{\xee\x9e_\x8f(\xdaV\xa4x\x0e\xed+\x8f\xbcbD\x17\x11\xe1A\x1f7_\x90\xccpV\x13\x14\xd0\xad\xfd\xb8\x12\xb7\xe5\xe7\x9c\xa6\x17\xd3D;\x8d\x8df\x9cV\\\x98*\x92\xde\xda\x82sr\xf0,\xee}T\xdc{P\xa18\xc2(\xdc~\xfa\xe6\xd9\xf1\xb1\x16O&\x01?f\x10\x84)\x8b71C\xc7\x87\x04\xd9-\x15tNnmR \x1b\xd0\x82\x9f\x9d\xc0\xee~\xf3\"{\x82\x14hXa\xad\x82\xe6I\xbd\xadc\xc9\xaa<4\x8aQ\x16*\xc03\xf7\xe0(\xecG\xede\xfc\x9dk\x8c\xc2XL\n\xc3d\x86(~G\x0e$\xbd\xa0\xe2\xda\xc9\x901\xa5\x05\xc8\xa7\x80K b\xc9\xd4Wrs\xf3\x82\x1e\xec\xef\x8d\x1e\x8aX\xa9\xfaG\x03Y\x93\x97\x8b<\xfa^\x19\xf7Q\xb2\x04\n\xc5\xd9\xa8YK/\x82\x84\xb6\x100\xfd\x01\xfe\x96\xd131!\x92\xfa!H\x1eQ'\x91\xf1\xd8\x99|\xbc\xb9A\x9e\x9b\xbf\xcc\x03Y\x1eb\xda*\xf9\xab\xd8\x04Q\"XE<\xde\xdc\x90\xd5\x02\x7f\x8b\x01\xaa\xf8;\x19\xa9J\xbdQ\xe4\x1a~)\x7f\x14\xdb.01|j\xf9\x981\nx\xb0b\x8bcQG|\"\xe8wK\xe5\xb7\xf4V\x0d\x1d\xf7.\x07\x06Q\xae\xc9\"\x06j\xb4(\x8e\xd0\x7fJ\x89\x84^\xa6\x1b\x02a\xa1:\x9fH_\x14\x11-m\xa7\x81\x08\x0c\xc5^\"$\x0d\x1c\x158(\xac\x1e\xd3P\xbb\x80<\x08\xf5A\x90\x9bFX8\xb7&\x92\xf3\x89^\xe7 \x0f\xf8\xb8\x0d\xc3'\x1e\xfc\xe0Z<\x8c\xc3|n\xb5\x07\xf4k\x9b8Z\x13E\xc3!\x9d\xe3rW\xc8G\xcb\x96\x1c\xcc-B\xf9\x88\xf3\xfc$\x91aFZH\xac<\x04[\x0c\x07\x10\xf0\x7f(\x04\x1bs\xa3i<\xab\xc7-\xdf\x1b\x0f\x9c<\x99\xdf\x99\xf6/XJ\xaa&T\xc9\xaf\xaa\xe7\x95\xd7\x1a\x8a-\x95\xb5\xe4\xb2N\x07\x06\x9f\x82<\x81C\xe0\xe6\x8aC\xa5\xa1W\x184\x085\xec\xda\x83\xb3,\x85e\x94\xf1[.\x8a\xd9\xad\x128\xe4I\x0c\xbe\xeeU\x93\x1e|\xdf\xb3\xe6+h\xd2B\xb4\xd8S\x04\x99\xb8\xcf\xaeR\x16.\xdc\xea\xf2\xd1\xa1\x1eCV\x9c\x0f\xef\xac\xb4\x1d\x12\xf8\xee\xd8\xd8W\xdaOc\x02\x87Z\xcc,f\xf3\xfd]gS\x8d\x0f\xfc\xe9\xe9\nL\xc1D\x03\xb7\x10z\xb1r\x97r<&.\x12\x89e\xcf\xb2\xe5\x92Pw\x15e\x86E\x94\x19\x8b\x9f\xf3h\x95\xad\xc3B\xa0\xd3\x1c\xee\x02-\xa3\xc19K\xdf\x84\xc1f\xc3\xd2\xa6\x05\xae\x98\xabW\xcfbG\x1b\xae\xa7\x0b\x0dL\xbc7\x88\x00\xf0\xbb\x1a\xc5\xf0pOD\xc0\x91\xf1o\xf4\xd9\n\xeb\x00~\x9do\xd3yvN\x07\xa7\xf1i\xf8\xff\xfe\xaf\x9eU\xc0\xe9\x07\xe1\x82]\xbdZ\xba\xdah\x10\x8b?M\xdd\x80\xf4\x17\x96\x90U\x01lS\xf0\xc0\xc2\"oc\xbf\x0c\x1e\xc0\x88(\x0f3\xb3\x86\xe3\x86~\xbf\x0f8\xf8\xee!\xec\x99\xb9\x946\xeef\xb8Dz\x1e\xbd\xd2Jd\x9c\xec\xd3\xa6\x97\x93Ww^\x9a\xcc\xba,n&\xd0\xf8vieZ\xacJ\xa4\xafJ\xc6\xd7\xf7\x13VE@\x94/\xd7CL\x80\xa8\xba\x80\\\x11sSJ@1\x94\xe0\xbc|4\x00\xefR\xc0\xfcn\xb9\x16t\x0d{\xde\xd5\xee\x8b.8\xbf::\x82\xd2\xcf\x90L\x19\xd86\x1b\xb5\xe3\x18\xef\xf8\xfc\xe8s\x82\x15)\x88{A($\x8f\xea\x1dFK\xbe\x87\xaarN\xb1\xf8)q0\x0e\xc6\xa3W\x98\x00\xf9\xba.\x9f\x9b\xc0\x04\xf9{Q@*\x10\xd2M0\xb9\xa096p\x85\x88\x8az\x19\xd3\xaa1\xde\xad\x11M+L\xf3\x89Hs\xa0])z\xe3\xfc2\x8e]C4\x9c$\x8d+\xd9\xfd>\x04\xe1b\x9c\xabs\x0b\xef\x94\xf7\xd7lu\xdb\xc6\xcd#\xaf\xdb\x17\x91\xe7\xf1Mz\xbdbcp\xd4z9\x7f\xf5q?\x8b\xa2?\xf5\xb8\x1bL\xa7Z\x1f\xf7\xc2\xb1N\xe3\x8c\xe9\xc7\xf8m\xf9\xf7O\xef\x9e\xcbc\xcd\x0b\xf6\xf4\x8f\x97\xfe*)\xd4~Q)x\xfa\xf2\xcd\xf3\xbb\xa2\x85\xbas|\x9b\x81\x7fN\xfc\xe1LE&\x81o\xa2h\xc5\xfcpF}T\xf2\xd2I\nT\xa8\xe1k\xe7^\x8bmL8\xc1\x9a\x82\\\xd2\xad0\x91\x0b4\x06\xb1KmN\xb1 E\xb4\xea\x8b\x16{,\xf7\xbbM_&\x8c\xd1\xae/9\xaf\x17\x96y\xfd\x1d\x10\x88%3\xe2m\xb3\x9aV\xf2\xa6\xed\xe5\xe344\x94\xb5o\xe8\xa1\xd6\x90|*c\xba\xc0\x84\xe9\x820\xfd; :\x12\xd7\xe8\xb2k#\xe0\x04v\x87zS\xc3\xca\"\x17\xee\xe4FU\xe8\x1a_\xe7\xbfD3\xeed\\\xbc\xc7\xf3\x1e\xa8\xf2\xe9i\xdf\x9d\x8c\x83pys\xcc\xff;y\xe1\xddPQ\xe8\x877'\xfe\xc9\xcd\xc9\xd3\x13\xcf\xfbZ7\xb9\xc7\x80\xfc\x98\xadW\xeb\x9c=\xb0K \x8d\xbc\xf3r\x15\xf9_\x84{\xd6\x85\xdb\xa4\x15\xe1\x88\xd6\xedD\x82\x80\xf1t\xda'\x9d\xeaf{\xb3\xcfN\xd2\x18#\xc1\xc8\x11\xc2!H2BX\x1eW\xa8\x91~\x1a\xbd\x8c.\xe5\x89\xe6\xa4\x04L\xf8=>\x06\x11\xfcw:\xeb\x81\xd3\xdd\xceu\xe7\x0c\xe9\x95#q\xc1\xb8d\xf2\xa7h\x91\x1e\xf0\x9a\xcb\x9c\xf4\x10\xa6G0\x11wY\xff\xf5\xab7\xc7o\x8f\x7f~\xfe\xfe\xf8\xe4\xc5\xf1\xc9\xf1\xdb_`,_\x9d<\xff\xeei\xf9\x95\xd3\x0f\xfd0o\xee\xc4?\x811\xb0\"\x85!0\x9b\xcb\xeeFf\x04E2\xe3\x05\x07\x9cZBCX\xe7\xc5Dh\x04\xb7\xe8\x8aIB#\xe6\x9f\xdb \x8d\x10\xees\xb2y\x8c\x0f\xda\xa8\xd8\xdf\x89\xd4p\x89\xd6\xe8\x1c\x92\x1b\x86\x81\xd4hKk\x14\xf0\xa4\x0d\xe2C\xb3l(HN\xfc\x13\xde\x17$\x97A:\xbf\x00\xd7*;\x98\xfb \xd3\xe5\x90cc-\xd0\x16\x07\x81\xcf\xcc\x1dQcJ\x8a\xdb\xa6\xb1\x93\xa7'\xb5\x8d)1m\xab\xc6\xfc\x13\x83<6\xf7x\xb6\x1e7!\xf4\xfb\x12\xab\xc5O\xfeg[\xad\xe3\x93\x17\x9fo\xb5\x8e\xc3e\x9b\xd5\xaab\xa0/\xb7Z\xdb\x9fu\xb9\xb6?\xebzm7.\x98\xe9\xb4\xe7\x9f\x0f\xfa\x03\xc3X\xb4{\xa9H\xf6\xf6 S\xc9\xbc&\x10\xaak\xcaa\x0e\xbfP(\x02fX\x87L\xfe,]C\x99\xfc\n*\xe4\x97\xa2\x8e\xb4\xffy\xdb\xae\xed\xc7\xd7N#A\xd7\xd8\xe2\xa4\xf4\x8b\x93no\xd3\xd9\xcd\x14NO\xd3Y\xd7+\xbc\x1c\xeb\xbd\x17~\x10}H%\xf7=\"\x10\xb1\x85\xfb\xee\xbfn\\N\x8by\xe5n\n\xdf{\x13\xcf\x9b\x14(\xb9V\xea\xdc4X\xb3$\xf5\xd7V+\x96\xcfN\xac\xe5\xe1\xca\x83>\xbbbsA\xb3\xa9\xd2H\x96~\x01r\xcd\x10\x07\xc5\xa23\xd9\x08\xb7L\xf3\xb5\xa7\xf47H\x81\xa9yx\x8a(\xcb'\xa1\xe7'\xf74\xf3\xee\xe7q\x1c\xc5\xae\xf3\xad\x9f2\xe5K\xcbx\x99)(S \xf2\x89v\xd9t8#\xda\xa7\xcb\xa6\xa3\x19y+e\xf4sg\xd6\x83\x0e\x9b\xee\xcer\xf3Wv \xbc\x03\x97\xff\xaf\xff\xee\xed3W,\x83\xc9\xff.\x10\xe1)\xba\xbc \x8aN\xd1e\xd3\xbd\x19\xc5\xa5\xe8\xb2\xe9\xfe\xac\x07l\xfapfC\xc2(p\xc5\x80\xb7\xd3\x873A\x94\x0ez\xb0\xe3=\x81U\xeeK\xb9\xf3\xc4\x83\x15\x1a\xf6\x99\x90\x14\x88\xa8\xd1\xddU\x15\xfd\xd9\xc0\x8bM\x1f\xcfp\xe1\xf9\x9e\xed\xb3]\xb8\x0f\xee\xfe\x00\xee\xe3j\x0df\xd0\x85\xae\xcb\xa6\xc3\xe1\x8c\x83\xd9@\x8a\x00qC\xf4/\xb77\x9e\x88\xcb`]6\x0dzV\x1eFS\xdf\xda\x82e?a\xe9\xdb`\xcd\xdce\xff\\\x93?\n\x0d\xda\xa5\x0b\xce\xd3o\x9e}\xfb\xfc\xc5w\xdf\x1f\xff\xe3\x87\x97?\x9e\xbcz\xfd\xdf?\xbdy\xfb\xee\xe7\x7f\xfe\xcf/\xff\xf2\xcf\xe6\x0b\xb6<\xbf\x08~\xfb\xb0Z\x87\xd1\xe6\xf78I\xb3\x8f\x97W\xd7\xff\x1e\x0cG;\xbb{\xfb\x0f\x1f=\xee>8<\x0dOc\xe7\x96\xec; x\xbe\xc4\x86\xddY\xfbm\xc1\xd3A\xa3b\x9cc\xc7\xc8\xa2\x1e\n)\xf2_H\x1eCa\x9d\x8e\xa8\xe3\"b\xcfr3vi\xbcN1\x00a\x7f\xb7Qk\xc4\xe0\x00\x06\xad4?(\x13\xdf7\xbe\xb6\xe2\xc1\x18\xfe\x0b\x1e\xa1\xf0\xb9\x08\xf6\x9f|q\x06E\xe9\xc5\xf44>\x0d\x0fgB\x86a_\xf4\xa0v[|\x8c\xffc|\x95\xd8\xb7{n\xd1\x07)\xff\xee\xc1\x13\xe0\xab\x9c=\x01\xd6\xedz\xc0\xe0\xbf\xd0\n\x8c\xe4%\xa4\xce\x99\x8b\xfc\x10pt\x04\xc3}\xd8\x82\xd1\xde\x9e\xd7\x03\xbd\xf8Q\xb9t\xb4\xb7\x07[\x90p\xa4\x9f`\x12\x90\x83\x03\xd8\x87\x1b\xf0\x158\x04\x12\x1c\x98\xe9r\x15[4\x00\x19\x087\xc3\x81\xdd\x87}T\xd1|\xd2\x90`\x0c\xc3GJ\xd0Slk`lk$J\xf1S\xe1q\xc8\x97F\xaf\xb3\xab\xbe\x8c1\xe9\xc62\x8e\xd6\xea\xc1\x9d#O\x80\xe8\x1e\x1f\xe7u w[\xa9\x08\x06\xf6\xe0,\x0e!\xd0\xf6Z\x93\xb6\x00\x1d\x93s\x8b\x15\xa1X\x80/k\xc45~\x0d\xae\xb1@\xe7N :\xf1\xe4\xfb\xd3\x00\xb7\x8fo\xfa\xfe\x0eR|Z\xe9\xc8T\xba_*\xdc\xdf\x81-@s\x1c>#7\xe0\x10\xfb\xc8\x83.\xa4SfW\xa8\x16\x01t\x87\xf4\x87\x9fyD0\x86Q\x0e\xae\x85v\x06\xa6vv+\x85\x07\x07P\xeeq\x7f\x17\x1b\x1e\xe6\xc0\\h\xb9:\xc0\x83\x83J\xc3\xfb\xbb\xc5\xf6z\x10\x17\x01O\xfd\xfad\x02\xc2\xca\xceVd\x7f\xc58\x93U\x02\xc1*,\xbc%\x89\x16\xd5x2X\x9c9>\xf1\xca\xb7\x19\xf2\x97\x985\x12\x83[o\x03C\x80\xca\xfc\xb8\x91>z\xae\\\x83\xf9\xe1\x0b\x9f\x90 \xd8\xea6\x16\x88|\xa1\xf3)\x9b\xe5I\xc0\x94\xa8\x96\x16|\xe6\x08f\x15E\xb2q\xb3=\x87\x08\x84\x13\x84\x10\xd7\x1b\xf0\x04\xa2Id\xd3j\x08\nY\xdfo\xecZ\xfe\xdd\xc9P\x07i\x9f\xe6>x5a\x81\x90\xa8;1k^\x16\x11\xce\xa2U\xd2\x0e\x058\xc5SyG\xfa\xa6*\x9c\xf8\x93<\x8cZ\x1c\xfa;\x9e\xe1\x8d\x1f\xc4\xc9\xdf\xeb\x10\x0b\x7f\xdd\x9a\x83\x9a\x89\x19=\x8dc\xff\xda\xf5\xa5\xdb\xa3R\xf4\xf0\x13\xec\xdf\xed\x04\xfbx\x82\xcd'7h}r\x03\xf4\xe1G\x93!\x0d\xe1~`\xd7 \xff\xba\xec\xd6ok%\x9b\xb2\x19Ge\xd1t\xc0o\x19\xfcw6\xfb\xd3\xa1\xde\xb2\x8f&\x9a\xfac9\xd4\x99\xf0\x06\xb6\xeccT\xd8\xc7\xcc\xb8\x8f\x99m\x1f\xf9ne\xb8[Ae\x89{\x10\x89\xb5\x0b\xc4\xda\x05\xb8vV\"&\xfa\xeb\x0fp\xf1\xd6\xbe\xe51N\x98Uun\xf6)\xfcrg\xb8\xf6\x82\x0dB\xb0\xc4\xfe\xd2\xee\xb1\xb0'L\x10\x15\xa2\x0d\xa7lV{\\>/\xc4\xdb\xf0\xfc\xdf\xcd\x8f\xf2\xb7\xe4A\x16.\xd82\x08\xd9\xe2\x13%/5\xcbp\xfbE\xf5*\x19\xe6o\xcb\xcf}\x8c\x82\x85\x8c(V\xd7\xbb\x89\x93\xab\x13\xfa\xfd\xcd\xbc\xa1\x7fK\x1e\xc4\xec\x9c]}\x11U\xca-\xe4f\x01F\xa6\xc1zm.'\xe5Mg\xa6\xb19\nxp\xfa\xc0\x9d\x9e\x07\xeb\xd9}\xef\xeb\x07R\xb3a\xae\x1e\x1bb\x0c\x80\x18\x94\xf3@\x8a\xdd\x07V%\x02i:\xa4\x05o8\x1d\"\x1b&\xd5\x07G\x9c%mq]\xf3\x9e\xd0\x9aw\xcar\x03\xa0\xb8`\x0b\x947Si\xe5K\xdf\xc1\x7f\xce\x8a\xcbS\xa2-:\xa9\xdf\xca\xab[0\"\xea\x81e\xc5P\x93\x95kFY\xaf\xcc\xc7|\"\x92PT\x1au\xd0\xd6\x14\xe6\xb6\xf8\xa4vC\xf8Zu!\xed'Q\x16\xcf\x19ty\x81ua\xd3\xfe\xf9*:\xf3WB\xe7\xd7=\x04\xe7\x9cB\xf5\xe5\xa9\xe7\xf3Wkz\x15\x9c\x87Q\xcc\x9e\xf9\x89\xfe.\xe0\xef\xd8\x97BfO\xb4J\xea~\xd1\xa21]\x06\xe1\"\xbaT@A?\xfb,\xd9\xc4\xc1\xda/\x19\x06\x06\x8d\x98\xd1\xa8N\xf8-y \x07\xff\x17\xe3\xc6\xaa\xbaF\xfe)\x18p\x11\x06\xf8\xe6{\x16\x11!\xc8\xf48}4\x0e\xe3g\xa1\x9eM\x8f\xfd\xf0\x9c\x8dkyo[TQq8^\xc7\xd1y\xec\xaf\xe9P\x84\x18\xfb\x8e\xef\x98\x0c-v\x16-\xae\xb58<\xce\xf3+\x0e\xf9I\x10\x85oR?ek\x16\xa6\x8eVu:\x98\xa9&\\\xe7i\x1cG\x97/\xc4\n\xe7_\x96?`\xea\x0d}\x8bN\xcf\xb7\xfd\xca\xc0\xe6\xebZ\xb1\xba5hD\xd4\x9f\x84\x8eEt\x9c\xe6\xcd\x0f\xb4\x8d\x0f\xeb6\xbe~\xd3\xff\xb0`s\x9b\xc3\x0b\xdej\n\n\x88\x81\x95\xdb0\x14\xbfu(\xe0\xbbc\x84\x82\xbc\xaa\x82\x02^\xd7\n\x04\xc5\xfae \xe0\xc0v\xeb\xaf\x0cf\x10/\xfc`\xc5\x16\x90F\xca\x16B!\x0c\xbb6\xc5\xd8\xc1\xc6\x8f\xfdur\x0b\xab\xd0H\x06T\x0d\xfd\xb5 >\xc5\x0di\xec\x0cW\x1c7\xba\x07\xce7\xabh\xfe\xa1t\xde\xec_\xe1\xf2Mp\x0d\xe4\x02\xbaQ\x0fB\x199x\x8a\x96\x0b\xfc>\x9e\x0egt\x01\x0b\x95\x8b^\xdd\x91\x08\x02#F\xe5\x9f\xd2g\xf5&4w\xbe\xa1\xe5\x00\xfe\xd4;Z\xdd\xba\xcat\xed\xcb\xda8X<\x00\xf6F&\x8b1\xf7\xd1N\xa98\xa3\xda\xe5b\xbfN\xdaW\xac\x9a4\xcb\x15J\x08\x0f\x0e\xe1q\xb1h \x870,i\xb3Vp\x08;\xa3\x12(\xf0\xb2\x9db\xd9\x05/\xdb-\x96-x\xd9^\xb1\xec#/{X,\xbb\xe6e\x8f\x8ae\xe7\xbc\xac4\xbe5\x1c\xc2ni,\xefyY\xa9\xdf3^V\xea\xf7\x12\x0ea\xaf\xd4\xc7\x15\x1c\xc2~\xa9\xbd7\xbc\xac4\xb7\xe7\xbc\xac\xd4\xc7S\xbe|%7\xc4W\xbc\xac\xf4\xedo\xbcl\xbfX\xf6\x01\x93\x15\x96*\x1eca\xa9\x97\x1f\xb1\xb04\x95\xb7ph\x80\xf8\xc1\x18\x9c\xd3\xd3\x81\xe1\x1ez\x88o|\xc3\x9bG\xf8\xe6\xcc\xf0\xe61\xbeI\x0do\x86\xd4Qhz5\xc4W\x1fM\xafF\xf8jiz\xb5\x83\xaf\xca\xd4\x1c\xff\x1b\xd1\xd0\xcbBh\xfe\xb7\xb3;\x86{\xa7\xa7\xce=\xc3\xd8\xa9\xaf\xd3Scg\xd4\xdb\x89\xe9\xdd>M\xed\xbdi\xa5F;\xd4\xeaK\xf3Kj\xf5uI\xc6P\xac\xfa\x8c_\xd6\xce\xb5\xd3\x03\xe7\x17\xfe\xbfk\x96\xe0\xb3\xf8\xe7\xf9\x1b\xfe\x0f\xd2\xbc\xce+\xfa\xff \xff?>\xd2S\x84\x8f\xf4\xffWX{\xb9\xc4\x8a\xe2\x9f\x17/\x9c\x99)\x90\xc6\xeb*\x92\xcc\xc5\xb5%\x0d4Y\x9e\x1c\xd6z\x93\xf5(X\xc6ho\xcf#B\xe8\xca\xa1h\xbd\xa3b[\xca\x02\x19\xab\xef\xef\xed\xed\xc8\x0f2\xf1\xc1\xae\xe1\x033\xc9\xde\xa1FvG\x8fw\x1f\xef?\x1c=\xde\xf3\xbcb\xf8\xdby\xb4`\xb0\x89\x82Bz\\\x8av\xb8\xf6\xafe\xda\x85\xf3\x98\xf9)\x8b)\xf3\xc2\xe0\xea\x85\xf83\xd1\x0d8\xd0wb\xa0\x8f\x8a;[\xf8%o\xbc\xd3SG\xc4p\xcc\x836\x0e\xf0\xfbm\xc5'{\xd0\xd5\x987S\xb0\x92\x9f\xaa\x9b\xa5\x85\xac\xc6\x9d\xc9crG2\"\xb6\x0c0\xfd\xa3\x9f^\xf4\xd7\xfe\x95\x8b\xf9\xc1E\xf1\xcd\x0d\x8c<\x19\xda\xfbC\xb09\x0e?\xfa\xab`Ami\xbf\xf58\xdc\xcbUt\xf9\x92}d+\xa4`\x83\xe4$\xe2kz\xee\xa6\xf9\x1bO\xfa\x1fie\xb2\x97\xf4z%\xe2m\x17\xaeU\x1bE]\xcd\xffkH\xdfU\xe0\xdcrw\xfe\xff\xfca\x919\x87\"\xfb \x19iP\xc6\xd5\xb8\xa40`J'C\xce\xff\xd1\x13\x8a\x88:\xa4\x8c\xe4\xf14\x10Z]q\x16\xd84C\x0f\xeeN\x87\xc8\x99,7]\x1d\x91A/\xff\xcc\xc0\xd5r\xd0\xc8\x94\xff\xb6\xd7\x03\x97\x12\xb8\x95B\x90\xf7eV!\xde\x0foOdt\x98\xf7u7\xcb\x1e\xf8\xd4\x99\x8f\nk\xfd\xd5\xd4\xe7\xe3\x0b\xa7\xd9\x0c\x0e\xcb\x91oA\x13p\x17\xe1\xd9\xd5@\x8c\x03\x0e\xb6\x98H\xf3H\x05;Q\x9c\xfe\xc0\xae)\xd5\x8c\xfaQ\x8c\xde\x1e\xb2\x7f\x06\x0b\x19=]\xfd\xba\xb9\x81G2\xf6y\x18\xfd\xc4\x96\xd4\x86x\xd4[\x08\xa3g\xd1z\xe3\xa7?\xf2\xe3Lu\xb4\x02\xbd\xe6<\xe2\xd0\x8d\xeeV\x97b)\xb5\x02\xbd\xe6\x1d\xe2\xc5\xcb\\Du\x9f<\xbf*\x86\x98\xc7\x9cWa\x1e\xa6\xbe\x98I\x9a\x97,2\xfe\x85\x9f2a\xa7@\xa5Y\xc2\x16\xdf\xeao\n\xc1\xfdL8\xe2\xc4x\x98\x10\xe8\xc5i\n\xe0\xb0\x14:\x96y\"w1)\xe6\xb6\x87\x04\xd7|l\x89f\xaa\xf4\x04\"8\x80\xe4\x89\x879\x1a\xd0j]\xa6\xe6\x17n|\x98\xf8?\xf2\xd0\xda\x87\xfcCD\n\x0b\xd1A\x82\xa9\xdd\nox\x97\x14\xc65Bc!z\x0eu!\xc4\xa9\xe0\x03C\x01\xd7\xddC\x08<>\xc4\xeea\xd9\x9dL\x80\xb0_\xbbD/\xebbo\x9bc\xebJty\x1f4\xce\xce\xd4\xf6\xb7U\x14-\x19\x0e\\\xb1\x15\x87>z\x9c\xd76\xf4okC;\xa3b`\xaa\xe1h\x1f\x99\xf7\xfda9\xf2\xd5\xe8\xf1\x1e\xff\xc5)\x94\xdcm\x82\x93$\xe2\xd7\xcd\x0d\xec=\xdc\xd9\xdd-~\xc7/\xe3\x1d\xfe\x8b\x92Q\xa8\xaa\xbc|\xbf\xd4\xf5p\xb8;\x1c\x0ek'\xf2\xc2:\x11\x9cb\xa9\x1fl\x99?\xbe\xcf\x1f\x9f\xe6\x8f\xaf\xf2\xc7\x0f\xf9\xe3\x8f\xf9\xe3e\xfe\xb8\xa8\x1d\xd6;\xeb\xb0\x1e\xfcz\x1a\xde\x07\x19\xc8D\xdfn\xf9\xc4\x0f\xd27\xd5X#\xbfs2\xa7X\xf4\x0b\xe7U\x8aE\xff\xe4\xb4M\xb1\xe8g\xc0\x88\xd2\xd5A\xfeP\x1fg\x9d\x8f#\xd2\xed\x9b:\x86\xe8'sK\xf9\nO:\x85\xfa\xa8\xbe}Kx\xa0R\xce)\xd5\x7f\x8b\xec\xa3\x85\x04%\xa5\x9d\xc4x<\x9do]\xba\x8c|,;\xcb\x1f\xdf\xe4\x8f\x97\xf9\xe3\xfb\xfc\xf1i\xfe\xf8*\x7f\xfc\x90?\xfe\x98?.\xf2\xc7\xeb\xfcq\x9d?n\xf2\xc7\xe3\xfc\xf1*\x7f<\xcf\x1f/\xf2\xc7\x8f\xf9\xe3\xf3\xfc\xf1713{V\x17C\x82\x07\x839\x8a\x97\xbf\xed\x10\x0bb\xf2\x06\x0e[\xff\x13a\x05c\xdd\xef\xd7\x9a\xcdS\xff\xe3m'@\x91\xdd\x9a'\x02\xe2\xe6\x8a\xa7\xa3\x861\x83\xca\xffB\xb3\x9c\xa3\xfa'\xe2'=\x81.\xe7\xf50\x9b=_\x07Q\x01&\xfcqL\xc9\xeb\xa0\x0b\xffp\xe7\xc4L\xa2\xd2\xa2\xb63{\x98K\xc8A1\xb2V\xfa\x83\x83g\xe65A\xfb\xcf\x8d\xd0~\x0f3\x934+\xf7\xe4\x9fb\xa4s\xaa\\p\xcaV\x1aI\xc8LK\x84\xd0\x111h\xfb\x80\x0e;\x9c]\xdb\xdf\x19\"\x11P\x8dO\x1a!WL\xdf\xec\xef\x8c\x06\x90\x07+\xdd\xd9\xdd\xe1\xcc6\n\xa6^\xbb\xc3\xc1\x08\xbd\x96\x19lS\xeb\x949f[|\xd6%\x1e\x8e/\x1b\xa7\xdd\xc6$\xf3z+\xcce\xbb\x87\xd0AJ\xe6\xdf\xfc\xe2\x99@:\x8df0\xa6[\xee\xb5\xd9\x1bM\xff\x93\xba\xd4\xba=\xf3(}\xa8\xb9!\x11\xfc\xc1\xbee\x05\x99n\xb0\xdeDI\x12\x9c\xad\x84\xb7\xfb\x18\x02!\xaa$\x0b\x10\x8a=\xe64\x11v\x7f\xb8\xf5\xfc\xfc\xd7\xf64Rp(\xe95)\x00\xc4\x90k\x06-@\\D&\x85XRF\xf9E\xc8\xcf\x1b%\xd46\x7f7\"|\xa4\xde\xf1Q8]\x07\xb7K\x1e\xcam\xbalNC\xa7v\x86\xdf[\x19a\xdb\x909l\xe4(u{\x88\xb9/\xa9\xf4\x85a,\x8a\xf8\x99\xb2\xf1/E6\xfe{G\x98\xa2_\xd0\xfe1\xf8\xf39\xdb\xa4 \xaa\xde\xf0\x06^QN0\\\x81{M7MqZ\xd3\xd5\x8cff\xbfy\xecW\x8ad\x87cc\x95\xda\x90\xd3\x06\x83,#\x9b\xdf\xa9\x97\x8f\xfeOA\xc6G\x87\xbe\xcc\xb3\x17\xf4\x07r\xc8a\x8f\x8er\xd8\x83\xce\x10C\xdf\xa8\x9f\x03Cj\xe0\x04\x14\x94P\x13\xe5$\xad\n\xf9\xe9,\xed\x01E\x85+r\xb9\xe5\x14\xa6\xbc\xf9y\x0fV=\xb4\xff\xa8\xbaIq\x00Ea\x87z\x85\xbe=\xf2MU\\\x86\x02;W\x93P\n\x8dX\xae$Q\xbbM\"@-al~\x13\x18\xda\xd1\x8a\x1aZ\xd4?.\xa0:\xa5\xee\\g Z\x12\xf8pF\xa9n([y\x9d\x05\"\x14D\xacDB,\n\xfa\xb6\xec \xf1`C\x0fE\xf6\x9c\xd5\x10\x1b\xceW&\xe2@\xedb\x1c$\xa1\xd6\x12\x91%\xc2)'p\x16\xd3h6\xeb \x1cCf\x80>\xe5`\xa7\xff\x08\xee\xf1t\xb58A\x02\xf8\xf1l\xf0\xa7\xdc\x9b\x823\x1e2\xeb\xbb\xac\xb3\x14[\x875\x8b\xc9\xcc'\"r\xd3\x84\x13\xaa\xe2\x11\x1c\xe5\xf1MS-\x1d{?\xf1\x97\xec\xdb\x92\xb5B\x8d\xe5\x1eM1\xee\xb3\xab\x94\x85\x0b\xb7z\x8e\xc8Fs\x0cYq\xb7\xf0\xc6/\x8d\xeeN>?\x02\x90\xc85V\xba\xd6\xf0\x83\xed\xbc\x7f\xcf\x92\x1f\xa3E\xb6\xaa\xc6.\xfd\xe8\xaf\xb2\xa2w\x1f:\x8a\xf5\xcfY\xfa,\n\x97\xc1\xf97\xd7\xefb\x0c\x86\xdb_D\x97\xe1*\xf2\x17T\x0e\x87\"\x1eB>\x80\xdc\xe9h4\x18j;h\xf8\xd4\xae\xf1*\xdb\x16\x18\x15\xbd\xa2\x92;\xe0C]\x86\xfd%K\xe7\x17^\xc5E+\x9f\x93qJmvU\xd51\x92-\xca\x97\xb8\x9fl\xd8\xfc)\xd6L\xccH2\xf7\xe7\x0dJ\xcb\xe1\xa6^?\xbd`\xe8\x07\x17\xe9\xe9F\xe5\x9f:E\x91y\x14\x80\x9aSM\xbe\x8c\xce\x88\xa8.\xed'\xa9\x9ff \x1c\x1d\xc2\xee\x00\xd3[\x04\xfdl\xb3\xf0S\xf62\xf2\x17Ax\xfe\x06\xdf\xbb\xce\x12\x1d\x17i@\x9c\xb3\xb8e\xb5w\xf1\xcaux\xc1<\n\x93h\xc5\xfa\xa8\x14se\xffo\xd9U\xaa\x91'Y\xbc\xe2@\x86\x17\x07R\x89\xcc\xe5[)\xdcQ\x7f\xf1\xd7+\xea\xc1s\xc3~\xca\xae\xca!\xb4\xa1\xaaF\xfb[\x9d\x1f\x1d\xf2\xcfY\xda\x12\xd2R^\xf78t\xcbw\x15L\x80\xc1\x18\xa6l\xf6\xf7\xc2\x12\xa5s\xaf\x08w~\xfa\xf7\x0c^\x84H\x91\xcb\x1b<\xef\x0b&\x10\x83)9\x93\xd4\xc7\x96\x83\x17\x16[F5\x9a;\xdc\x7fT\xea1\x11#\xd9-\xe2!j\x93\x02I\x92\x0b\x06\x07\xbcL\xbe\xf0\xdc\xa0\x07I\xff\xdd\xebo\x9f\xbe}\xfe\xfe\xd9\xab\x93\x17\xc7\xdf\xbd\xe9\xb5\xdc>\x0c\x0e\x8d\x80\xeccp\xd1\x7f\xbc\xf1\\\xd6\xdf\xf8\xd7\xfc\xa8\xeb(\xde3\xf7\xfa\xf6\xd5w\xdf\xbdl\xdb\xab\xbc9U\x07f\xb5/\x02UEt\xa2\x86\x9c\xf0\x97=\xe8\xc4\xc5\xd1\x05\xc2\xf3t\xe6}\xc5\xf7\xf9\xc1\x83\xff\x03\x14J\xe2G\n\xdb\xf4\xee\xa7\x97\x87\xc9\xa5\x7f~\xce\xe2\xed,\xd8\xe6xg\xe1\xaf\xa2\x90m\xa3N$\xed\xff\x96\xf4\xd7\xfe\xe6\xff\x07\x00\x00\xff\xffPK\x07\x08v\xf2\x8aA\x86\xba\x01\x00\xc5\x87\x08\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00 \x00swagger-ui.cssUT\x05\x00\x01\x80Cm8\xec\xfd{s\xdb8\xb27\x8e\xff\xff\xbc\n=\xbb\x95\x9a\x99\x1dS!EQ\x17\xabf\xeb\xc8\xb1\x93q6r\xc6\xcem\x92\xad\xad)\x8a\x84$\xda\xe0\xe5\x90\xd4\xcdz\xf6\xbd\xff\x8aw\\\x1a $;s\xf6\xf7\xad\xb3\xd9dl\xe2\xd3\x8dFw\x03h4\x00\xb2\x9bl\xed\xe5\x12\xc5\xda\xda;\xfc\x9fN\xe7\xe5\xdf\xfeo'\x08c\xdf\xc6\xde#\xea:I\xd2\xd9\x0c\xbbzW\xef\xfc\xbf\xce\xec\xfac\xe7\x9d\xe7\xa0 A\x9d\xff\xd7Yz\xe9j=\xef:\xa1\xff2@N\x88\xed\xe4%M\xf7\xb7\x97\x8b0H\xb5\x85\xed{x\x7f\x9e\xd8A\xa2%(\xf6\x16\x13'\xc4a|\xfeWs\xde7,\xe3\xdfD\xfd\x9dU\xea\xe3\x03\xf6\x02\xa4\xad\x90\xb7\\\xa5\xe7F\xd7\xb0&\x9a\x9fh)\xda\xa5Z\xe2=\"\xcdv\xef\xd7Izn\xe8\xfa\x8b\x89\xb6E\xf3\x07/\x85K)\xce\xf3\xd0\xdd\x1f|;^z\xc1\xb9N\x95\xd8q\xea9\x18\x9dQ\xcf\x12\xcf\xa5\x9f,\xc20E1\xf5h\x85l\x97y\x14\xd8\x1b\xea\xf7\x049\xa9\x17\x06\x07\xd7K\"l\xef\xcf\xe78t\x1e\xe8\x16\x1b\x87\\K\x99\xf0\xe7=\xe4OJ\x19\xbb\x83!\xf2;\xb4\xa4\x0bo\xe9\xd8Q\xc6\xf0\x8cy\xbc\x8eii}\xdb\x93UZPT\xea0\x90\xdf\xe9\xeb\xd1\x8e\x96+>T\xca\x9d\x87\xbbL\xe4\xdd2\x1f:\x16a\xec\xf3\xca\xfbg\xba\x8f\xd0/1JP\xfa\xaf3\xbe Y\xcf}\x8f)\x01*\xcbf\xb5\x92\xa2(\xfdW=\xb6\xdaQ\x84\xec\xd8\x0e\x1ct^\x14\x01\xd5\x974\xe7\xe7\x9a\x1f>j\x8b\xd0Y'\x9a\x17\x04\xcc\xd4C\x8a\xaa\x04-\x85o\xc1\x16\x95\xf3 \xde\xeb&\x91\xed\xba\xd9l\xa0K\xda\xd0\xb0\x89\xbd`)n@+\xae\x92^\x02,E\xa7\x11\x87p\x9df\xbevnD\xbbr\xec\xed\\\xe4\xc0\x8fh\x972\xb3$\xc2n\x82\xd2C\xd5\xb0\xaei!\xbf\xd3\x1d\xe6\xff\x0e\xb8a\x01\xa3%\n\\h\xda\xac\xe7\x14j\xd6$\x9e\x16\x83a5\xacW\xdd>\xb5\xe7\x18M|{\xa7m=7]\x15\x1d\xa5\xd6\xf2d\xbb\xf2R\xa4\xe5\x83\xf4y\x11y1Sl\xb8\x8cQ\x92\x80\x83\x8f\xd2(Xw\xe1\xbaw\xd9\xeb4\x04\xac\xeb\xac\x90\xf30\x0fwP\x1f\x89m\xd7\x0b\xffu\x92Vd\x0e\x15\xac\xfd9\x8a3\xef-\x19\xe7^\xa9%\x91\x17h@\x17\x14\x10\x85\xeb\x94&:\x94C\x90\xa0\xa1 \xb2cg\x05v\xdfLY\xb9\xc7LJ\x0f\xd3\xc2\xc5\"A\xe9\xb9\xd6cB+\x8aU#K\xf1@s2nX\xdc\x06\x11]\x13\\@\xd2q#[C\xbf\xf00\xd2\xd6\x11\x0em\xb7R\x82pt\xcaG\xed\xcaO\xe9X\x00\xa5\xb6\x87\x13:\nE\xc1Z\x12\x85&k\xdf\xb7\xe3}\x8d\xc0^\x92j^\xca\xf4*\xc7\x0e66\xec\xc4\xb4V\x8b \xed_\xcc$\xe4G\xd8N\x115\x93Rd]\x17\xcd\xd7\xcb\xce\xdf\xa8q! \xb1\xe7v\x96!v\x01\xac\x96\xf7;\x90\xe2\xaf\x8b\xc5\x02\xa2\x98c\xdby\x80)\xd8\xf8\xa7\xa4X\xc6\x9eK\x04Ndx\xdbY\xc7\xf8G\xd7N\xeds\xcf\xb7\x97\xe8e\x14,'Y\xf7\x1d\xf4\xcf\xbc\xcf\x17\xef\xef\xb6\xfa?\xde,\xc3\xe9t:\xbd\xf9\xf0iu\xf5i\x99\xfd\x98\xffs\xfdj\xfau:\x9d^^]\x0e\x07\xef\xb2\x07o~\xbf{\xfd\xe5\xd7\xbb\x8f\xf3\xde7\xdd\xed\xbd\xde\x7f\xbb\xbd\xb8\xf8\xf6f\xec}\xfbp\xf1v\xfe\xe5u\xf0\xed\xf3[\xfc\xf5\xcb\x9d\xe58\x18\xff\x96\x11\xecW\xd1\xe7\xd7+\xfd\xcb\x951{\xef\xdfl\xe6\x1f\xacU\x81\xb7\xfa\xf3\xdf\xa7\xc5\xff.\xb7/\xd1\xaf\x17\xab\xaf\xbd\x14\xbb\xaf.\xbco_\xdch~\xaf{\xc3\xe1\xfa\xe5\xb5w\x11}\xbb\xd4\xbd\xcf\x8f\x9fofW\xc6\xf6\xb6\xf79\xb4?\xad\x06\x8e\xff\xf9#z\xb0>}5\xa3\xf8\xeb#~\xb8\xbe\x1f\xfd|}\xb9\xeb\xbf\x0fV\xa9\xf3\xc6\xc0\xee\x9b\xab%zc$\xf3`6@\x97\xba\xf7\xf5\xcb\xdd\xe6\xab\xffi\x90\xfd>\xff\xf2Y\xff\xfaa\xe4]\xff\xba\x1c\xa07\xc6\xd6}\x93\x8c\xaf\x1f^?\xcc{o\xf1\xf5\xeb\xd5\xcd\xa7W\x17\x97s\xf3-\xbe\xbe\xfc\xb4\xbe\xf1\x8c\xfb\xd9\xc7\xab\xdd\xf5\xa5c\xbd\xbb\xbf2\xde_\xce\xf67\x1f\xb6\xcb\xd9\xfdtw\xf3a\xb4}\xffa\xb4\x9b\xbd\xd2\xb7\xb3\x8f\xe1nv\x19\xeeg\xaf\xa6\xcb\xeb\xea\xef}\x7f\xf9\xdb\xafo\x1f\xbe\xddG\x1f\xee\xae\xbe\xd6\xf28\xfe\x9d\xff\xdb\x87\xb7\xa1\xfb\xeb\xdd\xf6\xbd7\xda\xb8\xa6k\xbe\x0b\x9c\xc7w\xfex\xffm?\xda\xbd\xff\xf8`\xbd{\x9c\xee\xdf=^\xef\xdf\xfd\xfe\xf6\xe1\x9bg<\xa2/\x96\xfe\xf5\xf7e:\x0ff\xf7\x04\xdf\xabo\xbf\xdf\xdc;>\xde\xbao\xf0f\xee]\xec\xbf\xbd\xf9:\xf8\xfa\xe5\xed\xc6\xfd\xfdv|\xed]7:xcl?~\xd2\xc7\xd7\xfeJw\x7f\x9d\x0e\xde\xed\xc7kg_\xdb\xe2~\xde\xd37\xe8\xcd\xeb\xed\xbb\xc7\xab\xf5\xec\xd58\x9d\xe7\xfaY\xa5\xf37\xd6\xe3\xfb\xe0F\xff\xe4\x7f\xa6d\x9e\x07\xb3u\xa9\xd3\xf5\xd7\xde8}g\xaeV\xce\xab\xd1\xee\xdd\xfdt\xe3\x18w\x96\xf3\xe6\xd3\xe6\x93\xff\xf9qn~\xde\x7f\xed}\xfe\xf0\xed\xcb\xd7\xfbk\xef\xa2?\xff\xb2[;\x8fQf{EY\n9\x9c+\xe3\xe6\xfd\xc3\xdd\xe6\xab\xf99\xfd\xf6\xc5\xd2?|\xba\x1d_g\xb6~e=\xd8_n\x07\xb3\x8fw\x97\xef?~\xed\xdf\xe8\x9fz7\xfa\xe7\xd7\xb3\x8f\xaf_\xdf\xdc/{\xb3\xc7o\x97\xb7\xf7\x0f\xdb\x9b\x87\xdb\xfe\xec~\xb9\x9d]]\x13\xfc\xf0\xda1\xefVs\xff\x06\x13\xfc\"\x9a\xdf\xad\x1a\xbf\xcb\xe8\xd2\xf1?\xaf\xdc7\xe3\xfd\xe77\xe3\xcd\xfcR\xf7n\x0b\xfd,?\xbdYm\xdc7\xe3G\xfb\xcdx{}usy}y\xbd\x9d}\xfc\xb4\xfc\xc7\x95\xb1\xfa\xda\xc3\xeb\xbc\xec\xd5\x83\xf7\x9b7\x1d\x95v\x1a\xdc\xbd\xf9\xbc\xb7\x7f\xff\x86\xbf]}\xdb\xcf{\xfa\xd21\xef2\x1d\x0e\xec/\xd6\xa3\xfb\xe6\xf5\xfak\xef\xf3\xdb\xbbK\xdd\xcb\xf0\xef|\x1c}\xbb\x0c\xcd\x9b{g\x7f\xfbpk\xde\xdc\x7f5o\x1f?\xedf\x9f>\xf5n\xef\xdf\xbe\xba\xd5?\xedo.\xa7\xfd\xd9\xc7\xe9vv\x7fe\xce>\\\xd7\xfc\xbe\xbd\x19\xdf\xbb_\x0c<\x0f\xee\x08~w4\xbf\xc7V~\x9bL\xf6w&\xe0\x93\x99\xaf\xbe\x1a\xe7~\xf9\xe9\xe1\xeeM\x81+\xfa]\xde\x0f?\xf6\x97\xbf]\x8e\xfb\xce\x9b\xd7\xf7v\xef\xb3~\xfd\xe6\xf3:\xeb\xef\x8ew\xfd\xf2\xb7\xe4\xe2\xc3\xcfof\xd9\x08q\xff\xe1\xd3\xdd\xc5\xe7_\xef\xed\xaf\x9b\xc7\x97/\x1fG\x97\xef\x92\xcb\xfe\xd2y\xf3\xbb\xf7\xf5j\xfa\xe6\xe2\xfa\x1fo.\x02\xf4\xf2\xe5\xe2u\xb4\x9d.\xb7\xd3\x8b\xf1hj\xbf\xeeE\xf7\xf8\xd3mF~\xf1\xf6\xee\x93u\x15?\xbc].\x97\xbf\xfc\xf2S'F\x11\xb2\xd3\x8e\xde\x11\x8e\xa4\x9a1x\xc6\xc1\xf4\"\x1f\xe6n\x8b\xc1t\xba\x18\xbd\x1c\xaf\xfew0\xfd\xdf\xc1\xf4?u0}\x7f\xf9u\x7fw\xbf\xba\xba\xbb\xcc\x06\xd3\xaf\xfb\xd6\xc1\xafe0m\xf8\xdd\xaa\xf1\xfb\x0f\x1aLo?\xb6\x0e~G\x0d\xa6\xb7\xed\x83\xf3\xf7\x19L7\xaf>\xe8\xc6u6\x18\xcd\xea\xc1\xd4\xbf\xeb\xbf\xb4~\xbex\xfd\xdb\xc5b:{\xed\xbf\x9c],w\xa3\xbb\xe9\x9b/\xaf\x02c:\xf5?,\xcd\xfe\xed\xe0\xe1\xe2\xf2\x1f\xb37\xb3\xcbW\xdb\xebWhv\x8d\xfc\xd7/\xad[{{\xe5E\xd3/\xdbO\xab\xed\xd5\xfd\xecr3\x9f~\xc1_\x1e6\x9f/\xb6\xeb\xd1\xe6\xf6zz1\xbd\xda^\xbc\x8aV\xa3O\x03G\xcf\xc7\xa5+\xfc\xfa\xe3\xc3\x87\xf5\xad\xff\xea\x95\xd2\x00<\xd2\xf2x\x97\x1c\x85\xb3`\x99\x1d~\xef#T\x8f\xbf/\xc7\xf7/\xfb\xb7\xd3\xafw\xbf\xaf\xa2o\xcb\xe9\xf4\xc3\xa7\x87\xff.\x03\xd9\xe6\x7f\xbf\xbdL\xa6\x17\xaf\xaf\xdc/71\xba\xcdF\xe6\xdbj\xe0|\xd9\xbf\x9d\xed\xec_\xeft\xe72\xdc\xbc\xebY\x8f\xef\xfcb\x1c{\x97\x8f\xb5\xe3\xfe\xd7\xdf\xa7\x9b\xd9\x87\xfe\xf6\xddv:\xfa\xcd\\m\xbf~\xb9\x89\xbf\xfd~\xbb\xfc\xea\x7f\x0e\xec/\xfd\xf1\xf5\xfa\xe7\xe1f\x7f\xbd\xb4\xbf\xdc\x8e\xaf\xb1c|\xfcxq\xe3\\\xdd`\xfb\x0d\xbeF\xc1[\xfc\xc9\x8c\xde\x7f~s3\xb0{3\xeb\xdb\xab\xeb\x97\xb9\x8f^f\xfd\xf7\"\xfd\xf6\xfb\xdd\xaa\x19#\x96\xe3\xeb\xb2\xee\xf7\xbe\xf5\xf8\xde\xcf\xc7\xe0M\xd6\xe7\xf31\xf9\xd7\xbb\xf8\xb7\x0fo\xab\xb9\xe2\xeb\xc7\xcf\xd3\xe5mo\xbc\xff\xf6aj\xbc\xbb\xff\x9a~}\xbc\xda\xcd>L\xcd\xf7\x1f\xfa\xbb\x9b\x8f\xcb\xc7\xd9\xfd\xa7\xa4\xec'\x9b\xd9\xe5\xc3f\xf6q\x9a\xce.\xaf\x06\xb3\x8f\xd3\xc1\xec\x9e\x18c_]g\xe3~\xed_\x8d<\x99/\xea^\xad\x1b\xd35\xdd\xbde\xce\xf6\xd6\xc6\xf1\x9d\xcd\xec\xe3\x83\xf5\xfe\xc3h;\xf3F\xfb\x99gd\xf4\xa9cf}\xf1u\xff\xdd\x17\xeb\xf1z\xdf\xf0\xbd{\xf3\xf9\xf1\xab\xf96r~\xbd\x8b\xe6\xbd\xfe2\x1b\xbf\xdf\xfb\xaf\xbd\xb9\xf9Y\xff\xed\xc351Nf\xe3\x00Q\xa7\xcc\x1e\xfb\xff\xc0\xb1\xf9\xf7\xe9\xe0\xd6|\x8b\xbf\xfe~\xb7q\xf0\xddf\xde\xdb\x12\xf3\xe2E87\xef6No\xb5q^]\\\xde\xee\xa7\xfb\xd9\xe5\x95q\xfdju\xf3\xf5\xcbM4\x0f\xb2\xb2eT\xf0\xb9\xb8\xf9\xf81z;\x0fn\xf4\xaf_\xac\xfbo\x9f\xf0\xd5o\x1f\xdef\xfc\xd7\xf6\x17\xfc\xf0\xfe\xe1z7\xbb\xbf\xd6\xdf\x7ft\x1eo\xee\xddW\xb3\xc7\xab\xdd\xdd\xc7o\xaff\x0fo/\xef>^\xeb\xb3\xcb\xe5nv9\xdd\xcf>:;\x82\xdf\xd5\xbcwc\xcc\xbf|^\xbbW\x0d\xbfoo(~z+\xbf|\xee\xac\xe7\x13\xec\xf8\xb8\xf7\xed\xcb\xdd\x1b\xc7\x1f\xa7\xd7\xbf\x16\xba|\xef\x8b\xe7\x85\xdb\xfb\xab\xfd\xec\xfe\xd6\xbay\xbc\xea\xdd\xe8\xd7\x8f\xf9\xbc\xf0p\xbd\xbf}\xb8y=\xbb\xbf\xdd\xbe\xbf\xbc\xda\xce.\xafw7\x8fW^\xc3O\xde\xfa7\x97\xa3\xf0\x1f\x97\xe3_\x7f{\xfc\xf4\xb2\x8d\xa6\xfd\xef\xe2\xe5v:\xbd{5\x9d^O\xa7\xcb\xcb\xe9\x87\xeb\xe9tuu1\xdd]]\xbc\x1c\xddN\xbfd\xe3\xe6\xed\x14\xf8\xdf\xd7\x8b\xe9\xed\x15\xf0\xfc\xfa\xeajzu1\x9d\xce.\x98\x82\x8b\xe9\xe5\xd5\xab\xa9~u7\x9d^]^\xf0<\xef\xae?\xbe\xbe\xf8\xf4\xe5\xea\xc3\xf5\xe6\xa5=\x9dn/\xa7\xb7\xd3WW\xb7\xb3\xbb\xe9\xe5h\x1a\xbe\x0f>~6n?^\x0e\xdf\xbeMV\xbf\x99\x9b\x0f3\xf3\xb7\x97/\xbf)\xcd/\xc6@m\x829*\xbe\xcf\xe6\xd7W\xb7\x0f_\x96\xbd\xe9\xff\xc6\xf7\xff\x7f\x1d\xdf\xab\xce\x01t\x1c\x9e\x8d\xad\x8asV\xcfH\xc9y\xab\x8c!U\xe7\xad\xc7\xcf\xbf\xe2\xed\xb7\x0f\xe3\x0f\xdf~\xbf\xd9\xb8\xbf\xbf\xbd\xcf|\xe9\x9b7{\xb6\xf8Y%\xae\xbfy\xfcj\xce\x1e\xde^\x15I\x97\x99!\x1f\xbf\xdb\xd7\x1d\x0d\xbf\xaf\xad\xfc\x9e-\xbeoOn\x1c\x15\xdf\xdf]\xb6\xf2\xfbN\xf1=\x1a\xbc5\x1f\xb2\x11\xe2\x91M\x96\xe8\x9f.\x93\xd9vv\xff\xe1.\xfc\xfa\x9b\xf5\xe6\xbf\xfb\x1f~\xbb\x99\xdf\xdd\x7f\x9e]\xdd\x1a\x8bWw\x97\xcb\x9f\xbd\xe0\xe5\xe0\xe7\xb7\xc6\xf4\xed\xa7]\xb2\x9c^\xbd\x99NM\xe3b\xfav\xf6A\x7f\xf3\xb5\x18\xcf?|\xfa\xfc\xfe\xee\x1f\xd6\xab\xaf\xd7\xd7\x92\x04J\xb3\x15C\x1f\x8e\xa1\x7f\x03\x8e\xcf\xccCwO=\xe0N\"\xb8\xf4A\x04\xd7\xa3\xcf\xcd\xb8\x98\xfe\x95\xdeZ\xae6\xe6\xe8\x87\xfc\x01\x9dE\x18\xfb\xf4F\xacA\xff\xda\xa3\x7f5\xe9_\xfb\xf4\xaf\x16\xfd\xeb\x80\xfe\x95?\x0b\xb4J}\xba\x15\xf9Nu\xb1\x89\x83|\xdb\xc3\xff\x12\x95\x96\xdbT\xa2\xe2\xc8N\x92m\x18\xbbB@\x8a\xc4\xbcS\xb4K\x85\x85\xeb\x98!,\xb64\xe9G\x1e\xbd\xc7c{\xf4.UH7\x9a>'\x101\xe7\x94\xca\xf3Q\xd4\xb3|\xd7\x93~BKPmK\xd2\x0fW\xf4\xaf\xb4-\xd6\xf8\x94\x0dH\xba7\xd8I\x84\x9cT\xcb\xf7\xd8\x0e\xe2\xf3%b\"M3\x06\xbbq\xb5\x9b\\\x9d0\xb2\x06\xdd\x9e\xf5BF5\xde\x19\x03\x96\xca\x18\x0e\xbb\xc3\xa1\x94\xac\xbf3Y\xaa\xa1\xbc\"s\xd7\xe7\xea1\xcd\xaeiJ\xa9\x06<\xd5`\xd0\x1d\xb4\xc8\xc6\xb7\xc8\xd2\xa5$\xa3\x9d\xc5U\xd3\xeb\xca\x1bd\xedF\\5\x03y5C\xbe\x9a\xa1\xd1\xed\xf7Z\xea\x19r\xf5\xf4\xe5\xf5\x18;\x83#a\xcf,2$\xc5\xc9\xb5C\xedq\xf6< \xf1:E\x934\x8c\xce\xf5I\\zd\xc9M\x9f`\xb4\xc8~'\xce\x0eT\xe7k\xb2\x9f\x1f5/p\xd1.\xfb\xe5\xdf\xff\xe5#\xd7\xb3;\x89\x13#\x14t\xec\xc0\xed\xfc\xe8{Ay\xea\xc0\xd4\x91\xff\xd3A,W\x90<\xa17d\xd4'u\x08\x80P\xadO\x00\x84\xed\xdd\x02\xaaM\xa9g\x00\x84*\x9d\x03\xaa\xaf\xbd\x7f@\x95)t\x11\xa8\xb2\xf6^\x02\xe9Q\xa5\xa3@\xb5\xb5\xf7\x15\x88J\xa9\xbb\xe4\x84\xcf\xdfc\x14\xbaL\xf9\xb0>\xbd3h\xe9G\xfeS\xba\x91\x7fb/\xe2\xe8\x14;\x11G\xa7\xd0\x87\xf8\xba\xd4\xba\x10G\xa7\xd4\x83\xf8\xda\x14:\x10_\x95J\xff\xe1\xabR\xe8>\xbc\x06\x95z\x0f_\x97B\xe7\xe1\x89\xd4\xfa\x8e\xff\xe7w\x9d\xb6^\x82\x9f\xd2K\xf0\x89\xbd\x84\xa3S\xec%\x1c\x9dB/\xe1\xebR\xeb%\x1c\x9dR/\xe1kS\xe8%|U*\xbd\x84\xafJ\xa1\x97\xf0\x1aT\xea%|]\n\xbd\x84'R\xeb%\xf8\xbb\xf4\x12\xb2^\xcf_\x1e\xe8c\xa0\xb4XN\xb8A1y\xce>?W\x9d?\xfd\xbf\x9e\x1f\x85qj\x07)K\x12\xa4\xb6\x17\x00D\xf9s\x82\xac}\xa6;\xf0\xc2d\xd3\xee)\xf2\xc0t\xacH\n2)\xcc\xbe\x85\xa0\xfeirBd\xc7\x89)\x94\x08\x9f&\x11D\xc6IDQ\xce\x97\x9a\x83\x82\x94v\x9d\"\x19t\x1e\x84\xe5O\x13\xa2\xac\xf6sn\x90\x98/\xb54\x8c\x8e\xe6\x93\x86\x11\xc7'\xef4Gs\xe2;\xc5\xbc\xea\xc7G\xf3*\xc88nY\xe7=\x9a\xd7\xf1\x8b\xab\xda*L_P\xaaN`\x98SX ms\n3\x89yNa'\xb1\xd0)\xec\xda\x82\x12\xd5\x11\xa51\xdd\xf1N'\xb2\xdc\xf1\x9c\xc4\x86;\x9e\x97\xccn\xc7s\x93\x99\xedxnmV\x93\x1a\x08\x1f]\x9d\xc8@\xc7s\x12\x1b\xe8x^2\x03\x1d\xcfMf\xa0\xe3\xb91QL\xb7<\xfe\xce\x1f\x83\x07a\x1aqL\x1389O\x94\xc2\xe4zMt\xfc\x18\\\xf1\x08\x92\x13\x84\x05\xa9\x14\xe4%\xe9\xda|[uD\xaa\x98\xfb\xa7\xb4\x03 Ri\x86\xaf\xdc\n\x89\xc0\xf8\x14\x81\x01\"\x15\x811)0\xed\xfb6}\xcf-g9)\x1f\x95\xd18s\xbb\xa7;O+\x9alt\x00\xe8\xb2\xc7\"\xda\xfa^]1\x1e\x00\xd4E\x81\x88~N\xdf_\x86\x18\x94%\"\x0e\xb8\xe2\x90wz\x80>\x7f.\xa2\x0e\x80{\x81\x94\xba\x8e\xef\x8bs;\x9f\xd2\x8f7\x03Av\x8a%\x08\xf2S\x8dA\xb08\xdd\x1e\x04\x93\xd3L\xc2\xa9\x0f\xb2\x8a\x82Y\x14\x86\x9b\xb9\x9d\xcd\xe3'\x98\xca\x7f\x92\xa5\xfc'\x1b\xca\x7f\x06;\xf9O4\x93\xffT+\xc1\x06\xc1'\x19\x04?\xc9 \xf8\xc9\x06\xc1\xcf`\x90'\x0ee\xac\xe6@\x83\xd04Zq\xd5\xaf\xa2\x13\xbc\xe3 \xc3\x05\xc8\x8eA\xb0a\x18\x1c\xd8\xb5\xe3\x07m\x19\xdb{\x06k\x9a&\x87\xf5=\x17\x82Z\x96\xc5A\x01\xd8p8\xe4`\x89\x877\xcd\x85\xef\x128\x1e\x8f9 .\x8c\x0d\xc1m\xdb\xe6%\x0d\xc3\x00\x92\xc1q\x1c\x01k\x00\x8c\x10\x82u\x9b\xdf\xd2d\xc0\x8b~\xf6\x87\xc3\x83P\xf6&g\x85\xd3\xc6:\x0d]%\xd8\xfeQ?\xd3_\x9ce\xb1\xf8Yw\xfc\x93\x80p\xd4B8\x12\x11\x0e[\x08\x87\"\xc2A\x0b\xe1@Dh\xb5\x10Z\"\xc2~\x0ba_Dh\xb6\x10\x9a\"\xc2^\x0baODh\xb4\x10\x1a\"B\xdd\x92\x13\xeaB\xed\xe8\xbd6\xd2\x9e\x98\xd6h%6 \xea|\x8c\xe1\x9c6^\xces\xda3\x1dt\xd8\x82\x88uX\x92\x08p\xd6\x82\x88uV\x92\x08p\xd4\x82\x88uT\x92\x08p\xd2\x82\x88uR\x92H\xa8\x08\xd6AI\"\xc09\x0b\"\xd69I\"\xc01\x0b\"\xd61I\"\xc0)\x0b\"\xd6)I\"\xc0!\x0b\"\xd6!I\"\xc8\x19K*\xd6\x9f(2\xb1+\xf1\x8eH\x11\x82N\x98O`1r\xd9\xc1{\xa8\xf7u~\x9c\xe5\x81\x8bE\xdf0\x07\x82Y\x01\x82\x0f{\x16?\x89\x84\xb1\x1d,\xf9\x81~`\x02\xf3\xf32\xc4<\xd7\xf9\x10@\xee\x11\xc6\xe1\x96\xc6\xf2\xaf\x0e\xa8\xa5\x85\xe0\x7f]\xcc\x17\x86\xcdO\xa8\xd1:\x8e0+\xb0\x85z\x8e\xcdO\xe6\x05w\x90\xc2\xee\x0f\xccE\x0f6J\xe4\x05l\x04\xe2Z\xba>\xe2\xad\xb2\nS\x08\x9d\x99f\xce\xcf\xa9 r\xa4\x0b\xa7v\x10o\x9b.\x1f\x8e\x94\xc1\x10B\x01\x837\xcc\xe1\xd0\xe2\x9b B\xc7\xf6x\xc8\x0b]E\x19<\xc1\x18\xa1\xb9\xc3\xeb$\xb07l@\xa2\xeb\xc6\xbc\xcf\xb3\xce\xa5\x9e\xe35k\x1b]\xef\xf7\xc7|\x08\x03 Mk\x88\\\x91W\x01\xf8\xf1\xc0q\x80 &\xc7\xa3\x04$q\\\x04\x91l\xedd\x85\\\x88`1X,\x16\xbc\xf4%\x01\xa4H4Z\xb8\x0b\xde{K\n\xb8s,\x16\x0e\x9a\x8bH\xa0\xde\xef.\\\xbe\x15d:\x91\"\x10f\x88\xe6\x9aV\xbe\xea\x84&\x80\xde\x7f\xd2\x9d\xc7\xf5\xd0\x1d\xdb\xae\xb7N\xce\xd9\xa1\"6\x18@\xd7\xe8Y1b\xd3\xadq\x8f\x85\x81(\x93EA\xa0>\x032\x00\x8cf\xe8\xac\xe4@R9\xd6\"\x0fc\x067\x1e\x8f\xc7\xc0\xea\xaf\xdew+\xc0y\x92<[iUz!\xd7\x90\xc5:P\xa41\xad\xd8U,\xe0UV\x1bbU\x96\xb5q+\xf7\x16[\xe4\x82*\xe2y\x15\xdb\x81\xa2\x96\xc8\x05kO\xb6\x1cX\xe7\"\xd3Q\"\xff\xe21\"\x17\x03\x90\xb0\x97\x01@\xd0\xd1x\x9c\xc8\xd7\x00\xa4\xc8\xddx\xa8\xdc\xe3\x98\x8c\xdfS\x9c\x8eO\xdd=\xd9\xefT\xa4Sw=\x86\xdb1\xde\xa7\xe0~*\xb9\xbeX'\x12oB\x97d!B\x8f\xe4\x80\x02\x87\xe4p\xb0?\xb20\xa1;r@\xa17\xb2\xc8\x16g|\xb6\x01\x90\xcbN>\xdd\x15\xdbe;\xc2\x13\xfd\xef\xe3\x88\x02\x9fc'!\xc0\xe7X\x88\xd0\xe78\xa0\xc0\xe78\x1c\xecs,L\xe8s\x1cP\xe8s\xc7M\xb9,\xbc6oc \xa2\xa0<\x9e\x06\xfb\x1c\x9b\x80}\xba\xcf\xe1\xe7\xf49|\xb2\xcf\xd1\xfc4\xadx d\xc5\xaeH\xf5\x02/\xe5-\x82\xf8,\xe4d\xa0\xf93\x0eZ\xdeF&\x91\xc0&f\xb6\x84\x08\x03D\xe3\xf2w\xd4\xb5\x0f\xd1\x07\xb8!\xdcn\x8f\xb4-\xd8\x92a\xb5\xc8(\x1cDd\x17\x1e\x08\x9b\x86\xc7\x81\xd6\xe1`\xa0\x818\x14l#&\xee\x15\x9a\x89\xdb\xbe\x17Z\x8a\x0f\xf5\x85\xc6b\xf7\xe2\xebm\xc0v\x83\xa9\x0cl[\"\x1a\x15\x1a\xd1W\xb4!\x8b\x13\x98\x90\x85\xc1\x16\xf4U\x0c\xe8+\xd9\xcfW3\x9f\xafj=68\x16\x1b\xcf?\xc1v\x023\xe1V3aE3\xb18\x81\x99X\x18l&\xacb&\xacd&\xacf&\xacj&6\x9e\x14\x9b \xc3f\xa2\x80\xc9\xcav\xc3\xadf\xd0\xd7\xba\xf3\x87\xe7zG\xef\xf4\xa3]\xa7\x17\xed:\xf4\xa6\xcbD \x05\xd6\xd4\x13\xd54R\xaa F\x815\x99PM\xbd\x92\xbe\xbd]r$Xc_Vc&\xb9\xaeP\x1f\x84\x03k\xb3\xa0\xda\xfa\xa5\xc4m\xb5\xc9p\n\x83\xf0\x01t\xa2lT\xff\xd3\xfcHR\xd9\xf3\xbb\x92\xa0\xb2\xef\xebM-\x95\xb6\x99\xf8x\x87\x12T\xf8,>\xa5\xe0T\n3{\xedi\xfe\x9f\xe8h\xc2\xba\xbe\x83\x9f\x81u}g7\x93\xd6\xd9f\xf4\x13\xbc\x0c\xac\xefOp2\x99?\xe1?\xd1\x9f\x84u}\x07\x7f\x02\xeb\xfa\xce\xfe$\xad\xb3\xcd\xbe'\xf8\x13X\xdf\xf3\xf8\x13Ua\x14\xa3\xfa\x0b\x1e\xda.\xff\xb4E\xfdq.m_~\x08\xa8\xf9\\W\xe2\xc4!\xa6?%\xd2\xcdb@=\xff\xe6\x11\x13\xb0\x15Q\x9f~\x80S\x89E\xa4\xa7W\x9fRb\x8a\xf3\xf0N?\x14\xe9I\xbe>#\xaf\x8f\x0fa\x8b*\x8d\xb2J \xc4-j5\xaaZyD^\xb1QT\xcc\x97fu\xf7\xf2\xba\xf9\xc8\xb8\xa8\xbbW\xd6\x0dD\xceE\xdd\xbd\xaan\x1e\x91\xd7\xdd+\xea\xe6K\xb3\xba\xcb\x86k\xa2\x96\xd7M\x07\x10e\xfdM\xe3\x01L.A\xd5|\xa0<\x97\xa1P\x80&\xd2@\xad\x02\x00Q\xc9P+\x01\xc0\x142\x94j\x00\xca\xab{\xd4\x9a\xb6\xf00>HoS+\xcc\xd0\x07\xde\x99\xb3\x98\x01\xf0\xe7\xc2'\xb3B\xc8-Ko\xcf\x8a\xa5\x0e_\xa4 \x9f\xcf\x1d\xbb\xaa[\xe4\x99u\xf5B\xe7o$\x10\xfb?!\x84\xc0\xc9+9D^Z\xcb!\xec\x08\x8d\x1c\xe2\xbe@\xc8!r\xf8J\x10\x89\xcf75\xc9\xdc\x9e\xa8K\xec\xf9u\xb3\x84\xce_\xcb#\xf6\x7fB\x1eI\x17 \xe5\x11\xf6\x82F\x9e\xb6\x8eP;\xad\xb0/(t\x06\x85p\xb5\xe8!\xbe\xa4\x83\xf8\xd2\xfe\xe1\xb7t\x0f_\xda;|y\xe7\xf0\xdb\xfa\x86\xdf\xde5\xfc\xb6\x9e\xe1\xcb;\x86\xdf\xd6/\xfc\xf6n\xe1\xb7\xf6\n\xbf\xb5S\xf8*}\xc2W\xe8\x12~[\x8f\xf0[;\x84\xaf\xd2\x1f|\x85\xee\xe0\xab\xf6\x06\xffI\x9dA\xe8\xf7X\xe2\xf7X\xea\xf7\xb8\xc5\xef\xb1\xd4\xef\xb1\xdc\xefq\x9b\xdf\xe3v\xbf\xc7m~\x8f\xe5~\x8f\xdb\xfc\x1e\xb7\xfb=n\xf5{\xdc\xea\xf7X\xc5\xef\xb1\x82\xdf\xe36\xbf\xc7\xad~\x8fU\xfc\x1e+\xf8=V\xf5\xfb\xb6\x80\x88&v\x16\xe7\xf6\x82}5j\xf6t\x8e\x16a\x8c\x0e\xe5\xc7{\xcf\xff\xd2\xf9\x0b\xfd\xe5A\x98\xcd\xc1\xc1\xc8\x8e\xcf\xe7a\xbab\x01\x87\xbf=\x86\x99o1\xcfqI\x92I\xc7\x14U\xdc\xf2\x960esqMAYt\xd2N\xb9\x93O\xa3b\x91\x9aRP\xaa\xa6\x18\x12\xac)U\xd8 V\x9d\x8e\x9dl\xa8\x93\x08\xecK\xe5\xf5e\xe2\xfa\xea\xd2\xc2\x82\xc9\x8c[\x17\xc2\x82a\x99`\x98\x12\x8c*u\x03\xd9\xe7\xfc<\xe6S\x81L\xf1\\\xf2A\xc2\xae\xeb\xcd\xdb?4\xd8u\xbd\x94E\x01\xfd\xc5m@`\xa9C\x17k\x0eb\x17\xddn\xaa\xc5\xe1\x96\x81\xc5\xe1\x16Bi\xcb8\\G<\xb6x\xceQ8!^\xfb\x01+A\xfeP\x80\x05+ \x8b8:m\xe1\xed\x90{(\x90\xd8\xde\x87\xeb\xf4<\x7fD\xbc\xfeJ\xa1\x7f\x1c\x18\xdbg=Lf~\xb2\x1c\xf6\x00\x12\x01;\x01\xcfC\xe0\x07\x00\x1046\x89\x83\xbd\x81C\x08\x1d\x82GJ}\x02\x84K\xdd\x02\x10\xa5\xdd3DDR\xe7\xc8\xd73R\xffPp\x10\x85\x01\xd4\xcd\x06:\xa9\xd3\xf8m>\xe3\xb7\xb9\x0c\xcbA\xe41\x1c\x0ev\x18\xbf\xcd_|Uwa\x81ro\x01\xd0rg\xe1\xe4P\xf0\x15\x98F\xee*\xfe\x93<\x05v\n,w\n\xdc\xe6\x14\xb8\xcd)X\x0e\"\xa7\xe0p\xb0S\xe06\xa7\xc0\xaaN\xc1\x02\xe5N\x01\xa0\xe5N\xc1\xc9\xa1\xe0\x140\x8d\xdc)p\x9bSPt\x0b\x8cvu%D\xee\xbd\x0e{5?\xd12\x10\xf9,\xfb\x9dfS\x9a\x08\xe4V\x99\x99aJ\x90\x90E\xc4c^R\xcd^\xa7!\xb5E\x90==7&\x95\x94\xe7F\xc7\xe8\xe4\xd9|\xfa\xb7\xc6\xeb\xf5\xfc\xe7\xea\x85\xa9@\x15\xf9\xe1S\xae\n\xbd\xa9\"\x7f\xe7A\xfd\x13\xc0\xa1\x8c$H\x1ea\xece\xeb\x89\xea\x0b\xe3\x13\xb2\xcc\xf5\xe2\xe2\x95\xff\xe5\x17\xcb\xeb\x9a\x88\x92\x82\xe5\x04|\nH\x90\xc5H@\xf5\xab0\xf6\x1e\xc3 =A\x808\xdc\xb2\xb5s\xfd#/\xdf\xc6vt\xa8\x19d\xbf\x9dg\xffL\xe8_A\xbd\x03\xa4\xc5\xc3 \xfb@P\xaf\x16\xa3\x0d\x8a\x13\x04\xd4_\x15M\xe0\xc7B+6,\x8f\xb6fU\xa3\xd0\x9c\xb4L\xa2R\xd8\xbc2\xb9Z\xcd,\x91\x8c`\x0d\xd8\x1b\x96\xc9K\x91\x9fhIj\xc7)%N\xf1\x19\xfd\xfcyS\x15\xf90\xff9\xff\xbcy\x92\x8f)\x05\x0f\x889\n\\\x805\n\\\x96q\xf6\x88c\x8b\x02\x17bZ\xbe\xe8\x93\xe7[\x14\xb0\xac\xcb\xa7$\xf7\xe2\x11\xc4{n'(\x1b\xc8\x00\xeeU\x11\xcb\xbf~N\xd6P=\x845\x1e\xa3\xd4Y\x81:\xcfKx\xad\x17\x8f\xc9\n\xcag4\xff\x04\xe1Ee\xd0\x8aE\x06\x07\xac\x97A\x85\xc6\xcb\xf9\xe4\xb6\x03\xb84\xa6jxp\x96\xca9T\x86\x02\x98PF\xc9\xf9@6\xc9\xb94&\x01\xf80\xca\xcf9\xc1\xba/uS\xaa\x1e\xd4\x0e\xa9\xe5\x9c\x13\xa8\xe4\xfbu\x92z\x8b=\xd0q\"\xdby`\xfb\x0d\xf1\xac\"\xac\xb2T\"\xedW8\xb6\xf3\xe4\xac\xa8\xbeS?\x01YsF\xa9Q|\x07\xca9\xb1\xfd\x87|\xc8\xd6\x00\x99\xab\xc2\xccQ\xbaE(\xe0+(\x01L\x0d\xd5S\xb6\x8a$\xb2\x1dT1\x83k\xb2\xf3\xd74\x1eh~\xae\x97\xa4\xb17_\xa7H\xc0\xb2\xa0\xa29\x96\x08\xb6\xf7\xe4A\x0da\xc3\xc29\xda,X1\xa3\xbaP\xc3\xaa\xe9Ar{Ul\xd8~\xd4p\xa2\xba\x91\xcc4\x15\xab\xda4<\xaf\xca\x0c43\x89\x11*\x9e\xac\x11\x1a\x96\x84% \xaer;0=\x95\xb4\x04\xd9Qk\x96P_-\x0e\xdf\xea\xccl\xebz\x81\x8d\x8bh\x9c\x88A\xb5\x1c|\xaeO\xca\xffB\x9c\x0c \xa7\x1e\xcb\xc9(9\x19\x10\xa7\x9e\x84\x93\xc9r\xea\x95\x9cz\x10'S\xc2\xa9\xcfr2KN&\xc4\xa9/\xe1d\xb1\x9c\xfa%\xa7>\xc4\xc9\x92p\x1a\xb0\x9c\xac\x92\x93\x05q\x1aH8\x0dYN\x83\x92\xd3\x00\xe24\x94p\x1a\xb1\x9c\x86%\xa7!\xc4i$\xe14f9\x8dJN#\x88\x13\xb6\x93T\xe6\x9cz\xf6?\x96\xe38\xfb\xdf\x84\xf8\x19\x085\x97Y\xd4\xa7\xcb\xd6C\xe5\xbbm7\xe8\\\x9f\xd4$\xe0\xca*\xe7e\xc8\x96o\x0d/\x83\xe0e\x00\xbc\x92U\xec\x05\x0f\x99d\x15i\x80\x966)F\x81\x00\x05)\x89\x0d\x80\xd8\xa0\x88\x0d\x85\\\xdb\x81\xe7O\xe4\xfd\x88\xc6\x9e\xbe\xa4\x86\x18>\xf7\xaaZc\x0e\x0c/\xbe\xcb\xc2\x1a\xac\xe5\xf8\xb55\xcbFmA\xf6\x9c\xcbk\x81\x04\xadK\xafgZa\xe7\xd5W<\x8e^d\xf3\xd4\xa7\xad\xb3a)\x9e\xba\xd4>\xcd\xb8\x7f\xcaj\xfbT\xab\x7f\xbf\x057+\xd1\xf3\xae\xb9a\xee\xcf\xb2\xec\x86Y?\xe3\xca\x1b\xae\xe0\xb9\x17\xdf\"\xfd?\xd7\xfa\x9b\xeabOY\x82\x8b\x18\x1d\xbb\n\x17\xf19a!.bu\xdaZ\\\xac\xa9\x13\x96\xe3\xacY\x9f\x7fE\x0e\xd6\xf0|\x8br\x90\xfd3\xaf\xcb\xc1:\xbe\xd3\xd2\x9c\xb2\xee3\xad\xce)\x9eO^\xa0\x0b\xb8\x9d\xb6F\x170;u\x99.`\xf7\xc4\x95\xba\x80\xeb\xd3\x17\xebB\xc3\x1c\xbb^\xe7\xe7\xeb',\xd9\xe5\xcc\x8e\\\xb5\xcb\x99\x1d\xb9p\x973;r\xed.gv\xe4\xf2]\xce\xec\xc8\x15\xbc\x9c\xd9\x91\x8bx9\xb3#\xd7\xf1rf\xc7/\xe5[\xfc\xf6\x89\xaby\x96\xfb\xe2i\x0bz\x90\xddS\xd6\xf4T\xf7?aY\x0f\xd3\xb3+{\x85\xa5\xbd\xc21\x9a\x9c\xa7\xff\xcc\xcb}\x9e\xdf\xb3\xaf\xf6\xfd?c\xb1\x0fTr\xc2Z\xdf?a5\xf8\xacK}P\x80\xd65\xdfs\xad\xf4\xfd\xa7,\xf4Y\xe2\x13\xd7\xf9\x90\x0cO^\xe6\x9fb\xd7?g\x95\x7f\x9a\xc1\xbf\xe3\"\xdf\xff\x9ek|\x88\xf9\xf3,\xf1!\xce\xcf\xb9\xc2\x87\xf8?\xfb\x02\x1f\xd6\xfd\xb3\xad\xef\xfdgZ\xde\xc3|\x8e^\xdd\xc3lNY\xdc\xc3\x9cN\\\xdb\x8b\xb4t\xca\xd2\xde\xff\xde+{\xa0\x82g\\\xd8\x03\xdc\x9f{]\x0fT\xf1\xbd\x96\xf5\xfe\xf3\xaf\xea\xfd\xe7\\\xd4\x83\xccN\\\xd3\x83\xbcN^\xd2\x83\xdc\x9e\xba\xa2\x07\x99>\xc3\x82^`\x93\xa3\xd7\xf3\xec\xcc\xfc\x94\xe5\xbc\x8c\xd7\xb1\xaby\x19\xafc\x17\xf32^\xc7\xae\xe5e\xbc\x8e]\xca\xcbx\x1d\xbb\x92\x97\xf1:v!/\xe3u\xec:^\xc6\xeb\x84e\xbc\xd4]\x9f\xba\x8a\x97\xae\xae\x8e^\xc4K\x17\x84'\xac\xe1\xfd\xa7-\xe1!\xf2\xe3V\xf0\xa2\xc5:~\xe6\xc5:\xcf\xef\xd9\x17\xeb\xf8\xcfX\xac\x03\x95\x9c\xb0X\xc7',\xea\x9eu\xb1\x0e\n\xd0\xbav{\xae\xc5:~\xcab\x9d%>q\xb1\x0e\xc9\xf0\xe4\xc5\xfa)v\xfds\x16\xeb\xa7\x19\xfc;.\xd6\xf1\xf7\\\xacC\xcc\x9fg\xb1\x0eq~\xce\xc5:\xc4\xff\xd9\x17\xeb\xb0\xee\x9fm\xb1\x8e\x9fi\xb1\x0e\xf39z\xb1\x0e\xb39e\xb1\x0es:q\xb1.\xd2\xd2)\x8bu\xfc\xbd\x17\xeb@\x05\xcf\xb8X\x07\xb8?\xf7b\x1d\xa8\xe2{-\xd6\xf1\xf3/\xd6\xf1s.\xd6Af'.\xd6A^'/\xd6AnO]\xac\x83L\x9fa\xb1.\xb0\xc9\xd1\x8buvf~\xcab]\xc6\xeb\xd8\xc5\xba\x8c\xd7\xb1\x8bu\x19\xafc\x17\xeb2^\xc7.\xd6e\xbc\x8e]\xac\xcbx\x1d\xbbX\x97\xf1:v\xb1.\xe3u\xc2b]\xea\xaeO]\xacKWWG/\xd6\xa5\x0b\xc2\x13\x16\xeb\xf8i\x8bu\x88\x9c[\xac3\xf4\x87\x05\x0e\xed4\x7fG\xce\xe4\x0fz-\xcc@\xe3\x12\x9a\xbf1\xa7\x05\x1b\x94\xd8\x93\xde\x82\xb4\xc8\xdf\x82\xa4.W\x83V\x12\xad\x81+\xbcYH\xfd\xfc\x81\xe6\x1f#\xb2\x7f\x94\xc4\xbe\xba\xc0\xb0l\xc7\x98\xb9\x06\xab\xc9\x86)\xd9\xa8\xd2\xc4\x0e\x12-A\xb1\xb78,\xc2 \xd5\x16\xb6\xef\xe1\xfd\xb9fG\x11FZ\xb2OR\xe4\x9f]`/x\x98\xd9\xce\x87\xfc\xd7\xd7a\x90\x9e\xd9\x1b\x14xq'@\xbb\xea\xe7\xb3\x15\xc2\x1b\x94-r\x9b\x9f:\x01Z\xa3\xb3\xf5|\x1d\xa4\xeb\xb38\x9c\x87ix\x16d\xff$h\x19\xa2\xce\xda;\xb3c\xcf\xc6g\x8d\x14\x8ct\x9c`K\x14\xc6K\xcf>\x83\xc0\xb9t\x9a\xa0E\xc2*J*\x9e\x80\xc7:\xa1\x8b\xa8\xf7\xa0e\x0f(\xa2Wa\x90\x84\xd8N\xce\xfc0\xb0\x9d0\xfbO\x98G\x13,\xa3u\xec\xa1\x98!\xcd\x9fun2\x95\x96\x00\x11}\xad`\x8a\x03\xa3\xf6\xc6\x1e\xa2\xb6\x17\x86\xa3x\x00v\x15R\xa7+\x84\xed\x84&/\x9e\x9dI\xccT\x16\xa9Z5\xf5|D\xd7\x91?\x81\xa0\xf3\xd0\x0d\x03\x8f\xc2^\xe4\x8f:\xb3\x8f\x10\xde\xb1\xb1\x97\xa4!m\x85\xe2\x99\x80bi\xc7\xb6\x1f\x06.-|\xf9\x10\x14\xc9N\x1eP\xbc\xf10\xa6\xfd\x84x\x0e\x91\x95\x8d(>\xa1\xe5\xa56\xf6\x98\x0f_/\x12\xad\xc8\xc3\x91\xc0\xe2\x89\xc2`I\x8f=\xf9;\xafT\xebc\xb0e\x95\nu*\x0c\xd0^6\x88\xaa\xca\xe1\x1f-\x06X#V\xaf\x11\xd25\x8d%M\xb2-r\xc8}\xee\x93\xefT1\xf7E\xf8\xc5\xd6\xa0\x00\x06\x0f\xe8Q\x80\x1e\x0f0)\x00\xf7y\xfa\xc5\xb6/\x17q\xb1\xb5(\x80\xc5\x03\x06\x14`\xc0\x03\x86m\xcd\x1cQ\x80\x11\x0f\x18S\x80\xb1~\xfc\x9b\xba\x19\x8f\x15Z\x84E@Fa1\x90]X\x0cd\x1a\x16\x03Y\xa7U\xe2E\xf1\xb9\xb36\x1b\xb1\x18\xc8L\nm\x1f\xb1\x18\xc8X,&\xb3\x97\x82\xc1\x14F\x05\xba\xbf\x8b\x8d\xe8\xb7\xb5\xc3` \xa0 \xfdv\x0b\xfa\xed\x06l\x11v\x91\x7f\xed\xac\xd5|~\xbb\xf5Z\x1b=b \xa0\xed\xfc#M'\xb6R\xdb\xe0\xc7\x00@+\xe1v+\xe1v+\xe1v+\xb5\x08\xbb\xc8?v\xd6j%\xdcn\xa5\xd6F\x8f\x18\x08h%\xcc[\x89\xc2xA\xb4N\xb5\x18%\xa8\xb9\xdfnG\x11\xb2c;p\x8a/qN4?|d\x1f2&Z\xa7i\x18\x14l\xce\xcfs\xfc\"t\xd6\x89\xe6\x05\x01\xfb\x16`\xa2F\x1eZ~\x86\xed\\\x9fD\xb6\xebz\xc1\x92]\x18\xaf\x8cC\xb9\xd1\xca\xbf>y\xd5\xab\xca\xf8\xd7\x19\xaf\xcc\xaa\xac\xcf\x97\xf5\xab\xb2\x11_f\xd5\xf5\x0d\xf8B\xadW\x17\xf7\xac\x17l\xa1\xa5W\x85\x16\xfb\xa9\xe5\x956\xac)\x87<\xa5\xa1\xd7\xa4\xfcg\x9a\xf3\xcd\xe6\x1cBl;\xf3\xb0\x0d-\xddf\xc5\x15\x93\xf2\x01\xc5\xa4\x84@1-#\x0b\xc8D\xdb@R\xb2\xc0U\xf1\xce\xb9\x12\x90\xfd\xcc\x96{\xc1\n\xc5^ZA\xca_\x15\xe6\x89\x03\xe39\xd9t#q\x1e\xa2\x18\xf2\x1f\xa2\x18r!\xa2\x18\xf2\"\xb2n\xd8\x91\xc8\xea!_\"\xcaAw\"\xcaa\x8f\"E\x10;U\x86j\xf7+JX\xd0\xb5(qA\xef\xa2\x04\x86\x1d\x8c\x16Y\xecc\xbc\xd0\xb0\x9b\x11\xfc$\x9eF\xa0*gS\xf06\x85\xa8d\x95E\x132\x0f\xf4\xa5\x0e\xe8K\xfd\xcf\x97\xba\x9f\xdf\xe6}\xbe\xdc\xf9|\xb9\xef\xf9-\xae\xe7\xabx\x9e\xaf\xe2x~\x9b\xdf\xf9mn\xe7\xb7z\x9d\xaf\xe6t\xac\xbc\x02\x9f\xf3U\\\xce?\xce\xe3`\xe7\xc2R\xe7\xc2R\xe7\xc2R\xe7\xc2R\xe7\xc2m\xce\x85\xe5\xce\x85\xe5\xce\x85[\x9c\x0b\xab8\x17Vq.\xdc\xe6\\\xb8\xcd\xb9p\xabsa5\xe7b\xe5\x158\x17Vq.\xcc9\x17\x05Lc\xdby@\xee\x01\xa34E\xb1\x96D\xb6\x93E^]\x83\xfb>E\x01\xd4\xd2\x8c\x19\x0b\xd7\xba\xba%\"\xf0\xd1\xd2\xe6\xd8\xf72x\xfb\xb8z\x009\xe6\xdf/:F\\\x80\xa2Mb\xa8\x92\\h\x05\xa9\x15f\x83\xba\xaac[\xc2\x11\xb46\x84\xafB\xa1\x1d\x12\x91\xf1\xb1\"s\x04\xad\"\xf3U\x14\"S\x14x\xa5%!\xf6\xdcC\xbe\x8f^u\x16\x0e\x93z)F4\xa6\xdb\xb38\x98\x13F{\x06e)\x98\xfa\x00\x8a\x94;O\xbbT\x1cL$\x18\x0f\xb4\x9e\xc9\x0fk\x89}%\x81}EyY\\\x9b\xb82\xc9\xb0\x92dXQ2\x16g\xb1^\xe5\x05\x0f\x87\x14\xedR\xcdEN\x18\xdb\xe5 Vv\xd1\x9b\xc1\xce\xb8'\xe7\xb6\x93z\x1b\x04\x14\xe4\xcb\\\xe0\xf9*\xdc\xb0k\xe4\xfc\xb9\x80\xff\xc6K\xbc\x145o\x1cMc;H\xbc\xea\\g\x18w\xba\x86\x95t\x90\x9d \xcd\x0b&\xd2R\xbe=\x85\x90\x87p\x9df*:7\xa2]\xc7\x0d\xd3\x14\xb9\x1dg\x1d\xc7(H_eLX\xba$=d\xff\x14Yn-\xddGP\x8e\xc0\xdf\x16\xab\xc1\xda\x15\x81\xd9zk\x90\xe5\\,\xe1o{D9\x1f\xc6\xf8[\x93(\xe7\x03\x19\x7f\xdb'\xca\xf9P\xc6\xdfZd\xfd|0\xe3o\x07\x04\xc0\x84$\x18\x92\x12@U\x8c\x08\xc0\x00\x92qL\x00\xc6\x90\x0c\xc5+\xd4\x1b\xd0I\x9b\xf1\x859\xf2\x85\x93\xdc\"\x0c\x042\n\x0d\x01\xedBC@\xd3\xd0\x10\xd0:\x8c,\xa0\x81h\x0cl#F\x1a\xd0L4\x06\xb6\x14\x8d\x11\x1b\x8b\xc6)\xec\xf6\xab\x8e\xdd\xa5\x15\xfdV#\xfa\xad6\xf4[M\xe8\xb7Z\xd0o5\xa0\xdfn?\xbf\xdd|~\xbb\xf5\xfcv\xe3\xf9j\xb6\xf3\x8f3\x9d\xd8J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xddJ\xb8\xddJ\xb8\xddJ\xb8\xddJX\xcdJ\x98\xb3\x12\x05\xdb\x1a\x07\x91Z\xb7\xbd\x83H\x9f[\xf3 R\xe4\xb6\x7f\x10ipk\x1d\x84\xaa\xcb<\xa1*e=`\xab\xf5\xaa\xb2\x1ePVq\xe5\xd6\xd0[\xcd\xac\xe8L\x9e\xce\xac\xda`\x9a|Y\xd5\x08\xb3\xcf\x95\xf5+\x9e}\x9e\xa7U\x95q\x0b\xf6\xad6\xa8\xca\x06|\xd9\xb0*\x1b\x02eU\xfb\xb8U\xfeV\x1bUt#\x9en\\\x95\x8d\xf9\xb2,\xe0\x10\xf5\xb7\xad\x96\xae\xbc\xd8\xad\x95\xd35\xb3\xff\xf1\xa0mX\x00\x93\xaaY\x83\xee`0\x18\x0c9d\x9e\xc7.0\xf9b\xbc}\x80?0.\x9aM\x13b/mJ!GmJ!_mJ!w%\xea\x85=\x96\x00@NKH\x06\xf9-Q\x0c\xb9nS\x0cz/Q\x0c90Q\x0c\xf90\xa1\x16\xc8\x8d\x9bb\xd0\x93\x9bb\xd0\x99\x9bb\xd0\x9f\x89b\xc8\xa5 \x9b@^\xdd\x14\xc3\x8eM\xdaD\xe0\xdb\xa4\xeaZ\xdd\x9bh\xab\xcc\xc3\x1bX\xee\xe4\n^\xae\x10\xc6\xe4\x01\x8a\xc4\xf3}\x99\xe3\xfb2\xbf\xf7en\xef\xb7x\xbd/uz_\xea\xf3\xbe\xd4\xe5}\xa9\xc7\xfbR\x87\xf7\xa5\xfe\xeeK\xdd\xdd\x97z\xbb/uv_\xea\xeb\xbe\xd4\xd5}\xa9\xa7\xfbrG\xf7[\xfd\xdc?\xc2\xcd}%/\xf7\xd5\x9d\x1c\xf6g,\xf3g,\xf3g,\xf3g,\xf3g\xdc\xe2\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xee\xcf\xb8\xd5\x9f\xf1\x11\xfe\x8c\x95\xfc\x19S\xfeL!\xc2\x0d\x8a\x178\xdcj\x1b/\xf1\xe6\x18\x1d\xaa\x07\xe7\xe5\x03\x01|\xe5\xb9.\n\x1at\xf1\xbb\x00\x9c8q\x88q\x03.~\x17\x80\xf3H\xaa\x86\xf2;\x1b5p\xc7\xc9\xac\xedZ\xa4\xde\xb1rk;\xb9\xe4;Vvm'\x97~G\xcb\xaf\xedd-\xd8\xf3-\xd8\xb7\xb4`\xcf\xb5`/o\xc1\x9ek\xc1^\xde\x82=\xd3\x82\xfdi\x01-\xebXY\xe8p\x94oQ\x04\n\xeeE\xe1[=\x8cB\xab8\x19I\xa0\xecg\x0c\x91\x92\xab14\n\xde\xc6P\xa88\x1cE\xa2\xeas\x0c\x91\x92\xdb14\n\x9e\xc7P(\xcc\xc1\xaa\x81&\xe7\x92\xfe\x91\x1e\xe9\x1f\xe7\x90\xfe1\xfe\xe8\x1f\xe9\x8e\xfe \xde\xe8\x1f\xef\x8c\xfe\xb1\xbe\xe8\x1f\xed\x8a\xfe \x9e\xe8\x1f\xef\x88\xfe\xb1~\xe8\x1f\xe9\x86*\x1e\x87\x8f\xf48|\x9c\xc7\x1d3\xc7\x92`%\x8f\xc3'x\x1c>\xde\xe3\x8e\x9dki\x02%\x8f\xc3'x\x1c>\xde\xe3\x8e\x9dsi\x02 XKR;\xf5\x9cCq\x055\xcc\xdf\x8d\x91\xb2\xb7Ob\x84\xf3;\xa2\x0d\xaazB\xe3\xecy\x12\xe2uJ\xe0\xaa'4\xae\xf8\xa8~\x0d\xca\x7fU\x18\x8e\x0f\x80\xe0\xd9\xc8\xae$;\x05\x94\x8bOA%-\xa0pE#\x14Z\xa10\xa9\x94M\xf3\x15[\xe6+7\xccWk\x97\x7f\\\xb3\xc4-\xc0\x8a-\xc0\xca-\xc0j-\xc0\\\x0b\xe8N\x92'r\xc3\xc8v\xbct\xcf\xbdu@\x1b7e\xdd1[8\"\n\xd9\xbb\xe9\xda\x90(d/\xc1k\x03\xa2\x90\xbdm\xafYD!{\xad_\xeb\x13\x85\xec\xfb\x034\x93(d_T\xa0\xf5\x88B\xf6\x8d\x08\x9aA\x14rJ\xd0\xad\xa6P\xe7$\xd2{d1{0\"\xd4\x1a\xce\xccy\xfb8L\xed\x14i}\x8b>o\xb0\x08c\xff\xbc(\xfb\xb1o\xb9h\xf9\xd3D\xf0\x1cd7\xd6\xc5\xec\xc6:\xcc\xaex\x0e\xb23L\x89x\x86)\x90\xaf,\x809\x8e$\x12\x1a#\x81\x88e\x01\xc8\xb1\xd7\x93\xc8\xd8\xeb d,\x0b`\x8eC\x89\x8c\xbd\xa1@\xc6\xb2\x00\xe4h\x1a\x12\x19MC cY\xa00\x96\x1e`\xd7\xd2\x88\x0f\x1c<\x8fwI9\x9e\xe6`R\x96\xa7\xfa\x98\x9c\xe9\x89n&ez\xaa\xa7\xc9\x99\x9e\xe8lR\xa6\xad\xfe\xa6\xe0p\n\x93w\xe3\x85\xfes;\xa1\x84\xe1\x89>(\xe1x\xb2\x0b\xcax\x9e\xea\x81\x12\x9e';\xa0\x8c\xe7\xa9\xfe'\xe1\xf9D\xf7\x93z\x1a~nO\x930<\xd1\xd3$\x1cO\xf64\x19\xcfS=M\xc2\xf3dO\x93\xf1<\xd5\xd3$<\xdb=\x8db:\xc7\xb6\xf3\x90EP\xf9y\xce\xf3x9\xb7\x7f\xd4\xcf\xb2?\xdd\xf1O\x10t\x04AG t\x08A\x87 t\x00A\x07 \xd4\x82\xa0\x16\x08\xedC\xd0>\x085!\xa8 B{\x10\xb4\x07B\x0d\x08j\x80P\xdd\x02\xa0:\xdb\xae\xed\xca+\x02\xde\x02\xbbJp\x8e}qf\xe8\xfa\x0b\xded\x05|$\x82\xb3f+\xe0C\x11\x9c5]\x01\x1f\x88\xe0\xac\xf9\n\xb8%\x82\xc3M\xed\x8b\xe0\xac\x19\x0b\xb8)\x82\xb3\xa6,\xe0=\x11\x9c5g\x017Dp\xd0\xa4%\xf6\xaf:{\x93:@v\xacQ\x10\xc3`V`\xae\x1d?h\xcb\xd8\xdeW\x08\xd3dVw\xbe\xe7R\x00\xcbb\x96ad\xe1p\xc8\xacG\x13\x0foP\\\x15s\xefB\xc3\xf95\x0b\x1ad\xdb6#A\x18\x06\x94\x08\x8e\xe3@lH\x08B\x08\xd0E\xae\xdd\n\xb2\xe8g\x7f\x00\xf5\xd7\x80\xc5\x02PV\x8c\xdc\xba\x92\xa1\xde\xd7\x19\x0cQ\xbcX\xf4\x0ds\x00IJ\x81\x86=\x8biN\x18\xdb\xc1\x92\x10c\xc0]\xe9_\x86\x98\xe00\xe7\xae\xd9\xef\x11\xc6\xe1\xb6Dd`H\n\n\xf4\xd7\xc5|a\xd8\x8cy\xa2u\x1c\xe1Z\x10\x0b\xf5\x1c\x9b\xbd\x9c\x90s\xa2qv\x7f`.z\x80\xea\"/\xa8=\xd1\xb5t}\xc4\xe8n\x15\xa6\x14&S\xe0\x9c\xb1\x10]>\xd2aW\xa0Q\xb6\xe9\x0eA\xb7G(\xa8{\x869\x1cZ=\xd6\xb3I\xc0\xd8\x1e\x0f\xfb\xb0\xdf\x11\xb01Bs\x87iW`o\xf6M'5\xe6\xfd> \xcd\x1c\xafQ\x03\xea\xf7\xc7\xec\xcb\n\x88r\xd3\x1a\"\x17\xb4)\x89\x1a\x0f\x1c\x87u\xe1\x1c\x85\x12\x1a\xe8\xb8\x88\x03n\xedd\x85\\\n\xb6\x18,\x16\x0b\x04\xc2(\x15\xa0\xd1\xc2]X \x8eq\xb9\xc5\xc2As\x10H\xf5\x10w\xe1ro'\xc3a\\_\xb1/\x80\xd5-AZkK\xad\x8e<\xe6\xb6\xf3\xb0,\xde\x91ZPH\x83\x90\x8ap\xd4B\xc8\x85$\x15\xe1\xb0\x85\x90\x0bP*\xc2A\x0b!\x17\xaeT\x84V\x0b!\x17\xbcT\x84\xfd\x16B.\x94\xa9\x08\xcd\x16B.\xb0\xa9\x08{-\x84\\\x98S\x11\x1a-\x84\xdc\x0cY\x11\xea\x96\x9c\x90\x0b\x81\xe6K\xad\x8e\x828\xca\xb6\x80\xa8&\x86\xdc\xa7-<\xaa\x89!\x17j\x0b\x96jb\xc8\x8d\xdaB\xa7\x9a\x18r\xa5\xb6@\xaa&\x86\xdc\xa9-\xac\xaa\x89!\x97j\x0b\xb2jb\xc8\xad\xdaB\xae\x9a\x18r\xad\xd6\x00\xact/\x9e\x92\x0f\xc7\xe6K\x8d\x88\xc8x\x02.8\x9b/\xb5&>\xe3\xf1\\\xa86_ju\xb4\xc6\xc3\xb9\xc0m\xbe\x14A\xb90n\xbe\xac\x824\x1e\xcc\x05u\xf3\xa5F\xc5u< \x17\xe2e\x92\xd7Q\x1e\x8f\xe7\x02\xbe\xba\n\x01\x01\x17\xfeU\xba/\x02<\x9e\x00\n\x06+\xc7\x80\xe0\xect9_\x16+\xe4\xc8\x8eQ\x90\xf2\x14D!l\xe3l\xc2\x03\xda\x01D\x98\xf3\xa5\x00\x0c\xc5\x9b\xb5\xa2D$|\xf49_je\x00\n\xe1\xf9X4s\xa3,\x1c\x85\xd0|d:_VA\x00\x87\xe7\xe3\xd4Zz\x11 \x18\xb5\xce\x97U@\nt\x02 \x86\xadk\x11RA\x11me\xb8<\xd4\xe4I\xa0\xf8v\xbe\xd4\xea\x10\x176\x1f\x1b\xedfM\x11\xa1\xf9\xd8\xb7i\x88\x88\x86\x8f\x84\x9b1&\x8b\xe0\x80A \x88\x8b\xf3\x81C\x00\x07\xa2d\xa2\xb3\xc2DP\xcc\x9cu\xd8,l\x86\xc6U>\x82\xaeZ\x91\x87\xab\x10 \x10O/Eh(\xba\xae\xdb \xa0\x81b\xed\x8a\xa6\x0e\xb7\x81\x81\x0d\x88\xbc\xb3a\x87\x08\xbe\x013\x02qxC$R2\x14\x957T\xe2\x0e\x06\xc4\xe8\x0d\x99hT\xe1#\xf6\xf9\xb2\x0e\xd79\x020r\xcf\xef\x97\x17s%t\x07\x9d,\xce\x7fn\xd6N\xec\xbb\xd7rd3\xf3\x8a\xb9\x11\x18\x8a%71\x17\xf0zn\x16sl \x14Cn\xe6.\xd0\xd5\xe4-\xe6W#(v\xdc\xcc^\x80\xe5\xacx6\xdc\xac_\x00\x8bY\\\xcc\xa8,\xa7Xq1A\x01%\xc3\x021C\nE\xb1\xe5\xe2\x86R+U\xe8 Q\\\x0d\xa1\x18r\x81\x05)\x81\x9c#\x81\xa1Xr\xa1\x07\xe1[y8\xd1\xe2\x7f\x05\x86b \x05'\x05E\x0bC\x88\x17;\xdc\x10\x1dI\x1b\xeb-]-C\x90\xecd+h\x92l\xd4\xcax$f\xcc.\x8fH\xb2a+\xe3\xa1\x981\xbbt\"\xc9\x06\xad\x8c\x07b\xc6\xec\xb2\x8a$\xb3Z\x19[b\xc6\xec\x92\x8b$\xeb\xb72\xee\x8b\x19\xb3\xcb1\x92\xcclel\x8a\x19\xb3K5\x92\xac\xd7\xca\xb8'f\xcc.\xe3H2\xa3\x95\xb1!f\xcc.\xf1\x88\xae$\xed 5\x82d\xdc\x96' Ie\x9d\xa4F\xc8\x98\xc3\x1d\xa5J%\xb41\x1f\xca\x99\xc3\x9d\xa5J5\xb41\x1f\xc8\x99\xc3\x1d\xa6JE\xb41\xb7\xe4\xcc\xe1NS\xa5*\xda\x98\xf7\xe5\xcc\xe1\x8eS\xa52\xda\x98\x9br\xe6p\xe7\xa9R\x1dm\xcc{r\xe6p\x07\xaaR!m\xcc\x0d9s\xb8\x13\x95\x81\x9e\x98w\x05 Y\xcb\xa2\xc3e[HW#\n\x8e\xd0\xd2\x00\x0c\x17\xa9\\\x8d\x94=\x174\x02\x8b\"8~$\xd3;\xd2*\xd8(\x12X\xb2\xc0\x01%\x91\x10\x92V\xc0\x84\x95\xc0\xb2\x19\x8e0\xcb\x0c\x92\x94\xb7\x94\xaf \xe4\xac\xd3MR\xceT\x84\x08,\xc9\xe0\x18\x94\xc9NIk\x00\"Q 9\x00\x07\xa5dJK\xae|&4\x05V\x89p\x94J%\xc1\x14\xda!\xadC\x10\xb6Ry\xb3\xf6~@\x06\x9c\xc0\xbaP\x18\xc7V\xa96i\x0d-\xcc\x05\x81-\x95\x98\x93\xf2'q\x82Z\x84i\xbc\x9a\x89B \xbddci\xae\x1a\x85\xb0z\xa9\x12Y/\xd9\xe0ZZ\x93 \xce^\xaa\x84\xdaK6\xda\x96\xd6$\x08\xbc\x97*\xb1\xf7\x92\x0d\xbf\xa55 \"\xf1\xa5J0\xbed\xe3qiM\x82\xd0|\xa9\x12\x9d/\xd9\x00]Z\x93 V_\xaa\x84\xebK6b\x97\xd6$\x08\xde\x97*\xf1\xfb\x92\x0d\xe1\xa55 \xa2\xf9\xa5J@\xbfdcziMpdBl\xf6\xb5\x8fA\x92\x9e\xab\x16\xef\x13\xbb\x83\n\xb5\x89{\xaf\xda\x02\x80\xd8NT\xa8M\xdc\x83\xd5V\x04\xc4\xfe\xa3Bm\xe2^\xac\xb6D 6,\x15j\x13\xf7d\xb55\x03\xb1\xc3\xa9P\x9b\xb87\xab-\"\x88-Q\x85\xda\xc4=ZmUA\xec\xa1*\xd4&\xee\xd5j\xcb\x0cb\xd3U\xa16q\xcfV[wT;l\xe2\xaajDQO\x15\x14\x01\xdbo\x05^\xca\x8c\xe3\x03\xed\xcc\x15\xd0zsN\xcc\xad\x810<\xf9\xad\xbb\x82\xa0\xd8\xbd\x133,\xcb\x19n\xfc\xc6^\x81^\x86X\"\\^\xcap\xe27\xfd\nl\xb1\xc7 \xe6U\x96\x93\xdc\xf8-AR'm\x0c)\x14-$\xb0mX\xd0\x14{\x80b\x9ee9\xc5\x0d\xdaT$%h\xe3I\xa1(\xce\xd0\xc6#\xe1\xb0\x91\xe0\x05\xbd,\x84\xe2 \x9f\xbc\xcb\x08\xaa\xcdI1\xcb\x1a\xc1\xb97\xbbsYjK\xca\x0d\xe2\xc4\xefjR:\x92\xf2#0\x0cW~\xdf\x93PQ\xbec\xd6\xa2\xc6\x02Cq\x85vF\xcbN!g\x08\xf1\x02\xb6M\xc96\xb5p$A\x14_hg\xb5 \xec\x8dd\xcd\x98\x97R\x9c\xa0]WB?s\xbc\x968x\x03ax\xf2\xdb\xb2\x05\x81\x9c\x1d\xcf \xda\xb2%U#\xe7G`h\xed\x01\x9b\xba\x04E\xb5\xaf\xdb\xc2\xb8\x86Q\xbc\xa1\x9d\xdf\x82\x88\xd8\xfc\x15s&A\xb4\xaf\x03\x9b\xc3\x14I\x8b+Q(\x8a3\xb4\x81L\xd1\xb4\x0d\xc74\x8c\x96\x1a\xd8e\xa6\x88\xa43$\x81a\xb8\xf2\xfb\xd0\xa5\x07-\x15b\x02\x12T\xf0\x05\xd2&\xc2\x08\xa18\xa6#\xe5.c,\x0e\x19\xc8#=R\xf6l\xe0\x00U\"\x8a!\xeaC@\xd2\x1a\xa8H\x02b/\n*\xca3CR\xe6Dh\x01\xb1\x16E\x19\xf5\x01#)s\xca 9\xf6\xa2\xb0\x839\x8f\xa4\xa0}y=\x928\xa4>\xc4$\xad\x84\x8a\x19x\xf6\xe2\xc0\x849\xf3\xa4\xd0\x92\x96\xaa\xc4\x91\nyP\xaa\xbd\xb3\x11\xb37_\x898t!\x8eVI\xeb`\x02\x18\xb8\xdf\xc1\xb1Ly\x16Kn\x0f9kQpC\x1d\xdcR\xb1\x85\xbc\x1aQ\xb4C\x9d\xf5j7\x059\x07\xf0\xd5\x88\xc3\x9f\xeax\x98\xbcw\xcb\x99\x0b\xe3!\xfa0\x99\x82\xae\xe4\x15\x89\x03\xa4\xf2\x00\x9a\xb4\x06\"L\xe2Y\x8b#&\xf2\xb4Z\xbb\x19\x889\x1e\xaaD\x18B-\xdb\xf9KY\x8bc*\xea0\x9c\x82 \xa4\xd5\x88\x83,\xf6\xfc\\{ML\xa8\xc5W&\x8e\xba\xe8Sw\xd2\xaa\xf8\xd8\x0b\xe8\x84\xc20\x8c9\xa9\xa7R\x93\xdc\x85\xc5q\x19{\xbcO\xa5\xae\xb6 K\x18\xa8Q\x87\x02Uj\x92\x07&\x92\xc8\xadu\x17\x99\xc0\x08*\x00\xf7\x94#[?\x08\xbe\xdf\x1a\xd9F]\xd4\xedY\xdc{j#\xbb\xd7\x94C\xc5f]\xcc\xbfY7\xb2\xfbu)\xffj\xdd\xc8\xb6\xeaR\xfe\xdd\xba\x91=\xa8K\xf9\x97\xebF\xf6\xb0\xa9\x97\x7f\xbbn\x84\xeb\x06k\x18-R\xae\xd5\xd8\xa0\xcb\xc1\xa6\xe3\x1e\x03\x820&\x8d\x01\x94\x80\xfb4\x04\xd0\x04\xb6h\x08\xa0\x0e<\xa0!\x80N\xf0\x90\x91\x05PL\xdc(&\xce\x06\x16N3\xb1\xc1\x00@\xd5\xc4=\x16\x05\x81L\x06\x04('\xee3\x18@;\xb1\xc5`\x00\xf5\xc4\x03\x06\x03\xe8'\x1e\xb2\xf2\x00\n\x9a7\n\x9a\x87i\x1a\xfa\x9c\x86\xe6\x06\x8b\x00U4\xefq0\x08e\xb2(@I\xf3>\x0b\x02\xb44\xb7X\x10\xa0\xa6\xf9\x80\x05\x01z\x9a\x0f9\x99\x00E\xa5\x8d\xa2\xd20\xe2\xb4\x94\x1aT1\xa8\xa2\xb4Gc \x88IA\x00\xe5\xa4}\n\x01h&\xb5(\x04\xa0\x96t@!\x00\x9d\xa4CZ\x0e@!\x1bF!\x93\x16?\xda@\x1ab\x89@\xbdm\x00\xbdq\x84\x10\x1d\xafL\x96\x0cP\xf0\x86W0K\x05(}\xc3+\x9d\xa5\x02\x0c\xb1\xe1\x0d\xc1R\x01\xc6\xd9\x00\xc6\xe1\x1a\x06Xl\xc5\xce\x125\x11<6\xae\xc0Y\x83!\x02-\xb6\x82\xa6\x12\x96\x10\xa2\x03\xa6\x17\x86\x0c\xb0\xd8\n\x98q\x18*\xc0b+`\x12b\xa8\x00\x8b\xad\x80y\x89\xa1\x02,\xb6\x82\xa6*\xb6a\xc0\xc7\x85l\xfd\xe0\xdb\xf1\xd2\x0bX\xdb\xf8\xb6Q\x95@\x06\xf0\xed^]\x0c\x95\x9aU)\xf0\x95'\xbb_\x15\x02\x9fU\xb2\xad\xaa\x10\xf8Z\x92=\xa8\n\x81\xaf-\xd9\xc3\xbaN\xa0\xa1\xb8j(\x18\xbf\xf8\xd8\xa0\x8a\xc1&\xe3\x1e\x8d\x81 &\x05\x01\x1a\x8f\xfb\x14\x02\xd0\x00\xb6(\x04\xa0\x06<\xa0\x10\x80.\xf0\x90\x96\x03PH\\+\x04\xec\x9b~l\xd0\xe5\xa0J\xe2\x1e\x03\x820&\x8d\x01\x94\x12\xf7i\x08\xa0\x95\xd8\xa2!\x80Z\xe2\x01\x0d\x01\xf4\x12\x0f\x19Y\x00\xc5\xcck\xc5\xc0\xf3\x8c?7\x18\x00\xa8\x9ay\x8fEA \x93\x01\x01\xca\x99\xf7\x19\x0c\xa0\x9d\xb9\xc5`\x00\xf5\xcc\x07\x0c\x06\xd0\xcf|\xc8\xca\x03((\xad\x15\x04\xc4)~j\x90\xa5\xa0j\xd2\x1e\x05\x81\x10&\x89\x00\x94\x92\xf6I\x00\xa0\x91\xd4\"\x01\x80:\xd2\x01 \x00t\x91\x0e)\x19\x00ElhEL\xe4n\xb3\x01\x143Qp\xa4\x0d\xaf-\x96\x0c\xa2\xe248i\xf5\xb4\x0d\xa7\xd4I\xab\xe7m8=OZ=q\xc3\xa9~\xd2\xea\x99\x1b\xde\x1al\x83\x00\x0b\xad\x98Q\xbf\"\x81\x87\xbc\x154 \xd0$\xa0\x85V\xc0\xc4\xc0\x90AT\xfc\\A\x13\x01\x16Z\xf1\xb3\x07M\x03Xh\xc5\xcf'4\x0d`\xa1\x15?\xc3\xd04\x80\x85V\xc0\x9c\xc34(\xb7P\xfb[-\xe9\xd7\nFv\xfer\xce2\x96\x01\xf2-d\xa9 \xe5BA \x84I\"\xc0\xc4\x0b \x00s/$\x00L\xbf\x90\x000\x03C\xc9\x00&a\x08\x84(\x0f\xc3A\x04\xa9\x18\x1e\x07\xc1L\x0e\x06&d8\x14\x98\x93\xe1P`Z\x86C\x81\x99\x19^.09C\xc2D\xf9\x19\x1e#H\xd1\x00@\x08g\xf280Q\xc3\xc3\xc0\\\x0d\x0f\x03\xd35<\x0c\xcc\xd8\x00\xb2\x81I\x1b\x12'\xcc\xdb\x00 A\xea\x06BB@\x13\x00\x82 \x1c\x00\x07\xe6p\x00\x1c\x98\xc6\x01p`&\x07\x92\x0fL\xe6\x90@8\x9f\xc3\"\x04)\x1d\x0e\x06\xa1L\x16\x05&vX\x10\x98\xdbaA`z\x87\x05\x81\x19\x1eN&0\xc9\xc3)\xaa=\xcf\x03kN1\xd5\x03\xeaS-\xdb\x03)Y)\xe1\x03)^)\xe7\x03\x19C)\xed\x03\x19H)\xf3\x03\x1aM-\xf9C\x92*\xe6\x7f8\x92cR@<1D\x0b\x91\xc2\xd3\x9aJ\"\x88#T\xcd\x05q\x84\xaa\xe9 \x8eP5#\xc4\xb7Q9)\xa4\xe5\xdfs\x8f\xe1\xbc\x10Q(H\x0d\x91\x08\x08`\x12\x000AD\x94\x839\"\xa2\x1cL\x13\x11\xe5`\xa6\x88\xac\x1fL\x165\x00Q\xbe\x88E\x08RF\x1c\x0cB\x99,\nL\x1c\xb1 0w\xc4\x82\xc0\xf4\x11\x0b\x023H\x9cL`\x12\x89@\x89\xf2H\x1cD\x90J\xe2q\x10\xcc\xe4``B\x89C\x819%\x0e\x05\xa6\x958\x14\x98Y\xe2\xe5\x02\x93K\x04L\x98_\xe21\x82\x14\x13\x00\x84p&\x8f\x03\x13M<\x0c\xcc5\xf100\xdd\xc4\xc3\xc0\x8c\x13 \x1b\x98t\"pp\xde\x89\x01\x08RO,\n\x02\x99\x0c\x08L@1\x180\x07\xc5`\xc04\x14\x83\x013Q\xac<`2\x8aUPk>\nT\x98ZJ\n\xd2\xa2RV\n\xd0\xacJb\nP\xb6Jn\n\xd0\xbfJz\n0\x89J\x86\n\xb2\x92R\x92\x8a T\xcbS\xb1\x04G\xa4\xaa8R\x80\x12\"\x04\xe7(\x85\x84\x15K\xa6\x98\xb3b\xc9\x14\xd3V,\x99b\xe6\x8ak\x9b(y\xa5\x90\xbdR\xf8&Kd\xeb\x9a_\xc5fPF\xab)\x14%\xb4\x08\x04\x040 \x00\x9c\xcej\xca\xe1lVS\x0e'\xb3\x9ar8\x97E\xd4\x0f\xa7\xb2|f\xad\xc0\"\x0c\x16!Jd\xb10\x08e\xb2(8\x8d\xe5\xf3\xb1=\x0b\xb2X\x10\x9c\xc4\xf2\xf9\x98\x9d\x05\x0d9\x99\xe0\x14V\x83\x12f\xb0X\x88(\x81\xc5\xe1 \x98\xc9\xc1\xe0\xf4\x15\x8b\x82\xb3W,\nN^\xb1(8w\xc5\xc9\x05\xa7\xae\x1a\x988s\xc5aD\x89+\x1e\x08\xe1L\x1e\x07\xa7\xad8\x18\x9c\xb5\xe2`p\xd2\x8a\x83\xc19+^68e\xd5\xe0\x04\x19+\x1a JX1(\x08d2 8]Ec\xe0l\x15\x8d\x81\x93U4\x06\xceU1\xf2\xc0\xa9*FA\n\x99*Hc\xaa\x89*@\x8f\x8ay*^\xb9ji*^\xe1jY*\xde\x08jI*\xde0j9*\xc0X\x8a)\xaa\x86R5C\xc5P\x1c\x95\xa0bi!R\x88\x12\x9c\xae\x94\xd2S\x0c\x9drv\x8a\xa1SNN1t\xca\xb9)\xb6}\xea\xa9)\xbf\x8c\xd4\xa0\xccT]&JL5\x00\xa8\xdcl\xca\xe1\xb4T]\x0cg\xa5\xeab8)U\x17\xc39\xa9\xa6n8%\xe5\xd3k\x04\x16`0\x00QB\xca\xe7\xc3\x7f\x16d2 8\x1d\xe5sq=\x8b\xb1\x18\x0c\x9c\x8c\xf2\xb9\x88\x9d\xc5\x0cYy\xe0TT\x0d\x12f\xa2\x18\x84(\x11\xc5\xc2 \x94\xc9\xa2\xe04\x14\x03\x82\xb3P\x0c\x08NB1 8\x07\xc5\xca\x04\xa7\xa0j\x948\x03\xc5BD (\x0e\x07\xc1L\x0e\x06\xa7\x9fX\x14\x9c}bQp\xf2\x89E\xc1\xb9'N.8\xf5T\xc3\x04\x99'\xaa\\\x94x\xa2A\x10\xc6\xa41p\xda\x89\x82\xc0Y'\n\x02'\x9d(\x08\x9cs\xa2e\x81SN\xb4b\xda3N\x80\xa2\x14\x13N\xbc\xf6\xd4\xf2M\x9cF\x95\xd2M\x9c\x92\x95\xb2M\x9c\xde\x95\x92M\x9c)\x94rM\xbcu\xd4RM5\x9db\xa6\x89\xc6\x1f\x93hb(\x01B\x88\x0e\x9a{T\xd2L4\x95j\x96\x89\xa6RM2\xd1T\xaa9&\xa6]\xa7\xa5\x98\x04\xd9$\\\x85SP6\xa9)\x14e\x93\x08\x04\x040 \x00\x9cMj\xca\xe1lRS\x0eg\x93\x9ar8\x9bD\xd4\x0fg\x930\x13\xd7\xb3\x08\x83E\x88\xb2I,\x0cB\x99,\n\xce&a>\x16gA\x16\x0b\x82\xb3I\x98\x8f\xb2Y\xd0\x90\x93 \xce&5(a6\x89\x85\x88\xb2I\x1c\x0e\x82\x99\x1c\x0c\xce&\xb1(8\x9b\xc4\xa2\xe0l\x12\x8b\x82\xb3I\x9c\\p6\xa9\x81\x89\xb3I\x1cF\x94M\xe2\x81\x10\xce\xe4qp6\x89\x83\xc1\xd9$\x0e\x06g\x938\x18\x9cM\xe2e\x83\xb3I\x0dN\x90M\xa2\x01\xa2l\x12\x83\x82@&\x03\x82\xb3I4\x06\xce&\xd1\x188\x9bDc\xe0l\x12#\x0f\x9cMb\x14\xa4\x90M\x824\xa6\x9aM\x02\xf4\xa8\x98M\xe2\x95\xab\x96M\xe2\x15\xae\x96M\xe2\x8d\xa0\x96M\xe2\x0d\xa3\x96M\x02\x8c\xa5\x98Mj(U\xb3I\x0c\xc5Q\xd9$\x96\x16\"\x85(\xc1\xe9J)\x9b\xc4\xd0)g\x93\x18:\xe5l\x12C\xa7\x9cMb\xdb\xa7\x9eM\xc2eP\x06e\x93\xea2Q6\xa9\x01@\xe5fS\x0eg\x93\xeab8\x9bT\x17\xc3\xd9\xa4\xba\x18\xce&5u\xc3\xd9$L\xaf\x03X\x80\xc1\x00D\xd9$\xcc\x07\xf9,\xc8d@p6 s\xf1;\x8b\xb1\x18\x0c\x9cM\xc2\\l\xceb\x86\xac{U\x1fl?w\x15\x1fV\x00w\x17\x1f\xd4\x00w\x19\x1fR\x01w\x1b\x1f\xd2\x01w\x1d\x1fR\x02w\x1f\x1f\xd2\x02w!\x1fT\x03}\xe7\x1e\xd6\x01}\xe9\x1eT\x00}\xeb\x1ej=}\xed\x1ej:}\xef\x1ej7}\xf1\x1ej4}\xf3\xbelq\xfb\xc1\xcb\x033f\x90\x17UD\xa3\x1d\x05\x01\x07<\x12\x01\x8ey$\x00\x1c\xf6H\x008\xf2\x91\x00p\xf0\xa3d\x00\xc7?\xf6\x00\xabh\x08\xe4q\xe0(\xc8\xc1\xc0\x81\x90C\x81c!\x87\x02\x87C\x0e\x05\x8e\x88\xbc\\\xe0\xa0H\xc0\xe4\xe3\"\x00\x04\x87F\x1e\x07\x8e\x8e<\x0c\x1c y\x188F\xf20p\x98\x04d\x03GJ\x02\xd72XBHp\xbc\x04\x80\xe0\x90 \xe0\xc0Q\x13\xc0\x81\x03'\x80\x03\xc7NH>p\xf8$\x80\xb2\x11\x94\x83\x81\x83(\x8b\x02\xc7Q\x16\x04\x0e\xa5,\x08\x1cMY\x108\xa0r2)l5\xaa\x9ef\x0f\xc8\x83W\xc2\x81\x96@\xc0\xe3l\x03\x80\x87\xd9\xa6\x1c\x1ee\x9brx\x90m\xca\xe11\x96\xa8\x1f\x1eb\xe9\xfd[\xe1\x08\xcb\xc2\xe0\x01\x96A\xc1\xe3+\x03\x82\x87W\x06\x04\x8f\xae\x0c\x08\x1e\\Y\x99\xe0\xb1\xd5gF\x1b\xd1\xd0\xca\xe1\xe0\x91\x95\x85\xc1\x03+\x8b\x82\xc7U\x16\x05\x0f\xab,\n\x1eU9\xb9\xe0A\xd5g\x07\x18\xd1\x98\xca\x03\xe1!\x95\xc3\xc1#*\x07\x83\x07T\x0e\x06\x8f\xa7\x1c\x0c\x1eNy\xd9\xe0\xd1\xd4\xa7\xc6\x1a\xd1`\xca\xa0\xe0\xb1\x94\x06\xc1C)\x8d\x81GR\x1a\x03\x0f\xa44\x06\x1eG\x19y\x14\x86Q\xc1\x88\x89\xeb\xe1F4b\x12\x08x\xc4l\x00\xf0\x88\xd9\x94\xc3#fS\x0e\x8f\x98M9\x96\xdc\xca\x05\xfajr\xc1\xa8\x10\xa6\x95C\xdb7\x12Kf\xae\x1d?\xb4\xf2\x92}I5\xe3\xf3\x80\x0e)\xda\xa5\x9a\x8b\x9c0\xb6S/\x0c\xce\xb1\x17 -]\xc5\xe1z\xb9\xa2 \xd6\x81\x8b\xe2\xac\x98\xa3\xa9K\x18\xc7\x0b51M\x10\x06Ha\xe9s\x00d\xce\xd6Q'\x88\x0d\x91)H\x0e\x91\xe5\xc2+H\xaf\xb0p+\x9b\xe4\x9f\xd4\"\x9eJ\xa5A<\x95B{\xc4\xa2\xe3\x93D\xe7\xa9TD\xe7\xa9\n\xd1)\x8a\xb4D\xd9\xd8[\x06\xe7YT\xc0\x94\xc7dy>Q2\x00\x87\x048(HQ\xac`\xed\x03#E\xed9bA\x18\x08(\x0b\x83)\xc5Q\x90G\xc1\xfbR\\y\x83DF\xbf]D\xffh aaZ-G#`a0$\x0c\x0d\xaa,\x9c\x7f!~\x11\xc6\xfe\xb9cG^jc\xef\x11\xb1P\xccBq\xb8E\xb1c'\x1cr\xcd\"\xd7Q\x04#\x03\x16y\xd2p\x98\x12\xce\xa1\xd4\x12\x00-n\x0c\x00\x16\xb7\x07\x00+\x0c*\xcan\xda\xb8\x98Z;9\xb0\xa4\x99\x1cV\xd2J\x0e\xab\xd0HA{8\xb7\x92\xb5\xe7\x08\x1f\xe4\xb1\x92\xf6pX`8]h\x833\xe6\xc1\n\xd9n>\xab/\xc2 \x8b\xf5\x1e\xd19\x1fR/4\x8b\xa5K\xd6s\x80\x94\x0f\xa1\x17\x06Ql\xf2\xc5=\xa2\xb8\x07\x05\xea\x0b\x93@\x18@\x90\xbe\xe8S\x00\x88\x85E\"\xf8\xe2\x01Q\xdc\x1d\x0d\x01\x06C\x12Q\x00\xda{\xc3\x81\xd5\xbd\x16$\"\xf5g\x9d\xae\xc5\x02\x005a\x04\x9a\x01d\x07\x1a\x01\x99\x82F\x08\xacA\x83`\x83\xb0\x18\xd0&\x0c\x080\x0b\x8d\x10X\x86\x01\x15\x18\x05\xeb(\x8cU\x99\xc9|\xa1\xc5\xfcV\x83q\xb4\xa4\xbd\xfc6s\xf9m\xd6\xf2\x15\x8c\xe5\xb7\xdb\xcaW0\x95\xdff)_\xc1P\xfe\xb1v\x12\x98\x04\x0bM\x82[M\xc2\xd1\x92&\xc1m&\xc1m&\xc1\n&\xc1\xed&\xc1\n&\xc1m&\xc1\n&\xc1\x80I(\x8c\x8f\xecd\x1d\xa3C\xd3O\xb2\xce\x03b\xb2r\n\xd8\x17\x01\x03;\x8e\xc3-\x01\xedq<\xbd\xc0EAZLi\xc5\xcf\xe7Fs\"+m?\xcf\x98\xf86\xc6\x9acG\xe5\xe8\xb0\xb1c\xcf\x0e\xd2\xf3\xe69\x8dO\xe3u\xe0\xd8):\xe4\xc9\x81<5\x82\xce\x83p\x1b\xdb\xd1$\xdc\xa0x\x91\x7f\x9c\xcfs]\x14Lr\xa9\xea\x87\x08c/J\xbcDa\xcc9\xc0\xeaH\x94\xd5\xcb`[4L\xa3EJ\xae\xe3\xbd'\xea\xb9\x1e\x88UU\x9d\x11\x9c\xaem\x05u+\x0c\xf1\x95\xc2|u\x13\xf8\xc7X\xc0W1\x80\xff<\xfa\xf7\x8fT\xbf\xff\xdd\xb4/Q4VW4>F\xd1XE\xd1\xf8y\x14\x8d\x8fT4~\x8a\xa2)\x96U\xb9\xe6\x84Aj{\x01\x8a\x0f\xf5\xa3\xfdy\xe2\xc4!\xc64E\xb1h\xa6\xb7\x12\xecu\x1aN\xc8\x9d\x96\xec\x01\xa3\xddX\xcb\x1e\xf2t\x0c\x0cS\xb0\x86Y{\xe7<\x00bj\xec\xd9\x1buIARPX\x8d9\xf4\x94\x03\x15\x04V\x18M\xcaV\xf8'7\x02\xa0\x84\xdb\xe0\x1f\xdb\x04\xb1\xb4\xf8di\x01JXZ\x0cHK\x8b\x82\xbd\xe8\x10\x85\x89\x97'\x02\x17\xde\x0e\xb9\xff\xd7\xf3\xa30N\xed \x9d\xfcQ\x97\xd8\xf3$\xc4\xeb\x14\x11\x85\x19\xe9y\x8c\x9c\xf4G#\xdau\x88\xbf?\xd1Eg\xc4\xdf\x9f\x14\xcc}\xe0\x04\xcc\x1c\xe7\xcf\x94QAH\x15\x9f\xcc$\xf7\xff\x83\x04\x17\xc9\x88\xff\\\x19)\x01\xb6\x89\x16\x84\xb1o\xb3#u\xf6\x88F\x16\xa370\xa0\xd3\xb0(\xa6#\xc9(>>'X\x0b\xc5\x07J\"\xb9\xe0\x90\x8a\x13\x8d\x85e\xd2)\x88\xa7\xe0m\x8d\xcclt!\x14\x19\nCx\x89\xfd#\x05\x96\xca\xa6jfp\xe6\xe6e\xc3\xbcl\x14f\xa3\xcd\xed\x04\x1d6(N=\xc7\xc6e:;{\xc6\xef\x91l4\xdfsY\xa8\xef\xb9.\xe6\x80i\x18\xb1\xc04\x8c\xb8\xaaS\x9f\xab9\x0fp\x14\x0c~\x00\x9a\x91\xf9\x8ezK\x00\xb4\xb01\x00\x16n\x0f$B\xd1$\x856)8q\xd9P^o\x92vr`q39\xa8\xa0\x95\"\xbb\x1d\xed\xf8e{\xf01\xed\xe1\xc0\xe2\xf6pPA{\xf8\xfa\xcb\xf6PX\xd7\xf3\x0fad;^\xba?7\xb8\xa23\xf6\x01\xf41\xfa\xecq\xf1\xfdym\x8b\xe6\x0f^\x99\x15/f\x90\x92w\xa7kXI\x07ez\xf1\x82IK9'\x86\xbc\xd6J\xfc\xae\xc5\x13\xdaN\xeamP\x03\x19M\x94d\x0c\xd7\xa9\\\xc8p\xcd\xec\x9e-q\xb8=\xe3\x9e@\x82\xe7\xcf\xbf\xa3\xbe\x14\xea\x15\x18|\x95-\x03\xf3S\x11\x9dn\xfe\x9f\x1a\xa8\xab\xa9\xedXQ\x9b\nKC\x95\xf5\x9e\x89Py\xb3\xda@y\x1b\xd9\x16\x18\xdf\xa7\x05\xcd\x06{^+\xa4w\x16R\x98 _\x7f\xb6\xef\xe1/\xe3p{\xd0\xfc\xf0Q\x0b\x93\x9dVd\x0f\xfd0LW^\xb0<_\xc6\xf6>ql\x8c\xea\xb6\xcdm\xe7aa;H\xdbx\x897\xf7p\xd6\xf2r\xc1+)\xa24\x93of\xe5?a;E\xdf~\xd4\x7f\x9a\x88\x9e\x03\x1a\xe5Xu\xba=A\xa7:\x02z:\xe4\xac\xa5\x16^\xdb`\xd7\x89\xe1.\x9b\xeb$\xb7\xc0\x8fFW\xb7HM\x11O\x81:\xcaaI\xc4\xac;\xe6Yu\xc7\x00#\x0d\xdb\xf1\x12\xfd\x7f\xc5A\xbc\xe0\x18\x1f\xe1\xd1OEI\x9d\xa5\x80\x88L \xf2\x9a\xb2\xb4\xcdwz\x90\xeb\xf4\x84\x06o\xf7\x1f\xc0\x17\xb3\x87L0\x1dzAZ\x8fH\xce:N\xc2\xf8\xbc|H#\x93\x95\xed\x86[\x0d\x02N\xea\xc5b\x8c\xb0\x9d\x89\x05\x99\xdd\xc6\xb8\xd3\xb5\x92\x8e\xb3\x9e{\x8e6G\x8f\x1e\x8a\x7f\xec\x1a\x03\xeb\xac;\xea\x9fu\xfb\xfd3\xe3\xa7\xc9\x91x\xb1\x88\xe7\xf6\"\xcd\x04\x0d\x83\x14\x05\xe9\xf9_\xfe\xd2\xf8\x7f\xb8\xd3\n\xe4\xb9\xde\xd1;\xc6 \xdauz\xd1\xaeC\x9e\xf7\xeb\xfd4Q\x86\xe5\x07;c\xdb\xf5\xd6\xc9\xb9\x17\xacP\xec\xa5\x93f\xd2\xe4\xd6\xd1\x93\"\xf3\x99\xe7e\xf4I\x11A\x1a\xba\xfeb\xb2ByN'\xff\xf91\xcf\x98\xee\xce5\xf9\x9cu\x846Ui$\x1a\xcd\xfd\xbb\xd0\xeb\x99\x18Ej_\x10d\xcc\x97\x9a\x1dx\xbe\x9d\xa23\xc1s\xa8/\x11\xa5\xc2\xd0\x89=\xc4IM\xdb\xec(\xd0\n\xa6\xa5~\xd4\xf4Ce\x17\x9d-2\xea\"\x83-\xea\xd5E=\xb6\xc8\xac\x8bL\xb6\xa8_\x17\xf5\xd9\"\xab.\xb2\xd8\xa2\xf1x\\\x17\x8e\xc7c\xa0\x98*\xe7\x00\xbe\xbdk\xa45\xfa\xc3\xfe\xc8\x1c\xf4\x87,\xaa\xf4\xf2\x1aY\xfe\xce\xc3\xbc\xd4\xb3q\x0d\xe3\xb3\x95\x8f\xda:HP\xc3(\xff\x8d\x86\x04(IQf\xa0h\xaf\x15\x11T\xdeM:!\xb3\xaf,\xc2Ej\xb05>\x10\xbf\x9e\x1b\xecB\xa2\xa4k6\xae \xda\x95\x01\xd6\x01c{G`\xcd#\xb0\xfd#\xb0\xd6\x11\xd8\x01\xa3\x17\xe8`\x7fA\x8f\xbd$\xd5b\x94 \xa1q\x08\xc4\x9a{\xf1\x1c\x99\xaf\xd6'94I\xf7\x18i\xe9>B\xc5\xd1*\xa1%\x8b\xed\xa5N\xf4sDm7u\x8f\xdbo\"9&(B\xb1\x9d\x86q\xce\x94\xe0at-A\xfb=\x7f\xd9\xf1\xfc\xe5\x81\x18\xd2\x9b\x9cG\xfe\xab\xeb%\x11\xb6\xf7\xe7s\x1c:\x0f\x02\x1d\x06\x0fI\xc7>\x94\xe7\xe1Mk\x88\\\x17\x9a\x02\xf8\x01k\"-\x95\xd5\x06\x0d\xb6\x0c\xa2\x9c\xf5\x0b\xa9\xc6\x03\xc7Y,\x9e_\xaamlG\x11\x8a\x05\n\xec\x0f\xf4hW\x1a\xf0\\\xef\xe4\x9b&\xa5\x0b\x9d\xeb\x9d^VH\xcd\xf0\xdecVRN\xcf\xf3p7\x01\x9f\xd2\x12\x84Qn\x1a-\xb5\x97Z\x82\x9cL\xeaCe4\x82ymH\xcdO\xb4\x05F;\xf2Y\xf6;%I\x18{\x993V\x99\x18\xaa\xcc\xf5\xe2\xa2\x9a2%:\xa98\x12%N\x88\xd7~0\x01\x9f\n\xc5\x7f\xba\xd8\xe4 \xe0F,\xeai\xfe\x8b\xe6\xa5\xc8O\xaaG\x95E\x0c=\x0b\x97\xb2\x7f\x8c\xea\x9f \x134\x8aB\xc4^\xc2E\x81\xbddR\x9b,\xef\xb9F\xb4\xeb$!\xf6\xdc\"\x1c\xb3\xc6g\x03\xebld\x9cu\xcd\x9f\x84*)\x9d\xb8\x99\xf5\xa9\x1b\x1e:\x1bj\x93\xca$\x8e\x18\xf5I'\xd4;V\xb4\x9b\xe4\xa5\x0b\xdb\xf7\xf0\xfe<\xb1\x83DKP\xec-&U\x1f\x9e\xf7\x0d\xcb\x10\xf2\xee\x06\xa1\xe6\xa2\xc4\xe9$\x91\x1d\x1cH\x03d\xfa>7j\xd5\x9f\x1b\x93\xe2?BV\x9dd\xb3\x84\x82\xa2\\\x85}^\xab\xfdD\xc2\xca\xb71u\xde\xa9_5t[\xcc\x04}]\x9f\xa8HK\xf4\xd1\xdc \x8eWVd\xc7\xb6\x8fR\x14\xff\xf1G6\x15\x90B\xf5\xa2]\xcd\xdf\x8av\x1d\x9db\xef\x87A\x98o\x10P\x82\x0ft]V\xdb\xc6C[\xad\x9a\x06\x1f\x0e\xfc\xca&\x9b\x04\xcch7\xa9\x0e>\x90\xfe`\xa9{\xb9\xc5\xdb\xc3\x82\xedq \xdc\xcd\xc8j(\xba\x02\xd1\x07\xfe\xaa\xeb:\xb3\x10\xe9\xb3\xc3a\xb3\x921\x99E\x8c1\xe6\x16;\x00\x04\x14\xad\xd3M\xedy\x1e8\xa0\xf8\xe9#\xceQ\x0eOV]\xfc\x9c\x8dC\x87\xc6\xdb\xfa\xfc\x90s\x04\xa3\xf3\x85\x17'\xa9\x16.\xf2\xf0\x83a\xdb\xd1;\xfa\x11\xbc\xbaebs\xd5/:9\xe7S\xa7\xf3*\xd7Y\xfc\"\xb3\xbe\xad\x999L\x1eSY\xfa\x8bj\xb5\xd9kV\x9b\x99\x9f\x00kd \x9b\xf3\xfb\x8f\x9a\xa5\xbf\x00\x13=U\x111\xb4.c{\x0f6\xab\xeb%Z\x18\xa1\xa0\x19n\x92\xb5\xef\xdb\xf1\xfe \x1a\xe13\xef\x16h\xa8fQL\x8a\x95'V\xd6\x1a\x95s\xd0\xc4\xf7\x82*\x82\xb5\xb2\xdf A\xd9\x1b\x83\xa3\x9f\xe0~c\x00\xcb\x7f\x83\xe980\xe6(\xd9\xcf\x8e\x01w\xb0=G\xf8\xe9\x1d\xef\xa4\xa9\xfe\xa8f\x95\x922C79,\x0fu\xbd\x1eG\xb9\xc30'\xcc\x1aJ\x02\x95\xfd\x91\x9a\xa1$\x9d[\xc0j\xd5g'J\x95Q\xadi\xeds4\xae\xe8C\x9a\x8f\xd2U\xe8\xca\xe6\xed\\\xcf\xf5\xd6\xe5H'f\xd0A\x16\xa8e\xe3\x05w\x03\x8c\x99\\L\xba\x0b\xe5\xd3ONC\xf5\x04\x9d\xed+\xf2v.\x16\x0b\xc5F\x86\xf9\xd2,3\x80\xe7\xb6\xf5\x97\x92$\xb2\xd3\xd5\x11\xd0?\xfepQ\x14#\xc7N\x11\xa5\xccAD\xf4\xacS{[n~\xbdq\x08\xbdc\x16\xab\x19\xfa\xb7'w\xd0\xc96\x8c]m\x1e#\xfb\xe1<\xffW\xb31\x96\x85c\xaa\xf1R\xb9\x19N\xec\xe8\x0f\x07\xa3h\xc7l\x81\xff\x07\x9a\xaf\x17\xed\xd8\xd3\x9d\xcal\xd8\xcd:,\xbc\xa6\xab\xd4p\xa6\x8b*r\xc8\x16\n\xb1\x17\xe5\xebR\x82\x81\xa9:\xe4<\xdfH\xf3?4\xe9\x90\xd1\xbeZp\xc7\xc8\xad\x18\xe0\xf7\xea\x00\x9f\x98\x95\x9e=\xb2\xe7\xa4\xab\xf6\xad\x19\x19\xcb\xb0m\xc4,5\xe0\xf8\xaab\x19\x85IJ\xbc\x8f\"3p\x7f\xec8c}\xc2\xae\x80\x87\xe6YO\xef\x9f\x19\xfd\xbe0\\\xa1\xb8\n\xa7\x1drN(\xea:\x81\x19(\xb3\n\x1f\xf5p\xf9h9\xd7\xac&\x17\x8em\x98\xbc&{V\xef\xcc\x18\x18g\xfd\x91\x82&\xd7j\x8a,\xaa:\x9e\x17(\xb1\x02\x9b\xd3\xd4\xa8\xc2\xdeE\x18\xa5\x88\x95kl\"\x13\xf1\x9a\xec\x8f\xcf\x06\xbd\xec\xff\xad\x8a,\xd8\xaa\xe92\xaf\xec$v\xa0\xd8j\x9cN\xd4\xa8B\x0dK\xc4:\xe6\xc0\xb0\x17\x0b^\x9d\xe3\xe1\x991\xb4\xcez\x96B\x17_\"5\xc7,\xaa:\x9e\x17(\xb1\x02\x9b\xd3\xd4\xa8\xc2>\xb2Sg\xc5\x88e\xe9\xc8tz\x9c\"G\xfaY\xaf7<3\xc6\n\x8a\xcc\xd9*\xa9\xb2\xa8\xec\x14n\xa0\xd4J\x8cNS\xa7J\x05\x19WF\xae\xb1n\xf4\x00\xb7\xcc\xa6\x1cc\xa4\xe6\x96\x19W%e\x16u\x9d\xc0\x0c\x94Y\x85\xcfi\xaaT\xe1\x1f\xe6\xb1^\xc2H\xa6\xbb\x96m\x0fym\x9agc\xfd\xcc\x18\x0c\xdb\x95Y\xf2U\xd2gQ\xdbi\xfc@\xc1\x15Y\x9d\xa6U\x95*\x88\xb0\xbe>\x15:\x98\xd0\xa2\xa2y\xf6\x07\xce\x14\x8d{\xc0\xab\xa5\xc4\x95(i\xb9\xa8\xefd\x96\x07Hzun\xa7\xe9ZR\x0b!\xa0\xb3B>J\xb8\xa4\x9c\x1aY\xa7[\xfe\xa0\xa5^\x8aQk\xaef\xe1\xe14kD\xb3\xd6*\x9eh^\x90Eq\xd4\xd6b\x1eI\xe7{T:\xb5oU%\xd8{M\n\xd2\x1d\xb9.b\xbc*\xb5\xe7\xa7\xad\x82\xa8\x9a\x8bex\xdd,b\xe3\x1b\xd8\xf3N\xedy\x07{l\x1a\x8d<\x89N\xf1b\x16,\xc7\xaf\xfe\x8a\xfa\xd8\\8\xb7bbv\xf2\x99\xcf\x96\xf5X[C\\\x85\x89\xecb\xdf\xbe`5\xa8WeF\xb4\xa3\xceK\x11)l\xc1\xfe\x1e\xbb\xbdW\x08Q\xfa\xf8\x81\xc9\x90\x81\xbeI\xae\xbe\xb5r\xaf\x1aLJhh\x97\xa28\xb0\xb1\xe6\x86N\"\x87\xe6^\xfdGy\x13\x8a\xb5+\xbd\xcdX\xbb\xa8U\xa5\xb5\x8f7\xa8\xa4)\xdc\x11\x12ik\x84h\xb2ALf\x14h\xd3\xf3\xb6 :\xa6\x01\x020%\x7f\xc4fR\x9f\x9e\xb3\x15\xaa\x939\x0fC\x13\xa3\x1dr\xd6)\xaa\xe0\xf50\x98\xbb\x81\xfc\x9d^\x0ci\xa7;O\x03r\x1c$\xc7\xe5>7.\xcfCw\xaf\xe5;\xb0u,r\xd2\x98\xf7?s \x82\x97\x9ez\x86\\/=P'\x16\xf4V\xfab#\x83T\x9a\"M'A\x189i\xb5\x9bkB\xb3W\x8c\x92(\x0c\x12\x94h^\x100f\x96\"\xb9\xee\xc8\x95[\x82\x9eXN\xa3\xa7u\xc6\xaa\x96,\xec\xf8#I\xedt\x9d\x80{\x0fOeJ<\\\x07n\xe8\xac}\x140\xb9]\xe3\xd8d\xf6X\xcf\xfeH\xaa\xce\xcf>1\x9f\x0f\xcd\xcf\x93UY\xef\xbe\x8e\xfc\xc9\xf36\xb78o\xf5?\xd1Zb<\xfd\xe3\x8f\xc2g\\o\xd3\xf5\xed\xf8\xc1\x0d\xb7\x01\xec]2\xca\x18\x05.\x8a\x91;+9\x80\x9b\x7fE\xa0\x93\xbf\xb9\xcd\xa1\x8f\xc75C-\x10\x9a\x91\xa7\x1c\xa8d\x9e\xd1\xef\xf7\xd1q\x9a\xe1\xf6\x9dT\x1aW\xa9\x85\x9dEThY\xc5t\xa2\x038\xad|g\xc9\xedg\x90\xdc>\x1c%\xf0h<_\xe8\xfd\x89\xe2\xbd'\x15\x89\x9a\xd6\x14\xa9\xf3\xe7h\x13}\xd8qd\xcc\x0d\xddy\x82d\xec\xce\x95\n1'T\xba:N\xd3\x8b\xc5BxbN\xb8\xd3\xaaeSW\xf3\x1b\x0e\xed|\xe4+\x0e\xdd\x93G!\xa9\x0ej6gl\x9b\xfd\xfa\x96\xb7TP\x15F1w\xa6\x0b\xee\xfb\xcc\x95\xef<\xa2)69\xb3\x9f\xca=\xce\xecwx\xe7\x93{\x98C\xab\xe0c\xb5\x8fV(H\n\xf1\xb3\xa0\x83z@\xfd\xa24\x06\xd5/\x89ae;\xd6\x8er\xcd\x15'\x18\x1at\xf3\x96\x86\x16\xban\xb1\xdc\xcf\xba\xddAr.y\xe5-W\xc5{\xc0\x9d\xd0\x05\xd6~2\xf4\xdf\xbb\xbe\xe7\xc4a\xfe\x80|iN\xe9!\xbb\xeaHN_g\xce\xe8\x0c\xd8\x13\xd6Y\x1f\xc8\xdcQ+\xd7y\x89\xf8\xc4S\xee)\xe5\xca\x138tJZj\xe8\x8ezc\x138\xed@n2\xf2\xc6&\x0d\xf8\xd1K=\x8c\xbd\xb5\xdf\xf9\x82\xe6g\xc4\x84/\xe9\x97L\xc4P\xb6\xd9\xd4\xeb\xc5\xed\x90\xdb\xdb+r \xc4+\x88\x88eT\x8f\\\xf3\x9bE6\x83\xdaG \x8ej\x83\xa7\x95\x98s\x1a\x96\xe0P\x13\x07\x93\x8bX'n\x9e\xbe^8i\xa7XQ\xba\xbf+\x1dLzr\x13\xbe\xe7\x92\xa7\x1a-\xb5\xe2\xb8\xb5U,,N\x88D[\x94T/`\xeat\x93a\xd6\xcb\xcf\xe6T\xa0\xe0\x85\xb9\xd5l\xd2\xf8p\xe5\xb3\xe5\x89J\xe2x\x7fq\xd1\"\x9bW\x9a1\xc1x\x8e\xa37\x91\xed\xbc_'\xa9\xb7\xd8W\xe3L\x8d}\xaa7\xfei\xce\xd0\xa2\xf4\xfaQ\xdbH.\xa6,3uD\x8f\xd1\x81\x1e\x03'\xf2,\xfdEs\x18\xb5\xce\xd9\x95\x8c\xa5\xa7O\xf3\x13\xa6g\xc2\x13\xa8T\xb1\xc0\x1fO\xe8\x11\x12-\xcc\xd1\"\x8c\x91 aI\xb5\x93\x8e\x9a\x88Dm5\xdb\x11G\xc8\xb5\xbcG\x01\x07r\xeb \xec<\x0e\xd3\xfc\x87\x8e\x91t\xbc`\xe1\x05^\x8a:\xd94n\xc7g\xc4%\xcf\xc9\xf1\x14\xcd{\x12\xb8\x04x\xb1\xf7i\x9d\x15\xff/\x0e\xbe\xe6\xf3b\x1aF\xe5\x9e\x039;\x0c\xd8{\xb1y\xa6\xa9\xf6\xf3S.\xa0\xff\xfb\xbf*\xf2\x07\xb4_\xc4\xb6\x8f\x92N\xd5\xb0C\x1a\x02\xf7\xa0\xf3R\xf4\xa3\x91\xae\xe3\x80t\x1a\xea\xf9\xbf\xff\xfd_\xcf\xccO\x14\xec\xe7&\xa5N\x93W\xc3\x9c\x02I7\xfb%\x0eq\xa2\xd9\x8e\x83\xa2\xb4\xda\xac)\x87dj\xf3g\x19#\x14<\x85g~\xf5\x83\xe0ED,\xdd!\xf2!K\xcc\xb1\x17<\xa0\xf8`\xe9/\x9a\x17\x86P\xba\x15 H1\xcbc\xb5\x9d\x95y8\xba\xab\xda\xdd \xcc\x93 u\xb8\xe1\x05\xdc\x92\xb2\x06\x9d\x81O\xcf3\xa7\x83\xce\xfaU\xb7\xba\x8b\xea\xeb\xdf$\xc7\xcf6(N\xbc0\xd0\xa2\xd8^\xfa\xf6\x81\xdc\xaa\xa8\x83K\xe4\xb3\xe9?\x9a\xea\x8f?|\x94$\xf6\x12==\x82:u\xde#\xe5&\x06\xfcn\x0f\xf9@\xd8\xcc\\\xa0E>q\xd8\xb4\xcb\xc5\xf4\x82\xc6\xfe\xdd\xf56\xc4\x8bE-\xcbY)\x9dmTb\xde\xc9\x171Mt\\m\x97\xba(\xfbS\x8b\xdb\x8fv\x9d~\x11\xf6\xb2\x8bN\xba\x9ay\x1a\xb4\x9d\xb5&\xaf'\xf5\xc8\x83\x9a\xec\x19A\x93?6h&\xfcH\xbc\x8c\xed\xbd|\x05\x9as\x89\xec\x18\x05\xe9s_e8a\n\x9d\xa7A\xf6WK|\xd1\xc5\xad~\xa9\x19\x8e\xee\x9f\xae\x97\xd8s\x8c\xdc\x7fU\xef\x9b\x08\xc2\xcc\xe5p\xb8En=[uM\x8e\x90y?\x00s\xb9\xc9b\x9aer\xd7\x9fx\x04\xdf&\xc7\x0e\x1c\x84\xd9Sa\x8b\x81> \x97_e\x01i\x12\xb9\n\x0b\x0e|u\xf6:]\x85\xb1\xf7\x88\xe8\xeb\xd8\x13z\xb4\xab\xb8T\x07=\xe5\xa7?y\xe1$\xf5\x16\x89\x86\x05\x0e\xed4\xff\xb6\x0cm>p/\x9e\xa1\xdf,\x0f\x0b\x0fc\xf8\xc8e\x86-w\xaa\x80\xfe\xd9\x1f\x8fu\xd4\x03\x92[T9\xc7Q\xcb\xb8D\xa7\x0d\x9f\xe4\x8aZ\xc0\xb8\xe8\xff\xc7\x0fN4\x83r\x1f\xbcxU\x15\xd7\xb13\xadv\xb8\x03\xe2\x0c\x07l\x0b\x18\xe4\xa4\xf9_F\xdd\x95Y\xec\"\xf3\x98\xb5\x83\xb9\x18P\x0e\x0e\xca\xa2\xd3\\3\x0f\x95s\xce}\x98\xb8\xf7Y\xf6B~w\x8ef\xcc\xa8V\x06-\x0f\x80\x13}E\xcf\xfe\xb4\x89-\xbc\xf5\x0bO*\x05\xeb\xa1\x9e\xfd\xa1X\xcf\xd7i\x1a\x06\xec\xdb}\xc2u\x9a\x0d.\xbc\x02\x0bx\xd7\x0b66\xf6\xdc\x03\xbfVIV\xf6\x03\xeat\xfbI\xc7\x98\xc0O\xdb\x0e\x03\xffu\x81\xb83Fe\xd0{\xc4\xc4\x9b\xa7\x18\xac\xea\x1e:\x7f\xbc\xa7\xcc\xd9\xca\x13\xbb\x8ba\xf6\xa7\xb3\x8e\xf1\x8f\xae\x9d\xda\xe7\x9eo/\xd1\xcbd\xb3\xfcy\xe7\xe3\xc9\xdcN\xd0\xa0\x7f\xf6\xdb\xaf7\xbdo\xfb\x8b\xfe\xfc\xcbn\xed<\xea\x9e\xfd\xeb\x9d\xee\\\x86\x9bw\xa6k\xba{\xcb\x9c\xed\xad\x8d\xe3;\x9b\xd9\xfdt;{5~t}\xc7\xbb\xfe\xf5[\xf4\xedw\xf7\xd5\xdc\\\x8e\xaf\xef\xa7\xcb\xd9\xab\xe9\xbe\xf8{\xfd\xf3\xf5\xab\xe9\xf2\xfar\xb7\xfd\xfa\xfb]x\xfd\xe6v|\xfd\xa0\xeff\xfb\xbe>\xfb\xb8\\\xde\xec\xfb\xfd\x9b\x8f\xf8\xfe\xdd\xfd\xb59\xfb\xa0\xafg\xf7_\xfb\xef\xee\x9d\xed\xfb\xfa\xe7\x07\xf3\xfd\xab\xe9\xf6\xfaU\x7f\x7f\xb3\xef\xefo\xee\x97\xeb\xd9\xbd\xb3\xcf0\xb3\x0f\xf9s\xeb\xe6\x1e'\xef>\xce\xd6\xef?N\xfb\xd7\x97\xb3\xf5\xfb\xcb\x9b\xfbw\x1fj|\x9aa\x9b\x9f\x1f\xcc\xf7\x1f\xa6\xdb\xf9+\xfd\xf1\xdd\xfd\xc3\xf6}\xfe\xdf\xe5\xe3\xd7}V\x9f\x93\xbe\xbb\xbf\xee\xdd\xd4?\x17u\xbc\xfb\x90\xd5\xf1\x90=\xdb\xe5|\xef\x97\xeb\x9b\xc7\xa9U\xfd\xfc\xfe\xa3\xd3\xbf\xbe\xbc\x98\xcd>N\x97\xb3\x8f\xaf\x93\xb2m\xe9l\xdf\xdf\xdd\\\xbe\x1e\\{\xa3\x9f\x7f+\xf4\xf4\xf3O\x9d<\xaf[\x9c\xfc*b\xceN\x10j1\x8a\x90\x9d\x92\xf3ZqS\x9f{#\x84<\xa3\xd9SK|f0\x95(\xa8Y\xb9G\x11\xb2\xe3,Z(F\xa4\xfcEm\xecC\xe6w\xc0\xdd\xff\xe9\xafq\xeaE\x18\xfd\xabJ\xfeZ\xd4\xc15\x0b\xf4V\x80\xd1\x9f\xde]\xe9\xbd\x07.\x89\xd8\xcbg\xd8\xa3\xee\x94 8\x19#\x9d\xbd\xe0\xa5\x94\xdd}\xea\x99\xa4\xfch\xe1?\xb3%\xf5/\xc8\xb7=\xfc\xaf3A\xe9\xc2\xc3HX\x18\xd9I\xb2\x0dcW\x08H\x90\x1d;+aq\xb6\x1e\xa3\x0b\xb3'v\x8clRE:\x91l\xa2\x1dh\xc4\x0c\x8f\xc4\x86\xa1;\xce\xfe\xb4\x0d\x8f\x8b\x85\x9a\x15\xff\xf3\xd5\xd5\xbct&\xdf\x8a\x91\x1b\xbb\xeaO\xd2V\xb4\x81\xea\xd6\xb4\x01\xcbV\xb5\xc1\xf2\xd6\x81\xa0\xaa\x95\x7f\xca0\x00d\x8ar6\x07C\x7fq6\xd6_\x00Y\xb6:\xa5k\xba?jF\xb4\xcbF]0\xe5K\x96\xff\xbb\xa7\xbf8\x1b\xb5\xf2\xeb\xc9\xd9U\xc5\xff6\xf5\x17g\x96\xfe\xe2l\xd8\xcaQ\xeb\xb7HX\x95\xff\xbb\xaf\xbf8\x1b\xb4\xf2kaWs#3k\xff\xab\xd1g\xd1(8\x1403\x07y|\xbc\xd9\x9a\xeaQ\xb7\xe8\xf9\xd5\x137l\x92\x01u\xcb\xbb(\x8e:-\x00\xccMUK\x8aw|\x1d\xf8\xd0\x17\xb8\x1fU\x0f\x11\xce:\xe6\x0f%\x13[r\xe4d\xc2\x9c\xd5\x88QN\"P\xc0\xb3\x9f\xd9rV\xc8y\x98\x87\xbb\x03\x19\xf5\x97+Y`mD\xeez\x08\x1eW*\xd5\xb3?peOx\xfd\x86\x80aD\x1dD\xef\xeb:\xf1\xd1\x8d\xc2\x0e\xe4y\xb9J\xf3,HU\x8bP\xba\xae\x16\x85\x98L\xaag\xff\xaa\x9b\xca/\xa5\xa5t?\xe7\x8a\xfa{\xb7xC\x8f\xf0\x8dJt.K#\xf7\xcb\xf27/Tn7 \xcf\x91\x8f\xca\xedn2\x0ef\xcf|\xd0[Q\x8c\xff\xa1Q\xf6G\xf4\xb2$=_\x02T i!\x97\x08\"\xde\xf1\x90\xf7\x83\xfa\xa7\x13U\xd7\xfe\xca_\x85WFKk;\xcf\x7fB.e0^Y\xf9\x1a\xf8/\xc0\"\xd8Y\xd9q\x82\xd2_\xd6\xe9B\x1b\x9d\xbd0_%\x9be'\xb7\xe0/?\x18\xfa\x0f\x9d\xc2\x82\xbf\xfc0\xfa\xa1\xb3\xf1\xd0\xf6\"\xdc\xfd\xf2\x83\xd9\x19v\x0c\xbd3\xfa\xa1\xb3\xf3q\x90\xfc\xf2\xc3*M\xa3\xf3\x97/\xb7\xdbmwkv\xc3x\xf9\xb2\xa7\xebzV\xc7\x0f/\xcc\xab\x17\xe6\xab\xc8NW\x9d\x85\x87\xf1/?\xbc\xe8\x99}\xa3?\xec_\xfd\x90?\xd0\xe25F\xbf\xfc\x806(\x08]\xf7\x87\x8e\xfb\xcb\x0f\xb3A\xd74\xcd\x8ea\xbd3;\x86\xd1\x1d\x0c\x86\xd8\xc8\x9eh\xd9\xbf\xfdN\xaf\xd3{W<\xce\xc40;\xa3\xac\xec\xf1\x87\x97EMY\xa5/\xcc\xab\xbf\xfc\xd4\xb1\xf4\x17\xcdZ\x93\xd6\xa8\xeb\xd98\\j\xeb\x1d\xf35\x9d \xf9\xa2U\xea\x1e\x8b^\x1dV\xaa^\x03,`\xd8\xe9f\xbaw\xe30\x02\xb8K\x19\x8an\xc1\x8c~\x12V\xe5\x87\xae\x8d\xa9z\xea-m\xae!\xd4\xfe63)\x16\xbf\x9a\xe5\xdcP\x7f\xf3\xc3\xe2\x86\xe2\x937\xf8\xf9\x05JuY\xafm\x81\"\xc8\x07\xe8\xd1\xaeS\x9c\x9c\x92\xbe\x04Z\x8ckUj\xb5\xb1&;\x06g\xf5\xc90\x82O*J\xd8\xd2\x17U\x80{6U\x9e\x9c\x9fk\x95V\xb8\xd2\xba\xe9K>#f\x81=h\x16\xd8O8\x9a\x04\xd5\xff\x94\xd7\xce\xd5\xb1J\xaf8/':*[:\x16\xe96'\x9d\xffQmM\xa7\xeb\xe00AZ\xfe\xf8\x88\x94\xfc\xf3e\x9bd\xc2\xad\xc8\x0f\x83\xf7\xd8c?\x03\xf2\x0d^\x8d\xe8\\\x1eN\xb4Ir\x82[\xf8\xa1+O\xef\x98\xfa\x91g\xea\x85\xb5t\xba\xc4}\xd9$\xb2\x99\x1b\x11<&u\xabc\xb9\xb6\x9e\xfd\x11\x9d\xcc\xe5(\xff\x9e\xba\xcc\x8dK\xf5w\x0f\xe5\xcc\xb44\\.1b\x8fh\xc1\x81\xd7@\x14x\x95\xa6\xccF\xa9N\xd7D\xbe\xc2\xebo\xb8\xe1]\xf8*`u\xe4\xa9\x08\xe8C\x0e$\x03~**\xcf\xf1\x8cu\x17-\x81\xf3=\xe5s\x8eN\x0bc/\xcf\xa6\xe9/\xb2(a\"*\x10\x1b\xaa\xeb\x84\x18\xdbQ\x82\\\xf1\xa9#\x81P\xf9c1\xe7\xf2\xac\x1et\x02\x8d\xdd\xc0\x12\\\xa1=*\xd2k\x0f\xe0\xaa`\xb0\xd7o\x82\xc1\xec\xe7:\x1a\xcc\x83\xea~\xa7\xd7'c\xbd,\x8c3\xf4\xce\xe0\xdd\xa8k\x8d;\xc3n\xdf\xe8\x18f\xd7\x18v\x8c\x1e\xd6\xfa]k\xd4\xe9w\xad\xf1;C\xef\x18#<\xd0\x06m\xf1\x1b\xb7W\x90\x05/\x90\x16\xef\xd7~\xa4\xa5a\xfe60`\xe1\";\x01\xc43\x10\xbfz\x8a:;\xa8u\xfb\\g\x03-\\\xdc\x87\x97\x1f\xe3$\xa0\xd5\xbb\xa5\x8aG+/H\x0f\xc4!\xbb\xfcG\xf6cc\x04T \xab\xd1\x1d!\x7f\xc2\x9f\xe3\xab\x86\xff\xae\x81\xfcN~\x14\x08\xf8\x1eo9<\xaa\x04od\xb85\x84\x1c\x9e\xb8D\x95\xad\xfb\x99\xc3F\xe5\xc9\xb2\x02\x9a\xd4W0ub\xf2\x97\xbdR\x9a\x97M\xc2\xbdz\xc1)1{\xeb\xfc\x0b\x0f`\x9a,\x96b\"7Qh\"\x7f\xef5\xcd\x9e \xd1\x9e\xe5-\x86'\x85Ap\xb2\xe8Y\xdf\x13.\x0f\"\x06:w\xbc\x86S\xd5\x13_\xa3\x0d\xf0;\xe9\xcd\xde\x1c\x9f\xe3\xde_\xce\x92[\xac\x07\x90\xddEo\xdd\xf6\x02\x0e\x0b05\xa8\x0d\x99\xf9\xeaQ\xda\x17*F\xc0e\x97\xfa\x82\xc3Q\x1f\x1c\x02\xde\xc6\xa7>\xd8\xb0\xdf\xeej\x91\xb5\xc5F\xc3\xe3\x98\xd1Q \xf1\xda\x90\xa3\xb8\xe4\xa7\x83\x18&\xad#\x12\xc7\xa6|\x90\x08\x0cLM\x0b\xa3\xfa\nVf\xab\xe6\x15;\x96B\x85\xf3pw\x90\x1e\xdai`T\xc2\x19\x8ca\x95\xcd\xcc\xbe\xcc\xa7\xae\xe4\x08\xb7\xe6Ni\xd5L\xba\xd0\x0b\x87,\xf1\xa4\xce\xf4Ty\xcf\xb4\xf4\xec\x0f\xc4\xac\xa9U\xdb\xdaq\xe0\x05K\x903\xb7|\xab^\xdcR\xddn\x17\x1fV\xe4_Q\x97\x8du\x7f\xcf\xfe)\xa7\xe5\xee<\xb6\x1d\xa4\xe5\xabZjF\x84\xceBEq\x18i\x81\xed\xb3\x87\xb8\xa9\x15I#\x1d@\x9c\xfbx\xa5\x18\xcb\x06\x10(X\xfb\xb2\x0b\x8f9(\x0b\xb1\xed\xf4 \x9e4\xba \x8a7(\x16\\\x1f{\xb6\x0bYd%\xa2\xebW\xf47f@\x06\x9dU\xbf[\x9d%\xaf\xee\x1e\x94\x01E\x8fUcE\x92\xdas\x8c:i\xf55\x16So\x01\xba\"\x9b\xd5\xd2eQ \xf8\x85\xdb u\x1f\x82H\x82i\xc4\x9dNy\xe5\xf0\xeb\xfaKWik\xa3\xdb\xe1^\x0eE\x1c|\x87I\xbbN\xe8G\xeb\xack\xadc\\\x0f\xcd\xfc\x91~\x10_\x1cC\x07\xf5E\x9c\xaa\x9d\x88&l\xce\xf5\x978\x9c\xdbX+\xea\xfa\x8f\xbe%*\x90\xb4\xd6S9\x00\x92g\x9c{\xd50$~=S\xf5\xaa/\xc0\xdd\xcb1C\xe0\xed\xb9\x03@/\xc3\xa12nZ\xb5>?\xaf~\xe0\x99\x94\xc3]\x9a\x9fLJ\xe3\xac?\xd4\xbcX\xafg?\xd6,`\xc0\xf8tu\"\xa5O\xbe\xe2\xab\xd8\x84\x82ZU\xde\xefN2IZ\x12dp\xa7|j\xda\xac\xec\\\x80B\xaa7\xb7)\xe9E\xa2\x91fl\xe9Q{\x0f\x03\xe2\xe6 \xf0V\x9f\x92m\xfe\xea\xc6\x9c\xed\x99\xact\xd5vz\x8cI%\x13\xd7b\xf2c\xf2\x8a\xeb\xb7\x9e\xda\xa9Bf\xae\xaa\xbe\x8c\x93\xb0/\x93\xe0\xce\x02\xc1\x1f\xd52\xf9\x17>Ix\xd2\x97\xcdJ\x86B\xfa?\xfe\xc8grI\xc4\xd1\xd7O\x99\x14\x99\n\xba1\xfa\xef\xb5\x17W\xaf\xc7\x11\x0d\x12\"*\xf86+\x1c\xe0i\x03\xfasCM\xca\xac\xe2\xf6\x97R\xf0\xf2e\xd0V1\n\x0e\xd8o\xae6\xb2\xa0]\x8a\x82\xc4\x0b\x99l2\x81\xf0\x14^\x9csLW\xe5?\xccBT&|m\xfe\x13+\x8d\x91+V\x81\x1f\xa5\xfb?66^\xa3?\xf8\xc4\xb5ID\x03\xe5\xda\x91\x8b\x0e\xb8\x17\x0cJ\xb9\x97\x93=\x15L\x0e\x8f\xe2\xd0\xad\xee%5\xc1<\xffjH\x8c\x80\xab\xee\xfc\xa6^\x1aFs\x9b\xfeb\x0dpE\xa7|s\x0eDZ\xfd\x17~\xcd`\x89\xb1O\xdb%{r\xbe\x07\x14\x98:U\x95\xe7\x06\xd9!U%WB\x8eb\xf9^3\xbbIR\x1c\xb9\x90\xaf_\xd8cD\x95\x84E\xca\x06\xd8\xcc\xe2#\xd1\xca\n\xf5+J\xd61\xae_\xd3\xf7d\xad\xe7m5\x9b\xd6\x9b\x93\xea \x01\xca/r\xa2\xc0e\xaevfO\xd8{\x9dy)\n\\\xf56\xb4\xcc$\xa5\x86\xf8seV\x7f\xb8\x80\xbeJV]h\x12\xdf*\x91\x8b\xd3-f!\xed\xf4\xb3WOw\xeb 8\x99\x0e\xa8\xe3p\xa76\xa9\xbcgG\xcf\x9aJ\x1d\x82\xf6\xd2<\xc0\x92\xbf\x19\xf2\x18\xa1\x8a\xa9\x9f\x93\xa3\xd7\xc8\xd1\x9b\x94\xff!\x94#t\x0b\xea\x04$\xb0\xee(\xcf\x0dR\xbf\x1f#<\xf5\xb4\xbc\xd5$\x89D\xc88\xae_\x1e\xf2\x90\x9c\xe1$\xae\xd5Q\x8b\xa8\xb2qG\x0e:^\xb0\x08\xeb;\x1d\xc0K(\xb3\xf2\xce*\xbf\xee\xd7\xf5m/`\x97urt\x87=\xc4\n\xc0\xb1w\xc6?\x8c\x80g\xc5z\x89\xe0w\xda+\x0f\x0b\x19\x0d\xa0\x02\xf6\xf3\xc8\xc5C\x13z\xd8\x87\x1eZ\xc7\xbf9\xa0\xa0,\xdenU\xad\x8f\x8b\xdbb\xea\xe9C\xdd:\xf2\xa4.\xf4\xee\xf7\\\x0e\x9b\xd5\xeeQ\x1b\x11-\xb6\x80\xae\xc9\x16\xb5\xd2\xef\xbc3\x16\x83\xb1\x03xay7\x9f\xdc\x9f\x02\x98u\xe7v\x824\xe0\xe80\xa9\x0b\x93:\xdbZ\xcf#G)Qh\xcc.\x9bF5\x07O{w/\xc1\x95\xff2\xaad\xc1`\xb5\x1c\xae(\xd6\xef\xe4\xcb\x9d{\xc5\xc0\xc2.\x8d\x93u\xc4\x1dd\xb5\x86\xcc\x01\xb7\xa1;\xea\x8f!\xf3\x92\x92\xe7\xaf\xdbST\x057T\xd9\xebt\xa5\xcd\xd3\xe0i\x01\x0e\xbd6\x7f\x8e\x17U\xc8\xa5,\xeeK\xbba\x80\x0e\xf2\x14rN\xf8\xa4\xa6)M\xd4\xcf\x1a\xbb\x912w\x88\xd7\x040)\xd0&4\xd1\x9a\x97\xe3\x01\x9c\xc0\xe4\xa1\xc1\xdeo(\xd2\x89-\xa7\xe6d\xdc\xe1M)a\x1dl8E3#v\xcd\xcbc\xffV\xb4\x13\x1d\xb7bH\xeb\x8f\x8e\xf3\xc1\xbe\x94\xae\xf5&\x9a\x84\xa0\x08\xa3\xd9\x1b\x90R)Q\x1c\x87q\xc2\x0e\xa8\xd4\x06\x18?Y=y0M\x9c0BIg\xd5{\xfa\x94\x9f\xb3\xd2\\\xb4\x90\x1f\x8b(\x1b\xaa1V\xe9\xc1\x0eXu$\xe2\x92\x9acc\xf4)b^\x80E>\xe5C\xd2\xea\xfaZ\xebd/\xf9&\x15-v\xf9;\xdb\nx\xd3\x0b$e\x8fl\x08\xdf=\x7f\x92]\x05U&\xc4\x8b\x9f\xc0M/\x86\xae\x882\x9f>P\x9e\xb4\x06S\x90\x8c\xd6a\x8f\xba\xac\xa44P+\xb99t\xc7\xb1\xf0\xb7\x03x9\xad\xbc\x971\x02\xeej\x8c~\x9a4\xaf\xc6\x02\xdfAV\x00\x0d\x9e\xd6hH\x0d\xfav\xe0\xff\xb4,\x94\x9d\xee\xf2kaq\xb7\no\x9aTZ\xe5\x1d\xf9J\xef\xff\xbc\xfc\xdb_;I\xb8\x8e\x1d4\xb3\xa3\xc8\x0b\x96\x9f\xee\xde\xfd\xd20\xea:I\xd2\xf5\xed\xe8o/\xff\x7f\x01\x00\x00\xff\xffPK\x07\x08_;\x94/\xe8Y\x00\x00\xa8X\x02\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00 \x00swagger.yamlUT\x05\x00\x01\x80Cm8\xec}\xdbr\xe38\xb2\xe0\xbb\xbf\x02\xe1\xde\xd8\x9a\x8ei\xdb\xb2|w\xec\xec\x86\xaf\xdd\xee\xda\x9av\x97\xdd\xd53\xfd\xa2\x82HHb\x99\x02h\x02\xd4\xc5\x15\x13\xb1\xdf\xb1/\xfb\x8b\xfb '\x00\xf0\x02\x92\x00\x05R\x94Kv\x99\xe7\xc4\xb4KD&\x12\x89\xbc!\x91\x04\xb6\xb6\xb66\xe8\x14\x0e\x87(<\x05\x9b\xdd\xed\xce\xe6\x86\x87\x07\xe4t\x03\x80 \n\xa9G\xf0)\xd8\xdc\xe3?\x03\xc0<\xe6\xa3S\xf03\xf4\xe0\xd6\xff\xf6\x18\x02\x03\x12\x82\x0bB\xc7\x84n\x00\xe0\"\xea\x84^\xc0\x04\xc8\x19\xf8xuw\x0f<\xccP8\x80\x8elJ\x19d\x08\x12#T\x80~&\x13\x14b\x88\x1dT\x86\xcb\xde\x19\x80\xef|HG\xfa.\xe37\x06\xc0K\x8f\xb2\xd0\xebG\xbcq\x19\xf8\x1a!\xe0*-\x0cHn\xce5sys~a\"6\n\x02\x7f\xae!U\xfcn\x00\x8a\xd5D\xf9\xe5\x83\x87Y\x19 \xff\xd5<\xdc\x0f\x1eu\xca0\xbf\x0b\xe9\x82A\x90\xf6B\x9d\x11\x1a\xa3X\x1dF\x8c\x05tcD(;\xe5\xca\x15\x0e!C\xdb\x8eP\xc8m\x8c\xd8\x94\x84\x0f\x1b\x149Q\xe8\xb1\xf9%\x1ax\xd8\x13\x02\xc1\x81\x1f\xc6\xe2?\x00\xb0y\x80NA\x1fR\xcf\xd9\x08 \x1b\x89\x9fw0qQ/1\x04\x00\x0c\x11\x93\x7f\x14Y\x89\x07$\x1c\xc7z\xdb'\x11\x03l\x84\x80C0F\x0eC.\xe0hb8\x1a\x8d\xc70\x9c\x9f\x82\xfb\x11\x02AH\x02\x142\x0fQ@\x06f\x98D\xf1\xe5\xb3\xa5\xd3R\xc0q\xb9\x91\x83r\x0da\x10\xf8\\\x8d<\x82w\xbe\xd0X\x80\x00\x08\x11\x0d\x08\xa6j\xdbn\xa7\x93\xfd\xa30\xba\x7f\x12\x17 \xa3\x15Q\xa5\x89\x98\x01\xa8\x02%L$\xfd/\xc8a\xb9\x17\xd9@\xf3\x00@%\xb1\x97X\xdaB\x93*p\xfe\xf4#\xcfw{y&\xa9\x8f\xa4\x8a+I\xac\x7f\xf9\xc7\xf1=\x84YO\xc8_#x2\x1e{\xac\x11\xe8\x904\x02kL*E\xe1\x04\x85\xcd\x87j\x9c\xa0\x05\xb0\x055R\x9f\xea\xa9\xf5\xdc\xda}\xf1gL\xb0\xf7\x80\xc2F\xb0\x00\xa0\x19\x1c\x07\xdc\xc3\xa7^k\x8bsL\xd36\x08 #\x0e\xf1\xcd\x92\x0b\x16\x0eQ\xb4\xe8\x06\xa6W\x16\xf4\x02\x95\xe6#C\x13\xe1\x9a\xdb\xead\xb7ch\x03\x83\xd6\x06\xa2\xeb\"6\xe6\xcb\xce\xeb\x90Gn]\x9d*\x8f \xc6\xc8ofG|\x8f2\x84{\xd0u\x97\x16\xbc\xdd\x93\xee\xf6\xee\xe1\xf1\xf6\xc1\xe1\xf6\xeei\xf7\xf0\xf0\xe0\xb0\xae2\x9a\xa2\xb6\xccK\x97\x1f{\xfa:\xdb\xbb\x07\xdb\xba \"ldR\xbb\x1cEc\x12\"\xe0)^\x93\xe0\x844ZA\x9b\xc6\xb3$\xcfb%c\xb3\x9e\x87]4kK@\x0d\\\x04 \x0c\x1c!\x05\x88\x1ai\xa9\xdb\x17s\x82\xd3\x9d\x9d\xce\xb6\xf8?!\x11\x99\x9e\x1fT\xb8\xeek\xe8\xf9\xc8\x05\x8c\xc4\x01:\xce\xb9\xf2\x1d:\xc7\x8e\x87\x87\x12\\ n\xd2 \xe5N6\x88\x97,dP;*\xc9G\xc9\x88\x01O\xc69\x82\x10\x8f\x02'\nC\x84\x99?\x07t\x8eyOS\x8f\x8d\xa4\x18\x896\x894\xac:\xbaQ\xc6\xb9\x8a('\xc7h\xf5\x89\xc3NB|\x04\xb1\xd5\x94\xde \x1f.\x97\x94\x18\xfa\x00\x85! \xf9d\xca\xc5\xd7\x8e\x0f\x19\xa2\xcc<\xa5|\x12\xf8\x0c\xc8v\xd2/\xd4\x99\xd1\xd5\xcd\xc4\xbd\x9e*`\x98\x86\xff\x16\xa2\xc1)\xd8\xfca\xc7\xcdB\xfa\x9ds\x0e(\x96\x0b\x9b\xadp\xf3\xeb\x08y\xc3\x11\xfbO5?\xa1$\x18@\xfe\xa7\x83B\x06=\x0c$\xe4\x8aX\x1b\xc0\x10\x8e\x11Ca\xae\xb1\x87O\x01_\xbc(\xa3\x95\xcb\xaa\x1c-\xa0\xc8\x04\xc1\xb4r\x9b\x10=F^\x88\xdcS\xc0\xc2H\x0d\x7f\xa4\xd0\xe2h\xdcG\xa1\xf2\xf3l+s`\xcd%@\xe1$\x0d\x90\xe3\x0d<\xa7L\xdaR\xf2\xb0\xdf\xd97R\xf0\x11=F\xa9\x00\xc6\xfd\x02\x97 \x8a\xdf1\x05\x81y\x087XD\x8dE\x92\x1b\xc9\xa0\x9a5\xa9\xad\xd8)0\x909\x17\xb0\x02)l0\xbd9\xb2\xf84\x17m\x91\xddd7\xb0\xc1\x02{Ob7\x19b\xad?\xce\xa6\xc1\x04\x06\xc3\x10\xceK\xef<\x86\xc6\xda\x08@+\xa9\xd9\\|J\xfa[\xd2\x84\xe5\xc5\xc7\xd6\x92\x15&\xe8\xcd\x9c-g\xceJ\xf2\xae\x98\xb57y7\xc9{\x95\x89>O\x1cDl\x9d1a\x00N\xa0\xe7\xc3\xbe\x8f\x14\x0c\xcfc\xa3\xd9\x8c\xab\x16\xa4\xa3\x85\x8au?\x03\xfd9\xe0MMJT\xcc\xe7\x97|\x13\x0b=4A\x00\xe6\xf6\x0c\"\xca#W\x8fQ\x81{{\xf5\xca\x97\x8d\xa0D\xe2\xfd\xac\xf8z\x81\xd6\x95\x04P\xd1\xba\xf3\x8b\xf3\xabn\xe7\xea\xf8r\xff\xf0\xe8\xe0\xf8\xfc\xe4\xf0\xec\xea\xe0\xf8x\xef\xfc\xe8\xa4{|p\xdc=9<\xbb\xe8\x1c^\x1d\xec\xee\xef\x1d\xec\x9ft\xae\xcf//\xce\xae\xba\x07gG\xdd\xf3\xbd\x8b\x8b\xa3\xc3\xf3\x86J;\x93k\x10&\xf3\xb3\x13\xcfEnqP\xd6\xe1\xc7\xfd\xacF,z\x93\x08W,lW\x8a\x8c\x95\x84\xcbBx\xb2U\x9c\xd8\n*n\x86\x94\xfa\xd74\xe3\x12\x8b&\x083\xda\xaa\\\x89\xc5hI\xb0\xc6\x88R8D\xdb\xb2\xef\xc5\xa2\x92#~SU Ir\xba9\xf5.\x8f\xf9\x1f\x14a\xf7\x1d\x98\x8e \xbeO\xa6\\\xa1\x10v\x03\xe2av\n\xde\xfd|u/&\xe1\x7f\xe9\xf0ls\x03\x84\x00\x1bA\x06\x10tF\xc9\xc6\x86K\x9ch,\xc8\xe0\xaaI\xa6 U\xdb\xc0'\xe4Al\x04\xcef\xbd\xf8\xb7\xb1\x9b\x10\xe0\x90P\n\xac\xcb\x89\x90\x9b\x18[\xd4}\xd8q\x89Cw\xb8\xeb\x00\xae\x17\"\x87\x11U\xacrz\xb3\xc9\xe9\xda\xac\xc5r*\x8c\xf12,\xe7\xf2(\x15G\xe2Z\xc0\xb6\xff\x9e\xef\xf9\x1fr\xa0\xbb\x87\xb39\x1a\x07h\x1c\x04'\xdd\xd9\xc9h\xfe\xf4t2\x0d\x87\x83\x93\xfd\xf0\xf0\xcb\xc9\xe8`\xd09\x0cf\xb3\xc9;\xd3\xc0ka\xb1\xe3P\x00\x87\xc8\xc4\x80[8D\xe5\xb8A\xb2\x8e{\x8a\xe1\xa2x\xa2\xbak\xdf\x1b{\xc6 \xe7\x03\x9cy\xe3h\x1cw\x0f\xc8@\xba_\x10\xa0\xb0Hs\x0d\x82j\xda\xca3\xdf\x07lF\xc1\x182G\xeca\xe6\x8c\xa6\x94m\x05\xd6\xdal\xde\xc2\xa1\x87!C\xae\xb0\x9e\xf73\xaaF\x06\x8b\xfd:\x95\x86\xac\xd0\x7f\x13\xd3\x0b@@h#\x9b{\x9e\xeeAC@\xbd!F.`\xb3\x0dM\xd7\xda\x86\x80\x11\x00\xc1 \xf2}5\xe3\xe6\x10L\xa3\xb1\x9d\xedm\xc3L\xf7\x89[\x96J6K)6q\x93\xc7\xbdl\x06\xc6\x11_\xd3\xa1l\\w\xcc\xbd\x9fm\x8b\xd74\n\x02\x122\xa4n\xd6\x8f\x89\x8b\xb8!v\xfc\xc8E\xe0\xf3\xa6\x08`7?\xff-D,\n1\x80\x03\x86B\x8eWn\xb8\xfd\xf8\x13\xf8\xbcI\xe7\xd8Q[\xa0\x10\\\x8c\x90\xf3p?\xfbQT\x02|\xde\x84\xf9&\xa1\x08\x19\xe1\x14\xce\x7f\xdcV\xc87F)-\xc5\xe2L\x93u\xd6J\xbe`\xd1f\xa1-g\x8c)\x147d\x90S\xcdV3i5\xb5\x9b\x07\xacJ\x01J\xec*\x9b\xe8s*1\xf7\xb3\x0b1y\x1f\x05\xaa\xe5\xc3\xa2\x1dY\xddr\xba\x94\xaa^ \x1c\x85\xa8\x9a\x11a\xcc\xce\xc6\x1e&`\xea\x85\xa2tg\x0c\x99N\x85\xb5\x08\xfe\x16\x0b= y\x80\xf0#\x18\x84d\x0c~\xbd\xfb\xed\x9f\x1cu\x1fRt\xb8\xbf%\xa9w\xe3^(\n=\xe8{O\\)\xe6,M}\xaf\x89\xd6/PvF\xe2J\xa3\xb5\xd7\xaa\xbaZ \xc77\x85\"\x9et\x10\xa5\xdc,\xcf\x81\x8b\xe4\xdcq3\x13\xa2d*\x9fg\x90v\xaa/\xb2\xa9\x1aA\xdb*\n\x9a\x08F\x99\x18g\x8a\xad\xca\xcf*,\x19C_\xea\x852\xf4\xc6\xebh\xc9\xd2\xe5\x94\xf9\x12itQ\xe8\x9e\xb5:kQh\xd5\xd9J\x8d\xb9jp\xbd\x7fi\xea,g\xe3\x1b\xab\xb3\x9d\xa4\xdfM\xce\xbd\x7f\xa1\xfd\xf7\xb7\x8f\xde\x97\x7f\xffE\xde__\xffr\xf5\xf4\xeb\xb1\xd3\xfd\xe5\xf6l0\xe9^]\xff\xe1\xdc\x8cf\x9d\xf9-\x1cN\xafF\xf7\xf3\xce\xe4\xf6\xec\xef?\xff<\xba\xb8\xa2\xfe\xfb\x7f\xc1\xfd\xb3A':\xff\xfbxp7\"\x1f.\x86\x9f\x9e\xdc\x9f\xaf\xc3\xbf>\xde\\~\xb8?\x9b^\x0d\x7f\xff}\xfa+\xf9\x10\xf7\xde\xae\xf5X\xc0\xc4\xc5\xc6\xec\xf9\x15\xb5\x0f\xf1\xc3N\x1f\xfa\x10;\x88\xee|\x8d7\xba\x17d\xbf\xb8\xee\xc5\x95\x9c \x815(wZ\xdd\xd9\x92\xfcksX1\xd5\xa6\xc1\x9f\xc5\xa4\xc6\xcd\xf8\xda\xbc\x8f\x9c\xd1^7o5\xc0r\xf9\xadZ\xab\xd5f\xe2w\xa6\xe79\xa8T\xdarvW\x9b\xd9\xd5\n\xe7\x05\xf1\xb0]XW-`I\xd9o&`;\xc2\x1a\x0f\xd2\x19V\x1d\x84\x92\xe9\xc2.p\x88\x87\xa94\xd0\x04gr\xc7\x97TXT\x16,\x96\xbc\xe76\xd2\xafKH+]O<\x1d\xa6Q\x89\xc5\xa1\xc8 \x89\xc8\x8a\xcd\xd42!\x9b!\xb5\xe4\x8c\xb8k\xef\x85\xe8\xb1\xec\x92\xf4+\x1cH\xd1G\xf4X\\\xb9\xc11\x1f\xab\xc9\xad\xb5\xb1\x8d\xa2*\x9c\xd68t\xcd\xdeA\xf5K\xd2-\xc5\xdf\x1f\xac\xdc1%\x99\x9aPn\xb7\xa7\xcd\x1a\x19\x0c\x18\xb1\x91\xc6`\xd8{\xa4B!\x9aX2;#\xe8%\xf2V4\x14\xe9g\x0b\xeb\xa3\xfd6\x9a\xb1\x1aeo\xe8\x91\n\x19\x80\xcb\x04.\x851\xa8\xbf\x96\x13K\xa9\xbeq\xa7\xdb\xf7\x81\xc2\n\x19\x88\xc1l\x841L\xd1\xa8\xaa\xdfd\xd5\xb2\xab5\x0d\xd0o\xef\x957\xab \x82/\xd3\xd1\xd7\xf3\x86)\x8bJV\xbdI~\xd4\x14\"G\xfd\xb1\xc7\x94\x19J8^/\x83P\x82/\xd1%>p\x82\x94NI\xe8&\x9f7)\xb1x\x88\xc6d\x82\xb2\xd4\xcc\xfb\x0fwV\x13S\xcb\xec\xb7\x13\xc5\xa5\xf3b.\xeb\xd6\xa2\x8b\xf5\xb4\x88.\xad\xaf\xa9\x89.\xad\x931\xe0\xcd\xa6\xc4\x12\xa1j\xa5\xab\xd5q5\xeb\xa1\xb65\xb7\xd9\xdeC#\xcd\x04$T\xf8\x9d\xc4\xb1yU\xd9\xef\xec\x1a\x11\xbfG\xf3L9<\n\xa6!\xb1\xf4P\xc6\xed\x90z\x1ej\xe7\xebD\x15\xa7\xff|\x0f\x1e\xabb49fT\x8e\xe6\xb7\x80\xaf\x90R%\xe4CJ\x81\xdb\x19\xd2\x04\xfa\xdc\x9e-\x1cYw\xba\x8f\xbb\xbe\xc0\xa3\xf3\xc5\xf2\xa3YQS\"?\xb2P\x05\xb6\x8f\xd8\x14!\xac\xfae\xb1\xde\x86\xa5\xc1\xac\xad\x9f^\xad\xeb\xe5\n\x9e\xd5n\xb6\xe1\x8fm\x144\xc2}Y\xf9\xd3{\x0b&\xd3`2e\xcaw\x1eV\xfe\x91\xf0\xa15!_J\x9e\xab\xe3K\x88\xb5\xf3\x96\xcc\xc3[\xb0\xf9\xc2\x83M:\x82\xa1.\xcfa\xb7a\xb7\xb9\xdb\xe9\xbcE\x9e\x8dt\x96;&\x9df\xbd\x94\x18T\xeb\xe2\xde\xa2\xd1\xdch^m4jv\xe7\xaf5 \xd58\xed[\xe8\x85-\x18\x81\x15E\xa7!\xb2\x0e=\xf3e\xcb\x05ElI \x07\xd0\xa7\x95\"k&%s}\xdc\xefW\xd2\xf3 \xfa\n=w\xa1\xf3\xa9B\x89Z!\x89\x91\x1a\x04]R\xb6\x04AU\xb1un\xb6\xc1\xdf\x06\x9e\xcfP\x08\xfa\xf3\xf8\xbc\x001\xf3\xf4\xc7u\xd7\xbc\xe5c\xeb\x8f\n\x1f\xec\xea\x17\x16*R\x85\x0f\xac\xa1c\xaf\xc3\xd7U\xae\x14rB\x98\x08\xd3*\x16\x086u\x05\xdf\xc7Z\x80\x86\xe9\x11%\xf6X\x17- 2\xf4.e5)^\x84\xfb\xbbZn\xacAa\x866\xe2P\xf5T\xbf\xdcX\x95\xc1,~\x92\xfc\xba\xadeu\xfc\x9c\xf1B~t\xa8F\xcc\x1e\x05<\xdc\x14G\xfeX\xc9\xfb\xea\x84\xf8\x19\x9c\xb6\xf6\xc3\xf1\x06\xb2\xfd\x8c\xe2\xfb\xb6\xd0\xcd\x8d\xc6~\xa1[\x08\x88\xdb\x1dM\xbbk\\ee\xf6\xa2\x15t\xa5:\xb7\xc2\x15l\xd1YT\xad\x7f2\x12\x1c\x88]\xfe'\xa2\xdb\xe0|\x0e\\4\x80\x91\xcf\x80\xc7\x80\xfct\x90\x02\x82}\xb9\x9f\x16\xcf`\xd6O\xfaq|\xcd/\xdeK\xc7\x8d\x19\xc2\x99R$\x9b\x91\xcdi\x89\xf1l\x83\x0f\xf1\x17\x97\xc8\x13\x07\xa8\xbd\x93\x84\xbe\xfb \xbc\x93I\x17\xf17 \x93\x7fzx\xf8N\xfd\nR\xd1\x0b\xd9\xdaj\x10U_H\xcb\xb4|\xfa\x95\xf4vi\xa8V_%W\xf7_\xf9\x994'`\xbc\xe0S\xe9\x86T\xad\xad\xde\xae\xc4\xb1\xb6\xa4\x91K\xfb?{\x8f\xf1\xc2R\xa3\xdc\xb0\xa8E\xb1\xf1\xfe&\xf5\xf0\xd0G/< \xda\xd0i\xac\xdc?\x14\xa5q\xa9\x12\xceW(\x99\x15\xe5\x9c/F \x97\xb7\x86M\xb7\xdb\x9f_|\xdb)\x1fy\xc5\x82\\YJ\xf2\x1d\x89\xf4\xd2\xa5$+\x92\xed\x80\x10\xff\xb4r\x16\xd5z\xb6\xf4Tb\xfec\x8c\x02p\x14/c\x02k%\x94}B(\xea1\xf2\x80t_qT\xa4Ae$\xdf\x04\xd2\xc3\x03_\xb0\xa2\xe7C\xcaz\xcc\xd3\xdd\x1a`\x03_\x0b\x8a/\xc1d\x87\xe2\x9c\x17J9\x01!\xa2\xa8\xde!\x86A\x88&\xbdx\xec\xb5\x92\xc7\xcb\xc9o\xc1\xcaZJ\xb1\x14\xdc\x04\x16\x88o\x8fL\xdfG\xbfd!\xce$*\xe4\xb3\xec\x8c \x1e6\x94\xa9\xde\x18\xd6;.@\x81\xf4\xeaI\xe4\x90@?\x16\xa5Zp\x997\xae\xad:c8\xeb\x15\xd3\x18e\xd0\xf22\x15\xc4\n\xdfs\x11&c\xcb.\x9bH\xfc\x0f\xe0\xfe\xb7\xcb\xdfN\xc1\x9f\x08`$O\x98\x8f\x93\x0e\x03o\x06\xd8\xc8\xa3 $\x11C`:B\xf2\xeb\xbe\xcccxT\x9c\xd99 \x11\x16\xe7i@\xd7\xe5\x0b\x1d\x1f\xd2\x91\x9aU\xc9N\xc4\xc3,\x84\x0e\x03\x0cQq\x9c\xd7\x0f\\\xe1\xe2[\x93\xf4\xd1\xd0m\xd4\x7f\x8f\xe6\xff\xd9\xa1\xde\x10s\xfe'W\x8f\xfc\x002\x9d\xfcA\x8e6\xa7\x96\xbc\xbdX\x84q\xa72\xf4&\x08\xe7\x82\x82\x1f4\x0c\xb2\x07SU\xf5\x87\x84\xd9Zm\x8d\xdf&\x9a\xaf4V\xae\x91J\xb0\xe6,\x8e\xd2\xb40\xd5\xe9\x1b}$\x97q]~\xa2\x07\x1e\xd0<\x0fU\x88\x0d%\x8b\xf3MJ\x91\x9e\xf2N\x895\x95_u\xf1\x9eC0\x0d\xa2\xfe\xee\x93\xf3\xc5\x8dP\xf0\xd8\x99D\xdd\xa7\xe1\xc3\xf0a\xff\x04\x0d`\x07?N\x9f\xb0\x0b\xf1\xe3\xc1x\xdf9\n\xe0^\xb4\x0f\x83\xa7\xfda7<\x19\xd2\xe0qx8*\x91Q|n\xd7B\x1b\xa2\xfc\x1c[,\x1ek\xa4{:\x12*\x13\x03%:\xd9\xd0P\xd4\x10\xc7\xfa\x063\xb2\x12\xd04\x12nke\xb1\xacC0\x83\x1e\xa6\"aX\x04(/\xf9\xdf\xc2\x96\xe4Q\xef\xc1\xb9\xe5|\x03\x172\x02,\xb4l\x1a\xe0\xe4{\xf8#p\xb9t\x8e\xe1L\xc9\x9d\xad&ry\xe6\x88%yb\x89[e\xb7b\x9a\xf2\xb3T\xd3\x14\x8b\x03\xbe\x95u\xce\xeb \x9e\n\xa6\xf7k\xf2\xe7\x8d[q\xb0kR\x80_\xb56,\xb6\x01\xfd9\xf0\x12\xfe\xac\xde(\x1a4,\xb6f\xe9 \x95W\x0d\xb3\x97\x9b\xdd\x862\xb5\xd0\xbd\xb7\xec\xb1\xd3\x89\xf0\xecN\xa6o 1;yK\xb4(,G\xdaL\xbbl\x91\\\x95\x91\xb4\x14?\x94$\xeeM\x8e\x9a\xca\xd1m\xcc\xd7\x862ts\xb92\x19\x8a\xfd\x10]$CI;\xb3\x0c%-\xb8\xe9)M\xd5\x9b\xe8X\x88\xce\xf2+\x8cK9\x07\x0d\xc5lISeX8\xc44\x01Y\xab'\xef\x80\xabre\xba4\xa7\xbb\x18\xc7Z-\x12l6\x00ul_\xad\xbc\xda\xec\xdf\x89\xa5G\xb2^\x7f-+\x8f4Wb\x89\xc6\x10\xb3\xaf\xc1\xbd\x07KX\x97\xd5\xed5*\x92,O\x90\x95\xca\xfa-\x8f\xec\xb2\xf0x;_S\xb1X\x18|\xc7-74$\xe4\x1a\xe4}\x9f8\x93\xc3\x94\xa7\xfb\x9e\x8d\x90\x0deq}DU\x9a\xd3\x9c)mHe\x93\xaf\xc0\x9fEM\x97\xf5\xeb\x8aZj8Yu/\xfd\xb5\xa8g\xc5\xa4\xa0\x02\xed\xab\xe5\x840\xb40\n\x15\x89\xf7\x8a\x18T\xbe\xcfm-\xacU4\xfa\x8du\xafmY]>`\xfdD\x18j,\xd5K\xc9\xa2!Z\xe5\x045\x08P'Z\xb0\xb7\x98t\xa1H\x96b\xd2R}\x00\x11/6?\x83\x81\x87|7\xdbT\x9a#*\xb7\x8a0I\xfe\xdb\x9bzl\xd4\x9b F6?'7%\xf7)\x83\x1e6\xd5\x06\xf0y{5a\xae\xb0~\x96(\x0c!\xaedv\x19\x87\xe5N?\x9f\x93\xf8u\xdb\xb6\xe6\xd9\xc2W\xa1\xcak\x1a\xbb\n'\xb9\xf3UL\xf4\xc2\xa0\x95\xb7\xda\xd0t\x9c\xbd59J\x10\xc7\xae\xba}\xee\xef\xd9P\xd9P\x96\xd4\xf5\x1aJ\x04\xf4\xd5\x05\x0d\xa9[\xdbxu)\xb7\x9e(a\xc3@U\x11\xfb\xf6\x15\x90A\xdf\x9f\x9b\x15O|\x91\x9d\x8e\xe5\x1d\x05\xa2=\x90w\xcc\x03\x98/\x85e\xdeX\xab\x9f?#F\xeba\xd9\x067\x03%\x7f\xcf\xb9HA\x80\x92o\xc2\xe3\xbc\xec\xdf\xbcm\x14\x17j\x80w\xf1\x8a\xe2V\x94_\xbc\xfbQ=\x11\x08b\x80\xc6\x01\x9b\xe7\xba\xdd\xfe\xce\xd5\xffY\xd4\xe6\x9e3|I\x17\xd6\x82\xe8\xa7\xd3\xb2\x93\xdb\xa56{\x9aa:\xb3i\"\xa4T\xab\xa2qA\x95`\xdb\xc9)G\xbd|\xf5\x10\x880\x17f\x18r\xef\x050\xc4\x84\"\x87`\x97\xaeBB\xdb\x9e\xf5\x06\xa1\xe1\xd8\xc3\xcf]\xde\x98\xd3\xdc\x02j\xddMgw}t\xc4 \\\xedh\x88,\xff\xac\xa1\x1f\x12\xa0\xae\x82\x94\xa0\xa4[\xc9\x15\x9f\xbeh\x8fbV\xa7\xdc\x18\x1b\x8b\xe4\xba\x19n\x93\x184\x94J\xd7\xe3\x1c\xe8Gb\x1e+\xcf\xb6\x9f\xc2\xd0\x8dy\\\x8e[\xd7\xff`\xdb\xa3\xe9\xc9!s'c\xf8\x04\x1f\xdc\xe9\xc3\xb4\x1b\x1d\x1cu\xbbG\xc8\x8d\"\x1fv\x9d\xf9\xc1Q\xd7\x1f\x18\xb51\xf9\x8a\x8f\x11\x06}\x103\x03\xf4\xa1/\x94L\x9e4\x95?QM\xa7\x9d \x16\x1a\x8d\x93\x8f\xe7\xf9?\x13t\x08\x86\x18\xb9\xa0?\xcf_\xa12\xcf\xce\x0b,^\xc3\xb1\x84b^*\x13\xbf\"\xd5\xac:v\x8d\x84\xf7\x9c\x95\x1f\xe5\xd0\xed\xd4j5'=\x1b\xf2\xe0\x7fzl\xe4\x86p\x9a\xceR\xda\xeb;\x9a\xbf\x9fI\x8c@7\xdd\xcdPXL\xd4j\xd2\xea\xe6/D\xb4\x973\xa4\xa3\x0buG\xc6\xd75\xd6\xcb%\x80\x9fEr[\xc9\xb5\x9ae\xf7\x99\x93\xac5\x0d\xff\xd2'\xbc\xae\x8d#\xa8\x93+\xfc\x9e\x0eSL*\xa8K\x86iC3\xb8\xa4q\xde/e0\xd2k\x15\xdd\x95\x85i\xaba\xaf\xdaV\xfa\xe57s\xf39\x84\xe5\xccA\x13\xa5^\xe8\xca\xec&\xb7\xdc^\xef\xb1j\x1ef\xfc\xe6\xc8^\xb5#+\xdc\x9d\xfe-7\x10m}\xdb4\x9e\xf9\xfc\xadF/\xd1\xa9\xb5\xb3\xbaI\x16\" _\xa0_0K\xda\xd5\x8c\xb2XyW\x81b\x1b\xdc\x8f<\xcagX\xdc\xe2\x1b3\xc3\xc3`:\xf2\x9c\x91\xf81\xa2(\x04SO\\`\xe7 o\x82\x14\xaa\xc0 \xc2ub\xe4\x1a\xf6\xe2Y\x94\xaeTo\xd0H\xc9\x96\xd2\x0b\x83{\xf8\x88\x02\x1f:\xa8\x81\x04\xa8\x90\x96R\x10\x7fX\x83\xd1\x14\x10\x9c\xde\xd1`1\x9fo\xae\xc2P\xf4\xa27b\x0b\xb1\x15\xe4\xf1Yt\xa0e\xc7C\xc2t\xf0k\xb5\x9a\xca>\x9d]z\xd5\xf4\n\xd7\x19\xe9\xad\x11@e\x9a\xe6\xdeF\xcd\x82C\x18\x1a\x03\x94\xc8\xa8-\x11\x8b\xd6\xb0\x1a\xcf\xa2,)\x9f8\xad\xcb\x9c\x8f\xd8\x86\xeb\xb0\x15\xf0\x1d\x121\xca\xa0<\x1f\xb9i\xce\xf8\x15\n\xfd5*\x08\xae\xc2\xa7\xd4[\xbe\\\x01n{\xe9\xbcR\x11}\x13\xcbT,/\xd2\xb3\xf8E\xb9#E\xfe`\xab\x9c\x98\xae\x14L\x83\x95v\xac1\xa7\x08k\x04\x83\xafH\xd4\x9f\xdf\x96/\xca\x12\xe5N\xce}G\xadv8\x8a0\xc5\xf9\xe62\x90\x89D\x11\xa7\xc5\x8c\xbf\x85\xff/6Sd\x96\xdeo\x19\xa4si\x8c\xb0\xc7\xe6\xbd\xea\xdbi.\x92v\xe2\n\x9a\xf2\xbe\xbb\x85\xec\xd6\x10\xc8\xb6g\xb5mk\xb5<\xdf\x8b*g\x15-\xbd0\xae/\xd0yY\xac\x8a\xc28@.\xeb\x7fEiJ\x9f\xe0\x88.\x85!\x13|f}\xd7J\xa3i\x1f{\x98\xd9\x9e\x92\xfcA\xb6\x05c\xe2F>Z<\xdf\xbc\xfd:\xcf3\x1f{\xad\xdbZ\xe4\xf3}\xdd\xa4\x13\x9f\xef\x1c\xa0\xb07GP\xf3\xe1V\xfb\xb2X\xb8\xbcJk\xf0\xe3\xef\nb\x90\x8c/\xf2\x9b\xbc\xb5\x16\xc8\xf6\x19\x061\x8e\xa0\xbf\x15\x84d\xe2\x89\xd0\xcd\x9eq\x12\x14d\xa0\xdf\x15\x03\xbd\xbe\xb3\xe3\xf8\x1e\xc2\x8c\xee|\x95\x7fly\xee\x7fvx \x8b0\x8d\xe8\x96\xb8\xe7\xce\xccN\xb9\x96\xe2\x90\xe2\xf8D\x15\xc8\xc0\xc2\x9b\xf3\x8b\xfa\x1c4\x87\xc0\x85\xafBd\x08\x9c\x8e\xc4\xc4\x90\x0b\xd1@=\xb1\xa9\xe2\xe3\x13\x83qP\x96\xbb^\xdf\x91]z\x96\xd7V\x87d\x82L\xb4\xdd\x86\x84\x0c\xf8\x9aS~\xd2S\"\xa4O\x88\x8f \xd6S\xa2\x9e\xb8\xba\x1a\xb1\xab\xf5YD*\x12=E\x8e\xd4\xc7\x10\xcd\xc5Pw\x1c\xa8\xb8\x95\x10p\xfeXb\x12\xbc\xd4\"\x10u\xafu\xb0\xdcB6\xd2c\x1a!o82~\xf6Q\xbc\x0b\xc7f1\"\x85i\xe9\xcf\x84\x8c\xda-\xff\xb4V\xed\xe4\xba\xcb\xb8\xc5\x9bF\x7f\xcf\x1a-\xb8RO\x9d\x05\xc8\x9b.'\xcdZ\xd5\xe5\x90\x10\xfe\x8b\xa4{\xe1\xc7\xe611\x1c(n\xf0}+\xb3\x96<\xc9K\x13m\x1f a\xe5&\x0b\xa8+\xdd\xe8V\xfb\x82\xb6\xd5\x19\x18\x85\xe05\xb0/\\4-U\x99\xcf\xc4\xf7lP\x00 \x8b\x82\xd8\xd8\xb4\x8c\x10t\x17\x1fQ+[\xc5\xefZ\xb1\x1cmK\x9cv\x8a~\x11d/\x99\x1f\xe4\\\xc2\xc4Eva\x13o\xb9\xca\x05\xd1\xb3\xf0\xcd\x14\x877\xe6_\xa6Vf\xce\xdd\x9c_\xa8fy-\xb9\xb5\x92\x05\xb8\x04\xd6\xeez]\x84\x082\x14k~\xfcr5{M\x15\xec\xae\xb7\x0b\xb5\x99\xa39\xb7\x17\xa5\x1a\xca\x97qdS\x1c\xf4z\xf52\x87\x0b\x17\xbf\xc6\xf1\x80\xca1\xa5\xa0\x9a\xdf+ \xe2\x8f\xc8n\xe9!k\xd8\x80\xb6\x15J\xdbu\xe1\x0e\x80e\xf5+\x176G\xe2\x0e\x89\n\x95\x8b/\x99XS\x95[\xf3\xb0Zo\x11r,}\xe1\x16A\x8d\x97\x16\xe2\xc8\xc7\x1f\xdfBwj\xc5\x95i\xc3V5n\xec\xd1>\x1a\xc1\x89G\xa2\xb0B\xef\xe2;\x16\xd5\xd6q\x937\xed[J\xfb4\x8c}\xe1:\x98\xdc\xdcj\x89\xe5*n\xfe=\xe9!\xc1\x189\x92\x92\xaf\xd9?\xb8>J\x84\x15\x99\xa2\xb4\xf5bE\xb1\xd7\xb6\xba:\xa5\x92l\xd4\xab\xb4Q\xab\xba\x95b}\xd5\x19`S\xcc\x17\x8f\xfdc\xdc]M \xcef\xa4\x15)\xd6x\x13E\xb2\xed%9\xae\x11\xcd\xc5t\xdfD\xac\xd7\xc6U\xbc~Q\x16\xe3\xce\x04\x9a6\x94\xe8\xd5\xd8d\x12 \xbc\xc5i\x95\xa8\xf4k\xffL\x99\xd2\xe6q\x9b\xf5\x89\x88\x0c)\x00\x0d\xe9/<\xe6\xc8f\xafv6\xa0a\x0e!\xe2\xc2\x14\xc0\x90\xcd{m\xa0hN\xbf\x8a&\x08\xd1\xc0\xd3Tn\x192\xe4\xbc\xf1\xb7\x0c\xbb\xdaSV\x16\xcek\xe8*K\x8d\xebKSU\xa6\x1c\xff\xf5\xa6\xa9VP\xafNS\xb5\xf8&(T*\xec\xd4GRT\xf3\x94\xd3\x8aa\xc8\xfd\xb3\xcc;\x96\xc1\xd6;sZ\xb1\xbd\x98f\x86_\xdd\xc8\xeamw\xca'\xcb\x93\xd7\x81~\xb1~\xa4\xb0\x10\x97~\x05:\x0f5\xfc\nt\x1e\xe2&\xeb\xe3W^\xd0\x02\xde\xce\x05B\xe7\xe1\x85\xbb@\xa9\x92i\xc8\xa2>/\xdc\xcc\xbc\x19P\xf5if@\x93'\xf6\xe8&\xa0\xdc\xa0\xbf\x85\xd1\xb5Z\x9f\xb7\x9cqZd\xae\x1d\x82\x07^8\xaea\xb2c\x88\xb8\xd9\x9b\xd9\xce~n\xd9l\xc7\x8c~\x15\xa6;\x8d\n\xd4\xe7;2p\xdf\x89\xb9 H\xc8\xe8\xceW\xfe\x1f\x99\xdc\x1eA\x8c\x91\xcfm\x8f\xfc\xcbj\xc3F6\x8d_~\x8b\xb4vL\xbf\x89\x05\xb7$l5\xa5-\xbf\xc2\xe4\x9d\xda\x10\x97q\xd2D\xdf\x85l\xd1&\x89q\xa7\xdfa\xda]\x0e\xbcY\xb2\x9dOi\\\xde\x1a3\xb0\x15-K\xb5\xca*\xeb\x1ew\xfc\xe2R\xeeE\xba_\xba\x1f$a\xfd4\x9a\xe4A]\xb0:qp\xf2$]\x91P[\x0dT\x05\x99\xa5\xf7F$x\x86tZ>+\xd8\x84\xad\xb9\xecd=\x1e?\x8b\xd1i-Y\x933\x14\x0b2\xfe\xaa\xbe\xbd\xa0t\x7f\x81\xec7+a\x0b\xf6f%j h\xc8c\xdd\x86C-\x04\xafx\xeb`\xdd\x97O\x8d\xad\xae\xd5\"\xc8*Y\xae\xda\xb6\x17\x93)\x7f[<\xd9.\x9e,<\xda\xcbO\xdd\xb7d\x02_c\xee\x7f\xdd-\xe07\\\xe2\xd6\xb0\xa1\x16\x19lU\xa3^T\xfa\xfa\xcd\x96\xb6hK\xdf\xf2\xe9o\xe6\x10\xbcfs\xe8\xf8\x84\"\xdb|`\xd68n\xf1f\n\xbf\x0bS\x98\xcd\xfb\x0b5\x84\xdfB\xf5\x9fEq\xed\x03\x99\\\xfb\xb8\xd1\x9b\xfa~G\xea\xfb\x9aB\x99\xb7\xe4\xd670hk\x1f\xcb`4c[\x94\x8b7v\xd0V\x88\x9c\x89\xec\xad\xe2\xa0\x1a4c \x81Hn4\x8b\x9b\xbe\x15\x11\xa4\xcf\x1aY\xbc\xb6\x05_\xa7\\/@\xd4Y\x081\x1d\xa0\xaa\xb3\x04\xee\xe3&\x80\x91\x07\x94\xc8\xe3\x9b\xc7\x7f\xe1\xf2_\xed\xf1\xf3s\xfe\xc2]=\x1c\x93\x08\x1b\xfda\xcd]?}\xa1N\xee\xe2\x04\xf9\xc4N\xa0\xdeN%%Q\xa8;\x8aA\x82\xe4\xab\x93\xda\xb6`\xeb\xee\xba\xa1\xf3\x80\x18\xdd\x89\xf9Za\xb0>\xc6\x17\x8aJ\x88\xf8\xed\xfa\x18,\xbd\xc6\xe5\x89~\xe1\x1a'\x07a\x89\xe3V4\xd6\x86\xb2\x1a\x0dlOi\xb5\x11\xf4\xba\xc7\xce\x8d\xd4\x87FA\xe0\xcfw\x18a\xb0\xe2\xf6\x9b{\xfe\x1a\xc8\xb6\x80\x0c\x80C<,.\xed\x15w|\x8d\xa0g\x12\xfa;\x01R_y\x9e\x87\x7f\x82\xb8\x16\x19\xb8\xf3U\xdc\xf5\xe1a1\x9e\xfa\xd7|\xaa\xd0\x1bZ2\xb87\xd173h\xbf\xd6\xa1(\xee?\x82\x8c\x8c\xad\xe7=\xbd\xfe\xcd1\xd0\xb1\xae\xf3\xafe\x83\x8d\xc72\x0d\xb4\x89\xb4(\xb2\xc7!/F\xc8y\xb8\x9f\xc9\xbb\xb4$\xaa\x92U.[c\x87\xb8J\x10\xa0\xb3=.d\xb0\xd8\"7\xf2!\xa4\xbd\x88\xaa\xb7\xb4\xe8\xd0\xf0VS\x88\xd9\xa2v\x1e\x1e\x90\xca\xee|2\xac|\x9f\x97\x19\x9d\x11/\x19o\xad:\xbf\xfft\x0b\xbd\xf8\x10\xb8D\xbeU\xa6\x81\x8e\xca \xf1\xbf\n\x85\xfc\x7f\x8a\xfc\xe1s\xdc)\xb3\x03\xecv\xb2\xdf\xc5\xf0\xc5\xffj\x87\xb3\x0567\x8b\xff\xb8D>\x8f\xfe\xde\xa6\xfe\xf9\xa6\xfe`M\xa6\xdep\x93\x9e\xbd\x08p\x9b\xd1c\xcaq\x03\x86\xaf\x03\x14\xd3\x92\x10\xe1J\xb1[\x0c]\x90\xcf\x04~\x04\xe9h\x01\xe4/\x90\xa6\xa7t\x17\xc3\xa5\xa2\x00\xc99\xb3\x1e\xf9\x03\x9aW\x8aR!IZh\xf1\x81\x0e\xd5\x9e\xd2\xdf\xcf\xd4\xcb\xd2KXs6\xbd//uE\x98K\x94\x9b\xbb\xc40\xf5\xa6\xf2V\xd6]\x17\x05\x0f\x07\xfbN\x04\xbf\x0c\x1f\x9e\x10<|\n\x86\x0f\x8f{\x87\x0c\x7f\x99\xbaO\x93}8p\xf6\xdc\xee\xd1\x06\xc8.\xc1^ \x1d\xb5o\x87\xe5\xd1\x85\xf5\x84\x14\xae5\xd3z\xd8\x94 \xca\xe0C\x12\x94\x14\xd7\xdc\xd5\x90\x9b\x07\x1d.Q\xbf\xa4\xc2Wj\x9e6\xbd\xba:\xb8\xde\xdb\xef\xecw\xf6\xf6/\x0e\xba\xfb\x07\x9d\xdd\xc3\xee\xc9\xf9\xc1\xe1U\xe7\xf2\xf2b\xef\xf8\xfa\xec\xf2\xf0`\xf7\xba\xb3\xbf\x01\xc0\xfdL$g\xad\x07\x9b\x97\xfd\x05\x14_v\x8e\x0fv\xf7\x8e/Ov\xf7NN\xf6NvO\xba'\x07\xd7\xd7\xfb\xe7\x9d\xb3\x93\xdd\xce\xd1\xf5\xeeu\xf7\xe2\xf2\xaas\xb9wtv|tq\xd59\xdc\xdf\xbf\xea\xee\x1e]\x9c_\xef\x9d\xef\x9f\x1c\x1e\x1cVkP\xe1\xa6\x83\xb4\xdb\xbd\xc3\xe3\xf8\xc7\x85\n\x9e[8\x84\x8a\x05\x02:n\x00\xe3\xaa0g\xde\x81\x891z\x7fR\xd1\\\xe5e\x97\xdb\xdb\xcef\x01Y\xde\x85\xd9\xa2:\xdc;\xd8W1\xe5\xcd50x P\xeb\x9e\xcc\xcc\x13\xdd\xc2!\x0f\x19\x91+$\xed~F\xad\x85M\xac%z\x8eNKL\x93\x9f\\q\xd1\x08(\x80C\xd4\x93\x8d\x1a\x81*\x8bG{H\xdf\x1b{\xd6\x94\xee%.\x97\xcdZ\x89\x17b\xf5\xe7\xd3$t\xc1zj\xc6\xb4\x14\xd04\xe9\xff\x03\x1d&\x828@%\xafe\xa5{C\xa8\x95\xdd\x92\x06\xe82\x9c\xcb\x8b\xb9\x9a\xd5\x1c\xa3qu\x14H\xbd!\x86,\n\x9b\x0dT\x03m\xe8G>\xa9\xd0|\xb8\xfa\xe3\xe2\xe6\xf7\xcbNw@/oCx\xfc\x81\xf5?\xd2\xf9\xf9\xee\xf4\xa8\xffx\xff\xe1\xe0\xe0\xcfhw\xef\xf8\xe9\xf7\xfe\xb5\xf3\xe7l\xff\xef\x17\xd7\xf3\xb3\x9b!:\xf8\xf3\x9f\xb7\x83\xf77\xd1\xe4\xe9\xfc\xaf\xc3\x93\x0f\xf3\xc7_\xe8\xe3\xe5\xf1\xdd\xee\xcd\xd4\xbb\n\xfe\xee\xfd\xd1?\xfct\xe72?\x18\xfe\xfb\x1fJ\xafA\xd4\xef\xe5\x02\x14`\x1a#\xa8L\xb1 \x90\xc2o\x15C\x059\xfb\xc6\x10vQ8\xf60\xdb\xb9\x8d\xfa\xef\xd1\xfc\x0e9A\xf7\xe0\xf0a\xb7\x98\xc92l([\xf6s6y\xea\xec\x7f\x1a\xb1\xf7\xbf\x8e\x8e\xcf..>=\xf97\xc7\xf0\x9e\xd0\x9f\xe7\x1d\xef\xe1\xfa_\xefo>\xfd\xf2\xfb\xde\x97\xf7\x1fBB\x7fQ{\x86\x8e\xb0N%KS\xd9u\xd6m\xce $\xfb\xa9\xcd\xb0\x9c\xfb\xc4y\xb8\xb9\xb4\xd6\xfa\x9a\x91o\x00CV2SV\xb2^\xb0\xa4\xc0d\x18\x81:\xa6\x8e\xf2s\x9eR\xb0\x88Z\xc1\x88_\x94\x93\xd6-\x98!\xd2}\xb9\x0f\x8e\xaa\xc3!\x19\x8b\x8e\xa2\xfeV7ag\xad\xb8&q\x18\xcc\x1b\x9b\xe3\xfb\x02\xccf\xb7\xb3{\xb4\xb5\xdb\xdd\xda\xeb\xdcw\x0eN\x0f\xf6N;'\xdb\xdd\xe3\xa3\xbfwvO\xb3h\x02G\xe3\x9e\xc6\xa1\x98\x08I\xf8\xecC\xcaz\xe2\xd2\xda\x1c\x17\xf4Ip)iI\x8f\xd2\xb3\xd7\xe8s\xef@\xedT\\\x9d\xcfz5\xc5\x91\xafv\xeb\xc2\xa4\x97\xb5\xd3\xba\x90\x18\xcdX\xaf9\xb8r\xd2N=@\x18\x04uA\x04Oe\xf8[\xbb\xbb\xe4h\xf4\xbapAre7TW|F\xd0x]\x98NK\xf1;\x95\x1a\xb6EHl]{\xb9\xab\x1a\x17\x18\x04u\xe1;\x89\x91\xb16/\xc5{\x1f\xccj\x95\xbf\xf4\xa1~d\xa8\xa1\xbe|\xe0}SL\x8a\xbe6\x9f\xad\xd2g\x9d66F\xe2D\xb2\xefe\xd67\xc6\xf8\xa5\xba\xd0-\xd5\xfd\xb2\x88gOe\xa8\x91a\xf0\xb0\x8b4Gk.\x807F\x0d\xf21\xed\xe3-\x875$\x11\xd6|\x84\xbb\x1cR\xee\xf3(\x83\xe3`)\xc4V\xce\xb0\x80\xd7\xd8\x9f&\x12\x91O\xda_\xb7\xf4R/\xcc\xf2\xb1\x15i\xf9\x18\x16\x03\xf2\xb1f\xc8Qt\x7fq\xb4\xff\xbb\xff\x80\x1f\xff\xfd\xe7\xd5tx\xf4 \x1f~8\xfem|t\x1d\xfd\xd5\xb9\xfam\xbf\xffe\x12}9\x0c\xa7\xbf\xec\x8e\xef\xff\xf85\xfc\x18}\xf8\xf0\xd7\xe4\xec\xec\xf1\xfe\xe4\xd3\x97\x7f\x0eo;\x1f\xcfv\xee/\x83\xc3h\xe7\xa4{\xf6\x18\xfe5\xf8\xd7\xafw\xc1\xf9\xef\xff\xf8G\x1aR\xd5K.I\xf6\x8cQ9woe*t7\xe5\xd8ZM\xb0\x94\xa9)\xb8\x143\xc8\xa6\xdc\xf5@C\xb1\x85\x16\xffE\xc2\x8fh\nC\xd7\x9aO\x15\x96E\xdbu1\xbb\x9a\x90\x1d*\xdd\x02[\x1b_\xb9\x0cNG$6L\xe5\xb0\xa8\xf5\xb8B\xb5\xfdr\x04\x19\x99\x9c\x8b@\xdb\xe8)\x19z\\\xe6a=\xd8Ah\x9f5\xde\x8c\xf3\xe9\xc3\x138\n\x0fg\xa3\x11;\x08\xc7\x8f\x13\x84\x0f\xbb\xc7\xf8\xc1\x9f\xf9\xd1\xd3|r\xfct\xf2\xe5\xf1\x8b3v2\x99\xce\xe5\xcb\xef\xc4\xb28\xc9\x93\x03\x12\x82\xf7h\xde\x87\x14\x89Mw\xc0\x08\x18\"\x8cB\xc8\x10\x80@\xd4\x0c\x9e\xf6\x87\xdd\xf0dH\x83\xc7\xe1\xe1\xf0\xc4\xa1{\x0f'N4\x88;\x99\x10\xe6\xe1a/ \xd3\x1a\xa2\xbe\xabH^\xba\xe4\nB\x8f\x84\x1e\xb3\x1eS\x8a\xe5\x1e\xcd\xd8\xad\xc0\x92\xd8N\x0b\xf6\x071\x80F\xd5\xf3\xbb\xe8\xccc~\xb5*\xaabV\xd5.\xed2\x1f\xc2U\xb5\xa4\x0c\xb2\xa8Z\xa7\x07\x1e\xe6(\xa1\xef\xcf{\xc5\xcd\"}v\x9d7\xcd\xef\x1dSq7Zoa\x0eG&H\\\x14\x10Z^8-\xab\xec\xb1$Q\x06\xc3\x05\xa4\xdc\xc6\"\xd3\xc6dk\xf8^!\xc8\x97\xea\xd0-:\xd6o\xa6.\xcb)\xdb\xe1\xc4\x13E\x16\xad\xd7\x15\xdb\xa2\x08\x87\xf5 \xe7e\xc3ovr\xdb\x9d\xf4I\xfde\x9f2\xe8U\xeb\xce\"\x1c\xd8>\n\xd0\x83\xf7\xb8\x85\xefM\x10k\x8e\xe8\x13I<\x95\x05\xd3&\x84-0\x98\xb6\xb3L\xaa-O}\xcf\xc4\xff\xddB\x1c\x9f\xe5\n\x83\xa8\xbf\x16\xbe\xea\x0b\xf4\xfcr\xd1T>\x98\xd0[\xdc\x82K \x0f\x08W\xcb\xbc\x9b\xc4\xf7=:\x82\xe1\x02\x05\xa9p VK\xcc1\xc1\xde\x83\xe5\x9e\x8d\xe7\"\xccr^\xb6\xa2\xf1\x14\xf5\xa9W\xbc\xb9\xd9\xd0\x96\"'\xe2\xee\xbb\xe7\x10\xcc\xa0\xa3\xdd\xd3,\x01\xb9\x88A\xcf\xa7\x0b\xdb\xf6 vK_G.R\xcfM\x15\xd8\xc3,\x84=6\xeb\xc5'\x0bU\xcf\xb0f_!\xc2\x1c\x0f\xf7PM\xe9\xc80,t\xb4\xb90\xe7\xe4\xa8\xb3\xd5\xd9\xdd\xea\xec\xdew:\xa7\xe2\xff\xff\xcatl<\xf6h\xe3\xa4sX\xba\x96\xdb0O\xc6D\xd8\x18\xcez\xed`qF\x10\x0fQ\x0b\xc8\xe4\xd5\xd6\x05\x1e[\"2\xf1:[\xb8[[\xd1\xcc\x02\x94\xcc\xa8\x86\x90\x8a\xe4\x89\xa6\xb5\x85M\xe9C\x1f\xe6\xd6\x90\x95Q\xc5\x1f\x89hf\x03\xadU\xfe\xb7\xca\xc1\"\xccB\xaf\x9d\xb5e:\xcc+\x8937\xf4+\xb5\x1f\x8b1\x0b\xac\xd0\xef\x958m3\x1b\x9a6N\x88\x04\xe3m\xec\xcb\xd8\xc3\xd5FD3\xa1\xd6\x03[\xe5d>3\xd3\xf2V\xdd\xc4\xb5\xac\xd5G\xe4>\x1f\xbfh\xe8\xd4\x84p)\xb3\x82hQeT\x8el\x168\xc45\xc6>\x8f^k\xaa\x1c\xc2-\xb2h^=c`\x05B%\xcd+\xe7\xb6\xb1Y\x1a\xf4^z\x94\xdd\xa4\x85\xf6\x16lh)\xba\xa6\xc8\x1f\xf4Dd\xd3b~:\xb7\x1c\x17E\x8e\xa6\xf0b\x19\xec\xb7Q\xdf\xf7\x9c\xf7\xc8^tD\x93\xaa\x19\xab./\xbf\xf3\x86\xd8\xc3\xc3Z\xd3$\xd3\x10\x16\xa6Xl\x82\xf6\xc8`@QuC\xb9\xfa\xe8E\x98y\xa5\x14\x7f\xc1\xb8S\x8a\\Y\xc3BM\xf1j\nq\x0bC8\xbe\x10\xc1\x93\xfd\xe0\xa2>\x0d`\x8d\x0c3e\xf0\xc1\xc3iUd\x8d\xd5\xdc\xe6\x078Ke\x98* \xa7:86\xab\xa69\x1d\xa9\xfc\x9a\xcd\x9a \xad\xef\xb5\xdc\x9c_\xd4_l/g\x05\x0ci`\xab\xe0?\xafT\xc04\x0b\xdazD\x9d\n~\xfbD\xf0E\x92q\xb8c\xb0F*\xc6j\xcb\xc7\xc6i\x85\x84,J\xbe~$$\xcd\xba\xe6k\xb1z9\xfbQ-\x05w\xf2\xab\xeb\x8fi\x7f\x16\xa3lfC\xad$\xa9\\\xd6X\xb4Q\xca%\xac\xdf\x96\xd4\x07\xa4\xbf\x12\xb6\xd0\x89\xcaik\xb2\xb3\xb2\xba6\xac\x8ajM\x8a*\xb2@N\x8a\xa0\xf2\x12\xf8zJ\xb1@\x1d\x06!yB\xa5\xa8 K\xa5\x89O\xf4\xad;\x0b\xb2\xd6Z\x08=\x14\x10\xd1\x14\xd5M\xe4jk\xa8\xca\x96S\xf9\xbdl?\xe5S*@\xb7\x80\xc9\x7f0j\x04\xbaP\n\xd9,\xb8\xdd\xac8VW\xb4f%\xdd\x06&\x9b\x18\xbc\xb0@\xcd\xc8\xb1\x05\x85i\x15\x9c6d\x92L\xc5hM0i\x0b\xd0\x9a 2\x16\x9dY!\xabQl\xa6\x93r\xd9\x87\xb6\xc8,\xed#_`f*.\xb3\x119\xf9\x18\x8b\xca\xac\x06\xbc\xcab2\xbe\xae@n\xcd\x02\xfd\xa6\x15\xb4\xc5jUC(\xca\x1bq\x90\x9aT\xad\xd0\xe5\x96\xb9\x94<\xda!\xa8\xcdUA0\x04JF<\xc5`)y\xaa\xa2.kd\xd9\xa5\x9b\xc9\x15o\xd6\x9c\xce\xae\xb4Y8\x97IC\xc5\xfd\xabnR\x0b\x95;\x1bG\x9e*\x19@\xb6\xa8\x06^@\xddB6\xcaC.\nz/\nc\xb1\x18>e\x9az\x9e\x9c\xa49\"ZY\x14\x8f\xab\x17DX3\xf2B\x01J\xd7\x94\xa5\x0b\xfdkx5\xc5\x05\xeb\xfa\xb0\xe6\x8a\xed\x98\xd3\xdb\x90\x16\x162\xe4C\xdc\x1a\xeaj\x19!\xa7\x12c=F\x818'\x8a5\x18m\x1d>\x88\xa3zr\xbfT8\n\x84\x1d}[E\xc4\xc5\xccd\xd3K\x97Px1\xfc%\x05\x0d\xac\xa5\x1d\x90\xa7\xc5\xd5g\x8d\x84[\xa4\xbf\xb2\xd5\xfaZAu\x14\x16\xa3^l\x02\xc5Ei\x1e\xae>\x9d\xa5\x96\x05,\xdb=\xe3\xd5jM\xa5\xd2\xf0\xf5Sf\"%\x9b\x1a\xd9\xc7\xd2Ml:~H\xfcU\xcdn\x95\xd3\xed,z\x15M\xaa\xbal\x1e\x14U}![\xbe\xa6\x9e\xc7\xfc$\xd2\x96T\x94\x1b\xcb\x93(\xc5\xe5u:\x80\x92\x19\x8c\xdb\x97t\xb1\x02\xc4E\x94\xc5\x07n\xd9\xf7\xa3\x02\xd5\xea\xac\xb4\x08.4\xfc\x01\xdc\xffv\xf9\xdb)\xb8\x8c\xe4ae\xe8\x13a\xe8*\xfeVl\x03\xe8\x7fW\x85 \xc5\xa4{\xf9\xad$\xa4\x82\xea\xe4\xd1\xea\xba\x16N\x0d\x80\xcb\xe9N`f\xfe\x04\xfa\xc5\x94.\xa8\x12TQ \xba\x10\xe0\xbf\x02\x00\x00\xff\xffPK\x07\x08+\x96\x8a\xd7X(\x00\x00\xf2\x83\x01\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xd4`4t\xc7\x01\x00\x00\xbd\x01\x00\x00\x11\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00favicon-16x16.pngUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(6B\xc8\xd7\x7f\x04\x00\x00u\x04\x00\x00\x11\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x0f\x02\x00\x00favicon-32x32.pngUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xb9\xb1\xf1mT\x02\x00\x008\x05\x00\x00\n\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd6\x06\x00\x00index.htmlUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(]\x12r 9\x03\x00\x00T \x00\x00\x14\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81k \x00\x00oauth2-redirect.htmlUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(-\xe3\xb5\x97=9\x05\x00\xf7\x0c\x1b\x00\x14\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xef\x0c\x00\x00swagger-ui-bundle.jsUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(v\xf2\x8aA\x86\xba\x01\x00\xc5\x87\x08\x00\x1f\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81wF\x05\x00swagger-ui-standalone-preset.jsUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(_;\x94/\xe8Y\x00\x00\xa8X\x02\x00\x0e\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81S\x01\x07\x00swagger-ui.cssUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(+\x96\x8a\xd7X(\x00\x00\xf2\x83\x01\x00\x0c\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x80[\x07\x00swagger.yamlUT\x05\x00\x01\x80Cm8PK\x05\x06\x00\x00\x00\x00\x08\x00\x08\x00E\x02\x00\x00\x1b\x84\x07\x00\x00\x00" fs.Register(data) } diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 23298942e0d3..1f0230591e2e 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -21,6 +21,8 @@ tags: description: Slashing module APIs - name: Distribution description: Fee distribution module APIs + - name: IBC + description: IBC module APIs - name: Supply description: Supply module APIs - name: version @@ -1876,6 +1878,931 @@ paths: type: string 500: description: Internal Server Error + /ibc/clients/{client-id}/consensus-state: + get: + summary: Query cliet consensus-state + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + type: object + properties: + consensus_state: + $ref: "#/definitions/ConsensusState" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/clients/{client-id}/client-state: + get: + summary: Query client state + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + type: object + properties: + client_state: + $ref: "#/definitions/ClientState" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/clients/{client-id}/roots/{height}: + get: + summary: Query client root + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: path + name: height + description: Root height + required: true + type: number + x-example: 1 + - in: query + name: prove + description: Proof of result + type: boolean + x-example: true + responses: + 200: + description: OK + schema: + type: object + properties: + root: + $ref: "#/definitions/Root" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + 400: + description: Invalid client id or height + 500: + description: Internal Server Error + /ibc/header: + get: + summary: Query header + tags: + - IBC + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/Header" + 500: + description: Internal Server Error + /ibc/node-state: + get: + summary: Query node consensus-state + tags: + - IBC + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/ConsensusState" + 500: + description: Internal Server Error + /ibc/path: + get: + summary: Query IBC path + tags: + - IBC + produces: + - application/json + responses: + 200: + description: OK + schema: + type: string + 500: + description: Internal Server Error + /ibc/clients: + post: + summary: Create client + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Create client request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + client_id: + type: string + consensus_state: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/ConsensusState" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/clients/{client-id}/update: + post: + summary: Update client + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: body + name: "Update client request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + header: + $ref: "#/definitions/Header" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/clients/{client-id}/misbehaviour: + post: + summary: Submit misbehaviour + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: body + name: "Submit misbehaviour request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + evidence: + $ref: "#/definitions/Evidence" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/connections/{connection-id}: + get: + summary: Query connection + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: connection-id + description: Connection ID + required: true + type: string + x-example: ibcconnectionid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + $ref: "#/definitions/ConnectionResponse" + 400: + description: Invalid connection id + 500: + description: Internal Server Error + /ibc/clients/{client-id}/connections: + get: + summary: Query connections of a client + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + $ref: "#/definitions/ClientConnectionsResponse" + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/connections/open-init: + post: + summary: Connection open-init + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Connection open-init request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + connection_id: + type: string + client_id: + type: string + counterparty_client_id: + type: string + counterparty_connection_id: + type: string + counterparty_prefix: + $ref: "#/definitions/Prefix" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/connections/open-try: + post: + summary: Connection open-try + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Connection open-try request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + connection_id: + type: string + client_id: + type: string + counterparty_client_id: + type: string + counterparty_connection_id: + type: string + counterparty_prefix: + $ref: "#/definitions/Prefix" + counterparty_versions: + type: array + items: + type: string + proof_init: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_consensus: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + consensus_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/connections/{connection-id}/open-ack: + post: + summary: Connection open-ack + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: connection-id + description: Connection ID + required: true + type: string + x-example: ibcconnectionid + - in: body + name: "Connection open-ack request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + proof_try: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_consensus: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + consensus_height: + type: integer + version: + type: string + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid connection id + 500: + description: Internal Server Error + /ibc/connections/{connection-id}/open-confirm: + post: + summary: Connection open-confirm + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: connection-id + description: Connection ID + required: true + type: string + x-example: ibcconnectionid + - in: body + name: "Connection open-confirm request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + proof_ack: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid connection id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}: + get: + summary: Query channel + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + $ref: "#/definitions/ChannelResponse" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/channels/open-init: + post: + summary: Channel open-init + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Channel open-init request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + port_id: + type: string + channel_id: + type: string + version: + type: string + channel_order: + type: string + connection_hops: + type: array + items: + type: string + counterparty_port_id: + type: string + counterparty_channel_id: + type: string + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/channels/open-try: + post: + summary: Channel open-try + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Channel open-try request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + port_id: + type: string + channel_id: + type: string + version: + type: string + channel_order: + type: string + connection_hops: + type: array + items: + type: string + counterparty_port_id: + type: string + counterparty_channel_id: + type: string + counterparty_version: + type: string + proof_init: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/open-ack: + post: + summary: Channel open-ack + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Channel open-ack request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + counterparty_version: + type: string + proof_try: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/open-confirm: + post: + summary: Channel open-confirm + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Channel open-confirm request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + proof_ack: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/close-init: + post: + summary: Channel close-init + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Channel close-init request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/close-confirm: + post: + summary: Channel close-confirm + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Channel close-confirm request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + proof_init: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/next-sequence-recv: + get: + summary: Query next sequence receive + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + responses: + 200: + description: OK + schema: + type: integer + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/transfer: + post: + summary: Transfer token + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Transfer token request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + amount: + type: array + items: + $ref: "#/definitions/Coin" + receiver: + type: string + source: + type: boolean + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/packets/receive: + post: + summary: Receive packet + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Receive packet request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + packet: + $ref: "#/definitions/Packet" + proofs: + type: array + items: + $ref: "#/definitions/Proof" + height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error /supply/total: get: summary: Total supply of coins in the chain @@ -1908,7 +2835,7 @@ paths: 200: description: OK schema: - type: string + type: string 400: description: Invalid coin denomination 500: @@ -2530,3 +3457,273 @@ definitions: type: array items: $ref: "#/definitions/Coin" + IBCValidator: + type: object + properties: + address: + $ref: "#/definitions/ValidatorAddress" + pub_key: + type: object + properties: + type: + type: string + value: + type: string + voting_power: + type: string + example: "1000" + proposer_priority: + type: string + example: "1000" + ConsensusState: + type: object + properties: + chain_id: + type: string + height: + type: integer + root: + $ref: "#/definitions/Root" + next_validator_set: + $ref: "#/definitions/ValidatorSet" + Root: + type: object + properties: + type: + type: string + value: + type: object + properties: + hash: + type: string + Prefix: + type: object + properties: + type: + type: string + value: + type: object + properties: + key_prefix: + type: string + ValidatorSet: + type: object + properties: + validators: + type: array + items: + $ref: "#/definitions/IBCValidator" + proposer: + $ref: "#/definitions/IBCValidator" + ClientState: + type: object + properties: + id: + type: string + frozen: + type: boolean + Proof: + type: object + properties: + proof: + type: object + properties: + ops: + type: array + items: + type: object + properties: + type: + type: string + key: + type: string + data: + type: string + Commit: + type: object + properties: + block_id: + $ref: "#/definitions/BlockID" + precommits: + type: array + items: + type: object + properties: + validator_address: + type: string + validator_index: + type: string + example: "0" + height: + type: string + example: "0" + round: + type: string + example: "0" + timestamp: + type: string + example: "2017-12-30T05:53:09.287+01:00" + type: + type: number + example: 2 + block_id: + $ref: "#/definitions/BlockID" + signature: + type: string + example: "7uTC74QlknqYWEwg7Vn6M8Om7FuZ0EO4bjvuj6rwH1mTUJrRuMMZvAAqT9VjNgP0RA/TDp6u/92AqrZfXJSpBQ==" + SignedHeader: + type: object + properties: + header: + $ref: "#/definitions/BlockHeader" + commit: + $ref: "#/definitions/Commit" + Header: + type: object + properties: + type: + type: string + value: + type: object + properties: + SignedHeader: + $ref: "#/definitions/SignedHeader" + validator_set: + $ref: "#/definitions/ValidatorSet" + next_validator_set: + $ref: "#/definitions/ValidatorSet" + ConnectionResponse: + type: object + properties: + connection: + $ref: "#/definitions/Connection" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + Connection: + type: object + properties: + state: + type: string + client_id: + type: string + counterparty: + $ref: "#/definitions/ConnectionCounterparty" + versions: + type: array + items: + type: string + ConnectionCounterparty: + type: object + properties: + client_id: + type: string + connection_id: + type: string + prefix: + type: object + properties: + key_prefix: + type: string + ProofPath: + type: object + properties: + key_path: + type: array + items: + type: object + properties: + name: + type: string + enc: + type: integer + ClientConnectionsResponse: + type: object + properties: + connection_paths: + type: array + items: + type: string + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + ChannelResponse: + type: object + properties: + channel: + $ref: "#/definitions/Channel" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + Channel: + type: object + properties: + state: + type: string + ordering: + type: string + counterparty: + $ref: "#/definitions/Counterparty" + connection_hops: + type: array + items: + type: string + version: + type: string + ChannelCounterparty: + type: object + properties: + port_id: + type: string + channel_id: + type: string + Packet: + type: object + properties: + type: + type: string + value: + type: object + properties: + sequence: + type: integer + timeout: + type: integer + source_port: + type: string + source_channel: + type: string + destination_port: + type: string + destination_channel: + type: string + data: + type: string + # TODO: DuplicateVoteEvidence + DuplicateVoteEvidence: + type: string + Evidence: + type: object + properties: + type: + type: string + value: + type: object + properties: + DuplicateVoteEvidence: + $ref: "#/definitions/DuplicateVoteEvidence" + chain_id: + type: string + val_power: + type: integer + total_power: + type: integer diff --git a/types/rest/rest.go b/types/rest/rest.go index 89770c944650..5414b23abab1 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -375,3 +375,14 @@ func ParseHTTPArgsWithLimit(r *http.Request, defaultLimit int) (tags []string, p func ParseHTTPArgs(r *http.Request) (tags []string, page, limit int, err error) { return ParseHTTPArgsWithLimit(r, DefaultLimit) } + +// ParseQueryProve sets the prove to execute a query if set by the http request. +// It returns false if there was an error parsing the prove. +func ParseQueryProve(r *http.Request) bool { + proveStr := r.FormValue("prove") + prove := false + if ok, err := strconv.ParseBool(proveStr); err == nil { + prove = ok + } + return prove +} diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go new file mode 100644 index 000000000000..d8b77d658c0b --- /dev/null +++ b/x/ibc/02-client/client/rest/query.go @@ -0,0 +1,248 @@ +package rest + +import ( + "fmt" + "net/http" + "strconv" + + "github.com/gorilla/mux" + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc("/ibc/header", queryHeaderHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc("/ibc/node-state", queryNodeConsensusStateHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc("/ibc/path", queryPathHandlerFn(cliCtx)).Methods("GET") +} + +// queryConsensusStateHandlerFn implements a consensus state querying route +// +// @Summary Query cliet consensus-state +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryConsensusState "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/consensus-state [get] +func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyConsensusState(clientID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var cs tendermint.ConsensusState + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + } + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height)) + } +} + +// queryHeaderHandlerFn implements a header querying route +// +// @Summary Query header +// @Tags IBC +// @Produce json +// @Success 200 {object} QueryHeader "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/header [get] +func queryHeaderHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + header, err := utils.GetTendermintHeader(cliCtx) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + rest.PostProcessResponse(w, cliCtx, header) + } +} + +// queryClientStateHandlerFn implements a client state querying route +// +// @Summary Query client state +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryClientState "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/client-state [get] +func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyClientState(clientID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var state types.State + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &state); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + } + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewClientStateResponse(clientID, state, res.Proof, res.Height)) + } +} + +// queryRootHandlerFn implements a root querying route +// +// @Summary Query client root +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param height path number true "Root height" +// @Success 200 {object} QueryRoot "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/roots/{height} [get] +func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + height, err := strconv.ParseUint(vars[RestRootHeight], 10, 64) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyRoot(clientID, height), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var root commitment.Root + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &root); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewRootResponse(clientID, height, root, res.Proof, res.Height)) + } +} + +// queryNodeConsensusStateHandlerFn implements a node consensus state querying route +// +// @Summary Query node consensus-state +// @Tags IBC +// @Produce json +// @Success 200 {object} QueryNodeConsensusState "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/node-state [get] +func queryNodeConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + node, err := cliCtx.GetNode() + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + info, err := node.ABCIInfo() + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + height := info.Response.LastBlockHeight + prevHeight := height - 1 + + commit, err := node.Commit(&height) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + validators, err := node.Validators(&prevHeight) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + state := tendermint.ConsensusState{ + ChainID: commit.ChainID, + Height: uint64(commit.Height), + Root: commitment.NewRoot(commit.AppHash), + NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), + } + + res := cliCtx.Codec.MustMarshalJSON(state) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) + } +} + +// queryPathHandlerFn implements a node consensus path querying route +// +// @Summary Query IBC path +// @Tags IBC +// @Produce json +// @Success 200 {object} QueryPath "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/path [get] +func queryPathHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + path := commitment.NewPrefix([]byte("ibc")) + res := cliCtx.Codec.MustMarshalJSON(path) + rest.PostProcessResponse(w, cliCtx, res) + } +} diff --git a/x/ibc/02-client/client/rest/rest.go b/x/ibc/02-client/client/rest/rest.go new file mode 100644 index 000000000000..fb832f63a69a --- /dev/null +++ b/x/ibc/02-client/client/rest/rest.go @@ -0,0 +1,39 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" +) + +const ( + RestClientID = "client-id" + RestRootHeight = "height" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + registerQueryRoutes(cliCtx, r, queryRoute) + registerTxRoutes(cliCtx, r) +} + +// CreateClientReq defines the properties of a create client request's body. +type CreateClientReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ClientID string `json:"client_id" yaml:"client_id"` + ConsensusState exported.ConsensusState `json:"consensus_state" yaml:"consensus_state"` +} + +// UpdateClientReq defines the properties of a update client request's body. +type UpdateClientReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Header exported.Header `json:"header" yaml:"header"` +} + +// SubmitMisbehaviourReq defines the properties of a submit misbehaviour request's body. +type SubmitMisbehaviourReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Evidence exported.Evidence `json:"evidence" yaml:"evidence"` +} diff --git a/x/ibc/02-client/client/rest/swagger.go b/x/ibc/02-client/client/rest/swagger.go new file mode 100644 index 000000000000..b3f64c566e72 --- /dev/null +++ b/x/ibc/02-client/client/rest/swagger.go @@ -0,0 +1,61 @@ +package rest + +import ( + auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +type ( + QueryConsensusState struct { + Height int64 `json:"height"` + Result types.ConsensusStateResponse `json:"result"` + } + + QueryHeader struct { + Height int64 `json:"height"` + Result tendermint.Header `json:"result"` + } + + QueryClientState struct { + Height int64 `json:"height"` + Result types.StateResponse `json:"result"` + } + + QueryRoot struct { + Height int64 `json:"height"` + Result types.RootResponse `json:"result"` + } + + QueryNodeConsensusState struct { + Height int64 `json:"height"` + Result tendermint.ConsensusState `json:"result"` + } + + QueryPath struct { + Height int64 `json:"height"` + Result commitment.Prefix `json:"result"` + } + + PostCreateClient struct { + Msgs []types.MsgCreateClient `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostUpdateClient struct { + Msgs []types.MsgUpdateClient `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostSubmitMisbehaviour struct { + Msgs []types.MsgSubmitMisbehaviour `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } +) diff --git a/x/ibc/02-client/client/rest/tx.go b/x/ibc/02-client/client/rest/tx.go new file mode 100644 index 000000000000..50f9a38b022f --- /dev/null +++ b/x/ibc/02-client/client/rest/tx.go @@ -0,0 +1,164 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc("/ibc/clients", createClientHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/update", RestClientID), updateClientHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/misbehaviour", RestClientID), submitMisbehaviourHandlerFn(cliCtx)).Methods("POST") +} + +// createClientHandlerFn implements a create client handler +// +// @Summary Create client +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.CreateClientReq true "Create client request body" +// @Success 200 {object} PostCreateClient "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients [post] +func createClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req CreateClientReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgCreateClient( + req.ClientID, + req.ConsensusState.ClientType().String(), + req.ConsensusState, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// updateClientHandlerFn implements a update client handler +// +// @Summary update client +// @Tags IBC +// @Accept json +// @Produce json +// @Param client-id path string true "Client ID" +// @Param body body rest.UpdateClientReq true "Update client request body" +// @Success 200 {object} PostUpdateClient "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/update [post] +func updateClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + var req UpdateClientReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgUpdateClient( + clientID, + req.Header, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// submitMisbehaviourHandlerFn implements a submit misbehaviour handler +// +// @Summary Submit misbehaviour +// @Tags IBC +// @Accept json +// @Produce json +// @Param client-id path string true "Client ID" +// @Param body body rest.SubmitMisbehaviourReq true "Submit misbehaviour request body" +// @Success 200 {object} PostSubmitMisbehaviour "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/misbehaviour [post] +func submitMisbehaviourHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + var req SubmitMisbehaviourReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgSubmitMisbehaviour( + clientID, + req.Evidence, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/02-client/module.go b/x/ibc/02-client/module.go index 3df05cdfbdf2..9e5ddbd7dbd5 100644 --- a/x/ibc/02-client/module.go +++ b/x/ibc/02-client/module.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/rest" ) // Name returns the IBC client name @@ -17,8 +18,8 @@ func Name() string { } // RegisterRESTRoutes registers the REST routes for the IBC client -func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { - // TODO: +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router, queryRoute string) { + rest.RegisterRoutes(ctx, rtr, fmt.Sprintf("%s/%s", queryRoute, SubModuleName)) } // GetTxCmd returns the root tx command for the IBC client diff --git a/x/ibc/03-connection/client/rest/query.go b/x/ibc/03-connection/client/rest/query.go new file mode 100644 index 000000000000..f40bbfd2eba6 --- /dev/null +++ b/x/ibc/03-connection/client/rest/query.go @@ -0,0 +1,102 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + r.HandleFunc(fmt.Sprintf("/ibc/connections/{%s}", RestConnectionID), queryConnectionHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/connections", RestClientID), queryClientConnectionsHandlerFn(cliCtx, queryRoute)).Methods("GET") +} + +// queryConnectionHandlerFn implements a connection querying route +// +// @Summary Query connection +// @Tags IBC +// @Produce json +// @Param connection-id path string true "Client ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryConnection "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid connection id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/{connection-id} [get] +func queryConnectionHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + connectionID := vars[RestConnectionID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyConnection(connectionID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var connection types.ConnectionEnd + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + } + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height)) + } +} + +// queryClientConnectionsHandlerFn implements a client connections querying route +// +// @Summary Query connections of a client +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryClientConnections "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/connections [get] +func queryClientConnectionsHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyClientConnections(clientID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var paths []string + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &paths); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + } + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewClientConnectionsResponse(clientID, paths, res.Proof, res.Height)) + } +} diff --git a/x/ibc/03-connection/client/rest/rest.go b/x/ibc/03-connection/client/rest/rest.go new file mode 100644 index 000000000000..ed8e97b69280 --- /dev/null +++ b/x/ibc/03-connection/client/rest/rest.go @@ -0,0 +1,62 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +const ( + RestConnectionID = "connection-id" + RestClientID = "client-id" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + registerQueryRoutes(cliCtx, r, queryRoute) + registerTxRoutes(cliCtx, r) +} + +// ConnectionOpenInitReq defines the properties of a connection open init request's body. +type ConnectionOpenInitReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ConnectionID string `json:"connection_id" yaml:"connection_id"` + ClientID string `json:"client_id" yaml:"client_id"` + CounterpartyClientID string `json:"counterparty_client_id" yaml:"counterparty_client_id"` + CounterpartyConnectionID string `json:"counterparty_connection_id" yaml:"counterparty_connection_id"` + CounterpartyPrefix commitment.PrefixI `json:"counterparty_prefix" yaml:"counterparty_prefix"` +} + +// ConnectionOpenTryReq defines the properties of a connection open try request's body. +type ConnectionOpenTryReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ConnectionID string `json:"connection_id" yaml:"connection_id"` + ClientID string `json:"client_id" yaml:"client_id"` + CounterpartyClientID string `json:"counterparty_client_id" yaml:"counterparty_client_id"` + CounterpartyConnectionID string `json:"counterparty_connection_id" yaml:"counterparty_connection_id"` + CounterpartyPrefix commitment.PrefixI `json:"counterparty_prefix" yaml:"counterparty_prefix"` + CounterpartyVersions []string `json:"counterparty_versions" yaml:"counterparty_versions"` + ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` + ProofConsensus commitment.ProofI `json:"proof_consensus" yaml:"proof_consensus"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` +} + +// ConnectionOpenAckReq defines the properties of a connection open ack request's body. +type ConnectionOpenAckReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofTry commitment.ProofI `json:"proof_try" yaml:"proof_try"` + ProofConsensus commitment.ProofI `json:"proof_consensus" yaml:"proof_consensus"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` + Version string `json:"version" yaml:"version"` +} + +// ConnectionOpenConfirmReq defines the properties of a connection open confirm request's body. +type ConnectionOpenConfirmReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} diff --git a/x/ibc/03-connection/client/rest/swagger.go b/x/ibc/03-connection/client/rest/swagger.go new file mode 100644 index 000000000000..c8620ba41d6a --- /dev/null +++ b/x/ibc/03-connection/client/rest/swagger.go @@ -0,0 +1,46 @@ +package rest + +import ( + auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +type ( + QueryConnection struct { + Height int64 `json:"height"` + Result types.ConnectionResponse `json:"result"` + } + + QueryClientConnections struct { + Height int64 `json:"height"` + Result types.ClientConnectionsResponse `json:"result"` + } + + PostConnectionOpenInit struct { + Msgs []types.MsgConnectionOpenInit `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostConnectionOpenTry struct { + Msgs []types.MsgConnectionOpenTry `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostConnectionOpenAck struct { + Msgs []types.MsgConnectionOpenAck `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostConnectionOpenConfirm struct { + Msgs []types.MsgConnectionOpenConfirm `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } +) diff --git a/x/ibc/03-connection/client/rest/tx.go b/x/ibc/03-connection/client/rest/tx.go new file mode 100644 index 000000000000..f11abbccb111 --- /dev/null +++ b/x/ibc/03-connection/client/rest/tx.go @@ -0,0 +1,204 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc("/ibc/connections/open-init", connectionOpenInitHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc("/ibc/connections/open-try", connectionOpenTryHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/connections/{%s}/open-ack", RestConnectionID), connectionOpenAckHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/connections/{%s}/open-confirm", RestConnectionID), connectionOpenConfirmHandlerFn(cliCtx)).Methods("POST") +} + +// connectionOpenInitHandlerFn implements a connection open init handler +// +// @Summary Connection open-init +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.ConnectionOpenInitReq true "Connection open-init request body" +// @Success 200 {object} PostConnectionOpenInit "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/open-init [post] +func connectionOpenInitHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req ConnectionOpenInitReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgConnectionOpenInit( + req.ConnectionID, req.ClientID, req.CounterpartyConnectionID, + req.CounterpartyClientID, req.CounterpartyPrefix, fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// connectionOpenTryHandlerFn implements a connection open try handler +// +// @Summary Connection open-try +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.ConnectionOpenTryReq true "Connection open-try request body" +// @Success 200 {object} PostConnectionOpenTry "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/open-try [post] +func connectionOpenTryHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req ConnectionOpenTryReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgConnectionOpenTry( + req.ConnectionID, req.ClientID, req.CounterpartyConnectionID, + req.CounterpartyClientID, req.CounterpartyPrefix, req.CounterpartyVersions, + req.ProofInit, req.ProofConsensus, req.ProofHeight, + req.ConsensusHeight, fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// connectionOpenAckHandlerFn implements a connection open ack handler +// +// @Summary Connection open-ack +// @Tags IBC +// @Accept json +// @Produce json +// @Param connection-id path string true "Connection ID" +// @Param body body rest.ConnectionOpenAckReq true "Connection open-ack request body" +// @Success 200 {object} PostConnectionOpenAck "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid connection id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/{connection-id}/open-ack [post] +func connectionOpenAckHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + connectionID := vars[RestConnectionID] + + var req ConnectionOpenAckReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgConnectionOpenAck( + connectionID, req.ProofTry, req.ProofConsensus, req.ProofHeight, + req.ConsensusHeight, req.Version, fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// connectionOpenConfirmHandlerFn implements a connection open confirm handler +// +// @Summary Connection open-confirm +// @Tags IBC +// @Accept json +// @Produce json +// @Param connection-id path string true "Connection ID" +// @Param body body rest.ConnectionOpenConfirmReq true "Connection open-confirm request body" +// @Success 200 {object} PostConnectionOpenConfirm "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid connection id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/{connection-id}/open-confirm [post] +func connectionOpenConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + connectionID := vars[RestConnectionID] + + var req ConnectionOpenConfirmReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgConnectionOpenConfirm( + connectionID, req.ProofAck, req.ProofHeight, fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/03-connection/module.go b/x/ibc/03-connection/module.go index 713ed04d6c6b..d4d7d931c97b 100644 --- a/x/ibc/03-connection/module.go +++ b/x/ibc/03-connection/module.go @@ -3,10 +3,13 @@ package connection import ( "fmt" + "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/rest" ) // Name returns the IBC connection ICS name @@ -23,3 +26,8 @@ func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { return cli.GetQueryCmd(fmt.Sprintf("%s/%s", queryRoute, SubModuleName), cdc) } + +// RegisterRESTRoutes registers the REST routes for the IBC connections. +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router, queryRoute string) { + rest.RegisterRoutes(ctx, rtr, fmt.Sprintf("%s/%s", queryRoute, SubModuleName)) +} diff --git a/x/ibc/04-channel/client/rest/query.go b/x/ibc/04-channel/client/rest/query.go new file mode 100644 index 000000000000..b1f6a0f93b63 --- /dev/null +++ b/x/ibc/04-channel/client/rest/query.go @@ -0,0 +1,63 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}", RestPortID, RestChannelID), queryChannelHandlerFn(cliCtx, queryRoute)).Methods("GET") +} + +// queryChannelHandlerFn implements a channel querying route +// +// @Summary Query channel +// @Tags IBC +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryChannel "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id} [get] +func queryChannelHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyChannel(portID, channelID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var channel types.Channel + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height)) + } +} diff --git a/x/ibc/04-channel/client/rest/rest.go b/x/ibc/04-channel/client/rest/rest.go new file mode 100644 index 000000000000..55cf81215f64 --- /dev/null +++ b/x/ibc/04-channel/client/rest/rest.go @@ -0,0 +1,75 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +const ( + RestChannelID = "channel-id" + RestPortID = "port-id" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + registerQueryRoutes(cliCtx, r, queryRoute) + registerTxRoutes(cliCtx, r) +} + +// ChannelOpenInitReq defines the properties of a channel open init request's body. +type ChannelOpenInitReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + PortID string `json:"port_id" yaml:"port_id"` + ChannelID string `json:"channel_id" yaml:"channel_id"` + Version string `json:"version" yaml:"version"` + ChannelOrder types.Order `json:"channel_order" yaml:"channel_order"` + ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` + CounterpartyPortID string `json:"counterparty_port_id" yaml:"counterparty_port_id"` + CounterpartyChannelID string `json:"counterparty_channel_id" yaml:"counterparty_channel_id"` +} + +// ChannelOpenTryReq defines the properties of a channel open try request's body. +type ChannelOpenTryReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + PortID string `json:"port_id" yaml:"port_id"` + ChannelID string `json:"channel_id" yaml:"channel_id"` + Version string `json:"version" yaml:"version"` + ChannelOrder types.Order `json:"channel_order" yaml:"channel_order"` + ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` + CounterpartyPortID string `json:"counterparty_port_id" yaml:"counterparty_port_id"` + CounterpartyChannelID string `json:"counterparty_channel_id" yaml:"counterparty_channel_id"` + CounterpartyVersion string `json:"counterparty_version" yaml:"counterparty_version"` + ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} + +// ChannelOpenAckReq defines the properties of a channel open ack request's body. +type ChannelOpenAckReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + CounterpartyVersion string `json:"counterparty_version" yaml:"counterparty_version"` + ProofTry commitment.ProofI `json:"proof_try" yaml:"proof_try"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} + +// ChannelOpenConfirmReq defines the properties of a channel open confirm request's body. +type ChannelOpenConfirmReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} + +// ConnectionOpenInitReq defines the properties of a channel close init request's body. +type ChannelCloseInitReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` +} + +// ChannelCloseConfirmReq defines the properties of a channel close confirm request's body. +type ChannelCloseConfirmReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} diff --git a/x/ibc/04-channel/client/rest/swagger.go b/x/ibc/04-channel/client/rest/swagger.go new file mode 100644 index 000000000000..608196f69921 --- /dev/null +++ b/x/ibc/04-channel/client/rest/swagger.go @@ -0,0 +1,55 @@ +package rest + +import ( + auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +type ( + QueryChannel struct { + Height int64 `json:"height"` + Result types.ChannelResponse `json:"result"` + } + + PostChannelOpenInit struct { + Msgs []types.MsgChannelOpenInit `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelOpenTry struct { + Msgs []types.MsgChannelOpenTry `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelOpenAck struct { + Msgs []types.MsgChannelOpenAck `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelOpenConfirm struct { + Msgs []types.MsgChannelOpenConfirm `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelCloseInit struct { + Msgs []types.MsgChannelCloseInit `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelCloseConfirm struct { + Msgs []types.MsgChannelCloseConfirm `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } +) diff --git a/x/ibc/04-channel/client/rest/tx.go b/x/ibc/04-channel/client/rest/tx.go new file mode 100644 index 000000000000..641a62bf20e2 --- /dev/null +++ b/x/ibc/04-channel/client/rest/tx.go @@ -0,0 +1,336 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc("/ibc/channels/open-init", channelOpenInitHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc("/ibc/channels/open-try", channelOpenTryHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/open-ack", RestPortID, RestChannelID), channelOpenAckHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/open-confirm", RestPortID, RestChannelID), channelOpenConfirmHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/close-init", RestPortID, RestChannelID), channelCloseInitHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/close-confirm", RestPortID, RestChannelID), channelCloseConfirmHandlerFn(cliCtx)).Methods("POST") +} + +// channelOpenInitHandlerFn implements a channel open init handler +// +// @Summary Channel open-init +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.ChannelOpenInitReq true "Channel open-init request body" +// @Success 200 {object} PostChannelOpenInit "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/channels/open-init [post] +func channelOpenInitHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req ChannelOpenInitReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelOpenInit( + req.PortID, + req.ChannelID, + req.Version, + req.ChannelOrder, + req.ConnectionHops, + req.CounterpartyPortID, + req.CounterpartyChannelID, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelOpenTryHandlerFn implements a channel open try handler +// +// @Summary Channel open-try +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.ChannelOpenTryReq true "Channel open-try request body" +// @Success 200 {object} PostChannelOpenTry "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/channels/open-try [post] +func channelOpenTryHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req ChannelOpenTryReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelOpenTry( + req.PortID, + req.ChannelID, + req.Version, + req.ChannelOrder, + req.ConnectionHops, + req.CounterpartyPortID, + req.CounterpartyChannelID, + req.CounterpartyVersion, + req.ProofInit, + req.ProofHeight, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelOpenAckHandlerFn implements a channel open ack handler +// +// @Summary Channel open-ack +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.ChannelOpenAckReq true "Channel open-ack request body" +// @Success 200 {object} PostChannelOpenAck "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/open-ack [post] +func channelOpenAckHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req ChannelOpenAckReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelOpenAck( + portID, + channelID, + req.CounterpartyVersion, + req.ProofTry, + req.ProofHeight, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelOpenConfirmHandlerFn implements a channel open confirm handler +// +// @Summary Channel open-confirm +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.ChannelOpenConfirmReq true "Channel open-confirm request body" +// @Success 200 {object} PostChannelOpenConfirm "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/open-confirm [post] +func channelOpenConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req ChannelOpenConfirmReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelOpenConfirm( + portID, + channelID, + req.ProofAck, + req.ProofHeight, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelCloseInitHandlerFn implements a channel close init handler +// +// @Summary Channel close-init +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.ChannelCloseInitReq true "Channel close-init request body" +// @Success 200 {object} PostChannelCloseInit "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/close-init [post] +func channelCloseInitHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req ChannelCloseInitReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelCloseInit( + portID, + channelID, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelCloseConfirmHandlerFn implements a channel close confirm handler +// +// @Summary Channel close-confirm +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.ChannelCloseConfirmReq true "Channel close-confirm request body" +// @Success 200 {object} PostChannelCloseConfirm "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/close-confirm [post] +func channelCloseConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req ChannelCloseConfirmReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelCloseConfirm( + portID, + channelID, + req.ProofInit, + req.ProofHeight, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/04-channel/module.go b/x/ibc/04-channel/module.go index 4f9b17b03144..7fb21535e948 100644 --- a/x/ibc/04-channel/module.go +++ b/x/ibc/04-channel/module.go @@ -3,10 +3,13 @@ package channel import ( "fmt" + "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/rest" ) // Name returns the IBC connection ICS name @@ -14,6 +17,11 @@ func Name() string { return SubModuleName } +// RegisterRESTRoutes registers the REST routes for the IBC channel +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router, queryRoute string) { + rest.RegisterRoutes(ctx, rtr, fmt.Sprintf("%s/%s", queryRoute, SubModuleName)) +} + // GetTxCmd returns the root tx command for the IBC connections. func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { return cli.GetTxCmd(fmt.Sprintf("%s/%s", storeKey, SubModuleName), cdc) diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index 6f69c5d6ea86..16a7a1943999 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -46,10 +46,10 @@ func (msg MsgChannelOpenInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenInit) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } // Signer can be empty @@ -109,10 +109,10 @@ func (msg MsgChannelOpenTry) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenTry) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if strings.TrimSpace(msg.CounterpartyVersion) == "" { @@ -176,10 +176,10 @@ func (msg MsgChannelOpenAck) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenAck) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if strings.TrimSpace(msg.CounterpartyVersion) == "" { @@ -241,10 +241,10 @@ func (msg MsgChannelOpenConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenConfirm) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if msg.ProofAck == nil { @@ -296,10 +296,10 @@ func (msg MsgChannelCloseInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelCloseInit) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } // Signer can be empty diff --git a/x/ibc/20-transfer/client/rest/query.go b/x/ibc/20-transfer/client/rest/query.go new file mode 100644 index 000000000000..8e979152a768 --- /dev/null +++ b/x/ibc/20-transfer/client/rest/query.go @@ -0,0 +1,60 @@ +package rest + +import ( + "encoding/binary" + "fmt" + "net/http" + + "github.com/gorilla/mux" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" +) + +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/next-sequence-recv", RestPortID, RestChannelID), queryNextSequenceRecvHandlerFn(cliCtx)).Methods("GET") +} + +// queryNextSequenceRecvHandlerFn implements a next sequence receive querying route +// +// @Summary Query next sequence receive +// @Tags IBC +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Success 200 {object} QueryNextSequenceRecv "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/next-sequence-recv [get] +func queryNextSequenceRecvHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: channel.KeyNextSequenceRecv(portID, channelID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + sequence := binary.BigEndian.Uint64(res.Value) + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, sequence) + } +} diff --git a/x/ibc/20-transfer/client/rest/rest.go b/x/ibc/20-transfer/client/rest/rest.go new file mode 100644 index 000000000000..a43112f0cce3 --- /dev/null +++ b/x/ibc/20-transfer/client/rest/rest.go @@ -0,0 +1,38 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +const ( + RestChannelID = "channel-id" + RestPortID = "port-id" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) { + registerQueryRoutes(cliCtx, r) + registerTxRoutes(cliCtx, r) +} + +// TransferTxReq defines the properties of a transfer tx request's body. +type TransferTxReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Amount sdk.Coins `json:"amount" yaml:"amount"` + Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` + Source bool `json:"source" yaml:"source"` +} + +// RecvPacketReq defines the properties of a receive packet request's body. +type RecvPacketReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Packet channelexported.PacketI `json:"packet" yaml:"packet"` + Proofs []commitment.Proof `json:"proofs" yaml:"proofs"` + Height uint64 `json:"height" yaml:"height"` +} diff --git a/x/ibc/20-transfer/client/rest/swagger.go b/x/ibc/20-transfer/client/rest/swagger.go new file mode 100644 index 000000000000..c36f5d9e9822 --- /dev/null +++ b/x/ibc/20-transfer/client/rest/swagger.go @@ -0,0 +1,27 @@ +package rest + +import ( + auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +type ( + QueryNextSequenceRecv struct { + Height int64 `json:"height"` + Result uint64 `json:"result"` + } + + PostTransfer struct { + Msgs []types.MsgTransfer `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostRecvPacket struct { + Msgs []types.MsgRecvPacket `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } +) diff --git a/x/ibc/20-transfer/client/rest/tx.go b/x/ibc/20-transfer/client/rest/tx.go new file mode 100644 index 000000000000..de699c04e969 --- /dev/null +++ b/x/ibc/20-transfer/client/rest/tx.go @@ -0,0 +1,118 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/transfer", RestPortID, RestChannelID), transferHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/packets/receive"), recvPacketHandlerFn(cliCtx)).Methods("POST") +} + +// transferHandlerFn implements a transfer handler +// +// @Summary Transfer token +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.TransferTxReq true "Transfer token request body" +// @Success 200 {object} PostTransfer "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/transfer [post] +func transferHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req TransferTxReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgTransfer( + portID, + channelID, + req.Amount, + fromAddr, + req.Receiver, + req.Source, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// recvPacketHandlerFn implements a receive packet handler +// +// @Summary Receive packet +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.RecvPacketReq true "Receive packet request body" +// @Success 200 {object} PostRecvPacket "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/packets/receive [post] +func recvPacketHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req RecvPacketReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgRecvPacket( + req.Packet, + req.Proofs, + req.Height, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index a1e12ec35d8f..f29136061cde 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -1,10 +1,13 @@ package transfer import ( + "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/rest" ) // Name returns the IBC transfer ICS name @@ -12,6 +15,11 @@ func Name() string { return SubModuleName } +// RegisterRESTRoutes registers the REST routes for the IBC transfer +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { + rest.RegisterRoutes(ctx, rtr) +} + // GetTxCmd returns the root tx command for the IBC transfer. func GetTxCmd(cdc *codec.Codec) *cobra.Command { return cli.GetTxCmd(cdc) diff --git a/x/ibc/client/rest/rest.go b/x/ibc/client/rest/rest.go new file mode 100644 index 000000000000..f593ba135760 --- /dev/null +++ b/x/ibc/client/rest/rest.go @@ -0,0 +1,19 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + client.RegisterRESTRoutes(cliCtx, r, queryRoute) + connection.RegisterRESTRoutes(cliCtx, r, queryRoute) + channel.RegisterRESTRoutes(cliCtx, r, queryRoute) + transfer.RegisterRESTRoutes(cliCtx, r) +} diff --git a/x/ibc/module.go b/x/ibc/module.go index 2e91d5540df0..42da7343d6d6 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -18,6 +18,7 @@ import ( transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/client/rest" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -27,17 +28,17 @@ var ( _ module.AppModuleBasic = AppModuleBasic{} ) -// AppModuleBasic defines the basic application module used by the staking module. +// AppModuleBasic defines the basic application module used by the ibc module. type AppModuleBasic struct{} var _ module.AppModuleBasic = AppModuleBasic{} -// Name returns the staking module's name. +// Name returns the ibc module's name. func (AppModuleBasic) Name() string { return types.ModuleName } -// RegisterCodec registers the staking module's types for the given codec. +// RegisterCodec registers the ibc module's types for the given codec. func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) @@ -46,33 +47,33 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { commitment.RegisterCodec(cdc) } -// DefaultGenesis returns default genesis state as raw bytes for the staking +// DefaultGenesis returns default genesis state as raw bytes for the ibc // module. func (AppModuleBasic) DefaultGenesis() json.RawMessage { return nil } -// ValidateGenesis performs genesis state validation for the staking module. +// ValidateGenesis performs genesis state validation for the ibc module. func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { return nil } -// RegisterRESTRoutes registers the REST routes for the staking module. +// RegisterRESTRoutes registers the REST routes for the ibc module. func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { - /// TODO: + rest.RegisterRoutes(ctx, rtr, StoreKey) } -// GetTxCmd returns the root tx command for the staking module. +// GetTxCmd returns the root tx command for the ibc module. func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { return cli.GetTxCmd(StoreKey, cdc) } -// GetQueryCmd returns no root query command for the staking module. +// GetQueryCmd returns no root query command for the ibc module. func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { return cli.GetQueryCmd(QuerierRoute, cdc) } -// AppModule implements an application module for the staking module. +// AppModule implements an application module for the ibc module. type AppModule struct { AppModuleBasic keeper Keeper @@ -85,37 +86,37 @@ func NewAppModule(k Keeper) AppModule { } } -// Name returns the staking module's name. +// Name returns the ibc module's name. func (AppModule) Name() string { return ModuleName } -// RegisterInvariants registers the staking module invariants. +// RegisterInvariants registers the ibc module invariants. func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { // TODO: } -// Route returns the message routing key for the staking module. +// Route returns the message routing key for the ibc module. func (AppModule) Route() string { return RouterKey } -// NewHandler returns an sdk.Handler for the staking module. +// NewHandler returns an sdk.Handler for the ibc module. func (am AppModule) NewHandler() sdk.Handler { return NewHandler(am.keeper) } -// QuerierRoute returns the staking module's querier route name. +// QuerierRoute returns the ibc module's querier route name. func (AppModule) QuerierRoute() string { return QuerierRoute } -// NewQuerierHandler returns the staking module sdk.Querier. +// NewQuerierHandler returns the ibc module sdk.Querier. func (am AppModule) NewQuerierHandler() sdk.Querier { return NewQuerier(am.keeper) } -// InitGenesis performs genesis initialization for the staking module. It returns +// InitGenesis performs genesis initialization for the ibc module. It returns // no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { // check if the IBC transfer module account is set @@ -123,17 +124,17 @@ func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.Va return []abci.ValidatorUpdate{} } -// ExportGenesis returns the exported genesis state as raw bytes for the staking +// ExportGenesis returns the exported genesis state as raw bytes for the ibc // module. func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { return nil } -// BeginBlock returns the begin blocker for the staking module. +// BeginBlock returns the begin blocker for the ibc module. func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { } -// EndBlock returns the end blocker for the staking module. It returns no validator +// EndBlock returns the end blocker for the ibc module. It returns no validator // updates. func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} From e20e6878414bcefa014b8bc0bceb7000ec864e7c Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 2 Dec 2019 17:05:25 +0100 Subject: [PATCH 019/176] fix IBC proofs (#5351) * fix ICS02 proofs * fix ICS03 proofs * fix ICS04 proofs * fix ICS20 proofs * make format --- x/ibc/02-client/client/cli/cli.go | 45 ++++++ x/ibc/02-client/client/cli/query.go | 160 +++++----------------- x/ibc/02-client/client/cli/tx.go | 18 --- x/ibc/02-client/client/rest/query.go | 149 ++++++-------------- x/ibc/02-client/client/utils/utils.go | 126 +++++++++++++---- x/ibc/02-client/keeper/client_test.go | 5 +- x/ibc/03-connection/client/cli/cli.go | 41 ++++++ x/ibc/03-connection/client/cli/query.go | 66 ++------- x/ibc/03-connection/client/cli/tx.go | 30 +--- x/ibc/03-connection/client/rest/query.go | 37 ++--- x/ibc/03-connection/client/utils/utils.go | 59 ++++++++ x/ibc/04-channel/client/cli/cli.go | 43 ++++++ x/ibc/04-channel/client/cli/query.go | 30 ++-- x/ibc/04-channel/client/cli/tx.go | 109 +++++---------- x/ibc/04-channel/client/rest/query.go | 22 +-- x/ibc/04-channel/client/utils/utils.go | 32 ++--- x/ibc/04-channel/types/querier.go | 22 +++ x/ibc/05-port/keeper/keeper_test.go | 3 +- x/ibc/20-transfer/client/cli/cli.go | 37 +++++ x/ibc/20-transfer/client/cli/query.go | 36 +---- x/ibc/20-transfer/client/cli/tx.go | 22 +-- x/ibc/20-transfer/client/rest/query.go | 20 +-- x/ibc/20-transfer/client/utils/utils.go | 32 +++++ x/ibc/20-transfer/handler_test.go | 5 +- x/ibc/20-transfer/keeper/keeper_test.go | 7 +- x/ibc/20-transfer/keeper/relay_test.go | 3 +- x/ibc/20-transfer/types/msgs_test.go | 5 +- 27 files changed, 584 insertions(+), 580 deletions(-) create mode 100644 x/ibc/02-client/client/cli/cli.go create mode 100644 x/ibc/03-connection/client/cli/cli.go create mode 100644 x/ibc/03-connection/client/utils/utils.go create mode 100644 x/ibc/04-channel/client/cli/cli.go create mode 100644 x/ibc/20-transfer/client/cli/cli.go create mode 100644 x/ibc/20-transfer/client/utils/utils.go diff --git a/x/ibc/02-client/client/cli/cli.go b/x/ibc/02-client/client/cli/cli.go new file mode 100644 index 000000000000..ac182365a7ae --- /dev/null +++ b/x/ibc/02-client/client/cli/cli.go @@ -0,0 +1,45 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" +) + +// GetQueryCmd returns the query commands for IBC clients +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + ics02ClientQueryCmd := &cobra.Command{ + Use: "client", + Short: "IBC client query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics02ClientQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryClientState(queryRoute, cdc), + GetCmdQueryConsensusState(queryRoute, cdc), + GetCmdQueryRoot(queryRoute, cdc), + GetCmdQueryHeader(cdc), + GetCmdNodeConsensusState(queryRoute, cdc), + GetCmdQueryPath(queryRoute, cdc), + )...) + return ics02ClientQueryCmd +} + +// GetTxCmd returns the transaction commands for IBC clients +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics02ClientTxCmd := &cobra.Command{ + Use: "client", + Short: "Client transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics02ClientTxCmd.AddCommand(client.PostCommands( + GetCmdCreateClient(cdc), + GetCmdUpdateClient(cdc), + )...) + + return ics02ClientTxCmd +} diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index cc5cb3364c89..8bc6a755db4f 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -9,40 +9,14 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - tmtypes "github.com/tendermint/tendermint/types" - - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -// GetQueryCmd returns the query commands for IBC clients -func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { - ics02ClientQueryCmd := &cobra.Command{ - Use: "client", - Short: "IBC client query subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - } - - ics02ClientQueryCmd.AddCommand(client.GetCommands( - GetCmdQueryConsensusState(queryRoute, cdc), - GetCmdQueryHeader(cdc), - GetCmdQueryClientState(queryRoute, cdc), - GetCmdQueryRoot(queryRoute, cdc), - GetCmdNodeConsensusState(queryRoute, cdc), - GetCmdQueryPath(queryRoute, cdc), - )...) - return ics02ClientQueryCmd -} - // GetCmdQueryClientState defines the command to query the state of a client with // a given id as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query func GetCmdQueryClientState(queryRoute string, cdc *codec.Codec) *cobra.Command { @@ -64,28 +38,13 @@ $ %s query ibc client state [client-id] return errors.New("client ID can't be blank") } - bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) - if err != nil { - return err - } + prove := viper.GetBool(flags.FlagProve) - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), - } - - res, err := cliCtx.QueryABCI(req) + clientStateRes, err := utils.QueryClientState(cliCtx, clientID, prove) if err != nil { return err } - var clientState types.State - if err := cdc.UnmarshalJSON(res.Value, &clientState); err != nil { - return err - } - - clientStateRes := types.NewClientStateResponse(clientID, clientState, res.Proof, res.Height) return cliCtx.PrintOutput(clientStateRes) }, } @@ -93,19 +52,15 @@ $ %s query ibc client state [client-id] return cmd } -// GetCmdQueryRoot defines the command to query a verified commitment root -func GetCmdQueryRoot(queryRoute string, cdc *codec.Codec) *cobra.Command { +// GetCmdQueryConsensusState defines the command to query the consensus state of +// the chain as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query +func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "root [client-id] [height]", - Short: "Query a verified commitment root", - Long: strings.TrimSpace( - fmt.Sprintf(`Query an already verified commitment root at a specific height for a particular client - -Example: -$ %s query ibc client root [client-id] [height] -`, version.ClientName), - ), - Args: cobra.ExactArgs(2), + Use: "consensus-state [client-id]", + Short: "Query the latest consensus state of the client", + Long: "Query the consensus state for a particular light client", + Example: fmt.Sprintf("%s query ibc client consensus-state [client-id]", version.ClientName), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) clientID := args[0] @@ -113,54 +68,33 @@ $ %s query ibc client root [client-id] [height] return errors.New("client ID can't be blank") } - height, err := strconv.ParseUint(args[1], 10, 64) - if err != nil { - return fmt.Errorf("expected integer height, got: %v", args[1]) - } - - bz, err := cdc.MarshalJSON(types.NewQueryCommitmentRootParams(clientID, height)) - if err != nil { - return err - } - - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryVerifiedRoot), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), - } + prove := viper.GetBool(flags.FlagProve) - res, err := cliCtx.QueryABCI(req) + csRes, err := utils.QueryConsensusStateProof(cliCtx, clientID, prove) if err != nil { return err } - var root commitment.Root - if err := cdc.UnmarshalJSON(res.Value, &root); err != nil { - return err - } - - rootRes := types.NewRootResponse(clientID, height, root, res.Proof, res.Height) - return cliCtx.PrintOutput(rootRes) + return cliCtx.PrintOutput(csRes) }, } cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") return cmd } -// GetCmdQueryConsensusState defines the command to query the consensus state of -// the chain as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query -func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { +// GetCmdQueryRoot defines the command to query a verified commitment root +func GetCmdQueryRoot(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "consensus-state [client-id]", - Short: "Query the latest consensus state of the client", + Use: "root [client-id] [height]", + Short: "Query a verified commitment root", Long: strings.TrimSpace( - fmt.Sprintf(`Query the consensus state for a particular client + fmt.Sprintf(`Query an already verified commitment root at a specific height for a particular client Example: -$ %s query ibc client consensus-state [client-id] - `, version.ClientName), +$ %s query ibc client root [client-id] [height] +`, version.ClientName), ), - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) clientID := args[0] @@ -168,12 +102,19 @@ $ %s query ibc client consensus-state [client-id] return errors.New("client ID can't be blank") } - csRes, err := utils.QueryConsensusStateProof(cliCtx, cdc, queryRoute, clientID) + height, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return fmt.Errorf("expected integer height, got: %v", args[1]) + } + + prove := viper.GetBool(flags.FlagProve) + + rootRes, err := utils.QueryCommitmentRoot(cliCtx, clientID, height, prove) if err != nil { return err } - return cliCtx.PrintOutput(csRes) + return cliCtx.PrintOutput(rootRes) }, } cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") @@ -183,18 +124,14 @@ $ %s query ibc client consensus-state [client-id] // GetCmdQueryHeader defines the command to query the latest header on the chain func GetCmdQueryHeader(cdc *codec.Codec) *cobra.Command { return &cobra.Command{ - Use: "header", - Short: "Query the latest header of the running chain", - Long: strings.TrimSpace(fmt.Sprintf(`Query the latest Tendermint header - -Example: -$ %s query ibc client header - `, version.ClientName), - ), + Use: "header", + Short: "Query the latest header of the running chain", + Long: "Query the latest Tendermint header of the running chain", + Example: fmt.Sprintf("%s query ibc client header", version.ClientName), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) - header, err := utils.GetTendermintHeader(cliCtx) + header, _, err := utils.QueryTendermintHeader(cliCtx) if err != nil { return err } @@ -221,36 +158,11 @@ $ %s query ibc client node-state RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) - node, err := cliCtx.GetNode() - if err != nil { - return err - } - - info, err := node.ABCIInfo() - if err != nil { - return err - } - - height := info.Response.LastBlockHeight - prevHeight := height - 1 - - commit, err := node.Commit(&height) - if err != nil { - return err - } - - validators, err := node.Validators(&prevHeight) + state, _, err := utils.QueryNodeConsensusState(cliCtx) if err != nil { return err } - state := tendermint.ConsensusState{ - ChainID: commit.ChainID, - Height: uint64(commit.Height), - Root: commitment.NewRoot(commit.AppHash), - NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), - } - return cliCtx.PrintOutput(state) }, } diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 4cbc97b39842..2c8abcff4c95 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -8,7 +8,6 @@ import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" @@ -20,23 +19,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ) -// GetTxCmd returns the transaction commands for IBC Clients -func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { - ics02ClientTxCmd := &cobra.Command{ - Use: "client", - Short: "Client transaction subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - } - - ics02ClientTxCmd.AddCommand(client.PostCommands( - GetCmdCreateClient(cdc), - GetCmdUpdateClient(cdc), - )...) - - return ics02ClientTxCmd -} - // GetCmdCreateClient defines the command to create a new IBC Client as defined // in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create func GetCmdCreateClient(cdc *codec.Codec) *cobra.Command { diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go index d8b77d658c0b..bc135bebc1b8 100644 --- a/x/ibc/02-client/client/rest/query.go +++ b/x/ibc/02-client/client/rest/query.go @@ -6,129 +6,85 @@ import ( "strconv" "github.com/gorilla/mux" - abci "github.com/tendermint/tendermint/abci/types" - tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc("/ibc/header", queryHeaderHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/node-state", queryNodeConsensusStateHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/path", queryPathHandlerFn(cliCtx)).Methods("GET") } -// queryConsensusStateHandlerFn implements a consensus state querying route +// queryClientStateHandlerFn implements a client state querying route // -// @Summary Query cliet consensus-state +// @Summary Query client state // @Tags IBC // @Produce json // @Param client-id path string true "Client ID" // @Param prove query boolean false "Proof of result" -// @Success 200 {object} QueryConsensusState "OK" +// @Success 200 {object} QueryClientState "OK" // @Failure 400 {object} rest.ErrorResponse "Invalid client id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/clients/{client-id}/consensus-state [get] -func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +// @Router /ibc/clients/{client-id}/client-state [get] +func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyConsensusState(clientID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + clientStateRes, err := utils.QueryClientState(cliCtx, clientID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var cs tendermint.ConsensusState - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - } - - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(clientStateRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, clientStateRes) } } -// queryHeaderHandlerFn implements a header querying route -// -// @Summary Query header -// @Tags IBC -// @Produce json -// @Success 200 {object} QueryHeader "OK" -// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/header [get] -func queryHeaderHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - header, err := utils.GetTendermintHeader(cliCtx) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - rest.PostProcessResponse(w, cliCtx, header) - } -} - -// queryClientStateHandlerFn implements a client state querying route +// queryConsensusStateHandlerFn implements a consensus state querying route // -// @Summary Query client state +// @Summary Query cliet consensus-state // @Tags IBC // @Produce json // @Param client-id path string true "Client ID" // @Param prove query boolean false "Proof of result" -// @Success 200 {object} QueryClientState "OK" +// @Success 200 {object} QueryConsensusState "OK" // @Failure 400 {object} rest.ErrorResponse "Invalid client id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/clients/{client-id}/client-state [get] -func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +// @Router /ibc/clients/{client-id}/consensus-state [get] +func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyClientState(clientID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + csRes, err := utils.QueryConsensusStateProof(cliCtx, clientID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var state types.State - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &state); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - } - - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewClientStateResponse(clientID, state, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(csRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, csRes) } } @@ -153,31 +109,43 @@ func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Handl return } + prove := rest.ParseQueryProve(r) + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyRoot(clientID, height), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + rootRes, err := utils.QueryCommitmentRoot(cliCtx, clientID, height, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var root commitment.Root - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &root); err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + cliCtx = cliCtx.WithHeight(int64(rootRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, rootRes) + } +} + +// queryHeaderHandlerFn implements a header querying route +// +// @Summary Query header +// @Tags IBC +// @Produce json +// @Success 200 {object} QueryHeader "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/header [get] +func queryHeaderHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + header, height, err := utils.QueryTendermintHeader(cliCtx) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewRootResponse(clientID, height, root, res.Proof, res.Height)) + res := cliCtx.Codec.MustMarshalJSON(header) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -191,38 +159,9 @@ func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Handl // @Router /ibc/node-state [get] func queryNodeConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - node, err := cliCtx.GetNode() - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - info, err := node.ABCIInfo() - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - height := info.Response.LastBlockHeight - prevHeight := height - 1 - - commit, err := node.Commit(&height) + state, height, err := utils.QueryNodeConsensusState(cliCtx) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - validators, err := node.Validators(&prevHeight) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - state := tendermint.ConsensusState{ - ChainID: commit.ChainID, - Height: uint64(commit.Height), - Root: commitment.NewRoot(commit.AppHash), - NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), } res := cliCtx.Codec.MustMarshalJSON(state) diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 955e06f50e7c..a024e0856594 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -1,38 +1,52 @@ package utils import ( - "fmt" - - "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// QueryClientState queries the store to get the light client state and a merkle +// proof. +func QueryClientState( + cliCtx context.CLIContext, clientID string, prove bool, +) (types.StateResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyClientState(clientID), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.StateResponse{}, err + } + + var clientState types.State + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &clientState); err != nil { + return types.StateResponse{}, err + } + + clientStateRes := types.NewClientStateResponse(clientID, clientState, res.Proof, res.Height) + + return clientStateRes, nil +} + // QueryConsensusStateProof queries the store to get the consensus state and a // merkle proof. func QueryConsensusStateProof( - cliCtx client.CLIContext, cdc *codec.Codec, - queryRoute, clientID string, -) (types.ConsensusStateResponse, error) { + cliCtx client.CLIContext, clientID string, prove bool) (types.ConsensusStateResponse, error) { var conStateRes types.ConsensusStateResponse - bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) - if err != nil { - return conStateRes, err - } - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), + Path: "store/ibc/key", + Data: types.KeyConsensusState(clientID), + Prove: prove, } res, err := cliCtx.QueryABCI(req) @@ -48,17 +62,43 @@ func QueryConsensusStateProof( return types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height), nil } -// GetTendermintHeader takes a client context and returns the appropriate +// QueryCommitmentRoot queries the store to get the commitment root and a merkle +// proof. +func QueryCommitmentRoot( + cliCtx context.CLIContext, clientID string, height uint64, prove bool, +) (types.RootResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyRoot(clientID, height), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.RootResponse{}, err + } + + var root commitment.Root + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &root); err != nil { + return types.RootResponse{}, err + } + + rootRes := types.NewRootResponse(clientID, height, root, res.Proof, res.Height) + + return rootRes, nil +} + +// QueryTendermintHeader takes a client context and returns the appropriate // tendermint header -func GetTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, error) { +func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, error) { node, err := cliCtx.GetNode() if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } info, err := node.ABCIInfo() if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } height := info.Response.LastBlockHeight @@ -66,17 +106,17 @@ func GetTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, error) { commit, err := node.Commit(&height) if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } validators, err := node.Validators(&prevheight) if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } nextvalidators, err := node.Validators(&height) if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } header := tendermint.Header{ @@ -85,5 +125,41 @@ func GetTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, error) { NextValidatorSet: tmtypes.NewValidatorSet(nextvalidators.Validators), } - return header, nil + return header, height, nil +} + +// QueryNodeConsensusState takes a client context and returns the appropriate +// tendermint consensus state +func QueryNodeConsensusState(cliCtx context.CLIContext) (tendermint.ConsensusState, int64, error) { + node, err := cliCtx.GetNode() + if err != nil { + return tendermint.ConsensusState{}, 0, err + } + + info, err := node.ABCIInfo() + if err != nil { + return tendermint.ConsensusState{}, 0, err + } + + height := info.Response.LastBlockHeight + prevHeight := height - 1 + + commit, err := node.Commit(&height) + if err != nil { + return tendermint.ConsensusState{}, 0, err + } + + validators, err := node.Validators(&prevHeight) + if err != nil { + return tendermint.ConsensusState{}, 0, err + } + + state := tendermint.ConsensusState{ + ChainID: commit.ChainID, + Height: uint64(commit.Height), + Root: commitment.NewRoot(commit.AppHash), + NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), + } + + return state, height, nil } diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index 923a6e710981..cfc69e2f2245 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -3,12 +3,13 @@ package keeper_test import ( "fmt" + "github.com/stretchr/testify/require" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - "github.com/stretchr/testify/require" - tmtypes "github.com/tendermint/tendermint/types" ) const ( diff --git a/x/ibc/03-connection/client/cli/cli.go b/x/ibc/03-connection/client/cli/cli.go new file mode 100644 index 000000000000..820baa02b3b6 --- /dev/null +++ b/x/ibc/03-connection/client/cli/cli.go @@ -0,0 +1,41 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" +) + +// GetQueryCmd returns the query commands for IBC connections +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + ics03ConnectionQueryCmd := &cobra.Command{ + Use: "connection", + Short: "IBC connection query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics03ConnectionQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryConnection(queryRoute, cdc), + )...) + return ics03ConnectionQueryCmd +} + +// GetTxCmd returns the transaction commands for IBC connections +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics03ConnectionTxCmd := &cobra.Command{ + Use: "connection", + Short: "IBC connection transaction subcommands", + } + + ics03ConnectionTxCmd.AddCommand(client.PostCommands( + GetCmdConnectionOpenInit(storeKey, cdc), + GetCmdConnectionOpenTry(storeKey, cdc), + GetCmdConnectionOpenAck(storeKey, cdc), + GetCmdConnectionOpenConfirm(storeKey, cdc), + GetCmdHandshakeState(storeKey, cdc), + )...) + + return ics03ConnectionTxCmd +} diff --git a/x/ibc/03-connection/client/cli/query.go b/x/ibc/03-connection/client/cli/query.go index f4502807f859..4eb3f167b451 100644 --- a/x/ibc/03-connection/client/cli/query.go +++ b/x/ibc/03-connection/client/cli/query.go @@ -7,31 +7,13 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" ) -// GetQueryCmd returns the query commands for IBC connections -func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { - ics03ConnectionQueryCmd := &cobra.Command{ - Use: "connection", - Short: "IBC connection query subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - } - - ics03ConnectionQueryCmd.AddCommand(client.GetCommands( - GetCmdQueryConnection(queryRoute, cdc), - )...) - return ics03ConnectionQueryCmd -} - // GetCmdQueryConnection defines the command to query a connection end func GetCmdQueryConnection(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -43,33 +25,18 @@ Example: $ %s query ibc connection end [connection-id] `, version.ClientName), ), - Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s query ibc connection end [connection-id]", version.ClientName), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) connectionID := args[0] + prove := viper.GetBool(flags.FlagProve) - bz, err := cdc.MarshalJSON(types.NewQueryConnectionParams(connectionID)) - if err != nil { - return err - } - - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryConnection), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), - } - - res, err := cliCtx.QueryABCI(req) + connRes, err := utils.QueryConnection(cliCtx, connectionID, prove) if err != nil { return err } - var connection types.ConnectionEnd - if err := cdc.UnmarshalJSON(res.Value, &connection); err != nil { - return err - } - - connRes := types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height) return cliCtx.PrintOutput(connRes) }, } @@ -89,33 +56,18 @@ Example: $ %s query ibc connection client [client-id] `, version.ClientName), ), - Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s query ibc connection client [client-id]", version.ClientName), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) clientID := args[0] + prove := viper.GetBool(flags.FlagProve) - bz, err := cdc.MarshalJSON(types.NewQueryClientConnectionsParams(clientID)) + connPathsRes, err := utils.QueryClientConnections(cliCtx, clientID, prove) if err != nil { return err } - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientConnections), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), - } - - res, err := cliCtx.QueryABCI(req) - if err != nil { - return err - } - - var connectionPaths []string - if err := cdc.UnmarshalJSON(res.Value, &connectionPaths); err != nil { - return err - } - - connPathsRes := types.NewClientConnectionsResponse(clientID, connectionPaths, res.Proof, res.Height) return cliCtx.PrintOutput(connPathsRes) }, } diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index b3115069adbc..c2324322f08f 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -38,24 +38,6 @@ const ( FlagChainID2 = "chain-id2" ) -// GetTxCmd returns the transaction commands for IBC Connections -func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { - ics03ConnectionTxCmd := &cobra.Command{ - Use: "connection", - Short: "IBC connection transaction subcommands", - } - - ics03ConnectionTxCmd.AddCommand(client.PostCommands( - GetCmdConnectionOpenInit(storeKey, cdc), - GetCmdConnectionOpenTry(storeKey, cdc), - GetCmdConnectionOpenAck(storeKey, cdc), - GetCmdConnectionOpenConfirm(storeKey, cdc), - GetCmdHandshakeState(storeKey, cdc), - )...) - - return ics03ConnectionTxCmd -} - // GetCmdConnectionOpenInit defines the command to initialize a connection on // chain A with a given counterparty chain B func GetCmdConnectionOpenInit(storeKey string, cdc *codec.Codec) *cobra.Command { @@ -302,7 +284,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { Args: cobra.ExactArgs(6), RunE: func(cmd *cobra.Command, args []string) error { - viper.Set(flags.FlagProve, true) + prove := true // --chain-id values for each chain cid1 := viper.GetString(flags.FlagChainID) @@ -387,7 +369,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { // remove hardcoding this to 8 seconds. time.Sleep(8 * time.Second) - header, err := clientutils.GetTendermintHeader(ctx1) + header, _, err := clientutils.QueryTendermintHeader(ctx1) if err != nil { return err } @@ -414,7 +396,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), cdc, clienttypes.QuerierRoute, clientID1) + csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1, prove) if err != nil { return err } @@ -442,7 +424,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { // remove hardcoding this to 8 seconds. time.Sleep(8 * time.Second) - header, err = clientutils.GetTendermintHeader(ctx2) + header, _, err = clientutils.QueryTendermintHeader(ctx2) if err != nil { return err } @@ -468,7 +450,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), cdc, clienttypes.QuerierRoute, clientID2) + csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2, prove) if err != nil { return err } @@ -495,7 +477,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { // remove hardcoding this to 8 seconds. time.Sleep(8 * time.Second) - header, err = clientutils.GetTendermintHeader(ctx1) + header, _, err = clientutils.QueryTendermintHeader(ctx1) if err != nil { return err } diff --git a/x/ibc/03-connection/client/rest/query.go b/x/ibc/03-connection/client/rest/query.go index f40bbfd2eba6..8085a8965d0c 100644 --- a/x/ibc/03-connection/client/rest/query.go +++ b/x/ibc/03-connection/client/rest/query.go @@ -5,11 +5,10 @@ import ( "net/http" "github.com/gorilla/mux" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { @@ -32,30 +31,21 @@ func queryConnectionHandlerFn(cliCtx context.CLIContext, queryRoute string) http return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) connectionID := vars[RestConnectionID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyConnection(connectionID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + connRes, err := utils.QueryConnection(cliCtx, connectionID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var connection types.ConnectionEnd - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - } - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(connRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, connRes) } } @@ -74,29 +64,20 @@ func queryClientConnectionsHandlerFn(cliCtx context.CLIContext, queryRoute strin return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyClientConnections(clientID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + connPathsRes, err := utils.QueryClientConnections(cliCtx, clientID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var paths []string - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &paths); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - } - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewClientConnectionsResponse(clientID, paths, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(connPathsRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, connPathsRes) } } diff --git a/x/ibc/03-connection/client/utils/utils.go b/x/ibc/03-connection/client/utils/utils.go new file mode 100644 index 000000000000..5cfd7bf7dab4 --- /dev/null +++ b/x/ibc/03-connection/client/utils/utils.go @@ -0,0 +1,59 @@ +package utils + +import ( + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +// QueryConnection queries the store to get a connection end and a merkle +// proof. +func QueryConnection( + cliCtx context.CLIContext, connectionID string, prove bool, +) (types.ConnectionResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyConnection(connectionID), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.ConnectionResponse{}, err + } + + var connection types.ConnectionEnd + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { + return types.ConnectionResponse{}, err + } + + connRes := types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height) + + return connRes, nil +} + +// QueryClientConnections queries the store to get the registered connection paths +// registered for a particular client and a merkle proof. +func QueryClientConnections( + cliCtx context.CLIContext, clientID string, prove bool, +) (types.ClientConnectionsResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyClientConnections(clientID), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.ClientConnectionsResponse{}, err + } + + var paths []string + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &paths); err != nil { + return types.ClientConnectionsResponse{}, err + } + + connPathsRes := types.NewClientConnectionsResponse(clientID, paths, res.Proof, res.Height) + return connPathsRes, nil +} diff --git a/x/ibc/04-channel/client/cli/cli.go b/x/ibc/04-channel/client/cli/cli.go new file mode 100644 index 000000000000..2f6e76ca9b13 --- /dev/null +++ b/x/ibc/04-channel/client/cli/cli.go @@ -0,0 +1,43 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" +) + +// GetQueryCmd returns the query commands for IBC channels +func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics04ChannelQueryCmd := &cobra.Command{ + Use: "channel", + Short: "IBC channel query subcommands", + DisableFlagParsing: true, + } + + ics04ChannelQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryChannel(storeKey, cdc), + )...) + + return ics04ChannelQueryCmd +} + +// GetTxCmd returns the transaction commands for IBC channels +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics04ChannelTxCmd := &cobra.Command{ + Use: "channel", + Short: "IBC channel transaction subcommands", + } + + ics04ChannelTxCmd.AddCommand(client.PostCommands( + GetMsgChannelOpenInitCmd(storeKey, cdc), + GetMsgChannelOpenTryCmd(storeKey, cdc), + GetMsgChannelOpenAckCmd(storeKey, cdc), + GetMsgChannelOpenConfirmCmd(storeKey, cdc), + GetMsgChannelCloseInitCmd(storeKey, cdc), + GetMsgChannelCloseConfirmCmd(storeKey, cdc), + GetCmdHandshake(storeKey, cdc), + )...) + + return ics04ChannelTxCmd +} diff --git a/x/ibc/04-channel/client/cli/query.go b/x/ibc/04-channel/client/cli/query.go index 04bfcfcbbe92..e04e943d33e8 100644 --- a/x/ibc/04-channel/client/cli/query.go +++ b/x/ibc/04-channel/client/cli/query.go @@ -5,29 +5,15 @@ import ( "strings" "github.com/spf13/cobra" + "github.com/spf13/viper" - cli "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" ) -// GetQueryCmd returns the query commands for IBC channels -func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { - ics04ChannelQueryCmd := &cobra.Command{ - Use: "channel", - Short: "IBC channel query subcommands", - DisableFlagParsing: true, - } - - ics04ChannelQueryCmd.AddCommand(cli.GetCommands( - GetCmdQueryChannel(storeKey, cdc), - )...) - - return ics04ChannelQueryCmd -} - // GetCmdQueryChannel defines the command to query a channel end func GetCmdQueryChannel(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -39,17 +25,23 @@ Example: $ %s query ibc channel end [port-id] [channel-id] `, version.ClientName), ), - Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s query ibc channel end [port-id] [channel-id]", version.ClientName), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) + portID := args[0] + channelID := args[1] + prove := viper.GetBool(flags.FlagProve) - ch, err := utils.QueryChannel(cliCtx, args[0], args[1], queryRoute) + channelRes, err := utils.QueryChannel(cliCtx, portID, channelID, prove) if err != nil { return err } - return cliCtx.PrintOutput(ch) + return cliCtx.PrintOutput(channelRes) }, } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd } diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index fea92f900ee9..ff0123a060b6 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -11,9 +11,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/keys" @@ -21,9 +18,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -38,26 +36,6 @@ const ( FlagChainID2 = "chain-id2" ) -// GetTxCmd returns the transaction commands for IBC Connections -func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { - ics04ChannelTxCmd := &cobra.Command{ - Use: "channel", - Short: "IBC channel transaction subcommands", - } - - ics04ChannelTxCmd.AddCommand(client.PostCommands( - GetMsgChannelOpenInitCmd(storeKey, cdc), - GetMsgChannelOpenTryCmd(storeKey, cdc), - GetMsgChannelOpenAckCmd(storeKey, cdc), - GetMsgChannelOpenConfirmCmd(storeKey, cdc), - GetMsgChannelCloseInitCmd(storeKey, cdc), - GetMsgChannelCloseConfirmCmd(storeKey, cdc), - GetCmdHandshake(storeKey, cdc), - )...) - - return ics04ChannelTxCmd -} - // TODO: module needs to pass the capability key (i.e store key) // GetMsgChannelOpenInitCmd returns the command to create a MsgChannelOpenInit transaction @@ -67,7 +45,7 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Short: "Creates and sends a ChannelOpenInit message", Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -86,7 +64,7 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } @@ -103,7 +81,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Creates and sends a ChannelOpenTry message", Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -140,7 +118,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") @@ -156,7 +134,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Creates and sends a ChannelOpenAck message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -187,7 +165,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } cmd.Flags().String(FlagIBCVersion, "1.0.0", "supported IBC version") @@ -201,7 +179,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma Short: "Creates and sends a ChannelOpenConfirm message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -231,7 +209,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } } @@ -243,7 +221,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Short: "Creates and sends a ChannelCloseInit message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -254,7 +232,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } } @@ -266,7 +244,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm Short: "Creates and sends a ChannelCloseConfirm message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -296,7 +274,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } } @@ -342,10 +320,12 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie connid1 := args[3] connid2 := args[7] + prove := true + // Create txbldr, clictx, querier for cid1 viper.Set(flags.FlagChainID, cid1) txBldr1 := auth.NewTxBuilderFromCLI(). - WithTxEncoder(utils.GetTxEncoder(cdc)) + WithTxEncoder(authutils.GetTxEncoder(cdc)) ctx1 := context.NewCLIContextIBC(from1, cid1, node1). WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) @@ -353,7 +333,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie // Create txbldr, clictx, querier for cid2 viper.Set(flags.FlagChainID, cid2) txBldr2 := auth.NewTxBuilderFromCLI(). - WithTxEncoder(utils.GetTxEncoder(cdc)) + WithTxEncoder(authutils.GetTxEncoder(cdc)) ctx2 := context.NewCLIContextIBC(from2, cid2, node2). WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) @@ -377,7 +357,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) + res, err := authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) if err != nil || !res.IsOK() { return err } @@ -386,7 +366,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie // to retrieve the correct proofs time.Sleep(8 * time.Second) - header, err := clientutils.GetTendermintHeader(ctx1) + header, _, err := clientutils.QueryTendermintHeader(ctx1) if err != nil { return err } @@ -397,23 +377,23 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) if err != nil || !res.IsOK() { return err } viper.Set(flags.FlagChainID, cid1) - proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), portid1, chanid1, storeKey) + channelRes, err := utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) if err != nil { return err } - msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) if err := msgUpdateClient.ValidateBasic(); err != nil { return err } - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) + res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) if err != nil || !res.IsOK() { return err } @@ -422,7 +402,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie // to retrieve the correct proofs time.Sleep(8 * time.Second) - header, err = clientutils.GetTendermintHeader(ctx2) + header, _, err = clientutils.QueryTendermintHeader(ctx2) if err != nil { return err } @@ -433,24 +413,24 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) + res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) if err != nil || !res.IsOK() { return err } viper.Set(flags.FlagChainID, cid2) - proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), portid2, chanid2, storeKey) + channelRes, err = utils.QueryChannel(ctx2.WithHeight(header.Height-1), portid2, chanid2, prove) if err != nil { return err } viper.Set(flags.FlagChainID, cid1) - msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", proofs.Proof, uint64(header.Height), ctx1.GetFromAddress()) + msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx1.GetFromAddress()) if err := msgOpenAck.ValidateBasic(); err != nil { return err } - res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) + res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) if err != nil || !res.IsOK() { return err } @@ -459,7 +439,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie // to retrieve the correct proofs time.Sleep(8 * time.Second) - header, err = clientutils.GetTendermintHeader(ctx1) + header, _, err = clientutils.QueryTendermintHeader(ctx1) if err != nil { return err } @@ -470,23 +450,23 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) if err != nil || !res.IsOK() { return err } viper.Set(flags.FlagChainID, cid1) - proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), portid1, chanid1, storeKey) + channelRes, err = utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) if err != nil { return err } - msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) if err := msgOpenConfirm.ValidateBasic(); err != nil { return err } - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) + res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) if err != nil || !res.IsOK() { return err } @@ -508,27 +488,6 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return cmd } -func queryProofs(ctx client.CLIContext, portID string, channelID string, queryRoute string) (types.ChannelResponse, error) { - var connRes types.ChannelResponse - - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyChannel(portID, channelID), - Prove: true, - } - - res, err := ctx.QueryABCI(req) - if res.Value == nil || err != nil { - return connRes, err - } - - var channel types.Channel - if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { - return connRes, err - } - return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil -} - func channelOrder() types.Order { if viper.GetBool(FlagOrdered) { return types.ORDERED diff --git a/x/ibc/04-channel/client/rest/query.go b/x/ibc/04-channel/client/rest/query.go index b1f6a0f93b63..9fcd714de242 100644 --- a/x/ibc/04-channel/client/rest/query.go +++ b/x/ibc/04-channel/client/rest/query.go @@ -5,11 +5,10 @@ import ( "net/http" "github.com/gorilla/mux" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { @@ -33,31 +32,20 @@ func queryChannelHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Ha vars := mux.Vars(r) portID := vars[RestPortID] channelID := vars[RestChannelID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyChannel(portID, channelID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + channelRes, err := utils.QueryChannel(cliCtx, portID, channelID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var channel types.Channel - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(channelRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, channelRes) } } diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index 580a2bf1fb83..0084f57376a1 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -9,29 +9,26 @@ import ( // QueryPacket returns a packet from the store func QueryPacket( - ctx client.CLIContext, portID, channelID string, - sequence, timeout uint64, queryRoute string, + ctx client.CLIContext, portID, channelID string, sequence, timeout uint64, prove bool, ) (types.PacketResponse, error) { - var packetRes types.PacketResponse - req := abci.RequestQuery{ Path: "store/ibc/key", Data: types.KeyPacketCommitment(portID, channelID, sequence), - Prove: true, + Prove: prove, } res, err := ctx.QueryABCI(req) if err != nil { - return packetRes, err + return types.PacketResponse{}, err } - channel, err := QueryChannel(ctx, portID, channelID, queryRoute) + channelRes, err := QueryChannel(ctx, portID, channelID, prove) if err != nil { - return packetRes, err + return types.PacketResponse{}, err } - destPortID := channel.Channel.Counterparty.PortID - destChannelID := channel.Channel.Counterparty.ChannelID + destPortID := channelRes.Channel.Counterparty.PortID + destChannelID := channelRes.Channel.Counterparty.ChannelID packet := types.NewPacket( sequence, @@ -47,24 +44,25 @@ func QueryPacket( return types.NewPacketResponse(portID, channelID, sequence, packet, res.Proof, res.Height+1), nil } -// QueryChannel returns a channel from the store -func QueryChannel(ctx client.CLIContext, portID string, channelID string, queryRoute string) (types.ChannelResponse, error) { - var connRes types.ChannelResponse - +// QueryChannel queries the store to get a channel and a merkle proof. +func QueryChannel( + ctx client.CLIContext, portID, channelID string, prove bool, +) (types.ChannelResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", Data: types.KeyChannel(portID, channelID), - Prove: true, + Prove: prove, } res, err := ctx.QueryABCI(req) if res.Value == nil || err != nil { - return connRes, err + return types.ChannelResponse{}, err } var channel types.Channel if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { - return connRes, err + return types.ChannelResponse{}, err } + return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil } diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go index 707e9076ca39..9594f56473ef 100644 --- a/x/ibc/04-channel/types/querier.go +++ b/x/ibc/04-channel/types/querier.go @@ -69,3 +69,25 @@ func NewPacketResponse( ProofHeight: uint64(height), } } + +// RecvResponse defines the client query response for the next receive sequence +// number which also includes a proof, its path and the height form which the +// proof was retrieved +type RecvResponse struct { + NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewRecvResponse creates a new RecvResponse instance +func NewRecvResponse( + portID, channelID string, sequenceRecv uint64, proof *merkle.Proof, height int64, +) RecvResponse { + return RecvResponse{ + NextSequenceRecv: sequenceRecv, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(NextSequenceRecvPath(portID, channelID), "/")), + ProofHeight: uint64(height), + } +} diff --git a/x/ibc/05-port/keeper/keeper_test.go b/x/ibc/05-port/keeper/keeper_test.go index 320471d56030..c44c1f052d06 100644 --- a/x/ibc/05-port/keeper/keeper_test.go +++ b/x/ibc/05-port/keeper/keeper_test.go @@ -6,11 +6,12 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/05-port/keeper" - abci "github.com/tendermint/tendermint/abci/types" ) var ( diff --git a/x/ibc/20-transfer/client/cli/cli.go b/x/ibc/20-transfer/client/cli/cli.go new file mode 100644 index 000000000000..ce535761c9a9 --- /dev/null +++ b/x/ibc/20-transfer/client/cli/cli.go @@ -0,0 +1,37 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" +) + +// GetQueryCmd returns the query commands for IBC fungible token transfer +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + ics20TransferQueryCmd := &cobra.Command{ + Use: "transfer", + Short: "IBC fungible token transfer query subcommands", + } + + ics20TransferQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryNextSequence(cdc, queryRoute), + )...) + + return ics20TransferQueryCmd +} + +// GetTxCmd returns the transaction commands for IBC fungible token transfer +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + ics20TransferTxCmd := &cobra.Command{ + Use: "transfer", + Short: "IBC fungible token transfer transaction subcommands", + } + + ics20TransferTxCmd.AddCommand(client.PostCommands( + GetTransferTxCmd(cdc), + GetMsgRecvPacketCmd(cdc), + )...) + + return ics20TransferTxCmd +} diff --git a/x/ibc/20-transfer/client/cli/query.go b/x/ibc/20-transfer/client/cli/query.go index 6aad7157e228..6c431ea1ee12 100644 --- a/x/ibc/20-transfer/client/cli/query.go +++ b/x/ibc/20-transfer/client/cli/query.go @@ -1,35 +1,19 @@ package cli import ( - "encoding/binary" "fmt" "strings" "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" + "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/utils" ) -// GetQueryCmd returns the query commands for IBC fungible token transfer -func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { - queryCmd := &cobra.Command{ - Use: "transfer", - Short: "IBC fungible token transfer query subcommands", - } - - queryCmd.AddCommand( - GetCmdQueryNextSequence(cdc, queryRoute), - ) - - return queryCmd -} - // GetCmdQueryNextSequence defines the command to query a next receive sequence func GetCmdQueryNextSequence(cdc *codec.Codec, queryRoute string) *cobra.Command { cmd := &cobra.Command{ @@ -41,26 +25,20 @@ Example: $ %s query ibc channel next-recv [port-id] [channel-id] `, version.ClientName), ), - Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s query ibc channel next-recv [port-id] [channel-id]", version.ClientName), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] channelID := args[1] + prove := viper.GetBool(flags.FlagProve) - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: channel.KeyNextSequenceRecv(portID, channelID), - Prove: true, - } - - res, err := cliCtx.QueryABCI(req) + sequenceRes, err := utils.QueryNextSequenceRecv(cliCtx, portID, channelID, prove) if err != nil { return err } - sequence := binary.BigEndian.Uint64(res.Value) - - return cliCtx.PrintOutput(sequence) + return cliCtx.PrintOutput(sequenceRes) }, } cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index 13917f47a62d..ef56f1430b1d 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -31,20 +31,6 @@ var ( FlagTimeout = "timeout" ) -// GetTxCmd returns the transaction commands for IBC fungible token transfer -func GetTxCmd(cdc *codec.Codec) *cobra.Command { - txCmd := &cobra.Command{ - Use: "transfer", - Short: "IBC fungible token transfer transaction subcommands", - } - txCmd.AddCommand( - GetTransferTxCmd(cdc), - GetMsgRecvPacketCmd(cdc), - ) - - return txCmd -} - // GetTransferTxCmd returns the command to create a NewMsgTransfer transaction func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -94,6 +80,7 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + prove := viper.GetBool(flags.FlagProve) node2 := viper.GetString(FlagNode2) cid1 := viper.GetString(flags.FlagChainID) cid2 := viper.GetString(FlagChainID2) @@ -101,7 +88,7 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) - header, err := clientutils.GetTendermintHeader(cliCtx2) + header, _, err := clientutils.QueryTendermintHeader(cliCtx2) if err != nil { return err } @@ -126,16 +113,18 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { viper.Set(flags.FlagChainID, cid2) sequence := uint64(viper.GetInt(FlagSequence)) - packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), "ibc") + packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), prove) if err != nil { return err } + viper.Set(flags.FlagChainID, cid1) msg := types.NewMsgRecvPacket(packetRes.Packet, []commitment.Proof{packetRes.Proof}, packetRes.ProofHeight, cliCtx.GetFromAddress()) if err := msg.ValidateBasic(); err != nil { return err } + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } @@ -146,5 +135,6 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") cmd.Flags().String(FlagSequence, "", "sequence for the packet") cmd.Flags().String(FlagTimeout, "", "timeout for the packet") + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") return cmd } diff --git a/x/ibc/20-transfer/client/rest/query.go b/x/ibc/20-transfer/client/rest/query.go index 8e979152a768..1b9b42a877e6 100644 --- a/x/ibc/20-transfer/client/rest/query.go +++ b/x/ibc/20-transfer/client/rest/query.go @@ -1,17 +1,14 @@ package rest import ( - "encoding/binary" "fmt" "net/http" "github.com/gorilla/mux" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/utils" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { @@ -34,27 +31,20 @@ func queryNextSequenceRecvHandlerFn(cliCtx context.CLIContext) http.HandlerFunc vars := mux.Vars(r) portID := vars[RestPortID] channelID := vars[RestChannelID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: channel.KeyNextSequenceRecv(portID, channelID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + sequenceRes, err := utils.QueryNextSequenceRecv(cliCtx, portID, channelID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - sequence := binary.BigEndian.Uint64(res.Value) - - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, sequence) + cliCtx = cliCtx.WithHeight(int64(sequenceRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, sequenceRes) } } diff --git a/x/ibc/20-transfer/client/utils/utils.go b/x/ibc/20-transfer/client/utils/utils.go new file mode 100644 index 000000000000..b89b2116b8d4 --- /dev/null +++ b/x/ibc/20-transfer/client/utils/utils.go @@ -0,0 +1,32 @@ +package utils + +import ( + "encoding/binary" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// QueryNextSequenceRecv queries the store to get the next receive sequence and +// a merkle proof. +func QueryNextSequenceRecv( + cliCtx context.CLIContext, portID, channelID string, prove bool, +) (channeltypes.RecvResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: channeltypes.KeyNextSequenceRecv(portID, channelID), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return channeltypes.RecvResponse{}, err + } + + sequence := binary.BigEndian.Uint64(res.Value) + sequenceRes := channeltypes.NewRecvResponse(portID, channelID, sequence, res.Proof, res.Height) + + return sequenceRes, nil +} diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 89fad1195d09..7e0f430ddaa9 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -4,6 +4,9 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" @@ -16,8 +19,6 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/supply" - "github.com/stretchr/testify/suite" - abci "github.com/tendermint/tendermint/abci/types" ) // define constants used for testing diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index e5023a662caf..b7370a34d29f 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -4,6 +4,10 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" @@ -11,9 +15,6 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - "github.com/stretchr/testify/suite" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" ) // define constants used for testing diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 7546fc48a98c..fe20d2b26062 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "fmt" + abci "github.com/tendermint/tendermint/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" @@ -11,7 +13,6 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/supply" - abci "github.com/tendermint/tendermint/abci/types" ) func (suite *KeeperTestSuite) createClient() { diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go index f0b500b10d2f..935f94f0419f 100644 --- a/x/ibc/20-transfer/types/msgs_test.go +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -4,12 +4,13 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/merkle" + sdk "github.com/cosmos/cosmos-sdk/types" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/merkle" ) // define constants used for testing From 8ca3c28bfb26d560f3e11428616d27708990af2f Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 3 Dec 2019 16:36:04 +0100 Subject: [PATCH 020/176] fix build; comment handshakes --- x/ibc/02-client/client/cli/tx.go | 16 +- x/ibc/03-connection/client/cli/cli.go | 1 - x/ibc/03-connection/client/cli/tx.go | 573 ++++++++++++-------------- x/ibc/04-channel/client/cli/cli.go | 1 - x/ibc/04-channel/client/cli/tx.go | 457 ++++++++++---------- x/ibc/20-transfer/client/cli/cli.go | 2 +- x/ibc/20-transfer/client/cli/tx.go | 150 ++++--- 7 files changed, 589 insertions(+), 611 deletions(-) diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 2c8abcff4c95..197f7271b011 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -1,6 +1,7 @@ package cli import ( + "bufio" "fmt" "io/ioutil" "os" @@ -33,8 +34,9 @@ $ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node ), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) clientID := args[0] @@ -80,8 +82,9 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home ), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) clientID := args[0] @@ -124,8 +127,9 @@ $ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 ), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) clientID := args[0] diff --git a/x/ibc/03-connection/client/cli/cli.go b/x/ibc/03-connection/client/cli/cli.go index 820baa02b3b6..9d3777f1fefa 100644 --- a/x/ibc/03-connection/client/cli/cli.go +++ b/x/ibc/03-connection/client/cli/cli.go @@ -34,7 +34,6 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { GetCmdConnectionOpenTry(storeKey, cdc), GetCmdConnectionOpenAck(storeKey, cdc), GetCmdConnectionOpenConfirm(storeKey, cdc), - GetCmdHandshakeState(storeKey, cdc), )...) return ics03ConnectionTxCmd diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index c2324322f08f..3ad967b785d2 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -1,30 +1,24 @@ package cli import ( + "bufio" "fmt" "io/ioutil" "os" "strings" - "time" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -55,8 +49,9 @@ $ %s tx ibc connection open-init [connection-id] [client-id] [counterparty-conne ), Args: cobra.ExactArgs(6), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] clientID := args[1] @@ -107,8 +102,9 @@ $ %s tx ibc connection open-try connection-id] [client-id] ), Args: cobra.ExactArgs(6), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext(). + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) @@ -177,8 +173,9 @@ $ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [versio ), Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] proofBz, err := ioutil.ReadFile(args[1]) @@ -229,8 +226,9 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] ), Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext(). + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) @@ -277,289 +275,6 @@ func lastHeight(cliCtx context.CLIContext) (uint64, error) { return uint64(info.Response.LastBlockHeight), nil } -func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "handshake [conn-id-chain-1] [client-id-chain-1] [path-chain-1] [conn-id-chain-2] [client-id-chain-2] [path-chain-2] ", - Short: "initiate connection handshake between two chains", - Args: cobra.ExactArgs(6), - RunE: func(cmd *cobra.Command, args []string) error { - - prove := true - - // --chain-id values for each chain - cid1 := viper.GetString(flags.FlagChainID) - cid2 := viper.GetString(FlagChainID2) - - // --from values for each wallet - from1 := viper.GetString(FlagFrom1) - from2 := viper.GetString(FlagFrom2) - - // --node values for each RPC - rpc1 := viper.GetString(FlagNode1) - rpc2 := viper.GetString(FlagNode2) - - // ibc connection-id for each chain - connID1 := args[0] - connID2 := args[3] - - // ibc client-id for each chain - clientID1 := args[1] - clientID2 := args[4] - - // Get default version - version := types.GetCompatibleVersions()[0] - - // Create txbldr, clictx, querier for cid1 - viper.Set(flags.FlagChainID, cid1) - txBldr1 := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - ctx1 := context.NewCLIContextIBC(from1, cid1, rpc1).WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - // Create txbldr, clictx, querier for cid1 - viper.Set(flags.FlagChainID, cid2) - txBldr2 := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - ctx2 := context.NewCLIContextIBC(from2, cid2, rpc2).WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - // read in path for cid1 - path1, err := parsePath(ctx1.Codec, args[2]) - if err != nil { - return err - } - - // read in path for cid2 - path2, err := parsePath(ctx1.Codec, args[5]) - if err != nil { - return err - } - - // get passphrase for key from1 - passphrase1, err := keys.GetPassphrase(from1) - if err != nil { - return err - } - - // get passphrase for key from2 - passphrase2, err := keys.GetPassphrase(from2) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid1) - msgOpenInit := types.NewMsgConnectionOpenInit( - connID1, clientID1, connID2, clientID2, - path2, ctx1.GetFromAddress(), - ) - - if err := msgOpenInit.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid1, msgOpenInit.Type()) - res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - - fmt.Printf(" [OK] txid(%v) client(%v) conn(%v)\n", res.TxHash, clientID1, connID1) - - // Another block has to be passed after msgOpenInit is committed - // to retrieve the correct proofs - // TODO: Modify this to actually check two blocks being processed, and - // remove hardcoding this to 8 seconds. - time.Sleep(8 * time.Second) - - header, _, err := clientutils.QueryTendermintHeader(ctx1) - if err != nil { - return err - } - - // Create and send msgUpdateClient - viper.Set(flags.FlagChainID, cid2) - msgUpdateClient := clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) - - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - - // Fetch proofs from cid1 - viper.Set(flags.FlagChainID, cid1) - proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) - if err != nil { - return err - } - - csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1, prove) - if err != nil { - return err - } - - // Create and send msgOpenTry - viper.Set(flags.FlagChainID, cid2) - msgOpenTry := types.NewMsgConnectionOpenTry(connID2, clientID2, connID1, clientID1, path1, []string{version}, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), ctx2.GetFromAddress()) - - if err := msgOpenTry.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid2, msgOpenTry.Type()) - - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - fmt.Printf(" [OK] txid(%v) client(%v) connection(%v)\n", res.TxHash, clientID2, connID2) - - // Another block has to be passed after msgOpenInit is committed - // to retrieve the correct proofs - // TODO: Modify this to actually check two blocks being processed, and - // remove hardcoding this to 8 seconds. - time.Sleep(8 * time.Second) - - header, _, err = clientutils.QueryTendermintHeader(ctx2) - if err != nil { - return err - } - - // Update the client for cid2 on cid1 - viper.Set(flags.FlagChainID, cid1) - msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID1, header, ctx1.GetFromAddress()) - - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID2) - - // Fetch proofs from cid2 - viper.Set(flags.FlagChainID, cid2) - proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), connID2, storeKey) - if err != nil { - return err - } - - csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2, prove) - if err != nil { - return err - } - - // Create and send msgOpenAck - viper.Set(flags.FlagChainID, cid1) - msgOpenAck := types.NewMsgConnectionOpenAck(connID1, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), version, ctx1.GetFromAddress()) - - if err := msgOpenAck.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid1, msgOpenAck.Type()) - - res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID1) - - // Another block has to be passed after msgOpenInit is committed - // to retrieve the correct proofs - // TODO: Modify this to actually check two blocks being processed, and - // remove hardcoding this to 8 seconds. - time.Sleep(8 * time.Second) - - header, _, err = clientutils.QueryTendermintHeader(ctx1) - if err != nil { - return err - } - - // Update client for cid1 on cid2 - viper.Set(flags.FlagChainID, cid2) - msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) - - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) - - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - - viper.Set(flags.FlagChainID, cid1) - proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) - if err != nil { - return err - } - - // Create and send msgOpenConfirm - viper.Set(flags.FlagChainID, cid2) - msgOpenConfirm := types.NewMsgConnectionOpenConfirm(connID2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) - - if err := msgOpenConfirm.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid1, msgOpenConfirm.Type()) - - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID2) - - return nil - }, - } - - cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") - cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") - cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") - cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") - cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") - - cmd.MarkFlagRequired(FlagNode1) - cmd.MarkFlagRequired(FlagNode2) - cmd.MarkFlagRequired(FlagFrom1) - cmd.MarkFlagRequired(FlagFrom2) - cmd.MarkFlagRequired(FlagChainID2) - - return cmd -} - -func queryProofs(ctx client.CLIContext, connectionID string, queryRoute string) (types.ConnectionResponse, error) { - - var connRes types.ConnectionResponse - - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: []byte(fmt.Sprintf("connections/%s", connectionID)), - Prove: true, - } - res, err := ctx.QueryABCI(req) - if err != nil { - return connRes, err - } - - var connection types.ConnectionEnd - if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { - return connRes, err - } - return types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height), nil -} - func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { var path commitment.Prefix if err := cdc.UnmarshalJSON([]byte(arg), &path); err != nil { @@ -574,3 +289,265 @@ func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { } return path, nil } + +// func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { +// cmd := &cobra.Command{ +// Use: "handshake [conn-id-chain-1] [client-id-chain-1] [path-chain-1] [conn-id-chain-2] [client-id-chain-2] [path-chain-2] ", +// Short: "initiate connection handshake between two chains", +// Args: cobra.ExactArgs(6), +// RunE: func(cmd *cobra.Command, args []string) error { +// inBuf := bufio.NewReader(cmd.InOrStdin()) +// prove := true + +// // --chain-id values for each chain +// cid1 := viper.GetString(flags.FlagChainID) +// cid2 := viper.GetString(FlagChainID2) + +// // --from values for each wallet +// from1 := viper.GetString(FlagFrom1) +// from2 := viper.GetString(FlagFrom2) + +// // --node values for each RPC +// rpc1 := viper.GetString(FlagNode1) +// rpc2 := viper.GetString(FlagNode2) + +// // ibc connection-id for each chain +// connID1 := args[0] +// connID2 := args[3] + +// // ibc client-id for each chain +// clientID1 := args[1] +// clientID2 := args[4] + +// // Get default version +// version := types.GetCompatibleVersions()[0] + +// // Create txbldr, clictx, querier for cid1 +// viper.Set(flags.FlagChainID, cid1) +// txBldr1 := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) +// ctx1 := context.NewCLIContextIBC(inBuf, from1, cid1, rpc1).WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// // Create txbldr, clictx, querier for cid1 +// viper.Set(flags.FlagChainID, cid2) +// txBldr2 := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) +// ctx2 := context.NewCLIContextIBC(inBuf, from2, cid2, rpc2).WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// // read in path for cid1 +// path1, err := parsePath(ctx1.Codec, args[2]) +// if err != nil { +// return err +// } + +// // read in path for cid2 +// path2, err := parsePath(ctx1.Codec, args[5]) +// if err != nil { +// return err +// } + +// // get passphrase for key from1 +// passphrase1, err := keys.GetPassphrase(from1) +// if err != nil { +// return err +// } + +// // get passphrase for key from2 +// passphrase2, err := keys.GetPassphrase(from2) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// msgOpenInit := types.NewMsgConnectionOpenInit( +// connID1, clientID1, connID2, clientID2, +// path2, ctx1.GetFromAddress(), +// ) + +// if err := msgOpenInit.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid1, msgOpenInit.Type()) +// res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } + +// fmt.Printf(" [OK] txid(%v) client(%v) conn(%v)\n", res.TxHash, clientID1, connID1) + +// // Another block has to be passed after msgOpenInit is committed +// // to retrieve the correct proofs +// // TODO: Modify this to actually check two blocks being processed, and +// // remove hardcoding this to 8 seconds. +// time.Sleep(8 * time.Second) + +// header, _, err := clientutils.QueryTendermintHeader(ctx1) +// if err != nil { +// return err +// } + +// // Create and send msgUpdateClient +// viper.Set(flags.FlagChainID, cid2) +// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) + +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) +// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) + +// // Fetch proofs from cid1 +// viper.Set(flags.FlagChainID, cid1) +// proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) +// if err != nil { +// return err +// } + +// csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1, prove) +// if err != nil { +// return err +// } + +// // Create and send msgOpenTry +// viper.Set(flags.FlagChainID, cid2) +// msgOpenTry := types.NewMsgConnectionOpenTry(connID2, clientID2, connID1, clientID1, path1, []string{version}, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), ctx2.GetFromAddress()) + +// if err := msgOpenTry.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid2, msgOpenTry.Type()) + +// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// fmt.Printf(" [OK] txid(%v) client(%v) connection(%v)\n", res.TxHash, clientID2, connID2) + +// // Another block has to be passed after msgOpenInit is committed +// // to retrieve the correct proofs +// // TODO: Modify this to actually check two blocks being processed, and +// // remove hardcoding this to 8 seconds. +// time.Sleep(8 * time.Second) + +// header, _, err = clientutils.QueryTendermintHeader(ctx2) +// if err != nil { +// return err +// } + +// // Update the client for cid2 on cid1 +// viper.Set(flags.FlagChainID, cid1) +// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID1, header, ctx1.GetFromAddress()) + +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID2) + +// // Fetch proofs from cid2 +// viper.Set(flags.FlagChainID, cid2) +// proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), connID2, storeKey) +// if err != nil { +// return err +// } + +// csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2, prove) +// if err != nil { +// return err +// } + +// // Create and send msgOpenAck +// viper.Set(flags.FlagChainID, cid1) +// msgOpenAck := types.NewMsgConnectionOpenAck(connID1, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), version, ctx1.GetFromAddress()) + +// if err := msgOpenAck.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid1, msgOpenAck.Type()) + +// res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID1) + +// // Another block has to be passed after msgOpenInit is committed +// // to retrieve the correct proofs +// // TODO: Modify this to actually check two blocks being processed, and +// // remove hardcoding this to 8 seconds. +// time.Sleep(8 * time.Second) + +// header, _, err = clientutils.QueryTendermintHeader(ctx1) +// if err != nil { +// return err +// } + +// // Update client for cid1 on cid2 +// viper.Set(flags.FlagChainID, cid2) +// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) + +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) + +// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) + +// viper.Set(flags.FlagChainID, cid1) +// proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) +// if err != nil { +// return err +// } + +// // Create and send msgOpenConfirm +// viper.Set(flags.FlagChainID, cid2) +// msgOpenConfirm := types.NewMsgConnectionOpenConfirm(connID2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + +// if err := msgOpenConfirm.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid1, msgOpenConfirm.Type()) + +// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID2) + +// return nil +// }, +// } + +// cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") +// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") +// cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") +// cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") +// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") + +// cmd.MarkFlagRequired(FlagNode1) +// cmd.MarkFlagRequired(FlagNode2) +// cmd.MarkFlagRequired(FlagFrom1) +// cmd.MarkFlagRequired(FlagFrom2) +// cmd.MarkFlagRequired(FlagChainID2) + +// return cmd +// } diff --git a/x/ibc/04-channel/client/cli/cli.go b/x/ibc/04-channel/client/cli/cli.go index 2f6e76ca9b13..35bd02203a1d 100644 --- a/x/ibc/04-channel/client/cli/cli.go +++ b/x/ibc/04-channel/client/cli/cli.go @@ -36,7 +36,6 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { GetMsgChannelOpenConfirmCmd(storeKey, cdc), GetMsgChannelCloseInitCmd(storeKey, cdc), GetMsgChannelCloseConfirmCmd(storeKey, cdc), - GetCmdHandshake(storeKey, cdc), )...) return ics04ChannelTxCmd diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index ff0123a060b6..a0d5ceade64f 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -1,27 +1,21 @@ package cli import ( + "bufio" "fmt" "io/ioutil" "os" "strconv" "strings" - "time" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -45,8 +39,9 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Short: "Creates and sends a ChannelOpenInit message", Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -81,8 +76,9 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Creates and sends a ChannelOpenTry message", Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -134,8 +130,9 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Creates and sends a ChannelOpenAck message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -179,8 +176,9 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma Short: "Creates and sends a ChannelOpenConfirm message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -221,8 +219,9 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Short: "Creates and sends a ChannelCloseInit message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -244,8 +243,9 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm Short: "Creates and sends a ChannelCloseConfirm message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -279,218 +279,219 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm } } -func GetCmdHandshake(storeKey string, cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "handshake", - Short: "initiate connection handshake between two chains", - Long: strings.TrimSpace( - fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: - -Example: -$ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-client-id] [cp-port-id] [cp-chain-id] [cp-conn-id] - `, version.ClientName)), - Args: cobra.ExactArgs(8), - // Args: []string{portid1, chanid1, connid1, portid2, chanid2, connid2} - RunE: func(cmd *cobra.Command, args []string) error { - // --chain-id values for each chain - cid1 := viper.GetString(flags.FlagChainID) - cid2 := viper.GetString(FlagChainID2) - - // --from values for each wallet - from1 := viper.GetString(FlagFrom1) - from2 := viper.GetString(FlagFrom2) - - // --node values for each RPC - node1 := viper.GetString(FlagNode1) - node2 := viper.GetString(FlagNode2) - - // client IDs - clientid1 := args[0] - clientid2 := args[4] - - // port IDs - portid1 := args[1] - portid2 := args[5] - - // channel IDs - chanid1 := args[2] - chanid2 := args[6] - - // connection IDs - connid1 := args[3] - connid2 := args[7] - - prove := true - - // Create txbldr, clictx, querier for cid1 - viper.Set(flags.FlagChainID, cid1) - txBldr1 := auth.NewTxBuilderFromCLI(). - WithTxEncoder(authutils.GetTxEncoder(cdc)) - ctx1 := context.NewCLIContextIBC(from1, cid1, node1). - WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - // Create txbldr, clictx, querier for cid2 - viper.Set(flags.FlagChainID, cid2) - txBldr2 := auth.NewTxBuilderFromCLI(). - WithTxEncoder(authutils.GetTxEncoder(cdc)) - ctx2 := context.NewCLIContextIBC(from2, cid2, node2). - WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - // get passphrase for key from1 - passphrase1, err := keys.GetPassphrase(from1) - if err != nil { - return err - } - - // get passphrase for key from2 - passphrase2, err := keys.GetPassphrase(from2) - if err != nil { - return err - } - - // TODO: check state and if not Idle continue existing process - viper.Set(flags.FlagChainID, cid1) - msgOpenInit := types.NewMsgChannelOpenInit(portid1, chanid1, "v1.0.0", channelOrder(), []string{connid1}, portid2, chanid2, ctx1.GetFromAddress()) - if err := msgOpenInit.ValidateBasic(); err != nil { - return err - } - - res, err := authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - - // Another block has to be passed after msginit is committed - // to retrieve the correct proofs - time.Sleep(8 * time.Second) - - header, _, err := clientutils.QueryTendermintHeader(ctx1) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid2) - msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - viper.Set(flags.FlagChainID, cid1) - channelRes, err := utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) - if err != nil { - return err - } - - msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - // Another block has to be passed after msginit is committed - // to retrieve the correct proofs - time.Sleep(8 * time.Second) - - header, _, err = clientutils.QueryTendermintHeader(ctx2) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid1) - msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid1, header, ctx1.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - - viper.Set(flags.FlagChainID, cid2) - channelRes, err = utils.QueryChannel(ctx2.WithHeight(header.Height-1), portid2, chanid2, prove) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid1) - msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx1.GetFromAddress()) - if err := msgOpenAck.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - - // Another block has to be passed after msginit is committed - // to retrieve the correct proofs - time.Sleep(8 * time.Second) - - header, _, err = clientutils.QueryTendermintHeader(ctx1) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid2) - msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - viper.Set(flags.FlagChainID, cid1) - channelRes, err = utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) - if err != nil { - return err - } - - msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) - if err := msgOpenConfirm.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - return nil - }, - } - - cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") - cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") - cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") - cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") - cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") - cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") - - cmd.MarkFlagRequired(FlagFrom1) - cmd.MarkFlagRequired(FlagFrom2) - - return cmd -} - func channelOrder() types.Order { if viper.GetBool(FlagOrdered) { return types.ORDERED } return types.UNORDERED } + +// func GetCmdHandshake(storeKey string, cdc *codec.Codec) *cobra.Command { +// cmd := &cobra.Command{ +// Use: "handshake", +// Short: "initiate connection handshake between two chains", +// Long: strings.TrimSpace( +// fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: + +// Example: +// $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-client-id] [cp-port-id] [cp-chain-id] [cp-conn-id] +// `, version.ClientName)), +// Args: cobra.ExactArgs(8), +// // Args: []string{portid1, chanid1, connid1, portid2, chanid2, connid2} +// RunE: func(cmd *cobra.Command, args []string) error { +// // --chain-id values for each chain +// cid1 := viper.GetString(flags.FlagChainID) +// cid2 := viper.GetString(FlagChainID2) + +// // --from values for each wallet +// from1 := viper.GetString(FlagFrom1) +// from2 := viper.GetString(FlagFrom2) + +// // --node values for each RPC +// node1 := viper.GetString(FlagNode1) +// node2 := viper.GetString(FlagNode2) + +// // client IDs +// clientid1 := args[0] +// clientid2 := args[4] + +// // port IDs +// portid1 := args[1] +// portid2 := args[5] + +// // channel IDs +// chanid1 := args[2] +// chanid2 := args[6] + +// // connection IDs +// connid1 := args[3] +// connid2 := args[7] + +// inBuf := bufio.NewReader(cmd.InOrStdin()) +// prove := true + +// // Create txbldr, clictx, querier for cid1 +// viper.Set(flags.FlagChainID, cid1) +// txBldr1 := auth.NewTxBuilderFromCLI(inBuf). +// WithTxEncoder(authutils.GetTxEncoder(cdc)) +// ctx1 := context.NewCLIContextIBC(inBuf, from1, cid1, node1). +// WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// // Create txbldr, clictx, querier for cid2 +// viper.Set(flags.FlagChainID, cid2) +// txBldr2 := auth.NewTxBuilderFromCLI(inBuf). +// WithTxEncoder(authutils.GetTxEncoder(cdc)) +// ctx2 := context.NewCLIContextIBC(inBuf, from2, cid2, node2). +// WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// // get passphrase for key from1 +// passphrase1, err := keys.GetPassphrase(from1) +// if err != nil { +// return err +// } + +// // get passphrase for key from2 +// passphrase2, err := keys.GetPassphrase(from2) +// if err != nil { +// return err +// } + +// // TODO: check state and if not Idle continue existing process +// viper.Set(flags.FlagChainID, cid1) +// msgOpenInit := types.NewMsgChannelOpenInit(portid1, chanid1, "v1.0.0", channelOrder(), []string{connid1}, portid2, chanid2, ctx1.GetFromAddress()) +// if err := msgOpenInit.ValidateBasic(); err != nil { +// return err +// } + +// res, err := authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } + +// // Another block has to be passed after msginit is committed +// // to retrieve the correct proofs +// time.Sleep(8 * time.Second) + +// header, _, err := clientutils.QueryTendermintHeader(ctx1) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid2) +// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// channelRes, err := utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) +// if err != nil { +// return err +// } + +// msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// // Another block has to be passed after msginit is committed +// // to retrieve the correct proofs +// time.Sleep(8 * time.Second) + +// header, _, err = clientutils.QueryTendermintHeader(ctx2) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid1, header, ctx1.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } + +// viper.Set(flags.FlagChainID, cid2) +// channelRes, err = utils.QueryChannel(ctx2.WithHeight(header.Height-1), portid2, chanid2, prove) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx1.GetFromAddress()) +// if err := msgOpenAck.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } + +// // Another block has to be passed after msginit is committed +// // to retrieve the correct proofs +// time.Sleep(8 * time.Second) + +// header, _, err = clientutils.QueryTendermintHeader(ctx1) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid2) +// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// channelRes, err = utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) +// if err != nil { +// return err +// } + +// msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) +// if err := msgOpenConfirm.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// return nil +// }, +// } + +// cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") +// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") +// cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") +// cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") +// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") +// cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") + +// cmd.MarkFlagRequired(FlagFrom1) +// cmd.MarkFlagRequired(FlagFrom2) + +// return cmd +// } diff --git a/x/ibc/20-transfer/client/cli/cli.go b/x/ibc/20-transfer/client/cli/cli.go index ce535761c9a9..2007ed31908d 100644 --- a/x/ibc/20-transfer/client/cli/cli.go +++ b/x/ibc/20-transfer/client/cli/cli.go @@ -30,7 +30,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { ics20TransferTxCmd.AddCommand(client.PostCommands( GetTransferTxCmd(cdc), - GetMsgRecvPacketCmd(cdc), + // GetMsgRecvPacketCmd(cdc), )...) return ics20TransferTxCmd diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index ef56f1430b1d..dc14a53c5a3b 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -1,22 +1,18 @@ package cli import ( + "bufio" + "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - channelutils "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // IBC transfer flags @@ -38,8 +34,9 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { Short: "Transfer fungible token through IBC", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - ctx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) sender := ctx.GetFromAddress() srcPort := args[0] @@ -70,71 +67,72 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { return cmd } -// GetMsgRecvPacketCmd returns the command to create a MsgRecvTransferPacket transaction -func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "recv-packet [sending-port-id] [sending-channel-id] [client-id]", - Short: "Creates and sends a SendPacket message", - Args: cobra.ExactArgs(3), - RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) - - prove := viper.GetBool(flags.FlagProve) - node2 := viper.GetString(FlagNode2) - cid1 := viper.GetString(flags.FlagChainID) - cid2 := viper.GetString(FlagChainID2) - cliCtx2 := context.NewCLIContextIBC(cliCtx.GetFromAddress().String(), cid2, node2). - WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - header, _, err := clientutils.QueryTendermintHeader(cliCtx2) - if err != nil { - return err - } - - sourcePort, sourceChannel, clientid := args[0], args[1], args[2] - - passphrase, err := keys.GetPassphrase(viper.GetString(flags.FlagFrom)) - if err != nil { - return nil - } - - viper.Set(flags.FlagChainID, cid1) - msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid, header, cliCtx.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err := utils.CompleteAndBroadcastTx(txBldr, cliCtx, []sdk.Msg{msgUpdateClient}, passphrase) - if err != nil || !res.IsOK() { - return err - } - - viper.Set(flags.FlagChainID, cid2) - sequence := uint64(viper.GetInt(FlagSequence)) - packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), prove) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid1) - - msg := types.NewMsgRecvPacket(packetRes.Packet, []commitment.Proof{packetRes.Proof}, packetRes.ProofHeight, cliCtx.GetFromAddress()) - if err := msg.ValidateBasic(); err != nil { - return err - } - - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) - }, - } - - cmd = client.PostCommands(cmd)[0] - cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") - cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") - cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") - cmd.Flags().String(FlagSequence, "", "sequence for the packet") - cmd.Flags().String(FlagTimeout, "", "timeout for the packet") - cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") - return cmd -} +// // GetMsgRecvPacketCmd returns the command to create a MsgRecvTransferPacket transaction +// func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { +// cmd := &cobra.Command{ +// Use: "recv-packet [sending-port-id] [sending-channel-id] [client-id]", +// Short: "Creates and sends a SendPacket message", +// Args: cobra.ExactArgs(3), +// RunE: func(cmd *cobra.Command, args []string) error { +// inBuf := bufio.NewReader(cmd.InOrStdin()) +// txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) +// cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + +// prove := viper.GetBool(flags.FlagProve) +// node2 := viper.GetString(FlagNode2) +// cid1 := viper.GetString(flags.FlagChainID) +// cid2 := viper.GetString(FlagChainID2) +// cliCtx2 := context.NewCLIContextIBC(cliCtx.GetFromAddress().String(), cid2, node2). +// WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// header, _, err := clientutils.QueryTendermintHeader(cliCtx2) +// if err != nil { +// return err +// } + +// sourcePort, sourceChannel, clientid := args[0], args[1], args[2] + +// passphrase, err := keys.GetPassphrase(viper.GetString(flags.FlagFrom)) +// if err != nil { +// return nil +// } + +// viper.Set(flags.FlagChainID, cid1) +// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid, header, cliCtx.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err := utils.CompleteAndBroadcastTx(txBldr, cliCtx, []sdk.Msg{msgUpdateClient}, passphrase) +// if err != nil || !res.IsOK() { +// return err +// } + +// viper.Set(flags.FlagChainID, cid2) +// sequence := uint64(viper.GetInt(FlagSequence)) +// packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), prove) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) + +// msg := types.NewMsgRecvPacket(packetRes.Packet, []commitment.Proof{packetRes.Proof}, packetRes.ProofHeight, cliCtx.GetFromAddress()) +// if err := msg.ValidateBasic(); err != nil { +// return err +// } + +// return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) +// }, +// } + +// cmd = client.PostCommands(cmd)[0] +// cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") +// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") +// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") +// cmd.Flags().String(FlagSequence, "", "sequence for the packet") +// cmd.Flags().String(FlagTimeout, "", "timeout for the packet") +// cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") +// return cmd +// } From 2e1e0e3db3d8e700a1cc34cf429feb22feb017c7 Mon Sep 17 00:00:00 2001 From: Aditya Date: Thu, 5 Dec 2019 01:07:52 -0800 Subject: [PATCH 021/176] ICS-2 Implement Misbehavior (#5321) * ibc client evidence route * split evidence from misbehaviour * clean up client events * test misbehaviour and evidence * remove comments * remove frozen comments from demo * Update x/ibc/02-client/types/tendermint/evidence_test.go Co-Authored-By: Aditya * change evidence to detect malicious chain * remove unnecessary sort * fix evidence and persist committers to check misbehaviour * minor fixes and remove incorrect tests * add evidence tests * remove debug statements * cleanup evidence test * start misbehaviour tests * fix nondeterministic bug * add same height and next height checks in misbehaviour * fix bugs * apply fede review suggestions * finish code review changes * fix GetCommitter and write keeper-level misbehaviour tests * remove incorrect special case checking * save * final fixes * save * fix conflict * fix conflicts and add back submit misbehaviour msg * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * save * add godocs and fix test * fix test panics in other modules * Update x/ibc/02-client/keeper/client.go Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * add back aliases --- simapp/app.go | 6 +- x/evidence/exported/evidence.go | 12 +- x/ibc/02-client/alias.go | 11 +- x/ibc/02-client/client/cli/tx.go | 3 +- x/ibc/02-client/client/rest/rest.go | 3 +- x/ibc/02-client/exported/exported.go | 42 ++-- x/ibc/02-client/handler.go | 39 ++-- x/ibc/02-client/keeper/client.go | 44 +++- x/ibc/02-client/keeper/client_test.go | 111 +++++++++- x/ibc/02-client/keeper/keeper.go | 74 ++++--- x/ibc/02-client/keeper/keeper_test.go | 51 ++++- x/ibc/02-client/types/codec.go | 3 +- x/ibc/02-client/types/errors/errors.go | 22 +- x/ibc/02-client/types/events.go | 6 +- x/ibc/02-client/types/keys.go | 22 +- x/ibc/02-client/types/msgs.go | 16 +- x/ibc/02-client/types/msgs_test.go | 55 +++-- x/ibc/02-client/types/tendermint/codec.go | 3 + x/ibc/02-client/types/tendermint/committer.go | 26 +++ .../types/tendermint/consensus_state.go | 21 +- .../types/tendermint/consensus_state_test.go | 13 +- x/ibc/02-client/types/tendermint/doc.go | 4 +- x/ibc/02-client/types/tendermint/evidence.go | 106 +++++++++ .../types/tendermint/evidence_test.go | 135 ++++++++++++ x/ibc/02-client/types/tendermint/header.go | 26 +++ .../types/tendermint/misbehaviour.go | 111 ++++------ .../types/tendermint/misbehaviour_test.go | 202 +++++++++++++----- .../types/tendermint/tendermint_test.go | 3 +- .../02-client/types/tendermint/test_utils.go | 37 +--- x/ibc/03-connection/keeper/handshake_test.go | 8 +- x/ibc/03-connection/keeper/keeper_test.go | 13 +- x/ibc/04-channel/keeper/handshake_test.go | 10 +- x/ibc/04-channel/keeper/keeper_test.go | 13 +- x/ibc/20-transfer/handler_test.go | 21 +- x/ibc/20-transfer/keeper/keeper_test.go | 13 +- x/ibc/20-transfer/keeper/relay_test.go | 8 +- x/ibc/handler.go | 3 - 37 files changed, 954 insertions(+), 342 deletions(-) create mode 100644 x/ibc/02-client/types/tendermint/committer.go create mode 100644 x/ibc/02-client/types/tendermint/evidence.go create mode 100644 x/ibc/02-client/types/tendermint/evidence_test.go diff --git a/simapp/app.go b/simapp/app.go index a9b0e5f025b8..fe125305c8ea 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -24,6 +24,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/ibc" + ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" ibctransfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/params" @@ -201,8 +202,9 @@ func NewSimApp( app.cdc, keys[evidence.StoreKey], app.subspaces[evidence.ModuleName], evidence.DefaultCodespace, &app.StakingKeeper, app.SlashingKeeper, ) - evidenceRouter := evidence.NewRouter() - // TODO: Register evidence routes. + evidenceRouter := evidence.NewRouter(). + AddRoute(ibcclient.RouterKey, ibcclient.HandlerClientMisbehaviour(app.IBCKeeper.ClientKeeper)) + evidenceKeeper.SetRouter(evidenceRouter) app.EvidenceKeeper = *evidenceKeeper diff --git a/x/evidence/exported/evidence.go b/x/evidence/exported/evidence.go index 1c6adfdf8c0a..79ce2bec737f 100644 --- a/x/evidence/exported/evidence.go +++ b/x/evidence/exported/evidence.go @@ -15,11 +15,17 @@ type Evidence interface { Hash() cmn.HexBytes ValidateBasic() error - // The consensus address of the malicious validator at time of infraction - GetConsensusAddress() sdk.ConsAddress - // Height at which the infraction occurred GetHeight() int64 +} + +// ValidatorEvidence extends Evidence interface to define contract +// for evidence against malicious validators +type ValidatorEvidence interface { + Evidence + + // The consensus address of the malicious validator at time of infraction + GetConsensusAddress() sdk.ConsAddress // The total power of the malicious validator at time of infraction GetValidatorPower() int64 diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go index 00519d9da512..4713a4e77dee 100644 --- a/x/ibc/02-client/alias.go +++ b/x/ibc/02-client/alias.go @@ -61,17 +61,16 @@ var ( KeyRoot = types.KeyRoot NewMsgCreateClient = types.NewMsgCreateClient NewMsgUpdateClient = types.NewMsgUpdateClient - NewMsgSubmitMisbehaviour = types.NewMsgSubmitMisbehaviour + NewMsgSubmitMibehaviour = types.NewMsgSubmitMisbehaviour NewQueryClientStateParams = types.NewQueryClientStateParams NewQueryCommitmentRootParams = types.NewQueryCommitmentRootParams NewClientState = types.NewClientState // variable aliases - SubModuleCdc = types.SubModuleCdc - EventTypeCreateClient = types.EventTypeCreateClient - EventTypeUpdateClient = types.EventTypeUpdateClient - EventTypeSubmitMisbehaviour = types.EventTypeSubmitMisbehaviour - AttributeValueCategory = types.AttributeValueCategory + SubModuleCdc = types.SubModuleCdc + EventTypeCreateClient = types.EventTypeCreateClient + EventTypeUpdateClient = types.EventTypeUpdateClient + AttributeValueCategory = types.AttributeValueCategory ) type ( diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 197f7271b011..9e666f8f926b 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -16,6 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ) @@ -133,7 +134,7 @@ $ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 clientID := args[0] - var evidence exported.Evidence + var evidence evidenceexported.Evidence if err := cdc.UnmarshalJSON([]byte(args[1]), &evidence); err != nil { fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") diff --git a/x/ibc/02-client/client/rest/rest.go b/x/ibc/02-client/client/rest/rest.go index fb832f63a69a..51f8ce762bcb 100644 --- a/x/ibc/02-client/client/rest/rest.go +++ b/x/ibc/02-client/client/rest/rest.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" ) @@ -35,5 +36,5 @@ type UpdateClientReq struct { // SubmitMisbehaviourReq defines the properties of a submit misbehaviour request's body. type SubmitMisbehaviourReq struct { BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - Evidence exported.Evidence `json:"evidence" yaml:"evidence"` + Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` } diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index e611b94301fa..9a5f2bc2e89f 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -4,10 +4,7 @@ import ( "encoding/json" "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" - - cmn "github.com/tendermint/tendermint/libs/common" - + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -20,41 +17,32 @@ type ConsensusState interface { // which is used for key-value pair verification. GetRoot() commitment.RootI + // GetCommitter returns the committer that committed the consensus state + GetCommitter() Committer + // CheckValidityAndUpdateState returns the updated consensus state // only if the header is a descendent of this consensus state. CheckValidityAndUpdateState(Header) (ConsensusState, error) } -// Evidence from ADR 009: Evidence Module -// TODO: use evidence module interface once merged -type Evidence interface { - Route() string - Type() string - String() string - Hash() cmn.HexBytes - ValidateBasic() sdk.Error - - // The consensus address of the malicious validator at time of infraction - GetConsensusAddress() sdk.ConsAddress - - // Height at which the infraction occurred - GetHeight() int64 - - // The total power of the malicious validator at time of infraction - GetValidatorPower() int64 - - // The total validator set power at time of infraction - GetTotalPower() int64 -} - // Misbehaviour defines a specific consensus kind and an evidence type Misbehaviour interface { ClientType() ClientType - Evidence() Evidence + GetEvidence() evidenceexported.Evidence } // Header is the consensus state update information type Header interface { + ClientType() ClientType + GetCommitter() Committer + GetHeight() uint64 +} + +// Committer defines the type that is responsible for +// updating the consensusState at a given height +// +// In Tendermint, this is the ValidatorSet at the given height +type Committer interface { ClientType() ClientType GetHeight() uint64 } diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index 1b1e1807b54a..595656a86c20 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -1,8 +1,13 @@ package client import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" - exported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/evidence" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" ) // HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient @@ -12,7 +17,6 @@ func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.R return sdk.ResultFromError(ErrInvalidClientType(DefaultCodespace, err.Error())) } - // TODO: should we create an event with the new client state id ? _, err = k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) if err != nil { return sdk.ResultFromError(err) @@ -55,24 +59,17 @@ func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) sdk.R return sdk.Result{Events: ctx.EventManager().Events()} } -// HandleMsgSubmitMisbehaviour defines the sdk.Handler for MsgSubmitMisbehaviour -func HandleMsgSubmitMisbehaviour(ctx sdk.Context, k Keeper, msg MsgSubmitMisbehaviour) sdk.Result { - err := k.CheckMisbehaviourAndUpdateState(ctx, msg.ClientID, msg.Evidence) - if err != nil { - return sdk.ResultFromError(err) - } +// HandlerClientMisbehaviour defines the Evidence module handler for submitting a +// light client misbehaviour. +func HandlerClientMisbehaviour(k Keeper) evidence.Handler { + return func(ctx sdk.Context, evidence evidenceexported.Evidence) error { + switch e := evidence.(type) { + case tendermint.Misbehaviour: + return k.CheckMisbehaviourAndUpdateState(ctx, evidence) - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - EventTypeSubmitMisbehaviour, - sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), - ), - sdk.NewEvent( - sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), - sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), - ), - }) - - return sdk.Result{Events: ctx.EventManager().Events()} + default: + errMsg := fmt.Sprintf("unrecognized IBC client evidence type: %T", e) + return sdk.ErrUnknownRequest(errMsg) + } + } } diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index 3ee7a53143bf..9b72ef4a2c2c 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -5,9 +5,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" ) // CreateClient creates a new client state and populates it with a given consensus @@ -27,6 +29,7 @@ func (k Keeper) CreateClient( } clientState := k.initialize(ctx, clientID, consensusState) + k.SetCommitter(ctx, clientID, consensusState.GetHeight(), consensusState.GetCommitter()) k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) k.SetClientState(ctx, clientState) k.SetClientType(ctx, clientID, clientType) @@ -66,6 +69,7 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H } k.SetConsensusState(ctx, clientID, consensusState) + k.SetCommitter(ctx, clientID, consensusState.GetHeight(), consensusState.GetCommitter()) k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, consensusState.GetHeight())) return nil @@ -73,23 +77,47 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H // CheckMisbehaviourAndUpdateState checks for client misbehaviour and freezes the // client if so. -func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, clientID string, evidence exported.Evidence) error { - clientState, found := k.GetClientState(ctx, clientID) +// +// NOTE: In the first implementation, only Tendermint misbehaviour evidence is +// supported. +func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, evidence evidenceexported.Evidence) error { + misbehaviour, ok := evidence.(tendermint.Misbehaviour) + if !ok { + return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint") + } + + clientState, found := k.GetClientState(ctx, misbehaviour.ClientID) if !found { - sdk.ResultFromError(errors.ErrClientNotFound(k.codespace, clientID)) + return errors.ErrClientNotFound(k.codespace, misbehaviour.ClientID) } - err := k.checkMisbehaviour(ctx, evidence) - if err != nil { - return err + committer, found := k.GetCommitter(ctx, misbehaviour.ClientID, uint64(misbehaviour.GetHeight())) + if !found { + return errors.ErrCommitterNotFound(k.codespace, fmt.Sprintf("committer not found for height %d", misbehaviour.GetHeight())) + } + tmCommitter, ok := committer.(tendermint.Committer) + if !ok { + return errors.ErrInvalidCommitter(k.codespace, "committer type is not Tendermint") + } + + if err := tendermint.CheckMisbehaviour(tmCommitter, misbehaviour); err != nil { + return errors.ErrInvalidEvidence(k.codespace, err.Error()) } - clientState, err = k.freeze(ctx, clientState) + clientState, err := k.freeze(ctx, clientState) if err != nil { return err } k.SetClientState(ctx, clientState) - k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", clientID)) + k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", misbehaviour.ClientID)) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeSubmitMisbehaviour, + sdk.NewAttribute(types.AttributeKeyClientID, misbehaviour.ClientID), + ), + ) + return nil } diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index cfc69e2f2245..c99757d3eacb 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "bytes" "fmt" "github.com/stretchr/testify/require" @@ -19,7 +20,7 @@ const ( func (suite *KeeperTestSuite) TestCreateClient() { // Test Valid CreateClient state, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) - require.Nil(suite.T(), err, "CreateClient failed") + suite.NoError(err, "CreateClient failed") // Test ClientState stored correctly expectedState := types.State{ @@ -36,7 +37,7 @@ func (suite *KeeperTestSuite) TestCreateClient() { // Test that trying to CreateClient on existing client fails _, err = suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) - require.NotNil(suite.T(), err, "CreateClient on existing client: %s passed", testClientID) + suite.Error(err, "CreateClient on existing client: %s passed", testClientID) } func (suite *KeeperTestSuite) TestUpdateClient() { @@ -61,10 +62,10 @@ func (suite *KeeperTestSuite) TestUpdateClient() { suite.keeper.SetClientState(suite.ctx, clientState) }, true}, {"past height", func() { - suite.header = tendermint.MakeHeader(2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = tendermint.MakeHeader("gaia", 2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) }, true}, {"validatorHash incorrect", func() { - suite.header = tendermint.MakeHeader(4, altValSet, suite.valSet, altSigners) + suite.header = tendermint.MakeHeader("gaia", 4, altValSet, suite.valSet, altSigners) }, true}, {"nextHash incorrect", func() { suite.header.NextValidatorSet = altValSet @@ -79,28 +80,30 @@ func (suite *KeeperTestSuite) TestUpdateClient() { } for _, tc := range cases { + tc := tc // pin for scopelint suite.Run(fmt.Sprintf("Case %s", tc.name), func() { // Reset suite on each subtest suite.SetupTest() _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) - require.Nil(suite.T(), err, "CreateClient failed") + suite.NoError(err, "CreateClient failed") tc.malleate() err = suite.keeper.UpdateClient(suite.ctx, testClientID, suite.header) retrievedConsState, _ := suite.keeper.GetConsensusState(suite.ctx, testClientID) tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) + tmConsState.ValidatorSet.TotalVotingPower() tmConsState.NextValidatorSet.TotalVotingPower() retrievedRoot, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()+1) if tc.expErr { - require.NotNil(suite.T(), err, "Invalid UpdateClient passed", tc.name) + suite.Error(err, "Invalid UpdateClient passed", tc.name) // require no state changes occurred require.Equal(suite.T(), suite.consensusState, tmConsState, "Consensus state changed after invalid UpdateClient") require.Nil(suite.T(), retrievedRoot, "Root added for new height after invalid UpdateClient") } else { - require.Nil(suite.T(), err, "Valid UpdateClient failed", tc.name) + suite.NoError(err, "Valid UpdateClient failed", tc.name) // require state changes were performed correctly require.Equal(suite.T(), suite.header.GetHeight(), retrievedConsState.GetHeight(), "height not updated correctly") @@ -112,3 +115,97 @@ func (suite *KeeperTestSuite) TestUpdateClient() { }) } } + +func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} + } + + altSigners := []tmtypes.PrivValidator{altPrivVal} + + _, err := suite.keeper.CreateClient(suite.ctx, "gaiamainnet", exported.Tendermint, suite.consensusState) + suite.NoError(err, "CreateClient failed") + + testCases := []struct { + name string + evidence *tendermint.Evidence + clientID string + expErr bool + }{ + { + "trusting period misbehavior should pass", + &tendermint.Evidence{ + Header1: tendermint.MakeHeader("gaia", 5, bothValSet, suite.valSet, bothSigners), + Header2: tendermint.MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + "gaiamainnet", + false, + }, + { + "first valset has too much change", + &tendermint.Evidence{ + Header1: tendermint.MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + Header2: tendermint.MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "second valset has too much change", + &tendermint.Evidence{ + Header1: tendermint.MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + Header2: tendermint.MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "both valsets have too much change", + &tendermint.Evidence{ + Header1: tendermint.MakeHeader("gaia", 5, altValSet, altValSet, altSigners), + Header2: tendermint.MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + } + + for _, tc := range testCases { + tc := tc // pin for scopelint + suite.Run(tc.name, func() { + misbehaviour := tendermint.Misbehaviour{ + Evidence: tc.evidence, + ClientID: tc.clientID, + } + + err = suite.keeper.CheckMisbehaviourAndUpdateState(suite.ctx, misbehaviour) + + if tc.expErr { + suite.Error(err, "CheckMisbehaviour passed unexpectedly") + } else { + suite.NoError(err, "CheckMisbehaviour failed unexpectedly: %v", err) + } + + // reset Frozen flag to false + clientState, _ := suite.keeper.GetClientState(suite.ctx, tc.clientID) + clientState.Frozen = false + suite.keeper.SetClientState(suite.ctx, clientState) + }) + } +} diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index 3911c1f98f0e..e5c4feb26263 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -12,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -119,6 +118,32 @@ func (k Keeper) SetVerifiedRoot(ctx sdk.Context, clientID string, height uint64, store.Set(types.KeyRoot(clientID, height), bz) } +// GetCommitter will get the Committer of a particular client at the oldest height +// that is less than or equal to the height passed in +func (k Keeper) GetCommitter(ctx sdk.Context, clientID string, height uint64) (exported.Committer, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + + var committer exported.Committer + + // TODO: Replace this for-loop with a ReverseIterator for efficiency + for i := height; i > 0; i-- { + bz := store.Get(types.KeyCommitter(clientID, i)) + if bz != nil { + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &committer) + return committer, true + } + } + return nil, false +} + +// SetCommitter sets a committer from a particular height to +// a particular client +func (k Keeper) SetCommitter(ctx sdk.Context, clientID string, height uint64, committer exported.Committer) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(committer) + store.Set(types.KeyCommitter(clientID, height), bz) +} + // State returns a new client state with a given id as defined in // https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#example-implementation func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) types.State { @@ -127,24 +152,6 @@ func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState expo return clientState } -func (k Keeper) checkMisbehaviour(ctx sdk.Context, evidence exported.Evidence) error { - switch evidence.Type() { - case exported.ClientTypeTendermint: - var tmEvidence tendermint.Evidence - _, ok := evidence.(tendermint.Evidence) - if !ok { - return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint") - } - err := tendermint.CheckMisbehaviour(tmEvidence) - if err != nil { - return errors.ErrInvalidEvidence(k.codespace, err.Error()) - } - default: - panic(fmt.Sprintf("unregistered evidence type: %s", evidence.Type())) - } - return nil -} - // freeze updates the state of the client in the event of a misbehaviour func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) { if clientState.Frozen { @@ -164,12 +171,14 @@ func (k Keeper) VerifyMembership( path commitment.PathI, value []byte, ) bool { - // XXX: commented out for demo - /* - if clientState.Frozen { - return false - } - */ + clientState, found := k.GetClientState(ctx, clientID) + if !found { + return false + } + + if clientState.Frozen { + return false + } root, found := k.GetVerifiedRoot(ctx, clientID, height) if !found { @@ -187,12 +196,15 @@ func (k Keeper) VerifyNonMembership( proof commitment.ProofI, path commitment.PathI, ) bool { - // XXX: commented out for demo - /* - if clientState.Frozen { - return false - } - */ + clientState, found := k.GetClientState(ctx, clientID) + if !found { + return false + } + + if clientState.Frozen { + return false + } + root, found := k.GetVerifiedRoot(ctx, clientID, height) if !found { return false diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index da81be0edb12..da79777dae50 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -4,6 +4,7 @@ import ( "testing" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/tmhash" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" @@ -48,12 +49,13 @@ func (suite *KeeperTestSuite) SetupTest() { validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - suite.header = tendermint.MakeHeader(4, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = tendermint.MakeHeader("gaia", 4, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.consensusState = tendermint.ConsensusState{ ChainID: testClientID, Height: 3, Root: commitment.NewRoot([]byte("hash")), + ValidatorSet: suite.valSet, NextValidatorSet: suite.valSet, } } @@ -87,6 +89,7 @@ func (suite *KeeperTestSuite) TestSetConsensusState() { require.True(suite.T(), ok, "GetConsensusState failed") tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) // force recalculation of unexported totalVotingPower so we can compare consensusState + tmConsState.ValidatorSet.TotalVotingPower() tmConsState.NextValidatorSet.TotalVotingPower() require.Equal(suite.T(), suite.consensusState, tmConsState, "ConsensusState not stored correctly") } @@ -100,3 +103,49 @@ func (suite *KeeperTestSuite) TestSetVerifiedRoot() { require.True(suite.T(), ok, "GetVerifiedRoot failed") require.Equal(suite.T(), root, retrievedRoot, "Root stored incorrectly") } + +func (suite KeeperTestSuite) TestSetCommitter() { + committer := tendermint.Committer{ + ValidatorSet: suite.valSet, + Height: 3, + NextValSetHash: suite.valSet.Hash(), + } + nextCommitter := tendermint.Committer{ + ValidatorSet: suite.valSet, + Height: 6, + NextValSetHash: tmhash.Sum([]byte("next_hash")), + } + + suite.keeper.SetCommitter(suite.ctx, "gaia", 3, committer) + suite.keeper.SetCommitter(suite.ctx, "gaia", 6, nextCommitter) + + // fetch the commiter on each respective height + for i := 0; i < 3; i++ { + committer, ok := suite.keeper.GetCommitter(suite.ctx, "gaia", uint64(i)) + require.False(suite.T(), ok, "GetCommitter passed on nonexistent height: %d", i) + require.Nil(suite.T(), committer, "GetCommitter returned committer on nonexistent height: %d", i) + } + + for i := 3; i < 6; i++ { + recv, ok := suite.keeper.GetCommitter(suite.ctx, "gaia", uint64(i)) + tmRecv, _ := recv.(tendermint.Committer) + if tmRecv.ValidatorSet != nil { + // update validator set's power + tmRecv.ValidatorSet.TotalVotingPower() + } + require.True(suite.T(), ok, "GetCommitter failed on existing height: %d", i) + require.Equal(suite.T(), committer, recv, "GetCommitter returned committer on nonexistent height: %d", i) + } + + for i := 6; i < 9; i++ { + recv, ok := suite.keeper.GetCommitter(suite.ctx, "gaia", uint64(i)) + tmRecv, _ := recv.(tendermint.Committer) + if tmRecv.ValidatorSet != nil { + // update validator set's power + tmRecv.ValidatorSet.TotalVotingPower() + } + require.True(suite.T(), ok, "GetCommitter failed on existing height: %d", i) + require.Equal(suite.T(), nextCommitter, recv, "GetCommitter returned committer on nonexistent height: %d", i) + } + +} diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index d595f583baa9..ed923f5cbc89 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -12,7 +12,7 @@ var SubModuleCdc *codec.Codec // RegisterCodec registers the IBC client interfaces and types func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*exported.ConsensusState)(nil), nil) - cdc.RegisterInterface((*exported.Evidence)(nil), nil) + cdc.RegisterInterface((*exported.Committer)(nil), nil) cdc.RegisterInterface((*exported.Header)(nil), nil) cdc.RegisterInterface((*exported.Misbehaviour)(nil), nil) @@ -20,6 +20,7 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) cdc.RegisterConcrete(tendermint.ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) + cdc.RegisterConcrete(tendermint.Committer{}, "ibc/client/tendermint/Committer", nil) cdc.RegisterConcrete(tendermint.Header{}, "ibc/client/tendermint/Header", nil) cdc.RegisterConcrete(tendermint.Evidence{}, "ibc/client/tendermint/Evidence", nil) diff --git a/x/ibc/02-client/types/errors/errors.go b/x/ibc/02-client/types/errors/errors.go index 1e9510df6c44..1a7272ca1fcb 100644 --- a/x/ibc/02-client/types/errors/errors.go +++ b/x/ibc/02-client/types/errors/errors.go @@ -19,8 +19,10 @@ const ( CodeClientTypeNotFound sdk.CodeType = 205 CodeInvalidClientType sdk.CodeType = 206 CodeRootNotFound sdk.CodeType = 207 - CodeInvalidHeader sdk.CodeType = 207 + CodeInvalidHeader sdk.CodeType = 208 CodeInvalidEvidence sdk.CodeType = 209 + CodeCommitterNotFound sdk.CodeType = 210 + CodeInvalidCommitter sdk.CodeType = 211 ) // ErrClientExists implements sdk.Error @@ -112,3 +114,21 @@ func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) error { fmt.Sprintf("invalid evidence: %s", msg), ) } + +// ErrCommitterNotFound implements sdk.Error +func ErrCommitterNotFound(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeCommitterNotFound), + fmt.Sprintf("invalid evidence: %s", msg), + ) +} + +// ErrInvalidEvidence implements sdk.Error +func ErrInvalidCommitter(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidCommitter), + fmt.Sprintf("invalid evidence: %s", msg), + ) +} diff --git a/x/ibc/02-client/types/events.go b/x/ibc/02-client/types/events.go index 7e7f9a508cee..6b02bfa5eaf8 100644 --- a/x/ibc/02-client/types/events.go +++ b/x/ibc/02-client/types/events.go @@ -13,9 +13,9 @@ const ( // IBC client events vars var ( - EventTypeCreateClient = MsgCreateClient{}.Type() - EventTypeUpdateClient = MsgUpdateClient{}.Type() - EventTypeSubmitMisbehaviour = MsgSubmitMisbehaviour{}.Type() + EventTypeCreateClient = TypeMsgCreateClient + EventTypeUpdateClient = TypeMsgUpdateClient + EventTypeSubmitMisbehaviour = TypeClientMisbehaviour AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) ) diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go index acebca3ee09a..6dc55a77baf0 100644 --- a/x/ibc/02-client/types/keys.go +++ b/x/ibc/02-client/types/keys.go @@ -6,16 +6,16 @@ import ( const ( // SubModuleName defines the IBC client name - SubModuleName = "client" + SubModuleName string = "client" // StoreKey is the store key string for IBC client - StoreKey = SubModuleName + StoreKey string = SubModuleName // RouterKey is the message route for IBC client - RouterKey = SubModuleName + RouterKey string = SubModuleName // QuerierRoute is the querier route for IBC client - QuerierRoute = SubModuleName + QuerierRoute string = SubModuleName ) // KVStore key prefixes @@ -44,11 +44,17 @@ func ConsensusStatePath(clientID string) string { } // RootPath takes an Identifier and returns a Path under which to -// store the consensus state of a client. +// store the root for a particular height of a client. func RootPath(clientID string, height uint64) string { return fmt.Sprintf("clients/%s/roots/%d", clientID, height) } +// CommitterPath takes an Identifier and returns a Path under which +// to store the committer of a client at a particular height +func CommitterPath(clientID string, height uint64) string { + return fmt.Sprintf("clients/%s/committer/%d", clientID, height) +} + // KeyClientState returns the store key for a particular client state func KeyClientState(clientID string) []byte { return []byte(ClientStatePath(clientID)) @@ -70,3 +76,9 @@ func KeyConsensusState(clientID string) []byte { func KeyRoot(clientID string, height uint64) []byte { return []byte(RootPath(clientID, height)) } + +// KeyValidatorSet returns the store key for a validator of a particular +// client at a given height. Key => clientID||height +func KeyCommitter(clientID string, height uint64) []byte { + return []byte(CommitterPath(clientID, height)) +} diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index f09e126666ff..6f0aa7959ac7 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -2,12 +2,20 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) +// Message types for the IBC client +const ( + TypeMsgCreateClient string = "create_client" + TypeMsgUpdateClient string = "update_client" + TypeClientMisbehaviour string = "client_misbehaviour" +) + var _ sdk.Msg = MsgCreateClient{} // MsgCreateClient defines a message to create an IBC client @@ -35,7 +43,7 @@ func (msg MsgCreateClient) Route() string { // Type implements sdk.Msg func (msg MsgCreateClient) Type() string { - return "create_client" + return TypeMsgCreateClient } // ValidateBasic implements sdk.Msg @@ -90,7 +98,7 @@ func (msg MsgUpdateClient) Route() string { // Type implements sdk.Msg func (msg MsgUpdateClient) Type() string { - return "update_client" + return TypeMsgUpdateClient } // ValidateBasic implements sdk.Msg @@ -120,12 +128,12 @@ func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress { // MsgSubmitMisbehaviour defines a message to update an IBC client type MsgSubmitMisbehaviour struct { ClientID string `json:"id" yaml:"id"` - Evidence exported.Evidence `json:"evidence" yaml:"evidence"` + Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` Signer sdk.AccAddress `json:"address" yaml:"address"` } // NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance -func NewMsgSubmitMisbehaviour(id string, evidence exported.Evidence, signer sdk.AccAddress) MsgSubmitMisbehaviour { +func NewMsgSubmitMisbehaviour(id string, evidence evidenceexported.Evidence, signer sdk.AccAddress) MsgSubmitMisbehaviour { return MsgSubmitMisbehaviour{ ClientID: id, Evidence: evidence, diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go index f7e022ecc89c..b29633420ed4 100644 --- a/x/ibc/02-client/types/msgs_test.go +++ b/x/ibc/02-client/types/msgs_test.go @@ -9,11 +9,38 @@ import ( cmn "github.com/tendermint/tendermint/libs/common" sdk "github.com/cosmos/cosmos-sdk/types" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" ) +var _ evidenceexported.Evidence = mockEvidence{} +var _ evidenceexported.Evidence = mockBadEvidence{} + +const mockStr = "mock" + +// mock GoodEvidence +type mockEvidence struct{} + +// Implement Evidence interface +func (me mockEvidence) Route() string { return mockStr } +func (me mockEvidence) Type() string { return mockStr } +func (me mockEvidence) String() string { return mockStr } +func (me mockEvidence) Hash() cmn.HexBytes { return cmn.HexBytes([]byte(mockStr)) } +func (me mockEvidence) ValidateBasic() error { return nil } +func (me mockEvidence) GetHeight() int64 { return 3 } + +// mock bad evidence +type mockBadEvidence struct { + mockEvidence +} + +// Override ValidateBasic +func (mbe mockBadEvidence) ValidateBasic() error { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence") +} + func TestMsgCreateClientValidateBasic(t *testing.T) { cs := tendermint.ConsensusState{} privKey := secp256k1.GenPrivKey() @@ -79,34 +106,6 @@ func TestMsgUpdateClient(t *testing.T) { } } -var _ exported.Evidence = mockEvidence{} - -const mockStr = "mock" - -// mock GoodEvidence -type mockEvidence struct{} - -// Implement Evidence interface -func (me mockEvidence) Route() string { return mockStr } -func (me mockEvidence) Type() string { return mockStr } -func (me mockEvidence) String() string { return mockStr } -func (me mockEvidence) Hash() cmn.HexBytes { return cmn.HexBytes([]byte(mockStr)) } -func (me mockEvidence) ValidateBasic() sdk.Error { return nil } -func (me mockEvidence) GetConsensusAddress() sdk.ConsAddress { return sdk.ConsAddress{} } -func (me mockEvidence) GetHeight() int64 { return 3 } -func (me mockEvidence) GetValidatorPower() int64 { return 3 } -func (me mockEvidence) GetTotalPower() int64 { return 5 } - -// mock bad evidence -type mockBadEvidence struct { - mockEvidence -} - -// Override ValidateBasic -func (mbe mockBadEvidence) ValidateBasic() sdk.Error { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence")) -} - func TestMsgSubmitMisbehaviour(t *testing.T) { privKey := secp256k1.GenPrivKey() signer := sdk.AccAddress(privKey.PubKey().Address()) diff --git a/x/ibc/02-client/types/tendermint/codec.go b/x/ibc/02-client/types/tendermint/codec.go index 46814fec2479..a546ed313cef 100644 --- a/x/ibc/02-client/types/tendermint/codec.go +++ b/x/ibc/02-client/types/tendermint/codec.go @@ -8,8 +8,11 @@ var SubModuleCdc = codec.New() // RegisterCodec registers the Tendermint types func RegisterCodec(cdc *codec.Codec) { + codec.RegisterCrypto(cdc) + cdc.RegisterConcrete(Committer{}, "ibc/client/tendermint/Committer", nil) cdc.RegisterConcrete(ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) cdc.RegisterConcrete(Header{}, "ibc/client/tendermint/Header", nil) + cdc.RegisterConcrete(Misbehaviour{}, "ibc/client/tendermint/Misbehaviour", nil) cdc.RegisterConcrete(Evidence{}, "ibc/client/tendermint/Evidence", nil) } diff --git a/x/ibc/02-client/types/tendermint/committer.go b/x/ibc/02-client/types/tendermint/committer.go new file mode 100644 index 000000000000..ccf798feb570 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/committer.go @@ -0,0 +1,26 @@ +package tendermint + +import ( + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" +) + +var _ exported.Committer = Committer{} + +// Committer definites a Tendermint Committer +type Committer struct { + *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` + Height uint64 `json:"height" yaml:"height"` + NextValSetHash []byte `json:"next_valset_hash" yaml:"next_valset_hash"` +} + +// Implement exported.Committer interface +func (c Committer) ClientType() exported.ClientType { + return exported.Tendermint +} + +// Implement exported.Committer interface +func (c Committer) GetHeight() uint64 { + return c.Height +} diff --git a/x/ibc/02-client/types/tendermint/consensus_state.go b/x/ibc/02-client/types/tendermint/consensus_state.go index f57887045a2f..25c2f8d990f8 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state.go +++ b/x/ibc/02-client/types/tendermint/consensus_state.go @@ -20,6 +20,7 @@ type ConsensusState struct { ChainID string `json:"chain_id" yaml:"chain_id"` Height uint64 `json:"height" yaml:"height"` // NOTE: defined as 'sequence' in the spec Root commitment.RootI `json:"root" yaml:"root"` + ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` // contains the PublicKey } @@ -38,6 +39,15 @@ func (cs ConsensusState) GetRoot() commitment.RootI { return cs.Root } +// GetCommitter returns the commmitter that committed the ConsensusState +func (cs ConsensusState) GetCommitter() exported.Committer { + return Committer{ + ValidatorSet: cs.ValidatorSet, + Height: cs.Height, + NextValSetHash: cs.NextValidatorSet.Hash(), + } +} + // CheckValidityAndUpdateState checks if the provided header is valid and updates // the consensus state if appropriate func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (exported.ConsensusState, error) { @@ -64,6 +74,11 @@ func (cs ConsensusState) checkValidity(header Header) error { ) } + // basic consistency check + if err := header.ValidateBasic(cs.ChainID); err != nil { + return err + } + // check if the hash from the consensus set and header // matches nextHash := cs.NextValidatorSet.Hash() @@ -78,11 +93,6 @@ func (cs ConsensusState) checkValidity(header Header) error { return lerr.ErrUnexpectedValidators(header.NextValidatorsHash, nextHash) } - // basic consistency check - if err := header.ValidateBasic(cs.ChainID); err != nil { - return err - } - // abortTransactionUnless(consensusState.publicKey.verify(header.signature)) return header.ValidatorSet.VerifyFutureCommit( cs.NextValidatorSet, cs.ChainID, header.Commit.BlockID, header.Height, header.Commit, @@ -93,6 +103,7 @@ func (cs ConsensusState) checkValidity(header Header) error { func (cs ConsensusState) update(header Header) ConsensusState { cs.Height = header.GetHeight() cs.Root = commitment.NewRoot(header.AppHash) + cs.ValidatorSet = header.ValidatorSet cs.NextValidatorSet = header.NextValidatorSet return cs } diff --git a/x/ibc/02-client/types/tendermint/consensus_state_test.go b/x/ibc/02-client/types/tendermint/consensus_state_test.go index 07c1015a3067..778de45fa3a8 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state_test.go +++ b/x/ibc/02-client/types/tendermint/consensus_state_test.go @@ -9,12 +9,12 @@ import ( func (suite *TendermintTestSuite) TestCheckValidity() { // valid header err := suite.cs.checkValidity(suite.header) - require.Nil(suite.T(), err, "validity failed") + suite.NoError(err, "validity failed") // switch out header ValidatorsHash suite.header.ValidatorsHash = tmhash.Sum([]byte("hello")) err = suite.cs.checkValidity(suite.header) - require.NotNil(suite.T(), err, "validator hash is wrong") + suite.Error(err, "validator hash is wrong") // reset suite and make header.NextValidatorSet different // from NextValidatorSetHash @@ -23,13 +23,13 @@ func (suite *TendermintTestSuite) TestCheckValidity() { val := tmtypes.NewValidator(privVal.GetPubKey(), 5) suite.header.NextValidatorSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) err = suite.cs.checkValidity(suite.header) - require.NotNil(suite.T(), err, "header's next validator set is not consistent with hash") + suite.Error(err, "header's next validator set is not consistent with hash") // reset and make header fail validatebasic suite.SetupTest() suite.header.ChainID = "not_gaia" err = suite.cs.checkValidity(suite.header) - require.NotNil(suite.T(), err, "invalid header should fail ValidateBasic") + suite.Error(err, "invalid header should fail ValidateBasic") } func (suite *TendermintTestSuite) TestCheckUpdate() { @@ -40,13 +40,14 @@ func (suite *TendermintTestSuite) TestCheckUpdate() { require.Equal(suite.T(), suite.header.GetHeight(), cs.GetHeight(), "height not updated") require.Equal(suite.T(), suite.header.AppHash.Bytes(), cs.GetRoot().GetHash(), "root not updated") tmCS, _ := cs.(ConsensusState) - require.Equal(suite.T(), suite.header.NextValidatorSet, tmCS.NextValidatorSet, "validator set did not update") + require.Equal(suite.T(), suite.header.ValidatorSet, tmCS.ValidatorSet, "validator set did not update") + require.Equal(suite.T(), suite.header.NextValidatorSet, tmCS.NextValidatorSet, "next validator set did not update") // make header invalid so update should be unsuccessful suite.SetupTest() suite.header.ChainID = "not_gaia" cs, err = suite.cs.CheckValidityAndUpdateState(suite.header) - require.NotNil(suite.T(), err) + suite.Error(err) require.Nil(suite.T(), cs) } diff --git a/x/ibc/02-client/types/tendermint/doc.go b/x/ibc/02-client/types/tendermint/doc.go index f0e27c7696a7..26aa430a82da 100644 --- a/x/ibc/02-client/types/tendermint/doc.go +++ b/x/ibc/02-client/types/tendermint/doc.go @@ -1,5 +1,5 @@ /* -Package tendermint implements a concrete `ConsensusState`, `Header` and `Equivocation` -for the Tendermint consensus algorithm. +Package tendermint implements a concrete `ConsensusState`, `Header`, +`Misbehaviour` and `Equivocation` types for the Tendermint consensus light client. */ package tendermint diff --git a/x/ibc/02-client/types/tendermint/evidence.go b/x/ibc/02-client/types/tendermint/evidence.go new file mode 100644 index 000000000000..a8d1154a27ae --- /dev/null +++ b/x/ibc/02-client/types/tendermint/evidence.go @@ -0,0 +1,106 @@ +package tendermint + +import ( + "fmt" + + yaml "gopkg.in/yaml.v2" + + "github.com/tendermint/tendermint/crypto/tmhash" + cmn "github.com/tendermint/tendermint/libs/common" + tmtypes "github.com/tendermint/tendermint/types" + + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" +) + +var _ evidenceexported.Evidence = Evidence{} + +// Evidence is a wrapper over tendermint's DuplicateVoteEvidence +// that implements Evidence interface expected by ICS-02 +type Evidence struct { + Header1 Header `json:"header1" yaml:"header1"` + Header2 Header `json:"header2" yaml:"header2"` + ChainID string `json:"chain_id" yaml:"chain_id"` +} + +// Route implements Evidence interface +func (ev Evidence) Route() string { + return "client" +} + +// Type implements Evidence interface +func (ev Evidence) Type() string { + return "client_misbehaviour" +} + +// String implements Evidence interface +func (ev Evidence) String() string { + bz, err := yaml.Marshal(ev) + if err != nil { + panic(err) + } + return string(bz) +} + +// Hash implements Evidence interface +func (ev Evidence) Hash() cmn.HexBytes { + return tmhash.Sum(SubModuleCdc.MustMarshalBinaryBare(ev)) +} + +// GetHeight returns the height at which misbehaviour occurred +func (ev Evidence) GetHeight() int64 { + return ev.Header1.Height +} + +// ValidateBasic implements Evidence interface +func (ev Evidence) ValidateBasic() error { + // ValidateBasic on both validators + if err := ev.Header1.ValidateBasic(ev.ChainID); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Header1 failed ValidateBasic: %v", err)) + } + if err := ev.Header2.ValidateBasic(ev.ChainID); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Header2 failed ValidateBasic: %v", err)) + } + // Ensure that Heights are the same + if ev.Header1.Height != ev.Header2.Height { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "headers in evidence are on different heights") + } + // Ensure that Commit Hashes are different + if ev.Header1.Commit.BlockID.Equals(ev.Header2.Commit.BlockID) { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "Headers commit to same blockID") + } + + if err1 := ValidCommit(ev.ChainID, ev.Header1.Commit, ev.Header1.ValidatorSet); err1 != nil { + return err1 + } + if err2 := ValidCommit(ev.ChainID, ev.Header2.Commit, ev.Header2.ValidatorSet); err2 != nil { + return err2 + } + + return nil +} + +// ValidCommit checks if the given commit is a valid commit from the passed-in validatorset +// +// CommitToVoteSet will panic if the commit cannot be converted to a valid voteset given the validatorset +// This implies that someone tried to submit evidence that wasn't actually committed by the validatorset +// thus we should return an error here and reject the evidence rather than panicing. +func ValidCommit(chainID string, commit *tmtypes.Commit, valSet *tmtypes.ValidatorSet) (err error) { + defer func() { + if r := recover(); r != nil { + err = errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("invalid commit: %v", r)) + } + }() + + // Convert commits to vote-sets given the validator set so we can check if they both have 2/3 power + voteSet := tmtypes.CommitToVoteSet(chainID, commit, valSet) + + blockID, ok := voteSet.TwoThirdsMajority() + + // Check that ValidatorSet did indeed commit to blockID in Commit + if !ok || !blockID.Equals(commit.BlockID) { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "ValidatorSet did not commit to Header1") + } + + return nil +} diff --git a/x/ibc/02-client/types/tendermint/evidence_test.go b/x/ibc/02-client/types/tendermint/evidence_test.go new file mode 100644 index 000000000000..09f40499b458 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/evidence_test.go @@ -0,0 +1,135 @@ +package tendermint + +import ( + "bytes" + + "github.com/tendermint/tendermint/crypto/tmhash" + tmtypes "github.com/tendermint/tendermint/types" +) + +func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + + signers := []tmtypes.PrivValidator{suite.privVal} + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} + } + + altSigners := []tmtypes.PrivValidator{altPrivVal} + + testCases := []struct { + name string + evidence Evidence + malleateEvidence func(ev *Evidence) + expErr bool + }{ + { + "valid evidence", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 4, suite.valSet, bothValSet, signers), + ChainID: "gaia", + }, + func(ev *Evidence) {}, + false, + }, + { + "wrong chainID on header1", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("ethermint", 4, suite.valSet, bothValSet, signers), + ChainID: "ethermint", + }, + func(ev *Evidence) {}, + true, + }, + { + "wrong chainID on header2", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("ethermint", 4, suite.valSet, bothValSet, signers), + ChainID: "gaia", + }, + func(ev *Evidence) {}, + true, + }, + { + "mismatched heights", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 6, suite.valSet, bothValSet, signers), + ChainID: "gaia", + }, + func(ev *Evidence) {}, + true, + }, + { + "same block id", + Evidence{ + Header1: suite.header, + Header2: suite.header, + ChainID: "gaia", + }, + func(ev *Evidence) {}, + true, + }, + { + "header doesn't have 2/3 majority", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 4, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + func(ev *Evidence) { + // voteSet contains only altVal which is less than 2/3 of total power (4/14) + wrongVoteSet := tmtypes.NewVoteSet("gaia", ev.Header2.Height, 1, tmtypes.PrecommitType, altValSet) + var err error + ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round(), wrongVoteSet, altSigners) + if err != nil { + panic(err) + } + }, + true, + }, + { + "validators sign off on wrong commit", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 4, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + func(ev *Evidence) { + ev.Header2.Commit.BlockID = makeBlockID(tmhash.Sum([]byte("other_hash")), 3, tmhash.Sum([]byte("other_partset"))) + }, + true, + }, + } + + for _, tc := range testCases { + tc := tc // pin for scopelint + suite.Run(tc.name, func() { + // reset suite for each subtest + suite.SetupTest() + + tc.malleateEvidence(&tc.evidence) + + err := tc.evidence.ValidateBasic() + + if tc.expErr { + suite.Error(err, "ValidateBasic did not throw error for invalid evidence") + } else { + suite.NoError(err, "ValidateBasic returned error on valid evidence: %s", err) + } + }) + } +} diff --git a/x/ibc/02-client/types/tendermint/header.go b/x/ibc/02-client/types/tendermint/header.go index c2d9cfebc9c5..133c1741e56e 100644 --- a/x/ibc/02-client/types/tendermint/header.go +++ b/x/ibc/02-client/types/tendermint/header.go @@ -3,7 +3,9 @@ package tendermint import ( tmtypes "github.com/tendermint/tendermint/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienterrors "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" ) var _ exported.Header = Header{} @@ -20,9 +22,33 @@ func (h Header) ClientType() exported.ClientType { return exported.Tendermint } +// GetCommitter returns the ValidatorSet that committed header +func (h Header) GetCommitter() exported.Committer { + return Committer{ + ValidatorSet: h.ValidatorSet, + Height: uint64(h.Height), + NextValSetHash: h.NextValidatorsHash, + } +} + // GetHeight returns the current height // // NOTE: also referred as `sequence` func (h Header) GetHeight() uint64 { return uint64(h.Height) } + +// ValidateBasic calls the SignedHeader ValidateBasic function +// and checks that validatorsets are not nil +func (h Header) ValidateBasic(chainID string) error { + if err := h.SignedHeader.ValidateBasic(chainID); err != nil { + return err + } + if h.ValidatorSet == nil { + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), "ValidatorSet is nil") + } + if h.NextValidatorSet == nil { + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), "NextValidatorSet is nil") + } + return nil +} diff --git a/x/ibc/02-client/types/tendermint/misbehaviour.go b/x/ibc/02-client/types/tendermint/misbehaviour.go index 1edde8ec1c04..5b04b6e3ec0c 100644 --- a/x/ibc/02-client/types/tendermint/misbehaviour.go +++ b/x/ibc/02-client/types/tendermint/misbehaviour.go @@ -3,94 +3,65 @@ package tendermint import ( "fmt" - yaml "gopkg.in/yaml.v2" - - sdk "github.com/cosmos/cosmos-sdk/types" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" - - "github.com/tendermint/tendermint/crypto/tmhash" - cmn "github.com/tendermint/tendermint/libs/common" - tmtypes "github.com/tendermint/tendermint/types" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) -var _ exported.Evidence = Evidence{} +var _ exported.Misbehaviour = Misbehaviour{} +var _ evidenceexported.Evidence = Misbehaviour{} -// Evidence is a wrapper over tendermint's DuplicateVoteEvidence -// that implements Evidence interface expected by ICS-02 -type Evidence struct { - *tmtypes.DuplicateVoteEvidence - ChainID string `json:"chain_id" yaml:"chain_id"` - ValidatorPower int64 `json:"val_power" yaml:"val_power"` - TotalPower int64 `json:"total_power" yaml:"total_power"` +// Misbehaviour contains evidence that a light client submitted a different header from +// a full node at the same height. +type Misbehaviour struct { + *Evidence + ClientID string `json:"client_id" yaml:"client_id"` } -// Type implements exported.Evidence interface -func (ev Evidence) Route() string { - return exported.ClientTypeTendermint +// ClientType is Tendermint light client +func (m Misbehaviour) ClientType() exported.ClientType { + return exported.Tendermint } -// Type implements exported.Evidence interface -func (ev Evidence) Type() string { - return exported.ClientTypeTendermint +// GetEvidence returns the evidence to handle a light client misbehaviour +func (m Misbehaviour) GetEvidence() evidenceexported.Evidence { + return m.Evidence } -// String implements exported.Evidence interface -func (ev Evidence) String() string { - bz, err := yaml.Marshal(ev) - if err != nil { - panic(err) +// ValidateBasic performs the basic validity checks for the evidence and the +// client ID. +func (m Misbehaviour) ValidateBasic() error { + if m.Evidence == nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "empty evidence") } - return string(bz) -} - -// Hash implements exported.Evidence interface -func (ev Evidence) Hash() cmn.HexBytes { - return tmhash.Sum(SubModuleCdc.MustMarshalBinaryBare(ev)) -} -// ValidateBasic implements exported.Evidence interface -func (ev Evidence) ValidateBasic() sdk.Error { - if ev.DuplicateVoteEvidence == nil { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "duplicate evidence is nil")) - } - err := ev.DuplicateVoteEvidence.ValidateBasic() - if err != nil { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error())) - } - if ev.ChainID == "" { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "chainID is empty")) - } - if ev.ValidatorPower <= 0 { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Validator Power: %d", ev.ValidatorPower))) - } - if ev.TotalPower < ev.ValidatorPower { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Total Power: %d", ev.TotalPower))) + if err := m.Evidence.ValidateBasic(); err != nil { + return err } - return nil -} -// GetConsensusAddress implements exported.Evidence interface -func (ev Evidence) GetConsensusAddress() sdk.ConsAddress { - return sdk.ConsAddress(ev.DuplicateVoteEvidence.Address()) + return host.DefaultClientIdentifierValidator(m.ClientID) } -// GetHeight implements exported.Evidence interface -func (ev Evidence) GetHeight() int64 { - return ev.DuplicateVoteEvidence.Height() -} +// CheckMisbehaviour checks if the evidence provided is a valid light client misbehaviour +func CheckMisbehaviour(trustedCommitter Committer, m Misbehaviour) error { + if err := m.ValidateBasic(); err != nil { + return err + } -// GetValidatorPower implements exported.Evidence interface -func (ev Evidence) GetValidatorPower() int64 { - return ev.ValidatorPower -} + trustedValSet := trustedCommitter.ValidatorSet -// GetTotalPower implements exported.Evidence interface -func (ev Evidence) GetTotalPower() int64 { - return ev.TotalPower -} + // Evidence is within trusting period. ValidatorSet must have 2/3 similarity with trustedCommitter ValidatorSet + // check that the validator sets on both headers are valid given the last trusted validatorset + // less than or equal to evidence height + if err := trustedValSet.VerifyFutureCommit(m.Evidence.Header1.ValidatorSet, m.Evidence.ChainID, + m.Evidence.Header1.Commit.BlockID, m.Evidence.Header1.Height, m.Evidence.Header1.Commit); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("validator set in Header1 has too much change from last known committer: %v", err)) + } + if err := trustedValSet.VerifyFutureCommit(m.Evidence.Header2.ValidatorSet, m.Evidence.ChainID, + m.Evidence.Header2.Commit.BlockID, m.Evidence.Header2.Height, m.Evidence.Header2.Commit); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("validator set in Header2 has too much change from last known committer: %v", err)) + } -// CheckMisbehaviour checks if the evidence provided is a misbehaviour -func CheckMisbehaviour(evidence Evidence) error { - return evidence.DuplicateVoteEvidence.Verify(evidence.ChainID, evidence.DuplicateVoteEvidence.PubKey) + return nil } diff --git a/x/ibc/02-client/types/tendermint/misbehaviour_test.go b/x/ibc/02-client/types/tendermint/misbehaviour_test.go index f5e75e12f785..f69a6d12884e 100644 --- a/x/ibc/02-client/types/tendermint/misbehaviour_test.go +++ b/x/ibc/02-client/types/tendermint/misbehaviour_test.go @@ -1,64 +1,170 @@ package tendermint import ( - "testing" + "bytes" - "github.com/stretchr/testify/require" - - yaml "gopkg.in/yaml.v2" + tmtypes "github.com/tendermint/tendermint/types" ) -func TestString(t *testing.T) { - dupEv := randomDuplicatedVoteEvidence() - ev := Evidence{ - DuplicateVoteEvidence: dupEv, - ChainID: "mychain", - ValidatorPower: 10, - TotalPower: 50, +func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + + signers := []tmtypes.PrivValidator{suite.privVal} + testCases := []struct { + name string + evidence *Evidence + clientID string + expErr bool + }{ + { + "valid misbehavior", + &Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 4, suite.valSet, bothValSet, signers), + ChainID: "gaia", + }, + "gaiamainnet", + false, + }, + { + "nil evidence", + nil, + "gaiamainnet", + true, + }, + { + "invalid evidence", + &Evidence{ + Header1: suite.header, + Header2: suite.header, + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "invalid ClientID", + &Evidence{ + Header1: MakeHeader("gaia123??", 5, suite.valSet, suite.valSet, signers), + Header2: MakeHeader("gaia123?", 5, suite.valSet, suite.valSet, signers), + ChainID: "gaia123?", + }, + "gaia123?", + true, + }, } - byteStr, err := yaml.Marshal(ev) - require.Nil(t, err) - require.Equal(t, string(byteStr), ev.String(), "Evidence String method does not work as expected") + for _, tc := range testCases { + tc := tc // pin for scopelint + suite.Run(tc.name, func() { + misbehaviour := Misbehaviour{ + Evidence: tc.evidence, + ClientID: tc.clientID, + } + + err := misbehaviour.ValidateBasic() + if tc.expErr { + suite.Error(err, "Invalid Misbehaviour passed ValidateBasic") + } else { + suite.NoError(err, "Valid Misbehaviour failed ValidateBasic: %v", err) + } + }) + } } -func TestValidateBasic(t *testing.T) { - dupEv := randomDuplicatedVoteEvidence() +func (suite *TendermintTestSuite) TestCheckMisbehaviour() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) - // good evidence - ev := Evidence{ - DuplicateVoteEvidence: dupEv, - ChainID: "mychain", - ValidatorPower: 10, - TotalPower: 50, + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} } - err := ev.ValidateBasic() - require.Nil(t, err, "good evidence failed on ValidateBasic: %v", err) - - // invalid duplicate evidence - ev.DuplicateVoteEvidence.VoteA = nil - err = ev.ValidateBasic() - require.NotNil(t, err, "invalid duplicate evidence passed on ValidateBasic") - - // reset duplicate evidence to be valid, and set empty chainID - dupEv = randomDuplicatedVoteEvidence() - ev.DuplicateVoteEvidence = dupEv - ev.ChainID = "" - err = ev.ValidateBasic() - require.NotNil(t, err, "invalid chain-id passed on ValidateBasic") - - // reset chainID and set 0 validator power - ev.ChainID = "mychain" - ev.ValidatorPower = 0 - err = ev.ValidateBasic() - require.NotNil(t, err, "invalid validator power passed on ValidateBasic") - - // reset validator power and set invalid total power - ev.ValidatorPower = 10 - ev.TotalPower = 9 - err = ev.ValidateBasic() - require.NotNil(t, err, "invalid total power passed on ValidateBasic") + altSigners := []tmtypes.PrivValidator{altPrivVal} + committer := Committer{ + ValidatorSet: suite.valSet, + Height: 3, + NextValSetHash: suite.valSet.Hash(), + } + + testCases := []struct { + name string + evidence *Evidence + clientID string + expErr bool + }{ + { + "trusting period misbehavior should pass", + &Evidence{ + Header1: MakeHeader("gaia", 5, bothValSet, suite.valSet, bothSigners), + Header2: MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + "gaiamainnet", + false, + }, + { + "first valset has too much change", + &Evidence{ + Header1: MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + Header2: MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "second valset has too much change", + &Evidence{ + Header1: MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + Header2: MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "both valsets have too much change", + &Evidence{ + Header1: MakeHeader("gaia", 5, altValSet, altValSet, altSigners), + Header2: MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + } + + for _, tc := range testCases { + tc := tc // pin for scopelint + suite.Run(tc.name, func() { + misbehaviour := Misbehaviour{ + Evidence: tc.evidence, + ClientID: tc.clientID, + } + + err := CheckMisbehaviour(committer, misbehaviour) + + if tc.expErr { + suite.Error(err, "CheckMisbehaviour passed unexpectedly") + } else { + suite.NoError(err, "CheckMisbehaviour failed unexpectedly: %v", err) + } + }) + } } diff --git a/x/ibc/02-client/types/tendermint/tendermint_test.go b/x/ibc/02-client/types/tendermint/tendermint_test.go index cb3e572d6289..7f8b8e0e863c 100644 --- a/x/ibc/02-client/types/tendermint/tendermint_test.go +++ b/x/ibc/02-client/types/tendermint/tendermint_test.go @@ -24,13 +24,14 @@ func (suite *TendermintTestSuite) SetupTest() { privVal := tmtypes.NewMockPV() val := tmtypes.NewValidator(privVal.GetPubKey(), 10) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) - suite.header = MakeHeader(3, valSet, valSet, []tmtypes.PrivValidator{privVal}) + suite.header = MakeHeader("gaia", 4, valSet, valSet, []tmtypes.PrivValidator{privVal}) root := commitment.NewRoot(tmhash.Sum([]byte("my root"))) cs := ConsensusState{ ChainID: "gaia", Height: 3, Root: root, + ValidatorSet: valSet, NextValidatorSet: valSet, } diff --git a/x/ibc/02-client/types/tendermint/test_utils.go b/x/ibc/02-client/types/tendermint/test_utils.go index ac25a13fabbf..bc2b998c2e71 100644 --- a/x/ibc/02-client/types/tendermint/test_utils.go +++ b/x/ibc/02-client/types/tendermint/test_utils.go @@ -21,42 +21,13 @@ func makeBlockID(hash []byte, partSetSize int, partSetHash []byte) tmtypes.Block } -func makeVote(val tmtypes.PrivValidator, chainID string, valIndex int, height int64, round, step int, blockID tmtypes.BlockID) *tmtypes.Vote { - addr := val.GetPubKey().Address() - v := &tmtypes.Vote{ - ValidatorAddress: addr, - ValidatorIndex: valIndex, - Height: height, - Round: round, - Type: tmtypes.SignedMsgType(step), - BlockID: blockID, - } - err := val.SignVote(chainID, v) - if err != nil { - panic(err) - } - return v -} - -func randomDuplicatedVoteEvidence() *tmtypes.DuplicateVoteEvidence { - val := tmtypes.NewMockPV() - blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), 1000, tmhash.Sum([]byte("partshash"))) - blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), 1000, tmhash.Sum([]byte("partshash"))) - const chainID = "gaia" - return &tmtypes.DuplicateVoteEvidence{ - PubKey: val.GetPubKey(), - VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID), - VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2), - } -} - -func MakeHeader(height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { +func MakeHeader(chainID string, height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { vsetHash := valSet.Hash() nextHash := nextValSet.Hash() timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) tmHeader := tmtypes.Header{ Version: version.Consensus{Block: 2, App: 2}, - ChainID: "gaia", + ChainID: chainID, Height: height, Time: timestamp, NumTxs: 100, @@ -70,11 +41,11 @@ func MakeHeader(height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes. AppHash: tmhash.Sum([]byte("app_hash")), LastResultsHash: tmhash.Sum([]byte("last_results_hash")), EvidenceHash: tmhash.Sum([]byte("evidence_hash")), - ProposerAddress: signers[0].GetPubKey().Address(), + ProposerAddress: valSet.Proposer.Address, } hhash := tmHeader.Hash() blockID := makeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) - voteSet := tmtypes.NewVoteSet("gaia", height, 1, tmtypes.PrecommitType, valSet) + voteSet := tmtypes.NewVoteSet(chainID, height, 1, tmtypes.PrecommitType, valSet) commit, err := tmtypes.MakeCommit(blockID, height, 1, voteSet, signers) if err != nil { panic(err) diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index fede95f47fe9..4e39fbd8de23 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -267,9 +267,11 @@ func (suite *KeeperTestSuite) createClient(clientID string) { suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) consensusState := tendermint.ConsensusState{ - ChainID: chainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + ChainID: chainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, clientType, consensusState) diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index bf6dfe0d7839..904f02ca16d8 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -29,9 +30,10 @@ const ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet } func (suite *KeeperTestSuite) SetupTest() { @@ -41,6 +43,11 @@ func (suite *KeeperTestSuite) SetupTest() { suite.cdc = app.Codec() suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) suite.app = app + + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) } func TestKeeperTestSuite(t *testing.T) { diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index efd704c28d21..98a39778e467 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -22,11 +22,15 @@ func (suite *KeeperTestSuite) createClient() { suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, } + _ = consensusState.GetCommitter() + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) suite.NoError(err) } diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index 299b0ab9c5e5..fa011b3ae104 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -32,9 +33,10 @@ const ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet } func (suite *KeeperTestSuite) SetupTest() { @@ -45,6 +47,11 @@ func (suite *KeeperTestSuite) SetupTest() { suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) suite.app = app + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + suite.createClient() } diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 7e0f430ddaa9..2b07fbe5151a 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -50,9 +51,10 @@ var ( type HandlerTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet } func (suite *HandlerTestSuite) SetupTest() { @@ -63,6 +65,11 @@ func (suite *HandlerTestSuite) SetupTest() { suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) suite.app = app + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + suite.createClient() suite.createConnection(connection.OPEN) } @@ -75,9 +82,11 @@ func (suite *HandlerTestSuite) createClient() { suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index b7370a34d29f..cc67265bb1f8 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -46,9 +47,10 @@ var ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet } func (suite *KeeperTestSuite) SetupTest() { @@ -59,6 +61,11 @@ func (suite *KeeperTestSuite) SetupTest() { suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) suite.app = app + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + suite.createClient() suite.createConnection(connection.OPEN) } diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index fe20d2b26062..c28b4cc9db00 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -23,9 +23,11 @@ func (suite *KeeperTestSuite) createClient() { suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 07fc9f831be8..1a1e2d0189be 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -23,9 +23,6 @@ func NewHandler(k Keeper) sdk.Handler { case client.MsgUpdateClient: return client.HandleMsgUpdateClient(ctx, k.ClientKeeper, msg) - case client.MsgSubmitMisbehaviour: - return client.HandleMsgSubmitMisbehaviour(ctx, k.ClientKeeper, msg) - // IBC connection msgs case connection.MsgConnectionOpenInit: return connection.HandleMsgConnectionOpenInit(ctx, k.ConnectionKeeper, msg) From b330c8ef58d961e280beb08c698449e0bbff7178 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 10 Dec 2019 16:06:06 +0100 Subject: [PATCH 022/176] Misc ibc fixes (#5357) * fix cli ExactArgs * remove full handshakes * rm dup flag * fix error handling --- x/ibc/03-connection/client/cli/tx.go | 282 +----------------------- x/ibc/03-connection/keeper/handshake.go | 2 +- x/ibc/04-channel/client/cli/tx.go | 216 +----------------- x/ibc/20-transfer/client/cli/tx.go | 1 - 4 files changed, 14 insertions(+), 487 deletions(-) diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 3ad967b785d2..9693a62b96ea 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -36,18 +36,18 @@ const ( // chain A with a given counterparty chain B func GetCmdConnectionOpenInit(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: strings.TrimSpace(`open-init [connection-id] [client-id] [counterparty-connection-id] - [counterparty-client-id] [path/to/counterparty_prefix.json]`), + Use: strings.TrimSpace(`open-init [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json]`), Short: "initialize connection on chain A", Long: strings.TrimSpace( fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: Example: -$ %s tx ibc connection open-init [connection-id] [client-id] [counterparty-connection-id] -[counterparty-client-id] [path/to/counterparty_prefix.json] +$ %s tx ibc connection open-init [connection-id] [client-id] \ +[counterparty-connection-id] [counterparty-client-id] \ +[path/to/counterparty_prefix.json] `, version.ClientName), ), - Args: cobra.ExactArgs(6), + Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) @@ -87,7 +87,7 @@ $ %s tx ibc connection open-init [connection-id] [client-id] [counterparty-conne // chain B func GetCmdConnectionOpenTry(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: strings.TrimSpace(`open-try [connection-id] [client-id] + Use: strings.TrimSpace(`open-try [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] [counterparty-versions] [path/to/proof_init.json]`), Short: "initiate connection handshake between two chains", @@ -95,12 +95,12 @@ func GetCmdConnectionOpenTry(storeKey string, cdc *codec.Codec) *cobra.Command { fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: Example: -$ %s tx ibc connection open-try connection-id] [client-id] -[counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] +$ %s tx ibc connection open-try connection-id] [client-id] \ +[counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] \ [counterparty-versions] [path/to/proof_init.json] `, version.ClientName), ), - Args: cobra.ExactArgs(6), + Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) @@ -224,7 +224,7 @@ Example: $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] `, version.ClientName), ), - Args: cobra.ExactArgs(3), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) @@ -289,265 +289,3 @@ func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { } return path, nil } - -// func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { -// cmd := &cobra.Command{ -// Use: "handshake [conn-id-chain-1] [client-id-chain-1] [path-chain-1] [conn-id-chain-2] [client-id-chain-2] [path-chain-2] ", -// Short: "initiate connection handshake between two chains", -// Args: cobra.ExactArgs(6), -// RunE: func(cmd *cobra.Command, args []string) error { -// inBuf := bufio.NewReader(cmd.InOrStdin()) -// prove := true - -// // --chain-id values for each chain -// cid1 := viper.GetString(flags.FlagChainID) -// cid2 := viper.GetString(FlagChainID2) - -// // --from values for each wallet -// from1 := viper.GetString(FlagFrom1) -// from2 := viper.GetString(FlagFrom2) - -// // --node values for each RPC -// rpc1 := viper.GetString(FlagNode1) -// rpc2 := viper.GetString(FlagNode2) - -// // ibc connection-id for each chain -// connID1 := args[0] -// connID2 := args[3] - -// // ibc client-id for each chain -// clientID1 := args[1] -// clientID2 := args[4] - -// // Get default version -// version := types.GetCompatibleVersions()[0] - -// // Create txbldr, clictx, querier for cid1 -// viper.Set(flags.FlagChainID, cid1) -// txBldr1 := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) -// ctx1 := context.NewCLIContextIBC(inBuf, from1, cid1, rpc1).WithCodec(cdc). -// WithBroadcastMode(flags.BroadcastBlock) - -// // Create txbldr, clictx, querier for cid1 -// viper.Set(flags.FlagChainID, cid2) -// txBldr2 := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) -// ctx2 := context.NewCLIContextIBC(inBuf, from2, cid2, rpc2).WithCodec(cdc). -// WithBroadcastMode(flags.BroadcastBlock) - -// // read in path for cid1 -// path1, err := parsePath(ctx1.Codec, args[2]) -// if err != nil { -// return err -// } - -// // read in path for cid2 -// path2, err := parsePath(ctx1.Codec, args[5]) -// if err != nil { -// return err -// } - -// // get passphrase for key from1 -// passphrase1, err := keys.GetPassphrase(from1) -// if err != nil { -// return err -// } - -// // get passphrase for key from2 -// passphrase2, err := keys.GetPassphrase(from2) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// msgOpenInit := types.NewMsgConnectionOpenInit( -// connID1, clientID1, connID2, clientID2, -// path2, ctx1.GetFromAddress(), -// ) - -// if err := msgOpenInit.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid1, msgOpenInit.Type()) -// res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } - -// fmt.Printf(" [OK] txid(%v) client(%v) conn(%v)\n", res.TxHash, clientID1, connID1) - -// // Another block has to be passed after msgOpenInit is committed -// // to retrieve the correct proofs -// // TODO: Modify this to actually check two blocks being processed, and -// // remove hardcoding this to 8 seconds. -// time.Sleep(8 * time.Second) - -// header, _, err := clientutils.QueryTendermintHeader(ctx1) -// if err != nil { -// return err -// } - -// // Create and send msgUpdateClient -// viper.Set(flags.FlagChainID, cid2) -// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) - -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) -// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - -// // Fetch proofs from cid1 -// viper.Set(flags.FlagChainID, cid1) -// proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) -// if err != nil { -// return err -// } - -// csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1, prove) -// if err != nil { -// return err -// } - -// // Create and send msgOpenTry -// viper.Set(flags.FlagChainID, cid2) -// msgOpenTry := types.NewMsgConnectionOpenTry(connID2, clientID2, connID1, clientID1, path1, []string{version}, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), ctx2.GetFromAddress()) - -// if err := msgOpenTry.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid2, msgOpenTry.Type()) - -// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// fmt.Printf(" [OK] txid(%v) client(%v) connection(%v)\n", res.TxHash, clientID2, connID2) - -// // Another block has to be passed after msgOpenInit is committed -// // to retrieve the correct proofs -// // TODO: Modify this to actually check two blocks being processed, and -// // remove hardcoding this to 8 seconds. -// time.Sleep(8 * time.Second) - -// header, _, err = clientutils.QueryTendermintHeader(ctx2) -// if err != nil { -// return err -// } - -// // Update the client for cid2 on cid1 -// viper.Set(flags.FlagChainID, cid1) -// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID1, header, ctx1.GetFromAddress()) - -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID2) - -// // Fetch proofs from cid2 -// viper.Set(flags.FlagChainID, cid2) -// proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), connID2, storeKey) -// if err != nil { -// return err -// } - -// csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2, prove) -// if err != nil { -// return err -// } - -// // Create and send msgOpenAck -// viper.Set(flags.FlagChainID, cid1) -// msgOpenAck := types.NewMsgConnectionOpenAck(connID1, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), version, ctx1.GetFromAddress()) - -// if err := msgOpenAck.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid1, msgOpenAck.Type()) - -// res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID1) - -// // Another block has to be passed after msgOpenInit is committed -// // to retrieve the correct proofs -// // TODO: Modify this to actually check two blocks being processed, and -// // remove hardcoding this to 8 seconds. -// time.Sleep(8 * time.Second) - -// header, _, err = clientutils.QueryTendermintHeader(ctx1) -// if err != nil { -// return err -// } - -// // Update client for cid1 on cid2 -// viper.Set(flags.FlagChainID, cid2) -// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) - -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) - -// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - -// viper.Set(flags.FlagChainID, cid1) -// proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) -// if err != nil { -// return err -// } - -// // Create and send msgOpenConfirm -// viper.Set(flags.FlagChainID, cid2) -// msgOpenConfirm := types.NewMsgConnectionOpenConfirm(connID2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) - -// if err := msgOpenConfirm.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid1, msgOpenConfirm.Type()) - -// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID2) - -// return nil -// }, -// } - -// cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") -// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") -// cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") -// cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") -// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") - -// cmd.MarkFlagRequired(FlagNode1) -// cmd.MarkFlagRequired(FlagNode2) -// cmd.MarkFlagRequired(FlagFrom1) -// cmd.MarkFlagRequired(FlagFrom2) -// cmd.MarkFlagRequired(FlagChainID2) - -// return cmd -// } diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index f9288f7d9ae2..8e8dcbb96090 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -31,7 +31,7 @@ func (k Keeper) ConnOpenInit( err := k.addConnectionToClient(ctx, clientID, connectionID) if err != nil { - sdkerrors.Wrap(err, "cannot initialize connection") + return sdkerrors.Wrap(err, "cannot initialize connection") } k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: NONE -> INIT", connectionID)) diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index a0d5ceade64f..58bb189e2c4a 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -174,7 +174,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma return &cobra.Command{ Use: "open-confirm [port-id] [channel-id] [/path/to/proof-ack.json] [proof-height]", Short: "Creates and sends a ChannelOpenConfirm message", - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) @@ -217,7 +217,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command return &cobra.Command{ Use: "close-init [port-id] [channel-id]", Short: "Creates and sends a ChannelCloseInit message", - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) @@ -241,7 +241,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm return &cobra.Command{ Use: "close-confirm [port-id] [channel-id] [/path/to/proof-init.json] [proof-height]", Short: "Creates and sends a ChannelCloseConfirm message", - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) @@ -285,213 +285,3 @@ func channelOrder() types.Order { } return types.UNORDERED } - -// func GetCmdHandshake(storeKey string, cdc *codec.Codec) *cobra.Command { -// cmd := &cobra.Command{ -// Use: "handshake", -// Short: "initiate connection handshake between two chains", -// Long: strings.TrimSpace( -// fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: - -// Example: -// $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-client-id] [cp-port-id] [cp-chain-id] [cp-conn-id] -// `, version.ClientName)), -// Args: cobra.ExactArgs(8), -// // Args: []string{portid1, chanid1, connid1, portid2, chanid2, connid2} -// RunE: func(cmd *cobra.Command, args []string) error { -// // --chain-id values for each chain -// cid1 := viper.GetString(flags.FlagChainID) -// cid2 := viper.GetString(FlagChainID2) - -// // --from values for each wallet -// from1 := viper.GetString(FlagFrom1) -// from2 := viper.GetString(FlagFrom2) - -// // --node values for each RPC -// node1 := viper.GetString(FlagNode1) -// node2 := viper.GetString(FlagNode2) - -// // client IDs -// clientid1 := args[0] -// clientid2 := args[4] - -// // port IDs -// portid1 := args[1] -// portid2 := args[5] - -// // channel IDs -// chanid1 := args[2] -// chanid2 := args[6] - -// // connection IDs -// connid1 := args[3] -// connid2 := args[7] - -// inBuf := bufio.NewReader(cmd.InOrStdin()) -// prove := true - -// // Create txbldr, clictx, querier for cid1 -// viper.Set(flags.FlagChainID, cid1) -// txBldr1 := auth.NewTxBuilderFromCLI(inBuf). -// WithTxEncoder(authutils.GetTxEncoder(cdc)) -// ctx1 := context.NewCLIContextIBC(inBuf, from1, cid1, node1). -// WithCodec(cdc). -// WithBroadcastMode(flags.BroadcastBlock) - -// // Create txbldr, clictx, querier for cid2 -// viper.Set(flags.FlagChainID, cid2) -// txBldr2 := auth.NewTxBuilderFromCLI(inBuf). -// WithTxEncoder(authutils.GetTxEncoder(cdc)) -// ctx2 := context.NewCLIContextIBC(inBuf, from2, cid2, node2). -// WithCodec(cdc). -// WithBroadcastMode(flags.BroadcastBlock) - -// // get passphrase for key from1 -// passphrase1, err := keys.GetPassphrase(from1) -// if err != nil { -// return err -// } - -// // get passphrase for key from2 -// passphrase2, err := keys.GetPassphrase(from2) -// if err != nil { -// return err -// } - -// // TODO: check state and if not Idle continue existing process -// viper.Set(flags.FlagChainID, cid1) -// msgOpenInit := types.NewMsgChannelOpenInit(portid1, chanid1, "v1.0.0", channelOrder(), []string{connid1}, portid2, chanid2, ctx1.GetFromAddress()) -// if err := msgOpenInit.ValidateBasic(); err != nil { -// return err -// } - -// res, err := authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } - -// // Another block has to be passed after msginit is committed -// // to retrieve the correct proofs -// time.Sleep(8 * time.Second) - -// header, _, err := clientutils.QueryTendermintHeader(ctx1) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid2) -// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// channelRes, err := utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) -// if err != nil { -// return err -// } - -// msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// // Another block has to be passed after msginit is committed -// // to retrieve the correct proofs -// time.Sleep(8 * time.Second) - -// header, _, err = clientutils.QueryTendermintHeader(ctx2) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid1, header, ctx1.GetFromAddress()) -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } - -// viper.Set(flags.FlagChainID, cid2) -// channelRes, err = utils.QueryChannel(ctx2.WithHeight(header.Height-1), portid2, chanid2, prove) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx1.GetFromAddress()) -// if err := msgOpenAck.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } - -// // Another block has to be passed after msginit is committed -// // to retrieve the correct proofs -// time.Sleep(8 * time.Second) - -// header, _, err = clientutils.QueryTendermintHeader(ctx1) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid2) -// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// channelRes, err = utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) -// if err != nil { -// return err -// } - -// msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) -// if err := msgOpenConfirm.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// return nil -// }, -// } - -// cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") -// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") -// cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") -// cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") -// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") -// cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") - -// cmd.MarkFlagRequired(FlagFrom1) -// cmd.MarkFlagRequired(FlagFrom2) - -// return cmd -// } diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index dc14a53c5a3b..cc68453ddedd 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -63,7 +63,6 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { }, } cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") - cmd.Flags().String(flags.FlagFrom, "", "key in local keystore to send from") return cmd } From 5f65aaaefe3fc04ad96e68af2376c68d4cde0b5e Mon Sep 17 00:00:00 2001 From: Aditya Date: Thu, 12 Dec 2019 18:04:22 -0800 Subject: [PATCH 023/176] Implement Query Committer methods in ICS-02 (#5402) * add query methods for committers in ICS-02 * Update x/ibc/02-client/keeper/keeper.go * add REST docs --- x/ibc/02-client/client/cli/query.go | 40 +++++++++++++++++++++++++++ x/ibc/02-client/client/rest/query.go | 40 +++++++++++++++++++++++++++ x/ibc/02-client/client/utils/utils.go | 25 +++++++++++++++++ x/ibc/02-client/keeper/querier.go | 23 +++++++++++++++ x/ibc/02-client/types/querier.go | 36 ++++++++++++++++++++++++ 5 files changed, 164 insertions(+) diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index 8bc6a755db4f..3f8efd9d9698 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -121,6 +121,46 @@ $ %s query ibc client root [client-id] [height] return cmd } +// GetCmdQueryCommitter defines the command to query the committer of the chain +// at a given height +func GetCmdQueryCommitter(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "committer [client-id] [height]", + Short: "Query a committer", + Long: strings.TrimSpace( + fmt.Sprintf(`Query a committer at a specific height for a particular client + +Example: +$ %s query ibc client committer [client-id] [height] +`, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + if strings.TrimSpace(clientID) == "" { + return errors.New("client ID can't be blank") + } + + height, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return fmt.Errorf("expected integer height, got: %v", args[1]) + } + + prove := viper.GetBool(flags.FlagProve) + + committerRes, err := utils.QueryCommitter(cliCtx, clientID, height, prove) + if err != nil { + return err + } + + return cliCtx.PrintOutput(committerRes) + }, + } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd +} + // GetCmdQueryHeader defines the command to query the latest header on the chain func GetCmdQueryHeader(cdc *codec.Codec) *cobra.Command { return &cobra.Command{ diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go index bc135bebc1b8..ba9cdc33d690 100644 --- a/x/ibc/02-client/client/rest/query.go +++ b/x/ibc/02-client/client/rest/query.go @@ -17,6 +17,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute st r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/committers/{%s}", RestClientID, RestRootHeight), queryCommitterHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc("/ibc/header", queryHeaderHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/node-state", queryNodeConsensusStateHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/path", queryPathHandlerFn(cliCtx)).Methods("GET") @@ -127,6 +128,45 @@ func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Handl } } +// queryCommitterHandlerFn implements a committer querying route +// +// @Summary Query committer +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param height path number true "Committer height" +// @Success 200 {object} QueryCommitter "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/committers/{height} [get] +func queryCommitterHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + height, err := strconv.ParseUint(vars[RestRootHeight], 10, 64) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + prove := rest.ParseQueryProve(r) + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + committerRes, err := utils.QueryCommitter(cliCtx, clientID, height, prove) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(int64(committerRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, committerRes) + } +} + // queryHeaderHandlerFn implements a header querying route // // @Summary Query header diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index a024e0856594..04c0fa68888d 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -88,6 +88,31 @@ func QueryCommitmentRoot( return rootRes, nil } +// QueryCommitter queries the store to get the committer and a merkle proof +func QueryCommitter( + cliCtx context.CLIContext, clientID string, height uint64, prove bool, +) (types.CommitterResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyCommitter(clientID, height), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.CommitterResponse{}, err + } + + var committer tendermint.Committer + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &committer); err != nil { + return types.CommitterResponse{}, err + } + + committerRes := types.NewCommitterResponse(clientID, height, committer, res.Proof, res.Height) + + return committerRes, nil +} + // QueryTendermintHeader takes a client context and returns the appropriate // tendermint header func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, error) { diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go index 8956a72fab2e..8fedcebfb8f6 100644 --- a/x/ibc/02-client/keeper/querier.go +++ b/x/ibc/02-client/keeper/querier.go @@ -75,3 +75,26 @@ func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]by return bz, nil } + +// QuerierCommitter defines the sdk.Querier to query a committer +func QuerierCommitter(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryCommitterParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + committer, found := k.GetCommitter(ctx, params.ClientID, params.Height) + if !found { + return nil, sdk.ConvertError(errors.ErrCommitterNotFound(k.codespace, + fmt.Sprintf("committer not found on height: %d", params.Height))) + } + + bz, err := types.SubModuleCdc.MarshalJSON(committer) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go index 0bf71ebaa6ae..e7ffe21c2786 100644 --- a/x/ibc/02-client/types/querier.go +++ b/x/ibc/02-client/types/querier.go @@ -45,6 +45,21 @@ func NewQueryCommitmentRootParams(id string, height uint64) QueryCommitmentRootP } } +// QueryCommitterParams defines the params for the following queries: +// - 'custom/ibc/clients//committers/' +type QueryCommitterParams struct { + ClientID string + Height uint64 +} + +// NewQueryCommitmentRootParams creates a new QueryCommitmentRootParams instance +func NewQueryCommitterParams(id string, height uint64) QueryCommitterParams { + return QueryCommitterParams{ + ClientID: id, + Height: height, + } +} + // StateResponse defines the client response for a client state query. // It includes the commitment proof and the height of the proof. type StateResponse struct { @@ -107,3 +122,24 @@ func NewRootResponse( ProofHeight: uint64(proofHeight), } } + +// CommitterResponse defines the client response for a committer query +// It includes the commitment proof and the height of the proof +type CommitterResponse struct { + Committer tmtypes.Committer `json:"committer" yaml:"committer"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewCommitterResponse creates a new CommitterResponse instance. +func NewCommitterResponse( + clientID string, height uint64, committer tmtypes.Committer, proof *merkle.Proof, proofHeight int64, +) CommitterResponse { + return CommitterResponse{ + Committer: committer, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(RootPath(clientID, height), "/")), + ProofHeight: uint64(proofHeight), + } +} From 0d9bfd4dae667c374c5957e624555ad65ebd1a35 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 13 Dec 2019 13:36:03 -0300 Subject: [PATCH 024/176] fix test --- client/keys/root_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/keys/root_test.go b/client/keys/root_test.go index 2dcf912b98d8..49681b17e95f 100644 --- a/client/keys/root_test.go +++ b/client/keys/root_test.go @@ -15,7 +15,7 @@ func TestCommands(t *testing.T) { assert.NotNil(t, rootCommands) // Commands are registered - assert.Equal(t, 12, len(rootCommands.Commands())) + assert.Equal(t, 11, len(rootCommands.Commands())) } func TestMain(m *testing.M) { From fb2dd9ae9c5322dd508a4eec66a550efbaf1a9bc Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 16 Dec 2019 16:41:02 -0300 Subject: [PATCH 025/176] IBC UX improvements (#5364) * ICS02 iterators * ICS03 iterators * ICS04 iterators * ICS02 client updates * CLI connections * setup queriers * clean up queriers * add tests * IBC top-level querier tests * update ICS02 keys * update ICS03 keys * make format * update ICS04 keys * fix a few tests * fix ICS20 tests * update keys --- client/flags/flags.go | 11 ++- x/ibc/02-client/alias.go | 2 + x/ibc/02-client/client/cli/cli.go | 1 + x/ibc/02-client/client/cli/query.go | 32 ++++++++ x/ibc/02-client/client/rest/query.go | 53 +++++++++--- x/ibc/02-client/client/rest/rest.go | 5 +- x/ibc/02-client/client/rest/swagger.go | 1 + x/ibc/02-client/client/utils/utils.go | 25 ++++++ x/ibc/02-client/keeper/keeper.go | 48 ++++++++--- x/ibc/02-client/keeper/keeper_test.go | 19 ++++- x/ibc/02-client/keeper/querier.go | 84 +++++++++++++------- x/ibc/02-client/types/codec.go | 1 + x/ibc/02-client/types/keys.go | 71 +++++++++++++---- x/ibc/02-client/types/msgs.go | 4 +- x/ibc/02-client/types/querier.go | 22 ++++- x/ibc/03-connection/alias.go | 2 + x/ibc/03-connection/client/cli/cli.go | 1 + x/ibc/03-connection/client/cli/query.go | 33 ++++++++ x/ibc/03-connection/client/utils/utils.go | 25 ++++++ x/ibc/03-connection/keeper/handshake_test.go | 14 ++-- x/ibc/03-connection/keeper/keeper.go | 36 +++++++-- x/ibc/03-connection/keeper/keeper_test.go | 42 +++++++++- x/ibc/03-connection/keeper/querier.go | 52 ++++++++---- x/ibc/03-connection/types/connection.go | 2 - x/ibc/03-connection/types/keys.go | 42 +++++++--- x/ibc/03-connection/types/querier.go | 16 ++++ x/ibc/04-channel/alias.go | 2 + x/ibc/04-channel/keeper/handshake_test.go | 16 ++-- x/ibc/04-channel/keeper/keeper.go | 54 +++++++++---- x/ibc/04-channel/keeper/keeper_test.go | 57 +++++++++++-- x/ibc/04-channel/keeper/querier.go | 43 +++++++--- x/ibc/04-channel/types/codec.go | 3 + x/ibc/04-channel/types/keys.go | 78 ++++++++++++++---- x/ibc/04-channel/types/querier.go | 18 ++++- x/ibc/20-transfer/handler_test.go | 6 +- x/ibc/20-transfer/keeper/relay_test.go | 6 +- x/ibc/keeper/querier.go | 38 ++++++--- x/ibc/keeper/querier_test.go | 29 +++++-- x/ibc/types/keys.go | 40 ++++++++++ x/ibc/types/types.go | 15 ---- 40 files changed, 836 insertions(+), 213 deletions(-) create mode 100644 x/ibc/types/keys.go delete mode 100644 x/ibc/types/types.go diff --git a/client/flags/flags.go b/client/flags/flags.go index cbfc9d39e979..106061d3a78a 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -19,13 +19,17 @@ const ( DefaultGasAdjustment = 1.0 DefaultGasLimit = 200000 GasFlagAuto = "auto" +) - // DefaultKeyringBackend +// Keyring constants +const ( DefaultKeyringBackend = KeyringBackendOS KeyringBackendFile = "file" KeyringBackendOS = "os" KeyringBackendTest = "test" +) +const ( // BroadcastBlock defines a tx broadcasting mode where the client waits for // the tx to be committed in a block. BroadcastBlock = "block" @@ -35,7 +39,10 @@ const ( // BroadcastAsync defines a tx broadcasting mode where the client returns // immediately. BroadcastAsync = "async" +) +// List of CLI flags +const ( FlagHome = tmcli.HomeFlag FlagUseLedger = "ledger" FlagChainID = "chain-id" @@ -61,6 +68,8 @@ const ( FlagOutputDocument = "output-document" // inspired by wget -O FlagSkipConfirmation = "yes" FlagProve = "prove" + FlagPage = "page" + FlagLimit = "limit" FlagKeyringBackend = "keyring-backend" ) diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go index 4713a4e77dee..02f3aa623668 100644 --- a/x/ibc/02-client/alias.go +++ b/x/ibc/02-client/alias.go @@ -29,6 +29,7 @@ const ( StoreKey = types.StoreKey RouterKey = types.RouterKey QuerierRoute = types.QuerierRoute + QueryAllClients = types.QueryAllClients QueryClientState = types.QueryClientState QueryConsensusState = types.QueryConsensusState QueryVerifiedRoot = types.QueryVerifiedRoot @@ -37,6 +38,7 @@ const ( var ( // functions aliases NewKeeper = keeper.NewKeeper + QuerierClients = keeper.QuerierClients QuerierClientState = keeper.QuerierClientState QuerierConsensusState = keeper.QuerierConsensusState QuerierVerifiedRoot = keeper.QuerierVerifiedRoot diff --git a/x/ibc/02-client/client/cli/cli.go b/x/ibc/02-client/client/cli/cli.go index ac182365a7ae..d2db4d2be958 100644 --- a/x/ibc/02-client/client/cli/cli.go +++ b/x/ibc/02-client/client/cli/cli.go @@ -17,6 +17,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { } ics02ClientQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryClientStates(queryRoute, cdc), GetCmdQueryClientState(queryRoute, cdc), GetCmdQueryConsensusState(queryRoute, cdc), GetCmdQueryRoot(queryRoute, cdc), diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index 3f8efd9d9698..a64405b62993 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -17,6 +17,38 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// GetCmdQueryClientStates defines the command to query all the light clients +// that this chain mantains. +func GetCmdQueryClientStates(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "states", + Short: "Query all available light clients", + Long: strings.TrimSpace( + fmt.Sprintf(`Query all available light clients + +Example: +$ %s query ibc client states + `, version.ClientName), + ), + Example: fmt.Sprintf("%s query ibc client states", version.ClientName), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + page := viper.GetInt(flags.FlagPage) + limit := viper.GetInt(flags.FlagLimit) + + clientStates, _, err := utils.QueryAllClientStates(cliCtx, page, limit) + if err != nil { + return err + } + + return cliCtx.PrintOutput(clientStates) + }, + } + cmd.Flags().Int(flags.FlagPage, 1, "pagination page of light clients to to query for") + cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of light clients to query for") + return cmd +} + // GetCmdQueryClientState defines the command to query the state of a client with // a given id as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query func GetCmdQueryClientState(queryRoute string, cdc *codec.Codec) *cobra.Command { diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go index ba9cdc33d690..d831aa396719 100644 --- a/x/ibc/02-client/client/rest/query.go +++ b/x/ibc/02-client/client/rest/query.go @@ -13,16 +13,51 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx, queryRoute)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx, queryRoute)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/committers/{%s}", RestClientID, RestRootHeight), queryCommitterHandlerFn(cliCtx, queryRoute)).Methods("GET") +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc("/ibc/clients", queryAllClientStatesFn(cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/committers/{%s}", RestClientID, RestRootHeight), queryCommitterHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/header", queryHeaderHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/node-state", queryNodeConsensusStateHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/path", queryPathHandlerFn(cliCtx)).Methods("GET") } +// queryAllClientStatesFn queries all available light clients +// +// @Summary Query client states +// @Tags IBC +// @Produce json +// @Param page query int false "The page number to query" default(1) +// @Param limit query int false "The number of results per page" default(100) +// @Success 200 {object} QueryClientState "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients [get] +func queryAllClientStatesFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + _, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + clients, height, err := utils.QueryAllClientStates(cliCtx, page, limit) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, clients) + } +} + // queryClientStateHandlerFn implements a client state querying route // // @Summary Query client state @@ -34,7 +69,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute st // @Failure 400 {object} rest.ErrorResponse "Invalid client id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/clients/{client-id}/client-state [get] -func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +func queryClientStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] @@ -67,7 +102,7 @@ func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) htt // @Failure 400 {object} rest.ErrorResponse "Invalid client id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/clients/{client-id}/consensus-state [get] -func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +func queryConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] @@ -100,7 +135,7 @@ func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) // @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/clients/{client-id}/roots/{height} [get] -func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +func queryRootHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] @@ -139,7 +174,7 @@ func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Handl // @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/clients/{client-id}/committers/{height} [get] -func queryCommitterHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +func queryCommitterHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] diff --git a/x/ibc/02-client/client/rest/rest.go b/x/ibc/02-client/client/rest/rest.go index 51f8ce762bcb..34000c329e0d 100644 --- a/x/ibc/02-client/client/rest/rest.go +++ b/x/ibc/02-client/client/rest/rest.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" ) +// REST client flags const ( RestClientID = "client-id" RestRootHeight = "height" @@ -16,7 +17,7 @@ const ( // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { - registerQueryRoutes(cliCtx, r, queryRoute) + registerQueryRoutes(cliCtx, r) registerTxRoutes(cliCtx, r) } @@ -35,6 +36,6 @@ type UpdateClientReq struct { // SubmitMisbehaviourReq defines the properties of a submit misbehaviour request's body. type SubmitMisbehaviourReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` } diff --git a/x/ibc/02-client/client/rest/swagger.go b/x/ibc/02-client/client/rest/swagger.go index b3f64c566e72..2ff01ff34fb8 100644 --- a/x/ibc/02-client/client/rest/swagger.go +++ b/x/ibc/02-client/client/rest/swagger.go @@ -7,6 +7,7 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// nolint type ( QueryConsensusState struct { Height int64 `json:"height"` diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 04c0fa68888d..30f56e57a9db 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -1,6 +1,8 @@ package utils import ( + "fmt" + abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" @@ -11,6 +13,29 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// QueryAllClientStates returns all the light client states. It _does not_ return +// any merkle proof. +func QueryAllClientStates(cliCtx context.CLIContext, page, limit int) ([]types.State, int64, error) { + params := types.NewQueryAllClientsParams(page, limit) + bz, err := cliCtx.Codec.MarshalJSON(params) + if err != nil { + return nil, 0, fmt.Errorf("failed to marshal query params: %w", err) + } + + route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAllClients) + res, height, err := cliCtx.QueryWithData(route, bz) + if err != nil { + return nil, 0, err + } + + var clients []types.State + err = cliCtx.Codec.UnmarshalJSON(res, &clients) + if err != nil { + return nil, 0, fmt.Errorf("failed to unmarshal light clients: %w", err) + } + return clients, height, nil +} + // QueryClientState queries the store to get the light client state and a merkle // proof. func QueryClientState( diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index e5c4feb26263..a8b1876d1e41 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -6,7 +6,6 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" @@ -40,7 +39,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetClientState gets a particular client from the store func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyClientState(clientID)) if bz == nil { return types.State{}, false @@ -53,14 +52,14 @@ func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, b // SetClientState sets a particular Client to the store func (k Keeper) SetClientState(ctx sdk.Context, clientState types.State) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(clientState) store.Set(types.KeyClientState(clientState.ID), bz) } // GetClientType gets the consensus type for a specific client func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.ClientType, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyClientType(clientID)) if bz == nil { return 0, false @@ -71,13 +70,13 @@ func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.Client // SetClientType sets the specific client consensus type to the provable store func (k Keeper) SetClientType(ctx sdk.Context, clientID string, clientType exported.ClientType) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) store.Set(types.KeyClientType(clientID), []byte{byte(clientType)}) } // GetConsensusState creates a new client state and populates it with a given consensus state func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.ConsensusState, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyConsensusState(clientID)) if bz == nil { return nil, false @@ -90,7 +89,7 @@ func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.Co // SetConsensusState sets a ConsensusState to a particular client func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) store.Set(types.KeyConsensusState(clientID), bz) } @@ -98,7 +97,7 @@ func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusSta // GetVerifiedRoot gets a verified commitment Root from a particular height to // a client func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) (commitment.RootI, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyRoot(clientID, height)) if bz == nil { @@ -113,15 +112,42 @@ func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) // SetVerifiedRoot sets a verified commitment Root from a particular height to // a client func (k Keeper) SetVerifiedRoot(ctx sdk.Context, clientID string, height uint64, root commitment.RootI) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(root) store.Set(types.KeyRoot(clientID, height), bz) } +// IterateClients provides an iterator over all stored light client State +// objects. For each State object, cb will be called. If the cb returns true, +// the iterator will close and stop. +func (k Keeper) IterateClients(ctx sdk.Context, cb func(types.State) bool) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.GetClientKeysPrefix(ibctypes.KeyClientPrefix)) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var clientState types.State + k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &clientState) + + if cb(clientState) { + break + } + } +} + +// GetAllClients returns all stored light client State objects. +func (k Keeper) GetAllClients(ctx sdk.Context) (states []types.State) { + k.IterateClients(ctx, func(state types.State) bool { + states = append(states, state) + return false + }) + return states +} + // GetCommitter will get the Committer of a particular client at the oldest height // that is less than or equal to the height passed in func (k Keeper) GetCommitter(ctx sdk.Context, clientID string, height uint64) (exported.Committer, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) var committer exported.Committer @@ -139,7 +165,7 @@ func (k Keeper) GetCommitter(ctx sdk.Context, clientID string, height uint64) (e // SetCommitter sets a committer from a particular height to // a particular client func (k Keeper) SetCommitter(ctx sdk.Context, clientID string, height uint64, committer exported.Committer) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(committer) store.Set(types.KeyCommitter(clientID, height), bz) } diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index da79777dae50..2c74a5a22f7c 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -21,7 +21,9 @@ import ( ) const ( - testClientID = "gaia" + testClientID = "gaia" + testClientID2 = "ethbridge" + testClientID3 = "ethermint" ) type KeeperTestSuite struct { @@ -147,5 +149,20 @@ func (suite KeeperTestSuite) TestSetCommitter() { require.True(suite.T(), ok, "GetCommitter failed on existing height: %d", i) require.Equal(suite.T(), nextCommitter, recv, "GetCommitter returned committer on nonexistent height: %d", i) } +} + +func (suite KeeperTestSuite) TestGetAllClients() { + expClients := []types.State{ + types.NewClientState(testClientID2), + types.NewClientState(testClientID3), + types.NewClientState(testClientID), + } + + for i := range expClients { + suite.keeper.SetClientState(suite.ctx, expClients[i]) + } + clients := suite.keeper.GetAllClients(suite.ctx) + suite.Require().Len(clients, len(expClients)) + suite.Require().Equal(expClients, clients) } diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go index 8fedcebfb8f6..104ad554c700 100644 --- a/x/ibc/02-client/keeper/querier.go +++ b/x/ibc/02-client/keeper/querier.go @@ -5,95 +5,121 @@ import ( abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" ) +// QuerierClients defines the sdk.Querier to query all the light client states. +func QuerierClients(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { + var params types.QueryAllClientsParams + + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) + } + + clients := k.GetAllClients(ctx) + + start, end := client.Paginate(len(clients), params.Page, params.Limit, 100) + if start < 0 || end < 0 { + clients = []types.State{} + } else { + clients = clients[start:end] + } + + res, err := codec.MarshalJSONIndent(k.cdc, clients) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} + // QuerierClientState defines the sdk.Querier to query the IBC client state -func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryClientStateParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } clientState, found := k.GetClientState(ctx, params.ClientID) if !found { - return nil, sdk.ConvertError(errors.ErrClientTypeNotFound(k.codespace)) + return nil, errors.ErrClientTypeNotFound(k.codespace) } - bz, err := types.SubModuleCdc.MarshalJSON(clientState) + bz, err := codec.MarshalJSONIndent(k.cdc, clientState) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } // QuerierConsensusState defines the sdk.Querier to query a consensus state -func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryClientStateParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } consensusState, found := k.GetConsensusState(ctx, params.ClientID) if !found { - return nil, sdk.ConvertError(errors.ErrConsensusStateNotFound(k.codespace)) + return nil, errors.ErrConsensusStateNotFound(k.codespace) } - bz, err := types.SubModuleCdc.MarshalJSON(consensusState) + bz, err := codec.MarshalJSONIndent(k.cdc, consensusState) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } // QuerierVerifiedRoot defines the sdk.Querier to query a verified commitment root -func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryCommitmentRootParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } root, found := k.GetVerifiedRoot(ctx, params.ClientID, params.Height) if !found { - return nil, sdk.ConvertError(errors.ErrRootNotFound(k.codespace)) + return nil, errors.ErrRootNotFound(k.codespace) } - bz, err := types.SubModuleCdc.MarshalJSON(root) + bz, err := codec.MarshalJSONIndent(k.cdc, root) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } // QuerierCommitter defines the sdk.Querier to query a committer -func QuerierCommitter(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierCommitter(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryCommitterParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } committer, found := k.GetCommitter(ctx, params.ClientID, params.Height) if !found { - return nil, sdk.ConvertError(errors.ErrCommitterNotFound(k.codespace, - fmt.Sprintf("committer not found on height: %d", params.Height))) + return nil, errors.ErrCommitterNotFound( + k.codespace, + fmt.Sprintf("committer not found on height: %d", params.Height), + ) } - bz, err := types.SubModuleCdc.MarshalJSON(committer) + bz, err := codec.MarshalJSONIndent(k.cdc, committer) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index ed923f5cbc89..6cd376b6e8ea 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -18,6 +18,7 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgCreateClient{}, "ibc/client/MsgCreateClient", nil) cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) + cdc.RegisterConcrete(State{}, "ibc/client/State", nil) cdc.RegisterConcrete(tendermint.ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) cdc.RegisterConcrete(tendermint.Committer{}, "ibc/client/tendermint/Committer", nil) diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go index 6dc55a77baf0..eeb7e8b0d8b9 100644 --- a/x/ibc/02-client/types/keys.go +++ b/x/ibc/02-client/types/keys.go @@ -2,6 +2,8 @@ package types import ( "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) const ( @@ -18,67 +20,102 @@ const ( QuerierRoute string = SubModuleName ) -// KVStore key prefixes -var ( - KeyPrefixClient = []byte{} -) - // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space // ClientStatePath takes an Identifier and returns a Path under which to store a // particular client state func ClientStatePath(clientID string) string { - return fmt.Sprintf("clients/%s/state", clientID) + return string(KeyClientState(clientID)) } // ClientTypePath takes an Identifier and returns Path under which to store the // type of a particular client. func ClientTypePath(clientID string) string { - return fmt.Sprintf("clients/%s/type", clientID) + return string(KeyClientType(clientID)) } // ConsensusStatePath takes an Identifier and returns a Path under which to // store the consensus state of a client. func ConsensusStatePath(clientID string) string { - return fmt.Sprintf("clients/%s/consensusState", clientID) + return string(KeyConsensusState(clientID)) } // RootPath takes an Identifier and returns a Path under which to // store the root for a particular height of a client. func RootPath(clientID string, height uint64) string { - return fmt.Sprintf("clients/%s/roots/%d", clientID, height) + return string(KeyRoot(clientID, height)) } // CommitterPath takes an Identifier and returns a Path under which // to store the committer of a client at a particular height func CommitterPath(clientID string, height uint64) string { - return fmt.Sprintf("clients/%s/committer/%d", clientID, height) + return string(KeyCommitter(clientID, height)) } // KeyClientState returns the store key for a particular client state func KeyClientState(clientID string) []byte { - return []byte(ClientStatePath(clientID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyClientPrefix), + []byte(clientStatePath(clientID))..., + ) } // KeyClientType returns the store key for type of a particular client func KeyClientType(clientID string) []byte { - return []byte(ClientTypePath(clientID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyClientTypePrefix), + []byte(clientTypePath(clientID))..., + ) } // KeyConsensusState returns the store key for the consensus state of a particular // client func KeyConsensusState(clientID string) []byte { - return []byte(ConsensusStatePath(clientID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyConsensusStatePrefix), + []byte(consensusStatePath(clientID))..., + ) } // KeyRoot returns the store key for a commitment root of a particular // client at a given height func KeyRoot(clientID string, height uint64) []byte { - return []byte(RootPath(clientID, height)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyRootPrefix), + []byte(rootPath(clientID, height))..., + ) } -// KeyValidatorSet returns the store key for a validator of a particular -// client at a given height. Key => clientID||height +// KeyCommitter returns the store key for a validator (aka commiter) of a particular +// client at a given height. func KeyCommitter(clientID string, height uint64) []byte { - return []byte(CommitterPath(clientID, height)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyCommiterPrefix), + []byte(committerPath(clientID, height))..., + ) +} + +// GetClientKeysPrefix return the ICS02 prefix bytes +func GetClientKeysPrefix(prefix int) []byte { + return []byte(fmt.Sprintf("%d/clients", prefix)) +} + +func clientStatePath(clientID string) string { + return fmt.Sprintf("clients/%s/state", clientID) +} + +func clientTypePath(clientID string) string { + return fmt.Sprintf("clients/%s/type", clientID) +} + +func consensusStatePath(clientID string) string { + return fmt.Sprintf("clients/%s/consensusState", clientID) +} + +func rootPath(clientID string, height uint64) string { + return fmt.Sprintf("clients/%s/roots/%d", clientID, height) +} + +func committerPath(clientID string, height uint64) string { + return fmt.Sprintf("clients/%s/committer/%d", clientID, height) } diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index 6f0aa7959ac7..039f9d04d879 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -127,9 +127,9 @@ func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress { // MsgSubmitMisbehaviour defines a message to update an IBC client type MsgSubmitMisbehaviour struct { - ClientID string `json:"id" yaml:"id"` + ClientID string `json:"id" yaml:"id"` Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` - Signer sdk.AccAddress `json:"address" yaml:"address"` + Signer sdk.AccAddress `json:"address" yaml:"address"` } // NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go index e7ffe21c2786..d2862307b09b 100644 --- a/x/ibc/02-client/types/querier.go +++ b/x/ibc/02-client/types/querier.go @@ -11,6 +11,7 @@ import ( // query routes supported by the IBC client Querier const ( + QueryAllClients = "client_states" QueryClientState = "client_state" QueryConsensusState = "consensus_state" QueryVerifiedRoot = "roots" @@ -30,6 +31,21 @@ func NewQueryClientStateParams(id string) QueryClientStateParams { } } +// QueryAllClientsParams defines the parameters necessary for querying for all +// light client states. +type QueryAllClientsParams struct { + Page int `json:"page" yaml:"page"` + Limit int `json:"limit" yaml:"limit"` +} + +// NewQueryAllClientsParams creates a new QueryAllClientsParams instance. +func NewQueryAllClientsParams(page, limit int) QueryAllClientsParams { + return QueryAllClientsParams{ + Page: page, + Limit: limit, + } +} + // QueryCommitmentRootParams defines the params for the following queries: // - 'custom/ibc/clients//roots/' type QueryCommitmentRootParams struct { @@ -52,7 +68,7 @@ type QueryCommitterParams struct { Height uint64 } -// NewQueryCommitmentRootParams creates a new QueryCommitmentRootParams instance +// NewQueryCommitterParams creates a new QueryCommitmentRootParams instance func NewQueryCommitterParams(id string, height uint64) QueryCommitterParams { return QueryCommitterParams{ ClientID: id, @@ -76,7 +92,7 @@ func NewClientStateResponse( return StateResponse{ ClientState: clientState, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ConsensusStatePath(clientID), "/")), + ProofPath: commitment.NewPath(strings.Split(ClientStatePath(clientID), "/")), ProofHeight: uint64(height), } } @@ -139,7 +155,7 @@ func NewCommitterResponse( return CommitterResponse{ Committer: committer, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(RootPath(clientID, height), "/")), + ProofPath: commitment.NewPath(strings.Split(CommitterPath(clientID, height), "/")), ProofHeight: uint64(proofHeight), } } diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index b73456d28dc8..67367f45b6cb 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -36,6 +36,7 @@ const ( StoreKey = types.StoreKey RouterKey = types.RouterKey QuerierRoute = types.QuerierRoute + QueryAllConnections = types.QueryAllConnections QueryConnection = types.QueryConnection QueryClientConnections = types.QueryClientConnections ) @@ -43,6 +44,7 @@ const ( var ( // functions aliases NewKeeper = keeper.NewKeeper + QuerierConnections = keeper.QuerierConnections QuerierConnection = keeper.QuerierConnection QuerierClientConnections = keeper.QuerierClientConnections RegisterCodec = types.RegisterCodec diff --git a/x/ibc/03-connection/client/cli/cli.go b/x/ibc/03-connection/client/cli/cli.go index 9d3777f1fefa..e0ea7c89880f 100644 --- a/x/ibc/03-connection/client/cli/cli.go +++ b/x/ibc/03-connection/client/cli/cli.go @@ -17,6 +17,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { } ics03ConnectionQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryConnections(queryRoute, cdc), GetCmdQueryConnection(queryRoute, cdc), )...) return ics03ConnectionQueryCmd diff --git a/x/ibc/03-connection/client/cli/query.go b/x/ibc/03-connection/client/cli/query.go index 4eb3f167b451..b3cc8fa0ea80 100644 --- a/x/ibc/03-connection/client/cli/query.go +++ b/x/ibc/03-connection/client/cli/query.go @@ -14,6 +14,39 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" ) +// GetCmdQueryConnections defines the command to query all the connection ends +// that this chain mantains. +func GetCmdQueryConnections(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "connections", + Short: "Query all available light clients", + Long: strings.TrimSpace( + fmt.Sprintf(`Query all available connections + +Example: +$ %s query ibc connection connections + `, version.ClientName), + ), + Example: fmt.Sprintf("%s query ibc connection connections", version.ClientName), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + page := viper.GetInt(flags.FlagPage) + limit := viper.GetInt(flags.FlagLimit) + + connections, _, err := utils.QueryAllConnections(cliCtx, page, limit) + if err != nil { + return err + } + + return cliCtx.PrintOutput(connections) + }, + } + cmd.Flags().Int(flags.FlagPage, 1, "pagination page of light clients to to query for") + cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of light clients to query for") + return cmd +} + // GetCmdQueryConnection defines the command to query a connection end func GetCmdQueryConnection(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ diff --git a/x/ibc/03-connection/client/utils/utils.go b/x/ibc/03-connection/client/utils/utils.go index 5cfd7bf7dab4..0f54e9e3b5cc 100644 --- a/x/ibc/03-connection/client/utils/utils.go +++ b/x/ibc/03-connection/client/utils/utils.go @@ -1,12 +1,37 @@ package utils import ( + "fmt" + abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) +// QueryAllConnections returns all the connections. It _does not_ return +// any merkle proof. +func QueryAllConnections(cliCtx context.CLIContext, page, limit int) ([]types.ConnectionEnd, int64, error) { + params := types.NewQueryAllConnectionsParams(page, limit) + bz, err := cliCtx.Codec.MarshalJSON(params) + if err != nil { + return nil, 0, fmt.Errorf("failed to marshal query params: %w", err) + } + + route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAllConnections) + res, height, err := cliCtx.QueryWithData(route, bz) + if err != nil { + return nil, 0, err + } + + var connections []types.ConnectionEnd + err = cliCtx.Codec.UnmarshalJSON(res, &connections) + if err != nil { + return nil, 0, fmt.Errorf("failed to unmarshal connections: %w", err) + } + return connections, height, nil +} + // QueryConnection queries the store to get a connection end and a merkle // proof. func QueryConnection( diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index 4e39fbd8de23..ba42ba25ee27 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -52,8 +52,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.createClient(testClientID1) suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) - connectionKey := connection.ConnectionPath(testConnectionID2) - consensusKey := string(client.KeyConsensusState(testClientID2)) + connectionKey := connection.KeyConnection(testConnectionID2) + consensusKey := client.KeyConsensusState(testClientID2) invalidProof := func() error { proofInit, proofHeight := suite.queryProof(connectionKey) @@ -119,8 +119,8 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { suite.createClient(testClientID1) suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) - connectionKey := connection.ConnectionPath(testConnectionID1) - consensusKey := string(client.KeyConsensusState(testClientID1)) + connectionKey := connection.KeyConnection(testConnectionID1) + consensusKey := client.KeyConsensusState(testClientID1) connectionNotFound := func() error { //suite.updateClient(testClientID2) @@ -196,7 +196,7 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { suite.createClient(testClientID1) suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.OPEN) - connKey := connection.ConnectionPath(testConnectionID2) + connKey := connection.KeyConnection(testConnectionID2) proof, h := suite.queryProof(connKey) connectionNotFound := func() error { @@ -244,10 +244,10 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { } } -func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { +func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { res := suite.app.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", storeKey), - Data: []byte(key), + Data: key, Prove: true, }) diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index d86a527d169c..c20720c17788 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -6,7 +6,6 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -45,7 +44,7 @@ func (k Keeper) GetCommitmentPrefix() commitment.PrefixI { // GetConnection returns a connection with a particular identifier func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyConnection(connectionID)) if bz == nil { return types.ConnectionEnd{}, false @@ -58,7 +57,7 @@ func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.Conne // SetConnection sets a connection to the store func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(connection) store.Set(types.KeyConnection(connectionID), bz) } @@ -66,7 +65,7 @@ func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection t // GetClientConnectionPaths returns all the connection paths stored under a // particular client func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyClientConnections(clientID)) if bz == nil { return nil, false @@ -79,11 +78,38 @@ func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]st // SetClientConnectionPaths sets the connections paths for client func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths []string) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(paths) store.Set(types.KeyClientConnections(clientID), bz) } +// IterateConnections provides an iterator over all ConnectionEnd objects. +// For each ConnectionEnd, cb will be called. If the cb returns true, the +// iterator will close and stop. +func (k Keeper) IterateConnections(ctx sdk.Context, cb func(types.ConnectionEnd) bool) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.GetConnectionsKeysPrefix(ibctypes.KeyConnectionPrefix)) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var connection types.ConnectionEnd + k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &connection) + + if cb(connection) { + break + } + } +} + +// GetAllConnections returns all stored ConnectionEnd objects. +func (k Keeper) GetAllConnections(ctx sdk.Context) (connections []types.ConnectionEnd) { + k.IterateConnections(ctx, func(connection types.ConnectionEnd) bool { + connections = append(connections, connection) + return false + }) + return connections +} + // addConnectionToClient is used to add a connection identifier to the set of // connections associated with a client. // diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 904f02ca16d8..a4872d114363 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -25,6 +25,9 @@ const ( testClientID2 = "testclientid2" testConnectionID2 = "connectionid2" + + testClientID3 = "testclientid3" + testConnectionID3 = "connectionid3" ) type KeeperTestSuite struct { @@ -72,7 +75,6 @@ func (suite *KeeperTestSuite) TestSetAndGetConnection() { } func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { - _, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1) suite.False(existed) @@ -81,3 +83,41 @@ func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { suite.True(existed) suite.EqualValues(types.GetCompatibleVersions(), paths) } + +func (suite KeeperTestSuite) TestGetAllConnections() { + // Connection (Counterparty): A(C) -> C(B) -> B(A) + counterparty1 := types.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + counterparty2 := types.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + counterparty3 := types.NewCounterparty(testClientID3, testConnectionID3, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + + conn1 := types.ConnectionEnd{ + State: types.INIT, + ClientID: testClientID1, + Counterparty: counterparty3, + Versions: types.GetCompatibleVersions(), + } + + conn2 := types.ConnectionEnd{ + State: types.INIT, + ClientID: testClientID2, + Counterparty: counterparty1, + Versions: types.GetCompatibleVersions(), + } + + conn3 := types.ConnectionEnd{ + State: types.NONE, + ClientID: testClientID3, + Counterparty: counterparty2, + Versions: types.GetCompatibleVersions(), + } + + expConnections := []types.ConnectionEnd{conn1, conn2, conn3} + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID1, expConnections[0]) + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID2, expConnections[1]) + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID3, expConnections[2]) + + connections := suite.app.IBCKeeper.ConnectionKeeper.GetAllConnections(suite.ctx) + suite.Require().Len(connections, len(expConnections)) + suite.Require().Equal(expConnections, connections) +} diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go index 8802ec7443fe..f5c56834161f 100644 --- a/x/ibc/03-connection/keeper/querier.go +++ b/x/ibc/03-connection/keeper/querier.go @@ -1,29 +1,29 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) // QuerierConnection defines the sdk.Querier to query a connection end -func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryConnectionParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } connection, found := k.GetConnection(ctx, params.ConnectionID) if !found { - return nil, sdk.ConvertError(types.ErrConnectionNotFound(k.codespace, params.ConnectionID)) + return nil, types.ErrConnectionNotFound(k.codespace, params.ConnectionID) } - bz, err := types.SubModuleCdc.MarshalJSON(connection) + bz, err := codec.MarshalJSONIndent(k.cdc, connection) if err != nil { return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } @@ -31,23 +31,47 @@ func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte return bz, nil } +// QuerierConnections defines the sdk.Querier to query all the connections. +func QuerierConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { + var params types.QueryAllConnectionsParams + + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) + } + + connections := k.GetAllConnections(ctx) + + start, end := client.Paginate(len(connections), params.Page, params.Limit, 100) + if start < 0 || end < 0 { + connections = []types.ConnectionEnd{} + } else { + connections = connections[start:end] + } + + res, err := codec.MarshalJSONIndent(k.cdc, connections) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} + // QuerierClientConnections defines the sdk.Querier to query the client connections -func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryClientConnectionsParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } clientConnectionPaths, found := k.GetClientConnectionPaths(ctx, params.ClientID) if !found { - return nil, sdk.ConvertError(types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID)) + return nil, types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID) } bz, err := types.SubModuleCdc.MarshalJSON(clientConnectionPaths) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 23ec6ca5709b..8abbda60a313 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -36,8 +36,6 @@ func NewConnectionEnd(state State, clientID string, counterparty Counterparty, v } } -// TODO: create a custom JSON marshaler - // Counterparty defines the counterparty chain associated with a connection end. type Counterparty struct { ClientID string `json:"client_id" yaml:"client_id"` diff --git a/x/ibc/03-connection/types/keys.go b/x/ibc/03-connection/types/keys.go index dbdbc576c61d..345b6b58d023 100644 --- a/x/ibc/03-connection/types/keys.go +++ b/x/ibc/03-connection/types/keys.go @@ -2,6 +2,8 @@ package types import ( "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) const ( @@ -18,29 +20,43 @@ const ( QuerierRoute = SubModuleName ) -// KVStore key prefixes -var ( - KeyPrefixConnection = []byte{} -) - // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths +// ClientConnectionsPath defines a reverse mapping from clients to a set of connections +func ClientConnectionsPath(clientID string) string { + return string(KeyClientConnections(clientID)) +} + // ConnectionPath defines the path under which connection paths are stored func ConnectionPath(connectionID string) string { - return fmt.Sprintf("connections/%s", connectionID) + return string(KeyConnection(connectionID)) } -// ClientConnectionsPath defines a reverse mapping from clients to a set of connections -func ClientConnectionsPath(clientID string) string { - return fmt.Sprintf("clients/%s/connections", clientID) +// KeyClientConnections returns the store key for the connectios of a given client +func KeyClientConnections(clientID string) []byte { + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyClientConnectionsPrefix), + []byte(clientConnectionsPath(clientID))..., + ) } // KeyConnection returns the store key for a particular connection func KeyConnection(connectionID string) []byte { - return []byte(ConnectionPath(connectionID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyConnectionPrefix), + []byte(connectionPath(connectionID))..., + ) } -// KeyClientConnections returns the store key for the connectios of a given client -func KeyClientConnections(clientID string) []byte { - return []byte(ClientConnectionsPath(clientID)) +// GetConnectionsKeysPrefix return the connection prefixes +func GetConnectionsKeysPrefix(prefix int) []byte { + return []byte(fmt.Sprintf("%d/connections", prefix)) +} + +func clientConnectionsPath(clientID string) string { + return fmt.Sprintf("clients/%s/connections", clientID) +} + +func connectionPath(connectionID string) string { + return fmt.Sprintf("connections/%s", connectionID) } diff --git a/x/ibc/03-connection/types/querier.go b/x/ibc/03-connection/types/querier.go index c254bebd6b4c..02581d42b15e 100644 --- a/x/ibc/03-connection/types/querier.go +++ b/x/ibc/03-connection/types/querier.go @@ -10,6 +10,7 @@ import ( // query routes supported by the IBC connection Querier const ( + QueryAllConnections = "connections" QueryConnection = "connection" QueryClientConnections = "client_connections" ) @@ -48,6 +49,21 @@ func NewQueryConnectionParams(clientID string) QueryConnectionParams { } } +// QueryAllConnectionsParams defines the parameters necessary for querying for all +// connections. +type QueryAllConnectionsParams struct { + Page int `json:"page" yaml:"page"` + Limit int `json:"limit" yaml:"limit"` +} + +// NewQueryAllConnectionsParams creates a new QueryAllConnectionsParams instance. +func NewQueryAllConnectionsParams(page, limit int) QueryAllConnectionsParams { + return QueryAllConnectionsParams{ + Page: page, + Limit: limit, + } +} + // ClientConnectionsResponse defines the client query response for a client // connection paths which also includes a proof and the height from which the // proof was retrieved. diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index 8ce587180679..d5494175505a 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -44,12 +44,14 @@ const ( StoreKey = types.StoreKey RouterKey = types.RouterKey QuerierRoute = types.QuerierRoute + QueryAllChannels = types.QueryAllChannels QueryChannel = types.QueryChannel ) var ( // functions aliases NewKeeper = keeper.NewKeeper + QuerierChannels = keeper.QuerierChannels QuerierChannel = keeper.QuerierChannel NewChannel = types.NewChannel NewCounterparty = types.NewCounterparty diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 98a39778e467..98fa69d5451e 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -5,7 +5,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" @@ -84,7 +83,7 @@ func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID } func (suite *KeeperTestSuite) deleteChannel(portID string, chanID string) { - store := prefix.NewStore(suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)), types.KeyPrefixChannel) + store := suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)) store.Delete(types.KeyChannel(portID, chanID)) } @@ -92,10 +91,10 @@ func (suite *KeeperTestSuite) bindPort(portID string) sdk.CapabilityKey { return suite.app.IBCKeeper.PortKeeper.BindPort(portID) } -func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { +func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { res := suite.app.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: []byte(key), + Data: key, Prove: true, }) @@ -134,7 +133,7 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { func (suite *KeeperTestSuite) TestChanOpenTry() { counterparty := types.NewCounterparty(testPort1, testChannel1) suite.bindPort(testPort2) - channelKey := types.ChannelPath(testPort1, testChannel1) + channelKey := types.KeyChannel(testPort1, testChannel1) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.INIT) @@ -164,7 +163,6 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) - fmt.Println(proofInit) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) suite.NoError(err) // successfully executed @@ -175,7 +173,7 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { func (suite *KeeperTestSuite) TestChanOpenAck() { suite.bindPort(testPort1) - channelKey := types.ChannelPath(testPort2, testChannel2) + channelKey := types.KeyChannel(testPort2, testChannel2) suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) suite.updateClient() @@ -219,7 +217,7 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { func (suite *KeeperTestSuite) TestChanOpenConfirm() { suite.bindPort(testPort2) - channelKey := types.ChannelPath(testPort1, testChannel1) + channelKey := types.KeyChannel(testPort1, testChannel1) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) suite.updateClient() @@ -293,7 +291,7 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { func (suite *KeeperTestSuite) TestChanCloseConfirm() { suite.bindPort(testPort2) - channelKey := types.ChannelPath(testPort1, testChannel1) + channelKey := types.KeyChannel(testPort1, testChannel1) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) suite.updateClient() diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index 0de7cc329288..5d72ab76cc60 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -7,7 +7,6 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -46,7 +45,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetChannel returns a channel with a particular identifier binded to a specific port func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyChannel(portID, channelID)) if bz == nil { return types.Channel{}, false @@ -59,14 +58,14 @@ func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Cha // SetChannel sets a channel to the store func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel types.Channel) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(channel) store.Set(types.KeyChannel(portID, channelID), bz) } // GetChannelCapability gets a channel's capability key from the store func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) (string, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyChannelCapabilityPath(portID, channelID)) if bz == nil { return "", false @@ -77,13 +76,13 @@ func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) // SetChannelCapability sets a channel's capability key to the store func (k Keeper) SetChannelCapability(ctx sdk.Context, portID, channelID string, key string) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) store.Set(types.KeyChannelCapabilityPath(portID, channelID), []byte(key)) } // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyNextSequenceSend(portID, channelID)) if bz == nil { return 0, false @@ -94,14 +93,14 @@ func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) ( // SetNextSequenceSend sets a channel's next send sequence to the store func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := sdk.Uint64ToBigEndian(sequence) store.Set(types.KeyNextSequenceSend(portID, channelID), bz) } // GetNextSequenceRecv gets a channel's next receive sequence from the store func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyNextSequenceRecv(portID, channelID)) if bz == nil { return 0, false @@ -112,41 +111,68 @@ func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) ( // SetNextSequenceRecv sets a channel's next receive sequence to the store func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := sdk.Uint64ToBigEndian(sequence) store.Set(types.KeyNextSequenceRecv(portID, channelID), bz) } // GetPacketCommitment gets the packet commitment hash from the store func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyPacketCommitment(portID, channelID, sequence)) return bz } // SetPacketCommitment sets the packet commitment hash to the store func (k Keeper) SetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64, commitmentHash []byte) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) store.Set(types.KeyPacketCommitment(portID, channelID, sequence), commitmentHash) } func (k Keeper) deletePacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) store.Delete(types.KeyPacketCommitment(portID, channelID, sequence)) } // SetPacketAcknowledgement sets the packet ack hash to the store func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64, ackHash []byte) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) } // GetPacketAcknowledgement gets the packet ack hash from the store func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyPacketAcknowledgement(portID, channelID, sequence)) if bz == nil { return nil, false } return bz, true } + +// IterateChannels provides an iterator over all Channel objects. For each +// Channel, cb will be called. If the cb returns true, the iterator will close +// and stop. +func (k Keeper) IterateChannels(ctx sdk.Context, cb func(types.Channel) bool) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.GetChannelKeysPrefix(ibctypes.KeyChannelPrefix)) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var channel types.Channel + k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &channel) + + if cb(channel) { + break + } + } +} + +// GetAllChannels returns all stored Channel objects. +func (k Keeper) GetAllChannels(ctx sdk.Context) (channels []types.Channel) { + k.IterateChannels(ctx, func(channel types.Channel) bool { + channels = append(channels, channel) + return false + }) + return channels +} diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index fa011b3ae104..b8159d760bc4 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -21,10 +21,14 @@ const ( testClientType = clientexported.Tendermint testConnection = "testconnection" - testPort1 = "firstport" - testPort2 = "secondport" - testChannel1 = "firstchannel" - testChannel2 = "secondchannel" + + testPort1 = "firstport" + testPort2 = "secondport" + testPort3 = "thirdport" + + testChannel1 = "firstchannel" + testChannel2 = "secondchannel" + testChannel3 = "thirdchannel" testChannelOrder = types.ORDERED testChannelVersion = "1.0" @@ -63,8 +67,8 @@ func (suite *KeeperTestSuite) TestSetChannel() { State: types.OPEN, Ordering: testChannelOrder, Counterparty: types.Counterparty{ - PortID: testPort1, - ChannelID: testChannel1, + PortID: testPort2, + ChannelID: testChannel2, }, ConnectionHops: []string{testConnection}, Version: testChannelVersion, @@ -76,6 +80,47 @@ func (suite *KeeperTestSuite) TestSetChannel() { suite.Equal(channel, storedChannel) } +func (suite KeeperTestSuite) TestGetAllChannels() { + // Channel (Counterparty): A(C) -> C(B) -> B(A) + counterparty1 := types.NewCounterparty(testPort1, testChannel1) + counterparty2 := types.NewCounterparty(testPort2, testChannel2) + counterparty3 := types.NewCounterparty(testPort3, testChannel3) + + channel1 := types.Channel{ + State: types.INIT, + Ordering: testChannelOrder, + Counterparty: counterparty3, + ConnectionHops: []string{testConnection}, + Version: testChannelVersion, + } + + channel2 := types.Channel{ + State: types.INIT, + Ordering: testChannelOrder, + Counterparty: counterparty1, + ConnectionHops: []string{testConnection}, + Version: testChannelVersion, + } + + channel3 := types.Channel{ + State: types.CLOSED, + Ordering: testChannelOrder, + Counterparty: counterparty2, + ConnectionHops: []string{testConnection}, + Version: testChannelVersion, + } + + expChannels := []types.Channel{channel1, channel2, channel3} + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort1, testChannel1, expChannels[0]) + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort2, testChannel2, expChannels[1]) + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort3, testChannel3, expChannels[2]) + + channels := suite.app.IBCKeeper.ChannelKeeper.GetAllChannels(suite.ctx) + suite.Require().Len(channels, len(expChannels)) + suite.Require().Equal(expChannels, channels) +} + func (suite *KeeperTestSuite) TestSetChannelCapability() { _, found := suite.app.IBCKeeper.ChannelKeeper.GetChannelCapability(suite.ctx, testPort1, testChannel1) suite.False(found) diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go index 3bf671d1e0fb..8aef90c879ad 100644 --- a/x/ibc/04-channel/keeper/querier.go +++ b/x/ibc/04-channel/keeper/querier.go @@ -1,32 +1,57 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // QuerierChannel defines the sdk.Querier to query a module's channel -func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryChannelParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) if !found { - return nil, sdk.ConvertError(types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID)) + return nil, types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID) } - bz, err := types.SubModuleCdc.MarshalJSON(channel) + bz, err := codec.MarshalJSONIndent(k.cdc, channel) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } + +// QuerierChannels defines the sdk.Querier to query all the channels. +func QuerierChannels(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { + var params types.QueryAllChannelsParams + + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) + } + + channels := k.GetAllChannels(ctx) + + start, end := client.Paginate(len(channels), params.Page, params.Limit, 100) + if start < 0 || end < 0 { + channels = []types.Channel{} + } else { + channels = channels[start:end] + } + + res, err := codec.MarshalJSONIndent(k.cdc, channels) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index 06c268e3e307..a5d709662fa2 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -12,6 +12,7 @@ var SubModuleCdc *codec.Codec // IBC channel. func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*exported.PacketI)(nil), nil) + cdc.RegisterConcrete(Channel{}, "ibc/channel/Channel", nil) cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil) cdc.RegisterConcrete(OpaquePacket{}, "ibc/channel/OpaquePacket", nil) @@ -21,6 +22,8 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgChannelOpenConfirm{}, "ibc/channel/MsgChannelOpenConfirm", nil) cdc.RegisterConcrete(MsgChannelCloseInit{}, "ibc/channel/MsgChannelCloseInit", nil) cdc.RegisterConcrete(MsgChannelCloseConfirm{}, "ibc/channel/MsgChannelCloseConfirm", nil) + + SetSubModuleCodec(cdc) } func SetSubModuleCodec(cdc *codec.Codec) { diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go index 27c444959ec7..1fcbb4f44806 100644 --- a/x/ibc/04-channel/types/keys.go +++ b/x/ibc/04-channel/types/keys.go @@ -2,6 +2,8 @@ package types import ( "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) const ( @@ -18,73 +20,115 @@ const ( QuerierRoute = SubModuleName ) -// KVStore key prefixes -var ( - KeyPrefixChannel = []byte{} -) - // ChannelPath defines the path under which channels are stored func ChannelPath(portID, channelID string) string { - return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) + return string(KeyChannel(portID, channelID)) } // ChannelCapabilityPath defines the path under which capability keys associated // with a channel are stored func ChannelCapabilityPath(portID, channelID string) string { - return fmt.Sprintf("%s/key", ChannelPath(portID, channelID)) + return string(KeyChannelCapabilityPath(portID, channelID)) } // NextSequenceSendPath defines the next send sequence counter store path func NextSequenceSendPath(portID, channelID string) string { - return fmt.Sprintf("%s/nextSequenceSend", ChannelPath(portID, channelID)) + return string(KeyNextSequenceSend(portID, channelID)) } // NextSequenceRecvPath defines the next receive sequence counter store path func NextSequenceRecvPath(portID, channelID string) string { - return fmt.Sprintf("%s/nextSequenceRecv", ChannelPath(portID, channelID)) + return string(KeyNextSequenceRecv(portID, channelID)) } // PacketCommitmentPath defines the commitments to packet data fields store path func PacketCommitmentPath(portID, channelID string, sequence uint64) string { - return fmt.Sprintf("%s/packets/%d", ChannelPath(portID, channelID), sequence) + return string(KeyPacketCommitment(portID, channelID, sequence)) } // PacketAcknowledgementPath defines the packet acknowledgement store path func PacketAcknowledgementPath(portID, channelID string, sequence uint64) string { - return fmt.Sprintf("%s/acknowledgements/%d", ChannelPath(portID, channelID), sequence) + return string(KeyPacketAcknowledgement(portID, channelID, sequence)) } // KeyChannel returns the store key for a particular channel func KeyChannel(portID, channelID string) []byte { - return []byte(ChannelPath(portID, channelID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyChannelPrefix), + []byte(channelPath(portID, channelID))..., + ) } // KeyChannelCapabilityPath returns the store key for the capability key of a // particular channel binded to a specific port func KeyChannelCapabilityPath(portID, channelID string) []byte { - return []byte(ChannelCapabilityPath(portID, channelID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyChannelCapabilityPrefix), + []byte(channelCapabilityPath(portID, channelID))..., + ) } // KeyNextSequenceSend returns the store key for the send sequence of a particular // channel binded to a specific port func KeyNextSequenceSend(portID, channelID string) []byte { - return []byte(NextSequenceSendPath(portID, channelID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyNextSeqSendPrefix), + []byte(nextSequenceSendPath(portID, channelID))..., + ) } // KeyNextSequenceRecv returns the store key for the receive sequence of a particular // channel binded to a specific port func KeyNextSequenceRecv(portID, channelID string) []byte { - return []byte(NextSequenceRecvPath(portID, channelID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyNextSeqRecvPrefix), + []byte(nextSequenceRecvPath(portID, channelID))..., + ) } // KeyPacketCommitment returns the store key of under which a packet commitment // is stored func KeyPacketCommitment(portID, channelID string, sequence uint64) []byte { - return []byte(PacketCommitmentPath(portID, channelID, sequence)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyPacketCommitmentPrefix), + []byte(packetCommitmentPath(portID, channelID, sequence))..., + ) } // KeyPacketAcknowledgement returns the store key of under which a packet // acknowledgement is stored func KeyPacketAcknowledgement(portID, channelID string, sequence uint64) []byte { - return []byte(PacketAcknowledgementPath(portID, channelID, sequence)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyPacketAckPrefix), + []byte(packetAcknowledgementPath(portID, channelID, sequence))..., + ) +} + +// GetChannelKeysPrefix returns the prefix bytes for ICS04 iterators +func GetChannelKeysPrefix(prefix int) []byte { + return []byte(fmt.Sprintf("%d/ports/", prefix)) +} + +func channelPath(portID, channelID string) string { + return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) +} + +func channelCapabilityPath(portID, channelID string) string { + return channelPath(portID, channelID) + "/key" +} + +func nextSequenceSendPath(portID, channelID string) string { + return channelPath(portID, channelID) + "/nextSequenceSend" +} + +func nextSequenceRecvPath(portID, channelID string) string { + return channelPath(portID, channelID) + "/nextSequenceRecv" +} + +func packetCommitmentPath(portID, channelID string, sequence uint64) string { + return channelPath(portID, channelID) + fmt.Sprintf("/packets/%d", sequence) +} + +func packetAcknowledgementPath(portID, channelID string, sequence uint64) string { + return channelPath(portID, channelID) + fmt.Sprintf("/acknowledgements/%d", sequence) } diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go index 9594f56473ef..e010c6991d88 100644 --- a/x/ibc/04-channel/types/querier.go +++ b/x/ibc/04-channel/types/querier.go @@ -10,7 +10,8 @@ import ( // query routes supported by the IBC channel Querier const ( - QueryChannel = "channel" + QueryAllChannels = "channels" + QueryChannel = "channel" ) // ChannelResponse defines the client query response for a channel which also @@ -49,6 +50,21 @@ func NewQueryChannelParams(portID, channelID string) QueryChannelParams { } } +// QueryAllChannelsParams defines the parameters necessary for querying for all +// channels. +type QueryAllChannelsParams struct { + Page int `json:"page" yaml:"page"` + Limit int `json:"limit" yaml:"limit"` +} + +// NewQueryAllChannelsParams creates a new QueryAllChannelsParams instance. +func NewQueryAllChannelsParams(page, limit int) QueryAllChannelsParams { + return QueryAllChannelsParams{ + Page: page, + Limit: limit, + } +} + // PacketResponse defines the client query response for a packet which also // includes a proof, its path and the height form which the proof was retrieved type PacketResponse struct { diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 2b07fbe5151a..46ef6f08558b 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -141,10 +141,10 @@ func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connI suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) } -func (suite *HandlerTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { +func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { res := suite.app.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: []byte(key), + Data: key, Prove: true, }) @@ -197,7 +197,7 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { packetDataBz := []byte("invaliddata") packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - packetCommitmentPath := channel.PacketCommitmentPath(testPort2, testChannel2, packetSeq) + packetCommitmentPath := channel.KeyPacketCommitment(testPort2, testChannel2, packetSeq) suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) suite.updateClient() diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index c28b4cc9db00..79b84c13716a 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -82,10 +82,10 @@ func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) } -func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { +func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { res := suite.app.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: []byte(key), + Data: key, Prove: true, }) @@ -197,7 +197,7 @@ func (suite *KeeperTestSuite) TestReceivePacket() { packetDataBz := []byte("invaliddata") packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort2, testChannel1, packetDataBz) - packetCommitmentPath := channel.PacketCommitmentPath(testPort2, testChannel2, packetSeq) + packetCommitmentPath := channel.KeyPacketCommitment(testPort2, testChannel2, packetSeq) suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) suite.updateClient() diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index ee934fabd018..02b468cdb031 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -1,11 +1,10 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -13,37 +12,50 @@ import ( // NewQuerier creates a querier for the IBC module func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + var ( + res []byte + err error + ) + switch path[0] { case client.SubModuleName: switch path[1] { case client.QueryClientState: - return client.QuerierClientState(ctx, req, k.ClientKeeper) + res, err = client.QuerierClientState(ctx, req, k.ClientKeeper) + case client.QueryAllClients: + res, err = client.QuerierClients(ctx, req, k.ClientKeeper) case client.QueryConsensusState: - return client.QuerierConsensusState(ctx, req, k.ClientKeeper) + res, err = client.QuerierConsensusState(ctx, req, k.ClientKeeper) case client.QueryVerifiedRoot: - return client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) + res, err = client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName)) + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", client.SubModuleName) } case connection.SubModuleName: switch path[1] { case connection.QueryConnection: - return connection.QuerierConnection(ctx, req, k.ConnectionKeeper) + res, err = connection.QuerierConnection(ctx, req, k.ConnectionKeeper) + case connection.QueryAllConnections: + res, err = connection.QuerierConnections(ctx, req, k.ConnectionKeeper) case connection.QueryClientConnections: - return connection.QuerierClientConnections(ctx, req, k.ConnectionKeeper) + res, err = connection.QuerierClientConnections(ctx, req, k.ConnectionKeeper) default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName)) + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", connection.SubModuleName) } case channel.SubModuleName: switch path[1] { case channel.QueryChannel: - return channel.QuerierChannel(ctx, req, k.ChannelKeeper) + res, err = channel.QuerierChannel(ctx, req, k.ChannelKeeper) + case channel.QueryAllChannels: + res, err = channel.QuerierChannels(ctx, req, k.ChannelKeeper) default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", channel.SubModuleName)) + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", channel.SubModuleName) } default: - return nil, sdk.ErrUnknownRequest("unknown IBC query endpoint") + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC query endpoint") } + + return res, sdk.ConvertError(err) } } diff --git a/x/ibc/keeper/querier_test.go b/x/ibc/keeper/querier_test.go index 81abe9ffadb1..f15920608b6c 100644 --- a/x/ibc/keeper/querier_test.go +++ b/x/ibc/keeper/querier_test.go @@ -27,19 +27,24 @@ func (suite *KeeperTestSuite) TestNewQuerier() { expectsDefaultErr bool errMsg string }{ - {"client - QueryClientState", + {"client - QuerierClientState", []string{client.SubModuleName, client.QueryClientState}, false, "", }, + {"client - QuerierClients", + []string{client.SubModuleName, client.QueryAllClients}, + false, + "", + }, { - "client - QueryConsensusState", + "client - QuerierConsensusState", []string{client.SubModuleName, client.QueryConsensusState}, false, "", }, { - "client - QueryVerifiedRoot", + "client - QuerierVerifiedRoot", []string{client.SubModuleName, client.QueryVerifiedRoot}, false, "", @@ -51,13 +56,19 @@ func (suite *KeeperTestSuite) TestNewQuerier() { fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName), }, { - "connection - QueryConnection", + "connection - QuerierConnection", []string{connection.SubModuleName, connection.QueryConnection}, false, "", }, { - "connection - QueryClientConnections", + "connection - QuerierConnections", + []string{connection.SubModuleName, connection.QueryAllConnections}, + false, + "", + }, + { + "connection - QuerierClientConnections", []string{connection.SubModuleName, connection.QueryClientConnections}, false, "", @@ -69,11 +80,17 @@ func (suite *KeeperTestSuite) TestNewQuerier() { fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName), }, { - "channel - QueryChannel", + "channel - QuerierChannel", []string{channel.SubModuleName, channel.QueryChannel}, false, "", }, + { + "channel - QuerierChannels", + []string{channel.SubModuleName, channel.QueryAllChannels}, + false, + "", + }, { "channel - invalid query", []string{channel.SubModuleName, "foo"}, diff --git a/x/ibc/types/keys.go b/x/ibc/types/keys.go new file mode 100644 index 000000000000..f4f39edcd495 --- /dev/null +++ b/x/ibc/types/keys.go @@ -0,0 +1,40 @@ +package types + +import "fmt" + +const ( + // ModuleName is the name of the IBC module + ModuleName = "ibc" + + // StoreKey is the string store representation + StoreKey string = ModuleName + + // QuerierRoute is the querier route for the IBC module + QuerierRoute string = ModuleName + + // RouterKey is the msg router key for the IBC module + RouterKey string = ModuleName +) + +// KVStore key prefixes for IBC +const ( + KeyClientPrefix int = iota + 1 + KeyClientTypePrefix + KeyConsensusStatePrefix + KeyRootPrefix + KeyCommiterPrefix + KeyClientConnectionsPrefix + KeyConnectionPrefix + KeyChannelPrefix + KeyChannelCapabilityPrefix + KeyNextSeqSendPrefix + KeyNextSeqRecvPrefix + KeyPacketCommitmentPrefix + KeyPacketAckPrefix + KeyPortsPrefix +) + +// KeyPrefixBytes return the key prefix bytes from a URL string format +func KeyPrefixBytes(prefix int) []byte { + return []byte(fmt.Sprintf("%d/", prefix)) +} diff --git a/x/ibc/types/types.go b/x/ibc/types/types.go deleted file mode 100644 index 6722e5f3a426..000000000000 --- a/x/ibc/types/types.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -const ( - // ModuleName is the name of the IBC module - ModuleName = "ibc" - - // StoreKey is the string store representation - StoreKey string = ModuleName - - // QuerierRoute is the querier route for the IBC module - QuerierRoute string = ModuleName - - // RouterKey is the msg router key for the IBC module - RouterKey string = ModuleName -) From c8964675b56f355eaca13db58a93c19cceb339bc Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Wed, 18 Dec 2019 18:04:20 -0300 Subject: [PATCH 026/176] fix ICS02 queries (#5425) --- x/ibc/02-client/client/cli/query.go | 2 +- x/ibc/02-client/client/rest/query.go | 2 +- x/ibc/02-client/client/utils/utils.go | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index a64405b62993..682758783292 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -102,7 +102,7 @@ func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Comma prove := viper.GetBool(flags.FlagProve) - csRes, err := utils.QueryConsensusStateProof(cliCtx, clientID, prove) + csRes, err := utils.QueryConsensusState(cliCtx, clientID, prove) if err != nil { return err } diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go index d831aa396719..3b59aeb49f85 100644 --- a/x/ibc/02-client/client/rest/query.go +++ b/x/ibc/02-client/client/rest/query.go @@ -113,7 +113,7 @@ func queryConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - csRes, err := utils.QueryConsensusStateProof(cliCtx, clientID, prove) + csRes, err := utils.QueryConsensusState(cliCtx, clientID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 30f56e57a9db..848d489b2308 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -53,7 +53,7 @@ func QueryClientState( } var clientState types.State - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &clientState); err != nil { + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &clientState); err != nil { return types.StateResponse{}, err } @@ -64,7 +64,7 @@ func QueryClientState( // QueryConsensusStateProof queries the store to get the consensus state and a // merkle proof. -func QueryConsensusStateProof( +func QueryConsensusState( cliCtx client.CLIContext, clientID string, prove bool) (types.ConsensusStateResponse, error) { var conStateRes types.ConsensusStateResponse @@ -80,7 +80,7 @@ func QueryConsensusStateProof( } var cs tendermint.ConsensusState - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &cs); err != nil { + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { return conStateRes, err } @@ -104,7 +104,7 @@ func QueryCommitmentRoot( } var root commitment.Root - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &root); err != nil { + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &root); err != nil { return types.RootResponse{}, err } @@ -129,7 +129,7 @@ func QueryCommitter( } var committer tendermint.Committer - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &committer); err != nil { + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &committer); err != nil { return types.CommitterResponse{}, err } From 73a7e5d33bc26ec8e4b9923d499cdc6adf3eccc1 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Thu, 2 Jan 2020 10:18:12 -0300 Subject: [PATCH 027/176] fix CLI JSON param unmarshaling (#5431) --- x/ibc/02-client/client/cli/tx.go | 22 +++--- x/ibc/03-connection/client/cli/tx.go | 75 +++++---------------- x/ibc/03-connection/client/utils/utils.go | 39 +++++++++++ x/ibc/04-channel/client/cli/tx.go | 81 ++++++----------------- 4 files changed, 88 insertions(+), 129 deletions(-) diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 9e666f8f926b..6081ddcdddfe 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -7,6 +7,8 @@ import ( "os" "strings" + "github.com/pkg/errors" + "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client/context" @@ -43,14 +45,13 @@ $ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node var state exported.ConsensusState if err := cdc.UnmarshalJSON([]byte(args[1]), &state); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - + // check for file path if JSON input is not provided contents, err := ioutil.ReadFile(args[1]) if err != nil { - return fmt.Errorf("error opening proof file: %v", err) + return errors.New("neither JSON input nor path to .json file were provided") } if err := cdc.UnmarshalJSON(contents, &state); err != nil { - return fmt.Errorf("error unmarshalling consensus state file: %v", err) + return errors.Wrap(err, "error unmarshalling consensus state file") } } @@ -91,14 +92,13 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home var header exported.Header if err := cdc.UnmarshalJSON([]byte(args[1]), &header); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - + // check for file path if JSON input is not provided contents, err := ioutil.ReadFile(args[1]) if err != nil { - return fmt.Errorf("error opening proof file: %v", err) + return errors.New("neither JSON input nor path to .json file were provided") } if err := cdc.UnmarshalJSON(contents, &header); err != nil { - return fmt.Errorf("error unmarshalling header file: %v", err) + return errors.Wrap(err, "error unmarshalling header file") } } @@ -137,13 +137,13 @@ $ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 var evidence evidenceexported.Evidence if err := cdc.UnmarshalJSON([]byte(args[1]), &evidence); err != nil { fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - + // check for file path if JSON input is not provided contents, err := ioutil.ReadFile(args[1]) if err != nil { - return fmt.Errorf("error opening proof file: %v", err) + return errors.New("neither JSON input nor path to .json file were provided") } if err := cdc.UnmarshalJSON(contents, &evidence); err != nil { - return fmt.Errorf("error unmarshalling evidence file: %v", err) + return errors.Wrap(err, "error unmarshalling evidence file") } } diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 9693a62b96ea..cf54b6e785ff 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -3,12 +3,8 @@ package cli import ( "bufio" "fmt" - "io/ioutil" - "os" "strings" - "github.com/pkg/errors" - "github.com/spf13/cobra" "github.com/spf13/viper" @@ -18,9 +14,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // Connection Handshake flags @@ -50,7 +46,7 @@ $ %s tx ibc connection open-init [connection-id] [client-id] \ Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] @@ -58,16 +54,11 @@ $ %s tx ibc connection open-init [connection-id] [client-id] \ counterpartyConnectionID := args[2] counterpartyClientID := args[3] - bz, err := ioutil.ReadFile(args[4]) + counterpartyPrefix, err := utils.ParsePrefix(cliCtx.Codec, args[4]) if err != nil { return err } - var counterpartyPrefix commitment.Prefix - if err := cdc.UnmarshalJSON(bz, &counterpartyPrefix); err != nil { - return err - } - msg := types.NewMsgConnectionOpenInit( connectionID, clientID, counterpartyConnectionID, counterpartyClientID, counterpartyPrefix, cliCtx.GetFromAddress(), @@ -77,7 +68,7 @@ $ %s tx ibc connection open-init [connection-id] [client-id] \ return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -103,7 +94,7 @@ $ %s tx ibc connection open-try connection-id] [client-id] \ Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) @@ -113,29 +104,19 @@ $ %s tx ibc connection open-try connection-id] [client-id] \ counterpartyConnectionID := args[2] counterpartyClientID := args[3] - prefixBz, err := ioutil.ReadFile(args[4]) + counterpartyPrefix, err := utils.ParsePrefix(cliCtx.Codec, args[4]) if err != nil { return err } - var counterpartyPrefix commitment.Prefix - if err := cdc.UnmarshalJSON(prefixBz, &counterpartyPrefix); err != nil { - return err - } - // TODO: parse strings? counterpartyVersions := args[5] - proofBz, err := ioutil.ReadFile(args[6]) + proofInit, err := utils.ParseProof(cliCtx.Codec, args[1]) if err != nil { return err } - var proofInit commitment.Proof - if err := cdc.UnmarshalJSON(proofBz, &proofInit); err != nil { - return err - } - proofHeight := uint64(cliCtx.Height) consensusHeight, err := lastHeight(cliCtx) if err != nil { @@ -152,7 +133,7 @@ $ %s tx ibc connection open-try connection-id] [client-id] \ return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -174,17 +155,13 @@ $ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [versio Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] - proofBz, err := ioutil.ReadFile(args[1]) - if err != nil { - return err - } - var proofTry commitment.Proof - if err := cdc.UnmarshalJSON(proofBz, &proofTry); err != nil { + proofTry, err := utils.ParseProof(cliCtx.Codec, args[1]) + if err != nil { return err } @@ -205,7 +182,7 @@ $ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [versio return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -227,23 +204,18 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) connectionID := args[0] - proofBz, err := ioutil.ReadFile(args[1]) + proofAck, err := utils.ParseProof(cliCtx.Codec, args[1]) if err != nil { return err } - var proofAck commitment.Proof - if err := cdc.UnmarshalJSON(proofBz, &proofAck); err != nil { - return err - } - proofHeight := uint64(cliCtx.Height) msg := types.NewMsgConnectionOpenConfirm( @@ -254,7 +226,7 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -274,18 +246,3 @@ func lastHeight(cliCtx context.CLIContext) (uint64, error) { return uint64(info.Response.LastBlockHeight), nil } - -func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { - var path commitment.Prefix - if err := cdc.UnmarshalJSON([]byte(arg), &path); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(arg) - if err != nil { - return path, errors.Wrap(err, "error opening path file") - } - if err := cdc.UnmarshalJSON(contents, &path); err != nil { - return path, errors.Wrap(err, "error unmarshalling path file") - } - } - return path, nil -} diff --git a/x/ibc/03-connection/client/utils/utils.go b/x/ibc/03-connection/client/utils/utils.go index 0f54e9e3b5cc..55dcdcbff49e 100644 --- a/x/ibc/03-connection/client/utils/utils.go +++ b/x/ibc/03-connection/client/utils/utils.go @@ -2,11 +2,16 @@ package utils import ( "fmt" + "io/ioutil" + + "github.com/pkg/errors" abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // QueryAllConnections returns all the connections. It _does not_ return @@ -82,3 +87,37 @@ func QueryClientConnections( connPathsRes := types.NewClientConnectionsResponse(clientID, paths, res.Proof, res.Height) return connPathsRes, nil } + +// ParsePrefix unmarshals an cmd input argument from a JSON string to a commitment +// Prefix. If the input is not a JSON, it looks for a path to the JSON file. +func ParsePrefix(cdc *codec.Codec, arg string) (commitment.Prefix, error) { + var prefix commitment.Prefix + if err := cdc.UnmarshalJSON([]byte(arg), &prefix); err != nil { + // check for file path if JSON input is not provided + contents, err := ioutil.ReadFile(arg) + if err != nil { + return commitment.Prefix{}, errors.New("neither JSON input nor path to .json file were provided") + } + if err := cdc.UnmarshalJSON(contents, &prefix); err != nil { + return commitment.Prefix{}, errors.Wrap(err, "error unmarshalling commitment prefix") + } + } + return prefix, nil +} + +// ParseProof unmarshals an cmd input argument from a JSON string to a commitment +// Proof. If the input is not a JSON, it looks for a path to the JSON file. +func ParseProof(cdc *codec.Codec, arg string) (commitment.Proof, error) { + var proof commitment.Proof + if err := cdc.UnmarshalJSON([]byte(arg), &proof); err != nil { + // check for file path if JSON input is not provided + contents, err := ioutil.ReadFile(arg) + if err != nil { + return commitment.Proof{}, errors.New("neither JSON input nor path to .json file were provided") + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return commitment.Proof{}, errors.Wrap(err, "error unmarshalling commitment proof") + } + } + return proof, nil +} diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index 58bb189e2c4a..df0c53cddf82 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -2,9 +2,6 @@ package cli import ( "bufio" - "fmt" - "io/ioutil" - "os" "strconv" "strings" @@ -16,22 +13,16 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + connectionutils "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// IBC Channel flags const ( FlagOrdered = "ordered" FlagIBCVersion = "ibc-version" - FlagNode1 = "node1" - FlagNode2 = "node2" - FlagFrom1 = "from1" - FlagFrom2 = "from2" - FlagChainID2 = "chain-id2" ) -// TODO: module needs to pass the capability key (i.e store key) - // GetMsgChannelOpenInitCmd returns the command to create a MsgChannelOpenInit transaction func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -72,7 +63,7 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command // GetMsgChannelOpenTryCmd returns the command to create a MsgChannelOpenTry transaction func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "open-try [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof-init.json] [proof-height]", + Use: "open-try [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof_init.json] [proof-height]", Short: "Creates and sends a ChannelOpenTry message", Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { @@ -88,16 +79,9 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { order := channelOrder() version := viper.GetString(FlagIBCVersion) // TODO: diferenciate between channel and counterparty versions - var proof commitment.ProofI - if err := cdc.UnmarshalJSON([]byte(args[5]), &proof); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(args[5]) - if err != nil { - return fmt.Errorf("error opening proof file: %v", err) - } - if err := cdc.UnmarshalJSON(contents, &proof); err != nil { - return fmt.Errorf("error unmarshalling proof file: %v", err) - } + proofInit, err := connectionutils.ParseProof(cliCtx.Codec, args[5]) + if err != nil { + return err } proofHeight, err := strconv.ParseInt(args[6], 10, 64) @@ -108,7 +92,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { msg := types.NewMsgChannelOpenTry( portID, channelID, version, order, hops, counterpartyPortID, counterpartyChannelID, version, - proof, uint64(proofHeight), cliCtx.GetFromAddress(), + proofInit, uint64(proofHeight), cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err @@ -126,7 +110,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { // GetMsgChannelOpenAckCmd returns the command to create a MsgChannelOpenAck transaction func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "open-ack [port-id] [channel-id] [/path/to/proof-try.json] [proof-height]", + Use: "open-ack [port-id] [channel-id] [/path/to/proof_try.json] [proof-height]", Short: "Creates and sends a ChannelOpenAck message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { @@ -138,16 +122,9 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { channelID := args[1] version := viper.GetString(FlagIBCVersion) // TODO: diferenciate between channel and counterparty versions - var proof commitment.ProofI - if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(args[2]) - if err != nil { - return fmt.Errorf("error opening proof file: %v", err) - } - if err := cdc.UnmarshalJSON(contents, &proof); err != nil { - return fmt.Errorf("error unmarshalling proof file: %v", err) - } + proofTry, err := connectionutils.ParseProof(cliCtx.Codec, args[5]) + if err != nil { + return err } proofHeight, err := strconv.ParseInt(args[3], 10, 64) @@ -156,7 +133,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { } msg := types.NewMsgChannelOpenAck( - portID, channelID, version, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + portID, channelID, version, proofTry, uint64(proofHeight), cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err @@ -172,7 +149,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { // GetMsgChannelOpenConfirmCmd returns the command to create a MsgChannelOpenConfirm transaction func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return &cobra.Command{ - Use: "open-confirm [port-id] [channel-id] [/path/to/proof-ack.json] [proof-height]", + Use: "open-confirm [port-id] [channel-id] [/path/to/proof_ack.json] [proof-height]", Short: "Creates and sends a ChannelOpenConfirm message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { @@ -183,16 +160,9 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma portID := args[0] channelID := args[1] - var proof commitment.ProofI - if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(args[2]) - if err != nil { - return fmt.Errorf("error opening proof file: %v", err) - } - if err := cdc.UnmarshalJSON(contents, &proof); err != nil { - return fmt.Errorf("error unmarshalling proof file: %v", err) - } + proofAck, err := connectionutils.ParseProof(cliCtx.Codec, args[5]) + if err != nil { + return err } proofHeight, err := strconv.ParseInt(args[3], 10, 64) @@ -201,7 +171,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma } msg := types.NewMsgChannelOpenConfirm( - portID, channelID, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + portID, channelID, proofAck, uint64(proofHeight), cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err @@ -239,7 +209,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command // GetMsgChannelCloseConfirmCmd returns the command to create a MsgChannelCloseConfirm transaction func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return &cobra.Command{ - Use: "close-confirm [port-id] [channel-id] [/path/to/proof-init.json] [proof-height]", + Use: "close-confirm [port-id] [channel-id] [/path/to/proof_init.json] [proof-height]", Short: "Creates and sends a ChannelCloseConfirm message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { @@ -250,16 +220,9 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm portID := args[0] channelID := args[1] - var proof commitment.ProofI - if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(args[2]) - if err != nil { - return fmt.Errorf("error opening proof file: %v", err) - } - if err := cdc.UnmarshalJSON(contents, &proof); err != nil { - return fmt.Errorf("error unmarshalling proof file: %v", err) - } + proofInit, err := connectionutils.ParseProof(cliCtx.Codec, args[5]) + if err != nil { + return err } proofHeight, err := strconv.ParseInt(args[3], 10, 64) @@ -268,7 +231,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm } msg := types.NewMsgChannelCloseConfirm( - portID, channelID, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + portID, channelID, proofInit, uint64(proofHeight), cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err From e06d6a95382290ab848367b625387840da2c1a68 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Thu, 2 Jan 2020 11:36:36 -0300 Subject: [PATCH 028/176] Fix inconsistent string lookup functions (#5437) * fix inconsistent string lookup functions * test client type and ordering * channel and connection state tests * address golangcibot comments * fix test --- x/ibc/02-client/exported/exported.go | 14 +-- x/ibc/02-client/exported/exported_test.go | 49 +++++++++++ x/ibc/02-client/handler.go | 10 ++- x/ibc/02-client/types/msgs.go | 8 +- x/ibc/03-connection/alias.go | 4 +- x/ibc/03-connection/keeper/handshake.go | 2 +- x/ibc/03-connection/keeper/handshake_test.go | 2 +- x/ibc/03-connection/keeper/keeper_test.go | 2 +- x/ibc/03-connection/types/connection.go | 34 +++----- x/ibc/03-connection/types/connection_test.go | 46 ++++++++++ x/ibc/04-channel/alias.go | 9 +- x/ibc/04-channel/keeper/handshake.go | 8 +- x/ibc/04-channel/keeper/handshake_test.go | 22 ++--- x/ibc/04-channel/keeper/packet.go | 2 +- x/ibc/04-channel/types/channel.go | 73 +++++++--------- x/ibc/04-channel/types/channel_test.go | 91 ++++++++++++++++++++ 16 files changed, 276 insertions(+), 100 deletions(-) create mode 100644 x/ibc/02-client/exported/exported_test.go create mode 100644 x/ibc/03-connection/types/connection_test.go create mode 100644 x/ibc/04-channel/types/channel_test.go diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index 9a5f2bc2e89f..50632bf71ca8 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -82,23 +82,23 @@ func (ct *ClientType) UnmarshalJSON(data []byte) error { return err } - bz2, err := ClientTypeFromString(s) - if err != nil { - return err + clientType := ClientTypeFromString(s) + if clientType == 0 { + return fmt.Errorf("invalid client type '%s'", s) } - *ct = bz2 + *ct = clientType return nil } // ClientTypeFromString returns a byte that corresponds to the registered client // type. It returns 0 if the type is not found/registered. -func ClientTypeFromString(clientType string) (ClientType, error) { +func ClientTypeFromString(clientType string) ClientType { switch clientType { case ClientTypeTendermint: - return Tendermint, nil + return Tendermint default: - return 0, fmt.Errorf("'%s' is not a valid client type", clientType) + return 0 } } diff --git a/x/ibc/02-client/exported/exported_test.go b/x/ibc/02-client/exported/exported_test.go new file mode 100644 index 000000000000..f0eb1fc4d182 --- /dev/null +++ b/x/ibc/02-client/exported/exported_test.go @@ -0,0 +1,49 @@ +package exported + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestClientTypeString(t *testing.T) { + cases := []struct { + msg string + name string + clientType ClientType + }{ + {"tendermint client", ClientTypeTendermint, Tendermint}, + {"empty type", "", 0}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.clientType, ClientTypeFromString(tt.name), tt.msg) + require.Equal(t, tt.name, tt.clientType.String(), tt.msg) + } +} + +func TestClientTypeMarshalJSON(t *testing.T) { + cases := []struct { + msg string + name string + clientType ClientType + expectPass bool + }{ + {"tendermint client should have passed", ClientTypeTendermint, Tendermint, true}, + {"empty type should have failed", "", 0, false}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.clientType.MarshalJSON() + require.NoError(t, err) + var ct ClientType + if tt.expectPass { + require.NoError(t, ct.UnmarshalJSON(bz), tt.msg) + require.Equal(t, tt.name, ct.String(), tt.msg) + } else { + require.Error(t, ct.UnmarshalJSON(bz), tt.msg) + } + } +} diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index 595656a86c20..7363053f2319 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -12,12 +12,14 @@ import ( // HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.Result { - clientType, err := exported.ClientTypeFromString(msg.ClientType) - if err != nil { - return sdk.ResultFromError(ErrInvalidClientType(DefaultCodespace, err.Error())) + clientType := exported.ClientTypeFromString(msg.ClientType) + if clientType == 0 { + return sdk.ResultFromError( + ErrInvalidClientType(DefaultCodespace, fmt.Sprintf("invalid client type '%s'", msg.ClientType)), + ) } - _, err = k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) + _, err := k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) if err != nil { return sdk.ResultFromError(err) } diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index 039f9d04d879..d52c0a614a44 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -1,6 +1,8 @@ package types import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" @@ -51,8 +53,10 @@ func (msg MsgCreateClient) ValidateBasic() sdk.Error { if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { return sdk.ConvertError(err) } - if _, err := exported.ClientTypeFromString(msg.ClientType); err != nil { - return sdk.ConvertError(errors.ErrInvalidClientType(errors.DefaultCodespace, err.Error())) + if clientType := exported.ClientTypeFromString(msg.ClientType); clientType == 0 { + return sdk.ConvertError( + errors.ErrInvalidClientType(errors.DefaultCodespace, fmt.Sprintf("invalid client type '%s'", msg.ClientType)), + ) } if msg.ConsensusState == nil { return sdk.ConvertError(errors.ErrInvalidConsensus(errors.DefaultCodespace)) diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index 67367f45b6cb..4d44e18048e8 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -12,11 +12,11 @@ import ( ) const ( - NONE = types.NONE + UNINITIALIZED = types.UNINITIALIZED INIT = types.INIT TRYOPEN = types.TRYOPEN OPEN = types.OPEN - StateNone = types.StateNone + StateUninitialized = types.StateUninitialized StateInit = types.StateInit StateTryOpen = types.StateTryOpen StateOpen = types.StateOpen diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index 8e8dcbb96090..e5a011a84b3a 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -78,7 +78,7 @@ func (k Keeper) ConnOpenTry( version := types.PickVersion(counterpartyVersions, types.GetCompatibleVersions()) // connection defines chain B's ConnectionEnd - connection := types.NewConnectionEnd(types.NONE, clientID, counterparty, []string{version}) + connection := types.NewConnectionEnd(types.UNINITIALIZED, clientID, counterparty, []string{version}) expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) if err != nil { return err diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index ba42ba25ee27..52c53df884d5 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -132,7 +132,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { } invalidConnectionState := func() error { - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.NONE) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.UNINITIALIZED) //suite.updateClient(testClientID2) proofTry, proofHeight := suite.queryProof(connectionKey) diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index a4872d114363..8b3fb7f78cce 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -105,7 +105,7 @@ func (suite KeeperTestSuite) TestGetAllConnections() { } conn3 := types.ConnectionEnd{ - State: types.NONE, + State: types.UNINITIALIZED, ClientID: testClientID3, Counterparty: counterparty2, Versions: types.GetCompatibleVersions(), diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 8abbda60a313..65806e9f5a9a 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -2,7 +2,6 @@ package types import ( "encoding/json" - "fmt" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -72,7 +71,7 @@ type State byte // available connection states const ( - NONE State = iota // default State + UNINITIALIZED State = iota // default State INIT TRYOPEN OPEN @@ -80,17 +79,15 @@ const ( // string representation of the connection states const ( - StateNone string = "NONE" - StateInit string = "INIT" - StateTryOpen string = "TRYOPEN" - StateOpen string = "OPEN" + StateUninitialized string = "UNINITIALIZED" + StateInit string = "INIT" + StateTryOpen string = "TRYOPEN" + StateOpen string = "OPEN" ) // String implements the Stringer interface func (cs State) String() string { switch cs { - case NONE: - return StateNone case INIT: return StateInit case TRYOPEN: @@ -98,23 +95,21 @@ func (cs State) String() string { case OPEN: return StateOpen default: - return "" + return StateUninitialized } } // StateFromString parses a string into a connection state -func StateFromString(state string) (State, error) { +func StateFromString(state string) State { switch state { - case StateNone: - return NONE, nil case StateInit: - return INIT, nil + return INIT case StateTryOpen: - return TRYOPEN, nil + return TRYOPEN case StateOpen: - return OPEN, nil + return OPEN default: - return NONE, fmt.Errorf("'%s' is not a valid connection state", state) + return UNINITIALIZED } } @@ -131,11 +126,6 @@ func (cs *State) UnmarshalJSON(data []byte) error { return err } - bz2, err := StateFromString(s) - if err != nil { - return err - } - - *cs = bz2 + *cs = StateFromString(s) return nil } diff --git a/x/ibc/03-connection/types/connection_test.go b/x/ibc/03-connection/types/connection_test.go new file mode 100644 index 000000000000..7202b6f72a0b --- /dev/null +++ b/x/ibc/03-connection/types/connection_test.go @@ -0,0 +1,46 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestConnectionStateString(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.state, StateFromString(tt.name)) + require.Equal(t, tt.name, tt.state.String()) + } +} + +func TestConnectionlStateMarshalJSON(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.state.MarshalJSON() + require.NoError(t, err) + var state State + require.NoError(t, state.UnmarshalJSON(bz)) + require.Equal(t, tt.name, state.String()) + } +} diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index d5494175505a..f2d6a7f49d24 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -12,7 +12,7 @@ import ( ) const ( - NONE = types.NONE + UNINITIALIZED = types.UNINITIALIZED UNORDERED = types.UNORDERED ORDERED = types.ORDERED OrderNone = types.OrderNone @@ -20,12 +20,13 @@ const ( OrderOrdered = types.OrderOrdered CLOSED = types.CLOSED INIT = types.INIT - OPENTRY = types.OPENTRY + TRYOPEN = types.TRYOPEN OPEN = types.OPEN - StateClosed = types.StateClosed + StateUninitialized = types.StateUninitialized StateInit = types.StateInit - StateOpenTry = types.StateOpenTry + StateTryOpen = types.StateTryOpen StateOpen = types.StateOpen + StateClosed = types.StateClosed DefaultCodespace = types.DefaultCodespace CodeChannelExists = types.CodeChannelExists CodeChannelNotFound = types.CodeChannelNotFound diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index f71115da4792..5deef767e415 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -46,7 +46,7 @@ func (k Keeper) ChanOpenInit( return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) } - if connectionEnd.State == connection.NONE { + if connectionEnd.State == connection.UNINITIALIZED { return connection.ErrInvalidConnectionState( k.codespace, fmt.Sprintf("connection state cannot be NONE"), @@ -112,7 +112,7 @@ func (k Keeper) ChanOpenTry( // NOTE: this step has been switched with the one below to reverse the connection // hops - channel := types.NewChannel(types.OPENTRY, order, counterparty, connectionHops, version) + channel := types.NewChannel(types.TRYOPEN, order, counterparty, connectionHops, version) counterpartyHops, found := k.CounterpartyHops(ctx, channel) if !found { @@ -200,7 +200,7 @@ func (k Keeper) ChanOpenAck( // counterparty of the counterparty channel end (i.e self) counterparty := types.NewCounterparty(portID, channelID) expectedChannel := types.NewChannel( - types.OPENTRY, channel.Ordering, counterparty, + types.TRYOPEN, channel.Ordering, counterparty, counterpartyHops, channel.Version, ) @@ -238,7 +238,7 @@ func (k Keeper) ChanOpenConfirm( return types.ErrChannelNotFound(k.codespace, portID, channelID) } - if channel.State != types.OPENTRY { + if channel.State != types.TRYOPEN { return types.ErrInvalidChannelState( k.codespace, fmt.Sprintf("channel state is not OPENTRY (got %s)", channel.State.String()), diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 98fa69d5451e..4e39b906eb44 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -117,7 +117,7 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) suite.Error(err) // connection does not exist - suite.createConnection(connection.NONE) + suite.createConnection(connection.UNINITIALIZED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) suite.Error(err) // invalid connection state @@ -149,12 +149,12 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) suite.Error(err) // connection does not exist - suite.createConnection(connection.NONE) + suite.createConnection(connection.UNINITIALIZED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.TRYOPEN) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) @@ -168,14 +168,14 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) suite.True(found) - suite.Equal(types.OPENTRY.String(), channel.State.String(), "invalid channel state") + suite.Equal(types.TRYOPEN.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanOpenAck() { suite.bindPort(testPort1) channelKey := types.KeyChannel(testPort2, testChannel2) - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.TRYOPEN) suite.updateClient() proofTry, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) @@ -193,7 +193,7 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) suite.Error(err) // connection does not exist - suite.createConnection(connection.NONE) + suite.createConnection(connection.UNINITIALIZED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) suite.Error(err) // invalid connection state @@ -204,7 +204,7 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) suite.Error(err) // channel membership verification failed due to invalid counterparty - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.TRYOPEN) suite.updateClient() proofTry, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) @@ -229,20 +229,20 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) suite.Error(err) // invalid channel state - suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.OPENTRY) + suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.TRYOPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort1, testChannel2, proofAck, uint64(proofHeight)) suite.Error(err) // unauthenticated port - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.TRYOPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) suite.Error(err) // connection does not exist - suite.createConnection(connection.NONE) + suite.createConnection(connection.UNINITIALIZED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.TRYOPEN) suite.updateClient() proofAck, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 0590f3cfd37c..515b7ecdf107 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -154,7 +154,7 @@ func (k Keeper) SendPacket( return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) } - if connectionEnd.State == connection.NONE { + if connectionEnd.State == connection.UNINITIALIZED { return connection.ErrInvalidConnectionState( k.codespace, fmt.Sprintf("connection is closed (i.e NONE)"), diff --git a/x/ibc/04-channel/types/channel.go b/x/ibc/04-channel/types/channel.go index d14c42ad6e2c..1250d1208808 100644 --- a/x/ibc/04-channel/types/channel.go +++ b/x/ibc/04-channel/types/channel.go @@ -94,7 +94,7 @@ const ( // channel order types const ( - OrderNone string = "NONE" + OrderNone string = "" OrderUnordered string = "UNORDERED" OrderOrdered string = "ORDERED" ) @@ -102,14 +102,12 @@ const ( // String implements the Stringer interface func (o Order) String() string { switch o { - case NONE: - return OrderNone case UNORDERED: return OrderUnordered case ORDERED: return OrderOrdered default: - return "" + return OrderNone } } @@ -126,26 +124,24 @@ func (o *Order) UnmarshalJSON(data []byte) error { return err } - bz2, err := OrderFromString(s) - if err != nil { - return err + order := OrderFromString(s) + if order == 0 { + return fmt.Errorf("invalid channel ordering '%s'", s) } - *o = bz2 + *o = order return nil } // OrderFromString parses a string into a channel order byte -func OrderFromString(order string) (Order, error) { +func OrderFromString(order string) Order { switch order { - case OrderNone: - return NONE, nil case OrderUnordered: - return UNORDERED, nil + return UNORDERED case OrderOrdered: - return ORDERED, nil + return ORDERED default: - return 0, fmt.Errorf("'%s' is not a valid channel ordering", order) + return NONE } } @@ -155,33 +151,35 @@ type State byte // channel state types const ( - CLOSED State = iota + 1 // A channel end has been closed and can no longer be used to send or receive packets. - INIT // A channel end has just started the opening handshake. - OPENTRY // A channel end has acknowledged the handshake step on the counterparty chain. - OPEN // A channel end has completed the handshake and is ready to send and receive packets. + UNINITIALIZED State = iota // Default State + INIT // A channel end has just started the opening handshake. + TRYOPEN // A channel end has acknowledged the handshake step on the counterparty chain. + OPEN // A channel end has completed the handshake and is ready to send and receive packets. + CLOSED // A channel end has been closed and can no longer be used to send or receive packets. ) // string representation of the channel states const ( - StateClosed string = "CLOSED" - StateInit string = "INIT" - StateOpenTry string = "OPENTRY" - StateOpen string = "OPEN" + StateUninitialized string = "UNINITIALIZED" + StateInit string = "INIT" + StateTryOpen string = "TRYOPEN" + StateOpen string = "OPEN" + StateClosed string = "CLOSED" ) // String implements the Stringer interface func (s State) String() string { switch s { - case CLOSED: - return StateClosed case INIT: return StateInit - case OPENTRY: - return StateOpenTry + case TRYOPEN: + return StateTryOpen case OPEN: return StateOpen + case CLOSED: + return StateClosed default: - return "" + return StateUninitialized } } @@ -198,27 +196,22 @@ func (s *State) UnmarshalJSON(data []byte) error { return err } - bz2, err := StateFromString(stateStr) - if err != nil { - return err - } - - *s = bz2 + *s = StateFromString(stateStr) return nil } // StateFromString parses a string into a channel state byte -func StateFromString(state string) (State, error) { +func StateFromString(state string) State { switch state { case StateClosed: - return CLOSED, nil + return CLOSED case StateInit: - return INIT, nil - case StateOpenTry: - return OPENTRY, nil + return INIT + case StateTryOpen: + return TRYOPEN case StateOpen: - return OPEN, nil + return OPEN default: - return CLOSED, fmt.Errorf("'%s' is not a valid channel state", state) + return UNINITIALIZED } } diff --git a/x/ibc/04-channel/types/channel_test.go b/x/ibc/04-channel/types/channel_test.go new file mode 100644 index 000000000000..56b0dfe5eefa --- /dev/null +++ b/x/ibc/04-channel/types/channel_test.go @@ -0,0 +1,91 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestChannelStateString(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + {StateClosed, CLOSED}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.state, StateFromString(tt.name)) + require.Equal(t, tt.name, tt.state.String()) + } +} + +func TestChannelStateMarshalJSON(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + {StateClosed, CLOSED}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.state.MarshalJSON() + require.NoError(t, err) + var state State + require.NoError(t, state.UnmarshalJSON(bz)) + require.Equal(t, tt.name, state.String()) + } +} + +func TestOrderString(t *testing.T) { + cases := []struct { + name string + order Order + }{ + {OrderNone, NONE}, + {OrderUnordered, UNORDERED}, + {OrderOrdered, ORDERED}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.order, OrderFromString(tt.name)) + require.Equal(t, tt.name, tt.order.String()) + } +} + +func TestOrderMarshalJSON(t *testing.T) { + cases := []struct { + msg string + name string + order Order + expectPass bool + }{ + {"none ordering should have failed", OrderNone, NONE, false}, + {"unordered should have passed", OrderUnordered, UNORDERED, true}, + {"ordered should have passed", OrderOrdered, ORDERED, true}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.order.MarshalJSON() + require.NoError(t, err) + var order Order + if tt.expectPass { + require.NoError(t, order.UnmarshalJSON(bz), tt.msg) + require.Equal(t, tt.name, order.String(), tt.msg) + } else { + require.Error(t, order.UnmarshalJSON(bz), tt.msg) + } + } +} From 221ce96f5d85907c67ae4a60e03e091c88ae57c7 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Thu, 2 Jan 2020 19:58:58 -0300 Subject: [PATCH 029/176] Update x/ibc error handling (#5462) * Merge PR #5428: Add mod, exponentiation for uint * Modified examples in distribution module (#5441) * Merge PR #5442: Remove of the client/alias.go * Merge PR #5445: Mock rpcclient in tests for votes pagination * Merge PR #5435: Added iterator that allows to read only requested values * Merge PR #5427: Remove code duplication in x/auth/client/cli * Merge PR #5421: Refactor Error Handling * update x/ibc error handling * update ICS24 and ICS02 errors * ICS03, ICS23 and common errors * updates from master and errors from ICS04 * build * fix ics20 tests * fix tests * golangcibot fixes Co-authored-by: Kevin Davis Co-authored-by: kaustubhkapatral <54210167+kaustubhkapatral@users.noreply.github.com> Co-authored-by: Ferenc Fabian Co-authored-by: Dmitry Shulyak Co-authored-by: Alessio Treglia Co-authored-by: Alexander Bezobchuk --- CHANGELOG.md | 26 +- baseapp/abci.go | 176 ++++--- baseapp/baseapp.go | 161 +++--- baseapp/baseapp_test.go | 203 +++++--- baseapp/helpers.go | 6 +- baseapp/queryrouter_test.go | 2 +- baseapp/router_test.go | 4 +- client/alias.go | 129 ----- client/context/broadcast.go | 7 +- client/context/broadcast_test.go | 11 +- client/flags/flags.go | 4 + client/routes.go | 3 +- .../adr-015-ibc-packet-receiver.md | 2 +- docs/building-modules/handler.md | 13 +- docs/building-modules/querier.md | 6 +- server/mock/app.go | 12 +- server/mock/tx.go | 7 +- simapp/app.go | 18 +- simapp/test_helpers.go | 20 +- store/errors/errors.go | 26 - store/iavl/store.go | 9 +- store/iavl/store_test.go | 21 +- store/rootmulti/store.go | 21 +- store/rootmulti/store_test.go | 20 +- store/types/iterator.go | 61 +++ store/types/iterator_test.go | 119 +++++ types/decimal.go | 24 +- types/errors.go | 361 -------------- types/errors/abci.go | 39 ++ types/errors/abci_test.go | 26 +- types/errors/errors.go | 43 +- types/errors/stacktrace_test.go | 8 +- types/errors_test.go | 138 ------ types/handler.go | 2 +- types/queryable.go | 9 +- types/result.go | 57 +-- types/result_test.go | 14 +- types/store.go | 12 + types/tx_msg.go | 8 +- types/uint.go | 44 ++ types/uint_test.go | 19 + x/auth/ante/ante_test.go | 71 ++- x/auth/client/cli/decode.go | 102 ++-- x/auth/client/rest/query.go | 6 +- x/auth/client/utils/tx.go | 14 +- x/auth/client/utils/tx_test.go | 7 +- x/auth/keeper/keeper.go | 9 +- x/auth/keeper/querier.go | 15 +- x/auth/types/expected_keepers.go | 2 +- x/auth/types/stdtx.go | 26 +- x/auth/types/stdtx_test.go | 13 +- x/bank/alias.go | 29 +- x/bank/bench_test.go | 10 +- x/bank/client/cli/tx.go | 3 +- x/bank/handler.go | 28 +- x/bank/handler_test.go | 13 +- x/bank/internal/keeper/keeper.go | 101 ++-- x/bank/internal/keeper/keeper_test.go | 12 +- x/bank/internal/keeper/querier.go | 13 +- x/bank/internal/types/errors.go | 34 +- x/bank/internal/types/msgs.go | 43 +- x/bank/simulation/operations.go | 13 +- x/crisis/alias.go | 34 +- x/crisis/client/cli/tx.go | 3 +- x/crisis/handler.go | 17 +- x/crisis/handler_test.go | 24 +- x/crisis/internal/keeper/keeper.go | 2 +- x/crisis/internal/types/errors.go | 22 +- x/crisis/internal/types/expected_keepers.go | 2 +- x/crisis/internal/types/msgs.go | 4 +- x/distribution/alias.go | 16 +- x/distribution/client/cli/query.go | 15 +- x/distribution/client/cli/tx.go | 15 +- x/distribution/handler.go | 37 +- x/distribution/keeper/allocation_test.go | 38 +- x/distribution/keeper/delegation.go | 4 +- x/distribution/keeper/delegation_test.go | 64 ++- x/distribution/keeper/fee_pool.go | 5 +- x/distribution/keeper/keeper.go | 29 +- x/distribution/keeper/proposal_handler.go | 5 +- x/distribution/keeper/querier.go | 88 ++-- x/distribution/keeper/querier_test.go | 12 +- x/distribution/keeper/test_common.go | 8 +- x/distribution/simulation/operations.go | 25 +- x/distribution/types/errors.go | 56 +-- x/distribution/types/expected_keepers.go | 6 +- x/distribution/types/msg.go | 24 +- x/distribution/types/proposal.go | 9 +- x/evidence/alias.go | 30 +- x/evidence/client/cli/query.go | 5 +- x/evidence/client/cli/tx.go | 3 +- x/evidence/genesis_test.go | 3 +- x/evidence/handler.go | 15 +- x/evidence/handler_test.go | 13 +- x/evidence/internal/keeper/infraction_test.go | 15 +- x/evidence/internal/keeper/keeper.go | 13 +- x/evidence/internal/keeper/keeper_test.go | 3 +- x/evidence/internal/keeper/querier.go | 8 +- x/evidence/internal/types/errors.go | 56 +-- x/evidence/internal/types/msgs.go | 8 +- x/genutil/client/cli/collect.go | 4 +- x/genutil/client/cli/gentx.go | 26 +- x/genutil/client/cli/init.go | 6 +- x/genutil/client/cli/init_test.go | 4 +- x/genutil/client/cli/migrate_test.go | 4 +- x/genutil/client/rest/query.go | 19 +- x/gov/abci.go | 2 +- x/gov/abci_test.go | 51 +- x/gov/alias.go | 87 ++-- x/gov/client/cli/query.go | 6 +- x/gov/client/cli/tx.go | 5 +- x/gov/client/rest/query.go | 3 +- x/gov/client/utils/query.go | 13 +- x/gov/client/utils/query_test.go | 118 +++-- x/gov/genesis_test.go | 2 +- x/gov/handler.go | 33 +- x/gov/handler_test.go | 7 +- x/gov/keeper/deposit.go | 11 +- x/gov/keeper/deposit_test.go | 6 +- x/gov/keeper/keeper.go | 6 +- x/gov/keeper/proposal.go | 12 +- x/gov/keeper/proposal_test.go | 25 +- x/gov/keeper/querier.go | 76 +-- x/gov/keeper/querier_test.go | 10 +- x/gov/keeper/test_common.go | 8 +- x/gov/keeper/vote.go | 9 +- x/gov/legacy/v0_36/types.go | 30 +- x/gov/simulation/operations.go | 19 +- x/gov/test_common.go | 28 +- x/gov/types/content.go | 16 +- x/gov/types/errors.go | 71 +-- x/gov/types/expected_keepers.go | 18 +- x/gov/types/msgs.go | 27 +- x/gov/types/proposal.go | 8 +- x/ibc/02-client/alias.go | 29 +- x/ibc/02-client/client/cli/cli.go | 6 +- x/ibc/02-client/client/utils/utils.go | 7 +- x/ibc/02-client/handler.go | 26 +- x/ibc/02-client/keeper/client.go | 24 +- x/ibc/02-client/keeper/keeper.go | 14 +- x/ibc/02-client/keeper/querier.go | 13 +- x/ibc/02-client/types/errors/errors.go | 144 +----- x/ibc/02-client/types/msgs.go | 42 +- x/ibc/02-client/types/msgs_test.go | 2 +- .../types/tendermint/consensus_state.go | 6 +- x/ibc/02-client/types/tendermint/evidence.go | 31 +- x/ibc/02-client/types/tendermint/header.go | 6 +- .../types/tendermint/misbehaviour.go | 30 +- x/ibc/03-connection/alias.go | 46 +- x/ibc/03-connection/client/cli/cli.go | 6 +- x/ibc/03-connection/handler.go | 32 +- x/ibc/03-connection/keeper/handshake.go | 32 +- x/ibc/03-connection/keeper/keeper.go | 9 +- x/ibc/03-connection/keeper/querier.go | 8 +- x/ibc/03-connection/types/connection.go | 16 +- x/ibc/03-connection/types/errors.go | 96 +--- x/ibc/03-connection/types/msgs.go | 75 +-- x/ibc/03-connection/types/msgs_test.go | 212 +++++--- x/ibc/04-channel/alias.go | 139 +++--- x/ibc/04-channel/client/cli/cli.go | 6 +- x/ibc/04-channel/client/utils/utils.go | 6 +- x/ibc/04-channel/handler.go | 48 +- x/ibc/04-channel/keeper/handshake.go | 107 ++-- x/ibc/04-channel/keeper/keeper.go | 4 +- x/ibc/04-channel/keeper/packet.go | 152 +++--- x/ibc/04-channel/keeper/querier.go | 2 +- x/ibc/04-channel/keeper/timeout.go | 61 +-- x/ibc/04-channel/types/channel.go | 36 +- x/ibc/04-channel/types/errors.go | 110 +---- x/ibc/04-channel/types/msgs.go | 72 +-- x/ibc/04-channel/types/msgs_test.go | 180 ++++--- x/ibc/04-channel/types/packet.go | 57 ++- x/ibc/05-port/alias.go | 11 +- x/ibc/05-port/keeper/keeper.go | 17 +- x/ibc/05-port/types/errors.go | 42 +- x/ibc/20-transfer/alias.go | 1 - x/ibc/20-transfer/client/cli/cli.go | 6 +- x/ibc/20-transfer/handler.go | 16 +- x/ibc/20-transfer/handler_test.go | 65 ++- x/ibc/20-transfer/keeper/callbacks.go | 32 +- x/ibc/20-transfer/keeper/keeper.go | 8 +- x/ibc/20-transfer/keeper/relay.go | 25 +- x/ibc/20-transfer/types/expected_keepers.go | 10 +- x/ibc/20-transfer/types/keys.go | 3 - x/ibc/20-transfer/types/msgs.go | 33 +- x/ibc/20-transfer/types/packet.go | 11 +- x/ibc/23-commitment/errors.go | 14 + x/ibc/23-commitment/merkle.go | 8 + x/ibc/23-commitment/merkle_test.go | 3 + x/ibc/23-commitment/types.go | 2 + x/ibc/24-host/errors.go | 42 +- x/ibc/24-host/validate.go | 12 +- x/ibc/alias.go | 9 +- x/ibc/client/cli/cli.go | 5 +- x/ibc/handler.go | 8 +- x/ibc/keeper/keeper.go | 12 +- x/ibc/keeper/querier.go | 4 +- x/ibc/types/errors.go | 30 +- x/mint/alias.go | 7 +- x/mint/client/cli/query.go | 3 +- x/mint/internal/keeper/keeper.go | 8 +- x/mint/internal/keeper/querier.go | 19 +- x/mint/internal/types/expected_keepers.go | 6 +- x/mock/app.go | 2 +- x/mock/app_test.go | 16 +- x/mock/test_utils.go | 33 +- x/mock/types.go | 11 +- x/params/alias.go | 18 +- x/params/commmon_test.go | 2 +- x/params/keeper.go | 20 +- x/params/proposal_handler.go | 12 +- x/params/proposal_handler_test.go | 2 +- x/params/types/errors.go | 49 +- x/params/types/proposal.go | 15 +- x/slashing/abci_test.go | 6 +- x/slashing/alias.go | 15 +- x/slashing/app_test.go | 14 +- x/slashing/client/cli/query.go | 3 +- x/slashing/client/cli/tx.go | 3 +- x/slashing/handler.go | 15 +- x/slashing/handler_test.go | 91 ++-- x/slashing/internal/keeper/keeper.go | 7 +- x/slashing/internal/keeper/keeper_test.go | 30 +- x/slashing/internal/keeper/querier.go | 28 +- x/slashing/internal/keeper/test_common.go | 8 +- x/slashing/internal/keeper/unjail.go | 16 +- x/slashing/internal/types/errors.go | 57 +-- x/slashing/internal/types/msg.go | 4 +- x/slashing/simulation/operations.go | 6 +- x/staking/alias.go | 27 +- x/staking/app_test.go | 4 +- x/staking/client/cli/query.go | 3 +- x/staking/client/cli/tx.go | 20 +- x/staking/exported/exported.go | 40 +- x/staking/handler.go | 75 +-- x/staking/handler_test.go | 467 +++++++++++------- x/staking/keeper/delegation.go | 71 +-- x/staking/keeper/keeper.go | 14 +- x/staking/keeper/pool.go | 4 +- x/staking/keeper/querier.go | 134 ++--- x/staking/keeper/query_utils.go | 8 +- x/staking/keeper/test_common.go | 5 +- x/staking/keeper/validator.go | 2 +- x/staking/simulation/operations.go | 31 +- x/staking/types/commission.go | 24 +- x/staking/types/errors.go | 270 ++-------- x/staking/types/expected_keepers.go | 8 +- x/staking/types/historical_info.go | 4 +- x/staking/types/msg.go | 58 ++- x/staking/types/validator.go | 25 +- x/supply/alias.go | 3 +- x/supply/client/cli/query.go | 3 +- x/supply/internal/keeper/bank.go | 85 ++-- x/supply/internal/keeper/bank_test.go | 24 +- x/supply/internal/keeper/key.go | 8 - x/supply/internal/keeper/querier.go | 19 +- x/supply/internal/types/expected_keepers.go | 10 +- x/upgrade/abci_test.go | 12 +- x/upgrade/alias.go | 8 +- x/upgrade/handler.go | 12 +- x/upgrade/internal/keeper/keeper.go | 10 +- x/upgrade/internal/keeper/querier.go | 20 +- x/upgrade/internal/types/plan.go | 12 +- x/upgrade/internal/types/proposal.go | 14 +- x/upgrade/module.go | 6 +- 265 files changed, 3831 insertions(+), 4517 deletions(-) delete mode 100644 client/alias.go delete mode 100644 store/errors/errors.go create mode 100644 store/types/iterator.go create mode 100644 store/types/iterator_test.go delete mode 100644 types/errors.go delete mode 100644 types/errors_test.go create mode 100644 x/ibc/23-commitment/errors.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 8507b6b1f2ec..be6b7cec3274 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,21 @@ logic has been implemented for v0.38 target version. Applications can migrate vi ### API Breaking Changes +* (baseapp/types) [\#5421](https://github.com/cosmos/cosmos-sdk/pull/5421) The `Error` interface (`types/errors.go`) + has been removed in favor of the concrete type defined in `types/errors/` which implements the standard `error` + interface. As a result, the `Handler` and `Querier` implementations now return a standard `error`. + Within `BaseApp`, `runTx` now returns a `(GasInfo, *Result, error)` tuple and `runMsgs` returns a + `(*Result, error)` tuple. A reference to a `Result` is now used to indicate success whereas an error + signals an invalid message or failed message execution. As a result, the fields `Code`, `Codespace`, + `GasWanted`, and `GasUsed` have been removed the `Result` type. The latter two fields are now found + in the `GasInfo` type which is always returned regardless of execution outcome. + + Note to developers: Since all handlers and queriers must now return a standard `error`, the `types/errors/` + package contains all the relevant and pre-registered errors that you typically work with. A typical + error returned will look like `sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "...")`. You can retrieve + relevant ABCI information from the error via `ABCIInfo`. +* (client) [\#5442](https://github.com/cosmos/cosmos-sdk/pull/5442) Remove client/alias.go as it's not necessary and +components can be imported directly from the packages. * (store) [\#4748](https://github.com/cosmos/cosmos-sdk/pull/4748) The `CommitMultiStore` interface now requires a `SetInterBlockCache` method. Applications that do not wish to support this can simply have this method perform a no-op. @@ -76,7 +91,7 @@ if the provided arguments are invalid. `StdTx.Signatures` to get back the array of StdSignatures `[]StdSignature`. * (modules) [\#5299](https://github.com/cosmos/cosmos-sdk/pull/5299) `HandleDoubleSign` along with params `MaxEvidenceAge` and `DoubleSignJailEndTime` have moved from the `x/slashing` module to the `x/evidence` module. -* (keys) [\#4941](https://github.com/cosmos/cosmos-sdk/issues/4941) Initializing a new keybase through `NewKeyringFromHomeFlag`, `NewKeyringFromDir`, `NewKeyBaseFromHomeFlag`, `NewKeyBaseFromDir`, or `NewInMemory` functions now accept optional parameters of type `KeybaseOption`. These optional parameters are also added on the keys subcommands functions, which are now public, and allows these options to be set on the commands or ignored to default to previous behavior. +* (keys) [\#4941](https://github.com/cosmos/cosmos-sdk/issues/4941) Initializing a new keybase through `NewKeyringFromHomeFlag`, `NewKeyringFromDir`, `NewKeyBaseFromHomeFlag`, `NewKeyBaseFromDir`, or `NewInMemory` functions now accept optional parameters of type `KeybaseOption`. These optional parameters are also added on the keys subcommands functions, which are now public, and allows these options to be set on the commands or ignored to default to previous behavior. * The option introduced in this PR is `WithKeygenFunc` which allows a custom bytes to key implementation to be defined when keys are created. * (simapp) [\#5419](https://github.com/cosmos/cosmos-sdk/pull/5419) simapp/helpers.GenTx() now accepts a gas argument. @@ -88,9 +103,11 @@ if the provided arguments are invalid. increased significantly due to modular `AnteHandler` support. Increase GasLimit accordingly. * (rest) [\#5336](https://github.com/cosmos/cosmos-sdk/issues/5336) `MsgEditValidator` uses `description` instead of `Description` as a JSON key. * (keys) [\#5097](https://github.com/cosmos/cosmos-sdk/pull/5097) Due to the keybase -> keyring transition, keys need to be migrated. See `keys migrate` command for more info. +* (x/auth) [\#5424](https://github.com/cosmos/cosmos-sdk/issues/5424) Drop `decode-tx` command from x/auth/client/cli, duplicate of the `decode` command. ### Features +* (store) [\#5435](https://github.com/cosmos/cosmos-sdk/pull/5435) New iterator for paginated requests. Iterator limits DB reads to the range of the requested page. * (x/evidence) [\#5240](https://github.com/cosmos/cosmos-sdk/pull/5240) Initial implementation of the `x/evidence` module. * (cli) [\#5212](https://github.com/cosmos/cosmos-sdk/issues/5212) The `q gov proposals` command now supports pagination. * (store) [\#4724](https://github.com/cosmos/cosmos-sdk/issues/4724) Multistore supports substore migrations upon load. New `rootmulti.Store.LoadLatestVersionAndUpgrade` method in @@ -213,11 +230,12 @@ to detail this new feature and how state transitions occur. * (docs/spec) All module specs moved into their respective module dir in x/ (i.e. docs/spec/staking -->> x/staking/spec) * (docs/) [\#5379](https://github.com/cosmos/cosmos-sdk/pull/5379) Major documentation refactor, including: * (docs/intro/) Add and improve introduction material for newcomers. - * (docs/basics/) Add documentation about basic concepts of the cosmos sdk such as the anatomy of an SDK application, the transaction lifecycle or accounts. - * (docs/core/) Add documentation about core conepts of the cosmos sdk such as `baseapp`, `server`, `store`s, `context` and more. + * (docs/basics/) Add documentation about basic concepts of the cosmos sdk such as the anatomy of an SDK application, the transaction lifecycle or accounts. + * (docs/core/) Add documentation about core conepts of the cosmos sdk such as `baseapp`, `server`, `store`s, `context` and more. * (docs/building-modules/) Add reference documentation on concepts relevant for module developers (`keeper`, `handler`, `messages`, `queries`,...). * (docs/interfaces/) Add documentation on building interfaces for the Cosmos SDK. * Redesigned user interface that features new dynamically generated sidebar, build-time code embedding from GitHub, new homepage as well as many other improvements. +* (types) [\#5428](https://github.com/cosmos/cosmos-sdk/pull/5428) Add `Mod` (modulo) method and `RelativePow` (exponentation) function for `Uint`. ### Bug Fixes @@ -2801,3 +2819,5 @@ BUG FIXES: [v0.37.1]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.1 [v0.37.0]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.0 [v0.36.0]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.36.0 + + diff --git a/baseapp/abci.go b/baseapp/abci.go index e93b7c56c2c9..57bcec661eff 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // InitChain implements the ABCI interface. It runs the initialization logic @@ -153,54 +154,66 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc return } -// CheckTx implements the ABCI interface. It runs the "basic checks" to see -// whether or not a transaction can possibly be executed, first decoding and then -// the ante handler (which checks signatures/fees/ValidateBasic). -// -// NOTE:CheckTx does not run the actual Msg handler function(s). -func (app *BaseApp) CheckTx(req abci.RequestCheckTx) (res abci.ResponseCheckTx) { - var result sdk.Result - +// CheckTx implements the ABCI interface and executes a tx in CheckTx mode. In +// CheckTx mode, messages are not executed. This means messages are only validated +// and only the AnteHandler is executed. State is persisted to the BaseApp's +// internal CheckTx state if the AnteHandler passes. Otherwise, the ResponseCheckTx +// will contain releveant error information. Regardless of tx execution outcome, +// the ResponseCheckTx will contain relevant gas execution context. +func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { tx, err := app.txDecoder(req.Tx) + if err != nil { + return sdkerrors.ResponseCheckTx(err, 0, 0) + } + + var mode runTxMode + switch { - case err != nil: - result = err.Result() case req.Type == abci.CheckTxType_New: - result = app.runTx(runTxModeCheck, req.Tx, tx) + mode = runTxModeCheck + case req.Type == abci.CheckTxType_Recheck: - result = app.runTx(runTxModeReCheck, req.Tx, tx) + mode = runTxModeReCheck + default: - panic(fmt.Sprintf("Unknown RequestCheckTx Type: %v", req.Type)) + panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type)) + } + + gInfo, result, err := app.runTx(mode, req.Tx, tx) + if err != nil { + return sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed) } return abci.ResponseCheckTx{ - Code: uint32(result.Code), - Data: result.Data, + GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? + GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints? Log: result.Log, - GasWanted: int64(result.GasWanted), // TODO: Should type accept unsigned ints? - GasUsed: int64(result.GasUsed), // TODO: Should type accept unsigned ints? + Data: result.Data, Events: result.Events.ToABCIEvents(), } } -// DeliverTx implements the ABCI interface. -func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) (res abci.ResponseDeliverTx) { - var result sdk.Result - +// DeliverTx implements the ABCI interface and executes a tx in DeliverTx mode. +// State only gets persisted if all messages are valid and get executed successfully. +// Otherwise, the ResponseDeliverTx will contain releveant error information. +// Regardless of tx execution outcome, the ResponseDeliverTx will contain relevant +// gas execution context. +func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { tx, err := app.txDecoder(req.Tx) if err != nil { - result = err.Result() - } else { - result = app.runTx(runTxModeDeliver, req.Tx, tx) + return sdkerrors.ResponseDeliverTx(err, 0, 0) + } + + gInfo, result, err := app.runTx(runTxModeDeliver, req.Tx, tx) + if err != nil { + return sdkerrors.ResponseDeliverTx(err, gInfo.GasWanted, gInfo.GasUsed) } return abci.ResponseDeliverTx{ - Code: uint32(result.Code), - Codespace: string(result.Codespace), - Data: result.Data, + GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? + GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints? Log: result.Log, - GasWanted: int64(result.GasWanted), // TODO: Should type accept unsigned ints? - GasUsed: int64(result.GasUsed), // TODO: Should type accept unsigned ints? + Data: result.Data, Events: result.Events.ToABCIEvents(), } } @@ -278,11 +291,10 @@ func (app *BaseApp) halt() { // Query implements the ABCI interface. It delegates to CommitMultiStore if it // implements Queryable. -func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) { +func (app *BaseApp) Query(req abci.RequestQuery) abci.ResponseQuery { path := splitPath(req.Path) if len(path) == 0 { - msg := "no query path provided" - return sdk.ErrUnknownRequest(msg).QueryResult() + sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no query path provided")) } switch path[0] { @@ -294,61 +306,59 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return handleQueryStore(app, path, req) case "p2p": - return handleQueryP2P(app, path, req) + return handleQueryP2P(app, path) case "custom": return handleQueryCustom(app, path, req) } - msg := "unknown query path" - return sdk.ErrUnknownRequest(msg).QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown query path")) } -func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) (res abci.ResponseQuery) { +func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.ResponseQuery { if len(path) >= 2 { - var result sdk.Result - switch path[1] { case "simulate": txBytes := req.Data + tx, err := app.txDecoder(txBytes) if err != nil { - result = err.Result() - } else { - result = app.Simulate(txBytes, tx) + return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to decode tx")) + } + + gInfo, _, _ := app.Simulate(txBytes, tx) + + return abci.ResponseQuery{ + Codespace: sdkerrors.RootCodespace, + Height: req.Height, + Value: codec.Cdc.MustMarshalBinaryLengthPrefixed(gInfo.GasUsed), } case "version": return abci.ResponseQuery{ - Code: uint32(sdk.CodeOK), - Codespace: string(sdk.CodespaceRoot), + Codespace: sdkerrors.RootCodespace, Height: req.Height, Value: []byte(app.appVersion), } default: - result = sdk.ErrUnknownRequest(fmt.Sprintf("unknown query: %s", path)).Result() - } - - value := codec.Cdc.MustMarshalBinaryLengthPrefixed(result) - return abci.ResponseQuery{ - Code: uint32(sdk.CodeOK), - Codespace: string(sdk.CodespaceRoot), - Height: req.Height, - Value: value, + return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query: %s", path)) } } - msg := "expected second parameter to be either 'simulate' or 'version', neither was present" - return sdk.ErrUnknownRequest(msg).QueryResult() + return sdkerrors.QueryResult( + sdkerrors.Wrap( + sdkerrors.ErrUnknownRequest, + "expected second parameter to be either 'simulate' or 'version', neither was present", + ), + ) } func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.ResponseQuery { // "/store" prefix for store queries queryable, ok := app.cms.(sdk.Queryable) if !ok { - msg := "multistore doesn't support queries" - return sdk.ErrUnknownRequest(msg).QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries")) } req.Path = "/" + strings.Join(path[1:], "/") @@ -359,7 +369,12 @@ func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.R } if req.Height <= 1 && req.Prove { - return sdk.ErrInternal("cannot query with proof when height <= 1; please provide a valid height").QueryResult() + return sdkerrors.QueryResult( + sdkerrors.Wrap( + sdkerrors.ErrInvalidRequest, + "cannot query with proof when height <= 1; please provide a valid height", + ), + ) } resp := queryable.Query(req) @@ -368,7 +383,7 @@ func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.R return resp } -func handleQueryP2P(app *BaseApp, path []string, _ abci.RequestQuery) (res abci.ResponseQuery) { +func handleQueryP2P(app *BaseApp, path []string) abci.ResponseQuery { // "/p2p" prefix for p2p queries if len(path) >= 4 { cmd, typ, arg := path[1], path[2], path[3] @@ -383,28 +398,30 @@ func handleQueryP2P(app *BaseApp, path []string, _ abci.RequestQuery) (res abci. } default: - msg := "expected second parameter to be 'filter'" - return sdk.ErrUnknownRequest(msg).QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "expected second parameter to be 'filter'")) } } - msg := "Expected path is p2p filter " - return sdk.ErrUnknownRequest(msg).QueryResult() + return sdkerrors.QueryResult( + sdkerrors.Wrap( + sdkerrors.ErrUnknownRequest, "expected path is p2p filter ", + ), + ) } -func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res abci.ResponseQuery) { +func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) abci.ResponseQuery { // path[0] should be "custom" because "/custom" prefix is required for keeper // queries. // // The QueryRouter routes using path[1]. For example, in the path // "custom/gov/proposal", QueryRouter routes using "gov". if len(path) < 2 || path[1] == "" { - return sdk.ErrUnknownRequest("No route for custom query specified").QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no route for custom query specified")) } querier := app.queryRouter.Route(path[1]) if querier == nil { - return sdk.ErrUnknownRequest(fmt.Sprintf("no custom querier found for route %s", path[1])).QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "no custom querier found for route %s", path[1])) } // when a client did not provide a query height, manually inject the latest @@ -413,17 +430,22 @@ func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res } if req.Height <= 1 && req.Prove { - return sdk.ErrInternal("cannot query with proof when height <= 1; please provide a valid height").QueryResult() + return sdkerrors.QueryResult( + sdkerrors.Wrap( + sdkerrors.ErrInvalidRequest, + "cannot query with proof when height <= 1; please provide a valid height", + ), + ) } cacheMS, err := app.cms.CacheMultiStoreWithVersion(req.Height) if err != nil { - return sdk.ErrInternal( - fmt.Sprintf( - "failed to load state at height %d; %s (latest height: %d)", - req.Height, err, app.LastBlockHeight(), + return sdkerrors.QueryResult( + sdkerrors.Wrapf( + sdkerrors.ErrInvalidRequest, + "failed to load state at height %d; %s (latest height: %d)", req.Height, err, app.LastBlockHeight(), ), - ).QueryResult() + ) } // cache wrap the commit-multistore for safety @@ -435,18 +457,18 @@ func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res // // For example, in the path "custom/gov/proposal/test", the gov querier gets // []string{"proposal", "test"} as the path. - resBytes, queryErr := querier(ctx, path[2:], req) - if queryErr != nil { + resBytes, err := querier(ctx, path[2:], req) + if err != nil { + space, code, log := sdkerrors.ABCIInfo(err, false) return abci.ResponseQuery{ - Code: uint32(queryErr.Code()), - Codespace: string(queryErr.Codespace()), + Code: code, + Codespace: space, + Log: log, Height: req.Height, - Log: queryErr.ABCILog(), } } return abci.ResponseQuery{ - Code: uint32(sdk.CodeOK), Height: req.Height, Value: resBytes, } diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index ae1ca19db7f7..46f3e2649907 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -19,6 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/store" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) const ( @@ -446,13 +447,12 @@ func (app *BaseApp) validateHeight(req abci.RequestBeginBlock) error { } // validateBasicTxMsgs executes basic validator calls for messages. -func validateBasicTxMsgs(msgs []sdk.Msg) sdk.Error { +func validateBasicTxMsgs(msgs []sdk.Msg) error { if len(msgs) == 0 { - return sdk.ErrUnknownRequest("Tx.GetMsgs() must return at least one message in list") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "must contain at least one message") } for _, msg := range msgs { - // Validate the Msg. err := msg.ValidateBasic() if err != nil { return err @@ -508,11 +508,14 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context return ctx.WithMultiStore(msCache), msCache } -// runTx processes a transaction. The transactions is processed via an -// anteHandler. The provided txBytes may be nil in some cases, eg. in tests. For -// further details on transaction execution, reference the BaseApp SDK -// documentation. -func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk.Result) { +// runTx processes a transaction within a given execution mode, encoded transaction +// bytes, and the decoded transaction itself. All state transitions occur through +// a cached Context depending on the mode provided. State only gets persisted +// if all messages get executed successfully and the execution mode is DeliverTx. +// Note, gas execution info is always returned. A reference to a Result is +// returned if the tx does not run out of gas and if all the messages are valid +// and execute successfully. An error is returned otherwise. +func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (gInfo sdk.GasInfo, result *sdk.Result, err error) { // NOTE: GasWanted should be returned by the AnteHandler. GasUsed is // determined by the GasMeter. We need access to the context to get the gas // meter so we initialize upfront. @@ -523,7 +526,8 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk // only run the tx if there is block gas remaining if mode == runTxModeDeliver && ctx.BlockGasMeter().IsOutOfGas() { - return sdk.ErrOutOfGas("no block gas left to run tx").Result() + gInfo = sdk.GasInfo{GasUsed: ctx.BlockGasMeter().GasConsumed()} + return gInfo, nil, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") } var startingGas uint64 @@ -534,20 +538,28 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk defer func() { if r := recover(); r != nil { switch rType := r.(type) { + // TODO: Use ErrOutOfGas instead of ErrorOutOfGas which would allow us + // to keep the stracktrace. case sdk.ErrorOutOfGas: - log := fmt.Sprintf( - "out of gas in location: %v; gasWanted: %d, gasUsed: %d", - rType.Descriptor, gasWanted, ctx.GasMeter().GasConsumed(), + err = sdkerrors.Wrap( + sdkerrors.ErrOutOfGas, fmt.Sprintf( + "out of gas in location: %v; gasWanted: %d, gasUsed: %d", + rType.Descriptor, gasWanted, ctx.GasMeter().GasConsumed(), + ), ) - result = sdk.ErrOutOfGas(log).Result() + default: - log := fmt.Sprintf("recovered: %v\nstack:\n%v", r, string(debug.Stack())) - result = sdk.ErrInternal(log).Result() + err = sdkerrors.Wrap( + sdkerrors.ErrPanic, fmt.Sprintf( + "recovered: %v\nstack:\n%v", r, string(debug.Stack()), + ), + ) } + + result = nil } - result.GasWanted = gasWanted - result.GasUsed = ctx.GasMeter().GasConsumed() + gInfo = sdk.GasInfo{GasWanted: gasWanted, GasUsed: ctx.GasMeter().GasConsumed()} }() // If BlockGasMeter() panics it will be caught by the above recover and will @@ -558,8 +570,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk defer func() { if mode == runTxModeDeliver { ctx.BlockGasMeter().ConsumeGas( - ctx.GasMeter().GasConsumedToLimit(), - "block gas meter", + ctx.GasMeter().GasConsumedToLimit(), "block gas meter", ) if ctx.BlockGasMeter().GasConsumed() < startingGas { @@ -568,20 +579,21 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk } }() - var msgs = tx.GetMsgs() + msgs := tx.GetMsgs() if err := validateBasicTxMsgs(msgs); err != nil { - return err.Result() + gInfo = sdk.GasInfo{GasUsed: ctx.BlockGasMeter().GasConsumed()} + return gInfo, nil, err } if app.anteHandler != nil { var anteCtx sdk.Context var msCache sdk.CacheMultiStore - // Cache wrap context before anteHandler call in case it aborts. + // Cache wrap context before AnteHandler call in case it aborts. // This is required for both CheckTx and DeliverTx. // Ref: https://github.com/cosmos/cosmos-sdk/issues/2772 // - // NOTE: Alternatively, we could require that anteHandler ensures that + // NOTE: Alternatively, we could require that AnteHandler ensures that // writes do not happen if aborted/failed. This may have some // performance benefits, but it'll be more difficult to get right. anteCtx, msCache = app.cacheTxContext(ctx, txBytes) @@ -589,11 +601,11 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk newCtx, err := app.anteHandler(anteCtx, tx, mode == runTxModeSimulate) if !newCtx.IsZero() { // At this point, newCtx.MultiStore() is cache-wrapped, or something else - // replaced by the ante handler. We want the original multistore, not one - // which was cache-wrapped for the ante handler. + // replaced by the AnteHandler. We want the original multistore, not one + // which was cache-wrapped for the AnteHandler. // // Also, in the case of the tx aborting, we need to track gas consumed via - // the instantiated gas meter in the ante handler, so we update the context + // the instantiated gas meter in the AnteHandler, so we update the context // prior to returning. ctx = newCtx.WithMultiStore(ms) } @@ -602,10 +614,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk gasWanted = ctx.GasMeter().Limit() if err != nil { - res := sdk.ResultFromError(err) - res.GasWanted = gasWanted - res.GasUsed = ctx.GasMeter().GasConsumed() - return res + return gInfo, nil, err } msCache.Write() @@ -615,83 +624,63 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk // MultiStore in case message processing fails. At this point, the MultiStore // is doubly cached-wrapped. runMsgCtx, msCache := app.cacheTxContext(ctx, txBytes) - result = app.runMsgs(runMsgCtx, msgs, mode) - result.GasWanted = gasWanted - // Safety check: don't write the cache state unless we're in DeliverTx. - if mode != runTxModeDeliver { - return result - } - - // only update state if all messages pass - if result.IsOK() { + // Attempt to execute all messages and only update state if all messages pass + // and we're in DeliverTx. Note, runMsgs will never return a reference to a + // Result if any single message fails or does not have a registered Handler. + result, err = app.runMsgs(runMsgCtx, msgs, mode) + if err == nil && mode == runTxModeDeliver { msCache.Write() } - return result + return gInfo, result, err } -// runMsgs iterates through all the messages and executes them. -func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (result sdk.Result) { +// runMsgs iterates through a list of messages and executes them with the provided +// Context and execution mode. Messages will only be executed during simulation +// and DeliverTx. An error is returned if any single message fails or if a +// Handler does not exist for a given message route. Otherwise, a reference to a +// Result is returned. The caller must not commit state if an error is returned. +func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*sdk.Result, error) { msgLogs := make(sdk.ABCIMessageLogs, 0, len(msgs)) - data := make([]byte, 0, len(msgs)) - var ( - code sdk.CodeType - codespace sdk.CodespaceType - ) - events := sdk.EmptyEvents() - // NOTE: GasWanted is determined by ante handler and GasUsed by the GasMeter. + // NOTE: GasWanted is determined by the AnteHandler and GasUsed by the GasMeter. for i, msg := range msgs { - // match message route + // skip actual execution for (Re)CheckTx mode + if mode == runTxModeCheck || mode == runTxModeReCheck { + break + } + msgRoute := msg.Route() handler := app.router.Route(msgRoute) if handler == nil { - return sdk.ErrUnknownRequest("unrecognized message type: " + msgRoute).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message route: %s; message index: %d", msgRoute, i) } - var msgResult sdk.Result - - // skip actual execution for CheckTx and ReCheckTx mode - if mode != runTxModeCheck && mode != runTxModeReCheck { - msgResult = handler(ctx, msg) + msgResult, err := handler(ctx, msg) + if err != nil { + return nil, sdkerrors.Wrapf(err, "failed to execute message; message index: %d", i) } - // Each message result's Data must be length prefixed in order to separate - // each result. - data = append(data, msgResult.Data...) - - msgEvents := msgResult.Events - - // append events from the message's execution and a message action event - msgEvents = msgEvents.AppendEvent( + msgEvents := sdk.Events{ sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, msg.Type())), - ) - - events = events.AppendEvents(msgEvents) - - // stop execution and return on first failed message - if !msgResult.IsOK() { - msgLogs = append(msgLogs, sdk.NewABCIMessageLog(uint16(i), false, msgResult.Log, msgEvents)) - - code = msgResult.Code - codespace = msgResult.Codespace - break } + msgEvents = msgEvents.AppendEvents(msgResult.Events) - msgLogs = append(msgLogs, sdk.NewABCIMessageLog(uint16(i), true, msgResult.Log, msgEvents)) - } - - result = sdk.Result{ - Code: code, - Codespace: codespace, - Data: data, - Log: strings.TrimSpace(msgLogs.String()), - GasUsed: ctx.GasMeter().GasConsumed(), - Events: events, + // append message events, data and logs + // + // Note: Each message result's data must be length-prefixed in order to + // separate each result. + events = events.AppendEvents(msgEvents) + data = append(data, msgResult.Data...) + msgLogs = append(msgLogs, sdk.NewABCIMessageLog(uint16(i), msgResult.Log, msgEvents)) } - return result + return &sdk.Result{ + Data: data, + Log: strings.TrimSpace(msgLogs.String()), + Events: events, + }, nil } diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 52df9bbef0ed..01996e27ef40 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -514,8 +514,8 @@ func (tx *txTest) setFailOnHandler(fail bool) { } // Implements Tx -func (tx txTest) GetMsgs() []sdk.Msg { return tx.Msgs } -func (tx txTest) ValidateBasic() sdk.Error { return nil } +func (tx txTest) GetMsgs() []sdk.Msg { return tx.Msgs } +func (tx txTest) ValidateBasic() error { return nil } const ( routeMsgCounter = "msgCounter" @@ -534,19 +534,20 @@ func (msg msgCounter) Route() string { return routeMsgCounter } func (msg msgCounter) Type() string { return "counter1" } func (msg msgCounter) GetSignBytes() []byte { return nil } func (msg msgCounter) GetSigners() []sdk.AccAddress { return nil } -func (msg msgCounter) ValidateBasic() sdk.Error { +func (msg msgCounter) ValidateBasic() error { if msg.Counter >= 0 { return nil } - return sdk.ErrInvalidSequence("counter should be a non-negative integer.") + return sdkerrors.Wrap(sdkerrors.ErrInvalidSequence, "counter should be a non-negative integer") } -func newTxCounter(txInt int64, msgInts ...int64) *txTest { - msgs := make([]sdk.Msg, 0, len(msgInts)) - for _, msgInt := range msgInts { - msgs = append(msgs, msgCounter{msgInt, false}) +func newTxCounter(counter int64, msgCounters ...int64) *txTest { + msgs := make([]sdk.Msg, 0, len(msgCounters)) + for _, c := range msgCounters { + msgs = append(msgs, msgCounter{c, false}) } - return &txTest{msgs, txInt, false} + + return &txTest{msgs, counter, false} } // a msg we dont know how to route @@ -573,24 +574,26 @@ func (msg msgCounter2) Route() string { return routeMsgCounter2 } func (msg msgCounter2) Type() string { return "counter2" } func (msg msgCounter2) GetSignBytes() []byte { return nil } func (msg msgCounter2) GetSigners() []sdk.AccAddress { return nil } -func (msg msgCounter2) ValidateBasic() sdk.Error { +func (msg msgCounter2) ValidateBasic() error { if msg.Counter >= 0 { return nil } - return sdk.ErrInvalidSequence("counter should be a non-negative integer.") + return sdkerrors.Wrap(sdkerrors.ErrInvalidSequence, "counter should be a non-negative integer") } // amino decode func testTxDecoder(cdc *codec.Codec) sdk.TxDecoder { - return func(txBytes []byte) (sdk.Tx, sdk.Error) { + return func(txBytes []byte) (sdk.Tx, error) { var tx txTest if len(txBytes) == 0 { - return nil, sdk.ErrTxDecode("txBytes are empty") + return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx bytes are empty") } + err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx) if err != nil { - return nil, sdk.ErrTxDecode("").TraceSDK(err.Error()) + return nil, sdkerrors.ErrTxDecode } + return tx, nil } } @@ -604,25 +607,28 @@ func anteHandlerTxTest(t *testing.T, capKey sdk.StoreKey, storeKey []byte) sdk.A return newCtx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "ante handler failure") } - res := incrementingCounter(t, store, storeKey, txTest.Counter) - if !res.IsOK() { - err = sdkerrors.ABCIError(string(res.Codespace), uint32(res.Code), res.Log) + _, err = incrementingCounter(t, store, storeKey, txTest.Counter) + if err != nil { + return newCtx, err } - return + + return newCtx, nil } } func handlerMsgCounter(t *testing.T, capKey sdk.StoreKey, deliverKey []byte) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { store := ctx.KVStore(capKey) var msgCount int64 + switch m := msg.(type) { case *msgCounter: if m.FailOnHandler { - return sdk.ErrInternal("message handler failure").Result() + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "message handler failure") } msgCount = m.Counter + case *msgCounter2: msgCount = m.Counter } @@ -651,11 +657,11 @@ func setIntOnStore(store sdk.KVStore, key []byte, i int64) { // check counter matches what's in store. // increment and store -func incrementingCounter(t *testing.T, store sdk.KVStore, counterKey []byte, counter int64) (res sdk.Result) { +func incrementingCounter(t *testing.T, store sdk.KVStore, counterKey []byte, counter int64) (*sdk.Result, error) { storedCounter := getIntFromStore(store, counterKey) require.Equal(t, storedCounter, counter) setIntOnStore(store, counterKey, counter+1) - return + return &sdk.Result{}, nil } //--------------------------------------------------------------------- @@ -675,7 +681,9 @@ func TestCheckTx(t *testing.T) { anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, counterKey)) } routerOpt := func(bapp *BaseApp) { // TODO: can remove this once CheckTx doesnt process msgs. - bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result { return sdk.Result{} }) + bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + return &sdk.Result{}, nil + }) } app := setupBaseApp(t, anteOpt, routerOpt) @@ -847,9 +855,9 @@ func TestSimulateTx(t *testing.T) { } routerOpt := func(bapp *BaseApp) { - bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx.GasMeter().ConsumeGas(gasConsumed, "test") - return sdk.Result{GasUsed: ctx.GasMeter().GasConsumed()} + return &sdk.Result{}, nil }) } @@ -872,14 +880,16 @@ func TestSimulateTx(t *testing.T) { require.Nil(t, err) // simulate a message, check gas reported - result := app.Simulate(txBytes, tx) - require.True(t, result.IsOK(), result.Log) - require.Equal(t, gasConsumed, result.GasUsed) + gInfo, result, err := app.Simulate(txBytes, tx) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, gasConsumed, gInfo.GasUsed) // simulate again, same result - result = app.Simulate(txBytes, tx) - require.True(t, result.IsOK(), result.Log) - require.Equal(t, gasConsumed, result.GasUsed) + gInfo, result, err = app.Simulate(txBytes, tx) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, gasConsumed, gInfo.GasUsed) // simulate by calling Query with encoded tx query := abci.RequestQuery{ @@ -889,11 +899,10 @@ func TestSimulateTx(t *testing.T) { queryResult := app.Query(query) require.True(t, queryResult.IsOK(), queryResult.Log) - var res sdk.Result - codec.Cdc.MustUnmarshalBinaryLengthPrefixed(queryResult.Value, &res) - require.Nil(t, err, "Result unmarshalling failed") - require.True(t, res.IsOK(), res.Log) - require.Equal(t, gasConsumed, res.GasUsed, res.Log) + var res uint64 + err = codec.Cdc.UnmarshalBinaryLengthPrefixed(queryResult.Value, &res) + require.NoError(t, err) + require.Equal(t, gasConsumed, res) app.EndBlock(abci.RequestEndBlock{}) app.Commit() } @@ -906,7 +915,9 @@ func TestRunInvalidTransaction(t *testing.T) { }) } routerOpt := func(bapp *BaseApp) { - bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (res sdk.Result) { return }) + bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + return &sdk.Result{}, nil + }) } app := setupBaseApp(t, anteOpt, routerOpt) @@ -914,15 +925,19 @@ func TestRunInvalidTransaction(t *testing.T) { header := abci.Header{Height: 1} app.BeginBlock(abci.RequestBeginBlock{Header: header}) - // Transaction with no messages + // transaction with no messages { emptyTx := &txTest{} - err := app.Deliver(emptyTx) - require.EqualValues(t, sdk.CodeUnknownRequest, err.Code) - require.EqualValues(t, sdk.CodespaceRoot, err.Codespace) + _, result, err := app.Deliver(emptyTx) + require.Error(t, err) + require.Nil(t, result) + + space, code, _ := sdkerrors.ABCIInfo(err, false) + require.EqualValues(t, sdkerrors.ErrInvalidRequest.Codespace(), space, err) + require.EqualValues(t, sdkerrors.ErrInvalidRequest.ABCICode(), code, err) } - // Transaction where ValidateBasic fails + // transaction where ValidateBasic fails { testCases := []struct { tx *txTest @@ -940,27 +955,39 @@ func TestRunInvalidTransaction(t *testing.T) { for _, testCase := range testCases { tx := testCase.tx - res := app.Deliver(tx) + _, result, err := app.Deliver(tx) + if testCase.fail { - require.EqualValues(t, sdk.CodeInvalidSequence, res.Code) - require.EqualValues(t, sdk.CodespaceRoot, res.Codespace) + require.Error(t, err) + + space, code, _ := sdkerrors.ABCIInfo(err, false) + require.EqualValues(t, sdkerrors.ErrInvalidSequence.Codespace(), space, err) + require.EqualValues(t, sdkerrors.ErrInvalidSequence.ABCICode(), code, err) } else { - require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) + require.NotNil(t, result) } } } - // Transaction with no known route + // transaction with no known route { unknownRouteTx := txTest{[]sdk.Msg{msgNoRoute{}}, 0, false} - err := app.Deliver(unknownRouteTx) - require.EqualValues(t, sdk.CodeUnknownRequest, err.Code) - require.EqualValues(t, sdk.CodespaceRoot, err.Codespace) + _, result, err := app.Deliver(unknownRouteTx) + require.Error(t, err) + require.Nil(t, result) + + space, code, _ := sdkerrors.ABCIInfo(err, false) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.Codespace(), space, err) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), code, err) unknownRouteTx = txTest{[]sdk.Msg{msgCounter{}, msgNoRoute{}}, 0, false} - err = app.Deliver(unknownRouteTx) - require.EqualValues(t, sdk.CodeUnknownRequest, err.Code) - require.EqualValues(t, sdk.CodespaceRoot, err.Codespace) + _, result, err = app.Deliver(unknownRouteTx) + require.Error(t, err) + require.Nil(t, result) + + space, code, _ = sdkerrors.ABCIInfo(err, false) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.Codespace(), space, err) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), code, err) } // Transaction with an unregistered message @@ -975,9 +1002,10 @@ func TestRunInvalidTransaction(t *testing.T) { txBytes, err := newCdc.MarshalBinaryLengthPrefixed(tx) require.NoError(t, err) + res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes}) - require.EqualValues(t, sdk.CodeTxDecode, res.Code) - require.EqualValues(t, sdk.CodespaceRoot, res.Codespace) + require.EqualValues(t, sdkerrors.ErrTxDecode.ABCICode(), res.Code) + require.EqualValues(t, sdkerrors.ErrTxDecode.Codespace(), res.Codespace) } } @@ -996,8 +1024,7 @@ func TestTxGasLimits(t *testing.T) { if r := recover(); r != nil { switch rType := r.(type) { case sdk.ErrorOutOfGas: - log := fmt.Sprintf("out of gas in location: %v", rType.Descriptor) - err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, log) + err = sdkerrors.Wrapf(sdkerrors.ErrOutOfGas, "out of gas in location: %v", rType.Descriptor) default: panic(r) } @@ -1007,16 +1034,16 @@ func TestTxGasLimits(t *testing.T) { count := tx.(*txTest).Counter newCtx.GasMeter().ConsumeGas(uint64(count), "counter-ante") - return + return newCtx, nil }) } routerOpt := func(bapp *BaseApp) { - bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { count := msg.(msgCounter).Counter ctx.GasMeter().ConsumeGas(uint64(count), "counter-handler") - return sdk.Result{} + return &sdk.Result{}, nil }) } @@ -1051,17 +1078,21 @@ func TestTxGasLimits(t *testing.T) { for i, tc := range testCases { tx := tc.tx - res := app.Deliver(tx) + gInfo, result, err := app.Deliver(tx) // check gas used and wanted - require.Equal(t, tc.gasUsed, res.GasUsed, fmt.Sprintf("%d: %v, %v", i, tc, res)) + require.Equal(t, tc.gasUsed, gInfo.GasUsed, fmt.Sprintf("tc #%d; gas: %v, result: %v, err: %s", i, gInfo, result, err)) // check for out of gas if !tc.fail { - require.True(t, res.IsOK(), fmt.Sprintf("%d: %v, %v", i, tc, res)) + require.NotNil(t, result, fmt.Sprintf("%d: %v, %v", i, tc, err)) } else { - require.Equal(t, sdk.CodeOutOfGas, res.Code, fmt.Sprintf("%d: %v, %v", i, tc, res)) - require.Equal(t, sdk.CodespaceRoot, res.Codespace) + require.Error(t, err) + require.Nil(t, result) + + space, code, _ := sdkerrors.ABCIInfo(err, false) + require.EqualValues(t, sdkerrors.ErrOutOfGas.Codespace(), space, err) + require.EqualValues(t, sdkerrors.ErrOutOfGas.ABCICode(), code, err) } } } @@ -1093,10 +1124,10 @@ func TestMaxBlockGasLimits(t *testing.T) { } routerOpt := func(bapp *BaseApp) { - bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { count := msg.(msgCounter).Counter ctx.GasMeter().ConsumeGas(uint64(count), "counter-handler") - return sdk.Result{} + return &sdk.Result{}, nil }) } @@ -1137,23 +1168,29 @@ func TestMaxBlockGasLimits(t *testing.T) { // execute the transaction multiple times for j := 0; j < tc.numDelivers; j++ { - res := app.Deliver(tx) + _, result, err := app.Deliver(tx) ctx := app.getState(runTxModeDeliver).ctx - blockGasUsed := ctx.BlockGasMeter().GasConsumed() // check for failed transactions if tc.fail && (j+1) > tc.failAfterDeliver { - require.Equal(t, res.Code, sdk.CodeOutOfGas, fmt.Sprintf("%d: %v, %v", i, tc, res)) - require.Equal(t, res.Codespace, sdk.CodespaceRoot, fmt.Sprintf("%d: %v, %v", i, tc, res)) + require.Error(t, err, fmt.Sprintf("tc #%d; result: %v, err: %s", i, result, err)) + require.Nil(t, result, fmt.Sprintf("tc #%d; result: %v, err: %s", i, result, err)) + + space, code, _ := sdkerrors.ABCIInfo(err, false) + require.EqualValues(t, sdkerrors.ErrOutOfGas.Codespace(), space, err) + require.EqualValues(t, sdkerrors.ErrOutOfGas.ABCICode(), code, err) require.True(t, ctx.BlockGasMeter().IsOutOfGas()) } else { // check gas used and wanted + blockGasUsed := ctx.BlockGasMeter().GasConsumed() expBlockGasUsed := tc.gasUsedPerDeliver * uint64(j+1) - require.Equal(t, expBlockGasUsed, blockGasUsed, - fmt.Sprintf("%d,%d: %v, %v, %v, %v", i, j, tc, expBlockGasUsed, blockGasUsed, res)) + require.Equal( + t, expBlockGasUsed, blockGasUsed, + fmt.Sprintf("%d,%d: %v, %v, %v, %v", i, j, tc, expBlockGasUsed, blockGasUsed, result), + ) - require.True(t, res.IsOK(), fmt.Sprintf("%d,%d: %v, %v", i, j, tc, res)) + require.NotNil(t, result, fmt.Sprintf("tc #%d; currDeliver: %d, result: %v, err: %s", i, j, result, err)) require.False(t, ctx.BlockGasMeter().IsPastLimit()) } } @@ -1260,10 +1297,10 @@ func TestGasConsumptionBadTx(t *testing.T) { } routerOpt := func(bapp *BaseApp) { - bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { count := msg.(msgCounter).Counter ctx.GasMeter().ConsumeGas(uint64(count), "counter-handler") - return sdk.Result{} + return &sdk.Result{}, nil }) } @@ -1313,10 +1350,10 @@ func TestQuery(t *testing.T) { } routerOpt := func(bapp *BaseApp) { - bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + bapp.Router().AddRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { store := ctx.KVStore(capKey1) store.Set(key, value) - return sdk.Result{} + return &sdk.Result{}, nil }) } @@ -1338,8 +1375,9 @@ func TestQuery(t *testing.T) { require.Equal(t, 0, len(res.Value)) // query is still empty after a CheckTx - resTx := app.Check(tx) - require.True(t, resTx.IsOK(), fmt.Sprintf("%v", resTx)) + _, resTx, err := app.Check(tx) + require.NoError(t, err) + require.NotNil(t, resTx) res = app.Query(query) require.Equal(t, 0, len(res.Value)) @@ -1347,8 +1385,9 @@ func TestQuery(t *testing.T) { header := abci.Header{Height: app.LastBlockHeight() + 1} app.BeginBlock(abci.RequestBeginBlock{Header: header}) - resTx = app.Deliver(tx) - require.True(t, resTx.IsOK(), fmt.Sprintf("%v", resTx)) + _, resTx, err = app.Deliver(tx) + require.NoError(t, err) + require.NotNil(t, resTx) res = app.Query(query) require.Equal(t, 0, len(res.Value)) diff --git a/baseapp/helpers.go b/baseapp/helpers.go index 5ea3cdcd9a77..aa9c10d328d7 100644 --- a/baseapp/helpers.go +++ b/baseapp/helpers.go @@ -10,15 +10,15 @@ import ( var isAlphaNumeric = regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString -func (app *BaseApp) Check(tx sdk.Tx) (result sdk.Result) { +func (app *BaseApp) Check(tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) { return app.runTx(runTxModeCheck, nil, tx) } -func (app *BaseApp) Simulate(txBytes []byte, tx sdk.Tx) (result sdk.Result) { +func (app *BaseApp) Simulate(txBytes []byte, tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) { return app.runTx(runTxModeSimulate, txBytes, tx) } -func (app *BaseApp) Deliver(tx sdk.Tx) (result sdk.Result) { +func (app *BaseApp) Deliver(tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) { return app.runTx(runTxModeDeliver, nil, tx) } diff --git a/baseapp/queryrouter_test.go b/baseapp/queryrouter_test.go index 7743028313cc..c7637f17000e 100644 --- a/baseapp/queryrouter_test.go +++ b/baseapp/queryrouter_test.go @@ -10,7 +10,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -var testQuerier = func(_ sdk.Context, _ []string, _ abci.RequestQuery) (res []byte, err sdk.Error) { +var testQuerier = func(_ sdk.Context, _ []string, _ abci.RequestQuery) ([]byte, error) { return nil, nil } diff --git a/baseapp/router_test.go b/baseapp/router_test.go index 86e09cf21b79..1a6d999bcce6 100644 --- a/baseapp/router_test.go +++ b/baseapp/router_test.go @@ -8,8 +8,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -var testHandler = func(_ sdk.Context, _ sdk.Msg) sdk.Result { - return sdk.Result{} +var testHandler = func(_ sdk.Context, _ sdk.Msg) (*sdk.Result, error) { + return &sdk.Result{}, nil } func TestRouter(t *testing.T) { diff --git a/client/alias.go b/client/alias.go deleted file mode 100644 index eed043c54401..000000000000 --- a/client/alias.go +++ /dev/null @@ -1,129 +0,0 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/client/context -// ALIASGEN: github.com/cosmos/cosmos-sdk/client/flags -// ALIASGEN: github.com/cosmos/cosmos-sdk/client/keys -// ALIASGEN: github.com/cosmos/cosmos-sdk/client/lcd -// ALIASGEN: github.com/cosmos/cosmos-sdk/client/rest -// ALIASGEN: github.com/cosmos/cosmos-sdk/client/rpc -// ALIASGEN: github.com/cosmos/cosmos-sdk/client/tx -// ALIASGEN: github.com/cosmos/cosmos-sdk/client/utils -// ALIASGEN: github.com/cosmos/cosmos-sdk/client/input -package client - -import ( - "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/input" - "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/client/lcd" - "github.com/cosmos/cosmos-sdk/client/rpc" -) - -const ( - DefaultGasAdjustment = flags.DefaultGasAdjustment - DefaultGasLimit = flags.DefaultGasLimit - DefaultKeyringBackend = flags.DefaultKeyringBackend - GasFlagAuto = flags.GasFlagAuto - BroadcastBlock = flags.BroadcastBlock - BroadcastSync = flags.BroadcastSync - BroadcastAsync = flags.BroadcastAsync - FlagHome = flags.FlagHome - FlagUseLedger = flags.FlagUseLedger - FlagChainID = flags.FlagChainID - FlagNode = flags.FlagNode - FlagHeight = flags.FlagHeight - FlagGasAdjustment = flags.FlagGasAdjustment - FlagTrustNode = flags.FlagTrustNode - FlagFrom = flags.FlagFrom - FlagName = flags.FlagName - FlagAccountNumber = flags.FlagAccountNumber - FlagSequence = flags.FlagSequence - FlagMemo = flags.FlagMemo - FlagFees = flags.FlagFees - FlagGasPrices = flags.FlagGasPrices - FlagBroadcastMode = flags.FlagBroadcastMode - FlagDryRun = flags.FlagDryRun - FlagGenerateOnly = flags.FlagGenerateOnly - FlagIndentResponse = flags.FlagIndentResponse - FlagKeyringBackend = flags.FlagKeyringBackend - FlagListenAddr = flags.FlagListenAddr - FlagMaxOpenConnections = flags.FlagMaxOpenConnections - FlagRPCReadTimeout = flags.FlagRPCReadTimeout - FlagRPCWriteTimeout = flags.FlagRPCWriteTimeout - FlagOutputDocument = flags.FlagOutputDocument - FlagSkipConfirmation = flags.FlagSkipConfirmation - KeyringBackendFile = flags.KeyringBackendFile - KeyringBackendOS = flags.KeyringBackendOS - KeyringBackendTest = flags.KeyringBackendTest - DefaultKeyPass = keys.DefaultKeyPass - FlagAddress = keys.FlagAddress - FlagPublicKey = keys.FlagPublicKey - FlagBechPrefix = keys.FlagBechPrefix - FlagDevice = keys.FlagDevice - OutputFormatText = keys.OutputFormatText - OutputFormatJSON = keys.OutputFormatJSON - MinPassLength = input.MinPassLength -) - -var ( - // functions aliases - NewCLIContextWithFrom = context.NewCLIContextWithFrom - NewCLIContextWithInput = context.NewCLIContextWithInput - NewCLIContextWithInputAndFrom = context.NewCLIContextWithInputAndFrom - NewCLIContext = context.NewCLIContext - GetFromFields = context.GetFromFields - ErrInvalidAccount = context.ErrInvalidAccount - ErrVerifyCommit = context.ErrVerifyCommit - GetCommands = flags.GetCommands - PostCommands = flags.PostCommands - RegisterRestServerFlags = flags.RegisterRestServerFlags - ParseGas = flags.ParseGas - NewCompletionCmd = flags.NewCompletionCmd - MarshalJSON = keys.MarshalJSON - UnmarshalJSON = keys.UnmarshalJSON - Commands = keys.Commands - NewAddNewKey = keys.NewAddNewKey - NewRecoverKey = keys.NewRecoverKey - NewUpdateKeyReq = keys.NewUpdateKeyReq - NewDeleteKeyReq = keys.NewDeleteKeyReq - NewKeyringFromDir = keys.NewKeyringFromDir - NewKeyringFromHomeFlag = keys.NewKeyringFromHomeFlag - NewInMemoryKeyBase = keys.NewInMemoryKeyBase - NewRestServer = lcd.NewRestServer - ServeCommand = lcd.ServeCommand - BlockCommand = rpc.BlockCommand - GetChainHeight = rpc.GetChainHeight - BlockRequestHandlerFn = rpc.BlockRequestHandlerFn - LatestBlockRequestHandlerFn = rpc.LatestBlockRequestHandlerFn - RegisterRPCRoutes = rpc.RegisterRPCRoutes - StatusCommand = rpc.StatusCommand - NodeInfoRequestHandlerFn = rpc.NodeInfoRequestHandlerFn - NodeSyncingRequestHandlerFn = rpc.NodeSyncingRequestHandlerFn - ValidatorCommand = rpc.ValidatorCommand - GetValidators = rpc.GetValidators - ValidatorSetRequestHandlerFn = rpc.ValidatorSetRequestHandlerFn - LatestValidatorSetRequestHandlerFn = rpc.LatestValidatorSetRequestHandlerFn - GetPassword = input.GetPassword - GetCheckPassword = input.GetCheckPassword - GetConfirmation = input.GetConfirmation - GetString = input.GetString - PrintPrefixed = input.PrintPrefixed - - // variable aliases - LineBreak = flags.LineBreak - GasFlagVar = flags.GasFlagVar -) - -type ( - CLIContext = context.CLIContext - GasSetting = flags.GasSetting - AddNewKey = keys.AddNewKey - RecoverKey = keys.RecoverKey - UpdateKeyReq = keys.UpdateKeyReq - DeleteKeyReq = keys.DeleteKeyReq - RestServer = lcd.RestServer - ValidatorOutput = rpc.ValidatorOutput - ResultValidatorsOutput = rpc.ResultValidatorsOutput -) diff --git a/client/context/broadcast.go b/client/context/broadcast.go index 1996c47d99cb..67251b6da89d 100644 --- a/client/context/broadcast.go +++ b/client/context/broadcast.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // BroadcastTx broadcasts a transactions either synchronously or asynchronously @@ -52,19 +53,19 @@ func CheckTendermintError(err error, txBytes []byte) *sdk.TxResponse { switch { case strings.Contains(errStr, strings.ToLower(mempool.ErrTxInCache.Error())): return &sdk.TxResponse{ - Code: uint32(sdk.CodeTxInMempoolCache), + Code: sdkerrors.ErrTxInMempoolCache.ABCICode(), TxHash: txHash, } case strings.Contains(errStr, "mempool is full"): return &sdk.TxResponse{ - Code: uint32(sdk.CodeMempoolIsFull), + Code: sdkerrors.ErrMempoolIsFull.ABCICode(), TxHash: txHash, } case strings.Contains(errStr, "tx too large"): return &sdk.TxResponse{ - Code: uint32(sdk.CodeTxTooLarge), + Code: sdkerrors.ErrTxTooLarge.ABCICode(), TxHash: txHash, } diff --git a/client/context/broadcast_test.go b/client/context/broadcast_test.go index 2afddb8f3524..530645b9d187 100644 --- a/client/context/broadcast_test.go +++ b/client/context/broadcast_test.go @@ -4,16 +4,15 @@ import ( "fmt" "testing" - "github.com/tendermint/tendermint/crypto/tmhash" - "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/mempool" "github.com/tendermint/tendermint/rpc/client/mock" ctypes "github.com/tendermint/tendermint/rpc/core/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) type MockClient struct { @@ -43,9 +42,9 @@ func CreateContextWithErrorAndMode(err error, mode string) CLIContext { // Test the correct code is returned when func TestBroadcastError(t *testing.T) { errors := map[error]uint32{ - mempool.ErrTxInCache: uint32(types.CodeTxInMempoolCache), - mempool.ErrTxTooLarge{}: uint32(types.CodeTxTooLarge), - mempool.ErrMempoolIsFull{}: uint32(types.CodeMempoolIsFull), + mempool.ErrTxInCache: sdkerrors.ErrTxInMempoolCache.ABCICode(), + mempool.ErrTxTooLarge{}: sdkerrors.ErrTxTooLarge.ABCICode(), + mempool.ErrMempoolIsFull{}: sdkerrors.ErrMempoolIsFull.ABCICode(), } modes := []string{ diff --git a/client/flags/flags.go b/client/flags/flags.go index 106061d3a78a..d0ac95e45b8d 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -94,6 +94,8 @@ func GetCommands(cmds ...*cobra.Command) []*cobra.Command { viper.BindPFlag(FlagNode, c.Flags().Lookup(FlagNode)) c.MarkFlagRequired(FlagChainID) + + c.SetErr(c.ErrOrStderr()) } return cmds } @@ -129,6 +131,8 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command { viper.BindPFlag(FlagKeyringBackend, c.Flags().Lookup(FlagKeyringBackend)) c.MarkFlagRequired(FlagChainID) + + c.SetErr(c.ErrOrStderr()) } return cmds } diff --git a/client/routes.go b/client/routes.go index ded91ca897b0..9eac8fa0d828 100644 --- a/client/routes.go +++ b/client/routes.go @@ -4,9 +4,10 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/rpc" ) // Register routes func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) { - RegisterRPCRoutes(cliCtx, r) + rpc.RegisterRPCRoutes(cliCtx, r) } diff --git a/docs/architecture/adr-015-ibc-packet-receiver.md b/docs/architecture/adr-015-ibc-packet-receiver.md index e772c3234c47..2ea26dcb5bae 100644 --- a/docs/architecture/adr-015-ibc-packet-receiver.md +++ b/docs/architecture/adr-015-ibc-packet-receiver.md @@ -204,7 +204,7 @@ type PacketDataI interface { GetCommitment() []byte // Commitment form that will be stored in the state. GetTimeoutHeight() uint64 - ValidateBasic() sdk.Error + ValidateBasic() error Type() string } ``` diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 3b19bf9603a9..37b46511a09a 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -25,19 +25,24 @@ Let us break it down: ## Implementation of a module `handler`s -Module `handler`s are typically implemented in a `./handler.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `handler`s to the [application's `router`](../core/baseapp.md#message-routing) via the `NewHandler()` method. Typically, the manager's `NewHandler()` method simply calls a `NewHandler()` method defined in `handler.go`, which looks like the following: +Module `handler`s are typically implemented in a `./handler.go` file inside the module's folder. The +[module manager](./module-manager.md) is used to add the module's `handler`s to the +[application's `router`](../core/baseapp.md#message-routing) via the `NewHandler()` method. Typically, +the manager's `NewHandler()` method simply calls a `NewHandler()` method defined in `handler.go`, +which looks like the following: ```go func NewHandler(keeper Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { switch msg := msg.(type) { case MsgType1: return handleMsgType1(ctx, keeper, msg) + case MsgType2: return handleMsgType2(ctx, keeper, msg) + default: - errMsg := fmt.Sprintf("Unrecognized nameservice Msg type: %v", msg.Type()) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg) } } } diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 02c334fc3843..be4750778661 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -29,14 +29,16 @@ Module `querier`s are typically implemented in a `./internal/keeper/querier.go` ```go func NewQuerier(keeper Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case QueryType1: return queryType1(ctx, path[1:], req, keeper) + case QueryType2: return queryType2(ctx, path[1:], req, keeper) + default: - return nil, sdk.ErrUnknownRequest("unknown nameservice query endpoint") + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) } } } diff --git a/server/mock/app.go b/server/mock/app.go index 9063bb7c5ea1..d1e1146d6a57 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -2,6 +2,7 @@ package mock import ( "encoding/json" + "errors" "fmt" "path/filepath" @@ -49,10 +50,10 @@ func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { // KVStoreHandler is a simple handler that takes kvstoreTx and writes // them to the db func KVStoreHandler(storeKey sdk.StoreKey) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { dTx, ok := msg.(kvstoreTx) if !ok { - panic("KVStoreHandler should only receive kvstoreTx") + return nil, errors.New("KVStoreHandler should only receive kvstoreTx") } // tx is already unmarshalled @@ -62,10 +63,9 @@ func KVStoreHandler(storeKey sdk.StoreKey) sdk.Handler { store := ctx.KVStore(storeKey) store.Set(key, value) - return sdk.Result{ - Code: 0, - Log: fmt.Sprintf("set %s=%s", key, value), - } + return &sdk.Result{ + Log: fmt.Sprintf("set %s=%s", key, value), + }, nil } } diff --git a/server/mock/tx.go b/server/mock/tx.go index 6774fb28145a..27441051ce8a 100644 --- a/server/mock/tx.go +++ b/server/mock/tx.go @@ -6,6 +6,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // An sdk.Tx which is its own sdk.Msg. @@ -47,7 +48,7 @@ func (tx kvstoreTx) GetSignBytes() []byte { } // Should the app be calling this? Or only handlers? -func (tx kvstoreTx) ValidateBasic() sdk.Error { +func (tx kvstoreTx) ValidateBasic() error { return nil } @@ -57,7 +58,7 @@ func (tx kvstoreTx) GetSigners() []sdk.AccAddress { // takes raw transaction bytes and decodes them into an sdk.Tx. An sdk.Tx has // all the signatures and can be used to authenticate. -func decodeTx(txBytes []byte) (sdk.Tx, sdk.Error) { +func decodeTx(txBytes []byte) (sdk.Tx, error) { var tx sdk.Tx split := bytes.Split(txBytes, []byte("=")) @@ -68,7 +69,7 @@ func decodeTx(txBytes []byte) (sdk.Tx, sdk.Error) { k, v := split[0], split[1] tx = kvstoreTx{k, v, txBytes} } else { - return nil, sdk.ErrTxDecode("too many =") + return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "too many '='") } return tx, nil diff --git a/simapp/app.go b/simapp/app.go index 657054bfba33..117a63b46d9b 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -164,7 +164,7 @@ func NewSimApp( } // init params keeper and subspaces - app.ParamsKeeper = params.NewKeeper(app.cdc, keys[params.StoreKey], tkeys[params.TStoreKey], params.DefaultCodespace) + app.ParamsKeeper = params.NewKeeper(app.cdc, keys[params.StoreKey], tkeys[params.TStoreKey]) app.subspaces[auth.ModuleName] = app.ParamsKeeper.Subspace(auth.DefaultParamspace) app.subspaces[bank.ModuleName] = app.ParamsKeeper.Subspace(bank.DefaultParamspace) app.subspaces[staking.ModuleName] = app.ParamsKeeper.Subspace(staking.DefaultParamspace) @@ -180,25 +180,24 @@ func NewSimApp( app.cdc, keys[auth.StoreKey], app.subspaces[auth.ModuleName], auth.ProtoBaseAccount, ) app.BankKeeper = bank.NewBaseKeeper( - app.AccountKeeper, app.subspaces[bank.ModuleName], bank.DefaultCodespace, - app.BlacklistedAccAddrs(), + app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(), ) app.SupplyKeeper = supply.NewKeeper( app.cdc, keys[supply.StoreKey], app.AccountKeeper, app.BankKeeper, maccPerms, ) stakingKeeper := staking.NewKeeper( app.cdc, keys[staking.StoreKey], app.SupplyKeeper, app.subspaces[staking.ModuleName], - staking.DefaultCodespace) + ) app.MintKeeper = mint.NewKeeper( app.cdc, keys[mint.StoreKey], app.subspaces[mint.ModuleName], &stakingKeeper, app.SupplyKeeper, auth.FeeCollectorName, ) app.DistrKeeper = distr.NewKeeper( app.cdc, keys[distr.StoreKey], app.subspaces[distr.ModuleName], &stakingKeeper, - app.SupplyKeeper, distr.DefaultCodespace, auth.FeeCollectorName, app.ModuleAccountAddrs(), + app.SupplyKeeper, auth.FeeCollectorName, app.ModuleAccountAddrs(), ) app.SlashingKeeper = slashing.NewKeeper( - app.cdc, keys[slashing.StoreKey], &stakingKeeper, app.subspaces[slashing.ModuleName], slashing.DefaultCodespace, + app.cdc, keys[slashing.StoreKey], &stakingKeeper, app.subspaces[slashing.ModuleName], ) app.CrisisKeeper = crisis.NewKeeper( app.subspaces[crisis.ModuleName], invCheckPeriod, app.SupplyKeeper, auth.FeeCollectorName, @@ -207,8 +206,7 @@ func NewSimApp( // create evidence keeper with router evidenceKeeper := evidence.NewKeeper( - app.cdc, keys[evidence.StoreKey], app.subspaces[evidence.ModuleName], evidence.DefaultCodespace, - &app.StakingKeeper, app.SlashingKeeper, + app.cdc, keys[evidence.StoreKey], app.subspaces[evidence.ModuleName], &app.StakingKeeper, app.SlashingKeeper, ) evidenceRouter := evidence.NewRouter(). AddRoute(ibcclient.RouterKey, ibcclient.HandlerClientMisbehaviour(app.IBCKeeper.ClientKeeper)) @@ -224,7 +222,7 @@ func NewSimApp( AddRoute(upgrade.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)) app.GovKeeper = gov.NewKeeper( app.cdc, keys[gov.StoreKey], app.subspaces[gov.ModuleName], app.SupplyKeeper, - &stakingKeeper, gov.DefaultCodespace, govRouter, + &stakingKeeper, govRouter, ) // register the staking hooks @@ -233,7 +231,7 @@ func NewSimApp( staking.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), ) - app.IBCKeeper = ibc.NewKeeper(app.cdc, keys[ibc.StoreKey], ibc.DefaultCodespace, app.BankKeeper, app.SupplyKeeper) + app.IBCKeeper = ibc.NewKeeper(app.cdc, keys[ibc.StoreKey], app.BankKeeper, app.SupplyKeeper) // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 0e6d22150255..d132394c9bc7 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -115,7 +115,7 @@ func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, exp sdk.Coins) func SignCheckDeliver( t *testing.T, cdc *codec.Codec, app *bam.BaseApp, header abci.Header, msgs []sdk.Msg, accNums, seq []uint64, expSimPass, expPass bool, priv ...crypto.PrivKey, -) sdk.Result { +) (sdk.GasInfo, *sdk.Result, error) { tx := helpers.GenTx( msgs, @@ -131,28 +131,32 @@ func SignCheckDeliver( require.Nil(t, err) // Must simulate now as CheckTx doesn't run Msgs anymore - res := app.Simulate(txBytes, tx) + _, res, err := app.Simulate(txBytes, tx) if expSimPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.NoError(t, err) + require.NotNil(t, res) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.Error(t, err) + require.Nil(t, res) } // Simulate a sending a transaction and committing a block app.BeginBlock(abci.RequestBeginBlock{Header: header}) - res = app.Deliver(tx) + gInfo, res, err := app.Deliver(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.NoError(t, err) + require.NotNil(t, res) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.Error(t, err) + require.Nil(t, res) } app.EndBlock(abci.RequestEndBlock{}) app.Commit() - return res + return gInfo, res, err } // GenSequenceOfTxs generates a set of signed transactions of messages, such diff --git a/store/errors/errors.go b/store/errors/errors.go deleted file mode 100644 index 98e1b8aa1330..000000000000 --- a/store/errors/errors.go +++ /dev/null @@ -1,26 +0,0 @@ -package errors - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -const ( - CodeOK = sdk.CodeOK - CodeInternal = sdk.CodeInternal - CodeTxDecode = sdk.CodeTxDecode - CodeUnknownRequest = sdk.CodeUnknownRequest - - CodespaceRoot = sdk.CodespaceRoot -) - -type Error = sdk.Error - -func ErrInternal(msg string) Error { - return sdk.ErrInternal(msg) -} -func ErrTxDecode(msg string) Error { - return sdk.ErrTxDecode(msg) -} -func ErrUnknownRequest(msg string) Error { - return sdk.ErrUnknownRequest(msg) -} diff --git a/store/iavl/store.go b/store/iavl/store.go index b7b94307bbe6..2faf786cd236 100644 --- a/store/iavl/store.go +++ b/store/iavl/store.go @@ -1,14 +1,13 @@ package iavl import ( - "fmt" "io" "sync" "github.com/cosmos/cosmos-sdk/store/cachekv" - serrors "github.com/cosmos/cosmos-sdk/store/errors" "github.com/cosmos/cosmos-sdk/store/tracekv" "github.com/cosmos/cosmos-sdk/store/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/pkg/errors" "github.com/tendermint/iavl" @@ -236,8 +235,7 @@ func getHeight(tree Tree, req abci.RequestQuery) int64 { // explicitly set the height you want to see func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { if len(req.Data) == 0 { - msg := "Query cannot be zero length" - return serrors.ErrTxDecode(msg).QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrTxDecode, "query cannot be zero length")) } tree := st.tree @@ -296,8 +294,7 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { res.Value = cdc.MustMarshalBinaryLengthPrefixed(KVs) default: - msg := fmt.Sprintf("Unexpected Query path: %v", req.Path) - return serrors.ErrUnknownRequest(msg).QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unexpected query path: %v", req.Path)) } return res diff --git a/store/iavl/store_test.go b/store/iavl/store_test.go index b70be1dee138..d7c38aa0d548 100644 --- a/store/iavl/store_test.go +++ b/store/iavl/store_test.go @@ -11,7 +11,6 @@ import ( cmn "github.com/tendermint/tendermint/libs/common" dbm "github.com/tendermint/tm-db" - "github.com/cosmos/cosmos-sdk/store/errors" "github.com/cosmos/cosmos-sdk/store/types" ) @@ -497,7 +496,7 @@ func TestIAVLStoreQuery(t *testing.T) { // query subspace before anything set qres := iavlStore.Query(querySub) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Equal(t, valExpSubEmpty, qres.Value) // set data @@ -506,24 +505,24 @@ func TestIAVLStoreQuery(t *testing.T) { // set data without commit, doesn't show up qres = iavlStore.Query(query) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Nil(t, qres.Value) // commit it, but still don't see on old version cid = iavlStore.Commit() qres = iavlStore.Query(query) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Nil(t, qres.Value) // but yes on the new version query.Height = cid.Version qres = iavlStore.Query(query) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Equal(t, v1, qres.Value) // and for the subspace qres = iavlStore.Query(querySub) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Equal(t, valExpSub1, qres.Value) // modify @@ -532,28 +531,28 @@ func TestIAVLStoreQuery(t *testing.T) { // query will return old values, as height is fixed qres = iavlStore.Query(query) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Equal(t, v1, qres.Value) // update to latest in the query and we are happy query.Height = cid.Version qres = iavlStore.Query(query) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Equal(t, v3, qres.Value) query2 := abci.RequestQuery{Path: "/key", Data: k2, Height: cid.Version} qres = iavlStore.Query(query2) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Equal(t, v2, qres.Value) // and for the subspace qres = iavlStore.Query(querySub) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Equal(t, valExpSub2, qres.Value) // default (height 0) will show latest -1 query0 := abci.RequestQuery{Path: "/key", Data: k1} qres = iavlStore.Query(query0) - require.Equal(t, uint32(errors.CodeOK), qres.Code) + require.Equal(t, uint32(0), qres.Code) require.Equal(t, v1, qres.Value) } diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index 4f3d212e4914..0b22d5442cb0 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -12,11 +12,11 @@ import ( "github.com/cosmos/cosmos-sdk/store/cachemulti" "github.com/cosmos/cosmos-sdk/store/dbadapter" - "github.com/cosmos/cosmos-sdk/store/errors" "github.com/cosmos/cosmos-sdk/store/iavl" "github.com/cosmos/cosmos-sdk/store/tracekv" "github.com/cosmos/cosmos-sdk/store/transient" "github.com/cosmos/cosmos-sdk/store/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) const ( @@ -408,19 +408,17 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery { path := req.Path storeName, subpath, err := parsePath(path) if err != nil { - return err.QueryResult() + return sdkerrors.QueryResult(err) } store := rs.getStoreByName(storeName) if store == nil { - msg := fmt.Sprintf("no such store: %s", storeName) - return errors.ErrUnknownRequest(msg).QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "no such store: %s", storeName)) } queryable, ok := store.(types.Queryable) if !ok { - msg := fmt.Sprintf("store %s (type %T) doesn't support queries", storeName, store) - return errors.ErrUnknownRequest(msg).QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "store %s (type %T) doesn't support queries", storeName, store)) } // trim the path and make the query @@ -432,12 +430,12 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery { } if res.Proof == nil || len(res.Proof.Ops) == 0 { - return errors.ErrInternal("proof is unexpectedly empty; ensure height has not been pruned").QueryResult() + return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "proof is unexpectedly empty; ensure height has not been pruned")) } commitInfo, errMsg := getCommitInfo(rs.db, res.Height) if errMsg != nil { - return errors.ErrInternal(errMsg.Error()).QueryResult() + return sdkerrors.QueryResult(err) } // Restore origin path and append proof op. @@ -454,10 +452,9 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery { // parsePath expects a format like /[/] // Must start with /, subpath may be empty // Returns error if it doesn't start with / -func parsePath(path string) (storeName string, subpath string, err errors.Error) { +func parsePath(path string) (storeName string, subpath string, err error) { if !strings.HasPrefix(path, "/") { - err = errors.ErrUnknownRequest(fmt.Sprintf("invalid path: %s", path)) - return + return storeName, subpath, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid path: %s", path) } paths := strings.SplitN(path[1:], "/", 2) @@ -467,7 +464,7 @@ func parsePath(path string) (storeName string, subpath string, err errors.Error) subpath = "/" + paths[1] } - return + return storeName, subpath, nil } //---------------------------------------- diff --git a/store/rootmulti/store_test.go b/store/rootmulti/store_test.go index 47b2ece360a0..16181c4080f2 100644 --- a/store/rootmulti/store_test.go +++ b/store/rootmulti/store_test.go @@ -8,9 +8,9 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" dbm "github.com/tendermint/tm-db" - "github.com/cosmos/cosmos-sdk/store/errors" "github.com/cosmos/cosmos-sdk/store/iavl" "github.com/cosmos/cosmos-sdk/store/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func TestStoreType(t *testing.T) { @@ -324,37 +324,37 @@ func TestMultiStoreQuery(t *testing.T) { // Test bad path. query := abci.RequestQuery{Path: "/key", Data: k, Height: ver} qres := multi.Query(query) - require.EqualValues(t, errors.CodeUnknownRequest, qres.Code) - require.EqualValues(t, errors.CodespaceRoot, qres.Codespace) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), qres.Code) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.Codespace(), qres.Codespace) query.Path = "h897fy32890rf63296r92" qres = multi.Query(query) - require.EqualValues(t, errors.CodeUnknownRequest, qres.Code) - require.EqualValues(t, errors.CodespaceRoot, qres.Codespace) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), qres.Code) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.Codespace(), qres.Codespace) // Test invalid store name. query.Path = "/garbage/key" qres = multi.Query(query) - require.EqualValues(t, errors.CodeUnknownRequest, qres.Code) - require.EqualValues(t, errors.CodespaceRoot, qres.Codespace) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), qres.Code) + require.EqualValues(t, sdkerrors.ErrUnknownRequest.Codespace(), qres.Codespace) // Test valid query with data. query.Path = "/store1/key" qres = multi.Query(query) - require.EqualValues(t, errors.CodeOK, qres.Code) + require.EqualValues(t, 0, qres.Code) require.Equal(t, v, qres.Value) // Test valid but empty query. query.Path = "/store2/key" query.Prove = true qres = multi.Query(query) - require.EqualValues(t, errors.CodeOK, qres.Code) + require.EqualValues(t, 0, qres.Code) require.Nil(t, qres.Value) // Test store2 data. query.Data = k2 qres = multi.Query(query) - require.EqualValues(t, errors.CodeOK, qres.Code) + require.EqualValues(t, 0, qres.Code) require.Equal(t, v2, qres.Value) } diff --git a/store/types/iterator.go b/store/types/iterator.go new file mode 100644 index 000000000000..cfce4124e397 --- /dev/null +++ b/store/types/iterator.go @@ -0,0 +1,61 @@ +package types + +import ( + "fmt" +) + +// KVStorePrefixIteratorPaginated returns iterator over items in the selected page. +// Items iterated and skipped in ascending order. +func KVStorePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator { + pi := &PaginatedIterator{ + Iterator: KVStorePrefixIterator(kvs, prefix), + page: page, + limit: limit, + } + pi.skip() + return pi +} + +// KVStoreReversePrefixIteratorPaginated returns iterator over items in the selected page. +// Items iterated and skipped in descending order. +func KVStoreReversePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator { + pi := &PaginatedIterator{ + Iterator: KVStoreReversePrefixIterator(kvs, prefix), + page: page, + limit: limit, + } + pi.skip() + return pi +} + +// PaginatedIterator is a wrapper around Iterator that iterates over values starting for given page and limit. +type PaginatedIterator struct { + Iterator + + page, limit uint // provided during initialization + iterated uint // incremented in a call to Next + +} + +func (pi *PaginatedIterator) skip() { + for i := (pi.page - 1) * pi.limit; i > 0 && pi.Iterator.Valid(); i-- { + pi.Iterator.Next() + } +} + +// Next will panic after limit is reached. +func (pi *PaginatedIterator) Next() { + if !pi.Valid() { + panic(fmt.Sprintf("PaginatedIterator reached limit %d", pi.limit)) + } + pi.Iterator.Next() + pi.iterated++ +} + +// Valid if below limit and underlying iterator is valid. +func (pi *PaginatedIterator) Valid() bool { + if pi.iterated >= pi.limit { + return false + } + return pi.Iterator.Valid() +} diff --git a/store/types/iterator_test.go b/store/types/iterator_test.go new file mode 100644 index 000000000000..e081de80a3d5 --- /dev/null +++ b/store/types/iterator_test.go @@ -0,0 +1,119 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/types" +) + +func newMemTestKVStore(t *testing.T) types.KVStore { + db := dbm.NewMemDB() + store, err := iavl.LoadStore(db, types.CommitID{}, types.PruneNothing, false) + require.NoError(t, err) + return store +} + +func TestPaginatedIterator(t *testing.T) { + kvs := newMemTestKVStore(t) + total := 10 + lth := total - 1 + asc := make([][]byte, total) + desc := make([][]byte, total) + // store returns values in lexicographic order (or reverse lex order) + for i := 0; i < total; i++ { + key := []byte{byte(i)} + kvs.Set(key, key) + asc[i] = key + desc[lth-i] = key + } + type testCase struct { + desc string + page, limit uint + result [][]byte + reverse bool + } + for _, tc := range []testCase{ + { + desc: "FirstChunk", + page: 1, + limit: 4, + result: asc[:4], + }, + { + desc: "SecondChunk", + page: 2, + limit: 4, + result: asc[4:8], + }, + { + desc: "ThirdChunkHalf", + page: 3, + limit: 4, + result: asc[8:], + }, + { + desc: "OverLimit", + page: 10, + limit: 10, + result: [][]byte{}, + }, + { + desc: "ZeroLimit", + page: 1, + result: [][]byte{}, + }, + { + desc: "ReverseFirstChunk", + page: 1, + limit: 6, + result: desc[:6], + reverse: true, + }, + { + desc: "ReverseSecondChunk", + page: 2, + limit: 6, + result: desc[6:], + reverse: true, + }, + } { + tc := tc + t.Run(tc.desc, func(t *testing.T) { + var iter types.Iterator + if tc.reverse { + iter = types.KVStoreReversePrefixIteratorPaginated(kvs, nil, tc.page, tc.limit) + } else { + iter = types.KVStorePrefixIteratorPaginated(kvs, nil, tc.page, tc.limit) + } + defer iter.Close() + + result := [][]byte{} + for ; iter.Valid(); iter.Next() { + result = append(result, iter.Key()) + } + + require.Equal(t, tc.result, result) + require.False(t, iter.Valid()) + }) + } +} + +func TestPaginatedIteratorPanicIfInvalid(t *testing.T) { + kvs := newMemTestKVStore(t) + + iter := types.KVStorePrefixIteratorPaginated(kvs, nil, 1, 1) + defer iter.Close() + require.False(t, iter.Valid()) + require.Panics(t, func() { iter.Next() }) // "iterator is empty" + + kvs.Set([]byte{1}, []byte{}) + + iter = types.KVStorePrefixIteratorPaginated(kvs, nil, 1, 0) + defer iter.Close() + require.False(t, iter.Valid()) + require.Panics(t, func() { iter.Next() }) // "not empty but limit is zero" +} diff --git a/types/decimal.go b/types/decimal.go index b066c3e43374..63aecf6cab18 100644 --- a/types/decimal.go +++ b/types/decimal.go @@ -2,6 +2,7 @@ package types import ( "encoding/json" + "errors" "fmt" "math/big" "strconv" @@ -33,6 +34,13 @@ var ( tenInt = big.NewInt(10) ) +// Decimal errors +var ( + ErrEmptyDecimalStr = errors.New("decimal string cannot be empty") + ErrInvalidDecimalLength = errors.New("invalid decimal length") + ErrInvalidDecimalStr = errors.New("invalid decimal string") +) + // Set precision multipliers func init() { precisionMultipliers = make([]*big.Int, Precision+1) @@ -123,9 +131,9 @@ func NewDecFromIntWithPrec(i Int, prec int64) Dec { // are provided in the string than the constant Precision. // // CONTRACT - This function does not mutate the input str. -func NewDecFromStr(str string) (d Dec, err Error) { +func NewDecFromStr(str string) (Dec, error) { if len(str) == 0 { - return d, ErrUnknownRequest("decimal string is empty") + return Dec{}, ErrEmptyDecimalStr } // first extract any negative symbol @@ -136,7 +144,7 @@ func NewDecFromStr(str string) (d Dec, err Error) { } if len(str) == 0 { - return d, ErrUnknownRequest("decimal string is empty") + return Dec{}, ErrEmptyDecimalStr } strs := strings.Split(str, ".") @@ -146,17 +154,16 @@ func NewDecFromStr(str string) (d Dec, err Error) { if len(strs) == 2 { // has a decimal place lenDecs = len(strs[1]) if lenDecs == 0 || len(combinedStr) == 0 { - return d, ErrUnknownRequest("bad decimal length") + return Dec{}, ErrInvalidDecimalLength } combinedStr += strs[1] } else if len(strs) > 2 { - return d, ErrUnknownRequest("too many periods to be a decimal string") + return Dec{}, ErrInvalidDecimalStr } if lenDecs > Precision { - return d, ErrUnknownRequest( - fmt.Sprintf("too much precision, maximum %v, len decimal %v", Precision, lenDecs)) + return Dec{}, fmt.Errorf("invalid precision; max: %d, got: %d", Precision, lenDecs) } // add some extra zero's to correct to the Precision factor @@ -166,11 +173,12 @@ func NewDecFromStr(str string) (d Dec, err Error) { combined, ok := new(big.Int).SetString(combinedStr, 10) // base 10 if !ok { - return d, ErrUnknownRequest(fmt.Sprintf("bad string to integer conversion, combinedStr: %v", combinedStr)) + return Dec{}, fmt.Errorf("failed to set decimal string: %s", combinedStr) } if neg { combined = new(big.Int).Neg(combined) } + return Dec{combined}, nil } diff --git a/types/errors.go b/types/errors.go deleted file mode 100644 index c59571bfe540..000000000000 --- a/types/errors.go +++ /dev/null @@ -1,361 +0,0 @@ -package types - -import ( - "bytes" - "encoding/json" - "fmt" - "strings" - - "github.com/pkg/errors" - - abci "github.com/tendermint/tendermint/abci/types" - cmn "github.com/tendermint/tendermint/libs/common" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// CodeType - ABCI code identifier within codespace -type CodeType uint32 - -// CodespaceType - codespace identifier -type CodespaceType string - -// IsOK - is everything okay? -func (code CodeType) IsOK() bool { - return code == CodeOK -} - -// SDK error codes -const ( - // Base error codes - CodeOK CodeType = 0 - CodeInternal CodeType = 1 - CodeTxDecode CodeType = 2 - CodeInvalidSequence CodeType = 3 - CodeUnauthorized CodeType = 4 - CodeInsufficientFunds CodeType = 5 - CodeUnknownRequest CodeType = 6 - CodeInvalidAddress CodeType = 7 - CodeInvalidPubKey CodeType = 8 - CodeUnknownAddress CodeType = 9 - CodeInsufficientCoins CodeType = 10 - CodeInvalidCoins CodeType = 11 - CodeOutOfGas CodeType = 12 - CodeMemoTooLarge CodeType = 13 - CodeInsufficientFee CodeType = 14 - CodeTooManySignatures CodeType = 15 - CodeGasOverflow CodeType = 16 - CodeNoSignatures CodeType = 17 - CodeTxInMempoolCache CodeType = 18 - CodeMempoolIsFull CodeType = 19 - CodeTxTooLarge CodeType = 20 - - // CodespaceRoot is a codespace for error codes in this file only. - // Notice that 0 is an "unset" codespace, which can be overridden with - // Error.WithDefaultCodespace(). - CodespaceUndefined CodespaceType = "" - CodespaceRoot CodespaceType = "sdk" -) - -func unknownCodeMsg(code CodeType) string { - return fmt.Sprintf("unknown code %d", code) -} - -// NOTE: Don't stringer this, we'll put better messages in later. -func CodeToDefaultMsg(code CodeType) string { - switch code { - case CodeInternal: - return "internal error" - case CodeTxDecode: - return "tx parse error" - case CodeInvalidSequence: - return "invalid sequence" - case CodeUnauthorized: - return "unauthorized" - case CodeInsufficientFunds: - return "insufficient funds" - case CodeUnknownRequest: - return "unknown request" - case CodeInvalidAddress: - return "invalid address" - case CodeInvalidPubKey: - return "invalid pubkey" - case CodeUnknownAddress: - return "unknown address" - case CodeInsufficientCoins: - return "insufficient coins" - case CodeInvalidCoins: - return "invalid coins" - case CodeOutOfGas: - return "out of gas" - case CodeMemoTooLarge: - return "memo too large" - case CodeInsufficientFee: - return "insufficient fee" - case CodeTooManySignatures: - return "maximum numer of signatures exceeded" - case CodeNoSignatures: - return "no signatures supplied" - default: - return unknownCodeMsg(code) - } -} - -//-------------------------------------------------------------------------------- -// All errors are created via constructors so as to enable us to hijack them -// and inject stack traces if we really want to. - -// nolint -func ErrInternal(msg string) Error { - return newErrorWithRootCodespace(CodeInternal, msg) -} -func ErrTxDecode(msg string) Error { - return newErrorWithRootCodespace(CodeTxDecode, msg) -} -func ErrInvalidSequence(msg string) Error { - return newErrorWithRootCodespace(CodeInvalidSequence, msg) -} -func ErrUnauthorized(msg string) Error { - return newErrorWithRootCodespace(CodeUnauthorized, msg) -} -func ErrInsufficientFunds(msg string) Error { - return newErrorWithRootCodespace(CodeInsufficientFunds, msg) -} -func ErrUnknownRequest(msg string) Error { - return newErrorWithRootCodespace(CodeUnknownRequest, msg) -} -func ErrInvalidAddress(msg string) Error { - return newErrorWithRootCodespace(CodeInvalidAddress, msg) -} -func ErrUnknownAddress(msg string) Error { - return newErrorWithRootCodespace(CodeUnknownAddress, msg) -} -func ErrInvalidPubKey(msg string) Error { - return newErrorWithRootCodespace(CodeInvalidPubKey, msg) -} -func ErrInsufficientCoins(msg string) Error { - return newErrorWithRootCodespace(CodeInsufficientCoins, msg) -} -func ErrInvalidCoins(msg string) Error { - return newErrorWithRootCodespace(CodeInvalidCoins, msg) -} -func ErrOutOfGas(msg string) Error { - return newErrorWithRootCodespace(CodeOutOfGas, msg) -} -func ErrMemoTooLarge(msg string) Error { - return newErrorWithRootCodespace(CodeMemoTooLarge, msg) -} -func ErrInsufficientFee(msg string) Error { - return newErrorWithRootCodespace(CodeInsufficientFee, msg) -} -func ErrTooManySignatures(msg string) Error { - return newErrorWithRootCodespace(CodeTooManySignatures, msg) -} -func ErrNoSignatures(msg string) Error { - return newErrorWithRootCodespace(CodeNoSignatures, msg) -} -func ErrGasOverflow(msg string) Error { - return newErrorWithRootCodespace(CodeGasOverflow, msg) -} - -//---------------------------------------- -// Error & sdkError - -type cmnError = cmn.Error - -// sdk Error type -type Error interface { - // Implements cmn.Error - // Error() string - // Stacktrace() cmn.Error - // Trace(offset int, format string, args ...interface{}) cmn.Error - // Data() interface{} - cmnError - - // convenience - TraceSDK(format string, args ...interface{}) Error - - // set codespace - WithDefaultCodespace(CodespaceType) Error - - Code() CodeType - Codespace() CodespaceType - ABCILog() string - Result() Result - QueryResult() abci.ResponseQuery -} - -// NewError - create an error. -func NewError(codespace CodespaceType, code CodeType, format string, args ...interface{}) Error { - return newError(codespace, code, format, args...) -} - -func newErrorWithRootCodespace(code CodeType, format string, args ...interface{}) *sdkError { - return newError(CodespaceRoot, code, format, args...) -} - -func newError(codespace CodespaceType, code CodeType, format string, args ...interface{}) *sdkError { - if format == "" { - format = CodeToDefaultMsg(code) - } - return &sdkError{ - codespace: codespace, - code: code, - cmnError: cmn.NewError(format, args...), - } -} - -type sdkError struct { - codespace CodespaceType - code CodeType - cmnError -} - -// Implements Error. -func (err *sdkError) WithDefaultCodespace(cs CodespaceType) Error { - codespace := err.codespace - if codespace == CodespaceUndefined { - codespace = cs - } - return &sdkError{ - codespace: cs, - code: err.code, - cmnError: err.cmnError, - } -} - -// Implements ABCIError. -// nolint: errcheck -func (err *sdkError) TraceSDK(format string, args ...interface{}) Error { - err.Trace(1, format, args...) - return err -} - -// Implements ABCIError. -func (err *sdkError) Error() string { - return fmt.Sprintf(`ERROR: -Codespace: %s -Code: %d -Message: %#v -`, err.codespace, err.code, err.cmnError.Error()) -} - -// Implements Error. -func (err *sdkError) Codespace() CodespaceType { - return err.codespace -} - -// Implements Error. -func (err *sdkError) Code() CodeType { - return err.code -} - -// Implements ABCIError. -func (err *sdkError) ABCILog() string { - errMsg := err.cmnError.Error() - return encodeErrorLog(err.codespace, err.code, errMsg) -} - -func encodeErrorLog(codespace CodespaceType, code CodeType, msg string) string { - jsonErr := humanReadableError{ - Codespace: codespace, - Code: code, - Message: msg, - } - - var buff bytes.Buffer - enc := json.NewEncoder(&buff) - enc.SetEscapeHTML(false) - - if err := enc.Encode(jsonErr); err != nil { - panic(errors.Wrap(err, "failed to encode ABCI error log")) - } - - return strings.TrimSpace(buff.String()) -} - -func (err *sdkError) Result() Result { - return Result{ - Code: err.Code(), - Codespace: err.Codespace(), - Log: err.ABCILog(), - } -} - -// QueryResult allows us to return sdk.Error.QueryResult() in query responses -func (err *sdkError) QueryResult() abci.ResponseQuery { - return abci.ResponseQuery{ - Code: uint32(err.Code()), - Codespace: string(err.Codespace()), - Log: err.ABCILog(), - } -} - -// ResultFromError will return err.Result() if it implements sdk.Error -// Otherwise, it will use the reflecton from types/error to determine -// the code, codespace, and log. -// -// This is intended to provide a bridge to allow both error types -// to live side-by-side. -func ResultFromError(err error) Result { - if sdk, ok := err.(Error); ok { - return sdk.Result() - } - space, code, log := sdkerrors.ABCIInfo(err, false) - return Result{ - Codespace: CodespaceType(space), - Code: CodeType(code), - Log: encodeErrorLog(CodespaceType(space), CodeType(code), log), - } -} - -// ConvertError accepts a standard error and attempts to convert it to an sdk.Error. -// If the given error is already an sdk.Error, it'll simply be returned. Otherwise, -// it'll convert it to a types.Error. This is meant to provide a migration path -// away from sdk.Error in favor of types.Error. -func ConvertError(err error) Error { - if err == nil { - return nil - } - if sdkError, ok := err.(Error); ok { - return sdkError - } - - space, code, log := sdkerrors.ABCIInfo(err, false) - return NewError(CodespaceType(space), CodeType(code), log) -} - -//---------------------------------------- -// REST error utilities - -// appends a message to the head of the given error -func AppendMsgToErr(msg string, err string) string { - msgIdx := strings.Index(err, "message\":\"") - if msgIdx != -1 { - errMsg := err[msgIdx+len("message\":\"") : len(err)-2] - errMsg = fmt.Sprintf("%s; %s", msg, errMsg) - return fmt.Sprintf("%s%s%s", - err[:msgIdx+len("message\":\"")], - errMsg, - err[len(err)-2:], - ) - } - return fmt.Sprintf("%s; %s", msg, err) -} - -// returns the index of the message in the ABCI Log -// nolint:deadcode,unused -func mustGetMsgIndex(abciLog string) int { - msgIdx := strings.Index(abciLog, "message\":\"") - if msgIdx == -1 { - panic(fmt.Sprintf("invalid error format: %s", abciLog)) - } - return msgIdx + len("message\":\"") -} - -// parses the error into an object-like struct for exporting -type humanReadableError struct { - Codespace CodespaceType `json:"codespace"` - Code CodeType `json:"code"` - Message string `json:"message"` -} diff --git a/types/errors/abci.go b/types/errors/abci.go index 1f70758cdd1b..cc5633543192 100644 --- a/types/errors/abci.go +++ b/types/errors/abci.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "reflect" + + abci "github.com/tendermint/tendermint/abci/types" ) const ( @@ -40,6 +42,43 @@ func ABCIInfo(err error, debug bool) (codespace string, code uint32, log string) return abciCodespace(err), abciCode(err), encode(err) } +// ResponseCheckTx returns an ABCI ResponseCheckTx object with fields filled in +// from the given error and gas values. +func ResponseCheckTx(err error, gw, gu uint64) abci.ResponseCheckTx { + space, code, log := ABCIInfo(err, false) + return abci.ResponseCheckTx{ + Codespace: space, + Code: code, + Log: log, + GasWanted: int64(gw), + GasUsed: int64(gu), + } +} + +// ResponseDeliverTx returns an ABCI ResponseDeliverTx object with fields filled in +// from the given error and gas values. +func ResponseDeliverTx(err error, gw, gu uint64) abci.ResponseDeliverTx { + space, code, log := ABCIInfo(err, false) + return abci.ResponseDeliverTx{ + Codespace: space, + Code: code, + Log: log, + GasWanted: int64(gw), + GasUsed: int64(gu), + } +} + +// QueryResult returns a ResponseQuery from an error. It will try to parse ABCI +// info from the error. +func QueryResult(err error) abci.ResponseQuery { + space, code, log := ABCIInfo(err, false) + return abci.ResponseQuery{ + Codespace: space, + Code: code, + Log: log, + } +} + // The debugErrEncoder encodes the error with a stacktrace. func debugErrEncoder(err error) string { return fmt.Sprintf("%+v", err) diff --git a/types/errors/abci_test.go b/types/errors/abci_test.go index 20b4f74b6f8b..c098811ea474 100644 --- a/types/errors/abci_test.go +++ b/types/errors/abci_test.go @@ -15,17 +15,17 @@ func TestABCInfo(t *testing.T) { wantSpace string wantLog string }{ - "plain weave error": { + "plain SDK error": { err: ErrUnauthorized, debug: false, wantLog: "unauthorized", wantCode: ErrUnauthorized.code, wantSpace: RootCodespace, }, - "wrapped weave error": { + "wrapped SDK error": { err: Wrap(Wrap(ErrUnauthorized, "foo"), "bar"), debug: false, - wantLog: "bar: foo: unauthorized", + wantLog: "unauthorized: foo: bar", wantCode: ErrUnauthorized.code, wantSpace: RootCodespace, }, @@ -36,7 +36,7 @@ func TestABCInfo(t *testing.T) { wantCode: 0, wantSpace: "", }, - "nil weave error is not an error": { + "nil SDK error is not an error": { err: (*Error)(nil), debug: false, wantLog: "", @@ -112,23 +112,23 @@ func TestABCIInfoStacktrace(t *testing.T) { wantStacktrace bool wantErrMsg string }{ - "wrapped weave error in debug mode provides stacktrace": { + "wrapped SDK error in debug mode provides stacktrace": { err: Wrap(ErrUnauthorized, "wrapped"), debug: true, wantStacktrace: true, - wantErrMsg: "wrapped: unauthorized", + wantErrMsg: "unauthorized: wrapped", }, - "wrapped weave error in non-debug mode does not have stacktrace": { + "wrapped SDK error in non-debug mode does not have stacktrace": { err: Wrap(ErrUnauthorized, "wrapped"), debug: false, wantStacktrace: false, - wantErrMsg: "wrapped: unauthorized", + wantErrMsg: "unauthorized: wrapped", }, "wrapped stdlib error in debug mode provides stacktrace": { err: Wrap(fmt.Errorf("stdlib"), "wrapped"), debug: true, wantStacktrace: true, - wantErrMsg: "wrapped: stdlib", + wantErrMsg: "stdlib: wrapped", }, "wrapped stdlib error in non-debug mode does not have stacktrace": { err: Wrap(fmt.Errorf("stdlib"), "wrapped"), @@ -163,7 +163,7 @@ func TestABCIInfoHidesStacktrace(t *testing.T) { err := Wrap(ErrUnauthorized, "wrapped") _, _, log := ABCIInfo(err, false) - if log != "wrapped: unauthorized" { + if log != "unauthorized: wrapped" { t.Fatalf("unexpected message in non debug mode: %s", log) } } @@ -173,7 +173,7 @@ func TestRedact(t *testing.T) { t.Error("reduct must not pass through panic error") } if err := Redact(ErrUnauthorized); !ErrUnauthorized.Is(err) { - t.Error("reduct should pass through weave error") + t.Error("reduct should pass through SDK error") } var cerr customErr @@ -203,12 +203,12 @@ func TestABCIInfoSerializeErr(t *testing.T) { "single error": { src: myErrDecode, debug: false, - exp: "test: tx parse error", + exp: "tx parse error: test", }, "second error": { src: myErrAddr, debug: false, - exp: "tester: invalid address", + exp: "invalid address: tester", }, "single error with debug": { src: myErrDecode, diff --git a/types/errors/errors.go b/types/errors/errors.go index 22ed2f4c8c89..49624f784775 100644 --- a/types/errors/errors.go +++ b/types/errors/errors.go @@ -44,32 +44,43 @@ var ( // ErrUnknownAddress to doc ErrUnknownAddress = Register(RootCodespace, 9, "unknown address") - // ErrInsufficientCoins to doc (what is the difference between ErrInsufficientFunds???) - ErrInsufficientCoins = Register(RootCodespace, 10, "insufficient coins") - // ErrInvalidCoins to doc - ErrInvalidCoins = Register(RootCodespace, 11, "invalid coins") + ErrInvalidCoins = Register(RootCodespace, 10, "invalid coins") // ErrOutOfGas to doc - ErrOutOfGas = Register(RootCodespace, 12, "out of gas") + ErrOutOfGas = Register(RootCodespace, 11, "out of gas") // ErrMemoTooLarge to doc - ErrMemoTooLarge = Register(RootCodespace, 13, "memo too large") + ErrMemoTooLarge = Register(RootCodespace, 12, "memo too large") // ErrInsufficientFee to doc - ErrInsufficientFee = Register(RootCodespace, 14, "insufficient fee") + ErrInsufficientFee = Register(RootCodespace, 13, "insufficient fee") // ErrTooManySignatures to doc - ErrTooManySignatures = Register(RootCodespace, 15, "maximum numer of signatures exceeded") + ErrTooManySignatures = Register(RootCodespace, 14, "maximum number of signatures exceeded") // ErrNoSignatures to doc - ErrNoSignatures = Register(RootCodespace, 16, "no signatures supplied") + ErrNoSignatures = Register(RootCodespace, 15, "no signatures supplied") // ErrJSONMarshal defines an ABCI typed JSON marshalling error - ErrJSONMarshal = Register(RootCodespace, 17, "failed to marshal JSON bytes") + ErrJSONMarshal = Register(RootCodespace, 16, "failed to marshal JSON bytes") // ErrJSONUnmarshal defines an ABCI typed JSON unmarshalling error - ErrJSONUnmarshal = Register(RootCodespace, 18, "failed to unmarshal JSON bytes") + ErrJSONUnmarshal = Register(RootCodespace, 17, "failed to unmarshal JSON bytes") + + // ErrInvalidRequest defines an ABCI typed error where the request contains + // invalid data. + ErrInvalidRequest = Register(RootCodespace, 18, "invalid request") + + // ErrTxInMempoolCache defines an ABCI typed error where a tx already exists + // in the mempool. + ErrTxInMempoolCache = Register(RootCodespace, 19, "tx already in mempool") + + // ErrMempoolIsFull defines an ABCI typed error where the mempool is full. + ErrMempoolIsFull = Register(RootCodespace, 20, "mempool is full") + + // ErrTxTooLarge defines an ABCI typed error where tx is too large. + ErrTxTooLarge = Register(RootCodespace, 21, "tx too large") // ErrPanic is only set when we recover from a panic, so we know to // redact potentially sensitive system info @@ -89,12 +100,10 @@ func Register(codespace string, code uint32, description string) *Error { if e := getUsed(codespace, code); e != nil { panic(fmt.Sprintf("error with code %d is already registered: %q", code, e.desc)) } - err := &Error{ - code: code, - codespace: codespace, - desc: description, - } + + err := New(codespace, code, description) setUsed(err) + return err } @@ -247,7 +256,7 @@ type wrappedError struct { } func (e *wrappedError) Error() string { - return fmt.Sprintf("%s: %s", e.msg, e.parent.Error()) + return fmt.Sprintf("%s: %s", e.parent.Error(), e.msg) } func (e *wrappedError) Cause() error { diff --git a/types/errors/stacktrace_test.go b/types/errors/stacktrace_test.go index bef4bccb704e..042edc0b6919 100644 --- a/types/errors/stacktrace_test.go +++ b/types/errors/stacktrace_test.go @@ -15,19 +15,19 @@ func TestStackTrace(t *testing.T) { }{ "New gives us a stacktrace": { err: Wrap(ErrNoSignatures, "name"), - wantError: "name: no signatures supplied", + wantError: "no signatures supplied: name", }, "Wrapping stderr gives us a stacktrace": { err: Wrap(fmt.Errorf("foo"), "standard"), - wantError: "standard: foo", + wantError: "foo: standard", }, "Wrapping pkg/errors gives us clean stacktrace": { err: Wrap(errors.New("bar"), "pkg"), - wantError: "pkg: bar", + wantError: "bar: pkg", }, "Wrapping inside another function is still clean": { err: Wrap(fmt.Errorf("indirect"), "do the do"), - wantError: "do the do: indirect", + wantError: "indirect: do the do", }, } diff --git a/types/errors_test.go b/types/errors_test.go deleted file mode 100644 index 912de348a408..000000000000 --- a/types/errors_test.go +++ /dev/null @@ -1,138 +0,0 @@ -package types - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -var codeTypes = []CodeType{ - CodeInternal, - CodeTxDecode, - CodeInvalidSequence, - CodeUnauthorized, - CodeInsufficientFunds, - CodeUnknownRequest, - CodeInvalidAddress, - CodeInvalidPubKey, - CodeUnknownAddress, - CodeInsufficientCoins, - CodeInvalidCoins, - CodeOutOfGas, - CodeMemoTooLarge, -} - -type errFn func(msg string) Error - -var errFns = []errFn{ - ErrInternal, - ErrTxDecode, - ErrInvalidSequence, - ErrUnauthorized, - ErrInsufficientFunds, - ErrUnknownRequest, - ErrInvalidAddress, - ErrInvalidPubKey, - ErrUnknownAddress, - ErrInsufficientCoins, - ErrInvalidCoins, - ErrOutOfGas, - ErrMemoTooLarge, -} - -func TestCodeType(t *testing.T) { - require.True(t, CodeOK.IsOK()) - - for tcnum, c := range codeTypes { - msg := CodeToDefaultMsg(c) - require.NotEqual(t, unknownCodeMsg(c), msg, "Code expected to be known. tc #%d, code %d, msg %s", tcnum, c, msg) - } - - msg := CodeToDefaultMsg(CodeOK) - require.Equal(t, unknownCodeMsg(CodeOK), msg) -} - -func TestErrFn(t *testing.T) { - for i, errFn := range errFns { - err := errFn("") - codeType := codeTypes[i] - require.Equal(t, err.Code(), codeType, "Err function expected to return proper code. tc #%d", i) - require.Equal(t, err.Codespace(), CodespaceRoot, "Err function expected to return proper codespace. tc #%d", i) - require.Equal(t, err.QueryResult().Code, uint32(err.Code()), "Err function expected to return proper Code from QueryResult. tc #%d") - require.Equal(t, err.QueryResult().Log, err.ABCILog(), "Err function expected to return proper ABCILog from QueryResult. tc #%d") - } -} - -func TestAppendMsgToErr(t *testing.T) { - for i, errFn := range errFns { - err := errFn("") - errMsg := err.Stacktrace().Error() - abciLog := err.ABCILog() - - // plain msg error - msg := AppendMsgToErr("something unexpected happened", errMsg) - require.Equal( - t, - fmt.Sprintf("something unexpected happened; %s", errMsg), - msg, - fmt.Sprintf("Should have formatted the error message of ABCI Log. tc #%d", i), - ) - - // ABCI Log msg error - msg = AppendMsgToErr("something unexpected happened", abciLog) - msgIdx := mustGetMsgIndex(abciLog) - require.Equal( - t, - fmt.Sprintf("%s%s; %s}", - abciLog[:msgIdx], - "something unexpected happened", - abciLog[msgIdx:len(abciLog)-1], - ), - msg, - fmt.Sprintf("Should have formatted the error message of ABCI Log. tc #%d", i)) - } -} - -func TestResultFromError(t *testing.T) { - cases := map[string]struct { - err error - expect Result - }{ - "sdk.Error": { - err: ErrUnauthorized("not owner"), - expect: Result{ - Codespace: CodespaceRoot, - Code: CodeUnauthorized, - Log: `{"codespace":"sdk","code":4,"message":"not owner"}`, - }, - }, - "types/errors": { - err: sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "not owner"), - expect: Result{ - Codespace: CodespaceRoot, - Code: CodeUnauthorized, - Log: `{"codespace":"sdk","code":4,"message":"not owner: unauthorized"}`, - }, - }, - "stdlib errors": { - err: fmt.Errorf("not owner"), - expect: Result{ - Codespace: CodespaceType("undefined"), - Code: CodeInternal, - // note that we redact the internal errors in the new package to not leak eg. panics - Log: `{"codespace":"undefined","code":1,"message":"internal error"}`, - }, - }, - } - - for name, tc := range cases { - tc := tc - t.Run(name, func(t *testing.T) { - res := ResultFromError(tc.err) - require.Equal(t, tc.expect, res) - }) - } -} diff --git a/types/handler.go b/types/handler.go index d0cc41ec46dc..6815230a861f 100644 --- a/types/handler.go +++ b/types/handler.go @@ -1,7 +1,7 @@ package types // Handler defines the core of the state transition function of an application. -type Handler func(ctx Context, msg Msg) Result +type Handler func(ctx Context, msg Msg) (*Result, error) // AnteHandler authenticates transactions, before their internal messages are handled. // If newCtx.IsZero(), ctx is used instead. diff --git a/types/queryable.go b/types/queryable.go index 9223332bc833..f89965906af8 100644 --- a/types/queryable.go +++ b/types/queryable.go @@ -1,6 +1,9 @@ package types -import abci "github.com/tendermint/tendermint/abci/types" +import ( + abci "github.com/tendermint/tendermint/abci/types" +) -// Type for querier functions on keepers to implement to handle custom queries -type Querier = func(ctx Context, path []string, req abci.RequestQuery) (res []byte, err Error) +// Querier defines a function type that a module querier must implement to handle +// custom client queries. +type Querier = func(ctx Context, path []string, req abci.RequestQuery) ([]byte, error) diff --git a/types/result.go b/types/result.go index 5821cab538bc..8b9a28df502b 100644 --- a/types/result.go +++ b/types/result.go @@ -12,36 +12,27 @@ import ( ctypes "github.com/tendermint/tendermint/rpc/core/types" ) -// Result is the union of ResponseFormat and ResponseCheckTx. -type Result struct { - // Code is the response code, is stored back on the chain. - Code CodeType - - // Codespace is the string referring to the domain of an error - Codespace CodespaceType - - // Data is any data returned from the app. - // Data has to be length prefixed in order to separate - // results from multiple msgs executions - Data []byte - - // Log contains the txs log information. NOTE: nondeterministic. - Log string - +// GasInfo defines tx execution gas context. +type GasInfo struct { // GasWanted is the maximum units of work we allow this tx to perform. GasWanted uint64 // GasUsed is the amount of gas actually consumed. NOTE: unimplemented GasUsed uint64 - - // Events contains a slice of Event objects that were emitted during some - // execution. - Events Events } -// TODO: In the future, more codes may be OK. -func (res Result) IsOK() bool { - return res.Code.IsOK() +// Result is the union of ResponseFormat and ResponseCheckTx. +type Result struct { + // Data is any data returned from message or handler execution. It MUST be length + // prefixed in order to separate data from multiple message executions. + Data []byte + + // Log contains the log information from message or handler execution. + Log string + + // Events contains a slice of Event objects that were emitted during message or + // handler execution. + Events Events } // ABCIMessageLogs represents a slice of ABCIMessageLog. @@ -50,7 +41,6 @@ type ABCIMessageLogs []ABCIMessageLog // ABCIMessageLog defines a structure containing an indexed tx ABCI message log. type ABCIMessageLog struct { MsgIndex uint16 `json:"msg_index"` - Success bool `json:"success"` Log string `json:"log"` // Events contains a slice of Event objects that were emitted during some @@ -58,10 +48,9 @@ type ABCIMessageLog struct { Events StringEvents `json:"events"` } -func NewABCIMessageLog(i uint16, success bool, log string, events Events) ABCIMessageLog { +func NewABCIMessageLog(i uint16, log string, events Events) ABCIMessageLog { return ABCIMessageLog{ MsgIndex: i, - Success: success, Log: log, Events: StringifyEvents(events.ToABCIEvents()), } @@ -84,6 +73,7 @@ func (logs ABCIMessageLogs) String() (str string) { type TxResponse struct { Height int64 `json:"height"` TxHash string `json:"txhash"` + Codespace string `json:"codespace,omitempty"` Code uint32 `json:"code,omitempty"` Data string `json:"data,omitempty"` RawLog string `json:"raw_log,omitempty"` @@ -91,7 +81,6 @@ type TxResponse struct { Info string `json:"info,omitempty"` GasWanted int64 `json:"gas_wanted,omitempty"` GasUsed int64 `json:"gas_used,omitempty"` - Codespace string `json:"codespace,omitempty"` Tx Tx `json:"tx,omitempty"` Timestamp string `json:"timestamp,omitempty"` @@ -100,15 +89,6 @@ type TxResponse struct { Events StringEvents `json:"events,omitempty"` } -func (res TxResponse) IsOK() bool { - for _, lg := range res.Logs { - if !lg.Success { - return false - } - } - return true -} - // NewResponseResultTx returns a TxResponse given a ResultTx from tendermint func NewResponseResultTx(res *ctypes.ResultTx, tx Tx, timestamp string) TxResponse { if res == nil { @@ -120,6 +100,7 @@ func NewResponseResultTx(res *ctypes.ResultTx, tx Tx, timestamp string) TxRespon return TxResponse{ TxHash: res.Hash.String(), Height: res.Height, + Codespace: res.TxResult.Codespace, Code: res.TxResult.Code, Data: strings.ToUpper(hex.EncodeToString(res.TxResult.Data)), RawLog: res.TxResult.Log, @@ -162,6 +143,7 @@ func newTxResponseCheckTx(res *ctypes.ResultBroadcastTxCommit) TxResponse { return TxResponse{ Height: res.Height, TxHash: txHash, + Codespace: res.CheckTx.Codespace, Code: res.CheckTx.Code, Data: strings.ToUpper(hex.EncodeToString(res.CheckTx.Data)), RawLog: res.CheckTx.Log, @@ -170,7 +152,6 @@ func newTxResponseCheckTx(res *ctypes.ResultBroadcastTxCommit) TxResponse { GasWanted: res.CheckTx.GasWanted, GasUsed: res.CheckTx.GasUsed, Events: StringifyEvents(res.CheckTx.Events), - Codespace: res.CheckTx.Codespace, } } @@ -189,6 +170,7 @@ func newTxResponseDeliverTx(res *ctypes.ResultBroadcastTxCommit) TxResponse { return TxResponse{ Height: res.Height, TxHash: txHash, + Codespace: res.DeliverTx.Codespace, Code: res.DeliverTx.Code, Data: strings.ToUpper(hex.EncodeToString(res.DeliverTx.Data)), RawLog: res.DeliverTx.Log, @@ -197,7 +179,6 @@ func newTxResponseDeliverTx(res *ctypes.ResultBroadcastTxCommit) TxResponse { GasWanted: res.DeliverTx.GasWanted, GasUsed: res.DeliverTx.GasUsed, Events: StringifyEvents(res.DeliverTx.Events), - Codespace: res.DeliverTx.Codespace, } } diff --git a/types/result_test.go b/types/result_test.go index c4fedc2992f3..bbdf3b75e70a 100644 --- a/types/result_test.go +++ b/types/result_test.go @@ -7,17 +7,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestResult(t *testing.T) { - var res Result - require.True(t, res.IsOK()) - - res.Data = []byte("data") - require.True(t, res.IsOK()) - - res.Code = CodeType(1) - require.False(t, res.IsOK()) -} - func TestParseABCILog(t *testing.T) { logs := `[{"log":"","msg_index":1,"success":true}]` @@ -26,12 +15,11 @@ func TestParseABCILog(t *testing.T) { require.Len(t, res, 1) require.Equal(t, res[0].Log, "") require.Equal(t, res[0].MsgIndex, uint16(1)) - require.True(t, res[0].Success) } func TestABCIMessageLog(t *testing.T) { events := Events{NewEvent("transfer", NewAttribute("sender", "foo"))} - msgLog := NewABCIMessageLog(0, true, "", events) + msgLog := NewABCIMessageLog(0, "", events) msgLogs := ABCIMessageLogs{msgLog} bz, err := codec.Cdc.MarshalJSON(msgLogs) diff --git a/types/store.go b/types/store.go index db18b127b69d..0a972bf7403c 100644 --- a/types/store.go +++ b/types/store.go @@ -40,6 +40,18 @@ func KVStoreReversePrefixIterator(kvs KVStore, prefix []byte) Iterator { return types.KVStoreReversePrefixIterator(kvs, prefix) } +// KVStorePrefixIteratorPaginated returns iterator over items in the selected page. +// Items iterated and skipped in ascending order. +func KVStorePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator { + return types.KVStorePrefixIteratorPaginated(kvs, prefix, page, limit) +} + +// KVStoreReversePrefixIteratorPaginated returns iterator over items in the selected page. +// Items iterated and skipped in descending order. +func KVStoreReversePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator { + return types.KVStorePrefixIteratorPaginated(kvs, prefix, page, limit) +} + // DiffKVStores compares two KVstores and returns all the key/value pairs // that differ from one another. It also skips value comparison for a set of provided prefixes func DiffKVStores(a KVStore, b KVStore, prefixesToSkip [][]byte) (kvAs, kvBs []cmn.KVPair) { diff --git a/types/tx_msg.go b/types/tx_msg.go index bc4c2540d911..1b0da612b736 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -17,7 +17,7 @@ type Msg interface { // ValidateBasic does a simple validation check that // doesn't require access to any other information. - ValidateBasic() Error + ValidateBasic() error // Get the canonical byte representation of the Msg. GetSignBytes() []byte @@ -37,13 +37,13 @@ type Tx interface { // ValidateBasic does a simple and lightweight validation check that doesn't // require access to any other information. - ValidateBasic() Error + ValidateBasic() error } //__________________________________________________________ // TxDecoder unmarshals transaction bytes -type TxDecoder func(txBytes []byte) (Tx, Error) +type TxDecoder func(txBytes []byte) (Tx, error) // TxEncoder marshals transaction to bytes type TxEncoder func(tx Tx) ([]byte, error) @@ -73,7 +73,7 @@ func (msg *TestMsg) GetSignBytes() []byte { } return MustSortJSON(bz) } -func (msg *TestMsg) ValidateBasic() Error { return nil } +func (msg *TestMsg) ValidateBasic() error { return nil } func (msg *TestMsg) GetSigners() []AccAddress { return msg.signers } diff --git a/types/uint.go b/types/uint.go index da43f5fb9094..1cc289b900dc 100644 --- a/types/uint.go +++ b/types/uint.go @@ -99,6 +99,14 @@ func (u Uint) MulUint64(u2 uint64) (res Uint) { return u.Mul(NewUint(u2)) } // Quo divides Uint with Uint func (u Uint) Quo(u2 Uint) (res Uint) { return NewUintFromBigInt(div(u.i, u2.i)) } +// Mod returns remainder after dividing with Uint +func (u Uint) Mod(u2 Uint) Uint { + if u2.IsZero() { + panic("division-by-zero") + } + return Uint{mod(u.i, u2.i)} +} + // Quo divides Uint with uint64 func (u Uint) QuoUint64(u2 uint64) Uint { return u.Quo(NewUint(u2)) } @@ -172,3 +180,39 @@ func checkNewUint(i *big.Int) (Uint, error) { } return Uint{i}, nil } + +// RelativePow raises x to the power of n, where x (and the result, z) are scaled by factor b +// for example, RelativePow(210, 2, 100) = 441 (2.1^2 = 4.41) +func RelativePow(x Uint, n Uint, b Uint) (z Uint) { + if x.IsZero() { + if n.IsZero() { + z = b // 0^0 = 1 + return + } + z = ZeroUint() // otherwise 0^a = 0 + return + } + + z = x + if n.Mod(NewUint(2)).Equal(ZeroUint()) { + z = b + } + + halfOfB := b.Quo(NewUint(2)) + n = n.Quo(NewUint(2)) + + for n.GT(ZeroUint()) { + xSquared := x.Mul(x) + xSquaredRounded := xSquared.Add(halfOfB) + + x = xSquaredRounded.Quo(b) + + if n.Mod(NewUint(2)).Equal(OneUint()) { + zx := z.Mul(x) + zxRounded := zx.Add(halfOfB) + z = zxRounded.Quo(b) + } + n = n.Quo(NewUint(2)) + } + return z +} diff --git a/types/uint_test.go b/types/uint_test.go index d371c81369a0..e90fbf7f509c 100644 --- a/types/uint_test.go +++ b/types/uint_test.go @@ -256,3 +256,22 @@ func TestParseUint(t *testing.T) { func randuint() Uint { return NewUint(rand.Uint64()) } + +func TestRelativePow(t *testing.T) { + tests := []struct { + args []Uint + want Uint + }{ + {[]Uint{ZeroUint(), ZeroUint(), OneUint()}, OneUint()}, + {[]Uint{ZeroUint(), ZeroUint(), NewUint(10)}, NewUint(10)}, + {[]Uint{ZeroUint(), OneUint(), NewUint(10)}, ZeroUint()}, + {[]Uint{NewUint(10), NewUint(2), OneUint()}, NewUint(100)}, + {[]Uint{NewUint(210), NewUint(2), NewUint(100)}, NewUint(441)}, + {[]Uint{NewUint(2100), NewUint(2), NewUint(1000)}, NewUint(4410)}, + {[]Uint{NewUint(1000000001547125958), NewUint(600), NewUint(1000000000000000000)}, NewUint(1000000928276004850)}, + } + for i, tc := range tests { + res := RelativePow(tc.args[0], tc.args[1], tc.args[2]) + require.Equal(t, tc.want, res, "unexpected result for test case %d, input: %v, got: %v", i, tc.args, res) + } +} diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index 5ac42a6dc855..1d55b4d320c3 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -2,6 +2,7 @@ package ante_test import ( "encoding/json" + "errors" "fmt" "math/rand" "strings" @@ -26,14 +27,10 @@ func checkValidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx } // run the tx through the anteHandler and ensure it fails with the given code -func checkInvalidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, simulate bool, code sdk.CodeType) { +func checkInvalidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, simulate bool, expErr error) { _, err := anteHandler(ctx, tx, simulate) require.NotNil(t, err) - - result := sdk.ResultFromError(err) - - require.Equal(t, code, result.Code, fmt.Sprintf("Expected %v, got %v", code, result)) - require.Equal(t, sdk.CodespaceRoot, result.Codespace) + require.True(t, errors.Is(expErr, err)) } // Test that simulate transaction accurately estimates gas cost @@ -117,23 +114,23 @@ func TestAnteHandlerSigErrors(t *testing.T) { require.Equal(t, expectedSigners, stdTx.GetSigners()) // Check no signatures fails - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeNoSignatures) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrNoSignatures) // test num sigs dont match GetSigners privs, accNums, seqs = []crypto.PrivKey{priv1}, []uint64{0}, []uint64{0} tx = types.NewTestTx(ctx, msgs, privs, accNums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnauthorized) // test an unrecognized account privs, accNums, seqs = []crypto.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0} tx = types.NewTestTx(ctx, msgs, privs, accNums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnknownAddress) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnknownAddress) // save the first account, but second is still unrecognized acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) acc1.SetCoins(fee.Amount) app.AccountKeeper.SetAccount(ctx, acc1) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnknownAddress) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnknownAddress) } // Test logic around account number checking with one signer and many signers. @@ -172,7 +169,7 @@ func TestAnteHandlerAccountNumbers(t *testing.T) { // new tx from wrong account number seqs = []uint64{1} tx = types.NewTestTx(ctx, msgs, privs, []uint64{1}, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnauthorized) // from correct account number seqs = []uint64{1} @@ -185,7 +182,7 @@ func TestAnteHandlerAccountNumbers(t *testing.T) { msgs = []sdk.Msg{msg1, msg2} privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{1, 0}, []uint64{2, 0} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnauthorized) // correct account numbers privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{2, 0} @@ -228,7 +225,7 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { // new tx from wrong account number seqs = []uint64{1} tx = types.NewTestTx(ctx, msgs, privs, []uint64{1}, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnauthorized) // from correct account number seqs = []uint64{1} @@ -241,7 +238,7 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { msgs = []sdk.Msg{msg1, msg2} privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{1, 0}, []uint64{2, 0} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnauthorized) // correct account numbers privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{0, 0}, []uint64{2, 0} @@ -288,7 +285,7 @@ func TestAnteHandlerSequences(t *testing.T) { checkValidTx(t, anteHandler, ctx, tx, false) // test sending it again fails (replay protection) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnauthorized) // fix sequence, should pass seqs = []uint64{1} @@ -305,14 +302,14 @@ func TestAnteHandlerSequences(t *testing.T) { checkValidTx(t, anteHandler, ctx, tx, false) // replay fails - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnauthorized) // tx from just second signer with incorrect sequence fails msg = types.NewTestMsg(addr2) msgs = []sdk.Msg{msg} privs, accnums, seqs = []crypto.PrivKey{priv2}, []uint64{1}, []uint64{0} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnauthorized) // fix the sequence and it passes tx = types.NewTestTx(ctx, msgs, []crypto.PrivKey{priv2}, []uint64{1}, []uint64{1}, fee) @@ -348,11 +345,11 @@ func TestAnteHandlerFees(t *testing.T) { // signer does not have enough funds to pay the fee tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInsufficientFunds) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrInsufficientFunds) acc1.SetCoins(sdk.NewCoins(sdk.NewInt64Coin("atom", 149))) app.AccountKeeper.SetAccount(ctx, acc1) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInsufficientFunds) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrInsufficientFunds) require.True(t, app.SupplyKeeper.GetModuleAccount(ctx, types.FeeCollectorName).GetCoins().Empty()) require.True(sdk.IntEq(t, app.AccountKeeper.GetAccount(ctx, addr1).GetCoins().AmountOf("atom"), sdk.NewInt(149))) @@ -388,17 +385,17 @@ func TestAnteHandlerMemoGas(t *testing.T) { // tx does not have enough gas tx = types.NewTestTx(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeOutOfGas) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrOutOfGas) // tx with memo doesn't have enough gas fee = types.NewStdFee(801, sdk.NewCoins(sdk.NewInt64Coin("atom", 0))) tx = types.NewTestTxWithMemo(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee, "abcininasidniandsinasindiansdiansdinaisndiasndiadninsd") - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeOutOfGas) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrOutOfGas) // memo too large fee = types.NewStdFee(50000, sdk.NewCoins(sdk.NewInt64Coin("atom", 0))) tx = types.NewTestTxWithMemo(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee, strings.Repeat("01234567890", 500)) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeMemoTooLarge) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrMemoTooLarge) // tx with memo has enough gas fee = types.NewStdFee(50000, sdk.NewCoins(sdk.NewInt64Coin("atom", 0))) @@ -492,7 +489,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { chainID := ctx.ChainID() chainID2 := chainID + "somemorestuff" - codeUnauth := sdk.CodeUnauthorized + errUnauth := sdkerrors.ErrUnauthorized cases := []struct { chainID string @@ -500,14 +497,14 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { seq uint64 fee types.StdFee msgs []sdk.Msg - code sdk.CodeType + err error }{ - {chainID2, 0, 1, fee, msgs, codeUnauth}, // test wrong chain_id - {chainID, 0, 2, fee, msgs, codeUnauth}, // test wrong seqs - {chainID, 1, 1, fee, msgs, codeUnauth}, // test wrong accnum - {chainID, 0, 1, fee, []sdk.Msg{types.NewTestMsg(addr2)}, codeUnauth}, // test wrong msg - {chainID, 0, 1, fee2, msgs, codeUnauth}, // test wrong fee - {chainID, 0, 1, fee3, msgs, codeUnauth}, // test wrong fee + {chainID2, 0, 1, fee, msgs, errUnauth}, // test wrong chain_id + {chainID, 0, 2, fee, msgs, errUnauth}, // test wrong seqs + {chainID, 1, 1, fee, msgs, errUnauth}, // test wrong accnum + {chainID, 0, 1, fee, []sdk.Msg{types.NewTestMsg(addr2)}, errUnauth}, // test wrong msg + {chainID, 0, 1, fee2, msgs, errUnauth}, // test wrong fee + {chainID, 0, 1, fee3, msgs, errUnauth}, // test wrong fee } privs, seqs = []crypto.PrivKey{priv1}, []uint64{1} @@ -517,20 +514,20 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { types.StdSignBytes(cs.chainID, cs.accnum, cs.seq, cs.fee, cs.msgs, ""), "", ) - checkInvalidTx(t, anteHandler, ctx, tx, false, cs.code) + checkInvalidTx(t, anteHandler, ctx, tx, false, cs.err) } // test wrong signer if public key exist privs, accnums, seqs = []crypto.PrivKey{priv2}, []uint64{0}, []uint64{1} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrInvalidPubKey) // test wrong signer if public doesn't exist msg = types.NewTestMsg(addr2) msgs = []sdk.Msg{msg} privs, accnums, seqs = []crypto.PrivKey{priv1}, []uint64{1}, []uint64{0} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrInvalidPubKey) } func TestAnteHandlerSetPubKey(t *testing.T) { @@ -572,14 +569,14 @@ func TestAnteHandlerSetPubKey(t *testing.T) { tx = types.NewTestTx(ctx, msgs, privs, []uint64{1}, seqs, fee) sigs := tx.(types.StdTx).Signatures sigs[0].PubKey = nil - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrInvalidPubKey) acc2 = app.AccountKeeper.GetAccount(ctx, addr2) require.Nil(t, acc2.GetPubKey()) // test invalid signature and public key tx = types.NewTestTx(ctx, msgs, privs, []uint64{1}, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrInvalidPubKey) acc2 = app.AccountKeeper.GetAccount(ctx, addr2) require.Nil(t, acc2.GetPubKey()) @@ -686,7 +683,7 @@ func TestAnteHandlerSigLimitExceeded(t *testing.T) { privs, accnums, seqs := []crypto.PrivKey{priv1, priv2, priv3, priv4, priv5, priv6, priv7, priv8}, []uint64{0, 1, 2, 3, 4, 5, 6, 7}, []uint64{0, 0, 0, 0, 0, 0, 0, 0} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeTooManySignatures) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrTooManySignatures) } // Test custom SignatureVerificationGasConsumer @@ -717,7 +714,7 @@ func TestCustomSignatureVerificationGasConsumer(t *testing.T) { fee := types.NewTestStdFee() msgs := []sdk.Msg{msg} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) - checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey) + checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrInvalidPubKey) // verify that an ed25519 account gets accepted priv2 := ed25519.GenPrivKey() diff --git a/x/auth/client/cli/decode.go b/x/auth/client/cli/decode.go index 370f4fe72d7f..c9253d8fb4a3 100644 --- a/x/auth/client/cli/decode.go +++ b/x/auth/client/cli/decode.go @@ -1,98 +1,54 @@ package cli import ( - "bytes" "encoding/base64" "encoding/hex" - "encoding/json" - "fmt" "github.com/spf13/cobra" + "github.com/spf13/viper" "github.com/tendermint/go-amino" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/client/flags" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) +const flagHex = "hex" + // GetDecodeCommand returns the decode command to take Amino-serialized bytes // and turn it into a JSONified transaction. func GetDecodeCommand(codec *amino.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "decode [amino-byte-string]", - Short: "Decode an amino-encoded transaction string", + Short: "Decode an amino-encoded transaction string.", Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) (err error) { - cliCtx := context.NewCLIContext().WithCodec(codec) - - txBytes, err := base64.StdEncoding.DecodeString(args[0]) - if err != nil { - return err - } - - var stdTx authtypes.StdTx - err = cliCtx.Codec.UnmarshalBinaryLengthPrefixed(txBytes, &stdTx) - if err != nil { - return err - } - - return cliCtx.PrintOutput(stdTx) - }, + RunE: runDecodeTxString(codec), } - return client.PostCommands(cmd)[0] + cmd.Flags().BoolP(flagHex, "x", false, "Treat input as hexadecimal instead of base64") + return flags.PostCommands(cmd)[0] } -// GetDecodeTxCmd - returns the command to decode a tx from hex or base64 -func GetDecodeTxCmd(cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ - Use: "decode-tx [tx]", - Short: "Decode a tx from hex or base64", - Long: fmt.Sprintf(`Decode a tx from hex, base64. - -Example: - $ %s tx decode-tx TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz - `, version.ClientName), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - - txString := args[0] - - // try hex, then base64 - txBytes, err := hex.DecodeString(txString) - if err != nil { - var err2 error - txBytes, err2 = base64.StdEncoding.DecodeString(txString) - if err2 != nil { - return fmt.Errorf(`expected hex or base64. Got errors: - hex: %v, - base64: %v - `, err, err2) - } - } - - var tx = types.StdTx{} - - err = cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx) - if err != nil { - return err - } - - bz, err := cdc.MarshalJSON(tx) - if err != nil { - return err - } - - buf := bytes.NewBuffer([]byte{}) - if err = json.Indent(buf, bz, "", " "); err != nil { - return err - } - - fmt.Println(buf.String()) - return nil - }, +func runDecodeTxString(codec *amino.Codec) func(cmd *cobra.Command, args []string) (err error) { + return func(cmd *cobra.Command, args []string) (err error) { + cliCtx := context.NewCLIContext().WithCodec(codec).WithOutput(cmd.OutOrStdout()) + var txBytes []byte + + if viper.GetBool(flagHex) { + txBytes, err = hex.DecodeString(args[0]) + } else { + txBytes, err = base64.StdEncoding.DecodeString(args[0]) + } + if err != nil { + return err + } + + var stdTx authtypes.StdTx + err = cliCtx.Codec.UnmarshalBinaryLengthPrefixed(txBytes, &stdTx) + if err != nil { + return err + } + + return cliCtx.PrintOutput(stdTx) } } diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index be094b6c69a4..77cba3e59c1e 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -61,8 +61,10 @@ func QueryTxsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, - sdk.AppendMsgToErr("could not parse query parameters", err.Error())) + rest.WriteErrorResponse( + w, http.StatusBadRequest, + fmt.Sprintf("failed to parse query parameters: %s", err), + ) return } diff --git a/x/auth/client/utils/tx.go b/x/auth/client/utils/tx.go index ba8c81d59262..e6a038f24cb7 100644 --- a/x/auth/client/utils/tx.go +++ b/x/auth/client/utils/tx.go @@ -10,10 +10,10 @@ import ( "github.com/pkg/errors" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/input" + "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -94,7 +94,7 @@ func CompleteAndBroadcastTxCLI(txBldr authtypes.TxBuilder, cliCtx context.CLICon } // build and sign the transaction - txBytes, err := txBldr.BuildAndSign(fromName, client.DefaultKeyPass, msgs) + txBytes, err := txBldr.BuildAndSign(fromName, keys.DefaultKeyPass, msgs) if err != nil { return err } @@ -231,7 +231,7 @@ func SignStdTx( } } - return txBldr.SignStdTx(name, client.DefaultKeyPass, stdTx, appendSig) + return txBldr.SignStdTx(name, keys.DefaultKeyPass, stdTx, appendSig) } // SignStdTxWithSignerAddress attaches a signature to a StdTx and returns a copy of a it. @@ -253,7 +253,7 @@ func SignStdTxWithSignerAddress(txBldr authtypes.TxBuilder, cliCtx context.CLICo } } - return txBldr.SignStdTx(name, client.DefaultKeyPass, stdTx, false) + return txBldr.SignStdTx(name, keys.DefaultKeyPass, stdTx, false) } // Read and decode a StdTx from the given filename. Can pass "-" to read from stdin. @@ -317,12 +317,12 @@ func adjustGasEstimate(estimate uint64, adjustment float64) uint64 { } func parseQueryResponse(cdc *codec.Codec, rawRes []byte) (uint64, error) { - var simulationResult sdk.Result - if err := cdc.UnmarshalBinaryLengthPrefixed(rawRes, &simulationResult); err != nil { + var gasUsed uint64 + if err := cdc.UnmarshalBinaryLengthPrefixed(rawRes, &gasUsed); err != nil { return 0, err } - return simulationResult.GasUsed, nil + return gasUsed, nil } // PrepareTxBuilder populates a TxBuilder in preparation for the build of a Tx. diff --git a/x/auth/client/utils/tx_test.go b/x/auth/client/utils/tx_test.go index cde10cc56029..a9c33b232053 100644 --- a/x/auth/client/utils/tx_test.go +++ b/x/auth/client/utils/tx_test.go @@ -23,7 +23,7 @@ var ( func TestParseQueryResponse(t *testing.T) { cdc := makeCodec() - sdkResBytes := cdc.MustMarshalBinaryLengthPrefixed(sdk.Result{GasUsed: 10}) + sdkResBytes := cdc.MustMarshalBinaryLengthPrefixed(uint64(10)) gas, err := parseQueryResponse(cdc, sdkResBytes) assert.Equal(t, gas, uint64(10)) assert.Nil(t, err) @@ -39,14 +39,16 @@ func TestCalculateGas(t *testing.T) { if wantErr { return nil, 0, errors.New("") } - return cdc.MustMarshalBinaryLengthPrefixed(sdk.Result{GasUsed: gasUsed}), 0, nil + return cdc.MustMarshalBinaryLengthPrefixed(gasUsed), 0, nil } } + type args struct { queryFuncGasUsed uint64 queryFuncWantErr bool adjustment float64 } + tests := []struct { name string args args @@ -57,6 +59,7 @@ func TestCalculateGas(t *testing.T) { {"error", args{0, true, 1.2}, 0, 0, true}, {"adjusted gas", args{10, false, 1.2}, 10, 12, false}, } + for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { diff --git a/x/auth/keeper/keeper.go b/x/auth/keeper/keeper.go index d60a396d342b..244dec7c193b 100644 --- a/x/auth/keeper/keeper.go +++ b/x/auth/keeper/keeper.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/params/subspace" @@ -49,19 +50,19 @@ func (ak AccountKeeper) Logger(ctx sdk.Context) log.Logger { } // GetPubKey Returns the PubKey of the account at address -func (ak AccountKeeper) GetPubKey(ctx sdk.Context, addr sdk.AccAddress) (crypto.PubKey, sdk.Error) { +func (ak AccountKeeper) GetPubKey(ctx sdk.Context, addr sdk.AccAddress) (crypto.PubKey, error) { acc := ak.GetAccount(ctx, addr) if acc == nil { - return nil, sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", addr)) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", addr) } return acc.GetPubKey(), nil } // GetSequence Returns the Sequence of the account at address -func (ak AccountKeeper) GetSequence(ctx sdk.Context, addr sdk.AccAddress) (uint64, sdk.Error) { +func (ak AccountKeeper) GetSequence(ctx sdk.Context, addr sdk.AccAddress) (uint64, error) { acc := ak.GetAccount(ctx, addr) if acc == nil { - return 0, sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", addr)) + return 0, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", addr) } return acc.GetSequence(), nil } diff --git a/x/auth/keeper/querier.go b/x/auth/keeper/querier.go index b40dc0135d8f..28e505970b45 100644 --- a/x/auth/keeper/querier.go +++ b/x/auth/keeper/querier.go @@ -1,41 +1,40 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/types" ) // NewQuerier creates a querier for auth REST endpoints func NewQuerier(keeper AccountKeeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryAccount: return queryAccount(ctx, req, keeper) default: - return nil, sdk.ErrUnknownRequest("unknown auth query endpoint") + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) } } } -func queryAccount(ctx sdk.Context, req abci.RequestQuery, keeper AccountKeeper) ([]byte, sdk.Error) { +func queryAccount(ctx sdk.Context, req abci.RequestQuery, keeper AccountKeeper) ([]byte, error) { var params types.QueryAccountParams if err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } account := keeper.GetAccount(ctx, params.Address) if account == nil { - return nil, sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", params.Address)) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", params.Address) } bz, err := codec.MarshalJSONIndent(keeper.cdc, account) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil diff --git a/x/auth/types/expected_keepers.go b/x/auth/types/expected_keepers.go index 11e03ef36cb8..499bc288c849 100644 --- a/x/auth/types/expected_keepers.go +++ b/x/auth/types/expected_keepers.go @@ -7,7 +7,7 @@ import ( // SupplyKeeper defines the expected supply Keeper (noalias) type SupplyKeeper interface { - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error GetModuleAccount(ctx sdk.Context, moduleName string) exported.ModuleAccountI GetModuleAddress(moduleName string) sdk.AccAddress } diff --git a/x/auth/types/stdtx.go b/x/auth/types/stdtx.go index fa8b5d100d5f..bc6042abbbb2 100644 --- a/x/auth/types/stdtx.go +++ b/x/auth/types/stdtx.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/exported" ) @@ -42,20 +43,29 @@ func (tx StdTx) GetMsgs() []sdk.Msg { return tx.Msgs } // ValidateBasic does a simple and lightweight validation check that doesn't // require access to any other information. -func (tx StdTx) ValidateBasic() sdk.Error { +func (tx StdTx) ValidateBasic() error { stdSigs := tx.GetSignatures() if tx.Fee.Gas > maxGasWanted { - return sdk.ErrGasOverflow(fmt.Sprintf("invalid gas supplied; %d > %d", tx.Fee.Gas, maxGasWanted)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidRequest, + "invalid gas supplied; %d > %d", tx.Fee.Gas, maxGasWanted, + ) } if tx.Fee.Amount.IsAnyNegative() { - return sdk.ErrInsufficientFee(fmt.Sprintf("invalid fee %s amount provided", tx.Fee.Amount)) + return sdkerrors.Wrapf( + sdkerrors.ErrInsufficientFee, + "invalid fee provided: %s", tx.Fee.Amount, + ) } if len(stdSigs) == 0 { - return sdk.ErrNoSignatures("no signers") + return sdkerrors.ErrNoSignatures } if len(stdSigs) != len(tx.GetSigners()) { - return sdk.ErrUnauthorized("wrong number of signers") + return sdkerrors.Wrapf( + sdkerrors.ErrUnauthorized, + "wrong number of signers; expected %d, got %d", tx.GetSigners(), len(stdSigs), + ) } return nil @@ -240,18 +250,18 @@ type StdSignature struct { // DefaultTxDecoder logic for standard transaction decoding func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder { - return func(txBytes []byte) (sdk.Tx, sdk.Error) { + return func(txBytes []byte) (sdk.Tx, error) { var tx = StdTx{} if len(txBytes) == 0 { - return nil, sdk.ErrTxDecode("txBytes are empty") + return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx bytes are empty") } // StdTx.Msg is an interface. The concrete types // are registered by MakeTxCodec err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx) if err != nil { - return nil, sdk.ErrTxDecode("error decoding transaction").TraceSDK(err.Error()) + return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, err.Error()) } return tx, nil diff --git a/x/auth/types/stdtx_test.go b/x/auth/types/stdtx_test.go index 375a15c49cc4..8131006f59d5 100644 --- a/x/auth/types/stdtx_test.go +++ b/x/auth/types/stdtx_test.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) var ( @@ -78,7 +79,8 @@ func TestTxValidateBasic(t *testing.T) { err := tx.ValidateBasic() require.Error(t, err) - require.Equal(t, sdk.CodeInsufficientFee, err.Result().Code) + _, code, _ := sdkerrors.ABCIInfo(err, false) + require.Equal(t, sdkerrors.ErrInsufficientFee.ABCICode(), code) // require to fail validation when no signatures exist privs, accNums, seqs := []crypto.PrivKey{}, []uint64{}, []uint64{} @@ -86,7 +88,8 @@ func TestTxValidateBasic(t *testing.T) { err = tx.ValidateBasic() require.Error(t, err) - require.Equal(t, sdk.CodeNoSignatures, err.Result().Code) + _, code, _ = sdkerrors.ABCIInfo(err, false) + require.Equal(t, sdkerrors.ErrNoSignatures.ABCICode(), code) // require to fail validation when signatures do not match expected signers privs, accNums, seqs = []crypto.PrivKey{priv1}, []uint64{0, 1}, []uint64{0, 0} @@ -94,7 +97,8 @@ func TestTxValidateBasic(t *testing.T) { err = tx.ValidateBasic() require.Error(t, err) - require.Equal(t, sdk.CodeUnauthorized, err.Result().Code) + _, code, _ = sdkerrors.ABCIInfo(err, false) + require.Equal(t, sdkerrors.ErrUnauthorized.ABCICode(), code) // require to fail with invalid gas supplied badFee = NewTestStdFee() @@ -103,7 +107,8 @@ func TestTxValidateBasic(t *testing.T) { err = tx.ValidateBasic() require.Error(t, err) - require.Equal(t, sdk.CodeGasOverflow, err.Result().Code) + _, code, _ = sdkerrors.ABCIInfo(err, false) + require.Equal(t, sdkerrors.ErrInvalidRequest.ABCICode(), code) // require to pass when above criteria are matched privs, accNums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0} diff --git a/x/bank/alias.go b/x/bank/alias.go index 3533e3084d9d..1ac7cecebd90 100644 --- a/x/bank/alias.go +++ b/x/bank/alias.go @@ -1,25 +1,19 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/bank/internal/keeper -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/bank/internal/types package bank +// nolint + import ( "github.com/cosmos/cosmos-sdk/x/bank/internal/keeper" "github.com/cosmos/cosmos-sdk/x/bank/internal/types" ) const ( - QueryBalance = keeper.QueryBalance - DefaultCodespace = types.DefaultCodespace - CodeSendDisabled = types.CodeSendDisabled - CodeInvalidInputsOutputs = types.CodeInvalidInputsOutputs - ModuleName = types.ModuleName - QuerierRoute = types.QuerierRoute - RouterKey = types.RouterKey - DefaultParamspace = types.DefaultParamspace - DefaultSendEnabled = types.DefaultSendEnabled + QueryBalance = keeper.QueryBalance + ModuleName = types.ModuleName + QuerierRoute = types.QuerierRoute + RouterKey = types.RouterKey + DefaultParamspace = types.DefaultParamspace + DefaultSendEnabled = types.DefaultSendEnabled EventTypeTransfer = types.EventTypeTransfer AttributeKeyRecipient = types.AttributeKeyRecipient @@ -28,7 +22,6 @@ const ( ) var ( - // functions aliases RegisterInvariants = keeper.RegisterInvariants NonnegativeBalanceInvariant = keeper.NonnegativeBalanceInvariant NewBaseKeeper = keeper.NewBaseKeeper @@ -50,10 +43,8 @@ var ( ValidateInputsOutputs = types.ValidateInputsOutputs ParamKeyTable = types.ParamKeyTable NewQueryBalanceParams = types.NewQueryBalanceParams - - // variable aliases - ModuleCdc = types.ModuleCdc - ParamStoreKeySendEnabled = types.ParamStoreKeySendEnabled + ModuleCdc = types.ModuleCdc + ParamStoreKeySendEnabled = types.ParamStoreKeySendEnabled ) type ( diff --git a/x/bank/bench_test.go b/x/bank/bench_test.go index 9e0bd735484d..9161a88c31ba 100644 --- a/x/bank/bench_test.go +++ b/x/bank/bench_test.go @@ -34,10 +34,11 @@ func BenchmarkOneBankSendTxPerBlock(b *testing.B) { // Committing, and what time comes from Check/Deliver Tx. for i := 0; i < b.N; i++ { benchmarkApp.BeginBlock(abci.RequestBeginBlock{}) - x := benchmarkApp.Check(txs[i]) - if !x.IsOK() { + _, _, err := benchmarkApp.Check(txs[i]) + if err != nil { panic("something is broken in checking transaction") } + benchmarkApp.Deliver(txs[i]) benchmarkApp.EndBlock(abci.RequestEndBlock{}) benchmarkApp.Commit() @@ -63,10 +64,11 @@ func BenchmarkOneBankMultiSendTxPerBlock(b *testing.B) { // Committing, and what time comes from Check/Deliver Tx. for i := 0; i < b.N; i++ { benchmarkApp.BeginBlock(abci.RequestBeginBlock{}) - x := benchmarkApp.Check(txs[i]) - if !x.IsOK() { + _, _, err := benchmarkApp.Check(txs[i]) + if err != nil { panic("something is broken in checking transaction") } + benchmarkApp.Deliver(txs[i]) benchmarkApp.EndBlock(abci.RequestEndBlock{}) benchmarkApp.Commit() diff --git a/x/bank/client/cli/tx.go b/x/bank/client/cli/tx.go index 71e1392b968a..58bce19eba6f 100644 --- a/x/bank/client/cli/tx.go +++ b/x/bank/client/cli/tx.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" @@ -57,7 +58,7 @@ func SendTxCmd(cdc *codec.Codec) *cobra.Command { }, } - cmd = client.PostCommands(cmd)[0] + cmd = flags.PostCommands(cmd)[0] return cmd } diff --git a/x/bank/handler.go b/x/bank/handler.go index 8e6133347715..3c83ec4c2af4 100644 --- a/x/bank/handler.go +++ b/x/bank/handler.go @@ -1,16 +1,15 @@ package bank import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/bank/internal/keeper" "github.com/cosmos/cosmos-sdk/x/bank/internal/types" ) // NewHandler returns a handler for "bank" type messages. func NewHandler(k keeper.Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -21,25 +20,24 @@ func NewHandler(k keeper.Keeper) sdk.Handler { return handleMsgMultiSend(ctx, k, msg) default: - errMsg := fmt.Sprintf("unrecognized bank message type: %T", msg) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized bank message type: %T", msg) } } } // Handle MsgSend. -func handleMsgSend(ctx sdk.Context, k keeper.Keeper, msg types.MsgSend) sdk.Result { +func handleMsgSend(ctx sdk.Context, k keeper.Keeper, msg types.MsgSend) (*sdk.Result, error) { if !k.GetSendEnabled(ctx) { - return types.ErrSendDisabled(k.Codespace()).Result() + return nil, types.ErrSendDisabled } if k.BlacklistedAddr(msg.ToAddress) { - return sdk.ErrUnauthorized(fmt.Sprintf("%s is not allowed to receive transactions", msg.ToAddress)).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive transactions", msg.ToAddress) } err := k.SendCoins(ctx, msg.FromAddress, msg.ToAddress, msg.Amount) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -49,25 +47,25 @@ func handleMsgSend(ctx sdk.Context, k keeper.Keeper, msg types.MsgSend) sdk.Resu ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } // Handle MsgMultiSend. -func handleMsgMultiSend(ctx sdk.Context, k keeper.Keeper, msg types.MsgMultiSend) sdk.Result { +func handleMsgMultiSend(ctx sdk.Context, k keeper.Keeper, msg types.MsgMultiSend) (*sdk.Result, error) { // NOTE: totalIn == totalOut should already have been checked if !k.GetSendEnabled(ctx) { - return types.ErrSendDisabled(k.Codespace()).Result() + return nil, types.ErrSendDisabled } for _, out := range msg.Outputs { if k.BlacklistedAddr(out.Address) { - return sdk.ErrUnauthorized(fmt.Sprintf("%s is not allowed to receive transactions", out.Address)).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive transactions", out.Address) } } err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -77,5 +75,5 @@ func handleMsgMultiSend(ctx sdk.Context, k keeper.Keeper, msg types.MsgMultiSend ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } diff --git a/x/bank/handler_test.go b/x/bank/handler_test.go index 457afc8e69d9..f9d313385f0a 100644 --- a/x/bank/handler_test.go +++ b/x/bank/handler_test.go @@ -4,17 +4,20 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/stretchr/testify/require" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func TestInvalidMsg(t *testing.T) { h := NewHandler(nil) - res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) - require.False(t, res.IsOK()) - require.True(t, strings.Contains(res.Log, "unrecognized bank message type")) + res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) + require.Error(t, err) + require.Nil(t, res) + + _, _, log := sdkerrors.ABCIInfo(err, false) + require.True(t, strings.Contains(log, "unrecognized bank message type")) } diff --git a/x/bank/internal/keeper/keeper.go b/x/bank/internal/keeper/keeper.go index cd0242e23f17..f36477f3c3b1 100644 --- a/x/bank/internal/keeper/keeper.go +++ b/x/bank/internal/keeper/keeper.go @@ -7,6 +7,7 @@ import ( "github.com/tendermint/tendermint/libs/log" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" vestexported "github.com/cosmos/cosmos-sdk/x/auth/vesting/exported" "github.com/cosmos/cosmos-sdk/x/bank/internal/types" @@ -20,8 +21,8 @@ var _ Keeper = (*BaseKeeper)(nil) type Keeper interface { SendKeeper - DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) sdk.Error - UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error + UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error } // BaseKeeper manages transfers between accounts. It implements the Keeper interface. @@ -33,13 +34,13 @@ type BaseKeeper struct { } // NewBaseKeeper returns a new BaseKeeper -func NewBaseKeeper(ak types.AccountKeeper, - paramSpace params.Subspace, - codespace sdk.CodespaceType, blacklistedAddrs map[string]bool) BaseKeeper { +func NewBaseKeeper( + ak types.AccountKeeper, paramSpace params.Subspace, blacklistedAddrs map[string]bool, +) BaseKeeper { ps := paramSpace.WithKeyTable(types.ParamKeyTable()) return BaseKeeper{ - BaseSendKeeper: NewBaseSendKeeper(ak, ps, codespace, blacklistedAddrs), + BaseSendKeeper: NewBaseSendKeeper(ak, ps, blacklistedAddrs), ak: ak, paramSpace: ps, } @@ -50,33 +51,32 @@ func NewBaseKeeper(ak types.AccountKeeper, // vesting and vested coins. // The coins are then transferred from the delegator address to a ModuleAccount address. // If any of the delegation amounts are negative, an error is returned. -func (keeper BaseKeeper) DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) sdk.Error { - +func (keeper BaseKeeper) DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error { delegatorAcc := keeper.ak.GetAccount(ctx, delegatorAddr) if delegatorAcc == nil { - return sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", delegatorAddr)) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", delegatorAddr) } moduleAcc := keeper.ak.GetAccount(ctx, moduleAccAddr) if moduleAcc == nil { - return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", moduleAccAddr)) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", moduleAccAddr) } if !amt.IsValid() { - return sdk.ErrInvalidCoins(amt.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } oldCoins := delegatorAcc.GetCoins() _, hasNeg := oldCoins.SafeSub(amt) if hasNeg { - return sdk.ErrInsufficientCoins( - fmt.Sprintf("insufficient account funds; %s < %s", oldCoins, amt), + return sdkerrors.Wrapf( + sdkerrors.ErrInsufficientFunds, "insufficient account funds; %s < %s", oldCoins, amt, ) } if err := trackDelegation(delegatorAcc, ctx.BlockHeader().Time, amt); err != nil { - return sdk.ErrInternal(fmt.Sprintf("failed to track delegation: %v", err)) + return sdkerrors.Wrap(err, "failed to track delegation") } keeper.ak.SetAccount(ctx, delegatorAcc) @@ -94,28 +94,27 @@ func (keeper BaseKeeper) DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAcc // vesting and vested coins. // The coins are then transferred from a ModuleAccount address to the delegator address. // If any of the undelegation amounts are negative, an error is returned. -func (keeper BaseKeeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) sdk.Error { - +func (keeper BaseKeeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error { delegatorAcc := keeper.ak.GetAccount(ctx, delegatorAddr) if delegatorAcc == nil { - return sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", delegatorAddr)) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", delegatorAddr) } moduleAcc := keeper.ak.GetAccount(ctx, moduleAccAddr) if moduleAcc == nil { - return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", moduleAccAddr)) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", moduleAccAddr) } if !amt.IsValid() { - return sdk.ErrInvalidCoins(amt.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } oldCoins := moduleAcc.GetCoins() newCoins, hasNeg := oldCoins.SafeSub(amt) if hasNeg { - return sdk.ErrInsufficientCoins( - fmt.Sprintf("insufficient account funds; %s < %s", oldCoins, amt), + return sdkerrors.Wrapf( + sdkerrors.ErrInsufficientFunds, "insufficient account funds; %s < %s", oldCoins, amt, ) } @@ -125,7 +124,7 @@ func (keeper BaseKeeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegat } if err := trackUndelegation(delegatorAcc, amt); err != nil { - return sdk.ErrInternal(fmt.Sprintf("failed to track undelegation: %v", err)) + return sdkerrors.Wrap(err, "failed to track undelegation") } keeper.ak.SetAccount(ctx, delegatorAcc) @@ -137,12 +136,12 @@ func (keeper BaseKeeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegat type SendKeeper interface { ViewKeeper - InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) sdk.Error - SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error - SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) - AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) - SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error + SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, error) + AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, error) + SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) error GetSendEnabled(ctx sdk.Context) bool SetSendEnabled(ctx sdk.Context, enabled bool) @@ -165,11 +164,12 @@ type BaseSendKeeper struct { } // NewBaseSendKeeper returns a new BaseSendKeeper. -func NewBaseSendKeeper(ak types.AccountKeeper, - paramSpace params.Subspace, codespace sdk.CodespaceType, blacklistedAddrs map[string]bool) BaseSendKeeper { +func NewBaseSendKeeper( + ak types.AccountKeeper, paramSpace params.Subspace, blacklistedAddrs map[string]bool, +) BaseSendKeeper { return BaseSendKeeper{ - BaseViewKeeper: NewBaseViewKeeper(ak, codespace), + BaseViewKeeper: NewBaseViewKeeper(ak), ak: ak, paramSpace: paramSpace, blacklistedAddrs: blacklistedAddrs, @@ -177,7 +177,7 @@ func NewBaseSendKeeper(ak types.AccountKeeper, } // InputOutputCoins handles a list of inputs and outputs -func (keeper BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) sdk.Error { +func (keeper BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error { // Safety check ensuring that when sending coins the keeper must maintain the // Check supply invariant and validity of Coins. if err := types.ValidateInputsOutputs(inputs, outputs); err != nil { @@ -216,7 +216,7 @@ func (keeper BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.In } // SendCoins moves coins from one account to another -func (keeper BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error { +func (keeper BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeTransfer, @@ -245,10 +245,9 @@ func (keeper BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, // SubtractCoins subtracts amt from the coins at the addr. // // CONTRACT: If the account is a vesting account, the amount has to be spendable. -func (keeper BaseSendKeeper) SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) { - +func (keeper BaseSendKeeper) SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, error) { if !amt.IsValid() { - return nil, sdk.ErrInvalidCoins(amt.String()) + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } oldCoins, spendableCoins := sdk.NewCoins(), sdk.NewCoins() @@ -263,8 +262,8 @@ func (keeper BaseSendKeeper) SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, // So the check here is sufficient instead of subtracting from oldCoins. _, hasNeg := spendableCoins.SafeSub(amt) if hasNeg { - return amt, sdk.ErrInsufficientCoins( - fmt.Sprintf("insufficient account funds; %s < %s", spendableCoins, amt), + return amt, sdkerrors.Wrapf( + sdkerrors.ErrInsufficientFunds, "insufficient account funds; %s < %s", spendableCoins, amt, ) } @@ -275,18 +274,17 @@ func (keeper BaseSendKeeper) SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, } // AddCoins adds amt to the coins at the addr. -func (keeper BaseSendKeeper) AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) { - +func (keeper BaseSendKeeper) AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, error) { if !amt.IsValid() { - return nil, sdk.ErrInvalidCoins(amt.String()) + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } oldCoins := keeper.GetCoins(ctx, addr) newCoins := oldCoins.Add(amt) if newCoins.IsAnyNegative() { - return amt, sdk.ErrInsufficientCoins( - fmt.Sprintf("insufficient account funds; %s < %s", oldCoins, amt), + return amt, sdkerrors.Wrapf( + sdkerrors.ErrInsufficientFunds, "insufficient account funds; %s < %s", oldCoins, amt, ) } @@ -295,10 +293,9 @@ func (keeper BaseSendKeeper) AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt } // SetCoins sets the coins at the addr. -func (keeper BaseSendKeeper) SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error { - +func (keeper BaseSendKeeper) SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) error { if !amt.IsValid() { - return sdk.ErrInvalidCoins(amt.String()) + sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } acc := keeper.ak.GetAccount(ctx, addr) @@ -340,19 +337,16 @@ var _ ViewKeeper = (*BaseViewKeeper)(nil) type ViewKeeper interface { GetCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins HasCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) bool - - Codespace() sdk.CodespaceType } // BaseViewKeeper implements a read only keeper implementation of ViewKeeper. type BaseViewKeeper struct { - ak types.AccountKeeper - codespace sdk.CodespaceType + ak types.AccountKeeper } // NewBaseViewKeeper returns a new BaseViewKeeper. -func NewBaseViewKeeper(ak types.AccountKeeper, codespace sdk.CodespaceType) BaseViewKeeper { - return BaseViewKeeper{ak: ak, codespace: codespace} +func NewBaseViewKeeper(ak types.AccountKeeper) BaseViewKeeper { + return BaseViewKeeper{ak: ak} } // Logger returns a module-specific logger. @@ -374,11 +368,6 @@ func (keeper BaseViewKeeper) HasCoins(ctx sdk.Context, addr sdk.AccAddress, amt return keeper.GetCoins(ctx, addr).IsAllGTE(amt) } -// Codespace returns the keeper's codespace. -func (keeper BaseViewKeeper) Codespace() sdk.CodespaceType { - return keeper.codespace -} - // CONTRACT: assumes that amt is valid. func trackDelegation(acc authexported.Account, blockTime time.Time, amt sdk.Coins) error { vacc, ok := acc.(vestexported.VestingAccount) diff --git a/x/bank/internal/keeper/keeper_test.go b/x/bank/internal/keeper/keeper_test.go index ba6c3f56c440..f93ddaa52969 100644 --- a/x/bank/internal/keeper/keeper_test.go +++ b/x/bank/internal/keeper/keeper_test.go @@ -65,8 +65,7 @@ func TestKeeper(t *testing.T) { require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) require.True(t, app.BankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) - err2 := app.BankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50))) - require.Implements(t, (*sdk.Error)(nil), err2) + app.BankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50))) require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) require.True(t, app.BankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) @@ -109,7 +108,7 @@ func TestSendKeeper(t *testing.T) { blacklistedAddrs := make(map[string]bool) paramSpace := app.ParamsKeeper.Subspace("newspace") - sendKeeper := keep.NewBaseSendKeeper(app.AccountKeeper, paramSpace, types.DefaultCodespace, blacklistedAddrs) + sendKeeper := keep.NewBaseSendKeeper(app.AccountKeeper, paramSpace, blacklistedAddrs) app.BankKeeper.SetSendEnabled(ctx, true) addr := sdk.AccAddress([]byte("addr1")) @@ -136,8 +135,7 @@ func TestSendKeeper(t *testing.T) { require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) - err := sendKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50))) - require.Implements(t, (*sdk.Error)(nil), err) + sendKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50))) require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) @@ -149,7 +147,7 @@ func TestSendKeeper(t *testing.T) { // validate coins with invalid denoms or negative values cannot be sent // NOTE: We must use the Coin literal as the constructor does not allow // negative values. - err = sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.Coin{Denom: "FOOCOIN", Amount: sdk.NewInt(-5)}}) + err := sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.Coin{Denom: "FOOCOIN", Amount: sdk.NewInt(-5)}}) require.Error(t, err) } @@ -202,7 +200,7 @@ func TestViewKeeper(t *testing.T) { app, ctx := createTestApp(false) //paramSpace := app.ParamsKeeper.Subspace(types.DefaultParamspace) - viewKeeper := keep.NewBaseViewKeeper(app.AccountKeeper, types.DefaultCodespace) + viewKeeper := keep.NewBaseViewKeeper(app.AccountKeeper) addr := sdk.AccAddress([]byte("addr1")) acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) diff --git a/x/bank/internal/keeper/querier.go b/x/bank/internal/keeper/querier.go index bf303e2930fa..165d01879621 100644 --- a/x/bank/internal/keeper/querier.go +++ b/x/bank/internal/keeper/querier.go @@ -1,12 +1,11 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/bank/internal/types" ) @@ -17,24 +16,24 @@ const ( // NewQuerier returns a new sdk.Keeper instance. func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case QueryBalance: return queryBalance(ctx, req, k) default: - return nil, sdk.ErrUnknownRequest("unknown bank query endpoint") + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) } } } // queryBalance fetch an account's balance for the supplied height. // Height and account address are passed as first and second path components respectively. -func queryBalance(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryBalance(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryBalanceParams if err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms); err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } coins := k.GetCoins(ctx, params.Address) @@ -44,7 +43,7 @@ func queryBalance(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk bz, err := codec.MarshalJSONIndent(types.ModuleCdc, coins) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil diff --git a/x/bank/internal/types/errors.go b/x/bank/internal/types/errors.go index d9c0c7d11d1d..157408c941b7 100644 --- a/x/bank/internal/types/errors.go +++ b/x/bank/internal/types/errors.go @@ -1,33 +1,13 @@ package types import ( - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// Bank errors reserve 100 ~ 199. -const ( - DefaultCodespace sdk.CodespaceType = ModuleName - - CodeSendDisabled sdk.CodeType = 101 - CodeInvalidInputsOutputs sdk.CodeType = 102 +// x/bank module sentinel errors +var ( + ErrNoInputs = sdkerrors.Register(ModuleName, 1, "no inputs to send transaction") + ErrNoOutputs = sdkerrors.Register(ModuleName, 2, "no outputs to send transaction") + ErrInputOutputMismatch = sdkerrors.Register(ModuleName, 3, "sum inputs != sum outputs") + ErrSendDisabled = sdkerrors.Register(ModuleName, 4, "send transactions are disabled") ) - -// ErrNoInputs is an error -func ErrNoInputs(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInputsOutputs, "no inputs to send transaction") -} - -// ErrNoOutputs is an error -func ErrNoOutputs(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInputsOutputs, "no outputs to send transaction") -} - -// ErrInputOutputMismatch is an error -func ErrInputOutputMismatch(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInputsOutputs, "sum inputs != sum outputs") -} - -// ErrSendDisabled is an error -func ErrSendDisabled(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeSendDisabled, "send transactions are currently disabled") -} diff --git a/x/bank/internal/types/msgs.go b/x/bank/internal/types/msgs.go index 58336e24d9e4..c8fdaa5afe92 100644 --- a/x/bank/internal/types/msgs.go +++ b/x/bank/internal/types/msgs.go @@ -2,6 +2,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // RouterKey is they name of the bank module @@ -28,18 +29,18 @@ func (msg MsgSend) Route() string { return RouterKey } func (msg MsgSend) Type() string { return "send" } // ValidateBasic Implements Msg. -func (msg MsgSend) ValidateBasic() sdk.Error { +func (msg MsgSend) ValidateBasic() error { if msg.FromAddress.Empty() { - return sdk.ErrInvalidAddress("missing sender address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") } if msg.ToAddress.Empty() { - return sdk.ErrInvalidAddress("missing recipient address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing recipient address") } if !msg.Amount.IsValid() { - return sdk.ErrInvalidCoins("send amount is invalid: " + msg.Amount.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String()) } if !msg.Amount.IsAllPositive() { - return sdk.ErrInsufficientCoins("send amount must be positive") + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String()) } return nil } @@ -74,14 +75,14 @@ func (msg MsgMultiSend) Route() string { return RouterKey } func (msg MsgMultiSend) Type() string { return "multisend" } // ValidateBasic Implements Msg. -func (msg MsgMultiSend) ValidateBasic() sdk.Error { +func (msg MsgMultiSend) ValidateBasic() error { // this just makes sure all the inputs and outputs are properly formatted, // not that they actually have the money inside if len(msg.Inputs) == 0 { - return ErrNoInputs(DefaultCodespace).TraceSDK("") + return ErrNoInputs } if len(msg.Outputs) == 0 { - return ErrNoOutputs(DefaultCodespace).TraceSDK("") + return ErrNoOutputs } return ValidateInputsOutputs(msg.Inputs, msg.Outputs) @@ -108,15 +109,15 @@ type Input struct { } // ValidateBasic - validate transaction input -func (in Input) ValidateBasic() sdk.Error { +func (in Input) ValidateBasic() error { if len(in.Address) == 0 { - return sdk.ErrInvalidAddress(in.Address.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "input address missing") } if !in.Coins.IsValid() { - return sdk.ErrInvalidCoins(in.Coins.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, in.Coins.String()) } if !in.Coins.IsAllPositive() { - return sdk.ErrInvalidCoins(in.Coins.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, in.Coins.String()) } return nil } @@ -136,15 +137,15 @@ type Output struct { } // ValidateBasic - validate transaction output -func (out Output) ValidateBasic() sdk.Error { +func (out Output) ValidateBasic() error { if len(out.Address) == 0 { - return sdk.ErrInvalidAddress(out.Address.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "output address missing") } if !out.Coins.IsValid() { - return sdk.ErrInvalidCoins(out.Coins.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, out.Coins.String()) } if !out.Coins.IsAllPositive() { - return sdk.ErrInvalidCoins(out.Coins.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, out.Coins.String()) } return nil } @@ -159,26 +160,28 @@ func NewOutput(addr sdk.AccAddress, coins sdk.Coins) Output { // ValidateInputsOutputs validates that each respective input and output is // valid and that the sum of inputs is equal to the sum of outputs. -func ValidateInputsOutputs(inputs []Input, outputs []Output) sdk.Error { +func ValidateInputsOutputs(inputs []Input, outputs []Output) error { var totalIn, totalOut sdk.Coins for _, in := range inputs { if err := in.ValidateBasic(); err != nil { - return err.TraceSDK("") + return err } + totalIn = totalIn.Add(in.Coins) } for _, out := range outputs { if err := out.ValidateBasic(); err != nil { - return err.TraceSDK("") + return err } + totalOut = totalOut.Add(out.Coins) } // make sure inputs and outputs match if !totalIn.IsEqual(totalOut) { - return ErrInputOutputMismatch(DefaultCodespace) + return ErrInputOutputMismatch } return nil diff --git a/x/bank/simulation/operations.go b/x/bank/simulation/operations.go index 71a88386c960..7cf08a8452f2 100644 --- a/x/bank/simulation/operations.go +++ b/x/bank/simulation/operations.go @@ -1,7 +1,6 @@ package simulation import ( - "errors" "math/rand" "github.com/tendermint/tendermint/crypto" @@ -115,9 +114,9 @@ func sendMsgSend( privkeys..., ) - res := app.Deliver(tx) - if !res.IsOK() { - return errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return err } return nil @@ -259,9 +258,9 @@ func sendMsgMultiSend( privkeys..., ) - res := app.Deliver(tx) - if !res.IsOK() { - return errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return err } return nil diff --git a/x/crisis/alias.go b/x/crisis/alias.go index 6c176e265544..1b05371f376b 100644 --- a/x/crisis/alias.go +++ b/x/crisis/alias.go @@ -1,38 +1,30 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/crisis/types package crisis +// nolint + import ( "github.com/cosmos/cosmos-sdk/x/crisis/internal/keeper" "github.com/cosmos/cosmos-sdk/x/crisis/internal/types" ) const ( - DefaultCodespace = types.DefaultCodespace - CodeInvalidInput = types.CodeInvalidInput - ModuleName = types.ModuleName - DefaultParamspace = types.DefaultParamspace - + ModuleName = types.ModuleName + DefaultParamspace = types.DefaultParamspace EventTypeInvariant = types.EventTypeInvariant AttributeValueCrisis = types.AttributeValueCrisis AttributeKeyRoute = types.AttributeKeyRoute ) var ( - // functions aliases - RegisterCodec = types.RegisterCodec - ErrNilSender = types.ErrNilSender - ErrUnknownInvariant = types.ErrUnknownInvariant - NewGenesisState = types.NewGenesisState - DefaultGenesisState = types.DefaultGenesisState - NewMsgVerifyInvariant = types.NewMsgVerifyInvariant - ParamKeyTable = types.ParamKeyTable - NewInvarRoute = types.NewInvarRoute - NewKeeper = keeper.NewKeeper - - // variable aliases + RegisterCodec = types.RegisterCodec + ErrNoSender = types.ErrNoSender + ErrUnknownInvariant = types.ErrUnknownInvariant + NewGenesisState = types.NewGenesisState + DefaultGenesisState = types.DefaultGenesisState + NewMsgVerifyInvariant = types.NewMsgVerifyInvariant + ParamKeyTable = types.ParamKeyTable + NewInvarRoute = types.NewInvarRoute + NewKeeper = keeper.NewKeeper ModuleCdc = types.ModuleCdc ParamStoreKeyConstantFee = types.ParamStoreKeyConstantFee ) diff --git a/x/crisis/client/cli/tx.go b/x/crisis/client/cli/tx.go index cdea9206fbe6..e2df844db639 100644 --- a/x/crisis/client/cli/tx.go +++ b/x/crisis/client/cli/tx.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" @@ -46,7 +47,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - txCmd.AddCommand(client.PostCommands( + txCmd.AddCommand(flags.PostCommands( GetCmdInvariantBroken(cdc), )...) return txCmd diff --git a/x/crisis/handler.go b/x/crisis/handler.go index 9ff52c2f339e..c7e58b6861be 100644 --- a/x/crisis/handler.go +++ b/x/crisis/handler.go @@ -1,9 +1,8 @@ package crisis import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/crisis/internal/keeper" "github.com/cosmos/cosmos-sdk/x/crisis/internal/types" ) @@ -12,7 +11,7 @@ import ( const RouterKey = types.ModuleName func NewHandler(k keeper.Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -20,18 +19,16 @@ func NewHandler(k keeper.Keeper) sdk.Handler { return handleMsgVerifyInvariant(ctx, msg, k) default: - errMsg := fmt.Sprintf("unrecognized crisis message type: %T", msg) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized crisis message type: %T", msg) } } } -func handleMsgVerifyInvariant(ctx sdk.Context, msg types.MsgVerifyInvariant, k keeper.Keeper) sdk.Result { - // remove the constant fee +func handleMsgVerifyInvariant(ctx sdk.Context, msg types.MsgVerifyInvariant, k keeper.Keeper) (*sdk.Result, error) { constantFee := sdk.NewCoins(k.GetConstantFee(ctx)) if err := k.SendCoinsFromAccountToFeeCollector(ctx, msg.Sender, constantFee); err != nil { - return err.Result() + return nil, err } // use a cached context to avoid gas costs during invariants @@ -51,7 +48,7 @@ func handleMsgVerifyInvariant(ctx sdk.Context, msg types.MsgVerifyInvariant, k k } if !found { - return types.ErrUnknownInvariant(types.DefaultCodespace).Result() + return nil, types.ErrUnknownInvariant } if stop { @@ -86,5 +83,5 @@ func handleMsgVerifyInvariant(ctx sdk.Context, msg types.MsgVerifyInvariant, k k ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } diff --git a/x/crisis/handler_test.go b/x/crisis/handler_test.go index 064d6234bc9b..f4c2f8182dbf 100644 --- a/x/crisis/handler_test.go +++ b/x/crisis/handler_test.go @@ -69,14 +69,18 @@ func TestHandleMsgVerifyInvariant(t *testing.T) { switch tc.expectedResult { case "fail": - res := h(ctx, tc.msg) - require.False(t, res.IsOK()) + res, err := h(ctx, tc.msg) + require.Error(t, err) + require.Nil(t, res) + case "pass": - res := h(ctx, tc.msg) - require.True(t, res.IsOK()) + res, err := h(ctx, tc.msg) + require.NoError(t, err) + require.NotNil(t, res) + case "panic": require.Panics(t, func() { - _ = h(ctx, tc.msg) + h(ctx, tc.msg) }) } }) @@ -92,7 +96,10 @@ func TestHandleMsgVerifyInvariantWithNotEnoughSenderCoins(t *testing.T) { h := crisis.NewHandler(app.CrisisKeeper) msg := crisis.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichPasses.Route) - require.False(t, h(ctx, msg).IsOK()) + + res, err := h(ctx, msg) + require.Error(t, err) + require.Nil(t, res) } func TestHandleMsgVerifyInvariantWithInvariantBrokenAndNotEnoughPoolCoins(t *testing.T) { @@ -106,8 +113,9 @@ func TestHandleMsgVerifyInvariantWithInvariantBrokenAndNotEnoughPoolCoins(t *tes h := crisis.NewHandler(app.CrisisKeeper) msg := crisis.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichFails.Route) - var res sdk.Result + + var res *sdk.Result require.Panics(t, func() { - res = h(ctx, msg) + res, _ = h(ctx, msg) }, fmt.Sprintf("%v", res)) } diff --git a/x/crisis/internal/keeper/keeper.go b/x/crisis/internal/keeper/keeper.go index cb6f9a6548d8..f4c8163bb740 100644 --- a/x/crisis/internal/keeper/keeper.go +++ b/x/crisis/internal/keeper/keeper.go @@ -90,6 +90,6 @@ func (k Keeper) AssertInvariants(ctx sdk.Context) { func (k Keeper) InvCheckPeriod() uint { return k.invCheckPeriod } // SendCoinsFromAccountToFeeCollector transfers amt to the fee collector account. -func (k Keeper) SendCoinsFromAccountToFeeCollector(ctx sdk.Context, senderAddr sdk.AccAddress, amt sdk.Coins) sdk.Error { +func (k Keeper) SendCoinsFromAccountToFeeCollector(ctx sdk.Context, senderAddr sdk.AccAddress, amt sdk.Coins) error { return k.supplyKeeper.SendCoinsFromAccountToModule(ctx, senderAddr, k.feeCollectorName, amt) } diff --git a/x/crisis/internal/types/errors.go b/x/crisis/internal/types/errors.go index 3b7392abfae6..ac63f3ff43de 100644 --- a/x/crisis/internal/types/errors.go +++ b/x/crisis/internal/types/errors.go @@ -1,23 +1,11 @@ package types import ( - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -const ( - // default codespace for crisis module - DefaultCodespace sdk.CodespaceType = ModuleName - - // CodeInvalidInput is the codetype for invalid input for the crisis module - CodeInvalidInput sdk.CodeType = 103 +// x/crisis module sentinel errors +var ( + ErrNoSender = sdkerrors.Register(ModuleName, 1, "sender address is empty") + ErrUnknownInvariant = sdkerrors.Register(ModuleName, 2, "unknown invariant") ) - -// ErrNilSender - no sender provided for the input -func ErrNilSender(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "sender address is nil") -} - -// ErrUnknownInvariant - unknown invariant provided -func ErrUnknownInvariant(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "unknown invariant") -} diff --git a/x/crisis/internal/types/expected_keepers.go b/x/crisis/internal/types/expected_keepers.go index 5690c0c38688..3cd0e9e7f57a 100644 --- a/x/crisis/internal/types/expected_keepers.go +++ b/x/crisis/internal/types/expected_keepers.go @@ -6,5 +6,5 @@ import ( // SupplyKeeper defines the expected supply keeper (noalias) type SupplyKeeper interface { - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error } diff --git a/x/crisis/internal/types/msgs.go b/x/crisis/internal/types/msgs.go index e16ffb528e0c..f496df636b60 100644 --- a/x/crisis/internal/types/msgs.go +++ b/x/crisis/internal/types/msgs.go @@ -39,9 +39,9 @@ func (msg MsgVerifyInvariant) GetSignBytes() []byte { } // quick validity check -func (msg MsgVerifyInvariant) ValidateBasic() sdk.Error { +func (msg MsgVerifyInvariant) ValidateBasic() error { if msg.Sender.Empty() { - return ErrNilSender(DefaultCodespace) + return ErrNoSender } return nil } diff --git a/x/distribution/alias.go b/x/distribution/alias.go index de6f269e6a1c..ff181d7331e3 100644 --- a/x/distribution/alias.go +++ b/x/distribution/alias.go @@ -10,11 +10,6 @@ import ( const ( DefaultParamspace = keeper.DefaultParamspace - DefaultCodespace = types.DefaultCodespace - CodeInvalidInput = types.CodeInvalidInput - CodeNoDistributionInfo = types.CodeNoDistributionInfo - CodeNoValidatorCommission = types.CodeNoValidatorCommission - CodeSetWithdrawAddrDisabled = types.CodeSetWithdrawAddrDisabled ModuleName = types.ModuleName StoreKey = types.StoreKey RouterKey = types.RouterKey @@ -70,11 +65,13 @@ var ( CreateTestInputAdvanced = keeper.CreateTestInputAdvanced RegisterCodec = types.RegisterCodec NewDelegatorStartingInfo = types.NewDelegatorStartingInfo - ErrNilDelegatorAddr = types.ErrNilDelegatorAddr - ErrNilWithdrawAddr = types.ErrNilWithdrawAddr - ErrNilValidatorAddr = types.ErrNilValidatorAddr - ErrNoDelegationDistInfo = types.ErrNoDelegationDistInfo + ErrEmptyDelegatorAddr = types.ErrEmptyDelegatorAddr + ErrEmptyWithdrawAddr = types.ErrEmptyWithdrawAddr + ErrEmptyValidatorAddr = types.ErrEmptyValidatorAddr + ErrEmptyDelegationDistInfo = types.ErrEmptyDelegationDistInfo ErrNoValidatorDistInfo = types.ErrNoValidatorDistInfo + ErrNoValidatorExists = types.ErrNoValidatorExists + ErrNoDelegationExists = types.ErrNoDelegationExists ErrNoValidatorCommission = types.ErrNoValidatorCommission ErrSetWithdrawAddrDisabled = types.ErrSetWithdrawAddrDisabled ErrBadDistribution = types.ErrBadDistribution @@ -134,7 +131,6 @@ type ( Hooks = keeper.Hooks Keeper = keeper.Keeper DelegatorStartingInfo = types.DelegatorStartingInfo - CodeType = types.CodeType FeePool = types.FeePool DelegatorWithdrawInfo = types.DelegatorWithdrawInfo ValidatorOutstandingRewardsRecord = types.ValidatorOutstandingRewardsRecord diff --git a/x/distribution/client/cli/query.go b/x/distribution/client/cli/query.go index 36d12e57fb1d..dff8e5e06a5d 100644 --- a/x/distribution/client/cli/query.go +++ b/x/distribution/client/cli/query.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -26,7 +27,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - distQueryCmd.AddCommand(client.GetCommands( + distQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryParams(queryRoute, cdc), GetCmdQueryValidatorOutstandingRewards(queryRoute, cdc), GetCmdQueryValidatorCommission(queryRoute, cdc), @@ -66,7 +67,7 @@ func GetCmdQueryValidatorOutstandingRewards(queryRoute string, cdc *codec.Codec) for a validator and all their delegations. Example: -$ %s query distr validator-outstanding-rewards cosmosvaloper1lwjmdnks33xwnmfayc64ycprww49n33mtm92ne +$ %s query distribution validator-outstanding-rewards cosmosvaloper1lwjmdnks33xwnmfayc64ycprww49n33mtm92ne `, version.ClientName, ), @@ -113,7 +114,7 @@ func GetCmdQueryValidatorCommission(queryRoute string, cdc *codec.Codec) *cobra. fmt.Sprintf(`Query validator commission rewards from delegators to that validator. Example: -$ %s query distr commission cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj +$ %s query distribution commission cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj `, version.ClientName, ), @@ -148,7 +149,7 @@ func GetCmdQueryValidatorSlashes(queryRoute string, cdc *codec.Codec) *cobra.Com fmt.Sprintf(`Query all slashes of a validator for a given block range. Example: -$ %s query distr slashes cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 0 100 +$ %s query distribution slashes cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 0 100 `, version.ClientName, ), @@ -199,8 +200,8 @@ func GetCmdQueryDelegatorRewards(queryRoute string, cdc *codec.Codec) *cobra.Com fmt.Sprintf(`Query all rewards earned by a delegator, optionally restrict to rewards from a single validator. Example: -$ %s query distr rewards cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p -$ %s query distr rewards cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj +$ %s query distribution rewards cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p +$ %s query distribution rewards cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj `, version.ClientName, version.ClientName, ), @@ -243,7 +244,7 @@ func GetCmdQueryCommunityPool(queryRoute string, cdc *codec.Codec) *cobra.Comman fmt.Sprintf(`Query all coins in the community pool which is under Governance control. Example: -$ %s query distr community-pool +$ %s query distribution community-pool `, version.ClientName, ), diff --git a/x/distribution/client/cli/tx.go b/x/distribution/client/cli/tx.go index 29d0c17fc263..6eaee60992b6 100644 --- a/x/distribution/client/cli/tx.go +++ b/x/distribution/client/cli/tx.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -43,7 +44,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - distTxCmd.AddCommand(client.PostCommands( + distTxCmd.AddCommand(flags.PostCommands( GetCmdWithdrawRewards(cdc), GetCmdSetWithdrawAddr(cdc), GetCmdWithdrawAllRewards(cdc, storeKey), @@ -95,8 +96,8 @@ func GetCmdWithdrawRewards(cdc *codec.Codec) *cobra.Command { and optionally withdraw validator commission if the delegation address given is a validator operator. Example: -$ %s tx distr withdraw-rewards cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --from mykey -$ %s tx distr withdraw-rewards cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --from mykey --commission +$ %s tx distribution withdraw-rewards cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --from mykey +$ %s tx distribution withdraw-rewards cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --from mykey --commission `, version.ClientName, version.ClientName, ), @@ -134,7 +135,7 @@ func GetCmdWithdrawAllRewards(cdc *codec.Codec, queryRoute string) *cobra.Comman fmt.Sprintf(`Withdraw all rewards for a single delegator. Example: -$ %s tx distr withdraw-all-rewards --from mykey +$ %s tx distribution withdraw-all-rewards --from mykey `, version.ClientName, ), @@ -150,7 +151,7 @@ $ %s tx distr withdraw-all-rewards --from mykey // The transaction cannot be generated offline since it requires a query // to get all the validators. if cliCtx.GenerateOnly { - return fmt.Errorf("command disabled with the provided flag: %s", client.FlagGenerateOnly) + return fmt.Errorf("command disabled with the provided flag: %s", flags.FlagGenerateOnly) } msgs, err := common.WithdrawAllDelegatorRewards(cliCtx, queryRoute, delAddr) @@ -176,7 +177,7 @@ func GetCmdSetWithdrawAddr(cdc *codec.Codec) *cobra.Command { fmt.Sprintf(`Set the withdraw address for rewards associated with a delegator address. Example: -$ %s tx set-withdraw-addr cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p --from mykey +$ %s tx distribution set-withdraw-addr cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p --from mykey `, version.ClientName, ), @@ -272,7 +273,7 @@ func GetCmdFundCommunityPool(cdc *codec.Codec) *cobra.Command { fmt.Sprintf(`Funds the community pool with the specified amount Example: -$ %s tx fund-community-pool 100uatom --from mykey +$ %s tx distribution fund-community-pool 100uatom --from mykey `, version.ClientName, ), diff --git a/x/distribution/handler.go b/x/distribution/handler.go index 90c4bc14de93..642b9e0d89a1 100644 --- a/x/distribution/handler.go +++ b/x/distribution/handler.go @@ -1,16 +1,15 @@ package distribution import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/distribution/keeper" "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) func NewHandler(k keeper.Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -27,18 +26,17 @@ func NewHandler(k keeper.Keeper) sdk.Handler { return handleMsgFundCommunityPool(ctx, msg, k) default: - errMsg := fmt.Sprintf("unrecognized distribution message type: %T", msg) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized distribution message type: %T", msg) } } } // These functions assume everything has been authenticated (ValidateBasic passed, and signatures checked) -func handleMsgModifyWithdrawAddress(ctx sdk.Context, msg types.MsgSetWithdrawAddress, k keeper.Keeper) sdk.Result { +func handleMsgModifyWithdrawAddress(ctx sdk.Context, msg types.MsgSetWithdrawAddress, k keeper.Keeper) (*sdk.Result, error) { err := k.SetWithdrawAddr(ctx, msg.DelegatorAddress, msg.WithdrawAddress) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -49,13 +47,13 @@ func handleMsgModifyWithdrawAddress(ctx sdk.Context, msg types.MsgSetWithdrawAdd ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } -func handleMsgWithdrawDelegatorReward(ctx sdk.Context, msg types.MsgWithdrawDelegatorReward, k keeper.Keeper) sdk.Result { +func handleMsgWithdrawDelegatorReward(ctx sdk.Context, msg types.MsgWithdrawDelegatorReward, k keeper.Keeper) (*sdk.Result, error) { _, err := k.WithdrawDelegationRewards(ctx, msg.DelegatorAddress, msg.ValidatorAddress) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -66,13 +64,13 @@ func handleMsgWithdrawDelegatorReward(ctx sdk.Context, msg types.MsgWithdrawDele ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } -func handleMsgWithdrawValidatorCommission(ctx sdk.Context, msg types.MsgWithdrawValidatorCommission, k keeper.Keeper) sdk.Result { +func handleMsgWithdrawValidatorCommission(ctx sdk.Context, msg types.MsgWithdrawValidatorCommission, k keeper.Keeper) (*sdk.Result, error) { _, err := k.WithdrawValidatorCommission(ctx, msg.ValidatorAddress) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -83,12 +81,12 @@ func handleMsgWithdrawValidatorCommission(ctx sdk.Context, msg types.MsgWithdraw ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } -func handleMsgFundCommunityPool(ctx sdk.Context, msg types.MsgFundCommunityPool, k keeper.Keeper) sdk.Result { +func handleMsgFundCommunityPool(ctx sdk.Context, msg types.MsgFundCommunityPool, k keeper.Keeper) (*sdk.Result, error) { if err := k.FundCommunityPool(ctx, msg.Amount, msg.Depositor); err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvent( @@ -99,18 +97,17 @@ func handleMsgFundCommunityPool(ctx sdk.Context, msg types.MsgFundCommunityPool, ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } func NewCommunityPoolSpendProposalHandler(k Keeper) govtypes.Handler { - return func(ctx sdk.Context, content govtypes.Content) sdk.Error { + return func(ctx sdk.Context, content govtypes.Content) error { switch c := content.(type) { case types.CommunityPoolSpendProposal: return keeper.HandleCommunityPoolSpendProposal(ctx, k, c) default: - errMsg := fmt.Sprintf("unrecognized distr proposal content type: %T", c) - return sdk.ErrUnknownRequest(errMsg) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized distr proposal content type: %T", c) } } } diff --git a/x/distribution/keeper/allocation_test.go b/x/distribution/keeper/allocation_test.go index 8f1b84c5f35c..83821ea3820d 100644 --- a/x/distribution/keeper/allocation_test.go +++ b/x/distribution/keeper/allocation_test.go @@ -16,9 +16,15 @@ func TestAllocateTokensToValidatorWithCommission(t *testing.T) { // create validator with 50% commission commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, - sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + msg := staking.NewMsgCreateValidator( + valOpAddr1, valConsPk1, + sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt(), + ) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) + val := sk.Validator(ctx, valOpAddr1) // allocate tokens @@ -45,13 +51,19 @@ func TestAllocateTokensToManyValidators(t *testing.T) { commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // create second validator with 0% commission commission = staking.NewCommissionRates(sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0)) msg = staking.NewMsgCreateValidator(valOpAddr2, valConsPk2, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + + res, err = sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) abciValA := abci.Validator{ Address: valConsPk1.Address(), @@ -76,7 +88,7 @@ func TestAllocateTokensToManyValidators(t *testing.T) { feeCollector := supplyKeeper.GetModuleAccount(ctx, k.feeCollectorName) require.NotNil(t, feeCollector) - err := feeCollector.SetCoins(fees) + err = feeCollector.SetCoins(fees) require.NoError(t, err) ak.SetAccount(ctx, feeCollector) @@ -116,19 +128,25 @@ func TestAllocateTokensTruncation(t *testing.T) { commission := staking.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(110)), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // create second validator with 10% commission commission = staking.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) msg = staking.NewMsgCreateValidator(valOpAddr2, valConsPk2, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + res, err = sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // create third validator with 10% commission commission = staking.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) msg = staking.NewMsgCreateValidator(valOpAddr3, valConsPk3, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + res, err = sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) abciValA := abci.Validator{ Address: valConsPk1.Address(), @@ -159,7 +177,7 @@ func TestAllocateTokensTruncation(t *testing.T) { feeCollector := supplyKeeper.GetModuleAccount(ctx, k.feeCollectorName) require.NotNil(t, feeCollector) - err := feeCollector.SetCoins(fees) + err = feeCollector.SetCoins(fees) require.NoError(t, err) ak.SetAccount(ctx, feeCollector) diff --git a/x/distribution/keeper/delegation.go b/x/distribution/keeper/delegation.go index 4044c4d1961a..7b28b6048eaf 100644 --- a/x/distribution/keeper/delegation.go +++ b/x/distribution/keeper/delegation.go @@ -136,10 +136,10 @@ func (k Keeper) calculateDelegationRewards(ctx sdk.Context, val exported.Validat return rewards } -func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val exported.ValidatorI, del exported.DelegationI) (sdk.Coins, sdk.Error) { +func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val exported.ValidatorI, del exported.DelegationI) (sdk.Coins, error) { // check existence of delegator starting info if !k.HasDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) { - return nil, types.ErrNoDelegationDistInfo(k.codespace) + return nil, types.ErrEmptyDelegationDistInfo } // end current period and calculate rewards diff --git a/x/distribution/keeper/delegation_test.go b/x/distribution/keeper/delegation_test.go index db6f6fb434ea..6d23ad958991 100644 --- a/x/distribution/keeper/delegation_test.go +++ b/x/distribution/keeper/delegation_test.go @@ -15,9 +15,13 @@ func TestCalculateRewardsBasic(t *testing.T) { // create validator with 50% commission commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, - sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + msg := staking.NewMsgCreateValidator( + valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt(), + ) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond validator staking.EndBlocker(ctx, sk) @@ -72,8 +76,10 @@ func TestCalculateRewardsAfterSlash(t *testing.T) { valTokens := sdk.TokensFromConsensusPower(valPower) msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, valTokens), staking.Description{}, commission, sdk.OneInt()) - got := sh(ctx, msg) - require.True(t, got.IsOK(), "%v", got) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond validator staking.EndBlocker(ctx, sk) @@ -135,7 +141,10 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) { commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, valTokens), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond validator staking.EndBlocker(ctx, sk) @@ -207,7 +216,10 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) { commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond validator staking.EndBlocker(ctx, sk) @@ -226,7 +238,11 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) { // second delegation msg2 := staking.NewMsgDelegate(sdk.AccAddress(valOpAddr2), valOpAddr1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) - require.True(t, sh(ctx, msg2).IsOK()) + + res, err = sh(ctx, msg2) + require.NoError(t, err) + require.NotNil(t, res) + del2 := sk.Delegation(ctx, sdk.AccAddress(valOpAddr2), valOpAddr1) // fetch updated validator @@ -280,7 +296,10 @@ func TestWithdrawDelegationRewardsBasic(t *testing.T) { sdk.NewCoin(sdk.DefaultBondDenom, valTokens), staking.Description{}, commission, sdk.OneInt(), ) - require.True(t, sh(ctx, msg).IsOK()) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // assert correct initial balance expTokens := balanceTokens.Sub(valTokens) @@ -308,7 +327,7 @@ func TestWithdrawDelegationRewardsBasic(t *testing.T) { require.Equal(t, uint64(2), k.GetValidatorHistoricalReferenceCount(ctx)) // withdraw rewards - _, err := k.WithdrawDelegationRewards(ctx, sdk.AccAddress(valOpAddr1), valOpAddr1) + _, err = k.WithdrawDelegationRewards(ctx, sdk.AccAddress(valOpAddr1), valOpAddr1) require.Nil(t, err) // historical count should still be 2 (added one record, cleared one) @@ -343,7 +362,10 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) { commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, valTokens), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond validator staking.EndBlocker(ctx, sk) @@ -410,7 +432,10 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) { valTokens := sdk.TokensFromConsensusPower(power) msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, valTokens), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond validator staking.EndBlocker(ctx, sk) @@ -436,7 +461,11 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) { delTokens := sdk.TokensFromConsensusPower(100) msg2 := staking.NewMsgDelegate(sdk.AccAddress(valOpAddr2), valOpAddr1, sdk.NewCoin(sdk.DefaultBondDenom, delTokens)) - require.True(t, sh(ctx, msg2).IsOK()) + + res, err = sh(ctx, msg2) + require.NoError(t, err) + require.NotNil(t, res) + del2 := sk.Delegation(ctx, sdk.AccAddress(valOpAddr2), valOpAddr1) // end block @@ -491,7 +520,10 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond validator staking.EndBlocker(ctx, sk) @@ -511,7 +543,9 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { // second delegation msg2 := staking.NewMsgDelegate(sdk.AccAddress(valOpAddr2), valOpAddr1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) - require.True(t, sh(ctx, msg2).IsOK()) + res, err = sh(ctx, msg2) + require.NoError(t, err) + require.NotNil(t, res) // historical count should be 3 (second delegation init) require.Equal(t, uint64(3), k.GetValidatorHistoricalReferenceCount(ctx)) diff --git a/x/distribution/keeper/fee_pool.go b/x/distribution/keeper/fee_pool.go index a16e8258c029..34ad5f0d0d06 100644 --- a/x/distribution/keeper/fee_pool.go +++ b/x/distribution/keeper/fee_pool.go @@ -7,7 +7,7 @@ import ( // DistributeFromFeePool distributes funds from the distribution module account to // a receiver address while updating the community pool -func (k Keeper) DistributeFromFeePool(ctx sdk.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) sdk.Error { +func (k Keeper) DistributeFromFeePool(ctx sdk.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error { feePool := k.GetFeePool(ctx) // NOTE the community pool isn't a module account, however its coins @@ -15,8 +15,9 @@ func (k Keeper) DistributeFromFeePool(ctx sdk.Context, amount sdk.Coins, receive // must be reduced separately from the SendCoinsFromModuleToAccount call newPool, negative := feePool.CommunityPool.SafeSub(sdk.NewDecCoins(amount)) if negative { - return types.ErrBadDistribution(k.codespace) + return types.ErrBadDistribution } + feePool.CommunityPool = newPool err := k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, receiveAddr, amount) diff --git a/x/distribution/keeper/keeper.go b/x/distribution/keeper/keeper.go index 6aca0d86fa10..76b582bae209 100644 --- a/x/distribution/keeper/keeper.go +++ b/x/distribution/keeper/keeper.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/params" @@ -19,17 +20,17 @@ type Keeper struct { stakingKeeper types.StakingKeeper supplyKeeper types.SupplyKeeper - codespace sdk.CodespaceType - blacklistedAddrs map[string]bool feeCollectorName string // name of the FeeCollector ModuleAccount } // NewKeeper creates a new distribution Keeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, paramSpace params.Subspace, - sk types.StakingKeeper, supplyKeeper types.SupplyKeeper, codespace sdk.CodespaceType, - feeCollectorName string, blacklistedAddrs map[string]bool) Keeper { +func NewKeeper( + cdc *codec.Codec, key sdk.StoreKey, paramSpace params.Subspace, + sk types.StakingKeeper, supplyKeeper types.SupplyKeeper, feeCollectorName string, + blacklistedAddrs map[string]bool, +) Keeper { // ensure distribution module account is set if addr := supplyKeeper.GetModuleAddress(types.ModuleName); addr == nil { @@ -42,7 +43,6 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, paramSpace params.Subspace, paramSpace: paramSpace.WithKeyTable(ParamKeyTable()), stakingKeeper: sk, supplyKeeper: supplyKeeper, - codespace: codespace, feeCollectorName: feeCollectorName, blacklistedAddrs: blacklistedAddrs, } @@ -54,13 +54,13 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { } // SetWithdrawAddr sets a new address that will receive the rewards upon withdrawal -func (k Keeper) SetWithdrawAddr(ctx sdk.Context, delegatorAddr sdk.AccAddress, withdrawAddr sdk.AccAddress) sdk.Error { +func (k Keeper) SetWithdrawAddr(ctx sdk.Context, delegatorAddr sdk.AccAddress, withdrawAddr sdk.AccAddress) error { if k.blacklistedAddrs[withdrawAddr.String()] { - return sdk.ErrUnauthorized(fmt.Sprintf("%s is blacklisted from receiving external funds", withdrawAddr)) + return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is blacklisted from receiving external funds", withdrawAddr) } if !k.GetWithdrawAddrEnabled(ctx) { - return types.ErrSetWithdrawAddrDisabled(k.codespace) + return types.ErrSetWithdrawAddrDisabled } ctx.EventManager().EmitEvent( @@ -75,15 +75,15 @@ func (k Keeper) SetWithdrawAddr(ctx sdk.Context, delegatorAddr sdk.AccAddress, w } // withdraw rewards from a delegation -func (k Keeper) WithdrawDelegationRewards(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (sdk.Coins, sdk.Error) { +func (k Keeper) WithdrawDelegationRewards(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (sdk.Coins, error) { val := k.stakingKeeper.Validator(ctx, valAddr) if val == nil { - return nil, types.ErrNoValidatorDistInfo(k.codespace) + return nil, types.ErrNoValidatorDistInfo } del := k.stakingKeeper.Delegation(ctx, delAddr, valAddr) if del == nil { - return nil, types.ErrNoDelegationDistInfo(k.codespace) + return nil, types.ErrEmptyDelegationDistInfo } // withdraw rewards @@ -106,11 +106,11 @@ func (k Keeper) WithdrawDelegationRewards(ctx sdk.Context, delAddr sdk.AccAddres } // withdraw validator commission -func (k Keeper) WithdrawValidatorCommission(ctx sdk.Context, valAddr sdk.ValAddress) (sdk.Coins, sdk.Error) { +func (k Keeper) WithdrawValidatorCommission(ctx sdk.Context, valAddr sdk.ValAddress) (sdk.Coins, error) { // fetch validator accumulated commission accumCommission := k.GetValidatorAccumulatedCommission(ctx, valAddr) if accumCommission.IsZero() { - return nil, types.ErrNoValidatorCommission(k.codespace) + return nil, types.ErrNoValidatorCommission } commission, remainder := accumCommission.TruncateDecimal() @@ -147,6 +147,7 @@ func (k Keeper) GetTotalRewards(ctx sdk.Context) (totalRewards sdk.DecCoins) { return false }, ) + return totalRewards } diff --git a/x/distribution/keeper/proposal_handler.go b/x/distribution/keeper/proposal_handler.go index 2daf2245ed76..f60a3f88154d 100644 --- a/x/distribution/keeper/proposal_handler.go +++ b/x/distribution/keeper/proposal_handler.go @@ -4,13 +4,14 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/distribution/types" ) // HandleCommunityPoolSpendProposal is a handler for executing a passed community spend proposal -func HandleCommunityPoolSpendProposal(ctx sdk.Context, k Keeper, p types.CommunityPoolSpendProposal) sdk.Error { +func HandleCommunityPoolSpendProposal(ctx sdk.Context, k Keeper, p types.CommunityPoolSpendProposal) error { if k.blacklistedAddrs[p.Recipient.String()] { - return sdk.ErrUnauthorized(fmt.Sprintf("%s is blacklisted from receiving external funds", p.Recipient)) + return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is blacklisted from receiving external funds", p.Recipient) } err := k.DistributeFromFeePool(ctx, p.Amount, p.Recipient) diff --git a/x/distribution/keeper/querier.go b/x/distribution/keeper/querier.go index a057340340db..7e7c404cee14 100644 --- a/x/distribution/keeper/querier.go +++ b/x/distribution/keeper/querier.go @@ -2,18 +2,18 @@ package keeper import ( "encoding/json" - "fmt" abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/staking/exported" ) func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryParams: return queryParams(ctx, path[1:], req, k) @@ -43,82 +43,93 @@ func NewQuerier(k Keeper) sdk.Querier { return queryCommunityPool(ctx, path[1:], req, k) default: - return nil, sdk.ErrUnknownRequest("unknown distr query endpoint") + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) } } } -func queryParams(ctx sdk.Context, path []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryParams(ctx sdk.Context, path []string, req abci.RequestQuery, k Keeper) ([]byte, error) { switch path[0] { case types.ParamCommunityTax: bz, err := codec.MarshalJSONIndent(k.cdc, k.GetCommunityTax(ctx)) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil + case types.ParamBaseProposerReward: bz, err := codec.MarshalJSONIndent(k.cdc, k.GetBaseProposerReward(ctx)) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil + case types.ParamBonusProposerReward: bz, err := codec.MarshalJSONIndent(k.cdc, k.GetBonusProposerReward(ctx)) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil + case types.ParamWithdrawAddrEnabled: bz, err := codec.MarshalJSONIndent(k.cdc, k.GetWithdrawAddrEnabled(ctx)) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil + default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("%s is not a valid query request path", req.Path)) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "%s is not a valid query request path", req.Path) } } -func queryValidatorOutstandingRewards(ctx sdk.Context, path []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryValidatorOutstandingRewards(ctx sdk.Context, path []string, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryValidatorOutstandingRewardsParams err := k.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } + rewards := k.GetValidatorOutstandingRewards(ctx, params.ValidatorAddress) if rewards == nil { rewards = sdk.DecCoins{} } + bz, err := codec.MarshalJSONIndent(k.cdc, rewards) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } -func queryValidatorCommission(ctx sdk.Context, path []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryValidatorCommission(ctx sdk.Context, path []string, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryValidatorCommissionParams err := k.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } + commission := k.GetValidatorAccumulatedCommission(ctx, params.ValidatorAddress) if commission == nil { commission = sdk.DecCoins{} } + bz, err := codec.MarshalJSONIndent(k.cdc, commission) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } -func queryValidatorSlashes(ctx sdk.Context, path []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryValidatorSlashes(ctx sdk.Context, path []string, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryValidatorSlashesParams err := k.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } + events := make([]types.ValidatorSlashEvent, 0) k.IterateValidatorSlashEventsBetween(ctx, params.ValidatorAddress, params.StartingHeight, params.EndingHeight, func(height uint64, event types.ValidatorSlashEvent) (stop bool) { @@ -126,18 +137,20 @@ func queryValidatorSlashes(ctx sdk.Context, path []string, req abci.RequestQuery return false }, ) + bz, err := codec.MarshalJSONIndent(k.cdc, events) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } -func queryDelegationRewards(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryDelegationRewards(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryDelegationRewardsParams err := k.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } // cache-wrap context as to not persist state changes during querying @@ -145,14 +158,12 @@ func queryDelegationRewards(ctx sdk.Context, _ []string, req abci.RequestQuery, val := k.stakingKeeper.Validator(ctx, params.ValidatorAddress) if val == nil { - // TODO: Should use ErrNoValidatorFound from staking/types - return nil, sdk.ErrInternal(fmt.Sprintf("validator %s does not exist", params.ValidatorAddress)) + return nil, sdkerrors.Wrap(types.ErrNoValidatorExists, params.ValidatorAddress.String()) } del := k.stakingKeeper.Delegation(ctx, params.DelegatorAddress, params.ValidatorAddress) if del == nil { - // TODO: Should use ErrNoDelegation from staking/types - return nil, sdk.ErrInternal("delegation does not exist") + return nil, types.ErrNoDelegationExists } endingPeriod := k.incrementValidatorPeriod(ctx, val) @@ -163,17 +174,17 @@ func queryDelegationRewards(ctx sdk.Context, _ []string, req abci.RequestQuery, bz, err := codec.MarshalJSONIndent(k.cdc, rewards) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } -func queryDelegatorTotalRewards(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryDelegatorTotalRewards(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryDelegatorParams err := k.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } // cache-wrap context as to not persist state changes during querying @@ -192,24 +203,26 @@ func queryDelegatorTotalRewards(ctx sdk.Context, _ []string, req abci.RequestQue delRewards = append(delRewards, types.NewDelegationDelegatorReward(valAddr, delReward)) total = total.Add(delReward) + return false }, ) totalRewards := types.NewQueryDelegatorTotalRewardsResponse(delRewards, total) + bz, err := json.Marshal(totalRewards) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } -func queryDelegatorValidators(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryDelegatorValidators(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryDelegatorParams err := k.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } // cache-wrap context as to not persist state changes during querying @@ -227,16 +240,17 @@ func queryDelegatorValidators(ctx sdk.Context, _ []string, req abci.RequestQuery bz, err := codec.MarshalJSONIndent(k.cdc, validators) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } -func queryDelegatorWithdrawAddress(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryDelegatorWithdrawAddress(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryDelegatorWithdrawAddrParams err := k.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } // cache-wrap context as to not persist state changes during querying @@ -245,20 +259,22 @@ func queryDelegatorWithdrawAddress(ctx sdk.Context, _ []string, req abci.Request bz, err := codec.MarshalJSONIndent(k.cdc, withdrawAddr) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } -func queryCommunityPool(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryCommunityPool(ctx sdk.Context, _ []string, req abci.RequestQuery, k Keeper) ([]byte, error) { pool := k.GetFeePoolCommunityCoins(ctx) if pool == nil { pool = sdk.DecCoins{} } + bz, err := k.cdc.MarshalJSON(pool) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } diff --git a/x/distribution/keeper/querier_test.go b/x/distribution/keeper/querier_test.go index 2a2d1455f9db..e70ca2ea0f4b 100644 --- a/x/distribution/keeper/querier_test.go +++ b/x/distribution/keeper/querier_test.go @@ -189,10 +189,16 @@ func TestQueries(t *testing.T) { // test delegation rewards query sh := staking.NewHandler(sk) comm := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, - sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, comm, sdk.OneInt()) - require.True(t, sh(ctx, msg).IsOK()) + msg := staking.NewMsgCreateValidator( + valOpAddr1, valConsPk1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, comm, sdk.OneInt(), + ) + + res, err := sh(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) + staking.EndBlocker(ctx, sk) + val := sk.Validator(ctx, valOpAddr1) rewards := getQueriedDelegationRewards(t, ctx, cdc, querier, sdk.AccAddress(valOpAddr1), valOpAddr1) require.True(t, rewards.IsZero()) diff --git a/x/distribution/keeper/test_common.go b/x/distribution/keeper/test_common.go index 73c709e317e1..1d53c9d1816a 100644 --- a/x/distribution/keeper/test_common.go +++ b/x/distribution/keeper/test_common.go @@ -119,11 +119,11 @@ func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initPower int64, blacklistedAddrs[distrAcc.GetAddress().String()] = true cdc := MakeTestCodec() - pk := params.NewKeeper(cdc, keyParams, tkeyParams, params.DefaultCodespace) + pk := params.NewKeeper(cdc, keyParams, tkeyParams) ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger()) accountKeeper := auth.NewAccountKeeper(cdc, keyAcc, pk.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount) - bankKeeper := bank.NewBaseKeeper(accountKeeper, pk.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs) + bankKeeper := bank.NewBaseKeeper(accountKeeper, pk.Subspace(bank.DefaultParamspace), blacklistedAddrs) maccPerms := map[string][]string{ auth.FeeCollectorName: nil, types.ModuleName: nil, @@ -132,10 +132,10 @@ func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initPower int64, } supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bankKeeper, maccPerms) - sk := staking.NewKeeper(cdc, keyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace), staking.DefaultCodespace) + sk := staking.NewKeeper(cdc, keyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace)) sk.SetParams(ctx, staking.DefaultParams()) - keeper := NewKeeper(cdc, keyDistr, pk.Subspace(DefaultParamspace), sk, supplyKeeper, types.DefaultCodespace, auth.FeeCollectorName, blacklistedAddrs) + keeper := NewKeeper(cdc, keyDistr, pk.Subspace(DefaultParamspace), sk, supplyKeeper, auth.FeeCollectorName, blacklistedAddrs) initCoins := sdk.NewCoins(sdk.NewCoin(sk.BondDenom(ctx), initTokens)) totalSupply := sdk.NewCoins(sdk.NewCoin(sk.BondDenom(ctx), initTokens.MulRaw(int64(len(TestAddrs))))) diff --git a/x/distribution/simulation/operations.go b/x/distribution/simulation/operations.go index 9a9dea6b8d4b..d2857e6c5aff 100644 --- a/x/distribution/simulation/operations.go +++ b/x/distribution/simulation/operations.go @@ -1,7 +1,6 @@ package simulation import ( - "errors" "fmt" "math/rand" @@ -109,9 +108,9 @@ func SimulateMsgSetWithdrawAddress(ak types.AccountKeeper, k keeper.Keeper) simu simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil @@ -155,9 +154,9 @@ func SimulateMsgWithdrawDelegatorReward(ak types.AccountKeeper, k keeper.Keeper, simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil @@ -204,9 +203,9 @@ func SimulateMsgWithdrawValidatorCommission(ak types.AccountKeeper, k keeper.Kee simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil @@ -254,9 +253,9 @@ func SimulateMsgFundCommunityPool(ak types.AccountKeeper, k keeper.Keeper, sk st funder.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil diff --git a/x/distribution/types/errors.go b/x/distribution/types/errors.go index 2b6394114133..c06b731b6ee4 100644 --- a/x/distribution/types/errors.go +++ b/x/distribution/types/errors.go @@ -1,47 +1,21 @@ -// nolint package types import ( - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -type CodeType = sdk.CodeType - -const ( - DefaultCodespace sdk.CodespaceType = "distr" - CodeInvalidInput CodeType = 103 - CodeNoDistributionInfo CodeType = 104 - CodeNoValidatorCommission CodeType = 105 - CodeSetWithdrawAddrDisabled CodeType = 106 +// x/distribution module sentinel errors +var ( + ErrEmptyDelegatorAddr = sdkerrors.Register(ModuleName, 1, "delegator address is empty") + ErrEmptyWithdrawAddr = sdkerrors.Register(ModuleName, 2, "withdraw address is empty") + ErrEmptyValidatorAddr = sdkerrors.Register(ModuleName, 3, "validator address is empty") + ErrEmptyDelegationDistInfo = sdkerrors.Register(ModuleName, 4, "no delegation distribution info") + ErrNoValidatorDistInfo = sdkerrors.Register(ModuleName, 5, "no validator distribution info") + ErrNoValidatorCommission = sdkerrors.Register(ModuleName, 6, "no validator commission to withdraw") + ErrSetWithdrawAddrDisabled = sdkerrors.Register(ModuleName, 7, "set withdraw address disabled") + ErrBadDistribution = sdkerrors.Register(ModuleName, 8, "community pool does not have sufficient coins to distribute") + ErrInvalidProposalAmount = sdkerrors.Register(ModuleName, 9, "invalid community pool spend proposal amount") + ErrEmptyProposalRecipient = sdkerrors.Register(ModuleName, 10, "invalid community pool spend proposal recipient") + ErrNoValidatorExists = sdkerrors.Register(ModuleName, 11, "validator does not exist") + ErrNoDelegationExists = sdkerrors.Register(ModuleName, 12, "delegation does not exist") ) - -func ErrNilDelegatorAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "delegator address is nil") -} -func ErrNilWithdrawAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "withdraw address is nil") -} -func ErrNilValidatorAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "validator address is nil") -} -func ErrNoDelegationDistInfo(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeNoDistributionInfo, "no delegation distribution info") -} -func ErrNoValidatorDistInfo(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeNoDistributionInfo, "no validator distribution info") -} -func ErrNoValidatorCommission(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeNoValidatorCommission, "no validator commission to withdraw") -} -func ErrSetWithdrawAddrDisabled(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeSetWithdrawAddrDisabled, "set withdraw address disabled") -} -func ErrBadDistribution(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "community pool does not have sufficient coins to distribute") -} -func ErrInvalidProposalAmount(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "invalid community pool spend proposal amount") -} -func ErrEmptyProposalRecipient(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "invalid community pool spend proposal recipient") -} diff --git a/x/distribution/types/expected_keepers.go b/x/distribution/types/expected_keepers.go index a51bc9d0403f..faa2f37235da 100644 --- a/x/distribution/types/expected_keepers.go +++ b/x/distribution/types/expected_keepers.go @@ -70,7 +70,7 @@ type SupplyKeeper interface { // TODO remove with genesis 2-phases refactor https://github.com/cosmos/cosmos-sdk/issues/2862 SetModuleAccount(sdk.Context, supplyexported.ModuleAccountI) - SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) sdk.Error - SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error + SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error } diff --git a/x/distribution/types/msg.go b/x/distribution/types/msg.go index 408983cb0ff2..2068caef149e 100644 --- a/x/distribution/types/msg.go +++ b/x/distribution/types/msg.go @@ -3,6 +3,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // Verify interface at compile time @@ -36,13 +37,14 @@ func (msg MsgSetWithdrawAddress) GetSignBytes() []byte { } // quick validity check -func (msg MsgSetWithdrawAddress) ValidateBasic() sdk.Error { +func (msg MsgSetWithdrawAddress) ValidateBasic() error { if msg.DelegatorAddress.Empty() { - return ErrNilDelegatorAddr(DefaultCodespace) + return ErrEmptyDelegatorAddr } if msg.WithdrawAddress.Empty() { - return ErrNilWithdrawAddr(DefaultCodespace) + return ErrEmptyWithdrawAddr } + return nil } @@ -74,12 +76,12 @@ func (msg MsgWithdrawDelegatorReward) GetSignBytes() []byte { } // quick validity check -func (msg MsgWithdrawDelegatorReward) ValidateBasic() sdk.Error { +func (msg MsgWithdrawDelegatorReward) ValidateBasic() error { if msg.DelegatorAddress.Empty() { - return ErrNilDelegatorAddr(DefaultCodespace) + return ErrEmptyDelegatorAddr } if msg.ValidatorAddress.Empty() { - return ErrNilValidatorAddr(DefaultCodespace) + return ErrEmptyValidatorAddr } return nil } @@ -110,9 +112,9 @@ func (msg MsgWithdrawValidatorCommission) GetSignBytes() []byte { } // quick validity check -func (msg MsgWithdrawValidatorCommission) ValidateBasic() sdk.Error { +func (msg MsgWithdrawValidatorCommission) ValidateBasic() error { if msg.ValidatorAddress.Empty() { - return ErrNilValidatorAddr(DefaultCodespace) + return ErrEmptyValidatorAddr } return nil } @@ -155,12 +157,12 @@ func (msg MsgFundCommunityPool) GetSignBytes() []byte { } // ValidateBasic performs basic MsgFundCommunityPool message validation. -func (msg MsgFundCommunityPool) ValidateBasic() sdk.Error { +func (msg MsgFundCommunityPool) ValidateBasic() error { if !msg.Amount.IsValid() { - return sdk.ErrInvalidCoins(msg.Amount.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String()) } if msg.Depositor.Empty() { - return sdk.ErrInvalidAddress(msg.Depositor.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Depositor.String()) } return nil diff --git a/x/distribution/types/proposal.go b/x/distribution/types/proposal.go index 0562d81df18d..931e111ba719 100644 --- a/x/distribution/types/proposal.go +++ b/x/distribution/types/proposal.go @@ -47,17 +47,18 @@ func (csp CommunityPoolSpendProposal) ProposalRoute() string { return RouterKey func (csp CommunityPoolSpendProposal) ProposalType() string { return ProposalTypeCommunityPoolSpend } // ValidateBasic runs basic stateless validity checks -func (csp CommunityPoolSpendProposal) ValidateBasic() sdk.Error { - err := govtypes.ValidateAbstract(DefaultCodespace, csp) +func (csp CommunityPoolSpendProposal) ValidateBasic() error { + err := govtypes.ValidateAbstract(csp) if err != nil { return err } if !csp.Amount.IsValid() { - return ErrInvalidProposalAmount(DefaultCodespace) + return ErrInvalidProposalAmount } if csp.Recipient.Empty() { - return ErrEmptyProposalRecipient(DefaultCodespace) + return ErrEmptyProposalRecipient } + return nil } diff --git a/x/evidence/alias.go b/x/evidence/alias.go index 411f39751578..29b8447a365e 100644 --- a/x/evidence/alias.go +++ b/x/evidence/alias.go @@ -8,23 +8,19 @@ import ( // nolint const ( - ModuleName = types.ModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - DefaultParamspace = types.DefaultParamspace - QueryEvidence = types.QueryEvidence - QueryAllEvidence = types.QueryAllEvidence - QueryParameters = types.QueryParameters - CodeNoEvidenceHandlerExists = types.CodeNoEvidenceHandlerExists - CodeInvalidEvidence = types.CodeInvalidEvidence - CodeNoEvidenceExists = types.CodeNoEvidenceExists - TypeMsgSubmitEvidence = types.TypeMsgSubmitEvidence - DefaultCodespace = types.DefaultCodespace - EventTypeSubmitEvidence = types.EventTypeSubmitEvidence - AttributeValueCategory = types.AttributeValueCategory - AttributeKeyEvidenceHash = types.AttributeKeyEvidenceHash - DefaultMaxEvidenceAge = types.DefaultMaxEvidenceAge + ModuleName = types.ModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + DefaultParamspace = types.DefaultParamspace + QueryEvidence = types.QueryEvidence + QueryAllEvidence = types.QueryAllEvidence + QueryParameters = types.QueryParameters + TypeMsgSubmitEvidence = types.TypeMsgSubmitEvidence + EventTypeSubmitEvidence = types.EventTypeSubmitEvidence + AttributeValueCategory = types.AttributeValueCategory + AttributeKeyEvidenceHash = types.AttributeKeyEvidenceHash + DefaultMaxEvidenceAge = types.DefaultMaxEvidenceAge ) var ( diff --git a/x/evidence/client/cli/query.go b/x/evidence/client/cli/query.go index 4c5eb13abaf1..b4a1dffd0af5 100644 --- a/x/evidence/client/cli/query.go +++ b/x/evidence/client/cli/query.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/evidence/exported" @@ -46,9 +47,9 @@ $ %s query %s --page=2 --limit=50 cmd.Flags().Int(flagPage, 1, "pagination page of evidence to to query for") cmd.Flags().Int(flagLimit, 100, "pagination limit of evidence to query for") - cmd.AddCommand(client.GetCommands(QueryParamsCmd(cdc))...) + cmd.AddCommand(flags.GetCommands(QueryParamsCmd(cdc))...) - return client.GetCommands(cmd)[0] + return flags.GetCommands(cmd)[0] } // QueryParamsCmd returns the command handler for evidence parameter querying. diff --git a/x/evidence/client/cli/tx.go b/x/evidence/client/cli/tx.go index 7cf6c5f6eadb..b97b56c0a23d 100644 --- a/x/evidence/client/cli/tx.go +++ b/x/evidence/client/cli/tx.go @@ -2,6 +2,7 @@ package cli import ( "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/evidence/internal/types" @@ -24,7 +25,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec, childCmds []*cobra.Command) *co submitEvidenceCmd := SubmitEvidenceCmd(cdc) for _, childCmd := range childCmds { - submitEvidenceCmd.AddCommand(client.PostCommands(childCmd)[0]) + submitEvidenceCmd.AddCommand(flags.PostCommands(childCmd)[0]) } // TODO: Add tx commands. diff --git a/x/evidence/genesis_test.go b/x/evidence/genesis_test.go index a77b847db177..10a8a2c75730 100644 --- a/x/evidence/genesis_test.go +++ b/x/evidence/genesis_test.go @@ -32,8 +32,7 @@ func (suite *GenesisTestSuite) SetupTest() { // recreate keeper in order to use custom testing types evidenceKeeper := evidence.NewKeeper( - cdc, app.GetKey(evidence.StoreKey), app.GetSubspace(evidence.ModuleName), - evidence.DefaultCodespace, app.StakingKeeper, app.SlashingKeeper, + cdc, app.GetKey(evidence.StoreKey), app.GetSubspace(evidence.ModuleName), app.StakingKeeper, app.SlashingKeeper, ) router := evidence.NewRouter() router = router.AddRoute(types.TestEvidenceRouteEquivocation, types.TestEquivocationHandler(*evidenceKeeper)) diff --git a/x/evidence/handler.go b/x/evidence/handler.go index 714da444c444..d5af1206bc01 100644 --- a/x/evidence/handler.go +++ b/x/evidence/handler.go @@ -1,13 +1,12 @@ package evidence import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func NewHandler(k Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -15,14 +14,14 @@ func NewHandler(k Keeper) sdk.Handler { return handleMsgSubmitEvidence(ctx, k, msg) default: - return sdk.ErrUnknownRequest(fmt.Sprintf("unrecognized %s message type: %T", ModuleName, msg)).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg) } } } -func handleMsgSubmitEvidence(ctx sdk.Context, k Keeper, msg MsgSubmitEvidence) sdk.Result { +func handleMsgSubmitEvidence(ctx sdk.Context, k Keeper, msg MsgSubmitEvidence) (*sdk.Result, error) { if err := k.SubmitEvidence(ctx, msg.Evidence); err != nil { - return sdk.ConvertError(err).Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -33,8 +32,8 @@ func handleMsgSubmitEvidence(ctx sdk.Context, k Keeper, msg MsgSubmitEvidence) s ), ) - return sdk.Result{ + return &sdk.Result{ Data: msg.Evidence.Hash(), Events: ctx.EventManager().Events(), - } + }, nil } diff --git a/x/evidence/handler_test.go b/x/evidence/handler_test.go index 1957778950ad..e5798bd01482 100644 --- a/x/evidence/handler_test.go +++ b/x/evidence/handler_test.go @@ -31,8 +31,7 @@ func (suite *HandlerTestSuite) SetupTest() { // recreate keeper in order to use custom testing types evidenceKeeper := evidence.NewKeeper( - cdc, app.GetKey(evidence.StoreKey), app.GetSubspace(evidence.ModuleName), - evidence.DefaultCodespace, app.StakingKeeper, app.SlashingKeeper, + cdc, app.GetKey(evidence.StoreKey), app.GetSubspace(evidence.ModuleName), app.StakingKeeper, app.SlashingKeeper, ) router := evidence.NewRouter() router = router.AddRoute(types.TestEvidenceRouteEquivocation, types.TestEquivocationHandler(*evidenceKeeper)) @@ -66,8 +65,9 @@ func (suite *HandlerTestSuite) TestMsgSubmitEvidence_Valid() { ctx := suite.ctx.WithIsCheckTx(false) msg := evidence.NewMsgSubmitEvidence(e, s) - res := suite.handler(ctx, msg) - suite.True(res.IsOK()) + res, err := suite.handler(ctx, msg) + suite.NoError(err) + suite.NotNil(res) suite.Equal(e.Hash().Bytes(), res.Data) } @@ -94,8 +94,9 @@ func (suite *HandlerTestSuite) TestMsgSubmitEvidence_Invalid() { ctx := suite.ctx.WithIsCheckTx(false) msg := evidence.NewMsgSubmitEvidence(e, s) - res := suite.handler(ctx, msg) - suite.False(res.IsOK()) + res, err := suite.handler(ctx, msg) + suite.Error(err) + suite.Nil(res) } func TestHandlerTestSuite(t *testing.T) { diff --git a/x/evidence/internal/keeper/infraction_test.go b/x/evidence/internal/keeper/infraction_test.go index ca68948f5eb1..cbef53de1921 100644 --- a/x/evidence/internal/keeper/infraction_test.go +++ b/x/evidence/internal/keeper/infraction_test.go @@ -28,8 +28,9 @@ func (suite *KeeperTestSuite) TestHandleDoubleSign() { operatorAddr, val := valAddresses[0], pubkeys[0] // create validator - res := staking.NewHandler(suite.app.StakingKeeper)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt)) - suite.True(res.IsOK(), res.Log) + res, err := staking.NewHandler(suite.app.StakingKeeper)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt)) + suite.NoError(err) + suite.NotNil(res) // execute end-blocker and verify validator attributes staking.EndBlocker(ctx, suite.app.StakingKeeper) @@ -78,8 +79,9 @@ func (suite *KeeperTestSuite) TestHandleDoubleSign() { validator, _ := suite.app.StakingKeeper.GetValidator(ctx, operatorAddr) totalBond := validator.TokensFromShares(del.GetShares()).TruncateInt() msgUnbond := staking.NewMsgUndelegate(sdk.AccAddress(operatorAddr), operatorAddr, sdk.NewCoin(stakingParams.BondDenom, totalBond)) - res = staking.NewHandler(suite.app.StakingKeeper)(ctx, msgUnbond) - suite.True(res.IsOK()) + res, err = staking.NewHandler(suite.app.StakingKeeper)(ctx, msgUnbond) + suite.NoError(err) + suite.NotNil(res) } func (suite *KeeperTestSuite) TestHandleDoubleSign_TooOld() { @@ -92,8 +94,9 @@ func (suite *KeeperTestSuite) TestHandleDoubleSign_TooOld() { operatorAddr, val := valAddresses[0], pubkeys[0] // create validator - res := staking.NewHandler(suite.app.StakingKeeper)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt)) - suite.True(res.IsOK(), res.Log) + res, err := staking.NewHandler(suite.app.StakingKeeper)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt)) + suite.NoError(err) + suite.NotNil(res) // execute end-blocker and verify validator attributes staking.EndBlocker(ctx, suite.app.StakingKeeper) diff --git a/x/evidence/internal/keeper/keeper.go b/x/evidence/internal/keeper/keeper.go index 26b45db7d69d..fd6c8027d8fd 100644 --- a/x/evidence/internal/keeper/keeper.go +++ b/x/evidence/internal/keeper/keeper.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/evidence/internal/types" "github.com/cosmos/cosmos-sdk/x/params" @@ -24,11 +25,10 @@ type Keeper struct { router types.Router stakingKeeper types.StakingKeeper slashingKeeper types.SlashingKeeper - codespace sdk.CodespaceType } func NewKeeper( - cdc *codec.Codec, storeKey sdk.StoreKey, paramSpace params.Subspace, codespace sdk.CodespaceType, + cdc *codec.Codec, storeKey sdk.StoreKey, paramSpace params.Subspace, stakingKeeper types.StakingKeeper, slashingKeeper types.SlashingKeeper, ) *Keeper { @@ -43,7 +43,6 @@ func NewKeeper( paramSpace: paramSpace, stakingKeeper: stakingKeeper, slashingKeeper: slashingKeeper, - codespace: codespace, } } @@ -74,7 +73,7 @@ func (k *Keeper) SetRouter(rtr types.Router) { // no handler exists, an error is returned. func (k Keeper) GetEvidenceHandler(evidenceRoute string) (types.Handler, error) { if !k.router.HasRoute(evidenceRoute) { - return nil, types.ErrNoEvidenceHandlerExists(k.codespace, evidenceRoute) + return nil, sdkerrors.Wrap(types.ErrNoEvidenceHandlerExists, evidenceRoute) } return k.router.GetRoute(evidenceRoute), nil @@ -86,15 +85,15 @@ func (k Keeper) GetEvidenceHandler(evidenceRoute string) (types.Handler, error) // persisted. func (k Keeper) SubmitEvidence(ctx sdk.Context, evidence exported.Evidence) error { if _, ok := k.GetEvidence(ctx, evidence.Hash()); ok { - return types.ErrEvidenceExists(k.codespace, evidence.Hash().String()) + return sdkerrors.Wrap(types.ErrEvidenceExists, evidence.Hash().String()) } if !k.router.HasRoute(evidence.Route()) { - return types.ErrNoEvidenceHandlerExists(k.codespace, evidence.Route()) + return sdkerrors.Wrap(types.ErrNoEvidenceHandlerExists, evidence.Route()) } handler := k.router.GetRoute(evidence.Route()) if err := handler(ctx, evidence); err != nil { - return types.ErrInvalidEvidence(k.codespace, err.Error()) + return sdkerrors.Wrap(types.ErrInvalidEvidence, err.Error()) } ctx.EventManager().EmitEvent( diff --git a/x/evidence/internal/keeper/keeper_test.go b/x/evidence/internal/keeper/keeper_test.go index bde9f08f02ce..45347ab96be0 100644 --- a/x/evidence/internal/keeper/keeper_test.go +++ b/x/evidence/internal/keeper/keeper_test.go @@ -66,8 +66,7 @@ func (suite *KeeperTestSuite) SetupTest() { // recreate keeper in order to use custom testing types evidenceKeeper := evidence.NewKeeper( - cdc, app.GetKey(evidence.StoreKey), app.GetSubspace(evidence.ModuleName), - evidence.DefaultCodespace, app.StakingKeeper, app.SlashingKeeper, + cdc, app.GetKey(evidence.StoreKey), app.GetSubspace(evidence.ModuleName), app.StakingKeeper, app.SlashingKeeper, ) router := evidence.NewRouter() router = router.AddRoute(types.TestEvidenceRouteEquivocation, types.TestEquivocationHandler(*evidenceKeeper)) diff --git a/x/evidence/internal/keeper/querier.go b/x/evidence/internal/keeper/querier.go index dfbda68f66d6..cbb616677e8f 100644 --- a/x/evidence/internal/keeper/querier.go +++ b/x/evidence/internal/keeper/querier.go @@ -14,7 +14,7 @@ import ( ) func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { var ( res []byte err error @@ -31,10 +31,10 @@ func NewQuerier(k Keeper) sdk.Querier { res, err = queryAllEvidence(ctx, req, k) default: - err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint", types.ModuleName) + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) } - return res, sdk.ConvertError(err) + return res, err } } @@ -64,7 +64,7 @@ func queryEvidence(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, er evidence, ok := k.GetEvidence(ctx, hash) if !ok { - return nil, types.ErrNoEvidenceExists(k.codespace, params.EvidenceHash) + return nil, sdkerrors.Wrap(types.ErrNoEvidenceExists, params.EvidenceHash) } res, err := codec.MarshalJSONIndent(k.cdc, evidence) diff --git a/x/evidence/internal/types/errors.go b/x/evidence/internal/types/errors.go index 2054cee9fb66..83ffe06002ae 100644 --- a/x/evidence/internal/types/errors.go +++ b/x/evidence/internal/types/errors.go @@ -2,57 +2,13 @@ package types import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// Error codes specific to the evidence module -const ( - DefaultCodespace sdk.CodespaceType = ModuleName - - CodeNoEvidenceHandlerExists sdk.CodeType = 1 - CodeInvalidEvidence sdk.CodeType = 2 - CodeNoEvidenceExists sdk.CodeType = 3 - CodeEvidenceExists sdk.CodeType = 4 +// x/evidence module sentinel errors +var ( + ErrNoEvidenceHandlerExists = sdkerrors.Register(ModuleName, 1, "unregistered handler for evidence type") + ErrInvalidEvidence = sdkerrors.Register(ModuleName, 2, "invalid evidence") + ErrNoEvidenceExists = sdkerrors.Register(ModuleName, 3, "evidence does not exist") + ErrEvidenceExists = sdkerrors.Register(ModuleName, 4, "evidence already exists") ) - -// ErrNoEvidenceHandlerExists returns a typed ABCI error for an invalid evidence -// handler route. -func ErrNoEvidenceHandlerExists(codespace sdk.CodespaceType, route string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeNoEvidenceHandlerExists), - fmt.Sprintf("route '%s' does not have a registered evidence handler", route), - ) -} - -// ErrInvalidEvidence returns a typed ABCI error for invalid evidence. -func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidEvidence), - fmt.Sprintf("invalid evidence: %s", msg), - ) -} - -// ErrNoEvidenceExists returns a typed ABCI error for Evidence that does not exist -// for a given hash. -func ErrNoEvidenceExists(codespace sdk.CodespaceType, hash string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeNoEvidenceExists), - fmt.Sprintf("evidence with hash %s does not exist", hash), - ) -} - -// ErrEvidenceExists returns a typed ABCI error for Evidence that already exists -// by hash in state. -func ErrEvidenceExists(codespace sdk.CodespaceType, hash string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeEvidenceExists), - fmt.Sprintf("evidence with hash %s already exists", hash), - ) -} diff --git a/x/evidence/internal/types/msgs.go b/x/evidence/internal/types/msgs.go index b09f120da927..3fbb50844f57 100644 --- a/x/evidence/internal/types/msgs.go +++ b/x/evidence/internal/types/msgs.go @@ -33,15 +33,15 @@ func (m MsgSubmitEvidence) Route() string { return RouterKey } func (m MsgSubmitEvidence) Type() string { return TypeMsgSubmitEvidence } // ValidateBasic performs basic (non-state-dependant) validation on a MsgSubmitEvidence. -func (m MsgSubmitEvidence) ValidateBasic() sdk.Error { +func (m MsgSubmitEvidence) ValidateBasic() error { if m.Evidence == nil { - return sdk.ConvertError(ErrInvalidEvidence(DefaultCodespace, "missing evidence")) + return sdkerrors.Wrap(ErrInvalidEvidence, "missing evidence") } if err := m.Evidence.ValidateBasic(); err != nil { - return sdk.ConvertError(err) + return err } if m.Submitter.Empty() { - return sdk.ConvertError(sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, m.Submitter.String())) + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, m.Submitter.String()) } return nil diff --git a/x/genutil/client/cli/collect.go b/x/genutil/client/cli/collect.go index fe1c864eca9f..bc38ab74d287 100644 --- a/x/genutil/client/cli/collect.go +++ b/x/genutil/client/cli/collect.go @@ -10,7 +10,7 @@ import ( "github.com/tendermint/tendermint/libs/cli" tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/x/genutil" @@ -29,7 +29,7 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec, RunE: func(_ *cobra.Command, _ []string) error { config := ctx.Config config.SetRoot(viper.GetString(cli.HomeFlag)) - name := viper.GetString(client.FlagName) + name := viper.GetString(flags.FlagName) nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(config) if err != nil { return errors.Wrap(err, "failed to initialize node validator files") diff --git a/x/genutil/client/cli/gentx.go b/x/genutil/client/cli/gentx.go index ebfdded23a96..aae33d6b8b7c 100644 --- a/x/genutil/client/cli/gentx.go +++ b/x/genutil/client/cli/gentx.go @@ -21,9 +21,9 @@ import ( "github.com/tendermint/tendermint/libs/common" tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" kbkeys "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/server" @@ -64,7 +64,7 @@ func GenTxCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, sm RunE: func(cmd *cobra.Command, args []string) error { config := ctx.Config - config.SetRoot(viper.GetString(client.FlagHome)) + config.SetRoot(viper.GetString(flags.FlagHome)) nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(ctx.Config) if err != nil { return errors.Wrap(err, "failed to initialize node validator files") @@ -97,19 +97,19 @@ func GenTxCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, sm } inBuf := bufio.NewReader(cmd.InOrStdin()) - kb, err := client.NewKeyringFromDir(viper.GetString(flagClientHome), inBuf) + kb, err := keys.NewKeyringFromDir(viper.GetString(flagClientHome), inBuf) if err != nil { return errors.Wrap(err, "failed to initialize keybase") } - name := viper.GetString(client.FlagName) + name := viper.GetString(flags.FlagName) key, err := kb.Get(name) if err != nil { return errors.Wrap(err, "failed to read from keybase") } // Set flags for creating gentx - viper.Set(client.FlagHome, viper.GetString(flagClientHome)) + viper.Set(flags.FlagHome, viper.GetString(flagClientHome)) smbh.PrepareFlagsForTxCreateValidator(config, nodeID, genDoc.ChainID, valPubKey) // Fetch the amount of coins staked @@ -125,14 +125,14 @@ func GenTxCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, sm } txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := client.NewCLIContextWithInput(inBuf).WithCodec(cdc) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) // Set the generate-only flag here after the CLI context has // been created. This allows the from name/key to be correctly populated. // // TODO: Consider removing the manual setting of generate-only in // favor of a 'gentx' flag in the create-validator command. - viper.Set(client.FlagGenerateOnly, true) + viper.Set(flags.FlagGenerateOnly, true) // create a 'create-validator' message txBldr, msg, err := smbh.BuildCreateValidatorMsg(cliCtx, txBldr) @@ -166,7 +166,7 @@ func GenTxCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, sm } // Fetch output file name - outputDocument := viper.GetString(client.FlagOutputDocument) + outputDocument := viper.GetString(flags.FlagOutputDocument) if outputDocument == "" { outputDocument, err = makeOutputFilepath(config.RootDir, nodeID) if err != nil { @@ -184,16 +184,16 @@ func GenTxCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, sm }, } - cmd.Flags().String(client.FlagHome, defaultNodeHome, "node's home directory") + cmd.Flags().String(flags.FlagHome, defaultNodeHome, "node's home directory") cmd.Flags().String(flagClientHome, defaultCLIHome, "client's home directory") - cmd.Flags().String(client.FlagName, "", "name of private key with which to sign the gentx") - cmd.Flags().String(client.FlagOutputDocument, "", + cmd.Flags().String(flags.FlagName, "", "name of private key with which to sign the gentx") + cmd.Flags().String(flags.FlagOutputDocument, "", "write the genesis transaction JSON document to the given file instead of the default location") cmd.Flags().AddFlagSet(fsCreateValidator) - cmd.Flags().String(client.FlagKeyringBackend, client.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") + cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") viper.BindPFlag(flags.FlagKeyringBackend, cmd.Flags().Lookup(flags.FlagKeyringBackend)) - cmd.MarkFlagRequired(client.FlagName) + cmd.MarkFlagRequired(flags.FlagName) return cmd } diff --git a/x/genutil/client/cli/init.go b/x/genutil/client/cli/init.go index aed60d17f839..c611556ae8f1 100644 --- a/x/genutil/client/cli/init.go +++ b/x/genutil/client/cli/init.go @@ -14,7 +14,7 @@ import ( "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/types" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" @@ -70,7 +70,7 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, config := ctx.Config config.SetRoot(viper.GetString(cli.HomeFlag)) - chainID := viper.GetString(client.FlagChainID) + chainID := viper.GetString(flags.FlagChainID) if chainID == "" { chainID = fmt.Sprintf("test-chain-%v", common.RandStr(6)) } @@ -119,7 +119,7 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory") cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the genesis.json file") - cmd.Flags().String(client.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") + cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") return cmd } diff --git a/x/genutil/client/cli/init_test.go b/x/genutil/client/cli/init_test.go index 540e57cfb5f2..6ab1ef208abe 100644 --- a/x/genutil/client/cli/init_test.go +++ b/x/genutil/client/cli/init_test.go @@ -14,7 +14,7 @@ import ( "github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/mock" @@ -126,7 +126,7 @@ func TestInitNodeValidatorFiles(t *testing.T) { home, cleanup := tests.NewTestCaseDir(t) defer cleanup() viper.Set(cli.HomeFlag, home) - viper.Set(client.FlagName, "moniker") + viper.Set(flags.FlagName, "moniker") cfg, err := tcmd.ParseConfig() require.Nil(t, err) nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(cfg) diff --git a/x/genutil/client/cli/migrate_test.go b/x/genutil/client/cli/migrate_test.go index fca36a4dfc28..423629efcb13 100644 --- a/x/genutil/client/cli/migrate_test.go +++ b/x/genutil/client/cli/migrate_test.go @@ -12,7 +12,7 @@ import ( "github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" ) @@ -39,7 +39,7 @@ func TestGetMigrationCallback(t *testing.T) { func TestMigrateGenesis(t *testing.T) { home, cleanup := tests.NewTestCaseDir(t) viper.Set(cli.HomeFlag, home) - viper.Set(client.FlagName, "moniker") + viper.Set(flags.FlagName, "moniker") logger := log.NewNopLogger() cfg, err := tcmd.ParseConfig() require.Nil(t, err) diff --git a/x/genutil/client/rest/query.go b/x/genutil/client/rest/query.go index 4f0f318aa201..0159223e8e7c 100644 --- a/x/genutil/client/rest/query.go +++ b/x/genutil/client/rest/query.go @@ -1,6 +1,7 @@ package rest import ( + "fmt" "net/http" "github.com/cosmos/cosmos-sdk/client/context" @@ -14,15 +15,19 @@ import ( func QueryGenesisTxs(cliCtx context.CLIContext, w http.ResponseWriter) { resultGenesis, err := cliCtx.Client.Genesis() if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, - sdk.AppendMsgToErr("could not retrieve genesis from client", err.Error())) + rest.WriteErrorResponse( + w, http.StatusInternalServerError, + fmt.Sprintf("failed to retrieve genesis from client: %s", err), + ) return } appState, err := types.GenesisStateFromGenDoc(cliCtx.Codec, *resultGenesis.Genesis) if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, - sdk.AppendMsgToErr("could not decode genesis doc", err.Error())) + rest.WriteErrorResponse( + w, http.StatusInternalServerError, + fmt.Sprintf("failed to decode genesis doc: %s", err), + ) return } @@ -31,8 +36,10 @@ func QueryGenesisTxs(cliCtx context.CLIContext, w http.ResponseWriter) { for i, tx := range genState.GenTxs { err := cliCtx.Codec.UnmarshalJSON(tx, &genTxs[i]) if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, - sdk.AppendMsgToErr("could not decode genesis transaction", err.Error())) + rest.WriteErrorResponse( + w, http.StatusInternalServerError, + fmt.Sprintf("failed to decode genesis transaction: %s", err), + ) return } } diff --git a/x/gov/abci.go b/x/gov/abci.go index 31b1f40c9d2a..21db8f5cd2c2 100644 --- a/x/gov/abci.go +++ b/x/gov/abci.go @@ -65,7 +65,7 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) { } else { proposal.Status = StatusFailed tagValue = types.AttributeValueProposalFailed - logMsg = fmt.Sprintf("passed, but failed on execution: %s", err.ABCILog()) + logMsg = fmt.Sprintf("passed, but failed on execution: %s", err) } } else { proposal.Status = StatusRejected diff --git a/x/gov/abci_test.go b/x/gov/abci_test.go index 42616b36c00b..6ee3a3075920 100644 --- a/x/gov/abci_test.go +++ b/x/gov/abci_test.go @@ -32,8 +32,9 @@ func TestTickExpiredDepositPeriod(t *testing.T) { input.addrs[0], ) - res := govHandler(ctx, newProposalMsg) - require.True(t, res.IsOK()) + res, err := govHandler(ctx, newProposalMsg) + require.NoError(t, err) + require.NotNil(t, res) inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) @@ -81,8 +82,9 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) { input.addrs[0], ) - res := govHandler(ctx, newProposalMsg) - require.True(t, res.IsOK()) + res, err := govHandler(ctx, newProposalMsg) + require.NoError(t, err) + require.NotNil(t, res) inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) @@ -102,8 +104,9 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) { input.addrs[0], ) - res = govHandler(ctx, newProposalMsg2) - require.True(t, res.IsOK()) + res, err = govHandler(ctx, newProposalMsg2) + require.NoError(t, err) + require.NotNil(t, res) newHeader = ctx.BlockHeader() newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(time.Duration(-1) * time.Second) @@ -152,8 +155,10 @@ func TestTickPassedDepositPeriod(t *testing.T) { input.addrs[0], ) - res := govHandler(ctx, newProposalMsg) - require.True(t, res.IsOK()) + res, err := govHandler(ctx, newProposalMsg) + require.NoError(t, err) + require.NotNil(t, res) + proposalID := GetProposalIDFromBytes(res.Data) inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) @@ -169,8 +174,10 @@ func TestTickPassedDepositPeriod(t *testing.T) { inactiveQueue.Close() newDepositMsg := NewMsgDeposit(input.addrs[1], proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)}) - res = govHandler(ctx, newDepositMsg) - require.True(t, res.IsOK()) + + res, err = govHandler(ctx, newDepositMsg) + require.NoError(t, err) + require.NotNil(t, res) activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, activeQueue.Valid()) @@ -197,8 +204,10 @@ func TestTickPassedVotingPeriod(t *testing.T) { proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(5))} newProposalMsg := NewMsgSubmitProposal(keep.TestProposal, proposalCoins, input.addrs[0]) - res := govHandler(ctx, newProposalMsg) - require.True(t, res.IsOK()) + res, err := govHandler(ctx, newProposalMsg) + require.NoError(t, err) + require.NotNil(t, res) + proposalID := GetProposalIDFromBytes(res.Data) newHeader := ctx.BlockHeader() @@ -206,8 +215,10 @@ func TestTickPassedVotingPeriod(t *testing.T) { ctx = ctx.WithBlockHeader(newHeader) newDepositMsg := NewMsgDeposit(input.addrs[1], proposalID, proposalCoins) - res = govHandler(ctx, newDepositMsg) - require.True(t, res.IsOK()) + + res, err = govHandler(ctx, newDepositMsg) + require.NoError(t, err) + require.NotNil(t, res) newHeader = ctx.BlockHeader() newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod) @@ -259,8 +270,10 @@ func TestProposalPassedEndblocker(t *testing.T) { proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10))} newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins) - res := handler(ctx, newDepositMsg) - require.True(t, res.IsOK()) + + res, err := handler(ctx, newDepositMsg) + require.NoError(t, err) + require.NotNil(t, res) macc = input.keeper.GetGovernanceAccount(ctx) require.NotNil(t, macc) @@ -308,8 +321,10 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) { proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10))) newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins) - res := handler(ctx, newDepositMsg) - require.True(t, res.IsOK()) + + res, err := handler(ctx, newDepositMsg) + require.NoError(t, err) + require.NotNil(t, res) err = input.keeper.AddVote(ctx, proposal.ProposalID, input.addrs[0], OptionYes) require.NoError(t, err) diff --git a/x/gov/alias.go b/x/gov/alias.go index 0ca57b7a39fc..df5f2cb9ce77 100644 --- a/x/gov/alias.go +++ b/x/gov/alias.go @@ -1,62 +1,47 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/gov/keeper -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/gov/types package gov +// nolint + import ( "github.com/cosmos/cosmos-sdk/x/gov/keeper" "github.com/cosmos/cosmos-sdk/x/gov/types" ) const ( - MaxDescriptionLength = types.MaxDescriptionLength - MaxTitleLength = types.MaxTitleLength - DefaultCodespace = types.DefaultCodespace - CodeUnknownProposal = types.CodeUnknownProposal - CodeInactiveProposal = types.CodeInactiveProposal - CodeAlreadyActiveProposal = types.CodeAlreadyActiveProposal - CodeAlreadyFinishedProposal = types.CodeAlreadyFinishedProposal - CodeAddressNotStaked = types.CodeAddressNotStaked - CodeInvalidContent = types.CodeInvalidContent - CodeInvalidProposalType = types.CodeInvalidProposalType - CodeInvalidVote = types.CodeInvalidVote - CodeInvalidGenesis = types.CodeInvalidGenesis - CodeInvalidProposalStatus = types.CodeInvalidProposalStatus - CodeProposalHandlerNotExists = types.CodeProposalHandlerNotExists - DefaultPeriod = types.DefaultPeriod - ModuleName = types.ModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - DefaultParamspace = types.DefaultParamspace - TypeMsgDeposit = types.TypeMsgDeposit - TypeMsgVote = types.TypeMsgVote - TypeMsgSubmitProposal = types.TypeMsgSubmitProposal - StatusNil = types.StatusNil - StatusDepositPeriod = types.StatusDepositPeriod - StatusVotingPeriod = types.StatusVotingPeriod - StatusPassed = types.StatusPassed - StatusRejected = types.StatusRejected - StatusFailed = types.StatusFailed - ProposalTypeText = types.ProposalTypeText - QueryParams = types.QueryParams - QueryProposals = types.QueryProposals - QueryProposal = types.QueryProposal - QueryDeposits = types.QueryDeposits - QueryDeposit = types.QueryDeposit - QueryVotes = types.QueryVotes - QueryVote = types.QueryVote - QueryTally = types.QueryTally - ParamDeposit = types.ParamDeposit - ParamVoting = types.ParamVoting - ParamTallying = types.ParamTallying - OptionEmpty = types.OptionEmpty - OptionYes = types.OptionYes - OptionAbstain = types.OptionAbstain - OptionNo = types.OptionNo - OptionNoWithVeto = types.OptionNoWithVeto + MaxDescriptionLength = types.MaxDescriptionLength + MaxTitleLength = types.MaxTitleLength + DefaultPeriod = types.DefaultPeriod + ModuleName = types.ModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + DefaultParamspace = types.DefaultParamspace + TypeMsgDeposit = types.TypeMsgDeposit + TypeMsgVote = types.TypeMsgVote + TypeMsgSubmitProposal = types.TypeMsgSubmitProposal + StatusNil = types.StatusNil + StatusDepositPeriod = types.StatusDepositPeriod + StatusVotingPeriod = types.StatusVotingPeriod + StatusPassed = types.StatusPassed + StatusRejected = types.StatusRejected + StatusFailed = types.StatusFailed + ProposalTypeText = types.ProposalTypeText + QueryParams = types.QueryParams + QueryProposals = types.QueryProposals + QueryProposal = types.QueryProposal + QueryDeposits = types.QueryDeposits + QueryDeposit = types.QueryDeposit + QueryVotes = types.QueryVotes + QueryVote = types.QueryVote + QueryTally = types.QueryTally + ParamDeposit = types.ParamDeposit + ParamVoting = types.ParamVoting + ParamTallying = types.ParamTallying + OptionEmpty = types.OptionEmpty + OptionYes = types.OptionYes + OptionAbstain = types.OptionAbstain + OptionNo = types.OptionNo + OptionNoWithVeto = types.OptionNoWithVeto ) var ( diff --git a/x/gov/client/cli/query.go b/x/gov/client/cli/query.go index 69f89e7a7d05..1a0c0a179ef7 100644 --- a/x/gov/client/cli/query.go +++ b/x/gov/client/cli/query.go @@ -10,10 +10,10 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" gcutils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -29,7 +29,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - govQueryCmd.AddCommand(client.GetCommands( + govQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryProposal(queryRoute, cdc), GetCmdQueryProposals(queryRoute, cdc), GetCmdQueryVote(queryRoute, cdc), @@ -285,7 +285,7 @@ $ %[1]s query gov votes 1 --page=2 --limit=100 propStatus := proposal.Status if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) { - res, err = gcutils.QueryVotesByTxQuery(cliCtx, params, utils.QueryTxsByEvents) + res, err = gcutils.QueryVotesByTxQuery(cliCtx, params) } else { res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/votes", queryRoute), bz) } diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index 4bd49a610e95..8c6c1109c9d4 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -66,10 +67,10 @@ func GetTxCmd(storeKey string, cdc *codec.Codec, pcmds []*cobra.Command) *cobra. cmdSubmitProp := GetCmdSubmitProposal(cdc) for _, pcmd := range pcmds { - cmdSubmitProp.AddCommand(client.PostCommands(pcmd)[0]) + cmdSubmitProp.AddCommand(flags.PostCommands(pcmd)[0]) } - govTxCmd.AddCommand(client.PostCommands( + govTxCmd.AddCommand(flags.PostCommands( GetCmdDeposit(cdc), GetCmdVote(cdc), cmdSubmitProp, diff --git a/x/gov/client/rest/query.go b/x/gov/client/rest/query.go index de9ccf379dd5..3eb5800d7a99 100644 --- a/x/gov/client/rest/query.go +++ b/x/gov/client/rest/query.go @@ -10,7 +10,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" gcutils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -382,7 +381,7 @@ func queryVotesOnProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { // as they're no longer in state. propStatus := proposal.Status if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) { - res, err = gcutils.QueryVotesByTxQuery(cliCtx, params, utils.QueryTxsByEvents) + res, err = gcutils.QueryVotesByTxQuery(cliCtx, params) } else { res, _, err = cliCtx.QueryWithData("custom/gov/votes", bz) } diff --git a/x/gov/client/utils/query.go b/x/gov/client/utils/query.go index 2eaf2c5a7a78..d4be3c010f93 100644 --- a/x/gov/client/utils/query.go +++ b/x/gov/client/utils/query.go @@ -73,15 +73,10 @@ func QueryDepositsByTxQuery(cliCtx context.CLIContext, params types.QueryProposa return cliCtx.Codec.MarshalJSON(deposits) } -// TxQuerier is a type that accepts query parameters (target events and pagination options) and returns sdk.SearchTxsResult. -// Mainly used for easier mocking of utils.QueryTxsByEvents in tests. -type TxQuerier func(cliCtx context.CLIContext, events []string, page, limit int) (*sdk.SearchTxsResult, error) - -// QueryVotesByTxQuery will query for votes using provided TxQuerier implementation. -// In general utils.QueryTxsByEvents should be used that will do a direct tx query to a tendermint node. -// It will fetch and build votes directly from the returned txs and return a JSON +// QueryVotesByTxQuery will query for votes via a direct txs tags query. It +// will fetch and build votes directly from the returned txs and return a JSON // marshalled result or any error that occurred. -func QueryVotesByTxQuery(cliCtx context.CLIContext, params types.QueryProposalVotesParams, querier TxQuerier) ([]byte, error) { +func QueryVotesByTxQuery(cliCtx context.CLIContext, params types.QueryProposalVotesParams) ([]byte, error) { var ( events = []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgVote), @@ -93,7 +88,7 @@ func QueryVotesByTxQuery(cliCtx context.CLIContext, params types.QueryProposalVo ) // query interrupted either if we collected enough votes or tx indexer run out of relevant txs for len(votes) < totalLimit { - searchResult, err := querier(cliCtx, events, nextTxPage, defaultLimit) + searchResult, err := utils.QueryTxsByEvents(cliCtx, events, nextTxPage, defaultLimit) if err != nil { return nil, err } diff --git a/x/gov/client/utils/query_test.go b/x/gov/client/utils/query_test.go index ce9b548b93bb..68762b248066 100644 --- a/x/gov/client/utils/query_test.go +++ b/x/gov/client/utils/query_test.go @@ -7,72 +7,87 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/rpc/client/mock" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + tmtypes "github.com/tendermint/tendermint/types" ) -type txMock struct { - address sdk.AccAddress - msgNum int +type TxSearchMock struct { + mock.Client + txs []tmtypes.Tx } -func (tx txMock) ValidateBasic() sdk.Error { - return nil +func (mock TxSearchMock) TxSearch(query string, prove bool, page, perPage int) (*ctypes.ResultTxSearch, error) { + start, end := client.Paginate(len(mock.txs), page, perPage, 100) + if start < 0 || end < 0 { + // nil result with nil error crashes utils.QueryTxsByEvents + return &ctypes.ResultTxSearch{}, nil + } + txs := mock.txs[start:end] + rst := &ctypes.ResultTxSearch{Txs: make([]*ctypes.ResultTx, len(txs)), TotalCount: len(txs)} + for i := range txs { + rst.Txs[i] = &ctypes.ResultTx{Tx: txs[i]} + } + return rst, nil } -func (tx txMock) GetMsgs() (msgs []sdk.Msg) { - for i := 0; i < tx.msgNum; i++ { - msgs = append(msgs, types.NewMsgVote(tx.address, 0, types.OptionYes)) - } - return +func (mock TxSearchMock) Block(height *int64) (*ctypes.ResultBlock, error) { + // any non nil Block needs to be returned. used to get time value + return &ctypes.ResultBlock{Block: &tmtypes.Block{}}, nil } -func makeQuerier(txs []sdk.Tx) TxQuerier { - return func(cliCtx context.CLIContext, events []string, page, limit int) (*sdk.SearchTxsResult, error) { - start, end := client.Paginate(len(txs), page, limit, 100) - if start < 0 || end < 0 { - return nil, nil - } - rst := &sdk.SearchTxsResult{ - TotalCount: len(txs), - PageNumber: page, - PageTotal: len(txs) / limit, - Limit: limit, - Count: end - start, - } - for _, tx := range txs[start:end] { - rst.Txs = append(rst.Txs, sdk.TxResponse{Tx: tx}) - } - return rst, nil - } +func newTestCodec() *codec.Codec { + cdc := codec.New() + sdk.RegisterCodec(cdc) + types.RegisterCodec(cdc) + authtypes.RegisterCodec(cdc) + return cdc } func TestGetPaginatedVotes(t *testing.T) { type testCase struct { description string page, limit int - txs []sdk.Tx + txs []authtypes.StdTx votes []types.Vote } acc1 := make(sdk.AccAddress, 20) acc1[0] = 1 acc2 := make(sdk.AccAddress, 20) acc2[0] = 2 + acc1Msgs := []sdk.Msg{ + types.NewMsgVote(acc1, 0, types.OptionYes), + types.NewMsgVote(acc1, 0, types.OptionYes), + } + acc2Msgs := []sdk.Msg{ + types.NewMsgVote(acc2, 0, types.OptionYes), + types.NewMsgVote(acc2, 0, types.OptionYes), + } for _, tc := range []testCase{ { description: "1MsgPerTxAll", page: 1, limit: 2, - txs: []sdk.Tx{txMock{acc1, 1}, txMock{acc2, 1}}, + txs: []authtypes.StdTx{ + {Msgs: acc1Msgs[:1]}, + {Msgs: acc2Msgs[:1]}, + }, votes: []types.Vote{ types.NewVote(0, acc1, types.OptionYes), types.NewVote(0, acc2, types.OptionYes)}, }, + { description: "2MsgPerTx1Chunk", page: 1, limit: 2, - txs: []sdk.Tx{txMock{acc1, 2}, txMock{acc2, 2}}, + txs: []authtypes.StdTx{ + {Msgs: acc1Msgs}, + {Msgs: acc2Msgs}, + }, votes: []types.Vote{ types.NewVote(0, acc1, types.OptionYes), types.NewVote(0, acc1, types.OptionYes)}, @@ -81,7 +96,10 @@ func TestGetPaginatedVotes(t *testing.T) { description: "2MsgPerTx2Chunk", page: 2, limit: 2, - txs: []sdk.Tx{txMock{acc1, 2}, txMock{acc2, 2}}, + txs: []authtypes.StdTx{ + {Msgs: acc1Msgs}, + {Msgs: acc2Msgs}, + }, votes: []types.Vote{ types.NewVote(0, acc2, types.OptionYes), types.NewVote(0, acc2, types.OptionYes)}, @@ -90,33 +108,43 @@ func TestGetPaginatedVotes(t *testing.T) { description: "IncompleteSearchTx", page: 1, limit: 2, - txs: []sdk.Tx{txMock{acc1, 1}}, - votes: []types.Vote{types.NewVote(0, acc1, types.OptionYes)}, - }, - { - description: "IncompleteSearchTx", - page: 1, - limit: 2, - txs: []sdk.Tx{txMock{acc1, 1}}, - votes: []types.Vote{types.NewVote(0, acc1, types.OptionYes)}, + txs: []authtypes.StdTx{ + {Msgs: acc1Msgs[:1]}, + }, + votes: []types.Vote{types.NewVote(0, acc1, types.OptionYes)}, }, { description: "InvalidPage", page: -1, - txs: []sdk.Tx{txMock{acc1, 1}}, + txs: []authtypes.StdTx{ + {Msgs: acc1Msgs[:1]}, + }, }, { description: "OutOfBounds", page: 2, limit: 10, - txs: []sdk.Tx{txMock{acc1, 1}}, + txs: []authtypes.StdTx{ + {Msgs: acc1Msgs[:1]}, + }, }, } { tc := tc t.Run(tc.description, func(t *testing.T) { - ctx := context.CLIContext{}.WithCodec(codec.New()) + var ( + marshalled = make([]tmtypes.Tx, len(tc.txs)) + cdc = newTestCodec() + ) + for i := range tc.txs { + tx, err := cdc.MarshalBinaryLengthPrefixed(&tc.txs[i]) + require.NoError(t, err) + marshalled[i] = tmtypes.Tx(tx) + } + client := TxSearchMock{txs: marshalled} + ctx := context.CLIContext{}.WithCodec(cdc).WithTrustNode(true).WithClient(client) + params := types.NewQueryProposalVotesParams(0, tc.page, tc.limit) - votesData, err := QueryVotesByTxQuery(ctx, params, makeQuerier(tc.txs)) + votesData, err := QueryVotesByTxQuery(ctx, params) require.NoError(t, err) votes := []types.Vote{} require.NoError(t, ctx.Codec.UnmarshalJSON(votesData, &votes)) diff --git a/x/gov/genesis_test.go b/x/gov/genesis_test.go index 1beb0baecaa6..8626e7821e5f 100644 --- a/x/gov/genesis_test.go +++ b/x/gov/genesis_test.go @@ -29,7 +29,7 @@ func TestImportExportQueues(t *testing.T) { require.NoError(t, err) proposalID2 := proposal2.ProposalID - err, votingStarted := input.keeper.AddDeposit(ctx, proposalID2, input.addrs[0], input.keeper.GetDepositParams(ctx).MinDeposit) + votingStarted, err := input.keeper.AddDeposit(ctx, proposalID2, input.addrs[0], input.keeper.GetDepositParams(ctx).MinDeposit) require.NoError(t, err) require.True(t, votingStarted) diff --git a/x/gov/handler.go b/x/gov/handler.go index 47efe4473cd4..4e4aee2c5334 100644 --- a/x/gov/handler.go +++ b/x/gov/handler.go @@ -4,12 +4,13 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/gov/types" ) // NewHandler creates an sdk.Handler for all the gov type messages func NewHandler(keeper Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -23,21 +24,20 @@ func NewHandler(keeper Keeper) sdk.Handler { return handleMsgVote(ctx, keeper, msg) default: - errMsg := fmt.Sprintf("unrecognized gov message type: %T", msg) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg) } } } -func handleMsgSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSubmitProposal) sdk.Result { +func handleMsgSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSubmitProposal) (*sdk.Result, error) { proposal, err := keeper.SubmitProposal(ctx, msg.Content) if err != nil { - return err.Result() + return nil, err } - err, votingStarted := keeper.AddDeposit(ctx, proposal.ProposalID, msg.Proposer, msg.InitialDeposit) + votingStarted, err := keeper.AddDeposit(ctx, proposal.ProposalID, msg.Proposer, msg.InitialDeposit) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -56,16 +56,16 @@ func handleMsgSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSubmitPropos } ctx.EventManager().EmitEvent(submitEvent) - return sdk.Result{ + return &sdk.Result{ Data: GetProposalIDBytes(proposal.ProposalID), Events: ctx.EventManager().Events(), - } + }, nil } -func handleMsgDeposit(ctx sdk.Context, keeper Keeper, msg MsgDeposit) sdk.Result { - err, votingStarted := keeper.AddDeposit(ctx, msg.ProposalID, msg.Depositor, msg.Amount) +func handleMsgDeposit(ctx sdk.Context, keeper Keeper, msg MsgDeposit) (*sdk.Result, error) { + votingStarted, err := keeper.AddDeposit(ctx, msg.ProposalID, msg.Depositor, msg.Amount) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -85,13 +85,13 @@ func handleMsgDeposit(ctx sdk.Context, keeper Keeper, msg MsgDeposit) sdk.Result ) } - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } -func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result { +func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) (*sdk.Result, error) { err := keeper.AddVote(ctx, msg.ProposalID, msg.Voter, msg.Option) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -102,6 +102,5 @@ func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result { ), ) - return sdk.Result{Events: ctx.EventManager().Events()} - + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } diff --git a/x/gov/handler_test.go b/x/gov/handler_test.go index 33dec83ff121..134b25ff0fc5 100644 --- a/x/gov/handler_test.go +++ b/x/gov/handler_test.go @@ -15,7 +15,8 @@ func TestInvalidMsg(t *testing.T) { k := Keeper{} h := NewHandler(k) - res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) - require.False(t, res.IsOK()) - require.True(t, strings.Contains(res.Log, "unrecognized gov message type")) + res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) + require.Error(t, err) + require.Nil(t, res) + require.True(t, strings.Contains(err.Error(), "unrecognized gov message type")) } diff --git a/x/gov/keeper/deposit.go b/x/gov/keeper/deposit.go index 426d43d4f14e..c86df046e5e0 100644 --- a/x/gov/keeper/deposit.go +++ b/x/gov/keeper/deposit.go @@ -4,6 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -93,22 +94,22 @@ func (keeper Keeper) IterateDeposits(ctx sdk.Context, proposalID uint64, cb func // AddDeposit adds or updates a deposit of a specific depositor on a specific proposal // Activates voting period when appropriate -func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (sdk.Error, bool) { +func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (bool, error) { // Checks to see if proposal exists proposal, ok := keeper.GetProposal(ctx, proposalID) if !ok { - return types.ErrUnknownProposal(keeper.codespace, proposalID), false + return false, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) } // Check if proposal is still depositable if (proposal.Status != types.StatusDepositPeriod) && (proposal.Status != types.StatusVotingPeriod) { - return types.ErrInactiveProposal(keeper.codespace, proposalID), false + return false, sdkerrors.Wrapf(types.ErrInactiveProposal, "%d", proposalID) } // update the governance module's account coins pool err := keeper.supplyKeeper.SendCoinsFromAccountToModule(ctx, depositorAddr, types.ModuleName, depositAmount) if err != nil { - return err, false + return false, err } // Update proposal @@ -139,7 +140,7 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAdd ) keeper.SetDeposit(ctx, deposit) - return nil, activatedVotingPeriod + return activatedVotingPeriod, nil } // RefundDeposits refunds and deletes all the deposits on a specific proposal diff --git a/x/gov/keeper/deposit_test.go b/x/gov/keeper/deposit_test.go index c6c229893119..b5d6cce405a2 100644 --- a/x/gov/keeper/deposit_test.go +++ b/x/gov/keeper/deposit_test.go @@ -33,7 +33,7 @@ func TestDeposits(t *testing.T) { require.True(t, proposal.VotingStartTime.Equal(time.Time{})) // Check first deposit - err, votingStarted := keeper.AddDeposit(ctx, proposalID, TestAddrs[0], fourStake) + votingStarted, err := keeper.AddDeposit(ctx, proposalID, TestAddrs[0], fourStake) require.NoError(t, err) require.False(t, votingStarted) deposit, found = keeper.GetDeposit(ctx, proposalID, TestAddrs[0]) @@ -46,7 +46,7 @@ func TestDeposits(t *testing.T) { require.Equal(t, addr0Initial.Sub(fourStake), ak.GetAccount(ctx, TestAddrs[0]).GetCoins()) // Check a second deposit from same address - err, votingStarted = keeper.AddDeposit(ctx, proposalID, TestAddrs[0], fiveStake) + votingStarted, err = keeper.AddDeposit(ctx, proposalID, TestAddrs[0], fiveStake) require.NoError(t, err) require.False(t, votingStarted) deposit, found = keeper.GetDeposit(ctx, proposalID, TestAddrs[0]) @@ -59,7 +59,7 @@ func TestDeposits(t *testing.T) { require.Equal(t, addr0Initial.Sub(fourStake).Sub(fiveStake), ak.GetAccount(ctx, TestAddrs[0]).GetCoins()) // Check third deposit from a new address - err, votingStarted = keeper.AddDeposit(ctx, proposalID, TestAddrs[1], fourStake) + votingStarted, err = keeper.AddDeposit(ctx, proposalID, TestAddrs[1], fourStake) require.NoError(t, err) require.True(t, votingStarted) deposit, found = keeper.GetDeposit(ctx, proposalID, TestAddrs[1]) diff --git a/x/gov/keeper/keeper.go b/x/gov/keeper/keeper.go index b322d3e6b4cd..7a51e6e2bf29 100644 --- a/x/gov/keeper/keeper.go +++ b/x/gov/keeper/keeper.go @@ -29,9 +29,6 @@ type Keeper struct { // The codec codec for binary encoding/decoding. cdc *codec.Codec - // Reserved codespace - codespace sdk.CodespaceType - // Proposal router router types.Router } @@ -45,7 +42,7 @@ type Keeper struct { // CONTRACT: the parameter Subspace must have the param key table already initialized func NewKeeper( cdc *codec.Codec, key sdk.StoreKey, paramSpace types.ParamSubspace, - supplyKeeper types.SupplyKeeper, sk types.StakingKeeper, codespace sdk.CodespaceType, rtr types.Router, + supplyKeeper types.SupplyKeeper, sk types.StakingKeeper, rtr types.Router, ) Keeper { // ensure governance module account is set @@ -64,7 +61,6 @@ func NewKeeper( supplyKeeper: supplyKeeper, sk: sk, cdc: cdc, - codespace: codespace, router: rtr, } } diff --git a/x/gov/keeper/proposal.go b/x/gov/keeper/proposal.go index 2580565d38d4..c5d569314fb2 100644 --- a/x/gov/keeper/proposal.go +++ b/x/gov/keeper/proposal.go @@ -5,13 +5,14 @@ import ( "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/gov/types" ) // SubmitProposal create new proposal given a content -func (keeper Keeper) SubmitProposal(ctx sdk.Context, content types.Content) (types.Proposal, sdk.Error) { +func (keeper Keeper) SubmitProposal(ctx sdk.Context, content types.Content) (types.Proposal, error) { if !keeper.router.HasRoute(content.ProposalRoute()) { - return types.Proposal{}, types.ErrNoProposalHandlerExists(keeper.codespace, content) + return types.Proposal{}, sdkerrors.Wrap(types.ErrNoProposalHandlerExists, content.ProposalRoute()) } // Execute the proposal content in a cache-wrapped context to validate the @@ -20,7 +21,7 @@ func (keeper Keeper) SubmitProposal(ctx sdk.Context, content types.Content) (typ cacheCtx, _ := ctx.CacheContext() handler := keeper.router.GetRoute(content.ProposalRoute()) if err := handler(cacheCtx, content); err != nil { - return types.Proposal{}, types.ErrInvalidProposalContent(keeper.codespace, err.Result().Log) + return types.Proposal{}, sdkerrors.Wrap(types.ErrInvalidProposalContent, err.Error()) } proposalID, err := keeper.GetProposalID(ctx) @@ -149,12 +150,13 @@ func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, params types.QueryPro } // GetProposalID gets the highest proposal ID -func (keeper Keeper) GetProposalID(ctx sdk.Context) (proposalID uint64, err sdk.Error) { +func (keeper Keeper) GetProposalID(ctx sdk.Context) (proposalID uint64, err error) { store := ctx.KVStore(keeper.storeKey) bz := store.Get(types.ProposalIDKey) if bz == nil { - return 0, types.ErrInvalidGenesis(keeper.codespace, "initial proposal ID hasn't been set") + return 0, sdkerrors.Wrap(types.ErrInvalidGenesis, "initial proposal ID hasn't been set") } + proposalID = types.GetProposalIDFromBytes(bz) return proposalID, nil } diff --git a/x/gov/keeper/proposal_test.go b/x/gov/keeper/proposal_test.go index c359f1e5e1c8..67208bef6101 100644 --- a/x/gov/keeper/proposal_test.go +++ b/x/gov/keeper/proposal_test.go @@ -1,6 +1,7 @@ package keeper import ( + "errors" "strings" "testing" "time" @@ -51,12 +52,12 @@ func TestActivateVotingPeriod(t *testing.T) { type validProposal struct{} -func (validProposal) GetTitle() string { return "title" } -func (validProposal) GetDescription() string { return "description" } -func (validProposal) ProposalRoute() string { return types.RouterKey } -func (validProposal) ProposalType() string { return types.ProposalTypeText } -func (validProposal) String() string { return "" } -func (validProposal) ValidateBasic() sdk.Error { return nil } +func (validProposal) GetTitle() string { return "title" } +func (validProposal) GetDescription() string { return "description" } +func (validProposal) ProposalRoute() string { return types.RouterKey } +func (validProposal) ProposalType() string { return types.ProposalTypeText } +func (validProposal) String() string { return "" } +func (validProposal) ValidateBasic() error { return nil } type invalidProposalTitle1 struct{ validProposal } @@ -80,8 +81,8 @@ func (invalidProposalRoute) ProposalRoute() string { return "nonexistingroute" } type invalidProposalValidation struct{ validProposal } -func (invalidProposalValidation) ValidateBasic() sdk.Error { - return sdk.NewError(sdk.CodespaceUndefined, sdk.CodeInternal, "") +func (invalidProposalValidation) ValidateBasic() error { + return errors.New("invalid proposal") } func registerTestCodec(cdc *codec.Codec) { @@ -101,7 +102,7 @@ func TestSubmitProposal(t *testing.T) { testCases := []struct { content types.Content - expectedErr sdk.Error + expectedErr error }{ {validProposal{}, nil}, // Keeper does not check the validity of title and description, no error @@ -110,14 +111,14 @@ func TestSubmitProposal(t *testing.T) { {invalidProposalDesc1{}, nil}, {invalidProposalDesc2{}, nil}, // error only when invalid route - {invalidProposalRoute{}, types.ErrNoProposalHandlerExists(types.DefaultCodespace, invalidProposalRoute{})}, + {invalidProposalRoute{}, types.ErrNoProposalHandlerExists}, // Keeper does not call ValidateBasic, msg.ValidateBasic does {invalidProposalValidation{}, nil}, } - for _, tc := range testCases { + for i, tc := range testCases { _, err := keeper.SubmitProposal(ctx, tc.content) - require.Equal(t, tc.expectedErr, err, "unexpected type of error: %s", err) + require.True(t, errors.Is(tc.expectedErr, err), "tc #%d; got: %v, expected: %v", i, err, tc.expectedErr) } } diff --git a/x/gov/keeper/querier.go b/x/gov/keeper/querier.go index b5efc7619b05..9545e5e29b83 100644 --- a/x/gov/keeper/querier.go +++ b/x/gov/keeper/querier.go @@ -1,19 +1,18 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/gov/types" ) // NewQuerier creates a new gov Querier instance func NewQuerier(keeper Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryParams: return queryParams(ctx, path[1:], req, keeper) @@ -40,94 +39,100 @@ func NewQuerier(keeper Keeper) sdk.Querier { return queryTally(ctx, path[1:], req, keeper) default: - return nil, sdk.ErrUnknownRequest("unknown gov query endpoint") + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) } } } -func queryParams(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryParams(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { switch path[0] { case types.ParamDeposit: bz, err := codec.MarshalJSONIndent(keeper.cdc, keeper.GetDepositParams(ctx)) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil + case types.ParamVoting: bz, err := codec.MarshalJSONIndent(keeper.cdc, keeper.GetVotingParams(ctx)) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil + case types.ParamTallying: bz, err := codec.MarshalJSONIndent(keeper.cdc, keeper.GetTallyParams(ctx)) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil + default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("%s is not a valid query request path", req.Path)) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "%s is not a valid query request path", req.Path) } } // nolint: unparam -func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryProposalParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } proposal, ok := keeper.GetProposal(ctx, params.ProposalID) if !ok { - return nil, types.ErrUnknownProposal(types.DefaultCodespace, params.ProposalID) + return nil, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", params.ProposalID) } bz, err := codec.MarshalJSONIndent(keeper.cdc, proposal) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } // nolint: unparam -func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryDepositParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } deposit, _ := keeper.GetDeposit(ctx, params.ProposalID, params.Depositor) bz, err := codec.MarshalJSONIndent(keeper.cdc, deposit) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } // nolint: unparam -func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryVoteParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } vote, _ := keeper.GetVote(ctx, params.ProposalID, params.Voter) bz, err := codec.MarshalJSONIndent(keeper.cdc, vote) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } // nolint: unparam -func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryProposalParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } deposits := keeper.GetDeposits(ctx, params.ProposalID) @@ -137,24 +142,25 @@ func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper bz, err := codec.MarshalJSONIndent(keeper.cdc, deposits) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } // nolint: unparam -func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryProposalParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } proposalID := params.ProposalID proposal, ok := keeper.GetProposal(ctx, proposalID) if !ok { - return nil, types.ErrUnknownProposal(types.DefaultCodespace, proposalID) + return nil, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) } var tallyResult types.TallyResult @@ -162,8 +168,10 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke switch { case proposal.Status == types.StatusDepositPeriod: tallyResult = types.EmptyTallyResult() + case proposal.Status == types.StatusPassed || proposal.Status == types.StatusRejected: tallyResult = proposal.FinalTallyResult + default: // proposal is in voting period _, _, tallyResult = keeper.Tally(ctx, proposal) @@ -171,18 +179,18 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke bz, err := codec.MarshalJSONIndent(keeper.cdc, tallyResult) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } // nolint: unparam -func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryProposalVotesParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } votes := keeper.GetVotes(ctx, params.ProposalID) @@ -199,17 +207,17 @@ func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke bz, err := codec.MarshalJSONIndent(keeper.cdc, votes) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return bz, nil } -func queryProposals(ctx sdk.Context, _ []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryProposals(ctx sdk.Context, _ []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryProposalsParams - err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("failed to parse params", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } proposals := keeper.GetProposalsFiltered(ctx, params) @@ -219,7 +227,7 @@ func queryProposals(ctx sdk.Context, _ []string, req abci.RequestQuery, keeper K bz, err := codec.MarshalJSONIndent(keeper.cdc, proposals) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to JSON marshal result: %s", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil diff --git a/x/gov/keeper/querier_test.go b/x/gov/keeper/querier_test.go index a5f781da1807..b8cce877608c 100644 --- a/x/gov/keeper/querier_test.go +++ b/x/gov/keeper/querier_test.go @@ -156,7 +156,7 @@ func TestQueries(t *testing.T) { proposal1, err := keeper.SubmitProposal(ctx, tp) require.NoError(t, err) deposit1 := types.NewDeposit(proposal1.ProposalID, TestAddrs[0], oneCoins) - err, _ = keeper.AddDeposit(ctx, deposit1.ProposalID, deposit1.Depositor, deposit1.Amount) + _, err = keeper.AddDeposit(ctx, deposit1.ProposalID, deposit1.Depositor, deposit1.Amount) require.NoError(t, err) proposal1.TotalDeposit = proposal1.TotalDeposit.Add(deposit1.Amount) @@ -164,7 +164,7 @@ func TestQueries(t *testing.T) { proposal2, err := keeper.SubmitProposal(ctx, tp) require.NoError(t, err) deposit2 := types.NewDeposit(proposal2.ProposalID, TestAddrs[0], consCoins) - err, _ = keeper.AddDeposit(ctx, deposit2.ProposalID, deposit2.Depositor, deposit2.Amount) + _, err = keeper.AddDeposit(ctx, deposit2.ProposalID, deposit2.Depositor, deposit2.Amount) require.NoError(t, err) proposal2.TotalDeposit = proposal2.TotalDeposit.Add(deposit2.Amount) @@ -173,14 +173,14 @@ func TestQueries(t *testing.T) { proposal3, err := keeper.SubmitProposal(ctx, tp) require.NoError(t, err) deposit3 := types.NewDeposit(proposal3.ProposalID, TestAddrs[1], oneCoins) - err, _ = keeper.AddDeposit(ctx, deposit3.ProposalID, deposit3.Depositor, deposit3.Amount) + _, err = keeper.AddDeposit(ctx, deposit3.ProposalID, deposit3.Depositor, deposit3.Amount) require.NoError(t, err) proposal3.TotalDeposit = proposal3.TotalDeposit.Add(deposit3.Amount) // TestAddrs[1] deposits on proposals #2 & #3 deposit4 := types.NewDeposit(proposal2.ProposalID, TestAddrs[1], depositParams.MinDeposit) - err, _ = keeper.AddDeposit(ctx, deposit4.ProposalID, deposit4.Depositor, deposit4.Amount) + _, err = keeper.AddDeposit(ctx, deposit4.ProposalID, deposit4.Depositor, deposit4.Amount) require.NoError(t, err) proposal2.TotalDeposit = proposal2.TotalDeposit.Add(deposit4.Amount) @@ -188,7 +188,7 @@ func TestQueries(t *testing.T) { proposal2.VotingEndTime = proposal2.VotingEndTime.Add(types.DefaultPeriod) deposit5 := types.NewDeposit(proposal3.ProposalID, TestAddrs[1], depositParams.MinDeposit) - err, _ = keeper.AddDeposit(ctx, deposit5.ProposalID, deposit5.Depositor, deposit5.Amount) + _, err = keeper.AddDeposit(ctx, deposit5.ProposalID, deposit5.Depositor, deposit5.Amount) require.NoError(t, err) proposal3.TotalDeposit = proposal3.TotalDeposit.Add(deposit5.Amount) diff --git a/x/gov/keeper/test_common.go b/x/gov/keeper/test_common.go index 781964a206d5..777d71a8c887 100644 --- a/x/gov/keeper/test_common.go +++ b/x/gov/keeper/test_common.go @@ -139,19 +139,19 @@ func createTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context blacklistedAddrs[notBondedPool.GetAddress().String()] = true blacklistedAddrs[bondPool.GetAddress().String()] = true - pk := params.NewKeeper(cdc, keyParams, tkeyParams, params.DefaultCodespace) + pk := params.NewKeeper(cdc, keyParams, tkeyParams) accountKeeper := auth.NewAccountKeeper(cdc, keyAcc, pk.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount) - bankKeeper := bank.NewBaseKeeper(accountKeeper, pk.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs) + bankKeeper := bank.NewBaseKeeper(accountKeeper, pk.Subspace(bank.DefaultParamspace), blacklistedAddrs) supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bankKeeper, maccPerms) - sk := staking.NewKeeper(cdc, keyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace), staking.DefaultCodespace) + sk := staking.NewKeeper(cdc, keyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace)) sk.SetParams(ctx, staking.DefaultParams()) rtr := types.NewRouter(). AddRoute(types.RouterKey, types.ProposalHandler) keeper := NewKeeper( - cdc, keyGov, pk.Subspace(types.DefaultParamspace).WithKeyTable(types.ParamKeyTable()), supplyKeeper, sk, types.DefaultCodespace, rtr, + cdc, keyGov, pk.Subspace(types.DefaultParamspace).WithKeyTable(types.ParamKeyTable()), supplyKeeper, sk, rtr, ) keeper.SetProposalID(ctx, types.DefaultStartingProposalID) diff --git a/x/gov/keeper/vote.go b/x/gov/keeper/vote.go index 0204e56be273..309446714287 100644 --- a/x/gov/keeper/vote.go +++ b/x/gov/keeper/vote.go @@ -4,21 +4,22 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/gov/types" ) // AddVote adds a vote on a specific proposal -func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress, option types.VoteOption) sdk.Error { +func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress, option types.VoteOption) error { proposal, ok := keeper.GetProposal(ctx, proposalID) if !ok { - return types.ErrUnknownProposal(keeper.codespace, proposalID) + return sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) } if proposal.Status != types.StatusVotingPeriod { - return types.ErrInactiveProposal(keeper.codespace, proposalID) + return sdkerrors.Wrapf(types.ErrInactiveProposal, "%d", proposalID) } if !types.ValidVoteOption(option) { - return types.ErrInvalidVote(keeper.codespace, option.String()) + return sdkerrors.Wrap(types.ErrInvalidVote, option.String()) } vote := types.NewVote(proposalID, voterAddr, option) diff --git a/x/gov/legacy/v0_36/types.go b/x/gov/legacy/v0_36/types.go index f18cddac1c50..faaaa4e32171 100644 --- a/x/gov/legacy/v0_36/types.go +++ b/x/gov/legacy/v0_36/types.go @@ -16,14 +16,10 @@ const ( ModuleName = "gov" RouterKey = ModuleName - DefaultCodespace sdk.CodespaceType = "gov" - ProposalTypeText string = "Text" MaxDescriptionLength int = 5000 MaxTitleLength int = 140 - - CodeInvalidContent sdk.CodeType = 6 ) var ( @@ -44,7 +40,7 @@ type ( GetDescription() string ProposalRoute() string ProposalType() string - ValidateBasic() sdk.Error + ValidateBasic() error String() string } @@ -94,11 +90,11 @@ func NewTextProposal(title, description string) Content { return TextProposal{title, description} } -func (tp TextProposal) GetTitle() string { return tp.Title } -func (tp TextProposal) GetDescription() string { return tp.Description } -func (tp TextProposal) ProposalRoute() string { return RouterKey } -func (tp TextProposal) ProposalType() string { return ProposalTypeText } -func (tp TextProposal) ValidateBasic() sdk.Error { return ValidateAbstract(DefaultCodespace, tp) } +func (tp TextProposal) GetTitle() string { return tp.Title } +func (tp TextProposal) GetDescription() string { return tp.Description } +func (tp TextProposal) ProposalRoute() string { return RouterKey } +func (tp TextProposal) ProposalType() string { return ProposalTypeText } +func (tp TextProposal) ValidateBasic() error { return ValidateAbstract(tp) } func (tp TextProposal) String() string { return fmt.Sprintf(`Text Proposal: @@ -107,25 +103,25 @@ func (tp TextProposal) String() string { `, tp.Title, tp.Description) } -func ErrInvalidProposalContent(cs sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(cs, CodeInvalidContent, fmt.Sprintf("invalid proposal content: %s", msg)) +func ErrInvalidProposalContent(msg string) error { + return fmt.Errorf("invalid proposal content: %s", msg) } -func ValidateAbstract(codespace sdk.CodespaceType, c Content) sdk.Error { +func ValidateAbstract(c Content) error { title := c.GetTitle() if len(strings.TrimSpace(title)) == 0 { - return ErrInvalidProposalContent(codespace, "proposal title cannot be blank") + return ErrInvalidProposalContent("proposal title cannot be blank") } if len(title) > MaxTitleLength { - return ErrInvalidProposalContent(codespace, fmt.Sprintf("proposal title is longer than max length of %d", MaxTitleLength)) + return ErrInvalidProposalContent(fmt.Sprintf("proposal title is longer than max length of %d", MaxTitleLength)) } description := c.GetDescription() if len(description) == 0 { - return ErrInvalidProposalContent(codespace, "proposal description cannot be blank") + return ErrInvalidProposalContent("proposal description cannot be blank") } if len(description) > MaxDescriptionLength { - return ErrInvalidProposalContent(codespace, fmt.Sprintf("proposal description is longer than max length of %d", MaxDescriptionLength)) + return ErrInvalidProposalContent(fmt.Sprintf("proposal description is longer than max length of %d", MaxDescriptionLength)) } return nil diff --git a/x/gov/simulation/operations.go b/x/gov/simulation/operations.go index 0e0bcd06f600..b53a97350146 100644 --- a/x/gov/simulation/operations.go +++ b/x/gov/simulation/operations.go @@ -1,7 +1,6 @@ package simulation import ( - "errors" "math" "math/rand" "time" @@ -148,9 +147,9 @@ func SimulateSubmitProposal( simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } opMsg := simulation.NewOperationMsg(msg, true, "") @@ -231,9 +230,9 @@ func SimulateMsgDeposit(ak types.AccountKeeper, k keeper.Keeper) simulation.Oper simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil @@ -289,9 +288,9 @@ func operationSimulateMsgVote(ak types.AccountKeeper, k keeper.Keeper, simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil diff --git a/x/gov/test_common.go b/x/gov/test_common.go index 36479f7fa0c2..7ecd4bd50f68 100644 --- a/x/gov/test_common.go +++ b/x/gov/test_common.go @@ -4,7 +4,7 @@ package gov import ( "bytes" - "fmt" + "errors" "log" "sort" "testing" @@ -16,6 +16,7 @@ import ( "github.com/tendermint/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/bank" keep "github.com/cosmos/cosmos-sdk/x/gov/keeper" @@ -43,8 +44,11 @@ type testInput struct { privKeys []crypto.PrivKey } -func getMockApp(t *testing.T, numGenAccs int, genState types.GenesisState, genAccs []authexported.Account, - handler func(ctx sdk.Context, c types.Content) sdk.Error) testInput { +func getMockApp( + t *testing.T, numGenAccs int, genState types.GenesisState, genAccs []authexported.Account, + handler func(ctx sdk.Context, c types.Content) error, +) testInput { + mApp := mock.NewApp() staking.RegisterCodec(mApp.Cdc) @@ -69,7 +73,7 @@ func getMockApp(t *testing.T, numGenAccs int, genState types.GenesisState, genAc rtr := types.NewRouter(). AddRoute(types.RouterKey, handler) - bk := bank.NewBaseKeeper(mApp.AccountKeeper, mApp.ParamsKeeper.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs) + bk := bank.NewBaseKeeper(mApp.AccountKeeper, mApp.ParamsKeeper.Subspace(bank.DefaultParamspace), blacklistedAddrs) maccPerms := map[string][]string{ types.ModuleName: {supply.Burner}, @@ -78,11 +82,11 @@ func getMockApp(t *testing.T, numGenAccs int, genState types.GenesisState, genAc } supplyKeeper := supply.NewKeeper(mApp.Cdc, keySupply, mApp.AccountKeeper, bk, maccPerms) sk := staking.NewKeeper( - mApp.Cdc, keyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace), staking.DefaultCodespace, + mApp.Cdc, keyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace), ) keeper := keep.NewKeeper( - mApp.Cdc, keyGov, pk.Subspace(DefaultParamspace).WithKeyTable(ParamKeyTable()), supplyKeeper, sk, types.DefaultCodespace, rtr, + mApp.Cdc, keyGov, pk.Subspace(DefaultParamspace).WithKeyTable(ParamKeyTable()), supplyKeeper, sk, rtr, ) mApp.Router().AddRoute(types.RouterKey, NewHandler(keeper)) @@ -193,20 +197,19 @@ const contextKeyBadProposal = "contextKeyBadProposal" // badProposalHandler implements a governance proposal handler that is identical // to the actual handler except this fails if the context doesn't contain a value // for the key contextKeyBadProposal or if the value is false. -func badProposalHandler(ctx sdk.Context, c types.Content) sdk.Error { +func badProposalHandler(ctx sdk.Context, c types.Content) error { switch c.ProposalType() { case types.ProposalTypeText: v := ctx.Value(contextKeyBadProposal) if v == nil || !v.(bool) { - return sdk.ErrInternal("proposal failed") + return errors.New("proposal failed") } return nil default: - msg := fmt.Sprintf("unrecognized gov proposal type: %s", c.ProposalType()) - return sdk.ErrUnknownRequest(msg) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized gov proposal type: %s", c.ProposalType()) } } @@ -229,7 +232,8 @@ func createValidators(t *testing.T, stakingHandler sdk.Handler, ctx sdk.Context, keep.TestDescription, keep.TestCommissionRates, sdk.OneInt(), ) - res := stakingHandler(ctx, valCreateMsg) - require.True(t, res.IsOK()) + res, err := stakingHandler(ctx, valCreateMsg) + require.NoError(t, err) + require.NotNil(t, res) } } diff --git a/x/gov/types/content.go b/x/gov/types/content.go index 22a7f7a4af62..21d70d5ab1e8 100644 --- a/x/gov/types/content.go +++ b/x/gov/types/content.go @@ -1,10 +1,10 @@ package types import ( - "fmt" "strings" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // Constants pertaining to a Content object @@ -22,31 +22,31 @@ type Content interface { GetDescription() string ProposalRoute() string ProposalType() string - ValidateBasic() sdk.Error + ValidateBasic() error String() string } // Handler defines a function that handles a proposal after it has passed the // governance process. -type Handler func(ctx sdk.Context, content Content) sdk.Error +type Handler func(ctx sdk.Context, content Content) error // ValidateAbstract validates a proposal's abstract contents returning an error // if invalid. -func ValidateAbstract(codespace sdk.CodespaceType, c Content) sdk.Error { +func ValidateAbstract(c Content) error { title := c.GetTitle() if len(strings.TrimSpace(title)) == 0 { - return ErrInvalidProposalContent(codespace, "proposal title cannot be blank") + return sdkerrors.Wrap(ErrInvalidProposalContent, "proposal title cannot be blank") } if len(title) > MaxTitleLength { - return ErrInvalidProposalContent(codespace, fmt.Sprintf("proposal title is longer than max length of %d", MaxTitleLength)) + return sdkerrors.Wrapf(ErrInvalidProposalContent, "proposal title is longer than max length of %d", MaxTitleLength) } description := c.GetDescription() if len(description) == 0 { - return ErrInvalidProposalContent(codespace, "proposal description cannot be blank") + return sdkerrors.Wrap(ErrInvalidProposalContent, "proposal description cannot be blank") } if len(description) > MaxDescriptionLength { - return ErrInvalidProposalContent(codespace, fmt.Sprintf("proposal description is longer than max length of %d", MaxDescriptionLength)) + return sdkerrors.Wrapf(ErrInvalidProposalContent, "proposal description is longer than max length of %d", MaxDescriptionLength) } return nil diff --git a/x/gov/types/errors.go b/x/gov/types/errors.go index dfc7bf5a4596..2327a6f05b5e 100644 --- a/x/gov/types/errors.go +++ b/x/gov/types/errors.go @@ -1,66 +1,17 @@ package types -// DONTCOVER - import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// Codes for governance errors -const ( - DefaultCodespace sdk.CodespaceType = ModuleName - - CodeUnknownProposal sdk.CodeType = 1 - CodeInactiveProposal sdk.CodeType = 2 - CodeAlreadyActiveProposal sdk.CodeType = 3 - CodeAlreadyFinishedProposal sdk.CodeType = 4 - CodeAddressNotStaked sdk.CodeType = 5 - CodeInvalidContent sdk.CodeType = 6 - CodeInvalidProposalType sdk.CodeType = 7 - CodeInvalidVote sdk.CodeType = 8 - CodeInvalidGenesis sdk.CodeType = 9 - CodeInvalidProposalStatus sdk.CodeType = 10 - CodeProposalHandlerNotExists sdk.CodeType = 11 +// x/gov module sentinel errors +var ( + ErrUnknownProposal = sdkerrors.Register(ModuleName, 1, "unknown proposal") + ErrInactiveProposal = sdkerrors.Register(ModuleName, 2, "inactive proposal") + ErrAlreadyActiveProposal = sdkerrors.Register(ModuleName, 3, "proposal already active") + ErrInvalidProposalContent = sdkerrors.Register(ModuleName, 4, "invalid proposal content") + ErrInvalidProposalType = sdkerrors.Register(ModuleName, 5, "invalid proposal type") + ErrInvalidVote = sdkerrors.Register(ModuleName, 6, "invalid vote option") + ErrInvalidGenesis = sdkerrors.Register(ModuleName, 7, "invalid genesis state") + ErrNoProposalHandlerExists = sdkerrors.Register(ModuleName, 8, "no handler exists for proposal type") ) - -// ErrUnknownProposal error for unknown proposals -func ErrUnknownProposal(codespace sdk.CodespaceType, proposalID uint64) sdk.Error { - return sdk.NewError(codespace, CodeUnknownProposal, fmt.Sprintf("unknown proposal with id %d", proposalID)) -} - -// ErrInactiveProposal error for inactive (i.e finalized) proposals -func ErrInactiveProposal(codespace sdk.CodespaceType, proposalID uint64) sdk.Error { - return sdk.NewError(codespace, CodeInactiveProposal, fmt.Sprintf("inactive proposal with id %d", proposalID)) -} - -// ErrAlreadyActiveProposal error for proposals that are already active -func ErrAlreadyActiveProposal(codespace sdk.CodespaceType, proposalID uint64) sdk.Error { - return sdk.NewError(codespace, CodeAlreadyActiveProposal, fmt.Sprintf("proposal %d has been already active", proposalID)) -} - -// ErrInvalidProposalContent error for invalid proposal title or description -func ErrInvalidProposalContent(cs sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(cs, CodeInvalidContent, fmt.Sprintf("invalid proposal content: %s", msg)) -} - -// ErrInvalidProposalType error for non registered proposal types -func ErrInvalidProposalType(codespace sdk.CodespaceType, proposalType string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidProposalType, fmt.Sprintf("proposal type '%s' is not valid", proposalType)) -} - -// ErrInvalidVote error for an invalid vote option -func ErrInvalidVote(codespace sdk.CodespaceType, voteOption string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidVote, fmt.Sprintf("'%v' is not a valid voting option", voteOption)) -} - -// ErrInvalidGenesis error for an invalid governance GenesisState -func ErrInvalidGenesis(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidVote, msg) -} - -// ErrNoProposalHandlerExists error when proposal handler is not defined -func ErrNoProposalHandlerExists(codespace sdk.CodespaceType, content interface{}) sdk.Error { - return sdk.NewError(codespace, CodeProposalHandlerNotExists, fmt.Sprintf("'%T' does not have a corresponding handler", content)) -} diff --git a/x/gov/types/expected_keepers.go b/x/gov/types/expected_keepers.go index c0fda62d61fe..31e5d1e05cff 100644 --- a/x/gov/types/expected_keepers.go +++ b/x/gov/types/expected_keepers.go @@ -21,21 +21,23 @@ type SupplyKeeper interface { // TODO remove with genesis 2-phases refactor https://github.com/cosmos/cosmos-sdk/issues/2862 SetModuleAccount(sdk.Context, supplyexported.ModuleAccountI) - SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error - BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) sdk.Error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error } // StakingKeeper expected staking keeper (Validator and Delegator sets) (noalias) type StakingKeeper interface { // iterate through bonded validators by operator address, execute func for each validator - IterateBondedValidatorsByPower(sdk.Context, - func(index int64, validator stakingexported.ValidatorI) (stop bool)) + IterateBondedValidatorsByPower( + sdk.Context, func(index int64, validator stakingexported.ValidatorI) (stop bool), + ) TotalBondedTokens(sdk.Context) sdk.Int // total bonded tokens within the validator set - - IterateDelegations(ctx sdk.Context, delegator sdk.AccAddress, - fn func(index int64, delegation stakingexported.DelegationI) (stop bool)) + IterateDelegations( + ctx sdk.Context, delegator sdk.AccAddress, + fn func(index int64, delegation stakingexported.DelegationI) (stop bool), + ) } // AccountKeeper defines the expected account keeper (noalias) diff --git a/x/gov/types/msgs.go b/x/gov/types/msgs.go index b5b85ca167ea..882e0c560c31 100644 --- a/x/gov/types/msgs.go +++ b/x/gov/types/msgs.go @@ -4,6 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // Governance message types and routes @@ -35,21 +36,21 @@ func (msg MsgSubmitProposal) Route() string { return RouterKey } func (msg MsgSubmitProposal) Type() string { return TypeMsgSubmitProposal } // ValidateBasic implements Msg -func (msg MsgSubmitProposal) ValidateBasic() sdk.Error { +func (msg MsgSubmitProposal) ValidateBasic() error { if msg.Content == nil { - return ErrInvalidProposalContent(DefaultCodespace, "missing content") + return sdkerrors.Wrap(ErrInvalidProposalContent, "missing content") } if msg.Proposer.Empty() { - return sdk.ErrInvalidAddress(msg.Proposer.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Proposer.String()) } if !msg.InitialDeposit.IsValid() { - return sdk.ErrInvalidCoins(msg.InitialDeposit.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.InitialDeposit.String()) } if msg.InitialDeposit.IsAnyNegative() { - return sdk.ErrInvalidCoins(msg.InitialDeposit.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.InitialDeposit.String()) } if !IsValidProposalType(msg.Content.ProposalType()) { - return ErrInvalidProposalType(DefaultCodespace, msg.Content.ProposalType()) + return sdkerrors.Wrap(ErrInvalidProposalType, msg.Content.ProposalType()) } return msg.Content.ValidateBasic() @@ -93,15 +94,15 @@ func (msg MsgDeposit) Route() string { return RouterKey } func (msg MsgDeposit) Type() string { return TypeMsgDeposit } // ValidateBasic implements Msg -func (msg MsgDeposit) ValidateBasic() sdk.Error { +func (msg MsgDeposit) ValidateBasic() error { if msg.Depositor.Empty() { - return sdk.ErrInvalidAddress(msg.Depositor.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Depositor.String()) } if !msg.Amount.IsValid() { - return sdk.ErrInvalidCoins(msg.Amount.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String()) } if msg.Amount.IsAnyNegative() { - return sdk.ErrInvalidCoins(msg.Amount.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String()) } return nil @@ -146,12 +147,12 @@ func (msg MsgVote) Route() string { return RouterKey } func (msg MsgVote) Type() string { return TypeMsgVote } // ValidateBasic implements Msg -func (msg MsgVote) ValidateBasic() sdk.Error { +func (msg MsgVote) ValidateBasic() error { if msg.Voter.Empty() { - return sdk.ErrInvalidAddress(msg.Voter.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Voter.String()) } if !ValidVoteOption(msg.Option) { - return ErrInvalidVote(DefaultCodespace, msg.Option.String()) + return sdkerrors.Wrap(ErrInvalidVote, msg.Option.String()) } return nil diff --git a/x/gov/types/proposal.go b/x/gov/types/proposal.go index a02f7b54d6b9..945cf786687b 100644 --- a/x/gov/types/proposal.go +++ b/x/gov/types/proposal.go @@ -7,6 +7,7 @@ import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // DefaultStartingProposalID is 1 @@ -232,7 +233,7 @@ func (tp TextProposal) ProposalRoute() string { return RouterKey } func (tp TextProposal) ProposalType() string { return ProposalTypeText } // ValidateBasic validates the content's title and description of the proposal -func (tp TextProposal) ValidateBasic() sdk.Error { return ValidateAbstract(DefaultCodespace, tp) } +func (tp TextProposal) ValidateBasic() error { return ValidateAbstract(tp) } // String implements Stringer interface func (tp TextProposal) String() string { @@ -280,14 +281,13 @@ func IsValidProposalType(ty string) bool { // proposals (ie. TextProposal ). Since these are // merely signaling mechanisms at the moment and do not affect state, it // performs a no-op. -func ProposalHandler(_ sdk.Context, c Content) sdk.Error { +func ProposalHandler(_ sdk.Context, c Content) error { switch c.ProposalType() { case ProposalTypeText: // both proposal types do not change state so this performs a no-op return nil default: - errMsg := fmt.Sprintf("unrecognized gov proposal type: %s", c.ProposalType()) - return sdk.ErrUnknownRequest(errMsg) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized gov proposal type: %s", c.ProposalType()) } } diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go index 02f3aa623668..d818bbb99572 100644 --- a/x/ibc/02-client/alias.go +++ b/x/ibc/02-client/alias.go @@ -13,26 +13,15 @@ import ( ) const ( - DefaultCodespace = errors.DefaultCodespace - CodeClientExists = errors.CodeClientExists - CodeClientNotFound = errors.CodeClientNotFound - CodeClientFrozen = errors.CodeClientFrozen - CodeConsensusStateNotFound = errors.CodeConsensusStateNotFound - CodeInvalidConsensusState = errors.CodeInvalidConsensusState - CodeClientTypeNotFound = errors.CodeClientTypeNotFound - CodeInvalidClientType = errors.CodeInvalidClientType - CodeRootNotFound = errors.CodeRootNotFound - CodeInvalidHeader = errors.CodeInvalidHeader - CodeInvalidEvidence = errors.CodeInvalidEvidence - AttributeKeyClientID = types.AttributeKeyClientID - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - QueryAllClients = types.QueryAllClients - QueryClientState = types.QueryClientState - QueryConsensusState = types.QueryConsensusState - QueryVerifiedRoot = types.QueryVerifiedRoot + AttributeKeyClientID = types.AttributeKeyClientID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryAllClients = types.QueryAllClients + QueryClientState = types.QueryClientState + QueryConsensusState = types.QueryConsensusState + QueryVerifiedRoot = types.QueryVerifiedRoot ) var ( diff --git a/x/ibc/02-client/client/cli/cli.go b/x/ibc/02-client/client/cli/cli.go index d2db4d2be958..4a36894faf35 100644 --- a/x/ibc/02-client/client/cli/cli.go +++ b/x/ibc/02-client/client/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) @@ -16,7 +16,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { SuggestionsMinimumDistance: 2, } - ics02ClientQueryCmd.AddCommand(client.GetCommands( + ics02ClientQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryClientStates(queryRoute, cdc), GetCmdQueryClientState(queryRoute, cdc), GetCmdQueryConsensusState(queryRoute, cdc), @@ -37,7 +37,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { SuggestionsMinimumDistance: 2, } - ics02ClientTxCmd.AddCommand(client.PostCommands( + ics02ClientTxCmd.AddCommand(flags.PostCommands( GetCmdCreateClient(cdc), GetCmdUpdateClient(cdc), )...) diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 848d489b2308..02f1163b3d32 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -6,7 +6,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" @@ -62,10 +61,10 @@ func QueryClientState( return clientStateRes, nil } -// QueryConsensusStateProof queries the store to get the consensus state and a -// merkle proof. +// QueryConsensusState queries the store to get the consensus state and a merkle +// proof. func QueryConsensusState( - cliCtx client.CLIContext, clientID string, prove bool) (types.ConsensusStateResponse, error) { + cliCtx context.CLIContext, clientID string, prove bool) (types.ConsensusStateResponse, error) { var conStateRes types.ConsensusStateResponse req := abci.RequestQuery{ diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index 7363053f2319..0525e115a014 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -1,9 +1,8 @@ package client import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/evidence" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" @@ -11,17 +10,15 @@ import ( ) // HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient -func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.Result { +func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) (*sdk.Result, error) { clientType := exported.ClientTypeFromString(msg.ClientType) if clientType == 0 { - return sdk.ResultFromError( - ErrInvalidClientType(DefaultCodespace, fmt.Sprintf("invalid client type '%s'", msg.ClientType)), - ) + return nil, sdkerrors.Wrap(ErrInvalidClientType, msg.ClientType) } _, err := k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -36,14 +33,16 @@ func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.R ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgUpdateClient defines the sdk.Handler for MsgUpdateClient -func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) sdk.Result { +func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) (*sdk.Result, error) { err := k.UpdateClient(ctx, msg.ClientID, msg.Header) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -58,7 +57,9 @@ func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) sdk.R ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandlerClientMisbehaviour defines the Evidence module handler for submitting a @@ -70,8 +71,7 @@ func HandlerClientMisbehaviour(k Keeper) evidence.Handler { return k.CheckMisbehaviourAndUpdateState(ctx, evidence) default: - errMsg := fmt.Sprintf("unrecognized IBC client evidence type: %T", e) - return sdk.ErrUnknownRequest(errMsg) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized IBC client evidence type: %T", e) } } } diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index 9b72ef4a2c2c..91cadfe4a016 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -20,7 +20,7 @@ func (k Keeper) CreateClient( ) (types.State, error) { _, found := k.GetClientState(ctx, clientID) if found { - return types.State{}, errors.ErrClientExists(k.codespace, clientID) + return types.State{}, sdkerrors.Wrapf(errors.ErrClientExists, "cannot create client with ID %s", clientID) } _, found = k.GetClientType(ctx, clientID) @@ -41,31 +41,31 @@ func (k Keeper) CreateClient( func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) error { clientType, found := k.GetClientType(ctx, clientID) if !found { - return sdkerrors.Wrap(errors.ErrClientTypeNotFound(k.codespace), "cannot update client") + return sdkerrors.Wrapf(errors.ErrClientTypeNotFound, "cannot update client with ID %s", clientID) } // check that the header consensus matches the client one if header.ClientType() != clientType { - return sdkerrors.Wrap(errors.ErrInvalidConsensus(k.codespace), "cannot update client") + return sdkerrors.Wrapf(errors.ErrInvalidConsensus, "cannot update client with ID %s", clientID) } clientState, found := k.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(errors.ErrClientNotFound(k.codespace, clientID), "cannot update client") + return sdkerrors.Wrapf(errors.ErrClientNotFound, "cannot update client with ID %s", clientID) } if clientState.Frozen { - return sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientID), "cannot update client") + return sdkerrors.Wrapf(errors.ErrClientFrozen, "cannot update client with ID %s", clientID) } consensusState, found := k.GetConsensusState(ctx, clientID) if !found { - return sdkerrors.Wrap(errors.ErrConsensusStateNotFound(k.codespace), "cannot update client") + return sdkerrors.Wrapf(errors.ErrConsensusStateNotFound, "cannot update client with ID %s", clientID) } consensusState, err := consensusState.CheckValidityAndUpdateState(header) if err != nil { - return sdkerrors.Wrap(err, "cannot update client") + return sdkerrors.Wrapf(err, "cannot update client with ID %s", clientID) } k.SetConsensusState(ctx, clientID, consensusState) @@ -83,25 +83,25 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, evidence evidenceexported.Evidence) error { misbehaviour, ok := evidence.(tendermint.Misbehaviour) if !ok { - return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint") + return sdkerrors.Wrap(errors.ErrInvalidClientType, "consensus type is not Tendermint") } clientState, found := k.GetClientState(ctx, misbehaviour.ClientID) if !found { - return errors.ErrClientNotFound(k.codespace, misbehaviour.ClientID) + return sdkerrors.Wrap(errors.ErrClientNotFound, misbehaviour.ClientID) } committer, found := k.GetCommitter(ctx, misbehaviour.ClientID, uint64(misbehaviour.GetHeight())) if !found { - return errors.ErrCommitterNotFound(k.codespace, fmt.Sprintf("committer not found for height %d", misbehaviour.GetHeight())) + return errors.ErrCommitterNotFound } tmCommitter, ok := committer.(tendermint.Committer) if !ok { - return errors.ErrInvalidCommitter(k.codespace, "committer type is not Tendermint") + return sdkerrors.Wrap(errors.ErrInvalidCommitter, "committer type is not Tendermint") } if err := tendermint.CheckMisbehaviour(tmCommitter, misbehaviour); err != nil { - return errors.ErrInvalidEvidence(k.codespace, err.Error()) + return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) } clientState, err := k.freeze(ctx, clientState) diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index a8b1876d1e41..5732913247b3 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -18,17 +18,15 @@ import ( // Keeper represents a type that grants read and write permissions to any client // state information type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType + storeKey sdk.StoreKey + cdc *codec.Codec } // NewKeeper creates a new NewKeeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, errors.DefaultCodespace)), // "ibc/client", + storeKey: key, + cdc: cdc, } } @@ -181,7 +179,7 @@ func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState expo // freeze updates the state of the client in the event of a misbehaviour func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) { if clientState.Frozen { - return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientState.ID), "already frozen") + return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen, clientState.ID) } clientState.Frozen = true diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go index 104ad554c700..87da8c1eea5f 100644 --- a/x/ibc/02-client/keeper/querier.go +++ b/x/ibc/02-client/keeper/querier.go @@ -1,8 +1,6 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client" @@ -48,7 +46,7 @@ func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt clientState, found := k.GetClientState(ctx, params.ClientID) if !found { - return nil, errors.ErrClientTypeNotFound(k.codespace) + return nil, sdkerrors.Wrap(errors.ErrClientTypeNotFound, params.ClientID) } bz, err := codec.MarshalJSONIndent(k.cdc, clientState) @@ -69,7 +67,7 @@ func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([] consensusState, found := k.GetConsensusState(ctx, params.ClientID) if !found { - return nil, errors.ErrConsensusStateNotFound(k.codespace) + return nil, errors.ErrConsensusStateNotFound } bz, err := codec.MarshalJSONIndent(k.cdc, consensusState) @@ -90,7 +88,7 @@ func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]by root, found := k.GetVerifiedRoot(ctx, params.ClientID, params.Height) if !found { - return nil, errors.ErrRootNotFound(k.codespace) + return nil, errors.ErrRootNotFound } bz, err := codec.MarshalJSONIndent(k.cdc, root) @@ -111,10 +109,7 @@ func QuerierCommitter(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, committer, found := k.GetCommitter(ctx, params.ClientID, params.Height) if !found { - return nil, errors.ErrCommitterNotFound( - k.codespace, - fmt.Sprintf("committer not found on height: %d", params.Height), - ) + return nil, errors.ErrCommitterNotFound } bz, err := codec.MarshalJSONIndent(k.cdc, committer) diff --git a/x/ibc/02-client/types/errors/errors.go b/x/ibc/02-client/types/errors/errors.go index 1a7272ca1fcb..b6786a6113f6 100644 --- a/x/ibc/02-client/types/errors/errors.go +++ b/x/ibc/02-client/types/errors/errors.go @@ -1,134 +1,24 @@ package errors import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// client error codes -const ( - DefaultCodespace sdk.CodespaceType = "client" - - CodeClientExists sdk.CodeType = 200 - CodeClientNotFound sdk.CodeType = 201 - CodeClientFrozen sdk.CodeType = 202 - CodeConsensusStateNotFound sdk.CodeType = 203 - CodeInvalidConsensusState sdk.CodeType = 204 - CodeClientTypeNotFound sdk.CodeType = 205 - CodeInvalidClientType sdk.CodeType = 206 - CodeRootNotFound sdk.CodeType = 207 - CodeInvalidHeader sdk.CodeType = 208 - CodeInvalidEvidence sdk.CodeType = 209 - CodeCommitterNotFound sdk.CodeType = 210 - CodeInvalidCommitter sdk.CodeType = 211 +// SubModuleName is the error codespace +const SubModuleName string = "ibc/client" + +// IBC client sentinel errors +var ( + ErrClientExists = sdkerrors.Register(SubModuleName, 1, "light client already exists") + ErrClientNotFound = sdkerrors.Register(SubModuleName, 2, "light client not found") + ErrClientFrozen = sdkerrors.Register(SubModuleName, 3, "light client is frozen due to misbehaviour") + ErrConsensusStateNotFound = sdkerrors.Register(SubModuleName, 4, "consensus state not found") + ErrInvalidConsensus = sdkerrors.Register(SubModuleName, 5, "invalid consensus state") + ErrClientTypeNotFound = sdkerrors.Register(SubModuleName, 6, "client type not found") + ErrInvalidClientType = sdkerrors.Register(SubModuleName, 7, "invalid client type") + ErrRootNotFound = sdkerrors.Register(SubModuleName, 8, "commitment root not found") + ErrInvalidHeader = sdkerrors.Register(SubModuleName, 9, "invalid block header") + ErrInvalidEvidence = sdkerrors.Register(SubModuleName, 10, "invalid light client misbehaviour evidence") + ErrCommitterNotFound = sdkerrors.Register(SubModuleName, 11, "commiter not found") + ErrInvalidCommitter = sdkerrors.Register(SubModuleName, 12, "invalid commiter") ) - -// ErrClientExists implements sdk.Error -func ErrClientExists(codespace sdk.CodespaceType, clientID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientExists), - fmt.Sprintf("client with ID %s already exists", clientID), - ) -} - -// ErrClientNotFound implements sdk.Error -func ErrClientNotFound(codespace sdk.CodespaceType, clientID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientNotFound), - fmt.Sprintf("client with ID %s not found", clientID), - ) -} - -// ErrClientFrozen implements sdk.Error -func ErrClientFrozen(codespace sdk.CodespaceType, clientID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientFrozen), - fmt.Sprintf("client with ID %s is frozen due to misbehaviour", clientID), - ) -} - -// ErrConsensusStateNotFound implements sdk.Error -func ErrConsensusStateNotFound(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeConsensusStateNotFound), - "consensus state not found", - ) -} - -// ErrInvalidConsensus implements sdk.Error -func ErrInvalidConsensus(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidConsensusState), - "invalid consensus state", - ) -} - -// ErrClientTypeNotFound implements sdk.Error -func ErrClientTypeNotFound(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientTypeNotFound), - "client type not found", - ) -} - -// ErrInvalidClientType implements sdk.Error -func ErrInvalidClientType(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidClientType), - msg, - ) -} - -// ErrRootNotFound implements sdk.Error -func ErrRootNotFound(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeRootNotFound), - "commitment root not found", - ) -} - -// ErrInvalidHeader implements sdk.Error -func ErrInvalidHeader(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidHeader), - "invalid header", - ) -} - -// ErrInvalidEvidence implements sdk.Error -func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidEvidence), - fmt.Sprintf("invalid evidence: %s", msg), - ) -} - -// ErrCommitterNotFound implements sdk.Error -func ErrCommitterNotFound(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeCommitterNotFound), - fmt.Sprintf("invalid evidence: %s", msg), - ) -} - -// ErrInvalidEvidence implements sdk.Error -func ErrInvalidCommitter(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidCommitter), - fmt.Sprintf("invalid evidence: %s", msg), - ) -} diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index d52c0a614a44..128c76e4144b 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -1,9 +1,8 @@ package types import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" @@ -49,22 +48,17 @@ func (msg MsgCreateClient) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgCreateClient) ValidateBasic() sdk.Error { - if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(err) - } +func (msg MsgCreateClient) ValidateBasic() error { if clientType := exported.ClientTypeFromString(msg.ClientType); clientType == 0 { - return sdk.ConvertError( - errors.ErrInvalidClientType(errors.DefaultCodespace, fmt.Sprintf("invalid client type '%s'", msg.ClientType)), - ) + return sdkerrors.Wrap(errors.ErrInvalidClientType, msg.ClientType) } if msg.ConsensusState == nil { - return sdk.ConvertError(errors.ErrInvalidConsensus(errors.DefaultCodespace)) + return errors.ErrInvalidConsensus } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("empty address") + return sdkerrors.ErrInvalidAddress } - return nil + return host.DefaultClientIdentifierValidator(msg.ClientID) } // GetSignBytes implements sdk.Msg @@ -106,17 +100,14 @@ func (msg MsgUpdateClient) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgUpdateClient) ValidateBasic() sdk.Error { - if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(err) - } +func (msg MsgUpdateClient) ValidateBasic() error { if msg.Header == nil { - return sdk.ConvertError(errors.ErrInvalidHeader(errors.DefaultCodespace)) + return errors.ErrInvalidHeader } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("empty address") + return sdkerrors.ErrInvalidAddress } - return nil + return host.DefaultClientIdentifierValidator(msg.ClientID) } // GetSignBytes implements sdk.Msg @@ -156,20 +147,17 @@ func (msg MsgSubmitMisbehaviour) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgSubmitMisbehaviour) ValidateBasic() sdk.Error { - if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(err) - } +func (msg MsgSubmitMisbehaviour) ValidateBasic() error { if msg.Evidence == nil { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "evidence is nil")) + return sdkerrors.Wrap(errors.ErrInvalidEvidence, "evidence cannot be nil") } if err := msg.Evidence.ValidateBasic(); err != nil { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error())) + return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("empty address") + return sdkerrors.ErrInvalidAddress } - return nil + return host.DefaultClientIdentifierValidator(msg.ClientID) } // GetSignBytes implements sdk.Msg diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go index b29633420ed4..844276b3ae6b 100644 --- a/x/ibc/02-client/types/msgs_test.go +++ b/x/ibc/02-client/types/msgs_test.go @@ -38,7 +38,7 @@ type mockBadEvidence struct { // Override ValidateBasic func (mbe mockBadEvidence) ValidateBasic() error { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence") + return errors.ErrInvalidEvidence } func TestMsgCreateClientValidateBasic(t *testing.T) { diff --git a/x/ibc/02-client/types/tendermint/consensus_state.go b/x/ibc/02-client/types/tendermint/consensus_state.go index 25c2f8d990f8..cb7e2e42e849 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state.go +++ b/x/ibc/02-client/types/tendermint/consensus_state.go @@ -53,7 +53,9 @@ func (cs ConsensusState) GetCommitter() exported.Committer { func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (exported.ConsensusState, error) { tmHeader, ok := header.(Header) if !ok { - return nil, clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace) + return nil, sdkerrors.Wrap( + clienterrors.ErrInvalidHeader, "header is not from Tendermint", + ) } if err := cs.checkValidity(tmHeader); err != nil { @@ -69,7 +71,7 @@ func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (ex func (cs ConsensusState) checkValidity(header Header) error { if header.GetHeight() < cs.Height { return sdkerrors.Wrap( - clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), + clienterrors.ErrInvalidHeader, fmt.Sprintf("header height < consensus height (%d < %d)", header.GetHeight(), cs.Height), ) } diff --git a/x/ibc/02-client/types/tendermint/evidence.go b/x/ibc/02-client/types/tendermint/evidence.go index a8d1154a27ae..bc60b413b4e6 100644 --- a/x/ibc/02-client/types/tendermint/evidence.go +++ b/x/ibc/02-client/types/tendermint/evidence.go @@ -1,14 +1,13 @@ package tendermint import ( - "fmt" - yaml "gopkg.in/yaml.v2" "github.com/tendermint/tendermint/crypto/tmhash" cmn "github.com/tendermint/tendermint/libs/common" tmtypes "github.com/tendermint/tendermint/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" ) @@ -56,27 +55,31 @@ func (ev Evidence) GetHeight() int64 { func (ev Evidence) ValidateBasic() error { // ValidateBasic on both validators if err := ev.Header1.ValidateBasic(ev.ChainID); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Header1 failed ValidateBasic: %v", err)) + return sdkerrors.Wrap( + errors.ErrInvalidEvidence, + sdkerrors.Wrap(err, "header 1 failed validation").Error(), + ) } if err := ev.Header2.ValidateBasic(ev.ChainID); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Header2 failed ValidateBasic: %v", err)) + return sdkerrors.Wrap( + errors.ErrInvalidEvidence, + sdkerrors.Wrap(err, "header 2 failed validation").Error(), + ) } // Ensure that Heights are the same if ev.Header1.Height != ev.Header2.Height { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "headers in evidence are on different heights") + return sdkerrors.Wrapf(errors.ErrInvalidEvidence, "headers in evidence are on different heights (%d ≠ %d)", ev.Header1.Height, ev.Header2.Height) } // Ensure that Commit Hashes are different if ev.Header1.Commit.BlockID.Equals(ev.Header2.Commit.BlockID) { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "Headers commit to same blockID") + return sdkerrors.Wrap(errors.ErrInvalidEvidence, "headers commit to same blockID") } - - if err1 := ValidCommit(ev.ChainID, ev.Header1.Commit, ev.Header1.ValidatorSet); err1 != nil { - return err1 + if err := ValidCommit(ev.ChainID, ev.Header1.Commit, ev.Header1.ValidatorSet); err != nil { + return err } - if err2 := ValidCommit(ev.ChainID, ev.Header2.Commit, ev.Header2.ValidatorSet); err2 != nil { - return err2 + if err := ValidCommit(ev.ChainID, ev.Header2.Commit, ev.Header2.ValidatorSet); err != nil { + return err } - return nil } @@ -88,7 +91,7 @@ func (ev Evidence) ValidateBasic() error { func ValidCommit(chainID string, commit *tmtypes.Commit, valSet *tmtypes.ValidatorSet) (err error) { defer func() { if r := recover(); r != nil { - err = errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("invalid commit: %v", r)) + err = sdkerrors.Wrapf(errors.ErrInvalidEvidence, "invalid commit: %v", r) } }() @@ -99,7 +102,7 @@ func ValidCommit(chainID string, commit *tmtypes.Commit, valSet *tmtypes.Validat // Check that ValidatorSet did indeed commit to blockID in Commit if !ok || !blockID.Equals(commit.BlockID) { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "ValidatorSet did not commit to Header1") + return sdkerrors.Wrap(errors.ErrInvalidEvidence, "validator set did not commit to header 1") } return nil diff --git a/x/ibc/02-client/types/tendermint/header.go b/x/ibc/02-client/types/tendermint/header.go index 133c1741e56e..9509d6370019 100644 --- a/x/ibc/02-client/types/tendermint/header.go +++ b/x/ibc/02-client/types/tendermint/header.go @@ -42,13 +42,13 @@ func (h Header) GetHeight() uint64 { // and checks that validatorsets are not nil func (h Header) ValidateBasic(chainID string) error { if err := h.SignedHeader.ValidateBasic(chainID); err != nil { - return err + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader, err.Error()) } if h.ValidatorSet == nil { - return sdkerrors.Wrap(clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), "ValidatorSet is nil") + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader, "validator set is nil") } if h.NextValidatorSet == nil { - return sdkerrors.Wrap(clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), "NextValidatorSet is nil") + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader, "next validator set is nil") } return nil } diff --git a/x/ibc/02-client/types/tendermint/misbehaviour.go b/x/ibc/02-client/types/tendermint/misbehaviour.go index 5b04b6e3ec0c..36c8e14ce8ab 100644 --- a/x/ibc/02-client/types/tendermint/misbehaviour.go +++ b/x/ibc/02-client/types/tendermint/misbehaviour.go @@ -1,8 +1,7 @@ package tendermint import ( - "fmt" - + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" @@ -33,14 +32,15 @@ func (m Misbehaviour) GetEvidence() evidenceexported.Evidence { // client ID. func (m Misbehaviour) ValidateBasic() error { if m.Evidence == nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "empty evidence") + return sdkerrors.Wrap(errors.ErrInvalidEvidence, "evidence is empty") } - if err := m.Evidence.ValidateBasic(); err != nil { - return err + return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) } - - return host.DefaultClientIdentifierValidator(m.ClientID) + if err := host.DefaultClientIdentifierValidator(m.ClientID); err != nil { + return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) + } + return nil } // CheckMisbehaviour checks if the evidence provided is a valid light client misbehaviour @@ -54,13 +54,17 @@ func CheckMisbehaviour(trustedCommitter Committer, m Misbehaviour) error { // Evidence is within trusting period. ValidatorSet must have 2/3 similarity with trustedCommitter ValidatorSet // check that the validator sets on both headers are valid given the last trusted validatorset // less than or equal to evidence height - if err := trustedValSet.VerifyFutureCommit(m.Evidence.Header1.ValidatorSet, m.Evidence.ChainID, - m.Evidence.Header1.Commit.BlockID, m.Evidence.Header1.Height, m.Evidence.Header1.Commit); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("validator set in Header1 has too much change from last known committer: %v", err)) + if err := trustedValSet.VerifyFutureCommit( + m.Evidence.Header1.ValidatorSet, m.Evidence.ChainID, + m.Evidence.Header1.Commit.BlockID, m.Evidence.Header1.Height, m.Evidence.Header1.Commit, + ); err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidEvidence, "validator set in header 1 has too much change from last known committer: %v", err) } - if err := trustedValSet.VerifyFutureCommit(m.Evidence.Header2.ValidatorSet, m.Evidence.ChainID, - m.Evidence.Header2.Commit.BlockID, m.Evidence.Header2.Height, m.Evidence.Header2.Commit); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("validator set in Header2 has too much change from last known committer: %v", err)) + if err := trustedValSet.VerifyFutureCommit( + m.Evidence.Header2.ValidatorSet, m.Evidence.ChainID, + m.Evidence.Header2.Commit.BlockID, m.Evidence.Header2.Height, m.Evidence.Header2.Commit, + ); err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidEvidence, "validator set in header 2 has too much change from last known committer: %v", err) } return nil diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index 4d44e18048e8..2cb4faf887ff 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -12,33 +12,23 @@ import ( ) const ( - UNINITIALIZED = types.UNINITIALIZED - INIT = types.INIT - TRYOPEN = types.TRYOPEN - OPEN = types.OPEN - StateUninitialized = types.StateUninitialized - StateInit = types.StateInit - StateTryOpen = types.StateTryOpen - StateOpen = types.StateOpen - DefaultCodespace = types.DefaultCodespace - CodeConnectionExists = types.CodeConnectionExists - CodeConnectionNotFound = types.CodeConnectionNotFound - CodeClientConnectionPathsNotFound = types.CodeClientConnectionPathsNotFound - CodeConnectionPath = types.CodeConnectionPath - CodeInvalidCounterpartyConnection = types.CodeInvalidCounterpartyConnection - CodeInvalidVersion = types.CodeInvalidVersion - CodeInvalidHeight = types.CodeInvalidHeight - CodeInvalidConnectionState = types.CodeInvalidConnectionState - CodeInvalidCounterparty = types.CodeInvalidCounterparty - AttributeKeyConnectionID = types.AttributeKeyConnectionID - AttributeKeyCounterpartyClientID = types.AttributeKeyCounterpartyClientID - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - QueryAllConnections = types.QueryAllConnections - QueryConnection = types.QueryConnection - QueryClientConnections = types.QueryClientConnections + UNINITIALIZED = types.UNINITIALIZED + INIT = types.INIT + TRYOPEN = types.TRYOPEN + OPEN = types.OPEN + StateUninitialized = types.StateUninitialized + StateInit = types.StateInit + StateTryOpen = types.StateTryOpen + StateOpen = types.StateOpen + AttributeKeyConnectionID = types.AttributeKeyConnectionID + AttributeKeyCounterpartyClientID = types.AttributeKeyCounterpartyClientID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryAllConnections = types.QueryAllConnections + QueryConnection = types.QueryConnection + QueryClientConnections = types.QueryClientConnections ) var ( @@ -55,8 +45,6 @@ var ( ErrConnectionNotFound = types.ErrConnectionNotFound ErrClientConnectionPathsNotFound = types.ErrClientConnectionPathsNotFound ErrConnectionPath = types.ErrConnectionPath - ErrInvalidCounterpartyConnection = types.ErrInvalidCounterpartyConnection - ErrInvalidHeight = types.ErrInvalidHeight ErrInvalidConnectionState = types.ErrInvalidConnectionState ErrInvalidCounterparty = types.ErrInvalidCounterparty ConnectionPath = types.ConnectionPath diff --git a/x/ibc/03-connection/client/cli/cli.go b/x/ibc/03-connection/client/cli/cli.go index e0ea7c89880f..92c3fa8cc901 100644 --- a/x/ibc/03-connection/client/cli/cli.go +++ b/x/ibc/03-connection/client/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) @@ -16,7 +16,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { SuggestionsMinimumDistance: 2, } - ics03ConnectionQueryCmd.AddCommand(client.GetCommands( + ics03ConnectionQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryConnections(queryRoute, cdc), GetCmdQueryConnection(queryRoute, cdc), )...) @@ -30,7 +30,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "IBC connection transaction subcommands", } - ics03ConnectionTxCmd.AddCommand(client.PostCommands( + ics03ConnectionTxCmd.AddCommand(flags.PostCommands( GetCmdConnectionOpenInit(storeKey, cdc), GetCmdConnectionOpenTry(storeKey, cdc), GetCmdConnectionOpenAck(storeKey, cdc), diff --git a/x/ibc/03-connection/handler.go b/x/ibc/03-connection/handler.go index 854436eadd6a..b7c9eae08d3f 100644 --- a/x/ibc/03-connection/handler.go +++ b/x/ibc/03-connection/handler.go @@ -7,10 +7,10 @@ import ( ) // HandleMsgConnectionOpenInit defines the sdk.Handler for MsgConnectionOpenInit -func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenInit) sdk.Result { +func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenInit) (*sdk.Result, error) { err := k.ConnOpenInit(ctx, msg.ConnectionID, msg.ClientID, msg.Counterparty) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -26,16 +26,18 @@ func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.Msg ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgConnectionOpenTry defines the sdk.Handler for MsgConnectionOpenTry -func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenTry) sdk.Result { +func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenTry) (*sdk.Result, error) { err := k.ConnOpenTry( ctx, msg.ConnectionID, msg.Counterparty, msg.ClientID, msg.CounterpartyVersions, msg.ProofInit, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -51,17 +53,19 @@ func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgC ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgConnectionOpenAck defines the sdk.Handler for MsgConnectionOpenAck -func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenAck) sdk.Result { +func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenAck) (*sdk.Result, error) { err := k.ConnOpenAck( ctx, msg.ConnectionID, msg.Version, msg.ProofTry, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight, ) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -76,14 +80,16 @@ func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgC ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgConnectionOpenConfirm defines the sdk.Handler for MsgConnectionOpenConfirm -func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenConfirm) sdk.Result { +func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenConfirm) (*sdk.Result, error) { err := k.ConnOpenConfirm(ctx, msg.ConnectionID, msg.ProofAck, msg.ProofHeight) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -98,5 +104,7 @@ func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types. ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index e5a011a84b3a..8a40c427de52 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -22,7 +22,7 @@ func (k Keeper) ConnOpenInit( ) error { _, found := k.GetConnection(ctx, connectionID) if found { - return sdkerrors.Wrap(types.ErrConnectionExists(k.codespace, connectionID), "cannot initialize connection") + return sdkerrors.Wrap(types.ErrConnectionExists, "cannot initialize connection") } // connection defines chain A's ConnectionEnd @@ -58,7 +58,7 @@ func (k Keeper) ConnOpenTry( // XXX: blocked by #5078 /* if consensusHeight > uint64(ctx.BlockHeight()) { - return errors.New("invalid consensus height") // TODO: sdk.Error + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") } expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, clientID) @@ -112,7 +112,7 @@ func (k Keeper) ConnOpenTry( _, found := k.GetConnection(ctx, connectionID) if found { - return sdkerrors.Wrap(types.ErrConnectionExists(k.codespace, connectionID), "cannot relay connection attempt") + return sdkerrors.Wrap(types.ErrConnectionExists, "cannot relay connection attempt") } connection.State = types.TRYOPEN @@ -142,25 +142,25 @@ func (k Keeper) ConnOpenAck( // XXX: blocked by #5078 /* if consensusHeight > uint64(ctx.BlockHeight()) { - return errors.New("invalid consensus height") // TODO: sdk.Error + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") } */ connection, found := k.GetConnection(ctx, connectionID) if !found { - return sdkerrors.Wrap(types.ErrConnectionNotFound(k.codespace, connectionID), "cannot relay ACK of open attempt") + return sdkerrors.Wrap(types.ErrConnectionNotFound, "cannot relay ACK of open attempt") } if connection.State != types.INIT { - return types.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not INIT (got %s)", connection.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidConnectionState, + "connection state is not INIT (got %s)", connection.State.String(), ) } if types.LatestVersion(connection.Versions) != version { - return ibctypes.ErrInvalidVersion( - k.codespace, - fmt.Sprintf("connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version), + return sdkerrors.Wrapf( + ibctypes.ErrInvalidVersion, + "connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version, ) } @@ -223,13 +223,13 @@ func (k Keeper) ConnOpenConfirm( ) error { connection, found := k.GetConnection(ctx, connectionID) if !found { - return sdkerrors.Wrap(types.ErrConnectionNotFound(k.codespace, connectionID), "cannot relay ACK of open attempt") + return sdkerrors.Wrap(types.ErrConnectionNotFound, "cannot relay ACK of open attempt") } if connection.State != types.TRYOPEN { - return types.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not TRYOPEN (got %s)", connection.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidConnectionState, + "connection state is not TRYOPEN (got %s)", connection.State.String(), ) } @@ -247,7 +247,7 @@ func (k Keeper) ConnOpenConfirm( types.ConnectionPath(connection.Counterparty.ConnectionID), expConnBz, ) if !ok { - return types.ErrInvalidCounterpartyConnection(k.codespace) + return errors.New("couldn't verify connection membership on counterparty's client") } connection.State = types.OPEN diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index c20720c17788..5edec4cdf32b 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" @@ -17,16 +18,14 @@ import ( type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec - codespace sdk.CodespaceType clientKeeper types.ClientKeeper } // NewKeeper creates a new IBC connection Keeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, ck types.ClientKeeper) Keeper { +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ck types.ClientKeeper) Keeper { return Keeper{ storeKey: key, cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/connection", clientKeeper: ck, } } @@ -133,12 +132,12 @@ func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID st func (k Keeper) removeConnectionFromClient(ctx sdk.Context, clientID, connectionID string) error { conns, found := k.GetClientConnectionPaths(ctx, clientID) if !found { - return types.ErrClientConnectionPathsNotFound(k.codespace, clientID) + return sdkerrors.Wrap(types.ErrClientConnectionPathsNotFound, clientID) } conns, ok := host.RemovePath(conns, connectionID) if !ok { - return types.ErrConnectionPath(k.codespace) + return sdkerrors.Wrap(types.ErrConnectionPath, clientID) } k.SetClientConnectionPaths(ctx, clientID, conns) diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go index f5c56834161f..c888e84e32b2 100644 --- a/x/ibc/03-connection/keeper/querier.go +++ b/x/ibc/03-connection/keeper/querier.go @@ -20,12 +20,12 @@ func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte connection, found := k.GetConnection(ctx, params.ConnectionID) if !found { - return nil, types.ErrConnectionNotFound(k.codespace, params.ConnectionID) + return nil, sdkerrors.Wrap(types.ErrConnectionNotFound, params.ConnectionID) } - bz, err := codec.MarshalJSONIndent(k.cdc, connection) + bz, err := types.SubModuleCdc.MarshalJSON(connection) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil @@ -66,7 +66,7 @@ func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) clientConnectionPaths, found := k.GetClientConnectionPaths(ctx, params.ClientID) if !found { - return nil, types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID) + return nil, sdkerrors.Wrap(types.ErrClientConnectionPathsNotFound, params.ClientID) } bz, err := types.SubModuleCdc.MarshalJSON(clientConnectionPaths) diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 65806e9f5a9a..5a441c22eb26 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -54,13 +54,23 @@ func NewCounterparty(clientID, connectionID string, prefix commitment.PrefixI) C // ValidateBasic performs a basic validation check of the identifiers and prefix func (c Counterparty) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(c.ConnectionID); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty connection ID") + return sdkerrors.Wrap(err, + sdkerrors.Wrapf( + ErrInvalidCounterparty, + "invalid counterparty connection ID %s", c.ConnectionID, + ).Error(), + ) } if err := host.DefaultClientIdentifierValidator(c.ClientID); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty client ID") + return sdkerrors.Wrap(err, + sdkerrors.Wrapf( + ErrInvalidCounterparty, + "invalid counterparty client ID %s", c.ClientID, + ).Error(), + ) } if c.Prefix == nil || len(c.Prefix.Bytes()) == 0 { - return ErrInvalidCounterparty(DefaultCodespace, "invalid counterparty prefix") + return sdkerrors.Wrap(ErrInvalidCounterparty, "invalid counterparty prefix") } return nil } diff --git a/x/ibc/03-connection/types/errors.go b/x/ibc/03-connection/types/errors.go index d62e14a49218..41199efc4103 100644 --- a/x/ibc/03-connection/types/errors.go +++ b/x/ibc/03-connection/types/errors.go @@ -1,95 +1,15 @@ package types import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// connection error codes -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodeConnectionExists sdk.CodeType = 210 - CodeConnectionNotFound sdk.CodeType = 211 - CodeClientConnectionPathsNotFound sdk.CodeType = 212 - CodeConnectionPath sdk.CodeType = 213 - CodeInvalidCounterpartyConnection sdk.CodeType = 214 - CodeInvalidVersion sdk.CodeType = 215 - CodeInvalidHeight sdk.CodeType = 216 - CodeInvalidConnectionState sdk.CodeType = 217 - CodeInvalidCounterparty sdk.CodeType = 218 +// IBC connection sentinel errors +var ( + ErrConnectionExists = sdkerrors.Register(SubModuleName, 1, "connection already exists") + ErrConnectionNotFound = sdkerrors.Register(SubModuleName, 2, "connection not found") + ErrClientConnectionPathsNotFound = sdkerrors.Register(SubModuleName, 3, "light client connection paths not found") + ErrConnectionPath = sdkerrors.Register(SubModuleName, 4, "connection path is not associated to the given light client") + ErrInvalidConnectionState = sdkerrors.Register(SubModuleName, 5, "invalid connection state") + ErrInvalidCounterparty = sdkerrors.Register(SubModuleName, 6, "invalid counterparty connection") ) - -// ErrConnectionExists implements sdk.Error -func ErrConnectionExists(codespace sdk.CodespaceType, connectionID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeConnectionExists), - fmt.Sprintf("connection with ID %s already exists", connectionID), - ) -} - -// ErrConnectionNotFound implements sdk.Error -func ErrConnectionNotFound(codespace sdk.CodespaceType, connectionID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeConnectionNotFound), - fmt.Sprintf("connection with ID %s not found", connectionID), - ) -} - -// ErrClientConnectionPathsNotFound implements sdk.Error -func ErrClientConnectionPathsNotFound(codespace sdk.CodespaceType, clientID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientConnectionPathsNotFound), - fmt.Sprintf("client connection paths not found for ID %s", clientID), - ) -} - -// ErrConnectionPath implements sdk.Error -func ErrConnectionPath(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeConnectionPath), - "connection path is not associated to the client", - ) -} - -// ErrInvalidCounterpartyConnection implements sdk.Error -func ErrInvalidCounterpartyConnection(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidCounterpartyConnection), - "couldn't verify connection membership on counterparty's client", - ) -} - -// ErrInvalidHeight implements sdk.Error -func ErrInvalidHeight(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidHeight), - msg, - ) -} - -// ErrInvalidConnectionState implements sdk.Error -func ErrInvalidConnectionState(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidConnectionState), - msg, - ) -} - -// ErrInvalidCounterparty implements sdk.Error -func ErrInvalidCounterparty(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidCounterparty), - msg, - ) -} diff --git a/x/ibc/03-connection/types/msgs.go b/x/ibc/03-connection/types/msgs.go index e302badac9c4..bf0731c3bb66 100644 --- a/x/ibc/03-connection/types/msgs.go +++ b/x/ibc/03-connection/types/msgs.go @@ -47,17 +47,17 @@ func (msg MsgConnectionOpenInit) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgConnectionOpenInit) ValidateBasic() sdk.Error { +func (msg MsgConnectionOpenInit) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) + return sdkerrors.Wrapf(err, "invalid connection ID: %s", msg.ConnectionID) } if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid client ID")) + return sdkerrors.Wrapf(err, "invalid client ID: %s", msg.ClientID) } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.ErrInvalidAddress } - return sdk.ConvertError(msg.Counterparty.ValidateBasic()) + return msg.Counterparty.ValidateBasic() } // GetSignBytes implements sdk.Msg @@ -118,37 +118,40 @@ func (msg MsgConnectionOpenTry) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgConnectionOpenTry) ValidateBasic() sdk.Error { +func (msg MsgConnectionOpenTry) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) + return sdkerrors.Wrapf(err, "invalid connection ID: %s", msg.ConnectionID) } if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid client ID")) + return sdkerrors.Wrapf(err, "invalid client ID: %s", msg.ClientID) } if len(msg.CounterpartyVersions) == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "missing counterparty versions")) + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "missing counterparty versions") } for _, version := range msg.CounterpartyVersions { if strings.TrimSpace(version) == "" { - return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "version can't be blank")) + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version can't be blank") } } - if msg.ProofInit == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof init cannot be nil")) + if msg.ProofInit == nil || msg.ProofConsensus == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") } - if msg.ProofConsensus == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof consensus cannot be nil")) + if err := msg.ProofInit.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof init cannot be nil") + } + if err := msg.ProofConsensus.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof consensus cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } if msg.ConsensusHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "consensus height must be > 0") } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.ErrInvalidAddress } - return sdk.ConvertError(msg.Counterparty.ValidateBasic()) + return msg.Counterparty.ValidateBasic() } // GetSignBytes implements sdk.Msg @@ -203,27 +206,30 @@ func (msg MsgConnectionOpenAck) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgConnectionOpenAck) ValidateBasic() sdk.Error { +func (msg MsgConnectionOpenAck) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) + return sdkerrors.Wrap(err, "invalid connection ID") } if strings.TrimSpace(msg.Version) == "" { - return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "version can't be blank")) + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version can't be blank") + } + if msg.ProofTry == nil || msg.ProofConsensus == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") } - if msg.ProofTry == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof try cannot be nil")) + if err := msg.ProofTry.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof try cannot be nil") } - if msg.ProofConsensus == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof consensus cannot be nil")) + if err := msg.ProofConsensus.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof consensus cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } if msg.ConsensusHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "consensus height must be > 0") } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.ErrInvalidAddress } return nil } @@ -272,18 +278,21 @@ func (msg MsgConnectionOpenConfirm) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgConnectionOpenConfirm) ValidateBasic() sdk.Error { +func (msg MsgConnectionOpenConfirm) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) + return sdkerrors.Wrap(err, "invalid connection ID") } if msg.ProofAck == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof ack cannot be nil")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofAck.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.ErrInvalidAddress } return nil } diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go index 87fbae8b7276..8bca120769ba 100644 --- a/x/ibc/03-connection/types/msgs_test.go +++ b/x/ibc/03-connection/types/msgs_test.go @@ -4,20 +4,50 @@ import ( "fmt" "testing" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -func TestNewMsgConnectionOpenInit(t *testing.T) { +type MsgTestSuite struct { + suite.Suite - type TestCase = struct { - msg MsgConnectionOpenInit - expected bool - errMsg string - } + proof commitment.Proof +} + +func (suite *MsgTestSuite) SetupTest() { + db := dbm.NewMemDB() + store := rootmulti.NewStore(db) + storeKey := storetypes.NewKVStoreKey("iavlStoreKey") + + store.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) + store.LoadVersion(0) + iavlStore := store.GetCommitStore(storeKey).(*iavl.Store) + + iavlStore.Set([]byte("KEY"), []byte("VALUE")) + _ = store.Commit() + + res := store.Query(abci.RequestQuery{ + Path: fmt.Sprintf("/%s/key", storeKey.Name()), // required path to get key/value+proof + Data: []byte("KEY"), + Prove: true, + }) + + suite.proof = commitment.Proof{Proof: res.Proof} +} + +func TestMsgTestSuite(t *testing.T) { + suite.Run(t, new(MsgTestSuite)) +} +func (suite *MsgTestSuite) TestNewMsgConnectionOpenInit() { prefix := commitment.NewPrefix([]byte("storePrefixKey")) signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") @@ -31,7 +61,11 @@ func TestNewMsgConnectionOpenInit(t *testing.T) { NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, signer), } - var testCases = []TestCase{ + var testCases = []struct { + msg MsgConnectionOpenInit + expPass bool + errMsg string + }{ {testMsgs[0], false, "invalid connection ID"}, {testMsgs[1], false, "invalid client ID"}, {testMsgs[2], false, "invalid counterparty client ID"}, @@ -42,36 +76,41 @@ func TestNewMsgConnectionOpenInit(t *testing.T) { } for i, tc := range testCases { - require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %v", i, err) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } } } -func TestNewMsgConnectionOpenTry(t *testing.T) { - type TestCase = struct { - msg MsgConnectionOpenTry - expected bool - errMsg string - } - +func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { prefix := commitment.NewPrefix([]byte("storePrefixKey")) signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenTry{ - NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "ibc/test", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "test/conn1", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", nil, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, nil, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, nil, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 0, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 0, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, nil), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - } - - var testCases = []TestCase{ + NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "ibc/test", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "test/conn1", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", nil, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, nil, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{Proof: nil}, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, nil, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, commitment.Proof{Proof: nil}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 0, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 0, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, nil), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + } + + var testCases = []struct { + msg MsgConnectionOpenTry + expPass bool + errMsg string + }{ {testMsgs[0], false, "invalid connection ID"}, {testMsgs[1], false, "invalid client ID"}, {testMsgs[2], false, "invalid counterparty connection ID"}, @@ -79,79 +118,98 @@ func TestNewMsgConnectionOpenTry(t *testing.T) { {testMsgs[4], false, "empty counterparty prefix"}, {testMsgs[5], false, "empty counterpartyVersions"}, {testMsgs[6], false, "empty proofInit"}, - {testMsgs[7], false, "empty proofConsensus"}, - {testMsgs[8], false, "invalid proofHeight"}, - {testMsgs[9], false, "invalid consensusHeight"}, - {testMsgs[10], false, "empty singer"}, - {testMsgs[11], true, "success"}, + {testMsgs[7], false, "empty proofInit"}, + {testMsgs[8], false, "empty proofConsensus"}, + {testMsgs[9], false, "empty proofConsensus"}, + {testMsgs[10], false, "invalid proofHeight"}, + {testMsgs[11], false, "invalid consensusHeight"}, + {testMsgs[12], false, "empty singer"}, + {testMsgs[13], true, "success"}, } for i, tc := range testCases { - require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } } } -func TestNewMsgConnectionOpenAck(t *testing.T) { - type TestCase = struct { - msg MsgConnectionOpenAck - expected bool - errMsg string - } - +func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenAck{ - NewMsgConnectionOpenAck("test/conn1", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", nil, commitment.Proof{}, 10, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, nil, 10, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 0, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 0, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", nil), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", signer), - } - var testCases = []TestCase{ + NewMsgConnectionOpenAck("test/conn1", suite.proof, suite.proof, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", nil, suite.proof, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{Proof: nil}, suite.proof, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, nil, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, commitment.Proof{Proof: nil}, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 0, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 0, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 10, "", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 10, "1.0.0", nil), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 10, "1.0.0", signer), + } + var testCases = []struct { + msg MsgConnectionOpenAck + expPass bool + errMsg string + }{ {testMsgs[0], false, "invalid connection ID"}, {testMsgs[1], false, "empty proofTry"}, - {testMsgs[2], false, "empty proofConsensus"}, - {testMsgs[3], false, "invalid proofHeight"}, - {testMsgs[4], false, "invalid consensusHeight"}, - {testMsgs[5], false, "invalid version"}, - {testMsgs[6], false, "empty signer"}, - {testMsgs[7], true, "success"}, + {testMsgs[2], false, "empty proofTry"}, + {testMsgs[3], false, "empty proofConsensus"}, + {testMsgs[4], false, "empty proofConsensus"}, + {testMsgs[5], false, "invalid proofHeight"}, + {testMsgs[6], false, "invalid consensusHeight"}, + {testMsgs[7], false, "invalid version"}, + {testMsgs[8], false, "empty signer"}, + {testMsgs[9], true, "success"}, } for i, tc := range testCases { - require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } } } -func TestNewMsgConnectionOpenConfirm(t *testing.T) { - type TestCase = struct { - msg MsgConnectionOpenConfirm - expected bool - errMsg string - } - +func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenConfirm{ - NewMsgConnectionOpenConfirm("test/conn1", commitment.Proof{}, 10, signer), + NewMsgConnectionOpenConfirm("test/conn1", suite.proof, 10, signer), NewMsgConnectionOpenConfirm("ibcconntest", nil, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 0, signer), - NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 10, nil), - NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{Proof: nil}, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 0, signer), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, nil), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, signer), } - var testCases = []TestCase{ + var testCases = []struct { + msg MsgConnectionOpenConfirm + expPass bool + errMsg string + }{ {testMsgs[0], false, "invalid connection ID"}, {testMsgs[1], false, "empty proofTry"}, - {testMsgs[2], false, "invalid proofHeight"}, - {testMsgs[3], false, "empty signer"}, - {testMsgs[4], true, "success"}, + {testMsgs[2], false, "empty proofTry"}, + {testMsgs[3], false, "invalid proofHeight"}, + {testMsgs[4], false, "empty signer"}, + {testMsgs[5], true, "success"}, } for i, tc := range testCases { - require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } } } diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index f2d6a7f49d24..73e18df48d0c 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -12,84 +12,75 @@ import ( ) const ( - UNINITIALIZED = types.UNINITIALIZED - UNORDERED = types.UNORDERED - ORDERED = types.ORDERED - OrderNone = types.OrderNone - OrderUnordered = types.OrderUnordered - OrderOrdered = types.OrderOrdered - CLOSED = types.CLOSED - INIT = types.INIT - TRYOPEN = types.TRYOPEN - OPEN = types.OPEN - StateUninitialized = types.StateUninitialized - StateInit = types.StateInit - StateTryOpen = types.StateTryOpen - StateOpen = types.StateOpen - StateClosed = types.StateClosed - DefaultCodespace = types.DefaultCodespace - CodeChannelExists = types.CodeChannelExists - CodeChannelNotFound = types.CodeChannelNotFound - CodeInvalidCounterpartyChannel = types.CodeInvalidCounterpartyChannel - CodeChannelCapabilityNotFound = types.CodeChannelCapabilityNotFound - CodeInvalidPacket = types.CodeInvalidPacket - CodeSequenceNotFound = types.CodeSequenceNotFound - CodePacketTimeout = types.CodePacketTimeout - CodeInvalidChannel = types.CodeInvalidChannel - CodeInvalidChannelState = types.CodeInvalidChannelState - AttributeKeySenderPort = types.AttributeKeySenderPort - AttributeKeyReceiverPort = types.AttributeKeyReceiverPort - AttributeKeyChannelID = types.AttributeKeyChannelID - AttributeKeySequence = types.AttributeKeySequence - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - QueryAllChannels = types.QueryAllChannels - QueryChannel = types.QueryChannel + UNINITIALIZED = types.UNINITIALIZED + UNORDERED = types.UNORDERED + ORDERED = types.ORDERED + OrderNone = types.OrderNone + OrderUnordered = types.OrderUnordered + OrderOrdered = types.OrderOrdered + CLOSED = types.CLOSED + INIT = types.INIT + TRYOPEN = types.TRYOPEN + OPEN = types.OPEN + StateUninitialized = types.StateUninitialized + StateInit = types.StateInit + StateTryOpen = types.StateTryOpen + StateOpen = types.StateOpen + StateClosed = types.StateClosed + AttributeKeySenderPort = types.AttributeKeySenderPort + AttributeKeyReceiverPort = types.AttributeKeyReceiverPort + AttributeKeyChannelID = types.AttributeKeyChannelID + AttributeKeySequence = types.AttributeKeySequence + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryAllChannels = types.QueryAllChannels + QueryChannel = types.QueryChannel ) var ( // functions aliases - NewKeeper = keeper.NewKeeper - QuerierChannels = keeper.QuerierChannels - QuerierChannel = keeper.QuerierChannel - NewChannel = types.NewChannel - NewCounterparty = types.NewCounterparty - OrderFromString = types.OrderFromString - StateFromString = types.StateFromString - RegisterCodec = types.RegisterCodec - ErrChannelExists = types.ErrChannelExists - ErrChannelNotFound = types.ErrChannelNotFound - ErrInvalidCounterpartyChannel = types.ErrInvalidCounterpartyChannel - ErrChannelCapabilityNotFound = types.ErrChannelCapabilityNotFound - ErrInvalidPacket = types.ErrInvalidPacket - ErrSequenceNotFound = types.ErrSequenceNotFound - ErrPacketTimeout = types.ErrPacketTimeout - ErrInvalidChannel = types.ErrInvalidChannel - ErrInvalidChannelState = types.ErrInvalidChannelState - ChannelPath = types.ChannelPath - ChannelCapabilityPath = types.ChannelCapabilityPath - NextSequenceSendPath = types.NextSequenceSendPath - NextSequenceRecvPath = types.NextSequenceRecvPath - PacketCommitmentPath = types.PacketCommitmentPath - PacketAcknowledgementPath = types.PacketAcknowledgementPath - KeyChannel = types.KeyChannel - KeyChannelCapabilityPath = types.KeyChannelCapabilityPath - KeyNextSequenceSend = types.KeyNextSequenceSend - KeyNextSequenceRecv = types.KeyNextSequenceRecv - KeyPacketCommitment = types.KeyPacketCommitment - KeyPacketAcknowledgement = types.KeyPacketAcknowledgement - NewMsgChannelOpenInit = types.NewMsgChannelOpenInit - NewMsgChannelOpenTry = types.NewMsgChannelOpenTry - NewMsgChannelOpenAck = types.NewMsgChannelOpenAck - NewMsgChannelOpenConfirm = types.NewMsgChannelOpenConfirm - NewMsgChannelCloseInit = types.NewMsgChannelCloseInit - NewMsgChannelCloseConfirm = types.NewMsgChannelCloseConfirm - NewPacket = types.NewPacket - NewOpaquePacket = types.NewOpaquePacket - NewChannelResponse = types.NewChannelResponse - NewQueryChannelParams = types.NewQueryChannelParams + NewKeeper = keeper.NewKeeper + QuerierChannels = keeper.QuerierChannels + QuerierChannel = keeper.QuerierChannel + NewChannel = types.NewChannel + NewCounterparty = types.NewCounterparty + OrderFromString = types.OrderFromString + StateFromString = types.StateFromString + RegisterCodec = types.RegisterCodec + ErrChannelExists = types.ErrChannelExists + ErrChannelNotFound = types.ErrChannelNotFound + ErrInvalidCounterparty = types.ErrInvalidCounterparty + ErrChannelCapabilityNotFound = types.ErrChannelCapabilityNotFound + ErrInvalidPacket = types.ErrInvalidPacket + ErrSequenceSendNotFound = types.ErrSequenceSendNotFound + ErrSequenceReceiveNotFound = types.ErrSequenceReceiveNotFound + ErrPacketTimeout = types.ErrPacketTimeout + ErrInvalidChannel = types.ErrInvalidChannel + ErrInvalidChannelState = types.ErrInvalidChannelState + ChannelPath = types.ChannelPath + ChannelCapabilityPath = types.ChannelCapabilityPath + NextSequenceSendPath = types.NextSequenceSendPath + NextSequenceRecvPath = types.NextSequenceRecvPath + PacketCommitmentPath = types.PacketCommitmentPath + PacketAcknowledgementPath = types.PacketAcknowledgementPath + KeyChannel = types.KeyChannel + KeyChannelCapabilityPath = types.KeyChannelCapabilityPath + KeyNextSequenceSend = types.KeyNextSequenceSend + KeyNextSequenceRecv = types.KeyNextSequenceRecv + KeyPacketCommitment = types.KeyPacketCommitment + KeyPacketAcknowledgement = types.KeyPacketAcknowledgement + NewMsgChannelOpenInit = types.NewMsgChannelOpenInit + NewMsgChannelOpenTry = types.NewMsgChannelOpenTry + NewMsgChannelOpenAck = types.NewMsgChannelOpenAck + NewMsgChannelOpenConfirm = types.NewMsgChannelOpenConfirm + NewMsgChannelCloseInit = types.NewMsgChannelCloseInit + NewMsgChannelCloseConfirm = types.NewMsgChannelCloseConfirm + NewPacket = types.NewPacket + NewOpaquePacket = types.NewOpaquePacket + NewChannelResponse = types.NewChannelResponse + NewQueryChannelParams = types.NewQueryChannelParams // variable aliases SubModuleCdc = types.SubModuleCdc diff --git a/x/ibc/04-channel/client/cli/cli.go b/x/ibc/04-channel/client/cli/cli.go index 35bd02203a1d..7c24dff1e95f 100644 --- a/x/ibc/04-channel/client/cli/cli.go +++ b/x/ibc/04-channel/client/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) @@ -15,7 +15,7 @@ func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { DisableFlagParsing: true, } - ics04ChannelQueryCmd.AddCommand(client.GetCommands( + ics04ChannelQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryChannel(storeKey, cdc), )...) @@ -29,7 +29,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "IBC channel transaction subcommands", } - ics04ChannelTxCmd.AddCommand(client.PostCommands( + ics04ChannelTxCmd.AddCommand(flags.PostCommands( GetMsgChannelOpenInitCmd(storeKey, cdc), GetMsgChannelOpenTryCmd(storeKey, cdc), GetMsgChannelOpenAckCmd(storeKey, cdc), diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index 0084f57376a1..e7e9568e4add 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -3,13 +3,13 @@ package utils import ( abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // QueryPacket returns a packet from the store func QueryPacket( - ctx client.CLIContext, portID, channelID string, sequence, timeout uint64, prove bool, + ctx context.CLIContext, portID, channelID string, sequence, timeout uint64, prove bool, ) (types.PacketResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", @@ -46,7 +46,7 @@ func QueryPacket( // QueryChannel queries the store to get a channel and a merkle proof. func QueryChannel( - ctx client.CLIContext, portID, channelID string, prove bool, + ctx context.CLIContext, portID, channelID string, prove bool, ) (types.ChannelResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", diff --git a/x/ibc/04-channel/handler.go b/x/ibc/04-channel/handler.go index 31c97b668e1a..fb35ef8e5fbe 100644 --- a/x/ibc/04-channel/handler.go +++ b/x/ibc/04-channel/handler.go @@ -7,13 +7,13 @@ import ( ) // HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit -func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenInit) sdk.Result { +func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenInit) (*sdk.Result, error) { err := k.ChanOpenInit( ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, msg.Channel.Counterparty, msg.Channel.Version, ) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -29,16 +29,18 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCha ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry -func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenTry) sdk.Result { +func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenTry) (*sdk.Result, error) { err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, ) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -55,16 +57,18 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck -func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenAck) sdk.Result { +func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenAck) (*sdk.Result, error) { err := k.ChanOpenAck( ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight, ) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -80,14 +84,16 @@ func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelOpenConfirm defines the sdk.Handler for MsgChannelOpenConfirm -func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenConfirm) sdk.Result { +func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenConfirm) (*sdk.Result, error) { err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofAck, msg.ProofHeight) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -103,14 +109,16 @@ func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Msg ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelCloseInit defines the sdk.Handler for MsgChannelCloseInit -func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseInit) sdk.Result { +func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseInit) (*sdk.Result, error) { err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -126,14 +134,16 @@ func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCh ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelCloseConfirm defines the sdk.Handler for MsgChannelCloseConfirm -func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseConfirm) sdk.Result { +func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseConfirm) (*sdk.Result, error) { err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofInit, msg.ProofHeight) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -149,5 +159,7 @@ func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Ms ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index 5deef767e415..c09dac9344f7 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -2,11 +2,12 @@ package keeper import ( "errors" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -38,18 +39,18 @@ func (k Keeper) ChanOpenInit( // TODO: abortTransactionUnless(validateChannelIdentifier(portIdentifier, channelIdentifier)) _, found := k.GetChannel(ctx, portID, channelID) if found { - return types.ErrChannelExists(k.codespace, channelID) + return sdkerrors.Wrap(types.ErrChannelExists, channelID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.State == connection.UNINITIALIZED { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state cannot be NONE"), + return sdkerrors.Wrap( + connection.ErrInvalidConnectionState, + "connection state cannot be UNINITIALIZED", ) } @@ -58,7 +59,7 @@ func (k Keeper) ChanOpenInit( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } */ @@ -88,25 +89,25 @@ func (k Keeper) ChanOpenTry( ) error { _, found := k.GetChannel(ctx, portID, channelID) if found { - return types.ErrChannelExists(k.codespace, channelID) + return sdkerrors.Wrap(types.ErrChannelExists, channelID) } // TODO: Maybe not right key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -130,7 +131,7 @@ func (k Keeper) ChanOpenTry( bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) if err != nil { - return errors.New("failed to marshal expected channel") + return err } if !k.connectionKeeper.VerifyMembership( @@ -138,7 +139,7 @@ func (k Keeper) ChanOpenTry( types.ChannelPath(counterparty.PortID, counterparty.ChannelID), bz, ) { - return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return sdkerrors.Wrap(types.ErrInvalidCounterparty, "channel membership verification failed") } k.SetChannel(ctx, portID, channelID, channel) @@ -162,13 +163,13 @@ func (k Keeper) ChanOpenAck( ) error { channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return types.ErrChannelNotFound(k.codespace, portID, channelID) + return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } if channel.State != types.INIT { - return types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not INIT (got %s)", channel.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not INIT (got %s)", channel.State.String(), ) } @@ -176,18 +177,18 @@ func (k Keeper) ChanOpenAck( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -206,7 +207,7 @@ func (k Keeper) ChanOpenAck( bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) if err != nil { - return errors.New("failed to marshal expected channel") + return err } if !k.connectionKeeper.VerifyMembership( @@ -214,7 +215,9 @@ func (k Keeper) ChanOpenAck( types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), bz, ) { - return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return sdkerrors.Wrap( + types.ErrInvalidCounterparty, "channel membership verification failed", + ) } channel.State = types.OPEN @@ -235,13 +238,13 @@ func (k Keeper) ChanOpenConfirm( ) error { channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return types.ErrChannelNotFound(k.codespace, portID, channelID) + return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } if channel.State != types.TRYOPEN { - return types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPENTRY (got %s)", channel.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPENTRY (got %s)", channel.State.String(), ) } @@ -249,18 +252,18 @@ func (k Keeper) ChanOpenConfirm( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -278,7 +281,7 @@ func (k Keeper) ChanOpenConfirm( bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) if err != nil { - return errors.New("failed to marshal expected channel") + return err } if !k.connectionKeeper.VerifyMembership( @@ -286,7 +289,7 @@ func (k Keeper) ChanOpenConfirm( types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), bz, ) { - return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return sdkerrors.Wrap(types.ErrInvalidCounterparty, "channel membership verification failed") } channel.State = types.OPEN @@ -311,27 +314,27 @@ func (k Keeper) ChanCloseInit( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return types.ErrChannelNotFound(k.codespace, portID, channelID) + return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } if channel.State == types.CLOSED { - return types.ErrInvalidChannelState(k.codespace, "channel is already CLOSED") + return sdkerrors.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -354,27 +357,27 @@ func (k Keeper) ChanCloseConfirm( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return types.ErrChannelNotFound(k.codespace, portID, channelID) + return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } if channel.State == types.CLOSED { - return types.ErrInvalidChannelState(k.codespace, "channel is already CLOSED") + return sdkerrors.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -400,7 +403,7 @@ func (k Keeper) ChanCloseConfirm( types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), bz, ) { - return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return sdkerrors.Wrap(types.ErrInvalidCounterparty, "channel membership verification failed") } channel.State = types.CLOSED diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index 5d72ab76cc60..92b1a3bca1f1 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -16,7 +16,6 @@ import ( type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec - codespace sdk.CodespaceType clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper portKeeper types.PortKeeper @@ -24,14 +23,13 @@ type Keeper struct { // NewKeeper creates a new IBC channel Keeper instance func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + cdc *codec.Codec, key sdk.StoreKey, clientKeeper types.ClientKeeper, connectionKeeper types.ConnectionKeeper, portKeeper types.PortKeeper, ) Keeper { return Keeper{ storeKey: key, cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/channel", clientKeeper: clientKeeper, connectionKeeper: connectionKeeper, portKeeper: portKeeper, diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 515b7ecdf107..2703f283a814 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -3,13 +3,14 @@ package keeper import ( "bytes" "errors" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -34,51 +35,50 @@ func (k Keeper) CleanupPacket( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } if channel.State != types.OPEN { - return nil, types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + return nil, sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), ) } _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelCapabilityNotFound(k.codespace) + return nil, types.ErrChannelCapabilityNotFound } if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return nil, errors.New("port is not valid") + return nil, sdkerrors.Wrapf(port.ErrInvalidPort, "invalid source port: %s", packet.GetSourcePort()) } if packet.GetDestChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if packet.GetDestPort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf(types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, ) } if nextSequenceRecv >= packet.GetSequence() { - return nil, types.ErrInvalidPacket(k.codespace, "packet already received") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet already received") } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } var ok bool @@ -96,11 +96,11 @@ func (k Keeper) CleanupPacket( acknowledgement, ) default: - panic(fmt.Sprintf("invalid channel ordering type %v", channel.Ordering)) + panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) } if !ok { - return nil, types.ErrInvalidPacket(k.codespace, "packet verification failed") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet verification failed") } k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) @@ -121,64 +121,64 @@ func (k Keeper) SendPacket( channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } if channel.State == types.CLOSED { - return types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel is CLOSED (got %s)", channel.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel is CLOSED (got %s)", channel.State.String(), ) } if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, packet.GetSourcePort()) } if packet.GetDestPort() != channel.Counterparty.PortID { - return types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + return sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, ) } if packet.GetDestChannel() != channel.Counterparty.ChannelID { - return types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + return sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State == connection.UNINITIALIZED { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection is closed (i.e NONE)"), + return sdkerrors.Wrap( + connection.ErrInvalidConnectionState, + "connection is closed (i.e NONE)", ) } - consensusState, found := k.clientKeeper.GetConsensusState(ctx, connectionEnd.ClientID) + _, found = k.clientKeeper.GetConsensusState(ctx, connectionEnd.ClientID) if !found { - return client.ErrConsensusStateNotFound(k.codespace) + return client.ErrConsensusStateNotFound } - if consensusState.GetHeight() >= packet.GetTimeoutHeight() { - return types.ErrPacketTimeout(k.codespace) + if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { + return types.ErrPacketTimeout } nextSequenceSend, found := k.GetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return types.ErrSequenceNotFound(k.codespace, "send") + return types.ErrSequenceSendNotFound } if packet.GetSequence() != nextSequenceSend { - return types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet sequence ≠ next send sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceSend), + return sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet sequence ≠ next send sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceSend, ) } @@ -202,49 +202,49 @@ func (k Keeper) RecvPacket( channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetDestPort(), packet.GetDestChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetDestChannel()) } if channel.State != types.OPEN { - return nil, types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + return nil, sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), ) } if !k.portKeeper.Authenticate(portCapability, packet.GetDestPort()) { - return nil, errors.New("port is not valid") + return nil, sdkerrors.Wrap(port.ErrInvalidPort, packet.GetDestPort()) } // packet must come from the channel's counterparty if packet.GetSourcePort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID, ) } if packet.GetSourceChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return nil, connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return nil, sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { - return nil, types.ErrPacketTimeout(k.codespace) + return nil, types.ErrPacketTimeout } if !k.connectionKeeper.VerifyMembership( @@ -265,13 +265,13 @@ func (k Keeper) RecvPacket( if channel.Ordering == types.ORDERED { nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { - return nil, types.ErrSequenceNotFound(k.codespace, "receive") + return nil, types.ErrSequenceReceiveNotFound } if packet.GetSequence() != nextSequenceRecv { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv, ) } @@ -298,13 +298,13 @@ func (k Keeper) AcknowledgePacket( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } if channel.State != types.OPEN { - return nil, types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + return nil, sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), ) } @@ -314,34 +314,34 @@ func (k Keeper) AcknowledgePacket( // packet must come from the channel's counterparty if packet.GetSourcePort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID, ) } if packet.GetSourceChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return nil, connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return nil, sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } if !k.connectionKeeper.VerifyMembership( diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go index 8aef90c879ad..8c8cac783cec 100644 --- a/x/ibc/04-channel/keeper/querier.go +++ b/x/ibc/04-channel/keeper/querier.go @@ -20,7 +20,7 @@ func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) if !found { - return nil, types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, params.ChannelID) } bz, err := codec.MarshalJSONIndent(k.cdc, channel) diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index 3ae481373de3..af54040dad2c 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -3,9 +3,9 @@ package keeper import ( "bytes" "errors" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" @@ -27,19 +27,19 @@ func (k Keeper) TimeoutPacket( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } if channel.State != types.OPEN { - return nil, types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + return nil, sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), ) } _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelCapabilityNotFound(k.codespace) + return nil, types.ErrChannelCapabilityNotFound } if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { @@ -47,35 +47,35 @@ func (k Keeper) TimeoutPacket( } if packet.GetDestChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if packet.GetDestPort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, ) } if proofHeight < packet.GetTimeoutHeight() { - return nil, types.ErrPacketTimeout(k.codespace) + return nil, types.ErrPacketTimeout } if nextSequenceRecv >= packet.GetSequence() { - return nil, types.ErrInvalidPacket(k.codespace, "packet already received") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet already received") } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } var ok bool @@ -92,11 +92,11 @@ func (k Keeper) TimeoutPacket( types.PacketAcknowledgementPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), ) default: - panic(fmt.Sprintf("invalid channel ordering type %v", channel.Ordering)) + panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) } if !ok { - return nil, types.ErrInvalidPacket(k.codespace, "packet verification failed") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet verification failed") } k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) @@ -122,12 +122,12 @@ func (k Keeper) TimeoutOnClose( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelCapabilityNotFound(k.codespace) + return nil, types.ErrChannelCapabilityNotFound } if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { @@ -135,27 +135,27 @@ func (k Keeper) TimeoutOnClose( } if packet.GetDestChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if packet.GetDestPort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, ) } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } counterpartyHops, found := k.CounterpartyHops(ctx, channel) @@ -179,7 +179,10 @@ func (k Keeper) TimeoutOnClose( types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), bz, ) { - return nil, types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return nil, sdkerrors.Wrap( + types.ErrInvalidCounterparty, + "channel membership verification failed", + ) } if !k.connectionKeeper.VerifyNonMembership( diff --git a/x/ibc/04-channel/types/channel.go b/x/ibc/04-channel/types/channel.go index 1250d1208808..ae38cb2212df 100644 --- a/x/ibc/04-channel/types/channel.go +++ b/x/ibc/04-channel/types/channel.go @@ -2,11 +2,11 @@ package types import ( "encoding/json" - "fmt" "strings" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) type Channel struct { @@ -34,25 +34,25 @@ func NewChannel( // ValidateBasic performs a basic validation of the channel fields func (ch Channel) ValidateBasic() error { if ch.State.String() == "" { - return ErrInvalidChannelState( - DefaultCodespace, - "channel order should be either 'ORDERED' or 'UNORDERED'", - ) + return sdkerrors.Wrap(ErrInvalidChannel, ErrInvalidChannelState.Error()) } if ch.Ordering.String() == "" { - return ErrInvalidChannel( - DefaultCodespace, - "channel order should be either 'ORDERED' or 'UNORDERED'", - ) + return sdkerrors.Wrap(ErrInvalidChannel, ErrInvalidChannelOrdering.Error()) } if len(ch.ConnectionHops) != 1 { - return ErrInvalidChannel(DefaultCodespace, "IBC v1 only supports one connection hop") + return sdkerrors.Wrap(ErrInvalidChannel, "IBC v1 only supports one connection hop") } if err := host.DefaultConnectionIdentifierValidator(ch.ConnectionHops[0]); err != nil { - return sdkerrors.Wrap(err, "invalid connection hop ID") + return sdkerrors.Wrap( + ErrInvalidChannel, + sdkerrors.Wrap(err, "invalid connection hop ID").Error(), + ) } if strings.TrimSpace(ch.Version) == "" { - return ErrInvalidChannel(DefaultCodespace, "channel version can't be blank") + return sdkerrors.Wrap( + ErrInvalidChannel, + sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "channel version can't be blank").Error(), + ) } return ch.Counterparty.ValidateBasic() } @@ -74,10 +74,16 @@ func NewCounterparty(portID, channelID string) Counterparty { // ValidateBasic performs a basic validation check of the identifiers func (c Counterparty) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(c.PortID); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty connection ID") + return sdkerrors.Wrap( + ErrInvalidCounterparty, + sdkerrors.Wrap(err, "invalid counterparty connection ID").Error(), + ) } if err := host.DefaultChannelIdentifierValidator(c.ChannelID); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty client ID") + return sdkerrors.Wrap( + ErrInvalidCounterparty, + sdkerrors.Wrap(err, "invalid counterparty client ID").Error(), + ) } return nil } @@ -126,7 +132,7 @@ func (o *Order) UnmarshalJSON(data []byte) error { order := OrderFromString(s) if order == 0 { - return fmt.Errorf("invalid channel ordering '%s'", s) + return sdkerrors.Wrap(ErrInvalidChannelOrdering, s) } *o = order diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go index 318c78017d34..40e526476eae 100644 --- a/x/ibc/04-channel/types/errors.go +++ b/x/ibc/04-channel/types/errors.go @@ -1,104 +1,20 @@ package types import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// channel error codes -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodeChannelExists sdk.CodeType = 219 - CodeChannelNotFound sdk.CodeType = 220 - CodeInvalidCounterpartyChannel sdk.CodeType = 221 - CodeChannelCapabilityNotFound sdk.CodeType = 222 - CodeInvalidPacket sdk.CodeType = 223 - CodeSequenceNotFound sdk.CodeType = 224 - CodePacketTimeout sdk.CodeType = 225 - CodeInvalidChannel sdk.CodeType = 226 - CodeInvalidChannelState sdk.CodeType = 227 +// IBC channel sentinel errors +var ( + ErrChannelExists = sdkerrors.Register(SubModuleName, 1, "channel already exists") + ErrChannelNotFound = sdkerrors.Register(SubModuleName, 2, "channel not found") + ErrInvalidChannel = sdkerrors.Register(SubModuleName, 3, "invalid channel") + ErrInvalidChannelState = sdkerrors.Register(SubModuleName, 4, "invalid channel state") + ErrInvalidChannelOrdering = sdkerrors.Register(SubModuleName, 5, "invalid channel ordering") + ErrInvalidCounterparty = sdkerrors.Register(SubModuleName, 6, "invalid counterparty channel") + ErrChannelCapabilityNotFound = sdkerrors.Register(SubModuleName, 7, "channel capability not found") + ErrSequenceSendNotFound = sdkerrors.Register(SubModuleName, 8, "sequence send not found") + ErrSequenceReceiveNotFound = sdkerrors.Register(SubModuleName, 9, "sequence receive not found") + ErrInvalidPacket = sdkerrors.Register(SubModuleName, 10, "invalid packet") + ErrPacketTimeout = sdkerrors.Register(SubModuleName, 11, "packet timeout") ) - -// ErrChannelExists implements sdk.Error -func ErrChannelExists(codespace sdk.CodespaceType, channelID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeChannelExists), - fmt.Sprintf("channel with ID %s already exists", channelID), - ) -} - -// ErrChannelNotFound implements sdk.Error -func ErrChannelNotFound(codespace sdk.CodespaceType, portID, channelID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeChannelNotFound), - fmt.Sprintf("channel with ID %s on port %s not found", channelID, portID), - ) -} - -// ErrInvalidCounterpartyChannel implements sdk.Error -func ErrInvalidCounterpartyChannel(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidCounterpartyChannel), - msg, - ) -} - -// ErrChannelCapabilityNotFound implements sdk.Error -func ErrChannelCapabilityNotFound(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeChannelCapabilityNotFound), - "channel capability key not found", - ) -} - -// ErrInvalidPacket implements sdk.Error -func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidPacket), - msg, - ) -} - -// ErrSequenceNotFound implements sdk.Error -func ErrSequenceNotFound(codespace sdk.CodespaceType, seqType string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeSequenceNotFound), - fmt.Sprintf("next %s sequence counter not found", seqType), - ) -} - -// ErrPacketTimeout implements sdk.Error -func ErrPacketTimeout(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodePacketTimeout), - "packet timeout", - ) -} - -// ErrInvalidChannel implements sdk.Error -func ErrInvalidChannel(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidChannel), - msg, - ) -} - -// ErrInvalidChannelState implements sdk.Error -func ErrInvalidChannelState(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidChannelState), - msg, - ) -} diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index 16a7a1943999..d0a9e71955ba 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -45,15 +45,15 @@ func (msg MsgChannelOpenInit) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelOpenInit) ValidateBasic() sdk.Error { +func (msg MsgChannelOpenInit) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } // Signer can be empty - return sdk.ConvertError(msg.Channel.ValidateBasic()) + return msg.Channel.ValidateBasic() } // GetSignBytes implements sdk.Msg @@ -108,24 +108,27 @@ func (msg MsgChannelOpenTry) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelOpenTry) ValidateBasic() sdk.Error { +func (msg MsgChannelOpenTry) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } if strings.TrimSpace(msg.CounterpartyVersion) == "" { - return sdk.ConvertError(ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank")) + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty version cannot be blank") } if msg.ProofInit == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofInit.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof init cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } // Signer can be empty - return sdk.ConvertError(msg.Channel.ValidateBasic()) + return msg.Channel.ValidateBasic() } // GetSignBytes implements sdk.Msg @@ -175,21 +178,24 @@ func (msg MsgChannelOpenAck) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelOpenAck) ValidateBasic() sdk.Error { +func (msg MsgChannelOpenAck) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } if strings.TrimSpace(msg.CounterpartyVersion) == "" { - return sdk.ConvertError(ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank")) + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty version cannot be blank") } if msg.ProofTry == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofTry.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof try cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } // Signer can be empty return nil @@ -240,18 +246,21 @@ func (msg MsgChannelOpenConfirm) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelOpenConfirm) ValidateBasic() sdk.Error { +func (msg MsgChannelOpenConfirm) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } if msg.ProofAck == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofAck.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } // Signer can be empty return nil @@ -295,12 +304,12 @@ func (msg MsgChannelCloseInit) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelCloseInit) ValidateBasic() sdk.Error { +func (msg MsgChannelCloseInit) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } // Signer can be empty return nil @@ -351,18 +360,21 @@ func (msg MsgChannelCloseConfirm) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelCloseConfirm) ValidateBasic() sdk.Error { +func (msg MsgChannelCloseConfirm) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } if msg.ProofInit == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofInit.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof init cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } // Signer can be empty return nil diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index 3754ea4efa1a..2165f8c4eb40 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -1,10 +1,17 @@ package types import ( + "fmt" "testing" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -36,8 +43,39 @@ var ( addr = sdk.AccAddress("testaddr") ) +type MsgTestSuite struct { + suite.Suite + + proof commitment.Proof +} + +func (suite *MsgTestSuite) SetupTest() { + db := dbm.NewMemDB() + store := rootmulti.NewStore(db) + storeKey := storetypes.NewKVStoreKey("iavlStoreKey") + + store.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) + store.LoadVersion(0) + iavlStore := store.GetCommitStore(storeKey).(*iavl.Store) + + iavlStore.Set([]byte("KEY"), []byte("VALUE")) + _ = store.Commit() + + res := store.Query(abci.RequestQuery{ + Path: fmt.Sprintf("/%s/key", storeKey.Name()), // required path to get key/value+proof + Data: []byte("KEY"), + Prove: true, + }) + + suite.proof = commitment.Proof{Proof: res.Proof} +} + +func TestMsgTestSuite(t *testing.T) { + suite.Run(t, new(MsgTestSuite)) +} + // TestMsgChannelOpenInit tests ValidateBasic for MsgChannelOpenInit -func TestMsgChannelOpenInit(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelOpenInit() { testMsgs := []MsgChannelOpenInit{ NewMsgChannelOpenInit("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id @@ -81,34 +119,34 @@ func TestMsgChannelOpenInit(t *testing.T) { for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelOpenTry tests ValidateBasic for MsgChannelOpenTry -func TestMsgChannelOpenTry(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelOpenTry() { testMsgs := []MsgChannelOpenTry{ - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // valid msg - NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short port id - NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long port id - NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenTry("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short channel id - NewMsgChannelOpenTry("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long channel id - NewMsgChannelOpenTry("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", proof, 1, addr), // empty counterparty version - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty proof - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 0, addr), // proof height is zero - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // invalid channel order - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection hops more than 1 - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short connection id - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long connection id - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection id contains non-alpha - NewMsgChannelOpenTry("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // empty channel version - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", proof, 1, addr), // invalid counterparty port id - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", proof, 1, addr), // invalid counterparty channel id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // valid msg + NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short port id + NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long port id + NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenTry("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short channel id + NewMsgChannelOpenTry("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long channel id + NewMsgChannelOpenTry("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", suite.proof, 1, addr), // empty counterparty version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty suite.proof + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 0, addr), // suite.proof height is zero + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // invalid channel order + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // connection hops more than 1 + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // connection id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // empty channel version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", suite.proof, 1, addr), // invalid counterparty port id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", suite.proof, 1, addr), // invalid counterparty channel id } testCases := []struct { @@ -139,26 +177,27 @@ func TestMsgChannelOpenTry(t *testing.T) { for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelOpenAck tests ValidateBasic for MsgChannelOpenAck -func TestMsgChannelOpenAck(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelOpenAck() { testMsgs := []MsgChannelOpenAck{ - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", proof, 1, addr), // valid msg - NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", proof, 1, addr), // too short port id - NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", proof, 1, addr), // too long port id - NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenAck("testportid", invalidShortChannel, "1.0", proof, 1, addr), // too short channel id - NewMsgChannelOpenAck("testportid", invalidLongChannel, "1.0", proof, 1, addr), // too long channel id - NewMsgChannelOpenAck("testportid", invalidChannel, "1.0", proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenAck("testportid", "testchannel", "", proof, 1, addr), // empty counterparty version - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", nil, 1, addr), // empty proof - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", proof, 0, addr), // proof height is zero + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", suite.proof, 1, addr), // valid msg + NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", suite.proof, 1, addr), // too short port id + NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", suite.proof, 1, addr), // too long port id + NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenAck("testportid", invalidShortChannel, "1.0", suite.proof, 1, addr), // too short channel id + NewMsgChannelOpenAck("testportid", invalidLongChannel, "1.0", suite.proof, 1, addr), // too long channel id + NewMsgChannelOpenAck("testportid", invalidChannel, "1.0", suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenAck("testportid", "testchannel", "", suite.proof, 1, addr), // empty counterparty version + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", commitment.Proof{Proof: nil}, 1, addr), // empty proof + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", suite.proof, 0, addr), // proof height is zero } testCases := []struct { @@ -175,31 +214,33 @@ func TestMsgChannelOpenAck(t *testing.T) { {testMsgs[6], false, "channel id contains non-alpha"}, {testMsgs[7], false, "empty counterparty version"}, {testMsgs[8], false, "empty proof"}, - {testMsgs[9], false, "proof height is zero"}, + {testMsgs[9], false, "empty proof"}, + {testMsgs[10], false, "proof height is zero"}, } for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelOpenConfirm tests ValidateBasic for MsgChannelOpenConfirm -func TestMsgChannelOpenConfirm(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelOpenConfirm() { testMsgs := []MsgChannelOpenConfirm{ - NewMsgChannelOpenConfirm("testportid", "testchannel", proof, 1, addr), // valid msg - NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id - NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id - NewMsgChannelOpenConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenConfirm("testportid", invalidShortChannel, proof, 1, addr), // too short channel id - NewMsgChannelOpenConfirm("testportid", invalidLongChannel, proof, 1, addr), // too long channel id - NewMsgChannelOpenConfirm("testportid", invalidChannel, proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenConfirm("testportid", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelOpenConfirm("testportid", "testchannel", proof, 0, addr), // proof height is zero + NewMsgChannelOpenConfirm("testportid", "testchannel", suite.proof, 1, addr), // valid msg + NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", suite.proof, 1, addr), // too short port id + NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", suite.proof, 1, addr), // too long port id + NewMsgChannelOpenConfirm(invalidPort, "testchannel", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenConfirm("testportid", invalidShortChannel, suite.proof, 1, addr), // too short channel id + NewMsgChannelOpenConfirm("testportid", invalidLongChannel, suite.proof, 1, addr), // too long channel id + NewMsgChannelOpenConfirm("testportid", invalidChannel, suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testportid", "testchannel", commitment.Proof{Proof: nil}, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testportid", "testchannel", suite.proof, 0, addr), // proof height is zero } testCases := []struct { @@ -215,21 +256,22 @@ func TestMsgChannelOpenConfirm(t *testing.T) { {testMsgs[5], false, "too long channel id"}, {testMsgs[6], false, "channel id contains non-alpha"}, {testMsgs[7], false, "empty proof"}, - {testMsgs[8], false, "proof height is zero"}, + {testMsgs[8], false, "empty proof"}, + {testMsgs[9], false, "proof height is zero"}, } for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelCloseInit tests ValidateBasic for MsgChannelCloseInit -func TestMsgChannelCloseInit(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelCloseInit() { testMsgs := []MsgChannelCloseInit{ NewMsgChannelCloseInit("testportid", "testchannel", addr), // valid msg NewMsgChannelCloseInit(invalidShortPort, "testchannel", addr), // too short port id @@ -257,25 +299,26 @@ func TestMsgChannelCloseInit(t *testing.T) { for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelCloseConfirm tests ValidateBasic for MsgChannelCloseConfirm -func TestMsgChannelCloseConfirm(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelCloseConfirm() { testMsgs := []MsgChannelCloseConfirm{ - NewMsgChannelCloseConfirm("testportid", "testchannel", proof, 1, addr), // valid msg - NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id - NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id - NewMsgChannelCloseConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha - NewMsgChannelCloseConfirm("testportid", invalidShortChannel, proof, 1, addr), // too short channel id - NewMsgChannelCloseConfirm("testportid", invalidLongChannel, proof, 1, addr), // too long channel id - NewMsgChannelCloseConfirm("testportid", invalidChannel, proof, 1, addr), // channel id contains non-alpha - NewMsgChannelCloseConfirm("testportid", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelCloseConfirm("testportid", "testchannel", proof, 0, addr), // proof height is zero + NewMsgChannelCloseConfirm("testportid", "testchannel", suite.proof, 1, addr), // valid msg + NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", suite.proof, 1, addr), // too short port id + NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", suite.proof, 1, addr), // too long port id + NewMsgChannelCloseConfirm(invalidPort, "testchannel", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelCloseConfirm("testportid", invalidShortChannel, suite.proof, 1, addr), // too short channel id + NewMsgChannelCloseConfirm("testportid", invalidLongChannel, suite.proof, 1, addr), // too long channel id + NewMsgChannelCloseConfirm("testportid", invalidChannel, suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelCloseConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testportid", "testchannel", commitment.Proof{Proof: nil}, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testportid", "testchannel", suite.proof, 0, addr), // proof height is zero } testCases := []struct { @@ -291,15 +334,16 @@ func TestMsgChannelCloseConfirm(t *testing.T) { {testMsgs[5], false, "too long channel id"}, {testMsgs[6], false, "channel id contains non-alpha"}, {testMsgs[7], false, "empty proof"}, - {testMsgs[8], false, "proof height is zero"}, + {testMsgs[8], false, "empty proof"}, + {testMsgs[9], false, "proof height is zero"}, } for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go index 8cfadf458487..7d8242d8db30 100644 --- a/x/ibc/04-channel/types/packet.go +++ b/x/ibc/04-channel/types/packet.go @@ -1,8 +1,7 @@ package types import ( - "fmt" - + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -11,13 +10,13 @@ var _ exported.PacketI = Packet{} // Packet defines a type that carries data across different chains through IBC type Packet struct { - Sequence uint64 `json:"sequence"` // number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. - Timeout uint64 `json:"timeout"` // indicates a consensus height on the destination chain after which the Packet will no longer be processed, and will instead count as having timed-out. - SourcePort string `json:"source_port"` // identifies the port on the sending chain. - SourceChannel string `json:"source_channel"` // identifies the channel end on the sending chain. - DestinationPort string `json:"destination_port"` // identifies the port on the receiving chain. - DestinationChannel string `json:"destination_channel"` // identifies the channel end on the receiving chain. - Data []byte `json:"data"` // opaque value which can be defined by the application logic of the associated modules. + Sequence uint64 `json:"sequence" yaml:"sequence"` // number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. + Timeout uint64 `json:"timeout" yaml:"timeout"` // indicates a consensus height on the destination chain after which the Packet will no longer be processed, and will instead count as having timed-out. + SourcePort string `json:"source_port" yaml:"source_port"` // identifies the port on the sending chain. + SourceChannel string `json:"source_channel" yaml:"source_channel"` // identifies the channel end on the sending chain. + DestinationPort string `json:"destination_port" yaml:"destination_port"` // identifies the port on the receiving chain. + DestinationChannel string `json:"destination_channel" yaml:"destination_channel"` // identifies the channel end on the receiving chain. + Data []byte `json:"data" yaml:"data"` // opaque value which can be defined by the application logic of the associated modules. } // NewPacket creates a new Packet instance @@ -26,13 +25,13 @@ func NewPacket( destinationPort, destinationChannel string, data []byte, ) Packet { return Packet{ - sequence, - timeout, - sourcePort, - sourceChannel, - destinationPort, - destinationChannel, - data, + Sequence: sequence, + Timeout: timeout, + SourcePort: sourcePort, + SourceChannel: sourceChannel, + DestinationPort: destinationPort, + DestinationChannel: destinationChannel, + Data: data, } } @@ -60,25 +59,37 @@ func (p Packet) GetData() []byte { return p.Data } // ValidateBasic implements PacketI interface func (p Packet) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(p.SourcePort); err != nil { - return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source port ID: %s", err.Error())) + return sdkerrors.Wrapf( + ErrInvalidPacket, + sdkerrors.Wrapf(err, "invalid source port ID: %s", p.SourcePort).Error(), + ) } if err := host.DefaultPortIdentifierValidator(p.DestinationPort); err != nil { - return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid destination port ID: %s", err.Error())) + return sdkerrors.Wrapf( + ErrInvalidPacket, + sdkerrors.Wrapf(err, "invalid destination port ID: %s", p.DestinationPort).Error(), + ) } if err := host.DefaultChannelIdentifierValidator(p.SourceChannel); err != nil { - return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source channel ID: %s", err.Error())) + return sdkerrors.Wrapf( + ErrInvalidPacket, + sdkerrors.Wrapf(err, "invalid source channel ID: %s", p.SourceChannel).Error(), + ) } if err := host.DefaultChannelIdentifierValidator(p.DestinationChannel); err != nil { - return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid destination channel ID: %s", err.Error())) + return sdkerrors.Wrapf( + ErrInvalidPacket, + sdkerrors.Wrapf(err, "invalid destination channel ID: %s", p.DestinationChannel).Error(), + ) } if p.Sequence == 0 { - return ErrInvalidPacket(DefaultCodespace, "packet sequence cannot be 0") + return sdkerrors.Wrap(ErrInvalidPacket, "packet sequence cannot be 0") } if p.Timeout == 0 { - return ErrPacketTimeout(DefaultCodespace) + return sdkerrors.Wrap(ErrInvalidPacket, "packet timeout cannot be 0") } if len(p.Data) == 0 { - return ErrInvalidPacket(DefaultCodespace, "packet data cannot be empty") + return sdkerrors.Wrap(ErrInvalidPacket, "packet data cannot be empty") } return nil } diff --git a/x/ibc/05-port/alias.go b/x/ibc/05-port/alias.go index ef3b6be60633..f53d7a41f9ee 100644 --- a/x/ibc/05-port/alias.go +++ b/x/ibc/05-port/alias.go @@ -12,13 +12,10 @@ import ( ) const ( - DefaultCodespace = types.DefaultCodespace - CodePortExists = types.CodePortExists - CodePortNotFound = types.CodePortNotFound - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute ) var ( diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index 3d17a6881be8..45f0817f7702 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -5,25 +5,22 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) // Keeper defines the IBC connection keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType - ports map[string]bool + storeKey sdk.StoreKey + cdc *codec.Codec + ports map[string]bool } // NewKeeper creates a new IBC connection Keeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/port", - ports: make(map[string]bool), // map of capability key names to port ids + storeKey: key, + cdc: cdc, + ports: make(map[string]bool), // map of capability key names to port ids } } diff --git a/x/ibc/05-port/types/errors.go b/x/ibc/05-port/types/errors.go index d15b07bf0791..a0778ecd6b01 100644 --- a/x/ibc/05-port/types/errors.go +++ b/x/ibc/05-port/types/errors.go @@ -1,44 +1,12 @@ package types import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// port error codes -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodePortExists sdk.CodeType = 228 - CodePortNotFound sdk.CodeType = 229 - CodeInvalidPort sdk.CodeType = 230 +// IBC port sentinel errors +var ( + ErrPortExists = sdkerrors.Register(SubModuleName, 1, "port is already binded") + ErrPortNotFound = sdkerrors.Register(SubModuleName, 2, "port not found") + ErrInvalidPort = sdkerrors.Register(SubModuleName, 3, "invalid port") ) - -// ErrPortExists implements sdk.Error -func ErrPortExists(codespace sdk.CodespaceType, portID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodePortExists), - fmt.Sprintf("port with ID %s is already binded", portID), - ) -} - -// ErrPortNotFound implements sdk.Error -func ErrPortNotFound(codespace sdk.CodespaceType, portID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodePortNotFound), - fmt.Sprintf("port with ID %s not found", portID), - ) -} - -// ErrInvalidPort implements sdk.Error -func ErrInvalidPort(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodePortNotFound), - msg, - ) -} diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go index ee87c56d8b3e..00333d69f4b2 100644 --- a/x/ibc/20-transfer/alias.go +++ b/x/ibc/20-transfer/alias.go @@ -13,7 +13,6 @@ import ( const ( DefaultPacketTimeout = keeper.DefaultPacketTimeout - DefaultCodespace = types.DefaultCodespace AttributeKeyReceiver = types.AttributeKeyReceiver SubModuleName = types.SubModuleName StoreKey = types.StoreKey diff --git a/x/ibc/20-transfer/client/cli/cli.go b/x/ibc/20-transfer/client/cli/cli.go index 2007ed31908d..45a41239f974 100644 --- a/x/ibc/20-transfer/client/cli/cli.go +++ b/x/ibc/20-transfer/client/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) @@ -14,7 +14,7 @@ func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { Short: "IBC fungible token transfer query subcommands", } - ics20TransferQueryCmd.AddCommand(client.GetCommands( + ics20TransferQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryNextSequence(cdc, queryRoute), )...) @@ -28,7 +28,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { Short: "IBC fungible token transfer transaction subcommands", } - ics20TransferTxCmd.AddCommand(client.PostCommands( + ics20TransferTxCmd.AddCommand(flags.PostCommands( GetTransferTxCmd(cdc), // GetMsgRecvPacketCmd(cdc), )...) diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 731a6c27e7f5..6dfcf0470e4d 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -6,10 +6,10 @@ import ( ) // HandleMsgTransfer defines the sdk.Handler for MsgTransfer -func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Result) { +func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) { err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvent( @@ -21,14 +21,16 @@ func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Resu ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgRecvPacket defines the sdk.Handler for MsgRecvPacket -func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (res sdk.Result) { +func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (*sdk.Result, error) { err := k.ReceivePacket(ctx, msg.Packet, msg.Proofs[0], msg.Height) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvent( @@ -39,5 +41,7 @@ func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (res sdk. ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 46ef6f08558b..d3db1ed739fc 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -160,35 +160,41 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { source := true msg := transfer.NewMsgTransfer(testPort1, testChannel1, testCoins, testAddr1, testAddr2, source) - res := transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // channel does not exist + res, err := transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // next send sequence not found + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // next send sequence not found nextSeqSend := uint64(1) suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // sender has insufficient coins + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // sender has insufficient coins _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.True(res.Code.IsOK(), "%v", res) // successfully executed + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().NoError(err) + suite.Require().NotNil(res, "%v", res) // successfully executed // test when the source is false source = false msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, source) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // incorrect denom prefix + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // incorrect denom prefix msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, source) suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.True(res.Code.IsOK(), "%v", res) // successfully executed + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().NoError(err) + suite.Require().NotNil(res, "%v", res) // successfully executed } func (suite *HandlerTestSuite) TestHandleRecvPacket() { @@ -205,16 +211,18 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { msg := types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - res := transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // packet membership verification failed due to invalid counterparty packet commitment + res, err := transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // packet membership verification failed due to invalid counterparty packet commitment suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) suite.updateClient() proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // invalid packet data + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // invalid packet data // test when the source is true source := true @@ -228,8 +236,9 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // invalid denom prefix + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // invalid denom prefix packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) @@ -240,8 +249,9 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.True(res.Code.IsOK(), "%v", res) // successfully executed + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().NoError(err) + suite.Require().NotNil(res, "%v", res) // successfully executed // test when the source is false source = false @@ -255,8 +265,9 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // invalid denom prefix + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // invalid denom prefix packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) @@ -267,13 +278,15 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // insufficient coins in the corresponding escrow account + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // insufficient coins in the corresponding escrow account escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.True(res.Code.IsOK(), "%v", res) // successfully executed + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().NoError(err) + suite.Require().NotNil(res, "%v", res) // successfully executed } func TestHandlerTestSuite(t *testing.T) { diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go index 57c772e67b2f..b4c0675bed78 100644 --- a/x/ibc/20-transfer/keeper/callbacks.go +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -1,7 +1,6 @@ package keeper import ( - "fmt" "strings" sdk "github.com/cosmos/cosmos-sdk/types" @@ -24,18 +23,19 @@ func (k Keeper) OnChanOpenInit( version string, ) error { if order != channel.UNORDERED { - return channel.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") + return sdkerrors.Wrap(channel.ErrInvalidChannel, "channel must be UNORDERED") } // NOTE: here the capability key name defines the port ID of the counterparty if counterparty.PortID != k.boundedCapability.Name() { - return port.ErrInvalidPort( - k.codespace, - fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name())) + return sdkerrors.Wrapf( + port.ErrInvalidPort, + "counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name(), + ) } if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version must be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -55,22 +55,23 @@ func (k Keeper) OnChanOpenTry( counterpartyVersion string, ) error { if order != channel.UNORDERED { - return channel.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") + return sdkerrors.Wrap(channel.ErrInvalidChannel, "channel must be UNORDERED") } // NOTE: here the capability key name defines the port ID of the counterparty if counterparty.PortID != k.boundedCapability.Name() { - return port.ErrInvalidPort( - k.codespace, - fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name())) + return sdkerrors.Wrapf( + port.ErrInvalidPort, + "counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name(), + ) } if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version must be blank") } if strings.TrimSpace(counterpartyVersion) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "counterparty version must be blank") + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "counterparty version must be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -86,7 +87,7 @@ func (k Keeper) OnChanOpenAck( version string, ) error { if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version must be blank") } return nil @@ -169,7 +170,10 @@ func (k Keeper) OnTimeoutPacket( for i, coin := range data.Amount { coin := coin if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) } diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index c42786f42741..341f75374881 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -19,9 +19,8 @@ const ( // Keeper defines the IBC transfer keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType + storeKey sdk.StoreKey + cdc *codec.Codec // Capability key and port to which ICS20 is binded. Used for packet relaying. boundedCapability sdk.CapabilityKey @@ -35,7 +34,7 @@ type Keeper struct { // NewKeeper creates a new IBC transfer Keeper instance func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + cdc *codec.Codec, key sdk.StoreKey, capKey sdk.CapabilityKey, clientKeeper types.ClientKeeper, connnectionKeeper types.ConnectionKeeper, channelKeeper types.ChannelKeeper, bankKeeper types.BankKeeper, supplyKeeper types.SupplyKeeper, @@ -49,7 +48,6 @@ func NewKeeper( return Keeper{ storeKey: key, cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/transfer", boundedCapability: capKey, clientKeeper: clientKeeper, connectionKeeper: connnectionKeeper, diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index 8c3a6bb2ea5b..f30d59de04fb 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -1,7 +1,6 @@ package keeper import ( - "fmt" "strings" sdk "github.com/cosmos/cosmos-sdk/types" @@ -25,7 +24,7 @@ func (k Keeper) SendTransfer( // get the port and channel of the counterparty sourceChan, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) if !found { - return channel.ErrChannelNotFound(k.codespace, sourcePort, sourceChannel) + return sdkerrors.Wrap(channel.ErrChannelNotFound, sourceChannel) } destinationPort := sourceChan.Counterparty.PortID @@ -34,7 +33,7 @@ func (k Keeper) SendTransfer( // get the next sequence sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel) if !found { - return channel.ErrSequenceNotFound(k.codespace, "send") + return channel.ErrSequenceSendNotFound } coins := make(sdk.Coins, len(amount)) @@ -81,7 +80,10 @@ func (k Keeper) ReceiveTransfer( prefix := types.GetDenomPrefix(destinationPort, destinationChannel) for _, coin := range data.Amount { if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } } @@ -102,7 +104,10 @@ func (k Keeper) ReceiveTransfer( coins := make(sdk.Coins, len(data.Amount)) for i, coin := range data.Amount { if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) } @@ -132,7 +137,10 @@ func (k Keeper) createOutgoingPacket( coins := make(sdk.Coins, len(amount)) for i, coin := range amount { if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) } @@ -147,7 +155,10 @@ func (k Keeper) createOutgoingPacket( prefix := types.GetDenomPrefix(sourcePort, sourceChannel) for _, coin := range amount { if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } } diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index 252eb8060645..e7c709306228 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -12,7 +12,7 @@ import ( // BankKeeper defines the expected bank keeper type BankKeeper interface { - SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error } // ChannelKeeper defines the expected IBC channel keeper @@ -37,8 +37,8 @@ type ConnectionKeeper interface { type SupplyKeeper interface { GetModuleAddress(name string) sdk.AccAddress GetModuleAccount(ctx sdk.Context, name string) supplyexported.ModuleAccountI - MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error - BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error - SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error + MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error + BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error } diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go index 469456bbd946..1a3a8458ae53 100644 --- a/x/ibc/20-transfer/types/keys.go +++ b/x/ibc/20-transfer/types/keys.go @@ -21,9 +21,6 @@ const ( // QuerierRoute is the querier route for IBC transfer QuerierRoute = SubModuleName - - // DefaultCodespace is the default error codespace for the ibc transfers - DefaultCodespace sdk.CodespaceType = SubModuleName ) // GetEscrowAddress returns the escrow address for the specified channel diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index 2a353de56cff..42a56e0f30a6 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -3,7 +3,6 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" @@ -44,24 +43,24 @@ func (MsgTransfer) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgTransfer) ValidateBasic() sdk.Error { +func (msg MsgTransfer) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.SourcePort); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source port ID")) + return sdkerrors.Wrap(err, "invalid source port ID") } if err := host.DefaultChannelIdentifierValidator(msg.SourceChannel); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source channel ID")) + return sdkerrors.Wrap(err, "invalid source channel ID") } if !msg.Amount.IsAllPositive() { - return sdk.ErrInsufficientCoins("transfer amount must be positive") + return sdkerrors.ErrInsufficientFunds } if !msg.Amount.IsValid() { - return sdk.ErrInvalidCoins("transfer amount is invalid") + return sdkerrors.ErrInvalidCoins } if msg.Sender.Empty() { - return sdk.ErrInvalidAddress("missing sender address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") } if msg.Receiver.Empty() { - return sdk.ErrInvalidAddress("missing recipient address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing recipient address") } return nil } @@ -104,26 +103,22 @@ func (MsgRecvPacket) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgRecvPacket) ValidateBasic() sdk.Error { +func (msg MsgRecvPacket) ValidateBasic() error { if msg.Height == 0 { - return sdk.ConvertError(connectiontypes.ErrInvalidHeight(DefaultCodespace, "height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "height must be > 0") } - if msg.Proofs == nil || len(msg.Proofs) == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "missing proofs")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "missing proof") } - for _, proof := range msg.Proofs { - if proof.Proof == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + if err := proof.ValidateBasic(); err != nil { + return err } } - if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") } - - return sdk.ConvertError(msg.Packet.ValidateBasic()) + return msg.Packet.ValidateBasic() } // GetSignBytes implements sdk.Msg diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go index f7c79b9be07e..19aed7c60343 100644 --- a/x/ibc/20-transfer/types/packet.go +++ b/x/ibc/20-transfer/types/packet.go @@ -4,6 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // PacketData defines a struct for the packet payload @@ -38,18 +39,18 @@ func (pd PacketData) String() string { } // ValidateBasic performs a basic check of the packet fields -func (pd PacketData) ValidateBasic() sdk.Error { +func (pd PacketData) ValidateBasic() error { if !pd.Amount.IsAllPositive() { - return sdk.ErrInsufficientCoins("transfer amount must be positive") + return sdkerrors.ErrInsufficientFunds } if !pd.Amount.IsValid() { - return sdk.ErrInvalidCoins("transfer amount is invalid") + return sdkerrors.ErrInvalidCoins } if pd.Sender.Empty() { - return sdk.ErrInvalidAddress("missing sender address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") } if pd.Receiver.Empty() { - return sdk.ErrInvalidAddress("missing recipient address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing receiver address") } return nil } diff --git a/x/ibc/23-commitment/errors.go b/x/ibc/23-commitment/errors.go new file mode 100644 index 000000000000..89b2bf0b0ad7 --- /dev/null +++ b/x/ibc/23-commitment/errors.go @@ -0,0 +1,14 @@ +package commitment + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// SubModuleName is the error codespace +const SubModuleName string = "ibc/commitment" + +// IBC connection sentinel errors +var ( + ErrInvalidProof = sdkerrors.Register(SubModuleName, 1, "invalid proof") + ErrInvalidPrefix = sdkerrors.Register(SubModuleName, 2, "invalid prefix") +) diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/merkle.go index 33d84408f997..39a355fc9ce8 100644 --- a/x/ibc/23-commitment/merkle.go +++ b/x/ibc/23-commitment/merkle.go @@ -151,3 +151,11 @@ func (proof Proof) VerifyNonMembership(root RootI, path PathI) bool { err := runtime.VerifyAbsence(proof.Proof, root.GetHash(), path.String()) return err == nil } + +// ValidateBasic checks if the proof is empty. +func (proof Proof) ValidateBasic() error { + if (proof == Proof{}) || proof.Proof == nil { + return ErrInvalidProof + } + return nil +} diff --git a/x/ibc/23-commitment/merkle_test.go b/x/ibc/23-commitment/merkle_test.go index 01dc9f2edcb4..7dcb5cbfd0fc 100644 --- a/x/ibc/23-commitment/merkle_test.go +++ b/x/ibc/23-commitment/merkle_test.go @@ -25,6 +25,8 @@ func (suite *MerkleTestSuite) TestVerifyMembership() { proof := commitment.Proof{ Proof: res.Proof, } + suite.Require().NoError(proof.ValidateBasic()) + suite.Require().Error(commitment.Proof{}.ValidateBasic()) cases := []struct { name string @@ -73,6 +75,7 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() { proof := commitment.Proof{ Proof: res.Proof, } + suite.Require().NoError(proof.ValidateBasic()) cases := []struct { name string diff --git a/x/ibc/23-commitment/types.go b/x/ibc/23-commitment/types.go index 1b70f4f04d9c..bd2968da88dc 100644 --- a/x/ibc/23-commitment/types.go +++ b/x/ibc/23-commitment/types.go @@ -38,6 +38,8 @@ type ProofI interface { GetCommitmentType() Type VerifyMembership(RootI, PathI, []byte) bool VerifyNonMembership(RootI, PathI) bool + + ValidateBasic() error } // Type defines the type of the commitment diff --git a/x/ibc/24-host/errors.go b/x/ibc/24-host/errors.go index 0ff6ad59d896..26b7919e6cb5 100644 --- a/x/ibc/24-host/errors.go +++ b/x/ibc/24-host/errors.go @@ -1,47 +1,15 @@ package host import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // SubModuleName defines the ICS 24 host const SubModuleName = "host" -// Error codes specific to the ibc host submodule -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodeInvalidID sdk.CodeType = 231 - CodeInvalidPath sdk.CodeType = 232 - CodeInvalidPacket sdk.CodeType = 233 +// IBC client sentinel errors +var ( + ErrInvalidID = sdkerrors.Register(SubModuleName, 1, "invalid identifier") + ErrInvalidPath = sdkerrors.Register(SubModuleName, 2, "invalid path") + ErrInvalidPacket = sdkerrors.Register(SubModuleName, 3, "invalid packet") ) - -// ErrInvalidID returns a typed ABCI error for an invalid identifier -func ErrInvalidID(codespace sdk.CodespaceType, id string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidID), - fmt.Sprintf("invalid identifier '%s'", id), - ) -} - -// ErrInvalidPath returns a typed ABCI error for an invalid path -func ErrInvalidPath(codespace sdk.CodespaceType, path string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidPath), - fmt.Sprintf("invalid path '%s'", path), - ) -} - -// ErrInvalidPacket returns a typed ABCI error for an invalid identifier -func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidPacket), - fmt.Sprintf("invalid packet: '%s'", msg), - ) -} diff --git a/x/ibc/24-host/validate.go b/x/ibc/24-host/validate.go index f6b3d14751e7..c360abf8616f 100644 --- a/x/ibc/24-host/validate.go +++ b/x/ibc/24-host/validate.go @@ -25,15 +25,15 @@ type ValidateFn func(string) error func defaultIdentifierValidator(id string, min, max int) error { // valid id MUST NOT contain "/" separator if strings.Contains(id, "/") { - return sdkerrors.Wrap(ErrInvalidID(DefaultCodespace, id), "identifier cannot contain separator: /") + return sdkerrors.Wrapf(ErrInvalidID, "identifier %s cannot contain separator '/'", id) } // valid id must be between 10 and 20 characters if len(id) < min || len(id) > max { - return sdkerrors.Wrapf(ErrInvalidID(DefaultCodespace, id), "identifier has invalid length: %d, must be between %d-%d characters", len(id), min, max) + return sdkerrors.Wrapf(ErrInvalidID, "identifier %s has invalid length: %d, must be between %d-%d characters", id, len(id), min, max) } // valid id must contain only lower alphabetic characters if !isAlphaLower(id) { - return sdkerrors.Wrap(ErrInvalidID(DefaultCodespace, id), "identifier must contain only lowercase alphabetic characters") + return sdkerrors.Wrapf(ErrInvalidID, "identifier %s must contain only lowercase alphabetic characters", id) } return nil } @@ -76,7 +76,7 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { // Each path element must either be valid identifier or alphanumeric err := idValidator(p) if err != nil && !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "path contains invalid identifier or non-alphanumeric path element: %s", p) + return sdkerrors.Wrapf(ErrInvalidPath, "path %s contains invalid identifier or non-alphanumeric path element: %s", path, p) } } return nil @@ -89,13 +89,13 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { func DefaultPathValidator(path string) error { pathArr := strings.Split(path, "/") if pathArr[0] == path { - return sdkerrors.Wrap(ErrInvalidPath(DefaultCodespace, path), "path doesn't contain any separator '/'") + return sdkerrors.Wrapf(ErrInvalidPath, "path %s doesn't contain any separator '/'", path) } for _, p := range pathArr { // Each path element must be alphanumeric and non-blank if strings.TrimSpace(p) == "" || !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "invalid path element containing non-alphanumeric characters: '%s'", p) + return sdkerrors.Wrapf(ErrInvalidPath, "path %s contains an invalid non-alphanumeric character: '%s'", path, p) } } return nil diff --git a/x/ibc/alias.go b/x/ibc/alias.go index abb2aae3c59a..7c1ad02349e2 100644 --- a/x/ibc/alias.go +++ b/x/ibc/alias.go @@ -12,11 +12,10 @@ import ( ) const ( - ModuleName = types.ModuleName - StoreKey = types.StoreKey - QuerierRoute = types.QuerierRoute - RouterKey = types.RouterKey - DefaultCodespace = types.DefaultCodespace + ModuleName = types.ModuleName + StoreKey = types.StoreKey + QuerierRoute = types.QuerierRoute + RouterKey = types.RouterKey ) var ( diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index 4818d68008d6..cb095b788a52 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -4,6 +4,7 @@ import ( "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" @@ -22,7 +23,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - ibcTxCmd.AddCommand(client.PostCommands( + ibcTxCmd.AddCommand(flags.PostCommands( ibcclient.GetTxCmd(cdc, storeKey), connection.GetTxCmd(cdc, storeKey), channel.GetTxCmd(cdc, storeKey), @@ -42,7 +43,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - ibcQueryCmd.AddCommand(client.GetCommands( + ibcQueryCmd.AddCommand(flags.GetCommands( ibcclient.GetQueryCmd(cdc, queryRoute), connection.GetQueryCmd(cdc, queryRoute), channel.GetQueryCmd(cdc, queryRoute), diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 1a1e2d0189be..d7d7262a165e 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -1,9 +1,8 @@ package ibc import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -12,7 +11,7 @@ import ( // NewHandler defines the IBC handler func NewHandler(k Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -63,8 +62,7 @@ func NewHandler(k Keeper) sdk.Handler { return transfer.HandleMsgRecvPacket(ctx, k.TransferKeeper, msg) default: - errMsg := fmt.Sprintf("unrecognized IBC message type: %T", msg) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized IBC message type: %T", msg) } } } diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 2c28b5c9dd51..694dae13b9ec 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -22,18 +22,18 @@ type Keeper struct { // NewKeeper creates a new ibc Keeper func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + cdc *codec.Codec, key sdk.StoreKey, bk transfer.BankKeeper, sk transfer.SupplyKeeper, ) Keeper { - clientKeeper := client.NewKeeper(cdc, key, codespace) - connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) - portKeeper := port.NewKeeper(cdc, key, codespace) - channelKeeper := channel.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, portKeeper) + clientKeeper := client.NewKeeper(cdc, key) + connectionKeeper := connection.NewKeeper(cdc, key, clientKeeper) + portKeeper := port.NewKeeper(cdc, key) + channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper) // TODO: move out of IBC keeper. Blocked on ADR15 capKey := portKeeper.BindPort(bank.ModuleName) transferKeeper := transfer.NewKeeper( - cdc, key, codespace, capKey, + cdc, key, capKey, clientKeeper, connectionKeeper, channelKeeper, bk, sk, ) diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index 02b468cdb031..68447885bbd1 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -12,7 +12,7 @@ import ( // NewQuerier creates a querier for the IBC module func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { var ( res []byte err error @@ -56,6 +56,6 @@ func NewQuerier(k Keeper) sdk.Querier { err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC query endpoint") } - return res, sdk.ConvertError(err) + return res, err } } diff --git a/x/ibc/types/errors.go b/x/ibc/types/errors.go index 086851321b6a..5246b3c5a206 100644 --- a/x/ibc/types/errors.go +++ b/x/ibc/types/errors.go @@ -1,33 +1,11 @@ package types import ( - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// common IBC error codes -const ( - // DefaultCodespace of the IBC module - DefaultCodespace sdk.CodespaceType = ModuleName - - CodeInvalidProof sdk.CodeType = 234 - CodeInvalidVersion sdk.CodeType = 235 +// ibc module common sentinel errors +var ( + ErrInvalidHeight = sdkerrors.Register(ModuleName, 1, "invalid height") + ErrInvalidVersion = sdkerrors.Register(ModuleName, 2, "invalid version") ) - -// ErrInvalidProof implements sdk.Error -func ErrInvalidProof(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidProof), - msg, - ) -} - -// ErrInvalidVersion implements sdk.Error -func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidVersion), - msg, - ) -} diff --git a/x/mint/alias.go b/x/mint/alias.go index 9572d077b458..c6d2330f9a8b 100644 --- a/x/mint/alias.go +++ b/x/mint/alias.go @@ -1,10 +1,7 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/mint/internal/keeper -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/mint/internal/types package mint +// nolint + import ( "github.com/cosmos/cosmos-sdk/x/mint/internal/keeper" "github.com/cosmos/cosmos-sdk/x/mint/internal/types" diff --git a/x/mint/client/cli/query.go b/x/mint/client/cli/query.go index 3350706362f3..ec37cde40cf6 100644 --- a/x/mint/client/cli/query.go +++ b/x/mint/client/cli/query.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/mint/internal/types" @@ -23,7 +24,7 @@ func GetQueryCmd(cdc *codec.Codec) *cobra.Command { } mintingQueryCmd.AddCommand( - client.GetCommands( + flags.GetCommands( GetCmdQueryParams(cdc), GetCmdQueryInflation(cdc), GetCmdQueryAnnualProvisions(cdc), diff --git a/x/mint/internal/keeper/keeper.go b/x/mint/internal/keeper/keeper.go index ff4bd029dfda..3be3146fdf68 100644 --- a/x/mint/internal/keeper/keeper.go +++ b/x/mint/internal/keeper/keeper.go @@ -24,7 +24,8 @@ type Keeper struct { // NewKeeper creates a new mint Keeper instance func NewKeeper( cdc *codec.Codec, key sdk.StoreKey, paramSpace params.Subspace, - sk types.StakingKeeper, supplyKeeper types.SupplyKeeper, feeCollectorName string) Keeper { + sk types.StakingKeeper, supplyKeeper types.SupplyKeeper, feeCollectorName string, +) Keeper { // ensure mint module account is set if addr := supplyKeeper.GetModuleAddress(types.ModuleName); addr == nil { @@ -96,16 +97,17 @@ func (k Keeper) BondedRatio(ctx sdk.Context) sdk.Dec { // MintCoins implements an alias call to the underlying supply keeper's // MintCoins to be used in BeginBlocker. -func (k Keeper) MintCoins(ctx sdk.Context, newCoins sdk.Coins) sdk.Error { +func (k Keeper) MintCoins(ctx sdk.Context, newCoins sdk.Coins) error { if newCoins.Empty() { // skip as no coins need to be minted return nil } + return k.supplyKeeper.MintCoins(ctx, types.ModuleName, newCoins) } // AddCollectedFees implements an alias call to the underlying supply keeper's // AddCollectedFees to be used in BeginBlocker. -func (k Keeper) AddCollectedFees(ctx sdk.Context, fees sdk.Coins) sdk.Error { +func (k Keeper) AddCollectedFees(ctx sdk.Context, fees sdk.Coins) error { return k.supplyKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, k.feeCollectorName, fees) } diff --git a/x/mint/internal/keeper/querier.go b/x/mint/internal/keeper/querier.go index fe3943f0896a..258d1b111ed2 100644 --- a/x/mint/internal/keeper/querier.go +++ b/x/mint/internal/keeper/querier.go @@ -1,18 +1,17 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/mint/internal/types" ) // NewQuerier returns a minting Querier handler. func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, _ abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, _ abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryParameters: return queryParams(ctx, k) @@ -24,39 +23,39 @@ func NewQuerier(k Keeper) sdk.Querier { return queryAnnualProvisions(ctx, k) default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown minting query endpoint: %s", path[0])) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) } } } -func queryParams(ctx sdk.Context, k Keeper) ([]byte, sdk.Error) { +func queryParams(ctx sdk.Context, k Keeper) ([]byte, error) { params := k.GetParams(ctx) res, err := codec.MarshalJSONIndent(k.cdc, params) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to marshal JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryInflation(ctx sdk.Context, k Keeper) ([]byte, sdk.Error) { +func queryInflation(ctx sdk.Context, k Keeper) ([]byte, error) { minter := k.GetMinter(ctx) res, err := codec.MarshalJSONIndent(k.cdc, minter.Inflation) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to marshal JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryAnnualProvisions(ctx sdk.Context, k Keeper) ([]byte, sdk.Error) { +func queryAnnualProvisions(ctx sdk.Context, k Keeper) ([]byte, error) { minter := k.GetMinter(ctx) res, err := codec.MarshalJSONIndent(k.cdc, minter.AnnualProvisions) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to marshal JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil diff --git a/x/mint/internal/types/expected_keepers.go b/x/mint/internal/types/expected_keepers.go index 564a0136b5c7..ea20619164d3 100644 --- a/x/mint/internal/types/expected_keepers.go +++ b/x/mint/internal/types/expected_keepers.go @@ -18,7 +18,7 @@ type SupplyKeeper interface { // TODO remove with genesis 2-phases refactor https://github.com/cosmos/cosmos-sdk/issues/2862 SetModuleAccount(sdk.Context, exported.ModuleAccountI) - SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error - SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) sdk.Error - MintCoins(ctx sdk.Context, name string, amt sdk.Coins) sdk.Error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error + MintCoins(ctx sdk.Context, name string, amt sdk.Coins) error } diff --git a/x/mock/app.go b/x/mock/app.go index 1e59e050507b..d0cee9f592af 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -64,7 +64,7 @@ func NewApp() *App { } // define keepers - app.ParamsKeeper = params.NewKeeper(app.Cdc, app.KeyParams, app.TKeyParams, params.DefaultCodespace) + app.ParamsKeeper = params.NewKeeper(app.Cdc, app.KeyParams, app.TKeyParams) app.AccountKeeper = auth.NewAccountKeeper( app.Cdc, diff --git a/x/mock/app_test.go b/x/mock/app_test.go index db5e29522539..95bed4fda085 100644 --- a/x/mock/app_test.go +++ b/x/mock/app_test.go @@ -7,6 +7,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/supply/exported" ) @@ -32,18 +33,20 @@ func (tx testMsg) GetMemo() string { return "" } func (tx testMsg) GetSignBytes() []byte { return nil } func (tx testMsg) GetSigners() []sdk.AccAddress { return tx.signers } func (tx testMsg) GetSignatures() []auth.StdSignature { return nil } -func (tx testMsg) ValidateBasic() sdk.Error { +func (tx testMsg) ValidateBasic() error { if tx.positiveNum >= 0 { return nil } - return sdk.ErrTxDecode("positiveNum should be a non-negative integer.") + return sdkerrors.Wrap(sdkerrors.ErrTxDecode, "positiveNum should be a non-negative integer") } // getMockApp returns an initialized mock application. func getMockApp(t *testing.T) *App { mApp := NewApp() - mApp.Router().AddRoute(msgRoute, func(ctx sdk.Context, msg sdk.Msg) (res sdk.Result) { return }) + mApp.Router().AddRoute(msgRoute, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + return &sdk.Result{}, nil + }) require.NoError(t, mApp.CompleteSetup()) return mApp @@ -71,15 +74,16 @@ func TestCheckAndDeliverGenTx(t *testing.T) { // Signing a tx with the wrong privKey should result in an auth error header = abci.Header{Height: mApp.LastBlockHeight() + 1} - res := SignCheckDeliver( + _, _, err := SignCheckDeliver( t, mApp.Cdc, mApp.BaseApp, header, []sdk.Msg{msg}, []uint64{accs[1].GetAccountNumber()}, []uint64{accs[1].GetSequence() + 1}, true, false, privKeys[1], ) // Will fail on SetPubKey decorator - require.Equal(t, sdk.CodeInvalidPubKey, res.Code, res.Log) - require.Equal(t, sdk.CodespaceRoot, res.Codespace) + space, code, log := sdkerrors.ABCIInfo(err, false) + require.Equal(t, sdkerrors.ErrInvalidPubKey.ABCICode(), code, log) + require.Equal(t, sdkerrors.ErrInvalidPubKey.Codespace(), space) // Resigning the tx with the correct privKey should result in an OK result header = abci.Header{Height: mApp.LastBlockHeight() + 1} diff --git a/x/mock/test_utils.go b/x/mock/test_utils.go index 2b5978823363..11073e64f413 100644 --- a/x/mock/test_utils.go +++ b/x/mock/test_utils.go @@ -55,17 +55,19 @@ func CheckBalance(t *testing.T, app *App, addr sdk.AccAddress, exp sdk.Coins) { func CheckGenTx( t *testing.T, app *baseapp.BaseApp, msgs []sdk.Msg, accNums []uint64, seq []uint64, expPass bool, priv ...crypto.PrivKey, -) sdk.Result { +) (sdk.GasInfo, *sdk.Result, error) { tx := GenTx(msgs, accNums, seq, priv...) - res := app.Check(tx) + gInfo, res, err := app.Check(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.NoError(t, err) + require.NotNil(t, res) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.Error(t, err) + require.Nil(t, res) } - return res + return gInfo, res, err } // SignCheckDeliver checks a generated signed transaction and simulates a @@ -75,7 +77,7 @@ func CheckGenTx( func SignCheckDeliver( t *testing.T, cdc *codec.Codec, app *baseapp.BaseApp, header abci.Header, msgs []sdk.Msg, accNums, seq []uint64, expSimPass, expPass bool, priv ...crypto.PrivKey, -) sdk.Result { +) (sdk.GasInfo, *sdk.Result, error) { tx := GenTx(msgs, accNums, seq, priv...) @@ -83,26 +85,31 @@ func SignCheckDeliver( require.Nil(t, err) // Must simulate now as CheckTx doesn't run Msgs anymore - res := app.Simulate(txBytes, tx) + _, res, err := app.Simulate(txBytes, tx) if expSimPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.NoError(t, err) + require.NotNil(t, res) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.Error(t, err) + require.Nil(t, res) } // Simulate a sending a transaction and committing a block app.BeginBlock(abci.RequestBeginBlock{Header: header}) - res = app.Deliver(tx) + + gInfo, res, err := app.Deliver(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.NoError(t, err) + require.NotNil(t, res) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.Error(t, err) + require.Nil(t, res) } app.EndBlock(abci.RequestEndBlock{}) app.Commit() - return res + return gInfo, res, err } diff --git a/x/mock/types.go b/x/mock/types.go index 14ec10772006..56912780dac1 100644 --- a/x/mock/types.go +++ b/x/mock/types.go @@ -4,7 +4,7 @@ import ( "github.com/tendermint/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" - + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/supply" "github.com/cosmos/cosmos-sdk/x/supply/exported" @@ -22,24 +22,23 @@ func NewDummySupplyKeeper(ak auth.AccountKeeper) DummySupplyKeeper { } // SendCoinsFromAccountToModule for the dummy supply keeper -func (sk DummySupplyKeeper) SendCoinsFromAccountToModule(ctx sdk.Context, fromAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error { - +func (sk DummySupplyKeeper) SendCoinsFromAccountToModule(ctx sdk.Context, fromAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error { fromAcc := sk.ak.GetAccount(ctx, fromAddr) moduleAcc := sk.GetModuleAccount(ctx, recipientModule) newFromCoins, hasNeg := fromAcc.GetCoins().SafeSub(amt) if hasNeg { - return sdk.ErrInsufficientCoins(fromAcc.GetCoins().String()) + return sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, fromAcc.GetCoins().String()) } newToCoins := moduleAcc.GetCoins().Add(amt) if err := fromAcc.SetCoins(newFromCoins); err != nil { - return sdk.ErrInternal(err.Error()) + return err } if err := moduleAcc.SetCoins(newToCoins); err != nil { - return sdk.ErrInternal(err.Error()) + return err } sk.ak.SetAccount(ctx, fromAcc) diff --git a/x/params/alias.go b/x/params/alias.go index ace601c219dc..1198e93cede3 100644 --- a/x/params/alias.go +++ b/x/params/alias.go @@ -1,10 +1,6 @@ package params // nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/params/subspace -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/params/types import ( "github.com/cosmos/cosmos-sdk/x/params/subspace" @@ -12,15 +8,11 @@ import ( ) const ( - StoreKey = subspace.StoreKey - TStoreKey = subspace.TStoreKey - DefaultCodespace = types.DefaultCodespace - CodeUnknownSubspace = types.CodeUnknownSubspace - CodeSettingParameter = types.CodeSettingParameter - CodeEmptyData = types.CodeEmptyData - ModuleName = types.ModuleName - RouterKey = types.RouterKey - ProposalTypeChange = types.ProposalTypeChange + StoreKey = subspace.StoreKey + TStoreKey = subspace.TStoreKey + ModuleName = types.ModuleName + RouterKey = types.RouterKey + ProposalTypeChange = types.ProposalTypeChange ) var ( diff --git a/x/params/commmon_test.go b/x/params/commmon_test.go index 5ca01ad98d40..ecebf8eb2e60 100644 --- a/x/params/commmon_test.go +++ b/x/params/commmon_test.go @@ -43,7 +43,7 @@ func testComponents() (*codec.Codec, sdk.Context, sdk.StoreKey, sdk.StoreKey, Ke mkey := sdk.NewKVStoreKey("test") tkey := sdk.NewTransientStoreKey("transient_test") ctx := defaultContext(mkey, tkey) - keeper := NewKeeper(cdc, mkey, tkey, DefaultCodespace) + keeper := NewKeeper(cdc, mkey, tkey) return cdc, ctx, mkey, tkey, keeper } diff --git a/x/params/keeper.go b/x/params/keeper.go index 9e91259df656..c3532f32834f 100644 --- a/x/params/keeper.go +++ b/x/params/keeper.go @@ -13,21 +13,19 @@ import ( // Keeper of the global paramstore type Keeper struct { - cdc *codec.Codec - key sdk.StoreKey - tkey sdk.StoreKey - codespace sdk.CodespaceType - spaces map[string]*Subspace + cdc *codec.Codec + key sdk.StoreKey + tkey sdk.StoreKey + spaces map[string]*Subspace } // NewKeeper constructs a params keeper -func NewKeeper(cdc *codec.Codec, key, tkey sdk.StoreKey, codespace sdk.CodespaceType) Keeper { +func NewKeeper(cdc *codec.Codec, key, tkey sdk.StoreKey) Keeper { return Keeper{ - cdc: cdc, - key: key, - tkey: tkey, - codespace: codespace, - spaces: make(map[string]*Subspace), + cdc: cdc, + key: key, + tkey: tkey, + spaces: make(map[string]*Subspace), } } diff --git a/x/params/proposal_handler.go b/x/params/proposal_handler.go index e2e976454275..339cfd7410ce 100644 --- a/x/params/proposal_handler.go +++ b/x/params/proposal_handler.go @@ -4,28 +4,28 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) // NewParamChangeProposalHandler creates a new governance Handler for a ParamChangeProposal func NewParamChangeProposalHandler(k Keeper) govtypes.Handler { - return func(ctx sdk.Context, content govtypes.Content) sdk.Error { + return func(ctx sdk.Context, content govtypes.Content) error { switch c := content.(type) { case ParameterChangeProposal: return handleParameterChangeProposal(ctx, k, c) default: - errMsg := fmt.Sprintf("unrecognized param proposal content type: %T", c) - return sdk.ErrUnknownRequest(errMsg) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized param proposal content type: %T", c) } } } -func handleParameterChangeProposal(ctx sdk.Context, k Keeper, p ParameterChangeProposal) sdk.Error { +func handleParameterChangeProposal(ctx sdk.Context, k Keeper, p ParameterChangeProposal) error { for _, c := range p.Changes { ss, ok := k.GetSubspace(c.Subspace) if !ok { - return ErrUnknownSubspace(k.codespace, c.Subspace) + return sdkerrors.Wrap(ErrUnknownSubspace, c.Subspace) } k.Logger(ctx).Info( @@ -33,7 +33,7 @@ func handleParameterChangeProposal(ctx sdk.Context, k Keeper, p ParameterChangeP ) if err := ss.Update(ctx, []byte(c.Key), []byte(c.Value)); err != nil { - return ErrSettingParameter(k.codespace, c.Key, c.Value, err.Error()) + return sdkerrors.Wrapf(ErrSettingParameter, "key: %s, value: %s, err: %s", c.Key, c.Value, err.Error()) } } diff --git a/x/params/proposal_handler_test.go b/x/params/proposal_handler_test.go index 841f832160c5..9d83975c1020 100644 --- a/x/params/proposal_handler_test.go +++ b/x/params/proposal_handler_test.go @@ -74,7 +74,7 @@ func newTestInput(t *testing.T) testInput { err := cms.LoadLatestVersion() require.Nil(t, err) - keeper := params.NewKeeper(cdc, keyParams, tKeyParams, params.DefaultCodespace) + keeper := params.NewKeeper(cdc, keyParams, tKeyParams) ctx := sdk.NewContext(cms, abci.Header{}, false, log.NewNopLogger()) return testInput{ctx, cdc, keeper} diff --git a/x/params/types/errors.go b/x/params/types/errors.go index 12726b0322f5..4b218d9444ee 100644 --- a/x/params/types/errors.go +++ b/x/params/types/errors.go @@ -1,46 +1,15 @@ package types import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// Param module codespace constants -const ( - DefaultCodespace sdk.CodespaceType = "params" - - CodeUnknownSubspace sdk.CodeType = 1 - CodeSettingParameter sdk.CodeType = 2 - CodeEmptyData sdk.CodeType = 3 +// x/params module sentinel errors +var ( + ErrUnknownSubspace = sdkerrors.Register(ModuleName, 1, "unknown subspace") + ErrSettingParameter = sdkerrors.Register(ModuleName, 2, "failed to set parameter") + ErrEmptyChanges = sdkerrors.Register(ModuleName, 3, "submitted parameter changes are empty") + ErrEmptySubspace = sdkerrors.Register(ModuleName, 4, "parameter subspace is empty") + ErrEmptyKey = sdkerrors.Register(ModuleName, 5, "parameter key is empty") + ErrEmptyValue = sdkerrors.Register(ModuleName, 6, "parameter value is empty") ) - -// ErrUnknownSubspace returns an unknown subspace error. -func ErrUnknownSubspace(codespace sdk.CodespaceType, space string) sdk.Error { - return sdk.NewError(codespace, CodeUnknownSubspace, fmt.Sprintf("unknown subspace %s", space)) -} - -// ErrSettingParameter returns an error for failing to set a parameter. -func ErrSettingParameter(codespace sdk.CodespaceType, key, value, msg string) sdk.Error { - return sdk.NewError(codespace, CodeSettingParameter, fmt.Sprintf("error setting parameter %s on %s: %s", value, key, msg)) -} - -// ErrEmptyChanges returns an error for empty parameter changes. -func ErrEmptyChanges(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeEmptyData, "submitted parameter changes are empty") -} - -// ErrEmptySubspace returns an error for an empty subspace. -func ErrEmptySubspace(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeEmptyData, "parameter subspace is empty") -} - -// ErrEmptyKey returns an error for when an empty key is given. -func ErrEmptyKey(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeEmptyData, "parameter key is empty") -} - -// ErrEmptyValue returns an error for when an empty key is given. -func ErrEmptyValue(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeEmptyData, "parameter value is empty") -} diff --git a/x/params/types/proposal.go b/x/params/types/proposal.go index a4bcefab2df6..78f200d143e9 100644 --- a/x/params/types/proposal.go +++ b/x/params/types/proposal.go @@ -4,7 +4,6 @@ import ( "fmt" "strings" - sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -46,8 +45,8 @@ func (pcp ParameterChangeProposal) ProposalRoute() string { return RouterKey } func (pcp ParameterChangeProposal) ProposalType() string { return ProposalTypeChange } // ValidateBasic validates the parameter change proposal -func (pcp ParameterChangeProposal) ValidateBasic() sdk.Error { - err := govtypes.ValidateAbstract(DefaultCodespace, pcp) +func (pcp ParameterChangeProposal) ValidateBasic() error { + err := govtypes.ValidateAbstract(pcp) if err != nil { return err } @@ -98,20 +97,20 @@ func (pc ParamChange) String() string { // ValidateChanges performs basic validation checks over a set of ParamChange. It // returns an error if any ParamChange is invalid. -func ValidateChanges(changes []ParamChange) sdk.Error { +func ValidateChanges(changes []ParamChange) error { if len(changes) == 0 { - return ErrEmptyChanges(DefaultCodespace) + return ErrEmptyChanges } for _, pc := range changes { if len(pc.Subspace) == 0 { - return ErrEmptySubspace(DefaultCodespace) + return ErrEmptySubspace } if len(pc.Key) == 0 { - return ErrEmptyKey(DefaultCodespace) + return ErrEmptyKey } if len(pc.Value) == 0 { - return ErrEmptyValue(DefaultCodespace) + return ErrEmptyValue } } diff --git a/x/slashing/abci_test.go b/x/slashing/abci_test.go index 84d36c6ee083..bcd1ee7ce8a2 100644 --- a/x/slashing/abci_test.go +++ b/x/slashing/abci_test.go @@ -20,8 +20,10 @@ func TestBeginBlocker(t *testing.T) { addr, pk := slashingkeeper.Addrs[2], slashingkeeper.Pks[2] // bond the validator - got := staking.NewHandler(sk)(ctx, slashingkeeper.NewTestMsgCreateValidator(addr, pk, amt)) - require.True(t, got.IsOK()) + res, err := staking.NewHandler(sk)(ctx, slashingkeeper.NewTestMsgCreateValidator(addr, pk, amt)) + require.NoError(t, err) + require.NotNil(t, res) + staking.EndBlocker(ctx, sk) require.Equal( t, ck.GetCoins(ctx, sdk.AccAddress(addr)), diff --git a/x/slashing/alias.go b/x/slashing/alias.go index 677228182c0d..38d556a6e492 100644 --- a/x/slashing/alias.go +++ b/x/slashing/alias.go @@ -1,23 +1,13 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/slashing/internal/keeper -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/slashing/internal/types package slashing +// nolint + import ( "github.com/cosmos/cosmos-sdk/x/slashing/internal/keeper" "github.com/cosmos/cosmos-sdk/x/slashing/internal/types" ) const ( - DefaultCodespace = types.DefaultCodespace - CodeInvalidValidator = types.CodeInvalidValidator - CodeValidatorJailed = types.CodeValidatorJailed - CodeValidatorNotJailed = types.CodeValidatorNotJailed - CodeMissingSelfDelegation = types.CodeMissingSelfDelegation - CodeSelfDelegationTooLow = types.CodeSelfDelegationTooLow - CodeMissingSigningInfo = types.CodeMissingSigningInfo ModuleName = types.ModuleName StoreKey = types.StoreKey RouterKey = types.RouterKey @@ -89,7 +79,6 @@ var ( type ( Hooks = keeper.Hooks Keeper = keeper.Keeper - CodeType = types.CodeType GenesisState = types.GenesisState MissedBlock = types.MissedBlock MsgUnjail = types.MsgUnjail diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index 8704333b75b8..23dd43e590bf 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -3,6 +3,7 @@ package slashing import ( + "errors" "testing" "github.com/stretchr/testify/require" @@ -47,15 +48,15 @@ func getMockApp(t *testing.T) (*mock.App, staking.Keeper, Keeper) { blacklistedAddrs[notBondedPool.GetAddress().String()] = true blacklistedAddrs[bondPool.GetAddress().String()] = true - bankKeeper := bank.NewBaseKeeper(mapp.AccountKeeper, mapp.ParamsKeeper.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs) + bankKeeper := bank.NewBaseKeeper(mapp.AccountKeeper, mapp.ParamsKeeper.Subspace(bank.DefaultParamspace), blacklistedAddrs) maccPerms := map[string][]string{ auth.FeeCollectorName: nil, staking.NotBondedPoolName: {supply.Burner, supply.Staking}, staking.BondedPoolName: {supply.Burner, supply.Staking}, } supplyKeeper := supply.NewKeeper(mapp.Cdc, keySupply, mapp.AccountKeeper, bankKeeper, maccPerms) - stakingKeeper := staking.NewKeeper(mapp.Cdc, keyStaking, supplyKeeper, mapp.ParamsKeeper.Subspace(staking.DefaultParamspace), staking.DefaultCodespace) - keeper := NewKeeper(mapp.Cdc, keySlashing, stakingKeeper, mapp.ParamsKeeper.Subspace(DefaultParamspace), DefaultCodespace) + stakingKeeper := staking.NewKeeper(mapp.Cdc, keyStaking, supplyKeeper, mapp.ParamsKeeper.Subspace(staking.DefaultParamspace)) + keeper := NewKeeper(mapp.Cdc, keySlashing, stakingKeeper, mapp.ParamsKeeper.Subspace(DefaultParamspace)) mapp.Router().AddRoute(staking.RouterKey, staking.NewHandler(stakingKeeper)) mapp.Router().AddRoute(RouterKey, NewHandler(keeper)) @@ -152,7 +153,8 @@ func TestSlashingMsgs(t *testing.T) { // unjail should fail with unknown validator header = abci.Header{Height: mapp.LastBlockHeight() + 1} - res := mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, header, []sdk.Msg{unjailMsg}, []uint64{0}, []uint64{1}, false, false, priv1) - require.EqualValues(t, CodeValidatorNotJailed, res.Code) - require.EqualValues(t, DefaultCodespace, res.Codespace) + _, res, err := mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, header, []sdk.Msg{unjailMsg}, []uint64{0}, []uint64{1}, false, false, priv1) + require.Error(t, err) + require.Nil(t, res) + require.True(t, errors.Is(ErrValidatorNotJailed, err)) } diff --git a/x/slashing/client/cli/query.go b/x/slashing/client/cli/query.go index 836d2bcb1f3d..a5b0cd1be524 100644 --- a/x/slashing/client/cli/query.go +++ b/x/slashing/client/cli/query.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -26,7 +27,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { } slashingQueryCmd.AddCommand( - client.GetCommands( + flags.GetCommands( GetCmdQuerySigningInfo(queryRoute, cdc), GetCmdQueryParams(cdc), )..., diff --git a/x/slashing/client/cli/tx.go b/x/slashing/client/cli/tx.go index e6bb0b44e9b8..5aa262568d54 100644 --- a/x/slashing/client/cli/tx.go +++ b/x/slashing/client/cli/tx.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" @@ -24,7 +25,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - slashingTxCmd.AddCommand(client.PostCommands( + slashingTxCmd.AddCommand(flags.PostCommands( GetCmdUnjail(cdc), )...) diff --git a/x/slashing/handler.go b/x/slashing/handler.go index 3c338d0bc7b2..fe4ef7cb7c2e 100644 --- a/x/slashing/handler.go +++ b/x/slashing/handler.go @@ -1,15 +1,14 @@ package slashing import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/slashing/internal/types" ) // NewHandler creates an sdk.Handler for all the slashing type messages func NewHandler(k Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -17,19 +16,17 @@ func NewHandler(k Keeper) sdk.Handler { return handleMsgUnjail(ctx, msg, k) default: - errMsg := fmt.Sprintf("unrecognized slashing message type: %T", msg) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg) } } } // Validators must submit a transaction to unjail itself after // having been jailed (and thus unbonded) for downtime -func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result { - +func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) (*sdk.Result, error) { err := k.Unjail(ctx, msg.ValidatorAddr) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -40,5 +37,5 @@ func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result { ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } diff --git a/x/slashing/handler_test.go b/x/slashing/handler_test.go index e0d5228326da..a137ff8d0d08 100644 --- a/x/slashing/handler_test.go +++ b/x/slashing/handler_test.go @@ -1,6 +1,7 @@ package slashing import ( + "errors" "strings" "testing" "time" @@ -20,9 +21,12 @@ func TestCannotUnjailUnlessJailed(t *testing.T) { slh := NewHandler(keeper) amt := sdk.TokensFromConsensusPower(100) addr, val := slashingkeeper.Addrs[0], slashingkeeper.Pks[0] + msg := slashingkeeper.NewTestMsgCreateValidator(addr, val, amt) - got := staking.NewHandler(sk)(ctx, msg) - require.True(t, got.IsOK(), "%v", got) + res, err := staking.NewHandler(sk)(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) + staking.EndBlocker(ctx, sk) require.Equal( @@ -32,10 +36,10 @@ func TestCannotUnjailUnlessJailed(t *testing.T) { require.Equal(t, amt, sk.Validator(ctx, addr).GetBondedTokens()) // assert non-jailed validator can't be unjailed - got = slh(ctx, NewMsgUnjail(addr)) - require.False(t, got.IsOK(), "allowed unjail of non-jailed validator") - require.EqualValues(t, CodeValidatorNotJailed, got.Code) - require.EqualValues(t, DefaultCodespace, got.Codespace) + res, err = slh(ctx, NewMsgUnjail(addr)) + require.Error(t, err) + require.Nil(t, res) + require.True(t, errors.Is(ErrValidatorNotJailed, err)) } func TestCannotUnjailUnlessMeetMinSelfDelegation(t *testing.T) { @@ -46,8 +50,11 @@ func TestCannotUnjailUnlessMeetMinSelfDelegation(t *testing.T) { addr, val, amt := slashingkeeper.Addrs[0], slashingkeeper.Pks[0], sdk.TokensFromConsensusPower(amtInt) msg := slashingkeeper.NewTestMsgCreateValidator(addr, val, amt) msg.MinSelfDelegation = amt - got := staking.NewHandler(sk)(ctx, msg) - require.True(t, got.IsOK()) + + res, err := staking.NewHandler(sk)(ctx, msg) + require.NoError(t, err) + require.NotNil(t, res) + staking.EndBlocker(ctx, sk) require.Equal( @@ -57,15 +64,17 @@ func TestCannotUnjailUnlessMeetMinSelfDelegation(t *testing.T) { unbondAmt := sdk.NewCoin(sk.GetParams(ctx).BondDenom, sdk.OneInt()) undelegateMsg := staking.NewMsgUndelegate(sdk.AccAddress(addr), addr, unbondAmt) - got = staking.NewHandler(sk)(ctx, undelegateMsg) + res, err = staking.NewHandler(sk)(ctx, undelegateMsg) + require.NoError(t, err) + require.NotNil(t, res) require.True(t, sk.Validator(ctx, addr).IsJailed()) // assert non-jailed validator can't be unjailed - got = slh(ctx, NewMsgUnjail(addr)) - require.False(t, got.IsOK(), "allowed unjail of validator with less than MinSelfDelegation") - require.EqualValues(t, CodeValidatorNotJailed, got.Code) - require.EqualValues(t, DefaultCodespace, got.Codespace) + res, err = slh(ctx, NewMsgUnjail(addr)) + require.Error(t, err) + require.Nil(t, res) + require.True(t, errors.Is(ErrSelfDelegationTooLowToUnjail, err)) } func TestJailedValidatorDelegations(t *testing.T) { @@ -80,8 +89,9 @@ func TestJailedValidatorDelegations(t *testing.T) { valAddr, consAddr := slashingkeeper.Addrs[1], sdk.ConsAddress(slashingkeeper.Addrs[0]) msgCreateVal := slashingkeeper.NewTestMsgCreateValidator(valAddr, valPubKey, bondAmount) - got := staking.NewHandler(stakingKeeper)(ctx, msgCreateVal) - require.True(t, got.IsOK(), "expected create validator msg to be ok, got: %v", got) + res, err := staking.NewHandler(stakingKeeper)(ctx, msgCreateVal) + require.NoError(t, err) + require.NotNil(t, res) // end block staking.EndBlocker(ctx, stakingKeeper) @@ -93,17 +103,19 @@ func TestJailedValidatorDelegations(t *testing.T) { // delegate tokens to the validator delAddr := sdk.AccAddress(slashingkeeper.Addrs[2]) msgDelegate := slashingkeeper.NewTestMsgDelegate(delAddr, valAddr, bondAmount) - got = staking.NewHandler(stakingKeeper)(ctx, msgDelegate) - require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got) + res, err = staking.NewHandler(stakingKeeper)(ctx, msgDelegate) + require.NoError(t, err) + require.NotNil(t, res) unbondAmt := sdk.NewCoin(stakingKeeper.GetParams(ctx).BondDenom, bondAmount) // unbond validator total self-delegations (which should jail the validator) msgUndelegate := staking.NewMsgUndelegate(sdk.AccAddress(valAddr), valAddr, unbondAmt) - got = staking.NewHandler(stakingKeeper)(ctx, msgUndelegate) - require.True(t, got.IsOK(), "expected begin unbonding validator msg to be ok, got: %v", got) + res, err = staking.NewHandler(stakingKeeper)(ctx, msgUndelegate) + require.NoError(t, err) + require.NotNil(t, res) - err := stakingKeeper.CompleteUnbonding(ctx, sdk.AccAddress(valAddr), valAddr) + err = stakingKeeper.CompleteUnbonding(ctx, sdk.AccAddress(valAddr), valAddr) require.Nil(t, err, "expected complete unbonding validator to be ok, got: %v", err) // verify validator still exists and is jailed @@ -112,26 +124,30 @@ func TestJailedValidatorDelegations(t *testing.T) { require.True(t, validator.IsJailed()) // verify the validator cannot unjail itself - got = NewHandler(slashingKeeper)(ctx, NewMsgUnjail(valAddr)) - require.False(t, got.IsOK(), "expected jailed validator to not be able to unjail, got: %v", got) + res, err = NewHandler(slashingKeeper)(ctx, NewMsgUnjail(valAddr)) + require.Error(t, err) + require.Nil(t, res) // self-delegate to validator msgSelfDelegate := slashingkeeper.NewTestMsgDelegate(sdk.AccAddress(valAddr), valAddr, bondAmount) - got = staking.NewHandler(stakingKeeper)(ctx, msgSelfDelegate) - require.True(t, got.IsOK(), "expected delegation to not be ok, got %v", got) + res, err = staking.NewHandler(stakingKeeper)(ctx, msgSelfDelegate) + require.NoError(t, err) + require.NotNil(t, res) // verify the validator can now unjail itself - got = NewHandler(slashingKeeper)(ctx, NewMsgUnjail(valAddr)) - require.True(t, got.IsOK(), "expected jailed validator to be able to unjail, got: %v", got) + res, err = NewHandler(slashingKeeper)(ctx, NewMsgUnjail(valAddr)) + require.NoError(t, err) + require.NotNil(t, res) } func TestInvalidMsg(t *testing.T) { k := Keeper{} h := NewHandler(k) - res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) - require.False(t, res.IsOK()) - require.True(t, strings.Contains(res.Log, "unrecognized slashing message type")) + res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) + require.Error(t, err) + require.Nil(t, res) + require.True(t, strings.Contains(err.Error(), "unrecognized slashing message type")) } // Test a validator through uptime, downtime, revocation, @@ -145,8 +161,11 @@ func TestHandleAbsentValidator(t *testing.T) { addr, val := slashingkeeper.Addrs[0], slashingkeeper.Pks[0] sh := staking.NewHandler(sk) slh := NewHandler(keeper) - got := sh(ctx, slashingkeeper.NewTestMsgCreateValidator(addr, val, amt)) - require.True(t, got.IsOK()) + + res, err := sh(ctx, slashingkeeper.NewTestMsgCreateValidator(addr, val, amt)) + require.NoError(t, err) + require.NotNil(t, res) + staking.EndBlocker(ctx, sk) require.Equal( @@ -228,13 +247,15 @@ func TestHandleAbsentValidator(t *testing.T) { require.Equal(t, amt.Int64()-slashAmt, validator.GetTokens().Int64()) // unrevocation should fail prior to jail expiration - got = slh(ctx, types.NewMsgUnjail(addr)) - require.False(t, got.IsOK()) + res, err = slh(ctx, types.NewMsgUnjail(addr)) + require.Error(t, err) + require.Nil(t, res) // unrevocation should succeed after jail expiration ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.DowntimeJailDuration(ctx))}) - got = slh(ctx, types.NewMsgUnjail(addr)) - require.True(t, got.IsOK()) + res, err = slh(ctx, types.NewMsgUnjail(addr)) + require.NoError(t, err) + require.NotNil(t, res) // end block staking.EndBlocker(ctx, sk) diff --git a/x/slashing/internal/keeper/keeper.go b/x/slashing/internal/keeper/keeper.go index b7a3706369f9..e725519314d1 100644 --- a/x/slashing/internal/keeper/keeper.go +++ b/x/slashing/internal/keeper/keeper.go @@ -17,19 +17,16 @@ type Keeper struct { cdc *codec.Codec sk types.StakingKeeper paramspace types.ParamSubspace - codespace sdk.CodespaceType } // NewKeeper creates a slashing keeper -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, sk types.StakingKeeper, paramspace types.ParamSubspace, codespace sdk.CodespaceType) Keeper { - keeper := Keeper{ +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, sk types.StakingKeeper, paramspace types.ParamSubspace) Keeper { + return Keeper{ storeKey: key, cdc: cdc, sk: sk, paramspace: paramspace.WithKeyTable(types.ParamKeyTable()), - codespace: codespace, } - return keeper } // Logger returns a module-specific logger. diff --git a/x/slashing/internal/keeper/keeper_test.go b/x/slashing/internal/keeper/keeper_test.go index 54b77848a043..52eb6b59b77a 100644 --- a/x/slashing/internal/keeper/keeper_test.go +++ b/x/slashing/internal/keeper/keeper_test.go @@ -25,8 +25,10 @@ func TestHandleNewValidator(t *testing.T) { ctx = ctx.WithBlockHeight(keeper.SignedBlocksWindow(ctx) + 1) // Validator created - got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt)) - require.True(t, got.IsOK()) + res, err := sh(ctx, NewTestMsgCreateValidator(addr, val, amt)) + require.NoError(t, err) + require.NotNil(t, res) + staking.EndBlocker(ctx, sk) require.Equal( @@ -65,8 +67,10 @@ func TestHandleAlreadyJailed(t *testing.T) { amt := sdk.TokensFromConsensusPower(power) addr, val := Addrs[0], Pks[0] sh := staking.NewHandler(sk) - got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt)) - require.True(t, got.IsOK()) + res, err := sh(ctx, NewTestMsgCreateValidator(addr, val, amt)) + require.NoError(t, err) + require.NotNil(t, res) + staking.EndBlocker(ctx, sk) // 1000 first blocks OK @@ -119,8 +123,10 @@ func TestValidatorDippingInAndOut(t *testing.T) { addr, val := Addrs[0], Pks[0] consAddr := sdk.ConsAddress(addr) sh := staking.NewHandler(sk) - got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt)) - require.True(t, got.IsOK()) + res, err := sh(ctx, NewTestMsgCreateValidator(addr, val, amt)) + require.NoError(t, err) + require.NotNil(t, res) + staking.EndBlocker(ctx, sk) // 100 first blocks OK @@ -132,8 +138,10 @@ func TestValidatorDippingInAndOut(t *testing.T) { // kick first validator out of validator set newAmt := sdk.TokensFromConsensusPower(101) - got = sh(ctx, NewTestMsgCreateValidator(Addrs[1], Pks[1], newAmt)) - require.True(t, got.IsOK()) + res, err = sh(ctx, NewTestMsgCreateValidator(Addrs[1], Pks[1], newAmt)) + require.NoError(t, err) + require.NotNil(t, res) + validatorUpdates := staking.EndBlocker(ctx, sk) require.Equal(t, 2, len(validatorUpdates)) validator, _ := sk.GetValidator(ctx, addr) @@ -145,8 +153,10 @@ func TestValidatorDippingInAndOut(t *testing.T) { // validator added back in delTokens := sdk.TokensFromConsensusPower(50) - got = sh(ctx, NewTestMsgDelegate(sdk.AccAddress(Addrs[2]), Addrs[0], delTokens)) - require.True(t, got.IsOK()) + res, err = sh(ctx, NewTestMsgDelegate(sdk.AccAddress(Addrs[2]), Addrs[0], delTokens)) + require.NoError(t, err) + require.NotNil(t, res) + validatorUpdates = staking.EndBlocker(ctx, sk) require.Equal(t, 2, len(validatorUpdates)) validator, _ = sk.GetValidator(ctx, addr) diff --git a/x/slashing/internal/keeper/querier.go b/x/slashing/internal/keeper/querier.go index 4633d8ba50e9..11b365e1ee1b 100644 --- a/x/slashing/internal/keeper/querier.go +++ b/x/slashing/internal/keeper/querier.go @@ -1,70 +1,72 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/slashing/internal/types" ) // NewQuerier creates a new querier for slashing clients. func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryParameters: return queryParams(ctx, k) + case types.QuerySigningInfo: return querySigningInfo(ctx, req, k) + case types.QuerySigningInfos: return querySigningInfos(ctx, req, k) + default: - return nil, sdk.ErrUnknownRequest("unknown staking query endpoint") + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) } } } -func queryParams(ctx sdk.Context, k Keeper) ([]byte, sdk.Error) { +func queryParams(ctx sdk.Context, k Keeper) ([]byte, error) { params := k.GetParams(ctx) res, err := codec.MarshalJSONIndent(types.ModuleCdc, params) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to marshal JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func querySigningInfo(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func querySigningInfo(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QuerySigningInfoParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } signingInfo, found := k.GetValidatorSigningInfo(ctx, params.ConsAddress) if !found { - return nil, types.ErrNoSigningInfoFound(types.DefaultCodespace, params.ConsAddress) + return nil, sdkerrors.Wrap(types.ErrNoSigningInfoFound, params.ConsAddress.String()) } res, err := codec.MarshalJSONIndent(types.ModuleCdc, signingInfo) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to JSON marshal result: %s", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func querySigningInfos(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func querySigningInfos(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QuerySigningInfosParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } var signingInfos []types.ValidatorSigningInfo @@ -83,7 +85,7 @@ func querySigningInfos(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte res, err := codec.MarshalJSONIndent(types.ModuleCdc, signingInfos) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to JSON marshal result: %s", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil diff --git a/x/slashing/internal/keeper/test_common.go b/x/slashing/internal/keeper/test_common.go index 721967ca88c4..eb8870c1d199 100644 --- a/x/slashing/internal/keeper/test_common.go +++ b/x/slashing/internal/keeper/test_common.go @@ -88,10 +88,10 @@ func CreateTestInput(t *testing.T, defaults types.Params) (sdk.Context, bank.Kee blacklistedAddrs[notBondedPool.GetAddress().String()] = true blacklistedAddrs[bondPool.GetAddress().String()] = true - paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams, params.DefaultCodespace) + paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams) accountKeeper := auth.NewAccountKeeper(cdc, keyAcc, paramsKeeper.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount) - bk := bank.NewBaseKeeper(accountKeeper, paramsKeeper.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs) + bk := bank.NewBaseKeeper(accountKeeper, paramsKeeper.Subspace(bank.DefaultParamspace), blacklistedAddrs) maccPerms := map[string][]string{ auth.FeeCollectorName: nil, staking.NotBondedPoolName: {supply.Burner, supply.Staking}, @@ -102,7 +102,7 @@ func CreateTestInput(t *testing.T, defaults types.Params) (sdk.Context, bank.Kee totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, InitTokens.MulRaw(int64(len(Addrs))))) supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) - sk := staking.NewKeeper(cdc, keyStaking, supplyKeeper, paramsKeeper.Subspace(staking.DefaultParamspace), staking.DefaultCodespace) + sk := staking.NewKeeper(cdc, keyStaking, supplyKeeper, paramsKeeper.Subspace(staking.DefaultParamspace)) genesis := staking.DefaultGenesisState() // set module accounts @@ -117,7 +117,7 @@ func CreateTestInput(t *testing.T, defaults types.Params) (sdk.Context, bank.Kee } require.Nil(t, err) paramstore := paramsKeeper.Subspace(types.DefaultParamspace) - keeper := NewKeeper(cdc, keySlashing, &sk, paramstore, types.DefaultCodespace) + keeper := NewKeeper(cdc, keySlashing, &sk, paramstore) keeper.SetParams(ctx, defaults) sk.SetHooks(keeper.Hooks()) diff --git a/x/slashing/internal/keeper/unjail.go b/x/slashing/internal/keeper/unjail.go index 3fdab405eb91..51fda4855382 100644 --- a/x/slashing/internal/keeper/unjail.go +++ b/x/slashing/internal/keeper/unjail.go @@ -7,42 +7,42 @@ import ( // Unjail calls the staking Unjail function to unjail a validator if the // jailed period has concluded -func (k Keeper) Unjail(ctx sdk.Context, validatorAddr sdk.ValAddress) sdk.Error { +func (k Keeper) Unjail(ctx sdk.Context, validatorAddr sdk.ValAddress) error { validator := k.sk.Validator(ctx, validatorAddr) if validator == nil { - return types.ErrNoValidatorForAddress(k.codespace) + return types.ErrNoValidatorForAddress } // cannot be unjailed if no self-delegation exists selfDel := k.sk.Delegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) if selfDel == nil { - return types.ErrMissingSelfDelegation(k.codespace) + return types.ErrMissingSelfDelegation } if validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()) { - return types.ErrSelfDelegationTooLowToUnjail(k.codespace) + return types.ErrSelfDelegationTooLowToUnjail } // cannot be unjailed if not jailed if !validator.IsJailed() { - return types.ErrValidatorNotJailed(k.codespace) + return types.ErrValidatorNotJailed } consAddr := sdk.ConsAddress(validator.GetConsPubKey().Address()) info, found := k.GetValidatorSigningInfo(ctx, consAddr) if !found { - return types.ErrNoValidatorForAddress(k.codespace) + return types.ErrNoValidatorForAddress } // cannot be unjailed if tombstoned if info.Tombstoned { - return types.ErrValidatorJailed(k.codespace) + return types.ErrValidatorJailed } // cannot be unjailed until out of jail if ctx.BlockHeader().Time.Before(info.JailedUntil) { - return types.ErrValidatorJailed(k.codespace) + return types.ErrValidatorJailed } k.sk.Unjail(ctx, consAddr) diff --git a/x/slashing/internal/types/errors.go b/x/slashing/internal/types/errors.go index b00e6e4f94ab..290ed36cad66 100644 --- a/x/slashing/internal/types/errors.go +++ b/x/slashing/internal/types/errors.go @@ -1,53 +1,16 @@ -//nolint package types import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// DONTCOVER - -// Local code type -type CodeType = sdk.CodeType - -const ( - // Default slashing codespace - DefaultCodespace sdk.CodespaceType = ModuleName - - CodeInvalidValidator CodeType = 101 - CodeValidatorJailed CodeType = 102 - CodeValidatorNotJailed CodeType = 103 - CodeMissingSelfDelegation CodeType = 104 - CodeSelfDelegationTooLow CodeType = 105 - CodeMissingSigningInfo CodeType = 106 +// x/slashing module sentinel errors +var ( + ErrNoValidatorForAddress = sdkerrors.Register(ModuleName, 1, "address is not associated with any known validator") + ErrBadValidatorAddr = sdkerrors.Register(ModuleName, 2, "validator does not exist for that address") + ErrValidatorJailed = sdkerrors.Register(ModuleName, 3, "validator still jailed; cannot be unjailed") + ErrValidatorNotJailed = sdkerrors.Register(ModuleName, 4, "validator not jailed; cannot be unjailed") + ErrMissingSelfDelegation = sdkerrors.Register(ModuleName, 5, "validator has no self-delegation; cannot be unjailed") + ErrSelfDelegationTooLowToUnjail = sdkerrors.Register(ModuleName, 6, "validator's self delegation less than minimum; cannot be unjailed") + ErrNoSigningInfoFound = sdkerrors.Register(ModuleName, 7, "no validator signing info found") ) - -func ErrNoValidatorForAddress(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "that address is not associated with any known validator") -} - -func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "validator does not exist for that address") -} - -func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeValidatorJailed, "validator still jailed, cannot yet be unjailed") -} - -func ErrValidatorNotJailed(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeValidatorNotJailed, "validator not jailed, cannot be unjailed") -} - -func ErrMissingSelfDelegation(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeMissingSelfDelegation, "validator has no self-delegation; cannot be unjailed") -} - -func ErrSelfDelegationTooLowToUnjail(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeValidatorNotJailed, "validator's self delegation less than MinSelfDelegation, cannot be unjailed") -} - -func ErrNoSigningInfoFound(codespace sdk.CodespaceType, consAddr sdk.ConsAddress) sdk.Error { - return sdk.NewError(codespace, CodeMissingSigningInfo, fmt.Sprintf("no signing info found for address: %s", consAddr)) -} diff --git a/x/slashing/internal/types/msg.go b/x/slashing/internal/types/msg.go index 3513d3b6c12b..b2ccdce173ba 100644 --- a/x/slashing/internal/types/msg.go +++ b/x/slashing/internal/types/msg.go @@ -33,9 +33,9 @@ func (msg MsgUnjail) GetSignBytes() []byte { } // ValidateBasic validity check for the AnteHandler -func (msg MsgUnjail) ValidateBasic() sdk.Error { +func (msg MsgUnjail) ValidateBasic() error { if msg.ValidatorAddr.Empty() { - return ErrBadValidatorAddr(DefaultCodespace) + return ErrBadValidatorAddr } return nil } diff --git a/x/slashing/simulation/operations.go b/x/slashing/simulation/operations.go index 3e2a3bc78bad..f5e263b778dc 100644 --- a/x/slashing/simulation/operations.go +++ b/x/slashing/simulation/operations.go @@ -93,7 +93,7 @@ func SimulateMsgUnjail(ak types.AccountKeeper, k keeper.Keeper, sk stakingkeeper simAccount.PrivKey, ) - res := app.Deliver(tx) + _, res, err := app.Deliver(tx) // result should fail if: // - validator cannot be unjailed due to tombstone @@ -102,7 +102,7 @@ func SimulateMsgUnjail(ak types.AccountKeeper, k keeper.Keeper, sk stakingkeeper if info.Tombstoned || ctx.BlockHeader().Time.Before(info.JailedUntil) || validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()) { - if res.IsOK() { + if res != nil && err == nil { if info.Tombstoned { return simulation.NewOperationMsg(msg, true, ""), nil, errors.New("validator should not have been unjailed if validator tombstoned") } @@ -117,7 +117,7 @@ func SimulateMsgUnjail(ak types.AccountKeeper, k keeper.Keeper, sk stakingkeeper return simulation.NewOperationMsg(msg, false, ""), nil, nil } - if !res.IsOK() { + if err != nil { return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) } diff --git a/x/staking/alias.go b/x/staking/alias.go index 887b9b7bf690..51c7eecc7087 100644 --- a/x/staking/alias.go +++ b/x/staking/alias.go @@ -1,11 +1,7 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/staking/keeper -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/staking/types -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/staking/exported package staking +// nolint + import ( "github.com/cosmos/cosmos-sdk/x/staking/exported" "github.com/cosmos/cosmos-sdk/x/staking/keeper" @@ -14,16 +10,6 @@ import ( const ( DefaultParamspace = keeper.DefaultParamspace - DefaultCodespace = types.DefaultCodespace - CodeInvalidValidator = types.CodeInvalidValidator - CodeInvalidDelegation = types.CodeInvalidDelegation - CodeInvalidInput = types.CodeInvalidInput - CodeValidatorJailed = types.CodeValidatorJailed - CodeInvalidHistoricalInfo = types.CodeInvalidHistoricalInfo - CodeInvalidAddress = types.CodeInvalidAddress - CodeUnauthorized = types.CodeUnauthorized - CodeInternal = types.CodeInternal - CodeUnknownRequest = types.CodeUnknownRequest ModuleName = types.ModuleName StoreKey = types.StoreKey TStoreKey = types.TStoreKey @@ -92,7 +78,7 @@ var ( MustMarshalHistoricalInfo = types.MustMarshalHistoricalInfo MustUnmarshalHistoricalInfo = types.MustUnmarshalHistoricalInfo UnmarshalHistoricalInfo = types.UnmarshalHistoricalInfo - ErrNilValidatorAddr = types.ErrNilValidatorAddr + ErrEmptyValidatorAddr = types.ErrEmptyValidatorAddr ErrBadValidatorAddr = types.ErrBadValidatorAddr ErrNoValidatorFound = types.ErrNoValidatorFound ErrValidatorOwnerExists = types.ErrValidatorOwnerExists @@ -100,7 +86,6 @@ var ( ErrValidatorPubKeyTypeNotSupported = types.ErrValidatorPubKeyTypeNotSupported ErrValidatorJailed = types.ErrValidatorJailed ErrBadRemoveValidator = types.ErrBadRemoveValidator - ErrDescriptionLength = types.ErrDescriptionLength ErrCommissionNegative = types.ErrCommissionNegative ErrCommissionHuge = types.ErrCommissionHuge ErrCommissionGTMaxRate = types.ErrCommissionGTMaxRate @@ -111,7 +96,7 @@ var ( ErrSelfDelegationBelowMinimum = types.ErrSelfDelegationBelowMinimum ErrMinSelfDelegationInvalid = types.ErrMinSelfDelegationInvalid ErrMinSelfDelegationDecreased = types.ErrMinSelfDelegationDecreased - ErrNilDelegatorAddr = types.ErrNilDelegatorAddr + ErrEmptyDelegatorAddr = types.ErrEmptyDelegatorAddr ErrBadDenom = types.ErrBadDenom ErrBadDelegationAddr = types.ErrBadDelegationAddr ErrBadDelegationAmount = types.ErrBadDelegationAmount @@ -129,14 +114,13 @@ var ( ErrBadRedelegationAddr = types.ErrBadRedelegationAddr ErrNoRedelegation = types.ErrNoRedelegation ErrSelfRedelegation = types.ErrSelfRedelegation - ErrVerySmallRedelegation = types.ErrVerySmallRedelegation + ErrTinyRedelegationAmount = types.ErrTinyRedelegationAmount ErrBadRedelegationDst = types.ErrBadRedelegationDst ErrTransitiveRedelegation = types.ErrTransitiveRedelegation ErrMaxRedelegationEntries = types.ErrMaxRedelegationEntries ErrDelegatorShareExRateInvalid = types.ErrDelegatorShareExRateInvalid ErrBothShareMsgsGiven = types.ErrBothShareMsgsGiven ErrNeitherShareMsgsGiven = types.ErrNeitherShareMsgsGiven - ErrMissingSignature = types.ErrMissingSignature ErrInvalidHistoricalInfo = types.ErrInvalidHistoricalInfo ErrNoHistoricalInfo = types.ErrNoHistoricalInfo NewGenesisState = types.NewGenesisState @@ -233,7 +217,6 @@ type ( RedelegationResponse = types.RedelegationResponse RedelegationEntryResponse = types.RedelegationEntryResponse RedelegationResponses = types.RedelegationResponses - CodeType = types.CodeType GenesisState = types.GenesisState LastValidatorPower = types.LastValidatorPower MultiStakingHooks = types.MultiStakingHooks diff --git a/x/staking/app_test.go b/x/staking/app_test.go index 0c2615d7a3ea..a56923113380 100644 --- a/x/staking/app_test.go +++ b/x/staking/app_test.go @@ -35,14 +35,14 @@ func getMockApp(t *testing.T) (*mock.App, Keeper) { blacklistedAddrs[notBondedPool.GetAddress().String()] = true blacklistedAddrs[bondPool.GetAddress().String()] = true - bankKeeper := bank.NewBaseKeeper(mApp.AccountKeeper, mApp.ParamsKeeper.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs) + bankKeeper := bank.NewBaseKeeper(mApp.AccountKeeper, mApp.ParamsKeeper.Subspace(bank.DefaultParamspace), blacklistedAddrs) maccPerms := map[string][]string{ auth.FeeCollectorName: nil, types.NotBondedPoolName: {supply.Burner, supply.Staking}, types.BondedPoolName: {supply.Burner, supply.Staking}, } supplyKeeper := supply.NewKeeper(mApp.Cdc, keySupply, mApp.AccountKeeper, bankKeeper, maccPerms) - keeper := NewKeeper(mApp.Cdc, keyStaking, supplyKeeper, mApp.ParamsKeeper.Subspace(DefaultParamspace), DefaultCodespace) + keeper := NewKeeper(mApp.Cdc, keyStaking, supplyKeeper, mApp.ParamsKeeper.Subspace(DefaultParamspace)) mApp.Router().AddRoute(RouterKey, NewHandler(keeper)) mApp.SetEndBlocker(getEndBlocker(keeper)) diff --git a/x/staking/client/cli/query.go b/x/staking/client/cli/query.go index 632237c1d915..14a60c49bc04 100644 --- a/x/staking/client/cli/query.go +++ b/x/staking/client/cli/query.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -24,7 +25,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, } - stakingQueryCmd.AddCommand(client.GetCommands( + stakingQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryDelegation(queryRoute, cdc), GetCmdQueryDelegations(queryRoute, cdc), GetCmdQueryUnbondingDelegation(queryRoute, cdc), diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 5898a25933f1..374d061e070a 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -33,7 +34,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - stakingTxCmd.AddCommand(client.PostCommands( + stakingTxCmd.AddCommand(flags.PostCommands( GetCmdCreateValidator(cdc), GetCmdEditValidator(cdc), GetCmdDelegate(cdc), @@ -69,10 +70,10 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command { cmd.Flags().AddFlagSet(FsCommissionCreate) cmd.Flags().AddFlagSet(FsMinSelfDelegation) - cmd.Flags().String(FlagIP, "", fmt.Sprintf("The node's public IP. It takes effect only when used in combination with --%s", client.FlagGenerateOnly)) + cmd.Flags().String(FlagIP, "", fmt.Sprintf("The node's public IP. It takes effect only when used in combination with --%s", flags.FlagGenerateOnly)) cmd.Flags().String(FlagNodeID, "", "The node's ID") - cmd.MarkFlagRequired(client.FlagFrom) + cmd.MarkFlagRequired(flags.FlagFrom) cmd.MarkFlagRequired(FlagAmount) cmd.MarkFlagRequired(FlagPubKey) cmd.MarkFlagRequired(FlagMoniker) @@ -118,8 +119,9 @@ func GetCmdEditValidator(cdc *codec.Codec) *cobra.Command { if minSelfDelegationString != "" { msb, ok := sdk.NewIntFromString(minSelfDelegationString) if !ok { - return fmt.Errorf(types.ErrMinSelfDelegationInvalid(types.DefaultCodespace).Error()) + return types.ErrMinSelfDelegationInvalid } + newMinSelfDelegation = &msb } @@ -309,8 +311,8 @@ func PrepareFlagsForTxCreateValidator( details := viper.GetString(FlagDetails) identity := viper.GetString(FlagIdentity) - viper.Set(client.FlagChainID, chainID) - viper.Set(client.FlagFrom, viper.GetString(client.FlagName)) + viper.Set(flags.FlagChainID, chainID) + viper.Set(flags.FlagFrom, viper.GetString(flags.FlagName)) viper.Set(FlagNodeID, nodeID) viper.Set(FlagIP, ip) viper.Set(FlagPubKey, sdk.MustBech32ifyConsPub(valPubKey)) @@ -321,7 +323,7 @@ func PrepareFlagsForTxCreateValidator( viper.Set(FlagIdentity, identity) if config.Moniker == "" { - viper.Set(FlagMoniker, viper.GetString(client.FlagName)) + viper.Set(FlagMoniker, viper.GetString(flags.FlagName)) } if viper.GetString(FlagAmount) == "" { viper.Set(FlagAmount, defaultAmount) @@ -377,14 +379,14 @@ func BuildCreateValidatorMsg(cliCtx context.CLIContext, txBldr auth.TxBuilder) ( msbStr := viper.GetString(FlagMinSelfDelegation) minSelfDelegation, ok := sdk.NewIntFromString(msbStr) if !ok { - return txBldr, nil, fmt.Errorf(types.ErrMinSelfDelegationInvalid(types.DefaultCodespace).Error()) + return txBldr, nil, types.ErrMinSelfDelegationInvalid } msg := types.NewMsgCreateValidator( sdk.ValAddress(valAddr), pk, amount, description, commissionRates, minSelfDelegation, ) - if viper.GetBool(client.FlagGenerateOnly) { + if viper.GetBool(flags.FlagGenerateOnly) { ip := viper.GetString(FlagIP) nodeID := viper.GetString(FlagNodeID) if nodeID != "" && ip != "" { diff --git a/x/staking/exported/exported.go b/x/staking/exported/exported.go index eae33c8ee105..7c8a257cd342 100644 --- a/x/staking/exported/exported.go +++ b/x/staking/exported/exported.go @@ -15,24 +15,24 @@ type DelegationI interface { // ValidatorI expected validator functions type ValidatorI interface { - IsJailed() bool // whether the validator is jailed - GetMoniker() string // moniker of the validator - GetStatus() sdk.BondStatus // status of the validator - IsBonded() bool // check if has a bonded status - IsUnbonded() bool // check if has status unbonded - IsUnbonding() bool // check if has status unbonding - GetOperator() sdk.ValAddress // operator address to receive/return validators coins - GetConsPubKey() crypto.PubKey // validation consensus pubkey - GetConsAddr() sdk.ConsAddress // validation consensus address - GetTokens() sdk.Int // validation tokens - GetBondedTokens() sdk.Int // validator bonded tokens - GetConsensusPower() int64 // validation power in tendermint - GetCommission() sdk.Dec // validator commission rate - GetMinSelfDelegation() sdk.Int // validator minimum self delegation - GetDelegatorShares() sdk.Dec // total outstanding delegator shares - TokensFromShares(sdk.Dec) sdk.Dec // token worth of provided delegator shares - TokensFromSharesTruncated(sdk.Dec) sdk.Dec // token worth of provided delegator shares, truncated - TokensFromSharesRoundUp(sdk.Dec) sdk.Dec // token worth of provided delegator shares, rounded up - SharesFromTokens(amt sdk.Int) (sdk.Dec, sdk.Error) // shares worth of delegator's bond - SharesFromTokensTruncated(amt sdk.Int) (sdk.Dec, sdk.Error) // truncated shares worth of delegator's bond + IsJailed() bool // whether the validator is jailed + GetMoniker() string // moniker of the validator + GetStatus() sdk.BondStatus // status of the validator + IsBonded() bool // check if has a bonded status + IsUnbonded() bool // check if has status unbonded + IsUnbonding() bool // check if has status unbonding + GetOperator() sdk.ValAddress // operator address to receive/return validators coins + GetConsPubKey() crypto.PubKey // validation consensus pubkey + GetConsAddr() sdk.ConsAddress // validation consensus address + GetTokens() sdk.Int // validation tokens + GetBondedTokens() sdk.Int // validator bonded tokens + GetConsensusPower() int64 // validation power in tendermint + GetCommission() sdk.Dec // validator commission rate + GetMinSelfDelegation() sdk.Int // validator minimum self delegation + GetDelegatorShares() sdk.Dec // total outstanding delegator shares + TokensFromShares(sdk.Dec) sdk.Dec // token worth of provided delegator shares + TokensFromSharesTruncated(sdk.Dec) sdk.Dec // token worth of provided delegator shares, truncated + TokensFromSharesRoundUp(sdk.Dec) sdk.Dec // token worth of provided delegator shares, rounded up + SharesFromTokens(amt sdk.Int) (sdk.Dec, error) // shares worth of delegator's bond + SharesFromTokensTruncated(amt sdk.Int) (sdk.Dec, error) // truncated shares worth of delegator's bond } diff --git a/x/staking/handler.go b/x/staking/handler.go index 376da255ea1c..da5933930382 100644 --- a/x/staking/handler.go +++ b/x/staking/handler.go @@ -1,19 +1,19 @@ package staking import ( - "fmt" "time" "github.com/tendermint/tendermint/libs/common" tmtypes "github.com/tendermint/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" ) func NewHandler(k keeper.Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -33,8 +33,7 @@ func NewHandler(k keeper.Keeper) sdk.Handler { return handleMsgUndelegate(ctx, msg, k) default: - errMsg := fmt.Sprintf("unrecognized staking message type: %T", msg) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg) } } } @@ -42,30 +41,31 @@ func NewHandler(k keeper.Keeper) sdk.Handler { // These functions assume everything has been authenticated, // now we just perform action and save -func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k keeper.Keeper) sdk.Result { +func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k keeper.Keeper) (*sdk.Result, error) { // check to see if the pubkey or sender has been registered before if _, found := k.GetValidator(ctx, msg.ValidatorAddress); found { - return ErrValidatorOwnerExists(k.Codespace()).Result() + return nil, ErrValidatorOwnerExists } if _, found := k.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(msg.PubKey)); found { - return ErrValidatorPubKeyExists(k.Codespace()).Result() + return nil, ErrValidatorPubKeyExists } if msg.Value.Denom != k.BondDenom(ctx) { - return ErrBadDenom(k.Codespace()).Result() + return nil, ErrBadDenom } if _, err := msg.Description.EnsureLength(); err != nil { - return err.Result() + return nil, err } if ctx.ConsensusParams() != nil { tmPubKey := tmtypes.TM2PB.PubKey(msg.PubKey) if !common.StringInSlice(tmPubKey.Type, ctx.ConsensusParams().Validator.PubKeyTypes) { - return ErrValidatorPubKeyTypeNotSupported(k.Codespace(), - tmPubKey.Type, - ctx.ConsensusParams().Validator.PubKeyTypes).Result() + return nil, sdkerrors.Wrapf( + ErrValidatorPubKeyTypeNotSupported, + "got: %s, valid: %s", tmPubKey.Type, ctx.ConsensusParams().Validator.PubKeyTypes, + ) } } @@ -76,7 +76,7 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k ) validator, err := validator.SetInitialCommission(commission) if err != nil { - return err.Result() + return nil, err } validator.MinSelfDelegation = msg.MinSelfDelegation @@ -93,7 +93,7 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k // NOTE source will always be from a wallet which are unbonded _, err = k.Delegate(ctx, msg.DelegatorAddress, msg.Value.Amount, sdk.Unbonded, validator, true) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -109,20 +109,20 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } -func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keeper.Keeper) sdk.Result { +func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keeper.Keeper) (*sdk.Result, error) { // validator must already be registered validator, found := k.GetValidator(ctx, msg.ValidatorAddress) if !found { - return ErrNoValidatorFound(k.Codespace()).Result() + return nil, ErrNoValidatorFound } // replace all editable fields (clients should autofill existing values) description, err := validator.Description.UpdateDescription(msg.Description) if err != nil { - return err.Result() + return nil, err } validator.Description = description @@ -130,7 +130,7 @@ func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keepe if msg.CommissionRate != nil { commission, err := k.UpdateValidatorCommission(ctx, validator, *msg.CommissionRate) if err != nil { - return err.Result() + return nil, err } // call the before-modification hook since we're about to update the commission @@ -141,11 +141,12 @@ func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keepe if msg.MinSelfDelegation != nil { if !msg.MinSelfDelegation.GT(validator.MinSelfDelegation) { - return ErrMinSelfDelegationDecreased(k.Codespace()).Result() + return nil, ErrMinSelfDelegationDecreased } if msg.MinSelfDelegation.GT(validator.Tokens) { - return ErrSelfDelegationBelowMinimum(k.Codespace()).Result() + return nil, ErrSelfDelegationBelowMinimum } + validator.MinSelfDelegation = (*msg.MinSelfDelegation) } @@ -164,23 +165,23 @@ func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keepe ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } -func handleMsgDelegate(ctx sdk.Context, msg types.MsgDelegate, k keeper.Keeper) sdk.Result { +func handleMsgDelegate(ctx sdk.Context, msg types.MsgDelegate, k keeper.Keeper) (*sdk.Result, error) { validator, found := k.GetValidator(ctx, msg.ValidatorAddress) if !found { - return ErrNoValidatorFound(k.Codespace()).Result() + return nil, ErrNoValidatorFound } if msg.Amount.Denom != k.BondDenom(ctx) { - return ErrBadDenom(k.Codespace()).Result() + return nil, ErrBadDenom } // NOTE: source funds are always unbonded _, err := k.Delegate(ctx, msg.DelegatorAddress, msg.Amount.Amount, sdk.Unbonded, validator, true) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -196,24 +197,24 @@ func handleMsgDelegate(ctx sdk.Context, msg types.MsgDelegate, k keeper.Keeper) ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } -func handleMsgUndelegate(ctx sdk.Context, msg types.MsgUndelegate, k keeper.Keeper) sdk.Result { +func handleMsgUndelegate(ctx sdk.Context, msg types.MsgUndelegate, k keeper.Keeper) (*sdk.Result, error) { shares, err := k.ValidateUnbondAmount( ctx, msg.DelegatorAddress, msg.ValidatorAddress, msg.Amount.Amount, ) if err != nil { - return err.Result() + return nil, err } if msg.Amount.Denom != k.BondDenom(ctx) { - return ErrBadDenom(k.Codespace()).Result() + return nil, ErrBadDenom } completionTime, err := k.Undelegate(ctx, msg.DelegatorAddress, msg.ValidatorAddress, shares) if err != nil { - return err.Result() + return nil, err } completionTimeBz := types.ModuleCdc.MustMarshalBinaryLengthPrefixed(completionTime) @@ -231,26 +232,26 @@ func handleMsgUndelegate(ctx sdk.Context, msg types.MsgUndelegate, k keeper.Keep ), }) - return sdk.Result{Data: completionTimeBz, Events: ctx.EventManager().Events()} + return &sdk.Result{Data: completionTimeBz, Events: ctx.EventManager().Events()}, nil } -func handleMsgBeginRedelegate(ctx sdk.Context, msg types.MsgBeginRedelegate, k keeper.Keeper) sdk.Result { +func handleMsgBeginRedelegate(ctx sdk.Context, msg types.MsgBeginRedelegate, k keeper.Keeper) (*sdk.Result, error) { shares, err := k.ValidateUnbondAmount( ctx, msg.DelegatorAddress, msg.ValidatorSrcAddress, msg.Amount.Amount, ) if err != nil { - return err.Result() + return nil, err } if msg.Amount.Denom != k.BondDenom(ctx) { - return ErrBadDenom(k.Codespace()).Result() + return nil, ErrBadDenom } completionTime, err := k.BeginRedelegation( ctx, msg.DelegatorAddress, msg.ValidatorSrcAddress, msg.ValidatorDstAddress, shares, ) if err != nil { - return err.Result() + return nil, err } completionTimeBz := types.ModuleCdc.MustMarshalBinaryLengthPrefixed(completionTime) @@ -269,5 +270,5 @@ func handleMsgBeginRedelegate(ctx sdk.Context, msg types.MsgBeginRedelegate, k k ), }) - return sdk.Result{Data: completionTimeBz, Events: ctx.EventManager().Events()} + return &sdk.Result{Data: completionTimeBz, Events: ctx.EventManager().Events()}, nil } diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 0e999ba9b43b..92147eabb097 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -26,8 +26,9 @@ func TestValidatorByPowerIndex(t *testing.T) { // create validator msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // must end-block updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -47,8 +48,9 @@ func TestValidatorByPowerIndex(t *testing.T) { // create a second validator keep it bonded msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], initBond) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // must end-block updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -84,11 +86,12 @@ func TestValidatorByPowerIndex(t *testing.T) { unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, totalBond) msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected msg to be ok, got %v", got) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) var finishTime time.Time - types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime) + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) ctx = ctx.WithBlockTime(finishTime) EndBlocker(ctx, keeper) @@ -108,8 +111,9 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidator1 := NewTestMsgCreateValidator(addr1, pk1, valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidator1, keeper) - require.True(t, got.IsOK(), "%v", got) + res, err := handleMsgCreateValidator(ctx, msgCreateValidator1, keeper) + require.NoError(t, err) + require.NotNil(t, res) keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -124,18 +128,21 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { // two validators can't have the same operator address msgCreateValidator2 := NewTestMsgCreateValidator(addr1, pk2, valTokens) - got = handleMsgCreateValidator(ctx, msgCreateValidator2, keeper) - require.False(t, got.IsOK(), "%v", got) + res, err = handleMsgCreateValidator(ctx, msgCreateValidator2, keeper) + require.Error(t, err) + require.Nil(t, res) // two validators can't have the same pubkey msgCreateValidator3 := NewTestMsgCreateValidator(addr2, pk1, valTokens) - got = handleMsgCreateValidator(ctx, msgCreateValidator3, keeper) - require.False(t, got.IsOK(), "%v", got) + res, err = handleMsgCreateValidator(ctx, msgCreateValidator3, keeper) + require.Error(t, err) + require.Nil(t, res) // must have different pubkey and operator msgCreateValidator4 := NewTestMsgCreateValidator(addr2, pk2, valTokens) - got = handleMsgCreateValidator(ctx, msgCreateValidator4, keeper) - require.True(t, got.IsOK(), "%v", got) + res, err = handleMsgCreateValidator(ctx, msgCreateValidator4, keeper) + require.NoError(t, err) + require.NotNil(t, res) // must end-block updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -160,15 +167,17 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { // invalid pukKey type should not be allowed msgCreateValidator := NewTestMsgCreateValidator(addr, invalidPk, sdk.NewInt(10)) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.False(t, got.IsOK(), "%v", got) + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.Error(t, err) + require.Nil(t, res) ctx = ctx.WithConsensusParams(&abci.ConsensusParams{ Validator: &abci.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeSecp256k1}}, }) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "%v", got) + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) } func TestLegacyValidatorDelegations(t *testing.T) { @@ -181,8 +190,9 @@ func TestLegacyValidatorDelegations(t *testing.T) { // create validator msgCreateVal := NewTestMsgCreateValidator(valAddr, valConsPubKey, bondAmount) - got := handleMsgCreateValidator(ctx, msgCreateVal, keeper) - require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got) + res, err := handleMsgCreateValidator(ctx, msgCreateVal, keeper) + require.NoError(t, err) + require.NotNil(t, res) // must end-block updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -197,8 +207,9 @@ func TestLegacyValidatorDelegations(t *testing.T) { // delegate tokens to the validator msgDelegate := NewTestMsgDelegate(delAddr, valAddr, bondAmount) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got) + res, err = handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // verify validator bonded shares validator, found = keeper.GetValidator(ctx, valAddr) @@ -210,11 +221,12 @@ func TestLegacyValidatorDelegations(t *testing.T) { unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, bondAmount) msgUndelegate := NewMsgUndelegate(sdk.AccAddress(valAddr), valAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected begin unbonding validator msg to be ok, got %v", got) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) var finishTime time.Time - types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime) + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) ctx = ctx.WithBlockTime(finishTime) EndBlocker(ctx, keeper) @@ -232,8 +244,9 @@ func TestLegacyValidatorDelegations(t *testing.T) { // verify the validator can still self-delegate msgSelfDelegate := NewTestMsgDelegate(sdk.AccAddress(valAddr), valAddr, bondAmount) - got = handleMsgDelegate(ctx, msgSelfDelegate, keeper) - require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got) + res, err = handleMsgDelegate(ctx, msgSelfDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // verify validator bonded shares validator, found = keeper.GetValidator(ctx, valAddr) @@ -246,8 +259,9 @@ func TestLegacyValidatorDelegations(t *testing.T) { // verify the validator can now accept delegations msgDelegate = NewTestMsgDelegate(delAddr, valAddr, bondAmount) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got) + res, err = handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // verify validator bonded shares validator, found = keeper.GetValidator(ctx, valAddr) @@ -273,8 +287,9 @@ func TestIncrementsMsgDelegate(t *testing.T) { // first create validator msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], bondAmount) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got) + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // apply TM updates keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -301,8 +316,9 @@ func TestIncrementsMsgDelegate(t *testing.T) { for i := int64(0); i < 5; i++ { ctx = ctx.WithBlockHeight(i) - got := handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) + res, err := handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) //Check that the accounts and the bond account have the appropriate values validator, found := keeper.GetValidator(ctx, validatorAddr) @@ -340,8 +356,9 @@ func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { // create validator msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // must end-block updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -357,8 +374,9 @@ func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { newMinSelfDelegation := sdk.OneInt() msgEditValidator := NewMsgEditValidator(validatorAddr, Description{}, nil, &newMinSelfDelegation) - got = handleMsgEditValidator(ctx, msgEditValidator, keeper) - require.False(t, got.IsOK(), "should not be able to decrease minSelfDelegation") + res, err = handleMsgEditValidator(ctx, msgEditValidator, keeper) + require.Error(t, err) + require.Nil(t, res) } func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { @@ -371,8 +389,9 @@ func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { // create validator msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // must end-block updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -388,8 +407,9 @@ func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { newMinSelfDelegation := initBond.Add(sdk.OneInt()) msgEditValidator := NewMsgEditValidator(validatorAddr, Description{}, nil, &newMinSelfDelegation) - got = handleMsgEditValidator(ctx, msgEditValidator, keeper) - require.False(t, got.IsOK(), "should not be able to increase minSelfDelegation above current self delegation") + res, err = handleMsgEditValidator(ctx, msgEditValidator, keeper) + require.Error(t, err) + require.Nil(t, res) } func TestIncrementsMsgUnbond(t *testing.T) { @@ -404,15 +424,17 @@ func TestIncrementsMsgUnbond(t *testing.T) { validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // initial balance amt1 := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(denom) msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, initBond) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got) + res, err = handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // balance should have been subtracted after delegation amt2 := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(denom) @@ -431,12 +453,15 @@ func TestIncrementsMsgUnbond(t *testing.T) { unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) numUnbonds := int64(5) + for i := int64(0); i < numUnbonds; i++ { + res, err := handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) - got := handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) var finishTime time.Time - types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime) + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) + ctx = ctx.WithBlockTime(finishTime) EndBlocker(ctx, keeper) @@ -474,11 +499,12 @@ func TestIncrementsMsgUnbond(t *testing.T) { initBond, } - for i, c := range errorCases { + for _, c := range errorCases { unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, c) msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.False(t, got.IsOK(), "expected unbond msg to fail, index: %v", i) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.Error(t, err) + require.Nil(t, res) } leftBonded := initBond.Sub(unbondAmt.Amount.Mul(sdk.NewInt(numUnbonds))) @@ -486,9 +512,9 @@ func TestIncrementsMsgUnbond(t *testing.T) { // should be able to unbond remaining unbondAmt = sdk.NewCoin(sdk.DefaultBondDenom, leftBonded) msgUndelegate = NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), - "got: %v\nmsgUnbond: %v\nshares: %s\nleftBonded: %s\n", got.Log, msgUndelegate, unbondAmt, leftBonded) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err, "msgUnbond: %v\nshares: %s\nleftBonded: %s\n", msgUndelegate, unbondAmt, leftBonded) + require.NotNil(t, res, "msgUnbond: %v\nshares: %s\nleftBonded: %s\n", msgUndelegate, unbondAmt, leftBonded) } func TestMultipleMsgCreateValidator(t *testing.T) { @@ -516,8 +542,9 @@ func TestMultipleMsgCreateValidator(t *testing.T) { valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidator(validatorAddr, keep.PKs[i], valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper) - require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) + res, err := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper) + require.NoError(t, err) + require.NotNil(t, res) // verify that the account is bonded validators := keeper.GetValidators(ctx, 100) @@ -541,11 +568,12 @@ func TestMultipleMsgCreateValidator(t *testing.T) { unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) msgUndelegate := NewMsgUndelegate(delegatorAddrs[i], validatorAddr, unbondAmt) // remove delegation - got := handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) + res, err := handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) var finishTime time.Time - types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime) + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) // adds validator into unbonding queue EndBlocker(ctx, keeper) @@ -572,14 +600,16 @@ func TestMultipleMsgDelegate(t *testing.T) { // first make a validator msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected msg to be ok, got %v", got) + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // delegate multiple parties - for i, delegatorAddr := range delegatorAddrs { + for _, delegatorAddr := range delegatorAddrs { msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) - got := handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) + res, err := handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // check that the account is bonded bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) @@ -588,15 +618,16 @@ func TestMultipleMsgDelegate(t *testing.T) { } // unbond them all - for i, delegatorAddr := range delegatorAddrs { + for _, delegatorAddr := range delegatorAddrs { unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) - got := handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) + res, err := handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) var finishTime time.Time - types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime) + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) ctx = ctx.WithBlockTime(finishTime) EndBlocker(ctx, keeper) @@ -613,22 +644,25 @@ func TestJailValidator(t *testing.T) { // create the validator msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // bond a delegator msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected ok, got %v", got) + res, err = handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // unbond the validators bond portion unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper) - require.True(t, got.IsOK(), "expected no error: %v", got) + res, err = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) var finishTime time.Time - types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime) + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) ctx = ctx.WithBlockTime(finishTime) EndBlocker(ctx, keeper) @@ -640,16 +674,18 @@ func TestJailValidator(t *testing.T) { // test that the delegator can still withdraw their bonds msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper) - require.True(t, got.IsOK(), "expected no error") - types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime) + res, err = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper) + require.NoError(t, err) + require.NotNil(t, res) + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) ctx = ctx.WithBlockTime(finishTime) EndBlocker(ctx, keeper) // verify that the pubkey can now be reused - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected ok, got %v", got) + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) } func TestValidatorQueue(t *testing.T) { @@ -664,25 +700,28 @@ func TestValidatorQueue(t *testing.T) { // create the validator valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // bond a delegator delTokens := sdk.TokensFromConsensusPower(10) msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, delTokens) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected ok, got %v", got) + res, err = handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) EndBlocker(ctx, keeper) // unbond the all self-delegation to put validator in unbonding state unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, delTokens) msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper) - require.True(t, got.IsOK(), "expected no error: %v", got) + res, err = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) var finishTime time.Time - types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime) + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) ctx = ctx.WithBlockTime(finishTime) EndBlocker(ctx, keeper) @@ -722,16 +761,18 @@ func TestUnbondingPeriod(t *testing.T) { // create the validator valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) EndBlocker(ctx, keeper) // begin unbonding unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected no error") + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) origHeader := ctx.BlockHeader() @@ -762,29 +803,33 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) { // create the validator msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // bond a delegator msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected ok, got %v", got) + res, err = handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // unbond the validators bond portion unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper) - require.True(t, got.IsOK(), "expected no error") + res, err = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // change the ctx to Block Time one second before the validator would have unbonded var finishTime time.Time - types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime) + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime) ctx = ctx.WithBlockTime(finishTime.Add(time.Second * -1)) // unbond the delegator from the validator msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper) - require.True(t, got.IsOK(), "expected no error") + res, err = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper) + require.NoError(t, err) + require.NotNil(t, res) ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(keeper.UnbondingTime(ctx))) @@ -813,24 +858,27 @@ func TestRedelegationPeriod(t *testing.T) { // initial balance amt1 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // balance should have been subtracted after creation amt2 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom) require.Equal(t, amt1.Sub(sdk.NewInt(10)).Int64(), amt2.Int64(), "expected coins to be subtracted") msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], sdk.NewInt(10)) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) bal1 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins() // begin redelegate redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt) - got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) - require.True(t, got.IsOK(), "expected no error, %v", got) + res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // origin account should not lose tokens as with a regular delegation bal2 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins() @@ -867,27 +915,32 @@ func TestTransitiveRedelegation(t *testing.T) { // create the validators msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], sdk.NewInt(10)) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], sdk.NewInt(10)) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // begin redelegate redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt) - got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) - require.True(t, got.IsOK(), "expected no error, %v", got) + res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // cannot redelegation to next validator while first delegation exists msgBeginRedelegate = NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr2, validatorAddr3, redAmt) - got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) - require.True(t, !got.IsOK(), "expected an error, msg: %v", msgBeginRedelegate) + res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) + require.Error(t, err) + require.Nil(t, res) params := keeper.GetParams(ctx) ctx = ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)) @@ -896,8 +949,9 @@ func TestTransitiveRedelegation(t *testing.T) { EndBlocker(ctx, keeper) // now should be able to redelegate from the second validator to the third - got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) - require.True(t, got.IsOK(), "expected no error", got.Log) + res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) } func TestMultipleRedelegationAtSameTime(t *testing.T) { @@ -913,12 +967,14 @@ func TestMultipleRedelegationAtSameTime(t *testing.T) { // create the validators valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) msgCreateValidator = NewTestMsgCreateValidator(valAddr2, keep.PKs[1], valTokens) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond them EndBlocker(ctx, keeper) @@ -927,8 +983,9 @@ func TestMultipleRedelegationAtSameTime(t *testing.T) { selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) - got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) - require.True(t, got.IsOK(), "expected no error, %v", got) + res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // there should only be one entry in the redelegation object rd, found := keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) @@ -936,8 +993,9 @@ func TestMultipleRedelegationAtSameTime(t *testing.T) { require.Len(t, rd.Entries, 1) // start a second redelegation at this same time as the first - got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) - require.True(t, got.IsOK(), "expected no error, msg: %v", msgBeginRedelegate) + res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // now there should be two entries rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) @@ -965,12 +1023,14 @@ func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { // create the validators valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) msgCreateValidator = NewTestMsgCreateValidator(valAddr2, keep.PKs[1], valTokens) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond them EndBlocker(ctx, keeper) @@ -979,13 +1039,15 @@ func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) - got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) - require.True(t, got.IsOK(), "expected no error, %v", got) + res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // move forward in time and start a second redelegation ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) - got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) - require.True(t, got.IsOK(), "expected no error, msg: %v", msgBeginRedelegate) + res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // now there should be two entries rd, found := keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) @@ -1018,8 +1080,9 @@ func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { // create the validator valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond EndBlocker(ctx, keeper) @@ -1028,8 +1091,9 @@ func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected no error, %v", got) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // there should only be one entry in the ubd object ubd, found := keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) @@ -1037,8 +1101,9 @@ func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { require.Len(t, ubd.Entries, 1) // start a second ubd at this same time as the first - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected no error, msg: %v", msgUndelegate) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // now there should be two entries ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) @@ -1065,8 +1130,9 @@ func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { // create the validator valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // end block to bond EndBlocker(ctx, keeper) @@ -1075,8 +1141,9 @@ func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected no error, %v", got) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // there should only be one entry in the ubd object ubd, found := keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) @@ -1085,8 +1152,9 @@ func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { // move forwaubd in time and start a second redelegation ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected no error, msg: %v", msgUndelegate) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // now there should be two entries ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) @@ -1121,24 +1189,30 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { // add three validators valTokens1 := sdk.TokensFromConsensusPower(50) msgCreateValidator := NewTestMsgCreateValidator(validatorAddr1, keep.PKs[0], valTokens1) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) + // apply TM updates keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(keeper.GetLastValidators(ctx))) valTokens2 := sdk.TokensFromConsensusPower(30) msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], valTokens2) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) + // apply TM updates keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(keeper.GetLastValidators(ctx))) valTokens3 := sdk.TokensFromConsensusPower(10) msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], valTokens3) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) + // apply TM updates keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(keeper.GetLastValidators(ctx))) @@ -1146,8 +1220,9 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { // unbond the validator-2 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens2) msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr2), validatorAddr2, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgUndelegate") + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // apply TM updates keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -1169,17 +1244,20 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidator := NewTestMsgCreateValidator(valA, keep.PKs[0], valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) msgCreateValidator = NewTestMsgCreateValidator(valB, keep.PKs[1], valTokens) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + require.NoError(t, err) + require.NotNil(t, res) // delegate 10 stake msgDelegate := NewTestMsgDelegate(del, valA, valTokens) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgDelegate") + res, err = handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // apply Tendermint updates updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -1191,14 +1269,16 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { // begin unbonding 4 stake unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(4)) msgUndelegate := NewMsgUndelegate(del, valA, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgUndelegate") + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // begin redelegate 6 stake redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(6)) msgBeginRedelegate := NewMsgBeginRedelegate(del, valA, valB, redAmt) - got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgBeginRedelegate") + res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) // destination delegation should have 6 shares delegation, found := keeper.GetDelegation(ctx, del, valB) @@ -1266,9 +1346,10 @@ func TestInvalidMsg(t *testing.T) { k := keep.Keeper{} h := NewHandler(k) - res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) - require.False(t, res.IsOK()) - require.True(t, strings.Contains(res.Log, "unrecognized staking message type")) + res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) + require.Error(t, err) + require.Nil(t, res) + require.True(t, strings.Contains(err.Error(), "unrecognized staking message type")) } func TestInvalidCoinDenom(t *testing.T) { @@ -1283,33 +1364,47 @@ func TestInvalidCoinDenom(t *testing.T) { commission := types.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.ZeroDec()) msgCreate := types.NewMsgCreateValidator(valA, keep.PKs[0], invalidCoin, Description{}, commission, sdk.OneInt()) - got := handleMsgCreateValidator(ctx, msgCreate, keeper) - require.False(t, got.IsOK()) + res, err := handleMsgCreateValidator(ctx, msgCreate, keeper) + require.Error(t, err) + require.Nil(t, res) + msgCreate = types.NewMsgCreateValidator(valA, keep.PKs[0], validCoin, Description{}, commission, sdk.OneInt()) - got = handleMsgCreateValidator(ctx, msgCreate, keeper) - require.True(t, got.IsOK()) + res, err = handleMsgCreateValidator(ctx, msgCreate, keeper) + require.NoError(t, err) + require.NotNil(t, res) + msgCreate = types.NewMsgCreateValidator(valB, keep.PKs[1], validCoin, Description{}, commission, sdk.OneInt()) - got = handleMsgCreateValidator(ctx, msgCreate, keeper) - require.True(t, got.IsOK()) + res, err = handleMsgCreateValidator(ctx, msgCreate, keeper) + require.NoError(t, err) + require.NotNil(t, res) msgDelegate := types.NewMsgDelegate(delAddr, valA, invalidCoin) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.False(t, got.IsOK()) + res, err = handleMsgDelegate(ctx, msgDelegate, keeper) + require.Error(t, err) + require.Nil(t, res) + msgDelegate = types.NewMsgDelegate(delAddr, valA, validCoin) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK()) + res, err = handleMsgDelegate(ctx, msgDelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) msgUndelegate := types.NewMsgUndelegate(delAddr, valA, invalidCoin) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.False(t, got.IsOK()) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.Error(t, err) + require.Nil(t, res) + msgUndelegate = types.NewMsgUndelegate(delAddr, valA, oneCoin) - got = handleMsgUndelegate(ctx, msgUndelegate, keeper) - require.True(t, got.IsOK()) + res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) msgRedelegate := types.NewMsgBeginRedelegate(delAddr, valA, valB, invalidCoin) - got = handleMsgBeginRedelegate(ctx, msgRedelegate, keeper) - require.False(t, got.IsOK()) + res, err = handleMsgBeginRedelegate(ctx, msgRedelegate, keeper) + require.Error(t, err) + require.Nil(t, res) + msgRedelegate = types.NewMsgBeginRedelegate(delAddr, valA, valB, oneCoin) - got = handleMsgBeginRedelegate(ctx, msgRedelegate, keeper) - require.True(t, got.IsOK()) + res, err = handleMsgBeginRedelegate(ctx, msgRedelegate, keeper) + require.NoError(t, err) + require.NotNil(t, res) } diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 3aa244b3b3c9..faf8ba415ef7 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -6,6 +6,7 @@ import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -456,14 +457,16 @@ func (k Keeper) DequeueAllMatureRedelegationQueue(ctx sdk.Context, currTime time // Perform a delegation, set/update everything necessary within the store. // tokenSrc indicates the bond status of the incoming funds. -func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Int, tokenSrc sdk.BondStatus, - validator types.Validator, subtractAccount bool) (newShares sdk.Dec, err sdk.Error) { +func (k Keeper) Delegate( + ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Int, tokenSrc sdk.BondStatus, + validator types.Validator, subtractAccount bool, +) (newShares sdk.Dec, err error) { // In some situations, the exchange rate becomes invalid, e.g. if // Validator loses all tokens due to slashing. In this case, // make all future delegations invalid. if validator.InvalidExRate() { - return sdk.ZeroDec(), types.ErrDelegatorShareExRateInvalid(k.Codespace()) + return sdk.ZeroDec(), types.ErrDelegatorShareExRateInvalid } // Get or create the delegation object @@ -534,13 +537,14 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.In } // unbond a particular delegation and perform associated store operations -func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, - shares sdk.Dec) (amount sdk.Int, err sdk.Error) { +func (k Keeper) unbond( + ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec, +) (amount sdk.Int, err error) { // check if a delegation object exists in the store delegation, found := k.GetDelegation(ctx, delAddr, valAddr) if !found { - return amount, types.ErrNoDelegatorForAddress(k.Codespace()) + return amount, types.ErrNoDelegatorForAddress } // call the before-delegation-modified hook @@ -548,13 +552,13 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA // ensure that we have enough shares to remove if delegation.Shares.LT(shares) { - return amount, types.ErrNotEnoughDelegationShares(k.Codespace(), delegation.Shares.String()) + return amount, sdkerrors.Wrap(types.ErrNotEnoughDelegationShares, delegation.Shares.String()) } // get validator validator, found := k.GetValidator(ctx, valAddr) if !found { - return amount, types.ErrNoValidatorFound(k.Codespace()) + return amount, types.ErrNoValidatorFound } // subtract shares from delegation @@ -628,15 +632,15 @@ func (k Keeper) getBeginInfo( // processed during the staking EndBlocker. func (k Keeper) Undelegate( ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec, -) (time.Time, sdk.Error) { +) (time.Time, error) { validator, found := k.GetValidator(ctx, valAddr) if !found { - return time.Time{}, types.ErrNoDelegatorForAddress(k.Codespace()) + return time.Time{}, types.ErrNoDelegatorForAddress } if k.HasMaxUnbondingDelegationEntries(ctx, delAddr, valAddr) { - return time.Time{}, types.ErrMaxUnbondingDelegationEntries(k.Codespace()) + return time.Time{}, types.ErrMaxUnbondingDelegationEntries } returnAmount, err := k.unbond(ctx, delAddr, valAddr, sharesAmount) @@ -658,12 +662,10 @@ func (k Keeper) Undelegate( // CompleteUnbonding completes the unbonding of all mature entries in the // retrieved unbonding delegation object. -func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, - valAddr sdk.ValAddress) sdk.Error { - +func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { ubd, found := k.GetUnbondingDelegation(ctx, delAddr, valAddr) if !found { - return types.ErrNoUnbondingDelegation(k.Codespace()) + return types.ErrNoUnbondingDelegation } ctxTime := ctx.BlockHeader().Time @@ -697,31 +699,31 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, } // begin unbonding / redelegation; create a redelegation record -func (k Keeper) BeginRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, - valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdk.Dec) ( - completionTime time.Time, errSdk sdk.Error) { +func (k Keeper) BeginRedelegation( + ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdk.Dec, +) (completionTime time.Time, err error) { if bytes.Equal(valSrcAddr, valDstAddr) { - return time.Time{}, types.ErrSelfRedelegation(k.Codespace()) + return time.Time{}, types.ErrSelfRedelegation } dstValidator, found := k.GetValidator(ctx, valDstAddr) if !found { - return time.Time{}, types.ErrBadRedelegationDst(k.Codespace()) + return time.Time{}, types.ErrBadRedelegationDst } srcValidator, found := k.GetValidator(ctx, valSrcAddr) if !found { - return time.Time{}, types.ErrBadRedelegationDst(k.Codespace()) + return time.Time{}, types.ErrBadRedelegationDst } // check if this is a transitive redelegation if k.HasReceivingRedelegation(ctx, delAddr, valSrcAddr) { - return time.Time{}, types.ErrTransitiveRedelegation(k.Codespace()) + return time.Time{}, types.ErrTransitiveRedelegation } if k.HasMaxRedelegationEntries(ctx, delAddr, valSrcAddr, valDstAddr) { - return time.Time{}, types.ErrMaxRedelegationEntries(k.Codespace()) + return time.Time{}, types.ErrMaxRedelegationEntries } returnAmount, err := k.unbond(ctx, delAddr, valSrcAddr, sharesAmount) @@ -730,7 +732,7 @@ func (k Keeper) BeginRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, } if returnAmount.IsZero() { - return time.Time{}, types.ErrVerySmallRedelegation(k.Codespace()) + return time.Time{}, types.ErrTinyRedelegationAmount } sharesCreated, err := k.Delegate(ctx, delAddr, returnAmount, srcValidator.GetStatus(), dstValidator, false) @@ -745,20 +747,23 @@ func (k Keeper) BeginRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, return completionTime, nil } - red := k.SetRedelegationEntry(ctx, delAddr, valSrcAddr, valDstAddr, - height, completionTime, returnAmount, sharesAmount, sharesCreated) + red := k.SetRedelegationEntry( + ctx, delAddr, valSrcAddr, valDstAddr, + height, completionTime, returnAmount, sharesAmount, sharesCreated, + ) k.InsertRedelegationQueue(ctx, red, completionTime) return completionTime, nil } // CompleteRedelegation completes the unbonding of all mature entries in the // retrieved unbonding delegation object. -func (k Keeper) CompleteRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, - valSrcAddr, valDstAddr sdk.ValAddress) sdk.Error { +func (k Keeper) CompleteRedelegation( + ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, +) error { red, found := k.GetRedelegation(ctx, delAddr, valSrcAddr, valDstAddr) if !found { - return types.ErrNoRedelegation(k.Codespace()) + return types.ErrNoRedelegation } ctxTime := ctx.BlockHeader().Time @@ -787,16 +792,16 @@ func (k Keeper) CompleteRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, // amount of respective shares is returned, otherwise an error is returned. func (k Keeper) ValidateUnbondAmount( ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk.Int, -) (shares sdk.Dec, err sdk.Error) { +) (shares sdk.Dec, err error) { validator, found := k.GetValidator(ctx, valAddr) if !found { - return shares, types.ErrNoValidatorFound(k.Codespace()) + return shares, types.ErrNoValidatorFound } del, found := k.GetDelegation(ctx, delAddr, valAddr) if !found { - return shares, types.ErrNoDelegation(k.Codespace()) + return shares, types.ErrNoDelegation } shares, err = validator.SharesFromTokens(amt) @@ -811,7 +816,7 @@ func (k Keeper) ValidateUnbondAmount( delShares := del.GetShares() if sharesTruncated.GT(delShares) { - return shares, types.ErrBadSharesAmount(k.Codespace()) + return shares, types.ErrBadSharesAmount } // Cap the shares at the delegation's shares. Shares being greater could occur diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index a63f5cf1ed68..fd51603115b7 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -29,14 +29,12 @@ type Keeper struct { paramstore params.Subspace validatorCache map[string]cachedValidator validatorCacheList *list.List - - // codespace - codespace sdk.CodespaceType } // NewKeeper creates a new staking Keeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, supplyKeeper types.SupplyKeeper, - paramstore params.Subspace, codespace sdk.CodespaceType) Keeper { +func NewKeeper( + cdc *codec.Codec, key sdk.StoreKey, supplyKeeper types.SupplyKeeper, paramstore params.Subspace, +) Keeper { // ensure bonded and not bonded module accounts are set if addr := supplyKeeper.GetModuleAddress(types.BondedPoolName); addr == nil { @@ -55,7 +53,6 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, supplyKeeper types.SupplyKeep hooks: nil, validatorCache: make(map[string]cachedValidator, aminoCacheSize), validatorCacheList: list.New(), - codespace: codespace, } } @@ -73,11 +70,6 @@ func (k *Keeper) SetHooks(sh types.StakingHooks) *Keeper { return k } -// return the codespace -func (k Keeper) Codespace() sdk.CodespaceType { - return k.codespace -} - // Load the last total validator power. func (k Keeper) GetLastTotalPower(ctx sdk.Context) (power sdk.Int) { store := ctx.KVStore(k.storeKey) diff --git a/x/staking/keeper/pool.go b/x/staking/keeper/pool.go index 4ceb02446d93..004013ed8fe4 100644 --- a/x/staking/keeper/pool.go +++ b/x/staking/keeper/pool.go @@ -35,7 +35,7 @@ func (k Keeper) notBondedTokensToBonded(ctx sdk.Context, tokens sdk.Int) { } // burnBondedTokens removes coins from the bonded pool module account -func (k Keeper) burnBondedTokens(ctx sdk.Context, amt sdk.Int) sdk.Error { +func (k Keeper) burnBondedTokens(ctx sdk.Context, amt sdk.Int) error { if !amt.IsPositive() { // skip as no coins need to be burned return nil @@ -45,7 +45,7 @@ func (k Keeper) burnBondedTokens(ctx sdk.Context, amt sdk.Int) sdk.Error { } // burnNotBondedTokens removes coins from the not bonded pool module account -func (k Keeper) burnNotBondedTokens(ctx sdk.Context, amt sdk.Int) sdk.Error { +func (k Keeper) burnNotBondedTokens(ctx sdk.Context, amt sdk.Int) error { if !amt.IsPositive() { // skip as no coins need to be burned return nil diff --git a/x/staking/keeper/querier.go b/x/staking/keeper/querier.go index 15bc59ee5ff6..bc8a5b5b7fc0 100644 --- a/x/staking/keeper/querier.go +++ b/x/staking/keeper/querier.go @@ -1,7 +1,7 @@ package keeper import ( - "fmt" + "errors" "strings" abci "github.com/tendermint/tendermint/abci/types" @@ -9,53 +9,68 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/staking/types" ) // creates a querier for staking REST endpoints func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryValidators: return queryValidators(ctx, req, k) + case types.QueryValidator: return queryValidator(ctx, req, k) + case types.QueryValidatorDelegations: return queryValidatorDelegations(ctx, req, k) + case types.QueryValidatorUnbondingDelegations: return queryValidatorUnbondingDelegations(ctx, req, k) + case types.QueryDelegation: return queryDelegation(ctx, req, k) + case types.QueryUnbondingDelegation: return queryUnbondingDelegation(ctx, req, k) + case types.QueryDelegatorDelegations: return queryDelegatorDelegations(ctx, req, k) + case types.QueryDelegatorUnbondingDelegations: return queryDelegatorUnbondingDelegations(ctx, req, k) + case types.QueryRedelegations: return queryRedelegations(ctx, req, k) + case types.QueryDelegatorValidators: return queryDelegatorValidators(ctx, req, k) + case types.QueryDelegatorValidator: return queryDelegatorValidator(ctx, req, k) + case types.QueryHistoricalInfo: return queryHistoricalInfo(ctx, req, k) + case types.QueryPool: return queryPool(ctx, k) + case types.QueryParameters: return queryParameters(ctx, k) + default: - return nil, sdk.ErrUnknownRequest("unknown staking query endpoint") + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) } } } -func queryValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryValidatorsParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } validators := k.GetAllValidators(ctx) @@ -76,45 +91,45 @@ func queryValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, res, err := codec.MarshalJSONIndent(types.ModuleCdc, filteredVals) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to JSON marshal result: %s", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryValidatorParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } validator, found := k.GetValidator(ctx, params.ValidatorAddr) if !found { - return nil, types.ErrNoValidatorFound(types.DefaultCodespace) + return nil, types.ErrNoValidatorFound } res, err := codec.MarshalJSONIndent(types.ModuleCdc, validator) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryValidatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryValidatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryValidatorParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } delegations := k.GetValidatorDelegations(ctx, params.ValidatorAddr) delegationResps, err := delegationsToDelegationResponses(ctx, k, delegations) if err != nil { - return nil, sdk.ErrInternal(err.Error()) + return nil, err } if delegationResps == nil { @@ -123,18 +138,18 @@ func queryValidatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) res, err := codec.MarshalJSONIndent(types.ModuleCdc, delegationResps) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryValidatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryValidatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryValidatorParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } unbonds := k.GetUnbondingDelegationsFromValidator(ctx, params.ValidatorAddr) @@ -144,24 +159,24 @@ func queryValidatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, res, err := codec.MarshalJSONIndent(types.ModuleCdc, unbonds) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryDelegatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryDelegatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryDelegatorParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } delegations := k.GetAllDelegatorDelegations(ctx, params.DelegatorAddr) delegationResps, err := delegationsToDelegationResponses(ctx, k, delegations) if err != nil { - return nil, sdk.ErrInternal(err.Error()) + return nil, err } if delegationResps == nil { @@ -170,18 +185,18 @@ func queryDelegatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) res, err := codec.MarshalJSONIndent(types.ModuleCdc, delegationResps) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryDelegatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryDelegatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryDelegatorParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } unbondingDelegations := k.GetAllUnbondingDelegations(ctx, params.DelegatorAddr) @@ -191,20 +206,20 @@ func queryDelegatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, res, err := codec.MarshalJSONIndent(types.ModuleCdc, unbondingDelegations) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryDelegatorValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryDelegatorValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryDelegatorParams stakingParams := k.GetParams(ctx) err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } validators := k.GetDelegatorValidators(ctx, params.DelegatorAddr, stakingParams.MaxValidators) @@ -214,86 +229,86 @@ func queryDelegatorValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper) res, err := codec.MarshalJSONIndent(types.ModuleCdc, validators) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryDelegatorValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryDelegatorValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryBondsParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } validator, err := k.GetDelegatorValidator(ctx, params.DelegatorAddr, params.ValidatorAddr) if err != nil { - return nil, sdk.ErrInternal(err.Error()) + return nil, err } res, err := codec.MarshalJSONIndent(types.ModuleCdc, validator) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryBondsParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } delegation, found := k.GetDelegation(ctx, params.DelegatorAddr, params.ValidatorAddr) if !found { - return nil, types.ErrNoDelegation(types.DefaultCodespace) + return nil, types.ErrNoDelegation } delegationResp, err := delegationToDelegationResponse(ctx, k, delegation) if err != nil { - return nil, sdk.ErrInternal(err.Error()) + return nil, err } res, err := codec.MarshalJSONIndent(types.ModuleCdc, delegationResp) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryUnbondingDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryUnbondingDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryBondsParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } unbond, found := k.GetUnbondingDelegation(ctx, params.DelegatorAddr, params.ValidatorAddr) if !found { - return nil, types.ErrNoUnbondingDelegation(types.DefaultCodespace) + return nil, types.ErrNoUnbondingDelegation } res, err := codec.MarshalJSONIndent(types.ModuleCdc, unbond) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryRedelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryRedelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryRedelegationParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(string(req.Data)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } var redels []types.Redelegation @@ -302,7 +317,7 @@ func queryRedelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt case !params.DelegatorAddr.Empty() && !params.SrcValidatorAddr.Empty() && !params.DstValidatorAddr.Empty(): redel, found := k.GetRedelegation(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr) if !found { - return nil, types.ErrNoRedelegation(types.DefaultCodespace) + return nil, types.ErrNoRedelegation } redels = []types.Redelegation{redel} @@ -314,7 +329,7 @@ func queryRedelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt redelResponses, err := redelegationsToRedelegationResponses(ctx, k, redels) if err != nil { - return nil, sdk.ErrInternal(err.Error()) + return nil, err } if redelResponses == nil { @@ -323,39 +338,40 @@ func queryRedelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt res, err := codec.MarshalJSONIndent(types.ModuleCdc, redelResponses) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryHistoricalInfo(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryHistoricalInfo(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryHistoricalInfoParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(string(req.Data)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } hi, found := k.GetHistoricalInfo(ctx, params.Height) if !found { - return nil, types.ErrNoHistoricalInfo(types.DefaultCodespace) + return nil, types.ErrNoHistoricalInfo } res, err := codec.MarshalJSONIndent(types.ModuleCdc, hi) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryPool(ctx sdk.Context, k Keeper) ([]byte, sdk.Error) { +func queryPool(ctx sdk.Context, k Keeper) ([]byte, error) { bondDenom := k.BondDenom(ctx) + bondedPool := k.GetBondedPool(ctx) notBondedPool := k.GetNotBondedPool(ctx) if bondedPool == nil || notBondedPool == nil { - return nil, sdk.ErrInternal("pool accounts haven't been set") + return nil, errors.New("pool accounts haven't been set") } pool := types.NewPool( @@ -365,18 +381,18 @@ func queryPool(ctx sdk.Context, k Keeper) ([]byte, sdk.Error) { res, err := codec.MarshalJSONIndent(types.ModuleCdc, pool) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func queryParameters(ctx sdk.Context, k Keeper) ([]byte, sdk.Error) { +func queryParameters(ctx sdk.Context, k Keeper) ([]byte, error) { params := k.GetParams(ctx) res, err := codec.MarshalJSONIndent(types.ModuleCdc, params) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil @@ -385,10 +401,10 @@ func queryParameters(ctx sdk.Context, k Keeper) ([]byte, sdk.Error) { //______________________________________________________ // util -func delegationToDelegationResponse(ctx sdk.Context, k Keeper, del types.Delegation) (types.DelegationResponse, sdk.Error) { +func delegationToDelegationResponse(ctx sdk.Context, k Keeper, del types.Delegation) (types.DelegationResponse, error) { val, found := k.GetValidator(ctx, del.ValidatorAddress) if !found { - return types.DelegationResponse{}, types.ErrNoValidatorFound(types.DefaultCodespace) + return types.DelegationResponse{}, types.ErrNoValidatorFound } return types.NewDelegationResp( @@ -401,7 +417,7 @@ func delegationToDelegationResponse(ctx sdk.Context, k Keeper, del types.Delegat func delegationsToDelegationResponses( ctx sdk.Context, k Keeper, delegations types.Delegations, -) (types.DelegationResponses, sdk.Error) { +) (types.DelegationResponses, error) { resp := make(types.DelegationResponses, len(delegations)) for i, del := range delegations { @@ -418,13 +434,13 @@ func delegationsToDelegationResponses( func redelegationsToRedelegationResponses( ctx sdk.Context, k Keeper, redels types.Redelegations, -) (types.RedelegationResponses, sdk.Error) { +) (types.RedelegationResponses, error) { resp := make(types.RedelegationResponses, len(redels)) for i, redel := range redels { val, found := k.GetValidator(ctx, redel.ValidatorDstAddress) if !found { - return nil, types.ErrNoValidatorFound(types.DefaultCodespace) + return nil, types.ErrNoValidatorFound } entryResponses := make([]types.RedelegationEntryResponse, len(redel.Entries)) diff --git a/x/staking/keeper/query_utils.go b/x/staking/keeper/query_utils.go index 6bde68f5df6e..336bb842ab9e 100644 --- a/x/staking/keeper/query_utils.go +++ b/x/staking/keeper/query_utils.go @@ -21,7 +21,7 @@ func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAdd validator, found := k.GetValidator(ctx, delegation.ValidatorAddress) if !found { - panic(types.ErrNoValidatorFound(types.DefaultCodespace)) + panic(types.ErrNoValidatorFound) } validators[i] = validator i++ @@ -31,16 +31,16 @@ func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAdd // return a validator that a delegator is bonded to func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddress, - validatorAddr sdk.ValAddress) (validator types.Validator, err sdk.Error) { + validatorAddr sdk.ValAddress) (validator types.Validator, err error) { delegation, found := k.GetDelegation(ctx, delegatorAddr, validatorAddr) if !found { - return validator, types.ErrNoDelegation(types.DefaultCodespace) + return validator, types.ErrNoDelegation } validator, found = k.GetValidator(ctx, delegation.ValidatorAddress) if !found { - panic(types.ErrNoValidatorFound(types.DefaultCodespace)) + panic(types.ErrNoValidatorFound) } return } diff --git a/x/staking/keeper/test_common.go b/x/staking/keeper/test_common.go index 51d7f71ae9d6..0d730b48b3ca 100644 --- a/x/staking/keeper/test_common.go +++ b/x/staking/keeper/test_common.go @@ -115,7 +115,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context blacklistedAddrs[notBondedPool.GetAddress().String()] = true blacklistedAddrs[bondPool.GetAddress().String()] = true - pk := params.NewKeeper(cdc, keyParams, tkeyParams, params.DefaultCodespace) + pk := params.NewKeeper(cdc, keyParams, tkeyParams) accountKeeper := auth.NewAccountKeeper( cdc, // amino codec @@ -127,7 +127,6 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context bk := bank.NewBaseKeeper( accountKeeper, pk.Subspace(bank.DefaultParamspace), - bank.DefaultCodespace, blacklistedAddrs, ) @@ -144,7 +143,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) - keeper := NewKeeper(cdc, keyStaking, supplyKeeper, pk.Subspace(DefaultParamspace), types.DefaultCodespace) + keeper := NewKeeper(cdc, keyStaking, supplyKeeper, pk.Subspace(DefaultParamspace)) keeper.SetParams(ctx, types.DefaultParams()) // set module accounts diff --git a/x/staking/keeper/validator.go b/x/staking/keeper/validator.go index cd5e912ca92a..48ecbb384313 100644 --- a/x/staking/keeper/validator.go +++ b/x/staking/keeper/validator.go @@ -156,7 +156,7 @@ func (k Keeper) RemoveValidatorTokens(ctx sdk.Context, // UpdateValidatorCommission attempts to update a validator's commission rate. // An error is returned if the new commission rate is invalid. func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, - validator types.Validator, newRate sdk.Dec) (types.Commission, sdk.Error) { + validator types.Validator, newRate sdk.Dec) (types.Commission, error) { commission := validator.Commission blockTime := ctx.BlockHeader().Time diff --git a/x/staking/simulation/operations.go b/x/staking/simulation/operations.go index 8ddea88aa7c6..b1a932270641 100644 --- a/x/staking/simulation/operations.go +++ b/x/staking/simulation/operations.go @@ -1,7 +1,6 @@ package simulation import ( - "errors" "fmt" "math/rand" @@ -161,9 +160,9 @@ func SimulateMsgCreateValidator(ak types.AccountKeeper, k keeper.Keeper) simulat simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil @@ -226,9 +225,9 @@ func SimulateMsgEditValidator(ak types.AccountKeeper, k keeper.Keeper) simulatio simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil @@ -293,9 +292,9 @@ func SimulateMsgDelegate(ak types.AccountKeeper, k keeper.Keeper) simulation.Ope simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil @@ -373,9 +372,9 @@ func SimulateMsgUndelegate(ak types.AccountKeeper, k keeper.Keeper) simulation.O simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil @@ -479,9 +478,9 @@ func SimulateMsgBeginRedelegate(ak types.AccountKeeper, k keeper.Keeper) simulat simAccount.PrivKey, ) - res := app.Deliver(tx) - if !res.IsOK() { - return simulation.NoOpMsg(types.ModuleName), nil, errors.New(res.Log) + _, _, err = app.Deliver(tx) + if err != nil { + return simulation.NoOpMsg(types.ModuleName), nil, err } return simulation.NewOperationMsg(msg, true, ""), nil, nil diff --git a/x/staking/types/commission.go b/x/staking/types/commission.go index f447c452822f..38ab8e06a703 100644 --- a/x/staking/types/commission.go +++ b/x/staking/types/commission.go @@ -67,31 +67,31 @@ func (c Commission) String() string { // Validate performs basic sanity validation checks of initial commission // parameters. If validation fails, an SDK error is returned. -func (c CommissionRates) Validate() sdk.Error { +func (c CommissionRates) Validate() error { switch { case c.MaxRate.IsNegative(): // max rate cannot be negative - return ErrCommissionNegative(DefaultCodespace) + return ErrCommissionNegative case c.MaxRate.GT(sdk.OneDec()): // max rate cannot be greater than 1 - return ErrCommissionHuge(DefaultCodespace) + return ErrCommissionHuge case c.Rate.IsNegative(): // rate cannot be negative - return ErrCommissionNegative(DefaultCodespace) + return ErrCommissionNegative case c.Rate.GT(c.MaxRate): // rate cannot be greater than the max rate - return ErrCommissionGTMaxRate(DefaultCodespace) + return ErrCommissionGTMaxRate case c.MaxChangeRate.IsNegative(): // change rate cannot be negative - return ErrCommissionChangeRateNegative(DefaultCodespace) + return ErrCommissionChangeRateNegative case c.MaxChangeRate.GT(c.MaxRate): // change rate cannot be greater than the max rate - return ErrCommissionChangeRateGTMaxRate(DefaultCodespace) + return ErrCommissionChangeRateGTMaxRate } return nil @@ -99,23 +99,23 @@ func (c CommissionRates) Validate() sdk.Error { // ValidateNewRate performs basic sanity validation checks of a new commission // rate. If validation fails, an SDK error is returned. -func (c Commission) ValidateNewRate(newRate sdk.Dec, blockTime time.Time) sdk.Error { +func (c Commission) ValidateNewRate(newRate sdk.Dec, blockTime time.Time) error { switch { case blockTime.Sub(c.UpdateTime).Hours() < 24: // new rate cannot be changed more than once within 24 hours - return ErrCommissionUpdateTime(DefaultCodespace) + return ErrCommissionUpdateTime case newRate.IsNegative(): // new rate cannot be negative - return ErrCommissionNegative(DefaultCodespace) + return ErrCommissionNegative case newRate.GT(c.MaxRate): // new rate cannot be greater than the max rate - return ErrCommissionGTMaxRate(DefaultCodespace) + return ErrCommissionGTMaxRate case newRate.Sub(c.Rate).GT(c.MaxChangeRate): // new rate % points change cannot be greater than the max change rate - return ErrCommissionGTMaxChangeRate(DefaultCodespace) + return ErrCommissionGTMaxChangeRate } return nil diff --git a/x/staking/types/errors.go b/x/staking/types/errors.go index 523e720e2d98..d3ccf0a9dac2 100644 --- a/x/staking/types/errors.go +++ b/x/staking/types/errors.go @@ -1,223 +1,59 @@ -// nolint package types import ( - "fmt" - "strings" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -type CodeType = sdk.CodeType - -const ( - DefaultCodespace sdk.CodespaceType = ModuleName - - CodeInvalidValidator CodeType = 101 - CodeInvalidDelegation CodeType = 102 - CodeInvalidInput CodeType = 103 - CodeValidatorJailed CodeType = 104 - CodeInvalidHistoricalInfo CodeType = 105 - CodeInvalidAddress CodeType = sdk.CodeInvalidAddress - CodeUnauthorized CodeType = sdk.CodeUnauthorized - CodeInternal CodeType = sdk.CodeInternal - CodeUnknownRequest CodeType = sdk.CodeUnknownRequest +// x/staking module sentinel errors +// +// TODO: Many of these errors are redundant. They should be removed and replaced +// by sdkerrors.ErrInvalidRequest. +// +// REF: https://github.com/cosmos/cosmos-sdk/issues/5450 +var ( + ErrEmptyValidatorAddr = sdkerrors.Register(ModuleName, 1, "empty validator address") + ErrBadValidatorAddr = sdkerrors.Register(ModuleName, 2, "validator address is invalid") + ErrNoValidatorFound = sdkerrors.Register(ModuleName, 3, "validator does not exist") + ErrValidatorOwnerExists = sdkerrors.Register(ModuleName, 4, "validator already exist for this operator address; must use new validator operator address") + ErrValidatorPubKeyExists = sdkerrors.Register(ModuleName, 5, "validator already exist for this pubkey; must use new validator pubkey") + ErrValidatorPubKeyTypeNotSupported = sdkerrors.Register(ModuleName, 6, "validator pubkey type is not supported") + ErrValidatorJailed = sdkerrors.Register(ModuleName, 7, "validator for this address is currently jailed") + ErrBadRemoveValidator = sdkerrors.Register(ModuleName, 8, "failed to remove validator") + ErrCommissionNegative = sdkerrors.Register(ModuleName, 9, "commission must be positive") + ErrCommissionHuge = sdkerrors.Register(ModuleName, 10, "commission cannot be more than 100%") + ErrCommissionGTMaxRate = sdkerrors.Register(ModuleName, 11, "commission cannot be more than the max rate") + ErrCommissionUpdateTime = sdkerrors.Register(ModuleName, 12, "commission cannot be changed more than once in 24h") + ErrCommissionChangeRateNegative = sdkerrors.Register(ModuleName, 13, "commission change rate must be positive") + ErrCommissionChangeRateGTMaxRate = sdkerrors.Register(ModuleName, 14, "commission change rate cannot be more than the max rate") + ErrCommissionGTMaxChangeRate = sdkerrors.Register(ModuleName, 15, "commission cannot be changed more than max change rate") + ErrSelfDelegationBelowMinimum = sdkerrors.Register(ModuleName, 16, "validator's self delegation must be greater than their minimum self delegation") + ErrMinSelfDelegationInvalid = sdkerrors.Register(ModuleName, 17, "minimum self delegation must be a positive integer") + ErrMinSelfDelegationDecreased = sdkerrors.Register(ModuleName, 18, "minimum self delegation cannot be decrease") + ErrEmptyDelegatorAddr = sdkerrors.Register(ModuleName, 19, "empty delegator address") + ErrBadDenom = sdkerrors.Register(ModuleName, 20, "invalid coin denomination") + ErrBadDelegationAddr = sdkerrors.Register(ModuleName, 21, "invalid address for (address, validator) tuple") + ErrBadDelegationAmount = sdkerrors.Register(ModuleName, 22, "invalid delegation amount") + ErrNoDelegation = sdkerrors.Register(ModuleName, 23, "no delegation for (address, validator) tuple") + ErrBadDelegatorAddr = sdkerrors.Register(ModuleName, 24, "delegator does not exist with address") + ErrNoDelegatorForAddress = sdkerrors.Register(ModuleName, 25, "delegator does not contain delegation") + ErrInsufficientShares = sdkerrors.Register(ModuleName, 26, "insufficient delegation shares") + ErrDelegationValidatorEmpty = sdkerrors.Register(ModuleName, 27, "cannot delegate to an empty validator") + ErrNotEnoughDelegationShares = sdkerrors.Register(ModuleName, 28, "not enough delegation shares") + ErrBadSharesAmount = sdkerrors.Register(ModuleName, 29, "invalid shares amount") + ErrBadSharesPercent = sdkerrors.Register(ModuleName, 30, "Invalid shares percent") + ErrNotMature = sdkerrors.Register(ModuleName, 31, "entry not mature") + ErrNoUnbondingDelegation = sdkerrors.Register(ModuleName, 32, "no unbonding delegation found") + ErrMaxUnbondingDelegationEntries = sdkerrors.Register(ModuleName, 33, "too many unbonding delegation entries for (delegator, validator) tuple") + ErrBadRedelegationAddr = sdkerrors.Register(ModuleName, 34, "invalid address for (address, src-validator, dst-validator) tuple") + ErrNoRedelegation = sdkerrors.Register(ModuleName, 35, "no redelegation found") + ErrSelfRedelegation = sdkerrors.Register(ModuleName, 36, "cannot redelegate to the same validator") + ErrTinyRedelegationAmount = sdkerrors.Register(ModuleName, 37, "too few tokens to redelegate (truncates to zero tokens)") + ErrBadRedelegationDst = sdkerrors.Register(ModuleName, 38, "redelegation destination validator not found") + ErrTransitiveRedelegation = sdkerrors.Register(ModuleName, 39, "redelegation to this validator already in progress; first redelegation to this validator must complete before next redelegation") + ErrMaxRedelegationEntries = sdkerrors.Register(ModuleName, 40, "too many redelegation entries for (delegator, src-validator, dst-validator) tuple") + ErrDelegatorShareExRateInvalid = sdkerrors.Register(ModuleName, 41, "cannot delegate to validators with invalid (zero) ex-rate") + ErrBothShareMsgsGiven = sdkerrors.Register(ModuleName, 42, "both shares amount and shares percent provided") + ErrNeitherShareMsgsGiven = sdkerrors.Register(ModuleName, 43, "neither shares amount nor shares percent provided") + ErrInvalidHistoricalInfo = sdkerrors.Register(ModuleName, 44, "invalid historical info") + ErrNoHistoricalInfo = sdkerrors.Register(ModuleName, 45, "no historical info found") ) - -//validator -func ErrNilValidatorAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "validator address is nil") -} - -func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidAddress, "validator address is invalid") -} - -func ErrNoValidatorFound(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "validator does not exist for that address") -} - -func ErrValidatorOwnerExists(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "validator already exist for this operator address, must use new validator operator address") -} - -func ErrValidatorPubKeyExists(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "validator already exist for this pubkey, must use new validator pubkey") -} - -func ErrValidatorPubKeyTypeNotSupported(codespace sdk.CodespaceType, keyType string, supportedTypes []string) sdk.Error { - msg := fmt.Sprintf("validator pubkey type %s is not supported, must use %s", keyType, strings.Join(supportedTypes, ",")) - return sdk.NewError(codespace, CodeInvalidValidator, msg) -} - -func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "validator for this address is currently jailed") -} - -func ErrBadRemoveValidator(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "error removing validator") -} - -func ErrDescriptionLength(codespace sdk.CodespaceType, descriptor string, got, max int) sdk.Error { - msg := fmt.Sprintf("bad description length for %v, got length %v, max is %v", descriptor, got, max) - return sdk.NewError(codespace, CodeInvalidValidator, msg) -} - -func ErrCommissionNegative(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "commission must be positive") -} - -func ErrCommissionHuge(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "commission cannot be more than 100%") -} - -func ErrCommissionGTMaxRate(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "commission cannot be more than the max rate") -} - -func ErrCommissionUpdateTime(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "commission cannot be changed more than once in 24h") -} - -func ErrCommissionChangeRateNegative(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "commission change rate must be positive") -} - -func ErrCommissionChangeRateGTMaxRate(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "commission change rate cannot be more than the max rate") -} - -func ErrCommissionGTMaxChangeRate(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "commission cannot be changed more than max change rate") -} - -func ErrSelfDelegationBelowMinimum(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "validator's self delegation must be greater than their minimum self delegation") -} - -func ErrMinSelfDelegationInvalid(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "minimum self delegation must be a positive integer") -} - -func ErrMinSelfDelegationDecreased(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "minimum self delegation cannot be decrease") -} - -func ErrNilDelegatorAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "delegator address is nil") -} - -func ErrBadDenom(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "invalid coin denomination") -} - -func ErrBadDelegationAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "unexpected address length for this (address, validator) pair") -} - -func ErrBadDelegationAmount(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "amount must be > 0") -} - -func ErrNoDelegation(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "no delegation for this (address, validator) pair") -} - -func ErrBadDelegatorAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "delegator does not exist for that address") -} - -func ErrNoDelegatorForAddress(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "delegator does not contain this delegation") -} - -func ErrInsufficientShares(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "insufficient delegation shares") -} - -func ErrDelegationValidatorEmpty(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "cannot delegate to an empty validator") -} - -func ErrNotEnoughDelegationShares(codespace sdk.CodespaceType, shares string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, fmt.Sprintf("not enough shares only have %v", shares)) -} - -func ErrBadSharesAmount(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "shares must be > 0") -} - -func ErrBadSharesPercent(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "shares percent must be >0 and <=1") -} - -func ErrNotMature(codespace sdk.CodespaceType, operation, descriptor string, got, min time.Time) sdk.Error { - msg := fmt.Sprintf("%v is not mature requires a min %v of %v, currently it is %v", - operation, descriptor, got, min) - return sdk.NewError(codespace, CodeUnauthorized, msg) -} - -func ErrNoUnbondingDelegation(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "no unbonding delegation found") -} - -func ErrMaxUnbondingDelegationEntries(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, - "too many unbonding delegation entries in this delegator/validator duo, please wait for some entries to mature") -} - -func ErrBadRedelegationAddr(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "unexpected address length for this (address, srcValidator, dstValidator) tuple") -} - -func ErrNoRedelegation(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "no redelegation found") -} - -func ErrSelfRedelegation(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "cannot redelegate to the same validator") -} - -func ErrVerySmallRedelegation(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "too few tokens to redelegate, truncates to zero tokens") -} - -func ErrBadRedelegationDst(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, "redelegation validator not found") -} - -func ErrTransitiveRedelegation(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, - "redelegation to this validator already in progress, first redelegation to this validator must complete before next redelegation") -} - -func ErrMaxRedelegationEntries(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, - "too many redelegation entries in this delegator/src-validator/dst-validator trio, please wait for some entries to mature") -} - -func ErrDelegatorShareExRateInvalid(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidDelegation, - "cannot delegate to validators with invalid (zero) ex-rate") -} - -func ErrBothShareMsgsGiven(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "both shares amount and shares percent provided") -} - -func ErrNeitherShareMsgsGiven(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidInput, "neither shares amount nor shares percent provided") -} - -func ErrMissingSignature(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "missing signature") -} - -func ErrInvalidHistoricalInfo(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidHistoricalInfo, "invalid historical info") -} - -func ErrNoHistoricalInfo(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidHistoricalInfo, "no historical info found") -} diff --git a/x/staking/types/expected_keepers.go b/x/staking/types/expected_keepers.go index 8f346a71c4cb..5e98f0abbed0 100644 --- a/x/staking/types/expected_keepers.go +++ b/x/staking/types/expected_keepers.go @@ -29,11 +29,11 @@ type SupplyKeeper interface { // TODO remove with genesis 2-phases refactor https://github.com/cosmos/cosmos-sdk/issues/2862 SetModuleAccount(sdk.Context, supplyexported.ModuleAccountI) - SendCoinsFromModuleToModule(ctx sdk.Context, senderPool, recipientPool string, amt sdk.Coins) sdk.Error - UndelegateCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error - DelegateCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error + SendCoinsFromModuleToModule(ctx sdk.Context, senderPool, recipientPool string, amt sdk.Coins) error + UndelegateCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + DelegateCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error - BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) sdk.Error + BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error } // ValidatorSet expected properties for the set of all validators (noalias) diff --git a/x/staking/types/historical_info.go b/x/staking/types/historical_info.go index 8fae88f07f4e..78db1e7dd4a9 100644 --- a/x/staking/types/historical_info.go +++ b/x/staking/types/historical_info.go @@ -48,10 +48,10 @@ func UnmarshalHistoricalInfo(cdc *codec.Codec, value []byte) (hi HistoricalInfo, // ValidateBasic will ensure HistoricalInfo is not nil and sorted func ValidateBasic(hi HistoricalInfo) error { if len(hi.ValSet) == 0 { - return sdkerrors.Wrap(ErrInvalidHistoricalInfo(DefaultCodespace), "ValidatorSer is nil") + return sdkerrors.Wrap(ErrInvalidHistoricalInfo, "validator set is empty") } if !sort.IsSorted(Validators(hi.ValSet)) { - return sdkerrors.Wrap(ErrInvalidHistoricalInfo(DefaultCodespace), "ValidatorSet is not sorted by address") + return sdkerrors.Wrap(ErrInvalidHistoricalInfo, "validator set is not sorted by address") } return nil } diff --git a/x/staking/types/msg.go b/x/staking/types/msg.go index fa44090ac747..8b47cfec443c 100644 --- a/x/staking/types/msg.go +++ b/x/staking/types/msg.go @@ -8,6 +8,7 @@ import ( yaml "gopkg.in/yaml.v2" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // ensure Msg interface compliance at compile time @@ -151,34 +152,34 @@ func (msg MsgCreateValidator) GetSignBytes() []byte { } // ValidateBasic implements the sdk.Msg interface. -func (msg MsgCreateValidator) ValidateBasic() sdk.Error { +func (msg MsgCreateValidator) ValidateBasic() error { // note that unmarshaling from bech32 ensures either empty or valid if msg.DelegatorAddress.Empty() { - return ErrNilDelegatorAddr(DefaultCodespace) + return ErrEmptyDelegatorAddr } if msg.ValidatorAddress.Empty() { - return ErrNilValidatorAddr(DefaultCodespace) + return ErrEmptyValidatorAddr } if !sdk.AccAddress(msg.ValidatorAddress).Equals(msg.DelegatorAddress) { - return ErrBadValidatorAddr(DefaultCodespace) + return ErrBadValidatorAddr } if !msg.Value.Amount.IsPositive() { - return ErrBadDelegationAmount(DefaultCodespace) + return ErrBadDelegationAmount } if msg.Description == (Description{}) { - return sdk.NewError(DefaultCodespace, CodeInvalidInput, "description must be included") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description") } if msg.Commission == (CommissionRates{}) { - return sdk.NewError(DefaultCodespace, CodeInvalidInput, "commission must be included") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty commission") } if err := msg.Commission.Validate(); err != nil { return err } if !msg.MinSelfDelegation.IsPositive() { - return ErrMinSelfDelegationInvalid(DefaultCodespace) + return ErrMinSelfDelegationInvalid } if msg.Value.Amount.LT(msg.MinSelfDelegation) { - return ErrSelfDelegationBelowMinimum(DefaultCodespace) + return ErrSelfDelegationBelowMinimum } return nil @@ -226,22 +227,19 @@ func (msg MsgEditValidator) GetSignBytes() []byte { } // ValidateBasic implements the sdk.Msg interface. -func (msg MsgEditValidator) ValidateBasic() sdk.Error { +func (msg MsgEditValidator) ValidateBasic() error { if msg.ValidatorAddress.Empty() { - return sdk.NewError(DefaultCodespace, CodeInvalidInput, "nil validator address") + return ErrEmptyValidatorAddr } - if msg.Description == (Description{}) { - return sdk.NewError(DefaultCodespace, CodeInvalidInput, "transaction must include some information to modify") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description") } - if msg.MinSelfDelegation != nil && !msg.MinSelfDelegation.IsPositive() { - return ErrMinSelfDelegationInvalid(DefaultCodespace) + return ErrMinSelfDelegationInvalid } - if msg.CommissionRate != nil { if msg.CommissionRate.GT(sdk.OneDec()) || msg.CommissionRate.IsNegative() { - return sdk.NewError(DefaultCodespace, CodeInvalidInput, "commission rate must be between 0 and 1, inclusive") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "commission rate must be between 0 and 1 (inclusive)") } } @@ -282,15 +280,15 @@ func (msg MsgDelegate) GetSignBytes() []byte { } // ValidateBasic implements the sdk.Msg interface. -func (msg MsgDelegate) ValidateBasic() sdk.Error { +func (msg MsgDelegate) ValidateBasic() error { if msg.DelegatorAddress.Empty() { - return ErrNilDelegatorAddr(DefaultCodespace) + return ErrEmptyDelegatorAddr } if msg.ValidatorAddress.Empty() { - return ErrNilValidatorAddr(DefaultCodespace) + return ErrEmptyValidatorAddr } if !msg.Amount.Amount.IsPositive() { - return ErrBadDelegationAmount(DefaultCodespace) + return ErrBadDelegationAmount } return nil } @@ -335,18 +333,18 @@ func (msg MsgBeginRedelegate) GetSignBytes() []byte { } // ValidateBasic implements the sdk.Msg interface. -func (msg MsgBeginRedelegate) ValidateBasic() sdk.Error { +func (msg MsgBeginRedelegate) ValidateBasic() error { if msg.DelegatorAddress.Empty() { - return ErrNilDelegatorAddr(DefaultCodespace) + return ErrEmptyDelegatorAddr } if msg.ValidatorSrcAddress.Empty() { - return ErrNilValidatorAddr(DefaultCodespace) + return ErrEmptyValidatorAddr } if msg.ValidatorDstAddress.Empty() { - return ErrNilValidatorAddr(DefaultCodespace) + return ErrEmptyValidatorAddr } if !msg.Amount.Amount.IsPositive() { - return ErrBadSharesAmount(DefaultCodespace) + return ErrBadSharesAmount } return nil } @@ -383,15 +381,15 @@ func (msg MsgUndelegate) GetSignBytes() []byte { } // ValidateBasic implements the sdk.Msg interface. -func (msg MsgUndelegate) ValidateBasic() sdk.Error { +func (msg MsgUndelegate) ValidateBasic() error { if msg.DelegatorAddress.Empty() { - return ErrNilDelegatorAddr(DefaultCodespace) + return ErrEmptyDelegatorAddr } if msg.ValidatorAddress.Empty() { - return ErrNilValidatorAddr(DefaultCodespace) + return ErrEmptyValidatorAddr } if !msg.Amount.Amount.IsPositive() { - return ErrBadSharesAmount(DefaultCodespace) + return ErrBadSharesAmount } return nil } diff --git a/x/staking/types/validator.go b/x/staking/types/validator.go index 37e6cbc02575..2ac2903dcf0b 100644 --- a/x/staking/types/validator.go +++ b/x/staking/types/validator.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/staking/exported" ) @@ -304,7 +305,7 @@ func NewDescription(moniker, identity, website, securityContact, details string) // UpdateDescription updates the fields of a given description. An error is // returned if the resulting description contains an invalid length. -func (d Description) UpdateDescription(d2 Description) (Description, sdk.Error) { +func (d Description) UpdateDescription(d2 Description) (Description, error) { if d2.Moniker == DoNotModifyDesc { d2.Moniker = d.Moniker } @@ -331,21 +332,21 @@ func (d Description) UpdateDescription(d2 Description) (Description, sdk.Error) } // EnsureLength ensures the length of a validator's description. -func (d Description) EnsureLength() (Description, sdk.Error) { +func (d Description) EnsureLength() (Description, error) { if len(d.Moniker) > MaxMonikerLength { - return d, ErrDescriptionLength(DefaultCodespace, "moniker", len(d.Moniker), MaxMonikerLength) + return d, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid moniker length; got: %d, max: %d", len(d.Moniker), MaxMonikerLength) } if len(d.Identity) > MaxIdentityLength { - return d, ErrDescriptionLength(DefaultCodespace, "identity", len(d.Identity), MaxIdentityLength) + return d, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid identity length; got: %d, max: %d", len(d.Identity), MaxIdentityLength) } if len(d.Website) > MaxWebsiteLength { - return d, ErrDescriptionLength(DefaultCodespace, "website", len(d.Website), MaxWebsiteLength) + return d, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid website length; got: %d, max: %d", len(d.Website), MaxWebsiteLength) } if len(d.SecurityContact) > MaxSecurityContactLength { - return d, ErrDescriptionLength(DefaultCodespace, "security contact", len(d.SecurityContact), MaxSecurityContactLength) + return d, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid security contact length; got: %d, max: %d", len(d.SecurityContact), MaxSecurityContactLength) } if len(d.Details) > MaxDetailsLength { - return d, ErrDescriptionLength(DefaultCodespace, "details", len(d.Details), MaxDetailsLength) + return d, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid details length; got: %d, max: %d", len(d.Details), MaxDetailsLength) } return d, nil @@ -371,7 +372,7 @@ func (v Validator) ABCIValidatorUpdateZero() abci.ValidatorUpdate { // SetInitialCommission attempts to set a validator's initial commission. An // error is returned if the commission is invalid. -func (v Validator) SetInitialCommission(commission Commission) (Validator, sdk.Error) { +func (v Validator) SetInitialCommission(commission Commission) (Validator, error) { if err := commission.Validate(); err != nil { return v, err } @@ -405,9 +406,9 @@ func (v Validator) TokensFromSharesRoundUp(shares sdk.Dec) sdk.Dec { // SharesFromTokens returns the shares of a delegation given a bond amount. It // returns an error if the validator has no tokens. -func (v Validator) SharesFromTokens(amt sdk.Int) (sdk.Dec, sdk.Error) { +func (v Validator) SharesFromTokens(amt sdk.Int) (sdk.Dec, error) { if v.Tokens.IsZero() { - return sdk.ZeroDec(), ErrInsufficientShares(DefaultCodespace) + return sdk.ZeroDec(), ErrInsufficientShares } return v.GetDelegatorShares().MulInt(amt).QuoInt(v.GetTokens()), nil @@ -415,9 +416,9 @@ func (v Validator) SharesFromTokens(amt sdk.Int) (sdk.Dec, sdk.Error) { // SharesFromTokensTruncated returns the truncated shares of a delegation given // a bond amount. It returns an error if the validator has no tokens. -func (v Validator) SharesFromTokensTruncated(amt sdk.Int) (sdk.Dec, sdk.Error) { +func (v Validator) SharesFromTokensTruncated(amt sdk.Int) (sdk.Dec, error) { if v.Tokens.IsZero() { - return sdk.ZeroDec(), ErrInsufficientShares(DefaultCodespace) + return sdk.ZeroDec(), ErrInsufficientShares } return v.GetDelegatorShares().MulInt(amt).QuoTruncate(v.GetTokens().ToDec()), nil diff --git a/x/supply/alias.go b/x/supply/alias.go index 9bc7f5f13530..1138f7c5eee2 100644 --- a/x/supply/alias.go +++ b/x/supply/alias.go @@ -38,8 +38,7 @@ var ( DefaultSupply = types.DefaultSupply // variable aliases - DefaultCodespace = keeper.DefaultCodespace - ModuleCdc = types.ModuleCdc + ModuleCdc = types.ModuleCdc ) type ( diff --git a/x/supply/client/cli/query.go b/x/supply/client/cli/query.go index 009f2f7df983..26c4a77cd506 100644 --- a/x/supply/client/cli/query.go +++ b/x/supply/client/cli/query.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -25,7 +26,7 @@ func GetQueryCmd(cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - supplyQueryCmd.AddCommand(client.GetCommands( + supplyQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryTotalSupply(cdc), )...) diff --git a/x/supply/internal/keeper/bank.go b/x/supply/internal/keeper/bank.go index 60efbc4c3df5..9117286aaeb6 100644 --- a/x/supply/internal/keeper/bank.go +++ b/x/supply/internal/keeper/bank.go @@ -4,103 +4,110 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/supply/internal/types" ) -// SendCoinsFromModuleToAccount transfers coins from a ModuleAccount to an AccAddress -func (k Keeper) SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, - recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error { +// SendCoinsFromModuleToAccount transfers coins from a ModuleAccount to an AccAddress. +// It will panic if the module account does not exist. +func (k Keeper) SendCoinsFromModuleToAccount( + ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins, +) error { senderAddr := k.GetModuleAddress(senderModule) if senderAddr == nil { - return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", senderModule)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", senderModule)) } return k.bk.SendCoins(ctx, senderAddr, recipientAddr, amt) } -// SendCoinsFromModuleToModule transfers coins from a ModuleAccount to another -func (k Keeper) SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) sdk.Error { +// SendCoinsFromModuleToModule transfers coins from a ModuleAccount to another. +// It will panic if either module account does not exist. +func (k Keeper) SendCoinsFromModuleToModule( + ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins, +) error { senderAddr := k.GetModuleAddress(senderModule) if senderAddr == nil { - return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", senderModule)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", senderModule)) } - // create the account if it doesn't yet exist recipientAcc := k.GetModuleAccount(ctx, recipientModule) if recipientAcc == nil { - panic(fmt.Sprintf("module account %s isn't able to be created", recipientModule)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", recipientModule)) } return k.bk.SendCoins(ctx, senderAddr, recipientAcc.GetAddress(), amt) } -// SendCoinsFromAccountToModule transfers coins from an AccAddress to a ModuleAccount -func (k Keeper) SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, - recipientModule string, amt sdk.Coins) sdk.Error { +// SendCoinsFromAccountToModule transfers coins from an AccAddress to a ModuleAccount. +// It will panic if the module account does not exist. +func (k Keeper) SendCoinsFromAccountToModule( + ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins, +) error { - // create the account if it doesn't yet exist recipientAcc := k.GetModuleAccount(ctx, recipientModule) if recipientAcc == nil { - panic(fmt.Sprintf("module account %s isn't able to be created", recipientModule)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", recipientModule)) } return k.bk.SendCoins(ctx, senderAddr, recipientAcc.GetAddress(), amt) } -// DelegateCoinsFromAccountToModule delegates coins and transfers -// them from a delegator account to a module account -func (k Keeper) DelegateCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, - recipientModule string, amt sdk.Coins) sdk.Error { +// DelegateCoinsFromAccountToModule delegates coins and transfers them from a +// delegator account to a module account. It will panic if the module account +// does not exist or is unauthorized. +func (k Keeper) DelegateCoinsFromAccountToModule( + ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins, +) error { - // create the account if it doesn't yet exist recipientAcc := k.GetModuleAccount(ctx, recipientModule) if recipientAcc == nil { - panic(fmt.Sprintf("module account %s isn't able to be created", recipientModule)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", recipientModule)) } if !recipientAcc.HasPermission(types.Staking) { - panic(fmt.Sprintf("module account %s does not have permissions to receive delegated coins", recipientModule)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "module account %s does not have permissions to receive delegated coins", recipientModule)) } return k.bk.DelegateCoins(ctx, senderAddr, recipientAcc.GetAddress(), amt) } // UndelegateCoinsFromModuleToAccount undelegates the unbonding coins and transfers -// them from a module account to the delegator account -func (k Keeper) UndelegateCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, - recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error { +// them from a module account to the delegator account. It will panic if the +// module account does not exist or is unauthorized. +func (k Keeper) UndelegateCoinsFromModuleToAccount( + ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins, +) error { acc := k.GetModuleAccount(ctx, senderModule) if acc == nil { - return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", senderModule)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", senderModule)) } if !acc.HasPermission(types.Staking) { - panic(fmt.Sprintf("module account %s does not have permissions to undelegate coins", senderModule)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "module account %s does not have permissions to undelegate coins", senderModule)) } return k.bk.UndelegateCoins(ctx, acc.GetAddress(), recipientAddr, amt) } // MintCoins creates new coins from thin air and adds it to the module account. -// Panics if the name maps to a non-minter module account or if the amount is invalid. -func (k Keeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error { - - // create the account if it doesn't yet exist +// It will panic if the module account does not exist or is unauthorized. +func (k Keeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error { acc := k.GetModuleAccount(ctx, moduleName) if acc == nil { - return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", moduleName)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", moduleName)) } if !acc.HasPermission(types.Minter) { - panic(fmt.Sprintf("module account %s does not have permissions to mint tokens", moduleName)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "module account %s does not have permissions to mint tokens", moduleName)) } _, err := k.bk.AddCoins(ctx, acc.GetAddress(), amt) if err != nil { - panic(err) + return err } // update total supply @@ -116,22 +123,20 @@ func (k Keeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk } // BurnCoins burns coins deletes coins from the balance of the module account. -// Panics if the name maps to a non-burner module account or if the amount is invalid. -func (k Keeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error { - - // create the account if it doesn't yet exist +// It will panic if the module account does not exist or is unauthorized. +func (k Keeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error { acc := k.GetModuleAccount(ctx, moduleName) if acc == nil { - return sdk.ErrUnknownAddress(fmt.Sprintf("module account %s does not exist", moduleName)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", moduleName)) } if !acc.HasPermission(types.Burner) { - panic(fmt.Sprintf("module account %s does not have permissions to burn tokens", moduleName)) + panic(sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "module account %s does not have permissions to burn tokens", moduleName)) } _, err := k.bk.SubtractCoins(ctx, acc.GetAddress(), amt) if err != nil { - panic(err) + return err } // update total supply diff --git a/x/supply/internal/keeper/bank_test.go b/x/supply/internal/keeper/bank_test.go index f0cb48f1fc1f..bdd0a9430a1d 100644 --- a/x/supply/internal/keeper/bank_test.go +++ b/x/supply/internal/keeper/bank_test.go @@ -48,15 +48,17 @@ func TestSendCoins(t *testing.T) { keeper.SetModuleAccount(ctx, burnerAcc) ak.SetAccount(ctx, baseAcc) - err = keeper.SendCoinsFromModuleToModule(ctx, "", holderAcc.GetName(), initCoins) - require.Error(t, err) + require.Panics(t, func() { + keeper.SendCoinsFromModuleToModule(ctx, "", holderAcc.GetName(), initCoins) + }) require.Panics(t, func() { keeper.SendCoinsFromModuleToModule(ctx, types.Burner, "", initCoins) }) - err = keeper.SendCoinsFromModuleToAccount(ctx, "", baseAcc.GetAddress(), initCoins) - require.Error(t, err) + require.Panics(t, func() { + keeper.SendCoinsFromModuleToAccount(ctx, "", baseAcc.GetAddress(), initCoins) + }) err = keeper.SendCoinsFromModuleToAccount(ctx, holderAcc.GetName(), baseAcc.GetAddress(), initCoins.Add(initCoins)) require.Error(t, err) @@ -90,13 +92,14 @@ func TestMintCoins(t *testing.T) { initialSupply := keeper.GetSupply(ctx) - require.Error(t, keeper.MintCoins(ctx, "", initCoins), "no module account") + require.Panics(t, func() { keeper.MintCoins(ctx, "", initCoins) }, "no module account") require.Panics(t, func() { keeper.MintCoins(ctx, types.Burner, initCoins) }, "invalid permission") - require.Panics(t, func() { keeper.MintCoins(ctx, types.Minter, sdk.Coins{sdk.Coin{"denom", sdk.NewInt(-10)}}) }, "insufficient coins") //nolint + err := keeper.MintCoins(ctx, types.Minter, sdk.Coins{sdk.Coin{Denom: "denom", Amount: sdk.NewInt(-10)}}) + require.Error(t, err, "insufficient coins") require.Panics(t, func() { keeper.MintCoins(ctx, randomPerm, initCoins) }) - err := keeper.MintCoins(ctx, types.Minter, initCoins) + err = keeper.MintCoins(ctx, types.Minter, initCoins) require.NoError(t, err) require.Equal(t, initCoins, getCoinsByName(ctx, keeper, ak, types.Minter)) require.Equal(t, initialSupply.GetTotal().Add(initCoins), keeper.GetSupply(ctx).GetTotal()) @@ -125,12 +128,13 @@ func TestBurnCoins(t *testing.T) { initialSupply = initialSupply.Inflate(initCoins) keeper.SetSupply(ctx, initialSupply) - require.Error(t, keeper.BurnCoins(ctx, "", initCoins), "no module account") + require.Panics(t, func() { keeper.BurnCoins(ctx, "", initCoins) }, "no module account") require.Panics(t, func() { keeper.BurnCoins(ctx, types.Minter, initCoins) }, "invalid permission") require.Panics(t, func() { keeper.BurnCoins(ctx, randomPerm, initialSupply.GetTotal()) }, "random permission") - require.Panics(t, func() { keeper.BurnCoins(ctx, types.Burner, initialSupply.GetTotal()) }, "insufficient coins") + err := keeper.BurnCoins(ctx, types.Burner, initialSupply.GetTotal()) + require.Error(t, err, "insufficient coins") - err := keeper.BurnCoins(ctx, types.Burner, initCoins) + err = keeper.BurnCoins(ctx, types.Burner, initCoins) require.NoError(t, err) require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, ak, types.Burner)) require.Equal(t, initialSupply.GetTotal().Sub(initCoins), keeper.GetSupply(ctx).GetTotal()) diff --git a/x/supply/internal/keeper/key.go b/x/supply/internal/keeper/key.go index 6428d5445c05..65a23382961f 100644 --- a/x/supply/internal/keeper/key.go +++ b/x/supply/internal/keeper/key.go @@ -1,13 +1,5 @@ package keeper -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/supply/internal/types" -) - -// DefaultCodespace from the supply module -var DefaultCodespace sdk.CodespaceType = types.ModuleName - // Keys for supply store // Items are stored with the following key: values // diff --git a/x/supply/internal/keeper/querier.go b/x/supply/internal/keeper/querier.go index 9b74a45ccbe6..093edd2c6bea 100644 --- a/x/supply/internal/keeper/querier.go +++ b/x/supply/internal/keeper/querier.go @@ -1,18 +1,17 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/supply/internal/types" ) // NewQuerier creates a querier for supply REST endpoints func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryTotalSupply: @@ -22,17 +21,17 @@ func NewQuerier(k Keeper) sdk.Querier { return querySupplyOf(ctx, req, k) default: - return nil, sdk.ErrUnknownRequest("unknown supply query endpoint") + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) } } } -func queryTotalSupply(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryTotalSupply(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryTotalSupplyParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } totalSupply := k.GetSupply(ctx).GetTotal() @@ -46,25 +45,25 @@ func queryTotalSupply(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, res, err := totalSupply.MarshalJSON() if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to JSON marshal result: %s", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } -func querySupplyOf(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func querySupplyOf(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QuerySupplyOfParams err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } supply := k.GetSupply(ctx).GetTotal().AmountOf(params.Denom) res, err := supply.MarshalJSON() if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to JSON marshal result: %s", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil diff --git a/x/supply/internal/types/expected_keepers.go b/x/supply/internal/types/expected_keepers.go index bf0cc6ec328a..3ad1d8b13ce4 100644 --- a/x/supply/internal/types/expected_keepers.go +++ b/x/supply/internal/types/expected_keepers.go @@ -15,10 +15,10 @@ type AccountKeeper interface { // BankKeeper defines the expected bank keeper (noalias) type BankKeeper interface { - SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error - DelegateCoins(ctx sdk.Context, fromAdd, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error - UndelegateCoins(ctx sdk.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + DelegateCoins(ctx sdk.Context, fromAdd, toAddr sdk.AccAddress, amt sdk.Coins) error + UndelegateCoins(ctx sdk.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error - SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) - AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) + SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, error) + AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, error) } diff --git a/x/upgrade/abci_test.go b/x/upgrade/abci_test.go index edc71590dc0f..34c8944e0017 100644 --- a/x/upgrade/abci_test.go +++ b/x/upgrade/abci_test.go @@ -1,11 +1,13 @@ package upgrade_test import ( + "errors" "testing" "time" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/upgrade" @@ -37,25 +39,25 @@ func (s *TestSuite) SetupTest() { func (s *TestSuite) TestRequireName() { err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{}}) s.Require().NotNil(err) - s.Require().Equal(sdk.CodeUnknownRequest, err.Code()) + s.Require().True(errors.Is(sdkerrors.ErrInvalidRequest, err), err) } func (s *TestSuite) TestRequireFutureTime() { err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: s.ctx.BlockHeader().Time}}) s.Require().NotNil(err) - s.Require().Equal(sdk.CodeUnknownRequest, err.Code()) + s.Require().True(errors.Is(sdkerrors.ErrInvalidRequest, err), err) } func (s *TestSuite) TestRequireFutureBlock() { err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: s.ctx.BlockHeight()}}) s.Require().NotNil(err) - s.Require().Equal(sdk.CodeUnknownRequest, err.Code()) + s.Require().True(errors.Is(sdkerrors.ErrInvalidRequest, err), err) } func (s *TestSuite) TestCantSetBothTimeAndHeight() { err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now(), Height: s.ctx.BlockHeight() + 1}}) s.Require().NotNil(err) - s.Require().Equal(sdk.CodeUnknownRequest, err.Code()) + s.Require().True(errors.Is(sdkerrors.ErrInvalidRequest, err), err) } func (s *TestSuite) TestDoTimeUpgrade() { @@ -156,7 +158,7 @@ func (s *TestSuite) TestCantApplySameUpgradeTwice() { s.T().Log("Verify an upgrade named \"test\" can't be scheduled twice") err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now()}}) s.Require().NotNil(err) - s.Require().Equal(sdk.CodeUnknownRequest, err.Code()) + s.Require().True(errors.Is(sdkerrors.ErrInvalidRequest, err), err) } func (s *TestSuite) TestNoSpuriousUpgrades() { diff --git a/x/upgrade/alias.go b/x/upgrade/alias.go index b7324f2c3e41..fe36f23097bc 100644 --- a/x/upgrade/alias.go +++ b/x/upgrade/alias.go @@ -1,10 +1,7 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/upgrade/internal/types -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/upgrade/internal/keeper package upgrade +// nolint + import ( "github.com/cosmos/cosmos-sdk/x/upgrade/internal/keeper" "github.com/cosmos/cosmos-sdk/x/upgrade/internal/types" @@ -19,7 +16,6 @@ const ( DoneByte = types.DoneByte ProposalTypeSoftwareUpgrade = types.ProposalTypeSoftwareUpgrade ProposalTypeCancelSoftwareUpgrade = types.ProposalTypeCancelSoftwareUpgrade - DefaultCodespace = types.DefaultCodespace QueryCurrent = types.QueryCurrent QueryApplied = types.QueryApplied ) diff --git a/x/upgrade/handler.go b/x/upgrade/handler.go index 925d4e875c9d..8a4a9f89ab10 100644 --- a/x/upgrade/handler.go +++ b/x/upgrade/handler.go @@ -1,9 +1,8 @@ package upgrade import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -11,7 +10,7 @@ import ( // It enables SoftwareUpgradeProposal to propose an Upgrade, and CancelSoftwareUpgradeProposal // to abort a previously voted upgrade. func NewSoftwareUpgradeProposalHandler(k Keeper) govtypes.Handler { - return func(ctx sdk.Context, content govtypes.Content) sdk.Error { + return func(ctx sdk.Context, content govtypes.Content) error { switch c := content.(type) { case SoftwareUpgradeProposal: return handleSoftwareUpgradeProposal(ctx, k, c) @@ -20,17 +19,16 @@ func NewSoftwareUpgradeProposalHandler(k Keeper) govtypes.Handler { return handleCancelSoftwareUpgradeProposal(ctx, k, c) default: - errMsg := fmt.Sprintf("unrecognized software upgrade proposal content type: %T", c) - return sdk.ErrUnknownRequest(errMsg) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized software upgrade proposal content type: %T", c) } } } -func handleSoftwareUpgradeProposal(ctx sdk.Context, k Keeper, p SoftwareUpgradeProposal) sdk.Error { +func handleSoftwareUpgradeProposal(ctx sdk.Context, k Keeper, p SoftwareUpgradeProposal) error { return k.ScheduleUpgrade(ctx, p.Plan) } -func handleCancelSoftwareUpgradeProposal(ctx sdk.Context, k Keeper, p CancelSoftwareUpgradeProposal) sdk.Error { +func handleCancelSoftwareUpgradeProposal(ctx sdk.Context, k Keeper, p CancelSoftwareUpgradeProposal) error { k.ClearUpgradePlan(ctx) return nil } diff --git a/x/upgrade/internal/keeper/keeper.go b/x/upgrade/internal/keeper/keeper.go index bb95ec6eafdb..e0c0823b0842 100644 --- a/x/upgrade/internal/keeper/keeper.go +++ b/x/upgrade/internal/keeper/keeper.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/upgrade/internal/types" "github.com/tendermint/tendermint/libs/log" ) @@ -36,26 +37,27 @@ func (k Keeper) SetUpgradeHandler(name string, upgradeHandler types.UpgradeHandl // ScheduleUpgrade schedules an upgrade based on the specified plan. // If there is another Plan already scheduled, it will overwrite it // (implicitly cancelling the current plan) -func (k Keeper) ScheduleUpgrade(ctx sdk.Context, plan types.Plan) sdk.Error { +func (k Keeper) ScheduleUpgrade(ctx sdk.Context, plan types.Plan) error { if err := plan.ValidateBasic(); err != nil { return err } if !plan.Time.IsZero() { if !plan.Time.After(ctx.BlockHeader().Time) { - return sdk.ErrUnknownRequest("upgrade cannot be scheduled in the past") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "upgrade cannot be scheduled in the past") } } else if plan.Height <= ctx.BlockHeight() { - return sdk.ErrUnknownRequest("upgrade cannot be scheduled in the past") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "upgrade cannot be scheduled in the past") } if k.getDoneHeight(ctx, plan.Name) != 0 { - return sdk.ErrUnknownRequest(fmt.Sprintf("upgrade with name %s has already been completed", plan.Name)) + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "upgrade with name %s has already been completed", plan.Name) } bz := k.cdc.MustMarshalBinaryBare(plan) store := ctx.KVStore(k.storeKey) store.Set(types.PlanKey(), bz) + return nil } diff --git a/x/upgrade/internal/keeper/querier.go b/x/upgrade/internal/keeper/querier.go index 291f7bb9d049..164a2340c0a7 100644 --- a/x/upgrade/internal/keeper/querier.go +++ b/x/upgrade/internal/keeper/querier.go @@ -2,16 +2,16 @@ package keeper import ( "encoding/binary" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/upgrade/internal/types" abci "github.com/tendermint/tendermint/abci/types" ) // NewQuerier creates a querier for upgrade cli and REST endpoints func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryCurrent: @@ -21,38 +21,40 @@ func NewQuerier(k Keeper) sdk.Querier { return queryApplied(ctx, req, k) default: - return nil, sdk.ErrUnknownRequest("unknown supply query endpoint") + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) } } } -func queryCurrent(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryCurrent(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { plan, has := k.GetUpgradePlan(ctx) if !has { - // empty data - client can respond Not Found return nil, nil } + res, err := k.cdc.MarshalJSON(&plan) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to JSON marshal result: %s", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } + return res, nil } -func queryApplied(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func queryApplied(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryAppliedParams err := k.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } applied := k.getDoneHeight(ctx, params.Name) if applied == 0 { - // empty data - client can respond Not Found return nil, nil } + bz := make([]byte, 8) binary.BigEndian.PutUint64(bz, uint64(applied)) + return bz, nil } diff --git a/x/upgrade/internal/types/plan.go b/x/upgrade/internal/types/plan.go index 24fd28b72005..c2b88171e218 100644 --- a/x/upgrade/internal/types/plan.go +++ b/x/upgrade/internal/types/plan.go @@ -6,6 +6,7 @@ import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // Plan specifies information about a planned upgrade and when it should occur @@ -40,19 +41,20 @@ func (p Plan) String() string { } // ValidateBasic does basic validation of a Plan -func (p Plan) ValidateBasic() sdk.Error { +func (p Plan) ValidateBasic() error { if len(p.Name) == 0 { - return sdk.ErrUnknownRequest("name cannot be empty") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "name cannot be empty") } if p.Height < 0 { - return sdk.ErrUnknownRequest("height cannot be negative") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "height cannot be negative") } if p.Time.IsZero() && p.Height == 0 { - return sdk.ErrUnknownRequest("must set either time or height") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "must set either time or height") } if !p.Time.IsZero() && p.Height != 0 { - return sdk.ErrUnknownRequest("cannot set both time and height") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "cannot set both time and height") } + return nil } diff --git a/x/upgrade/internal/types/proposal.go b/x/upgrade/internal/types/proposal.go index 3dc54f494f60..958c10674645 100644 --- a/x/upgrade/internal/types/proposal.go +++ b/x/upgrade/internal/types/proposal.go @@ -3,14 +3,12 @@ package types import ( "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov" ) const ( - ProposalTypeSoftwareUpgrade string = "SoftwareUpgrade" - ProposalTypeCancelSoftwareUpgrade string = "CancelSoftwareUpgrade" - DefaultCodespace sdk.CodespaceType = "upgrade" + ProposalTypeSoftwareUpgrade string = "SoftwareUpgrade" + ProposalTypeCancelSoftwareUpgrade string = "CancelSoftwareUpgrade" ) // Software Upgrade Proposals @@ -39,11 +37,11 @@ func (sup SoftwareUpgradeProposal) GetTitle() string { return sup.Title } func (sup SoftwareUpgradeProposal) GetDescription() string { return sup.Description } func (sup SoftwareUpgradeProposal) ProposalRoute() string { return RouterKey } func (sup SoftwareUpgradeProposal) ProposalType() string { return ProposalTypeSoftwareUpgrade } -func (sup SoftwareUpgradeProposal) ValidateBasic() sdk.Error { +func (sup SoftwareUpgradeProposal) ValidateBasic() error { if err := sup.Plan.ValidateBasic(); err != nil { return err } - return gov.ValidateAbstract(DefaultCodespace, sup) + return gov.ValidateAbstract(sup) } func (sup SoftwareUpgradeProposal) String() string { @@ -73,8 +71,8 @@ func (sup CancelSoftwareUpgradeProposal) ProposalRoute() string { return Router func (sup CancelSoftwareUpgradeProposal) ProposalType() string { return ProposalTypeCancelSoftwareUpgrade } -func (sup CancelSoftwareUpgradeProposal) ValidateBasic() sdk.Error { - return gov.ValidateAbstract(DefaultCodespace, sup) +func (sup CancelSoftwareUpgradeProposal) ValidateBasic() error { + return gov.ValidateAbstract(sup) } func (sup CancelSoftwareUpgradeProposal) String() string { diff --git a/x/upgrade/module.go b/x/upgrade/module.go index a365cd1a36c2..129cc904bf10 100644 --- a/x/upgrade/module.go +++ b/x/upgrade/module.go @@ -6,8 +6,8 @@ import ( "github.com/gorilla/mux" "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -52,7 +52,7 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { Use: "upgrade", Short: "Querying commands for the upgrade module", } - queryCmd.AddCommand(client.GetCommands( + queryCmd.AddCommand(flags.GetCommands( cli.GetPlanCmd(StoreKey, cdc), cli.GetAppliedHeightCmd(StoreKey, cdc), )...) @@ -66,7 +66,7 @@ func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { Use: "upgrade", Short: "Upgrade transaction subcommands", } - txCmd.AddCommand(client.PostCommands()...) + txCmd.AddCommand(flags.PostCommands()...) return txCmd } From 1e2217191272d3de89b5ee4a0454af69b62ef6b1 Mon Sep 17 00:00:00 2001 From: Joon Date: Wed, 15 Jan 2020 00:21:20 +0900 Subject: [PATCH 030/176] ADR 015 Implementation (#5401) * implement in progress * rm unneccessary change under simapp, modify baseapp for codetxbreak * fix test in progress * fix test error * fix golangci * address minor comments * mv antehandler to ante/, address comments * fix GetCommitment => GetData, fix syntax * checkout types/ to ibc-alpha * checkout to origin/ibc-alpha * fix branch problem * fix syntax error * recover PacketI interface * mv recvpacket rest from 20 -> 04 * address minor comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * rm wrong files * Apply suggestions from code review * PacketDataI field is now named, not embed * add acknowledgement hashing * rename finalization functiosn * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Rename GetCommitment() to GetBytes() * Add recv sequence incr to RecvPacket() * Revert but where is PacketExecuted() called * Call PacketExecuted(), check seq in RecvPacket() * The port is called "bank" * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update simapp/app.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Remove omitempty * Add godoc * Move events * set ProofVerificationDecorator on AnteHandler * Apply suggestions from code review Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * format Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Christopher Goes Co-authored-by: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> --- client/context/verifier_test.go | 3 +- simapp/app.go | 32 ++- x/auth/alias.go | 103 ++++---- x/auth/ante/ante.go | 10 +- x/auth/ante/ante_test.go | 26 +- x/ibc/02-client/keeper/client.go | 24 ++ x/ibc/04-channel/alias.go | 8 +- x/ibc/04-channel/client/rest/rest.go | 8 + x/ibc/04-channel/client/rest/tx.go | 46 ++++ x/ibc/04-channel/client/utils/utils.go | 18 +- x/ibc/04-channel/exported/exported.go | 13 +- x/ibc/04-channel/keeper/packet.go | 79 ++++-- x/ibc/04-channel/keeper/timeout.go | 65 +++-- x/ibc/04-channel/types/codec.go | 12 +- x/ibc/04-channel/types/msgs.go | 167 ++++++++++++ x/ibc/04-channel/types/msgs_test.go | 133 +++++++++- x/ibc/04-channel/types/packet.go | 76 +++--- x/ibc/20-transfer/alias.go | 18 +- x/ibc/20-transfer/client/rest/rest.go | 10 - x/ibc/20-transfer/client/rest/tx.go | 46 ---- x/ibc/20-transfer/handler.go | 62 ++++- x/ibc/20-transfer/handler_test.go | 118 ++------- x/ibc/20-transfer/keeper/callbacks.go | 44 +--- x/ibc/20-transfer/keeper/callbacks_test.go | 123 +-------- x/ibc/20-transfer/keeper/keeper.go | 18 +- x/ibc/20-transfer/keeper/keeper_test.go | 2 +- x/ibc/20-transfer/keeper/relay.go | 65 +++-- x/ibc/20-transfer/keeper/relay_test.go | 117 +-------- x/ibc/20-transfer/module.go | 94 ++++++- x/ibc/20-transfer/types/codec.go | 3 +- x/ibc/20-transfer/types/expected_keepers.go | 3 +- x/ibc/20-transfer/types/msgs_test.go | 81 ------ x/ibc/20-transfer/types/packet.go | 64 ++++- x/ibc/20-transfer/types/packet_test.go | 32 +-- x/ibc/ante.go | 51 ---- x/ibc/ante/ante.go | 47 ++++ x/ibc/ante/ante_test.go | 272 ++++++++++++++++++++ x/ibc/client/cli/cli.go | 3 - x/ibc/client/rest/rest.go | 2 - x/ibc/handler.go | 10 +- x/ibc/keeper/keeper.go | 10 - x/ibc/module.go | 3 - x/mock/app.go | 4 +- 43 files changed, 1290 insertions(+), 835 deletions(-) delete mode 100644 x/ibc/ante.go create mode 100644 x/ibc/ante/ante.go create mode 100644 x/ibc/ante/ante_test.go diff --git a/client/context/verifier_test.go b/client/context/verifier_test.go index 6eacccae5452..bd2539492349 100644 --- a/client/context/verifier_test.go +++ b/client/context/verifier_test.go @@ -4,8 +4,9 @@ import ( "io/ioutil" "testing" - "github.com/cosmos/cosmos-sdk/client/context" "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/client/context" ) func TestCreateVerifier(t *testing.T) { diff --git a/simapp/app.go b/simapp/app.go index 96fede2dedd1..0cebb05866ef 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -25,7 +25,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/ibc" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" - ibctransfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/params" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" @@ -65,17 +65,18 @@ var ( ibc.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, + transfer.AppModuleBasic{}, ) // module account permissions maccPerms = map[string][]string{ - auth.FeeCollectorName: nil, - distr.ModuleName: nil, - mint.ModuleName: {supply.Minter}, - staking.BondedPoolName: {supply.Burner, supply.Staking}, - staking.NotBondedPoolName: {supply.Burner, supply.Staking}, - gov.ModuleName: {supply.Burner}, - ibctransfer.GetModuleAccountName(): {supply.Minter, supply.Burner}, + auth.FeeCollectorName: nil, + distr.ModuleName: nil, + mint.ModuleName: {supply.Minter}, + staking.BondedPoolName: {supply.Burner, supply.Staking}, + staking.NotBondedPoolName: {supply.Burner, supply.Staking}, + gov.ModuleName: {supply.Burner}, + transfer.GetModuleAccountName(): {supply.Minter, supply.Burner}, } // module accounts that are allowed to receive tokens @@ -127,6 +128,7 @@ type SimApp struct { ParamsKeeper params.Keeper IBCKeeper ibc.Keeper EvidenceKeeper evidence.Keeper + TransferKeeper transfer.Keeper // the module manager mm *module.Manager @@ -151,6 +153,7 @@ func NewSimApp( bam.MainStoreKey, auth.StoreKey, staking.StoreKey, supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey, gov.StoreKey, params.StoreKey, ibc.StoreKey, upgrade.StoreKey, evidence.StoreKey, + transfer.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(params.TStoreKey) @@ -233,6 +236,12 @@ func NewSimApp( app.IBCKeeper = ibc.NewKeeper(app.cdc, keys[ibc.StoreKey], app.BankKeeper, app.SupplyKeeper) + transferCapKey := app.IBCKeeper.PortKeeper.BindPort(bank.ModuleName) + app.TransferKeeper = transfer.NewKeeper( + app.cdc, keys[transfer.StoreKey], transferCapKey, + app.IBCKeeper.ChannelKeeper, app.BankKeeper, app.SupplyKeeper, + ) + // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. app.mm = module.NewManager( @@ -293,7 +302,12 @@ func NewSimApp( // initialize BaseApp app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) - app.SetAnteHandler(ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, auth.DefaultSigVerificationGasConsumer)) + app.SetAnteHandler( + ante.NewAnteHandler( + app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, + ante.DefaultSigVerificationGasConsumer, + ), + ) app.SetEndBlocker(app.EndBlocker) if loadLatest { diff --git a/x/auth/alias.go b/x/auth/alias.go index 01b20a68f3d7..599ab823967b 100644 --- a/x/auth/alias.go +++ b/x/auth/alias.go @@ -1,17 +1,16 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/ante -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/keeper -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/types package auth import ( - "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/types" ) +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/types + const ( ModuleName = types.ModuleName StoreKey = types.StoreKey @@ -28,39 +27,34 @@ const ( var ( // functions aliases - NewAnteHandler = ante.NewAnteHandler - GetSignerAcc = ante.GetSignerAcc - DefaultSigVerificationGasConsumer = ante.DefaultSigVerificationGasConsumer - DeductFees = ante.DeductFees - SetGasMeter = ante.SetGasMeter - NewAccountKeeper = keeper.NewAccountKeeper - NewQuerier = keeper.NewQuerier - NewBaseAccount = types.NewBaseAccount - ProtoBaseAccount = types.ProtoBaseAccount - NewBaseAccountWithAddress = types.NewBaseAccountWithAddress - NewAccountRetriever = types.NewAccountRetriever - RegisterCodec = types.RegisterCodec - RegisterAccountTypeCodec = types.RegisterAccountTypeCodec - NewGenesisState = types.NewGenesisState - DefaultGenesisState = types.DefaultGenesisState - ValidateGenesis = types.ValidateGenesis - SanitizeGenesisAccounts = types.SanitizeGenesisAccounts - AddressStoreKey = types.AddressStoreKey - NewParams = types.NewParams - ParamKeyTable = types.ParamKeyTable - DefaultParams = types.DefaultParams - NewQueryAccountParams = types.NewQueryAccountParams - NewStdTx = types.NewStdTx - CountSubKeys = types.CountSubKeys - NewStdFee = types.NewStdFee - StdSignBytes = types.StdSignBytes - DefaultTxDecoder = types.DefaultTxDecoder - DefaultTxEncoder = types.DefaultTxEncoder - NewTxBuilder = types.NewTxBuilder - NewTxBuilderFromCLI = types.NewTxBuilderFromCLI - MakeSignature = types.MakeSignature - ValidateGenAccounts = types.ValidateGenAccounts - GetGenesisStateFromAppState = types.GetGenesisStateFromAppState + NewAccountKeeper = keeper.NewAccountKeeper + NewQuerier = keeper.NewQuerier + NewBaseAccount = types.NewBaseAccount + ProtoBaseAccount = types.ProtoBaseAccount + NewBaseAccountWithAddress = types.NewBaseAccountWithAddress + NewAccountRetriever = types.NewAccountRetriever + RegisterCodec = types.RegisterCodec + RegisterAccountTypeCodec = types.RegisterAccountTypeCodec + NewGenesisState = types.NewGenesisState + DefaultGenesisState = types.DefaultGenesisState + ValidateGenesis = types.ValidateGenesis + SanitizeGenesisAccounts = types.SanitizeGenesisAccounts + AddressStoreKey = types.AddressStoreKey + NewParams = types.NewParams + ParamKeyTable = types.ParamKeyTable + DefaultParams = types.DefaultParams + NewQueryAccountParams = types.NewQueryAccountParams + NewStdTx = types.NewStdTx + CountSubKeys = types.CountSubKeys + NewStdFee = types.NewStdFee + StdSignBytes = types.StdSignBytes + DefaultTxDecoder = types.DefaultTxDecoder + DefaultTxEncoder = types.DefaultTxEncoder + NewTxBuilder = types.NewTxBuilder + NewTxBuilderFromCLI = types.NewTxBuilderFromCLI + MakeSignature = types.MakeSignature + ValidateGenAccounts = types.ValidateGenAccounts + GetGenesisStateFromAppState = types.GetGenesisStateFromAppState // variable aliases ModuleCdc = types.ModuleCdc @@ -74,19 +68,18 @@ var ( ) type ( - SignatureVerificationGasConsumer = ante.SignatureVerificationGasConsumer - AccountKeeper = keeper.AccountKeeper - BaseAccount = types.BaseAccount - NodeQuerier = types.NodeQuerier - AccountRetriever = types.AccountRetriever - GenesisState = types.GenesisState - Params = types.Params - QueryAccountParams = types.QueryAccountParams - StdSignMsg = types.StdSignMsg - StdTx = types.StdTx - StdFee = types.StdFee - StdSignDoc = types.StdSignDoc - StdSignature = types.StdSignature - TxBuilder = types.TxBuilder - GenesisAccountIterator = types.GenesisAccountIterator + AccountKeeper = keeper.AccountKeeper + BaseAccount = types.BaseAccount + NodeQuerier = types.NodeQuerier + AccountRetriever = types.AccountRetriever + GenesisState = types.GenesisState + Params = types.Params + QueryAccountParams = types.QueryAccountParams + StdSignMsg = types.StdSignMsg + StdTx = types.StdTx + StdFee = types.StdFee + StdSignDoc = types.StdSignDoc + StdSignature = types.StdSignature + TxBuilder = types.TxBuilder + GenesisAccountIterator = types.GenesisAccountIterator ) diff --git a/x/auth/ante/ante.go b/x/auth/ante/ante.go index bdf24823f137..54c3b8017eb7 100644 --- a/x/auth/ante/ante.go +++ b/x/auth/ante/ante.go @@ -4,12 +4,17 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/types" + ibcante "github.com/cosmos/cosmos-sdk/x/ibc/ante" + ibckeeper "github.com/cosmos/cosmos-sdk/x/ibc/keeper" ) // NewAnteHandler returns an AnteHandler that checks and increments sequence // numbers, checks signatures & account numbers, and deducts fees from the first // signer. -func NewAnteHandler(ak keeper.AccountKeeper, supplyKeeper types.SupplyKeeper, sigGasConsumer SignatureVerificationGasConsumer) sdk.AnteHandler { +func NewAnteHandler( + ak keeper.AccountKeeper, supplyKeeper types.SupplyKeeper, ibcKeeper ibckeeper.Keeper, + sigGasConsumer SignatureVerificationGasConsumer, +) sdk.AnteHandler { return sdk.ChainAnteDecorators( NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first NewMempoolFeeDecorator(), @@ -21,6 +26,7 @@ func NewAnteHandler(ak keeper.AccountKeeper, supplyKeeper types.SupplyKeeper, si NewDeductFeeDecorator(ak, supplyKeeper), NewSigGasConsumeDecorator(ak, sigGasConsumer), NewSigVerificationDecorator(ak), - NewIncrementSequenceDecorator(ak), // innermost AnteDecorator + NewIncrementSequenceDecorator(ak), + ibcante.NewProofVerificationDecorator(ibcKeeper.ClientKeeper, ibcKeeper.ChannelKeeper), // innermost AnteDecorator ) } diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index 1d55b4d320c3..df2bb4b16eb2 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -38,7 +38,7 @@ func TestSimulateGasCost(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -89,7 +89,7 @@ func TestSimulateGasCost(t *testing.T) { func TestAnteHandlerSigErrors(t *testing.T) { // setup app, ctx := createTestApp(true) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -138,7 +138,7 @@ func TestAnteHandlerAccountNumbers(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -195,7 +195,7 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(0) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -251,7 +251,7 @@ func TestAnteHandlerSequences(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -327,7 +327,7 @@ func TestAnteHandlerSequences(t *testing.T) { func TestAnteHandlerFees(t *testing.T) { // setup app, ctx := createTestApp(true) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -367,7 +367,7 @@ func TestAnteHandlerMemoGas(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -407,7 +407,7 @@ func TestAnteHandlerMultiSigner(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -457,7 +457,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -534,7 +534,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -652,7 +652,7 @@ func TestAnteHandlerSigLimitExceeded(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -692,7 +692,7 @@ func TestCustomSignatureVerificationGasConsumer(t *testing.T) { app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) // setup an ante handler that only accepts PubKeyEd25519 - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, func(meter sdk.GasMeter, sig []byte, pubkey crypto.PubKey, params types.Params) error { + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, func(meter sdk.GasMeter, sig []byte, pubkey crypto.PubKey, params types.Params) error { switch pubkey := pubkey.(type) { case ed25519.PubKeyEd25519: meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519") @@ -749,7 +749,7 @@ func TestAnteHandlerReCheck(t *testing.T) { require.NoError(t, acc1.SetAccountNumber(0)) app.AccountKeeper.SetAccount(ctx, acc1) - antehandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + antehandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // test that operations skipped on recheck do not run diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index 91cadfe4a016..11e805e466e6 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -34,6 +34,18 @@ func (k Keeper) CreateClient( k.SetClientState(ctx, clientState) k.SetClientType(ctx, clientID, clientType) k.Logger(ctx).Info(fmt.Sprintf("client %s created at height %d", clientID, consensusState.GetHeight())) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeCreateClient, + sdk.NewAttribute(types.AttributeKeyClientID, clientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) + return clientState, nil } @@ -72,6 +84,18 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H k.SetCommitter(ctx, clientID, consensusState.GetHeight(), consensusState.GetCommitter()) k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, consensusState.GetHeight())) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeUpdateClient, + sdk.NewAttribute(types.AttributeKeyClientID, clientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) + return nil } diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index 73e18df48d0c..ff4895eae42a 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -77,8 +77,10 @@ var ( NewMsgChannelOpenConfirm = types.NewMsgChannelOpenConfirm NewMsgChannelCloseInit = types.NewMsgChannelCloseInit NewMsgChannelCloseConfirm = types.NewMsgChannelCloseConfirm + NewMsgPacket = types.NewMsgPacket + NewMsgTimeout = types.NewMsgTimeout + NewMsgAcknowledgement = types.NewMsgAcknowledgement NewPacket = types.NewPacket - NewOpaquePacket = types.NewOpaquePacket NewChannelResponse = types.NewChannelResponse NewQueryChannelParams = types.NewQueryChannelParams @@ -108,8 +110,10 @@ type ( MsgChannelOpenConfirm = types.MsgChannelOpenConfirm MsgChannelCloseInit = types.MsgChannelCloseInit MsgChannelCloseConfirm = types.MsgChannelCloseConfirm + MsgPacket = types.MsgPacket + MsgAcknowledgement = types.MsgAcknowledgement + MsgTimeout = types.MsgTimeout Packet = types.Packet - OpaquePacket = types.OpaquePacket ChannelResponse = types.ChannelResponse QueryChannelParams = types.QueryChannelParams ) diff --git a/x/ibc/04-channel/client/rest/rest.go b/x/ibc/04-channel/client/rest/rest.go index 55cf81215f64..4c869297d6e7 100644 --- a/x/ibc/04-channel/client/rest/rest.go +++ b/x/ibc/04-channel/client/rest/rest.go @@ -73,3 +73,11 @@ type ChannelCloseConfirmReq struct { ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` } + +// RecvPacketReq defines the properties of a receive packet request's body. +type RecvPacketReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Packet types.Packet `json:"packet" yaml:"packet"` + Proofs commitment.ProofI `json:"proofs" yaml:"proofs"` + Height uint64 `json:"height" yaml:"height"` +} diff --git a/x/ibc/04-channel/client/rest/tx.go b/x/ibc/04-channel/client/rest/tx.go index 641a62bf20e2..ccbfebde13fc 100644 --- a/x/ibc/04-channel/client/rest/tx.go +++ b/x/ibc/04-channel/client/rest/tx.go @@ -21,6 +21,7 @@ func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/open-confirm", RestPortID, RestChannelID), channelOpenConfirmHandlerFn(cliCtx)).Methods("POST") r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/close-init", RestPortID, RestChannelID), channelCloseInitHandlerFn(cliCtx)).Methods("POST") r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/close-confirm", RestPortID, RestChannelID), channelCloseConfirmHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/packets/receive"), recvPacketHandlerFn(cliCtx)).Methods("POST") } // channelOpenInitHandlerFn implements a channel open init handler @@ -334,3 +335,48 @@ func channelCloseConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } + +// recvPacketHandlerFn implements a receive packet handler +// +// @Summary Receive packet +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.RecvPacketReq true "Receive packet request body" +// @Success 200 {object} PostRecvPacket "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/packets/receive [post] +func recvPacketHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req RecvPacketReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgPacket( + req.Packet, + req.Proofs, + req.Height, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index e7e9568e4add..912c77d463e9 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -4,12 +4,14 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // QueryPacket returns a packet from the store func QueryPacket( - ctx context.CLIContext, portID, channelID string, sequence, timeout uint64, prove bool, + ctx context.CLIContext, portID, channelID string, + sequence, timeout uint64, prove bool, ) (types.PacketResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", @@ -30,14 +32,23 @@ func QueryPacket( destPortID := channelRes.Channel.Counterparty.PortID destChannelID := channelRes.Channel.Counterparty.ChannelID + var data exported.PacketDataI + // TODO: commitment data is stored, not the data + // but we are unmarshalling the commitment in a json format + // because the current ICS 20 implementation uses json commitment form + // need to be changed to use external source of packet(e.g. event logs) + err = ctx.Codec.UnmarshalJSON(res.Value, &data) + if err != nil { + return types.PacketResponse{}, err + } + packet := types.NewPacket( + data, sequence, - timeout, portID, channelID, destPortID, destChannelID, - res.Value, ) // FIXME: res.Height+1 is hack, fix later @@ -63,6 +74,5 @@ func QueryChannel( if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { return types.ChannelResponse{}, err } - return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil } diff --git a/x/ibc/04-channel/exported/exported.go b/x/ibc/04-channel/exported/exported.go index 6fd31751fef6..75608bd532a7 100644 --- a/x/ibc/04-channel/exported/exported.go +++ b/x/ibc/04-channel/exported/exported.go @@ -8,6 +8,17 @@ type PacketI interface { GetSourceChannel() string GetDestPort() string GetDestChannel() string - GetData() []byte + GetData() PacketDataI ValidateBasic() error } + +// PacketDataI defines the packet data interface for IBC packets +// IBC application modules should define which data they want to +// send and receive over IBC channels. +type PacketDataI interface { + GetBytes() []byte // GetBytes returns the serialised packet data (without timeout) + GetTimeoutHeight() uint64 // GetTimeoutHeight returns the timeout height defined specifically for each packet data type instance + + ValidateBasic() error // ValidateBasic validates basic properties of the packet data, implements sdk.Msg + Type() string // Type returns human readable identifier, implements sdk.Msg +} diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 2703f283a814..a2db8d3f66a2 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -77,7 +77,7 @@ func (k Keeper) CleanupPacket( } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } @@ -184,7 +184,7 @@ func (k Keeper) SendPacket( nextSequenceSend++ k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend) - k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), packet.GetData()) // TODO: hash packet data + k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), types.CommitPacket(packet.GetData())) return nil } @@ -196,8 +196,6 @@ func (k Keeper) RecvPacket( packet exported.PacketI, proof commitment.ProofI, proofHeight uint64, - acknowledgement []byte, - portCapability sdk.CapabilityKey, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) @@ -212,9 +210,8 @@ func (k Keeper) RecvPacket( ) } - if !k.portKeeper.Authenticate(portCapability, packet.GetDestPort()) { - return nil, sdkerrors.Wrap(port.ErrInvalidPort, packet.GetDestPort()) - } + // RecvPacket is called by the antehandler which acts upon the packet.Route(), + // so the capability authentication can be omitted here // packet must come from the channel's counterparty if packet.GetSourcePort() != channel.Counterparty.PortID { @@ -243,6 +240,20 @@ func (k Keeper) RecvPacket( ) } + if channel.Ordering == types.ORDERED { + nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) + if !found { + return nil, types.ErrSequenceReceiveNotFound + } + + if packet.GetSequence() != nextSequenceRecv { + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv, + ) + } + } + if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { return nil, types.ErrPacketTimeout } @@ -250,26 +261,49 @@ func (k Keeper) RecvPacket( if !k.connectionKeeper.VerifyMembership( ctx, connectionEnd, proofHeight, proof, types.PacketCommitmentPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), - packet.GetData(), // TODO: hash data + types.CommitPacket(packet.GetData()), ) { return nil, errors.New("couldn't verify counterparty packet commitment") } - if len(acknowledgement) > 0 || channel.Ordering == types.UNORDERED { + return packet, nil +} + +// PacketExecuted writes the packet execution acknowledgement to the state, +// which will be verified by the counterparty chain using AcknowledgePacket. +// CONTRACT: each packet handler function should call WriteAcknowledgement at the end of the execution +func (k Keeper) PacketExecuted( + ctx sdk.Context, + packet exported.PacketI, + acknowledgement exported.PacketDataI, +) error { + channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) + if !found { + return sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetDestChannel()) + } + + if channel.State != types.OPEN { + return sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), + ) + } + + if acknowledgement != nil || channel.Ordering == types.UNORDERED { k.SetPacketAcknowledgement( ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), - acknowledgement, // TODO: hash ACK + types.CommitAcknowledgement(acknowledgement), ) } if channel.Ordering == types.ORDERED { nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { - return nil, types.ErrSequenceReceiveNotFound + return types.ErrSequenceReceiveNotFound } if packet.GetSequence() != nextSequenceRecv { - return nil, sdkerrors.Wrapf( + return sdkerrors.Wrapf( types.ErrInvalidPacket, "packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv, ) @@ -280,7 +314,7 @@ func (k Keeper) RecvPacket( k.SetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv) } - return packet, nil + return nil } // AcknowledgePacket is called by a module to process the acknowledgement of a @@ -291,10 +325,9 @@ func (k Keeper) RecvPacket( func (k Keeper) AcknowledgePacket( ctx sdk.Context, packet exported.PacketI, - acknowledgement []byte, + acknowledgement exported.PacketDataI, proof commitment.ProofI, proofHeight uint64, - portCapability sdk.CapabilityKey, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { @@ -308,9 +341,8 @@ func (k Keeper) AcknowledgePacket( ) } - if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return nil, errors.New("invalid capability key") - } + // RecvPacket is called by the antehandler which acts upon the packet.Route(), + // so the capability authentication can be omitted here // packet must come from the channel's counterparty if packet.GetSourcePort() != channel.Counterparty.PortID { @@ -340,18 +372,23 @@ func (k Keeper) AcknowledgePacket( } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } if !k.connectionKeeper.VerifyMembership( ctx, connectionEnd, proofHeight, proof, types.PacketAcknowledgementPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), - acknowledgement, // TODO: hash ACK + acknowledgement.GetBytes(), ) { return nil, errors.New("invalid acknowledgement on counterparty chain") } - k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) return packet, nil } + +// AcknowledgementExecuted deletes the commitment send from this chain after it receives the acknowlegement +// CONTRACT: each acknowledgement handler function should call WriteAcknowledgement at the end of the execution +func (k Keeper) AcknowledgementExecuted(ctx sdk.Context, packet exported.PacketI) { + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) +} diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index af54040dad2c..ccbffd25bd83 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -23,11 +23,13 @@ func (k Keeper) TimeoutPacket( proof commitment.ProofI, proofHeight uint64, nextSequenceRecv uint64, - portCapability sdk.CapabilityKey, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) + return nil, sdkerrors.Wrapf( + types.ErrChannelNotFound, + packet.GetSourcePort(), packet.GetSourceChannel(), + ) } if channel.State != types.OPEN { @@ -37,15 +39,14 @@ func (k Keeper) TimeoutPacket( ) } + // TimeoutPacket is called by the antehandler which acts upon the packet.Route(), + // so the capability authentication can be omitted here + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { return nil, types.ErrChannelCapabilityNotFound } - if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return nil, errors.New("port is not valid") - } - if packet.GetDestChannel() != channel.Counterparty.ChannelID { return nil, sdkerrors.Wrapf( types.ErrInvalidPacket, @@ -55,7 +56,10 @@ func (k Keeper) TimeoutPacket( connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap( + connection.ErrConnectionNotFound, + channel.ConnectionHops[0], + ) } if packet.GetDestPort() != channel.Counterparty.PortID { @@ -70,12 +74,18 @@ func (k Keeper) TimeoutPacket( } if nextSequenceRecv >= packet.GetSequence() { - return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet already received") + return nil, sdkerrors.Wrap( + types.ErrInvalidPacket, + "packet already received", + ) } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") + if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { + return nil, sdkerrors.Wrap( + types.ErrInvalidPacket, + "packet hasn't been sent", + ) } var ok bool @@ -99,13 +109,6 @@ func (k Keeper) TimeoutPacket( return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet verification failed") } - k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - - if channel.Ordering == types.ORDERED { - channel.State = types.CLOSED - k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) - } - return packet, nil } @@ -114,7 +117,7 @@ func (k Keeper) TimeoutPacket( // never be received (even if the timeoutHeight has not yet been reached). func (k Keeper) TimeoutOnClose( ctx sdk.Context, - packet exported.PacketI, + packet types.Packet, proofNonMembership, proofClosed commitment.ProofI, proofHeight uint64, @@ -122,7 +125,7 @@ func (k Keeper) TimeoutOnClose( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) + return nil, sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetSourcePort(), packet.GetSourceChannel()) } _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) @@ -154,7 +157,7 @@ func (k Keeper) TimeoutOnClose( } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } @@ -196,3 +199,25 @@ func (k Keeper) TimeoutOnClose( return packet, nil } + +// TimeoutExecuted deletes the commitment send from this chain after it verifies timeout +func (k Keeper) TimeoutExecuted(ctx sdk.Context, packet exported.PacketI) error { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return types.ErrChannelCapabilityNotFound + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + if channel.Ordering == types.ORDERED { + channel.State = types.CLOSED + k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + } + + return nil +} diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index a5d709662fa2..dea16064dbcd 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -2,19 +2,27 @@ package types import ( "github.com/cosmos/cosmos-sdk/codec" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // SubModuleCdc defines the IBC channel codec. var SubModuleCdc *codec.Codec +func init() { + SubModuleCdc = codec.New() + commitment.RegisterCodec(SubModuleCdc) + client.RegisterCodec(SubModuleCdc) + RegisterCodec(SubModuleCdc) +} + // RegisterCodec registers all the necessary types and interfaces for the // IBC channel. func RegisterCodec(cdc *codec.Codec) { - cdc.RegisterInterface((*exported.PacketI)(nil), nil) + cdc.RegisterInterface((*exported.PacketDataI)(nil), nil) cdc.RegisterConcrete(Channel{}, "ibc/channel/Channel", nil) cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil) - cdc.RegisterConcrete(OpaquePacket{}, "ibc/channel/OpaquePacket", nil) cdc.RegisterConcrete(MsgChannelOpenInit{}, "ibc/channel/MsgChannelOpenInit", nil) cdc.RegisterConcrete(MsgChannelOpenTry{}, "ibc/channel/MsgChannelOpenTry", nil) diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index d0a9e71955ba..3f578425dda0 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -389,3 +390,169 @@ func (msg MsgChannelCloseConfirm) GetSignBytes() []byte { func (msg MsgChannelCloseConfirm) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Signer} } + +// MsgPacket receives incoming IBC packet +type MsgPacket struct { + Packet `json:"packet" yaml:"packet"` + Proof commitment.ProofI `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` +} + +var _ sdk.Msg = MsgPacket{} + +// NewMsgPacket constructs new MsgPacket +func NewMsgPacket(packet Packet, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgPacket { + return MsgPacket{ + Packet: packet, + Proof: proof, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgPacket) Route() string { + return msg.DestinationPort +} + +// ValidateBasic implements sdk.Msg +func (msg MsgPacket) ValidateBasic() error { + if msg.Proof == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.Proof.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") + } + if msg.ProofHeight == 0 { + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") + } + if msg.Signer.Empty() { + return sdkerrors.ErrInvalidAddress + } + + return msg.Packet.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgPacket) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgPacket) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgTimeout{} + +// MsgTimeout receives timeouted packet +type MsgTimeout struct { + Packet `json:"packet" yaml:"packet"` + NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"` + Proof commitment.ProofI `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` +} + +// NewMsgTimeout constructs new MsgTimeout +func NewMsgTimeout(packet Packet, nextSequenceRecv uint64, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgTimeout { + return MsgTimeout{ + Packet: packet, + NextSequenceRecv: nextSequenceRecv, + Proof: proof, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgTimeout) Route() string { + return msg.SourcePort +} + +// ValidateBasic implements sdk.Msg +func (msg MsgTimeout) ValidateBasic() error { + if msg.Proof == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.Proof.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") + } + if msg.ProofHeight == 0 { + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") + } + if msg.Signer.Empty() { + return sdkerrors.ErrInvalidAddress + } + + return msg.Packet.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgTimeout) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgTimeout) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgAcknowledgement{} + +// MsgAcknowledgement receives incoming IBC acknowledgement +type MsgAcknowledgement struct { + Packet `json:"packet" yaml:"packet"` + Acknowledgement exported.PacketDataI `json:"acknowledgement" yaml:"acknowledgement"` + Proof commitment.ProofI `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` +} + +// NewMsgAcknowledgement constructs a new MsgAcknowledgement +func NewMsgAcknowledgement(packet Packet, ack exported.PacketDataI, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement { + return MsgAcknowledgement{ + Packet: packet, + Acknowledgement: ack, + Proof: proof, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgAcknowledgement) Route() string { + return msg.SourcePort +} + +// ValidateBasic implements sdk.Msg +func (msg MsgAcknowledgement) ValidateBasic() error { + if msg.Proof == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.Proof.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") + } + if msg.ProofHeight == 0 { + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") + } + if err := msg.Acknowledgement.ValidateBasic(); err != nil { + return err + } + if msg.Signer.Empty() { + return sdkerrors.ErrInvalidAddress + } + + return msg.Packet.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgAcknowledgement) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgAcknowledgement) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index 2165f8c4eb40..a6d324670200 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -1,10 +1,13 @@ package types import ( + "errors" "fmt" "testing" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/tendermint/tendermint/crypto/merkle" abci "github.com/tendermint/tendermint/abci/types" dbm "github.com/tendermint/tm-db" @@ -13,6 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -38,7 +42,7 @@ var ( invalidShortConnHops = []string{invalidShortConnection} invalidLongConnHops = []string{invalidLongConnection} - proof = commitment.Proof{} + proof = commitment.Proof{Proof: &merkle.Proof{}} addr = sdk.AccAddress("testaddr") ) @@ -347,3 +351,130 @@ func (suite *MsgTestSuite) TestMsgChannelCloseConfirm() { } } } + +var _ exported.PacketDataI = validPacketT{} + +type validPacketT struct{} + +func (validPacketT) GetBytes() []byte { + return []byte("testdata") +} + +func (validPacketT) GetTimeoutHeight() uint64 { + return 100 +} + +func (validPacketT) ValidateBasic() error { + return nil +} + +func (validPacketT) Type() string { + return "valid" +} + +var _ exported.PacketDataI = invalidPacketT{} + +type invalidPacketT struct{} + +func (invalidPacketT) GetBytes() []byte { + return []byte("testdata") +} + +func (invalidPacketT) GetTimeoutHeight() uint64 { + return 100 +} + +func (invalidPacketT) ValidateBasic() error { + return errors.New("invalid packet") +} + +func (invalidPacketT) Type() string { + return "invalid" +} + +// define variables used for testing +var ( + packet = NewPacket(validPacketT{}, 1, portid, chanid, cpportid, cpchanid) + invalidPacket = NewPacket(invalidPacketT{}, 0, portid, chanid, cpportid, cpchanid) + + emptyProof = commitment.Proof{Proof: nil} + invalidProofs1 = commitment.ProofI(nil) + invalidProofs2 = emptyProof + + addr1 = sdk.AccAddress("testaddr1") + emptyAddr sdk.AccAddress + + portid = "testportid" + chanid = "testchannel" + cpportid = "testcpport" + cpchanid = "testcpchannel" +) + +// TestMsgPacketRoute tests Route for MsgPacket +func TestMsgPacketRoute(t *testing.T) { + msg := NewMsgPacket(packet, proof, 1, addr1) + + require.Equal(t, cpportid, msg.Route()) +} + +// TestMsgPacketType tests Type for MsgPacket +func TestMsgPacketType(t *testing.T) { + msg := NewMsgPacket(packet, proof, 1, addr1) + + require.Equal(t, "valid", msg.Type()) +} + +// TestMsgPacketValidation tests ValidateBasic for MsgPacket +func TestMsgPacketValidation(t *testing.T) { + testMsgs := []MsgPacket{ + NewMsgPacket(packet, proof, 1, addr1), // valid msg + NewMsgPacket(packet, proof, 0, addr1), // proof height is zero + NewMsgPacket(packet, nil, 1, addr1), // missing proof + NewMsgPacket(packet, invalidProofs1, 1, addr1), // missing proof + NewMsgPacket(packet, invalidProofs2, 1, addr1), // proof contain empty proof + NewMsgPacket(packet, proof, 1, emptyAddr), // missing signer address + NewMsgPacket(invalidPacket, proof, 1, addr1), // invalid packet + } + + testCases := []struct { + msg MsgPacket + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "proof height is zero"}, + {testMsgs[2], false, "missing proof"}, + {testMsgs[3], false, "missing proof"}, + {testMsgs[4], false, "proof contain empty proof"}, + {testMsgs[5], false, "missing signer address"}, + {testMsgs[6], false, "invalid packet"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "Msg %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgPacketGetSignBytes tests GetSignBytes for MsgPacket +func TestMsgPacketGetSignBytes(t *testing.T) { + msg := NewMsgPacket(packet, proof, 1, addr1) + SubModuleCdc.RegisterConcrete(validPacketT{}, "test/validPacketT", nil) + res := msg.GetSignBytes() + + expected := `{"packet":{"data":{"type":"test/validPacketT","value":{}},"destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid"},"proof":{"type":"ibc/commitment/merkle/Proof","value":{"proof":{"ops":[]}}},"proof_height":"1","signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}` + require.Equal(t, expected, string(res)) +} + +// TestMsgPacketGetSigners tests GetSigners for MsgPacket +func TestMsgPacketGetSigners(t *testing.T) { + msg := NewMsgPacket(packet, proof, 1, addr1) + res := msg.GetSigners() + + expected := "[746573746164647231]" + require.Equal(t, expected, fmt.Sprintf("%v", res)) +} diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go index 7d8242d8db30..df9b78dd0cd5 100644 --- a/x/ibc/04-channel/types/packet.go +++ b/x/ibc/04-channel/types/packet.go @@ -1,46 +1,68 @@ package types import ( + "encoding/binary" + + "github.com/tendermint/tendermint/crypto/tmhash" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) +// CommitPacket appends bigendian encoded timeout height and commitment bytes +// and then returns the hash of the result bytes. +// TODO: no specification for packet commitment currently, +// make it spec compatible once we have it +func CommitPacket(data exported.PacketDataI) []byte { + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, data.GetTimeoutHeight()) + buf = append(buf, data.GetBytes()...) + return tmhash.Sum(buf) +} + +// CommitAcknowledgement returns the hash of commitment bytes +func CommitAcknowledgement(data exported.PacketDataI) []byte { + return tmhash.Sum(data.GetBytes()) +} + var _ exported.PacketI = Packet{} // Packet defines a type that carries data across different chains through IBC type Packet struct { + Data exported.PacketDataI `json:"data" yaml:"data"` // opaque value which can be defined by the application logic of the associated modules. + Sequence uint64 `json:"sequence" yaml:"sequence"` // number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. - Timeout uint64 `json:"timeout" yaml:"timeout"` // indicates a consensus height on the destination chain after which the Packet will no longer be processed, and will instead count as having timed-out. SourcePort string `json:"source_port" yaml:"source_port"` // identifies the port on the sending chain. SourceChannel string `json:"source_channel" yaml:"source_channel"` // identifies the channel end on the sending chain. DestinationPort string `json:"destination_port" yaml:"destination_port"` // identifies the port on the receiving chain. DestinationChannel string `json:"destination_channel" yaml:"destination_channel"` // identifies the channel end on the receiving chain. - Data []byte `json:"data" yaml:"data"` // opaque value which can be defined by the application logic of the associated modules. } // NewPacket creates a new Packet instance func NewPacket( - sequence, timeout uint64, sourcePort, sourceChannel, - destinationPort, destinationChannel string, data []byte, + data exported.PacketDataI, + sequence uint64, sourcePort, sourceChannel, + destinationPort, destinationChannel string, ) Packet { return Packet{ + Data: data, Sequence: sequence, - Timeout: timeout, SourcePort: sourcePort, SourceChannel: sourceChannel, DestinationPort: destinationPort, DestinationChannel: destinationChannel, - Data: data, } } +// Type exports Packet.Data.Type +func (p Packet) Type() string { + return p.Data.Type() +} + // GetSequence implements PacketI interface func (p Packet) GetSequence() uint64 { return p.Sequence } -// GetTimeoutHeight implements PacketI interface -func (p Packet) GetTimeoutHeight() uint64 { return p.Timeout } - // GetSourcePort implements PacketI interface func (p Packet) GetSourcePort() string { return p.SourcePort } @@ -54,7 +76,10 @@ func (p Packet) GetDestPort() string { return p.DestinationPort } func (p Packet) GetDestChannel() string { return p.DestinationChannel } // GetData implements PacketI interface -func (p Packet) GetData() []byte { return p.Data } +func (p Packet) GetData() exported.PacketDataI { return p.Data } + +// GetTimeoutHeight implements PacketI interface +func (p Packet) GetTimeoutHeight() uint64 { return p.Data.GetTimeoutHeight() } // ValidateBasic implements PacketI interface func (p Packet) ValidateBasic() error { @@ -85,34 +110,11 @@ func (p Packet) ValidateBasic() error { if p.Sequence == 0 { return sdkerrors.Wrap(ErrInvalidPacket, "packet sequence cannot be 0") } - if p.Timeout == 0 { + if p.Data.GetTimeoutHeight() == 0 { return sdkerrors.Wrap(ErrInvalidPacket, "packet timeout cannot be 0") } - if len(p.Data) == 0 { - return sdkerrors.Wrap(ErrInvalidPacket, "packet data cannot be empty") + if len(p.Data.GetBytes()) == 0 { + return sdkerrors.Wrap(ErrInvalidPacket, "packet data bytes cannot be empty") } - return nil + return p.Data.ValidateBasic() } - -var _ exported.PacketI = OpaquePacket{} - -// OpaquePacket is a Packet, but cloaked in an obscuring data type by the host -// state machine, such that a module cannot act upon it other than to pass it to -// the IBC handler -type OpaquePacket struct { - *Packet -} - -// NewOpaquePacket creates a new OpaquePacket instance -func NewOpaquePacket(sequence, timeout uint64, sourcePort, sourceChannel, - destinationPort, destinationChannel string, data []byte, -) OpaquePacket { - Packet := NewPacket( - sequence, timeout, sourcePort, sourceChannel, destinationPort, - destinationChannel, data, - ) - return OpaquePacket{&Packet} -} - -// GetData implements PacketI interface -func (op OpaquePacket) GetData() []byte { return nil } diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go index 00333d69f4b2..d819b6ed2399 100644 --- a/x/ibc/20-transfer/alias.go +++ b/x/ibc/20-transfer/alias.go @@ -35,13 +35,13 @@ var ( ) type ( - Keeper = keeper.Keeper - BankKeeper = types.BankKeeper - ChannelKeeper = types.ChannelKeeper - ClientKeeper = types.ClientKeeper - ConnectionKeeper = types.ConnectionKeeper - SupplyKeeper = types.SupplyKeeper - MsgTransfer = types.MsgTransfer - MsgRecvPacket = types.MsgRecvPacket - PacketData = types.PacketData + Keeper = keeper.Keeper + BankKeeper = types.BankKeeper + ChannelKeeper = types.ChannelKeeper + ClientKeeper = types.ClientKeeper + ConnectionKeeper = types.ConnectionKeeper + SupplyKeeper = types.SupplyKeeper + MsgTransfer = types.MsgTransfer + MsgRecvPacket = types.MsgRecvPacket + PacketDataTransfer = types.PacketDataTransfer ) diff --git a/x/ibc/20-transfer/client/rest/rest.go b/x/ibc/20-transfer/client/rest/rest.go index a43112f0cce3..61c6dc44daa6 100644 --- a/x/ibc/20-transfer/client/rest/rest.go +++ b/x/ibc/20-transfer/client/rest/rest.go @@ -6,8 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" - channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) const ( @@ -28,11 +26,3 @@ type TransferTxReq struct { Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` Source bool `json:"source" yaml:"source"` } - -// RecvPacketReq defines the properties of a receive packet request's body. -type RecvPacketReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - Packet channelexported.PacketI `json:"packet" yaml:"packet"` - Proofs []commitment.Proof `json:"proofs" yaml:"proofs"` - Height uint64 `json:"height" yaml:"height"` -} diff --git a/x/ibc/20-transfer/client/rest/tx.go b/x/ibc/20-transfer/client/rest/tx.go index de699c04e969..2413e4e8046e 100644 --- a/x/ibc/20-transfer/client/rest/tx.go +++ b/x/ibc/20-transfer/client/rest/tx.go @@ -15,7 +15,6 @@ import ( func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/transfer", RestPortID, RestChannelID), transferHandlerFn(cliCtx)).Methods("POST") - r.HandleFunc(fmt.Sprintf("/ibc/packets/receive"), recvPacketHandlerFn(cliCtx)).Methods("POST") } // transferHandlerFn implements a transfer handler @@ -71,48 +70,3 @@ func transferHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } - -// recvPacketHandlerFn implements a receive packet handler -// -// @Summary Receive packet -// @Tags IBC -// @Accept json -// @Produce json -// @Param body body rest.RecvPacketReq true "Receive packet request body" -// @Success 200 {object} PostRecvPacket "OK" -// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/packets/receive [post] -func recvPacketHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req RecvPacketReq - if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { - return - } - - req.BaseReq = req.BaseReq.Sanitize() - if !req.BaseReq.ValidateBasic(w) { - return - } - - fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - // create the message - msg := types.NewMsgRecvPacket( - req.Packet, - req.Proofs, - req.Height, - fromAddr, - ) - - if err := msg.ValidateBasic(); err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) - } -} diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 6dfcf0470e4d..877d20f01984 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -2,11 +2,39 @@ package transfer import ( sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) -// HandleMsgTransfer defines the sdk.Handler for MsgTransfer -func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) { +// NewHandler returns sdk.Handler for IBC token transfer module messages +func NewHandler(k Keeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + switch msg := msg.(type) { + case MsgTransfer: + return handleMsgTransfer(ctx, k, msg) + case channeltypes.MsgPacket: + switch data := msg.Data.(type) { + case PacketDataTransfer: // i.e fulfills the Data interface + return handlePacketDataTransfer(ctx, k, msg, data) + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 packet data type: %T", msg) + } + case channeltypes.MsgTimeout: + switch data := msg.Data.(type) { + case PacketDataTransfer: + return handleTimeoutDataTransfer(ctx, k, msg, data) + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 packet data type: %T", data) + } + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 message type: %T", msg) + } + } +} + +func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) { err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source) if err != nil { return nil, err @@ -26,11 +54,19 @@ func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, }, nil } -// HandleMsgRecvPacket defines the sdk.Handler for MsgRecvPacket -func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (*sdk.Result, error) { - err := k.ReceivePacket(ctx, msg.Packet, msg.Proofs[0], msg.Height) +func handlePacketDataTransfer(ctx sdk.Context, k Keeper, msg channeltypes.MsgPacket, data types.PacketDataTransfer) (*sdk.Result, error) { + packet := msg.Packet + err := k.ReceiveTransfer(ctx, packet.SourcePort, packet.SourceChannel, packet.DestinationPort, packet.DestinationChannel, data) if err != nil { - return nil, err + panic(err) + // TODO: Source chain sent invalid packet, shutdown channel + } + + acknowledgement := types.AckDataTransfer{} + err = k.PacketExecuted(ctx, packet, acknowledgement) + if err != nil { + panic(err) + // TODO: This should not happen } ctx.EventManager().EmitEvent( @@ -41,6 +77,20 @@ func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (*sdk.Res ), ) + // packet receiving should not fail + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil +} + +func handleTimeoutDataTransfer(ctx sdk.Context, k Keeper, msg channeltypes.MsgTimeout, data types.PacketDataTransfer) (*sdk.Result, error) { + packet := msg.Packet + err := k.TimeoutTransfer(ctx, packet.SourcePort, packet.SourceChannel, packet.DestinationPort, packet.DestinationChannel, data) + if err != nil { + // This chain sent invalid packet + panic(err) + } + // packet timeout should not fail return &sdk.Result{ Events: ctx.EventManager().Events(), }, nil diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index d3db1ed739fc..9dcf9e9b1060 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -159,134 +159,46 @@ func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitment.Proof, h func (suite *HandlerTestSuite) TestHandleMsgTransfer() { source := true + handler := transfer.NewHandler(suite.app.TransferKeeper) + msg := transfer.NewMsgTransfer(testPort1, testChannel1, testCoins, testAddr1, testAddr2, source) - res, err := transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err := handler(suite.ctx, msg) suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // channel does not exist + suite.Require().Nil(res, "%+v", res) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err = handler(suite.ctx, msg) suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // next send sequence not found + suite.Require().Nil(res, "%+v", res) // next send sequence not found nextSeqSend := uint64(1) suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err = handler(suite.ctx, msg) suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // sender has insufficient coins + suite.Require().Nil(res, "%+v", res) // sender has insufficient coins _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err = handler(suite.ctx, msg) suite.Require().NoError(err) - suite.Require().NotNil(res, "%v", res) // successfully executed + suite.Require().NotNil(res, "%+v", res) // successfully executed // test when the source is false source = false msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, source) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + + res, err = handler(suite.ctx, msg) suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // incorrect denom prefix + suite.Require().Nil(res, "%+v", res) // incorrect denom prefix msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, source) suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().NoError(err) - suite.Require().NotNil(res, "%v", res) // successfully executed -} - -func (suite *HandlerTestSuite) TestHandleRecvPacket() { - packetSeq := uint64(1) - packetTimeout := uint64(100) - - packetDataBz := []byte("invaliddata") - packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - packetCommitmentPath := channel.KeyPacketCommitment(testPort2, testChannel2, packetSeq) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) - suite.updateClient() - proofPacket, proofHeight := suite.queryProof(packetCommitmentPath) - - msg := types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - res, err := transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // packet membership verification failed due to invalid counterparty packet commitment - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // invalid packet data - - // test when the source is true - source := true - - packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().NoError(err) - suite.Require().NotNil(res, "%v", res) // successfully executed - - // test when the source is false - source = false - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // insufficient coins in the corresponding escrow account - escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err = handler(suite.ctx, msg) suite.Require().NoError(err) - suite.Require().NotNil(res, "%v", res) // successfully executed + suite.Require().NotNil(res, "%+v", res) // successfully executed } func TestHandlerTestSuite(t *testing.T) { diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go index b4c0675bed78..3e478a16c6c7 100644 --- a/x/ibc/20-transfer/keeper/callbacks.go +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -1,12 +1,19 @@ package keeper +// NOTE: +// OnChanOpenInit, OnChanOpenTry, OnChanOpenAck, OnChanOpenConfirm, OnChanCLoseConfirm +// will be implemented according to ADR15 in the future PRs. Code left for reference. +// +// OnRecvPacket, OnAcknowledgementPacket, OnTimeoutPacket has been implemented according +// to ADR15. + +/* import ( "strings" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -123,35 +130,6 @@ func (k Keeper) OnChanCloseConfirm( return nil } -// onRecvPacket is called when an FTTransfer packet is received -// nolint: unused -func (k Keeper) OnRecvPacket( - ctx sdk.Context, - packet channelexported.PacketI, -) error { - var data types.PacketData - - err := k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) - if err != nil { - return sdkerrors.Wrap(err, "invalid packet data") - } - - return k.ReceiveTransfer( - ctx, packet.GetSourcePort(), packet.GetSourceChannel(), - packet.GetDestPort(), packet.GetDestChannel(), data, - ) -} - -// nolint: unused -func (k Keeper) OnAcknowledgePacket( - ctx sdk.Context, - packet channelexported.PacketI, - acknowledgement []byte, -) error { - // no-op - return nil -} - // nolint: unused func (k Keeper) OnTimeoutPacket( ctx sdk.Context, @@ -191,8 +169,4 @@ func (k Keeper) OnTimeoutPacket( return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Sender, data.Amount) } - -// nolint: unused -func (k Keeper) OnTimeoutPacketClose(_ sdk.Context, _ channelexported.PacketI) { - panic("can't happen, only unordered channels allowed") -} +*/ diff --git a/x/ibc/20-transfer/keeper/callbacks_test.go b/x/ibc/20-transfer/keeper/callbacks_test.go index fb505cf190ac..171cb99e7306 100644 --- a/x/ibc/20-transfer/keeper/callbacks_test.go +++ b/x/ibc/20-transfer/keeper/callbacks_test.go @@ -1,11 +1,7 @@ package keeper_test -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" -) - +// TODO: move to 04-channel after CheckOpen implementation in the following PR +/* func (suite *KeeperTestSuite) TestOnChanOpenInit() { invalidOrder := channel.ORDERED @@ -52,117 +48,4 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenAck(suite.ctx, testPort1, testChannel1, "") suite.NoError(err) // successfully executed } - -func (suite *KeeperTestSuite) TestOnRecvPacket() { - packetSeq := uint64(1) - packetTimeout := uint64(100) - - packetDataBz := []byte("invaliddata") - packet := channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - err := suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.Error(err) // invalid packet data - - // when the source is true - source := true - - packetData := types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.NoError(err) // successfully executed - - totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) - suite.Equal(testPrefixedCoins2, totalSupply.GetTotal()) // supply should be inflated - - receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) - suite.Equal(testPrefixedCoins2, receiverCoins) - - // when the source is false - source = false - - packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.Error(err) // insufficient coins in the corresponding escrow account - - escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.NoError(err) // successfully executed - - receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) - suite.Equal(testCoins, receiverCoins) -} - -func (suite *KeeperTestSuite) TestOnTimeoutPacket() { - packetSeq := uint64(1) - packetTimeout := uint64(100) - - packetDataBz := []byte("invaliddata") - packet := channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - err := suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.Error(err) // invalid packet data - - // when the source is true - source := true - - packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.Error(err) // insufficient coins in the corresponding escrow account - - escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.NoError(err) // successfully executed - - senderCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Sender) - suite.Equal(testCoins, senderCoins) - - escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) - suite.Equal(sdk.Coins(nil), escrowCoins) - - // when the source is false - source = false - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Sender, sdk.Coins{}) - err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.NoError(err) // successfully executed - - totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) - suite.Equal(testPrefixedCoins1, totalSupply.GetTotal()) // supply should be inflated - - senderCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Sender) - suite.Equal(testPrefixedCoins1, senderCoins) -} +*/ diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index 341f75374881..05639f581b14 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" @@ -19,10 +20,8 @@ const ( // Keeper defines the IBC transfer keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - - // Capability key and port to which ICS20 is binded. Used for packet relaying. + storeKey sdk.StoreKey + cdc *codec.Codec boundedCapability sdk.CapabilityKey clientKeeper types.ClientKeeper @@ -34,9 +33,8 @@ type Keeper struct { // NewKeeper creates a new IBC transfer Keeper instance func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, - capKey sdk.CapabilityKey, clientKeeper types.ClientKeeper, - connnectionKeeper types.ConnectionKeeper, channelKeeper types.ChannelKeeper, + cdc *codec.Codec, key sdk.StoreKey, capKey sdk.CapabilityKey, + channelKeeper types.ChannelKeeper, bankKeeper types.BankKeeper, supplyKeeper types.SupplyKeeper, ) Keeper { @@ -49,8 +47,6 @@ func NewKeeper( storeKey: key, cdc: cdc, boundedCapability: capKey, - clientKeeper: clientKeeper, - connectionKeeper: connnectionKeeper, channelKeeper: channelKeeper, bankKeeper: bankKeeper, supplyKeeper: supplyKeeper, @@ -66,3 +62,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { func (k Keeper) GetTransferAccount(ctx sdk.Context) supplyexported.ModuleAccountI { return k.supplyKeeper.GetModuleAccount(ctx, types.GetModuleAccountName()) } + +func (k Keeper) PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketDataI) error { + return k.channelKeeper.PacketExecuted(ctx, packet, acknowledgement) +} diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index cc67265bb1f8..b4d4132c7109 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -74,7 +74,7 @@ func (suite *KeeperTestSuite) TestGetTransferAccount() { expectedMaccName := types.GetModuleAccountName() expectedMaccAddr := sdk.AccAddress(crypto.AddressHash([]byte(expectedMaccName))) - macc := suite.app.IBCKeeper.TransferKeeper.GetTransferAccount(suite.ctx) + macc := suite.app.TransferKeeper.GetTransferAccount(suite.ctx) suite.NotNil(macc) suite.Equal(expectedMaccName, macc.GetName()) diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index f30d59de04fb..d58412d26b1d 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -5,10 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // SendTransfer handles transfer sending logic @@ -51,22 +49,6 @@ func (k Keeper) SendTransfer( return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, coins, sender, receiver, isSourceChain) } -// ReceivePacket handles receiving packet -func (k Keeper) ReceivePacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, height uint64) error { - _, err := k.channelKeeper.RecvPacket(ctx, packet, proof, height, []byte{}, k.boundedCapability) - if err != nil { - return err - } - - var data types.PacketData - err = k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) - if err != nil { - return sdkerrors.Wrap(err, "invalid packet data") - } - - return k.ReceiveTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestPort(), packet.GetDestChannel(), data) -} - // ReceiveTransfer handles transfer receiving logic func (k Keeper) ReceiveTransfer( ctx sdk.Context, @@ -74,7 +56,7 @@ func (k Keeper) ReceiveTransfer( sourceChannel, destinationPort, destinationChannel string, - data types.PacketData, + data types.PacketDataTransfer, ) error { if data.Source { prefix := types.GetDenomPrefix(destinationPort, destinationChannel) @@ -117,6 +99,40 @@ func (k Keeper) ReceiveTransfer( } +// TimeoutTransfer handles transfer timeout logic +func (k Keeper) TimeoutTransfer( + ctx sdk.Context, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel string, + data types.PacketDataTransfer, +) error { + // check the denom prefix + prefix := types.GetDenomPrefix(sourcePort, sourceChannel) + coins := make(sdk.Coins, len(data.Amount)) + for i, coin := range data.Amount { + coin := coin + if !strings.HasPrefix(coin.Denom, prefix) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "%s doesn't contain the prefix '%s'", coin.Denom, prefix) + } + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) + } + + if data.Source { + escrowAddress := types.GetEscrowAddress(destinationPort, destinationChannel) + return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Sender, coins) + } + + // mint from supply + err := k.supplyKeeper.MintCoins(ctx, types.GetModuleAccountName(), data.Amount) + if err != nil { + return err + } + + return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Sender, data.Amount) +} + func (k Keeper) createOutgoingPacket( ctx sdk.Context, seq uint64, @@ -175,22 +191,15 @@ func (k Keeper) createOutgoingPacket( } } - packetData := types.NewPacketData(amount, sender, receiver, isSourceChain) - - // TODO: This should be hashed (for the commitment in the store). - packetDataBz, err := k.cdc.MarshalBinaryBare(packetData) - if err != nil { - return sdkerrors.Wrap(err, "invalid packet data") - } + packetData := types.NewPacketDataTransfer(amount, sender, receiver, isSourceChain, uint64(ctx.BlockHeight())+DefaultPacketTimeout) packet := channel.NewPacket( + packetData, seq, - uint64(ctx.BlockHeight())+DefaultPacketTimeout, sourcePort, sourceChannel, destinationPort, destinationChannel, - packetDataBz, ) return k.channelKeeper.SendPacket(ctx, packet, k.boundedCapability) diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 79b84c13716a..b22135c409b3 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -101,20 +101,20 @@ func (suite *KeeperTestSuite) TestSendTransfer() { // test the situation where the source is true isSourceChain := true - err := suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err := suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // next send sequence not found nextSeqSend := uint64(1) suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // sender has insufficient coins _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.NoError(err) // successfully executed senderCoins := suite.app.BankKeeper.GetCoins(suite.ctx, testAddr1) @@ -134,12 +134,12 @@ func (suite *KeeperTestSuite) TestSendTransfer() { isSourceChain = false _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, isSourceChain) suite.Error(err) // incorrect denom prefix suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, isSourceChain) suite.NoError(err) // successfully executed senderCoins = suite.app.BankKeeper.GetCoins(suite.ctx, testAddr1) @@ -152,13 +152,14 @@ func (suite *KeeperTestSuite) TestSendTransfer() { func (suite *KeeperTestSuite) TestReceiveTransfer() { // test the situation where the source is true source := true + packetTimeout := uint64(100) - packetData := types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - err := suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + packetData := types.NewPacketDataTransfer(testPrefixedCoins1, testAddr1, testAddr2, source, packetTimeout) + err := suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.Error(err) // incorrect denom prefix packetData.Amount = testPrefixedCoins2 - err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.NoError(err) // successfully executed totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) @@ -171,17 +172,17 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { packetData.Source = false packetData.Amount = testPrefixedCoins2 - err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.Error(err) // incorrect denom prefix packetData.Amount = testPrefixedCoins1 - err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.Error(err) // insufficient coins in the corresponding escrow account escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) - err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.NoError(err) // successfully executed escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) @@ -190,95 +191,3 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) suite.Equal(testCoins, receiverCoins) } - -func (suite *KeeperTestSuite) TestReceivePacket() { - packetSeq := uint64(1) - packetTimeout := uint64(100) - - packetDataBz := []byte("invaliddata") - packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort2, testChannel1, packetDataBz) - packetCommitmentPath := channel.KeyPacketCommitment(testPort2, testChannel2, packetSeq) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) - suite.updateClient() - proofPacket, proofHeight := suite.queryProof(packetCommitmentPath) - - suite.createChannel(testPort2, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - err := suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // invalid port id - - packet.DestinationPort = testPort1 - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // packet membership verification failed due to invalid counterparty packet commitment - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // invalid packet data - - // test the situation where the source is true - source := true - - packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.NoError(err) // successfully executed - - totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) - suite.Equal(testPrefixedCoins1, totalSupply.GetTotal()) // supply should be inflated - - receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) - suite.Equal(testPrefixedCoins1, receiverCoins) - - // test the situation where the source is false - source = false - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // insufficient coins in the corresponding escrow account - - escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.NoError(err) // successfully executed - - receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) - suite.Equal(testCoins, receiverCoins) - - escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) - suite.Equal(sdk.Coins(nil), escrowCoins) -} diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index f29136061cde..914f4d148c71 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -1,31 +1,109 @@ package transfer import ( + "encoding/json" + "github.com/gorilla/mux" "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) +const ( + ModuleName = types.SubModuleName +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +type AppModuleBasic struct{} + // Name returns the IBC transfer ICS name -func Name() string { +func (AppModuleBasic) Name() string { return SubModuleName } -// RegisterRESTRoutes registers the REST routes for the IBC transfer -func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { +func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { + RegisterCodec(cdc) +} + +func (AppModuleBasic) DefaultGenesis() json.RawMessage { + return nil +} + +func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { + return nil +} + +func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { rest.RegisterRoutes(ctx, rtr) } -// GetTxCmd returns the root tx command for the IBC transfer. -func GetTxCmd(cdc *codec.Codec) *cobra.Command { +func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { return cli.GetTxCmd(cdc) } -// GetQueryCmd returns the root tx command for the IBC transfer. -func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { - return cli.GetQueryCmd(cdc, queryRoute) +func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetQueryCmd(cdc, QuerierRoute) +} + +type AppModule struct { + AppModuleBasic + keeper Keeper +} + +func NewAppModule(k Keeper) AppModule { + return AppModule{ + keeper: k, + } +} + +func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { + // TODO +} + +func (AppModule) Route() string { + return RouterKey +} + +func (am AppModule) NewHandler() sdk.Handler { + return NewHandler(am.keeper) +} + +func (AppModule) QuerierRoute() string { + return QuerierRoute +} + +func (am AppModule) NewQuerierHandler() sdk.Querier { + return nil +} + +// InitGenesis performs genesis initialization for the staking module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { + // check if the IBC transfer module account is set + InitGenesis(ctx, am.keeper) + return []abci.ValidatorUpdate{} +} + +func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { + return nil +} + +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { + +} + +func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} } diff --git a/x/ibc/20-transfer/types/codec.go b/x/ibc/20-transfer/types/codec.go index ba018b3fc676..1b9680c8da3d 100644 --- a/x/ibc/20-transfer/types/codec.go +++ b/x/ibc/20-transfer/types/codec.go @@ -8,8 +8,7 @@ import ( func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgTransfer{}, "ibc/transfer/MsgTransfer", nil) - cdc.RegisterConcrete(MsgRecvPacket{}, "ibc/transfer/MsgRecvPacket", nil) - cdc.RegisterConcrete(PacketData{}, "ibc/transfer/PacketData", nil) + cdc.RegisterConcrete(PacketDataTransfer{}, "ibc/transfer/PacketDataTransfer", nil) } var ModuleCdc = codec.New() diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index e7c709306228..a8bd48a215de 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -6,7 +6,6 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" ) @@ -20,7 +19,7 @@ type ChannelKeeper interface { GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channel.Channel, found bool) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) SendPacket(ctx sdk.Context, packet channelexported.PacketI, portCapability sdk.CapabilityKey) error - RecvPacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, proofHeight uint64, acknowledgement []byte, portCapability sdk.CapabilityKey) (channelexported.PacketI, error) + PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketDataI) error } // ClientKeeper defines the expected IBC client keeper diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go index 935f94f0419f..42e55d32677c 100644 --- a/x/ibc/20-transfer/types/msgs_test.go +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -5,11 +5,8 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/merkle" sdk "github.com/cosmos/cosmos-sdk/types" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -24,17 +21,7 @@ const ( invalidLongChannel = "invalidlongchannelinvalidlongchannel" ) -// define variables used for testing var ( - packet = channel.NewPacket(1, 100, "testportid", "testchannel", "testcpport", "testcpchannel", []byte("testdata")) - invalidPacket = channel.NewPacket(0, 100, "testportid", "testchannel", "testcpport", "testcpchannel", []byte{}) - - proof = commitment.Proof{Proof: &merkle.Proof{}} - emptyProof = commitment.Proof{Proof: nil} - proofs = []commitment.Proof{proof} - invalidProofs1 = []commitment.Proof{} - invalidProofs2 = []commitment.Proof{emptyProof} - addr1 = sdk.AccAddress("testaddr1") addr2 = sdk.AccAddress("testaddr2") emptyAddr sdk.AccAddress @@ -120,71 +107,3 @@ func TestMsgTransferGetSigners(t *testing.T) { expected := "[746573746164647231]" require.Equal(t, expected, fmt.Sprintf("%v", res)) } - -// TestMsgRecvPacketRoute tests Route for MsgRecvPacket -func TestMsgRecvPacketRoute(t *testing.T) { - msg := NewMsgRecvPacket(packet, proofs, 1, addr1) - - require.Equal(t, ibctypes.RouterKey, msg.Route()) -} - -// TestMsgRecvPacketType tests Type for MsgRecvPacket -func TestMsgRecvPacketType(t *testing.T) { - msg := NewMsgRecvPacket(packet, proofs, 1, addr1) - - require.Equal(t, "recv_packet", msg.Type()) -} - -// TestMsgRecvPacketValidation tests ValidateBasic for MsgRecvPacket -func TestMsgRecvPacketValidation(t *testing.T) { - testMsgs := []MsgRecvPacket{ - NewMsgRecvPacket(packet, proofs, 1, addr1), // valid msg - NewMsgRecvPacket(packet, proofs, 0, addr1), // proof height is zero - NewMsgRecvPacket(packet, nil, 1, addr1), // missing proofs - NewMsgRecvPacket(packet, invalidProofs1, 1, addr1), // missing proofs - NewMsgRecvPacket(packet, invalidProofs2, 1, addr1), // proofs contain empty proof - NewMsgRecvPacket(packet, proofs, 1, emptyAddr), // missing signer address - NewMsgRecvPacket(invalidPacket, proofs, 1, addr1), // invalid packet - } - - testCases := []struct { - msg MsgRecvPacket - expPass bool - errMsg string - }{ - {testMsgs[0], true, ""}, - {testMsgs[1], false, "proof height is zero"}, - {testMsgs[2], false, "missing proofs"}, - {testMsgs[3], false, "missing proofs"}, - {testMsgs[4], false, "proofs contain empty proof"}, - {testMsgs[5], false, "missing signer address"}, - {testMsgs[6], false, "invalid packet"}, - } - - for i, tc := range testCases { - err := tc.msg.ValidateBasic() - if tc.expPass { - require.NoError(t, err, "Msg %d failed: %v", i, err) - } else { - require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) - } - } -} - -// TestMsgRecvPacketGetSignBytes tests GetSignBytes for MsgRecvPacket -func TestMsgRecvPacketGetSignBytes(t *testing.T) { - msg := NewMsgRecvPacket(packet, proofs, 1, addr1) - res := msg.GetSignBytes() - - expected := `{"type":"ibc/transfer/MsgRecvPacket","value":{"height":"1","packet":{"type":"ibc/channel/Packet","value":{"data":"dGVzdGRhdGE=","destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid","timeout":"100"}},"proofs":[{"proof":{"ops":[]}}],"signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}}` - require.Equal(t, expected, string(res)) -} - -// TestMsgRecvPacketGetSigners tests GetSigners for MsgRecvPacket -func TestMsgRecvPacketGetSigners(t *testing.T) { - msg := NewMsgRecvPacket(packet, proofs, 1, addr1) - res := msg.GetSigners() - - expected := "[746573746164647231]" - require.Equal(t, expected, fmt.Sprintf("%v", res)) -} diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go index 19aed7c60343..189ae9b40c63 100644 --- a/x/ibc/20-transfer/types/packet.go +++ b/x/ibc/20-transfer/types/packet.go @@ -5,28 +5,34 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" ) -// PacketData defines a struct for the packet payload -type PacketData struct { +var _ channelexported.PacketDataI = PacketDataTransfer{} + +// PacketDataTransfer defines a struct for the packet payload +type PacketDataTransfer struct { Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred + Timeout uint64 `json:"timeout" yaml:"timeout"` } -// NewPacketData contructs a new PacketData -func NewPacketData(amount sdk.Coins, sender, receiver sdk.AccAddress, source bool) PacketData { - return PacketData{ +// NewPacketDataTransfer contructs a new PacketDataTransfer +func NewPacketDataTransfer(amount sdk.Coins, sender, receiver sdk.AccAddress, source bool, timeout uint64) PacketDataTransfer { + return PacketDataTransfer{ Amount: amount, Sender: sender, Receiver: receiver, Source: source, + Timeout: timeout, } } -func (pd PacketData) String() string { - return fmt.Sprintf(`PacketData: +func (pd PacketDataTransfer) String() string { + return fmt.Sprintf(`PacketDataTransfer: Amount: %s Sender: %s Receiver: %s @@ -38,8 +44,9 @@ func (pd PacketData) String() string { ) } +// Implements channelexported.PacketDataI // ValidateBasic performs a basic check of the packet fields -func (pd PacketData) ValidateBasic() error { +func (pd PacketDataTransfer) ValidateBasic() error { if !pd.Amount.IsAllPositive() { return sdkerrors.ErrInsufficientFunds } @@ -54,3 +61,44 @@ func (pd PacketData) ValidateBasic() error { } return nil } + +// Implements channelexported.PacketDataI +func (pd PacketDataTransfer) GetBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(pd)) +} + +// Implements channelexported.PacketDataI +func (pd PacketDataTransfer) GetTimeoutHeight() uint64 { + return pd.Timeout +} + +// Implements channelexported.PacketDataI +func (pd PacketDataTransfer) Type() string { + return "ics20/transfer" +} + +var _ channelexported.PacketDataI = AckDataTransfer{} + +type AckDataTransfer struct { +} + +// Implements channelexported.PacketDataI +// ValidateBasic performs a basic check of the packet fields +func (ack AckDataTransfer) ValidateBasic() error { + return nil +} + +// Implements channelexported.PacketDataI +func (ack AckDataTransfer) GetBytes() []byte { + return []byte("ok") +} + +// Implements channelexported.PacketDataI +func (ack AckDataTransfer) GetTimeoutHeight() uint64 { + return 0 +} + +// Implements channelexported.PacketDataI +func (ack AckDataTransfer) Type() string { + return "ics20/transfer/ack" +} diff --git a/x/ibc/20-transfer/types/packet_test.go b/x/ibc/20-transfer/types/packet_test.go index 8471fb0cf2da..1a3c1b46fc16 100644 --- a/x/ibc/20-transfer/types/packet_test.go +++ b/x/ibc/20-transfer/types/packet_test.go @@ -6,34 +6,34 @@ import ( "github.com/stretchr/testify/require" ) -// TestPacketDataValidation tests ValidateBasic for PacketData -func TestPacketDataValidation(t *testing.T) { - testPacketData := []PacketData{ - NewPacketData(coins, addr1, addr2, true), // valid msg - NewPacketData(invalidDenomCoins, addr1, addr2, true), // invalid amount - NewPacketData(negativeCoins, addr1, addr2, false), // amount contains negative coin - NewPacketData(coins, emptyAddr, addr2, false), // missing sender address - NewPacketData(coins, addr1, emptyAddr, false), // missing recipient address +// TestPacketDataTransferValidation tests ValidateBasic for PacketDataTransfer +func TestPacketDataTransferValidation(t *testing.T) { + testPacketDataTransfer := []PacketDataTransfer{ + NewPacketDataTransfer(coins, addr1, addr2, true, 100), // valid msg + NewPacketDataTransfer(invalidDenomCoins, addr1, addr2, true, 100), // invalid amount + NewPacketDataTransfer(negativeCoins, addr1, addr2, false, 100), // amount contains negative coin + NewPacketDataTransfer(coins, emptyAddr, addr2, false, 100), // missing sender address + NewPacketDataTransfer(coins, addr1, emptyAddr, false, 100), // missing recipient address } testCases := []struct { - packetData PacketData + packetData PacketDataTransfer expPass bool errMsg string }{ - {testPacketData[0], true, ""}, - {testPacketData[1], false, "invalid amount"}, - {testPacketData[2], false, "amount contains negative coin"}, - {testPacketData[3], false, "missing sender address"}, - {testPacketData[4], false, "missing recipient address"}, + {testPacketDataTransfer[0], true, ""}, + {testPacketDataTransfer[1], false, "invalid amount"}, + {testPacketDataTransfer[2], false, "amount contains negative coin"}, + {testPacketDataTransfer[3], false, "missing sender address"}, + {testPacketDataTransfer[4], false, "missing recipient address"}, } for i, tc := range testCases { err := tc.packetData.ValidateBasic() if tc.expPass { - require.NoError(t, err, "PacketData %d failed: %v", i, err) + require.NoError(t, err, "PacketDataTransfer %d failed: %v", i, err) } else { - require.Error(t, err, "Invalid PacketData %d passed: %s", i, tc.errMsg) + require.Error(t, err, "Invalid PacketDataTransfer %d passed: %s", i, tc.errMsg) } } } diff --git a/x/ibc/ante.go b/x/ibc/ante.go deleted file mode 100644 index 0e1f7f635d70..000000000000 --- a/x/ibc/ante.go +++ /dev/null @@ -1,51 +0,0 @@ -package ibc - -// // TODO: Should extract timeout msgs too -// func ExtractMsgPackets(msgs []sdk.Msg) (res []MsgPacket, abort bool) { -// res = make([]MsgPacket, 0, len(msgs)) -// for _, msg := range msgs { -// msgp, ok := msg.(MsgPacket) -// if ok { -// res = append(res, msgp) -// } -// } - -// if len(res) >= 2 { -// first := res[0] -// for _, msg := range res[1:] { -// if len(msg.ChannelID) != 0 && msg.ChannelID != first.ChannelID { -// return res, true -// } -// msg.ChannelID = first.ChannelID -// } -// } - -// return -// } - -// func VerifyMsgPackets(ctx sdk.Context, channel channel.Manager, msgs []MsgPacket) error { -// for _, msg := range msgs { -// err := channel.Receive(ctx, msg.Proofs, msg.Height, msg.ReceiverPort(), msg.ChannelID, msg.Packet) -// if err != nil { -// return err -// } -// } - -// return nil -// } - -// func NewAnteDecorator(channel channel.Manager) sdk.AnteDecorator { -// return func(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { -// msgs, abort := ExtractMsgPackets(tx.GetMsgs()) -// if abort { -// return ctx, host.ErrInvalidPacket -// } - -// err := VerifyMsgPackets(ctx, channel, msgs) -// if err != nil { -// return ctx, sdkerrors.Wrap(host.ErrInvalidPacket, err.Error()) -// } - -// return next(ctx, tx, simulate) -// } -// } diff --git a/x/ibc/ante/ante.go b/x/ibc/ante/ante.go new file mode 100644 index 000000000000..1873c2edf612 --- /dev/null +++ b/x/ibc/ante/ante.go @@ -0,0 +1,47 @@ +package ante + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" +) + +// ProofVerificationDecorator handles messages that contains application specific packet types, +// including MsgPacket, MsgAcknowledgement, MsgTimeout. +// MsgUpdateClients are also handled here to perform atomic multimsg transaction +type ProofVerificationDecorator struct { + clientKeeper client.Keeper + channelKeeper channel.Keeper +} + +// NewProofVerificationDecorator constructs new ProofverificationDecorator +func NewProofVerificationDecorator(clientKeeper client.Keeper, channelKeeper channel.Keeper) ProofVerificationDecorator { + return ProofVerificationDecorator{ + clientKeeper: clientKeeper, + channelKeeper: channelKeeper, + } +} + +// AnteHandle executes MsgUpdateClient, MsgPacket, MsgAcknowledgement, MsgTimeout. +// The packet execution messages are then passed to the respective application handlers. +func (pvr ProofVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + for _, msg := range tx.GetMsgs() { + var err error + switch msg := msg.(type) { + case client.MsgUpdateClient: + err = pvr.clientKeeper.UpdateClient(ctx, msg.ClientID, msg.Header) + case channel.MsgPacket: + _, err = pvr.channelKeeper.RecvPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight) + case channel.MsgAcknowledgement: + _, err = pvr.channelKeeper.AcknowledgePacket(ctx, msg.Packet, msg.Acknowledgement, msg.Proof, msg.ProofHeight) + case channel.MsgTimeout: + _, err = pvr.channelKeeper.TimeoutPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight, msg.NextSequenceRecv) + } + + if err != nil { + return ctx, err + } + } + + return next(ctx, tx, simulate) +} diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go new file mode 100644 index 000000000000..b23f9fbeefcf --- /dev/null +++ b/x/ibc/ante/ante_test.go @@ -0,0 +1,272 @@ +package ante_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/cosmos/cosmos-sdk/x/ibc/ante" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// define constants used for testing +const ( + testChainID = "test-chain-id" + testClient = "test-client" + testClientType = clientexported.Tendermint + + testConnection = "testconnection" + + testChannelVersion = "1.0" +) + +// define variables used for testing +type HandlerTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet +} + +func (suite *HandlerTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.app = app + + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + suite.createClient() + suite.createConnection(connection.OPEN) +} + +func (suite *HandlerTestSuite) createClient() { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + suite.NoError(err) +} + +func (suite *HandlerTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) +} + +func (suite *HandlerTestSuite) createConnection(state connection.State) { + connection := connection.ConnectionEnd{ + State: state, + ClientID: testClient, + Counterparty: connection.Counterparty{ + ClientID: testClient, + ConnectionID: testConnection, + Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + }, + Versions: connection.GetCompatibleVersions(), + } + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) +} + +func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channel.State, order channel.Order) { + ch := channel.Channel{ + State: state, + Ordering: order, + Counterparty: channel.Counterparty{ + PortID: counterpartyPort, + ChannelID: counterpartyChan, + }, + ConnectionHops: []string{connID}, + Version: testChannelVersion, + } + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) +} + +func (suite *HandlerTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + +func (suite *HandlerTestSuite) newTx(msg sdk.Msg) sdk.Tx { + return auth.StdTx{ + Msgs: []sdk.Msg{msg}, + } +} + +func (suite *HandlerTestSuite) TestHandleMsgPacketOrdered() { + handler := sdk.ChainAnteDecorators(ante.NewProofVerificationDecorator( + suite.app.IBCKeeper.ClientKeeper, + suite.app.IBCKeeper.ChannelKeeper, + )) + + packet := channel.NewPacket(newPacket(12345), 1, portid, chanid, cpportid, cpchanid) + + cctx, _ := suite.ctx.CacheContext() + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, packet.SourcePort, packet.SourceChannel, 1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, packet.SourcePort, packet.SourceChannel, packet.Sequence, channeltypes.CommitPacket(packet.Data)) + msg := channel.NewMsgPacket(packet, nil, 0, addr1) + _, err := handler(cctx, suite.newTx(msg), false) + suite.Error(err, "%+v", err) // channel does not exist + + cctx, _ = suite.ctx.CacheContext() + suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channel.OPEN, channel.ORDERED) + packetCommitmentPath := channel.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, packet.Sequence) + proof, proofHeight := suite.queryProof(packetCommitmentPath) + msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) + _, err = handler(cctx, suite.newTx(msg), false) + suite.Error(err, "%+v", err) // invalid proof + + suite.updateClient() + cctx, _ = suite.ctx.CacheContext() + proof, proofHeight = suite.queryProof(packetCommitmentPath) + msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) + _, err = handler(cctx, suite.newTx(msg), false) + suite.Error(err, "%+v", err) // next recvseq not set + + proof, proofHeight = suite.queryProof(packetCommitmentPath) + msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, cpportid, cpchanid, 1) + cctx, write := suite.ctx.CacheContext() + + for i := 0; i < 10; i++ { + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(cctx, cpportid, cpchanid, uint64(i)) + _, err := handler(cctx, suite.newTx(msg), false) + if i == 1 { + suite.NoError(err, "%d", i) // successfully executed + write() + } else { + suite.Error(err, "%d", i) // wrong incoming sequence + } + } +} + +func (suite *HandlerTestSuite) TestHandleMsgPacketUnordered() { + handler := sdk.ChainAnteDecorators(ante.NewProofVerificationDecorator( + suite.app.IBCKeeper.ClientKeeper, + suite.app.IBCKeeper.ChannelKeeper, + )) + + // Not testing nonexist channel, invalid proof, nextseqsend, they are already tested in TestHandleMsgPacketOrdered + + var packet channeltypes.Packet + for i := 0; i < 5; i++ { + packet = channel.NewPacket(newPacket(uint64(i)), uint64(i), portid, chanid, cpportid, cpchanid) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, packet.SourcePort, packet.SourceChannel, uint64(i), channeltypes.CommitPacket(packet.Data)) + } + + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, packet.SourcePort, packet.SourceChannel, uint64(10)) + + suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channel.OPEN, channel.UNORDERED) + + suite.updateClient() + + for i := 10; i >= 0; i-- { + cctx, write := suite.ctx.CacheContext() + packet = channel.NewPacket(newPacket(uint64(i)), uint64(i), portid, chanid, cpportid, cpchanid) + packetCommitmentPath := channel.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, uint64(i)) + proof, proofHeight := suite.queryProof(packetCommitmentPath) + msg := channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) + _, err := handler(cctx, suite.newTx(msg), false) + if i < 5 { + suite.NoError(err, "%d", i) // successfully executed + write() + } else { + suite.Error(err, "%d", i) // wrong incoming sequence + } + } +} +func TestHandlerTestSuite(t *testing.T) { + suite.Run(t, new(HandlerTestSuite)) +} + +var _ channelexported.PacketDataI = packetT{} + +type packetT struct { + Data uint64 +} + +func (packet packetT) GetBytes() []byte { + return []byte(fmt.Sprintf("%d", packet.Data)) +} + +func (packetT) GetTimeoutHeight() uint64 { + return 100 +} + +func (packetT) ValidateBasic() error { + return nil +} + +func (packetT) Type() string { + return "valid" +} + +func newPacket(data uint64) packetT { + return packetT{data} +} + +// define variables used for testing +var ( + addr1 = sdk.AccAddress("testaddr1") + + portid = "testportid" + chanid = "testchannel" + cpportid = "testcpport" + cpchanid = "testcpchannel" +) diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index cb095b788a52..6a98669c858e 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -9,7 +9,6 @@ import ( ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -27,7 +26,6 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ibcclient.GetTxCmd(cdc, storeKey), connection.GetTxCmd(cdc, storeKey), channel.GetTxCmd(cdc, storeKey), - transfer.GetTxCmd(cdc), )...) return ibcTxCmd } @@ -47,7 +45,6 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { ibcclient.GetQueryCmd(cdc, queryRoute), connection.GetQueryCmd(cdc, queryRoute), channel.GetQueryCmd(cdc, queryRoute), - transfer.GetQueryCmd(cdc, queryRoute), )...) return ibcQueryCmd } diff --git a/x/ibc/client/rest/rest.go b/x/ibc/client/rest/rest.go index f593ba135760..2e0d96e0ec6d 100644 --- a/x/ibc/client/rest/rest.go +++ b/x/ibc/client/rest/rest.go @@ -7,7 +7,6 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" ) // RegisterRoutes - Central function to define routes that get registered by the main application @@ -15,5 +14,4 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) client.RegisterRESTRoutes(cliCtx, r, queryRoute) connection.RegisterRESTRoutes(cliCtx, r, queryRoute) channel.RegisterRESTRoutes(cliCtx, r, queryRoute) - transfer.RegisterRESTRoutes(cliCtx, r) } diff --git a/x/ibc/handler.go b/x/ibc/handler.go index d7d7262a165e..eb6705888f81 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -6,7 +6,6 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" ) // NewHandler defines the IBC handler @@ -20,7 +19,7 @@ func NewHandler(k Keeper) sdk.Handler { return client.HandleMsgCreateClient(ctx, k.ClientKeeper, msg) case client.MsgUpdateClient: - return client.HandleMsgUpdateClient(ctx, k.ClientKeeper, msg) + return &sdk.Result{}, nil // IBC connection msgs case connection.MsgConnectionOpenInit: @@ -54,13 +53,6 @@ func NewHandler(k Keeper) sdk.Handler { case channel.MsgChannelCloseConfirm: return channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, msg) - // IBC transfer msgs - case transfer.MsgTransfer: - return transfer.HandleMsgTransfer(ctx, k.TransferKeeper, msg) - - case transfer.MsgRecvPacket: - return transfer.HandleMsgRecvPacket(ctx, k.TransferKeeper, msg) - default: return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized IBC message type: %T", msg) } diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 694dae13b9ec..35104f4f3eb1 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -3,7 +3,6 @@ package keeper import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/bank" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -17,7 +16,6 @@ type Keeper struct { ConnectionKeeper connection.Keeper ChannelKeeper channel.Keeper PortKeeper port.Keeper - TransferKeeper transfer.Keeper } // NewKeeper creates a new ibc Keeper @@ -30,18 +28,10 @@ func NewKeeper( portKeeper := port.NewKeeper(cdc, key) channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper) - // TODO: move out of IBC keeper. Blocked on ADR15 - capKey := portKeeper.BindPort(bank.ModuleName) - transferKeeper := transfer.NewKeeper( - cdc, key, capKey, - clientKeeper, connectionKeeper, channelKeeper, bk, sk, - ) - return Keeper{ ClientKeeper: clientKeeper, ConnectionKeeper: connectionKeeper, ChannelKeeper: channelKeeper, PortKeeper: portKeeper, - TransferKeeper: transferKeeper, } } diff --git a/x/ibc/module.go b/x/ibc/module.go index 42da7343d6d6..0dc1093e447a 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -15,7 +15,6 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/client/rest" @@ -43,7 +42,6 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) channel.RegisterCodec(cdc) - transfer.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } @@ -120,7 +118,6 @@ func (am AppModule) NewQuerierHandler() sdk.Querier { // no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { // check if the IBC transfer module account is set - transfer.InitGenesis(ctx, am.keeper.TransferKeeper) return []abci.ValidatorUpdate{} } diff --git a/x/mock/app.go b/x/mock/app.go index 29448e8a9067..aaffad901f91 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -18,7 +18,9 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/ante" authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" + "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/cosmos/cosmos-sdk/x/params" ) @@ -78,7 +80,7 @@ func NewApp() *App { // Initialize the app. The chainers and blockers can be overwritten before // calling complete setup. app.SetInitChainer(app.InitChainer) - app.SetAnteHandler(auth.NewAnteHandler(app.AccountKeeper, supplyKeeper, auth.DefaultSigVerificationGasConsumer)) + app.SetAnteHandler(ante.NewAnteHandler(app.AccountKeeper, supplyKeeper, ibc.Keeper{}, ante.DefaultSigVerificationGasConsumer)) // Not sealing for custom extension From 2ecbfe9226fd826af08cb80aba81b925bd579d0a Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 5 Nov 2019 17:46:15 +0100 Subject: [PATCH 031/176] IBC alpha --- x/ibc/module.go | 1 + 1 file changed, 1 insertion(+) create mode 100644 x/ibc/module.go diff --git a/x/ibc/module.go b/x/ibc/module.go new file mode 100644 index 000000000000..a81836a9c7ed --- /dev/null +++ b/x/ibc/module.go @@ -0,0 +1 @@ +package ibc From 220a482d261e89db6d33c7aa5b86d53153c0a791 Mon Sep 17 00:00:00 2001 From: Joon Date: Tue, 5 Nov 2019 08:53:04 -0800 Subject: [PATCH 032/176] ICS 23 Implementation (#4515) * add mapping * rm unused mapping/*, rm interfaces * rm unused code * mv mapping -> state, rm x/ibc * rm GetIfExists * add key * rm custom encoding/decoding in enum/bool * fix lint * rm tests * add commitment * newtyped remote values * newtyped context * revert context newtype * add README, keypath * reflect downstream ics * add merkle * add test for proving * soft coded root keypath * add update * remove RootUpdate * separate keypath and keuprefix * add codec * separate root/path * add path to codec * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * reformat test * rm XXX * add godoc * add query * update query.go * update query.go * add Query to boolean.go * fix key * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * revise querier interface to work both on cli & store * rm commented lines * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * remove Mapping * remove store accessors * refactor ICS23 * cleanup types * implement batch verification * gosimple suggestion * alias * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * complete types testing * delete empty test file * remove ibc errors from core error package * start batch-verify tests * minor changes on commitment types * use testsuite * upstream changes * context changes --- client/context/context.go | 47 ++++++++ client/context/query.go | 113 ++++++++++++++++--- x/ibc/23-commitment/codec.go | 18 ++++ x/ibc/23-commitment/commitment_test.go | 37 +++++++ x/ibc/23-commitment/merkle.go | 143 +++++++++++++++++++++++++ x/ibc/23-commitment/merkle_test.go | 122 +++++++++++++++++++++ x/ibc/23-commitment/types.go | 65 +++++++++++ x/ibc/23-commitment/verify.go | 62 +++++++++++ x/ibc/24-host/errors.go | 19 ++++ x/ibc/24-host/utils.go | 11 ++ x/ibc/24-host/validate.go | 98 +++++++++++++++++ 11 files changed, 719 insertions(+), 16 deletions(-) create mode 100644 x/ibc/23-commitment/codec.go create mode 100644 x/ibc/23-commitment/commitment_test.go create mode 100644 x/ibc/23-commitment/merkle.go create mode 100644 x/ibc/23-commitment/merkle_test.go create mode 100644 x/ibc/23-commitment/types.go create mode 100644 x/ibc/23-commitment/verify.go create mode 100644 x/ibc/24-host/errors.go create mode 100644 x/ibc/24-host/utils.go create mode 100644 x/ibc/24-host/validate.go diff --git a/client/context/context.go b/client/context/context.go index c778a4345c3c..2814d4dbc491 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -111,6 +111,53 @@ func NewCLIContextWithFrom(from string) CLIContext { return NewCLIContextWithInputAndFrom(os.Stdin, from) } +// NewCLIContextIBC takes additional arguements +func NewCLIContextIBC(from string, chainID string, nodeURI string) CLIContext { + var rpc rpcclient.Client + + genOnly := viper.GetBool(flags.FlagGenerateOnly) + fromAddress, fromName, err := GetFromFields(os.Stdin, from, genOnly) + if err != nil { + fmt.Printf("failed to get from fields: %v", err) + os.Exit(1) + } + + if !genOnly { + if nodeURI != "" { + rpc = rpcclient.NewHTTP(nodeURI, "/websocket") + } + } + + ctx := CLIContext{ + Client: rpc, + ChainID: chainID, + Output: os.Stdout, + NodeURI: nodeURI, + From: from, + OutputFormat: viper.GetString(cli.OutputFlag), + Height: viper.GetInt64(flags.FlagHeight), + HomeDir: viper.GetString(flags.FlagHome), + TrustNode: viper.GetBool(flags.FlagTrustNode), + UseLedger: viper.GetBool(flags.FlagUseLedger), + BroadcastMode: viper.GetString(flags.FlagBroadcastMode), + Simulate: viper.GetBool(flags.FlagDryRun), + GenerateOnly: genOnly, + FromAddress: fromAddress, + FromName: fromName, + Indent: viper.GetBool(flags.FlagIndentResponse), + SkipConfirm: viper.GetBool(flags.FlagSkipConfirmation), + } + + // create a verifier for the specific chain ID and RPC client + verifier, err := CreateVerifier(ctx, DefaultVerifierCacheSize) + if err != nil && viper.IsSet(flags.FlagTrustNode) { + fmt.Printf("failed to create verifier: %s\n", err) + os.Exit(1) + } + + return ctx.WithVerifier(verifier) +} + // NewCLIContext returns a new initialized CLIContext with parameters from the // command line using Viper. func NewCLIContext() CLIContext { return NewCLIContextWithFrom(viper.GetString(flags.FlagFrom)) } diff --git a/client/context/query.go b/client/context/query.go index 2a553d663367..2a01a7577a0c 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -3,6 +3,7 @@ package context import ( "fmt" "strings" + "time" "github.com/pkg/errors" @@ -12,6 +13,7 @@ import ( tmliteErr "github.com/tendermint/tendermint/lite/errors" tmliteProxy "github.com/tendermint/tendermint/lite/proxy" rpcclient "github.com/tendermint/tendermint/rpc/client" + ctypes "github.com/tendermint/tendermint/rpc/core/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/store/rootmulti" @@ -28,6 +30,55 @@ func (ctx CLIContext) GetNode() (rpcclient.Client, error) { return ctx.Client, nil } +// WaitForNBlocks blocks until the node defined on the context has advanced N blocks +func (ctx CLIContext) WaitForNBlocks(n int64) { + node, err := ctx.GetNode() + if err != nil { + panic(err) + } + + resBlock, err := node.Block(nil) + var height int64 + if err != nil || resBlock.Block == nil { + // wait for the first block to exist + ctx.waitForHeight(1) + height = 1 + n + } else { + height = resBlock.Block.Height + n + } + ctx.waitForHeight(height) +} + +func (ctx CLIContext) waitForHeight(height int64) { + node, err := ctx.GetNode() + if err != nil { + panic(err) + } + + for { + // get url, try a few times + var resBlock *ctypes.ResultBlock + var err error + INNER: + for i := 0; i < 5; i++ { + resBlock, err = node.Block(nil) + if err == nil { + break INNER + } + time.Sleep(time.Millisecond * 200) + } + if err != nil { + panic(err) + } + + if resBlock.Block != nil && resBlock.Block.Height >= height { + return + } + + time.Sleep(time.Millisecond * 100) + } +} + // Query performs a query to a Tendermint node with the provided path. // It returns the result and height of the query upon success or an error if // the query fails. @@ -49,6 +100,12 @@ func (ctx CLIContext) QueryStore(key cmn.HexBytes, storeName string) ([]byte, in return ctx.queryStore(key, storeName, "key") } +// QueryABCI performs a query to a Tendermint node with the provide RequestQuery. +// It returns the ResultQuery obtained from the query. +func (ctx CLIContext) QueryABCI(req abci.RequestQuery) (abci.ResponseQuery, error) { + return ctx.queryABCI(req) +} + // QuerySubspace performs a query to a Tendermint node with the provided // store name and subspace. It returns key value pair and height of the query // upon success or an error if the query fails. @@ -72,40 +129,64 @@ func (ctx CLIContext) GetFromName() string { return ctx.FromName } -// query performs a query to a Tendermint node with the provided store name -// and path. It returns the result and height of the query upon success -// or an error if the query fails. In addition, it will verify the returned -// proof if TrustNode is disabled. If proof verification fails or the query -// height is invalid, an error will be returned. -func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, height int64, err error) { +func (ctx CLIContext) queryABCI(req abci.RequestQuery) (resp abci.ResponseQuery, err error) { + node, err := ctx.GetNode() if err != nil { - return res, height, err + return resp, err + } + + // When a client did not provide a query height, manually query for it so it can + // be injected downstream into responses. + if ctx.Height == 0 { + status, err := node.Status() + if err != nil { + return resp, err + } + ctx = ctx.WithHeight(status.SyncInfo.LatestBlockHeight) } opts := rpcclient.ABCIQueryOptions{ Height: ctx.Height, - Prove: !ctx.TrustNode, + Prove: req.Prove || !ctx.TrustNode, } - result, err := node.ABCIQueryWithOptions(path, key, opts) + result, err := node.ABCIQueryWithOptions(req.Path, req.Data, opts) if err != nil { - return res, height, err + return } - resp := result.Response + resp = result.Response if !resp.IsOK() { - return res, resp.Height, errors.New(resp.Log) + err = errors.New(resp.Log) + return } // data from trusted node or subspace query doesn't need verification - if ctx.TrustNode || !isQueryStoreWithProof(path) { - return resp.Value, resp.Height, nil + if ctx.TrustNode || !isQueryStoreWithProof(req.Path) { + return resp, nil } - err = ctx.verifyProof(path, resp) + err = ctx.verifyProof(req.Path, resp) + if err != nil { + return + } + + return +} + +// query performs a query to a Tendermint node with the provided store name +// and path. It returns the result and height of the query upon success +// or an error if the query fails. In addition, it will verify the returned +// proof if TrustNode is disabled. If proof verification fails or the query +// height is invalid, an error will be returned. +func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, height int64, err error) { + resp, err := ctx.queryABCI(abci.RequestQuery{ + Path: path, + Data: key, + }) if err != nil { - return res, resp.Height, err + return } return resp.Value, resp.Height, nil diff --git a/x/ibc/23-commitment/codec.go b/x/ibc/23-commitment/codec.go new file mode 100644 index 000000000000..7e90e8cac69e --- /dev/null +++ b/x/ibc/23-commitment/codec.go @@ -0,0 +1,18 @@ +package commitment + +import ( + "github.com/cosmos/cosmos-sdk/codec" +) + +// RegisterCodec registers types declared in this package +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*RootI)(nil), nil) + cdc.RegisterInterface((*PrefixI)(nil), nil) + cdc.RegisterInterface((*PathI)(nil), nil) + cdc.RegisterInterface((*ProofI)(nil), nil) + + cdc.RegisterConcrete(Root{}, "ibc/commitment/merkle/Root", nil) + cdc.RegisterConcrete(Prefix{}, "ibc/commitment/merkle/Prefix", nil) + cdc.RegisterConcrete(Path{}, "ibc/commitment/merkle/Path", nil) + cdc.RegisterConcrete(Proof{}, "ibc/commitment/merkle/Proof", nil) +} diff --git a/x/ibc/23-commitment/commitment_test.go b/x/ibc/23-commitment/commitment_test.go new file mode 100644 index 000000000000..2535f5705e29 --- /dev/null +++ b/x/ibc/23-commitment/commitment_test.go @@ -0,0 +1,37 @@ +package commitment_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + + dbm "github.com/tendermint/tm-db" +) + +type MerkleTestSuite struct { + suite.Suite + + store *rootmulti.Store + storeKey *storetypes.KVStoreKey + iavlStore *iavl.Store +} + +func (suite *MerkleTestSuite) SetupTest() { + db := dbm.NewMemDB() + suite.store = rootmulti.NewStore(db) + + suite.storeKey = storetypes.NewKVStoreKey("iavlStoreKey") + + suite.store.MountStoreWithDB(suite.storeKey, storetypes.StoreTypeIAVL, nil) + suite.store.LoadVersion(0) + + suite.iavlStore = suite.store.GetCommitStore(suite.storeKey).(*iavl.Store) +} + +func TestMerkleTestSuite(t *testing.T) { + suite.Run(t, new(MerkleTestSuite)) +} diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/merkle.go new file mode 100644 index 000000000000..ab428eeaf737 --- /dev/null +++ b/x/ibc/23-commitment/merkle.go @@ -0,0 +1,143 @@ +package commitment + +import ( + "errors" + + "github.com/tendermint/tendermint/crypto/merkle" + + "github.com/cosmos/cosmos-sdk/store/rootmulti" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +// ICS 023 Merkle Types Implementation +// +// This file defines Merkle commitment types that implements ICS 023. + +// Merkle proof implementation of the Proof interface +// Applied on SDK-based IBC implementation +var _ RootI = Root{} + +// Root defines a merkle root hash. +// In the Cosmos SDK, the AppHash of a block header becomes the Root. +type Root struct { + Hash []byte `json:"hash" yaml:"hash"` +} + +// NewRoot constructs a new Root +func NewRoot(hash []byte) Root { + return Root{ + Hash: hash, + } +} + +// GetCommitmentType implements RootI interface +func (Root) GetCommitmentType() Type { + return Merkle +} + +// GetHash implements RootI interface +func (r Root) GetHash() []byte { + return r.Hash +} + +var _ PrefixI = Prefix{} + +// Prefix is merkle path prefixed to the key. +// The constructed key from the Path and the key will be append(Path.KeyPath, append(Path.KeyPrefix, key...)) +type Prefix struct { + KeyPrefix []byte `json:"key_prefix" yaml:"key_prefix"` // byte slice prefixed before the key +} + +// NewPrefix constructs new Prefix instance +func NewPrefix(keyPrefix []byte) Prefix { + return Prefix{ + KeyPrefix: keyPrefix, + } +} + +// GetCommitmentType implements PrefixI +func (Prefix) GetCommitmentType() Type { + return Merkle +} + +// Bytes returns the key prefix bytes +func (p Prefix) Bytes() []byte { + return p.KeyPrefix +} + +var _ PathI = Path{} + +// Path is the path used to verify commitment proofs, which can be an arbitrary +// structured object (defined by a commitment type). +type Path struct { + KeyPath merkle.KeyPath `json:"key_path" yaml:"key_path"` // byte slice prefixed before the key +} + +// NewPath creates a new CommitmentPath instance +func NewPath(keyPathStr []string) Path { + merkleKeyPath := merkle.KeyPath{} + for _, keyStr := range keyPathStr { + merkleKeyPath = merkleKeyPath.AppendKey([]byte(keyStr), merkle.KeyEncodingURL) + } + + return Path{ + KeyPath: merkleKeyPath, + } +} + +// GetCommitmentType implements PathI +func (Path) GetCommitmentType() Type { + return Merkle +} + +// String implements fmt.Stringer +func (p Path) String() string { + return p.KeyPath.String() +} + +// ApplyPrefix constructs a new commitment path from the arguments. It interprets +// the path argument in the context of the prefix argument. +// +// CONTRACT: provided path string MUST be a well formated path. See ICS24 for +// reference. +func ApplyPrefix(prefix PrefixI, path string) (Path, error) { + err := host.DefaultPathValidator(path) + if err != nil { + return Path{}, err + } + + if prefix == nil || len(prefix.Bytes()) == 0 { + return Path{}, errors.New("prefix can't be empty") + } + + return NewPath([]string{string(prefix.Bytes()), path}), nil +} + +var _ ProofI = Proof{} + +// Proof is a wrapper type that contains a merkle proof. +// It demonstrates membership or non-membership for an element or set of elements, +// verifiable in conjunction with a known commitment root. Proofs should be +// succinct. +type Proof struct { + Proof *merkle.Proof `json:"proof" yaml:"proof"` +} + +// GetCommitmentType implements ProofI +func (Proof) GetCommitmentType() Type { + return Merkle +} + +// VerifyMembership verifies the membership pf a merkle proof against the given root, path, and value. +func (proof Proof) VerifyMembership(root RootI, path PathI, value []byte) bool { + runtime := rootmulti.DefaultProofRuntime() + err := runtime.VerifyValue(proof.Proof, root.GetHash(), path.String(), value) + return err == nil +} + +// VerifyNonMembership verifies the absence of a merkle proof against the given root and path. +func (proof Proof) VerifyNonMembership(root RootI, path PathI) bool { + runtime := rootmulti.DefaultProofRuntime() + err := runtime.VerifyAbsence(proof.Proof, root.GetHash(), path.String()) + return err == nil +} diff --git a/x/ibc/23-commitment/merkle_test.go b/x/ibc/23-commitment/merkle_test.go new file mode 100644 index 000000000000..bfd2dc5a485c --- /dev/null +++ b/x/ibc/23-commitment/merkle_test.go @@ -0,0 +1,122 @@ +package commitment_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + + abci "github.com/tendermint/tendermint/abci/types" +) + +func (suite *MerkleTestSuite) TestVerifyMembership() { + suite.iavlStore.Set([]byte("MYKEY"), []byte("MYVALUE")) + cid := suite.store.Commit() + + res := suite.store.Query(abci.RequestQuery{ + Path: fmt.Sprintf("/%s/key", suite.storeKey.Name()), // required path to get key/value+proof + Data: []byte("MYKEY"), + Prove: true, + }) + require.NotNil(suite.T(), res.Proof) + + proof := commitment.Proof{ + Proof: res.Proof, + } + + cases := []struct { + name string + root []byte + pathArr []string + value []byte + shouldPass bool + }{ + {"valid proof", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, []byte("MYVALUE"), true}, // valid proof + {"wrong value", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, []byte("WRONGVALUE"), false}, // invalid proof with wrong value + {"nil value", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, []byte(nil), false}, // invalid proof with nil value + {"wrong key", cid.Hash, []string{suite.storeKey.Name(), "NOTMYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong key + {"wrong path 1", cid.Hash, []string{suite.storeKey.Name(), "MYKEY", "MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong path + {"wrong path 2", cid.Hash, []string{suite.storeKey.Name()}, []byte("MYVALUE"), false}, // invalid proof with wrong path + {"wrong path 3", cid.Hash, []string{"MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong path + {"wrong storekey", cid.Hash, []string{"otherStoreKey", "MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong store prefix + {"wrong root", []byte("WRONGROOT"), []string{suite.storeKey.Name(), "MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with wrong root + {"nil root", []byte(nil), []string{suite.storeKey.Name(), "MYKEY"}, []byte("MYVALUE"), false}, // invalid proof with nil root + } + + for i, tc := range cases { + suite.Run(tc.name, func() { + root := commitment.NewRoot(tc.root) + path := commitment.NewPath(tc.pathArr) + + ok := proof.VerifyMembership(root, path, tc.value) + + require.True(suite.T(), ok == tc.shouldPass, "Test case %d failed", i) + }) + } + +} + +func (suite *MerkleTestSuite) TestVerifyNonMembership() { + suite.iavlStore.Set([]byte("MYKEY"), []byte("MYVALUE")) + cid := suite.store.Commit() + + // Get Proof + res := suite.store.Query(abci.RequestQuery{ + Path: fmt.Sprintf("/%s/key", suite.storeKey.Name()), // required path to get key/value+proof + Data: []byte("MYABSENTKEY"), + Prove: true, + }) + require.NotNil(suite.T(), res.Proof) + + proof := commitment.Proof{ + Proof: res.Proof, + } + + cases := []struct { + name string + root []byte + pathArr []string + shouldPass bool + }{ + {"valid proof", cid.Hash, []string{suite.storeKey.Name(), "MYABSENTKEY"}, true}, // valid proof + {"wrong key", cid.Hash, []string{suite.storeKey.Name(), "MYKEY"}, false}, // invalid proof with existent key + {"wrong path 1", cid.Hash, []string{suite.storeKey.Name(), "MYKEY", "MYABSENTKEY"}, false}, // invalid proof with wrong path + {"wrong path 2", cid.Hash, []string{suite.storeKey.Name(), "MYABSENTKEY", "MYKEY"}, false}, // invalid proof with wrong path + {"wrong path 3", cid.Hash, []string{suite.storeKey.Name()}, false}, // invalid proof with wrong path + {"wrong path 4", cid.Hash, []string{"MYABSENTKEY"}, false}, // invalid proof with wrong path + {"wrong storeKey", cid.Hash, []string{"otherStoreKey", "MYABSENTKEY"}, false}, // invalid proof with wrong store prefix + {"wrong root", []byte("WRONGROOT"), []string{suite.storeKey.Name(), "MYABSENTKEY"}, false}, // invalid proof with wrong root + {"nil root", []byte(nil), []string{suite.storeKey.Name(), "MYABSENTKEY"}, false}, // invalid proof with nil root + } + + for i, tc := range cases { + suite.Run(tc.name, func() { + root := commitment.NewRoot(tc.root) + path := commitment.NewPath(tc.pathArr) + + ok := proof.VerifyNonMembership(root, path) + + require.True(suite.T(), ok == tc.shouldPass, "Test case %d failed", i) + }) + } + +} + +func TestApplyPrefix(t *testing.T) { + prefix := commitment.NewPrefix([]byte("storePrefixKey")) + + pathStr := "path1/path2/path3/key" + + prefixedPath, err := commitment.ApplyPrefix(prefix, pathStr) + require.Nil(t, err, "valid prefix returns error") + + require.Equal(t, "/storePrefixKey/path1/path2/path3/key", prefixedPath.String(), "Prefixed path incorrect") + + // invalid prefix contains non-alphanumeric character + invalidPathStr := "invalid-path/doesitfail?/hopefully" + invalidPath, err := commitment.ApplyPrefix(prefix, invalidPathStr) + require.NotNil(t, err, "invalid prefix does not returns error") + require.Equal(t, commitment.Path{}, invalidPath, "invalid prefix returns valid Path on ApplyPrefix") +} diff --git a/x/ibc/23-commitment/types.go b/x/ibc/23-commitment/types.go new file mode 100644 index 000000000000..1b70f4f04d9c --- /dev/null +++ b/x/ibc/23-commitment/types.go @@ -0,0 +1,65 @@ +package commitment + +// ICS 023 Types Implementation +// +// This file includes types defined under +// https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments + +// spec:Path and spec:Value are defined as bytestring + +// RootI implements spec:CommitmentRoot. +// A root is constructed from a set of key-value pairs, +// and the inclusion or non-inclusion of an arbitrary key-value pair +// can be proven with the proof. +type RootI interface { + GetCommitmentType() Type + GetHash() []byte +} + +// PrefixI implements spec:CommitmentPrefix. +// Prefix represents the common "prefix" that a set of keys shares. +type PrefixI interface { + GetCommitmentType() Type + Bytes() []byte +} + +// PathI implements spec:CommitmentPath. +// A path is the additional information provided to the verification function. +type PathI interface { + GetCommitmentType() Type + String() string +} + +// ProofI implements spec:CommitmentProof. +// Proof can prove whether the key-value pair is a part of the Root or not. +// Each proof has designated key-value pair it is able to prove. +// Proofs includes key but value is provided dynamically at the verification time. +type ProofI interface { + GetCommitmentType() Type + VerifyMembership(RootI, PathI, []byte) bool + VerifyNonMembership(RootI, PathI) bool +} + +// Type defines the type of the commitment +type Type byte + +// Registered commitment types +const ( + Merkle Type = iota + 1 // 1 +) + +// string representation of the commitment types +const ( + TypeMerkle string = "merkle" +) + +// String implements the Stringer interface +func (ct Type) String() string { + switch ct { + case Merkle: + return TypeMerkle + + default: + return "" + } +} diff --git a/x/ibc/23-commitment/verify.go b/x/ibc/23-commitment/verify.go new file mode 100644 index 000000000000..7c620c2b5a90 --- /dev/null +++ b/x/ibc/23-commitment/verify.go @@ -0,0 +1,62 @@ +package commitment + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// CalculateRoot returns the application Hash at the curretn block height as a commitment +// root for proof verification. +func CalculateRoot(ctx sdk.Context) RootI { + return NewRoot(ctx.BlockHeader().AppHash) +} + +// BatchVerifyMembership verifies a proof that many paths have been set to +// specific values in a commitment. It calls the proof's VerifyMembership method +// with the calculated root and the provided paths. +// Returns false on the first failed membership verification. +func BatchVerifyMembership( + ctx sdk.Context, + proof ProofI, + prefix PrefixI, + items map[string][]byte, +) bool { + root := CalculateRoot(ctx) + + for pathStr, value := range items { + path, err := ApplyPrefix(prefix, pathStr) + if err != nil { + return false + } + + if ok := proof.VerifyMembership(root, path, value); !ok { + return false + } + } + + return true +} + +// BatchVerifyNonMembership verifies a proof that many paths have not been set +// to any value in a commitment. It calls the proof's VerifyNonMembership method +// with the calculated root and the provided paths. +// Returns false on the first failed non-membership verification. +func BatchVerifyNonMembership( + ctx sdk.Context, + proof ProofI, + prefix PrefixI, + paths []string, +) bool { + root := CalculateRoot(ctx) + for _, pathStr := range paths { + path, err := ApplyPrefix(prefix, pathStr) + if err != nil { + return false + } + + if ok := proof.VerifyNonMembership(root, path); !ok { + return false + } + } + + return true +} diff --git a/x/ibc/24-host/errors.go b/x/ibc/24-host/errors.go new file mode 100644 index 000000000000..afc1c26ea303 --- /dev/null +++ b/x/ibc/24-host/errors.go @@ -0,0 +1,19 @@ +package host + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// IBCCodeSpace is the codespace for all errors defined in the ibc module +const IBCCodeSpace = "ibc" + +var ( + // ErrInvalidID is returned if identifier string is invalid + ErrInvalidID = sdkerrors.Register(IBCCodeSpace, 1, "invalid identifier") + + // ErrInvalidPath is returned if path string is invalid + ErrInvalidPath = sdkerrors.Register(IBCCodeSpace, 2, "invalid path") + + // ErrInvalidPacket is returned if packets embedded in msg are invalid + ErrInvalidPacket = sdkerrors.Register(IBCCodeSpace, 3, "invalid packet extracted from msg") +) diff --git a/x/ibc/24-host/utils.go b/x/ibc/24-host/utils.go new file mode 100644 index 000000000000..c75f356561f6 --- /dev/null +++ b/x/ibc/24-host/utils.go @@ -0,0 +1,11 @@ +package host + +// RemovePath is an util function to remove a path from a set. +func RemovePath(paths []string, path string) ([]string, bool) { + for i, p := range paths { + if p == path { + return append(paths[:i], paths[i+1:]...), true + } + } + return paths, false +} diff --git a/x/ibc/24-host/validate.go b/x/ibc/24-host/validate.go new file mode 100644 index 000000000000..6632d27c25c1 --- /dev/null +++ b/x/ibc/24-host/validate.go @@ -0,0 +1,98 @@ +package host + +import ( + "regexp" + "strings" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// ICS 024 Identifier and Path Validation Implementation +// +// This file defines ValidateFn to validate identifier and path strings +// The spec for ICS 024 can be located here: +// https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements + +// regular expression to check string is lowercase alphabetic characters only +var isAlphaLower = regexp.MustCompile(`^[a-z]+$`).MatchString + +// regular expression to check string is alphanumeric +var isAlphaNumeric = regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString + +// ValidateFn function type to validate path and identifier bytestrings +type ValidateFn func(string) error + +func defaultIdentifierValidator(id string, min, max int) error { + // valid id MUST NOT contain "/" separator + if strings.Contains(id, "/") { + return sdkerrors.Wrap(ErrInvalidID, "identifier cannot contain separator: /") + } + // valid id must be between 10 and 20 characters + if len(id) < min || len(id) > max { + return sdkerrors.Wrapf(ErrInvalidID, "identifier has invalid length: %d, must be between %d-%d characters", len(id), min, max) + } + // valid id must contain only lower alphabetic characters + if !isAlphaLower(id) { + return sdkerrors.Wrap(ErrInvalidID, "identifier must contain only lowercase alphabetic characters") + } + return nil +} + +// DefaultClientIdentifierValidator is the default validator function for Client identifiers +// A valid Identifier must be between 10-20 characters and only contain lowercase +// alphabetic characters, +func DefaultClientIdentifierValidator(id string) error { + return defaultIdentifierValidator(id, 10, 20) +} + +// DefaultConnectionIdentifierValidator is the default validator function for Connection identifiers +// A valid Identifier must be between 10-20 characters and only contain lowercase +// alphabetic characters, +func DefaultConnectionIdentifierValidator(id string) error { + return defaultIdentifierValidator(id, 10, 20) +} + +// DefaultChannelIdentifierValidator is the default validator function for Channel identifiers +// A valid Identifier must be between 10-20 characters and only contain lowercase +// alphabetic characters, +func DefaultChannelIdentifierValidator(id string) error { + return defaultIdentifierValidator(id, 10, 20) +} + +// DefaultPortIdentifierValidator is the default validator function for Port identifiers +// A valid Identifier must be between 2-20 characters and only contain lowercase +// alphabetic characters, +func DefaultPortIdentifierValidator(id string) error { + return defaultIdentifierValidator(id, 2, 20) +} + +// NewPathValidator takes in a Identifier Validator function and returns +// a Path Validator function which requires path only has valid identifiers +// alphanumeric character strings, and "/" separators +func NewPathValidator(idValidator ValidateFn) ValidateFn { + return func(path string) error { + pathArr := strings.Split(path, "/") + for _, p := range pathArr { + // Each path element must either be valid identifier or alphanumeric + err := idValidator(p) + if err != nil && !isAlphaNumeric(p) { + return sdkerrors.Wrapf(ErrInvalidPath, "path contains invalid identifier or non-alphanumeric path element: %s", p) + } + } + return nil + } +} + +// DefaultPathValidator takes in path string and validates +// with default identifier rules. This is optimized by simply +// checking that all path elements are alphanumeric +func DefaultPathValidator(path string) error { + pathArr := strings.Split(path, "/") + for _, p := range pathArr { + // Each path element must either be alphanumeric + if !isAlphaNumeric(p) { + return sdkerrors.Wrapf(ErrInvalidPath, "invalid path element containing non-alphanumeric characters: %s", p) + } + } + return nil +} From 35e0428c6a7700dc6f131cd08e08ef6090f186d7 Mon Sep 17 00:00:00 2001 From: Joon Date: Tue, 5 Nov 2019 08:56:38 -0800 Subject: [PATCH 033/176] ICS 02 Implementation (#4516) * add mapping * rm unused mapping/*, rm interfaces * rm unused code * mv mapping -> state, rm x/ibc * rm GetIfExists * add key * rm custom encoding/decoding in enum/bool * fix lint * rm tests * add commitment * newtyped remote values * newtyped context * revert context newtype * add README, keypath * reflect downstream ics * add merkle * add test for proving * soft coded root keypath * add update * remove RootUpdate * separate keypath and keuprefix * add codec * separate root/path * add path to codec * add client * add counterpartymanager * fix manager * add Is() to counterobject * add readme, reflect ICS02 revision * reflect downstream ics * test in progress * add test * in progres * fin rebase * in progress * fin rebase * add CLIObject in progress * cli in progress * add CLIObject * separate testing from tendermint * add key to node * add root and storekey to tests/node, add codec * rm cli/query.go * fix test * fix lint * fix lint * add handler/msgs/client * rm relay * finalize rebase on 23 root/path sep * fix lint, fix syntax * rm freebase, reformat query * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * add godoc in progress * reformat test * rm XXX * add godoc * modify store * add query * update query.go * update query.go * cli refactor in progress * cli refactor in progress * add Query to boolean.go * fix key * fix cli / merkle test * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * fix dependency * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * rm commented lines * address review in progress * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * add verification functions * ICS02 module.go * top level x/ibc structure * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling * start batch-verify tests * minor changes on commitment types * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * use testsuite * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes --- x/ibc/02-client/alias.go | 85 ++++++ x/ibc/02-client/client/cli/query.go | 258 ++++++++++++++++++ x/ibc/02-client/client/cli/tx.go | 172 ++++++++++++ x/ibc/02-client/client/utils/utils.go | 75 +++++ x/ibc/02-client/doc.go | 10 + x/ibc/02-client/exported/exported.go | 123 +++++++++ x/ibc/02-client/handler.go | 78 ++++++ x/ibc/02-client/keeper/client.go | 104 +++++++ x/ibc/02-client/keeper/keeper.go | 205 ++++++++++++++ x/ibc/02-client/keeper/querier.go | 77 ++++++ x/ibc/02-client/module.go | 32 +++ x/ibc/02-client/types/codec.go | 30 ++ x/ibc/02-client/types/errors/errors.go | 73 +++++ x/ibc/02-client/types/events.go | 21 ++ x/ibc/02-client/types/keys.go | 67 +++++ x/ibc/02-client/types/msgs.go | 173 ++++++++++++ x/ibc/02-client/types/msgs_test.go | 140 ++++++++++ x/ibc/02-client/types/querier.go | 66 +++++ x/ibc/02-client/types/state.go | 24 ++ x/ibc/02-client/types/tendermint/codec.go | 18 ++ .../types/tendermint/consensus_state.go | 89 ++++++ .../types/tendermint/consensus_state_test.go | 52 ++++ x/ibc/02-client/types/tendermint/doc.go | 5 + x/ibc/02-client/types/tendermint/header.go | 28 ++ .../types/tendermint/misbehaviour.go | 96 +++++++ .../types/tendermint/misbehaviour_test.go | 64 +++++ .../types/tendermint/tendermint_test.go | 87 ++++++ .../02-client/types/tendermint/test_utils.go | 47 ++++ x/ibc/24-host/errors.go | 5 +- x/ibc/alias.go | 29 ++ x/ibc/client/cli/cli.go | 43 +++ x/ibc/handler.go | 30 ++ x/ibc/keeper/keeper.go | 19 ++ x/ibc/keeper/querier.go | 24 ++ x/ibc/module.go | 131 +++++++++ x/ibc/types/types.go | 15 + x/ibc/version/version.go | 13 + 37 files changed, 2607 insertions(+), 1 deletion(-) create mode 100644 x/ibc/02-client/alias.go create mode 100644 x/ibc/02-client/client/cli/query.go create mode 100644 x/ibc/02-client/client/cli/tx.go create mode 100644 x/ibc/02-client/client/utils/utils.go create mode 100644 x/ibc/02-client/doc.go create mode 100644 x/ibc/02-client/exported/exported.go create mode 100644 x/ibc/02-client/handler.go create mode 100644 x/ibc/02-client/keeper/client.go create mode 100644 x/ibc/02-client/keeper/keeper.go create mode 100644 x/ibc/02-client/keeper/querier.go create mode 100644 x/ibc/02-client/module.go create mode 100644 x/ibc/02-client/types/codec.go create mode 100644 x/ibc/02-client/types/errors/errors.go create mode 100644 x/ibc/02-client/types/events.go create mode 100644 x/ibc/02-client/types/keys.go create mode 100644 x/ibc/02-client/types/msgs.go create mode 100644 x/ibc/02-client/types/msgs_test.go create mode 100644 x/ibc/02-client/types/querier.go create mode 100644 x/ibc/02-client/types/state.go create mode 100644 x/ibc/02-client/types/tendermint/codec.go create mode 100644 x/ibc/02-client/types/tendermint/consensus_state.go create mode 100644 x/ibc/02-client/types/tendermint/consensus_state_test.go create mode 100644 x/ibc/02-client/types/tendermint/doc.go create mode 100644 x/ibc/02-client/types/tendermint/header.go create mode 100644 x/ibc/02-client/types/tendermint/misbehaviour.go create mode 100644 x/ibc/02-client/types/tendermint/misbehaviour_test.go create mode 100644 x/ibc/02-client/types/tendermint/tendermint_test.go create mode 100644 x/ibc/02-client/types/tendermint/test_utils.go create mode 100644 x/ibc/alias.go create mode 100644 x/ibc/client/cli/cli.go create mode 100644 x/ibc/handler.go create mode 100644 x/ibc/keeper/keeper.go create mode 100644 x/ibc/keeper/querier.go create mode 100644 x/ibc/types/types.go create mode 100644 x/ibc/version/version.go diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go new file mode 100644 index 000000000000..00519d9da512 --- /dev/null +++ b/x/ibc/02-client/alias.go @@ -0,0 +1,85 @@ +package client + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/02-client/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" +) + +const ( + DefaultCodespace = errors.DefaultCodespace + CodeClientExists = errors.CodeClientExists + CodeClientNotFound = errors.CodeClientNotFound + CodeClientFrozen = errors.CodeClientFrozen + CodeConsensusStateNotFound = errors.CodeConsensusStateNotFound + CodeInvalidConsensusState = errors.CodeInvalidConsensusState + CodeClientTypeNotFound = errors.CodeClientTypeNotFound + CodeInvalidClientType = errors.CodeInvalidClientType + CodeRootNotFound = errors.CodeRootNotFound + CodeInvalidHeader = errors.CodeInvalidHeader + CodeInvalidEvidence = errors.CodeInvalidEvidence + AttributeKeyClientID = types.AttributeKeyClientID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryClientState = types.QueryClientState + QueryConsensusState = types.QueryConsensusState + QueryVerifiedRoot = types.QueryVerifiedRoot +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + QuerierClientState = keeper.QuerierClientState + QuerierConsensusState = keeper.QuerierConsensusState + QuerierVerifiedRoot = keeper.QuerierVerifiedRoot + RegisterCodec = types.RegisterCodec + ErrClientExists = errors.ErrClientExists + ErrClientNotFound = errors.ErrClientNotFound + ErrClientFrozen = errors.ErrClientFrozen + ErrConsensusStateNotFound = errors.ErrConsensusStateNotFound + ErrInvalidConsensus = errors.ErrInvalidConsensus + ErrClientTypeNotFound = errors.ErrClientTypeNotFound + ErrInvalidClientType = errors.ErrInvalidClientType + ErrRootNotFound = errors.ErrRootNotFound + ErrInvalidHeader = errors.ErrInvalidHeader + ErrInvalidEvidence = errors.ErrInvalidEvidence + ClientStatePath = types.ClientStatePath + ClientTypePath = types.ClientTypePath + ConsensusStatePath = types.ConsensusStatePath + RootPath = types.RootPath + KeyClientState = types.KeyClientState + KeyClientType = types.KeyClientType + KeyConsensusState = types.KeyConsensusState + KeyRoot = types.KeyRoot + NewMsgCreateClient = types.NewMsgCreateClient + NewMsgUpdateClient = types.NewMsgUpdateClient + NewMsgSubmitMisbehaviour = types.NewMsgSubmitMisbehaviour + NewQueryClientStateParams = types.NewQueryClientStateParams + NewQueryCommitmentRootParams = types.NewQueryCommitmentRootParams + NewClientState = types.NewClientState + + // variable aliases + SubModuleCdc = types.SubModuleCdc + EventTypeCreateClient = types.EventTypeCreateClient + EventTypeUpdateClient = types.EventTypeUpdateClient + EventTypeSubmitMisbehaviour = types.EventTypeSubmitMisbehaviour + AttributeValueCategory = types.AttributeValueCategory +) + +type ( + Keeper = keeper.Keeper + MsgCreateClient = types.MsgCreateClient + MsgUpdateClient = types.MsgUpdateClient + MsgSubmitMisbehaviour = types.MsgSubmitMisbehaviour + QueryClientStateParams = types.QueryClientStateParams + QueryCommitmentRootParams = types.QueryCommitmentRootParams + State = types.State +) diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go new file mode 100644 index 000000000000..6f6a487bbbf6 --- /dev/null +++ b/x/ibc/02-client/client/cli/query.go @@ -0,0 +1,258 @@ +package cli + +import ( + "errors" + "fmt" + "strconv" + "strings" + + "github.com/spf13/cobra" + + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// GetQueryCmd returns the query commands for IBC clients +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + ics02ClientQueryCmd := &cobra.Command{ + Use: "client", + Short: "IBC client query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics02ClientQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryConsensusState(queryRoute, cdc), + GetCmdQueryHeader(cdc), + GetCmdQueryClientState(queryRoute, cdc), + GetCmdQueryRoot(queryRoute, cdc), + GetCmdNodeConsensusState(queryRoute, cdc), + GetCmdQueryPath(queryRoute, cdc), + )...) + return ics02ClientQueryCmd +} + +// GetCmdQueryClientState defines the command to query the state of a client with +// a given id as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query +func GetCmdQueryClientState(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "state [client-id]", + Short: "Query a client state", + Long: strings.TrimSpace( + fmt.Sprintf(`Query stored client state + +Example: +$ %s query ibc client state [client-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + if strings.TrimSpace(clientID) == "" { + return errors.New("client ID can't be blank") + } + + bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) + if err != nil { + return err + } + + res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), bz) + if err != nil { + return err + } + + var clientState types.State + if err := cdc.UnmarshalJSON(res, &clientState); err != nil { + return err + } + + return cliCtx.PrintOutput(clientState) + }, + } +} + +// GetCmdQueryRoot defines the command to query +func GetCmdQueryRoot(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "root [client-id] [height]", + Short: "Query a verified commitment root", + Long: strings.TrimSpace( + fmt.Sprintf(`Query an already verified commitment root at a specific height for a particular client + +Example: +$ %s query ibc client root [client-id] [height] +`, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + if strings.TrimSpace(clientID) == "" { + return errors.New("client ID can't be blank") + } + + height, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return fmt.Errorf("expected integer height, got: %v", args[1]) + } + + bz, err := cdc.MarshalJSON(types.NewQueryCommitmentRootParams(clientID, height)) + if err != nil { + return err + } + + res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryVerifiedRoot), bz) + if err != nil { + return err + } + + var root commitment.RootI + if err := cdc.UnmarshalJSON(res, &root); err != nil { + return err + } + + return cliCtx.PrintOutput(root) + }, + } +} + +// GetCmdQueryConsensusState defines the command to query the consensus state of +// the chain as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query +func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "consensus-state [client-id]", + Short: "Query the latest consensus state of the client", + Long: strings.TrimSpace( + fmt.Sprintf(`Query the consensus state for a particular client + +Example: +$ %s query ibc client consensus-state [client-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + if strings.TrimSpace(clientID) == "" { + return errors.New("client ID can't be blank") + } + + bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) + if err != nil { + return err + } + + res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryConsensusState), bz) + if err != nil { + return err + } + + var consensusState exported.ConsensusState + if err := cdc.UnmarshalJSON(res, &consensusState); err != nil { + return err + } + + return cliCtx.PrintOutput(consensusState) + }, + } +} + +// GetCmdQueryHeader defines the command to query the latest header on the chain +func GetCmdQueryHeader(cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "header", + Short: "Query the latest header of the running chain", + Long: strings.TrimSpace(fmt.Sprintf(`Query the latest Tendermint header + +Example: +$ %s query ibc client header + `, version.ClientName), + ), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + + header, err := utils.GetTendermintHeader(cliCtx) + if err != nil { + return err + } + + return cliCtx.PrintOutput(header) + }, + } +} + +// GetCmdNodeConsensusState defines the command to query the latest consensus state of a node +// The result is feed to client creation +func GetCmdNodeConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "node-state", + Short: "Query a node consensus state", + Long: strings.TrimSpace( + fmt.Sprintf(`Query a node consensus state. This result is feed to the client creation transaction. + +Example: +$ %s query ibc client node-state + `, version.ClientName), + ), + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + + node, err := cliCtx.GetNode() + if err != nil { + return err + } + + info, err := node.ABCIInfo() + if err != nil { + return err + } + + height := info.Response.LastBlockHeight + prevHeight := height - 1 + + commit, err := node.Commit(&height) + if err != nil { + return err + } + + validators, err := node.Validators(&prevHeight) + if err != nil { + return err + } + + state := tendermint.ConsensusState{ + ChainID: commit.ChainID, + Height: uint64(commit.Height), + Root: commitment.NewRoot(commit.AppHash), + NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), + } + + return cliCtx.PrintOutput(state) + }, + } +} + +// GetCmdQueryPath defines the command to query the commitment path. +func GetCmdQueryPath(storeName string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "path", + Short: "Query the commitment path of the running chain", + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCLIContext().WithCodec(cdc) + path := commitment.NewPrefix([]byte("ibc")) + return ctx.PrintOutput(path) + }, + } +} diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go new file mode 100644 index 000000000000..4cbc97b39842 --- /dev/null +++ b/x/ibc/02-client/client/cli/tx.go @@ -0,0 +1,172 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" +) + +// GetTxCmd returns the transaction commands for IBC Clients +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics02ClientTxCmd := &cobra.Command{ + Use: "client", + Short: "Client transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics02ClientTxCmd.AddCommand(client.PostCommands( + GetCmdCreateClient(cdc), + GetCmdUpdateClient(cdc), + )...) + + return ics02ClientTxCmd +} + +// GetCmdCreateClient defines the command to create a new IBC Client as defined +// in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create +func GetCmdCreateClient(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "create [client-id] [path/to/consensus_state.json]", + Short: "create new client with a consensus state", + Long: strings.TrimSpace(fmt.Sprintf(`create new client with a specified identifier and consensus state: + +Example: +$ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node0 --home ../node0/cli --chain-id $CID + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + + clientID := args[0] + + var state exported.ConsensusState + if err := cdc.UnmarshalJSON([]byte(args[1]), &state); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + + contents, err := ioutil.ReadFile(args[1]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &state); err != nil { + return fmt.Errorf("error unmarshalling consensus state file: %v", err) + } + } + + msg := types.NewMsgCreateClient( + clientID, state.ClientType().String(), state, + cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdUpdateClient defines the command to update a client as defined in +// https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#update +func GetCmdUpdateClient(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "update [client-id] [path/to/header.json]", + Short: "update existing client with a header", + Long: strings.TrimSpace(fmt.Sprintf(`update existing client with a header: + +Example: +$ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home ../node0/cli --chain-id $CID + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + clientID := args[0] + + var header exported.Header + if err := cdc.UnmarshalJSON([]byte(args[1]), &header); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + + contents, err := ioutil.ReadFile(args[1]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &header); err != nil { + return fmt.Errorf("error unmarshalling header file: %v", err) + } + } + + msg := types.NewMsgUpdateClient(clientID, header, cliCtx.GetFromAddress()) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdSubmitMisbehaviour defines the command to submit a misbehaviour to invalidate +// previous state roots and prevent future updates as defined in +// https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#misbehaviour +func GetCmdSubmitMisbehaviour(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "misbehaviour [client-it] [path/to/evidence.json]", + Short: "submit a client misbehaviour", + Long: strings.TrimSpace(fmt.Sprintf(`submit a client misbehaviour to invalidate to invalidate previous state roots and prevent future updates: + +Example: +$ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 --home ../node0/cli --chain-id $CID + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + clientID := args[0] + + var evidence exported.Evidence + if err := cdc.UnmarshalJSON([]byte(args[1]), &evidence); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + + contents, err := ioutil.ReadFile(args[1]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &evidence); err != nil { + return fmt.Errorf("error unmarshalling evidence file: %v", err) + } + } + + msg := types.NewMsgSubmitMisbehaviour(clientID, evidence, cliCtx.GetFromAddress()) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go new file mode 100644 index 000000000000..5d0786267373 --- /dev/null +++ b/x/ibc/02-client/client/utils/utils.go @@ -0,0 +1,75 @@ +package utils + +import ( + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" +) + +// QueryConsensusStateProof queries the store to get the consensus state and a +// merkle proof. +func QueryConsensusStateProof(cliCtx client.CLIContext, clientID string) (types.ConsensusStateResponse, error) { + var conStateRes types.ConsensusStateResponse + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: []byte(fmt.Sprintf("clients/%s/consensusState", clientID)), + Prove: true, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return conStateRes, err + } + + var cs tendermint.ConsensusState + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { + return conStateRes, err + } + return types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height), nil +} + +// GetTendermintHeader takes a client context and returns the appropriate +// tendermint header +func GetTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, error) { + node, err := cliCtx.GetNode() + if err != nil { + return tendermint.Header{}, err + } + + info, err := node.ABCIInfo() + if err != nil { + return tendermint.Header{}, err + } + + height := info.Response.LastBlockHeight + prevheight := height - 1 + + commit, err := node.Commit(&height) + if err != nil { + return tendermint.Header{}, err + } + + validators, err := node.Validators(&prevheight) + if err != nil { + return tendermint.Header{}, err + } + + nextvalidators, err := node.Validators(&height) + if err != nil { + return tendermint.Header{}, err + } + + header := tendermint.Header{ + SignedHeader: commit.SignedHeader, + ValidatorSet: tmtypes.NewValidatorSet(validators.Validators), + NextValidatorSet: tmtypes.NewValidatorSet(nextvalidators.Validators), + } + + return header, nil +} diff --git a/x/ibc/02-client/doc.go b/x/ibc/02-client/doc.go new file mode 100644 index 000000000000..2b6952ba97eb --- /dev/null +++ b/x/ibc/02-client/doc.go @@ -0,0 +1,10 @@ +/* +Package client implements the ICS 02 - Client Semenatics specification +https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics. This +concrete implementations defines types and method to store and update light +clients which tracks on other chain's state. + +The main type is `Client`, which provides `commitment.Root` to verify state proofs and `ConsensusState` to +verify header proofs. +*/ +package client diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go new file mode 100644 index 000000000000..e7d1ac5c5411 --- /dev/null +++ b/x/ibc/02-client/exported/exported.go @@ -0,0 +1,123 @@ +package exported + +import ( + "encoding/json" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + cmn "github.com/tendermint/tendermint/libs/common" +) + +// Blockchain is consensus algorithm which generates valid Headers. It generates +// a unique list of headers starting from a genesis ConsensusState with arbitrary messages. +// This interface is implemented as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#blockchain. +type Blockchain interface { + Genesis() ConsensusState // Consensus state defined in the genesis + Consensus() Header // Header generating function +} + +// ConsensusState is the state of the consensus process +type ConsensusState interface { + ClientType() ClientType // Consensus kind + GetHeight() uint64 + + // GetRoot returns the commitment root of the consensus state, + // which is used for key-value pair verification. + GetRoot() commitment.RootI + + // CheckValidityAndUpdateState returns the updated consensus state + // only if the header is a descendent of this consensus state. + CheckValidityAndUpdateState(Header) (ConsensusState, error) +} + +// Evidence from ADR 009: Evidence Module +// TODO: use evidence module interface once merged +type Evidence interface { + Route() string + Type() string + String() string + Hash() cmn.HexBytes + ValidateBasic() sdk.Error + + // The consensus address of the malicious validator at time of infraction + GetConsensusAddress() sdk.ConsAddress + + // Height at which the infraction occurred + GetHeight() int64 + + // The total power of the malicious validator at time of infraction + GetValidatorPower() int64 + + // The total validator set power at time of infraction + GetTotalPower() int64 +} + +// Misbehaviour defines a specific consensus kind and an evidence +type Misbehaviour interface { + ClientType() ClientType + Evidence() Evidence +} + +// Header is the consensus state update information +type Header interface { + ClientType() ClientType + GetHeight() uint64 +} + +// ClientType defines the type of the consensus algorithm +type ClientType byte + +// available client types +const ( + Tendermint ClientType = iota + 1 // 1 +) + +// string representation of the client types +const ( + ClientTypeTendermint string = "tendermint" +) + +func (ct ClientType) String() string { + switch ct { + case Tendermint: + return ClientTypeTendermint + default: + return "" + } +} + +// MarshalJSON marshal to JSON using string. +func (ct ClientType) MarshalJSON() ([]byte, error) { + return json.Marshal(ct.String()) +} + +// UnmarshalJSON decodes from JSON. +func (ct *ClientType) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + bz2, err := ClientTypeFromString(s) + if err != nil { + return err + } + + *ct = bz2 + return nil +} + +// ClientTypeFromString returns a byte that corresponds to the registered client +// type. It returns 0 if the type is not found/registered. +func ClientTypeFromString(clientType string) (ClientType, error) { + switch clientType { + case ClientTypeTendermint: + return Tendermint, nil + + default: + return 0, fmt.Errorf("'%s' is not a valid client type", clientType) + } +} diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go new file mode 100644 index 000000000000..1b1e1807b54a --- /dev/null +++ b/x/ibc/02-client/handler.go @@ -0,0 +1,78 @@ +package client + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + exported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" +) + +// HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient +func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.Result { + clientType, err := exported.ClientTypeFromString(msg.ClientType) + if err != nil { + return sdk.ResultFromError(ErrInvalidClientType(DefaultCodespace, err.Error())) + } + + // TODO: should we create an event with the new client state id ? + _, err = k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + EventTypeCreateClient, + sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgUpdateClient defines the sdk.Handler for MsgUpdateClient +func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) sdk.Result { + err := k.UpdateClient(ctx, msg.ClientID, msg.Header) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + EventTypeUpdateClient, + sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgSubmitMisbehaviour defines the sdk.Handler for MsgSubmitMisbehaviour +func HandleMsgSubmitMisbehaviour(ctx sdk.Context, k Keeper, msg MsgSubmitMisbehaviour) sdk.Result { + err := k.CheckMisbehaviourAndUpdateState(ctx, msg.ClientID, msg.Evidence) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + EventTypeSubmitMisbehaviour, + sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go new file mode 100644 index 000000000000..b75f8174939a --- /dev/null +++ b/x/ibc/02-client/keeper/client.go @@ -0,0 +1,104 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" +) + +// CreateClient creates a new client state and populates it with a given consensus +// state as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create +func (k Keeper) CreateClient( + ctx sdk.Context, clientID string, + clientType exported.ClientType, consensusState exported.ConsensusState, +) (types.State, error) { + _, found := k.GetClientState(ctx, clientID) + if found { + return types.State{}, errors.ErrClientExists(k.codespace, clientID) + } + + _, found = k.GetClientType(ctx, clientID) + if found { + panic(fmt.Sprintf("consensus type is already defined for client %s", clientID)) + } + + clientState := k.initialize(ctx, clientID, consensusState) + k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) + k.SetClientState(ctx, clientState) + k.SetClientType(ctx, clientID, clientType) + k.Logger(ctx).Info(fmt.Sprintf("client %s created at height %d", clientID, consensusState.GetHeight())) + return clientState, nil +} + +// UpdateClient updates the consensus state and the state root from a provided header +func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) error { + clientType, found := k.GetClientType(ctx, clientID) + if !found { + return sdkerrors.Wrap(errors.ErrClientTypeNotFound(k.codespace), "cannot update client") + } + + // check that the header consensus matches the client one + if header.ClientType() != clientType { + return sdkerrors.Wrap(errors.ErrInvalidConsensus(k.codespace), "cannot update client") + } + + clientState, found := k.GetClientState(ctx, clientID) + if !found { + return sdkerrors.Wrap(errors.ErrClientNotFound(k.codespace, clientID), "cannot update client") + } + + if clientState.Frozen { + return sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientID), "cannot update client") + } + + consensusState, found := k.GetConsensusState(ctx, clientID) + if !found { + return sdkerrors.Wrap(errors.ErrConsensusStateNotFound(k.codespace), "cannot update client") + } + + if header.GetHeight() < consensusState.GetHeight() { + return sdkerrors.Wrap( + sdk.ErrInvalidSequence( + fmt.Sprintf("header height < consensus height (%d < %d)", header.GetHeight(), consensusState.GetHeight()), + ), + "cannot update client", + ) + } + + consensusState, err := consensusState.CheckValidityAndUpdateState(header) + if err != nil { + return sdkerrors.Wrap(err, "cannot update client") + } + + k.SetConsensusState(ctx, clientID, consensusState) + k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) + k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, consensusState.GetHeight())) + return nil +} + +// CheckMisbehaviourAndUpdateState checks for client misbehaviour and freezes the +// client if so. +func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, clientID string, evidence exported.Evidence) error { + clientState, found := k.GetClientState(ctx, clientID) + if !found { + sdk.ResultFromError(errors.ErrClientNotFound(k.codespace, clientID)) + } + + err := k.checkMisbehaviour(ctx, evidence) + if err != nil { + return err + } + + clientState, err = k.freeze(ctx, clientState) + if err != nil { + return err + } + + k.SetClientState(ctx, clientState) + k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", clientID)) + return nil +} diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go new file mode 100644 index 000000000000..ce0d54e99782 --- /dev/null +++ b/x/ibc/02-client/keeper/keeper.go @@ -0,0 +1,205 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// Keeper represents a type that grants read and write permissions to any client +// state information +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store +} + +// NewKeeper creates a new NewKeeper instance +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, errors.DefaultCodespace)), // "ibc/client", + prefix: []byte{}, + // prefix: []byte(types.SubModuleName + "/"), // "client/" + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName)) +} + +// GetClientState gets a particular client from the store +func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyClientState(clientID)) + if bz == nil { + return types.State{}, false + } + + var clientState types.State + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &clientState) + return clientState, true +} + +// SetClientState sets a particular Client to the store +func (k Keeper) SetClientState(ctx sdk.Context, clientState types.State) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(clientState) + store.Set(types.KeyClientState(clientState.ID()), bz) +} + +// GetClientType gets the consensus type for a specific client +func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.ClientType, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyClientType(clientID)) + if bz == nil { + return 0, false + } + + return exported.ClientType(bz[0]), true +} + +// SetClientType sets the specific client consensus type to the provable store +func (k Keeper) SetClientType(ctx sdk.Context, clientID string, clientType exported.ClientType) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Set(types.KeyClientType(clientID), []byte{byte(clientType)}) +} + +// GetConsensusState creates a new client state and populates it with a given consensus state +func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.ConsensusState, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyConsensusState(clientID)) + if bz == nil { + return nil, false + } + + var consensusState exported.ConsensusState + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &consensusState) + return consensusState, true +} + +// SetConsensusState sets a ConsensusState to a particular client +func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) + store.Set(types.KeyConsensusState(clientID), bz) +} + +// GetVerifiedRoot gets a verified commitment Root from a particular height to +// a client +func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) (commitment.RootI, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + + bz := store.Get(types.KeyRoot(clientID, height)) + if bz == nil { + return nil, false + } + + var root commitment.RootI + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &root) + return root, true +} + +// SetVerifiedRoot sets a verified commitment Root from a particular height to +// a client +func (k Keeper) SetVerifiedRoot(ctx sdk.Context, clientID string, height uint64, root commitment.RootI) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(root) + store.Set(types.KeyRoot(clientID, height), bz) +} + +// State returns a new client state with a given id as defined in +// https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#example-implementation +func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) types.State { + clientState := types.NewClientState(clientID) + k.SetConsensusState(ctx, clientID, consensusState) + return clientState +} + +func (k Keeper) checkMisbehaviour(ctx sdk.Context, evidence exported.Evidence) error { + switch evidence.Type() { + case exported.ClientTypeTendermint: + var tmEvidence tendermint.Evidence + _, ok := evidence.(tendermint.Evidence) + if !ok { + return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint") + } + err := tendermint.CheckMisbehaviour(tmEvidence) + if err != nil { + return errors.ErrInvalidEvidence(k.codespace, err.Error()) + } + default: + panic(fmt.Sprintf("unregistered evidence type: %s", evidence.Type())) + } + return nil +} + +// freeze updates the state of the client in the event of a misbehaviour +func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) { + if clientState.Frozen { + return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientState.ID()), "already frozen") + } + + clientState.Frozen = true + return clientState, nil +} + +// VerifyMembership state membership verification function defined by the client type +func (k Keeper) VerifyMembership( + ctx sdk.Context, + clientID string, + height uint64, // sequence + proof commitment.ProofI, + path commitment.PathI, + value []byte, +) bool { + // XXX: commented out for demo + /* + if clientState.Frozen { + return false + } + */ + + root, found := k.GetVerifiedRoot(ctx, clientID, height) + if !found { + return false + } + + return proof.VerifyMembership(root, path, value) +} + +// VerifyNonMembership state non-membership function defined by the client type +func (k Keeper) VerifyNonMembership( + ctx sdk.Context, + clientID string, + height uint64, // sequence + proof commitment.ProofI, + path commitment.PathI, +) bool { + // XXX: commented out for demo + /* + if clientState.Frozen { + return false + } + */ + root, found := k.GetVerifiedRoot(ctx, clientID, height) + if !found { + return false + } + + return proof.VerifyNonMembership(root, path) +} diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go new file mode 100644 index 000000000000..5f56b8d6b01a --- /dev/null +++ b/x/ibc/02-client/keeper/querier.go @@ -0,0 +1,77 @@ +package keeper + +import ( + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" +) + +// QuerierClientState defines the sdk.Querier to query the IBC client state +func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryClientStateParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + clientState, found := k.GetClientState(ctx, params.ClientID) + if !found { + return nil, errors.ErrClientTypeNotFound(k.codespace) + } + + bz, err := types.SubModuleCdc.MarshalJSON(clientState) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} + +// QuerierConsensusState defines the sdk.Querier to query a consensus state +func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryClientStateParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + consensusState, found := k.GetConsensusState(ctx, params.ClientID) + if !found { + return nil, errors.ErrConsensusStateNotFound(k.codespace) + } + + bz, err := types.SubModuleCdc.MarshalJSON(consensusState) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} + +// QuerierVerifiedRoot defines the sdk.Querier to query a verified commitment root +func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryCommitmentRootParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + root, found := k.GetVerifiedRoot(ctx, params.ClientID, params.Height) + if !found { + return nil, errors.ErrRootNotFound(k.codespace) + } + + bz, err := types.SubModuleCdc.MarshalJSON(root) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} diff --git a/x/ibc/02-client/module.go b/x/ibc/02-client/module.go new file mode 100644 index 000000000000..3df05cdfbdf2 --- /dev/null +++ b/x/ibc/02-client/module.go @@ -0,0 +1,32 @@ +package client + +import ( + "fmt" + + "github.com/gorilla/mux" + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/cli" +) + +// Name returns the IBC client name +func Name() string { + return SubModuleName +} + +// RegisterRESTRoutes registers the REST routes for the IBC client +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { + // TODO: +} + +// GetTxCmd returns the root tx command for the IBC client +func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + return cli.GetTxCmd(fmt.Sprintf("%s/%s", storeKey, SubModuleName), cdc) +} + +// GetQueryCmd returns no root query command for the IBC client +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + return cli.GetQueryCmd(fmt.Sprintf("%s/%s", queryRoute, SubModuleName), cdc) +} diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go new file mode 100644 index 000000000000..7a141e811a0a --- /dev/null +++ b/x/ibc/02-client/types/codec.go @@ -0,0 +1,30 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" +) + +// SubModuleCdc defines the IBC client codec. +var SubModuleCdc = codec.New() + +// RegisterCodec registers the IBC client interfaces and types +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*exported.Blockchain)(nil), nil) + cdc.RegisterInterface((*exported.ConsensusState)(nil), nil) + cdc.RegisterInterface((*exported.Evidence)(nil), nil) + cdc.RegisterInterface((*exported.Header)(nil), nil) + cdc.RegisterInterface((*exported.Misbehaviour)(nil), nil) + + cdc.RegisterConcrete(MsgCreateClient{}, "ibc/client/MsgCreateClient", nil) + cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) + + cdc.RegisterConcrete(tendermint.ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) + cdc.RegisterConcrete(tendermint.Header{}, "ibc/client/tendermint/Header", nil) + cdc.RegisterConcrete(tendermint.Evidence{}, "ibc/client/tendermint/Evidence", nil) +} + +func init() { + RegisterCodec(SubModuleCdc) +} diff --git a/x/ibc/02-client/types/errors/errors.go b/x/ibc/02-client/types/errors/errors.go new file mode 100644 index 000000000000..c133bcfef808 --- /dev/null +++ b/x/ibc/02-client/types/errors/errors.go @@ -0,0 +1,73 @@ +package errors + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// client error codes +const ( + DefaultCodespace sdk.CodespaceType = "client" + + CodeClientExists sdk.CodeType = 101 + CodeClientNotFound sdk.CodeType = 102 + CodeClientFrozen sdk.CodeType = 103 + CodeConsensusStateNotFound sdk.CodeType = 104 + CodeInvalidConsensusState sdk.CodeType = 105 + CodeClientTypeNotFound sdk.CodeType = 106 + CodeInvalidClientType sdk.CodeType = 107 + CodeRootNotFound sdk.CodeType = 108 + CodeInvalidHeader sdk.CodeType = 109 + CodeInvalidEvidence sdk.CodeType = 110 +) + +// ErrClientExists implements sdk.Error +func ErrClientExists(codespace sdk.CodespaceType, clientID string) sdk.Error { + return sdk.NewError(codespace, CodeClientExists, fmt.Sprintf("client with ID %s already exists", clientID)) +} + +// ErrClientNotFound implements sdk.Error +func ErrClientNotFound(codespace sdk.CodespaceType, clientID string) sdk.Error { + return sdk.NewError(codespace, CodeClientNotFound, fmt.Sprintf("client with ID %s not found", clientID)) +} + +// ErrClientFrozen implements sdk.Error +func ErrClientFrozen(codespace sdk.CodespaceType, clientID string) sdk.Error { + return sdk.NewError(codespace, CodeClientFrozen, fmt.Sprintf("client with ID %s is frozen due to misbehaviour", clientID)) +} + +// ErrConsensusStateNotFound implements sdk.Error +func ErrConsensusStateNotFound(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeConsensusStateNotFound, "consensus state not found") +} + +// ErrInvalidConsensus implements sdk.Error +func ErrInvalidConsensus(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidConsensusState, "invalid consensus state") +} + +// ErrClientTypeNotFound implements sdk.Error +func ErrClientTypeNotFound(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeClientTypeNotFound, "client type not found") +} + +// ErrInvalidClientType implements sdk.Error +func ErrInvalidClientType(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidClientType, msg) +} + +// ErrRootNotFound implements sdk.Error +func ErrRootNotFound(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeRootNotFound, "commitment root not found") +} + +// ErrInvalidHeader implements sdk.Error +func ErrInvalidHeader(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidHeader, "invalid header") +} + +// ErrInvalidEvidence implements sdk.Error +func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidEvidence, "invalid evidence: %s", msg) +} diff --git a/x/ibc/02-client/types/events.go b/x/ibc/02-client/types/events.go new file mode 100644 index 000000000000..7e7f9a508cee --- /dev/null +++ b/x/ibc/02-client/types/events.go @@ -0,0 +1,21 @@ +package types + +import ( + "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// IBC client events +const ( + AttributeKeyClientID = "client_id" +) + +// IBC client events vars +var ( + EventTypeCreateClient = MsgCreateClient{}.Type() + EventTypeUpdateClient = MsgUpdateClient{}.Type() + EventTypeSubmitMisbehaviour = MsgSubmitMisbehaviour{}.Type() + + AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) +) diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go new file mode 100644 index 000000000000..8d97ca893324 --- /dev/null +++ b/x/ibc/02-client/types/keys.go @@ -0,0 +1,67 @@ +package types + +import ( + "fmt" +) + +const ( + // SubModuleName defines the IBC client name + SubModuleName = "client" + + // StoreKey is the store key string for IBC client + StoreKey = SubModuleName + + // RouterKey is the message route for IBC client + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC client + QuerierRoute = SubModuleName +) + +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space + +// ClientStatePath takes an Identifier and returns a Path under which to store a +// particular client state +func ClientStatePath(clientID string) string { + return fmt.Sprintf("clients/%s/state", clientID) +} + +// ClientTypePath takes an Identifier and returns Path under which to store the +// type of a particular client. +func ClientTypePath(clientID string) string { + return fmt.Sprintf("clients/%s/type", clientID) +} + +// ConsensusStatePath takes an Identifier and returns a Path under which to +// store the consensus state of a client. +func ConsensusStatePath(clientID string) string { + return fmt.Sprintf("clients/%s/consensusState", clientID) +} + +// RootPath takes an Identifier and returns a Path under which to +// store the consensus state of a client. +func RootPath(clientID string, height uint64) string { + return fmt.Sprintf("clients/%s/roots/%d", clientID, height) +} + +// KeyClientState returns the store key for a particular client state +func KeyClientState(clientID string) []byte { + return []byte(ClientStatePath(clientID)) +} + +// KeyClientType returns the store key for type of a particular client +func KeyClientType(clientID string) []byte { + return []byte(ClientTypePath(clientID)) +} + +// KeyConsensusState returns the store key for the consensus state of a particular +// client +func KeyConsensusState(clientID string) []byte { + return []byte(ConsensusStatePath(clientID)) +} + +// KeyRoot returns the store key for a commitment root of a particular +// client at a given height +func KeyRoot(clientID string, height uint64) []byte { + return []byte(RootPath(clientID, height)) +} diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go new file mode 100644 index 000000000000..612f7e543e53 --- /dev/null +++ b/x/ibc/02-client/types/msgs.go @@ -0,0 +1,173 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +var _ sdk.Msg = MsgCreateClient{} + +// MsgCreateClient defines a message to create an IBC client +type MsgCreateClient struct { + ClientID string `json:"client_id" yaml:"client_id"` + ClientType string `json:"client_type" yaml:"client_type"` + ConsensusState exported.ConsensusState `json:"consensus_state" yaml:"consensus_address"` + Signer sdk.AccAddress `json:"address" yaml:"address"` +} + +// NewMsgCreateClient creates a new MsgCreateClient instance +func NewMsgCreateClient(id, clientType string, consensusState exported.ConsensusState, signer sdk.AccAddress) MsgCreateClient { + return MsgCreateClient{ + ClientID: id, + ClientType: clientType, + ConsensusState: consensusState, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgCreateClient) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgCreateClient) Type() string { + return "create_client" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgCreateClient) ValidateBasic() sdk.Error { + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if _, err := exported.ClientTypeFromString(msg.ClientType); err != nil { + return errors.ErrInvalidClientType(errors.DefaultCodespace, err.Error()) + } + if msg.ConsensusState == nil { + return errors.ErrInvalidConsensus(errors.DefaultCodespace) + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("empty address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgCreateClient) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgCreateClient) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgUpdateClient{} + +// MsgUpdateClient defines a message to update an IBC client +type MsgUpdateClient struct { + ClientID string `json:"client_id" yaml:"client_id"` + Header exported.Header `json:"header" yaml:"header"` + Signer sdk.AccAddress `json:"address" yaml:"address"` +} + +// NewMsgUpdateClient creates a new MsgUpdateClient instance +func NewMsgUpdateClient(id string, header exported.Header, signer sdk.AccAddress) MsgUpdateClient { + return MsgUpdateClient{ + ClientID: id, + Header: header, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgUpdateClient) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgUpdateClient) Type() string { + return "update_client" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgUpdateClient) ValidateBasic() sdk.Error { + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if msg.Header == nil { + return errors.ErrInvalidHeader(errors.DefaultCodespace) + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("empty address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgUpdateClient) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +// MsgSubmitMisbehaviour defines a message to update an IBC client +type MsgSubmitMisbehaviour struct { + ClientID string `json:"id" yaml:"id"` + Evidence exported.Evidence `json:"evidence" yaml:"evidence"` + Signer sdk.AccAddress `json:"address" yaml:"address"` +} + +// NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance +func NewMsgSubmitMisbehaviour(id string, evidence exported.Evidence, signer sdk.AccAddress) MsgSubmitMisbehaviour { + return MsgSubmitMisbehaviour{ + ClientID: id, + Evidence: evidence, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgSubmitMisbehaviour) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgSubmitMisbehaviour) Type() string { + return "submit_misbehaviour" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgSubmitMisbehaviour) ValidateBasic() sdk.Error { + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if msg.Evidence == nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "evidence is nil") + } + if err := msg.Evidence.ValidateBasic(); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error()) + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("empty address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgSubmitMisbehaviour) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgSubmitMisbehaviour) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go new file mode 100644 index 000000000000..cd416fabdfe8 --- /dev/null +++ b/x/ibc/02-client/types/msgs_test.go @@ -0,0 +1,140 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + "github.com/tendermint/tendermint/crypto/secp256k1" + cmn "github.com/tendermint/tendermint/libs/common" +) + +func TestMsgCreateClientValidateBasic(t *testing.T) { + cs := tendermint.ConsensusState{} + privKey := secp256k1.GenPrivKey() + signer := sdk.AccAddress(privKey.PubKey().Address()) + testMsgs := []MsgCreateClient{ + NewMsgCreateClient(exported.ClientTypeTendermint, exported.ClientTypeTendermint, cs, signer), // valid msg + NewMsgCreateClient("badClient", exported.ClientTypeTendermint, cs, signer), // invalid client id + NewMsgCreateClient("goodChain", "bad_type", cs, signer), // invalid client type + NewMsgCreateClient("goodChain", exported.ClientTypeTendermint, nil, signer), // nil Consensus State + NewMsgCreateClient("goodChain", exported.ClientTypeTendermint, cs, sdk.AccAddress{}), // empty signer + } + + cases := []struct { + msg MsgCreateClient + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "invalid client id passed"}, + {testMsgs[2], false, "unregistered client type passed"}, + {testMsgs[3], false, "Nil Consensus State in msg passed"}, + {testMsgs[4], false, "Empty address passed"}, + } + + for i, tc := range cases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +func TestMsgUpdateClient(t *testing.T) { + privKey := secp256k1.GenPrivKey() + signer := sdk.AccAddress(privKey.PubKey().Address()) + testMsgs := []MsgUpdateClient{ + NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, signer), // valid msg + NewMsgUpdateClient("badClient", tendermint.Header{}, signer), // bad client id + NewMsgUpdateClient(exported.ClientTypeTendermint, nil, signer), // nil Header + NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, sdk.AccAddress{}), // empty address + } + + cases := []struct { + msg MsgUpdateClient + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "invalid client id passed"}, + {testMsgs[2], false, "Nil Header passed"}, + {testMsgs[3], false, "Empty address passed"}, + } + + for i, tc := range cases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +var _ exported.Evidence = mockEvidence{} + +const mockStr = "mock" + +// mock GoodEvidence +type mockEvidence struct{} + +// Implement Evidence interface +func (me mockEvidence) Route() string { return mockStr } +func (me mockEvidence) Type() string { return mockStr } +func (me mockEvidence) String() string { return mockStr } +func (me mockEvidence) Hash() cmn.HexBytes { return cmn.HexBytes([]byte(mockStr)) } +func (me mockEvidence) ValidateBasic() sdk.Error { return nil } +func (me mockEvidence) GetConsensusAddress() sdk.ConsAddress { return sdk.ConsAddress{} } +func (me mockEvidence) GetHeight() int64 { return 3 } +func (me mockEvidence) GetValidatorPower() int64 { return 3 } +func (me mockEvidence) GetTotalPower() int64 { return 5 } + +// mock bad evidence +type mockBadEvidence struct { + mockEvidence +} + +// Override ValidateBasic +func (mbe mockBadEvidence) ValidateBasic() sdk.Error { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence") +} + +func TestMsgSubmitMisbehaviour(t *testing.T) { + privKey := secp256k1.GenPrivKey() + signer := sdk.AccAddress(privKey.PubKey().Address()) + testMsgs := []MsgSubmitMisbehaviour{ + NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, mockEvidence{}, signer), // valid msg + NewMsgSubmitMisbehaviour("badClient", mockEvidence{}, signer), // bad client id + NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, nil, signer), // nil evidence + NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, mockBadEvidence{}, signer), // invalid evidence + NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, mockEvidence{}, sdk.AccAddress{}), // empty signer + } + + cases := []struct { + msg MsgSubmitMisbehaviour + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "invalid client id passed"}, + {testMsgs[2], false, "Nil Evidence passed"}, + {testMsgs[3], false, "Invalid Evidence passed"}, + {testMsgs[4], false, "Empty address passed"}, + } + + for i, tc := range cases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go new file mode 100644 index 000000000000..7638c0200882 --- /dev/null +++ b/x/ibc/02-client/types/querier.go @@ -0,0 +1,66 @@ +package types + +import ( + "strings" + + tmtypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/tendermint/tendermint/crypto/merkle" +) + +// query routes supported by the IBC client Querier +const ( + QueryClientState = "client_state" + QueryConsensusState = "consensus_state" + QueryVerifiedRoot = "roots" +) + +// QueryClientStateParams defines the params for the following queries: +// - 'custom/ibc/clients//client_state' +// - 'custom/ibc/clients//consensus_state' +type QueryClientStateParams struct { + ClientID string +} + +// NewQueryClientStateParams creates a new QueryClientStateParams instance +func NewQueryClientStateParams(id string) QueryClientStateParams { + return QueryClientStateParams{ + ClientID: id, + } +} + +// QueryCommitmentRootParams defines the params for the following queries: +// - 'custom/ibc/clients//roots/' +type QueryCommitmentRootParams struct { + ClientID string + Height uint64 +} + +// NewQueryCommitmentRootParams creates a new QueryCommitmentRootParams instance +func NewQueryCommitmentRootParams(id string, height uint64) QueryCommitmentRootParams { + return QueryCommitmentRootParams{ + ClientID: id, + Height: height, + } +} + +// ConsensusStateResponse defines the client response for a Consensus state query. +// It includes the commitment proof and the height of the proof. +type ConsensusStateResponse struct { + ConsensusState tmtypes.ConsensusState + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewConsensusStateResponse creates a new ConsensusStateResponse instance. +func NewConsensusStateResponse( + clientID string, cs tmtypes.ConsensusState, proof *merkle.Proof, height int64, +) ConsensusStateResponse { + return ConsensusStateResponse{ + ConsensusState: cs, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ConsensusStatePath(clientID), "/")), + ProofHeight: uint64(height), + } +} diff --git a/x/ibc/02-client/types/state.go b/x/ibc/02-client/types/state.go new file mode 100644 index 000000000000..8c60260df0a2 --- /dev/null +++ b/x/ibc/02-client/types/state.go @@ -0,0 +1,24 @@ +package types + +// State is a type that represents the state of a client. +// Any actor holding the Stage can access on and modify that client information. +type State struct { + // Client ID + id string + // Boolean that states if the client is frozen when a misbehaviour proof is + // submitted in the event of an equivocation. + Frozen bool `json:"frozen" yaml:"frozen"` +} + +// NewClientState creates a new ClientState instance +func NewClientState(id string) State { + return State{ + id: id, + Frozen: false, + } +} + +// ID returns the client identifier +func (s State) ID() string { + return s.id +} diff --git a/x/ibc/02-client/types/tendermint/codec.go b/x/ibc/02-client/types/tendermint/codec.go new file mode 100644 index 000000000000..46814fec2479 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/codec.go @@ -0,0 +1,18 @@ +package tendermint + +import ( + "github.com/cosmos/cosmos-sdk/codec" +) + +var SubModuleCdc = codec.New() + +// RegisterCodec registers the Tendermint types +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterConcrete(ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) + cdc.RegisterConcrete(Header{}, "ibc/client/tendermint/Header", nil) + cdc.RegisterConcrete(Evidence{}, "ibc/client/tendermint/Evidence", nil) +} + +func init() { + RegisterCodec(SubModuleCdc) +} diff --git a/x/ibc/02-client/types/tendermint/consensus_state.go b/x/ibc/02-client/types/tendermint/consensus_state.go new file mode 100644 index 000000000000..3ad0892a9ea8 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/consensus_state.go @@ -0,0 +1,89 @@ +package tendermint + +import ( + "bytes" + "errors" + + lerr "github.com/tendermint/tendermint/lite/errors" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +var _ exported.ConsensusState = ConsensusState{} + +// ConsensusState defines a Tendermint consensus state +type ConsensusState struct { + ChainID string `json:"chain_id" yaml:"chain_id"` + Height uint64 `json:"height" yaml:"height"` // NOTE: defined as 'sequence' in the spec + Root commitment.RootI `json:"root" yaml:"root"` + NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` // contains the PublicKey +} + +// ClientType returns Tendermint +func (ConsensusState) ClientType() exported.ClientType { + return exported.Tendermint +} + +// GetHeight returns the ConsensusState height +func (cs ConsensusState) GetHeight() uint64 { + return cs.Height +} + +// GetRoot returns the commitment Root for the specific +func (cs ConsensusState) GetRoot() commitment.RootI { + return cs.Root +} + +// CheckValidityAndUpdateState checks if the provided header is valid and updates +// the consensus state if appropriate +func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (exported.ConsensusState, error) { + tmHeader, ok := header.(Header) + if !ok { + return nil, errors.New("header not a valid tendermint header") + } + + if err := cs.checkValidity(tmHeader); err != nil { + return nil, err + } + + return cs.update(tmHeader), nil +} + +// checkValidity checks if the Tendermint header is valid +// +// CONTRACT: assumes header.Height > consensusState.Height +func (cs ConsensusState) checkValidity(header Header) error { + // check if the hash from the consensus set and header + // matches + nextHash := cs.NextValidatorSet.Hash() + if cs.Height == uint64(header.Height-1) && + !bytes.Equal(nextHash, header.ValidatorsHash) { + return lerr.ErrUnexpectedValidators(nextHash, header.ValidatorsHash) + } + + // validate the next validator set hash from the header + nextHash = header.NextValidatorSet.Hash() + if !bytes.Equal(header.NextValidatorsHash, nextHash) { + return lerr.ErrUnexpectedValidators(header.NextValidatorsHash, nextHash) + } + + // basic consistency check + if err := header.ValidateBasic(cs.ChainID); err != nil { + return err + } + + // abortTransactionUnless(consensusState.publicKey.verify(header.signature)) + return header.ValidatorSet.VerifyFutureCommit( + cs.NextValidatorSet, cs.ChainID, header.Commit.BlockID, header.Height, header.Commit, + ) +} + +// update the consensus state from a new header +func (cs ConsensusState) update(header Header) ConsensusState { + cs.Height = header.GetHeight() + cs.Root = commitment.NewRoot(header.AppHash) + cs.NextValidatorSet = header.NextValidatorSet + return cs +} diff --git a/x/ibc/02-client/types/tendermint/consensus_state_test.go b/x/ibc/02-client/types/tendermint/consensus_state_test.go new file mode 100644 index 000000000000..2f4129226228 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/consensus_state_test.go @@ -0,0 +1,52 @@ +package tendermint + +import ( + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/tmhash" + tmtypes "github.com/tendermint/tendermint/types" +) + +func (suite *TendermintTestSuite) TestCheckValidity() { + // valid header + err := suite.cs.checkValidity(suite.header) + require.Nil(suite.T(), err, "validity failed") + + // switch out header ValidatorsHash + suite.header.ValidatorsHash = tmhash.Sum([]byte("hello")) + err = suite.cs.checkValidity(suite.header) + require.NotNil(suite.T(), err, "validator hash is wrong") + + // reset suite and make header.NextValidatorSet different + // from NextValidatorSetHash + suite.SetupTest() + privVal := tmtypes.NewMockPV() + val := tmtypes.NewValidator(privVal.GetPubKey(), 5) + suite.header.NextValidatorSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) + err = suite.cs.checkValidity(suite.header) + require.NotNil(suite.T(), err, "header's next validator set is not consistent with hash") + + // reset and make header fail validatebasic + suite.SetupTest() + suite.header.ChainID = "not_mychain" + err = suite.cs.checkValidity(suite.header) + require.NotNil(suite.T(), err, "invalid header should fail ValidateBasic") +} + +func (suite *TendermintTestSuite) TestCheckUpdate() { + // valid header should successfully update consensus state + cs, err := suite.cs.CheckValidityAndUpdateState(suite.header) + + require.Nil(suite.T(), err, "valid update failed") + require.Equal(suite.T(), suite.header.GetHeight(), cs.GetHeight(), "height not updated") + require.Equal(suite.T(), suite.header.AppHash.Bytes(), cs.GetRoot().GetHash(), "root not updated") + tmCS, _ := cs.(ConsensusState) + require.Equal(suite.T(), suite.header.NextValidatorSet, tmCS.NextValidatorSet, "validator set did not update") + + // make header invalid so update should be unsuccessful + suite.SetupTest() + suite.header.ChainID = "not_mychain" + + cs, err = suite.cs.CheckValidityAndUpdateState(suite.header) + require.NotNil(suite.T(), err) + require.Nil(suite.T(), cs) +} diff --git a/x/ibc/02-client/types/tendermint/doc.go b/x/ibc/02-client/types/tendermint/doc.go new file mode 100644 index 000000000000..f0e27c7696a7 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/doc.go @@ -0,0 +1,5 @@ +/* +Package tendermint implements a concrete `ConsensusState`, `Header` and `Equivocation` +for the Tendermint consensus algorithm. +*/ +package tendermint diff --git a/x/ibc/02-client/types/tendermint/header.go b/x/ibc/02-client/types/tendermint/header.go new file mode 100644 index 000000000000..c2d9cfebc9c5 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/header.go @@ -0,0 +1,28 @@ +package tendermint + +import ( + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" +) + +var _ exported.Header = Header{} + +// Header defines the Tendermint consensus Header +type Header struct { + tmtypes.SignedHeader + ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` + NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` +} + +// ClientType defines that the Header is a Tendermint consensus algorithm +func (h Header) ClientType() exported.ClientType { + return exported.Tendermint +} + +// GetHeight returns the current height +// +// NOTE: also referred as `sequence` +func (h Header) GetHeight() uint64 { + return uint64(h.Height) +} diff --git a/x/ibc/02-client/types/tendermint/misbehaviour.go b/x/ibc/02-client/types/tendermint/misbehaviour.go new file mode 100644 index 000000000000..512bb0f72161 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/misbehaviour.go @@ -0,0 +1,96 @@ +package tendermint + +import ( + "fmt" + + yaml "gopkg.in/yaml.v2" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + + "github.com/tendermint/tendermint/crypto/tmhash" + cmn "github.com/tendermint/tendermint/libs/common" + tmtypes "github.com/tendermint/tendermint/types" +) + +var _ exported.Evidence = Evidence{} + +// Evidence is a wrapper over tendermint's DuplicateVoteEvidence +// that implements Evidence interface expected by ICS-02 +type Evidence struct { + *tmtypes.DuplicateVoteEvidence + ChainID string `json:"chain_id" yaml:"chain_id"` + ValidatorPower int64 `json:"val_power" yaml:"val_power"` + TotalPower int64 `json:"total_power" yaml:"total_power"` +} + +// Type implements exported.Evidence interface +func (ev Evidence) Route() string { + return exported.ClientTypeTendermint +} + +// Type implements exported.Evidence interface +func (ev Evidence) Type() string { + return exported.ClientTypeTendermint +} + +// String implements exported.Evidence interface +func (ev Evidence) String() string { + bz, err := yaml.Marshal(ev) + if err != nil { + panic(err) + } + return string(bz) +} + +// Hash implements exported.Evidence interface +func (ev Evidence) Hash() cmn.HexBytes { + return tmhash.Sum(SubModuleCdc.MustMarshalBinaryBare(ev)) +} + +// ValidateBasic implements exported.Evidence interface +func (ev Evidence) ValidateBasic() sdk.Error { + if ev.DuplicateVoteEvidence == nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "duplicate evidence is nil") + } + err := ev.DuplicateVoteEvidence.ValidateBasic() + if err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error()) + } + if ev.ChainID == "" { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "chainID is empty") + } + if ev.ValidatorPower <= 0 { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Validator Power: %d", ev.ValidatorPower)) + } + if ev.TotalPower < ev.ValidatorPower { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Total Power: %d", ev.TotalPower)) + } + return nil +} + +// GetConsensusAddress implements exported.Evidence interface +func (ev Evidence) GetConsensusAddress() sdk.ConsAddress { + return sdk.ConsAddress(ev.DuplicateVoteEvidence.Address()) +} + +// GetHeight implements exported.Evidence interface +func (ev Evidence) GetHeight() int64 { + return ev.DuplicateVoteEvidence.Height() +} + +// GetValidatorPower implements exported.Evidence interface +func (ev Evidence) GetValidatorPower() int64 { + return ev.ValidatorPower +} + +// GetTotalPower implements exported.Evidence interface +func (ev Evidence) GetTotalPower() int64 { + return ev.TotalPower +} + +// CheckMisbehaviour checks if the evidence provided is a misbehaviour +func CheckMisbehaviour(evidence Evidence) error { + return evidence.DuplicateVoteEvidence.Verify(evidence.ChainID, evidence.DuplicateVoteEvidence.PubKey) +} diff --git a/x/ibc/02-client/types/tendermint/misbehaviour_test.go b/x/ibc/02-client/types/tendermint/misbehaviour_test.go new file mode 100644 index 000000000000..f5e75e12f785 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/misbehaviour_test.go @@ -0,0 +1,64 @@ +package tendermint + +import ( + "testing" + + "github.com/stretchr/testify/require" + + yaml "gopkg.in/yaml.v2" +) + +func TestString(t *testing.T) { + dupEv := randomDuplicatedVoteEvidence() + ev := Evidence{ + DuplicateVoteEvidence: dupEv, + ChainID: "mychain", + ValidatorPower: 10, + TotalPower: 50, + } + + byteStr, err := yaml.Marshal(ev) + require.Nil(t, err) + require.Equal(t, string(byteStr), ev.String(), "Evidence String method does not work as expected") + +} + +func TestValidateBasic(t *testing.T) { + dupEv := randomDuplicatedVoteEvidence() + + // good evidence + ev := Evidence{ + DuplicateVoteEvidence: dupEv, + ChainID: "mychain", + ValidatorPower: 10, + TotalPower: 50, + } + + err := ev.ValidateBasic() + require.Nil(t, err, "good evidence failed on ValidateBasic: %v", err) + + // invalid duplicate evidence + ev.DuplicateVoteEvidence.VoteA = nil + err = ev.ValidateBasic() + require.NotNil(t, err, "invalid duplicate evidence passed on ValidateBasic") + + // reset duplicate evidence to be valid, and set empty chainID + dupEv = randomDuplicatedVoteEvidence() + ev.DuplicateVoteEvidence = dupEv + ev.ChainID = "" + err = ev.ValidateBasic() + require.NotNil(t, err, "invalid chain-id passed on ValidateBasic") + + // reset chainID and set 0 validator power + ev.ChainID = "mychain" + ev.ValidatorPower = 0 + err = ev.ValidateBasic() + require.NotNil(t, err, "invalid validator power passed on ValidateBasic") + + // reset validator power and set invalid total power + ev.ValidatorPower = 10 + ev.TotalPower = 9 + err = ev.ValidateBasic() + require.NotNil(t, err, "invalid total power passed on ValidateBasic") + +} diff --git a/x/ibc/02-client/types/tendermint/tendermint_test.go b/x/ibc/02-client/types/tendermint/tendermint_test.go new file mode 100644 index 000000000000..11817f73e9ff --- /dev/null +++ b/x/ibc/02-client/types/tendermint/tendermint_test.go @@ -0,0 +1,87 @@ +package tendermint + +import ( + "math" + "testing" + "time" + + "github.com/stretchr/testify/suite" + + "github.com/tendermint/tendermint/crypto/tmhash" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/version" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +type TendermintTestSuite struct { + suite.Suite + + privVal tmtypes.PrivValidator + valSet *tmtypes.ValidatorSet + header Header + cs ConsensusState +} + +func (suite *TendermintTestSuite) SetupTest() { + privVal := tmtypes.NewMockPV() + val := tmtypes.NewValidator(privVal.GetPubKey(), 10) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) + vsetHash := valSet.Hash() + timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) + tmHeader := tmtypes.Header{ + Version: version.Consensus{Block: 2, App: 2}, + ChainID: "mychain", + Height: 3, + Time: timestamp, + NumTxs: 100, + TotalTxs: 1000, + LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt64, make([]byte, tmhash.Size)), + LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), + DataHash: tmhash.Sum([]byte("data_hash")), + ValidatorsHash: vsetHash, + NextValidatorsHash: vsetHash, + ConsensusHash: tmhash.Sum([]byte("consensus_hash")), + AppHash: tmhash.Sum([]byte("app_hash")), + LastResultsHash: tmhash.Sum([]byte("last_results_hash")), + EvidenceHash: tmhash.Sum([]byte("evidence_hash")), + ProposerAddress: privVal.GetPubKey().Address(), + } + hhash := tmHeader.Hash() + blockID := makeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) + voteSet := tmtypes.NewVoteSet("mychain", 3, 1, tmtypes.PrecommitType, valSet) + commit, err := tmtypes.MakeCommit(blockID, 3, 1, voteSet, []tmtypes.PrivValidator{privVal}) + if err != nil { + panic(err) + } + + signedHeader := tmtypes.SignedHeader{ + Header: &tmHeader, + Commit: commit, + } + + header := Header{ + SignedHeader: signedHeader, + ValidatorSet: valSet, + NextValidatorSet: valSet, + } + + root := commitment.NewRoot(tmhash.Sum([]byte("my root"))) + + cs := ConsensusState{ + ChainID: "mychain", + Height: 3, + Root: root, + NextValidatorSet: valSet, + } + + // set fields in suite + suite.privVal = privVal + suite.valSet = valSet + suite.header = header + suite.cs = cs +} + +func TestTendermintTestSuite(t *testing.T) { + suite.Run(t, new(TendermintTestSuite)) +} diff --git a/x/ibc/02-client/types/tendermint/test_utils.go b/x/ibc/02-client/types/tendermint/test_utils.go new file mode 100644 index 000000000000..a88bd13d3b1c --- /dev/null +++ b/x/ibc/02-client/types/tendermint/test_utils.go @@ -0,0 +1,47 @@ +package tendermint + +import ( + "github.com/tendermint/tendermint/crypto/tmhash" + tmtypes "github.com/tendermint/tendermint/types" +) + +// Copied unimported test functions from tmtypes to use them here +func makeBlockID(hash []byte, partSetSize int, partSetHash []byte) tmtypes.BlockID { + return tmtypes.BlockID{ + Hash: hash, + PartsHeader: tmtypes.PartSetHeader{ + Total: partSetSize, + Hash: partSetHash, + }, + } + +} + +func makeVote(val tmtypes.PrivValidator, chainID string, valIndex int, height int64, round, step int, blockID tmtypes.BlockID) *tmtypes.Vote { + addr := val.GetPubKey().Address() + v := &tmtypes.Vote{ + ValidatorAddress: addr, + ValidatorIndex: valIndex, + Height: height, + Round: round, + Type: tmtypes.SignedMsgType(step), + BlockID: blockID, + } + err := val.SignVote(chainID, v) + if err != nil { + panic(err) + } + return v +} + +func randomDuplicatedVoteEvidence() *tmtypes.DuplicateVoteEvidence { + val := tmtypes.NewMockPV() + blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), 1000, tmhash.Sum([]byte("partshash"))) + blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), 1000, tmhash.Sum([]byte("partshash"))) + const chainID = "mychain" + return &tmtypes.DuplicateVoteEvidence{ + PubKey: val.GetPubKey(), + VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID), + VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2), + } +} diff --git a/x/ibc/24-host/errors.go b/x/ibc/24-host/errors.go index afc1c26ea303..e6a526e6d0f8 100644 --- a/x/ibc/24-host/errors.go +++ b/x/ibc/24-host/errors.go @@ -14,6 +14,9 @@ var ( // ErrInvalidPath is returned if path string is invalid ErrInvalidPath = sdkerrors.Register(IBCCodeSpace, 2, "invalid path") + // ErrInvalidEvidence is returned if evidence is invalid + ErrInvalidEvidence = sdkerrors.Register(IBCCodeSpace, 3, "invalid evidence") + // ErrInvalidPacket is returned if packets embedded in msg are invalid - ErrInvalidPacket = sdkerrors.Register(IBCCodeSpace, 3, "invalid packet extracted from msg") + ErrInvalidPacket = sdkerrors.Register(IBCCodeSpace, 4, "invalid packet extracted from msg") ) diff --git a/x/ibc/alias.go b/x/ibc/alias.go new file mode 100644 index 000000000000..7c1ad02349e2 --- /dev/null +++ b/x/ibc/alias.go @@ -0,0 +1,29 @@ +package ibc + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +const ( + ModuleName = types.ModuleName + StoreKey = types.StoreKey + QuerierRoute = types.QuerierRoute + RouterKey = types.RouterKey +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + NewQuerier = keeper.NewQuerier +) + +type ( + Keeper = keeper.Keeper +) diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go new file mode 100644 index 000000000000..5657d2aad3c7 --- /dev/null +++ b/x/ibc/client/cli/cli.go @@ -0,0 +1,43 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ibcTxCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "IBC transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + ibcTxCmd.AddCommand(client.PostCommands( + ibcclient.GetTxCmd(cdc, storeKey), + )...) + return ibcTxCmd +} + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + // Group ibc queries under a subcommand + ibcQueryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Querying commands for the IBC module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + ibcQueryCmd.AddCommand(client.GetCommands( + ibcclient.GetQueryCmd(cdc, queryRoute), + )...) + return ibcQueryCmd +} diff --git a/x/ibc/handler.go b/x/ibc/handler.go new file mode 100644 index 000000000000..5dc802b6f063 --- /dev/null +++ b/x/ibc/handler.go @@ -0,0 +1,30 @@ +package ibc + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" +) + +// NewHandler defines the IBC handler +func NewHandler(k Keeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + switch msg := msg.(type) { + case client.MsgCreateClient: + return client.HandleMsgCreateClient(ctx, k.ClientKeeper, msg) + + case client.MsgUpdateClient: + return client.HandleMsgUpdateClient(ctx, k.ClientKeeper, msg) + + case client.MsgSubmitMisbehaviour: + return client.HandleMsgSubmitMisbehaviour(ctx, k.ClientKeeper, msg) + + default: + errMsg := fmt.Sprintf("unrecognized IBC Client message type: %T", msg) + return sdk.ErrUnknownRequest(errMsg).Result() + } + } +} diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go new file mode 100644 index 000000000000..fce91fb353bd --- /dev/null +++ b/x/ibc/keeper/keeper.go @@ -0,0 +1,19 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" +) + +// Keeper defines each ICS keeper for IBC +type Keeper struct { + ClientKeeper client.Keeper +} + +// NewKeeper creates a new ibc Keeper +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { + return Keeper{ + ClientKeeper: client.NewKeeper(cdc, key, codespace), + } +} diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go new file mode 100644 index 000000000000..7cbd4ec9c499 --- /dev/null +++ b/x/ibc/keeper/querier.go @@ -0,0 +1,24 @@ +package keeper + +import ( + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" +) + +// NewQuerier creates a querier for the IBC module +func NewQuerier(k Keeper) sdk.Querier { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + switch path[0] { + case client.QueryClientState: + return client.QuerierClientState(ctx, req, k.ClientKeeper) + case client.QueryConsensusState: + return client.QuerierConsensusState(ctx, req, k.ClientKeeper) + case client.QueryVerifiedRoot: + return client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) + default: + return nil, sdk.ErrUnknownRequest("unknown IBC client query endpoint") + } + } +} diff --git a/x/ibc/module.go b/x/ibc/module.go index a81836a9c7ed..675b18aa1ddf 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -1 +1,132 @@ package ibc + +import ( + "encoding/json" + + "github.com/gorilla/mux" + "github.com/spf13/cobra" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// TODO: AppModuleSimulation +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the staking module. +type AppModuleBasic struct{} + +var _ module.AppModuleBasic = AppModuleBasic{} + +// Name returns the staking module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterCodec registers the staking module's types for the given codec. +func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { + client.RegisterCodec(cdc) + commitment.RegisterCodec(cdc) +} + +// DefaultGenesis returns default genesis state as raw bytes for the staking +// module. +func (AppModuleBasic) DefaultGenesis() json.RawMessage { + return nil +} + +// ValidateGenesis performs genesis state validation for the staking module. +func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { + return nil +} + +// RegisterRESTRoutes registers the REST routes for the staking module. +func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { + /// TODO: +} + +// GetTxCmd returns the root tx command for the staking module. +func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetTxCmd(StoreKey, cdc) +} + +// GetQueryCmd returns no root query command for the staking module. +func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetQueryCmd(QuerierRoute, cdc) +} + +// AppModule implements an application module for the staking module. +type AppModule struct { + AppModuleBasic + keeper Keeper +} + +// NewAppModule creates a new AppModule object +func NewAppModule(k Keeper) AppModule { + return AppModule{ + keeper: k, + } +} + +// Name returns the staking module's name. +func (AppModule) Name() string { + return ModuleName +} + +// RegisterInvariants registers the staking module invariants. +func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { + // TODO: +} + +// Route returns the message routing key for the staking module. +func (AppModule) Route() string { + return RouterKey +} + +// NewHandler returns an sdk.Handler for the staking module. +func (am AppModule) NewHandler() sdk.Handler { + return NewHandler(am.keeper) +} + +// QuerierRoute returns the staking module's querier route name. +func (AppModule) QuerierRoute() string { + return QuerierRoute +} + +// NewQuerierHandler returns the staking module sdk.Querier. +func (am AppModule) NewQuerierHandler() sdk.Querier { + return NewQuerier(am.keeper) +} + +// InitGenesis performs genesis initialization for the staking module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the staking +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { + return nil +} + +// BeginBlock returns the begin blocker for the staking module. +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { +} + +// EndBlock returns the end blocker for the staking module. It returns no validator +// updates. +func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} diff --git a/x/ibc/types/types.go b/x/ibc/types/types.go new file mode 100644 index 000000000000..535a8f2461e5 --- /dev/null +++ b/x/ibc/types/types.go @@ -0,0 +1,15 @@ +package types + +const ( + // ModuleName is the name of the IBC module + ModuleName = "ibc" + + // StoreKey is the string store representation + StoreKey = ModuleName + + // QuerierRoute is the querier route for the IBC module + QuerierRoute = ModuleName + + // RouterKey is the msg router key for the IBC module + RouterKey = ModuleName +) diff --git a/x/ibc/version/version.go b/x/ibc/version/version.go new file mode 100644 index 000000000000..a7d3275fae5b --- /dev/null +++ b/x/ibc/version/version.go @@ -0,0 +1,13 @@ +package version + +import "strconv" + +const Version int64 = 1 + +func DefaultPrefix() []byte { + return Prefix(Version) +} + +func Prefix(version int64) []byte { + return []byte("v" + strconv.FormatInt(version, 10) + "/") +} From e9f3385cead1db6a583d65adf1f4716573803025 Mon Sep 17 00:00:00 2001 From: Joon Date: Tue, 5 Nov 2019 09:01:33 -0800 Subject: [PATCH 034/176] ICS 03 Implementation (#4517) * add test * in progres * fin rebase * in progress * fin rebase * add CLIObject in progress * cli in progress * add CLIObject * separate testing from tendermint * add key to node * add root and storekey to tests/node, add codec * rm cli/query.go * fix test * fix lint * fix lint * add handler/msgs/client * rm relay * finalize rebase on 23 root/path sep * fix lint, fix syntax * fix querying * extract out context withstore * fix 02-client test * fix 23-commitment test * add query in progress * rm freebase, reformat query * add cli/handler/msg in progress * add cli/msg/handler * add CLIQuery, fix tests * fix golangci * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * add godoc in progress * reformat test * rm XXX * add godoc * modify store * add query * update query.go * update query.go * cli refactor in progress * cli refactor in progress * add Query to boolean.go * fix key * fix cli / merkle test * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * fix test * fix client * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * fix dependency * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * rm commented lines * address review in progress * address review, rm cleanup/closing * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * update expected client keeper and export verification funcs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * start batch-verify tests * minor changes on commitment types * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * use testsuite * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * fix --- client/flags/flags.go | 1 + x/ibc/03-connection/alias.go | 102 ++++ x/ibc/03-connection/client/cli/query.go | 130 ++++ x/ibc/03-connection/client/cli/tx.go | 569 ++++++++++++++++++ x/ibc/03-connection/handler.go | 102 ++++ x/ibc/03-connection/keeper/handshake.go | 256 ++++++++ x/ibc/03-connection/keeper/keeper.go | 171 ++++++ x/ibc/03-connection/keeper/querier.go | 54 ++ x/ibc/03-connection/module.go | 25 + x/ibc/03-connection/types/codec.go | 21 + x/ibc/03-connection/types/connection.go | 143 +++++ x/ibc/03-connection/types/errors.go | 73 +++ x/ibc/03-connection/types/events.go | 23 + x/ibc/03-connection/types/expected_keepers.go | 22 + x/ibc/03-connection/types/keys.go | 41 ++ x/ibc/03-connection/types/msgs.go | 300 +++++++++ x/ibc/03-connection/types/querier.go | 83 +++ x/ibc/03-connection/types/version.go | 96 +++ x/ibc/client/cli/cli.go | 3 + x/ibc/handler.go | 15 +- x/ibc/keeper/keeper.go | 10 +- x/ibc/keeper/querier.go | 33 +- x/ibc/module.go | 2 + 23 files changed, 2265 insertions(+), 10 deletions(-) create mode 100644 x/ibc/03-connection/alias.go create mode 100644 x/ibc/03-connection/client/cli/query.go create mode 100644 x/ibc/03-connection/client/cli/tx.go create mode 100644 x/ibc/03-connection/handler.go create mode 100644 x/ibc/03-connection/keeper/handshake.go create mode 100644 x/ibc/03-connection/keeper/keeper.go create mode 100644 x/ibc/03-connection/keeper/querier.go create mode 100644 x/ibc/03-connection/module.go create mode 100644 x/ibc/03-connection/types/codec.go create mode 100644 x/ibc/03-connection/types/connection.go create mode 100644 x/ibc/03-connection/types/errors.go create mode 100644 x/ibc/03-connection/types/events.go create mode 100644 x/ibc/03-connection/types/expected_keepers.go create mode 100644 x/ibc/03-connection/types/keys.go create mode 100644 x/ibc/03-connection/types/msgs.go create mode 100644 x/ibc/03-connection/types/querier.go create mode 100644 x/ibc/03-connection/types/version.go diff --git a/client/flags/flags.go b/client/flags/flags.go index d609e26729f6..622f582c9956 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -61,6 +61,7 @@ const ( FlagOutputDocument = "output-document" // inspired by wget -O FlagSkipConfirmation = "yes" FlagKeyringBackend = "keyring-backend" + FlagProve = "prove" ) // LineBreak can be included in a command list to provide a blank line diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go new file mode 100644 index 000000000000..27757d8163e5 --- /dev/null +++ b/x/ibc/03-connection/alias.go @@ -0,0 +1,102 @@ +package connection + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/03-connection/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +const ( + NONE = types.NONE + INIT = types.INIT + TRYOPEN = types.TRYOPEN + OPEN = types.OPEN + StateNone = types.StateNone + StateInit = types.StateInit + StateTryOpen = types.StateTryOpen + StateOpen = types.StateOpen + DefaultCodespace = types.DefaultCodespace + CodeConnectionExists = types.CodeConnectionExists + CodeConnectionNotFound = types.CodeConnectionNotFound + CodeClientConnectionPathsNotFound = types.CodeClientConnectionPathsNotFound + CodeConnectionPath = types.CodeConnectionPath + CodeInvalidCounterpartyConnection = types.CodeInvalidCounterpartyConnection + CodeInvalidVersion = types.CodeInvalidVersion + CodeInvalidHeight = types.CodeInvalidHeight + CodeInvalidConnectionState = types.CodeInvalidConnectionState + CodeInvalidProof = types.CodeInvalidProof + CodeInvalidCounterparty = types.CodeInvalidCounterparty + AttributeKeyConnectionID = types.AttributeKeyConnectionID + AttributeKeyCounterpartyClientID = types.AttributeKeyCounterpartyClientID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryConnection = types.QueryConnection + QueryClientConnections = types.QueryClientConnections +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + QuerierConnection = keeper.QuerierConnection + QuerierClientConnections = keeper.QuerierClientConnections + RegisterCodec = types.RegisterCodec + NewConnectionEnd = types.NewConnectionEnd + NewCounterparty = types.NewCounterparty + StateFromString = types.StateFromString + ErrConnectionExists = types.ErrConnectionExists + ErrConnectionNotFound = types.ErrConnectionNotFound + ErrClientConnectionPathsNotFound = types.ErrClientConnectionPathsNotFound + ErrConnectionPath = types.ErrConnectionPath + ErrInvalidCounterpartyConnection = types.ErrInvalidCounterpartyConnection + ErrInvalidVersion = types.ErrInvalidVersion + ErrInvalidHeight = types.ErrInvalidHeight + ErrInvalidConnectionState = types.ErrInvalidConnectionState + ErrInvalidConnectionProof = types.ErrInvalidConnectionProof + ErrInvalidCounterparty = types.ErrInvalidCounterparty + ConnectionPath = types.ConnectionPath + ClientConnectionsPath = types.ClientConnectionsPath + KeyConnection = types.KeyConnection + KeyClientConnections = types.KeyClientConnections + NewMsgConnectionOpenInit = types.NewMsgConnectionOpenInit + NewMsgConnectionOpenTry = types.NewMsgConnectionOpenTry + NewMsgConnectionOpenAck = types.NewMsgConnectionOpenAck + NewMsgConnectionOpenConfirm = types.NewMsgConnectionOpenConfirm + NewConnectionResponse = types.NewConnectionResponse + NewQueryConnectionParams = types.NewQueryConnectionParams + NewClientConnectionsResponse = types.NewClientConnectionsResponse + NewQueryClientConnectionsParams = types.NewQueryClientConnectionsParams + GetCompatibleVersions = types.GetCompatibleVersions + LatestVersion = types.LatestVersion + PickVersion = types.PickVersion + + // variable aliases + SubModuleCdc = types.SubModuleCdc + EventTypeConnectionOpenInit = types.EventTypeConnectionOpenInit + EventTypeConnectionOpenTry = types.EventTypeConnectionOpenTry + EventTypeConnectionOpenAck = types.EventTypeConnectionOpenAck + EventTypeConnectionOpenConfirm = types.EventTypeConnectionOpenConfirm + AttributeValueCategory = types.AttributeValueCategory +) + +type ( + Keeper = keeper.Keeper + ConnectionEnd = types.ConnectionEnd + Counterparty = types.Counterparty + State = types.State + ClientKeeper = types.ClientKeeper + MsgConnectionOpenInit = types.MsgConnectionOpenInit + MsgConnectionOpenTry = types.MsgConnectionOpenTry + MsgConnectionOpenAck = types.MsgConnectionOpenAck + MsgConnectionOpenConfirm = types.MsgConnectionOpenConfirm + ConnectionResponse = types.ConnectionResponse + QueryConnectionParams = types.QueryConnectionParams + ClientConnectionsResponse = types.ClientConnectionsResponse + QueryClientConnectionsParams = types.QueryClientConnectionsParams +) diff --git a/x/ibc/03-connection/client/cli/query.go b/x/ibc/03-connection/client/cli/query.go new file mode 100644 index 000000000000..266ac4bf02d3 --- /dev/null +++ b/x/ibc/03-connection/client/cli/query.go @@ -0,0 +1,130 @@ +package cli + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +// GetQueryCmd returns the query commands for IBC connections +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + ics03ConnectionQueryCmd := &cobra.Command{ + Use: "connection", + Short: "IBC connection query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics03ConnectionQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryConnection(queryRoute, cdc), + )...) + return ics03ConnectionQueryCmd +} + +// GetCmdQueryConnection defines the command to query a connection end +func GetCmdQueryConnection(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "end [connection-id]", + Short: "Query stored connection end", + Long: strings.TrimSpace(fmt.Sprintf(`Query stored connection end + +Example: +$ %s query ibc connection end [connection-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + connectionID := args[0] + + bz, err := cdc.MarshalJSON(types.NewQueryConnectionParams(connectionID)) + if err != nil { + return err + } + + req := abci.RequestQuery{ + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryConnection), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return err + } + + var connection types.ConnectionEnd + if err := cdc.UnmarshalJSON(res.Value, &connection); err != nil { + return err + } + + if res.Proof == nil { + return cliCtx.PrintOutput(connection) + } + + connRes := types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height) + return cliCtx.PrintOutput(connRes) + }, + } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + + return cmd +} + +// GetCmdQueryClientConnections defines the command to query a client connections +func GetCmdQueryClientConnections(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "client [client-id]", + Short: "Query stored client connection paths", + Long: strings.TrimSpace(fmt.Sprintf(`Query stored client connection paths + +Example: +$ %s query ibc connection client [client-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + + bz, err := cdc.MarshalJSON(types.NewQueryClientConnectionsParams(clientID)) + if err != nil { + return err + } + + req := abci.RequestQuery{ + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientConnections), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return err + } + + var connectionPaths []string + if err := cdc.UnmarshalJSON(res.Value, &connectionPaths); err != nil { + return err + } + + if res.Proof == nil { + return cliCtx.PrintOutput(connectionPaths) + } + + connPathsRes := types.NewClientConnectionsResponse(clientID, connectionPaths, res.Proof, res.Height) + return cliCtx.PrintOutput(connPathsRes) + }, + } +} diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go new file mode 100644 index 000000000000..22ccf7777d31 --- /dev/null +++ b/x/ibc/03-connection/client/cli/tx.go @@ -0,0 +1,569 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "os" + "strings" + "time" + + "github.com/pkg/errors" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + abci "github.com/tendermint/tendermint/abci/types" +) + +// Connection Handshake flags +const ( + FlagNode1 = "node1" + FlagNode2 = "node2" + FlagFrom1 = "from1" + FlagFrom2 = "from2" + FlagChainID2 = "chain-id2" +) + +// GetTxCmd returns the transaction commands for IBC Connections +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics03ConnectionTxCmd := &cobra.Command{ + Use: "connection", + Short: "IBC connection transaction subcommands", + } + + ics03ConnectionTxCmd.AddCommand(client.PostCommands( + GetCmdConnectionOpenInit(storeKey, cdc), + GetCmdConnectionOpenTry(storeKey, cdc), + GetCmdConnectionOpenAck(storeKey, cdc), + GetCmdConnectionOpenConfirm(storeKey, cdc), + GetCmdHandshakeState(storeKey, cdc), + )...) + + return ics03ConnectionTxCmd +} + +// GetCmdConnectionOpenInit defines the command to initialize a connection on +// chain A with a given counterparty chain B +func GetCmdConnectionOpenInit(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: strings.TrimSpace(`open-init [connection-id] [client-id] [counterparty-connection-id] + [counterparty-client-id] [path/to/counterparty_prefix.json]`), + Short: "initialize connection on chain A", + Long: strings.TrimSpace( + fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: + +Example: +$ %s tx ibc connection open-init [connection-id] [client-id] [counterparty-connection-id] +[counterparty-client-id] [path/to/counterparty_prefix.json] + `, version.ClientName), + ), + Args: cobra.ExactArgs(6), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + connectionID := args[0] + clientID := args[1] + counterpartyConnectionID := args[2] + counterpartyClientID := args[3] + + bz, err := ioutil.ReadFile(args[4]) + if err != nil { + return err + } + + var counterpartyPrefix commitment.Prefix + if err := cdc.UnmarshalJSON(bz, &counterpartyPrefix); err != nil { + return err + } + + msg := types.NewMsgConnectionOpenInit( + connectionID, clientID, counterpartyConnectionID, counterpartyClientID, + counterpartyPrefix, cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdConnectionOpenTry defines the command to relay a try open a connection on +// chain B +func GetCmdConnectionOpenTry(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: strings.TrimSpace(`open-try [connection-id] [client-id] +[counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] +[counterparty-versions] [path/to/proof_init.json]`), + Short: "initiate connection handshake between two chains", + Long: strings.TrimSpace( + fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: + +Example: +$ %s tx ibc connection open-try connection-id] [client-id] +[counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] +[counterparty-versions] [path/to/proof_init.json] + `, version.ClientName), + ), + Args: cobra.ExactArgs(6), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext(). + WithCodec(cdc). + WithHeight(viper.GetInt64(flags.FlagHeight)) + + connectionID := args[0] + clientID := args[1] + counterpartyConnectionID := args[2] + counterpartyClientID := args[3] + + prefixBz, err := ioutil.ReadFile(args[4]) + if err != nil { + return err + } + + var counterpartyPrefix commitment.Prefix + if err := cdc.UnmarshalJSON(prefixBz, &counterpartyPrefix); err != nil { + return err + } + + // TODO: parse strings? + counterpartyVersions := args[5] + + proofBz, err := ioutil.ReadFile(args[6]) + if err != nil { + return err + } + + var proofInit commitment.Proof + if err := cdc.UnmarshalJSON(proofBz, &proofInit); err != nil { + return err + } + + proofHeight := uint64(cliCtx.Height) + consensusHeight, err := lastHeight(cliCtx) + if err != nil { + return err + } + + msg := types.NewMsgConnectionOpenTry( + connectionID, clientID, counterpartyConnectionID, counterpartyClientID, + counterpartyPrefix, []string{counterpartyVersions}, proofInit, proofInit, proofHeight, + consensusHeight, cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdConnectionOpenAck defines the command to relay the acceptance of a +// connection open attempt from chain B to chain A +func GetCmdConnectionOpenAck(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-ack [connection-id] [path/to/proof_try.json] [version]", + Short: "relay the acceptance of a connection open attempt from chain B to chain A", + Long: strings.TrimSpace( + fmt.Sprintf(`relay the acceptance of a connection open attempt from chain B to chain A: + +Example: +$ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [version] + `, version.ClientName), + ), + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + connectionID := args[0] + proofBz, err := ioutil.ReadFile(args[1]) + if err != nil { + return err + } + + var proofTry commitment.Proof + if err := cdc.UnmarshalJSON(proofBz, &proofTry); err != nil { + return err + } + + proofHeight := uint64(cliCtx.Height) + consensusHeight, err := lastHeight(cliCtx) + if err != nil { + return err + } + + version := args[4] + + msg := types.NewMsgConnectionOpenAck( + connectionID, proofTry, proofTry, proofHeight, + consensusHeight, version, cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// GetCmdConnectionOpenConfirm defines the command to initialize a connection on +// chain A with a given counterparty chain B +func GetCmdConnectionOpenConfirm(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-confirm [connection-id] [path/to/proof_ack.json]", + Short: "confirm to chain B that connection is open on chain A", + Long: strings.TrimSpace( + fmt.Sprintf(`confirm to chain B that connection is open on chain A: + +Example: +$ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] + `, version.ClientName), + ), + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext(). + WithCodec(cdc). + WithHeight(viper.GetInt64(flags.FlagHeight)) + + connectionID := args[0] + + proofBz, err := ioutil.ReadFile(args[1]) + if err != nil { + return err + } + + var proofAck commitment.Proof + if err := cdc.UnmarshalJSON(proofBz, &proofAck); err != nil { + return err + } + + proofHeight := uint64(cliCtx.Height) + + msg := types.NewMsgConnectionOpenConfirm( + connectionID, proofAck, proofHeight, cliCtx.GetFromAddress(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + return cmd +} + +// lastHeight util function to get the consensus height from the node +func lastHeight(cliCtx context.CLIContext) (uint64, error) { + node, err := cliCtx.GetNode() + if err != nil { + return 0, err + } + + info, err := node.ABCIInfo() + if err != nil { + return 0, err + } + + return uint64(info.Response.LastBlockHeight), nil +} + +func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "handshake [conn-id-chain-1] [client-id-chain-1] [path-chain-1] [conn-id-chain-2] [client-id-chain-2] [path-chain-2] ", + Short: "initiate connection handshake between two chains", + Args: cobra.ExactArgs(6), + RunE: func(cmd *cobra.Command, args []string) error { + + viper.Set(flags.FlagProve, true) + + // --chain-id values for each chain + cid1 := viper.GetString(flags.FlagChainID) + cid2 := viper.GetString(FlagChainID2) + + // --from values for each wallet + from1 := viper.GetString(FlagFrom1) + from2 := viper.GetString(FlagFrom2) + + // --node values for each RPC + rpc1 := viper.GetString(FlagNode1) + rpc2 := viper.GetString(FlagNode2) + + // ibc connection-id for each chain + connID1 := args[0] + connID2 := args[3] + + // ibc client-id for each chain + clientID1 := args[1] + clientID2 := args[4] + + // Get default version + version := types.GetCompatibleVersions()[0] + + // Create txbldr, clictx, querier for cid1 + viper.Set(flags.FlagChainID, cid1) + txBldr1 := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx1 := context.NewCLIContextIBC(from1, cid1, rpc1).WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + // Create txbldr, clictx, querier for cid1 + viper.Set(flags.FlagChainID, cid2) + txBldr2 := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx2 := context.NewCLIContextIBC(from2, cid2, rpc2).WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + // read in path for cid1 + path1, err := parsePath(ctx1.Codec, args[2]) + if err != nil { + return err + } + + // read in path for cid2 + path2, err := parsePath(ctx1.Codec, args[5]) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + msgOpenInit := types.NewMsgConnectionOpenInit( + connID1, clientID1, connID2, clientID2, + path2, ctx1.GetFromAddress(), + ) + + if err := msgOpenInit.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenInit}) + if err != nil { + return err + } + + // Another block has to be passed after msgOpenInit is committed + // to retrieve the correct proofs + // TODO: Modify this to actually check two blocks being processed, and + // remove hardcoding this to 8 seconds. + time.Sleep(8 * time.Second) + + header, err := clientutils.GetTendermintHeader(ctx1) + if err != nil { + return err + } + + // Create and send msgUpdateClient + viper.Set(flags.FlagChainID, cid2) + msgUpdateClient := clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) + + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + fmt.Printf(" [OK] client(%v)\n", clientID1) + + // Fetch proofs from cid1 + viper.Set(flags.FlagChainID, cid1) + proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) + if err != nil { + return err + } + + csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1) + if err != nil { + return err + } + + // Create and send msgOpenTry + viper.Set(flags.FlagChainID, cid2) + msgOpenTry := types.NewMsgConnectionOpenTry(connID2, clientID2, connID1, clientID1, path1, []string{version}, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), ctx2.GetFromAddress()) + + if err := msgOpenTry.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenTry}) + if err != nil { + return err + } + + fmt.Printf(" [OK] client(%v) connection(%v)\n", clientID2, connID2) + + // Another block has to be passed after msgOpenInit is committed + // to retrieve the correct proofs + // TODO: Modify this to actually check two blocks being processed, and + // remove hardcoding this to 8 seconds. + time.Sleep(8 * time.Second) + + header, err = clientutils.GetTendermintHeader(ctx2) + if err != nil { + return err + } + + // Update the client for cid2 on cid1 + viper.Set(flags.FlagChainID, cid1) + msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID1, header, ctx1.GetFromAddress()) + + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + fmt.Printf(" [OK] client(%v)\n", clientID2) + + // Fetch proofs from cid2 + viper.Set(flags.FlagChainID, cid2) + proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), connID2, storeKey) + if err != nil { + return err + } + + csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2) + if err != nil { + return err + } + + // Create and send msgOpenAck + viper.Set(flags.FlagChainID, cid1) + msgOpenAck := types.NewMsgConnectionOpenAck(connID1, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), version, ctx1.GetFromAddress()) + + if err := msgOpenAck.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenAck}) + if err != nil { + return err + } + fmt.Printf(" [OK] connection(%v)\n", connID1) + + // Another block has to be passed after msgOpenInit is committed + // to retrieve the correct proofs + // TODO: Modify this to actually check two blocks being processed, and + // remove hardcoding this to 8 seconds. + time.Sleep(8 * time.Second) + + header, err = clientutils.GetTendermintHeader(ctx1) + if err != nil { + return err + } + + // Update client for cid1 on cid2 + viper.Set(flags.FlagChainID, cid2) + msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) + + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + fmt.Printf(" [OK] client(%v)\n", clientID1) + + // Fetch proof from cid1 + viper.Set(flags.FlagChainID, cid1) + proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) + if err != nil { + return err + } + + // Create and send msgOpenConfirm + viper.Set(flags.FlagChainID, cid2) + msgOpenConfirm := types.NewMsgConnectionOpenConfirm(connID2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + + if err := msgOpenConfirm.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}) + if err != nil { + return err + } + fmt.Printf(" [OK] connection(%v)\n", connID2) + + return nil + }, + } + + cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") + cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") + cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") + cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") + cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") + + cmd.MarkFlagRequired(FlagNode1) + cmd.MarkFlagRequired(FlagNode2) + cmd.MarkFlagRequired(FlagFrom1) + cmd.MarkFlagRequired(FlagFrom2) + cmd.MarkFlagRequired(FlagChainID2) + + return cmd +} + +func queryProofs(ctx client.CLIContext, connectionID string, queryRoute string) (types.ConnectionResponse, error) { + + var connRes types.ConnectionResponse + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: []byte(fmt.Sprintf("connections/%s", connectionID)), + Prove: true, + } + res, err := ctx.QueryABCI(req) + if err != nil { + return connRes, err + } + + var connection types.ConnectionEnd + if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { + return connRes, err + } + return types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height), nil +} + +func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { + var path commitment.Prefix + if err := cdc.UnmarshalJSON([]byte(arg), &path); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(arg) + if err != nil { + return path, errors.Wrap(err, "error opening path file") + } + if err := cdc.UnmarshalJSON(contents, &path); err != nil { + return path, errors.Wrap(err, "error unmarshalling path file") + } + } + return path, nil +} diff --git a/x/ibc/03-connection/handler.go b/x/ibc/03-connection/handler.go new file mode 100644 index 000000000000..854436eadd6a --- /dev/null +++ b/x/ibc/03-connection/handler.go @@ -0,0 +1,102 @@ +package connection + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +// HandleMsgConnectionOpenInit defines the sdk.Handler for MsgConnectionOpenInit +func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenInit) sdk.Result { + err := k.ConnOpenInit(ctx, msg.ConnectionID, msg.ClientID, msg.Counterparty) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeConnectionOpenInit, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + sdk.NewAttribute(types.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgConnectionOpenTry defines the sdk.Handler for MsgConnectionOpenTry +func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenTry) sdk.Result { + err := k.ConnOpenTry( + ctx, msg.ConnectionID, msg.Counterparty, msg.ClientID, + msg.CounterpartyVersions, msg.ProofInit, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeConnectionOpenTry, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + sdk.NewAttribute(types.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgConnectionOpenAck defines the sdk.Handler for MsgConnectionOpenAck +func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenAck) sdk.Result { + err := k.ConnOpenAck( + ctx, msg.ConnectionID, msg.Version, msg.ProofTry, msg.ProofConsensus, + msg.ProofHeight, msg.ConsensusHeight, + ) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeConnectionOpenAck, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgConnectionOpenConfirm defines the sdk.Handler for MsgConnectionOpenConfirm +func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenConfirm) sdk.Result { + err := k.ConnOpenConfirm(ctx, msg.ConnectionID, msg.ProofAck, msg.ProofHeight) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeConnectionOpenConfirm, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go new file mode 100644 index 000000000000..21a005b12c9f --- /dev/null +++ b/x/ibc/03-connection/keeper/handshake.go @@ -0,0 +1,256 @@ +package keeper + +import ( + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// ConnOpenInit initialises a connection attempt on chain A. +// +// NOTE: Identifiers are checked on msg validation. +func (k Keeper) ConnOpenInit( + ctx sdk.Context, + connectionID, // identifier + clientID string, + counterparty types.Counterparty, // desiredCounterpartyConnectionIdentifier, counterpartyPrefix, counterpartyClientIdentifier +) error { + _, found := k.GetConnection(ctx, connectionID) + if found { + return sdkerrors.Wrap(types.ErrConnectionExists(k.codespace, connectionID), "cannot initialize connection") + } + + // connection defines chain A's ConnectionEnd + connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.GetCompatibleVersions()) + k.SetConnection(ctx, connectionID, connection) + + err := k.addConnectionToClient(ctx, clientID, connectionID) + if err != nil { + sdkerrors.Wrap(err, "cannot initialize connection") + } + + k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: NONE -> INIT", connectionID)) + return nil +} + +// ConnOpenTry relays notice of a connection attempt on chain A to chain B (this +// code is executed on chain B). +// +// NOTE: +// - Here chain A acts as the counterparty +// - Identifiers are checked on msg validation +func (k Keeper) ConnOpenTry( + ctx sdk.Context, + connectionID string, // desiredIdentifier + counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier + clientID string, + counterpartyVersions []string, + proofInit commitment.ProofI, + proofConsensus commitment.ProofI, + proofHeight uint64, + consensusHeight uint64, +) error { + // XXX: blocked by #5078 + /* + if consensusHeight > uint64(ctx.BlockHeight()) { + return errors.New("invalid consensus height") // TODO: sdk.Error + } + + expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, clientID) + if !found { + return errors.New("client consensus state not found") // TODO: use ICS02 error + } + */ + + // expectedConn defines Chain A's ConnectionEnd + // NOTE: chain A's counterparty is chain B (i.e where this code is executed) + prefix := k.GetCommitmentPrefix() + expectedCounterparty := types.NewCounterparty(clientID, connectionID, prefix) + expectedConn := types.NewConnectionEnd(types.INIT, counterparty.ClientID, expectedCounterparty, counterpartyVersions) + + // chain B picks a version from Chain A's available versions that is compatible + // with the supported IBC versions + version := types.PickVersion(counterpartyVersions, types.GetCompatibleVersions()) + + // connection defines chain B's ConnectionEnd + connection := types.NewConnectionEnd(types.NONE, clientID, counterparty, []string{version}) + expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) + if err != nil { + return err + } + + ok := k.VerifyMembership( + ctx, connection, proofHeight, proofInit, + types.ConnectionPath(counterparty.ConnectionID), expConnBz, + ) + if !ok { + return errors.New("couldn't verify connection membership on counterparty's client") // TODO: sdk.Error + } + + // XXX: blocked by #5078 + /* + expConsStateBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConsensusState) + if err != nil { + return err + } + + ok = k.VerifyMembership( + ctx, connection, proofHeight, proofConsensus, + clienttypes.ConsensusStatePath(counterparty.ClientID), expConsStateBz, + ) + if !ok { + fmt.Sprintf("couldn't verify consensus state membership on counterparty's client\n") + return errors.New("couldn't verify consensus state membership on counterparty's client") // TODO: sdk.Error + } + + */ + + _, found := k.GetConnection(ctx, connectionID) + if found { + return sdkerrors.Wrap(types.ErrConnectionExists(k.codespace, connectionID), "cannot relay connection attempt") + } + + connection.State = types.TRYOPEN + err = k.addConnectionToClient(ctx, clientID, connectionID) + if err != nil { + return sdkerrors.Wrap(err, "cannot relay connection attempt") + } + + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: NONE -> TRYOPEN ", connectionID)) + return nil +} + +// ConnOpenAck relays acceptance of a connection open attempt from chain B back +// to chain A (this code is executed on chain A). +// +// NOTE: Identifiers are checked on msg validation. +func (k Keeper) ConnOpenAck( + ctx sdk.Context, + connectionID string, + version string, + proofTry commitment.ProofI, + proofConsensus commitment.ProofI, + proofHeight uint64, + consensusHeight uint64, +) error { + // XXX: blocked by #5078 + /* + if consensusHeight > uint64(ctx.BlockHeight()) { + return errors.New("invalid consensus height") // TODO: sdk.Error + } + */ + connection, found := k.GetConnection(ctx, connectionID) + if !found { + return sdkerrors.Wrap(types.ErrConnectionNotFound(k.codespace, connectionID), "cannot relay ACK of open attempt") + } + + if connection.State != types.INIT { + return types.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not INIT (got %s)", connection.State.String()), + ) + } + + if types.LatestVersion(connection.Versions) != version { + return types.ErrInvalidVersion( + k.codespace, + fmt.Sprintf("connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version), + ) + } + + // XXX: blocked by #5078 + /* + expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, connection.ClientID) + if !found { + return errors.New("client consensus state not found") // TODO: use ICS02 error + } + */ + prefix := k.GetCommitmentPrefix() + expectedCounterparty := types.NewCounterparty(connection.ClientID, connectionID, prefix) + expectedConn := types.NewConnectionEnd(types.TRYOPEN, connection.Counterparty.ClientID, expectedCounterparty, []string{version}) + + expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) + if err != nil { + return err + } + + ok := k.VerifyMembership( + ctx, connection, proofHeight, proofTry, + types.ConnectionPath(connection.Counterparty.ConnectionID), expConnBz, + ) + if !ok { + return errors.New("couldn't verify connection membership on counterparty's client") // TODO: sdk.Error + } + + // XXX: blocked by #5078 + /* + expConsStateBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConsensusState) + if err != nil { + return err + } + + ok = k.VerifyMembership( + ctx, connection, proofHeight, proofConsensus, + clienttypes.ConsensusStatePath(connection.Counterparty.ClientID), expConsStateBz, + ) + if !ok { + return errors.New("couldn't verify consensus state membership on counterparty's client") // TODO: sdk.Error + } + + */ + connection.State = types.OPEN + connection.Versions = []string{version} + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: INIT -> OPEN ", connectionID)) + return nil +} + +// ConnOpenConfirm confirms opening of a connection on chain A to chain B, after +// which the connection is open on both chains (this code is executed on chain B). +// +// NOTE: Identifiers are checked on msg validation. +func (k Keeper) ConnOpenConfirm( + ctx sdk.Context, + connectionID string, + proofAck commitment.ProofI, + proofHeight uint64, +) error { + connection, found := k.GetConnection(ctx, connectionID) + if !found { + return sdkerrors.Wrap(types.ErrConnectionNotFound(k.codespace, connectionID), "cannot relay ACK of open attempt") + } + + if connection.State != types.TRYOPEN { + return types.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not TRYOPEN (got %s)", connection.State.String()), + ) + } + + prefix := k.GetCommitmentPrefix() + expectedCounterparty := types.NewCounterparty(connection.ClientID, connectionID, prefix) + expectedConn := types.NewConnectionEnd(types.OPEN, connection.Counterparty.ClientID, expectedCounterparty, connection.Versions) + + expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) + if err != nil { + return err + } + + ok := k.VerifyMembership( + ctx, connection, proofHeight, proofAck, + types.ConnectionPath(connection.Counterparty.ConnectionID), expConnBz, + ) + if !ok { + return types.ErrInvalidCounterpartyConnection(k.codespace) + } + + connection.State = types.OPEN + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: TRYOPEN -> OPEN ", connectionID)) + return nil +} diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go new file mode 100644 index 000000000000..1488c6c03ec7 --- /dev/null +++ b/x/ibc/03-connection/keeper/keeper.go @@ -0,0 +1,171 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// Keeper defines the IBC connection keeper +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store + + clientKeeper types.ClientKeeper +} + +// NewKeeper creates a new IBC connection Keeper instance +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, ck types.ClientKeeper) Keeper { + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/connection", + prefix: []byte{}, + // prefix: []byte(types.SubModuleName + "/"), // "connection/" + clientKeeper: ck, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName)) +} + +// GetCommitmentPrefix returns the IBC connection store prefix as a commitment +// Prefix +func (k Keeper) GetCommitmentPrefix() commitment.PrefixI { + return commitment.NewPrefix([]byte(k.storeKey.Name())) +} + +// GetConnection returns a connection with a particular identifier +func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyConnection(connectionID)) + if bz == nil { + return types.ConnectionEnd{}, false + } + + var connection types.ConnectionEnd + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &connection) + return connection, true +} + +// SetConnection sets a connection to the store +func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(connection) + store.Set(types.KeyConnection(connectionID), bz) +} + +// GetClientConnectionPaths returns all the connection paths stored under a +// particular client +func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyClientConnections(clientID)) + if bz == nil { + return nil, false + } + + var paths []string + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &paths) + return paths, true +} + +// SetClientConnectionPaths sets the connections paths for client +func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths []string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(paths) + store.Set(types.KeyClientConnections(clientID), bz) +} + +// addConnectionToClient is used to add a connection identifier to the set of +// connections associated with a client. +// +// CONTRACT: client must already exist +func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID string) sdk.Error { + conns, found := k.GetClientConnectionPaths(ctx, clientID) + if !found { + conns = []string{} + } + + conns = append(conns, connectionID) + k.SetClientConnectionPaths(ctx, clientID, conns) + return nil +} + +// removeConnectionFromClient is used to remove a connection identifier from the +// set of connections associated with a client. +// +// CONTRACT: client must already exist +func (k Keeper) removeConnectionFromClient(ctx sdk.Context, clientID, connectionID string) sdk.Error { + conns, found := k.GetClientConnectionPaths(ctx, clientID) + if !found { + return types.ErrClientConnectionPathsNotFound(k.codespace, clientID) + } + + conns, ok := host.RemovePath(conns, connectionID) + if !ok { + return types.ErrConnectionPath(k.codespace) + } + + k.SetClientConnectionPaths(ctx, clientID, conns) + return nil +} + +// VerifyMembership helper function for state membership verification +func (k Keeper) VerifyMembership( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + pathStr string, + value []byte, +) bool { + // FIXME: commented out for demo + /* + clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) + if !found { + return false + } + */ + path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) + if err != nil { + return false + } + + return k.clientKeeper.VerifyMembership(ctx, connection.ClientID, height, proof, path, value) +} + +// VerifyNonMembership helper function for state non-membership verification +func (k Keeper) VerifyNonMembership( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + pathStr string, +) bool { + // FIXME: commented out for demo + /* + clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) + if !found { + return false + } + */ + + path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) + if err != nil { + return false + } + + return k.clientKeeper.VerifyNonMembership(ctx, connection.ClientID, height, proof, path) +} diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go new file mode 100644 index 000000000000..85bb02559e78 --- /dev/null +++ b/x/ibc/03-connection/keeper/querier.go @@ -0,0 +1,54 @@ +package keeper + +import ( + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +// QuerierConnection defines the sdk.Querier to query a connection end +func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryConnectionParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + connection, found := k.GetConnection(ctx, params.ConnectionID) + if !found { + return nil, types.ErrConnectionNotFound(k.codespace, params.ConnectionID) + } + + bz, err := types.SubModuleCdc.MarshalJSON(connection) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} + +// QuerierClientConnections defines the sdk.Querier to query the client connections +func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryClientConnectionsParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + clientConnectionPaths, found := k.GetClientConnectionPaths(ctx, params.ClientID) + if !found { + return nil, types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID) + } + + bz, err := types.SubModuleCdc.MarshalJSON(clientConnectionPaths) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} diff --git a/x/ibc/03-connection/module.go b/x/ibc/03-connection/module.go new file mode 100644 index 000000000000..713ed04d6c6b --- /dev/null +++ b/x/ibc/03-connection/module.go @@ -0,0 +1,25 @@ +package connection + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/cli" +) + +// Name returns the IBC connection ICS name +func Name() string { + return SubModuleName +} + +// GetTxCmd returns the root tx command for the IBC connections. +func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + return cli.GetTxCmd(fmt.Sprintf("%s/%s", storeKey, SubModuleName), cdc) +} + +// GetQueryCmd returns no root query command for the IBC connections. +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + return cli.GetQueryCmd(fmt.Sprintf("%s/%s", queryRoute, SubModuleName), cdc) +} diff --git a/x/ibc/03-connection/types/codec.go b/x/ibc/03-connection/types/codec.go new file mode 100644 index 000000000000..23fb04e37a8f --- /dev/null +++ b/x/ibc/03-connection/types/codec.go @@ -0,0 +1,21 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" +) + +// SubModuleCdc defines the IBC connection codec. +var SubModuleCdc = codec.New() + +// RegisterCodec registers the IBC connection types +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterConcrete(MsgConnectionOpenInit{}, "ibc/connection/MsgConnectionOpenInit", nil) + cdc.RegisterConcrete(MsgConnectionOpenTry{}, "ibc/connection/MsgConnectionOpenTry", nil) + cdc.RegisterConcrete(MsgConnectionOpenAck{}, "ibc/connection/MsgConnectionOpenAck", nil) + cdc.RegisterConcrete(MsgConnectionOpenConfirm{}, "ibc/connection/MsgConnectionOpenConfirm", nil) + cdc.RegisterConcrete(ConnectionEnd{}, "ibc/connection/ConnectionEnd", nil) +} + +func init() { + RegisterCodec(SubModuleCdc) +} diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go new file mode 100644 index 000000000000..07eb0a25c6ac --- /dev/null +++ b/x/ibc/03-connection/types/connection.go @@ -0,0 +1,143 @@ +package types + +import ( + "encoding/json" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +// ICS03 - Connection Data Structures as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#data-structures + +// ConnectionEnd defines a stateful object on a chain connected to another separate +// one. +// NOTE: there must only be 2 defined ConnectionEnds to stablish a connection +// between two chains. +type ConnectionEnd struct { + State State `json:"state" yaml:"state"` + ClientID string `json:"client_id" yaml:"client_id"` + + // Counterparty chain associated with this connection. + Counterparty Counterparty `json:"counterparty" yaml:"counterparty"` + // Version is utilised to determine encodings or protocols for channels or + // packets utilising this connection. + Versions []string `json:"versions" yaml:"versions"` +} + +// NewConnectionEnd creates a new ConnectionEnd instance. +func NewConnectionEnd(state State, clientID string, counterparty Counterparty, versions []string) ConnectionEnd { + return ConnectionEnd{ + State: state, + ClientID: clientID, + Counterparty: counterparty, + Versions: versions, + } +} + +// TODO: create a custom JSON marshaler + +// Counterparty defines the counterparty chain associated with a connection end. +type Counterparty struct { + ClientID string `json:"client_id" yaml:"client_id"` + ConnectionID string `json:"connection_id" yaml:"connection_id"` + Prefix commitment.PrefixI `json:"prefix" yaml:"prefix"` +} + +// NewCounterparty creates a new Counterparty instance. +func NewCounterparty(clientID, connectionID string, prefix commitment.PrefixI) Counterparty { + return Counterparty{ + ClientID: clientID, + ConnectionID: connectionID, + Prefix: prefix, + } +} + +// ValidateBasic performs a basic validation check of the identifiers and prefix +func (c Counterparty) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(c.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty connection ID: %s", err.Error())) + } + if err := host.DefaultClientIdentifierValidator(c.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty client ID: %s", err.Error())) + } + if c.Prefix == nil || len(c.Prefix.Bytes()) == 0 { + return ErrInvalidCounterparty(DefaultCodespace, "invalid counterparty prefix") + } + return nil +} + +// State defines the state of a connection between two disctinct +// chains +type State byte + +// available connection states +const ( + NONE State = iota // default State + INIT + TRYOPEN + OPEN +) + +// string representation of the connection states +const ( + StateNone string = "NONE" + StateInit string = "INIT" + StateTryOpen string = "TRYOPEN" + StateOpen string = "OPEN" +) + +// String implements the Stringer interface +func (cs State) String() string { + switch cs { + case NONE: + return StateNone + case INIT: + return StateInit + case TRYOPEN: + return StateTryOpen + case OPEN: + return StateOpen + default: + return "" + } +} + +// StateFromString parses a string into a connection state +func StateFromString(state string) (State, error) { + switch state { + case StateNone: + return NONE, nil + case StateInit: + return INIT, nil + case StateTryOpen: + return TRYOPEN, nil + case StateOpen: + return OPEN, nil + default: + return NONE, fmt.Errorf("'%s' is not a valid connection state", state) + } +} + +// MarshalJSON marshal to JSON using string. +func (cs State) MarshalJSON() ([]byte, error) { + return json.Marshal(cs.String()) +} + +// UnmarshalJSON decodes from JSON assuming Bech32 encoding. +func (cs *State) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + bz2, err := StateFromString(s) + if err != nil { + return err + } + + *cs = bz2 + return nil +} diff --git a/x/ibc/03-connection/types/errors.go b/x/ibc/03-connection/types/errors.go new file mode 100644 index 000000000000..b2a2cbe2ad5f --- /dev/null +++ b/x/ibc/03-connection/types/errors.go @@ -0,0 +1,73 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// connection error codes +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName + + CodeConnectionExists sdk.CodeType = 101 + CodeConnectionNotFound sdk.CodeType = 102 + CodeClientConnectionPathsNotFound sdk.CodeType = 103 + CodeConnectionPath sdk.CodeType = 104 + CodeInvalidCounterpartyConnection sdk.CodeType = 105 + CodeInvalidVersion sdk.CodeType = 106 + CodeInvalidHeight sdk.CodeType = 107 + CodeInvalidConnectionState sdk.CodeType = 108 + CodeInvalidProof sdk.CodeType = 109 + CodeInvalidCounterparty sdk.CodeType = 110 +) + +// ErrConnectionExists implements sdk.Error +func ErrConnectionExists(codespace sdk.CodespaceType, connectionID string) sdk.Error { + return sdk.NewError(codespace, CodeConnectionExists, fmt.Sprintf("connection with ID %s already exists", connectionID)) +} + +// ErrConnectionNotFound implements sdk.Error +func ErrConnectionNotFound(codespace sdk.CodespaceType, connectionID string) sdk.Error { + return sdk.NewError(codespace, CodeConnectionNotFound, fmt.Sprintf("connection with ID %s not found", connectionID)) +} + +// ErrClientConnectionPathsNotFound implements sdk.Error +func ErrClientConnectionPathsNotFound(codespace sdk.CodespaceType, clientID string) sdk.Error { + return sdk.NewError(codespace, CodeClientConnectionPathsNotFound, fmt.Sprintf("client connection paths not found for ID %s", clientID)) +} + +// ErrConnectionPath implements sdk.Error +func ErrConnectionPath(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeConnectionPath, "connection path is not associated to the client") +} + +// ErrInvalidCounterpartyConnection implements sdk.Error +func ErrInvalidCounterpartyConnection(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidCounterpartyConnection, "couldn't verify connection membership on counterparty's client") +} + +// ErrInvalidVersion implements sdk.Error +func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidVersion, msg) +} + +// ErrInvalidHeight implements sdk.Error +func ErrInvalidHeight(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidHeight, msg) +} + +// ErrInvalidConnectionState implements sdk.Error +func ErrInvalidConnectionState(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidConnectionState, msg) +} + +// ErrInvalidConnectionProof implements sdk.Error +func ErrInvalidConnectionProof(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidProof, msg) +} + +// ErrInvalidCounterparty implements sdk.Error +func ErrInvalidCounterparty(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidCounterparty, msg) +} diff --git a/x/ibc/03-connection/types/events.go b/x/ibc/03-connection/types/events.go new file mode 100644 index 000000000000..2ede46db907c --- /dev/null +++ b/x/ibc/03-connection/types/events.go @@ -0,0 +1,23 @@ +package types + +import ( + "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// IBC connection events +const ( + AttributeKeyConnectionID = "connection_id" + AttributeKeyCounterpartyClientID = "counterparty_client_id" +) + +// IBC connection events vars +var ( + EventTypeConnectionOpenInit = MsgConnectionOpenInit{}.Type() + EventTypeConnectionOpenTry = MsgConnectionOpenTry{}.Type() + EventTypeConnectionOpenAck = MsgConnectionOpenAck{}.Type() + EventTypeConnectionOpenConfirm = MsgConnectionOpenConfirm{}.Type() + + AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) +) diff --git a/x/ibc/03-connection/types/expected_keepers.go b/x/ibc/03-connection/types/expected_keepers.go new file mode 100644 index 000000000000..1a114f6f8374 --- /dev/null +++ b/x/ibc/03-connection/types/expected_keepers.go @@ -0,0 +1,22 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// ClientKeeper expected account IBC client keeper +type ClientKeeper interface { + GetConsensusState(ctx sdk.Context, clientID string) (clientexported.ConsensusState, bool) + GetClientState(ctx sdk.Context, clientID string) (client.State, bool) + VerifyMembership( + ctx sdk.Context, clientID string, height uint64, + proof commitment.ProofI, path commitment.PathI, value []byte, + ) bool + VerifyNonMembership( + ctx sdk.Context, clientID string, height uint64, + proof commitment.ProofI, path commitment.PathI, + ) bool +} diff --git a/x/ibc/03-connection/types/keys.go b/x/ibc/03-connection/types/keys.go new file mode 100644 index 000000000000..7dd82ae80a2e --- /dev/null +++ b/x/ibc/03-connection/types/keys.go @@ -0,0 +1,41 @@ +package types + +import ( + "fmt" +) + +const ( + // SubModuleName defines the IBC connection name + SubModuleName = "connection" + + // StoreKey is the store key string for IBC connections + StoreKey = SubModuleName + + // RouterKey is the message route for IBC connections + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC connections + QuerierRoute = SubModuleName +) + +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths + +// ConnectionPath defines the path under which connection paths are stored +func ConnectionPath(connectionID string) string { + return fmt.Sprintf("connections/%s", connectionID) +} + +// ClientConnectionsPath defines a reverse mapping from clients to a set of connections +func ClientConnectionsPath(clientID string) string { + return fmt.Sprintf("clients/%s/connections", clientID) +} + +// KeyConnection returns the store key for a particular connection +func KeyConnection(connectionID string) []byte { + return []byte(ConnectionPath(connectionID)) +} + +// KeyClientConnections returns the store key for the connectios of a given client +func KeyClientConnections(clientID string) []byte { + return []byte(ClientConnectionsPath(clientID)) +} diff --git a/x/ibc/03-connection/types/msgs.go b/x/ibc/03-connection/types/msgs.go new file mode 100644 index 000000000000..10ede21b1124 --- /dev/null +++ b/x/ibc/03-connection/types/msgs.go @@ -0,0 +1,300 @@ +package types + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +var _ sdk.Msg = MsgConnectionOpenInit{} + +// MsgConnectionOpenInit defines the msg sent by an account on Chain A to +// initialize a connection with Chain B. +type MsgConnectionOpenInit struct { + ConnectionID string `json:"connection_id"` + ClientID string `json:"client_id"` + Counterparty Counterparty `json:"counterparty"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance +func NewMsgConnectionOpenInit( + connectionID, clientID, counterpartyConnectionID, + counterpartyClientID string, counterpartyPrefix commitment.PrefixI, + signer sdk.AccAddress, +) MsgConnectionOpenInit { + counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) + return MsgConnectionOpenInit{ + ConnectionID: connectionID, + ClientID: clientID, + Counterparty: counterparty, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgConnectionOpenInit) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgConnectionOpenInit) Type() string { + return "connection_open_init" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgConnectionOpenInit) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + } + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("missing signer address") + } + return msg.Counterparty.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgConnectionOpenInit) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgConnectionOpenInit) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgConnectionOpenTry{} + +// MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a connection +// on Chain B. +type MsgConnectionOpenTry struct { + ConnectionID string `json:"connection_id"` + ClientID string `json:"client_id"` + Counterparty Counterparty `json:"counterparty"` + CounterpartyVersions []string `json:"counterparty_versions"` + ProofInit commitment.ProofI `json:"proof_init"` // proof of the initialization the connection on Chain A: `none -> INIT` + ProofConsensus commitment.ProofI `json:"proof_consensus"` // proof of client consensus state + ProofHeight uint64 `json:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgConnectionOpenTry creates a new MsgConnectionOpenTry instance +func NewMsgConnectionOpenTry( + connectionID, clientID, counterpartyConnectionID, + counterpartyClientID string, counterpartyPrefix commitment.PrefixI, + counterpartyVersions []string, proofInit, proofConsensus commitment.ProofI, + proofHeight, consensusHeight uint64, signer sdk.AccAddress, +) MsgConnectionOpenTry { + counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) + return MsgConnectionOpenTry{ + ConnectionID: connectionID, + ClientID: clientID, + Counterparty: counterparty, + CounterpartyVersions: counterpartyVersions, + ProofInit: proofInit, + ProofConsensus: proofConsensus, + ProofHeight: proofHeight, + ConsensusHeight: consensusHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgConnectionOpenTry) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgConnectionOpenTry) Type() string { + return "connection_open_try" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgConnectionOpenTry) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + } + if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + } + if len(msg.CounterpartyVersions) == 0 { + return ErrInvalidVersion(DefaultCodespace, "missing counterparty versions") + } + for _, version := range msg.CounterpartyVersions { + if strings.TrimSpace(version) == "" { + return ErrInvalidVersion(DefaultCodespace, "version can't be blank") + } + } + if msg.ProofInit == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof init cannot be nil") + } + if msg.ProofConsensus == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof consensus cannot be nil") + } + if msg.ProofHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + } + if msg.ConsensusHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0") + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("missing signer address") + } + return msg.Counterparty.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgConnectionOpenTry) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgConnectionOpenTry) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgConnectionOpenAck{} + +// MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to acknowledge +// the change of connection state to TRYOPEN on Chain B. +type MsgConnectionOpenAck struct { + ConnectionID string `json:"connection_id"` + ProofTry commitment.ProofI `json:"proof_try"` // proof for the change of the connection state on Chain B: `none -> TRYOPEN` + ProofConsensus commitment.ProofI `json:"proof_consensus"` // proof of client consensus state + ProofHeight uint64 `json:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height"` + Version string `json:"version"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgConnectionOpenAck creates a new MsgConnectionOpenAck instance +func NewMsgConnectionOpenAck( + connectionID string, proofTry, proofConsensus commitment.ProofI, + proofHeight, consensusHeight uint64, version string, + signer sdk.AccAddress, +) MsgConnectionOpenAck { + return MsgConnectionOpenAck{ + ConnectionID: connectionID, + ProofTry: proofTry, + ProofConsensus: proofConsensus, + ProofHeight: proofHeight, + ConsensusHeight: consensusHeight, + Version: version, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgConnectionOpenAck) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgConnectionOpenAck) Type() string { + return "connection_open_ack" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgConnectionOpenAck) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + } + if strings.TrimSpace(msg.Version) == "" { + return ErrInvalidVersion(DefaultCodespace, "version can't be blank") + } + if msg.ProofTry == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof try cannot be nil") + } + if msg.ProofConsensus == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof consensus cannot be nil") + } + if msg.ProofHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + } + if msg.ConsensusHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0") + } + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("missing signer address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgConnectionOpenAck) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgConnectionOpenAck) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgConnectionOpenConfirm{} + +// MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to acknowledge +// the change of connection state to OPEN on Chain A. +type MsgConnectionOpenConfirm struct { + ConnectionID string `json:"connection_id"` + ProofAck commitment.ProofI `json:"proof_ack"` // proof for the change of the connection state on Chain A: `INIT -> OPEN` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgConnectionOpenConfirm creates a new MsgConnectionOpenConfirm instance +func NewMsgConnectionOpenConfirm( + connectionID string, proofAck commitment.ProofI, proofHeight uint64, signer sdk.AccAddress, +) MsgConnectionOpenConfirm { + return MsgConnectionOpenConfirm{ + ConnectionID: connectionID, + ProofAck: proofAck, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgConnectionOpenConfirm) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgConnectionOpenConfirm) Type() string { + return "connection_open_confirm" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgConnectionOpenConfirm) ValidateBasic() sdk.Error { + if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + } + if msg.ProofAck == nil { + return ErrInvalidConnectionProof(DefaultCodespace, "proof ack cannot be nil") + } + if msg.ProofHeight == 0 { + return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + } + + if msg.Signer.Empty() { + return sdk.ErrInvalidAddress("missing signer address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgConnectionOpenConfirm) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgConnectionOpenConfirm) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/03-connection/types/querier.go b/x/ibc/03-connection/types/querier.go new file mode 100644 index 000000000000..6fbb151342f4 --- /dev/null +++ b/x/ibc/03-connection/types/querier.go @@ -0,0 +1,83 @@ +package types + +import ( + "strings" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/tendermint/tendermint/crypto/merkle" +) + +// query routes supported by the IBC connection Querier +const ( + QueryConnection = "connection" + QueryClientConnections = "client_connections" +) + +// ConnectionResponse defines the client query response for a connection which +// also includes a proof and the height from which the proof was retrieved. +type ConnectionResponse struct { + Connection ConnectionEnd `json:"connection" yaml:"connection"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewConnectionResponse creates a new ConnectionResponse instance +func NewConnectionResponse( + connectionID string, connection ConnectionEnd, proof *merkle.Proof, height int64, +) ConnectionResponse { + return ConnectionResponse{ + Connection: connection, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ConnectionPath(connectionID), "/")), + ProofHeight: uint64(height), + } +} + +// QueryConnectionParams defines the params for the following queries: +// - 'custom/ibc/connections/' +type QueryConnectionParams struct { + ConnectionID string +} + +// NewQueryConnectionParams creates a new QueryConnectionParams instance +func NewQueryConnectionParams(clientID string) QueryConnectionParams { + return QueryConnectionParams{ + ConnectionID: clientID, + } +} + +// ClientConnectionsResponse defines the client query response for a client +// connection paths which also includes a proof and the height from which the +// proof was retrieved. +type ClientConnectionsResponse struct { + ConnectionPaths []string `json:"connection_paths" yaml:"connection_paths"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewClientConnectionsResponse creates a new ConnectionPaths instance +func NewClientConnectionsResponse( + clientID string, connectionPaths []string, proof *merkle.Proof, height int64, +) ClientConnectionsResponse { + return ClientConnectionsResponse{ + ConnectionPaths: connectionPaths, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ClientConnectionsPath(clientID), "/")), + ProofHeight: uint64(height), + } +} + +// QueryClientConnectionsParams defines the params for the following queries: +// - 'custom/ibc/client//connections' +type QueryClientConnectionsParams struct { + ClientID string +} + +// NewQueryClientConnectionsParams creates a new QueryClientConnectionsParams instance +func NewQueryClientConnectionsParams(clientID string) QueryClientConnectionsParams { + return QueryClientConnectionsParams{ + ClientID: clientID, + } +} diff --git a/x/ibc/03-connection/types/version.go b/x/ibc/03-connection/types/version.go new file mode 100644 index 000000000000..bf74a52dae92 --- /dev/null +++ b/x/ibc/03-connection/types/version.go @@ -0,0 +1,96 @@ +package types + +// GetCompatibleVersions returns an ordered set of compatible IBC versions for the +// caller chain's connection end. +func GetCompatibleVersions() []string { + return []string{"1.0.0"} +} + +// LatestVersion gets the latest version of a connection protocol +// +// CONTRACT: version array MUST be already sorted. +func LatestVersion(versions []string) string { + if len(versions) == 0 { + return "" + } + return versions[len(versions)-1] +} + +// PickVersion picks the counterparty latest version that is matches the list +// of compatible versions for the connection. +func PickVersion(counterpartyVersions, compatibleVersions []string) string { + + n := len(counterpartyVersions) + m := len(compatibleVersions) + + // aux hash maps to lookup already seen versions + counterpartyVerLookup := make(map[string]bool) + compatibleVerLookup := make(map[string]bool) + + // versions suported + var supportedVersions []string + + switch { + case n == 0 || m == 0: + return "" + case n == m: + for i := n - 1; i >= 0; i-- { + counterpartyVerLookup[counterpartyVersions[i]] = true + compatibleVerLookup[compatibleVersions[i]] = true + + // check if we've seen any of the versions + if _, ok := compatibleVerLookup[counterpartyVersions[i]]; ok { + supportedVersions = append(supportedVersions, counterpartyVersions[i]) + } + + if _, ok := counterpartyVerLookup[compatibleVersions[i]]; ok { + // TODO: check if the version is already in the array + supportedVersions = append(supportedVersions, compatibleVersions[i]) + } + } + case n > m: + for i := n - 1; i >= m; i-- { + counterpartyVerLookup[compatibleVersions[i]] = true + } + + for i := m - 1; i >= 0; i-- { + counterpartyVerLookup[counterpartyVersions[i]] = true + compatibleVerLookup[compatibleVersions[i]] = true + + // check if we've seen any of the versions + if _, ok := compatibleVerLookup[counterpartyVersions[i]]; ok { + supportedVersions = append(supportedVersions, counterpartyVersions[i]) + } + + if _, ok := counterpartyVerLookup[compatibleVersions[i]]; ok { + supportedVersions = append(supportedVersions, compatibleVersions[i]) + } + } + + case n < m: + for i := m - 1; i >= n; i-- { + compatibleVerLookup[compatibleVersions[i]] = true + } + + for i := n - 1; i >= 0; i-- { + counterpartyVerLookup[counterpartyVersions[i]] = true + compatibleVerLookup[compatibleVersions[i]] = true + + // check if we've seen any of the versions + if _, ok := compatibleVerLookup[counterpartyVersions[i]]; ok { + supportedVersions = append(supportedVersions, counterpartyVersions[i]) + } + + if _, ok := counterpartyVerLookup[compatibleVersions[i]]; ok { + supportedVersions = append(supportedVersions, compatibleVersions[i]) + } + } + } + + if len(supportedVersions) == 0 { + return "" + } + + // TODO: compare latest version before appending + return supportedVersions[len(supportedVersions)-1] +} diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index 5657d2aad3c7..04289628f640 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -21,6 +22,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ibcTxCmd.AddCommand(client.PostCommands( ibcclient.GetTxCmd(cdc, storeKey), + connection.GetTxCmd(cdc, storeKey), )...) return ibcTxCmd } @@ -38,6 +40,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { ibcQueryCmd.AddCommand(client.GetCommands( ibcclient.GetQueryCmd(cdc, queryRoute), + connection.GetQueryCmd(cdc, queryRoute), )...) return ibcQueryCmd } diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 5dc802b6f063..ed740f39183e 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" ) // NewHandler defines the IBC handler @@ -22,8 +23,20 @@ func NewHandler(k Keeper) sdk.Handler { case client.MsgSubmitMisbehaviour: return client.HandleMsgSubmitMisbehaviour(ctx, k.ClientKeeper, msg) + case connection.MsgConnectionOpenInit: + return connection.HandleMsgConnectionOpenInit(ctx, k.ConnectionKeeper, msg) + + case connection.MsgConnectionOpenTry: + return connection.HandleMsgConnectionOpenTry(ctx, k.ConnectionKeeper, msg) + + case connection.MsgConnectionOpenAck: + return connection.HandleMsgConnectionOpenAck(ctx, k.ConnectionKeeper, msg) + + case connection.MsgConnectionOpenConfirm: + return connection.HandleMsgConnectionOpenConfirm(ctx, k.ConnectionKeeper, msg) + default: - errMsg := fmt.Sprintf("unrecognized IBC Client message type: %T", msg) + errMsg := fmt.Sprintf("unrecognized IBC message type: %T", msg) return sdk.ErrUnknownRequest(errMsg).Result() } } diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index fce91fb353bd..dafe8892d167 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -4,16 +4,22 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" ) // Keeper defines each ICS keeper for IBC type Keeper struct { - ClientKeeper client.Keeper + ClientKeeper client.Keeper + ConnectionKeeper connection.Keeper } // NewKeeper creates a new ibc Keeper func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { + clientKeeper := client.NewKeeper(cdc, key, codespace) + connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) + return Keeper{ - ClientKeeper: client.NewKeeper(cdc, key, codespace), + ClientKeeper: clientKeeper, + ConnectionKeeper: connectionKeeper, } } diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index 7cbd4ec9c499..43db6f574dc0 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -1,24 +1,43 @@ package keeper import ( + "fmt" + abci "github.com/tendermint/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" ) // NewQuerier creates a querier for the IBC module func NewQuerier(k Keeper) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { switch path[0] { - case client.QueryClientState: - return client.QuerierClientState(ctx, req, k.ClientKeeper) - case client.QueryConsensusState: - return client.QuerierConsensusState(ctx, req, k.ClientKeeper) - case client.QueryVerifiedRoot: - return client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) + case client.SubModuleName: + switch path[1] { + case client.QueryClientState: + return client.QuerierClientState(ctx, req, k.ClientKeeper) + case client.QueryConsensusState: + return client.QuerierConsensusState(ctx, req, k.ClientKeeper) + case client.QueryVerifiedRoot: + return client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) + default: + return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName)) + } + + case connection.SubModuleName: + switch path[1] { + case connection.QueryConnection: + return connection.QuerierConnection(ctx, req, k.ConnectionKeeper) + case connection.QueryClientConnections: + return connection.QuerierClientConnections(ctx, req, k.ConnectionKeeper) + default: + return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName)) + } + default: - return nil, sdk.ErrUnknownRequest("unknown IBC client query endpoint") + return nil, sdk.ErrUnknownRequest("unknown IBC query endpoint") } } } diff --git a/x/ibc/module.go b/x/ibc/module.go index 675b18aa1ddf..21ba001210de 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -13,6 +13,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -37,6 +38,7 @@ func (AppModuleBasic) Name() string { // RegisterCodec registers the staking module's types for the given codec. func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) + connection.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } From a654fca26b36b8e85fad79514ef477382d3f5ba3 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 5 Nov 2019 18:04:49 +0100 Subject: [PATCH 035/176] ICS 05 implementation (#5193) * fix lint * fix lint * add handler/msgs/client * rm relay * finalize rebase on 23 root/path sep * fix lint, fix syntax * fix querying * extract out context withstore * fix 02-client test * fix 23-commitment test * add query in progress * rm freebase, reformat query * add cli/handler/msg in progress * add cli/msg/handler * add CLIQuery, fix tests * fix golangci * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * add godoc in progress * reformat test * rm XXX * add godoc * modify store * add query * update query.go * update query.go * cli refactor in progress * cli refactor in progress * add Query to boolean.go * fix key * fix cli / merkle test * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * fix test * fix client * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * fix dependency * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * rm commented lines * address review in progress * address review, rm cleanup/closing * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * start batch-verify tests * minor changes on commitment types * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * use testsuite * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * upstream changes --- store/types/store.go | 4 ++ types/store.go | 1 + x/ibc/05-port/alias.go | 39 +++++++++++++++++ x/ibc/05-port/keeper/keeper.go | 77 ++++++++++++++++++++++++++++++++++ x/ibc/05-port/types/errors.go | 37 ++++++++++++++++ x/ibc/05-port/types/keys.go | 31 ++++++++++++++ x/ibc/keeper/keeper.go | 4 ++ 7 files changed, 193 insertions(+) create mode 100644 x/ibc/05-port/alias.go create mode 100644 x/ibc/05-port/keeper/keeper.go create mode 100644 x/ibc/05-port/types/errors.go create mode 100644 x/ibc/05-port/types/keys.go diff --git a/store/types/store.go b/store/types/store.go index 5b5e64742552..bd8a3d58c85a 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -277,6 +277,10 @@ type StoreKey interface { String() string } +// CapabilityKey represent the Cosmos SDK keys for object-capability +// generation in the IBC protocol as defined in https://github.com/cosmos/ics/tree/master/spec/ics-005-port-allocation#data-structures +type CapabilityKey StoreKey + // KVStoreKey is used for accessing substores. // Only the pointer value should ever be used - it functions as a capabilities key. type KVStoreKey struct { diff --git a/types/store.go b/types/store.go index 1c50444c0efd..0a972bf7403c 100644 --- a/types/store.go +++ b/types/store.go @@ -81,6 +81,7 @@ const ( // nolint - reexport type ( StoreKey = types.StoreKey + CapabilityKey = types.CapabilityKey KVStoreKey = types.KVStoreKey TransientStoreKey = types.TransientStoreKey ) diff --git a/x/ibc/05-port/alias.go b/x/ibc/05-port/alias.go new file mode 100644 index 000000000000..a74c7fe61537 --- /dev/null +++ b/x/ibc/05-port/alias.go @@ -0,0 +1,39 @@ +package port + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/05-port/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/05-port/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" +) + +const ( + DefaultCodespace = types.DefaultCodespace + CodePortExists = types.CodePortExists + CodePortNotFound = types.CodePortNotFound + CodePortNotAuthenticated = types.CodePortNotAuthenticated + CodeInvalidPortID = types.CodeInvalidPortID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + ErrPortExists = types.ErrPortExists + ErrPortNotFound = types.ErrPortNotFound + ErrPortNotAuthenticated = types.ErrPortNotAuthenticated + ErrInvalidPortID = types.ErrInvalidPortID + PortPath = types.PortPath + KeyPort = types.KeyPort +) + +type ( + Keeper = keeper.Keeper +) diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go new file mode 100644 index 000000000000..5a7a9fb05bae --- /dev/null +++ b/x/ibc/05-port/keeper/keeper.go @@ -0,0 +1,77 @@ +package keeper + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +// Keeper defines the IBC connection keeper +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store + ports map[sdk.CapabilityKey]string + bound []string +} + +// NewKeeper creates a new IBC connection Keeper instance +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/port", + prefix: []byte{}, + // prefix: []byte(types.SubModuleName + "/"), // "port/" + ports: make(map[sdk.CapabilityKey]string), // map of capabilities to port ids + } +} + +// GetPorts returns the list of bound ports. +// (these ports still must have been bound statically) +func (k Keeper) GetPorts() []string { + return k.bound +} + +// GetPort retrieves a given port ID from keeper map +func (k Keeper) GetPort(ck sdk.CapabilityKey) (string, bool) { + portID, found := k.ports[ck] + return portID, found +} + +// BindPort binds to a port and returns the associated capability. +// Ports must be bound statically when the chain starts in `app.go`. +// The capability must then be passed to a module which will need to pass +// it as an extra parameter when calling functions on the IBC module. +func (k Keeper) BindPort(portID string) sdk.CapabilityKey { + if err := host.DefaultPortIdentifierValidator(portID); err != nil { + panic(err.Error()) + } + + for _, b := range k.bound { + if b == portID { + panic(fmt.Sprintf("port %s is already bound", portID)) + } + } + + key := sdk.NewKVStoreKey(portID) + k.ports[key] = portID + k.bound = append(k.bound, portID) + return key +} + +// Authenticate authenticates a capability key against a port ID +// by checking if the memory address of the capability was previously +// generated and bound to the port (provided as a parameter) which the capability +// is being authenticated against. +func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { + if err := host.DefaultPortIdentifierValidator(portID); err != nil { + panic(err.Error()) + } + + return k.ports[key] == portID +} diff --git a/x/ibc/05-port/types/errors.go b/x/ibc/05-port/types/errors.go new file mode 100644 index 000000000000..20031c826107 --- /dev/null +++ b/x/ibc/05-port/types/errors.go @@ -0,0 +1,37 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// port error codes +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName + + CodePortExists sdk.CodeType = 101 + CodePortNotFound sdk.CodeType = 102 + CodePortNotAuthenticated sdk.CodeType = 103 + CodeInvalidPortID sdk.CodeType = 104 +) + +// ErrPortExists implements sdk.Error +func ErrPortExists(codespace sdk.CodespaceType, portID string) sdk.Error { + return sdk.NewError(codespace, CodePortExists, fmt.Sprintf("port with ID %s is already binded", portID)) +} + +// ErrPortNotFound implements sdk.Error +func ErrPortNotFound(codespace sdk.CodespaceType, portID string) sdk.Error { + return sdk.NewError(codespace, CodePortNotFound, fmt.Sprintf("port with ID %s not found", portID)) +} + +// ErrPortNotAuthenticated implements sdk.Error +func ErrPortNotAuthenticated(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodePortNotAuthenticated, "port failed authentication") +} + +// ErrInvalidPortID implements sdk.Error +func ErrInvalidPortID(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidPortID, "invalid port ID") +} diff --git a/x/ibc/05-port/types/keys.go b/x/ibc/05-port/types/keys.go new file mode 100644 index 000000000000..b1250e0e4463 --- /dev/null +++ b/x/ibc/05-port/types/keys.go @@ -0,0 +1,31 @@ +package types + +import ( + "fmt" +) + +const ( + // SubModuleName defines the IBC port name + SubModuleName = "port" + + // StoreKey is the store key string for IBC ports + StoreKey = SubModuleName + + // RouterKey is the message route for IBC ports + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC ports + QuerierRoute = SubModuleName +) + +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-005-port-allocation#store-paths + +// PortPath defines the path under which ports paths are stored +func PortPath(portID string) string { + return fmt.Sprintf("ports/%s", portID) +} + +// KeyPort returns the store key for a particular port +func KeyPort(portID string) []byte { + return []byte(PortPath(portID)) +} diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index dafe8892d167..c9708a6e79a1 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -5,21 +5,25 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" ) // Keeper defines each ICS keeper for IBC type Keeper struct { ClientKeeper client.Keeper ConnectionKeeper connection.Keeper + PortKeeper port.Keeper } // NewKeeper creates a new ibc Keeper func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { clientKeeper := client.NewKeeper(cdc, key, codespace) connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) + portKeeper := port.NewKeeper(cdc, key, codespace) return Keeper{ ClientKeeper: clientKeeper, ConnectionKeeper: connectionKeeper, + PortKeeper: portKeeper, } } From 017be7f3dc724885528f1c26962bda98f8fb2308 Mon Sep 17 00:00:00 2001 From: Joon Date: Tue, 5 Nov 2019 09:08:55 -0800 Subject: [PATCH 036/176] ICS 04 Implementation (#4548) * merge from ics04 branch * merge from ics04 branch * fix lint * add port * fix test * add mocks * fix connid -> portid in handshake.go * add mock * add ibc module.go, finalize mock * add keeper * add StoreKey const * fix test * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix cli errors * fix dependency * fix dependency * reflect method name change * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * reflect downstream changes * fix from address in tx cli * fix cli in progress(squash later) * fix cli * remove timeout, add channel cli * fix golangci * fix cli * Clean up * fix mock cli in progress * finalize cleanup, mock cli wip * add cli for mocksend * fix handler * rm commented lines * address review in progress * address review, rm cleanup/closing * rename mock packages * fix interface for gaia * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * update test * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * refactor: remove store accessors, update keeper and types to match spec (WIP) * update handshake and packet * implement packet timeouts * implement send and receive packet * implement packet ACK * update handler * add channel errors * channel querier * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update ICS04 with downstream changes * Implement tx cli actions * add MsgSendPacket handler; msg validation, errors and events * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * rm legacy tests; add query proofs support * remove capability key generation and authentication logic * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * downstream changes; custom marshal JSON; msg validation, and update errors * update errors and aliases * start batch-verify tests * update msg validation and CLI UX * minor changes on commitment types * fix channel and packet check (#5243) * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * authenticate port ID; remove send packet msg from CLI * comment out handlers * use testsuite * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * upstream changes * upstream changes --- x/ibc/04-channel/alias.go | 123 +++++ x/ibc/04-channel/client/cli/query.go | 55 +++ x/ibc/04-channel/client/cli/tx.go | 535 +++++++++++++++++++++ x/ibc/04-channel/client/utils/utils.go | 70 +++ x/ibc/04-channel/exported/exported.go | 16 + x/ibc/04-channel/handler.go | 153 ++++++ x/ibc/04-channel/keeper/handshake.go | 410 ++++++++++++++++ x/ibc/04-channel/keeper/keeper.go | 146 ++++++ x/ibc/04-channel/keeper/packet.go | 357 ++++++++++++++ x/ibc/04-channel/keeper/querier.go | 32 ++ x/ibc/04-channel/keeper/timeout.go | 195 ++++++++ x/ibc/04-channel/module.go | 25 + x/ibc/04-channel/types/channel.go | 225 +++++++++ x/ibc/04-channel/types/codec.go | 28 ++ x/ibc/04-channel/types/errors.go | 73 +++ x/ibc/04-channel/types/events.go | 27 ++ x/ibc/04-channel/types/expected_keepers.go | 31 ++ x/ibc/04-channel/types/keys.go | 85 ++++ x/ibc/04-channel/types/msgs.go | 379 +++++++++++++++ x/ibc/04-channel/types/packet.go | 108 +++++ x/ibc/04-channel/types/querier.go | 71 +++ x/ibc/handler.go | 22 + x/ibc/keeper/keeper.go | 4 + x/ibc/keeper/querier.go | 9 + x/ibc/module.go | 2 + 25 files changed, 3181 insertions(+) create mode 100644 x/ibc/04-channel/alias.go create mode 100644 x/ibc/04-channel/client/cli/query.go create mode 100644 x/ibc/04-channel/client/cli/tx.go create mode 100644 x/ibc/04-channel/client/utils/utils.go create mode 100644 x/ibc/04-channel/exported/exported.go create mode 100644 x/ibc/04-channel/handler.go create mode 100644 x/ibc/04-channel/keeper/handshake.go create mode 100644 x/ibc/04-channel/keeper/keeper.go create mode 100644 x/ibc/04-channel/keeper/packet.go create mode 100644 x/ibc/04-channel/keeper/querier.go create mode 100644 x/ibc/04-channel/keeper/timeout.go create mode 100644 x/ibc/04-channel/module.go create mode 100644 x/ibc/04-channel/types/channel.go create mode 100644 x/ibc/04-channel/types/codec.go create mode 100644 x/ibc/04-channel/types/errors.go create mode 100644 x/ibc/04-channel/types/events.go create mode 100644 x/ibc/04-channel/types/expected_keepers.go create mode 100644 x/ibc/04-channel/types/keys.go create mode 100644 x/ibc/04-channel/types/msgs.go create mode 100644 x/ibc/04-channel/types/packet.go create mode 100644 x/ibc/04-channel/types/querier.go diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go new file mode 100644 index 000000000000..25f73b478565 --- /dev/null +++ b/x/ibc/04-channel/alias.go @@ -0,0 +1,123 @@ +package channel + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +const ( + NONE = types.NONE + UNORDERED = types.UNORDERED + ORDERED = types.ORDERED + OrderNone = types.OrderNone + OrderUnordered = types.OrderUnordered + OrderOrdered = types.OrderOrdered + CLOSED = types.CLOSED + INIT = types.INIT + OPENTRY = types.OPENTRY + OPEN = types.OPEN + StateClosed = types.StateClosed + StateInit = types.StateInit + StateOpenTry = types.StateOpenTry + StateOpen = types.StateOpen + DefaultCodespace = types.DefaultCodespace + CodeChannelExists = types.CodeChannelExists + CodeChannelNotFound = types.CodeChannelNotFound + CodeInvalidCounterpartyChannel = types.CodeInvalidCounterpartyChannel + CodeChannelCapabilityNotFound = types.CodeChannelCapabilityNotFound + CodeInvalidPacket = types.CodeInvalidPacket + CodeSequenceNotFound = types.CodeSequenceNotFound + CodePacketTimeout = types.CodePacketTimeout + CodeInvalidChannel = types.CodeInvalidChannel + CodeInvalidChannelState = types.CodeInvalidChannelState + CodeInvalidChannelProof = types.CodeInvalidChannelProof + AttributeKeySenderPort = types.AttributeKeySenderPort + AttributeKeyReceiverPort = types.AttributeKeyReceiverPort + AttributeKeyChannelID = types.AttributeKeyChannelID + AttributeKeySequence = types.AttributeKeySequence + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryChannel = types.QueryChannel +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + QuerierChannel = keeper.QuerierChannel + NewChannel = types.NewChannel + NewCounterparty = types.NewCounterparty + OrderFromString = types.OrderFromString + StateFromString = types.StateFromString + RegisterCodec = types.RegisterCodec + ErrChannelExists = types.ErrChannelExists + ErrChannelNotFound = types.ErrChannelNotFound + ErrInvalidCounterpartyChannel = types.ErrInvalidCounterpartyChannel + ErrChannelCapabilityNotFound = types.ErrChannelCapabilityNotFound + ErrInvalidPacket = types.ErrInvalidPacket + ErrSequenceNotFound = types.ErrSequenceNotFound + ErrPacketTimeout = types.ErrPacketTimeout + ErrInvalidChannel = types.ErrInvalidChannel + ErrInvalidChannelState = types.ErrInvalidChannelState + ErrInvalidChannelProof = types.ErrInvalidChannelProof + ChannelPath = types.ChannelPath + ChannelCapabilityPath = types.ChannelCapabilityPath + NextSequenceSendPath = types.NextSequenceSendPath + NextSequenceRecvPath = types.NextSequenceRecvPath + PacketCommitmentPath = types.PacketCommitmentPath + PacketAcknowledgementPath = types.PacketAcknowledgementPath + KeyChannel = types.KeyChannel + KeyChannelCapabilityPath = types.KeyChannelCapabilityPath + KeyNextSequenceSend = types.KeyNextSequenceSend + KeyNextSequenceRecv = types.KeyNextSequenceRecv + KeyPacketCommitment = types.KeyPacketCommitment + KeyPacketAcknowledgement = types.KeyPacketAcknowledgement + NewMsgChannelOpenInit = types.NewMsgChannelOpenInit + NewMsgChannelOpenTry = types.NewMsgChannelOpenTry + NewMsgChannelOpenAck = types.NewMsgChannelOpenAck + NewMsgChannelOpenConfirm = types.NewMsgChannelOpenConfirm + NewMsgChannelCloseInit = types.NewMsgChannelCloseInit + NewMsgChannelCloseConfirm = types.NewMsgChannelCloseConfirm + NewPacket = types.NewPacket + NewOpaquePacket = types.NewOpaquePacket + NewChannelResponse = types.NewChannelResponse + NewQueryChannelParams = types.NewQueryChannelParams + + // variable aliases + SubModuleCdc = types.SubModuleCdc + EventTypeChannelOpenInit = types.EventTypeChannelOpenInit + EventTypeChannelOpenTry = types.EventTypeChannelOpenTry + EventTypeChannelOpenAck = types.EventTypeChannelOpenAck + EventTypeChannelOpenConfirm = types.EventTypeChannelOpenConfirm + EventTypeChannelCloseInit = types.EventTypeChannelCloseInit + EventTypeChannelCloseConfirm = types.EventTypeChannelCloseConfirm + AttributeValueCategory = types.AttributeValueCategory +) + +type ( + Keeper = keeper.Keeper + Channel = types.Channel + Counterparty = types.Counterparty + Order = types.Order + State = types.State + ClientKeeper = types.ClientKeeper + ConnectionKeeper = types.ConnectionKeeper + PortKeeper = types.PortKeeper + MsgChannelOpenInit = types.MsgChannelOpenInit + MsgChannelOpenTry = types.MsgChannelOpenTry + MsgChannelOpenAck = types.MsgChannelOpenAck + MsgChannelOpenConfirm = types.MsgChannelOpenConfirm + MsgChannelCloseInit = types.MsgChannelCloseInit + MsgChannelCloseConfirm = types.MsgChannelCloseConfirm + Packet = types.Packet + OpaquePacket = types.OpaquePacket + ChannelResponse = types.ChannelResponse + QueryChannelParams = types.QueryChannelParams +) diff --git a/x/ibc/04-channel/client/cli/query.go b/x/ibc/04-channel/client/cli/query.go new file mode 100644 index 000000000000..04bfcfcbbe92 --- /dev/null +++ b/x/ibc/04-channel/client/cli/query.go @@ -0,0 +1,55 @@ +package cli + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + + cli "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" +) + +// GetQueryCmd returns the query commands for IBC channels +func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics04ChannelQueryCmd := &cobra.Command{ + Use: "channel", + Short: "IBC channel query subcommands", + DisableFlagParsing: true, + } + + ics04ChannelQueryCmd.AddCommand(cli.GetCommands( + GetCmdQueryChannel(storeKey, cdc), + )...) + + return ics04ChannelQueryCmd +} + +// GetCmdQueryChannel defines the command to query a channel end +func GetCmdQueryChannel(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "end [port-id] [channel-id]", + Short: "Query a channel end", + Long: strings.TrimSpace(fmt.Sprintf(`Query an IBC channel end + +Example: +$ %s query ibc channel end [port-id] [channel-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + + ch, err := utils.QueryChannel(cliCtx, args[0], args[1], queryRoute) + if err != nil { + return err + } + + return cliCtx.PrintOutput(ch) + }, + } + return cmd +} diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go new file mode 100644 index 000000000000..833ed29af01c --- /dev/null +++ b/x/ibc/04-channel/client/cli/tx.go @@ -0,0 +1,535 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + "time" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + abci "github.com/tendermint/tendermint/abci/types" +) + +const ( + FlagOrdered = "ordered" + FlagIBCVersion = "ibc-version" + FlagNode1 = "node1" + FlagNode2 = "node2" + FlagFrom1 = "from1" + FlagFrom2 = "from2" + FlagChainID2 = "chain-id2" +) + +// GetTxCmd returns the transaction commands for IBC Connections +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics04ChannelTxCmd := &cobra.Command{ + Use: "channel", + Short: "IBC channel transaction subcommands", + } + + ics04ChannelTxCmd.AddCommand(client.PostCommands( + GetMsgChannelOpenInitCmd(storeKey, cdc), + GetMsgChannelOpenTryCmd(storeKey, cdc), + GetMsgChannelOpenAckCmd(storeKey, cdc), + GetMsgChannelOpenConfirmCmd(storeKey, cdc), + GetMsgChannelCloseInitCmd(storeKey, cdc), + GetMsgChannelCloseConfirmCmd(storeKey, cdc), + GetCmdHandshake(storeKey, cdc), + )...) + + return ics04ChannelTxCmd +} + +// TODO: module needs to pass the capability key (i.e store key) + +// GetMsgChannelOpenInitCmd returns the command to create a MsgChannelOpenInit transaction +func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-init [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops]", + Short: "Creates and sends a ChannelOpenInit message", + Args: cobra.ExactArgs(5), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + counterpartyPortID := args[2] + counterpartyChannelID := args[3] + hops := strings.Split(args[4], "/") + order := channelOrder() + version := viper.GetString(FlagIBCVersion) + + msg := types.NewMsgChannelOpenInit( + portID, channelID, version, order, hops, + counterpartyPortID, counterpartyChannelID, cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + + cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") + cmd.Flags().String(FlagIBCVersion, "1.0.0", "supported IBC version") + + return cmd +} + +// GetMsgChannelOpenTryCmd returns the command to create a MsgChannelOpenTry transaction +func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-try [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof-init.json] [proof-height]", + Short: "Creates and sends a ChannelOpenTry message", + Args: cobra.ExactArgs(7), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + counterpartyPortID := args[2] + counterpartyChannelID := args[3] + hops := strings.Split(args[4], "/") + order := channelOrder() + version := viper.GetString(FlagIBCVersion) // TODO: diferenciate between channel and counterparty versions + + var proof commitment.ProofI + if err := cdc.UnmarshalJSON([]byte(args[5]), &proof); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(args[5]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return fmt.Errorf("error unmarshalling proof file: %v", err) + } + } + + proofHeight, err := strconv.ParseInt(args[6], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgChannelOpenTry( + portID, channelID, version, order, hops, + counterpartyPortID, counterpartyChannelID, version, + proof, uint64(proofHeight), cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") + cmd.Flags().String(FlagIBCVersion, "1.0.0", "supported IBC version") + + return cmd +} + +// GetMsgChannelOpenAckCmd returns the command to create a MsgChannelOpenAck transaction +func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "open-ack [port-id] [channel-id] [/path/to/proof-try.json] [proof-height]", + Short: "Creates and sends a ChannelOpenAck message", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + version := viper.GetString(FlagIBCVersion) // TODO: diferenciate between channel and counterparty versions + + var proof commitment.ProofI + if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(args[2]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return fmt.Errorf("error unmarshalling proof file: %v", err) + } + } + + proofHeight, err := strconv.ParseInt(args[3], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgChannelOpenAck( + portID, channelID, version, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + cmd.Flags().String(FlagIBCVersion, "1.0.0", "supported IBC version") + return cmd +} + +// GetMsgChannelOpenConfirmCmd returns the command to create a MsgChannelOpenConfirm transaction +func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "open-confirm [port-id] [channel-id] [/path/to/proof-ack.json] [proof-height]", + Short: "Creates and sends a ChannelOpenConfirm message", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + + var proof commitment.ProofI + if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(args[2]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return fmt.Errorf("error unmarshalling proof file: %v", err) + } + } + + proofHeight, err := strconv.ParseInt(args[3], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgChannelOpenConfirm( + portID, channelID, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } +} + +// GetMsgChannelCloseInitCmd returns the command to create a MsgChannelCloseInit transaction +func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "close-init [port-id] [channel-id]", + Short: "Creates and sends a ChannelCloseInit message", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + + msg := types.NewMsgChannelCloseInit(portID, channelID, cliCtx.GetFromAddress()) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } +} + +// GetMsgChannelCloseConfirmCmd returns the command to create a MsgChannelCloseConfirm transaction +func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "close-confirm [port-id] [channel-id] [/path/to/proof-init.json] [proof-height]", + Short: "Creates and sends a ChannelCloseConfirm message", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc) + + portID := args[0] + channelID := args[1] + + var proof commitment.ProofI + if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { + fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + contents, err := ioutil.ReadFile(args[2]) + if err != nil { + return fmt.Errorf("error opening proof file: %v", err) + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return fmt.Errorf("error unmarshalling proof file: %v", err) + } + } + + proofHeight, err := strconv.ParseInt(args[3], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgChannelCloseConfirm( + portID, channelID, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } +} + +func GetCmdHandshake(storeKey string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "handshake", + Short: "initiate connection handshake between two chains", + Long: strings.TrimSpace( + fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: + +Example: +$ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-client-id] [cp-port-id] [cp-chain-id] [cp-conn-id] + `, version.ClientName)), + Args: cobra.ExactArgs(8), + // Args: []string{portid1, chanid1, connid1, portid2, chanid2, connid2} + RunE: func(cmd *cobra.Command, args []string) error { + // --chain-id values for each chain + cid1 := viper.GetString(flags.FlagChainID) + cid2 := viper.GetString(FlagChainID2) + + // --from values for each wallet + from1 := viper.GetString(FlagFrom1) + from2 := viper.GetString(FlagFrom2) + + // --node values for each RPC + node1 := viper.GetString(FlagNode1) + node2 := viper.GetString(FlagNode2) + + // client IDs + clientid1 := args[0] + clientid2 := args[4] + + // port IDs + portid1 := args[1] + portid2 := args[5] + + // channel IDs + chanid1 := args[2] + chanid2 := args[6] + + // connection IDs + connid1 := args[3] + connid2 := args[7] + + // Create txbldr, clictx, querier for cid1 + viper.Set(flags.FlagChainID, cid1) + txBldr1 := auth.NewTxBuilderFromCLI(). + WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx1 := context.NewCLIContextIBC(from1, cid1, node1). + WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + // Create txbldr, clictx, querier for cid2 + viper.Set(flags.FlagChainID, cid2) + txBldr2 := auth.NewTxBuilderFromCLI(). + WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx2 := context.NewCLIContextIBC(from2, cid2, node2). + WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + // // get passphrase for key from1 + // passphrase1, err := keys.GetPassphrase(from1) + // if err != nil { + // return err + // } + + // // get passphrase for key from2 + // passphrase2, err := keys.GetPassphrase(from2) + // if err != nil { + // return err + // } + + // TODO: check state and if not Idle continue existing process + viper.Set(flags.FlagChainID, cid1) + msgOpenInit := types.NewMsgChannelOpenInit(portid1, chanid1, "v1.0.0", channelOrder(), []string{connid1}, portid2, chanid2, ctx1.GetFromAddress()) + if err := msgOpenInit.ValidateBasic(); err != nil { + return err + } + + err := utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenInit}) + if err != nil { + return err + } + + // Another block has to be passed after msginit is committed + // to retrieve the correct proofs + time.Sleep(8 * time.Second) + + header, err := clientutils.GetTendermintHeader(ctx1) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid2) + msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), portid1, chanid1, storeKey) + if err != nil { + return err + } + + msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenTry}) + if err != nil { + return err + } + + // Another block has to be passed after msginit is committed + // to retrieve the correct proofs + time.Sleep(8 * time.Second) + + header, err = clientutils.GetTendermintHeader(ctx2) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid1, header, ctx1.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid2) + proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), portid2, chanid2, storeKey) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", proofs.Proof, uint64(header.Height), ctx1.GetFromAddress()) + if err := msgOpenAck.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenAck}) + if err != nil { + return err + } + + // Another block has to be passed after msginit is committed + // to retrieve the correct proofs + time.Sleep(8 * time.Second) + + header, err = clientutils.GetTendermintHeader(ctx1) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid2) + msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) + if err != nil { + return err + } + + viper.Set(flags.FlagChainID, cid1) + proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), portid1, chanid1, storeKey) + if err != nil { + return err + } + + msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + if err := msgOpenConfirm.ValidateBasic(); err != nil { + return err + } + + err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}) + if err != nil { + return err + } + + return nil + }, + } + + cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") + cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") + cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") + cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") + cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") + cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") + + cmd.MarkFlagRequired(FlagFrom1) + cmd.MarkFlagRequired(FlagFrom2) + + return cmd +} + +func queryProofs(ctx client.CLIContext, portID string, channelID string, queryRoute string) (types.ChannelResponse, error) { + var connRes types.ChannelResponse + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyChannel(portID, channelID), + Prove: true, + } + + res, err := ctx.QueryABCI(req) + if res.Value == nil || err != nil { + return connRes, err + } + + var channel types.Channel + if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { + return connRes, err + } + return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil +} + +func channelOrder() types.Order { + if viper.GetBool(FlagOrdered) { + return types.ORDERED + } + return types.UNORDERED +} diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go new file mode 100644 index 000000000000..580a2bf1fb83 --- /dev/null +++ b/x/ibc/04-channel/client/utils/utils.go @@ -0,0 +1,70 @@ +package utils + +import ( + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// QueryPacket returns a packet from the store +func QueryPacket( + ctx client.CLIContext, portID, channelID string, + sequence, timeout uint64, queryRoute string, +) (types.PacketResponse, error) { + var packetRes types.PacketResponse + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyPacketCommitment(portID, channelID, sequence), + Prove: true, + } + + res, err := ctx.QueryABCI(req) + if err != nil { + return packetRes, err + } + + channel, err := QueryChannel(ctx, portID, channelID, queryRoute) + if err != nil { + return packetRes, err + } + + destPortID := channel.Channel.Counterparty.PortID + destChannelID := channel.Channel.Counterparty.ChannelID + + packet := types.NewPacket( + sequence, + timeout, + portID, + channelID, + destPortID, + destChannelID, + res.Value, + ) + + // FIXME: res.Height+1 is hack, fix later + return types.NewPacketResponse(portID, channelID, sequence, packet, res.Proof, res.Height+1), nil +} + +// QueryChannel returns a channel from the store +func QueryChannel(ctx client.CLIContext, portID string, channelID string, queryRoute string) (types.ChannelResponse, error) { + var connRes types.ChannelResponse + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyChannel(portID, channelID), + Prove: true, + } + + res, err := ctx.QueryABCI(req) + if res.Value == nil || err != nil { + return connRes, err + } + + var channel types.Channel + if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { + return connRes, err + } + return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil +} diff --git a/x/ibc/04-channel/exported/exported.go b/x/ibc/04-channel/exported/exported.go new file mode 100644 index 000000000000..8fb84f7c1c01 --- /dev/null +++ b/x/ibc/04-channel/exported/exported.go @@ -0,0 +1,16 @@ +package exported + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type PacketI interface { + GetSequence() uint64 + GetTimeoutHeight() uint64 + GetSourcePort() string + GetSourceChannel() string + GetDestPort() string + GetDestChannel() string + GetData() []byte + ValidateBasic() sdk.Error +} diff --git a/x/ibc/04-channel/handler.go b/x/ibc/04-channel/handler.go new file mode 100644 index 000000000000..31c97b668e1a --- /dev/null +++ b/x/ibc/04-channel/handler.go @@ -0,0 +1,153 @@ +package channel + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit +func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenInit) sdk.Result { + err := k.ChanOpenInit( + ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, + msg.Channel.Counterparty, msg.Channel.Version, + ) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelOpenInit, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry +func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenTry) sdk.Result { + err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, + msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, + ) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelOpenTry, + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), // TODO: double check sender and receiver + sdk.NewAttribute(types.AttributeKeyReceiverPort, msg.Channel.Counterparty.PortID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck +func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenAck) sdk.Result { + err := k.ChanOpenAck( + ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight, + ) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelOpenAck, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelOpenConfirm defines the sdk.Handler for MsgChannelOpenConfirm +func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenConfirm) sdk.Result { + err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofAck, msg.ProofHeight) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelOpenConfirm, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelCloseInit defines the sdk.Handler for MsgChannelCloseInit +func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseInit) sdk.Result { + err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelCloseInit, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgChannelCloseConfirm defines the sdk.Handler for MsgChannelCloseConfirm +func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseConfirm) sdk.Result { + err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofInit, msg.ProofHeight) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelCloseConfirm, + sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + }) + + return sdk.Result{Events: ctx.EventManager().Events()} +} diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go new file mode 100644 index 000000000000..f71115da4792 --- /dev/null +++ b/x/ibc/04-channel/keeper/handshake.go @@ -0,0 +1,410 @@ +package keeper + +import ( + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// CounterpartyHops returns the connection hops of the counterparty channel. +// The counterparty hops are stored in the inverse order as the channel's. +func (k Keeper) CounterpartyHops(ctx sdk.Context, ch types.Channel) ([]string, bool) { + counterPartyHops := make([]string, len(ch.ConnectionHops)) + for i, hop := range ch.ConnectionHops { + connection, found := k.connectionKeeper.GetConnection(ctx, hop) + if !found { + return []string{}, false + } + counterPartyHops[len(counterPartyHops)-1-i] = connection.Counterparty.ConnectionID + } + return counterPartyHops, true +} + +// ChanOpenInit is called by a module to initiate a channel opening handshake with +// a module on another chain. +func (k Keeper) ChanOpenInit( + ctx sdk.Context, + order types.Order, + connectionHops []string, + portID, + channelID string, + counterparty types.Counterparty, + version string, +) error { + // TODO: abortTransactionUnless(validateChannelIdentifier(portIdentifier, channelIdentifier)) + _, found := k.GetChannel(ctx, portID, channelID) + if found { + return types.ErrChannelExists(k.codespace, channelID) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) + } + + if connectionEnd.State == connection.NONE { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state cannot be NONE"), + ) + } + + /* + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + */ + channel := types.NewChannel(types.INIT, order, counterparty, connectionHops, version) + k.SetChannel(ctx, portID, channelID, channel) + + // TODO: generate channel capability key and set it to store + k.SetNextSequenceSend(ctx, portID, channelID, 1) + k.SetNextSequenceRecv(ctx, portID, channelID, 1) + + return nil +} + +// ChanOpenTry is called by a module to accept the first step of a channel opening +// handshake initiated by a module on another chain. +func (k Keeper) ChanOpenTry( + ctx sdk.Context, + order types.Order, + connectionHops []string, + portID, + channelID string, + counterparty types.Counterparty, + version, + counterpartyVersion string, + proofInit commitment.ProofI, + proofHeight uint64, +) error { + _, found := k.GetChannel(ctx, portID, channelID) + if found { + return types.ErrChannelExists(k.codespace, channelID) + } + + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + // NOTE: this step has been switched with the one below to reverse the connection + // hops + channel := types.NewChannel(types.OPENTRY, order, counterparty, connectionHops, version) + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + // expectedCounterpaty is the counterparty of the counterparty's channel end + // (i.e self) + expectedCounterparty := types.NewCounterparty(portID, channelID) + expectedChannel := types.NewChannel( + types.INIT, channel.Ordering, expectedCounterparty, + counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofInit, + types.ChannelPath(counterparty.PortID, counterparty.ChannelID), + bz, + ) { + return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + k.SetChannel(ctx, portID, channelID, channel) + + // TODO: generate channel capability key and set it to store + k.SetNextSequenceSend(ctx, portID, channelID, 1) + k.SetNextSequenceRecv(ctx, portID, channelID, 1) + + return nil +} + +// ChanOpenAck is called by the handshake-originating module to acknowledge the +// acceptance of the initial request by the counterparty module on the other chain. +func (k Keeper) ChanOpenAck( + ctx sdk.Context, + portID, + channelID, + counterpartyVersion string, + proofTry commitment.ProofI, + proofHeight uint64, +) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.ErrChannelNotFound(k.codespace, portID, channelID) + } + + if channel.State != types.INIT { + return types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not INIT (got %s)", channel.State.String()), + ) + } + + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + // counterparty of the counterparty channel end (i.e self) + counterparty := types.NewCounterparty(portID, channelID) + expectedChannel := types.NewChannel( + types.OPENTRY, channel.Ordering, counterparty, + counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofTry, + types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), + bz, + ) { + return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + channel.State = types.OPEN + channel.Version = counterpartyVersion + k.SetChannel(ctx, portID, channelID, channel) + + return nil +} + +// ChanOpenConfirm is called by the counterparty module to close their end of the +// channel, since the other end has been closed. +func (k Keeper) ChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, + proofAck commitment.ProofI, + proofHeight uint64, +) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.ErrChannelNotFound(k.codespace, portID, channelID) + } + + if channel.State != types.OPENTRY { + return types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPENTRY (got %s)", channel.State.String()), + ) + } + + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + counterparty := types.NewCounterparty(portID, channelID) + expectedChannel := types.NewChannel( + types.OPEN, channel.Ordering, counterparty, + counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofAck, + types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), + bz, + ) { + return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + channel.State = types.OPEN + k.SetChannel(ctx, portID, channelID, channel) + + return nil +} + +// Closing Handshake +// +// This section defines the set of functions required to close a channel handshake +// as defined in https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#closing-handshake + +// ChanCloseInit is called by either module to close their end of the channel. Once +// closed, channels cannot be reopened. +func (k Keeper) ChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.ErrChannelNotFound(k.codespace, portID, channelID) + } + + if channel.State == types.CLOSED { + return types.ErrInvalidChannelState(k.codespace, "channel is already CLOSED") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + channel.State = types.CLOSED + k.SetChannel(ctx, portID, channelID, channel) + + return nil +} + +// ChanCloseConfirm is called by the counterparty module to close their end of the +// channel, since the other end has been closed. +func (k Keeper) ChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, + proofInit commitment.ProofI, + proofHeight uint64, +) error { + // TODO: Maybe not right + key := sdk.NewKVStoreKey(portID) + + if !k.portKeeper.Authenticate(key, portID) { + return errors.New("port is not valid") + } + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.ErrChannelNotFound(k.codespace, portID, channelID) + } + + if channel.State == types.CLOSED { + return types.ErrInvalidChannelState(k.codespace, "channel is already CLOSED") + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + counterparty := types.NewCounterparty(portID, channelID) + expectedChannel := types.NewChannel( + types.CLOSED, channel.Ordering, counterparty, + counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofInit, + types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), + bz, + ) { + return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + channel.State = types.CLOSED + k.SetChannel(ctx, portID, channelID, channel) + + return nil +} diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go new file mode 100644 index 000000000000..6169c72ffc3a --- /dev/null +++ b/x/ibc/04-channel/keeper/keeper.go @@ -0,0 +1,146 @@ +package keeper + +import ( + "encoding/binary" + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// Keeper defines the IBC channel keeper +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store + + clientKeeper types.ClientKeeper + connectionKeeper types.ConnectionKeeper + portKeeper types.PortKeeper +} + +// NewKeeper creates a new IBC channel Keeper instance +func NewKeeper( + cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + clientKeeper types.ClientKeeper, connectionKeeper types.ConnectionKeeper, + portKeeper types.PortKeeper, +) Keeper { + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/channel", + prefix: []byte{}, + // prefix: []byte(types.SubModuleName + "/"), // "channel/" + clientKeeper: clientKeeper, + connectionKeeper: connectionKeeper, + portKeeper: portKeeper, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName)) +} + +// GetChannel returns a channel with a particular identifier binded to a specific port +func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyChannel(portID, channelID)) + if bz == nil { + return types.Channel{}, false + } + + var channel types.Channel + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &channel) + return channel, true +} + +// SetChannel sets a channel to the store +func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel types.Channel) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(channel) + store.Set(types.KeyChannel(portID, channelID), bz) +} + +// GetChannelCapability gets a channel's capability key from the store +func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) (string, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyChannelCapabilityPath(portID, channelID)) + if bz == nil { + return "", false + } + + return string(bz), true +} + +// SetChannelCapability sets a channel's capability key to the store +func (k Keeper) SetChannelCapability(ctx sdk.Context, portID, channelID string, key string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Set(types.KeyChannelCapabilityPath(portID, channelID), []byte(key)) +} + +// GetNextSequenceSend gets a channel's next send sequence from the store +func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyNextSequenceSend(portID, channelID)) + if bz == nil { + return 0, false + } + + return binary.BigEndian.Uint64(bz), true +} + +// SetNextSequenceSend sets a channel's next send sequence to the store +func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set(types.KeyNextSequenceSend(portID, channelID), bz) +} + +// GetNextSequenceRecv gets a channel's next receive sequence from the store +func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyNextSequenceRecv(portID, channelID)) + if bz == nil { + return 0, false + } + + return binary.BigEndian.Uint64(bz), true +} + +// SetNextSequenceRecv sets a channel's next receive sequence to the store +func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set(types.KeyNextSequenceRecv(portID, channelID), bz) +} + +// GetPacketCommitment gets the packet commitment hash from the store +func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyPacketCommitment(portID, channelID, sequence)) + return bz +} + +// SetPacketCommitment sets the packet commitment hash to the store +func (k Keeper) SetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64, commitmentHash []byte) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Set(types.KeyPacketCommitment(portID, channelID, sequence), commitmentHash) +} + +func (k Keeper) deletePacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Delete(types.KeyPacketCommitment(portID, channelID, sequence)) +} + +// SetPacketAcknowledgement sets the packet ack hash to the store +func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64, ackHash []byte) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) +} diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go new file mode 100644 index 000000000000..0590f3cfd37c --- /dev/null +++ b/x/ibc/04-channel/keeper/packet.go @@ -0,0 +1,357 @@ +package keeper + +import ( + "bytes" + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// CleanupPacket is called by a module to remove a received packet commitment +// from storage. The receiving end must have already processed the packet +// (whether regularly or past timeout). +// +// In the ORDERED channel case, CleanupPacket cleans-up a packet on an ordered +// channel by proving that the packet has been received on the other end. +// +// In the UNORDERED channel case, CleanupPacket cleans-up a packet on an +// unordered channel by proving that the associated acknowledgement has been +//written. +func (k Keeper) CleanupPacket( + ctx sdk.Context, + packet exported.PacketI, + proof commitment.ProofI, + proofHeight, + nextSequenceRecv uint64, + acknowledgement []byte, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + if channel.State != types.OPEN { + return nil, types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + ) + } + + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelCapabilityNotFound(k.codespace) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return nil, errors.New("port is not valid") + } + + if packet.GetDestChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + ) + } + + if nextSequenceRecv >= packet.GetSequence() { + return nil, types.ErrInvalidPacket(k.codespace, "packet already received") + } + + commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + } + + var ok bool + switch channel.Ordering { + case types.ORDERED: + ok = k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.NextSequenceRecvPath(packet.GetDestPort(), packet.GetDestChannel()), + sdk.Uint64ToBigEndian(nextSequenceRecv), + ) + case types.UNORDERED: + ok = k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.PacketAcknowledgementPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), + acknowledgement, + ) + default: + panic(fmt.Sprintf("invalid channel ordering type %v", channel.Ordering)) + } + + if !ok { + return nil, types.ErrInvalidPacket(k.codespace, "packet verification failed") + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + return packet, nil +} + +// SendPacket is called by a module in order to send an IBC packet on a channel +// end owned by the calling module to the corresponding module on the counterparty +// chain. +func (k Keeper) SendPacket( + ctx sdk.Context, + packet exported.PacketI, + portCapability sdk.CapabilityKey, +) error { + if err := packet.ValidateBasic(); err != nil { + return err + } + + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + if channel.State == types.CLOSED { + return types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel is CLOSED (got %s)", channel.State.String()), + ) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return errors.New("port is not valid") + } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + ) + } + + if packet.GetDestChannel() != channel.Counterparty.ChannelID { + return types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State == connection.NONE { + return connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection is closed (i.e NONE)"), + ) + } + + consensusState, found := k.clientKeeper.GetConsensusState(ctx, connectionEnd.ClientID) + if !found { + return client.ErrConsensusStateNotFound(k.codespace) + } + + if consensusState.GetHeight() >= packet.GetTimeoutHeight() { + return types.ErrPacketTimeout(k.codespace) + } + + nextSequenceSend, found := k.GetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return types.ErrSequenceNotFound(k.codespace, "send") + } + + if packet.GetSequence() != nextSequenceSend { + return types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet sequence ≠ next send sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceSend), + ) + } + + nextSequenceSend++ + k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend) + k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), packet.GetData()) // TODO: hash packet data + + return nil +} + +// RecvPacket is called by a module in order to receive & process an IBC packet +// sent on the corresponding channel end on the counterparty chain. +func (k Keeper) RecvPacket( + ctx sdk.Context, + packet exported.PacketI, + proof commitment.ProofI, + proofHeight uint64, + acknowledgement []byte, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + + channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetDestPort(), packet.GetDestChannel()) + } + + if channel.State != types.OPEN { + return nil, types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + ) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetDestPort()) { + return nil, errors.New("port is not valid") + } + + // packet must come from the channel's counterparty + if packet.GetSourcePort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID), + ) + } + + if packet.GetSourceChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return nil, connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { + return nil, types.ErrPacketTimeout(k.codespace) + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.PacketCommitmentPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), + packet.GetData(), // TODO: hash data + ) { + return nil, errors.New("couldn't verify counterparty packet commitment") + } + + if len(acknowledgement) > 0 || channel.Ordering == types.UNORDERED { + k.SetPacketAcknowledgement( + ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), + acknowledgement, // TODO: hash ACK + ) + } + + if channel.Ordering == types.ORDERED { + nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) + if !found { + return nil, types.ErrSequenceNotFound(k.codespace, "receive") + } + + if packet.GetSequence() != nextSequenceRecv { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv), + ) + } + + nextSequenceRecv++ + + k.SetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv) + } + + return packet, nil +} + +// AcknowledgePacket is called by a module to process the acknowledgement of a +// packet previously sent by the calling module on a channel to a counterparty +// module on the counterparty chain. acknowledgePacket also cleans up the packet +// commitment, which is no longer necessary since the packet has been received +// and acted upon. +func (k Keeper) AcknowledgePacket( + ctx sdk.Context, + packet exported.PacketI, + acknowledgement []byte, + proof commitment.ProofI, + proofHeight uint64, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + if channel.State != types.OPEN { + return nil, types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + ) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return nil, errors.New("invalid capability key") + } + + // packet must come from the channel's counterparty + if packet.GetSourcePort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID), + ) + } + + if packet.GetSourceChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if connectionEnd.State != connection.OPEN { + return nil, connection.ErrInvalidConnectionState( + k.codespace, + fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + ) + } + + commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.PacketAcknowledgementPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), + acknowledgement, // TODO: hash ACK + ) { + return nil, errors.New("invalid acknowledgement on counterparty chain") + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + return packet, nil +} diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go new file mode 100644 index 000000000000..3618c5f29fd4 --- /dev/null +++ b/x/ibc/04-channel/keeper/querier.go @@ -0,0 +1,32 @@ +package keeper + +import ( + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// QuerierChannel defines the sdk.Querier to query a module's channel +func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryChannelParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID) + } + + bz, err := types.SubModuleCdc.MarshalJSON(channel) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go new file mode 100644 index 000000000000..3ae481373de3 --- /dev/null +++ b/x/ibc/04-channel/keeper/timeout.go @@ -0,0 +1,195 @@ +package keeper + +import ( + "bytes" + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// TimeoutPacket is called by a module which originally attempted to send a +// packet to a counterparty module, where the timeout height has passed on the +// counterparty chain without the packet being committed, to prove that the +// packet can no longer be executed and to allow the calling module to safely +// perform appropriate state transitions. +func (k Keeper) TimeoutPacket( + ctx sdk.Context, + packet exported.PacketI, + proof commitment.ProofI, + proofHeight uint64, + nextSequenceRecv uint64, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + if channel.State != types.OPEN { + return nil, types.ErrInvalidChannelState( + k.codespace, + fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + ) + } + + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelCapabilityNotFound(k.codespace) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return nil, errors.New("port is not valid") + } + + if packet.GetDestChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + ) + } + + if proofHeight < packet.GetTimeoutHeight() { + return nil, types.ErrPacketTimeout(k.codespace) + } + + if nextSequenceRecv >= packet.GetSequence() { + return nil, types.ErrInvalidPacket(k.codespace, "packet already received") + } + + commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + } + + var ok bool + switch channel.Ordering { + case types.ORDERED: + ok = k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proof, + types.NextSequenceRecvPath(packet.GetDestPort(), packet.GetDestChannel()), + sdk.Uint64ToBigEndian(nextSequenceRecv), + ) + case types.UNORDERED: + ok = k.connectionKeeper.VerifyNonMembership( + ctx, connectionEnd, proofHeight, proof, + types.PacketAcknowledgementPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), + ) + default: + panic(fmt.Sprintf("invalid channel ordering type %v", channel.Ordering)) + } + + if !ok { + return nil, types.ErrInvalidPacket(k.codespace, "packet verification failed") + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + if channel.Ordering == types.ORDERED { + channel.State = types.CLOSED + k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + } + + return packet, nil +} + +// TimeoutOnClose is called by a module in order to prove that the channel to +// which an unreceived packet was addressed has been closed, so the packet will +// never be received (even if the timeoutHeight has not yet been reached). +func (k Keeper) TimeoutOnClose( + ctx sdk.Context, + packet exported.PacketI, + proofNonMembership, + proofClosed commitment.ProofI, + proofHeight uint64, + portCapability sdk.CapabilityKey, +) (exported.PacketI, error) { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, types.ErrChannelCapabilityNotFound(k.codespace) + } + + if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { + return nil, errors.New("port is not valid") + } + + if packet.GetDestChannel() != channel.Counterparty.ChannelID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return nil, types.ErrInvalidPacket( + k.codespace, + fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + ) + } + + commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + } + + counterpartyHops, found := k.CounterpartyHops(ctx, channel) + if !found { + // Should not reach here, connectionEnd was able to be retrieved above + panic("cannot find connection") + } + + counterparty := types.NewCounterparty(packet.GetSourcePort(), packet.GetSourceChannel()) + expectedChannel := types.NewChannel( + types.CLOSED, channel.Ordering, counterparty, counterpartyHops, channel.Version, + ) + + bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) + if err != nil { + return nil, errors.New("failed to marshal expected channel") + } + + if !k.connectionKeeper.VerifyMembership( + ctx, connectionEnd, proofHeight, proofClosed, + types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), + bz, + ) { + return nil, types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + } + + if !k.connectionKeeper.VerifyNonMembership( + ctx, connectionEnd, proofHeight, proofNonMembership, + types.PacketAcknowledgementPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), + ) { + return nil, errors.New("cannot verify absence of acknowledgement at packet index") + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + return packet, nil +} diff --git a/x/ibc/04-channel/module.go b/x/ibc/04-channel/module.go new file mode 100644 index 000000000000..4f9b17b03144 --- /dev/null +++ b/x/ibc/04-channel/module.go @@ -0,0 +1,25 @@ +package channel + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/cli" +) + +// Name returns the IBC connection ICS name +func Name() string { + return SubModuleName +} + +// GetTxCmd returns the root tx command for the IBC connections. +func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + return cli.GetTxCmd(fmt.Sprintf("%s/%s", storeKey, SubModuleName), cdc) +} + +// GetQueryCmd returns no root query command for the IBC connections. +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + return cli.GetQueryCmd(fmt.Sprintf("%s/%s", queryRoute, SubModuleName), cdc) +} diff --git a/x/ibc/04-channel/types/channel.go b/x/ibc/04-channel/types/channel.go new file mode 100644 index 000000000000..98bbb9b44f1e --- /dev/null +++ b/x/ibc/04-channel/types/channel.go @@ -0,0 +1,225 @@ +package types + +import ( + "encoding/json" + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/errors" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +type Channel struct { + State State `json:"state" yaml:"state"` + Ordering Order `json:"ordering" yaml:"ordering"` + Counterparty Counterparty `json:"counterparty" yaml:"counterparty"` + ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` + Version string `json:"version" yaml:"version "` +} + +// NewChannel creates a new Channel instance +func NewChannel( + state State, ordering Order, counterparty Counterparty, + hops []string, version string, +) Channel { + return Channel{ + State: state, + Ordering: ordering, + Counterparty: counterparty, + ConnectionHops: hops, + Version: version, + } +} + +// ValidateBasic performs a basic validation of the channel fields +func (ch Channel) ValidateBasic() sdk.Error { + if ch.State.String() == "" { + return ErrInvalidChannelState( + DefaultCodespace, + "channel order should be either 'ORDERED' or 'UNORDERED'", + ) + } + if ch.Ordering.String() == "" { + return ErrInvalidChannel( + DefaultCodespace, + "channel order should be either 'ORDERED' or 'UNORDERED'", + ) + } + if len(ch.ConnectionHops) != 1 { + return ErrInvalidChannel(DefaultCodespace, "IBC v1 only supports one connection hop") + } + if err := host.DefaultConnectionIdentifierValidator(ch.ConnectionHops[0]); err != nil { + return ErrInvalidChannel(DefaultCodespace, errors.Wrap(err, "invalid connection hop ID").Error()) + } + if strings.TrimSpace(ch.Version) == "" { + return ErrInvalidChannel(DefaultCodespace, "channel version can't be blank") + } + return ch.Counterparty.ValidateBasic() +} + +// Counterparty defines the counterparty chain's channel and port identifiers +type Counterparty struct { + PortID string `json:"port_id" yaml:"port_id"` + ChannelID string `json:"channel_id" yaml:"channel_id"` +} + +// NewCounterparty returns a new Counterparty instance +func NewCounterparty(portID, channelID string) Counterparty { + return Counterparty{ + PortID: portID, + ChannelID: channelID, + } +} + +// ValidateBasic performs a basic validation check of the identifiers +func (c Counterparty) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(c.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty connection ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(c.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty client ID: %s", err.Error())) + } + return nil +} + +// Order defines if a channel is ORDERED or UNORDERED +type Order byte + +// string representation of the channel ordering +const ( + NONE Order = iota // zero-value for channel ordering + UNORDERED // packets can be delivered in any order, which may differ from the order in which they were sent. + ORDERED // packets are delivered exactly in the order which they were sent +) + +// channel order types +const ( + OrderNone string = "NONE" + OrderUnordered string = "UNORDERED" + OrderOrdered string = "ORDERED" +) + +// String implements the Stringer interface +func (o Order) String() string { + switch o { + case NONE: + return OrderNone + case UNORDERED: + return OrderUnordered + case ORDERED: + return OrderOrdered + default: + return "" + } +} + +// MarshalJSON marshal to JSON using string. +func (o Order) MarshalJSON() ([]byte, error) { + return json.Marshal(o.String()) +} + +// UnmarshalJSON decodes from JSON. +func (o *Order) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + bz2, err := OrderFromString(s) + if err != nil { + return err + } + + *o = bz2 + return nil +} + +// OrderFromString parses a string into a channel order byte +func OrderFromString(order string) (Order, error) { + switch order { + case OrderNone: + return NONE, nil + case OrderUnordered: + return UNORDERED, nil + case OrderOrdered: + return ORDERED, nil + default: + return 0, fmt.Errorf("'%s' is not a valid channel ordering", order) + } +} + +// State defines if a channel is in one of the following states: +// CLOSED, INIT, OPENTRY or OPEN +type State byte + +// channel state types +const ( + CLOSED State = iota + 1 // A channel end has been closed and can no longer be used to send or receive packets. + INIT // A channel end has just started the opening handshake. + OPENTRY // A channel end has acknowledged the handshake step on the counterparty chain. + OPEN // A channel end has completed the handshake and is ready to send and receive packets. +) + +// string representation of the channel states +const ( + StateClosed string = "CLOSED" + StateInit string = "INIT" + StateOpenTry string = "OPENTRY" + StateOpen string = "OPEN" +) + +// String implements the Stringer interface +func (s State) String() string { + switch s { + case CLOSED: + return StateClosed + case INIT: + return StateInit + case OPENTRY: + return StateOpenTry + case OPEN: + return StateOpen + default: + return "" + } +} + +// MarshalJSON marshal to JSON using string. +func (s State) MarshalJSON() ([]byte, error) { + return json.Marshal(s.String()) +} + +// UnmarshalJSON decodes from JSON. +func (s *State) UnmarshalJSON(data []byte) error { + var stateStr string + err := json.Unmarshal(data, &stateStr) + if err != nil { + return err + } + + bz2, err := StateFromString(stateStr) + if err != nil { + return err + } + + *s = bz2 + return nil +} + +// StateFromString parses a string into a channel state byte +func StateFromString(state string) (State, error) { + switch state { + case StateClosed: + return CLOSED, nil + case StateInit: + return INIT, nil + case StateOpenTry: + return OPENTRY, nil + case StateOpen: + return OPEN, nil + default: + return CLOSED, fmt.Errorf("'%s' is not a valid channel state", state) + } +} diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go new file mode 100644 index 000000000000..0839edede775 --- /dev/null +++ b/x/ibc/04-channel/types/codec.go @@ -0,0 +1,28 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" +) + +// SubModuleCdc defines the IBC channel codec. +var SubModuleCdc = codec.New() + +// RegisterCodec registers all the necessary types and interfaces for the +// IBC channel. +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*exported.PacketI)(nil), nil) + cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil) + cdc.RegisterConcrete(OpaquePacket{}, "ibc/channel/OpaquePacket", nil) + + cdc.RegisterConcrete(MsgChannelOpenInit{}, "ibc/channel/MsgChannelOpenInit", nil) + cdc.RegisterConcrete(MsgChannelOpenTry{}, "ibc/channel/MsgChannelOpenTry", nil) + cdc.RegisterConcrete(MsgChannelOpenAck{}, "ibc/channel/MsgChannelOpenAck", nil) + cdc.RegisterConcrete(MsgChannelOpenConfirm{}, "ibc/channel/MsgChannelOpenConfirm", nil) + cdc.RegisterConcrete(MsgChannelCloseInit{}, "ibc/channel/MsgChannelCloseInit", nil) + cdc.RegisterConcrete(MsgChannelCloseConfirm{}, "ibc/channel/MsgChannelCloseConfirm", nil) +} + +func init() { + RegisterCodec(SubModuleCdc) +} diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go new file mode 100644 index 000000000000..37d3925b513e --- /dev/null +++ b/x/ibc/04-channel/types/errors.go @@ -0,0 +1,73 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// channel error codes +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName + + CodeChannelExists sdk.CodeType = 101 + CodeChannelNotFound sdk.CodeType = 102 + CodeInvalidCounterpartyChannel sdk.CodeType = 103 + CodeChannelCapabilityNotFound sdk.CodeType = 104 + CodeInvalidPacket sdk.CodeType = 105 + CodeSequenceNotFound sdk.CodeType = 106 + CodePacketTimeout sdk.CodeType = 107 + CodeInvalidChannel sdk.CodeType = 108 + CodeInvalidChannelState sdk.CodeType = 109 + CodeInvalidChannelProof sdk.CodeType = 110 +) + +// ErrChannelExists implements sdk.Error +func ErrChannelExists(codespace sdk.CodespaceType, channelID string) sdk.Error { + return sdk.NewError(codespace, CodeChannelExists, fmt.Sprintf("channel with ID %s already exists", channelID)) +} + +// ErrChannelNotFound implements sdk.Error +func ErrChannelNotFound(codespace sdk.CodespaceType, portID, channelID string) sdk.Error { + return sdk.NewError(codespace, CodeChannelNotFound, fmt.Sprintf("channel with ID %s on port %s not found", channelID, portID)) +} + +// ErrInvalidCounterpartyChannel implements sdk.Error +func ErrInvalidCounterpartyChannel(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidCounterpartyChannel, msg) +} + +// ErrChannelCapabilityNotFound implements sdk.Error +func ErrChannelCapabilityNotFound(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeChannelCapabilityNotFound, "channel capability key not found") +} + +// ErrInvalidPacket implements sdk.Error +func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidPacket, msg) +} + +// ErrSequenceNotFound implements sdk.Error +func ErrSequenceNotFound(codespace sdk.CodespaceType, seqType string) sdk.Error { + return sdk.NewError(codespace, CodeSequenceNotFound, fmt.Sprintf("next %s sequence counter not found", seqType)) +} + +// ErrPacketTimeout implements sdk.Error +func ErrPacketTimeout(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodePacketTimeout, "packet timeout") +} + +// ErrInvalidChannel implements sdk.Error +func ErrInvalidChannel(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidChannel, msg) +} + +// ErrInvalidChannelState implements sdk.Error +func ErrInvalidChannelState(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidChannelState, msg) +} + +// ErrInvalidChannelProof implements sdk.Error +func ErrInvalidChannelProof(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidChannelProof, msg) +} diff --git a/x/ibc/04-channel/types/events.go b/x/ibc/04-channel/types/events.go new file mode 100644 index 000000000000..b82b3e8700cf --- /dev/null +++ b/x/ibc/04-channel/types/events.go @@ -0,0 +1,27 @@ +package types + +import ( + "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// IBC channel events +const ( + AttributeKeySenderPort = "sender_port" + AttributeKeyReceiverPort = "receiver_port" + AttributeKeyChannelID = "channel_id" + AttributeKeySequence = "sequence" +) + +// IBC channel events vars +var ( + EventTypeChannelOpenInit = MsgChannelOpenInit{}.Type() + EventTypeChannelOpenTry = MsgChannelOpenTry{}.Type() + EventTypeChannelOpenAck = MsgChannelOpenAck{}.Type() + EventTypeChannelOpenConfirm = MsgChannelOpenConfirm{}.Type() + EventTypeChannelCloseInit = MsgChannelCloseInit{}.Type() + EventTypeChannelCloseConfirm = MsgChannelCloseConfirm{}.Type() + + AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) +) diff --git a/x/ibc/04-channel/types/expected_keepers.go b/x/ibc/04-channel/types/expected_keepers.go new file mode 100644 index 000000000000..ab88a2284f27 --- /dev/null +++ b/x/ibc/04-channel/types/expected_keepers.go @@ -0,0 +1,31 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// ClientKeeper expected account IBC client keeper +type ClientKeeper interface { + GetConsensusState(ctx sdk.Context, clientID string) (clientexported.ConsensusState, bool) +} + +// ConnectionKeeper expected account IBC connection keeper +type ConnectionKeeper interface { + GetConnection(ctx sdk.Context, connectionID string) (connection.ConnectionEnd, bool) + VerifyMembership( + ctx sdk.Context, connection connection.ConnectionEnd, height uint64, + proof commitment.ProofI, path string, value []byte, + ) bool + VerifyNonMembership( + ctx sdk.Context, connection connection.ConnectionEnd, height uint64, + proof commitment.ProofI, path string, + ) bool +} + +// PortKeeper expected account IBC port keeper +type PortKeeper interface { + Authenticate(key sdk.CapabilityKey, portID string) bool +} diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go new file mode 100644 index 000000000000..f308640b2e32 --- /dev/null +++ b/x/ibc/04-channel/types/keys.go @@ -0,0 +1,85 @@ +package types + +import ( + "fmt" +) + +const ( + // SubModuleName defines the IBC channels name + SubModuleName = "channels" + + // StoreKey is the store key string for IBC channels + StoreKey = SubModuleName + + // RouterKey is the message route for IBC channels + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC channels + QuerierRoute = SubModuleName +) + +// ChannelPath defines the path under which channels are stored +func ChannelPath(portID, channelID string) string { + return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) +} + +// ChannelCapabilityPath defines the path under which capability keys associated +// with a channel are stored +func ChannelCapabilityPath(portID, channelID string) string { + return fmt.Sprintf("%s/key", ChannelPath(portID, channelID)) +} + +// NextSequenceSendPath defines the next send sequence counter store path +func NextSequenceSendPath(portID, channelID string) string { + return fmt.Sprintf("%s/nextSequenceSend", ChannelPath(portID, channelID)) +} + +// NextSequenceRecvPath defines the next receive sequence counter store path +func NextSequenceRecvPath(portID, channelID string) string { + return fmt.Sprintf("%s/nextSequenceRecv", ChannelPath(portID, channelID)) +} + +// PacketCommitmentPath defines the commitments to packet data fields store path +func PacketCommitmentPath(portID, channelID string, sequence uint64) string { + return fmt.Sprintf("%s/packets/%d", ChannelPath(portID, channelID), sequence) +} + +// PacketAcknowledgementPath defines the packet acknowledgement store path +func PacketAcknowledgementPath(portID, channelID string, sequence uint64) string { + return fmt.Sprintf("%s/acknowledgements/%d", ChannelPath(portID, channelID), sequence) +} + +// KeyChannel returns the store key for a particular channel +func KeyChannel(portID, channelID string) []byte { + return []byte(ChannelPath(portID, channelID)) +} + +// KeyChannelCapabilityPath returns the store key for the capability key of a +// particular channel binded to a specific port +func KeyChannelCapabilityPath(portID, channelID string) []byte { + return []byte(ChannelCapabilityPath(portID, channelID)) +} + +// KeyNextSequenceSend returns the store key for the send sequence of a particular +// channel binded to a specific port +func KeyNextSequenceSend(portID, channelID string) []byte { + return []byte(NextSequenceSendPath(portID, channelID)) +} + +// KeyNextSequenceRecv returns the store key for the receive sequence of a particular +// channel binded to a specific port +func KeyNextSequenceRecv(portID, channelID string) []byte { + return []byte(NextSequenceRecvPath(portID, channelID)) +} + +// KeyPacketCommitment returns the store key of under which a packet commitment +// is stored +func KeyPacketCommitment(portID, channelID string, sequence uint64) []byte { + return []byte(PacketCommitmentPath(portID, channelID, sequence)) +} + +// KeyPacketAcknowledgement returns the store key of under which a packet +// acknowledgement is stored +func KeyPacketAcknowledgement(portID, channelID string, sequence uint64) []byte { + return []byte(PacketAcknowledgementPath(portID, channelID, sequence)) +} diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go new file mode 100644 index 000000000000..a6d7d856e34f --- /dev/null +++ b/x/ibc/04-channel/types/msgs.go @@ -0,0 +1,379 @@ +package types + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +var _ sdk.Msg = MsgChannelOpenInit{} + +type MsgChannelOpenInit struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + Channel Channel `json:"channel"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelOpenInit creates a new MsgChannelCloseInit MsgChannelOpenInit +func NewMsgChannelOpenInit( + portID, channelID string, version string, channelOrder Order, connectionHops []string, + counterpartyPortID, counterpartyChannelID string, signer sdk.AccAddress, +) MsgChannelOpenInit { + counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) + channel := NewChannel(INIT, channelOrder, counterparty, connectionHops, version) + return MsgChannelOpenInit{ + PortID: portID, + ChannelID: channelID, + Channel: channel, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelOpenInit) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelOpenInit) Type() string { + return "channel_open_init" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelOpenInit) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + // Signer can be empty + return msg.Channel.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelOpenInit) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelOpenInit) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelOpenTry{} + +type MsgChannelOpenTry struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + Channel Channel `json:"channel"` + CounterpartyVersion string `json:"counterparty_version"` + ProofInit commitment.ProofI `json:"proof_init"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelOpenTry creates a new MsgChannelOpenTry instance +func NewMsgChannelOpenTry( + portID, channelID, version string, channelOrder Order, connectionHops []string, + counterpartyPortID, counterpartyChannelID, counterpartyVersion string, + proofInit commitment.ProofI, proofHeight uint64, signer sdk.AccAddress, +) MsgChannelOpenTry { + counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) + channel := NewChannel(INIT, channelOrder, counterparty, connectionHops, version) + return MsgChannelOpenTry{ + PortID: portID, + ChannelID: channelID, + Channel: channel, + CounterpartyVersion: counterpartyVersion, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelOpenTry) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelOpenTry) Type() string { + return "channel_open_try" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelOpenTry) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if strings.TrimSpace(msg.CounterpartyVersion) == "" { + return ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank") + } + if msg.ProofInit == nil { + return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + } + if msg.ProofHeight == 0 { + return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + } + // Signer can be empty + return msg.Channel.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelOpenTry) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelOpenTry) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelOpenAck{} + +type MsgChannelOpenAck struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + CounterpartyVersion string `json:"counterparty_version"` + ProofTry commitment.ProofI `json:"proof_try"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelOpenAck creates a new MsgChannelOpenAck instance +func NewMsgChannelOpenAck( + portID, channelID string, cpv string, proofTry commitment.ProofI, proofHeight uint64, + signer sdk.AccAddress, +) MsgChannelOpenAck { + return MsgChannelOpenAck{ + PortID: portID, + ChannelID: channelID, + CounterpartyVersion: cpv, + ProofTry: proofTry, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelOpenAck) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelOpenAck) Type() string { + return "channel_open_ack" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelOpenAck) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if strings.TrimSpace(msg.CounterpartyVersion) == "" { + return ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank") + } + if msg.ProofTry == nil { + return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + } + if msg.ProofHeight == 0 { + return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + } + // Signer can be empty + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelOpenAck) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelOpenAck) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelOpenConfirm{} + +type MsgChannelOpenConfirm struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + ProofAck commitment.ProofI `json:"proof_ack"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelOpenConfirm creates a new MsgChannelOpenConfirm instance +func NewMsgChannelOpenConfirm( + portID, channelID string, proofAck commitment.ProofI, proofHeight uint64, + signer sdk.AccAddress, +) MsgChannelOpenConfirm { + return MsgChannelOpenConfirm{ + PortID: portID, + ChannelID: channelID, + ProofAck: proofAck, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelOpenConfirm) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelOpenConfirm) Type() string { + return "channel_open_confirm" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelOpenConfirm) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if msg.ProofAck == nil { + return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + } + if msg.ProofHeight == 0 { + return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + } + // Signer can be empty + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelOpenConfirm) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelOpenConfirm) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelCloseInit{} + +type MsgChannelCloseInit struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelCloseInit creates a new MsgChannelCloseInit instance +func NewMsgChannelCloseInit(portID string, channelID string, signer sdk.AccAddress) MsgChannelCloseInit { + return MsgChannelCloseInit{ + PortID: portID, + ChannelID: channelID, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelCloseInit) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelCloseInit) Type() string { + return "channel_close_init" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelCloseInit) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + // Signer can be empty + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelCloseInit) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelCloseInit) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgChannelCloseConfirm{} + +type MsgChannelCloseConfirm struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + ProofInit commitment.ProofI `json:"proof_init"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` +} + +// NewMsgChannelCloseConfirm creates a new MsgChannelCloseConfirm instance +func NewMsgChannelCloseConfirm( + portID, channelID string, proofInit commitment.ProofI, proofHeight uint64, + signer sdk.AccAddress, +) MsgChannelCloseConfirm { + return MsgChannelCloseConfirm{ + PortID: portID, + ChannelID: channelID, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgChannelCloseConfirm) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (msg MsgChannelCloseConfirm) Type() string { + return "channel_close_confirm" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelCloseConfirm) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if msg.ProofInit == nil { + return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + } + if msg.ProofHeight == 0 { + return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + } + // Signer can be empty + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgChannelCloseConfirm) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgChannelCloseConfirm) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go new file mode 100644 index 000000000000..8d170cc62a9d --- /dev/null +++ b/x/ibc/04-channel/types/packet.go @@ -0,0 +1,108 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" +) + +var _ exported.PacketI = Packet{} + +// Packet defines a type that carries data across different chains through IBC +type Packet struct { + Sequence uint64 `json:"sequence"` // number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. + Timeout uint64 `json:"timeout"` // indicates a consensus height on the destination chain after which the Packet will no longer be processed, and will instead count as having timed-out. + SourcePort string `json:"source_port"` // identifies the port on the sending chain. + SourceChannel string `json:"source_channel"` // identifies the channel end on the sending chain. + DestinationPort string `json:"destination_port"` // identifies the port on the receiving chain. + DestinationChannel string `json:"destination_channel"` // identifies the channel end on the receiving chain. + Data []byte `json:"data"` // opaque value which can be defined by the application logic of the associated modules. +} + +// NewPacket creates a new Packet instance +func NewPacket( + sequence, timeout uint64, sourcePort, sourceChannel, + destinationPort, destinationChannel string, data []byte, +) Packet { + return Packet{ + sequence, + timeout, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + data, + } +} + +// Sequence implements PacketI interface +func (p Packet) GetSequence() uint64 { return p.Sequence } + +// TimeoutHeight implements PacketI interface +func (p Packet) GetTimeoutHeight() uint64 { return p.Timeout } + +// SourcePort implements PacketI interface +func (p Packet) GetSourcePort() string { return p.SourcePort } + +// SourceChannel implements PacketI interface +func (p Packet) GetSourceChannel() string { return p.SourceChannel } + +// DestPort implements PacketI interface +func (p Packet) GetDestPort() string { return p.DestinationPort } + +// DestChannel implements PacketI interface +func (p Packet) GetDestChannel() string { return p.DestinationChannel } + +// Data implements PacketI interface +func (p Packet) GetData() []byte { return p.Data } + +// ValidateBasic implements PacketI interface +func (p Packet) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(p.SourcePort); err != nil { + return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source port ID: %s", err.Error())) + } + if err := host.DefaultPortIdentifierValidator(p.DestinationPort); err != nil { + return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid destination port ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(p.SourceChannel); err != nil { + return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source channel ID: %s", err.Error())) + } + if err := host.DefaultChannelIdentifierValidator(p.DestinationChannel); err != nil { + return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid destination channel ID: %s", err.Error())) + } + if p.Sequence == 0 { + return ErrInvalidPacket(DefaultCodespace, "packet sequence cannot be 0") + } + if p.Timeout == 0 { + return ErrPacketTimeout(DefaultCodespace) + } + if len(p.Data) == 0 { + return ErrInvalidPacket(DefaultCodespace, "packet data cannot be empty") + } + return nil +} + +var _ exported.PacketI = OpaquePacket{} + +// OpaquePacket is a Packet, but cloaked in an obscuring data type by the host +// state machine, such that a module cannot act upon it other than to pass it to +// the IBC handler +type OpaquePacket struct { + *Packet +} + +// NewOpaquePacket creates a new OpaquePacket instance +func NewOpaquePacket(sequence, timeout uint64, sourcePort, sourceChannel, + destinationPort, destinationChannel string, data []byte, +) OpaquePacket { + Packet := NewPacket( + sequence, timeout, sourcePort, sourceChannel, destinationPort, + destinationChannel, data, + ) + return OpaquePacket{&Packet} +} + +// Data implements PacketI interface +func (op OpaquePacket) GetData() []byte { return nil } diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go new file mode 100644 index 000000000000..707e9076ca39 --- /dev/null +++ b/x/ibc/04-channel/types/querier.go @@ -0,0 +1,71 @@ +package types + +import ( + "strings" + + "github.com/tendermint/tendermint/crypto/merkle" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// query routes supported by the IBC channel Querier +const ( + QueryChannel = "channel" +) + +// ChannelResponse defines the client query response for a channel which also +// includes a proof,its path and the height from which the proof was retrieved. +type ChannelResponse struct { + Channel Channel `json:"channel" yaml:"channel"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewChannelResponse creates a new ChannelResponse instance +func NewChannelResponse( + portID, channelID string, channel Channel, proof *merkle.Proof, height int64, +) ChannelResponse { + return ChannelResponse{ + Channel: channel, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ChannelPath(portID, channelID), "/")), + ProofHeight: uint64(height), + } +} + +// QueryChannelParams defines the params for the following queries: +// - 'custom/ibc/channel' +type QueryChannelParams struct { + PortID string + ChannelID string +} + +// NewQueryChannelParams creates a new QueryChannelParams instance +func NewQueryChannelParams(portID, channelID string) QueryChannelParams { + return QueryChannelParams{ + PortID: portID, + ChannelID: channelID, + } +} + +// PacketResponse defines the client query response for a packet which also +// includes a proof, its path and the height form which the proof was retrieved +type PacketResponse struct { + Packet Packet `json:"packet" yaml:"packet"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewPacketResponse creates a new PacketResponswe instance +func NewPacketResponse( + portID, channelID string, sequence uint64, packet Packet, proof *merkle.Proof, height int64, +) PacketResponse { + return PacketResponse{ + Packet: packet, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(PacketCommitmentPath(portID, channelID, sequence), "/")), + ProofHeight: uint64(height), + } +} diff --git a/x/ibc/handler.go b/x/ibc/handler.go index ed740f39183e..b80267dd7d92 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" ) // NewHandler defines the IBC handler @@ -14,6 +15,7 @@ func NewHandler(k Keeper) sdk.Handler { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { + // IBC client msgs case client.MsgCreateClient: return client.HandleMsgCreateClient(ctx, k.ClientKeeper, msg) @@ -23,6 +25,7 @@ func NewHandler(k Keeper) sdk.Handler { case client.MsgSubmitMisbehaviour: return client.HandleMsgSubmitMisbehaviour(ctx, k.ClientKeeper, msg) + // IBC connection msgs case connection.MsgConnectionOpenInit: return connection.HandleMsgConnectionOpenInit(ctx, k.ConnectionKeeper, msg) @@ -35,6 +38,25 @@ func NewHandler(k Keeper) sdk.Handler { case connection.MsgConnectionOpenConfirm: return connection.HandleMsgConnectionOpenConfirm(ctx, k.ConnectionKeeper, msg) + // IBC channel msgs + case channel.MsgChannelOpenInit: + return channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelOpenTry: + return channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelOpenAck: + return channel.HandleMsgChannelOpenAck(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelOpenConfirm: + return channel.HandleMsgChannelOpenConfirm(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelCloseInit: + return channel.HandleMsgChannelCloseInit(ctx, k.ChannelKeeper, msg) + + case channel.MsgChannelCloseConfirm: + return channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, msg) + default: errMsg := fmt.Sprintf("unrecognized IBC message type: %T", msg) return sdk.ErrUnknownRequest(errMsg).Result() diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index c9708a6e79a1..52158b48b140 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" ) @@ -12,6 +13,7 @@ import ( type Keeper struct { ClientKeeper client.Keeper ConnectionKeeper connection.Keeper + ChannelKeeper channel.Keeper PortKeeper port.Keeper } @@ -20,10 +22,12 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) clientKeeper := client.NewKeeper(cdc, key, codespace) connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) portKeeper := port.NewKeeper(cdc, key, codespace) + channelKeeper := channel.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, portKeeper) return Keeper{ ClientKeeper: clientKeeper, ConnectionKeeper: connectionKeeper, + ChannelKeeper: channelKeeper, PortKeeper: portKeeper, } } diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index 43db6f574dc0..fc2527df104c 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" ) // NewQuerier creates a querier for the IBC module @@ -36,6 +37,14 @@ func NewQuerier(k Keeper) sdk.Querier { return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName)) } + case channel.SubModuleName: + switch path[1] { + case channel.QueryChannel: + return channel.QuerierChannel(ctx, req, k.ChannelKeeper) + default: + return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", channel.SubModuleName)) + } + default: return nil, sdk.ErrUnknownRequest("unknown IBC query endpoint") } diff --git a/x/ibc/module.go b/x/ibc/module.go index 21ba001210de..791517826f03 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -39,6 +40,7 @@ func (AppModuleBasic) Name() string { func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) + channel.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } From 5bdff3cacceab279cfe4871c1251e14818b55cc3 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 5 Nov 2019 18:15:59 +0100 Subject: [PATCH 037/176] IBC v1.0.0 (#5245) * applying review in progress * apply review - make querier interface * fix cli errors * fix dependency * fix dependency * reflect method name change * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * reflect downstream changes * fix from address in tx cli * fix cli in progress(squash later) * fix cli * remove timeout, add channel cli * fix golangci * fix cli * Clean up * fix mock cli in progress * finalize cleanup, mock cli wip * add cli for mocksend * fix handler * rm commented lines * address review in progress * address review, rm cleanup/closing * rename mock packages * fix interface for gaia * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * update test * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * refactor: remove store accessors, update keeper and types to match spec (WIP) * update handshake and packet * implement packet timeouts * implement send and receive packet * implement packet ACK * update handler * add channel errors * channel querier * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update ICS04 with downstream changes * Implement tx cli actions * add MsgSendPacket handler; msg validation, errors and events * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * rm legacy tests; add query proofs support * remove capability key generation and authentication logic * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * downstream changes; custom marshal JSON; msg validation, and update errors * update errors and aliases * start batch-verify tests * update msg validation and CLI UX * minor changes on commitment types * fix channel and packet check (#5243) * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * authenticate port ID; remove send packet msg from CLI * comment out handlers * add ibc module to simapp * ICS20 implementation (#5204) * add ibc bank mock * modify handler * import channel * add receiving logic * add cli proof handling * modify cli * modify receiver type * modify errcode * optimize codes * add denom prefix when source is true * refactor code * error return * switch ibc antehandler to decorator pattern * fix name/comment * ICS 20 implementation (#5250) * move ics20 code to 20-transfer * clean code * fix compiling error * add transfer module * address ICS20 comments from review * add routing callbacks * clean code * add missing err return * modify err type * modify err type * add supply handling * modify proof type * add comments for msg and packet data * add timeout supply handling * modify module account name * use supply keeper for burn and mint coins * restructure keeper * update alias and module.go * golangci linter * add ics20 handler to IBC handler * update callbacks * update ICS20 escrow address * fix querier routes * fix create client cli * minor updates * ibc querier test * Refactor ibc/mock/bank into ICS 20 (#5264) * Most of code port from mock module to ICS 20 * A few minor fixes * Apply suggestions from code review Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * Fix suggestions from autolinter * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Fix order of messages * Add invalid height error code, check non-nil proof * Fix linter error * Return the underlying error * Tendermint starts at height 1 * Apply suggestions from code review * setup ics20 test suite * add event to MsgRecvPacket * update ibc keeper test to use test suite * Add handshake commands * WIP connection handshake * WIP Connection Handshake * use testsuite * Add cliCtx.WaitForNBlocks * fix connection handshake in progress * fix connection handshake in progress * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * finish tendermint tests * complete merge * Add tests for msgs * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * upstream changes * upstream changes * upstream changes --- simapp/app.go | 23 ++- types/result.go | 9 + x/auth/client/utils/tx.go | 39 ++++ x/ibc/03-connection/client/cli/tx.go | 66 ++++--- x/ibc/20-transfer/alias.go | 62 +++++++ x/ibc/20-transfer/client/cli/query.go | 68 +++++++ x/ibc/20-transfer/client/cli/tx.go | 150 +++++++++++++++ x/ibc/20-transfer/genesis.go | 17 ++ x/ibc/20-transfer/handler.go | 43 +++++ x/ibc/20-transfer/keeper/callbacks.go | 184 +++++++++++++++++++ x/ibc/20-transfer/keeper/keeper.go | 68 +++++++ x/ibc/20-transfer/keeper/keeper_test.go | 35 ++++ x/ibc/20-transfer/keeper/relay.go | 193 ++++++++++++++++++++ x/ibc/20-transfer/keeper/relay_test.go | 6 + x/ibc/20-transfer/module.go | 18 ++ x/ibc/20-transfer/types/codec.go | 21 +++ x/ibc/20-transfer/types/errors.go | 51 ++++++ x/ibc/20-transfer/types/events.go | 17 ++ x/ibc/20-transfer/types/expected_keepers.go | 44 +++++ x/ibc/20-transfer/types/keys.go | 46 +++++ x/ibc/20-transfer/types/msgs.go | 138 ++++++++++++++ x/ibc/20-transfer/types/packet.go | 70 +++++++ x/ibc/alias.go | 9 +- x/ibc/ante.go | 51 ++++++ x/ibc/client/cli/cli.go | 4 + x/ibc/handler.go | 8 + x/ibc/keeper/keeper.go | 9 +- x/ibc/keeper/keeper_test.go | 37 ++++ x/ibc/keeper/querier.go | 3 - x/ibc/keeper/querier_test.go | 102 +++++++++++ x/ibc/module.go | 4 + x/ibc/types/types.go | 13 +- 32 files changed, 1569 insertions(+), 39 deletions(-) create mode 100644 x/ibc/20-transfer/alias.go create mode 100644 x/ibc/20-transfer/client/cli/query.go create mode 100644 x/ibc/20-transfer/client/cli/tx.go create mode 100644 x/ibc/20-transfer/genesis.go create mode 100644 x/ibc/20-transfer/handler.go create mode 100644 x/ibc/20-transfer/keeper/callbacks.go create mode 100644 x/ibc/20-transfer/keeper/keeper.go create mode 100644 x/ibc/20-transfer/keeper/keeper_test.go create mode 100644 x/ibc/20-transfer/keeper/relay.go create mode 100644 x/ibc/20-transfer/keeper/relay_test.go create mode 100644 x/ibc/20-transfer/module.go create mode 100644 x/ibc/20-transfer/types/codec.go create mode 100644 x/ibc/20-transfer/types/errors.go create mode 100644 x/ibc/20-transfer/types/events.go create mode 100644 x/ibc/20-transfer/types/expected_keepers.go create mode 100644 x/ibc/20-transfer/types/keys.go create mode 100644 x/ibc/20-transfer/types/msgs.go create mode 100644 x/ibc/20-transfer/types/packet.go create mode 100644 x/ibc/ante.go create mode 100644 x/ibc/keeper/keeper_test.go create mode 100644 x/ibc/keeper/querier_test.go diff --git a/simapp/app.go b/simapp/app.go index 2b5d240c3e5b..81d7fd4b6e21 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -23,6 +23,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/evidence" "github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/ibc" + ibctransfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/params" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" @@ -61,16 +63,18 @@ var ( slashing.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, + ibc.AppModuleBasic{}, ) // module account permissions maccPerms = map[string][]string{ - auth.FeeCollectorName: nil, - distr.ModuleName: nil, - mint.ModuleName: {supply.Minter}, - staking.BondedPoolName: {supply.Burner, supply.Staking}, - staking.NotBondedPoolName: {supply.Burner, supply.Staking}, - gov.ModuleName: {supply.Burner}, + auth.FeeCollectorName: nil, + distr.ModuleName: nil, + mint.ModuleName: {supply.Minter}, + staking.BondedPoolName: {supply.Burner, supply.Staking}, + staking.NotBondedPoolName: {supply.Burner, supply.Staking}, + gov.ModuleName: {supply.Burner}, + ibctransfer.GetModuleAccountName(): {supply.Minter, supply.Burner}, } // module accounts that are allowed to receive tokens @@ -121,6 +125,7 @@ type SimApp struct { UpgradeKeeper upgrade.Keeper ParamsKeeper params.Keeper EvidenceKeeper evidence.Keeper + IBCKeeper ibc.Keeper // the module manager mm *module.Manager @@ -145,6 +150,7 @@ func NewSimApp( bam.MainStoreKey, auth.StoreKey, staking.StoreKey, supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey, gov.StoreKey, params.StoreKey, upgrade.StoreKey, evidence.StoreKey, + ibc.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(params.TStoreKey) @@ -224,6 +230,8 @@ func NewSimApp( staking.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), ) + app.IBCKeeper = ibc.NewKeeper(app.cdc, keys[ibc.StoreKey], ibc.DefaultCodespace, app.BankKeeper, app.SupplyKeeper) + // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. app.mm = module.NewManager( @@ -239,6 +247,7 @@ func NewSimApp( staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper), upgrade.NewAppModule(app.UpgradeKeeper), evidence.NewAppModule(app.EvidenceKeeper), + ibc.NewAppModule(app.IBCKeeper), ) // During begin block slashing happens after distr.BeginBlocker so that @@ -252,7 +261,7 @@ func NewSimApp( app.mm.SetOrderInitGenesis( auth.ModuleName, distr.ModuleName, staking.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName, mint.ModuleName, supply.ModuleName, - crisis.ModuleName, genutil.ModuleName, evidence.ModuleName, + crisis.ModuleName, ibc.ModuleName, genutil.ModuleName, evidence.ModuleName, ) app.mm.RegisterInvariants(&app.CrisisKeeper) diff --git a/types/result.go b/types/result.go index 9530be01d25c..7ef9a1775e3a 100644 --- a/types/result.go +++ b/types/result.go @@ -85,6 +85,15 @@ type TxResponse struct { Timestamp string `json:"timestamp,omitempty"` } +func (res TxResponse) IsOK() bool { + for _, lg := range res.Logs { + if !lg.Success { + return false + } + } + return true +} + // NewResponseResultTx returns a TxResponse given a ResultTx from tendermint func NewResponseResultTx(res *ctypes.ResultTx, tx Tx, timestamp string) TxResponse { if res == nil { diff --git a/x/auth/client/utils/tx.go b/x/auth/client/utils/tx.go index 55b7007002d9..e6a038f24cb7 100644 --- a/x/auth/client/utils/tx.go +++ b/x/auth/client/utils/tx.go @@ -108,6 +108,45 @@ func CompleteAndBroadcastTxCLI(txBldr authtypes.TxBuilder, cliCtx context.CLICon return cliCtx.PrintOutput(res) } +// CompleteAndBroadcastTx implements a utility function that facilitates +// sending a series of messages in a signed transaction given a TxBuilder and a +// QueryContext. It ensures that the account exists, has a proper number and +// sequence set. In addition, it builds and signs a transaction non-interactively +// with the supplied messages. Finally, it broadcasts the signed transaction to a node. +func CompleteAndBroadcastTx(txBldr authtypes.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg, passphrase string) (sdk.TxResponse, error) { + var res sdk.TxResponse + txBldr, err := PrepareTxBuilder(txBldr, cliCtx) + if err != nil { + return res, err + } + + fromName := cliCtx.GetFromName() + + if txBldr.SimulateAndExecute() || cliCtx.Simulate { + txBldr, err = EnrichWithGas(txBldr, cliCtx, msgs) + if err != nil { + return res, err + } + + gasEst := GasEstimateResponse{GasEstimate: txBldr.Gas()} + _, _ = fmt.Fprintf(os.Stderr, "%s\n", gasEst.String()) + } + + // build and sign the transaction + txBytes, err := txBldr.BuildAndSign(fromName, passphrase, msgs) + if err != nil { + return res, err + } + + // broadcast to a Tendermint node + res, err = cliCtx.BroadcastTx(txBytes) + if err != nil { + return res, err + } + + return res, err +} + // EnrichWithGas calculates the gas estimate that would be consumed by the // transaction and set the transaction's respective value accordingly. func EnrichWithGas(txBldr authtypes.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg) (authtypes.TxBuilder, error) { diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 22ccf7777d31..cef560ccdd57 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -349,6 +350,18 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } + // get passphrase for key from1 + passphrase1, err := keys.GetPassphrase(from1) + if err != nil { + return err + } + + // get passphrase for key from2 + passphrase2, err := keys.GetPassphrase(from2) + if err != nil { + return err + } + viper.Set(flags.FlagChainID, cid1) msgOpenInit := types.NewMsgConnectionOpenInit( connID1, clientID1, connID2, clientID2, @@ -359,11 +372,14 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenInit}) - if err != nil { + fmt.Printf("%v <- %-14v", cid1, msgOpenInit.Type()) + res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) + if err != nil || !res.IsOK() { return err } + fmt.Printf(" [OK] txid(%v) client(%v) conn(%v)\n", res.TxHash, clientID1, connID1) + // Another block has to be passed after msgOpenInit is committed // to retrieve the correct proofs // TODO: Modify this to actually check two blocks being processed, and @@ -383,11 +399,12 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) - if err != nil { + fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] client(%v)\n", clientID1) + fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) // Fetch proofs from cid1 viper.Set(flags.FlagChainID, cid1) @@ -409,12 +426,14 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenTry}) - if err != nil { + fmt.Printf("%v <- %-14v", cid2, msgOpenTry.Type()) + + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] client(%v) connection(%v)\n", clientID2, connID2) + fmt.Printf(" [OK] txid(%v) client(%v) connection(%v)\n", res.TxHash, clientID2, connID2) // Another block has to be passed after msgOpenInit is committed // to retrieve the correct proofs @@ -435,11 +454,11 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] client(%v)\n", clientID2) + fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID2) // Fetch proofs from cid2 viper.Set(flags.FlagChainID, cid2) @@ -461,11 +480,13 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenAck}) - if err != nil { + fmt.Printf("%v <- %-14v", cid1, msgOpenAck.Type()) + + res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] connection(%v)\n", connID1) + fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID1) // Another block has to be passed after msgOpenInit is committed // to retrieve the correct proofs @@ -486,13 +507,14 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) - if err != nil { + fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) + + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] client(%v)\n", clientID1) + fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - // Fetch proof from cid1 viper.Set(flags.FlagChainID, cid1) proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) if err != nil { @@ -507,11 +529,13 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}) - if err != nil { + fmt.Printf("%v <- %-14v", cid1, msgOpenConfirm.Type()) + + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) + if err != nil || !res.IsOK() { return err } - fmt.Printf(" [OK] connection(%v)\n", connID2) + fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID2) return nil }, diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go new file mode 100644 index 000000000000..66028740581e --- /dev/null +++ b/x/ibc/20-transfer/alias.go @@ -0,0 +1,62 @@ +package transfer + +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types + +import ( + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +const ( + DefaultPacketTimeout = keeper.DefaultPacketTimeout + DefaultCodespace = types.DefaultCodespace + CodeInvalidAddress = types.CodeInvalidAddress + CodeErrSendPacket = types.CodeErrSendPacket + CodeInvalidPacketData = types.CodeInvalidPacketData + CodeInvalidChannelOrder = types.CodeInvalidChannelOrder + CodeInvalidPort = types.CodeInvalidPort + CodeInvalidVersion = types.CodeInvalidVersion + AttributeKeyReceiver = types.AttributeKeyReceiver + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + BoundPortID = types.BoundPortID +) + +var ( + // functions aliases + NewKeeper = keeper.NewKeeper + RegisterCodec = types.RegisterCodec + ErrInvalidAddress = types.ErrInvalidAddress + ErrSendPacket = types.ErrSendPacket + ErrInvalidPacketData = types.ErrInvalidPacketData + ErrInvalidChannelOrder = types.ErrInvalidChannelOrder + ErrInvalidPort = types.ErrInvalidPort + ErrInvalidVersion = types.ErrInvalidVersion + GetEscrowAddress = types.GetEscrowAddress + GetDenomPrefix = types.GetDenomPrefix + GetModuleAccountName = types.GetModuleAccountName + NewMsgTransfer = types.NewMsgTransfer + + // variable aliases + ModuleCdc = types.ModuleCdc + AttributeValueCategory = types.AttributeValueCategory +) + +type ( + Keeper = keeper.Keeper + BankKeeper = types.BankKeeper + ChannelKeeper = types.ChannelKeeper + ClientKeeper = types.ClientKeeper + ConnectionKeeper = types.ConnectionKeeper + SupplyKeeper = types.SupplyKeeper + MsgTransfer = types.MsgTransfer + MsgRecvPacket = types.MsgRecvPacket + PacketData = types.PacketData + PacketDataAlias = types.PacketDataAlias +) diff --git a/x/ibc/20-transfer/client/cli/query.go b/x/ibc/20-transfer/client/cli/query.go new file mode 100644 index 000000000000..1795e1919edb --- /dev/null +++ b/x/ibc/20-transfer/client/cli/query.go @@ -0,0 +1,68 @@ +package cli + +import ( + "encoding/binary" + "fmt" + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/version" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + abci "github.com/tendermint/tendermint/abci/types" +) + +// GetTxCmd returns the transaction commands for IBC fungible token transfer +func GetQueryCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + queryCmd := &cobra.Command{ + Use: "transfer", + Short: "IBC fungible token transfer query subcommands", + } + + queryCmd.AddCommand( + GetCmdQueryNextSequence(cdc, storeKey), + ) + + return queryCmd +} + +// GetCmdQueryNextSequence defines the command to query a next receive sequence +func GetCmdQueryNextSequence(cdc *codec.Codec, queryRoute string) *cobra.Command { + cmd := &cobra.Command{ + Use: "next-recv [port-id] [channel-id]", + Short: "Query a next receive sequence", + Long: strings.TrimSpace(fmt.Sprintf(`Query an IBC channel end + +Example: +$ %s query ibc channel next-recv [port-id] [channel-id] + `, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + portID := args[0] + channelID := args[1] + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: channel.KeyNextSequenceRecv(portID, channelID), + Prove: true, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return err + } + + sequence := binary.BigEndian.Uint64(res.Value) + + return cliCtx.PrintOutput(sequence) + }, + } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + + return cmd +} diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go new file mode 100644 index 000000000000..28870567b55c --- /dev/null +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -0,0 +1,150 @@ +package cli + +import ( + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + channelutils "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// IBC transfer flags +var ( + FlagSource = "source" + FlagNode1 = "node1" + FlagNode2 = "node2" + FlagFrom1 = "from1" + FlagFrom2 = "from2" + FlagChainId2 = "chain-id2" + FlagSequence = "packet-sequence" + FlagTimeout = "timeout" +) + +// GetTxCmd returns the transaction commands for IBC fungible token transfer +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + txCmd := &cobra.Command{ + Use: "transfer", + Short: "IBC fungible token transfer transaction subcommands", + } + txCmd.AddCommand( + GetTransferTxCmd(cdc), + GetMsgRecvPacketCmd(cdc), + ) + + return txCmd +} + +// GetTransferTxCmd returns the command to create a NewMsgTransfer transaction +func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "transfer [src-port] [src-channel] [receiver] [amount]", + Short: "Transfer fungible token through IBC", + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + + sender := ctx.GetFromAddress() + srcPort := args[0] + srcChannel := args[1] + receiver, err := sdk.AccAddressFromBech32(args[2]) + if err != nil { + return err + } + + // parse coin trying to be sent + coins, err := sdk.ParseCoins(args[3]) + if err != nil { + return err + } + + source := viper.GetBool(FlagSource) + + msg := types.NewMsgTransfer(srcPort, srcChannel, coins, sender, receiver, source) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.GenerateOrBroadcastMsgs(ctx, txBldr, []sdk.Msg{msg}) + }, + } + cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") + cmd.Flags().String(flags.FlagFrom, "", "key in local keystore to send from") + return cmd +} + +// GetMsgRecvPacketCmd returns the command to create a MsgRecvTransferPacket transaction +func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "recv-packet [sending-port-id] [sending-channel-id] [client-id]", + Short: "Creates and sends a SendPacket message", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + + node2 := viper.GetString(FlagNode2) + cid1 := viper.GetString(flags.FlagChainID) + cid2 := viper.GetString(FlagChainId2) + cliCtx2 := context.NewCLIContextIBC(cliCtx.GetFromAddress().String(), cid2, node2). + WithCodec(cdc). + WithBroadcastMode(flags.BroadcastBlock) + + header, err := clientutils.GetTendermintHeader(cliCtx2) + if err != nil { + return err + } + + sourcePort, sourceChannel, clientid := args[0], args[1], args[2] + + passphrase, err := keys.GetPassphrase(viper.GetString(flags.FlagFrom)) + if err != nil { + return nil + } + + viper.Set(flags.FlagChainID, cid1) + msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid, header, cliCtx.GetFromAddress()) + if err := msgUpdateClient.ValidateBasic(); err != nil { + return err + } + + res, err := utils.CompleteAndBroadcastTx(txBldr, cliCtx, []sdk.Msg{msgUpdateClient}, passphrase) + if err != nil || !res.IsOK() { + return err + } + + viper.Set(flags.FlagChainID, cid2) + sequence := uint64(viper.GetInt(FlagSequence)) + packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), "ibc") + if err != nil { + return err + } + viper.Set(flags.FlagChainID, cid1) + + msg := types.NewMsgRecvPacket(packetRes.Packet, []commitment.Proof{packetRes.Proof}, packetRes.ProofHeight, cliCtx.GetFromAddress()) + if err := msg.ValidateBasic(); err != nil { + return err + } + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + }, + } + + cmd = client.PostCommands(cmd)[0] + cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") + cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") + cmd.Flags().String(FlagChainId2, "", "chain-id for the second chain") + cmd.Flags().String(FlagSequence, "", "sequence for the packet") + cmd.Flags().String(FlagTimeout, "", "timeout for the packet") + return cmd +} diff --git a/x/ibc/20-transfer/genesis.go b/x/ibc/20-transfer/genesis.go new file mode 100644 index 000000000000..facde722a27d --- /dev/null +++ b/x/ibc/20-transfer/genesis.go @@ -0,0 +1,17 @@ +package transfer + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +// InitGenesis sets distribution information for genesis +func InitGenesis(ctx sdk.Context, keeper Keeper) { + // check if the module account exists + moduleAcc := keeper.GetTransferAccount(ctx) + if moduleAcc == nil { + panic(fmt.Sprintf("%s module account has not been set", types.GetModuleAccountName())) + } +} diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go new file mode 100644 index 000000000000..731a6c27e7f5 --- /dev/null +++ b/x/ibc/20-transfer/handler.go @@ -0,0 +1,43 @@ +package transfer + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +// HandleMsgTransfer defines the sdk.Handler for MsgTransfer +func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Result) { + err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), + sdk.NewAttribute(types.AttributeKeyReceiver, msg.Receiver.String()), + ), + ) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + +// HandleMsgRecvPacket defines the sdk.Handler for MsgRecvPacket +func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (res sdk.Result) { + err := k.ReceivePacket(ctx, msg.Packet, msg.Proofs[0], msg.Height) + if err != nil { + return sdk.ResultFromError(err) + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + ), + ) + + return sdk.Result{Events: ctx.EventManager().Events()} +} diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go new file mode 100644 index 000000000000..8594783e6456 --- /dev/null +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -0,0 +1,184 @@ +package keeper + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +// nolint: unused +func (k Keeper) onChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + counterparty channeltypes.Counterparty, + version string, +) error { + if order != channeltypes.UNORDERED { + return types.ErrInvalidChannelOrder(k.codespace, order.String()) + } + + if counterparty.PortID != types.BoundPortID { + return types.ErrInvalidPort(k.codespace, portID) + } + + if strings.TrimSpace(version) != "" { + return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + } + + // NOTE: as the escrow address is generated from both the port and channel IDs + // there's no need to store it on a map. + return nil +} + +// nolint: unused +func (k Keeper) onChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + counterparty channeltypes.Counterparty, + version string, + counterpartyVersion string, +) error { + if order != channeltypes.UNORDERED { + return types.ErrInvalidChannelOrder(k.codespace, order.String()) + } + + if counterparty.PortID != types.BoundPortID { + return types.ErrInvalidPort(k.codespace, portID) + } + + if strings.TrimSpace(version) != "" { + return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + } + + if strings.TrimSpace(counterpartyVersion) != "" { + return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid counterparty version: %s", version)) + } + + // NOTE: as the escrow address is generated from both the port and channel IDs + // there's no need to store it on a map. + return nil +} + +// nolint: unused +func (k Keeper) onChanOpenAck( + ctx sdk.Context, + portID, + channelID string, + version string, +) error { + if strings.TrimSpace(version) != "" { + return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + } + + return nil +} + +// nolint: unused +func (k Keeper) onChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + // no-op + return nil +} + +// nolint: unused +func (k Keeper) onChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + // no-op + return nil +} + +// nolint: unused +func (k Keeper) onChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + // no-op + return nil +} + +// onRecvPacket is called when an FTTransfer packet is received +// nolint: unused +func (k Keeper) onRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, +) error { + var data types.PacketData + + err := data.UnmarshalJSON(packet.GetData()) + if err != nil { + return types.ErrInvalidPacketData(k.codespace) + } + + return k.ReceiveTransfer( + ctx, packet.GetSourcePort(), packet.GetSourceChannel(), + packet.GetDestPort(), packet.GetDestChannel(), data, + ) +} + +// nolint: unused +func (k Keeper) onAcknowledgePacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, +) error { + // no-op + return nil +} + +// nolint: unused +func (k Keeper) onTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, +) error { + var data types.PacketData + + err := data.UnmarshalJSON(packet.GetData()) + if err != nil { + return types.ErrInvalidPacketData(k.codespace) + } + + // check the denom prefix + prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourcePort()) + coins := make(sdk.Coins, len(data.Amount)) + for i, coin := range data.Amount { + coin := coin + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) + } + + if data.Source { + escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) + return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Sender, coins) + } + + // mint from supply + err = k.supplyKeeper.MintCoins(ctx, types.GetModuleAccountName(), data.Amount) + if err != nil { + return err + } + + return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Sender, data.Amount) +} + +// nolint: unused +func (k Keeper) onTimeoutPacketClose(_ sdk.Context, _ channeltypes.Packet) { + panic("can't happen, only unordered channels allowed") +} diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go new file mode 100644 index 000000000000..95576d4609f3 --- /dev/null +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -0,0 +1,68 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" +) + +// DefaultPacketTimeout is the default packet timeout relative to the current block height +const ( + DefaultPacketTimeout = 1000 // NOTE: in blocks +) + +// Keeper defines the IBC transfer keeper +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType + prefix []byte // prefix bytes for accessing the store + + clientKeeper types.ClientKeeper + connectionKeeper types.ConnectionKeeper + channelKeeper types.ChannelKeeper + bankKeeper types.BankKeeper + supplyKeeper types.SupplyKeeper +} + +// NewKeeper creates a new IBC transfer Keeper instance +func NewKeeper( + cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + clientKeeper types.ClientKeeper, connnectionKeeper types.ConnectionKeeper, + channelKeeper types.ChannelKeeper, bankKeeper types.BankKeeper, + supplyKeeper types.SupplyKeeper, +) Keeper { + + // ensure ibc transfer module account is set + if addr := supplyKeeper.GetModuleAddress(types.GetModuleAccountName()); addr == nil { + panic("the IBC transfer module account has not been set") + } + + return Keeper{ + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/transfer", + prefix: []byte(types.SubModuleName + "/"), // "transfer/" + clientKeeper: clientKeeper, + connectionKeeper: connnectionKeeper, + channelKeeper: channelKeeper, + bankKeeper: bankKeeper, + supplyKeeper: supplyKeeper, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName)) +} + +// GetTransferAccount returns the ICS20 - transfers ModuleAccount +func (k Keeper) GetTransferAccount(ctx sdk.Context) supplyexported.ModuleAccountI { + return k.supplyKeeper.GetModuleAccount(ctx, types.GetModuleAccountName()) +} diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go new file mode 100644 index 000000000000..77c423052098 --- /dev/null +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -0,0 +1,35 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/keeper" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.keeper = &app.IBCKeeper.TransferKeeper +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go new file mode 100644 index 000000000000..d87a589bbd80 --- /dev/null +++ b/x/ibc/20-transfer/keeper/relay.go @@ -0,0 +1,193 @@ +package keeper + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// SendTransfer handles transfer sending logic +func (k Keeper) SendTransfer( + ctx sdk.Context, + sourcePort, + sourceChannel string, + amount sdk.Coins, + sender, + receiver sdk.AccAddress, + isSourceChain bool, +) error { + // get the port and channel of the counterparty + channel, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) + if !found { + return channeltypes.ErrChannelNotFound(k.codespace, sourcePort, sourceChannel) + } + + destinationPort := channel.Counterparty.PortID + destinationChannel := channel.Counterparty.ChannelID + + // get the next sequence + sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel) + if !found { + return channeltypes.ErrSequenceNotFound(k.codespace, "send") + } + + coins := make(sdk.Coins, len(amount)) + prefix := types.GetDenomPrefix(destinationPort, destinationChannel) + switch { + case isSourceChain: + // build the receiving denomination prefix + for i, coin := range amount { + coins[i] = sdk.NewCoin(prefix+coin.Denom, coin.Amount) + } + default: + coins = amount + } + + return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, coins, sender, receiver, isSourceChain) +} + +// ReceivePacket handles receiving packet +func (k Keeper) ReceivePacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, height uint64) error { + _, err := k.channelKeeper.RecvPacket(ctx, packet, proof, height, nil, k.storeKey) + if err != nil { + return err + } + + var data types.PacketData + err = data.UnmarshalJSON(packet.GetData()) + if err != nil { + return sdk.NewError(types.DefaultCodespace, types.CodeInvalidPacketData, "invalid packet data") + } + + return k.ReceiveTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestPort(), packet.GetDestChannel(), data) +} + +// ReceiveTransfer handles transfer receiving logic +func (k Keeper) ReceiveTransfer( + ctx sdk.Context, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel string, + data types.PacketData, +) error { + if data.Source { + prefix := types.GetDenomPrefix(destinationPort, destinationChannel) + for _, coin := range data.Amount { + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + } + + // mint new tokens if the source of the transfer is the same chain + err := k.supplyKeeper.MintCoins(ctx, types.GetModuleAccountName(), data.Amount) + if err != nil { + return err + } + + // send to receiver + return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Receiver, data.Amount) + } + + // unescrow tokens + + // check the denom prefix + prefix := types.GetDenomPrefix(sourcePort, sourceChannel) + coins := make(sdk.Coins, len(data.Amount)) + for i, coin := range data.Amount { + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) + } + + escrowAddress := types.GetEscrowAddress(destinationPort, destinationChannel) + return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Receiver, coins) + +} + +func (k Keeper) createOutgoingPacket( + ctx sdk.Context, + seq uint64, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel string, + amount sdk.Coins, + sender sdk.AccAddress, + receiver sdk.AccAddress, + isSourceChain bool, +) error { + if isSourceChain { + // escrow tokens if the destination chain is the same as the sender's + escrowAddress := types.GetEscrowAddress(sourcePort, sourceChannel) + + prefix := types.GetDenomPrefix(destinationPort, destinationChannel) + coins := make(sdk.Coins, len(amount)) + for i, coin := range amount { + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) + } + + err := k.bankKeeper.SendCoins(ctx, sender, escrowAddress, coins) + if err != nil { + return err + } + + } else { + // burn vouchers from the sender's balance if the source is from another chain + prefix := types.GetDenomPrefix(sourcePort, sourceChannel) + for _, coin := range amount { + if !strings.HasPrefix(coin.Denom, prefix) { + return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + } + } + + // transfer the coins to the module account and burn them + err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, sender, types.GetModuleAccountName(), amount) + if err != nil { + return err + } + + // burn from supply + err = k.supplyKeeper.BurnCoins(ctx, types.GetModuleAccountName(), amount) + if err != nil { + return err + } + } + + packetData := types.PacketData{ + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: isSourceChain, + } + + // TODO: This should be binary-marshaled and hashed (for the commitment in the store). + packetDataBz, err := packetData.MarshalJSON() + if err != nil { + return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidPacketData, "invalid packet data") + } + + packet := channeltypes.NewPacket( + seq, + uint64(ctx.BlockHeight())+DefaultPacketTimeout, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + packetDataBz, + ) + + // TODO: Remove this, capability keys are never generated when sending packets. Not sure why this is here. + key := sdk.NewKVStoreKey(types.BoundPortID) + + return k.channelKeeper.SendPacket(ctx, packet, key) +} diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go new file mode 100644 index 000000000000..e6aa98f9eacd --- /dev/null +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -0,0 +1,6 @@ +package keeper_test + +func (suite *KeeperTestSuite) TestSendTransfer() { + err := suite.keeper.SendTransfer(suite.ctx, "", "", nil, nil, nil, true) + suite.Error(err) +} diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go new file mode 100644 index 000000000000..269be2377f6e --- /dev/null +++ b/x/ibc/20-transfer/module.go @@ -0,0 +1,18 @@ +package transfer + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/cli" +) + +// Name returns the IBC transfer ICS name +func Name() string { + return SubModuleName +} + +// GetTxCmd returns the root tx command for the IBC transfer. +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetTxCmd(cdc) +} diff --git a/x/ibc/20-transfer/types/codec.go b/x/ibc/20-transfer/types/codec.go new file mode 100644 index 000000000000..ba018b3fc676 --- /dev/null +++ b/x/ibc/20-transfer/types/codec.go @@ -0,0 +1,21 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterConcrete(MsgTransfer{}, "ibc/transfer/MsgTransfer", nil) + cdc.RegisterConcrete(MsgRecvPacket{}, "ibc/transfer/MsgRecvPacket", nil) + cdc.RegisterConcrete(PacketData{}, "ibc/transfer/PacketData", nil) +} + +var ModuleCdc = codec.New() + +func init() { + RegisterCodec(ModuleCdc) + channel.RegisterCodec(ModuleCdc) + commitment.RegisterCodec(ModuleCdc) +} diff --git a/x/ibc/20-transfer/types/errors.go b/x/ibc/20-transfer/types/errors.go new file mode 100644 index 000000000000..51f95d560a01 --- /dev/null +++ b/x/ibc/20-transfer/types/errors.go @@ -0,0 +1,51 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// transfer error codes +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName + + CodeInvalidAddress sdk.CodeType = 101 + CodeErrSendPacket sdk.CodeType = 102 + CodeInvalidPacketData sdk.CodeType = 103 + CodeInvalidChannelOrder sdk.CodeType = 104 + CodeInvalidPort sdk.CodeType = 105 + CodeInvalidVersion sdk.CodeType = 106 + CodeProofMissing sdk.CodeType = 107 + CodeInvalidHeight sdk.CodeType = 108 +) + +// ErrInvalidAddress implements sdk.Error +func ErrInvalidAddress(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidAddress, msg) +} + +// ErrSendPacket implements sdk.Error +func ErrSendPacket(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeErrSendPacket, "failed to send packet") +} + +// ErrInvalidPacketData implements sdk.Error +func ErrInvalidPacketData(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidPacketData, "invalid packet data") +} + +// ErrInvalidChannelOrder implements sdk.Error +func ErrInvalidChannelOrder(codespace sdk.CodespaceType, order string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidChannelOrder, fmt.Sprintf("invalid channel order: %s", order)) +} + +// ErrInvalidPort implements sdk.Error +func ErrInvalidPort(codespace sdk.CodespaceType, portID string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidPort, fmt.Sprintf("invalid port ID: %s", portID)) +} + +// ErrInvalidVersion implements sdk.Error +func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) sdk.Error { + return sdk.NewError(codespace, CodeInvalidVersion, msg) +} diff --git a/x/ibc/20-transfer/types/events.go b/x/ibc/20-transfer/types/events.go new file mode 100644 index 000000000000..759548ae1827 --- /dev/null +++ b/x/ibc/20-transfer/types/events.go @@ -0,0 +1,17 @@ +package types + +import ( + "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// IBC transfer events +const ( + AttributeKeyReceiver = "receiver" +) + +// IBC transfer events vars +var ( + AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) +) diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go new file mode 100644 index 000000000000..252eb8060645 --- /dev/null +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -0,0 +1,44 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" +) + +// BankKeeper defines the expected bank keeper +type BankKeeper interface { + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error +} + +// ChannelKeeper defines the expected IBC channel keeper +type ChannelKeeper interface { + GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channel.Channel, found bool) + GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) + SendPacket(ctx sdk.Context, packet channelexported.PacketI, portCapability sdk.CapabilityKey) error + RecvPacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, proofHeight uint64, acknowledgement []byte, portCapability sdk.CapabilityKey) (channelexported.PacketI, error) +} + +// ClientKeeper defines the expected IBC client keeper +type ClientKeeper interface { + GetConsensusState(ctx sdk.Context, clientID string) (connection clientexported.ConsensusState, found bool) +} + +// ConnectionKeeper defines the expected IBC connection keeper +type ConnectionKeeper interface { + GetConnection(ctx sdk.Context, connectionID string) (connection connection.ConnectionEnd, found bool) +} + +// SupplyKeeper expected supply keeper +type SupplyKeeper interface { + GetModuleAddress(name string) sdk.AccAddress + GetModuleAccount(ctx sdk.Context, name string) supplyexported.ModuleAccountI + MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error + BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error +} diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go new file mode 100644 index 000000000000..09b54dcadea5 --- /dev/null +++ b/x/ibc/20-transfer/types/keys.go @@ -0,0 +1,46 @@ +package types + +import ( + "fmt" + + "github.com/tendermint/tendermint/crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +const ( + // SubModuleName defines the IBC transfer name + SubModuleName = "transfer" + + // StoreKey is the store key string for IBC transfer + StoreKey = SubModuleName + + // RouterKey is the message route for IBC transfer + RouterKey = SubModuleName + + // QuerierRoute is the querier route for IBC transfer + QuerierRoute = SubModuleName + + // BoundPortID defines the name of the capability key + BoundPortID = "bank" +) + +// GetEscrowAddress returns the escrow address for the specified channel +// +// CONTRACT: this assumes that there's only one bank bridge module that owns the +// port associated with the channel ID so that the address created is actually +// unique. +func GetEscrowAddress(portID, channelID string) sdk.AccAddress { + return sdk.AccAddress(crypto.AddressHash([]byte(portID + channelID))) +} + +// GetDenomPrefix returns the receiving denomination prefix +func GetDenomPrefix(portID, channelID string) string { + return fmt.Sprintf("%s/%s/", portID, channelID) +} + +// GetModuleAccountName returns the IBC transfer module account name for supply +func GetModuleAccountName() string { + return fmt.Sprintf("%s/%s", ibctypes.ModuleName, SubModuleName) +} diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go new file mode 100644 index 000000000000..506676e66d7e --- /dev/null +++ b/x/ibc/20-transfer/types/msgs.go @@ -0,0 +1,138 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +type MsgTransfer struct { + SourcePort string `json:"source_port" yaml:"source_port"` // the port on which the packet will be sent + SourceChannel string `json:"source_channel" yaml:"source_channel"` // the channel by which the packet will be sent + Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred + Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address + Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain + Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred +} + +// NewMsgTransfer creates a new MsgTransfer instance +func NewMsgTransfer( + sourcePort, sourceChannel string, amount sdk.Coins, sender, receiver sdk.AccAddress, source bool, +) MsgTransfer { + return MsgTransfer{ + SourcePort: sourcePort, + SourceChannel: sourceChannel, + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, + } +} + +// Route implements sdk.Msg +func (MsgTransfer) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (MsgTransfer) Type() string { + return "transfer" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgTransfer) ValidateBasic() sdk.Error { + if err := host.DefaultPortIdentifierValidator(msg.SourcePort); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + } + if err := host.DefaultPortIdentifierValidator(msg.SourceChannel); err != nil { + return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + } + if !msg.Amount.IsValid() { + return sdk.ErrInvalidCoins("transfer amount is invalid") + } + if !msg.Amount.IsAllPositive() { + return sdk.ErrInsufficientCoins("transfer amount must be positive") + } + if msg.Sender.Empty() { + return sdk.ErrInvalidAddress("missing sender address") + } + if msg.Receiver.Empty() { + return sdk.ErrInvalidAddress("missing recipient address") + } + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgTransfer) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgTransfer) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Sender} +} + +type MsgRecvPacket struct { + Packet channelexported.PacketI `json:"packet" yaml:"packet"` + Proofs []commitment.Proof `json:"proofs" yaml:"proofs"` + Height uint64 `json:"height" yaml:"height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` +} + +// NewMsgRecvPacket creates a new MsgRecvPacket instance +func NewMsgRecvPacket(packet channelexported.PacketI, proofs []commitment.Proof, height uint64, signer sdk.AccAddress) MsgRecvPacket { + return MsgRecvPacket{ + Packet: packet, + Proofs: proofs, + Height: height, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (MsgRecvPacket) Route() string { + return ibctypes.RouterKey +} + +// Type implements sdk.Msg +func (MsgRecvPacket) Type() string { + return "recv_packet" +} + +// ValidateBasic implements sdk.Msg +func (msg MsgRecvPacket) ValidateBasic() sdk.Error { + if msg.Height < 1 { + return sdk.NewError(DefaultCodespace, CodeInvalidHeight, "invalid height") + } + + if msg.Proofs == nil { + return sdk.NewError(DefaultCodespace, CodeProofMissing, "proof missing") + } + + for _, proof := range msg.Proofs { + if proof.Proof == nil { + return sdk.NewError(DefaultCodespace, CodeProofMissing, "proof missing") + } + } + + if msg.Signer.Empty() { + return sdk.NewError(DefaultCodespace, CodeInvalidAddress, "invalid signer") + } + + return msg.Packet.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgRecvPacket) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgRecvPacket) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go new file mode 100644 index 000000000000..a9df673cc19f --- /dev/null +++ b/x/ibc/20-transfer/types/packet.go @@ -0,0 +1,70 @@ +package types + +import ( + "encoding/json" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// PacketData defines a struct for the packet payload +type PacketData struct { + Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred + Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address + Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain + Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred +} + +func (pd PacketData) MarshalAmino() ([]byte, error) { + return ModuleCdc.MarshalBinaryBare(pd) +} + +func (pd *PacketData) UnmarshalAmino(bz []byte) (err error) { + return ModuleCdc.UnmarshalBinaryBare(bz, pd) +} + +func (pd PacketData) Marshal() []byte { + return ModuleCdc.MustMarshalBinaryBare(pd) +} + +type PacketDataAlias PacketData + +// MarshalJSON implements the json.Marshaler interface. +func (pd PacketData) MarshalJSON() ([]byte, error) { + return json.Marshal((PacketDataAlias)(pd)) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (pd *PacketData) UnmarshalJSON(bz []byte) (err error) { + return json.Unmarshal(bz, (*PacketDataAlias)(pd)) +} + +func (pd PacketData) String() string { + return fmt.Sprintf(`PacketData: + Amount: %s + Sender: %s + Receiver: %s + Source: %v`, + pd.Amount.String(), + pd.Sender, + pd.Receiver, + pd.Source, + ) +} + +// ValidateBasic performs a basic check of the packet fields +func (pd PacketData) ValidateBasic() sdk.Error { + if !pd.Amount.IsValid() { + return sdk.ErrInvalidCoins("transfer amount is invalid") + } + if !pd.Amount.IsAllPositive() { + return sdk.ErrInsufficientCoins("transfer amount must be positive") + } + if pd.Sender.Empty() { + return sdk.ErrInvalidAddress("missing sender address") + } + if pd.Receiver.Empty() { + return sdk.ErrInvalidAddress("missing recipient address") + } + return nil +} diff --git a/x/ibc/alias.go b/x/ibc/alias.go index 7c1ad02349e2..abb2aae3c59a 100644 --- a/x/ibc/alias.go +++ b/x/ibc/alias.go @@ -12,10 +12,11 @@ import ( ) const ( - ModuleName = types.ModuleName - StoreKey = types.StoreKey - QuerierRoute = types.QuerierRoute - RouterKey = types.RouterKey + ModuleName = types.ModuleName + StoreKey = types.StoreKey + QuerierRoute = types.QuerierRoute + RouterKey = types.RouterKey + DefaultCodespace = types.DefaultCodespace ) var ( diff --git a/x/ibc/ante.go b/x/ibc/ante.go new file mode 100644 index 000000000000..0e1f7f635d70 --- /dev/null +++ b/x/ibc/ante.go @@ -0,0 +1,51 @@ +package ibc + +// // TODO: Should extract timeout msgs too +// func ExtractMsgPackets(msgs []sdk.Msg) (res []MsgPacket, abort bool) { +// res = make([]MsgPacket, 0, len(msgs)) +// for _, msg := range msgs { +// msgp, ok := msg.(MsgPacket) +// if ok { +// res = append(res, msgp) +// } +// } + +// if len(res) >= 2 { +// first := res[0] +// for _, msg := range res[1:] { +// if len(msg.ChannelID) != 0 && msg.ChannelID != first.ChannelID { +// return res, true +// } +// msg.ChannelID = first.ChannelID +// } +// } + +// return +// } + +// func VerifyMsgPackets(ctx sdk.Context, channel channel.Manager, msgs []MsgPacket) error { +// for _, msg := range msgs { +// err := channel.Receive(ctx, msg.Proofs, msg.Height, msg.ReceiverPort(), msg.ChannelID, msg.Packet) +// if err != nil { +// return err +// } +// } + +// return nil +// } + +// func NewAnteDecorator(channel channel.Manager) sdk.AnteDecorator { +// return func(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { +// msgs, abort := ExtractMsgPackets(tx.GetMsgs()) +// if abort { +// return ctx, host.ErrInvalidPacket +// } + +// err := VerifyMsgPackets(ctx, channel, msgs) +// if err != nil { +// return ctx, sdkerrors.Wrap(host.ErrInvalidPacket, err.Error()) +// } + +// return next(ctx, tx, simulate) +// } +// } diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index 04289628f640..cc6bd3bd7822 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -7,6 +7,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -23,6 +25,8 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ibcTxCmd.AddCommand(client.PostCommands( ibcclient.GetTxCmd(cdc, storeKey), connection.GetTxCmd(cdc, storeKey), + channel.GetTxCmd(cdc, storeKey), + transfer.GetTxCmd(cdc), )...) return ibcTxCmd } diff --git a/x/ibc/handler.go b/x/ibc/handler.go index b80267dd7d92..07fc9f831be8 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -7,6 +7,7 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" ) // NewHandler defines the IBC handler @@ -57,6 +58,13 @@ func NewHandler(k Keeper) sdk.Handler { case channel.MsgChannelCloseConfirm: return channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, msg) + // IBC transfer msgs + case transfer.MsgTransfer: + return transfer.HandleMsgTransfer(ctx, k.TransferKeeper, msg) + + case transfer.MsgRecvPacket: + return transfer.HandleMsgRecvPacket(ctx, k.TransferKeeper, msg) + default: errMsg := fmt.Sprintf("unrecognized IBC message type: %T", msg) return sdk.ErrUnknownRequest(errMsg).Result() diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 52158b48b140..2145416efb55 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -7,6 +7,7 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" ) // Keeper defines each ICS keeper for IBC @@ -15,19 +16,25 @@ type Keeper struct { ConnectionKeeper connection.Keeper ChannelKeeper channel.Keeper PortKeeper port.Keeper + TransferKeeper transfer.Keeper } // NewKeeper creates a new ibc Keeper -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { +func NewKeeper( + cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + bk transfer.BankKeeper, sk transfer.SupplyKeeper, +) Keeper { clientKeeper := client.NewKeeper(cdc, key, codespace) connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) portKeeper := port.NewKeeper(cdc, key, codespace) channelKeeper := channel.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, portKeeper) + transferKeeper := transfer.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, channelKeeper, bk, sk) return Keeper{ ClientKeeper: clientKeeper, ConnectionKeeper: connectionKeeper, ChannelKeeper: channelKeeper, PortKeeper: portKeeper, + TransferKeeper: transferKeeper, } } diff --git a/x/ibc/keeper/keeper_test.go b/x/ibc/keeper/keeper_test.go new file mode 100644 index 000000000000..4aee65b6db9e --- /dev/null +++ b/x/ibc/keeper/keeper_test.go @@ -0,0 +1,37 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/keeper" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper + querier sdk.Querier +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.keeper = &app.IBCKeeper + suite.querier = keeper.NewQuerier(app.IBCKeeper) +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index fc2527df104c..ee934fabd018 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -26,7 +26,6 @@ func NewQuerier(k Keeper) sdk.Querier { default: return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName)) } - case connection.SubModuleName: switch path[1] { case connection.QueryConnection: @@ -36,7 +35,6 @@ func NewQuerier(k Keeper) sdk.Querier { default: return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName)) } - case channel.SubModuleName: switch path[1] { case channel.QueryChannel: @@ -44,7 +42,6 @@ func NewQuerier(k Keeper) sdk.Querier { default: return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", channel.SubModuleName)) } - default: return nil, sdk.ErrUnknownRequest("unknown IBC query endpoint") } diff --git a/x/ibc/keeper/querier_test.go b/x/ibc/keeper/querier_test.go new file mode 100644 index 000000000000..62e37faac203 --- /dev/null +++ b/x/ibc/keeper/querier_test.go @@ -0,0 +1,102 @@ +package keeper_test + +import ( + "fmt" + + "github.com/stretchr/testify/require" + + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + + abci "github.com/tendermint/tendermint/abci/types" +) + +// TestNewQuerier tests that the querier paths are correct. +// NOTE: the actuall testing functionallity are located on each ICS querier test. +func (suite *KeeperTestSuite) TestNewQuerier() { + + query := abci.RequestQuery{ + Path: "", + Data: []byte{}, + } + + cases := []struct { + name string + path []string + expectsDefaultErr bool + errMsg string + }{ + {"client - QueryClientState", + []string{client.SubModuleName, client.QueryClientState}, + false, + "", + }, + { + "client - QueryConsensusState", + []string{client.SubModuleName, client.QueryConsensusState}, + false, + "", + }, + { + "client - QueryVerifiedRoot", + []string{client.SubModuleName, client.QueryVerifiedRoot}, + false, + "", + }, + { + "client - invalid query", + []string{client.SubModuleName, "foo"}, + true, + fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName), + }, + { + "connection - QueryConnection", + []string{connection.SubModuleName, connection.QueryConnection}, + false, + "", + }, + { + "connection - QueryClientConnections", + []string{connection.SubModuleName, connection.QueryClientConnections}, + false, + "", + }, + { + "connection - invalid query", + []string{connection.SubModuleName, "foo"}, + true, + fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName), + }, + { + "channel - QueryChannel", + []string{channel.SubModuleName, channel.QueryChannel}, + false, + "", + }, + { + "channel - invalid query", + []string{channel.SubModuleName, "foo"}, + true, + fmt.Sprintf("unknown IBC %s query endpoint", channel.SubModuleName), + }, + { + "invalid query", + []string{"foo"}, + true, + "unknown IBC query endpoint", + }, + } + + for i, tc := range cases { + i, tc := i, tc + suite.Run(tc.name, func() { + _, err := suite.querier(suite.ctx, tc.path, query) + if tc.expectsDefaultErr { + require.Contains(suite.T(), err.Error(), tc.errMsg, "test case #%d", i) + } else { + suite.Error(err, "test case #%d", i) + } + }) + } +} diff --git a/x/ibc/module.go b/x/ibc/module.go index 791517826f03..2e91d5540df0 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -15,6 +15,7 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -41,6 +42,7 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) channel.RegisterCodec(cdc) + transfer.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } @@ -116,6 +118,8 @@ func (am AppModule) NewQuerierHandler() sdk.Querier { // InitGenesis performs genesis initialization for the staking module. It returns // no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { + // check if the IBC transfer module account is set + transfer.InitGenesis(ctx, am.keeper.TransferKeeper) return []abci.ValidatorUpdate{} } diff --git a/x/ibc/types/types.go b/x/ibc/types/types.go index 535a8f2461e5..bce43911994f 100644 --- a/x/ibc/types/types.go +++ b/x/ibc/types/types.go @@ -1,15 +1,22 @@ package types +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + const ( // ModuleName is the name of the IBC module ModuleName = "ibc" // StoreKey is the string store representation - StoreKey = ModuleName + StoreKey string = ModuleName // QuerierRoute is the querier route for the IBC module - QuerierRoute = ModuleName + QuerierRoute string = ModuleName // RouterKey is the msg router key for the IBC module - RouterKey = ModuleName + RouterKey string = ModuleName + + // DefaultCodespace of the IBC module + DefaultCodespace sdk.CodespaceType = ModuleName ) From c378fb6f57efd0b25cfcd7f87c0fd409ac8c2ccc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 5 Nov 2019 18:20:44 +0100 Subject: [PATCH 038/176] IBC demo fixes (#5267) * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * refactor: remove store accessors, update keeper and types to match spec (WIP) * update handshake and packet * implement packet timeouts * implement send and receive packet * implement packet ACK * update handler * add channel errors * channel querier * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update ICS04 with downstream changes * Implement tx cli actions * add MsgSendPacket handler; msg validation, errors and events * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * rm legacy tests; add query proofs support * remove capability key generation and authentication logic * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * downstream changes; custom marshal JSON; msg validation, and update errors * update errors and aliases * start batch-verify tests * update msg validation and CLI UX * minor changes on commitment types * fix channel and packet check (#5243) * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * authenticate port ID; remove send packet msg from CLI * comment out handlers * add ibc module to simapp * ICS20 implementation (#5204) * add ibc bank mock * modify handler * import channel * add receiving logic * add cli proof handling * modify cli * modify receiver type * modify errcode * optimize codes * add denom prefix when source is true * refactor code * error return * switch ibc antehandler to decorator pattern * fix name/comment * ICS 20 implementation (#5250) * move ics20 code to 20-transfer * clean code * fix compiling error * add transfer module * address ICS20 comments from review * add routing callbacks * clean code * add missing err return * modify err type * modify err type * add supply handling * modify proof type * add comments for msg and packet data * add timeout supply handling * modify module account name * use supply keeper for burn and mint coins * restructure keeper * update alias and module.go * golangci linter * add ics20 handler to IBC handler * update callbacks * update ICS20 escrow address * fix querier routes * fix create client cli * minor updates * ibc querier test * Refactor ibc/mock/bank into ICS 20 (#5264) * Most of code port from mock module to ICS 20 * A few minor fixes * Apply suggestions from code review Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * Fix suggestions from autolinter * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Fix order of messages * Add invalid height error code, check non-nil proof * Fix linter error * Return the underlying error * Tendermint starts at height 1 * Apply suggestions from code review * setup ics20 test suite * add event to MsgRecvPacket * update ibc keeper test to use test suite * Add handshake commands * WIP connection handshake * WIP Connection Handshake * use testsuite * Add cliCtx.WaitForNBlocks * fix connection handshake in progress * fix connection handshake in progress * Add print debugging (old-school) * Add log line * More debugging * Set prove flag to true * More debugging * Use store query * Fix query, hopefully * Fix query path * Hmm * Fix context bug * Generate & return & use consensus state proof * Print debugging * Add debugging * Begin working on the channel creation command * remove submodule prefix from keypath, fix addConnectionToClients to treat nil as empty array * fix OpenConfirm, rm debugging code * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * WIP channel shake :man_dancing: * Update bound port * Add from flag to ICS 20 commands * Undefine flag * add debug * Uncomment channel message handlers * fix validatebasic identifier failure * Fix printing * add debug code * CLI debugging * fix counterpartyHops, channel handshake working w/o port * Fix compilation error * Push channel query command update * Remove unused code * Add gaiacli keys test * Update error * Add printf * fix token restriciton * comment out port * fix querier to retrieve the next sequence * Alter command to take arguments * Name it packet-sequence * add packet query utils * Use the querier * Packet is JSON * printf the value * fix query packet * fix packet receive in progress * lol * export Packet fields, rename Packet.XXX() -> Packet.GetXXX() * fix route * add debug * comment out port logic from packet.go * token transfer now working * fix client tx * Integrate Evidence Implementation into ICS-02 (#5258) * implement evidence in ics-02 * fix build errors and import cycles * address fede comments * remove unnecessary pubkey and fix init * add tests * Apply suggestions from code review * clean up * finish tendermint tests * complete merge * Add tests for msgs * ICS02 changes * upstream changes * fix * upstream changes * fix cons state * context changes * fix cli tx * upstream changes * upstream changes * upstream changes * upstream changes * more cleanup --- client/keys/add.go | 38 +++++++++++++++++++-- client/keys/root.go | 3 +- types/coin.go | 4 +-- x/ibc/04-channel/client/cli/tx.go | 49 ++++++++++++++------------- x/ibc/20-transfer/client/cli/query.go | 6 ++-- x/ibc/20-transfer/client/cli/tx.go | 8 ++--- x/ibc/20-transfer/module.go | 5 +++ x/ibc/client/cli/cli.go | 2 ++ 8 files changed, 79 insertions(+), 36 deletions(-) diff --git a/client/keys/add.go b/client/keys/add.go index 60f4dfe20060..9ef7f0531046 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -39,8 +39,42 @@ const ( DefaultKeyPass = "12345678" ) -// AddKeyCommand defines a keys command to add a generated or recovered private key to keybase. -func AddKeyCommand() *cobra.Command { +func addKeyScriptingCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "test [name] [mnemonic] [password]", + Short: "Add a recovered mnemonic to the keystore encrypt it, and save to disk, for testing", + Long: `Derive a new private key from an existing mnemonic file and encrypt to disk. + +NOTE: This is insecure and only meant to be used during testing!!!! HERE BE DRAGONS! +`, + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + kb, err := NewKeyBaseFromHomeFlag() + if err != nil { + return err + } + + _, err = kb.Get(args[0]) + if err == nil { + return errors.New("key already exists, exiting") + } + + if !bip39.IsMnemonicValid(args[1]) { + return errors.New("invalid mnemonic") + } + + info, err := kb.CreateAccount(args[0], args[1], "", args[2], keys.CreateHDPath(0, 0).String(), keys.Secp256k1) + if err != nil { + return err + } + + return printCreate(cmd, info, false, "") + }, + } + return cmd +} + +func addKeyCommand() *cobra.Command { cmd := &cobra.Command{ Use: "add ", Short: "Add an encrypted private key (either newly generated or recovered), encrypt it, and save to disk", diff --git a/client/keys/root.go b/client/keys/root.go index b7f70059c015..7786070e9109 100644 --- a/client/keys/root.go +++ b/client/keys/root.go @@ -21,7 +21,7 @@ func Commands() *cobra.Command { } cmd.AddCommand( MnemonicKeyCommand(), - AddKeyCommand(), + addKeyCommand(), ExportKeyCommand(), ImportKeyCommand(), ListKeysCmd(), @@ -31,6 +31,7 @@ func Commands() *cobra.Command { UpdateKeyCommand(), ParseKeyStringCommand(), MigrateCommand(), + addKeyScriptingCommand(), ) cmd.PersistentFlags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") viper.BindPFlag(flags.FlagKeyringBackend, cmd.Flags().Lookup(flags.FlagKeyringBackend)) diff --git a/types/coin.go b/types/coin.go index 98eaa6b806df..a23e3962e37e 100644 --- a/types/coin.go +++ b/types/coin.go @@ -594,8 +594,8 @@ func (coins Coins) Sort() Coins { // Parsing var ( - // Denominations can be 3 ~ 16 characters long. - reDnmString = `[a-z][a-z0-9]{2,15}` + // Denominations can be 3 ~ 32 characters long. + reDnmString = `[a-z][a-z0-9/]{2,31}` reAmt = `[[:digit:]]+` reDecAmt = `[[:digit:]]*\.[[:digit:]]+` reSpc = `[[:space:]]*` diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index 833ed29af01c..265ec880d73a 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -356,17 +357,17 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) - // // get passphrase for key from1 - // passphrase1, err := keys.GetPassphrase(from1) - // if err != nil { - // return err - // } + // get passphrase for key from1 + passphrase1, err := keys.GetPassphrase(from1) + if err != nil { + return err + } - // // get passphrase for key from2 - // passphrase2, err := keys.GetPassphrase(from2) - // if err != nil { - // return err - // } + // get passphrase for key from2 + passphrase2, err := keys.GetPassphrase(from2) + if err != nil { + return err + } // TODO: check state and if not Idle continue existing process viper.Set(flags.FlagChainID, cid1) @@ -375,8 +376,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err := utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenInit}) - if err != nil { + res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) + if err != nil || !res.IsOK() { return err } @@ -395,8 +396,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + if err != nil || !res.IsOK() { return err } @@ -411,8 +412,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenTry}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) + if err != nil || !res.IsOK() { return err } @@ -431,8 +432,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) + if err != nil || !res.IsOK() { return err } @@ -448,8 +449,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr1, ctx1, []sdk.Msg{msgOpenAck}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) + if err != nil || !res.IsOK() { return err } @@ -468,8 +469,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + if err != nil || !res.IsOK() { return err } @@ -484,8 +485,8 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - err = utils.CompleteAndBroadcastTxCLI(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}) - if err != nil { + res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) + if err != nil || !res.IsOK() { return err } diff --git a/x/ibc/20-transfer/client/cli/query.go b/x/ibc/20-transfer/client/cli/query.go index 1795e1919edb..4be0103385ee 100644 --- a/x/ibc/20-transfer/client/cli/query.go +++ b/x/ibc/20-transfer/client/cli/query.go @@ -15,15 +15,15 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) -// GetTxCmd returns the transaction commands for IBC fungible token transfer -func GetQueryCmd(cdc *codec.Codec, storeKey string) *cobra.Command { +// GetQueryCmd returns the query commands for IBC fungible token transfer +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { queryCmd := &cobra.Command{ Use: "transfer", Short: "IBC fungible token transfer query subcommands", } queryCmd.AddCommand( - GetCmdQueryNextSequence(cdc, storeKey), + GetCmdQueryNextSequence(cdc, queryRoute), ) return queryCmd diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index 28870567b55c..13917f47a62d 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -12,8 +12,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" channelutils "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -26,7 +26,7 @@ var ( FlagNode2 = "node2" FlagFrom1 = "from1" FlagFrom2 = "from2" - FlagChainId2 = "chain-id2" + FlagChainID2 = "chain-id2" FlagSequence = "packet-sequence" FlagTimeout = "timeout" ) @@ -96,7 +96,7 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { node2 := viper.GetString(FlagNode2) cid1 := viper.GetString(flags.FlagChainID) - cid2 := viper.GetString(FlagChainId2) + cid2 := viper.GetString(FlagChainID2) cliCtx2 := context.NewCLIContextIBC(cliCtx.GetFromAddress().String(), cid2, node2). WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) @@ -143,7 +143,7 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { cmd = client.PostCommands(cmd)[0] cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") - cmd.Flags().String(FlagChainId2, "", "chain-id for the second chain") + cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") cmd.Flags().String(FlagSequence, "", "sequence for the packet") cmd.Flags().String(FlagTimeout, "", "timeout for the packet") return cmd diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index 269be2377f6e..a1e12ec35d8f 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -16,3 +16,8 @@ func Name() string { func GetTxCmd(cdc *codec.Codec) *cobra.Command { return cli.GetTxCmd(cdc) } + +// GetQueryCmd returns the root tx command for the IBC transfer. +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + return cli.GetQueryCmd(cdc, queryRoute) +} diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index cc6bd3bd7822..4818d68008d6 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -45,6 +45,8 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { ibcQueryCmd.AddCommand(client.GetCommands( ibcclient.GetQueryCmd(cdc, queryRoute), connection.GetQueryCmd(cdc, queryRoute), + channel.GetQueryCmd(cdc, queryRoute), + transfer.GetQueryCmd(cdc, queryRoute), )...) return ibcQueryCmd } From d8cf351f375a245efb07d2d8da83d2ef6735de6f Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 7 Nov 2019 23:24:22 +0800 Subject: [PATCH 039/176] Add unit tests for ICS03 (#5275) * add Is() to counterobject * add readme, reflect ICS02 revision * reflect downstream ics * test in progress * add test * in progres * fin rebase * in progress * fin rebase * add CLIObject in progress * cli in progress * add CLIObject * separate testing from tendermint * add key to node * add root and storekey to tests/node, add codec * rm cli/query.go * fix test * fix lint * fix lint * add handler/msgs/client * rm relay * finalize rebase on 23 root/path sep * fix lint, fix syntax * fix querying * extract out context withstore * fix 02-client test * fix 23-commitment test * add query in progress * rm freebase, reformat query * add cli/handler/msg in progress * add cli/msg/handler * add CLIQuery, fix tests * fix golangci * add docs in progre * add comments * add comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add comments in progress * add comments * fix comment * add comments in progress * recover IntEncoding scheme for integer * add uint tests, don't use codec in custom types * finalize merge * add godoc * add godoc in progress * reformat test * rm XXX * add godoc * modify store * add query * update query.go * update query.go * cli refactor in progress * cli refactor in progress * add Query to boolean.go * fix key * fix cli / merkle test * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * godoc cleanup * fix test * fix client * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * merge from ics04 branch * fix lint * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix dependency * fix dependency * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * rm commented lines * address review in progress * address review, rm cleanup/closing * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * update expected client keeper and export verification funcs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * minor changes on commitment types * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * implement ics25 * update comment * refactor method name * fix file name * add test case * refactor code * refactor code * blocked the consensusState check * refactor code * fix golangci comments * refactor testcase * replace rootMultiStore with simApp * remove unless code * remove unless code & refactor test case * refactor testcase * goimports code * clean up --- x/ibc/03-connection/keeper/handshake_test.go | 311 +++++++++++++++++++ x/ibc/03-connection/keeper/keeper_test.go | 75 +++++ x/ibc/03-connection/types/msgs_test.go | 156 ++++++++++ x/ibc/keeper/keeper_test.go | 6 +- 4 files changed, 545 insertions(+), 3 deletions(-) create mode 100644 x/ibc/03-connection/keeper/handshake_test.go create mode 100644 x/ibc/03-connection/keeper/keeper_test.go create mode 100644 x/ibc/03-connection/types/msgs_test.go diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go new file mode 100644 index 000000000000..b8884c56b3ee --- /dev/null +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -0,0 +1,311 @@ +package keeper_test + +import ( + "fmt" + + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + abci "github.com/tendermint/tendermint/abci/types" +) + +func (suite *KeeperTestSuite) TestConnOpenInit() { + suite.createClient(testClientID1) + counterparty := connection.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + + success := func() error { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty) + + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.True(existed) + + expectConn := connection.ConnectionEnd{ + State: connection.INIT, + ClientID: testClientID1, + Counterparty: counterparty, + Versions: connection.GetCompatibleVersions(), + } + suite.EqualValues(expectConn, conn) + + return err + } + + connectionExists := func() error { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty) + return err + } + + var testCases = []TestCase{ + {success, true, ""}, + {connectionExists, false, "connection already exists"}, + } + + for _, tc := range testCases { + suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + } +} + +func (suite *KeeperTestSuite) TestConnOpenTry() { + suite.createClient(testClientID2) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) + + connectionKey := connection.ConnectionPath(testConnectionID2) + consensusKey := string(client.KeyConsensusState(testClientID2)) + + invalidProof := func() error { + proofInit, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + + counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx, + testConnectionID1, counterparty, testClientID1, + connection.GetCompatibleVersions(), + proofInit, proofConsensus, + uint64(proofHeight), uint64(consensusHeight)) + return err + } + + success := func() error { + suite.updateClient(testClientID1) + proofInit, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + + counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx, + testConnectionID1, counterparty, testClientID1, + connection.GetCompatibleVersions(), + proofInit, proofConsensus, + uint64(proofHeight), uint64(consensusHeight)) + suite.Nil(err) + + //check connection state + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.True(existed) + suite.Equal(connection.TRYOPEN, conn.State) + return err + } + + connectionExists := func() error { + suite.updateClient(testClientID1) + proofInit, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + + counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx, + testConnectionID1, counterparty, testClientID1, + connection.GetCompatibleVersions(), + proofInit, proofConsensus, + uint64(proofHeight), uint64(consensusHeight)) + return err + } + + var testCases = []TestCase{ + {invalidProof, false, "invalid proof"}, + {success, true, ""}, + {connectionExists, false, "connection already exists"}, + } + + for _, tc := range testCases { + suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + } + +} + +func (suite *KeeperTestSuite) TestConnOpenAck() { + suite.createClient(testClientID2) + suite.createClient(testClientID1) + + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) + connectionKey := connection.ConnectionPath(testConnectionID1) + consensusKey := string(client.KeyConsensusState(testClientID1)) + + connectionNotFound := func() error { + //suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + return err + } + + invalidConnectionState := func() error { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.NONE) + //suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + return err + } + + invalidVersion := func() error { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) + //suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, "1.0.1", proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + return err + } + + invalidProof := func() error { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) + //suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + return err + } + + success := func() error { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) + suite.updateClient(testClientID2) + + proofTry, proofHeight := suite.queryProof(connectionKey) + proofConsensus, consensusHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) + + //check connection state + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID2) + suite.True(existed) + suite.Equal(connection.OPEN, conn.State) + return err + + } + + var testCases = []TestCase{ + {connectionNotFound, false, "connection not exists"}, + {invalidConnectionState, false, "invalid connection state"}, + {invalidVersion, false, "invalid version"}, + {invalidProof, false, "invalid proof"}, + {success, true, ""}, + } + + for _, tc := range testCases { + suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + } + +} + +func (suite *KeeperTestSuite) TestConnOpenConfirm() { + suite.createClient(testClientID2) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.OPEN) + + connKey := connection.ConnectionPath(testConnectionID2) + proof, h := suite.queryProof(connKey) + + connectionNotFound := func() error { + //ErrConnectionNotFound + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) + return err + } + + invalidConnectionState := func() error { + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.INIT) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) + return err + } + + invalidProof := func() error { + //Error proof + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) + return err + } + + success := func() error { + //Success + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) + suite.updateClient(testClientID1) + proof, h = suite.queryProof(connKey) + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) + + //check connection state + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.True(existed) + suite.Equal(connection.OPEN, conn.State) + return err + } + + var testCases = []TestCase{ + {connectionNotFound, false, "connection not exists"}, + {invalidConnectionState, false, "invalid connection state"}, + {invalidProof, false, "invalid proof"}, + {success, true, ""}, + } + + for _, tc := range testCases { + suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + } +} + +func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", storeKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + +func (suite *KeeperTestSuite) createClient(clientID string) { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := tendermint.ConsensusState{ + ChainID: chainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, clientType, consensusState) + suite.NoError(err) +} + +func (suite *KeeperTestSuite) updateClient(clientID string) { + // always commit when updateClient and begin a new block + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := tendermint.ConsensusState{ + ChainID: chainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, clientID, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, clientID, state.GetHeight(), state.GetRoot()) +} + +func (suite *KeeperTestSuite) createConnection(connID, counterpartyConnID string, clientID, counterpartyClientID string, state connection.State) { + counterparty := connection.NewCounterparty(counterpartyClientID, counterpartyConnID, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + connection := connection.ConnectionEnd{ + State: state, + ClientID: clientID, + Counterparty: counterparty, + Versions: connection.GetCompatibleVersions(), + } + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, connID, connection) +} + +type TestCase = struct { + fun func() error + expected bool + errMsg string +} diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go new file mode 100644 index 000000000000..9c086f647d06 --- /dev/null +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -0,0 +1,75 @@ +package keeper_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" +) + +const ( + clientType = clientexported.Tendermint + storeKey = ibctypes.StoreKey + chainID = "test" + + testClientID1 = "testclientid1" + testConnectionID1 = "connectionid1" + + testClientID2 = "testclientid2" + testConnectionID2 = "connectionid2" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.app = app +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (suite *KeeperTestSuite) TestSetAndGetConnection() { + _, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.False(existed) + + counterparty := types.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + expConn := types.ConnectionEnd{ + State: types.INIT, + ClientID: testClientID1, + Counterparty: counterparty, + Versions: types.GetCompatibleVersions(), + } + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID1, expConn) + conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) + suite.True(existed) + suite.EqualValues(expConn, conn) +} + +func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { + + _, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1) + suite.False(existed) + + suite.app.IBCKeeper.ConnectionKeeper.SetClientConnectionPaths(suite.ctx, testClientID1, types.GetCompatibleVersions()) + paths, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1) + suite.True(existed) + suite.EqualValues(types.GetCompatibleVersions(), paths) +} diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go new file mode 100644 index 000000000000..7c94f3036936 --- /dev/null +++ b/x/ibc/03-connection/types/msgs_test.go @@ -0,0 +1,156 @@ +package types + +import ( + "fmt" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/stretchr/testify/require" +) + +func TestNewMsgConnectionOpenInit(t *testing.T) { + + type TestCase = struct { + msg MsgConnectionOpenInit + expected bool + errMsg string + } + + prefix := commitment.NewPrefix([]byte("storePrefixKey")) + signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") + + testMsgs := []MsgConnectionOpenInit{ + NewMsgConnectionOpenInit("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, signer), + NewMsgConnectionOpenInit("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, signer), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "test/conn1", "clienttotest", prefix, signer), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "test/conn1", prefix, signer), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", nil, signer), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, nil), + NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, signer), + } + + var testCases = []TestCase{ + {testMsgs[0], false, "invalid connection ID"}, + {testMsgs[1], false, "invalid client ID"}, + {testMsgs[2], false, "invalid counterparty client ID"}, + {testMsgs[3], false, "invalid counterparty connection ID"}, + {testMsgs[4], false, "empty counterparty prefix"}, + {testMsgs[5], false, "empty singer"}, + {testMsgs[6], true, "success"}, + } + + for i, tc := range testCases { + require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + } +} + +func TestNewMsgConnectionOpenTry(t *testing.T) { + type TestCase = struct { + msg MsgConnectionOpenTry + expected bool + errMsg string + } + + prefix := commitment.NewPrefix([]byte("storePrefixKey")) + signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") + + testMsgs := []MsgConnectionOpenTry{ + NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "ibc/test", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "test/conn1", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", nil, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, nil, commitment.Proof{}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, nil, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 0, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 0, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, nil), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), + } + + var testCases = []TestCase{ + {testMsgs[0], false, "invalid connection ID"}, + {testMsgs[1], false, "invalid client ID"}, + {testMsgs[2], false, "invalid counterparty connection ID"}, + {testMsgs[3], false, "invalid counterparty client ID"}, + {testMsgs[4], false, "empty counterparty prefix"}, + {testMsgs[5], false, "empty counterpartyVersions"}, + {testMsgs[6], false, "empty proofInit"}, + {testMsgs[7], false, "empty proofConsensus"}, + {testMsgs[8], false, "invalid proofHeight"}, + {testMsgs[9], false, "invalid consensusHeight"}, + {testMsgs[10], false, "empty singer"}, + {testMsgs[11], true, "success"}, + } + + for i, tc := range testCases { + require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + } +} + +func TestNewMsgConnectionOpenAck(t *testing.T) { + type TestCase = struct { + msg MsgConnectionOpenAck + expected bool + errMsg string + } + + signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") + + testMsgs := []MsgConnectionOpenAck{ + NewMsgConnectionOpenAck("test/conn1", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", nil, commitment.Proof{}, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, nil, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 0, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 0, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", nil), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", signer), + } + var testCases = []TestCase{ + {testMsgs[0], false, "invalid connection ID"}, + {testMsgs[1], false, "empty proofTry"}, + {testMsgs[2], false, "empty proofConsensus"}, + {testMsgs[3], false, "invalid proofHeight"}, + {testMsgs[4], false, "invalid consensusHeight"}, + {testMsgs[5], false, "invalid version"}, + {testMsgs[6], false, "empty signer"}, + {testMsgs[7], true, "success"}, + } + + for i, tc := range testCases { + require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + } +} + +func TestNewMsgConnectionOpenConfirm(t *testing.T) { + type TestCase = struct { + msg MsgConnectionOpenConfirm + expected bool + errMsg string + } + + signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") + + testMsgs := []MsgConnectionOpenConfirm{ + NewMsgConnectionOpenConfirm("test/conn1", commitment.Proof{}, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", nil, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 0, signer), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 10, nil), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 10, signer), + } + + var testCases = []TestCase{ + {testMsgs[0], false, "invalid connection ID"}, + {testMsgs[1], false, "empty proofTry"}, + {testMsgs[2], false, "invalid proofHeight"}, + {testMsgs[3], false, "empty signer"}, + {testMsgs[4], true, "success"}, + } + + for i, tc := range testCases { + require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + } +} diff --git a/x/ibc/keeper/keeper_test.go b/x/ibc/keeper/keeper_test.go index 4aee65b6db9e..acf6b4a52241 100644 --- a/x/ibc/keeper/keeper_test.go +++ b/x/ibc/keeper/keeper_test.go @@ -16,9 +16,9 @@ import ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - keeper *keeper.Keeper + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper querier sdk.Querier } From 97c36138d0503ecd0d853452629430e7b7a2df78 Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 7 Nov 2019 23:28:18 +0800 Subject: [PATCH 040/176] Add unit tests for ICS04 (#5286) * fix test * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * applying review in progress * apply review - make querier interface * fix cli errors * fix dependency * fix dependency * reflect method name change * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * revise querier interface to work both on cli & store * reflect downstream change * fix cli * reflect downstream changes * reflect downstream changes * fix from address in tx cli * fix cli in progress(squash later) * fix cli * remove timeout, add channel cli * fix golangci * fix cli * Clean up * fix mock cli in progress * finalize cleanup, mock cli wip * add cli for mocksend * fix handler * rm commented lines * address review in progress * address review, rm cleanup/closing * rename mock packages * fix interface for gaia * rename Path -> Prefix * Store accessor upstream changes (#5119) * Store accessor upstream changes (#5119) * add comments, reformat merkle querier * rm merkle/utils * ICS 23 upstream changes (#5120) * ICS 23 upstream changes (#5120) * update Value * update test * fix * ICS 02 upstream changes (#5122) * ICS 02 upstream changes (#5122) * ICS 03 upstream changes (#5123) * ICS 03 upstream changes (#5123) * update test * cleanup types and submodule * more cleanup and godocs * remove counterPartyManager/State and cleanup * implement SubmitMisbehaviour and refactor * errors * events * fix test * refactors * WIP refactor ICS03 * remove Mapping * remove store accessors * proposed refactor * remove store accessors from ICS02 * refactor queriers, handler and clean keeper * logger and tx long description * ineffassign * Apply suggestions from code review Co-Authored-By: Jack Zampolin * Apply suggestions from code review Co-Authored-By: Jack Zampolin * remove store accessors * refactor handshake to update it to the latest ICS03 spec * update handler and msgs * add verification functions * update verification * ICS02 module.go * top level x/ibc structure * update connection queries * update connection tx * remove extra files * refactor: remove store accessors, update keeper and types to match spec (WIP) * update handshake and packet * implement packet timeouts * implement send and receive packet * implement packet ACK * update handler * add channel errors * channel querier * update expected client keeper and export verification funcs * ICS 05 Implementation * release port and godocs * Update x/ibc/02-client/client/cli/query.go Co-Authored-By: Jack Zampolin * Update x/ibc/02-client/types/tendermint/consensus_state.go Co-Authored-By: Jack Zampolin * address some of the review comments * resolve some TODOs and address comments from review * update connection versioning * minor error updates * update ICS04 with downstream changes * Implement tx cli actions * add MsgSendPacket handler; msg validation, errors and events * update errors and add port Keeper to ibc Keeper * minor UX improvements * rename pkg * fixes * refactor ICS23 * cleanup types * ICS 5 updates (#5222) * Validate port identifiers * Refactor to static bind * Add comments * Add 'GetPorts' query function * rename pkg and fix import * implement batch verification * gosimple suggestion * various fixes; remove legacy tests; remove commitment path query * alias * minor updates from ICS23 * renaming * update verification and rename root funcs * rm legacy tests; add query proofs support * remove capability key generation and authentication logic * move querier to x/ibc * update query.go to use 'custom/...' query path * add tests * ICS 24 Implementation (#5229) * add validation functions * validate path in ics-23 * address @fede comments * move errors into host package * flatten ICS23 structure * fix ApplyPrefix * updates from ICS23 and ICS24 * msg.ValidateBasic and ADR09 evidence interface * complete types testing * delete empty test file * remove ibc errors from core error package * custom JSON marshaling; msg.ValidateBasic; renaming of variables * minor update * custom JSON marshaling * use host validation for port ids * downstream changes; custom marshal JSON; msg validation, and update errors * update errors and aliases * update msg validation and CLI UX * minor changes on commitment types * fix channel and packet check (#5243) * R4R - Store consensus state correctly (#5242) * store consensus state correctly * fix client example * update alias * update alias * update alias and keeper.GetPort() * authenticate port ID; remove send packet msg from CLI * comment out handlers * add ibc module to simapp * ICS20 implementation (#5204) * add ibc bank mock * modify handler * import channel * add receiving logic * add cli proof handling * modify cli * modify receiver type * modify errcode * optimize codes * add denom prefix when source is true * refactor code * error return * switch ibc antehandler to decorator pattern * fix name/comment * ICS 20 implementation (#5250) * move ics20 code to 20-transfer * clean code * fix compiling error * add transfer module * address ICS20 comments from review * add routing callbacks * clean code * add missing err return * modify err type * modify err type * add supply handling * modify proof type * add comments for msg and packet data * add timeout supply handling * modify module account name * use supply keeper for burn and mint coins * restructure keeper * update alias and module.go * golangci linter * add ics20 handler to IBC handler * update callbacks * update ICS20 escrow address * fix querier routes * fix create client cli * minor updates * ibc querier test * Refactor ibc/mock/bank into ICS 20 (#5264) * Most of code port from mock module to ICS 20 * A few minor fixes * Apply suggestions from code review Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * Fix suggestions from autolinter * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Fix order of messages * Add invalid height error code, check non-nil proof * Fix linter error * Return the underlying error * Tendermint starts at height 1 * Apply suggestions from code review * setup ics20 test suite * add event to MsgRecvPacket * update ibc keeper test to use test suite * Add handshake commands * WIP connection handshake * WIP Connection Handshake * Add cliCtx.WaitForNBlocks * fix connection handshake in progress * fix connection handshake in progress * add channel unit test * add more channel tests * fix channel test * refactor channel test * add capability test for channel * make channel testing work * optimize channel test * delete types/errors.go * modify capability test * uncomment * add msg tests for channel * fix port capability store * fix channel test * use simapp * modify channel test * refactor channel msg test * go fmt --- x/ibc/04-channel/keeper/handshake_test.go | 329 ++++++++++++++++++++++ x/ibc/04-channel/keeper/keeper.go | 10 + x/ibc/04-channel/keeper/keeper_test.go | 132 +++++++++ x/ibc/04-channel/types/msgs_test.go | 304 ++++++++++++++++++++ x/ibc/05-port/keeper/keeper.go | 10 +- 5 files changed, 780 insertions(+), 5 deletions(-) create mode 100644 x/ibc/04-channel/keeper/handshake_test.go create mode 100644 x/ibc/04-channel/keeper/keeper_test.go create mode 100644 x/ibc/04-channel/types/msgs_test.go diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go new file mode 100644 index 000000000000..5a8ce10ceb4a --- /dev/null +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -0,0 +1,329 @@ +package keeper_test + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + abci "github.com/tendermint/tendermint/abci/types" +) + +func (suite *KeeperTestSuite) createClient() { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + suite.NoError(err) +} + +func (suite *KeeperTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) +} + +func (suite *KeeperTestSuite) createConnection(state connection.State) { + connection := connection.ConnectionEnd{ + State: state, + ClientID: testClient, + Counterparty: connection.Counterparty{ + ClientID: testClient, + ConnectionID: testConnection, + Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + }, + Versions: connection.GetCompatibleVersions(), + } + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) +} + +func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state types.State) { + channel := types.Channel{ + State: state, + Ordering: testChannelOrder, + Counterparty: types.Counterparty{ + PortID: counterpartyPort, + ChannelID: counterpartyChan, + }, + ConnectionHops: []string{connID}, + Version: testChannelVersion, + } + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, channel) +} + +func (suite *KeeperTestSuite) deleteChannel(portID string, chanID string) { + store := prefix.NewStore(suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)), []byte{}) + store.Delete(types.KeyChannel(portID, chanID)) +} + +func (suite *KeeperTestSuite) bindPort(portID string) sdk.CapabilityKey { + return suite.app.IBCKeeper.PortKeeper.BindPort(portID) +} + +func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + +func (suite *KeeperTestSuite) TestChanOpenInit() { + counterparty := types.NewCounterparty(testPort2, testChannel2) + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.NotNil(err) // channel has already exist + + suite.deleteChannel(testPort1, testChannel1) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.NONE) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(types.INIT, channel.State) +} + +func (suite *KeeperTestSuite) TestChanOpenTry() { + counterparty := types.NewCounterparty(testPort1, testChannel1) + suite.bindPort(testPort2) + channelKey := types.ChannelPath(testPort1, testChannel1) + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.INIT) + suite.updateClient() + proofInit, proofHeight := suite.queryProof(channelKey) + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel has already exist + + suite.deleteChannel(testPort2, testChannel2) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // unauthenticated port + + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.NONE) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) + suite.updateClient() + proofInit, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel membership verification failed due to invalid counterparty + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) + suite.updateClient() + proofInit, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) + suite.True(found) + suite.Equal(types.OPENTRY, channel.State) +} + +func (suite *KeeperTestSuite) TestChanOpenAck() { + suite.bindPort(testPort1) + channelKey := types.ChannelPath(testPort2, testChannel2) + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.updateClient() + proofTry, proofHeight := suite.queryProof(channelKey) + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // channel does not exist + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // invalid channel state + + suite.createChannel(testPort2, testChannel1, testConnection, testPort1, testChannel2, types.INIT) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort2, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // unauthenticated port + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.NONE) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) + suite.updateClient() + proofTry, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.NotNil(err) // channel membership verification failed due to invalid counterparty + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.updateClient() + proofTry, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(types.OPEN, channel.State) +} + +func (suite *KeeperTestSuite) TestChanOpenConfirm() { + suite.bindPort(testPort2) + channelKey := types.ChannelPath(testPort1, testChannel1) + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) + suite.updateClient() + proofAck, proofHeight := suite.queryProof(channelKey) + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // channel does not exist + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // invalid channel state + + suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.OPENTRY) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort1, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // unauthenticated port + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.NONE) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) + suite.updateClient() + proofAck, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.NotNil(err) // channel membership verification failed due to invalid counterparty + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) + suite.updateClient() + proofAck, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) + suite.True(found) + suite.Equal(types.OPEN, channel.State) +} + +func (suite *KeeperTestSuite) TestChanCloseInit() { + suite.bindPort(testPort1) + + err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort2, testChannel1) + suite.NotNil(err) // authenticated port + + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.NotNil(err) // channel does not exist + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.NotNil(err) // channel is already closed + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.TRYOPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(types.CLOSED, channel.State) +} + +func (suite *KeeperTestSuite) TestChanCloseConfirm() { + suite.bindPort(testPort2) + channelKey := types.ChannelPath(testPort1, testChannel1) + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) + suite.updateClient() + proofInit, proofHeight := suite.queryProof(channelKey) + err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort1, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // unauthenticated port + + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel does not exist + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.CLOSED) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel is already closed + + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // connection does not exist + + suite.createConnection(connection.TRYOPEN) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // invalid connection state + + suite.createConnection(connection.OPEN) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) + suite.updateClient() + proofInit, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.NotNil(err) // channel membership verification failed due to invalid counterparty + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) + suite.updateClient() + proofInit, proofHeight = suite.queryProof(channelKey) + err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) + suite.Nil(err) // successfully executed + + channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) + suite.True(found) + suite.Equal(types.CLOSED, channel.State) +} diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index 6169c72ffc3a..dc6bbd3fb021 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -144,3 +144,13 @@ func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID stri store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) } + +// GetPacketAcknowledgement gets the packet ack hash from the store +func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + bz := store.Get(types.KeyPacketAcknowledgement(portID, channelID, sequence)) + if bz == nil { + return nil, false + } + return bz, true +} diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go new file mode 100644 index 000000000000..f05cc56db841 --- /dev/null +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -0,0 +1,132 @@ +package keeper_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" +) + +// define constants used for testing +const ( + testChainID = "test-chain-id" + testClient = "test-client" + testClientType = clientexported.Tendermint + + testConnection = "testconnection" + testPort1 = "firstport" + testPort2 = "secondport" + testChannel1 = "firstchannel" + testChannel2 = "secondchannel" + + testChannelOrder = types.ORDERED + testChannelVersion = "1.0" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.app = app + + suite.createClient() +} + +func (suite *KeeperTestSuite) TestSetChannel() { + _, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.False(found) + + channel := types.Channel{ + State: types.OPEN, + Ordering: testChannelOrder, + Counterparty: types.Counterparty{ + PortID: testPort1, + ChannelID: testChannel1, + }, + ConnectionHops: []string{testConnection}, + Version: testChannelVersion, + } + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort1, testChannel1, channel) + + storedChannel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(channel, storedChannel) +} + +func (suite *KeeperTestSuite) TestSetChannelCapability() { + _, found := suite.app.IBCKeeper.ChannelKeeper.GetChannelCapability(suite.ctx, testPort1, testChannel1) + suite.False(found) + + channelCap := "test-channel-capability" + suite.app.IBCKeeper.ChannelKeeper.SetChannelCapability(suite.ctx, testPort1, testChannel1, channelCap) + + storedChannelCap, found := suite.app.IBCKeeper.ChannelKeeper.GetChannelCapability(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(channelCap, storedChannelCap) +} + +func (suite *KeeperTestSuite) TestSetSequence() { + _, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + suite.False(found) + + _, found = suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceRecv(suite.ctx, testPort1, testChannel1) + suite.False(found) + + nextSeqSend, nextSeqRecv := uint64(10), uint64(10) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + + storedNextSeqSend, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(nextSeqSend, storedNextSeqSend) + + storedNextSeqRecv, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(nextSeqRecv, storedNextSeqRecv) +} + +func (suite *KeeperTestSuite) TestPackageCommitment() { + seq := uint64(10) + storedCommitment := suite.app.IBCKeeper.ChannelKeeper.GetPacketCommitment(suite.ctx, testPort1, testChannel1, seq) + suite.Equal([]byte(nil), storedCommitment) + + commitment := []byte("commitment") + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, seq, commitment) + + storedCommitment = suite.app.IBCKeeper.ChannelKeeper.GetPacketCommitment(suite.ctx, testPort1, testChannel1, seq) + suite.Equal(commitment, storedCommitment) +} + +func (suite *KeeperTestSuite) TestSetPacketAcknowledgement() { + seq := uint64(10) + + storedAckHash, found := suite.app.IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, seq) + suite.False(found) + suite.Nil(storedAckHash) + + ackHash := []byte("ackhash") + suite.app.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, seq, ackHash) + + storedAckHash, found = suite.app.IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, seq) + suite.True(found) + suite.Equal(ackHash, storedAckHash) +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go new file mode 100644 index 000000000000..c57a35af74ad --- /dev/null +++ b/x/ibc/04-channel/types/msgs_test.go @@ -0,0 +1,304 @@ +package types + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/stretchr/testify/require" +) + +// define constants used for testing +const ( + invalidPort = "invalidport1" + invalidShortPort = "p" + invalidLongPort = "invalidlongportinvalidlongport" + + invalidChannel = "invalidchannel1" + invalidShortChannel = "invalidch" + invalidLongChannel = "invalidlongchannelinvalidlongchannel" + + invalidConnection = "invalidconnection1" + invalidShortConnection = "invalidcn" + invalidLongConnection = "invalidlongconnection" +) + +// define variables used for testing +var ( + connHops = []string{"testconnection"} + invalidConnHops = []string{"testconnection", "testconnection"} + invalidShortConnHops = []string{invalidShortConnection} + invalidLongConnHops = []string{invalidLongConnection} + + proof = commitment.Proof{} + + addr = sdk.AccAddress("testaddr") +) + +// TestMsgChannelOpenInit tests ValidateBasic for MsgChannelOpenInit +func TestMsgChannelOpenInit(t *testing.T) { + testMsgs := []MsgChannelOpenInit{ + NewMsgChannelOpenInit("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg + NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id + NewMsgChannelOpenInit(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long port id + NewMsgChannelOpenInit(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // port id contains non-alpha + NewMsgChannelOpenInit("testport", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short channel id + NewMsgChannelOpenInit("testport", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long channel id + NewMsgChannelOpenInit("testport", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // channel id contains non-alpha + NewMsgChannelOpenInit("testport", "testchannel", "1.0", Order(3), connHops, "testcpport", "testcpchannel", addr), // invalid channel order + NewMsgChannelOpenInit("testport", "testchannel", "1.0", ORDERED, invalidConnHops, "testcpport", "testcpchannel", addr), // connection hops more than 1 + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", addr), // too short connection id + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", addr), // too long connection id + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", addr), // connection id contains non-alpha + NewMsgChannelOpenInit("testport", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", addr), // empty channel version + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", addr), // invalid counterparty port id + NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, addr), // invalid counterparty channel id + } + + testCases := []struct { + msg MsgChannelOpenInit + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "invalid channel order"}, + {testMsgs[8], false, "connection hops more than 1 "}, + {testMsgs[9], false, "too short connection id"}, + {testMsgs[10], false, "too long connection id"}, + {testMsgs[11], false, "connection id contains non-alpha"}, + {testMsgs[12], false, "empty channel version"}, + {testMsgs[13], false, "invalid counterparty port id"}, + {testMsgs[14], false, "invalid counterparty channel id"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelOpenTry tests ValidateBasic for MsgChannelOpenTry +func TestMsgChannelOpenTry(t *testing.T) { + testMsgs := []MsgChannelOpenTry{ + NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // valid msg + NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short port id + NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long port id + NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenTry("testport", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short channel id + NewMsgChannelOpenTry("testport", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long channel id + NewMsgChannelOpenTry("testport", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", proof, 1, addr), // empty counterparty version + NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 0, addr), // proof height is zero + NewMsgChannelOpenTry("testport", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // invalid channel order + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection hops more than 1 + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short connection id + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long connection id + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection id contains non-alpha + NewMsgChannelOpenTry("testport", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // empty channel version + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", proof, 1, addr), // invalid counterparty port id + NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", proof, 1, addr), // invalid counterparty channel id + } + + testCases := []struct { + msg MsgChannelOpenTry + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "empty counterparty version"}, + {testMsgs[8], false, "empty proof"}, + {testMsgs[9], false, "proof height is zero"}, + {testMsgs[10], false, "invalid channel order"}, + {testMsgs[11], false, "connection hops more than 1 "}, + {testMsgs[12], false, "too short connection id"}, + {testMsgs[13], false, "too long connection id"}, + {testMsgs[14], false, "connection id contains non-alpha"}, + {testMsgs[15], false, "empty channel version"}, + {testMsgs[16], false, "invalid counterparty port id"}, + {testMsgs[17], false, "invalid counterparty channel id"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelOpenAck tests ValidateBasic for MsgChannelOpenAck +func TestMsgChannelOpenAck(t *testing.T) { + testMsgs := []MsgChannelOpenAck{ + NewMsgChannelOpenAck("testport", "testchannel", "1.0", proof, 1, addr), // valid msg + NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", proof, 1, addr), // too short port id + NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", proof, 1, addr), // too long port id + NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenAck("testport", invalidShortChannel, "1.0", proof, 1, addr), // too short channel id + NewMsgChannelOpenAck("testport", invalidLongChannel, "1.0", proof, 1, addr), // too long channel id + NewMsgChannelOpenAck("testport", invalidChannel, "1.0", proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenAck("testport", "testchannel", "", proof, 1, addr), // empty counterparty version + NewMsgChannelOpenAck("testport", "testchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenAck("testport", "testchannel", "1.0", proof, 0, addr), // proof height is zero + } + + testCases := []struct { + msg MsgChannelOpenAck + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "empty counterparty version"}, + {testMsgs[8], false, "empty proof"}, + {testMsgs[9], false, "proof height is zero"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelOpenConfirm tests ValidateBasic for MsgChannelOpenConfirm +func TestMsgChannelOpenConfirm(t *testing.T) { + testMsgs := []MsgChannelOpenConfirm{ + NewMsgChannelOpenConfirm("testport", "testchannel", proof, 1, addr), // valid msg + NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id + NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id + NewMsgChannelOpenConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenConfirm("testport", invalidShortChannel, proof, 1, addr), // too short channel id + NewMsgChannelOpenConfirm("testport", invalidLongChannel, proof, 1, addr), // too long channel id + NewMsgChannelOpenConfirm("testport", invalidChannel, proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenConfirm("testport", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testport", "testchannel", proof, 0, addr), // proof height is zero + } + + testCases := []struct { + msg MsgChannelOpenConfirm + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "empty proof"}, + {testMsgs[8], false, "proof height is zero"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelCloseInit tests ValidateBasic for MsgChannelCloseInit +func TestMsgChannelCloseInit(t *testing.T) { + testMsgs := []MsgChannelCloseInit{ + NewMsgChannelCloseInit("testport", "testchannel", addr), // valid msg + NewMsgChannelCloseInit(invalidShortPort, "testchannel", addr), // too short port id + NewMsgChannelCloseInit(invalidLongPort, "testchannel", addr), // too long port id + NewMsgChannelCloseInit(invalidPort, "testchannel", addr), // port id contains non-alpha + NewMsgChannelCloseInit("testport", invalidShortChannel, addr), // too short channel id + NewMsgChannelCloseInit("testport", invalidLongChannel, addr), // too long channel id + NewMsgChannelCloseInit("testport", invalidChannel, addr), // channel id contains non-alpha + } + + testCases := []struct { + msg MsgChannelCloseInit + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgChannelCloseConfirm tests ValidateBasic for MsgChannelCloseConfirm +func TestMsgChannelCloseConfirm(t *testing.T) { + testMsgs := []MsgChannelCloseConfirm{ + NewMsgChannelCloseConfirm("testport", "testchannel", proof, 1, addr), // valid msg + NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id + NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id + NewMsgChannelCloseConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha + NewMsgChannelCloseConfirm("testport", invalidShortChannel, proof, 1, addr), // too short channel id + NewMsgChannelCloseConfirm("testport", invalidLongChannel, proof, 1, addr), // too long channel id + NewMsgChannelCloseConfirm("testport", invalidChannel, proof, 1, addr), // channel id contains non-alpha + NewMsgChannelCloseConfirm("testport", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testport", "testchannel", proof, 0, addr), // proof height is zero + } + + testCases := []struct { + msg MsgChannelCloseConfirm + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "empty proof"}, + {testMsgs[8], false, "proof height is zero"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.Nil(t, err, "Msg %d failed: %v", i, err) + } else { + require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index 5a7a9fb05bae..cdb48010237f 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -15,7 +15,7 @@ type Keeper struct { cdc *codec.Codec codespace sdk.CodespaceType prefix []byte // prefix bytes for accessing the store - ports map[sdk.CapabilityKey]string + ports map[string]string bound []string } @@ -27,7 +27,7 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/port", prefix: []byte{}, // prefix: []byte(types.SubModuleName + "/"), // "port/" - ports: make(map[sdk.CapabilityKey]string), // map of capabilities to port ids + ports: make(map[string]string), // map of capability key names to port ids } } @@ -39,7 +39,7 @@ func (k Keeper) GetPorts() []string { // GetPort retrieves a given port ID from keeper map func (k Keeper) GetPort(ck sdk.CapabilityKey) (string, bool) { - portID, found := k.ports[ck] + portID, found := k.ports[ck.Name()] return portID, found } @@ -59,7 +59,7 @@ func (k Keeper) BindPort(portID string) sdk.CapabilityKey { } key := sdk.NewKVStoreKey(portID) - k.ports[key] = portID + k.ports[key.Name()] = portID k.bound = append(k.bound, portID) return key } @@ -73,5 +73,5 @@ func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { panic(err.Error()) } - return k.ports[key] == portID + return k.ports[key.Name()] == portID } From 20950b7b4ca1bfe070d54d2ecdd7aa3d06b90f53 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 11 Nov 2019 11:57:27 +0100 Subject: [PATCH 041/176] IBC alpha general cleanup (#5291) * remove prefix from keeper; update client queries; address ICS02 comments from @cwgoes * add proof for root query * golangci * remove hardcoded bind port logic * space * WIP: register errors * register errors; make format * use new instead of register; unescape path * golangci --- client/context/query.go | 24 ++- x/ibc/02-client/client/cli/query.go | 60 +++++--- x/ibc/02-client/client/utils/utils.go | 24 ++- x/ibc/02-client/doc.go | 2 +- x/ibc/02-client/exported/exported.go | 11 +- x/ibc/02-client/keeper/client.go | 9 -- x/ibc/02-client/keeper/keeper.go | 23 ++- x/ibc/02-client/keeper/querier.go | 6 +- x/ibc/02-client/types/codec.go | 1 - x/ibc/02-client/types/errors/errors.go | 101 +++++++++---- x/ibc/02-client/types/keys.go | 5 + x/ibc/02-client/types/msgs.go | 18 +-- x/ibc/02-client/types/msgs_test.go | 7 +- x/ibc/02-client/types/querier.go | 53 ++++++- x/ibc/02-client/types/state.go | 9 +- .../types/tendermint/consensus_state.go | 13 +- .../types/tendermint/misbehaviour.go | 10 +- x/ibc/03-connection/alias.go | 3 - x/ibc/03-connection/client/cli/query.go | 8 - x/ibc/03-connection/client/cli/tx.go | 7 +- x/ibc/03-connection/keeper/handshake.go | 3 +- x/ibc/03-connection/keeper/handshake_test.go | 3 +- x/ibc/03-connection/keeper/keeper.go | 29 ++-- x/ibc/03-connection/keeper/keeper_test.go | 5 +- x/ibc/03-connection/keeper/querier.go | 4 +- x/ibc/03-connection/types/connection.go | 8 +- x/ibc/03-connection/types/errors.go | 94 +++++++----- x/ibc/03-connection/types/keys.go | 5 + x/ibc/03-connection/types/msgs.go | 45 +++--- x/ibc/03-connection/types/msgs_test.go | 3 +- x/ibc/03-connection/types/querier.go | 3 +- x/ibc/04-channel/alias.go | 2 - x/ibc/04-channel/client/cli/tx.go | 3 +- x/ibc/04-channel/exported/exported.go | 7 +- x/ibc/04-channel/keeper/handshake_test.go | 3 +- x/ibc/04-channel/keeper/keeper.go | 42 +++--- x/ibc/04-channel/keeper/keeper_test.go | 5 +- x/ibc/04-channel/keeper/querier.go | 2 +- x/ibc/04-channel/types/channel.go | 13 +- x/ibc/04-channel/types/errors.go | 97 +++++++----- x/ibc/04-channel/types/keys.go | 5 + x/ibc/04-channel/types/msgs.go | 70 ++++----- x/ibc/04-channel/types/msgs_test.go | 139 +++++++++--------- x/ibc/04-channel/types/packet.go | 19 ++- x/ibc/05-port/alias.go | 28 ++-- x/ibc/05-port/keeper/keeper.go | 33 ++--- x/ibc/05-port/types/errors.go | 39 +++-- x/ibc/20-transfer/alias.go | 39 ++--- x/ibc/20-transfer/client/cli/query.go | 3 +- x/ibc/20-transfer/keeper/callbacks.go | 35 +++-- x/ibc/20-transfer/keeper/keeper.go | 28 ++-- x/ibc/20-transfer/keeper/relay.go | 10 +- x/ibc/20-transfer/types/errors.go | 51 ------- x/ibc/20-transfer/types/keys.go | 4 +- x/ibc/20-transfer/types/msgs.go | 29 ++-- x/ibc/23-commitment/merkle.go | 9 +- x/ibc/24-host/errors.go | 49 ++++-- x/ibc/24-host/validate.go | 10 +- x/ibc/keeper/keeper.go | 9 +- x/ibc/keeper/querier_test.go | 2 +- x/ibc/types/errors.go | 33 +++++ x/ibc/types/types.go | 7 - x/ibc/version/version.go | 13 -- 63 files changed, 782 insertions(+), 652 deletions(-) delete mode 100644 x/ibc/20-transfer/types/errors.go create mode 100644 x/ibc/types/errors.go delete mode 100644 x/ibc/version/version.go diff --git a/client/context/query.go b/client/context/query.go index 2a01a7577a0c..be664f1c8420 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -129,11 +129,10 @@ func (ctx CLIContext) GetFromName() string { return ctx.FromName } -func (ctx CLIContext) queryABCI(req abci.RequestQuery) (resp abci.ResponseQuery, err error) { - +func (ctx CLIContext) queryABCI(req abci.RequestQuery) (abci.ResponseQuery, error) { node, err := ctx.GetNode() if err != nil { - return resp, err + return abci.ResponseQuery{}, err } // When a client did not provide a query height, manually query for it so it can @@ -141,7 +140,7 @@ func (ctx CLIContext) queryABCI(req abci.RequestQuery) (resp abci.ResponseQuery, if ctx.Height == 0 { status, err := node.Status() if err != nil { - return resp, err + return abci.ResponseQuery{}, err } ctx = ctx.WithHeight(status.SyncInfo.LatestBlockHeight) } @@ -153,26 +152,25 @@ func (ctx CLIContext) queryABCI(req abci.RequestQuery) (resp abci.ResponseQuery, result, err := node.ABCIQueryWithOptions(req.Path, req.Data, opts) if err != nil { - return + return abci.ResponseQuery{}, err } - resp = result.Response - if !resp.IsOK() { - err = errors.New(resp.Log) - return + if !result.Response.IsOK() { + err = errors.New(result.Response.Log) + return abci.ResponseQuery{}, err } // data from trusted node or subspace query doesn't need verification if ctx.TrustNode || !isQueryStoreWithProof(req.Path) { - return resp, nil + return result.Response, nil } - err = ctx.verifyProof(req.Path, resp) + err = ctx.verifyProof(req.Path, result.Response) if err != nil { - return + return abci.ResponseQuery{}, err } - return + return result.Response, nil } // query performs a query to a Tendermint node with the provided store name diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index 6f6a487bbbf6..cc5cb3364c89 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -7,15 +7,17 @@ import ( "strings" "github.com/spf13/cobra" + "github.com/spf13/viper" + abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -44,7 +46,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { // GetCmdQueryClientState defines the command to query the state of a client with // a given id as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query func GetCmdQueryClientState(queryRoute string, cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Use: "state [client-id]", Short: "Query a client state", Long: strings.TrimSpace( @@ -67,24 +69,33 @@ $ %s query ibc client state [client-id] return err } - res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), bz) + req := abci.RequestQuery{ + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), + } + + res, err := cliCtx.QueryABCI(req) if err != nil { return err } var clientState types.State - if err := cdc.UnmarshalJSON(res, &clientState); err != nil { + if err := cdc.UnmarshalJSON(res.Value, &clientState); err != nil { return err } - return cliCtx.PrintOutput(clientState) + clientStateRes := types.NewClientStateResponse(clientID, clientState, res.Proof, res.Height) + return cliCtx.PrintOutput(clientStateRes) }, } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd } -// GetCmdQueryRoot defines the command to query +// GetCmdQueryRoot defines the command to query a verified commitment root func GetCmdQueryRoot(queryRoute string, cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Use: "root [client-id] [height]", Short: "Query a verified commitment root", Long: strings.TrimSpace( @@ -112,25 +123,34 @@ $ %s query ibc client root [client-id] [height] return err } - res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryVerifiedRoot), bz) + req := abci.RequestQuery{ + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryVerifiedRoot), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), + } + + res, err := cliCtx.QueryABCI(req) if err != nil { return err } - var root commitment.RootI - if err := cdc.UnmarshalJSON(res, &root); err != nil { + var root commitment.Root + if err := cdc.UnmarshalJSON(res.Value, &root); err != nil { return err } - return cliCtx.PrintOutput(root) + rootRes := types.NewRootResponse(clientID, height, root, res.Proof, res.Height) + return cliCtx.PrintOutput(rootRes) }, } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd } // GetCmdQueryConsensusState defines the command to query the consensus state of // the chain as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Use: "consensus-state [client-id]", Short: "Query the latest consensus state of the client", Long: strings.TrimSpace( @@ -148,24 +168,16 @@ $ %s query ibc client consensus-state [client-id] return errors.New("client ID can't be blank") } - bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) + csRes, err := utils.QueryConsensusStateProof(cliCtx, cdc, queryRoute, clientID) if err != nil { return err } - res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryConsensusState), bz) - if err != nil { - return err - } - - var consensusState exported.ConsensusState - if err := cdc.UnmarshalJSON(res, &consensusState); err != nil { - return err - } - - return cliCtx.PrintOutput(consensusState) + return cliCtx.PrintOutput(csRes) }, } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd } // GetCmdQueryHeader defines the command to query the latest header on the chain diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 5d0786267373..955e06f50e7c 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -3,23 +3,36 @@ package utils import ( "fmt" + "github.com/spf13/viper" + abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" ) // QueryConsensusStateProof queries the store to get the consensus state and a // merkle proof. -func QueryConsensusStateProof(cliCtx client.CLIContext, clientID string) (types.ConsensusStateResponse, error) { +func QueryConsensusStateProof( + cliCtx client.CLIContext, cdc *codec.Codec, + queryRoute, clientID string, +) (types.ConsensusStateResponse, error) { var conStateRes types.ConsensusStateResponse + + bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) + if err != nil { + return conStateRes, err + } + req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: []byte(fmt.Sprintf("clients/%s/consensusState", clientID)), - Prove: true, + Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), + Data: bz, + Prove: viper.GetBool(flags.FlagProve), } res, err := cliCtx.QueryABCI(req) @@ -28,9 +41,10 @@ func QueryConsensusStateProof(cliCtx client.CLIContext, clientID string) (types. } var cs tendermint.ConsensusState - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &cs); err != nil { return conStateRes, err } + return types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height), nil } diff --git a/x/ibc/02-client/doc.go b/x/ibc/02-client/doc.go index 2b6952ba97eb..cfe3c76c6af7 100644 --- a/x/ibc/02-client/doc.go +++ b/x/ibc/02-client/doc.go @@ -1,5 +1,5 @@ /* -Package client implements the ICS 02 - Client Semenatics specification +Package client implements the ICS 02 - Client Semantics specification https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics. This concrete implementations defines types and method to store and update light clients which tracks on other chain's state. diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index e7d1ac5c5411..e611b94301fa 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -6,17 +6,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" cmn "github.com/tendermint/tendermint/libs/common" -) -// Blockchain is consensus algorithm which generates valid Headers. It generates -// a unique list of headers starting from a genesis ConsensusState with arbitrary messages. -// This interface is implemented as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#blockchain. -type Blockchain interface { - Genesis() ConsensusState // Consensus state defined in the genesis - Consensus() Header // Header generating function -} + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) // ConsensusState is the state of the consensus process type ConsensusState interface { diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index b75f8174939a..3ee7a53143bf 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -60,15 +60,6 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H return sdkerrors.Wrap(errors.ErrConsensusStateNotFound(k.codespace), "cannot update client") } - if header.GetHeight() < consensusState.GetHeight() { - return sdkerrors.Wrap( - sdk.ErrInvalidSequence( - fmt.Sprintf("header height < consensus height (%d < %d)", header.GetHeight(), consensusState.GetHeight()), - ), - "cannot update client", - ) - } - consensusState, err := consensusState.CheckValidityAndUpdateState(header) if err != nil { return sdkerrors.Wrap(err, "cannot update client") diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index ce0d54e99782..3911c1f98f0e 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -23,7 +23,6 @@ type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store } // NewKeeper creates a new NewKeeper instance @@ -32,8 +31,6 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) storeKey: key, cdc: cdc, codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, errors.DefaultCodespace)), // "ibc/client", - prefix: []byte{}, - // prefix: []byte(types.SubModuleName + "/"), // "client/" } } @@ -44,7 +41,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetClientState gets a particular client from the store func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := store.Get(types.KeyClientState(clientID)) if bz == nil { return types.State{}, false @@ -57,14 +54,14 @@ func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, b // SetClientState sets a particular Client to the store func (k Keeper) SetClientState(ctx sdk.Context, clientState types.State) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := k.cdc.MustMarshalBinaryLengthPrefixed(clientState) - store.Set(types.KeyClientState(clientState.ID()), bz) + store.Set(types.KeyClientState(clientState.ID), bz) } // GetClientType gets the consensus type for a specific client func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.ClientType, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := store.Get(types.KeyClientType(clientID)) if bz == nil { return 0, false @@ -75,13 +72,13 @@ func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.Client // SetClientType sets the specific client consensus type to the provable store func (k Keeper) SetClientType(ctx sdk.Context, clientID string, clientType exported.ClientType) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) store.Set(types.KeyClientType(clientID), []byte{byte(clientType)}) } // GetConsensusState creates a new client state and populates it with a given consensus state func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.ConsensusState, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := store.Get(types.KeyConsensusState(clientID)) if bz == nil { return nil, false @@ -94,7 +91,7 @@ func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.Co // SetConsensusState sets a ConsensusState to a particular client func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) store.Set(types.KeyConsensusState(clientID), bz) } @@ -102,7 +99,7 @@ func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusSta // GetVerifiedRoot gets a verified commitment Root from a particular height to // a client func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) (commitment.RootI, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := store.Get(types.KeyRoot(clientID, height)) if bz == nil { @@ -117,7 +114,7 @@ func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) // SetVerifiedRoot sets a verified commitment Root from a particular height to // a client func (k Keeper) SetVerifiedRoot(ctx sdk.Context, clientID string, height uint64, root commitment.RootI) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) bz := k.cdc.MustMarshalBinaryLengthPrefixed(root) store.Set(types.KeyRoot(clientID, height), bz) } @@ -151,7 +148,7 @@ func (k Keeper) checkMisbehaviour(ctx sdk.Context, evidence exported.Evidence) e // freeze updates the state of the client in the event of a misbehaviour func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) { if clientState.Frozen { - return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientState.ID()), "already frozen") + return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientState.ID), "already frozen") } clientState.Frozen = true diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go index 5f56b8d6b01a..8956a72fab2e 100644 --- a/x/ibc/02-client/keeper/querier.go +++ b/x/ibc/02-client/keeper/querier.go @@ -21,7 +21,7 @@ func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt clientState, found := k.GetClientState(ctx, params.ClientID) if !found { - return nil, errors.ErrClientTypeNotFound(k.codespace) + return nil, sdk.ConvertError(errors.ErrClientTypeNotFound(k.codespace)) } bz, err := types.SubModuleCdc.MarshalJSON(clientState) @@ -43,7 +43,7 @@ func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([] consensusState, found := k.GetConsensusState(ctx, params.ClientID) if !found { - return nil, errors.ErrConsensusStateNotFound(k.codespace) + return nil, sdk.ConvertError(errors.ErrConsensusStateNotFound(k.codespace)) } bz, err := types.SubModuleCdc.MarshalJSON(consensusState) @@ -65,7 +65,7 @@ func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]by root, found := k.GetVerifiedRoot(ctx, params.ClientID, params.Height) if !found { - return nil, errors.ErrRootNotFound(k.codespace) + return nil, sdk.ConvertError(errors.ErrRootNotFound(k.codespace)) } bz, err := types.SubModuleCdc.MarshalJSON(root) diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index 7a141e811a0a..551403e6ad89 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -11,7 +11,6 @@ var SubModuleCdc = codec.New() // RegisterCodec registers the IBC client interfaces and types func RegisterCodec(cdc *codec.Codec) { - cdc.RegisterInterface((*exported.Blockchain)(nil), nil) cdc.RegisterInterface((*exported.ConsensusState)(nil), nil) cdc.RegisterInterface((*exported.Evidence)(nil), nil) cdc.RegisterInterface((*exported.Header)(nil), nil) diff --git a/x/ibc/02-client/types/errors/errors.go b/x/ibc/02-client/types/errors/errors.go index c133bcfef808..1e9510df6c44 100644 --- a/x/ibc/02-client/types/errors/errors.go +++ b/x/ibc/02-client/types/errors/errors.go @@ -4,70 +4,111 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // client error codes const ( DefaultCodespace sdk.CodespaceType = "client" - CodeClientExists sdk.CodeType = 101 - CodeClientNotFound sdk.CodeType = 102 - CodeClientFrozen sdk.CodeType = 103 - CodeConsensusStateNotFound sdk.CodeType = 104 - CodeInvalidConsensusState sdk.CodeType = 105 - CodeClientTypeNotFound sdk.CodeType = 106 - CodeInvalidClientType sdk.CodeType = 107 - CodeRootNotFound sdk.CodeType = 108 - CodeInvalidHeader sdk.CodeType = 109 - CodeInvalidEvidence sdk.CodeType = 110 + CodeClientExists sdk.CodeType = 200 + CodeClientNotFound sdk.CodeType = 201 + CodeClientFrozen sdk.CodeType = 202 + CodeConsensusStateNotFound sdk.CodeType = 203 + CodeInvalidConsensusState sdk.CodeType = 204 + CodeClientTypeNotFound sdk.CodeType = 205 + CodeInvalidClientType sdk.CodeType = 206 + CodeRootNotFound sdk.CodeType = 207 + CodeInvalidHeader sdk.CodeType = 207 + CodeInvalidEvidence sdk.CodeType = 209 ) // ErrClientExists implements sdk.Error -func ErrClientExists(codespace sdk.CodespaceType, clientID string) sdk.Error { - return sdk.NewError(codespace, CodeClientExists, fmt.Sprintf("client with ID %s already exists", clientID)) +func ErrClientExists(codespace sdk.CodespaceType, clientID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientExists), + fmt.Sprintf("client with ID %s already exists", clientID), + ) } // ErrClientNotFound implements sdk.Error -func ErrClientNotFound(codespace sdk.CodespaceType, clientID string) sdk.Error { - return sdk.NewError(codespace, CodeClientNotFound, fmt.Sprintf("client with ID %s not found", clientID)) +func ErrClientNotFound(codespace sdk.CodespaceType, clientID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientNotFound), + fmt.Sprintf("client with ID %s not found", clientID), + ) } // ErrClientFrozen implements sdk.Error -func ErrClientFrozen(codespace sdk.CodespaceType, clientID string) sdk.Error { - return sdk.NewError(codespace, CodeClientFrozen, fmt.Sprintf("client with ID %s is frozen due to misbehaviour", clientID)) +func ErrClientFrozen(codespace sdk.CodespaceType, clientID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientFrozen), + fmt.Sprintf("client with ID %s is frozen due to misbehaviour", clientID), + ) } // ErrConsensusStateNotFound implements sdk.Error -func ErrConsensusStateNotFound(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeConsensusStateNotFound, "consensus state not found") +func ErrConsensusStateNotFound(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeConsensusStateNotFound), + "consensus state not found", + ) } // ErrInvalidConsensus implements sdk.Error -func ErrInvalidConsensus(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidConsensusState, "invalid consensus state") +func ErrInvalidConsensus(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidConsensusState), + "invalid consensus state", + ) } // ErrClientTypeNotFound implements sdk.Error -func ErrClientTypeNotFound(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeClientTypeNotFound, "client type not found") +func ErrClientTypeNotFound(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientTypeNotFound), + "client type not found", + ) } // ErrInvalidClientType implements sdk.Error -func ErrInvalidClientType(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidClientType, msg) +func ErrInvalidClientType(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidClientType), + msg, + ) } // ErrRootNotFound implements sdk.Error -func ErrRootNotFound(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeRootNotFound, "commitment root not found") +func ErrRootNotFound(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeRootNotFound), + "commitment root not found", + ) } // ErrInvalidHeader implements sdk.Error -func ErrInvalidHeader(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidHeader, "invalid header") +func ErrInvalidHeader(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidHeader), + "invalid header", + ) } // ErrInvalidEvidence implements sdk.Error -func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidEvidence, "invalid evidence: %s", msg) +func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidEvidence), + fmt.Sprintf("invalid evidence: %s", msg), + ) } diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go index 8d97ca893324..eba16d0c169c 100644 --- a/x/ibc/02-client/types/keys.go +++ b/x/ibc/02-client/types/keys.go @@ -18,6 +18,11 @@ const ( QuerierRoute = SubModuleName ) +// KVStore key prefixes +var ( + KeyPrefixClient = []byte{0x00} +) + // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space // ClientStatePath takes an Identifier and returns a Path under which to store a diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index 612f7e543e53..f09e126666ff 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -1,8 +1,6 @@ package types import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" @@ -43,13 +41,13 @@ func (msg MsgCreateClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgCreateClient) ValidateBasic() sdk.Error { if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(err) } if _, err := exported.ClientTypeFromString(msg.ClientType); err != nil { - return errors.ErrInvalidClientType(errors.DefaultCodespace, err.Error()) + return sdk.ConvertError(errors.ErrInvalidClientType(errors.DefaultCodespace, err.Error())) } if msg.ConsensusState == nil { - return errors.ErrInvalidConsensus(errors.DefaultCodespace) + return sdk.ConvertError(errors.ErrInvalidConsensus(errors.DefaultCodespace)) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("empty address") @@ -98,10 +96,10 @@ func (msg MsgUpdateClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgUpdateClient) ValidateBasic() sdk.Error { if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(err) } if msg.Header == nil { - return errors.ErrInvalidHeader(errors.DefaultCodespace) + return sdk.ConvertError(errors.ErrInvalidHeader(errors.DefaultCodespace)) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("empty address") @@ -148,13 +146,13 @@ func (msg MsgSubmitMisbehaviour) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgSubmitMisbehaviour) ValidateBasic() sdk.Error { if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(err) } if msg.Evidence == nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "evidence is nil") + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "evidence is nil")) } if err := msg.Evidence.ValidateBasic(); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error()) + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error())) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("empty address") diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go index cd416fabdfe8..f7e022ecc89c 100644 --- a/x/ibc/02-client/types/msgs_test.go +++ b/x/ibc/02-client/types/msgs_test.go @@ -5,12 +5,13 @@ import ( "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/secp256k1" + cmn "github.com/tendermint/tendermint/libs/common" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" - "github.com/tendermint/tendermint/crypto/secp256k1" - cmn "github.com/tendermint/tendermint/libs/common" ) func TestMsgCreateClientValidateBasic(t *testing.T) { @@ -103,7 +104,7 @@ type mockBadEvidence struct { // Override ValidateBasic func (mbe mockBadEvidence) ValidateBasic() sdk.Error { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence") + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence")) } func TestMsgSubmitMisbehaviour(t *testing.T) { diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go index 7638c0200882..0bf71ebaa6ae 100644 --- a/x/ibc/02-client/types/querier.go +++ b/x/ibc/02-client/types/querier.go @@ -3,9 +3,10 @@ package types import ( "strings" + "github.com/tendermint/tendermint/crypto/merkle" + tmtypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - "github.com/tendermint/tendermint/crypto/merkle" ) // query routes supported by the IBC client Querier @@ -44,13 +45,34 @@ func NewQueryCommitmentRootParams(id string, height uint64) QueryCommitmentRootP } } +// StateResponse defines the client response for a client state query. +// It includes the commitment proof and the height of the proof. +type StateResponse struct { + ClientState State `json:"client_state" yaml:"client_state"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewClientStateResponse creates a new StateResponse instance. +func NewClientStateResponse( + clientID string, clientState State, proof *merkle.Proof, height int64, +) StateResponse { + return StateResponse{ + ClientState: clientState, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(ConsensusStatePath(clientID), "/")), + ProofHeight: uint64(height), + } +} + // ConsensusStateResponse defines the client response for a Consensus state query. // It includes the commitment proof and the height of the proof. type ConsensusStateResponse struct { - ConsensusState tmtypes.ConsensusState - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + ConsensusState tmtypes.ConsensusState `json:"consensus_state" yaml:"consensus_state"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewConsensusStateResponse creates a new ConsensusStateResponse instance. @@ -64,3 +86,24 @@ func NewConsensusStateResponse( ProofHeight: uint64(height), } } + +// RootResponse defines the client response for a commitment root query. +// It includes the commitment proof and the height of the proof. +type RootResponse struct { + Root commitment.Root `json:"root" yaml:"root"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewRootResponse creates a new RootResponse instance. +func NewRootResponse( + clientID string, height uint64, root commitment.Root, proof *merkle.Proof, proofHeight int64, +) RootResponse { + return RootResponse{ + Root: root, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(RootPath(clientID, height), "/")), + ProofHeight: uint64(proofHeight), + } +} diff --git a/x/ibc/02-client/types/state.go b/x/ibc/02-client/types/state.go index 8c60260df0a2..6ae3d0552693 100644 --- a/x/ibc/02-client/types/state.go +++ b/x/ibc/02-client/types/state.go @@ -4,7 +4,7 @@ package types // Any actor holding the Stage can access on and modify that client information. type State struct { // Client ID - id string + ID string `json:"id" yaml:"id"` // Boolean that states if the client is frozen when a misbehaviour proof is // submitted in the event of an equivocation. Frozen bool `json:"frozen" yaml:"frozen"` @@ -13,12 +13,7 @@ type State struct { // NewClientState creates a new ClientState instance func NewClientState(id string) State { return State{ - id: id, + ID: id, Frozen: false, } } - -// ID returns the client identifier -func (s State) ID() string { - return s.id -} diff --git a/x/ibc/02-client/types/tendermint/consensus_state.go b/x/ibc/02-client/types/tendermint/consensus_state.go index 3ad0892a9ea8..f57887045a2f 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state.go +++ b/x/ibc/02-client/types/tendermint/consensus_state.go @@ -2,12 +2,14 @@ package tendermint import ( "bytes" - "errors" + "fmt" lerr "github.com/tendermint/tendermint/lite/errors" tmtypes "github.com/tendermint/tendermint/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienterrors "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -41,7 +43,7 @@ func (cs ConsensusState) GetRoot() commitment.RootI { func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (exported.ConsensusState, error) { tmHeader, ok := header.(Header) if !ok { - return nil, errors.New("header not a valid tendermint header") + return nil, clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace) } if err := cs.checkValidity(tmHeader); err != nil { @@ -55,6 +57,13 @@ func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (ex // // CONTRACT: assumes header.Height > consensusState.Height func (cs ConsensusState) checkValidity(header Header) error { + if header.GetHeight() < cs.Height { + return sdkerrors.Wrap( + clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), + fmt.Sprintf("header height < consensus height (%d < %d)", header.GetHeight(), cs.Height), + ) + } + // check if the hash from the consensus set and header // matches nextHash := cs.NextValidatorSet.Hash() diff --git a/x/ibc/02-client/types/tendermint/misbehaviour.go b/x/ibc/02-client/types/tendermint/misbehaviour.go index 512bb0f72161..1edde8ec1c04 100644 --- a/x/ibc/02-client/types/tendermint/misbehaviour.go +++ b/x/ibc/02-client/types/tendermint/misbehaviour.go @@ -52,20 +52,20 @@ func (ev Evidence) Hash() cmn.HexBytes { // ValidateBasic implements exported.Evidence interface func (ev Evidence) ValidateBasic() sdk.Error { if ev.DuplicateVoteEvidence == nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "duplicate evidence is nil") + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "duplicate evidence is nil")) } err := ev.DuplicateVoteEvidence.ValidateBasic() if err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error()) + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error())) } if ev.ChainID == "" { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "chainID is empty") + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "chainID is empty")) } if ev.ValidatorPower <= 0 { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Validator Power: %d", ev.ValidatorPower)) + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Validator Power: %d", ev.ValidatorPower))) } if ev.TotalPower < ev.ValidatorPower { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Total Power: %d", ev.TotalPower)) + return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Total Power: %d", ev.TotalPower))) } return nil } diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index 27757d8163e5..b73456d28dc8 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -29,7 +29,6 @@ const ( CodeInvalidVersion = types.CodeInvalidVersion CodeInvalidHeight = types.CodeInvalidHeight CodeInvalidConnectionState = types.CodeInvalidConnectionState - CodeInvalidProof = types.CodeInvalidProof CodeInvalidCounterparty = types.CodeInvalidCounterparty AttributeKeyConnectionID = types.AttributeKeyConnectionID AttributeKeyCounterpartyClientID = types.AttributeKeyCounterpartyClientID @@ -55,10 +54,8 @@ var ( ErrClientConnectionPathsNotFound = types.ErrClientConnectionPathsNotFound ErrConnectionPath = types.ErrConnectionPath ErrInvalidCounterpartyConnection = types.ErrInvalidCounterpartyConnection - ErrInvalidVersion = types.ErrInvalidVersion ErrInvalidHeight = types.ErrInvalidHeight ErrInvalidConnectionState = types.ErrInvalidConnectionState - ErrInvalidConnectionProof = types.ErrInvalidConnectionProof ErrInvalidCounterparty = types.ErrInvalidCounterparty ConnectionPath = types.ConnectionPath ClientConnectionsPath = types.ClientConnectionsPath diff --git a/x/ibc/03-connection/client/cli/query.go b/x/ibc/03-connection/client/cli/query.go index 266ac4bf02d3..f4502807f859 100644 --- a/x/ibc/03-connection/client/cli/query.go +++ b/x/ibc/03-connection/client/cli/query.go @@ -69,10 +69,6 @@ $ %s query ibc connection end [connection-id] return err } - if res.Proof == nil { - return cliCtx.PrintOutput(connection) - } - connRes := types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height) return cliCtx.PrintOutput(connRes) }, @@ -119,10 +115,6 @@ $ %s query ibc connection client [client-id] return err } - if res.Proof == nil { - return cliCtx.PrintOutput(connectionPaths) - } - connPathsRes := types.NewClientConnectionsResponse(clientID, connectionPaths, res.Proof, res.Height) return cliCtx.PrintOutput(connPathsRes) }, diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index cef560ccdd57..b3115069adbc 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -12,6 +12,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" @@ -25,7 +27,6 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - abci "github.com/tendermint/tendermint/abci/types" ) // Connection Handshake flags @@ -413,7 +414,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1) + csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), cdc, clienttypes.QuerierRoute, clientID1) if err != nil { return err } @@ -467,7 +468,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2) + csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), cdc, clienttypes.QuerierRoute, clientID2) if err != nil { return err } diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index 21a005b12c9f..f9288f7d9ae2 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -8,6 +8,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // ConnOpenInit initialises a connection attempt on chain A. @@ -157,7 +158,7 @@ func (k Keeper) ConnOpenAck( } if types.LatestVersion(connection.Versions) != version { - return types.ErrInvalidVersion( + return ibctypes.ErrInvalidVersion( k.codespace, fmt.Sprintf("connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version), ) diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index b8884c56b3ee..e0c0cce29c11 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -3,11 +3,12 @@ package keeper_test import ( "fmt" + abci "github.com/tendermint/tendermint/abci/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - abci "github.com/tendermint/tendermint/abci/types" ) func (suite *KeeperTestSuite) TestConnOpenInit() { diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index 1488c6c03ec7..337e6dd66a88 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -16,22 +16,18 @@ import ( // Keeper defines the IBC connection keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store - + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType clientKeeper types.ClientKeeper } // NewKeeper creates a new IBC connection Keeper instance func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, ck types.ClientKeeper) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/connection", - prefix: []byte{}, - // prefix: []byte(types.SubModuleName + "/"), // "connection/" + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/connection", clientKeeper: ck, } } @@ -49,7 +45,7 @@ func (k Keeper) GetCommitmentPrefix() commitment.PrefixI { // GetConnection returns a connection with a particular identifier func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) bz := store.Get(types.KeyConnection(connectionID)) if bz == nil { return types.ConnectionEnd{}, false @@ -62,7 +58,7 @@ func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.Conne // SetConnection sets a connection to the store func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) bz := k.cdc.MustMarshalBinaryLengthPrefixed(connection) store.Set(types.KeyConnection(connectionID), bz) } @@ -70,7 +66,7 @@ func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection t // GetClientConnectionPaths returns all the connection paths stored under a // particular client func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) bz := store.Get(types.KeyClientConnections(clientID)) if bz == nil { return nil, false @@ -83,7 +79,7 @@ func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]st // SetClientConnectionPaths sets the connections paths for client func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths []string) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) bz := k.cdc.MustMarshalBinaryLengthPrefixed(paths) store.Set(types.KeyClientConnections(clientID), bz) } @@ -92,7 +88,7 @@ func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths // connections associated with a client. // // CONTRACT: client must already exist -func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID string) sdk.Error { +func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID string) error { conns, found := k.GetClientConnectionPaths(ctx, clientID) if !found { conns = []string{} @@ -107,7 +103,8 @@ func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID st // set of connections associated with a client. // // CONTRACT: client must already exist -func (k Keeper) removeConnectionFromClient(ctx sdk.Context, clientID, connectionID string) sdk.Error { +// nolint: unused +func (k Keeper) removeConnectionFromClient(ctx sdk.Context, clientID, connectionID string) error { conns, found := k.GetClientConnectionPaths(ctx, clientID) if !found { return types.ErrClientConnectionPathsNotFound(k.codespace, clientID) diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 9c086f647d06..bf6dfe0d7839 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -3,14 +3,15 @@ package keeper_test import ( "testing" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" - "github.com/stretchr/testify/suite" - abci "github.com/tendermint/tendermint/abci/types" ) const ( diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go index 85bb02559e78..8802ec7443fe 100644 --- a/x/ibc/03-connection/keeper/querier.go +++ b/x/ibc/03-connection/keeper/querier.go @@ -20,7 +20,7 @@ func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte connection, found := k.GetConnection(ctx, params.ConnectionID) if !found { - return nil, types.ErrConnectionNotFound(k.codespace, params.ConnectionID) + return nil, sdk.ConvertError(types.ErrConnectionNotFound(k.codespace, params.ConnectionID)) } bz, err := types.SubModuleCdc.MarshalJSON(connection) @@ -42,7 +42,7 @@ func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) clientConnectionPaths, found := k.GetClientConnectionPaths(ctx, params.ClientID) if !found { - return nil, types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID) + return nil, sdk.ConvertError(types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID)) } bz, err := types.SubModuleCdc.MarshalJSON(clientConnectionPaths) diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 07eb0a25c6ac..23ec6ca5709b 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -55,12 +55,12 @@ func NewCounterparty(clientID, connectionID string, prefix commitment.PrefixI) C } // ValidateBasic performs a basic validation check of the identifiers and prefix -func (c Counterparty) ValidateBasic() sdk.Error { +func (c Counterparty) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(c.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty connection ID: %s", err.Error())) + return sdkerrors.Wrap(err, "invalid counterparty connection ID") } if err := host.DefaultClientIdentifierValidator(c.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty client ID: %s", err.Error())) + return sdkerrors.Wrap(err, "invalid counterparty client ID") } if c.Prefix == nil || len(c.Prefix.Bytes()) == 0 { return ErrInvalidCounterparty(DefaultCodespace, "invalid counterparty prefix") diff --git a/x/ibc/03-connection/types/errors.go b/x/ibc/03-connection/types/errors.go index b2a2cbe2ad5f..d62e14a49218 100644 --- a/x/ibc/03-connection/types/errors.go +++ b/x/ibc/03-connection/types/errors.go @@ -4,70 +4,92 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // connection error codes const ( DefaultCodespace sdk.CodespaceType = SubModuleName - CodeConnectionExists sdk.CodeType = 101 - CodeConnectionNotFound sdk.CodeType = 102 - CodeClientConnectionPathsNotFound sdk.CodeType = 103 - CodeConnectionPath sdk.CodeType = 104 - CodeInvalidCounterpartyConnection sdk.CodeType = 105 - CodeInvalidVersion sdk.CodeType = 106 - CodeInvalidHeight sdk.CodeType = 107 - CodeInvalidConnectionState sdk.CodeType = 108 - CodeInvalidProof sdk.CodeType = 109 - CodeInvalidCounterparty sdk.CodeType = 110 + CodeConnectionExists sdk.CodeType = 210 + CodeConnectionNotFound sdk.CodeType = 211 + CodeClientConnectionPathsNotFound sdk.CodeType = 212 + CodeConnectionPath sdk.CodeType = 213 + CodeInvalidCounterpartyConnection sdk.CodeType = 214 + CodeInvalidVersion sdk.CodeType = 215 + CodeInvalidHeight sdk.CodeType = 216 + CodeInvalidConnectionState sdk.CodeType = 217 + CodeInvalidCounterparty sdk.CodeType = 218 ) // ErrConnectionExists implements sdk.Error -func ErrConnectionExists(codespace sdk.CodespaceType, connectionID string) sdk.Error { - return sdk.NewError(codespace, CodeConnectionExists, fmt.Sprintf("connection with ID %s already exists", connectionID)) +func ErrConnectionExists(codespace sdk.CodespaceType, connectionID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeConnectionExists), + fmt.Sprintf("connection with ID %s already exists", connectionID), + ) } // ErrConnectionNotFound implements sdk.Error -func ErrConnectionNotFound(codespace sdk.CodespaceType, connectionID string) sdk.Error { - return sdk.NewError(codespace, CodeConnectionNotFound, fmt.Sprintf("connection with ID %s not found", connectionID)) +func ErrConnectionNotFound(codespace sdk.CodespaceType, connectionID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeConnectionNotFound), + fmt.Sprintf("connection with ID %s not found", connectionID), + ) } // ErrClientConnectionPathsNotFound implements sdk.Error -func ErrClientConnectionPathsNotFound(codespace sdk.CodespaceType, clientID string) sdk.Error { - return sdk.NewError(codespace, CodeClientConnectionPathsNotFound, fmt.Sprintf("client connection paths not found for ID %s", clientID)) +func ErrClientConnectionPathsNotFound(codespace sdk.CodespaceType, clientID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeClientConnectionPathsNotFound), + fmt.Sprintf("client connection paths not found for ID %s", clientID), + ) } // ErrConnectionPath implements sdk.Error -func ErrConnectionPath(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeConnectionPath, "connection path is not associated to the client") +func ErrConnectionPath(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeConnectionPath), + "connection path is not associated to the client", + ) } // ErrInvalidCounterpartyConnection implements sdk.Error -func ErrInvalidCounterpartyConnection(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidCounterpartyConnection, "couldn't verify connection membership on counterparty's client") -} - -// ErrInvalidVersion implements sdk.Error -func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidVersion, msg) +func ErrInvalidCounterpartyConnection(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidCounterpartyConnection), + "couldn't verify connection membership on counterparty's client", + ) } // ErrInvalidHeight implements sdk.Error -func ErrInvalidHeight(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidHeight, msg) +func ErrInvalidHeight(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidHeight), + msg, + ) } // ErrInvalidConnectionState implements sdk.Error -func ErrInvalidConnectionState(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidConnectionState, msg) -} - -// ErrInvalidConnectionProof implements sdk.Error -func ErrInvalidConnectionProof(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidProof, msg) +func ErrInvalidConnectionState(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidConnectionState), + msg, + ) } // ErrInvalidCounterparty implements sdk.Error -func ErrInvalidCounterparty(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidCounterparty, msg) +func ErrInvalidCounterparty(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidCounterparty), + msg, + ) } diff --git a/x/ibc/03-connection/types/keys.go b/x/ibc/03-connection/types/keys.go index 7dd82ae80a2e..40eda70e340f 100644 --- a/x/ibc/03-connection/types/keys.go +++ b/x/ibc/03-connection/types/keys.go @@ -18,6 +18,11 @@ const ( QuerierRoute = SubModuleName ) +// KVStore key prefixes +var ( + KeyPrefixConnection = []byte{0x00} +) + // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths // ConnectionPath defines the path under which connection paths are stored diff --git a/x/ibc/03-connection/types/msgs.go b/x/ibc/03-connection/types/msgs.go index 10ede21b1124..e302badac9c4 100644 --- a/x/ibc/03-connection/types/msgs.go +++ b/x/ibc/03-connection/types/msgs.go @@ -1,10 +1,10 @@ package types import ( - "fmt" "strings" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -49,15 +49,15 @@ func (msg MsgConnectionOpenInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenInit) ValidateBasic() sdk.Error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) } if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid client ID")) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("missing signer address") } - return msg.Counterparty.ValidateBasic() + return sdk.ConvertError(msg.Counterparty.ValidateBasic()) } // GetSignBytes implements sdk.Msg @@ -120,35 +120,35 @@ func (msg MsgConnectionOpenTry) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenTry) ValidateBasic() sdk.Error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) } if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid client ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid client ID")) } if len(msg.CounterpartyVersions) == 0 { - return ErrInvalidVersion(DefaultCodespace, "missing counterparty versions") + return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "missing counterparty versions")) } for _, version := range msg.CounterpartyVersions { if strings.TrimSpace(version) == "" { - return ErrInvalidVersion(DefaultCodespace, "version can't be blank") + return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "version can't be blank")) } } if msg.ProofInit == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof init cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof init cannot be nil")) } if msg.ProofConsensus == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof consensus cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof consensus cannot be nil")) } if msg.ProofHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) } if msg.ConsensusHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0")) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("missing signer address") } - return msg.Counterparty.ValidateBasic() + return sdk.ConvertError(msg.Counterparty.ValidateBasic()) } // GetSignBytes implements sdk.Msg @@ -205,22 +205,22 @@ func (msg MsgConnectionOpenAck) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenAck) ValidateBasic() sdk.Error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) } if strings.TrimSpace(msg.Version) == "" { - return ErrInvalidVersion(DefaultCodespace, "version can't be blank") + return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "version can't be blank")) } if msg.ProofTry == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof try cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof try cannot be nil")) } if msg.ProofConsensus == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof consensus cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof consensus cannot be nil")) } if msg.ProofHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) } if msg.ConsensusHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0")) } if msg.Signer.Empty() { return sdk.ErrInvalidAddress("missing signer address") @@ -274,15 +274,14 @@ func (msg MsgConnectionOpenConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenConfirm) ValidateBasic() sdk.Error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid connection ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) } if msg.ProofAck == nil { - return ErrInvalidConnectionProof(DefaultCodespace, "proof ack cannot be nil") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof ack cannot be nil")) } if msg.ProofHeight == 0 { - return ErrInvalidHeight(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) } - if msg.Signer.Empty() { return sdk.ErrInvalidAddress("missing signer address") } diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go index 7c94f3036936..87fbae8b7276 100644 --- a/x/ibc/03-connection/types/msgs_test.go +++ b/x/ibc/03-connection/types/msgs_test.go @@ -4,9 +4,10 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - "github.com/stretchr/testify/require" ) func TestNewMsgConnectionOpenInit(t *testing.T) { diff --git a/x/ibc/03-connection/types/querier.go b/x/ibc/03-connection/types/querier.go index 6fbb151342f4..c254bebd6b4c 100644 --- a/x/ibc/03-connection/types/querier.go +++ b/x/ibc/03-connection/types/querier.go @@ -3,8 +3,9 @@ package types import ( "strings" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/tendermint/tendermint/crypto/merkle" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // query routes supported by the IBC connection Querier diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index 25f73b478565..8ce587180679 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -36,7 +36,6 @@ const ( CodePacketTimeout = types.CodePacketTimeout CodeInvalidChannel = types.CodeInvalidChannel CodeInvalidChannelState = types.CodeInvalidChannelState - CodeInvalidChannelProof = types.CodeInvalidChannelProof AttributeKeySenderPort = types.AttributeKeySenderPort AttributeKeyReceiverPort = types.AttributeKeyReceiverPort AttributeKeyChannelID = types.AttributeKeyChannelID @@ -66,7 +65,6 @@ var ( ErrPacketTimeout = types.ErrPacketTimeout ErrInvalidChannel = types.ErrInvalidChannel ErrInvalidChannelState = types.ErrInvalidChannelState - ErrInvalidChannelProof = types.ErrInvalidChannelProof ChannelPath = types.ChannelPath ChannelCapabilityPath = types.ChannelCapabilityPath NextSequenceSendPath = types.NextSequenceSendPath diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index 265ec880d73a..fea92f900ee9 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -11,6 +11,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" @@ -24,7 +26,6 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - abci "github.com/tendermint/tendermint/abci/types" ) const ( diff --git a/x/ibc/04-channel/exported/exported.go b/x/ibc/04-channel/exported/exported.go index 8fb84f7c1c01..6fd31751fef6 100644 --- a/x/ibc/04-channel/exported/exported.go +++ b/x/ibc/04-channel/exported/exported.go @@ -1,9 +1,6 @@ package exported -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - +// PacketI defines the standard interface for IBC packets type PacketI interface { GetSequence() uint64 GetTimeoutHeight() uint64 @@ -12,5 +9,5 @@ type PacketI interface { GetDestPort() string GetDestChannel() string GetData() []byte - ValidateBasic() sdk.Error + ValidateBasic() error } diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 5a8ce10ceb4a..fde534b0f26d 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "fmt" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" @@ -10,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" - abci "github.com/tendermint/tendermint/abci/types" ) func (suite *KeeperTestSuite) createClient() { diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index dc6bbd3fb021..0de7cc329288 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -15,11 +15,9 @@ import ( // Keeper defines the IBC channel keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store - + storeKey sdk.StoreKey + cdc *codec.Codec + codespace sdk.CodespaceType clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper portKeeper types.PortKeeper @@ -32,11 +30,9 @@ func NewKeeper( portKeeper types.PortKeeper, ) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/channel", - prefix: []byte{}, - // prefix: []byte(types.SubModuleName + "/"), // "channel/" + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/channel", clientKeeper: clientKeeper, connectionKeeper: connectionKeeper, portKeeper: portKeeper, @@ -50,7 +46,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetChannel returns a channel with a particular identifier binded to a specific port func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyChannel(portID, channelID)) if bz == nil { return types.Channel{}, false @@ -63,14 +59,14 @@ func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Cha // SetChannel sets a channel to the store func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel types.Channel) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := k.cdc.MustMarshalBinaryLengthPrefixed(channel) store.Set(types.KeyChannel(portID, channelID), bz) } // GetChannelCapability gets a channel's capability key from the store func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) (string, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyChannelCapabilityPath(portID, channelID)) if bz == nil { return "", false @@ -81,13 +77,13 @@ func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) // SetChannelCapability sets a channel's capability key to the store func (k Keeper) SetChannelCapability(ctx sdk.Context, portID, channelID string, key string) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) store.Set(types.KeyChannelCapabilityPath(portID, channelID), []byte(key)) } // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyNextSequenceSend(portID, channelID)) if bz == nil { return 0, false @@ -98,14 +94,14 @@ func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) ( // SetNextSequenceSend sets a channel's next send sequence to the store func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := sdk.Uint64ToBigEndian(sequence) store.Set(types.KeyNextSequenceSend(portID, channelID), bz) } // GetNextSequenceRecv gets a channel's next receive sequence from the store func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyNextSequenceRecv(portID, channelID)) if bz == nil { return 0, false @@ -116,38 +112,38 @@ func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) ( // SetNextSequenceRecv sets a channel's next receive sequence to the store func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := sdk.Uint64ToBigEndian(sequence) store.Set(types.KeyNextSequenceRecv(portID, channelID), bz) } // GetPacketCommitment gets the packet commitment hash from the store func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyPacketCommitment(portID, channelID, sequence)) return bz } // SetPacketCommitment sets the packet commitment hash to the store func (k Keeper) SetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64, commitmentHash []byte) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) store.Set(types.KeyPacketCommitment(portID, channelID, sequence), commitmentHash) } func (k Keeper) deletePacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) store.Delete(types.KeyPacketCommitment(portID, channelID, sequence)) } // SetPacketAcknowledgement sets the packet ack hash to the store func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64, ackHash []byte) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) } // GetPacketAcknowledgement gets the packet ack hash from the store func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) bz := store.Get(types.KeyPacketAcknowledgement(portID, channelID, sequence)) if bz == nil { return nil, false diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index f05cc56db841..299b0ab9c5e5 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -3,13 +3,14 @@ package keeper_test import ( "testing" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - "github.com/stretchr/testify/suite" - abci "github.com/tendermint/tendermint/abci/types" ) // define constants used for testing diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go index 3618c5f29fd4..3bf671d1e0fb 100644 --- a/x/ibc/04-channel/keeper/querier.go +++ b/x/ibc/04-channel/keeper/querier.go @@ -20,7 +20,7 @@ func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, s channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) if !found { - return nil, types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID) + return nil, sdk.ConvertError(types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID)) } bz, err := types.SubModuleCdc.MarshalJSON(channel) diff --git a/x/ibc/04-channel/types/channel.go b/x/ibc/04-channel/types/channel.go index 98bbb9b44f1e..d14c42ad6e2c 100644 --- a/x/ibc/04-channel/types/channel.go +++ b/x/ibc/04-channel/types/channel.go @@ -5,8 +5,7 @@ import ( "fmt" "strings" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -33,7 +32,7 @@ func NewChannel( } // ValidateBasic performs a basic validation of the channel fields -func (ch Channel) ValidateBasic() sdk.Error { +func (ch Channel) ValidateBasic() error { if ch.State.String() == "" { return ErrInvalidChannelState( DefaultCodespace, @@ -50,7 +49,7 @@ func (ch Channel) ValidateBasic() sdk.Error { return ErrInvalidChannel(DefaultCodespace, "IBC v1 only supports one connection hop") } if err := host.DefaultConnectionIdentifierValidator(ch.ConnectionHops[0]); err != nil { - return ErrInvalidChannel(DefaultCodespace, errors.Wrap(err, "invalid connection hop ID").Error()) + return sdkerrors.Wrap(err, "invalid connection hop ID") } if strings.TrimSpace(ch.Version) == "" { return ErrInvalidChannel(DefaultCodespace, "channel version can't be blank") @@ -73,12 +72,12 @@ func NewCounterparty(portID, channelID string) Counterparty { } // ValidateBasic performs a basic validation check of the identifiers -func (c Counterparty) ValidateBasic() sdk.Error { +func (c Counterparty) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(c.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty connection ID: %s", err.Error())) + return sdkerrors.Wrap(err, "invalid counterparty connection ID") } if err := host.DefaultChannelIdentifierValidator(c.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid counterparty client ID: %s", err.Error())) + return sdkerrors.Wrap(err, "invalid counterparty client ID") } return nil } diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go index 37d3925b513e..318c78017d34 100644 --- a/x/ibc/04-channel/types/errors.go +++ b/x/ibc/04-channel/types/errors.go @@ -4,70 +4,101 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // channel error codes const ( DefaultCodespace sdk.CodespaceType = SubModuleName - CodeChannelExists sdk.CodeType = 101 - CodeChannelNotFound sdk.CodeType = 102 - CodeInvalidCounterpartyChannel sdk.CodeType = 103 - CodeChannelCapabilityNotFound sdk.CodeType = 104 - CodeInvalidPacket sdk.CodeType = 105 - CodeSequenceNotFound sdk.CodeType = 106 - CodePacketTimeout sdk.CodeType = 107 - CodeInvalidChannel sdk.CodeType = 108 - CodeInvalidChannelState sdk.CodeType = 109 - CodeInvalidChannelProof sdk.CodeType = 110 + CodeChannelExists sdk.CodeType = 219 + CodeChannelNotFound sdk.CodeType = 220 + CodeInvalidCounterpartyChannel sdk.CodeType = 221 + CodeChannelCapabilityNotFound sdk.CodeType = 222 + CodeInvalidPacket sdk.CodeType = 223 + CodeSequenceNotFound sdk.CodeType = 224 + CodePacketTimeout sdk.CodeType = 225 + CodeInvalidChannel sdk.CodeType = 226 + CodeInvalidChannelState sdk.CodeType = 227 ) // ErrChannelExists implements sdk.Error -func ErrChannelExists(codespace sdk.CodespaceType, channelID string) sdk.Error { - return sdk.NewError(codespace, CodeChannelExists, fmt.Sprintf("channel with ID %s already exists", channelID)) +func ErrChannelExists(codespace sdk.CodespaceType, channelID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeChannelExists), + fmt.Sprintf("channel with ID %s already exists", channelID), + ) } // ErrChannelNotFound implements sdk.Error -func ErrChannelNotFound(codespace sdk.CodespaceType, portID, channelID string) sdk.Error { - return sdk.NewError(codespace, CodeChannelNotFound, fmt.Sprintf("channel with ID %s on port %s not found", channelID, portID)) +func ErrChannelNotFound(codespace sdk.CodespaceType, portID, channelID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeChannelNotFound), + fmt.Sprintf("channel with ID %s on port %s not found", channelID, portID), + ) } // ErrInvalidCounterpartyChannel implements sdk.Error -func ErrInvalidCounterpartyChannel(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidCounterpartyChannel, msg) +func ErrInvalidCounterpartyChannel(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidCounterpartyChannel), + msg, + ) } // ErrChannelCapabilityNotFound implements sdk.Error -func ErrChannelCapabilityNotFound(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeChannelCapabilityNotFound, "channel capability key not found") +func ErrChannelCapabilityNotFound(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodeChannelCapabilityNotFound), + "channel capability key not found", + ) } // ErrInvalidPacket implements sdk.Error -func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidPacket, msg) +func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidPacket), + msg, + ) } // ErrSequenceNotFound implements sdk.Error -func ErrSequenceNotFound(codespace sdk.CodespaceType, seqType string) sdk.Error { - return sdk.NewError(codespace, CodeSequenceNotFound, fmt.Sprintf("next %s sequence counter not found", seqType)) +func ErrSequenceNotFound(codespace sdk.CodespaceType, seqType string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeSequenceNotFound), + fmt.Sprintf("next %s sequence counter not found", seqType), + ) } // ErrPacketTimeout implements sdk.Error -func ErrPacketTimeout(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodePacketTimeout, "packet timeout") +func ErrPacketTimeout(codespace sdk.CodespaceType) error { + return sdkerrors.New( + string(codespace), + uint32(CodePacketTimeout), + "packet timeout", + ) } // ErrInvalidChannel implements sdk.Error -func ErrInvalidChannel(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidChannel, msg) +func ErrInvalidChannel(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidChannel), + msg, + ) } // ErrInvalidChannelState implements sdk.Error -func ErrInvalidChannelState(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidChannelState, msg) -} - -// ErrInvalidChannelProof implements sdk.Error -func ErrInvalidChannelProof(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidChannelProof, msg) +func ErrInvalidChannelState(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidChannelState), + msg, + ) } diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go index f308640b2e32..7849b37f90e1 100644 --- a/x/ibc/04-channel/types/keys.go +++ b/x/ibc/04-channel/types/keys.go @@ -18,6 +18,11 @@ const ( QuerierRoute = SubModuleName ) +// KVStore key prefixes +var ( + KeyPrefixChannel = []byte{0x00} +) + // ChannelPath defines the path under which channels are stored func ChannelPath(portID, channelID string) string { return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index a6d7d856e34f..6f69c5d6ea86 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -1,10 +1,10 @@ package types import ( - "fmt" "strings" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -46,14 +46,14 @@ func (msg MsgChannelOpenInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenInit) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } // Signer can be empty - return msg.Channel.ValidateBasic() + return sdk.ConvertError(msg.Channel.ValidateBasic()) } // GetSignBytes implements sdk.Msg @@ -109,23 +109,23 @@ func (msg MsgChannelOpenTry) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenTry) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if strings.TrimSpace(msg.CounterpartyVersion) == "" { - return ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank") + return sdk.ConvertError(ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank")) } if msg.ProofInit == nil { - return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } if msg.ProofHeight == 0 { - return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) } // Signer can be empty - return msg.Channel.ValidateBasic() + return sdk.ConvertError(msg.Channel.ValidateBasic()) } // GetSignBytes implements sdk.Msg @@ -176,20 +176,20 @@ func (msg MsgChannelOpenAck) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenAck) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if strings.TrimSpace(msg.CounterpartyVersion) == "" { - return ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank") + return sdk.ConvertError(ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank")) } if msg.ProofTry == nil { - return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } if msg.ProofHeight == 0 { - return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) } // Signer can be empty return nil @@ -241,17 +241,17 @@ func (msg MsgChannelOpenConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenConfirm) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if msg.ProofAck == nil { - return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } if msg.ProofHeight == 0 { - return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) } // Signer can be empty return nil @@ -296,11 +296,11 @@ func (msg MsgChannelCloseInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelCloseInit) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } // Signer can be empty return nil @@ -353,16 +353,16 @@ func (msg MsgChannelCloseConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelCloseConfirm) ValidateBasic() sdk.Error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if msg.ProofInit == nil { - return ErrInvalidChannelProof(DefaultCodespace, "cannot submit an empty proof") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } if msg.ProofHeight == 0 { - return ErrInvalidChannelProof(DefaultCodespace, "proof height must be > 0") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) } // Signer can be empty return nil diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index c57a35af74ad..3754ea4efa1a 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -3,9 +3,10 @@ package types import ( "testing" + "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - "github.com/stretchr/testify/require" ) // define constants used for testing @@ -38,21 +39,21 @@ var ( // TestMsgChannelOpenInit tests ValidateBasic for MsgChannelOpenInit func TestMsgChannelOpenInit(t *testing.T) { testMsgs := []MsgChannelOpenInit{ - NewMsgChannelOpenInit("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg - NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id - NewMsgChannelOpenInit(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long port id - NewMsgChannelOpenInit(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // port id contains non-alpha - NewMsgChannelOpenInit("testport", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short channel id - NewMsgChannelOpenInit("testport", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long channel id - NewMsgChannelOpenInit("testport", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // channel id contains non-alpha - NewMsgChannelOpenInit("testport", "testchannel", "1.0", Order(3), connHops, "testcpport", "testcpchannel", addr), // invalid channel order - NewMsgChannelOpenInit("testport", "testchannel", "1.0", ORDERED, invalidConnHops, "testcpport", "testcpchannel", addr), // connection hops more than 1 - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", addr), // too short connection id - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", addr), // too long connection id - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", addr), // connection id contains non-alpha - NewMsgChannelOpenInit("testport", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", addr), // empty channel version - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", addr), // invalid counterparty port id - NewMsgChannelOpenInit("testport", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, addr), // invalid counterparty channel id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg + NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id + NewMsgChannelOpenInit(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long port id + NewMsgChannelOpenInit(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // port id contains non-alpha + NewMsgChannelOpenInit("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short channel id + NewMsgChannelOpenInit("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long channel id + NewMsgChannelOpenInit("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // channel id contains non-alpha + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", Order(3), connHops, "testcpport", "testcpchannel", addr), // invalid channel order + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", ORDERED, invalidConnHops, "testcpport", "testcpchannel", addr), // connection hops more than 1 + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", addr), // too short connection id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", addr), // too long connection id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", addr), // connection id contains non-alpha + NewMsgChannelOpenInit("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", addr), // empty channel version + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", addr), // invalid counterparty port id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, addr), // invalid counterparty channel id } testCases := []struct { @@ -90,24 +91,24 @@ func TestMsgChannelOpenInit(t *testing.T) { // TestMsgChannelOpenTry tests ValidateBasic for MsgChannelOpenTry func TestMsgChannelOpenTry(t *testing.T) { testMsgs := []MsgChannelOpenTry{ - NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // valid msg - NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short port id - NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long port id - NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenTry("testport", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short channel id - NewMsgChannelOpenTry("testport", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long channel id - NewMsgChannelOpenTry("testport", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", proof, 1, addr), // empty counterparty version - NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty proof - NewMsgChannelOpenTry("testport", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 0, addr), // proof height is zero - NewMsgChannelOpenTry("testport", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // invalid channel order - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection hops more than 1 - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short connection id - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long connection id - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection id contains non-alpha - NewMsgChannelOpenTry("testport", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // empty channel version - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", proof, 1, addr), // invalid counterparty port id - NewMsgChannelOpenTry("testport", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", proof, 1, addr), // invalid counterparty channel id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // valid msg + NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short port id + NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long port id + NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenTry("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short channel id + NewMsgChannelOpenTry("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long channel id + NewMsgChannelOpenTry("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", proof, 1, addr), // empty counterparty version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 0, addr), // proof height is zero + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // invalid channel order + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection hops more than 1 + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // empty channel version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", proof, 1, addr), // invalid counterparty port id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", proof, 1, addr), // invalid counterparty channel id } testCases := []struct { @@ -148,16 +149,16 @@ func TestMsgChannelOpenTry(t *testing.T) { // TestMsgChannelOpenAck tests ValidateBasic for MsgChannelOpenAck func TestMsgChannelOpenAck(t *testing.T) { testMsgs := []MsgChannelOpenAck{ - NewMsgChannelOpenAck("testport", "testchannel", "1.0", proof, 1, addr), // valid msg - NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", proof, 1, addr), // too short port id - NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", proof, 1, addr), // too long port id - NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenAck("testport", invalidShortChannel, "1.0", proof, 1, addr), // too short channel id - NewMsgChannelOpenAck("testport", invalidLongChannel, "1.0", proof, 1, addr), // too long channel id - NewMsgChannelOpenAck("testport", invalidChannel, "1.0", proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenAck("testport", "testchannel", "", proof, 1, addr), // empty counterparty version - NewMsgChannelOpenAck("testport", "testchannel", "1.0", nil, 1, addr), // empty proof - NewMsgChannelOpenAck("testport", "testchannel", "1.0", proof, 0, addr), // proof height is zero + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", proof, 1, addr), // valid msg + NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", proof, 1, addr), // too short port id + NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", proof, 1, addr), // too long port id + NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenAck("testportid", invalidShortChannel, "1.0", proof, 1, addr), // too short channel id + NewMsgChannelOpenAck("testportid", invalidLongChannel, "1.0", proof, 1, addr), // too long channel id + NewMsgChannelOpenAck("testportid", invalidChannel, "1.0", proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenAck("testportid", "testchannel", "", proof, 1, addr), // empty counterparty version + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", proof, 0, addr), // proof height is zero } testCases := []struct { @@ -190,15 +191,15 @@ func TestMsgChannelOpenAck(t *testing.T) { // TestMsgChannelOpenConfirm tests ValidateBasic for MsgChannelOpenConfirm func TestMsgChannelOpenConfirm(t *testing.T) { testMsgs := []MsgChannelOpenConfirm{ - NewMsgChannelOpenConfirm("testport", "testchannel", proof, 1, addr), // valid msg - NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id - NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id - NewMsgChannelOpenConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenConfirm("testport", invalidShortChannel, proof, 1, addr), // too short channel id - NewMsgChannelOpenConfirm("testport", invalidLongChannel, proof, 1, addr), // too long channel id - NewMsgChannelOpenConfirm("testport", invalidChannel, proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenConfirm("testport", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelOpenConfirm("testport", "testchannel", proof, 0, addr), // proof height is zero + NewMsgChannelOpenConfirm("testportid", "testchannel", proof, 1, addr), // valid msg + NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id + NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id + NewMsgChannelOpenConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenConfirm("testportid", invalidShortChannel, proof, 1, addr), // too short channel id + NewMsgChannelOpenConfirm("testportid", invalidLongChannel, proof, 1, addr), // too long channel id + NewMsgChannelOpenConfirm("testportid", invalidChannel, proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testportid", "testchannel", proof, 0, addr), // proof height is zero } testCases := []struct { @@ -230,13 +231,13 @@ func TestMsgChannelOpenConfirm(t *testing.T) { // TestMsgChannelCloseInit tests ValidateBasic for MsgChannelCloseInit func TestMsgChannelCloseInit(t *testing.T) { testMsgs := []MsgChannelCloseInit{ - NewMsgChannelCloseInit("testport", "testchannel", addr), // valid msg - NewMsgChannelCloseInit(invalidShortPort, "testchannel", addr), // too short port id - NewMsgChannelCloseInit(invalidLongPort, "testchannel", addr), // too long port id - NewMsgChannelCloseInit(invalidPort, "testchannel", addr), // port id contains non-alpha - NewMsgChannelCloseInit("testport", invalidShortChannel, addr), // too short channel id - NewMsgChannelCloseInit("testport", invalidLongChannel, addr), // too long channel id - NewMsgChannelCloseInit("testport", invalidChannel, addr), // channel id contains non-alpha + NewMsgChannelCloseInit("testportid", "testchannel", addr), // valid msg + NewMsgChannelCloseInit(invalidShortPort, "testchannel", addr), // too short port id + NewMsgChannelCloseInit(invalidLongPort, "testchannel", addr), // too long port id + NewMsgChannelCloseInit(invalidPort, "testchannel", addr), // port id contains non-alpha + NewMsgChannelCloseInit("testportid", invalidShortChannel, addr), // too short channel id + NewMsgChannelCloseInit("testportid", invalidLongChannel, addr), // too long channel id + NewMsgChannelCloseInit("testportid", invalidChannel, addr), // channel id contains non-alpha } testCases := []struct { @@ -266,15 +267,15 @@ func TestMsgChannelCloseInit(t *testing.T) { // TestMsgChannelCloseConfirm tests ValidateBasic for MsgChannelCloseConfirm func TestMsgChannelCloseConfirm(t *testing.T) { testMsgs := []MsgChannelCloseConfirm{ - NewMsgChannelCloseConfirm("testport", "testchannel", proof, 1, addr), // valid msg - NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id - NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id - NewMsgChannelCloseConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha - NewMsgChannelCloseConfirm("testport", invalidShortChannel, proof, 1, addr), // too short channel id - NewMsgChannelCloseConfirm("testport", invalidLongChannel, proof, 1, addr), // too long channel id - NewMsgChannelCloseConfirm("testport", invalidChannel, proof, 1, addr), // channel id contains non-alpha - NewMsgChannelCloseConfirm("testport", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelCloseConfirm("testport", "testchannel", proof, 0, addr), // proof height is zero + NewMsgChannelCloseConfirm("testportid", "testchannel", proof, 1, addr), // valid msg + NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id + NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id + NewMsgChannelCloseConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha + NewMsgChannelCloseConfirm("testportid", invalidShortChannel, proof, 1, addr), // too short channel id + NewMsgChannelCloseConfirm("testportid", invalidLongChannel, proof, 1, addr), // too long channel id + NewMsgChannelCloseConfirm("testportid", invalidChannel, proof, 1, addr), // channel id contains non-alpha + NewMsgChannelCloseConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testportid", "testchannel", proof, 0, addr), // proof height is zero } testCases := []struct { diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go index 8d170cc62a9d..8cfadf458487 100644 --- a/x/ibc/04-channel/types/packet.go +++ b/x/ibc/04-channel/types/packet.go @@ -3,7 +3,6 @@ package types import ( "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -37,29 +36,29 @@ func NewPacket( } } -// Sequence implements PacketI interface +// GetSequence implements PacketI interface func (p Packet) GetSequence() uint64 { return p.Sequence } -// TimeoutHeight implements PacketI interface +// GetTimeoutHeight implements PacketI interface func (p Packet) GetTimeoutHeight() uint64 { return p.Timeout } -// SourcePort implements PacketI interface +// GetSourcePort implements PacketI interface func (p Packet) GetSourcePort() string { return p.SourcePort } -// SourceChannel implements PacketI interface +// GetSourceChannel implements PacketI interface func (p Packet) GetSourceChannel() string { return p.SourceChannel } -// DestPort implements PacketI interface +// GetDestPort implements PacketI interface func (p Packet) GetDestPort() string { return p.DestinationPort } -// DestChannel implements PacketI interface +// GetDestChannel implements PacketI interface func (p Packet) GetDestChannel() string { return p.DestinationChannel } -// Data implements PacketI interface +// GetData implements PacketI interface func (p Packet) GetData() []byte { return p.Data } // ValidateBasic implements PacketI interface -func (p Packet) ValidateBasic() sdk.Error { +func (p Packet) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(p.SourcePort); err != nil { return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source port ID: %s", err.Error())) } @@ -104,5 +103,5 @@ func NewOpaquePacket(sequence, timeout uint64, sourcePort, sourceChannel, return OpaquePacket{&Packet} } -// Data implements PacketI interface +// GetData implements PacketI interface func (op OpaquePacket) GetData() []byte { return nil } diff --git a/x/ibc/05-port/alias.go b/x/ibc/05-port/alias.go index a74c7fe61537..de0907a93212 100644 --- a/x/ibc/05-port/alias.go +++ b/x/ibc/05-port/alias.go @@ -12,26 +12,22 @@ import ( ) const ( - DefaultCodespace = types.DefaultCodespace - CodePortExists = types.CodePortExists - CodePortNotFound = types.CodePortNotFound - CodePortNotAuthenticated = types.CodePortNotAuthenticated - CodeInvalidPortID = types.CodeInvalidPortID - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute + DefaultCodespace = types.DefaultCodespace + CodePortExists = types.CodePortExists + CodePortNotFound = types.CodePortNotFound + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute ) var ( // functions aliases - NewKeeper = keeper.NewKeeper - ErrPortExists = types.ErrPortExists - ErrPortNotFound = types.ErrPortNotFound - ErrPortNotAuthenticated = types.ErrPortNotAuthenticated - ErrInvalidPortID = types.ErrInvalidPortID - PortPath = types.PortPath - KeyPort = types.KeyPort + NewKeeper = keeper.NewKeeper + ErrPortExists = types.ErrPortExists + ErrPortNotFound = types.ErrPortNotFound + PortPath = types.PortPath + KeyPort = types.KeyPort ) type ( diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index cdb48010237f..54e5e1ad13de 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -14,9 +14,7 @@ type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store - ports map[string]string - bound []string + ports map[string]bool } // NewKeeper creates a new IBC connection Keeper instance @@ -25,22 +23,13 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) storeKey: key, cdc: cdc, codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/port", - prefix: []byte{}, - // prefix: []byte(types.SubModuleName + "/"), // "port/" - ports: make(map[string]string), // map of capability key names to port ids + ports: make(map[string]bool), // map of capability key names to port ids } } -// GetPorts returns the list of bound ports. -// (these ports still must have been bound statically) -func (k Keeper) GetPorts() []string { - return k.bound -} - -// GetPort retrieves a given port ID from keeper map -func (k Keeper) GetPort(ck sdk.CapabilityKey) (string, bool) { - portID, found := k.ports[ck.Name()] - return portID, found +// isBounded checks a given port ID is already bounded. +func (k Keeper) isBounded(portID string) bool { + return k.ports[portID] } // BindPort binds to a port and returns the associated capability. @@ -52,15 +41,13 @@ func (k Keeper) BindPort(portID string) sdk.CapabilityKey { panic(err.Error()) } - for _, b := range k.bound { - if b == portID { - panic(fmt.Sprintf("port %s is already bound", portID)) - } + if k.isBounded(portID) { + panic(fmt.Sprintf("port %s is already bound", portID)) } key := sdk.NewKVStoreKey(portID) - k.ports[key.Name()] = portID - k.bound = append(k.bound, portID) + k.ports[key.Name()] = true // NOTE: key name and value always match + return key } @@ -73,5 +60,5 @@ func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { panic(err.Error()) } - return k.ports[key.Name()] == portID + return k.ports[key.Name()] } diff --git a/x/ibc/05-port/types/errors.go b/x/ibc/05-port/types/errors.go index 20031c826107..d15b07bf0791 100644 --- a/x/ibc/05-port/types/errors.go +++ b/x/ibc/05-port/types/errors.go @@ -4,34 +4,41 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // port error codes const ( DefaultCodespace sdk.CodespaceType = SubModuleName - CodePortExists sdk.CodeType = 101 - CodePortNotFound sdk.CodeType = 102 - CodePortNotAuthenticated sdk.CodeType = 103 - CodeInvalidPortID sdk.CodeType = 104 + CodePortExists sdk.CodeType = 228 + CodePortNotFound sdk.CodeType = 229 + CodeInvalidPort sdk.CodeType = 230 ) // ErrPortExists implements sdk.Error -func ErrPortExists(codespace sdk.CodespaceType, portID string) sdk.Error { - return sdk.NewError(codespace, CodePortExists, fmt.Sprintf("port with ID %s is already binded", portID)) +func ErrPortExists(codespace sdk.CodespaceType, portID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodePortExists), + fmt.Sprintf("port with ID %s is already binded", portID), + ) } // ErrPortNotFound implements sdk.Error -func ErrPortNotFound(codespace sdk.CodespaceType, portID string) sdk.Error { - return sdk.NewError(codespace, CodePortNotFound, fmt.Sprintf("port with ID %s not found", portID)) +func ErrPortNotFound(codespace sdk.CodespaceType, portID string) error { + return sdkerrors.New( + string(codespace), + uint32(CodePortNotFound), + fmt.Sprintf("port with ID %s not found", portID), + ) } -// ErrPortNotAuthenticated implements sdk.Error -func ErrPortNotAuthenticated(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodePortNotAuthenticated, "port failed authentication") -} - -// ErrInvalidPortID implements sdk.Error -func ErrInvalidPortID(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidPortID, "invalid port ID") +// ErrInvalidPort implements sdk.Error +func ErrInvalidPort(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodePortNotFound), + msg, + ) } diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go index 66028740581e..ab75c9dab2d2 100644 --- a/x/ibc/20-transfer/alias.go +++ b/x/ibc/20-transfer/alias.go @@ -12,36 +12,23 @@ import ( ) const ( - DefaultPacketTimeout = keeper.DefaultPacketTimeout - DefaultCodespace = types.DefaultCodespace - CodeInvalidAddress = types.CodeInvalidAddress - CodeErrSendPacket = types.CodeErrSendPacket - CodeInvalidPacketData = types.CodeInvalidPacketData - CodeInvalidChannelOrder = types.CodeInvalidChannelOrder - CodeInvalidPort = types.CodeInvalidPort - CodeInvalidVersion = types.CodeInvalidVersion - AttributeKeyReceiver = types.AttributeKeyReceiver - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - BoundPortID = types.BoundPortID + DefaultPacketTimeout = keeper.DefaultPacketTimeout + DefaultCodespace = types.DefaultCodespace + AttributeKeyReceiver = types.AttributeKeyReceiver + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute ) var ( // functions aliases - NewKeeper = keeper.NewKeeper - RegisterCodec = types.RegisterCodec - ErrInvalidAddress = types.ErrInvalidAddress - ErrSendPacket = types.ErrSendPacket - ErrInvalidPacketData = types.ErrInvalidPacketData - ErrInvalidChannelOrder = types.ErrInvalidChannelOrder - ErrInvalidPort = types.ErrInvalidPort - ErrInvalidVersion = types.ErrInvalidVersion - GetEscrowAddress = types.GetEscrowAddress - GetDenomPrefix = types.GetDenomPrefix - GetModuleAccountName = types.GetModuleAccountName - NewMsgTransfer = types.NewMsgTransfer + NewKeeper = keeper.NewKeeper + RegisterCodec = types.RegisterCodec + GetEscrowAddress = types.GetEscrowAddress + GetDenomPrefix = types.GetDenomPrefix + GetModuleAccountName = types.GetModuleAccountName + NewMsgTransfer = types.NewMsgTransfer // variable aliases ModuleCdc = types.ModuleCdc diff --git a/x/ibc/20-transfer/client/cli/query.go b/x/ibc/20-transfer/client/cli/query.go index 4be0103385ee..6aad7157e228 100644 --- a/x/ibc/20-transfer/client/cli/query.go +++ b/x/ibc/20-transfer/client/cli/query.go @@ -7,12 +7,13 @@ import ( "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - abci "github.com/tendermint/tendermint/abci/types" ) // GetQueryCmd returns the query commands for IBC fungible token transfer diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go index 8594783e6456..444e966b97c8 100644 --- a/x/ibc/20-transfer/keeper/callbacks.go +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -5,8 +5,11 @@ import ( "strings" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // nolint: unused @@ -20,15 +23,19 @@ func (k Keeper) onChanOpenInit( version string, ) error { if order != channeltypes.UNORDERED { - return types.ErrInvalidChannelOrder(k.codespace, order.String()) + return channeltypes.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") } - if counterparty.PortID != types.BoundPortID { - return types.ErrInvalidPort(k.codespace, portID) + // NOTE: here the capability key name defines the port ID of the counterparty + if counterparty.PortID != k.boundedCapability.Name() { + return porttypes.ErrInvalidPort( + k.codespace, + fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", portID, k.boundedCapability.Name()), + ) } if strings.TrimSpace(version) != "" { - return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -48,19 +55,23 @@ func (k Keeper) onChanOpenTry( counterpartyVersion string, ) error { if order != channeltypes.UNORDERED { - return types.ErrInvalidChannelOrder(k.codespace, order.String()) + return channeltypes.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") } - if counterparty.PortID != types.BoundPortID { - return types.ErrInvalidPort(k.codespace, portID) + // NOTE: here the capability key name defines the port ID of the counterparty + if counterparty.PortID != k.boundedCapability.Name() { + return porttypes.ErrInvalidPort( + k.codespace, + fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", portID, k.boundedCapability.Name()), + ) } if strings.TrimSpace(version) != "" { - return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") } if strings.TrimSpace(counterpartyVersion) != "" { - return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid counterparty version: %s", version)) + return ibctypes.ErrInvalidVersion(k.codespace, "counterparty version cannot be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -76,7 +87,7 @@ func (k Keeper) onChanOpenAck( version string, ) error { if strings.TrimSpace(version) != "" { - return types.ErrInvalidVersion(k.codespace, fmt.Sprintf("invalid version: %s", version)) + return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") } return nil @@ -122,7 +133,7 @@ func (k Keeper) onRecvPacket( err := data.UnmarshalJSON(packet.GetData()) if err != nil { - return types.ErrInvalidPacketData(k.codespace) + return sdkerrors.Wrap(err, "invalid packet data") } return k.ReceiveTransfer( @@ -150,7 +161,7 @@ func (k Keeper) onTimeoutPacket( err := data.UnmarshalJSON(packet.GetData()) if err != nil { - return types.ErrInvalidPacketData(k.codespace) + return sdkerrors.Wrap(err, "invalid packet data") } // check the denom prefix diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index 95576d4609f3..c42786f42741 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -22,7 +22,9 @@ type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec codespace sdk.CodespaceType - prefix []byte // prefix bytes for accessing the store + + // Capability key and port to which ICS20 is binded. Used for packet relaying. + boundedCapability sdk.CapabilityKey clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper @@ -34,9 +36,9 @@ type Keeper struct { // NewKeeper creates a new IBC transfer Keeper instance func NewKeeper( cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, - clientKeeper types.ClientKeeper, connnectionKeeper types.ConnectionKeeper, - channelKeeper types.ChannelKeeper, bankKeeper types.BankKeeper, - supplyKeeper types.SupplyKeeper, + capKey sdk.CapabilityKey, clientKeeper types.ClientKeeper, + connnectionKeeper types.ConnectionKeeper, channelKeeper types.ChannelKeeper, + bankKeeper types.BankKeeper, supplyKeeper types.SupplyKeeper, ) Keeper { // ensure ibc transfer module account is set @@ -45,15 +47,15 @@ func NewKeeper( } return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/transfer", - prefix: []byte(types.SubModuleName + "/"), // "transfer/" - clientKeeper: clientKeeper, - connectionKeeper: connnectionKeeper, - channelKeeper: channelKeeper, - bankKeeper: bankKeeper, - supplyKeeper: supplyKeeper, + storeKey: key, + cdc: cdc, + codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/transfer", + boundedCapability: capKey, + clientKeeper: clientKeeper, + connectionKeeper: connnectionKeeper, + channelKeeper: channelKeeper, + bankKeeper: bankKeeper, + supplyKeeper: supplyKeeper, } } diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index d87a589bbd80..dae2180dc44f 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -5,6 +5,7 @@ import ( "strings" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" @@ -61,7 +62,7 @@ func (k Keeper) ReceivePacket(ctx sdk.Context, packet channelexported.PacketI, p var data types.PacketData err = data.UnmarshalJSON(packet.GetData()) if err != nil { - return sdk.NewError(types.DefaultCodespace, types.CodeInvalidPacketData, "invalid packet data") + return sdkerrors.Wrap(err, "invalid packet data") } return k.ReceiveTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestPort(), packet.GetDestChannel(), data) @@ -173,7 +174,7 @@ func (k Keeper) createOutgoingPacket( // TODO: This should be binary-marshaled and hashed (for the commitment in the store). packetDataBz, err := packetData.MarshalJSON() if err != nil { - return sdk.NewError(sdk.CodespaceType(types.DefaultCodespace), types.CodeInvalidPacketData, "invalid packet data") + return sdkerrors.Wrap(err, "invalid packet data") } packet := channeltypes.NewPacket( @@ -186,8 +187,5 @@ func (k Keeper) createOutgoingPacket( packetDataBz, ) - // TODO: Remove this, capability keys are never generated when sending packets. Not sure why this is here. - key := sdk.NewKVStoreKey(types.BoundPortID) - - return k.channelKeeper.SendPacket(ctx, packet, key) + return k.channelKeeper.SendPacket(ctx, packet, k.boundedCapability) } diff --git a/x/ibc/20-transfer/types/errors.go b/x/ibc/20-transfer/types/errors.go deleted file mode 100644 index 51f95d560a01..000000000000 --- a/x/ibc/20-transfer/types/errors.go +++ /dev/null @@ -1,51 +0,0 @@ -package types - -import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// transfer error codes -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodeInvalidAddress sdk.CodeType = 101 - CodeErrSendPacket sdk.CodeType = 102 - CodeInvalidPacketData sdk.CodeType = 103 - CodeInvalidChannelOrder sdk.CodeType = 104 - CodeInvalidPort sdk.CodeType = 105 - CodeInvalidVersion sdk.CodeType = 106 - CodeProofMissing sdk.CodeType = 107 - CodeInvalidHeight sdk.CodeType = 108 -) - -// ErrInvalidAddress implements sdk.Error -func ErrInvalidAddress(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidAddress, msg) -} - -// ErrSendPacket implements sdk.Error -func ErrSendPacket(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeErrSendPacket, "failed to send packet") -} - -// ErrInvalidPacketData implements sdk.Error -func ErrInvalidPacketData(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidPacketData, "invalid packet data") -} - -// ErrInvalidChannelOrder implements sdk.Error -func ErrInvalidChannelOrder(codespace sdk.CodespaceType, order string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidChannelOrder, fmt.Sprintf("invalid channel order: %s", order)) -} - -// ErrInvalidPort implements sdk.Error -func ErrInvalidPort(codespace sdk.CodespaceType, portID string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidPort, fmt.Sprintf("invalid port ID: %s", portID)) -} - -// ErrInvalidVersion implements sdk.Error -func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidVersion, msg) -} diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go index 09b54dcadea5..469456bbd946 100644 --- a/x/ibc/20-transfer/types/keys.go +++ b/x/ibc/20-transfer/types/keys.go @@ -22,8 +22,8 @@ const ( // QuerierRoute is the querier route for IBC transfer QuerierRoute = SubModuleName - // BoundPortID defines the name of the capability key - BoundPortID = "bank" + // DefaultCodespace is the default error codespace for the ibc transfers + DefaultCodespace sdk.CodespaceType = SubModuleName ) // GetEscrowAddress returns the escrow address for the specified channel diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index 506676e66d7e..d0e7d9fbbe72 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -1,13 +1,12 @@ package types import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" - host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" - + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -46,11 +45,11 @@ func (MsgTransfer) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgTransfer) ValidateBasic() sdk.Error { - if err := host.DefaultPortIdentifierValidator(msg.SourcePort); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid port ID: %s", err.Error())) + if err := host.DefaultConnectionIdentifierValidator(msg.SourcePort); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source port ID")) } - if err := host.DefaultPortIdentifierValidator(msg.SourceChannel); err != nil { - return sdk.NewError(host.IBCCodeSpace, 1, fmt.Sprintf("invalid channel ID: %s", err.Error())) + if err := host.DefaultClientIdentifierValidator(msg.SourceChannel); err != nil { + return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source channel ID")) } if !msg.Amount.IsValid() { return sdk.ErrInvalidCoins("transfer amount is invalid") @@ -106,25 +105,25 @@ func (MsgRecvPacket) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgRecvPacket) ValidateBasic() sdk.Error { - if msg.Height < 1 { - return sdk.NewError(DefaultCodespace, CodeInvalidHeight, "invalid height") + if msg.Height == 0 { + return sdk.ConvertError(connectiontypes.ErrInvalidHeight(DefaultCodespace, "height must be > 0")) } - if msg.Proofs == nil { - return sdk.NewError(DefaultCodespace, CodeProofMissing, "proof missing") + if msg.Proofs == nil || len(msg.Proofs) == 0 { + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "missing proofs")) } for _, proof := range msg.Proofs { if proof.Proof == nil { - return sdk.NewError(DefaultCodespace, CodeProofMissing, "proof missing") + return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) } } if msg.Signer.Empty() { - return sdk.NewError(DefaultCodespace, CodeInvalidAddress, "invalid signer") + return sdk.ErrInvalidAddress("missing signer address") } - return msg.Packet.ValidateBasic() + return sdk.ConvertError(msg.Packet.ValidateBasic()) } // GetSignBytes implements sdk.Msg diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/merkle.go index ab428eeaf737..3c41559f4b4f 100644 --- a/x/ibc/23-commitment/merkle.go +++ b/x/ibc/23-commitment/merkle.go @@ -2,6 +2,7 @@ package commitment import ( "errors" + "net/url" "github.com/tendermint/tendermint/crypto/merkle" @@ -90,9 +91,13 @@ func (Path) GetCommitmentType() Type { return Merkle } -// String implements fmt.Stringer +// String implements fmt.Stringer. It returns unescaped path of the URL string. func (p Path) String() string { - return p.KeyPath.String() + path, err := url.PathUnescape(p.KeyPath.String()) + if err != nil { + panic(err) + } + return path } // ApplyPrefix constructs a new commitment path from the arguments. It interprets diff --git a/x/ibc/24-host/errors.go b/x/ibc/24-host/errors.go index e6a526e6d0f8..0ff6ad59d896 100644 --- a/x/ibc/24-host/errors.go +++ b/x/ibc/24-host/errors.go @@ -1,22 +1,47 @@ package host import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// IBCCodeSpace is the codespace for all errors defined in the ibc module -const IBCCodeSpace = "ibc" +// SubModuleName defines the ICS 24 host +const SubModuleName = "host" + +// Error codes specific to the ibc host submodule +const ( + DefaultCodespace sdk.CodespaceType = SubModuleName -var ( - // ErrInvalidID is returned if identifier string is invalid - ErrInvalidID = sdkerrors.Register(IBCCodeSpace, 1, "invalid identifier") + CodeInvalidID sdk.CodeType = 231 + CodeInvalidPath sdk.CodeType = 232 + CodeInvalidPacket sdk.CodeType = 233 +) - // ErrInvalidPath is returned if path string is invalid - ErrInvalidPath = sdkerrors.Register(IBCCodeSpace, 2, "invalid path") +// ErrInvalidID returns a typed ABCI error for an invalid identifier +func ErrInvalidID(codespace sdk.CodespaceType, id string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidID), + fmt.Sprintf("invalid identifier '%s'", id), + ) +} - // ErrInvalidEvidence is returned if evidence is invalid - ErrInvalidEvidence = sdkerrors.Register(IBCCodeSpace, 3, "invalid evidence") +// ErrInvalidPath returns a typed ABCI error for an invalid path +func ErrInvalidPath(codespace sdk.CodespaceType, path string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidPath), + fmt.Sprintf("invalid path '%s'", path), + ) +} - // ErrInvalidPacket is returned if packets embedded in msg are invalid - ErrInvalidPacket = sdkerrors.Register(IBCCodeSpace, 4, "invalid packet extracted from msg") -) +// ErrInvalidPacket returns a typed ABCI error for an invalid identifier +func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidPacket), + fmt.Sprintf("invalid packet: '%s'", msg), + ) +} diff --git a/x/ibc/24-host/validate.go b/x/ibc/24-host/validate.go index 6632d27c25c1..8c20c0065282 100644 --- a/x/ibc/24-host/validate.go +++ b/x/ibc/24-host/validate.go @@ -25,15 +25,15 @@ type ValidateFn func(string) error func defaultIdentifierValidator(id string, min, max int) error { // valid id MUST NOT contain "/" separator if strings.Contains(id, "/") { - return sdkerrors.Wrap(ErrInvalidID, "identifier cannot contain separator: /") + return sdkerrors.Wrap(ErrInvalidID(DefaultCodespace, id), "identifier cannot contain separator: /") } // valid id must be between 10 and 20 characters if len(id) < min || len(id) > max { - return sdkerrors.Wrapf(ErrInvalidID, "identifier has invalid length: %d, must be between %d-%d characters", len(id), min, max) + return sdkerrors.Wrapf(ErrInvalidID(DefaultCodespace, id), "identifier has invalid length: %d, must be between %d-%d characters", len(id), min, max) } // valid id must contain only lower alphabetic characters if !isAlphaLower(id) { - return sdkerrors.Wrap(ErrInvalidID, "identifier must contain only lowercase alphabetic characters") + return sdkerrors.Wrap(ErrInvalidID(DefaultCodespace, id), "identifier must contain only lowercase alphabetic characters") } return nil } @@ -76,7 +76,7 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { // Each path element must either be valid identifier or alphanumeric err := idValidator(p) if err != nil && !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath, "path contains invalid identifier or non-alphanumeric path element: %s", p) + return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "path contains invalid identifier or non-alphanumeric path element: %s", p) } } return nil @@ -91,7 +91,7 @@ func DefaultPathValidator(path string) error { for _, p := range pathArr { // Each path element must either be alphanumeric if !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath, "invalid path element containing non-alphanumeric characters: %s", p) + return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "invalid path element containing non-alphanumeric characters: %s", p) } } return nil diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 2145416efb55..2c28b5c9dd51 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -3,6 +3,7 @@ package keeper import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -28,7 +29,13 @@ func NewKeeper( connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) portKeeper := port.NewKeeper(cdc, key, codespace) channelKeeper := channel.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, portKeeper) - transferKeeper := transfer.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, channelKeeper, bk, sk) + + // TODO: move out of IBC keeper. Blocked on ADR15 + capKey := portKeeper.BindPort(bank.ModuleName) + transferKeeper := transfer.NewKeeper( + cdc, key, codespace, capKey, + clientKeeper, connectionKeeper, channelKeeper, bk, sk, + ) return Keeper{ ClientKeeper: clientKeeper, diff --git a/x/ibc/keeper/querier_test.go b/x/ibc/keeper/querier_test.go index 62e37faac203..81abe9ffadb1 100644 --- a/x/ibc/keeper/querier_test.go +++ b/x/ibc/keeper/querier_test.go @@ -13,7 +13,7 @@ import ( ) // TestNewQuerier tests that the querier paths are correct. -// NOTE: the actuall testing functionallity are located on each ICS querier test. +// NOTE: the actuall testing functionality are located on each ICS querier test. func (suite *KeeperTestSuite) TestNewQuerier() { query := abci.RequestQuery{ diff --git a/x/ibc/types/errors.go b/x/ibc/types/errors.go new file mode 100644 index 000000000000..086851321b6a --- /dev/null +++ b/x/ibc/types/errors.go @@ -0,0 +1,33 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// common IBC error codes +const ( + // DefaultCodespace of the IBC module + DefaultCodespace sdk.CodespaceType = ModuleName + + CodeInvalidProof sdk.CodeType = 234 + CodeInvalidVersion sdk.CodeType = 235 +) + +// ErrInvalidProof implements sdk.Error +func ErrInvalidProof(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidProof), + msg, + ) +} + +// ErrInvalidVersion implements sdk.Error +func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidVersion), + msg, + ) +} diff --git a/x/ibc/types/types.go b/x/ibc/types/types.go index bce43911994f..6722e5f3a426 100644 --- a/x/ibc/types/types.go +++ b/x/ibc/types/types.go @@ -1,9 +1,5 @@ package types -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - const ( // ModuleName is the name of the IBC module ModuleName = "ibc" @@ -16,7 +12,4 @@ const ( // RouterKey is the msg router key for the IBC module RouterKey string = ModuleName - - // DefaultCodespace of the IBC module - DefaultCodespace sdk.CodespaceType = ModuleName ) diff --git a/x/ibc/version/version.go b/x/ibc/version/version.go deleted file mode 100644 index a7d3275fae5b..000000000000 --- a/x/ibc/version/version.go +++ /dev/null @@ -1,13 +0,0 @@ -package version - -import "strconv" - -const Version int64 = 1 - -func DefaultPrefix() []byte { - return Prefix(Version) -} - -func Prefix(version int64) []byte { - return []byte("v" + strconv.FormatInt(version, 10) + "/") -} From c617d8966b74287725bd0d512aaf7311fdc08d86 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 12 Nov 2019 10:34:14 -0800 Subject: [PATCH 042/176] Fix codec issue in ics23 --- x/ibc/23-commitment/codec.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x/ibc/23-commitment/codec.go b/x/ibc/23-commitment/codec.go index 7e90e8cac69e..6e977ac1e678 100644 --- a/x/ibc/23-commitment/codec.go +++ b/x/ibc/23-commitment/codec.go @@ -4,6 +4,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ) +var SubModuleCdc = codec.New() + // RegisterCodec registers types declared in this package func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*RootI)(nil), nil) @@ -16,3 +18,7 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(Path{}, "ibc/commitment/merkle/Path", nil) cdc.RegisterConcrete(Proof{}, "ibc/commitment/merkle/Proof", nil) } + +func init() { + RegisterCodec(SubModuleCdc) +} From 3fb0c56c833631b5b746eda29a694676d2d04c9e Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 12 Nov 2019 10:46:17 -0800 Subject: [PATCH 043/176] Modify codec registration style to match previous working state --- x/ibc/02-client/types/codec.go | 8 +++++--- x/ibc/03-connection/types/codec.go | 8 +++++--- x/ibc/04-channel/types/codec.go | 6 +++--- x/ibc/23-commitment/codec.go | 8 +++++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index 551403e6ad89..d595f583baa9 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -7,7 +7,7 @@ import ( ) // SubModuleCdc defines the IBC client codec. -var SubModuleCdc = codec.New() +var SubModuleCdc *codec.Codec // RegisterCodec registers the IBC client interfaces and types func RegisterCodec(cdc *codec.Codec) { @@ -22,8 +22,10 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(tendermint.ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) cdc.RegisterConcrete(tendermint.Header{}, "ibc/client/tendermint/Header", nil) cdc.RegisterConcrete(tendermint.Evidence{}, "ibc/client/tendermint/Evidence", nil) + + SetSubModuleCodec(cdc) } -func init() { - RegisterCodec(SubModuleCdc) +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc } diff --git a/x/ibc/03-connection/types/codec.go b/x/ibc/03-connection/types/codec.go index 23fb04e37a8f..4317d3c6d539 100644 --- a/x/ibc/03-connection/types/codec.go +++ b/x/ibc/03-connection/types/codec.go @@ -5,7 +5,7 @@ import ( ) // SubModuleCdc defines the IBC connection codec. -var SubModuleCdc = codec.New() +var SubModuleCdc *codec.Codec // RegisterCodec registers the IBC connection types func RegisterCodec(cdc *codec.Codec) { @@ -14,8 +14,10 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgConnectionOpenAck{}, "ibc/connection/MsgConnectionOpenAck", nil) cdc.RegisterConcrete(MsgConnectionOpenConfirm{}, "ibc/connection/MsgConnectionOpenConfirm", nil) cdc.RegisterConcrete(ConnectionEnd{}, "ibc/connection/ConnectionEnd", nil) + + SetSubModuleCodec(cdc) } -func init() { - RegisterCodec(SubModuleCdc) +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc } diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index 0839edede775..06c268e3e307 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -6,7 +6,7 @@ import ( ) // SubModuleCdc defines the IBC channel codec. -var SubModuleCdc = codec.New() +var SubModuleCdc *codec.Codec // RegisterCodec registers all the necessary types and interfaces for the // IBC channel. @@ -23,6 +23,6 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgChannelCloseConfirm{}, "ibc/channel/MsgChannelCloseConfirm", nil) } -func init() { - RegisterCodec(SubModuleCdc) +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc } diff --git a/x/ibc/23-commitment/codec.go b/x/ibc/23-commitment/codec.go index 6e977ac1e678..1fc535cfc0ca 100644 --- a/x/ibc/23-commitment/codec.go +++ b/x/ibc/23-commitment/codec.go @@ -4,7 +4,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ) -var SubModuleCdc = codec.New() +var SubModuleCdc *codec.Codec // RegisterCodec registers types declared in this package func RegisterCodec(cdc *codec.Codec) { @@ -17,8 +17,10 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(Prefix{}, "ibc/commitment/merkle/Prefix", nil) cdc.RegisterConcrete(Path{}, "ibc/commitment/merkle/Path", nil) cdc.RegisterConcrete(Proof{}, "ibc/commitment/merkle/Proof", nil) + + SetSubModuleCodec(cdc) } -func init() { - RegisterCodec(SubModuleCdc) +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc } From 61b1b5965fe14e304d0c4d7dabbdb3ba4c8b9298 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Tue, 12 Nov 2019 14:59:00 -0800 Subject: [PATCH 044/176] write port tests --- x/ibc/05-port/keeper/keeper.go | 2 +- x/ibc/05-port/keeper/keeper_test.go | 76 +++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 x/ibc/05-port/keeper/keeper_test.go diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index 54e5e1ad13de..450c76418ef8 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -36,7 +36,7 @@ func (k Keeper) isBounded(portID string) bool { // Ports must be bound statically when the chain starts in `app.go`. // The capability must then be passed to a module which will need to pass // it as an extra parameter when calling functions on the IBC module. -func (k Keeper) BindPort(portID string) sdk.CapabilityKey { +func (k *Keeper) BindPort(portID string) sdk.CapabilityKey { if err := host.DefaultPortIdentifierValidator(portID); err != nil { panic(err.Error()) } diff --git a/x/ibc/05-port/keeper/keeper_test.go b/x/ibc/05-port/keeper/keeper_test.go new file mode 100644 index 000000000000..f4bf12590428 --- /dev/null +++ b/x/ibc/05-port/keeper/keeper_test.go @@ -0,0 +1,76 @@ +package keeper_test + +import ( + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/keeper" + abci "github.com/tendermint/tendermint/abci/types" +) + +var ( + validPort = "validportid" + invalidPort = "invalidPortID" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.keeper = &app.IBCKeeper.PortKeeper +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (suite *KeeperTestSuite) TestBind() { + // Test that invalid portID causes panic + require.Panics(suite.T(), func() { suite.keeper.BindPort(invalidPort) }, "Did not panic on invalid portID") + + // Test that valid BindPort returns capability key + capKey := suite.keeper.BindPort(validPort) + require.NotNil(suite.T(), capKey, "capabilityKey is nil on valid BindPort") + + // Test that port is added to bound list after BindPort is called + ports := suite.keeper.GetPorts() + require.Equal(suite.T(), []string{validPort}, ports, "portID not added to bound list") + + // Test that rebinding the same portid causes panic + require.Panics(suite.T(), func() { suite.keeper.BindPort(validPort) }, "did not panic on re-binding the same port") +} + +func (suite *KeeperTestSuite) TestAuthenticate() { + capKey := suite.keeper.BindPort(validPort) + + // Require that passing in invalid portID causes panic + require.Panics(suite.T(), func() { suite.keeper.Authenticate(capKey, invalidPort) }, "did not panic on invalid portID") + + // Valid authentication should return true + auth := suite.keeper.Authenticate(capKey, validPort) + require.True(suite.T(), auth, "valid authentication failed") + + // Test that authenticating against incorrect portid fails + auth = suite.keeper.Authenticate(capKey, "wrongportid") + require.False(suite.T(), auth, "invalid authentication failed") + + // Test that authenticating port against different valid + // capability key fails + capKey2 := suite.keeper.BindPort("otherportid") + auth = suite.keeper.Authenticate(capKey2, validPort) + require.False(suite.T(), auth, "invalid authentication for different capKey failed") +} From e54cd1f7c7c94ec20c6fc469cae6a630909bb190 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 Nov 2019 17:12:54 -0500 Subject: [PATCH 045/176] ICS-02: Keeper Tests (#5329) * add keeper tests * fix tendermint tests --- x/ibc/02-client/keeper/client_test.go | 113 ++++++++++++++++++ x/ibc/02-client/keeper/keeper_test.go | 102 ++++++++++++++++ .../types/tendermint/consensus_state_test.go | 4 +- .../types/tendermint/tendermint_test.go | 46 +------ .../02-client/types/tendermint/test_utils.go | 48 +++++++- 5 files changed, 266 insertions(+), 47 deletions(-) create mode 100644 x/ibc/02-client/keeper/client_test.go create mode 100644 x/ibc/02-client/keeper/keeper_test.go diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go new file mode 100644 index 000000000000..923a6e710981 --- /dev/null +++ b/x/ibc/02-client/keeper/client_test.go @@ -0,0 +1,113 @@ +package keeper_test + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/stretchr/testify/require" + tmtypes "github.com/tendermint/tendermint/types" +) + +const ( + testClientType exported.ClientType = iota + 2 +) + +func (suite *KeeperTestSuite) TestCreateClient() { + // Test Valid CreateClient + state, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + require.Nil(suite.T(), err, "CreateClient failed") + + // Test ClientState stored correctly + expectedState := types.State{ + ID: testClientID, + Frozen: false, + } + require.Equal(suite.T(), expectedState, state, "Incorrect ClientState returned") + + // Test ClientType and VerifiedRoot stored correctly + clientType, _ := suite.keeper.GetClientType(suite.ctx, testClientID) + require.Equal(suite.T(), exported.Tendermint, clientType, "Incorrect ClientType stored") + root, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()) + require.Equal(suite.T(), suite.consensusState.GetRoot(), root, "Incorrect root stored") + + // Test that trying to CreateClient on existing client fails + _, err = suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + require.NotNil(suite.T(), err, "CreateClient on existing client: %s passed", testClientID) +} + +func (suite *KeeperTestSuite) TestUpdateClient() { + privVal := tmtypes.NewMockPV() + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + altSigners := []tmtypes.PrivValidator{privVal} + + // Test invalid cases all fail and do not update state + cases := []struct { + name string + malleate func() + expErr bool + }{ + {"valid update", func() {}, false}, + {"wrong client type", func() { + suite.keeper.SetClientType(suite.ctx, testClientID, testClientType) + }, true}, + {"frozen client", func() { + clientState, _ := suite.keeper.GetClientState(suite.ctx, testClientID) + clientState.Frozen = true + suite.keeper.SetClientState(suite.ctx, clientState) + }, true}, + {"past height", func() { + suite.header = tendermint.MakeHeader(2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + }, true}, + {"validatorHash incorrect", func() { + suite.header = tendermint.MakeHeader(4, altValSet, suite.valSet, altSigners) + }, true}, + {"nextHash incorrect", func() { + suite.header.NextValidatorSet = altValSet + }, true}, + {"header fails validateBasic", func() { + suite.header.ChainID = "test" + }, true}, + {"verify future commit fails", func() { + suite.consensusState.NextValidatorSet = altValSet + suite.keeper.SetConsensusState(suite.ctx, testClientID, suite.consensusState) + }, true}, + } + + for _, tc := range cases { + suite.Run(fmt.Sprintf("Case %s", tc.name), func() { + // Reset suite on each subtest + suite.SetupTest() + + _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + require.Nil(suite.T(), err, "CreateClient failed") + + tc.malleate() + err = suite.keeper.UpdateClient(suite.ctx, testClientID, suite.header) + + retrievedConsState, _ := suite.keeper.GetConsensusState(suite.ctx, testClientID) + tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) + tmConsState.NextValidatorSet.TotalVotingPower() + retrievedRoot, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()+1) + if tc.expErr { + require.NotNil(suite.T(), err, "Invalid UpdateClient passed", tc.name) + + // require no state changes occurred + require.Equal(suite.T(), suite.consensusState, tmConsState, "Consensus state changed after invalid UpdateClient") + require.Nil(suite.T(), retrievedRoot, "Root added for new height after invalid UpdateClient") + } else { + require.Nil(suite.T(), err, "Valid UpdateClient failed", tc.name) + + // require state changes were performed correctly + require.Equal(suite.T(), suite.header.GetHeight(), retrievedConsState.GetHeight(), "height not updated correctly") + require.Equal(suite.T(), commitment.NewRoot(suite.header.AppHash), retrievedConsState.GetRoot(), "root not updated correctly") + require.Equal(suite.T(), suite.header.NextValidatorSet, tmConsState.NextValidatorSet, "NextValidatorSet not updated correctly") + + } + + }) + } +} diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go new file mode 100644 index 000000000000..da81be0edb12 --- /dev/null +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -0,0 +1,102 @@ +package keeper_test + +import ( + "testing" + + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + testClientID = "gaia" +) + +type KeeperTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + keeper *keeper.Keeper + consensusState tendermint.ConsensusState + header tendermint.Header + valSet *tmtypes.ValidatorSet + privVal tmtypes.PrivValidator +} + +func (suite *KeeperTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.keeper = &app.IBCKeeper.ClientKeeper + + suite.privVal = tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + suite.header = tendermint.MakeHeader(4, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + + suite.consensusState = tendermint.ConsensusState{ + ChainID: testClientID, + Height: 3, + Root: commitment.NewRoot([]byte("hash")), + NextValidatorSet: suite.valSet, + } +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (suite *KeeperTestSuite) TestSetClientState() { + clientState := types.NewClientState(testClientID) + suite.keeper.SetClientState(suite.ctx, clientState) + + retrievedState, ok := suite.keeper.GetClientState(suite.ctx, testClientID) + require.True(suite.T(), ok, "GetClientState failed") + require.Equal(suite.T(), clientState, retrievedState, "Client states are not equal") +} + +func (suite *KeeperTestSuite) TestSetClientType() { + suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) + clientType, ok := suite.keeper.GetClientType(suite.ctx, testClientID) + + require.True(suite.T(), ok, "GetClientType failed") + require.Equal(suite.T(), exported.Tendermint, clientType, "ClientTypes not stored correctly") +} + +func (suite *KeeperTestSuite) TestSetConsensusState() { + suite.keeper.SetConsensusState(suite.ctx, testClientID, suite.consensusState) + + retrievedConsState, ok := suite.keeper.GetConsensusState(suite.ctx, testClientID) + + require.True(suite.T(), ok, "GetConsensusState failed") + tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) + // force recalculation of unexported totalVotingPower so we can compare consensusState + tmConsState.NextValidatorSet.TotalVotingPower() + require.Equal(suite.T(), suite.consensusState, tmConsState, "ConsensusState not stored correctly") +} + +func (suite *KeeperTestSuite) TestSetVerifiedRoot() { + root := commitment.NewRoot([]byte("hash")) + suite.keeper.SetVerifiedRoot(suite.ctx, testClientID, 3, root) + + retrievedRoot, ok := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, 3) + + require.True(suite.T(), ok, "GetVerifiedRoot failed") + require.Equal(suite.T(), root, retrievedRoot, "Root stored incorrectly") +} diff --git a/x/ibc/02-client/types/tendermint/consensus_state_test.go b/x/ibc/02-client/types/tendermint/consensus_state_test.go index 2f4129226228..07c1015a3067 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state_test.go +++ b/x/ibc/02-client/types/tendermint/consensus_state_test.go @@ -27,7 +27,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { // reset and make header fail validatebasic suite.SetupTest() - suite.header.ChainID = "not_mychain" + suite.header.ChainID = "not_gaia" err = suite.cs.checkValidity(suite.header) require.NotNil(suite.T(), err, "invalid header should fail ValidateBasic") } @@ -44,7 +44,7 @@ func (suite *TendermintTestSuite) TestCheckUpdate() { // make header invalid so update should be unsuccessful suite.SetupTest() - suite.header.ChainID = "not_mychain" + suite.header.ChainID = "not_gaia" cs, err = suite.cs.CheckValidityAndUpdateState(suite.header) require.NotNil(suite.T(), err) diff --git a/x/ibc/02-client/types/tendermint/tendermint_test.go b/x/ibc/02-client/types/tendermint/tendermint_test.go index 11817f73e9ff..cb3e572d6289 100644 --- a/x/ibc/02-client/types/tendermint/tendermint_test.go +++ b/x/ibc/02-client/types/tendermint/tendermint_test.go @@ -1,15 +1,12 @@ package tendermint import ( - "math" "testing" - "time" "github.com/stretchr/testify/suite" "github.com/tendermint/tendermint/crypto/tmhash" tmtypes "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/version" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -27,49 +24,11 @@ func (suite *TendermintTestSuite) SetupTest() { privVal := tmtypes.NewMockPV() val := tmtypes.NewValidator(privVal.GetPubKey(), 10) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) - vsetHash := valSet.Hash() - timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) - tmHeader := tmtypes.Header{ - Version: version.Consensus{Block: 2, App: 2}, - ChainID: "mychain", - Height: 3, - Time: timestamp, - NumTxs: 100, - TotalTxs: 1000, - LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt64, make([]byte, tmhash.Size)), - LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), - DataHash: tmhash.Sum([]byte("data_hash")), - ValidatorsHash: vsetHash, - NextValidatorsHash: vsetHash, - ConsensusHash: tmhash.Sum([]byte("consensus_hash")), - AppHash: tmhash.Sum([]byte("app_hash")), - LastResultsHash: tmhash.Sum([]byte("last_results_hash")), - EvidenceHash: tmhash.Sum([]byte("evidence_hash")), - ProposerAddress: privVal.GetPubKey().Address(), - } - hhash := tmHeader.Hash() - blockID := makeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) - voteSet := tmtypes.NewVoteSet("mychain", 3, 1, tmtypes.PrecommitType, valSet) - commit, err := tmtypes.MakeCommit(blockID, 3, 1, voteSet, []tmtypes.PrivValidator{privVal}) - if err != nil { - panic(err) - } - - signedHeader := tmtypes.SignedHeader{ - Header: &tmHeader, - Commit: commit, - } - - header := Header{ - SignedHeader: signedHeader, - ValidatorSet: valSet, - NextValidatorSet: valSet, - } - + suite.header = MakeHeader(3, valSet, valSet, []tmtypes.PrivValidator{privVal}) root := commitment.NewRoot(tmhash.Sum([]byte("my root"))) cs := ConsensusState{ - ChainID: "mychain", + ChainID: "gaia", Height: 3, Root: root, NextValidatorSet: valSet, @@ -78,7 +37,6 @@ func (suite *TendermintTestSuite) SetupTest() { // set fields in suite suite.privVal = privVal suite.valSet = valSet - suite.header = header suite.cs = cs } diff --git a/x/ibc/02-client/types/tendermint/test_utils.go b/x/ibc/02-client/types/tendermint/test_utils.go index a88bd13d3b1c..ac25a13fabbf 100644 --- a/x/ibc/02-client/types/tendermint/test_utils.go +++ b/x/ibc/02-client/types/tendermint/test_utils.go @@ -1,8 +1,12 @@ package tendermint import ( + "math" + "time" + "github.com/tendermint/tendermint/crypto/tmhash" tmtypes "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/version" ) // Copied unimported test functions from tmtypes to use them here @@ -38,10 +42,52 @@ func randomDuplicatedVoteEvidence() *tmtypes.DuplicateVoteEvidence { val := tmtypes.NewMockPV() blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), 1000, tmhash.Sum([]byte("partshash"))) blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), 1000, tmhash.Sum([]byte("partshash"))) - const chainID = "mychain" + const chainID = "gaia" return &tmtypes.DuplicateVoteEvidence{ PubKey: val.GetPubKey(), VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID), VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2), } } + +func MakeHeader(height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { + vsetHash := valSet.Hash() + nextHash := nextValSet.Hash() + timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) + tmHeader := tmtypes.Header{ + Version: version.Consensus{Block: 2, App: 2}, + ChainID: "gaia", + Height: height, + Time: timestamp, + NumTxs: 100, + TotalTxs: 1000, + LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt64, make([]byte, tmhash.Size)), + LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), + DataHash: tmhash.Sum([]byte("data_hash")), + ValidatorsHash: vsetHash, + NextValidatorsHash: nextHash, + ConsensusHash: tmhash.Sum([]byte("consensus_hash")), + AppHash: tmhash.Sum([]byte("app_hash")), + LastResultsHash: tmhash.Sum([]byte("last_results_hash")), + EvidenceHash: tmhash.Sum([]byte("evidence_hash")), + ProposerAddress: signers[0].GetPubKey().Address(), + } + hhash := tmHeader.Hash() + blockID := makeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) + voteSet := tmtypes.NewVoteSet("gaia", height, 1, tmtypes.PrecommitType, valSet) + commit, err := tmtypes.MakeCommit(blockID, height, 1, voteSet, signers) + if err != nil { + panic(err) + } + + signedHeader := tmtypes.SignedHeader{ + Header: &tmHeader, + Commit: commit, + } + + return Header{ + SignedHeader: signedHeader, + ValidatorSet: valSet, + NextValidatorSet: nextValSet, + } +} From 0c6ea220d32d7b61e59618f48052bb65ff732182 Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 21 Nov 2019 01:22:13 +0800 Subject: [PATCH 046/176] Fix proof verification; remove store key prefixes; add additional path validations (#5313) * fix poof verify * minor cleanup * fix tests * remove key prefixes * fix tests --- client/keys/root_test.go | 2 +- x/ibc/02-client/types/keys.go | 2 +- x/ibc/03-connection/keeper/handshake_test.go | 8 +- x/ibc/03-connection/keeper/keeper.go | 15 ---- x/ibc/03-connection/types/keys.go | 2 +- x/ibc/04-channel/keeper/handshake_test.go | 87 ++++++++++---------- x/ibc/04-channel/types/keys.go | 2 +- x/ibc/05-port/keeper/keeper.go | 4 + x/ibc/05-port/keeper/keeper_test.go | 7 +- x/ibc/23-commitment/merkle.go | 7 +- x/ibc/23-commitment/merkle_test.go | 3 +- x/ibc/24-host/validate.go | 10 ++- 12 files changed, 73 insertions(+), 76 deletions(-) diff --git a/client/keys/root_test.go b/client/keys/root_test.go index 49681b17e95f..2dcf912b98d8 100644 --- a/client/keys/root_test.go +++ b/client/keys/root_test.go @@ -15,7 +15,7 @@ func TestCommands(t *testing.T) { assert.NotNil(t, rootCommands) // Commands are registered - assert.Equal(t, 11, len(rootCommands.Commands())) + assert.Equal(t, 12, len(rootCommands.Commands())) } func TestMain(m *testing.M) { diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go index eba16d0c169c..acebca3ee09a 100644 --- a/x/ibc/02-client/types/keys.go +++ b/x/ibc/02-client/types/keys.go @@ -20,7 +20,7 @@ const ( // KVStore key prefixes var ( - KeyPrefixClient = []byte{0x00} + KeyPrefixClient = []byte{} ) // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index e0c0cce29c11..fede95f47fe9 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -79,12 +79,12 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { connection.GetCompatibleVersions(), proofInit, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) - suite.Nil(err) + suite.NoError(err) //check connection state conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) suite.True(existed) - suite.Equal(connection.TRYOPEN, conn.State) + suite.Equal(connection.TRYOPEN.String(), conn.State.String(), "invalid connection state") return err } @@ -172,7 +172,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { //check connection state conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID2) suite.True(existed) - suite.Equal(connection.OPEN, conn.State) + suite.Equal(connection.OPEN.String(), conn.State.String(), "invalid connection state") return err } @@ -228,7 +228,7 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { //check connection state conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) suite.True(existed) - suite.Equal(connection.OPEN, conn.State) + suite.Equal(connection.OPEN.String(), conn.State.String(), "invalid connection state") return err } diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index 337e6dd66a88..d86a527d169c 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -128,13 +128,6 @@ func (k Keeper) VerifyMembership( pathStr string, value []byte, ) bool { - // FIXME: commented out for demo - /* - clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) - if !found { - return false - } - */ path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) if err != nil { return false @@ -151,14 +144,6 @@ func (k Keeper) VerifyNonMembership( proof commitment.ProofI, pathStr string, ) bool { - // FIXME: commented out for demo - /* - clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) - if !found { - return false - } - */ - path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) if err != nil { return false diff --git a/x/ibc/03-connection/types/keys.go b/x/ibc/03-connection/types/keys.go index 40eda70e340f..dbdbc576c61d 100644 --- a/x/ibc/03-connection/types/keys.go +++ b/x/ibc/03-connection/types/keys.go @@ -20,7 +20,7 @@ const ( // KVStore key prefixes var ( - KeyPrefixConnection = []byte{0x00} + KeyPrefixConnection = []byte{} ) // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index fde534b0f26d..a383e3622bda 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -108,23 +108,23 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.NotNil(err) // channel has already exist + suite.Error(err) // channel has already exist suite.deleteChannel(testPort1, testChannel1) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.NONE) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) suite.True(found) - suite.Equal(types.INIT, channel.State) + suite.Equal(types.INIT.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanOpenTry() { @@ -137,35 +137,36 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.updateClient() proofInit, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel has already exist + suite.Error(err) // channel has already exist suite.deleteChannel(testPort2, testChannel2) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // unauthenticated port + suite.Error(err) // unauthenticated port err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.NONE) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel membership verification failed due to invalid counterparty + suite.Error(err) // channel membership verification failed due to invalid counterparty suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) + fmt.Println(proofInit) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) suite.True(found) - suite.Equal(types.OPENTRY, channel.State) + suite.Equal(types.OPENTRY.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanOpenAck() { @@ -176,40 +177,40 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { suite.updateClient() proofTry, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // channel does not exist + suite.Error(err) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // invalid channel state + suite.Error(err) // invalid channel state suite.createChannel(testPort2, testChannel1, testConnection, testPort1, testChannel2, types.INIT) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort2, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // unauthenticated port + suite.Error(err) // unauthenticated port suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.NONE) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) suite.updateClient() proofTry, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NotNil(err) // channel membership verification failed due to invalid counterparty + suite.Error(err) // channel membership verification failed due to invalid counterparty suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) suite.updateClient() proofTry, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) suite.True(found) - suite.Equal(types.OPEN, channel.State) + suite.Equal(types.OPEN.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanOpenConfirm() { @@ -220,70 +221,70 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { suite.updateClient() proofAck, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // channel does not exist + suite.Error(err) // channel does not exist suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // invalid channel state + suite.Error(err) // invalid channel state suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.OPENTRY) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort1, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // unauthenticated port + suite.Error(err) // unauthenticated port suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.NONE) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) suite.updateClient() proofAck, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NotNil(err) // channel membership verification failed due to invalid counterparty + suite.Error(err) // channel membership verification failed due to invalid counterparty suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) suite.updateClient() proofAck, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) suite.True(found) - suite.Equal(types.OPEN, channel.State) + suite.Equal(types.OPEN.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanCloseInit() { suite.bindPort(testPort1) err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort2, testChannel1) - suite.NotNil(err) // authenticated port + suite.Error(err) // authenticated port err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.NotNil(err) // channel does not exist + suite.Error(err) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.NotNil(err) // channel is already closed + suite.Error(err) // channel is already closed suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.TRYOPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) suite.True(found) - suite.Equal(types.CLOSED, channel.State) + suite.Equal(types.CLOSED.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanCloseConfirm() { @@ -294,37 +295,37 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { suite.updateClient() proofInit, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort1, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // unauthenticated port + suite.Error(err) // unauthenticated port err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel does not exist + suite.Error(err) // channel does not exist suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.CLOSED) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel is already closed + suite.Error(err) // channel is already closed suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // connection does not exist + suite.Error(err) // connection does not exist suite.createConnection(connection.TRYOPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // invalid connection state + suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NotNil(err) // channel membership verification failed due to invalid counterparty + suite.Error(err) // channel membership verification failed due to invalid counterparty suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.Nil(err) // successfully executed + suite.NoError(err) // successfully executed channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) suite.True(found) - suite.Equal(types.CLOSED, channel.State) + suite.Equal(types.CLOSED.String(), channel.State.String(), "invalid channel state") } diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go index 7849b37f90e1..27c444959ec7 100644 --- a/x/ibc/04-channel/types/keys.go +++ b/x/ibc/04-channel/types/keys.go @@ -20,7 +20,7 @@ const ( // KVStore key prefixes var ( - KeyPrefixChannel = []byte{0x00} + KeyPrefixChannel = []byte{} ) // ChannelPath defines the path under which channels are stored diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index 450c76418ef8..3d17a6881be8 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -60,5 +60,9 @@ func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { panic(err.Error()) } + if key.Name() != portID { + return false + } + return k.ports[key.Name()] } diff --git a/x/ibc/05-port/keeper/keeper_test.go b/x/ibc/05-port/keeper/keeper_test.go index f4bf12590428..320471d56030 100644 --- a/x/ibc/05-port/keeper/keeper_test.go +++ b/x/ibc/05-port/keeper/keeper_test.go @@ -1,9 +1,10 @@ package keeper_test import ( + "testing" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - "testing" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -46,10 +47,6 @@ func (suite *KeeperTestSuite) TestBind() { capKey := suite.keeper.BindPort(validPort) require.NotNil(suite.T(), capKey, "capabilityKey is nil on valid BindPort") - // Test that port is added to bound list after BindPort is called - ports := suite.keeper.GetPorts() - require.Equal(suite.T(), []string{validPort}, ports, "portID not added to bound list") - // Test that rebinding the same portid causes panic require.Panics(suite.T(), func() { suite.keeper.BindPort(validPort) }, "did not panic on re-binding the same port") } diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/merkle.go index 3c41559f4b4f..33d84408f997 100644 --- a/x/ibc/23-commitment/merkle.go +++ b/x/ibc/23-commitment/merkle.go @@ -91,8 +91,13 @@ func (Path) GetCommitmentType() Type { return Merkle } -// String implements fmt.Stringer. It returns unescaped path of the URL string. +// String implements fmt.Stringer. func (p Path) String() string { + return p.KeyPath.String() +} + +// Pretty returns the unescaped path of the URL string. +func (p Path) Pretty() string { path, err := url.PathUnescape(p.KeyPath.String()) if err != nil { panic(err) diff --git a/x/ibc/23-commitment/merkle_test.go b/x/ibc/23-commitment/merkle_test.go index bfd2dc5a485c..01dc9f2edcb4 100644 --- a/x/ibc/23-commitment/merkle_test.go +++ b/x/ibc/23-commitment/merkle_test.go @@ -112,7 +112,8 @@ func TestApplyPrefix(t *testing.T) { prefixedPath, err := commitment.ApplyPrefix(prefix, pathStr) require.Nil(t, err, "valid prefix returns error") - require.Equal(t, "/storePrefixKey/path1/path2/path3/key", prefixedPath.String(), "Prefixed path incorrect") + require.Equal(t, "/storePrefixKey/path1/path2/path3/key", prefixedPath.Pretty(), "Prefixed path incorrect") + require.Equal(t, "/storePrefixKey/path1%2Fpath2%2Fpath3%2Fkey", prefixedPath.String(), "Prefixed scaped path incorrect") // invalid prefix contains non-alphanumeric character invalidPathStr := "invalid-path/doesitfail?/hopefully" diff --git a/x/ibc/24-host/validate.go b/x/ibc/24-host/validate.go index 8c20c0065282..f6b3d14751e7 100644 --- a/x/ibc/24-host/validate.go +++ b/x/ibc/24-host/validate.go @@ -88,10 +88,14 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { // checking that all path elements are alphanumeric func DefaultPathValidator(path string) error { pathArr := strings.Split(path, "/") + if pathArr[0] == path { + return sdkerrors.Wrap(ErrInvalidPath(DefaultCodespace, path), "path doesn't contain any separator '/'") + } + for _, p := range pathArr { - // Each path element must either be alphanumeric - if !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "invalid path element containing non-alphanumeric characters: %s", p) + // Each path element must be alphanumeric and non-blank + if strings.TrimSpace(p) == "" || !isAlphaNumeric(p) { + return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "invalid path element containing non-alphanumeric characters: '%s'", p) } } return nil From 296628608d55f0d082c0e37ad947e08e5ceef8af Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 21 Nov 2019 18:33:22 +0800 Subject: [PATCH 047/176] Add ICS20 tests (#5308) * add ics20 test * delete debug * fix ics20 test * revert and modify * optimize test * add ics20 msg test * fix test * add packet tests and more msgs tests * add ReceivePacket and callbacks tests * fix callbacks test * add handler tests for ics20 * fix handler tests * minor cleanup * test all positive amounts * update test suite NotNil to Error * fix ics20 tests * expected error --- x/ibc/04-channel/keeper/handshake_test.go | 2 +- x/ibc/05-port/alias.go | 1 + x/ibc/20-transfer/alias.go | 1 - x/ibc/20-transfer/handler_test.go | 271 ++++++++++++++++++++ x/ibc/20-transfer/keeper/callbacks.go | 71 +++--- x/ibc/20-transfer/keeper/callbacks_test.go | 168 +++++++++++++ x/ibc/20-transfer/keeper/keeper_test.go | 61 ++++- x/ibc/20-transfer/keeper/relay.go | 29 +-- x/ibc/20-transfer/keeper/relay_test.go | 279 ++++++++++++++++++++- x/ibc/20-transfer/types/msgs.go | 10 +- x/ibc/20-transfer/types/msgs_test.go | 189 ++++++++++++++ x/ibc/20-transfer/types/packet.go | 37 +-- x/ibc/20-transfer/types/packet_test.go | 39 +++ 13 files changed, 1061 insertions(+), 97 deletions(-) create mode 100644 x/ibc/20-transfer/handler_test.go create mode 100644 x/ibc/20-transfer/keeper/callbacks_test.go create mode 100644 x/ibc/20-transfer/types/msgs_test.go create mode 100644 x/ibc/20-transfer/types/packet_test.go diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index a383e3622bda..efd704c28d21 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -80,7 +80,7 @@ func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID } func (suite *KeeperTestSuite) deleteChannel(portID string, chanID string) { - store := prefix.NewStore(suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)), []byte{}) + store := prefix.NewStore(suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)), types.KeyPrefixChannel) store.Delete(types.KeyChannel(portID, chanID)) } diff --git a/x/ibc/05-port/alias.go b/x/ibc/05-port/alias.go index de0907a93212..ef3b6be60633 100644 --- a/x/ibc/05-port/alias.go +++ b/x/ibc/05-port/alias.go @@ -26,6 +26,7 @@ var ( NewKeeper = keeper.NewKeeper ErrPortExists = types.ErrPortExists ErrPortNotFound = types.ErrPortNotFound + ErrInvalidPort = types.ErrInvalidPort PortPath = types.PortPath KeyPort = types.KeyPort ) diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go index ab75c9dab2d2..ee87c56d8b3e 100644 --- a/x/ibc/20-transfer/alias.go +++ b/x/ibc/20-transfer/alias.go @@ -45,5 +45,4 @@ type ( MsgTransfer = types.MsgTransfer MsgRecvPacket = types.MsgRecvPacket PacketData = types.PacketData - PacketDataAlias = types.PacketDataAlias ) diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go new file mode 100644 index 000000000000..89fad1195d09 --- /dev/null +++ b/x/ibc/20-transfer/handler_test.go @@ -0,0 +1,271 @@ +package transfer_test + +import ( + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/cosmos/cosmos-sdk/x/supply" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" +) + +// define constants used for testing +const ( + testChainID = "test-chain-id" + testClient = "test-client" + testClientType = clientexported.Tendermint + + testConnection = "testconnection" + testPort1 = "bank" + testPort2 = "testportid" + testChannel1 = "firstchannel" + testChannel2 = "secondchannel" + + testChannelOrder = channel.UNORDERED + testChannelVersion = "1.0" +) + +// define variables used for testing +var ( + testAddr1 = sdk.AccAddress([]byte("testaddr1")) + testAddr2 = sdk.AccAddress([]byte("testaddr2")) + + testCoins, _ = sdk.ParseCoins("100atom") + testPrefixedCoins1, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort1, testChannel1))) + testPrefixedCoins2, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort2, testChannel2))) +) + +type HandlerTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp +} + +func (suite *HandlerTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.app = app + + suite.createClient() + suite.createConnection(connection.OPEN) +} + +func (suite *HandlerTestSuite) createClient() { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + suite.NoError(err) +} + +func (suite *HandlerTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) +} + +func (suite *HandlerTestSuite) createConnection(state connection.State) { + connection := connection.ConnectionEnd{ + State: state, + ClientID: testClient, + Counterparty: connection.Counterparty{ + ClientID: testClient, + ConnectionID: testConnection, + Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + }, + Versions: connection.GetCompatibleVersions(), + } + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) +} + +func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channel.State) { + ch := channel.Channel{ + State: state, + Ordering: testChannelOrder, + Counterparty: channel.Counterparty{ + PortID: counterpartyPort, + ChannelID: counterpartyChan, + }, + ConnectionHops: []string{connID}, + Version: testChannelVersion, + } + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) +} + +func (suite *HandlerTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + +func (suite *HandlerTestSuite) TestHandleMsgTransfer() { + source := true + + msg := transfer.NewMsgTransfer(testPort1, testChannel1, testCoins, testAddr1, testAddr2, source) + res := transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // channel does not exist + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // next send sequence not found + + nextSeqSend := uint64(1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // sender has insufficient coins + + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.True(res.Code.IsOK(), "%v", res) // successfully executed + + // test when the source is false + source = false + + msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, source) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // incorrect denom prefix + + msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, source) + suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) + res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.True(res.Code.IsOK(), "%v", res) // successfully executed +} + +func (suite *HandlerTestSuite) TestHandleRecvPacket() { + packetSeq := uint64(1) + packetTimeout := uint64(100) + + packetDataBz := []byte("invaliddata") + packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + packetCommitmentPath := channel.PacketCommitmentPath(testPort2, testChannel2, packetSeq) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) + suite.updateClient() + proofPacket, proofHeight := suite.queryProof(packetCommitmentPath) + + msg := types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + res := transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // packet membership verification failed due to invalid counterparty packet commitment + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // invalid packet data + + // test when the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.True(res.Code.IsOK(), "%v", res) // successfully executed + + // test when the source is false + source = false + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + + msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.False(res.Code.IsOK(), "%v", res) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.True(res.Code.IsOK(), "%v", res) // successfully executed +} + +func TestHandlerTestSuite(t *testing.T) { + suite.Run(t, new(HandlerTestSuite)) +} diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go index 444e966b97c8..57c772e67b2f 100644 --- a/x/ibc/20-transfer/keeper/callbacks.go +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -6,36 +6,36 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // nolint: unused -func (k Keeper) onChanOpenInit( +func (k Keeper) OnChanOpenInit( ctx sdk.Context, - order channeltypes.Order, + order channel.Order, connectionHops []string, portID, channelID string, - counterparty channeltypes.Counterparty, + counterparty channel.Counterparty, version string, ) error { - if order != channeltypes.UNORDERED { - return channeltypes.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") + if order != channel.UNORDERED { + return channel.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") } // NOTE: here the capability key name defines the port ID of the counterparty if counterparty.PortID != k.boundedCapability.Name() { - return porttypes.ErrInvalidPort( + return port.ErrInvalidPort( k.codespace, - fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", portID, k.boundedCapability.Name()), - ) + fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name())) } if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") + return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -44,34 +44,33 @@ func (k Keeper) onChanOpenInit( } // nolint: unused -func (k Keeper) onChanOpenTry( +func (k Keeper) OnChanOpenTry( ctx sdk.Context, - order channeltypes.Order, + order channel.Order, connectionHops []string, portID, channelID string, - counterparty channeltypes.Counterparty, + counterparty channel.Counterparty, version string, counterpartyVersion string, ) error { - if order != channeltypes.UNORDERED { - return channeltypes.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") + if order != channel.UNORDERED { + return channel.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") } // NOTE: here the capability key name defines the port ID of the counterparty if counterparty.PortID != k.boundedCapability.Name() { - return porttypes.ErrInvalidPort( + return port.ErrInvalidPort( k.codespace, - fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", portID, k.boundedCapability.Name()), - ) + fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name())) } if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") + return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") } if strings.TrimSpace(counterpartyVersion) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "counterparty version cannot be blank") + return ibctypes.ErrInvalidVersion(k.codespace, "counterparty version must be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -80,21 +79,21 @@ func (k Keeper) onChanOpenTry( } // nolint: unused -func (k Keeper) onChanOpenAck( +func (k Keeper) OnChanOpenAck( ctx sdk.Context, portID, channelID string, version string, ) error { if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version cannot be blank") + return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") } return nil } // nolint: unused -func (k Keeper) onChanOpenConfirm( +func (k Keeper) OnChanOpenConfirm( ctx sdk.Context, portID, channelID string, @@ -104,7 +103,7 @@ func (k Keeper) onChanOpenConfirm( } // nolint: unused -func (k Keeper) onChanCloseInit( +func (k Keeper) OnChanCloseInit( ctx sdk.Context, portID, channelID string, @@ -114,7 +113,7 @@ func (k Keeper) onChanCloseInit( } // nolint: unused -func (k Keeper) onChanCloseConfirm( +func (k Keeper) OnChanCloseConfirm( ctx sdk.Context, portID, channelID string, @@ -125,13 +124,13 @@ func (k Keeper) onChanCloseConfirm( // onRecvPacket is called when an FTTransfer packet is received // nolint: unused -func (k Keeper) onRecvPacket( +func (k Keeper) OnRecvPacket( ctx sdk.Context, - packet channeltypes.Packet, + packet channelexported.PacketI, ) error { var data types.PacketData - err := data.UnmarshalJSON(packet.GetData()) + err := k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) if err != nil { return sdkerrors.Wrap(err, "invalid packet data") } @@ -143,9 +142,9 @@ func (k Keeper) onRecvPacket( } // nolint: unused -func (k Keeper) onAcknowledgePacket( +func (k Keeper) OnAcknowledgePacket( ctx sdk.Context, - packet channeltypes.Packet, + packet channelexported.PacketI, acknowledgement []byte, ) error { // no-op @@ -153,19 +152,19 @@ func (k Keeper) onAcknowledgePacket( } // nolint: unused -func (k Keeper) onTimeoutPacket( +func (k Keeper) OnTimeoutPacket( ctx sdk.Context, - packet channeltypes.Packet, + packet channelexported.PacketI, ) error { var data types.PacketData - err := data.UnmarshalJSON(packet.GetData()) + err := k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) if err != nil { return sdkerrors.Wrap(err, "invalid packet data") } // check the denom prefix - prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourcePort()) + prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) coins := make(sdk.Coins, len(data.Amount)) for i, coin := range data.Amount { coin := coin @@ -190,6 +189,6 @@ func (k Keeper) onTimeoutPacket( } // nolint: unused -func (k Keeper) onTimeoutPacketClose(_ sdk.Context, _ channeltypes.Packet) { +func (k Keeper) OnTimeoutPacketClose(_ sdk.Context, _ channelexported.PacketI) { panic("can't happen, only unordered channels allowed") } diff --git a/x/ibc/20-transfer/keeper/callbacks_test.go b/x/ibc/20-transfer/keeper/callbacks_test.go new file mode 100644 index 000000000000..fb505cf190ac --- /dev/null +++ b/x/ibc/20-transfer/keeper/callbacks_test.go @@ -0,0 +1,168 @@ +package keeper_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +func (suite *KeeperTestSuite) TestOnChanOpenInit() { + invalidOrder := channel.ORDERED + + counterparty := channel.NewCounterparty(testPort2, testChannel2) + err := suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, invalidOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "") + suite.Error(err) // invalid channel order + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "") + suite.Error(err) // invalid counterparty port ID + + counterparty = channel.NewCounterparty(testPort1, testChannel2) + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) + suite.Error(err) // invalid version + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "") + suite.NoError(err) // successfully executed +} + +func (suite *KeeperTestSuite) TestOnChanOpenTry() { + invalidOrder := channel.ORDERED + + counterparty := channel.NewCounterparty(testPort2, testChannel2) + err := suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, invalidOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", "") + suite.Error(err) // invalid channel order + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", "") + suite.Error(err) // invalid counterparty port ID + + counterparty = channel.NewCounterparty(testPort1, testChannel2) + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion, "") + suite.Error(err) // invalid version + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", testChannelVersion) + suite.Error(err) // invalid counterparty version + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", "") + suite.NoError(err) // successfully executed +} + +func (suite *KeeperTestSuite) TestOnChanOpenAck() { + err := suite.app.IBCKeeper.TransferKeeper.OnChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion) + suite.Error(err) // invalid version + + err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenAck(suite.ctx, testPort1, testChannel1, "") + suite.NoError(err) // successfully executed +} + +func (suite *KeeperTestSuite) TestOnRecvPacket() { + packetSeq := uint64(1) + packetTimeout := uint64(100) + + packetDataBz := []byte("invaliddata") + packet := channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + err := suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.Error(err) // invalid packet data + + // when the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.NoError(err) // successfully executed + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(testPrefixedCoins2, totalSupply.GetTotal()) // supply should be inflated + + receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testPrefixedCoins2, receiverCoins) + + // when the source is false + source = false + + packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.Error(err) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) + err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) + suite.NoError(err) // successfully executed + + receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testCoins, receiverCoins) +} + +func (suite *KeeperTestSuite) TestOnTimeoutPacket() { + packetSeq := uint64(1) + packetTimeout := uint64(100) + + packetDataBz := []byte("invaliddata") + packet := channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + err := suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.Error(err) // invalid packet data + + // when the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.Error(err) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.NoError(err) // successfully executed + + senderCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Sender) + suite.Equal(testCoins, senderCoins) + + escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) + suite.Equal(sdk.Coins(nil), escrowCoins) + + // when the source is false + source = false + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) + + _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Sender, sdk.Coins{}) + err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) + suite.NoError(err) // successfully executed + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(testPrefixedCoins1, totalSupply.GetTotal()) // supply should be inflated + + senderCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Sender) + suite.Equal(testPrefixedCoins1, senderCoins) +} diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index 77c423052098..e5023a662caf 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -1,24 +1,53 @@ package keeper_test import ( + "fmt" "testing" - "github.com/stretchr/testify/suite" - - abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/keeper" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" +) + +// define constants used for testing +const ( + testChainID = "test-chain-id" + testClient = "test-client" + testClientType = clientexported.Tendermint + + testConnection = "testconnection" + testPort1 = "bank" + testPort2 = "testportid" + testChannel1 = "firstchannel" + testChannel2 = "secondchannel" + + testChannelOrder = channel.UNORDERED + testChannelVersion = "1.0" +) + +// define variables used for testing +var ( + testAddr1 = sdk.AccAddress([]byte("testaddr1")) + testAddr2 = sdk.AccAddress([]byte("testaddr2")) + + testCoins, _ = sdk.ParseCoins("100atom") + testPrefixedCoins1, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort1, testChannel1))) + testPrefixedCoins2, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort2, testChannel2))) ) type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - keeper *keeper.Keeper + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp } func (suite *KeeperTestSuite) SetupTest() { @@ -27,7 +56,21 @@ func (suite *KeeperTestSuite) SetupTest() { suite.cdc = app.Codec() suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) - suite.keeper = &app.IBCKeeper.TransferKeeper + suite.app = app + + suite.createClient() + suite.createConnection(connection.OPEN) +} + +func (suite *KeeperTestSuite) TestGetTransferAccount() { + expectedMaccName := types.GetModuleAccountName() + expectedMaccAddr := sdk.AccAddress(crypto.AddressHash([]byte(expectedMaccName))) + + macc := suite.app.IBCKeeper.TransferKeeper.GetTransferAccount(suite.ctx) + + suite.NotNil(macc) + suite.Equal(expectedMaccName, macc.GetName()) + suite.Equal(expectedMaccAddr, macc.GetAddress()) } func TestKeeperTestSuite(t *testing.T) { diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index dae2180dc44f..8c3a6bb2ea5b 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -7,7 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -23,18 +23,18 @@ func (k Keeper) SendTransfer( isSourceChain bool, ) error { // get the port and channel of the counterparty - channel, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) + sourceChan, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) if !found { - return channeltypes.ErrChannelNotFound(k.codespace, sourcePort, sourceChannel) + return channel.ErrChannelNotFound(k.codespace, sourcePort, sourceChannel) } - destinationPort := channel.Counterparty.PortID - destinationChannel := channel.Counterparty.ChannelID + destinationPort := sourceChan.Counterparty.PortID + destinationChannel := sourceChan.Counterparty.ChannelID // get the next sequence sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel) if !found { - return channeltypes.ErrSequenceNotFound(k.codespace, "send") + return channel.ErrSequenceNotFound(k.codespace, "send") } coins := make(sdk.Coins, len(amount)) @@ -54,13 +54,13 @@ func (k Keeper) SendTransfer( // ReceivePacket handles receiving packet func (k Keeper) ReceivePacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, height uint64) error { - _, err := k.channelKeeper.RecvPacket(ctx, packet, proof, height, nil, k.storeKey) + _, err := k.channelKeeper.RecvPacket(ctx, packet, proof, height, []byte{}, k.boundedCapability) if err != nil { return err } var data types.PacketData - err = data.UnmarshalJSON(packet.GetData()) + err = k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) if err != nil { return sdkerrors.Wrap(err, "invalid packet data") } @@ -164,20 +164,15 @@ func (k Keeper) createOutgoingPacket( } } - packetData := types.PacketData{ - Amount: amount, - Sender: sender, - Receiver: receiver, - Source: isSourceChain, - } + packetData := types.NewPacketData(amount, sender, receiver, isSourceChain) - // TODO: This should be binary-marshaled and hashed (for the commitment in the store). - packetDataBz, err := packetData.MarshalJSON() + // TODO: This should be hashed (for the commitment in the store). + packetDataBz, err := k.cdc.MarshalBinaryBare(packetData) if err != nil { return sdkerrors.Wrap(err, "invalid packet data") } - packet := channeltypes.NewPacket( + packet := channel.NewPacket( seq, uint64(ctx.BlockHeight())+DefaultPacketTimeout, sourcePort, diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index e6aa98f9eacd..7546fc48a98c 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -1,6 +1,281 @@ package keeper_test +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/cosmos/cosmos-sdk/x/supply" + abci "github.com/tendermint/tendermint/abci/types" +) + +func (suite *KeeperTestSuite) createClient() { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + suite.NoError(err) +} + +func (suite *KeeperTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) +} + +func (suite *KeeperTestSuite) createConnection(state connection.State) { + connection := connection.ConnectionEnd{ + State: state, + ClientID: testClient, + Counterparty: connection.Counterparty{ + ClientID: testClient, + ConnectionID: testConnection, + Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + }, + Versions: connection.GetCompatibleVersions(), + } + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) +} + +func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channel.State) { + ch := channel.Channel{ + State: state, + Ordering: testChannelOrder, + Counterparty: channel.Counterparty{ + PortID: counterpartyPort, + ChannelID: counterpartyChan, + }, + ConnectionHops: []string{connID}, + Version: testChannelVersion, + } + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) +} + +func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + func (suite *KeeperTestSuite) TestSendTransfer() { - err := suite.keeper.SendTransfer(suite.ctx, "", "", nil, nil, nil, true) - suite.Error(err) + // test the situation where the source is true + isSourceChain := true + + err := suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + suite.Error(err) // channel does not exist + + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + suite.Error(err) // next send sequence not found + + nextSeqSend := uint64(1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + suite.Error(err) // sender has insufficient coins + + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + suite.NoError(err) // successfully executed + + senderCoins := suite.app.BankKeeper.GetCoins(suite.ctx, testAddr1) + suite.Equal(sdk.Coins(nil), senderCoins) + + escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, types.GetEscrowAddress(testPort1, testChannel1)) + suite.Equal(testCoins, escrowCoins) + + newNextSeqSend, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + suite.True(found) + suite.Equal(nextSeqSend+1, newNextSeqSend) + + packetCommitment := suite.app.IBCKeeper.ChannelKeeper.GetPacketCommitment(suite.ctx, testPort1, testChannel1, nextSeqSend) + suite.NotNil(packetCommitment) + + // test the situation where the source is false + isSourceChain = false + + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, isSourceChain) + suite.Error(err) // incorrect denom prefix + + suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) + err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, isSourceChain) + suite.NoError(err) // successfully executed + + senderCoins = suite.app.BankKeeper.GetCoins(suite.ctx, testAddr1) + suite.Equal(sdk.Coins(nil), senderCoins) + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(sdk.Coins(nil), totalSupply.GetTotal()) // supply should be deflated +} + +func (suite *KeeperTestSuite) TestReceiveTransfer() { + // test the situation where the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + err := suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.Error(err) // incorrect denom prefix + + packetData.Amount = testPrefixedCoins2 + err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.NoError(err) // successfully executed + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(testPrefixedCoins2, totalSupply.GetTotal()) // supply should be inflated + + receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testPrefixedCoins2, receiverCoins) + + // test the situation where the source is false + packetData.Source = false + + packetData.Amount = testPrefixedCoins2 + err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.Error(err) // incorrect denom prefix + + packetData.Amount = testPrefixedCoins1 + err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.Error(err) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) + err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + suite.NoError(err) // successfully executed + + escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) + suite.Equal(sdk.Coins(nil), escrowCoins) + + receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testCoins, receiverCoins) +} + +func (suite *KeeperTestSuite) TestReceivePacket() { + packetSeq := uint64(1) + packetTimeout := uint64(100) + + packetDataBz := []byte("invaliddata") + packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort2, testChannel1, packetDataBz) + packetCommitmentPath := channel.PacketCommitmentPath(testPort2, testChannel2, packetSeq) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) + suite.updateClient() + proofPacket, proofHeight := suite.queryProof(packetCommitmentPath) + + suite.createChannel(testPort2, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + err := suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // invalid port id + + packet.DestinationPort = testPort1 + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // packet membership verification failed due to invalid counterparty packet commitment + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // invalid packet data + + // test the situation where the source is true + source := true + + packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.NoError(err) // successfully executed + + totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) + suite.Equal(testPrefixedCoins1, totalSupply.GetTotal()) // supply should be inflated + + receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testPrefixedCoins1, receiverCoins) + + // test the situation where the source is false + source = false + + packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // invalid denom prefix + + packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) + packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) + packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) + + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) + suite.updateClient() + proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.Error(err) // insufficient coins in the corresponding escrow account + + escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) + _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) + err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) + suite.NoError(err) // successfully executed + + receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) + suite.Equal(testCoins, receiverCoins) + + escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) + suite.Equal(sdk.Coins(nil), escrowCoins) } diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index d0e7d9fbbe72..2a353de56cff 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -45,18 +45,18 @@ func (MsgTransfer) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgTransfer) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.SourcePort); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.SourcePort); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.SourceChannel); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.SourceChannel); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source channel ID")) } - if !msg.Amount.IsValid() { - return sdk.ErrInvalidCoins("transfer amount is invalid") - } if !msg.Amount.IsAllPositive() { return sdk.ErrInsufficientCoins("transfer amount must be positive") } + if !msg.Amount.IsValid() { + return sdk.ErrInvalidCoins("transfer amount is invalid") + } if msg.Sender.Empty() { return sdk.ErrInvalidAddress("missing sender address") } diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go new file mode 100644 index 000000000000..f0b500b10d2f --- /dev/null +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -0,0 +1,189 @@ +package types + +import ( + "fmt" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/merkle" +) + +// define constants used for testing +const ( + invalidPort = "invalidport1" + invalidShortPort = "p" + invalidLongPort = "invalidlongportinvalidlongport" + + invalidChannel = "invalidchannel1" + invalidShortChannel = "invalidch" + invalidLongChannel = "invalidlongchannelinvalidlongchannel" +) + +// define variables used for testing +var ( + packet = channel.NewPacket(1, 100, "testportid", "testchannel", "testcpport", "testcpchannel", []byte("testdata")) + invalidPacket = channel.NewPacket(0, 100, "testportid", "testchannel", "testcpport", "testcpchannel", []byte{}) + + proof = commitment.Proof{Proof: &merkle.Proof{}} + emptyProof = commitment.Proof{Proof: nil} + proofs = []commitment.Proof{proof} + invalidProofs1 = []commitment.Proof{} + invalidProofs2 = []commitment.Proof{emptyProof} + + addr1 = sdk.AccAddress("testaddr1") + addr2 = sdk.AccAddress("testaddr2") + emptyAddr sdk.AccAddress + + coins, _ = sdk.ParseCoins("100atom") + invalidDenomCoins = sdk.Coins{sdk.Coin{Denom: "ato-m", Amount: sdk.NewInt(100)}} + negativeCoins = sdk.Coins{sdk.Coin{Denom: "atom", Amount: sdk.NewInt(100)}, sdk.Coin{Denom: "atoms", Amount: sdk.NewInt(-100)}} +) + +// TestMsgTransferRoute tests Route for MsgTransfer +func TestMsgTransferRoute(t *testing.T) { + msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + + require.Equal(t, ibctypes.RouterKey, msg.Route()) +} + +// TestMsgTransferType tests Type for MsgTransfer +func TestMsgTransferType(t *testing.T) { + msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + + require.Equal(t, "transfer", msg.Type()) +} + +// TestMsgTransferValidation tests ValidateBasic for MsgTransfer +func TestMsgTransferValidation(t *testing.T) { + testMsgs := []MsgTransfer{ + NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true), // valid msg + NewMsgTransfer(invalidShortPort, "testchannel", coins, addr1, addr2, true), // too short port id + NewMsgTransfer(invalidLongPort, "testchannel", coins, addr1, addr2, true), // too long port id + NewMsgTransfer(invalidPort, "testchannel", coins, addr1, addr2, true), // port id contains non-alpha + NewMsgTransfer("testportid", invalidShortChannel, coins, addr1, addr2, true), // too short channel id + NewMsgTransfer("testportid", invalidLongChannel, coins, addr1, addr2, false), // too long channel id + NewMsgTransfer("testportid", invalidChannel, coins, addr1, addr2, false), // channel id contains non-alpha + NewMsgTransfer("testportid", "testchannel", invalidDenomCoins, addr1, addr2, false), // invalid amount + NewMsgTransfer("testportid", "testchannel", negativeCoins, addr1, addr2, false), // amount contains negative coin + NewMsgTransfer("testportid", "testchannel", coins, emptyAddr, addr2, false), // missing sender address + NewMsgTransfer("testportid", "testchannel", coins, addr1, emptyAddr, false), // missing recipient address + NewMsgTransfer("testportid", "testchannel", sdk.Coins{}, addr1, addr2, false), // not possitive coin + } + + testCases := []struct { + msg MsgTransfer + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "too short port id"}, + {testMsgs[2], false, "too long port id"}, + {testMsgs[3], false, "port id contains non-alpha"}, + {testMsgs[4], false, "too short channel id"}, + {testMsgs[5], false, "too long channel id"}, + {testMsgs[6], false, "channel id contains non-alpha"}, + {testMsgs[7], false, "invalid amount"}, + {testMsgs[8], false, "amount contains negative coin"}, + {testMsgs[9], false, "missing sender address"}, + {testMsgs[10], false, "missing recipient address"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "Msg %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgTransferGetSignBytes tests GetSignBytes for MsgTransfer +func TestMsgTransferGetSignBytes(t *testing.T) { + msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + res := msg.GetSignBytes() + + expected := `{"type":"ibc/transfer/MsgTransfer","value":{"amount":[{"amount":"100","denom":"atom"}],"receiver":"cosmos1w3jhxarpv3j8yvs7f9y7g","sender":"cosmos1w3jhxarpv3j8yvg4ufs4x","source":true,"source_channel":"testchannel","source_port":"testportid"}}` + require.Equal(t, expected, string(res)) +} + +// TestMsgTransferGetSigners tests GetSigners for MsgTransfer +func TestMsgTransferGetSigners(t *testing.T) { + msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + res := msg.GetSigners() + + expected := "[746573746164647231]" + require.Equal(t, expected, fmt.Sprintf("%v", res)) +} + +// TestMsgRecvPacketRoute tests Route for MsgRecvPacket +func TestMsgRecvPacketRoute(t *testing.T) { + msg := NewMsgRecvPacket(packet, proofs, 1, addr1) + + require.Equal(t, ibctypes.RouterKey, msg.Route()) +} + +// TestMsgRecvPacketType tests Type for MsgRecvPacket +func TestMsgRecvPacketType(t *testing.T) { + msg := NewMsgRecvPacket(packet, proofs, 1, addr1) + + require.Equal(t, "recv_packet", msg.Type()) +} + +// TestMsgRecvPacketValidation tests ValidateBasic for MsgRecvPacket +func TestMsgRecvPacketValidation(t *testing.T) { + testMsgs := []MsgRecvPacket{ + NewMsgRecvPacket(packet, proofs, 1, addr1), // valid msg + NewMsgRecvPacket(packet, proofs, 0, addr1), // proof height is zero + NewMsgRecvPacket(packet, nil, 1, addr1), // missing proofs + NewMsgRecvPacket(packet, invalidProofs1, 1, addr1), // missing proofs + NewMsgRecvPacket(packet, invalidProofs2, 1, addr1), // proofs contain empty proof + NewMsgRecvPacket(packet, proofs, 1, emptyAddr), // missing signer address + NewMsgRecvPacket(invalidPacket, proofs, 1, addr1), // invalid packet + } + + testCases := []struct { + msg MsgRecvPacket + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "proof height is zero"}, + {testMsgs[2], false, "missing proofs"}, + {testMsgs[3], false, "missing proofs"}, + {testMsgs[4], false, "proofs contain empty proof"}, + {testMsgs[5], false, "missing signer address"}, + {testMsgs[6], false, "invalid packet"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "Msg %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgRecvPacketGetSignBytes tests GetSignBytes for MsgRecvPacket +func TestMsgRecvPacketGetSignBytes(t *testing.T) { + msg := NewMsgRecvPacket(packet, proofs, 1, addr1) + res := msg.GetSignBytes() + + expected := `{"type":"ibc/transfer/MsgRecvPacket","value":{"height":"1","packet":{"type":"ibc/channel/Packet","value":{"data":"dGVzdGRhdGE=","destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid","timeout":"100"}},"proofs":[{"proof":{"ops":[]}}],"signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}}` + require.Equal(t, expected, string(res)) +} + +// TestMsgRecvPacketGetSigners tests GetSigners for MsgRecvPacket +func TestMsgRecvPacketGetSigners(t *testing.T) { + msg := NewMsgRecvPacket(packet, proofs, 1, addr1) + res := msg.GetSigners() + + expected := "[746573746164647231]" + require.Equal(t, expected, fmt.Sprintf("%v", res)) +} diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go index a9df673cc19f..f7c79b9be07e 100644 --- a/x/ibc/20-transfer/types/packet.go +++ b/x/ibc/20-transfer/types/packet.go @@ -1,7 +1,6 @@ package types import ( - "encoding/json" "fmt" sdk "github.com/cosmos/cosmos-sdk/types" @@ -15,28 +14,14 @@ type PacketData struct { Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred } -func (pd PacketData) MarshalAmino() ([]byte, error) { - return ModuleCdc.MarshalBinaryBare(pd) -} - -func (pd *PacketData) UnmarshalAmino(bz []byte) (err error) { - return ModuleCdc.UnmarshalBinaryBare(bz, pd) -} - -func (pd PacketData) Marshal() []byte { - return ModuleCdc.MustMarshalBinaryBare(pd) -} - -type PacketDataAlias PacketData - -// MarshalJSON implements the json.Marshaler interface. -func (pd PacketData) MarshalJSON() ([]byte, error) { - return json.Marshal((PacketDataAlias)(pd)) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (pd *PacketData) UnmarshalJSON(bz []byte) (err error) { - return json.Unmarshal(bz, (*PacketDataAlias)(pd)) +// NewPacketData contructs a new PacketData +func NewPacketData(amount sdk.Coins, sender, receiver sdk.AccAddress, source bool) PacketData { + return PacketData{ + Amount: amount, + Sender: sender, + Receiver: receiver, + Source: source, + } } func (pd PacketData) String() string { @@ -54,12 +39,12 @@ func (pd PacketData) String() string { // ValidateBasic performs a basic check of the packet fields func (pd PacketData) ValidateBasic() sdk.Error { - if !pd.Amount.IsValid() { - return sdk.ErrInvalidCoins("transfer amount is invalid") - } if !pd.Amount.IsAllPositive() { return sdk.ErrInsufficientCoins("transfer amount must be positive") } + if !pd.Amount.IsValid() { + return sdk.ErrInvalidCoins("transfer amount is invalid") + } if pd.Sender.Empty() { return sdk.ErrInvalidAddress("missing sender address") } diff --git a/x/ibc/20-transfer/types/packet_test.go b/x/ibc/20-transfer/types/packet_test.go new file mode 100644 index 000000000000..8471fb0cf2da --- /dev/null +++ b/x/ibc/20-transfer/types/packet_test.go @@ -0,0 +1,39 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// TestPacketDataValidation tests ValidateBasic for PacketData +func TestPacketDataValidation(t *testing.T) { + testPacketData := []PacketData{ + NewPacketData(coins, addr1, addr2, true), // valid msg + NewPacketData(invalidDenomCoins, addr1, addr2, true), // invalid amount + NewPacketData(negativeCoins, addr1, addr2, false), // amount contains negative coin + NewPacketData(coins, emptyAddr, addr2, false), // missing sender address + NewPacketData(coins, addr1, emptyAddr, false), // missing recipient address + } + + testCases := []struct { + packetData PacketData + expPass bool + errMsg string + }{ + {testPacketData[0], true, ""}, + {testPacketData[1], false, "invalid amount"}, + {testPacketData[2], false, "amount contains negative coin"}, + {testPacketData[3], false, "missing sender address"}, + {testPacketData[4], false, "missing recipient address"}, + } + + for i, tc := range testCases { + err := tc.packetData.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "PacketData %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid PacketData %d passed: %s", i, tc.errMsg) + } + } +} From 77718c17f717d1c1a6983f6a388fe9833ae093ca Mon Sep 17 00:00:00 2001 From: vincent Date: Mon, 2 Dec 2019 16:44:55 +0800 Subject: [PATCH 048/176] Add IBC REST endpoints (#5310) * add rest framework * add rest endpoints for ibc connection * add rest endpoints for ibc client * add rest endpoints for ibc channel * modify ibc rest api * add rest endpoints for ibc transfer * fix query route * fix receive packet * fix query client state api * use sub module name instead of icsxx * use const for prove judgement * modify ibc rest api * add api docs to swagger * add ibc config * fix proof path in swagger * return query result proof * update swagger docs * parse prove * clean up * fix ibc rest api and swagger docs * fix host validate * fix typo * add submitMisbehaviour error response in swagger * fix rest queryRoot and swagger doc * add response comments for each REST functions * fix rest function comments --- client/lcd/statik/statik.go | 2 +- client/lcd/swagger-ui/swagger.yaml | 1199 +++++++++++++++++++- types/rest/rest.go | 11 + x/ibc/02-client/client/rest/query.go | 248 ++++ x/ibc/02-client/client/rest/rest.go | 39 + x/ibc/02-client/client/rest/swagger.go | 61 + x/ibc/02-client/client/rest/tx.go | 164 +++ x/ibc/02-client/module.go | 5 +- x/ibc/03-connection/client/rest/query.go | 102 ++ x/ibc/03-connection/client/rest/rest.go | 62 + x/ibc/03-connection/client/rest/swagger.go | 46 + x/ibc/03-connection/client/rest/tx.go | 204 ++++ x/ibc/03-connection/module.go | 8 + x/ibc/04-channel/client/rest/query.go | 63 + x/ibc/04-channel/client/rest/rest.go | 75 ++ x/ibc/04-channel/client/rest/swagger.go | 55 + x/ibc/04-channel/client/rest/tx.go | 336 ++++++ x/ibc/04-channel/module.go | 8 + x/ibc/04-channel/types/msgs.go | 20 +- x/ibc/20-transfer/client/rest/query.go | 60 + x/ibc/20-transfer/client/rest/rest.go | 38 + x/ibc/20-transfer/client/rest/swagger.go | 27 + x/ibc/20-transfer/client/rest/tx.go | 118 ++ x/ibc/20-transfer/module.go | 8 + x/ibc/client/rest/rest.go | 19 + x/ibc/module.go | 41 +- 26 files changed, 2985 insertions(+), 34 deletions(-) create mode 100644 x/ibc/02-client/client/rest/query.go create mode 100644 x/ibc/02-client/client/rest/rest.go create mode 100644 x/ibc/02-client/client/rest/swagger.go create mode 100644 x/ibc/02-client/client/rest/tx.go create mode 100644 x/ibc/03-connection/client/rest/query.go create mode 100644 x/ibc/03-connection/client/rest/rest.go create mode 100644 x/ibc/03-connection/client/rest/swagger.go create mode 100644 x/ibc/03-connection/client/rest/tx.go create mode 100644 x/ibc/04-channel/client/rest/query.go create mode 100644 x/ibc/04-channel/client/rest/rest.go create mode 100644 x/ibc/04-channel/client/rest/swagger.go create mode 100644 x/ibc/04-channel/client/rest/tx.go create mode 100644 x/ibc/20-transfer/client/rest/query.go create mode 100644 x/ibc/20-transfer/client/rest/rest.go create mode 100644 x/ibc/20-transfer/client/rest/swagger.go create mode 100644 x/ibc/20-transfer/client/rest/tx.go create mode 100644 x/ibc/client/rest/rest.go diff --git a/client/lcd/statik/statik.go b/client/lcd/statik/statik.go index 48a9278324ee..0639033f1870 100644 --- a/client/lcd/statik/statik.go +++ b/client/lcd/statik/statik.go @@ -8,6 +8,6 @@ import ( ) func init() { - data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00 \x00favicon-16x16.pngUT\x05\x00\x01\x80Cm8\x00\xbd\x01B\xfe\x89PNG\x0d\n\x1a\n\x00\x00\x00\x0dIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x01\x84IDATx\x01\x95S\x03Luq\x1c\xfd\x8c\xf1\xc3\xec0\xa7)\xcda\xb6k6\xb2\x9b\xf9\xb2k\xc85/\xdb\x8dqx\xc6\x94m\xcc{\xef\x7fO\xff\xf3l\xdc\xed\xf2\xe0\xfe\xf8\xc9\xffP\x14\x11/\x14[\xa3P\xc4\xa1\xbc?\xf1t>7\x12s\x13\x03\x85\xca7IR a\xb5j\x8f\xa71\xbe]\x88\xf6\xb9L\xf0\x1c\x93\xcf\xda\xe3)\x10\x93f\x8d\xe4\x06\x13\xcf\xde<\x9b\xd14\x95\x8a\x92\x81OA\xcfF\x89\xdd<\x9b M\xe6}L\xe4\x07\x15\xc5\xf5\xe3\xffI\x0c{\xd6\x8d\xffs\x994\xbasfh\xae?\xafk\x1aprw\x10 <\xb9\xdb\xc7\x86\xa6\xd1\x19I\n\xa8\xb1\xd7\x84y3g\x171T$\xb5c\x7fq\xfbbq\xbfk\x8e'\x1dQ\xb0\xc2,\x92\x0bx|;F\xe5\xf0\xef\x00\x83\xf2\xa1\x1fx|?q\xbd\xcb\xc2\x16\x80ZF\xf0\xc4J\xf3\xe3\xe4n1\xcc\x17k`:}\xcby\xe8\x98\xcbB\xc7|6z\x97r\xd14\x9d\x06\xd3\xf9\x8a\xe4\x94\x90\x8b\xb6\xd9\x0cP\xebc@\xd0|\xbe*\xc94\xc8\xa7\x98'\xcdh\x00\xe3\xd92\xa6vK}\x0cB\xa4\xf0+D\n\xc7\x81)\xb0\x10\x9a\xe3\xa9\xd8\x8bx\xe4(\xa2\xbb\x8dl\x0d\x01\xb6\x8a-\xf378\xbe\xdd\xc7\xa6\xb6\xc9\xd9\xc6d\xd8\\m\xf4\x0c\x92 uQ\x0e\xd2\xf5\xb3\xd1\xf1w\xdfQ\x16\xb34a$\xa1\xc4\xc4(V\xbcF\xd9\xdf\xa4\x91\xe9\xb0&,\x12+\xcd\x93\xcf\x1c\x1cb\xdc\xca\x00qt\xeb\xcc-\x14\x89\xfe\xfc\x0fm2j\x88\xec\xccs\x18\x00\x00\x00\x00IEND\xaeB`\x82\x01\x00\x00\xff\xffPK\x07\x08\xd4`4t\xc7\x01\x00\x00\xbd\x01\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00 \x00favicon-32x32.pngUT\x05\x00\x01\x80Cm8\x00u\x04\x8a\xfb\x89PNG\x0d\n\x1a\n\x00\x00\x00\x0dIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\x00\x00\x04|ID\xc4\xcf\xd0@\x04&%\xad\x1e\x16\x0f\xf7\x8d\x97AR\xfa\xca\xe7l\x87\x05\xf8\xd2\xfb\x0c\x84\x1d\x0dLVY\xdc/ju\x13\x1a\x88\xd2\xa0\xaaa\x82|nzp_\xf4\x03\xc8 \xd4;^\x8a9}\xeeu\x9a\x91 `\x04\x14s\xec\xe1\x0c\xc6]\xa3\x05``\xd1w\x12*~ \x00\xf3\xae\xd3\xa0\x9cb\x82\xa2bx(\xb3n\x1fqx\xd2\xf2\xda4\x1d\x8a}\x1ck\xd4>\x9cI+\xeb\xb3\xf4k\xc8u`L\x93\xf3]4\xb5\xd0\xc3\xe33\xd9\xee\xd7\xf2\xd9\x19\xea\x18\xc9\xc1Y:\x18\xfb(-\xadN\x82\x06e\xd5\x1f0\xa2\x1dV\xf8\xbe0\xc1\x985\x01\xf8\xd2~\\\xa6\xa5\xb5)&\xf6\x98V\x80l\xe4\x03\xf8\x03\x04\x00s\x9a^\xec\x85\x00\xf4+\x0b\x00\xe1:G\xf2p\x96\x0e\xc4,\xe46\x1e5\xbbP\xdd\x15J\x80}\xce\xa4\xe2\xc8{m\xa4\xe2\xc3\xc2\x01\x07\xc0\xdb\xa4\x18-\xa1\x931\xba\x10S\xfa%\xb6P`\x10\x19v\x99#|Gg\x9b \x10W\xf6\x8dI1\xba\x92\xd66\x17E\x12\xfa\xd9\xa8\xf3UTe\n\x1b\x95\x9d\x81f\xe5\x18\xa5umc\x81\x86\xa6\xeb\xec \x804\xcbg\x17\xa19\xfa\xc6\xf7<\xa3\xbd\xf2\x0e\x7f\x02\x80\x97Y\xc7\xac\x184$h\xa3v\xba! \xcc{\xcd\xb4!\xb1\xd8\x92%h\xe3\x93\xdc\xd3_\xda1\xe6\xaei\xcf\x83\xa6p\xbc$\xf0\xb2\xda\x94\xa2q\x14B@\x13\xdb\xff\xf3\xd7\x0d\xfaA\xb9\xc5n{\x8e\xd6Y\x08\x01u\xc1'~\x16\x8e\xe9\x04\xa2\xfbA+\xc74\x0c\x98\xab\xd7:\xfc0\xd1v\xaf$\xa2#\xb7\xf1\x08\xfdm!OXh8\x10j|g\xd1\xe0a\xb2\x99\x04\x9a[y\x9a\xbdk\xf24C$\xa0\x9e#\x9f\xa3\xa8\x001\xc6\x1a\"\xc0\xe4i\xa6\xcc0\xf3\xf7\xb7\xf5XE\xb8\xe0\xa1\xc9\xc2\x0c\x90\x83\x80$\x838\xdf\xd6\xe3\xd4\x82FNG\x0f\x876\x8a\xbf1\xa8d(\xa7@\x8cQX\x90\xdb\x19\x9f\xc5YG\xe9\x9e\x00\xa5y3]\x9aJ\xe1\"\x00\x00\x00\x00IEND\xaeB`\x82\x01\x00\x00\xff\xffPK\x07\x086B\xc8\xd7\x7f\x04\x00\x00u\x04\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00 \x00index.htmlUT\x05\x00\x01\x80Cm8\x9cT]k\xdc:\x10}\xdf_1Q\x1e\x92\\\"\xfb&\x81p\xf1\xb5\xfd\x90\xa6\xa5\x81\x94\x06\x92}(\xa5\x14\xd9\x1a{\xa7\x91\xa5E\x92\xf7#!\xff\xbdX\xf6\xae\xb7\xdd\x90BYX\x8f\xe7\x9c9\x1a\x1d\x8d\x9c\x1ep\x0e\x1f\x1f>\xddBe,8/<\x95 \xc9yKE\xeb\xc9h(Z-\x15B\xd1\x92\x92\xc0y>I\x0f\xae?\xbf{\xf8r\xf7\x1ef\xbeQ\xf9$\xed\x1e\xa0\x84\xae3\x86\x9a\xe5\x13\x80t\x86Bv\x01@\xda\xa0\x17P\xce\x84u\xe836}\xf8\xc0\xffc\x03\xe4\xc9+\xcc\xef\x97\xa2\xae\xd1\xc2\xf4&\x8d\xfbL\x8f*\xd2\x8f`Qe\xcc\xf9\xb5B7C\xf4\x0c\xfcz\x8e\x19\xf3\xb8\xf2q\xe9\x1c\x83\x99\xc5*c\xae\xd7\xe0-E!\xbb'A\xa5\xd1\x9bbjD\x8d\xf1\\\xd7\x9b\xeaJ,:\x9c_\x9c\xaf.\xce\xa3\x008zB\x97\xb1\x90a\x10\xff\x9d\xde\xd9\xe5\xea\xec\xf2\x17\xbd\x90\x19\xf5\xc2\xc6\xfa\x18\x82\x9bC\xf8<<\x01\n\xb3\xe2\x8e\x9eH\xd7 \x14\xc6J\xb4\xbc0\xab\xff\xb7\xb8Y\xa0\xad\x94Y&\xc0\x1b\xf3\xc4]i\x8dR\x85\xb0\x8e/\xd0z*\x85\xda\xe7\xf2u\x02=q\x83\xbdL\x86\xe0\x9f\xd3M\x90\x14X\x19\x8b\xe3\xbb\xa8<\xda7\xfb#=CK~O\xb40r\xbdW\xd8\x08[\x93N\xfe\x1d\xdb+D\xf9X[\xd3j\x99\xc0a%\xba\xdf(\xd5\xfd\xa7\xf1\xd6\xaf4\xee'\xac\x0b;\xf9\xc1OI\x0b \xb9;\x0e,OcI\x8b|2\x18^Z\x9a{p\xb6\xdc%\xf1~\xc6\xa3\x1f\x8e\xe5\xdd*\x81\x94\xbfY\xe1\xbc\xd0R(\xa3\x91\xcf-:\xf4o\x14\xf7/K\xd2\xd2,#\xa3\x95\x11\x122\xa8Z]v\x17\xec\xf8\x04\x9e7N\xc51\\\x85{&\xc0\xad\x9d\xc7f\xc8\x97F;\x0f-A\x06\xc3m\x99\xde\\\x85\x9e\x8fGG[\xab\x12`Q\xeb\x8c\xd8v\xfb_}K7\xd3F\xfe]\xb1\xa1\x82h%q{\x8b\x9b6\x88/\xc4i }\xc07u~}\xe5\xad\xfd\xc9\x98\xe7q\xd8_}o\xf1\x92%\x9dx\x15\x9f\xd3yO\xbdX]\x1aA\xc9>t\xd6o\x93\xd3\x92\xf2\x04l\xc5\x8d\x92jz\xc1jN\xd6\xf2\xa9\x87\xfa\xb5]\x05\xcc\xf9\x1acB\xa9,\x9f\xd0\x08\x05\xb7\x962\xec\xdb\xb6\xe2\x16b\xc6\xd5\x942H\x05KfI\x06\x7f\x9c\x98\xa8\xc0\xd5\x9c\xa2\x0c\x13\xa3\xe7U\x8e\xb55;'Nk\xe6\xd0\x9d;\xd4%^\x14\xbd\xd5\xf7\x92QN\x8e.\x1c`\x079m\xe3\x9e\x8a\xfe\xed\xa2\xad\xe0y>\xe6\xe23\xdc\xf8u\xa7=\xa3\xf6\xa1\x98\xb4\x17g\xa9\xf4\x1dA\xa8Z\xe4\xf6\x88_\xfc)\xf8\xd5N\xcf,\xea\xb4\xabS\xf2\xd2\xe0v\x10\x90\x82\xbd\xb3\xe1\xc1g\xc8>\x120\x0c{\x1d\xbd\x1c\xd1\x7fd\xb4\xbf\x82|\xf7\x9f\xd0\xa7\x1e\x82\xc5`H\xc0\x94F3p0$H.\x0f]v3\xaa\x9b\x1c\x83EW}\xba4\x12O`_\xb5!H5\xd1 \x9a\x0c\xaa\xcd\x04\x8cE\xe7M:\xe1\x08\xfe\xefQ\xab\x02\xfe\xb7A\xeb\xb6k\xbb\x05{\xef\x8e\xde\x84\xcb\x9c\xb2\x8f\x04\xd7U\xf9\x9aQ:\xbe\xf51\xf1\x1a\xaaW\x97uR\xdd\xe7\xf59\x974\xb7\xfc5s\xd0\xc4P\xdf\xdd\"\xd7\x96\xc2\xdab7x\xb8;\xfc\x01\xfa'\x00\x00\xff\xffPK\x07\x08]\x12r 9\x03\x00\x00T \x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00 \x00swagger-ui-bundle.jsUT\x05\x00\x01\x80Cm8\xec\xfdyw\xdb6\xf68\x8c\xff\xffy\x15\xd7\xfa\xf6\x9b!kZ\xb1\x9d\xa5\xad\x13\xc5\x93\xc5m\xb3g\xe2\xa4\xcb\xa8\x1a\x1fZ\x82,6\x14\xa8\x90\x90m\xb5\xf2\xef\xb5\xff\x0e.\x00\x12$\x01\x10r\xdc\x99\xf9<\xcf\xc3s\xdaX\\\xb0\\\\\\\xdc\xfdn\xc1tI\xc7,\xc9h@\"`!\xfc\xf9?\x00\x00\xbd\xec\xf4w2f=\x18\x0c\x80\xad\x16$\x9b\x02\xb9\\d9+\xe0\xd6-\xd3\xd3y6Y\xa6\x04\x0e\xe5\x1f}\xf5\xf6\x00X\x10\xc2\x01\xf4T7\xfaG\x132M(\xe1-\x8a\xbf\xfa\xf1|\x02\x87\xf2G0\x1c\xe1\x80\x0e\\\x839T\x7f\xf5\x8f/\xe2\xb33\x92\x7f|\xfedI'));&\xe6'\xffs\x15\xb0YRD\xd5\xf4\xd5\xd4s\xc2\x969\xd5\xc0\xa2\x1e\xf0\xeb<\xce\x81\xc1\x00\xfe\xbcz\xf0?\xe5M\xf5*\xd0 \xd7_\xe6W2\x85\x80\x0d\xf3Q\xa8\xda\xe5?\x14t\x1e\xd4^\xe5mg|t\xc3|\xc4\xbb\xa8=\xc4\xb6\x0e \x8fZw\xd3\x03\xd8\xdak\xdf\x96]\x1c\xc0\x9fW\xb5gW\xf5N\xe5\xa8\x08\x1f\xd58N\xd3 S\x83\x8b \x8b@\xfbEC\xfe3\x85\x01l\xedj\x0f\xca\xd6\xaand\x9b\xb4?\x87\x01\x90\x08h\x7f\xcc\xa7\xc5\xff\x98\xc0\xa0\x8ep\x11\xb4@F\xfb\x99\xc4\xc5\xf5\x1a\xde\xe2\xd2\xf7\x05J\xbc\xcb\xb3\x05\xc9\xd9J~\xd9\x86\xd08\xa3\xd3\xe4l\x99\xc7\xa7)\xb1\x80\x85.\xe7D=\xdfm??#\xec\x00\xf2:\xc4\xc2j\x8e|\x0e\xb46\x87\xe6\xe8\x15\x86 Z\x93\xfe\xc9 )^\xab\xbd\xd1\xc25\xfdR+\xc1\xe7\x1a/SV\x1f\x03\x1c\xf8}\xed\xb1\xd6\xb4? X\x04\xbd\xb8\xc7\x81\x1c\x01\xabO/k.Q\xb3;\xd9\x8c\\\x99E\x9e\xb1\x8c\xef\xca\xfe,.\xde^P\xb5F\x02\x9b\xf0\xfbz\xfb\x0b\x18@\xef\xf6$)X/\x02\x1a\xd0>'\x12w\xef\xde\x13\xaf]\x05\xc3\x06~P\xbd\xff\xde\xb2 P\xb0<\x19\xb3^59\x9d\xdc\xd0\xe0\x1b\xd5T\xd4D\xb5ZS\xf5\x8f\xbe\xbdw'\x0c\xbc\xbe3\x0f\x81\xe9+-\xb6\x08S+\xd9\x05PN#\xb6\x02\x02 -XL\xc7\x9c\xbe\xb10\x046\xcb\xb3\x0b\xa0\xe4\x02>\xac\x16\xe4(\xcf\xb3<\xe8=\x8d)\xcd\x18p\xe0B\x0c\xe34.\n\x88\x0b\x88\xcb\x1ezacG\xde\xcct\xaaG\x1c\xc1\xf3\x08)\x15\x0d\xf6\xef\xef\x87\xf5M\x94\xc0\x00\x82\x1c\x06\x90\x85|\x07\xe4\xf5\x1d\x90\xc3\x81\x01y%\x9cZ\x1bO\x1f\x8f\x01\x96M8\x96t\x98\x18\xc1\x8c\xafd9\x04|\x06|\x13\xef>\x00\n\x0f\x81\xf5SB\xcf\xd8\xec\x01\xd0\xedm\xd3G\xa0f\x8d\xc4\x99\x8e\x1e\x18\xdf\xc8\xfb\x15m\x81A\xfd\xe7z\xcd\x89\x11\xe4}\x9d@I4\xe9\x9d\xc7\xe9\x92\xf4 \xa1\x90s\x88\x05y\xff\"OX\xf9F\x18A\xb0\x1bA\xa2 \x10\xf2\xc9\xe5\xfdOd\xc5igk(\x0djo\xda\xb9%\x009.\x18\x08\xb0\xf6*E*\x16h\xdb\\\x1c\x04\xb9\xbc\xcf\xbf\xd6)H\xbd\xcf+\xbf\x1d\xa5\xef\xc4\xfaHJ\xc4\xa0\xc17\xf7\xef70\xadB,N\xca\xff\x9dX\x7f\xf7\xde\x7f\x0e\xe9\xad\x04\x84\xe8\x14\xe3=\x99\x92\x9c\xd0\xb1\"\x1b\x9c\xd7\x81Y\\\xd0\xbf18%\x84BB\x13\x96\xc4iR\x90 \xec@\xb1\\\x90<\x08kop\x12C&\xbd\xd0x\x86l1\x8e\xd3%c\xb65\x18@p\x9e%\x13\xd8\x85\x01\xe7\xd2\xe0\x10zK*N\xedI\x0f\x0e\x9a(\xcc\xe9\x1bg$+\xaep\xab\xe4\xed\xf8\xc7\x04\x0e\xf4s\xe9\xaf[R\x18@\x1cp\xec\xfa6l\xaci&\x1f\xdd\xb9\xfb]\xf3Q\"\x1f\xdd\xbd\x17\x86&>0n\xb3\x05\xea|6p\x05\xc4\x8d\x1e\xc4\xb6\xb9\xae\x87'\x16\x90\xdf\xba\x05t\x99\xa6\xb8\x92\xccr\xf6\x1cs,\xe1\x8ceN\x8a\x82\xcfs\xbe,\x18\x90\x84\xcdH\x0e\xa7D4\x90\xe5\xdaa\x14\x01?\xacz\xb0\xbd1v4\xd0\x8eT\x04\x88o5d@\xab\xd7\xf9\xe8k$\xca\xc8\x19\x16,_\x8eY\x96\x9b\xa0\x0d\x88\x0f\xe9\x92\x1c\x00i3\x85\xd0d\x1c\x0d\x8c%\xbf\x14\xdd6\xb3\x96\xd0fPw[/5\xc87'\xae\xf2PPk|\x88\xd3\xcfk\xc7\x01\x13\x92\xce\xc9 \xc2\xe0\xe4\x84\x1fT\x1b\xf2\x01\xb8\x1b*\xa0\xe7\xae\x83\xd6\xbc\xd5T+|\x85\x1e\xe7y\xbc\xd2x\xc3\"M\xc6D\xdb*\xa0o\x17f=\xae\xc5\xdc\xeb\x8b/\xf9\xceqNbV;\x99\xc20\xd2\xf1\xa4\xaf-9\xe7\xc7\x1b\xdb\xc8<\x14\x03C\x0f\xd5\xee\xc5}-6\xec\x8b\x80\x84^-\xe6\xce\x16\x97U\x8b\xbf\xfa\xb6\x989[,\xaa\x16_\xfa\xb6\x98t\xcf\xfa\xd6-\xd8J\xab\xa6\x7f\xf0m\xda@\n\xb5\xa6\xb7\x82-\xc1\x1c\x91\xe1t\xe4\xd7\xe0\xd2\xb7\xc1\x85g\x83\x85o\x83\x13\xcf\x06\xd3\xee\x15_\xaf\xb1[\xaf\xe6\xc6\xbe\xe3\x9b\xb5\xc6\xa7\xffbA.X7\x16d\xea\x8fD\xfcA\xfbI\xf1\x9c\x95\x9ck,\xee\xbc$+\xc2\xc5\xf5\xa5|\x81N\xc8%\xde(\xc4\x8d\xc7E\x91\x8d\x93\x98%\xe7\xfc\xa3T\xdc|\x9bOH\x8eo\x8d\xf9\x0d\xd5\x06\xef\xba_\xb5\xc0\x07\xd0?&\xfc\xbcJ\xda\xf4c\xca\x05\xc4\xbf\xff\xfd\xe4\xe4\xf9\xeb\xd7\x1f?<~\xf2\xea\xe8\xe4\xf9\x87\xa3\xf7\xf8\xc7\xc9\xdf\xff\xdekS\xd6E\xfb\x8b\x97G\xbf\x1e=\xb3\xbc>1t\xf0\xe6\xd9\xd1/\xd6\x0ff\xed\x0f\xde\xbe\x7fv\xf4\xde\xfa\xc19\x0c\xe0^\xfb\xf6\x1c\x06\xb0\x07\x0f\x1f\xc2\xb9A\xf1\x00\x03\x98\xc3\x0e\x18\x8e\x96\x15*\x9c\xda\xf7O\x8dZ\"\xa8\x8e\xb2\xad\xbd\xd6SC3'\xd7i\xc6F\xcb/\x9c\xd8J\xfa\xd8$g\xc4\xf6\"O\x92|dn\x91\xc8\xa3\xa1lp\xd7o;]\xf2\xd3\xcc\xf6\xf0\xd8q\x12q\xbee\xbd\x86\xdd\xb6\xf4W\x13*_\xc7l\xd6\x9f\xc7\x97\xfc\x90&R\xb2\x84\x1dT\xb4\xf0c\x88\xb3Tx8\x06\xa8O\x13Rh\x06\x0f\x81>\x80\x8c\x8b\x9f\xf90\x1b\xf1\xe3j\x98\xc160\x83\xac)A\x99{\xcd\xf6\xa9s94\x9e\x8c\xf4\x8b\xe4\x0f\x05S\xfcs\x80\x0cE\xc2\xe9\x02#\xc1cq\xba\xf2'^\x1d\x7f\xb2B\x12\x99P\xba\x9c\x9f\x92\xbc\xc6\x82\xba$o\x8a\xd0\x7f\xf4\xe8\x91 \xfc\xa0\x1a\xe5|&\x15\x1c,_\xa9\xbb\xfb\xdf\xdd\xfd\xee\xfe7\xfb\xdf\xdd\xc3\x19\xd2R\x05\xfb&~cn\x85/2m\xe3\xba\x0d|\x0c\x1e\xc2.\x1c\n o\x03\xab\xc9,\xe0\x00\xcec\x97\n\xaf\xc1\x14\xda\xdaxkb\xe2\x1aM\x05rm94\xe4Zs\xe8\x08\xa1\x1e\x1e\x0e`\x87\xe2\xc9^g\xce\x0d/3x\xc4\x01\xe85\xb0w\xd6\x95\x97\xa3z-G\xee\xb9a?\xf8\xb6\xc7\xfc\xda{\xed\x018}c\xc0!P\xce]\xcb\xc5\xd6\xf77\x83m \x9c\xf5n\x087\x9cC\x12\xef%\xa8di\x9d\xf4\xfa/\x8e\xdf\xcf9\x1dhS\xe6\xdf\xf9y\xd1\xbe\xfd\x06\x06\xb0\xdf\xbe\xfd\x9e\x9fR\x95tW\x19K\x8eW\xf3\xd3,\xe5\xeb(\xfe\xea\x8bM\x9d\x19\x8c \xcf\xc4I\xa7^0\x1cm\xaf`\x00\xef9\x8e<\xb3\x1d\x01\x1f\xcd4\x87\xcd\x92\xa2O\xc9%\xf3f\xc6?\xab\x95\xb2\xe8\xa8\x94\xc1\xa4Z(\xbe\x05\xf7j\xcb6\xe4\xdf;\xa8(\x1cB^\x9e!\x19\x1c \x91v\x9e\x86\x99Y\xb2\x9bd\xd4v\xe2z\xd2\xea\xef]T\xc19$\x81~\xcequJ\x9a\x96A\xfd\xe1\xe6>\xb7~\xf4ec\x9f\xb8\x19\x83\x866H\xb3\xf4!\xcexu\xf1\x93\xb9\x0be\x91\xe1C\xb5\"\x82\xd4!\x08\xa3\x85\xdf\x8c~tw'\x0e\xd3\xf7Hk\x87\xefG|\xcb\x90\xe1\xb3\x91a\x08\x0d\xb5\xcc@?\x13\xd5\xf0\xbcF\xf4\xb3\x07\x8c\xd5\xc9\xabCXp)^]\xbcpv\x81\x1a\xa0\xe6\x91\xa3\xb6cB\xd0 \xab\x84\xe8>\xcb\x8e\xc9g\xbc\xa5Z7\xb7\x0d\x1aP\x0b\"\xc5'\x93M\x18\x95X\xe4\x02\x181\xae4(M\xa9M\xbfut\xb9 cF&\x82A\x83,\x87DIE\xa27\xc8\xa6b\xcb\x15\x11\x7f\xfa \xa5\x1b\xf1\xe8\x00\xb5\\\xb6n\x8d\xab\xc8\xaf+_d\xfb\xf5\xcb\xe0\xdeg\x19\xcab\n\xe2r\x11\x96\xed\xb5 \xfdi\x9e\xcd\x8f(\xcbW\xe5\xcb\xc4w\x94/\xbfl\x94\x86\x81\x11} |\x9cR\x8aT\xb7\x96\xdec\xfb\xc19\xb6\xe0\xcb\x07\xa7F\x13\"4\x19\xdeo\x8cL\xff\xf5QSU\xb1\xec\x98\xe5 =s)\xdd\xb4\xc1\xf6\x86\xcf\xe5\x01=\xea\xd5{\x88\xe0c\xff\xe5\xd1\xaf\xc70\x80\xe7\xfc\xef\x9f\x1e\xbf\xfax\xc4\x7f\xfd\xce\x7f\x1d\xbd\xf9\xf0\xfe9\xfe|\x13\xd5\xfaOh\xc1Q\x1f\x06\xcdQe\xcb|Le\xf2\xd9\xb3M\xd3\xd8^\\\x7fQ\x11|''%\x00{|$\x7f\xf6\"\xe8]\xf5\x9cc\x1e\xc7\xe3\x19yO\x8a\x0e\xeb\xa8\xd6\xd5\x96\xe8\x0b?\xc4sOt-e\xbd\x8f\x14\x1fL\xf0\xfc\xd2\xdf\x1c\x88\x17+\xac\xef\xb3L\xc8\xb2a$\x1eI\xc1Q\xfbH\x9e-\xf2\x05\xd74\xca\xfe\xbb\xac\x18\xdaDR\"\xbdx\x04\xa3\xd8\xd2\x01\x98{\xc8\xf2\x0d\xba\x18wv\xc1\x82_#x\x11F\xf0km\xf1\x15\xbd\xf5\\\x133\xa6\xbf\x14-\xbf\xf4\xc7\xf4\x97\x0eL\x7fY\x1b`EI=\x9b6\x0d\xf1\xe5\x0d#\xfc\x90#\xfc\xa8\x8d\xf0/o\x18S\xf6\xbcz\xf8\"Liw\xc1\x82\x1f\xc4z\xfe\xe0\xbf\x9e?8\xd6\xf3\x87\x06\xe5b_\xb6\x96/\xfaI!Z\xc8\x08\xff\xa5\xb4\xb7\x1c\xbd\xa5\xba\x96\x8f_S\xe4\xbelko\xbf\x8a\xe0\x9f\x11\xfc\x12\xc1?\xdaJ\xd3\xe3\xa3\x7f\xa0\xc2\xd4&9\x12\xe2\x10\x1dOb\xe4\xca\xd0\xa3L'6\x1b\xb1\xaf\xcc\xd2\x83\xe2/\xa5q\xe9\x13Y\x15F\x1eR\x8cDr\x83\xd5PN\xf8\x07\xc2\xc7\xadF\x077\x19\x1auN>\xa9\xf4\xf3\x96\xf9\xa3\x80\xe1\xaf\xa0\xcb\xbb\xbb\x93\x86\xb3\xa8q\xef\xa9<\x0c\x86#\xaf\x8e2KG\xea,\xaa\x0c\x18\xff\xf04\xb0 7fm\xf0+\xdeZ\xf0\x95\xd4\xb5\x12\x12\x0cG\xa1_\xbbq\x07r\x08\xa3fR\x883\x0fy@\xd9\x05 \xdb\\\xf3\x93\xea\x8d\xdc\xfc\xc6\x1f\xd5\x1b\xd4\xfc\x86Q\xca9\xac\x84\x9cR\xf5d\x16*\xbfL\xd2\x19~\x8a\xe0|\x04\xfc\xb8O6\x92x6\x92Y\x97\x1d@/\xcc\xc2\xdc\x97OO\x08r74\x8b\xc2\x8d\xe4?7\xb0\xc5\x80\x1e\x06|(W\xd7k\x08)\xf1T\x97\x11\xc9\x9a\x99\x81\x9a\xd9D\xf0\xd2\xca\x91\xf0\x03\xa2\xb2l\xecE\x10\x0b3F\x0c\x0f\x07\x90<\x80\xd8\xeeF\x07r\x1cK\xde\xc6\x90r\xd1\nv \xe6\xb2\x95\xc5\xad\x0e\xd4b\x0b\xbd\x1e\x0b\x96\xc3\xbdQ\x84\x8a\xbb\xe5pw\xc4\xbf\x8c\x80\x84\xa5\xa6$\x86mh+\xe1\xa0%~\xa9K}\xd6zhU\xfb\x936\xab\x8c\x9et~Df\xfc\x17/\x93q\x85\xac\x90\x15+\xe7\x02\x0c\xc7\xc6\x8f\x81\x93\xa5P\x97r\xfe\xf0_X\x05\xfc\xedmx\x04 \x1c:\x1a\x07?u\xa7\xba\xacjOu]\xc1\x01|F\x07F.\xcaKL\x12\xe8L\x86{\x8d\x93\xa8\xfc\xa8}\xdb\x03M\xb2\xfc\x1ax2\xb5;\xb1*\xca\xa4y\x94\x0b_L\x8eR\x11XQ\x83\xe3M\xfd\x0c\xa3\xd5\xbe\x91\xba\xcf\x0c\x9bx\x19\xd0\xb0?\x8f\x17\xd5\xba\xbb\xda\x05m\xd2\x08Q\x0c\x1d\xa06\x10:Ts\x13b\x1d\xd2\xaf\xff\x81!\xa9-\xd0^t\xb4\xeaD\xd0\xeb\x99|\xcd\xf8\xd5\xeb5=\xf7\xf0;N\xd3\x17\xde*\xab\x85\xfbT1\xf0#/9\x1b\xc1\xa1\xb4 \\:\x7f\x95\x14\"\nfB\xc4\xf3_\xeb\xcf_\xc7\x0b\xa1\xbb\xf2\x1a\xce\xc4=\x1ce=\xae\xf9]\x0d\x14O\xdd\xd4\xaa\xe9\xaf\xf9Acf\xdf\x11\x1cwHe\xbe$\xb0%\xf5\xef\x0c-\xcc%Fm\xd9\x18%\xc1\x82j/\xeem\xa0\xa6\x97N\x08o\xa7V#\x06So\xb8\xb6f \xb8y\xf9f\x10\x868\xa1\x00=\x0f\xf4\xbb\x9bN\x10\xec\x93\xf4\xa7f[f\xc7Q\xd2'\x9f\x97qZ\xa0J\xde\xf4\x02\xd3^\xd8Ro\x07\xcc\x93#?\xf7Z\xf2\xee\xe5\x8d\x03\x11M\xa4\xd9\xb5+\x87\x07\xed&+o\xca\xc7\xda\xcd\xe6\xe7''\xb3\xb8\x98\xb5\x1a\xa8n\x97\xaf\xd4\x1e\xac\xd7B\x7f\xcco.\xe5\xb0\nu\xa3\x907\xc6\xea\xc6\x18=\xa5;\x90\xb2\xe9\xc1!\x0d\xd1\xf8\xdb \x1b\xe5Z\x81\x9e}\xe6\xb6\xf9H\\\xac\x06J\x88})#\x04\x1d\xe6\x8f>9'\xf9*\xe8T\xa8\xa8K\xb1B9\xda\x00\x83P\xec\x82Nv\"\xe3@\x98\x91 CNQ8/\x06\x94\xc3\x15o\xeeb\\\xa1\xed(\x00\xf4\xdf\x97\xfdq.\xc2c\x8f\xa8q\xda\x16\xa8\xe5gc\xee\xbc\xf1\xaaZ@\x0b\xcd\xd1\xd5\xbe\x88m\xda\x0d\xdbB\x90\xb4 \x0exg\x0d\x0f\xf9\xe6\xa5xK\xc7\x12\x10\xa9\x05\x81\x01$f\x08\x1b\xa17\x15\xc10\xc6/\x16 \xb6\x8frE*\xd1\xc7\x14<\xa8_\x1c\x9e\x9c\x13\xdd\xc2\xd8\xb4\x00\x9d\xa43\xfe{\x86<\x01\xe9\x9f\x11\xf4\x8a\\\x85\xfc \xbf\xab\xddB\x1cQ\x185\x95\x1ek\x06\x8a \x885V\xf1q\xaa\x11\x13\xbe\xa8\x0b/\xba7w\xd3\xbd-T4\xea\xf1bsM\x02\xe2\x1c\xbbj\xc0\x8c\x8fB\x9f\xa3\xbc\x1e\x1a\xfa\xa4\x86/\xcb\x1e\xdc\x86\xdd\xd2\x9fE\xfa\xbd\x84\x91zC}\xe8:\xd8\xfeY\x0e\xed\x9ff\xc4\xf9\xa7\xb4\x19tl5\x1b\xb4\xce:\xa0U\x8b\x8c\x11*\x02O_\xa1\x15q9\x0b\x99\x97b\xd5X\n\xad\x0d\xf3j\x9c\x91@\xbaZE\xa0\xe2\xfb\nF\x16\x10\xc3\xfb\x98\x9e\x118]\xc1n/\x8cpo\xe19\xb4\x1b\xd5W \x0d5\xe8[z\x1bv\xc3\x08i\xba\xf6\x02\xc5e\x94K\x18\x9f\x16\xe8z\xc8\xe0\xa1\xe4\xd8\xf8\xdb;T\x99pN\n\x16\xe75\xdd&\xa1\x13M\xb5y\x82C\xc3\xc1\xeaX\xa3\xa3\x07\xfe=&I\x1a\x04\x0cv8\x01\xbe\x0d\x94\x8bV!\x97\xcd7\xc3\x9d_JX\xfeb\xc6\x9d_\xbe\x0cwN\xcd\xbaD\x81/\x9aJ\xe9\xf1i\xc1\xf2x\xcc\x9a\x96 K\xb3'\xc4\xe5fz\xe1|z$\x9f\xea\x0f53\xd6\xf0\x1f#\x15`\x1a\x10\x12\xc1K\x8e\x19z\xdc\xc3\x19\xe9\x0c\x04\x82\x86\x15\x86\x93G\x94\x0f4M\xfb\xf0\x932g\x84\xa3\xb6gc\xa3\xcf\x8dL25\x7fY\xadG\xe9![S-U\x1e\xb2\x03\xc8\x85\x8b\xac\x15W\xa4\x8a\x88\x04t\xc80\xecn\x07=\xba\xb2\x11\n\x7f\xbc\xa3jgf\x1c\x15\xadT;\xf3\x9a\xac\x9fu\xc84Q\xe3\x14Z\x937\xbe\x95\x9956\x9bikJ \xaa7\xbd\\M\xa8/\xf4\xc3CbD\xf9Z\xdf\xb3\xb8p&\x02\x80\xa6\xa5S4\xdd\x08\x93o\xa9\x02\x1a\xbd|\xe9\xc6\x12\x9d\x8a\x9dU\x99\xaa\"\xc9V\xeb;-\x11;-\xe1;-{\x00\x89;\x16:\xe6\xdf\xe3bf\xb0\x03 \x1c@b\xd1\xf35vf<\x8a n\xee\xc6\xc4\xa8\xb4\xb5\n\xa3\x89\x17\xc8\xae\xb3=%\xb8\xac\xfbS\x03\xa1uw\xe6\x9d{8\xb9\x89=\xbc\xd9*(\xc8\xa1\xa65\xfb\xf7\xed\xf9\x98\xef\xf9\xd8o\x8fk\x8b8\x9cU\x87\x1c\x95\x87\x1c5\xee\x8b\xd2[\xc5c\xad\x91\xf7\x0dk\xbb\xb2&4iB\x86\x85{V\xd8\xf2SP7\xcb\x86v\x94\xb1\xe8$\x9e\x04\xd4\"\x83\x96\xbb8{\x00[\x01F\x9cKyT\x08\xa4\x18\x8b\xb7'\xb4\x10A&d\xe2\x08\xf2\xedm\xb9\xab\x1e\xd8\xa5\x91\xbc s#L+}\xf5\x8d\x025\xcb7\x86\xaaE\x9d\xf3D\xd7\x12\x8b\xed\xf2\xbd\xa5Y\xcb\nl\xbe\xd5\x98\xb6\x0e\x1dZ\x0e\\$\xe1\x8c\x8e{@,\x8dX(\xaf\x8d\x10\xe4\x12\xe5\xf3\xff\x02\x94\xaf\x0e\x15\xfd\x14)C\x08D\xca\xa2\xb6\x83\x80~\xa0\x94\xc6\xa8\x07\x1e\xcc[6LF\x11'T\xadC\xc226\xbeK\xa8\xa6%\x12\xbb\xe4A\x17\xdd\xa4.m\x12\x9a\xd8\x86\xc9H\x84C\x96c\x8b\xeb\x03;\xcdI\xfc\xa9\xbd\xa06lk\x1d[\xc6\xe5\xfd\x8f\xed\xbe\xc6\xc2Z \x9ai\xb1\x8d/\xdf\x08\xab\x8a+\x01\x8f\xaac\xb5Ka\xd8\xbdQA\xc1\x0d\x11\xa5\x02\x9eC\xb1(\x82\xf2\xe4\x1e6\xbe\xe6\xb4.+\xf67\x1f\xfa3\xbcsI\x03\xe6\xe4\xfa.v\x0dA\x1b\x0e\xa1\xf7\x9e,H\xcc`8\xea\xc1A\xf5\x0b\xbd \x98\xa6\x16\xda\x86^u\x0f\xbf\xe5wX2'\x05\xb4\x9d\x8e\xe7\xd7g\xcaML\xb8\x18\x82\x81\x01\xaf\xf5\x93\xd0q\xba\x9c\x10o.|Ft\xc5W;*\xab\xd1<\xa6,\xf0\x99Hm\xffpPYQ^\x8b\xd9\x13S\x85\x03\xa5\xad\xab\x8d\xec\x83\xb0\x13\xc3\x8e\x08\xa6k2\n\xcd\x91\xe6\xe4\x9c\xe4\xc5&n\xda\x1dp\x9d\x90\xcb\xb7\xd3\xeb\x83\x15\x0eQc\xb8\xb3\xe7\xec&\x8d\x0b\xf6\xfc\x06\xba\xaa0\xb4\xb3\xcb\xeb\x0bS*UT\xb9\xc4\x98+\xcaJ\xb0\xca\x03\xa36\\\xda<\xd1\xa8S A\xbd\xe6\xb2\xb9\x94\xb3\x11\xab\xba\x19\xb1Vl&<\x04\xaa(N\xc5\x02Q \x89\xd0\x98\xf0F]7\"~xP\xd8\x1a4\xa5\x91\xd2\x13\x0fI]\xf5\x0e\x87m\xcc\xd4\xa6z\xde\xb6\xf7s\xfa\xbe\x92\xf4}u\xc3\xf4\x1dU\xc6\x8a\xbc\x8b\x1f\x1au\x17\xda\xddm\xe8\xf5\xfb\xfd\xea.\xa1\x13\xd8\x86@\x08\x15\xeaE\xb2\xe0\xed\xc1\xe9\xaa\xf69Y\xf0\x86{!\x9e\x07\xed\x93`u\xb3'\x81\x1an\xa5\x8b\x84\xaf\xebCi\x9d\x11\xabk\x9d\x11\x8as\x08\x08\xec\xe8}\x87p[\xeb\xcf\xba?0@zW\x18\xe452!n\xf05B\x9d\xf84\xcd\x0c\xb6\x87\xc6\x90\xbd\xcf\x9d\xc6\xa1Rv\xaa\x1d.\xe8R \x02\xb2\xcb\xa7\x91\xb0\x15\xe0\x19S\xdd\x0d\xe1\xe1\xa0\xf4-]\x91`7\x82\xddP\x1eO+\x89\xdcg\x84\x05\xbaU@\x99\x0c\xf8}f\xb8\x8f k\x9f]\xab\xeb\x1c6\xe7eTemy,\xf6-\xf8\xbf:\x92\x0c\x06|.vi@d\x17p\xaf3\x94\xf6D\xb5\xd0\xb5\xf3 4\x13mp\x89\x03\xed\xc3j\xf5\x85\xe7#\x0eGB\xd4@sV7s\x16V\xd8\x8dz\xc3J$\xe0\x90\x93\xf2`k\x03S\xf8\x1a\xf3\xe0iw\xeb*G\xeaT9\xd6%\xc4\x08\x12\xa3\x06\xd1\xbcl\x19l\x8b\x11\xed\xf0\x01\xe4\xfe\x0b\xd4\x92\xd7\x8c\x00\xdc\xfc\x00\xae\x80g\x1co\x03\xa0\x969\xf9\x02\xd9\x0c\xce\x9b8\xec\x95 \x9d9\xd5!\x0d\xe8\xf3E\x7f\x84\x16\xc9\xbf\x98\x03P\xca\x17\x94\xd7c\x1f\x91kuC\x0c\xc1\x8a4\x16F\xf8}\xc8\x1fe\xb8\x1d\x9aU\xc5\x13\xfegy_\x92,\xf9 \x9eq\xe7ed\x91\x81\x8f8%*\x9d\xd3 \x89\xe0\x94\xe0\x9f\x17\xd5\x9fG\xea\xcfSRF\xf4\x887\xb5@\x1e\xf1\xbe\x0c\xf29jH0|\xa1/\x89-\xbb\x04\x9el\xc9|\x89 &v\xf6\xab\xd3\x8e\xdf\x0b\xaa$,\x11\xec\x87*\x7f\x06\xbe~\xe0\xbfk\xee\xdf\xbbw\xe7\x1e\xdc\xe2\xe7\xd9\x9a\x13s\xfb\xc6)\xdfd\xe2M;\x92\xe3^\xd9F\xb7\xbbG\x8f\x1e\xc1\xde\xfdP\xde\xe1O\x02V\xde|\xf8\x10\xf6\xee\x8b\xdc3!\xac\x9b\xce\xf8\xb6P\xa6\xe3._Il\x1en\xc1\xde\xee7w\xbe\xb9\xbb\xf7\xed\xfe]X\xc3\x9d\xfd\xfd\xbd\xfd\xfd{w\xbf\xe1O\xfc\x9c2\x9fZ:\xd2)&\xac\xd7\x8e\xe0\xeb\x92\x86Z4\xd5\xdd>\x8f\xaa\xa3\xb6\x07\xa3\xbb\xe3\xae\x9e\xb7\x9a#4Px\xc5\x18\xa8qY\xe6P\xa5=\x18\xd8}\xce\x12\xf4)\xdc\x92C\x15\x0e;\xc2\xa7\xc21P\xd0\xf0t\x17\xd66\xe7(q\xec\x8d\xe0\xbd\x80\xf5\x1b\x993\x83`:\x1cxF0\xf1\x19>\xe7T\x1c\x1b\xe7K}\x9d,\x0bp :\xdb\x08\xc7gq1{\x9aM\x88\x06\x19u\xcb\xa4\\\xc4\x96\xaa\x90-\x1d\xa4\x9e \xb43\x9e\x1f\x9a\xbe\xaa\x08\xbfw\xc2c\x8d\x84a\x97\x1a3\xa9\x9c\x0b\xcb\xaf\xc9\xf09\x19y}\xb9\xf5\xd6:n\xb05\xceOS\xb4q?/\x8e\xaaT\xd8\xe8\x0egz\xe25\x16[g\xdd\xe0\xd5\xbf\x96\xa3\xa0\xd9\x84|X-\xf8\x96\xdb\x0d\xa1\xb8H\xd8x\x06Au\xbf\xab)~\x8d\xe3\x82\xc0\xdeA\xe7{\xa0\xd1\xfe\xfe\x92&\x9f\x97\xe4\xf93\xfb\x1c\xd5\x85\xcd\x7f\xb7a\xf3\x93l\x8c\x01\xc3G)\xe1\xff\x88\xc96n\x96cp6mVj\x83\xdcR\xdaj\x19\xdf3\x7f\xcd\x97k{\xfb5\x89\xf4\xa3\xef\x16\xbc\x16{\xff5\xee}G\x88\xc8\x07\x12r\xac/\xa4,z=G\xd7\x06\n=V6\xd5\x01\xfe@\x97\xe7\xa6\xc7`\xefMFw\xc8%#\xb4H\xaa@\xc2\x02\xe2\x9c`\x92\xe38M\xb3\x0b2\x81\xb8\x80OdU\xf4\x9b\x89\xb3\x9b\xdd\xf3\x0de-n\xf1\xdc\x98\xc3X\xbf|\xd2\x11\xab\xab\xbb*\x86~iI\x8c;\xde\x94|\xbay\xf1\x01\xcc~\xb1\xea\xc2\x15j\xac\xc3\xa6$C\xb2\xc9Z$\x89\xc6\xc1\x9b>\x08\xad\x0d\xb9\xd5m\xfa\xa5\xcb\xda\xfe=\xf7\xe3\xc5\"]I6\xde\x12\xd1\xaf_W\x91\x83L\xf23\xb0\x03\xb2\xddD\xb0\xe6\x94^\x91\xbc\x16\xde\x7f\xa4\x08!\x96AA\x18\xc4@\xf9>\xa8 \xa7\xc6\x08\x19\x95{\xc2\x89\xfa\xfc*\xe7`\x9f\xfd\x06\xf4\xc4y\xeaot\xda+\xe5kI\xd68\xc3\xa0e\xb41\xe6\x03h@\xeb'4]\xf1&\x85\xd6\x14\xd5\xa4c\xe1\xd4{J\x80s\x0fd\xd2\xf7\xf4\"\xfdd\xe1\xedKu\x0c\x13\x8c\x92f\xa1 \xf5b\x16\xfc\x85;{\xf0\xb5HU\xd8\x1f\xcf\xe2\x9c3/\x8fY@Q\x98\xb1\x8aG\xc7\xa4\xed#\xad\xff\xe2\xbd?&U\xc6\x84\xa48*ic\x9bj\xbc\xf5\xdaa,_9\xf0V\xa9;\x8d4\xf3\xcf\xab\x08z\x7f\xefE\x82]\xb4\xea\x04\xc6\xb18\xe2]{\\\xf6cs\xf57\xa0Y\xd8\x16\x97\xdf\x91\x08>XE\xe6\x9fI\xfc\xe9u\xdc\xd02\n\x06/xGd\xe6\x02\xf9\x92\xa1qqF\xb6\xa1\xfc\x1c;<9I\xe6\xf3%\x92p\x8em''\x8d\x14\xed\x1d)\"\x03lE\xfc\x0e\x9e\x93&\xd2\xf3\xfe\x7f\xe7o\xec\xdd7$\xa6\xe4\x0f\xf6\xef\x192\x1f\xbf\xb7\x0cY\xb2\xf86)\xfa\x95e\x03\x9c\x91@\xc4f\xa1tV\xb9\xcd/H>\xcd\xf2\xb9P\x7f\xc7\xa2\x8d\x8b\x84\xcd \xa6\x90\xd0iB\x13F\xa0H\xfe \xbe;\xf0\xa3[\x8cw&\x0d\xfbE$\x0d\xfb\x8cMp\xfeb\x1c\x94\xf9\xd3\xf9\xb3>\x1f\xd9\xeb%\x8byO\x85\x16\xd6\xd2\xa5\xab\xce\xad\xe9\xed^\x91\x80*-?\xedO\xb3\xfc(\x1e\xcfj\xf1V\xc6@\x06u)R\x8a\xdc\x15m\xa9\x9b\xd4e\x8a\x82\xf6\x03\xe7g\xef\\ \x7f\x90\x8el\xe6\x1fI\x04'|\x9e\x1f\x89G2\x9d\xd2| B\x8a\xcb\x038r\xa9\x88\\\x8bd%!\x1d\x15\x86`{\x00\xfb]\xa2\x14\xda\x85\xe1Q\x95@\xc6p,\xbfN\x8a\"\xa1g\x82 \xc3^?\x91\x95\xc8f\xc1\x86\xd4\x94fR]\x82y\xe6/E\xfcU\xde\x97-\xdc\xbds\x9d\x11\xfc\xd76_\n\x85\xa7\x96\x01\xeau\xbc\xb0\xa6<\xfb\xf8\x85\x96\xc5\x93<\xcb*\x959\xff\x81\xa2s\x19K#\xf26\x85&\x93b\xad\xebb\xa3\xae\xff\xa1'\x85r\xcf\xa9 \xec9\xdd\xa0i\x9c\xc8r1\x89\x19y\x8e/\xaf\x0c\xd5\x0cm\xdfn\xba\xb29\x99g\xe7\xa4S\xd26\xccz\xe5nxBR\xc2'\xe0\xdbtk\xd6\xbeS^m:e\xd1IsA\xdc\x89\xa3\x85\x08Y\x92\x17\xa5G;\x94\xae \xa12\xce\x94\x13\x18\x92\x91l\xd4c,m\xf4\xb0\x8c\x06\x83]\xd1)R\xc6b\n\x14w\xf8\xc8\x96$\xda'\x91\xc4\xb9\x8c\x03\x15\xa6\x8d\x95]'\x1aw\xfa\xe2qr\x17K?<;Q<\x97)c\x12YM\xcbb\xd6RW\x01\x03\xc8\x82\xa5\x83\x06\xca\xe5*p\x02K\xe9\xac\xdb\x8e!\x03\xab\xd4qF\x82\x04cH\xd0p\xc3\xf7n\x04\xbd\x84\x9e\xc7i2\xe1\x94\xf8]\xccf69\x88\xcf&\x85\x01\xc4.\x0fT\xfe\xd2XNy\xc5\xa7\x8c\xd4*\xe5\xfb\xc9\xfe\x01?\x07I0\xae\x16\xd0\xa9(\x9d\xe2\xec\xc7r\xf6\xe2\xd7\x8a\xff\x92\xbb=H9\xbe\x06I\xc5\xcb\xb0\x10\xcf\x8e4\x82\xa9\x81\x07\x90{\x9eR\xd4\xe9Z\"\x1ee\xdfy\xd9\x9b\xe4\x9aZu\xd0\x1a;`\x9c\x92\xd8Y\x94Hk\xbc\xed\x16\xc3\x84?\x84Ym\xc0:\xea\x8d\xb3\xee\xf6k2P\xe7\x04J\x8b,_\xa9\xb8x-t\x11&\x06@\x8e\x86 b\xb1\xfeE\\<\x16\xf44@\x1f\xb6\xfe\xc9 \xa1\xc52'o9\xbd\x0e\xea\xc4[\xb1R\xce\x81\x97\xbd{\xee\xc1\xd6\xf9P?7\xf4\xd1pQ\xec\xd2\x0d\xb6\xb8x\xae41\x9b\xf5\xaf\xf7\xd3\xb12%\xc86\xebA\x9e[\xce\xb67spR\x1a\x11r\x01/\xfde\x9e\x8d\xbc\xd0\xbe\xd4\x89Y;\xdcKo\x1b\x94\x03\xdb\x99E:\x88\x08\xba3\x93\x80a\x82\x19\x86\x19eL6\xf7H\x94}\xea\x80\x80\xb6\xda\x9d{K\xed\x98\x8a\xc11`+?\xd2\xfeI*\xd6Fgk\xa2*\xaf\x03\xb24\xc8\xe15\x1a\xd2r?\xe8\x0c\xce\x9edp\x0c\xd3I\n.\xb9\x0f\xe0\xb3\xc1s\xe8{\x12\x01\xb2W\x8dd\xc0\xaf\x1f\xbf\xb3TO{\xc2\xdf\xd6\x81dS\x0f\xfedO\xfc\x81\xc3oOH&*j\x19\x1f\xac5>\x9c @,\x9d\x9c&l\x8e\xe0PN\xb14\x13.\xc8\xd4\xab\xcf\x9f\xaf\xd3\xe78[Rv\xed._\\\xa7\xcbOd\xf5\xa3`\x8aY\x0b\xba~\xdd\xfezs\xdd\xae\xbc;}\xd9\xdd\xe9 \x13\xa5FK\xa7\xe6*\xc2\x86V\xbe\xcd\xf1\xf8\x93H\xd3\xa9(\xcaW$\x90\xbf\xfc\xb4\xa1?t\xa6x\x14\x15\x90D\xc6\xaaVRJ[\xb3_u6k\xa6m\x1ce\xac\xe5o\xd1\xab\xf8\xc0\xe6\x8eyr\xb2\xc8\xc9\xb9\xc9\x14\xec\x97\x85\xe5\x9f\xbeIQ\xeb\xc5_\x9f8\xf2\xf6fJ\xaa#\x11d\xa5H\xc7\xf0\x87F\xe9\xa8\xb8!\xa5\xbb\\\xfc\xaa\x13\xbd\xcck\n\xbf8\x93R\x7f\x8fz\xed\xe0{>\xa0\x7f\x92`\xd73\xff\xdd?\x9c\xb8z.k\x92\x9b\x8d\x9c\n\x15-\xab\xadt8\x17\xc1\xa9\xc5\x9d\x12d~\xd8\x8b\xe0\xc4\xa1\xbc\xc1\x04pL\xf5\x86\x91/\n\xbc\x11h\xcaU\xb1\xb8I\x04q\x18\xc1\x96T}T~U\xe6\x0eD\x1e\\\x19~\x18$\xb2P\xd7!\xe7\x02\xa4\xf6`g\x0fK~\x1d4\xab\xc9\xf1\xeb\xcae\n\x17zvl\xc6g\x14{U\xf9\xc6\x9fp\x9bW\x93\x1cZ\xa1'\x8a\x8f\x19\x1f\x9b\x82@m\xc8C\xea*\x8b\xb2>c\x16\x95\xd4\x07Q\x97\xb4\xd5\x14\xa4\xa5\xa3@O\xb8\\p\x08\x19\xee6\x93\xbe\xc2\x82\x8f\xd2\xe9\xa6\xd4/\x89\x05\x8d`\xe9\xe4U\xb8D%$\xb6\xc0\xf8\xe9\x01GD\xb9\x9e\x84\xf3#G\xc12\x8c\xe0(\x881\xeb\xc3\x05?'D\x0e\xd7!\xff\xcc7\x9d;cn\x1e\xaa\x95\xa8\xf4W\xe1\xf6\xd9\xba\xff\xc2\xcf\x13\x976\x80c\xea[l\xcc\xf2\x08\x1b\x0c\xf8\x02h\xac\xf3\x8br\xa6\xb2\xbaP\x04\x99\xc9\x96\x83\xbbW$\xde\x0e\xaa$_U\xcb\x07\xda\xdf\x8f\x1e=\xe2\xf4\xe3\x16\x9c\x99\xf7\xf9\xb2\xde\x08\xba\xe9k\x1fY),\x1f\xef\x8f8^\xaci\x1b\xc3Z\xfc\xb1\xc4qI\xbd\xea\xb0\x82\nl\xc3\xb9\x84\xccH\xe8\x15\x07\xf5\xd5\xcdB\xfe\xe5C\xf1\x1d\xe1+\x0d\x070L\" \xbeK\x9e3\x17\xbd\xac\x12k`\xf5\x82Z\x86\x02Z\x9a\xe8:\x12\xdfph\xd1a2\xb2\xd3\xcc\x02M\xb46\xeds\x1c,\xd1-:\xe0\xaf\x15\xf5\x8c\xc6>~ \xd3V4\xa1\xba\xae\xc2\x90\x1f_\x8be1\x0b\x0c\x9eEV\xf2\x12+\xa0e~@\xce\x9c@.w=zmUj\x95[\xb7\x00\xb3\xb0\xd6\xd4+\"'c\x99\xd8Wl\x7f?\xce\x12\xc1S\x82\xc9h\x87\xbc\xa3QX\xe3\xc8\x98\x0fG\xa6.\xe5l\xc0\x86\xb6\x04x\xea\xca\x10\xab%\xf9'5\x115FEKl\xad\xfe\x01F.J]\n\xd9\xcd\xb4\x99wU8\x8d\xf2|\n\x0b\x90\xd1a\x9a\x82W\xc9\x99\xd6\x8e\xb9d\xb7\xe0\xb8\x85\x14\xa9\xe8\xb2\xf9\x1f\"\x7f\x9dJ\xdb\xff\x0e\xec\xc1!L\xfa\x8bLT\x82\x98\x0cSN\x8dZ7\x86|\xe4\x9c\x1f\x9f\x08\x06S\xfc\x0e#\xec9hh\xff&\x95)\\ \xcc\x11L\xbaX\xd2\xab\x08~\xbc693F\x97!vY6+\n\xf5\\\\ \x82z\xfdp\x11\xf9IP\xf6\xb1hF\x12EC\x84\xa6\xd7J\xd8x\xc3\\\xce\xb9%\xb8\xbb24\x1b\x95\xb3\xc3%\x13\x8f03\xf2H\xc4q \x19\x89\x99\xd8\x89&x\xaeM\x17k\x99\xa1U\x02\xe8\xa7$\xc8m\xa0\xd2\x04D&Y\x1e\x8a@b\x0e\xa9\xb2P\xf0]\x9a\x9f\xa7u\x18\x9a_\x1acL\xe5\xd6\x00\x82\x14n\x81 \xb5\x91\xae!\xa1\xce\x1a\xca\x1c3AUtz\xc9D\x93\x08|s\xe7\x0b5B\\.\xf3;|\xef\x8d\xe1\x10\x16\xc3\xe9\x08\xdc!\xeb3\xa1(\x9b\x08\x0b\x8cX\xe8\xfaZ\x99g'\xd4\x04\x13\x8f\x83B\xc0\x01E\x97\x85F\xde\xc7N\xf2\xeep\xf3\xaaU\xfc\x92\x0c\x01\xdf\xcf\xa2\xde\xcc<\x8c\x103v\x1fHV\x9f>\x80%\xa6\xf9\xe1\xb81\x80\xbd\x10\xe2\xe1r\x84hp\x0b5\x0bl\x98lo\x8f\x1c5\xeb@\x13J\x87\xf9H\xa8\xb8\x84/|\x80 \x05\xb7\xb1\xda\x98\x81\x90\xf0\xc7\x8b\x08\xd2\x08\x96\x11\xcc,\x90\x94\xe79\xff\xbf\x08S/\xa1\xc4\xe5?\x16,\x86{\xf0/\x98j\x9c\x8b\xba\xe3h\x0f?\xde357\xab\xda\x99\x99\x11\xf1tSr\x7f\"\xd1m\x86\x14\xfc\x00R\xf8\x17\x92\xfd\x14\xd6`\xc1\xd0\x0b\xed\x93\x82\x05\x8b\x08\xa6\x11\xcc\"8\x0d\x9b\x01\xf8\x1d\xe2\xc7yY\xed\xa3\xf2\x80\xb0\x1f\xb5B\xbdZ\xa6\xbf\xc9\xb5\x08Z!\xc5P\x80O\xb9\xa7\x1eb\x99=Q\xf3\xacslz\x97\x88\xf6\xf5\x0e\xdd*\x8d\xa4\xfa\xcc1\x06\xb7\xa2#\xe9\x92\x16\xf0%\xb5L5\x00\xa8\xbbn\x19\xa2\x81_0\x80\xafH\x90X\xed\xe7\xe0\x14\x17\xc6\x19e \xdd\xa8\xf8C\xbb\x7f\xedW_\xf8\xccv\xecj\xa8\xb6\xa7mct\xe6J\xb5\xe6Im\x10\x90:0\xf9*\xa7|\x06s\xb8\x0dw\xdb-\x8f\xd5\xb3\xfd\xf6\xb3i\xf9\x9d\xcds\x7fa\xf1\x188\x97\xb1CG\xc6\x80a\xe4\x9b\xbb\xf3XZ\xe4\xea \xe6\xc9+\xa9\x9d\x99/\xa4\x18:\xec\xaa\xe7D\xdd5\x1e\xc4`r\xa9\x03\n^\x89\xe3:\x87G\"kt\x0e\x0fa\x0e\x87p\x81\x99\x07\xf2\x08U\x0c\x18g\x8a\x85 X@\xfb,\x13\xf2w\x88ei\xd9\xc6n1\xe8'r\x9c\xfc!z6\xa4\x01\xe9\xd2\xf4\x96\x9a\xda\x0e\x7f\x13\x93\x17\x89\x9f\xa7\xc5\xc4\xed0\xa2\xe5\x01\x99\xb1\x8e< \x0b\x16\xc1\x05\xe1l2\xf3\xc8\x03\xa2 \x1f\x81=\xc6r\xc1\xb4#\xeeKsZ\xbcJ\n\x06\xc3^\x04\xbdQ;\xa9E\xad'\xcf\xa4\x16\x89\xaa\x15_%\xc5\x0f\xcb\xac\xe4\xa4\x9e\x95\xdcq\x9ar\x01\xb6d-1I3\x8e<\xcb\x93\xb3\xc4\xe6\xd9\xa6d.\xde\x13\xed\x8b2\xa1\x04n\xc1\x99!\x14\xd2\n '\x0c6\xcb\xae\xe1k\xbf@\x901\x04\x99d\xabjU\xf3\x1dE\xa00\xb1\x7f\xe5\xc4\xc6\xe0\xa1\x96\x0dvs\x975\xc0c\xe1!\xec\xc2!|\x92\x19\x0cq\x9b\xed\xca\x08SqsW\xa8\x1f\xf7\xc43f\x8c.\x03\xb0'\xd8c\xe8\xfb\xa4\x16\xd3\xfcNe\xcf9aq\x92\xba\x19*\xe5\xdeo})q\x06\n \x14\xdfb\x94\xc08^\xc4\xe3\x84\xad\x84A|\x00\x97Xo\xbb\x195 \xe4A\x14\xb12\xf1R\xd6x\x89\xf4ORrN\xd2\xea]\xfb\"n%~\xe1\x06\x89\x08\x9b\xa8BL\xcbuV^\xf6b\x14\x1c^\x9b\xb8\xdc;7\xd3\x05\x82E\xac\x14~\xad \xa4\xcf13z\x17^\xb9\xe2,k\xdbj\xb3\xf4-H \xcaJ\x1c\x9aU\x03 \xcb,\x992T\\h2\xaf\xcah\xaf^R\xba\x0d\xf1p\x91&c\xe4\xdb\xf6lQ\xbb\xb5\xc1&\xb4 \xf9&d\xa0\xd1\xcbn'8\xfe\x0d\xc9$tjZ\xfeTK\xab'\x9b\xc0\x15\xe6\xf8\xd3\xc8>!%%\x81j\xd7NE\xc1\x19)'(\x16\xcbb\xd6\x05 %\xbcU\x11\xfa\x96]\xae\xc1\xc9\xca \xe1\x1b\x16\xbai%\xe0\x9f\x90\x11\x91dQ\xd9R-;\xbe\xe6\x16\xbc\x8b2\xbb\x96\x16\x11%w*\xe8*l\xe3\x1e\x1e\xe6^%\xd9\xea`\xcb|\xf3:|R\x87\xecn\x04;{\xeeV\x97\x14wWW\xcb\xad\xf5\xb8\x16\xb0\xad\xa1a\x9f\xf0\xc8\xd9\xf1\x05\xb3#\xfbd\x99HnH7\x07\xb1\x17(\x9a@\xee\x00\xf0&\x89W\x1e\xfb'^i\xf7\xe1\x95\x90\xa3\xd9\x91o\xe2\x95vw\x1b\xe4\x19y\xec\x97g\xc4\xdc\x87\xd7\xb4\xce\xaf\x93\xd7\xe3qg\x9e\x91&\x9fx,\x08\xad\xd7\x89\xa6o\xc2v\x11\x8dz\xcb\xbe\xf5\x97\xce\xbf\xa8\xee_9\"Y\xe2\xaf\xac\xfa\xe7\x1e\xddfI\x19\xca\xedi\x17gOJ\xe4\xb3\xaf\xcd\x06\x05a0\x14\xb1\xabB.\x9e\xa8\xa7\xec\xdfW\x04\x86b\xd1\xd6\x8d)\xd0F\xd9)\x9aur\xa5\xfe\xd8 _\xbc\x02\xa1s@\xa1\x04\xc1\xa2\xd7w\xa6\xd7\xad\xec\xdc\x98\xc8_\x92d\xe2\x82\x05:\x9b\x135\xb8\x9c\x1a\x87\xa3s7\x91\xc6\xdcl\x94\x90\xc2\xb4\\I\x81\x12\xf6\x00&\xac\xad\xc1\x9a\xb1v\xe2\x89W\xcf\x8f?X2O\x9c\xa3\x05]\x83\x9cM\x7f5gV<\xc0\xb1\xa3h\xac%-\xa8f\xd2\x8cn\xd3\x7f\x9d\xb3\xe1\x8c\xa9`\x90sV\x05\x83\x9c\xb32\x18\xe4\x9c\x95\x89\"\x9f\xc8\x9c\x91\xda\xbbx\xbf|[\xbd\xa5~\xe1\x8b\xa5\xfd\xed\x89\xb2\xc5i\xb7\xd5\x17\xea\x17>\xaaR{=)\xf3|U\x0f\xcadOOj\xd9\x9f\xf0\x85f\xe2\xa0'\x0d\x89\x19_\xd2\x93\xf4<\xd1r\xf6\xc8\x87z\x0e\x9d'\xb5\xa4:\xa2\x0b=\x03\xce\x13=#N\x04\xf3\xb6\x08\xf4\x84L\xb3\xdcd}\xb4iZh\xe9\xd0\x84\xde\xcc\x0c#\xdb\xca\x8d\x81\xeb\\\x86^hL\x97Y\xbb\x88\xfaC\xe1\x13e\x0e\xad\x15\x0e\x80\x8f\\\xadK=\xe1p\xc4O2s7\x99\xf4\xbb\x10\xaaHs/LT\xbd\xb0S\xf2\x18\xf4Q\x0c]\x06,,R\x1fs\xba\x15\xd7\xc0\x8c\xb0\x85\x1d\xd4q\x86!\x8e\x06\xdfJj\xa0jSe\xe3\x80\x85\x95,\xf3\x80\xf2\x12\x06p\\\xe5\xce2\xcf\x7f+1\xabTj\x8e\x13\xbb\x0f\xa0\x10.\xa6\x05\xfaIJX\x14\xa3R\xfc\xb2\x12\xe4\x0c\xddD\x96%\xf48\x8d\x0f#X6)\x98\x01G\x1fO\x19i\x1d\xef\x9d(\x1a\xd4q\x14\x83\x8c\xbf\x00S\xa5\xf5\x13\x85\xfa\x0e\x84\xcd\xdc\x08k\xee\xc4\x0b\x07\x93:\x0e\xda,J\x88\x839&\xcb\xe4\xd8\xa5\x83\xd1\x80\x82\xf8Rf\x86\x0c\x1a\xbf6DN\xb5Y\x9c('\x9b\x8ceoRY\x91\xa1\x92/\x92~mq9M\xceD\x85\x11\xc4udi\x1fog,\x82\x15\x8b8\xd3\xe0J\xa3~b?\xad*^]\x1d\xe2F\x08KEay\xb2\x1b_\xc2\x04-,\xc8\x1dQ3Ryf\x87O-\x91\x88d\x1cv\xc3\xc6\xc4\xa0\x16\xf7\xcc\xe7\xb6\x8c\xc0jc\xad\xe9q\x96\xb5rV\x16O\x13u)b\x12K\xff\xa5C\x85`\xe2x?PQ\xee\xf8\xd3\xce\xa3\x82\xf4K\x89e\xe5\xc3]\xf4\x8c\xdd\x81\xd8\xfd \xaa\x18\xf9k\x16\xbe\x11_y\x04s\xc4\x1d\xfe\xf2\xdca\x0f\x95@\xe8\xe4\xe1\xd5\x95\xa0\xe3,\x9fvZ\xee\x87SG\xd1\x11\xd0\xd4\x12X\xedq'\x85\x03N5\xdd\x9f\xc8\x96\xd1\xb3k9$\xe6\\)`\xdcvx\x97/a\xd1t\xcb\xcfPs\xdc\xb1\xac\xc2\xa9\xd5\x7f\x01S$/\xf5\x05L\xe0\xd1#\xc8\xdc\xdf\x8d1\x00f\x9b\x1f\xeb\xea\x03\xc72\x8d\xcb\x05\x1d\xdf\xf0\x82\xe2\xb9\xf6\xc0\xea`\xa1_|\xed\x8d\x19]L\x97Z\xf4\xa5M\xe8k^\x89,\xb2\xc7E\x9d.\x85|\xf3ZJUh\xe7\xcbv;\xbe\xba\xf80\xd2\x86/a\x17\x82\x83.\xf5#\x92\x8f\xe1\x00\xd2.$\x079\xf2X\xb8\xa2\x17\x98y?\x13\x87R\xc2Q\x83\xf2S;\x0b\xedn \xe0\x9c\x92co ]l=\xf6K(qaL\xf6c;D\x96\xad\xec\\\xe7\x0e\x8d\xc2\xb2T\x93\xc3\x0e\x17\x92\x96\x9a\xaa\\\xfc\xd4T\xe5\x0co(=9\xc5_U\xd6\xa3e\xa9$\xcf\xf0\x87&5&\xe2\x86\xd4\x97\xc7\xe2W=\xb9\xd7\xd2\x0b\x14G\xcc\xa5Q;c\x18\x06}\xc6\x07$\xec\xfa\\|\xf34\x85_\xb6\xa1l\x03q,\xfc\xf1er\x1ewL\x05\x11N\xf3\x0f\x15qS\x8a\xd9\xd6\x07\xc8\x0b#^j\xbe\x14\x99kc\n\x96\xb3\x83sK\x1b\xc4u\xb8td\xcc\x19\x0b\x13\x9f\xb4\xe5\x89\x8d\xa1`\xe1\xd4$\x8d\xc5 \xa5\xf2F\x05\x92\x0d\x136\xde\xb2c\x18\xc0\xd8\x1c6h[\xd1\xa2>\xf2\xf2\xf8'\x95[\xa6\xdeUT\x83\x9d\x80<\n;-\xde\x12\x0e\xcb\x9b\xcaD\x16\xeb\xe3l\xc7 \xd8\xf0\xe6\xd8\xce\xd3\x95j6\xf4\x07(c\xf0\x88\xe6\x99J\xa4\x07\xea\x9c\x05\"?\x97dK\x91+\xe5\xa3\xe2\xe2\xa5g\x1a\xc3\xa7\xf6\x91\x94\x16\xf4\x86\xedW\xb7\xac\x9a\xf9A\xf1\xe5C!\xd0(V\x10\xb6\xe1\xdc\x86t5sD\xc9DJ\xbe\x15\xbf~ \xfc\x16\xd0\x15\x07\x0b\xab\x0eJ\x1f\x06\x11\xaa\x95\xa3'\x03\xffhg\x00\xe7N\xc4\xeb*\xf3n\xad\xe8\xe5L\xd2\xa3\x05\xbd\xa8\xa83Q\xeeX\x7f\xa2\xe2\x0f,\xe5\x8d5\xb3\xbe\x9en\x07\xf33\xd8\xd9\xf6\x0e\xf6?\xf1a\xff1\xc6\x03\xb6m\xc5\x19\x96\xa5\xcc\x8c\xd8H\x91\x9b>@\xb3\xd1.\xfe\xbd\x8d!c\xbc\x05\x83\xc7\x02\xc7\x87\xb8\xb9\xbf\x92.2\x15s\xdc[j\xd8\x86\x86_\x13\xa7R\x13\xfb+\xd1#\xd5\x91i\xac\x82N\xb7a\xccG\xfd \xc4\xe7r\x1fa\xf5\xac\xb4\xbe\xe3\x0fa\xa8\x8cG\xe9H\xee*.\xd8\x8da[e\x1f(\xf8\x9f\xe7\x86\x11\x8d\x85L\xc8\x1f\x8f#QF}\xcc\x0f\x00\xf1o\x82\xff\xba&2\x15\xd2X\x82\x11\x04\xf8\xe72|\x00\x0b\x0e\x11\xec\xb9\xe0\xbb\xc9k\n\xb5\xa1\x8b\xf1\x9a\xf1n\xd2\xe5N2\xc3 \x8a\x87\x18#!\xc8\xc6RH\xdc\x07|`x[Soat\xe3\xc4\xbc\xb2X0]|s\xeb\x16\xc6\x01\xa3h6i\xa8 :h\xc5\x1c#X\x90\x90\xa7bz\x9c\xdf(\x1e\xc0\n\x1e\xc19\xff\x87S\x82.Y\xe2\x14\x060E\n\xb22+I\xd4\xc5\xbb\x9bK\x92s:\x12\xfdV\xbf\xad \xa4\xcc\xfc\x9d\xfaP\xf4|\x8e\xb4\x0b\x060\xe9\xa0L\xa0\x18|\x05\xb2\x80/\n\xc6\xac\xcfj\x8a\x93\x1c\xd9\x98e\x88g\xdd\xa3\x01,B\x8898\x16\xb8h\xf8o!\xdc\x16*\x07\x85VSR\x0f(\xda2\x85O\x96\xee\xc8\\8\xce8\xa5B\xfcp\xae\x9c\xdc\x87\xa9S\x98\xe1\x0bs\"\x84\xeeG\x8f\xf8\x81\xeeZ\x18>\x80\x13\xa4\xae\x8b\xea\xf5\x10Ns\x12\x7f\xb2\x7fu\"\x05\xb5\xed\x01\x04bK\x85\xf05\x9c\xe0&\xd9)!#\xf7\xd3\xf0\xc4,\xdc\x9a\x177\x15X\xfdH\xaa\x11E;M\x90\x16|ev`\xcc\x97(\x15\xfb\xe1\xa1\xd8\x0f\xb5\x0f\xca\xe5,8%\x90\xef+\xea\xb2#\xa9\xca\x8e1\x8ar\xe3\x94\xa4KTkT\xc7\x89`\xbbI\x8d\x9d_V\xba\x1d\xc08\xce\xca\xbd*\xd5\xdd\xabf\xbe\xeeU\x9cL\\\xb0 \x16\xe2\x0eFj6\xa3\x1b-\xc7\xf1c\xbf|\x91\xb9\x9e/\xb2\x16A_eY[\xba#B0)\xb6\x93 F \xc6\x9a\xbe'\x15\x10~$\xf7l\x82\xeb++\xfd\xc5A!RJ\x8aU\xbf\xe9\x94\x92\xb9\x88GK7@\x8f\x04\x1e)\xa7\xc9[\xb7D\x82\xa8\xca+9A\x92\xa2 \xdf\xccrcY\xa9\xb7])\xe6\x84[\xf5.*\xe5\x94\xce\xfa\x9co\xcas\xaf\xf6\xdf\xb9\xdbw\x16z|.\xdc\xe1>\xb0\xaa\xbe#\xbf\xb5\xb1\xdf\xcd\xf9\xff\xfa\xfa\x8e\x1f\xdcP,Ka\x8e\x9b\x08gk\xf0\xb5oJ\xbe\xba\xea\xe1\x9dfT\xb1+!\xaa\x14\xe1(\x02\xe1\x8f\x03\xb4\xdb\xf7OD\xea \x91;<\x15\xf6e\x8f\xdc\xe1^sz\xeeT&\xac\x842a\xc5{|\xcd\x02Q\xdd\xe6\x88\x05\xadP?K\xeb\xbf\xbb%\x0ci\xda\x89\x14KoM\xbd\x14K>8)\x1c\xfc\xbcHI\xc1,\n\xff\xa2\xe2\xf8\xf9\xd1\xba\xb4\xa9\x12\x06\"o\x93\x19o\x85~\xa2KQ\x18K\xf28\x10\xda\xd3\xea\xe7>|\x0d\x89r\xdcD\x1b\x910V\xb6\x93\x9fZDXu\xc9\xfe\xb5\xf9H\x15\x0bJk\x96}\x14\xf6Y\xf6\x92\xac\xc8\xe4\x98|\x0e\xc2\xcd)3\x19\xeeZ\xb8\x86\xb0?M\x93E\xc0;x\x1d\x8b|:\x1anr\xa2\x9b\xd7p\xb5\x8e\xb9\xba\x933:\\\xa0\xf1L\x95}c\xa10\xfe)%\x86\xe6\xdc\x1bkj\x0bND\x96J45(/\xb5X3\xabm\xa6B\x80\x18Qi\x19\x0e\xf7F]\x8b\x9d\x0b\xd5\x9eXG9\n\x91j\xdd:\x081?\xe9L\x1f+\x12Z\xb5\x10\xcbB)\xb2\x19+\xc9\xb0\xf1=\xb9\xfc\x9e(\xca!|\xc3%\xe5\xc8\xcc\x9c\x0c\x07\xe3kt\x7f\xf7\xcc\xbc\xfc\xa6\xc3\xeb\x04\xdd\x954\xaf\x93\x93eA^\x92U\x01U)\x0bE\xf1\xdaI|m\x9d\xbe\xb7\xd0tc\x8f\x9b7\xff\xec\xafm\xfe\xd5_\xdb\xfc\xc7\x8e8\xb6\x7f0W\x8aXV\x1bA\xbd{~\x83o\xf1.\xafN\xad9CR\xe6\x08\x8b9\xaa\xe2%\x9d\x0d\x9d\x97e\x92\xe5G\xb2\xfe\x19\xfa^9\x15b\xfe\x83\x05}7\xc9n\x02\x0b#\x12\x99*\x8a\xf09\xcd\xe2\xa2\xd3\x0d\x15\xf4\x8e\x12:N\x97\x13R4\xab\xda\x97-\xaa\x176kv\x16\xdb[\x1c\xc7\xe3\x19yO\x8a%\x86Q\x12\x1aaE3\xe9Q\xf8\x91\xe2\xe3Z\xd9.W\x04\x93\x12C\xcc\xce\x14P\xa7P\xadzV\x9e\x8c\xa1\xf4:\x14\xbc\xa1]\x1da-v\xa5y\xa7n:?\xa1\xef\xe5\x07\xc1\x9b.\xa9^i7UW\xa2]\xbb\x98\xaeXx?'Vu)\xbbf\xee,_\xab.\xe4RHg\x1d[uU\xfb\x0c\xdd\\\x87\xbb\x1d\xd9\x90\x00\xc3:\xd5\xbb\xda\x87{\xa3H\xfb\xbb\xe5^\xd8\xbc\xdcfQ+\x19Q\x97-\x8b\xb9\x1f>\xf2\x95\xc2\x15\xfe\x9d\xcbLp\x00\xbf[\x11\xa9v\xd3F{?ws\xba\x9d\x148o\x12\xdd|s\xd2b\xa7\x01y3\xa4\xd3\xa7\xa82\xc6\x81bbz7\xc5\xadj\xa6d\x18&\x8c\xbe\xf6\xa2\xc4Nn\x14\xedp@N\x02\xe43\xbck\x13\xa0\xac\xc3\xd9\xa6N\x83\xf2\xa0\x9a\x91\xfaXZ\x04mD)\xeb\x98\xb2\x99(\xf9\xcc\xb9\x86\xc3o:\xeb*o@i\x94\xf8\x9atR\x19t\xb4\x93\x04F\xc9\xaf\xf6\xb7\xcf\xa5OZ&h\x83\xdbE\x05}\x13\x9c4H\xc9\xef\x1cZ\xcbHC\xb6\x18)\xd0\x92\xe3\x9bq\x01\xc0\xa2NhUE\xb4\xec\xf1\xef\xbb=\xd7\xdc\x1b\x9c\xea,\x16m\xeev\xba s\xe4\xe2\xb2\x88`\x7f\xd02\xe7\xcd \xa9S\xe0\xa3y\x06\xa0sW\x1b\x8c\x13\xf4\xbd(\xa4D\xdb\x961pW\xa8Yj\x90-W:\xc1\xb2'\xd4\x04\xc8\xbc\x8f;{\xb0cHa\x0d\x92{h\xd2X+WP\xa7\xb1\xb5\xc6--_\x8f\x8d\xeb\xe0\x0e\xa9\x81\x97\xa3\xe6\xe8\x90\xff8\x0f\xd7Q\x8c\xe4*\x82-\x1b\xec\xcc\xb1E\xae\x19\x19\xcfx{\x0f^[\xfe\x0f_\x95_\xc7\xc9\x8e\x9b1k\xa2\x9a\x15\x8f\xcf\xcbD\xbd~\xc7o\x86\xc7\xd4\x8a\xf7\xb2\xb5U\x11\xc4\xccq\xfaf\x7f-;P\x8e\xa7\xcd\x0bH[\xbb\xa1\xb4P(t\x98\x0e\xa6\xc0\xe5My\xae\xc5 \xd8\xcf\x98\xa5\xb9*/t#|\xe2p\xeb\x05%5\xe8|\x02~P%R\xdc\xde\x8e \xe3\x0d\xe5\x12\x02hn\xb6\xe7\xf9\xe4Sm\xfa\x84\x81Z<7\x1f\xe1\x03\xa6&\x1f\x918*/v\x03m\x036\xc3\xd3\xf9S\xe1\\\xdc\xc9\x8d\x80\n\xca\xa8s$\x89\xfb\x0be\x08K|\xb8\x12\x906\xb1b\xb8\xeb\xb0\x9a\xa9\x0b\xb3Y\x1a\x13\x83\xeaW\x1d_\xc6h*\xd4r\x02}\xc6\x8a\x882\xb7:\"\xcf\xd8\xcap\x82U\xf01\xf3;~\xb6\x81'\xbe\xc4\x8fX\"N\xf9\x0c7r#\xe2B\xc4\x1e\xdcF\x1f\x1c\x0cDD\x9f\x1c\xf9\xfe[Y\xc1,\xeb\xcc\x9b\xc4\xd1\xe6\x9d\xa8cf\xb7'|@\ni \xc8\xe1\x04\x0c\x12X\xaf!\xe6\x7f\xc5e\x8f\x1c&}\x96 \x15\xbav\x10\x07a\x05)\xf3\xa0\xa4\x93w\x0c;&\xcc,`0\x10\x9e~\x01\xdfl\x85tD\xda\x85\x03c\xa5\x89s\xe9\xd5\xe8>vR\xc5bV\xe1\x06K\xac\xac\xa5\x8c\xa1\xcb\xca\x80\x18\xc1\x16\x9eR\x992\x8b-\xcb4>A\xda<+<\x8ea\x99\xe1\x86\xc9p\xd3*)\x10\x93E\x15\x15\x93\xb6\xcd\xe9$\xa6\x9b1\xf8\xb1\x85\x11\xa4_\xa6\xa7\xca\x9c\xe09\x96!\xda\xa4\xc2\xbcf!F\x11\xb4\xdd\xe5\xaf\xf45\xbe\x9e\xb2N\xda\xf4x\xff^K\xe4\xd6\xd3)\xb4\xd1Zm\xab\xf8\xec\xeb\xe3\xb1\xbc7|\x96\xaa\xb5z\x10B\xd6yZrxmo\x17\xf0HC\xf9\xae\x93\xd8+\xfa\x1d\xba\"\xe0\xf9u\xe5V\x13\x10T\x13tM\xa1\xe4\xaa1 \x96\xd2\xe2\x11\x0c\xb0g\x91\xa8\xa3\x13\xc9'\xcfU\x92\\\xf4\xc6\xd05\x95\x9b(\x08\xeaXk;0\x7f\xf2=0\xddd\xfb\x86x`;\x19K|\xf6\x08 \x1c.\xef\xe72\xc8\xc2E\xa7\xba\x11\xdd\xc1i\xa7\x9d\xa4J\xa4\xe4\xc6\xd3\xb2\xc9u\xa7aE\xb5\x8a\x16\xdb]\xb8\xd9\xee0\x02C\xa0\xe5\xcd\xf0\xdc7\xb0,Y\xee\xb3.\x9b0\xf7_~\xdel@\xb0p\x93\xe3\"\x19\x12\xb5\xabk\x92uP\xa4De\x1d\\JZ\x11\xd6Y\x7f\xa4\x0cY\x832d\x918\xc2\xb2.\xba\xd0-7L+\xabG\x07\x8f\xcf1\x04+\xf9\x8d\xf1/\xde\x81\xe0\xf2\x8a\x1a\xde\x8ee<\x93\x83\xbd\x87\x8bY\x92\x12\xb0:\xe5\x81\xae\x0e@\xdb\x95>\xf3\x04\xfb\xd8\x88\xe6\xf9 ?\xde\x88\xe1\xe3\x8b-\x01\x0e\xfcE:e\xa9s$\x07P\xce\x86\x04E\x07\xed9WUC\xac[\x99_\x85\x89\xb2e\x1d\n\x04\xd0\xb8\xe7-\xf4\xbcJ\xe1!\x16\xac\xb9\x05q\x80U\xfb\x90(\xa7\x18\xa8\x0d\x07*M7R\x04*\xcb\x01$()\x86\xa5$\xb1\xb5\x8b\xc59\xedxeW\x95\xf3\x85\xe5_\xb7K(\xfd\x15\xa6\x8c\xdc.\xae\x81\\\xc5aG\xa1\xf3\x1b\xa3R\x92\xadJ\xbc\x94\x14\xc4\xcbd\x02\xea\xdc\x92\xa9\xe672\xcf\xa6\xbe\xf4\x06d/\xb9\xa4\x00\xa5\xfb\xf5po\xc4%T\xd4\x10\x06K\x15O\x81\xd8\xc5\x8f\xd18H\xab#\x93\x96\x84#\x8f\xc4\xf9\x99v\x93E~-\x85sn\"K\xa3\xa5\xad\xe5u\xb6\xa0\\\xb4\x90\xac\xa3g\x97\x1di\xbb(`\xd7\xaa\xdd C\xbb\x01E\xf533\xfd\xec\xa4\xa8\xc2#\x13]@M\xf2\x8b\"\xb8Kk\xda\xe8\xccN-\xc5\x9eT\xda\x8d\x9a\x83 \xeb(\xe2$\xe1>\xccq\xe4\x99(\xbdx\x08\xe2C\xe9^\xc6\xac\xee\x83e\x96i\xeb\x11\x91\xf4\x8b,g~\xd2\xacb\xa2\x022\xbc3\x8a\x80\x0e\xef\x8c\x10\xcb\xc9p\x7f\x04;@\x87\xfb\x86\x0c\xc1aU\x90\xbc\x91\x95\xc1j\xb1I\x86l\xa4v\xd2\x00\xf6\xdbm6+\xf4\xb9\x1a\xe2\xa0\x1f\xee\x99\x06&8\xd7_e\x8d\x0f\xe1\xd6\xfdR\xfc\xfa!h(\x04m8\xf5\xc2\x89S\xc2\xdfE\xc3+\x0f\xbb\xd1\x17\xe2 \x1fJ\x89\x1bV\xbc\xc8\xc9d9\xde@\x87![\xff\x15=+\x05;G\xd1\x87S(*,\xf9\xf2\xdd\xb6\x0c\xd4\x8a\xe5&\xdfWG@\xca&\x03\xaf\x0f:\x12\x89\xf9\xcc\xc3\xf5\xf4|\xff\xd5\x8b'\x13\xf5s\xec[N%\x8f\xbfu\x0b\xa8\xa6\xbf\xad\x85M\xae\xd7U4\x82\xf8\x05[\x03\xde\xedz-b[\xbd\xc6\xfb\xb2\x8a\xbf\xf8\x02\xa1Y\xea:\xf91OH\x90\xfbz8\x97k\xd6\xf2\xb3\x04\x81\x84\xf3\x84\x06u\xcb\x14\x0c\xfc\xf6u3\x0b\x9f\xf0\xf3\xac\xce\xc4\xdfE\xbcv&Bx\xb6T\xfd\x0bM\xa2\x81Z\xfa=i\xa9\x10\xe4\x95\xd9\x92\xf0\x81\x06\x94\xf6|\xba\x05Y\xe2\xc1\xb9\xe5\x9e\xc0U\x97\x022_\x1f~2\xc1O\x01\x86\xb0W>\x97\x1c\xdf\x1d\x07\xfe\xf5\xf5m\x1e\xec\xff\x06\x9c!\xaef\xa7\x00\x86\xba \\\xce\xe4\x9a\x80\x92X\xe0\x02\x88H@\xd2/\xb29\xb9N\x07\x1c\xbd\x1c\xcd\xcb\xfaR\xffFFJ\xe5\xc7\x8c\x11\xbb\xa5\xb3\xaf,Gq](\xe2\x00]\xb3\xbcy\x81\xf8\x87\xce\\\x08\xc2\xc4\"jr\x90\xfe8\xa3\x05\xcb\x97c\xd4,\xfb\xd1\xf7\xaf,\x8e\xdeI\x99\xcdFD a\x89\x116\xcb\xb3\x0bD\xf1\x0f\xab\x059\xca\xf3,\x0fzG\x97\x0b2fd\x02\xc3\x97\x11\xfc4\x02\xb6\\\xa4\xe4\x00z\xb0\xdd\xcaHk\x19\xc3?\xdd\xd1U\xaf\x88\x8cG\x08#x\xea\x1b`\xf5\x8b\xbb\xcd\xa5\x00[^\xb1A\x19\x17x\xbd\x9a\xfe\x87\xbb\xe9z\xc4V {\xfaUc\xb88\xb7\x15j\x81\\^\xbd\x12\x8f\xea\x1c\x9c\x14\xd7\\zT\xee\xf6\xd6\x13\xb41\xce\x9aY\xdd\xf1-\xe9\xa4/\xf3\xac\xbf\xd0\xb3\xcbW\xdf\x0bm\x13k\xa7.\xb5\x8c\x9eu\xe6\xba'\xf0Hf\xa3<\x10\xc5>\xe0\x10v\xf8\x0f\xbfs\x9fZ\xb6\xf2\xb9\xf4E\xfb\xc9x\xe0\xa3\x14m\xe7\xa5\xf9\xd3\x9f=0\x1f\x8f\xc0\xd3\x94@\x96\x03\x06E\xef\xa4\xc9\xa7r\x0f\x98I\xbc\x18\x14\x1f\xb5\x81@X\x97\xd9\x0b\x16yG\xe2d\xc1A\x94$\xd0\x99SLX\xb0\x13Z\xb0\x98\x8eI6\xd5*\x9e;\x9c\"\x10r\x88\x1e\xf5Ok\xc9>\xf3\xc0\xa6z.\x9bpr\xe8\xfc\xa2\xa8\x96\xea\xd6\xb2\xc6U(\xe5'\xb2*\xac~\x89\xea\xda\xf2\xe3\xca\xf4\x8b\xe5+\x8f\xb7\xf8\xc5\x8c\x11\xae^\x9d\xa8K\xceeB\xa6 %\xef\xf2lAr\xb6\x92\x9c\xaf\x7f+\xfc:#L\x13-7\x19\x83\xbat\x12$\xc2&7j\xe2\xaa\xdb F\xbf\x8a\xdax;\x8fo\xd3uF\x1a\x89\x98#\xe8=\x8d)\xcd\x18o\x1d2\n1\x85\xa4L\xcf\x9b\x93q\x96O\xfa\xbd\x92d\x8ah;\x07\x8bi\xba\xba3\xb7\xa9\xcb\x12\x8d\xd0\xbc\xae\xfa\xa7 \x9d\x04U\xd4]\xf7gW0\x8e\xd9x\x06\x086\xf7\x80\xae\x02\xe5\x9a\xae\x8e\x88X\xea'\x90\xeb\xa7\xf1\x9c\x94\xa1\xc3\x9fD(^\x8c?&d\x1a/S\xf6\x13\xe7\x960\xe7\x8c\xb5\x1b\xfb\x00\xc4\xea\x88\x80\xc3\x8f\xa4\xa9\x98P\x97\x05q2\x94)\xcaS\xab\x15C\x9d\x99t]\xa5\xe4\xa7\xb1P\"\xda\xb1\xa9h\xd3\x7f\xb1\xe0\x1d\x8b\xe0#gL\xde\xdd\\\x95\xaew7Y\xa5\xebm>!9\x99\xbc\x8e\x17\xf0g/\x82\xdeU\xbbV\xd7\xbbk\xd4\xea:\xd7k\x04\xf0\x95\x125\xfc\xed\x90\xadyh\xc9b:\x18F\x8a\x1f\xd2PT\xa6m\xd5\xd0z\xf7o\xaenS\x96\x9d\xe1S\x92I\x95\"}\xb4\xb5{\xa1\xcc\x88\xe0\x1c\xf5f\x95\xbf~g\xae\xdaG\xef\xae_\xfbHo\xb8]\x06\xb5\xd6p-\xf5\xb8\x0f\xb0+\x90U\x9f\x06\xa8\xb8\xd1 \xa7?rv\xbf\x91nDGD+\xf2i\xa30\xd8\xd2\xba\xdc\xe8E\xbe\xb9\x80\xa1\x0e\x90\xa1\x05\xd6\x12\xde\xe57/\xbf\x12\x17\xed\xa1O\xf3l~DY\xbe\x12\xbaRM\xf9\xd3\x8d+\x9b\x15J\x10\xc2\xdf\xa0U%\xc1#\xbf6\xab\x11\x85Z\xb7V3BEH\xe4\x12\xd5?\xb2.+\xdf\xd5\xaf\x99t\xe5$\xfe\xd5\x16\xd4\xd1\xc2\xf4\x9d-\xf2^\x18$\x1a\x84dRh\x84t\x00\x1fX\x1d\xbe\xc3\x99\xaanP\x83zY\xe7\xc0\xb0o#`\xc1\x1b\x16\xc1\xafa\x04o\xaeA\x81\xdb\x82\x1fR`\x13&\xd4\x9ao\xc4\x0dt\x96K\x13m\x8b\xa2i\xce\x86Q?rL>oD3\xb0q\xf5e\x9b.\xbc\xa9\xc3\xcd+T\xe8\\\xab\xc8l\xc67\x0e\xdf\xef\x159\xdc2%\x1b\xac\x8dQ%\x1b@\xa3\x86\xf74A\xd7\x1d\x89y*+\x87=8\xfc*l\x05\x896\x80 0\xb7\x13;t\xb2h\x06\x02\xa7\x02\x9fk\x87\xcd\x06`\xc8\xaf\x03\x06\xda\x00\xc3<^\x18\xf0\x15$\x18Z\x85_\xde|\xd9\x19\x119B\x94\xda(\xa99\xe0\xd6&\xaf\x99\xf3<\x1c\x97I\xc0l1KW\x9c@\xa9|\xcb\xff\x14\xeb\x10\x8a,=e\x0fV\xd5y\xd9|\x16\xc9|\xcd\x14\x0eD1 SWa'Q\xd8\xechB\x1b\x9f\x0e\x96\xd0\x01Au<\x99\x8f\x0bZ\xd7=\xb5\x0c\x1aV\xd4m\x82\xcd\xba\xa8\x9e\nye\x19\xa2N\xef\x8bRL@\x83\x8aP\x1a\xa2\xa2Y\xac\x02\x16\xc4G\xbf\xb0\xd2\xbcbZ\x0e\xd7RT' \x0b\xde\xb3\x08^\x86\x11\xbc\xd7\x97\xca\x14\x08\xe8I\xc4\xcbh\xc06%\x7f\xffe\x9b\xab\x93\xd2\xd8\xd7\xc7\xb8\xe9\xbcy3\xdca\x08r_\x96\xcc8S?\xbc\xff\"\x84\xbd\x11\x0ce\xbe\x18\xca\x14\x862\x85\xa1\xa2\xda\x96\xc2K\xaf\x9aa,x\xc6\"\xf8!\x8c\xe0\xd9\x97s\x10\x0e\xe4{v#\xc8\xf7Wb\x18\xf3\xc7/\xe3dn\x0c\xbf\xfe\xc3HT\xe1\xcf\x86\x88\xf4Jr\xba\xaft\xe8\x10)\xcct\xf1\x10\xedu\x94,D\xb3\x9fW\xff\x95\x88\x84\xc7\xa5\xed!\xbf\xbeb\x81\xb5\x88\x9e\xe6d\x11;\xdf*\xd1\x15K\xf4\xa30 \xaa\x12\xa3\xd8Z\xdd\xdc\x157-R,\xbf\xdaz9#\xa2\x1b\x81\xfd_\x83\xe8\x1e\x91\xa1~{\x01\xca\xf0\xca\x9a[\xb8\xa3\xa2\x86Z/\xd6\xe5e\x89\xde\x95\xae\x11\x82@\x0eS\x18\xa0~)\xde%\xee|S\x0e\x1e\xf7r\x06\x87\"\x91\x8b@\x89\x1cQ\xa2\xba\xb9'n\xee\xb5\xf3\xe5\xeb\x97\xc5e\xd1\x83&\xd4\xce\xe1z\x1a\x827\xf6G\xcf\xec\x8f^\xd9\x1fa\x8e\xaa \xa7\x11\x9c\x10.ZP\xed\xcd/T\xb0.\xa9\xe4A\xb7\xa1g\xd5\xb0\xd6:\xdc\xf8\xf8\xaci\xd4\xf9\xe7o/he\xf2qw\xe6\xa9L\x10v\xd0YY\x1d\xdd\x85\xe6\xf5\xcd[\x1b\xdc\x90\x18\xe2\x94ks\xe1\xe2\xeba\xf5\xb7\xd2Y\x18b6\x9b3\xf1R\xfeV\x92\x89Qe%\xfa\xbfuK\x1b@M\x9fk\x9eli\x1f\xd7l\x03v\x9dT\xff\x84\xcc\x17l\x85br\xf9c\x001\x95\xa2\xf6/\xa4\x9d\xf2\xb41UO\x8dq{\xd1*+\xb5\xb0P\xffM\xb3j-\xe9'\x9a]P\xf8DV\xd0\xfb\x1bl\x03\x81m\xf8[\x0f2\n\xfc\x97\xc2c\x8b\x91\xbc\x06\xbd\xad\n|\xb2\x98~Y\x8b\xc3\x8c\x14\x1ez\xc3\x9a1\xa1\xbeD\x85\xd2ku\xe0V\xad,\x846\x9a\n\xe7\xe0\xa0Z\x87v\x1d\xe6\xda\x1ax*\xd7\xed\x1b\xc7OCZ\x9f\xa9\xccS\xea\xca\xac\xd8\x9a)\xeb\x9ci\xfb\xe8\xae\xcd\xf4\x86\xb4\xfd\xce>\xae\xcf\x1eX!\x91\x07\x06\\k:jZ:\x00])e1Y_uk\xd8\x8dS\xbc9v\xf3\xdf8C\xe25\xc1\xff\x84 \xa1\xbeA62\x0dT\x1b@\x06\x0d\xf8\x1a\x04\x1ap\xa8w\x82\xcc\x16z\xd7j\xc0\xb1\x15\xa8\x8c\xc5\nuxO\xd7\xed\xd3\xf2\xd7\x19a\xefT\xf3o\xa7\x9c\xb4\xd8\x11E\x1b\x7f\xde\xcc\xe4\xed\x17(\xb2\xec(\x99--\xfe\xebu\xdd\xcb\xb0\xaf\xee\xf6\xde\xa3\x93D\xcf\xab\xb3\xc2\xdd\x993'\xfd9E\xff\xde\x94\xcacgk\x1c\x94\xc9\xe9\xf9\xb3k'\xa7O\xae\x9d\x9c\xde\xc5\xc1\x97\x92t<\x99\xd8\x8b\x11\x18\xb6\xa6\x17 S7 \xb7\x82-\x04\xe1\x16\x19N\x9b9\xa4\xeb,zF+[UFK\x0bUy\x1b\xeb`\x97\x0f\xda\xe5\xb73*Jdk\xd5\xb2\xab\x9b?'\x18\xd4\xa2\x1e\xf0\x9f\xd5\xc3V\xf9m\xf5\xe0\x19!\x8bF\xf1\xed\xfa\xc3F\xb3\xeaV\xfd%c\x01\xef\x8c\x1aJ\x8dg\xd4XA\xbc\xbc\xdd\xae \x9eQ\x8f:\xe0\x19\xed\xdb\xeb\x80\xe3CW\x1dp\x16\x144\x82#\x8ey\x05\xbd1\x07\x93\x82\xa2-Yf\xd0\xf6\x96D\x02Nq\xfb\x9f\x88\xb0?\x9bZ\xbd1\xa9\xaawL\x98U\x9a*\xbeH\x9a\xaa\xb8Vg\xbb\xf1d\xe2\xdb\xee\xa4\xc0\x9aq\xac\xac\xbcC\xb7\xb7CH\x026\xa4\xa3\xb0}\xec85\x8a\xe5\xb1\xcd\x8f\x1d\x8b\xfa\xc6x\xec(\x07\xa9Z$\xc1p\xb7yx4\x96>\xa1\x8c\xe4\x05\x19\xb3\x9b]\xfe*\xa3\x12\xf3\xab\xbd.0\xc4/\xbeC6\x94\x98NeS\x18\x9f\x17\xcb~-,0\xf0\x14N\xbfg\xd6'\xe7$_y\xb4\xac\xae\x12\x1dJ#\x8cE\xf5\x0b\x02 \x90\xcd\x93\xa4\xc5\xa6$\xeefZ\x1aHR,OY\x1e\xff\x7f8\xf2o\xc2\x91\xeb\xc6ry\xa2\x08&\xb2\xbai\x14Q<\xa4\xcf1\x85`\xc43G\xab\xe5\x10\x81\x93\xebi\xf4$9H7I=/K\xaf6\xd1q\xafCM\xd3\x1e\\[\xe7T\xdf!Y\xce|y\x819\x0d~.\xbdw:Nf\xde\xee\x93\x95\x8f^\xc2\xd08\xebn\xff/\xd2 \x15\x7f\xadz\x85iZ\x85\xb61\xcf#3t\x90c\xcc\xb9\xafa\xd88\x1d?\x85Xk\xc4\x9b\xea\x80L\xf9\xb0;\xd5[\xc5\x7f^\xfb\xb3\x99\xc2G\xf65\x8f?\x91\xe0\x0bu>8\xfb\xa48FM|J\xdb*\xa01\x8d`\xcaq\xac\xf7\xf7\xbf\x9f\x9c<\x7f\xfd\xfa\xe3\x87\xc7O^\x1d\x9d\x1c\x1f}89\xf9\xfb\xdf{mG\x90\x05\x7f\xbb\xf0P\x1aM:\x11\x81X\xaa5\xb1f\xb5&\x05\x05U([j\x88\xb1\x1c\x9c<4\xa5w<\xae\xf0|\xc1V\"|\xba\x04\xa3\x9f\"b\xd6\xbd\x17\xebJ\xae\x85#\x08\xa3\xcaf\xdf(_G\xd5\xb4\x88\xc8\xea]\xad)\xf3M\xc2}\xee\xa4Kc\xcc;\x10\x8c\xf9xg40\x99j,\xed\xce\xbf@\xa5u!TZg\xb4\xd2d]\xfc\xbfM\x93u\xe6\x86_\xa9\xee3\x14X\xd4\x7f-\xe8pJ\x95\x03\xddBSj-*\xa5\xd6\xa2\xae`R?\xeb\x0f$k\xb0\xa0\xba\xcej\xe1\xa3\xf0Y\xb8\x14>\x8b.\x85\xcf\x82\xaa}\x08\x038\xa7\xf2\x06\xdf\x8a\x88\x92\x11\xb0`N9q\n#\x98\xdf\x9cFh\xfe\x97h\x84\xe67\xa9\x11\x92\xfe\xf7.\xc5\xd0\x9cV~\xfa\x82r\x9f\x19(\xf7\x8aFp\xca\xf7\xc9\xdc\x83\x16\x9flJ\xd8N\xffC\x84\xed\xc2 \xcd\x95 l+>\xde\x13\x1a<\xf7/\xbby\xf4\x05\x84\xed\xad l\x97\x1aa\xe3\xb7\xfaKZ\xcc\x92){\x9c\xa6\xbe\xd1\xfc\x97\xde\x8a\xee\xa7nE\xf7)\xad\x1clO\xf5\xbdvA\xe5\x0d\xb9\xd7Np\xaf\x1d\xd1\x08.8\xb5<\xba\xb9\xbdvt\x93\xbb\xe2\x98\xc5\xe3O0\xe4\x1bb\xd4\xde\x10G\xd7p\x05\xa9\x1b\xe3g$6\x14\xaaG\xbd\x15\xd1\x92r\x93\xf0\x81H\xbcNvv\x1e\x84\xf8\xbd\xf0\xaa\xb2\xef\x058\x04\x99\x84\xc6\x14\xf7W\x1b\xf9\x82\x90O\x1b\x01\x88\x8f\xba2\x1c\xf2_\x86\xec\x1d\xad^\x96\xc5\xac\xab\x97J\xdbP\xae\xaf\x9f\xd6\xa1\xd4\xf4\x95\xce$\xb8\xfb\xb7[\xedD\x1a\x03\xcc\x07\x1e!0\x9bo\xc1\x0e\xecq\x88?\x12j\xc3\x9d\x9d\x10?\xb3\xf1\x05\x98Y\xa5lcH-\xb9\x0f\xf9\x825\xd7\x82_\x86D\xcbu|\xb4\x04S\x96\x9c6\xae\x87\x16o\xd5\xac\x18*\xef\xd6\xcb\x9f3\xe9\xda\xff\x98\x9a\xc5\x93\xd6\xe2=\xe6\xa4\xc8C0\x91\xead\xb4u\x05$\x0c\x05G\xe4^\xbf*\x07I\x87\xd4\x82\x0c\xb8\x19\xba\x1d\x9b\xaa\xe4\xed\xcb\xf0\xa0\x0d84&\xb2\xe4\xd9P\x00*4pT\xa7\x10\xeb\xdfN\x9d\x0f-2\x8aw\xca\xc0X\xdb\xfa\xb3\xc6\xfa\xd3\xeb\xae\x7f\xdb\xfd\xba\xb5\xfeYge*\x1de\x8b4\x19\x93`\xcf\xdd\xa6<\xa66i\x97\xa3\xa1\xa7:\xca\xd4\x95\x0f\x067\xbb3\x9d\xa2\x8d\xd67\x9fF\xb6\xb8\xce,6\xb12}i|\xb6D\xa9\x06\x06m\x82W\x9c\x15q\x83\x8d#\x89\xcf\x91\xc9\x89\xca[\xe9\xe8Q\x0e\xd6\xc7\x15\x8cbq\x11\xa2\x7fe\xd6p\x7f\x08jM\xd7-TeG\x17\xa49\xfa*M\x8f5\xc6\xaf<\x99\xf2\xda\xc9\x84e\xce\xb2:\xc9\xe2\x07\xcd\x83\x10\xeff\xee\xd3\xdd\xbd\x88yc\x11\xb3k\xad\xdfcj\xaa0\xddX\xc3\xcd\xd4V\xa5.\xa9\xad\xb9\xaa\x10\x94\xe3\xeacZMH\x9f\xcc\x86a\xc8\xfa\xcc\xf6,z\xa8\xa3kkAe\xdc\x81\xbe$\xd5\xd1\xa2y~\xb9\x90\x82\x8a=\x977\x10!\xaf%\x13\xccU0\x08\xd5\x92 \xe27y\x07\x13\xe85Y?\x1d\xa9\xd7l3\xb3\x0e\xb1\x9a\xa9\xf1\xec\xcb\xfdNn\xcf\xc8\x84N\xaf\x7f\xc5O\xe4]\xf1\x03\xb2\xdf\n\xd0\x91\xf0\xec\x17\xcb`Q\xd1\x98g(Z\xead\x1e\xba\xb2\xf393\xf3\xf9D\x05\x1c\xa1\xd6\x15\x85\x9a\x01\\\x1a\xa4\xf7c\x1a\xc1S\x93\xde\xf5\xc3\xe3\xa7/-\x9a\xd7O\xfc\xfd#\x0fi\xffq\xe9\xae\xd7\x91?\xb4.\xf3\x7frf\x94\xa9\x98\xe1L\xe7\x84\xb3\xa6\xa3^V\xd1\xbf\\\xfc\xaaS\x07\xbf\x94\x81o\x9d\xa7\xee\xb1\xd0\x03\x1cs\x80<\xa6A\xcb=\xc5\xd2\xe8\xbbnq\xb1D{\xabYR;\x9c\x86\xa8\xa3cCjH\x84k\x85\xa4\x9e\xbe\x8bU\xbc1\x0d#\xa8\\&\xb5\xd0\x88\xe3\xd5\xfc4K\xb1B\x82\xeby\xb3\xadf}|\xfd\xd7':|Z\xaa\x17?\xf9h\x03?\xb9\xb4\x81\x9f\xba\xb4\x81\xbc\x0b\xdd\xb6\xf6D\xb7\xb5E@\xfb\xcf+\x02\xf91\xe2\xcbDM\xe9\xbfdJl\x8f4_\xafH\xe0bE@.8\x91\xb9qE\xa6\xed\xeah_\xaf\x8d6zh0\x06U\xbe\x07\x8b\xe9\xcdi\xdaV\xd8c\xa61\xad\x15\xc4\xbbm\x9a\xc0\xb2\xe7tB.\xc9\xe4\x98|\xf6\x00\x8cF\xe2\xdf\xcb\xa8s\xbf^^\x1c\xfb\xb7\x8e\xc01\xa6\xc2\xf6\xd1\xccc\x82\xdf\x9e\xfa\xa4\x07\x9c\x85Y-H6\xc5\xfc\xda/\x8eQ\xe7\xc8\xff\x10\x16\x1e\x0b\xf8P\xbb\xc4\xdf\xf1\x9d\xde\xdb7\xff-\x13|\xfb\xa6\x9c\xe2\xdb779\xc9\x97du\x0dAC\xf8\x13\xd8\xfa\xa4\x93F\x8f\x1eU\xa3\x10\x98\xfcS\xcc\x89\x1aX\xcc\x1b\xa0\xebI\x0f1\xa1\x89\xb9<\xb8aXB+\xb4\x19,j\xc8\x125W\x9c\xa1\x84\x8ay\xbbYh.Sc\x18\x08\xe7@|6o\xa3oRZR\x04=\x84C\xe8aE\x028\x80^\xd4\xb3c2\x83\x01\xf4\x0czTu} \xa6\xbbp\x9c\xcaR\xfd[{\xe8\xb2\xba-,%\xfc_t3\xdaR%\xa4\xb4I\xe1\x9a\x96^4x\xe6\xf4\xda\x9c%\xc8\x1d\xe0\xc5\xb7}\"\xab/ ?\xcf\xbdVt^\x93C=\xd0\xaa\xdcb\xf5\x94\x9d^\x9d\x89\xb3t\xc3\x0d\x16A\xe6\\\xe0\x06\xae\xb5\x1cT\x1e\xc2>\xe6G\xe4\x98\x02\x07b\xc3\xb6\xb6\x83\xae\x06\xc0\x9a\xb5\x0e\xe4\xc8\xe0\x10\x82LR9l.\x94\xed\x92\xb2\xf4\xad\xa8\x18\x988\x0b2\xe7\xfe {\x9f\x9c\xcd\xd8\x86pS\x84Ig\x84*C\x94\x9b>I\xaeG\x9a\xdes\xab\xdd\x1dl\x83\xc6^\xfcq\xb7D*=\x19\xaeWWh\\\xbe&\x06?\xb9\xde!\xc1\xb9\x91\xcdz\x14yYD\xac\xdc\x1b\x8a\xa5\xc2LY0L]\xe5^5&\x9a3\xb3\x06\xe4\x80\xb9\x1f\x94\xba\xbf\x80\xd6\xfc\xee\xd5\xcb\xe9\x92\xbd\x8a7Q\x0f\x88}\x8d\x1e2\xbb\x11\xec\xecy\xf5\x92\x14G\xf3\x05\xf3\xb11\xc8^4\"\xae\xcb\xe9M\xc9\xfd@.c\x9d\x19\xf5\xe0EmFH\xaf\xd9\x8c\xb3%m\xee\xfc\x8e\xf9<\x0dH\xa5J\x12\xdb^\n\xb0\xe2\xe3\x0d\xf4*\xd8\xfb\x13_\xf6T\xf6\xefK\xa5@\xa3T\x1fI\x10V\x06)W\x06<%\xe5\x98\x88w\x17\xeb\x8a\xdf\xcb\xbc AU\xa7\\T\x12\xe7\xbbR\xcfy\xec%\xb5i2\x97\x99\xddU\x97\xa3\x94\n\x9e\x05\xba\xb9\xcdR!\xefJ?o}V\x8f|^\xc6\xe9&\xc2\xd69)\xc9\x86W\xfb2k\xa6\xc7V\xd3\x1dN\xcdk\x8b\x81Z\xfd\x13L\x97W+\xceDHu\xdf\xcd)\xd6\xab\xb7\xfeN\xc3\x86\xaa\xd5\xcd'\xd6\xaa\x1at\xf9\x8e5>&\xc6<\xa0\xea\xba\xf2\xe4\xf7\xc4.}\x93m\xb8\xdf\xa5\xf8\x81;|\xa3\xd3\xa5\x14Y6\xe7,,\xd5\";xn\xea']V\xc2%m\n\x97\xbc\xefa\x16\x01\x1d9\x05L/\xd6\x8aO\xff%\xf1%n5o\xf4M\x84=T\x8dQc\xa9]\xf3\x98\x1agd\xc7\x8a\xe8 7\xb3z8\xda\xb2\x99MF\xb1!rx\x0e\xa5\x02\xdc\xa6\xe3\xf1_-\xcf\xa1\xbc$r\x05\xfdF\x91o\xcc\xbc \xe8\x1f\xfb5\x9f\xc6\xec\xf5\xb5\xa51\xdf5\x02m\x13\xffb\xae\x93\xa4\xae&m\xabk\xea\xbb6\xb2\xd6Bn8k]\xc7\xa1\xae\x895o\xf1\x8d%O\xd9\xe2\x06ga \xd9\x1f5)\xc1WD\xd0\x8f\x12\x7f\x8c\xe1\xa7\xdd\xab\x0d\xcc\x90\xf5\x82y\x1e\xd8R\xa1\xa4.\xef\xfa\x14\x1f\x9fa]m\x9b>5\xaa\xfcd}\x07\xfe\x9cz\x0e\xddTnZ\xf8\x03c\xa1MUa:\xabU\x98\xee\xcc\xb6\x9c`\\\x90GV\xe4\x00}\x1a\xb1Z:\xc6-\xa9\xa4\xc4I\x04+\xceJ\xafB\x14\x13V\x95\xbf\xa7\x19D\xaee\xf1:\xad\xce\xf2l\xb9\xf8w\xb0\xe2~6\xbc@f\xbb{\xc7P\xd5\xc5\xf9wO\x06\xde\xc8\xb9w\xe9\\\xf8\x95\xb59w\xfe\x99\xe0\xdc\xbb\xf7\xb5~I\xf0\x04\"\x04r\xbd\x86\xe1(\xc4\x18\x06\xccY>\x8c#HFp\x00\x89\x87q\xd0A\xc7\xec0P(\xe8G\x81\xb3:\xe5\xed4?U\x14\x8cD\x90\x04&\x12\xa9.\xcb\xf87\x165f\xf1&r\x06\xd2!\x99py%b\x08V\x9e\xbd<\xdf\x84\x86\xab~\x9e\xd3M{J\x8a\xe3\xe5\xa9g\x81\xcfR\x06\x1c\xd8|\xc2\xcaJ)\xc2\xea,y\xf4J'\xe4\xb7\xb4\xe5y\\&\xc6\xd9 \x9f\x96y\x8a\x0b\xce\x0bm2\xc9\xc05K 3m\x96ay\xd3\xffT\xfbDVo\xa7\x1b\x0c\xa9<\xd483\xb7\x11$o\xc0H(\"\xce\xfd\x8f\xf8\x9aV\x86\xef\xea\xe7-)\xd5\xa7\xdbts5Z\xab\xe4W\x1f\xf9Y\xff\xfe^^g],\xbc7\xae\xb11\x97U\xbb\xefy|\xb9A\xaf/\xd8F*\x8cy|\xb9\xe9\x99\xfa\xa2\x96\x8f\xc8\xab\x13?\xa3Yk\x06p\x08\xef\xa9pa\xf9\xe8'(\xcd\x13z\xfd\xe9\x88\xee\x98\xe8\xcewn9\xd9\x18\x13\x8d!\x8f`n\xbe\xf8\x94,6\x80\x9d\xd6\xfe\xeb\x98\xcd\xfa\xf3\xf82\xb0T$\xb6t\xd6\x14\xbe}\xa5\x04\xcb\x1e\xe3M\x06D\xbb\xe3=\x90\x9fgI\xba\xa1\x99\xa1\x1c\xccO\xd74l|J\x16\x1f)K\xd2\xcd\xba\x15@WC\xdeL\x05%\x12\x82m\xd6_\xdb\xcaa\xc8\x0c\x06\xe6\xfeX\xfc\x89l\xb0\xbc\xacf\x80\xb8\x06J\xf1\xfen\x18\xa5x\x93\x9b\xa3\x14\xff\xeaKP\xea:\x92\xc4?\xbc\xb8[\xad\x84\xd1G\x8aj\xdeZ\xf26\x8c\xac\xec`x\x15;\xcd\xac\xdaeuq\x91.\xab\xc7\xe6i\x05Zja \xd8\xb1\xbb\xb5sY\xcf\xbf\xa3\xec\x7f\xc9\xb8\x19\x04\x1f\x82*\x91e\xd7\x0c\xb5f*\xe9\xa7\xfc\xf6\xd6-\xd8\xde\x8eQH\x95\x0dZ\n\x95\xab\xeb*\x8c \xb6\xbeq\x15\x81^\x06\xe9\xbfhU\xb2|\x93e!5o,\xfe\x9d[\xae\xe5\xd7\xd2\xe1Q\xa2.9N\xcf(K\xfdB\xdf\xa9e9\xd3\xee\x0f\xc0?\xe2Q\xbf\x9c\xd1\x8f\xfae\x89\x95\xd0/e\xba\x89;\x8bS\xa9K\xe8\xf0kE\xaa<\x1c\x1aUD\xa3\xac\xdf\xeb7\xd1B:\xab\xfa\xbd\x9d\xe2\xdb{\x1d\xae\xad`\xdaki\x04\x05j<\x0f9i\x1b\x0c\xe0\x8d\x14s>s\x8c,\xf0\x05\x91\xe6o)=C\xfe\x0b\x16\xb7\x8b\x088)\x80\xf1\xe1\xe6\x9aW~\xf0\\\x97\xa9(\x0f\xad\xcd\x98\n\x15C\xb0!_\xba\xb9\x186\x8b\x8b\xd9\xd3l\xb2\x81\xa3\x0b\x9bU\xd9\x05\xb0\x8a\xf3L\xcf6\xd0\xcd#@\xb9\xbd\x84\x83\xf2`\x00{p\x1bv\xcb\x8d\xe6 ]\xcaL:\xeeT\xf0\xf9\xb9\xf2\xa36\x16\x0ea\xcf\\\xf5\xb6|M\x0c\xcck\xf1\x1b\xdf\xf0\xd1^\xa2\x90~\xe7\xee\x9d\xfd\xef\xf6\xbe\xbds\xefN\x18\x95\xb7\xe1\xe1C\xd8\xbb\x07k`\xf0\xe8\xd1#\xd8\xd9\xbb\x17\xc1\xdd\xfb{\xdf\xde\xbd\xf7\xdd\xee7\xcd\xf7\xeeh\xef\xdd\x89\xe0^\xf5\x1c\xd3\xb9\x07\x0c\xb6\xe1\xce\xb7\xf7\xef\xee\x7f\xb7\xbf\xf7\xdd}Xs\x98\xfe\x8bo\xe9\x7f\xc9\xcf\xf6\xeeG\xb0\xbf\x7f\xf7\xfe\xb7\xfb\xfb\xf7\xca\xe6\x8f\xe5\xe7\xd8M\xf9\xe6\x9d\x08\xee\xec\xdf\xbf\x7f\xf7\xdb\xef\xbe\xdb\xfd.\xd4\x9bpl\xb9@\xe7\x0f(\xd6\xba<\xdc\x10j0\x80;{\xf05\xe4\xb0\x0d\x9fi\xf0\x94\xe0\xa6yJ\x02\x16\x86|F\xf6\xce\xc1sw\xaaKh\xc5\xaf\xd1K}R>\xdd\x943\xc2\x8e:;\xd8\xacq\xcfvCc9k( \xa2\x89\x14\xd6\xee4\x95\xc1|/~\x10\xc9\xc9\xb4\\\x00\xfa\x1b\x1f\xe8p\xaa\x02\xbc?\xd0\xe1+\xfe\xf7\x07i\xb2(\xf8-\x19:*n\xcb\xc0\xea\xf2\xbe\x1e8\x04\x03xF\xf1IB\x8b\x85\xc8\x8d\x8f\x9f\x1cg\xcb\xbc\x9eW\xc6\x04\xb2\x86\x12I\xba\xb7\xd6g\x87\xad\x8fgqBE\xdb\xd2\x96)ng\x94\xc5 F\xa5\xe3\x10\x84\xee\x12c\xc4s\xd3)9M\x93\x0dB#K\x01\xe5#\xb3\xae\x84I\xed\xb38j\xb9\xf7\xfbZ\xff\xedT1\xb7\xcb\x02N\xe1n#\xc3j)M('\x89a\x12A6\xb2\x17\x9f\x06\x10FU\xcd&\xe9)4\xce\xe3\xc5\xcb\xba\x0f\xb2/\x8c\xae\x01\x04\xbe\xeeMXt\x89\x19-X\x88h\x04\x07\x10\xb0\x93\xeb\xec\xd6\xd7\x14\x93\x9btf\xeexn\x07\x92\xdaI\xf5\xbe,\xed\xfc\xde\xd9\xce\x90E@F^\x8d\xbd\xb1\x90\xc3\xe6\xd9\xdc\xb1\xd9\xb6\x88O2.h\xc3\xd32\xac\xf773\xac\x9d\x1b\x1e\xd63\xf7\xb0z\x05\xd2\xc0\x9a\xf1\x03\x0e\xe1\xc5\xf1\xdb7}\xf1(\x99\xae\x84\xdaVRK\xcf\xdc\xa2\xaf\x9c\x04\xf8\xd8\x9a\xc9\xd3\xd2\xdc\xc7N\x0c\"\xf0\xb0\xe4\xe0\x08<\xc2\xbfw\x90\x9d\xf3\xea\xe0\xb3G\x07\x9c\xf5\xd9\x86\xfd\xfb\xf7\xee\xde\xbds\xef\x9b\xfb\xdf\xc16\x04\x843d\xf7C\xf1\xe7\xa3G\xb0\xdf>}\xeb\x0b%[{M\x87\x0bu$\xbe\xae\x8eD\x19\xa8\xc5\xef5\xceD\x91^\xa0|\xd08\x14;\x89\x9a\xec\xb6\xb1\xb0\x0c\xa3o\x0f0\xfc\x161\xa5>p<\xd82s\xf2\x93/M\xdf\xe0\xa73\xbf\xd1\xc0\xa9=\xbf\x93b\x9a\xd0 JO\x9e\xdd~\x817\xdd!:\xd3\xc1\x01\xec\xb4\xfd\xffLfN>*?\xc3\xd5\xb9\x9e>S\x99\xa8\x9c\xa3\xd1\xd2\x0c\x97{\xc7\xcb\xd53\x8d\x0b\xf6\xfc\x9a#+\x8dq\x7f\xd9\xe8n\"~\xc3\x13qn2~\xc3\xb7\xcb\xc5\x06}*Dm\x86\x15\xd9\x9d\x98\xf9:U\x96\x02.u\x8a\xa0Z\xb1\x10\x98\xf6j_\xfe\x89\x15\x8c;\xb23\xf2\x8b\xa8\xec\x8c\x9c`\xef*\xe7~t\xce\xafRDt\x04\x85VI\x15\x959\xa3\x03{J0\xef\xc9\xd1\x1eB\x0e\x07\x90\xab\xd0\xfdc=\x02x_94\x88\xd61\xc7\x81gP\xb0r\xee\xfc\"\xf2Qz\xab\xfe\x15$\xe4:\x8e\x9f\xa2\x9a\xbdW\xeb7\xe4\x9a\xe8\x89\xfd\x1b;\x0d6\xd2k\x87\x88\x82\xaa\x14]]\x0b\xa5e^\xafG\xd3\xdc\xba%\xf8\x8b\x99\x96dU\xe1\xed\xb5\xfc\x11EUmKV\xa5M\xdd\x117s^j\xc1\xe3\xd1\x00v1\x07\x85%\x90\xc8\x02(d\xbefUt\xd1\xce^\xf5\xa5<\xb4Z\xd5\x14\xc1v\xc61\x92/\xb2b\x13\xd3\xe6\xf5\x93|\xf8\x99\xf5\xaa\x12\x03%\n\xec\xc3\xd7\xea\xd7\x0e\xec\x89\x02\x03\x0e\xcb\x9f-\xf5\xa1~)\xa3\x01s\xca\xe5\xeaJ\xbe\xd8V\xd79 \xad\x8d`+\xc1R\x00b]Eh)\x17\xd1\xb30\xd4\x92\x96b\xb3\xf2\xbe\xb3\xe5+\xde{\xe4\xca\xa3\xa1C\xd4l\xb6\xf3\x06i\x84\xb0\xaa\x19\xd0~\xc7\xfe;'\xefo\x0f\xbd\x86\xfd\xac\x84l\xc6!\x1b\xc3\xff\xe5\xb2\x03\xdfz\x1c\x07\x92\x9a\x0b0\xc6\xfc\x1e\x88w\xe0\x10>\xf3\xb9\xc7\"\x1d)Zm\xd4\xcfL\xa5\x8c\xed\x02\xbf\xd3ZbIU^Q \xefm\x9c\x92\xf8\xdc\x87\xf3Rf\xb9!\xefbd8\x94C\xc7bq\x1e\xe5\xa5 \x00J\xff\x12\xc1\xcb~6EgZ\xebg\"?\x89\xe6\x9d\xef}\\\xc3\xbf\x8e\x1f\xf8\x9e\x11\xaa7\xed\xde\xe3y\xf2\xffq-\xbd\xeaK\xf5\xc7+\x1a\xb9\x90\xcd{\x0c?'l\xe6sN)\x99G\xef\xc5\x8do\x9c\xa7S\x01\x02\xed\xf1\xdbL\x96\xb5;W!\xa7\x08Uz\xd8\x89\xd27\xe87\xcb\xba-\xef\xd0q\xbd=\xfc\x8dy,\xc4 Q\x0bZ\x9a\x95\xbd\xe4\xb4\xeb\xe6\xd31T\x9d\x86\x9b\xd9l\xd8|\x95\xc3\xcd\x03\xda\x89\x96g[\x94\xd0\xaeY \xf4\xc7\x9a%A\xbf]3)\xfc\x1a\xe9J\xda\x10\xef\xbd\xac-\x9f\xb8\xf7C\xadiq\xef\x84\x18>\xbe \x86\xaf\x8fH\xf3\xf36TT~\xb9\x03\xa0m\xb8\"P_\xb4\xef?\xcd\xd2\x94 \xa4\x0f\xe0\xd4\xe0\x03\x81\x01b\x1f\x0d\x0f\xf4\xb4\x92\xefX\xfb\xb9\xc8\xcb\xb70<\x91\xa9\x02\x8f\x8c\xa3d\x07P\x18\x1e\xe8Y%\xe7\x86\xe7\xef\xc98\xcb'\x07\x90\x9b\x9e\xc5\xf4\x8c\x1c\xc0\xca0\x89\xf7dAb\xde\xa4\xe1YR\x1c\xc0\xccp\x7f\x9agsLmkK\x97|\x15\x01\xe9\x93\xcbE\x96\xb3\x02\x93\xc4 \xac\xbcr\xfb\xb4\xf5\x96\x05\x81\x82\xe5\xc9\x98i\xf9i\x94 ]\xdbn\x9a\x0f\x8d\xdeQ\xb3u\x15\xfb\x16G\xb0\x8c\xa0hn$L\xc6\x1e\xb00\x82-\xe3\x1e\xe6]\xa7m\xfa\xa7\xa5\x01C=OX&L;\xca\xf3,\x0fz\xaf\x13\x9aL\x132\x01r9&\x0b> \xc8\xc6\xe3e\x9e\x93\xc9\x03\xe0\x93d3\x024\xa3;s\xf5\xe2\x84\x9c\x03\xa1\xe7I\x9eQNu1\x02\x8b\xbf4]\xa6)\x10\xde*\xccIQ\xc4g\x04b:\x81x2Ix\xb3q\n3\x92.\xa6\xcb\x14.\xe2\x9c&\xf4\xac\xe8\xf7\x0c\x14\x9b\xa4\x05q\x90\xfc1\xe7i\x9a\xc0r\xf8\xf7L\xed\xfcfP\x07\x05\xeb\xe7d\x91\xc6c\x12\xdc\xfe\xbf\xc5\xed\xb3\xa8\x9b\xa8AE\xd8\xc6\xc3\xe9\xf6v;\x84\x17\x90\x8a\x85a\x9f\xc6s\x0c\x8dxN\xcf\xe3<\x89)\x83\x9f\x92,\xc5\xe4\xdb\x86\xfc\x92\xad;l\x96g\x17\x90\xf6\xa7y<'\xc5\x87\xec\x1dV\x91\xd9k\xa6b\xd3\xb0\xfa\xcb\x91\x98\x06w\xee\x86f\xdc\xcd\xaf\xdf\xba#K\xa2L~>!\xd3\x84\x12\x95\xfc\x9c\x8bE\xbd\x93\x13R\xbc\xce&\xcb\x94\xf4L\xa4T:I5\\\x9e0\x8f\x12\xe7\xbb\x9ef\xf3yF\x8f.\x19\xa1\x85\xcc\x7f\x8e\xf7\x1bwH1\x8e\x17XS\xf1UB?\xbd\x8b\xb1\xae\xa2J\x9d\xdf\xba]\xcc\xe24\xcd.\x8e>/\xe3TV#d\xfd\xd3e\x92N\xbe\xcf\xf2\xf9\xb3\x98\xc5\xe2\xb5,g$\x97OY&o\x92<\x89\xd3\xe4\x0frL\xe2|,\xda[\xc4y\xa1\xff>#\xec8\x9e/Rr<\x9e\x91\xb9\xf8\xee\xaf\x17\xc7o\xdf\x88\x9d\xd1\xe9\x01\xc6\xf2U\x07\xb3\x8c\xb6*D5\xab\x8eF\xe8\xa8o\xdd\x82^\x86\xbd\xf6D\x11\xb2\x86\xb1\xa0\xb7\xa4b\x9fNzp\x00\\\x82*\xf8\xc6\x8d\x97)\x0b\x03\x16\x86\x8ex\xd7+\x18\xc7l<\x03q8\xb6\x1e\xcb\xef\x1a\xd9\x1b\xae\xf8^\x16\x03J\xa6\xabNH\xc8F\x8e\x05\xc3|$\xf9f-\xa9<\x1c4\xfb\xc6\x1e\xe2<\x8fW\x1bt@d\xb3\xe8]\xa3\xff-\xeaI\n+\xefp\xd4\xeeH\xb0%\x92O\xd2z\x03b\x0eM\xe3\xabr\x84\x1eT\n\xae\xe6\xb3\x9eAB\x0b\x16\xd31\xc9\xa6\xb0RK\xd2\xe7[\xd2\xf5i /\xc6\x01U\xcf\x86\x8b\xb7\xd2\xb2)\xce\xb8\xcb\xb4\xbc$\xec\x8b\x8c\xce8\xdb\xea\x95\x8a\xd9\xac\xde4\xd5Nd\x98`\xf0Cv\xcc<\x0b\x05)\x15\xa3)\x87\xbb\xd2\xfd\xecF\xb0\xacP\x91\xb4\xb3\xf3v [\xe6\xf0\xc5!3$\xe80\x14\xbe\xeb*\xc6N\x879\x17\x0f\xc90\x1f\x89\xf4\x8at\x99\xa6fMt+\x13&\x82\x8cf\xf9\x1c\x0f\x0f\x81s\x03\xb8\x8c\x90N|O}\x91\xd6<\xc1vOIQ\xd2\x9dc\xd9\xc7\x92\x8eo\xbe\x175\x11\xaff\x9b\x99\x9a\x8dT\xe2u\xbc\xf0A'+\xca4\x93\xfa\xba\xf4\xa2\xf5ue\x01_Y\xa1\x8a5\xe5\xee\x84?\xdb\xa5\x84p\xc8\xef\xb1\xcb\x7f\xdb\xa8K\xc5x9^\xa7\xee$s\x1e\x08Y\xd7\x81 U\xda\xfcn\\\xdd\xa5\x18r\xb1\x01\x98\x8aU\xc1\xc8\xfc\xc3lI?\xbdN&\x93\x94\\\xc49\xf1E\x9c\xee\xfd\xcf\xfa\x93\xa4X\xf0\xb3I2\x8eH\x97\x9cp\xe9n\xd4\xf4\xb2\xd3\x82\x05\x1d[\x08\xcd\x93\x01 0\x959\x0b,\xbel`\x14#\xccw\x0d\xe7\xa0\\#\x0e\x80e\xf14\x9btC\xf9\xbcL\xb2\xa5\xaal[I4+55\xc1\x05?[.\xf8D\xfc\x93\xa8+\xe0\xec\xf7Ty\xd4m\xe8\xf5Bc\x06\xa5\x10\x19pK0\xf3\x95\\f~\x82\xf9l<\x8c\xce\xa9N9\xa5\xc0\xe1\xbc\xa7\xfc3\xd0\x8a)V/\x8a\x13\xb2\x0d\x0eu\x9a\x11\x99\x83\xc0p\xec2\xce>\xb0\x91\x1d\x96\xf5^\xfaI\x81\x9dQ\x91\xf8\xfe\xa05\x88\xf6\xfcg\xc9\xd9,M\xcef\xdd\xdc\xa5Z\xe1I6Fu\xab\x99\x01\xd9\xaa\xf8\x8c\x9e!s\xaf\x08N`\xe4\x92=\xcd(#\x94\xa94\xac\x8f\xe0\x1e\xb9S\xc5\x03\xe9\xafX'\xdf\x8d+\xb5\xec0\xba\xd2@\xa4\x83\xab\xfa\x88\x90\x0b\xdf\x8dP=\xb2\x1c\xee\x8e\"\xd44\xecE\xa8@ \xfd\x84R\x92\xff\xf8\xe1\xf5+\x91q\x18\x16\xa8V\x10r\xb2\xa8g\xbb\x80\x87\xf0\x0d\x92\xc9\xdf~\xc3\xfdJ\xa5\xe7\xdc\xd8\x99m\x86\x03\x84\xf7\x94\xaa\xae\xb7\xb7\x8b\x910\xafM+\xd8\xecE\xb05\x86\xf5\x1a\x16\xf0\x08\xbe\x15\xbd\x08\xaa\x80w\x87\xb7\x7f;\xbe\xddg\xa4`\xc18\x8c\xf8\xdb\xfc\x83\xdb\xc3\xaf~\xbb\x18i\xf7\x83\xdem9\xb2\xf5\xbal\x80\"iN\"\xf8[\xefo\xa0\xdcN\x92\x08z\x7f\xeb\xe9?\x97\xc3\x02v\xe0\xee\x08\xb6\xd1)\x9e\xf2g\xbd\x9d\x9d\xdf.\xefp\x99\xbc\xba\xf5\xf5\xed\xdeh\xb8\x18\xb9\x8de\xb8,SQ\x98\xa1\x1f/\x16\x84N\x9e\xce\x92t\x12\xc4\x9a\xc8}\x94\x12\x8efA\xafX\xc4\xb4\x17\x86\xfd\x82\xb0\xc7\x8c\xe5\xc9\xe9\x92\x91\xa0W\xb0\x15\xaa\x03\x86\xbdq\x96f\xf9\x01\xfc\x9f{\xf7\xee=\x80iF\xd9\xce\x05\x11 qO\xb3t\xf2\xa0\x17\xe1\x8a\xe1\x7f\xfa\xabxo4\\\xc0!\xae\xdd\x1d8\x84}8@\x08\xdf\x87C\xb8+\xff\xe6\xf7\xef\xc0\x01l\xdf\xfeW\x10\x07\xa7\x05\xcb\xe31[\xa7I\\\xac\xe9d\xadL\x0fk\xbeg\xd7E0_\x17$g\xe1\xe1z\xc9\xb2p}\x1a\xc4\x05Y\x93\xb3\x84\xae\xb3,\x0dHL\xc3\xc3uN\xe2O\xeb\x15#\xe1z\x8c\x8f\xf9\x81\xb3\x9e\xc5\xf9\x1aE\xdb\xc9:\x8d\x8bb\x9df\x94\xac\xb3\xf9\"]g\xb4`\xeb\x8c\xb2\x84.I\xb8\x9e\x90\xe0tyvF\xf2\xf58\x99\xc7\xe9z\x9c\xc69YO\x03\xbe\xc7\xd7$\x0f\x0f\xd7 M\xd8:\x0d\xc8Y\xcc\xc8\x9a0\x12\x1e\x86\xebI\xb6\x9ed\xcb\xd3\x94\xacI0\x9ee\xeb\xb48L\xa6\xeb\xb4 A2\x0d\x0f\xf9<\xb0\xf6\xe8\x9a.\xe7\xebsB\xd9\xfa2\x18\x93\x05[\x93\xf1z\x11\xa4\xc98a\xeb,g\xe1\x9a\x91\x80N\x8a5*M\xd69\x0d\xc3\x90w\x9d\xa6l\x96g\xcb\xb3\xd9:N\x0b\xb2Nh\x9c\x06\xe9\x8a\x0f\xe5\x92O'\x8b\xf9\xd7\x01\x89\xc73>\xfb\x84p\xb0e\xf3\xf5\x92\x8e\x03\xbe{\xf9\x00\xcf\xd2\xec4N\xd7g\x19\xcb\xd6g\xcb8\x9f\xac\x93`\xba\x9e/\x02\x81\x03\xc5Z\x1b\x04\x0d\x12\xb6F\x95~p\x92\xd11 \x0f\xd7i\xc2\xa1\xb5dk%\xfa\xacY@\xf2i<&k\x92\xd38\x0d\x0f\xc3\xc3u\x11\xae\xd3 \x9e\x9fN\xe25a\xebl\xfci\x9d\xd1\xb3p=\x0f\x92q\x9e! \\\xa3\x8ai-\xd4\x08\xe1\xfaM\xfcfM\x83xN\x8a\x05o)f\xc99Y\x93K\xb6&\x17\xeb$]gl\xbdL\xd3p\x9d\x05\xc8\x16\xad\x17\xc2\x10\xbe\xce\xd7K\xb6>'y\x9eLH\xb8^\x04\xf1\xf8S|F\xd6q\x1e\xcf\x8bu\x9e\x9c\xf3u\xc93F\xc6\x8cp@\xb0l\x9c\xa5\xeb\xe5i\x9a\x8c\xc3u\x1e\xc4 \xc7\x98 \x9ed4]\xf1\x85\x9b\xae\xcf\x92\x82\x91|\xbd 1[\x7f^&y5\xefb\xbc$k\xa1b[\xb3|\xb5\xe6T1\x0c\xd7Ep\xba\xe2\x8b\x1f\xa7d\xb2&\xe9t=\xcbr\xb6N\xce(\x99\xac\x93?\x10<1K\xc6kT\xe7\xacY\xbe\x1c\xb3\xf5\xf2\xb4\x18\xe7\xc9\x82\xad\x97\x0b\x92\xafWt<\xcb3\x9a\xfcA&\xeb\x8b\x84\x8dg!\x87\xe8|\x91\xf2\xc1\xcf\x08]\xcf\x92b=\xcb\xb3\x8b\xe2p\x9d\xc7\xb4H8\xd2\xe4K\xb2\xceW\xeb\xd5\x82\x041\xee\x8f \x99\xae\x93\xc9\x9a\xc6s\xb2\xce\xa6a\xb8^\x064\x18K4\x9f\x90i\xc0\xd9E\x8e'\x19]\xa7\xa4(\xd6\x85\x18#K\xd2p]\x90u\x91\xf0\x05:\x0f\xe2|\x9d\xe4l\x19\xa7\xeb,\x99\xacQm\xca\xd7\xe7\"\x18\xcf\xe2\xfc\x84\x89\x01\x91\x9c\xacgIJ\xd6 \x9b\x85\xeb\xcb,_\xaf\x12\x92N\xc2\xaf$\x01\x9cr~iw\x14r\x16T'9\x8a\xdc| \x97\xecM6!\xc14\x0cC\x91Al\xc1)\x94\xa0\xeb\x9cF\x1c\xf0\xf3c\xaa\x1d\x00{{\x0f`k\xb8\x17\xc1\xed\xe1o\xb7\xff\xbc\x1a\x06\xbf\xedl\x7f=x\xf8\xe8\xe0\xc1\xfa\xb7\xdf\xfa\xd1\xe1\xd6\xad\xbf\xff\xfft\xfa{{\xf8\xdb(\xac\xdfhPhI\xa0\xc7\xbc\xe3\x0cS\x93sR\xff\xb0\x07[x\xceH\x12=.\xa9\xf3\x98\x1fS\xdb\x90\xc26\x12\xe8m\xd8\x1b\x95\x7f\xee\x8f\x90 \xffvyg\xbc\xb5\xb3\xd3So\xf2{\xb7\xbf\xae\xff\xbc\xcdi\xe1\xff\x11-\x8e\x86;;\x8b\xd1\x03\x87\x07\xcf\x14\xb6\x070\xf6e.\x8d2\xda<^|\xc8\x1a|\x97M\xf5as\xb1\xe4\xc7b#\xc9~\xf9\xcapo\x04\x87\xf5\x9f\x07\xd0\xfbDV\x06\x96D)\x06\x0d\xed\xef[\xdb\xdf\xaf\xb7\xbf?\xaa1[\xaf\xe3\x85\x89\xe1k0\x90\xaf\xe3E?)\x84\x96\x04=\x81\x84\xf7\xc3\x06\x1cd\x9dc\xa4\xa2\x82\x0dE\x0b\x89\x89g\xe4\xfd\xd3*\xef\xfd^\xa5\x11\xea\xcfI~F\x02\x93\x14x.\xa3\xe5\xbbG\xc3\xdf\xe4\x8c\x155V\x07\xe2O\x0bK\xf4\xbc2\xecl\xed\x99\x9fM-:]p*=K\xe6o\x11\xc1\x04\x06(~&\x9a\x96RE\x06\x04!\xa6 \xe4\x83\x0b\xf8\xb6\x9e\xd4\x1c\x85\xc2\x07r\xd8..\x8e\xf72\xe3\x14\xc3'8\xfd\\\x8e%\xab\xc62C\x17Y\xe7Ws\x0e\x83\xceP\xf63|k\xaf\xe3\xad\x15\xe7i\x83\xb3\x08h\x99m'\x82\x9c3X\xc12\x82yS\x0d\xad_mTPB\xc7\x8a\x0b\x1d\xb1r\xfe\xc0\xec\x87\xb1H\x9a\xb72s\x83\x06b\xa1\xab\x86\x8d\xdf\x8c\xa5k\x05r\xe5\x86\xef\xa7\x9c\xfbHm\x18a\xc7\x15~ma \xdeI_n\n\xedo[\xe2\xe6\x8e\xee@\xf1\xf7\xa14\xe0M}\xe1\xd0\xba#\xc7\x14\xb7I)\xb9D\x8e\xf4\xfb$%o\xe29\xf9>\xcf\xe6R\xa6y\x96\x14\x8b\xac@\xe3\xeb\x8f$\x9ex\x94\x95W\"\xde\xedi\x92\x12~l\x0fz\xc1\xf0_\x0fF_\x87\x0f\x0e{\xb7\x93>\xb9$c\xa3\xe1\x00\xcb\x9e\x08\xdb\x00g\xea\xebm\x94MT-\xd8\x88\x93\xaa\x9e\x82\xcdh\xb2\xa1F\xaa\x8c\xf9\x19\x94\x12n\x99\xa6m\x08-\xe2b\x1c\xa7O\xe3\x82\xc0\x00\x9e\xd6\xef|/\x07\xd9 \x1a\xd9\xc3\xd3\x80Tf\xe2\xdf\xfa\xc3\x7f\xf5o\x8f\xbe\xfe\xea6\x17%B\x93\xc6*\xa6 K\xfe \x1f\xf3\xb4\xb3\x07\x0e\x802vlK\x8b\x1d\xe3\xc2\x9a\xd0u\xb8ekM18\xd6{\x0e\x8dG\xf0\x19a\x8f\xc7\x9c\xcb\xe7\xd8\x92gi\x9a\xd0\xb3\xf7\xa4Xd\xb4\xe8\x86F\xe3$\xab\x14\xfe\xfd\xa4\xd0\xb4\xff\x9a:\x84/\x8dMcP?\xf6\xccoV\xfa\xa5\xbaCx\x97Wry\xc2\x15,\xceY\xf1s\xc2fAo\xbfW\xea#u\x15*:\xe9\xf5\xc6b\xf7\xf4\xf04\xfd\xf3*\xac\xb0\xd0V\xa8\xc1LlK\xd5N\xd0\x93]\x88&\x8dv\x12K\x1b|\xcb\x06\xd40.s#a\xa9|\x93\xa6.5v\xa1\x0d2CVA\x887\x9b\xb7\xf1dB\xc8\"]\x1d\xb3\x8e\xbaLmJ\xf3\xdeP\x86\xffye\x0eLi\xe0hf09\xd9\x15\xdaU\x1cQ\x1edC6\xc2\xbdr\x08\x13\x92\x12F\x80\xdf\xe1B\x0d\xff\x87\xf3\x03\xe2\x0dj\xcce`\xcaV\xabl\x03\x06\xb2\xa7\xa2!\xbd\x08\x89)`\xd6\x95\x19HV We=\x95Y\xd7r\xa6X\xad\x16\xa4k\xc1\x89\xb0Z\x94\x87\x12 \x1d\x0c\x84F|s\xad\x89\x08\x84}o\xdf\x00R\xc5\xect\x19$\xcdQ\xc2\xe0\xe2\x13\x88#\x15\x03\xebS\xf4\xbd\xf8\x90\x95\xfe\x1c\x1ek$\xbe\xb1\xac\x91\xd6\x9b\x15M\x1a\xa6\xbf\xfa{\xe7\xb2\x92\xe7I@\x83oL>\x12ctH\xba\xf7\xcd\x9e\xe1\xd9T~x\xef\x1b\xa3{\xc5B\xb9f|\xbbkz<)\x1f\xdf5=\x9e\x95\x8f\x8d\xe3:\x97\x8f\xef\xdf36>W.%\xbb\xf7L\x8f\xcfpV{\xdf\x99x\xff\x95\xfc\xf4\x8eqR\xa7\nX\xfbw8\xe2\xd7\x9e\x97\x04\xfa\xa4\xc3w\xe1\xd6-\x0c\xe1P\xbeU\xd2\xb5\xd8\x8c\x8b\x12\xa5M\xa5\xea\x9bQ\xf3\xfa/\xbe\xb0\x170\x80\xf2\x08lO\xe5\xc8\xe0\xc0\xd3\xad\xd9o\xc9\xc8fsL{\xb06`]ndv\xae\n\x047&on\xfc\xd8\xd9\xf8\xd6\x16q\xdaW}(\x95c\x0dtO\xa9\x89\xfa\xc8\x06\x86\xa7\xce\x91\xf2~\x17U\xbf\xfc\xe7\xd4\x7f\x18u\x07\xaeN\x16\xce\xa1\xf8\xd9\x8c\x8b\x18Z\xc4a\x0b\x8br\xc7\xda\xf8\x9dz\xe3wD\xe3NN\xbcn\xa2\x97} \xefQ\x7f\xc8\xca\x87\xeb5 `\xcfk\xc7\x88\x0e-\xab\xfd\x18\x9d\x84\xab\xfc\xdf\xb4b\xbfM\x9a\x15\xd0\xfd\x00\x86\xd4\x92\xf6\xces\xa3\xc1!h\x02AR\x04\x182\xc5Q\xd5\xcaq\xf9\xa05\n?\xb6\x06|\xfc\x0e\xf0\x08'\xf8i\xd6&\x06\x82{k\xd4l\xeb*`\xb3\xc5{\x99k\xc3\x1cR\xceY\x0d\xa9\xc1\xeau\xd5\xdc\x12\xeds\xef\x93\xc5\xe1\xb1s\x7f\x80\xb2\xa7\xc2#\xa8\xc2\xc4{?\xc5\xe9\x92\xc0|Y08%\x90\x92\xa2\x006\x8b)\xc8\x96\xbd\xca\xd9?\xb68fn0\xa6\x87\xf61\x9d\xa1\xc2=\x97\xc3\x12\x8d{\x0d\xeb\xad\xd9\x85\xb4\xfb\xb4@9\xf3\xf6\xbfv\x0e\x7f\x9bl\x07\xbf\xf5\xf9?\xe1\xa1\xb2\x0chRjc\xa01H\xb6\xc7gp\xef,>\xaf\x9b\x8d\xcecP\x14#\x01\xcf<\x87\xf5\xc1\xe4\x9b\xeb7&<\x95\xb6\x02\xe2\xf0)\xb4Cn\x9a\xa4\xc4k\x80\xaf-\x0e\xc5~c\xec\xb1|Iz\xb2n0?D\xa7qZ\xe87\xb6v\xb5\xbf\xf7\x14#o\x1b\xf5\xa9\xe8\xdek\xe0\xcf\xcd\xce\xd1~\xe3\x16\x835\xa8{\xecc\x93/\xfb\x0c\xedw\x9b3\xb7\xdf\xe0\x92\xe2M\xfc&\xe0\x9f\x95\xce\xc2\x8e\x95V\xcd{\x8d\xec\x8d\xc9\xef\xdcoTJ\xd8S\xa2F\x9fe\xaf\xb2\x0b\x92?\x8d\x0b\x12\x84\x11l\xdd\xfe\xd7\xf0\xcf`t8\xdc\xdd\xf9.\xde\x99\x8e\xfe\xfc\xf6j\xa7\xfc\xfb\xae\xc7\xdf{\xfbW\xc3\xf0j\xe4E\x18\xf8\xc8\xbd&\xfc\xde\xea~\xefOL+\xde\xc4\x8f\xce\x8b.\xbc\x86\xf7\xcc\x1a3\xb0\xf9\xf06 \xf9\x1b\x8c\xf0\x95%\xd2\xc1{|[\x94\\\xc0{rvt\x89\xfe\xc8\xae\xa5\x9dfi\x9a]\xc0Bv\xd2\x83m\x93\x03{\xfd\x0co\xc7et\x8e\xec\xba\x9c\xed\xad[\xb5\xdfv\xae\xd6\xc6\xf1\"\xab\x87\x94\xe74\x9b\xac\xa4RY\xa8\x17\x13\xda\x13N\xf2\xf8\x0b\xcdX'\x97\xf3\xb4\x87\xee\xf2\xda\xcd\x9eEU\x99T\xea\xce\x9c\xa0\x9b\xc2\xc4\xf6j\x0c\xc2;J\xbe^`\x84\x8b\xe8\xc8\xa2\"\x8e\xcb\xd5\xca\xedv\xc7X47\x97|\x8e\xa5\xf3\xb1\xf6\xa6d=,oN\xab79q\xb6\xbd\xb6\xa8^\x9bf\xf9\x8f\xe0,\x82\xd3\x08N\"\xb8\x88\xe0(\x82\xcb\x08\x8eG\x0d\xe1\xd59\xf6J\xdfd|\xc5V\x92\x0eYB\xe4\x9f\x9f\x86\xcd\xb9\xbf\x97\xb4\x1e\xa6 I'\x90\x14@3\x06\x8b<;O&x\x02\x98(\xb6j\xf4\xdc5X>\xf1\x8f0\x80WA\x16\xc1\xb9\xc3%\xe1#\x1a8\xc4x>\xfa\xba\x1a\x80\x1c\xc2\xa4\xda:\x93\xae\xd1|\x86\x01\xbc\xe7\xa3\x998F\xf3Y\x1b\xcd\xe7MG3\xeb\x1a\xc2\xf70\x80g|\x083\xc7\x10\xbe\xd7\x86\xf0\xfd\xa6CXV\x00q\x96\x1d\xe1\xa3\xf9\x03S]a\x91\x11\xfbh\xfe\xd0F\xf3\xc7\xa6\xa3\x19W\xa3\x19w\x8d\xe6 \x0c\xe01\x1f\xcd\xd81\x9a'\xdah\x9el:\x9a\xfa\x91\xd85\x9e\x9f\x1c^K\xeaB\xee&\xf8 5\xe41#;\x8c\xcbQ\xd8\xfc\x02\x0e\xe1\xf7\x00Uh\xbd%\x176\xca\xbbo\xc4\xdd\xe7\x82\x88\xda\xf9\"u\xc9\xd9\xfedsb\xa9\xc8l\xfd`\xeb\x9a\xdf\x8f0\x80\xd7\x81\xab\xda\n\xce\xee\xc7\x0d\xc6\xf8c\xf7\x18k\x87g\xd7\x10\x7f\x86\x01\xbc\xed\x1e\xe2\xcf\x1b\x0c\xf1\xe7\xee!\xd6O\xe8\xae1\xbe\xc0\xec\x8d\x9dc|\xb1\xc1\x18_t\x8fQg\xb0\xbaF\xf8k\xc7\xd0N\x91\xf9)\xd90\x9f\x81\xfe\xaax\xd6\xe74\x18\xf6\x12F\xe6E/\x02\xc1g\x8f0\xc9N\xcb\xcc\xdd\xe5\xe9\x01\x9a`\xd5\xb5\xed\xf8U\xc3\xa4_\xd1E\x82#\x0b\x86\xaa\xd6\x97P=|'\x1f\xeaT\xe0Wd\xc0\xf8\xd3\xe7\\\xa8\x8c\xa4\xb9]\xac\x83{\xb0\xfcJDVKC\xde\x95\xe6\x85\x995\x0e,\x99\xc4\xd4\xe5\xac7\xdb\x89\x13\x1a\x83\xdc\x85\x12/a\x00\x1f\xba\x91\xf6\xa5\x0f.H`\xbd\xf4\xa5\xc6V\xab\xb7\xc1{\xa5\x9dF\xc1\xcd))7\xa3/w66X:Az\x05m*\xf6\xb7\x0cZ\xa6\xf8g\x0e\xef\xdb\x97\xf3T\xea\xae\x98U\xbeK\x84\xcf\xd5\xe5<\xc5m\x8b\x7fa~\x12\xd7\x9a\x0b=\x0f\xff\x86K\xf9\xf2\xdb?\xaf\"\xfe\xfdW_\xe5d\xaa;\x03\xac\x16\xe8\xb4F\xfa\xb8\xaf\xc5\x9f\x0b\x91\xcf#!\xf2w\x95\x16\xe6]\xf5\xe4\x10\xfe\xf6\xf0\x907~N\xf2\"\xc9\xe8\xa0\xb7\xd7\xdf\xed\x01\xa1\xe3l\x92\xd0\xb3A\xef\xe3\x87\xefw\xbe\xed\x1d>\xfa\x8dJ\xb7v\xf8\xe5\xf5+ \x97\xb8\xc40\x8e)g>O \x9c\x11\x8a\xc9\x19' B\x94\xfef\xf5~R\xd7yY^\n\xa7\xd3\x9fsQ \xb8\xfd\xdb\xf1\xd7\xbf\xdd\x0e~;\xde\x0e\xbf\xba\xed@\xf6\n\x88\xb2\x84\x94'*C\xddXx\xa6,\xb5\x93\xa7\xa8/\xfb\xe5\xf5\xab#17\xe1J\xe2\xe3\x01r.\xcb\xaa\xd5\xdb\x13\x9b\xe0\xfb<\x9b\x8b\x8d \xdbk\xcfH)\xc5l\x92]\xd2%\xd9%a\x08\x87M?\x98\xa4\xf2\x83\x81\x83F\x8eJ\xe9\xa3\xa9\xa7?q\xba}\x9d\xcb\xcc\x86\x7f\x1at\x85 \x93\x17V\xe2|\x9a\x8d1\xcbN\xbf\xc0\xc6-\xfa\xa5Joi\xdbZ=\xa1\xa4w)MD\x16\x94byZ\xb0<\xd8\x0b\xfb\xc5\"MX\xd0\xbbe\xd2\xc6\x80\xee\x9f\x9eCB\x81\x86@\xfb\xb3\xb8x{A\xcb\xdc7\xb9pS\xc4(\xc3a>R-\x0e\xb8XE\x86\x132\xce&\xe4\xe3\xfb\xe7O\xb3\xf9\"\xa3\x84\xb2 \x1f\xee\x8e\xc2\x11\x0c \xe7T\xe8\xd6-0\xbe\xb37\x12v\xd5\x9e\x0f>\xa9m\xdd^\xb3v\x1a\x1b7m\xb5Z\xc5\xfd\xca\x97\xab\x81\xd0\xd6\x8cD\xca\xfdA\x0f\xb6MO\xc9\x90\x19\x0d\xb3\xfd\xdf\xb3\x84\xe2\xf2\xb4\xa7&S\xf5\xb8\x07\xa5\xe6S\xcb\xb9\xa1r\x17Sr\x01$`\x9a\xb9\"\x82\xde\x92Mw\xbe\xed\x85au\xb7w\x1a\x17\xe4\xfe]\xd3\x18\xaa\xd4A\xed\xae3\x0c6K2Z\x1c\xe3[6\xaf\x9d8]\xccb\xcf\\\x83\xa0\xbb\x8f)m\xe2\xac\x17\xe2\x16J \x07h\x9c\xf3)i\xcf,G\xb6yc\xce \x9be\x93k\x8fF|n\x1b\x8fz\xea\xcdD\xb4\xc7\xc8\xe2\xb3\xbf\n\x9c\x8d!{\x0f\xd2\x80\x99\x8d\x14S~\xec\x8c\xc9I\xa5\x8a\x8d\xe6\xe4\xc7z\xfa+_^b\xf5\x10\xd1\xd8\x96\x1c5\x88\xbd\xeao&x\xbb!\x8d\xf8\x06\x8dL\xfb3\x0f\xb5\xc4k\xfb\xbb\xb7\xcf\"\xe8m\xf7\xc2\x91\xdc\x9f\xa6%\xb5R)\xe6\xda\xd4\x86\x94]\xb5\x95\xb48\xd6\x94J3N\xb8f\x15\xe1\xa2\x9aSN\x97\xcb\xc8F\x1e#\xf5\x91\xd7a\xae\x94b\x96\xbcd^\x04\xd8X\xa0\x063\x8ektL\x9a\xb31\xa5Q\x9e\xcc\x03m\x91~\xc3\xecx\xbd\x13\xb4\xd8\xf4z\xae\xe1Z\xb2\xaay\x0d\x93\xc3\xec\xb4\x82\xd9\xc7\xb6{Yd\xc8\xe3\xe6\xd54ig\x9b\xe8N\xc2z\xfb_\x97;%s\xdd\xb9l\x915\xf7\xdc_9Bi\xffY\x97\xf6\xa5ui=ZK\xbb\xd8ZZ\xbd\xfc\xa7\xf2?\xd5\x83\xb2\x90\x16\x0d\xee\xdd\x0d\xfbO\x96\xd3)\x91\xde\xe2\xd7\xca\x06hN\x88\xd9\x9cfI\xa9\x8c\x92\x99\xc8\x15\x0f\xff\x7f\xf2\xde\xbc\xbbm\x1cK\x14\xff\xbf?\xc55\xa7_\x8a,\xd3\xb4$\xaf\x91\xedx\xb28\xdd\x99\xc9\xf6b\xa7\xea\xd7\xa3\xf2xh\n\x92\xd8\xa1H\x15\x17;\xae\xb2\xe7\xb3\xff\x0e.\x00\x12\x04\x01\x92rR\xd3\xfd\xde\xe3\xc9\x89E\x12\xc4r\x01\\\xdc\xfd\x9e@\x15\xcb\xf2\x13\xf1\x83\x9c\xc7\xa2\xfc\x17$\x0b(\x81p\x047a\x16\xe6\xb0\xc8\xf3\xd5x{{\xe6\x07\xe4:I\xbex\xf30_\x14\xd7^\x98l\xa7\xf4\xbb\xedi\x12d\xdb\xf8\xf1\x16#\x9fRo\x91/\xa3\xd3P\xc4nd\x94\x86\xcb\xf3\xb9A\n\xc7\x90\x1fA\xba\xb9\xe9@\x0c\x9b'`=\xf1\xd3y6\xb94Q$\x157\x97\xa2\xcb\xaeB\x1f\xb2:\xeaq5ED\xcd$\xed\x1f\x94\xb3\n\xc8\x99uG\xe2l\xa2\x99\xa4\x16\x1dS\xe5\x15\x98C[\xd2\x1a\xd8\x12\xc58j\xc4\xca\xca\n\xef\xbb\xc4\xa8'\x14\xd8\xe7\xa4\x1f\xac\x932\x1a\xf1#\x9a\xacB\x19\xcbcf\x1d\xa8nz\xf5#\xcb\xfd\xe0\xcb#\xba\x80\x11\x98\xd9\xb8\xe9/:r\xfa\xb7W\x9b!\xb7\xd0}D\xb3\xc2\xb8\x17[\xd6\x18\xfd\xf6j?\xc5H\xcfk\xb5^\xd4\xb3\xbd\x88\xa8=\xad\xca\xa8\xf2\x84\xc84'\x04\x8b\xac\xc3\x8c\x102x\x06{p\n\x19l\xc1\x1e\x8c1\xf3R\x00'\xb0w\x04\x01\x1cCv\x04\x01E\xe3\xd1$\xa0\x05.\xe5\xda&AKb\xf0\x1b\xee\xa5n\xb6\xa3\x86R\xdb3\x93\xe9\xac\xd4c\xc1\xb0\x8d\xe2:q\xd1\x16\xd0\xd4\xc4\x9eux\x8a\x03\xb75 \xdb\xe5\xdf\x1c\xdcR,h\x8a\xc3\xa3p\x8afOSzb\xc2\x7f\xd1\x9f\x05\xfd\xf9_\x90\xcc\x90Zd\xcfV\xecYV\xacV\x11=\x7f\xf2\x84=O\xf0\xb9\x0b\xe4\xeb\n\x03\x9c\x80\x1fC\xe9\xd8\xe1\xfd=\xe3\xa1\xbf=\x8d\xe8A\\z)\x19\xc8\xb3\xbch\xe5X\xc4EK\xde \xe7\xb2\xe8H\xe9\xde\xa9\x8b\x16\x97\xb0\x8d\x99\x95\xd9\x03\xdb\xacN\xe4\x0b\x1d\xf3y\x1eJ\x91~h\xb2taQ\xaeo\n9\x8f\xc2pQfP\x88\xda<\xf1\xc5E;?/\xe5W\xf3\xd6\xf2f\xd8\x1a\x82\xc5\xf5\xda\xe4\xd9\xc2_\x911\xac\x9aoD\xa07\xed\xcb\xa5\xbfzY\xbe\xef\x8d\x1ef\x88\x9c\x1ew\x06F\x18\xe5>\xb3\xf5\xe7\xb6\xb6\x87X\xbc\xd9Z\xdb\xf9\x8a\x9f\xf4<+\xb5'#V\xd0<\xeb\xdaN6\xb9\xcd\xae\xb3\xcap2\xb1V\x0dg\x8d\xae\x9f\xbf\xf2~\xfe\xca\xfb\xf9+\xf6\xf3WM\xd9\x94\xc7\xfb\xcfl\x8b\xed\x7f\xcb\xed?\xe1D\x87.\x9b\xb3\xadi6,S,d\xf6\x9a\xc7\x99\xec&&z\n~\xb3\xaf\x82+\x11|t}\xbb\xf2\x11h\x9c\xc7\x84\xfeu\\\x1f\x1e\xb3R\xa5\xef\x85\xfc}\xac\x8e_\xf4\x97\x16\xaa0+r\x1ae\xcen\xbb\x14>\x03\x06F\xac\x05\xdf}\xd0\x8c\xac\xd00]\xe2]\xce\x8f\xe1\xb4\x0c\x9e\xa7\x9b\xb0\xb5N\xe0}~\x02\xefK'\xf0\xbe\xee\x04\xde\xef>\x81\x05\xd5\x00'\x80\xa6+)\x0b\x9e\xc7\x8c\x1c]\xe1\xbd\xcb\xe2\xb3\x9e\x02QQpm`2\xe2\xe5\xc9\xe8\xa5\xe3\xb14u\xa2\xc0\xf6\x1b\xe7\xe3\xad\xcfl\x9f\xb2\x15 \x18S\x16\xc6\xac@\x88\x05<\x94\x97\xb0\x86\xebk\xad\xb1\xa2\x98&A\n\x0f\xbc1t\xb4++\xf6\xc2\xac\xec\x96\xfa\xcd\xa0\x16\\U7\xed\x99\x96\xfco\xd2ar\xf4D\xed\xec\x8b\x89\xa7P6\xa9X\xec\xac\xd5\xe44B\xda\xa6#\x87\x8f\x81X \xdb\x89\x95\xa8/\xb1\xf2_\xa5\xac\xe0\xbft\x14\x8aQ\xec\xd8\x8c;\xe2\xb4\xc2=2\xc9\x1b\x9b\xa0\xaf\xe0\xaeI\n\x02\xf2\xc6\x8b\xb4\x1b/(7^\xc4I\xdfH\"}g\x8c\xf4\x9d\xc11DG0\xa3\x1b/\x98\xcc\x9a\xa4\xef\xcc\x10\xd0i\x85\xaa\xa6\xc44\xe7\xb1\xbdj\x9ds\xbaf\x0b3\xfd\x84F\xd0\xf6\xeaQKB\xa2_3\xcd\x92X\x18\x96D\xd8E\xbf\xa2K\x00#\xd5\xfa,\x10fW\xc1'S\xef\xe7\xa3\x19\x00-#\x1ce\x0d]\xc4y_\xa5\xc9\xea\xa2\x1cS\xd6\xe8{\xb9\xe2\xb4\x99V\xca\x95s\x83\x91\xab\xca\xc8\xf5.\x92\xb8\x03\x97\xd3\xac<\xa1-,\xe1\x18\xe6G\xb0\xa4\x8b\xc4<\xa5\x18ZJE\xb27.,\xcbEL{9\xa1\xfd]\xd2_\x97V\x89t\x03\x13\xb5K\x81x'\x9f\x82\x08\xae\x12\x80w\x1d\xf3\xd0\xb1\x19\x85xC\x17.\xbb\xb9\x1f[\xb7`\xa2\xdd\x82a\xb9\x05\x13\xc7\xe5 \x10\xc1\x87cH\x8e\xc0\xa7\xd0\x0c'~}\xbb\xf9\xe6s\x0eQ\x07vU\x01r\x88:]\x16\x7f \xf3\x8d\xb8r\xb7\xab!\xa2[\xae~\xfe\xcaq\x84\xdaq\xf8\xe58B\x8eJB \x95\x14\x0c\x95\x14p\x0c\xe1\x11\x14t\\\xfe\xa4h\xa2\x92\xc2\xa4E\xe2(\x8cLrC \xe3^\xca\xda\xf6\xd2\x17r\x97]H\xfb\xc9NV\\\x08\x9a\x91 \x89\xa7e\xd7\x9c\xe6V\x8bM[\xad\xc9\xe6\xb6o5\x90\xa1\x8b\xe1~\xe5H=\xe5\xbe\x9b\xb1}G\xb1jP\xee;\x8a\x9cW\x1c9\x9b9T\x81N3u\xef\x05.\xcc\xca\x99G\xa4\xb8\xf5\x8c\x02\xc5\xa6\xe3\x08&\xb3K\xfa\xcc\xa9v\xa1\xdf\xc6s2\x8bi\xe3Nl\x92\xe5\xa0\xc5\x8a\x0fNs\xf5\xea\x0f\x98l\x9d\x9d<3\xd3\xe7\x92\x05\x8bb\xb7U1\x060\xae\xbdk\x9eK\xb1\xa9\"\xb4\xd1\xd2r\x15\xb5:G\x97Z\"\xee\xff\xa5\xd3\xfe\xb1\xc7y\xd1~\x9cO\xff\x87\x8e\xf3\x9b2\xcec%\xffi=X\xbb4\xebK\xc4x7-\x18o\xd9\xb5\xeb\xe9)\xbdTw\xfd\xc2\x85\x9b\xda\x89\x8b\x1c\xe2M\xf7Y\x0b=%J\x9d\xc6\n\xed[u\xd5\xdc\xaa\x95|G\xfeT\xfc\x925\x85\xcc~\xecQ\x8a\xa3\xed\x1f\xcb\x9f\x8c\xc3\xde\xf2\xb3,\x9cWl\x92\x1d8p\x1e\xc6\xd3\x94\xc0y\x92.\x8a\n\x01\xfdk\x14\x06$\xce\x08\xbc{sQ>\xfcq\xbb\xfc)tR<\x8d\xd9\x9c\xe4\x92)\xd7\xf9\xdd\xf2:\x89\xb2\xa6\xae\x8a\x97\xae%\xb9\x94\xbek\xea\xae\x1a\x1fp\xcb\xca\xbb7\xd9Y\\,\x19\xda9\xd2\xc2\xcdH\xc4\xe8=\xa9pS\xf3\xe6\x18\x94Z\xc3\x89\xdcp\xbb<\xba\x83\x85u\x93\x7f\x1d\x98|\x11\xc9\x04\xb1\x8e5%\x96\x0b\xd6\x1e\xb34\xd4\xc2\xee\xbd\xbf$\x99M\x9c\xc9\xe0\xb2\xb5\x0355\xf1\xef\x0fL)<8\x82\x18\x8eaH\xffR\x84\x97O\xac+\xba\x15X\x0f1\x0f\xd3\xcb\x85\x9f\xbeL\xa6\xc4\x8e\xd1t.\xd6\xf7\xd7\x1a\x0cG;\xbb{\xfb\x07\x87O\x99}KK_s\xc5\xa6\xadK\xc4\x95\xabq\x84\x00$\x0b5\xab=\x8c\x8bXw-I\x91\xe8\xc9p3\xb4\xb6\xb2\xd2\xb6\xc2\x94\xd7\xc4\xbb\x9aE\xfe<\x83'PPZ\xe5\xa5\x1f,\x08K\xa5@[\xd1\xcbxo\xcaLG\x154\xe8\x17)\xd1$\x80\x06\x11\xa7\x82%m\xc2\x82M\x9c@\xc6\xb2\xb8\x02\xed\xe7\xb55!zV\xed\xea\xc3Vm\xfb\x0d\x8fx\x1fO\xc2\x8e8\xea\x19\x02\xddw\xbc\xabi\xb2|\xf3\xaa\x9d\xa2f\x16\xb2Z\xaeN\xbepTGU\xd4\xd1\xe4\x08\xa1\x91`P\xfa\xf3\xf0:\n\xe3\xb9Yy..\xda`d'\x94\x8b\xecjP\\3\xdbw\xa1\xcd\xa3K\xbe\x02\x9e\x91FC\x08\xa8\x97Y\xe7L\xaf\xd4\xb6vF\x16\xed\xa7\xb1\x98A5\xdd\\\x12bi\xde\x9f\xe8\xd7\xe6\x9f\xf4\xdf\xeb\xb6\xc0\xb4\xb9\xb5\x19\xd1\x9aU4(\xbd92\xec~&qa\x96\xd7\xb0\x81%M\xc4\x03w\x7f#\x98\xda\xdb[\xf9)\x89q\xc3:\xb2vA\xb3\x01p?U\xc5\x0d\x83\x83jI\x91\xd2U\x11\x87q\x84U\xa4\xde*Y\xd9\x8e\x83\xd8\x8a\xf6Y\x98U>y\x02+z\x96\xaa(E\x90\xac\x7fj\xb6%\xb8\xe3\xfa8\xe7$\x7f\x19%\x19\xc9rq\xc6\xbcN\x93%\xed\xf2\x18\xa6\xaeZ\xb4Y\xa6\x9d\xfc\x12\xf4\xfeT\x1b\x97^\x82 \xca\x0b\x99I\xba\x84\x13y\x18\xc2\x9c\xfb\x87\xd5\x81\xd8\xe8\x1c\xfd\x86vLt\xb2\xabsa=\xfb:\x91Z\xc6\x98\xcc\xd6\xce\x0e\xba\xf2T\xcf%7\xba\xf2Y\x07\xa7\xc3V\x98T\xdc\x11V\xf7\xa4\xaa\xfb#\xae\x13\xd4\x8f\xda\xd6\xce.\xb6\n'\xf5\xb7\x86v\x8e\xca@\xfcl\xc5\xe4b\xc5\xe01!\xf7\xdd\x08\x7f\xa9P\x1b\x84W) \xe8\x96\xadvl\xc3nD\x14\xe1KC!ub\xf9]\xafe\xd3\nf&L\xe7\xd1\xb2\xe9\xc9Y\x1b.\xdd/E\x14\x19\x8d\xa5\xf5<\xf8\x02\x9f\xaa\x04\xa4\xdc\xc5\xea\xb0\xac\xbeR\xce{\xe6\x1d9\x06k\xe4\xedy{\x96\xaeMM\xc0\xe6\xab+\x86\x01\xe8\xdf\x13q^~+);\xd0\x19\xe0N\xac/a<\xa5|}J\xb2$\xba!,\xf7Z\x9ca\xae)z#D\xc8\x1ff\xf4n\x95\x92i\x18\xf89a\x9f\xacR\x92\x91\x18\xcbq\xf3\xffs\x9e\xec\x8de}{\x1e\x85~F2\xeb\xb2I.O\xac,\xf0#?\xc5\xb2\xe4\xd7\x82\xc4\x01~\xb7\xf4W\xab0\x9e[\x97\x1d\x92\x11#y\xe5\x82__ \xe1\x8c\xe5\xb9\xc8\x85'\xac\xcc\xe1\xe6}\xc3\xb4\xd3Z\xb6x\xd8 \x0f\x9d\xc1?\xcc\xd0w\xb7b\x1bS\xfb\x87\xcf\xf1\x978\xb9\x8d\x81\xa9.\xc0\xfa\x81\x13\xa8?X\x10f\xb0$9%\x80\x90KD\x03oHf\xac\x0cae\xfe\xf6\xfc\xdd[\\\x04\xde\x0f\xcaju\\\xc8\x17a\xe6\xe5\xfe\x9c\xae8~G'\x0f7:\xfe\xe0\xf1\xed\xf9;>\xa1\xf8Z\xfc\xbe\xbf7\x8b\x96@b\xd3\x15\xb3\x07^c\xb9.\x98[Ky'\xd7\xda\xea*\xa1\xad\xb5Z`,\xbctu[\x1fO\xb9\xf4\x18f+\xef\xd4Q\xf35\xc9\xc7-\xee\xea\xa5\xe4\xc5\x8a\x05k\x0f\xeae\xe5\x85\x8c\xec\x1cs\x1e\x95\x9f\x96\x1f\xf8B\x9e%hB\x8c1 \xaf\xb7\xb8\xaf\x08'\x9e\x90\xcb\x9eK\x93^\xfe\xa4d\xc6LR\x9f\xc6\x82\xf2\x1d\x17\xf8\x92\x0e\xab%-\xd6\x95ii\xe3Rc\x0b\xbb\\\x82b\x81W\x165\xf4@\xea\\\xd9\xbdx\xf4\n\x85\x8dvG\x8em\xdd~\xc9\xd4\xf8j\x8c+\x1f\xee\x1b\xd8\xf2\x1d\xc7cR\xdd&s\xaeM\xdc+\x99\xe3\xda\xfd\xfc^\xf8\x02G\x91\xdb\xfd=\xd8\\\xf6\xe6\xd3\xd9\x0f\xc5C\x1f\xf5\xb0cH\x1c\xdbb\xfda\xc6`\x92\xb3\xd4\x83\xe3ey\x82\xa9\x92\xd3>\xb0\xd1#\xfd\\\x0e\x15_\x0f\xdc%\x80\x19\xda\xb1\xbd\xb7\x7f\xa8\x06\xacO\xf8\xab\xa7CG+7\x08\x8dC\xef\x1f\xa3\xde\x10\x9f\xfe\xe1O\xcd_\xe5\xbel\x13\x89\x0bmD\xdb\xc1\x00\x1c\x81\xab\xf6}\x15\x11\xa7\x17\x81)\xce\xf1\xa5\xf0\xae\xfa\xb0\xb3Y\x90\x08\x05S\xb0Gz\xa5,_\x96\xf1}\x88!\xe1\xcc\xef\xfd\x8e`*\xed1\xd8J:\xb5`bH%\xeb\x19\xc1\xbck\x98\xe3\xa6@\xd5u-\xef\x1a\xe3V\x18%[\xb0\xbcj\x94EbHW\x8e\xa4\x9e;G|\x9c\x06\xe6\xb5_`\xb7\x90\xa7\x16\xf3\xb5\x88\x0e\xa0_\xbe\xaf\xee\xa0t\x1b\xe8\x18\x9bIi\xc6\xb2\xf64c\xd0\xb3i\xe0\xcb+\x14(\xd67W\xa7\x1f\x9f\xf6\xa9\xe0\xa1\x1a/\x1f\xd8\xea\xd4\xd0\xcd:\x91\xb7\xd0\xe6\xfayN\x96\xab\x1c\xf2\x04\xa6\x84\x1d\xf5E\xca\xbc\xd9\x84\xbdni`\xa0*\x03\xaa\xcdl\xf7\xa2^%:u\xbf\x1d\xc9\x0f\xf7\xb5H~4\xfc\xbf\x16\xc9K\x07\xa0^\x1c=\xdc\xd3\x82d\xf7\xa9F\x1a\x1d\xdb\x0d!u\xc1\x1e\xab\xa9M\xfaz]\xa3\xf2\xc1\x05f\xbd\xb2\x02\x0c\xe0\x0d\x99\xf7Z\x8f\xaa\xa6e\x81\xbf\xe8\x0b,\xca\x02\xe7\xfa\x027e\x81\x8f\xfa\x02\xcb\xb2\xc0\x0b}\x81yY\xe0g}\x81;8\x81)\x9cB\"\x92.\xd1\x99\xe5\xd9\x97~7e\x11\xbb\xc6h&\xa5\xb6W_\xe8\x8a\xd7\x9c\xc2\x18\x16\xf4/\xcb\xecd\xa7\xbc\x95\xdf\x1f\x9c\xaa\n\x03\x9b\x8f\x9a\x9ei)\"\xca\x1d:1\x98\x9a|\x03\xf3\xe0^)\x11\x8a\xae&\x11\xd3\xb1\x14\xf6\x1d\xaa\x7f\xe8h(\xb1\x1d\xc0)\xbe\x841\xaa\x81\\\xb8c:!\xac[k\xbf\x85\xa5O\xb14\x8caI\xcb\xd1JB{\x86&yc\x98c\x07\xb0\x9a\x13\x98\xc1i\x07c\x00\x12\x83_\xd1\xb8z\x0b?\xf9B\x96n\x11f\xb5x\x1e]\xe2\xd3\x0c\xf3#\x83\xad\xea\xd6\xba\xbe\xa3W\xe0g\x04\x06\xe3\xcerP\xb7\x8f\xd1L\xa1za\xcd\xc3\xf5k\xb6u\xf8\\\xbd\xb0\xf2\xd1c*\xd7\xc60\x92\xaf\x0ea\xb1Z\x996W\x99\xb8\xccu\x95b)f5C\xe7\xdc\xad\x94\xa3\xfa\x1a5\xdau\x90\xc4\xa1\xd5\xfebr\xd9r\xc3\xea\x02\x88\xb3d\xd47\xca\x86\xa8N\x91\x19\xae\xfe\xd7\xfc\x0d\xaa5]\xc0of.\xfb\xcc\xb6\xef\xbc\x1b\x96\x14\x1b7^u\x87\xb8\xc4a[n\xe6r\x8c\xf4\x89~sM\xff\xdb\xb8\xa6\xaf\x9e<\x01\xdf\xbev\x01\xab5\xa7(\xc9\xbc\xd7\xcci;\xf3\xfe\x02'0\xa2?\xce\xe1\x04v\xe9\x8f\x8fp\x02\x87\xf4\xc7\x0bZf\x9f\xfe\xfa\x19N`\x07K}\x86\x13\xd8\xc7b\x9f\xe8\xdb\xd1\xa1[\x93\xb70Q\xfc\xbaR09\xeeT\x85=n\xc3x\x9a\xdc\xd2!\xb1_\xde;\x0c2q\x82ZL8\x15\xef\xc7\x86\xcf3\x12a\x10e\xfaW\xfd\x14\xdf\x8dAL\x84m\x89\xd9^\x84\x99\xe5\xc8\xa6_Zq\xdb\x9c\x8b\xdb\xe6\xdf(n\xeb\xe2\xbc\\~b\x8f\xf6\xd5\xd3\x16\x03\x81\xd1S\x9eE\xcaN\xeb\x9cT\xda\xceI\xa5\xa6e\xa1e\xa0\xda=\x1aPBEx`\xb0\xb0\x96\xd9(w\xb5\xc7\x7fT\x901h\xd4\x83\xa44r\x1ak9\x9b \x89g\xe1\xbch)q\x9b\x86\xb9x[\x1f\"\x86\xa0g\x07r\xec\xd6T\xb1\xd0=wfym \xd1\xd8\xde\xdb\xd9Q\xa6\xa8\x9a\x91Z\x7f\xf4M\xeavH\x8d\xfb\xd4\x8b7\xe3>\xfd\xff\xc6\xb5\xa7\x8e\xeb\x8f_z\xe52j\x17\x15\xd6\x94%\xc3#\xc8\xb5\x860\xb9\xde\x10\xe6F\xcd\xd4\xa0\xb5NoDr\xeb\xb0\xea+\x0dUx\x8072I/\xb9\xf7\x94\x89\xe3\x01\xbd\x89\x00=\xa8\xde\xef\xef\x0d\x06\x07\xec\xfd\xfe\xde\xde\xce\x1e]I\xfc\xd7\x13`\xf2&z\xb7\xaby.*\x1c\x94\x95\x1d\xb2\xe7\xc3a\x95]J\x14\x1a\xee\x96\xa5v\x86\xb5\xcf\x87\xa3\x83\xf2\xd5p\xef\xa9\x03<\xbf\xd63\x18\x0e\x87\xbb\xc3\xe1\xd0a\x97\x04\xd3&T4\xbe\xba!\xcf\x02\x87\x9d6\xa11\x8a\xfe\x18\xc06\xc1\xb6 l\x9d`\xf9}\x07\x9e=\x83\xa1\xca\xbe\x8b\x8b\"\xbf\xbd\xfd\x9d\xd1\x80~5\x1c\x8cv\x10&FM\xaf\xce\xac\xb6I\xf5k\xd1\x9a\xeeS\xad)\xf8\x0dw6\xdd~bO\xfc\xad\xdf\xfe\xe5\x92\xfe?\xd8zz\xf9\xfb\xd0\xdd\x19>8G\xdbs\xc5\xe0\x8dR\xc5\xdb\xff\xf9/\xb6}:\xfe:\xf1\xb7f\xbc\xf0\xe1\xc3\xfd\xa4\xfc\xe98\xdb\xcaW,\xe7\xec\xeep_+\xb4n7\xc5R\xc4\xa5|\x88\x89\x1d\xf0\x14\xcc\x01\xe3\xd0w\xf6PO\x92{\x01\x1f\xf1\xf3\xdc\x1e\xe0\xb2\x88Dx.F\xabc|\xab\xaf\xcc\x946\x9f\x0c/\xeb\xb9\xaf\xe0\x140\x80\xea\x9b8\xb7\xf3\xd2D\xcf\x85\xe1>\xa5h\x1a\xaf\x86\xf4\xd5\x00\xe3\xb4\x16v\x8cD\x8f\x01\xcc+\n\xb8\xc9\x93\xe3g\xd6\xe5v\x1d8S\xe9\xcd\xbc\xfe\xaai\x02B/\xeb\x895\x06\xeb\x89\xbf\\\x1diB#[\xc7\xf86\xca\xb5/\x9f\xe1\xcb\xb9\xf6\xe5\x0f\xd6\x0f\xf4\xe5\xafE\x92\x1f5b\xd15\xa7\xed\xc6\x88S\x16\xb2\x11\xb6\xac-\xe0V\xba=\x84x\x93K\x06a\x86\x1eK\x9a\xc1\x85\xe1:\xfa\xe0\xd6dVR2Lq\x0c\xe6z#c\xb4`\x149H\xf8W\x06\xe6\xbeKum\x0coH/2\x89/y\xe4\x1bm\x19]\x0c\x91\xfa<95Z\xdb\xc5l\xc0=\xd2\xe9q\xa0[\x1368\x8e@.y\x04\xf3V \x11\xff\xb4q<\nSW~\xbe5\xcd\xa9\xeb\xdd\\\xf8xN\xd3\x9fE\xcc\"\x1d\xbek\xcfgWJ\x1e\x84b\xd4\xfa\xe5\x17\xcb\x81c\x18p\xcd\x16)\xe3,\x86.X\x7f\x1eZ\x8e\n\x99\x9f\xfc(\x9c\x9e\xc5y\x98\xdf\xbddf(>}\x81x3\x99\x92\x8fI\x88j\xea\xc2e\x9ajZ\x17\x96\x0eI/A\xb4\xd4\xb5'\x86\x9ee\xae\x9c\x18\x08\xbb\xc5\x06\xff\xd7\x1c\x03\x84w\xb6\xb1\x12I\xd80\"\x83\xa8v\xea\xc2\x8d\x0e\x19\xb51Ak\xc9\xd8\xa5\xa0\xd6U\xe0\xcbS)\xc1;\x8c\xf5\xf2\x98\xae\x1e\x19E\xeb\x0dn\x8f1K\xfb\xeai\xcbD\xeb{\x87Z\xd1\xfa\x81Z \x13\xad\x0fGj-\x8f\x93\xad\xbb\x92\xf4\xdc ^_t\x89\xd7o\xba\xc4\xeb\xcb.\xf1\xfa\xbcK\xbc~\x07'L\xb6\x8d\x923.\xe3f\n\x13!A7\x8a\xbc\xcd\xa2\xf5\xc5\xba\xf2\xf8+8\x81kI\xd8G\xbf\xb9\xae \xff~\xd7\xa5Q\xaaD\xechY)\x89\xd8\xd1+\xd3f\x82v\x14\x91\xdfA]\xd0~\x87\x82\xf6S\xb8\x831\xc4\x0eJ\xd4\xe9\xb1\x8c\xc2\xa5\x00\x8fp!&G\xc9\xb9Q\xa0X\x98\x04\x8aw\x8c\xc4\xb8c\xe2@!2\xfc\xec\xb8\x80\xb2\xc2\x0d\x9ee,\xe4\x02\xc3\x15\x06\x08\x10\x02y\xf1\xd6\xbe\xe2\"G\xa301\xf5\x02\xa6\x9eJ\xdc\xffi\xc1\xa2Y\xf5\xa5*\xb3\xb8\xeak\xa0\xaa\xc4\xf8\x06Uw\"\xdd\xa0\xdb\x96J\x00\x15\x9a}hP=\xdc\xf0\xa8\x01\xdc\xcc&\xc4\x1c\"\xda\x85W``KtM0R\xdf<\xf22*\x95\xed\x82\x85\x11\x15~\xec?\x9c\xa0\xe1\x0coH\n\xba\xec\xbb%\xf9\xe4\xa0U\xcd\x0f\x0e\x8fF\xf6\xactu?\xde.}\"\x9e\x19\x03\xfe\xaegP\xa7\xf1X\x8b\x99\xea3\xb7\x0b\xc7\x85\xd4N\xbd\x8f\xb0 \xa9\xf7\x1a~\x84\xa4=\x02\x83\xe0o,\x0b&\xe4\xd2\xa6c0\x02)gF\x03\n\x05}\x7f\x0f9w\x88\xa3_K\xd9\xe0\xeb\xc3u0 #\xc6O\xae\xb15\xddG\x15\x8e\xba\xeaU\xdc\xc3\xfa$_\x84\x95\xd1\xfa\x83,on\x9a\x19\xd0\xfab:\x0c\xa3\xb4\x1aq\xd5\xc0\x05r\xe3G\x8em\xb1\xc7U\xf5F# \xcd\xb1Y\xc9\xdc\x11\x93\xb1[\x1d\xaf\xf6\x9d\xa4\x905Q\xe3S\xdd\xe6\xfc\xfe\xa2\xc6^\x9e\xb37\"\x19E\xa3\x01\x91xb\xacMT\xb1\x08\xb3SV\x160\xf1\xf0j\xb9\xd0\x84\xe7C\x91\xd89\xf6\xb2\x15 \xceIDh/2\xcd#\xbc\xfb\xb7,i\x15\xf7\x89\xa3\xcc\xf4\xad. \x8e\xb8x\xa7}\xbb\xa0\x0cmi \\\xd7\x1e\xd25\xa8XH\xff\xfe\x80\xb1lb\x9d\xa5\x80|}H\xc3\xb1\xc6\xdeF\\\x0f\x18\xd5\xd3\xd4l\xeeB\xd8\xf7x\x85j0\xe2\xd4\xb8\xf5\xd3\xd8\xb6p\x95\xde\xa6\xfejE\xd21\x04I\x11M\xe3\x1fr\x98\x13\x16\x17\xd4r\xdc\xa6\x9fa\xb3 \xad\x17\x99@dt{\x0c\xfe\xa1\x86\xf4\xcd\x86[\"\xe3\xf2\xcdGiZ\x7f\x15\xaa\x9bO0\xae\xcd\x944\xcc\xf9\xae\xbe\xc9v\xbc\x81g!\x8d\x9fW\x0c\xdan\x17\x13f\xe6\xfe\x0f\x9d.\xeeU\x1d\x15:\xc1\xa7h\xe3\xcf\x08\x91J\xde\x8eqCE\x02l?\xe6\"\xf7\x0d\xc3\x88\x1f-R\x1c\x1d\xa8RBLy\xd1\xe4\xd1d*\xa0\xa4\x06\x18\xda\x96\"\xb2\x887M\x8e*\xa5\xfcb\xd2\xcaQ\xea\xa1\xa7\x0f\xcf$\x8f\xa6\x1f\xaco\xfa\xc4V\x16\xae\xbdL\x03[\x03\x03\xed\xba\"\x0d[s\xa9tx?\xd6\xfc\xb2\xdb\xcc\x7f\xae\x8b\xf9E\x92D2\xb3\xd9\xab}I\x90\xac\xda\xa7\x0b\xab\x1bu1\x84\xdcv[uZ\xf2+k\x80\xfa\x99-\x9f\xb23\xa6\xf1\xdc\x95\xa2\xe6\xd4\x0b\xab\xd1s4\x87\x13\xba\xb4\xa3\xeb1\xda\xe8P\xb4\x8a\xe4Qj\xc7\x8ekN\xdb_\x1e\x0d\xa2\xdaZ\x89\x1a\xe1\xfe\xd0h\xcf\x9a\x93\xdcb\x91j\xe8\x9cg\xe2\xae\xb9I\xad\xe7A@\xb2\x8c\x9e\x7f\x18\xab\xb9X\xd19#S\xd36\xb5\x90d\xe1u3\x86\x8c\x99\x87\x95\x0e)kn\xe4~Vb\x0dw\x84\xb5\xac\xc4\x1e\xd7\xa4\xbab\xbe\xa5\xc9N\xb7a\x83\xcb\x81\xce\x88,\xb6w\xf6v\xb5\x8a\x91}Uz[\xf0\xe2\xaa\xe7\x02J\x9f\xecCu\xafD\xac\xd1]u\xe4L\xf1\xaf\x96\x9ei\\\xadV\x18\xb0\xb3\x0eS\xb4L\x9b\x93\xfcc\x92Dd\xaa\xe6\x87Xh\xe4\x1a7%2)\x1f\x97'\xeb\xb2\xc1\x1d\x9cy\x98\xde\xea\x13 \x928\x08#r\x91\xfaq\xe6\xb3\xd2O\x9e\xc0\x0d0'\xff\xe1h\xc72YOP\xeem\xa2l\xdb8\xccY6\xcfq;\xe3\xc5<]\xc34\xbf+i\xdb\x8ce\x18\xc3\xbc\x18\xecX\xae}\xa5\x88\xa54\x82\xabu\x1a\xd98\xa9\x9a\x81S\xb0g(\xb5\x0d\x08%\x19\xcd\x9f9.\xdc\xdaH\xfe\x95\xdf\x9e\x18\xc3\xb0?\xa8t\xe6z\xc0 \xfc(\xba\xf6\x83/\xff\xbb \x05\xf1R\x92\x91\\\x11{<\x16\"\xf5\x9a\xe3$\x0fgw\xcf\xa3H\xad\xbd\x1a\xc8\xa5nI\xdd5\xe3\xff1\x1f\xe7j\x98\xd2\x9a\xb2\x9d6\xb8\xf2\x95\xebj\xfa\xd7\xd8\x07\xa2\x19\xcd\xba=i[\xd5R%\x1b\x83v\xdb\xa8\xeb6\xe35\xe2]-\x93\"\xce1\x15\x06lA.\xdf\xb7V{\xd5F\xdej\xe1\xa2\x88G\xeb\xab\x96\xc5\xfe\x18\x8ev-\xc4\x9c\xe2\xb9C\x7ffI\x9a\xdb\xd7\x8e\x0b\xab\xcd\xcdz%Ud\xba*\xaca\xce\xa3\x1a6\xd7\x0b\x17tR\x04:\x9b\xc4\x06\x0fQ\x1f\xe7\xe8jE\xe2i\x18\xcf_\xf2\xd9\xcb\x9a\x0c\x1c\xba\x156\x0b\x96\xb3_xQ2\xbfHVo\xc9\x0d\x89>a\x88'c\xa0\xa3\x1b\x1e\xbd\xd6\x90\x9e(\xf4\xae\x82\"MI\x9cs\xc6\x0c\xf3\x89c\x9e\x03?\xc8E\x1b?3\x16\x0b\x8f\xe4\x88\x8d\xa2\x11g\xcba\n\x03\x8be\x03,VS?',\xb8WD\x97\xd4{\x7fI\xe8\xaa\x14\x0c\\\x1e.\x89\x9dt\x19\xab\x00\x87F\xe6\xadH:K\xd2\xe5g\xac\xf7\xcd\xec=\xa1\x84\x85\x9f\xde\xd9\xa1\x8bF\x0d\xcd\x85\xcct\xa7 *n\xa5F\xcf\xe2)\x8b\x0c\xae\xe7>{D\xbe#\nf \xf1\xaf\xf4\xaf\xedO\x82K\x97\xef\xc2\xe2:\n\x03\x11\xb8\xc6V}>\xfe\xd4\xfc\x95\xd8\xb2\xdf\x19D*R\x9c\x93\\\x1a\x1b\x9f\x90\xac\x03\x8d\xf1\xad8oC\x87\xc2-4I\xfb\xe0\xc4v\xb4\x14z)\x89\x88\x9f\x11\xbb\x89\xa0\x1c\x03\xd6b_\xb6!\xa4Z\x9d\xba\x99\xee@v]\xa1\x86\xf8\xd2\xea&\xb6\xa1\x02i$\x16$\xcf\xd1\x89>M\xc6N\x88\xc2-E\\\xd0\x93\xe2\xd5R\xa1k\xd6\xf3\xa7S\x8a\x9c\xc3x~\x91\xd8w\x8a8\xef\xb6M\xcc\xc9\xa3\x0b\x95h\xf1\xfe\x1e\x16\xc6(Y\xb3\x0e\xb7:\xa1\x88\xbb\x93\x8f\x1c=\x86!b\xf0\xf6\x95HKO\xd7\xc2]9\xad\xba\xd4v\xdaN\x19{\xc3\xa8<}\xf3\xe2\xe4\xd0\x04\xb5\x03-\xfd\x08\xb9|\xd4\xd7\xd6tWG\x8d\x82\xa4\xb3\x06/`\\\xed,2V}\x81^Sn\x8cL\x19\xee\xcb\x9a\xeb\xb4\xcc\x17\xd3\xb2`\x97t,7^\xbd\xaaf\x05m\xfb\x84\xe3\xb9\xcf\x1c\xb5\x97\xe75\xd1\xdbP\xf2\x16\xc3\xec\x05m3\x8c\xe7\xbcQFFb\xa0\x81\x9c\x0b\xe8PZ\xe0]\xb1C\x03\x8b\xbfGm\x08\x17Ji^\x9c`N\xbc!\xd2\x98\xdaQ\xb5\x8ed\x16\x15\xd9\xe2\x85\x02\xd5[\x85\x19\x8a)G\xceT\xca\xcd\xe5\x88/\xf5\xf3g\x16\xb1\x88\x8b\x94L\xc3\xbe\xe5\xb4\xe2>\xbd\xb6\xb0I^\xb0\xfe\x08@\x9f\xe7\xa9\x9f\x93\xf9\xddz}9\xa0}\xd1gOQ\x00\\\x92T\x87\xf8\xc95\xdd:\xbe\xf2Es\xda\xc5GO\xe9G7\xfa\x91\xb5M\x9a\x9f\xf9\xab\x1e\xa9T\x03[\xb3\xe6\\N\x97\xf0[\x8f\xd5\xf5\xd2\x8f\x7f\xc8\xc5\xb2\x06?\xc6&@\x1cP\x10\xc6\xe0c\xe8E\xf25\x87\xdb\x05II\xc1\x87\xe2c\x08\x85\x1c\xaeI\x18\xcf\xc5\xf6\xf4\xe8\xb8\xa6%5\x80\xfds\x19n2\xb2>z\x81\xd6\x19>]C\xce\xb0\x11\xdb{C\xc7l\xb4\xc3q\xc0\x01\x9d!\xbd*\xe9\xf7\x07\x17,\xbf\xa1B\x02FytP\x06r\x13]s\xeaxU\x9c\x8c\x87G\xa84\xc5\xd3.O9\xcc~@\xc1\xf2T\x17\x1f\x07_\x8d\x86\xea\xab\xd0\x14h\xa2\xd4b\xa0\xcd_\x861!\xe4\xf7\xa5\xf6\xa4\xd3[^\xc8tUSWz=@\xd7\x8e\x95\xf5\x0b\xdd\x1d%U|\xaf$\xe5Q\xcf\xe4\xd7,\xe2i\xa9\xa0\xa9\xcc*O\xab1\x8e\x0d]]\xcf\x83\xe8\xbb*D\xc4/\xd9;\xb1\x1b\x18\xd2\xac\x9d@hW\xfa\xae\xd6)\xe3\xfd\x97\xc3JR\xe8H\x86\x00c\xd4\x03U\xddk\x9d\xc3\x7f\xc4\xfc\xad\xd1\xf7\xc7oG\xb3\xd4\x93\xb3\x97J\xc4O}S&\xfc\xd6 \xd0\x9a^Bgx\xfe=\xc6( T\x0d\x86\xe6\xaa\x84\x94\x0bTu\xf2T;\xb6\x9f:.L\xaci\x98\xad\xe8\x01\xf2\x12=\xa9-\x17\xac\xab\xdcOylVz\x1b\xfbyx\xc3\xfc+1\x96c\xf6\x8a\xcd\xf7\xc7\x94\xd0gd\xca\x9eRT\xee\xcf\xd1\x08\xee\xa5\xa94B\x1f\xca\xdd%j\xd8p\xdf\x18K\xdb\x10\x1d\xad4\xfb\xd3ft\x03\\\xd4\xa7\xd8i\x96\x01\x8e{\xe3Y\x0c\x00\xec`\xf0y \x8f=D\xc5\xecX\xfa&\x9e\xf8\x9a\xdc!\x0d\xe8\x08Y\x1d\xe6B\xf5\xd4Y\x87S\xdd\xc31l\xb08\x8e1\xb7\xde\xfb\xa9i\xbc(i\x84\xbd&\"\x80\x13\xa0\xdcU\xd8\xb0\x9aR\xf6\x1bZY\x89\xc8\x9d\x1a\xc4\x81<\xb1\xbe\xfc\x9f\x9acN\xedL\x96\\\xd5\xa7l\xc5\xfa\xf6J\x9c\xea=$L\xcdAmh&\\H \xd4\xd5\xda,\xc9t\xd5\xc4\xabw\x05}\xa1\xea\x8fl\x87\xd9\xf8a\x88\xcc:7#M\x08\xafM~r\x02h\xadf\x9e\x95\xc6\x8c\xb4r\xa7Y\x9e\xac\xa4I\xe9\x00\xda\xfa\x80P\xeaGH(\xcfZ@\xc1\xb0\xea\x0bD\xbd\xbc\xc2\xda\xa3\x13\xa6\x80\xee\xbd\xb8:\xc1\xb1\"i\x86\x99\xc4\xbb\xd7N\x98}d\x85\x19\xdaj\xb4\xd3\xd6\x8c\xfc\xadv\xbf\xd4J\xf7\x96\x9a\xd6\xa6\xa7\x07\xae\x84z\x0c\x0d\x96\xd1\x0c\xf1\x0f\xd3\x84k\xa3\xd3\xeb\x94\x15\x95\xd0\x9aebB\x146\x89//\xb5\x12\xd1j_;.dU\xe7\x98kc\xe6\xf9\xc5|I\xe2\xfce\xe4g\xbd\x1dNd\xb8\xa8\xbe'5\x1f.\x84\x8d!b\xda\x0d\x8fn\x10\x93[\xf5\x18J\x99\xec\xbf\xfc\xd0\xa9\xdda\"\x16\xf9A\x9d\x98\x06\x8c\xa6.\x8f3E&\x18\xfbR>f<\x9e\x8b\x98\xa4\x19\x908H\xa6a<\xafgD\xc8\x17$\xc6\x8d\x87\xc9\xd2\xca\xc3\x0fD\xe0\x17\x1fx\x03\x06e\xb88c\xb9\xc1@/\xd57\xffF\x18\x19\x18\xcc\x04\xf4S\x13\xb5\x88\x85\xc0\x0cCC\x8c\x9b\x1f\x84}n}\xdc<\x9b\xa6\x0f\xac\xa2\x16gp\xbd\x03\x1d\xae\xdb\x17\x0c\xdb=y\x82LO\xb9\x1e\xe4w\xcdC\xbe\x85P\xc3\xd0>\xde\xf5]N\xde\xf2l\xdd1FWA\xcf\xf3\xea1\x1cWv\xcb\xeaV\xfd!\x99\xcd2\x92\xff@\x97@R\xe4\x90\xcc\xe0:)\xe2if\x9a]\xb5MZ9l\x82\x8d\xb6\xfd\x03\xc7\xd8\x0e\xdbs\xfd\xdb\xc9\xeb\x99\xd1\x99!juO!\xd5@\nuE\x80\xae\x08n\xe0\xb1\xee1\x05\xb3\xbe'\xad\x88)oCD\xb4\x00\xcf|\xd8\xbaU4J\xe2\xda\xec\x8f\xf5\xde,\xdd\x04\xa1\xb84\x9f#@\xcb\xe8\x0e\xf7\xf7\xcc\xed\xde*\xf2\xd9a\xdb\xd4od^\x98\x9dq\xbca\xc7\x8ei\x13 \xd4bIh\x83\x1d\n\xac+%\xee\xd1\xed$\x90\xce\xd3\x01\xdc\xc3\x82M\x9c\xde\xe2\x10\xf8\xe1\x8a\xd3\x81\xc7V\xea8\xdem\x1a\xe63/HX\xa7\xdcL\x8d\xe1\x98\x11\x91\x84rZ$\xb9)\x1bUJi\x08\xfag\xf3\x04\x86t`\x18\xbax\xb4\xb7\x07O \x9f\xa4\x1a=\xd7Z#\xd4$^\x85r\xdd<;\xa1\xbc\x95\x89jy^e\x96\xf1#\x0c\xbfB\xf8\xce\x82\xc8O\xe7\x842\xa8~\x0cK\xffk\xb8,\x96\x90\xa1;\xc7\xe0+\xe5\xb3}9\xcd\xf5p\xdfAWNJ6i)\x9e\x12a\xdf\xf7\x1c\xd4\xa2u%J'\x8b\x9c;JH\xcb\xf5\xdb\xb4\x0f\x92\xd6\xdasHe\xbc0\xfb)$,\xd0H\xf31\x9d\x88\xfb{ \x06\x14/\xf7\xb4\"0\x9b\xbd\xd5\xb8\xd6W\x8c\x9e\xa5\x13r\x80\xb4\x9c\xdb\xa1\xc0\xa9\xcd\xb2'\x9a\xedU[\xbe\x1b\xc3\xa3#\xa7\x14\x0d\x1bOB\x14\x88Z~\x16\x84\xa1\xa5\x17\x8b\xb2\x12\x91\x9f\x87\xf1\xb0\xb5\xc8u\x18\xfb\xe9\x9d\xa1\x08H\x12(\xfdq\xc2*A2\xaf\xad\x95\"\x9fm\xb5\x96`\x84vg/^\xdb\xc41\x02\x1c\xaa\xe6\x82l\xd4\xde\x9f \xdb\xea(\x91\xcf\x86\xfb\x11\xe9*\xb3\xd5R\x08\xaa~\x8f\xe0\xc7v\x08.\xc8\xd7\xeeZbx\xf6\xec\x19\x18\xac\xb6\xf9t\xfa\x19\xd9\xdf\xed\xae\xea\xb7.@\n\xa32cE\xa8\xedpzO\x0cp&\xcc\xc6\x1d\x95;\xf5\xe8f.\xcf\x8f\xd6\xf8T\x95\xbe\xeb\xd1\xd7M\x1b\xc7\"\xf6\x16\xd1F\xc6\xe7riz\xfc\xb9\xe2\x10L{5\xba\x94\x98*\x83\xc6\xa1B\x01\xa4\xa4\x189\xc0\xb64\xd3h\x10\xb7\xc4\x94;L\x99\xf0\x1cOn\xe49\xe1\x99,\x91;\xc575\x11\x1d=\xdd\xb7\xca'\x87 b\xa1I\xcf\x1cV\xe1f\xecB\x98\xbd\xf7\xdf\xdb\xb1S\x16K\xf8\xe1\\\xca\xb7\xb6`\xe8\x08\x91\x80(T\xbe\xdcDZ?\xa6\x07 \xe9p\x84@\xcb\x95V8\x00\x8f\xfe$7\xdd\\\x19@\xa2\x8c`m1\xa3\xd7\xcc\xcdm\xf4k\xafk\xf9A\x8bH\x8c\xd9\xdd#\xcf>K\x93%\xe5\x15S\x07\x15\xc35\xae\xac\xc6J\xe5\x15\xfb\xb45\x841\xcc\x95\x15eX!Z\xe1\x13\xaf8\x87'H\xeb\xb8\x069\x83\xe9\xd0\xad\xc4\x17\x92\xf6\x97\xc7\xd9\xc5\x08\xa4\xa7\xadE*\xf5\x04\xe7Z\xb5\x85#?\xcb\xdf\x18>\xc0\xb1O\xf2\xcb\xb6\xd1ky\x97\x1b?* {\xc1\xae0\x08Q\xce\x843Z\xfd\xe8q\x15\xfe\x06d\x12\xb2\xf0l\x86\xd8o\x85\xb4p\xf5%2\x89\n\xd6O\xb1\x14\\\x95\x89\x14\xd8\x89\xc6\xf8\xef\xb4\x8a\xc6\x99*h\x14\xe9!~\xb8q\xa1\x15>\xe0gY\xfd\xd1\x96\xf4\xcc(/@\xb2\xb6\xa2\xd8GL\x18X\xddw\xee+\x9fEO-`\x9bEQ\xe5\x7fc\xfc\xab\xd9o\x8dG\x8a`\xd6\xd4Q\xde\x8dai\x92FX\x00{\xe2\xa5\xc4\x9f~~\x13\xe7\xc3\xfd\x17gv\x0e?\xea\xdc\x18\xf5\xfb\xdc\xa8E\x16\xce\x8e\xa6A#M\x87j\x98#\x08\xe1\x18\x8a#\x0877\xf5L\x19\xf0\xc6px\xa1\x83\xfdG\xad4OQ\x1cp<\x1c\xc2\x16\x04\xadr\x1dQS\xf9!]9\xb4\x9b\xa1\xe3\xb2\xcfa\x93\x03(+\xe7-\xa0\x001V\xc9\x91\xec\x16K\"\xc1j\x0ca\xeb\x84\xf7\xc6\xe5P0 g3lb\xd8\x84\x0c\x9eAQ\x9e$\x05lA\xe60\x7f`\x84\xda3d\xe6\xc2\xad\xad\xb6!\x97\xc4\xf3\x8c\x07\x0b\\1\x1ep\x05\xc7\x90\x1d\xc1\xaa\x0d\xe8P\x03[{>\x1cCz\x04\x9b\x9b~\x1b\xfa\xa0\xc7\x84\x9c\xf7\xa2\xb8\xce\xf2\xd4\xa6|\x82\xef\x02O\x8d\xa1_X8H\xa4\xd6\x8a\x8a\xa0\xf0\xf5e\xc9\x84\xee4f\xba\xdb\x03\xe9\x89\xcaz-\x9a\xeb\x8eE\xc3+{a\xbf\xa6\x1bJ^\x16\x0e\xaa\xe4\x9a&@\xa6\x96\xae\xfa\xb6d6\x18(\xeb\x94smM.]Y\x14V\xb2\xf2L\"\x963\x87K&8\"r\x02\x94\xb8C\xa2\xafK\xa8\x98\xaf;\xe8\xdb~\x83\xae\xc1\xa6W\xc5g\xfd*~a\xff\xb6~\xa7\xbf\xf6\xad\xbb\x97V\xa3\x92W\x96\xde\xb6|\xd6\xa4\xadF\xa4\xa0\x15\x1b\xb6\x9d\xd3\xd3i\x84i!\x1c\xbe \x19+!\xcd\x9f\xcf\xf9M\xcaO\xc3!\x8f\xdaL\xd1\xc6\xde\xbe\x0b!\x9b\xf6\xc4)\x7f\x9a4yF\x94\xfc\xf0\xad\x0b\xfe\xbc\x8d\x9f\xad\xb3\x10t\xd8q\x8d\xc5\x84SH\x91\x07yq\x97\x13\x91\xf1\x9dbU\xf5!WQ\xe5u\x9b\xae\xb6~\xbdl\xeb\x17\x05\xf3;?_x\xcb0.i\xc6\x1e\"[:\x9f\xe8\x1aq\x04 \x8an\xdb\xd0&\xa5\xbd]\xb4\xafu1F\x07\x99$-\xc9\xe5\x03\x11,\xc1X\x82\x9e\xe0\x11e\xa5w\x9e\xc2)\xec\xc2\x98\xdd\x8dv\xe0\x14v\xf8\xdd\xf0\xe9\x10Na\x04c\x93\xe8\x05iE\xd8\x84\x19\x1c\xa3\xb0O\xc8\xeffm4D\x9f\x04\xb8\x11\x1c\xc3ptX\x12rQ\x8b^ \x04\x9da.\xd2'-.m\x8er\x19\xc3\xa7#x\xc2\x88X2\xa1\x83\x1b^:L8@\xd9\x17{g\x08O r\xe0\xf8\x18\xf6\xe1\x1e\xf6w\xe0 %^\x9f\x89\x0cb\xd8\xdd\xec;t\xd7`\xf6).\xb9\x7f<3>\xde\x8d.]e(!\xf6\xbe\xfe\xcc\x97F4\xdc+G4\x1c\xc1=\xd8bL\xf2\x10}:\xc4\xd1`\xf7\x80\x7fw\xcc\x13\x96\xdd\xdf#9+%x\xfb^\xe3\xdf}\xfc\xf8\x8b\xf2ng\x0dh\xd4\x9f\x15\x06\x08\x1d*\x10\x92@\xe6\xd7AV8\"\xef\x1b\xad\x89\x82\x8c\xa5\x92\x1bI`\xd2\x0eQO\x12\x97\xc6X\x94/\xc2\xcfi\xdd;.\xee\xe4!\xc5s\x81\xdc\x9e\x1d\x94i\xe4\\H\x19>\x0f\x98\x18u\x00O\x00\xf3\xc5\xdd\xb3I\xe4\xdc\x0c\xcb%w\x0f<\x95\x1cer\xc4w\x18\x1bg\xf3\x04fM\x8co\xc2\xd2\xdd\x14\xc9M\x19\xa7\xa9M|\x8a\x8aq\x8a^\xbe\x94$\x9f&\x1d\x1d\xb71>\xe7b\x10\x9d\xde\x02$\xdd\x85\xa5\xc9V&\xaeT\xaf\x0c\x04(\xc3\xa2\xa4\xa8=\xa4\xc7\xeb\xe6I\x9f\xce\xf0\xe3&u\x99j\xeeK\x07\x11\x157\x81l7\x8eO\xf9.\xf7\xb8b\xe9\x84\x1e\x0e\xb9w\x1e%\xb7\xe5\x93\xf6y\xd8$U\x84N\x82\x12V\x0dC\xc0\xba\x95y\xa8\xba\xb37\x1b\x1e8\x90{o\xde\x9f\x7f<{yq\xf5\xee\xf9\xffw\xf5\xe2o\x17g\xe7t=\x0dL\xb2\xb8\x139\x89\x0e1\x98\x05\xe9\x9fwy\xf6\x18\x83\xdf\x0b\xdf\x1a\xc5di\xd8a\xa2R\xb3J2\x9fie)\xbd\x00\xb0\xe5\x18N\x92\x1e\x01\x13\xc4\xc5{\xb5\xdb\x94\x1f\x89K\x8f;\x1e\\\xd8\x1dqZi\x96$\xb6c\x14\x87\x12\xca\x901K\xd3'O\x84'x\xf9\xcc\x1eb\xc2\xbcJ\xa9\xd8\\\xaa\x9d\xd9\x0d\xf8\x1864\xb2\x93\xfa\xbab\xf1u\xbe\xbc\xf3\xbf\x96\x91\xa3|\x1b\x05\xcb\xab$\x89\xce\xc3\xdf\xe8t\x1e\x0e\x9fb\xf2\xa1+\xeea\xd3\xb9\xe2\xb5\x13[sJT=\xbf\xb8`\xbb\x87\x1f\x8cT\x7fd\xf3\xf0EZ\x0b\xcc\x16!\xb5\xec Y\xeb\xa3v]\xd1\x91k\xcb\xb8\x06\xfb\xc9st\xf5\xa7\x0d\xb1_\x18\x1cJ+!\x13\xdetY\xa9Xa_hmM\x98\xe1K\xdd\xd5\xad\xcd\xccAV\xec16\x08\x02ZGc\xdf\xd43\xd0\xc9\xb5\xd5\\j\xb5\xd0B\x0c\x933\x0c\xd2\"\xd5\xa5\xbc\x07\x99\xc4\x97FvK\xc8\xa5j\xc7\x83\xad\xcb\xb3\x0f\xdcV\xdc\x84\xee\xcc\xbd0\x13\xe7>7F1\xb3\x812\n\xf7\xff\xa0\xf9\xa3\x97\xcf\x8c\xb9Q\x13\xce\x19_\xe1 \xdf\xb1\x16\xa1Z\xb7is\x91J\xce\x1e'\xb0p\xa1F\xe9I\xc7\xe7\xc6\xa0\xfe.\xbb\xf5W\xc3\xfd\xb6x\x9d\xa0\x06\x0fh\xd3\x13\x11\xad\x9eH6\xd7\xe4=\xc9(\x89]\x99\x0e/\x8b(\x0fW\x11\xa1\x10\x1c\xeeo]\x87\xb9\xf6X\xac)\x1a\x06Gh\xbeK\x8e\xd8\xf2\x1b9p#\xe2\x9f\xba\x98\xb4R\xc7\x7f e\x82\x1cB\x04\x04\x10\xeb`\xd9\x19}W\xb0\xec~#XvF\x8f\x02\xcbn\x03,;\x8e[=\xa2`b\x7ftZ\xb85\xa0\xb5\xbf\xfb]\xa1u\xf8\x8d\xd0\xda\xdf}\x14\xb4\x0e\x1b\xd0:\xd0Ck_y\x9d\xe8\xda\xf9\x83F0\xcc\xe6LX}a\xfc\x16x&\x8f\xa7\xf2(\xb1\xfa\xd5\x8b~S\xb1Z\x890\x90\x90\x1f\xa2\x19\x1e.\xba>M\xa0\xd9(\x96>>\xa1\xbd\xe5w\x9d\x1f\xe3\xeac \xa4\x89\xe4\xcc%\x19(\x1b\xa5\x1b\xd0\x83\xee\x14\x17\xef\xc5\xc7j1\x9b\x9c\xac\xa0\x0f\xb5\n\xbd(Vq\xf1\xc6_\xae\xd3x\x1b\x9d+.^\xef\xf3u\xeam\xa5\x8e\xa1\x1f\x85,.\xde\xfe\x87u\xda\xef\xb4\x1d\x86\xaa\xe2\xf3u*n\xa1\xc6\xa1\x17E\x0e=\xa9rX\x872\x87j4\x17\xfdF\xd3I\xac\x03\x94v\xd1Z\xc6\xfa3\x8b\x0eUz+\x8e\xb51\x14\xd4\x8b0w\xc4M\xb0\xac\xbef\xd3\xa0\xa5\xc9\x1eD\x0c\x12\x1c\xac)\x0cI\x1d\xa9\x93_\x0b?j\x8f\x1f\x01ZiC\x87lA:\x0c\x85\x8df\xeb\xc1\xc3\xcf\x80\xfb{\x8e,KY\x88\xde/\\\x19E\x18g+L+\xd6\xefd2)F\x98\xffRC\xca\xdf\xdaqq>=\xe3f\xd3%]Q\xba\xf3 \x8e\xe4\xfe\x92\xde\xd2\xcf\x83\x85\xbd\xed\xfd>z\xd8\x9e;\xde\xdf\x930\xb6-\xb0Dx\xb0\xb22\x9e\xec\x89\xa5P\xf7<\x0f,\xc7q\xc1:\xe6\xf4\x06\xae+]6\xf4:\\\x0c\xf2\xa4N\xa3\xf6\xef?\xd5*\x8fW;YU\xcfmf{\x8e\xda\x11\x0e\x90\xb1Z.-\xed\xb6\x94\x17\xcc\xd6,i\x9c\xa8\xb9\xf0u\xa7'pY\xef\xfd=\np\x06,\xd5\x9cr4\xeb)>\xee\x8f\x9e\xd2G\x80\xf6\xd1\xa6\xf1\xa6\xf0\x8c\xf7'\xa7\xbfZ\xdd\x84\xaa\xf2\x9d.\x04Je\xe6RH\x07\xb8\x10\x97\xbf\xd2\xf2WR\xfe\xaa6_/\xf1^\x88\xae\x03[t\xf5`\x0e,\xd8\xa2\xcb\xa9\x90%z\xa1\x0b\xbe\xc3\xcc7\x10\x9c\xa5^0\xe1*\xd8\x9ae\n\xd3\xec\x0e\x8e`\xc6\x0ci77gf `4\x991 `0\x99\xb5J\x00i7ia\xd6KZ\xda\x8c\x83\x1f!\x01\x0c\xe1\x18\x8d\x90Q\x02\xe8\xc31\x84f \xa0\x8c\xa5\x82\xa8\x98\x92>\xb1\xc6\xa4\xb6\xb8q.\x82\x92\x9b\xe3\xdbf z\xd3\xba\x7f\xad\xc6\x96\xf5\x90\x1a\x98:\xaf\xad\x11\xc9\xe4\xff[\x1b\x1a\xb66\x84\x1e\xfaz\x0cf=\xbdp\xdf\xd4E\x10\x86\x1cm}\xa5\x10?X\xac\x0f\xda0@\\X\"\xe2\x87\x984\xd99\xba\xa8\xf1\xe5\x1f\x1a\x03\x03\xa9\x91\xfe\xd4\xd8t\xa6\xeacz&IB\x07s\x1c\xcc)\xf9\n\xb2x\xa1'D\xff\xde\xc1\x0c\xe5\xa5O\x7f\xce\xed\xa9\xf7p\xc2\xf5z\xc9\xda\xeeU\xadud\xaf\x17\x17Fu\xc3\x1d\xee\x8e\x96\\\x02\xea!\x9e`P\x9e\xe3c8\x84\x1f)\xfd{\n \x8ca\x08[\x908\x0e\xdahk^\xf4\x1a\xf0\xfb\xb5\x06\xbc;z\xba\xfbt\xff`\xf4\xf4;\x8dz\xd7<\xea\xbc9\xac\x1d\x1c\x16\x03F\xaf\xc1}\xea\xbd?\xbeea\x99\x96j\x0b>y\xf4\xfa|U\x1bQ[J\xc6\x90\xeeB\x04\xc0\xc0e\xa0v!\xe1<\xae\\\xc7h\x87\xbd\xa3\x10\xd8\xed\xd5\x87\xb7\x8f\xee\xc3\xa1\xa1\x0f{#\xf6\x8e\xf6\xe1P\xe9\x83|\x97\xa9t]\x1f\xfb\x1d\xe1\x15\xd7OI}\x02\xff\xfd\xdf\xc4U\x83`\xe6p\x8a\xa9Z\xfe\xfb\xbfs\x97\x9d\x14,\x0c\xe5&=\xb5\xcb\x1dBD\xc4\x11B\x0f\xf6\xf2Q\xeaT!\xc9\xec\\\xf9&\x17\xdf\xe4\xe57\xb9\xf4\x0d)\x9f\x10\xc7`\x03\xecT:\xcf\xd2\xea\x1aaa\x0c\x90\xb9\x96\xfc\xa4\xa4\xc0`K\x8d\xcb/\xae\xb8\x0c\xf3\x9b\x08q\x86\x81\xbb\xa81\xe7\x9cNH8\x19\x13S\"\x80\x0d\x04)\x00\xd2\x95\n\x07\xaa\x85V\xf7\x80P\xd8\x0f\x11\xd5\xe0\xedYO\xb9\x1a\xe1\x92\x19!\xb8A\xaaM\x90\x13\xb2|\xa3\x05\xf7\x89\xe56!\xdcgoX\x12G\x9b\x9bt\xd89\x17\xae\xffxB\xe9\x1e\xe7\x88\x13\xb5\xec\x1b\xd8\x84\xf0\x12~\xd4\xb9v\xebIY\xfd\x88_\xfccF\x0c\x9b\xb0\xb5\x95\x8bq\x1f\xe1\xd2\x1et\x0c\x97~\xf0\xed\x03>\xec\x83\x10\x84\xc6\xa9\x1c\xe3\xd0U\x15\x1cl\xe2\xfa\xb48\xdco.\xab^\x8d\x8e\x0c\x8drK\x0f\x04\xca\xf0\x12\xcf\xfc~\xfdhN\xf6\xb7\xf5\x03\xa9\x8dZg\xfa\xf4cg\xf4Hx\xec\xaa\xfd\xb0\xcd\x00\x91\x1f\x8d\xf0\x11\x8b\xf37\xdc?88\x18\x0d)\x17Q\xbe\xdf\xe9\xd9\xedG\x82\xaf\xd1\xedF\x1f(gc+#\x18\xee7\x87P\x1b\xd5\xcee\xab\x08\x9fv\xfb\xff:\x8c\x06\xcfN\xf8\xe7\xc3\xd1\xa1\xc3E\xe1[\x9cv\\%\xb76\xa5\x12(X\x1d\xc7\xedF\x07\xff\x10\xf4W\x03\x8c\x84\xdb\xd2\xcb#$/\x9bX0T\xb0`\xda\x0e\xa4P\x03\xa4\xd0\x08\xa4\xb0\x07\x90\xbe\x13\xcaD\xdf\xebr\xc5\xa3:\xefG\xc0\x88\x10[\xd2>@\xaf\xd3\x9e\xd8u\x0d\xe4j\xc4fM8\xde\x88\xd8\xaaF\xe4b\x84\xfd\xce\xe8`\x9f\x0e2\x86S\xc6\x08\x0d\x86\x07\xfb\x03\xb8\x87\x18\xc6\xdd\x14\xc8\x1a8\xfa\xd1\xc3a\x83\xb8\xaf\xa1\xf0?n8\xdf\x0f\xd5\xaf\x87\xe9\xebx\x92>\x1b\xed\xf6\xean?\xe8\xf7\xef.\xb6\xdc\xect\x0f\xe4\xde\xd5\xdd\xd7Q\xe2k\xb0\xfb\xe3\xba\x9b`\x95\x95\xa2ac \xb8\xbe^\xdd\xf8^Pktc\xd8\xb7\x1b\xaf\x92\xe2:\"\x8f\x04\xc7ag?\x06\x82\x01\xed\xd7\x8fG\xc2\xa3\xbb\x1f\xc3>\xfd@\xe6\xd9\xc8\xcd\x18\x848\xc8\x86n\x92\xda\x01\xc7\xacXPm\xfbF5 P\x0f\x93\xd8\x81-\x8a\xf2M\x8e(\x899\xc6_\xd8\xe2\xf4\x81\x1b\"\xafBN\x13AI\xc4\x8dc\x92\x15eD\xc4 \x10\xd8\x86\x84\xc9\x81\x8c\xe8\x8d\x16n\xc5b%$\xb5d\xc2?\x10\x921\x161BSc\xa4$AS\x88\xcfJ\x88nm%\x18 \x8e\x93\n\x1a\x90&\x02\xa4\xe1w\x03i\x83\xa8h\xb7`\xd1\x00U\x85%E\x16{{.\xeaQ\x8c\xf9~pv\x10\xe4\xb3(IP\xd2\xcd\xb1\xb5\xbc\xca\xb8\xc9\x7f\xaf\x81\xe8(\x90o\x1e\xcb\xc8e\x92\xe3\xb6\xd1\x9cj\xb6\x87[\xcd\xd9\x90\xcd\x19\x8aH)M\xf5\xf7Z\x03,G*=|z\x0e\xb27\xa5\xfc\x07\x0e\x92\x8fF\x1d$\x1f\xbbf\x90\xc3\xb5\x06\xa9\xa3V\xbey\x90\xbb\xae$\x12\xef5RF\xb3\x88\xd1\x8ev\xa5\xe1\x8e\xaa\xe7\xc3}\xc3\\k\x963\x85\xcc{\xfd\xf4\xb7\x92E\x12d\xfe\x80\xe9_\x1f2\x06\xa8\x0c\x0dP\x19\xe9\xd7\xccN;d\x86\xbd!\xb3\xe6\x11+\xa4\xc72X6\x8c\x06G\x02\xd57\x8e\x07\x0c\x1d\xad\x97\x9d6\xce\x96\x84\x1d%[\x1a7o\xbd=\x18\x9e\xc5\xfa\x83\xa5#J\xef#Op_:n\x88\x10y3\x89z\xc1~\nsLv\xb6\xd3\x01]\xe2\x97\x05\x86(r\x95s\xdf\xa6\xa7\x94\x0f\xcf\x9e\xc1\x80\x9e\xa3\xc5w9\xaf\xd6\xa4\x00\xfeO\x99\xe8\x16*\xe2\x9b&[\xcc\x85D`\x84\x15\x81\xb1\xf6\x8co\xfecf\xfc\x0f!P\x86\xa3\x03\x17\xb6\x86\xa3\xc3\xb5i\x14R\xd3!Q\xd02\x9f\x84\xe1\xb7\xd0/\x7f \xf9\xb23:\xd8\xa7cE\x19B?\xd4\xfe\x07\xd20\x7f \xf3\x88\x81\xfe\x81t\xcc\x1fH\xc6T\xf9\x10\\%\xedA\x8f!\xb7\xcfm\x0f\x12\xa7F\x12}\x13A\xf3\x07\xd23f\x10\xd5\xb7o\xcdHB\xec\xe2\x1eP\xfc'\"~\x0c\xf2\xa7v(\xbeR\xe6\xac\xcb\xab\xa2ji\xdd\xf9RZ\x1a\xf6j\xc9$Ejo\xea\xedc\x06e\x12\x14\xad\xd5T\xe7\xa8\x82du\xb7\x1e\xddR\xa5\x9b\x1c\xa0Cd\xe9\"X\xd9\xd5\xe7\x8a\xa7\x97\x94\xa5\xa42E\x90\x0b\xd0\x0f\xf3\xb2F\xae\xe2HK\x12\x10\x9d\x17\x98\xf7eWz\xa7\xb0\x11 \xa5\xea\xa0\xdc\xad\x8e*\xf26\xc3\x9b\xdcO\xe7$?\xcf\xfd4\xef\xce\x86Z\x9a\xf1\x003\xd6T\xba\xa1o!K\x8a4 k\xb4\x90\xb6\xf5\x97\xd5v\x16O\xbb\xebJ\xeb\xce\x17%\xf4\xeb3*\xd9_\xe5\x18{iK\x9a\xa8\xda\xcbM\xadU.\x12\xb4L\xbf\x95\xea\xe3\xd6\xe3\x1cTn\xa8\x18t\x99+\x07\xb1\xc5\x96\x904 \xb0t \xc3#HxV\x83\xad-4\x0bK`\x13\x10I\"\xae\xa3w\xba\xb8/\xa5\x93\x11eA\x86d\x07X\x18\xaf\xf5\xb2\xfe\xb105\x8aY\xda\x1a\xedk\xf3\xb9d$\xaf\xf2\xb8\xd4Lubf\xf6\x14:\xfa\\\x98B\xef\xd7\x86\x08fa\x14\xad\x87\x084NWkg\xb6\x16\xe9 0\xa4\x06?6\x95\x1d\xa2M\x9f+\xe1\x85\xe6'.\xcf\xba\xd1\x95\x19 $\xde\xaa\x16\xb0\xdcdy\x04\x18\x80\xe8\x18m\x8c\xc5Am\x88\x8ff\xce\xb7\xaa&\x9b\xd1\xe4\xc33\xf9\xb3\x97\x19\xbf\xfb&\xf36\x80\x1d\xdb\xad\xe7\x02NM^\xc5&\xcf\x8fF{\x95\x12`:-\xc9\x9b)\xcb-\xe2T\xe9\x17a9\x00n\xab\x87>\xca\xb5A\x08\xbc\xe8OB\xf8_P\xaca\xb3\x977b\xe4\xd4\xfb@\x07\xfb\x19N`{\xf2\x9f\x9b\xbfl\x0f\xb6\x9e>\xdf\xfa\x0f\x7f\xeb\xb7\xad\xab\xcb\xed\xb9\xc9\xf5\xe6\xd7\xf6\x10\xae\x80\xca\xd9S\xb0\x06\xe8\xf4_O\x13:V\x1e\xd4\xfbfh\xf0\xb5Q\x01x\xa3\x0f\xd0\x96\x03\x8f\x8a3\x84\xed\xce\x1c\x97\x95\x83L\"\xc2\xf3\xeb\xf2:\xb4\xa7P Y`\x9bFb\x07\x07\x9ea4\xef=qD\xef\x1d\xec\xec\xee\xb6!\xdc\x90\xe7\x873\x97\x80r\x93>\x83\xbd\xfd\x9d\xe1\xd3\xae\xc2\xf4b\x89(vh\x7f\xb6\x86\xb43<\x99\xc4h\xe7\xa9\x0b\xc3\xa7C\x17\x86\x87O[\xd0\xba\xb8\x82$\xce\xc3\xb8\xd0\xe7R\x12\x979{\x10\xf0\xbe\xfb R?\x19\xa5z\xf2\xf5O\xd4{\\$\xed-u\xb6\xd2\x9e] \x97\xc9\xfe\xce\xc8\x98BP\\\xfd\xa0\xe2\xfe\xc1]\x8e\xb9\x8f\xc6>lR\xban\x8b\xa7 8>\x86!3t\xd9\xe2\xa3\xd1\xd6\xc0O\xc5\x84\xf3==\xc6c>\xc9\xab\xfd\x1b\xb3D\x15]\xfb\x8c58d\xd9Y\xba\xd2\x1f\xf0\xce\xc4\xad\xe3\x10\xf37\x1a\xec\xf6l}\xb4^\xeb\xf0\xec\x19\xe62\xc0\x00\xdb\x98\xd0 \xa6w\xa3\xc3^\xdd\xc2y\xea\xd7\xaf\x9d\xf5\xfb\x85I\x17F\xa3]\x16\xc2\x03\xf6\xe1 \xed!\xf6n\x8d\xbev\xa0F\x1c\x07O\xd9\xa0\x8b3 \xd2i\x05\xc9\x94\xc0*1x\x91\xc9U\xb2\xf1\xee>b\xbc\x87t\xbc\xbb\xe4\xeb*I\xf3\x0cN\xe0\xf7\x07\x89v,\xc1\x106<\xd2\x1b\x9b7#\xf9E\xb8$I\x91\xc3\xc2g~\xa0\xd7\x84\xc4 B\xe6W\xf0~\xd04\xe0w7\x10D\xc4O\xbf\xa1\x89\xa2\xb9\xe0\x19n\xc5\x18`e\xef\xab\xe8\xc2\xe5#\n>\x95o\x16T\xe3\xc9 \xf3\xe2\xda`\xf9\x8e5\xf5\xd0C\xb6z\xecv\xd4\xab\xcf\xb7!\xaab_\xd4\x97\x81\xc8\x0f\xa17\x955\xa6\xef\x10U\xb2\xa5SF\xcb\xd79\xfc\xb7\xb6\xd0\xac\xab\x94\xd2v\x07\x0f\xa8&l\xa3Z\xac\x8d\x95\xa0\x1d\x03f\x9d\x11\xdf\xc8\xbc\xa6\xb4\x10O\xe5\x9b\xb1\x8av[\x13k\xd0\xeaU4-\xdf\x19\xe6\xc9\xd4\xa9\xda\xe2=\xad\xdf\x8e\xd5,\x89\xad\x1d\xa3M\xa8Y\x15\xcb_\xb6\xb4\x9a\xe8\x1e\xe7\xa9\xcd&Jb\xb3\x00C\xbf\xd4\x9f\xcdx\x12\xda\xe6\xc6Y5f\x04\xb3\xb7b\x1a\x0b\x9bW\x05\xa5X\xe0\x14[\x14\x01\xc4\xed\x08\xc3\xa7b\xdd.D\x92\xecuj;\xed\xfbu\xdah\x16\x89\x88\xc0\xc4L\xd2\xb3\xad\xb0W\x1a\x8a\x01\xfb\xd8\xc6KR\xa6S\xf4\xed\x083\x11\xe9\xd79~@\xb1d$\xe0\x8aA\xc4x\xf6\"\x9e\xf2cv\xe9\xa5El\x9b<\xfc8(\xe4&;v \xf0D\xcfl\x8f\xea\xe6N\\\xfd\x8ev&T\xa7\x98K^\x86U\x1a_\xe9\xa1\xdd\x16P\x12Q \xab\xc8G\x14\xc8b5h+\xa5\xabV~\xe1\xf6o\xc6\x8c\xc2\xc4\x95\xda\x06\xf9\x12\xf4\xc2^\xe2\xean\x08d\xf2K\xc6\x9b\xe6\xe6a\xad.@\xa3\x01\x8eL;\x1a0\x8f^\xfb\xe6A\x05\xd8C\xebN\\h\x858(\x0b\x9c\x15(9\xe1B{\x96\xe6\xe8D\xcaZ\xaa\xab\xee\x86n\xec\xaa\xc5\xc4\x8b\xc9\xd7\xfc\"\x0c\xbe\xb4\x12\xa7b\x9fR\x8a\x80\xd1\xbc\x8d\xb8\xcdM\x93!\x94W\xa8\xc5\x9e\xc1\xb0 \xce\x12\x17\xc4\xcc'\x93\xb2*\xea\x97G\x10onRr-f\x86XR\xe8\xe8F\x98\xfd\x883\x1b\xe4V\x80\x0fe\xf7\x98\x15Z\xa2\x07\x03\xfa_aO%T\xe8\xc2B\xb6\xabG\x00\x9b\xcfF> <\x1c+[\x8e\xd5\\\xd4\xaaM\xbc<\xcc#\x0cJz\x9d&\xb7\x19I-\xfa\x90\xff\xe6a\xf2\x13\x8f\xc47H\x07\xd2\xdf~:\xbf\x11y5\xbd\x1b\x92ft\xfeX$\x93\xf2>+K\xe3\xbb\x1b\xfcn:}\x1bf9\x89\xb1\xde\x1b\xf6\x12\xdd\xd1\xd9\xef\xd9L\xfcL\xc92\xb9!ja\xf6\xf4y\x14\x89\x17\x99xC\x96a.~\xafR\xb2\"q\xa3%\xfe\xf8C\x1c4\xea\x8d\xa4\xea\xccK\x8d\xef\xc0\xc9e\x1dz\xd7a\xdc\x99\\\xa5A\xb5\xae\xd2$ YV~\xccC\xa4HA\xf1\xea\x8d\x04\xb7\xd3\xb6\xf9\x16\xac\xd2\xb6\xa5|\xb6\x98\x86\xe9\xe3z\xc6>\xed\xeaW\xb1\xf4\xb3/=z6\x90\xb6>h\xb8\x10E\xc5o\x15\x19AEO\x90KL\x9c\xcc\x90\x98G\x84\x1a\xa0\x8a\xd8\xda\x90Uu:}\x0f\x06\xb1\x15\x03\xf5\xcb\x8aU\x19C\x83k|\xc4@\x9aH/\xd5\xe2\xd0\xca\xbe\xe6\xa4\x0bk&f\x94\xd8\xc0p\xc7'0\xa4\x88E\xd2\xdeT\x98jx\xc9\x835\xc8\x8f\x9a\xf4DlLx+duZ\xb0\x19\xd7\x07\xa8\xc2{\xb5\xd7Lt\xcfP{\xea\xa8\x02|\x9fb\xdep\xe2\xd7\xb1\xaeof\x961\x17\xd6\x86\x88\xa2\x19\x0b\xd0 \xc3&\x91\xa1\xa1GnHzW\xcb\"\xdd\x95\xda\x0c\x19\xb7x\x92^j\xf8\x1bts\xb1\x19W\xcdp2\x9b\x04\x17B\xc7a:\xb5\xd05s\xf2Z\xde\xbb1\xf15\xc2\xb5 \xc7\xb8\x84cN\x0f;8\xc5\xe0\x14C\x1e\xd98e\x07\x1c\xcb\xb9 )\x85k3\xa9\x9d\xe4-\xa0\x16\x97\x00]\xfb\xa6\xef\x03}6\xc4Y\x9a,[Yv;4\xcc\xc3\x83\xf1\xb8\x8f\xbc\x94dE\x94\xbf.\xe2\x80\xae%\x17\x9f\x04\xc9rU\xe4~\xce\xd9\x94\xce\xcd&6Z\xe3\xe5\x03\xab/#\xf9\xa7GWJgH[q\xed\xa1L\x0c\x88_\xb9wuE\xb2w\xc9\xb4@\xf6\x8d\xf2i\x98:\xd6/\xa2\xfc\x1dY&,soB\x9f\"\xda$\x02\x8b\xbedH\x94\x11\x1d\xe5\xcb<-\x82\xbcH\xc9\xb4D\xb6}\x18\xefGP\x99\xbeBe6\x99s+\xc1<\xb8F\xea]\xc8\xfeM\x1dg\x87C\x06\xb30\xcd\xf2*^\";\x18\xfc\x18X\xf5p\xbb )\x01\xe2\x07\x0bX\xf1\\\xbb\x94\x11\xf0A\x9c%\x9a\xa3\xc3Gk\xb0\xb2SG\x0d\xa0\xd0\xbd\xc6\xd3\xf8~!wYC\x88UR\x8bq\x1dU\xb5\xf9\xc3\xd3\x0dY_\x0e\x8e\xdb\x93\xe4\"Z\x84\x9cW\x08\x81\xd3~\x03F\xfb\x11N\xfb\xe5\x93\xb4\x9d\xee\x03i(^J\xa6E@l\x85\x13\xea\"\x98\xc9\x84R\xcb\x97\xcc\x18R\xa3\x8es\xe1\xf7\x07E %\xb1\x9fu\x91\xb6\x8f\x04L}\x99\xd3\xf5m'z\xb5\x97\xc2\xa7 \xee#\xb6\x87\xc3\x03\xe5@D\xc6\xc6\x1e\xed\xee8zV4\xb6\x87\x83\x01\xa5\xfc\xda\x1a\x00Y\x84'\xd2'$6Z\xabK\x83\xea\x91TLZ\x12\xcc\x18tM\x96\xb4\x1a\xea\xc1\xaeaD\xed\xcc\xf5\x86\x1c\x0b\xd5\xc4G\x8b=\xb6\xf1H>Z\xedq\xac*$\xeb\xfb\x8e\xc9\x9c\xc6`\x8d\xbc=o\xcf\xd2\xad\x12\x8d\xfd\xe1\xd5\x153\xd4\xa4\x7fO\x84\xdb@o\xf0\x8d\x0e\x0e\xd6\x86\x9f\xcc\x85\xca)\xe7j\xb2\xeau\xa7Q\xbf`\xf7\x0ev\x95\xe7!\x7f\xbe\xa7<\xa7{\xc7\x9ap\x9c\xf8\xbe\x88\xa2K%Tx!\x17\xf8,\xd2\x9d\xab\xa524n?E\x13\x04f\x0fx\xe1\xcf\xcb\xcc\xde\xdf\x01R\xd2\x89Bo\x0b\xcc|2\xe6\n\x16\x08c\x8ev\x99q'\nF\xc6\xc8&?\x16\xb0{OGz\xc8>\xdd\xeb\x9cx\x0d\xbd,\x96q\xc2\xdej\xb7E\xca\xb2\\\xc4%\xd8\x1e\xdb\xf7\xd1Su\x96Y\xdf\xf7w\xd41\xb1Uqp\xd89$\xc3\x0c\x85\x0c\xde)\x83w\xb26\xbc\xf5\xb2> !\xef\x0e4#\x91NXJl\xb4\x93\xd4\x82V\x99h\xce0\x89s c\xa42\x84U\x98\xf9\xbc\xab\xbdx0\xc0\xad>\x96\x90\x1f\x14\xfbR\xb5\xa1\x17\xc6\x0b\x92\x86\xfc\x149\x1c:\xcd3-\xb6w\x06\xeaL\x16\xac\xae\xda*\xac\xea\xb2g.\xf8\xd2\x9br\x80\x19\xae\xbd\xa2\xd2\"\xf0\x14I\x83#\x88\xe0\x18*uFD \x80\xe6\xda\xa5\x04t6\x89\x14\x18\xce\xaa\xfa&\xc1%\x8a\xb9\x94G\x94)\x93\x1f\xb4\xebwg\x86C\x879\xc7\x88@\xda\xc9\x0cfU~IJ\x12\xce\x1a\x84\x96_W\x95\xb9P\xa8\x0f\x10\xfbo\x08\xd7\x89\x94\xf8S\xff:\xe2\xb1c\x17aV=9a^\x80\xf5\xf2\xb7i\x98\xd7\xcb\x97Oxy\xa6q\x89\xa2\xe4\xf6\xaf~4\xfb\xb0\"1'\xd3\xeb\x15\xd5K\x94\xb55>,\xabL\xe2\x80\xd8\x16\x89\xa7\x96\x0b\xabvp6\xb5\xf4\x9a\xba\x85\xc3\xc1\x95\x18\xc0y\xee\xe7\xc4#\xf1\x94L\xe9\xcb\xb4\xd4\xc5\xd9S\xd6\x85.\x1d}c\x0e\xb16[E\x0d\xf4\xe2;\x99\x1d*\x1f9\x19.\xaf!\x17,\xd1\xaf\xbf\x86\xf3\xc5\xcf~N\xd2w~\xfa\xc5r\xd56\xe2bIRZn\xdc\xd0\x85\xcfI>n\xa7\x98\xc5\xe6\xd6\x00b!7[\xdf\xfc\xd5\x80\x1c\xb7\xd7P\xa6$\xcb\xd3\xe4\x8eL\x1b\xdd\xef\xddE\xc9\x9f\x86\xf5V\xacS\xec-]@\x8d\x12\xb5\xf1TK\xac\xfe\xa5W\xf6\x0d\xbd\xce4\x80(\x0b(d\xb9B\x08\xd4\x06\xa2\xc7\xc8\x7f\xfc\x10*\xfd\xb3i\x10\xb4\x88Q\xe1M\x19,I\xe1z\xc5\xbf\xea:\xe4\xb1Av\x80\x14Q$6,\xae}W\xdeGyM{\xff]\x0e\xca\x9d\xe1\xc8\xb1\x1f{\x8a\x93\xca=\xabT\x91t\xd1\xe8k\xf6o\xff@w\x90\xb3\x10\xf7\xfe\xd7G\xf6;\xb1\x07.\xd2\x1e\xdf\x00\xccu\xcbk\xa9\x94\xa1flvl\x1f:]\xf2\xbe\x90;~z\xe2l\xfb\x98$\xc2\x16\xc0\xc4@\x0b\x82\xa6\xf9\x1d*8\xf4\xb2;\x19\xc1 \xc3Pz\n6\x05\xd6F\x0bez\xd0\xd2\xef\x1b\x86\"\x1a\x9a\xb2}\xd4D>\xca\xf1h\xa7\xe7\x8cm\x8d\xf6,t\xb7\xc5\xedVP.\xde\x16\x9bH\x03\x1f8\xe6\x1b.I\xa2\xf3\xf07R\xe2\xad:L\xe8vl\xa4o\xad\xdd\xfa((\xab=*\x1a\\&\x16\x9cNi\x9d\x94\xb9I\xc6\xed\xa8@\\%\xfb\xda:-q\xad\xcf\xdc\xba\"\xf6\xe6$\xa7\xf7\x88\xac\xd0\x01\xca\xa7O\xcb\xf1\xa2czu{\x02\xc3\x81C\x0b\xa4$\"~F\x98\x84\xaf)\xa1}\xd0\xa8oc\"\xd2\xa9b\x83\xe9X\x05\x08\xbd\xf2\xdbD-\xd5\x0b\x06\x8fY\xe4 \xeb\xa6\xd6Y\xe8\xa0[\xec1\x8b\x10\xe0\xe8\xc0\x01\xda5\x0f\xbauO\xab\xe8\x03\xce|\x91\x92\x06@\xbbD;\xe2\xfa\x16h\xa5\xdf\x05Zi\x19G\xa9\x114Z\\\xfd\x01\xd6\x88\xc8\x00z\x98\xcd\x92\"\xed\x02Y\x8bT\xf1[\xa0\x96|\x17\xa8%R\xf4\xa9\xd4Q\xf5\xf9\xe2Z\x0bp\xae\xd6\xf1\xb8\x8e\xca\xf4Gg\x81O\xdb\xe4ju\x03\x7fmq\xb3\x98tO\x95.%\xfcy\xb7l\xc4p\x94\xa7v\xb2\xfe9.\xf7\xe8\xd1-s\xb9\xd1#\xc8\x08\x89\xfa\xda\xd1\xcb\x8a\x0e\xb5\xe2\x96\xe1P}\xce\x98\xfd\xe1\xfe\x81c[Y\x1aX\x1a\x9e\xff5\xefH)_k\xca\xdfX\xfe\xc1\xc2\xf1\xb2U\x14\xe6\xb6%J\xcaR\xd8\xd8\xde\x1f8\"a\xf99F\xca\xe8\x03$\xce=\x93\x9a\x05\x98m\x94~\xe1\xda-tr\x84\xc8d\x0d\xafx4FH\xe4\x87\x14s[\xb1\xbf$\x16\x1a\xd1$\xd5=7\x9fDIxi\xd2cK\x9f\xf9\xd5\x17>/\x87\xf2\xd6M\xf6{\x0c\x19\xb3H\xe0\xde\xcb\xb9\xe3\xb0\xa8b,\xb6\xcbi)c\x871\x14\xe2\xb6\xf64\xa9\xd6\xc4\x18\xec)\x89HN\xf0\xbd+\xbd\x92\xd7\x94c\x97\x93(3\x85\xe54\xb5hu\xf84h!\x87\x04\x14\xa7}&>Ja$a\x87\xdc\xfeZH\xa1sM\x94z:9\xf4\xc1\xa9\xc4A\xc0\xb8\xcb^\xa5\xd76\xeb\xa4\xbe\xf5\x9bo\xb4o\x10\x81\xef\xeckw\xdf\xde\xaeJ\xc53Q\xdb\x81Z<\xe3\xc5UYj\xc4\x9f\xab\x12\xbb\x80?W\xeb\x99\xf1\xe7*2X\xa1\xd0\x8ci\xb3\xce\"B\x0f\xc4z\x81\xa9T\xe0\xb5O\xc9\xe4\xbbz\x81\x05+\x10%\xb1\xbe\x82\x1b8\x81\xb4\xfeh\xd9I\xb47t7\xd0<\xc8\xe7Z\xb2\xf9\xe5\"\x8c\xa6)\x89\xc7\x86sx\xe9\xaf\xc6\x10zK\x7f\xd5$\x0b\x80 1\xcf\xfc`A\xcb\xf0\x9f\xfarAR\xc49-\x85?\xf4e\xf2\x045\x9f\xb4\x14\xff\xa9/\x97\xc4\xd1\xdd\x18f\x8dw\x1a\xca\xe5e\xb2\\%1\xa1M'^y\xd3,\xf7\xb1HI\xadl\xedA\xb3|m\x05\x8cA\x03\x1cy\x86\xc7\xa0\x81J\x98\xfd\xe4G\xe1\xb4,Rx\xf5'\x9aN\xa6\xc9\xea\x82\x99De\xa6.\xbd\x8c\xfc,\x1bC`z\xcf\xd7\xe4\x18\xa6\xa6\x12\xef\xc2\xafa<\x86e\xf3\xfd\xab\x0f\xef\xc6\xe07\x9f\x97J>\x8d\xf1\xe9\xd5U\xb6J\x89?\x1d\xc3M}q\xea)\x829>\xfdc\x90Nc\x93\x87L\x12\xf0\x94\xb2\x1e\xf6h\x7f\xbf\x12\x14V\xe2\xa5\x85\x9f}\xb8\x8d\x85\xc8P\x8b\x9cF\xfb\xaa\x9eO\xcf\xa1~!wc\xd8\xd0XA\xa6d\xa6\x7fqu\x95\x91\xc8\xfc\x0e)\x84\xb1\x9a\xbeX\xeb\x10\x9a\x19O\nI\x9cG\xbc\x94T\xbbJ'?\x8e\xfaU\xf3\x85\xdcI\xd5\x88_BU\xa1\xe1\x1cX2C\x03Y\xd2\xd4*\xd3\xeb\xcf\x7ff'\x96vE\xe6\x98^\x994_\xe0\x1ch\xb6\x16NA\xdc|\xbeJ\x93U6\x86B\x03\xff\xe46\xa6|PhZ\xd6P\x01\xa7\x8a\x0b#\xbd\x0f\xea\xc7\x88\x060:`\xa4\xcc\xd0\xfaw\x1d\x97\x06&\x0b\xf0\x15\xe8,\xc0\xd1\x9b\x96\x11\x04:\xde\x19\xd5S)\x84t\xf1\xe4,3\xcf\nm9R2s\\\x88\xc4\xc3\x19:\x98\xc0&\xa0\xd2\xcfqky\x06=\xb6\x84\x05\xe91.\x9f4\x8b1z\xb7^\x10\x9f!\x1d\x14\x96\x921\xe6\xb5\xb6Q([\xd3\xe6\x99\x87}f\x1f\x93OR5\xe3.\x05\xdfTg\x18\xb5\x05\xa3&d\x98\x0eh\xea\x80\xef\x05\xfc\x8c\x84Fl\x8f2\xe2\xc3\x14\xbd\x944\xcb\xb4T\xf2-J\xc3\x9e)\x85\x11S\xef\xdd\xc01L\x8f\xe0fs\xd3\x81\xc5\xe4\xa6n\xd8s\x83\x811\x9b\\\xee\xc0\xad\xf7\xa9\xee\x8f\xf8\xd0\x18 \n\xdf\x88\xb0?\xa3\xf0\xcat=\xa5\x9d\\\xa21\x87\\\xb2\xd9|\xb5.\x96N\xcd\x96\x8c\x02^\x9a\x81e\xc3\xe0\xfeA\xb77\x02\xba\xdag.\xac0\xa9&z4\x05E\x9a\xd2\x03\x10\xfc\x1aK\x13\xd4\xc9\xaa^Fp\xca&C\xb7\x9e\xd2 P\xbbWs\x8f\"\x0f\xae\xa4P\x9a\xa7G\xfa\xf3x\xfa\x89\xc5F\xf8w\xd2\xa9t\xa8\xc6\xe81\x86\"w\x19\x96\xa5\x7f\xf8>\xa0?\xf8:'\x1e\xc3*\xf4\x17b\x1eu\xfc\x12M\xd1\x13_\xf8\x0c\xb8\x94\xa8\xb4\x7f\x7f\xa8*n\" \xd4\xba\xd0-\xdc|\xb5\x00~8h\xce~\x0cj\xdd2\x16\x8d\x87_\x17\xd2\xf1kHg!\x90\x0e\xdb5\xe5\xf2\x90q\xd0T\xc5A\x0c\xdel\xe1\xe39.\xaf\xe9\x12mi\xde9\n\xb6\xf1\x0d\xd8\x86=\xb7e$F\xf9\xbb\xba~\x8c\xe2\xbd\x15\xf3\x81\x99\xd1?cqG\xcbj\xb0\xd3rM\xec\xb4t`\xd5\x07;-;\xb1\xd3\xbc\xc4NK\xc7\x85;\x86\x9d\xee\xe0\x18\x96GpG\xb1\xd3|rW\xc7Nw\x06\xecT\xeb\xd0\xbc\xd7\xfe\xe7{c\xea\xc2B \x81\x9b\xba\xfe\x9c.\xfe:u\xfch&\xb8\xa6Gc\x0bD\x90\x12\x0c\x8d\xc9\xad\xca\xa4i\xf0'\xe8&M%\xb1\xd3\x81\xe3\x9d\xdf-\xaf\x93HO\xe9\xa6\xebU7:\xd4\x9b\x0d\x0d\x0f\xbf\xcd\xd6m\x83C!\xa9\x0c\xd0q\xc1\x7f\x8b\xdd\xdb\xc8 \x81|\xaa\xaa\x19\x19\xd3\xbf\xdf\xb0#bt\xf5\xfe\xb0sdf\x94+E\x12\xe4f]p\n\x13r\x89\x96g\xfe\xb7\xc8\x131\x1e~cxJ\xf8\xbb~\x13\x11\x1aB\x972\x95\x1b\xa9\xechH\x13W`\xe0b\xd8lD\xe1\x11k\x7f\xc0j\xa4\x93I\xfbF\xe8\xddV\x02\xa7`m\x0d,J_u\x8c\xbf\xc6p\xe9$E\x9cUb\xe7+F\x1c\xea9C\xc4\xcb\x8a\x15I\xaf\xb8yq\xc5lU\xd6c\xacR;\x97eqM\xec\x15$\xb1\xd0E\x9a\xc4\x17\x98\x98_\xcb @\x87]\x8a\xb8\x84\x89\x82\x9e\x0b\x03\xd6\x8dY8/D=\x1a\x9f\x81\xda\x93\x87\xbaU\xf1\xa3\xc0\xd6\\\x0e\xaa\xd7\xb9\xc2\x88\xc45(\xd7\xe0Z\x9f\x80\x98\xdc\xa2\xe9r-.w f\xf8\xfe\xb6\x07\xfb\x9d\x9b\\\xb7kj\xa6\xceJ\x98\xd8\x97~\x1c'9\xd0\x86\x11\xc5%)\x14q\x19sH\xbb[\xbe\xcb\xa0\x1a^\x1f\xcaxyt@\xfb\xa0\x81@P\x10\x91b\x04_\xba_S\xb9\"\xe6\xfb\xdb\\\xdd\x9ch\x19\xab\x99c\xe5\xfe\xf02\x9d\xd0\xec\xe3\xc9\xf4\x87x.\x89\x93\xa8>\x04\xdd\x0c\xd9\x03\x17B1 g\xed\xc3\xa9\xe7\x8c\xb9\x06\xa0\xb5\x18\x0d\xab;M\xf2\x99\x16f\xab\x18\xff\xf7\xc3\x8cr\xa8\x98X\xe6\xfe\xbeK\xceT\xc6\xd6\xe6Lm\xccX*\xd2dj\x1b\x10|\x048\xca\xc7\xa5\x9c'\xed\x92\xf30S\xef\xfb{a\x06\xde\xc4\x0b \xefg/\xcc\xde'\xf9\x82EcH\xdd\xda\x0b\x06\x8a>\x04K7=W\xf5An\x83\x0b\x93\xfb4\xa1\xee\x04NBpjbB\xc9\x079\xd5o\xad\x99\x94\xac\x88\xdfo\xdd0\xcf\x1e\xf5\xe8\xc6\xa5\x133\xda;f^\xd61lb\xd4L\xccP\x85\xc5\\\xefL\xcf\xc1\xe6F\xf4[e\x81\x1a\xcby1\x18/\x8c\x83\xa8\x98\x12\xa1\x95\xe9p\x1fG\xef\xe0\xb2\xad\xda\xeb\x07\xae\xc9\xed[S\xb3\\\x9bEM\xee\xe5\xfe\x9c\x9b[\xd3_O\x9eP\x1e>\xa4\x8b\x88\x89\x92\xe9O<\x13M!a\x1f\xd0\xaeJkJ\x86ofa\x94\x93\xd4n]\x91PAn\x8b\xc7J.\xb1v\xaeV*\xad\x93\xe6\x84i\xa2\x16r\xf3\x15\x9c\x0e\x14:\x88\xdf\xf7\xf7hK\xc6\xde/WQ\x18\x84,\x1dIy#\x97 _\xa5\x12\xe5\x8d\xae\x8e\x9e3\x85\xb2A/J\xfc\xe9\xbfs [Y\xe0G~jq1\xbex%\xd3Y\x89m]\xa0s&\xbac\xc6I\xbc\xc5\xbeA\x84LO\xbc|A\xa0\xec\x7f\x14f\x18\x07\xdf\x87,X\x90\xa5\xef\xc1\x1b\xf1*%Y\x12\xdd\xd0\x13!\x99AV\x04\x0b\xe6\xed\xdf\x08l\xe3Y\xcdIe\x86=\xc9r\x15Fd\xfa\xa6\x82\x9c\xcf]\x08,\xd1\x01\xcb\x85\xc9\xa5\xfa\xc1\xd9\xd7\xe6\x07\x02\x9e\xda\x0f(m\xf9\xce_)\x14v\x03\x9etK\xf2\x1d\xa4\xd5X\xd0\x8b\x01k\xac\x95\xdf\xe3{\xf2kA\xe2\x80\x98K,\xfd\xd5\ns\x1f\x98\n\xcc\xfc(\xba\xf6\x83/c9h\x97\xb8\x1e\x94H\xf3\xd0q\xea\x8b+\x9e\xb0\xadx9\xc1m\x8af\x16\x9eh\xa9z\xa6\xf1\x15m6GQ9a\xa8\\\xe7\xa7|\x84q\xed\xf3#\x16,v\xe8H2'R!!U\xae\x08Fj\xd2\xd6\xae\x16\xc3\x9aP\xc9Jz\x15\xde\xab\xb3\xd7\xcf?\xbf\xbd\x10\xfa\x95R\xc1\xdf\xb6\"\xc4j\xa8w3\xbb\x0d1\xb2\x9c:h\x1d\xdc\x03?#0\x1ck\xe7\x03\x83'\x8a~)p\x9c\x0c\x0c1\x02\x0c\xf1\x96\xb1\x9d\x91\xb9\x1d\xb9b\xb5)\xd5G\\\\\x86\xa6\x04\xd3\xa2\xfd\xa6\x86d~N\x93x\x0e\xcc3\x141\x88h\x12\xd7\xcf9\xc3&|\x16J\xe9D\x9b\xba!\xe4y.SA\x0e\xa2\x83u^{\x92;.l\x90^\xf1_\xc49+[K\x17\n\xa2R\xf0\xe6\xf9\x8a\x04\xe1,$\xd3\x12-\"C\xcfQc\x06v\x92RD\x19\xc6\xf3\x88\xf0\x11r_]\x07\x83\xc6\xfba,pn\xed\xad\xa72\xb5k\x84\xb1\xd1\x0d#\\w\x18\x7f{\xfe\xee-\xc7\xde\xb51P\xbci\x1a\x81\xf4\xae\xd1\x7f\xb1\x8f\xc9-\x14\xb6\xe6\xdcb\xc7\xa7V\xaa#\xf0\xf8X\xf5\x05\xac \x93\xbb\xad1\xd7$\xf6\x86\xc3\x9a\x19\xdf\xa1\x96\x96K\xda\xe4\x956\x81'\xf4\xa5\x1aXLn+\xd4\x1e+\xef>\x9f_\\}>?\xbb\xfa\xf8\xe9\xc3\xc7\xb3O\x17\x7f\x1b\xeb\x92\xa1\xfe\xf5\xf9\xf9\xd5\x8b\x0f\x1f\xde\x9e=\x7f\x7f\xf5\xd3\xf3\xb7\x9f\xcf\xc6\xb0\xab/\xf5\xfe\xf3\xbb\xb3Oo^\x8aR\x87\xfaR\x1f?\x9c\xbfA\xd6@)>2\xd4\xfa\xe1\xa7\xb3Oo?<\x7fu\xf6J\xed\xc6\xce\xa8\xf9E\x18\xd3\x85\xf1\xea\xc3;\xc1\x10\xbfD\x19[\x97\xf3\x12H\xb2\xd1P\x7f:\x02'v\x89\xc7\xab\x0e z8\x98NS\xe0\xe2h\xe2\xbd\xfa\xf0\xeey\x9e\xa7\xe1u\x91\x93\xf7\xfe\x92d+?\xe8\xfe6\xd3\x7f\xdb\xf5Y$>\x13\x00\xe8\xf5U \xbez\xc7\xe3\x9d\xbc#\xf9\"\x99\xf2\xef\xf4\x98\xba\x94W\xccP^\xe1\x85\xd9\xcb\"\xcb\x93e\xd9_J\x18\x16\xdeU\xe3\xb9\xb0\x97\xe4^U\x9a/\x9d\x16\xba\x1f\xf0`]\x95s\xa0\xea\xd7fL\x12f[\xbb\x87\x96\x0b\xb3\x16co\xdaw\xa4\xcd\xbc&Y\x98\x877\xc4X\xa7\x1e\xcb\xf5\xab\xfc\xc3\x0dI)\x07E\xa6\xc6\xe1\x9b\x90b\x93\xc9\x95/\xc3F\x06~\xf2/<\x05\xe2\xb0 \xf8L\x1e\xa5x\xa6\xefd\x19*(\xb5\xad\xbd\x01\xee?\x174[\xb4ms\x03\xdf\x9a7\xe8\x9c>\xeb\x08[\xb5\xf0j{\x02N\x14sA\xf9\xd2\xbbi\x00:\x96k\xb1\x88\xad\xd4\x8e;\x0es|\xcd(\xaf\x17\x19\xbf\x92w\x1b\x9c@\xc4\xca\x07\xc6\xf2\xf5\xcd\x06'\x10\xb0/dD7\x99]6lv\xc4\xa5\xe1\xd7jO4\xbeq\xd6\xf8\xf9\xd6\x7f\\\xf9[\xbf\xfd\xf2K1\x18\xbc\x1cl\xe1\xdfW\xfb\xec\xcf!\xbb}\xcdn_\xb3\xdb\xd1\xeb\xd7\xf4\xcf\xce\x01+\xbcs\xf0\x8a\xfdyMo\x87\xaf\xf1\xedh0x\xb9\xc5\xfe\xbe\xc2?\xac\xf0hx\x88o_\x0e\xd8\xed\xeb3z\xbb3\x18\x0c\xe9\xed\xab\x03\xfc\xf6\xf5S\xf6\xf6\xf5\xab\x97x\xfb\xea5\xbb}\xfd\xfa\x95&|Is\x05\xbdyu\xf5\xfc\xe2\xe2\xd3\x9b\x17\x9f/\xce\xae\xde?\x7fw6\x06k\xea\xe7\xfeVJ\xfc \x0f\xa7Vs\xfb}\xfa\xf0\xe1\xa2\xed\xa34Ir\xcdg\xf5/\xae\xce/\x9e\x7f\xba\xb8z\xf9\xd7\xe7\x9f\xb4F\x85Ji^\x0e6\xc1\xfa\xe5\x97-o\xb0\xf5\x14\x81\xfc\xe2\x00\xa19\xe0\xc0\xddg\xd0\xdcy\xcd\xa0\xb9;\xd0t\xa3Z\x1cz\xae\x1e]\x0d\xb3,d\x8e\xd2\xf1\xd4O\xa7\x0c\xff\xeb\x91y\xcbQ=n\xa4\x16\x00\xb4DV\xca\xf7\xa1\xb3\xea\xfa \xa6\xfai'\x13jj!3\xe2\xc00\xf5\x03\xb7\xbd\xb2I~\xe9\xc8\nr\x8d\xd6\x15\x8c\xa8B|3ln7\x13)\x8a\xe6\xcdFS\xcf\xef\xceO\x1c\x1c\xee\xd4\x18\x8a\x1df\xa3\xfc\xd4\xc0W4x\n\x8a\xef\xfc`\xf1\x89\xcc2.\xe1Bi\xc7\x157\x9d\xe264:a\x87\x9e\xcfX&E\x9cK\xf6\xf1\xea\xd8P\x98\x1f\xa2\xb5\x94^.V eZ\xaf\xc6\xae\x7fi\x94\xe7\x10\xb5\xdf\x92\xce\xa7\xf9\xd2K\xc9\x8cI\x91\xe7$\xffD7\xff;\xda\xea'\xe2O\xefl\xc7#\xf1\xaf\x05)\x08z\x04R\xcc\xdc\x86_\xe7$\xffk\x92\xe5\xef\x93i\xe7\x8e(\xbb*}c\xb7:6\x17q+P\xb5\x8dxSRN+3\xb1S&\x94>S+n\x08\xb0\xeb\xfd\xe0\xf1\xf3Z'74M+\xe3\x8c\x94^4'\x12\x95:(T\xc6\xc4\x13!\x97/_\x05I\x9c\x93\xafF\xdfdM\n\x10\x90\xd6S\xeae\x8b\xa4\x88\xa6\x9fWS?'\x08\x14_\x9ft\x18\xf0\xacA-B\x1d\x82\xbe\xc3\xec1\xeb \xb0\xc5\xa8]\xf6\xd5\xe3\x16`\xdcc\x016\x11P\xdbT\xadH:K\xd2%\x1b\xef\x9b\xd9{\x12\x90,\xf3\xd3\xbb~\xfe\xcb\xc4\xbb*\xf0\xcb\x17~\x1e,\x98\x86\x8f'\x8a\xc51\x9ajo\xac\x9f\nk\xe81`\xf8=0\xe0\xc8\x10\xedo\xb8\xfbT\xab?\x1b\x19\xfc6w\xf6\xd4\xf2\x183\xad2\x08\x91\"YN\x93\xa0\x10\xd3\xab J'^{\xe2\xc7\xbb\x84)q\xf4\xb5\xc5\xfeM8\xc7h\x9erf\xe5\x93\xe6{\xaf\xc8H\xfa|\xce\x1b\xde\xfe\xe5\xfal:'\xbfl\xff2\xdd\xf6r\x92\xe5\xb6\xa6\xa0\xf6\x1c\xd0\xf8x\xd0\x8d\xd7\xf0\xa9\x00\xd9\x82\xcc\x8b\x93\xa9\xc1:*\xe69V\x995\xa7~W\x8b8\xedz\x8e\xa5\x16?\x9e\xc7\xb1\x8cK:\x00\xc3Y\xb2,h\x93\xf4\xd2\xc5\x1d\xa5\xd9\xbch\xc5Z\xed\xb6E\xbe\x8c0\x8a\x1c\xda\x8e\xd1;\x07\xc6\xd2{\x8aP(\x1c}V\x00\xf1\x8bi\xfd\xd6\xd6]\x84Q)\xbbv\xd2p\xc8=\x16(\xdc\xf0?\x94db\x02\\\xdd\x0b:\xf7\x95\xd9B\xed=\xa5\xe1\xea2\x0bf\xeb\xc1\x03\xeb\x89\x92\x82a\xf9\xfc\xe9\x0d\xc6\x83\xd2C\xe1\x1c+\x10\x85\x84\xd2\x94A\x8e\xb7\xaf>\xbc\x93\x7f\xb3\xca\xc5\xddE\xf2\x85\xc4\xec\xc6\xcf\xfd\x8b\xd4\x8f\xb3\x19I\xdf\xe4d\x89\x0f_\x87\xbcQ\xba\x9d\x9fG\xd1\xcb$\x8a\x18\xc7\x8bO\x94\xdb\xd7I\xba\x14\x0e\xca\xf4\x9e\x85t\x16O\xde\x91i\xe8ce\xef\xc2%\x1e\x80\xcc\x8d\x9b\x9e\x03S\x8a\xce\xde\xf9+\x97\xfe\xc52\x1f\xfd\x90\x8e\xe1\xd7\x82d\xac\xeb\x1f\xa3b\x1e\xc6\xfc\x0f\xfb\xf2\xfc\xa7\xbf\xbc\xc5\xb5\x8e\x05\xce\x7f\xfa\x0b#\\\xc5\xddG?_\x9c\x93yy\x9b\x84q.n$(\x9c\xff\xf4\x176\xee$e\x83f\xd15^\x14\xb3\x99\xa8\x8b\x82\xfb|A\x08\xfb\x9c\xa2\xa1\x8b\xd4\x0f\xbe\xbc\xe4\x00/\x1f\xb0\xbb\xa4\x08\xb0G\x96\x88\xe7\xe1\xd2y\xcc\x18\x99\x93\xa1(Dl\xd1L\x1f\xb4\x93\xee\xccb\x92iv&\xddK)\xdd\x89\x8d73\xe0\xfb-\xa8,G\x15t\x81\xce\x1b3\xee\x8a\x94`\xc8Q\x17\"\xba\x10'\xd1%\xdd\xee\x1e\xc2\xb5c\xcd\xab8\x91\xa1\xa62\xbcI\x17\x024\x1c\xe9\xb1\x08T\xe2eQ\x18\x10\xfb\xd0\x85\xada\x97!\xafi\xbb\x9b[\xeb\xce3\xd5\x99c\xea{\x04\xc7\xeem\xd8o$xj\xee \xf6\x10\x9e\xd0s\xbf\xb9\\\xea\xee\x07\xf6\xc8PNrd\xb0w\x0de\xb8\xbb\x84\xa2;_\x0fAJ\xb8pG\xe5\xbd8\x0f\xb7o\x8a\xd8\xde;xp\xe5\xe5\xe3B\xd2\xb5\x84\x8c\x1d\xdc\x1d8\xdeL\xd7\xc3=},\xe6&\xee\xee\xda z&\x82E\x99M\xd0\x1e%\xe6&\xc6D\xf6\xc9\x08\xb9\xf6\x93\xa0l\xac\xb92T\x97\x93\xbe3\xb9&\xa4\xba\x98\xf4\xdd\xbd=\xc7\xde\x18\xd4D\x95\xa3\x9d\x03\x87\xc7\xedq\xc1jF\xcf\xd1\x9bG^QR\x8eG\xfb!\xc2\xfe\xee\xaa\x9e\x82\xe3\xa1%\x06\x8f\xb0\xb6\x12\xd1\xc2\xae4>\xfee\xb8\xba\xabPooRK\xfe}\xaa\xa5\xa8\x10\xa8<]L\xe3\xf54\x895\xe1\x18\x90\xdbB\xff\xdb\x9c\xf1Wbl\x9b'\xa5\xaf\x84n\x8e\xcd\xaeK\xbc\x9d\xa1qn\x1d\xed\xe4\xfe\x13!\xf5\x162n#\xb6\x87\x83\xa1c\x1b\xa7\x9a\xb7{@\x11\xbb>\xae\xef\xef\x0f.X~#\x8c/\xf4\n\xe5+7\xd1x\xa9\x88\xe7\x1c\xcf_\x07\xe8\xfd\xe0\xda\x9aQ|c\xa3!Vn\xcf>\xadU\x8ftat#\x89\xddk6e\xb3(\xdd\x01\xc0\x02\xcb\x86\xf1#\x17\x1c\x81g0@\x1e#ET\xf1t08\x18>}:\xda\xdb=\xd8\x1d<}:\xa4,\xc7\x9a4\xfd\xb7d\xb5lM\xa1\x07[0d\xe6\xc0\xd6\xbb0fVs(\x12\x06B\xc9\x0f\xf8\x17\x0cyFi\x90#\xb8 \xb30\x87E\x9e\xaf\xc6\xdb\xdb3? \xd7I\xf2\xc5\x9b\x87\xf9\xa2\xb8\xf6\xc2d\x1b\x15\x99\xdb\xd3$\xc8\xb6\xf1\xe3\xad) \x92)ar\x9f\xd30\xbe\xf1\xd3\xd0\x8f\xf3\x13\xac\xb2\x96:\xa6L\x1bHQ\x8e\xf5\xc4O\xe7\xd9\xe4\x92\x95\x8bi\x15\x9f?\xbd\xa9d\xdfRb\x19\xd8\x84\xa1\xeao\xc4\xea\xc0Qc\xae\xb6\"\x8a`I\xb2\xcc\x9f\x13t\xb4\xcb\x08>\x8f\x93xk)F<%7@\xe2\x9b0Mb\x14\xaf\xd2\x8f\xf1C\x1cG\x06~<\x05\x7f:\x0d)\x80\xfd\x08\x16$Z\xcd\x8a\x08n\xfd4\x0e\xe3y\xe6)n27<,d\x95oHM \xc0\xa8\xbc\x04\x85d\x14\xf6o\x04p\xe0\xa70\x89\x90\x9d\xc2\x8c\xb8\xb3\xd4_\x92\xec\"\xf9\x98\xac\xe0\x84\xceT\xf2\xc8\x8d\xd1\x87\xbe\xe3IC)]CJ\xb7\xeb\x1c\xc9\xd3\xf5Vk\x8bI\xa7x\x03\xedj\xaa\x86\xf7\x998\x03\x1a\x91\x04\xa1\x81\xf4r\xe1\x1d\xd5\xba+\xa4\xc6j.Up\xdat\xb1\x1aW)L\xf0\xd9%\x93\x94\xc6\xcd\xc8\xc0\xd887T\xe9\xdb\xbcu\xcd\xca\x9b\x932\xf2z\xdf\xa3\xdc\xb5_\xa5\x1a\xaf7\xa5\xa6\x0fi\x99\x8ee\xcdJMu2}M\xbf\xaa4\xda\x0bm\xadl\xd6{\xd7\xaaqU\xd7\xd6\x8aa\x0f\xfa\xd7\x8a\xc5;k]\x1b\x9e\xb2\xab\xa2\xae\xc2Od~\xf6u\xd5\xb7\xb6r\x8d\xb2\xcf:\x16i\x0f\xa7F\xb9\xee\xfe\x8e\x8dR\x1b\xaf\x14\x0f\x84^\xbd\xa7\x1fu\xf4\x1dq\xea\xda\x15\xe3WR\xcd\x0c\xcfIf\xe5X@\xd7\x9e0\xea\xe8\xdd\xa4(\xd5\xb9d>\xa6\xe1\x12\x0d\xfc\xfaV]\xedk\xd4\xeb\xe9P\x07\xbe\xd0l/|n\x88\xe5\xa0[\xe2P\xcf\xc4\xa7\xed?\x93O1\x970~S\x16{p\xca\x185\xb1\xbd\xb7\xebx\xec\xbd\x9e\n]\xdf\xfdWs\x8e\xe1\x04J\xc1K9'#\x0e\xd9\xbf=\x7f\xf7\xf6\xeck@V\xfcx\xc5\x97)\xf13\x9cY\xc2\x1f,\xfd\xf4\x0b\x0b\xfc\xc0n9\xe9pR%v\xa1\xe5)\xcc\xec\"\xfe\x12'\xb71\xb0g\x8e\xe5\xc0&/\x85\x95\x9c\x82\xc52\xfe\x89'\xe5)f\xe3\x99b9n\xd9\xe5U^\xa4\xe4<\xf7\x83/\x17\xa9\x8fQ\xc6\x0codk\x19)\xee\x01\xad\x10\x9fe\xb4$\x86\x0d\x14\xc4\x87\xc3\x9f\xd1.K\xe9\xcd\xca_iK|\x0b\xd6 9\xedOj\x8c\xbb\x90\xd6_\x8a\xb1\xb6\xae\xec\x1b9\x1b\x01\xce\xd3&Xc\xd0G\x0c\xc9)e\xd79 .lT\xc1\xfcq\x1e0\xe1\x07\xa3\nM\xd3\xe1(\xa1\xb4\xd6\x8e\x83\xd3%\x8884E\x91\xa0\xd3\x94*>$\xa5\xff\xc8$\xb6wv\x07\x8e\"h\x15\xbe\x83\xf8\xfe`o\x88\x96W\x07{#\xb5\\\xe5j\x82\xe5vx\xb9]\xfew\x8f\xff\xddw$w\xf1G\xecN\xf1T\xe6\xaat\xe9:b{\xd4Hu\x11r\x13\x08\xf5\xb90\x8dP\xa5\\E\x15\x103\xf5\xe6L\x14NX\x0c\xaf&\x92\xc8L\xd2-\xd1\xd3\xb61\xaaeso\x1af+\xca\xc82O\x0fo\xb5\xf032\xfdD\xe6a\x963\x05\x08Z\xeeNbs\x14\x89\xc2&\x8d\xa0\xec\x0f\xf4Y\xdc\xb4\nJ\x99\xaa\xdd\xbb\x12\xcd\x8a\xa1\xa2\x01\x8b\xf6\x05\x8b\x1c/\xbdy\xc3\xcf\xb6\xc6'\xe5\x0b\x17\xeaq\x86\x9a@\xd4\x04\xd4\x14\xe1\xfaz\xc1\x03\xa5\xfc^\x9e\xfa7$\xcd\xc8\xc5m\xf2\x91\x96\xb3\x89w\x95\xfb\xe9\x9c\xe4\xb4+.dJN\x9bf?\x02\xbd\x18}\xad\xbe\x98\xe6\x97\xd9\x99\xc8\x1dj\x14\x03!\x9e\xa3|=\xa6\xd6@\x05\xb8\x00$\xd3M7#X\xd2K3\xfaX\x1d1@]\xe6\xd1\x1c\xff\xcc\xb4H\xd1\xc8\x85\x99s)PH\x95\xf1\xb7-\xef\xce\x8f\xf5 \xa1\xfb\x9a\xafj\xcd\xc0\x1f\xb3\x84\x93o[\xc2\xd0 \xc8U\xdf\x05\xadB\x80\x16\x9a\xa9\x0bw\xa0I\xc6\x04\x1c\xae\xd3\x86\xce\xd7\x0f\x82bYD~^.\x85W\xbcM\x92u\x19pb\xf0\x83\xa8\xd5R\xb2\xad\xfa\xf3/\xe1\xea\x02;\xde\xab!U\x15nj\xe8U\x98\x92 _s\x14\xab\x9e\x95\x9f\xc59I\xdf\x12\xff\xc6\x00\xa6\xd2\xb4W\xd7R\xb5\xed\xaajlf\xcd;\xe3 ]L\xabF\x7fRO\xf1\xe97\x1f\x8d\x86\x93Q\x1fy\xaeyb\xf2\x88\xceC\xdd\xc9\xa8;I3\xc3I\x1aUI\xa6~Ws0a\xcc\xf9\x86\xc9\xd1\xacK\x8c\x04b+\xd9\xa1G\xbe\x92\xa0\xc8\xa5y{\x13\x7fH\xa7\x84\xd3\xedh\xfb\x95}$i\x86\x1b?\xb7\x193&\x13\x94\"\x0f\x91\xdd\xd8\xdd\xf5^\xf5f\x8f\x11\x81n\x0cZ+\xeb\xcd\xb9\xb3\xca\x86\xad\x95-\xfaVfy(\xe9\xf4\xae\xd2$A\x93\xaa7\xaf\xea\xf5\xd6\x17\xd2M\x03\xadH\x1e\x00\xcdF\xd8\xcb\xb3\x1b\x12\xe7\xccl\x01\xe7a\x0c\x89\xa7\x7f\xd3D\xf4\x8dr\xd9\x0b\xee\xde\xa7\xa9\x83\xbfk\x9d\xb2\xa2\xa4\xdb\xfa\x19\x06ku\xe51S@ZOw-\xfcR<\xd6\x1cD7\xdce`\xd1H\xf4I/;\x9a\xe4,\xfbh\xc4\"\x81\xfd\xfe\xe08\x93\x10#H\xe8\xeb\xc2\x94_\x8d\xf3\x81\xd9\xebd\xda0b>\x1a|z\xd3p\xfa\xb1\x1a\xbc\xeeY \x866\x00J\x84o\x0f\xa3|\xa1I\x8b\xb4=\xa3\xe4C\x9f9\x00)6\x84v1\x8b\x0b\x835XI\xfc2\n\x83/\x96>\x90B\xa3\xdcK\xc6\xe6\xf6(\xfe*)\xae#\xd2\xb7r\xa9t\xff&\xde%EF^%\xb7\xf1:e\xd7\xac\xfe]r\xb3V\xd95\xab\xff\xbc\xea_\xb2\xbbj\x90\xf4t\xf6\x06\x92\x8a\xfeu\xc4\x12\xbcbT\xc0\xdc\x05\xeb\xba\xc8s\xb6Cy2H+\x8cWE.?\xc8\xd0\x14K~\x92\x93\xaf\xb9\x9f\x12\x9f?sZ\xbc\xa8[#s\x88K\xf4\xb2\xe98\x05\xa0\xea \xc4\x85\x87s\xe3\xcd\x03\xb3\xceV]'DDJ\xf59\x8bY\xed\xc8b:=\xeeH\x8dx\xa8T\xf2SZ~\x92^\xb6a\x00\x96/\xe8\x11H`=\xb4\xc5\xf9\x8a\xdb0\x8a^\xd5Z4=g\xed\x9bG\xae\xc7AX\x1dO\x81\x94N(tz\x0c\xfey\x14\x95lC\x17\xd5)\x98<=\xe0\xeby\xbc\x15\x12[\\\x14O6\xfcpc\xb4\x82\x89&\xf1\xe5$\xbflC\x8ab\xfcf\xf0\xeb\xc4\x06\xe2B\xf8\xa4\x86i\xd0=\xb7\xb9\xa1<\x87)\xef`\x8f=\xf1\xa0J\x90\xf2\xd4\xe7\xc7{\x7f\xca\xbb\x84g\xe8\xf2\xa3r\xc5H\x83\x9a\xfd\xa1\xdff\x7f(.a\x87\xe8O2\x03|p^\xba@O \xda\xc8\xab\x8dF\x1e\x83\x19\xf2\xccv8D.7\xa4\\\x91~q4\x11K\xf3 \xdf\xdea+\xbc\x99\xebU\x13\xdefR;\xc0\xbe\x05\x1a.X!\xba\xd2$ Y\x86U\xffo\xdaHW\xf5b\xcf\x04M\xe8\x94\xfc\x01d\x88%\xe1\x14V0\x86\xa9\xe32\x80Q\xaa\x0c\x93\xb1\xfa^JP\xd5\xfd\xd2/\xe6\x8b\x9c\xe9\xc2[\xbbyu\xb5*\xd29\xe90\x81\x89*S\x0fc=\x12\x91\xf4\xc2\x8f\xbf\xf4\xcb\x8f\x1d\xd5\xeb,\xef\x0c,!\x0b\x01\xf0\x8d,a#\x85\x97` \xd5$A\xfa\xe8:7!\xb9\xed\x9aK(\x83\xe9\xd1\xd2U\xd0n\xbc\xd5\xaf~1\xfd\x89\x16e\x82\xf0\x99\xf4n\xc3x\x9a\xdc2\xcb\x81\xb2b\x8d\x87%H\x87P\xeea\xe2\x85W\xdcKM_\xb8<\x0eO!\x16!o\x7f\n\xc9-\xc6t\xe5\xfe'?\xb3\xc6\xc7\xc0z\xd1\xdc\x85MffJr?\x8c\xfa\x00\xac\x04\x12\xfb\x84\xb6\xdb\x199\xbb5B\xa6\x0b\x89\xda\x16oCRZIy@\x1bf\xa3\xf8\x85\xe7\x17s\n5\xcc\xa3e\xfb\xcc\x0bT^\x94\xfe\xb7/J\xb5\x93\xcb\xe4\xa6\x13_\x10\xcc\xa7\x1e\xe4o\xe2\x9c\xa4\xb1\x1f \x01\x1d\xdd&\xa8El\xdb\xae=\xc4R\xe5t\xe8\x9bi\xab}\xe1w\"\xd3\xbaF\x9e{\xff\xae\xdd\x90\x92\xbe\xde$#1C\xcah\xd7\xac\xc7?\xbdTS8\xa9\xd5\xf7\xdb?nH\x8d\xbcLVwi8_\xe4`\x07\x0e\x8c\x06\xc3}\xf872\x85\x9f\xfd\xdcT\xec\xefdz\xcb\xea\xabl\xc5\x02\xbaz\xd1E\xb0,\xff\xe3\xf6\xffQ}\xdc0\x1f(\xfa\xcd\x05u\xab\xd6:)\xa9D\xbd,\x91G3t\x02\xc8\x14\x16\xe1\xd9\xbe\xa5\x10\x17\xcdh\x95-\xe1,\xc4\x86\xafl\xeat\xf49plo\xcc\x9f\x0c\x92\x90\x85\xcbaR3Q\xa5$\x958\x81P1Y8\x81\xd0\x01\xc2\x9c\xfe\xda\xa8\xb32}L\xddb+u\xca\xaf\x13\xcf_\xad\xa2;\x9eP\xa9\x95\xbf,+\xaby\xc3\x86z\x82O\\\xe5D`F\xa0\xd4\x11\xc6\xc6\xa9\xc8\xcb\x93rG\x17\xde\x1f\xff\x9b\xe9G\xc2\xf2\xceZ\xd0\x1aKR\xc6c\xacy\x814\xeai0\x92\xd2\x85\x0eGk\xd7\xb4\xa2-x\xb2\x9e\x9e\xfa\x81C9\xc7\xd8\xb4(\xcb\xade\xf7\x95T\x9e\x0f\xf6zV\xc8\xdc.\xb8\x0f\x8a\xe3\x9e\x1b:\xd5\xf3?\x81A\xaf\xda]\x16*\xbc\xde\x9a\xe8i\xea\xc7\xd3diw\xfan\x18\xbak1\xf36\xdb\xf2\x82$\x0e\xfc\xdc\xae\x85\xc4\xc74\xc6cJeX\xce\x95\xe5\x82\xbd\xb9\x19\xc3&\xa4Ne\x0e\xb1\xb3\xff\xf8\xe43\x8dh\x06<\xb5e\xe39Sp\xec6\xe6\xcb\x07\x83\xd5|\x05\x8d\xdcc\xd9o\x87\x83\x81\x03\xa7\xfa\xd2\xd0-ZF\x94V\x06Y\x0d\xe9\xf2\xdd\x188.\xa46\xe5\x9d\x13\xa7\xdd\xd0\xdd\x14\x8c\\\xb6v\x7fh\xb4g\xcdInQ\\\xc1\xacW2q\xd7t\xfc\xb2\x9e\x07\x94aKR%\xdc\xb4\xc9\xf3\xcbBw\x0c^7\xe5\x0cE\xb2i\x0f_P\"\xf1\x11KTsP\x89\"\xeb\x9a\x17\xc7e\xce\x88F\\\x9f>=\xc1\x9d\x11\x9002l\x9aY\x94$iW\xef\x0c]\x0b\xb3\xf7\xfe{\xf4\x81\xd9\xc44\n\x03\xe6\x12\xc3v}\nc\x88\xd7O\xe8!\xe1\xa4Q\xaf\x87J\xe3>\xc3\x99\xa6\x91\x1b\xb4\xc4qn\xf4\xc1 \\R\xcaK\xddh\x98\xd6\x88\xcb\xd4\x93\x9d\xfe=\xd1\xb0n\x9aO\xea\x9d\xa91p\xf2\xa5\xf0\x8c\xba\x05\xd9\xe7\x0c&\xd5\xa9[\x92ofC\x08X\xe3\xd05\xef\x97\x7f\xa0\xe7\xaa\xd9Gr_\x9f\xc8b\xcf\xe4\xc3\xd9\x89\x0eR;Y?\xffZ\x97\x98gO/\xe69\xd0Iy\x98\x87Y\xf3\\\xc4A\xd5\x1f3\xbd\xff\xb0;\xc7\x9e\xd9\x14.cF<\x1ao[\x96\x94\xdeGk%\xcb\x82 \xb9\xd4\xb9\xf7\xa2\\\x7f`\xf0\x06\x8f\x1a\x11\xd8C\xb3\xe7\x1cH\x82']8`!^\x9ad\x97]\x84\xaaT\\\xe3%\xe72\xef<6\xa6f\x02\x0ds\xc21X\x1f,\xd8\x84\xcdMM\xf2oq\xddj\x93l@\xe3\xdc\xc1'\xad\x92\xf9\x99H\xeb\xa2\x8dfB\xaf\x7f?\xfb\xdb\x184\xf6#\xef\xcf\xce^\xe9\xd3\x17\xce\xfc,\xffw\xa2\x86\x873mg\xcc\x1a\x90\xc8A5\xb5n\x0b\xcc[]\x9f\xb6\xf2\x14\xacs\xca\xfdX\x1f\xd1X\x9f\x98e\x1d\x1b!NOk\x04a,\x97\xd5:\xf4\xdaj\x97{lT\xd4\x9bu\xd6R6P]_\xc4\xa5\x9fLq\x86N\xd2K/lNl\x13\xf2s\x92\xffL\xfc/\xeb@\xfeQ\x00\xd90\x84H\x84&<6\x86\x7f\x088zi\x05\x92\xf8uJ\xc8o\x9dBn\xa8*\x8f\xd0\x1e\xd4\xa3\x8b\x9b\xfe\xc2\xd8vO\x9e\x80\x00\x13\xfd\x1d\xd8u\xb6K\\:\x02\xb0\x8d6c\xfc\xee\xef\x0fe\xb8\xe77\xd9Y\x19yC\xfb\xf5Z\xb4\xc9\xef\xdf\"]\xd6W\xadw{\xcf]\xb0\xaa\xc8F\x0d\xf7w\x8e\xf2\xe4xG\x947\xf7^\xbe={\xfe\xe9\xea\xc5\xdfPs\x847\xf8\xeb\xfd\xd9\xcfW\xcf?_\xfc\xf5\xea\xecS\xf5\xe0\xfc\xe3\xd9K\xfa\xe0\xea\xc5\xf3\x8b\x97\x7fm<.\x1f\\\xfc\xf5\xd3\x87\x9f\xdfkJV/J\xc5\x05\xedCLn/(}\x1b\x9f\xa5\xed\x9eg|u4\x97\x0e\xc5A\xda\xa8\xcd+\xff.J\xfc\xe9\xb8%\x83$\xd4\x89y\xb5C\x18/\xf3[z\xa59@\xca^\x91\x8e^\x9c\xafH\xf0\x8d@\xc9\xbe\xbd\xf9o\x06\x81&\xbe^\xef>\xbf\xba\xa6;\xd7j2\x01\x0d\xc4]~\x9c\xadH\xa0i92\x1f\x02\x8dO\xb5\xad\x06\xbac\xa5\xfc\xd4/\xf2\x85\xa6\xd5Y\xedT\xc2\xd2\xb8\x80\x95b\xab\xaa\x18;\xc9\xaa\x92W\xd7w\xcc-\xb37_\xb6\xaf2X\\\xc6\xaeK\xdcY\xba?3\xa5\xc0\xe5\xda\xe1C\xdaH\xed\xfb{\xb4\x0fa6?\xc4\xa1\xef*\xeasMfs\x7f\xc7\xe1\xec\x96\x0b\x16s?5E\xaf\xeaE\x98H5\x0f\xf4\xee\x88\xfb\x0d\x19\x0bO\xf7?\xd03\xb0\xfb\x03\xbd\xf0e\x7f\xb0\xdb7\xdc\xb1\x10nli\x98\xa1\x98[U\x01W\xd3\x0c0\xe6\x16W\xe2\xd6\xd7\\\x92r?c\\@\xb6s\x04\x9b\x9b9\x1cCl\x0c\xb3\x99\x1a3\\3\xafa\x92\xdb)f\xcfK'\xc3\xcbv)\"\xbd2\xd9\x0b\x98\x9f@\xa9[{\xccm\x0fO \xa9?\x9f\x13\x96\xfc\xaa\xf6p\xe1\xa3\xe5J\xfda\x86%\x8b\xbauK\xb6\xde\xdc\x0f\x07{}$c*\xd8$\x93\xd0\x13)_x\xbc\xb5u\xd4\xe4C\xb8\x94~\x12_\xb2\xfc\x83\x92\x19\xb0\xf6\xac\xd8\x1a>z\x8f\x0c\xba\x93\xd1kFS\x0d\xe4\xeaj\xea\xe7\xfe\xd5\x95\xb6_\xa9\x9d;p\n\xf1D\xc3:\xe7\x94u\x16\x8f\xc7`-\xfcla\xd1\x134\xf6\x96\xfe\xea\xd1\xe31\xb8C\xed7\xe2\xf2\x89\xf0v\x06w\xa8]\xfd\xc6\xec\x11\n\xd7\x84\xeeD \x9dlA\xde\xa5!\x85\x86.:\xc6)\xf86*\x93\x12\x9b\xe0\xba tg\x89T\xddc\x94\xb8v\xc0M\xee\xdbZ\xbd'\xde-\xb9^\xf9\xc1\x97\x8fIt7\x0b\xa3\x88\xab\xe4\xa7d\x95\x92\xa0\x99\x17\x14=\xdeW~\xbe\xc8\xb8=I\x15z\x99\x7fY\xde\x9e\xb0\xf4\xb3z\x06\x8f\xb8`\xb1dM\xda\xd8f\xb5p\x91\x9a\xf0tk\xc5>#^\xd4x\xad0\xd6\xad\xfd\x0c\xffG\xfa\xa8\x11\xc64\xfa\xd8\x9c\xad\x13\x18>R_\xab\x9a&\xd4\x07@w\xdd\xf6\x7f\xda\xa7\xe3\xc1\xfdd\xb8\xf5\xf4\xf2\x97\xe9\x8f\xce\x9f\xb7\xbb\xb6\x88\x01\xa3$\x95\xb1\x8f>\xef\xfb\xc6\x86\xfd\xff\xb3\xf7\xef}q\xe3\xc8\xe20\xfe\xff\xbe\x8a\xc2\xe7\x9c\xac=\x18\x03I&\x97\xce\xb0,\x03\x9d\x1d\xce\x06\xc8\x0f\xc8\xcc\xce\xaf\xc3\x971\xb6\xba\xdb\x1b\xb7\xddk\xab\x9b\xb0\x9b<\xaf\xfd\xf9\xa8$\xd9\xb2,\xd9\x86\xb0{.\xcf\xd7\x7f@[\xd6]\xa5RU\xa9.T9\xd3\x18\n\xc9`\xc4*{\xf2\x04\\\xd5EI\xde\xf0A\xb2\xb1\xc7M\x87\x0b\x1e]\x80xX\x80\xc0\x1f`k\x97\xff\xfa\x0f\xf4e\xcfi}\x8c\xc5\xfb\x80\x99\xd2]L\xf5\xcd\x82\xed(\x17\xfa5\x8a\xe9\xa2\xf9z\x8b+\xd8\x18\xf1\n\x86\x03P\xba\x82*\xae}\xc8\xa1\x83\x90\xd2\xb1\xa1`\x1f^Y\xc8\x9dg\xfa\xfd\x99 w\x9e\xe9\x0e\xc6\x05V}\xa6\xd3\x99\xa5\x99*M\xc5%\x81^\x0d^\x18\xb9\x85\xd7&\xa4S7\xf7\xdats\xea&Zj\x8c\xa9\xa1\x96:\xc7\xd4\x95\x96\x8a\xe1\xdd\xea%q\xb9\xe1\x91\xe2m(\xfc9!\xb7W\x08vk\x97\xbb\xe3`\x7fQ\x97\x8c\xbb\xacqw=\xae\xd5\x947\xca\x9e\x84K\xb5X\xee\xf1\xd01j\x96\xf7E\xbeHJ\"\xb3%\x01\x0f*N\\^_\xd8\xc8|A\xa8Z_\x88YV\x8d,\xbf\x90\xf0\x93\xd6\xec\x8ao\x0fw=\x08ZK\xe3=_\xa62\n|c\\9r\xcf6\xfd\xbc\xd8\x9d\x8b\"\xf4\xc1>\xa4n\xc6\xdd\xdbh\xd7~\\\x81P*)\x18/\xf7\xf1Z>\xea\xbc\x967\xac\\\x9b\xa6\xc5z\xa6\xc3\xea\xc1\xe9\xb4T\xb1\x1cVE\xb5\xca\x96j\xe2a\xd5\xe0\xfa[\xaa\x98\x0f\xab\xa2\x82\x8fFn\xa3\x8a\x81\x8235\x05\xf2AV\x0d\n\x89\xfd\xecu/\x95e\xbf|\xce5\xaeG\x88nF`\xb4%\x13}W\xb4arq\xaa\xf49F\xb4v\xbf%T\xe1\xd8\xf2\xd5\xce\x90Au\xf2\x0d;\xdc\xb9>\x1e\x82\xe8[\x97x^\xcdJ\xc8x0l\xf3f\xf0\x03$o<\x94i\x91I\xee\xd2I\xb6\xb9y\xe5]\x19\x07\xcf\x8d\xf2\x90\xd7\x16\xf4\xa8\xa6_?h\x02\xccr\xfb\xfaZ\xb45\xb4\x0d\x1a\xacIQ&\xdc\xef\x92PE\x92IA\x92\xc5\xe4\xf3\xd9\xd4u\xd6;\x81\xe3u\xe7\xd8e9\x9e<\x11\x02:s\x8eW,\xcf~\xcf\x85cF>\xd3\xcb$\xd2n\xb1z\xf4u\xfaUX\x18V\xad\xd5X~\xefDa\x9a\xde\x84\xd1'\xa7\x92\x1eb\xf8Y\xb8!\x8aZ\xcb\xef-\xaa\xc5ka\x07\xc7c(\xb4\x94\xb3\x8de$\x8e4\x06F\x92\x0f\xa2\x85\x9d\x1e+_\x8b\xc2\x97|$*\x08\xe4LZ\x8d}\xa0G}K>\xed\x1a{ie\xf5\x11\x1aT\\]\xdb\xa2X&\x1f=\x10\x89\xfat\xe9w\xc9\xe7Q\xbbjU>\x93Ooo\x9f\xffk{k\xd5N\x93OW\x87\x07\xd9b#.D\x12SRS\xee\n\xb6\x90\xb3 \xb9\xb9B\xc8\xd0\x9e\xdc \x1e$\x93ps\xf3\xaaa\x8d\x10\xf6D\xe5\xfd\xe6YQ\xcd\x03zt\xfd\xbf\x0e\xbd\x81\xd68<\x14\xe3\xd5hL=wU\x07\x89\xdf{f\xcdx\xbb\xa6\xb5\x89\xcc/\x84\x97E\x93<2\xe9;\xb2\x92\x0c\x91\xe0$\xbb\xc2s(S\xfc\xc2u\xd9\xb5Y\x84\x10y\xf5]\xa9F\xfe\xca\x83i\x91/\x00\x9d\x83\x85i\x9aG\xca\xcf\x0fY\x19NI+\xe1\"\xcdo\xb5#\x81\x91\xa3n\xe2\x16\xdc\xa7\x0c\x0d*w\x94\xa1\xe7C\xe2\xe6<~b\xc8\xdb\xea\xa7G\xf0h0x\xce4\x1f\x0c\xceA\xe34\xc8rq\"\x88\n\xcc\x94\x8biRX\x0f\xf9\x1c\xdc\xb3\x8b\xbdg\x97\xd6\xc5\x8e\xeeI\xb0j\x9b{6I\xae\x0d\xc1\x14\x98\xc2\x05\xc2>\x14\xc14\x91Z\xc1\x8c\x86\x13\xaf\xcaoT\xb07\x8c],z\xaf\xf2\xe9?a\xec\xf5\xd2\x98\x16E\x01\xbe\xff\xc2\xce\x15\x01\xeb\x81`G{\x05\x87\x83h=u#e\xee\x8b\x97\xdf{\xae3\xcd\x8bq\x18\xcd\x9dA\xa8\xa8O\xe3\xf5\xd9\xaeY\x10\xf1\xcc\xe2\x06r\xf7\xb5.)\x10\x82\x88W\xaa\x18\xd7\x1dL\x8c#R\xc3\xf8$+T\xcfL\x8d3\xdb\xbaC\xfe\x01\x9e6\\\xe5n4\x84\xban)\x9c\xc3r\x97\xb1D\xb0/\x0c\xc2\xcb\xc6\xd1\xf5T\x04\x8c\x94\x8c\x0dFO[\xa1I\x13\xe7\x0b6\xd0n\x08\x93\xc3J\x7f\xd3\x89\x1c\x11\x93KI#2\x04\x97\x92v\xebx\x9e\xcf\x0d\xe1\x1b\xa3\x82Z\x91\xc6\xe0\xc6\xb0\x19\x96%kgP\xc5\x9fI\xfbs\x1d\xa2G\x8fK\x0c%\xdb\xfen\xee\x96\xac[ld\xb5x\xf6\xab\x17\xcc\x86\xf2\x83b\xa9|\xdd\xef@u\x0di^\x15\x945\xf1@\x06\xe6\xc5I\x1b\x8b\xf3LY\x1c\x86\xceh\xa5\xec\x03#H\xc4=\x88\xf8\x8e\x16\xe8\xcd\xef\x19\xb7qS\x1a\xe5\x1fqA\xd3\xba\x0f\xca\x17\x0d\x18$ \x945 \xac\x0c\x80P\xb6\x00\x01},\x98\x16\x1d\x05\xd3\x86%G\x9bd\xc3J7A\xc1\xa0\x01\xa4\x82B\xa9\xafv*V;\xf5D\x0c\xbd\xe8~(\xa9\xc6\x12\xadp\xb9\x02I<5_\x01={f2\x18\xcb\\\x8b\xb0rwW\x17nrt\xb7\xfbB\xc7M\xdc\xa7D[R\xa9\xaa\xbd\xb8TS\x82\xd5\x87\x88\xbe\x05\x97&\xb8\x8e}\x98\xfb\xb0\xf6a\xe1\xc3\x0c\xf6`\xa9\xaa\x89\xdbhU);n}dD\xa5Y\x94w\x87\xc2\x06\xde\x11\x06\xd9Oa\x04:\xbae\xcf\x0d\x92\xe0\xcd \xb6q\xc6\xb3\x1e\xe3\x8e\x84r8i\x99v\xb0\x1a\x13wf\xd4\x19E\xba3\xe6\xa6\x072F\xef\x1b\x88\xe1\x0fp\xf3\x06n67\xcd\xd46\xab\xd1]\x08G\xacwn\xe8\xce\x91T\xbd\xb9\xf2\xf0\x8em.\xee\xd8\xee\\L\xf3P\x06\x81\xb7_\x0b\x1e\x0b\xb2\xba\x9a]4!\x1a\xcd\x7f\xcd}\\\xc3\x1eTq'\xde\xc0\x066\xb9F\x8e\xc3\xf5\xbc \xce3b\xb8\x14\x06\xb5\xb3\xb9\xbb\xf6\xe1\xce\x879\xb7\xc5\xe3w\xc4\x03\xba\xf6\xd5\x0b~<\x1f\x1f\xfc\x99\xc7j\xa5\xc1\xf9\xf8\xf2\xc3\xf9)\xec\x89\xdd\xf6\x8d\xe7\xb3\xd5'u\x11\x1c\x8d\xdf\x1e|xw \xfd\xfe\xa9ww^\xf5\xf8\x9d~)\xfcL\xbf\x12\xff_\xdf\xdb\xdf\xb4BR<\xb7\xdcm\xec\xe8\xdb<1\\\xf1\xdc\xdf\x94\xd1rH\x85Fm\x8aD1pD\xee\xc5\x0d\xb1\x18\xddd\x83\x00\xad6a&\x1f\xec\x96\xd6+W\xa8\x869O_\xeaGCU\xcchc]}\xb5-\xdc\x0e\xa7}\xd9\x7f\xdep\x05\xa7\x07\x82\xc9\x8cxp\xf8\xda \xb39FQ\xde\xe2(\x10\xa6I\x16\xa6ig\xd7:;\x0eP\xb9&\xeb\xcf\x08r\xa4Q\x9a\x97b\x00\x9d\x05\x9aF\xe6\xdcu\xc5\xe0\n\x86\x0c\x0e\xba\xe6\xde\x93\xa8\x15{\x1a@\xba\xd2\xb0\xd9)\x81d-\xb0\x11s\x03a\xdbu\x8b|V\xed\xab\x05\x90\xd8\x81\xfb\x83GM?\xae\xff\x93U\xbcNh\xe7u*\xcffA$\xa0\xf8\x80\xbaa\xa7+\n\xae\x01\xd6\xa3T\xc5\x88,\xe7\xc9\xdfV9}\xd3\xe1\x8b\x83=7\x05 ?\xd9\xb3\xf0\xd6^\x0di-\\,\x1f\xa5\xb1\xd7C\x1a\xfb\xb7\xcfO_>Fk/:\x14\x0d\xa1j-}\x94i|\xd1\xa3b\xc8\xdb\x9a}k[\x83t\xd8\xa2<\xa3I\xb6j\xdf\x0c\x81\x95\xc5\xe3|0j\xf6\xbb l2\xfcX\xaen\xf8\xb5\xb5\xbb\xf2!\xf4\xe4e>\xe3@\x19+\xbc\xa9#:s\xe5b\xaf\xca\xfa\xf7Y\xc9v\xe50\xd2C\x0c<\x92\xbaH\x83\xea2\xfa\xa67\x851\x0b\x852\xb5\xd9@\xaf\xcd\\\x96\"\xbf\xce@ [\x92\x96FId\xb8\xb5\x9d\xa2p\xa1\x99\xb6l\xa3\xabvx>\xf6\xd0|yp\x93\x17t\x04N\xc8\xfe\x1b\xd0\x1f\xcb\x92%\x0b\x0c\xe11\xce\xe2\x11\x94\xae\x13\xca\x04\x92\xc5\\\xff\xb9\x99\xd4]\xcb1%<\"H\xb3\xaeD&\xeb5\xd6\x1f\xba\xeb\xbd\xa0!\x1b\x89Zg\xc9\x92\xf4\xfax\xa2\xb1\xae\x1f\xd3U1\x02\xe7&]\xe9&\xed\"\xc3a\x98\xbdO\xc3\xbb\x118Q\x98-\xd3\xf0\xae3\xdb\xe5\xbc\xc8W\xb3y\x9d\x9b\xf2\x04K\xa1y\x98\xcd\x08\xcb\x8c?,\x99RT\x01w\"\x8c e\xce\x92/\x96y\x99T\x0b\xe6Du\x82uu\x94Bb\x1e\xd5b\x1dS\xa6\x14\xfc\xb0\x8cQ&\xa0\x96\\a\x9a\xadhF\xc9gzB\xb2\x15\x16\xc2\xb7\x05\xc9V\xb6\xecK\x9c\xf8|i\x9b\xf5\x15v{e\xe9\xa9\x12\x1ek\x04N|\x93v\xcc\xe1Q\x11\xceX\xa6\"\x9c\xd93\xf0\xd9ey\xac\xd3\xca\xb3QRT\x19)\xb1\x80\x16f\xfd\x9cP\x99\xf3sb\x1bG\x11\xce0\xc0\xa3\xc8\x99\xb2\xdf\xf6\xacg\xeb\xaa\xf5|\xdd\xd5\xb8\\w\x96\xb3c\xc1\x8f\x8a|\x89\xb9\xf2\xa5%\xc3\x8ao\xd7\n\x9ec\x91\xd0\x05\xd7\xe3\xc5\x92&\x84\xcd'\xe1\xbf,\xd9\xb2\xa8\xb8[R\x9eQ\xfe\xb6e\x8dE\xb6\xd8\x9a\xa5(r67\x84\xfd7gy\x9bG\xabr\x04\xce\x94\xfd7g9\xce\x96\x08x<\x02\x981\xcb\x9f\xc9\xddQ~\x9b\x8d\xc0\xf9D\xee\xe2\xfc\xd6\x82\xca\xfeL\xee\xde\x17\xa4,y\xbe%\xfbi\xcd\xf8a\xc9s\xad,\xab\xf0\x0e-\x93\x19\x0f2\x92f\xca\x8cs\xe9\xca|Bh\x18\xab\x05\x16\"\xc1^H\xc2\x0c\xcb\xdf\x013U\xe0\xb8\x118\x0b\xf6\xdb>\x07U\x108\x99\x95qW\x1dY\xcfp\xee1gn\x9b~\x9e\x91\xef\x03\x9e\xd3\xba\x11D\x988\x99\xd16\xbb\xef\xc3\x121\xdd\x92\xfd\xb7eY\x95<\xcb\xaa\xb4e\xe1G\x89\xfd\x1ca\x19\x92l&\xf2$\x99\x05\x19\xbd/\xf2\x99\x80\x9b\xa5\xf8i\xcex\x1eRRm\xcb\"\xa4\xa4kKr \xdb\x08\x9c\x12\x7fX2\x11\xf2 \xb7Y\x89?\xec\x99\xf80J\xfe\xcb\x96-\xe5\x91=\xab.\x962\xa5\xb3\x9f4LS\xde\x07\xfe\xcb\x92mU. b\xec\x92\xff2g\xbb$\x9f\xa9\xdc\xd1T\xfe\xb6dM\x16\xa4:\xf3h\xb2 ]\x87\xdde\xbe\x8a\xe6\x87a\x16\x116\xa5\x94\xbdE\xf8\xd6\x91\x9d\x1f0\x98\xd7\xde_\xf6U\xec\x17\xcci\xdf/\x98U\xeeX\xcc\xdb\xb1e\xf1\xda/Q\xa9>Z\xa5\xd4d_3\xcdX\xd1\xcfy\xbaZ\xd4P\xb7\xc6\xd7\xae\xf5\xfc%L(\x87\x96[\xfe\xcb\x92mNp*o\xd9\x7f\xcd\x04\xb4Y`\xcex(\x1e\x85\xa6\n\xa2w|\xe4\xc0\xa6\x90\x18\xb9\x8d8\x04^P\xa6ID\xdc\xa7^\x93\x1dX\xa3j\xdb?\xbe\xa2VE\x93\x94>'2\xd2Z\x1d\xa4\xb0}\x990 p\xad\xa9\xa2~\xf99:\x8f\xf9)\xcc\xe2\x94\\\xe6\xcbwdMRw\x1d\xcc\x1b \x9e\x0f\xeb\xa0]=\xec\xf5{ll\x8e\xa2$t\x9ca@\xcc\xbe\xae\x19\xdb{\xf2\xc4\x98\x1e\xd4\xd5\xb6\\\x01j\xb3X\xb6\x9b7\xb5.5\x88\xdc\x0dc?\xbe|\x01\xe3\x87\xa0\xaa\xdf\xed\x0e1\x97b\x81\xcb|\x80S\xd1\x86\xa4\x98\xfa\xd0\xed;O>b\x00=j}\x95\x16\xde\\D\"\x99\xcc\xaf`\x0f\x96\x9b\x9b>D\x13\xf6&\x82\xfcV\xaf\xed\xe5\xe6\x11 `\x0f\x92V\xc0\xc6#\xc20%\xc9\xa2\x84\x94\x13r\xd50f\xcb\x87\x08\xb3P\xcb\x9d\xed\x1c\xabu[\xa1\xc7\x99\\\x89X2+\x1e\xa7\xd8\x91{\x9d\xcb\x86Wht/v\xbd\x07\xfbfp\xa2E\xb8\xfcqu\xc3\xd6\x11?(\xb5\xf8\x12e\x08\xb3\x9d\xd4\xe5G\xfd7\xd5\xa8\xd4 \xaa}@%Gg'H~\\\x88\xf3\x96W\xe4TGqc\x02\xe4\xa1\x0c\x1b;\x9d}\x16\x01o\x95\xf6\xaa\xea\xeb:\xee\xd9cC\x0d\xc6\xc2\xbf\x1c\x9f\x1e\x9d\xfdr\xfd\xd3\xc1\xe9\xd1\xbb\xb1\x1c\x0bR\xd4r(x\x86p\xbe\xbb\x1e\x9d\x9b\xba\x92\xde\x16\xa3s\xef1\xbc\xb7\xa2dUEf\xc1}\x96\xf2\xd8\x17_\n\x01 \xf3\x04\x90`uI\xe6\x08\x15\xd7\xc1\x93\xd5\xecO\x92\xf5\xf5\xa8U\x81\xec\x10\x96G\x1a\x97u\xca\x87\"\x10\x1f\x85N\n\xbeck\x98\xc0\xba\x1d\x9b\xf7\xd6\xb0\xb6W>\xc4\x93\xd5\x15\xef.n\xc7\xbdVHy\xe8;.\xf4Z\xfb\x03\xd5\x80b\x867\xa8\x9f-\x85bK7\x1aK\xfd8\xfdhB\xcf\x90\x8e\x88\xc86<4\xe9\xfbpF\xfe\xf2k\xcfA\x86\xb7\x17\xfa\xad\x1e+\xdd\xe9Kz-\x9c\x86\x9a\n\xba\x0e\xa2\x19\xfcm\xd2\xe3\x92\xf7$\xaa\xd3\x06UQ\xa0k|$+W\x85\xc0`?\x87\xe9\x8a\x9c\xe4YB\xf3\x02 \xba\xdeq*\xae.\x90T\xc0K\xdcu`\x984\x97\xed\x80\x0d\xcc\xb41\xed:|\xd8$\xac\x82\x82L\x0bR\xce\x95~\x95\x96\xfb@\xd3R/\xf8\x18\x94\xd2\xe8\xebzZ\x87\xecR\x1fm?To_-\x06\x08\x83<\x904\xc5\xd4Ur\xa5\xd1P\xb4\xe6\x94k\xb4^\x17\xab\x94\x94\xd7\xd7\x0d\xdd\xf0\xeb(\x8c\xe6\x04\x13-\xd7\x8b\x85Bp\\_O\x93,\xc6\xdcv\xaa\xa5\xad\xf7W5-\xc8\x04~\x8d\xb7\xb5\xfb\x06\xa8\xd5\xb1`\xb3\xe0ds3\xbbB\x85\x01\xae*s\x0fO\x83\xbe6\x82(_,\x93\x944\x07a\xbaB'\xa2\xfb\x06\x96\x83M\xa1\xe3hT\x0cQ\xc6)\xecI\xddn\xda\x8e\x04\x84\x13\x98\xfc~\xe3\xf5\x18\x07\xa8\x95\xa2\xae\xfe?\xd0\x07q\xaby[ OY\x92\xc7\xda\xe2\xae\xf3:\x86oD\xa9\xec\xc9\xd4)p\xd1!X\x86\x13!\x07G\xf9\xe0\xbe|\xd1Z\xe5#\xcd\x82if\x88M\xdd\x1a\xad\x0d\x1cB:\xd0\xf2\xa5\xa8a\x99o\x01\xa3\x11\x1a^\x12\xb1\xbe\xea>\xa3\x19Doq\xb5\x81B\xb5\x8c\x16V\xd1\xef\xc3\xa2$\x05\xb0\xe9C\xc3\xb2i\xbeB~\x1f6A7K\xd7\xf6Eq\x15L\xa5\xf1g\xebK\x98b$c\xfc\xff\xe5\xcb\x90]\xdf\x9c\x9d\x1b2\xcd\x0bb4\xf7k\xb9\xb1ZK\xcfx\xbd\x93\x94Hm\x9c\x8eI\xca\x1fs\x92\x82r\x89l|\xee\xc3\x8e\xc9\xf5!C+F\x13R\"\xd9K\x93C\xc4if4/\x0dS:\x82\xa4\x9e\xf2\xd6\xb6\xbb\xd7\n\x84SJ\x8a\xff=\x0b\xc0o~\xff\xa7-\x02\xc34\xf7@\x13F\x04\xa0M\x08\"/\xdb$\x18T[z'\xc10q8 \xc5cM\x02\xefA\x9f\xf2\x17\xcb\xd0\x0cJ\x8b\xae` \x8c\x00e\x06\xdc\xe3cs.\x86\x1dy\xf5Y\xd9\xd2\xa0\xe7\x87\xd9\xb0j4\xba\xa4\xda%fU!\xca\xce\x1e\xc3N8g]\x87E\x98\x853R\x8c \xc9\xd6a\x9a\xc4bg0\"\xc5\xb4'\xa0\x8d\xbd\xe9\x95:*=\x84\x13\xe6\xbe\xef:\xc5I\xd9Z(}\"\xdc\xeee\xf2\xfe\x17\xcc\xe5\xeec\xcc\xe5\x8cP\xde\xbb\x01jo\xc2\xcb\xc1\x9e\xdeB\x0d\xef\x15\xe1\xe9\xb6\xfa1!W\xda\x1e\xfd\xea\xdf\xdf\xf3{\xbf\xbb\x93\xce\xbd\xbb\xe6nC\nn1hq\xd6\x8e\x16\xc0\xc12/O\xc2\xcf\xed\xaf+\xf9\xb5\xfd\xa9\xc4OIy\x9c\xbd\x0boH\xda>x\x94\x8f^M\xc7\x9b\xf2\xa5,\xcf\x87l\x11\xd2hN\xe2\x8b(_\x92\xb2\x8e\x0dj\xfc\xbc\xb5\xe5\xb7*C>\x05{\x8bf\xf5x4)\x9d\x10\xa2\x14F\\\xed\xbe\xe1\xa3\x82\x1f 4z\x9ag\xfdz\xcd\x0fN7\x07\xa1\xca\xaf\xea\xecaq\xcf\xf3 \xdb\xdclCr\x15\x82\xfb\xf53\xe1\xdb\x11\xbd\x04\xb2\x9f[[V\xd2\x99\x0b{\xcc\xbc+\xea\x80\xb5\xbe\xb4u\xabP)\xb7$EP~J\x96\x97\xf9'\x92\xd9\xc3\xef\x80\xa2\x11\x0f\xfb\xdc\xc5\x19_l\xcb\xa4\xc3\x1e\xf7\x0cb\xfd\x9a\xc1\x16\x9ft\xbe\x06+}\xfeK\xff\xe1a\x15^\xdb\xa2`r)\xba\xeb\xfc\xdd\xf1\x8cq\xa5\\%\xb6r\xa7V\xaa\xd4w\xbd\xa8=B\x15\x02\x8f\"\xc1C]\xc7a\xc3\x17\x0d\xf6j\xa3\xa9\xf5\x0f\xd3\xb8m\xc8IL\xa1H\x9d\xc30\xfb=\x85(LSX\x10:\xcfc\xc830b\xd4\x96\xcb\x8d{\xcew+&\xa20S\xd8\xf5\x02)x\xd2no\xd0a\x87\x08\xe0\xe2\xe6M%\xf5^\x1f\xa4\x96\xc5H`\x1f\xb4\xaa\\\xf4:\xaf\xd8\xb1\xdd\x7f`}\x9d1 S\x14\xd5\x15jD8\xcdW\xb8\xc0\xb6y\x1b\xc1!\x8dd\xf2\x97\xedr\xedt\x19\xae\x9c\x87]+\x10\xe1\xc8\x18\xd3^\xdd\x9e\xa1\xe6\x8eJ\xd1?\xc7\xd9\xf4\xfeun\xfcs\xbak\x83\xe4<[\x93\x82\x82p\xfbKsX\x16\xc9\"\xa1\xc9\x9ap\xefON\xdf.\xd3\xd6\xb9\xe9\x0c\xec\xfb\x9d\xfb\xfa\xe5\xd0\xadpd\xd4w\xdd'\xb8\xf0\xf4\xf5B\xd7\x1f\x0dE\xfa\xae\xe7:\xc7\xe3\xeb\xf7\xe7g\x97gz\xd0\xd1U+jA\xe3s\xd9%\xc8\x02)\xcc\x12\x8e\x99\xdc\xdd\xef_x\xae\x93L\x8bpA\xf4\x86\xe4S\xe0\x05\xa0\xcdS+\x8f\xc2\x12\xa0I\x10#7\x97ix\x07{\xe0dyF\x1c\x1f\xa3R\xecx\x0d;\x17\xee\xa4\xb0,\"\x96\xed\xaf\xe1:\xe4VE#\xc7\xe7\xa4(\x0dP\xe3/\xa3\xbf$Y\x9c\xdfV\x08\xc3\x0b\xf2%\xc9\\\x1e*\xa0H(q\x9d\x1fx\xd1?T\xc2\xec\xb7{\x1c\xbf\xfe\xf0q[|r0?\x1a\xbc\xba\xc2\x95\x14 \xde\xbe\x81bk\xeb\x8d\x07\"<\x8b\x12oe\x92L\x8a+\xc3\x8d\xa4\x00\xcc\xd2\xd5\x0e\xc4\xaecE\xa0\x1eP\xa3\xb6Zi-#\x02\x16\xa2v\xe9.Kq\x8e\xcf\x8f\x17N\x91\xa0\x03t\x1f\x9a\x9f\x85\x93\xd3I\x88n,\xd1\xfe\x04=\x9fka\xd4\xa5\xe3h7\xfb\xff^D\xfa\x17O=\xd7\xf9D\xeeJs`\xdf\xdd\xdd\xfe83\x96\x8e\x17\x82\x86w\xf1\x07w(\xf9\xe0~>5\xd9$\x17\x13\x871\x11\x05\xd9\xfaky]\xce\xc3\x82\xc4\xd7\xd7\x8el\xd4\xfc\x0d\xef\xfb\x1f8\xa2\\\x8e(\xe7#\xfa\xc7\xd7\xbe\xf1\xd8\x10\xab\xa38\xd2\xf7\x9b\xd7\x90~R\xbe\x97 |6\xf5M\x04\x99O\xf3wy\x14\xa6\x84\x9f#\xbe\xe4\x9e'\xb0u\x82~\x07\xd1\xa1\xacsVG]B\xbb\xb2\x02\xcd\"-T\x18;\\\xc34%8be\xe9F\xc2\x12\x19\x1e\x008\xde5#8773\xd8\x84\xc2\xab\x18\x13F\xc4\xf7\x9dl\xd6\xbd\xf0\xd2\xe2\xea\xf7\xd9\xffx\xb6\xf7y\x0f\xa9\xf4\xe2\xe5C{\xfb\xa8\xa4\xd2\xee\xeeK/\x98\x9a\x899\x93\x07\x17\x13\x9e\xea\x1b\x87\xf9\xbe\x07\x95a6r$V3!='5A\xeeC\"\x03\x84\xa2\x03\xb6\xf6foz\xa25\xdd\xecH\x87\xc6\xcd\x8d~\xcf\xb9\xea\xf5\x80\xf3t\xd74\x03\x18{\xbdw-\x19#b\xcf\x04\n\xcem3X(\x03_\xf2\x18B\x82\xa7!\x0d\xdf\x11\xc6XI\xa0\x13L\x8c\xa5\xf9\xf2Eu\xd4\x9e\x19$a?\x86\xb1\x8cW\x04\n9ju\xcf\xc7=)g\x95\xec]}\xaa\xcb3\x11\xd5J\xa0\xd1*\x11e\x13\xe8\x8eVc\x1d\xbf\x81uy\xfa\xbdY\xd4\xf0\xbdM\xce\xd9\x07\xbe F\xefd\xc8\xbf5W|k\xfc\x9b\x03\x9b\x90\xa1\xbf\xdb8'e\xf6{\na\x14\x91%\x85\x82\xcc\xc8\xe7\x96\xd3[\x01\x11\x02\xa9~\xdb\xa6f[\x14\xa5\xc5\xfd\x9b\xd3x\xc6\xc3\x1el\x07\xdb\x9aH\xc9x\xe2:\xdb\xc1\xb6\x03\x13r\xe5jnu\xaa\xa3\xd6(\x80\xef=\xbe\xe9\xa4\xb8\xe2\xf6\xb8\xb0am\x03z\x8et\xd3\xfcn\xdc3\xe0\x11\xc5\x8d\x8c\xb4\xfd\x90\xec=L(\xb27F\xac\xda2Q\x16\xa2\xad\xd6 \xc9M\xa0\x9f\xefx\xc1\xf4\xa1k\x9b\x07\xfc\xcc\xe7\xec\xa9|\xe1\x81\xa1\xfe\xf1\x15\x83.\xd4\x19\xfe\xa1Gtq\xae\x91\xc4!xAs@\xdd\x1d\xd4\x97'\x90d\x1c\x93\xac0f\x95 c\x0b|\x1c\x06\xd3\xd65I\x1f\xac\xb7\x97DH\x8cf\x84*\xfc0\xef\xb6\xd9\x8d\x07\x0fXz\x7fT\xdf\xa1\xcd\xb5\xfd\xddFs\x90\xdf\xc1\x1fc\xc2\x05iI\x9e\xc19\x89VE\x99\xac\x89\x94\xb8\x92\xcf\x94dq\x92\xcdZ\xc5\xc2\x15\x9d\xe7\x05\xfc\x9c\x84\xd1\x9c\x94i\xb8\x86w9-\x17a\x96\xaf\xe1\x87T\xfe|\xf5\xfa\x8f\xb3E\x98\xa4A\x94/\xfe\xd0\xaa#M\"\x92\x95\x04N\x8e/\xb5oz\xd6\xcb9\xe6\x82w\xa2\x84{r|\xe9\xf5\x949\xcc\x97wE2\x9bSp#\x0f\x9e\xee\xec>\xdbz\xba\xb3\xfb\xca\xd8\xe5\x9e\xaa\xde\x93b\x91\x94\x18\x14,)aN\nrs\x07\xb3\"\xcc(\x89}\x98\x16\x84@>\x05\x06_3\xb6L9\x84\xd9\x1d,IQ\xe6\x19\xe474L\xb2$\x9bA\x08Q\xbe\xbc\x83|\xaaW\xcf\xce\x11(\xf3)\xbd\x0d\x0b\x02a\x16CX\x96y\x94\x84\x94\xc4\x95\x1e/Zf\xc04II .\x9d\x13p.D \xc7\xc36c\x12\xa6\x90d\xed\xca \xc8\x9cp\x9b\xd0y\xbeb(\x9d\x83M\x92g\xbe\xf0s\xcdz(?\xa7\xc9\"\x11\x0d\xb2\xe28\x8b%\xd0\\\xaf{U\x12\x1f\x07\xe5\xc3\"\x8f\x93)\xfbOp\x0e\x96\xab\x9b4)\xe7>\xc4 k\xe9fE\x89\x0f%K\xc4\x05\xf4\xd9(\xb7\xf3\x02J\x92\xa6\xac\x86\x84\x94\xc6\x89\xa9\xfb\x8eE\xf0\n\x80-\x06\x15\xd3\xcbz\x05\xb7\xf3|\xd1\x1cgR\xc2tUdI9'X&\xce\xa1\xcc}\xbd\xfarU\xdd+\xb0\xd2\xd3>\x1a\x1f\x81sp\x01\xc7\x17\x8e\x0f\xbf\x1c_\xfet\xf6\xe1\x12~98??8\xbd\xfc\x15\xce\xde\xc2\xc1\xe9\xaf\xf0\xe7\xe3\xd3#\x1f\xc6\x7fy\x7f>\xbe\xb8\x80\xb3s\xbd\xe6\xe3\x93\xf7\xef\x8e\xc7G>\x1c\x9f\x1e\xbe\xfbpt|\xfa'\xf8\xf1\xc3%\x9c\x9e]\xc2\xbb\xe3\x93\xe3\xcb\xf1\x11\\\x9ea\xfb\xa2\xe6\xe3\xf1\x05\xab\xfbd|~\xf8\xd3\xc1\xe9\xe5\xc1\x8f\xc7\xef\x8e/\x7f\xf5\xe1\xed\xf1\xe5\xe9\xf8\xe2B\xaf\xff\xed\xd99\x1c\xc0\xfb\x83\xf3\xcb\xe3\xc3\x0f\xef\x0e\xce\xe1\xfd\x87\xf3\xf7g\x17c88=\x82\xd3\xb3\xd3\xe3\xd3\xb7\xe7\xc7\xa7\x7f\x1a\x9f\x8cO/\x038>\x85\xd33\x18\xff<>\xbd\x84\x8b\x9f\x0e\xde\xbd\xc3\x96\x0f>\\\xfetvn\xea\xfd\xe1\xd9\xfb_\xcf\x8f\xff\xf4\xd3%\xfct\xf6\xeeh|~\x01?\x8e\xe1\xdd\xf1\xc1\x8f\xef\xc6\xbc\xe5\xd3_\xe1\xf0\xdd\xc1\xf1\x89\x0fG\x07'\x07\x7fb}?\x87\xb3\xcb\x9f\xc6\xe7\x98M\xf4\xfd\x97\x9f\xc6,\xa957\xa7pp\n\x07\x87\x97\xc7g\xa7l\xcc\x87g\xa7\x97\xe7\x07\x87\x97>\\\x9e\x9d_V5\xfdr|1\xf6\xe1\xe0\xfc\xf8\x82\xcd\xde\xdb\xf3\xb3\x13\x1f\xd8R\x9c\xbdeY\x8eO\xdb\x9d>=\x1d\xf3J\xd9\xaa5\x17\xf7\xec\x1c\xdf?\\\x8c\xeb\x9e\x1e\x8d\x0f\xde\x1d\x9f\xfe\xe9\x82uH\xcd\xacC\xcdv\xe3]\x9e%`!\xf7\xa5\xf4\x02\x92\x8c\xc1g\xc4\xe3\xfc\x8a\xf3\xb5J9\x12\x97$\x8d\xc4s2\x1b\x7fn:\xf1S\xe2oAS\xc7\xdd\xd88\xea\x874Z\xb6q\x10R&AE\x04\xaa}\xf9\xab\x0e\xca\x00#dI\xa8\x12\xa6\xc1XU\xa5x\xc26<\x1a\xd0\x19\xbc\x92\xf7w\x95M\x89\xa7\xb2U,\xc1E%\xa4\xcbdA\x1a\xd2.k%|\n\x1b\xd5\xf0$\xa3ZVK\x17\xebCF>/I\xc4N\x992\xa1+\xe1\x83e\xd0\x8a\xe4VI\x97\x14\xd3\\_#o|}\xedT\xf7PUh\x99\x96\xb0\xab9ak\xe1\x94\xcbH%\xda\x00\xc1\x10\xe0h\x17\xad\xccd\xd4\xfa:\xd0G\x1d g\xe7\xaa\xd3\x96\xc6R\xefS\xaf%\xab\x9c\xec\x18\xae\x14\xe5M,7\x9e\xec\xce+*\xe4jz\xb5N\x1aZ$\xf3\xeb\xf3\xaa\xbc\x0f\xbb\x06\x9d=k\x14M\xc3\x04\xa0\xf9]%\xe0\xc4\xb7\xa6~\xe0\nidA\xb2~\"w\xa5\xbb24iu\xa1\x0f\nc\x84\x12\x9f\x90\xfb\xa2G\xe1I\xee\xa2gz\x1e\x19$T\xc1\xc2\xd0S\xd2\xe8\xa9\x8c\x9c\xeb\x86\x93\xb2\xba\xf54h6\xaay*\x90%f\xeb\x06\xf5Y\x0b\xa5\xea\xc9\xd0x\x8cm\x03\ntN\xd5\xdd\n\xa8\x8b\xa2\x85G\xaf\xee\x83\xd9~i\x8e\x0c\xa35\xe5\xe2\xba\x97\x8bw\xb3F\xa2\x90\xf9\x8a\xb7\x04-\xd6\xd5\x94\xb6\xf7-\xf5\xf9\xea\xf9\x90[s|E\xdd\x96\x11?\x06\x9a\x13\\\x88O\x86\xd5\xa3\x8d\xd5\xa3m8\xa3ze\xbc\xd7\xbc\xc2f:\x0f,l\xec\xa0!d%\x1bMhA1\xcd\x80\x94\xcf=\x11Oq\x10\xbf|\x1f\xa5K\x9b\x00\xbb\xbd\xf4D\x89\x92\xc4\xd6\xd6b\x94\x88\xcc\xba\x01u\xb4\xd4{qZ'W(\x11n\xe7\xcf\xb8>\xba\x1et\x9a=\xea\x8e\xa7\x86\x1do\x0d7,Q6\x9d\xe4\x96\xbdc\x0c\xb9\x94\x08\xffqO\x9e\x98\xa6\x85\xf1\xf7[\xbb\\\xc6W[\x08M\xf2+6\xbcb\x92_a<\xf7\xc3\xa4\x88ViX\\90\x92\xa9\x04\xb3\xf9\x90 \x97\x0e;\x08P\xe2\xa3!\x00\xaa)\n\xac!\xf6#\xe56ih\x9f(\xcc\xd3D\xda\xd0\xf2\x0bR\x96\xe1LV!\xdf\xf6\xea/C+*i\x18}\x12\xd5\xf0\xdf{2\xd5P\x85\x14\xc57w\x04\x03\xf0 \x06\x922\xde\x06\xe1m\xca\xe4\xad\xf8\xc2-?\x84\x1f_\xe0~\xd5\xf2\xecn\x91\xafJ\xc7\x83Mpp\xfe\x1f\xacP\xf8\xfd+\xf35\xe3\x0bc\xc8#\x96n\xf2|\xcc\xd2\xf5k\x80\x95H\x7f\xed\x99\xcc'K\xbb\xd8\xc9\xa4\x10\x8d\xda8J\x84\xbb\x1d\xae\xf0j\xd0\x9d\xe2zS\xdc\x19? \x0b\xd7{\x03\x9b\x9b\x14~\x80\xcc\xa8S,g\xa2\x1do \xa4\xec\xbc$\xd4-0\xfeW1\xd9\xbd\xb2\xe9\xed\xd6\xbf\x14\xa5'\xde\x07\x86\xac\xfdF\xb2P\x8f\xc2`\x1ceS\x15\x9em\x94f\xe2{\xe9\xf9\xe0\x9c\x84K\x9b\x10x\x90V\xbc\"Un\x85\xd0\x13\x10e\xf1\xea\xf8\xc2\"\xd2|\xd1\x12\x81\n\x88\xda\xd5E\xf4\xa5H\x7fi\x84\xb4\xd4\x0ei\xc2< \x0ei\xc8\xad\x140\x1a\x99\xd1\xca\xaaL\xfe\xce\xf1\x05\xfbaX\xf4\xd4\xb0\xe8\xb9\xdfH\xae\x16=i\xa6\xf3E\x0f\x9b\x89|\xd1W\xcdD\xbe\xe8es\xd1S\xe3\xf2\xa8C\x1e\xacN\xdb\xf0\x9b\xb2\xb5\xcb\x1d\xa7\xd0\xca\x9c\x98\xeb\xdcK\x1f$\x9b\x9b\x19\xfc\x00\xc5\x1b\x0f\xc8$\x87M\xc0\xf81\xed\xb05\x92o\xd3\xe6l08\xbdx\xaa#\x1c\xa1\xf2\xfcZ\x07\x1bcL6\xa3\xaaS\x0b\xda\xba\x84\xc4m\x18\x0c\xd5\xe0\x8a]\xec\xb9\x8a\xb1\x90,@B\\Q\x1e(\xdc\x90\x1b\xb6[E\xc7Z\x8dj\x10\xb8V\xbe\xaf\xba\x03\x1dF\x83\x9a\xf7\xf4\xea\xbe\x8b`>%\x9e\xebkcZ\x83\xf6t'\x9a\x97\x8c\xf6\x14'\x03\x16\x0eq\xd37\xaa\xb6\x08u\xc7A\xab\x99\xb3\xaf<\xe8L\x15E\x15\xd56\xb8\x87\x92\x8dU;\xbd\xd9\x9ey)\x06!\xed\x0e\x1b\xb1z\x95\x9e\xe9\xab\x015\xf2m!e\x90\xbaB\x16\x8e\x08\xffl\xd0 \xcbcry\xb7D\xd2\xc9d\xfe\x88\xf7Af:\x92;\xa4\xc7zH\xa3\x1e\x83\xe9%\xdfW8\xbb\xd5\xd4\xec\xf1\xab&\x19t^\xb0&&\xbf\xe0l\x1e\xdd\x15\xec\xc3*HJ-7\xb2\xd4\x9a\xde{{\xfeAgPv\x9f=\xf7\xaa\xcb\xd5!z7\xafwv^\xee\xbe~\xfd\xf4\xfb\xe7/\x9f\xef\xbc~\xbd\xfbP6\xc5\xe4\xbf\x1d\xe7\xf1\x0f\x8c(\xc7_\xff\x81\xbe\xf1\xb93\x02\x02?\xec)\xa2\xb0\xfek\xb1{\xf5\xa6\x1b1I\xdc\xde\xba\xd4\xed\xe9\xceC\x80\xfb\xe9K\x9d\xc0\x04\x01\xdd\xdf\x08\xc1l\x13\xe4\x8f\x00\xc1\xd5NH\x1a\x10\x8cU\xa3\xb9cDJ\x83\xc5\x9env\xd0\xca\x00\x9d\xf7\xe0 \xe5]u\xeb\x05\xf9\xdb*)H\xe3\xc5uV4I\x1d/`\x03\xb3xb\x01U\xae\xfc\xe5\x8b\xdc\x8e7 \xdeD6^du\xc6zz\x02[}u=\xfbf\\=`3v(W\x99\xaf\xd6[FT\x0c\x04\xb6?\x06_>N\xdc\xfd\xd1\xe4\xffL>^]}\xf7\xc5\x9d8\xbf\xbf\xf2\xdc\xfd\x91\xbb\xbf\xf1q\xd7\x9b\xfc\x9f\x8f\x1f\xaf\xbe|\xfc\x18x\xdf\xed\x7f\xdc\xf5>\xea\x81Yx\x00\x98\x8f\xb7\xdf\xfd{oH\x07\x8b!S\xc3\x8eI\x17\x8bV\x92t\x01\x98F\"k\xc3\xad\xb0\xc7\xc6\x1ed\x08\xd4%R1JB\x158B\xa64\xdc\x0em\xa0F .?\x8f\x05\xc2\xa3\xc8n$\xea\x9b,A\xf9\xf6H\xa4\xd3<\xf7^\x86\x0e\xf7BD\xf7\xa4\x1f\xcd\xf2\"A\x99pm\xd3\xcaE\x17\xf5\xc1\xb9\xbe&\xe5I\x1e\xafR\xe2\xe8\x1a B\x1bAU\x08AC\x9b\x05Y\xe4\xc9\xdfI|\x11.\x96)y[\xe4\x8b\x8bhN\x16\xa1\x90*\xf0\x8f\x87\xa8,\xf8\x97\x93w\xe3\xcf\x98\x8d\xb3\x10\xf8\xf3/\x8bT+\x94dSR(\xefe\xbbfq\x00\x824\x81i\xd4\xac(z(\xec\x98\x89\x1b\x0b\xdd\xcc}\xf1\xfd\x0b\xcf\xb0\x0f\xf0\xd3\x8b\xd7\x9e\x91\x97\n\xed\xeb\x83\xa0\x10\xd4\xf3(T\xf5\xdaXKFF\xd0\xddZ\xfd\xae\xfdk-|\x19\xb6+\xe1\xa2\x99\xe1qm\xa5,\xa7\x95\xc7\x10F\x8bg\xbd&\x8b0I\xef\xd1\xc2\xaa$\xc5\x1f _\x8c \xca\x17\x83\xda\x12\xfdb,(\xd9\xa2\xc9\x828\xc3[t\xe5\xf5\x95\x17\xd0\xfc\xf8\xe2L\xa8\x84\x19\xf8\x02\x83<\x05\xd1\xc4\xf0\xb6\x06\xc5u\xe3\x95^O\xd3<\xa4\x8f\\u\x92Q2{\xf4\x0e\x0bT\xd8G\xff\x83\xb2\xca*\xf6\x94\xb88\x10 \x8dW\xad\xf2\xa5\xdd~\x13\xdc\xdb\xbcLw'\xa4\xcc\x82mt\x17\x9d\x0frr%\x99\xdeyF\xff3 \xc4f4h3a\xf2AO6\xc14/\x16\xa1\x812\x02\x81\x12V\x13\xd4O\xbcv`\x13\xb8\xa9\xcc\xca\x18\xd5S\xc2%\xf6.)\xdf\xae\xb2\xc8s\x13\xc6c%\\O\xda\xf9\x90}\xca\xf2\xdb\x0c\xb5 \x85K\x1b\xec]\xd7\xd4\xa46\\Xa%\xcb\x0d\x93<2[7\x89\x7f\x00\xa4\xa3\x15U\xd6\xfa\x8ep\xf7\n\xf6\x9b\xaf\xa3\x96)\xa8|r\xd3RP\xcbR \x99\xd9\xb1\x14\xca\x97\"P\xe1\x8035V\xb3Vg\xaa9\xef\x1c[\x16\x00m\xce\xb26\x844\x93\xcf\xa2\xe3\xdb\x0c\xc9\xb0\xcf\x0bC\xc0f\xf60\x1c6\xc3;j\xf3\xf7\x1b\xfc\xbe,\xc841x\xb4b\xcfuU\x03F\xab5g\xba\xe5S\x9b\xad\x16\xe6\xef\xe3\x8aG\xb6\x1c\xe0a\xc7\x01\xceN\x90\xd4C\xa8\xfa\x97\x9c\xe2a\xdf)\xee\xb2Y\xbd\xc3K\xff,\xa7\xe1\x8cM\x8e\xc3\xcd\xa5\xdc\x1b\xd8\x87\x1bF\x96\x8f\xd0>\x16u\x01\xee|\xb8\xe6\xde\xd2\x17\x13\xf6\xdd\xf9\xbcH\xb3r\xc4\xce\x8e\x1b\x96 _\xd1_\xc1\xb5\x85\xc0Q\x0f\x05\xc48\x91\x0d\xf9\xb2\xdc\x11\x83\x07\xd8\x03\xfe\xff\xcb\x17\x98qK\x10\x9f\xa7HU\x0d\xe5\x85\xe5\xe1P\x023\x11\xa9>\xae\x88\xbf\xf5$\x93nn\x9b'\x04\x9e\x0d\xd3\x81ns\xe5\x13\xc9\x1d\xc8\xfd\xb6\xb2\xca\x85\xdf^v\"\xe4V\x9d\xa6\xd6\xf94g\xad\xcf\xef\xdd\xba|\xb6\xac\x8b\xfb\x8d\x0bs\xaf\xf6E\xaeV\xa6\x01\xe4\xb6U;\x91M\xfd\x85\x99\xdc\xee!\xa7\x0f\x199\xad\xec\x19\xb4$\x95\x1b\xf0\xc2N\x9d\xb2\xbe]\xe8q\n\x0e9\xde\xd8\xb8\x98\x1c*\x84\xf7\x97/\xb0T?\xd4$7#\xc6-\xd3\xd5h\x87\x95\xe2H\xa2\xfa){(\xde\x03\x06\xb3h\xa9\xd2\xb5l\xf2a\x03\xff\xd4R\xbc\xc3\xba\x90Jc\x9d\xad\xde&;Wv\x96E}\x0ed\xff:\x0fm\xfd9\x93\xa5\x04D\xd91\xbd|\x16\x93j\xd4\x12\x1d\x1e^UG\x16\x92M\x07l\x04\x07\xd04\xb5\x9dN\x0e\x91\xef\xc1\xff\xcdOg,\xfd\x8c%~b\x7fJ\x9c\x8b\xee\x85\xf9\xdaw\x80\xc9\xa7\xd9\xd9=hw\xbe\xe1\xf3H\x9dA\x8d\x18\x94\x03p\x1byx\xba\x05\xce\xd5\x87\xad\xfa{d\x99.\x86\x15h\x82\xc7{Tw\xe5;\x05\xd1\xa8pa\xf0^\xa2[\x8e\x04\xde\xf7L[\x17j\x94\xcc\xa4h\xa8\x0fQ7\xa9\xcd\x118\x07\xd9\x1d\x9d\xa3\x0dT\x98\xc1\x0dAc7\x0bU\x80\xe1Q\x86\x9e\x08zC\xa5\x8doeH\xee\x11\xcf\x99\x018R\xcc\xdc\xb8 \xffSv\xd4W,\x15&\xcd\xd9\xf9\xdbB\xff\xb7lQo9WV\xa2]\xb8Xa\xc6\xe1M\xcc}\xb7\xf6\xfb\xab\x0fcV\xd1X\xef\xfaW\xe3=\xc8\xd4x\x89'\x05\x8e\x11\xff\xda\x84R\x86\x0d\xb3\x86\x9c+\x97x\xc3s3\x93\x19lL\xa24\x94\x81{M~\x0b\x92,\xc6\xc0*\xceG\xaa\x85c\xd3\xaf\xe1\x00\xcda;.\xa5X\x7f\x92\xba?\xd3\xbe\x1b.-\x7f\xda\xaf&Q\xcd][t\xcf\xd5\xf0\xc8\x9aq\x87\x95V\x9ex\x15\x87\x05O[\x84\x9f\xabxrU\xc6Fb\x85\x1b\x95 hw\xc1`\xd7$\x85\"2OCl\xd8YY~?\x8ds\xd5\xd8\xa0\xbb\xe2\xc4Z\xb1\xeaz\xc5\xb0\xd2\x0dGY>d\x01\x06W\x19/\x12\xca\xdd\xdcc\x9a\x12\xac\xa3\x9ayy\xbb\xd8\xf8\xaaMz\x9dG\xac\xfeI\xf3\xfb\xaeV\xbe$z\x0e\xbb\xd4\x03\xa9&\xe5\x06\x9b*\xc6(D\x06\xa8\x10\xbe\xebL\x1e\x152X\xacJ\xca\xd0g\x08<\x1e\xf2\x9a\x88[)\x8b\x1b\x05#\\\x11\x0eo\xf5\xcc6GD\x16 \xed\xb7\x9f\xe7\xfe\x8f|X\xf9P\xfa`\xf0\xc4\xac\x83\xb9\xabm\x03\x0c!'\"\xe5\n+\x1c$\xc4\xd4l\x01~F\x05'\xb7\x9d\xce\xd5\xd2\xda\xe9\xd2\xd0\xceDo\xb1\x9e\xa1\x8b#U^\xe3\xa9\xc6oc^5\x9f|\x03\xcd\xc3F\x1f eZ\xbe.\xbf\xff\x90E\xe1j6\xa7>\xac\xb2rI\xa2d\x9a\x90\xb8\x1a\x1bv-\x00\xf7\xf7\xb0\x89\x0e\xa2\x1d\xcf\xe4.\x84\xb7\x17\x05\"j5\xa7\xde\xa3&\xdak\xcdq\x82^\xa2\xd4\x19\x98\x90+\xbb\x92\x05\xd7\xc2\xc8<\x0f\xca\xdb\x04UXt9\x97i\xca\xa2\xb0$\xb0k\x8e\xf4/\\\xb0\xa2[t3\xd5\x82>\xa4\xdb\x9f\xb0\xd2\xa7\xbd\x95\xfa\xcdu\xba\x7f\x13\xcf\xee\xd9\x84\xfa\xf6\xf4\x9e\x0d\xca\x9b\x7fc\x99UE\xd4\xf7[\xe1\xb1\xfd\x18.\x97\xe9\x9d\xe8\xe0J\xd7{\xad\x84\xf4\xb9k\n\\\x83,\xd4\xfd\x1a\xc4C/\xc5\xeb-n\xda\xe2y\x95^t\xc9C4r\xc7\xe5Pnnz\x90N\xca+\xad\x8bF\xfc\xa3j\x954\xb1L\x18\xc7J\xcc\xd0N\xe5!\xb6\xe3\xc26$oX\xfc\xce\xa4\xb2\xda\x1aYV\xa7^\x17\x96\xecAU\x0d<\x93\x91[5\x02)~cx\xd3u\x94/\x0e\xfa\xff(\\\x1a\xc8.y(\x90\xaf:8\x02\xaaU\x94\x04\x08/\xa5\x9f\xf6\xae\x074\x87$\x8b\n\xc2\x90\x0d\xfa\xb7\x08\x9c\xd6\x92J\xe4\xea\x9b\xe9/\xd9\x7fZ\x84\x11\x1e\x82\x8d\x04\x0cL\xd7u^\xe7h\xe6\x00\x1b`\x15\xb9&<\xfa\x8du5\xd9\xc3\x03\x88d\x12\x83\xee\x83[\xfd\xdec\x8c\x8dyU\xd0\x08[F\xd8J8M\xf0\xad\xeb\xd4\xbf\x13\xfb\xb7\xdaA\x9a\x0e\xe3\xad\xd6F\x07\x81\xad\xed\xd1\xb3\x156:\xc6\\\x15\xe5\x9ci\xeb\x8ax_g\xf4\xd1\x87\x98~\xe6>y\xd2\xb9/\xda]2\xb7f\x05t\x8a\x0e\xc8\x1a#\xd6\x97G8\x02\x90K\xd8\x9eh\xa3\x0d\xb7J+\x19\x8a\xe8\x8dh\xf0#cC\xaa\x0b\x0eF\x9e\xa6\xb0\xf04\x96\x93!\xb3\xa1\x03\x83\xc6\x04N\xd0\x9bjo\xbc\xb1W:\xa9\xf6\xcc\x16\xb4\xf8\x0e1\x13]\xcbh\x03\xeat\x10,\x9b\xc8\xd26\x8d\xc4\xdd\xf1\xea\xdbx\xbfE\xfc\x19(?I\xe3\xc3H\x8b\x16e\xea\xeba\xbe\xca\xba\x05\x02:\xbboS\xae\xa0\xed\x85m\xc3YRy\x94\x14\xd3`q\xa0R\x87+\x96\x16\x9c\xfd\xf8F\xe3F\xec#4\x1c\xe6\x95\xbaJ\xa3T\xbfI\x80n\x0cD5\x0f4\x99\xfbl\xe7{\xcf\x0b.hA\xc2\x85\xa0H\x82s\x12\xc6\"\x02\x1b\xbe\xffR$T\xbcg\xee\xee\xeb\xefQ\x80y\xb4Z\xa6\xe437\x80\xe3)\x97E\x98\x95\xd3\xbcX\xf0\x8aww0\xf5}X\x96\x97\xf3\"_\xcd\xe6<\xf3\x8b\xe7\x83LMz\x1d\x01\xf28_&T,\xdc9>\xdf\xf1l\xf4\x9fA\xd7\x1e481II\x12\xc6|\xa1|\x84\x07\xaa\xe0\xa7PF\x8b\xbbf\xd24\xc9\x92f\xc0E\xdb9\xbd\xd19\x07\xfa#-\x0f\x08o\xd4~\xb6\x93F\xaf\xec\xf9\x04R*\x8c\xe6\xfb\xea\xb3\x16^d\nd\xe0o\xc2\xc8 \x82P\x1f\x1a,\xb9\x93\xc5\xe8fk\x8b\xf1y\x18v\x1d+`3h-k\xbe\x07\x02\xac1\xca\x8bO$>'\x7f[\x91\x92\x96o\x0b\xf4\xe9mJ\x96\x8bDP/\xcdPlO\xd3\xdb\x92\xcfW\xee\x91\xa5\xf5\xedk\xc7\xeeV\xb7\xd3]\x9b\x0fYq\x11\xc6\x06\x0dn\x8a\xfc\xb6\xe4\xd4\xcb\xc4Y\xef\x04\xbb;\x8e\x0f\xec\xc7\xeb\xc0\xb9\xaa]\x81\x04kR\x94I^y\xf9\xf0\xe1{\x8fk\xd2\n{\xda\x04\x87w\x99\xe8KpW\xed\xd3\x0b\x1a\xa2-\xfc\xac\xdd\x9dT\xd8\xad\xbc\xd0\x8e\x954H\xb29)\x12\x81\x15^\xed\x1aX\xaa\xc8h-\x02(|\x12z\xa6#\xdc\xe0\xcf\x06\x99IL\x05\xfe\xd1=\x0e\x80\xd4uvw\x9f\xefJG6\xed,\\u\xebC\x92\xd1W(i\x025`\x8d\xd7R1e\x03\x98\xfb\xa8\xa1\xc5\x1a}iE\x0d\x0b,l\xf983bg\x10\"6\xee\x82\x8a\xa3C\x0420\x84Q\x05e\x1fSU\xf6k \xd5\x11\x99\xf0\x8b\x8e\x93\xd9\x15\xfc\xeaz\x7f\xea/\x10\x19z\xb7\x0f\xbb/`\x04\xbb/\x9e\xbdzn\x99\x85FW\xd0\xaa\xf4\xcb\x17A\x0c\xe7\xb0\x0f9\x8c\xc4\\\xa4\xf5\x87\x94Q$)\x8c \xf2\xcd\x95\xd4\xb1~\xdc\xf6w\xafF\xe6az\x18\xa62,\xa7/\x0f\x02\x12\x1f\x15a\x92\xa9\x89\x1c\xe7i)\xcdr\xfclh\xa6\xc5\xa4\xa4E~'\x12\xcd+\x82\xf1\xf99\x7fE\x82\x98Dy,\xa2\xc9\xd8N\xaaF\x1eVxZ\xb5\x86B\xb2q\x16\xe5\xa2\xb7\xa4\x95\xf6\xe5\x0b8+:}%\xe5I*\x13\x87 l\xc5\xb5\xa1rD\xab\xe4)\xef\xb2HJL\xd8\xfb\x0dn\xe5\xf7\xdcZW+\x9cg\xa8\xff\xd2\xab\xb8\x0b\xedC\xb3\xef\xc4\xe4A\xdc\xaeoU\xec\xd8\xad\x84RpY\xf4]\x16u\xe7\xe3\x81\xe0\xb0\xe3\xd1\x8d\xfd@d\x14c\xff\xa8\xe4C\xb4\xb9%\xb2\x81\x8a\xc6 \x15\x7f \xf7\x1eII\xe6+\xbf\xd9\"X\x1b\xf9\x8a\x871\xf5\x0c\xc4\x87\x99\xa6\xd2\x9f\xad-\xe5x\xf71r\x80[\x9fJn\xeeC\xe1\xf9\xca9\xe5^\x08\xa6\xdco\xad\x03\x97\x9br\xb9\xa8\x14\xa9\x12\xc1\xd8\xf3+,V\x19\xe3\x15\xdc\xdc-\x1e\\\x81\x0f\x17\x1cT\xecZ(\xe89\x8aO\x00es\xd0A\\\xf5+\xf8\xe0\xad\x01\xec\xc1\xd8\xd5YD\xfd \xf1\xcc\x90{\x07\x7f\xb7\xb6 C\xde2\xb9\xa2dX\xea-gB}\x8cfZ\xba\xd78\xcd\xfcj4gsv\xed*\xef\xf6\x91\x1b\xbfXi!\x05\x01\xa8@Y'\n\xf8kl\xfa\xba\xdb\x8d\xfciX\xd2\x1f\xbb2T`\xa6\xd4\x88\x8a\xcem$\xaa\x03\xc2\xae\xb9\x03\x92\xdf\xdai`-\x8d<\xcc\xc8-\x84\xfcf\xb11\x016\xba\xe0\xce\xbc\xad\xb9\xe6s\x930\xd8p\xe7\xfc\x12\xec\x8ew\x00\x8d\xbe\xd9\x8f\x06-\xe05\x1c\xa0\xdeY|\x9f2n\xf6V#\xfaX~N\xa6(\xe1\xa2ok\x0e\x0e7\x08\x9e\x94f}\x0c\xbe\x86\xca\xc5\x87\xc4\xcb\xe2\x8b\xed\"A|^\xeb%\xd7u\xd1\xb5\xbd\xac8\x01\x95\xc22e\xaf\xfej/\x8eg\xb4R\x98\xbf\xef\xc9/\x9e\xe7\xc3T\xb9-\x1e\xb4\xa67M\xa4\xc8E\xe9\xc6k\x03\x15\xec\x19\xfaP\xf6F(_\x05>\xc7\xcb\x03\xe5\\\xc4\xa8+r\xa6\x18\xe6\xa4\xf2$\xe4a\x87\xf9\x17\x97\xb7^\x7fSk\xd9\x1d4\x9ake4\xa6Ad\xd0\x17\xf0Q>\"\x06\xa3<\x83\x9e<\x01\xaa\x10C\xb8\x06-\xe2Hb\xe4\x98\xa59\x06,\xfc\xd5\x15\x07\x84\xc68\x16n\x8d\xbb\x07\x8d\xf3\xd6\xdawj\xa4?\x0c\xb6\x0c\xeb\xca\xb1\xb2\x86:\xcc\xb2\xa0j\xf9PD\xcfo#\xd8\xc9g\x9b\xbf\x8a\xf87b&;\xc1\x91\x8b\xcd\xcd5\xf4\x8a\x0e\x83AtZi@l\xe6\x93(\xa9e\x05\xe6\x0c\x95R\xf4\x8a\xa3\xcd\x92\xcf\x1b:\xfd\xcb\xf1\xc6\x82k=\xa1w \xbc'\xc3\x1c\xbb2\xd0'\xce\x86\x0f+\xd8\xdc3\xc9\xd3\xd8\x93\x07a\x9a\xf2\x83\xa0\xe4^\xd8\xe4\xee\xe3;\xa6\xf2\x92\xe6\x83\xe30\xd2\x82\x1f\x00Mx\xd9\xdc\xc4\xac\x1dG\n'I\x18\xb9b\x11\x0b$\xa2\xaf\x89*\xe7\xf1\xecb\x04qN`?l\xe7L\x1b\xd6\xbb(\x08)&\xee\x94\xc8T\x9c|\x10\xcdW\x99\x85\xd1\x92\x0f\xea\x0b\x05DP\xf6\xddy\xb99r\xbf\x88\x87\xc1}\xb5B\xbb\x88\x99\x1a\xdc\x1c\x8c \xad\x16-\xf5\x19\x036\xd5\xc0\xc1\x0b\xae\n\xb9\xa3\x81S\xdau\xf4\xca\x83\xbd\xa6\xb9\xf9\x1e\xb2\xd4ZW\xa9\x87\x0bhn\xa4Z\xb4\xc8H^\x86\x06fM\x07\x9d\xc2\xa7\\\x8f\xb4\xbc:\x85*\xf1\x96\xb6\x07xx\xf0\xc9\xd5\x1b o<6\x0c\xb4=\x92\xa28\x9c6\xebJk\xe1\xe9\x0c\xc2\xca>A~\xb7\x171\xb3s$e\x1e|p\xf8pZ.\x92\xf4gF\xe8\x08\x0d\xad\x84\xc8\xb5\xdbI\xa3\xfe\xa8\xb7{\xd5\xd4\x1b\xdc\xda\xa8\xcfW\x1f\x1c\x8d\xe9\xe6}\x85\xa4\xacE\xbfBYI\xcbX//\xe3nH\x18\x07\x8e\x0f\xce\xd1\xf8\xfd\xce\xce\xce3\x8b\x8f3ho\xf0*\xb9\xd7\xfd\x99\x85E\x10\xb1\xb4\x9e<\x11\xbf\x82yX\x1e\x0b~\x0bl\xa1C\xa5\x9b\xe8z\x99&\xed\xd2Wh(\x07{\x03s\xfb\x16X\xb8\xf3\x0d=\xeb\x08\xe0\xd5/O\x92Z\x90\x1bsU\xdf\x94\xd4\xfc&\xdb\xed\x9c\xe3\x92\x0e\xa6\x9a\xbc\xa4\xc2\x8f\xce\xfaN\xcb\xaf\x88\x85\xe6\xbd\xe2;y\xce5\"\x9c\xb4\xee\xe5}P\x15G\x97\xc9\x92\xf4a\x07.\x01h\x1e4uP\x90\xc30\xcbr\n\xac\"\x1f\xd8\xafB\xdcp\xea\xac\x88\xd6r[$i\xbf\xa3C\xb2\x9e\x1b\xf0\x1b\x18s\xbb\x8d\xfd\x86\xc1#7\x88\x0b\x85\x8d\\\xa5\xab\xd01:W\xa1_V\xae8\xdd\x02\x17\xb4P'4\xb6\x1fi+$\x0d\x94\xe2\xdc\xed\xaa;L\xf0**Y\x06\xd3\"_\xe8\xf1\xe3\x00DH\x05\xcb\x16D\"\x85\xebWpT\x8dT\x18\xe3\x0b\xf6\xf1U\"@FmsEX\xbc\xe1\xd1$\xd3\xcd\xdak;\x86\xac\xaa}\xe1\xf9\x90\x0b\xb9\xfb\xfe\xb0\xb3[R\x03\n\xc8\xf0\xa5\x0f\xa7\x94\x14@\xb2\xd8\x16d\xd3D\xdd(G\xb4\xc5y\x86\xd8\x8b\x19\x9e\xdc\xab\x16\xe7m\xe7\xd2A\xb9\x9e1Y-\xc9'\xb4\\$\x80B\xdc\xd4\xa4\xf2>\xf7\nN\x1az\x80'\xe1\x1dn\x15>\x11\x98\x1bQ\x0fF'+Q_\xc0\xf1\x8c\xd1\xa3\xb9,A\xb1\xa3\xc989\xd4\xbc\x8er\x0dm\x1eg\xeb0Mb\xc8\xf2l\x8bW\xbb-N\x1a\xe4s\x1c\x0f\x95\xc5\xb9/\x8e\xe6\xbc\x87\xcdy/xJ.\xf9\xd0v\x10\x10\xb9\x069\x97\x99\xf2\x00\xd2n\xde$\xc0B\xc3\xde\xaf\xa4A\xb6\xf5AU\xae\xdek|S\xd5}\x078\xd1o\xf4\x8c\xd7Axw#\x17E\x8b[\x82{Jl_\xda\xe1\xc2G>F\xf2H}\xbeVz\x18\xf6\x8a\n\xee\xb2\xa4\xda\xa0\x8c\x88\xcc\x95\x0d\xcf\x15\x03,\xce#\xcc|\x9e\x94F\x18\xf8\xce\xc2\x18\xb9@>\x95\xd8j\xd3\xaa\x1b\xc9\xeaF\x0b\xb8:8\x12m\xde\x0c\x9a\xcb \xed\xfd\xa6\xeck\xa7\xc3GR-\x18\xc4\xed\xc1\x05\x0c}p\xc3=\xb6\x19\xd8Z\xfb\xfc\xdb\xb8\xe0n`\xc3\x1d7\x02\xc3\xcd\xbb\xfaH\xb1\xc2\x08\xf4P\x84\xda\x83\x07\xce\x08\xb2\x1eY\x85\x90<\x8c \xe9\xce\xc8v:\x8fgo\x07M\x1f-\x86S)\xca1O\xc3\xc8\xc8\xe4\x1b\xf3Z\x85<\x9b{\xd0vs\x06\xb5\xa4G\x95\x94\xacj\xfc\xd1\x89\x9e\xcb.\x8c\xb5\xf2A\xa2\x8cvL\xa0& \xc3\xa0j\x10\xf1\xa4\x11\xee\x1c\x1a77\xbb\xea^eCjo\xf0l\xcdV\xda3 \x1b\x16H\x9e\xbflm\xf9\xca\xad(:\x82\xac\xef\xcb\x14\xa9\x07\xbe\x19o\xcf\xda\x02\x13\xbc=\x93$q'\x11X\x12z\xd4\xba1\xef\xa6\x95\xd0\xd6\xd2\xe2\"O\xb8\x99\xa2\xf9\xbb\xfc\x96\x14\x87a\xc9\x8d,6\xdc\x893'\x9f\x19w$\xee\xdd\xd9\xff-\xfc\x11\x96Q\x92\xb0\x1f7I\x16\x16w\xf8+,\xc9\x8b\xe7\x98+*\x9f\x8a\xff[OE\xb1\xdd\x17\xe8k\x17k\x90\xbf\x8b\xf0VQ3r l\x82\xe3xZ?P\xcf\xa8\xb2\n\xd0Ng\xe9`\xb2\xde\xf3\xe8d\xb2G]W\x83+\x83\xf2\x81I3\xd7\xca&5X\xe6[\x93\xda\x89\x91\x83&U\x9c\x83\x91\x91\xe2F\xae\xba\x97\x93\xee\x18W\xe3\x80h\xef\xdd\xe6\xe8\xbc&\x84]\xdf\x87\xcf\xc8\\\x85J\x15\xd7C\x1e\xe3\xc4\x19\xb1\x96,\x96)Y\x90\x8c\x92\xb8\x87\xb5\xa9/\xe7\xb8h\\\xfdF\xb2x`g\xaa\xbb\x8c!{\xdb\x1a\x90 \xa9\x02\xc2\x055\xe2\xeeW\x11\xbd\xdf\x8b\x99\xa8\xcd\xbf\xa1\xe9$\x83{\xa8\xaf\xee\xa8\xa5\xcc\xabP\xf1MQ\xab\xb0\xc8\xcbc\x8e\xe2p\x87\x16R6\xcb\xd8\xad\x06\xd2\x192S\x80\x07q\xad\x1f\xb4S 7\xfdJX]\xd5\xb9\xaf\xd2\xb2\x19\xbf \xcc\xb3\x88TB\xb7\x0e\xd2\x8d\xd6*G;\xbe\xa2\x9a\xd5\x16Q\x83r\xa8\x14-Fe\xe0\x16\xacT\x97\x8c\xdb\xee^\xdbJY-\xd3\xd5v\xa5\x84\xae#\x14\xd1\x81\xf6\xd8\xda\xdb\xbcl\xf4\xc7\xca\xe7Z\x9aw;\xdb\xc7\xd8\x8d\xf7\xdc\xf9\xf5%\xf7Z\xfe\xd6\xb6\xe9*S\xf3ToZ\xae:O/\xbf\xcb%%Y\xecz>\xd0V\x0c\xf8\xdf\xd5=U\x03\n~\xcf\xa0\xd4}\xb6\xf3\xcac\xc7\xe1\xf1bA\xe2$\xa4\x04\x13w\x87\x85\x0ex\x8c(\x83F\x04\xf2\xbbf\xe7\xbf\xb9\x1b\x99\xfb\xe2\xf5\x8e\xe7z\x95\xdbN\xc6-a\x98\xc8\x17\xafw\xbfa\xa8\xeb\xcam\xfc\xcb\x1ds\xf0\x84\x17\xa6\x88?\x99\xfb\xea\xa9!\x86\x97n]-\x0e\xf6f\xc6\x95)jSWx\xa0R*E\x867\x9a\xff\xc5\xb4\xa1.y\xdf\x05\\W^\x1b\"_u\xa5\x0f\xb51\xa2\x12\x9f!\xb4\x98W6\xcb\xe1\x85@\x86\xc1W\xb9A\xb0W\x9b\xbaF\x9a\x93\x05~F\xa0sI\xf4p\x11y\"\xce]\x04\x7f\xd8\x83\x1d\xc6&\xb0\xb4\x914H\x96vN[\x90\xba\xa5\x1by\xde\x1b\xe0a\xee`s\xd3p\x1d\x85z>\xaa\x94\x95rq\xc2T\x1c\x8d\x13z\xe5C\xe1N\xbdz\x8c\x1a\xbf&R\x15w\xc9\xdf\x00\xcd\x0d#\x89\xd6i$\x05\x95Z\x07\x86\x11\xb5&\xd1\x1b1\xd3\x8bHaJ\xc2\xc4nD\n\x8aT\xb8\xf1\xe1+\x97\x12tw\xaa\x06,\x967\xce#\\r\x11\xc0\xe1\x92|\xa6\xa7yL\\\xc7\xe9p\x1cn\xd0\x00QT\xaf\x06\xdc\xaf \x83\xd3\xc1\xe6{\xf2\x80\xe7\x97\xeb\xdc=\x16\xb5\x9d\xdfC\xfc_f\xfd\xfe/\xb11\xe3W\xb3D\x05\xad\xd6\x9a\xe4\x94E\x8e[;Z\"B\xf3\xa3\xca\x8f'8\xd1c\xd0\xc8\x077l\x1e\xc4!\xe5\xe1|\xf6`s3\x81\xff\x80\xa7\\\xdd\x01k\x0b\xcay2\xa5.z\xa1\x10\xe2\x17ix-(\\6\x82 \xad\x96qH\xc9\xbb\xf0\x8e\xcd\xf3\x00*\xd7@\xb2cD\x0f\x83\x80u\x19\xde\xa5y\x18w\x84\xfb\xa9;\xf06I)\xe9>\xe5{:`\x10\xc9\x0e\xeb@9\xcfo\xfb\xc9C\xc6\xa0\xb6|B\xf5\xf8>\xe7\xc1\xb4\x94\x04#UE*\x17\xb0\xba\xfby\x06\xc5\xb6\xe1\xae:\x86ke\x1b\xb3\xd9\xc8\x14\xbf\x8e=l\x16\xb2\x91\xe1.\xc5f]\x88s\x17\xcd\xc3lF\x84UW\xff\x0c\xdes\xfe\xda\xbe\xe3\x1d\xe7\x11\xa70|\xe4)\\\xe41\xb9\xd7\x0c\x9a\xb8/c\xd0\xae\xf6\x06vR\xdc\xb1\xd7|\xf7\\\xf37\xa7\xcd\x9f\xb5\x91\x81Vr\x8a\x1b\xcfi\xb3p:Z\xd1\xca\xb1\xc1:m~\xae\xc2J2;\x83+\xee\xa2\xf2\xbf\x1ea\xe2\xf5mH\xc9\x8fd\x9a\x17d\xfc\x99D+\x14l\xd2 \n3\xf1\x8a~.y\"k\x0cOR%m\x1e\x96?\xe5\xe2\x12\xa6\xfa\xfeKB\xe7'\x84\xf2Y[\x86E\xb8 \x94\x14\xe6\xd4\xe3,JW%\xab\x94P\x9ad\xb3\xb7ya.\xf6\xe3\xddqL2\x9a\xd0;\xfc\x1e\xa6i~{Y\xdc\x1d\xd3\xb3\x15\x95\x85\x16\xec\xa8\xafn\x0ddj\xa1\xbf\x96\xcb<+\x89\xb9P\xa9\x16)\x1b\x05\xf8\x1b\x0dg3\x12\x9f\xc9\xb1\x96\xcd\xa1\x97\xac\xbb\x97\xe1\xac\xca{Dh\x98\xa4\xd5\xab)\xfby\x9e\xd3c\xaet\x87r)\xca\xa3Z\x88\xf6\xe6rzo\xc2\x92\xbc\x0f\xd1\xacO\x00@Rw`\x9ad\xf1Q\x95\xc6+!\xd1\xaaH\xe8\xdd\x91\x96U\xa6\xf3i.\xf2x\x15\x89\xa6\xa2<+W\xb2\xdd\xbc9\xc2eH\xe7\xb2\xfcb\xcd\xfd!I\xe3g\xfcM>SRdaz\x94G<_\x92M\xf9^M\xca\xb3\x83\x8bg\xbc\xec\x92D\xd5\x8f\xff,9\xa8\x9c\x932O\xd7$\xbeX\xdd\xd0\x82\x88\xe6Y\x06\xedC+\xbdQS\xf5r\x91\xaf\x8a\xa8\xce|Ay_WE}\x19\x8b,\xaf!>\x82\xa2\x15\x94\xb9\xafLA\xdaQ\xa5'GyA\xd1\x0c\xf1Wt\x87\xf8+\x9aH\xafn\x13cm\xbf\x97\xd0nVa\xb0\x1c\xfd\x08\x17\xecL\x9d\\1\x96bF\xe8q\xe6N\x9c\x05\xa1\xa1\xe3\x83\x83K\xe6T.\x9e5G\xb5\xd4\xf3a\xe2T\xdb\xact\xae<\x1f\x0f\x8d\x12Eh\xffy\xe1\xb9\x93+\xcfC\xc8\xea\xb1\x87\x94\x97\xa0\xc1I\xb8\x0c\x92\xf2$\\\nE%\xec\x93\xeb`\xb0\x06\xaf\xd6\xf4\x16\xc9I&\x12\xb5\xb9A2\x81\xf7\xe4$\\z*9\xea\xab\x98\xe1g\xae\xe0\xd2\x7f\xf7a\x9a\xae\xf7Bj%)\xbf \xb1O\x94\xe7\xf1\x0e+\x93%\xa7\xea]RR\xcf\xf5\xbc\xa0 l\x1f\xb9\x8d\xaet\xdd\xc1\xc8\x08\xa4\xb1\x081A\x959\xd9\x97o\x88\xb8\xaf?/R\x87[5\xd4\x89]r\x19F\x9c\xbbj}\x9b\xe0\x04\x0el\xca\n\xf8r0\xb0j\xce\xbb\xbe\xfc\xffP\xa3\xa87\xa7\xbe<\xe6AX\x8e\xb3\xff\x1a:\x87\xf1\x84|\xf2\x83\xa4d\xffT\x81$ \xca|A\xbe\x11f+\xe0\xd4\x94\x8d\xfbf\xe4\x92\x07\x1d\xba\xf49>\xa5$\xa3,\xc9\x0c\xabz\xc7\x14\x08}\xd3\x9aH6\xd5\xb1K\xbcj\x9f\xf7\xed\xef\xd6~f\x0b\xda&\xd5\xb8\x8b\x92\xfb\"\x8f\x81\x953Tz\"n\xceZ\x1fQ\xa7\xac\xb5\xb5x\\]r+vW\xbb\xd8\n\x1d\x93`1yb]\x8bM\x811\xd2\xcd_Fp\x89\xd1\xf30j\x15\xcb\xe8,V)M\x96aA\xb7\xa7y\xb1\xd8\x8aC\x1a:u\xb6\xbcX\x1c\xb1\x14\xcc\xcapE\x12\xe1q\xb8\xfdy\xeb\xf6\xf6v\x0b\x8b\xac\x8a\x14\xaf\xd7I\xecT~\xda\x8d\x04\xb96U\x06h\x14\n*\x15\xc0\x189\x1aI\x894\xf2\xe5\x9d\x00Z\x1d\xe3\x87\xf5\xe1\xde \x83&dy/\xb0c\xc7\x8a\x9c}\xc3\xa1\xd2\xc6*\xd1\xaa(HF\xdf\x0bR\x84\xd3e'\xcdS\x19A\xc5\xfd^\xbfrY\x99y\x04~1\xf4\xd2k\xd6\xc1\xce\xff\x893#\x14\xe1{\xc5\xff\xe5%\xfe\xe7\x1e\xba\xd8\xaf|\x89D\x0f\xfb9'a,\xf6B4g?\xd0\xcb\xa6\xa3E\xd2\x88z\xc5\xde\x15Wf;\xd7\x00Z\xf7\x9fS\x1e%M\xa5VX\xd1P\x08\xcb/HJ\"\x9a\x17\x9e\x1b\xf5\x05\x82\xac\xb0\"\xee\x8b\xaaBM\x9d\x9fs\x04\x9cHz\x94\x86V\x85\x1e\x15\x9d7Q\xd3d\x8f\xd2\x0c\xab\x8e\xa3\x0cG\xf7\xfc\xef\xeb\x04\xe1\xa35\xc8k\x14\xcdf9\xdd\"qB\xf3\xc2\xd6\x01A\x9e>J\xf3\x7f-\xf3\xac\xa2>8\x18\xe9\xb3\xacm\x86%\x87$\x8dp~\x94\xce\x14\xa2\xbe\x9e\x0e\xf9Vz\xbe\x97\\R\xdbC\xecSh\xccB\xf7\x11\xc5Qr\x8b\xce\x91\xcd\xca\x80\x89\xc3\xe8\x03~M\xa8\xa6d\xdc\x8f1\xce\x05\x8f\xca\x8a \"~b\x19\x9c\x151)H\xccg%X\x90bF\x18\xc3S\xd3\xa9#\xdd\x16K[\xbbx\x08\xb3\xf4mK\xd9\xdd\xd3\xa5\xdf\x00<\xcf\xd7\x97\xbeZ\x87\xf6\xaa7\xde\xe7*\xff7\xa8c\xd3\x96\xbaC\xb3\xc6\xb5\x88#)\xb9K\xf34\xcc\xfd\xee\x0b\x16\xd1\x98n\x0f\x8a0+8\xd8\xfe\x8a\xbb\x86\xf1Wi\xaf#\xc8\xcai\xde\x9e*m\xae\x16|d\x1aG\xfd\x98\xddP\xab6\xac\\\x83\xb57\xb7\xbb\x1e\xd8\xae\xda\xaa\xa8\xb3u,h\xc3\x9f \x84%\xe5\x0c\xe6\x0e,\x06v`{\xbd\xefNv\xb6^_}\xe7}\x0c\xda\xbf\xb6\x93\x80|&\x11#p\xb8\x0b\xb7]\xd3lH\xe9\x87\xb9+\xf1\xc0\xae\x10I\xeb2\x02\xaag\x12\xee\xdaB\x18s\xe3\xb3\xbe\xc6\xf1\x0e\x9a\x07\x0e \xca\xe4\xef\x04~\x80]\xaf\xb9\xfb\x05\x17\xdbf)%\x03\xd7\x93\xad\xb9\xd6\"\n\x1d\xec\x83K\xda!\xe9H\x87\xca]\xdd\xd5\x8d\xaad\xd5Uk\x18bc\x1bV\x83\x1c\x10F\xae\\\xb3\xb6\xf0d0\x15\x97K\xd9\xf0\x9a\xb7\x8f\\W\x1f\xb6\x9a\xbd\x9a\xf2\x0bB\xe7y\xdc\xab\x9f_-\xb7U\xa6.\x9f\x84U\xc6\x18\xfb-\xc6\xd8\x9bU\x07\x80\xc3\x95\xe5J\xdat/\x8f\x87\xf0\xa8\xb9\xda\xfanh\xbc\xdf\xe8r\xc3oCR\xbc\xe1\x0bB=\x974\xd9\xb8\xbe\xe3\xe5Z\x97f>vGd\xd5}\x1d\xb9\x95\xc8\xab\x12\xb2~[O$\xd5)\xeak \x9e\x0c\xc8\xca,\xf8}\xd4n(U\x1b\x89\xfc\x968\xba\x97\xd0\xab]\xbfY)=d\xd3\xeav}\xa0W\xbe\xd031\x82xS\xb0!\x08g[\x15v\xb5\"\xd4 F\x99D\xeb\xa6\xdcoI\xe2\x1fe\x96\xd5.\xda\x85\xa1P\xcd\xb6r3\xf0(\xed\xcb\xfa\x8cK+\xee#\x1e\xa5!V\x97\x99I\xac.@\x1e\xa5\x1dQ\xdd\x006\xa5\xfbf\xc6\xdc\x99;\x1fn|\xb8\xee\xbe\xceku\xac\x11\xd8\xdd\xaa\xc5Qe\xe7\xd7\x8c\xaeSu\xd0\xe9\x9b\x02\xf9\xa0\xd7\xa3\xae\x0c2\xd3FS\x18\xda\xaf\xb5\x06j\x07o\x13:\x97\xaa6\xe5\x80\x91\x19+\xd1p>'Z\xe4\xd0\xab\xf4\xa1#W\x1f\x03b\x17|\x8ekP\x11\xd5\x9f\xaf5\xe3S\x1f\x04\xcd\xdeU\xe9\x8f\xdc;\x83E\xb2\xfe|m\x85\xb6o\xe7\xb0~\xb6\xfbpnt\xca\x80|\xe4c$%\xb4\xbd\xa5\xa1h\xae\x97#\xeeC\x1fe\x8b\xb3\xbaz\x0f\xc7\xc6\xfbg\xd9\x87\xfa\x8a\xb6\xf7\x94\x92S\x82~\x81*\xc4\\]\x02q\xe5\x01W\xd9G\x83\xee\xcf\xa05\x1a\xe5\xc6\xcc\xa0?\xd1\x89\xc6\x9a\x83\xbc\xd0\xd8\x08\xe5z\xda<\xed\xb7>\x8c\xfd\xc1\x13A\x06\xdf{\x81r\xc6+`N\xab\xf3YEl|5\xaflJ\xb7\xf2d\x0e\"\xf4\xab\xcfH\xf8]\xf4\xcc'\xf7\xa2\x10\x02\xe9\xf0\xd0\x07QZ\xfdD\x06\xce\xb2@=\xc6A1\x8c\xbf\xd32\\G\xe8\xd9\x03\xfb\x08C\xfb \xf6\xed\xff\xd5\xea2\xf4^\xcbZuC\xb9w\x94w\x8c\x1d\xfb\x11TPn\xc8\x9fz6\xee!'\xb1\x0d\x8a\x18\x83\x10F\x95i\x10\x9c\xe2x\x0e\xf3l\x9a\xccJ\xb6<\xf6\x85\xc5\xcb,\x06\xb8\x17yAM>\xd0\xe5\xc3\xfd\x10\xd7{\x92\xe7\xef\x04\xf5\x0b\x94O\xe4\x05\xfd\xf1n\xd8\x9a(e\xcd\xee\x00\xba\x02\xd4\xea\x8f\x9c\x0f\xa3\xdej!t\x1fV\xd8?R\x94\xca\x1cL\nK\x14}P\xe9\xeb}\x90]\xe8\xb0\x11\xff\xea5)\xa6>\x0f\x0c\xf2\x9e\xdd\xd8g\xe9\x83\xbc\xee\xb3\xbe\x1a\x93\xbc'^z\x02{8t\x8aU\xb8\x05^\xd0\xf7\x0eV\xc1\xdb\xdd[\xbb>\x96F\xdc\xd9[\xd6\x01z\xa0\x8a\x0e\xca\x11$\xf7F\x04\x86\x9d\xd9\xdc\x82\xbe\xa6\x07e><\x86\xca\x9ck\x192\xaf\xf0~\x17\x1a\x9f\xf0LST\xb4\x1e\xa93\xbc\xbe>&\xa1\xf1~\x80]ik\x90=J\x8f\xb4j\xef\xd5\xb13\x8e#\x9b\xban\xf7\xe0O\x0e\x95\x1b_\x96U\xb2\xc9&\xa8P\xb4\xeb\xee\xd1\xc2\xa7\xc1-\x98\xb4\xfa\xee\xd1\xd0\xc1\xe0\x86\x0c:\x85U;\x1d\x0dh\xc6)M\xbd\x10\xa3\xfa\xe2\x90\xdeK\x04v\xef\xbbw\xa3JW\xf3|5\xa3\x92\xfcA\x8a \x03\x9b\xb4\xcaW\x8a\x81\x9c\xb0\x14E\xe7\xb89\xb2\x06\x9d,\x15\x9c2y\xc9\xe2\xd8\xc6\x08\xe2\xa4\x1eX\x0b\xa6\xcd\xc3r\xce\xc5\xac\xf8\xf30\x8f\x89q@\xa0\xe3y\xc3\xa5\x9aXq\x93\x11\xca\x03Y\x85JQI\xed\xb6Y\xf7NMi\xb7o^\xb7N,\xf3\x9ec\x99\x1ee^\x1d\xda-\xc2y\xe9)+\xab\x16\xc2@\x13\xa9c\x7f8\x98^'\xb2\xa3\x0c\xab\xe6\x0cf7\xf4{\x1f\xe3.\xbe\xffh\xfe\x19\xdb\xf7\x1b\x01\xa5\xb0\x80\xc7P\x90\xb0\xae\xca\x99\x98\x93\xdc0\x95&\xe5\xf0oD\x83\xbc\xd0\xd5c\xa1\xb8\x07T\x97\xd4\x9ah]\xba\xa1\x0d\x04\xd7y1\xa5N\xa4<\xac\x0c\xb8\x02p/Z\xd7\xc1\x8e}\xd0\xf7\x17\xf2i\xcd\x0e'\xfa>W\xf5\x93k\x1d\xff\x07Hj$\xdanH|\x8d:r\x06\x17<\xdc\xcc\xb1V\x1a\xc5\xf8\xcf\xce\xb6\x08K9\xd9Q\x02\x12\xaa\x11\xa2do\xe0\xd2\xde\x9f\xff\x81*\xa9lRz\x95R\x0d\xb3p\xf2\xaf\xd155\\\xa3\xa0\x99\xb2\xf4\xf1\xd2\xb9\xbd\x1f\x88\xd0\x85\xccU(y^y\x9d\xf7A\xb9T7\xe5#\xaa\xe5\xb5;\xbd\x97@x\xff\x83A\xac\x1a\xaa\xa0x\xa7\xd4\\\x8a\xdf\xb5\x7f\xb11\x1e7\xe5p\x95\x05M\x1f\nl\xcc\x8fP\xaa\x0b\x16!\x8d\xe6\xee\xf6\xffq'\xe1\xd6\xdf\xaf\xd8\x9f\x9d\xad\xd7\x9b\x1f\xb7\x82\xab\xef\xbc\xd1\xb6E\x0b\x97\xbb\xa0HJ\x19\x90\x80\xb1\xed\x1c\x92\xb3V\xd0\xc1\xd6)\xcb/P$\x8a\x14\x92\xef\xd6G\xe7Z\xac\x0f\x1f\x9e\xc33\xe6\x9ar^\xc3\xf6\xc1`h\xd47%\xa2s\x13gN\xe9\x12\xd54)]\x96\x8a\xb7\xac\xe3\xaa$\xf7\x90U\xb7\xdce\xf4\xd4)\x0d\xe9\xdd,zd\x8a\xc7\xa1S\xecF\x19-\x8d\x07\xdb\xe6Rp/z\xdf,M\x96\x03\x02\xcfJqj\xe5\xfa\xd1\xa0\x0b\x93\xa9\xeb\xd8\xc65\x7fm\xf7\xc4\x8c\xd6\xf61\xde#W\xf3> \x97\xda\xb6\xf9\xaf\xb7\x8d#\x8a5\x9c\xf8\xddp8\x98\xcf\xd4\xd7\x92p3\xf3\xa6W\xc2\x92\xd0\xd6+\xe7\xc7\xb9E\x12J\x80\xc7\x8b%\xbdC\xfb\x9f\x8az\xc6\xaf\x12N\xf1\x93\xb4\xa8\x92\x89\x9a\x16\xe0a\x18\xcd\xd5:M\x86S\x82O7\x7f\xc2\xb4\x0bi\x9c\xb5\x0c\x8b\x92\\\xe6\x95U\xd5\xc5\xf8\xf2\xfa\xe2\xf0\xa7\xf1I\xc3\x9c\xfa||q\xf6\xee\xe7\xf1\xd1\xf5\xc5\x87\x1f/\xcf\xc7\xc6oj\xda\xd9\xfb\xf1\xf9\xc1\xe5\xf1\xd9\xe9\xf5\xc9\xf8\xf2\xe0\xfa\xe7\x83w\x1fx\x99\xc3w\xe3\x83s\xf6~\x8c\xf9\xde\x1f\x9c\x1f\x9c\\(_\xce\xc7\xff\xbf\x0f\xe3\x8b\xcbF\xca\xc5\xfb\xb3\xd3\x0b^\xfc\xdd\xd9\x9f\x1aYXoO>\\\x1e\\\x8e\x8fZ\xe9\xedw\xa5\"S\x0fD\xdf\xc7'\xef/\x7f\xe5\xe9\xd7\xc7\xa7\x87\xef>\\\x1c\x9f\x9d\xaa\x19\xf0\x93\x9a\xf0\x9f\x17\xcd\x0c\x1f\xce\xdf\xa9\xaf\x17\xef\xc7\x876\x034\xd8\x83\x1b7s\x9f~\xaf\x93\x9d\xb9\xf8\xf2\xea\xb9\xfe%\x91e\x9e\xe9_B\xf1\xe5\xf9S\xfd\xcbJ\x96\xd9i\x15*\xc5\xa7g\xcf^\xe9\x9f\xd2\xea\xd3k\xfdS$\x9b\xfa\xdek\xd0\x8f\x1c&/\xfaT?%\xb6z\xc7\xe8\x8e\x82,\xd30\"\xee\xf6G\xba=\xf3\xc1\x01\xd0\xf1\x96\xcdkc\xad/\xd6Fsh/q\xdd>\x1f+3g\x8d\xaej\x9e\x1c\xcd\xbd\xf5-\xb6\xf9\xa7\x1d]\x18\xe0\x1c\xe0\x03j\xe9?\xb8\xf5\xdbok\x9d\xa1\x85\xde\xc5\xec\xe9\xc2\xf8\xa1]\xe0\x06\xf6\x88\x13\xcd\xbc\xb8! bO_>w\xf4\xc5\xcc\xa9q\x95?\x8b\x86\x9e8P,\xf7?x\xb4\x9f\x86\x0b2\x02K\xf0\xa8%?\n\xac*\x85I\xf9\x97E\xaa[\xfd\x00\x0crL\x80\xf3\xd6)\x89\xb4\x1b\x9b\xfe\x8b\xa6\x0f\x87o\x9d\x1c1\xb9\xddSS\xdcsjR\x12\x16?\xeb\xa7\xed\x83A\xfb\xf8A\xf3q\"\x14D\xdbj\x1c\x03\x96U\x9av\xa1\x91a\x1f)\xdb\xd3\xfd\xbf>\xa8\xfb}\xbb\xc1\xb2\x9c\x9f\xc8\xdd\x08tS\xbd\x87\xcc\x80\xb4\x1d\xfb\x1f:\x03\x1a\x1f{\xcf\x19`\xf0\xab\x10\x96\xdf2\xf6\xcb\xc7\x1d\xbbT{\xbe\x87\x0f\x10eD\x92r\xfe\x96\x01\x9d\xfc\xb7\x18PI\xe8}\xd9[\xdb\x80\x8e\xee= \xce\x9ew \\6^\x0bx\xca\xf1\x1ad\xc3\xb6\xf16\x89\xd9iEd\xbe4\xd9\xa5e\xaen\xd1\x19W\x05Z\xf4\xe5\\|\xda}\xd9\xfa\xb4\x96Ti\x9b\xcc]\x88O/_\xb4\xc8\xdcY\xf5\xa9Ej\xdfI\xc3R\x13\x93{c=\x14dh\x1e\xd51\x04\xe9v\x0ca%w\x1a\xf3xm`\x1e\xd0\x14Q\xfa\x9fA;\xc8\xe6\x18n\xdb\xfcG\xa3\xc8\xaaH\xb5\x12c\x03\x07\xd3(\xc2\x95\xa8\x1be>\x9b\xd8\xa0F!<\xd2\xb5R\x83\xb8\xabF-\x84\xf1\xc9\xbc\xae\xfa\xfaF\xab\xf5\xd0\xc2\xc7\xf1\x8a$\xf3l\xec\xd0'\x13O\xc8\xcb\x95\x84^\xcb\x8bt\xad\xd4\x81\x81\xb3T\x0b!\n\xd3\xca\x9cup\xa9uYq\xe9m\xa9\xe3\xbd\x81\xf3\xe5e\xd3|f)ca\xa0y1D\xb9\xb6Q\x9e\x18\x99\xf1fAS\x8b\xc7\x9d\xec\xbdZ\xbesi\xfe:@\x8a\xd0\x00\x95J\xccz\xbd 4\x14\x87j\xb3\xceS\x8b\xb4\xa2QOm\xde\xda({\xde#\x051\xd6q]r\x81\x8bV\xd7Q\x05\x0c\x95\x80\xc5a\xcb/e\xaa\x8d\xcc\xef\x86\xaa\xb8\xb9;>\xba\xa8\x16R\xc5J\xdc\xa6\x9bH\xab\\zS\xe8\xd3K\xfeV\x19:\xad9\xb8\xc5\xe7\x01\xe6,\xcdGLQe\x937J\x96\x8c\xdc\x99\x10)\x8a\xce\xea\xf8\x95\x9c027g \x85{R\x83\x1c\xd4\x1a\x16\x10\xc3@\xc0\x97/\x90\xb8\x18\xb0\n\xc1\xb6C\x87\xabD\x0bqF\xda\xb1i-\xda$\x1d{\xbez\"h\x91\\\xaa\xa0\x0c\xa7\xe4]\x1e\xc6\xc6h]j4=\xf3T\xf2\xa5a\xf4t\x9e\x8aX\xfb\xe8\xf1-\x0f2r\xcbx\xf6qq\x9fN\x9b\xa7\x8f=)Y\x93t\x042\xa0\x935\xdf\x82\x94e8c\xc4GP\x90\xb0\xcc;\xcc\xe4\xd2$\xc3|\x8b\xb0\xf8\xc4OQ\xf6+`\xc9\xa8\xdb[\xbfmb\xe4 .:\xb3\xcck{\xf2l[\x05\x03\x1d)\xde6\xf7\xc0Uba\x85\xb0\x0f\xce*\xe3\"et\xf2\xc1\xb6VTo\xad\xd0\xe3&\xe0M\xd1\x88\x1bz\xec\xd0\x1fH#}0\xc4\x95\xfb[\xa5\xbf\xa5Hf; a0\xecM\xab\x86d\xe5\x85\xa8\x7f\x7fBus6`\x8f\x82t\x83\xde\xbbO\xa1\xf2\xff2\xed\x00\x8a\x15\xecA\x18L \x8d\xe6\xf6L%f\x12S\xd5\x01`\x98\xed\xe0\xc2\xc0\xe3\xc8'\xaaD\xb2\xb8\xfa)\xec\xc3?\xbe\xc2\x08R{\x91\xa9\xbcT\x14:\xc2f\xb5\xa0\x0fh, 7\xe6mXd\xdc\x91\x84\x98\xa2\xc6:7\xc2tB\x99d\x11\x81\xf5\xb3`w'\xd8\x810\x8b\xe16IS\xb8!P\x90E\xbe&1$\x19\xac\x9f\x07;\xc1\xce\x1bX\x95\x04,r~\x11\xd0s\xc3\xf1|\x0ep\xb6XW\x0c4\x18i>\xedRv\x8e10\xd9\"\x8fI*/ZN\xc2\xa8\xe8\x88*5\xc7\x12\xd5\xcdVO\xee5\xe6\x16C9\xce()\"\xb2\xa4y\x87R\xf5B\x94\xe0\x04\x8cR\xc42\xcaz\x95\xeb8?y\xe5i\xc1\xad\x9dG\xf0\xfb\xf6\xca%x\x1e\xac\x8a\xd4\xaa\xfe\xc5&\x8fq\x15\x11\x83\x88wIFNW\x8b\x1bR\xbc\xcd\x0b\xb4\xcf\xdb\xb7}h\x86\xdd0\x84\xc2\x90\xcf]\xd5\xcd\x0bZ\xd8\\w\xcb\x1b\xb7\x0eT\x8f[\xca\xe8cH>\xac\x8dN3\xe4\x9b\xb0$Gyd\xe5\x1dA\xb8\x00mB\xc8\x08b{\xf6&x\x8c\xa0c\xd3\xb7ac\x04\xeb\xae\xec-\xc0\x18\xc1\xc2\x98\xfd\xab\x17\xd09\xc9\x06\xe8WA\xe3\x8e\x95M\x98\xbd\x03\xec\xe1\xf6\xad\xfc\x1a\xd6\xae*\x9eL\xc1Mz \x0c\xa8$\x02\x0e\xba\xf3\xcf\xcc$\x06\x082\xa3y\xfb\x9f\xe1\x1do\xa6(\xd6t\x0d\x11T\xe5\xbc\x81\xda\x9a\xeac%K\x08?\xcf\xd9\xa4LWi*\xb6\xc8\xcc\xbd\xf3\x95\x14i\x15\xc0\xd2\x96\xdc\xc8\xb5\x91\xbd~ \xfe\x9a'\x99\xeb\x04\x8eZ\x04)\x15FU\xcb\xd8\x93$\xa0\xdcE\x9b\x9c7\x1f\xb5s\x84\x8b iu\xccr\x9a\xef\x93\x89\x0f\x8e kz\xa3?\xcb\xa7\x11\xcf\xaa#\x10\xa8\xfa\x08\xb9! Dc\xbd\x85\x86X\x01\xda\xa1\x8e= #\x13/qV\xc6E\xf1#j\x99\xe4\xdf`9XhWfvS\xaaVr\xcb\xfc`r\xa5\x1dGo\x85>\xda\xa2&\xc6\xd8kZ\xbf\x96\x15Y\xcdh\xc7\nh\x81X\x03\xdfQ5b\xa8\x0f!\x0f\x80\xe2C\xec\xc3\xdc\x87\xb5\x0f\x0b\x1f*k\xdf[\x1f\xc6V\x85\xa1\xba\xed\xdbb\xd0\x86\xc1p\x0bo\xdexP\xde&\x9c\xca\x0f\x96\x05F\xfc\xe2\xc1\xd0\xbb6Z\x14\x96\x04vF\xddk;\xe5\xe7\xd7\xdf\x82\xf2\xae\xa4d1d\xe3\x12\x19\x8c\xf1y7\xdc\xb0\xe7\xa6 a;\x92\x9a\xfa\xd8\xc1\x05lH\xc2\x89\xc9\x8d\x00\x1e\xe9\x05`\x04q\x9e\xfd\x9e\xc2<\\\x13\x08\x81\x0f\x06h.\x0c`\x08\xe4\x99\x0f\xe1M^\xd0$\x9b\x05\xdcaQxS\xac\x96h\xe2\xc1\xda\xb0\x05\x07\x069\x93\xcf\xfbg2\xd3yQ\xc1\xc6\x92\xa2\xa8)d\xc1\xb1N3\x1fi\xe2\xbc\xa2\xf2\xf8P8\xef\x97#E\xaaS\x9e\xa1\xa4\xfc\xade\xee9\x04\x94\xd6\"R\xe8`\xacK\x0dw\xf3\xb6\x87U\x1eb\xe8\xd4\x14\x91\xf0\x12\x91\xf0\xa2\x1fh\xe1\x1bp\xb0\xe9\xf9\x16\xbclz\x86\xe0j\xd3S)\x14\x8au{\xeaw\x99\x1b\x9a\x1el\xf9\xe9\x83[\x0e9\x91K2\xea\x0b\xb6\xbc \xe5*\xa5'\xe1\xd2\x17\xbc5\x83\xf2_\x12:?\xe4\x0e=%\xcaV\xa0\xed\xa5\x0f\x89\x9b\xe2\xf9z\xbfi\x93O\xc5tL9\x1f6\x8c\x96\xd2\x1f\x13[r\xf7\xb0\xaat\x96\xe5\xe6a\xd5\x98\xd8\x19\x83\xa2\xd2\x90\xc7\xc8\xea\xdc\xde\xbb\xaa>bQ\x7f\x10\xbc^>\x18\xbc\"\x05\xbc\x96\x88x9\x9f\xc4\x8f\xba\x88sWP\x04a\x9a\xe2 R\xba\x1e\xf7f\x86\x8c\xcc\x10n\xc9\xf6\x0c\xe4\xa2lO\x9b\xbbZ\"w\xb5\xd4\xcc\x16\\.\xa1\xb8?\xfbdz*l`b\xa0\xe6\xee\xfa\x7f\x1b\x03ez\x1e\xc2T\x99\x9e{3Z\xa6\xa7\x9f\xf92=\xa8Pm`\xba\x16\xd2\xbd\xf6\xac>WW\x885\xe3\xf6\x87\xb4\xfa\xd0\xa2\x83\x1e:\xbd\x15f\xef\x94\x10u=\x96\xa3`\x04\xf6\x08\xf0\xb6\xe7A\x88h\xf7\xfb\xfba\",\xe4\x90,v\xeeW\x0e\xd4\xcdX\xd2|i\xf1\x91cz\xba\xa9g\xf9|\xc5\xe8\xf1&G\xb6\xc6\xdc6\xc9\xa4\xfa\xb4\xae\xf0z|)\xa8O5Xs\xd0\xcf\xde:\xba\x07\xfd\x95Q\xc3\xab\x8an\x13\xb8d\x00bW \xd6\x9d\x9a\x9c\x0d\xbb\x93\xab\xcac\xcfR\x9a\xd0\x074\xff\xcf\x8b!D\x84\x15\x9c\xa7\x8a\xc8X\xd4\xd6=\xc0\xae\xf5\xe1\x90\xdb\xc3~\x8e\x95\x83\x92{-\xafxz\x1f\xaf\x8dx0\x10I&>\xed\x06\x07\xe4\xf1\xfaz\xf4\xba\xbbG5c\xf1\x1aO\x87\x1d\xec!^V\xba\xbb\xbb\x9e\xafK\xfe\x02j\xbb{\x80\x8aL\xed\xa1Sc\xb3\xa1\x83\xcb\xc6>\xae \xd3\xdef\x9e\xd9\x9b\x19\x8a\x11\x86\xec\xfe6\xd0\xab\xbb\xda\x87\x89\xb1\xd4\x841j\xbb\xaf\xafZ\x1f\xaf\xda\x0e2\xe0\xd9\xf7\x0d\x9d{\xab\xb5\xc77^\xec\xffM\xc6\xc1\xf4+\xa8\x03\x0cC\xfaV\xf7LX\xbd}m\xdb\x02\xdc\xd3\x11x\x8fJ\xdcy{\xff~\x8b\x8e\x9fT\xd8l\xaf\x99m\x80\xfe\x10\xdb\x1c+o\xfdO\x1a\xdd\xc4\xe2\xc0F\x0cO\xc5\x83\xf7\x1bi\xcb0\xe9[\xd6\xee\xf0A\xa3\xab\xb4\xa5\xcdC\xe4.\xc1\xef\xbd\x84]\xf6X\xdf\xae'\x7f\xf1\xcf\x18\xe9#\x98\x13\xf0\xb058\xea\x9f\x85\xe9\xc2\xf0iS\xb7v\xd3\xbc\xed\xc1j\xae\x03&\xa5_=\xd7\xfc\xb9`'\xb6\xc9\xcd\x81e\xc9>uAK\xc3\xb8\xef\xbf\xe7h\xffv\xaf\xd1\x1e\xf4\x8c\xb6e\xe0\xf8\xbfa\xd0g]\x83n\x18y\xf6\x1e\x9c\x1d\xe34\x8c\x857\xff\xbe\xab\xf9\x96\xd9io\x17\x86*\xe5\xd9Tn\x8aa*{\xf9P\x95\xbd\x95&\xeb6\xe7\x12\xf1\x06\xc3\xf2YOu)\x12\x96\x0c<\x18\xca3\xe7\xe1r$qW`\xcc1\xc5\x1c\x95\x8e\xa8\x05m\xc2\x1e\xacl\x9c\xc1\xfd\xb4S\xac\x9a)\xe6\xec3\xbc0\xe0\xacD\x9b|M\xa6\xe0\xce\xe0\xc9\x13\x98)\xa1\xc7\xf4w)y\xd2\x93\x85{\xd2~\xf1\x93\xa4iY\x0d\x1bBK\x86{\xc7\xaa\xcf\x89\xf6\x1e3\x98\xa5w\xc6\x0b\xcf;\x1d\x07\xb9\x93\xd4\x87\xe8\x8am\x84\x8c\xad6\xd2X^\x17\x9bJ\xd4)\xd9k\xbe~\xf9b\x8d\x1f\x00\xca\xd6P\xcbLx\xc3\x1d\x1e\x0c\xdd\x0dt\x0e\x8e\xa1\xfcv\x84\x8b\xa52\xf9;w\xda\xe1\x9a\xea\x82=p\x0c\xbe\x97\xc0\xcc#\xa0H\x07\x83\xc8}\xa6\x1f\xaa\xc8Lq-\xfa\x91\xcaH\x01\xcd/\xd0\x12\x96\xb1\xcf\x02<*\x00?\x8eQ\xc8\xa7\xbe\xefi\xdfG\xbcP\xca\xfeD\xa2\xf3\xcd\xfcY\x90/\x8fcw\xc6\xefc<\xd4)\xe5d\x96k]\x136\xa97\xb0\x07)l\x823r`\x13\"\xf3\\2v\xb6\xe0\xb1>\xca\xa0D\x1c@\xe2\x0bLro\x90ko%w\xe8_]\x8bjX\xbe\x9f\xc3\" oR\xd2\xa5\n\x05\x18,\x9d\xe5\x1eU=\xe9\x96\x08\xb0\xa5,\x97aDFpc\xcd\xf8\xb5_\xbap\xfb\x08=\xedo\xbf{\xce\xabv+\xf7>\x15t]{\x12\x91\xec\xc35\x8c\xe0\xd6G5^=R\x1d\x0e\xa2\x9d\xec\"\xa0\xf0\"\xad\xa8u\xa2L+\x9d\x17B\x87!\xdfm\x7f\xe7\xd8\x17y\xac\xb6\xfac\x1es\x9c\xc4\x8b\x9bK\xb1\xc1\xdd\x05I\xf9\x9f\x17g\xa7\\0\xed\xb9cT\x8cW\xab\x81=`\x19\xb86\xbc;\xf6F0f\xfba\x8csi\xc8<\x16\x93\x0c\xa3\xf6\xa7\xf6\x86n\xa5\xb0\xa1|\x163\xaf\xb8\x01\xf9\x07z\xe6m\x8f\xe33\xee\xc4\x9bU\x92J2\xcc\xfd\xec\xf9P(\xc4\xa8\xab\x1c\x90\xf5A\x08\x9f\x0d\xb5\x11\xc3\x11\xa6R\x19\xbd\xfeq\xd7\x0d!\xe0\x84\xea*:\xea\x93\x9bG\x99u\xab0\x16m\xc2\xd32\xc0\xbc\xe1\x9bD>_U\xf8k\x0e\xd3p\x97\xcc\xc6u\x01{p\x14R\x12d\xf9mG\xa8\x9bLRg.\xd1\xd5\x05\xad\xd3F\x83x\xc5Qj\xa3\x0d\xd8\x82\x8bj\x0dyO-c4\xa8O}\xf5\x84\xa0\xad\xbfyuJ{\x1a\xea8c\xb9\xf6F\xd7}\x0b)\n.^\x98\xab~m\xccg\x9ei@\x8d$\x0b\xafI\xdan{\xf4aK\xf5\x04\x83\xa3\xaf\x1d\xab\xa3\xaf\x9d\xa6\xa3\xaf\x9d+T\xe37P\xef\x15%\xda\xfe\x96uR\xa0\x89\xd8\x07\xb9b\x9e\xc3}\xfeP\x0c1\xc9\xcb9Wf\x1fi\xdd\xa4\x9bT\xd2$\xc14\xebR\x9a\x0f+}\xd5\x01\xf4;\xe9\xe7\x07\xca\xea\xf6\xdf\x16\xa5\xce\xed>\x0c\xb9\xfa\x80\xe6\x1d\x8b_K\xd8\xa9\xfc\xb0\x1d_W8x\xednl\x8a\xf7\xc9\xed\x03\xcb\xce\x08D\xa6\xa3\xca\x9c\x9d\xd1J\xdb\x9f\x17\xe9v\x12P\x86\xac\xa6\x96N\xccq\x00\x15\x81\xd8\xe8\xbe\x0f\xb1\xfd\xec\x16\x80\xb0\xd2\xb8C\xd4},\x9a\xb85\xb1md\xa1\xfcm\xd1\xbf\xe7\x8a\xdf\x96\xa5\x96\xd8\xa2\xdfb\xd8V^\x92\xc4V\xednS,\xdc\xa9\xa5\xab\xc2\xb4\xd9b\x9fa\x0c\x97\xbb4\xa0\x1c+\xce\xc1_=\xce\xa8H@>/\xf3\x02\xfd>7\xe7\xbb\xb2\xf1\xcd\xdc\x97\xcf\x9ej\x90P\xdb\x087\xbdO\x19\x9b\xb4\xb57@,\x89\x91]\\n\x00\x12f\x11\xbaUD\nKA\x80\xe8\x11\xb4\x80$\x03\xe2\x01\xde\xea\x03\x9b,T\xb4p\xd1\x1f\xeb\x08\x92,\xca\x8b\x82D\x14\x92l\x9ds\x07x\x1b\x16W\x8e\xe4~3hv\xe7U\xd9(\xb9\xaf\x9f+\xcdT\xc3\x0f\xa6CD\"\x19\xb9\x1d\x805Y\x8f\xda{\x8d\xd15\xc1\xb2\xc8\x17 \x8a4YUdX\x9096\xe9\xca\xfcRm\xbe\xb3\xf6,;?\x861\xbc\x17mEyV\xd2b\xc50\xb3M\x97\x11O \x1f\x0f\x1b\x83\xbc\xd6\xf3y\xe7\xc5\x05*\xcb\x84\xbe\xe5D\"\xa3~1M\x0b.\xf3U\xb5;\x1c\xb4t\xf5\"}\xbfcZ\xa4\x01bB\xd4\xb0\xe3GW\x921\xd8D~\x9aLrv\x16\xe3\xbf=\xa0\xec\xdf\x08\nVG\xee\xe3\xeb\xbf\x04\xf2^>\xdf\xb5\x8c\xaax\x8c\xea_\xbd\xb0\xd4\xce@M\xd7g\"\x9f\x97i\x12%t\x04\x13\xd6\xb1\xe7\x8c\xe0u_>\xff^\xfc\x7f\xe1\xa9\xdeP\x1f\xde\xbb\x0eJR\x99\x97\x17\xbb\x167\x93\xec\x9b\x8e\xea@\xd0=\x9a\xc7\xca`s\xeb\xea\xbb\x91\xb7\xef~\xdc\xfe\xb8\xed\xed\xbb\x93\x8f\x17\x1fK\x0c\xc9\xd9.\x1eb\xf1\xc9\xc1\xd6\xff\x1f+\xe0\xffw\xb6^on\x05W\xdf\x8dX\x05\xdb\xedB\x8c|\xb1\\\xad:\xff\x86\x9e#\xc3r\xae\x87\xf3\xae\xb3\xec\xb3,\x7f[\x91\xe2\xce\x9eg[\xfatDG\xca\xd6l\x7fd\xd9\xc2\x15\x92x\xbb\xb6\\\xa7\xe1)\xeb\x13\x8fH.\xaf\x86w;\nl\x8f\xdc\x8f\xf1\xa6\xf7\xef\xdb\x18\xc8\xbch\x14\xebo\x04{\xac5\xd4*c\xa8\xa6}\xce\xc9\x87M\xe7\x08v\xcd-\xe3D\x8e`\xb7\xf5Q\xf5# \xaa\x9b\x8d\xd4\x8e\xaf3\xaepo\xb3\x94C\x015\xfa\x83s+\xc3m\x1a\xa4\xe2\xd4\xe2\xc2@\x8bp\xd5\xb9I\xf3\x9b\x91#d\x9e\xcb\"\xa7y\x94\xa7\x1e\x87{v\x96\xb8\xab\x8c\x94Q\xb8\x94\xbc\x13\x9bF\xcf7WH\xd2\x92\xe8\x8e\xea\xf6t\xf7\xd8\xf2A<\x981\x1cX\xb7E\xb0b\x1fJO\xeaz\x14\x93\xcc \x91\xac\x1bR-\x99\xad\xda\xd6uS\x84\xa1\xdb$\x03\x94\x90\xba\xacr6_\x93LG\xaf\xf2Ql\x14\x8a\xa0L\xc3rNP\xfc\xec\xd6o\x8c\xb0\xa5\x9cQ\x9f\x17dj\x8a\xfa\xd3J\x91\xbc\xe9\xef\x9a\xd9\xccp\x11u{;\xad\x02\xfaZ\x89g\xf3\xa4\xc8\xb5\x1e\x01\xe5\x0e\x9f\xd9\xbf\x80\xe6\xef\xf2[R\x1c\x86%A)\x8fc\xb1v\x17\xa3\x1f\xc1\xc6\x06\x9d<\xb5\xec\xbe\x82\x94\x94U\xff\xac\xbd\xd1\xf4+V\xf3\xd0\xa7\xb6C\x14*J\x8f\x1d\xf1*\xb17\xad\xbdPW0E\xcd\x82\x176\x83\xdc\xec\xa9\x94\x1a\xf7sn\xc1\xb0\x12\xc1\x91-\xdc\xcc\x02j\x97\xdd\xe6\x1c3\x96c\x9eX\xb8\x8a;\xd8\x83\x9dv\x7f\x10L+\x88f\x84\xd3\x02\xad\xf5\xe5f\xaaR\xb8=\x8e\x8f\xcb\xcf\x1d@s\"B \xfe\xb3Q\xf50\xabJ\xe4\\\xcc\xe7\xf1\x82)RH\xec\x9c\xdap\xd9q\x13\xb9\x84{.\xf6\xbc\n\x0f\xe0\x85H(A\xdd\x87Y\x03\xea\xe5\xef/_ \xe1\x1eu\x95\x8cU\x15\xc8\xf8\xc9\x17DL\xea\x9b\xe3\xf8\\l\xc1h7\xea7ku\xd7\x93\xa7l\x83N\xb6\xdd\xe0;o\xbbq\xf4xo\xe0\x0e~\x80\xb5\x10s\xbc\x81\xbb\xcdM\x0f\x91\xb5\xcbx\xd8\xf5\xe4\xee\xca\x9b\xec\\\xf9\xdc\x12{\xb2{\xe5C\xc9f\xa5\x84}\x98M\xe6\xb8\xef\x19|\xb7]j\xb2\x1c\xff\x8f\x1b\xa3,@\xfaX.=~\xc9\xe1dh\xfe\xa2f_\xb2>\xee\x83++\x15\xa0\xb3#tT\x95\xa4\x1861\xb7\x87A\x87\xb5\xfczf,\xcfs\xc6(\xfc\x15\xbb\x9c\xf7C\x14\x8eq\\z1\xdek\xcf\xf3\xe5@\xf1\x9f\\\xa5\xe5\xe4\xd9\x15\xae\x96Hd+\xb0\x9c<\xbfR\xebe\xff\x9a\xa8\xc0\xb0}8`\xcd\x02<\xe9\x90\x14\x12\xbf=\x84+\x15 @\xf1c?\xab\x8e\x91 \x9a\x87\xc5\x01uw\xc4\xdc\xea\xdfy\xef8GQ\x9f=\xa2\xd5*\xd3\x00?\x11\xa0\x92\xdd\x18\xe9\x0c9\x14g\xdb\xf1\x82r\x99&\xd4\xe5?\xe5\x0cn\xedz\xd2a5Q2x\xbep\"\xc1A\x8e\x1b\xbce\x93\x02\xb6\x18\xfd\xc1\xb7\xd2.7s\xdby\x03\xc5\xd6\xd6\x1b\x0f#{\xe0M\xd9\xa4\xb8B\xcf\x19\xac\xba\x08#\x13\xec\"~\x0d\x9a\x19\xdcf\x0e\x1fB\x06\xd6#\xee\xb7\xc3\xdd\xa9\x03Z\xb8 \xf7j\xe0C\xab\xc4\xd6V\xb7\x94\x19\xd7&\x0bVY9O\xa6\xd4u\x1c\xcf\xc7~\xb2\x89\xceq\xa9\x82\xea\xed\xcb\x17\xc8\xb8\x0e\x1cf\xcb\x84\xce\xfc\xb6)\xa2\x8a\xb2*\xbe\xbabl\xde\xd8\xb7\xbc\xa0*f\xe0\xfa\xa93\x19a\x97\xff\xe0\x85yf~{\xc8\xdeV%)\xc4b\xb36\xca\xf26/b\xfc\xcc\xbe2B\x13\xa7d\x89\xdf\xd9\xab\\\xb5Q\xab\xfcr\xb2S\x81}\xa3.\x86#\x04\x02d_\xf2\"\x99%\x19oP\xc1\x86\xa2\xbb\x88l\x93\x94\x8c*\x98\x95y\xf6\xd5\x97Mp\xb6\xb7\x1d\xd8\x94\xc5F\xe00|\x8dM3b\x01\xab\xaf/3\xb53Q}\x9b\xf2J\x85)B\x1b\xc4KBG\xbd\xac\xa7|\xf0\xe0\x13'\x94\x19R*\xeb\xaf\xae\x0bh\xae2\xca9\x86n\xa5\xd1\xdeX\x17\xd2\xdd\x84\x8b\xd4\xaa<\xa8x\xa0\x85d\x82\x17\xc9=\xe6_C4{9\xd7\xd0c\xee*Zc0K}H\x14p\xdd\x17~1\x12 \xb2I\x05\xb2\xd5\x95/\x0f(o\xc8Q\x8d\xc3\xe92\xd7\x84\xa1#\xa98\x9a\xa1\xa3I\xf8\x96\xe2\x13\xbd\xb9'\xba\xcbS\xd9$\xcb\x1e?\xc64#O7\xb4c\xdb\xa3\x8f\xf1\xe6\xbfos\x1a\x9a\xb2Yv\x85\xffxe\x0b'\x12!\xd0`\x99/\xdd\xaa\xc3bSS\x81\x96F\x8e\xa7\xcc\xbf\xfc\xa8\x14\x7f\x9c\xc9\x97 \xd17F\x95\x08\xa2\xcd\xf3\x94\xf5\xa9\xa6\xa56z\xa2N\x0f\xeb\x95\xa4\x8d\xfa\x94\xbcQ\x0c\xd0o\xf4=\xc8\xd6\x13\x0dW\xd9\xc4V\xad\x0b'3\xfbx\xe0\x8f\xc0\xf97\xcb\xb5\xb6\xfaHhP(\x82\x0da\x16\x1e\xb2M\x05&\xe5V\xf5\xf9*X\xc2\xc7@\x15R\x8c=\x08~\x8d\x99\xccF\x1f\x15\x05Rr\x02\xa1\x84\x1f`U\x91\xaf%;\xe7\xed\xf3\xcd\xca10ZM\xca\x0e\x0d\x9dT\xd2q\xc9$\x9d\xec^\xb1\x1e\x8a_\x1a5w\x8fnK\xa2\xa1>\x11\x93\xc6\x89\x98\x18O\xc4D=\x11\x13\xc3\x89\x98\xe8'b\"O\xc4\xa4\xa1\xde\xd3\x0e\xeei\xba\x9f\x14\x05F=\xb2o@\xd7vMNI\xf1\xa5\x8f\x04\x89\xf0\x8c\x84\xf5%\xd3\xbb\x0e\xcd\x1b\xca\xe5\xd1v>\x0f@\xc6\xc9\x95\xe3\xb7\xd0e\xd8%1s\x85\xdc\x04\x85<\x1c\xb7\x18\xa9\x88B\x07\x81\xb8;\xfa\xc4\xe3\xb4n\"\x1d)\xd0\xcb>\x9f\xf2\x91\x1d\xf9U\x97\xfc\x15\x9d\xc4 \xcc\xcd=%\x8d\x11\x7f\x15\xb9T}\xe7\xc7H\xfd\x05I\x7f\x96\xfeGG\xfe\xcc\xf8J\xf3\\\x92\x10\xcf\x87\x8d4X\xa6\xabY\x92\x95\x93\xec\xaa\x0biR\xb9\x86\xe35\xc9h)\xeby)\xeaQ\xab\xe9>5\xe4)G\x03\xb2\x167\xab\x1d\x1e\xad\x14D\x9fd\x10z\xb0r\xc3Iy\x85\xeb\\z\xb2\x17\xaf\x1c\x94;\x19<_\x82\x11\x17\xab\xd7\xb4\xed\x95\\\xd9h\xfe\x94w\xf94\\\x90\xa3\xa4\\\x864\x9a\x0b\xedd\xb6\x19\xcen\xb3\xcaP\x99{\xc9b]{\xed\xa0*BGY!8m\xceA\xad\x8f\xb1\x9c\x87%\x89\xcf\xc9,))\xd7q`uhS\xc6A\xcd\xb0|\xd5\xfc%l\xfe\xacR]\xaeS\xab\x0d\"\xf1<(\xdd|\x92\\\x89\xe9\xe8\xd9\xe9P\xa3?=\xae\xed\xefLy6HPh\xc3B\xfcR\xba\xed\x0f\xa2\x07>c\xd3;\x17\xaf\xb4/\x9e^'\xbfB/\x19\xf5\xc1\x17kwg\xa7\x02\xe7\x8e\xccH\x06\xb7s\x1c\x91%\xc9b\x92EI\x95M\x01\xf1Iv\x15\xc4J\x0ee\x10\xf2\x97\xa4K\x9a\xfd\x16\xfb\xaam\x95e\x83\xa7\xb6\xda\x91e,\xfd\x19\xd5!\xb5s/\xf3\xb2LnR\xd2\x82M\xe1\x01\xa0 \xa1\x19;\x9e\x10y\xbc\xc7\x11a\x8c\xc9>\"#\xafVf\x97\x9d\x81u0\xba\x8a\x83\xe7\x92&~0\xb0\x95\x0bu\xd6\xbf\xa7\x1b\xe5\x8fw\\)e\xc0M?\n\xa5,\xb2f.\x0e\xc3k\x11\xeb\x0e#m4\xd1G\xa7\xe6\xe2N\xc5\x8e!\x133\xeeI\x10\xadH\xb9\x93\x8b\xafr.\x9f\n\x9c\xc4\xf3\xe0\xad8\x17\x80\x0dD\x9fH\xa1\xf6L\xf4\x8c\x88 \xe6\xc0\xf66/p\xd2\x87\xce3 \xe2\x06T\xb7\xc7\x8flUk\x13V\x17\x16\xf6\x1d\xdc.\x84\xb2*\xb3[g]\x1b\xc3\x86\x8e\xbbNqn83\x08\x8f\xcb\xa7\x02)\xd4\xac1`^\xf9\xe0\xc9\xaeC@\xd1 V\xa0\x80\x96}\x96\xb2Iq\xd5\x01uP\x1f:b\xc2\xdbQ\x85\xe4\xd3u\xfe\xcaG\x92\xcd\xab4\xed\x82\xaa\xeb\x82\x94\xa4\xb1}Gv5Nh\x11[\xb9\xb8\xe4A\x8fg\xad\x8d\xc3\xe5\xe1\xe2\xb2\x94\x91]\xed\xe1Wd\x8e\xe4'\x8c\x97O\x12\x88\xedg~\x1f\x12\xa1\x1e\x0f\x9e\xdb\xde\xd7\xa2{\xd4\x88\x13$Yk]\xd6\x8evC\xbc>\xf6\xa0\xd0\xdb\x0d\xd5v\x8bI\xd8\xbc\x804j\xd9\xaa\xf4;_\xcf\x87S\xe9\xdc\xa3\xa2\x99VG/\xd0\xee\xd3\xdd\xa7\n\xdd+Hw\xf7\xb51\xfe\xc6\xaaC\xdd\xad\xa6\xb9P4\xfc\xe5\x0b8\xab\xecS\x96\xdff[\xb8\x8e\x9a\xf0\x85\x04\x11w\xe9p\x19\x163B\xf1biF\xe8i\x1e\x93\xb7E\xbe8\x16\xf7\xa8n\x81\x97\x84\xfb\x10\x06I\xb6\xce?\x91?\xad\xc2\"&\xf1a\x98\xa67a\xf4 }Cp\x7f\x99\xd8-\x82W\x14\xe6\xbcU\x16\xdf\xd0zc\xef4\xa9\x8a\xb6\xdeER\x8e\xb38)\xe7}\xf8X\xecK\x87\xe6\xcb\x93|U\x92\x0fK)\x94b\xd3C\xf3\xe5e\xbe\x8a\xe6\xe3,6%\x1f\xb2\xf1\xa7\xe2K\xd7\xb6N\xca\x93|M\x1e\xd0\x1dV\xcc\xd4\xb2\x92\xde\xdd\xee\x05\x0d\x0b\xfa\x80\x86\x8f\xf2\xdb\xcc\xd40\xd67\xa0e\xa1\x82{\x94\x14$\xa2\x129\xf4u\xa2>\x1c\xaf\xe5\xe9\xf8.))\xc9\x88M\x0b;k\xe6\x960i\xc0\x03M?T\x94\xd3\x10\x8cXx\xe6\x18\xa1\x8dA\xb4\x19\xde3\xcf\x18\x18\x18\x14\xfc\xc4\nS\x97\xd83J\x95<#\x90\xfb\xc6 0}\xac\xc6[},\x06-\n/M\xca\xe36\x95j\xb9\x16]WV\x80C\x97\xa6\x18\xbc4\xec\x9c\xd5\x9d0w\xe8\x01I4\xb6\xf3\x06r\xf8\xa1v\xd5\xfc\xe4 l\x90 )\x19b\x0fg\\[\x9e\xe6\xcb%\x89]\xef\x0d\xe4\x9b\x9b^\x8d\x1d'\xf9\x95\x0fE[U\x12\xa4\xc2\x10^X7\x90\xa9!\xe3\x03W\xe9!K\xc4Fr@/\x8b\xd5`J\xbe_\xbay\xff\xed\x06\xf7\xdar`\\[\xdaI\xbc)\x84!\xbf\x19\x87\x1f\x1a7\x7f\x1d+\\lnv;\x18B\x8azR\\\xb1Ue\xe4\x9f\xa2\xfd3)\xdajG\xa0\xdc\x15\xa0\x87\xe0'O\xd8\xa6\xe6\xc1\xb3e\xc1n!\xa9\xbe\xd8Xe\x97\xfaU\xe7\xde\xee\x847\xda\x05U\xf3\xb0\xac!\xaa\x0f\x80\x14\xf1E\xbb\xbd\xaeV0\x9e7\xef4C\x98\x0cq\x0el\xab\x08\x0ce\xf5@/\xed\xd6t\xd4|\x9f\xd6Zh\xbd\xbb\xb5\xa4<`k\x81\x0e#{\x91\xa5\xe4\x18\x82\xba\x14\xcf\xdb3\x9ew\xf9-Zw,\x16y\xf6\x90\xe6,U\x0cj\xfb}\xc8\xce\xa1{\xce$6\xd9,\xd93\x8f\xb4\x08\xd7\xa4(\xc9\xe5m\xfe\x9e1\x8c\xc3\x14\x11\xaa\xe6\xf4\xe2U\xa1!m\x8e3J\x8aw$\\\x1bZE\xd7\xe6FYu\xab\xed\xba\x1a\xadp'\xfc\xa0\\&\xc93\x93g\x0f\xfe\xf10_,\xf3\x8c\x11\x03\x05\xe9]\x00\x90'l\x1b\xbf\xb4Q7\xaf\x9fU{\xc9\xc7\x10\xa6C\xea\xcf\xcd\xf5\xff\xce\xfcfa\x8f8\xc6x8{\x042 U\x95\\\xf1:\xb9\x0dd\xcc\xb1\xaah\xcb\xa4\xa33j\x14kUQ\xa1\xc2\xc9\xee6\x86\x02\xe5^M\xe3FL\xccN\xcb\xca\xac\x9b}je/\x08\x1a\xca\x1c\x86\xab\xd9\x9c\n\xd7\xe1\x9d\xb2\x02v\x8aY\xcdr\xd6\xc2&\xd4\x12\x14\x86\xdb\xe4\x14\xf5Y\xf4\xadp\x91<\x1c.\xcc\x164&n\x97S7\x94\x13\xd7_\xbe\x00 \xca\"\x1a\xa7dA2|\xbfM\xb28\xbf}\xa3O+\xdb\xef4@\x9b\xaer\x99gq\x92\xcd>\x94D\x96\x93\xfaG\xd6\x1c\x9e\x0f\xcfxh\x9c \xcbc\x82F\xfd\xfb<\x8c\x1c\xc9\xf0\xe0i\xe8(|\xab5\x8e\xd0-t\x9f\xaa\x163y\x10\x85\xd9\x87\x92\x1c\x9d\x9dT\xe0\x1b\xe7\x11\x1a\xef\x06\xc9b\xc9{\xca/'\x9f<\xb1}\n\xe6a\xf9\x96\x84tUH\x7f'\x1b{\xd6z\x94\xcc\xae\xe3\xf8\xa8\x1d\xdc\x98\xd9\xed\xef\xbekB\xcdwp8'\xd1\xa7\x92Af\x98q\x81?$%\x94\xab%[_\x1e\xc0\x89\xce \x08.IP\xc7\xe82=['E\x9ea7\xb4J\xf56N\xcf.\xc7#\xb8\x9c'%\x8f\x0f\x95\xe5\x14n\xf3\xe2\x13\x08\xa3\xbd\xf4\x0e\xa9\xce,\xcf\xb6f\x8c\xc6I\"\xde\x13\xd6\x8fh\x0ea \xbf\xf1H\xca\xbf\xf9z\xd5\xbf\xa1\xb8\xee7\x1f~K\xf30f\xff\xd1\x08\xfc7\x1f\xa3Q\xfd\xc6\x1ds\xfc\xd6\xd7\xc1\x1f\xf3\xa2\xc8oK\x98\x16\xf9\x02N\xf2\x98\x14Y\xf2\xf7\xa2\xaf\xd4\x1f\xd1^\x14\xfe\xc1\xb5\x0f\xbe\xd6\xd7%\x17\xab\xe94\xf9\x0c(D\x84L\x98\xaf\xcf\x02p\xa24\x89>9z\xbdUE\xfb7y\x9e\x920chq\x89K\x8e\xab\xc3\x16\x07\xd7@$\xa2\x9c\xb7\xb1J\xed\x1a\xa51AU#c\\dE\xedenW\x90\xb036\x0b\xd3\xd6\x874\x89HV\x92z\x9a\xe0Y\xb0\x13\xec,\x0b\x02\xee\xe1\xaa\xa4\xf9\x02~\\%i\xec\xc1\x1789\xbe\xd4\xcao7\xde}\xbb-\x9e\x8eL\xd0~@\xddS_\xbe\xf0[\x82\x0d\xd7 \xe3\x18\xe7Z\xd2\xc8\x0e\x83Z\xb9GjVA\xbfY\x91\x1c\xb5\x93g\x0el\x9a\xfc`\xa1PP\xad\xecM\xbbOF\x92e-\xae\xa0\xab\x8d\x1a\x15$\xa4\x12=\xb9N\x9c\xacM\xea\x1daP\x12z@i\x91\xdc\xac(q3\x1f\x84\xb3\xe47\x8e\xd0\xfe7\xaa\xc2\x84\x93\xcc&2\x05\x85\x9d@Mb\xae\xbdr;'\x95\xd8\x0c\xa4~\xf2\x10\xac\xc2\xef\xe6\x03^\xde\x07\xe7Y\xb0\x83\xaa\xd6\xc9\xa3!\xd3\xd6\xd1}\x90\xd2\x118aJ\xffL\xee\xf4\x90\xbayF\x8b<\x1d\x81\x13\xd1\"m\x7f?!4\x1c\xa1\xdb\x82\xb0\xfd\xf1b\x9eLY\xcd\xa8W\xcd>\xd7C\xb0\xd0:\xb6\x03\x0e\x0dW\xb3\x90&k\x82\xf3\xd3\x86\x12\xf43v\x92\xc7\xc94!\xc5\x05\x0di}\x8d\xd4\xfe\xd4bO%\xa0\x16\xad\x1b\x83\x8aS\xc43dc\x83\xaa\x90PC\xc1\xb0\xf3\xbau\xcd\xf2\x08K\x99\xb9\xaf^\x1b\xd4_2\xf7e+=\xe1j1\xbb\xdcv\xf4\xd9k\xfc\xf7t\xf7\x95\x1e\xfd\x9a\x8b\xe4w\x9f\xeb\xe5W\x98\xfe\xec{\xb3X\xbe4b\x151d\x93h\x92S\x18\x93\xdd+!\\\xa7\xe8\xb5\xf8\"\xb9I\x93l\x86\x1eu\xa6IQ\xd2\xc3y\x92\xc6\x86)_\x8b\xab\xf6\xc4\xedc\xafH\x90d%)\xe8\x8fd\x9a\x17\xc2\xb1D]\xa1q0\x91\xad\xaeB\xd4\xc58\x0dQ_\x8b?3\xe94XM\xb7Z3\xb3ob\xdcl(07+\xeaTaK\xec\x840\x8fI\xa4\xcc\xb8]\xb8\x95\xba\xdc\xee\xba\xe0\xd7\xf7\xdc\x82\xbdCk4\xafh_\xf5\xd1\x88g\x1c\x1cZ$Q\xb4\xdaA\x91s:l2\x97\xd6\x03l\x88\x1c\xae\xba\xcf\x9d\xec\x1a\xee\xdfb\xac\x1b?\xef\\\xf1;v\x12\xf0`\x9b\x08\x89-\x0eK\x0355+\xed\x1eFl\x83\x89\x8e\xe5\xab\xc4\xef\xddK\x87|P\xcfR5\xfbZ\x0cc\xfc\xe6\x0861\xa3\x15\x8b|U\xa6w\xe7d\x99\x86\x11a$?\xe3\xe3N\xc2\xe2\xd3j\xd9DS\xeb\xb6k\x8c\x9e\xf2-\xef \x05\xcfuD\xd2d\x91P\x12_\x92\xcf\x03\x0d<\xe4\x84\x11\x8571K~\xf9\xbda\xe7\xb4\xe6\"\x1c\xe8>\x17\x9e\xa7n\xe1\xeb\x14\x08\xeb\x19\x8a\xf6\x18\xe4\xe4x=\x02\xfb\xe0\xae\xf0\xde\xcf\xf3!v\xf9u(E\xd5||\xeb\x95]-\x8b<\"e\xf9\x01=\x14\x97\x03\xc4e\x0d\xeb\xae\x9d7\x90)\"\xe67\x90\xd9u\xab+\xf0\xb2\xea\xabHS\x98\x02oXm\xf5@\xa5]\x7f|z1>\xbf\xbc>98\xff\xf3\x87\xf7=j\xf6\x88u\x0b\xe9\xd8\xc7\xe7GJ\x11\x84SJ\n6\xa7}\xd1\x0d\x06\xd9\x05\x9c\x9c\xfd<\xbe\x1e\xff\xe5\xf8\xe2\xf2\xf8\xf4O=\x1d\x9a\xf2\x0eL\x85\xb8\xf6\x9f\xd4\xa3\x8b\xf1\xc0\xf9 \x1b\xf3\xf3\x18M_\x8e\xffry}xvz9>\xbd\xeci|\xf5\xe8\x8d\x9f\x8fq-N\xcf\x8e\xc6=m/\x9b\xeb0T\xc9\xe9\x9e\xf2\x9a5\xa6>\x88\x1a\xb3{\x01\x9a\xd3\x05#\x9f\xe7\x94.G\xdb\xdb\xb7\xb7\xb7\xc1\xed\xb3 /f\xdb\xbb\xaf_\xbf\xde\xfe\xcc>kd\xf3\"\xa4s{\x99W\xdb'!\x9d\xe3\x9f\x93wZ\xc9r=3\x16{\xba\xb3\xb3\xb3]\xaeg\n\x01\xfe8C\xed%u\xd5\xe8\xe9\xb5\x0d\xf6\xc9\xc5\xc1r\xc9\x10(\xfe@S\xde\x0f\x19\x0f~\x1f\x85\xe9[y>*\x94P%\x826\xaa\xbfvV\xd3\x1f\xd6N^L\xa9\xad\xb4aI\x17\xac\x8e\x1e\xdb\xdb\x8cQ\x8d=s_\xed\xbc4\xd0\xf1\x99\xfb\xf4\xc5+\xcf\xcd\xdc\x97\xdf{AR\xfe\x1c\xa6I\\\xc9\xe6\x1a\xb9CE\x19\xdee4\x7f{\x12nV\x94\xe6\x99\xd9\xaf_4'\xd1\xa7\x9b\xfc\xb3\xf9k\xb2\xc0\xf8\xfe\xa6O\xf3$\x8e\x89\xa5\xd2\"\x8c\x93\xdc\xf2\x89\xa0\xed\xa6\xe9S\xb9\xbaY$t\xd4\xd2L\xb6i \xe9\xeb\x8d\xe2\xee\x0dv\xc8\xe3\xa0H\xfc.\xc9>10\xac?`x\x04\x99\\\xb8\xce\xab\x97N\xaf\xae\xb2\xde\xcc\n\x95X]\xadR\xa9\x9f\xc8\x93\xf2\xec\x10\xe5mR\xc7\xfc\xd5\xab\x9ev\x0c\xdePZ\xed\x88Q\xf5\xb4\xf4\xba\xd1\x92\xfc\xc5\xc002\x9a\xd2\x8a\x88\x11Ch-P\x18f2\xa1\xa8\x93\x19N\xb8.\xd6\x15\x17N\xcb\xee\xf0\xb7\x82\x84\xf1Y\x96\xde\xf1\xb78)\xc3\x9b\x94\xc4\x8c\xbcb\xfd\x1f\xa1\xcb\n\xe1 \xeb\xd7|%\xc3\x83\xc6\x10\xc2o\xd8\xad\xdfX\xd2\x12h\x0e!\xa3y\x160MH\x1a\xc3mB\xe7\xf9\x8aB\x98\xc1o\xb2\xc1\xdf`\x1efqJ\x8a@\x91\x93\x16$\x8bI\x01!\xb0\x8el\xe5\xac'XC\x00\xc7\\\x90\xc7\xeb+\xe7\xf9*\x8d\xe1\x86\xc0bEY\x171\xd4\xfeo\xc22\x0e\xbd\xf7\xfd\x16\xc0\x19\x9d\x93\xe26)\x19\x99@(\x90\x84\xbd\xab\x1d\xc8\x0b\xf8M\x8e\xf8\xb7\xc0d2n\xd9~$~\xf8\xfc?\xe2\x94\x8b\xbe\xfc\xb7\x98\xf4C\xd1\x97\x7f\xd2\xb4\xcb\xd2#H\x026\xf3\xbf\xeb\xc8?\xb5\xda\x13-\xdb\x9b\x16u\xc8m|\n\xbf\xcb\x99\x11\x94q\xdb\xfc\xbf\xd3J\xb0\xe5\x08\xe95\x9b31\xa9\xdc\xff\"\xe4S\xf8\x8d[~m\x82\xf3[\xd0\x0ckh\x94]::m\x00\xa2Oq\x0b) \x18\xbc/\xf2%\x1aE\x0c\x83\xcc\xa62td\x03^6\xbe\xc8\xa4\n-%\x16\xd1\xa4\xb8b\xc74\xe7\x9a\x1c\x06\x88\x8e/\xee\xeb\xf2\x0e\xcb\xa9D\xf5\x89\x83\xe0\xcd%\xdb\x89\x0c\xfb\xc7\xba5\xedV\xdb\x99T\x99\xafP\xd5\xdeN\xde.u!\x81|zI\xd4&d\xcd\x08\xfdY\xc7\xbe\xa6.V\x9a5\xf5\xf1\xb5\x8f68(\xbc\xa8\x12\xff_\xf6\xfew\xbdm\x1cY\x18\xc4\xbf\xf7U\x94\xf9;\xa7\x0f9\xa6\x15\xc9v\x9cD\x89\xe3\xe3v\xdc\xd3\x997\x89sbg\xfa\x9d\x9f\xc6G\x0f-A\x16'\x12\xa9CRv<\x93\x9c\xeb\xd8o{\x0d{\x01\xfb\xec%\xed^\xc2>(\x00$\x08\x14H\xcaq\xf7\xf4\xec;\xfc\x90X\x04\x88?\x85B\xa1\xaaP\x7f\xc4_\"X\xf5\x8d\x15\xc4\xdf\xee\xfb\xc4\xa6=\x8d\xbd\xeb\xa7\xea\x11\xaa\x8d\x84\xd9a\xf5Z\x1f\x81|\xdd4\x06i)vVn\xc6V\xc1\xb7+$T\x94Ql\xd7/\xe4\xfd\xa9\x1c^m|M\xb3q\xb4\"\xab\xc8vJ\xf2{\xa4\xfd\x10\xce.*\xf8\x1aFI\x10?\x1c;\xd5!\xb1\x08\xe8\xfd\x12|\xa7\xe4\x18\xb7\xcc2\xfb\xe2\x1f*\xf5\x8c\xa9\xc4\xb1]\x88\xa0\xd2f\xa0\xda)cI\xa9\xd5\xa0k7Z\x95T\x15N\xab\xcb\xd26|UO\xe5\x98\xb4/b*\x90\xb3@\x92L\x96\xc8h\x18\xc4\\@\x06\x8f#\x8a\xc4M\xb6\xc1\xc1\xaa\xa7\x95<\xd0X\xf0\x0dv\x06\n\x0bd\xae\xd6\xca%\xabN\x83\xdd\xa6)\x0e\xb9\x8f\x95\x8a2q\x9f\x8e\xcc\x87\x16\x0du\x00\x8f\xb0\x0e\xfeQ\xf0}\x82\xdc*\xda\x1f\xa2\xa0Xa>9\xe5FB\x80N-\xa2\xa4\xba\x9a\xec\xdbwFZl\xb1\x9a\xcf{i\x16#\xec\xc2\xedZE\xadV\xd1z\xff)\xa1\xfb\x89\xdd!%\xb2q\xdc\xa8cjW\x84\x87\x90\xb4\x10\x15\xe1\x04\xc4\x0fg\xcf\x9aK\x08*\x00#\xcd\x8a\xf89\x06Q\xb2\x071\x03\x7f+\xab\xdc\xb3G\x91H\x99\xb9\x95\xfal\xc4\x7f\xa1\xaa\x1e\xffp\xdf\xf8\x96\xd06\xd6\xef^\xc8\xd9y\xc1\x15\x9c\xeb\x0b\xb75\x10\x7f\x132\xa6^\xb7\xd0\xea\x12\x17\x8b\x18\x81'\xab\xaca\x85\xbd\x94\xbd\xceU\xd0I\xd7=\xb7B\x1e\x12b\xf5\x10\x91\x88wUl5\xfe\xe6\xa8^%\xb6\xaa\xc40\x84Z\xfcG\xbc\x8dV\xe9\x9a\xd1T\x07\xff\xc4\x97\x9f\xd8\x9d|\xf7\x89\xdd=\xc4Z\xd17\xcb\"Tf\x1bAV\xac/M\xaa\xbdCo\x08\xdea\xdf\x11y\xd1\x1bb\xf1\xae\x9d\xba\x9bH\xf8\xa3\x80\xfd/\x9c9\xf6=4J\x08\x14u\xf7\x1f\x8d\x0e\x87\x97\x8f\xae\xc3\x0e\xe7\x87\xbaZ\x1e1\"\x96c\xa3._\xc5\x0f\xfdV\xa0\xf4q\xda.\xa0\x1c\xee\xf2\xe2\xe1&@\x11\xe0\xf0U\x8466\xea\xa3\xb7)\x87\x95\xf8\x8dQ1Y/__ D\xf4w\x05\x83S\xbd\x18\x04\x81\x06M\xff\xb0\xff\xe5p7xx\x80V\xf8J\xd3\x8a\x07 \xce\xec\xe2\x8a\xf6\x0fP\x916\x18\xec\x9a\xd7\xe6\xf2z]\xde\xab\xef\xef\x05\x9d=\xda\"BN\xec\xb1\xe4\xbf\xd6l\xcd\x04\xdfP\x8f\xccm\xb7@h\xbbJ\xdb I\x94\x1a\xcf?\xfd\x14+\xe8C\x0csQ\xa9\xb8\xe4\x82\x8ah/z*B!\x11\x014\xb3\x8e@\x92\x04fF\x8a\x8e\xf2\xf7\x0b\xd8\xed\xe3\x95\xdb6x\xe0\xf3&\x86\xc0q5\x93a\xaeB\xf0\x02^\x16x\xa0g\xffs\x87\x16p\x9d\x1fh\xeb\xed\x1a^\xa2\x0e}\xad\x03\xbd\x01\xdb\xed?\xce\xdf\xa6\xeb\xa4h\x97\xa0\xd4R\xd1\xfd\x83n\x86RH3\x94\xdeXH\xfclZ\xdaT\xd77\x89!I d\xaa\xecr\xbb\x08\xed\x8b2\xd9k\xe9\xbc\x88U\xed\xe1\xa9mc\xaf-\x94\x9cEu\x84\xd2\xeeb\xbd\xf1\x8a\xa1\x95\xa9\xea,\x87#\xea\xad\x08\xbf\x88\"\x13\xf5\xcd!\x8c\x8a\xcb\x10\"\xebB\xbb\x11 \xaf\xa51^\x07\x11\x93\x91\x03%\xdej\x03\xa5\xbe)\x07\xda\xecM \x07\xfac\x9aM$-\xe8\x8aM\xf4bH\xe3\xder@Z\xc3(\x98\xf0\x11\x15fJ\x0crH\xf2\xe6\x1e-\xaa\xba!T3\x9aH#\xf4rd\xd8\xf0\x7f\xf0\x9e\x14\xac\xaa2\xbdo9l=\xc1\x82\xa6\xd4\x97\xbf|\x02\x99\x85\xf5_\xd5\x90\x17\x84\x9b\xa2a\xd2\x80\x86\xc9e \xf0\xb0\x0b0\xcfYA\x01\xd2\x05\xc5\xc4 E1[?\xa1\xc0\xf8\xe5\x0b\xd0\x05\x870\xba\x0c\x02\x85\xb0|\xd4\xa6{\"=jy\xe3\xe4\xd8=\x0e,\xa86\x8327\xc7h,\xac7\x96\xc9\x0e\xf9\xf9\xdb\xbe1\xcc\xe5\xec\x0093\xd6\x99.\xf7I]\xc0\xee\xae\x87#\xe7\x07\xea\x86l\xc77x\xc9'\xfe`/\xa0\xb8\x90\xbd}\x9a\x0b\xe1<\x86\xee\xaf\xa9\x8f#\xbd\xff8\xba\xdd\xed\xdeT\xc1\xdeP\x928I\xa7\x8c\x16j&\xf3(\xe3\xa5h/\xccP\x1b\xc0yI_(\xbaU)^M\x0d\x84?ARZ\x06\x0e\xf6\xf8\xde\x92\xc8P\xc0\xcbC\xd8\xdbE\xd5\xc1^\xa9[(`\x08\x1bJ\x9a\x15h\xad<\x15\xd2\xc5`\xf7)y\xdd\xbao\xde\xc2b\x98\xc7\x91`\xa1${si\xb0\xe3k8\x04u\x0d]\xe9V\xeaurB\xfbR\xaf\x81q\x0e\xcb \x80\xf5\xb2 \x86,\xa8+k\xec\xdb\x89\x85\x90\xeae\xde\xc3M\x97[\x18a\xf3\xf7\x18\xaa\x8b\x05|\xdfD\x8dJ\x0fdf,\xf2\x84\xe24\xa15\xe9\xd3\x0c\xe7\xa4\xd4Ex\xb5\x8c8\xa8$\xd2yO\x1a\xf7\xaam~X\x0f\xfe\x9e\xe8w\x01\xc2\x8eK\xf4\x94\x04\xbc\xea\xec\xbe\x08\xb5\xfb\xecI a\x8c>\x83j5\xcff!4\x82\xbe\x93\xbc\xa2\xf7\xe3\xcaJ\xd3\xb2eA&1\xd2a\xe7\xb3\xde\xd5]\xc1\xde\x08u\x12\xcd\xf8b6\x9a\"\xe8\xe5\xac\xf0\xc5\x0f\x0cb\xdd\xe6\xdec\x8e^\x05\x87\xc4\xf5\x9b\xc7yo*\xe6\xa5R \x0e!\xe2EJmm\x16\xba\xc1\xa0\x00\xaam\xfc\x01n\xf2G\xfa\xc6\xff\xef\xbe\xd8\xf8\xfa\xbeG\x94\xc4\xa8\x0b\xc5\xfc\x03\x9b\xac\xb3<\xc6$\x86\xebP\xf8r\xf1\xf7mWB\xb8w\x8d\x8dk\xedX\xc5\x95H\xaabs\xab\x9e\xa7|(\x84s\xb8f\x1c%\xe84z\xda\xce\xd2u\x82~\xbcY\x9a\x16\x8e\x9c\x98\xe6~\xc6I\xce\xa3\xfc\xa3BhmB\xc0\xec`\xf3q\x15\xc4\xb0\x99{\x16&B$fuq\x8e\x01\xcb{ \x94\xfe&u\xec\xc5c\x90\xfc\x1a\x14\xf4}\xe4\xc0\x02\x02\xd9\xd4\xf3\x95\xcc\\V^\x94\xb9\xc6\xa7\xae\xdbb\xdf\xb4u\xd5\x9f\x08\x15\xaar\xd4\xeeyjg|\xd4qV\xe9(\xb9l\x99\x18\xb9\xdb\xaa\xe4w_\xeb\xb2~3\xef^\xa2E\xa1\x19(;\"yH\xc3\x12\x91\x92\xbdL\xf9\xa9l\x9cD\x96,\xe1K\x89\xb9 \x12\xf9\x13\x0fl.\x89\xc8\xdfe.fyh\xf0wE\xc6\x98\xe5\xd8EN\x14\xcd\xb5Y]B\xf0q\xdbh{\xa3\xe8!w)l\xb1:\xc6\xd0\xa8d \xcb7Q\x08\xef\x83\xc7\xa6\xbeD\x08\xefOLY_\xba8\x0e\x1e\x93.\x8e\xcf\x06OZ%\xac\x86k\x04\xce\x06Q\x97\xc0\xbc\x81]G\x19\x17\xf2\xf7\x1ce\\\xc8\xdfw\x94q\xf1\xfe\xc0Q\xb6\x82Cx\x0c\xea:\x9cH\xa2<\x05y\xfd\xbd&iV9\xd9\"\xe4\xb4w\xde\xc8D\xdf\x84\xb0\x0c1\xd1\x1bnKL\xea\x96\xfa\xd7A\x08W\x98kv\x8d\xd9\xe4\xf6\x82\x10\xc6\xfcL\xf1\xef*6\xfbV\x90\x99S\xf4\x05?\x82)\xefo\xccE\xa4\\\xfd\xeaW\x06R\xcfa\x0c/\xe1\xf69\xdc\xba\xb6*\xdf\xa6\xfe\nc_p\xa2,\xa3\xe4/\xe1\x10\xae\xfc\x1b8\x84\xbb\xd1\xede\x08\xb7!\xf0\xc1\x99Z>\xb3\xa1$\x80\xd3\xd1-\xe7\xf5\x974\x11\xe1OI\xc5\x96A\xb7TA\xa0\x18\x9a\xbdf\xbf\x17\xd0\xcfjw\xff\xa0\x9a{\xdc\xb9\xb9\x9b\x0e\xad\x1dtn\xed\xb6Ck\xbb\xed\xad\x9d\ny\xe5\xc6\xbd$\xda\x891i\xe4\x7f\x14\n\xc3\x11\x17K\x86\x80\xd9\xf5&p\x04\x13\x18\xc2i\xad\xba\xe9\xeax/\xcd\xa9\x14\xdb\xc4a^j$\x8a\x10\xbc*\xd3\xb7g\xfa^H\xd3z\x9d\x0d\xe3T\x13Sv\xa5Y\xfcW\x95\xde\x1d\xcf\xdf\xf2\xe5\xf1\x04\xed\xca\xa4-\xda\x0fQ\x1eO\x8e\xd7\xc5\x9c%E\\\xa6bpV\xff1\xcd\x96\xef\xa3,Z\xe6F\xad\xd5jA~\xfe\xbeJ V\xf4V\x19;V\x05\xaf\x97\"!1\x16\x9c\x9c\xbd\xfb\xf1\xf5\xef?~8\x1d\x1f\x7f\xbc\xf8 _\xfd\xf1\xf8\xcd\xebW\xc7\x17\xa7\xf8\x83\xbf=\xfb\xf0\xfa\xff\x7f:>\xe3\x7f\xee\xe2\xcb\xf7\xb2\xbaU\xf0\xe6\xec\xf7g\x1f/\xea\x1f\xe2\xaf\xf3\x9f\xce~\xc6O\xc6\xef\xcf\xde\x7f|\x0f\x87\x8a(|W\x81T\x86\xcf\xf5\x13\x7f\xff\xb1yE\x9f\xca\x92\xdd=\xea\xf2\x1e\xbf\x19\x04\xb5C*\x9f\xa7\xb7\xaf\xf8\xa2\xc6\x1c4\x9d|\x9e\xecm_`\xea\xf9 A\xa1\xa3\xbbE\x1aM\x87\xcdbG\xb9\x16\xdf\xd2;A\xfe\xbb\xf5\xbeH\xaf\xd3u'V\xdf\xd5\xf5\xea\xbe]\x97\x13?\xe3\x7f\xed~\xcb\x18\xa6\xf7\x1d\xc3\x04\xa3=\xaf\x05\xe2\x7f\xcb\x08\xe6\xf7\x19A\x1d\xb1#\x85\xbe\xfdg&\xfe\xaee\xd1\x9ee\x96\x92\x0bV\xa7OZ\x9e\x10nEJn\x13&\x1e\x15\xf5\x92\x8a\x1c{zJ\xacv\xcf\xa26\x89\x89c'{|\xab\x8dW\xe9j\xbd\xf2\xec+\x8c:%\xf0J\xcc0\xaa\xae\xea\xf4\xc3\x13\xc8kT\x9ab\xcaK\x17\xf9\xf1V\x19\x1b\x97\xed\x8fSD=/\xa4\x89\x98gU4\xa0?\x17}i\xc4\xd0S\x17\x97\xd8\xa6E8\xbd\x12\xe1p\x10^\x8d\x1a9\xe8o+NV\x9c\x1c\xc5\x95\x94\xcay\xdcp\xc7X\xb3!\xe2m\xd1cY\xd6XKx\xd2\xf3\xc6\xe8\xf2H\xc4,K?\xb1\x84\xae ,\xa8\xa5[#]e!\xf2RM\xe6l\x19\xd15&\"\xc2E\xb4t\xf8\xfb\x8b\x9b\xb1kV\xf8\xdel\x91\xdeR\xe1\x82d\xc4\xf4uO\xe2x/\xbf\x8d\xae\xafY\xf6\xf1\xf5\x076\xc5\xb8\xcf\x822\x85\xe0E\xe51+t\x063\xcep\x88\x1c;\xbd\x84\xdd\xf2e;\xcd\xcc\xa4\xfe\xea\xe1\x8d\xbc\x9e\x92G\x04\x7f\xf2t\x9dM\xd8P\xe5\x90\xa7\xe1\xc1n\xd8b\x08\xdem\x94%qr\xed\xa8%%\xc1!x\n\x8f\xc4\x91\xbf\x8c\xee\xe0\x8a\xc1\x1a\xddgCXEy\xce\xa6\x90\xa3y\xc5m\x94\x83\x88\x0e\x86J\x8e\x9ce7,\x83\xf7F\x95\xe4\xdf\n\x89ml*\xc2|a\x1eRQ\x9b\xb0C\x0cB\x88z\x18J\x0c\xed+~M\x10a\xafm\x00\xf2\xfb!\xc4j\xdd\x03?\xa2<\x821\x13\x97qH5\x0c\xdf\no\xa8\x1e\xdc C\x88\x88.\\$U\xa7\n\x14\xaf\xf6\xeb\x92\x04\xd6\xb8\x11c\x11X\xc3\xb9\x11\x059(\x13\xab\x91u\xd62\x84\x87\x98\xa0\x9b$Tu.\xac\x8bt\xf5L\x84zu\x11\xb3\xa4x\xedhk\xa6\xd59g\x93\x8c92\x9b\xaf\x9c&\xba\xfc\xb9\xce\xa2\xa4\x18\x8b\xf3\xdfS\x03s`\x1e\x7f\xf2I\xca\xabrp\xa6+\x96K\xfbF |\x16\x01\xac+A\xf5\xa0\xc7\x9e\xa3l.}\x15\xcd\xf7JKy\xc5\xa5 A\xc0\x16p\x04\xf3^\x9dL\x1c\x82\x87\xf2\x06\x9a_\xf2\x1d\x92\xf7\xae\x8a4\n\xfc\xa8\xcc\xf8\xba\xc6\xbbM^\x96V\xbbgEy\x9d\xf3G-:\x89\xfc\xae\x8f\x14 \x87\xb0&\xe9\x8a\xcc\xc1[\xce\xc2\x9f\xa0\x06`*\x97s\x1cs\x08M\x82\x10f\xf5\xf79\xae3\xdf<\xe8\xba\xd5y\xf2\x93r\xf2\xb3\x00\xd3\xec\x99\xf2\x9b\x83&\\\xa5\xd3\xbb\xa1ji\x1d/\xa6\\8{\x15\x15Q\xe0\xaf\x1c\x8a\xcdu\xb6\x18\x8a\xe0\xce\xbe\x87T\xe3c\xb60Y\x0e\xf5\x08\xb8\xc6\x0eD`\xd1\x94e9\xc9\x96\xf2\x07AH\xb2\xcdPR3\xe2N\xdcI\xafB\xb7\xb0\xf9[\"U\xa9\xac\xc1w\xdf\xb7\x10\xb3f\xe2\xb2\xeeH\\l\x93b\xfd\xa9a\xe7\xb0\xcb\xce\xdc\x84\x8a\xd0\xc1\x00\xd4S#lr\xfbL26eI\x11G\x8b\xbc\x9d\xc4\xa5m\xb4\xcdI\xa3\x1eb{M\xee\xb3e6\xd9{r\x83\xb4\xec=\"r~\xc7\x0d\xe4\xd6\xe9\xb4\xdb\x00\xb98\xf3D\xba:\n\xc6\xf6c\xb6hV\n;m\x8f\xb3\xb2\x8fV!\xa1h\xe5\x1b\x8a\x96\xadVt\xd8j\xc57o\xb5\x1a\xbaG\xfa\xbe\x1bO8\xc7\xefF\xf7 f\x08(z\x13g\xd81\xac\xa5\x0e\xa6!8`\xa1\xd5\x12\xc7\xd4\x10\xd6\xee\x9aj\x11\xc7\xeb,\x1e\x12V\x04\xd0\xb8\xc3\xb2\x07\xd8af\xd2U\xf5\xb4\xef\xb0t\x93\x1df'\x9c\xbe\xd7\x0e\xa2\x95\xa8\xff\xdcJ\xb5\xe7a\xb6\xd2o\xe6\xd4\xfa\xbbm\xe3\xbf\xff\xe6\xbc\xff\xf1\xb7\xd9\xe6\xfc\xa5\x8e\xbf\xeaZ\xe4\xc1x\xc7\x99C\x13%\x90\xfe\x9a\x152\xeb\x1f]+\xef\xc6\x7f.:i\xcf\x84\x824\x8d\xf2\xbds\x0c\xae\x9e\xbaR\x15 \xbdh\xbeb\x93\x96\x8a\xabrx-\x15\xa7Ho8\xe68\x96\x0e\xcbQ6\xa0+\xdc\x94W2(}\xcd\xe1\x08\xfe\xf6\x15\x9cR\xc6\x12\xdb\x93\x08AW\xb9\xae\xb7\xb8T-.\xe9\xeaw-\xec\xf9\x95\xd05dD\xa4 \xfe\x8c[4\x97\xb7p\x08\xfeJ\xc3\x07\x1f\xad\xe2\xff\xf65\xe8E\xd3)\xde\x11E\x8b\xff\xe0\xf0\x11\xd6\xfa\x82-\xa3\xdb:%\xae\xaf\xf4\xb2Y/\xce\xcf\x8e\xcf\xf7\xfc\x80\xcb\xb0\xfd\x10\xa2J\xa0\xbe\na\xd2\x13\xb1\xf7\xd9\xf4\x1cul\xbe\xc8\xac\x0cC\xa2\xee\x8c\xcfXV\x08\xeb^\xe2\xbaU\xd1-\x1c\xd5\"\xf6\x89\xa6\xb2\xaa\xa9\xdb@\\\xa6\x9f\xca\xb4\xf4\x87`\x08\xfa\x7f\xfb\x1a\x82,\x0c\xe1\x96\xb2\xe3\xe3[\xee3\x1c\xc2i\xe9\xd1\xe0;\x88\xc89\xd1\xbc\x93\xa8\xf2\xf3|\x85a\xcc+\xd9\xf2\xd1_\xf24 \xa1`\x9f\x8bG\xabE\x14'!\xfc\xee\xd1\xef\x1a\xa8\xbcw\"\x82[\xee\\\xdc\xad\x98g4\xf6y\xe7\xf6\xf6vg\x96f\xcb\x9du\xb6` ?\n\xa6\xb6b\x13\x04\xb5\xba\xa6\\\xb3z3VL\xe6\x8eY }\xfd\xec\xd8'\x18\xd6i\x08\xde*\xcd\xcd\xdb\x0c\xf5\x94d\xf5\x9c.\x97\x12\xfd\x8dc_\xe0i\xe18\xf9e\x9c\x1bt\xf3\xe2`N\xb3!\xac\xfd\xa0g\xbfw}\x9f\xaf\xd2$gD\x03V\x81\xd5\xc0\xd7\xa0\xc7\xf92\xbf\x99[\x02\x8d+\xd3,KYo\xcaO<\xf7\x92#\xf5\x97.\x91B\x1b\xfd\xe5\x0bx\xaes\x0d\xd4\x15\x88\xfc\x02;9\xd5>\xa3\xed X/\xfd\x84\x0e\xcc_\xbe@\x06G\xb0hWw\x83\xa6\xf2v\xd0Z\xe8\xa8\xd2\x86\x8e\xeaqhP\x7f\x13\x16\x85\xa0T\xe0yG\x158\x94\x8c\xc1\xd8=\x00\xa9\n\xb7\xf9zP\xdd\xfd\x03\x00\x8f\xf5\xf2\"*\xd6\xf9\x05\xfb\xec\x9a\x08\x85\xe6\x98\xaai\x03<\xaf\xacQY\xa0l\xfch\x04D\xcb\xc5r\xb7\x89\x9b]\xf5K\xec\x90\x06\xae\xf9\xa6\x0c\x00P\xfb\xc4m\xf2C\xe7\xa6\xd2\x1f%\xdbh!M*\x17\xad#}\x03\x8bL\xa4\xcd\xe6E\x99\xdc\xb9\xc2sp\xfb\x10\xbc\x10\x98H\x16%\xc2\x04\xe0\x0ft\xee\xc5\xbf\xc6S\x96O\xb2x\x85b\x9e\xfe\x91\xf6\xbe\xf6\xa9\xfeA\x93m\x92\x96k\xcb\xf6\x0e\x02\xa0|\x86\x00\xfd\xec\x7f\xf3\x18\xbd\x01\x1a\xd7^\xfd\xf6l\xab\x10\xad\xfe\x14-\x17\x82\x81s\x99\x10\x95\x19\xa7\xc8\xe8\xbb\x98k*\x15!U\xeb&\x12Y\xb3\x89\x84\x91\xbb\xb6v\xb7o\x0d\xac\xd1\xd8\x94\xdedR\xea\x89\xab\x0bk\x0c\x87\x1cM-g\xea\xc6\xc4p\xb2\x19\x91\x0fT\x13X8\xa2^\xcc\xb3\xf46\xe1\xa8\xaa\xd3\x9f 4q\xfe\xb7\xb7\xf4\x8b4\x9a2a\xc8vq\xf6\xfb\xdf\xbf9\x1d\x0b\xeb\x8bs|\xf5\xf1\xfd\xab\xe3\x0b\xfdU3^\x98\x16\xc5\xbf\x14Z\xacUh\x86Flh\xb1=\"\xb4\x11\xa5\xed\x91q\xd2s\x0e\x9e\xd9 *PrH\x16\xe9\xf5\xf5\xe2\x9b\xcc\xd1\x08\xe5\xe5}\xac\xa1\x88e\x93\x064\xf9X@\x8ep\xc9&\x96\xbf\xfcH\xcc\xcc\xd3W\xa0D\x9br\xb2m\xba\x86\x1a\xfd\xbf\x07\xf6\x97\xafK;\xadL}D\x07AG\x03\xfd<\xc3\x8bmi\xae\xcf\x92\x9b\x9aA\x7f!\xcd\x17\x95\xc9?\x92\x1b\xe4e\x95}?\xe7\xbcr\xcd\xe0\x7f\x95\xe6\xc20[\xfdz\x1bq\xc1M\xf5%\xed\xb7e1\x9e\x9e\xd6Z\x90j\xe3\xf1U:\xbd\x1b#\xf6y\xb6,e5&\xb3T\x8d/\xfe\xf4\x9enN2Vx\xbfk4\x18\xd5\x1b<\x7f\x7f\xf6\xee\xfc\xb4\xa9E\xb1\xd3\x9b\x9a\\\xd7\xe1\xc5\xc14\xfe\xe3\xf1\x87\xd7\xc7?\xbc9%\xe6,\xa06\xbe\x91\x08/\xa7\x8d-\xde\xeb\xd8\xbf\xd1\x02\x95R1\xc2\x12\x7f\xb7O\xba\xc2\x0e\x1e\x9b\xf1\xad\x84/\xecc\xb3\xbap\x85}b\xbe\x16\xee$\xfb\x8f\xcd\xf0\xa8\x0b\xe19kjK&b,\xfbf\xf5\x99\x18\xcc\xb3\xc0\xf7\xe2\x82e\x11Fv\xaaWYq\xfe\xdf\x1f]b,\x14\x8c\x9c\x91p\x8e\x1a\xe2\x04\xe4K\xdf\xf4ui\x94\xd2@Sl\xcc\xe3\xbc\xbe-*\xc8:\xdd}Q\xfa\x9a\x87\xca\xd3\xd5l>\xf7\x13\xacdFQ\xe2+u\x17\xc2U\x08c\xe1\xea\xda\xae\xe0\xc50\x10\x98 \x0b\xf3R\x9c\x94\x9e\x8e'V~Z\xf5tr;\x15148\xe4\x1a\xf2\xad\x89J\x88\x9fM\xd5\x80\x96{\x1b\xebk\xdf$\xec\x16\x12\xe9\xa7\xee\xc8\xe7\xa6\x9eMT\xa9\x9b\x8c\xa8\xfbH\xec\xbe\x08\xf3\x13\xf4P\xc4\x10\xb5\xaf\x15B\xdb\x95>K\x07 \x0e[8<\xa4n\xe3\xce\x85\xd8k\xbd?\x11\xdc\x02\x1d#\x8e?\x9f\xe0\x10NF3\xcc\xfas2\xf2\xfe\xfd\xdf\xcb\x8d\x85\xafn8>\x9d\x8cn.\xed/\x8f\xe1\x10>\xa1\xc3\xb4\x7fC\xdc|\x9d\xc1!\xdc\xc0\x11|\x86#\xb8\xf5=\x96\x14Y\xccr/\x80!\x1c\x97~\xd9\xf6g\xe8\xd4\x85\xb1&\x84~\x1f\xfb\xef\xc9\xafyoF\x82@\x8e\xf5\xefQ\x1f?\x86C\x98\xf8\xefeT6v\x0b,\x08\x02\x8c\xe5i\x86\xbc\xe2\xd5\xc7\x98\xb3\x13?\\\xf8\xe3\x10N\xe55\xb7\xb8\x93S\xa8\xa0\xdf1\x8c%\x94\"^}\x16\xc24\x08B\xf8\xcc[\xc0\xbc_\xe5\x02\xf1\x1e?\x89X \xbc\xf5s\x19i\xf4\xb8#\x95\xf9T\x05c0\xb4i8\xba\xef\xbf\x87\xadk\x0c>\x8f[}\xeb\\,\x90\x1a\xda \x0e\xed8\x08a=*\xb8\xa8z\xcc\xff:\xe5\x7fMC |\xa49\xfc\xee\x9c\xf6ObNC\\D\xbej\xb7\xbe\x9a\xa6\xe3\xaeS\xc4Y^V\xd5\x91n8*\xcbU\x1d\xc2\x19\xb1U\xe0\x9a\xdeV(\xd8_I\x1f}\xfc\xff\x84O=\xe6S\xbf\n\xe1ntuI\\\xa8\xa2\x03x\xea\xa7\xbd\xf7\xb0\x0di\xefG\xf8\x1d\x08o\xff\xf3\x00\xe9\xef\x1d\x1d\x80e\xc3(\xf7\xfa)\xb0\x95\xf8\xfb\xfb\xa8\xd5\xddJ\xfc\xc7\x83\xc0\x9dQP\xf6\xf5\x04\xb6\x0e\x1d\x829?\x80\x0f\x02\x99\x9f>\x04/\xb2ds\x10\xc9w\x86\xedDL\xf5f\x83\xdc\xc0\xb6^\xe5\\!\xefg:\x07\xdaxLG\xc9|B\xe5\x85\xe1l\xc1^\xe0[9cd\xb0\x8d\x83A\xe0{\xafO\xc7\xef?\x9c]\x9cy\xf7\x0e\xb0\x11\"g\x92\x92\x894\x84\xc2\xd2z\xbdp\xc5M\xc3P\x82\xeb\x00\x12\x0ci\x89z{\x7f\x8d\xb0\xc0\xa8\x902\xc4/\xf1\xe1\xf32 \x0e\xbc\x84\xfcy \xbf\xe3G\xc0(\xdf\xde\xbe\x14f2\xff\x1d\xfb\x0bl\xed\xcb\x97\xaa5\x1a=\xcd\xa8\xe2\x9d\x17hw\x10\xf4T\nb\x1a\xa4\x99\xb8\x8fP\x95d\xd0\xdd\xcdzq\xa1\x01u\x0bb/\xb5\x8d\x0e&\x1d\xa7GN\x06\xd3\xac\x07\x8btj\xe4$\x8a\x08\xcdy\x8ca\xe8F\xf1%\x0c\xe9\x13\xc1\x0en\xaf\x07 \xad\x97\x1e\x19\x91\xef\xab\xc3hX\xffL\x86\x88:\x82\x08\x86T\xe4\xf8\xce\xd0\xdf\xdb#\xa0\x9f\x8d\xbc\xf1x\x92fl\xe7/\xf98\x9fG\x19\x9b\x8e\xc7\xe2\xa8\xf7]e\x87\xf0\xb7\xaf\xad\x1b\xcf\x01\xd2t$r8\xfa\xa9\xd0\x9c\xfe\xedk\xd02\x1f\x17=\xbd\x9fF\x91%\xeb%\xcb\xb8\xf04\x84-\x7f\x00\xdf\x03E\x01\x94\xf7\xb4\xaa\xb7\xeb\xa8w\x9b\xc5\x85\xaa\xb3\xef\xa8\xa3\x14#\xb5\x82o\xba\xd8\xa9Z.\xb7\xef\xfe\xe3\xc0\xdf\xd2\xb5\xd4\xfc\xddA\xe0\xcbh\xbf\xe0\x89?\xbc\xa6$\x1a\xa8g\x1e\x17p\x08\xd2\xa2\xaeT\xca\x8f\xe3\xfa\xcdG\xe8>U\xf8\x98\x98L}/\xda\xb3!Rj\xe0\xc71I\xc5\x12xyXQ\xc6#b\x15%L]<\xe34M\x98\x9d\xe0\x15\x86\x18\xcc\x0d2\x91\x7f\xa0\x9a\xdb\xf6a\x19V\x8f:Feg\x04\xaf,\xfb\x19\xd4\xfb\xd1\x10z\xc3cr0\xa0\x03R=\xde\xbb\xefv++4\x05\xd3\x8fC\x88\xc4y(\x17>\xf5\x0bS&V\x0f\x1e\x05~\xe2(\x15A\xa6]\xd1\xd2\xe4\x98rx\x01}\xe1\xd7\xfeR\xb8V28\x02\xcf+\x85\x00\xbeP1\xb6\xa4\x05/\xcc\x83\x00^\xc0\xe3\xc7\xbb\xcf\x0e\x90\xbd\x83\x97\xf0\xf8`o\xf0L4\xb4\x0d\x03\xe9\xa8\xc9iKd}\xcc+\x88\x06\x0e\xf6v\xb1\xf3\x887\xf0do\x7fO\xf6/\xeacG0\xc44H\xe2m\xbe\x88'\xcc\xcfC\xec\x04s\xd5D\xb0#\x9b\xd9\xe6\xe3\xdc\x91\x83z\xf1\x02\x06\xfd\x00\xb6\xe1\xe0\xf1\xe3\xbd\x83_v\xb7\x9b\xfa\x11\xa9\xab1\xb1G\x86-3\xe9\xbeT\xd5\x98\x1a\x9c\xb5\x0c\xf1a\x9e\xc6RWs@\xebj\x06\x96ng\"\xeb\x9b\x83\x94\xca\x9a'\xffT\xd6\x10\xcf?\x955\xfa\xf3Oe\x0d>\xffT\xd6\xfcSY\xf3Oe\xcd/\xa6\xacqjj\x06duw\x18\xd1\x03\xc7\xdd\xc9\xe3\xbe\x83o\xd3\xc2\xb3w\x12DQ\xfcL\xdb$\xa5\x0d\xf9\xca\xb7Q1\xef-\xa3\xcf6\xcf J\xe2\xa4\xc3 \xe9\x18\xb0d\xb4\x19\xf2\\}8\xe2b4l\x83\n\xc2\x19\xfb\xcc\x88\xc9\x0f\x1b\xac\x8f\x9e\xc8#4\xb2\x96\xc4\xb9\x9e1c%_\xbf\xceOK\xb9/,\xd27\xe9$Z0)\x1b\x95)Qpo\x9c\xcd\xbc^\xbeZ\xc4\x85\xef\x85\xde\x86\xec\xfb\xde\xde\xaf\xa2Dq\x04\xad\xdd\xa5\x95i\xc8o\xe5+6A\xfa}\x8f\x15\x95\xea\xb2H.hk\xca\x14\xcd\x13,\xc2CH\xfd\x16Q\x923?\nF\xf1e \x13\xef\xa4z\x92\xf3\xeeh-b\x17\x87J)h\xddR\n^v\xff\x89 \xab\\nL\x07/{`\xf2\xc4\x13Zs\xc2Y\xd9\x89\xca\xcdl\xb3\xb0\x93^\xce\x8a\xd7\xcb%\x9b\xc6Q\xc1l~u\xd2\x9b,X\x949j\xcc\xb1\xc6[a4\x7f2\x8f\x92\x84\x19~\x867X\xe3U\x9c\xaf\xa2bb\x98},m\xe5\xe55\x11\xca\xe7\xae\xed@CA\x1e\x0ea\x9b\x9fe6I\xe6'\xcf\xb5\x99:\x85\xce\x90\x01\x9a\xe1\xc5\xb5\x93\x9b\x95A\xd2x\x85\x10\n\x9f\xf0 \xa8\xbd1\xa6s\xd5\xcad\xdf\xc9\\ \xc2Q\xa5\xdeV5\"<\x96\xa7(D\xae\x1a\x9b\xac\xa5\xfd\x18]\n\xad\xed\xe09D\xd95n\xed\xbcR\xec&\xcf\x03\x95C\xa3,\x1d%\xdb\xdb\xe6I'\xf7\xcf\xf5h{{y\xd9\xb6\xd0\x02(\x7f\xe5\x0c&_\x87\x9b^\x92\xde\xb6\xb6\x86\xb5\x9c\x0d\xcd\xe1H(\x13|$\x93\xec\x16\xe6A\x8f\xd3\xbd\xdd\x10R\xfcc\xd0K\x93*\xb4\xf9\x95\x08T\x1f\xf9qo\x95\xe6\x85\xdc\x85Hk\x06\x18\xcfi\xd2\x8b\xa6\xd3\xd3\x1b\x96\x14o\xe2\xbc` C\x9aN.\x86\xd6\x00r{\x93^\xbc\xe4=\x9e\xa3\x17P\xceG\xd6<\xb5\x89>\x06<@=/\x04\xefw\xf54\x07\xf6\x88|ON\xc8C\xaejK\x8c\x1c]\xa5\xd2$c\xd1\xf4\x0e\x03\xee\x89p|(]/|O\xf8&a\xaa\x15\xf7\x88\xf2^\xb4Z\xb1d\x8a\xf9\xe8}\xed\xab\xa0g\xb7\xdc\x86\xc3y/c\xcb\xf4\x86\x89\xc6\x90g\x0e\xcb}\xea\xf4\x1c\x80\xa6\xcc\x959+.\xe2%K\xd7\x85\x86\x11\x9c\xe9\xa8\xbe\x0f\xeaF\xb3\xd6\xf7V\xa4Y\xa4\xd5C\x98VM\xe0_]\xb9\x15\xf7`\x1b\x9doh:\x8a\xeaF\x9a\x1f\xbf\x19\x02k'\x9b]\x1cv\xdc]\x13\"\x1f\xc8\xae\xdb:n\x81\xde\xa6\xec\xce\x13:D\xff\xe0I{V3G\x9e\x8f\x0cie\xea\x17vj8\x91\x90\xa8-\xb5q\xdc\x9b\xb9\xb2\xfe\xfa\xfd\x10\x92^\xc6\xf2tq\xc3\x02\x8cl\x8f\xa9\xfc\x96\xb1\x96\xdfjC\xc0X\x10\x10\x80yF+\x01\x91\x0dDg\x86v&\x90\xe2\x00\xe9|\xf3\x98\xc7\x8f\xcb\xc9Z\xdaT\x91wF\xb2x[[\x9c\xc9\xf3>\xb0\xeb\xd3\xcf+\xa4\x8di-%\xe6\x86s\xb6\xf8<\x95\xb0\x81\x9c\xf3\xe3{\xe1\x82ZN?\xed\xc9\xab7\x11\x9aA^\\\x89w\x9cK\xb10>\"\xc2\"F\xd2A\xc0O\xf0\x161\xeb\x9d\xa3C(\x17ac\xb7\x05\x00\x88l\x9e\xb6\nA&\x8c\xf1B\x88\xee\x0d\xc4g\xae\xdb\x84Zf\x97Nr\xa9\xa6\xeb\xc9\xea\xc9\xc57\x1a\xd1\xee\x9eC\xa69\xd8Cyc\x12\x15\xbe'\xf8)O0\x1dB\xc2\xab\x875\x9e\xd5\xeez5\xbe\xf4]\xb4d\xbf\x8e\x9c\xbdk\"\xa2\xdc\x934~Z\xe6\x0fR\x9aylj\xce\x854c\xdd\x9eKaf\xcf\x14Z\x16.@\xbc\x92\x0e\xc8\xba\xe4&\xe0&lS\x8e`\x01- peF$\xcc\x98'\xae\xf9\"\xbf\x90\xda\xb7\xd2\xccL|`\x1eH_\xad\xaedN\xa5\x92\xf4\xa6\xfeV\xd6\x9bii\xfdB`\xa3\xe2\xb2m\xc5\xcc\xe5Jp\xa7\x96\xb1C\x1el;\xa8D\xae\xf8\xc9\xa5\xe0\x8a-~\xa6\x13R\xb9Y\x94\xd2\xdd3\xf1\x1f\xef\x99\x18Ty\xeb\xd4\xfdr\xbat\xd9v\xed\xf4\xec\x80\xde\xa4O\xcc\xf7\xb1c3\x08\xf4\xb6\xac=\xe4\xbd\x93\x95tGS\x94Ey\x1e_;\xd4Q[\xb8\xb5[L\xaa\x944KE\xb4-\x1c\xef9\x92\x9c\xdf-\xaf\xd2\x05\x15[\x06\xb9\xe9\xe8j2e\xb3\xeby\xfc\x97O\x8be\x92\xae\xfe+\xcb\x0b\x8f<)e:\xd1'!dJ\xbf\xe4\x05\xbdY\x9a\x9dF\xad\xd1\x1a\nq\x86\x18\x0e\xadA(,\xc4r\xe1l\x1b\xf0\x0e\xca\xf3I\xdc\x95\x89\xa2\"\x08d\x98L\x0f\x93\xeeVn\x16_\xeb\xcc~\x9b\xd7\\\x84{\x9e\xc3\xdc\x94rC\xa49\x83PFK\x9f\x85\xa8!\x89{\xb3\xe7\x90\xc3KX<\xb7\xf9\xd2\xb2\xe5\x95\x90=\xd7\x9ap\xbc\xe0\xc2q(\x14!\\\xfe\xf3\xa7\xe510\xf1\xa7B\x98\xf1\xa7A\x88\x8a\x90y9\x86\xa5H\xc2u\x03/a\xf9<\x00I&\xa6!\xead\xe6\xa3eiQ\x95\x8cV\xa8S\x1f\xad\x1c2\xb8\x96a\x0d\x86\xdd\xb2J\xb5\xed\x9eA\x9f\xe6\xd7\x06\xa6nI\xec\x9e\xdd\x03j\xf7\xf8\xbc\xe0\x80s\x8f\xfe`\xf7 \xa8\xd9{<\xc5\xd7\x8f\xf7\x1e\x93)\x1a\xd6\xd4\x98\xa1t\xd7\xcc\xd2U\xae\xb9\xfdV)\xd4\x95_o\xc6f\xb9\xcc\xe2\xc7\x7f\n\xafh\x9c\x19\xea\xef5Jc\xf7\x9d\xff\x1d\xfb^\xd4\xdd\xa8\xd7\x9aof\x9c\x7f`\xd1\xa4\xd0\xf3\x10\xf2\xed\xa2W\xc9e>\xfd6\x9e\xb1\x8c\x85e\xe4\x82wg\x89\xc7\xbc\xbe[\x87e\xca\xf8\xa7\x8f\xbd\xa0>\xbf\x9e\x91\xd3\xbf\xbc\xaf\x0ceD\x05\xa2\xae\xcab\xafR\xb7\x85\xe0\xa9)\xd4u\x06\xfa$gi6a\x1f\xed\x00\x01\xe4j\x19\x1d\xfeX}\xab\x04x\xd6qp,\x04O\xeb\xba>\xbeE-\xab\xf1Z\xcfj\x9c\xd7\xf3#\xb3[X\xd4^\x1a)\x97s.\xd3\xe5z\x03ZkA\xfd\xcb8\x7f\xbf\xce\x98\x85\x15[\xfd&\x95AY\xd3r\xe5\xe2\x8di\xa5\xb9\x86\xa8p_\x82\x92\xf8\xcf\x02\x9b\xbc\x18\x0bc\xf5l\xfe\x90\xae\xafa\x861\x0c\xba\xfe\x07\x91\xcb\x13q\xb5k\x1fjk\x10\xf5+X;nb\xee\xbf\x04\n\xe8z\xc2\xb0\x07n\x9aT'\n^\x84\xef.\xf1\x17\xdf\xb8\xf5_\xbe\x97q\xdc\xed1q\xaf\xe4\xa1\xc9\xf0A\x7f\xd0\xdf\xfb\xc5F\x9a\xf8\x8f\xf7\xefm\x9d\x86\xe2\xd6\xd6`C\xd6\x98\x1eP\xed\x82\xf0\xfc\xf4\xe4\xc3\xe9\xc5\xf8\xd5\xd9\xf8\xdd\xd9\xc5\xf8\xfd\xf1\xf9\xf9\xf8\xe2\xa7\xd7\xe7\xe3\xb3\x0f\xe3?\x9d}\x1c\xff\xfc\xfa\xcd\x9b\xf1\x0f\xa7\xe3\x1f_\x7f8}\xf5\x0d\xees\x0f\xe65O\xc1u\xd7\x12\x0f\xa51\xe0\x01\xed\x92\xf7\xd82\xd0\x92v^\x074\xc3\xbd\xfb\xe4q\xdd^\xf4\xc9\xbe\xfe\xbb\x87)\x13=\x91k\xfe\xbcH3\xe65\x98}\xaa\x05\xed]i\xb3\n\xabV\xd2\xe5U\x9c\xb0\x0fl\xba\x9e\xa0\xd7gkKi\xcd\xdb\xa0j\xe9*N\xa6\"\x8c\xd0 \x1fY\xda\xa9\xb1\xd8\xd1X\xb4Z-\xee\xde\xc6\xd3\xe9\x82\xddF\x9d&\x189Z\x9ap2\x9fwia\xbd\xb1\x1b\x85\xe3 Ps\xe8\xd0g\\\x1bs\xd1\xd3o\xcb\x80\xc9|\xb0V\xf46\x8e\x8aFJO\x92.a\xf4\xb3\xda\xad/\xe7\xb1\x11\xf9\xc4\xb5\x98(38m-\x15\xf1\x16\xff\x88:\x9f0\xa5/\xc5BED*\xe5\xd3\xcf+\x8c\xf9\x00\xc5\x9c\x01K\xe6Q2a\x19\x14)\\1\x88\xca\xe9\xf6\xa8\xe8\x8ajq}\x16\x08C\xd9Z\x0d[+A\x8e\xa9h\x1bS&\xb0\xbf}H72\x99/\xa1g\xc6{j\xfb\xf5\x84pM\xe1\xef\xf1\x9e\xda~\xbd\x92\xa7W\xad\xa0D\x88)\xa9\x8e\x9c\xe1\xda\x8a\x1c(\xe2\xfa[X\xc6\x06&\xb0\xe8F\xe7MVS\x8bNM\xdc\xd0L\x8csAX\xd3\x82,\xd4\xe5]\xebj\x80v}M\xa5O\x95s\x98\xfaA\x08\xb32\x9a\x8dU\x0d\xb4\xa94\xda(\x8a\xd4\xdb\x0d\x15@\xea,\xb6\x06!\xef\xd5\x1e\x91\xfe(\xd9}&\xb23\x9f\xd9W\x14\xe63C\xfd\xc4\x84\xf9I\x08\x03\xda\x8a\x0b\xac]A\xbfu\xad\xe4\xd2\xbd\x92[Y/B;\x02k\xe9d\xf08X\xae\xf3\x82/\x19\xc6\xe2\x05!x\xe5=\xf8\x983\x98\xac\xf3\"]\xc2\xb2\xa4\xe8\xa8e\x88\xf2\xbbd\x02\x91\xf8\x9c\\^#-:\xeb\xa1l`\x0d\xe1\xdf\xca!Dw\x98\xb2}\x1e\xdd0\x88\x12(\x83\x1d\x83\x87jiPvG=\xf8\x89W\xb9K\xd7\xb0\x8c\xf3|\xc5\x16\x0b6\x85\x08PD\x89\x92\xe2\xe8\xdf\x1c\xa3Y\x11\x00P\xa7g\xd9\xfdT\x1a\x804\xce\xcd\x1dFs%E\x1bNSr\x7fA\x9a\xc2~\x85Y\x9cD\x8bEc\x1b\x03\xfb3\x9b|\xe8\xf6\x12\x9c\\\xcd\xc4\xd9 \x93\xa6k\x89\xe1\xb7\xb7]\xc8\x7f#3\xb6\x17\xa3\xc4aD\x92\xb6^\x80\x82\xa6\x92\xfb\xce]m\xe9\x0c\xc8\x15\xf7^\xbf{}Q\xff\x94V\"\xadI\xc3L\xb5hd\xec\xf1|}\x95O\xb2\xf8\x8a\x91\x11\x96\xafKq\x87\n\xf5\"\xe4'\x89$m\x92\x1f\xdc\x9bp\xf2\x93,a\x9f\x8b\x0f]O3\xf5H\x1d\x0f\x05Y\xf58!\xac\x1e*Th})BX\x8f\xd2^\xd4j?sS\xf9)\x11I\xacu+Fz\xb8\xdaJ\xb5C\x1a\x14\xb4 5\x91\x0e\xeb\x8b\xbb\x15\xa3\xe0\x9d^\xc9t\x89\x12\xd8\x8a\xec!\xac\x9d=\x96\xe4\xb6\xddJ\x9f\x95\xf6\xd4\xe2/\x7fn\x9e\xeb\xfaC\x93~@)\xa2\xe1pQ\xa2Ma9\xc3\xeaO\xa3\x0d\x82z\xd6\x89\x06\x7f;l\x90z\xba\x9cQ\xf8&\xe8\x843P\x0d\xcf\xf2&\x01\x81|\xcc\xc2\xc6\xf2\x05\x11)\x87\x0b]\xb4K\xecc\xeb\x0e0&Q\x91\xef\x94!x\xff\xfe\xef\x9c\xb9\xfc\xfc\x88\xff\xac\x07\x93\xff\x06\x89Z\x17\xf1\x1d~i\xd6\x9d\x8d\x14E\x1f\x9bWB\\\x1a(o\xc7\x84\xd8|I\x84\xc2Qfk.\x9f\x87\x9cp\xfa\xad\xd7\x10\x1eh\xa5Mo\xad\x8c\x1f;\xb9a\xb3X\xaf!\x92\xb9\xe2\xb5\x81\xe8\xa6v\xc1\x1c5\xea4\x90{\x89\x91{\x01\xcc\xd7\x8a\x7fm\xa1hS*\xdal^\xbc\xc0\x1b\x93\xc8b\xcbxs\xa8$\xe6\x1cIQ5\xd1\xb7\x9bH\x90\x1d\x17\x8e\x07a\xcd:\xda\xb3mY\xc8\xa3\xca-\xd7%\xba+2\xbe\x91\xf0I\x02^uV\xa1\xf7\x83 \xda\xe3~\xd0\x8bzB\xa3e\x82~cm\xd5\xa6\xf5\x9dkm.u\xc9\xcc0\xf2.\xacP\x97\xc7x_\xa6q9exIq\x19\xa8Y\x83^\xda\x8b/xQ\xc5\x18\x95\x08\xd0|\xda\xd0\xac\x8d\xdd\xf8\x80n\xbc\x18\xf5/I\x04)zBz\xf5k\xb0l\x18AWB\xca\xfc\xa2\x87j\x18\xc9\x80\x87\x15T\x88\x13\xc88\xec\x1fDq\xf8`J\xbc\x10\n\x15\x00\xb9\x8b\xf2S\\\x10\xd5(\xb7&}\xc0\x11xq\x12\x17q\xb4\x107P\n,*\xabr\x91\x82\xae\x9b\x83!\xa6\x1c\xbf\x89\xd3u.\xd3)gl\xc2\xe2\x1b6\x85\xab;]\xffP\x8b\xec\xaakM\xcb\xd1w\x81e\xb5g\x9f8\x9cQ-\xdb{y\xb1i\x1e\x19\xca\x84\x9frG\x1d\xc0#\xd3\x98]\xb8Q\x1cA=b\x02\xe5\x90\x86r\x0d\x1cA^\x1e\x07e\xc5j\xf5)}5GJ\x8a\xba\x13y\x06\n\x97Q \xaf\x1f\xfb5\xcb\x95\x82KXh\xc3kW\x8d\xf4\xaa\x0bL\xee!\xe8y\xc0\x17\xd6\xa3i~A4\xa6\x08z_\x18\x9fp\x1c\xe3@,\xf8\xaf\x9d5\xc7\xaa\x9d>G\x96d\xb3\xadS\xed{\xa7\xbd\x9c\x96\x0f\xa8\x84\x0e\x9e>\xe2\x08\x92\xb6t\x87\xa5G\x1f\xbe\xae\x0f^_\x0cm\x80Ay\xb6%\xfe\x9e2\xf0\xde\xdc\xfc\xb6\xcd\xbcag l\xbf\xe5\xa9\x8b\xb6\xf4}\x18j\xb1\x01\xd2\x92\xb0g\xc1s\xd8\xde\xe64={\x1e@*\xe8y\xe1\xb3Qr\x89\xcaT\x87\x1dh\xba\x19\xd4\xb5\x83\xf1\xc9A\xe0{E\xfaq\xb5b\xd9I\x943\x97\x15'}Hv\x02\x0eqA\xaf\x06\xb0C\xd8\x1c\x8bh\x97\x94\xaf\x7f\x81>_\"%\xc6!\xec\x14\xf0\x12R \xcb\x14\xb6\xd1h\x0b]\x81\x12Y\x90r|\x0c\xca\x8f\x12\xd8>\x844\x10\xe0\xe6\x1f'\xf2\xe3\x04v\xf8\xef\x97/1v7\xff\xe3\xd0\xcczU.h\\.U\x8aK\x95\xc1\x0bH\x9f\x07\x10\x8f2\xb4\xa5\x19e|$\xf4a\x17\xb7\xac\x92\xb9D|.\xc2\xc2\xd5\xf7F\x7f\xfe\xf3z\xb7\xdf\x9f\xfe\xf9\xcf\xeb\xe9\xd3~\x7f\x87\xff?\x9b\xcd\xfe\xfc\xe7u\x7fO\xfc\xec\xef\x1d\xf0\x9f3\xb6\x8b?glw\x86\xdfL\xf1\xe7n\x7f&J\xfbL\xfc7\xbb\xdc\xdc`W\xce#\xe9\x15,/\xdaM\xcf\xbabG\x08\x19\x85 \xa9\x03A\xe2\x86\xbdD\xac\x1a\xdee\xc6\x12\x03\xf8\nmo\xa7\x97\xb8v)\xbc\x80\xf8y h\x9e\xcfw\xd7(\xbdD\x0f0\xc76\xdb\x90\xb8U\xdbl\xf0\x9420\xae\x84\xf1J\xcdA\xc6\xd7\x8fI\"\xe3\xd6\xb3\xa0\xe1\x9a4\x04)\x9c\xf6\"\x05\xad\"H\x89[\x83\xa4M\x84US-\x99,ZQ-v\xde\x11(\xdeLXldhx5\xea\x13\xa6\xcf\xa0\xd6[\x04*\xb7\xc5{<\x0f\xb9\xec\xe5\xa7\xd5A\x17c\x1eHs\" \xc7)r`\xd7\x07`\xd7,q]e\x00\x88{9o\x14/\xb4\xbe|A'\xc1\xdaG_i\x94)\xbfO\xd8\xad\x1f\xf7N\xf0\x17\x97\xe38\x0bo\xe0\x13\x7fT\x15\xcc\x8e\xa0\xef\x9ax3\x94\xb3ng\x05\xfbd\x19\xf5\xc6\xba\x04}\x9c\xdf%\x13%,\x9b\x82tM\xd6vUZ\xeb\x95~\xcf\x12\x116\xc0U;\xd7k\xbf\xcf\xd2\xcfw\x97\x8e\xab\xf7\x16\xf9\x18\xad\xff\xdb\xc4\xe1\xcc\xe5F\x81\\\x0c:\x95\xe2_\xeb\xf2\xaf\xb8\xfc\xab\xcd\xc8\x86\xa2\xdd\xb6\xd6\xa1\xc52\xb8y\x92\xa5i\x17\xb5\x01\xdd\xeax\x0d\x11m\xff'\xfe\xb4d\x86jmY\xf8\x8fm\xd2\xecWj\x11\xf4\xd4\x10\x1b\xa2\xfa\xa0\x1f\xf8\x89\x7f\xb0\xff$\xd8\x88{ih\xd0\xdc%b\xf3\xec?i92\xcbKo\x19\xfa\xc8q\x80\nv\x15\xad\x0c\x95.\x06\x8a\x92h\xab\xa2-\xe53\xb4\x95\xfa\x89\xf0kV\xf4\x1c#\x02&h\xae\xaa\xf7\xc7x\x97m\xa7r\xc3\xacim\xdc\xee3\xda0\xe4\xc0\xca2\x14\xa1\xb1n\xed\x15\xa7\x07\xbbm\xd8\xae\xd8\x80<\x84E\x08\x13\x8a\x19@g\x02\xf8\x9e\x0c \xaf1\x8cv\xa9\xc8\xa8Dq\x07x\x1f\xc6\x019E \xfb3@\x1f\xdd\x97\xb0j&%\xc2\x8f\x9a\x9f0\x94nm\xce[\x11\xc5\x9a\xe85\xc7%\xb6\xdb\xbaq\xf08Kq\x87f\xbd\xbf\x96`\xe0\x12\x17?\xb63B\xf4\x04\xc5\xf9\xa0\xbb\xb8\xa0N\"!k!dE\xce\xfb\xdc\xc0\x0bX=w\x1d\xe5\x98\xa7\x96\x8c\xef\x02\xd2)\xba\x18\xdd\x10we\x1c\x00y\x80M\x8c\xf9\ns)\xd9\xbf\n\xe1\x0eC\x1d\x15\x88\xa1\x13\xcc\xca\xe8\x8b8F7\"\x9d\x13\x7fK\xb7\xa6\x99r\x8c]*\x1f^o\x1c`\xea\x9a8Y;\x92\x0c.\x0d\xcb:\xfd\xb9\xcaX\xf4\xc9*\xb1I!:\xa77\x8db\x0b\xa5\xf1V]V\xed\x93\xd8\xbf\xc6j\x9cA\xbd\x13\x9a\x1a\xbe\xfb\x17\xd2\xcdTl\x8bIP\xe1\xd2\xb50\x06p&\xbdl\xea\xb1 \n\xe0\x84\x04\x90\xd0\xf8*\xe2\xa7\xc4\x18+\x86/\xd0\x15\xee\xa3\x85\\\xdar\xe0\x8e\xe1|\xeb\x82\x90\x87\xc8\xa4'<\xcaQCZ\xfe(\xeaN\xe9\xf8\xd7\xbd\x84\x95o\x92\xf35\xc9\x9e\xc4\xac\x9a\x98\xefT\xcc\x97\x84\xa9e>N2\xbf\xf7$\xe8}\x8c\x93\xe2)\x8a\xb1\x0fr^\xee>\xa3B\x80r\xb1\x87\xbe\xc79\xd8\xbf\xaf\xe8)\xe2\xa5~\x93/\xddSz\xac\xbb\xedcr\xeb2b\xa1\xa5q(g\xf8l\x8e0\xf4_\xe6\xc7!$\x1dp\xa4D8x\xfc8\xf03\xc7\xd6M7\xebc\xd0\xa7\xa3RqN\xcd\xbf\n!'&v\x0d\x870\xf2X\x96\xa5\x99\x17\x827Y\x08\x7f5o\xca\xf2\"K\xef0\xb0N\xb4\x16\xef2\x96\xaf\x97\xcc\xbbt\xb9\x08\xdd9\x11&\x06y\x1b\xc3a\x88\xde\xe0ROf\xce\x154\x1aU\xe8F\x86\xb1]\x0f\xbd\xc9\xc5\xed\xd3\xdbt\xca\x9b\xdc\xdab\xda\x0b\x19Z\xd9\xb7\xeb\x99o\xbe|\xc1O3\xb9\x7f\xce\xca\x12\xc7\x1d\xa40r\x98\xc7\xd7\xf3\x9f\xa3\x82eo\xa3\xec\x93\xbd& id\xd5\xeeO\xed\x1f\xac\x89\xd1\x1d\xc1\xe0\x00\x8608\xd8{\xba\xef\x80Bm(\xfc,\xe0S\x12'\xa42\xa5\x10\xb0\x88\xaa\x82(\x90\xd9c\xd6!\xdd\x08\xc6\xfb\x9d-\xd24\xf3\xedr\x15\x96@\x08\x8a \\\xeeo\xca\x84\xed\x18\xe4R\xcb\xd8\x1e\x8b<\xe9\x9c\x8f\xd5_\x9d\xa4k\xf4\xa5W\xf5f\x8b\xf4V\xa4\x1a\xd7j\xb2D\xa4\xc8/\xf3\xb5\xb3d*\xe8W\xed-\x87\xb2\xf8\xb6|\x85.>\xc2\x9d\x05\x7f'\x8cM\x15\x91\xac5(Z\xa3\x8a\xd4\xda\x89 \x8aF\xfbbC\x9cO\xe6l\xba^\xd4G#\xf7\x8f\xf9\x12-\xe9N\x93I*\x87\xca\xacw\\\xae^\x17\xb3\xa7*\xe3|t\x1b\xc5\xc5\xab,\x8a\x13\x0dNr\xaeo\xd3\x8c\xd5\xdb\x9f\xa4S\x96\x99\xe0+{\x13oY\xf5\x8a\xa3\xc4\x1c/\xb2\xe6\x92\x82<\x0bzBE\xf1J\xb4\x15\xd8M\xb3[\x98\xfbU#\x81\xdd\x8fVX\xc3W\x97\xe7\xd7\x95\xdb\xf3\xcb\xa4\x1c[\x88\x8b:e\xb8\xaa8\x08>\xb4+\xd2\x95\x0dG8\xce\x8c\x03\x92\xd7\x17DK\x04\xa9\xa8\xad\xb8\n\xf1 \x14\"4\x03\xcc\xebV4\x06\xdb/w|\x10\xba\xd8f\x89\x1b\xda\x87\xea\xcdaU\x1a`\x14\nW\xdcx\x07 \xc7\xd5m\\\x16B\xeab\xe9%\x17\xc1\x0c\x88\xd8`\xabL\xcd\xe1\x08\xfc\xc8\xd8c\x9d\xf8\x04\xd4\x8d\x8b=\xac\xd6\xc9\xee\xa7\xaa(\xf1\xcc\xd5\x1ah\x9c{Y\x99\xb7\xde\xe4b\"\x94\x01\x8a*!\xd4%\xddRy\xd3\xc2*\xb1\xd06o\xb8N}aX\xb1\x91d'\xf6\xed\n\xa0\xb9xI\xb9\xfa!\x9c\x93\x97\xf7\x1ct\x11\x86.\xf2\x91f#\xbew\x82+B\x81\x9es&\xa2\xe4,zq.\xd8'?\x13\xce\x07\xfa\xb6A\xcd%e\xbb\nztn\xa5*1NKa\xa8W\xf7Mz\x9d\xdcD\x8bx\nI\x9a\xec\x88f\x1f\xc9\xc3a2_'\x9f<39\x9dz\xf0\xb8wLDnk\x02n\x11F\xb0\n!F\xe1\x93\x13p\xbf\xe4bb\xcc\xc7c\x0cY\x1a\x9c\x96\xf1\x97\xfb\x1c\xa3]\xf37?&\x93\xc5qi\x16\xb3\x0bi6\xc7\x1c6\xcdv\xde\xc6\xdc\x16\xbdY\x96.i\xdc\xc0 f\xfc\x94\xd6\x8f<{\xbe\x9aC\x9e\xe0({\xeb$\x9f\xc7\xb3\xc2\x0f \x9a\x15,\x03\x96L\x81\xdd`\xf0\x8f\x00s80\xb48\x10!\xfa\x10X\x02U\xbb\xb4\x8d[F5|z\xf6\xa3h\xd2\"\x0eQyd`nK\x0em\x8c\x0bXn\xda\xdb,\x96\x97{&\xb4\xa5\x8e\xaeJ\xf5\xa5\x8fw\xc0{\xfbT\xed\x9bz\x99\x0ci\x8c\xe9\x9ej\x03\xa2\xb0\xcfT,\xb6\xad\xd5\x16\x93`\xe2$\x84\xd5\xb9 \xdc$r\xc0/L\xe6\xb0b\xba\x98\x93\x8e|\xf5\xcd\xf8\xe3\x0e\x1a\x7f\xab\xd1xj\xc0E\xc9E}\xff=\xd4\xddEp)\n\xc1\x16\x1d\xf1)\x88\xb5\x9eFE\xc4\x97\x1ac s\xa0\xf9}\xb1\xa6\x1d\x89\xa2@\xd2\x92\xa6*\xe4Kx\x1b\x14\xa5\xad\x01\xee\xfb\xef\x914\x06\xa1XT3\x10d\xed\x17\xed\x94q\xa5\x87q\xf2J\xc6\xeb\xdb\x93\x9f\xea\nc\x82\x7fP\x01\xad\xea\xaf+\xce\xcf^bB\n\xae\x8d\xc7\x89\x80\x8e\xee\xfd\xc6\xfe\xf9 \xdf\xee,\x13\x82\x06\xbf^\xc5\x88,\xd5\xdf\xf5\n\xe3u\xa2\xd7)\x7f\x19\xb5\xaa:\xad\x87\x99\x90\x06\x10;\xd6\x8b\x05G\x10+\xccw\xbdq^\xb7K\xc37\"EE\x06\xe4\xf29\xc9AVG\xf4\x04\xcfoC{Th1\xdb|\xa4kxld&7/r\x15eu\x86\x9b\xa1;\xa1 \xfb\xc2\xba\x07U\xac\x9e\xf4\n\xc3\xa0\xa9\xe3*\x1c\x1a\x126;\xfcH\x1d&r\xcf\xb5\x9e\xe4\x97/_\xc2\xa0\xf6k\xb7\xf6k\xbf\xf6\xebi\xfd\xbb\x83\x10\xd8\xf6v`:]\x83\xe0\xb6\x03T>\xbd\xa8q\x17\x0c\xe7\xab\xa0\xa9\xcf\xbc\xb04\x06\xfd\x10\xfa\x1dc\xdb\x9c\xd3PPW*\xed\xc2\x97\xdd;\x97\xf3-e\x05\xc7\xfa\xa9\xef\xf1\xd7\xea\x9d\x17V\x8b\x1eP\xdfH\x9d\x88\xe2\x04\xd2*\xf5\xc6 \xba\xa3\x0d\xe1\xa4f\xe6\x02\x0d\xf3<\xa1\xe7)\x87\x04j\x92\x9e\xc8\xb0\x80\x0c\x87\xfe\xee\xc2N\xea@\xf7\xf3\xc9}\x82\xd4\xf4!\xc8\x82\x9b\x1a\x92~\xa8O\xf2X\x10\xd6\x8e\x13\xbb\xca!\x864\"\x01\x0bXV\x9c\x16\x17\x10\xce\x9c\xab\\\xeaK8x\x8bx\xf2\x89\x1ag\xa7>\xde\xb7\xaf\xb0\xc2v\xa1y\xa3zB|w(\xe6,eZ\x85\x90\xa8\xd9\x96\xe8\x18\x82\xb9d\xdarn6\xa5\x8bo%\x02\x88bS\xdf\xe3\xe3\xa9m\xeb\xe7\xf5AJ\x0b\x01\xa5|\xf2\x83\xe7\x86\xc0\xe3\x1a\xe1\xdb\xb6C\xc88z\x8eDWH\x1d-F\xa9{\xaf\xe3\x98\xdeu\x13I\xfaB\xfbU\xb9\xb0\x08\x07\x16\x0c7D\xe2\x15_$\x91\x93\xa4\x16^\x8a\xb8g\x92%;\xa6\xf4\xa0\xff\xd2\x15:\x99\xd8\x93\xcd\x1a\x02)Mx\xe2\xecd\x9a\x91$\x9f\xef\xc0\xb4\x95\x02\x0d\x01 \xa5\x0dM 1\x8a\x00\x8d\x9er\xfd\xa4r\x832\n(\xa9\x9b\xd0\xfeZ\x9al\x0d\xc3\x0f-\x99\xee\xcb\x17\xa5f\xa8n\xac\xe5\x8c\x87`\x89\xef\xa2\x9d\xb0\xfc$l\xd4\x01\xbd\x16\x97\xc40\x84s\x95q\x81\x13D\xd7<%\x81>T*\xa8@k-p0\xfe\xdf\x7f\xafzq\xb5\x8d|\xb2\x0c\xd0Q\x03\x8d\x13}\xa6\xbe\xc7\xebUJ\x82\x10C|\x18Q\xae\x04\xe4\xaa\x93\xc6\x96\x97q\xfcS\xe5\xf6\x00\x0b\x96\xe7P\xcc\xa3\x04ny\x8de\x94}\xf2\xc4\xb8P\xb9\xaa\xc0\x86\xcd*\xd1\xeeH\xad\x05\xff\x91\xe2\x95\x19\xde!\xa4b\xe1\x91\xbf\x93R\xf94\xc5\x01{A\xa8}_S\xa9HM\x91\x05@J\xa3T\xd38\x9aJ\xb5@or\x10\x1a\x82\xb0X\xc1\x04WP\xae\x8aX\xdaL\x1e\xf1}8*\x05\xbc\xa1<\"\x8f\x1cz-\xfe\x7f?\xd0u\x7f;\xa8\xec$gQ\x02\xd01\xa3\xa4\xdaJ\x9a\xc2C\xe2\x8f\x1a*\xea\xc6\xcbk\x94\xda]\x14?\xb0\xea\xa7\x9b\xa1 \x1ew\"(Z\xc3\xc4\x85\xa6\x80x\x00q\x8e\x81s\xe3\xe5JdH`6\x1d6n b\xcc2\xd2\xca\x8c\x96\x82\xd6\xf7B\xb8#\x8b\xa7Y\x14'^\x083\xb2T\xed\xcf%Y*g\x17\xc2\"\x109S\x8d\x8f\x13N\xaa'\x0deWd\x99\xa467AX\xc6\xbd\xde\x8au-!^\xeb\x8fo\xb3\xb8\xa8]\xbcn\x99/\x91\x08\x96\x9f\xcc\xa88\xb9_\x1b\xd6w\xe2\xbc\x8a\xc6\xb5E\xceP\x18\xeeM;\xc5\xb2\x8e\xeb\x06#\x1a\xef\x8b\x04\xf2\x8c\xab\x8cQ9^\\X\x17\"\xea!|\xeb\xc9X\xc6\x02\xc6\xd5.\xa0A\xac\xb20Pes 24\x00\xd4\xb2!8O\x05\xc4$1\xc1P\xb6\x14*j\xc5Jk\x1c\x8e\xbeBt\x91\xd1@k\xe4\x12\x1d&%qW\xa1\x0ej\x15^\xc2\x80W\xda\x11\xcd\xbe\xf3+\xfa/x\xcc\xad\x95b\xa2f\xd1\"g\x80\xddB\xc6\xf2U\x9a\xe4,\x04ek\x9e\x98\x17\xb0\xb5%n(\xdd\xde\x96\x93\xeb\x8bl\xca\xbc\xbdMw\xe3\xb2\x05\x88\x8aT\x15A\x08W~+5\x13\x08'\x10L\xbc\x17\xe7\x82\xc1\x98\x10\x11!\x9a\x06y\xed\xdcV-\x84\xf9\x8a\xa4 \xee\x8e\xee\x9ai\x93l\xbb\xf5\xb8\xd8\xb4\xdb\xab\xa6n\xab\xc3.\xe9\x89\xbf\xbb\x9d\xfdJ\x9e\x15;\xb1$\xfed7]o\x07\x00\xac`n\xba\xb1\xef*c+\x96L\x15P*/=\xb3D\xe4\x98iP\xa1\xf7\xc6h\xc2\x97\x0b\xe4\x91?F\xc5%\x1cA\xe4\xeb/\x02\xb4\xe3\xab~\xd7-\xb2j\x9f\x1e\xc2( k\xaf.\xb1\x8a\xf0\\J\x1c\x04OCeu`\x8b\x03\xa5\xce\x1f\x88w\x06W \x90^\x9e3|3\xc7%\xa1\x95w{\xc8\x8aU7r\x89\xbc\xcd\xf3\x03\xebR\xdf2\x82\xb1\x18\xf3&\x9d\xd5F*\x03\xf7\xdaWL\xd4\x90Jz\xc1\x1f\xc2\xc9%\xd6b9\xeb\x1c\xbdR\x11\xce\xe3\x9c\xfeh\xe0\xfe\x88U\xcc\xa5,\x87#lIXq(\x89Q\x96\xe1Qi8f\xd8^\x19\xfa)8\x90\xd6\xf0j\x11KvA\x18\x13%R\x92%p\x18\x9d\xfd\x9c\xfcB\xe9\xf0#\x0f\x0b'\xa8S\xa8\xcf\x9c\xde,\x9b\xce\x8an\xa5\x163\xb4\xff\x1cb\x0c\x15\n\xf1\xf6v\x00\xd9(\xbet\xc1\xa0Qak\x19\x0e\x01I\xa6nd\x9c\xc3w~Q\x9d\x9f\x0d:8D\x89H[l\xf9\x99\xca\xd9\x13\x850\x08\x0c@\xec\xa0\xe4cc\x93d~\x14\x08\xe5_\xa3\xfe\xa5\xb6{]\x0b\xdf\xb49S\xeb\xc6\xb5Ib\xcek_Vn\x10\xd2p\x83\xc60A\xd1\x05g\x12\x94\x82\x98\xdb\x00\xadT=(\x02C\xf0l*FRe\xb3\xa2\xdao\xc1\xe5.B=\xe0]Q]\x89\x9c\x11.G|\xe7R\xef\xc5\x85\x88\xa5\xc9\xc9\x1c\x0eM\x99\xa6\xec\xca4}\xcey\xa9<\xd4\x04\x853\xb9\xa6\x9b\x1c\xabM\xeb\x1fM\xcb\x93\x0e\x0e\x0d\xcc\x08\x0dU1\xdav\xb4\x98\x19\xde\xc8@\xfb\x9d\x00]\x9e\xb9\xc6QS\x9d2\xcc`\xf7[1\x15\xa4YJ\xdd\xd0D\x19\x1fY\xe6'\xf5\x1b\x88\xf7\xa4\x01\x12\xe0\xd9*\xd1<\x08(;CC\x0f\xc5\xb9\xdb6@U\xaaV\xbe\x8b\x04\x87\x0dr\xb2B\xc7\xd1\xb0E\x82\xb0\xe3>\xc2\x83\x1b\x99w\x87\x05e\xfd\x1c\xd1\x14s\xf2\xab\x0e\xd3\xbd\xcd\xa2\xd5F\xa7\xbb\xfb8\xef|\xf6g\x8e#\xa2<\x1eR\x8c\xc7\x83\x0c\xa5\x10\xa7[\xc5^NN\xa6\xbe\xc7g\xb3bS\x90\xc2}R\xf7\x97P\xba\xf8f\xc9\x99 \xcb\x87nnP\xf2\xec\xd6\xaf\x0f\\Z3p^c\x16\x9a\xa9\xb6\x8d\xbc\xa5&A\xf2\xd6%,HW4\xfe\xe8\x90P\xc2i\x0d\x14~Z\x9b\xa3\x90SS\x8e.[\x89\xe17R*\x95QS\xafY\xef\xa7B\xa4\xf7\xcd\x0f\xb0\x9e\xb2JQb?\xce/\x0d\x04\xd1U\xba\xf1R\x90\xa4\xb6l\x806\x93\xba\xcf\xd4<\xceG\xe9%\xd4c7kR\x81,\xf4UE\x0d\xa9\xdb\x1c\xee[\xd1K\xab\xcb8\xf3/B%3=\x85F\xc7\xf5\xfe\xca\xe1\xdc\x80\xfa\x1agt]^1\"\x83\x84Hp=\x8a/\xb5\x9d\xde\xbb\x8a\x93\xa9\xa4n\xbc\xa8\xc1#\xa7\xd0\xbd)\xdb!\xa3\xa1\xd0X\xde\x1f\x16\x81\xf2\xfe\xce\x14\xe7Z\x89\x11\xf6Di\xda\xd3\xc5\xddD\x91\x90\x9ao7\xe9z\xc2\x92\xf5\x92e\xbc.\x97\x13lj\xb3\x91k\nEak\x17G\xf6\x1c\xeb\xb3C\xbf\x8f\xf1,K\x97\xfcT\x86Cx\xfb]UV\xcf\xac\x10b\n\x1eG\x82\x05C0\xae\xe5j\xb0\xe3Mti\xa2-\x1b\x90\x88\x99Q\x16\x94\n\x83\x94<\xaa\x1b\xb4,_\xc9Q\xd7?\x97~,\x1d\x0c\x8f\xee}\xd7\x03m~D\xee\xd0\x02\xe23K;M\xbc\xaeZsn:\xf4\xb2\x8e\x84\x9f\xde\x11:\xe1\x94\xd6\x9b\x1b\xf4\x83p\xae\xb1\xb3%\xd3\x93*yA9Y\x08s\x9d{\xba6i\x17\xa7\xd6\xc0\xfcF\x08\xd4?\x96\xaf\xfd\xf2\x04 ;h\xb8\xb7\xe4=\xce\x11\xe7\xcb\xf5 &bv 5(\xf3e\x1dV8(\xbc~E\xd0\x92\xfa,\x87\x9cU\xfbYzd\xb5\x10\x93{\xc3}@\xf3w\x99\x1d~\xc1\xf2\xa1\x996\xb6`\x84u\xf8\x96\xe5\x1d\x90\xdf\x12#\xb0\xca\xcd)\xd4+\x08]Vs\x1b\xc6\xa2\x9aNU\x06\xf9\xe9\x9ca\x87\x0c\xc8\x96\x95\xa1g\xaa\xfbvDd\xafL>\xabG\xcf\xca\xd9B\x04\xb5\xe4\xff\x7f\xf9\x02\xb7q2Mom\xfa\x92\xd2\xe1\xef\x91\x93p93\xd1Y.\xa0\xc4\xb4xZ\xf9N\xf5\xc6h\x89\xfd#\xd2K\x07x\xf0\xcb^\xce\x8a\x8bx\xc9\xd2u\xd1Q\xccI\xd8-\xc4~*N\xb0\xeak\x8c\x87P1@!\xe0\x00d\xa1\xa5\xb7\xc0~_'\x05\xcbn\xa2\xc5=;V\x9f\xd3=\xabR\xa2k}d\xa8\x80\xa9}\xd0*\xffH.\x1f5\xb1\xbe\xd5|\\S\x97fl\x86\xb6\x91\xba\xec=3\xe6k|\x84\xed\xb6\x81\xa4\xb6\xc6\x02\"YX\xe2\x011g\x96d\xe9b\xd1EA\xa4C\xc7g\xbc\xb9\x05\x93?_OQ\xfc\xd0_\xd9\xf8\xc5{['D\x7f\x0f\xd2\x99i\x0e\xc7{\x1b#\x9c\x8f'E|#\xb4\xaf\x91\xfa\xf3[:\xa7/\x08\xe5M\xaaV\xd5\xaeW\xc0\xcbC\x99S\xc9l\x15\x0e\xa1\xda2~+/\xcaz\xe34Q\x93\x17\x97\x12\xe5o\xea\xb6\x87p\xb9\n1\xa4\xd5n\xa0\xf6\xdcr\xc9\xa6\xb1\x08\xce\xd2N\xc2\xea_Ta+*Rh\xd5\xe08X\xb2.za\xb9\xf36\x1c\x82\xf1\x0d9\x08\xbbNm\x18\xf5\xe2\xea|\xe8\x94\xe0lc\xe6\xd9\x11S-Eeb\x9c\xebq\x88\x9a\xf1SY$\xe1\x9d\x82\xe7\xc16\x17\x82q\xbeE\xfa&\xbd\x15 \xc9|\xa7\xfd7\x1a\x11ys\xf6\xd9\xa3\x8d{D9FBj\xa9\xb0\xd3\\#\xca'q\xdcX\xe3*N\xa2\xec\xae\xb9J\x94\xb3\x83\xfd\xe6\x91L\xf2\xdd\xb6\n;-5\x8a\xd9\xe0`\xc1\xda\xea\xec\xb4V\xca\xa2[G9h\x1e\xda\xfd{\xda\\\x95\x1e\xde\xf6\x16\xaf\xefnG6,\x8a\x931\x08\x95B.\xdc \xac\xab'\xb8\"\x81\xed\x0c\xbc\xba\x90\x92S\x11x\xd6r\x11T<\x7f\x1e\x94\x03s\xb6\x0c]p\x17:\xe1\xafz:\x0c\x12\xba\xa0!tBE\xe8\x88\x8e\xd0\x15%\xd5\xa3M\x03k\xb7\xcdd\x11\x15q2h\xed\xbdq\xf7\xaaG\xf5-\xdbl\xeb\xbaq\xbbC'\xd2\x02\x1dh\x9cz\x94\xba\xae\xc1\xe8\xa9mO\x82r\xb1h\x0e\xb2\xa5\x1eN\xb3}I\xb4\xeb\xf4ZD\xa3\xd0R\xd8\xea\x0f\xa5#\xa4n&\x1d\xd1{\xc5\xe5b\xed\x989<\x94\xd1\nE\x120\xdb+\xc4\xfb\x98|J\xd2\xdb\x04\x14\x15\x18\x82\x18\xb6[{\x88V{uJT\x05v(#\xd3Q,W\x07\xb4\xc7F\n\xf6\x99C)/\xdb\xe4\xac\xd3B\x80\x8e\x88\xd1\x08n#\xd7VR\x81\x1d\xcc\xe2\xc5\xe2M\x84z\xba\xf5\xfd{i\xc4j}^\x93\xda\xbcf\xa2\xc7\xbd\x8dzlDX]\x89),\xc0\x0ea\x15\"\xe7\xe4k\x1d\x9b\x92B\xed\x17\xd6[Dy\xf1\x8e\xa1\xa0\xadB#\xf2W\x17i\x81\x92\x92\xfe\xeed\x1e \x9f:\xdd\x1f\xb0\xa6\x0d,\xff,\xcf\xaa\xc8&\xf3\xa5\xa9\xc5\x8bC\x18\xec>QIb\xe0\xe5Kx\x0c\x87\x87p #B\xe3\x9b}\xfef\xb0\x0fG\xb0\xa7^\xed\xf1W{}8\x82}\xf5\xea\x80\xbf\xda\x85#\xd8\x19\xc0\x10vv\x1b\x87\xb4v\x1c\x9fJ\x1bXM\x7f\xa7\x0e\"[\xca\xdf\xc4\x05\x1a-Ov\x9f\xf2\xbd\xec\x0f\x9e\xed\xc2\xf7\x98\x14<\xd0\xac\x99\xeaK\xe1\xfd\xdf\xff\xd7\xff\xe9\xa0\xb2\xe8cTU\x97\x16\x83\x9ak\xd8\xa0\xe9h\xa5\x062p\x0dd\xd08\x10\xa0\x06\xb3k\x0c\x06\x7f\x9b\x1d\xee\xba:\xdc\x95\x1dv&\x9e\x85T\x88>\xa7\x90L\x93$\x12t\xb0\x1f\x1aX\xffB\xf36\xc3x^\xe8\x97YCy\\V}\x1f\xf0\x0f\x03c_\x94\x89\x0d\xeb\xfcVho*\x11\x17\xac\xa9\xa32\xc2\x99\xbe\x9f\xcb\x11\xefh!\xd0\x9a\xf7^N\xaa\x00\xf8z\x95\xd9T8\x8a\x07\xf0\xaf\xb0\xcb7P\xbfI)_\xa5n\xf4K\xf2\xee\xb6#i\x0e\x04\x80\xd7\x91\x93y\x94\x9d\xa4Sv\\\xf8\x9a\x0f\xac\x199Z=\x18b\x9f\x8b\xdd\x8f\x1f\xef>;\x004\xcc\x7fq\x08\x8f\x0f\xf6\x06\xcfj&_\x06.Y\x04m\xdfX\xb8Q_\xa4-\xd6 \xb2{i\xd6\x19Xu\x06\x97!$\x95\xa3\xfa\xce\xe0\xfeF\x1e\x14\xde\x9a3\x19\x103\xd9m\x9f \x1f\xa5c\xe1*4C\xa87\"\xd2\xc2M1\xeb7\xe2G\xda\x81$n?\xa8\x9c\xec\xf5\x8d\xd4r\x11\xe4&\xc7\x0d\xdc\xcb\xb6ksj\x10\xe8\xdb\x01\xc1\xc8\x95h\x84\xcc\x84\xdcbj\xfc\xd66\xdb#\x89T_z\x9b\x1c\xd5\xd6J\xb2\x1a\xd2\xf1\xcc71b\x0fv !\xb0bOY\xa4%j5\x1a\xf1\xa3\xd6\xf47\xed\x87 t\x0c\xbf\x86iI\x0b\xcd\x9a=\x1c\xaa\x91[\xe9\xa8\x11;\xcaA\xf7C\x04\xb0\x81\xa9\xc3\x16lX\xb9\x99\x1d\xc7\xf9\xd0\x0c\x8ci\x03\xf3\xd4\x06\x0b\xada\xf5WQ\x8f\xe7\x06\x87\x10\xd75\xd3\x8a\x91t\x0b\xff\x95\xcdmy\x06\x95\x82\xa1\x01~\\\xb6\xd0t|\xee\xb4\xff\xe3*\xef%\xfab\x96\xac\x99b\xe2\x85\x9c\xe3\xe8\x18t\x03%\xd5Mhs\xbb\xf5\xbd/\xec\x14\xd1\xe5\x9bD\xa3\x04c\x92V\x00\xd71\x89\xf3\xfc\x9c\x10$\x81\xe2/\xeao\xf0:I[\x91:\xd4\xa5\x88\xd0xK\xf5\xc0\xf8\x8f\x1cV\x1d\x9d\xebc\x92RL\xe3]\xc2\x8d\x99\x17\xbd\x81\x01\xae\xec\x93+\x8aAs\x0e\x19\xbc\xe0M(\xd2hW\xba\x91\xd9\x03\"\xbf\x18e\x97\x0e\xfe#E\x0d}\xd9L\x8a\x8e\xbcB_\xaf\xa1@\x8aG_\x08)\xdd\xc8\xce\x0e\x0e\x86\xaf\xde\xce\xae\x10\xb3\x9b\x06\x86\x8c\x956\xb2\xa0\xf3\x18v\x7f\xfd1\xc8\xb60\xf8\xce\xa1\xca\xd2Y\x1f\xd5\x1e=*\xd5y}\xfb\xb8M\x8bQOhly\x9b*\x96\x01\xfb\x8d\xaf\xad\xf3-\xb1\xa9\x8c\x1e\xa0\x01v\xc0O,\xcaMn\x0c\x9a\x05\xef\x0b\xcfijh\xf5|a\xf5\x0d\xa3\xa9\x17\x9a\xa9g};\xbe \x08\xa9C4h\xe4\x85\x1eT@\xa9C\xeb\xde\xc3\xd1\xc4\x98\xfa\xa45 \xc68\xa5\xeeu5\xa3\x9b\x1ei9Nn\xb4\\Pt\xa63LcS\x164\xa9\xd7\x11\x87\x11\x04\xb5\x84*\xf5\xb4 \xb1\x9d\x01\xabfu_Zc\x14Y\x94\xe4\xb34[\ns\x0c\xca3\x06C\x83_\xa8z\x1dl\xa7\xc0d\x9b\x8d^h\xa9*\xe9\x95\xb5\x9a]9*\xb1\x0d\x0f\x9c\xc9\x95[J\xdb\xca\xea\xf2\x983v\x80\xe068\x84\xae\xa2\xc9'\x15\xaaf\xb9^\x14\xf1j\xc1\xa0\x88\x97,w\x86\xbcW\x03\x99\xaf\x93O\xa5\x9bJ9\xba\xea\x8d\xcc\xfaW\x94W\x852ut\x88Y\xf8\xdc\x93M\xbb\xda\xc5\xf3'5Lw\xfc\xd4\x8al\xaeLd\xe1\x05\xa4D\xe0\x8d\xaa+\xdf,\xb6z\xfcZ\x99\x81Ri\x04\x19\x9bj\x88C\x99I\xeakN\xd7\x90`\x14\xf1.\\\xc5\x1c\xf4\x8d5*u3\xafT?/h\xfb%\xc2\x13\x83\xaa\xa6E\xf3h\xcc-RNT3y\xaa\xde\x1d\xea5\xdc\xa9Ff\x8bu>\xd7\x1a\x10\xbf\x0fU\x89\xb2\xbaG\x9b\xedU\xc6J_\xbd\xa8M1J\xf1S\xca\x1d\xa3\x8eg\xe4\xc8\xf4\xd1\x1c\xe9\xbfj\x99\xd3Hnl]\x12\xd7\xfa\xa2p.r-\xc9U\xb5\x7f\x9a\xe7\xb1v\xb1}\xb5\xab\x14\xc2\x88\xd4\xe6\x12j\x99GY\x15\xee\xde\x8a\x14\xa0\x0eL\xeb\xa2\xe3$Z,\xf86\xac\x16y\x9a&\x0cn\xe7,\x81\xdb2\xa9\xd2\xd6!\xf4\xcd\\\x86B\x8bi\x10\xcd\x1au\xdc\xb0\xbb\xbc\x88\x17\x8b\xdaV3\xbb,!C\xb8\x03TB[j\xa5V\x0b\xb5w~,\xd8\x95x\xc3\xe0\xee:\x816']\xa3 \xa5\xdfS\xbd}\xcb\x9d\xac\x1ay}0\xb5\xfd\xd6&)X\x00\xae\xbev\xc4\x98qvk\x8b\xb2t\x97ug\xb3\xa63\x13\x85\x13\xfd\x80\xe1P\xa9\x1dB\xac|\xa3]\xb7\x17!le\x06\"\xd1\xf2Q\xe7#\xc7\xcf\x8c5\xc2\xf3\xe5\x17:q\xbe:Al:\x174\xdf\xaa4\xc2\xb6t;)t\x88\xe25\x82\x02\xb8\x88\"\\cW0\x0c\x93\xc9\xc0\xf4-.\xcb\xd7\x1b\x0dU\x93\x15\x03\\\xf4\xea\xdc\x960!\xb6\xb7A\xdf \x89\x8e\xa9\x1at\xfe\xccd\x14\xed\xd6\x8c-\xd6l\x90Q\xf8\xc2fZ\x10Y\xe1Cn\x12w\x83\xb8\xdc\x8b\xd7\xd6\x98j3\xeb$G_\xcc#\xa9KEiv\x1aM\xe6\xf5\x8aq\x95\xdf~\x92\xb1\x1a.tK\xdf\xab\xf0*\x16D\x93\xa4\xaa\xd2\x8a\xb4\xb4\x1am\x03 \xe7\x069\x8eug\xb4iV\x10M]\x12\x99`\xbe\xc08\x80\xc0F\xc9\xa5U\xf9\xab/\xf3f\xa3\\`\xaeUX\xd34\xc2}\x97\x8b\x84g\x00\x7f\xfb\x86&5\x0c\xd0Sen\x92\xb7\x16\x89\x1d\xb9jq\xfe.z\xe7c\xfa_\xd4b\x14B\x7f\x817w\xdf\x7f/\xd5\x15;\x98\x9b!\xc5\xe8\xd6\xc32\xfc\n^ \xb5\xa7O\xef4\xc7\xba\x0b\xce\xc1\x93\xa7\x81\xcf\x87$\x916\xca\xf3\xf8:\x81!\x16=\xfbV\x9b\xc2\x10\xd2\x10\xb3\xc9\x85\xb0\x0eA\xf5h\xec\xadNv\xbd\xd6\x85\x05\x7f\xb4\xb8 Evg|E{g-B\x90Q\x00I'\xacI\x9a\xcc\xe2\xeb\xb5r\xc3\xea\xd3\xcc\x7f\xe4t\xd2js\xe2\xc2,\xd8C0\xcc\x80\xb5u\x85IT\xda\x8fU\xa7\x93\xb8\xf4Xhw\xb9\x99%Y7\x0f\xdd=\xec\xfa\x90\xab\x91\x88\xd0\x86$\x14\xc3\x8d\x13\xd4\xa35\x0cJ\xa6\xa5.\x0b\x1d!ez\x0d?\x13\xf9\xc1\x05K\x81\x9eZ\xd5*e\xfa\xad\n^\x17\xc9\xd4\xd2\x83\x83 \xc4\x8c\xa8\xa3\xcb\x10\xe2v\xaa\x1aR\x1ap\xce\xf9\xacG\xec\xb2d\xe6\xf9\x8fz\x15${\x05\xf6\xf3\x1c\xd8\xce\xce\xf3@\xb9\xb9z\x91\x07\xdb\xe0oo'A\xa5\x82\xda;0\xe5zM\x8f\xa2\xdc&|o\x96\x88\x9c\xb9XTJ\x1c>o\xb0\x90Q\xeeC\xf0\x02\xd8\xe6\xff\xfcM\xb51K\xa4\xc3\xa68;+\xc7\x81\xe7\xf0\xf5y\x9de\xec\xbcF\x04\xc5G\xf9\xc6\xb1f\xaeD\xf2 \x9eZE`\xa9\x1e\xec\xbd\xc9\x9f\xc8OB3\x01\x95\x03\xfd\x81\xba^\xfe\xfa\xad\xc4I\x88\x1cT&u\x1a\xe9\xeb\x00\xaa\xaa]\xb3\xe2\xec6Q\xd5^\xb1|\x92\xc5\xab\"5\x0c\xa8#\xd7\x07\xef\xa2\xa5\x19\xd3d\xed\xaa{~\xb7\xbcJ\x17y\x87\x93\x89\\cA\x82\xe5\xd1\x9c\xf9\x85\x89\xa7('\xea50\xca@\xe4\xe7\x81bv*\xf1\x9b\xce-G\xae4\x7fpOg\xa1H\xba\x9eQ>\xb6\xfa\xd2\x93M\xa0\xa1\x86\xfd]\x1d\x81\\\xaa\x0e\xcc\xe7\xbe\xfe\x07\x9b\x89n\xe0SJ\xe8\xb4\x9c\xfd]\xbd\x95o\xdc\x15\x8f)\xfe7\xf1\x07\xfb\xe6n\x89iO0\xce\x9e\xde\x17I\xf9\xc1Fd\xc2\xe3\xfb\xa7\xa4v\xa3\xddK\x12\x0c\x19\x92+\\!\xbd#\xc1\x87\xac\xa9\xe5HF\xd9%\xfa8)_\x8a\x08\x05\x12\xf5\x85\xb5$I\x0b\xa0\xf5>\xba1\xfcr\xe8[[R\xdb'B\x10\xd4\xd3\xc8}\xf9\xe2P\xe0![\xefR\x10\xceY\xdbh;\xa1\x05\xcdH\x15!x\xe31\xcb\xdf\xa6\xd35\x9a\x9c\x98K\x89\x8c\x8e.W\x06\"\xde<\xda}v\x81\x88\xbdX9\x17\xae\xdf/\xd6\xd7q\x92\x0f\x1d{\x8be\x99\xab\x08\xb0\xed\xe9z\xc2\xb2|\x08~\x9f\x0b\xbar\xe9\xcd\xe2E\xc1\xb2\xee\xc4\x80\xf5>\xb1\xbbs\xf6_~\xd0c7,\xd3\xc8\xb4\x13\xb4`u_\xb4d\x0bD\xa9mT4d6Q\xb2?z\xb8f\"\x16aw\xb2\xefDg\xd6[\xb2\xec\x9a\xf9N \x19\xc5T\";\xdc\x06X0\xfe\xe1O\x0f\x8d\x08\x9a\x1e\xa3\xf2 N~\x0dtH\xe8pZ\xbf\x06\x805)\xb2.\xc2\xc5B\xe5\xb6k^\x97\x89\xcb\x0f\xf3m%\x94\x0f:\x0b\xe5j2\xa6\\./e\xec\xc9\x95\xaa\x03\xc3{\xfa;\xfb/>\x83\x85uG\xc5\x19\x9b!\x18WS\x0bv\xc3\x16\xc32`|\xadl\xc9\xf2<\xba\xe6Go\xe9\xe6\x8d\xb5\x8c\x1e\xff\xbe\xa2\xb7K\xaf\xd5\xa4\xe1\xb4`\xfb\x97\xfc|\xc5&C(z\x9c\xc98W\xda$\xfc\xf5\x87\x04\xd6\x91\xb28f\xf35\xe8\xc0\xb1\xaaok\xa2\x80\xd8\xa1\xf8b\x15 \xbe\xc4l\xba\xc2G\x87\xf6\xf0\xc9\xae\xa9\xd4\x7fH\xed!Er\x08\xf7\xf8\xff\x15\xf4\x80 \x87\x8e7\xd3\x11\xd2\xe4]q\x8f\xc6\xff\xdc\xab\xfe\xdc\x0f\x02a:\xf3\xf7'_\xb4!\xa3\xeb\xc0\xe8\x80\xc67e\xb41\xc4ZI\xc7\xbd\xa0\x17'S\xf6\xf9l\xe6{\xd2\xe21\x9dA\x84g\xbd\x9f\x07\xa6\x11)\x947\xd1/a\xc7\xe9\xf6\x7fS:q\x1b] \x07ft \xa3:S\x96\xb6\x98\x05\xa1\xf0\xbd\x90\xea\x1e\xf4i\xe7z\xfb\xa1\xab\xc3>\x92\xd8\xed\x0ebB\xadqq3\xe1\x9b\x88\xd0\x90\xd7\xcdh\"\x91i\xdc*'4\xb1\xab\xe5\xef\x970\xc0\x83}\x1b\xbc4\xc3\x18)\x05\x0c!\x1b%\xb0\x0d\x83K\xa3\xea\xae\xac\x8a\xc0\x0b\xc1\xd3kj%X\x80\xbf\x9c\x03\xfc\x1a\x82\x97\xcf\xd3\xf5b\nW\x0c\"\x97Z\xc3O6\xc9$\xe0&~\xbf\xe9\xfdD\x9c\xbdEO\x1c\xfc$\xa1\xd1nu\x1dD}\xb0\xf7TCZ\x071\x0f\x91_\xfcMC\xe6\x1b(\x8dkw\xfa\x14\xf9\x11&@\x9e\xf2s\xeay\"e\xeaj\x11M\x98\x9f\xb0[\xf8\xc0\xaeO?\xaf\xfc$\x04\xef\x9aW\xf7\xbc\x80\xd2\x1b({\xa2\xdf:\x1e.\xa2\xbc@ss\x11Yr\xb1\xc0\x1fy\x19\x16\xd6@+R\xb4\x10\x98\xf6\xd8|\x1d[M\n\xa5\x8b0{U\x0cl\xd0q\xf5\xea\x80l\xd3\xb1\x94k\xae\x8b}JXU\x9a\x16cm\xaa\xa9\xd6\xc1B\x8f:n\x1aB\xd9=oG\xe3\xc8\xbf\xc5$\xe9A\x97\x9d\x90F\x1cs\xb0a\xdb\xe5\x92}\x11\xdd\xa5\xeb\xa2\xdb={)\x88\xfc\x03\xdc\xafS8\xfeP\x1c2}\xbf\xbe\xdb\xef\xbb\xef\xd7\x9fv\x16\xe5\xffW\xe0\xab\xff\xbe\xdb\xca\xc6\x99P\xaahvM\xa3\xa8HaM\xfc\xd0X\xb3& \xb4\xb0\xab\xe6\x98\xa4\xd3\xb8\n\x96hm\xaen\xe7\xa3J/\x90\x86\x90\xf7>\xbe\x7fu|q:~s\xfc\xa7\xb3\x8f\x17-\x8a\x82\xfaQ+\x88\x00\x9e\xa0R\xb9\xa7S\xc2\xc6\xde~|\xfd\xe6\xe2\xb4M\x91\\\xefM\x08\xde\x9b\xf5v\xfe\xd3\xd9\xcf-\x9dX\n\xca^>Oo\x13\x9b\x0e\xa9\xa3b]j\xed\xabO\x8ay\x9c\\\xbb\x1c\xe0\x94\x16\x1f\xdb\x95\x87T\xd5\xc8\xdf\xf8\xd8;\x1ev\x1c\x0e\x19\xe1\xd8\xd8\n\x07 \xf5\xb7g\xafN7\x06\x07\xce\x8d\x06GUi\x99N\x99c\xfa\x18\xea\xdc\x1fy\xbcJ\xee]\xaa\xfb\xab\x84\x0f5\x13\xb1C\xd0\xc6\xd9\xabO#\xfd\xad\x1c\xa5|\xd9\xce\xd7\xcbe\x94\xdd\xe1\x94o\xe7\x91\xc8\x0f\xc4\x7f\xc4\xf99_U\x11\x86}\x9de,)~D<\xd5\xdf\xb8\x98-u\xec<\xdd\xfbUO\x1d\x82\x95\x13de`Z\x97\xe5\x92\xda\xe8T\xa5\x9aS\x07\xf6\xe8Z#\x13\xda\xf2\x86\x04\xb4\xba\xb6&\xc9\x80S\xdd\xb50\xd6\xa5 {\xb4\xd6\x8brw'i\xb6\x8c\x16\xf1_\x19\xba{\x05\xd2\xfe\x1d\xfb\xd6wp\xae\xef\xe0\x00\xcb\xeb\xaf\xf9w 9\xcc\x1a\x0eu\xda\x8d\xa5\xdd\xab.\xa0\xd7SX\xe9\xa6\xb1pT\xff\xe9\x8e\x9e\xd3>kj\xef\x1a\xea\xe5\"0\xa6jo\x1bA\x94\xbaK\x06\xb6\xfc\xdb\x81\x1d\xdfBf\xc3c\xd3\xb8Hk\x18\xd2\x89\x94T\xf2\xcf\xdeAG\xd7/N\xa5\x8c\xa1\xd0jt9\xc0\x14\xf3\xe6d~\x12\x8c\xfa\x97!$\xa3\xc1%zc\xfa&EoTm\xab\xbb!\xd6\x13\xcd\xda\xc2\xa90\x14\xd7\x90#\x16\xfec\xd2\xc8Y\xa4\x0e\xac\xf7\xf8]\xfd\xaf\xce\xb0zb\xd2\x0c\xa9\x96x\x16\xf8^\\\xb0,\xc2\xa5\xb0\xc9\x9b\xe1K\xd9\x06o\xc7\x8a\x9b\xa1\xf4\xfd\xac\x87\x0dk\xc9\xc71{\xdaa\x8d\x9f\xddp\x8a\x8dsI\x8d\xb0\"\xf6\xfa\xab\xe5\x1a=\xb9\x1ce\x97f\xfe\xbdX.b\x93\xa4\x06\xaa\x1f#*Q(\xa1\xc8)NM^\xa5\x1a\x108\xb1[oA\x83 \xedx\xd3\xd9r_\xc4AB?\xe6*\x84\x93\x19oE\x913\xf3=\xbdi4\xc0\xd1R!?\xccb\x02\xa6X\x86Y\x97\xda\xa0\nMr\xb0z\xa6i\xc2\x86b\xdc\x9d\x83^\x878\xb0\x0d\xba\x8f\xa86\x98\x1f;\x08\x03\xeb\xe0\x1e\xd5\x05\xcb\x7f\x05\xfe\xe9\x97VE\xe4xk\xea^\xbe\xdb,Z\x1d+\xfdBC\xee\xe8\x7fH\x85\xc5\xde\xaf\xcb:.Paa\x99\x94\xaf\xcb\xa2\x81Y\x94\xcb\xa2\xbd\xfd\x03Z\x97AD_\xfd\xa7.\xe3\x97\xde\x97$:\xadHw\x81X\x95\xec\x99%\x91,yj\x954i),!c!\x9b\xd9\xb3\xba\x9eH\xb5\xc6\xc0x?\x93\xefwI\x84j\x08S\xfaK\xd8\xb9\xd4\xf4,\x99\xa6g\xd1\xac\x0f\xb3\x10fJ\x06?\x7f\x7fz\xd2M\xefQ\xe6G\xd0\xa2\")\x81\x1b\xa3\xe9\xa2Z\x04-Ru\xa5\x08\xe8\xa3V\n\x01\xc7`>~x\xd3m,\xb2\xb3u\xb6\xd0\xfb\"\xc4\xf6\x86\xce\xfep~\xf6n\xa3\xde\xfe\x92\xa7\xa6\xb4u\x96MY\xc6\xa6\x9a\xee%\xe8\xdc\xff\x87\xd3\xf3\xb37\x7f<}\xb5\xc1\x18P\xf8\xc9X\x9e.n\xd8\xd4\xbb|\xf8\xb1\x8c\xcf?\xfep\xf1\xe1tc\xad\x0c\xad\x8fI\x84\x13\xbd]\x98J\x13\xdab\xde\xa2\xa4Qs=__\x15\x193e>]\xad\x14\x04\x0ehd\xdd\xa1\xf0\xfe\xf8\xc3\xf1\xdb\x87\x9a:\x9f\x9d{\xe6Y\xb4|\x17- \xd0\xc4U\x85\xd7\x84\xd6o]\x15\xdb\x85y\x13\xcc1\x9cg/\xce\xff\xe7\x92\x88 7!tB\xea\xbd\xf0T\xe6\xe7\xcf\xfc$\x9d\"\xd1\xda\x8a\x05g\x0dG\xb0\x16\xaa\x88$Z2\xa17\xeby\xb0\xad\xde\xc6\x89|\xc7?\xde\x11\x05\xaa\x1d\x1f\xf3\xf7\x97_\xc4\xf61\xca\xe9\xea\x02\x8e\xc0\xc3\x19\x8d?/\x17\x1e\x0c\xe5/Z\x7f\xa0i\xf7\x18\xe6\xf3F\xeb$7\xd6dA\x08#\x0f\xa1\xc9\n\x86Wv\x93\x10f\x97A\x08yg\xac9}\xfb\xfe\xe2O\x02w\xc6\xaf\xdf\x9d\xbc\xf9x\xfe\xba\x95\xb0l\x84EoY1O\x89\x1a\x0f\x83Kq2Y\xac\xa7\xect\xb9*\xee\xfe\xc8Ak\xf3-\xc2\x1cx+.y\x1ee\xc2v\x1be\x89\xef\xfd\x1ce \x06\x1el\x02\x08L\xd0\xe4\"I\x0b\xb8f \x17^\x19D\x80c\xfb\x1f\xec\xae\x87\x16d6\n\xe4\x18\x1d\xd7\x81#\x0f\xb3\xe8c\x04@\xce\xd9g/\x84\x9c\xaf\xfd\xba}\xed\xffx\xfc\xe6uE3\xce\x7f\xbd\xe5\x8e\xf3\xb3\xe3\xf3=z\xad5\x05YGH\x04\x84\xfa\x9f0\"\xe7\xb4\xe3\xd1\xe7\xe5\xe2Q\xdc+X^\xf8\xb1\xd8\xde\x1c\x0d\xd6K\x96\x8f\xc5\x96\xa4\xbe\xe4{x\xd2\xe3\x9ca\xc4\xa1\xf3s\x8c\xf3\x8bd\xcc\x10ArB\x18\xb1\x86!6\xdfcl4]c\xb7_R\xd3\xefx\xfb1S\xd6\x8f\x1a\xed\x10m\x95\x8e\x15\x94\x01\x95K\xecV\x18\"\x8e\xb0\x9bh\x11\xf3\xc9\xbd\xe7\xad\xa3\x91\xfb\"\x84\xb4\x835\x18\x87FAR\xe4\xa2\xa2\xc8!(\x0b\x85Ks\xfe\xa4\xd1\x93\x1d\x15\xa5}\x7f\x08\x93\xfco\xdc%\xdavx(\x1cH\xdaq`t\xd9\x15\x07\xbaX\x03\x81\xc5F\xd6\xacCj\xdd\x12\xb0\xdf\x18\xf0\xe7\xa7\x17\x9c\x9b{\x7f\xf6\xee\xfc\xc1\xb8\xb8\xcc\x8c\x07\x035\x1e\xce.\xc3k\x9d\xde\xd2A\xc8\xd6\x0ef\xc3_\xa3\x13\x1d\xc2\x07\x8e\xc0\xd0\xea\xdb\xa0\x15\xd6\xd2dP,\x8e\xfcC\xd1V/!\xcf\xc6\xd2\x90_T\x92? \x9e\xaa\x88\x8au\xce\x19\x16U\xb5zS_\x9bP\x96g,_\xa5I\x8eY\x02\xb2\xa07g\xd1\x94\xa19\xd2\xba\xfc\xfb\xcb\x17K?\xc0\x17c\x824\\\xe3}\xb1\x1d\x8e*i\x08\x91\x8b\xdd_;(\xe4B\xc1\xae\xf7\xc3\"\xbd\x12\xda\x97iTDzPm\xbb\x8e?A\x8a\xed\x1aD\x08^\xc1>\x17\x9cr\x88\xd6\xf8\x112\xe9\x88\x95\xff\xf1\xf1\xf4\xbc\xedJ\x7f\x03\xa4\xfc\xaf\xcd\x902\xd6\x90\xb2U\xec\xf8\xaf5\xcb\x0b9\xe9\xd8\x05\xf9.\xa2\x05\x9f\xf9\xdb\x8f\x17\xc7\x17\xa7\xaf\xfe\x91 \xb0\\\x17Q\xc1\xa6\x1f\x1e\x0e\x10\x929<{\x7f\xfa\xe1\xf8\xe2\xf5\xd9\xbb\xf1\xdb\xd3\x8bc~B||0:\xd5$r9\xa4\"\x01\x92O\xec\x8e\x96\xa6F\xad,\x85\x83[\xeaz\x1eYN\xa0\xe5J(V\x0e\xb5\x0e\xae\xcf\xf3 \x080{dY\xbd\xd2\x0el\xfcI\xab\x90\x8d\x9f\x1eUX\xe2\xaa\xb7\xe0\x87ll\x9f\xaci\xd0M\x1b$\x98\x87\x87>\xc5\x9a\xb0\xa3qOL\xd9\x82I&C'\x87Y\x08\xe9e;\xde\xab\xc9<\xe8\xd6\x7f\x98\xb9\x94{\xbb\xe3T8-;?\xf9\xe9\xf4\xed\x83\xadI>\x993\xeat\xfe&*\x96\xf2s,\xd6\x11\xd5\x13\xfdTT,\x13\xca\x87/_\xb0\x9e\xbc\xb6\x1dR\x1fxc \x83s\xf1\xe6\xb2\x9e\x97$(\x7fv\xbe\xbf\xdd\xa3c\x99=\xdb'4\xdd\xf2\xb67_\xb1I\xccr\xaf\x8b\x1d\x00\xb9\x16!\xb2d\x99\xcf\xd0_?/\xb2\xf5\xa4H3\x12zZ*\xa8HK\x0f\x7fx\x08~\x82mD\x01\xdf\xdb\x98\xdbh\x08\xa9n+\xd0\xe9*\xe1\xa6\x16\x87\x15\xe7\xb8\xff\x8cV\xd8\xef\x99 \x91\x86\x85\xfb\x94\xce>\xf1\x07V\x948\xa9\xb1\xa7\x14\xf6\x93\xde*K',78\xdbU\xc9\xfd\x94\x89\xf6k\xe5S,\xafg\xc0\xaf\xd7\x98c\x8d\xb7\x82\x9f<\x99GI\xc2\x0c\x85\xdb\x0d\xd6x\x15\xe7\xab\xa80\xc35/1\x1di\xed\xd55\x11\x80\xee\xae\xed*\xf7F\xa67\xd8\xb6\xc3_\x83\xd4\xea\\\x1bWJ>s\xe6\xbeW\x97Z\xd7V(R\xf5\x08\xba\x82\x15B(|B\x92\xa9\xbd1\xa6s\xd5h\\\xc1\x1fu\xe1%x\xcez[\xd5\x88V|\xe7O1\xc6\xc1\xaa\xb1\xc9*G\xba\x8c\xd6\xcaQ{\xf0\x9c2lJ\xaa\xe8\xaa\x95\x11S\xb2\xbd\xed\xb8g\xbb\x1emo/[o\xda\xd7\x8e$\x1a\xf2\x06\xe8\xc7j\xe0\xa1\x15\xae:\x84\xcc_\x06!,\xbf\xd3^5\xc7\x86\xd7VG\xff\xc8\x93[\x00\x87\x90\xf8\xcf\xf6\x02\x7f\x16\xe0\xb5l#\xec\xd0\x94\xe1\"\x9e|\xf2#\xff\x0e\xe3\x94\x0ct\xfe\x0f\x86p\x83\xc6`\xbd$\xbdmm\x0dk9\x1b\xc2\xd0\xc2\xb12\x19N\xd8-\xcc\x83\x1e'{\xbb\xfct\xe2\x7f\x0czi\"\x8578\x84\xab\x10\xbb\x8b\xfc\xb8\xb7J\xf3B\xeeB$5\x03d>&\xbdh:=\xbdaI\xf1&\xce\x0b\x96\xb0\x0c\\\x01\x0b\xb5\x06P\xdb=\xe9\xc5K\xde\xe39\x86S\xcdU\xd0c\xf7\xd4&\xfa\x18|tt\xe3\x07\xca\xef\xea\xa6\x87\xf6\x88t\xa7\xa1\xab\x10\xb6\xc4\xc8y_^\x9ad,\x9a\xde\xa1\x1d\xc2d\x1e%\xd7\xcc\x838\x81\x85\xef\x89 \xaf\x1e_>\xf7\x88\xf2^\xb4Z\xb1dz2\x8f\x17S_\xfb*\xe8\xd9-\xb7\xe1p\xde\xcb\xd82\xbda\xa21\x91 \xa7\xdc\xa7\x06\xce\xd6\x16\xb5a|\xac\xb8\x88\x97,]\x17\x1aF\x84\xd0\xaf\x1f\xb8\xfa\xd1g}?\x84\x95q\x06pZ=\x84i\xd5\x04\xfe\xf5\xedq2\x1bM\xebh:\xea\x08\xc2\xcd\x9f\x9b!\xb0v\xb2\xd9\x18\xc9\xb5\xb5kBQ\x02\xb2\xeb\xb6\x8e[\xa0\xb7)\xb3\xb3\xfb\x94dvv\xfb\x8f\xef\xc3\xe2`\xb2\x10\xa4\x95\xa9_\x88|\x1b:\x9b#\xed\xedJK\x08[\xf1\x82\x91\xa2{3;\xa5\x98\xf8\x82\xf3\xc2\xa8\x05\xe3b\x92\xb4\xa4\xe5\xec\xc32\xce7\x8cs[\x8fu\xffd\xef[\x02\xda\x17\xba\xe5\xc0!l\xb9\xcc\xb9w\xfb\xbf\xa4Q\x8e>\x1eY\xa7\x8b\xa5d+\xf3\"\x9c%\x1d\xa1\xc5]\xa8\x8f\x89\xe1\xd40j\x8aw2\x9a\x13\xd8\xe3\x81\xccOC\x88\\\xb5\xa112\x85zn\xa4\xb3}1J/\xfd\x88\xd0\x10\x98\x8f\xd0\x0e\xa2\x8a\xc2Y\xb7=\x8a\xb3ztF\x9e\x0c$\xa3\x1e\xdb\xe0K=x\xeb\xb7\xeeM\xd3\xa4\xda7%`\xd5N\xf0\xf3\x00c\xfav\xd0\x80\xab'\xf3=\xce\x15\xcb\xc8\x1b\x89\x88\xd7 \xd2'\\\xb6exq\x918\xc2^\nM\xc0\xb7R_\x84\xc9\x8e\xe5\xff\x98\x0d\x87\x8b\xdb\x9b\xa1Q5\xe9\xc1>}\xca>1\xe5j\xa9R\xd83St\xca\xfc\x15\xe6\xa1,\xc4\xf0\xa7\xfd.g2\xba\x1f\xe4\xd4\xc9\xbc\x15\xa1d\xa9TP\xf5\x8dX\nb\\\x84\xdf\x19\x84(\xb2\xa3\xa7|\x8aQ\xe2\x82@Jb\xa1\x90\xdaa\x07\x06!J\xe9\xecy\x99o\x12\xc5\xbe\xed\xed\x05\xbc\x80\xc9s\xd7\x81\xc2%\xa4\xb5_\x8c\x16\x97\x0e\x82\xcc\x05w\xc2y\x81O\x01{\x995I\xc7\\\xa6_\x8d\xa6\x0e\xe9XO\xaf\xcd\xbb\xe1\xc2C\xee\xdf\x840\x0da\xc5\x99{QA\x98r\xceQ\x80\xb9\xe1\x9c\xfc\x0d\x0c!\xe6c\xc6@\x17\xfc\xcd\xe8\x92\x9f\xceT\xf8!\xebM\xe6\xaf\xb0\x83y \x00\xc6\x87\xf7\x9d\xfb\x13\xb5>\xf7E\xc2\xbd\xfdN\xbc\x1bq\x14{\xe31\x9a\xb9\x8e\xc7b\xaf\xe0\x9e\xe0\x8c\x88\xfc\xc0\x86z{V\x9cZ\x12\x19\xa2\\Z\xa1\x12V1Zb\x1a\xc3\xbf\x01\x95\xd7\xa3\x82\x0b\xf7\x1b\x9a\xb5k\xf4\xc9\xe4\xc5\xd261\xab9\x10\x16C\x95\x9c0\xc4\x0d\xc1\xab\x9b\xe2\xb6\xc5\x8f\xc10\x94\\&E\xb3\x07B\x06p\x9b\xf7\x7f\xf5\x1d\x8b\x9dv\x81\xc7/lN\x1cBQ7\xa1\xc8Q\x17\xcd>\xb3\xc9\xba`\xf2N\x0b_ \xfb\x81?\xe4ir\xbeb\x13\xed\x95\xfc\xe9\nJ\x11\xfb\x89\xbfO\x862\xe7%\x83=\x87\xa3<\x91\xecX\xad\xc5/c\x0b\\\x9bL\xa3\x0cU\xa9\xec\xf3\x15\x9bH\x07\x05R\x1aj\xc4VfX\xf6TL{(L\xd1rv\x91rx\xcbz\x89^\xc55\xa1\x90Z\xa9_c655\xa1\xa9\x1b\x0c+\xc71\x14 #\xcc\xe5\x04\x11\xbc\x80\xe29D\xdb\xdb\x01\xc4\xa3\xe8\xb2\x96&$\"\x0e\x08\x13d1\x82*N\x14\x06\x7f\xa8_\xcf\x9dD\x939\xa3\\\x8c\x94\xd4\x11\x8f\xfa\x0e\x07\xa5\xdc\x0eP\xbf\x0e\xab;\xce\x80\xb2K\xe0\x8f_\x8f\xb9I\xe5\xacq\xf2\xe9F\x7f9\x1a{\x05\xbd\x7f\xc9\xd8\x8c\xa3<\xdeb\xf3\xedh\xcc\xd2W\xa3\n\x81]n\xc2\x80\x87\xd4F\x7fh\\!\xcd\xb8\x94\x0c\xda[\xa4\xd7\xb2k\xe1\xb6\xea\x9b\x1a\xdc\xfah-J\xb5\xc1h\xcb\xb0\x8c\xf7\x1f/\xc3`\xc7\xd2\xae\xd0\x8aRcP\x95\xbf?]\xef\xa2c\xb8\xd1c\xbd\x9d\xa4\xcbU\x9a`VJ\x0b\x04e\x94\xb6\xf3\"\xcd\x1c\xd6\x01Z\xa0b\xbb\x02\xde\xaa\xd5z\xb1\xeb\x08\xab\xa6\x8c%S\x96\xd9\xa5\xb9\x0c\x1c\xfe\x89\xbd\x8dV+6=I\x93\"\x8a\x13\xaa\xea\xa2\xdc\xbeK\xb6L\xe3\xbf\xb2\xc0\x8fDvr\x91>:F\x1e\xdcJ\xa2\xe5T\x0bfiZ\xbcN\xf8\xda8\x9d\xd9\xf4\x99\x0d\x810\x1c\xe7\x0f1\xf8\xa19\xd0\xdc\x1e\xe8\x02\xc7J7)\xa05\x84\xb5\xfdYd\xdd\x88\x80\xc5\xcb\xba=\xd5Z/\x9a6r\xf6\x02\x0d\xd9(\xc2\xd9\xe2\xf4\x05\xbf\xa8\xe3\x17Tk\xeft\xfe\x02d\xe58\xf3\xfe\x94bf\xd0=\xea7\xb2\xf1uTD\xfa'p\x04\xff$0\xb0\x81y\xbb\xe6\xcc\xdbcj\xbe\xd7$[\x17\xcb\x12\xda\xe5\x0cK\xac\xd6\xd6\xaa5\xca\x01\x11?1\x0b\x16\xb2\xc0\xead\"\x0b\xac>f\xb2\xe0\xc0,X\xe1\xd2\x99\x97\xe4S\xac\xbe2\xde\xcee#O\x9eXC\xbd\x11\xe2\xffc\xf3\xfa|)?y\xfa\xf8\x19\xcd\xe6^\xff\xbal._W+\x1d\xb4C\xe5k\x13\x81\x06\xa3l \x8eR\xa7\"Y=\x9a&\xb9\xad*\xd4\xaf\x18\xf2\x8aM\x12\x1a\xefL\xda\xe1L\xcc\x02?\xeb\x952\xb3\x8a\xe8\xbf\xae\x19\x9594\xe7n\x0d)\x90:\x04\xfd\xd1F:\xab\x19\x06%r\x98\x8b\xda\xdbQ\xfb\xdc?\xb1\xbb!xb\x1f{\xf4A\xa0?\x9224r\xec\xd4#\x07>-\xf5\xd7\"\xee\xc7\xa9Hl\xcf\xe9\x91a\xbf\xf67\xf4u\x0fdn\xf3U\x96\xaer\xf9\xf7$M\n\xf6\xb9h\x81#\xb4\xc2\xf2\xebe\x10\x12\xe1\xd8\xcbb\x7f\xd5+\x89\x9dK9\x8d\x98KC-\x95\x9c\xc2\x0d\x1fp\xc2&\x85\x16\xdb\xa4-\x80\xeb\x8dL\x8eo\x9a_\x7fE31\xe6S\xd1'\xd5\xa3PD?\xbe\x96\xd1\ns\xd0_\xa4\xfc\x04@\xdb\xe7v\xa9\xc1h\xb0}\x9d\xf1\xde\x9a\xba\xc7\xd4\x1f\xf7\x9a|\x0d\xfc\xa4\x8c\xf1D\x146d\xf6Ij7\xee\x0d\xd4d#J\xb2\x01\x15\xf9\xadP\x107t\x1f\x96rl@5\xeeC1Z\xa8\xc5M\xef}\x96\xde\xc4\x9c\x97\xef\xd0\x18 j\xa6Y+j\x82\xe0\xb16\xa3Qn\xf2t_:\xdf@\x97Zh\xd2W\xb1\x81`h$\x0ci\xb4\xf4j\x8c(]r\xc6)\xe7\x8c\x1b=\xa7by\xd9JS&\xd2\xba'\x1670\xc9(\xbd\x0c!\xc3\x7f\x19\x99\x88\xa6i6c\xbc\xacp\xb0\x9f\xc44\x85\xcdc\x830\xde,\xb1C\x9d0\xb8x\x1c\xf58(\x82\x9b|\xeb\xa4\xff>\x14C\xa4\xac\xc5\xda8\xb6\xf6\x93\xe2\x8a\x03'\x12Z~\x8c\xb2G\xa3^\x13=\xb5\xa9J\xb1)U\x11\x14e\xa2\x90\xfb\xe7x\xb1\xf8\xc0&,\xbeA\xa1%o 2&\x81id%\xf9\xa3M\xb8\xda\xbd\x9b\xd2\xd4\xafM\xa4\xa7#y\xdc\x944\xaa\xcb\x06\x0e\xd8e\x1d7\x14 \x8a\xa4\xd3\x96\xa6\xee\x8b8A\x18\xb9n\xdc\xf4\xa7@a#\x0e\xc1\xcb\xd2\xb4p\xdd\\\xa8\xa7\x9d\xa5\xdb\xd8\xec\xc1A\xfa\x1a\xc8\xde\xd7P\x97B\xc9\xedn\xc5c\x03\x8db\xa9\xaaY\x08\xde\xf1j\xe55\xcc}\xde\xabl/x\x7f\xbek\xe6q\x88\xb7\xa2\x81\xc5\xcc\xb4\x1aUTJ\xb3$Z\x12z\x8e\x16\x90{\xd3\xf8\xc6\x92\xe5\xd5\x93\x17w\x0b\xd6\x14\x14i\x15M\xa7\xe8B\xee\x0d\xd8\xb2\x01k'\xe9\"\xcd\x86\xe0\xfd\xff\xa2(r\xe4\xbd\xb3W0\x04\xef\xff\xf9\xdf\xff\xb7\xff\x03<\xf7\xf9\xea\xc5\x9e\x00\\\x08\xdeI\xe9\xa8.\xd7\x96/\x0c\xe6\xbf>\x84\x02\x8e\xc0\xe38\x0f%\xb5\xf0`\xc8\x17\xd1\x0b!g\x0c\x8a9+\xbd\xe3=+\xe4w}b\xb7\xad\xca(\xb5&\xdd\x18f\xb9B[>\xab\xd8o!oW\xdcx\x9c\x7f`\xd1\xa4h\x17.\x9a\x0dI\xf5\xa7\xf3\xd1\xa5\x9e\xf2\x08k\xa7:\xd0\xc2\xdf&N\xfe6i<\xad\x92{\xf0\xb7\xd0*\xd5\xd1'RB\x9eHI+\x9f\x0b\xdd\x89\xb9z6%\xea\xea\xa9\xae\x02:\x9cI\xea\xe9 \xe1&n\x1a\xdcI\xc2\xc5\x1bwz\xda\xd2\xbd\xa8Dl\x01\xa3\x06\x0d\xa8Y\xb5\xed\xde\x1dZM\xfdJ\x06\x95\x91\xb7\x83Yy;\x88\x96\xa9\xe2v0\x85\x17\xc0\x9eC\xba\xbd\x1d \xd7Y\xbb\x1dt1\xb0\xa0\xdf.\xe9h\x9b9 \xd7\xc9TP\xb6XOG\xc5\x87\xea\"\x92\xe36\x89G:d;VL=\xc27\xbb\xc0c\xc6\x8d\x1f\x8e\x99Q\xd4\xddPgW0\xb4\x94\xc6\xf6\x19\x9d\x86\x10\x9b@\x8ag\xe0\x97\xc6[U\xe2\xbf4\x90A+\x13v\x0b\x17w+v*\x12x\xbdcl\n\x11\x88\x0fB(R\x981\x0e\xfd\xa8:#z\xf0s\x94\xc3u|\xc3\x12\x880\xd5\x8d\xaf\x99\x04\xa5\xfcPY'BM>\xe5\xe7\x89q\xe1\x9aZA08\xd6 \xa3-3*\x84\\U\xce\x8b\xc5\xbc]\xe4(\xb0\x1b\xfe\xf3N\xb1\x9f>\xfa\x14\xe0\xcf[?\xc2\x1f\xb7\x82[\xf3\x99\x1f\xf4\x16\xe9\xb5\x0c\xeeR\x9d\x86\xb38\x99j\xc7\x1e\xe70$\xb3Q\x0e\xa0\xd3%\xa1\xdb|_Nx\x08\x89\xff\xe4\x89i\xc8W\xe9\x8c\xeb\x97\x03]\xba\xa4\xaf'\xdc\x03\x99G9^\xb3\x0bG\x89w\xe9\x94\xe5C\x18\xddX\x12\xc2:\x04\xe1V\xa4\x90\xd5w\x10T4\xdb\x16\xb1\x93\x1c'\x838\x94\xd7x\n$x\np\xc4Jz\xf2,\x80\xa1\x8a_\x87\xb1\x89\x9d:\xee\x05\xca\x11\x92\xfd\xec)\xa4\xc6hl[\xfd\xc6\x03\xd0\x81\x8e\x8dwR4,\x0b\xa1U\xd1\x1b4\xb8@\xd26[g\xd0\x84\x1b\xec7\xf1\\\xf5Q\xcbKC\x93\xceO\xd1b\x8cz[\xc4K\xa2\xc4SE;\x8bt\x12-<\xbb\x06[F\xf1\xc2~\xbdL\x93bn\xbfN\xd6\xcb+F\x8ck\x15\xe5\xf9m\x9aM\xed\x92\x8c\xef\x07\xfbu\xce\xa2lBtP0b0\x9c\xef'\xde\x923^gD\x03\xb7\x8c}\xaak`\xdb\x94tN.W\\N*v\xb6\xfe\xab\xce\xb5\x92\xac\xae\xce\xe5\x16p\x04[[\xd9Hp\xce\x98b\x8e\xcf4\xcaX$+T\xe3}p\xfc\x12\xa9\x03\xcf'\\\x8c|\xc3f\xc5\xd0\x0c\xe1U\xabq\x91\xae\xac\n\x19\x9be,\x9f\x8b\n\xb8m\xf3\xb6}\x98\xf5\xac~Q:\xf8\x1c\x9aE\x17)\xfaK\xf7\xeejm\xb4\xee\xc3\xec\xdb\xe1\xe4R\x83\xfa\x83\xc7\xa6u\xbatM\xb7B\xc1E]\xd4W\x9c\x82\xb7\x86\xd6f\xbdY\x9c\xe5\x05\xaa\xf4\xddZ\x1b\x94\x9f\x12\x112\x06\xd3ic}\xferO\x8aS\x1cC/\xeeV\xd5\x89s\x93\xc6S_\xbc\xc7\xa5\x83\xc3v\x0f\x15@`k\xeaX\x8bU\xd2V\xc5T\xfbvW\xf9r\xae\xba\x15\x82{\"a]918\xe2\xc4]\x04\xd3AMy}j\x15\xde\x04F0\xa6o\xa0\xdc\xdd(\x07}\x1f\xcbz\xb3t\xb2\xce\xcds\x86v^~\xf0\xdd\x1f%\xf1\x12c\xdb\xbf.d\x90\xfb\x93t\x9d\x104\xf6*\xcd\xa6,{\xbd\x8c\xae\xd9\xd9\xba@\x06\xbf\xa1\xca\xf9\"\x9e\x10$Y\xab\xf1s<\xa5\x8e\x95\xab\xf4\xf3\x8f\x0b\xf6\xd9Y\xf0\xfb,]\xaf\xc8\xd2\xb3l\x1a'\xd1\xc2Qa\x92.\xd6K\xd7\xdcDan\x17\xcc\xc8\xa1\xcc\xc48n\xe9\x92\xf7i\x1e\x17\xf1\x0d1{^z>\xcf\xe2\xe4\x13]\xf6\x8e]G\xee/1\\\xb1]t\x9d\xc5\xd3\x0f\xd4Xd\xc1iB\x1c\xc5\xb2\xec|\x15%\xee\xc2\"\xca\x08X\xf1\xd2\x13\x84WS\x99\xb3WQ\xec\xeeX\x96\xd3}\xcf\xd2\xa4\xf8\x99\xc5\xd7s\xa2l\x11'\xecd\x11-\x89\xb5\xe7E?9>KW\xd1$.\xee\x88\x02\x1a\xdci\xb6\x9aG\x14\xaa\x14\xd1\xd5y\xfcWb\xedn\xe3izK|\xf0\xd7\xd7\xc9\x94\xc2\xae\xbf\xa6\xe9\x92\x98z\xbcX\x9c\xb9\xc6:[\xa4\xe9\xd4Y\xca\xb9\xd9\x86\xc2,\xfd\xc4^E\xf9<\xca\xb2\xa8\xb1B:\x9b\x91\xdb^\xd4x\x1b\x17,[\xc4\xcb\xd8Y\xa3e\x0c%A(\xcb\xbe\xda\x17p#\xefgv\xf5).\xbc\x10\xbce\xce\xff}\x9b\xfe\x95\xffw\xe6i\x9a\x1e\xa9\x89\xf9\xc4\xeer?\xeb\xe2\xee\x9d\xdauh\xa7\xe3Q\xeba\x0e\x9a:\x11\x13WL\xe6Qv\\\xf8\xfd\xa0W\xa4\x1f\xb90+5\x99\xbc,__ \xc3\x0b\x7f@\xd9\xa4\xa3!\xe8%gf\xf4\xd0\x97X\xa6\xa98\x8d{\xca\xd8\xa2\xf1q\xfe1\x89\x8b\x05\xcb\xf3w\x92i7\xdcs\xf3y\x9a\x15\xf3(\x99*\xad\xd5\xe9\xe7U\x94\xe4\"'\xa3=\xc5\xabh\xf2\xe9:K\xd7|\x8f\xd3\x00\xa8j\x1c\x17E4\x99/\x19Ev\xed\xda'\xb4\xaccW\xc4#\xa4KEA\x8d\xd3\xe4\x7fnR\xf9O]*\x7f`+\x16\x15C*\x8d)\xa1:\xb1;i\x87\xdd\xfd\xc7\xdeiD\x92\xc29F\x81\xa5\x8eC\xba^\xe9\\\x98\xc76W*W\xb6\xfb\xd0~H\x8b\x82\x93\xc2\xa6\x01\x8a:\x9d\x86)\xaav\x1a\xac\xa8z\x8f!\x0b\xf1\xa9i\xc0\xbcF\xa7\xe1\xf2\x8a\x9d\x06\xcb+\xdec\xa8\x1f\xc4y\xd84V\xac\xd2i\xb0X\xb3\xd3h\xb1\xe6=\x86\x8bbg\xd3`/\xd2U\xa7\xa1^\xa4\xabN\x03\xbdHW\x1b\x0d\x93\xf3&\xae\x11\xf2\xb2\x96Ny\x95?FY\x1c5\x11\xca&\xfeG\xafC3\"\xeaib\x87\xd4\xc3[\xf91Z\xc6\x8b\xbb\xae\xf3O\xd7\x05o\xd8\x05\x02Y\xdc\xb2D\xb2V\x0b\xacd\xad\x86\xe5\xf9\x8e\xfe\xe5P\x15\xc4\xf8\xf6\x9b\x84\xaa\xc4\x7fj\x06\xe3K\x85a\xd0`\x1f\xe3\x02\xee\x89\xf0\x80O\xfb\x96\x83\xbc4 \xc2rv\x0b\x1f\xd8\xf5\xe9\xe7\x95\xef\xfd\xe7\xc8\x83m\xc8z\xc7\x17\x17\x1f^\xff\xf0\xf1\xe2t\xfc\xee\xf8\xed\xe9\xf8\xfc\xe2\xf8\xc3\xc5\xf8\xe4\xa7\xe3\x0f\xb0\x0d\xde%]\xa9,\xfe\xdd\xbfXi\xcd\"\"\x1e\xfbZ\x06\x80(_\x96w\xa5\xb9\xf3\xaetkkmG`\xc7\x00\x81\x11\xf1\x9e\xcb\xfd2\xfb\x1a\x1a\xb4\xf9\xeb\x11\xbb\xc4\xb0\xaf\xa8\xdd\x85!\xf8\x91\xf6\xa6\x16H\x9bNs\xdc\xc5\x9e\x10\xf3\x84\xcc\xa3\xfc\x874]\xb0(\x11:\x80\xef\xbf\x87\xad\xaa\xe8\xddz\xc9\xb2xR\x16\xc5\xf9\xbb\xe8\x1dg\xfeT\x05%\xce\x99\x15\x0bx\x01\x83\xb2\xd6\xd9\x0d\xcb\x16i4eS\xab\xaf\x01\xa9\xc0\x03\x89<\x13[\x1f\x87V\xcbo\xa3\xec\xd3z\xf5c\x9a\xbd~\xd5\xaaJ\x13\xd3\xcez\xaf_\x8d\xeb\x88\xc0q\xe0\x90cHj\x85\xb4\xae#@\xce\x8a\xe3\xa2\xc8\xe2\xabu\xc1\xac>\x1d\x8c.f\x9b(\xbf\xf2\x89\xee\x89\xe0\xefM3\xfd\x90\xa6m\xd7\x95\xe5T?\x9c\x9d]\xd8\x93\xfd\xb7C\xcf\xfb\xb7\x0d\xe6i\xf4HB\xd7\x9a&\xd1uXK\xdcK\xf4k\xccT\xed\x8c\x0ePV\xea?\xbc\xfc\xe6\x1f\xc5,'\xf6\xd7Q\xad\xc2\x08U\xc8\xb4Q\x15j ]\x82\x0bF\x8b\x14.\x1f\xa5~\xd0\xf3huc\xe9\x07\xd6\x8b\x14tl\xb3\x0e\xf5\x94\xf6\xff\xe6n\xfc\xf2E\xbcl\xd8@\xfdRE\x1e\xab5\x86!\xfe\xad\x90\xbb\x93\xbe\xb2\xc4\x9d8?Y\xe7E\xba\xac\x16\x15\x01X\x91\x0d\xbc\xc1\x1a\xa2\xf8V\xf5 \x01\xba\xc1*\x1b\xbdtXl9\xc4\\RL\x15{\xa7\xc00#\xc6`<\xaf\x05\xd1\x11\x80ndk\x880\x92\xb6\xe0[a\xe1[\xd1\x8co\xa4\x1f!h8\x94\xf60cW\x9c&T\xbeD\xf5\xf0\xa6\xe2@hw]\x06~l\x913GgP\"x\x8a\xee\xbd\xba\x02\\\x98}\x89\xabb\x13pb\xb9\xe8\xeeT\x9b|\x02y\xf11/\xed>\xd0$Q\x81\xe8\x8eo\x8cK:@\xabzZ\x06\x0e\x9a\xbdQZ\xdfq4\x93\xa4?k\xfb\xa3|\x15M\x1c{\xb5\xfa\xea\xc8\xa0~\xef\xce\xfd\xb5\xc8\xa2\x877\xbc\xe8.O\xed\xe8\xb4\xd3\x8eN\xac\xf6}l:P\xa9\x8c\x8c\xf7\xd8\xa5s\xc4\x8e+|\x9b0\x08Hc\xd0}\x82\x14\x14\x06^Lz\xdaV\xd2(\x86\xdcA\x1d\xf7\xa0\x8b\x0886a.\xf3\x00\xf8\x8a& P\x89\x84\x15\xfaXmH\x15%\xa4\x1a\xc7V\xc7\xf4Mh\x145\x8c\xee==\xf0\xc9\xb71%r\x9e|\xa5\x85\x7fgJ\x94\x06\x9c\xad\nU\xf0\xe3\x06r\x84\x1d\xdb\x04\xc2\xbd\xd9\xab\xa3U' \xee\xddj\x1f\xabG\xc0F1\xb2\xd3\x03\x0c\xfb\x8b\x7f{\x0e\x9fc1J{a\x8d\x93\x9d8d\xc5\x97\xf4>\x12\x17\xe2m\xc8R\xfer\xc8f\"9\xe77\xcaf\x03*lq\xe2\xef\x0e\x1c\x11\xc6\xcdp\xeb2\xcf\x97\xd9\xca\xba\x92\xdc\xb6\x06\xa4\x91lnq\xb1x\xd7\x8bV\xccY\x9a\xa25\xcd\xebW\x95\x0dv\xcd\xdci\xc5\x92i\x9c\\\x7fD\xa3\"\n]\xda\xbe\xc1\xe5\xb7\xb1\xc6\xf0.\x10w\xed\xf2\xcaU\x06C \xf1\x04\xc3\x9aW\xf6B\x94\xfdL\xc5\xb1|\xff=(\x03>\x89\x98>\xeb-\xd7\x8b\"^-\xa8\xb4P\x15\x1e8\xc5=\x82X\xde\x94\xd9\xd8\"\xcc\x81B\x1b(\xf5\xd2UaGEu\xde\xba\xa3\xbbA&\xc4d\xdd\xe5 \xa9\xbb\x1cd#AhG\xe9\xe5\xff\xcb\xde\xbbv\xc7\x8d\x1b\x0d\xc2\xdf\xf3+J\xcc\xacCF4\xad\x8b\xc7c\xb7G\xd1\xeb\xb1\xe5\x8d\xb3\xe3\xcbZ\x9e\xe4\xeci+Z\xaa\x1b\xdd\xcd\x11\x9bdH\xb6de\xac\xe7\xb7\xbf\x07\x85\x0bA\x12 \xc0\xb6<\x93d\x1f|\xb0\xd5$\x88K\xa1P\xa8*\xd4\xe5\xac\x93\xc0\xa4\xd5\x92\xd2B\xdcn\xc1L\x89X\xd0\xcd\x0e\xb1\x8b\xa7\xf9\x197\xa4\xd2\x93\x02\xacPaLU2\xc7[\xf1\x0d\x9e\"\xed\xe7Gj\x82xQ:\x1a\x13\x137\"A\xc3\xa6\xde\x02O{r\xda\x01R\x907\xb3@&\xa0l\xdb!t\x87\xba\xa3#\xac\xb1\xe2k\xe2\xc7\xd3\xbd\xee\x17F\xcc\x12\x7f\xe9\x05\xef%\xa9\xff\x9cW5\x06Mq8\x9f\x84<\xc1b\x19\x99\xecA\xf3\x8c\xd9\x01Nz\xd6\x8c\xe2\x8d~\xb3q_xv\xb8\xf4\x97k\xf0\xc8]\xe7\x9b\xac\xfe\x1b\xeb\xcba\"\xe2\xa0U\xf6\xb6\x8e\xdd\xed\x8c\xbf\x07>QZ$\xc8\x9c1*\xc9\x92:\x89Sn\xb9*\x08\x07et2\x984!?\xf1\xbdI\x8f\xc9\x12\x8eU\xecs\x83\xaeP\xc2\x7fX\xcc\x17EXw\x8d%\x8e\xa20@\xf2\x10\xceoy\xe7\xec\"\xcf|~\xeb\x0e\x04\xdf\x85\xba\x9b\xd8\x0eP\xcd\xb9\xe3*.|\x1ec\xcb\x18\xd5\xe0\x96\x85\xaa5\xd9\xf9_\xc7\xd5kN\xbc'\x92\xa0\xd7\x0dA\xefch\xa8\xa6\x8d\xa8\xf9\x8eW\x13r\x1eu\x16\x99\xbe\xdc\xa0\xc9\xcfF\xb7\x8d\xc3\xee^e\xc1\xa3\xf1\xd3\xe7\xcc!\xc8\xb6\xc6\x06/\x0f\x15\x13\x87\xfa,\xf2\xaaf\xa0\xd7\xec-\xd3\xc6bVmZD\xb2n\xb1\xd6\xc8\x0cY\xe7\xa1e\"\xd6\xfe\\Y4{_Je8\xd2-\xb1\xbe\xdf\xd2N8\xc4\xde.\x99\x7f\xb6\x8da \xd9q\xaf\x19A\x08%Ztex\xb6i*42\xd3N\x0f\xbb\x8e\x07\x9amW\xa5]\x0c\xd5\x15?D>\x13\xaf\x17)G\xfe\xfa\xaaLm7\xb0m\xae\xe7u\x19O\xfbx\xbf\x1b\x91\x80g\xcdy\xd45q\xdc\xf0\xe7\xdd\xfb\x8c\x8a;:\xd3\x0e\x809<3\xdewx\x13 \x19\x93N<==\xb4\x96m\xd6\xab\xf7\x11\xcd\xfb<\x1c\x97\x91\x8fxz\xa2}\x91/\x8f\xee\x88\x98\xc7\x00\xf1\xd3\x0e^J\xb9\xccc\xd9\x92Zi\x8e\x86\xf4b\x86\xb3\x88)\xb1h\x03z\xb9S\xeb:\x84A\xfc4\xa1:z!=D\x11|\x8bI%\xbb\x17\xc2\x0cv]\xbc@Ax\xf9\x0eU\x80\x16\x0d\xa3\xbcu\xbc\xd6\xe6nP\x0bg\xab\x85\xf2\x18\x9e\xaf\xc8\xec\x12\x03K\xf1\xc05,\xf55\xe4\x0b\xf8\xbf\xe8\xa3\x05\xbb\xe0\xfd\xdfH/\x9a\x82Q\xb1\x03\x8a!\xb5A\xac\xf5\xf3\xe8<\xbf\xceHI \x87\xef\xed\x1f\xeeyMX\x89\x04\xd5\xc9\x13 \xf2\x10f6\xae\x98\x16MV,\xb6\xec\xc8\xb7\x1c\xc1\x86#\xdc\xab\xac&e\x16\xa72|\x8b\x8f\xc1%]<`\xc4\xac\x1a\x8cQ3p\xdd\xbb'NPf\xf5\xda\n\x95\xa5\xffF\x8dfK9\xc3&\xa4\x8c\xcb'%\x0b%(?\xea\x03\xc9g\x10\x088\x082r\x0d\x15\x9b\xae/~\xb3\x1a~\x1e\x04\x11\xe7\xb2)\xa3\x83\x87}\xd6zr\x04\x19C4\xbcr\xcb\xe7]r\xc16\xae)7\x99\xc7\x9c\x12\xba9\x89\xdb\x0b\xc3\x9d+s\x0c\x1c\xe1#\xb5G\xec\xd8\xf7\xc2\x86\x02\xb4q\\\xde^\x9c#\x00\xd1p\x8fy\x8f\xcbGk\x96\xc1\x97\xb9)w\xf3+\xd1\x92\xfb\x95\xea\xbf\x98t\x05\x86s\x16\xc9\xa1N0g\x8a\x1a\xe4l\x02\xcd\xadC7\x81,{\xf3uN\x92\xef\xbay\xd6\x94P\x17}\xd4\xfd\xf3\xdb\xd3\x0f=\xc7\x00Z\x9e\xbf}\xfd\xee\xed\xe9\xab\x0f'\x13\xd0\x88\x02'\xaf\xdf}\xf8?\x138\xe8\xbfY\x92\xfa\xc3M\xe1\xc4\xb8\xb7/~;'\x01\xdd\xe8\x11v\x83\xea\xea\xa4\xfak\x9c&s\x11\x15\n\xd1\xd6\xb0 \xf8\xbeN\"9\x05\x98@\x12\xd1\x99\x8a\xa4g\xa5\xef\x1d<\xd2'o\xec\x88\xd4\x067\xf1/\xb5=`\"x\x1f, f\xc68Y\x17\xf5\x8dD\xa4\x97\xf1\xac\xce\xcb\x1b'\x88R\x92o\x9bR\x1f;\xfa\x8d\xb1]\xe7\xd4\xa5\x90\xa7\xed\xb0l`\x90Dl\xa2\x94k8\x82<\xbcS\xd8\x9a7\x07\xdf\x05,Ve\x0f\nm\xf5\xf3\x95\xd6K\xdcpL\xd8\x00\xc5\x81\x94S\x04\xa7Tk\x9fR-\x86\xa9\xdc~\xc4v\xd5\xaf%\x83\x8e\xddb\x82ZK\xfbI\xf5\x01\xdd;\xc6M\xa8\x15\xc8&\x19l_\xac\xb7\xce\xd2\x88\xbd\xfc\x9f$#e2\x93cx\x9e\xc6\x95\xd5! \xf8\xd2j\xb0\xbeO\x9bX?\xad\x89:w\x92\xb8l-\xf9\xeb\xeby\x19\x9aQ\xfb\xe1#\xc6\xe1\xef\xf7rj\x08YB\x97\x81S\xec \xff\xa0\x9fiD\xd1\x94{\x91\xa7\x11,\xbc\x89\xe7.\x08H\x9c\xa1\xfc\x8b\x86\x7fW\xef\xceItIn\xe0\x18\xe2\x88T\xb3\xb8 >>\x08P\xc5T\xe7,G\xaa\x7f\xf8H57\x12\x7f\x8d\x89\xd9\xd51=\xa2\xc7\xc6\x9e\x92+\x9e\xa7\xa9\na\x16\xea\x13q\xd2E)BLr\xc2gQ\x1b\x04 %\xd2\x1e\xe5\x00\xd1\xb7\xcb\xbb`\x92\xaaxD\xf9\xaa\x9a\x13\xa2&\x94\x9a\x88\x94\xd10O\xbc\xae\xc26\x89'\x0dTy\x17u\xf4\xcd7|d\x18\xf4Or\xf83\x7f\x81 \xf1\x85p\xa2\x07\x8b\xc6\x0e\xa3\xf7\x84\x13\x94U\xeb\x05\x86\xda\xf0\xbc\xae\xb9\xc5\x97\xfaA\xb2\xd0\xa9h\xcb\xb2 \xa1\xc2tn3v(\xeeuo\x7f\x17\xec\xf6\xf7Q'\xe0%S\x7f\xe9N\xad\xc2\xec4\xfe\x92\xd7Q\x04lq\n\xf5\x177k\x02\xe4\x98\xf2\xa9\xf5?\xa2G\xbb\xb4!\xf6\x98\x07\x12\x06\x89\x0c\xa2\x92\x14i<#\xfe\x83\xe9\xc7\x8f\x7f\xff&\xfa\xe3\xee\xb1\x1fL?\x9e\xfdr\xfb\xf9\xec\xc12\x04\xef\xe3\xc7o\xeeyJ\xb5vW\x9f\xa5oT\x10\xfd\xf1\xd8?>\xfa\xf8\xf1\xa3\x1f|\xc6m\x1b\xed\xf2\x07g\x01\xb6\xf4\xcd~\xf4\xc7c\x86\x18\xdft\x03\xc2\xeb\xbd`\x85~\x8d\x8fV\xa7n\x96\x06|hF\xdc\x0d\x10?\x184X\xd8,\xef\xb7\xbf\xf9]\xff\xaf\x8e\xb2\xae\xe1*\xd8\x11\xb3(\xf3\xb5Qm\xf2:\xc6T\xde\x85\xff:.Z\x06|\xaf\xe3\xc2AQ\xd3\xaa\x85\xdbL\xb6\xd6y\x1e\x18\xdb8%5\xfb\xe8\x94\xd4\xad!\x9c\x92\xdaa\x08\xadZ\xca\x10\xfa\xcf{q\xa4\xaex\x92r*#\xbc\x8e\x8b>b\xae\xf8\xcbS\xd2am\x9c\x12\x9a\xcd\xa3\x8a\xd4\xecm{\x0d\xc3v\x0e\xea\xa1\xe5\x9fGK\xd2\xd7@\xb3D\xb8\xc3\x0d\xcc\xb9i\xa0\xe6\xe3\xd8\x16T\x8ew\xde\xe0\x8f?g4\xb4g\xa1\x85l\xf2\xf0@VQ<\x9fkF1\xecx\x0e<\x07\x83a\n\xd6\x98\x94\xfd)\xac\xf4Sh6\x94\x8e)\xba\xe2\x99\xe6\xbb\xee\x07\xc0\xb3\xf2\xe9\x9e/\xad\x13\x03Eg\x1a\xe9C\x1ai\xda\xbd\x19\xd3.&~~\x95\xd5>\xe1\x1e\x9b\xfe>ej\xf74\x8a\x8a-P[\\\xdf-\xb5T\xef\x8ae\xc8\xac\xc7c\xbd8s\xf4\xed\n\xab\x8bi}6~?\x0c7\xcd#.\xe9\x9av\xdd-*\xafq\x15D\xeb\xb8\xf0o\xb6\xd8.\xc3\xe3\\\xb3l\xf8\xddD\xf9.\xbb\xc9 \x00k\x0d\x00\\\xf7\x9a\n\x80\xb5\x1e\x00\xbf\xeb\xffE\x87E\x05\x85\xe9\x99\x8e/97\xf3%yo\x1eF\xf3\xa8+\x99\xc2y\xb6J\xd2\xf9\xab\x17:\x99\x0c\xc3Oe\xd2\xab\xfa|\x8c\xb5\xd7\xb5E\xc8\xf6>f\xd8G\xc6B\xd13\xcd\xffO\xd9e\x96_g\xc8s\xf8h\xc2\x0f~\\\x03c\x80\x16I\xca\xa2\xf2H\xd6\xe6\xef\xd1\x1f\xa7\x1f?~|p\xf6\x80Y\x1c\xef\x827au\xd3$#\xccM\x9a>\x0c<\x14<\xb19\xa69\x9b\xc3\xc5\x0d6\x9b\xc9\xf7\xaa\xf3\x87nB'}\xb8k\xf4\x05\xde\xef\xc9\xba\xa8o\xb0\xc1q\xf7\x1b\xde\xefk\xf2\xa96}(\xd4\xd8\xfc\x8f \xff#\x9a'U\x91\xc6hY\xca\xdc\x98\xf0i\xc6\x7fJ\x80\x0e\xce\xec\x93\x01\xa3B\xc4\x90Sz\xde\xbeh\xba\xd1Z\x97\x94\xa2b\xa3\x91\xefW\xcaE\xa5\xb7\xd7\x19)_\xbd\xe8a\xab\xd4\x8b\xa2\xe5\x8c\xae\xef<\x08B\xb8\xc6\xfc\x91\x80\xb1\xc8\xcf\xab|S\xce\xda\x1cE{'\x9d\xf6\xb4\xb6yvJXH\x9d\x92dcL\xab\xf4\xd6\x92\x14\xd03\xdf\xdb\x7f\x88\xd1\x923\xb9\xa1\xe8\xee\xeaW\x97\x92z\xc9$\xf5\xb2\xa5\xbe(\x87-\nY\x8e\xb9\xd2\x90Z\x1f\xb8\x0e/\xf7\x13\x93m\xa1\x1ck+:\x7f\xdc\x8cY\xaf\x8c\x8b#\xc2\x83\xf9(\xcch\xeb!6\xbaO\x1b\x8d\xa3\xa4z\x9do2\xba\xc9Xo\xdf\xed\xb7;+\xe2\x92d57\x90R~\x1ea\x8cr\xe5\x01^\x8e\xca\xd6\x0f<&\xec\xc9\xf7.\x176\x1d\xd5h\xf6\x03Y\xe4%y\xdd\xbaAu3\xe7/}c\xb8H\x0e\x87 h2\xaf\x03FSc\x03\x9e@\xa6\xaf\xc0\xec\x9e\xcc\xf6oby&05\xac\xbd\x84\xb9\xd9V\x8f\xc55\xe4\xc1s\xc6Z#\n\xc8\xfd\xc4\x1b\xd1\x83n\x9b\xddC1JA\x194\xfe\x91\x98\xd5\x8bb\xd5\x1b\x96y)\x87N|\xfd`\xea\xf6V\xae\x95a1\x97Va\xf1\xa6b\xf0\xc6r\x95\x92g\x030\xdbf\x8c\xa8\xc7m\x01\xac\x8e\x94\xb5\xdd\xdd\xb5\x8c&[\xdf)\xc8X\xa4\xc7\x16\xa4\xf6\xf5\x90\xaa|\xa2K\xc7x!\x82\xf7\x0f\x8d\xbb\xd8\x94K\xc2\x87N\xe6r\xf0\x95\xc5\xd5\x14\xc3j\x9eF\xe7EI\xaeHV\xbf\xdb\x94\xcb$3*j[\xc9\x94\xf6\x9e\x02\x81\xef\xe1B\xd2fb\xa6\xcd\xb4\x9c\xfb\x17Sr\xe6\xaa8\x03\x9c\xf8@\xd0\xfa\xe1[\xdaf\xb7\x7f\xc9\xe2 \x85\xcaN\x17\xa9\x86\xfa^\x92\xfa9\x8f\xecW\xc7\xb3\xcbg\xf39\xc9\xe6\x9b\xb5\xebHtVO\x836L\x82~\x9c\x0c\x86\xaf.\x99\xe5$Z\n\xe9\xcf\xbe\x1av\x8f\x18\xeb@\x1a\xae\x81s\x11\xd2*\xcav\x9e\x80\xa2\xe4Z\x88\x08\x87\x06\x8aL\xc1N\x9b\xcf\xa3\xf39\xb9\xd8,_\xbd0\xae\x00\x8e\x0d\x99\x9d\x16L\x7f\xb8y\xf5B\xc4\x9c\x17EcB\xdb\xfd\xc4\xb6\x14\x12\xcd\xf9z\x00y\x1a\xb0!|B\x8e\x9f\x08\xce\xeb\x1d\xdf\xbcC\xc8\xd3\x15i{\xb8\"\x8f.7\xfc\x18\xc4T*\x124\x12\x0b\xa6\xf5\xb4t\xaf0\x8f\xae#\xe8\xf0\xb1\x83\x839q\xf3)n\x1at\x1d\x84\x03\x18\xc4\x19\xe9\xd4=g\xb9]\xbbw\x87\x01\x12\x0e\xb6\xefpT\xecO\x89\xf2n\xa3{'\x19$\xb7\xe19@G\x1e\xcfk$Gi\xff\x15Y&UMJ\xc2\xe8U\xdc\xe5@\xaa\xd5\x9b<;\xad\xe3l\x1e\x97\xf3\xbf\xc5e\x96dK$\xbe\x0e\\\xb0\xf1FB\xa4>,I(\xf2\xc2N\xaat\xd8\xecH\xa2N2\x94;\xb5/\xc6\x86\xda?\xc5\xa7\xdb\x1b\x010G\x97\xeeu\xbf\xde\x9e\x969\x1b\xba\xe9{\xa09gH\x14\xcf\xe7'T\x80\xfc\x91{+2'\xa8\xeeSn\x1e\xb6\xb3\xaf\xb5\xadn\x1a]\xe7Wc\xd2\x8a\x08\xff{C_c1\x90\xc5\x9b\x881\xa4'6\xc9'\xd3<\xf0=\x8a\x00\xbb\x0c4w<\x959\xd1w\xb3\xcd,L~\xb5\xfd\xed?\x8b\x8bzS:\x06\xee\x80\xedW~\xef\xae\xc15\xb0\xf2\x9a\x8bKQ\x06`f\x1f]\xa9\xff\xd8\x05\xcc%\xe7\xa0^\x88$\xba\xeaL\x8d\xe6\xdf\xad\x84kwA\x0d\x1e\x1f\xe8\xc2\xf8\xd1\xe7\xfaP\x11\x87\x8f\xba\x99\x00\xb8[\xddw\x07A\xbb\xfd\x8d.M/\xf3aM\xf2\xecy\\\xc4\x17I\x9a\xd4\x89=u\xc2\xd5\x97&\xa0\x80\x8e\x14\xe6\xb7SQ\xdc\xbb\xc7\xb2Ox<\x8d\x00^\x1b}\xfe\xdcKI\xc1\x9e\x95\x1b\"*\xceXL\xff\x93yR\xc7\x17]\xa7`\x93\x03o\x92g\xaf\xb2E^\xb2(\xf4\x16\x0c\x17\x1a\xb6x`Jz4\xc5\x18\xfb\x04\xdd>\x8c)\xbe+1\xa0\xf7\xccc\x1c\x03\x1cj\x97\xc8G\xb7\x91M\xa4\xce\xc2'Zy\x1el'nI\xaa:/\x89l\xc7i\xf9\xd9\x05[lJ\xda\xc3tZ\xca\x9c\x0d\x13\xc6j\xedi\xeb\x14\xed;G\x9c\xe9\xc7\xab\xb52\x84\xdc7\xe5l`\xa1\xe30!\x90\x19z%\xd6\xd8D\x95\n\xbe2\x84*\x08!\xf1\xcb\xe1\xd0E*\xcc\x9d`\xa5\xd7\x1azr\xda\x18l\x1e\x13Q\x90\x007\x96\x1e\x83*\x16\x93^\x81\x17~\xa8\x87,\xc9\xe6\xad\xaa'\xd9\xbc\x8f\x15\xfd\x81I\xebP ^\xd9B\x7f\xb3\xab\xbb\xd6\xb4\xf1m\x12a\xbf\x1f\xee'\x87\xb8`\xf2\xf5\xcc\xb8\x8eD\x08*\x01\xf7\xb4\x12\x18b>)8\x10\xefg\x11=1\x10\x80\xbe7[\xc5e<\xabI\xe9\x85p\x9f\xa7\xf9\xe2\n\xee\x01\xb1\x04A\xcc\x1b\xa2\xcc\xe3`3\xdaV4Y\xfa\xb9\xddR-\xd2]\xbd\xc5\x98\xf7\xd5\xb0*\xe1\xf3\xe7a\x941\x98\xb8\xe3\x04F\xaa\xef+\x03\xf2[n\xd0\xea\xa82\xe3*3\xbb$\x99&\xd6\x15E\xc5V\xaa\x7f\x91\xb6\x9b2w\x86\x1d\xd4\xdd \xb4v\xd8\xd9\x0bp\x04\xaf\xe3z\x15\xad\x93\xccG\xa7\xad\xd6b\xfd\xc6\xfb\x02\x1dt\xf86\xf8@>\xd5\x83[!\x89fy\x9a\xc6EE|d\xe1\x12\x13bg\xf2e\x0fYs\xb8\xcf_\xb3Y\xe9\x12\xcf\x8aH[\x95\x82\x93CQ\x94\xf4<\x12\xcb/\xb8\x15\x8f\xe4\x96\xe2\xa6\x830>\x01\xee\x8d\xd9q\\\x11\x02\xa2XO8n\xfe\x14\xdcy\xd0\x84\xe2\xeb+B\xf5\xea\xa5\x86\xf7\x9e\xd5\xc9\x15Q\xf2\x08\x91\xe8\"\x9fwRH \x81z(\xbc\x8f\xee\xbb\xdf\xb5\xff\xda\n\x9cW6\xef\xdb\xc7z\x86\xb3\x17f:\xd6\xfb\xea\xb2(\x0e\xfb\xdfv\x1b\xafZ.^}\x0f\xaf\x94\xf5\xf2\xb0+\x15\xcf\xf8\xf3n?\xcc8\xfe\xf0\xdb\xee\xf3\x82\xcf\xad\x1bub\xce\xfa\x17\xe1\xb0\x1f>\xea\x0e`\xc5:z\xdcy|\x85\x8f\x0f\x0e\xba\xe3Z\x8364\xdb\x92u\xdf\xcb\xdfu\xc3\xb9\xf6n3\x17\xaa\x03\xdb\xfe\xc3'\xddQ\x9d\xf3\xee\xbb\xd3\xb9n\x1c\xdb\x92~\x00\xe4N\xe5\x13\x8cQ\xa6\x8b\x1f\xdc\xaa\xf6 \x8e\xba\x9e\xd2\xa7p\x04O\xda\x8f\x9e\xd3Z\x9dj\x97\xc68\xde\xcf\x8c&h\xcc4L&\xcf\xa2\xbb\xf6\x14\x1fu\x93qMZ)\xc8\xba\xac\xae\xce:\xec\xad\xb9Sz\xb6\xca\xa0\x80\x8c\x84\xabO\xfck\x96\x8ew\xd8\xfa\xec\x9d\xd8n!\xf2\xa4\xdd\xbe\x90\x96\xb7\xa9\x06%O\x8b\xa8\x9f5\xdbtv\xc6\xe6\xe8=\xec.\xd1\x14\xf2\x03\x8e\xc0C/~\x16\x8ck\xc2L\x155w$1\x1cC\x0c\x13\x88\xbb\xf6x1\x9a\xe2\x05\xa1T\x95\xd5\xc9\x9a\xf4\xaet{\x13\xa6\xfb~\xd5\x89\xf3@\xc1\x94\x85<6\x01w\xa9D\x07\x98n\xf8\xa8DU\xcd\xd1\xfe\xe8Q\x95`\xc8\x81s\x16\xbdC1\xa0\x88\xcek\x0eD\x1e\x0e\x89e\x87\xffQ\x8d\x88\xf0*\xabsLa\xbd\xc1\x85\"\xb8P\xd9\xb0\xb5\xe4\x07eUuKJ\xc9\xe3:B\xe0\xbe'\xb3<\x9b%)\xf9P\xc6Y\x153\xfeuI\xeawy\x9e\x92\xb9\xbf\x83\xcc\xc1,\xdaT\xe49\x9e\xe6|\x01;\xb3\xce\xa3\x82\x94T\x02\xf5\xdf \xb1\x11\xe4|\x10\xe1`\x7f%I \xe5)\xf2\xe1i\xbd6\xe9\x8d\xf0*d/\x84U\xb4\xc94\xeb\x86\xd6D\x9d\xed)\xf8\xec\x9e\xf4\x15<\x85\xbaI\xfb\xf74\x80\x9a\xab\x81\xf0\xb7\xaf\xbc\x1b\x1e\xec+\xb3\xa5\xf0\xb3\xf1\x96\xc2U\xa4\xcbj\xae\xf3Q\x13f%t\xe9>\x7f\x86\x9d,:_\xe5\x15\xbf\xdb\x18cC\xfc\xb3\x91\xf4\xec\xf8;\xdc\xdeU\x02u\x07\xfd\xde$\x1f)\x9f\x9dj\x9e=\x1f\x06\xdc\x1b3\xe0\x1c$U\x0e^=\x9b\xce.\x88\xef\xdd\x1b\x0fN\xdc\x06mX\xf20{\xfd\x9bW\x93e-\xbb\xf6\xc2\x16\x9e\xe7Y\x1d'\x19)_e\x8b\xbcO\x05z\x07\x83\xf8\x8bN\xf1}\xffl{a\xb3\x88\xc7\x08R%^\xbe\xc2\x11\xbc\xefZ\xa95\xc3}\xa1\xf8(%U;\x88\n\x0f\xe7\xf9\xa2\x15\xd9\x06\xe3\x11\x0d\xf4.\xe6N\x07\xa0\x10\xfdfn\xb4A\xde\xd3\x87\x1e1T#\x82\xd2\xb9\xff\xd8\x93\x8c;\xdfL\xe0E\x87\xeb\x10A\x11\xaa\x1fn\x18\x01B(L\xe0\xb2\xc3\xd4a\xa2\xd4\xd7y\x96\xd4\xb9K\xc4\xc7\xae\x84\xd1\x112\xcf\xd9\xbd8\xedl\xc0\xd2U\x7f\xe8B\x03\xb6\x1f\xa3\xd6\xb8\xfc2\xb4\xab\xaf\xaf\"\x92\xfdcC6\x82T\x8b\x00\x19\x92x\x86L\x08\x95\xf5\x9e\xc7iz\x11\xcf.\xd5\x8a\xb9F~\xa2\x87\xd8\xe0\x9c\x196\xbc!\xd7\xd6ik\xe7\xfc3\xcf\x19R\xfa\xde\xe1w^\x10\xc2&\"Y\xb5)\x89\x92\x14\x97\x03\x02\x93J\xf77\xab\x10=1\xde<\xc6\x13\xee\xd6XG\x17T`!sf\x0dQ\xf9\x1f\xd0\xacY\x8cJ\xdf$\x0b\x8c+1\x89o$#\xad\xb8\x9c\xc6g\xf4\x8bp8\n\x07\x83\xd6\xe9\xe6\xa2. \x9e\xf2\x92(8C\xacc\xc6\x82\\`\x11\xadbT\xaerH>\xa6\x90\xfcQ0\x1f\xba\xee\xd4N\x1c\xd6\xf7\x8bF|\x15]\xc5i\x82&#\x1c\xeb\xfc<\xe4|\xde\x8b\xb7\xaf9A\x11\x96\xec\xad0C\x0dr<\xf1B\x93\xad\x8c\x07\x94\xaa\x93\x18\x83\xa3\x15qU%\xd9\x12b`\x95!M. \xfca\x9e\\\xfd!\xc4\x97\x80\xfdr=\x85\xe8\x07\xdf\x07\x90\x97\xf0\xfd<\xb9\x82\x07\x7f\x8a\xd0-DL\xd0\xb1\xc7YJ\xdb\xc7\x0e_\xe6\xf9@w/\xf3\x9cu\xf62\xcfEg\x99\x1a\x03Z\x89U\xc6\xf9f\xec\xf5\xc3*\xa9`\x1d\xdf\xc0\x05\x81Y\xbc\xa9\x98W\xcd&K\xf0\x02!\xc9\xb38Mo \xcd\xe39\x1dP}\x9dC\x92\xcdIA\xe1\x9b\xd50\xcb\x8b\x84Tt\xc8lL\xdc\x07\xc7\xb0\xa5\x98\x9fX\xdc\x19\xf9\x0b\xd3m\x1bR\xf8 h\xe2\x9ci:\xb0\x9a\x9fRq\xbb\xe0n\xa7\x06\x05\x122H\xe7E\x99\xcfHU!o\xc6\xc3\x99\xfaUt>c\x7f\x1a\x15B\xf4\xeb\xa5~\xe2T\x92\x7f\xe3\xeb\xf2d`\x12\x8c\xa1QSa?\x1d\x12{\x0cSY\x80\x7f\xee\xcf\xd8\x15\x80Y\x07L{X\xb0\x1e\xfaB\x05\xe5\xde7\x17i2\x93\xf1\xbb-\x96)sa,k=[\xd4\x9237\xf3\x85\xf9\"\x14@\xab\xa1\x17E\x9eq\xba\xc3\xd2O1\xac@\x82\xa4d\x1e\x84\xb0\xd0\xb6\xa3\xbfk\xfd\xb1'\x07<\xc3\xd8xvS\x0e\xe0\xc0]!\x1f\x99\x19\x00\xb7\xa6\x12\"r\x84;o}\x93\x82\xfd\x06\x8e\xe0\x95\xb1\x89\x0b*\x82a\x13)\xfe\xab C\x00\\9\"\x89w\xf7d\xa5\"a\x16\xc2E\x08I\xe0\x88\x08\xc6C\x8b\x1bK\xe3\x92^\x07!\\\xdb\x8f.\xb7\xfb\xfcf\x95\x07N Ud\x1c\xce\x08\xa2_X\xdb%\xd6\xcf\xcd\x81\xf8p\xcfD\xe6j\xdc\xed:\"\x83\x8e\x0c\xc6T\xb5\xaf\xd0n{_Q\x96\x7f\xe0\x01\x020\xd4D\xa3\x9191\xd0/!V\xed; '\xaf\xcb\xddc/\xa7u\x8f/9\x0b\xfb\\\xcek\xa1;@\xeb\x98\x9e\xb7n\xeb\xa7F\xf7\xa0;\xde\x93\x10b\x1dD(\xac\x14N\x8e\xb9\xa5\x0d\x86c\xdd\xe0^\x1b\n\xee3\x8ffq\xf6\x9el*\x9e\x19\x8a\x8eb\xd3\xc92C\xc5\x0b2\x8bg+\xc2v:\xad\xa1oQP\xf6M[_6\x8f\x9e\xff\xf9\xe4\xf9\xff:\xfd\xe95\xaa\x16\x99\xf6Q\xdf\xc2\xa6\x97\x93c\xc4\xc7\xe2t\xd8D\xf9\xa6&\xe5\x9f?\xbc\xfe\xd1\xd4Ke\x1b_\x08\xdd\xa8\xbc\xa2\x88\x13b \xb5Q\xe1\xe2Y\xaf\x16\xe9\xba\x90\xa9\x97O\xe2\xce)\x94\x9e\x94A\xa8\xfaWf\xcc\xb1r\xb0e\x10\x8c\x80H\xf5\\\x06\x9c\xe1\x91\xbf\xe5j\x1b\x1c\xec\x85P\xc0.\x1c\xec\xa1S\xf4\xc7\x0c\xfc\x8a\x94W\xa4d\xd5g\xe6\xea\xfa\x99\xe9tWtg\x1dx!h\xaee\xfb4\x03\xb5K\x86F\x0e\x19\xaf\xdd\xd3\xef\x19P\x81\x07\x98r\xd5\x90\xe9'\x94GIV\x91\xb2\xfeP\x12\xc2\x1c\x1b}F\x9d\xe81`\xe4\xd3.X\n\x80P\xb3\xd3kE\xab>\xf2:\xefG|\xfa\x85\xf7O\x87\x8f\xbe\x0d\xf4\xcd\x9b\x8f\xa5\xc6\x0fH\x03$TM*\x1a\xe37|\xed\x98\x95@\xd9DS}\x1a\xa01\x8fN\xb9l\xd0A\xb1\x060\x00\xeb\xb1\xf6;\x98\xc8Z,\xe4+\xcf\xeb\xd7\xb3\xf8\xfb\x82\xab\xbb::?'\xd5\xeb|\xbeI\x89F\xcd\xc3C\xb2f~\xf7\xea\x0d\xc3\xe7b\xbc|4\x7f)\xd5f\x8e\xa1\xd4Z\xd8\xcd\x859\\\xdb\xb4\xeeV\x1d\x0d\xaf\x83r>\xff;\xaaVqA:f\xd3t\xe7\xce\xca\xe4\x82L\x94\x8at\xfa\xa8\xc2\xfa\xc7&)\xc9\xbc=\xe2yR\x15\xf4,v\xfe\x80\xf9\x94\xd5C=4+\x10\xdc\xe1\x12\x84-8\x98\x11W\x7f\x0b\xcd\xaf<\xc0\x14\x16I\\\x89\x90\xb2\xccK\xf5\x8e\x04\x1f\xf4\xb8.\xfd\xddt\xbd*\xf3k\x8c\x80t\xc2\xbfj/\xa9\xde\xbc\xdb O\x95\xcb\xe4\xc7\xdd\x1bJ~\x9b\xdc\xb3S\x14\xa9\xae\xba7\xa41\xaf\xdf\xc5\xde\x0d\x7f\xdem\xbf\xe2\xcf\xbb\x17\xc0\xfc\"\xb9\x97^\x80_$\xf7\xd2\x0b,\xf8\xf3\xee\xc5/\xbbH>x\xa2\xbbH\xce\xfc\xc3\xc7\xddy\xb1\xfb\xe3\xfd\xc3n\xfbW\xbc\xfd\xee\xb5\xfa\x9a_\xabw\xdbY\xf2\xe7\xddy\xb1\x1b\xe4\xde=\xf4\x05\x07\x7fw\xba\xe7\xbc\x99\xeep\xae\xf9\xf05W\xc4\xb4zw\x94\x9f\xf0y\xef\xda\xfa\xb4\xafN\x7f\x0eG\xddh\xda\x97p\x04\x0f\xdb\x8f\x9eQN@\x04\x00|V.\xf1\x12\xa9:\xebD\x18|\xab\xd6\x12\xa1\xeb\xba\x95\xde\xa9\x950\xf4n\\\xe7\xa5\xa9\xf6\x07\xb5\xb6\x88<\xd8\xae\xf2\x9a\xdfb\xcb\xdf\xd3gg\x94g\x9b*\x03.\xe3\x9b3O\xf7\xf4\x87\xcdbA\xca\xde\xbb\x17q\x1d\xff5!\xd7\xbd\x17<\xc7\x87\xee\x03\xd2{\xf82\xcd\xe3\xfa\xf0@\xdf=\xbe|\xf4P\xff\xf2UV?6\xbe\xd9\x7fd|e\xea\xecu\\\xf4\x9e1\x17\x14\xf1\xf8C\xe7-\x8b \xd8\xfb\xe8\x94\xd4\xfdg\xc8\xdf\xf5\x1f\xdf\xac/\xf2\xb4\xf7\xf8\xa7\xc487|\xf5<\x8d\xd7\x05\x99\x9bk\x98\xa6O\xdf\xb5\xe6O\xc9\xbc\xf2\x1e\xc9\xa8\xf8\xeam\xe7\xe3\xbf\x91\xf8R\x02ig?\xd4262,\xef\xab\x10~\x0e\xe1M\x08\xefu\xb7w/B\xbc\xbb\xc9\xe0\x1e\x9c\xf6\x99\xeb\x9f\xf8\xab\xe7\xfdW\xff\xe0\xaf.\xdb\xe7\x03ei_\xe1%\xee\x0b*\xb5\xc31\xbc\xa2\xe3\x90#\x98\xd0\xdfA\x10\xaa\xda\xd3\x17R\x84x\xd1ol\xe7Z\xcd[\xdaa\x9e\xe8\x0c^\xe2\xbdBWJ\xa5\x9f\xbe4\x89\xc1thW~M%\xee\x1fe\xd3\x18\xd5\xf7E\xf7\xe02\xc4\xbf\xa5\x1d\xff\x13\x8e`E[\xe9\xbd\xa5\xe5\x078\xa25\x8e\xe0-\x15\xb8\xf1\xafwz\x05\xc6\x85:\xc1\x8a\x8e\xe2G\x83\xaa\x03[\xf9 \xdb{F\xff\xfa\x01\xb5ToLr\x81\x98\xeeO\xac\xee1\xfcr\x0b\x13Xv'\xff\x13\x1c\xc3\x82v\xbd\xf1_0\x1d\xe7\x04f\xf4w\xcc\x7f\xf7\x1a7\x82F\xf4\xba\xf3z\xfa\xcf3\xd9\xc1\x1b\xee/\xfb\x8bA\xefH\xc7\xb8\xa6\x1d\xfe\x93N\xbf\xdf\xdb\xef\xcc\xbf\xde\xa3\x0d\xde{`!\x18\xcb\xa0\x8f\"\x7f\x85#x\x8f\x9aj\x1d\x9a\xfcU\x0e\xf2\xaf\xfd\x97\xef16#bF\x88~\xed\x0d*\xca\x08`\x92}\xe9\xd9t\x00\xde\xdcbXC\xbf\x14\xbb\xb1D&\xe7}\xd7\x12<\x08u\xe8\x7fn\xeb\xd2p\x9f\xf3\x02\xc7\x9d\x87\xa0t\x9c\xbbvLa\xf6g8\x82\x7f\xc01b\xc6\x1c&P\xc0\x04\xff\xbe$7\xd5\xab\x0c\x03\xe2\xf6:\xfd\x1b\x1c\xc1K8\x16{{\x02\x7f\xee\x01\\h5\xfd\xbf\xd1U\xab\x15\xde\xcf4\x93\xbf!5)1\xc6\x13z\xe8\x9e\xa1%\xfd\x0b\x9c\x8f\xdb\xec\xe4\x93\x91\x1c\xe7\xc1\x93.\x87$8N}\"\xaa\xef\x1e\x8f\x9669<\x12\xe6u\x81W~;\x18Z\xbc\x95\xeb`\xe4\xb8\xf7\x1f\x1b\x92\xc2\x1ety2\xce)?\xd6g\x85=x\xd2}\xbei\xc2\xf62\x0f[\x11A\x97\x1d\xa0\x15%#\x83\n\xdfV\x94\x8d\xe9\x19\x8b\xb2\x81\xce[\x14\x04<\xcc\xc6\xb0{{{}a\x02\xb1\x1e\xe8N\x06\xc1\xeab\xeb\x81v\xd8cX\xb9{\xd4\xf6\xab\x8d\xcb\x9c\xb4\xaeuG\xae\xf0\xe3\xc7z\xcc<\xec\xc9H|\xb0\x8f\x0f\xb7\x1dl\xe2+\xa9\xa0\x99\xc9\x18&\xec\xf7\xbe`\xf0]4\xcc\xa5\xde2\xfed\x1b\xa6\xfeF\xa3Q\xa3@\xaeZi\xd7\xa8L\xe1Z\xc6\xfb\xb0\x0f\x13\xc0\xe0\xfd}\xe2e\xbdc\x93\xa8KA\x1a\x0b\xb9\x82\xc5\xfd\xbc\xbf\xcf\xaebs?i:c\x1d\xa1\x14\xc9\x82\xf7o\x82\xa7\xb0\xbb\x1b\xc3\xf7\xb0y\x1a@\xc5\xcd\x11\xa65\xecB|\xa6?\x17Y\xe3\xfawr@\xa9\xec\x816\xb5/{\xa9\x9f\x06\x90\x8a^L=\x08\xf6\x87\x05\x0c\xcd\xfc\nS\x8a\x11\x96S3\x04\x9d\xdeo\xfb\x85\xefn%a\x0f\xbe\x1f\xf8\xa5\x01A\xbf\xc0\xf7\x91S*\xa6\x15i\x12\xab\x87\xe05*\x16\xaf{Y\xce\xb3\xd3*w1\xb7\x81A\x05c@B\x0d\xd5\xcbzZ\xae\xa6\xf5\xa7=H\x99\xf7$\xea\xe2\xd9\x0dV3\x05\xc9\x1f\x90\xfe1^w\x04N\xd1\x884M\xe9/\xafr\x9b\xc0\xbc^,q\xdayTs\\\x11\xb4\xdedQ}\xc94;3\xd8\xdb)\xb0\xa4k\xd9\x80\xc2\xcf\xfc\xfd'\x07\xc1\x17h\xcf\xbe\xf6\x92\x1bM \xf54\x03\xc3\x88\x18\xbd\xa4\x92l\x91k3\x87\xd1\x92\xe6Km\xee0\xc0\x94\xb5e6\x81C\xfdKT\xdcM\xe0a\xef\xa5\xc659\xb3\x1ao\x82\xb2nSrF\xb9\xb6\xfb\x9a\xfb\xd0~\xd3\xccOs\x96g\x8bdYEi\xbeDs\xc0~=F\x02J5\xdb\x00\xa8f\xa7\x89\x8d\x91`\x97Z\x92 \xcb[\xafDR\xc5\x12\xfe\x04\xfb\xa8\x87f'\x00\xa5\xca\x94\xb0\xee?\x05J&\xcb\xa7\x10\xef\xee\x06\x94F\xd2\ngjkZ\xb2\x89\xa0\xfa\xd3\x91\x12\x92\x95+M\x83)9\x8b\xe2\xa2H\x11\xe5\x06\x0d\xda\xc5\xe9\x1a\xd1\xb5D\xfd6&)f\x17\xee\x1e}\x88\xf7\xb3\\/\xdb}\x8fOY\x05\x8aD\xbd\xf7\xf4!{\x8d\x18\xd8{\x8fO=\xad[>^Vc\x0e\xa8\xca\xe4\x17\x8f\xa8\x99\xf4\x91\xc00]\xa7S\xc2\x9a\x07\x8e21]M\xe3\xd7\xb9vpc\x8f\xc4\xc6\x978\xae\xa5u\xfa\xb3\xc0\xc0`\x90\xce}\xc4:\xbe$\x7f\xae\xeb\xc2\xa7\xc4\x97\xbc\xa4\xaf)Y*\xf2\xaa\xc6\x1f\x06\xd5\xc3\xc5&I\xe7\xef\xc9?6\xa4\xaa\xd5\xe6\xd4\xe7\x06\xd2\xc1r{\xab\x1f\xf1G\xfa\xfa%\xa9\xf2\xf4\xaaU\x9f?\x1a\xac\xcfMM4\x9f\xf17\xfa\xaf+R&q\x9a\xfc\x93\xbc'\x95\xfa\xad\xfa\\\xffe^\xbc\x9a\xab_\xacHZ\x90\xb2\x8a\xe8\xf3\xbbEc7\xdc\x91\xc4\xad\xd6\xeb\x0c\xf0\x84\x9e\x96\x8d\xfa\x84\xfe\x10-\xf7\xe9\xd1\x15w\x1d\xa1\xb5\x8cGQ2\x81\xd2p\xd2\x98\xa3\xe3\xf2.'\xba\xa8<\x1aM\x8e\xe0C\xe8h\x91+\xc8\xc5\xa0Q>W~\xa1\x97N\x94r\xcd\xa7|a\x00=\xf0If\x1anF2\x15k\xceNDx\x0d\x83\xe7wGp\xd0\xb9\xdd\x00^\xb9\xe5\x9c\x7f\xf9\xfc\xd9\xc0A\xb0\xaf\xf5\x90e\xfb\x7fS\xc6\x17)\x19\x00e\xb6Y\x13Q\xc7\xc0\x10,I\x8f.\x01h\x82\x10C\x1d\xd9On\x01\xb0\x1e\xbf\xa8\n\xe9\x96#\x9f\x88-\xd3\x1f\x138Dl\x11\xad\x8c\xc0\x9d:\x9a\xfbY\x08^\xcc\xfd\x8a\xb3\xfe\xd4s\x17\xfb\x18\xde\x9c+\xef\xdaO\xbdRG\x05KL\x05\xb5_Gt?\x1f\x1c*\"\xaf?\x1d\x1c\x82J\x072\xff\xe1\x81\xf2e8<\xf8\xce\x97\xdfn\xfbek\xb4\xe3\xbe\xdc\xba\xcf\xc3\xc3\xc7\xe6O5R{\xfb\xd0o\xbd\x92$\xb2\xd4c\xb7@-\x0dr\x13c@\x1fy\xf6\xdb\x93T\xea\x07\x93\x1b\xf1M\xec\xb6.\x1f\n\x7f\x82\x83\x8e\xb5x\xc3\\\x1e\x9c\xc1q\xfb\xe7\xc4\x98\n\x8d\xb29\xbe\xa6\xf5Cc\xeb\x87\xed\xd6\x0f\xcfP\xff\x1eDW\x07o\x0bRbL\x9aWh^\x12\xd7 \xc6/\xb9y\x9d\xcf5\x1e\x9f*\xa8[\xa9\xddTE\x0b&kP,\x10&\xe8\xf87\x13\xf4#\xf0I\x10\xb0(Qy\xd39s\x84U\xd2r}\xac0\xc7\x96\x174\x86a\xab\xf6'\x01L \xe1W[\xfaE\x1e\x9e\x9e\x9e\xbej\xfd\xc5\xcc\x02\xc9@8K\xdd\x12\x8dC\x00\xfb\x12\x99\xc8\xad\xc0A\xbfnG\x84\x80]\xf0\xce1}P+QZ\xb5\xf3\xff\xfd\xfe\x9b\xff\xf1\xf7{\x7f\xf4\x83\xf3\xdd\xa3\xe9/\x1f\xcfn\x9fN\xbe\xff\xd3\xe7\xe8\xe3\x83\xe3\xf0\xe3\xc7?x\xde}\x96<\xed\\g\x99\x0b\x0df\xb0\\\xe8\xcc\xf3\xb0\xb1\xa1\xdbo\xfa\xad\x95~}\xff<\xf8\xe5 \xbc\x0dD\xd3J\xe6\x12\xff<\xf8\xa3@\x80\xe6\x83\xe9\xf9Y\xf0\xc7o\xf8s\xcb\xc6UF\x851X\xe7~M\x87\xd1\x0f\xa4nX\xdc\xd8v\xa0\xf0\x06\xbd\xfb\xfdtL\xa667\xb66+N\x1fw\xf6\x90\x03q\xc6\xc4\xcaDWA\xdc\xc1\xb1\xe0Vb\xcf\xeel\xb3g?\x7f\x86\x1d\x12\x15q\xbd\xaa\xfa\x8du\xaa\xb3jC\xb1-@Qs\xf1\xea\xfd\nR\xb6\xcf!\xc9\xa0\xd4\x9b\xa8*\xeaXZi\x9a\x1b\xa2\xcc\x03\x87\x85\xf7\xee\xd9\xfbg\xafO>\x9c\xbc?e\x83O\xa2:\xff\xa9(laSD\xb9\xe2\x0eg\xb4\xa7ibP\xa6\x8aB;\x8c\x07\xe9el\x83}\x1cX\x87\x04\xd0\x18j\xdbk\x8aR\x15df\x8c\x13\xa6+t\x95XX\xd1\xdc\xfd\xa35\xa9W9\n]-(\xbb7 i\xfed \x9c\xa8Z4:(]\xc1\x0c4\xbe\xc9\x06]-(\x85\xa1W\xb2D\xe8\xcd\xe0Gz\xa7\x97\xfe\x9b\xf6\xaf\xadT\x96\xa0U[b\xe3\x9a\x0bp*g\x95~\xe6\xef?\xee\x06\xff\x00n\xb6\x86o\xbby(\xea(\xa9\xde>;=t\x125\x98.$/H\x16\x17\x89\x91\x89\xe0Y\x15(\xae\x17\x0d\xae\xd3\xc9\x1ez\x1a\x16<\xa9N\xaf\xe3\xe5\x92\x94\x07#\xc6P\xb1O\xb6\x18\xc3\x81n\x0cy\xf1j\xce\x12\xf0\xd7Q2\x7fY\xe6\xebwq\xbdz\x8d\xf8\xcd\xdcI\xeb(%\xcbxv\xf3\xaa\xff6\xa6o\x97\xa4\x96\xc7\xf9\xfb\xf8z\x84\xf8\xc2\xd9[F}\x8f\xd9Ib\xd7\xd7J\xc9/\x12[\xd7\xbc5\x18!f\xbb\xd5\\+\x11\x8b\xcb&\xa1\xdf;x\xe2$\x83'Nb\xa3z\x89\x12\x19i\xc7p\xef%H^\xa2\xf2\x85\x83\x0c\xca4\xf7\x13\x19\xf0\"\xf6\xf9\x1f\x9b\xb3\xa8\xca\xd7\xc4\xb7\x03\x14\xba+\xc2\xee\x16\xb5uu\x91\xd7\x0c\xd9\x10\xd0>>\x9bK\xdc\x80#\xd8\xd0\x87$\x9e\xad\xd4\x87\x15\x8b\x93Q\xaeQ\xcb\xc5w\xc4\x98\x0dQ\x90\x99~mY\x005D/\xb3\xd4\xa1\xb3\xd9\xc1\xb5F\x96\xaf\x8e\xbe\xf9F\x8emn\xba\x8b\x82\xde\x89m\x0c2+\x0e\xda\xccx\xca\"\x9f\xbd\x17\xc2\xa2uZ\x0e\xac\x9d\xc0\x18\xcc\x92\x15\xafIMJ\x0d\xdb!\x8a\x1cgE\xc7\x19\x07\xb0\xe3\xb0\xe7D\x91r\xe0\x948\xf0\x08;\x9did\x0d\xf6{\xb3<\xab\x93lC4\xa9a\xd4r\xc5]qs\x9f9\x7f\x99\x9cqE\xa1\xddj\x83\x02uK9\xad\xa8tB\xffc\x91\xca3\x8a\xc6\xf8\xf4\x08\xa6\x99ev\xc0\x87\x86\x87\xcb\xb4r\xa8M\x076k\x84\xa6\xfd\x00f}{'\x13\xbd\xd4\x15\x12\x9d\x9f\xe7e\xb2L\xb28U\xc4)\xe6\x96\xa1}\x83\x12\x8cBT\xc2\xf6O\x96\xb7\x9f%L\xe7W\xed\xd6\x81\xe8\\\xab\xbbE\x86\x00Td\xc4\xac-\xf4\xba\xcd\x98\x02\xbc\x80#\x98M\xf7\x1c\x00NKa\x84\x91\xe9\x0d\x15P\xda0*:0\xaa\xac=\x9b\x19%\xfb[\xe4\xe5\x9bm\xcc\xce\x18\xeb\xb6\x04\x0e\x9d\xb9%U\x84ZV\x06\xda\xd7-\x92^\\QzQ\x07\xe0\x15e>\xdf\xcc\x08\x1f\xdc\x15\n\x02\xb3<\xab6\xeb\xf6\xb3\x8a\xcc6eR\xdf\x88g\x9f?\x83\xbf\x9a^\x9d\xa1\xb1\xdb\xd5Y\x08s\xb6\xf3V\xba\x0ca\xddB\x01\xb3A\xc6f\xa5\x909v\xa64\xed\xd0\xbf\xb97\xa0\x03\xc8\x80\x83m\xcd\x14\xf5N\xf5\x81{\x18\x98\x14\xe1\xbar\x03G\\Ab\x9f'X3pt\x8b\\\xa0\x8b\x10\x9d\x16(\xd1M\x1b\xa2;\x0f\x9e\xc2\x8eO\xa7\xe8_\xc0\x11\x9cG\x19\xf9T\xfbA\x10\xcd\xf3\x8c\x04O\xf9\xe4]\xc1%\n\xed\x8f\xb2z\x17,\x00\xa8\xdb\xbcD\x91#>\xa1(um'3\xdd\xc2n\x90N\xce\xc6\x8eZ\x94\xde.\xa3\x0c\xcf\xc9\xb6\xad\x01\x87\xc7\xa7\x91h\xa4+\xa7#QKW\x9e\x8fD7]\x19\x87\x82\xba\"\x17\xf92D\xa7\x95\x0eZ^\xd3\xe5\xa3\x98I\xa1\xe6_\xc2\x11<\xebb\xe6'\x8e\x99;\xf6\xab\x981\xe5\x8a\x87\"\xbf\xdc\x06uu\x85bb\x87\xd7v>\xc5mE\xde\x1be\x1e\x81\xb7\x19*p\xc4\\\n\xc4\xbcq\xfe\xd4q\x9d\xac\xb5\xb6\x150n\xfdJ\x0f\x1b\x8d\xf9K\xef\x89<\x89T\x85\x08G\x8e\xceMQ_E\xbb\xe0J\xd8\x87\xdf\xe9T\xb4\x85P\xd1\xf6\x82Z\x03\xf7\x17\xb6k(\xf8\xf0\x98\x07\xa4b\x11\xa1\\\x15rs\x08\x8d\x06\xab\xdf\xe9jL\xa7D\xb9w\xfc\xfb\xc7\xeb\xb3\x07\xcb\x84]\xfe\x0d\x80u\x9c\xe9\xc1\xe3'\x036\x16\xffo\x98\x1e\xdc\xcd\xd5s\x9a\xc7\xf3S\xa3\xc2\xb0\x94\x9c3\xd3R\xd0\xe6\x0d\xe9\xdb\xf5\xc9\xc6\xe4\xdb\xcb \x90(\xbf43\xf2\x9b2\xa5U6e\xca\\\xc5\x8c\x15\xab:\xae7\x15\xe6$\xc1\xbfl5Y\x8aPQ\x9b\xfe2\x7f\xb1\"\xf1\x9c\x94\xd5\x04\x12\x9fD\xfc\x87\x81B\xe8\x1b\x89\xe1\x08r\xf1\xe5\xd4\xe3y\x84\xee\xd3\x9d\xe7\x19\xf4\x10\x1b\xccC\xf9\xf93\x9c\xfb\xb1\xd9\x0f\xca\xdf\xa0kKM>\xb1\xf8\xe5\x17i~\xc1\x14X\x17\xe8'\x1e\x88\xcd\x1c\xd5+\x929(\xb9)\xc9\xceY{hH\x97G\xf3\xb8\x8e\xd9\xdf\x9b\xc0r\x00]\xf5\"\x01;(\xea\x84\xa63.\x8a4\x99\xa1\x02\xe9\xc1\xcf\x15\x8bO\xc1\\w\xfer\xfa\xf6MT\xc4eE|LA\xb4l\x8c>\xe3\x05\xf91\x8f\xe7C\x0c\xf4-\x1d\x85\x0e\x84\xa2\xe4\x98\x01\x01\x8e(\x85\xc8\xa3\xfc\xe2g0j\xf5\x9dX\x83\x9c\x8d\xf5\x84\xdbl\xeb\xb9\x01\xfd\xe9\xc3a\x91\xf7\xa9\x83\x9b\xe1B2\x9cT\xaaO\x19\xf6\x8c\x94a\xafM\x19\xf6\x18e\xd0\xe3\xaa\xce\xbf\x04\x94\xa5\x15\xe3SC\x8e\x10\xa1\xd6e\xf6@:\x1d\xaf\xf9r@ \xba9\xcd\xe8@\x85\xbf \x9a\xfaGI\xc5\x1d\xa1\xa6\xd9Y\x00\xc7\xac\xd2\x04\xa6\xf4\xff\xb3\x10\x7f\n\xb9\x8b\xe2\x93\xf0U\xd1@\x1d\xf1\xb7\x1b,s\xc0ld\xe0\xa4\xd0Gfy\x99\xf0#C\xc4\x89\x13\xcfd\x9c\xd1\xa3\xadl\xaeVm\xfb\x0dS\xe0\x17\x12\x15I\xf1\xa5\x06,\xcdM\xe3,Oy\xd6\x9a\x97\x98\xf0\xcc||\x90(N\xd3\xfc\xfad]\xd47\x18;\xd8|||\xd9\xcc\x8fE\xf2\x1dJ\x1f\xf5WX\xdd\x04@es\xfdb\xc8\xc8\x1f\xfb9\xcb\xdfp\xc1\xa2k\xa8 \xcd\xe5\xd7y\xff\xe3+\x91~'\x9b\xe5s\xf2\xd3\xfbW\x86\x80P\xa0p\x92\xa8\xcdM\xb8j\xe8\xa6\x99]\x1eX\x1dma\xd0\xfc\x16l\x81\x19\x95\xcf;\xf7\xe4:\xee0\x08\xcdW\xbe\xb9m\xa9rfd\xd4\xde\xbf8C\x97G\x18\xfe\x1d\x8e!\x8f\xd6q\xe1'A\xf4s\x9ed\xbe\x17zt\xf3z\xebMZ'\x0c}\xd4J0\xe9\xd4\xd7\x03`V]M\xc0\x0b\x0d\x06\x99\x15\xbe\xfd\x1f\x07{\x86\xf75{\xbf\xf7\xc4\xf0\x9en\xbfj\x02\xdeg\xaf\x0fP\xa4^\x94\xe9\xc0\x14\xd0\x9e\xe7\xb4M\xab\xe1{\xe0\xceU#\xda\x02\xce73U'7Dx\x85\xd1\xd64\x1b\xb8>\xa1\x9bvg\xa7\x8c\xaa\xcb\xa48\xa1\x88\x9ed\xcba\xab\x82\x9c\x87\xeb\xefo\x0bc\x88V\xe0l\x95\x1d\x83EQ9\xf6/\xa2)\xc6^ny\xe2\xbf\x9d6\x82v\xa3Q\x88\"6\xf84\xa1\xc7\xcf\xc6\x8f\x8d\xeeJ\xa2pc\x1fC\x1a\xd2\x10\xf2 \xd4\x05v\x0e)Oo$0\xeb\x86\x9dB\xa90Y\xa0\xe1\x91~\x14l\x85\xcc\x0e\x0eI6Of\x14\xa3u\xf1R\xbb9o`\x00\x8f\xd3\xdf\x8e\x95Aq\xc3*\xf9\x08\xee\xd4\xf3\xd0\x9d\\[=\xc7\xd6\xfe\xb1!\xa5!\x8203\xa9Y\xe4\xe5Z\x7f\xd0\x0c\x86fM\xfb\xfb9 \xc6X\xb3@\x83\x04\xb1\x9fL\xc9\x19;)\x07\x10|`3\x168\x15\x83\x8c\xc3d\x12\xf9\xf29\x7f\xf9\x01_\x9a\xed;P\xe8{\x80\xf4\xbb\x88\xcb\xfa\xe3\x03\n\xa9\xfbT\"y\x90D5\xa9j\xbf\xb0\x9a|\xf08j\xa6\xf8\x9d\x80J\x04.\x01d\xe4\x1a\xe6\xa1\x06\xa8=\xf6\xd4*\xd6\xb06\xa3\xb8(H6gAu\x92i}\x86\xf6\xbdC\x00\xd6om\xa6\xf4\x94\xe3\xac\xfc\xc40\x1d\x1ez\x98\xe1T\x7f\x07j\x91L\x1bq\x058\xf8V\x98)\xb2*\xd2\xa4\xf6\xbdco\x00\x01\xae\xa0g\x0b\xbc\n\xa1\x1b\x8aB-K\xba\x9b\xa6{\x03G ^ O\xf7\x07j\\\xa0=\x86\x19\x85nl\xf8q\x8e\xe9\x96\x04 db\xe6\xcd\x00\xb2t\x90#\xd7 \x87\xeb\xa6\xe3\x8bu>%f%6e\xab.ZCl\xa8\xf4\xf9PFmP\xa9u?\x0b\xa7(&\x8c3\"\xc4\xb5-\x9d\x8d(\xf2fSG\xb0C\x96\x0c\x08\xcfG\x12\xb0l\xbf{O!\x83\xef\x81<\x85lw7\x10bYC\xb8\x87\xac\x8d\x04gRG\x8b$\xadI9~1\xccZ\xfb[\xc1O\xde3\xb9@@\xd3LI\x8f\x84c\x0fv\xf1(\xf7\xfal\x1d \xa3p\x11BE\x99^}{L\xe1u\x04K\xd8\x85\xeb\xb0\xd9\xd4x\x928\xecj\xed\x94\xbe\xb2\xc1q\x08uT\xad\xf2M:\x7f\x91_gi\x1e\xcf\x9f\xa1Z\x8deg%\xe9\xc2p\xdd.\xed\xc3\xfc\xcc?\xe8eK\xa4Eh\xc5\xf7\x86\x94\xe2Z\xa3\xe6\xb9\xd0\xa7\xeb^\xae\x1a\x8b\xe7\xfe\xcb+\xf1Rc\x0f\xad\xba\x1a\x0b\x9b`\xf9\xec\xcf\xec\x8c\x136\xc1l\x07Ri\xf8m\xf9\xbf\xe9\xea K\xce5)\x97\xe4U\x86\xcf\xde\x96\xb4\x02\x1cA\x8ao\xb8\xc3\xb7C\xc0\x1bh\xd6Zz\xdf\xd8\x11\xdf,\x11\xb2]Y\x7fq3\xda\xfa\xb2E\xad\xfb\xad(B\xf2\xeeg\x90a \xbaK\xab\x9b\x03\xaa\x8c\xf5,2\x08\x82\xaa\x01\xbf_\xf2\xc8\xe85\xfe\x95\xf9\xa4\x97\xa8[6\xd1F}Z\xf9\xe0;\x8d\xc5\xfdZ\xa0\xb5\x169\x97\x02\xc5\xbe\xd5\xbd\xbd\x11\xdf\xf6Ru\x02?\xf5\xe4\xae\xd2\x83\xa3\xed(op\xda\xe8\x83a\x02\x9a\xf4\xee\xdd\x1d\xc0\x8f\"\xdbI \x88?=2\xaf\x14S+y\x94\xad\xe3\xf2RRj f\xae\nUL,!\x17Kn\xa0\x97\x01\xf6\x8d2\xc0~[\x06\xd8?\x1b\x08C(Ng9\xcc\xeb2.\x1c\x0f\x14\x16\x82\xfdi\x00\xd5u\xc2T\xc5QQ\x92+\xe4\x8d3\xf2\xc9\xca6\xce\xe2\x8a\xc0\xded\xb0\x0e\x08\xd3,\x93\x10[\xdb\x84X\x91\xc2\x1e5\x02\x14\x96u@O\x1c\x0c6\xbf\x92\x04\xac\xf9\xfb\xf3gL.\xa7\xdd6q\x10\xc2N\x1c\x95,\xa4\x04\xa6)\x9b\x91\xa2\xce\x07w\xb9Z\x18`\xe0\x08\xf6\x1d\x0d\xb1.J\x12_Zk\xda\xef\x87\xe5\xb5$\xef\xff\x11\x9d~\x7f\x1e\xda\xfb\x17\xb5\xe0\x9a=r[3\x12\xd5{\xcc\x1c\x9fdu\x08\xf4\xe7h8=\xf9u\xc1\xc4\x87\x1c;\x00\xe1\x89\x1d\x08,\xe3lmYjlm\xdfa\x1f(\xa7_<$|\xc6&\xe13\x1c\x96/y8+\xce\x81\x19\xbb\x90<\x9a\xb1\x1f~\xb8\x88\x08z\x92,\xec\x1f\x86\xca\x0ex\x14\x82\x8f\xf9\x1eJ\x8c\xed\x82\x071\x06y\xa1O\xcbt\xf8\"\x0b$\xe0\x1c\x90Q\xb2\xab*2\x8aa<\xa1{]=@|\x16\xaf\xd4\xadw\x07,\xa0[A\xed\x1a HU\xe4YE\xbe\x84\x82\x1c|\xf7\xebn\x8d.\x0598d$\xa47\x13\xa3\x0eP\x14\x84\xdc\xc1\xa1\x1b\xe4HT\xef\xb7\x89\xc8\xfexP=\xfauA\xc5\xc7l\xc9\x0f\xc3\xc0\xe0\x82\xbe\x8c\x8c\x18\x9c\xc3Da\xcd}goN\x82\xe5\xd0\x01\x83\x10$.\x1d;n\x04I\x0b\x0e\x9e\xe0b\x1e\xb0\xbb\xb4\xb8\x9e\xad\xfc\xfd\xc3\xc0\x10\xafFW\x9ai\x1c\xda\xa7\x01w\xb8\xba\xcc\xc4\x8b\x8e\xdd\x01.\x87\x0eh\xce\x1a\xf4s\xae\x94c\x19%J\xc5Z#\x08\xf8\x8f\xe7\xf9\x1c\xc3\xc5\xf2\x9fL]\xc5L@ \x97{Q\xde\xc6G\xf5A\xa8\xbb\x99S\x0b\x1b\xa5\x03\xda \x19\x8b\xf2\xcb\xd1\xeb\xf3\xd0\x02'Q\xeev}\xf0\x16\xd1\x0d\x9c\x89\x0e\x9c\x89\x04'}\x1cv\x93\xcfw\x0b\x82\xf1\xe1\x81\x1d\x8c\x92\x8c\xc6\x17\xe5\xa6\xa8}\x8f=\xf0\xc2^ \xefna]X\xf0 +y$\x9b{#\x86R\xd5y1`\"\xa9\x07\xf9-K\x93\x871S\xa7\xc6o\xa7\xf4\xcc?x\xa2\xd7\xf9i\x02\x18\xdc\xea\xd4D|\xa0v\x85t\x03\\\x16\x92\x10\x07'%![(\x8d\xdbnVB\xa125*{\x06%B>\x98\x07\xfe\xcfU\x9e}\xfe\xb4N?\xdf\xc4\xeb\xf43\xa6\x00\xfdx\xf1\x80\xf1\\_|\xb9\xd3\x8d\x10\xb2\xad9\xe1\xc3\xfd\xffxk\xc2\x81\xc1\xb4/1I\xa0\x06Q\xfe\x1eCi\xe2\xd5\x97\xf7\x00\x83\xa0\xe0M\xba]F\x16\xe6\x04\x99`\x02\xddkTS\xe3\xb3\x01\x13)#\xa3\x85\xbaR\xba9\xd8\xbc\x9b\x00\xcfti\xce\x95\xa5\x19GZ5S\x991+g\x9d9\xaa#i]\x0c3\x19\xeeW\xa4\xfc\x0b\x85\xf1\xd2\x8d\xcaiL\x85\x9d\xf1\x19i\x94ua6\xca2\x0db\xee0\x08Q\xb9e&\xeb\xd4\xfaJ\xdf:zAY\xf6\xb8\x88\x9b4x!\xe1\xc5\xf3\xb9\xb0\x8a\xff\xfc\x99\xb2#\xeb\xfc\x8a\xb4\x9f0\x06\xc5\x10\x99\xc6\xb8/;\xc6Z\xa6 ^\x0d\x82\x0f\xa7\xff\xf93\xd0\xb9\"$\xd7\x9b:\x16\x90D\xc9\xfb\xc6\xd1\xd4x=\xd8\xcf\x15o\xdfo\xe0AA\xd7\x07\x80|\x8a\xb7\x16\xbag/\x08)\x9a\xe7n8\xb4t\xc0\xa1\xaf\x8e\xc87Fcl\xb3\x87\x06\x1f\xe1\xa9\xbc\xd6Z\x92\x1aM\xaf\x7f\xb8y\x97'\x19\xa5\x08\xfd\x18\xb8\x00.n\x0f\x82\xbcw\xb2\x86\x86\xda\x88\xd1\xbf3\xff\xbas\xa3\x84\xbe\xecz1t\xeb\x7f\xce_\x1ej\x0d\x06\xae\x87\xec\x10N\xc4\xa7\xda\xdb\xdcO\xe26W\xf7\xf2T|\xaa\xb5~x>d\xc3p)>\xd5:\x0c>\x13o\x1f\xf7\x8d\x18\x9a+\xdc>4\xe3\xf9|2,'\x8b2(3\x81\x90\x9b\xe8>\x1d0\x1c\x1c\x92\x9b@\x91\x9d\xb4\x154\x08\xd6o\x89\x93\x85 $\xbaw\x94\x8a\xde\xe9|9a\xb6Ny\xfb !\xf5\xba\xab1S\xba\xe8\x1a'\x8a8\x899\x19\xca\x86\xa3\xe5\xdc\x06\xdd %\xad\xb7!L\x87\xb6\xa3\x89\x9a\x9b\x0e\x1ae=\xdb\x8a\x0b\xdd\x9a\xdaV\xf1\xaa!\xb6\xe6\x11f\xcc\xeb\xf85\xa9c\x1c\x1d\xa9\x00\x83}\xadI\x8d\xaa\xcd\xb5_3\xd5B\xc7\x8f\\\xd0\xfc\xcf\x9f[xEk^\xe9)\xd7U\xc8\x9b\x15\xe9l\xafl00\x9e\x85\xf5Y\x10\xde\xf1\xc8m\xc0\\v\x0e\xc7a<\xbb\xd0\x83`)A0\x1ee\x14\x06\xe0\xc2\xc8\x00h\x9f\x8a\xdd\xd7{\xa9a\xcf\x8a\xb8$Y\x8d\xa1\xba5<\xda\x10\x83\xd6\xf1\xf0\xac\xed\xf1\xaa\x95\x84\x9aG\x98B\x17\xf1\x95]\x9b0\xbf\x97\x92\xf9\xbd\x18aE\xfbE\x9f\x18\xd4\xc3\xa2s\xb0\xa5O\xf1\xba\xef\xfd\xa3\x01\xc6\"\x8d\xeb\x9ad\x13\xd0\x04}Yl\xd2\xf4\xe6\x8d\x08g\x84s\x1e\xe1;\xbe\xf0g~\xea\x93\xae\xf6\x1a\xf4\xe3\xc8:\xddh<1\x93\xea]\x99\xaf\x93\x8a\x8c\x18D\xc1\xb5\x86s\x9f`,\x14\xa7\xb1p\xcf\xae7\xe4\xda\x117\x86\xe3\xa3\xf0\xa1\xe0}m\xa5U\xb5\x01\xb8\xa8\xdb`\x08\xcf\xc1U\xc4j&\xf7\xaeL\xd6I\x9d8kA\xdcg\xb9\xf9\xcdg\x99T\x7f\xa9\xf2\x8c\xcb`+\xdd\xfb\xe7L\xde\xed\x89i\x16\x84\x92jn!/\x9b\xb4\xdc`\x1a\x18\xefQ\xe3\x1b\x9fT\xaf\xb9&b\x02W\xba\xd7\xcf\xe6s\\\xb0\xa6\xdaZW\xed\x7f\x92\x8c\x94q\x9d\x97#\xe6\xf5\\\x92d\xe5\xfb\x97\xcd\xd7ns\x13\x1fL@\x93P \xa9\x18\xdb=\x81B\xf7\xf2\x84\xe5\xaeu\x1eq+x\n~\xdc\x1fc\xeb \x95\xdf\x15C\x1f\xa9\x0c\xfd\x9dRap#t\xa3\x8e}A\xae\xb4'\xdb~\xba?\x94fm\xf8\xd3'{\x03\x86M\xb6O\xb7\xcebw\xb0\xf7\x9d\xf9\xd3\xff`s*q\xbfw\x07\xfeJz>\x8c\xe5o\xe8;\xae\xe8k\x97\xbcv\xcfF]_\x9d\x850\xb8N\xea\xd5\xf3\x92\xccIV'qZ\xc11xI6K7s\x82&`U\xbc&\xf7Y\x9cx\x8d+\xb6`\x03\xc4z\xdb\x14yd@hB\xe7\xbe\x81Pm\"p\x9d9\xbd&`G]XML\x01\xecX\xf5\x1e\xb0\x8cyTA\x8d\x177,\xfc=\x9b\xd1\xb6&\x9a\xd0g\xc6\xcf\x06\xd2\x1b\xcd\x9a\xe5\x99h\"\x88\x01\x8aw\xaea\xe0@\x95c/\xf2\xb9>x\xa7.\xcb\xc9\xef\xcc\xbf~\x85\xdb\xbdd\xe8\xb2,\x1e\xf0\xe9]\xc7\x97,\xb7\xf2_N\xdf\xbe\x11N\xbd\xb3\x94\xc4\xe5\xf3x\xb6\"6\xbb\xd6**\xd2\xcd2\xc9\xaa\xa8$\x8bJ\xf9\xb0cB|\xeb\x9aQ\x1eT\xc2R\x9b\x17J\x10\x97z\x95\x18\x92\x99\x9c\xa0X\xd8\x19\xe0<\x9f\xe1\xf0X\x14]\x12\x84\xdd\x19,TX\xf8\xd7C\xeae\xddf2\x84;\x01\xd3f\xba0\xe0\x97~JB\x8c\x9a\xb6\x07m\xd0i\n\xeb \x01N\xd5\xb0cI\x81\x931MM\xd3X\x13\xf2>\x08\xf5\xdf\xad\xf5\xdf1\x9cN\x08~\xc7\x8f.$\xec\x85\xb6~\x9c\xa6o\x17A\xd8\x8d\xf9n\x06\xb55k\x9b\xbc\x11\x1a\xa6<\x17qE^\xe4\xb3 \x9clCi\xf8\xf0\x07IfW[\xa1\xe5\xbdE\xa1\x82\xfe\x8b\xa4\x9aQ1$c\xec\xaa\x86\xebmj\xf3\xd5y\x1d\xcf\xca\\\xcb?\x8b\xb2\xce\xe7$\x15\x94\x86W\xefGE\x01\x854\x9e\xbb\xe4E\x86\x8eos\xdc\xac]b\xf4mv\xd5\x1b&\xdb\xb8\x1d\x8b\xf2\xa5\xee\xc7\xa2\xb8\xba!\x8b\"\xcf\x8a\x9e\x07\x87\xc9\x16\xb4[\x98\xeb\xa0[\x8fc\x1c:D\x91#\xb48v\x882\xac\xf2\xe6\x8e\x1e\xe6f\xb4>\x1b\xa283D\x9d\x0f\x9c}8D1(\xd2\xfd\x00&0\xeb%\x13\xb3\x9d\xe6\xa0\x90^\xc2N\x083\x8b9\x94pl1\x1cd\x8bE\x92\xa2{W\xff~\xde\xc4\x8fT(\x8c\xbe\xee\xaa\x1d\xb0\x0b3\x17\x19R\xdc\xb1]\xd2\xa3E\xfa\xcak9\xc66}\xd1\xd7^\xf2\xa6U\xc2\xa5\xaf\x89\xf1\xe3\x9dy\xf9\x0b^\xdb\x91\x97?g\xebr\x99\x14B\x97\x87<\xa7\xbe\xf25\x8b\xe7U\xd7\x1a\x19\x1d\xb8\xc1\x13\x89\xf8Ibd\xfai\xad\x13tc\x0e\xb1E\xbc\xd5\xbe\xa6\xffl\x04\x9d\x0b1fN\xed\x97\x18\x91\xd1\xcck\x8c\xe03\x1cy\x8c\xdb\xc0?\xe1t\xbf\x9b\xfa\xbd\xcfZn8\xf7\xa8\xb5\xb4\xe2\xd2\xfc\xbe\xe6\x15K\xbbY\x19Rnf\xfe\xd6\xba\x83\x83\xbd\xad\x93\xbb?\xd9Z\xfe\xdfZ\xfa\x1f\x18\xabU\xf6W\xdf\xdc\xb9\x10a\xe2\xc8\x0d\xfaOy\xa2\x9b\xd9\x03TAE\xb3\xb8\xa87%9\xad\xe3\xd9\xe5\x872\x9e\x1186\xbd\xe1\x04\x9d\xfe\x1b\xcd\xf2\xac\xaa\xcb\xcd\x0c\xdd\xdf'\xecYEkR^C\xfan\x06\xec\x99\xe5\xaaA\x1fx+k\x05\xde*Y\xe0\xad\x92\x05\xde*ww\x03\xc8\xa6e;\xf0Vi\xe0\xacqpkRU\xf1\x92`\xae\xc6\xbd\xb3\x90\x99\xd0\xd4\xad\x93J\xa7l7\x11\x8c\xac\xb9\x8bW\x9dUC\xf5\x05\xcf\xedC\x8f`\xf5\xa9\x02:\xfai\xd8q\xa8\x1a\xad\xf5\xfb\xed\xf12\xa9^\x96\x84\xa47o\xe25\xb1\xe7w\x90\x86\xe4S\xd2\xf2\xc7\xd1\xae\x1d;\xc4\xa5\x0b\x9d\x91\x80\x97Q\x92\xcd\xc9\xa7\xb7\x0b\xca\xa5\xfc \xee\xefS\xda\x9d\xcb\x87Y\xf30q\x0d=)WZ4BX#}$\xb1\x12e\xf4i\xf2\x1a\xb9K\x17M?\xc7:\xb80 \x1dX\xe5\x85\xa0f5\x0b\xc1\x13\xe7\x05\xfe\x10\xf9\xf8^\xb4\xbf\x98\x89\x90\xb4\xd5\x83j\xb6\"\xeb\xb8\xfb\xb4\xd5\x88\xf2\xbc\xdd\x95\xda\x0c\xef\xe8\x946\xa7\x1f{\x82cg\xfd= \x9f\xe2u\x91\x12\xefl\x0c\xc6v\xc8\xf7\xc3/ \xc3\xadW\xff\x96*X$G\xc6\xedp\x07\n\xda\xfe6B\xf3\x86~03\n\x87\x8cG\xf9\xc3`\xef\x8c\x9c\xed \xc5T\xef3r%\x91>\xb9F\xab\x8f~'\x1d!TP\xdd~E\xb1g\x90r\x97\xa4\xca\xd3+\xe2w\xb5\x82\x96}[G\xf3\xa4\x8a/R\xc6]-\xe2\x19\xc1\x00Q\xdd1\x84\x18]\xfb\x92<+\x92\xeaC\xbc\x94\xd9C\xfd:\xd0G)\x1e\xa2A\xb34!\x99\\\xc1Nt\xb7\xdfL\xcbxh\xd62\xfah\xed\xffm\x80\x91\xe4\x1e\x05\xba\x8a\x82\xa1\xd4\xa7\xf3\xa9\xc4[\xad\xb7A\x8a\xbb\xf9;\x03SY\xfa\xa9!\x8cb\xe6\xef?2\x06Q\\\x0cEP\xd4\x86\xb0[17\xf9'\x86\x00\x8a\x99\xff\xad\x8e#^s\xbe\xb7\x0d\xd8\x1ce\x0d48\x94\x82A\xae\x06CL\xe5\x8f\xe8\"\xc9\xe6~\xb6I\xd3\x90\x7f\x16\xf0X\x1f\x14\x9f1m\xad\xd2\x04\x7f|\xba\xb9\xa8KB\xdf\xce\xd5\xb7\xe4\x13\x99mj\xb4\xd0\x11\x7f\xd3\xc7\x9d\x18\x8fi\xebA\xabB\x13\xf01\xed=\xa4\x15\xdbJd\xe5g\xc82\x85\xb0\xb3\xe1\x87M\x92\xf2f\xae\xa2w\xcf\xde?{}\xf2\xe1\xe4\xfd\xf9\x0f?\xbd\xfa\xf1\xc5\xc9\xfbS\xd3f\x82#Xi_\xd0\x0f.h\x9b\xef\x99\xd4\x84\xed\xaa\x0f\x10r$-X\x9f\xfd\xdd\x90\x17\xaf\xe6\x13Xc\xe2\xfb\xf6\x86\xc0q+-\xc8\xac\xd1\xe2\xf1\xffY\xd8\x17\xfe\x00\x9d\xfc\x98 \xc5\xfe4\x99\x8e\xdao [\x14\xa5\xbd\xcbm\x17o*n\x0d \x84`\x1d(.\xe8y4\x96fe/l\xf4R\xc8\xc3xt\xef{\x83\xbe\xbb\x94\x08WRi\xcf\x02\x88\xd7\x06\xed/\x89Vy\x85\xbe\xba>\xff\xf3\x082\xfc#@ 3I\x80\xbf\x17\xbf\x8e`\xca\xc5\xdcY\x9e\xca\xe8(\xde\x84\x8a\x13^p\x86_^\xc4\x15y\x17\xd7+\xfe\xa9\xfcy\x04T\xba\xb3/\x80\xaa\x03\xc9\xc7\n\xca\x16e\xd3\xde\x80\xd01\xfc\xe9\xfe\x17\x98\xb8l\xadW{\xb2\xf7h\xdbO\x0f\x1fn\xad\x1f{\xb27` \xf4\xef%\x9a\xa9\xbf\xee\x9c\x1bG\x9bdv\x01\x89\xb8I \xd5\xeb\xb8\x18\x08.\x9e\xc3@\x84\xf0d\xc8\x1dX\x1a\x0chu\xbe\x9b![\x83j\xc8W8\x15\xedj\x87$\x82\xa1\x1fj\x9d\x85\x17C\x9e\xc42C\xa86h\xb4\xe0\xe5\x0f\xf6\x86\xdc\x81\x87Y2E\x14\xbd\xf6I@E\xc1\x02\x8d\xb6\xad\xaa\x1a\x11n\xfdP+5\x89x\xeb\xda\x81\x8b8\xda\x87\xda\xb7\"\x8e\xf6Cm\xc3\"\x8e\xf6C\xed2 o\xf0\x87Z\xafm\xe1\x0e\xfeP\xeb\x98\xed\x94\x08A\xb9\x00\x1e<\x80;\xf9\xb5\x98\x98K\x82^.\x12\xf6b\x98\xcdd,\x92g\xf1'\x99\x93\x8b\xcd\xf2GrE(\xe7\x98d\x8b\xdcR_\xde\xfaO-\xael\xac\xe2\x9f\x93\xaa\xce\xcb\x1b\xb3\xd5\x9a(\x8cy\xb07+|s\x1d\xaa\x16\xcc:|.Y:\xdb\x07U\x1dSi\xc46\xd4\xc2\xb5\xbd\xc6\x0c\xc3\xd2\"\xaf\xf8\xa1$d\x82\x9b\xea\xdc,4\xa9\xa5Z\xe5\xd7/\xe8\x02\x9a31\x89\x12\xa7\xa93\x1c\xd8\xd2Q2M\xa5 FY-h\x91&\x17\xafI\xbd\xca\xe7\xd5\xa4\x8b\xab\x9dd0\x14u\x035\x10\xbcu\xdc\x1d\xc6\\\x93RJ\x14\xca\xc1\x04\xfc\x06eI$\xb7w\xbe$5S\x16\xf0\xceE\x05n\xf3\xad\xd6\xe3\x8f\xfa\xd5Wq\xf5~\x93\xc9\xaa\xecg\xbf\xdau\x19\x17\x05\x99\xbfk\xce&\xfaT\x98\xfa\xac\xe3\xc2\x97\xd5X\x1d\xa5\x89@\x84\xe4\x91\xc0\x89\x1a\x13j\xd1\x01\xc7>fD\xd4T\x8c\xe7s\x7fz\x166\x1cp`\xf9\x80\xe3\\\xf3\x11\x7f \xbf\xdb\x14\xf3\xb8&\x1c\xec\xbe\xda\x94\xde\xd2`\xd0\x11\x87\"\xc1\xbcA\x02\x12\xc2\xd4L\xbd.\xc9\xcd\x04<\xa4L\x03h\xc7Y\x03\xbb\xee@\x14\xe4\xef\xe94\x1a\x9a\xc7\x8c\xf5m\x1f\x82z\x9bV\x87Z-1\xbbBc\x17j\x19\xaa\x8c\x8f!\x83\xfb\xb0\x0f\x13\xd8\x0bBd?\xf6\x9fB\x0e\xdfC\xf6\x14\xf2\xdd\xdd\x00\xcai\x8e73\xadK\xb6\xdc\xc1%\x17\xdd\xbfy\x94\x95 J\xf3e\x13\x86Jc\xbd\xa1\x16\xb39\x8b\xc1Fd\xe8\x90a\xcbtE\xca\x8b\xbc\x1a\x8a\x04\xb1\xd5B\xc9v\x99\xf3_{\xd9l\x0d\xc0\xbf\xcf\x82M\xbd)\x06\xce\x84]\xf0\xce(C\x7ff\x8b\xca&\xcaWX\xcb\x86*\x8dYNKx\x05P\x04dAE\\lk\xd4\x827\xb9\x83*\x13Qr\x83\x08\xd0-B\xfa\x99*\xf4\x99\x9ex\x98F\xb8d\xd70h\xf4\xde\xab\x10\xc0\x04t\x04\xda\xc7\xb0m9\xbf\xc9Qk0\xe9G\xc4\xab\xca\xad\xdcu\xb7\\m\x93P[\x14>\xd1\x9d^\x889\xcc\xc5G\xaeHy3\xce\xb1Y-R\x86<\xe2I\x98\x9d\xbe4$\x1bkU\xb1o*\xde\xb7T\xd4tL-K?\x0f\xc1\x988\xb1[0\x16D\x08\xb3\x10\x16!\x14\xe8\x14\xbf\na\x8d\xee\xab7\xf6\xb1\x80n\x85p\x1a\xc2\xf3\x10.Cx\x16\xc2\xdb\x10\xde\xb9A\xbe[,+\x11o;~\xd0\xadL,V&\xdeje\xbae\xdb\x95\xea\x16\xcch\xdd\xa7A\xf9\xa8\x00\x16C%\x96\xf9r\xb6[\xa4nq\x0fk1T\xec!*l\x85\xa5b\xb8$7x\xd3\xbf\x98.T#\x9a;\x07\xde\xc3\xff,\xe0\xf1\x9d\xd7L\x0f\xe3D\xe3\xd9\xe9\xa3>\xf9\x92\xdc \x0d1%.u-,\xe2\xff\x97o\x93f\xa4\x8f\xbfl@\xe0\x96\x11\xc4V\\\x93H\xd9\n\x9a\x89)\x98\x1b\xa2\xe2m1\x9d\x9f\x85\xa8G[H\xab+\xd5l*\x08Q\x8d\xa6>\xc2\x93\x1dC\xa9\xcc\xf1\xcfu\x88\x87B\xa2\x0dD1\x9b\xe6\xd17\xdf\x94dq\xc6\xb2\x95\xee\xec\x85\xa8=\xdb\xd9gf\xbf\"\xed\x91\xa4\x99\xfb\x0fC\xb4\x0d\xee\xb8\xbe\xd0\x9fU\xf3\xd3\x98 \xd3\xb58\xa7C\xb2\x15J\x1c0\xce\xc5'8\x82\x13\xc4\x1d?\x08\xa2y\x9e91r.Eb\xe4\xe1\x7f\x18m\xc0\xe8&p\x04\x9fD\x10\xf9\xe7p\x04\xf9\xf4\xf4,\xc4\xf8\x95\x0b!\xf7\x9c\x06!\x86\xac\xd4\x9c^\xcf\x83\x10\xdeb\x96\x17\xc4\xb2\x10\x06\xd3\xfa\x8e)\xf1\xd8\x84H\xb6\xf2\xaf\x04\xf5\x9dg\xff\x0d&K\x91^W:\xb2\xf6\x16\xe5\xb6\xd9\xf4\xed\x19\xd2\xb4\x80Y\xb8\xa5d\x19\xd7\xe4\xff$$\x9d\xfb\xa5\xcf\xd8\xd6\"\x08\xc1\xab\xf7\xbc\x10\x0e\x1e\xdd\x05\xcdr\xc9\x81e+\x18x\x9aJ{\xa7,d\x0c=\x83\xef\x1c\x1f\x0e-)\xb8\\\xcb\xbf\n>P\xa0\xbd\xc3\xcc\x06\x19\x8b\xd0\x96a$\xbbw\xff\x0d8K\xe9r\x80\x87\xfb\n\x0b\xf8\x1c%\xbcK\xcc\xddZ\xdc\xc5\xfe8tt\x15\x1c*\x82Q\x89\x9b\xf4\x8b_62\xb8CV\xf0\xf0Ny\\\xc7\xcc\xaaC\xe5\xce&v\x07\x94M\xb2\x91\x87\x98\xb3\x153\x0b\xc6\"c\xde\xc3\x80\xf3\x9e{\x8c\xf7\x8c\xadi\x02m\x85\xc9\x1cw \x9b\xcbq?Ty\xe1\x87\xfb!\xec\\P2s\x12\xf1]\xa4\xfc\xddM\xc05\xb68\xa5Hs)\x9426c>\x0ca\xe7\xfc\xce\x89\xe2\xc3;\xd8\x81\xf0/D\x14Y\xde\xbd\xeb/\x9b\x14[\xc1;\xd86\x92D/\x92,\xa9V\xfe\xc3\xc3;\xc1-\x87D\x89\xb6\xd2\x1b\xd9\xde\x9d\x8c\xec\xf1\x97\x8dl\x1b?sS\x913t\xf4?7\x95\xedp\xf26\x84\xd8\x9e\x98\xd0V\xa6Tj\xa7$\x97\x92\xaf\x87\x8f\x1dB\x1a\x9b\xca\x94\xd2\xbc\x10\xa9\xc8\xc3\xef\xdc\xee\x0e\xba\xc5\x10\x15r\xa8\xdc\xb2\xc4\xf1\x9d\x8b\x83\x9b D\x9b+\x0c\xc9\xcb\xcf\x8d\x82\xeb.\xe6\x8a\xeeBj\xe2\x1f\x852f\xac\xa2\xba\xc8uw\xf8\xdd8mc\xf5\x19\x88\x81[`1\xa5\xd5\x18\x84x\x8d\x1e\x02w\xa1\xae(%\x97\xb4\xa5zb;\x9a<\x1e\xdf\xf9N[\xc2\x11\xac\x85\xc6\xa1\xec\x88m7\xfeR\xbcZ\xf28\xa3K)\xc1\xed\xefo\xb3J\xfb[p\xa4\x02\xdd$l\xb7\xd0En\xc1\x97\xb1\xf1n\xc1`\xcaq\x1el\xc1Pn=\xd0-N>\xb9W\xf7\x1fQ\xe8\xb2\xd4\xd3\x9cA|\x14\xf0\xfd\xbd\xc7\xf6w9\x9a?d\x12\xfa\x16\xfc\xa0\x1c\xd6\x81JO\x0e(\xff\xb7\xa0<\xdfJ\xe1\xffV[\xf2\x7f\xce\x99\xc4\xbb\x85%3\x16c\xa2\xfc\xdd\xd6\xf7}\xe5\x97j\x8b~-Z\xc1\xf8\xb3\xf9\xb8An\xad\xa0\x91\xee\x8c\x9c\xcb9\x18\xcb\x7f9\xe73\xef\x96^\xcfc\xf9+\xd6\xf3\xc8\x93\xe8K\xf8'9\xe2\x91\xfc\x92\x1b\x0e\xdc\x86P\x8e\xe7\x87\xa6\x8fB$(t\xf7\x1e\x8ca\x7f\xa6\x07\xc8\xee\xd0Mu\xe0\xc8\xee8\xb07\x16k\x8a[\x9f\x04}\x03\xe2\x9c\x99\x1d\x96\x81\xcd\x8a\x18\xa4=\xe8\x9bxM&\xc0\xa3.|\xfe<\x14~Q\x94V\xe8Y\x95!\x92\x8f\xfd\xdc2\xfa\xd1Q\x8d\xecVN\x94(\x8d\xb6r\xb2\xd1@\xbbw\x9b(\x8aE\xe4\xaam\x16\xdb1\x1eU\xbc?\x9c\xcc\n\xa4\xf7\xd6\x92\xd4\x82\xd3\xac^\xe6%k\xce\xaf\xd5\x8c\xae\xbf\x0d\xd0U\x83\xec;\x84\xbd4\xec\xecX|\xb72\xd8J\xc9K`\xa1\x0c\xb9\xd2\xfb\xcc-u\xa7Z$\xe8q\xe8\x16\xe0~\x05\xe8. \xc7hno?\x02\xb8\xd6\xf9\xa9Q\x13\"\xd9\x11\xa5\x06>\xb1\x1c\x1f\xaa\xd7n\xcb\x1f`Z\xf3\xfc3_\x11\x14\xef7\xd9\xf3|\x93\x0de\xb0\x1a\x0d\x0buB]\x98\xfbDl\xb0\xaf8)\xde\xd7\x87d\xc8 \x7f\xf4\xb4\xf4K\xdc\xcc\xcbm\x951\xe2\xcf\xb4V\xedeX\xf2\xaa\xaf\x08\x0fA\xe7^es\xf2\xe9W\x03\xc9\x87\xa4\xc0\xe4\xcbj\xe7N0\xf2\xb2\xcd\xfa\x82\x94\x1e\xec4\xbe\xd9p\x0c\xf7\xf7\xc1\x94&\x0d\xee\x04Lt\xb7\xde%t$\xbdkX\x83\xbb\x1f=w@\xd8\x96\xae9\xd8\xc8\xb6\xcc\x92\xc7\x916_C\xd4\xb2\xb3\xb6\xbf\x87\xf2\x9c\xa7TG\x1f\x8c\xa1x\x91_\x08+v\x80}E(\x0d\x03\xa5a\xf1\xda\xe9;\xe8f\xe1y&F\x1e\xach\x8d\xd7\x0b\xec\x1f@\xc6\xbd\xcd\x19Dm\x8bE\x0bf\xd8\x19NY\xa1\x16\xb4\x9b\xd0\x1aqKV\x025\x82\x19sK\xf0\xbb+\x00\xde\xff\xcck\x88!\xcb\xb3\xfb,\x0f0\xf3\x1b\xf3Bp\x19-\xf0!d\x91\xf4\xf1b\xb1\x83\x1b?.1\xf5\xb0\xc5Ys\x1e\xcb'2=\x91\xf0\xd5\xec\xb19\xcd\xf7l\"\xad\xf7\x1fV$s\x82+h\x8cM\xd5\\\x1a\x1a\x88U\xd2\xcd\xca'\\\xed&\x86\xbb]\x7f\xe2\x14\xd0\xf4\xc5\x96E\xb2\xc3\xba\xcc\x15\xdd\xe2\x96\x93D-\xfd\x8c\xc7]\xfc\xb463,\xb0~\x0d\x8e\xbc\x03\x991D\xc3\x06\x97v\xe6\xebvL\x16\xb1\xd2hO\xd1qJP^!\x19\xd5\x19\xe3\x88Z\\\xf5\xae\xc8\xb4\xbf\xdc6xdA$q\xba+\xfesM\xe2)\xe6BW\xc75\xc1\xf0\xbev\x14p\x0c\x1ebY\xe1\xe1\x11\xb3\xc0\x14\xd8\xaet\x81mvp3dJ\xa7\xbf\x02\xb2\xb0\\\xc6\xdb\npV\x84iq[]:\xd5\xc4\x07\xb4\x81\xe8{\xd8\x13!n8U\xfeP&d\x0eu\xce\xf3;C\xdc\xf6\n\x86z\x15\xd7\x90T\xd9\x1fj\xa8W\xa4$;\x9e\x0c\xb7\xd9\x1dFU\xa4 \x95\x18C\xd8\xff\n\x00\xee\x11\xdf\xaf\x05^'>\xb5\xd9c\xfc\xafN\x14\x19''!\x11eN\xb7M]\xb6\x154S\xcd\xac\x95m\xfb\x070\xbe\x81\x06\x8d\xd9\xfe\xe9x\xbb\xda\xdc(\x03~\x890\x0e \xee\xfdkB\xa5\xaa\xe5k\x1c\x07\xaa\xd2h\x0c\xee90\x90\x8d\x97\x18\xa0\xe6p/\xd4\x0bBH\xe1\x04\x15h\xa8\x1c\x93'\x05\x95k\x9eW\xb8\x1f-\x01\xd8\xbf\x00\x1c\xcf7eI\xb2\xad\xa0\xe2\x08\x11!w\xe8\xb4u\xfc\x15\x1f\x04\x7f\xfa\x95tG\xfd\xfeG\xccu\x14\xf5\x89\xf4\x92\xbb\x95\xb6\x9b\x00\xe6\xd7\xb0\xfbU\xe8q\x17\xf4#\x00b\x83\x87:\x97\x99\xda\xc7W\x99\x05')o\x17\x1fn\x8aQ:\x80\x11\x1b[\xd8<|\xa5\x8d\xf8cr1b\xe0\x8e\x83F\xf07a+\xee~\xe0\xe7K\xf25t\x8f\x0d\xcb\x8a\xc9\xf1\xdb\xdc\xeaW\x80\xbf\x12\x14\xe3+\xcc\x86m\x82&\xfc \x9d\xd4\x90\xb8\xb4\xf54\xaa\xadf\xe1\xbe\x07z\x13\xa9\xe8D\xbe\xce\xd9\xc4\x83\x8f\x8c\x99\xc8\x98Y\xf44\xe8\xc6\xc3\x08\xfe\x04>;\xd1\xbf\xc6,gi\x9e\x8d\xa2X\x8e\x93\xfc\xcb\xe9\xdb7<@\x1feMsE6\xfd\x1a\xe7\xab\x88\x8d5b&\xb6\x89H\x97lb\x9f4-\x84 \xce-\x81W\x93\xcc\x97k.\xda\xac( a\xfbH\x14\xd09\xfe\xedW\xc6\x99sM\x19\xc0\xba\xb9\xcf\xb5\x19\xc9\xa0R\xcf\xc9\x11_D\x8ck:h\xf1\xec\x0e\xc2\x06\xed+\x97\xda\xa8\xdc1\xb8v\xb7\x88}i\x8a\xb0\xa6+}\xe9\xe4\xeb\xf6f\x87\x85\x88\x96\xed6\n5\xb6+\x9ekN_\x89\x00b\xf8\x1d\xfba\xfd\xce=\xca\x04\x1b\x8d\xaa\x8a\xf5\x13\x11\x0eI\xa0I\xa3\x9a\x0dB\xf5\x9e\x99\x07\xb3M\xbed\x131]0\xbbV@\x9a\x8c\x11C\xd5\xdfx\xd3\x16\xb6\x1f\xb2\x0c\x1e~\xef\x19Rl\xca8k\xea\xff \xf6\xf7\xb4\xd7\xe5\xd6\x98\xbc\xa2\xb0\xf5\xcb\\\x17O,\x9cT\x99r?P\x99\xf4\xc3\xf7\xfeF\xfepE\xa0$\xf1lE\xe6\x10\xc3*.\xe7\x90&\xeb\xa4\x86|A\xc7\xcbMT\xa0\xdcd\x95g\xa3V\x0eD\xa2DW\xb9>\x87.5\x93zK\x03\x97}&\x92\x08i\x9b\x19oy\x00\xe3\xac\x0f\xc0\x01\x00\x00\xd0_\xfe8M\xfd\xcd\x97\x8e\x0fi\xa0\x88\x97\x13\x82\x0cmfm\xe56p\xcdN\xd0-\xdb\x91\xb4/\xd8\xa9\xbc\xc3Q\x03\xcd:Xv\x04\xa5}\x89\xc4\xb9\x9aE\x1a]\x85o \xab'J\x8e\x0dtu-p\x1f\x1cla\xc7]\xa6\x95\xaa\xd9\x97\x0bPD\x11\x87\xc7P&_]\x89\x99\xf1\xfe\xa8o6\x8e\xd1\xa3\xd4\xe2\x0e\x06Qdh\xb2\x8a\x99 w\\\x08J\xbf\x0e\xd9\xaa\xfe\x98\\\xf8A\x10<\x85\x1d\x9fB\xc0\xaf0\xa9A\xcb\x8c\xff)\x87M\x00\xc4\xaf\xf8\xe5\x87\xf3`\xc6\xdft\x89\x12s\xcbi\n0;\xc5\x11\xe5\x16\x16I\x16\xa7\xe9X\x80\x8d\x071-; %\xd7\x85bL]Hc\xeaQ\x8dm;l\x10\xeer\x01\xb70\xde\x8c\xfa\xdc\xcd\x86\x15\x9ck\xde\xb2;p\xd2G0\xeb\xe7\x12Q\xac\xe2\xb0(\xed+Q\x8ck\xeeO-\x91A\x9d\x8cQEa'\xfe\x04\xfaY\xfeu\xe56p\xb1\xa4\x1d\xb9\xceRTj\x99K\x95cf\xd12!2%\xec\xee\x16\x97\xf8i\xd6\x1a\xd2,\xc0\xf1`\xbc\x1dxo\x90\x8d1&}\xef\xd5\xad\xeel:1J\x07%YT\x13X\x0b4\xd1\xd3sL\xa1<\x81\xe5p\xad&\x05\xd7\x04n,Ue\x04\x9c \\\x88\xaa\xfd\xa9\xb4O 5\x0c\xf9u;By\x93ay\\<\xf8\xc3\x87\x03\xf1\xe0\x87?=x\xfc\xdd\xb6\x9f>\xde:\xa5\xe4\xc1\xf6\x91\xef\xf7\xf7\xb6\xfdt\xff\xbb\xed\x13\x04\xec\x7fIF\xca\xd6+\xa9\x94\xf9\x8d\xe2\xed\xeb\x07\x93\x1b\x95\x98,2LT\x93\x8aY5\xe9\x07\x80\xb5jq\x80Q\x99\xecm\xebV\x9d\xe5Z\x8a\xa1$i\\'W\x04~z\xffc\x08\xd7I\xbd\xca75\xac\xe2\xab$[B\x0c\"\x13E\x84Y\xbe'\xf0\x07\x19\xf4\xf4\x0f\xf2\x1d\x7fZ\xe3S].Bh\xa0\xf8\xa9'\x97\xd6Z\xf5w\x9f2\x89ep\x82^b\x84\x9e \x9f\x0c \xcf\xf3M:\x87,\xaf%DJ\xb2 %\xc9f\x04.\xc8,\xa6X\x93/&\x80\xb3\x16\xb92\x11\xc3:c6\x0d$\x1e\xc4)\x1f!\xe9\x05h\xa3P\xfb\xde\xef=\xb7V7\xc6\xe9 \x9b\xbfwS\xa2\x89o\x8b\xda\x084\xe09\xd5\x98\x9eeA0\xc0\xb1 \xab\x80\x14\x99\x90\xe1U\xa6\x0c\xc2E\xc3 ,{\x8b>\xec\xbfr~\xce\x15\xabz\x1eA\x97\x91\xc6\xca\x10\xf3\x91\xa9C\xe1v\x81\xee\xb8W\xf9\xa4+\xce\xda\xfaKM\xf8\xed\xb6\xd0\x95\xbe\x03!B\xeaWY\x88\xcep\x0c\xbae\xae\x038\x86\x1a&\xd0_\x96:\x80 \xf8\xb4U8\x82W,G\xf8_N\xdf\xbe\xe9\xcf\xdb\xc8O\xf2\xcey\x1b\xb5>U`\x88\xef\xdd@\x90Zq}\xa6\xbd\x85f\x9a7.\x17\x7f\x0f\xfbR5V\xf7\xeb\n\xdc>\xed\xde\xd1\xe91\x1d\xcd\x18\x9b\xac\xe4e\x87\xca\xf6\x89J\x91'YMJNG\xe8\x9e\x87yN*\xacC>%U\x0dI\x06\xf3|\x86\xa1\xa9\xb5\xf9Th\x91\xadh\xce\x14\xcd(\xf9t\xbb\xc9\x16\xf5P\x9e\xe9\x11\xad\x95\xfe\xb21\xf9 \xea\x8c?\xdc\x14\x84\xeb\xfbN>\x15dV\xa3\xaa\x8f}\x14\xc2\x12\xadi\xe9\xbcU\x90\xd1\xc3\xd3\xdbd,\xaf\xcc\xdc\x03\x96|\xe0\xaau\xa3c\x9e\x92\xf7\x80Y(\x92\xe9\xde\x99\xbc!!Q\xb5\xb9\xa8\xea\x12s\xc1\x80\xe7\xc9~\xa6g0\xc1\x0cXHb\x1fx\x01\xd3\x86\xb9a\xdfb\x90~\xeb@\xc3\xd9\x82\x13\x89J\x9b\x8cT\xb3\xb8 >\x91\xc9\x9f\x1e\xfc\xd7\xfe\x83e\x88\xb9\x9d\x94g{\xf8\xec\xbf\xbazP\xd3\xd0\x8a\xc1\xa15\xfdkzg\x1d\xed\xa9\xbd\x7f|\xc0\x1e\xee\xbbv?\x1fdP~\xf6\xeb\xc6\xa4wG\xa3\x95\x11\x9b\x97D\xb3U\\>\xab\xfdZ\xda\x0b\xe9\xe9\n\xcb^\x86\xa6C\xf7u\x1e\xfe\xbc/\x8e_j\xdac\x8a!;\x98\xb9^ \x0e\xfb\xf1{\xfe\x03k\xd0_;t3;M~%\xf8\xcc\x10\xb4:1q\x0d\xf5\x01\xef\xc5K\xcdpsL\xf5\x95\xf3\xc0\x15\x1f\xf0\xda\xb9\x0cA\x1b2Sh\xd2\xec\xa7\x0e\xf4\x01\xc1)\xe01\xdd\x12\x13\x84\x00\xb22q\xe1\x17A\x93@Z\xdb\xda\xad\x9f\x19V#\x86#\xf0\xf1\xee\xc2\xfb\xbe*\xc8l\x1d\x17\xf7);\xf8'/\xa0\xd4\xed\xf7\xd8\x89\x9ep\xd6p\x84\xce\xfc\x1d\xdb\x81\xe9Y\x80i\xcf^\xe43\x0cZ\xea'\x98\xca\xd0\x86B\x1b8\x02\xcf3Q\xffq\x19\xadi[\x1b:|\x84Q\x81\xb7\xaa\xf9t\x83$\x86\xfe\xef\xda\x9c\xd2$n\x92\x18c\xb6\xcf\xfd\xd8h\xe8\xa1\xe3h\x86\xe7\x9eO\x13\xbc\"\xc2\xff\xb9\x93\n\xbf\x7f\x89\xbb\xfbW\xfdu\xe7 \xbd\xdaC\xa3Kr5\x94\x93k=\x94Xk9\x98\xb0K\xa6\x82\xd2~{1\x94X\xeb\x9c%\xba\xd5e\xb3\xbd\x16}jSH\x9d\x88>\xb5\xcd~\x1aL\xf2{:\x94\x13\xeb\xb9\x18\xae\x16J\x97B&\xef\xbfz\xc6\xd3\xea\xbf'\xcb\x93O\x85\xef\xfd\xdd\x9f\xc6\xf7\xffy\xb6;y\xf0\xe0\xf3\x83\x07\x81\x17\x82\x97x\x9a\xef\xder}\xf5\xf3\xe6\x8c\xf5(k\xf7\x9e,\xf0\xf0\xf6\xec2\xb4(x\x03&2M\xe2\xc7,_\x7f\x87\xebGk\x00\xe0\x17\x9c:\x04\xef\x0f\xf2\x1d#\x87\xbd\xe7\x1f\xf8\xa4\x07\x94?\xaf\x8d\x8a(f\xcd\xf1MI\x16\x06K\x0e\xa1\x91\xec\xce\xdf@\xdbE\xc1\x8b\x00\xbc\x86a\xa7\xd2^\x08\xda\x83I\x14\x94\xc8i\xad\xcb(\xa9^\x96\x84\xa47o\xe25\x99\x07~e\x0d\xeeN\xfb\xc2\xb4sJ\xf6#?\x93\x14\xd3~1\xaag\xe2\xda\xc20\x05\xd1\x04\xd6\x9b\xaa\x86\x0b\"Y8\xf0)\x9a\xdc\x7fO\x16\x81\x913U\x0bk\xc5\xe1\xfe\x98\x8f}\x02\x0e\xd9A\x16\x1b\xbc\xa3_\xd9,\xcamW\xa4\x14\x8e\x0b8B\xb1\xdc\xdek\x81\xa1\xb7\xf7\x1c\"E`\xd8\xee)\xf3\x9b\xb5en\xa3\xe5\xca\xf1\xbe\xca\xed\x02\x85\xb6\x96\xd2\xae\x0b8\x86\xdc/BH\xa9 gL.+\xca\xb8\xdb\x01\x8e, =-\xec\xb5A\x15X\xe6v\x88\xc0\x18\xd4\x01\x8e>\x0c%\xae\xdc>p\xc5!\xd0\x1f\xc8\xad\xd7V$[6\x91\xc7\xac\x9d\xdd8\"\x03\x12\x90\x95?\x0f\xe1*\x84\n\xcd\xbb\x1c\x16\x029\xa1M\x9aR\xb6\xeb\n\x8e\xc1\xbfA\x91y.\xfc\x07\x19\x9f\xe8/\x05u\xf1o\x02\xc62/9\xd1\x1dV\x93q\x99\xf6_\x06%\\)\n\x8c\xc6\x88\x80\xee\xa9%OhD\xe9(Bh\xe3_\x850\x0f\x82\x88+\xad\xe0\x18\x96\xf2\xef ,\xbb&]N[\x0ddl\xa3\x11\xbb\x0d\xb6\x00/\x8c\x051l\x01f\x18 j\xb0o@\xe0j\xa4\xa5\xc6\xc5\x98\xd3\xa9\xe9\xa9\xa2\xdeZ\xe7W\x84\n3\xb0t\xc8\xfaE\xf7\xefEK\x1b$\xa4\xe4\n\xd3\xdf\xb8-\xc77\x1c\xae\xd6\xca\xb63\x0b\x84\xc6\x89\xee\xca+\x14R\xd3f\x96\x17\xa12N\x91\x1b\xd0\x9acT\x14\xb9\x94W\xd6\xea\xb7\x81\x03\xe8\xdc\xce+\x10\xc4l\x9c\xc5\xb6Z\x84\xfa@\xab\x005\x15iST\xc4\xf5**\xc9|3#\xfe\xd6C\x00\xf52\x96ytNk\xbc:\x9d\xd6nA\xa2h\xc1\x8c\xfd\xee\xfb\x08F$\xa55\x15>hU7\xcc\x9d\xe4\xb9\xb2$S\xb5'\x7f:\x82=\xd4U\xec\x85\xcdmn\xe0\xd7AG\x1cv\xf2\xa4\xd3\x15q\xb1\xe3\xd7\xd3\xcc\xe1\xb2\xbf[\x86\xe2\xf2\xe8\xca\xad_\x8f1\xb7\xb9\xf5K\xe1\xa5q\xd1\x88\xe4\x17\xd6o\xed7\x12\xdd\"p\xc9\xc6\xb5\x81\x95\x011\xbf5\\\xf8\xf7\x9ejd\xb0W\\\x80T$\xbc\xd7&23\xcfg\xcf\xe3\xd9\x8aL\xe0\x9d\x1e\xb5\xe3\x8b*O75I\x167\x13\xc8\xf5uf)\x89K\xde\x8c\x9b\xd2\x85\xf33;\\\xf1;')\xa9 \xbb\x8a\x98t\xf1\xf7\xdd6\x91-\x94\x16\xcd 6\xa8x\xf4\x93TE\xf0 \xbc\xd5W\xba.\xe3\x82\xd7H\xf45\x96\xa4F2n0\xbfG\xdd\xf7\x04b\xfd[\xf2\xa9.\xe3Y\xfd\xb2\xcc\xd7\xd8\xc8F_M\xde\x06\xb9.\x87r\x19x\xce\xee\x920\x81\xec0\x88W$\x9e\xa3\xa1\x87}\xd3<\x9b\xcdHQO\xc0\x8b\x8b\"Mfh\x8f\xf3\xe0\xe7*\xcfBP\x9f\xdc\xc4\xeb\xd4\x1b\xde/\xc3\xf47\xcd\xe3\xf9)\xdaF\xef\x98\xe3\xaf\xdd:\xdf\x0c\x8a\"\xe8^\x84G\xf6\x80\x91\xce\xb6-_K\x02_\xc5\x0b\xf2c\x1e\xcf\x07=\xb4F\xe1-\xc7\x19#\x0fH\x97\xe1\x1dcF?\xe4\xe8\xa42\x81\x99\xbe\xaa\xb8\x1f\xf9\x8b\xfa\xc9%\xc9&\xb0\xe8\xd3\xa5\xa0k\xb9\xc3\xa7\x08G\xf0\xaa\xaf\x8a\xfc\xd9\xaa4\x17*V\xa2^\x0f\x10\xf5z\xa0cp\xd0\xeeD5J\xa9{\xe6FcMZ\x1enm\x0ds\xf0\xed\xf6\x9f>\xfa\x02C\x1a\xf5\xcd\xaf\xa0Z.\xad\xeb \xdb\x1a\xec\xc0\xb0\xd1\x0e\xe8\x8fI\x93\xc29\x17\n\\3\xba\xf6\x87\xc1\x14\x95h\x12\xa7Q!\x99\xb5\x94 ^1\xe8\xa7\x85lv\x1c\xadI\x1dS\xa4\xe6\x7f\xb24\\6\xe5\xe6f\x1b\xe5f\xdeUnn\xacZ\nf\xd0\xd4Isk\xfb\x08T\x0dl\xfb\x16\x1a!\xd8\xe813\x88i\x9b&\xc3$\xb5\x08;\x8fH\x88\xabL\xb1m\x89\x003\xf8Vhn],\xdag\x98\xee\x04\xb7\xc3\xf0X7[\xf0.\x80\x1d`B,8\x82Y\xcf\xfe\xa2[\xa8x\xcd\xf8\x1d\xfc\xc0\xdfca\xd89\xfb\xf4\xcbm\x08\xb3 \x88\x10\xd6n:\xd7i\"\xe5\xe8M\x08\xbf\xdc\x062c6\xe9\xf8\xa78\nb\x887I;\xc4\x97\xfd+\xe0_624\xe5\xb8\xed\xb8A\x0b.\xa4\xa3\x8b\x81\xa0W]\x13\x89\x94`\xfeqH2h#*\x8b\xbdT\xb9\xe0)(\xe6\x1d\x1d\\\xb5\x9bU;\x9b\x18'\xd1\x9a\x94K\xf2\x82\x90\x82\xae\x98E`\xba\xb5\xc5n\xe2\xad.\x98\xac\xdci|\x16\x04!\xcc\x18]\xa2\x84J\xd6\xe2\xba\x9b\xa9D\x96M\x08\x1eV\xf3\x02\xfaM\x9fG\x10\xc5Y\xd6i=\xc1XTc\x0eu\xeb\x19\xd9z%e\xf7\xdf\xc8\xd8T\xfd\xf5+\x1c\xd8\xf9\xd0\xadl\xd2\\\x90\x8e?&\x1b\x9b\xf0Qgei9+{\xd9\xd6q\x1d\xec^\x82\xe2\xbc\xec8\xa6O\xcf\xec\xea\x9d\xfe\x1d\xa2E\x1c\xe9wC\xa9q\xd2\xb1]+\xa3\xaa \xb3\x10\xaa\xa1})e\x90\xfey\xe2@\x84\xdd\xb4}\x9bi}\xa6,h\x19\xc9\xa5{\x1d\xcf\xca\xdcO\xed\xa4e\x94.E\xe0]\xe3\x87j\x0bR\x03\x0d$\xf2\x0e9\x1dv\xec\x18P\xb4\x04\xea\x8a\x88s/\x0bac\x10\xb3\xb4O%!\xd64d5\\\xfdoJ\xf6oB\xc9\x9a\xa4\xcd\xa3(\x99i/\xd0\xd1\xc6z\x1aa\xda\x08\xd2\xb1qC\xd9\x122d\x06NK<\xdd\xb4w\xf4:\x9f\x93T\xc0\x9d\xedjZ\xc7\x80\xeaN\xbbY\xe5\xed\xed\xbbx\x14\xe3>~\xaf\xc5\xff\x8f\xef5\xfd`\xcc.*\xd2T@\xdf\xf3l\x95\xa4\xf3\x92d\x13]\x8cq\x16e\xb0v3BM\x86l\x95\xe4\xe1&b\"\xca`\x0b$*\xca\xbc\xce\xff\xca\x9fgp\x8c\xbbe\xd3\xde-\x99R\xab\x89P\x8a\xc6\xc4W\xec\x99\xbf\xa7\x04\x8c\x08|\x12\x89\x99i\x94\xcb\xc6\xd3T\xb5\x84e_Ok\xc3\xa5V\xab\n\x1cAB\x913\x13\xa3\xd1\xba\x19t=\xf9~u\xc2\x19\x0fY\xfcm\xf8\xcbC\xdd\xcbJ\x98\xd7i-\xe8RA\x90\xb5\x0d\xcfTM\x91 \xf2\xae\x17i\x9d\xb4\xf6\xcc\xb0M\x86o-\xf3\x9cR\xc1\xdc7\x9a\xba\x81\x8d\xe8t\x1c\xc9I\x08S\xf3hd\\\xac\x11\x81\x89\\\xb8\xb9\xabnP\xf5\xb8$\x19\xc6\xc2\xda\xb1\xa5\x1bB\x1b\x13[\xfb\xa0\x08\xc5dJ\xd4t\x03v\xd5\x08p\xa3\xe3L\xee\x00;K\x17O\xcb38\x86\xc4\xa7\x7f\x0821a\x8fq\xbd\xe8\x83\xc1V\xb8\xe7u\xe2\xcb\x85f\xcdl\xd2t@\x91\xae_\x7f{\xc0\xa9;\x8e;G\x17\xc5\x97\xb1;\xa7g\x81\xd6\x19FL\xccE\xed$\xd9\x04\x19\x15\x92\x81$S\xd3,*\x7fS\x9ei\xef)\xe4\xf0}c\x87~\xef\x1e\xf8\x0c\x03\xf2\xb3\x10|D\xb8\x86lN\xcb\xb3\xe0)\xe4\xbb\xbb\x01\x0b\x911--\xd7\xfbb\x1a\x18\xe0E\xa1\xd7_eu\xd8\x8e\x18\xb3F\x0e\xdb\xaeu\x03A\x945\x82cfi4Q\x9f\x1e\x888\xc9Hu\xd0\xafE\x11\x1cu6\x0dN\xfb\x12Ui\x8dA\xa8\x05\x0f@\xdd\xc9#6\xa4\x98j9\xcd\xd0\xa8\x9eE\x8e-Y\xfe\x85\x1c\xad\xd4\xd0\xe8?\x04\xfalxg*\xc4w\xf4V4\xfa\xb7\x9b\x99\xf7\xd9X\x06o\xf8\xd6\xe5p\xc0\xf1\xf9\xdf\x8b5T\x7f\xfd\n\xdc\x84\x10\xc3\x1e\x0e\x89aZnB\xf0!\xfbZ\x8b{\xc1\x88\xeck\xe5;\xc9\x89<2q\"\x99\xff\xed\x00\xf6\x0cr\"W<\x03Y\x87\x99\x94\xa2\x1bKs\xab\xf2*\x03\x9b\x1a\xb7%f\x0b\x9e\x85\xb0\x08\xa1\x08a\x1e\xc2\nMF\xd7h\xbdv\x03G\x10\x97Kt5T2m\x1d\xa0uYc@!\xabL\x0f\xe8!\xda\xfaI\xf9v\xfdn\x97Z\x141\xf6\xeb\xd29\xf2\x14\x9e.O\x9f\x06P]'L>\x14\xd9, \x86\xce\xb1\xd11LW\xe8\x90\xd5S(\xce\xe1\x08nx\\\x99\x93\xacNJ\xf2\xa1$\x84\xa5\x18\xbe\x11\x86\xf5,\xb50\xad\xf6\x8f\x0d\xa9\xeaWYM\xca\x19)\xea\xbcd\xc9\x86\xe9\x9b\xaa\xc8\xb3\x8a\xb4^\x15\xf8\xaa\xad\xe7b\xd9Jo4\xb22\xcbGl'\xd2\x80\xa10\xea\xd5\x8b\xa4\x9a\x95\xc9:\xc9X~\xbe\xcc\x8d{\x92\xa6~\x06+\x90n\xe9O\xd9x\x83\xdf-\x1a\x98L`\xe1\xf6m\x1bh\x13(\xdc>\xebCu\x02s\xeb\x97\xb7!\xda\xce3\xf6[\xa6\xbe9\xbd\x8e\x97KR\x06\x0e!\xf3\xa0 {h\xadKe\xb15\x86\xf2d\x8aY\"\xb2\xac~\x1bv%\x8cN\xea\x0d*\x8c\xael\x863\xa2\xb0\xe1\xac\xdd\xc0\xd6\xcf\x80\xe1\x1a\xad\xab\xbaL\n\x11\x85\x14\xedl\x06\xadcD\xb1^\x12\xe1&\xfe\xd6y\x13/\x99\xe3/\xc9\xea\x10vJJ\xc2\xda\n|\xe6\xdb\x99\xa9\xcc\xe7\x12\xc1\xcfW]\x91\xf8\x97|Y2\xf4\xd6C\x16\x9f\xaeQ|Qn\x8a\xda\xf7X\x87^\x08K\x97\x19X2\xad\x8e\xc9\xac*\xb5\x18\x96L\xaaF\xc6\x960VI\xebb\xd8\x9f\x8a\xb8\xa5\x93j\x8b\x81\xc3F\x0e\x0d\x93\xb0p\xb9X\x9e\x14V\x9d\x99\x1f\x8ce\xaa\xfe\xbdX#\xfd`\xf2A&@s2\xef\x19O\xe6\xbd\xf6\xc9\xbcg:\x99{kjSE1\x0b\xe97\xf1z\xc0+\x809d\xaf1\n\xbb\xb9\x16\xc6\xe2\x8d(Yf\xe1\xb2\x0c\xb9\x9a\x9dG\x08|\x94\x89\x1eV\xfbFX\xed\xb7a\xb5?\xc4\xc5\x80\x8a\xdb\xe4\x13\x99mj\x16rZa\xcf\x86\x891#\xc2\x04I\x8ay\xc7\x86]\x1aDB\xf0\xfa\xe7\xae\x87O{G*}\xbc\xa9H\xf9\x92\xd4\xb3\x95g\x8d\xc1&V\xd4\xca0\xb0%\x9d@9\\M\x0d\xcaeI)\xac,\xffP\xa8\xb4\xdb\x10\x12\x831\xb7\xf5\xd6\xde\xac\x1f6\xed\xb6\x9a\x1d\x1d\x94\xe6k\xbb\xe4*\xd9\x0b\xfd\xdbF\xcd\xc1\x03\n\x1c\x03\x95\xd4\x0d\xa0\xcd\xb1-\xbe\xcc\x1f\xe2\xa5\xbeV\xd2n3\x87c\xf0\xf87\x1e\x18\xcd\xa4c\x96\xec\xe7\xe0m\x03\xe4\xe7\xf9\xba\x88\xeb\xe4\"I\x93\xfa\xe6u>7\xec\xe2\x8d\xc1\xdb\x96\x96\x05\xbe3\x92\x12\xc6\xaf\x90x\xb6\x92\xdd\x06\xf4\xa8\xb0s\xfa\x8d\xb6\xdbNb\x18\xd8l$&\xc5Z\x12\xc7\xf4[\xdaO\xa3:^Vp\x0c3\xfeg\x00\x13\x98&gc\xcd\xc0[\xce\xb4G\xaa3\xad]\xbb\x8a1\x1cX`\x1c\xfc\x8f\xddF\x0c~\x06\\\x97\xcd\x00\x9e\x17\xaf\xe6\x81\x9f\xe2\xfd_n\xdb\xf0\xa2\x0c\xa3\xc6\x04bk+:W\xedn)PDv\x1b\x11\xe7\x98\xed\x8d\xc2\x18\xba%\x8a\xa0_\x86\xfd\xd2-\x12q\x9c\xfd\xd9Z\xe4\xccL\xdeE\xb1\xf9wQ\x8c\xdaLgg\x01\xd0\x7fwwCH\xa6\x9e\x07\xbb0\x83]|D\xf1\xa5\x18n\x83\xa9\xa9\x9b\xb0D\xf4\xecK\xb0M\xfb\x8aP\xcc\xa4\xa2)\xed\x8a\xa2\xa4C\x04a\xacz\x04s\x16\x8a|\xfcp\x81wK\xe5^:L{m\xeeyA+\xb7:\x9c\xd3\xde\xcc\x89\x9bAQ\xe2\xb31\x17\xc6\xba\x06\x06Z\x7f\xa9\xd66;\xfb\xcaj\xb0\x10\xea\xa8\"\xe9\xc2\xe0'\xac\xde\xb2\x1d\xf6-\x10\xd6\xf1%9aL\x0c\x1cQ\xb2\xc1\x1e=+\x92\xeaC\xbc\x94\xb4\xa1\x92\x7f5\x95\x9d\xf4Vw\xc0\xb2\xea\xf7\x1dj\xce\xd4\xe1\x1b\x9d\xf63^\xb3hMh\x80\x1a\xd9h\xe2v\x07*t8?s\xad\xd9\x85Ic`\xa2\xb5\xa5\xe1@\x96w29$\x99\xe9>KVJh\xa5r\x9a\x9f\x0d*\x9c$\x81\xab\xb47\xf4\xc0x\xb5l\x9a\x9f\x05\xd8Xs\xf8V,,\x8d\xb9i\xceMO\xf0\xebi\xa2W\xf2\x9b\xf9\x0e}\xc3q\x91T\xba`\x81=\x1b\x0d=\xe6\xffK\"\xfaV \xf8\x8f\xd9\x03nK\xd9\x9e*=K\xfa\x84Q(\xf6\xbf\xd5\x9a T\\u\xdf\x7f\x93\xda\xb0\x02\x9a%\xd1\xbalj\xd6z6\xc6}\xa5g\x89\xca\xb4\x12:\xd7CMW\x0b\x16.\x8d\x1d\x1a\xfa~\xba\xf03:\x17*\x88\xa9\x13\xdf\x9a\xa5\x19w\x07\xf6\xe4` \xce\xf1\x7f\x86\xa6\xe7\x0b\x85O\x85\xd14\x1f\n>\x89*2\xdb\x94I\x9d\x90*\x04\"\xee*0JPV\x7f\xb8)\x08{\xca\x14\x08\xcac\xc3I\xc3\xa4\xaej\xb6\"&\xd9\x8c\x89\x9c\x9a;\x11m\xed\x8a\xd7\xee\xdf\x93h\xab\xcf\x98\xdc\xcd\"\x19\xfcT\x1ax\xf2\x05\xd6\x92\xea\x0f}\xa5\x82\x81\x87\x0f\xf4\x87|~\x13\xa2\xb6\xb8\xbc\"\xa5a\xf2s\xaeP\xa6U\xfe\x1a\x97I|\x91\x12\x83S\xed\n\xab\xae\xea\xdapE\xb1\xe4R\xaeP\x93\xe8k\xdd\xb4k\xfd\xb0I\xd2\xb9\xb1\xb2\x08\xe2\xf5)J\xaa\xb7\xcfN\x0f\x03\xbf\xd6\x1c\x147\xe8\xaeO\x1b~\x0b\xc7p.\xef!\x95\x88\xe8\x86 \x83\xef\x8c\xc4bS\xa6\x13cd\xa3YI\xe6$\xab\x938\xad&\x80Z\xf6Ut\x9d\xd4\xab\xe7\xcds8\x06/\xc9f\xe9fN0\x0ca\x15\xaf\xc9}\x16C\xcc\xd0h\xe3\x08l85gy~\x89q\xdeuF\x84\xfd\xf9\xc5\xa8\xfd\x7f\xa7A[z\xb4\x07!T\xb2B\x0fS\xe1\x08*\xca\xf4\xf3\x1a\x12\xed(=7\x80\xf2\x83\\\xaa%\xa9%\x91}\x1f_\x07CQew>\xa8\x91U\x9f\xfb^\xc3\xa4P\x89'\xc3\xd0\xb1Y^\xc3\"\xdfds\x9d\xab\x10\xed\xfb5F\x9e\x94\xd4C\x0f\xbeWmm\xd3k8\x86_na\x02\xaf\xf5\xd5\x7f\xc66\x87t1o\xb0\x86\x10\xd7\xf5\xf3{\x17m\xca\x14v\x8f\x8c\xa6\xa1\x83\xaa\x01F\x93\xcc\x01\x03$\xcd0\xdeT\xb2\x8dm\xbcU\xec\xec{c\x18\x9dF'\xf1\xc6pdr\x1d\xc4\xcf}\xcc\x0cB\xd8\xc9\xa4\xa5\x8d\x88(\x10ql\x0e\xe1]\x1fr\x12joBx\xc7\xd7\x80\xa2\x17J\xc1?\x07Q\x9d\xffT\x14\xa4|\x1eW\xc4\xc7\xa08G\xb0d\xca%=~\xbc\x97*\xfej\xfa\xe6\xccT\xb3\xe4\xd8\xce7b\x14\xa3\xbb=e\xa7\x0ch\xf7\x02\x8e\xe0\x99\xe2\xa9u\xea\xbfR\xc8_\x104\xcf\xdf\xb7\x9ek\x9a{1B+'4\x8a7S\x12%\xd9\x80-ai\x89\xb3\x85\xaa\xbd\x8b|~\xe3\xc9\x18\xb2\x8ca@\xbc\x8b\xd5\xbf\xa3\xc6h_Z\xb4-;\x11\xb5\xd0:\x8a}\x94\xc5k\xfck9e\x7f\x9fQn\xce\xf0>\xc1M\x1e\xb10\xadX\x19&p\xe9\xb3\xbfCx\x11tn;D\xc2\x96\xeb\xb8\xcc|\xef\x9d\x80+\x8f\xd4\xcf\x9a\xc6p\xfdI\x05\xf1\xfa\"Yn\xf2M%\x83\xdb\xd7+\x02<\n3\xee=X\xc5\x15\xac\xf3\x92\xbe\x893\xc83\xd2(\xfa1;\x00~\x91!\xee\xf7z\x88\xb39\xbe.\xe2\xaa\"\xf3\xfbI\xa6|\x8b\xba\x8d\n\xe6 \x8b#\xc6\xfa\x848\x83?$\xd9\x1f\xd8\xdb\xc8\x0bB\x11\\\xebh8\xf6bG\xd5%u\xeb\x8a8\x86\x91\xb9\x1bsCy\xf2\x85\xbd\n\x8cCHJ2\xa7\xbfvH\x84\xb7\xe2'\xeb\xa2\xbe\xf9+3\xf9nH2\xf7\xe2|/>h&\xd8\x06\x06\x856\x9dgQ\xe6W\xc9\x9chI\xb5:\x99\xb7]L\xf3\x98;\xa8@E\x8ev\xf5M\x81\x88\xa2\xd1@\x976\xaf\x0d\xe0[@I\xa3:\x90.\xdf\xcdK\x03d\xa02\x058M\xb48\xec\x85;\xb6vqA\x84\x97\x8c+\x1c\x91!\x041\x18\x15s\x80l\xf2\xbd{\x90Y\xb4\xce%\xf9\x871\x0e\x8d(rl\xd6@h\"3\xc1p-E\xa9\xfcj\xb8\xa6\xcdz\xc4\xd9\x9c\\\xa7f\xa6\xa4\xf1\xc7\xbe\xa9\xc3/\xcc*@\x0f6u\xe8N\x9d\xa0\x9d\xf1;\xcem\xd2\x9e\xae\x9b\x9e~\x0c\xe1]\xc0\x83\xef\x9ct\x1e\x07\xe2\xcc\xc3M\xda\xb6\x80\x97\xe7a`\xf1\xbd\xa43\xfc\xa9\x9f\x8aM\xf9~l\x98/q\x9c\xc8&\x8c\xde\x18\xa0J\x96\xbb\xe0cP\xfb{\xc8\xdeb\x18\xec&goE\xca\x04M\x8b\x06l\xceoC\xfa\x99\xbe\xa7\xe6\x10~\x8ec\x82#\xf8\xa9\xbf6\xfd\x13\x9c\x0d\xee\x9d\n\xe8>\xc3\xc1\x02#\xa17\xf6\xab\xec\x7foHy\xf3\xb6|\x99\x97\xeb\xc0\x7f\x17\x84\xf0\xeew\xed>Z?m\xf7\xac\xcama#\xb20\xb9\x97\x9e\x80ng\xbbMV\x06)/\xdbo\x14K\xa7\x1b\xc5\\\x11\x02\xcd\xb5\x12'A\x15\xa4\xbc\xec$TB+\x99!\x12\xffXp\xe6\x03\x86{\x15\xdf\x02J\x92\xb6:\x84\xa9\x87<\x9e\x87\xf7\x85~\xc9\x82\xd3Rv\xf1\xc7\xfc\xbaa\x17=6\xb0\xca;\x0bD\x9c\xb7\x81f\x1cj75\xcc\x03N1n\xbb\xf9\xfd\x8c\xc7\xd94sj9\xc5fDi\x97,\xae\x14\x91\n*\xc6\x8dL\x85*\xcd@6\xa59*\xdb\xd0\x0d_!c\xe9\xe5\x01\xfc \xee#\xcf\xe6\xa7\xec&\x86\xce\xb2\x9a\xaaUL>\x93;io\xba\xb2\xa1j\xbawF\xc7'\xda\xdb;\x0b(1\x14\x8dz\xbfxM\xcfn3o9zL\xcf\x98\x87\xc7\x83_\xfc\xe9\xdfo\xcfv\x83\xdb\x07K\xd5\xcf\xe3)\x0bs\x81\x862> \x9e\x06T\xb6\xd8T+\xbf\x9c\xee\x9f\xd9}6\x0d*`?\xdd\xe6f~\x16]\x89\xfd\x85\xbcq\xf3sJ\xac\x97\xa1b\xc2\xed\xaf\x86\x8fo\xe0\xc4g\xc3\xef\xf3\xa5\x0d\x9b\xfd\xb3\xb2\x13\xc9\xfd\x17\x99\x1c\xe6\xd6\x0b\xc1[\xda\x02\x81\xd0\xa5O\xa5\x97j9\xe8\xccd\xba\xdb\xd4\xf7\xd0\xb5\xc6\xb2m\xac;\xb9\x1c\xb1\x85\xcd\xae\xef\xc2\xe2\xcb\xd6 ]\xca\x95<\xb6\x19\x93l\x8b\xdfPj\xbe\xa9-\xdf\xd0\x13\xe6\x9d\xcf\x1dLgy\x8a\xb4\xf4\x9d_\xb6\x1f\xd8F\x9b\xe0\xbe[\xe5\x15z\x1e\x96\xf8\xd7\xf0\x17\xcc\x85\x8e\x92s\x14T\x1c\xfap\xc9\xac\xcb\xf1E\x84O\xf3\xe97H\x9e\x138\x86\x9cb\xf4\xe4\x01\xe6\xd4\xf0\x13\xd8\x85\x18\x9d\xf0\x82\xe9F\xf5\x00\x84c\xd8\xb4\\\x99`b\xc8\xbaz\xeb\xa7!hr\xb2\xdf\xfa\xe8\x9bk\xa7\x15\xe3x\x8a!=8H\x8e\xc2\x85\x0b\xc8\xdb\xc7z)R\xb2XX\x8c.j\xe5\x03\xa8E\x97\xb7}oT\xf3 T\x98\xf4K\xfc`;\x0e\xfd\xad\x8cma\xf4/\x8a!1\xc3\xcd\xa4\x83\x9b\xab\xba.\x06p\x87\x19\xf4\n\xdcL\xe4_C\xf8\x96\xe27\"\xb0\xbb\xad\xf6\xcc\x82\x99]\xac\x9caz\x17>\xc9\xae\x99+\x96\xf6\x89\xf0\x1b\x17&\xc6\xf2\xbfy\xf80E\xdd\xc4n\x98e\x8di&i\xa2\xe6nU\x03\x82\x7flH\xf9\x95V\xc86{ &\xb3\x8e\xbd\x8ep|\x08\x03\xf6\x17\x87\xc0\xce>w{\xbbw\x0f\xbc\x8b'?\xbd\x7f\xf5<_\x17yF\xb2\xda\xcf4\xbe\xa7:\xcb\xea\xbc\\\xbf\x88\xeb\xf8_\x12\x00~\xc64\xc1=\x0b\x16F\xa5\xe8\xd8\x11<\xf8\x87D\x13\xfa\xcbiC\x89-a\x1ee\xa7\xe3I\x7f,\xe6o]\xb6\xab\x1ei\x1d\xfc\x05\xfe\x93\x03\x0d\xa8\xbf\xee\x9c\xc5\xe8\xcb\xf9\xf9\x90\x12P\xc4`\xd2\x8a\xc8B-\xf9\xed\xe3q\x81r\xff\x05\x08\x8e\xb9bC\xa9\xcdu\x10*QU\xdf\xa4\x03\x95P/K\xd14\x1d\xf6\xae\xe9\xabr\x86%\x18\x8c_g\x1b!8moZp\x16\x13HP?_%\xeb\x82\"\xd4\xe0\x17|J\x13\xd8\xd0ol\x990X6\xa0 \xec\xec\x1b\xab\x99$\xcb!\xfa\x9f\x0b\xd2\xaf\x0bL\xf2\x1f\xc9\x98\x99\x19\xb06K5\xcc\x88l\xfa\x91\x0e\xbcM\xc6mF=n\xdb\xa5\x04+\xd2\x99\xb6\x8b\xe2\xcd )\xde*\x86\x8d|Op\xc3\xb1\\me\xa4\xb4\x0f\nq\xca\xacY!\xdb\\$\xc5\x8c\xa9\xbc}?\xf3\x86\x0fAQ\xf8n\x19\xb5\x15E\xc1-\xe9\x98r\x95\xf7\xe3\xe8\xce\xcew\xa7\ni\xb7\x0f\xc5\xb6\xe3\x07\xf6{\x82f\xb4\xf0\xd0IP\xcd\xc6\x1dJ\xee;e\xf4\xa1\xd0\xdf\x1e\xad'\xb7}U\x0b]\xdf\xa9\xc7S(K\xe6\x8c\x12\x9e\x9a\xbf\xec\x9ad\x11\x14\xbb\xa6g\xae\xdd\x81\xeat!\xc1\xb0\xff\xa8\xe3\xe5\xac\xdf`[t\xe2\xfd\x0f\x14\xfcM\xed\xfd\x9c'\x99\xefi\x9c\x13\x95w\xd0E\xd8_]#\x9b\x0cid\xe3F#\xdb\xd5\xb9\xb2[\x90\x17I\x85\\!\x99S\xfc\x88g5;\x01\xf3P\x1f\xc3\xdeb\xb8i8_\xb5VF\xf5X/\xb0Krcc\x04\x9cTl\x16M,3\xfd\xb42D\xcc\xafk\x88\x1e\x00W\xeb\xda\xe7(\n\x87\x13\xe6\xd6\xb2Ku\xe2(\x1c\x8e\xe1h8\x8f\xa0\x7f\xe6\x88\xc2\xa2\\2\xa6\x92\xb15M\xb6\xdc\xf1{lc\xca;/7Qhrv\xc1\x81\xa4\xf1\x05I\xbb\xe3`.\xf2_e4\xd1\xe0h\xd6q]&\x9f\xbe2X\xc6&r\xe1M\xb2,2 \x1c\xd3\x83\x84\xb9\xfbQ\x06\xef)\x05U\xcdX=\x0c#2a\xaa\xce\x10\x7f\xe9\xc70\xe0\x8e\x8a``\x8a\xb4#\x9b\xa7\xbe\x90`\x13\xee\x1c\xdb\x8ccB\xfb73\x9e[\xc0\x15\x1c`\x0b\xcaBkn\x02\xc0(\xed\xb3-Q\xc43\xf2\x82\xa4\xc9:\xa9)\x93\xee4\xfd\x94O_\x99\xf8o;o\x0f\x83\x15\x18RX\x0d\xcc\xbeH\x8a\xd1\x93\x9f\xfd\xcbM\xfe3\xc6\x0eu\x9dh\xde\x0d H\xeb\xa1AE\xc7\x1d\x92\xbe}\xc2\x1c\x92\x1e\xe9\x1d\x92\x985\xf9#]~\xff\xd4i%\x05\xec&\x0f\x8e\x7f?=\xfb\xffv\xbe\xb9\xf7\x07?\xf8\xe3n\xf8\xf4\xc8\x93\xf7\x19\xdcp\xb6?\x15\x8d&~L\xa7\x0f\xfe>\x8d\xef\xffs\xef\xfe\x93\x8f\xf7\xa3\xf3\xff:\xdb\xfd\xe6A\x12\xd5\xa4\xaau,\xd7\xb6~\x01O\x0e\xf7\xb7\xb7\xd1?\xd8\xfe\xd3\xc3/0\xefo\xbd\xfa\xb7\xd4\x8a\xca\x00\xa9f\x95\xa6\xdd5\xb5\xec[ a\xcc\x9a\xc1\x84(\x96\x08\x95\x9a|(\xd8\xe6`\"\x14\xb3\xdb\xef\xa2\xef=\x8bw\xa3\x86\xcbbtR\x8c\x84\xc2\x9d\x18\xdc{\xe7\xed1\x16b\x8c\x06\xdfeLx \x80\x89F[q\xeb\xd7\xd4\x10n\xe4\n\xb3-\xdc\xbb\x07;;\x1d\xfd\xea\\D\xc8\xd2\x7f\xb8\xee\xc7\xc6\x8aC\x98z3a\xf6\xac:\xfd\xde\x9c\xb2\xf0\x00<\xb6\xcfP*)\xe5\xa6l\xd1\xbd\\]H\xe3\xb4E\xdb8\xad3\xf42P\x14\xd8W\xf4\x1f\x16\xd3\xa6s}\xd5\xc0\x0bG\xd5\xfc\x94a\x7f\x8e\xc1_il4\x06X\x13\x19\xe0&\x83$\x1bN\xde\"8\x98\xf9t(\xb6$p\xa4^O\xb3\x01{\x0f\xb4\x07\xb0\x9d\xd3R\xa1\xcb\xf3\xd6\x7f\xfel\xbb\x10\x03\x8e\xfd9zN\x0c\x9b\x9b\xb0!X\x9bCy?.\x92\xffEx4\xcc8\x00\x0f\x17\x93\xdf3\xf2\xe0\x98\xfeB8\x19\xc8\xeb\xf0$\x08\xc1c(\xd1\xab+.\xcf;\xb5\xd9\x9dp\xaf\xb6\x08\xc0\xa6\xd6\x1e\x9e\x1d\xa8>\x18\xcc/^\x8c\xde\xce\xf2\x80\x8c\x01\x1aW\xc9L\x8c\x86\x85\xccp\xfd\x1e\x14\xae \xc1@\xc1\xf6[\xcfnAuYT\xc4Uu\x9d\x97\x03a\xcatE\xc8\xb3\x8a\x7f,\x0buA\xd9\xa3\xca\x01z\xa2\xc8\xb5\x8a\x9e\xa9w\x8ep\x04\xde\x0f\x14\xfcN\xf1\xbf\xbc\xe5\x81*-R\xae>R\xa1\xe0r\xf9\xb9\x87a\xdf\xe9\x06\x8eVq\xf5\xf6:\x13'`{x\xb9-_\xb2d\xb3 \xcf)Bi\xfa\xdeS\xa8\xe1{8\xf8\xf6\xd1S\xd8\xdd\xad\x03 ,\xda&\xf3\xca\xa1t\xff{\xd8\x7fD\xb9\xb1=\xc5\xf2\xb1\xe5\x17\xd4q\x0c2\xab\xef:>:\xbeR\xb3\x8ebJ:?\xe4l\xca\xb6\xb3V\x91\x18\x8e\x00s\xce\xd5Q\x91\xc6I\xc6>\xa7\x9c\x1a\x87\xdd\xac$qM\xfcl\x93b|y\xca\x0b\x96l\xda%|/\x1d\xb8\xe8\xdc\xcb@UV\x91iy\x86\xf8\x98\xd1?\xd8\xef\xee\x92sS\xe9f\xcd1)6)\x97\xa43\xfe,\xec;\x92\xa2\xba\xb6IC\xd9\xe1\xc3\xd9\x0d\x99T\x7f \x9d\x9b\xd6\x03\x81\xd6\xed\xc6\x0e\x96\xeb\xa8\xb3\xa5E*gVDk\xfa%r\x9cS:\x1d\x83\xe8\xe5\xe7\xedE\xf8\xfc\x99\x8a(i\x9a_\xbf\x13\x18\x8c\x0fw\xcah\x16\xa7\xa9\xdfEo\xba7\x18\x11 S\x0cv\xbb\xb37b\xc3\x0fy\x809LK&\xcd\xecBLp\x87D\xbb\xfa\xbd\xa0\xcd}\xef\xdf\x8c\xcd)A'\xd0\x16\x9aS\xdc@m\xa7\xae\x95^#\xc7\xe0g}\xc1:\x0b!\xd1*\xc0\x18\x8c \xbe>\x062M\x10\x9f\x15\xad\xb6\x84\x02}\xc5k\xfc\xff\xec\xbdk\x97\x1c\xc7\x95 \xf6]\xbf\"P3KU\x0d\n\x8d\xee\x06@\x11MAt\xa3\xbb\x014\xd4\xe8n\xf6\x03 \x00a\xa0\xac\xcc\xa8\xaaDge&\xf2Q\xdd\x8d\x11\xe6\x90#\x8a\xc2\x83;\xb3\xde\x91\xa8\x91=cy\xd6$H\x00\xb3^\xdb\xeb\xb5\xd7\xf6\x8e\xf7\x1c>\xd6>Gs\xa8\x99\xbf\x80?\xb0\xfe >\x117\"2\xf3\xde\xc8\xac\x02 R\x9c\x1d\xd59\x12\x1by\xe3\x1d7\xee+\xee\xbdqFcp[\xfcSc\xeeB\x81M\xe2o(X%\xf9B\x8e\x97\xbe\x9cjS\xf7\xf8a\xda\x0e\xada4\xd6\xe1j\xd2\x1b^\xf7\xebc6ms\xc2#v\xf4\x88\x01\xe8t1bT\xde.\x01\xbe\x90\xa6\xfe \x9cDs\xd4\x18\xca\xf3\xcb\xa6\x0f\x13\xd2H\n\x88\x9d]\x0foX\x06\xc6\xd1\xc0<.$\x95F'A\xfb\x8b\x93\xaa7\xa8_\xc9\xb1X\xce.|Tf\x17f-\x946\xc0<e\xbe\x9e\x9e5_O\x7f\xc7|\x9d\x9b\x9f\x97q\xc5G\xf5\xc0\xe4\xa0\xd8\x82\x80\xb2\xb9\xf9W40\x12\xd8\x0e_\xe7gO\x96>\xcf\x9d\x9eg\xb2\xd9\xef\xb1\x97o\xb0\xa3\xe2\xcb\xfc+\xecG\xec\xe5\x13\xec%f\xea\x9c:5\x7f\xfae\xd3\xff\xa9\xef\x9c8y\xb2hb~\xfe\xa4nbn\xbe\xdc\x06\xb4\xca^b/\x9f\xb07\xddND\x0bs]\xb9\xb0/\x9f:u\xe2e)S\xcc\xcd\xce\xcb\"\x1d\xf6\xdd\xef\xb2\xb9Y\xf6#\xa6\xbe\xa0\xb5\x97; C89k\x86\xf0\n\x19\xc2\xdc<\x19C\xf3\xd0:\x0d\xac\xc2\xce\xd5\xddh\x14;ns\x14n\xf5\xcd6\x8aaQ\xefV\xdd\xc5Cd\xbdr\xa0\xe2g\x9cD\xf1\x02kE\xd5\x0c{\x96fI\xeef\x91zH\xbb\xf4\xa1\xe8\xab\x16\"4\x85b|\xdfb_VaU3/\x16C \x1bTS=\xfe\xcf\xe6g\x8f\x0f\x8a\x16\xca\xf7\xc4\xd5\xc50\x97\xb2\xad\xadsK'N\xbf\xf22J\x1f\xd3\x97i\x89\xe1m \x8a\xbd[\xe7\x96\xe6\xbes\xe2\x95ib\x8c\x88\x90\x19uY\xeb\xa8-\xf3\x04\xa5\x13jh\xcf\xd1\xcd\xc4+\xe6j'f\x1e-\xf5W\x8b\xc0a\x00f\x95\x9eo_\xf5\x0e\x02E(6P\xbe\xbdF\xb7/l\x9f\x9e\xc3a4\xbe\xfa>\x8f\xbe\x9b0W\xb5\xbd\x93n\xfdY\xe9\x04H\xef\xc8P\xbf{\x02O\xb9H\xc7\xac6/;\x9b,;\x99<\x13\x19\xf9\xf8\x1a\xe33\x03\x9e\xed\xf8#\xde\xee@\xf5\xd2\xbf\x17T\xbc\xfe\x11x\x19\xcf\xa2!Vt\xa6\xe2\xbb\xcc\xf62\x03\xe7@\xca\x9f0\xb0\x05\xf9\x97\xfcc\x9aY2\xb5\xf0A\x97\xb9\xf5t;oC\n\x97\\\x12h\xb52G,~f\xba\x02/\xf6\x0fhp\xf1\xef\xa9\xea\xfb\xd2\x80\xa0\x0b\x1e\xf1\x85\"\xa03\xe3\xe8\xd3\xd1\x01\xf3\x91\xfag\xd6\xe92\xc7\xcc\xb4\x81\x07\xa5\xb2\xe9z&#\xad\"\xe94\x13ef\xb2\xca\xbc\x083E\xbaDSm\xc9\xd0\x02`bA\xc5\x18\x14\x1c=\xda|\xe7);\xbe\x1e\xdcP,.\xb81U\x87\xba\xc8\xb4\xe9\xfeX\xad~\xa7\x7fc\xf5\xe8W4\xf1\x8d\xd4X\x96\xcaj\\\xf6\xb4\xc67M\xd2\x8c\xba\xe4s\xb5{\xde/v\x88\xc5\xd3n\x90\xdc\x9c\xfeL\x1a%Y\xbb\xd3e\xb1\xf9K\x06\xea\x95\x9e\x88\x14{\xf7=\xd8\xc3c\xc7\xeawM\x0e\x04v\x8c\xc5\xd3l\x98\xc1\x8e/\xd8\x99\x8c\xed\xbb\x1e\xdc\xe8\xb2#N\x9b_wotY&\xff?\x9c\x8c\xdbZx\xd14\xa8\x90yi\xfa\xfd\xbb\xc5\xb1\xab\xc0\xee\x96\x1c\xa6\x8c\x7fR\xde,kHu\x9c\x15Y\x17\xcfT\x1e\xce\xbaki0\xadm\xf0H\x1bH\xab\x95\xa8\x8a\xef:\xffV\xe9\xbbA\x0e\xe9\xcc\xa9;\xa9(\xfb3n\x14\xcb\xb7\xf8j\xc0\x92_I\xf1\xa8\xa0\x0c\xea!d[\x8f\xd7go<\xaf\x04\xa49%=(\xc0\x0e\xe8u\xb3\x8d}\x9e8=ka\x9f\x13/\x98\xd5\xe2Fj`H\xad\xbbK\x19o\xd8\x9e?1[1\xb4_L\xa3pS\x1cw\xfd\xa0\x9b3S\xfc\x13\xacN<^\n\xa2P>*=s\xd3\xfc\xb3*\xee\xe5\xd6%p#\xfe[G\xc8s\xa9+\xd4\x11\xa2\\&O\xa9;\xdc\xf9\x8c\xf8o\xf5@\xd9\x14\xaa\xc0*\xa9Kw\x03\xd0K\xean5\xb5\xd5\x9e.\xa7d\x02\xa2w\x0b\x17P\xd4\x1f\x8f\xab\xfcO\xc3i\xe4Mt\x97\x85\xb0q\xa6\x8cM\x8bs\x95\x93JR\xe3\xa7R ~\xd3\xd2\xcf\x91\xb9\"\xbc\xeb\x8cN|.\x1f\x98?2\xdb\xe9\xaa\x82V--a\xaf\xb1Dp\xc2\xd9.\xe3\xf2\xeeDH[l\x81\xc5\xf2\xa3\xcc\xb8\xdcR\x179\x00\xa2\xab4V\x99\x0d\xed\xe8XAE\x8b\xa5\x95\"=x\xb0{\x9e\xee7\x8a\xcd\xce\xb93\xa5\xe6\xe4\x1d\x8a:\n\x16\x9b\x9dlF\x9d\xc7\xe7jJ\x8bl\xe2T\xd6\xb7,\xa5C\xd3\xacT\xa3\x05\x8eO\xd1\x93D\xd4\x10D\x94.\xc3\x0d\x89\xad\xaa\x0c\xa1S?\x06ql\xca\x1d\xdaw@\x9a@\xe4\x11cg\x04\xf75\x88\xd81Od\x01\xb8\xc3\xb2a\x12\xed\x8b-#\xcai\xbb\xb5#\x1a0\xce\xc1\xac\xef\xf8\x01\xf7Z]\xd6\xdaY\xd9\xde\xb9\xb9\xb1\xb9\xb2\xb5\xb8\xb3\xba\xb1~\xf3\xdc\xe2\xea\xda\xcarK\xa2T\xd8e|\x82\x18\x86\x16G\xac8E\x92\xba\xcd\xad\xae]i\xc5\xab[\x88\xb7:\x0f\xecf^\xd9\xaa<\xef\xb4\xcd\xb0\x90\x18j\xeb&\xcd+h\x1e\x81g?\x8c\xe2\x1f\xca\x8bL\x9ed\x87\xccOY\x18eL\xa8\xf9Q\xbfX\xe2\x94\xa9\xa8J\xe6\x87l\xeb\xdc\xd2\xb1\x97O\xcf\xce\x8b\x05/\xd6zc\xf3\xe6\xea\xfa\xe5\xc5\xb5\xd5\xe6\xf5\xd6\xcbR%V\x95\x7fE\xca\x92\x8fT)\x8eU)m\xe6l\x03=`\x90WW2\xd0\xac\xdd:\xde\xb2\xd8>a\x17\xc8\xe7!;\xc3,\x8f\x16\x8cKv>\x0b\xb31!b\x146h\x80\x1d\xd6\x84\xe3J\xd3\xe2\xa1|\x1a\xae\x8e:\nb\xf8\xaa\xf5\xcaWl\xf9@\xda\x16\x877\x14\x95-\x11a\x08\xde.\xc7\xb3]\x1f\xdc`\xaf\xc9)\xf4\xc18\xd6\x9e\xed\xb2\xa1N\xc5z\\f\xe7\x1b\x8a\xee\xc7\xec\x18\xe4\xe2o\x8f\x98\xa1\xbc\x95\x00^\xd9\xf8aA\xb8G\x82R\x0f\x8f\x1e\xc5\xf7\xc8^\xad\x89_\xe2\xfa1@\xf4AG.\x9e\xa7\xad\xee\xd6\n\x0d\xae\x8aL\xe3\xbf\xb4\xf6\x95\xa5\xd2A\xa7\xf9H\xac\x1c\xc4\xdc\xcd\xb8\xc7\x9c\x90\xe5a\xea\x0f\x04\xba\xf7\x9c\x94\x1f\x9b\x9be\xea9d\xa6\x08\xf3\xc8\xd9\xf3\xc3\x01\xcb\x86\\6\x96\xf0>Ox\xe8r\x0f\nH\x80\xf4\xe9c<\xe0\xf2\xa8\xef\xfb\xd9P~\xbe\xc3\x93\xe8\x98h\xd6\x03\x81\xb5z\x8a6\x17w.\xdc\\][[9\xbf\xb8vsqkk\xf1\xea\xcd\xd5\xf5\xe5\x957\xd4\x99\x02\xed\x8e5\xbd\xe5W\x9d\xb2\xdc9\xb1\xa0\x7f\xfc\xc7\x83iu\x1b\xa6\x96p\xc8\xbew\x86\x8d'\xdd\xcb\xc8\x85\xae\xf2H\xf1e\xc0\xbeg6q\x021\x1fr\x19\xc6\xe1\xf7}\xbd&\xec\xd2\xee\xf6\x0e[\xdf\xd8a=\xce\x06\xd2W7a\xd9\xd0 a\xc5\xa5\xc1V\xd0'\xb5\xb8\xa9\xa0Jf\xc9\xab\x0bzyqmw\xe5\xe6\xc6\xee\xce\xcd\x8ds7\xcfn\xec\xae/oO\xbf\x96\xf2\xde \xd8\x92\xb4\xdc\xa7\xd7\xc5\xf4n\xc0\xedV\xd8e^\x97\x0d\x04\x99\xeb|\xfd<\x8b\xd5\xd1R\xfd\xb3\x08\xccE \xc3@\xb9\xc5\x1c9\xc3\x06E\xaa\x83?n\x15\xf8\xe2\xcc\xe4!\xe4\x9a\xdct\xb2a\xe1)8\x90\xa7\xbb\x113\xf0\xaa\xe5\xdf\x9cU\xab]1\xbaZ\x1e\x032Y\xc3\xa8l\x02s\x7fz\x81\xd9&\x16\x13\x07\xe1\xe6\xa5\x91\x7f\xb3\x94\xdf\xce\x05\xe5a\xa3<\xcd\xc4qq\xc2\xe2\x18l\xaf\xbc\xbe\xbb\xb2\xbe\xb4rs}c\xe7\xe6\xe2:\x10\x14\x1c\xe12-\xbb5\x9e>\xf2F\x9f\xef3\x1d\xd6\xa4\x0e\xb9\xf2\x00\xebB>Msk\x9a\xb3\xef\xb2\xf4U\x96\x1f=\xdaa\xfe\xf5\\\x86`\xcau\xba\x9e\x0bN\x05\xf7\xf7\x12R\x16\x8d\xac\xda\x8bO\x054\xbfqC\xe2 \x1bRw\x0bU\xbd\xf6\xa2^\xf4\xd3IVJ\x96rB\xa6\xba\xa9\x10&\xb5%\x1bg/\xae,\xed\xb4\x00k\xc5z\xbcJFy$\xbf\xce\xc5\x01\x9a\xb6\xdf\xafD\xa2\xab\x1f\x9eq\xbe-_\xd9\x81\x826\xe5xEa:b\x87\xa9\x86-\x0cr\x8aa)\x9f(9\x92\x82\xc4\x1d\x07\x12\xa7>\x177\x81\x8dc\xfdv\xfdX\xe5\xa9K3'Q\x1c\xbeu\xbc\xf5\xed/6\xde\xb2\x1a\xc7\xa9\x1a\xc7\xa5\x02 X\xadm\xb9\xa5\x027\xedr\x8b\xc2t\xb9\xe3\x84\xa7\xe2X\xb5U\x88\\/\xe0\x025~(F\xf5C\xe6\x84\x1e\xfb\xa1\x18\xcd\x0fK(\xd4\xa9n\xcd\xb9\xad\x8dK7\xb7V^\xdf]\xddZ\x994W#/\x98\xa9V\xd4c\xf3\xb5P+\xcd\x02\x94o\xa1\xb5Eq\xca\x99\xcb\xd2\xd3O\xdd\xf1\xbc\x1fv\xd9\x0f\xd5\xc8\xd4\"\x88\x115,\x02\xc8\x1b_\xfd*83C'\xdd\xd5\xc9n\xdaz%\xbeyK\xb1\xb4\xb8.H\xdd\xd2\xc6\xfa\xce\xe2\xea\xfa\xcd\xdd\xf5\xe5\x95s\xab\xeb\x13\x96\xc6r%Q6\xc5\xa8e\xa87cB\xa0\xb4<\xe3\x85:\xd8\x98_\x83)kxD+\xd8E 1\x1e_\xd2\x98\x94\x1d\x05\x15I\xfd\xb3y\x0f\x96\x9cP.4OdT\xb2\xa3\x16\xb7$\xe48\x99\x14f=\x9e\xfa \xf7\xa4u\xcfB\x03\xd5\xba..\x97W\xb2I\xe6\xab\xc1\xad\xb2\xe5\xc2|,\x0c\x0fM+\xed\x83W\x99\xa3\xdc\xac\xa2\xe7\x9a\xb8\x98be\xce\x8e\x9c\xa9\x10\xf33\xe6E\x1c\xf0\x91\x1f\xf8if\x99\xfd\xee\xfa\xd6\xca\xf6\xc6\xda\xe5\xc5\xb3k+\xd3\xce\x7f\n\xfaZ\x8fQ\x81\x10\x07\xdb\x16\xff}\xfdk2\xd0\xea\x1f\x18j\x81\\O\xbc\xa3\xab\xc9}.~wo\xd0c\xa3\x7fb\xaa\xd2\xeb\xbdq\xc9\xe4\x9c\x03\x99\xf9\xe2K\xec\x9a\x98\xc7\xd4\xfb&\xd9\xc3\xd4\xfb\xd6(\xd7yZ\xae\xc3;f\xf7\x8b\x93B\xd4\xf3Iq/J\xb8\xd6\xdd\x87\x1d\xd6oW\xe4\xeb\xb0\xd3\xc5\x02\xb7\xd0\x03~\xf4#\xa1\x11\xd0F\x1aL\x1e\x89L\x19\xf6\xa3\x1f\xd5\xe5\x01\xac\x84t(\xd7\xfc\xc2\xab1\x12\x82y\xd2\xe6\xd7\xa3\x1b\xd2\xb79\xd4\xc6\x9dI1\x0b\xcd\xee\x81\x926\x94\xfdn\xf1\x1a\xd7]\x81\x88\x1f\xecLm0\x99\xf9K:\xed\xca\xf7\x92\xcf\x1enF~\x98I\x0f\xfa\xc0Du\x17\xfc\xee\x0cs\xcdW\xd8\xdb3\xaco\xbel\xc9p\xbd\x04\xc7\xe7\xe2y\xe9\x0b2u\x8bb\x91\xd4A\xebM\xbe>\xc5V\xadaR\xd6\x8c\x8a\x85\x12\x13\x1c;\x81\xef9\x99\xf4\xe9\x8aK\x1f\x84\xd6\xe5}K\x15\x9b\xc6\xb3-l\xcf\xbfR\xea\xbd\xd6w\xdb\xa6h\x1dI\x94\xb72\x9f\xb9\x99\x81{\xac^\x9e\x9d\xc3\x98\xab5Y\x0de@U\xe6\x0b\xa9#\xe1.\xf7\xc7<\xe92\xf3\x96\x84L)\"x\xe2\x11|\xcc4*!\x1c\xf9BQ\x0b_(\xad\x0cM)SN'Sr\ni\xcf\xcfw*\x8ew\x96<25\xbe\x93\xf4\x909\xfd\x8c'k\x91\xe3M\x13a \xafk\x93(\xcaVC\x08\xc4>C?\xe9w\xc9\xd1\xf7\x19?\xf4\xb3\x8d\xc5<\x1bB\xb2\x98<\x1b.\xca\xde\xd2\x197\n\xfb\xfe O\xb8\x80Zj\xc6 7)\xdc\x16e*(is\xee\xf9\xa1\xd7\x86\xcb\x0f\xe94\xdeT\x0d\xf2\x1a\x9dan\xb5\x16%O\x94\xa5\xa6\x99\x93\xf1\xcd \x1f\xf8\xa15\x0eD\xfcD?u0&W_\x12\x87t\x81Ez\xb3\xeay\xb7\x03\xcb\xd2\x185\x96\xf2\x80\xbbY$Z\xb4\xbf\x0fY\x93\x95\x16r\xdd\xd4\x0ft?q\xe2E\xdd\xbf\xfdQ\xae\x89\xee!U\xdaa\xdd\x05\x0c(v\xb5\x8a\xf0\x91B\xf8\x13\xa7O\xe2\x9c\x19>\xbc<\xd4\x9e?A\xb2M:\nt\xe2\xf4)\x0c\xca\x0dH\xe6\xd90\xb0&\xb7c`C(\xdbc\xd3\xed{&\xa3J(iWQW6\xbc#\x89\xea&$\xe80\x91D*\x05@\x06\xd1\xdf\xfczX\x93K\xa2L$x9\xff\xa7M6\nj}\xaf\xa7\xcfzY\x93\xf1\xb2Y(s5\x89\xb5\x18\xdb\n\x9d\xacL;\x0c\nQ|/\x1e\x0d\xd9\xd6\xa7\x85\x16\xca\xa5\xcdR\x14\x12\xdc\xd5r\xfaMz5?\xddX\xdc>\xd1\x91 \xcd&>\xb2\xc1\x16\xd8\xf5\x96%\xd3b\xcb\x12\xa6*\xd4\x82\xbc\xdd\x11r\xc8j\xd8\xben\xd2E\xa4]v=\xbbA\xd2\xc1\xc0F\x04\xec5\xe6\xcb\x07\x99\x13\x94\n\xb3![\x99\xfd\xdc\xebdq\xb5\xae5:u\x9c\xcd\xcf\xd2F0\xc5\"8\x0b,\x98\xc9\xa2\x8b\xdb\xe8=gHS+NB#\"\xf4\xeb\x1c\x8d4U\x98\x1a\x0b\xfci\xb0\xc0\x81\xb7[j\xb1 7O ~eX \xc3\x98-X\x907aA\xca^c\xd1\xf3b\x81\x0d\xcb\xd5\x96\xa5So\x19\xfb\xa6\x89F]\xed\n-\xa5#\xca+$\x84d^r\x14d\x8e<\x00\x90Kq\xf5;\xe8+$\x1b\x9e\xc3\x11\x16\x81\x8a\x87\x98\xb7\xf2\x14\xf7\xeb!\xa7\xfa\xaf2\xa9\x97\xfeT:'kT\xca\xc9\xdae\xc1\xcc\xf6\x85\x8d+7\x17ww.\xdc\xdc\xdc\xd8\xdc\xdd\x9c\x90oY\xfb\x95e3\xb1-\x9f\x9f\x9e\xd1L\xca\xb3v+\x1dF\xfbe\x84\x17\xa8Q\xda;\xfbx\xc4P6\xb6V\xaf\xad<\xefH(B'&Op?\x89F\x17\xb7;BW&\xa5\x80\x90\x0c\xc4\x80\x8b\x1c\xc1-x8CV\xbe\xe4\xc4\x1d\x1c\xf8n\xd4%\x1ef\xc9\xe16\xbf\xdd\x9e6\xe3\xba\x96\x0dP\xbaN\xdee8\xb0U\xff\xe4,\xaf\xcf\xd6\xe46H$t\xae\x06\nIe\x159i\xc1 \x17T*\x939\xcfjl\x0c\x95T\xab2\xc7H\xe9\xa5\x1d\xbf#W,\x92[\x1c\xda\xcdG\x85\xa9\xac\x94\xdf\xd4\x9a\x97\x87\x95\xc2}\x8aq\xca\x93.\x86\xa9\xb9R\xebFC\xfca`\xaf\xab\x19\x96u\x9aLm|\xdb\xccET\x0e\xbbL\xd5ot\x9f.xe^?*H3\xb7P\xce\xa6\n\x8f\x93\xf5\xb2\xc8)?\xdaS\xf7Ls\xa7S\x1e\x96\xda\xba\x1b]\x98j[\x7f\x98\x98\x11B\x066\xc3y,\xa1\xb7\x10\xad\xa6?\x8a77\xc4\x9f\xf3/\xe6D\x86\x92Q\xdb\xcfaX\x97,\xd9\xa9\xf1u2\xe7\x10\xde\xeb!o\xfd\n\xaa\x17u \xcfH\x95\x14$z]$\xd6T\x96\xc6\x81\x15\x96\x88\xd7\xb9\xd1-\xe7\x05\xac[\xaa\xb5\x8d\xf3\x1b\xbb;/f\x81,\xc4hf\xdf\xcf\x86\x97\xf2\x0c\xaeG\xa6\xc8\xa8h\xc9\xe4\xd5\xf8\x8c+\x9f\x81\xc0\xb2\xda\x10^\x0b\x9a\xd5\x98N,\xb8\x96L^\xc0\xa5\x8d\xf5s\xab\xe7w\xb7V$/z\xde\x85l\x1a \x18\x16,\xdcG\x8d\xea\xb7+\xc0t\xc1\xf6\xb8\x04\x83\x94s\xf2\xd3E\xb3x\x90\xd4\xad\xfaO\xaf`\xa9\xe7\xa2d\x0bLY\xe0\xbe\xa4\xd2\x0f\x94\x98\xee\xd9\xc3ug\xc4S\\q'2}H\x90`\xd5a\xa9\x9a\xe5\xb8i\xdbS\xde\x0e\xdb'\x89t\x15)\x08\x95\xa1 o\xc3),D9J\xb4z\xbe8\xe2\xafDV\x1a\xab\x04B\xf5\xc7\x8a\x9a\x05\xcb\x967\xcb\xe2\x01\x19\x82\xec\x90Z\xe5\xe8\x08enr\x1f\x8a\xbc#\xd9\xa9\x83p\xa6v/'\xf7\\\xd3\xf1tb\x0b\xd2\xa2l\x0f \xb4\x8d\xec\xe4\x80\xecT\xfb\xcaQh\xe4\xa05?\xcd\x88\x90\xc5\xca\x96\x8b\xe7\x16\xb4\x18\x12\xb6\xa2\xa9\x84-fD\xaa:\x81\x8b)\x9c\xae\x17\xbaXIYt\xac\xe2c\xb9T.\xc9T\xd2\x95/%\x86\xe0\x1b\x9b\xa7\xc3vn#\xb9]\x9c\x17\x91\x92\x12\xeb\xe1o$\xa7S#@H\x11\x80\xce\xcb\x8d\xc24\n\xf8\xcc\xbe\x93\x84\xed\xd6\x95\xc5\xad\xf5\xd5\xf5\xf3\x0b\xcc>2?e\x1e\x8f\x13\xee:\xe00\xeb\xb1}?\x08X\x8f\xeb0\x1e\xed\x91\x19\xf2\x83\x8c\x8d\x9c[Q\xc2\xc6\\g\x9aB7\xe2;\xd3\x04\xbb\x11\xe7\x99\xce`,I\x98?\xa1W\x1b\x8f\xc1\xbf\xca\x9b\x039PF\xa9\xba(\xd7\x95T\xd0\xbc\x97^b\xed6\xbcp\xa1$\xe3(\xe6i\xab\xd3\x99\xd9\xe3_h%\x99\xf4~v\xa30s\xfc0U\x17N\xb2\x87T\x8bI\xdc\"w\xeb\xdf]\xe5\xc1\x98+I(\x08\xa2}\xeem\xc3\xa8\xba,\xed\xa8\xe46\x99\x84\xfb]f9\xe9\xba\x1d\x1f\x9e\n\x95\xb9\xcd\xec\xf4\xc0\xaf\xa3\x07\xddI\xa2B\xfdbh|u\x92\x81\xbc\x08L\x0b\x07\xb79V\xcd\x15f\x8a\\\x9f\xbb\xc1^\xab\xfes\xa1\xe9TMEtT\xa16\x18\xfa\n\xaec\xe7~e\xc6\xa3\xfa\xecL\x9f\x84\xdc\x1c\xf14\x1a\xf1)\xc5fSG \x1e/\xe1\x9b\x9f\xa4Y\xbb\x06G\xac\xb2t\xd3.V\xe4\xbf\xc9\xfc}\x82da3rh\xa2\x84\xb8 \x92D_$\x13\xa9\xeeg1\xa6\x06\xe2\x0b\x9b:\xe3\xa7\xe2?\x10\x1b|\xe4H\xa6\x8c\x95\xcf\xbd\xcf*\x97#2\x9b\xf2\xce\xcc\xc8\x89\xa7h\xa5\xd4\xd2\x91#!\xec\x7f\xddv\x1b\xaf\xd1#s\xb6\xad\xd7\x87\x0b\x99W\x19E\x84\x8a\xa2\xf0\xa5\x11A+F\xe5]\xff\x16\xfbFhD\xfc\x80\xbb\xb9\xf4,\xb0j!]\x95\xe5f\xfe\x94E\xd7\x90\xd6\xceH2\x88\xa4\xaa($\xcd\x8aB5^\xb8\"\xe1\x17\xe3\x99R/\xad\xa0\xb7]\xcd\xcf\x9a\x04)|\x9aj\x9f\x83\x89\x94\x1a\\\xe7\x8e\xe8\xa8\x0c\xd6\xd90\xaayr,\x97%\xa6x\xc1M,C\x968\x0d\xcf\xc9\xd6\x1f\x95\xe2\x80/(\x03\x90>\xeeb\x9f\xaa_\xd4\x89\xae\x97\x1eJ\xd4\x7f\x81%5*\x88\xdc~+hb\xfb\xe5W\xdd\xca\x1d\xe0VMS\xf6s_K\xc8x\x1b[\xa9\xac\x0d\x80\x93_\xcd\x1by\xb0\xa3\x0b\xcc\xb1\x83K\x0f\xde\xd4\xd8(\xcb\xaf\xe6X^\xbf\x95rJ\x1d-\xfa\x86P\x89/\xe3\xf1\xd2\x0f\xebnB\xd3\xa1\x94\xd8Vn\xe7N\xf0}~\x08(\x86\xbe\xd1\xf5\xaa[*j?\x917G\xdf\x80\x15\xa4#K\xdba\xfb$y\xe7:2>\x16\x13\xfd\x8dj\x05I>\xd3\xb7\x10\x16{\x82\x02\xf1\xf3\xa2\xfd0\x98\xd2\x1d\x89Y\xc8emj\n\xfd+\xf4D\x9e$\xea\x02\xb9Y]aZQ\x9at\x8d\x8c\x7f\x8e\xa94u?\x10\xf8Tp\xfb\xc95\x02I\x9f\xfb\xa0\xc4v\xcc\xddv6\x93 ~'\xf4\x8a< \xda\x9d\"\x93\xbf.\xb6\x9b\x04u6\n\xfdk\x1e\xbbL\x14#8\xac\xea\xa2[7\xc6\x00\xfe ,\xdc\x0d\xb8\x934\xbc\x8d\xa1\x7f\xcf\x83dB\xfe\x0f\xa6h3O\x82\x05[\x9e\x16\xfc\x13\x03\xde\x96^\xd1G\x1a\x1e<\xd4?\xf5 \xe9j\x98\xf1\xc4\xe5q\x16%\x0b2=\x0f\xfe*\x96j:\xf9\xb5\xfc#w\x8du\xbf\x1a\xef\xee\xf2/\xe1i\x1c\x85)'C%\x9f\x7f\xfbcu\x13\xee\xf10\xf3\x9d ]`\xad\xd4\x19qEg\x1b\xe2\xe0\xf4O\x91\xb7&\xa7\xf6\xf2OP\xc98[\xa8\xbe\xe2y+\x8d\xc2\xee\x1f\x1c\xff\x83\xc9\xe4\xad\xf9\x94\xdc\xed\xccdC\x1e\xb6\xfb]\xd6o\xb8$\xb0Bj\x96\xc9r\xc8\xa6\xd5\x8c\xb4@x\x1d\xa2\x1d\xcc\xd1\xec\xb2V\x11*\xa4i\x8a\xf9\x08zG\xab\xe1\x0d\xf4\xaa\x1553&Nx\\N\xdf\x01r\x95\x11G\xfcg\x01\xc4p)\x90Ws h\xdf\xa8\x92\x1d6\xebLdT\xd9a,\xa8\x85\x90\xb5n\xc2\x02\xddT\x93\xbb B\xf8\x04\xbcQ\xae#\xb6\x04n\xfaW\xb3I\xe4\xab\xcd\xff\xb9V\xb7\x0d\xaa\xdbh7\xe3N\xb7\xb9\xc6)\xa2\xce\x8c_\xfe\xddm\xb2\x0c\x97\x7fU+qe\xb8pc@\xcc\xd4\xfag\xbb\xd9\xb0\xda5i\xe7\xd3\x04\xd8L\x8a[113\x8d\xd9!u\x10N3v\xd5\xa3\xd5B\xb3\x0d\xd8\xf6S\xb3\xb6\xbc.g<\x98 \xd1)]\xf0nQD\xe6;m&=\xf5\x98\xdc`\xed,\xa2\x88j\x1e\xa0\xa2\x9b\xfa-\xfb\xbf\x90\xb5k\x82\xe7O\xf5\xab \xca\x99\x9f:&\xe7\xab\xf2 \xfa\xed\xda\xe5\xbe\xace\xf3\x85\x9e\xa4\x1a\xf32\xab\xe2M\xdf\x8e7\xf6\xba\xea\xdai\xbaH\xb9t\xe6EG\xca}\xe9x6j7u\xdba\xfb\xf4 \x12\x9c\xa6\xee\xa8N\x9c\xb0\\R\xc9\x00NZ\xc5Q\xa0\x93\xb3\xb3\xb6P\x04\x00\x11\x0bm\xaa\xc6pr\xb6\xe6\xecXB\xb9\xfe\xe9\xc5\xb3}\xcd\x01\x18c\x95T\xb2\xda\xc8\x80gk\x91\xeb\x04 `-4\x9b\x03\xb5\xf7\x834K\xc4N\x92\xf2\xab\xceHU\xed\xb4\x0bi\xa9q,\xbf}bf\xec\xd8g\x0fw\x130Tk\xfb>|op6\x85\xf3S\xb9v\xc0U'^w7_\xa2\x96\x169\x9b\xe9\x87`C\xef`E\xb9\xee\"^O\xe9\xb9\\#\xac\x06*}\x99[\xb9*\xa0\xf2\xb7<\xb7\xe6\x9cFh9\xda\\)\x1f~\x97\xf96\x03\xbf9\x0d~\xfd\x1dIh5\xe2\x87U#>{\x8d\xb5\xa3&\xfb\xbdR!:\x02w\x9f\xab\xd8n\x12\xb4[\xe2CU\x89\x08KV\xfd\xc2\xa8?\x93'\x81@2x\x81]HH\x99\x8a\x84#\xe7%\x04\x03\x89ED\xfd\x06\x9f\x9f2\xe6\x0fx6%\xa6q\x15\x0d\x83\xdf\xdf\x94\xf6\xfc\x05\x19J\xf8\x0d\x9d\xa5v\xef\xe8*\xe1q\xde\xf6\xda\x9f\xf4\xf0\xf0\xbf\xbc\x87\x07e\xb0u\xb1~\x82U\xdb\xef>e\x00\x91\x8e\xad+\xc5sE]\x96\xce\xecn./\xee\xac\xdc\x84\xd8\x86\xed A\x0df\xef\xe0\xb9\xf1j\xb4J\xa1\x04\xd0P\n\xdc\xeb\xce\xc6\xf9\xf3k\xd3\xf6\xfa\\1)8U\x89\x19\xb2\x8a\x05;\x82\x02=\xa2o\xc2=\xf7\xf3\xc9\xd3\xd7\x0d[\xb5\xd9\x1f\xa6\x91\xad\xa7\x90o+ \x16\xea\x8b1e-\xe0\xf8\x15\x8d\xe7\xd09\x9f\xfb\xbe\x91C&\x1b\x95c\xb4[xtNa\xb2f%\x84\xda\xf7C/\xda/.3\x86NZ\x93\x00\x0d\xff\xb2\x99\xc09\x8c\xf2L\xc7uKJ\xbe\xccy\xbc\xe6\x87{\x17\x9ct8\xcd\xfd\xd2\x04\x1b]-\xf4K\x98|\xc4\xae\x9a\xfc\xb6\xb5\x1b[\xf2\xcc\x99\x90\x06\xc4$\x1d\xdaq\x06\x0b\x85\xbb\x10\x1dJ\xe5\xcb\xdd\"\xd1\xacEUq\xa4\x9a`UU\x00\xf4\xb2-|\x07@\xdf\xb1+\x17\xce\xd7'W\xff\xf6 \x89\xbc\xcc\xd8v\x93(\x08v\xc0\xf5.U\xffPw\xe0\xf2[\xc2\x1d\xefp'\x82r\x8a\xb8\"\x1c\xae\xd45!X\xcd\x0e\x8f\xfd\xda\xb8\xf6\xbe5\xf2\n\x0c-'g\xb1\x97d\xaej\x9c>AR\xa34\x86\xb6c\xde(\xdf\xa0l\x07V\xac\xe8\x7f}X\xc1\xd4*\xc5\xe5e\x9cH/\x0b\xc67\xc9\xcf\x06\x9c5\x81&5\xc4\xbdLKp+\xef\xf8c\x0f{\xd8h-\xafU\xde\xc2\xcfT\xee\xe3\x08r\x1f\x17\x9e\xf6y\x8d\x99\x1e\xb2*V\xa9y\xd4\xe9\xb2\xb0\xdd\x91\x8f0\nT\xf4\xc3Ag\x8aG`\xc5\xfeG\x13#D\\Yj\xae\xe1\xd6 0O@k\xa14\x10Bi \x84\xd2\xa0\xa1\x9eV\xa6\x13!\xef\x8b\xe3#+\x9fK\xa2\xd1j\xba=\x8c\xf6\xc3\xef\xf3C\x89\x88u\x0d\xc8\xdca}\xf4:ls\x7f1\x8d&\xeeO\x8e\xa5\xf1\xd8\x19\x16O\\\xa9\xa1,\xd5\xb4Rr\xc0n\xa7\xac\x9e:B\xcc\x12\x93\xef\xc8\xa4\xa2\xf5u\xe7\xe5\x9d\x8cyX\xf65\\\xbb-\xe3\xd0\xe1\xcaA\xd3\xa4M'\x83v\xd9Q\xe6Iw\x16\xf1\xd7P\xaaTs\xd5\xf6^z\xe9\xb9\x1b\xac\x8b\x84\x98\xea.\xbe\xaa\x07N\xff\xb2Z\x95hT7\xc4\xc3\xf4\xb7\xf9j\xa4\xd6\xd8\xca\x8a\x8b( \x107\xa1\xcd\x9bYTs\xfdd\xae\x9dp\x1eIE\x06\xafs\xfaTW\xe3T\x86\xb5\x0cf\xaa95[GX\x85RV\xe4\xb2z\x0c\x9f\x92`2\x85\xe6`z)\xa8p\xa7J\x9f$\xbbh\xc2\x8f\xb1\xc9\x06\x04\x0f\x90\xcc5\x1c\x8d\xd6\x11\xf08\x13\xc4\x8c\xe9\xcc\xf9\x91\xa9\xd8\xe9J\xc4o*\xd1L4|\x9c\xf9w\xfah\x12\xfd\xd3'\x9e\xebwhT\xba\xdd\xf6\xf1\x9b\xc7\x07]\xd6b\xad >\x1c\x13(\x94#\xe9\xa8o\xe8\xa6\xa0\xa2\xbb%\xaa\xda\xf6\x1b\xe6\x18J\xfe\xdav\xba\xf0\xdc@h\x8eP\xdby!\xe7rl\x95\x9f&2\xf3\xa9,l\xac\xe2\xf7\x8b\xd0S\xe0\x9f\x96\xeb\x043\xa9Y\x03\xd7xi\xf9i;\x01\xfd;0Z:\xef\x80\xe1:D\x1a\x0c\x92\x11%g\xc7e*\x92\xa5-t\xacq\xddF5\xb2\xe8\x8b[\xb9f!A\xca\xbd`&\xec\x87\xc5Zn:\x89\x98/\x17\x92\x8cY9u\xd7-\x0b\xc8G\x1eg\xb2\xa8\x96\xac\xff\xd68\xc4@\xae(\x96\xf7\xa7\xb1\xd7O\xc3%d\xbb\x8aWP\x87\x1340\xbb\xe5\xa9\xda\x8d=\x9e\x01m\xc4\x94f\x04M\xf0\x8d\x97\xaf\xfeC\xe1U3\xe5\x97\x84|\x14\xe7\x19\xf7\xb6\xb3\xc3@\xe6#\xae\xad \xd6\xb4\xe5\xf4\xd2(\xc83\x95S;\x99\x89\xa3T\xc6\xea\xd4W\x93\xf1\xf7\xec5v\xbc\xed\xe4Y\xf4#X\xc7\x1f\x0d}\xcf\xe3a\xe78[\xa8\x02:\xc7\xeb\x99O\xab\xef\x1fp\x0f\xf7\\\xbc\x90f\xafidx\x99^\xf0U\xf9\x1fG\xf0\xe0b\x91^\xad\xa7\xd221\xbdm\xa5\x9cN\x97\xb5\x8f\xc8wTZi\xe6d\xbe\x0b\xae\xd3\xe5\x81\xbd\xf4\x12\xf3eZ\xe0v2\x13\x8dy\xd2\x0f\xa2}v\x94\x15\xff\xb8Z\xf9\xd7\x1b\x9d\xc2\xdd\xde>\x17=\xd3IX\x88\x14\xc5 \x960\xc0\xf3\xdaT\xa9\x93\x8d_\x88\x96-\xb0\x86D\xe7\xba\xec\x02\xab\x89q\x13\xbf\xcaQ^`\x83\x06,.\xb3\x9f\x056\xae/I\xa4\xae\x056\xb4\x13\x1f{\x1b\xa5{\xe9\xfa\x95\xa8r\xa6i\x1d\xbf\x18\xc3\x9e\xccM\xef$\xf5UZ\xac\xed\x01\xb4_\xd4{\xa44\x8b&\xa9\x1e^;\xf1\xbb,\xb7SgDX\xb2\xa1\x9fvY\x9d]\xd5\x08\xc1\xa9\xd5\x90\xed\x1aCv\xda\xe9J\xeb\xed\xec\xab\xac\x0f\x8f\xf8\xf5\x8f\x1e\xed0\xf7z\xbfj\xc8\xee7\xbf\x16/\xd8\x9cO3\xa7\xc2 \xe5\xbb\x83\xc1\xcc\xcd\x9b\xd2\xb9\xec\xe6M\xed\x12]\xf2)\x0f:\x1d\xe9a\xa6L\xe2\xbc\xcb\xae\x8b\xba&\xc9\xb2\xdb\xe9\xc8\xf0\x99(\\\x8b\x1co\xa2\xfdL\xff4\x07\xf6g\xe2$\x8a\xd3\"\x93\xc2L\x16\xc1\xc1j\xca5\xc0\x14\x17F\x92G8\x939\x83\xae|\x04U}]\xf5\x1a8*\xbe2\xadH\xb0\x82?\xd4\xe9\xc4p\xc3\x10\x12G\x02{V\"J\x96K\xe6\xe9\xbc\xb4\xd2\xf06<\x92I\x82.\xaby\xf6hO\x88=\xad\x84\x87\x1eOj\xcc\xa6\x8a\xdaL\xbc]a\xc5\xa0Rdq0Q\xaai\xec\x84\x84\x9c\xd1F\xfa\x0b\xf0\x9c\x04\xe0Cm\xe1\xbb\xdd\xda\x9e\xb8z\x90B\"F\x1d?\xa7\xab|\xa3\xd3E)\x19\xee\xb6\x8b.\xcc\x15\xf37\xda\x87\xe7\x1bG\xfaCi\x176\xff\xfc\x1d\xd9/\xfd~G\xf6\xbf8\xd9\xb7\xe8\x85\x9a\x13d\xce\xe0\x0b\xd3\xec\xf0w4\xfbw4\xfb\xab\xa6\xd9\xcf\xe7\x1ag!?\xb5It\xa28='\x13\xb2=\x87\xe3R10\xc4Kt\xba\xaf\x93\xb3\xa7-L\xe3E\xe5\xfb\xfa\xe6\xeeG\xa3\xb7(\xc9{gy/\xa5TA\xbe\xd5~\x86\x85&`\x13\x87\x0f\xfc\x97\x85\xa1\x93\xcc\xd4l\x8a`\xa8)\xed\x19\xcc\x04\xeaB$\xf9tlD\xff\xa6\xf5\x1e\xc2?U/\x91\x0f\xc0w\x1b\xbc7'\xb6f7\x9a\x19h\xb3\n\x03\x13\xbf\x98F!\x9e\xfc\x146L\xf6%\xe6os\xe3jwf\xa2P\x90\xdc\x80g\x96G!m?\xb3\x8c/\xbd\xc4Zz\x10\xe5@\xcdP^\xec\xa6<\xdb\xf1G<\xca\xa5\xbb3<\xb8\x7f\x86\x1d\x99\xeb|\x95+_\x0b\xad1s\x92\xaf\xd3\xd2Y9\x15\xeb\xa1/\xefF\xf9\xbd\xc6\x96\xe7d\xce\x82?r\x06\xfcx:\x1e\x1c=\x18\x05\xaf\xf6\x9c\x94\xbf|\xb2\xbbya}\xfe\xda\xe1\xd9\x13\xce\x95\xadYgy\xd6\xbftkq\xdf\xbd0\xf0W\x97\xceF\xd7\xae\x04\xa1s\xe1\xf5\xd3\xab\xb7V\xf7/]8{r\xd5_\x1c\xf0\xf3si/\xbctzu4\x9c\xf5.,\xbe\xbcvx\xfa\x84w\xc2\xcd\xbd;\x97\xf2\xde\x89\x8b\xe1\xda\x9d\xd5\xfdK\xcb\x8bc\xf7\xc4\xb5p\xd5?;\xef\\\xb9|\xe2\xf5\xd1\xe9\x93\x9b\xdb\xab\xfb\xab\xcb\x8b\x83K;\x8b\xfb\xab\xcb+\xfb\x97\x96V\x07\xee\x85\x8b\x81;\x7f\xf9\xd0\x1b]>\xeb\x9e8\x1b\\=\xb1\xb5}\xf5\x8d\xad\xb8wg\xd6\xe7+s\xf1\xb5s\xc1\xbas\xe5u\x7f\xf5\xfczz\xf5\x8d\xf5;\x9b\xdb\x17\xd3k\x17.e\xee\xe8t\xda;\x1f\xe4\xd7\x0eW\x07\xee\x89\xadS\xbd\xf3\xbb\xa7WG\x17\x87W\xe7\xb3\xd0\x1d\x9d\x9e\xeb\x8d^\xcf\x9c+s\xc3k\xf3\xbb/\xaf\x9e?5\xee\x8dv\xbf\xb3z\xbe\nw\xcf\x9f\xbe\xe3\x88\xbe\xe6O\xbe\xbcz>\xc8\xc5\xdfW\xaf\xec\x0f\x9c+\xa7b\xef|0\xec-\xa7\x83\xab\xa3s\xb7\x9cy\xef\xb0w\xe2r~mi\xee\xf0\xda\x1bg\x83\xabo\xbc^W\xde\xdf\xbcup\xcby\xe3\xe2\xad\xde\xf9\xdd\xc1\xd5\x13\x83\xd3\xab\xb7v\xf7W\xfd\xb3\xb7\xf8\xce\xac\xbf\xbe\xb3\xe8\xaf\x9e\xbf\x16\xf7\xce\xef\x9f^\x1d\xc91\xf9\xab\xe7O\x85kW\xce\xcdz\x17V3\xf7\xc4\xd6ao>\x0b6\xb7/~\x87\xcf\xaf\x8f{\xa3k\xf1\xb5\xc3S\xb7z\xf3\x07c7\x9c;\xbd\xea\x9f\xcd\xaf\x1d\xce\x0d\xbd\x0b[\x87ko\xac\xcf\xba\xa3\xd3\xc9\xb5\xed9\xb3o\xfcDv\xab7\x7fj\xe4\\qso>\xd8\xf3\xce\x0fO\xf7\xb7W\x07\xbd\x91\x9b]}ck\xd6\xf5\xe7\x0eQ\xdb\x87W\xafl\xc5\xde\x1b\xeb\xb8\xdc\x1d\xef\xc2\xc5\xb13\xbf\x9b];\x7f\xee\x8es\xfe\xdc\xa1;:w\n\xd5\xdd\xbb\xfa\xc6zt\xf5\x8d\x8b\x87W\xdf\x08d\xfdb\xfc\xab\xb7\xd6wv\xe7\xc4\xffV\xfd\xb3\xa6-\x18\x93X\x93\x15\xb1&\x87\x9b\xdb\xabw\xd6K\xf5\xd6\xael\x0d\xdd\xf9\xe1\xd0\x0d/\x0e\xc5z]\xda\xb9:\xbbvk\xef\xce\xa5;W\x0f\xd6\x97/\x1d\\\xba\xf3\xfa\xfc\xfa\xf2\xca\xdc\xea\xf2\xee\xfc\xda\xad\xbd\x13\xebw\x06'.\xed\xbc~g\xfd\xce\xe0\xf0\xd2\xce\xa5\x93\xab\xb7N\xber\xf5\xca\xa9\xb8w\xe5\xdc\xec\xb5\xcb[\x87W\xaf\x9c\xbasmt\xfa\xb0\xb7}V\xae\x99s\xe5\xe2\x9cw\xfe\xf2\xc6\xd5+sb\x8dg\xdd\xd1\xb9\xdc\x9d\xbf6vG\xb3\xfe\xea\x85\xadS\xae\xc0\xa1\xf0\xe2\xd8;\x7fn\xf6\xda\xf6\xea\xe0\xea\xfc\xb9\xf4\xea\xec\xdc\xf8\x9a\xc4\xad\x83\xb87\xbau\xf9|\x90]{\xe3\xd2\xe9\xd5[\x8b\xdf\xb9\xb4\xbd:\xb8v\xe1\xb2\x98\xf3\x81{\xb8:\xb8:\xba\x1c:WN\x9e^\xbdu\xf6\x8eX\x0b\xc0\xab\xade\x81g\xde\xf2\xac\xef\\9\xb5w\xed\xca\xb5\xb87\n\xc4X\x8en.\x9d\x1e\xf6F\x81\xd8\x9f\xe0\xf2\x85\x8b\xc3^\xb8>\xea\x9d\xb8\x98m\xde\xda\x1f_\x9d\x0f\x0e\xaf\xce\x1f\x04\xe2oq\xe66\x07\xd1\x99\xd67D\"X\x8a\x82\xc0\x89Sx\xbab\xcd\x0f\xf7\xe4\x1f\xe0\xcb#\xff\\\x0d\xe3\x1c\xfe\xda\xe1\x07\xd9b\xc2!\x0d\xea\xd9<\xcb\"\xe0\x16[\xd2KX6\xa5\xfe+\xb3}\xcb\xb7{\xeb\x82\x11\xa5\xff51Ch\xcf\xecW\xac\xafS\xf6mF\x10G7f3i\xf4mF\x90T\x01H\xef\x81\x02\x10#\x88\xab\x00\x15#\x88\xf4\x13\xb7\x9b\xbf\xbf&\x87m\xdaqLx\xbd\xb10p\xab\x85!3\x16\x06\xae^L\x98}\x95\x85\xec\xbb\x8c\xbf\xca\xc2\xa3G;L\xc5\x0d\x17\x16\x86\x10\xa9\xe1jb\xd9tI\xa3U\xe9#G\xd0\xac:3\xb7\"?l\xb7X\xab3\x93%\xfe\xa8\x8dEg&\xb5\xfc2f\xd5wd\x96#\x9b\x14\nLl \x99R\xdbSb\x1c\xc9\xa8a\xa4|G\xdc\xe9(\x99\x05\x8a\x17\x12K]\xec+\x1aIPj\x0b\x9e\xdfE6\x85\xccj=\x98`9\x98\xd6j\xa0\x11\xa4\xd0\xd6\xebET\x95\x834\x0f\x82\xd4M\xb8\xed\x81)\xfd\x0bM\xc9\xfa2\x96\\q\xbc\xcb\xae\xb7\x8a\xf6e&\x9d<\x08j\xdf\x1e\x93\xc9\xec\x8cg\x8e[k\xf5\xe0 \x88B4\xaf\xad!\xed\x84\xd4J\xf7\x9d\xc1\x80'\xc7\\\x8dn2\xabN\xc8^c\xadcr(l\x81\xb5\xea\xbc\xc6\xa7\x1fG\x9b>3\xe97\x99e\xdc\xc0I\xd3u\xf9XZ\xdc\xf6g\xcc?+\xafj\x95\x7fw'\xbb>\xde\xe8Tb\xfd\xdb\xae\xc5\xceR\xa5\xde\x1e\xf1\x97\x1bE=?\xe0bI\xaa\xfb\x9c9\xbd\x80g\x0b\xacu\x0c\xfeB`\x8f\xa7{Y\x14\x0b\xb8\xfa\x13\x15\x08\x9cd \x9a=6\xf4JW\xb3\xafV\xe8A\xf0;J\x00\xbf\xdf\x1a%\x18\xfa^CV8\xa0\x01{\x9c\xc7K\x90\x8d\xb3\xa1=I\x0b\xf8\x0c\xa0\x93\xd0\x02\x01m\xba\xd2\x9bB\"\x88\xf8Sb\x05\xf1\xdb\x90DC\x0cE\x90\x8brw\xe2\xdf\xd0\xa2|\xabQ!\"k\x19\x94c-\xd9b\x8b< k\x86%\x93\xf1\xbe\xf4\x12;\x12NAe\xc0\xb6*C\xe8\x9b\xa9\xcc\xf5\x1a{\xb6\xe1\xd89\xf3C\xe65\xbb>z(\xedG;\xefL\xd2\xf6\xf5u\x83W\x1b\xec\xa4\x7f\xa2\x83\x1c\x1e\x0d2F\xdc)L :\xc8\xa9\xa85\xb1'\xa6z\x0b\xd8w\xd9\xdc4}0\x99\xd4Q\xbe\xe5\xd2\n\xa3\x90\x0b\x02=mT\xad\xa0\xea~\x98O\x91hob =\x84^\x10\xb9{0\x86\xae\xf9\xe8F\xc11\xf9(\xa5\xfc\xde\xd8\xd6\xf3\xda%t\x0cW\x8c\x0c%\xd7K\\\xc1\\\xca8u\x88=\x11\x97\xbf0\xa7J\xb3\xc3\xa0\xf6yl\xfd\xf3\xfc4\x0e\x9c\xc3\x05\xe9}\xacv\xd1\xf2nG\xf9\xd7`9+1\xc7\x9a\x14J/\x86\x19v\x8d\xc2\xf3;\xb6\xf3\xe2\xd8\xce$T\xf4\xfc\xb1\x1d\x0dK|jZ\xc9\xa9\xa8R\x16\xa1Z\xfb\x89\x13\xc7<\xa9u\xd2{!\xd8S\x1c\xc4vI\x85\xfe\x1d&}}\x98\xd4\x93\x8b\xfeU#\x93\xea\xe5+\xc5\xa5\x8e\xfe&\x98?\xcd\x91Y\x1af\xabF|.\x19t\xeaQp\xd2\x82f\xfc s\x12\xee\xb4*\xb7\xec2\xb5\x936\x1d}\xf1\xc6}\xd1\x02j\xb9r\x86\x8c\xa1j\xaa3Tw\xa1Ws\x80(\xdb\xd4\xe6\xab/z\xb0dV6(-\xc7b\xe9b\x08\x85lo\x81\xeb\xe8\xcc\xba\x17 \xd4jB\x00\xa7<02\x15&\xfc\xb5\xc0\xf8\xcc(\x0f2?\x96V\xa7\xeb\xad\x96\xf4\x0bo\x89S \xaf\xf6j\xb3\xac\xaa\xa3\x17Q\xa4\xedZ/~\xf5\xef\x1bC\x13\x9e_\xa9Q\x0f\x0d^\x16\x1d4\x14\x06\xedF\xafj}\xb9\xa4hte\x14g\x87\xb2\xdd\xfa\xe2\x91\x1e\xab\xdc\x17\xd8?\xf9<\x12{\xcd\xfe\xbd-\xb3u!\xc8\x17\x15\xfa\xc4\x81jt\x0f)Q\x16+\xf9\xab\xad\xa8\x17\xaa1\xab\xac\xc6\xb6\x86\xe5 \x97\x86N8\xe0\xc6?\x05\xfei-/P\x94\xbdV?\xdd(V\"n\xfdt\xd5\x80Z\xf6d\xd6w\xbb\xacu\xecX\xab\xa3DWA\xf6\xaaq\xca\xd3\x054|\x99\x012}R\x1a\xa2 Y1\x91m\x999\xb7)}\xfd\xddnQ\xe8\xb7\xc9\xc2\n|92\x87\xac\xfe\xd5\xa3T\xbd\xd7\xa8\xda\xab\x86\x93BM\xcb\xd4\x81\x9e\x99\n\x8a\x95\x9b\x9a\x18\xf2\xc9'\x91\x1a\x08\x9e\xd6m7\x93\x83p\n*\xe3K\xab\x02\x84\xd7+N3\x939\xc9\x80g3\x80Ei\x83\xf3\xb43\xe1\xa5\x1b\x01\x8f\xd8k\xcc\x9f\xce\xd0\xaf\x7f\xc6\xb7\x06\xe8\n\xb7\xfb\x91\xdd}\x9e\xe0~\xd3\xa4\xc4\xe7\x9a\xf6\x04=\xd4\x93\x97\xe5\xba\x103\x04\x81!\x13\x0f\xbbS\xd3l\x17\xdc\x1a\x12[\x88>\xc2\xff\xeaR\x8f\x85\xd0`.\xd8\x9a':A\xe8g\xbfe\xc1\x9f\x91\xb9\xb2\x17\xc2\xec\xd9d\x86\xcf\x9e\x83\xe9\xb3)\x88\xab\xf3e\xf4\x00\xe8 X`\xad0\x8ab\x1e\xf2\x84\x85Q\xc2\xfb\x9fCe\xd5e\xb0\xce\xb6\xd1\x8c\x98c\xf3\x04\x9d;\xf4\x03/\xe1\x96\x90\xeeIK\x0e\x9a\xbc}U'\x9a\x8d\x86\xdc\x1f\x0c\xe5c\x13ymR\x18\xf1\xebE\x89\xc7\x93\x05eUj\x10H\x9cd\xe0\x87\x0b\xac\xe1\xa1\x92\xd8\xf1\x95\xfa\xf2O\xc9\x04\xb0\x1ee\x8b\xa1?r2\xee} \xc9_\xdfN\x17'\xccO7\xc4Y\xf5\x1a\x84\xc2\xb1\x8e\x19,\x1fL\x85\xf0\x82\xb1\xd4\xe2v\x18\xa5n\xe2\xc7\x99\xbe\x00\x98@6\xef\xda\xce\xc1oO\xe5Q\xab=I\xdb\xd1\x0b8I\xdb\xa9'\x11\xac\xb41\xec5p:\x0e\x95\x8f1,\xfc\xc4\x9dI:F\xe3!\xe8by\xb3\xe3\xc5\x8b\xa6z\x15,\xa2\xa9\x1a\xc6\x82v\x00d\xec\x9b\xe1\xffK\x9dp\xbcZ'\x1c\xcf\xe6j\xe3\xeb*6\x1f\x1c\xcf\xe6j\x93+\x8057\xa2gs\xb5 \x14\x80\xe4\xecw\x15\xe0\xf4+\xa71\xa8\xaf@sd`\xb1\x86\xd8\xfdt\xbc\xaf\xc7OG\xffE\xb4\x91\xe7\xa5\xf5E\xfcQ\xd2\xb5\xa5 \xc1d\xbc\xd6\x8c5!\xee(\xa8\xc4\x1d\xb9\xe0\x15\xe4B\xdc\x91{\xf4h\x87\x05\xd7\xdd\xaaW\x90k\xb9\xe0SK)\xa8\x866\x99\xe5\x84\x11\x81\xdf\x19aF\x115\x9b\xd5\xc5\x1c\x052\xe6(\x99\x19\xf0\xecR\xe4\xf1@HO\x13E\xec\xd2\xf8\x94\x17?7^\xfc\xad\xdf;^z\x15\xfbxKf\x93+2\x87\xfd\xe1\xcc\x1f\xfc\xde\x0f\xca%~p\xfcx\x97\xb5\xa4\x05\xc0\xd6\x96k\xd2\xd8\x1eO\xdd!\x1f9\xa4\xc9\x9aB\xbaQ\xd0\xca\xc8\x14\xee\xaaIo\xf1\xfe\xb6\xac\xf2<\x93N\x14[\xab\xbc\xbf;\xd3\xf7C\xafx\xde\xdbf!\xb8\xdb\x85\x9c\x14\x84\xa1'\xc4 \xa5V8H\xad\xc2\x81\xf3<\xc2\xc1\xd7\xca\x18Uj!\xb9=\xcdJ:\x9f\x98\xff\x94)2\xca\xa7}\xf9\xd8\x81\xc2r\x83\xebK\xe5\xb2T\xc2o\xe7~\xd2\xc4\x99SY.l4\xd2\xb9\x8a\xcbo\xf1~}\xa1\xbe\x99\xc3f\xeds\xf9L\x11`>\xa3nz\x9b\x8d\x832\x8dd\xbb\x05\xecN\x9e\xe4V\x83\xb9b\x08\xa5%\x95\x9aXx\x0c\x857\x13\x7f\xe4g\xfe\x98O\xac0bgX+\x92#i\xd0\x1e\x06\x82\x04\xc2\xab\x902)\xd0\xef\xff~\xc2\xfbuna2 \xa9|\xccx\x00\xe1\x0f\x1a\x07\xcbt\xab=\x10\xb4\xec\x88S\x14sJ\xc5\xccIo\xa7P\xcc\xb8\xa3\x04\xb5\xd6\xdcI\xa1~\xe5[\xa2\x91\x18\x06\x93\xff\x7f,\xf3\xb3\x80\xd7Z<_`\x7f\xd0\xd3\xcd\x9b\x19?\xc8j\xfb\x8b\x05_\x10\xbc\xa8\xb6c\x7f4h\xec7M\xdc\x05\x16\xb6O\xce\xcd5!\x95V/\xe7g\xe3\x83\x86\x8d\xdf\xf7\xbdl8\xb9\xd8Du\x96\x19\x15t\x8d\xf7E\xbfs|4\xe9\xa5=\x95\xbcL\x92\xc2\xc0\x11\xd8<\xa1F/\xca\xb2h\xb4\xc0Zb\xb0\xb5%k\xe2_\xea\\G\x04\x15=\x94\x89\x1a\xfctcq\xfbD\xbbS:\x07\x1e\x8f\x13\xeeJ\xcd\xad\xa6z\xba\xef\xcbL\x84\xae1:J\xbe\xe9\n\xa5\x8c-\xb0#G\x06]y\x06\xcb\xa7+;\x8c9\xbc\x997j2\xf9\xb8N\xca\xcd\xd9]h\\\x99 \x87\xc7\xa3\xb6\xa1\xc6\xe6\x18Bo5\x86\xc6:\xcfelb*\xc0N\x90\xdc\x05\xd6@\x9d\xf5\xaf\xe0F\x8d\xf7)\xfa\x07\\\xa6\xf1\xa12\xfd\x0b\xe5\x14\xa7xL\xbf\xc0\x85\x05v8\xb9\xb8d;\x0b\xccm^\xb4\xa6\xcc\xb1\xb0\xff\x8e\xe0\x0b_n\xfb\x87_r\xfba\x08/v\xf7\xff\xf1m\xa8\x96I\xea\x1e\x8b\xd3\xbf)\xf6T\xbd\xf8X\xbf\xa9P,\xccG=\x9eL,\xe6\x87\x19\x1fLQ\xae\x17E\x01w\xc2\x86rZ\x03\xfc2\xc86\xfe\x92vh\xa6\x91C\xc9\xa9\x13\xef\x02\xd9\x7f\xe9\xd8d\x85O\x8c\xe7\xac\xb5\x0c\x95\xb0s(\xb7d\xe70\xe6\xd4,\xa4\xd7\xa8o\xf6YZ\xa2\xb9w\xc9\x89\xa5Lm\x93\xd0\xab\x1b\x17\x9b\xaaB\x97i\xae\xa46o\xca*\x15\x95\xa3\\\x0b8Um=\xd8\xcd\xa28\x1c\xc4j\x99\x92\x88?\xa9\xa8\xa2\xf1E!q\xc4\xaaE\x8a}n*\xc5\x0fbG(\xac\xb1`\x87EA \x00hx\xd3\x14*\xf1VS.\xf0\xd3\xf2\xc2\x14\xa8Q\x8d\xa6\x87L\xa5\xbf]\xfb\x9e\x18Q\xea\x08\xdd\xfd\x8e\x0c\x90\n\xa8\xc1/\xb7Y\xd6\x84\xe6\xda\xce\xc1J\xd6\x95EN\xce\x9d\xea\xd8\x8c\x7f\xb2\xd0\xec)\xab\xfdO\xc2\xe6N\xd8\x0dm\xf9\xd7kh36\xb0\x19\xc7\xf3.D\xd1^\xbb\xd5\xe3\xfd(\xe1\xdbjy\x14\xd9M\x1b\xd3:\x9a{\xe6a\xc2\xfb0\xcc\x94g\x8bY\x96\xf8\xbd<\xe3m!\x80\xb7\xba\xf6\xdb\xbfN\xb74LlzM\xa7q\x89;\xfe\x87\xd7\x17\x8f]\xfbA:{\xec\xf4\x91\xd7~0s\xe3\xe8\xef\x1f\x1f\xa8d\xc5Ug8\xba\xda\xf5i\x98\x8a\x85\xd1\x88\"\xf0\x94\xae\xf5\xe2\xf2\xf2\xcd\xc5\x9d\x9d\xad\x05v\xbd\x05\x97\xe8\xadj\x86P\x92\xda\x82\xd5\xe6c\xc2C).\x11\xd3(O\\\x8bE\x00\xee\x19\x1a\xfc\x89\xfcBm8s\x06\xee\x0eZ\xd2w\xbc*B\x08\x95;mgE\xd6\xe6\xa4N{\xac\xbb\x94\xach\xabN\xb2\xe7E\xfbaU\xa4\xbbK\x0d\xac\x10\xbbq\x86\x85|\xbf\xb0c\xd6\x08\x8f\xc3l\x14\x88clg}\xd9a\x1c\x0d\x12'\x1e\xf2\xa4\xbeP/\xe1\xce^Z\x0f\x0f\xfcp\xcf\xef\x1f6\x17\xd8\x91\x9b\xbc\xc0Z7{\x81\x13\xeeY\xd2\xa8w\xd4EK;\xb3(\xd0\xae\xcc\x12\x96\xa3\x850w\xff\xafI\x15\x05\xf8\x9fq\x8d\x91\xe3\x8aa\x7fJ\x86\xa6\x01\x04\xb1FN \xd6\xeb\xd9Gx\xd7\x17/m.\xb0\xd6K\xa4|l\xf9\xba\x18J\xccy\xfc\xe7\xb84|\xbf\xf7!\xfd\xae@\x8f\x7fNA\x00\xf8K\nH\x83H>)\xf1\xec\xf1_P\xe0X\x02\xfe\x1b\x02\x90\xb3\xbbGvDz\xa6\xb6\x9e=z\x9f\x02d\x94\xac\xb5\xca(\x85\xf9`,\x02\x90\xe3\xc8\x16?\xb2\x03{\x12\xf8\xd8\x0e\x94\x07\xf2\xd1\x13;P\xf6\xf9\xe8\xa9\x1d\x08\xb3\xf8\x1b;P\xe2\xfc\xa3\x7fm\x07\xca\x85y\xf4?\xda\x81\x12#\x1f\xfd\x1b\nL2\xb9\x02\xbf\xb2A\xc6r\x8e\x0f\x08]\x01\x18L\xe3\xaf(0\x05\xfc\xbfGhE8HEo\x9f\xfc\x84\x02\xee8\x89\xc0\xe7g\xff\xfc?`T\x8c\x06\xd2\xee\xfa)9\xd0\x1a\x80[[\x8c\xe2>\x1c\xf5\x7fO\xaa(\xc8\xcf\xff%\x86\x88S\xf0\xec\xfe=\xf2Y\x10>\x89\x88d\xe9bID\x1fcJ\xe6\x00F\xdf\x7f@\xbe\xfbr\xc1\xee?$\x80(]`\xado\xe3Y\xc4qpxN1#+\xa9s\xe28\x89\x0ej\xc6-@\xfc\xb6u$\x8b\x89\xf4\xac\xb2l\x83\x06|\x80k\xa4.\x10\xcf\x7fI\x0e\xb1\x81\xfco\xa4N\xea\x0f\xe4\xc0\xef\xff\x8cT\x12X\xf0\x07\xe4\xeb\xe1\xa8f\x17\x04DM\xe6\x9f\xe3n2?\xf0$\x8d&L\xd1@\xfe\x07\\'\x17\x02G\xeb\x13\x82Q\xea;!!\xfbn\x14\xfa!\x1c\x14\xcc2\x9d}\x05\xf9\x08S\xf5\x9e\xe3\xee\xb9\x11\xd0\xab\xfb\xefZ\x80Z\xcf\xee\xbdG\xa0\x89\xa4\xbaO1}\xef9\xc9\x98\xcb\xb1<\xc0\xfd\x9du\x92}.1\xfb]\xcc\xbb{\x05\x08\xa3\x1a\x80\x80dS`/\xd9\x13\x80?%\xf3\xee%{\x99\x06\x92%\xab]\xeb\xb3 s\x90\xfd\x81\xcf\x98\xe7\xf6\xbc\xdby$\x97\x1dK\n=\xee:y*W\x0e\x8f\xec\xac\x04q+\xac\xd7\x08\x1b\xc5\xd9\xa1\\\xf4G\x98\x92\xf4\x04~X\x91\x83'a\x94\x8b:oc>qV\x82\x82\xc0Ok\xc0\x99\x9430\xf9\xeb\xa9\xef\xff\x0b\xfd\x0e\xa2\x0c\x1dB\xb6\xcf9\x1co\xd2\x89\x96\xb4\xc8\xbej\x00f6=\x7f\xe0\x02\x05~\x88\x05O\x01\x02\xd1\xf3\xd9/0 \x16\xb0\x1c\xaa\xe1\xc3\xdf\xf3\x07\x91\x17\xc1\xb9\xc4\xb2\x93\x80\xc5\x01l\xe4GX~\x12\xc0\xcc\x1fq\x80ZF\x93\xdeV}~D\xd0\xdd\x1f\xa4\x99#\xb9\xc5_\x90\xa9\xfb\x83,\xf1\xa5,\"\xf4&Q\xe6=rr\x8b2\xd0\xc3{\x98\xd6\xf4\xfcAnF\x8e\xa9W\xcf\x1f\xa83\xfa\xd02)s\xda\x1e\x92\xe5\xd8s\x92h_\x80\xde\xc7\xd4\xa2\x178\xee^\x10\xdd\xe1J\xb8\xfa\x10\xcb,\xb2@z;w\x12 \x7f\x0f\x0b<\x12\xae'%K`5\xa1R\xc2,\x0d\x968*\xa5\x02\xb8\xb5}\xf6\x0b\xb2;\xe5R\x89\xbaT~\xf6\x1e\x96\x02\xa4\xae- \xff\x023\x86^\xb077/\xeb\x90\x03\x12\xec\xcd\x9d\x94\x10BE\x82\xbd\x13\x00\xc1\xc2\xb2LO !\x98\xa1\xf5B\xb1\x18g\x9e\xfd\x183\xda^\xc8o\xe7\xbe$\x07\xf7\xff\xda\x02^\x07\x94~\x8a%\xc0^\x08\x80w\xb1\xbau\xd6\xc8B\xff\x07\xaebd!2nh\xeb\x01\xe9]_i\xdb@\xfb\x99\x0f\xe8E\xe6\x1a\x1d\xf4@J\xf9\xf0>\x05-\xaf \xc8\xcf\x7fa\x81\x04\x12\x82YT/:\xf0\xa0\x0eV4\x04D\xd6\xf9\x19^\x04\xd1\xda\x96\xac\x83%\x11\x01\x91\x07\xd6\xb2\x08\x07\x1e\xd4!\xa8\x10\x1dx\xb2\xce\xcf\x08O\x8f\x0e.\xc8*\x96\x01H2\xfa3r\xf6\xa2\x83\x0b\xcb\xb2\nVo\x05D\xb2\xce\x9fciD4\x06u\xe8.\x1c\x0ce\x9d\x9fa\x92,Z\xdb\x95u\xb0\xbe\" \x92\x95\xfc\x9c\xf0\xfc\xe8`\x08u\xb0\x02$ \xb2\xce\xcf\xc8i\x8e\x0eF~\x08\x04\xea\x01\xa1\xf2\xd1\x81&^\x0f\x08k\x8d\x0e\x0c\xd5}\x80\x15\xb5^t\xb0\x0b{\x8e\x95\x0d\x01\x01<\xc1\x82i/:\xc8\xa1\xce\x7fk\x81\x00\x9e`\xa5S\xb4\x06{\x8e\xb5N\x01\x01<\xf9\xa5\xa55\xa8ci-\x07<\xb1`\xddeY\x85\xd0\x92\xe8@\x9e\xfd\x9f\x11\xca\x16\x1d\\\x06\xd4\xb2\xec\xece\x89[?'\xb49:\x18C\x1dB\x95\xa3\x831\xe0#V\xb6Dk\xb0j\x844F\x07\x97a\xa5\xb1V'Z\x83:XA\x11\x10Xi\x0b\x0e_\x86U\xb3\xec\xf5eXi\x0b\xfa\x8c\xa1\x8e\x05y\xc6\xb0\xd2\x04\x0b\xeae\xe8\xb3\xca\x98\xf6k\xb2o\xf5\x80qO\xb2\xf7\x8f\xf1a=\x0bZ\x10\x95\xb7zF=\xfa\xdf \x84\x8f\x84p\xf7\xec\xad?#\x90:\xc9>Us!R}/\x8d\xc4:\xff\xe0\x07\x96\xefR\x85\xff\x90\xc8#i\x14\x0c\xd3\\\x02\x7fEHv\x1e\xc8m{\x93lu\x1e@j1\x1bH)o\x7fj\x01HM\xf9 \xb6L\x08\x08\xe8\xcax \xce\xe6F\xdf\xb35\xa7@\xb8\xd6\x92\xb6E~\x8a%3\xd7@~J\xea\x80\xfc\x88\x89\xbc\x12G\xefar\xe9:\xb16ta\xf9\xcbu\xe2^\xa2d\xc3\xc7\x98\xd5\xb9N\xac\x9a|\x8c\xf5\x7f\x01R\xb5\xf0\xe8\\'VB\xecc\xcc9\x96\x9c\xd8\xcf\x9c`\xd9\xef\xf7y\xc2\xc3\xccw\x02\xc9\x14~\x82w\xdaubPY\x1e\xff\xe7\x7f\x8f\x1bq\x9d\x04\xb6\xf3-,1\xbaN\"\x15\xd3_\xd3\x05;\x0c\xf8!h\x17X\nqu_\x8f1\x82.\xe9\xf6>\xc5<\xd35\x10Z\x87{\xbe\xd4\xc7\xc9\xb2\x18\x08\xe6YKJW\xf8\x14\xa3\xb4\xab\x01xc\x96J\xaa=V\xc0\\7W\xf3\xa1\xa3\xce\xe34\x95\xc7\xf41f\xf6K\xb0e\x9fb\xb3\x8b\xab\xbe\x93\xfdW\x93\xf9\x18\xcb\xa9K\x02\x1086\x90[R\x1b\xb1\xce\xe6J\x7f\x86\xd6\xc7\xf8\x84.\xf10\xe3\xc9\xb2\x1c\xc4\xc7\x98\x1c\xb9\x12\xe8\xd9\x81K\xfd\xc4\xbe\xdfZ\x9f\xc3D|\xe9\x02\xa8\xd6x{\xdc\xa1\xfc\xfe\x0fdC\x87\x1c$\xe5\xbf\xc4b\x98\x84\x8c\x9c\xc4\x0e]\x1a\n\x12\xfa9\xedF\xaa\xcd\xa4\x17\xb0\xe4\xfd\x82l\x00\xa0\xc6\xaf \xd5\xf0\x13W\x91\x1a,\x9f\nP\xc0\x9d$\x89\xf6\xb56\xf2\xce\xffY_\xc6\xe8\"\xef\xfc_\xd6B\x1eX\xc4\x9e=\xc0\xb2\x8a\x02k\x0d\xf8\x01\x96K\x14\xdcS\x06\x9d\x07X>Z\x92\xf0e%\xd0c\xd9E\xd5\x16L\xf5cL\x9c\x15l[T\xfcs|\x9a\xa0\xd9KF\xd2\xc3B:\xc07\xb5\xb0\x87%u\x00\xef\x18y\xcf\xb2\xba\x92c|\x88\xb5z\xd7\x07=\xd3\xb6\x1f}}\x8c?\xc2\x07\xd2\xf5\x93\x11\xd8^\x9fb\x0b\x82\xeb'\xa9B\x8b\x0f\xb1\xcc\xb5$\xd4\xb7}?\xe5KQ\x98Ey\xb2\x1af|\x908\x923\xde\xc3\x87n)\x88R\xbe\x94'\xc1\xe1r\x94\xf7\x02\xfez\x1ee w\x90-1%\x8b2dc\x82\xbc'\x97\xe6\x97X\x0c\x93\x90\xdc\xcf\xac\xc0\xa5\x08\xac\x89\xcf\xee\x91\xe3\xad \x0b\xb6\x1ap\x03\x83Ey\xd7\x80\x88\xfd\x16@\xb7k`\xa3\x91 Y]\xdbw1\xec\xff\x8a\x02\x80\xd5\x12\x16\x14\x8d\xe2>L\x07Kb\xae|\x19a\xc4\x15\xdd\xb6\xd5\x0c\xf8\x01`\xd7\xdbx_\x8d\x99\x90p\xca(\x1chv\x8bI\xddR\x14\x0e\x92\\ux\x1f\x0b\xbaK\x05\x0f!\x18V\x80\xf0\x11\xb3\xe1\x15-#\xb5t\xdb,\xb4\xfaNw N\"\xb8\xd6\"\xacI\x82r7\xb3C76\xaf\nR@d\x9e(>\xac\xfb\x9e\x02g\xc0\xe7q)\xca\x05?i%\xa2e\xa6\x90\xec!\x99M\xee9I\"W\xe7}26 \x93\xeb\xf3>^\x1f7\xe7\xb1\x84<$s\xcdy*9\xc7C\xacM\xb9y\xa0\x97\x1b\xdbv\x01$\xa7\xf5>\xd6A\x96\x94\xbd\x95\xf0i\xf8~\x0f\xab\x9an.\x84b%\xf9\x126\x92\xc7J\xfe&\xd7:nn\xe4e\xc2\x96s#/\x13\x11+\xd7\xf2\xf2\x03K\x83\x11\\\xe4\x91c\xaf\x84\xbc{O,\x02rn\x90\x92\x90T \x92\"\xe0\xfbX\x8dv\x05y\xe7\xb7\xe3\x84\xbb5\xdb\"\xe1i\xee\xd6mN\x12\x1cjc.\xd6\x80$\xb00\xe7\x12\\\xcd\x93D\x1a\xe6?\xc6J\xb7\x9b'c$\xb3\xd0\xad\xd7E\n\x91\x85N\xbc~d\xea\xba\x87\x0e\xaa|\x83F\x04V}\x83v\x0f_\xc5\xb8\x87\x81\x9b \xda\xf3\xec]L\x90\x97e\xaep\x01z\x13Sc\xaf\x00a\xc1\xd4s\x02}\xa3\x81\x0f\xd8\xb2\xdeh\xd2\xdc\"\x00~\x8aq\xde\xd35(\x00\xc4\xb171QXv\xd2!\\\xb0\xe1\xbd\xf14\xe4\x01f\xea^\xc9>\x8f\x97\xd5\xeb\x05\xd2\xd3\xe0\xd7X\xc8X6Z\x15\xde#\xcf@pc\xcb \xb3cv\xe2\xc1g,\x1e,\xdb\xb5M\xf0\xf5\xf8 >\xb3\x9e\xd7\xb0]z\x1d\x7f\x8a\x8f\xf3\xf2r\x94%\x0e\x984\xdf\xc7\x94\xd7\xf3\xa2,\x05!\xe41FQ\x8f\x0b\x0e\xff1\xd6\xe7\x969p\x1e\xac\x18,\xf3\x00\xae\xbf\xc8\xdc5\x00\xcf\xde+\xe9_\x18i\xbd\xbe\x9f\xc2\xd1\xf9\x00\xbb\xe0,k\x85 \x8f\xc0\xd3\x00\xb28\x17\xe0B\xe9\x03l\xeb\xf5\x86\x0ep\x8a\x9fb!Y@`=\xb1\xcc\xb0\xec;n\xe2g\xbe\xeb\x04\x8bun[\xa52\xa06\xfc\x1a\x0b\xa7\x95\x12B\xd6\xd5mQ,,J\x9eW\x9eT?\xac/\xb2\xa3\xae\xeb\x7f\x8d\x8dx\x9e\xefH2\xfb\x10[\\\x96}g\x14\x815\x86\xc0\xbc\xc90#Gcs\x9e\x80\xa75\x10\xb9h\xd8 N\xad0\xe4\x00\xf8\x03\x07\x04\xe3\xdf\xe0U\xf2\xfc\xd4\x97b\xeeCL\x18=y\x13\xf4 \xc1n\x7f\xec\x83c\x83\x1d\x12\x85\xc6\x94\xfe\x90 \x9a?\x8e\xc2\x03+h\xf9\"\x9ct\x8c5\xde-P\xda\xb1\x1c\xe3\x05n\x94\xc8\x81\xbf\x8b\xf9\x9b\x17\xb8\x89|b\xe0\xd9\xbb\x98\x0f{Q\x10H\x94\xfe}\xdc\xbd\xb9\xa9\xc2:\xb2gD]\xacH*c\x06\xde\x0e\xaf\x06q\xa3Li\xc2?&(\x16eJ\x9f\xc1$[B\x94Pq\x1f\xd3\xa0\xe5([\xb9\x9d\x83>8+:f\x01S\x0c\xae\x01\xd8Z\xc1\xb5\x9d\xf4\xd9}\x8c\x1f+\xb0hX\x0d\xe5\xb0fX\xca\xe1\xcbJ\xd2 \xaa\xc9\x8a\xba\x05\xc2\x83\xd5Fz\"cpU\x01\x1fR8\x9f?\xc1R\x1c\xef\xeb\x860cZ\xd1:\x066\xc3p\x0d\xc07FR\x8bz\xf6\x04o\xc5\x8a \x8b -\x19\x08fy| \x89\xf7\x132\xedA\xaa\x8e\xca\x13l\xe4\x05e\xed \x96\xe2VJ\x86_\xd2\x7f\xe0\x87\x19OdW\x7f\x86 \x13\x87K\xed\xb71\x93\xe2\x01\x0c\x0d\xef8\x0f\xcc\xd0\xf0\xda\xaf\xe8\xe8\x0b\xbc\xc6\\\x03H'B_\x94c\xc6\x04IBR\xb8\x86%@\x99ky{\xe4\x04\xc1\xb6\x91\x08\x7f\x81\xe5\xe3B\x17\xb5\xd7\xbf\xcc\x13\xdc\xc6{\xd8Y\x84\x8fRI{\xdf\xc4\x9cS\x00\xe6NH\x10V\xa3$H\xba\xbe\xbdI\xfa]?\xbf\xc0Z\x9f\x91\x83'-\xef\x9f\xe1\x0b8\x1e\xaa\xce1G^\xd1.\xfe\x0474\x80`\x87\xd1\"\xb0M\x8e\x1b-\x82\xe0`\x0cT\xf4!\xc1\x80\xd8IR\xe0\n\xd8*\xc3\xb5\xf4\xfe\x18Sx\xe5\xb4\xfb9&\xd6+\xc6\xd9\xfbs\xda\x8f\x01\xe1Z\x02$\xb6\xf67\x04p[_\n\x12\xba\xc7o\xd7\x931~[y\x97\xdc\xc7k\xcdo\xa7\x81\x13f\x83,\xb1\x1fT\x00\x07<\xb5\x9f\x16\xa3\x07=\xa6#\xcd\x1dy\xc4\xce\xd8\xaah\xad\xdf6\xa0\x9c\xc3\xb5\xe8}\xcc\x92Vn\xe7~\xe0\xf7\x12?\x97s\xf9)\x16\x18JN\x946\x08\xd8\xae\x1ec\xa5\x81\xdf\x1e\x17\x1b\x8e\xa5h\xaeY\xe0\x07d\xc3\x13Mq\xf1\xa1_\xd1nA\xd8\x10\xc55\x00\xf3m\xaeI\x0e\xd1&W\xd4\xbe=\xc6\xd7&\xbcnCW\xc0tE\xf8\x06|&|i\xe7\x82\xa0\xdb\xb8[\xb0\x96~\x82'\xb0\xa2\"%\xc8IV\xdf y\xc9\x13\xe9R\xff'\xd8A\x8a\x1f\xb8\xa2\xc2\x11\xf2\xd9\x87\xad\xbf\x87\xe9\xd1\x8a\x80\xa4V\x10?\x88\xb9\x9b9:^\x86\xac\xfa\xca\x01${\xf0\x9d@^/S\xdeY\x14\xb03\xd7\xbe\x13\x04\xbe\xbc$T\x96G\xc2d\xcf\x81\x98\x80\xa5\xe6>\x88 \x98\x82\xf6\xf9Hu\xf5K|\xf3\xd0\xef\xfb\x10\xf8\xf8\x9f\xff\x06\xcf\xb3\xdf\xd7\x10Z)\xd0 \xdc\xd59\xcd\xe4\xb1\x9c\xd6\xd7\x00L\xe2\x8a\x01`5\xe2\x9c\x1f\x04\xdc\xc3l \x13\\(ec>X\xec\xea\xdf\x82\x9e\xfa\xb70 p\xc0B\x87\xc5\xaeb\x9e\x18\xeb\xfbA\x16J\xf4x\x0f\x9f\xd3~\x18 \x06\xf0\x9f\xc8\x96\x19\x96\x81\xf5\xb3\xbea\x19\xf8\x10\x9d\x8b\x92E\x10'\xee\x91=\x88\x12\xa7\x1e$\xfdX\x1eb\xc3\x87\x00\xc0\xbd\x00\xe6g\xe7\xa2<\xf1y\x92%p\x0bL\xe6\x14;I\xa6\xfd\x1e\xb0\x10\xdaO\x1cW\xba\xb3\x7fL&& \x92\xa9\xff\x04\xd3, \x12L\xfdc\xbc\x9f\x12rJV\xc2\xc4_\x82^\x96 <\x01 zE\x82\xb0\xe0.@\xf30\n\xb2 \x02\x04}aF$@\xd2\xe1\xfec\xac(I\x08T\xc2\xfb%A0\nl\xfa\x13\xa0\x93P\x0bK\x19\x02t\n\xa6\x85e` \x82\x06\xb1=W\x80\xbe\x03 l\x13\xe8'\x0e\xb0\x97\xb7\x08%HT\xe8\xc3\xbbX\x08?\xa7y\x05\xd9{\xa3\xfbb\x81p\xa0U\xaf\xff\x07\xf3\xe2\xf3\xca\x08\xfd9\xdevm\x9d\xfe\x1c\xb3\x17Y\xc3\x13\x12\x08^\xb8\x81\x81\xe0\x15\x18\xc0\xcd\xed\x13l\x970\xa2\xc9\x13L\xd6\x00$\xf9\xfb\x13L\x8e\x15\x0c\xe6\x8a\x91~\xc0S5Yz\xf3.`0\xc8'\x988\x9c\xd7\x1c\x0b\xab\x17\x03\x0d\xc0\xec\xf7\xbcTd\x1fb\xda4\x00? ,\xac\x0c\x065\xc5\xfd\x11l\xce\xdbXx:\xaf\xaeN0\xa7\x1e\xa8\xab\x13\x82qpc\x80\x9b\x19Hg\xcfgO\xc8\x1e\x83\xbc\xf2\x04s\xaeApK~\xc7\xd3\x1d\x84\xea\x00\x92\x05\n\x8b\x98a\x0b\x10\x10\x98\xec\xc5\x9ckud]\x96U}\xaf\x82\xcf\xb4\xaf\x01X\xc6\xf0G\x0eh^\xb6\xb6\x06~\xe8$\x87\xab\xf6\xd5\x199\x83@\x9d\xe8\xb71j\x0b`\xec@\xca$\xbaw#\x99\xc5\xb4\xf5)\xd6\xd4\xfd\x91\xb4<={\x80Y\xb8?\x8a\xa5\xc3\xec\x7f\xc2\xf8\xb4:\x8a\x03\x1f\xd4\x1f\xe2`\xe2\x87l\xc1v\xf9\xe5\x87\xae2\xb0\xbd\x8d\xafc\xcc\xde\xdd\xc3\x8a\xb7\x84\xa8\xd0\xfd\x0f\xb1\xbe\xec\x87*\x87\x06\x99\xd1\xaa\xc2\x12\x82q\xea;\xd9\x8d0s\x81\xc6<\xc0B\x9c\xca\x08\x0d\xb1\x1a\x98\x81V\x9c\x97,\x8d\xf2\xa4\xae\xd9Uy\x11\xc8M\xf6$\x92X\xc4\x0f\xb3\xc0I\x86\xd2 \xf7\x11\x16\xda\xfc0\xd3A\x14\x1fa!q5\x1c\xfb\xa9/\x1d\xac\xc0fb![\xba\x88\x89qz\x0bK\xe5\xab\x1b@I\xb0m\xd5\x8f@\xf4!X\xabo\xbc0\xc1\xf35\x00\xdf%\xac\x1a\xae\x86\xf9\x92o \xd8\xac\xb5\n'\xf9s\xcc\x07\xd5 \xff\x1c\x0b\x16~\xed*\xf9Z\xca\xfe\x18\xb3\xf9U\xcd\x15\xc9\xe12\\\x11k?\xdaC\x92\xe2|\xea\x87Z\xf0&49\xf5A\xc8}HF\x9d\xfa`#~\x88\xbd_%DZb\x1fb\xca$@c\xfb 2\xfb\x0e\xeb\xfcS\x9f\xe2\xcbp\xdf@\x08\xc1\xcc\xf7\x00-\xb0\xee\xe1+\xc0?`s\xe8\xaa\xbaq\xc1\xac\xdbW\xdf1V\\\xd4\")\x9e\xfa-\x0d\xc0\xeb\xa8l\x1b\x18%\xc0\xb4\xf1\xf7xm/j\x06\x86y\xff-\x0d\xc02\xca-E6\xff_L\x1d/\x1a4\xc5\x87\xe4\x96\x81`}\xea\xa2\xc1!,\x94\xde2\x10\x8c\x90\x17S\x9e\xc0d\xf0\xce\xde\xd2\x90\x7f\xc0\xf2\xc4E\xbdQ\xd8\xa6uKo\x14\xe6\xf8\xdfw\xe2X\x9e!|\xe6\xf64\x00\x930 \x90\x97\xbfX<\xf9\xbe1\x8abo\xa5=\x03\xc1\xab\xf9}\x18/\xe9\x1d>\xe3\xbe\xbf\xafw\x0b\x0b^{\x1a\x80\x91zo\x90@B\xa8O\xb1\x90\xf5}\x15\x0d\x8cwdOE\x03cn\xf5}\x85qX8\xd9S\xd64,\x7f|\xdf`\x03\xa6\xf1{\x06B\xea\x18l\xc0\x82\xd6\x9e\x86\xfc9&\x9b\xc1\xa2\xd6\\\xf0\"\xae\x99\xfc\x02\xf88\x04\x06\x82W8pJ1\x04\xf80\x06\xce q\xe0\x16\x13\xb3\xff5g\xd4\xf3$\xbe`\xdc\x0f\x0c\x04\xabOk*k\xe6\xaf\xb0\xf8\x14h\x00\xdeM\x01\x80\xfc\x8e\x98\x11\x05\xc6\xb3\xccR \xcc\x8exC\xd7\x1c\xf9\xe2\x9a\xbe\xc4\xc23\n\x1cH\xb8\xf61f\xf0kZ\xab\xc7RK\xa0\xed\x00\x98\x85\x98\x986\x1b@\xc6\xf6\xfd\x14\x8b\x18\x12\xd2\x97\xec\xe0}|\xf9 `\n\x84e#\x01\x02\xe1\x81\xa8\xa2\x02\x14\xc8\x95x\x07\xcfH\x06\xd6I\x81\xe5}\x8a)\x89\xb6\xe7|\x80y\x8f\x80e\xb2\xda;\x98\xcb\xa8\x1b\xd2'\xa4\xa7\xc5\xcc\xf1\xa1'\x8a'\x06\x84\x89z\xe0@D\xf2\x13,\xfe\x0b\x00\x98\xa8\xfe5\xb5\x18\x05g\xd5\xb2\xbf\x8f\xa9E\xd0\xd3\x10|\x98\x03\x9d\xe4\xef\xaf\xb0n\x10\xf4\x12\xb0:\xfc\x91\x0d \xea\\\xa7\x80=9\xecGX\xd1\x16\x904\x00D\xc6\x1c\x12`2\x8f\xd1#\xcc\xac\xd6\x8c\xb7!V\xd0\x03\x03\xc1B\xca\x9a!\xbd\xf8\xf8\x05\x06\x82\xa5\xa4\xc0\xe5\xb0\x13\xefb\xd6\x13\xb82\x16\x15\xaf\xc1\x1a\x90F\xb2\xa5\xf0\x99t\xec\xb9R@}\x1f\xb3\x89\xc0\xe48\xc4\x84QB\xc0\xe2AN\x9d\x97x\xda\xe1\x143\xf1\xc0K\xf2T\x03\xc9.x`\xd2x\x87l5\x18!1 \x06\xf2r\x1f\x9fT\xe9\xf2/\x88\xcfY\x81\x07\xe01GhP%.\x80\x90\x81\xb5\xb2\x0d\x89R\x8f\x8a\x85\xc9V\xb7\xec\xedN(\x89)\x80\"\x04\xb0,g\xba\xd1\xc7\x90\x1cj\xd1\xd2\x12\xf7\x03H\xc7J\x91C\xc0\xc1\xf9\xbf\xbc\x14x\x19\xa1\x94t\xd7.\xf9\x8dc\x0b\x85.Ur\x1b\xc7\xb6\x9ej\x11\xed5\x8ei\x87(u.\x88\xa0\x8dw\xb1\xe9VLZy\xe0\xeb,\x7f\xc4\x1f\xbeT\x06\x02|\xdf!\xe7\x85\xf73\xb3|\xa0\x1ec+5\x0d\xf8 FaQ\xa4j+$\xf6\x99\x80\x14!\xadT\x8b\xa4\xb5[-\xcb\xa8iA)r>t\xa9\xf4v\xee\x0f\x8a\x1e1\x11\xb6\x05'`\x8a[\x8a\x9e!\xa1\xa4\nV,\x8c\x0d\x83\xab\xd8\x82%\x1d1\xd4l\x98p^\x84\x98\xe1\xd9\xc8FJ)\x1f\x1f\xe0S_.\xa0\x90\xe9CL\x9c\xcbe\x8c}\xf2\x01\x16\x93D)\x08\x92)\x0d\x19\x0b,P\xa8:-|\xa7\x0feJ\xa1\x1aXG(\x17\xd0\x07\x00\xeb\x04(\xda\x03\xe3.\x8d\xf4 \x82\xd0\n8\\S\xfc\x80\x0bi\xba\x19p\xc1CD\x1a}\xf3C k\xc9'\x80\x9e\xbe\xb4\xee\xbb\xba\x99#\xf2\x9e\xf1 x\x8c\xd7+(\xf9\x04`\xedM\xc1\xe4\x1a<\xc1\xb4&\xe0\xa9\x9a\xacE\xce\xe0\xa9r\\x\x82o\xd4\x03\x9e\xa6\xa5\xab;,\x81\n\xb0\xb6\x13`\x0dZ\xc0\xf8m\xe5\xf7jYc\x01\xd5`\xb25kO\xaa*\x14\xa1U\xa2\x08\x12\xb0 \xe1\x8a\xeeHrA\x94\x80\"\x95\xb8\x0d&\xcdC$\xc7x\x00k\xd9\xb6|\x06\xd7\x92GD\x18\xd0~:T\x1eOJ\x04\x92X{\x12\xa5\xc0R\x01=1\xb4\x91\xec\x00\xa4\x00z\x93X>\x12E3\x1f\x10\xca\x98:Z\xf9\xc6\xf8\xb9\xa6\xafF\x88dh\x8c\x92X\x98ZS\xaa5\xa1\x95\xb5\xdfk\xa4\x81\xc08}ac\x88\x80\x80`J8vz\xbbg\xb3\xc7\xa4z\x82\x041Rc] B\x92vb\xf8\x8c\xc8\x8b\x06\x82\xed\xbbk;\x0b\xac\xf5]\xfcQ\"\x05\xe5\x9a\x99\xa5l\xa0\x9d\xce\x08\xdd6Ng\x84\x86d\xb5\x82\xa4T\x8c\x16l:QP\xa8K\x84=e\x9a\x9d\x7f@hQ\xc9U\x8d\x98v4K&t$K\xe0:\x97hK\x81\x0e1&\x89\xf3\x83,\xd1\xeerdRy\xe2\x19\xc3\x0e9\xb3ybB\x90\xc9\nV|\xd0>\xb2H\xf3\xda\x07\xcd\x02S\xb7\xfa\x1f\xe3\xdb+\x13.\x83g0r\x80\x16\xfc%\xd6\xec\x04\x80\xc3\xe3\x1b\x04v \xc4\x89\xf71\x91\x1e\xc1\xf7w\xf0\x94\n\xfeT\x032\x96\x0dl\x1e\x03\xb0a)Xa\x03\xb0\xb2y\xe0k\x92\x91\x93\xec\x01\xc5z\x0f\xdf\xfd\x8et\xb6\xc5g\x1fa\x99\xf9\x12H\xa0\xd8\xbc7\x82\xcf\x98\xbd\x8eL\xca*l\xe5\x18\xe9H\xe6{\x98\xb1\x8f\xb8\x93\xe6 \xf7\x8a\x07\xb6\xb0\xf2q\x89{~>2Ndoa\x82{\x89\x07\x81\x1f\xeak\x01l\xf4\xbe\xa4\xd5\x01l\x88\x1bi\x00>\xe2\xa3\xa1\xdc\x9c\xb7\xc9\xea\xfb\xae\x0c?\xfb\x18K:*-\xe8=l(\x19\xf9\x9e\xfd\x8d\xa2\x91\xef)\xba\xf0\x14\x13\xd6\x91\xef\xd5\xa4\xcf-\xb2\xc0`\xb2.!\xf0\xc6\x16^\x1b \x82\xd1a \x0e@R]\xf9\x08/\x81\xcc\xc9\xaa\x13\xaf\xde\xc3\x8cq\x14\xb8\x90\xad\x10\xdb\x8fG\x01\xb3\xb4g\x1e\x1a\xa3\xb0\x0c\x1e9\xf8%\xa6M\x12\x02f\x85:\x18\xf8\xfc`\x1f\xbb\xb0'\x9d\x8c?\xc6\xd4:,R\xcc\xd3\xb1\x97r\xc9S\xa0\xce$\x89\x97}]\xdf\xe5|\x86\xb7*4\x10lz_\xd7w9\x9fa\xae\x11\x1a\x08\x96:C\x93r\x96\xf6S\xce9k\x19\xb9Jt\x89Q|\x1d\xc88\xd6\x14B\xf8\x8c\x15\xca\xd0Pw|\xbaT\x82_\xb2\xd4\\{F\xbd\x8fYU\xc8\xf5\xdd+V*D% y\xc7\nQ\xaa\x02\x85\x99\x88g2\xfdu>p2\x7f\xcc\x11\x1fy\x13KW\xba\xdc\xce\xd0w\xf7\xa6*\x16N.u\x99'\x87\xcd%Ko\xf5`KS\xc8S\xaer\"a[AX\x04l[&\x9cf\xdc\xa3A%$\x82\x02\n\x96-\x7fD\xde]\xe7\xfb\xca1\xf9\x07!\x19\x82 \xaf&\xf4\x86\x17\xf1\xd5\x18\xb6\xae\xf9.6\xb8\x85\x1a\x80\x87\x19\xea\x988\x8a\xd9*,\x0e;\x16\x86:\xce\xcd\x06\xb8]\xdfX9\xd6\xcd\x06O\xeb@:4\xccRI\xef\x13\x96\x1aB\x1d\xd6b!\xc9\x03\x00a\xb95\xd4\xc6[\x028\x9f\x01\x06=\xa5\x030\xd1\x0eX\xb7\x0cM\xb8\x03!\xacCexx\x8a\xd5\xbbPj\x0b\xf7\x08\x0e\xc3Cq\x0f1\xf3\x0b}\x10>\x1eb\xa9/\x04\x8c'\x0d\xad+\x93'V\x11Be\xf2\xc4\xea^h|8\xb0\xba\x19\x1a'\x0eZGI)XD\x0e\xf5E2]Du\x97\x8c\xa5\xb5\xb0z\x13L\xc7P\xb9\n&\x03\xb1\xdc \x92M\xb2\\!\x92\xed\xd278dx\xc5\x15\x8emJ\xe5[\x1c\x1b\x19jM\xdbr\x0e@\x1b\xa3\xddh\xb5\xf5!&W\xa1\xd1[\x1fbkZ\xb8\xa6\xce\xc8\x13:8-\xc1c6\xb5\x1e\x9dM\xb8#Y\xd8[\x98\xbb\xadG\xa1\x04\xfa\xe1@\x13w\"l\xac\xebX\x11\"\x9d\x18\x01\x16K\xec\xfam62|\xd0\n\xf0\xe7\xf5(\xab&\x95\xc7\x86\xc9_\x01.\x06\x81)\x7fQ\x06\xc5b\xda\x86b\xe3\x9d\x0d\xe5\x0c\xf7\xc4V\x9e\xa2\x08\x0e\xcclh\xadX&\xcc2\xd6\xa3\x8c\x86\xe2\xd8ZB\xf18\x14\xe1\xa3L\xb9B\x13I\\@\x8c/\xb4\xbd\xa2r\x87\xb6\x03\xc7N}\xbb\xf0\x10\xf4C\xac\xd9\x02\x0cr\x98c\xe3\xd5z\x94aO\x00r\xe8Q\x19\xe3\x0c`[\x19\xabG\x00\xa1\x15\xb2`\x0d\x8dS\xb0by1\xd5U\x05\xca\xc8c\x1dHY\xea\xb2\x0f\x95^\xac\xd6\x95+p\x06\x93\xd7\xf5(\xab\x93\x07\x9f\xfc+[sT(|\xf2\xd7\xb6\xadV\xa2\x00\xf6\xc8\x93\x10\x85\x04v\x18 \x01\xd6\xa9\x01\x06H\x805\x8f\xf5(\xdbL\xb8\xcb=\xf5\xd2\x0b\xb6\xf3\x95\xe0f\xad\x9e\xfc\x1b\xdb\xe4t\xb1\xea\xba>\xb4P\xac->\xe6I\xca\xcbD\x0fOG\x94\x92\x195\xcb\xc8IdlTHc\xa7EOA%\x8b\xe1Y\xa86\xe4\xc1\xd9\xce{*\xe7\xdb\x03+\xb6\x97K\x15\xcdYX\x84.\x18\x8b9C\x83\xd6\x01V\xcb\x15Mb\xd3\x97(Z\x8c\xedO(k7\x05\n\xb7\x1c\xa2#\x8b\"\xae\xcb\xb9\x07\xbb\x8e\x0d\xfa%x\xb1\xeb\xd4XQ*\x86v\x1d\x1b\x1aK%\x8b\xf3\xf4\x1f\xed\x0d\x96\x16\xea\xc75\xb3Ck\xf4\xc0\xc23\x8bn,\x93\x93\xc0\x82\xccXx\xa2,Qeg\xc4Z\xa4J\x15=Y\x86\x81\x99?\xd1\xd6\xe3\x1a\xa9@\x00\x9c P \xf1mPH\xcd\xf1\xf4o\xe9+\xb4\xa1\x8e\x80\xbbG\xa5\x810\x8e\x02\x1d\\\x88M\xc9!?}\xc7Z &Id\xcc4\x8f\x1b\x88\xb2\x02\xabI\xd6T\xd6\x93\xb4\xf4\x9b\xa9|;D\xc8\xd7qx\x9f\x10\x8b\x96\x81\x10;T\xa6\xbc\xd1h/\xe8yr\xaa\xe2\x96K\xc0d\xa8\xaeK\x9e/\xa7\x07\xbfRD\xb5C\x04\x0dy\xa5A\xec\xc3\xf2+1\x0f\xcb,\x9a\xbfG\xbfrH\xda\xf86\xbe\x13\x0es\x9d-\x96\xd8\xb3\xc7\xfa='\xcb.^^\xd6\xcf\x14\x12+\xd8e\xf3\x82!\xb1\x18\x8cM-B\xe6\xc6\xa6\x16Y\xc6\xb1N\xbbe\x19\xc7\x18\xf2\xcf\xd8 \x17t\xb8\n9\xbc\xe3\"\xfe\x1d\xdf\\\x85cm\xcbz\x1f\xdb\xe9\xc3\xb1\x8ee\xb0\xf5\x06. v\x88\xb9\xc4\xb7\x815\x0b{\x9f\xd0\xdd\xb1\xe1\n\x0f\xfe\x9d\xad\xa6~[\xf8?X\x80\xfb\xc6\xe8Oh\xda\xbe\xe6\x99\x04\x15\xf65\xcf\xb4B\x14W\xa3\xb0P\x9b\xc7\xf1\xd5\xe1\x86I\x11\x81\xef*\"\x03\xc1W\x81Q\xdd\xf3\x99\x91\xba\xac%\xeffn\xe8\xf4\x11XF\x894\x00kc*\\\x1b\xef=Dk\xff=\xd6\x89\xa2\xda\x1797\xf4\x9bM\x9f\xe1k\xed\xc8@05\x8a\xe0!\x98g\x1fa\x9a\x13\xe9\xd7\xce\xb0\x93V\xe4\xa5\x91\n{\xc2\x96\xdd\x8d\x15H\xbd\xf0\x19\xde\xff\x88+\x00Y\xf8\xbeZ\xc6G\xd8\x95iC\x1b\xfeI[\x1a\x80\x0f\xa6\nV\xff5\xde\xa9\x0d\x93\xc4\x824e \xd8\xa4\x1d\x81\xb1\xfdC\xcc\xba\"\x9d\xa8\xe7\x116\xc3DC\x81\xfd\x9fc9&\xaa{\xa112\xa6hl\x06\x8f\x02\xbd&d\xeb\x03\xf3(\xe1#\xec\xb4\x13\xe9\xc4\x12o\xd2Z0\x17,\xcbn(O\x98\xcf\xb0\n\x1bi\x006]o\x8c\xf8\xc0\xb1\xceR\x01~\x83\x19\xe8\x86\xf4\x8f\x90\xe9\xa7\xb1M3*@x\xef#%R=\xc2\x86\x9fhT\xfb.\xec\x861\x9e\xe2+\xd2\xc8@\xb0\n`\\)\xb1\xf1i#\xe6\xa1\xf5\xc5U|\xbdo\n\x16E\xb0_Z\x14sx\xf0\xf0\x11\x96\x11\x8c\xef%y\xc5vC\x0e\xeb1\xa1 N\xe2k\xbf\xc8(\x17\x04)\xc0\xb3\xf01\xa6\x14Q\xe2\x81\xb5\xe7mL\x8b$\x04R\x8a\xd8`2\x13\x17\x16>\xa2\xc4\x13\xb8\xff1A\xe4\xc4\x1f\xa8\xec$d#\x13\xf5b\"\xde\xc6(I\x83\x08D\xb9\xc7\xf8>7J$\xa9zLH\xb1\xfd%\xe1\x0d\xa3\\\x90\x01k\xc7\x0fB\x89u\x8a\xa4O\xc8.\x1a\x08!\x94\xeau\x8f\x07\xb8\xca\x86\x11\xf4\xf0\xf6F\x06\x82\xa9\xc8F\xe1s\x8bq\xb2p\xc7%\x8f\x1a\x03\xc8\x81zx\xa97T\xb6\x06\xb2\xd2\xea;\xd9\x9a\xb1\"q\xefbanc\xccu|\x11!2\x12\xa6\x82k\x9f\xfd\x19fe\x1a\xaa\xc2 \xff\x94\xac\xfb\x98'\x9bN\xc2\xc3l\xc8S\xb86\xfc3|\xd4\xb42\x85M\x06B\xd7\x13\xd8\x87\xe7Q\xd1\x01-\x95\x94\xb8\xf2\x14s\xfc\x92}\x82B\x94m\x02\x016\x9d\xc4<\xcfF\x81\xc0\xc61\xf9\x8b\xe13&}1O\\\xc91\xfe\x19\x05\xf82\x1f\xca\x0c\x05\x8c \xd6\xf3Mlt\xd6\x94\xe7\x01\x99>O2\x1eJ\x81\xecM\xac\x85lj\xfe\x8ayu\xac\x01XX\xde\x84\xa7\xd2\xb1\x96\x1b\xc3S\xe9\x98\x1c\xc7Cxu\x00\x1f\x8ax\xa8^q\xa6\xfeX\xf1P=\x17\xfd\x17\xf8&tS\xf6\x8c\xe9z,;\xc6\xfc.\xf63wX\x9b';\x86Q\xe1S\x12\x07N\x08\xef\xc7\x93\xa4i\x00\x82\x84jx\\\x02\x06i\xb7-\xd5$\xd1?j\xf9\xec(\xc6\xff\x11\x16\x92\x05\x104\x7f|\xb2\x04D\xd7\xc2\xa6\x04\x01\xf3\xa4\x9aE\xde\x81\x93 p\xf3#\xb8\x11\xe4\xe0\xd3\xfa\x18\x0bE\x9bA\x9e\xea\x87\xd9?\xc6h#\xaa\x8d\xc2:\x88:l\x1f\x11\x1c \xf24\xdb\x97c\xfc\x08\x8b\xeb\xf1\xc8\xd6\xdaf\x04\xc9\xa8\xc4\n\xcba\x92\xcc\x83\xb1\x90\xb9\xb4\xa1\x10c\xd9\xa6\xbe|\xc5bml\xa4\x04l\xbf\x8a\xa3\\>\xf6\xf81\xde\x95M\xb9\xecO0\xd3\x05S\xe4}\xcc\x0d\xe3DE\x18a\xc2nL\x94\xf7\xb1<\x1d\xc3[\xf5O\xc8y\xd0\x96K\xfa\xdd\xad\xe9\x9b\xbb\xa50&:\x02\xee\xaaw\x83\xad\xe3(\xdf\xb3\x90\xb6-\x97,5%\xaa\x96\xf6\xda^\n\xab4f2e\xe3\xab\x05T\x8e\xd4\xc2\xb2\x96\x84+;\xce\x13\xccu%P\x87Ya\xe9J\x00\xb5\xc5\x10\x0fh3Q\x16\xc37\xe9\x16i\x08>E\x12\x92\xdaq0\xd1Qht\xf8p\xc1j\x19z\xc3\xc0\xd5S\xed\x98\x02m\x96\x1ej'\xd4)\x89\xfaN\xa0\x04\x00\xac\xb3\x08\xa0V3\xde\xc5\xca\x94\x00\xa698\\\xbfKx\x87z\x7f\xed\x1e\x96D7\x93(\x8e\x12\x9dI\xed\x1e\xc6\xcc\x02\xac\x12\xb5\xe1\xfa\xa2a\xf0\x9b\xb7\x80\xea\xb6-N\xf2\x04\x04\x83\x07\x98en\x1a\xa1\x11\xdb\xc6bc\x91\xc6\x86\xc9Mx\x95\x87\xac\xbf\xfc\xfc\x1b,\x96\xc6y\xe8*\x13\x17\x06\xbd\xae9,&\xd7\xb75\x00\xef\xc8\xed\xbal\x8b\xafk:\x87\xcd\x13\xb7\x0d\x9d\xc3\xec\xe2\xb6\xc1\xd9\xb7\xb0\x80\xf9\xbaY\x15\xact\xdf6\xab\x82\xf9\xfc\xed\xdc\xc9x\x12\xfa*3\x01\xc9\x8c*\xe0z\xf4\x98\xeb\xea\xd8\x94\xd7l\xdf\x15\x91\xc2\x02\xd5\xeb\xbb\x1b;\x0b\xec\xdb\xado\xe3*Qf\xf9\x9c\x98\x84KX\x9b\xd0B\xec\xbd\xbf\xfd;\xcc{\xb6\x8c/5\xde\xa0\xc4@0\xc3I\x1c\x0f\x12\x90\xde\xc3;\x91\x94\xb34a\xfa\xb1\xa5c;1\x1a&\x1a\x80u\xf0\xc4\xa4U\xc2'S@\xe4\x94\x1ea^\x9f\x14 \x97hs*s\x12fo[Z\xd9\xc4R\x97\xb9\xfc\xa2\xfd\xab\x1a6\x00\x10\xbc\x0f0]KLR%:\xe6\"\xa9\x12\x19Bq\x97f\x81\xa8JX\x84J\x8atKXQL\x8atK\x18\xf1\x13\x93n\xe9\x03L\x0f\x92R\xba%\xac\xe9l\x99tK\xefc\xa4O\x8aLLX\xd2(]\x03\x92E7 \x97\xb0\xc2\x94\x14\xb9\x98(\xeae>\x10M\xac5IH\xa8\xfd\xe7q\xbd-\x93\x8d [\x18\x13\x03\xc1\x1c%1y\x9a0\x05HL\x9e&\xb2[:O\xd3]\x1b@\xd4\xb9A\x01*O\x13\xa6\x84I)O\x13\x16\xd3\x93R\x9e&<\xa3-\xe3\xa7\x8f\x15\xfb\xc4@0\x03\xdf2~\xfads\x0d\x04\xd3\xd6\xc4\xe4i\xc2\xc6\xb3\x04\xf24\xe15\xd8\x02\xcd\x91\xe0>8\xc3b\xad'\xd1y\x9a0kM\xbc\xc0\xa4\\\"\x87\xdf\xe4p\"\xf8V\xe4p\xa2 \x15\x17Jh\x19\xc8\xe9\x04?9\xf0t+@g\xc9%\xd4\x99;\x81\xc9\x92k\xab\x08\x88K\xc6\xc6A\xdey\x0f\xeb\xae[+\xe7\x05\x91\xc3|5\x81W\xfe\xf1g\x8b\xff\x0fvV\xd6E\xd03r5\xc5vcT\x90<\xb7\x9a\x14\x890\xb0=\")\x12a\x90\xe6U\x0eh\xb2BZ\x90 \xdd\xe8\xc4\x16\xf8\x16\xdb\x84'\x93\x17\x7f\x13\x9d\xd8\xe2\xa7\x04\xe7\x8a\xc4\x16\x98ln\xc98\xba\xcf\xb1\x8e\x95\xc8\xcf\xbf\xa1]DR+'\x8cX\xc6\x88\xe3|]\x18\x8bQ$9\xe6>\xc8}\x820\xa7\xaa\xf7\x84\xb5v%g\x17fTE\x89J\xd4\xfbO\xf1\xfd_\xd1\x91I\xda\x85\xe9\xbfl\xaa\x9c\xb5\x0b\x93\nY\x80\xa6\xed\xc2*\xb5*\x86\xf3v\xe1\xd3b\x8a\x95\x12wa\xb3\x16*\xa3\xf3\x0ea\xf1G\x16;W\x8b\xa7\xe5\x04V:\xc2\x95\"Z\xa9\x10\xf8\x06P\x8c\x13EP\xf6.\xeb:\x97\xf2\x80A)\xc2.D)\x9c{\x8bPf\x9ff\xd4\xb2.\xa2N\x97\x85em\x0d,\xb0\x13[F,\xcfr\x13Z(\x8a\xa0\x8cYx:\xc4\x17\xf1\x01\xa1\xceVG\xc4\xa6B\x85\xf7\x1a\x96\xdad1\x925\x0bK\x04\xaaTur\x98R\xa9B\xa5\xa4WX\x8b\xab\x94\xd0\xf8\x87\x05s\x94\xd3\x8c N \xae\x9b\xc0\xbak\x02\x87\xee\xd7D\x88\xf2\xd3\xea\x83\x8d\xa4\xa2I\xa6CP1\xd0\xe9 \x08\xfa\x05\x90\xf3\x81HQEf\x1bL\x0c\x93jf\x1b\x02\xd6\x81\x0cO \x933 d0WLL\x02\x19\xbc\xe8\x89I \x83iKbn\xd3\xb0&\xb8\xa5uQ\xc2\x95\x8d.J\x04\xde\"/ \x1duqGB\xf0/\xcaC\xaf\x94\xe0\xfe\x03\xac\xde'0\xc6\x8e\xe53\xdc\xf8>\"\x9a]\\r;$<\xc2d\x03!\x04\x19\x85\xf0\x90\xb3[d\xea\xc0\x06\xb5-};E\xebh]\x1b\xfb\xc6l)\xc9\x8b\xec}\xedw\x99\\\x83\x08\xd1&\xb9\x06\x16l\x93\"\xb9\x06\x01\x15\xa9)\x082\x17t \xc7ni\xdf\xc3\xf7\xb0\xa5\xab\xe4db\x81H\xc2zE:\xe2\xc5\x93\xf7d\xbc\xb5\xe8:\xf2a0\xefR\x88\xdc\xc9'd'G*\xaf<65\x08\x00\x84\xaa\xfd\x0d\xcd\x02\xb5\xbdqn\x07\xce*\xa9\x16\xf538\xadX\x9c\x01G\x9f\xe3\xf4\xab$\xe3\x1fb!_\x00\xd4E\x1aa!F\xf0\xc5rQj d\xc9bG]\xc1\xfe\x92\xa0\x99\x04\xe9w\xfd,\xd0\xc4z\xf0\xd3\xdbJ\x96x@\x98\x9f\x80\x80\xaf\xd1\x9f\xd3\xb5Ko\xab\xdc!\x0f\xb0\xb0,!P\xefg\x965\xbf\xad\xfcg\x88\xd4t[\x076`\xb5\xa7\x08\x94x@(\xce\xedR\xf8\x82\xb5^\xe1\xd7o\xab\x0b3 \xb4\xd4D_<\xc04P\x82L \\\x0dPuH\xebJK\xd9{\x98\xd5\x97^\xae'R@=\x08j\xe1g\xa8\xc8.\xd2p\xc0\x86\x02\x85R\x8f\x17\xcb\x16\x06\xd8X\xa4h\x8a\xb0\x11Yn7\xd4#\xa6\xf8\x93;p\x83L\x1e\xf2Oo\xe75\x80\xda\xeb\xa5msk\x89u\xc8\xd4hR\x98#\xa7\x0d\x02I\x03mJ35\xee\x87\x98jogp\xfa\x08 U\x80\xbf\xb0\x01d[\x7fAD\xc6,q\x04\x9f\xe6q\xea\x07r \x7f\x83\x95$]D9_as\\\x9a%\xd2\xeeE\xb2\xdfm\xc3\x01|H\xf0Z\x1dL\xc2r\xf3\x9e~\xb3\x9b\xa8\x0e&\x16\x89\x02\xe0d\x91\x19\xe7=\x9d\xaa\xe7)\xe1\xbayo\x94\x83\x07\xf3S\"[\xe7=\x90\xfa\x9fb\xbb\xa2\x80@_\x84\xc0\xe6=\xcdE\x9f`\xb2\x9c\xe6=\xc3E\xb1^Z\x1c#\xdb\x1a\x990*+H\x11\x05\xcb\xb4\xcb\x11T\xd6\x0e\x8b\xb3d\xaf\xad\x12\n\xdb\xa6 \xd0\xdbu\xeb\xa3\xfd\x1f\xb1-A\x80`\xd3\x9f\x12\xec\x11 \xc8\xf2F8\x86\n\xf6\xa2\xfaj\xee\x96]\x8f\xb0\xd6*\xc0e\xd7#\x8cL\xe5`_\xd2\xb6%\xd2\xb7\xa6\x04r=\xaa\xeb\xa5\x14\xe1k\x19\xa7\x0eY\xb3\x80\xca\xaeGD5\x15p\xedzD\xd4S\x01\xacUPs\xb7^\x0b\xcd\xdd\xe1\xce\xd0\xb1_Bm\xc3e\xd2=\xc2\xf7j\xbf\x83!\xf0\x97\x98\xb8n\xc3v?\xa4\x15\x80}\xd2\xd3\x1a\xcf \xf2\x82OO\x9a\xc7\xf3\xe2;\x91M\xf3\xf8\x84\xf8N\x84\xc7<\xd6\xe4\x05[ \x05H#(\x11XM\x84 \x05\x009\xa0\xd8\x1e\x1b\xd2\x83\x05\xb8j@w\x0d\xb08\xa0\x96\xa6\x87\xca7\xfcWXQ\x9405 |!\x9c\xe6\xb1I\xdbJOSl\xa8!\xa55\xb1\xa2\x86Dp\xcdcE\x0d)\x1d\x8855|J\xc45#\xed\xd8\xb6\xbfn]*b\x90eI\xca\xe1\x94V\xa8\xa6h\x96\xa1\x96)\x9ae\x8e\x9a\xa2\x11\x9e\x9e\xc7z\xad\x89\xc0!@@\xd1\x08\xbb/b\xd6\x88\x19\xc6\xc4\xacachjb\xd6\xac\x90\x9a\xbc\xd7\xe9~\xa8\x8d'D\xba\xb9\x03\x91S\x9f`=q\xc7\x113\xfaA\x86>gN2\x80\x9dy\x17Oh\xc7\x91!\x9aX\xaf\xc8\xe4\xe7\xdf`\xe4\xcf\x94\x9d\x9f\xf8\xea\xef\x18k\"i\xc9@\xb0\xa6\xb1cl\x80\xd8\xfe\x92\x19\x08\x96\xa9\x94zF+H\xdd\x0c#\xbf\xce\x9c\xfcclw\xcdx\xa0\xbcb\xdf\xc5\xeclG\xdb\x8b\xf0 \xcc4\x00\xdb\xcd\xb3!O\xf8I\xd1\xd8=\xb2,\x02\xd4\x8f@b'\xd0\xac\x11\xba3\xe4\xf0\x06*\xa6g\x99\x06`\xb6)\x01\xe9\xa1\xc0\xf7\xdf\xe0\xc3)ac;\xc4w\xf7J\x197\xf1A\x91\xf0:cJ5\x03\xe2[\xbf\xa2/\xf5gC?T\x9e\x8d\x98\xdeU\xb3\x1dbh6\xdcS\xb1\xbdtD\xf5\xe3\xb9\xb0\xb1\xb5.N\x066\xc7d\xc3(\x11X\xf8 \xe6\x1c\x86\xbb\x93\xb6t<\xce\xaf\xb1%\x1a\xa5\xdb\xc0\xc4\xce\x92k\x03\x8bq(\xd1\x06\x99\xa0\xba!\xf9\x84\xe0\xa0\x00\x80\xec\x8d\x15z\x00\x01\xc1\xf8\x88\xa0\xa8\x00\xc2\xbb\xb9XP\xc9\xea\x1e\xe0\xce\"\x0e>B\xd8n\x99\x81\xd7\xee\x03r\xd2\xa3\xb8\x07\xe7\xed],\xd0dQ\xac\xd3\x18\xe3\xa1\xed\x18\xdb\x06\xa6\xed\x99\x81`\xca! *d\xe3)6\x1bdQ\n\xc3\xc6rSVx_\x93\xa3\xb6\xb5\xb8,\x99\xe4\xdb\x84\xb0$\x0e\xec\x91\x05R\\\x9f\xbf\x87\x15.\x0d\xd4\xde\x0b\xefaA\x0d\xc7\xee\x93\xac\xea4t\x9f\xa4W\xd7E@F\xc6HJ\xe2\xfa\xc9\xa5\x9a%\xac\x9f\\\xafe\x89zU\xe5\xd9/\xb0IL_\xc9\xd9z6\xb6\xc1\x8f\xb0\xdc\xbb\x93\xf8q\xc0\x97\xeb\xe8\xb2\x80\xaa\x9a\x96\xe1\x02\xea\x7f\x88]\x06\xb3\xc4\xcf\xd4\xd6~\x84e\xa3,\x89\xf9\x1d\xe5F\xf5gx\x0fw\x8c-\x00k\xbe\x99\xb1\x05\x10\xa2\xa5nz0\xfb\xcf\xd4U\x0f\x96_v\xb4\xf9\x9f\xa0\xb7\xb6\xff\xe3E\xd81\xcf\x0f\xd0>4\x04_\xc0d\xfb>\\\x8c\xdc'\xdb\xb4\x1f\x0d\xb9\xe3U\xf3K\x12\xea\x08\x85\x90w\x13&1\xbb& \x1e\x1f\xba\xdc@\xf0~\xefj\xd1\x07\x8b*\xb9\x96\x960?\xcau\x0d\x0c\x10M\xe9\x00\xfb\x0f\xf0\xb6\xec\xf6\xd4\x93\xca\xf8\xa67W\x80\x7f\xc0s\xde\xed%\\\xc6y\x7f\x86\x97,7\x10L\x13wu\xb4>\xde\xb3\\\x030\xfe\xed\xc2\xa8\xb0\x1c\x93\xc3\x98\xf0\xa9\xcf=\xed:\x809\xc6\xae \xd6\xc7\x04<7\x10LZs\xe3\xca\x89M]y\xe1?\x88\xf9\xe1\xae\x16s\xb0\xd8\x91k\x00V\xd7vM\xc0<\x16as\x03\xc1\x879\xd7\x9e\x85da\x86N\x02\xeen\x98d\xe6& -\x1ern\xde\xc5\xc2\xdaJ.\xdf\xa7\x12\xa0w1\x95\xca\xcbOWY\x80*6\xe5]l\x1e\xcd\xcdC\x18X\xfc\xda\xd5\x11\xf2X\\\xcf5\x00\xbb\xedC\xb0\xed\xc7\x98\xc1\xee\x86\x9e\x8e\xa9\xc5\xef\xe5\x00\xc8\x84\xd4\xe2Ce\xc0:\xa6\x16\xd3sY\x00\x07\xd5\xe2{(c\x8a}\x88\xf1SBt\xb6\xff\x07\xf8\xa8\xed\xaad\x0b\x9fa\x0c\xc95\x00k\xf4\xbb\x86\xc5c\xcd-7\x10L\x04\x9b.\x1cw\xe3\xc2\xb9\x86\xd0\x95\x02f\xa9Wv\xda|\x1f\xdb\x8c\x15\xb8r'KOh\\\xbd\xb3\xc5\x8a\xc5n,\xa4\x81b|\x18\x9eW\xe1\x96\xfa\xd8+\x98\x9c\xeaX91\x9aw?\xc8\x19\xd2%\x8a\xa7\xa4\xc8a\x8ak\xb77\x8e\xf1[MX\x9b\x94E\xd0\xad1\x96awU\x08\x14^\xe4\\}\xc7\xeb*\xbe\x0fm\x15v\x8d\xc1\xfbs, \xe6\x85-\x9cn\x93v\xbf\xc4\x95$\xa4\x187mSa\x10x\x7fb\x99=O\x0c\xa9\xc1\xe7)/?\x02e\x01jRC\x16\\9\x19~F6Z\x03\xb0\xd8\x92k\x0f\xaa_`\x82\xbbkD\x1d\xc2?\x8c\xa8\x83U\xb7\xdc\xbc<\x84\xeb\xecj\xdd\xe83L\xbbr\x03\xc1\xf2w\xae\x9d\xbb0M\xca\x8d\x0b\x17\x96ps-\x0b\x90\xd5\xdeUy\n\x08\xe1V\xdf\xb1.\x97\xef\x1ba\xfd\x11\x96\x9d\xc6N8\x80;\xc8G\xb8\xb9\xb1\x934\\\xab\x8c\x9dD(\xce\xd2c\x01\xaf\xd0\xd8I\xc2H\xe8\xbe\xf0\x9a\x06\xc6\xc2\xb1\x93\xd4\\\xc6\x08\x88o\x0b:\x17\x80\xfa\xb8\xc6\xb1\x16\xa7,\xed%Vz\"\x00\xe0`\x8f\xe5\x86\xb1\x93\x18O\x0clR\x11\xb0\xea\x1d\x03\xbd\xd2-\x97Q7\x0d5\x85*\xa6\xbd\xe62\xca\xc0g-\xa4-\"\xc4\xb6!`H\xd3\"\xaf\x03\x97\xca\x18\xaaH\xfc\xa1/+\xcd\xfa)f\xe1c\xc53\x9e\xe2\x83 \x002\x8a\xef)>\x08\x97A$\xc4\xe4l\x0c\x9f\xf1\xf0\x8a$f\xb8\xeb\"\x87\x19\xee\xa1HaFFe\xea`]H\xb6&%\xaf\xa7\x98\xe3^V\x9e\x9c\xf8\xa6m\x0c\xdfI\xea\x991\xe7j\xb9\x1e`qx\xcc\xb9\xd2W\xb1\n1\xe6A\xe0\xc3\xbd\x02&w\x97y\xa2\xda{\x93\x1c\n\x0d\xfa\x11\xad\x93\xd5\xd5\xc8j\xca\x97\x13\x9bb\xb9T\xc3\xd5\x13\x17u\xd5\xb7y\xec$\x8e\xf2+\xff+,B\xebR\x85\xe5\x07#3}\x04\x04\x13\xe5\xcbZ\x0c\xc7\xc2\xf6X\x030\xee\x8e\xb5\xc4JQ\xdf\xe4\x8e\xb4dz\x1c\x9b\x9c\x8b\x96\x0c\x89\x97\x8dx\x86\x95\xf1\xb1\x81\x10:[\x1b\xef=6o\x17\x92sg\xd8\x16!R\x86ma\xc5z\\\xba\x01\xb6\x90\x8b\xd2-\xb0\x15j\xeeKj\xa0\xbc\x8eZ].\x0e\x17\xd6\x00\xc6w\xfc\xc1\x1dG\xb2\x82G\x18\xf1\xafh\xbfV\xcc\xfd\xf65\x00\xf3\x9d}\xee\xa9\xf3\xf0\x18+\x00W\xb8\x07Q\xbd\x0f\xf1\xe8\xf65\xe4\x1e\xde\x17 \x81C\x89qj\x9f\xfb*[\xcc\xdb\x18\x97\xafht\xc3\xf3\xd9\xd7\x00<\x9f+\x063\xb0\xa0\xb3o \x98\x94\xec\xdb;\xdfO\xac\xa7g?\xe1N6\xb4\x82\xae\x18D\xc2\x87`\xdf \x12\xd6A\x0e\x94'\xd4C\xcc\x04\x0f\xd4\xce<\xfb\x05\x16\xc0\x0e\x94\x13\x14\xd1\x9c\x0e<-\xfe\xe0k\xe67\xf4za\x9b\xc2\x81\x06\xe0\xfd?\xd0\x0f\xb5\x90\xb7o\x0f\xb4\x8eL\x9e\xbb}Cf#\xc06\x90\x03\xf9\x15\xab\x00\x07:\xbd$y\xcb\xf7@\xdfA\x927|\x0f\xd4\xf3d\xe4!\xdd\x03\xfd\xe2\x0bf\x05\x07:\x99\xe0Gx\xaf\xde0\xe8\x80\x95\xef\x03\x03\xc1,\xef\xa0\x88\x0d\xc1l\xea 2\xd6A\xb2\x91:<\x9d\xbc\xdc{\xa0}>\xc8\x83\xbdo\x18L\xc2\xc4\xea\xc0`\x12&\x8a\x07\xc6;\xee#l\x1f<0\n\xd7G\xf8\xb6\xed\xc0\x88\xcc\xa4\xa7q\x0dK>\xd8\xaf%\x00W\x8d\x8d\x0e\x93\xdfC\x03\xc1\xb8yu\x11\x84\x12\x8c\xe6\x87\x0e\xd8\xaf\xf0\xfe\\\xd5$\x0b/\xda\xa1\x06`\xbc\xbc\n\x1d`\xd9\xe6\x10\xda\xc7\xa4\xfd\x90\xcbdBX5\xbb\xaaO\n\x96\xdf\x0f5\x00\x8f\xe7\xea*\xf4\x8b\xef\xa2\x0f}\xe8\x18+\xadW\x0d\xe2a?\x9fC\x03\xc1D\xff\xaaA\x14L \x0f\x0d\xa2`JxU\xd9\x0b\xb1\x08t\xa8\x0c\x86\xa4<\xe8;\x9f\xe1\x83z\xa8\xf4 l\x00\xb8fBQ0\xc2\xdf1\x10LT\xae\x99\x1b\\\x8c\x1ew\x0c\x04\x93\x90k0\x0d\xbc\x8cw\xe03F\x82k\xea\xe5vL\"\xee\xa8\xef\x98\xa6\xdc\xe1\\?\xe2\x89\x19\xc65\x9eDW|/\x1b\xd6?\xa3vM]\x9fb\xc9\xf0\x8e\xfa\x8eq\xe5\x9a\n\x9b\xc6]\xdd\xd1\xc8E\xa6\xa3,\xfe\xa4\x030\xf8\xff=\xee\xe0\x8e?0!c\xf8l^\xd3ar\xf8\xb6\xed\x8e\xc1;|v\xae\x19\xbc\xc3D\xfa\x8e\xc1;|p\xef\xec\xdf\x92k\x85 \xd7\x9d\xfd\x10\x00\xef\xb6\xcc\xf7\xbb\xf2\xaf\xbb]\xd6\xcfC\xe9g\xda\xe6]\x96uY\xd8a\x7fd\n\xb5\xf2\x94\xb34K|7k\xbdj\xbe\x8e\x9d\x84%\xec\x0c\x0b\xdb'\xe7^\xe9T\xbb\x8a\xe4\xf7\xf9\xeftf\xf2\x90\xa7\xae\x13\xf3K^Q\x93\xcf\xf0\x838J\xb2\x94\x9d\xa9\xf6[\xeeTw\x11v\x99\xdfeN\x97\xe5\xec\x0c\xcb\xaa\xdd\x88\x9fh\x84\xcf\xc4Qz\xc99x\xb5\x02\xf5\xfb\xac\xfd\xf2,;sF\x14H\x13w\xc6\x1d:\xc9R\xe4\xf1\xc5\xac\x9dup_\xe2\xd7\x8f\x12\xd6\xce\x8e\x1e}\x95e\xec\xbb,}\xd5VF\xb7<\x07-\xb7Cfo\xbe\xc3\x12\x9e\xe5I\xc8\x8e\xcc\xbdZ\xdb\xc8\xcb\xf3\xb2\x91\xd0\x14v\xd8\x19\x96\xb4\xa36\xb4\x98\x06\xbe\xcb\xdb9;\xca\xe6\xc4\xeat:]v\xe4\x08\x9f\x89\x9d$\xe5\xc9\xcc\xd8 |\xcf\xc9\xf8\x9a\x1f\xee\xb5\x9d\x0e{\xe9%\xd6\x96+!\x16\n\xea\xf0\x99\xc0\x0f\xf7\x96\xa20\xe3a\xc6\xce\x88e<2\xdb\xb1\x8f\xe7\xb4\x1a\x8bhGV\x17K\xc0^\x13\x7f\x9fa\xf3l\x81eG\x8f\x92\x8aw\xc9\x173\xebo\xd5\x97\x93\xeb\xec\xb33lV\xad\xb4\xe8\xf3\xc4<;\xd2\xb4\xa0\xa2\xcc\x91v\xc8\xbe\xc7^\x11\x7f\x86\xec\xbbl\xeed\xe7\xd5\x0e\x19\x81XX\xebd:j.t\xfe\xfe\x83\xf4\xe8\xf1A\x97\xb5X\xab3\x93E\xf2\x0eg\xc9Iy\xfb\x85\xe0\xf0F\xef\x16w\xb3\x19\x8f\xf7\xfd\x90o&Q\xcc\x93\xec\xb0\x9duY\xeb\xe6M\x9e^\x8a\xbc<\xe0\xad.\xc1\xd6 \xe7\x0b\xec\xc8l1\x82N\x97\xc9V\x9c<\xc8\xca\xd3\xac\x99%\xc5\x147\x1a\xc5Q\xc8\xc3,]`\x8en\x89\"\xfb~\xe2\xc4K\xa5\xa2y}\xd14s2\xbe\x19\xe4\x03?L\x17jXA\x1as\xb7\x0e\xc6Tw\xdb<\x90\xb9&\xd2\x05\x96\xd0^\xf4/-J\xf9\xd6Bw\xedu\x9d<\x1b>\xc7\x08\xa2\xe7i;r\xd2\x13Mm;r\x8f\xd2\x05\x96\xd6\xcf+\xe1^\xeer\xd1\xb5[\xbf\xd4\xfaWZ\x84\xc0>P\xf2\xf5n\xcd)\xbcK\xe9l\xdc\x0e\xdb'\xe7\xe7;\x16\xc9\x14@'0\xc87\xa0\x93\x18$\x88W_\x82NaP\xaeA'H\xadT58\x7f\xe2e\x0c\nt_'\xc9\x08]\xdd\xe0\xc9\x13\x9d\xce\xab\xdf20}JX\xbf\x9e\x1c\x08\x02\xc6g\x8a\xc3\xc8^c\x9c\xd96Um\xce\x02\xe3u+j\xe98\xa6\x1d\x0b\x92Mz-\x88t\x95\xd4j\x0e\xfeGw)\xbb \xf3 `G\xce0N\xe59\xc9P$\xcfc~\xc8xG\x93\xa18\x89\xb2(;\x8c\xf9\xcc\xd0I7\xf6CM\x90f\\'\x08\x04Q\x0bA\xd6\xc9\xae\x877\x04S\xb9\x1e\xde@|N\x0d\xb3L\x8b\x04-,-\x02\xfbF\x90J?\xdd\xdew\x06\x03\x9e\xcc\x0b\x8e7\xe3\xa7\x1b\x8b\xdb'\xe4\x9f)O\xc6\xb7\x1b(\x82\x103y\x91\x942\xc5#KtY.\xddJ\xa4\xec\xaa\x93\xe6\xc7\x03&\"\x99\xb0\x90\x00\n\x17^l\xb1\x97{fz\xaek\xcd\x03\xcc\x9f9o0\xefp\xde\xa4=/2+vD\x00\x01 \"\x80$)Y\xd5}\xb0\x96\xad$\"\x10\xd7\x1d;\xf6}'a\x00\x9b*\xfaf\xe7\xbe\x92\x1bl\xbf\x0d\xf1\xed\xd6\x8e\x12\xc6}-\x8cW[\xd1\xde\x07]=\x1d\x13W\x0d\xd8;#\xc5\xe1U^\x10z\x91R\x1c_aP\xfc\xeb\xbb\x9c6\xa2&\xday_\xf6\xa6\x0b!\xdf\x16\xc7\xce\x1cz\xec\xcb\x85\xcdc\xa7\x851\xd5\xf8\xec\xa3\xcc\x94\xf7t\xc8\xb0/\x9fq\x03\xf4\xc5L\xd94s\xb7\x89\x85\xf1o E\xe3\xdf\x12\xfe\xc6\xbfk\xdc\xce\xfe\xac\xd0\xfe\xddLI,e\xffvUw\x8f\x91C\x1d\x82\x83)\x84\x13\xbcXn\x86\x7f\x95\xb8\x17\x87\xed\x85\xf9K\x1f\x89\x15F\xfe\x18\xcee=\xbd\xce=\xfb\xb9MP\x0c\xed6\x93\xc4_\xbf?=#\xe1\x9f\xa3\xe4IY,\x92,\xfc\x99\x18\x88\x8a\x9cR\xd1JZ\x9e\x96\x8c\x1e\xa8Hy\x05!\xe2+ \x91\xd2D\x88\xe4\x9f\x86\xd8\x16\xbf\xe8\x84#\x0d\xaan.\x95-\xee\xceP\x7f7k\x87.\x83}\x7f\xed6\xccvq\xab\x8c'\xdc\x01\xc2+>t\xdf{\x11\xe6\x85\xd3\x06\xfe\xeav#q\x91]\x1d\x92\xbf\xdb\x8e7O\xb2\x03\x7f\xb60\xcc\x0d\xa4[\x93\x1d\x06\xbe\xee\x0e\x1d\xc7\xd8Q3\xa2\x14R\x8a\xe9\xe6\xb1\xba\x14u\x0e\xd3\x91\xa6\x94\xe2\xdf\x92Q\x01\x94\x0d\xb1\x14g\xd8J(\xcb>\xb6P\xbe\x84bn\xfe\xc1c\x7f\xf6}D\xf7|\xd2\x04\x00m\xfdk\x0d\x03\x11#\x03\x92\x96\xf9\xc2\x8e\xc9\x05\xf8\x14\x81\xf3\x1b\xbd\xda\xd6_\xaeQ\x056\xf3\xe6aT\x90l\x00|@}\x88\x18FE\x91-Q\xd6\xbdv\x1cG\xc1v8.X\x8b\xa2H-\xfc\x14!\xd7\xf2\xd3\xf0\xcf\xe4J\xbc\xa1\x84\xc2\n\xc3/;\xfd\xd0>\xe2?\xc8\x7f\xadt\xe5*\x99\xbfJV@o\x8d\x8a\xad\xf2\"\x12\x9f\x15\x0b&2\x7f\x92e\xfe\x95\x9d\xc1c\x18\xc1>d\xb0\x01#\x98\xc0\xa6\xe3\".\x18=\x82\x10\xbe\x82\xec\x11\x84\xeb\xeb\x0e$\xd3\x90V8\x96[\x9b\x86\xc7\xdd\xcd\xa4}\xfaws\xd9\x97\x155\xe3\xd3\xcb=j1\x8b\xd3\xe2\x98\x92\x8b3\xbf\xb0\x13\x87r\x93mV3\xd1^\xff\xac\xe0\xf7\xbf\xff[\xf2\x8c\x9a\x9a\xbdK\xa1\x82\xdc\x06W\x1f\x0f\xe3\xebVe\x91\xef\x84\x8d\\\x99\x81\xbd3\xd6y \x03+\x13%\xf5\x86\xa1Z\xa7GB\xa0\xd5\xe4E\x1d\xde\xd6\xc8\xd7\xe6m\xbev\x18\xf1\xb2\x12\x8f\xe3\xf6*#\xccK[\xe1\x9fB\x89\x7f\xe2\n\xff\x14\x1c\xff\x14\x12\xfe\xc9\x18\xfe\xc9\xe0+(\x1eAF\xf1O<\xcd\xba\xf8'\xd3\xe0\x9f\x04Ug\xb7\xc6?\x127E\xf1\x8f\xdfB/1\xc59]\xd1\x8e\xe9\x88\xaf\x84\xd7?)+E>gV\xa9\x8b\x07\x99\x0e\xa2\xa3MH\xaa\xa2\xfb*N\x88\x15u\x98\xa4Z\xa9\xf1P\xaf\xd4\xd8T)5X\xd1H%\xcdcEz\xa5\xc6\xd6\xef\xab\xd4\x10\xbfd\x91\x7f\xb3\xa1\xa7~\x14\x9d\xfa\xb3\xf7\xf9\xa4&b\x9as\xf9\xb6(\xd2'\xa8\x88\x8b\xd4\x15\xde\x12Lc\xf5u\x12\\Mj\xfa\xbcY\xe7\x90a#\xad\xfa\x92\x97?M\xe2\xc2\x0f\xd1\xdfL\xa3\xbc\x94:;\x08B\xf4V\xc8\xd55_\xa7\x84%\xff\xa9\xfa\xd6(\xe9\x12Q\xf1E\x18\xbf\x9f@(j}\xe6\x87\xc3\xb7c\xbb\xab\x9fKxI\x07\x90C\xbc\xbe\xec\xd8\xa6p\x8cUF\x14l\x91\xa8XQ'\xf1\xd1A\xb4\xff.%\xa8\xf5B\xc0\xedr-\xb1\xb8\x18*ex\xb7\x0e7\x0cI\xc9\xec\x8d_,\xba\xe5LJbU@TA\xa6\xa5\xb0)\x0b\xe7`\xaf\x15\x95\x1e\xb0:\x03\x9cH\xe0\xe9ul+O}J\xf5\xd0\xdb\xc4\x05\xebU\x02\xd5$\xda\xcc4\x9d'SI-\xfd\xb4\xa6-z\x94@\xda\x8e\x83\xf0\xbc\x03e\xe2yO\xae&\x12c\"\x9ekW\xdf\xdcb\\\xcd\"\xc6\xeb\xaf=\xc8\\\xc7\xaa\xf1\x81Z_|\x91\x91\xb9\x10\x13\xecc[0\xb9\xd9\xf8A\xcc!W\x16_\xab\xc6\x17\x99XI\xba\x9b\xf2\x00\xa3jc\xe90\xd5\x8c-\xf0=\x9bUR\xaaa\x02\x83\n\xf7LZ\n\x0c\xf9\xd1q\xd3\xd0\xbf\xf3\xa5\x0b\n\xfe\x94\x98\xd6\x12pX\x13\x98\x99\xc5\x01\xb8\xe4Q\x8f\xc8\x00\xfd\x86,s\xa5%)\x16I\xd0\xdbV\x8a\xee1=\xa2\x15q\x9e\xe9=\xc3\xd8t\x17r\xba\xdd=\x12\x99(J.\x8e\xb2\xab\xe7\xc5\xeb\xb2\x98\xb4\x8d9\xe5\xe7Z!<\xd0\xbdo\xbfko\xe3\xb0C\xcb\x8eY\xfey\x194uo\xa3Pu\xe7\xd0\xcb\xc8\x0e\xc5\x9d\x13\xf6\xdf9\xe1\xe7}\xe7d5\xf1\xa1\xbbu\xa4*\xdf\xd3\x85\xeb\xd6\x0b\x07\xdfNX'\x9e\x87g\n\xa8/\xab\xfb\xabb \xba\x95\x98\xb1\xf8<\xee\x96D\xec\x0ee\x06\x84GW\xa9b\x9c3\xac\x12\xe6\x07\x97dV\x16\x8a\n\xf3\x9e+4\xc5\xf2$~\xba\xf0\xe33\xc5\xf7\x01\x82\x8d\xf5\xd2\xcf\xde\x07\xc9E\xac\x92?.X\x95e\x12\x90\xe8\xe0\xd2_\xa6\x11QU;g\xd5:\xb4\xa1\xaa\xee\x12\xb85q\xc1\xe4\x01\x01\xc9gY\x98\xd2\xad\xb7*]f\xf7\xb3\xb3\xd6g|\xe9\xf8'\xe4\x02\x12\xefu\x16\x90\x8c\x04/\xfd\xb4y\xce\xe9ZG\xb4\xda\x99\xf7\x9e\x08\xe1w\x98\xe5E\x9bu\xa3\x80v\x05{p\x86]\xa8\x90\xd6)\xec\x81\x95\xe0)fw\xd3U\xcd\xef\xa3\n\xdar\x81\xc9f\xdb\xb6?H\xa2\\\x19n2\xbc\xf5(\xeb\x1b\xce\xf0B\xba\x97\xcc\nRl\xe4EF\xfc%\xbf\x08\xe9$\x98\x91k\xe4\x85q@._\xcfm+\\\xfag\xe4\x1e[\x88N\xa1_\x06a\xa2+<\x0f\x03B\x0bu,\xf0 \xdb\xd6\xe7qZ\x16*m\x03\x9f\xcb\x0c\xf6\xeb\x0b\xae\x85DOt7\x1d\x93f[\xf3\x90b\xecK\xf3;\xc1\x0e\xa1\x82V\x98t\n\xb5\xa3)\\lL;(.'\xd0\x8f*/\xae\"b\xb2^\x07\xf4\x1a\x880\x98\x07\x1d\x9d\xb6b\xf72\x026F\xeb\xdf\xfe\xf5\x8f\x96\x90}\xdf\x14\x07\x81\x0e:NN\xf0p\xea:/]\x88(\xc0\xdf|\x85\x1a\xbdfI\xba\xc1O\xb8v\xba\xf6\x17\xfc^p,\xe7#L7 iFf~\xa1\xdb\x0b\xca\x95\x0b\xbcQ\xd5\xa4\x97\x82\xfc\xb7\xd8\x0d\xd3\xf8nw\x88dj\xb8w\x9c\x12\xe1\xec\x1a\xa9\xb0\x06+\xab\xabta\x1a\xf6<6\xf2\xfeA\x98\xa7~1[<\x8f\xc3\"\xf4\xa3\xef9\xcb\xaa`J\xc4\xc3n\xff (\xf8\x12\xf1H\x13\x9c\xa0\x9f\x94\x05\x1b`\xc1\xbaz\x01\xb4\xcd\xc8\x9c\xde\x04B}E\xcehs\x13\x06\x8a\xcf\xe7\xb0\x0f\x01L`\xae\xffhU*\x15\x18\xa5\x8azu\x83\xfd\x86z\xef\x9d\n\x1f(\xa5\x1dZC<\x18p\x07\xc9 \xb24\x9d\xfd@\x05'yRf32\x81es\x04\x86\x83\xb2P5\xd3\xbbW5K>\x01_\xc1p\xcb\xfc\xf8\x04\xcan\x0dr\x99\xfaq\xf0\x8c\xa4\xc5b\x02#\x85t@\xf0\xdbJ\x01\x9c\x80\xda+a\xb8\x83$\xac\x02\xf8jA\xd8\x9c \xc2d\xe2WQ\x9f\x13&z.\xe4\\w:3Y\xfb\xa3!\x12j M\xd5\x15\x90\xd58B\x96L#\x06\xec\xdd\x19\xe8]\xe9 \xefz\x8c\xa7\x15\xe9\xa2\xad\xd2\x90\xbc\xc5\x14\xeb\x95\xb0\xaf\xad\x9e\x18g\xcc\x89\x9d\xee\xed\x05B\x98\xc8\x996\xedh\xd2L\x12\x03VJn\xf8\x17\x0b\x8dW-\xfa\xaf~\xb2\x19\xff\xd4\xd4\x81\\\xc9zS\x818X=f\xaf\xf2\x83\"i!\x04Y\xdbCQd2\x87Z\xd1nY\xbd\x8a\xd1\xc2\xcb\xd3(,l\xeb\xc7\xd8r\x86)\xd3\x15\xad\xc4\xf0\x186a\x9f\x1b\xb3\x11X\x87\x91\xe3\xfd\x94\x84\xb1m\x81\xe5\xc0:\x14`V\xe0\xf2\xcat\x10\xeaM\xa3\xb8\xaa\xa5\xa9\xf5\xc5\x06\x8d\x1d&/\xfa\xe5z\xd8\xb6\xa8\xa8\xf3\xe6=q\xdc4,\xb4#\xafF\x91\xb2\xe5#\xef\n\xf6 \xc5\xb7\x9f\x1b\xf13S\x918 /\xe8\x908!/\xe8\x908>/Pz\xbb\xcfT$N\xce\x0b:*\xcf\x88\xdb\xe9\xd6c\x9d *gf\xa0rf\x9f\x9e\xca1;e\xf6P9x\xa5\xbb=\xc2\x90U\xa1'L\xce\x18\xd3\xd3k\x88M\x9f\xd0\xcbI\xc1\xbe\xaa\xd5Hx\x06\x14gY\xee\xe3{?\x0b\xfd\xd3\x88\xa0\xc8c\x85\x0e\x85R;\xec#\xc8bn\xb3^(\xfa\xd3\x7f\x951O\xfc2\xcbH\xcc\xbf4\xd3j\xd5\xa4\xcfH\xf1\xa4(\xb2\xf0\xb4,\x88m\x05~\xe1o\x9c\xf3>\xfb\xe8\xac\xe6\xc2\xa9\xaf\x06K,\x8d\x05{\xd5\x8d\x82\x91pb\x83\xa9\x0e3\xa66\xc68AZ9\xd1\x97\x9f\xfb\xd1\x04|e\xf1\xb5f\x8f\xabE\x1f\xb4\xa3\x8c\xe3\xc0\xddd_R.\x97\x04\xac\x85\x8e\xe9/\xef\x04\xcd\xdc:\xdc\x00\xfa\xafh\x90\x08\xb4\xbd7T\x9cE8\x8c\xb3\xa8\\\x8b\x9f\x85\xc1\xcb\xa4\x8c\xdb\xc9\xff\xe0\xa32\x19\xdcB^\x0d'\xa4 \xbcH\xf9\xd3\x96\xebcZ\x08%>#\xc7\xcb,\xb2\xfa/^\x15Y\xd7Z\x8b\x1f\xc2(zKf$<\xc7\xcb2\x1f\xb0&\xbd\xa7|\xc8\xa2\xc4\xb2sJ\xdf\xc9^\x15\x1f$\x955{\xe3+\xf5\xdaS\xba\xaf\x1eqk#\xd0\xb5\xab\xf9\xceD\xc4\xd1\x15@/\x19o\x1e\xc6\x81D\xfc\x0d\xa4\xfc\niwyl\xc5F\xdf\xda6LF{h\x8c\x11Vdl\x0b\xb0b\x15`\xe9\x1b\xb3CVO`\xc9\xdc\xaa<>\xa2\x96:zu\xfa7\xb1[\xf3\xc5o>|\x80\xac\xc7\xb0\x11$\xac\xd9n\xa2\xf7Cf\x92\xda_\x0fqj\xa1P\xb7Zz\xe6\x0e\xd4\x08\xb7\xa7Ha\xb31\xf4`\xdf\xa9\xf8\xc4\x8c\xd3\xee\xfc\x98\x0f\xdc7\xcd\xe9\x1e `9\x98\xcf\xc9\xac\x08\xcf\x89\xf8\xd2\x88E\xd0\xfb\xaa}\x92{\xd5\x1d\xb2k\x94|\x92MgW{\x82\x06\x1e5\xb3\x04\x87\xc7\x14\xf4\xf2\xf0g\x0d\n\xe4c\xceo*\x14\x91\xd5|\xc2\x13L\x0d\xd8\xae\xbe\x93\xc8?%\x91\xb1\x9bE\xb1\x8c\xbeA%\xf3\x8d;aa\xd1\x8c\xbd\xd4\xea\x03\x04\xf0&y\xad\xeb0fT 3\xb7k\xda\xa2\x98\x00\xa6o\xe1\x13&p\xeb3\xa0\xe6g[\x8693:C\\!W\xd7\x03\xa7\xdb\xa8\xa7\xb3G\xf6\x8a\x841N\x8e\x905\xf5\x00\x1374\xbe\x0b\x88\xa3\xb4LY\x90`\x83\x8eP\xb7A\xd6S^\x0b\xde\xbd}1\xb1\x0c]7Dg\xa1\x9d\xe1\x8c\xb4\xb5\x17\xdb\xb5d\x8b\xd3\x0c\xd2y5|\xd8\xb4s\xd2Wk\xd89\xf9\xab\xdd\xa9}\xe0\xd5c\x89\x03z\x7f\x0d\xf1\x98\xce\x1a\xda\x06\xd4~\x1bC\xea\xf1\xdb\x95\xc4\xe5\x12\xcd\x11ns\x8e\xe9\xd3\xe2\xe8z\xaf\xf9\xfa\xec\x13\x13\xcfkZ\x8e\xc6\x14V@\x050`\xbf\x06\xa2\x03\xa8\xe2?\x92`B/\xf3\xbd=Hl$\xa6\xfa\xa9\x1c\x86\x1a\xfa\xeb \x9cc\xacH\xb1\x87\x89\xfaq`\xa2\x9fm\x88\x96\xb8}\x93\xe5\xa6\xb5\x05\xb9T\xf1s\xf2\xc3G\xccW\xa2\xcf&\x0e\x86\x83\x83\xb9\x91.\x0c\x9a\x16D\xeb\xf0Q[Ctj\xf4\x88[\xeb\x05\xee\x13\xbb\xce\xf1\xed\xe7&v\x8dtb\xd7H'v\x8dtb\xd7H'v\x8dtb\xd7\x88\x89]\xebQEL\xc0\xaa\x12\xabF\x9f^\xac:\xbb\x8dXU\x12\xac(\xa4\xa7]\xad\xadVy\xdc\x92Z\xdeJy|+\x11\xcf\x9dr?}\xbcM1\xc4)F\x19\xe9\xa3\xa6Q4\xb7\xa5\xeb\xb5\x10\xb2\xa5\x98\x81I\xdbMk\x1f\xa1w\xee1+\xa4p~\xe5\xd8\xed:\x15\xd2\x17\xb0>GI8\x962\x0fE4\xe5a\xf3\xe8\xe3\x9d\xb9\x8b\xdb\x0fYX\x90\xd7qt\xd5\xc0\xbc\xedG\xa7\xabp%\xb0\x1f\x0c\x08\x83\xa1\xb7W\xcc\xc0\x80\x96\xe9\xee\xaa\xd3g\x02\xd9\x85\x1f\x07\x11y\xbd\xea\x88[\xa0;\x14\xd0(\x10\xdf\xfb)O\xe2{\xa1W\x90\xbc\xb0\x0b\x16\xc0^\xb6\x1d\xe0yf`2\xc8\xa6\x00VY\xbe\xf6\xe17m\xaf\xbc\x91vlX\xc1\"9;\x8b\xc8\xf3\xfc \x08\x8b\xaf\x93K0$\x99\x91\x1f\x19\xbf\xb2\xb1\x0f[y\xe9\xdb~\xb9W(F5\x815\x8c'\xc0\xfe2~\xa7\xb6\xc0\x84\x1e\x98\xc7\xa46\x9d\x08W\xf2#\x8fE\xe1|!\x9e\x0e\x82\xd6W\xe5\xa7A\xa3p\xa4\xc3\xea\x14t'w{f\x1bV\xb2\xa9\x80\x15\xf8o\xfa\x08\x05u\xe3\x16\xaa/\xf1\xc1*S\x1d\xf6[\xdd\x02\x02V\xb1\x82\x001\x85\x16\x9e\xe0\xb6\x04\xf5\xdf_~\xa9\x9e\xaa-Ur\\X\x93\x1a\xab\\N\x18\x11\xd8\xf8\xb3\xd2\xeb\x0f@\x0b2d\xae\x8e\xf1o\xbc\xd4\xcf\xc2\xe0]\x1a\xf8\x85.\x08\xc2M\xd7X\xa2\x11\xf8*\xcbo\xb4\xeb\xac\xda\xa5;\x9a\xb2V\x10\x05+\x1e\x86a\xeaxXA%\x0f\x15ie\x88\xb6\"?\x99P\x9f\x0f\x101A\xa5\x9f\x1fx?\x86\x98O\xce\xfa\xba,\n\xb3c#p\xba+\xb3\xad#rY<\xc9\x88\xd2\x15M~JV}\x11\x9e-\xa2\xf0lQ0\xb0\x9a\xf4T\xe1\xee\xab\x97\x9ef\\zz\x13W\xe0\x81\xd2\xd3\x94U\xcc\x0c\xa3@\xf2\xad\x8f\"\x1f\xaa\xf0\xd5SK\x91M\xcer!9\xee\xd9'\xc7\x85s\x13\xa3a-vk\xab\xe7*o^`\x19XS\xbfo\x99fC\xe6%b\x11\xa8\x82R\xf4\xcf\xe9\xc6c\xab|\x13\xf8\x94\xdfqH\x9bX\xb8Rz\xfe\xb4\x15\x01\x15,\x17\xce\xf1_\n\xa2\x06 \x83y8\xbd|\x1e\xacd\x17\x0b\x9ck 3\x12\xe0\xed&\"b\xf6~\xc5\x08\xa2\xfa\xe0\xf5\x7f\xd1q\xae\xe8\x91\xc7\x00\xdb\xbb\xbb\xdc\xbc7~\x9e_$Y\xb0\xf2\xe6\xfd\x11\x9fO\xb1w7\xdb\x0d\xbf,\x12z\xddG\xa4\xa0\xbb\x12\x93\x8b\x8d\x94\xcfu\xc0\xd7\xb1\x08\"8\xf8\x0b\x0ea+|q\xf3\xdd_\xe8\xfdkz\xc2z\x88\xa7\x07\xdd\xe7C\xf6\x85>\x84^\x9e\x83,\xe4\xa1\nf\xda[\xd5\xe0\"\xc8\x8a\x0dF\xf4\xda\x12\x11\xb6\xe4\x94\xf8\x19\xc9\xf8\xbdj\x82\xf7\xdf\xe9\xc6\xc3\xe1\xdd\xea\xca\xbb\xf1u\x87\xd7B\xf0\xd9]u7\xba\xe6\xee\xf6\x8ac\x16\x89\x16.\xcf\xe7\x86\"\x87_m\xab\"\x9c\xbb@6w\x81h\x86#\x99\x01\x08\xc6\xe8\x7fl\xda\xa9a\x08\x81,\xfb\xeb\xd4\x11\xab\x12\x0c\xf6\xfe\xed\xd1\xd1\x1b\xccLK\xe2\x82\xcbR'P\xc6y\x99\xa6IV\x90\x80IR\x08\xa5\x97\xac\xffh\xc1:\xa4\xb0N\x7f\xddN\xfc[\x0f\xaf\x16\x017W8\xed\xb3e\x919\xf6.{\xd1\x002\xb9)c4r\xc6\xab7-\x98\xf4\x1b\xcf\xb4\xab\xccLH_+D\x0b\xb5\x1e\xd5$3c33\xf1e\x95\x82\x92\xaf\x1d\xcf\xe9\xc3\xc4e\xfd\x02$w\xb3\x00\x9d\x99\xa8\xb2\x92\x1b\xb3\xbe\xd1;'O}J\xe3\xd6\xab\xa7\x96\x1e*s\x9d\xd1\x01\x9d\x99\x00\xca\xb4\x9cd\xc8r2Q\xbby9\xd9\xc5=h9\xd9\xeau\x86l\x17\xd5\xec\x15\x06\xb7\xf54\xe5\x15\x87\x9e\x94\xbf\xe2\x11\xa4E\xefT3\x96g\xbe\x17r\xe2\x95\xa7*\x0f\xdbp\xdbK\xd0\x90\xd5\xd0\xa0\x1fL\x15\xe9G\x0d0tM\xb4k\xa9r\xbc\xfa\xf4\x07q\x05LT-\xa7j\xe4\x03\x82\xc8\x19h;\xe5)T\xc7\xa9Q\x07\x8d\xcb\xebxn\xd2\xd5\xe17\x12\x08B\x87\xa0\xba\xbd\xfa\xf2ws\xf6MZY~\xfbp\x03\x85\x82\xde\xaaYGW\xa7\x06 \x96\xf7\x95R>k\xf1\x80$\xa1\xe7\xbc\x8d+u\xe5;pKo\xea\xa2\x11[p\xb8;t\xdb\xa1\xba\x9eT6(\xc2\x9b\xd6\xa3Z4\xa4*U\xef\xfe\x8d\xe2Yw\xe5J\xffhB\x83\xed-\xbd\xd4`\xab\xc3\xd3\x87UQ\xc7\xad\xd9\xaf\x8a\x1e\xe8d\x07\xdb[\x0fu\xd2\x83\xedme\x8ckV\xf4yX\xf2\xc9\xfb\xd9lHX\x8dHym\x9aSyR\x16\x8b\xe7\x05YJ\xb9\xc7\x9b\x15\xea\xec\x0c\x93ZR\xd0\xacR\xa7\xa26\xa6<%3\x1e\xb6\xd0\x9ba?\x98\x90\xeb\xeb\xab\xe7\x01\x89\x8b\xb0\xc0\xa06b\x08\x7f&W\xa8*\xc2\xbe;\x8db`mQ\xf5i\x12\xe7\xe5\x92\xe4?0\x01\xd1JB\xfb\xdea\x17\x8aa\x8b\x0eQX\xe0\xd8Ek\xd0\x9a\xe12_\xcf#\xfft\xd0\x00\x05\n\x97\xd2\xf2\xb1\xbc\x0f\xb0\x8f\xd1\xe0z-%\xea\x0f\xbf\x0f\xf3\x10\x85'k\x9bj*\x8d>\x14FN\xfd\xd9\xfb\xba\xb2:\x1c\x14\xa2QK\xd4^uP\xdd^\x0cCR\xcd\xc00(FO\xab\xd7\xde\xec\xc2\xa5\x98\xbbzT\xca5U\xf6\xa8A\x1f\xf0\xb9j9\xf4\xbb04z\x04\xd3n%\xf1Qv\x95\x94\x05:\x07\xeb+'\xbc2\xf3g\xee\xa9\x1cr\xbd\x99X{}M\x96\xe5\xd2\x8f\xa2\xe4\xe2(\xbbz^\xbc.\x0d\x96P,\x87e\xc1\xeb\x1d\xc4\xfei\xa4\"\xd5\xc4\x83\xf1\x1f\xbc\xb9A\x0b\x12\xad\x10\x0e#\xa8\xebb\x1ag}\xcd\x05\xd6\x1c\x18L\xf6\xbc\xaa\xdc\x1b\x1fv\xc9\xb6`H(\xd9\xb3\xaa\xea\x80!\\UZ\xce\x97\xa8\xc5\xd4\xd7<\xad\x06\xfb\xc6\xa8\x13=a\xdd\x0b\xad\x8e\xbe\xe2\x05\x86e\xaeQf\x8f\xc3\xd8\x01\xab. \xa5?\xd2\xc8%\xfb\x80\x07\x85;BZZ_\xfb\x90\xd5~Z\xa1\xca\x1e\x0f\xb0\xa7\xac\xfe\xdb\xdaM\xbc\xef\x8b\xf7\xb0\x07%\xa5m\x0c>\x7fO(Q\xe5\x859e\xbe\xf4\xb5^\xc3\x1e\x9c0\x16ArS7\xcd\xee\x0d\xec\xc1\xa9\x97G\xe1\x8cP\x9c\xb51rx\x82\xef\xc6\xf7F\xe5\xdf\x8dS\xad\x1a\xb4oZ\xcd\xcd\xc7\xe8\xacO\x05w'}\x0eP\xf5\xdd\xb8\x9f\xd5\x838T>~\x155\xd3\xcc\x1c\xac\xfdX# \x02\xc5l\xc3\x82,\xc1\x82u\x9e}\x8b\xd9\x93v\xae^\n\xf7\x96\x8f\xaa\x1b]2S\xc3\xca\xac\xa0\x13\x1c\xa6\x04\xd5\xf6\xc4#2W>F\xf5ZQv\x86\x1f\xba\x9a\x9er\x0c\xd9x?\xd1~J\x83\xf9h\xdb\xd9\"\xb9\xfe17\xb3F\xedR\xcce\x17\xcd\x9bu-\x1c\x98\x06J\x18\x0d\xa2\x14\x8b\x88\xa7A3\x193=6H1]r 9K\xb3\xf1\xb4\xdd\x02*\xe5\xf5\xaf\x1b\x1e\x10r=\xf4fI\x19\x17\xf6\xad\xceD\x0b\x1c#2\xa0cmg\"7\xcf\xb0\xee$\xc4\xb8zO\x14\xe7W\xa0\xa6\xaf\x96\x0d\xa8\xb3\x18<\xe2Y\x12\xc1,\x89N\xd8\x85\x03\x8d\xdd\x8aN\xd0IK7\x13\xeb\x15\xbap}\x8aq\xc8nO\xda\xe1<\x93}\xa3\x1c\xe3\xb8\x1a\x99\x94\x06\x99P\x82\x8c:%\x9f \xee7\x9fV]\xbd\xf4S/\xcc_\xfa)\xf3\x17R\xd8\x1f\xd2\xe7\xda\x0e\xa5\x8e\x07&o\xd2\xcd\xe7\xa2\xcf\x8fh\x1e\x1bc\x95@G\xcaj\x88ZB\x1fA\xc1O\xe0\x94\xd1\x80}\xd9\x84j\xb6g\x02\x06\xfe\x80>\x99\x7f\x81W\xe6\x04z\xe2T\xa4\xac\xd6\xa2F]?\x84\xc8\x82\xf8\xb5|\xc9\xbe\xc2\xf4%\xc6v\x98\xdb\x94\xec\x94h\xae\xdf\xcc\x04\xd4\xe7\xa3#\x7f!\xa4H\xf2\x97-QV\xff\xbaK\xb2t\x03\x07%jsNo\x02\xe7}\x8b)\xb8\xb7 \xf4\x04\xd7\xaeBEN\xe0\xbd\xb6\xa2.^h#;\x1c\x06\xd8\xbb\x0b,\x7f\x13\xe31m\xc7i}\xdd\xbfJ m\x90o0\x01\xcbj\xdc\x9bm\xb2\xe6\x8e\xee\xad\x8a\"\xab\xef.\xb8\xcbY\x1e\x1a\x07\":\x9f\xf0\xb0\xe2\x98Z\xb2K\xb8\x1a\x0e\x8a\x8c!\x14,c\x1f\xc1y]-\xf5\x13\xdb\xa1\xa4\xe2\xeb:t\xab\x9e9\xb8\x93\x95\xff\x87d/oJ\x0f\xd7\xe0}\x82w=\xa3\xda_\xd7r\x01\x8c7\x80; \xfd\xa9\xbd\x81\xb9$\x03#%\x1a \x83\xa6\x87\xb1\xae\xda\xa5iN\\\xe6y&\xe2\xfb>\xade4\xdc\xff\xe8\xccmk\x8a\xafL + y\xf2 \xf05\x10\xe9\x00\x1c\xef=\xb9\xc2\x1b\xdfH\xa8\xf3\x8b\xa1_\xd8/\x9e\xa5\x97\x93\xe2mg\x06\x03r\x1c\x8bh\xf8fd\x0dm\xdcn\xacmr\x0f\x1e\xc6\xfeI\xd1<\xf9\xd2m\xa0\x06Zw\xcaM@r\x93\x83t\x17\xb8\xf1\xa9\xd1,\xb7Blo\xf4+\xd2\x08\xfc\xf8zP\xbd\xef[\xe0\\\xbd3\x01s\x9d\xf8\xa1/\xf9\xaf|i\xaf\x06\xc1\x03\xdc\xdc\xb5\xa6T\xedG\xa85W\x9be?\x84\x03W0\xcck\xea\xdb\x8e)\x0f\x19C\xe3\n3D\x9d\x12\x0f'\xb5\xe5sY\x0dr\xc0\xa9\x84\xd5h)\xf1\xf0\xc3\x9c\xd0^\x9f\xc7L5\xd4\xfba_\xa4\x90\xc1\x88g\x95 ~Fh\xa7F\x97\xab_\x03Z|t\x03\x8bo\x95\xa5\xf7\xb9\xe8M\x1dD\xb6%\xa9\xe9\xcb\xb5\xd4\x12\x01\xf5Uoi\xb8\xba\xda\xcd\x86\xbe\xac\xab\x92\x95\x94\xdb\x13\x98\xd6!SZ\xf1h\xe9\xaa\x06\x06\x1b\xaf\xf3\xcf\xd0\xa8\xc6e\xa6\x0b\x1d\x03\x16\xcc)\x95\xc1\x1e$H\xecdM\xd3\x91\xccl:\xd2\xf4\x93k\x81\xac_[\xe8\x89W\xab\x98)\x0e4\x94SZ\x83\x85\x83\x84\x9a\xbaZ\\?\xadod\xe9G\xea$\xedyq\x15\x11\x9de)%\xfb\xcf\xb2\xa4\x8c\x83\xa7I\x84\x19\xdc\xff\x7f\x0f\x1e\x9e\xce7\xb7\xbb\xf7t\xeb\xe4\x19\xc6\x92fj\x19\x9dL\"\x9c3\x1bx\xab\xdd\xa8E\x17\xdf\x92O\xfegj\x0d\xd6\x03E\xd9\x10(\xd2\xd8K5\x0dj?\xcf\xe9\x07\xdax\x16\x81\xce\x18.\xd0\x19\xc3\x05:c\xb8@g\x0c\x17\xacf\x0c\x17\xa8\x8d\xe1\x82\xda\x18\xae\xebd\x93r\x0f\x81-\xa5\xb1[\xf0\xe9\x8d\xdd\xcc)\xfe$c7\x15\xed'\x19\xbd(L\xde:\x9e\xc2\x83M\xdbn\x95Q\xf8\xf31\xbf\xe93\xae)jO\xe0\x1es\x11JPO-t\xde\xd98M.\xadc\x03}O!L\xeb%\xcc\xd7i\x8d\xf9M\x88\xe0\xc2\"\xeeX\x9a\x91\x99_\x08i\x80\x1dsI\x8e\\\xc0.\xd7>U\xda0\x86\x8e\xcd\xa7n}\xe3\xc2\xcf\xe20>3\x89\xffE\xdd\x89uW|e\xec\xfd\x94\x84\xb1m\x81^\xe8\x91\xe8{J\xbd\x97t\x16\x1d\xfa\xf3\x97kW\x86\x01\xc3Pd\xb9\xb9\xc9\xb6\x88\xa4\x94#5d\x0b#\x97\xa9\x1f\x07\xcfX\xbd\xbaoOzO\xcf\x9b:\x01\xd4\xcd\x1c!\xfb\x1c \x19_\xa6\xbf\xb3\x16\x9f\xe75\xf4\xef\x0e\x1a\x9f\xad\x83\x86\xc15C\xaf\xa8\x890\x91c\x97\x89\x02~\x93\x87\xde<\xc9\x96\xbe\xa2_\xee\x92\xc1\x03\x9a\xab\xfd1\x84K\xd7\xda\xde\x1eD\x18\xd9\xfb4\x8c\xfd\xec\x8a\xbd\xc1\xecB\xd6\xa9\x9f\x93\xddm\xf1F\xef\xa9\xc1@_\xef\xd2\xa0\xf4\xe4\xe0\x01\x12\xe7\xa12\xdd\x90\x84\xeaJ\x1eS\n\xf6\xc1\n\xe3s?\n\x03\x8b\xc9\xe0\xbbm\x86E\xd4\xfc\xa2\xd4\xd4\\E$\x9a\xdbU\xcaK:\xda|\xba\xa9\x08\xd2\xaf\x90\x07\x04a\xce\xd9\xdc\xc2\x0b\xf3g\xfc\xaf\xe6a\xf8\xcch{\xb7\xca\xbd\xdfL\xef\x0duR~\xe1\xe8\x9e+\xde\xd5u3\x92\xa7I\x9c\x13I\xea\x01R\xa6\\\xcd\xebJ\xde\xc3\xdbnEN\xd2\xb9\xcb\xc6\xf6}\x05\xd6\xd3\"\xb7P\x8b\xdc\x8c\x84R\x15\xf0\xacP\x06<\x8b\xab\x80g\x94\x88\xccX\xc0\xb3\x0c\xbe\x82\xe2\x11d\xeb\xeb\x0e\xc4\xd3\xac\x19\xf0,\xd3\x07<\xab\x15\xf0&\x92\xadJzwx\x95\x17di;M\xdb\\\xfc\xeb\xbb\x9cN\xc7HW1Z\x96\xd9e:v\xc6r\xbf2j\x96\xad8?\xde\x0d^L<\xad\xdb\xf6\x0f\xdd_\x8a\x8d\x0c\xcd\xd1J\x854\xb6\x80}\xc0\xd4\x18\xcd\x06\xacc`\x81t\x9b/\x95x\x0e)\xd5\xe7\xb1\x1d\xf3\xec\x05-XW\xc0]kl\n\x03\x88V\xd3Sag\xfa\xcc/|\x8b}\xe22\x85\x03\xcbZr\x8c}\xb78YWw\x18\xee\xaa\xffn\xe3\xa6\x81\xa8N\xeb\xdd\x8d\xa4\xd3\xba~(j\x84\xd2?\x14q\x1eT\xae\xcc\x98\xb8\xa1\xbe\xf0\x84\x0f\xb3\xd6\xc9:\x91P\x9b\x9are~\x00Ul*\xc59\xc6\x80\xa2\xfb0\x0d\x11|;s\xc2\x98\xcf.\xc4\x02\x94\xf5\x15\x9a\xe7\x0bH\x94\x13\x15S\x8b\xbc\x96\xa6\x9d\xa2\xdb\x8ei\x1b\xb3a{\x93\x0f?\xc8\x9f\xc9\xa6\xc4C6\xc5\xbc#\x03\xb7#6n\xc7\n{\x11W\xaa\xb4\xcc{\x9dq\x17\xf5\xd4\xb1\x1d\xe5\xd6t.\xed!\xfb\xe3Br\xbb\x9d {w\xc6\xef\xdb\x99\x84\xc5\xddeq>\xf7k\x84\xe2\x9b6\x8a%#\x17\xa8G_M\xb5e\x08Mn\x9d\x82\xa8\xa7\x89G\x9de\xa3\xb4}\xa2\xbcrl\xdah\xac\xd9\xb6\x81\xb1\xbai\xeb\xa5\x97\x914\xf2g\xc4\x8e\xc9\x05\xbc%g\x07\x97\xa9m\xfdb\xc1:`D\xc6k\xcb\x05\xeb\xccr:*9\n\x11\xa5\x04\x1f\xf8\xf3\xf7\xa5+\x95\xca\x8e\xd2\x8e\xedqG\n\x1a\xf2\x92Q'4\x0fSX\x8c\xb7v\x95T]\xf9;\xb2\xac\x14\xfb\xfer\xed\xb6\xa5\x82\x99\x0b\xbe\xf7\xee\xcd\xb3'G\x07'\x87\x07/\x0e\x9e\x1e\x1d<;9}\xfd\xea\xe8\xe0\xd5\xd1\xc9\xd1\xdf\xde\xfc\xfbZ\xaa\x88\xe0\xd5\x16\xf5\xf0\xcd\xebW\x87\x07\xbf\xcf\xaa\xeadR\xaa\x98\xac=\xeb\x91\xb8\x10\xeaH\xf1U\x16\x84a\xaf\x93\xef\x9f\xbc}\xfe\xe4\xeb\x17\x07w{du$\xc4 \x0c\x16{\xef\x89\xc2\xa8\xc5\x17K\xad\x069 \xef)\xef\xfe\xcc\x85\xd0H\x11b\x05\xe3V\x94.\xf8\xcd\xf5\xcdnq%\xd72\x8fQ[\xbd\x97\xf0\xd7;\x0f\xa4\xfb6\xa1\xcb\x82y\xf4\x92\xec\xc0\x9f-l\xbdh\x01\xe9>\xef^\x18\x07\xe4\xd2\xfb)gr?-\xd5Gw4\xb1U1\"\x88G.\xd3$+\xf2)#\x80R?\x9f\xf9\xd1S?'\xdf\x84\x11\xa1\xdb\xe8\xd8\x85s\x8c\x1b#.\xd1}\xe9w\xdbAH\xba~\x07-\\loo\xefR\xb2H\x8c\x03\xd7eg\xb43\xe8k\xc3\xb2\x0b\x1b\x8d\xad\xb1L\xd0\xd4\x11\xbd\xecU\x0c5*Z#\x93\xa6W P\xdfd\xc92\xcc\x91r\x89\xed\xed\x9d\xfb\x8e\x0b\x87H\x91\xd7\xa65^^\xf8Y\x91\xff\x102\x0dIlo?\xd8\x1d4\xc3\xd8~8FM\xef\xc3\x07\x9dU\xda\xde\x19\xd6F\x1fpno?TB\xe7\xf6\x8e\xca\xc0%\xb6\xef\xb7_3b\xef\xfeHZ\xe9\xe6H\xc7[\xf7\x1d\x1b\x05n.X\xf8\xaf\xd5\x83\x87P\xbbt\x82\xd2;\x9b\x08'\xb3\x13\xda\xff\xa6\xf8\xe3=ES\xf5~\x18\x92x4T\xa6'\n!|\x15\xac\xe0Da\xd7\x18W\x85\xe1\xfa\xba\x12{\xac\x11\xdcTxL\x19\x94J\x9cm\xd7s\x10\xa2\xb9\xc4\x1e\xa1MzB\x0f\x9bE\x0f;\x8b\xd3\xc6\x8d\x0cYZ\xd9\xfa\x1d\x992\x99C\xec\xe2O\x89;\xbav\xab\xcah]\xf3D\x08*Q\xd7\xc0W:\xb3Y\x17\x0e\xfe\xac\xabg\xb6E\xe2\"\x0b\x890\x9co\xc3\x8f\xbc~\xf2F\xca\x0b\xac\x8e\xd0\xd8\xfb\xa5j\xaf\xf9*\xaaP\x17\x8b\xb9\xda\xdd\x93 \x89)\xdb\xb2f\xa6\xfdoy.F;\xeas\xf1\xb0\x1d\x95\x91\x1d\x8b\x87m\xc1\xb6\x8f\x9c\xc6#\xe9,\xeflb4\xf3\xd8\x1e=tl+,H\xe6\x17\x98CV\x0f\xbb|q(,\xd5\xb3k\xa1\x82>y\x1b\xa9\x11\x11\xc6\xef\xf6U:\x9e\x98\\\x16\x142Gn;u\x00\xed.\xc4\xb6)+\x0b\xcf\xaba\xaf\xb6\xdc\x12\xc2Q\xdf\x86[\xbb\xeau\xdd\xd5\xe2\x95\xedm\x07\xf6\x95\x9coHr\xe81@N\xecv\xa2\xa1Jk\x10\xbb\xb8y!\xaa\x07\x90\xda\xadT\x079S\x16\x94\xf0\x18\xf2G\x0ed\xde\xdc&\\\x182\xcd\xd7\xd7\x8f](\xa6q[\x08!\xa8\x8c\x9b.\xd8\xfd\x91\x9a|\x18\xa9!q{g[\xb3duw\x1a8\xab)\x0e\x96wFGQ\x94l%\xf4q-#$9\x84\xcaES U\xa3\x14\x1c#\x05iBI\x1cv\xa9\xc2\xda\x9e\xde\xb5\x117\xed\x11D\xf0\x18f\x8f\xf46\xc0\xb45\x9bne>\x9d\xad\xaf\x1f;\xb4\xcd\xd2\xa9\xcdU:\x1f2\xe1S\x7f\x970[_\xef\xe9\x16\xaf\x87\x19\x841\xe4Ho\xe4\xd3\xd91\x0b+\xea\xd4r\x0f\xac\xf2\xe1\x03j\xa2\xaak\xe5\xcb/a\xa3\x19\xbbhE\x1c'a\xb3]\xd5\xa9{\xe9\x17\x0bo\xe9_v\xc1\x88\x95\x84q\x1f \xe9\x11\xba\xcd\xb0\x0dq\x1c\xf8\n6a\x9f\x9e8X\xa7C\xdc\xa4\x97 C)7F\"\xea\xf9P\xac\xbds'\xc0\xaf\x83\xfc\x10\x83\xb8SHbD\x9eM k\x0d|\xb3#\xa2\xf3k\x8dPp\xc8\x0e\x88B+\xc1\xc6\x94\xe3\xda}\xf8\x009%/\"\x14\x87\xf1X\xb4\x9c\x9a\x9d\x80\x8dr8o\xb6\xf0\xb3\xa7I@\x9e\x14v\x8ek\xbe\xb33~\xb8K\xbf\x0d\xe11\xec\xecn\x8d\x1e\xb2\x86\xd6a\x84\xe0\x87\xb6\x04\xb6\xdf\xf9\x98V`\x0d\xecn\x8d\xb1s\x9f6p\x7fk{\x8b\xf7\xcf\xeacGt'a\xc2\xdf2/\xbd\xdc\xc5N\xc6\xb4\xcc\x87\x0d\xde\xcc:\x1d\xe7\x06\x1f\xd4W_\xc1h\xd3\x81u\xd8\xdd\xd9\xd9\xda\xbd\x1b\x08\xef\xdc\x1f\x1c vu\xd8\x90\x02\x8b\x83\x12e~\xa5\x0d\x8a*\xdc\xbd7\x90\x19\x13\x1f\xb6\xc4\xf0\xc5\"K.\x802\xef\x98%\x1dO\x80\x05a\x0eqR\x00R\x00\xa7\x11Y\xd3X~dv\xc1\xa2\xf0\x11g\xc5sB/\x81\x07\xc88\x8c\xb7\xb7\xf1\xdf\xed\xdd\x87\xec\xdf\xfb[\xec\xdf\x07\xfc\xfd\x83\x9d\x0eg\xb1\xbb\xe9\x08\xaefHg\xbd\x84\xd4\xaejgd\xd2(\x99\xc6\xf6\xe8\xbec[E\xc2N\xd5\x91\x7ff!\xdbi\xfdlQVn\x9d\x82\xfc\xda\x1eX\xd3\x04o{\xf8\xf9\xd8b\x0c\xd7\xfd-\xc7\xe6\x14@\xed\xc9\x00UCV?mU\xb5\x89\xe9j\x90l\xa7\x90i\x1dK\x1ah\x0c\xa94d-\xe4\x85\\\xa3\x1c\xfe\xa6\xc32\xac\xd8\xa3\xcdQ\xbf\x0d\xf5}:I\xb5(\x9f\xae\xe3\x03\x87Y\x1e:.X\xbe\xd2\xfe\x10\x83ik{i\xf7\xd6)l\x99\x088\x9e_\xaf\xc1\xa0\xf9KDK?\x11\xa2\xb8;0)\x0d\xbb4\xc4\xd5\xf8\xa8s\x0c\xd5z0Le#\x9d\xc3*\x02\xb6\xcdTG\x02$\xd8\x86d6\x13U\x89\xf3U\xf5\xa7\xd2\xb0\xe9\x1bE\x1e\xe5\xf5|\xf56\xd7>\xcep\xdb\xf8\xc6z\xea\xc7\xff\xb1\x80Y\x12\x9f\x93\xac\x00\x0e\xe9E\x02i\x16.\xc3\"<'\x8c\xcdZ\x95\x9a\xef;\xf3\xdb\xbbm\xc91\xc3\xc6\xe3\xed-%\xcd:RJ\x15Z\xec\xd3\x03\xc1>\xdd\xff\xef\x99}\xd2\xb0\xa5\xdb\xbb\xea\x95\x1dw\xc48>\xc7\xca\x94 }~p\xf2\xe6\xed\xeb\xa3\xd7\xed\x80\x15e\x9b\xdfo\x16\xb7\xc5\x01\x9d\xf58g\xb9+\x0b\xde\x15E\\\xe1<3D\xc6@+\x0c-5\x84$w\xe1\xa1S\x90\x17\x84y\x1a\xf9W\xf4v\x88\x93\x18\xf3E\xdb\xe3\x9d\x11\x9a\xf5\x938x\xba\x08\xa3\x00Y\xb7\xc2\xcb3\xcacX?\xf9\xe7>\xf3\xe9\x9dXU\x16J\xee\xfb\xf7C\x18\x07\xc9\x85\x17$3\x14\xa18^\x92\x92\xd8F\x18\xb9\xc8\xc2\x82\xd8\xd6W\xec\xd3\xc7\xa2\x8a\xf7\xcd\x1eC\xd1_\xfdx\x8f\x17\xa1j\xd7\x9bEI\x8e\xe9\x0ds<\xc1\xdf<\x82lc\xe3\x91\x03\x01\x89HA \xaf\x01i\x1aN\xb3c\xbdMYn\xb7`H\x8dI\xf9E\xc1,8)\x9dfD\xad\x889\x95tF\\F\x11J\x90)\x15g\x97-x'\x0ecpcrA\xf9\xbef1s\xff\x8aYZ^\x82\xa6g\x98\xd5\xc2qei\xab\x90p%v|+\x9a\x7f\xa46\x1e\xec\x9c\x08\x0e\xf9\xdb\x0f\xf4\x94\x1f\xbd\x98\xff{\x90\x1d\x8cF\x0f\xd4d\xf1\xb8\x8d\xa0\xb9\xf0`w\xd7\xb1\xd7\xda\x02\x075\xca\xb8\xc1\xfd\xce\x97\xa8\xe4\x84t\x17\x17\xe0\"u_Sfiz\xacX\xf3\x98\xf2\xd5\xa5\xc3\xa4\x04>\x8a\xf31%<^\x9b\x91\x88,\xa4\xf8\xf0\x11\x14BX\xcb\xf7\x03\xbf\xa3\xa8\x01w\x83\xb9\xa8\xfc\xa7\xd0\x8e\xb0\xb5\x0f\x1f\xea\xd6\xd4[\x14\xddt\x8b\x1e>\xd4\xac$\x83N\xdb\xfa\xd9r\xd0\xd5\x82\xd2\x81\xcf\xf3\x83\xb8\\2\xbe\xc1\x96`\x18L\xe6\xd1\x82\xd2=\xac\x93\x83\xd0s\x8d\xe6;y\x1a\x85\x85ma\x8e}\xde!\xb9\xf9 \xed@\x95\xd0ti.\xa7m\xdd\xdc{'\xd3\xe0\xd6\xff]T\xf5\xdf\x92\xa8J\x83\xb2\xb6w\xdb\xef\xc3\x01\x94\x8c__\x94\xd5\xc5e\xbcN\xcfH\xf1FT|=o^\xab\x1aX$\x02\x9d\x01fp\x0e\xf1dMQ\x1b\xad\xa2\xf0)\xa9\x90\xc4y\x91\x95\xb3\"\xc9\xd0\xe4 \xc28/\xfcx\xd6-\xddo\xfe-\xdd\xbe\x93\xe6g\x1c\x0f\xec\x83\xdf6\x00_q\xfdw\xb6nz&9\xfe\xc8V\x17XT\xf7'g\x1f(;P\xb1\x0c\x0f( \xcd\x98\xca-\xc7\x15\xde\xf0[\xfc\x82E\xc6\x80'\x8f\xb5G\x9bc\xc7\xe5>\xb5\x94Z\xc0\x83\x1b\xb5\xb8\x05\xf6\xaa!kp\xd1s6\x17\xba\xb3\xa0\x13m\xe1\xe9\xe1\xe1\xdb2\"/\xc2\\\x11\xec\xe0\xe9\xe1\xe1!%M\x9f\x91Y\xe4\xb3x\xd3\xdd\x80 O\x0f\x0f\xd1\x14\x817\xd1.\x8dB\x12\x17o\xc9\xacP\x97?{\xfd\xd2X\xc8\xe6\xa2->J\xde\x93X=\xf8g~\xe1\x1fe~\x9c\xcfI\xf6\xbc Ku\x1b\xdf\x84\x91f\xe4\xdf\x1e\xbd|\xf1$\x8a\x9e&Q\xc4\"P\xa9\xab\xf4\x95\x7f\x93dK\xee\x85\xa4\xae\xc0\x9c%\xb4U^\x92 \xf4\xd53|\x19. e\x89qs\xbb_\xbe\xf2\x97$x\x95\x04\xe4\xa5\x9f*J\x93@\xb3\xebo\xfc0\x16\xe1O\xd4K\xf3&*\xcfB\xc5|\xd9{\xcdp\x0e\xbf\xff\xd3\x0b\xbc\x8a\xd4m\x1e~\xff\xa7W\xe5\xf2\x94d\xda\xe27\x98%X\x03\x0b\xb4< c\xcd\x80\x0f\xbf\xff\x93 \x90\x0e\xbf\xff\x13\x83\x94$\xd3\x80\xc9!f\\\xfb\xba\x9c\xcf\xb5\x03\xa4\x07\xe5pAH\xa1^\xd5#rY\x1ce\xfe\xec\xfdS\xddQ\xa9jh\x8a\x93rV\xad]Ur\xed\xa2+zb\x07\x945a\x94\xf89|\x05\x0b\xc1s\xc2\xf9\xfa\xba\x8aZ]\xba\x18\xc9~1=W\x18\xbcQ&4\x98\x9e)JN\x91\xacW\x95\x9c\xc0\x1e\x9cR\xa4\x7f\xaa\xba\x90\x80_\xc5'H~\x9e\xd0\xfb\xf7\xc3\x07(\xed\x13\x17f.\xa4\x8e\x0b'\xd3y\xfdn\xee\xc2\x19E~\xd33\xca\x80\xa5.\xa8\xe2\xd2 r]\xd2[=s\xe0d\xba\xc4\xcfC\xfa\xf9\xd2\x85l\xba<\xae\xc5\x9b0\x14a\xf7\n\x804J\xcb\xed\xfbj\xbe\x03\x11w\xe3\xbd_Q\x94:&n\xbc\xbd\xfb\xefv%\xff8v%z\x82\xef\xbec[e\x9c\xcf\x92\x14\xbdU\xda$\\\"\xfc\xf5T\x07\xa6\x123@2\xcd\x8e\x99R`\xe7\x01\x1a\xaff.\xfc\xa2\x97\xf6u\x98\xfaiv<%\xf4\x18\xc9\xf6\xf0\xca\x99\xe8$\xfeF\xd8\xfb\x0c\xed\\\x84\xb1\xa9/(\xa9\xf1v[\xc2\x92W\xc4V\xe35\xa7\xb0\xc6\xaa\xb8%*\x8d\xcf\x9c5\xdf\x16\xd4\xb0p%\xf7\xb7[\xaf\x03\xdez\x1b\x85,8\ni\xd7?\xe7\xef\xdb\xf6\x10K\xd6\xebN\x1b\xb5\x9c\xf1\xf7[\x8e\x97\x93\xd6\xba_\xb1\xb6\x1elvb\xe1\x9dr`m\x8f\xea\x84\xb7\xd6\x1e\xd5\x05\x7f\xdf\x1e\xd5\x01R\x9a\x95\x8c\xbeYx\x89\x85i\x96\xccH\xde\xf2D?\xc4\"\xae\x98k\x16=\x85=\xb0\xf8Gx\xceg\xf6e\xab\xd7\xf7f\x89\xee\x13\xb4\xb0\xdd\x83So\xde,xM\x0f\xc4\x9aY\xda[dW\x1a\x9eW\xe0\xc8C/#y\x12\x9d\x13\xbb\xbdz\xf2\x83\x1e\x1aM\xf6g\x8f\x1ea\xa1\x1e\xccS2C\xfcr<(\x1b\x96x\x88\xfd\xde\x85\xf7z\xd6\xf7\xba\xcb\xd2\x83d\xc7\xf0\x14\xfdQU|\x1c\xdf\x8b\xb7\xe4'F\xd9\x1e\x9c\x93\xb8p\x98\x0fK\xb1 \xb1\xfd\xde\x919\xb4\xa2\xd3\xcd5\xcc\xfcb\xb6\x00\x9cCK\xf9\xd6\x06\xbf7\xbdsF\x15\xb5V\xa8\xbcf\xaf\xa5\xf4\xbb\xe6d*m\xb5\xcd\xe21\xd0a;8\x85\xe6h[\xe0r\xd4\x87\xed@\xe8\xb9\x88w\xa2\x95\x88\xd02\xc4\xb7\xea\x0d8\xe7\xb6\xcb\xc4;\x99\xa9k\\\xe95\xaa\xf2\xd3\xe0.\x89wr\xcex\xcb\x11`\x8c\x9a\x93\x9c\xb1\x97\x9b\x8c\xb5\xac\x05K}p\xc5\x85\x995\x02M`\x1f\n/y\x0f\x13(\xbc\xb9\x1f\xf6\x84@\x87*A\x14?\x1c\xfd\xd5#^\x9d\x02\\\x7fm\x9649H\x96~\x18\xab\x17P<\xfa\x13,?%\xa5?\x124\x1b\x19\xf3\xb5[PP\xf9 \x89)\xfck\x0fF\x8e+\xe2\xff\x94H\x81\xec\xa1I\xb5\x8d\x81*f\x1e\x89\x0b\x92\xd9\\\xa7P\xda\x19\xf2\xe8\x98\xa1\xd8#\x97aas\x06\x7fm\xd3au\xf6\xd0\x1b\x81\xdbX\xefCd\x1f\xd8\x16?w\x1b\xb3\x85\x1f\xc60\xbb\x9aE\xc4B\n\x08Ma\xde\xd8\x14\x82\xf7!d\xda\xd2\x18\xfdK\"Z\x9cc\xc9\x04\"[\x91\x1dP~\x1a\xe7\xb2wYp\xfck>\x9f\x1f\x9fDd\xf7\x84\xdf\xbc6\xe0#\x88k\xd9t\xf8\xc8\x01\xdf\x8e\xa7\xe1\xfaz[9 ?\xf4\x90\xa0\x90\xdc\xad\x8e\xd5\xc8\x05\xd42\xaf\x89}z\xa9\x1b\x93\"z\xe6\xb5\xe9\xf8\xbf\xec\xc5Egl\xf1s\x03\xfd,\x1eD[(\xc4\xe5f\xfbxB\xb5\x13\xa5[\xfc\xbc\xa3\x80\xa9J\xe7\x14\x08(|\xc0C\xe0\xf0\xa3c\xea\xed\xa7\xde\xdeV\x85_54\xca\x80U-\xfa\xb7l7,\x01S\x05\x87\xa9\xaa\x02\xdf.v\x0b\x9b\x92u\x0e\x00'\x01J\xf4L\x0d>\xfa\xc6\x9dz\xd5\xbbv\xc2T\x8er\xaa\xddu)\xbc\x93\x00\xaf\x10\xfcA1\xbd\xcb\xd6\xa0\xf0N.hA\xe1x'\x94\xa2\xa7d\x85wB/\xc81\xfe\xf2\xc5W\xccG\xfdd\xc6\xed\x0d\xe9Eqd\x17(\xc40\x8e\xfc\xed\xb0\x91\xbb\x15o\xaeV\xf5\xac\xc5\xdeI\xa0\x03\x86\xb8\x9e\x14*\xcd\xf9\x9c4\xd7\xaf\xf9\xda\xa5\x9d\xb1\x1b\xb0:X\xf5\xe5\x073\xb4\xec9\xa5\xa7\x19\x89\x87\x00\xc2\"'\xd1\\\x97?\x8f>\xb8\xceo\xd0\xbcj\x7f(\xf1\x04\x12\xaf\xde\x7f\x17\x9e\\L\xc0\x90l\xb1\xaa\x16h\xd3\xb2\x8aGC\x95\x8bg\x18\xc5\"\x0c(\xe9}\xfc\x16/\x98\x11\xde\xcd\xaf\xf8\xef\xbb$\x03^\xb1\xbe\xb2\xde\xc0\xdb\x86\x9b\xdf\xa1wL\x05\xfe1\x03\xff\x11\x85\xef\xd8\x855\xddx\x87\x8d\x93\x8f\xcf<\x91\x01\xfb\xd7\xb3w\xd7\xda\xf9w\xe7\xdd\"2\xea\x1d\x7f\x8dg\xfd\xd0x`\x17<\x82\xe7\xa1\x0b\xe2PX.X'\x0b\xcbq1\xd4\xa9\x0bY\x9d\xc5\xbau*\xd4\xe0Cl\x04\x13\xd6n\x05)\xe2\xcf\x16r1.\xfa\xabf\xfe\xec\xe6\x97\xd5_\xd7.\xbb\xc4\xf5\x93d\xd2>A\xd9\xb1\xbf\xe4\x9b\x97\xbd\xc9e f h?\xfc\xeb\xbcSy!Wf\x84b= \xa7i\xdeco?\x189\xf6\xa1l[\xdb\x1e\x1f\x89\x07\x84\xfa\x17\xac\xdc\x13{)v\xcd\x9cS\xfc=\xec)\xd9T\xa6\x7f\xc6\xb3A\x19\xacf\xad\x9a3G\xba\x97br\xce\xfd \x19C\xefb\xfe\xe7\xa4\xb5&\xb3*\x07U\xb5\xc6\"Y\xcc\x89\xdf.\xcbi\xd9\x11\x9f\xc7\x1a\x05\x93Xp(\xcd}n\x9e#\x04\x97\xbe(v\x92\xc5\"\x13!\x88q\xeaa\x88kG{\xe5\xd41\xb9\x80\xecQ\x17\xba\x04U\xc8n\\\xfa\x86\xdf(\xa8'}\x8b \xd5GNU\x84Z\xe6=v2\xb0D\x86\xe6SoNwy\x88\xb2\x98\xe0\xcdv\x88\xdb\x89?}JA\x93\x0b\x16\xf4m\x82\n\xf5\xc6$\xe7\xf6\xdc\xfb\x13\xac\xc3\xdc\xfb\x01\xff\xff\x0d\xfc\x11\xd6^\xb7\x01\xf2\x8d \x8a\x0e\x1b\x1f3\x13S[\xc6\x15\xdc\xfe}\xec\xd8\xf2+\xa6v\x90L\xe0Y\xc7\x87\x8d.%|\xd3\x9e\x1b]\x9e\xbeM\x16\x04\xd2\x13\x15f\x02I\xf4\xb4\xe9V\xdc\xbe\xc3\x14\x16j@\xeb\xacS=\\\xbb\xa4+\xbc\xf6\xda1\x8e\x1a\xf7\xbbo\xd8|T\x17v)\x0eG\xb5o\x870\x81>\\\xd7\x19\xda\x9a\xfd\x9a\xc9\xeb\xb7\x1fl\x99\xa2\x85\x1ez\xcc\xea\xd9\xc3\x13d\xbf\x97\xc1\xc24-?\x8a\xfa\xa6$\x93\xaa\xea[\x8fa-\x9d\xf1\x10\x8b\x86`\x14\xdf$\xbc\x8a^d\x13\x0e\xe7T\x05\x1e\x9d\x1a\"4\x03o\xd2\x90$\x1f\xb8~m\xa4\xa7\xb1\xce).\xa7\xd7\xc8p9\xeb9\x0f\xb6\x14\xae\xaf\xf7S\x80\xe8!a\xe8\x1f\x90\x98F\xcc\xcbP =\x9b\xeb\xebn--\xa3\x10\x81(r\xf8\x08\x01;\xa6\xa4E.\x88\xf4iy\xcc0\xdf\xc6\x062\x18\x99\x1d\xf7Q\x85Z\xa6\x198\x98KM)\xeb]\xeb\x8f|\xe8\xa1-Ub\x87\xde\xf9\xd0\x8b%\xf3g\xbdg\xf7\xae\x00]\x0f\xc5\xc9\nP\xbc:luw\xbd>v`\x90\xe6i\x93\x08jw a;\x90\xd9\x89i\x07$\x14\x84?o\xa4\"dB\xaf\xf6\xd4\x91\xc7\xb4\x1b\xb6]\x05\x8a\xed\xb9\xaasmo\x0f\x98\x84\x07\xc2\xb8f\x0dk\xa7\x8f\x18\xd6\xc1\x9a@\x18\xcf\x92,\xa3\xb7u\x18\x9f'34K\xd2\xb9\x9a\xdd\xdc\xbe\xb8\xa3\x02\x14z~\xb5;\xf7\xf6}\x95\x9f\xbc\xc2\x86\xbb\xe4f\x01m\xcdc\xce\x9bi\xdb\x02F,\xb0W\xe3\xdd\xac\xe5C\xc2u\x1c\xa6\xdd\x98\xbb\x90\xaa\x08\xa8\xc0\x85\x85\x0b\xe7\xae\xb0\x07Ia\xbf_2\xd4Y\\\xf1\\\xa30Ze\xff|\xc5|Fq E-p\xeb\xd4;E\x13\x96\x0e\xdc(I\xe6\xb3\x9b\xfa!\xa20\xd5>sT\xf3C\x9dJ\x802|a\x9d\xe0<\x82\x00\x1e\xc3\xe9#8\xd5Y\x9a\xa2\x95\xe9\x92\x07\x8c\xbd\xb2}\x9b2#dzz\xecL7\x8f]XLG\x18+\xf0\xca\xc6wN\xed\xa7\xba\xc4\x9f\xb3\xca\x0cu\xd9<\x8ej\x13X\xa6\xf7\xc1da\xdcq\xea\x11\xaca\x97\xe7^L.\x0b\xdbq\xbc \x89\x89\xc6\x1a\xb7\x1alb\x9f\xbbp\xe5\xc2\x82\x07\x82\x82b\xd8\xd0\xae\x1d\xef\xeb\xb7\x07O\xfeL\xc9ezq\xbd=8z\xf7\xf6\x15\xec\xc1l\xb5C\xb6\xd3o%-\xe07\xe90\x90JFW\xe0:\xd8\x87\xc2\xa6\xf7\x14.\x7f\xcc\x97\xbfh_\\\x15\xafk\x8c,I<\xd6\xacB\xe6\x87\xe0'\xe1\xaf\x90\xa1\xd8\xb0rhs\xdb\xfa\xc6?4\x7f\x0d^\xab\xae!QR\x1b\x99Hf\xa0M@7Y\x98\x0c3\x1f\xe1+*\xcd\x11\xaf\x11;cv3L\x8c\x87\x86W\xd3\xe4\x98\x0b\xf5n&:\x8d\x1c/a\x98\xc3NuY\xa1f\x0b?\xf3g\x05\xc9\x9e\xf9\x85?Q\xba\x94q\xfb\x9c\xde\x85H\xbd\xc0/\xd0j\x8aNe\xde\x03\xdfJ$\\\xf5\xa1\x9a\x85'\xde\xdc.\xd0TOA\xf0a\x82\xb4\x12\xb9\xe0\xaeK\n\xac\x1aX\xa5\x90\xe3M\x88\xa7u\x14nLo\x18\x89\xfc\xa4%U\xed\xde\x7f\x82Y\x9b\xde?\x9ef\xc7m,\x1br\x16\xae\xef\xec'M3y`\x13`,\xd4\xac\xd3q H\x04\xe3\xaaB:\x1d\x1c\xc5\xd3\x12t\xfc\x01\xb8\xf3C#t\\fg\xde\x1bX\x87\xcc{kP1\xcd\xc3\xd8\x8f\xa2\xab\xa1\xd2w\x9f+\x8d\x93*j0\xe5\x88\xc5\x1f\x1a\xd1{\xacSr\xab\x92\xd9\xb4\xd5\xc7\xb1,\xa7\xd4\x1ab\xf3\xcfJ\xcchj;m\xbd\x8a\x89\xcc\xeal\xb4\xfc\xa8\x8c\xcb(\xebF\xa9\x8b\x8f<.\x86`V\x1b\x96^u\xf9\x11\x81\xb7\xebP\"\x02\xf7l\xb7\xc0\xf1\xd0\x00\x88E6\x18\x08\xf1\"\\\x84\xb9\x01\xdcB\xa5}\xad\xd0J\xc7\x1eACwn\x0b0\xa9\x953\x8e\x1d\xa3\xd2\xa4_M=dAc{\xfb\xc1}\xae\xa5\x7f\xc0\xff}\xd8\x8cj\xc7\xc3co?\xe4Q\xed\x1e\x8a\xf7;\xfc_\xfe\xfdC\xfe\xfdC\xf6\xfd\x0e%G\xf0\xdf\x11\xffw\xcc\xff\xdd\xe2\xffn\xf3\x7fw\xf8\xbf\xbb\xfc\xdf\xfb\xfc\xdf\x07\xfc_\xde\xde\x88\xb77\xe2\xed\x8dx{#\xde\xdeh[\x19e\x8f9\xdb\x0eY\x8b^0\x1aw\xc2x\x87U\x90J\xbc\x92\x9f\xf2\x10\x8f]\x94(WJ\x02\x82\xfe\xc1-\xc8CD\x88\xe6\x04k\xcc\xd0}\x84\xf1V\xaa\xa0\x19Ul\x91\x0e\x82\x94\x1b\xed\x83\xd0:o\x9f+\xb4\xdc8\xe9n\n?_$\xed{\x0c\xbeVL\xc0\xa2\xc2\xed\xc1z\x9d\xc8\xcf\xc78; \xc5'\xa3\xd1h{4\x1a9\"v>C\x18o\xfd\xf8\x8c\xebH\nYG\xe2\x03\xa6\xb3\x84Y\x12\x10H\xe9dtv\x96\\i]\xc0W,\xba%\xecc4 \x0cy\xca\xa2_\xae\x83m\x17\xb0\xb1\xc7\xca\x1dx\xfc\x18\x10~\n\xf8\x0f0\xda\x1co\xc3:\x8b\x99\xd9\x9b1\x17$\xfc\xcb\xb3\x0c[\xb7\xc3a\xbd`\xa6\x8b\x1b4\xda\xdcR`+\x0dPd\xfe\xc5pP`\xb15\xbc\xcc\xbf\xe0LiX\xcbnM\xe0A\x81\xa7d`\x12\xc3c(\x1f9\xc0-\xb9x\xe4\xd6bZ\xae\xaf\x1f;\x18F\xe2+&kiV\xa8\xc1\xa6<6X\xab\xf9w\xb3\xf4\xea\xeb\x83\xe2\xacM\xc7\xb6\x8a,\\Z&\x85y\x9b\x9bV-\xaa`\x059\x15\xb2u\xbb\x01\xf7\xc2\xca\x8e&\xd6\xdf\xa6:\xbc\xd4\xf6\xc3\xf6{\xba}\xd6\xd4\x82u\xf0YD\xce\xaeXS$\xdb\xfa\xff\xd3Z%\xff\xcf\xfac\x9b/\x8a\xea\xaau\xa5/\xda\xb5f\x03\xb8o\x90\x85\x12\x8aT\xb2\xc0\xc7\x1d\x0e#S\x04k\xb2\xe6O\xc9\xb1\xcd\xbc\xf3~\xfb\xf5\xff\xf8\xb7\xff\xc2\xe2\x9d\xf2\x9fX\xa6l\xe3Zs\x8b\xd3\xb5I\x98;s\x89J\xbe9\x86\xe3\xed0\xca\x807\xfe\x97_\x82\x9dLcZ;GWnA\xfbR\x94_\xca\x07\xb9e\xf9\xd2Z\x809\xec\xc1\xcc\xa3\xb0\xda\xc7\xa0\x81\x04\x8er0eT\x05\x8e\x803\xef6\xe1jE\x96]-w\xc1\xc2\xbc\xeccM\x85HTh\x11\x1ej\xc1\x82Z\x0b+\x8fT\xaem\xfdX\xfc\x18\xffx\xfe\xe3\xfc\xc7\x0c\xfe\xed_\xff\xeb\xff\xf5\xeb\x7f\xfd\xd7\xff\xf3\xb7_\x7f\xfd\xed\xd7\xff\xfc\xdb\xaf\xff\xc3o\xbf\xfe\x8f\xbf\xfd\xfa?\xfd\xf6\xeb\x7f\xf9\xed\xd7\xff\xf9\xb7_\xff\x97\xdf~\xfd_\x7f\xfb\xf5\x7f\xfb\xed\xd7\xff\xfd\xb7_\xff\x9f\xdf\xfe\xf3\xff\xfd\xff\xfe\xfa\xeb\x8f\xe5xs\xfc\x00\xff\xff\xf0\xc7rN\xe6sk\xc8\x19\xbb!M9\xde\xde\xc1(n-vF\x8f\x91g\xe2\x8a~\xd2{I\x0b\xd5q\xafm\xf3 $r\xc3 \xea\x02\x8a\x8d:\xe1%(n\xb1,\x8f\xc4\x01\xe6_Q1x\x14\xc8\xe9\xa7[\x8em\x89z\x96\x81\xa6\x11u\xfaVJ\\_\xa1X*\x17\xe4\xf6\x95\xe76V\xdcg\xf0\x18F\xb0/\xa5#\x1e\x1d\xd7\x06\xcc\xcaV2\x96\xf1\xc7\x1c\xd3\xacl\xe9Iy\xee\x1b\x11\xf9\xddN\xd0\xe493 \x18~j\x0d\xbc\x82O\xc7\xcdM\xe1\xd1\x0f\xb3DM \xf7\xdc)a\x03\xeaK\xbbd6\x15\xf9\xef\x02O\xf7\xc7J\xde_\x06\x8d0\x9eEe\xc0\x82]\xe8@C\xd4\xe9\x03\x8d\n\xed\xff\xa7D\x02\x8e\xba\x07\x0fS;\xbd\xc6\x08\x91\xab\x80\xc3\xed\x0ecc\x99\x06\xe3\x8e\x8c\xa4\xc4/&x\x83\xef:+v\xd9\xb7_\xa3\x91\x96\xb6\xb8\xa9\xb4\xb8\x0e\xdcO\x99`\x05x\xa3\xc0E\x91\x89>\xe4\xf1P[\"S\xf48\xe5a\xfaC\xd8\xdb\x83\x11\xdc\x83M\x05Ca=M\xca\xb8\xa8\x1d\xb7br\xe6\x17\xe19is\x12\x0f/\xc9\xdd\x0f\xbd(>\xc9\xd8\x93\xb8\x98%\xd1\xc78\xb2\xb4i:|\xd1\xfc\xc7<\xb6\xb4\xaf<\xfc\x99|\xbcY\xf0\xd6?\xe6$\xc2\xc2\x8f\xc2Y\xbe\xd2\x1c\x86L!\xfc\x14\x80\xb42\xf2\x19\xb4\xfa\x88\xf6\x17\x19\x99\x7f\xe4\xa5\xcf\x97~\x14\xad4\xfc!\xa3\x17\xad~\xf4\xc5\xa7\xef\xdf\xaf\x06\xfc\x83\xc6/\x9a\xfd\xf8\x13(O\xef~\xf4\xe5'\xc1\xfey\x99~\x84\xa1\xa7w4\xf4\xd8\x1e\x8d)\xb9\xbc\xf4\x8b\xd9\xc2rad\xae.\x0dfZ\xd5S\x8a?\xd5k\"\x1e\xc1\x19\x10\x93\x921\x91e\x0f(z\xa8\xd2\x99\xc5\xd3B\x9f\x19C2\xafO`_\xd8\xe11/\xaa \x9a\xc0q)o\xecL\x8bc!\xc8\xcf:qA >\xbe\xe1jrQ\xa3\xe5\xc2\xf8\x06\xeb\x99)<4`\xd0\x92\x86}K\xea7\x964\x93\x974\x1b\xb8\xa4\x12?\x91a\\\xb3\x04W\x95\xbd\xe1k\x19:,N\xd3\xdd\xadhN\xfc\xec\xdf\x01\xf4\xee\x963\x8d\xc2B \x9e\x1d\x03K\xfd: \x0dGl\x8fw\xda\xbe& D!\xdd\xd7L\xef\x86J\xb4\xae\x90\xc4\x9a\xa1\xf1\x8a\xe5\x9f\x9e\xce,\x9ew\xe2\x9e}\xea\xfc\xf1\x9eC\x99\xe3\x0f\x1f`\x1bu\x1e\x05\xc9\x8b\xba|\x7f\xe2\xdcsac$\xc2:\xd1zc\xac\xe7\x9f\xca\xb5|lH\xaa\xc4\x1a\xf3\xea:\xde\xbeC\xffkT\x92\xcb\x1d[*\xa3\xdc;-\xaf\x8a\xbd\xfd\xaaP\x05r\xe7\xdc\xf7Y\x12\xa8\xde\xb3\x9d\xfd\xfd{\x1e\xb9$3\xdb\xb2\xe8\x1c\x15P3DO\x02\x92\xad\x9a\xd0]\xaa\xe3\x06@\xd3'gOx!\xf14<\x95%\\;\x95\x8a\xfc\xedZ\"\xa7_\xab\x83\xe8\xe1\xe8\xd4\x9f\x9d3K\xff\xdc\x85\x08\xc3T\xcfY8}\x93\x93z\xc0B}\x86gq\x92\x91\xa7>\xc6\xf6\xb3B\x0b&\xf4\xda\x83uZ\xb6,\xa3\"\x8c\xc2\x18\x8b\x96\x8d\xa22\x0eQ\x11\xbf\x0fV\xd9(\xc8\x8bp\xf6\xfe\x8a\xbe\xbf\xe2\xef\xf5CX\x98}\xe4\xcf\x9b\xbbY\xc0>l\x8f\x1fn?\xdc\xbd?~\xb8\x83\xe6\xfe\x8f\x1f?65\x80\xd1g\xeb\x03O\xbc\x1c\x83\xa3\xbb\x10\xc0:Xg:\xfb\x01\x94\xfea\xd0\x06t\x8e\x90Z`J\xce%o\x876\xf2\x85\xbd\xbf\xf6\xe3\x8f\xb9c\xb9\x10\xa84\xd4\xd5\x83\xfe\xeeK\x06\x8b<\xbe\xe7\x9amG\x18y\x0cE\xcd\xb0\x0e\xf9t\xf3\xb8\x82\xf0\xc7\x80\xf1\xd5\xec\x94\x07?\xe12\xa5\x85+>p\x1c\x17\xd6\xd0\xb6\xbf!\xf1\xc2\xa4!\x9b\xc7\x95F.s\xcd\xe4O\xe3\xc1\xa9\xcf1.\x01\xcc\xe1\xab\xae\xe4{\x03\xc6\x8f`\xbe\xbe\xee\xc8;S\x8b\xd8\xe6h\xe8k\xe3\x8f=\xa5D\xbc\xf1\\;nw\xf0|9\xbe\xaaC0\xa2]\x00s\x14J\xe9\x07l%F\x0e\xcf.!-\x1b\x8b1\x1f\xb9\x90V\xad\xee\xc1\xb9\xe3|\x00\xbec,\xa3O{\xfb\xe8\xa0\xeb\xc1\xc19\xecC\xca\xcb6]8\xc7O:#hY.3\x8f\x06kS\xa0F!\xd3\xdct\xa4\x15\xb3\x07a\xb6\xe6\xa5\xd9FW\xb0\x0f\xd3c\x98\x08\x1cT g\xdb\xdc\xa0Z\xcc-\xd1\x08\x1a\xa2\xeb\x06d\xd5\x8d\x08\x01\x89\xac\x8ak\xb2*\xeb\x90U\xb1\x8a\xac\xcaV\xa5\x03\xcc\xf2\xfa\xd4\x8e\xed\xedQ[\xec\x9c\x88\x92q\xbb$\x14%;\xed\x12\x9f\x97\x8c\xee?h\x17\x95\xbchgk\xb3]\x94\xf3\xa2\xadNO\x11/\xb9?\xden\x17\xcdz\x03\xf7U)\x98\x88wrB\xf2\x97IPFD\x97C\x14$\x99\xff/\nW\x10\x8c\xbb\xc7r\xe2\xe9B\x99\xd5\xf9\xdex\x0c\x86v\x8a!o\xe1\xe7\xaf/b\x91\xbe\xb5\nC\x17s\x95\x0d3\xb6 \xdd\x84oP\x83\x10&\xa6\xf3\xcb\xa8\xe0\xa1\x99\x9a\xa0A7e\xbb\xb3Ts\xae|q\x1e\xfd\xa1z/\x96\x0eR-\x8b\xdaY;\xcc\xf4<\x18Y\xa3.E\x92\xd6Y0\xde\xdd\xd9\xdd\x1c\x05-E\x1b\xbdv\xad-o\xf4\xc0\x1b\xb7J\xe8}j\x9d\xfa\xf1OI\xab\xe0\x8c\x16\x1c\xfa\x85\x0b\xe3\x1dxR\x9e\xc1xs\xf4\x006\xefOv\xc6\x93\xf1.\xfc\xe9\xe5\x91t\x10\x86\xe9\ns\xb1\xf4\xde9\xc9\xf20\x89s\xbc*;/?|\x80_\xae]E\x89\x97_\xf8gg${\x17*\x9d\x97x\xb5 (\x02\xdd\x9e\x85\xc5[r\x1e\xb2\xf2\x85\xb2\xfcY\x98\x15W\x13\x08\xba\x85\xa7e\x18\x05G\xe1\x92\xe4\x85\xbfL'p\xd6\xad\xb2\xf4g\x8b0&\x93v\x0c\x85.\x07Ph\x1d\xaf\x82dy\x12\x06,\xcf\x94\x1ao\x06\xc9\xf2U\x12\x10S\x95<%\xb3\x89\xde\x88*\x8b&J5,/\xccMMG\xfeUR\x16\x13\xb0\xbe\xf6s\xf2\x02\xff\xd0\xb4\x14$\xb3\x83\xcb\xd4\x8f\xd9r[Q\x98\xebj.\xfd\xcbg,\xf5( \x8e\xfc3c\xff\xf30*Hf\xaa\x81\xe6\xa4~\x91d\xefp\x9e\x8b\xa2H\xf3\xc9\xbd{IL)^\x01=^\x98\xdc\xab*j\x86\xc5|\x97r\xfdB\xce\xca\xbcH\x96\xfar\x9eO\xf5uJX\xea\xaa\xe7A7\xa9N\xab.\xcfz\xf4\xac\xd4%\xbb\xaa\xea\x13\x92\xbe\x08\xe3\xf7a|\xa6\xaf\x94\xb1\xd6\x9e\xc7\x05\xc9f$-\x92\xacOc[\x7f\xc9\xb0\x97\xb2\x82f\xba\x19\xc9\xd3$\xce\xc9'\xea._$\x17\xe8\xd3M\x02\xbejj\x073\xa8q\xeb\xcb$ \xd1[\x12\x07$\xc3u\xb3\xc8\xa5\xbfL#\xa2\x83`\xe9+\x04\xe5\xe0\x19I\x8b\xc5\x04\xb4{R\xd7\xcf\x87|@\xa7ppY\x10<#\xb9~\x1fi\xbd\xa7\xc9r\x99\xc4\x83j\x97)\xc5\xc3$8,O\x97a\xc1\xa2M\xe4\x13\x98Zg\x04\xd5.i\xc9\xfeIr\xfc\x97e\xd1\xa5\xbf\x92\x94nU\x8e\xfa\x01\xe2\x07X\x89\xcb8\xad\"\xf3g\xc4\xd20\x9eiFrR\xd0>\"\x81\xb0u51C\x17\xad\xa9\xa9\x10\xc6a\x11\xfa\xd1!\xddX\xfd\xd1\x9a\xc7\x86c\x99,\xd3$\xa6|\xcb\xa4\xed<\x05jp\xa2\xfc?%\xd3\xe7^\xeag99D\xb9Y'M p\x82\x89x\x1c\x057\xf1:OF\xac)\xa5X?\xe5\xdd\xf8b\x8d\x1c\x9b\xdeq\x05\xd2\xde\xb1\xa2\xb7+\xed5\x91_\xe5\x05Y\xaa\xc8\x08\xf1T\xd8+\xf5\xf8\xcfU\x0eW\xb5M\xa9\xc7\xf7V\x03kl\x9b\xda\xb3\xd2\x8eJ\\\x1ff~U\xd4J=\xf6K\xdd\xb7x\xc4\x95\x90z\xec\x97\xb6\xb2f\xaeP\xdf\x98\xc6~X\x1d\xdd\xc5)\x1e\xbc]S\xaf\xcc\"\xfd84;\x01\xa9'C\x7f\x97@V\xc4&\xe8\xfb\xa4\xa2\xa7O)=\xdd\xaa\xdd\xfa\xbbEZ\xdb\xa7HRK\xfdS\x15\x9a\x078`\xb2\xdc#\xa5\xc0\x86\xb0\x073\xc7\x85\x13/'\x05\x1bCn\x97\x8e\x0b\x17\x02;=\xc1\x99\xe7^\x94\xf8\x01 0\x8fI\x9d=\x9d6\xb5\x16\xd3CE\x7fZ \xf2\x84\x16KQ\xb0\xe9BX\x8f\xb2\xc4y3^p\xd3\x85\xa4S\"%|ck$:.\xd3\xc0/\xc8\xbb,\xb2-\x0b\x07\xd6-|\x91\xf8A\x18\x9fQ\xe8/s\xdb\xca\xcb\x19\x06~\xd1\xd4>L\xc9\xcc\xa6\x83\xc8:\x83\xc0d)\xcdo\x82\xe4\"\xa6s\x07\x0c\xea\xc1g\xaa\x1d\"\xd6\xe8\xf4+\xda\xe0\xc5\xe8\x81#6\xc0\x81\x0b/C\xd2\xa7\xde\x14\x17\xac'i\xaa\x93\x97V\x91J\xb0\xfeI\xa8\x0d\xcd\x0f\x1c0s9\xb2\xc6\xdfK\x92] \xf8\xab\x9b\xd0\x8bR\xab\xe1\xe5bXj4\xc9\xa3\x89P\xe0\xc0T8\xbceL\x06\xd0x\x89`\xf7\xe1\x03\xf04\x1e\"k\xc7\xe1\xfb0MI\x00YM\x07\xc6 \xfc\x0bk\xe5_ \xc9\xf07\xfd\xf8_\xe0\xc2\xcf\x11\xed\x87\xf3\x90\x04\xbau\xe2x\xe8\xa2\x8b\x18\xba\xe7\xeb\x92bB\x0e\xf2L\xa6\xc8~\xbf\xcb\"\xa5\xac\x0d\xe5\x98\x8dM\xee\xbc\xa0G\x9b\x9d\xa8\xaf\xaf\xdeq\xb0Y3\xd6\xf8\xf0\xc1\xd8\x82\xe2\xfa\xc6K\xed\xb2;\x1d\nlo\xc92)\x08\xfb^M\x81\xab\xd8\x90\xd4\xeb\xbeU}\xa9`)\xe8\xa7\x9d\xd7M\x1c\xec\xc2\x01fb\xb0\x8d\xf3\xbc\xa4\xd5\\\xb8\xa0\x87\xf1@r\x03\xba\x96\x91,\xe9\xa5E\x1c2\xe1\xd8\xde\x19=\xe88\xf0\x8ev\x1c\x8f\x8b\xfd\xde\x93\xab|HC\xf5\xcau\xac\xa0\x99\xb6\xf5\xe1\xae4\xe1\xd8\x1e\xef\xdcwx\xbaM\x03\x95\xd1631\xbb\xed4\xb3s\x03\xacnX\"/C\xb3\xa3J8\x18\xdb;\x9d\xc0\xb0\xb5pq\xd2\x9fb\xb3\xb3\x03\xdc\x83\x1b\x1d\xbe[\xfbp\x7f\xdb\xf1\xe6rL\x94!-\x0e\x9cD{\x9bn7\x89\x9d1\xf3\x07\x1f\xdd\xe7~\xe4c\xeeW>\xbe\xaf\x04\xaf\xc3\xab\xe5i\x12\x0di\xbb\xd7J_\x9d\x8e\xb7\x13\n\x83G\xe9m\xe7\xb2\xe4\x913\xda[\xca\x83\xf4\xee\xb4\x83\xf1\xf2\x19\x8c\xb7\x1d\xef\xcf\x07\x7fk\x96\xb1\xd4\xa1;\xed\xf1\x88\xcc\xa1\xed\x011\x81\xf6\xc3vX\xa1\x94{\x87\xb4\x8d\x13x\xea\xd0\xb6O\xc2\xa2\x82\x94\xe6\xfbs\xfe^\x9d9tg\xdc\xae/2\x87\xb6'\xcc\xb2\x86n\xb5G\xc3R\x86\x8e\xdb\xb5Y\xc6\xd0N\xdc\x87\x0b\xbe\x9a\xed\xb9\x1e\xb0%h\x8f\xf1\x92Wo\xcf\xf5\x90\x8f\xbd]\xff)\x1bL'X\xca{\xb6\xe5\xed\xd7O\x04Bj\xbe~\x0d{\xf0\xb4\x9d$\xf4\x0d\xec\xc1\xfb\xf6\xcb#\xcc\xfb\xd9z\xf9\x12/\x08\x06\xd7\xcd\x92\xe7\xd5\xd5\xd1|\xff\x13\xec\xc1sJ.<\xafQz\xb3\x06\xbd`\x02\xdb:Y\x84A@\xe2\xb6\xca\xff-+-\x927Y\xb8\x0c\x99\xbfM\xb3\xc63\xd4\x03y)g(\x9f\xe7\x07q\xb9d!\x91\x9b\x15_\xd0\x1b\xd2\xb6r\x1c\xfd\x06c\x05\xb3\xabvs\xef\xe4Z\x9dd\xc6\x7fg\xa5I\xba\xa1\xa9\xf0\x0d\xecu\xb4I\xcd\x1a?\xeb\x02\xc2\xbcl\xd6\xfb\x1aW\xf4/\xac\xb1f\xd1\xf7\xb0\x07k_cf\x88\xaf\xa5\x8c/\xad\xbf\xbdy\x18\x07O\x17a\xd4R4|\x0b<\x82odvr\xe6w\xce}X\xdb\x83K\xfb\x0d\xf2fh\xd7\xab&\xd0\x87\xc5\xd8\x82\xba\xe17\xb2\xad\xb0Y*\xc2\x93,\xdf\xd7V\xbav\xbcn\xd0#P\x8aA\xae\x9dv\xddkG\x0eg\xa3\xb1]\x03 !\xbf\xb6\xbfQ\x9b\xd3d\x92\xac\xe2\x9biq\xec\xc2\x9b\xaa=\x1e\x10\x92 \xb7\xf9\x0d\xfd\xf9\x06\x9b\xe9\x04\xc0\xbf\x86 \xbcin\xd9\x0f\xbd|\xbb\xe0\xd9\xdf1\xaf\xf1K\xfbe\x0d\x08&\x1d%fL\xef\xaa'\x9b\xdd\x7f\x07{\xf032\xc5\x0c\xea\x1bP\xeb\x89\x9b\xbb\xb1\x88\x06\x80R4B:\x0b0\xa8\xa5F\x94\xfd\x97\xa6\x19\xfcm`l\x80\xaa\xe1=\xb1I\x7f\xb3\xff^m\xe0\x15\xcb\xe2\x02{p\xc13\xd6\xd1w\xb4$\xb1\xdf\xa1\x91\xc4>\xc6\xd7\xa9\x10\x10f\\\xa5\xfd\xbdby\x85\xa7\xaf\x8e\xa7\x053s\x11\xbf\xf7x\x0e\"\xdc\xb4Xw\x10\xea&)\x17\xb1\x89\x89\x8bT\x90\x0d\x93\xba\xc3\x0f\x1f\x18\xf4\xbdr\xe1\xc0\x1ea6uJ\xa6\xd4\xfd\xd2\xe1\x7f[\xad\x06\xfd\xb6\x86V\xd3b\xfey\x88q\xc8\x95\xd2\xf5\xad\xd6\xbc\xb3\xe0\x1fK\x9e\xe8\xb3\xa0CKXj+\x16e\x97IP\x98\x1fe\xf2\xc8\x81\xbf\xa1\xfe\x1d\xc3\x05&\x18\x06\xa60j\xdf\x8d)7\xfe4\xf88=k\x18\xaf\xe0\xc6\x13\x96\xaaP\xdb\xf3\x1a\xd6\xae\x01\x08A\x83\xe5\xf7\\K(0\x11f\xc1e\xaf\xd9\x05\xa2\xec\xda\x17\x9f\xff\xf9N\xfc\x16%\x0cz\xe8o\xbay\xe4\x18\x0b\xdbv4\xcd)~1d\x8f\x98\xdd\x05]\xff.\\\x0b)\x11\x89\xa9\x9e\x94\xff\xc8\x11{\x82\x87\xcd\x17\xb3\x8a9\x04\x7f#v+dSz7-\x0c\xe70l\xce\xaa\xae\xf73nmi\xdb/M\x81\x0d1\x08\x14=N2\xa2\xef&\xc4\xb0\x18IZ\x87{\x92\x92\xd0w\xf2b\x9c\xf3\x8cj\xa9\xca\xebw\xb3\xe1\xf5\xbb)\xf9\xe6\xbb\x9d)6\"B*\xaf\x13\xe0Y\xdajl\xc0SZ\xfe\x9d](\xcd\x03\xce\xfe\x9a\xbe:\x16\xf8\xc2\xae\x8f\xbc\xb8'\xbe\xad\x0d\xe9\x10\xa9\xab\xd2\x1d]+\xa5|H\xf2}O\xff\xf7-\xdd\xc3N.@\x18\x14I5\xa7T^\x8bXp\\\xf8\xa1\x99\xeeM\xce8h\x15I\xe5\xe3\xdd'\x04)0C\xdf\xfb?\xc8M?\xc5\xa4t_\xb8\x94E\x81=\xf8\x1bF\x90\xdby\xe8\xe0_\x87\xf8\xff\x7fF\xae|\xbc\xc3\xde\xfd\x89\xf1\xe8\xbb\xec\xaf\xbf\xf2\xfc\xc6k\x94\xdf\xdc\xc6e-\xe9\xfc-\x15\xc3`\xb9\xf4kD0\x0b\xfc\xbaWR\xf5\x83\x1d4$2t\xc4\xbe\xedc\xaa;\x1fS\xdd\xf9,[\xda\xcf\xed\xf5f ;\x91\xe8\x16Y\\V\x1d\xe7\xbfPva\xe1\xe7\xcf\xf9\x01p\xc3\xfci\x12\xcf\xfc\xe20\xcd\x88\x1f \x9b#(0\x17\x9d\x85\\n\xbd\xeb2\xd7\x0c\x97\x07\xe8u\xd1\xde\xd3\x958)W\xec\xcc\x91\x7f\xe6\x96q>KR\xda\\.LC-\xd7\xa2\x17\x01a8\xe2/\xf5!!\xe4\x91\x03\x81\xfd\x97)!\xcd\xb4\xe65\x12\"\x98\x8f*\xf0\xf2\"\xc9\xe8\xe5\x12\xf3V\nR7\x13\xd3f\xce\xed\x82L\xe3V;t\x05\x0f\x1bk\xc7Ox7B]\xbf\xfdG%;{Ao\xb5\xf5=\xb47\xdf\x87\x17\xf4TM\xd8?{\xdd\xe4\xea-\x04\xfc\x9e\\}\xd3\xdf\x15Z\xe0\x7f\x87\x16\xf8\xc6\x9c=>0\x1a\xb8\x83\x9b\xa0\x19<-\x8c\xe1\x85ZCA{z\x81t\xdc\x9e\x9c\xba\xc3H\xc6\x9799$\x05\xaa\xb1\x8d|\xda\xf7\xaa\xf0\xc0\x9d\x96\xc2e\x1a\x91!-5\x93\xcd^w\x8eJk\xa3\x19\xc3\xdb\x8dq\x84A\xd4\x07$+\xedZ%\x17\xb0\x0f\x976\xa6\xa5\xfc\xb3}\xc9h\x1d\xe3f\x07d\x1e\xc6D\xa8\xa8'\xf07CqH\xf2 \xfc\xb9Y\xe1\x8c\x14\x92\x8a\xfb\x19\xc9gY\xc8\xd4\n_\x98*\xbe\xf2\x97\xb4\xb1\x7f6\xd5a\xc7 \x9f\xc0_\x1b\xeb\x88\"\x96\xe6b\xdakx\xc5\x1a\x98|q\x11\xbel\xc7<\x16\x8c\xda4.\xa3\xe8\x18c\x99\xfdd\x0b\xba\xd3\xfa\xe5\x9a\xbf\xe9\xae\xbd\xdf1,m}\xc26\xb7\x851\x1d\x17\xac\xef\x0e_\xbfR\x04\x01\xa9\xb4\x0c+\x10?\x9cd#\xc7\x8c\xa3\x18=R\xc5\xe0\xa1,\x05\xa7\xc9\xea\xeb>ib!\xf1\xf0L\xde\x9c \x1a\x1d\xbb`\x9f\xda\x9d\xa4n\x9c\xc4\xffN\xf6\xbf9\xe3\xd5\xecb\x089.\xfaRJ\x87X\x987\xa44;\x06\xf5\x8eK\xfb-\x1c\x0d\x1a\x00\x0e$t\xect\x1a.\xfc\xc4\xb5*\xcf\xbb\xc2\x87\x06XIB\x84\xe9[$\xc6c{g\xd3\x91\x85\x0b.\xbcm\xd4cI\xb6^\xcf1_\xe8\xcb\x1aq\xb3\xbf\xfdb\xe1\x82E\xff\xb1\xf8=;\xe7j\xa6\x1a\x06\xd66\x07\xa9\x00j\xe9xG\xca)\xa2B\xa9\x93\xd8QBaU\xbd\x94\xe0\x073e\xda\xb7\x98\xc5\xe5\xed\x1a\xce(2HV\xa0\xea\xbb\\\x00O\xf1\x11\xed=\xf4\xe6,/\xcb\xe6#(kH\x8d\x1e9\x90W\x16\xe8\x94`/\xa7\x11\x12\xe5HN2\x10V\x1f`Ia\xb8\xda\x8av\x84\xdb\xc2\x9b\x90\x92]\xdd5\xfd\xe5\xda\x13\xa4D\xb3\x10\x83\x03\xd5\x86\x14\x02\x96/\xc28H.P\xc9\\\xfd\xe2BS\x05F\x84}C\xa1\xcdZ\xa0\xb8]v\x8b\xab\xb5\xa3\x83\xa88\x0c\x8akM\xd9H\xe1\x07l\xf2\x18G\\\xe58\xeb\x95n\xe9\x93\xd5T\x04\x88\xca\xda\xaa7\xf9\xbb\x18\"w\xf4Q4\xd1<\xc06\xcf\xbf\xdc\xd4\x14\x0e\x02\x00\xa6K\xb1-?\xbf\x8ag\xcfWR\xc8\x89OY\xfa\x12\xa4\xa5\x07}\xa7\xd6|\x15\xde\xe9UA^\xb0#0\xe4\\F\xdas\x89\xe9\xa5:%\x19\x96\xb4}:\xf9Ro\xd1\xdb\x13\x83/9p\x0f\xb6aC\xe2\xcd\xaf](\xbc\"\xf9\xfa\xaa <3\x9catm\x9e\xfd\xa4\xb0\xe7\xce1|\xf5\x15\x8c\x1e\xc0\x87N\x11\xac\xc3\x88\x17\x8f\xd5\xc5cV\xbc\xab.\xddr\xe8JL\xf3\xf5u\xbc\xa60\xb2\xf2.| \xe3\x9d\x9d\xf6\xfb\x07\x9d\xd7\xe3\x9d\x1d\xf8\x12Z\x89\xa4\xc6<\xc5\xb5\xb8:\xd5\x93\xd1\x0c\x96\xce\xe5\xf1c\xd8\xeev\xd2\xc2\xb6\xa3A\xbd\x8c6\x8dK\xb6\xad_\xb1\xc7\x8fa\xa6\x87wZ\xb0u\xfd\x12v\xb7\xe8\x0bko\xcfB)\xf7\x98\xb7\"\xf6\xcbf\xed\x8cq\x1f\x1e8\xb0\xaemx\xb4)Z\xa6\x80Q\xb5\xcc\xbb\x1aK]Y\xed\xa1\x0b)L7\xdc\xf4\xb5\x82\x7f\x16B\xc7D\x12>Ze\xcc8\x8f@N\x0f\xfb.\x8c\x8b\x07l\x1f\xf7\xe5?&,\x9f\x0b\xdb\x14\xeb\xc9\xd7O\x9f\x1d|\xf3\xa7o\x9f\x7f\xf7\xe7\x17/_\xbd~\xf3\x97\xb7\x87G\xef\xbe\xff\xe1\xaf\x7f\xfbg\xfft\x16\x90\xf9\xd9\"\xfc\xe9}\xb4\x8c\x93\xf4\xefY^\x94\xe7\x17\x97W?o\x8e\xc6[\xdb;\xbb\xf7\x1f<\\\xbfg\xf1h\xdc\x0c\x8f\xf8\x95t\xbe\x84\xaf \x7f\x04\xeb\xeb\xa5\x03\x19K\xc6\xedOK:\xf0\xa9/\x83r\xe9`,c\x95[[\xa4\xc7\xea\x02\xd8\xba\x84U\x01\xff\x01\xb6)\x1a\x13\x8c6E\x9e\\\x16\xf8\xc1vn\xc2\x84!f:^9mfw\x1df:\x8c_g\x8cB\xf7S9:z\xc1v \xa6\xff\xac\xef\xc1\x96\x83\x00c\x13\xba\x13\x14\xe5P\xec9\xda\xbd?\x1a\xed>\xd8d>\xf6\xd3\x92\x9e-\x06\xe9\x14\\w\xc6\xbc\x84\xa1\x0fV>>\xa6\xac\xb9\x80|;\xc4\x8cZ\x08\xff\x0f$\x98\x0f\xf1\xcd\xb8\xfdfWz\xb1\xbb\x05_B\xd8\xe6\xa9*\x8a\xa6{\x14\xaa_\xc9\xd4\xda\xb0d\x08\xdaD\x08\xda\x1dS\xd0\xb2NTE[JzC^\xcd\xc2\xcb\x88\x1f(T\x81<(\x8a\x02\x0cCW\x10\xea\x0f\xe0\x8f\x90PZ\x80b\x06\x85`\x94.\xfc\x88\xaek\xe9\xa8k\xa0\xbf>\xaeY\xb7\x8c^\xcb\x1b\xf7\xbb\xef\xd1~\x06\xf6\xb1\xe3\x11LT\x01\x0bR^e\x83\x96+\x9a\x0e\x10QR2a\xde\"w\xb8\xc3\xfe\xfa\x1e\xa4\x0c\xc3\x04\xf0%\x9f\xc3\xc6\x8cM\x02\x02x\xfcx\x0f6f\x94rX\xa7'\x18f\x18\xd8\x14\xeb\x8fwv\xe1\x8f\x10\"\xc2d\x1d\xb8 \xda\x9b\xc1\xc6\x1e\xcc_\xf9\xaf\xb8\x8c\xa7\xc0\xb6\x18x\xec\x83\x8dY\x04D1o\x92!\xef\x19j\xe9}\xd1\xd6R5\xcf?\x85\x0dX\x1c\xc3\x87=\x18\x8d\xe9\xc1:o\xddp7b\x8a\xb9\x10\xa4)\x9c\xb6\x0b\x17\xac\xda\xac\xb5#B\xe5\x96S\xb2\xb1\xab4bAj^)\xa3G$\xbcd\xac\x8c+\x81%[\xaa\xb8\x12X\xa2\x8a*A\x0b:_\xe4\xbc\xa0\x13l\x82\x99\x9a\x8e\xef\xb7U\xaf\xcc\xd6\xb4mf9\xc7ff\xad\xb7)o\\\x11\xe6\x82\xd9\x9a\xee\xec\xb6\x03]/\xaaO\x1e\xb6?\xe1\xf6\xa6\xe3v\xdfK1\xb7\xce\xac\x99\xc5\xa9&\xa0\xc3\xd5\xa7\x0f\xe8p:D\x1a&%\x1bm\x82\xca\x89IU_M\x8b(UA\x92t\x9e\xb15J\xe5{\xed\n\xb8\xd6\x88\x0d\xb4y\xdc\xd5\xcb\xab\x82\x7f\xb4\xdc\xc9\x84a\x8d\x8b\x05i\xbb@-p\xcb\xcd^\xc1\xbd\xce\xc5+\xb8\xcd\x9a\xbc\xe3L\xde\xc7\xd0\xf1@\xd6\xd7\xcb\x92\xa4x\x1eS\xd4\xd1S\x11\xe7\xfdF\xccN\xe1\xd4\x0c]M\x99xN\x932\x0e\x0e\xc5\xc45\x95\x8a$\x89N\x93K\x8d\xc34bz4\x00\xa8\\\x18\xe9\x1d\x81\x16\x01\xd5\x1b\xef4\x8c\x03\x1e\xf0\x87\x95\xa1\x82\x99\xdd<{p\xeaVn\xd63\x14r|w\xc8\xf6\x9ayUr\xe1[\xb3\x93\xfe\xb0\x85\xe2\xa9\x18s\xda\xfe\x99\xc7\xf6\xf9hQ\xc6\xef_\x86A\x10\x91\x0b?#\x8e\x1d;\x86\xc0i \x06\xf2\x12\xe1FNN\xde\x1e<{\xf7\xd7\x93g\x07\xdf\x1f\xbd~\xfd\xe2\xf0\xe4\xe0\xafG\x07\xaf\x0e\x9f\xbf~u\xf2\xf4\xf5\xcb7\xaf\x0f\x0fNNP\x87\xc7\xbcGsE$\x1c\x90\xc8\xc6M\x97\xd6D=\xe9!\xaa\xdd\xf9\x84\x12;b\xfa\x9ez\x98\\\xffS\xa5*wTf$6?\xaf\x8eXk\x0cO\xc2\xbdK\xd1\x1a\x05\xdfVN\xb5\xf8\x17?\x1e:\xadRk\xbce}$\x89\x0b\xd3\xee\xba\xbf'W\x13\xb0\xe8f\xd1\x19)\xdc\xa2\xf9\x05gTCC\xcb\xc2\x04a\xa6;\xdf\xe6\x90U\xe8\x81\x8dFLx\xc0hz}l\xd7\xd4\xa9\x07txp\xc4t\xb0\xf2\x0b=\xb0\xc9y\x80\x81\xd8&\xd0\x16\x0f\xe5}\x18t\x879\xa37\x1cJ\x91b\xc09\xfe\x1a\xc5JNC\xdb\xa8\x06KU\x9b\xdf\x94\xf1\xac\xf1-\xb1\x0b4\xa0\xd5y\xf9\xaa\x1aQ\x8c\xc0[\xfai-:\xd7jW\xe5\xa7\x1e@\xc7\xde\xb5\xfd\\;^F\x82rF\xec\x0b4\xa35\x0f\x957\xacA\xa0\xc0t4mTg\xeb\x02\x00^p\xfc\xc5qU\x8c,\x01\xb7\x06m\x1cH\x85\xfe\x03\x9a\xd7r\x1f\x00\x08\xfcF\x9b\xd6O\xf1\x9c\x07\x17U\xc0\xedX\x0b\xb7\xe3\xe6\xfd=>\xeeq\x0d\x07Nd&\xde\xc2\xcf_\xa0\xb7\xb6yD(T\xd0W\x19\n\xd3\xa8\x07T\xa9\xdf\x0b\xcf\x9f\x17${\xc1\x9d\xa7\x91\x83X\xdbt\xe1\xc0\x96J\x1cY3\x1f\x9bB:\x9a\xcf\x84\xdc\x0c?\x1e}\x1e\x12\xd52M\x14\xd9\x9f\xc5c\x82\xdc\xbb=`\xcd\x99dB\x18\xd1\x7f*\x07\xcd\x03\x00TY\x80\xeb\"\xfd4\x85\x95\x18\xb0z\xd3\xc5\xbb\xa1\xad\xf0\x18T\xba\xe3\xd13\x02\xceG\x16\x82K\xe2o\x06u\xfe|9\x81\xb9XZ}\xb5\xb7\xc4\x9f\x15\x93:H\xa2\x1as\nn\x8cqi\x12\xcf \x18\xc6\xe5\x96p\xce\xa7u{p\x92\x07\xa9\x8bX5xdw9\xb0\x01\xc2\x82!c\x87\xce\xf8\xbbo\x0c3\xcaW\x99\x91\x96\xb7Q\x0c\x14\xf6\x14q\xf7\x06\x0f\xab\x894\x07\x0c\xcdxE2b\xc4p\xef {(b`\x0bLmW\x97\x18\x9f\x99,.a\xbea\x8c|JN\x7fz\xe9\xa7\x0e\xbdA\xfa\x97\ndZ\x89\xf1\x18\x99fW\xb9\x87V+\xd6\x0f\xa9X\x93\x9a8\x1bB\xe6\xf7RH<\xc6-F\x82&\xd3\xf8x\x85H\xe0\x82\x10Y\x91\x0c\xe9J\xf8br\x013\xef\xa5\x9f\x9a\x19\x05\xe0\x84\x89\xcc\x15\xf7s\x93k\x99)\xc2\xb0\xfc\x08\x93\x80lZx\x94\x1d\x18\xd0x/\xa3\x0d\x12'u`\xc7\x8e\xc9_N~\xf8\x88\xab D \x97\x0c'\xc6/\xf5\xac(\xa8\xc4\xbe\xed\x07aO\x0d\x95\xc8\x0f\xbbm\xa8,\xe4\x08X\x9b.\x04\xde,Y\x9e\x86\xb18M\xb9\xc3r\xea\x9f\xf6&\xc97\xa3\xdf\xa3\xabt\x88L\xa8W\nC\xa6\x9b\xc7^\x91\xbcKS\x92=\xf5sb\xa3\x11P\x15+\xbeW\xec\x86\xa7\x9e\xcd\xcd\xb1\xf5H\xa2\x1aP\xacH\xe7!?\xe7<\xb6y\xac\xcc\xf8-\x1eTT;\xf28\x92&}\x9c\xc1:\xc5u\xa1\x9aU\xba\xcd\xa5L\xc9\x13A+\x0f\xd8\x80!\xb72\xdfN\xdb\xca\xab\x86o7@N\xef\xdfbx\x02\x915\xc7\xe7\xf3v\x07\x82\x05^\x06d\xc5\xcb\xa0\x03T\xc4`\xd6\xa2z\x1a\x02\x06\x8a^\x1c\x13\xa0\x14\x9dL\xe0\xf2\xa3a\xb5o ?j\xeel\xc0n\xf5\x9ef\xba]\xc3\x98\xd1\x06_\xa8\xf2W\x07\xdd\x86\xc6\xcd\xfd\xe8\xbfpi\xaf*\xac0\x8d\xeb\x0c\x0e\x1b\xf7\x9dc\xef\"\xf3S>\xa4\xdeK:\xe3\xf8U\x03h\x03\x04\xbe\xe2\x0e\xca\xa6q\xcf\xb5\xc6\xbbD\xe3K\x14\x10 A\x91\x9d0\x1f\x17\xb4UL\x8e\x1d\n]m\x9ad\xc8P@Z\xaa\xde\xa3\xd9~\xc4\xbd\x88\x87\xa3!\xaci\xa9:\x14Q\xc4t\x8fB\xbf\xd8~\x90\x90\x90\xcfY\xe6\xc8\x16\x89\x92\x87\xb2\xb4\xad\x10\x13\x12\xe4P$\x954\xaa\x96\xd2\x16\x0b\xbf\xe0\xafs\xf0\xb1\x91\xaa\xcc\x0e \x14\x0b\x02\x17\xec\xe4\x00CD\x8e\x0e\x11\xc9\x0f\xef\xe8\xc0\xcez$\xdd<\xf0\xe67\xbcO)\x88\x08\xbd\xafM$\x82\xb6\xf8n\xf1\xc4*\xd7\x8e Q\n\xa2\xce\x8c,\xb26\xb2\xa8%D\xfd\x01\x0e\x9a'S\xce\xa5\xa3J\xe7%?\xe2TN3 9<4)\x16A\xb87)qL\xc2\xd0J5\xf8^\xc4\x12v\x10K\xb1\xc2\xf0A\x16\xcaO\xb3a\x88\xc5\xef\"\x16\x9f!\x16\xb4x\xf5\x99M\xaa\x82\xd9\xe9\x1d\nH\x14\xd5\xca\x88\xa5\xb2\xbe\x0d\x15\x1c\x0d3Mb\x83\x0d\x1dn#\xcdlr\xc3GP\xae\xaf;h\x0e\xdd\xe0M\xca\x9e\xe5\x10\x8f@\xf1\xc8\xcf\x990\xda\x94\xcb\x8b\x9e\xc7v\xe2\x1cS\x8e{\xe6\x17\xb6\xaf \xad\xdb\xcfM\x10\\hBp\x02\xc0~?\x0c\x17\xf6\xa1\xb7\xc2\x80\xde\xd4<\x0e\x08\xf4\xa6a\x81n\x87\xdeP\xca7\x08\x99\x0d\x90\x94fM\x0b\x17\x15.X]^\xd0\x14\x08\x10\njL\xec\xad^\x0e\xf7v\xe2\xbe\xa6|\xfd\x1fg]\x06#\x16\xc1m\xb3C\xabr\x11\x15\xcf\xf5G\\\xe3o\xe2\x01K{c\x99\xe5\xc4+\x93\xc7z\xeaV\x83\x92\xaa\xb05<\xb6\xf9\xbe~\xf4\xd0\x96,\x8b\xb2[m\xce\x9d\xd2jJz\xaa\xd2\x98T\x14\x99\xb3\xa2\x84EEa\xf5RFz6\xb0\x97\xc1\xe1-\xf4\x1e/\xf9ix\x84u\xc9\x8f\xb0\"?2\xa7\x8a\xe6\xe4\xc3W\x90=\x02\x9f\x92\x1f\xe1\xd4o\x92\x1f\xfe\x00\xf2\xe3\x9c\xa7C=\xb0cAl`*$\x0d\xa9\x11\x1a\x93W\xf2\x87O^i\\\x81\x89(m\xd6c\xe9\xd8\x85\xcd\xa2\xca\x1b\xdb4X\xd7|\x14q\xc5] )\x08\xc6\xe6\xfa\xf0\xa1\xa3\xf1\x13jt\xf5R\xcah\xca\xab\x85[\xed\xc8\x1d\xe2Q\x9f\x18\x99\x84\x1f\x80nl4(<\x0d\xc5\xbc\x9ff\xc4\xa7\x07\xcd\xa9\x10\x17\x90\xc1\xa6 \xd2\xc6\xd7\xce\x8b\x85\x99\xcd\xe8k\x1a\xe4\xeb\xb4\xe8\xb3\xe1\x82\x017\x9b\xfc\x08\xe9\x1f\x05\xfd~\xf8\xd6\xbb\xff\xb7\x1f\x94(\xdeB*!\"\x06\x0cZ\x1e\xe0\x1d\x0e\xabI\x1f\xba5\x138\xf7^\x1d\xfcpr\xf4\xed\xdb\xd7?\xbc:9x\xfb\xb6_\x03#\x1e\xcc\x80\xa0\xcf\x92\xa5zR\xff*J\xfc\x80\xa5\xf8Y\xc8j\x84AM\x98\xb5\x1bX\x03\xe6a\xecG\xd1\xd0-\x12@\xd5[\xd9\xdc\xb5\xc9\x02\xb0p\xb42\xd7[b\xaa\x97~\xca(\xe8\xe4M\x96\xa4C\x90\xd5\x10\xf9\xb7\x11\xcf\xf4\xb6\x04M\xac\xd2\xb2\xe3!\x03H\x9a\xdb.\xc93\x8e^\x87\xaf\xca \x92q\xd8\xb2\x0c!\xee\xec\xa6\x87\x02\x8a\xe5\x0dVL\xc8\x81\xd5VG:P\xea[\xb6c\xfam\xf5\xea\xdaV:\xaa\\hCG\xddZ\xc5\xab2\x02-\xd4\x0d\x9b\xac\xa2\x1b\x0d\x8fT\xde!\x0dA\x860\x03\x95\xb4\"\x83\xea\xcbF\x9a\xcd\xea\x05\n\xd8j\x96\x04)\x9a\xd6\xd5\xd6\xaa2\x80Z\x15T*\x91\xc8r\xe6\x1a$\x91\xf0*\xf9\x1a\x067\xe8H\xe9\xf7\xc1n}\x89&\xb6\x9c\x8c\x9b\xc6\x14\x18x\xf4\xea\xf6`\xa7\xd91\x86\x95\xc1yu\x1b\x99&.\xc4\xc7\xc6\xaf\x9bp\xa7\xd0\x19\xb7\xbe\x91\x13\xfdk\x9a\xd5\xba\xee\xcb\x8c}w[\xdb\xbb\xaa\x8a\xa1Y;\xddC\x18\x9b]B\x98\xa261$\xe5ow\x18V\xa9\xa3\x1aoe\xd5\x8f6\xc2.\xc8\xb2\xd5a\xca\xa2j.%\x9d\x8b\xdfG6\x9c\xf3,K~\xaf\xa8\xb2 `9\x93\xd6\xd2O\xa7\xf9\xb1+$\x9fye\xb1\xde\xd8\x96\xee\x9bir\xac|)O\xb2\xb7\x02\xed\x13\xe3z\xf4Ub\xf3\x13\xb0\xdfW\xdd LU_\xf2}\x88W\x8d\xf4I#2\xa1*J\xc4\x81>Z\xc6\xaa\x9e$*\x9c\xe9xQr\x86\x02]\x850$\x96\x93\xa9\xef1Ij\xcb\xf7\xc3D\xec\x0b'F#\xb1\xa0'\xa3\xa5\xb0\x98*N8\xab8\xe1B\x84\x12\x7f\x04 |\x05\xc5#H('\x9cQ\xf8\x92W@wb\x05\x82GcpN\xa7\x13\x17\xa6\xf4\xba\xaf\x00&SY\xae\x0c\x8d\xe5\x85\x11C\x9a\x19\xc3\x08\xcfE\xd7\x036\xd7\x7f\xe8\xfe\x92\x13\x8d\x9f\xe0\xdb\xdeX];[c\x85\x17\xb0\x9c\x14\xa9.U\x07\xc8S{\xca \x9dE\xdbI\x99\xb4\xa3\xca_\x0f\x19g=\xae\xf1\xa64\xdc\xcc\xce0\xcce\xc6b\x86\xb2|7\xda\xb8\xa1\xedX\x9e\x98+\xc5\x9b\xd7#q\x86\x0c\x85.\xd9\xb6)\x87\x94\x9f\xe7\xe1Y<\xa4\xa9\xfeY\xe9'\xc3z\x99`\"\x98-g\xc59\x98\x93\x0c\xc9\xa7\xf2Z\xbd\xfb\xd9\xed{\xa1\xeb\xd8\xf6\x9ef\xb1\x055\xc1\x1a\xb7\xd4\xb9\x8cv\xb6\xdaYyJ\xcc\x1aP\\$O\xf8\x01\x7f\x93$\x11i\xa5{\xc3Yx\xf3\xa4\xccL\xb5\"\xd8\x83{?\xde[\xbfw\xa6\"\x86gZ\xbfi\xdb\xb2`\x1d\xd0\"\x13MG\xed\xc8\x05\xeb\x8b/\xefYf\x94>W\xca>Q\xd0C\xeb\xf0\xfc\x1c\xf4\xcfY\x12\x17\xe4\xb2`1<\xf9\x9b2\xa6\x7fo\x1a{Hu\xe7Ul\x0b\xc1\x9e\xba\x18_\xd0\x9e\xd8m\x0b\xd33_\x99\x84\x19\x0f\xb1\x81\xac\xaf\x9bg\x1aHaI\x94\xf3\xcdH\xce\xf0\x98\x98\xf1{r\xf5&#\xf3\xf0R\x9a3_\x94\xb8\xb3(\xd9J\x8b\xb2\xe8_\x146\x9c\xee\xb2\xf8XZ\x8d\xad[\xa14\xaci.\xafi\xb7\x98\x02_\xc9\xd66o\xadms\x03\x9a\xc4WD\xa9\xfbs\nq\x19\xaeo\xe8\x15\x0b\xbfx\xcb\xd4\xac\x02\xd8)\x05\xcf\x13\x9e\x02\xcb\xe1\x98xa\xfe\xbd\x1f\x85\xc1ADh\x0d\xda\x0e}\x1f1\xc6 Jb\xf2$\x0e\xde2x\xfe3\xb9\xa2\x1d\xf8\xb0\x0e\xf6ZD\xe7\xcf\xe2\x9e MF\xff\xa2T\x01{\xbf\x0f\x96\x05\x13\x98\xd9\xf8\xa7\x03\xeb`\xdd\xb3\x1c\x0cU\xe8\xb8\"\xf0n\xe4\x98\xc1\xe5\xdc\xee\x0f\xcf\x04{`Y\xcd\x85\x113dq\xb9h\x8d\x19e\xc0\xd9\x10\xba\x1c\x03\xdd\xab\x802\xd2\x88\n\x02\xbb\xc0([\xd8a\xb3\xb2O\x87\xb3p\xa1\xa4\\\x92\x97\x91\x88\xf89\xb1K\xf3\x1c\x96=We\xe3\xce\xaf\xef\xf4\xb9\x14P7 \"\x95\x81I\xcd\xd88\x1a(\xaco\x9d\x8e\xc6\xcb\xce\x01\xa1\x9b\xe2\x07\x01]\x830>;J\xec\xb9\x98\xe8\x8d\x06R\x1dd\xa9W\xf9,K\xaf\xefp\xcc\x81\x0by\x8b\xae9\xeb\xc8>\xe7Iv\xe0\xcf\x16\x93^b\x06\x84-7\xb3\xb5\x96\xa2\xac+\xec\xc5\xabk\xb4 I*\xb7f\x84\xa3\x94\x85\x84\x9aWp\xd4\x8e\xc3\xdc\xc4\x0cK?\xfdH\x03\x9e*\xa8`\xfe\x15\x9e\xbf\xcc\x15\xbb\xc0\x9c\x8f\x8diJ\x96~\xfa<.\x92\x1f\xc2b\xf1g\xb1\xdb\x98?5\xf6\xa3 \x9c7+\xe3\x8e\x0e\xd0\x00\xf2\xd1\xe0\xb2-\xd9h\x8ckU$\x88\x12\xfb$y\x82\x95\xe8[\x80B,\x80\x1a\xa5vRg\xd5\xf0\xa9\xa6\xa2\xce\xf0\xed-\xa9\xa8\xd1f\x9b.\xc2\xc0\x7f\xb1\xfd\xc0\xe9\xb34\x16)U<\x91R\x85B+g\xa3\x86H<\x9b\xdf\xa5I\xda\xa3\x83b\xa7\x17\xfdjY(\x16Epr\xdd\x06\xc4\xe4\x02\xbf\xef$gP\xd0\x8a\xe6Y7R\x85\xd1&1)\x8fm\x8dw0\xc7\x85\x84\xdb*\x1fN\xc5\xfaPv\x92\x16\xa5I\x12\x1d\x86?\xd7n\x9d\xcd5\xa1\x97\x9b9\x9d\x04\xa5 \x92.\x01\xdb\x1d\xb7\x8c\xdf\x06\x9c\x15\x90\xc5`\xc6m\x89\x1bc\xe61%\xe3\x1a{\x01g\xf0}\xfa\xb6\x9a/K\xc7T\xfd\xb9\x07#L\xc6$\xb0\x18\xec\xd1\xbbS\x91\x9bIAZ\xc6\xa4I\x83O\xda\x0bB\x9f\x0e=?p\x0dn\x02\xe4 \xad\xddJ\x80\x0e*`\x8fyl~\xd5r\x80\x12\xe6A\x05\xf7\x9dT\x15\xa0^\xceb\x91\x91\xce\x82\x0e\xb90\xe0\x96\xab\x95\xdd\xc9je\xae\xf0\xcb\xeb\\1\xe2\x19\xbe`\xcax\x1e\x8a5\xeb\xf2\x81\xdd%3\x98\x91\xdcf\xd5\x92;Y\xb5\xa4Z5FM\xa8\x9d\xc0VZ\xb8NB\x88n\x0b\x9a{\x8d\x99k|\xac{m\x9b\xa5Z\x1e\xef\xdeW\xc5\xa2\x8b\xed\x9d\xadv\"]\xbf\xbe\x10c{g\xbb\x13^\xaed\xe5\x0f\x1d\x17,\xaf\x9d\xc6\x95N\xc8\x9aX\x9ax\xc5\n\xc4#\x08-\x0c \xd2\xcdx\x80\xef\x05cB8\x8b\xe4{$\x9f\xf9)\xb1 c\x92&\x18Z\x9e\xe5Q\xb0\xb7v\xdb\xd22\xb8\x990\xae\xa2\x06y\xdc\xccj\"\x84\xc7w\x9a\xb90\xd7\x11H\xa9\x8bq\xf2\x84\xb9F\x1761_I#05\x86\x91\xfd\x12\xacSz\xa2\xfcX\xbc\x12YP\x90|sk\x07F\xbcd,\x16\xab\xd9\xc27X\xd7\x8a\xcb\xe5)\xc9\xe47\xf5\xaa\xf2.\n\xef\x8b/\xf8\xc8\xd0\x15\xb2\"wg\x94{)\\\xca\x83\xb2\x00\xcd\xfbP\xc2: \x05\xb2\x89L\xb0\xe3\xc2HM\x13/0\xc6\xa5\xf2\xc8\x9c#\xb3)59\x81\x18\xd6A\xa1y\xa1\xab\xd2\xe4\xcf\x0b\x8d\x06\xa1\x92j/\x99\xc4zII\x8c*\xbc\xf6r}\xdd\x81\x05\xac\xef\x01\xb1S\xba\x0f\xd3\xe5\xb1\x0b\xe78\x97\xd4\x85\xa5\xc3w\xaf;\x02Ml[\x90\xd8\xa2P\x99\x8d\x10\xf8\xf0\xcf\xfaP\xd8\x95\x8b\xd1\x04\xcf8m\xd7\x13Z\xe6\x0c\xc1\xa0\xf0H\\d!\xe91s\xa9\x16\xe5\x84-\xca\x9a}\x05{p\xea\xc5\xe4\xb2\xb0\x1d\xc7\x0b\x12L\x1d&-\xcc\x15K;#\xad\xcd\xc9\xfa\xba~u\xc4CW\xa9\x7f$\xda\x01\xe8\x17H\x91i\xd2\x8e\xe1\xae\xcdSU(\x92P\xdd\xc1\xca4\xc7\xca\x0e\xc2P\x0e_\x0d\xc6\xd6\x9e5\x01koS\x03\xc1\xd6\x04\x8b\xc7V\x17J\xb4\xf2\x02\xeb\x0b\n\x93\x1d5\xc0\xbd\xe9\xde\xe4\xf8\xdeY\x1fc.5TL\xc9q\xb7_#GY\xc6w\xb3(\x9b8m\xdd\xa2\xec\x8di\xf1d\x95Ea\xcba[\x1e;\xccd\xba\x89\x1az\xbaV\xeco\xd4D\x13//O\x19\x15`\x8f\xd1\x97Pz1r\x1ci5\xed\xbd\xcd\x0f{c\xe7\xee\x17\xb4\x86W\xf5\xd9\xb9\x13\xfd\xd7\xfd]\x87\xc7\xe8\xfc\xc6\x9f\x15Iv\xd5=\xc5\n)\xc0\x84\xa2H\xbfM\xa5b\xd1\xe9i\xc6JOO3e\x85 \xc8H\x9e\xb3:\xec\xb7\xb2ZFx/\x19Qw\x94\x15\xe1,\"\xbc\x0e\xfeVV\xcb\xc3\x80W\xa2\xbf\x94U\xca LX\x15\xfaKU\xe5\x14\x8bO\x95E~\xce\xda\xa7?\x94\x15\x82\x90\x95\x07\xa1\xba8\xe1\xc5\xea\x9e\xc33V\x1c\x9e)\x8b\xa3d\xf6\xfe\xefeR\xf01T\x7f*+'\xc1\x15\xab\x96\x04W\xca\nl\xeb\xd4\x1bwZ\x16E\x12\xb3\n\xf8SUi\xe6\xc7\xe7>\xdb\\\xf6S])\xa5\xe0\xcak\xe1oe\xb5\x90\xcf\x8a\xfePVH\xf8\xd6\xd2\x1f\xea\n\x11/\x8f4\xc5gYR\xa6\xa2\x0e\xfe\xa1\xaa\x18\xf8\x05\x03F\xfaCW!\n\xf3\xa2\xaaD\xffPV\x0cX\x95@YH\xd8p\x03\xa2\x1cn@\n?\x8cr^\x05\x7f+\xab\xcd\xd9\xca\x06s\xe5\xaa\x06\xa1\x1f%\x0c\xa6\xd8Ou\xa5s^\xe3\\Y\xcc\xc7\xa9\x1e&_\x05\xe5\xfc\xc9\x12\x0b\xc9R]xJ\x02^~J\x94K4\x0fI\x14`\xd2\xe7\xcc\xb6\xc4\x1f\xea\x8ag2\x98\xd5\x7fj*\x97\x19\x11\x15\xcbL L\xf3$\xc1\\\xb5\xff\x1f{o\xda\x1d7\x92$\x08\xbe\xdd\x8f\xf5+\x9c\xf1\xaa% \x03\x0c1H\x89\x94B\xa2\xd8J%\xb3[\xdd\x99\x92FRVMw0\x8a Fx0PB\x00Q8xdQ\xef\xf5\xcc\xec\xdc\xf7\xee\\=\xf7\xd9\xb3;\xf7\xb1\xc7\xec\xce\xf4\xf4\x87\xce\xfc#\xf3\x07\xf6/\xecs3w\xc0\x017\x07\x10$\x95U\xbbo\xf1\x81D\xf8\x05wssss3s3Q\x08^\xe9B\xc9R\x16I\xc81.\x86\x90\xbd\x18\x92\x99\xdb\x98\xb9Mf\xee`\xe6\x0e\x99y\x1f3\xef\x93\x99\x0f0\xf3\x01\x99\xb9\x8b\x99\xbbd&\xf7qB\xc4\x8b\xad\x80\x04\n\xbe\x92\x85\xcaU\xb6\xb0\xae\xb1\x85l\x85n![\"\xca\x89\x17\xaa\x00\x92X\x92\xc0\x06\xf3\xc4_\xe2\xe4\xe2+Yh\x89K\"X\x92\xeb!\x88V9\xe2\x1c\xbc\xd1ERY\x80\\\x95\xefO\x10\x90\xefOH8\xbe\xe7\x97\xa7\x1cQ\x15_\xa9B\xa1\x7f\")\x04\xbc\x91E\xf8)\x8f\xf0K\xf8J\x16Bh\x85$\xb8\xc2 z/\xb3\xa3\xf7T\x81\xa5\x1f`G\xc5\x0b]`%\xf3\xc9\x89^\xfa\xc9{\x99\x9f\xd0\x1f\xe0Q\x8e\x05x\x94\xdb\n\x04\x99$%\xea\x07]P\xd2m\xf1b) \xb1\x17\xde\xa8\"\x91\x8f\xa40\xf2IR\x18\xc5\x18M\x19\xcb\xc8\x1fTA<0B1y\xac\xa5\n\xe1\xf4\xd2\xdbU\xbc\xca\xca\x85\xa4~X\n*\xba\x17[i^\x9cg\n\xa7\xf1\x95*\x84\xdf\"?\xb2\xf2\x13\x1fg\x00\xde\xc8\"\xc14StU\xbe\x93\xc5T\x11[v|Zp\x8c\xea\x07U\xf0gP\xe2gTV\x82\x03I\xc8\x91$\x08\x85\x84\x84@\x92\x9f \xcf$^\xa8\x02\xd8/\xb2C\xa9\xbf\xc4\xef\x8a\x17\xb2@\x89:v\xc4I\xf9\xb4\x98N\xf9N\x17\x0b\x15~\xe1+Yh\xe9\x87\x88b\xf0F\x16\x89\xf3d\x8a\x13\x82\xafd\xa1\x95/;\xb4\xf2\xe9\xdedI\x1c!I\xc5W\xba\xd0\xa5d\xe0\xe1\x8d,\x92#\xeb\x9d\xe6$\xf3\x9d\xe6\xcb\xa5\x9f\\\xca\"\xf0N\x17\x93\xf3@\xaf\x97\xcc?\x91\xfd\xc80R,Q\xa4\xe0\x9d3\x1b\xf3\x9c!\xd9\xcdH\x92\x9b\xf1\x8b\xac8\xd2\xa8\x1fdA\xc1[`)\xf1F\x16Y`\xfe\x82\xceT[vf\xdb\xb3\xb3@n\x87\xe2\x85.\x90)x\x887\xb2\x08R\xcd\x8c$\x99Y\xe2O\xdf\xcb|\x7fJ\xd2x$\xf0$u\xcf\x11As\x12;\xcf|\xfc\xf0\x99O~\xf9,\x98qW\xfc\xfa\x9c$\x11<\x0c\x83\x95<@\xcaw\xaa\x18\xae$\x9a5Y\xfa\xa7\x92\xbb\x11oT\x910\x88\xb0\x84x\xb1\x15\xf0\x93_K\xfcY\xc0\xa3\xac(Z&Q\x95\x96~\xaa\xf6\xf1\x94\x9c\xe3\x95\x82\xd0\xca\x02\x9d\x95\x9fe<\x89T\x19\xf1N\x16\x8b\xc3\xcbSI\x00\xe5\xbb\xadX1R\xf5\x83*(\xc6\xe4\x87\x95\xd1V\x93\xc8J\x8a\xb8&6\xd2\x9a\xc5\x92\xc8d1M\xec\xcf$=<#\xe7Q\x10\x85\x82:\x90\x05\n\xa2\x9b!\xd5\xad\x94\xb0\xc8\x88P\x05{\x0b2\xa2\xaa]f\xb5w2\x1a\xfb\xae\x1e|\xac\xd2 eMv\xc3~\x18\xc6\xd7\xf8\xe1\xba\xe95j`)\xfdk\xe4\x0c\xeb\xe1\xb5r\xd9\xf7zq\xb4\xa8\x7fp\xff\xbeeL\x8df\x1f\xcal\xe3&\xf2s&\x8doi\x19\xba\xfa\xcaT\x94x\xf2\xc4\x8f\xe2\xe8r\x19\xe7\xe9\xd3\xa7\x84\xa8tn\x95\xaf\xfah\x99v\xe6\xf4\xe0\x8dB;\x06\x82#\xc1\x98\x9e9\x85\x12\xd5RN\x0c\x17\xca\x15\xe3\xb6\x14Dm*\x14\x95\x8aUKA\xc55\x9f5q\xcd\x0c\x19\x8e@0\x1cg\x8eR\xde\xda\n\x02\xd0\xb1 \xbc\xda\n\xfa\xd1\xe5\x88-\x9cD7\xb3{ \xdab;(_\xcd\xdb\xe4\xdd\xeaQ\x9a\x9c\xaa\x7f\x1fk|\xcc\xfaS\xd3wh\xb7\x9a\\\xdd\x94b\xe6\xf4\xd4U\x13\xf6u\x8f\xf5!8j\xefk\x16\xcf\xcbx]\x98\x91`\xc6\xc2OY \x03\x16\x8b\x9a\xef.W\x9cEq\xe6\x83\x8a>\x88\xd2`\xc6\xd5P\x07m~\xb0\xce\xe4\xbd\xc0\xac\xd5\x99#\xdcn\xad;[k\x83\x01\x93\x9f\x00+F\xc7\xef\xee\xf4CBF\x05f\x16\xc3\x8f\xc5\xf0\xeb \x12 \xc5\xb4\x14\xd3\xd2|\xb5\n\x03>cY\xacC\xcdc\xfcb\xc5\xa7\x19\x9f1?B\xe8\x0c\x08g\xb1\xfa\xd3|Q\xbfP8\x87\xa8p\x0e\xd9\x13-\xc8u\xd8\xefw\x05\x0d\xdc\xd6p|\x8f\x85\x05f\x89\x1e\x8fE\xdfC\xf16\xe9y,\xef\x0091AS\xddf\x11.\xe5\x95\x16\x0e7\x18,ey^\x7fl>T\xe8\xa5\xc8q\x93\xea\xe0Q\x80\xdd|%\xae\x89\xe4|\x0d\xc4\xce?>b\xe7\x9d\x11\x9b\xa5At\x1ar\x8c\xbf \xd9\x80\x9ba\xf9M&\xde\x16^Ja\xe8\xf7J\x887\x1cp\xba\xa6\xad\x0e\xdey\x8e\xf1\xeeN\xe4/\xc1\x98\x95\xb8\x9fC=y\xab}\xb1\xedA\x1c\x1cL\xe3\xa8\xb8;qu\xc5\xaa)\xd0\x9bri\xb7c\x9fz\x94\xd1\x99\xd1X\xa7\x16>\x00\x14\x7f)\x90]\xcd\xa4\xa8\x0e%|(\xf1\x8bCw\x0b\x17\x05\xfa\xafk\x12\xb9\xc6\xbbL\xf5\x07\xd0f\xe9\xf0q6q\xeb\x0c\x86>\x01I9\x01\xb1\x05\xd8\x91IY\x80\xa4\xbc\x8cg\xbc\x95\xa3\xb8 \x0cm$\x03\xf9\xca\xef\x95`\xfc\xc2875\xd6V@\xeb\xbbZ;M\xea\xc6\x81UL\xba6*\xf1\xec\xd7_\xcb\xebpd\xf8\xcd\xd61k\\\x17\xf8\xa5h\x1d\xb6\x18\x90?X\xf8\xe9\xab\xf3\xa8\xb8[\x1ev\"\xfd\xac\x99A\x1b\x00\x83\xd6\x8d5c7e\xcf\xd8/\x80t\xc5\xd1\x1a[4q:\xd0<\xe5\x18\x07\xb4\x06\xbb\xbe\x9b-\xdd\x02A\x8a\x95\xa1{X\xe6\x05\x83\x9e\xeb\x17\x8fm\x8f\x18\xd4J\xcc<\x07\x7f\x1e:\x8c\xdb\x97\xa6Xp\xbf\xf1\xf6\xd5\xcb\x01\x9eu\x83\xf9\xa55\\\x80z\xd6\\i`\x1f\xaao~\x1d\x96Z\x1c\xc1\x8eY,\xcf\xa6\xfd\xf2\x1a\xe8\xf2\xee\xb2\xdd\x9cL=\xb7\x862\x157\x1f[\x8fYV\x99\xe9\xac\xfd(\xa6dAb\xef\xec@\x1f\xa9\x9d!*:\x1e8\x1bC\x8f\x15\xb3\xa7\x9c\x87T\xe6\xa6\x80\xd5\x80\x1d\xd6\x8f\xa5\xb0},\xf8\xf4}\x01\xc6\xd4c'y\xc6\x12>\xe5\xc1\x19\x9f\xb1_I\x99\x9f\xb1 \x9a\xf1\x0b\xf6+\xe9\xa0\xe7\xb1\x13\xf4\xed\x05\xf7\xa4k`\xb3\xcf\xee\xf7\xb2\x04\xa5o\xd1r:\xfc\xf6\xe9`\xda\n\xe2\x9d\xbc\x8f\xeaWX\xd3jo\x05\x81v;QG\xd6\x99\xc6vY\x9f\x96\xa5x{\xeb-]t0\xddT\xcf\x0d\xa7\xf4\xff;\xac\xc6\xd7\xf8\xc5\xaf\xd7\xe44:\x1d\xe0\nfa\x1cv\xc4\xd9i\x97f\x99lz\x0en n\x85\x0f\x99\x17\xa0\x9e\xb7\xd6i^\x12\xdd\x16\xcc\xed1%\xfc\x02BK~oX\x9fv\xc6\xfa\x10\xb0\xbe\xee`\xae\xfe\x18X\x1f\xde\x00\xeb\xc3[\xc7z\x85\xc2>:\x93\x04\xfe\xa9\x8dk)V\xca\\\xac\x94N(-J\xaf`\xa5\xcc;\xae\x94\x8d\xd5zpz\xcf\xe5\x99l\xdeL\x8e\x8f\xa2O\xfdY\xa1\xc2\x10\x195\x9e\x0da\x80\xd7\xf9{L^\x139\x8a@\xd3\x06\xb7J\xc8Z\xfa%\x13\xe5\xa7K\xd6\xef\xb0L\xcf\xe4\xa5\xb2\x95\x93zln\xae\xf6y\xb7\xd5.\xe0\xb6(\xc0\xb6\xf8\x05\xadc#\xf5\x83vE\x92\x99>\x87(\xfcQR+y\xfd\xef\xa0pR\x7fu\xc5\x86\xec\x1ed\xc0K\xc6F\x8c\xc3\x85I\xb8\xed\x07\x0cZ\xa5\xb5\x0f\x96o\xcfhJ\x02\x17g\x97J\"\x81\xe8\x84\xe2=\xf0\xd8\x1c`\x92\xa37\x1ep\xb1\x13#+\xfa\xdc\x0f\xc3 :-D\x0e)\x83\x95\x03\x8e\xb9\xd9,H\xf84\x0b/Y\x90\xb2(F65N\x04\xd18\xb9\x84\xc0*_\xaf\x92x\xb5)\x88N\xfa5[\xf9\xd3\xf7\xfe)\x1f\xb0\xafR\xce\xbe.\x1a\x1c\x00\xc3Z\xfct\xdc\xaf\xc5:\x9b\xfaa(\x9aX\x0e\xd8\x1b\xee\xcf\xd82N\xb8\xe0\\\x17Y\xb6\x1a\xdd\xbb7?\x19,\xf9\xbd<\xe5\x9bP{\xb3\xfc\x8eu\x91hx(f<\x19\x07\x13v\x007+\x8b\xcb\xa1*\x0d\x89\xc4\xbb\x05/\xcf:\x15\xa2\x19\xa4`\xe5(\x18\xef\x94%\xfcgy\x90\x80TQ?O!\xdf\x1dd\xa9$\x067b\xdc\xa9\xe0H\xdb\xa5k\xa6+\xe61\xbc3\x92\xa1\x0d*\xb4^\xba\xd6B\x1co\x10\xd7\xdd\xd5#\xc6\x10c,\x91\xa4\xdbm\xee\xa4v\x9b\xbb\x8b\x10\xe11\xdb\x80\x10\x91A\xed\x16ucMV\xeaBb\xbcB\xadM\xe4\xd0\x0e\x9a5nvS}\xea\xc8\xf5\x82\x17\x9f\xae7\xbbAx-\xf0cc\xe9\xf8\xe3\xe1\xa4\xd3@X\x17\xd9\x8e\x0d\xa3\xa5[\xd8\xf6\x05k~\xbf\xeeu\x96&s\xa7\xcdWL\x95\x9e\xc5\xba?\xd5\xe5\x85\xec\x80I\xbb(\xe0\xfc4\xf1\xfa\x1b~zx\xb1*\xef\x81\xf7XGG@\xf2K\xca\xf4\x08\xaf\x9c\x82;\x89\xb7ZJ6\xee\xfd\xea\xaf*\xd7\x1b\xef\xfc\xd3\x1e,\xe0\x16k\xb2L\xef &\x9bpD\xa7W\xa2\xe3\xaa\x07\xf58r6\xe0^\xda\xddwiN\x98a,\x05\xb5+UZx\x07\xd9\x84\xbc\x9a\x9bSR~m8\x01ht\xb0T\x99\xa1\xcf\xfcL\xfb\xfa\xcc\xcfx\x8f\xc6J\xa3&\xcemY7\xe1\xa7\xfcbE\\1\xb6\xa1Q7x\x9e4#+-\xd0/v\xec\xe6\xad\x1a\x91\xb6i\x1bn\xdd\xf6\xd4\xe8\xfd\x088\x9b\xc6=\xb4y+\xc620\x03M\x05$\x98;\xf4\xa8\xa9C]iL\x9b\xd3\xb7\xea/YIs>\xc9\xf6Q\xc5V\xa6xl^;\xa9\xb0}\xc1J\xcf\x07z\xc2\xdc\xd3\xa4b7\xf0C\xd0\xe4x\xa7P\xe9\xdfR\xfb\xbd\xe1\x83\xc1\xee@z\x1e\xb8Vkg\xa5\x8f\xe9\xdd\xfb\xee\xa0\x88\x98@Y\xf3\xb6\x19\x1b\x07\xb2\x9d\x07\xa4}\xef\x83\xfb{\x16\x83]\xdfQ\x92\xb9\xdb\x18\x87aG\x8c\x9d\x1fn\xd3n\xa3\xeb&\xca\xa2\xb3\xbdep\x11Di\xc7I\xad/xuf\x19\x13\xd2\xc3\xd4j\xef\x8b\x9f\x1c\xb1\xdeg\x87\x9f\xbfxyx\xfc\xe5\xb3\x97\xbfe\xf1\xad\x90f~\x16L\xbb\x95])\x0c\xefTZ\xfaS]\xa3\xc2\"\x08g\xcf\xd7\xadu\xca\xb3\xcf\x90\x1a@\x84\x9dj\x9d\xe3/\x0f\xdf\xfc\xda\xe1g\xf6\xaa/\xa2 \x0b\xfc\x10\"\x17\xadY\xf5\xb9\xd6\xddu\xaa&<\x82\xbb\xb4\xaa\xc6\xab\x97\xcf\x0f\xad \x94+\xe8\xc7A\x18~\x89\x8eK;\x80\xa4\xa8\xf6Y0\xbbF-\xf1\xb17\xa8($@j\xc3\xa3E\x9c\x0bp\xc86\xbeZ\xcd*\x10\xed:\xc8z\xbd.\xfd\xfd,\x98]\xa7\x1a|.Zv\x86\xcfW/\xdf>\xfb\xfc\xf0\xf8\x9asB\xd5^\x1b\xc8T#k\x0c=\x87\xa2\xc5\x1c\x8dX\xef\xd5\x8f\x0e\xdf\xbcy\xf1\xd9\xe1\xf1\xa7\xcf\xde\x1e\x12\xbc\x8f\xd9Nh%:\xb0\x10\x93\xe0\x8c\xcf`5}\x9e\xc4\xcb\x86\x15\xd9\xe5[S\xeb\xb7fA\xba\n\xfd\xcb\x97p\xe3\xbb\x13G\xce\x80\xf0j\xf5X]\xac\xab\x1e\x8b\xd6H\xd1\xd4\xce_\x13\x1cgK(\xb9B\xed\x11\xa1\x9a;\xaa\xb8a\x8b\xfa}W\n\xb4\xc7\xd1d-\x15\x17AJ;\xf7\x9b\x0f\x8c\xda\xe2\x88.C\xa6\x19y\xa4\xabP\xd6\xd0\xb5k\xf7\xca\xd2\xa1\x1b\xf4\xc5\xd8;\xd6\xe8N\xad.8\x13\xaa\xa7\xed\xb3\x85c\xa4B\xcb#\xb2\xf4Z\x08\xa9\xed\xc6kt{\xa5q\xa9\n\x84E\xda\xba\xf0+\x98\x87\xce\x1d\xd8\xe8^\x94u[C\xac\xba\x8e\x82\xa8\xbdU\xf5(>\xaf\xdd\xa6_=\xd0\x9f\xba)`\xd4\xd9\x14\x90)\xb1\x97\xe0\x16A\xd3\xd9\xed\xb3\xe2 \x9c\x8d\xd8cw\xc1\x88\xf6y\xe8\xa7\xe9\x88\xfdV\x9c3\x1f\xf4!\x19_\xae\xb2 :eY,C\xcf0\x9f%<\xe5\xc9\x19\x9f\x01\xa6\x88\x9ez\xec\xeb_I\xbf\xf60\x16>n\xd8\xd1\xd1\xdd\x8c\x9dp\x06\x11\xf2A\xb4\x0b3\xdac\xef\xf9\xe5\x80}\x86M\x05\x19\xf3S\xe6G\xa5\xc1\xb4j\x11R\xb8?{,\xca\x9c\x07a\xc8\xd2L\xfc=\xe1\xcc\x9fNy\x9a\x06'a\xd1\xb8n.~\x97vRo{\x94\xd8\x0b\x80\xd6A\xea\xa5\x1e\x90~\xad3;L\xe3\xb9Cs\xa2\xd9\x01\x0b\xc7\xd1D\xca\xe9\xbb\xf7\x83\x95\xa7\xcb\xc0\xa1\xb6C\x10{\xe4\x1e\xebu\x9e_1\x95\x02\xb2\x97q\x9eh\xb6\xc2\xa0 \xcb\x16~\xc4\xe2h\xca\x07\xec\xdd\"H\x05\xe4\xe7a0\xcd\xd8\xd2\xbf\x14s3\xcb\xb9h\xc9\xc7Mm\xd0C\x07\xc8gq0s8\xc6\x95_\xc0\x8b\xc7\xa8\x80S\xb6\xa7Y\xff\xab?\xf2#\xb4\xc7\xe5\xfa\xd3\xde\xac\xbd\xc4\x07\xa42\xeb\xd04?\xcf\xe2\x93 \x9aU-\xee\xd7PA\xd3\x81u\x98f#\x98\xd6\x11+\x13\x88\x95\x8e3;b\x9d\x10U\xee\xdc\x11\xc8Te\xe1\xd0Ml\x05\x8f \x12\xc2\xdc\x9fr\x1bB\xc5g`\x87Q\x9a#\x86eXj\xc9\xb3ENDg\x9f\xe5Y\xfci\x10\xcd^\xfbAb\x89TY\x8dR\x19\xd5\x97\x99\x0f\xcbl:@\xee\x1f\xa6T\xbe\xbb\xa4\xbfw\xf5\xc0\x1c\xd7\x1bC\xbb\x8a\x1cC\"\xb6\xedJg\xf2^h4\xce;X\x8e\xad`\xd8\xc6\xf7\xda\xf5\x80sg\x85!w\xa6fm\x97M\xc7\xf9D\x0c:li\xa9\xc1\xef\xb3\xfe\x881\xcd(\x02\xd8\xd6S\xd6d7\x0d\xc6+\xe0\xac{\x05\xb7\xdc\x86H*\x06\x8a\x92w\xdb\xc1\xc0P\xbfmR\xf4\xe7L\xba\xcfN[\x03\x96\xeaO\xe0\x80\x13q;\x13\xb0\xac\x13@\x99\\_\x81_E\x85\x11\x81 \xd1l\x15\x87\xc1\xf4\x92\xfdJ\n(\xfd\x9e\xc3\xeb\xf9\x82G\xb8\x02O\x81\xdd,\x96\xa6\xa8\x02\xc4x\x89\xb3\xdf\xd0\x9d\x03\x96`\xe4\xd2\x85#^\x042\xb0\x11\xd5C\xf4\xe0\x8be\xcf\x8a\xb2\xdd\xa0/\xddA\xcb\xda\x1d8+(\x1ec\xd0\x93\\|\xc7+*7\xd6m\xe0\x15\xcc-\xbe\x13\xa1\x9fY\xf7\xfb\xea\xb1$p\xa4AY\x83\xaf~\"=\xf3Xo\xc9\x93S\xaeB\x1c\xbd\x8c?\xcbW\xa1\xd8\x90\xf9o\xf2\xcb\xd4qG\xec\xb9\x1f\x89m\x17\x8a\xb1(\x8e6\xb1\x99\x14\x08x\xe62\xe2\xc8\x82Q\xca*:=`\xf8Z\xbf\xf5.\x91\x06-\xf8\xb5\xec<\x96\xf4;\xc5\xed^p\xfa\xa9\xbf\xe4\x18\x06]l\xbd\x9dv\xd6\xc7\x02D+\xf0\xf0*\xf6\x044\x92SE\xa7~\x9eJk\xb2\xf3\xb8.\xb6u\\\xb1\xc5\xd5\x0e\xd3\x8e\xab8\x0e\xc9w\x8b\x15P\xe9\xa7\xd8\x1c\x17\"\xf5=\xbfL\x15\x0b,\x19S\xcb\x0dUeB\xd8 -\x16m\x96\x88:{i\xdd\xf70\xb04F\x83\x15\x10\xf1\xcaH\xb2\x96{\x8e\xe2\x81C\xad\xa5\x96]=\xaaL\xe2\xca{(I{\xe1\xd2\xd6#\xb2\xef\xde\xe0^\x98\xf0\xd5\xcc4\xa5\x9b\x13\xe3\x14\xc0\x0b\x1dV\xa4\xdbz<\xbb1\xe0\xad\x00\xb7\x02\xf5\x9a]]\xb6\x1e\x1524\x9e\xa3\x94\xc4\n\xec\xb5/\xd5[1C\xd1\xa9\x87P\x13\xb4\x82\x86)\x83\xd6\xe3\xe3 \x85J`\xe3\xb7\xb1E\x96&H\xaa\x89\xb4\x97\xed\x1d\xac\x88\xea\xaf\xddG\xda\xde\xa5S\x1fO\xac}\x94\xfe\xc1\xa5\x02\xa9\xb3p\x0b\xfa\x87\xf2\xf8d\xc0\xa3\x9f\xe5<\xe7o\xb4\xa6$\x86\xad}z-\x06\xdc\x11N\xca\x16g\xa3\x0e\xb0\xeb\xc3\xea\xd8\x1e\xd6\x97iF\xa2\xce\xb1\xaeT\xd7y{vB\x90\xb6\x12\xb2M\xe42\xab\xa9T\x93\x06sPV\xa2\x89yXP\x91\xd7\xee\xdc\xe9\xf0e\xf5T.\x11r\xb2]\xcf\"\xeag\xfd}\xb6\xdd\xd6>\xab\xc9,\xdb\x8f\x05L\x9e\x88\xb2q\xc4\xfal\xd8\x81O\x85\xe0\x0b\xfbH\x99\xe2\xeb\xfaA\xf8\x00\xe8\xab\"\xda\xad\xa4t\x9b[C\xe7&|\x0e\x0e\xc4\xbc\xca\xbaP6\xeaQi1\x9fq\x19\xcb\xc7>\x90\xc2\xcaWT\xa9\xb1\n\xec\x80Lv\xdcV\x81^\xe0\x10\xacY\x0evuUs2`\xa6\x7f\x85\xf8\xc4\x88-\xc5\xc9W\xa2\x7fq]]\xf0.\xe2\xd3=\xb1\xb9\xe8\xea)q\n@~_P\xc14\xd0\x14w=\xb7\x06\x91\x9c^\xad-'\xde\x04\x84\xe5\x15c\x97\x88\x9f\xb3cOO\xac\xf8\x10\xc1h\xc8Z&\x85\xe22\xa8_>\x90!O\x9d\x95n\x00\x9e\xb9\xae\xc7VN\xe6\xb1S\xf5\xc2\xd5\xcb%\xec\xb0u\xb5\x08\\EP\xc1\xe6\x0bMI\xbd\x98\xe3\x82\xacB\xef\x1c*\xda=\xd6\xc3\xc0\x07pnr\x06\x83\x81`\x98M\xd1\x16NO\xb0\\\xa15\n\xf3\xd9\xd7\xd8\xc0\xd7\x92\x93\x04f:u\xf5\xf1\xcb@%N-I\x86\x9bj\xe4w\x9a,\x93n`\xd0s\xd6\x12\xd3\x0c\x0co\xca\xe2\x91cs\xe6g\xa7zr\x00F\x0cg\xee\xca\xe0\x96\xc3\xfb;\x10\xdd\xf2v\xc7\xb3\xbdG\xdb\xe2)\x1b\x00\xb1\xd5\xc5.Ek\xfd\x12*5Z\x0b\xc1X\x1f\xeby\x96#$\x8f\xf2%O\xd0\x01\xfe\x86%\xd0\xe8)\xef*]Q[\xf3\x80\x96\xb5\x13b\x82\xc6\xbe\x07\xdf{\xbf\x83[\xe9\xb7D\x93\x8e\x9d'\x1b\xcf\xea\x08\xc4\xf6\xd9\xd0Bv\x18uz\xb8\xc1\xfao\xa3E\x80\xb7\x9e\x14A\xe3M\xa3*\xca\x927\x95\xe0&\xf5 >Iyr&\x86.\xce\xdcp\x0bXK\x1a\xc9\xa0\xbc\xe2P\xad\x12{\x10\xd1]+\xb4\x8fvr\x19:\xc7\xd6\n\x92;\xf0\xf7\x02\x91\x8a\x80\xc7\xf0\xcf\x00Bn\xa4\x98[\x8fYP\x11\xf0\x04\xb4\xcb\xa2\xb3\xc2)N@\xc8f\xb6<\x1a\xc4|\xecO\xf0\xe2\xa7xA\x07G\xb6\xbd\x8ai\"\x11\xbd\xc7u\xeb\xab-\x93\xd8\xa6\x16F\x8a\xe6\xbc6:\x08\xca\xaa +\x04\x04E\xc5F\x91\xe9\x99\xe6a\xabY\xf2\x85\x07C\xec\xbamm\xeaO\x06\x1e\xc7\x04;\xfb\xe2\xe5\x8bw\x8d\xc5?\xb4\\Q\xd5No\xb1\xcb\xb2E\x12\x9f\x83P\x05n\x119w\xdf\xf0Y>\xe5 \xeb\xdde}\x96\x81\x1b\x90\x9e\xc4`>c\xc5V\xc9fy\x82*[\x90 \x05\xdfH\xe3\x9b\x17sT\xaf\x81\xd8g\xe5\xa7)j\xe2DZ\"[\x0e\xd2\xb2\x19\x8f]\xc69\xca5\xf8\xc5*\x0c\xa6A\x16^\x16\x0bf\xc1U\xfb\xd8\xe0\x80\xbd\xab'\x81\xfe-\x8a\xc1B\xb0h\x15\xba!\x1a\x9e\xc5\xd1\xdd\x8c\x9d\xfbQ&:\x91\xf2\x8c\xf9\xd2\x01\x81X'\xa0\xbf\x93\xbd\xc2\x8eL\xfd\x08\x0c?\x80\xb9\x91\x86\x83,\x9ek-7\xb9\x96\x11\xd3\x1f -\x10\xad^\xdc{\xfd\xe6\xd5\xa7\x87\xc7_\xbd\xfc\xcd\x97\xaf~\xfc\xf2\xf8\xd9\xf3w/^\xbd<\xee\xb1>\xfb\xd2\xcf\x16\x83\xc4\x8ff\xf1\xd2q+\xa1\xcd\xb5\xe0\x9e{\xee ]\x85A\xe6\xf4z*\x80o\xe3\xe7k\x93\xdb\x15\xbd\x10\xb5\xe8\xed\x86\x01>\xdd\x00K@\xbb\xbfJ\xe2\x13\xf1\x1ed\x0b\xe63\x1c6|v\xc0>\x83 \x12\xcb5\x8b\xd9\xc2\x8ff!z\x99P\x98\xce\xfa\xec.\x8b\x13\x16g\x0b\x9e0\x1f\xd6 \x88\x18z\x08\xe1Ozh\xd6\xb5\xf2\xd1<\x8a_\x82\x8d\xd54\x06/\xa3 X\x96\x06g\x80:\x85yO\x81q\x1a\x9aM\xf3$\x01\xa3\x03\xc0)\x81\x1c~t\xc9\xf2\xe8}\x14\x9fG\xea\xbb\x1e\xcb\xa3\x90\xa7)\x0b\xb2\x1a\x12\x07\x11;_\x04\xd3\x05\xde \xa4>PAZ\x8f%\xfc\xd4Of\xd0X\x8c+\x06\xbf!\xc1\xd2\x0d\xcd\xd1\xa9\x86\xc0\xd9\x13D\xd9\xc1]\x8b&\x86\xd0\xfe95\xd3\xa0\xca\x01\xd3(\x0e\xc2\xf1\x06\xfa\xddEo)\x96\x87\xd83\x0b\x9d\xa4\xd2`\xc6\xb2\x12\x14\xc9\x80\x8f\xb2\xf8*/\xbd\xbc\x88\xceb4\xdcz\xed'>\x84u\xff\xb2\xf0\xb1\x9b\x15\xac\x84\xf4\xf4@\x124\xf0\x16$\xb6\xae]\x97\xd8\xbbD\xd6\x83]#+(\xb2\xf6\\\xf2X\xeb[\x95\xba\xd2v\xa4\xb2\xfey\xf3\xfa\xb7\x1e\xc0\xb5\x05_\x1bj\xa2\xe6\xd8[\x0bd\xb1^\x8d\x82\xff/1\xe9\x15\xbds\x04\xe5%\xa61P3L\xcdU\xf0}\xcf\x15E\x9c\xed\x8e\x9f\x82\x1a\x89\xa6\x0e\xb5\x1b\x81\xa4\xb9\xa5'\xbb\xb7Y\x9cp6\x8b9zc^\xf8g\x1c%\xf3\xc1L\xc9\x1c\x06\xecK\xff=g\xf2*//#\x8c\x94J\x85\xfa\xe6\x1b\xa4\xday\xf7|\x11\xa7\x1c\xa7&\x05\x99\xb0l7\x1d\x10\xc1k}I'\x0b\x14s\x0d\xed\x13\xba\x0d-\xb6\x84\x17\x19\xaaM\x07A\xaa^\xf5\xb8.\x85\xbbd\x1f$\xd8A\x8aB\x91\xe2\\\x9e\xd5\xa2\xa2\xa8\xc1e18&\x88*\x81\xdf^,\x979\xc4\x83/\xbeZ\xdec\x9a\xc7a\x18\x9f\x07\xd1\xa9rx\x10\x80S\xaa\xbb\xac\xcf\x02T\x1a\xdc\xedy\xacw\x17eL\x83\xbb\xe6\xd8\xe1\xc0%f\xef-\xff\x19(#\xf0\\\xe8\x0e\xe6A\x98\xf1\xa4\xe5\xa8 \xc7\xbba\xdc\xdf\xaa\x1da\xeaZ)Y/\xd7e\xc0\x07\xac\xa7]\x19\x04\x81\x04^\x94,J\x1d\xb0\x9e\xf2\xeb\xd0c\xa3\xe2G\xc0S\x14\x97\xe1\xc0ss\xe0l\x1e\xe7\x118\xa5\xbe\xab&E\x03\x7f\x16\xb3y\x10\x15a\x83\x04\\Q\xf0\xaf\xe4_\x853 \xbcC.\xc5\x1a\x0dp\xd6\xef>\x96\x9dD\xff\x13'\\J\xeaf\x83\xbbuw\xca\xb7\xbf\x1b\xde\x1aE\xf3\xd6\"\x0euo\x9c]tH\xa4d\x13UH\xa0\x1a\x12X\xaed\xa7\x97+)\x0bEQ\xe7\xad\xc8?\xeb\x02(M\xb6y+\x13\xa4W\xacB\xab\xa0\xd0b\xd7\xae\x07\x00/\xe7\xa9:#]>\x199\x8fP\xc4\xfd\xe8\xa1[\xedy\xe4<\xd8\xdb\xead\xe0Y\x1e\xa1\x87\x86\xafC\xe9l\xf0\x91\xeb\xf4\x8a\xd8\xe0\xa4\xad\xf3\xde\x96\xc5\x8a;r\x86\x0f\\\x8d\x8a\xaeq*\xb0\x1d\x084ER6\x8e\xd1c\xad\x16\xbb\x1c\xee\x14@4\x81:\xcdJ\x1c]~\xd7 \xc0\xcdV\x86\xf7~\xe2\xfc\xca\xf6\xd6\xd5Q\xea~\xe2\xfc\xd4?\xf3\xd3i\x12\xac\xb2\xab\x99\x9f\xf9\xee\xbd`i\xc2\xf2\xde\xf8'G\x17\xdb[\x9bG\x17{\x87\x93{\xa7\xf5\"\x01\xb69\xfe\xc9h\xd2wG\xf7N\x97\xe6qk\xdc\x1b\x08Bt\xaf7\xa1\xe1]\x05h\xeaGA\x16|\xc3\xbfJ\xc26a\xd5\x99\xb4\xb5\xf1\xe4\x8e!\xaf\x95\x89cA\x8fRKw\x12\x10j\x05\xfd\x010\xec\xaf\xe6\x0e\x1foM\\\xf6\x94m\x12\xee\x97\x9d\xdc\x95&\xe7N\x04\x12\xc0\xa5\x9fM\x17N\xe0\x8ad4\xd9\x11\x873\x96\x0c2\x9ef\xe8\xb6\xa4\xe7\x9f\xc4y6: \xfd\xe8\xbd\xd86r\xb8\x1d\xae'V\xbe\xb3\xa6\x15e\xb9<\x1e\xd8\xec\xff\x1f\x0e]#\xdci\xc3f\n.\xa2\x07Y\xfcE|\xce\x93\xe7~\xca\x1dpG\x02\xfa\xa3\x03&\x90\x94\x8d\x0c\x1f\x1f\x96\xe5\x15\xaf7\x84]\xca\x9e>r\xb6\x1f\xda\x96\xaf}z\x95\xb0\xdbI\x1c\xeeVG\xb3\xe6\x1a+\xbb\xb7W\x17]|/\xa6\xe4`H\xdelF\xde\x0d$g\xff\xbf1y1\xc7\xf5 \x8e\xba\xd9\x8cw\x03t!d\xb9\x96\xe5\xb8\xbe\xa2)\x84\x13\xeb\xc1r\xa3g\x8f\xf2\xaf\x0b\xcb\xea\x9aCh\x96\xf5\x80\xc5\x03\x19\x94@\x814F\x12\x18 \xd1\x90\xe2y\xa34\x93\xa8\x0e\x96\x91hd\x91\x0d\xa6\x0b?y\x969[\x16%L*\xcb'N\xe4\xb1\xa1\xb2P\x82\x08!\xd9 \x0d\x83)w\x1a\"\xb0\xe4c>\x01\xc5wU\xd8\x7fm\xda\xbb\xfd\xb0\x1d\xc4\xf6cl\x0c;\x9a\x14\xdf\x93\x98T,2\xe9\x02\xea\x80\xc5\x82w\xf7\xd8\x06\x98\x01D\xec\xe9>\x8b\x95Ux\xf1\xa9\xeb\x8e\xe6\xc1^\x9d l\xc1\xbb\x9b\xd0g\x8e\x08\x02\x97\xb4\x92\xf6\xc5b\xe3h[\xbf\xc4Ks\xb65>\xa1\x10\xb97>:\xcag\x0f\xb7\xb66\xc5\xff\xf9|^\xbf\xf4\x96\xa8B[;Xhkgw~t\x94\xcf\xf96\xfc\x9c\xf3m\xf1s{k\x06?\xb7\xb7\xcc&\xe0\xc6\x00|fg:\xc6\xcf\x9c\xd8>\x07\x86~\xe3\x9f\xb4t\n.\xf49\x07#\xbd\xd1\x19\xdf\x85\xe2\xb3\xf9|\xe2\xfe|\xfb\x03y\xc5Oo\xf7d>\x9f@\xc2\xd4\xfe\xa1T~\xa8\x08\xe1sU\x84\x01r\xc5[\xef\xa0V!T\x9f\x99\xf3-\x8e\xff\xe6\x93\x03\x15\xe1\xc9\x91\x9d\xde\xde\xda\x9a\xc9V\xc7\x18\x93)\x9f\xc8\x95~\x85A\xe2\\k\x1b=\xf7\x93\xfaY`\xaa\xf5r\x1c\xa8\xae\x1e\xf4\xf0\x1a<(\x08\xa3z\xfb\xb5~\xcf\xd9\xbe\x0c\x8c\xe0\xc0\xe8\x9c\x83\xfdr\xa40\xe8)F\x8a\xec\x9d\xf6\xae\xbb&\xb8\xe4*\xe7p_t<\xb9\xee2\xde~hc\x08m\xcb\x98\xf2%/G\xdb\x1b\xdf\xfdo\xbf\xf3\xbb\x93\xde\x8dF\xd6\xbc\x9d\xa8\xdd\xdd \x1c\xb1o\x14,\xbe\x0f,\xbe\x0b\xce\x1ez\xbd\x1b\xdd9\xd2h\x9c\x058\x06\x0b\n\x87\x9e\xf1\xd1\xc5T\x1c\x8bf\xbbG\x17\xb3\x87\x9bG\x17\xf3\xdd\xa3\x8b9\xbc\xcc\x8f\xf2\xad\xa1X\x19\xf9\xd6po>\xb9w\xda\x00\xc2u\xc9\xc3M`\xed\x80\xd0\x1a\xa4\x82 \xa9U\xd0\x0c<\x96\xd4a{} \xdew\x9d\xea\xd7{\x7f\xf8;\xbd\x11\xeb=\xab\xad\x9b\xde\x1f\xfe1:\xf9\x8f\xd3\xc9\x7f\x82N\xfe\x1f\xe8\xe4?I'\xffC\x91\xec\x1b\xc9\xff\x88N\xfe\xc7t\xf2?\xa1\x93\xff)\x9d\xfc\xcf\xe8\xe4?-\x92\x9f\x1b\xc9\xff\\$O\x8d\xe4\xbf\"\x92\xeb\xde\xf1{\x7f\xf8\xefD\xf2\xccH\xfe3\"\xb9\xee;\xbe\xf7\x87\x7f\x96N\xfest\xf2\x9f\xa7\x93\xffg\x91\xcc\x8d\xe4\xff\x85N\xfe\x17t\xf2\xbf\xa4\x93\xff\x82H~a$\xffE:\xf9/\xd1\xc9\x7f\x99N\xfeW\"90\x92\xff5\x9d\xfco\xe8\xe4\x7fK'\xffU\x91\xfc\xd2H\xfe\xf7\"92\x92\xffG\x91\xfc\xcaH\xfe\x9f\xe8\xe4\xbfF'\xffu:\xf9o\xd0\xc9\x7f\x8bN\xfe\x0f\"96\x92\xff#\x9d\xfc\xbf\xd2\xc9\xff\x1b\x9d\xfc\xbf\xd3\xc9\xff\x89N\xfe]\x91\xfc\x95\x91\xfc\xb7\xe9\xe4\xbfC'\xff]:\xf9\xff\x14\xc9\xb9\x91\xfc\x7f\xd1\xc9\xff\x99N\xfe/t\xf2\xdf\x13\xc9\xf5\xd8\x01\xbd?\xfc}\x91|i$\xff\x01\x9d\xfc\xa7D\xf23s9\xfc\x9eH\xf7\xcd\xf4\xbf/\xd2\xdf-\x8c\xf4\xff*\xd233\xfd\x1f\x88\xf44\xad\xa7\x7fK\x93\xe5oi\xfa\xfb-Mh\xbf\x05\"n\x90\xb7o\xff\x04\x9d\xfc'\xe9d\x80\x80A\x0c\xbf\xfd3t\xf2\x9f\xa3\x93\xff\x02\x9d\x0c\x84\xd6\xa0\xa8\xdf\xfeY:\xf9\xcf\xd3\xc9\x7f\x91N\x06\x12d\x90\xe5oij\xfd-P&\x83Z\x7f\xfbW\xe9d \x13\x06\xfd\xfd\xf6\xaf\xd1\xc9\x7f\x83N\xfe[t\xf2\xdf\xa6\x93\x81\x04\x19\xf8\xf6\xed_\xa7\x93\xff&\x9d\xfc\xbbt\xf2\xdf\xa1\x93a\xcd\xfe\x9a\x91\xfc\xf7\xe9\xe4\x7fH'\xffc:\x19\x16\xe7\xa9\x91\xfc\x0f\xe8\xe4\x7fD'\xff\x13:\x196\xfb_7\x92\x7f\x8fN\x06\x1e\xc0X\x98\xdf\xfes:\x19\xb6Xc\x07\xfb\xf6_\xd0\xc9\xff\x8aN\xfe7t\xf2\xbf\xa3\x93a\xfb66\xb6o\xff%\x9dLo\x9a\xdf\xd2\xbb\xe3\xb7\xff\x9eN\x86\xed\xe47\x8cd\xd8N~j$\xc3v\xf2\x9bF\xf2\xff!\x92\xdf\x1b\xc9\xff\x89N\x86\x9d\xe0\x0b#\xf9?\xd3\xc9\xbfO'\xff\x01\x99\xfc\xdd\x1f\xa3K\xc3.\x13\x1a\xc9\xff\x85N\xfe\xafd\xf2w\xbfC'\xffq:\x19H\xaf\xc1\x8d|\xf7'\xe9\xe4?M'\xff9:\x196\x01\x83\xa5\xf9\xeeO\xd1\xc9\x7f\x86N\xfe\xf3t2\xd0o\x83I\xf9\xee/\xd1\xc9\x7f\x85N\x06Bm\xf0\x17\xdf\xfde:\xf9\xaf\xd2\xc9@c\xdf\x18\xc9\x7f\x83N\xfe[t2P\xcd\xc4H\xfe\x9bt\xf2\xef\xd2\xc9@\xa8\xdf\x1a\xc9\x7f\x97N\xfe\xfbt\xf2?\xa4\x93\x81\"\x1b\\\xc1w\x7f\x8fN\xfe\x07t\xf2?\xa2\x93\x81\"\xbf3\x92\xff)\x9d\xfc{t2\x90\xde\xccH\xfegt\xf2?\xa7\x93\x81\x98\x1aL\xe1w\xff\x82N\xfeWt\xf2\xbf\xa1\x93\xff\x1d\x9d\xfc\x1f\xe8d\xa0\xb1\x06\x0b\xf9\xdd\xbf\xa4\x93\xff5\x9d\xfco\xe9\xe4\x7fO'\xffG:\x19H\xef\x8f\x8dd \xbd\xe7F2\x90^\x83\xc7\xfd\x0eH\xaf\xc1\xcc~\xf7\x9f\xe8\xd2@z\x7f\xdbH\xfe\xcft\xf2\xef\xd3\xc9@L\xbf1\x92\xff\x0b\x9d\xfc_\xc9\xe4oav^\x98\x1b\x0f\xc0*0v\x9e\xef\xf0\xb8fp.\xdf\x01\xb3\x14\x9b\xe9\xc0X\xde5\xc9\x1b\xec\x1bi\xa9\xd9\xb5)Hi\x8f>\xd7\x16rw\x12\xb0\x11\xce\xd4F`\xa3[\xa9p\x03\xc9Z=\xf6\xa3\x12;R\x96\xdf\x84\xc4M\x9am?l\xf7\xbcG\xabT\n\x0b\xc5}\xd0+x\xba\xea\x04u\xf4\xfa\xc0AA%\xd5\x10~\xa9\x86\x80\x00T(\x87\xcd\xba\xc9a)\xb5\x01\x18Tlmm\x1e]l\xcf\x8f.v\xfc\xcd\xa3\x8b\xfb[G\x17\x0fN6\x8f.v\xb7\x8e.\xf6\xc4\xcb\xde|\xd2\xbfw]%\xa3\xeadt\x93N\xfa\x9b\xdfL\xc6\xcf6\x7f{r\x05\x7f\x7f\xbe\xed}\x80\xb4\xab\xf1\xd6\xe6\xa3\x89x\xc5L\xf9\x02\xa9W\xe3\x9f\xe0\xcf\xad\xcdGlr\xef\x9a\xdd\x8f\xd0Pb-\xb5O\xa1\x939:\xba\xf0\xa7GG\x17'\xc3\xa3\xa3\x8b\xd9\xde\xd1\xd1\xc5\\\xfc\x01\x01\xab\x008B\x1c@\x8e0\x07\xa0#\xd4\x8f.NP\xe0\xba%\x05\xae\xbbsvt\x94\x89\xea'GG\xa2\xae\xbf\x05r\xd9\xf9\xfc\xe8(::J\xa0\xd0\xf6C\xfc\xf7\xe8\xe8(\x1f\xee>\x14%\x86\x0fA\xf9 \x1a\xc2\x7fC\xfc\xb7\x8d\xffv\xf0\xdf}\xfc\xf7\x00\xff\xed\xe2\xbf=\xfc\x87mn=\xc2\x7f>~\x01;\xf7@\xfc\xdb\xd9\xda\xda\xaa\x11\x18\xd46\xf5X\x9fE\xac\xcfz\x16M\xd2\xac\xdf3\x17\x1cH\xa1\xb7\xf7\xe4\xb0\xf7Nh\xa5\x91\x98j\x01\xd4\xb9\x80\xd4|\xf7\x08\xa5\xddG\x17\xa6\xea''5Q\xaak\xa0\x18\xa9}\xd0\xda\xf4\xb3\xcd\xdf>BA;H\xdaQ\xd4~t1\xe36u\xd3\x1az\xad\xf0Zz-\xd0\x18\x8d;\xf7k\xae)\x98\xfcB\x0d\x96S\x8a\xa4\x95Vt\xda\\t&\x8b\xae\xa9>\xb8\xb2\xa9\x12\xdd\xba2naU\xc6\xcd,\xca8R\xf5\xc8R\x8f\x85\x9d\xf4s3Z?wV\xd1\xcf\xd1\xed\x89\xbc\xda}\xcbe\xa9b\x19OQ\xa3\xa7\xe0\xdf\x17`\x03\xc5\x95s0\x9a]\x85\xe1\xd5\xf2*\xe1W\xe9Uvu\xc6]\xf7@\xaa\xef\xc6\x89\xc7\xa6\x1e\xeb\xfd\xb0g\xaa\xff\xd8\xcah\xe8\xb3\xab/\xbe\xb8\xfa\xf2\xea\xcd\xe1\xd5\xdb\xabwW?:\xac5\xc4\xfalnk\xac\xec\xdf\xbcK\xffT\x8d\xb6\xcf\xf79\xc0\x1d\xeb\x87\xd7\xa6\xec\x1b\xce\x06\xd8t \xea\xa6l\x10\xc0\x14\x97\x1d\xb0\x15\x18A#\xe3\xef\x17\x0eG\xd9Z\xa8S\xdc\xb5~d\xbdk}o\xfc\x93\xc1\xa4\xff\xc3{\x03~\xc1\xa7N,z\x10\xc35\xb1\xf2m\xf0\xe2\xf0\xf8\xf5\x9bW\xef^\x81\x91~\x0f\xac\xb8{\xe8\xc8\xd1I\x93\xa9{<\x1c\xa0E\xd3\x88\xf5z\xd7\x85\xc4F >\x18@`\xd6k\x8c\x14\x91~\xcf\x1d\xf7\x8e\x8f\xa7q\xc27\x7f\x9a\x1e\xa7\x0b?\xe1\xb3\xe3c\x9b\x95\xfdu\xa5\nv\xdf6\xed2\x83\xf6s[7\xb0\xa9\xad\x01\x88\xcb\xc2\x87\xcd\xe3\xce\x1de\xde[!JcN{\x05)\xe9\xd2\xe6>\xcb\xd8\x01\x1b\xb2\x11l\xda\xd7\x05\xbf\xa0\x9e\xc4 \xeb\xf88\x8cg~\xba8\x16{\xfdqqg\xe8\xf8\x988v\xb5\xb8OX\x17\xb9*PR\xf0\xa8\x02#\x983\xc7pZ\xcc\xb4\xf3sf\xc0\x8fULN\xf7\xd1\xa6\xb4\x98\xee\xa6@J\xb2VPx\x15\x86\x95.\xbeP\xd8\xfd\xde.\xf0\xbf\x7fx\x16\xc6\xe7\x07\xd5+>0\xc4X\x1b\xf8\xed\x0e\xb4\x01\xcb\xda\x06\xd9\xe4=\xacu\x9c\xe5\"\xeaW\x17#rdC\x8fEb\xe8\xfbh\x8d\xaf\x89\xd82i\x9d\x9c!\x83pS\x02\xd1\xc6\x96\x8c'\xb7\xc4\x88\x0cw(\xf6\x18\x83\xd7h\xcc\xd8*\x0c\xa6\xbc\x0d\xf2\x9d\xd0\x8bf}\x13D\"rN6\x9c\x88=A\xc7\x11N\x04\x9e\xa0\xd4\xd5\xd4M6\x14\xebm\xb0\x8a\xd1WD\x89\x8f`\x1e\xef\xb1\xcd\xcd\x02H\x1e\xdb\xba\xd6\x9e[@\xe9\x174z\x1c\xbb.\xba\x1dG\x93\xf1\xb0m\x0b\xba\xd5\xa1\x146\xaa\xd5\xb1\x08rW\xb91\xf6\x11\xba\xd2u5\x9b\x80\x8d\x01\xb0\x91\x15\xb0\xb1\x04\xac\xd3\xefkH\x12a\xec\xd0\xb1\xf8\xf0\xc4\x85\x08P\xe3X\xc0[F9j_\xdb\x0d\xc3\xddn\x1d\xae\x0d\x89\x12\x15\xf9\xcd\x95G+\xdb-\xa1\xebr\x01\xad\x14\xc9\x8e\xdf\xd2S\x1d\xd9\x9d\x1e\x9e\xe8\xd1\x81\x1b\xf0\x9bQ\xbe<\xe1\x89\x96\x90\x02\xe7\xa9%\x9c\xc4q\xc8}\xe9\xf4M\xf0\xa6\xc7\xc7@\x89\x8e\x8f{2\x10\xc0Hs\xce\xf7}\xceFe\x1d\xc0d\x9c\xf2\x0eb\xfc\x8f\xdc\x07\xdc\xa1>f\x1f\x1a\x16a\xd9\x0fz\x05F\x80\x8c4e\x03\xc1\x034\xeeU7\xdeHnk\xc8\x8a\xc9\x8d\xf7fK\x8f\xb6{7\xae\x8eI\xe5\xdc\xfdV\x90X\xa6\xa5(\x80{\x10\xe9u\xef\xac\xe2w\x9d\xbcI\x06\x8e/b's\xa9\xfa\xaa\x8dT\x11\xb8\x1d\xa2\x05&o\xaa\x05\xe0{(j\xec\xbb\xfe\xc8q\xa4N>\xe6\x13\xb8|\x90wu3k\xa6\x9cI\x8f\xbc\xbc\x00\x87\x95\xf3\x0ea'a\x07,\x1f\xa7\xc0C\x87\x82\xc1\x0c F\x9a\xb1\x1bH\x03w\x87\xf5[ \xf2\x02\x84!`AL\xd8~\xd4*A\xb2\x12\xc6\xd8F\xa3\x87\x15&\xe6\xce\x1d\x96\x8d\xb7&\xe3\xed \xde\x19\x14\xef[\x82\xbd\x13/\xc3\x89\xd8\x82\x8ao5\xdd`\x8e\xa4\x13Q\x88\xb6\x16QAB\xaf\x0d\xb5\xa1qwF]\x8d\xa3\xa064%U\xdbm0\xc4\xaf\x0bd#\x80\x99\x02\x1d\x91n4\x8d\xe1\x0b\x04K\xcd\xe4)\xdbg\x1b\xb9y8,\xce\xf4\x85\xdf\x98\x8dZ\xfc\n\x10\xb0\xf2\x8a\xc7\x03\x96nnZ\xa5\xabs\xd1\xbdqjq}=\x85`\xa18\xbbs\xc1G\xc0\x166\x9e\x8f\xb7&\x02\xb97\x1c\xf1\x06b\x92\xd2\x93\xcdFS\xac\x0f\xe8\xdec\xd6\xef\xa7\xec \x0b\xad\xbdZ\xb1}\xe6\xa8\xae\xb9V\xe7i3\x10\x0d\xaf,\xb9\x0b1IV\xaf\xde\xc5\xd0l\x04\xa5\xe6\x90\x04B\xdco8\xab\xe6\xd1\x8aG\xc6}\xb7\xd3\xbe3\x86Q)\x1bBQ\xe7.\x94\\\xb2}\x96;3\x8f-<\xb6\xc2U\xe1\xb13\x0b\xc5\x04\xba\xabwy f\x12\x0b\x8f\xcd<\x16\xb0+y_\xeeL,\xcae\xf3\x08\x1afP\xd5\xba\xc1\xa1\xad\xf5\xeai}J\xea\x07HT\xd1\xacu\x86\xbc\x01\x8b\xd8~\x04\xca:\xf3\xb5\xa2\xac\xe4\xd5o\xbd\xc3\xfa\xc7T\x7f\xbb\xf1x\xb7\xf4\xad\x9b\xf2r\x16\x8d\xe0C\xea~\x9fH\xaf\x97\x07b\xbd\xd5\xead\xa1\xeb\xa9\x8c \xbfLy\xd9\x8a\xe7ft1\xa6\xb1G\x91\xa5\x15V\xf0Gb\xab+\xdcT=a>\xdbd\xc3bM\xe6\x95\x83\\\x15\xd3\xfb\xfdH\xa2\x90H5\x9b7\xc6!\x17L\xe0\xe4\x1d\\M[\xf8Z\xc5\xd6\xde\x90\x93\xb5n\xc5u1\x9ade\xb7\xa9x\xa7\"\x9d\xd2\x1c \x14\xaa\xab?Sl\xbf\xaeq\x08ew\xea\xcdL%\xdfTO\x9f\x9b\x9c\xc1J\x0f\xac\xfaLy\xf0\xac\x9b\x97\xcc\xaa\xa5\x12\xff\xb2^b\xa1\x97\xc0M\xbb^\xe4\xec\xe6\xc2S\xc5\xa2,=v\xea\xb1K\n\xffO\x04+\xe2PG\xa1c\xc8\xc9\x88\x9cs\xb6\xcfN\xd8\x01\x9b\xb1\x11\xcb\xc9\xba\x87l\x9f\x1d\x17%\xa86.\xc4^/\x1a:\x17\x9c\xcd\x8a\x1d\xb0\x05\x1b\xb1sW\xfc\"8\xa6\xb7\xa2\xb8h\xf5P/~h+\xfe\\5|h.\xe7\xe7bK\x0fA\xd7e\xaedX\xa5!\x9cb\x8a\x8d\xd2\\l'\xe0+\xc5\x83A42>\xc5\xf76.\x8a\x06/A*x\xa964\xd7c'\"e\x8a\"\xdb\x98\x98\xb5\x11\x0bd\xeay%\xc3\x1c\xdb\x86\x13\xb1;lN\x0eM\xcc\xf6{\xb6\xcf.@\x0c\\\xb8\x96\xe9\x1d\x1f\x9f'\xfej\x05\x82jb\xa2\xc4\xf3\x8c\xed\xb3\xb7Z\xb5\xac^\x8d&w\xef\xc5\xb8\x9e5\x9d\x07_\xb1}\xf6\x9e\x1d0>\x00Wr \x11mp\x9a\xfe\x9a\xed\xb3g >-\x8bg4[d\x05\xf6\xa9\xf3\xcac\xaf\x15\x1c/\xdb|^\xd3l\xd0\x06L\xaac\xb6\xee\x9b\xd3w\xfd\xad\xd1\xd8\xea\xe4\xc1o\x9b6\x96\xd9\xdd\x1ev\xf5\xe3zv\xcbf\x1du.M\xb7\xef\x80\x02\xfel\xe6\x80w\xe1\x1a0\xc4\xe3k\xf4\xcd\x9f\xcd\xc0\xabP\x99\"\xb6D4\xca\xf0\x0d\xfb\x8b\xa0jj\xe1\x93\xf0\xad\x037\xba\x99\xae\xa6\x13O$w\xd3\xc8\xed\xb4s~\x9f\x8cX\xfb\xb7\xec\xbae\x00\xbb\x93\xb5}\xc2\x8a\xd06/I\x86\xb9\x93d\xf5\xb6(7\x17\x14\xdf\x90K\xfc\xafo\xf8\xa9L\xaf\xb7\x13\x9a\x1b\xbb\xe0\x01\xb6\xcd\xed\xbf\xd8\xa3?E o}\x93\xae\xf0\x03\x9f\xf9\x99aiZa\x05\xc0\xa3e#+\xf0\xa5\xbf\xa2\xf8\x00-\xd8\xfb\xf2\x84\x1bM,\xf5\"h\x97R/r\xaa\x17y\xcb\x0dn\xe3\xb2\x92\x0f\x12\xf0z\x91\x93J\x11\x10\x81\xd7\x8b\x1c\x1b\x8c\xcf\xa7\xf9|nv\xf8\xbc\x066\xffG\x01?\xaf\x17:,\x9c\xaa\x15\xeb\xde\xe2\x9b\xea\x02\x18\x83\x03v\x88\xfb\xc2\xabyg\xd7k\x8aX'\x1e;\xf4\xd8[\x8f=\xaf\xe3~z\x1e\x80\x0f4R\x8e\x05q\xdc\xceGF:\x93; \x1f\x9c\\f\xfc\x0bd\xf77\xc41P\xfb}u\xc50\xff\xd5|\x9e\xf2\xac\xcc\xc7\xdf\x8d\x1c\x88x8x\xa3:\x01\x00{\xd2\x1b \xfe2\xcbCG\x8f\xe9\x8e\x16:\xcb\xb6\xden\xbcu\x04u\x8f1\x18\x0c\xbce\xaeKl\xfe\xf0\xb5\xb9\xf95H_Y\xd2\xcf\x1a{\x178}\xee\xb1>%y\x86\xda\xb3\xc6\xda|\x10\x81Oq1&x\x03O+K\xe53\x1c\xc2\x9d\xe0\x0fK\xf3KK\xa7/\x9b?\x8b\xfa\xa0~\xc5(\xa9R\x7fA\xd7W\xbcZn\xa9vj\xaf\xf6\x0c5\xfd,\xb4\x8b\x8b\x80/sD\xfb)x{\x85\xb3\xde\x86\x12R\x00\xbb\xfa\xac\x15\xfb\x14\xfb\xf6\\\n\x1b\xec\x9f{U\xb4\xf5\n\xe0aa\xd8\xd8\xd5>\x9bz\xecyy\x14\xb5\x7f\xf858\xb4{\x0f\x88\xf8\x1eC\x15\x94\x0b\xb8\x91!|^\nm<\xf6\xda\x02\xde\x13\xfb\x8a.\xf9\xf8\x0b\xe55P\x0cJ\xfe\xb0J\xaf\x99\xb6\xce\xda\x94\xcf\xed[\xf4\xba\xec\x9c\x0c\xe1\x04\xd3K\xcb\xaa\xb8\x195\x82\n\xa5\x0e\x0d\x8e\xfb\xfdl\xc2\xf6\xc1\x86\x9e\xd7\xee\xa2\xb9\x1fC\xc4\xf5q\x86\xd786\xbe\xf6\xb0\xecv\xb3\x8f(\xf1\xc7\xd0\xe4xn\xe9\xb0\x8f\xf2\xde\x94\x02\"\x08@\xd8\x1d\x16\x9bp\x9c\x82f\x8e:\xcb\x0b6hJ\xf2\xffb=\xcc\x05\xe1H\x9c\xcc\xd5tC\x1b\xa1\x95z\x14\xd1\x8a\x04\xe34\x7f\xccV\x0dJ\n\xc1:M\xc7+\x8b$\x7f\xc3 A\xc0\x00^\x9aG\x9aA\xdb\xcc\xed\xa8\x95\x10\xdfX\x80\x190E\xc1\xc47`4\xa9\x0c\x87R4\xba \xa8\x98\x12\xf0o\xd4\xbc\xab\xa6\xba`-U\xf1P\xea\xdf*\xa0\"\x18\xb9P\x1c\x9eV\xec \x9b[!s\n\x1a\x10\x05\x1f\x8b\"\xe4\x12,\x07g\x16\xf0\xf9n!\xfe \xe1B\xe5%\x1cWg\x80E\x1c\xf0g\xc4|G\x9c`!\x15\xd1+\xb5)~u\x05\xc4 ;\x10=\xdc\xdf\xc7\xd3w.\x1bA\xd4\x84vO\xecJb\x90\xa8\xd0\x14\xfc$\xe1\xfe{#\xc7T\xe1.a{\x03\x9exZ\x1a\x92\x83m\xc6\xac\x89>\x83\xea\x07\xf0wi\x03\xfc1\xb0\\Z\xab4\xe8\xcf\x81\x17\xd3\x8a\x99\x03:\x16\xeb\xe6\\|\xad\xda\xc9@F\xec0R3\xd4D\x91\x01\x06\x8fE\xde\xb1.\xa6\x86\x14\xb2,|\xf3\\/{\x8eF\xdf\x08\xfa\x0e\x1bX\xaao\xa1\xc5\x0f\x81\xe0g?\xa8V\\\x9f\xf4\x13\x87\xcfJ|\xc7\xcd!F\x83\xb5 (\xd0\xdc|\x0b\x03>\x8e'b)E\xec K\xacK\xc9\x87\xa5T\x8fZ(\x9e\xcc\xf1\x01i\xd1\xac\xd9 \xc6q\xbf\x0f\xb1\x0e;\x80(\xf8\xde\x00\xa1\xa23\xaa\x91\xf2\xc7.K0(cf\x04'\x91\xbdKZzg7E\xa0\x05\xf9\xf7\xa9\xfb\xe2\x94\x94\xbcm\x0b\xb3\xc8\x1dbiZ\x9eHf\xeb\xc6\xd0\xb5|\xa7\x953[\x170C\xcbMz\x03`>\x84)-\xc1\xe3\x8f\x0b\xf0}\x1e\xc6~\xb6\xb3-\xb5\x08\x80\x80\xb5\xcc\xdd\xfbt\xe6\x8b({h\xcd\x19\xeeZ\xb3l\x1f\xfb*\xb06\x08Y\xcfC\x7f\xb9\xe23{ \xdb7E^\xe5\xa3\x1b[\x9e\x9e\xafaP\xad&\xdd^E\xf0P\xcb+\xe48\xb5\xf4R\x08afp#Q\nr\xea\xb3!q\xc5\xc8\x00\xa9N-MIrj\xc9J\x17TKVB\x9dZ2\x08r\xeaiRxSK\xfe1\xf7\xdf\x17\xfd\xd8\x18z\xeb-\xc1@.\xc1\xd8\xe1E\x94&\xb1\x1fm\xf8c\xb1*o`\xdaK\xfb\xa0\xd85\xac\xdfn\x81C\xae\x8f\x0dc5\xe9\xf1\x98L\xfb'u\xf6\x18O,,[$6\xe7\xc2\xec\xc6\xd5\x9c\xf6G\xae\xb9\x91o\x00\x03~\x87e\xa8\xea\xb5\x10\xe86\xcb\xd7\x86\xb3\xc6\x9e\xebh\x81\xb6<\xd93\x8b\xe9\x05}\xfd\xc8N\xe5v\\\x07\xae8y\xac\xa7\xd6\x8b\xed\xe2\xd9\x0d\x9a~\x9d\xc4\xcb \xe5\x1f\xa1\xe5\xb7<\xfb\x08\xad\xca\x95uK-o\x1b\x97v\xe5\x8aX\xdf\xc0\xb3\x12\x856.B8gE\x00\xda\xa8\xe1\xf4\x15\xc0\xf1!\xb2\x1c.\x90m\n(\xb6 \x99\x0f\xe9\x06\x96\x95\xd2E0\xcf\x9c\x06D\xd5.\xfe\x03k\xd1\xb64E\xf9\xc0\x89\x8b\xbd\xcb\xde\xb2x\x00\xf8q\xc3\xa2\xa2)-\x99\x8aS\xe1$\xec\xa9\xf4%\xa6\xf6\xbc\x91\xd8\xc0Y\x9f9\xd2\xc8\xfd\x80\xf5\x9e\xdc\x13TM\xfe\xee\xb3\xde\xd3\x9e^Jn\xa0\x82\xa1\x8aD\xe9\xa3Hf\x83\xa6\x10\xe4\xa0\xd4\xc2\xb3\xcfb`\xdf\xc2\xd4)kC\xc7\x138J\x96\xbf\x07\xfej\xc5#\xf0\xef\xe0\xe9\xf84\xc0\xc4\xb8\x92\xa8\xcc\x18\x9c\x0dq\x06\xdd\xd8\xeaB\"\xe0N\x06br\x01\xb5*\xbc4pi\x80*W\xbf2s=`=\x86e\xb5\x072\x0e\xd6\xabN/\x8a3\xe6\xa7ip\x1a\xf1\x19\xcbb\xe6\xb3\x95\x9f\xf0(\xdb\xa0\xf8\x07\xf5\x9ci\xfe\x91\xe8^\xaa\xa7\xf4H\xa3 f\xec\x0d\xe7\x8e\xd6[IT#\xaf\xd2\x02\x8a\x80\xfa\x82\xc1P\x94\xd6\xf5\x9agE\x7f\x14{\xe9P\xbc\xa2zlT\xca\xc2f\x08\x9a\xd7uJ\xb4\x0d\x17\x0d<\xc4\xd0\xe0\x84\xcb\x95\xd7\x1d\xc1\xe7\xaa\x1c\xd1\xd3\xce$\xd3*\xfa\xac]d+~}pK\xc7\xc3\xce\x83\x07\xf2\x80\xdd$\xe8W\xdbyu\x80\xbd;\xbd\x11\xeb\xdd\xf1\x97\xab\xc75\xa2x\xb7wW\xe4\xfc,\x8f\xb3zV\xef.VZ\xc5\xa9\x91\xf5\x04\xb2B\xb3\xceS\xc88\xcd\x1ek\xc1\xfa\xda\x04\xe3\x16\xa9\xb8$^\x92\xb2\x01\xf1*\xc4=\xce\xf8N\xef\xc9\xd3\xbb\x18c\xa1U\xd8\xa6\x04\xccFP>\xe0\xd9\xca\x8e\x92\xd0\xad\x91G}\x08\xf1\xe3\n\xdc\xa5\x19\xc1\xa3\x1dwpx\xc6\xa3\xecp\x19d\x19O(o\x1f\xe6A:\x913\xbd\x08\x0cu\xb5x\"\xe7\xe1\xd0ub\x0f\xfc\x97\xc4\x837%\xc5\x14_\xbc\x0f\x89?N\x82\xacH\xdc\xdd}\x00\x89\x9f\xe5\xab\x90_\xc8\xa4]Hz\x97\xf8Q:\x8f\x93\xa5L\xdd\x83\xd4\xd7~\x9a\xbe[$q~\xba\x90\xe9\x0f!\x1de\xe2x\xb0\x8bu\x97\x1f\xc1\x8a\xb7\xe97\xce4\xdf]6\xc9yL\x9fF\xf9\xe0\\\x0d\x07U \xb8\xd5\x88D.j\x80\xd5\xd8\xca\xcfS\xae\xbd\x1a\xc7&\xfa\x93\x01I\x85\xa2r\x1f\x82\x16\x13\x9e\xe6\xcb\xca{\xe3\xa9,\x1a\xc4Q\xc1\x92\xc5`,\x08 \x89\x1fD=\x8f\x05\x90r\x1c\xa4o\xb3Y\x00r\xfcL\x1b\x18\x1e\x9e\xc1\x119\xd4\x12l\x9c\xc7r`\x88\xc4od\xdb<\x96\xd6\xa5xg\xd2Ztch\x83oN\x0e\xd6\x87\x8f\xf9r\xc7\xe5H\xc7\xbaA/\xed\xd0 y\xa9\x8d\x0ff<\xcd\x92\xf8\x12\x17\xb6\xfc\xd1\xf5\xb3!M\xb7\xc5\x16:u\\OZ\x02$\x830H3\x1e\xf1\xe4\xb9\xd8\x87\xa4\x13\xe1\x1e\x17\x9bi\xcfU\xfbk\x9d\xde\xd2_\x9cZ\xd1d\x19\x9f\xf1/\xe4wjsndj\xf3oV\xd5\xe7\xb9\x9eW\xce9Y\x13F$\x98%\xea\xabz\xae\xed\xab\xd3\xc6\xafN\xc9v\xcb\xdc\x86\x95\xa0\xc8-br\xa5\x9f\xf5\x14\x1d\xdb\xa7\x06\xb6O\x8b:\xd5\x14<\xca\x08\x02\x04gL\xaf\x95\x86\xbb\x10`\xa9\x89\xac\xf7\x04!I\xb3$\x98f=\x92\xaa\xdf\x1f\xba\x03\xbc\xadDZ\x08\xec\xb6z\x9c\xaf\xe3R\x81f\x9cD\xb3\x8d\xf6m\x8d\x15\xa6\x91\x9ci7E3Wg#\xdf]\xae\xb8d%\x9f\xfb\x91\xe0&\xc5>\xc3|6\x0d\xfd4e~\xca\xfc\xe2K\xc4\xb9\xf0C\xe9\x86\x1b\x19\x9e\x05\xf7g\xd2LK\xa6d~\x10VS\xe4y`\xdf\xea\\\x99i\xbb\xbc\xe9E\xaa\x99QS\xbc\xad\xe5h\xe9g\xbe\xd5;Y\xc4/2\x94G\x99\xe34y3}(O\xc1\x16\xa9\x18.\x88}@Q>\xaa@%\xab\x82$\xf3\x98\x8c\x01\x80\xcdT\xa1\xe1U\xc6\x9eG \xfc\xfe\xf8\xc3/\xfa\xdb\x05\x062\x06\x89\x06 \x10\x06\xebc\xac!\xc6:c6Fl#\xf0R\x00V\xb6\xdat`\xe5\xeaH#z4\x10\x10\xa1\xcf3\x12\x01\x87\xc6\x10\x0f\xaa\x03\xaa\xe1x}\xca\x8b/ \xf0\x16\x91A\x949\x05a\xce\xde\x04\x11\x15\xf5\xae\x11\"M\xbdkY\x81\xd5\xaf\xfd4\x0e\xda\x1d\xb8#\xfc\xf7\xeb\xf0\x97\xd0\xa3|\xe6Tn4\x15\x9d\xc5kM=\x14\xc7\xc3\xacHoH\x02n\x8f]\x16\xb1\xfe>\xe8\xc03\xcb\x9c\xd1f\"5\xf8\xc5\xd1\xd4o_D\xcdcJ\x06~\x18\xc6Sg\xcbb\x8an`LQ\xb3\x0d\xedJ\xc8\xc0\xb19F\xb3)\xf9\xbd\xaf\xa2\xd4\x9fs\x87\xb3\xa7O\x9f\x82x\xd2\xaf\x82/\x17\xd3\xf9\x98\xf9\x8f]\x00\x9c\x0f\xdf@\xa8\x06x\xa3>\xf7@\x97\xb6\xbaD\x9b\x1fQ\xa5\xaf\nV\x0c||\x04\xba\x0d\xc4\x81\x01\xe2\"\xe1\x83`\xb5d\xf4\xb7 JW|\x9aU~\x0c\xa6y\x9a\xc5K \x13\xa5t\xa6\x98\xa0q\xbd\xe0\xa4 \xd9\xd5j.*\x11r5\x1c\xd6\x88YI\x8e\xe5\xf2\xa6(\xae]\xfa,to\xa0/\xd2\xc6k=rw6H\xa2\xb6\xef\xea\xeeN+nH\x8eD=\xb0\xefC0\xcb\x17\xcb%\x9f\x05~f\x95jH\x05\x0d\x1a\x19I\xbf3\xe6}7\xfd \xe1\xa2\xbb=\x7f\xda\xa0\x9baRw\xc3\x07\xb3x\n\x922{\xb9Uitt\xca\xb3\xd7\nI^\x81R\x83\xcc\xb0\xba\xb0\x12M\xad\xc0\x92D\xc0\xe4]\xb0\xe4q\x9e\xc9\xe8\x88\xdc+\xfd\x1c\xac\x92x\xca\xd3t\xd2\x835\xfc\xf3\x0fEpIy!x \x0b\xa0\xb1m\x1b\x1dQ\x8f\xa6\x07j\xa4\xdc\xfa\xb3p\x88\x0b_\xea\xb1 \xb8\xd8HG\x9d\xa6O\x80\x12u\xb0\x8a\xd3\xecK\xe9@M\x9c6\xf9 X\x8a%\xf9v\x9a\x04\xab\xccj\xef\xa3\x1eE\xc47\xb6\x9a\xa5\x88LJ\x12\x05\xb3nu\xd1\xa6?\x05\xf3W\x94o\xdb\xf4\xeaOF\xeb\x10\xf4\x07\xf7\x86\x12\x02N\xaf\xe7\xb1\xde'=y\xaa(?\x1c\xd5o\xd9UZ\xa1g\xc2qA\"%\x9b~\xbe\xf0\xa3\x88\x838\xdb\x01{J~\xce\xaaY\xee@\xc0}H\x0f\xb8\x11\xb9\x16\x0e\x07\nn\x93y\xae\x81\xa7\x01tb\xbb\x02\x14\x0b\x16\x82l\x0c\x16b/\x8e\x12\xee\xcf.\xd3\xcc\xcf\xf8t\xe1G\xa7\x1c|\xdd\xcc\x07\xd3\x84\xfb\x19\x97\xa2w\xa7\x97\x02R\xf5\x04`\xc0\x8eq^\x90\x00Yd\x9d\xae*\xd4\xb3~\xc5\x8e`\xd9\xc0\xec\xf1:\xe8%E\xbdt+\xc8d\xc5\xf2d\xfc|\x11\x8430s\xced\x9e\x1d\x8fD-\x94m\xabZv\xc0w\x87SI\xed\x9c\x85\xc7\xb6\x8c\x1bF\xea\x11\xa4\x03\xc43=}\xcf\xf8\xa1\xd8\xed\xe0\x16P\xe2G\xb3x\xe9\xc8@\xb5\xc8m\x14=h4a\xcc\x06i\x9c'S.ob\x08\x8c\xd1\x83sI\x1b\xa5\x812\xe9\x93|\x172%A4\xe3\x17\xaf\xe6\x8e\x0f\x02\xbd\x85\xd3\x97\xe9\xa0pq\x14\xd3b3q\x14\xeb\xd8\x9f\xcd@\xd8\xaad\x14\xb0*\xeb\x89NO.\xba\x1el\x7f\x1bC\x10\xfc\x0e\xfc,\xf3\xa7\x0b(\xe9\xf4\x8a\x85)\x052Ig\x00T\x89\x8c/XX\xa43\x96\xf9\xf5p\x93*&\xa1\xf3\\kR\xb5\x8d\x9a\x19/\x97DGy7q\x80\xd1\xe6MF\x7f\x156\xbd48.\x14\\\xea\x10\xb1 \x11\x0f#\xe4>#\xf6DwM\xd0\xef\xbb\xca\x97@Qo\x0c\xaaA\x8b\xdd>\xd3\xec\xbe\x9aW\xa1\xd8\x8fO\xfc\xe9\xfbF_\xe3\xe2\xf1\x93\xd3\x942\xb8S\x0fq\xacU\x8f\xdc\x86\xc2q:A\x01w\xe2\xa4\xae\xc7\xd2~\xdf\x86p+<\xa2\xe9sG\x1c\xa4\x1b\x8c\x08f\x0d\x16%\x18\x947\xac\xdfhd-M6\x18\xa9\x80t\xd4\xa5\x88\x04\x0d\x94\x86\xe88L#\xca!\x19\xebV=p\x85\xad\x8d\xc8N ?|\xf5'K.;p\x02\x1b\x1dW\x8f\xfe\xa8\x81\xa0RW\xa0Y;\x83\xa3\x9e\x04\xea \xack\xee\xbdz\x94\x91u\xd2\"\xbb\xa0\x1e0\xbc\xde\xb2\x1b\xdfRO\xa3\x01%\xf5\xb4\x98i\xd7\x1f\xe8\xd3p\xdd>%\xe3-\xeajw\xd3s\x9d~m_\xa7_\x1eK\xc6\xc3\xef\xa3w;\xd7\xef\x9d\xf8\xbb\xfd\x91\xfb\xd8j\xebM=\xa0\xb0\x0fA\xe4@\xd8{P\x0f\xcdQWJ\xd8\x98\xa3\xa2\x00\x9b\x07\x91\x1f\x86]\xe8\xc3\x0c\xd8\xb9i\x87\xf3\x825\xb7\xab\xe1oM\xb6\xe7\xf4\x8a\x98\x05:/\x94\xf2p^^aW\xf7W\xb3E\x90\xc2\x0d\xd7\x11\x14\xd0\x94\xc0\xba\x11\xc0\x0e\xec\xc5v[\x80\xee\xd7\xa2\x8a\xed\xc3B6\xed\xc4\x17\xadV\x06a<\xf5\xc3\xb7Y\x9c\xf8\xa7\xbc9\xe6\xda\xd4\x07\x02\xd8\xe6\x15\xa45\xda\x19\xd3U\xca\x95\xef7\xc6^\x97>#\xc0\x9c\xac\x97%9\xc7\xc3?\x9e\xfb\x9d\xc8\x1dd\xf1\x17\xf19O\x9e\xfb\x84\x06Y\xff\xd5\xf9^\x1fS\x97a\x9c^\x14\x7f\xc6W \x9f\x82\xe9ZO\xbb\x97g\xf6Wi\x9b(\xd7\xaa\xf5\x9b\x82M\x1b\xfe\x06ycS/\x119=\xd0\x10\xd5\xbaV7>\xb29\xf7f`\x90\xd0\xcb\x12\x7f\xca+M\xb0\x036\x8d\xa34\x0e\xf9\x002\x1d\xf0w\xa4\x92\xce\xfd$B7\xe0\xb0\xf7w\\SL\x17\x17 \xa9\xc9@%UZb\xb5\xadC\xebR\xea\xb4\x86hA\\\xc5\xf9N\x99\\j\x0cw\x86\x96+\xe5[\xbbd\x00\x98\xc0\\\x1f\xa8\xdc\x03\xc2\xa0\xe9\xf7\x82\x12\x890v\x98\xe1N\xbb4%!\x02\xe8\x8b'\x1e\x04\xd1\x82'A&\x1d\xc1\x0c\xc1\xd2C\xa59\x01\x9a\x99\x04\x9a`\xfd8\xd3\x8cF\x9a\xa0\xc5\x007\xf0\x94\xdc\xea/\xa4\xc1\xb6&r\x86\x8f\x1et\x9a\x9fj\xad\xdd\xebT\x1a>\xba\xef\x96f1\xd7\xac\xaf\x19\xd0ti\xa1M\xe3\xbc3\xa4\x02\xe8\x8bt\x8bK\x82\xbd\xf6[\xea\xf5\x89\x92\xaa\x08\xbc\xac]\x1e\xe0\x0c^H\xa2\x9b?\x88\xe2d\xe9\x87\xc17<\x81k\xa9\xa0\x96s2\xed\x8678.+\x95\x0d\xa5G\x0c\x7f\xe0\xa7\x97\xd1\xd4E\xcf\x04\xfe`\x95\x04\xcb \x0b\xce\xc4\xd6\xa7\x8c`\xd8A\xf5\x13p\xb1z\x0b\x0e\xeb\x19\\\xb3\xc0\xaaF\x89m\x17<\x7f\x8f\xea\xb5\xb5vE\xb1\x1d\x17bQU\x13\xf70Q\xbc>\x84f\x8a\xae\x82\xe5\x8f\xb3\xb7\xf5\xc8\x95Q\x8d\x96\x8146r\xf6\x86\xa0\x9f\x19\xcc\x82t\x15\x97\x89\xbb\x90\xb8\xf4/\x9e\x9d\x16i{*M&lc\xcd\x84\xcf\xc1@\x85'*}[\xac8\x81(\xfe\x9a\xab\xa6\x0d\x91v\xf7(D\x02\xa1\x8f\x7f\x92\x9a\xa8\x049\xf30\xd6\x1dbwC'\xa5>J_\xfa/\xd1_\x05\xba\xe8\x00,\x11Get\xa7\nN?\xee\xdcaA\xfay\x10\x05\xe0\xa2\x1a\x1c\x0dq\xf0\xf2\xe1\xc4\xd2\xdfP\x9bQG'0\xd4\x88\xc3\xde\xb6\x0b\x82[\x18c\x1a\x9cF0\xf5\xbb{;\x9d\x88F\xfb'\xac\xfb\xb3Re\x15\x1f&\x17\x18m6\x05h/\x0d\xe0\x9c!z\xa5\xdbT\xbf7\xb7\xb7\xd6u\xe7\xb1\xc60\xec\xb6\x99\xdadz\xe5\x8c\x03Q\xd0=\xb2pi:\x81>pn\xa3\x9f%b?\xa0\xbd\xd2\x0e\xef\xd7\xfd\xdaH\x02Y\xf7\x98$\x03V\xee\xd1\x01+\x05\x9dm\x86\x0e\xe3\xb4\xb3\x81\x08oCUgX\xec\xe5\xe8\x10\x03n^I\x97\n\x15\x9a\xebjtG\xd1\x1b\xc2\"\xfc\xd5J|\x1d\xf3 l\xe8\xca\x9f\xf4\xb4\xe6\xce\xa8\xe5\xcc\x9bbEt\xd8z\xa0\xda =6\xf7X4\xe6\x13\x88\xe9\x81Nx\xc8K\xe5\xb6\xe3\xea\xad\xe0\xf2\xae%\x16\xe0\xce\x90\xf6K9\xbco\x89 \xfcp\xcf\x1d,y\xb6\x88g)Ejw\x0d\xff\xc0\xa9\xe4\xec\xeaG\xa8\x90^\x0cp,\xac\x96\x9cv]6\xf3re\xa0\xa6\xb1\x9a\xad\xd9(\xa0(G\x12\xcb\x80\xd7\x86\x82!1\xe3\x9a\xdf\x80\x05\xa4\xf2e\x90uXX\xc4Q\n\xec\xbb=vVD*\xf5\xd8\x89\xc7\x8e!\xc8\xec\xa1\xc7.0\x9a\x96\xc7\xde{\xec\x99\xc7^y\x10tk\x0e\xe7/\x9a\xe2c\x00\x11y\xa1\x14i\xb9\xdc\xbd\x0b\xf14\xee\xd6\\#\xe8\x1aW-\x10\xff\x02\x9cu\xea\xc9\xae\x07Qq.\x06\xa7<\xf3 \xf2\xcd\xc5 \x15\xaf\x97\xf0\x8a\x9a\x0d\x0f\x02\xd9\\\xa0\x06\xc5\xf5J\xc1\xcc \xe1i\x1c\x9e\xf1$\x85\xe6_\xc9\xad\xa5H\x15\x8b\xfa\x19SA\xf3\xed\"-Vn\xc0\xd2\xb4\xaa\xa0 &\xf9\x10\x1b\xf2+\xf8\x1e\xf8\xbeq\x02\xb7\xec\xd2>n\xd2K\x91\x08\x8aIb\x9b|-f\xab8\x89C\xe0]_Z&\x9f\xf2\xac\x07\xab6@s<\xd7c\xaf\xc9\xe8%\xa2\x0f\xe8tO\xf0LAi\x808-\xe8 \x9e\xe2\x83\xf1\xd6DP\x80\xb0\x9e\xae\xfa\xbc\x8f\x9e\xa1\xecB!bd\x8a\xb7H\x9c\xde\xf3 \x99\xe6\xa1\x9f\xb0 :\x8b\xa54\xc7c\xbd\xe7/\xde<\xff\xea\x8bgo\x8e_\xbc\xfc\xd1\xab\xe7\xcf\xde\xbdx\xf5\xd2\xa6x\x17\xad\x9e:\x01!\x8bA\xa5\x92\xe8C\x03\x18o\xa9'r6^\xa3J2\xf6\xd8s}^R5/R\x89/\xf8\x90*\xfd\xf4\xd8\x99[x\x15\x14\xeb\xa3Q\xe0\x06\xc7gzV-C\xc5\xbb\x02\x8dh\xa3\xae\x13\x14\xa8[\xe2\x90\xc5\xaa\x10\xf4m:\xb2\x97xT\xc7\x97Rf\xc6F5$s=\x1b\x9a\x17\x9d\xbe\xe5IB\x93\x000\x19&\xa6\xa9\xb8C\x8eV\xad\xa6'l\xdd\x93\xfa\xed\x92\x02\xfd\x8e'lyRT\x0c\xab\xd0\n\xa6\xb8qZ\xe3*5\xa0\xfc\xda\xc12\xbd)5h\xe8\xdc-O\xdf8\x16k,\"'/V\xf3\x16U\x82\xf21\\c>\xa9\xfc\x8f\x93\xe04\x88\xfc\x90T\xf8+n}\xc4\x9e\x99\x99\x92\xd5\x7f \xde\x83`\xb7W?\xcd\xb2\xa7<\xebr\x15T\x0e\xf2U\xc1\xe8\xbdr\xb8\x0b\xbb\xdc\x01[\xa2\xb3\x07\x89\x14\\L\x86I\xf5\xcc//\xfct\x8d/[\xe6\x91r\x12o~\n\xf7\xdb._\xb3\x900\x86\xfd\xa5{\xc00\xaa\xfa\x9d;\xec\x12-\xa5\xd8>{\x0d\xbc\xaa\xb4`\xc0\x1f\xefu\xb4\xc0\x9c\x1e\x86\xa8\xa3\x1cE\x99\x83\x006a\xd4\xae\xf2P\xa2\x15\"N(\x83\x80\xc8w\xee\xb0\x13q\xe6\xd3X#\xaf\xe8\x18|\xa5\xd7\x15\xb0q4j?\xb52M\xa0#\x16\x7f!\x10y\x0bz\x0f6\x02\x1b\xac2\xf9y\x91,\xa1TZRA\xfcW\xf0\xe41\xab\x08\xf5i\xdf\x15f\x7f\xc5\x18Glaf\x14\x87\xe1\x0e\x00\xe6\xc8\xd9\xca\xe5i~\xb6\xbe\xbc\x8fMV\xcd~\x95\x05-\x8b\x1a\x883.A8\xe5\xe1\xf1\xae\xe4d2\xe0d\"\xe4\xd1\xfc2\xc6]\xbdC\xeb\xec\xe9\x85\xa8[\xb6&7\xbfj\x93\xacmi\x11\xe4\xa3\xdcTp\x17\xf1\xcb\x00}\xf5\xfe\x9e\x83\x14\xbd\x95\xf5\xe0\xad\xb0\x93\xdd(\x87.\xf7\xdc\x91\xda\xef4\xb0r9k\x02\xa0%u\x8b\xb0\xb3bE\x9b\x82\x97\xc3\x8f\xd6O\x1f\x82\xd8K\xd8\x93\xdd-\xb1\xa0\xa1\xe3\x1210\xe6\xbe\xd9\xff\x95\xf3\xcc#\xfa\xac\x0b\xbfF,\x00\xd7UV\x12\x1b8\xc7D\xae\xa4]\x81\xe3\xab\xd3\x8e\xf9\x15\xd8\x89\x02\xe7\x9c\xca\x83\xbd\"p\x0e\xcd>\xfbE\xca\xad\x1c\xf1w\x86T \x10q$\xb7h\x99\xea\xe2-\xb1\x97\x83`r0\xf5WY\x9e\xf0\xb7\x99?}\xff.\xf1\xa7\x9a(\xa9\xe2\xab\xa3U#\x15I{D\x94wR\xd1n\xf3\x8aphH\x88\x90\xd2\x9a\x90\x89<\x0b\x07N*\xddm\xe5\xb8\xa9I\x8f\xa4\xca\xa9=hdR\x19\xd50\xc2\x9b\xb8\x81*\x1b\x0d\xa6\xf1L\xe0^\x0eWu \x08D\x84\x8c\xea\x9a\x0e\xa8\xd7\x90\xc7\x93j\x05\xdc\x81\xa5\x90\x02}\x85t\xd7.H\xf7n\x0e\xed\x15e\x1e\xc7#\xd6K\xfcozu\x1ae\x96=\x11\x18\xdf\x9b\x9d\xfb\x1d\xcaf\xc97\x97#\xd6\x13\xffz\x06\x8a\xf3\xc1<\x8eY\x9f\xf1\xc1\x89\x9f\xc0\x7fQ\x0eh\x83\xe8\xca\xec\xdc\x87z\xb7,\xb8\xdd5\xa2B5Hn\xd7\x08\x9c`\xd1\x10\x94\x17q\x02\xc3\xe4\xd6c\xdb5\xbe\x1blu\xb9.\xe9\x04n\xb4b\xa4M\x8a\x1a\xedV<|\x9c@\xfc\xd1qBX\x9b\xb6\x9a\xecD\xe8\xac@\xac\xebV\xf3\x0bd\xf8\x87\x8f\x99\xcf\x9e\xb0\xf41\xeb\xf7}y\x85\xadX\xa0\xfe\xc4\xc3\xf8\xd4\xca=Q\xee\x9a\xea\x13\xcd5KT\xe8EHL\xff\x18\xaa\xc3\x87CT\x1dj\"vT\x1e>\xdc\xfe\xd8\xcaCz\x12\x15\x8f\xa1\xf9\x96\xed\x15Z\xf5\x1ex[\xac\xceC\xe3\xa4\xd26X\xb7-P\xa6\x94#\xda\x00\xda\x96S\xbd\xe3\xb2\xd31x\xc3-\xe6\x06\x8fg\xeb\x1a\x9f\\\xab\xef\x04\xc5\x94\x9f\x18\x91\x97\xa6\xf0\x16\xda\xc8\x98\x9ak\x0e\x1c\x86}\xe7\x0e\x8b\xc7J11\x11\xebr\xdd\x10\xb9\xed\xa8)\xd0\xfc\x01\xe2\xbf\xbc.W\xb9s\x9b\xf9A\xa4V\xc3\xee\x0dV\x83\x82\xb6N\xe6\xd7\\+M{]R\xf6Ulz\x1b\xcae\x88Ju`\xf7R\xbe\xeb\xeby\xf38\xee\xdd\x8e\xaa]\x0d\xd3\x00\xa5\xbc\x0es]l\xa8\x1d\x11+\xcae\xf6\xf46\xf5\xef\xb5\xeb\xa4\x9er\xc8N\xe9\x80\xe6\xb4^t\xd5Y\x953\xeb\xaa\xcaY4\xabr\xce,\xaa\x9c\xda\xe7\x96]5>\xa7\xed\xc1n\xab\x15.I\x8a1\x8d\xa3yp\x9a\x83\xf6\x95\xa6\x1a\xbc\xd0\xce\xd2\xae\xaf\x95\xa7\xa4&\xba\x92\x1b\xdf\x164*i\xe3V\x98\xe2X\xac\x87\xb69\x185\x9c\xea\xb8\xd7;>\xe6\x1c\x0c\x07\x0e4\x07s\x90&\xcer\"\xe9rp\xe6\x87\xb9\xe0h\x16J\"sV\xab\xed\xb1K\xd7\xd3\n\xcab\xd1\x98O\xd8\x01\xe5t]\xe6\x88\x7f\xe8\xb1\x0d\xacO!u\x9f\x8dQ\x9b\x9aM\xca$\xe9\xad\xa3\n\xb1\x1a\x8d\x8f\xa6|\x04\x94\xbe\x1b\x94<\xdd'\x98z*\x80\x8a\x95[>c\xb9F]\xee(J5u\x8c5\xe0*\x992\xdah\xb7\x8a\x05\x07;\x02\xba\xaf\xa2i\xe1\xd4\xe7\xf8\xb8#(\xe6\xf3\x11\xf0\xbe]!!\x89\x04-\xe7F`l\xd0hS\xf1\xa7@\xd7\x97q\x80J\xc4r\xc7|\xd2\xa1\x9e\x896\xe8`T\xd46!\xc6\x14\xeb\x1d\xe0\xed71y\xc98\x98\x08\x1e6pY\\\xfa\xe5\x8d)\xb8b\xae`\x94\xb7\x95s*%\xd2\x97(\x98\x8c\x03i%7\x14\x88\x99\x0c\xd2\x15\xdc|\x0c<6\xa4\xee\xee\x81*-)?\x9b4~V\x8ac\xa3&\xeb\xf8\xb6iG \xa2\xdfzG\xf1\xac\xf0j\xd18\xef\x16:!\xb6\xe3\xb8:\xa1\xf6\x19\xa1\xe7\xb1\xd9\x19<\xccbD(\xc9d\xac6-\xde\n\xdew\xcc\xf0\xc8\x92\xb1',\x12\xd3\x9d\xb9,\x18g\"\xb3z\xd91k\xb8\x08\x07\x1f\x8d\xc1\x81\x05^h\x95\xedn=\x06\xc2\x1b\x8b\xca\xd8\xb4\\\xc5I\xa9\xc9!\x1b\x95\xbaTu\xa3\xac>\x96&\x00t\xb9\xb55+\x88\x0b\xe8\xa9\xec\x03c\xedw\x8b\xba\xdc\xc6\xaa~\xaf\xc6\xb0\xdc\xfc\xeb-\xb7\xad\x9a\xbe\xeeU\x84G7\xebK\xa7[U\xbf\x10\xfc\x14\xcf\xaa\x06\x05\x1b\xe6\xfd\x80\xfe\xf5\x81\xf2\xc6,8\x8b\xa9S\x17z\xe2^:u\xe2z\xba\xd8X\xa6N\xe0R\x84g\xea\xe8\xe6\xd0hG\xb8t~\xfe\x01\x85q:{\xdc\xec\xf5G\x19\x8bi\xa1*\x17N\x88\xce\x88\x8bSc5T\xa4\xc72e\xb4\xc4\xf6Y\xfe\x03vS\x8eY\x9e\xa3\xea\xb1~\x1b\x04\xab\x04\xdb,\xf88\xd2=q\xf9\xbdf\xe7\x01\x1a\xdd\x1f,\xfdU\xbb#hU\x81\x1d\xb0\xcc\xe1\xe3\x08T\xcf\xe2\x7f\x15%\\\xe9|\xc9\xc9+Zi\xf3\n\xff\x07o\xbdc\x0d\xc8\xbd@\xe0\xd516O O\xc5\xbe\xa1Zq\x05\xd7u\x12D\xb3\xf6P\xb6\xddg\x16\x8f=\x8f(S9\x9c\xa8 \x85\xff\xd7<\xd5\xc5(\xda\xe0\x10\xce\xfdv\xba\xdd\xe9 \xadD\xcb\xc8\x98\xe2H\xe6I\\\x0b\xc8\xd5t\xdcF\xff\xed\xe0]\x00\xe6p\x0c\x82d\x0fe\xc4\x13\xd7c\x9f\xc6q\xc8\xfd\xc8\x01V&+}.C\x01\xd4\x05\x81]\xf4m\x8cY\x13\xe4<\xdav\x07A\xc6\x13?\x8big\x8e\xc6\\\xca%\xfa\xc8fAN\x1a\x90\x1bK7\xa5\xe5\xc9!\xbd\xfe\xa7\xf2\x9bur1\xaf\xe3U\xa7c\xb5yX\x9e\xdd\xc6a\x94\xc8\xd7\x0f\xa3f.\x1c\xe6\x08\x1f\x8c\x1f\xac'\xf9\xeaQ}\xddET\xb2\xa5V\x13\xcaV]\xd2\xdbF]\x128Z*%\xf3)J\xe6C\xe7B\x06\x08\xbf\x90\x0e\x12\x99t\x19\x0eh\x0e\x13'R\x02\xf4\xf8\xec\x16\xbe\xf2\xaa\x8d[\xfc1\xc0 \xe8\xc2zF\x9c3y\x89F\xaeN4\xf7tN\xb5\x10\xc5\x82\xa4 \x16\xc9\xdb\xdb\xf2\xc2\x9e8\x9f;\xcb\n\xc71t!b\xd9>\xe3p\x19}i\xe1\x86\xf0T'\xbe\xda\xc2\x85W[\xaft\xaa\xe2f\xe4T\xb05\x91\xcb\x96h\xcc\xc7I\x0bJ\xf5\xc8\x91.\xc9\x02\xe6\xa5R3e !\x03\x7f`/\x040\x9f\x1bzdf*'\x9cs\xe8n2\xb1\xc2\x02\xe0p\x02f\xae\xe7\xf2J*\x1a\xd2\x08\x82\xa9\xe0#\x0e\xc8\xe2l~\x02\xce\xc5\x9c\x128\x1b\xc7\x83Y\x1c\xf1\xc7.(\xe0/\xd8\x81b\xe2\xd0\x1a\xf8\x18%&\xd2\x90\xbd\xf8%\xf6ogVHS\x0e=\xb6p\x96\xb02fp\xddJ\x82\xf9\xb0\xfe\xd1~\xdf\x125K\xcc\x1c\x11\"\xa84\xf7\x9c6`\x03@\xe0\xb4\x123\xdb\x1c=\x8c\xd7\x03\xb9]\x0d'\x0e%B\xc8Py\"GZ%\xed\xb3\xc3\xc1t\xe1'\xcf\xe3\x19\x7f\x969[\xae\xcb\x9e\xee\xb3\x07\x0f\xb6\x1f\xed\x82\xc5\x12{\xb2\xcf\x1e\xec\xee\x0c\x1fA\xf9Cp:9\xee\xf7\xa3\x89\xb4g0\xc0y(\xedG\x0e\xad <+Ax&A\xd8\xef\x9f\xd9\x81v\xd6\x82\x8e\x1a:\x89=\xf0\xd4D\xb8\x02z\xbe\xa3\xad\x9d\x1a\x00\x9dS\x97^P\xe40%4\x15o\xd7\x1d_H~\x00\xbb2\xab\xc8\xee<\xb6,/\x89B\x8c\x90\xa2\xe6\x0d\xf6\xf5\x9a\x96\xe2\xd1\x8e\xd4R\\.O\xe2\x10U\x12\x8f\xee\xdf\x82J\xa2v\xc2)\xf48\xb5-\x1e>[\x91\xc3\xb6\xe9vH\xbe\xcb\xdcb\xc8{(8J\xcd\xf9Bm\xf7`\xfb\xb2\x88\xd3\xcbx\x9a\xc9\xee\xd5\x8d:i\xf5\xa22o\xac\x9b>\xddD\x89\xa8\x97\xd9H\xc6\x95Q\x14,\xd9\x04\x953F~\x16\xbfV\xdaM(B\x95\xc0N\xbf\xf3O'\xb7\xc74\xea\xba\x0e\x8b\x8aC!_\xfdZL\xd8\xac\x90\x98v\xd54\xcc\xbbi.V\x84B\xc2d\xfa\xc2\xfa\xed\x90\x1az\xed\x1b\xe8U;\x97\x14X\xb5\x06\x1a%\x8e+=\xda6i\xa5\xeb\xeaf&\xe7`\x81\x9b\x80\xb3(\xbb\xef50}57\xbb \x92\xc0\xc5\x98c\xac?\x8c\xa1q-wF\xe3\xca)\xb4z\x98\x8f\xbb\\\x8f5\x89[\xbd\xb3\xfc\xd6:\xeb\xc3\xcdrP\x04\x01\xf4CG\xf3j!\xc5h\xda^\x0b\x01\x1a{\xa5\x15\xa1\xe0B\xa6ND[ \xce8\xfa\xa2\x0c\xe2\xe8\xf8x\xc4r\xf0/\x9aQ\xe6|\xc7\x91\xbf\xe4e\x993\xa7n\x02\xfd\xa1*\x1f\x99:q\xfd\x93\xf38\x11\xd5\x9b\xb1L\x0ez\x86\x8a0\xf87\xc2\x7f\xfb,v\n\x8anHE*\xbf\xdf\xf3\xcb\xcf\xbb|\xccb:\x0e\x8b/cA\xc4R`jgv!\xfel\x9cM\xd0\xd6\xb9\xd4\xdc4vm\xe1\xa7/$\x96(X&\xa8\x06\xd1r\xd0\xa2\xaf\xa7\xa5\x18\x01\xd3\x83\xf49\xc8\xaa\xde\xaeT\xc8\x97Zsf\x01\xd9\xaa\x99a6.\xf7\xb1z\x932Y5$\x7f\x1a\xd5\x97\x82\x1c\xd6\xeaB\x9a\xac\x08\xefF-\x19\x19\xa9VO\xc5N\xc2\x9a\xf2\x97Q7\xe5~b|\x12\x13eM\xfcaV\\\xf1i\xc0\xd3zMLUU\xf1\x17Q7\x0c2\xa3f\x18dE\xbd0\xc8\x8cZ\x1a\x0fP\xab\xab\xe5\xc8\x16\xb4\x14\xa2\x9d\x82S0\xda)r\x8av\x8a\x14\xa3\x9dW\xddS\xdfoT!\xeb\xc2_E\x95j+\xae\xd6\xb1\xd8\xde1\xfd\xcb]\xbe\xaa\xc8\xb7\x031\xdcQ\xf01\xa8\x91Q\xd6g=\xd70 \xad\xfc\x863\xc5\xaby\xd7\xaf\xa6\xb5\x98Z\xcc\x1c\xe5\xbc:\xcaXG&\xaf\x0d\xac\xea\xfa\x89\xfc\x0e-\x1e\x95\x8cw-B<8\xc8(0\xce\xd1;E\xf7\xaa@D\xe8\xd5\xb4\xe7)\x98\xf6\xb0B\xd0^!\xae8\xe3\xafp\xcct\x13UHPM\x94l\xf9M\x1cj\xe9\x02\xda\xdd\xb5=\x19\xa1\xdf3\x108P\x9c\x03\xba\xf6/\xf8\x06\xfa\x1c$'\xeb\xd6\x8dG[E\xfc\x1b\x1bx\xd9\x87D\x93\xab+\x91\xaf\xc7*\xc0\xb2o\x8b\xb2\xe0\xc6\xb4\x1e\xca\xe0\xce\x1dV-2\xae\x16\xaa\xce\xfcm\x0cYM\xa0a\x12\xa5>U]\xc6`K\x81\x12\x88.\xcb\xb8\x10\xc0V\x17\xb2\xe3\xae\x8d*Uk9\xee\x02x\xe2_,\x04\"gg\xb8}\xed\xa1\xd8\xdd\x06\xfdR\x0d\xb2\x12\xf2|\xbd\x01\xa6\x86CqX\x18\x88\xe6\xa6)\x88\xf2\xcf\xa1\x1d)\xb0o\xa2R\x0d&\xee\xedY\xcc\x9e\xe9^`\xd6\x1d*\xc1N7O\xef\x01\xb1XR\x9e\x91\xd7g\xe1\xaeQ-\xea\x9d8\x12\xd1\x91\xa4\xa0t\xe2\xf0\xc1)'.\xd3i\x01R\x07)\x071a\x06/\xfbP'\xe5\x10\x9d\\\xdenC\x15\xa0\xfa\x81%\xf0\x07\xdc9\x93\x01\x8f\xb0\x90\n~$\xca\xe0\xad)\x88\xd1\x0d\xfd\x94\x1f\xc8\xd0\xc1Dv;\x14k\x8d\x89)\x04 J\xdej\x1eb\xb5\xa0\xff\xbd\xff\xbeW\xcd\x97\x87\xa2\xfd\xf2\xd20\xc8e'\xeec\xb6\xb9\x99@D\x9f\xfe>\xeb\xfdw V\x00q4\x89 \xd9\xf77j\xb5\x19\xea\xf7%Ik\xbfB\xd8\x12\x95\xc3\xcb\xf0\xd6`\x82\xf2{A\x02\xb8\x18h\xac\xc2<\xe1@\xb3q\xbf\x9f48\xf61\xd0\xb5\xcb>Q\x8b'\x7f\xcb\x17\x18\x86\x86\n8\xae\x8b\xf8Z\x00mc\x1f ]i\x06*)3=\x82\xd3\xbc\xdd\xc5\x8beA7\x9f\xe6\x99f\xc2JwG=\x01\xd8\x8bZ\xb3}\xeb\"QOPD\xdf\xf2\x8b\x15\x13\x8c}\xb8\xba Fe\xaf%>-J\xda\x06\xc0\x14>>f1{\xc2|\xb6\xc9\x86\x8f\x9b\n3\xd9\xb0t\xa7\x07\"\"\xb9?\x04\xa0\xed\xe4\xe3x\xe2j\x0eW\xad\xdd+Z\x83.\x0e'\xa0C\xe9\xf7ckaS\x05\xa9\x1e\xf9\xad\x96>\xb1\x03\x15\x8eN~N\x81\x8fl\x97\xfe\x9a6*#\x9f\xb8M\x9eV\xd0\xc8jo)\xd0(@ao\x03\x1a\xe5\xcdh\x04\xd2\xc4\x8eh\x94\xba,\xc7\x10\x0e\xfd\xbe%\xf0PK`\x03@\x1ah\xe3\xeaJ\xbe\xec\xb3q\xe3DS+\xb3\x9ao\xcd\x9e\xc8\xab{\xe2;\xf2V\x9c\xc4\xd4M\xe9\xfc\xc3 \xcaI\xcfa\xd2c\x81\xf6h(\x1b@\xd5-i\xe4\x0e\x19\xa2\xa2\xc7\xf2\xf1P&~\xc4\xae\x17}\x1fN\xc6\x01\xe0\xb8\xff\xf8F\xfdv=\xd5\x18N\xe05\xf0WJ8\xc9p\x8b\xe6P\xd7\xf3\x8e!\xdd\xc74`\xb2\xdf\x8c\xc9\xb9\xb4/o\xc6\xf5\\\xe9\xc1\xad\xa5B\xd8\x0e:\xac\x05\xc9l\xf9\x02\xbb\xec\x8bAT\x81X\x80\xe3\xb4\x0b=\x0d4,\xedNO5\xee\xdf\x07t\xc8\xc7\x81FO\x9bIi\x88\x88\xe2\xa3\xa7&\xec\xebp2\x8e\x01\xe9\x82k\x10\xd6[\xe9Yq\x15\xb7\xe8\x8c\xa8\xaf\x0c\xf7c\x0f\x10Z\xe4U\x92\x1e\xb3\x0d(&\x15\xe0w\xee\xb0P\x117\x176\xdcp\xb0\x8aW\x8e\xeb\xe1\xa4\xc8_n\x87\x96\xd7X.\xda}\x80.\xeb\xa4\xab\x03\x16\xc9\xa7\xe8|\x89\xd9\xfc\x0f\xe8_7\xe0\xca\xaa\x9a\xff\xbd-y?\x11\xdd\xd2\x0e\xc0\xa9\x9dt\xec|\x93+\x89k1q\xfa\xb7\xd79\xca\x81\xc2\x9b;?\xff\x00\x84\x92;/\xfd\x97x\x0b\x91;;\xf7\xbf\xcf\xb3N\xc1\xf5o\xec\xdf\x8e\x1c\xac\xca:_\x13\xack\xf2\xc6u\"y\x1bl\xb1F.2\x0f,\xe1,fpU\xe6-.\xb9\xb4h\x1cwZuU&\xab\xcd\x7fh\x8642\xc1\x03W\x84\xbf\xfa}\xee~\x9c\xbdP\x93XA\x10)\xd8\xf87`\xa0x\x86\xaf\x12\xab\xa8\xf2\x9b\xa0\n\xb7Ct\x08~\xe5#\xd0\x9b\xdb<\x05\xd2B\x06\x1a\xd5#++j\xe3\xe3\x08x\x10%\x83\x1b\x1e#\xad\xbe\xaf\n\x89@\xc1:\xa1\xa142\x11\xbc\x95\x89h\xdc\xa6\xb3\xca6\xddr \xeb\xc434\xb2\x96-\xfd(\x97\xb7\xfc\x8c\xf5\x10\xd6\xba\xd2\xad\xc7\xa9\x02\x9c\xd2\x00i\x0b\xaf\xdcD\x8fY\xae\x81\xb3\xe0\xc0\xfd\xb2\xa7\xa9\xe4\xc0s\xc5\x81\x8b\xbcT\xe3\xc0surH;\x9c\x1c\x9aN\x0d\x96\x13\x03\x9c\x16R\xf8\xe8p\x02N>\xfa\xfd\xbc\x0b\xdd\xbc\xce(\\O}\x06\xce\x11\x99\xc7\x02\xb0/\x10hHxN\xee@\x0b;a8\x1es\x91\xcb\xc7\xc1\n\xb2\x14\x82\x18 \x93\xc7\xbbk\xe3<\x9e\xa1B8C\xb5\xb3\xa6)B$W\xc1\xbf\xe5)\x0d\x91\xdf_\x03\xf9eo6\x1a{\xd3rd\xc8\xf4\xcf\xe7&#\x9b\x13,r^e\x91\xd3*\x8b\x9c\x16,r^\xfe\"Xd\xb3ekO%G,f\xaa#xn\xb0e\xd9 9\xbb\xe6\xf2\xf2t\"nv\xf5\x07\xf4\xaf[\xda\x03m\xbe\xc1\xe9\xcb3;C\xfa\x82\x9b\xe9K\\\x1aY\x1a\x17_R\xdb\xcd\xb7j\xb1\xf5\\\x84[6m\x88\x16!\xe3\x18\xb4\xdcx\x97B\xd3\xb9\xc7V\x1e\xd8WN\xa5\x81\xa21\x1f\x8b\xa6\xcc3\xd0n(\xc7sf\xfe\x12\xf2\x95\x13\xc6*F\x97\xf5\xc0$\xbc\x99\x97S\x9cF\xe9_\x98\xc4\xad\x04|C\xa9\xa8\x0ep\xaf\xd4*\xa9\xa7\x9d\xad0\xe5\xb1/A3\xbb\xb4`\x9f\xb7<\xb69\x14[\xc3\x99\xbc}2/\x9c\"\xac\xc4\x9b\xa9s\xead\xb1\x1c8\x1a\x00\xd9Y\x83\xe1\xf2\x87\x1a\xf8\xe2H\xb9\xe9m\x87]\xe3\xf5v\xf2\x02%+\xcc\xdd4\x17\x05$\xcct\xc3\xbd}6\x9e\x81\xcb\x8aH\x19\xf1!u\x8f\\\xd4\xc1\x01h \xeeM= nH`\x91\x89tb%}L@\xa8|e\x93\xdfbD\xa3\x1e\xe0?\xect\x94\xf2\x15\xbb\x901\x0d`\xbf^\xa0\xf7\x8d\xd2%2\xac-\xf4\x07\x1b\xe0~%\xbd\x19'\x10M!\x8e2~\x91A,\xa6\xe44u\x0b\xfb\xcd\x04\xe3G\xc4\x88)A\x89BbNlq\xa2[I#\x86\xfb\x96k\xab\xcd\x0d\xc7\x19^\x8c\x94F\xe1\xd6E\x11\x89\xa1\xf3jd-\xe9\xffC5\xcf\xb8\x1da\x14\xff\x8c,\x05\x1f\x043\xbb\xe4O\xfa\xc2d\x8d\xf1\xfc\x01\x03q\xbb\x13\xadaOf\xe3\xb4t\xdb\x8b?\xe2R'ct>\x03W\x9a\xa9t\x80\xc8\x0e\x98\xd2\xec:\xe0P\xdcY\xa0\xe0\xdc\xde \x86\xf6lbnG\xb8\xe2\x1b\x8bbh\xe7\x06Q_\x89Ri\x89R\xa9G\xaf\xaeXF6\x88\x8b;\xc9nCI\x14\xc3\xd5/\xc7C\xf5n\xd7\x90\xf5Gk\x8c\xb7\xdc\xb4gr\\\xe8)\xdc\xc2\xb5\xa1\x087wBy\x9b\xd9\xf4\xfeB\x1d\xb6q+\xa6\xa8\x00\x97\xbc\xb4\x94\xb3\xca\xae.U\xb3\x1c\xe2\x03NOp\xc9E\xb8\x00}\xcd\x05\xf9\xb2\xc5\xfd\xcc\x07OR\xd9\xb4\x03\x95\x85\x95#I\xe1\x1adr0=\xa9Q\xca\xc1\xf4\xc4-\x0d\xa0\xc5\xcf\x02\xd7\xf1G4\x08\xc4\x96)\x9d\xef\x001e\xa3\x12\xa9\x89\xeb\xe38\x8a\xc2\x9bu\xfbvA\xb0\xeb\x14\xb1\x9c\x01\xb1\xbc\xba\x02BY\xec\x9c\x0b\xdd\xabv\x95\x84b\xa2FEU$\x19 \x98 n\xb1\xf5^\xb9\xbcn\xa7r\xa2\x0bD\xff5>\xa6\xe8\x0f4\xaa\xba\x13\x0b\x8cl_\x1d\x92\xce\xc8\x9e\xf3\xa2\xe7&\xea\x1ac)~\xde\n3k2\xad\xc8\xcc\xee\x191\x18\x03\x99^\xbf\xc4\xed\xcb\xf4\xba7]\x15K\x8c\x0epc2\xb9\x1dn\x0c\xc5N/[p\xf0\xd8/\xfe\x8fd$d\xb8X\x1fG\\\xfd/\xd2\xdd:[\xabB\x19val\xb5\x0b7\xc6\xac\xc4M\x99s\xea\xa6\x11S\xa62[\xca\xec_]\x0e\xac\x96)\x14T\x1c\xfc\xa3\n\xf2\xb3\x01\x91\x96\xe8k!w{\xac\x0f\xde\x1eX\x9f\xf5\xee*3\xcf3?\x0cfL\x0dv\x19\xcf\xb8q\xf1\x8d\"I \xee\xeb\xb65\x11Z\x02\xf4\xc2\xb0r\xc7/ES1:X\xf5\xa5\xc9\x14\xb1Q%\xf4\xe14\xc2\x8aC\x8f\xcde\x13f\x19\xd1\x95i\xabS&\xbd4`\xee\x98\xb2\xb7Q\x8f\x18BH\x04\x9c\xfb\x12yj\xce\xb8\xf8=b\x9f\xf1\x8cO3>cy\x14'3\x9e\xf0\x19\x13\x88x%\xb0\x8e\xdd)\"sC\xf8\x9e\\t\xcec\xe7\x8b`\xba`A\xc4\x002K\xff=O\x19F\x1fc3hMpC\xf1\x9c\xa5\xf9t\xca\xd3\xf4\xde\xdc\x0f\xc2<\xe1,X\xae\xe24\x0dNB\xce\x9c\xf3\x05\x8fD\x13wu\xec\xbe\x0b\x13\xeb\x1eE\xcf\xe3(\x0df\x80N\x04m3*?\x1c7\x1f\x1b\xc6 \x15\xbd\xc8\x02\x89\xb5N\x0e\x84'T\x9dc\xac\xf0\x96:\xbbh9S$k\x9d)H\x13\x97\x8fz\x8a\xa8\x8b\xa6\xa5\x90\xe0#\xe9\x89\x9b\x14\xb7JOY\x06\x90k\x06[\x86\xe7\xe3\xfa\xc5\xfc\xea\xe5\xf3\x9b\x03\x88p}\xa5NYm\x91\x96\xad\x86*\xe8\xf9\xfdV\xe7Q\x9c\xca\xd6\xbf\xbd\xd1\xe8\xa2\x1f\xaf\xe28\xe5\x15\x19p\xe8\xa6]\xfc\xd3\xa2\x895H\xad\xcd\x89\xa3\x0eC\xaf\xfd4\xe5\xb3B\x10\xa3\x05\x84\xc6K4\xc1\x9c\xcf\xea\xf1\x8cn\x17~{\x86JG\xcc\xf3\xbd\xf1Qt\x94\x1c\xe5\xdb[\xdb\x0f\xe1\xef\xa3\xc9\xbd\xd3u\xc1\xac\xd0_\xcc:\x89\xfb\x85\xc2\xe2)\x1bnm1\xe5\x80.\x93\x0eX\xb7<\xf6\xe8\x11\x1c\x13\xff\xdb\xef\xfc^O\xde\xff\xcf\xd4=iAq\x9b\x97\x8a\xfc\xcao\xbc}\xf5r\xa0\xc0y\xe9pW6?\x04\xc5Fm\x19\xdd.p\xff_\x83\x9cJ\xcf1~\x19G\x9b\xd3\x98'S<\xc6e\xb1DD\x17o\xf2N>\xea\x85\x8d\xdb\x88\x11o\xd3&\x96\xdf\x0b\x06\xb3 ]\xc5\xa6L\x85p\xa9)\xfaV\xb3\x81\x08 6\xa5\xa2\x9dg\xa7]W\xe0\xcc\x03\xa7B\x1e\xab\xf93\x05\x89#\xf8\xe4AY\x0b\xdbg+\xc5\x96.@\x89P,\xd0\xd4\xb2@\xd3\xe2\xc7\x01\xeb\xe1za#\x06\xbea\ny#\xeb\x8b\xcf\x17\x1d%\xf1u\x86\x0e\xd6R\x9e\xbd\x0b\x96<\xce\xb3\xf6sO!\x00\x8aH\xe1\n\xb7\xe9\xbb\xc4\xa7\x06y\x94\xf0\xb9\x18@\xf9\xcb\x81\x88\xa7\xe0UNt\xe6\xce\x1d\xd6\x8b\xf8E\xf6.\x98\xbe\xef\x81u\x90J\x86\x05\xa4\xba)\x12E\xc5\xf5\xfb/\x8f,\xcb\xbasa\xd9\xff3[\xff\x97\x95\xfe/\xb5\xfe\xb7hpj\xf3@.\xfb\xca\xd8f\x18\xef\xbf\xd0\x98\x8a\xb3\x15B\xc8\x80\x0c\xa7 \xa3\xd7^\x92A\x15\x05.\xf1\xcf\xb9\xd8XE\xb3g\x18\x1ct\x7f\x7f_\xcf\xb9\xba\x92Q\xdb\xcb4\xb1m\x0fvvv\xd8\x88M\x9d\xb9\x83\xa6\xe8z>\x1aGmI\xcc^\xb2}\xf6\xf3\x0f\xd2\xaf\xd6\x90m\xb23\x97}\x82\xd2M%\xaa\xa8\x03\x07t\xde9\x05\"\x18\xec\xd5\x15\x83\x01\xb2}\x0dK<\x16\xb4O\xbbE\xda!\x1e\x0d\xaa\xfb\x1aT\x1d\x0d\x84\x9e\xae\xb0\xabl\xa1h\xbb\xe6\xc4\xae\x8b\nA\x08\xe8W\xb1\xb3\x91\xc6\x03\xd2b\xae\xb2\x8c}'@Hu\x12O\x84\x1e\x0b5 \x05\xfc\xa4$\x9c\xa6\xdf\xa7\xea\x1eT\x839\xbd\x0d\xcd\xdaP\x96\xd5\xd1\x96\xdc\x8b\xd0\\I \x01bp\xec,\xbb4\\Ctn`\xb9\xe5c\x88q\xc6\xf8\x8b\xdf\xb7\xb2\x05\x1a\xbe\x98\xd5\x11\xf3\xd1\xda\\\xb3\xe0\xca\xa4\x01\x87\xd8\x0e\x9e\xb2\xb8\xc9\xb7\x08\xbf\x98r>K\xd9\xd2\xbf\x08\x96\xf9\x92\x15z\x8b\x0c\xa1\xf2}9\x1b\xd9\x1e\xde\xdf\xbb\xffpg\xf7\xfe\xde\xf5\xdbk\x07\xe76\xad\x17\xdd\xd5\xafx\x04bG\xee\xb8\x1d\xcb8R\xc4^\x9c\x14{q.\xdd\xc0Kk\xf258\xe5\xe6\x8d\xd8G\x13\x9bf\xc4\xd7\xdd\xfb\x02\x8b0X\x04\x99\xeaZ\xbb\xc1\xc0i\xf9)b\x0b\x12\xa3W^\x11\x0cr\x00\x99\xd2\x1d\xc2m K\xcb\xe46(\x9f\x83\xf6xW\xeb\xae\xb1\xb32\x044q\xf3\x01\xc2F\x9a\xc9y)\xff23\xd3\xa6\xcc\x10\xda*R\x1f\xed\x15\xa9\xc3\xedm\xb8\x0f\np\x02\x18 \n\x8e]\xae&\x02\xdcz\xff\xf7\x1f\xfc~\xafq\x1d\x9av\xef\x84\x1d\x85\x8e\xb1 \x82\xc178j{\x15D\x96a>\xabK\xb5\xea\xbe;\xd1\x05\x87\x1f\xdc\xe2\xc2N\xe4\xec\x0co\xe2\xdb\x93\xf4]/\x1a\xee\x1d\x1f\xf3\xf4\xcbx\x96\x87\xbcW\xa7\xda2T\x90\x1eJ\xc1EY\x0f\xc4\xd3k\xb2UQF\x00\x89*\xec\xb1X\xbd\x96\x1b\xd0\x07\x93\xdd\x08\x1cq\xb8}Pw\xf3\x1b\xcb\xac\xfb\xdb\x10\x95\xb3\xc8S\x1d\xc0\x90cd\x1f8\x12\x99r\x9c\xd2\xef+\xb5Ca\x9c\xc0\xba\x9f\xbe\xf5\x88\xe9/\xc7\x04\xa8}\x87&\x8b\xd3x\xb9\x8a#A\x0e)8\xa8\xe7\xd9j5b\x97\xc5\x0cZ\xcb\xf9y\xb6\x88\x93\xe0\x1b_\xf4\xe4u\xbc\xcaW#v\xd2\xbd\x1a\xff4\x8bF\xecx\x8d\n\xafV<\x81\x8fA\xcd\xf3n5\xd3\x11;l/\xf9,\xcf\x16/2\xbe\x1c\xb1\x8b\xf6\xc2\xa2\xd9C4{{\xdb^:\x16\xc5\xb7G\xecY{Q\x7f\x15\xfc&\xbf\x14}\x19\xb1\xe7\xed\xc5O\xfc4\x98b\xe9\xf7\xed\xa5\xe5\x91\xe4U{\xc908\xe3ox\xba\x8a\xa3\x94\x8f\xd8\xeb\xf6\nA4\x8fG\xec\x8f\xb4\x17|\x11\xcd\xe3\xe7\x18\xd8\x9d'#\xc6y{\x95\xdf\xc8\x97\xabw\xf1k_\x8c2\xebP>\x8e\xc2 \xe2?\xf2\xc3`\xe6gq\xf2\xa9?;\xe5#\xf6\xaeCE\x85]\xe9\x88}\xb9F\xf1\x11\xfbi{\xe9\x02u\xdf\xe6\xcb\xa5\x9f\\\x8e\xd8\xcb\xf5+} A1G\xec\xcd\xfaU\x11~\x9f\xb5W\\\x04\xa7\x8b08]d\x82\xe1\x18\xb1\x9f\xb5\xd7H$\xa6\xa4#\xf6y\xf7\xd2#\xf6M\xf7\xc2\x9f\xc6\xb3\xcb\x11\xfb\xb4\xbd\xc2\xcaO\xfc%\xcfx\x92\x8e\xd8\x8f\xd6(\xfe&>\x1f\xb1\xdfh\xaf\xc0/\xf84\xcf\xf8\x88\xfdV{\xd9\x05\xf7g\xd0\x91\xdfl/\x0bF\xb4\xe9\x88\xfdZ{Q\xb8\xc5\x17e\x82y\x1d\xb1\x1f\xb6\x97\x8f\xcfxr\x16\xf0\xf3\x11\xfb\xed\xf6\xc2\xf38\xce\xc4\xc2\x8c:,\xb4\xcf\x830\xe3\x89\xb6\x9a\x93\x0e\x95^\x0b\x88\xe3t\xc6\x1d\x8aO\xf3$\x1c\xb1\xa0C\xc9t\xba\xe0K\x81\x83~\x87\xc2o\xb1\xb0\xd6\xf7\xbcC\xade<\xe3\xe1\xe1\x85\xbf\\\x85|\xc4\xc2\x0e5\xbe\x145~\x9c\xf8\xab\x95\xf8\xc6\xb4k\x8d\xe7q\x18\xfa+\xb1F\xd2\xaeUFl\xde\xb5h:b\xab\x0ee\x0f\xa3|)\x9b\x9eu(\x8e\x8c\x8e\xac\xb0\xe8P\x01\xcc6e\xf9\xb3\x0e\xe5\x0bg\xf7\xb2\xce\xb2S\x1dd\xb8F\xec\xb4C\xe9w\xc9\xe5\x8b\xecU\x9e}\x9ag\x99 \xeb\x97\x1d\xea|\xe9'\xefg\xf1y4b\x17\x1dJ\x7f\xea\xa7\xfc\x0b\xff2\xce\xb3\x11{\xdb\xa1\xfc\x8fx\x92\n\xde*\xf1O\x97>\xae\xb7\x11;\xe9^\xf1m\xe6/W#v\xdc\xa1F\xb1a\x1c^d#\xf6\xc5z\x15\x80|~\xd5^\xe7\xb5\xa2\xb7\xf0\x91__\xa3\xc2\x8bh\x1a\xe63~\xb8\\\x89\xd9\xfcq{\xcd\xa2{\x10i\xe4\xc5\x1a\x154\xaap\xda^\xed3\xceW_\x04\xd1\xfb\x11;\xef\x00e\xc1\xff|%H\xda\x1f\x1d\xc8\xd7\xe6\xb2\x02ap\xeb\xc6\n\xeaw\x03i;;}\x96\xa6\\p\xf8\x87E\x87\xc8\xd2\x9d\xe4\xd8\xb4\x9frV;K<\xef\xa4F\x88:\xb5\xf5\x9eh\x8b\xd4\x1c\x8dg\x05\xbc\xd9\xbc|M\xcbW\xbf|\x0d\xcaW\xeal\x8az@\xf9\x8a\x87\xbb\xb0L\x88<6-\x7f\xad\xca\xd7E\xf9zV\xbe.\xd5k\xe3\x89\xf7\x15\x87\xe0\x03\x8f\xa8#/\xe6m\xef\x1a\x11\x8e\x8a\xbc\x9d\xedz\x9e_\xe4\xdd\xdf3\xa2\xe5\x14y\x0f\xef\x1b\xf1\x80\xca<\xe3\xf8\x1d\x96yF_\xa6E\xde\xa3\x9dz\xde\xbc\xcc3\xfa\xb2*\xf3\x1e\xd6\xf3fe\x9e\x01\x97\x85\xca\xbb\xbfe|\xef\xac\xcc3\xda\\\x16y\xc3\xadz\xde\xa9\xca{\xb4c\x8c\xef\xb2\xcc3\xc6pR\xe6\x19\xdf;.\xf3\x8c1\x9c\x17y\xf7\x8d\xbe\x1c\x96y\xc3z\xdeE\x99g\xcc\xfb\xdb2\xcf\x80\xcb\xf32\xcf\x98\xf7\xf7e\x9e1\xef\xcf\xca<\x03.\xaf\xca\xdaq\x07\xdc\xebv\x11G\xab6\xcd5\xd9\x1amW\xc7\xceQzs\xa8\xc5\xe8=}\x10\xa0\xad\x1a\x04D\x10\xa0\xadj3b\x1a5w\xc9\x807\xbfU5\xb2\xf5x\xfd]ugDN48\x81\x1eD\x837\xf0\x03tX7#\xd7\x12\x8e\xa3\x00X)\x8d\xb3\xdb\x87.>\xaa\xdd\x02\xb2\xaaM\xf1\xc1\xaf\xf3\x14Y\x11\x8f\x84)\xc3\xf6\xd4j\x82\x10\xaf\xb4F\xf5\x98\x06z\xc2\xff\x8c\xf9H\xf5-\\j6\xaf\xbe&\x13\xc9\xd0\x19\x14&\xc5\x1b\xd3\xd1\x0c\xc6\xc2\x82D\xff\xda\xaalar\xad\xaf\xb54\xe7\x05ab\x9b\xe7\xac5\xd6\x1a\xec\xe4Y\xe5\xae\x1d\xb1s\xdd\xc7\x01n\x96\x06\xb8\xa9\x0c\x106]\xb7_$\xa9\x86;\xb8\xbfg0\x14.\xe7\xac\xa9\xcc\xb93D|\xc1\x83\x0c\x83\x9b\xd1\x1b\x98\xa3!G\xe2\xac\xf3\x00x\xcf!\x85\x97\xb0|\x0e\xcb^\xcf\x05\x8c\xea\xbe\xec\xc3\n&p\xed\xac\xa7\xcbY\x1f\x96\x8c\x8c\xb0\xaf\x86\x10+\xe6^\x99\xf4-\x0e\xc6\xb5p\xf7\xc7A<\x87\x0e:f,\x06!\xbdM\x1d\xd7E\x0f\n\xcd\x10\x88\xb3@\x17\xadi4\xc0\xab\xe8>\xb0\x01q\x8b)Q\xa4\x19\x944b\x924}\x9f5W\xc9%\xa6\xe0\xfd7!\x1b\xd5\x8d\xcd\xc9\xc6\xb3\x9d/<\xc10{6;\xc9\xe3\xc1B\xd4\x89\x9c!\xab\xc8\xa6NyT\xeb\x07\x12\xef\xd0\x19\xed\xed!)\x15\x14\xf5\xd9\xa6 \xac[\xe2\xef\x9e\xf8\xfbTKh?p\xf3\xc46]Y\xc0\x95\x87\xcd\xec\xcb0\xbf\xb5\x88i\xbc\xcb\x9a\x83A\xa0'\xd0\x92$VI\xe8BO\xb8\xd7\x82u\xa9\x14\xcf\xf9zU\x87r)\x1a\xa9\x96_\xf3N\xb7\xab\xe5+A\xe7\xab\xe5KQ\xbe\xe3\x0e\x12ZQ\xcb\xde Z\xbf\xe3:U^_\xf4^\x9d\xda\xb9h\xad*Y\xde\x88\xf2*;u\x88\xb1ws+\xb3\xf2\xc3[\x1eI;\x8e<\x9aT\x82q\x9e\xe0#\xb1\xee\xe5G\xaf\x18\x05\x17/!\x01\xf7\x9c\xdb*w_1\x0f\xa9(b\x0f`\x1fw\xc9\xc5`Q~p\xcc\xd8\x97\x8e\xdd\x04T\xef\xcf\x0e\x8a\xdd\xc9\xc9\x00\xa3\x8f]S\xa7\x8aG\xea\x87QC\xa7\x9cZ\x17\xed\xa6\xa6\xa13z\xe6*\xb9\xcbg\xad\xac\xfd\xe4\x87:W}\xb82\x1b\xc3\x1b\xa2\xe1\x08\xc2\xe5\xbcb\xf4]{>\x8a\xb5\xf8H\xff\xe0\x11\xd3\x0e\xafi\xc8M\xdb(w;\xbbr\xd5\x94\xa7\x9a\xa0\xf7\xe6 \xc8\x9f\xab\xe8\xf7\xa1q\xce\xd7\xf5\x8c\xa5P\xcc\xa3\xe3t\xd6\x0e\x8fi\xa9\x8b\xea\x84G\x11\x1f\xb6p\xa2)\x0f\xa7<\x98\xd3\xa6`\x85 M\xf0\xe9\xe0\\\xebM\x0bH\x83\xcfCt\xa7\xd4/\xc0\xb5\x08xH\x07\xe7\x9e\xbe\xc6]\xb3\xc5-\xa8\xd2#O\x18z~\xcd\xcd.\xd1\xd0\x91\x0e\xce\x93RZ\x8c\xbcE\xa37\xb9\xfc\x08c\xd8\x82|F\x18\x817\xba\xc2\x98\xa5\x0b\xe2[nq\xe4'\x11\xf1.ps4W\x0fDu\x86p\xcd\xb5=\xac=\x8fV\xc4oH\xede\xde\xc1\xea'c\xf2\x0c\x1at:\x9b\x02v\xe8\x14\xfb\x07\xda\xb5\xe2\xaf}tj\x15\x0e\xb2\xac>\x97\x83\xc6\xe0\xa0\xb9\xbd7\xa0aJcG\xf0\x1f\x19\xba\xbap\xdfPo@o\xfd\xd4\x11\xeed\x9d\xa1\xcb\xeb\xb0\xdd\xa6\xd8\xe2\x07\xce\xa1\xd3\x15\xfbn\xc3\xbb$~\x08\xde\x9d\x17\xd0.\x0fI\xcd\xd6\xf1\x83\x13rk\xd8<1N\"\x9cA\x13\x87\x9f\xd8\x81\x13\x9b\xa9\x01T\xf7e#Xp\xfc\x1d\"\xe6'&\x11\xe8\xdc.\xd5\x8f\xde\x95\x07\x9f\xd4\xf8\x8d\xc8\xb7\x08\xaf\xec\x89 O\xec\xa08uR\x94D\xad#\xff\xd8n\xe4\xfch\xd2\x0f\x9e{\x15\x0e\xce\x8d\x01=\xc3bR(`\x8b9\x19\x8e_\xfb\xb1\x8b:q\x19\x98\x99o\xac\xe2\xf0\x03\x8f\x84\x8f1\x8c\x98`\x1e\xe6\xe0\xa7 \x0d\x16\xb60\xba\x08\xe7\x0f\xe8&=i\xcb<\x81\"Z7\x9f\x85\xe77c\x08\x9b9\x93\xf3\xf9X\xcd\xf1\xaf\xfb\x18\xb8r\xf9i\xc7\xb1\xa4\xf9E@\xe0|\x14\x01\x9e\xd9\xf7#\xf1\xfd[\xb2\x01Gy\xbe\x8c/?\xf9]v\xc6\xe4\xe8\x1fr\xf4\x1f1\xfc\x0e\xfb\xd01\x8d\xb7\xdd8\xc5\xf8\xec\x13i\xb1~\x0dk\xf7\xd98\x7f\x8deQy\xbb*\xfe\x11\xb8\xd7O\xac\x1b\xf6RD.>\xe9\x83\xdc\x14\xdd>t\xcf/\xbbn\x1f\xe6\xdc\xd5Jx\xcc\\\xfaU\x17;=\xfaP\x07\xd1\x84\xb7\x9bc\x8a\xfcY!.V\xa0\x1f\x15=\xd7\xe0\xa1\xa8\xbb\xfa\xfc\x107O\x925Ppv\xfc\x97z\xf2\xf2\x92\x84\x8b/\xfc\xc7\\\xf2~\xf8\xeb\xbaV\xf9R\xad\xcc\x19\xc5b@nq\xa5&\xd4\x1d\xbb\xaes\xa2\xc4\x8c\xaa\x8d\x8f\x86\xe3fQP\x8ar\x07\xceJ\xae\x9ak\xd3\x15FWe\x9dtGI\xce\xca\xcey\xb67\x98\x80e\xd4\\\xe3\xd9\xc9jq\xe9\x07\xd9\x18v\x16\x8b\x9f\xe3\nL\xbc\"\x97\x8f\x841k\x80\x7f\xad>K\xd8\xb3S1\x8f\xceH\x0dTS^\xe7\xf2>Bti\xd2\xdc\xcb\xebH\xd6\x11\xaa\x10\xe48\xcd8$\x82\xe8\x18\x89\xb9\xd4\xc1\x84\xf4\xa6\xea\xb8\x89\xdd\x14\xe9\x07\xa8\x98\xa18Q0\x04\xecG\xbc\xaf\x1a\xb9\xf9#\xc6\xa4\xe0\x93#\xf1D\xc5\xe6\x8b\xc1\x82\xad\xb2\x15\xa5\x8b\x08\x0f\xfb\xfb\x80>r\xfc+a\x1c4\xbd\xe1\xbe[c\x0c-R\x9a\xe4\xc2Y\x0c~\x82\x1e,\x06\xbf\xe1\xffx\xbfr\\E\xc8\x0f\x92):)\xbd\x1c:\xcf\xf6\\G%\x15B\xbb\xba\xeb:j\x11\xa9*Xy\xbf'\xa5\x1e\x15rS\x9d\x1a\x83N\xd3\x1aK\xfe\xe8@G\x98@\xd1<1\xf4\x14\x10w\x1d\x1e\x8aD\x8bg50\x15\xc3u2\x06\xe0\xce\xb1k\x1d5.w\xd3\xb0\xc5\xa8n\x9cL\xee\x8d|\xd9Nro_+\x9aV \xe9\x1c\xb3\x86\x1ao\xc8N\x06x\x84\xbb\x03\xdc@\xce\x95\x8a\x15\xb6i\x91 h\x9a\x92\xca\xa9\xea\x0f=N\xb4R\x83\xd2\x92\xbb\xf2Z\xb57\x91\xa8b\xd6\xd8\xf8\xed\x05UIFm\xb9 A4iI\x90\x0f2\x96\x8b\x99\xc5\xbaf\xa4\x9c\x9d\"\xed\xd5\xac\x18|\x01\xf6\xc1\xef\xf5\x9a\x19\xc0\xc4\x90\xb6C\xfd\x88\xec\xc9\x9c\x02\xb2\xbd\xd9\xeb\xf5\x0be\x19\xc3\x88\x96\xa9\x0e\xd4O\x82\x9cE\x92'q\xc8D\x12\x89\x8d\x0d\x94/b'lb\n\x8d23\x084W\x9a\xd2\xd6\xd3eG\x90.\xc6\x03\x1e}\xc2\xf1\x07\xd7m\xcf\x95\x98x\x8d{\xf7[!\xba\x19\x8b\xa3\x07`\xf1\xc3q\xab\xbe\xea\xc5\xb6\x03\x8b2O#\xdd\x82}\x05\xa2\x81\x08\xc0\x1b\xd9V@!A\xf8\xf5KmMtgu\\\xdcuc\x94\xc1\xf2P\x93\x1b\x1f\xb9\xce4\x8f\\P\x87\x9cG\x12\n\xc3\xb1~%e\xb8\xa1 P\x8c%L\x85\x9aT\x03\x12lg\xd4\xa2\x9dt:\x9c\xa9m\xf5!\xd5gd\xc7\x167[\xb6\xc8Z\x19i\xda\x15\xe5\x86\xd6\xb7\x1e\xd4:\xfb\x7f\xd3\xd8\x87xj\xe8i\xfb\x0bzb\xffo5\xf4'\xea\x180N\xe9B\xc4=\xc66\x94SQ\x8b\x91f\xbb\xb1\xea\x8d\\d\xb9\x1d\xc5\x14\x84\x83\xf7Y\x8a.1\xc7\x17 \x8d\xaf)\x06v\x88\x07\xbf\xd1\x8b_\xfc\xb4\xfa\xac\xfc>O#\xad\xbd\xde\xcc\xf0\x91\xf6z3\xa9^o\x86\xce\xb3-\xd7!M\xd7\xf9ZNX\x1ay\xb5\xca+\x19\xf7ui\x13\xf0> \xa5\x00\x94\xde\x88\x90*\xa4\x06\x16o\x00\x9e\x035&\x98\xe6J\xeeE\xd8G\xbe\x9c\xa2\xdd\xc5\x97(\x88\"M\xd2\x0cPEScl4\xc8\xa3\xd5cl\x1c$\x04\xa9\")\xb6\x8d>V/)\xb5\"\x00\xc2\xaf|\xca\xf8\\\x9e\xaf\xbf\x00'qy\"D\xdb\x9a\x90\x81\x0cv\xe9\x04\xd6\x06\xf3D\x1e\x1d\x9fcgH\xae\xfd%I\xa5n<\xff9HR\x12\xceI\x10\x85\x1a\xad\x05\xc6\x7fC\x83\x1ey\xda\x98\x00z-\xf2\x7f\xe5\x15\x1d\x83\x1a\xaeq\x8a\xf2\xe3\x89\xc8\xa5\xadu)|\xce\xad\xda\x8frU\x95.M\xb5\x06\x92\xfa\xdd\xb1\xe0\\\x94\xb6\x8b5\xec\xc3<\xf2x\x94\x1c\x1e\xff\xeb\x94\xde\xa6G\xd1\x9c:]\x9d\x8e\x92\x8b~\x81;\x888\xe5p\xd6\xba\xb0Q\xec\xe3]\x92\x98x)\x8d_\x93\x94\x8c\xaby2@J|m\x00\xb1\x1e\xccI\x8a\xb7\xbel*\x8b\x06\xfc\xd6\x12\xe1\xbc\x0f\xedf\xbb\x16A\x08\xf5\xdd/\xc21\xc4\x06~\x0cS\xb2\xf2\x9d\xd4\xb4D\x80\xfb\x8e\xc7\xb2b\xef\xc1>\x86\xcf\xa5<\xfe\x0c\xcf\x0e\x1a\xa2\x9e\x1c\x1f\x19\xe6\xd4\xea\xdch2\xbd2\x9c&5\x93J_o\xa8\xc5\xc5\xef\x9a!\x8fLA\xae\xda\x804\xd0\xfe\xdaN\x95,\xb0>\xc1,\x8f\xa8\x15\xf1\x88Zq-D!W\x07\xe1ej\xcaD\x06\x8cf\xbapR\x0c\x93\xaaa\xc0\xa2p\xe1/\xb3\x98\\p#\xdb\xfa\x12/i\xda\"\x0c\xa0\xa2\x0djB\xcd\x07\x9e\xff\x8d\xeb\xa87\xa13\xaccm\xd5\x89\xc1\xf2*\xcbm\xa2\x8aNc'\x1e|\x80\x1e\xc4\x83\x8f\x16i^\xa4\xf7j+\xe8\x10\xa1\x9e\x8b$G\xc1\xf6\x82/\x7f\x18\xa4\x9c\xd0\x84\x1e\x9a\xa0c5E]\x08\x93blF\x93\x17\xf1\x1aOH\xe0\xb8U\x11\xd6v H\xe5\xa8\xb6\x82\xee\x1a\x8f1\x99}\xf8\xee\xe3\x12\x91\xd3\x1e4,\xb3\x96\xe8;\"o\xddt\xcf\xcfM\xf7\xca\xe8xbA\xc44n\x8d\x84\x11#\x11\x987\xda\x88n\xbe\xd6\x92A*\x00\xc3\x01E\x93\"\xa1u\x1d\x17r\xb0\xeb\x84(\x9f6k\x04\xdb\x00T\x82\xce\xba\xde&b\xf4\xd9A\xa32\x99_\xc2\xe9*\x15\xbb5+J\x0c\x01?\x88\xe9\x92\x864f\x0c\xd8\xc7,L\xfd\x15\n\xdd\xc2\xa9gIS\xc5\x95\xe7\x88\xach\xe2\xc4\xee\xc0\x0f\xe7\xf4\xf6x\xc1\xda\xaf\xbe\xdcu\xe1eM\xe3\xe5\x83\x08c\xa7\xeb\xae\x809&{\xd1\x0d\xa8\xe0c\xcb\xd6\xb7{\xec\xd4\xc2\xb4\xec\xfa\xb7\x94\xc8\xf9\xc8;\xd5yx\x11}S\xf7~\xb1p\xc6\xeb%\xeb`\x8b\xf7\xb5\xeb\xae\xb6\xa5\x18u\xd6\xeel\xf4;\x0c\n\xa37tU\xaf\xf8`\xd5\xb1\x9c/v\xd95\xab^\xcb7\x91\xdd\x93\xbb\xd5E\x14\xc0D~\x19\xd7\xccVA\x9c5\xfe\xc0O9@\xd0\xbe\xf1?\xffS\xfe\xec\xd6\xeb\xa3\x8e\x92\x87}}[~\xa9T\xa6y3\xc17e\xb0\xc3S\xb2\x14\xef)%\x9a\xb7\xf0\x92*BX\x95\xce\x94zMOX\xf7\x99\x91\x15\x04\xc2z.\x04\xc8\xf0\xa9\xa8\xe9\xb9\xad8w\xc7\xd4\x0d\xecC\x80\xb9\xa6d\x93\x0c\xde\xee\xe0&&\x8c\x99?\xaf\x93))\x03t\x93,Y\xd3pN\xe7')\x89S\x0d\x0c@H\x04E\xcd\xbf\xfa4\x98\x1bj\xa2C\n\x8f\xa9\xe4\x87:\x90\x820\x06\xefz\xd1j\xcd\xf6\x92\xa9\xa5k\x9ePA\xfbl\xa5qC\xc4\xf2)\x995\xd1Bhb\xce\xf4\xc0Z\x16\xbbfI\xd3\x0fr\xe3\x1c/\xf4#\xbc\x83}X\xb2e^:K\xe7\xbd3\x9d\xb9\xbaKS\xf48\xb9C\xb3(\x14n\x85pw\x87I\xb3ej\x91;\xcd\x8blD\x17h\x9c\xad\xde\xf9\x1e\x96~\x95\x028;+M+\xb7\xa5\xfa\x17\x15\xeb\xed\x93>\x9cT\x8an\xfbp2M\x18\x88o1MW@\x90\xc6\xb3\xe5\xfcIb\xa4(\xbf\xf8\xa5\xcf\xd7mp6\xc3\x83\xd2\x19\xb2\x0fW8m\x8c'\xaeu+\xb5!j$n\xe8\xaf\x9cs\xf5\x0d{dh\xed\xde`\xa7\xf9\x04\"t\xca\xe2\x1e]\x0f\xb9'\xcbU\xcb\"\x9f\x0e\xe5\x8e]Jk\xfa%\xd0\"\xf7+\xc4\x8f\x8b*vuY\xd97 \xb2}\xb8\xc8O\xe3\x074\xd6\x9d\xf2\xd3\x18\xf2\x01Ur\x1e\x82\\\xe0+z\xd7\x9c\x8a\x04\x14R35\xa46\xa8\xf9\xaf\xa7\xd2\xa8\xc4\xba\xbe\xec\x94\xbe\xa6qB\xab\\\xb4\xfa\x91\xa3\x83f;>\x91\xd9@\xde\x1d\x19\x15\xd4\xeaG\xca\x06\xe9`\x1d\xadMZM\xf5\x83\x0c\xb5\x98fn\xd0\xc3\x91\x08\xd3h\x84\x1c\xb5\xb8\x91\x92^l\x94\x1f\xb3\xa5\x1c(\x02q\xde\xde\xd0\xd6\x9e\x96Hx|`l\x91\xdf\xf7\xe1\xb4D\xe8\xf4\xa0Q\x0e\x8c1\x9c\xeaW%\xa6 m\xb4\x02\x91\x1f\xccz\xc1\xedp\xe8\xb5b\x9a%\x14y\xf2gBCy\x81;8\x17?B\xf1L\x81'\xffM\x03\xba$\x18\xa5\x84'\x92\xc4\xd2\x15\x86 \x95\xd9\xc0\xba\xa2\x94\xc4K\xa5\xa54\xbe;\x0c\xd3\xd8\xa7\x89\xcc\x97\xec|p\xfb\xd0i\xb0h,\xa2\x9d\xb3uG\x91\x17\xbaiWxo\x88P\xdbCW\xe1N\xb8v\x86;Kux\xea\xb4\x9eL\n;\x12 \x86X\x1d\xe1[i :z\xf0'i\xb4n\xa1\\\x03i\x00\x95\xa3\x8f\x19\xb7\xa5\x0dU\x05H\xd3\xe1l XP?\xb2\xb8\xd8`*}\xd4\x93p\x98\xd0\x01\x1eJ\xf2\n\x86-\x82\xf9eU\xd3\x14_\x93zb\x020\x83\x821\"L\x8c<\xbc\xf5\xe8:\xc5\xa8\xb4\x0f\xc4J\x06\x9c|\xa0v\x00\x156\xdf\xcd\xb4*vL\xa9\xf6\xd5\x8f\xd4J\x0d\xc4\x96\x140\xecC&\xf0\x16m\xc4\xc5NA\xef\x11\xae\x04\xaf\xa3\xba\xc4s\x86\xcc\x1d\x8b_\x85y\xe4\x12\xc5\xfd:\x1aHg\x9d\x0d\x18=\x07\x1fU\x11\xcfacC\x1b\x17B\xfd\\\x8b\x1c\xffU\xac\xf2\x1b\xcc{@H\xb1\xa4\x15\xf2\x81D\xc08\x8a\xc4\x9e$\xac\xb7w\x91\x97\x13\xe8\xd8\xe9\xd2pn3\x1d\x97\xad\xc8W\xe1\xc5>\xe4d\xabi\xa2 &\x8b\xb9kD6\xf4>tQ\xc3\xf1.\xf2\xba\x96\xd3M\xfd\x04\xe5\xd7\x85J\x18\x1bhw,\xe1\x9dm\xd0f\xb4P\xa3\xcc/0=/\x1f\xb0\x02\xb7\xa2\x10\x1d\x10\x9a\xc7\x01\xda\x96\x8b\xb9\x94\xdaV\x8a\x1b\x1b\xfe\\\\z&\xdfs\x8a\x8d\x0d\x7f6i\x1et\x1f\xbc\xa3\x0d\xd4\xfc\x1b\"\xf7F\x1a\xdfA\x92\x92\x94b\xd6\xf4\x1b?\xbd\x8c\xb2T(\xc5\xa2X\xde\x07\xb4Yy\xf8n\x10\xb7\xd6\xb0\x98\xf9?\x84\x84\x93\x8b8[\xa7-l\xac\xe5G\xe15\xed\x94*\xcc)\x95\xf1Z@~r&\xb0B\xa9B\x03\xbf+?\\\xb9\xaa\xa1\x18\n+\x10W\xb6rny-\x96*.-U3VI\"m\x10\xe8\xd5\xcfEL\xc9\xd57]D@}&\xa6)\xc5\xc6\xc5y\x8f\xfa\x02\x99>\xac+}z\xf0\x16Q\x01\x0e\xc8\xd4%\xbe2el\xcc\x17\xac\x9c\x05\xdb\xe5a\xe2s\xd7\xd7\xfc`@-^#wA\xe4\x11K\xfb@\xc4a\x99\xf6\xb11\xc7\xc2=\x8a\xa3W\x1do\x1f\xae]a\x0e,GA\x1d\xf2 \x06N\xbe\xf6\x00\xa4\xff\x16\x1cVi\xc58<4\xcb\xc6\x1fLJ\xf3\xc7\xf6a\x0c\xe2\xea\xa3R\xd3\xc9Y7\xb9\x83\x04\xf3\xc2\xfe\xd6\x98s\xd1D\x19\xc0\xfctf=\x84Q\xbc\"A\xa9\x07y5\xed\xa8o\xa4n\x1f\x0c\x1e\x7fz\xa0/\xfc\xd0O\x1a\xfd\x13\xf2\xda\x05\xc7o'2iNd\xda\xf9\xd3k\x88L\xda\x82\xc8\x84\xea\x8e\x11\xdbKe\x9csL\x0c\x95\xad\x81\xc9\x89\x17)\x8d\x19e\xe9\xa3\xe3\xb8 h\xf0P\xb2\xdd\xca\xdbC~\xfe\xfd\xa0)\xa8\x92\x80d;\xa2\xcb\x8d\x84\xdb\xb2\xa4\xa0\xd9\xb5\xb1\xd8\xb5\xcd\xfd\x81\xa26\x8b\xed\xbb[\xfd|0\xd9d\xab\x1f\xfb\xb1\x0e\x05\xc10\xcb\x11\xf0\x85GG\x8d\x0b\xf2\x03&\xca\x07\x82\xef!iJW\xeb\xb4\xfb j*\xb5\x01x\xe32\xae\xea%\xad&\x82\xea\x0eR\x94\n\xf6\xe5\x91Woc\x8c7`\xe7\xecc\x9adAzDVt\x0c\x0d\x01-\x18]{\x17yc\x83m\"p\x85\x0e?\x9d\xb8\xe2A\xa1\xab9u,\xc4@\x03q\xac\x95VM\xc0J?sy\xf6\xbcA\xcd+q\x95\x9f\xf1\x8a\x9eI\x89\x0fs(\xf2\xe6\x1d\xea\x01Q\xcb\xa7\xe9D\xaa\x82[\xfb\x0e\x11Z\xe5S\x07\xef8\xa7:[f\xb1\xc8\xfe\xe0\xdc\x0f\xaf#\x8c\x02j\xb3\x15P?\xb9\xdd\x80U\x8b\x99\xb7f\x8a\x95(?\\s\xc8\xd6n\xae\x11\x08rm-\xf8 \x90 \xa6d~\x07q\x16\x86~\xb8\xb4\x89\x01E\xabZc\xf9jU\x95\x1e\xe5\x19\xc6\x0d\xd9\xf0\xe5GL\xf4\xadA9\x0e\xcd\x9a\x85\xb0\xe0\x00\"<\x96\x10O\xfd\xe7\x8d*Z\xc9\xf6\x85\xf9\x06m&\xef\xa4\xa9Q\x10\x0dg\xe8\x14B\x18\x064\xd3W4\x96m\xd32\xc8\xca\x08\xe3\xeb\"\xafns\x1f\xa0(\x85\x1a+\x7f\xa9x\x06\x12\x13\nZ\"\x97\xc7\x85Pjb\xc3B\x0d\xdb|\xfe\xe4\x92\xb9\x8a]E\xa3\xcd0+\x90x!q\x92m\xbc\xcb~\x9b\xde\x01\x9d\xa9j\xba@\x07_m\xf0v\xe2C/1\xb6\xa1BU\xc3\x01\x97O\x9d\x82o\xe5\xad6l\x18\xd8\x87\xb9\xbd\x8a\xd4\x17\xdd\xe4D\xa8\x19\xb1K\xdcq\xd2\x9a\x99\x10\xc0\x957 \x13\xb8\x841\xac\xfb \x8e\x8b\x87\"i\xe3u\xa6\xfa\x11I\xfd\xb0\xabvZ06\xc6\xb1\x18k\xe3\x0b_\xb3\x07T\\MrQ\xc3\xc9\xf1\xae\x90Y\xa4ZV\xd2\xad\xc4\x8eX\x06F\xbaV\xfa\x99-}\xd8\x07\xe2\xf6+\xc97M\xc7\xf0\x8d\xed\xc42;S4\xaeX\x8ai\xb5$z\x99\xd7\x89\xc4\xcb\xdc\xb3\x07\x87\xd1v\xa6\x8d\x11\x1c\xda\x0eQ,E\xc3\x08\xdb\x0e\xab\x15\xd0\x0f1\x9e\xa0\xe1\xe1\xad\xed\xe1\x89\xed\xe1+=0\xa6R\x01\x91c\x9d$=\xb3\xfc\xce\xcal\xd8&?\"hg;\xf1Le\x83\x05\x93\x84v\xb2\xadW\xb7j\xee\xaa\x9f\xf0\x95\xc5\x9a\xb4Nu\xd4\xd1\xa83\xb1\x19\x1a\xe4]\xf9\xad,\x8d\xe9\x8dt\xa7W \xda\xc0\xc3A\xc9\xb2\x90\x07\xbc\x8ey\x90\xbc\xa6\xd7@\xe1:n\x1c:\x0dg\x18a n\xc9{Hr\xd5\xd9\xdf\x177Fm:\x04\xe5\xa8\xc9\xda\x13a\x10\xd7\x11 \xbf@n\x1e!\x14pE\xcb=\x8dE`\xa0(E\x03L\x05\x8bV/]\x17&r\x1dr\xef\xa2` \x9e>\xc8\xb8\xa3\xfaI\x1d\xb9\x99\xa8X\xa2V\xaf~~\x88\xeb\xae\xfaI\x9d|\xd3>\xacC\x17\xc6u\x10|\xd5\xd4\x93\xdc$\x01C\xc9'-\x07\xd2j\xc8\xcd\n\x04\xe2d-x/\xb1w\xd2Z\xb0\xf8R\xad\xb6T\x08\x14J\x06\"K;\x87\xa0\x8f{z\xcc\xa8B\x9dv\xb5\"]\x07\xd6\xc8/<\xec\xa6\xd4\x0bL\xe5\xfd\xacF\x11U\xb0\xb9F\x99\x13or\xea&\x0e*\xb3\x92\xb6`\xac}L:/\xc74\x10\x80\xa9^\x1f\x17\xca\xd8\xc2PB\xcc\xd5\xd0e\xaev\xbc6\xd3\x84T\xc3:\xe5\x1d\x943\xd0\x9f^\xd2\\\xa1\x02\xf3\x88&\x10F)\xac\xe3\xe8\xda\x9fS \xf0\x18\xdf\x7f\x0c\xbcA\x93b\xc8\x86\x0b\x9aH}\xdaE\x8c\x90*\xc7}e%\xc5\xa85\xf4\xb9&H\x0bz,\xf1\xcf\x02\x80Hh\xc5\xebK\xac\x81\xa8\xbc\xeb\x89\xf4B\x90Tm\xe0\x95\x88\xe0\xed\x9dt\x8a4D\xe8\x9dfx}!\xe2\x99\xa7\x85B_\xa8\x9b\n\xee\x02\xcf\x95\xb4\xa4P\xb2\xdb\x19\xe8f\xc0\xb3\xcd\x8f\xcb\xef6\xa0@\xbe\xfc|\xd0\xe0s\x1c !\x88#\xc4\xd4W\xab\x9d{lwa\xd1o \xae\x1d\x1e\x03\x9d\x0egu\xf4\xa9\xaf\xc3\x88\x9b\x9ar\xa0\xc9\xcbd\xcc\xc72\x9a\xb9}\xd8T\x1f\xabz|\xa0\xdc\x1d>\xd7\xd2c\xd1\xd6\xcc\xad\x9b+\xa19]\xdan\xce\x1f\xecs\xa6\xea\xed\xd9\xfd\xbd\xf6\xfa,\xcdMR\xa4L \xbd:R\x8e\xbf\xa5F\xf6\xab\xd1\x94\x0d\x03;\xd5\x0f\xac2W\xd8\x87\xa9}]\xb8\xa9G}e08\xacd\x92\x8f9\x10\x8b\xc8N M\x9d\xea\xfd\xbei\xa4\xef\xf5#E\xaaj\xd3\x16\"|\xa7\xc4p\x07\x81\xb4]\xa1\x12|\x7f R\x9fom\x8fJ\xcf_\x1d\x7f<,?/eU\x1a\xbc>|s\xf0\xe9\xdd\xe9y\xb5\x9fQ\xa5\x1fY\xef\xcd\xa7w\xefJ\xf5\xb6wJ\xf5\x82\x88\xcc\xf1\xc2\x94}\xa9>8\x08\x82\xfc\xd9\x01\xe3 \x8a\xc7 Y\xd0w\xf2]\xf9CWA\xb6\xa1\xfcV\xab\xcd\xb3\xd5\x1a\xb95\xf6\xa5\xfa\xfek\xf9P\xfeP+\xfc\xf5\xe0\xfd\xbb\\q-`\xb0W\x9a\xdb\xfb\xb7Go\xdf\x1f\xbc\xb3-G[0Z \x98x\x84\xbb\xedv\xd9\xb7n\xe9\xd9\x9a\xc4\x18F\xd1w\xba\xf8\xb5\xfc\x14\x93\x19\xcb\xe7\xe2G\xb9\x06\x99\xcf_\x95<\xa5|\xa7[.\xeb~\x93M\xfc\xb4\xea\x06\x1d\x15\x00-\x95\x8b\xb4Z\xdb\xfaDq\x08\xbdRyV\x80\xacT\x9eh\x9cE\xad^\xa1\x01F\xbd-\x15y\x18\x07\xbaL\xaba\x1f\xb6\xcaE\x0c\x81\xb6\xcbE\xf3z[\x97\xf5\xb6\xae\xebm\xad`\x1f\x9eL\xcfn\x87\xc3\x8d\xb3\xdb\xe1\xd3\xb3\xdb\xe1\x8fg\xb7\xc3Wg\xb7\xc3\xc3\x8d\xb3\xdb\xd1\x9b\xb3\xdb\xbd7\x1bg\xb7O\xb7\xcfn\x9f\xeen\x9c\xdd>{s\x96\xbdy\xf3\xe6\x10\xff\x7f3\xbb\x9f\x9ee\xaf\x9f\xb2\x97\xb3\xd7?\xbey3s&\x1dV\xf2\x8a\x97\xb0\x1a\xee\xbd3\x19O\x7f/W\xbb\xff\xdd\xadT{R\x1e\xd6R\x0c\xeb\xe9\xceY\xb69\xdc|\x8a\xff?\xab\xd6\xba\xc3Z\xfd\xb3\xe9\xd9\xec\xec\x1fg\x9f\xab\x8f/\xd8\xe3\xdf\x9d\xc9\xb8s\xdf\xe9\xdcw\xa6d\xe3\xefg\x1b\xb3^\xc7\xfd\xf3\x13\xbf\\\xf3\xbc\xa89\xfd\xbdh\xcfu&\xe3\xff\x98\x0e7\x9e\x91\x8d\xc5\xec\x1f\x9b\x9f\xef\xf9\xf7\xbf\x9fm\xfc_\xcf\xcf\x9e\x9cM\xc6\xff\xf9h\xff\xacw\xf6\xe7\xfe\xf9\xd9\xa0\xf3?g?<>s\xce\\\xf6\xf6\xcc\xfd\xe1\xcfO|\xddYqc<+F\xc3\xc2\x8an\xb4\xc5\xbf+\xd4\xbc\xde\xd4\xa1\xb1\xa9gEK[\x9b-Z\xba}HK8\xbe\x87\x8e\xf5\xc4\xd8\xc3\xf6v\xd1\xd4\xb3\x91\xf2}K\xe9b\xb3\xf4c\xa7E\x87\x1a\xbd\xbaF\xc5,\xc7\xf0\x14^\xec\x0bgI\xf6mg\x0f\x13Zn\xb0\x07cx\xb6\xc7\xca0\xaa\xf8\xd6&\xdc\x0b\x9bF4a\x1c\x0d7\xd1\x9ca\x83U\xea1\xb0\x8cacd\x1d\x98F\xff]\x8c\x82Or\x02\xdd\xb3a\x97\xf7\x9c\x97\xfc\xff\xb0@\xadr\xc1JF\xa3]\xa5(\xc5J\xd5\x82Q\xbe\\\xac(\xe4EjK\xd7X4\xdcT\x8a\x16\xbc\xd6\xb6R\x14\xf3Z\xa3\xa2\xe8\xff\xcfJ\xb6\x94\xd7\x00\x0b\x8a\x97\x1ew\x1f\xc3\x18\xb6\x95i<\xc1\x11\xaa=\x9d\xb1\x92=e8\xff\xe7\x7fc\x9d\x1d\xa5\xe4\xff\xc6:\xeaL\x91*\xb0\xd2\xa7\xc3J\xe93V\xda\xedZ\x17\xe1\xc0\xb8\x08\xb8\xfe\xbb;;[;0\x01\xeet\x87y\x0b_]\x92\xf8U4\xc7\x9c\xa8c\xed\x83\x9d\x9d\xcdg\xbb\xd0\x03\x87!\x0eka\x17^\xbe\x84\x11\xe3uvv\xb76\x87\xe5G\x8f\x18\xbc\xb7\x14o\xd9\x82_\xcb\xed\xe4\x8e\x85\x9a\x043\xee9\x9b;\x8c5\xfb\xa0);\x054\x97;\x85\x17\xb0\xb9\xb3\xfb\x1cN{=\x17\x8e\xa7\xa73\xd8\x87+\xe7\xd4\x85 \x8c`\x0c\xc3>|(\nu\xc4\xe9\xbdV\xc1\xa9\\\x94Dx\xdf\xc7\xc3\x17\x0f\x16~@C\xb2\xa2\xa8,\x0b\xd7Y\x8aN\xb4Q\xe2\xa7huH\x07\x81\x1fR\xb5\x0c6D!:\xd0\x97\xe6^\x1f\xcb[\xedX8\xcf,\xc6i}\xff\x0f\xed\xfbt\x10\x85\xbf\x918\xf4\xc3%w\x8d\xce\x7f\x8a@\x85\xa8U\x12\xed\xeb\x16\x87\xad\xcbQMe\xc4\x18\xb7\x9a\xd1\x99V\xb9{]$\xa4\xab\xcb\x8e\"7\xf0>\xd0\xc15\x8d\x136\x8dG\x8f8$\xba\xf3l\x1d\xf8\x1eF\x1d\x84h\x01\xff\xc1\xba\x84\xb9\x1fS/\xf5\xaf\x91\xc7\xe2IC\xf2\xa4:\xf9\x9b\xe5\x9a@<\xc6`&@o\x89\x97\x06w\xc0d]\x99\x03\x12\xe3E\xb3A\xb0-\x85w\xe0O~w\xd8\xa17\xeb\xb9g\x03\xf9\xed\xcfO\x06\xf4\x96zN8\x1d\xce\xb8\x17\x1b\xef\xc8\x0f\x82\x8dE\x14\xaf\x98\xa4\"\x1a\x04L\xb0I\xa1>Z\xc6\x8e!\x03\xf96L\x9d\x18\xc3B\xe2^\xf1\xcb\xe5\x9b\xb2\x9c\xcf.*z\xcbB>\x13r\x11\x88\xf6%\xccD\x9f20\x1b\xe7?\xe5\xc3}\x081\x12%\x1dx\x97\xd4\xbbz\xe7\x87\xf4\xc7\x98\x92+\x0c{\xc1v\x90\xec\n\x0d\xdc7\x8b\xaf\x7f\x88^\x93l\xcd8Y:o\xe8\xb4\xb4\xba\xd5\xccb\x07?=\x0c]\xea\xb8\xb2iX\xed\xd3\x83\x9f,\x8b\x9d\xdeDE\xc2O\x06\x988\x07\x08\xf2\xc7\xb8\x0e\x17\x83\x94&\xa9\x13\xa3\xa8][\xda\x94,\x81'o\x01g\xe1\xc7I\x9a7\xe8J \x94\xc6\xc0zI\x84\xeef\x90\x92\xe5{\xb2\xc6\xcb[9\xe2\xc7\xe9%\x8d)\x9a\xbb\xc1:\xa6\xd7~\x94%\xc1\x1d\xcc\xa9\x17\x90\x98\xce!\xc9\x16\x0b\xff\x16\xa9b\xf71\xf4 \x86\x1e<\xee*\xc3x\xec\xf6\xe1\x9c\x0f92\x0fy\x1dS\xd6\x8c\x93P/\n\xe7-\xc6,\x07;\x8dg\xb6xr::\xfa\xd1b'\x89\xb7\x0cy>\xb5\xf2\xba\xa2f\x10^\xe8QA\x18\x93Ib+\xdcH\x11q\x8c\xd1\x81\xf1(\x89\xb8\x83\xad\x8fw\xbfB\xed\x06\x11\xbc\x00\x9f\xfd\xe9\xed\xc3\xc8\x15<\x83C\xb0\x8e'\x8e\xb4\x03\x06PW\xf0~/\xf6y|8\x82|\xcfh\xb4=\x1a\x8d\n`\xd3\xdb5\xf5\xd8\x9e\xb8&\x81?\x87\xbf\x9c\x1c\x1f\x15\x11\x0cuv\x8bhp\xb5\xe2\xab\x96)4\x84-E\x92\xc6\x94\xac\xd0\x16\x89\xf8a\x02a\x14n\xacc?\xe4[=o6\xd1\xb6+n=\xd8\xbc2\xd3\x9ai\x96\xecu\xb1d5\x87M\xbc\x7f\xe1\xeb\xd5\x87\xa0\xdc'B8\x1e\xf8 \x17\xfd\x9cP\xc1@\xa1\xaaY\xd1xIaE\xd6k?\\&\xcf\x11\xdb\xc4\xdd\xd6\x1c\x92(\x8b=*.9\xd8&P\xc9\x1aC\xc3\x8c\xaf\x1e\x13\x16\x1d\xc58\xf6\x8a\xdea\xa2\xb7|A3x\x01\x01\xfb\xc3\x17\x14\x9dd\xa6\xd9,\xdf{)\xda&`r!\x1e\x95 \x9c\x12\xb6\xeb\xf9\x0fU#\xae\x03\xcf;\x05\xa3\xd5t\xaa:P\x05}\xf0\xeax\xcd\xb0\x90\xb3MN\xa4\x9e2y\xc4\x11\xf8\x07\xe6\x83N\xc9r|GV\xc1 \x8a\x97\xfd\xcd\xe1ps\x8c\xf0\x13\xa6\xf3u4gm\xf3\xf4\xd2~\xc2\x99\"\xdf\x96\x958\xe0\xe0\xf4\xf0BL\xc2.\x80\x17\xe0\xb1?\x1cv\x12\x17\xfci0\xd3\x9b\xe4!\xf6\xe6\xd5\xeau\xf09\x1d\xfc\x91\xf0\xbb\x95$\x8f\x82\xcc T\xa7X\x13^\xe0p\xbe\x08\xd8\x1e\xc3\x0c_5\xd6i\x1f2\xfe\xa4`\xb0\xca|\x01\x9dK\x14\x83+z\x87!M\xd2i\x84\x17\x7f\xf9\xadM8\x8dfZ\x01(\xb5.\xfe\xa7V\xb2\x94\x102D\x8aMN\xa3\x14JR\x8c\x1c\xf32\x15?{=&Vl d\x98\x80\xa3>\xea\xe7\xa2\xa6\xb5E\xce\xcb\x15\xaf1\x1e\x9d\x83\x87\x00\x02\x16\x9d\x9e\xd8\xf6\x92\x84\x8aSx|\xd6\xc3\xe4C\ng\x8a\x13\x90\x8dY!\xf37\xd3\xd9]J\xc69\x94\x19\xfflSx.\xb2~GZchqyr\xe8D\xees\xd7\xd4Z\xaf\xa7\xb6\xa7\xdd)\xb8\xdb\xb6\xb8he\x08\xf0?\x8f,\x979mz\xd6\xbe\xfc\x19n.}\xc62\x8c\x86\x05#7\xda*\xbe\x8bb\xc3\xb8;7x\x14\xe12\xd6k t>a\xf2\x90f@\xf7!fx\xc5\xd7\xfbm8\xe7\xe6\xcd\xc3\xe7R\x90e\x0b\xa0>d\x95\x1f<\xed\xcf\xba]\xb6!8\xf4b\xba1G\\e$/\xf8c\xcel\xce\xe9\xc2\xf7|V\xec\xe3S\xe4\xfe\x91k\xb3b\xe5\x1b\xc3~\xed\x8bD\xb3r\xc8ZR\xd0q\xb6wpl\xa6\x8d,2\xe7n\xefr[\x01\x0c\xfd$\x84\x96z]\xe81\x82\xdaTe\x93\x13\xc1\x90m\xc5\xad\xbe\x80MC\xff\x9d['u\x1bd\xc8\xbfke\xc0QNjTf\x81\xeb.R\xcc\xda\xcfc\xce\x15\xcf\xe2AL\xd7\x94\xa4N\xf7\x0c\xcdd`\xa3\x94(K\xd7\xf5\x8f\xda\xae\xafE\\A\x89Q)\xd1X\xe2\xf9\xdck2\xf4.\xaby\xb3A\xa8\xa5u\x99Q2M\xae\x11\xeetQ\x08\x95\xbcM1=\xfe\x831\xb8\xf2;;,\x88\x90 \xda\x11+lk\x9b\x93\x13\xfc~\xebX_Dtp5\x97\xbe\x92\xb9\xed\x0c\xfbP\xa6\xffHbY\xf1\xc6\xc8\xad\xef\x96}\x06c\x99\xbb*\x0b\x82v\xa3\xafu\x9f{.\xf0\x0d\xc2O\xdf\xdf\x04q_\xf0<\x1e\x1d\xcc\xce\xc2\xbb\x92\xc8\xe1\x96\xc7\xd7\xa6\xf3~q\xd8#-\xc8\x8f{1\xa5\x97\"^\x8c\x00\xb0+\xce\xb1\x0b2W\x89\x00\x93Z\x08$\xf4o\x19\x0d=\n4Lcm\x94\x80|b\x15\"\x93ji\xa9$\x01\x9dL\xe0\x08\x13\x9c\xd0W'\xc7\x1dd'\xe8\xe0\xca\x0f\xd1\xaaG\x8e\xa0\xdb/6\xd3>\xe3\x0c\x9b\x18\xca_\xcd4*g1\xf95\xbev\x07T1\x9dMq\x8b\x9f&N\xf3\x11P\xd8\x0f\xe8\xdaQ6\x0c\x9b\xbfI\x03C\x84X\xc9\xafv\x18U\xde\x15\x1cP\x9b\xd3\x82\xf1@\xc8\xcfw\xcc\xdcA\xe5\x851lq.)b\xef\x12%\x01g\xb7\xd3\xe9\xb6o\x85\xbf\xd1\xedC\x99\xd11\x98<\x1b\xd9\x816\xdd\xd5^\xcc\xd9\x00\x85\x0b\xd8\xdd4\x1e\xfd\n\xe5(lF\xd8\xecc\x9d \\\xdaem\x86W\xb0\x89Y\x98K\xb04\x9cK\x9d\x80\x10Do\xfc\xf4\xd2\x0f\x81\xc05\x8d/H\xea\xaf\xd8\xcaW\x15<\xa6p \x82sS\xe6\xdb\xb9\xe5\\\\\xbe\x9al\xaf\x11\x98H \x98,\xa5\xceC\x08\x90B\x10\x06z\xeb\x05d\xc5\x11pE\xe2\xab\xa4\x9b\xa7k\xae\xc0\x82\x1dP%\xf1\xa1\x87\xc9\xed\x84bG\x95QCR\xd1\xe9T\xfaL2\xef\xb2$r\xcb\xcc\xe5U\xf4\xe1\xa4\xbd\x1d\xdc\xeb\x0b\xdd\xbc\x9ew\xb9R\xaa\xd0\x15\x18!\xb5\x08\xa2\x1bF.\xd9v\x8d\xe2\xd2\xf8\xcb\xab\xa6#\x7fx\x90u\xce\xf5\xfd1x5\xc0h\x8c\xf6\x1b\xb1\xcb\x03KH\"\x1a\xc3\xb8\xae\x06\x0b]\xa5F\xaep\ng\xa8\xe6\x1a\xb3]*N\x89\xa2\x16+\x93Ou\x8f\xeb\xf2\xb3\xac\xcf\xb5mY\x98k\xd6\x94UG\xcdZ\x88\x9a\xb5\xc7\x98\xda\xdeJ\xbc\x7f6\x13o\x0dY~\xca\xc9r\xf8\x15d\xd9\xcc\xc8\xe8Is\x08\xa2\x86J\x9e\x0d\x03(af\x15\xab\xe5\xc6\x0d\xc5\xc6\xe5\xa2f\xe7\xc4 \xd9\x0en\xd3\xa2\xf6\x84U\xb6M\xae\x03)\xf6cy\na4\xa7\xb0\xca\x92\x02\xdfH\n\x01%I\x8a\xaa{E\xcbV:\xa6\xed\xbb\xa9a\x81\x7fS\xb4a\x9as\x01\xddqQ\x1b\xb6\xea\xc3\xb2\x0fw}\xb8\xe8\xc3y\x1f\xae\xf8e\x94\xe6\xd0~o8\xcc\xff0\x1c\xe6\xcab\x07~\x92\xd2\x90\xe6\xb2\x12\xff\xe5t\xa35\x0d1\xbfx?\xc7~~}\xa3@A\x16\x08~E\xfe\xcc9\x15^\x80jO\xd8Gc\x88u\xc1\x97-\xf8W\x11q\xad\xca\x88:\xefs~\xb5\xcc\xbe\xc1\x84\x03\x01\xd3_\xa9B\xa6\x90:\xf0\xba\xae\xfa\xf0\x85P\x84\x9d\xa2\xf1\xa5\x8b\x17\x1e\xec\x85\xd3\xfa\x19*N\x14\xe4\xa0\xee\xefq3>w\xcb\xc3\x9b\x14\xa3[q~\xec\xbb\x0c\x12\xc6\xd8\xbcn\xfdV \x832\xbfg\x83\xf4\xf3\x1b\x9cS\xf6`-6\x15\x93\xfa\xce1\"w\x0et/'i\x98\n\x80\x1d+}\xb8*\x1f5\xa5{\xc4\x1cR0\x01\xde+\xca^W\x08\x9c\x87\xdc\xb1\xf4\x0b%ob\x96\xce@X\xee\x98%4\xf6YXBr\xcf-\xcf.%Nj\x9f^[\x9f\xae\xacO\x97\x86\x0d\x08\xc2\x8eF\x97\xa7\xf2\x0b\xe4\xc7\x85PY\xb7\x93\x1f3\xa3\xe7\xbf\xf4Vn\x16'\xfbB`\xe6B\x1b\xa9\xf0\xb4\xbb\\(@\x81f\xe7\xa9\xf8~\x7f\xcfhyl\xb5\x84F\xad\x13\xd2\xc1\xb0\x0f^.\x02\x1auP\xea{\x8a\x80\xd7\xe8F\x880n\x03\xb1C'c\xfb\xdcP\xb5\x81\xbfR?l\x84;\xdc\xde\"s\xe1\xd6\xd4y\x85S\xce9F\xc2X\xf8\x94&k\xe2)\xa7\x8f\xaa[\x05td@\x0e\xfa\x8a\xdemp\xd3\xea\x84\xae \xf7\xf0\xc8\xd9\xe9\x8b \xf2\xae\xa4\xd6\x9a\x1d_(l9x\xd7\xb0\xe8\xc3\xbc\x0f\x97}\xb8\xe6w\x05n\x1f\xf7\xc6\xb5\xa0\xd2\xa2\xe8N\x109\x81\xdc\xc8|\xb2\xbf\x97\xf9\xfe\xc57$\xc1\xb7\xc3\xa5e\xf2+\xa6\x04\x88\x97vF\xe9\xba\x91Q2\xe5'a\x80\x17\xe6\xa0\xce\xba\x19\x17\xf8\x9d\xd8\xb3\xad\xbe\xd0\x83sM\xac.P\xbd\x85\xf2\xb1>G\x9b\x9caX\x1beQ\xf9a\x1d\x8e6wD\x8fC\xde\xe3?\xda8\xf4|\x01[\x15\xbb}0\x80\xa1|\xf2\x0b\xfc_[\x19\xab|\xab\xb1\xbd\xda\x06\xbc\xe2\xbe\xb0.\xbe\xf2\x9b4\x8e\xbb\x97%\xdc\xbdVp\x97\xd1\xdb\x1c\x7falR\x1b\xc7\xe6\xc3d^\xf0\x1f\x9c>\x82\x17\xadV\x04.hzC\xa9P\xf8xQ\x10P.\xc0R\xeeD\xc8H\xa3\xc7\xb6\x95H~\xc9\xc5=\x1f\xef\xd99\x9a\x88\x13a\x0dm//@F*%\xf6\xeb\x8a\xd4\xcdU\x0e\xe5\xeb\x84@\xb9N\xf0\n>%Q(h\xa9\x19\xe3\xc2\x97\x05z\x02\xf9\xe5H!\\ \x8ew\x8d\xe4Xj\x9b\xdb\xe0Qe\x04\xba\xb1/\xca$\x9f\xad1\xd2\xb8\x18\xe9\xbc\x874d\xc1]\x81'\x10\xf3{\x13\xac\xc0\x17A\xa9\xc3*\x89\nI\xb5ga\x1e\xde\nI'\xe0\xcc\x1f0G\xd6-\xd6\x1f\xb5\xd8\xb3\x0fQ\x13W\x90\xb1\xaasd-\x9d\xb3\xd1\xa2\xee\x83 \xd9<\xfdn[R]\x15T\xe7f!\xd5$\xf0y\x96g\x0b\x0c\x8a\xab}\xb4\x86Z\xfe9\xf9\xd1\xe9\x01 \xa7\xa9b\x11I\xf3\"\xba\x82\x87\x7f0\xe1\x16\xb7\x08\xa4\x15\xddntP\x04I\xa6\x95\xab.\x8f\x04$.S\xacnW\x12\\b\xf0deC\xdb\xde\xb2N\xbf.h\x89\x1bU\xe22\xfc\xdcg\xe4k\x82+-\x1a\"\xc8\x7f\x8d1\x80\x17\xc7K~=\xcd\x99\x1b\xef2Z!w\xb3B\x86\x92q-\xfe\xc2\xd7[\xe1A\xb3\xd8\x83b\x80\x83\xc4\x83\xbbI\xa0\xbc\xc8\x93ne\xb9\xb3D&\x9d%6F\xbfF\xf1`\xdf\x18\x11\xbe\x8e5\x0c^\x87\x0e1\xea\x16\xac\xe65m0D?\x0ey\xaf\x86]\x9b\xf9\xfe-\x89Y\xc6!X\xc7\x07_3FP\xc7\xd9\xb9q\x88r\xcf\xad\x19\x90aC*\x1b\xce0P\xc5\x1a\xa8j\xe4\xd37\x8d\xbe\x9d\xf2\xc4\xe9x5Y\xe9\x05;\xe4\x1e=\x92\xd6CDc=\xd4\x06b\xe6%\xebxP5{x \x0bdC\x169{\xc1\x1f\xb8}\xb8A\xd4[\xf7z_\xbc\xd9\xeb\xb3\xb3\xe3C\x82\xf3\xbe\xae\x98\xd3TLf\x02\xf4A\xe9\xc1\x1a\xc6\x8c\xb5\x1e\x8b\xb70\xc4\x88\xcc\xf1\xa8\xd8\xe2\x9c\x85M)\x0f\xecA\xed\xcd\xaa\x0fa\x11=\x01\xb6Q\x18\xc7\xb0\xca\xd9\xb8\x96\x83\xe7Zo\xf9\xe6\xc8\xfa\xe6Z\xf0\x8ccA\xed\xd60\xd1M\x17\x90\xee\xd8\xdaix^\x1e!\xb7\x16\xee\x0c%\xe9\xea\x8b\x83\xbbj\xfe\x05\xd5M\xf8\xdc\xfd\n\\e\x9f\x8fB_\xaaj`;\xa3\xb6\xa4\xd3(@W\x8ek\xc9A=P\xbc\xd53'[\xcf\xbe\xfez\x12\xdar\x0bUi!\xc6\xec\xbd\xfb\x9a\x0b\xc76\xe3\xb1\xb0\x1c[\xdc\xa0\xdf\x9a\xf2\x82\xd5\xfb(8\xf6\xd2\x821\xee\xbe\x01,e\x9e\xa5\x00\x8cE\x17\x18\x97\xe6Y\x85D\x19\n\x863\x0e\xa9\xd7\x8d\x83\xb7\xe6\xf9\xd0#1b4\xf6\xe3\xb2\xc3H\x88_u\xf0\xf2}\x94Kt\xfb\xfb\xfb%\xc3\xdfG\x8f\xb8\xf1\xe4\xc4\xca\xefK\x1f\x9f\x82\xe3O\xfcp\x19P\xf8[\x16\xb1\xaab\xedEBJ\xf3,5\x1b\xe9!b\x86\xbe\xd3o\xb1ST\x01\xc3\xb0k\xb69z\xb4P\xd3}\xfb]\x13\xa29\x85v\xd7\xb4\x18\x8fU3\"|W\xb3|\xd0Z\x8a6t\xabC2!>\xaa\xb16e\x9b-\xf6\xa2\xae\xab\x9bvW4\xae\x8a\xfd\xe6}\x98\xeb53\xee/\xca\x90\xfex\x9a\xcd\xdc\xd2\x01\xf3\x01}G\xd4I\xb6h\x11%\x9c\xd1\xa60\x83\xc3`\x93l/m\xa2+\xf1^.\xcal\xc3\x18\x9e\xee\xe4?\x99\xd80t\xe1%\xfb\xaf\xc5]Y\xc4/\xb4}n\xb4\x1d\xb1\xf7\x9eC\xb4\xb1\xe1b\xef\xaf\xda\xc2\x8a )0\xc1f\x1c\x1f^\xbc\x80m\x17z@r\x91*\xdf\x81\x97\xf4\x96\xcc\xa9\xe7\xafH`wiR?*(\x0f\x1c\xbf\x82/f\xbe\x85\xc3RR\x81\xab0\xba \x81&\x1eY\xd3\xdc\xd8\xd3\xd6u}g\xd8)iVPR\xbe\xf5M\x94\xb4\xde\xf0w\xa2\xa4\xf3(\xbbhCI+\x83i\xc1K<\x84\xb4\xeaG\xa1%\xad\x8a\x1aG\xc95o\x0e\xbd\xc6!\xad\xa7\xaa\xdb\\\x87\xd1|\xf1\xdd\x86\xaa\x1a\x1aie\xee\xc4M\xe0n\x85\xf5[\xe7\xc4\x89\x19\xd9l\xd3b}0\x0f2y\n|\x92<\xc8\xe2Ic\xfc\xd8/\x9b:)*\xf5J8\x16\xd5\x10\xf2q\x16\xe6j\x80\xb9\x18G\xc5(N9\x93T5}8\xab\xde]\xd5\xd9U\x86&_j\x8a\x82ZWO\xea[\xd9IiV\xce\x99/\xba\x19z\xdd:^3b1\x88\x9c8\x1ew\xfb\xe4D\x1a\x85\xde\xad\xa7\xc5\xf7\xedM\xa5|\xab\xf8.\x15}\xf8cW\xad\xf4L\xf9\xae\xd4\xd9\xdaS\xea+\xe5\xcfx\xa8\x07\xcf\x8a\xe5x\xe2\xec*\xdd\x0b\xb5\x99\xc7u\xf4\xb7\xcd\xdbHHg\xf7\xf7\xdc\xbe\x8f\xa1y\x8b\x8d\xd5\xcc\xaeD\xe8K^fw\x85\xd5\xba\xd8`\x9e\x95\x0b\x11\xd6\x19\xd6Dp|A\xbfh\x8a\x16\xe1YI\xaf\xb8\xb5\xd3v\x10\xf6\x01\xa0\xafL\x8b>\x9b\xb4\x12\x8dGM1G\xafY\xfb\xc8\xda\xbc\xc1\x8a\xcdV\x10Y\xaef\x91\xd74\x8a\xf1Y\x90\x17p\x95\x89rrn\x8cjw\xd4\xfb\xf6\x04o\xf2C\x14\xf9\xfd\x8b\xb5U\xe2#S:X+\xda\x839\xab\xc0\xe7\xfe\x1f\xdcx\x80\xd1'u%\xc4\xfduI\xe7\x16|{=\x8e\xbe\x14/\xc08/\xc3\xe9gg$y\x191\xde\x0d\xc8\\\xdb\xe6t\xfbp((\x9fS\xae!\x0c\xcd\x0c\xcb\xd1\xe0\xf2`:\x11\xabC\xedtr2\xc2]\x82\x05\x99Y\x94\xe8\xcb\xba\xaeQ\xe1\xacH_ZQr\xf2\xf7\x87@\xa1\xdc\xd1:\xf7f\xc9\x8d\x0d\xba\x93.\xea\xa6,u\x95\x12q\xb3[\xd8\x81\x15gur\x19e\xc1\x1cmu.\xc95\x05\x12\xdeI\xcbk\xbc\x84\x95\xfe\xde\xad\xaf\xbb\xf3{\xc5Buv\x9a\xcf\n\x8d<\x85\x8dg\xa5i1\xean\xa7[\x14\xe8\x9d\xcd\xba\x93n1S\xab&y\xc9ugw|\xed\x85\x11\xd2\xe9\xdd:OZ\xf7\x1c\x96\xf0\x02\xee\xd8\x1f\xf4\x1f\xb7\xd2\x1c\xe7\xa2\xde\xcet9s\x072\xe0\xbb2u;\x9dPp\xe2b\x90'lW]\xd3\xe4:_\xf0\x1b\xe6/\\\x82o\xbb\x7f\x05\xb1/\xb1t\xe7\xb6`T\x0b\x86N\x19\x13\xbfw\x16\xc7\xdb\x91\xf0\xf0;\x9a\x863\xa9cc\xf4\xf4\x0f\xa1q\xe0\xf44W\x82\x15hZ\xd2<\xfc\xc9\xdcy\x99\x1e\x0c\x15\xd1H\xec\xf7\xc2=\xdfN(\xdaV\xe4\xf1\x1c\xdaW\xdet\xcb\x11]D\x84\x07u\xdc\x0c D\xb3W\x13T\xd0\xadH\\\x8b\xdb\xf2[\xc1\xd3\x8bi\xa2\x9d\xc6Z1N+\x03\xa6N\xa4\x1f=\x82%w\xf0,\xaf\xbd_^{\xc8Cq\x84Q\xb8qp\xf2\xea\xed[%\x9eL\x02$\xa6\xe0\x87)\x8d\xd71E\xc7\x87\x04\xc5\xad<\xe8\x9c\\\xda\xa4\x166\xa0\x85<;\x81\xed\xddf \xbb\x82\x15h\x80\xb0RA\xf1\xa4\xdeP\xa9d]\x1f\x1a\xc5\xa8\x0b\x15\xe8Yxp\x94\xd6\xc3z\x18\xff\xd5\xd1Fa,bAQqv\xa0\xcc\xc3\xce\xc8\xa1\xe4\x17\xf2\xb8v2d\x0c-\x03\xa0\x98\x02\x82@\xc4\x92\xb1Wrhn^\xd0\x87\xdd\x9d\xcd=\x11+U}i(k\xb2r\x8e\x15#\xb7J\xfb\xaeE\xde\xe9\x90\xde4\xdf\xaca\xe6 \\B\xc0DL\xf8[F\xcfds/~\x08\x96G\xd4Id\\\xf6T~\xbd\xbfg27>,\x02Y\xb2\xe7\xc5\xafr\x13\x9c\x13\xc1*\xe2\xeb\xfd=W\xeb\xb3\xa7\x18\xa0\x8a=\x93\x91\xaa\xf2'9\xbb\x86o\xca\x1f\xe5\xb6KB\x8cL\xc2\xcd\x07\x8a\x81\xc0\xfd\x80\xce\xdf\x8a:2\x97 \xe7\xdf\x0d\x95O\xf9\xd3|\xe8\xb8v\x052\x88rE\x171\xccG\x8b\xea\x08\xf5\xa7\xd4H\xa8e\xaa!\x10O\xf7,\xf7'\xf2\x17eB\xcb\x97S\xc3\x04\x86b-\x11\x93\x86\xdd\xaev\xe5\x97s\x93t\xf2\xdc$EZ\x12_3#%$V\x11\x82-\x86\x17\x10\xb1?<\x04[\xea\xf8\xd3xf\xa7-?i7\x9c\xdc\x99\x7f\xd5\xad\x1f\x1b\xb1p\xe8\x96\xd9P4\xfb\x95\xd5\x1a\x89%\x95\xb5$X\xa7C\x8dOA\x91\xc9!r\x8a\x8b\xc3\xfc\x86>\xa7\xa0~\xa8P\xd7>\\d),\xa2\x8c\x9drQL\x1f\x94\xc9\xa1He\xf0K\xbf\x9e\xfa\xe0\xa7\xbe1kA\xd3-D\x8b5E\x94\x89\x07\xf46\xa5\xe1\xdc\xa9\x83\x8fo\xea1\x90\xf2|Xg\x95\xe5\x90\xc8\xf7\x85\x8d\xfdI\xf9\xa9M\xe3`\xa5\xccb6?}\xe9l\xea\xf1\x81\xbf>c\x81.\x98h\xe4\x94B/V\xa7\x81tL\x1c$\xf2l\xb9\xc8\x16\x0bN\xba\xeb$3,\x93\xccX\xfc\xf4\xa2 [\x85\xa5@\xa7\x05\xde))\xd8\x07K\x9a\x9e\x84\xfezM\xd3&\x00\xd7\xcc\xd5\xeb{\xb1\xa3\x0c\xd7U\x95\x06:\xd9\x1bD\x00\xf8m\x85c\xd8\xdb\x11\x11p\xc4\xadKi\xb6\xc2:\x80\x1d\xe7\x1b|?w\xcf\x86g\xf1Y\xf8\x7f\xfe\xb7\x9aU\xa0;\xf0\xc39\xbd=^8\xcah\x90\x8a\x1f\xa4N\xc4\xef/\x0c!\xab\"\xd8@2^\x06\xf2\x06\xf6\x9b\xc2\x13\xd8\xe4\x9c\x87^X\xc3q\xc3`0\x00\x1c|o\x1fv\xf4RJ\x1bw3\x04\x91/ A\xea\x90 \xf0B\xc5\x0d\x85\xbd\xfab\xd0\x10#X\x1c\"\xc8\xf8F\x052-\xa0\xe2\xabP!\x0c\xbe_\x01\x15\x81Q\x99\x84\x87\x98\x00\xe7\xea\"\xee\x8aX\x98R\x02\xaa\xa1\x84\xe4\x95\xa1\x01x\x8f\x07\xcc\xefUkAO\xb3\xe6=\xe5\xbc\xe8A\xf7\xf7\xaeJ\xa0\xd4=\x94F\x9c\xfb\xb5\xe6\xe6UB\xf6u\xbb\xda3\xbe\xd8\xfa\x8caE\x0e\xe2\xb1\x1fr\xe1\xb1x\x86\xd1\x92\x1f\xe3U9\xe3XH\xca%\x186)\xa7\xa0\x04(\xd7\xf5\xd8\xdc\x04%(\x9e\x8b\x02~\x05\x82;\x10\x85r|VP\x03G\xa8\xa8x/c\x0e5\xd4]j\xc9tNi\xbe\x92h\x8ev\x953Em\x9d\x9d\xc6\xb1\xa3 \x87\x93\xa4q\xb7_\x81\xf5\x95\x1f\xce\xc7\xc5}n\xe9Y\xae\x90\x1d7\x98w\xd4t\x9e\x98D\xa2\x94\x8b\x00\xca\x07\xbb\xfb/\x82\x00\xfd\x9b\x11\x02\xb9c\xde\xb7\x85A\x95\xb9\xfe\x97\xc3`E\xd6&\x18\xe4\x8e\xb6\xdf\x16\x04\x15\xd7\xd0\x7f=\x08\xd8\x08\x1f\xb4\x13\xc4\xedA\x13\x00|\x19\xbe\x07Ek\xabm\xf0u\x9e\x8cR\xc8\x01&h\xca\x98\x9d\x8f\x1eA\xf7\x7f\xc4\xcd\x1d\xf2\x02E\xb9\xd3\xc5 \x15\xcf\xbaG\xd5\xdf\x9f\xde\xbd\x13\xbf+\xbcv\xf3R7\xac\xb4\xad\xb9uL1\x10Y#\xe0T\xcc\xc1Q\xdaZ\x8d\xe9:\xa6 \x0d\xd3\xb1\xa6%\x8f\x84Q\xe8{$h\x98\x01\x14\xbdv\xffG\x93J\xb3~5\x12D74\xf6HB\x1f\xd02\xaeK\x9b\xc6\xb3\xf5\xfa\xc1\x8d\xe3\xa2\xb6i\xdc#+\x1a<\xb4q\xfd\xc8m\xeb2\xa7\x0b\x92\x05\xe9Iz\x17\xd01tsxu\xff\xe5\xfb\xfd\"\x8a\xfe\xa9\xfb]c?\xd5z\xbf\x97\xf6u\x1agT\xdd\xc7\xa7\xd5\xdf\x1f?\x1d\xca}\xcd\nv\xd4\x97\x17$HJ\xb5\xdf\xd4\n\x0e\xde\x9d\x1c~)]\xb0m\xe4\x87\x0c\xfc[\x12\x90\xeeT\xa4\x13\xf81\x8a\x02J\xc2\x19\xef\xa3\x96\x9cN\xb2\xa12\x03\xed\x17\x93\x1b\x1dQ0&\xc8\x95\xf6\xa00\x91\x00\x1a\x83X\xa56\xdbXG#Z\xf5\xc5\x81=\x96\xeb\xdd\xa6/\x1d\xc9h\xd7\x97\x9c\xd7\x1b\xc3\xbc\xfe\x1d(\x88)C\xe2\xee\x03\x93\x9c\xd6\xb2\xa7\xed\x14\x03\xd54D\xda7\xb4\xa74$\xbfUI]\xa4#u~\x98\xfe;P:\xae\xb4Q5\xd8Z\xcc\x89\xccn\xf5\xba\xa8\xde \x95'q\xa3ylw\x83\x1bB\xf1[\xd4i4C\x19\xad\xdb\x13y\xdesY\x8eN{\xbdh\xe6\xf6\xa1;\x14\x99\xfe\x8d\xe29j=z\x82!\x8b\x1b=\xbfp\x14\x17\xbcQ\xb5+S\xfb\x90\xbby\xf4z\xa4\x9fb\xe6\xb7\x959\x8ev\xddA\x1a}b\x02\xe9+\x92PG@\xa2\xb1\x9a\x0526\x1c\xab\xc8\x85b*\x15I&aO\x0f\x02\x9f$4\xb1\xe1\xe2t\xb3\x0f\xdd\x0b?\xecjR \xe4\x98>\xedC7\xf2R]\x95\x1c\x8e\xd3\xd1\x10\x13Uy\xbaZ%\x88OG\xbb}\xe8^\xd2\xdb\xee\xf7\xbd\x0b0\x8b\xb5\xe5b_\x08\x90\x1f\xe9\xf2\xf0v\xedt\x7fw&\xe3\xe9Fo6q&\xe3\xe1\xfdt\xb4\xf1l\xc6\x8e\xd8\xf3\xd9\x0f\xae3\x19\x9f\x9d\x0d\xe4/VaJ\x0fgXY\xa4\xc4\x9d\xdc\xe7\x15z\xda\xc7\xc5/\xd1\x8c3\x19\x97\x0f\xf2\xa2\x07^\xf9\xecl\xe0L\xc6~\xb8\xb8\x7f\xcb\xfe\x1d\xbdq\xefyQH\xc2\xfb#rt\x7ftp\xe4\xba\x7fV-\xef1.?&\xedU:\xa7O\xcczB\xad\xf0\xbc\x08\"\xf2]\xc4gU\xbf\xcdoF\x18\xa5u:\xbe\xe0`\\\x95\xf9\xa1S\xd5zo\xf6\xcdy\x1am@\x189B\xd8\x07\xc9G\x08\x03\xe4\x1a;2H\xa3w\xd1\x8d\xdc\xd2\x8c\x97\x80 ;\xc8\xc7 b\x00Og}\xe8\xf66\x94+tdX^\x8a\x13\x86\xdf\xa1\x16\xccH\x1fX\xcdE\xc1{\x08\x0b$\x98\x88\xc3l\xf0\xe1\xf8\xe4\xed\xe9\xdb_\x0f\xcf\xdf\x1e\xbdy{\xf4\xf6\xf4\xaf0\x96\x8f\x8e\x0e\x7f:\xa8>\xea\x0eB\x12\x16\xcd\x1d\x91#\x18CZf1\x04is\xd2/\xe33\xa22\x9f\xf1\x86!\x8e\x95\xd3\x10\xb6w1\xe74\xa2\x07t\x95JN#f\xaf\x9b9\x8d\x10~`|\xf3\x18\xbf(\xa3J\xff\x9dx\x0d\x873\x1b\x9d}\xee\x8d\xa1\xe15\xda2\x1b%Bi\xc2\xf8P\xaf\x1c\xf2\x93#r\xc4\xfa\x82\xe4\xc6O\xbdKp\x8c\xca\x03\x8f$T\xd5D\x8e\xb5\xb5@\x01\x0e\"\x9f^<\xe2\x8d\xe5z\xdc6\x8d\x1d\x1d\x1cY\x1b\xcb\x15\xb5\xad\x1a#G\x1a\x8dl\xe1\xf8l\xdcnB\xeb\xf7=\xa0\xc5v\xfe7\x83\xd6\xdb\xa37\xdf\x0eZo\xc3E\x1bh\xd5)\xd0\xf7\x83\xd6\xc67\x05\xd7\xc67\x85\xd7F#\xc0t\xbb\xbdx}8\x18j\xc6\xa2\x9cKe\xbe\xb7\x0f$\xcf\xe95\x810?\xa6\xba\xb4\xcb\x0e\x14\x1e\x083\xb4\x11\x93\x7f\xd6mC\x8d\xff\x8aj\xfcW\xce\x1e)\xff\xb9\x1b\x8e\xe9\xc7\x9f\xbb\x8d\x1c]c\x8b\x93\xca/\xc6\xbb\x9d\xa6\xb3\xfb)\x9c\x9d\xa5\xb3\x9e[z8V{/\xfd\xe0\x0c\"/\xf9\xc1\xe5\x1c\"\xb6\xf0\x83\xf3\xdf\xf7\x0ec\xc6\xdcj7\xa5\xf7\xdd\x89\xebNJ\xac\\\xab\x1b\xdd\xd4_\xd1$%+\xa3)\xcb7\xe7\xd6\x8a\xb0\xe5\xd1\x80\xdeRO0my\xa9/K\xbf\x03\xbf\xa6\x89\x87b\xb85Y\x0b\xf7L\xfd\xb9\x97\xdf\xe0 \x0b\x96\xcf\xc3\xcd\xb9\xb2b\x12j\x9erW1\xf3>\x8c\xe3(v\xba\xafIJs\x9fZ\xca\xcat\xc1\x99|\x91W\xb4\x97NG3\xce\xfc\xf4\xd2\xe9\xe6\x8c{-\x11\xfesk\xd6\x87N:\xdd\x9e\x15f\xb0\xf4\x06X\x07\x0e\xfbo\xf0\xe9\xf4\x95#\xc0\xa0\xf3\xc3\xf3E\x98\x8a\x1ek\x82G\xa9\xe8\xa5\xd3\x9d\x19\x8fO\xd1K\xa7\xbb\xb3>\xa4\xd3\xbd\x99\x89\n\xa3\xca\x15\x03\xdfN\xf7f\x82+\x1d\xf6a\xcb}\x0e\x8b\xc2\xa7r\xeb\xb9\x0b\x0b4\xf0\xd3Q)l\x87u\xb7\xa8\xd3?\x13z\xa5\xd3g3\x04<[\xb3]\xba\x0d?\x80\xb3;\x84\x1f\x10Z\xc3\x19\xf4\xa0\xe7\xa4\xd3\xd1h\xc6\xd0l(\x95\x80\xb8 \xea\x9b\x1bkW\xc4g0\x82M\xc1\x9e\x85\x8bQ\xd5\x1f=\x02o\x90\xd0\xf4\xd4_Q\xc7\x1b,\xc57\x1760\x88\xa6gCa?LR\x12z\xf4x1\xc6\xeeZph\x96M\xc6\x88\xfa\xdb\x93cA\xd7\x8d\x8e\x00\xdf\x8a\x10?\x90\xcc\xf0\x04\xfc\xdf\x8f\xc4t_\xbcP\xac\"L\xe6O\xdf\x0e\x0c\xc5\xcf4\xbe\xab\x0c\x8b\xc3hg\xdb\x1d\xfc\x88\xb6\xc2E\xaf\xe0\x11dd\xd8L>\x97\x1a\xb4(\x18\xba\x07?\xbez}\xf8\xe6\xa7\x9f\xdf\xfe\xe5\x97w\xef\x8f\x8e?\xfc\xd7\xc7\x93\xd3O\xbf\xfe\xf6\xbf\xfe\xfa\xdf\xe4\xc2\x9b\xd3\xc5\xf2\xd2\xff\xe3*X\x85\xd1\xfaoq\x92f\xd77\xb7w\x7f\x1f\x8e6\xb7\xb6wv\xf7\x9e>\xeb=\xd9?\x0b\xcf\xe2\xee\x03%x\xae\xe4\xf9\x1e+\xf6\xc57\xe0\x06J\x1d5^\x8e3\xfa\xe8\x1b\xae\x88B\x1e\x030\xe4\xbeC\xa1\xed\x9e\xa8\xe3 i'\xb9\xfcK\xa5\x19;\x8f\x06\x08\xbb\xdb\x8d7G)\xbc\x80a\xab\xdb\x1f\xd4\x8b\xefj\x1f\x1b)a\x0c\xff\x01OQ\x01]\xc6\xfb\xaf>:\xa3\xb2\x02cz\x16\x9f\x85\xfb3\xa1\xc60\x03=\xb2.K\x86\x91\x80\xb4\x8f\x12\xf3r\x07\x86;\xa1\xdc\xd3{\xf8\x1c\x18\x94\xc9sH{=\x17R\xf8\x0f4\x05\xe3*\x13~\xa5\x13\x88L\x11\xf0\xf2%\x8cv\xe1\x11l\xee\xec\xb8}P\x8b\x9fVK7wv\xe0\x11$\x8c\xec'\x98\x0e\xe4\xc5\x0b\xd8\x85{\xc8rt\x88$:\xa4\xba\xe3U,\xd1\x10dH\\\x82\x03\xfb\x01v\xf1\x9a\xe6\xab\x86\x04c\x18=\xcdu=\xe5\xb6\x86\xda\xb66E)\xbe*|\x0f\x19h\xd4:\xdb\xf9\x9b1\xa6\xdfX\xc4\xd1*\xff\xe2\x04(\x16 \xbd\xc7\xaf\xdf\xd4~\x15C|0)\x87S\xd0\xf67'm\x11:\xe6n.F\x82b@>\xd2Hk2\x0b\xad1`\xe7V\x05;q\xe7g\xd3\x08\x97\x8f-\xfa\xee\x16\xf2|J\xe9\xa6\xaet\xb7R\xb8\xbb\x05\x8f\x00Mr\xd8\x8c\x9c\x88a\xecS\x17z@\xa7\xa9\xf9R\xb5\x8c\xa0[\xfc\x0e\xf1\x1b\x8f\x08\xc6\xb0Y\xa0k\xa9\x9d\xa1\xae\x9d\xedZ\xe1\x8b\x17P\xedqw\x1b\x1b\x1e\x15\xc8\\j\xb9>\xc0\x17/j\x0d\xefn\x97\xdb\xebC\\F\xbc\xfc\xd7Ws\x10f\x89\xb6\xa6\xff+\x87\x9c\xacs\x08F\x85\xe1\x03\x99\xb4\xc8\xe2\xd1`\xf0\xea\xf8\xca3\xdfd\xcf_\x91\xd7\xb8*\xdcx\x1cP\xdb~\xe3\x97\xd2A\xee%\xccv_\xf8\x9c+\x83\xcd\x1ed\"uh0MgE>\xb0\\]\xcb\x01>\xeb\ny\x15\xd5\xb2q\xb3Q\x87\x88\x89\xe3\x87\x10\xdb\xadx\"\xd1$Jj\x16\x8eB\xd6\xcf\x1a\xbb\x96\x9f/\xb2\xd6A\xe6\xa7\xb9\x0fVM\x98!$\xf9\xa1H\x9a\xc1\"\"[\xb4\xca\xdf\x91#Ny[~!\x83S\xd7O\xfc\xb3\\\x8dZ\xec\xfa/\xdc\xc4k\xe2\xc7\xc9\xbf\xd7.\x16\xbe\xbb\x96\x9dJ\xc4\x8c\x0e\xe2\x98\xdc9\x99t\x81\xcco{\xd8\x16\xce\xbel\x0bg\xb8\x85\xf5[7j\xbdu}\xf4\xe7G\xc3!\x85\xe2^\xd1\xbb\x84\xbd]u\xf17\xb5B\xa6\xe9\x8c\xd12\x7f:d\xe7\x0c\xfe\x9d\xcd\xfe\xe9hoXG\x1dW}]\x0d{&R\xd1\x18\xd6\xd1/\xad#\xd1\xae#1\xad#[-\x82\xab\x15\xd5@\xdc\x07_\xc0.\x12\xb0\x8b\x10vF6\xc6\xff7\xd8\xc1\xe5s\xfb\x81\xfb8\xa1\xc6\x0bt\xbdw\xe1\xf7\xdb\xc4\xd6#\xd6\x0f\xc1\x10\x08L9\xc9\xc2\xbe\xb0D\xccIm8Mg\xd6\xfd\xf2mQ\xdeD\xe9\xff\xed<*\xffH\x9ed\xe1\x9c.\xfc\x90\xce\xbfR\xfbb\x81\xc3\xc3\xa1\xea\xd6\xf2\xcd?T\xa6\xbb\x8e\xfc\xb9\x8c/f\xeb]'\xcd\xd94\x7f\xffn\xae\xd1\x7f$Ob\xba\xa4\xb7\xdf\xe5F\xe5\x01\xca3\x1f\x03\xd5`\xbd6\xe7S\xeeW\xa7\xe7\xb3\x19\x11xr\xf6\xc4\x99.\xfd\xd5\xec\x07\xf7\xcfO\xe4\x05\x87\xbez\xac 9\x00\xd2z\xfa\x89\xd4\xbe\x0f\x8dw \xfc\xc2C\x9a\xf2\x86\xd3\x11\xcab\xf2\x16\xe1%\x93K[\x9c\xd8\xac'4\xeb\x9d\xa6\x85!P\\\xb2 *\x9a\xa9\xb5\xf2\xbd\x8f\xe1\x7f\x0e\xc4\xe56Q\x80\xceo\xe1\xaa\xd0-\x19\x13\xf5\xc1\x001\xbc\xd0*.H\xd3~U\x96\xf9J*\x913j\xbc\x83\xb6&1\x0f%(\xd6\x05a\xb0\xea\x01\x1d$Q\x16{\x14z\xac\xc0\x08X:X\x06\xd1\x05 \xc4\xd5_o\x1f\xbaK\x1e\xb9\xaf\xc8D_\x11\xf5\x9fV\xca3\x9b\xd2\xaf\\5i\xd6.\x94_\x08`\x1f\x9eU\xc8 \xec\xc3\xa8r\xad\xb5\x80}\xd8\xda\xac`\x03+\xdb*\x97\xcdY\xd9v\xb9\xec\x92\x95\xed\x94\xcb\xaeY\xd9^\xb9l\xc5\xca\x9e\x96\xcb\x96\xac\xac2\xbe;\xd8\x87\xed\xcaX.XY\xa5\xdfsVV\xe9\xf7\x06\xf6a\xa7\xd2\xc7!\xec\xc3n\xa5\xbd[VV\x99\xdb +\xab\xf4\xf1\x8a\x81\xaf\xe2\x93x\xc5\xca*\xef\x1e\xb0\xb2\xddr\xd91\xe6/\xacT\xfc\x80\x85\x95^N\xb1\xb02\x95\xf7\xb0\xafA\xfa\xe1\x18\xbaggC\xcdQ\xb4\x87O\x88\xe6\xc9S|r\xa1y\xf2\x0c\x9f\xa4\x9a'#\xdeQ\xa8{4\xc2G\xd7\xbaG\x9b\xf8h\xa1{\xb4\x85\x8f\xaa\x0c\x1d\xfbl\xf2\xa1Wu\xd1\xec\xb3\xb5=\x86\xc7gg\xdd\xc7\x9a\xb1\xf3\xbe\xce\xce\xb4\x9d\xf1\xde\x8et\xcfv\xf9\xd4\xceu\x90\xda\xdc\xe2\xad\xbe\xd3?\xe4\xad~\xa8(\x1a\xcaU\xdf\xb2\xf3\xba{\xd7\xedC\xf7\xaf\xec\xbf;\x9a\xe0w\xf1\xe7\xf0\x84\xfdA\xb6\xb7{\xcc\xff?b\xff\xe3W\xfe-\xc2\xaf\xfc\xffc\xac\xbdX`E\xf1\xe7\xcd\x9b\xeeL\x17U\xe3\x8f:\x9d,\xb4\xb6\x95\xabhn\x82\xb2ou-\xeb\xf3\xc8\x19\x9b;;.\xe7\x85n\xbb<\x80\xeff\xb9\xad\xdc\x1a\x19\xab\xef\xee\xecl\xc9\x172\xf1\xc2\xb6\xe6\x05=\xd7\xde\xe1\x8dlo>\xdb~\xb6\xbb\xb7\xf9l\xc7u\xcb\x11q\xbdhNa\x1d\xf9\xa5\x8c\xb9<\x00\xe2\x8a\xdc\xc9L\x0c\xcb\x98\x92\x94\xc6<\x19\xc3\xf0\xf6\x8d\xf8\xe8X\x07\x1c\xe8'1\xd0\xa7\xe5\x95-\xfd\x92\x87\xde\xd9YW\x84u,\xe28\x0e\xf1\xfd\x8d\\Vv\xa1\xa7\x08p\xba\xc8%G\xf5\xc5R\xa2X\xf3x\xe1y\x98n_\x06\xc9\x961\xa7\xdf\x93\xf4r\xb0\"\xb7\x0e\xa6\x0c\x17\xc5\xf7\xf7\xb0\xe9\xcah\xdfW\xfe\xfamxM\x02\x7f\xce\xdbR~\xab\xa1\xb9\x17At\xf3\x8e^\xd3\x00\x99X?9\x8a\x18L\x97\x0e-\x9e\xb8\xd2\x17I)\x93\xbd\xa4w\x81\x08\xc1]:YMLu=%p\x93Ym\xe1\xdb\xff\x8f\xcf\x06\xcds(\x12\xa2pk\x0d\x9e\x845\xae\xdc\x1b\xa4\xf9\xd5\x0c\x8f\x04\xe0?\xe7ARG\x90\x89\x86X?\xac=\x91\xe4!\x18\xa8>\x97}\xc8xg\x19^\\\xab\x8f\xa6\x19\x1b_8%3\xd8\xaf\x06\xc3\x05E\xcd]\xc6gGA1\x868\xd8b\"\x0d%s\xdc\x89\xe2\xf4\x17z\xc7\xb3\xcf\xe4?\xca\x01\xddC\xfa\x9b?\x97\x01\xd5\xf3_\xf7\xf7\xf0T\x86C\x0f\xa3\x8ft\xc1\xdb\x10_\xd5\x16\xc2\xe8U\xb4Z\x93\xf4=\xdb\xce\xbc\x8eR\xa0\xd6\xf4\"\x86\xdd\xe8zu#@\xa9\x14\xa85\xbf \x84\xbcLOd{\xe5\xf0\xb6\x1cu\x1e\xd3`\x85E\xe4\xfaR\xb6F,\x99g\xec\x0d\x92Ra\xaf\xc0K\xb3\x84\xce_\xabOJ\xb1\xfet4\xe2\xa3v3!\xd2\x8b\xdd\x14\xc1~%\x9al\xea\x8at\xc6\xfc~nc\xc4\xf1\x9a\x8d-Q\x83\xa5\x81\x0f/ y\xeeb\xda\x064`\x97\xd9\xfa\x85K\x1f;\xfb\xc1w\xd1\xec\x87\xfb\x8a\x88\xac\x16\xa2\x83\x04\xb3\xbd\x95\x9e\xb0.ydW\x1f\xad\x86\xf8\xf7P\xd5C\x9c Q0\x14x\xdd\xdb\x87\xc8eC\xec\xedW]\xcb\x04\ngV\x10\xbd\xb6\x85\xe3\xd6\x87\xdb\x95\xe4\xf2\x07H]k\xdb\xef\xea$Z\xca\x1c\x08\xb1\x05\xc3>\xfe\xd5\xbe\x8e\x9f\x8c\x0dmm\x96\xa3T\x8d6wQ~\xdf\x1dU\xc3`m>\xdba\xbf\x18\x87RxP0\x96D\xfc\xba\xbf\x87\x9d\xbd\xad\xed\xed\xf2{\xec0\xdeb\xbfx~\x8a\xbc*+\xdf\xadt=\x1am\x8fF#\xebD\xfef\x9c\x08N\xb1\xd2\x0f\xb6\xcc\xbe^\x14__\x15_\xaf\x8a\xaf\xc7\xc5\xd7\xd3\xe2\xebM\xf1\xf5\xd2:\xac7\xc6a=\xf9\xfd,\xfc\x01dT\x13u\xb9\xe57\xb6\x91\xfe^\x0f<\xf2#cs\xcaE\xbf2Y\xa5\\\xf43\xe3m\xcaE\xbf\x01\x06\x99\xae\x0f\xf2/\xf6\xd0\xebl\x1c\xbej\xe7\xd4\xd1\x84B \x0c\xe5\x0b\xdc\xe9<\xeeG\xfd\xe9{N\x07j\xe5\x8cS\xfd$\x12\x92\x96r\x96TV\x12\x83\xf3t\xde9\xfc0\xca\xb0\xec\xbc\xf8z[|\xbd)\xbe^\x14__\x15_\xaf\x8a\xaf\xc7\xc5\xd7\xd3\xe2\xebe\xf1uU|\xbd+\xbe\xae\x8b\xaf\x1f\x8a\xaf\x87\xc5\xd7e\xf1u^|\xbd.\xbe\x9e\x14_\x0f\xc4\xcc\xcc\x89^49\x1f\xd2\xbaJ(7y\x18r\xba\xaaP\xd9^\xcfv\xb3\xd5\xf9$\xc8\xae\xd2\xbf\xafD\x05\xfaM\xaf\x04f+\xf7\x96\x8d\xfdoZc)\x13\x83\xfd\xc5\xc3\xd4\x0e\x12 \x9f\xe7rd\x1d\xf6a\x01hQ\xcdX\x15\xe4Ya\x03\xde\xe3\xe9\xf2\x92[\xf1vA$\xd2\x9c\xbeg'\xc3\xac\x8f\x88\xe9\x1b\xf4\xdc\xb9P\xc1@\xf4\xb5\x00\xd1n$\x1c%\x0e\xbaq\xa8\x7f2\xb7&\xc6\x85\xdcM\x00\x13\x08\xe1%<\x83\"\xed\xd2o0\xc6\xf2\x9fa\x0c\xbf\xc2\x98\x8f\xb2\x13\xf1\x87\x7f\x871\xfch%m\x7fU\xa8Fu\x85\xe8`\x9e\xadJ\xbc\xb7\xe9.\x84\xdf\xfe\xa6\xd5\xdb\xdf\xee\xe3\xc7\x86\x9b\xd9N\x85!\xe3\xa1\xfd\x19H\xde\x16!\x08\x14W\xd3\xc7\x18\xa0\x1dz\xec\x9b\xfeF\xd9\xcf\xb9\x0b;\xe9\x94\xfc\x17'\xed\xf3$\xc6\xbeH\xdeL\x14\x85\xa3\xd1eY\x80\xb0Q~\x92\x1f)G\xe97\x02\x94\xdcYd\xc0H}\xa6\xd9\x90\x87D\xe3\xd9\x82\xccv\xa8 p\xa2\x9ah6\x9c\xe5\x19H\x15T0\xc5n\x04\xeb\xbd\x0d@\x9e$\xa9\xbe{\x8d\x96\xaf\xe8Q\xfd\xf7F?jM\x06{\x90o\xff\xd8\xf8\xb6\xc0\xed\xc2\xe7\xe51z\xbb<~\xdcuM\xf8\x0e\xb2\xf5_\x9b[\xbfg\xad\xff\xc2\xf3\x04r\xbca\xcd\xfe\xe4|dE\xbe)M\"\xb6\xfess\xeb/\x8d\xad\xb7\xc67(\xcb\xee\xb0\x0fO\x9c\xb3\xb0\xe7:\xd3\xdf\xcf\xc2\xd9\x0f\xee\x93\xa5~W\xa9\x1f\x94\xc9\xb3\x9a|\xe1r\xd9DP\x96\x0c&\x90\xa1\x9aA\xb8U@4\x08H\x92\xbeeo\xf0\xfc\xe0\x7f\xce#\xd3\x0d\xfb\x98\x7f;u\x0d{Z\xfd\xa0\xa8~\x16\xcaP0Ct\xffd$^\xfe6c,\x88\xc9k$l\xf5#b\x0c\xc6\xaa\x0b\xb01\xc1\xa7\xfaam'\xc0\xc3\xbc5O\x04\xc4\xc9\x15O7\x1b\xc6\x0cyJ\x18>\xcb\x00o\x80|\xb6\xd3\x13\xe81Y\x0f\x13\xdc38\x88\n0a_\xc7<\x9f\x1d\xf4\xe0\xcfN\xc0\x85I\xbc\xb5\xb0vf\x8ey \x05*\xfa\xc6J\x9f\x19z\x12\xb7 \xdb\x7fk\xc4\xf6\xc7\x98\xac\xa4\xf9~O~rA\xba\xe0\xca\x85\xa4l\xe4\x91\x84\xce\xb4\xc2\x08\xbd\xe4\x02\xda.\xa0\xe7\x0e\x13\xd7v\xb7F\xc8\x04\xd4\x83\x95\xfa(\x15\xf3wv\xb76\x87PD.\xdd\xda\xdeb\xc26*\xa6\xfepF\xc3Mt`Na\x83\xb7\xce\x93\xc9l\x88\xd7z\\\x86c`c\xbc\xdb\x98\xeb\xbc\xde\x0b\xab\xd9\xde>t\x90\x93\xf9\xe4`Zh:\xf5g0\xe6\xa7\xdc\x1fz\xb74\xf5#\xafSmk\xe6\xf2\x8c\xa2\xfa\x86D \x08\xf3\x92\x95t\xba\xfej\x1d%\x89\x7f\x11\x08\xc7\xf71\xf8BU\xc9\x8d@x \xb2n\x13c\xf7\xd9\xb1\xcb\xf3\xbf\x983K\xc1\xbe\xe4\xd7\xa4\x02\x10\xe3\xafin\x01\xe221)\xc5\x95\xd2\xea/B\xb6\xdfx\x8em\xfd{\x9b\x9c\x1e\xe5\xcf\xd8(\xba\xbd..\x97\xdc\x94\x1b\xfc\xb09\x0b\xbb\xd6\x19\xfed\x14\x84MCf\xb8Q\x90\xd4\x8d\x11\xa6\xf7\xb4\xf6\xf1g-\x14\xd1\x1aAq\xbcV\xc9k\xce\x1bTl\x87UE\x96\xe2CY+:\xae2\x90\x85*\x9d\xc0\x0b\x08\xd8\x1f=\x07\x89\xa2\xa3\xe31)oJf\xee\xa0\x88s\xc0P\xc4\x1b\xe4\xf6\x06\\\xcb\xdd\xf1*5\xba\xdc\xbc\x80aR\x9e9\x90\xd3XY/Z\x80\xfaR\xdeN\xder\xa5#F\xfal\x82.\x95\xea]\x98\x80\x87\xdf\xc7\xd0\x9dt\xfb\xe0\x0dr\xbb\x04\xdb\xb1\xc2\xdaXp\x95\xa8\xb8\x1a\x99b33>\x0e5>N\xdfh>\x91\xf1\xbb\x00\xb5K\xee\x13\xa1\x94\xb03sa\xa1\xe2\x06\x0d\x80\xfaA9/\xa9\xf5\x85\x11-\xca\xf4\x99'\xe8\xf7D\x82\xfe\xc7/1k\xbf\xe0\xfdc \x9eG\xd7i\x82Wo\xfc\x04\xe6i\xc2\x10\x02\x8f\x9bN\x9a\xf2\xb4\xa6\x8b\x19\x9f\x99\xf9\xe41OY\x8a\xc3\xb1\xb6\x8a5\xfe\xb4\xc6&K+\xe6w\xec\xfa\xd1\xffU\xd2\xf1\xf1M_\x95\xd9\xd5\xfb\x83|\xc8a\x9fo\xe5\xb0\x0f\x9d\x11F\xc1\xc9\x7f\x0e5\xd9\x82\x13\xc8\xb1\x847Q\xcd\xdb\x9a\x13?U\xa4}\xc1#\xc4\x95\xa5\xdcjVS\xd6|\xd0\x87E\x1f\xed?\xea\xdeR\x0cAQ\xd9\x91?B\x17\x1f\xf9\xa4\xae.C\x85\x9d\xa3h(\xc5\x8dXqI\x92\xcb\x04\xa1\x8b7f\x85o\x06\x02\xeb\xd1#\xb6\x05\x95\x02T\xdb\xdc\xdf\x83P\x84K\xa5\x02\x12\x86\x97 R.\xfb\xa8*u\x85Z\x8aVn_\xa6\xc1\xcc-\xa0\xdf\xfd!\xa6\x8bs\x86\xe3\x15\xf1\xderQ\x8d\xd3\xc2\xb6;\x9a\xc6q\x08\xba\xf2}\x9eR\xdc\x00W\x97\xaf\x1c\xcf*\xab\xde_\x8aU\x96\xc7\xcd\x04\x9cN\xcd\x96I\xa3!\x92\x9f\xb2r\xb9\xaf.\xb0\xc5\xa2\x95\xdf\x1c\xa7\xc4\"\xe0]V\xeeYM\xb9\xf1\x91\xd6H\x1f\x04y\xa5\xe8\xc2%~w\x9aT\x80J\x0e\xd9\xe2$\xd0\xb4\xa3\x145\xb4\xa8\xbe\\\"u\xf9u\xe7*K\xd0\x92\x80\xc0\x05O|\xc3\x13\x98\xdb\x8c\x10\xa1\xa4b\xe5,\xc4e\xe9\xbe\x8d<\xe72\xd8\xc8E\x95=\x135\xc4\x823\xc8\xf8\x0c\xa9\x1d\x0c\x89$\xae\xb5D\x88\x89p\xca\x18\x9c\xcb\xa9?\x9b\xf5\x05\x8d\xe1\x96\x80\x19O\xcb\xce\xffq\xbc\xc7\xdd\xd5b\x07 \xe4\xc7\xbd\xc1\xbe\x15\x1e\x15L\xf0\x90\x89\xe0e\x1dO,\x1d\xd6,\xe77\x9f\x88 N\x13\xc6\xa8\x8a\xaf\xd0\xc5\x8d\xd7\x93\xaf0\x0e\x83S\x81\xd2\xdc\xd4\xa9$|\x1a\xc1\x17\xf4<.z\x1eC\x97\xe1uo_\xed\xdd$\xedHZk\xa2\xee\x89}&g\xe4K\xda\xe2\x14t\xe4QNG\x90\xc9\xe3\x9d3\xd9\xac\xbe[m[\xb5b#\x914\xec\xd3\xa0y\x9fz-\xf7i5\xa7\xb6\x97\xa3o%\xa7vV\xbf\x8a\x9f\xa0\x00\x8eR\x93\xa0`\xfc\x18\xc2\xbb\xddn\x1fq\x02\x95 S\xb6?\xbci\\`3N\xb63\xe2\x87_\x01\xd22N*\x8dq\x04\xcb\x8a%f2\x96q8\xc8x\xa3eF\xbd\x0e\x17\xaf\xb099\x14R\x1e\n\xb2\xe6Y{lR\x8f\xf5\xee?X\xaf \xeb\xbf\x11\xa3\x9a\xd0\xa9\x0b]\x05\xa9\xeac(\xa8\xa5\xf6`.\x1d-e\xf0~\xc9iRx\x00\xdb03\x93\x98i\xc16\xc5l'4\xd9\xe8\xa8\x84\"D[\x1d\x95\xe4)$4B\x12J\xcad\xa6%1\xc1\xb7\xba\x1b\x0c!\xc4W\x9e5\xb8Xy\xfb\xc2g\xca\xc2\x13\xce!\xcd\x9a\x16\xfd\x9fAF\x1a\xd6\x88\xb4X#\x85\"\x84&\x8a\x90\xf3\xbe\xd3xV\xdeA*1\xf091h\xd8\x8c\xae\xd0U\xb6\x82;Q7\xdc\xb4+S-7\xc2\xbe \xf0\xad6\x9cY\x94\xcc\xb7!\xd7(\x89@\x03I\x93\xf4X2\xd5k\xf4m\x84\xaa*-\x0b\xb98F.\x02\x8a\x9eT\x10-\x801/|,i\x048W$Kz!K/'\x95\xf9\x87G\x8f\xf8\xc5\xa4DbT\xe0\xd6\xc1]+i\xe2K\xca\xab\xc1\xc5N*\xc4\xce\xeeKu=\xfed\xee\xa8.\xd2\xe9D\xb5\xff2+\x03sm\x94.\xd4\x8c\xce\x1d\x87\xc7\xbb\x94-\xa3\xfb\x97\x89~*\xb4\xb3\xbe\xa2\xb9\xe5c'O \xa6\xd1\x80\x98}\xec7\x94\xc0\x14\xa1zO[Xy\x15ia|\xdc\x9c1\xf7ui\xbc\x85\x0fy\xbd\xd4\xed\xf3ce\xe0'<\xb4C\xaa\x89\xce.?Uf851\xc3\xd4I\xa7\xfeL@\xcd<\x12{G\xd5X\x11\x15K\xb8\xc8\xd6y\xc4y\xeb\xb0\xee\xc4\xca\xd0$\xe2dZ\xb9R\xf5\x0d\x97\xa8\x90\xaar-\x82,\x9a\xfa\xd3p6\xabL+\xd5\x98\x03\xe6\xe12b\xbb\xd2\x8fR\xab\"\x9b\xb5s\xc43\x02\xb0S\xe8\x1fUOB\xa9\x97V\xcc2q3\x84\xc8\x03\x85}6GZ\x9c\xb0\x13\x08%\x8b\x85\xda\xcbR\x0e\xf2b\xe7\xe5n\x9fr\xfbR\xaadh\x1f$dA_W\xac\x15,\x96{|\x8a\xf1\x80\xde\xa64\x9c;\xf5}\xc4m4\xc7@\xca\xab\x85'~et_\xe4\xf6\xa3z\xb1Z\x07,\x0d\xe9\xd5\xac\x07x\xd9\xd6q(\xecC\x8f\x9aC\xcaX\xa3\x99\xf3h\xe1\x97i\xba\xd6\x04\n\xe7\x0fo\x12C\x0cq\xd1\xdfS\xc1\xec\xd57T\xd1\xb8\xae \xd9zC\xf3\xdb\xdb[\xf6\xf6\x17\xda\xb1+-l\x8e\xec\x0d,\xa3\xf5%\x8d\xedm\xec5Lr\xe1\x07\xa6P\xebzs\x04\xeda\":\xf9\x16\x98%\x1d\xca\x1a\x83\xc4\xd47~d\xbc\xde\x99S/\x9a\xd3O\x1f\xdf\xbe\x8aV\xeb(\xa4a\xea(Q:\xcfzh\xb2\xc0\x18+\xcd\xceM\x07\xdc\x7f\xc2_\xdc5!{NT\xaa\xf1\x05$\xed\xd1\x9e\x8c\xdcQ\xdc\x0f\xa1\xcb;R\x9d\xcd\xf95\x0dZOO\xd0#\xde\x85X(6\xd1H\xf2\xd1#\x10G\x0f\x0dkS\x8cP\xb2\xdbG\xb6\xa0\xfe\x94'\xf03\xd0\xbe\\\xf4I\xd1O\xf2\x8f\xc8\x0f\x9d\xee\xa3\xae[!o}H\xb9go 2U\xb0\x94.\x92\xd1@b\xfa\xfb\xfe\xe4\xd1\xac\xe7\xeeO\x9c\xe9\xef\x8f\xb8\x95\x04\xae\xfa?>?G(\x86V3\x01i0\x159\xe8\xb4i6\x8fb\x156\xabg\x0b \x9b\xe2\x87\xfc\xba\xd7\x89\xa7\xfe\x8c\xb1\xc9-x\xa6\xf8a\x08^\xf8FnU}\x1a\xb9o\xe4\xde\xee\xb6\xd67rk\xb8\xa9\xf1\x8d\xec\x1e\xde\xae\xa9\x97\xd2\xb9\xaag+W\xcb\x14\xdf\x97\xf2\x93$\x7f\xe2\x87-\xc8\xb8\xe1\xcaL\xdc\x94\xf5a\xdd\x87y\x1f.\xfb\xe8\xc9\xa8\x89\x01\xba2X\xe2.\x0d\xe5w\xa8\xf9-\xafSE\xb5Yl\x8a\x92?\xf4\xe9\xdd\x9ar\x9fh\xa2\xe6R\x06\x950\\\xe8\xcf\x10\xb9+\x03=\x02\xe1\xddK\x1du\x04.\x04\xec)\xec\x8bh=\x1c\x10)W\x1a\xd3\x01Y\xaf\x83;'\xeeW#>}6\x0c\xf0\xdc\xech\x8f\x16\x12\xb0\x01\xe6\xfc\xedJ\xbc\xa0Kn\xb7\xf2R\x90\xa1P\xdei\xa0\xe8\xc0Z\xb9f\xcf\x16\xad\xc6t\xa35\x97dC\xa2\xb8\xb3t\xbbj\x01\xce\xb9\x9ac\xe3\x90\xed\xe0Z\xb59\xec\x83\x08\x05\x1fe\xa9s\xd3oa\x94\"A\x91\xc2\x068\x08\x0f{\x00\x88%L a\xdc\xdaB\xbep\xed\xd6\xf3s\x00ga\xabn\xdf\x06\x88\x1cZ\x1d\xad\xe7\n2\xa0Av\x00\x13\xb8`\xaf\x8c\xf9\x9d\x8e\x8a-5 M\xdf\xe3m\xd3\x1a\xe81\x97\x01\xea\\\x0bz\xb6Bl,$^f+\x1a\xa6 \x0f\xe4\x9f^\xfaI\x1fo+\xa8Ei\xc2^V\x90\xad\x10\xbf\x9b\x97\x0f\x14t\xe5\xbd\xd4\x91\x80 $\xab\x02fkmC\x9f\x1d\xd3\xc2\xb3\xd1-]u5\xea\xcd_8\x97m\xe4\xf0\xfa\xc6BSyG\xd7\xa8\xdb\xaf\x8cT{r`\xaa\x0bF\x85\xee\xefQFrB\xae\xfbA:\xd9a\xe7-\x99\xfb\xe1\x92g\xdap\x18\x95\xec\xae\xc8\xedo\xc4O\xbbty\xbb\xb5PS\xe5~p\xa2{#\x97u\xff@ *\xdd\xeb9\xe1-]B\x0f\xab\xac\x05\x82\xe43\xa1\xaf\x0f\x9d\xd8\xa9\xc4\xcd\xccs\x08\x15\x0c\":`\x8c\xc1#\xe1\xe3\x94\xcd\x0dH\x02\xb9|\xd9\xa9\xd8O~\xd6\xef\xd0\x1a\x80\xc6\xa0]\x14\x14-\xba\xe7\xe7\xd8\xfe\xf99R\xe4\x7f|\x86I\x15LZ-\xa89\xe8\x16\x8fC\xe7l?s\x1di\x15\x85\xe2`\x9f\x81vw\xe8\x0e\x16NUp\xee\x832\x0c\\\xbc>l\xba.\xeb\x7f*\xc3\xd9u\x1c\xaa\xda\x8c\xa1\x9aM\xe78\xd5\x14y*\xd5G\xcd6\x9e\xb0*0\x8cl\x87\xa8\xebK%\\\x8aFx\xf9\x9c\xd0\x1cM\xd0@\xf6\xb8\xae\x06\xad\x9a\xc1\xfe\xe33\xbf|\x19\x8b\x83\xa6\x82z\xde%\xf5\xae\xc6\x8aEv\xebM\xab\x92\xf5\x02\xe5\x8b\x8d\xdb\x82\xe8\x1b\x8f\x1d\x0fC6\xf0:\x0f\x1b\xd9\x97\xed}\xde\xdf\x18\xc7\xff\xcc}\xe0~oV\x1a2p\xed|E[\nx\xab2\xb4\x90\xad\xf7\xb4I\x88\x9d\xad\xbd-m\xdc\xa1\xa7\xba\xb0C\xa1\xb3]\xad\xcd\x07\xfft\xbbZ=\x10\xe5\xd5\x83\xc0\x13\xbdVG\xb9\xe0\xf5w\x86\xa5\xd3\xf0\x99\xf2+\x1a\xf8![\x1a\xa7\x82U\xeb\x1a\x19Z\xf8\xe1\xfc\xf5\xf1\xfb\xa3hN\xc7Ui6\xa6\xe1\x9c\xc6c\xf0\x07\xfc[e\x92\xe1*\xca\xc24\xd7\n\x1d\xa4\xbc\x11\x7f\xa0\x7fR~\xfb\x9a\xc6\x89\x1f\x85cH\xaa\xad&x\xc3v~\xc1\xe8\x05\x9d\x7fZ\xcfIJ\x931d\x83r\x89\xe15>\xd2\x93\xec\"\x8d)}\x1b\xa6\xd1\xab(L\x89\x1f\xb2y\x14\xc2\xabB\xa1\xf5\x91\x1a\xcf\xcf?\x1e\x1e\xbc:=\x7f}\xf8\xeb\xe9\xf1\xf1\xbb\x93\xf3\x9f\xde\x1d\xffx\xf0\xee\xfc\xe7\xe3\xe3_\xce\xd1CWk9e\x7fM,\n{\xbbU\xc5\x8ar>\x87\xe7iL\xa9.i\xf8\x92\xa6\xaf\x82(\xa1I\xfaV\x10\xe47q\xb4\xe2\xab\x12\x0f\xccO5\xba\x16\x8aK\xc6*\xc8\xcaM1\xc3@\xb9b\x18\x88e\xa0\xf3|\xcc\xfc\x02\x921\xfbR/\n=?`\xcb_\\h|\xaepH\xeboAL\xf6\xf6\xaa\xd1\xca$5\xa9\xeewNM\xf6\x9e\xea4u\xac\xbc\x1a\xdd,\x13\xe5U\xaa$\x88\xe1\xd3j\xbf\x81(\xaf\xf6\xcb\xe9\xc9\xde3==\xa9\x11\xc35'3\xa3*Y\x9a\xf3\xf2\xcd\xea\xe1w)\xcaG\x95\xf2kQ^\x9d\xeeJ\x94W\xc9\xe4R\x94W\xc1p'\xca\xab`\xb8\xe0\xe5[\xd5\xf6\xcfEy\xb5\xfd\x1bQ^\x9d\xef!*\x18\xdb\xf0n|{6\xc4\xce>D>\xeeP\xb8p/\x07\x87\xd74L\x0fW~\x9a\xd2Xl\xf0\x8f\x94x)\x96\xbf\xf3\x93\x94\x864vVn^\xf7C\x90-\xfd\xf0\xe7\xecB\xd4V\n\x8f\xe39\x8d\x1dR\xad\xfb)\xf5\x83D\xd4.Q\x0bga\xab\xcaj\x9c\xc6\x84\x91d\x12\xa0\x80\xde<\x82\xe4\xc7\xbb#\xb2\xa2\x9a\xfbC\xf69\xf1W\xeb\x80*\xd5\xc7pS\xa72\xecs\x18\xa64~G\xc9u\xb9v\xa6\xaf\xfd\xea\x92\x84\xcbrMCv\xb3\x13\x1a\x94\x07<\x86s}\xcd\x1f\xe9\"\x8a\xe9\xdbp\x9d\x95\xab\xd7]\xb4>#d~\x8e\x92\x02\xb8\x020?\xb1\xb5\xf3\xbd\xbc\xf8U@\x92\xc4\xf1\x8c\xf5O\xe9mZ\xa9|\x89\x95_\x1f\xbf\x97\xd7T\xa2\xaaR\xf2*\n\x17\xfe\x1235\xb4\xab\x99\xb4\xaey\xc1\x17}\xb5f%\xe5\xb1\x96\x0b\xdf\x10/\x8d\xe2\xbb\x16\xb1>\xa5\xc2\x81\xde\xc0\xba\x1a\x98\xb2\x80\xa68\xcd\xf3\x0d!\xc8\xf5iL\xc2\x84\xf0\x1e\xee4\x15\x7fd\xbc\x80\x1f.O\xd2\x98\xa4ty\xe7\\c\xa5\xda\xd8\xc3k?\x8e\xc2\x15\x0dS'0K\xf3\xf8\xed\x8b\xc8\xbf\x99F\x08\x00\xfb\x8cw\xa9\x03\xa8Kb\x9flxY\x1c\xd30\xed\x8eu\xf7 \xbc\xca\x9c\xa6\xc4\x0f\x12k\x15?a\xac\xcf\xdcV\xe7\xd2\x9f\xcfih\xab!\xfc\x02mU\xae\xe8]r\x19\xc5\xa9\x97\xa5\xd6\x01\x05\xe4\x82\x06\xb6\nq\x14\xd09M\xbc\xd8_#\x07e\xa9J\xb24\xf2\"FMRj\xab\x87\x92\x97\x1d\x06\xf4vM\xc2y\x03\x9cH\xb2\x8e\xd6\xd9\xda:=zm\x9f\xde*\x9a\x13{\x05\x19\xb5\xbc\xb1R\x82d\x8c-\xaf\xadj\x14\xfb4LI\x13,\xf1\xce\xfa2\n\xe64\xb6V\x8bi\x92\xd8\xc1\x14S2\x8f\xc2\xe0\xce^\xe7o\x99\x1f\xdb\xdb\xe1\xd3k\xa8\x13\xc5\xd6\x1drM\x82\x8c\xae\xc8ms\x1d\xdf\n\x1d\xac\x13F7\x8duRzk\x1d\x10I\xa3\x95\xef\xd9j\\d\x89\x15t\x81\x7fm]\xef\x98\x06\xf4\x9a4\x10\x0eF\x7f\x16\x0b&\x9f[j-crqa\x87?\xa3\xc2\xd7\xb8]i8o\xe8\xd4\x8b\x02\x8f\xf1\xe1\x0du\xd0P\xae\xa1N\xb2&\xd6\xe5\xf2\xa20\x8d\xa3\x06\xca\x884\xe6\x82\xce/\xac\xe0F\xcf\xe8\x15M\x12\xb2\xb4\x82}\x11D7id]8F\xf9\x82\xa6\xfe\xa2\x9b\xd0:\xecu\x94\xf8aB\xadP\x8c\xa3\x9bFH\xc7\xd1M#\xa4\xe3\xe8\xa6 \xd2 M\x13\xff\xef\x08\x99R\x8d\x8a\x00\xf6\xfa\xf8\xfdA\x9a\xc6\xfeE\x96R\xc6\x1a\xb2s\xaf^E\xf2\x1dy\x8d\xbc\xc2W\x9c\xc2\x8aFgX\x95V\xc4\xd5\x81^\xa3\xb3\xb7W\xad.e\xb0\xaap#e\xb0\xaap\x83q\x08\x9f\xf5a\xb4\xd5\x87\xcd\xbd>lmV,[\x990\xb6\xb9\xa9 \x14\x1d\x0d<\x12~J\xe8\xeb\xe3\xf7\xa8O@\xde%\xf1\xd9\xcc\x91\x0fE\xbd/O\x11Q~\x19\xc5\xb5R\xda\xfcjS\xf3\xc8\xc3+\xda\xf7\xd1\x9cb3\xb2\x00\xa4\xc3\xa0,\x18\xa8U\xab\xca\"~\xd3Zm\x9c\xf1\xae\xd5\x01\xb2\x07\x1d\xee\xb2\xe7\xd4\x0dk1\xf5\xbbHv\xc1V\x9f\xb8F\x05\xcaz \x14C\xac\x06\x9a\x07\xbd\x0dS'/u\xdc>\x8c\x86.\x8f\xe7\xa7\x11?+cu:\x1e\xc8HT\x0b\xc0\xec\xbe\xec\x0b\x86\xe4\xabL\xf6Z\x13\xa6{\x95G-\xc5t\xbc\xaf\x84W\x03\xe35K\xf5\x96\xdax\xd2\x17\x85\\\xa1\xe3\x00\xd9g}I\x12:\xffH\x97~\xc2\xf8X?\n\xe5\xb6\xd0Vg\x9f\x8b\xec\x82\xf1zc\xe8F\xa1\"\xb9X\xbc\x10<\xb2N\xb3\xb8\xfe\xca+^^\xb7\xe5\x87\xfa\xde\x96\x9f9]\xd3pNC\x0f\xd9\xdai7\x8d\xd6*\xda\x86\xf3n\x1fX\xe1/\xf4\xee\x03\xe3\"\xc4O\x862b\x98\xf8\xfb\x03IR\xda\xd5$\xe5\xab\xf7\xea\x95\x9a\xffN\x80\xac\xce\xa1\x1d,\xcbo}#p\xfe\x18d\xb1\x80\x92 \xb2\xaf\xa3\x9bP\x0f\xe7_\xe8\xdd\xa7\xb5\xf8\xfe>\xca\x12\x8aU\x1f\n\xe7\x93\x94\xc4\xdf\x0be_U\xba\xf9\x02X\xe3{\xdf\x15\xdabd\xff,xs\xc9\xf6\xfb\x03\x9c\xf7\xf3\x05\x10\xe7/~W\x90\xcb\xb1}C\x98\x97J*\xe3\xbb\x13\xaa\xbe\xbc07\x9b\xba\xd0^\xa5I{r\xad\xb2\x83[C\xe7C\xb3ZD\xd7r\xf7\xa2G\xc5\xab\xf2\xe1\xabk\x18gim:o {\xd0D\xd3S\x9b\xe3\x105\x19\xa8\x97@k\xa9\x84ki\xb7\x00\xd7\xc4\xac\xb3F0j\xb2\x1c\xd7ymhL \xafe\xde\xb7\x01W\xa0\x94G!:1\x05A\xe9\xceIJ\x90\xbbIa\x02\xe9\x80\xfd\xac\xdeI\x14#b]\xdd\xe4,Y}t\x87\x92\x8f5\x84\xa6\xcd\xfa\xba\xd8\x0e\x1e\x86l\xb3\x99FC\x13^\x82\xbaT5\xf2\xd6\x18\xf3k9\xa8\x9e z\xe39]\x17\xec\xbczX\x07\x87\xe1\xbc}\xf3\x82Z<\xac\x07\xfeR\x13\x9d\xe0\xd7O7\xdc\x96\x10\x85\x8fG\"J|u\xb8h=\xd7df\"1M\xd9\xc4\"\x92\xd3\xa3G\xca\x8e-\x07\xba\x16\x031\xf7\x8e\xab\xe1\xf6AI\x18^\x16\x08\x00\xf9a\xf6.\xc6q\x17\xe1{kMp\x1c\xab>:\x0c\xd1j\x8f\xe7\xa9c\xf2\xcd\xcd`I\xd3\xd7$%\x8e\xcb\x81\xb3\x0f>\xdawEQ@\xe7NTu\x05`X\xbd\xc0,\xc4E\xa5\xac\xd8\x03udO\\X\xf0]V\x8bsbp\x05\x95\x97\xd9\xe7Z\x7f\xfb\xdc\x92GDH\x91m\xb7qn\x8c\x07\xc4\xf3\xb2U\x16\x90\x94\x9e\xdeD\x1f\xd8\xf1\xfb\xdaO\xd6x\xf9\x9c\xe0E\xca\xc2J\x8dn\x1b\xf6;\xa9\xcf\xbf\x83\xd1\xa2\xe6U\x13\x9fo\xb6\xe3[m\xc7s\xa7\x1a\xb0F~\xda\x1c\x1c\xf2\x93\x1fF7\x97\xbew\x89\x8bp\x0d\x13\xbe\"cp\xee\xc4u\xd8\xaa\xa9\xabBd0\xf7\x95\x1bv\xe3\xfa\xea\x1b\x04\xe5&\x02Q\x1dc_\xdf\x15C\n\xf5\xef5\x86\xd9S\xf6]3M\xc1\xad\xdc\x82\\0d\xb81\xad,:5\xd4\x17\xb6\x88\x0c\xd7\xf1\xd8\xdc\x04\x07cj\x05\x14\xc0)\x1b\xbb\x11z\xfe \xa6\x01% un\xdc~~\xe0\xf5\x0d\x01,\xf5\xae\xce\xeda\x06\x0fBu.O\xb6Z\xabo\x8e\xe1\x8f\x1eA\xa7\x85iD\xe5m\x87\x0e\xbc4\x0e~\xa1w\xb8\x1ayJ~\xd8\xd0\xd1\xa2\xcf\xd1s\x80\xf2\x83\xf7\xba\xf9\xbe\xb9t<]XD\xa8\xb1\xa8\xf8*\x1b \xba1\x8b\xdcQ\x1a\xda\xd6HX\x01J\x810\xc1\xaa\xac\x96\xbc\x0d\x1d\x9c\xdf\xc4d\xbd\xa6\xf1I*\xb2~\xa4\xe5\"\xf3\xd5\x01gT0\xd0\x980\xd7\x0d8\xaf\xd3\x0d\xb3\xd5\x05\x8d\xf3\x95c\x0b`\x19\x0b(\xacw\x97\xe7\x8c\xc3\x03\xcc\xdc3`\xf4\xb5%Ms\x93TG\x9cyn\x112\x17\x1d\xefk\x15\xb4+\"?\xfa{\x8dz)\x9eB\x81\xd1\xe1D\xafp}\x8f\xa5_)*\xef=\xd595\xab)\xde#q\xa4\x8a$\xe2V\xb4i\x197\xd5@\xe0\xf8\xe5\\L\x17\xf5\x85\x928\x18\xd60\xd7\xe2\xce\xaf\xcfV\x00\x13\xa0\x0e\x0f8\x92]\x04\xbe\x97SMd\x02\xe2\x01\x99\x17n\xa8\x07\xc9G\xba8\x8d0m_\xbf\x1ab\x0bp\xe1B.\xc8\x0d\xce\xa3\x9b\x90Vc\x96\x16K\xc8\xc4\xb7\xe42\xca\x02!\x06\xb5\x81\xa6\x84I]r\x03\xa9\xae\xac]a\xe4\xd0\xa7\x06\xe8c\xb9\xc8\x86\x16\xd3\x85LL)\x86_\xbf\x0f\x89\x8c\x03\xf0\xb5\x03P.W\xecX\x90\x13\xcb\x94\x8f\xc3\xc7\xafb\x1c}\x08\xf1m\x0c#\x9eG+,\xde\x8e\x90\xc0\xf1\xbdY\x062g\x89\xdb\x80\xf7\xff5\xc8\x8a<;\xe2fLW\xd15-\xa3';\xf9\xbf \x82~\x075\\)\xe2\x80Q\x03iP\x8a\xfc\xe6\xc1^\x0b\x13G\xedR\xa7\x91Xh\xf3\xfb\x1e\xe6\\\x9a@d\x89\xfc\xe2\xac\x8d\xc1V\xd8\xe73_\x81 W8z\xe6!\x8b\xf0\xa0\xfb\xfb\xe0\xb5\xc4\x94\xb9h\x16D\x92\xe4\x04\xc6|\xb05\xf5G`\xb8\x96\x07\x19uD\xb4\xe2Y[\xf1,\xad\\WlZ\xc9\xa0 P\x88\xd0\xb8S\x0ds\xc9ov\xf0\x9d\x80S'V\xcc\x17\x0c\xd3`]WVq_\x17\x95\x17\x04dV\xfa\xd1 \x81\xc60\xca\x96\xd1\x08\xd0\xaf\xca\x83\xa2\x9c\xb6\xb3\xe2\xbc\x7f\xf6\xab:\xa8y\xd9\xce\xa98D\x95{\xa9\xeb>\xac\xf8&w\xfb0e\xbf\x1a \xa9\xfe\x8c\xcf\xb0\xf4+\x0f\xd2Z\xf4\x1bv\x8e\xca\x00+~\x14\x0e\xde\x7f:9=\xfftrx\xfe\xe1\xe3\xf1\x87\xc3\x8f\xa7\x7f\xad\x9f\xafj\xf5\x9f\x0fN\xce\x7f<>~wxpt\xfe\xeb\xc1\xbbO\x87\xf5c\xb7Z\xfd\xe8\xd3\xfb\xc3\x8fo_\xe9\xaag\x9a\xea\x1f\x8eO\xde\x9e\xbe\xfd\xf5\xd0\xf6^\xa2y\xef\xf8\xd7\xc3\x8f\xef\x8e\x0f^\x1f\xbe\xb6\x0d0\xd0\x9eR~\xf2*K\xd2h\x95k;\xc6\xf0\x91.\x0fo\xd7J\x94\xfc\x94&\xe9\xe0\xc2\x0f\xe7NHo\xc4c\xa7\xfb\xbb3')\xb9'\xb1O\xdc\x0d\xcc\x01\x14\x0f\x0eNO?\xbe\xfd\xf1\xd3\xe9\xe1\xf9\xd1\xc1\xfb\xc3\xf3W?\x1f|\xc4\xbc@?\xfc\xb9\xab\xcb\x1ao\x0f\x85\xc1><\xb3\x8e\xd6\x07\xb9x\xfc\xea\x92\xc4\x185\xd1R+I~\xa1w\x96\x1a)\xc6\x1c3=\x0e\x82\xe8\xe6M\x16\x04'^L\xa99\xb6\x0c\xd6\xc3\x08%xjx\x96\x0e\x03\xcbp\x13\xcb\xa3\xbb\xd03w\x9f\xa5\xd1+\x11\x12\xc3\xdcD\x96F\x1f\x02rglE\\\xec\x9b\x9f\xd3 \xf8@\xe6s?\\\x1a;auN\xd6\xc4\xb3\xd6\xb9$\xf1\x89e\xd5\xbcK\x12\x04\x14-\x1c\x8c50\xb4\xc7\x18\"\xb87\x8e\xd6\xb7\xc0\xc2\x0bH\x92\xbc}m\x7f\xceYLS\x8d(H\x8cA\x89\xbc\x88\x01\xc1\x8cV^\x14\xa64\xb4@\x80??\x9c\xfb\x18\xe8\xc3^\xef6}O\xc3\xccZ'\xc6\xc1\x9a\x00%*\xbc\xf3\x13\xdb\x88\xa2xnFO/\x8e\x92\xe48\xf61L\x92\xa1\x0e\xb7\x0c2?\xa4\xa7\xbe\x05\xdey|\\\xc3,\xe6t\x81\x81 \x0dO\xfd\xd8\xdc\xb2\x08\x96c~9\xba \x83\x88\xcck\x91 \xf3\n1Y.\xad\x0bEC\x8f \x04\xc6\xe7\x8b(^Y\x1f\x1e\xd8\xe9\x14\xabr\xd8\xa2\x8f\xf74\xbd\x8c\xe6\xd6*G\xd1\xaf$\xf0\xb9\xff\xa9\x01 \xac\x1a\xe7\x0f\xcc-\xc5dE\x7f\x8cb\x8c\x16i\xa8sI\xc9\x9c\xc6f\xa4\xba\xa4\xfe\xf2\xd2\xdc\x05\x0f`d\x1c\xe4\xa5\xbf\xbc4\xbf\x1b\xd3\x85\xf5\xe1;b!`\x97\xe9*x\x13Y&\x96\xa6\xeb\xc3\xbfe\xfe\xb5\xb1\x86\xefY\x16\xd37/\x10\xden\xbd\xc7\xf0\x8d\xc6\x1a)]\xc6~j>\x81|3\xc4\xaf\xe8\xdd\x07\x12\x93\x95\xb5\x86\x15\xc9\xae\xfc\xd0d\xeet83ov*nd\xd9$e\xba]D(4\x7f2\xec\"~]\x19\x95\xea3\x08a\x08|\xda\xd7\xed\xbe\xca>3$WK\xbe\x052\xd5\xd0C\xe4\x87xVE2\x11\x9b\xf4\x99>?\x84.\xd9L\xac\xac\xe8\xa40\x9d\xe7\x89x\x04\x85r\xbas\xff\xfa\xffa\xefM\xdb\xdb\xc6\x91E\xe1\xef\xf3+`\xde9ij,)\x96\x9d\xc5Q\xe2\xf6u;\xce\xe9\xdc\xc9\xf6\xc6N/\xa3\xf6\xf8\xc0$$\xf1\x84\"8\\d\xbb;\xf9\xef\xef\x83\x02@\x82d\x81\xa4lgf\xeey.?\xd8\"P\x00\xb1\x16\xaa\n\xb58\xfa\xbe\xb7\xb9\xf2\x1e\xfe\xfd\xb7\xf4//\xdc\xdf\xae\xb6\x07\x0f\xf1Q\xe8\xa5\xdbX\xbb\xca\xcf\xc5\x9a\xa2\xee\xd6\x04\xd1DL:\xfd[\x91\x8ab\xf8\x8af\xde\xd2M\xdb/>\x01Ug\xb3\xc9yU\x1f\xbc9\xf1\xa8yVH\x94np\xe0\xd6u'\xe1\x82\x1bkd4\x0e\xa2\x88%b\xbb\x08\x9c<\x9b\x9c\x93m\xc2\xc86 g\xbb\xc8\n/B\x1a{\x00\xbds\xfe\x9cx\xa3\xd1\xf3\x81\xd4\x0c\x1d\x874\xcd`\xe1V\x17\xa6\\\xda\xd5O\xb1\xe6\x90\xce\xb5B\x98\x9a\xf4\xf4\x87\x9b3\xba\x80H\x0d\x8e\xf4\xb7^?a\xe7:`\xb3\x8c\x16\xadgkH\xb8;\x1f\x8c\xe7<9\xa1\xde\xd2\xcd\xeaF\x80E/br \x83~\x81\xfa\x89\x1b\x8d=\xd1x\xb1m\xd3\xc1s\xb3?\xa2\x87Z\xdfQn\xe42\x0f7\x99,\xf1\xfc\xd7\xfb\xd8\x7f\xfb\x96\xcdm_\x82\xaa\x1d\xedkT+7nI\xcd\x1cTC\xb7\xaa\xd0x`\x86#~\xf0\x808r\x06\xc05\x03T\xb2\xe5:)\xcb^G\x19K\xd64\x94\xe9\x83\x8a\xde\xbc\xa9\x13)p\xb3 \xcd\xe1\xf3r*\x82\x14\xfe\x8b\x06\x8bO{4\x0c\x19S\xf5\x83\xa9G\xc6V\xaa\xda\xea2\x13%\x0eI\xa3\x12 \xa2\xc0\xf6\xbf\xdb\x98\xa3\xdc\xaf6\x7f b'\xe1\x0d\xd5c\xb7U\xd5n\xb6\x85r\x86\xc3\x08\x16+20\x99\x91\xad\x0c.\xc1x\x81\x8c\xc8\xa4\x18 ]\x1c\x9d\x9c\xb1\x1c7\xa3\x9ez(\xf9AK\xbc=\xb5.d?\xcb[v\x18F\x15\x87\x1d\xc1Jf\x9c\xbc&UX\xec\xbaH\xef:7\x13[U\xfa\x9e\xe0\xe4\x05\xc9\x9e\x13\xbe\xbd= \xd1\x8c\x9f\x8bI\x98q\x04\x05i\xf5\x9c\xe6\xdcO\xc9\x8c\x9d\xdf\xef\xb6\xb3\x1c{XP\xa4\xbb\x1ec\xa0\x13\x89h\xed\xcd&C\xf2\xdd\x0b\xc9\x1f\x16\x02\xec\x03'Kr\xe6|\xff\xdd\x908/\x1e\xca\xcc\xef\x9d\xf3\xe6\xc1(J;/\x80\xb1\xfc\xde\x01`\xf5\x1b\xf1\xf4=\xdb+a_d\x97\xdc\xbf\xf9\xfeE\x96\xe8b\xc9\xf7/\x1e\xaaDK\x1d^\xd9\xda\xf5\x82\\\xaf\xc2(=\x00\x8eo\xfa\xf0\xe1\xd5\xd5\xd5\xf8jo\xcc\x93\xc5\xc3\xdd\x9d\x9d\x9d\x87\xe9zQ\xb4~\xbdhT5G\xa9x\xe7/\xceT\xf6\xe8\xf0\x85\x1f\xacU\xcb\xe0\xd7y\xf38\xa4 \xa3\n\xfc\xc5\x8a\xc6\n\x1a~!\xd0\x1e\x0f\xa7d\xb6\xdb\x1c\x01\xddi\x8f\x87\x8b\x84\xe7\xba\x9e\xe2\xd56\x1a\xe2 \xd9\x82E\xben\xc4<`\xa1\x9f\xb2L\xd5P\xbe\"%c\x9a\xd0\x95.(1\x8b*\xa6_\x90BY\x82vAM`\xeb\xdc\x11y\xb7\xb0\x90\"wDn\xcacy\xad\x8bdyT\xe5!l\x92\x1e&4\x13\x9a\x84\xe7\xcc9\xcf\xf0\x9c%\xb3\xdcog~#\x08\xa0,0\xad\xbb\xa7,w\xfa\xcc\xf1\x82\xc4\x0b\x81\xc5\xf5\xc2 \xfe@\xb3\xa5\xf8\xed\xb39\xb8n`a\x18\xc4)d/\xc4\x9f`E\xa5\xaf\x07\x08\x80\xa2\xfe\xd3\xe4?\x13\xea\x07,\x02-\xdd\x15M\xc1\x03D\xac\xaaR72\xf0\x93\x877\x0b^\xfc\xd4u\x88\xc244\xebHddJ'\xcd\xb8\xf4\x0d\xc1\xae\xa5\x060\x84;8/(\x1b\xfba6\x07\x0f>\xc4\x1b\x12*\x7f\x99\xc1xk^N:i\x88@\x9c6\\\x9e\"\xf3\xda)\xa2N?p!\xe4\xfcEpV\xd4\x02\x11T\xe8?\xe7/\xa5m\xb5\xf3\"\x0c\xa2\xcf\xe4\xe1\xf7\x0e\x99\x12\xe7\x85\xa3HP\xe7\xfb\x17\x0f\xcb\xdfN\xd9\x95`<\x0f\x12M}\xa9\xe4C\xd9e\xd4\xd3\xed]\x0f\x01T\xc8`Qwoe~q\xe1BO\xeeW\x1f\x9d\xb8\x82(\xe6\x83\x99\x80\xab\n%\xfb\xd0\x0e/\xa2>\xac$Nl\xde\xc1<\xa2S,\xd1p@\xa3\x19\xc9z$=-\x97\xa8\xcfI\x8eK7R5\x85x\x9c\xc1\x86\x02\xa6\n[\xfa\xa4\xce\xbe\xaa0\x83\x0dW>\xb1\xaa\xbe\x9e.\xe3\x0cN\x1e\xd7;+\xe3\x0c\xee=\xae\xc3\xaf\xf1\x15\xa5\xc2\x0c\xee\xd4;\xab\xc2\x0c\xee\xd4 \x91\x1b\xd5\xfc\xfa`\xaa0\x83\x0d\xbb\x8d\x0b)\xb5\xd9{6\x18B\xb8\xc4\x9d\xba\n\xa4\x8a7\xd8\x18\xbe\x13U\xf0\x11\x14\x9c\xf8\xeb\xebB\xa2`r\x0b\xa2\x85\x16{\xf7\xa8\x10\xf9;\xe4l\x19\xa4D\xd0\xf6\x82c%W4%:L,\xb9\xbc!\xff%\xce\xa9H\x9cS\xff5Fn6\xfed\x7f\xd3\x1f(Ka./\xde\xa1'\x83\xb4Z\xfd?36\xbe\xc8\xe8\xe2\\\x1a\xd7(s\xcfl\xac\x97\x85\x1e)\x99jY\x0c\x8a\x1fu&{O\x1dA\x1d\x88\n\x87\xf6\xc1?$\x0e\x81\x0btA\x8f\xa9\x91P\xaa;\x84\xcf \x9c\xda\x96\xb2\xe5\xc0\x8b\xe1\x1a\xc3\x91\x0f\xf6\x89]M\xb4uO6\xfc\xc9\x0eHu\x11\x9b\xd9\xb6\xfa\xce\xc0\xa3\xa4\x15B\x8a\x94\x9fL\x9cA\xa5\x81p\xcf^1\xd158\xf72W\x14\xddu\x86\xb0\xec\x07\xed.M>\xb6x\xdc\x90N\xb6\x133P\xfd\x15\xea!\x19\xf1\x88\xa8m\xa6\xd9\xf8b \xa1!\xda[\xe4\x05\xac\xf2\x07\x0f\xf4\xcfRN#h\xb6\xd7`\x99#a\xa6\xe2W\x87 \xd3\x91\x9b\x0dI\x00>\xb2\x16L\x06\x8e\x85\x88\xc7\x1f\x19\xf5o\xdc\x81v\xa6\xe5\xbe\xc4\xee\x0e\xa0QQ\x9aM \x12\xeb\x99\xa0\xb6v\x16\x97\x9a\xa1:3\xa6\x88\xdf\xe7\xafVKQd\xb6^6\\ \xcd\xc7q^\xc6\xc1\x05\xe7\x92\xa2\xcd\xca\xcfd\xbd\x85*Y\xb7\xa7}i\xbci|l5\x8ey*G\xf0g\xe9\xca\x02\xbe\xd8^\xcd\xa7F5\x97\xb7\xa9\xe6\x1f\x8dj\x16\xdd\xd5\xe8_b5\xbej\x1ca\x19\x8f\x8f.y\x02w\xd3\xe2\x7f\xed\xcc\xcbx|L#i\x0e\xe0x4\x8aCzc\x05)\xfc\xe1h\xc8L&4\x0b\xbc\xcc\xe5|\x1c+\x0f\x85\x8e\xaf\x12<\xcc\xab`\xc6\xe3\x93U\x9c\x05\xe0K\x90\xc9_\x08H\xe4%7q&\x81\xf4o\x0c\xccW >\x9a\x9d$p\xa3\x0e\x91\xfd\x9a\xd9o8\xf5\x99/\xfd\xd6:!\xbc@\xc8\x0f\x0b\xe0[\x96Q\xdf\x04^\xa9\x04\xbc\x80\x8a\x9f\x04\xb0)\x12\xe4\x08\x1c\x96\xe7\xa9\x18\xb0X\xfcG\xb2\xe5L\xe1\xd3$2\x81\x88\x80\xfc Z _$\xa0X\xe6\xc4\xeag\x13\xe8#\xcdX1s \xcd\x98m\xd6N\x19\x03\xf3\x0b'\x85\x1f8\x80lQ*\x7f! \x19\x0d\xa5\xcf\xc9T\xfeB@\xf24\x06I\x8f\x93\xca_M\x90\xb3`\xc5t\xb4$'\x0bV,\xc7B\x1ae<\xfe\x89\x87\xf9\xaa\xec\xdd\x1a^m\xfd\xfb\x99\x06\x99l\xfe\x95\xfce\xd0\x11\x18 \xf6{c\xff^\x8f\xb3\x84z\x9f{\xec\xfd\x1f\x1aeK_\xcb\x82\xe0~\xfdR\x1f\x98{\xf5\x8b\x1a\xb1\xf3\x199 \xea3\xd5\xcc\xc2W\xbe.\xfe\xc8)<\xf4ft\x81\x1du\xd2\xd3{\x00\xba\xfb\xd6 ?\xeap\xc6\xdd\xb5\xcb\xeaMW@\x05>\x06\xb9\xa9/\x86%\xfeA\xba\x1bU\x0e\xdc\xd4\x1e\x01\xb9\x8f\xfc\xcf\x06\x96k\xe0\xcb\x84\xd1\xcf\xcd,\xd9\xb0u\xe03nm6\xcd\xfd\x00\xcb%\xa6\x0c=+]a\xdb\xfbp>$\xaf\x06\xe4U]\x1e\x93\x01\xb1\xd7Vx\x1c\xe7\xe9\xd2E\x86 \x1b\x92W\xb3\xec\\t\xdcB7\xb7v\\j\xac\xdd\xef\x8c\x9cH4Y\xe0\xcb[\xceI\xb0Z|\xf3v\x0d\xc9\xb7\\Us\x9e\xac\xee\xb7\x0b\x1f\x19h\x88\x11'Q?Z\xbap\x9a_\xae\x02)\xb4\xd4\xbfn\xd7\x8d\xc0\x128E\xad \xe9*\xce\x1a\xd7\x8b]g4a\xf4~\xc7\xe1\xb5\n/>\x14\xad\xd3?\x99=$\x01\x82;\x7fj\xe0\xce\x1b\xa0\x9b\xe4\x89\xd0\x87p\xfa\x11\xe5\xfd\xe5%\x07&k\xb8\xa4\xe2\x94Fs\x12<\x1d\xae@\xb0\x0c\xb6\xba\x14\xc7\x1f\x96\xb5\xb4\xd4\x15\xac,\"\x90@\xc6\x14\xc5\xb2>\xb3\x9b\x05\x8b\xf0\xbc0\x88>\xe39\x82\x9e\xc1s\xd4\x1d\n\x96\xa5Ug\xb1<8\x0e\xf1\xac\xab\xcbN\xe1\xcd\xcf\xe84\x89Uf\x95\n\xc5\x89\xad%j5w}\xf3\xff\x80\xff\xbe\xe6WW,\xca\x83\x8c\xad\x90\xf2\xe4\xc7\x9ap\xedW\xd0\xa2\x99\xd1\xd1\xefG\xa3\xbf\x9d\xab\xff\xd3\x8b\xdf\xc6\xbf\x8d~\xf3\xcf\xff\xf2\xe7\x87U\xf0\xbf\"\xb7\x95\xff i\xb5\xd3\x06#B\xfe\x8cJ3\n\xedJ\x1d^\xd0\x199\x03\xf2\xfd\x01\xd9\xa9J0\x02[\xa4\x92\xbfA\xb0\x01\xe4{\xbf\xb4\xc5\xd8\x13|{\x15\x17u\x85\xc4\xf9Oy\x03\xfeW\xf03\xfb\xe5\x0bq\x7f\x05\xf3su\xcf!\x08\x98\xc7\nW\xfeU\xdf\xbd4\xdc\xbc\x16\x04NUFb\x86\x03\xc9\xe8\x824\\C\xea\xcc\x88\xaeX\x1aS\x8f}\xfa\xf8\x9aT\xe3ph\xb9\x94\xbee\xa8e\xc7 [\x07r\x9e\xb9e\x9dRZ[\x1a\xa4\x05,u%\xa99\x17\xb4\xbe\xa5\x9d*\xbcv\xee\xc6\x16\x08\xd5s\x18\x92\xd7Q\x90\x054\xd4t\xbb\xa0%\xe7C\x92\x0c\xc9\xd5@\xfa\xd8o\xfa\xf4\xfb\xda\xe6fP|\xfd\xa4\\\x98\xf0\x8d\xf71\x8b\xce\xe8B\x9a\xdd\x1cE\xfe\x87\xf2\xda*\x85\x0f\xb6,\xf6\xebZ]JA@\xd6\xa5[k\xe9\xa7h\xfe\xd6\xb5@)?\xce\x8a]yN\x0e\xc9\x89X\xdeR\xf3\xebD\xaet\xb2M\xae\xc5/\xb9\xfc\xadKC\x02\xf7@\xe0\x1b\x92\xaf]\x14O\xc7\xc9\xf2\xa68\x82\xe6c\x9ag\x1c\xc2\x88H\xd3\xba\xd6r\xc1x. M\xfe\xe3\x9fr\x14w4\xeb\xd3\xbfSwZ\xa9\" r\x99gY+-\xf7o\xd0\x8dNz\xb3\xa3Q\xff\xe8O\xbc(\x99J\xab\xbeN\x0f\xcc\xd0CCQ+\xd6\xc8\x03l\x83\xb3\xb0\xb8\xd2H\xe0J\x03?\xc7@\xa7\xa7~\x8f\x91t\xc6\x89\x06/\xee\xb3\xa4\xc5T\xcf\x0c)\x11\xd8\xcfP\x0d\xfa\x1ek\x03x\xa7\xfe\xa8N\xa1\x04\xe2\xa2\xd8\x0e\x04\xfdt8\x87\xd5\x8f\x03\xba$\x92\x96\x01\xcb.7P\x7f5&\xc6$6\xdc\xfd\xe3\xebP+\xa2\x08\xa2-\x80x\xf6r\x9a\xe5\xfc\xbe\xe2 \x94H\xdd@-\xa6\x8e\x06\x135\xa29\xc1\xdc\xeccOA'\x9b\xf4\xe4\x9fK,\x0c\xeb\xe8\x90\xbcm\x8e(\xc8\xd4\xc4\x87\xbcz\x9bk~ ]1\xd8\x10(\x01\x85.\xab\x94\xda'\xb9\xd4 \"\xdb\x07\xc4\x01\x15\xa5\xbc}\xc2\xfb\xc6\xcb0\xcc\xc2#\x9f%g\\\xf0\xf9\x81'\xdbA\x0eID\xa6\xfa\xf4\xa9\xd2\x1cf[\x1a\xad\x07\xfa\x03\xf4\x8eZ\x80^\xbfT\x15\x83\xech\xd0\xea\xd3\x1d;\xb5\xfb\xf9s_\x17\xe1Kp\xe2\x80\x93\x16\xb5\xad\xe6J1\xf7\x1c\x1f\x14\x0b\x85\x8f\xa5\xce#\xccRB\xca\x04divP=b\xc1\x7f\x98\x15\x1aYZUL\xd0\x1b\x86\xe2\x98M\x01R?T\xadu\xc0\x0df\x84p]\x83\x9d_)Q\n\x0c\xdc\x89\x1b\xb4\xd1\xc5f \xda\x86\xd3\x12\xbd\xef\xa5\xfcQ\x13\x8aT\xc5[\x18\xff7\x0f\"\xd7qng\xa7O\xca\xa5\xfc\xb3I\xa3 \xce\xf37\x15\x02,\x19{K\x9a\x1ce\xee\x8e\xd8\xbb\x90\xbcM\x1225\xe2^\x10\xeb\xca\xab\xd1\xb7\xbd\xa5\xa6Z\x89\xed~\x97X>\x86\xd3T\x94\x17\x08\xe2\x7f\xc6bs\xa4\x83\x89\xc0\xe8 \x84\x86\x06\x0c\xd8{\x05Z\x1bY\x9c\xd5i\xfbB\x94\xec\xca\xces\x12\x92\x17$\xd5\xb6\x94$\xdc\xde\x1e\xe8fI\x0e6\x19\x92t\x16\x9ew\x912\x8d\xe8\x14\x1e\x0b\x8c\xf0\x14\x9ba1\x8c6i\x0e\x0d\x06e\xdc\xceHv\xb0h\x81\x9b\xc1\xc9\xdf\x8czR7\xe8\xab\x16\xbb\xc5\x16\x00\x19=\xbe\x8c\x82o+\xd7\xefb\x8c\xb8M\xdc\xcb\x15 \x82f\xda\x96%\xb9\x17J\x9a\xdb\xa4\xb3\xbaMh\xe6\x9d\xda\xd4)\xba\xe56\xf1\xacn\x13\x9ay\xa76\xf5\xe0\x03\xb9M\xec\xaa[\x85f\"$\xb3\x9d\x01\x7fW\x14j\x13\xaapE@7`\n,\xa3 \xc4V\x19v\x8b\xf8\xfa-\xde\x95\xda\xd1\x15M\x8c!\xb9\xc6\x83\xe3\xde\x95\x03\xec1\x1f\x97X\x83\xee\xf0\xc9\xcee\xd9\xc1t\xfe\xd4\x8f\xe9\xac\x9f\xfc\xc8\x0co\x80\xade\x8cI\x0b\xcf\x98 >\x00\xf4\x03:\xf3\x08\xc3(Y~4Y\x1f\x7fl\x96 \xe7\x91Yq\x85+\xeb#YN\xed\xecZ;\x1f\x05\xfd\x0cD?\xd3\x01I\xeb\xed\x0e\xa4\xec\x1fX%pU\xf2\xc7\xd7\xc1,8\x07B\xbd\x83\x9d\xb33\x8f\xedW\x8e\x92Z@\xb8`r\x08\x03G L\xad\xdc\xe6\x89`\xcc*\x0c\x1fka\xf8f\xd8A\xecB\x11\xd1\xed9\x90\x81q\xc5dfn\xaa\xd1\xc4\x83M\xd6x\xebZ\x12\xe0\x10\x98\xa6\x87Pb.\xa6\xb0}\xf1\x0dI\xdc\xb5\xa7Hek\xc4\x03\xb2\x15#{\xe3\xcb\x172\x87\xb1\xc0\xf3n\xb5o\xaa_\x9e\x0f\xd0\xca\x1f< \xb1\xa8OL\xc1\\\xfc\xb0\xecR\x91\xd7!\x81\x90\xfbM\x14E\"\xfb\xe9\xa7\xa0\xe0Q\xe9\x94\x98\x1aC85\x07|;\x95k\xa3\xdc\xaa=j\xaf\xc9n\x06\xf6\x9d\x9c\xb2\xacm\x1b\xb7\xdf\x8d\x17\xdf\xdb`\xa3w\xa3`\xdf\xa6|^\x7f\xca\xddrX\xedI\xd1K_u\x81L\xed\xd8\xc5\xdf0\x10k3\x05\x84U\xd4l\x80\x12\xd8\x15\xe3\x98c'\xb2\xf5\xfc\xbd5\xd7]\xb0\xb6\xac\xc2\xda\xb2~\xac\xed\xdd\x99c\nZz-6|\xd6L\xc5\xd1\xe3\xd5\xe6m\x02\x05\xd0\x8f\xbfU\xb5\xa9\xc1\xc6\xf3\x92\x8d/G\x0b/\x16vq\xffx1\xaf\xf25\x03\xbd[\xbc\x07\xcf+\x9f1\xe0\x11\x1aKg\xa5\x05q\xa4B]e\x06\xff\xabIr\x89\xb8#uF{\xa2\xc8\x16 _\x03\xf8\x8c]gJ\xf8\xe8V,>\x03PF(\xe4\x16\xd6\"d\x9b\x04\x03\xe3\x98\xcc\xc9!\xa1P.\xaf\x95SW\x92\x8e\x14\xf2\x1aE\xc2\x1a`\xd1\x81\x10\x0bg]\xdbL\x8a\xffy\x07\x0e\x85\x8b]\x84\xed\x1d%F\xab\x1b\xd5 u\xe6\x91]\x95\x10\xabyC\x9e\xfd\xff\xe9\xe2\x19\x8f\xd6\xf9\x95c\x87[\x01\xd8\x0f\x07iV\xdezvT<\\\xed<'\x11yA\xb2B\xfa\x15mo\x0fH6\x8b\xce\x95\x0e\x87\xcd\xf2\x9c\xf4a\xe7\xda\xf8\xd9\xde<\xe6\xf58\xcdx|\x96P\xefs\x10-\xbaN\xc7\xce6\x81\xc3\x82\xb6&-\x19\xf5\xdboo\xb9\x7f\xd3\xd2\xde\xc4u\x9e6\x1f\xe93\\\xf6\xd9i*C\xea\xa7\x8f&\x8bA6\xe0\x07\xa2\xf4h|\xc7\x03\xf1\xe9\xb3\xba\xcb2\x0e\x86\x87\xa3U:\xea\xf4\xdc]_\xeaj\xeb&n\xe1e\xdd\xe5C\xe2\xac\xd2\x913\xa8\xe3\xda;\xb5\xfb\xe1\xc8\x1d\x0f\x1e.n\xd9\xbe\xb2u\xc9\xb0\x1b\x85kW\xe0\xe3\x8c\x7f\x12\x14$\xe2\x02\xfc\xeb\xbdv\xceF\xa5(\xaa!\x19\x07\xe9\xa7(\xc8B\x96\xa6\xef\xc0\x7f\xd9\xa0k\x1cZ]\x19iQ\x02h@9\x97\x9c\x87\x8cV\\\x17\xcb\x0c\xa5\xc0_z\xe0\xaa\xed\x04\xady\x11\xa4\xef\xe8;7\xab\xa1\x07\xbd2DU \xe80\x9c(s\xc4?\xe5\x83\x07\x84K/\x922\xd2\x05\x99\x82\x08\xbc\x11!\x80HG\xe3`\x96\x99\x04+\xd0\xcf\xca\xc4y\x13_7N\xf7;N\xca\xfe\x0e6)\x0f\xff~\xb7\x8d2\xa8\xec\x94\x11l\x95\xfbl\xf7Cwv4\xfa\xdb\xf9=m\x16g\xf4\xe7\x893\xb08\xc3\xbfCk\xfb\xb5H\xcb\x0b\xfe\xf8\x8a.\xae\xa2 z\xe6\x17\xdb\xb8\xb6\xd8\"y\xf9\x90\xcd\"pq-M\x89\xa5\x14>\x82\xd54\x8b\xec~\x05\xc8m;lpg\x8fw:\xf7\xafej\xbes\xbe#\xdb\xb0\x88\xc8\xb6x\xb9\xe7\x86M\xcc\x86i\x92\xa9\xda\x10q\x08\x87\xecL\xd9\xfcb\xa2l\x8e\xcdE\x97A7\x01?\xa9\xea\xa6\x1b\xdc>\xa4 !(|\xa7B\xda\xff\x07\xf7\xe0[\x13\x84\x9ft\x931\xbb\xce\x12\xeae\xbat\xd9\x1e+s\x8e\xcf\xc2\xbd\x84~\xd9}2\xc0\xec\xe09z\xe8h\x9e\xc1\xb2\xcc\xa3\x19\xabn\xc0s\xcc*=\x9a9?\xb3\xcb\xcfA\x06\xae\xff\x80\x1c\xb9*\xde3\xc8\x7f\xcb\x7f/3W\xf2E\xe6\xac\xd22\xe3\xedi\x99\xfe\xbeL\xe6\x90\xda\xf8jm \x12\xe3`hN3\x8d\x82\x15\xb8\xf8\x02OM\xdcu\x8et\x823$\xe5\xcbI\xe4c|KQ:\xc8\x98\xf4\x14\xd6R\xc7k\x0d\xd3Z\x93\n\xf5g\xad\x05\x9cqa5d\x89\xa0?\xcd\xae\x9c\x15)\xa2\x86\xf2\x0d:S]\x81My\x02\xe6v\xde\\\x0d\xa6k{q\x00\xe6\xfd\x18\xf6\xca\xa0\x8a}\x01Q\x1b\xae\x82\xc8\xe7W\x80\x04\xa5\xa8\x8d\x04csf\xca\x97!i\x02\x14\x83\xdf\x0e\x06#[\xbe\x0e\xaac\x82\xb4\xa5\xa8\xa22\xb4\xc6[o\x9f\xd9\x82\xc6\xa13v^P.\xe2\xe5y\x03d+0a\x90h(\xe2\xe4 \x1aE\x0d\x113\xce)\xa2\\b$5\\D\x91\xbc\xd2.P`\x88\xce\xd1\x8d_qIJ\xee\x8e\x946s\xfc\xdct\xc1,%_\xbb\x93\xba\x0f\xe3\x1c\x97:J\xc7\xcf\x8f\xf6\x8cCE\xbb#~\x86b\xc7\xb0\xdb\xbd\x19h\x13 zY\xc6@5\xeb\xf5\xac\x07\xaa\xe3-\x99\xf7\xf9\x92_\xebHU:,\x1c\xb8\x84\xe7\x95\xd4\xc3R;d\x0c\xc5\x98oj\x8c\x8c!R\x9b\x05\x1d6\xa3)\x98\xaa|\x1b\x88\x95\xe8x\xa1$ nf\x11\xed$\x1a\xecX6\xb2A\x9a\x93\xb2\xff\x98\xcf\x1a\xf1\xc8\xb0\x9aR\xe8f\xb9f\x850\xa8m\x10\x10(\xba\x15\x80^k\x80F\xfeWX\xddx\xe3Tx\x7f\xd5\xbd\xf6o(\xd8\x9fd\xd8\xc16H\x15\x99P\xcfg\xa4\xccFX\xed\x9e*\x90*\xf4P!^\x91\xa7\xdb\xa5\xabJ\xc8!h\xe8[\xaaR\xfd\xc0++\xddc\xd6K\xeb\x9c\xe6\xd0\xb5\x9e6\xa6\xd9\xff\x06\xeb.\x1b\x9b#\xd9\\O\xac\xa7\x8b\x8dj\x9f\xcb1\xca\x8a-uh\xfc\x9e\x96\xdfm\x1d%sR\xcc:aN\xa1F\xf9kJl\xb7\xffU\x8f\x1f]s\xd1M\xcc\x92\xc6m'\xa6\x11\xde.\x9b\x95\xfb\x9d]3/\xcf\xd8{\xf5q7k\xb7mK\xc74\xa5\xb1\x1bv\x1aI\xae\x0b\x85\xf6\x88\xaeZ,\xe4Azh`Ce\xfbk\xe8k\xa2\x14\xbf\xf9\x14G\xa68Xr\xfb=\xd1\x10\xee0\x82\xe7\xc43\xc2\xf7=\x1f@j%\xa9\xdf\xd7\xe6P\xec\x1f9KnNA\xf7\x96'Ga\xe8\xca\x9b\xdb\x99\xe8\xf5\x81\xa0i\xff\xcf\xe9\xfbwc)i\x08\xe67Re\x01D\xd8\xdf\x9d\x83\xda\xcc\x81\xea\xfd\xf9w\x03\xe9\x02`\xe79\x89\xc9\x8b\"\xf4\xd9s\x12oow\x0d\x01Q#\xee\x83\xd6Y\xdc!\xb3$j\xdc\xfdR'\xc3\x1f\xcfy\xb2\x82\x19\x08\xe0g\x9f/\x12\xf5\xd5\xa5\x1ew=\xdeb\xec\xe1\xd2\xb5\x1e;\xcd\xf6,\x95c\xadg\xe0\xe4\xbb\\d\xcbn\xc9*.\xfa\xec\xce\xb5\xe7\xa0\x01\xa8\xf4\xf3u|\x19D>\x1a\x9eO<\x1e\x8f\xb2\x84Ko\xb2\x1e\xa6N\xd0\xaaM]\xa1<\xba\xf0\xc0\xda\xea@\xbfe\xf3Kd\xab\x10`sn\xca\xe3\xe9\xc1\x03\x12\xa0\xdaq\xf8\x06\x13\xdc\xb4\xa3\xaa\x85;\x1b\x88}\x8b\xcc\xbe&\x17\xad\xd5\xe0\xb8\xb1N\x9b4+\xaeZ\x84\xe1x|N\\)'\xe4pG\xa1M\xde\x00{\x0f\xf4\x0f\xc1\x8d\xeeX\xc4\xf2\xc5MD\x11\xd2\xad\xc4Y]\xb8\x1aD\xec4I\xe5]\xa1\xab\xbe6$\x93\x1d\x90\x18\xb5\xdc\xc9\xb8\\\xeai)\x8f1RcK\xb7VbH0\xa9,\xdb/\x91\x0c\xbe\x80e'\xca\xe2\x1a\x1c\xaf\x039\x8b!\xd6\xa3\x16\xf2*x\x03_W\xcfr\xd9\xd4JJ\xf1\xc9&\xa4[\x03E\x01\xb5f\xd9\x81y\xaec\x0d8.\xf3\xca\x8au\xe2\x01\xd9\xda\xaaC\xb6\x926u/\xe8\xdfl\x7f\xda\xb6Fs*\ne\xb1\xd6\x05\xa8\xf4\xab\xa4\xd7\xd66\xed\x1c\xe9\x05\xb6\xc5d\xa5KA\x08\x02\xbd\xb7~\x02\x9a\x06\x1a\x85\xdc\xa3\xed*I+\x1ee\xcbv=\xaa\xae\xaf]1f\xd3n#\x10a\xb5\xdc2C\xe3-\xea\xa0i\xf5\xd32\xaa\xaa\x82>\xdf\x8ej\x0c\xa2~\x9a\xc7\\\xc1\xb0[(3eb*\xdd\x11H \xa99?,\xbbdl\xa2zZ_(\xfc3u\x05\xcd\xe2\xcd\"M\x9dC\xea\xad\x04\x17f5\xce\xe9\xc9\xf1\xc7\x93\xb3\x8b\x97\xef/\xde\xbd?\xbb\xf8ptzzq\xf6\xe3\xeb\xd3\x8b\xf7\x1f/~}\xff\xe9\xe2\xe7\xd7o\xde\\\xfcpr\xf1\xea\xf5\xc7\x93\x97\xce\xed\xbfi\x08K\xeaR\x11\x15o\xb9\x1e\x0d+\xc0\x85\x1f\x94\xe0q\xa0\xf2\xf2^\x0f\x8e\xdf\"\xb3\x90V\xa4\xf6{\x90\xfa\x15\x9c\xe6\xe2\xc7Z\xad\xae\x88K\xc7\x86\x1d\xc8\xaf\x90[\x10\xe9\x9f\xacq\xd3&\xc5 \xe5)Z\xa6\x1f\x92\x8cl\x8b\x92SiN\x01\xd2\xc8\xad\x9d\xba\x9c}0$Y\xb9:*#\x1c\xe2\xee\xd9\xb8\xe9K\xc2\xd0\xa5\x96\x94\x8b2\xf6\xab\x17,d3\x92!\x01\xc4\x03\xea\xd5\xd7\x99[\xbf\xa8 V\xe4\x10\x0c[\xbc\x80\x98=\xb7X@\x08\x90\xc0PDo2\xca\xdbb\xf7OI\xea\x96\xfa\xef\x03\xf9\xd1\xad\xc9\xb0\x16\xe0\xb7]7\xa9\xe0\xc6\x0c{\xf4\xa4b\x8fn-J4\xf7 .\x0ef\xe1\xb9\xe4~\xfa0>rEv\xb36\x80\xda[\xa1,\x8a\x1b\xa5Y\x90l\x9dl\xda\xed\xe5\"r\xbd\x08\xa6$\xefX\x04\xdf\x96\xe8\xb1s\x1c\x06!\x19X\xe8\x9f\x8a\x037\xd7\x01xg\xa8K\xb6\xd2n\xb7\x14\x87&\x16\xf9e9\x9cm\"\xbf2l[\x8b\x14\x12\xa1\xeaJ\x99oU$\xa7\xbf\xaaN\xcc\xe2\xd5\x0ei\xe1\xbf\xc0\xe7\xa3\xb9\xf7\xec\x02\\\xf5-\xaft5\xcd+\xd7r\xa4\xcf!-U\xee\xeez`nt\xbb\xd0\xbcE\xa0\xf8A\x9aoz\x8b\x90\xf6\xbaE\x08;n\x11\xf4/\xfc\xb8\xdap\xb9j\x81E\xc9\xff\xd8\xad\x9e\x12\xd7y6q \x82\xfe\x1fmRp%\xaf\xbe\x1f\xe1w\xb9\x13\x1c\x159nC\xa1\xf7\xbf\x8b\x9c:\xe8\xbe\x1f\xb1\x9c\xf8\xa6fT+\xc5@\x1b\xe2p\xbb\x187$\x07\x9d\x0ed*\x96QnE\xd7V\xac\x85]\xb1\x16\xaa'n(\xc5 \xa1:F\xc9\x8b\x032\xd1\xf2\xb9=G\xf9~ g;\xe7\x03\xe9\xdc\x16\xe644\xb8r\xa9\xc8K5\xd7\x00\xc2\x9b\xe6\xfc4R\xfa\x1efUq\xbc\x94S\xfc_&w\x0f6\x95\xbb\xab-\x9eK\xc9hZ8m\xec\x10Rv\x8c\xfa\xbfD\xfcH7\x92\xfc%\xf5]\xd7E\x92v\x10\xe3\x92\x9e\xc2\x07Z\xda(F%%\xe2\x96\xfc5\xafH\x9d\x1ar\xab\xa8.\xb7B\xa4o\xcd\x15o\x17\x995+\xac\xc9\xc0\xda\xe6\xf1\xb6D\xdbf3#E\xc9Yi\xc1\x89P2\xea\x82\xdb\x8e\xee\xa1\xafY)\xc5\xd8\x90\xfd\xff\x96\x94\xc5\xee.f\xcf\xe4\n\xf8]\x19\xe4X\xda\xf2l\xaeg\xa3A\x9f*v\xc3\xa85\xfd\x90\xf0\xa1\x9dQ\x04Y\xbfv\x90\xd6\xd6\xec\x14\x1cGgC8;i\xdd`\x99\x0dE-\xc5\xe7\xa4\x06\xa9\xbd\x86\xf28B\x17V\xc7\xaa\xe0bU\xd0\x86\x05q\x04\x12T\xd8\x0fQ}M\xf0\"\x9a\xf6d\xdffg\xa5\x95\xbeg\xaer+h_DR\x1d\xca9;\xf9\xe5\xec\xe2\xf8\xfd\xbb\xb3\x93wg\x16G\xacD]1\xc3\xd0X\xa2 \x8bg\x0e\x07\xb8\xcf\xae\xbb\xbcR\xce\xd5M}\x17\\\xc6{UG\xe7\x19K\xca\xfaP\xb8\xaf\x03\xcc\x1d\xa4m14\xdd\xd8\xfe\x8f_\x07\xa7'g\x17o\x8f>\xfe\xf5\xd3\x87\xff\xb7\nH\xdeq\x1c\xdbVCf\xf8\x16\xbc\x1dIp\xdb/\xd7\xcf\xc9\xea\"\xb4\x8f\x1aG\x14\xb5\xcd\x87v\x9c\x809r6W\x89\x19Wz0\xa5\x92\xa0\xb0\x9f\xcf\xe2\x1c\x84\xab\x97V\xe7wp\x0c\x0d\x0b\x973\xed'\x1f(6\xb5\x83\xf8\xdd \xcbn\x90\xb5\xf5\xe6B?\xb0\xe1=\xa9*\xddZ\x15\x0cC}\xcb{\x9d\xe4\x00Qc\xb3\"\xeav3\x99y=\xe8\x02\xf1,\x04E8\xf3z\xa8oIU\xad\x059$\xee\x1c\xa4\xb9su\xe4\x97\xc1cVC\xb2\x1eB$\x9e\xc1@\x86\xe3yK\xb3\xe5xE\xaf\xdd\x95y\xc0\x0b\x80!Y\xd5\xce\xfc\x18|\xf1\xad\x80\xb1h/\xabB:\x95M\xb8(\x11\xe8\x91\x04s\x17CBg\xcbs\xdd\xa2L\xd9B-\xb7\xb7\x07C\x12\x0b\xf2b\xad\xf9|\xed\x81\xc7E\x9c\x7f\x98\x8f]\x7f\xab\x9c`>h\x1a\x03zR\xbaUk\xb2\x89\xf5]\x980\xc2g\xde\xf9\xa0\xcdm>\xf8?\xd2\xe8}^\xfa\x0fi\xd2\xb5\xcdK\x17\x82\xf6\x00\xc3\x7f\x91\x95\\o=\x087<\x05\x9b\xe7^f\xfah\xb5\x84\x9c\xec\xd3\x81bA\xf6vLF\n7\x05\xe6\x92|!\x80\xeb\x96y\x1d\xa8\x98\x94\xf4g\xfb\x9eU'\xef\xdb\xf7?\x9d\\\x9c\xfc\xf2\xfa\xf4\xec\xf5\xbb\xffl9|\x89y\x00w#?\xe3\x1c\xae\xf4\xa9\xbb\x94{\xcd\xae\x11\xaf\xac\xc7E\n\xb1L\xed}\xcd\xeb\xc7\x13\xd8\xc3\xef\xde\xbf<\xe9;\xab\xdd\xe3\x7f\xd7\xfd\xdbB\xa2\x93\xfeT5\xe9IY\x93\x8em\xdbkV\x9bg\xf8-$a\x85\xc5w\x95\xb4H\xd4\xa9b\xe0\x05Qe\xd4\xbbm\xe6Q\xd5s\xcd\xe9\x0b<\xf8\xb0\x19b\x8f\xe1w\xf0\xc4\xde\xfcH\xbaBl\xb6\xf4O\xf8\x9bEt\xedA\xea\xadD\xd7\xa5\x9b'\xd4\xd6W\xb9\x17\xa8\xfb\xe1 \x86\xa7\xae\xfa-8)\xa5\xdb\xbb\xbb{ \x97\xde\xdd\xdd\xad\x0b\xb4\x89\xa1x\xb6_\x1b\xb4\xdau91\x85\xccy\xc7\x81\xbfV\xb6\x1b\x86\x17&\xd60Z$\xe6} \xa8\x89H\xa1\xb7\xb4\xb3\xe7\x82^i*\x89U\xc7FV\xbfu\xa0*x\x0fN \x11\x15\x0f\x81=.N\xde\xfd4%N\x9cp?\x87^ \xe8\xe4\xe7\x93\x1f>\x1c\x1d\xff\xf5\xe2\xf5\xbb7\xaf\xdf\x9d\\\x9c\x9e\xfd\xfa\xe6\xe4tJ\xb6&\xd5F\xd4FJ\x8b\x0b\x9b\xdfE\xa4\xd8\x1b\x13M\xfa\x8e\x8a\x0dL\xb5\x80v\xb9j\xdd0\\?Z\xbc.>\x9d\xcb@\x01\x1b\x88\xf1\xda\xba@\xa1\xc2\x14\xa2U{\xe0k\xd7\xde#\xf0\xe9\xd1y#+\xf8\x9c\x0e\x9e/n\xf1\xbd\xa4\x1f\xd4\xba6\xee\xcd\xf3 \x06\x15\xd8%\xb8\xd8b\xb3\xf8\x1c\xb8\x0d\xbf~G\xda\x8f\x1d\\\x83\xf5n_k\x1e\xbd9@?(p\x97C\xb2\x1e\x0cH2\xae\x07Sq}`\xc3\xf2!\xf8b\xca\xa4\x1f\xa2\x96\xb1\xd3O\x0f\xbfJ\xfa\x91*JTV\x9dT\xa8W\x1f\xdc.\xd4\xbd\xa2\x8a6mM\xfa\xc4(#\x06w\xcd\xdd5l\xfa~\xa5TOW\xfd\xa0\xc57\x16\xd0\xfaZKW\xf5\xa5\xdb\xaf\xbeH\x8a\xcf;\x98Z\xd2\xca\xd8\xb6\xe7\x96k\x9c\x0d\xc8V\xc3\xc7[\x0cV&\x80\xf8\x90\x05.\xcd\xf5\xc1[[|.\x98\xf5\x8d\xa7\x0em\xd7]Y\xdc\x96\x13\xbdj(o\xf1vG\x88\xc5\xe3]\xd4\xb9\xa55r\xc4O\"\xf3A\xc6\x84\xa3\xb4\x8c~\x90Q\xa9\xa4\xd4\xd0\xb1I5\x94\x17|_\x07\xca\xb5\x8c8\xac\x1f?V\x13p+z\xa2\xf3*\xdc\xa2d\xd7PV\xa7\x96\x8bs\xa5dW\xf7\x89\x99*U\xbd\xba#\x80P\xb5\xa5\x9e\xeeU|h\xee=y\\'P\xe68\xe5\x13\xcb\xfa\x1a>9}Y\xdf\xbe\xa2w&\xf5\xea\x96\xaa;\xf5v\xacK%\xfbzO\x05Z\xaa9\xce\x14Xd\x17\xbb\xd2\x07\xc7T\x7f`\xb7\xf2\x97\xe8\xca/\x15H\xcb\xe5rS:\x7fU\xd1 M\xdf\x15\x18u\xc8\xc8\x01 \xc5\xbe\x96:\x89xX\xe8\xc6\x02\x85\xbb\x0b\xe9\x94Z\xaa\xf7(\x12^*\x97Wbf\xd5c\x0d(*B\xf5\xa9\xa2\xb5_]\x82\x17\xcd\xb1\xbbB\xe9$\x8fGi\x96\xe4^\xaf\xebALM\xcb\x88\xf3eq\xf7\xeb\x89\xad\x9c\x06\x19;\xbb\x89YA\xf4\xcb\xbc@i\xc6\xd4\x92\x8d\xd0\x8f\xcd\x8c\xca%l-_\x0e\xdb\x0f4\xf3\x96\xd2\xffZ-?f\x91\x1fD\x8b\xb2\xedH&h\xd6\x80\x03#<\xff\xa3\xf4\xb9\xa5\x15\xeb\xb6&\xb5\xfcW<\xf1\x98\xbc-\xa8dk\xc1\x9f\x18!d(\n\xb9\xa0\xc6|\xb5|\xb5>j\xa9\x80,\xdf'r\xb1\x16C\x9e)\xafOJi \xef\xc71\x0d\xc3K\xea}N\xeb\x1f\xa2ah4\xe3\xe7 \x0c?I\xa4\x0c\xddi\xac\x0c\xabZD[\xe46\xab%z\xbd\xb3\x1c\xed\xe9\xc5\xf66\xbaV\xb2\xd6\x85b'\xdd\xe9\xd0\xb8\xf3\xe9\xaf\x83G\x14\xe6U\xe3\xaa\x14}\n+\x11{!\xcf\xf61\x1ce\xe8g\x0eJ\x82\x0b\x96\xc9\xe5%\xbdl\xb5|\xc6o\xf5\xbeS\x7f\x14v\xd9r\xb7X\x89\n\xc1\xfa\xd8x\x1f\x07)\x04\xbe*f\xb7\xe5lv\xbd\x96\xb6-\xcb!\xd08\xa8B\x08I\xca\xd0F\x13\xfafD\x86%1LV\x97\x1ay\x1f\xf6\xf2eF6\xe8\xf8\x87\x9d\xe9\xb3tl\xb2\xeb\xb6N\x05\xd2\xb8!\x91\x1e\x06b\x1eD\x99-\xa0\x07\xee\xaa^?E\xd4Vl\xa5V\x9b\x83#f\xed\xda>o=\x0e\xc6 \x97\xa4\x91K\x07u\x1c\x86\xee=7o\xd9\xf9\xa0\x96]\xadC#\xa7\n\xdd\xf0\xc1(Y/`2\ne\xaa\xc2\xc2\x83\x016\xbeV\xba\xb2\xc9bo\xed\x808\xa2\xd2\xeb;\x0fu\xdbZ\x0dn\xb9\x1ao\xb5\xf8\x8aq\xd6\xe3f\xa7IZ4_\x83\x12\x83 \x8a\xb8@|.\x96\xe1v,\x87\xa0\xc7\n\x08\xf4\xa4\x07\xe5<\x0f\x86\x15\xc1~\xa1\xaan\xce4\x90\x0543&\xdc\xb5 \x03\xd7\xca\xe5\xbd'\x90\xb78\xecQ\xcf\x18\xa4\xa1flp0H0,b\x08\xe6\xcd\x81\x07a|\x95|\x02i8\xdc\"x\xe3\x93\xb7\x1f\xce~m\xbf>\xb2,hI\x85\xcc\x11\x15\xdeD/\x92*\x81\xbe\x0cB\xdf\xa0\xd2\xb1(\xde\xc8z\xec\x1f\xd2\x8a\x187\xb3\x15\xb1\x9f\xa5\x03\xbd>\xbfi\xf4+\xa2E\xf0\x96ov\\\x02d\x8dmc\x97\xdcII\xbf\x87q\x8c\x0f\x1e\x90\xad\xac\x8d\xa7\xecs\x87\xd0\xc1\x92\xee\x0c\xdb\xef4\xf4S\xb9\xb8, \xbam\xe2\xa0mw\x07\x1d\x01\x05\x08\xe8w\x07\xd1\x9a\x7ff\xff\x99\xd3\xc4g\xbe\xe6\xa9A\x05\x00\xadU\x9a\x93e-!E )\xac\xd6\xf1*\xda\x82a\xd9\xb6\x08\xe8i51\xbf\x05\x1c\xd3W\xba\xa5\xd8\xa2&\xe1\xf9\xf6\x14r%\xdb&\xe3h\x95\x03\xe1\x92\x16\\\xb8e\x93\xb4\x84:p\x99\x8dE\xec\xb3\xe5/V4\xfd\xac\x10U\x9f\xed\xben3\xa7\x04\x1eVuM\xcc\xa3%\xec\x07\xf8\xdb-C \xc4v\xfc\x8e\xf9\xc1\xd6O5~N6 \xd1,9o\x0d`c\xf5\x14\x87\x8dKU\xd2\xb2\xf9\xd0\x18\xe3j=\xf2\xf4\x99\xb3Q\x83\x8c\x93\xa5w\xabL=\xfb\x8d\xa4AM\xca\xc6>\xa5\x81t3[6\x8f\xe8\xe8\x0c\x8d\x1c\x19\xa8\xa1\x0d\xa1VC\xf0 \\\xb5\xf2rpl\xac\xb6\x82\xa5~\xba9K=\x90\x1f\xc2j\xd5B\x8f\xfd\xcdj\x15g\xbe\x1d\x89\x96.w\xbf\x02\xdf\xdb{\x0f\x13\x83\x1d\xeb\xb5n\x80`7;\xd4_\xab\x0f\xf3\x81\xd1H\xaa_X\xf7\xaf~]Q\xbd\xef{\xe5\xceM\xa1\x9e\xe8T\x1b9\xd9\x86\x84\x95\xdeCyP\x011\xc7@I\xaa\x9f\xaa\xa4b\x1f\xe4\xd9\xf0z\xfe\x8e\x89\x0dJ\x93\x9b>\xfb\xb2P\x8e\xc1\xdayH\xe6ME\x80\xcc\xb0\x14\xab\xc2\x0f\xcb\xfb\x11M\xc7\x97\xce\xa8\x0f\xac\xa7\xe1\x97/\xf6\x83\xee\x10\x1f\xa3\xf2;\xd5\xd9jO\xad\\;\x99M\x94 \xb6\x1b\x95>SPk z\x0f\xd0a\xfdI{\xe2\xb8\xc8\xf4\x97 0\xc2\xde\xa6\xa2\xbb\x16\x16i\x08\xbc\xcc\xd6\xa4m1\x17D\xc3\x81\x0c\xd2\x9b\x83\x11\xb8N\x9dJ\xd7[jF\xab\xf7\x04\xc1@\xd5o\xd3\xbeX+\xc7&\x9dW\x11\x10\xe2\xd8\xe6\x1d\x88\xc0\xd5#X\xe5\x03\xeeW\x9f\x1cJ\x17\x98\xb4Ji~\x94\xeb\x1b\xbc\xa6td\xbb\x9e=\xa6\xd9Z\x07\xfe7\xfb]\xe1r\xa1\xb0\xbdGq\x8bw(\xeb\xf6\x80\xf8h\xe3t\xc9\xf3\xb0$K\x8b\xad\x13\xc3\xc4\xa0\xb9\xa25\xf3\xa1\x8c\x82\xacg\xb5\"\n?8 \xd2\x8c\x03\xda\xe5\xbb\xe1\x90x\xb0\xac\xb6|\xf1E\xd1\xa3!\x99\x03\x9f\xde\xbe{\x86$&\x87\x9a7\xeb$e\x01\x91\xd5\xdb\x1aI\x9d\x19\xb8(ab\x17\x81\x95 \xb6\xd5\xc57\x9b\xb4m0$\xb4\x10\xea{\xe2E\xcb$\xe6Cc\xe5\x1e`\xa6=-$\x909\xbb=\xd5O*|Y\x0f)My,5\xd0f\x1fb \xe1,\xect\x93\xb5\x08\xc6m \xcc\xccVii\x11\xb5]dHGo\x0f\x1e\x90\x89r\xa4+\x1d\xc6\x14\x85\x93\xd9\x8e\x85p6\x88\xb1\x03E\xb2\x08\xfc#\n\x88sF~T\xb9\x84\x13\x19\x132%;\xcfI^\xf1\xee\x96\xb7\xfb\xc5^\x1bf\xd9v\xb2\x89\xbbtH\x1c=\xe5\xa6'\xc2\x94\x1c\x92T\xea\xd8H\x8dE\xb9\x1c\xa6$\xbd\x05e\x85\xf8\xbf\xc1\x96#\xbakn\xa1y\xad\xaf\x87\x87\xda\x13A\xdfe*\xb0\xf1\x0f2d\x9b\x1bV\xee?d[,8\xd3#\xda\xe3O\xa8%\x809\xbc(\xf4\x02\xbe:\n\x91\xe0\x90\x845\x19\x81D \xe07\x0b\xc9(\xee\x03p\xaa\xc0\xd4\xe6\xa8\xa0\x8a\xb0@\x15\xd9P\xb7E\xe2\x95\xd0@\x15I\x15\xef}\xac\xcb\x06\\\x18\xe8\xa1\xec#o\xbf2\xc2\x86L\nO\xc2B\xe9Ut\xbf\x1fv\xb24\xe8V\x18\xaa).iEU\xd1m\xc8g\xbb,\xb7\x1d\xc5\xd9\xa4\xd7s\xe2.]\x10\x95\x0f0\xf2URb\xacMP\x9a\xd9\xa4\xc8\x1d\xca\xac\x1a5U%\xa16{Y\xf1 r\xaah\x88\xbb@\xd7OS\x92\x8d\xb9\xdb\xd6Ou\x1a\xbb\xa5\xd9d\x03\x896\xef'\xd1&-\xb2\xba\xd6\x90\xac\x9a\x18\xc4\xc4\xdd\xc5\xfc\x95:1fJ\xcd{E\xdbT\x8bm\xda\xddp8\x0d\xc5\xf0\xfd\x1cdK\xe9]@\x1c\x01!\xca\xa2\x91\xdeR/\xb4\xe2\xfe\x9c+\x1d\xe3-c\x1b\xd8\xd9Y\xf7\x9fy\xb9\xfb>i\x8az\xda0\x08\xeb\xc9\xcb\x14\xc62\xb2\x11\xee\xddZ\xdc\xb7q]4P\x95\x14\x16+|\xd1F2\xe4c\x85\xf4T\xa7[VS\xeb\x95\xafx\xba\xaf\xb8\xd0iA\x06N?_\xc9<\x88h\x18v}\xd9\xec\x05\xca\xf5\xea\xa7\xd5\xf9\xec\xad\xdb\xdf.*\xd5\xdaA\xcc\xd0\x0eb\xa8v\x10+\xb5\x83\x9em\xc8\x16\x0f\xfbI\xb2h\x96Qo\xf9\x91\xcdos\xa2.X\xf6!\xbf\x0c\x03\xafp\x94f\xe9\xb9\xe6\xf2#\xcd\xe5Ov\xda\x18w\x194\xa7w\xedn\xa4\x14\x99\x0e\x0e\x80=\xd3\xaf\xe4\x8f\xaf@I\x8b\xb7\x81\x0c\x04\xd7\xcbv\xc7g\xc8\x98\xd8\x06D\x05\xd5\xb3\x8d\x07||\xc6\xce\xfb|W\xcdl\xdf\x8d\x7f;\xe1s\xf3~\x10\xcc!*)\xe3B9\x86[\xdcQ\x15\xa8\xae\xa6\xae\xa6l+j\xa9\xacPbS\xf9\xfa\xb5\xaf@\xaa1\xb0\x1b\x8fQ/\xcc\x8d!L\xedc\x02\x96\xf0\xb4\xdf\xa6\xb2\x93\x19\x88\xcd\xaa\xc56R*X\xdd\xc9\x96a\x82\xd7l\x1d9\xcd\xb2no\x17\xc9_\xef\xde\n\x94\xb1<\xbdY]rp\xc7*\x7f\x8d\x057\\ys\x9dD\x8c\xdc\x98\xc9U\xed\x00\xba{\xb23\xd9\xd9\xc3{\x95\xfc\xb3Z*\xa3s\xf2\xa4:\xed\xe0W\xf3\x7f\xffo\x9dy\xeb8\xcc*\x04\x0c\xa8\xe6\xcd\x92s\xd8=3~^\xc3|\xe0\xb3\x1dkmy\x01X\x0f\x0cp\xab\x91i\xb1\xb2\x95V\xb2\xcf\x1b\x9d\x90F4\x9b\x19\xc7\xf2\x0e%;0_\x12CR\\Y\x19\xc1\x12\xda\xf6?\x18/\xb53^\x86^\x0e\xb7\x9a9\xed\x0c\xa5\xa9md\x1a\xdf\xba\\\xda\xddvG\xb8\xaa\x0e\xd2\xbf\xca\x04\xd7\x16\xdc\xd5r\xda\xe3\x96\xb4\x08\x02m\xbbS\xd6(\xc5\xd57@-\x8e\xd3\xbf\x891\x17\x1eb\xe4I\xdd3\xba\x0e1\xf2\x14\xb1\xe6*\xcd\xad\xf6'\x0d\x07\xa79x\xa4\xaa~\xbai\xd9\xacd#\xd5S\xabb\x1e_\xfc.6E\xd8D\x12p>%L9\x8f\x0d~g\x10\xef\x97\xaa\x1a\x87:_\x90\xaag\xfc4\xa3Y\xe0I\x1e\xca\x10\x0f\xe5);6\xa3\x19\x9b\xf2\xd0\xbc\xb4NP\xea\xe5\xb4\xd5k{\xd3\xdd\xa9\xe0\xe2\xcb6)\xe5\x8a\xb4\xe3\xb4V\x8b\xa4\xea!\xa8v\xac6EN\xfd*M;*5\x0c2\xfaUX\x1f\xa8\xb6\xfa}\xa6\xa9\xa8\xda\xccW\xc1J\xed\xcfV0\xad\xe6\xd9\xb2\x8a\nP7,\x0d \xc03\xaa7\x18\x12>\xa6\xbe\xff\x81\xf30\x88\x16g\xdc\x0dk\x18\xe1^\x1c \xef\xee>2\x10\xbfD\xfa&\x14o#@\x8a\xb5\xcf\x9a\xe7\x0d\xa9\xc5\xb8o\xe1Q@\x15\xc6eD\xd3|p.\x0eH\xb6L\xf8\x15\xacjA\xd8I\xfd_\xe7\x98F\x11\xcf\x88\xc0<\x84\x12/\xa4iJhJh\xf1%\x07\xc1\xee\xea\xd6\xb8\xd0\xb5\xca\xca%/\xce\x83\xea\x92\xa8\xce\xa1\xa6\x9bM\xf3\x14X\xd3\xac\xdb\xe6G\x9b\xbb\xd4\x10\xfb\xb0R\x9dB5Z\x81\xaa\x8e\xe9-\xf2\x97z7\xc6A\xfa:\xaa`\x17\xe0\xdc\xea\xb5\xe3\xb2\x19\xbcE\xd5k\xb2\xf6\x9en\xd8\x1c\xa3\xea\xba\xc3w\xbc-\xb5\x0b\xa1\xceU\xb5a{\xcc\xea\xdd\xa6\x1e\n\xde\xa6S\x96}\xab\xf6\xe8\xaa-m)1\x88\xc9a\x9b\xa8\x81\xdf\x07j\xb0\x9c\xc5\xfb\xb6\xb3\x189\x8a{\xac\x1a\xe4\x0e\xb5f\x87\xfa\x8e\xfbu\xa5\xc5[\xdb\xad\xfa|%\xf5\n\xab\x83jbbjb\xe2j\xa3\xbb\xcd-\xad\xbeb\xa8\xbc\xa0\x08\xfcc@\x1e\xc9\xf6v\x93\xf8\xaa6\x91\xa2\x9d\xdd\xd4\xf0R\x0b\xec\x1d\x02\xec\xd9\x88\xad\xe2\xecfJ B\xa5\xf1\xb9m\xe2\x10D\x0bW\xfa!\xa8\x93 m\x14|*\xfb\xc9\xaf\"\x96\xbc\xe4^\x0e\x12\x0e\xe55\x89\xaf@HfSb\xd06\x0b\xe38a\x1e\xf5\x96\xacP\xe5\x967P\xdcEn1\x9b\xf2\xc0\x9aT\xb7FX\x1d\xca0^\xceo\xd7{\xde\xd6h$\xc6!\x17\xbd\x1f\x8d~\xbb\xdecNm\xaf\xd5\xce\x02\xab\x8eW\xf3\xf0\xef\xaf\xc4^t\xdb\x1a\x04\xba\xadQ-\xda\xea(\x930\xce\xa3\xea\xd8\xd6j/qK\x8d\xda\xa0\xf7\x82R&\x15b\x03\x0f\x1b\xc0Q4\xea\x14\xb8\xc0\x01\xe7\x19J\xd0\xba\x07\xd1]j\x99\x99\x91Y]k\x86\x07\x0eP.\x06\x86\xf39\xe1\xcfI3\x80\x1d\x89\xea\x9b\xb4\x12\xb5{G\x1a\x03e\xcf }\x0e\xbfh\xb5t\x80\x96~N\"2\"\x01\xf9\x9e\xec<\x1f\x80\xbc\x8bU\xaf\x91\xa2\xd1\x08-\x16\x90\x11\x89T1@\x04\xd5b\x01ZL\xef\xfe\xe89\xc9G\xa3\xe7v^\x1dB\x02\xb71\x8dHK\x1b\xad\xb0\xac$R\x15\xa5\xff\xa9 a\xae\xb3j\x0b\x83\xf4(\xf2XZ\xa5\xc8m\xa7\xacm\x89$\xc9lr\xbe\x89\x96W\xdb\xdc\xf5gIk\xea\n\x06\xea\xb5\x88\x08\xda8\x07i\xe8\x88\xec\x0e\xbcS\x05\xd1\x01*\xf1v\xa6x\x1c\xb1\xeb\xec4\xb8\x0c\x83h\xf1\xdcJ\xa7\x93\xda\xc5X\xa6\x14Z\x9e\x14\xd6q\x12\xe9\x0e\x86d_2A\xe3H\xab)>x@j\xf8\xcc\x80\x90\x11\x0d[\xbeJ\xcaE\\\xc7 \x16c-\xfd\xb4G\xe0\xb6;\xd3\x94\x04\x981,=\x17\x8d\x9e:A\xe1U\x0fx\x1c\xab\x9d[\xcedVWa\xba\x9b\xa8\xe2vD\x81\xc0\xd0\xb7\x15q\xdc\xcb\x85\x8aEj\xfa\x08'\x07\xf1\x1bL\x19h\xb1:x\x16\xef\xcb\xfafqJh\xf3\xb0\x15\x83\xd7\xb5\xd7 (\x02\x07)\xd8\xce\x04\xd1B\x85M\xb4\xb8\xa0k\x9b_Qfv\xdb6\xf2\xf1<\xcc\xd3%\xb4\x82)-\xf4T\xaa\xa1\xf3\x86\x04Gv%+\xbb!e0\xc9`\x08\x85A\x17m\xee\xd6<\x91}%W\xcb d\xc4\xadKT\x8cX\x82 \x97\xe1\xe4E\xa5n-b\xe1 \xa1\x81\xc5Qd\xce\xf8\xf9\x90,\xc7\xcaC\xd7\x99\x9a\x03\x97U\xa6C:\xb53\x87j\xd8\x18;\x1c\x17\xc7v.\xde\xa6\xa9\xd1\x18&lu\x18$Du\x81\x18\x19\xf5\x01h\xde\x19\x96M\x06n\xb1\xa2\xaa!\xf8\xc5qv\xc5\x8f\x92\x05\xf0\xb5\"\xa7\xe2dx\xad\x1c\xefW\x1b|\xc1\"z\x192\x7f*0d5\xa7:\xc4X\xdc\x95\x9f_\xbf{\xf9\xfe\xe7\x8b\x1f\x8f\xde\xbd|s2%\xc1\xd8\xa3\xd1\xa7\x94\xbd|\xff\x96\x1c\x92\xab \xf2\xf9\x15\xc1\xca\xa5,\xfb\xb1Vy\xbb\xe4\xa81\xe1bQT\xc7\xa6\xf1\x85\x13\xdd\xb1\xce\xaa\xd5\x10\x88Sb\xab\xb5\xd6 mV\xdar\xfc\x96U\xb7U\x9a%4\xfeAJ\x1faQ\xf4\x13V\xeb\xdb\x0drH\xf8X\x06\xf0W\xb1\x89\x96\xa0Z-\x0e@\xa8N\x124r\x99\xb1\x81\x16\xd7v5\xe8X\x892o\xdb\"%\n\xbd\xaf&\xadx\x14d<9\xf5\x12\x1e\xca\x88\xe8]\xd3\xaaQf;\x94x\x98\xeb\xb9r\xad\"\x8e\x9b\xbeV\xdb\xda$<\x8a\xc1\x97U\x0c\x89\x93B#\x1dD\x8d\xa2\x8aN\xcc\x11\xe9)\xd3(\x17T\x1b\xd1$0f\x0c\x86\x06\x02\x05\xb4\xc6\xeei\xb7\xcfI\xc7U\"\xce\xf5\xedr\x81\x1eF7\xf18a!\xa3)so+\\(\xde,$\xd7\x12RoEr\xf5S\xc1.\xc4`?K\xe4\x067\x1d\x86\x0eY\x91q\x88\x8c\x03\xc4\xc5\x8a\xe9\x82\xfd\xf2~>O\x99\x0c\xd82\xf6\xb5\xc6\x82\xfe\xa1m4\xe4:z\xc3\xe6\x88\x00\xf5FW\xf5\xeb\x06U\x9d\xf1\xaaX\xf0+\xc1\x82\xceC+;\xbfm\xa9\xf1O\xd5_\xb7\x9a\x89\x92\xf8\xdd\xaf3\xaa\xea\x9acb!~\x1b\xd7\"\xed\x81\x16\xf6\x9e\xe0\x91\x16&\x8f\xeb\xf5\x84\n\xbe\xde\x1e\x0f\xa7\x97q\xbe\xc9\x10B\xd0q\x10\xfd7\x83qi\x8e\xef\xcb\xf7ou\xfc\x8d)I\xda OVqvcT\x9b\xb7\x02\x0b<\xf3!\xcc\x17A\xf4c~)\xb8\xdf~\xc0\x9f\xb2 L\xc5\xd9\xde\x05~\xb2\n\xb2\x8c%S\xf0\x9bg\x05\xfd\x11t\x88\x8a&\x87m\xb0\x05\xef\xe8\x95P\xd5\xf5\xf6/\xe0\xbc\x1e\xd7\x99\xa6\x00g\xb1\xa8e-\xa9\xb5\xf7\xb4\x9e\x9eV\xd4\xc8'\x8f\x9e\xd6\xd5\xc8\x15\x17\xb6[\xff\xbe\xd7-\x03\x01\x8e\xe0\x94\x85r\x08_G\x82\xd9\xa5\xf8\x98+\xd9H>N\x80\x16eE\xa9\xea\xc0c\xf1\xb9\xcd/v\xca\x7f\xb4\xbc\x97\x8e\x0b\xa2\xaa\xc3&\x92\x8eK\xa2\xce\x85X\xe3\xbd\x0c\xad\xea\x02)+\x1dP\xa9\x1f \x94S\x17D\xddu\x04\x94\xa4\xa8\xa2\xb0.F\x9da\xc6\xad=:\xb6\xd1w\"\x9e\x05\xf3\x9b\xa30\xc4\xbeU\xed(*\xf8B\x98\xfbv\xc9W\xbb\xe5Aa^Pk'\xa8Q\x94\x94Ldx\x99D\x8c\x14\x0c-\xd5\xca\x86\x8e\xef\xd5\x06\xc1\xab\xad\x83z\xc5\xb7\xb2A\xc0:\xdf\xf1\x9d\x8d\xcd\x12Z)l\x9b\x81\xc1&\x0d\xae\xf8\xa8n\xfb\x18b\xa6`W\x18hl\x11\xed\xca\xba\xa1\xc6]y\xed\xcd\xae\xf3\x82,\xc5>7\xb0.\xcc&\xcfR.\xbf\x12\x91%\xee\xdc\x14)\xa4C\x12\x0f\x86$\xa8\xf2\xee\xf3\xba\xe1\x15\x14\xbf\xe3\x01\xd6\x90\x05*]\xea\xddz\xdc\xa7@\x1dl{\xa8\x18\x8f\xb6h)\x94\xd78\xdap[*\xa8%\x96\x8d\x98KO\xe6\x85\x90\xe0\xc1\x03\xe2\xa4\xfa\x80\x01\x85/M\xb9\x8a\xac-\xd71\x8f-\xc8W\x8cZ\xf3\xe8l\xce\xeb\x82e\x928N\xa7$'\x87=N\x00\xcd3\x16tt\xd16u}\xff\x91F\x8b\xd6\xa0,`\xdb1\xce\xd8u\xa6d8vP\xb8\xb3\x1d\xfby\x1c\x06\x1e\xcd\xac\xd7\xb5 \x84\xaa?\xe3\n\xcb\x9dI\xb7\xa6C\x92\xc8\xd3\xca\xff\x00\xbb\xcd9\x89|@\xaaI\xe6\xd8\xb9=-rK\xcc\x16\xb6\x9e\xb9-\xbc\xa1\xf8VC\xed\xcf|X\xe4OA\x03\xa5\xe9\xf7\x95\xe0\xcc\x1e\xe9\xc2\x07\xc4\x98$\xb9\x12*\x84\x8dX4H\xb2mh\xe5-\xb1`\x9dv\xd4-k\"\xe6\x174mz\x86\x05\x95\xf3M#o\xc9!\xdep\xd7tKH\xb9,\xed\xb0\xd2\xb7\xc1\x9c{y\xda^iP\x02v\xd5\x99k\x7f \xb0\x86\x8f2\xd7\xe6\x91\xb0]$\x90\x8fa\xe2\x0b+\x80\xe2\xeazH\xf21\x8b\xfcf\x06>\xf9:XC\x9f\xd8=\xa8\x07\x00\x82.!b\x98\x04P\xb723\xf5\xd1\xaf\x8cpu\x14\x07\xe4\x90\xec\x10A\x04g\xfc\x14\xd40\xdcA\xe7~\x0eA\xf2\xee\x85<\xd2h\x02\x1f\xdfPa\x15\xf1]p\x06\x12e)\xec\xe8P\xedh\xb7>\xc6C=\xea\xaau\xf6\xe5\xe8)\x0d\xa7z\xf9\xd0,/^\xcd\x99R\xef\xd5\xae\x87\x9bt]\xf0\xbb\x1e\xd9&-\xee+c\x13\xadV\x90)\xde\x9bX\x0c\x06\xe03W\xb94\x8b\xf5\xf0p\xbb\x03#\xad\xd2\x14\x8f=\x1e\x864N\x99%`k_\xf4\xe6\x8bs\x83L\x89\xd7\x81\xe6\x04\x9c'\xd0W\xcfu\x8a\x90\xf3\xa9\xf5\xb8\xear\xb52\xd4\n\xcb]\xe7V\xf7icX\xbagbQ\x90CIL\x00\xf2\x801!\xd3\xe2\xd7\xf7\x05\x8c+\x01X\xe4\x0f\x15\xa2\x03\x08\xf0Zi\x94\xd5\x99,\xf2\xc1\xd4\x14?\xd9d\xba\x9c{\xc7[\xd2\x84z\x19K\x1ci\x19\xce[\x8e=^\x14\x16\xcb\xa4R4!\xa3\xa2\xb8\x18\x1a\x8c\xeb!=\x84\xb0D\x1d\x1b\xc8)\xd3\x86\xc8\xf4Q\x81\x1eN\xf6\xa5E\xd4\xb9\xc1f\x81;8\xef\xdc\x86DI\x1d\xde\xd2l9^\x05\x91[\x0e{\xc7G\xf2\xaa\x93\x03=\xad\x94L\xcd\xca\xe4\xf4\xb6\xa9\x95\x89\x035\x1a\xb3\xebL\x94\x7f\xf0\x80P\xf2=i\x0d\xc7C\x0c|\xdd\xe2\xa0\x8d\xa86Ri\xff\x92Z\x01\xed\x9aJZ9\x15\xb4\xd6i\xc7xx\x1a\xd0f7FTo\xc1\xe9\x87\xd7\xa7\x87\xf3\x0d\x11\xa0~\xe6%\"\x0c\xe1L\x15\xe8\x9aK\\=\x04\xc7Eb\xc1\x1f\x85!\xd4\x96\xba\x10/\xe8{\xc0 n$\xb8\x0c\xf9\x959\x00\xcb\x99q=U\x91\xa7+\x82\x8d:\xd7\x08\xb6\x91-\x8a\x1a5\xe1\xc2{b\x1d\xfeN\xb1>.\xc5\x93\xb3\xbc\x11\x13T$\x17\xdcKbWB\x00\xe1\xfdx\x1e$\xa9t\x91_(\"\x18I\x95\x82\x9a\xdb)\x12\xb1\xdb{n\xff\xa0\xdd\x16\xca\xd4\xa0+\xf5\x1a+\xea\x86\x8d\x82\xb2\xad\xa5\xeaCuH\xff\xd4\xfc\xd5\xdb\xb3G\xc5`-\x01\x9cl\x18\x9f\xed<'\x91\xb5'{\x92\x13,\x88\xbf6\x1cJ\xc1i\xed6\x89\x80\x1bQ\xa4\x90Fr$ /\x94\xea$%\xdf\x9b\x86b\xf6\xad\x16\x81\x96)\"\xd3\xd4\x8f\\\xceS\x92\x91\x11\x12\xa6\x8a\x90FHi\xfd\x04\x851b\x05\xb8\x91\"\x07\x8c\xbb\xd1\xe0\x9b\x9a\x7f\xec\xef\xedX\x8c\xb0\x8be(\xd5\x9c,\xfc\xfa\x96b{\xb6\"\xb0\x01WVe\x11$%n&\x13\x137\x1a\x14\xfaR\xc6:\x13\xb8\xc2\xf1$\xf1\x98*\xbb\xb6C\x88f#\x93D\xb1)\xd9\xda\x92\xf1mhR(\xda\x7f\xe0i\xa0\xb9\xb4\xad-w\xf2\x84< V 1\x84\x0d\x15\x8d;\x0f\xdb\xa4c\xd8\xac\x17~\x80F\x1e< {\xe0\xe9\xa6\xc9\xdb\xdc\xa1}\xfd\xda\xa1\xb9^\x97\x899\x19W\xec+\xe0\xf2\x8fL\x8b\xe3e0\xf6\xd9\x9c\xe6a\xf6S\xc0\xaeD\xa6$;Pd\xb6\xe5nI\x17\x83\x16_Qc0\xba9\xac\xder\xaa\xd4)\xeak \x84:\x118D\xaf\xa4W\x95\x9c\xa5v{\x13\xe0\x1d]\xb1\xfb\x9dwg\x99e\xf1\xf4\xe1\xc3\xab\xab\xab\xf1\xd5\xde\x98'\x8b\x87\x93g\xcf\x9e=\xbc\x0e\x83\xe8\xb3\xd3\x94\x90!\xf0\xbf\xbc}#\xca\xec?\x8c\xe8\x8a\xa51\xf5\x98\xd3\x94\xa05\xf1\x12\xf5<\x16e?\xb2`\xb1\xcc\xa6\xc4\x91\xaf\xa3%\xbc#>\x9a\xa8\xe7\xe5\xab<\x04O\xd6;H\xb6\xef\x07Y\xb0\xb6d\x86\xc1\"\x12s\xff\x03MY\x18DL|O\xa7\x8d.U\"\xf6\xd10\xe4W\x1f\x19O|\x96@\x99\xf2\x15\x85\x8e\x97\xf4\x92e\x81\x87\xb7b\x15\x87A\x96\xfb\x966&\xf42\xf0^\xf1d%>\x04/\xa39OV\xd8wR\x0fn\x07\xb1Z\xb2, .\xf3\x8cI7\x88N\xe5\x1d\xabJ\xe7\x8b\xa5g\xc2\x8bw\x0c>\xcf\xf8G\x06\xc6\x92\x02\xba|\xc3`\x7f\x0fVy\xb6D\xdb)\xc6\xfcU\xc2\xfe\x91\xb3\xc8\xbb\x99\x12\xa7\xf2\x8e\xd4%\xf2?$|\x1e\x84LA\xab7\x0b\xac\x98\xcf\xd3e0\xcf\x14\xb4x\x1f\xa5\"\x01+p\xc9\xaf\xf1V\xb2E\x10\xe19\x01M\xf1\x8c\x1b4\xd9\xa3\xa1\xf7\x16\x0e`G\xffD\x1a\xe2\xd1\xb8\xd8\x0f\x1e\x8d\xed\x9b\xc1\x0b\x83\x18\xffN\x18\xc4\x1f\xa8\x18tG\xfc\x1c\xc54[Z\xca\x7f\xcca,\x01,\xc9\xd1\x91\xd4\xb5}\x8a\x02\xc1w;\x95w\x0c\x9e\x87\xb3#\x1b?\x98\xcf\xf3\x94\x1ds\xe9\xabsJ\x9cZ\n\xd2\x1b?H$go\xa9\x11\xbc\x9eZ\xf2\xd6\x81m |\xbe\n\"Z\xc1\xef:\xa9\x0d\xbd\xfb\xb9\xa5:|\\}\xbca\xcc_0\xb5\xb7\xf5O\xe4[,dkj\xed\xb8\xd4[\xfb\x81z\x9f\x17 \xcf#_\xd4\x05I\xa3\xcb\"\x0d\xab4\xc2'U\xd0L\x91m\xda\x04\x9b\x9bD4\xfc\xc8R\x9e'\x1eK?\xb2\x7f\xe4A\xc2\xe0\xa3\xb6<\xe4\xe3\xf3 \x0c\xd1\x0f\x88\x8c\xf71\xf5\x02\xf0k#\xdeF\\\xbeZjQ\xa8\x08 -\xa8H\xeew\xdb\xe72\x96|d\xa9\xacB\xfe\xb6V\xa1q\x99\xf1\x86\xc1\x86\x9c\xfb\xc7\x02\x13\x08P\xf12\x02\xbc`\x035\xba\x0b\xc0-\xfd\xe5^\x9e\x8a\x99\xc5\xfb\xc2\xa3\xec\x15]\x05!T\xc5\xa3l4\x877\xb4\xa2(;\x05]\n \x98\x06\xbf\xa3\x03\xa7\xc0\x8e\xfc\xff\xce\xd3\xcc\x04\x1eQH\xb2\x95\xc9\x12\x96y\xcb\xa2\x80|\xb5\x02\xdf\x84eC\xc4\x8b\x05\xf0'\x9a\x04\x12U\x00\xe8Z\xbeZ\x80\x7f\xd6g!\xc0^\xd9\x0eC\xa9\xae\x83\x0fg\xc2Wx\x06\xbe\xc3\xe7\xf8\x0e_L\xf0\xe4]<9\xbc\x89\x97\x8a\xfe\x82\xdf\xa3\x08'\xbe \xf3}\x12\xb0(\x03\xcc\xf0#O\x82\xdf\x05\x9f\x18\x16%y\x99;Z\x16\xd9=\xea\xfa\x89%Y\xe0YjZ\xabL[=\xe0\xb8\xdb\xd1?1\xa8\x84\xfa\xa2:\xd0\x12\x99K\x9a\xb5\x91\xd6RNo\xc2\xca;\x02\xbf\xa4\xd1\x02Ned\x98a8\x8e\xfc\xf5/S\xe2\xc0\xef\x11\xf5\xd7\xa3k\xac\x16\x91\xfb> \x16AT\x02sxG\xe1\x03\x9f\xf1EB\xe3\xa5\x85\x90\x0fVt\xc1L\x92\x01\x12ZI\x86 \"xU\x11\xbe\x86\x80\xd8\xf1X\x8c/\xeb\xcfx*\xbeJ?\xe3_\xf8\xbc\x87'?\xc2\x93Y\x12\xb1\xf0-\xcd\x92\xe0zJ\x1c\xf3\x15\xe9\xad\xcc\x16\x93\xfa\x06\xe4UE\x892\xc9R\xca6\xd9\x9f\xd9\x0d\xdci\xa4P\x95\xfa\x8d\xd6qs\x1a\x8b\xd3^\x01\xaa\x17\x1c\xf2,Xi8\xf8\x89@Iy[\x81;\xcdW\x14:\xcbXr*p?\xac\x0b\xf9>Je\x02V@\xa040\xa6\x95'\x8d~\xb7\x1e6`\x8f\x0e\x05\"v\x14-\x00\xe96\xd2\xb0r\x1cp\x012\xb2+\x9a|f\xc9 \x90\x1c\xf2\xf7\x88\xa1\xb4\x86\xcc|\x1b\x18\x80\xab\xc0\x0ex*\xaf\x085h*o\xa1,\xc0\x05\xd7c\xbeZ\xa15\xf60\xde\xac\xb0?\x07>\xac?\xe3\x0d\x85M\xf1=U\x84\xcb-qV=\xc9R\x9d n\x87\xcb\x96lE\x15\xa2\xc6>\xcf-\xd2\x82(_\xbd\xf72\xba\x86\xf5[\xbe \xdf\xd0R]\xa4\x12\xae\x89\x164O\xbaa\xc73\xa5<\x04\xcd ld\xa7q\x00\xd9\xf2m\xdc6_\xb3d\x1e\xf2+k\xa6\xd8\xe4Z6:%\x8eN\x1a\xc5*\x0d\x1b\x17\x05s\xb6\x0c\xbc\xcf\x11KS\xb3\\\xa6\x13\x91\x821\x0d\xa2\xec\xbd\x92\x08\xc1\xcb\xc8&\x10\x8ai\xc4S6\x018\xf1k4A\x81\xb2e\x81&\xcb\x17\x1cRP\xe7\xb5\xf5\x88\xa4\xda\xcb\x9a\x07v=\xc9^\xaa\xf6)\xeb78\x1c[\xa0\xee\x0e\xe0\xf2}\xc4 \xc1V\x00\x97\xa3\xc8\xac\xa3\xec\x17]\x8f\xf8m\xad\xe2(\xfb\xd5\x80\xfb\xb5\x05\xeeo\x06\xdc\xdf0\xb8\x84\xa5,Y\xb3\xa30^R\xf0\x1bo\xbc\xb7\xc1\xa71\xf3\xb2\x8fby\x9b\xa5\xcaT\xb4,`\xee5+\xc6\xb7\x92\x80\x94\xc07\x9d \xa2r|\x18\x136\x17#(\xfea\xd5\xb1\xf9\xaf2\x17\x1b\xb2\x82\x9ey\x0d+\x0b\x00U\n\x08cP\xba=a1\xa3\x19(\x89A\x81\xe2\xcd\n\xfbR0\xe1N\xf1\x1b\x85\x93<\xe8\xc9u\xc6\xa24\xe0Q\n\x05\xea\x89-%_1\x9a\xe5 3\xcb\xe9$\xb4\x94\xd2oA\x074\xcdCK\x16\xcflR\x94\x04g7\x12\x1c\xf7\xa6\x1e\xb5\xb0\x87)c8\xc3\x9f.i\\!I!\xa1\x95$MC\x1e[\xbe\xa2 \x184\x8fyyH\x13C\xe8SO\xc2\xbe\xa5@N\n\xb9\x84SO\xc2K\xd9\xba\x1b'\x8c\xfaoY\xb6\xe4>\xd4U\xbeb\xf5\x94\xda]\x02\xb8|Ca\xfd\x97l\x1dh\xe1\xa5\xf9\x8aB\xb3\x15.\xe0\x169kKN\x90y\xcb\xb3 \x84\xe5h\xbc\xa1\xf5\xf3X\xd3\x86\xe2\xb7\x95.\x14\x99\xa5\x0c\x02@\xed\"\x884K\x82\xcf,[&<_,\x8dc\xb3\x92\xdevvV\x00\xcd\x03\xb4ZC\xdb)*o\xb8,\x03\x94\xf0\xcf\x96\x95 Y/i\xba\xa4IBeWE\xca\xc8\xd7I\xf8\xa7T!^\xae\x81\xa2\x14\xb7\xaf\x04\x01\xf3&\x88\x98G\xe3\xb2L(\x13Z\x0b\xfc7\x0f\xa2j \x91b-\xf26\xc8\x04\xdd\xb1\n\x8c\xa6\xad\x8a4k1s\xbe\xa1L\xeb\x8c\xf3\xcfL\xd3\xc2\n\xfc\xcaB\x0c\xa7y2\xa7\x1e;\x95X\xc81_1\xe8\x1b\xb1\xd4\xdf\xd0h\x91\xd3\x05\xc0W\x12\x90\x12\x19\xbd\x0c\xa5\xb7&\xb1d\x8c7\x146Y0 \x02\xd4/+\xcc\xaf\x05\x0cv\x96e\xec:;\x02\xfdV\x01\xc6\xae\xb3\x91\xd4v\xb5\x80\xbed\x1eO4\x0e\x00p\xbfH\xb1\x141\x91/\x94h\xc3\xbd\x02\xa0\xa0\xf9\xca\x17\x0c\x92\xa3\x1b!+\xe98$7\xc7%\x019. \xc8E;k\x14t\x91\xd6\x86\x06\n \x13\x05\x94%\xdb\xb6\x7f\x1e\x05\x9e\x8d\xb7Qy?\x04~\x00\xf5\xc1\xdb\xe82\xf0\x03{E\xa0|e@\x83\xaa:\x0e\x9e\xa5\x1fXr\xb2\x92\xc0Y:\x8a\x05\x85\x8a\x11\xbf\xeb#\xe3>\xd7Y\x8f\xca\xeb]\x0c\xf8G-\xaar\xd6#%\xb6\xc2\xc0^\x9b\xb2%g=2dM\x18\xf8\xdb\n\x87\xe8\xacG&\xcb\x88\x15P\xdb\n\x19\xd65\xf32\x9e\x9c\xcc\xe7\xcc\x13xF\xbe\x8e\x18\xbcc5\xb1$\xb5\xb1jk\x96dG\xfe\xfaW\xa8&\xc9@\xf0\x86\xa1\x1d\x91Y\xca\xdd\x00\xb4E\xecVB\xffZ\x83F\xeb\x0e\xd8\xd5\x0f\xfcZ@\xca_\x16\x983\xc0 \nL\xbe\xa0\x90ip\x19\x846n\x18P%>\xacW<\xf1K\x89\x8fxk\x91\xf7\\% \xa9Q\xb7E\xeam\xb4\xc2o\x8cp\x9a\xf1\xba\x90\x95\\\xdb\xef\x87\xafq\x04p\x8d#\x80\xeb\xe3%\x8d\"\x16J\xad[@\x91\xf5$\xec\x1ba\x10}>\xf2\xb2\x1c\x88^\x07^\xa7T\xbe[\xc1\x13/\xe1\xa1\x01.\xdfm\xe0?& \x88\x96\xb0\xcb\x04\x15EC\xe6G\xb3\xd2\xb6\x1aO\x97\xfc\xaa\x00L\x97\xfc\xca\x06x\x16dF\x95\x99x\xb3\x82\xca\xab\\\x05\x89_\xe2^\xaf\xc2\x1f\xc0\xd3\xb6s\xbd\n\xa7\x97\x14U\x98\xb8^\x85\x11\xbe\xc8 \xe7\x17\xf8\x00\xd4\x10\xa5SLAG\x81\x8a\xb3W})\xa4\xe8:\xbc^\x85b\xcd\xea\xf6`J;D\xfa2@\x1as\x83/\xae\x1b|q\xdd4\x17W= \xf9\xf2\xefh]\xbfs\xbe:\x8a\xfc\x0fT\x1cQ\xe5K\xab\x7fT\x8a*\x1f)\x17\x02\x81\xc0\x95\xf5@\x11Dz\x1982Ug`\x84R\xcc!\x04il\x85\xa4Y\x1dil\x806 \xb9\xec\xdb >v\xd6!\x17z\x1b\x84Z\xe1\xad \xb0\xb2m\x10zI[\x8c\xdc\x8a\x85h\xcfWk\xb0WH\xd9\xc6\x8cL\xcd\xc8]\xa4\xaa\x9d*#\x02\x8e?\xb3\x9b\xd4\x0d\x06\xe39ON\xa8\xb7t\xed\n\x84t\\\xae\x08\x19\xe7vgH\x02\xf1\xeb\xc1\x03\xe2\xd2q\xe3\xeb\x12H@\x18\xeax\xdf$@\xc7N\xddu\x02\xc7\xedW[\x82\xfe`\x0e\x15\xa4\xa3\x85Guk\xd7T\x81\xef\xe2>>\x1e\xe3>>vw\xeb\xd5\xcf\xc16\xbdj\xcb\xaa50\xdf\xea\xf8\x05\xa69k\xc3;\x8b\x80\"/\x0e\xc8\xa4\xe6=\xb1i\xaeN@2\x12\x02]\x83o\xd0xIS\xe6\x7fd\x8b \xcd$\x15\xaf\x97\x10\n.\x1e\xe5\xf1~J\x1c\x1eID\x85\xa0)\xfdh\xd7\xf6\x06\xb4r\x11\xe5\xa0e\x90\xf5M@\xd9&\x16LC\xe4\x01^\x9a9\x19\x8f\x7f\x08\xf3\xc4\x19\x12\x07\x04\x01\x10\x1b\xfb-\x8br\x95\xf2\x8a{y\xaa~\xff\x95\xdd\xbc\xe4WQ\xf9\xf6)V\xbf\xdf\xf2\x06\xe8I\xe47'\xab\xa9\xa2\xbf\xa1EV\x8b\x05q\x87\x0b\x12\xfbf*\x0dM\xa7=\x0d\x82Mc\xd4io\xd3\xe0\xc2du\xda\xcfB\xd8\xb0j\x9dV\x8d\\\xf1m\xdb\xb17\x88\x1a\xed\xa6\xa5a\xab\x85b\x0f\xdb\xc4[\x8e\xbb\xb4KP&\x84\xd3\xc2PA\x07\xc7o\xb1\xf3\x92Q\x12\xa4\xf1I\x0b\x14\x8f\x05\xd0%\xcf#\x1f|5\xc4v\xd8\x90\xcd3\x13\xf8\x0d\x9b\xdfn\x94\xbf\xba~m<\xc0\xb2n\x0d\x8a\xfa\x9e\xbb\x16\x07,6\xde\x80~\x9a\x03\xa9\xcd\xfes\xc3\x93J\xac\xe6aH\x96Cbq\x10\xa7\x06\x9fC\xb4xr\xa0]58C\x91\x04|\xa6\x98\xd7!I\xc6\xa5\xea\xba\x8e\xb8\xf3Ry\xb7c\xa9\x0bf\x99\xd5\xfe\xfd \xf9\x8c%N\x93h\xfce3X\xee\x9aE\xa0\x84\x9aNImF\xd8u\x96P/\xd3wtu\xca\xa4%|\xf4\xd6\xa2\xc3\xea_\x0fdF\x0em\xb1\xd3\x06d\x8a\x9a[\x88'\xbd\n\xdam\xde=\x9a2\xe3\xd8\x9bZW\x9a\x1b\xba\x1c\x82\x9d;Y\x923\xe9#\x9e\x8f\x95\xaa\xed\x89\x1f\x80\xc8Q\x9a\xf1\xf82\xb6\xc7R\xfa\xa2\xd5\x07T\x8b\xd1!\xb8\x82\xc7\xb3\x8b\xf6\xc1\x99mo^qd\x96\xc7d\xf1\xe5\xbb}\xb8<\xe9\xed_\x87\xe3\xd6\x12\x17\x8b\xf4\xfc\x8eI\x89\xe0_\xaa6\xe9S\xdc\xd2 \xb5\xa6\x14\x19@n\xa4E{G\x0b\xeaT\x8b\xbdz\xb1t\xe7\x83^\xdd\xd2$TG\x97$m\xd5\xd9!\xd5\x91\x0edFZ\x1c94\\b\xfa\x1f\xf2\xec\x0d\xf8\xd3d\xf5\xe8k\x16\xaf\xa3%\xf1*M\x97a\xd1\x03u\xb5c\xb5\xc1\xc3\x8d\xaf.!\xf5\xae\xcc\x0c\x1e\x99\xc9\xe6\xaf\xbb\xc9\xfbP\x9c\xc9\xc9\x95\x05\xdbc\x94\x9b\xd9\xdf\xab\xf3J!\xce\xfc(\x8f\xdd{u&g\xae\xd2\xeb\xf0\xb1jM=\xdd\x97\xf0\x8f\xea\xbdZ\xaa\xf4\xfa(\xacUz\x9d\xe9Z\xa9A\xab\xc3/\x14|\xdd\x07\xdf\x8d\x1c\xcd\xfa\xe8\\*\x1e\xad>\n\x17e\x84\xaa?\xbe\xd6\xf2\xaej\xe1\xe8g\x0e\xbd\xe4\xe0G\xc0\xa1Q \xdd\xe3\x9dD~\xe5\xfdu\xc6\xf4\x15\x89\x91\xaa\xfd\x0f8\x97\x8a\x95\xf1h\xf4!\xa47\xc6\xcf3ya\x08)a\xe0}\x86\x1fUn\xc7\xe3\xb1,\x91C]>\xcf/Cv\xac\x81\xfd\x84.\xf4\x7f\xd5*\xf9S\xfa7\x90/\xd7A\xa6\x7fC\x8c7\xfd\xf2~]\x02\x15\x8d\xf5\x13\x0e\x1c\x92\x9f\xcb.)<3$\x0e[\xc5Y\x00Q\xcc\x1c\x16y\xc9M\x9c\xe9\x17_\xfdH\x12\x0e\x15\xce5{\x16D\xb1lv\x10\xadi\x18\x00\xd4\xe7\x92_\xfb\xccn>$pO\x02\xbf%k\x16r\xea\xeb\xff\xcc\x7fI3Z\xbe\xbde\x19\xf5\x8d\x94\xa2\xd5+\x93\xd5\x83\x97\xb7\\v\x14^\xde\xe7%\x94\xee\xf5\xaa\xe4\x06c\x9afL\xfe\xc8S\xf9C\xcd\x93\xf8\x0f\x12m\xe2\xc4 _\xe8\xc6&4c\xe5\xc0\x80s>\xc7t\xf1\xeb\xa4\x8c}\x96\x83\"~\xa9\x1a\xd2\x8c\x86\xa1J\xcd/WrV\xd2<\x8d\x99\x9c\xb9,X\xa9P\xd4\xf0\xc6soy,\xc8\x87\xb0xUS\x0c\xbfu\x07\xe1\xa5\x18\x08\xb8\x1f\x0b\x8cE\xba\xe6a\xbe2\x1a{EA\xf6\x0e?\x97\x8c\x85\xcey\x0f)\x91f\x8d\xd8l\xe7|\x9c\xf1Oq\xcc\x92c\x9a2w@\xb6\x05c\x16\x06\x1es\xeb\x9b\x95(\xcbg\x87G\x10\xe3\xb7\x99\x0bv\x98\x19\x8f-\xd9\x1c\x15x\x90;\x8a5Z\x0c\xc1KiFD\xb6\x89s\x0f\x92\x8c\x04\x91*T\x0f\xe3\x0b)P\xe3Cr5K\xce\x8b\x80\xd9\x00Y\xf3\xd2~\xa2PS\x91X\x08\x07\xae\xad\x16\xca\xce\x18\xe2P\x8d/\x12\xce\x81.}\xfd\xb2\xac\x1f\xa9\xe9\xd4^\xd3e\x9ee\xd2\x0c\xf8@\x06\xe0T\xdb\xdbHH\x8d#W\xa6\x08TF\x13FU\x9a\xf1m\xfdK\xf4\xec\xb8\x95\x92\xbf\xd8\x90\x92\xe7(\x13D\x13B\x87pR\\\xcd\xd89.-\xd8\xba\xe9 \xf5\xfb\xd3\xeaGpjtPT\xc7\xeaD\xe8\x07\xa6O\x8b\x0e\xe8\x97U\xcc\xdd\x01}\xa2\xb0z\x17X\x81\xf1;\x01\xfd\x1e@pRt\x00\xbd\x86\xd5\xd5 $\x0f\x96\x0e\xb07\xe2P\xe9\x01\xa3\x0e\x9c^\x90\xc5a\xd4\x03Z\xe2\xe7\x0e\xc0\x0fp\xfat\x01\xf5X/\x1f\xd4\xa9\xd5\x05\xa6O\xb4\x0e\xb8\x8f\xe5i\xd7\x05 'a\x07\xd0\xa9<\x1b{@\xf5\xe8\xc3\xa9:S\xbb\xc0\xe4y\xdb %\xcf\xe2\x0e\xb0\xb3\xf2\x9c\xee\x80\xfc\xc9<|;`\x7fV\x07\xb3\x9d\xbf\x12<\xc0\x1d\x19\xe5\xbfj\x8a\xab\x9do\x94\xfe\x9e.\xdd\xa8M\x82\xac\x9f\xfbf#!\xb8\xd3\xdd\xba\xd9\"\x88(`\xba\x84)\xa2\x19\xde\xdd\x9a!\xc9\xf4\xf6\xa1\xdeU\xaeq\xe4\xe9\xba\xc9p\xbf4X\x81\x8e\xbev\xc9G\xaa\x80@Y\xf6\x01\xb4Nc\x15\xec}7\x1a\x7f[P\xe6\x1d\x80\xdd\x12\x18\xa2\xe6.\xbe\xdb\xdc\xbd\x14\x9cUGc^*\xae\xab\x17X\xd6\xdd\xb9\x97\x9a[\xeb\x01'9\xb9\x1e\x80}F\xf5e\xc1\x01v\x02\xf2\xae\xadkq\xadHz\x8e\xfb\x99\xc1\xf6t\xe1a\xcd\x12\xf5\x81\xeb\xb3\xa8\xcfJV\xaa\xbd\x8f\x16\xef\xb8\xa4g\x1f\x8fLABG\x9b\x8e\x9aB\x86\xbe%\xfa\xf4\xa4\xc5\xbb^\x9f\x9e\x9cU\xd8\xcd\xf6O\xad\xef\xf6)\x19\xe4\xa7\xe3\x1b\xab\xbb}\xe3g\xe0\x88\xdb?\x81\xf8\\\xd3O\x9fO\x1c\xf3\xb8\x93~;\xeeF\x98\x1f@d\xd1\xde\xd2\xa6?\xc4\xa6\x08\x96\n.-q\x9d\xfd'\x0e\x1e\xc8H\xf0M\x17\x10\x90\xa1\xbc%\xba)9\xadf\x01u\x80\x05\xed\xb7?\x17\x83!\xb9\xa8\x94\xbd\x07\xa1/\xdcV\xf3H\x1e\x89\xa5\xdcw\xeb\xd4e\xe3\x8b\x8c.\xd0\xdb1b\x08j\x05\x1fm\x17\x0f\x04z\x18\x90`\x83\xf8\xac\x9f\x08\x96\xfe\xcb\x17\xe2\x9e(\xde^G\x85\n\x0c\x89\xdf\x0d\x16_\xaamh\xae\x820|\xc9B\x961\xcb\xf0\xdc\xfb\xd8Djll\xbd\x8c\xce\x95\xc3Iw0$>4\x0dR\xbb\xfaU\xbcYd\xef\xc7\x90zG\xd9\xfb\xa3}\xd4\x81=o\x11\x18h\xf7nc\x8f\x86\xa1\x8a\xacn@\x97\xcd.~%c\x9aC\xbc\xf8\xe3\x90\xa6\xa9\xcb\xeba@\n\xa9\xb0\xf4\x8f\xd0\xd4\x06a\xd2/\xb1\xe0-\xb0\xec8e\xb9\xcf\xcb\x0b\xed\xca\xadhM\xfd\x8a\xdf\xd3\xa85o,\x9a+\xc4\x0b\x83\xf8\x92\xd3\x04\xf8\xe6>~\xda\xb54\xa9RP\xe9\x94\x1c\x126\xae\xa4\x17\xb7\xa6\xd5\xe4\xaee\x85Mw\xf0-\xa7;\x90^\x86\xcdI\x08\xeec\x12&\x93\xc9\xbf\xc1\xdaM\x98@\xe2\xbeV(\xff\xf6k\xafy\xf1\xc3-79\xb8\x87\xbd\xcf\xecf\n\xf7V\xf5[4\xa2<\x02d\xa0\xe0\xdf\xdce\xe2\xf1\xb2$\xfc+T\x80f\x83/\xb5\x96|\x1a\xb6\xe5\xaeXF[\xb2\xa51\xa8-\x17|\x19\xa0\xd8\x81\xc8\xb8\x16o\xb9\x1f\xcc\x03pA\x90 8wwR\xbf\x18\x14\x8f\xb7\xa4\xc9q5\xf4~\xe7v\xfd\xccnb\x10\x1cH9\xae\xd4\xfd8\x94nm\xa7\xb5x\xa4\x04\x17\x8f\x7ff7\xb7\xf8\xaa/\xb8V\xf3\xa3_\xbe@z\x1e\xd7\x9a\xc2\xc6\xea\x03}\xdbs\xb5\x0c\xbc\xe5\x86\xadi\x19\x83\xfbll%\x05Eg\xf4[b\x00:$\xc1\xb7P\xe9m\xee_\xfcP9I\xbd)qNR\x8f\xa26\x05\xa0=}I\x93)q\x08\x92\xfd\x06\xf4\xad\x9c\xa3$\xe1W\xe27\x02\xf2)\xd6\x00\x9f0\x83\xc6\x8f\xca\xd0\x04 >ZLM^\xf2\xabH\xc3\xc8\x9b\xc7&\x08\x0b\xa7\xc4\x91\xa4\x1a\x92\xfd3\x18K\xbe?E\xb2\xde\xb2(\x9f\x12\xa7\xa2\xf9\xda\x00:\x8a\xe3\xb4\x13H\xb2MS\xe2\xc8\x1fo\xb8\x87\x19O\xbc\xe5\xbf\x7fH\x82\x08\x14\x84\x00?9\x9f\xa2\xc0gQ&\xf0\x89\xdfjg\x80\xa3\xe0\xfd)q~\xa0\xdeg\x9b\x85\xc5\xb3)q\xce\xe8%\x923\xd9\x15}\n\x19\xc5\xcc#&{ba\xc8\xdb\xedf\xe6\x13\xd1M\x8b\xaf\xcb\xc9S5T \xc7\xec\xc7&\xa2\xc1G!ZR\xb4U\xca\xe6\x9b\x99\xbb;S\xb8(L-\x03\xbb\xfb\xb4m%\xef\xedZ\xd6\xf0\xde\x1e|s\xc1\xd0\xf5\xb9\xf7H\xe5Z\xd6\xdd\xdec\x18%\xcc$|O\x8c\xd1\x8f\x1cu\xcb\xb5\xf7\xb4c\xdb\xec\xed\xb7n\x9b\xbdg]{\xe6\xd1N\xc7\x8ey$Z\xfe:J\x19\xea3\xe7\xd1\x93\xb6\xed4\x81\x95\xf3\ns52\x81u\xf3j\x17\xcd\x12\x83\xf9j\x0f\xcd\x12\xady\xf5\x08\xcd\x12My\xf5\x18\xcd\x12\xc3\xf8\xea \x9a%\x06\xf0\xd5S4K\x0c\xde\xab}tC\x88Q{\xf5\x0c\xcd\x9a@\x97w\xd0<9\x1c\xe8x\xec\xc2xL\xd0\x01y$\x06\xe4]\xbe\xb2\xac\xe8 \xccQ+6\xd9\xdd\x15U\xbce\x19\xada\x0e\x9c\xcb\xb3\x9f\xc0\xd2\x0b\xfegvc\xbb\xd1\xcd\x04\xc99\x03\x90s\x19\xec\xf63\xbbir\xa9\xc0\xfcV0\x1ah\xc8\x97\xde\xe3\xab\n\xb9_\x1b\x8d@\xcf~[\xa3\xb4\x7f|\xabld\xa2\xfc\xe1\x93C\x8d\xcc\xc8\x94\xc8\xb0:\xe3y\xc2W\xc7\x8a@\xab\x07DF\x15d7\xa2;\x82YAy\xc0x\xd5\x06eJ\x9cr\xc6\xee\xc1\xc9\xb6\xd4\x11\xfb\xd7s0>\xcd\xa8t\xf7\xc3\x92\x7f\x1d\x03\xd3\\-\xa0\xbb\xc3R\x1bI/\xb5\xa9\xcf\xda\x81<\xb8]\xf4;\xa0\xee\xc4\x96\xdc\x91%\xb2q&\xd5\xb5\xfd?\x86i\xff\xb7X\xf1\xb1\n\x15\xfd\x7f\x8b\xb8\xe9\xdf\x04O\xb00\xa3\xbft\xf1\x84\x1a\xf1JhCv%\x13\x04\x16\x05\xd5\xba\x97\xd5\xfc\x11\x1b\x1b\xc9\x0d\xc6\xaf\x11\xa74\xcc\xe8\xaf\x1b5\xe5\xd7zS~\xad6\xe5W\xbc)5(\x1c\xa8Ws\xff\x86-%\xc8\x91\x86\xff\xdfj\x19 \xce\xf2\xf1\xa0\xb9\xac\x9eu\xd1\x1b\x88\xac\\\x1f\xe0\xcd\xb1\xbe\xc8x\xfc\x86\xadY\xa8\xe2\x02O b`u\x11\xf8\xe0\xf5KdO\x90\xecJ\x84\x8e\xa9\x8a\x91R\x84\xc0\x80 \xa9\" \xc2\xa9U\xa3y\xd8\xb0\xeb\x85\x8co\x83\xe8O^dta~B\xe0\x82q\xc6\xdf\xf0\xabB{\xd3^\xa9\xb6\xfd\xfe\xf4\xf1uQ\x87\x91F\xa6\x88\xda\xfesl{F\xb5}x\xab\x196\xa7\xaf:3\xf5x\xcfS\xb2U3\xa0\xcfS\xf6*\xb8\x14\x13\xb25\xb9\x8f\xb6\x18\x91c\x1e\xd5\x15\xe6\xc51\xff\xf0\xb7\x87\x87\xdf?\xac\xa6\x0b&\xf9\xe1\xdf_\xfc\xb6\xf5\xdb\xe8\xb7Q-\x0f7\xd4?\xfe\xf1\xe4\xf8\xaf\xa7\x9f\xde^\x1c\x9d\x9d}\xbcxw\xf4\xf6dJ\x1cA\xc7\x8c \xe4\xf0\x08b*\xa79\x1a&\xc3\xf7\x8fU\xee\x19\x97\xb1\xb4\xbb\xf0\x081\xe8i\x9ct%\xe6\xd5^\xc6\xd2LTt\x08\x01f\xd88aqH=&\x10\xaaC\x1c\xb2M\xe8\xb8\xd9~\xb2M\xbe;p\xbe#\xdb$\x13?\x9d??\xf8\xae_@s\x1a}dy\xca\x9a=\xe9\x8a\x80\xa8c\x9b\x16\x16\xec.\xd6\xae\xf6\xce\x8aJ 6QL\x93\x94\xbd\x8e \xf0\xe4dg0\x94\xc1\x7f\x80\x8eo\xf6\xc2\xb6/\xeeY\xa4\xf6\xe4\xf1\xe3\xddI\x17\x92\xab\x0fQ\x11\xc7KL\xf6d\x08=\xdc\x91\x91\"wdH/V\x84\xdb\x12ks\xf4\x88< \xc1s\xc2\xc9\x0bB\xd1\x10_E\x8d\xb9\x19f\x90\x93m\xf2h\xe7\xd9\x93!\xa1\x03Y:\x17\xff\xb6\x0f\xc8\xa3\x01\x89\xc4\x7f7\x13\x7f\xd9X\x0b\xa4\x8f2\x97\x0f\x06d\x1b\xcd \xdbd\xd2\x96\xb9\xdb\x96\xb97@f9#\xffq@\x121\x00\xffa\xc6\xa6&\x8d T\x91\xdaD\x17\xc48lo\xab\xf6c\xcdGq\xa0+?5 _\x88\x1b\xa9\x9f/^\x90\xc9\x93\xfb\xc0G\xe6\xac;\x93\xc7\xe3'\xe3]\xe7\xf6\xb5u\xd8,\xb9\x91\xfb\xe8\xc9`(m\x91p\xdb\xa5I\xdd\x9aG{bx40\x8f\xec}\xa8\xe5\xd9\xc6\xa1\xb7\x04;\x1e)kw\xd6\xa2/'\xe0&\x8a\xfb-\xe3\xce)pV\x85\xd5\xbb\x01\xac7\x1b\xe8O\xd4T\x8a\n\xdcL\x06\x11\x1e\x08\xf4\xc7\xed\xe6\x9e\xcd\x16\xa1\xa1\xb4\x04\xf2\x8c|&N\xfd\xc4u\x1e=rDY\xf1\xeb\xb13\xac\xb8\xf3\xb8\xe7\xf8WbB\xf6,\x83\x9f\xa86\x9d\xe6\x97Y\xc2\x04\xd2\xe3EX\xe0\xdb\x7f9\x1b_\\\xb0\xf4-\xf7\xf3\x90\x81!\xdeP\x86\x87\x8b\x98\x97\x01\xa6\xfe\x90\xf0u \x86BG\x1dm\xb6:p#w\xff\xf1n}\xe5\xf1\"\xeb\xd1\x00e#\x02\xabY\x83\x8a\xf7h4M\x1ejM,\xa7\xa2\xa7MIwL\xc5J_\x12\x1dw\xad\xda_\xae\x93\xefyDU\xad-\x83\x18\xb9u\xfb<\x0eK:r'\xd8\x96\x16\x19{O\x1f\x9b\x18T&=\xc1\xc7\x9a\xfes\xc7Z\x9f;-\x07\x9en\x99\n\x1a\x8d|o\xab\x1fU\x016\"n5\xe8\xdd`@\xb2e\xc2\xafH\xc4\xae\x88@2`\xdc\xe0:\xc74\x8axF\x04oJ(\xf1\x04\xc3IhJh\xf1%\x07\xa1~\x14\x17\x8b\x99\xdd\xaf\x95\x95y\xff\x862\xb3e\x1f\xd9\x9c%,\xf2t\xf3\xc4\x87\xc8\x92\xa6\xd1w\x19\xb9d,\"A\x14d\x01\x0d\x83\x94\xf9dD\xd2\xd3\x05\x1b\x93O)+\xeb\x1b\x83\xb4\xa2xu\x07$\xe3\xf2d\xcc\x96l5&\x1f\x19\xf5\xc9J`m\x9a\x11\x15hu~9^\xb1\x87y\xca\xa4\xa8cT~\xc5\xa9\xdf\x8a\xe1\xa3\x91\xb5-~\x1b]A`\xd0\xcb\x95 \xb8\xe1&\xaf\x80\x0b\x08\x95kn\x04C^r\x1e\xa2\x19\xa2\xb1h\x86\x8c\x94\x8bf\xc9\xa3\x15\xcd\xd2\xce\xc5\xb1\xac\x9b\xd5\xa5\xa5\x114\xc2[\x0d\xfdy?Ge\x8bLK\xdb\x90r\x9a:\xb2\x14\x95\xf2Jk\xc7,\xa5xd\xab\x0fr\xa4\xc7F$\x17\xe2\x01\xe0]\xb8\xa6b\x18kW\xbf(\xff\x1e\xd5\x160\x91r\x83\xb1\x99 \x0e\xec\xa2\xec\x1d\xf0F\x83\xa8o\xa2\x14u\x82\xd14\x0d\x16\x10\x9e\xbb\xaf\xb0\xe79\xc9\xc8\x0bB\x93\x05\x88\x94S%\xe6yN\xb2\xedml\xaf\xe8\xa5^\x14\x98e\x88\xe1t\xf1\x89\x84\x04\x91\xe8\xa1j^y,-i\xfa\xfe*R\x8e&o$-')qqN3\xa9\x1b\x1f\xcd\x92\xf3\x1e\xd7\xdd\x86 9~\xe8\xb4\x8d8Q\x9d\xf2\xccN\xa9Q \xdf\x93=\xd1\x1e\xc95\x01\x8e,\xfb\xbdwN\x0e\xab\xaf\xb8\xfb\xd4\x159 ?p\x1e2\x1a\xa1\xa6\x04\x0b\xa2\x0c\xe3\xe7\xcd\xbc\x1b\x84e\xd3\xe9x\x14n}S@\x0e\x89\xbb#\x0e=5\n\x03)\x81\x88\x9b\x88\x0b<\xa2\x80\x8b\xc0\xe6\xf7\x05\xbd\xe3\x8d\xe3H\xf2z\x1dNb\xdc\x99^u\xcd]Y\x8a\xe6\xd58\x00\xe5\xdb\xbdp\xd4\xeeJ\xcb\xd3\xe8\xcb\x17\xb2%\xe8oZ\xd2\xdf\xba\xce\x12j e$\xf5\xb2\x07\x82\x0d\xa8\xbb\xb2\xd5\x0f: \x95\x11\xbd\x8f1\xa9N\xd1\x1d\x87\xc5\xaf\xe0\xad\x96\x91\xa9\x00\x9a\x83\xe3\xd70\xdf\xa6\xe3\xf3\x96%\x0b\xe6\xdfit\xba$OX9\xb1_/\x8b\x02\xed\xacf\x8b\xf3j\xd2\x85\xa1H\xc1N\x1a\xcb\x08\x1b\xd3\xcd\xa6oKV\xb9*\x07O\xcc\xc8)L\x0b>\x81\x06\xa89}f\x0d\x9bL^\x90\x9e\xe6\x97\xa9\x97\x04\x97\xfd\xe7K\xb5\x1d\x97\xa9\x89\xc6\xe4Q\xaa+\xed\xd3\x86,\xb9)\x1a\xd1\xb7\x0d+p\xbeQ\xffZ9\x1ef\xe2\x81q\x1f8.\x92%\xdc\x92F~\xa8\xa8\xe2\xf1e\x10\xf9\x90<\x18\x0cI#\xdbE\xfc\x8c\x10\xb47\x9f*\x1f\xef\xd5\x9f^=qu\xb3\xaa\xbd\x13\xecd\xaf\xa6\x15\x92\x83\x97\x81\xff\x96\xe7Q\xe7]\xab~\xe0\xa3\xe64\xb9\x9b}\xef\xe7 \x0c?2\x8f\x05k\x84\x93h\xfb\xf0U\xcbN\x90[\x0c\xdc\xc3\xa8\xb9j\xf2@M\x7f\xe5\xfaik\xea\xa7hu\x9b\xd1\xf9\x84\xcc\x94)\xb3\xe8\xd5\x8e\x02~\xa3\xaf\xd7\xb17h\xa5\xd7\xcf\xc2jz\x15c\x18\x19\xb6q,\xb2\x9b\xecd5\x7fm\x9c\xf7?0\x16}H\x98GC\x0f\\\x19\xf9\xca[\x7f\xadi\x06H\xc0#\x10\xa3T\x1b%o\xe6\x99\xaf\xb4\xd4\xab\x99v\xa2\x0b\x01\xaa\xf1%\x0d-|\xfd\xd4&\xc6\xc4\x04}\xa7\x06\x14\x1fk\xfb\xb5\xcf\xa1VCY}\xf9[\x02:\xb9\x07\xc6\xd8\x8eK\xe9Z\xfb\xd9\x07\xec\x8b\x14'\x00\xd1\xd9\xd9L]\xe8\xaa\xc4\xc3m\x1c]\x9f\xea\x08&\xcd\xef\xa2\xf2\xebO\x96\xdcl\x00M\xcc\xab \x1a\xc7\xe1\x8dk\x11\xe2`\xcfW\xe2\xd1vo\xc6\xb6G}s9\x06y\x9a<\xb0\x97\xbdk\xb0\xcb\xb3\xccGQ+6r^\xee\x8a\x0e\x8aI?\xb0<\n\xe7\x9a\xfd\xcaDp\xd3\xb5\xc4\xc8o|\xb7\xab\xd1\x18\xf4\xc7#\xedb?\xd2k\xa8z\xe1\xb4T\xef\xc0~\xd3l\xca\xb4q\n\xc8|\xbe\xb6\xaf\xb8\x16\xe9e\x1f\xbc\xb5`\x99\xb4\xb7\xf2\xb5zu_\xec\xa59\x8c\xea\x15\xc7\xf5\x908g\x9cP\xcfci\n\x97\x12W\xb2\xfa\xe2\xf6kHnxN\"\xc6|\x92q\x88\xe0\x1f\xcco\xc8\x1fD]kNI\x96\xe4\x8c|%T\x16\x9f\xf3<\xc9\x96\xc5\xe50\x01\"\x12\xeeF\xe0~q\x00\xf7HcgP\x1c\x04\xf3t|U\xedQ\x9fq\xe8\xa7\xda\xa5\x1f}\xcdi;\x10\xdb\x11qT\x96l\xae\xab\xf6\xa2\x81\xf9\xd1\x96\xe5\xdf^\x0b\xad\x9c\x02\xb6=\xd7^G\xae\xeb\xa8\x1d\xbd\xf6\xdd_\x1cw\x16\nb\xd2AAL\xfa\xef\xfc\xcd(\x08\xaa\xefih\xbb`-\x95{\xbeuX\xc2\x8e0Hp \xe6\x80\xf5R\xad, /e\xba\xce\xc8!\xd4m\xc2\xb6\n\x88:\x84\x84\x1e\x12\x1d\xb1\xfe\xccU\xb4D[~@\x0ee=;dJ\x803u=\xbd*l\xe7\x8a+x\xa7\x10`\xe7UXT\x82\xe2\xb6]\xc5\x16L\xf2\xd6\x96\xeb\x81\xd6\x07\x8c\xe6\xa0\x18\"\xab\xe8\xc1\x95\xbcqN\x0eIN\xa6jY6i\xc8k\xa5\xf9\xc1\xd5\xf5\x99\xca\x01\x1e#q\xff\xf8\xda$\x95\xbb\xee\xd3d\xe0\xe9\x1a~\xc2#`\x10\xc0\xfd\x03\xd1\x88TX\xc7j\xc5\xd5U\xb4l\xac^um^\xb5\xdf\xaf\x16Z\x93\x03\xe5!\xe0~\xb4\x1e\x87v\xa5\xbez'\xc1K\x90ti[\xdcR\xd5\x8f8\xcd\x98U-\xea\x9a\xc7KR\x83\xa9#\x19\xb0>\xd4\x1a\x83\x82\xd3L\xd4K\xf9\xe5\xda\x81T\xa8G\xf2\xb2j\x9bj\xa44\xbf\xddyN\x02\xf2\x82D\x85zf\xb0\xbd\xdd\xc4\x91\xc0\xd3p\xa5\x194$\xd1,8\x07a\x12\x9b\x89\x9f\xe7\xf2\xeeE\xfe\xb6\xb6\xad\x18\xac\xda\x0e\xf9\xb6Sh\xd9\xe7\x05\x00\xca0\x1b\xd4|\x02\x82\xce#\x00\x06\xdb\x7f\x9e\xa4\xf2\xbc\xe9\x89&\x957\xc2\xa7J\xb4\xd6\xd1[(QV\xd0J\x83\xe3#C\x0c\xb9\x08\x8e\x04\x1a\xd6\nv5\x12\xaf\x17\x94\x1aw8v[\xa0\xcaS\xd2\x0e\xb4`\xd9\xcb^\xb5\x01`\x12\xac\x99\x0fd\xd5\xab\x84\xaf:J\xac\x82\xeb j\xc9/\xceS;H\x06\x8a\xdf\x08+\x8dh\xe7f\xd6\xf1\x8fZG@\xee\xc3\xd6f\xca\xed\xdc2k4\x0c\xc1\x05E[~K\xf9B\xf7\xb8\x0d$\xc8n\xfa\x0e\x85\x81\x0b}6\x0f\"V\xa0\xa0\xe6\xce+A\x17,3\xb0\x15\xc4\\k\xc2s\x1b\xfc)\x98 %\x02[\x89\x97,\xf5\x92 \xce0^\x8fV\n\x19\xdaMMPA\xcaPAEP\xa5'\x85[\xe9\x17\xb4H\xea\x86C\xe2\x0d\xc9\x1cCD\xa0['\x0d-L\xcd:\xcf\xc6\x8e\x0bx\xd4\x0eG?\x023\xc4`g\xeb\xb5\xf0\x12\xb1h\x7f\x0cX\x1d\xb83hc,\xda\x88\x16\xc1e+\xe2S>\xb8\xf8\xb0}\x8a\x13\x1d\x1d\xd8\x17\x84\xb1G3\x97\xbb\xde\xc0\xc6\xe5\x14\x87\xdbR\x9e[K\xf2\x82\xf8\xc5\xb9\xb5\xbd\xbd\xec\xea\xb8 \x1b\xfc\xd9\x121+\xd0\x8fRN\x9e\xad\xc1a]\xa6\xfe\xcfE;\xe7\xb3\xf5\xb9\xd5o\xbd~\xc4WV`\x1f\xee\x0d\xc9\xbaC`\xd8O\xfc\x1a\x89\xb1_\x0f\xc9\xaaC\xf2e\xcaW7\x16\x83\xa1\xa9j\xa56%\xfeMp\x14\xd48\x12\xab\xde\x97\x12\xb7\xd7Y\xd8\xed\x81\xa2^\x1aL\xd1\xf8\x90\x04\xb8A\x9a\xd6\xdcn\x0e:\x084\x9a\xb3%\n\x18\x96\x08\xd9@\xc6\xbaeWD)\xaf\xbe\x0d\"\xf0fH\xd8\xb5\xc7b\xd8\xcf\xdc\xf3\xf2$a\xfes\"\x9a\x9f-\x19\x89x4Zi@\x9f\xad \x8b\xd6A\xc2#\xe0\xab\xc5\xa2\x06\xc9^\x1e\x86\x04\x82\x9a\x92\x15KS\xba`\x84F>\xa1\xbe\x0f\x11OhH\x96,\x8c\xe7yH\xaeh\x12\x05\xd1\"\x1dc\xda\xe2,L\x99eQ\x89>\n\xcehV\x1f\xa6s\xbb\xe0\xc3\x83\x9d\x86f\xbb\xd5\xa1\xc8\n\xbf<\x0f\xff#}\xb8\x18\xf6\x13\x1d\xeau3\xf3\xb6\xb7\x9b\x01\x1c\x88d\xfa\x07\xd2\xee\xe1\x808\xaf\xa35M\x02\x1ae\xe4\xa7\x80K\xe1\x15b\x00\xd1H\x91\xf2\xact\xd2\xec\xcc\x1f_\xf1\x1d\x828Hi\x02\xea\xd5\x87\x89\xd0\xa4#\xa8l\xd8A\x95\x13C}L\xbaE\x91\xf6\xd1!\\k\x83<\xb04\xaf\x9a\x0c\x86\x98\x8d\xff`Hr\xd1QO0d\xa0h,\xc5o\xa2\x7f\xdc\x8d\x86\xe4\xe9\x90\xa4\xd8\x01T\x1c>s\xe3;\xcf\xc9|4z> \x01\xa8\xfc\xcd\xe6\xe7-R\xa2\xeaR\xb3\x99\xdd\xa2\x0b\xcf\x1c\x8c\xde\xbe\xe5\x8a\x06\x8b\xae\x8d&C\xa2E\xbc0U\xe4\x90\xec\x80Nvy|F\xe4\x05I\xe0\x86R\xe9\xd2\xb9l\x16\x9dK.~\xf0\x1c\xa7b\xea1V{o\x99\xc6\x9a\x96;\xe6\xc9\xa3.{d\xac\xab\xa6\xec\x06\xd6\x11w\xb3AE\x90u?\xad\xdb{\xba\xffo\xd1\xbcF\x88t\xd9\xbcI#\x02\xbbB7O\xea\x88\x82vK\x07\xba\xfa\x89\x9e\xad\x89\xcb\xca \x8eA\xc3\xb7\x91\xbe(\xe2\xa84D\xac\xd3\xd9\xb9E\x9e\x91\x835\xd0\xc0u\x0c\x1b\x0c\xa0\x88sP\xe0\x83\x8b\x00*\xe5\x13L\x9c\xfc \xd1\x8e\xc6q\x9e.\xdd\x1c_\xbb]\x06\xb4\xdd\xbb\xae>\x06\xba\x7f\xf5^\x14Hr\xeb\xa0.]%\xd5\x9d\x1aDj^` 3\xd9\xfe\xba\xaa\x9e\xc6\x81\x9b-\x9f\x8e\x88\xdb\xdaM\x1321\x1c\xe2j+c\xb3\x83\xaay\x8f\x8c\xebdx\x95\x14i8\xd3\x05\xd4>R\x8f\x14\xb9B=\xacR\x0ff%N\x943\x81\xa0\x9c\x90\x03Q\xf5!I\xc6?\xe4\xf39K\xc8T\x99}\xdaX\xb3CB\xc74\x0c\xb9\xf7)J\xe9\x9c\x15\xf0\xd5A\xee\xbd\xbb \xa9;\xed\xd21\xca\x91\xc3`]h\xa4+e\xe4\x06\x04QL0\xdc\xc6\xb8\x11h\"\xb3+\x02z\xdez\xe1\xa3\xba\xe3\xc5\xc7=\x1e\xdf\xb8\xc9`h\xf52\xf7uP\n\xf2\xdc\xc9\xde\xa3A\xe1\xeek\xf3-\x80\x0c\x88q\xe64\x1bi\xf4\x1d\xd9\xe9\x99TP#\x07\xe4(I\xa8\xe8\xc5\xa08\x99\x9e\x0fH6\x8b\xce!0|t~\x1f;\xa2\x13\xdfO\xf6\xefr\x1c%\"\x13P\x9d)+\xbc\x9f\x96\xed=\xedt\xdcqO-\xab7+\xba\xff\xa3C\xa3M\xfb\xa6H\x14\xabQ\xdd\x05\x16\xc9\x8a4\x82\xd5B\x13\x03\xcf\xccv\xce\xe5\xa9\xa0\x8f '\x88|v\xedH\xcd\xe0d\x0co\xd0\x0e\xf85$\")\xce3\x95\x14\xe7YeSm8\x93\xbb\xbb8\x93\xb0\xff\xb4N\xae\xabS\xfb)\xee\xdap\xff\xe9\x1e\xca%\xec?\xad\x9f\xf2b\xd4\x9d\x99D\xb8\xdaQ\xc0\xb9\xd3d\x19\n\x98\x974cu\x00\xcf\x04xK\xe3z\xfe\xdc\xcc\x7f\x07\x8eD\xea \xb1 \xf2\x91-N\xae\x1b\xb5\xf8&\xc8)\xcb\xea\xf9\xcbJ>Lm\x1dd]\x01\x01\xe9_\x1dde\x82\x00\x86\x91GF\x1dnQ\x1b\x14\xfaS\xc0\xae\xea@7&\xd0\xab\x90\xd3lo\x17\xea\xac\x03^6\x00\x9f\x01\xd4\xb1\xbbA\x1d\xe2\xef\xc4Z\xd3\xde\xc65\x89\xbf\xbb\xbd\xbc\xe7j+a1\xd6\xb7]\xa9\xfb\xb6\x1b\x90G\xf8R\x9d<\xc3tk\x04\x1b\xdbzH\x90\x9aL\xcd\xc9\xb8\x143;-\x91\x0c*^\xf5\x9aHH<}<\xfb)\x83\x07\xc1~\xe0\x00\xa6\xbb\xbf\x06@\xcd\"V\xb0i\x01\xbe\xf3\xf0\x18`\xdd\xbb\xc5\xb2O[93\xbd\x04,\xab\xa4{\xe3j\xd6h\x7f\xa76\xb2bYL\x9e4\x97\xc4K\x9a\xb1q\xc4\xaf6\xc5:\x9a\xdeA&0hj\xbf\xf5\xe9\xfbZ;\x02\xb5\xf9 \xc8\x01{\x8e\x88K\xc9\x08\xf5O+\x98L\x88\x86#\x0e\xa7\xef\xc9\x0e\xf6\x15\x0d\xb7\xbd\x9d\x91\xef\x0fHapnx\x8e\xdei\xaa\xd4}\x95\x1a\x82\x19\xae\xd7W\xdb\xb8\x9a\xcd,j\xbc'\x89\xe1\xe4\x11.\xe3hluEn?\xc3\xc9\xed\x06S\x9a\x93\x03T\x0d&\x85\xf4\x86\x16L\xd8}\x95Y-\xe0\x011\xde\x89G@ \xdb\xcd\xe0\xf0\x92\xb1\xbb\x80\xc6L\x95\xd6Os\xd8\xc5\x94\xa0\xf3[\xd5\x0c\xc9\x06$,\xf1\xb1\xe6|\x80D\xcafQ\x1d#[\xa8+o\xb3\xa9\xda\x7f\x86\xc7\x93\xd8\xdb\xe9\xbe\x1a\xb7R\xbc\x05\x08v\n\x13\xe3\xfb\x18iG\xf4\xbahU\xa1\x90\xfc\xaf$\xbf\xa2YPeL\xec\xbbR\x14\xd9\x85\"\xbb\xe7\x16\xc5\x10\xa2\xe7\x85\x1aW\xd6\xda\x9f;\xea\xe6Ip\xdan0\x1a\x81mu\xd1\x06\xa9Y\xcf]\xf3`\xcd\xe5U\xb4l\xfc\x0b\xb2g2\x06T\xdak\x81^c\xb1p\x05\x95A\xb6\xb7\x13\x08\x16h\xc3\x12\x9aP\x8ef\x89E\xf5\x1d\xcc\x95\x81\xdcNe4\x8f\xa6\x92\x92U\xb8V\x0bip\xeb\x83\xbeyp\xab\x95fa\xc2\xf7\xf6m\x11\xe5\xfap\x83\x81\xab\x83='bS\x92m\xe28\x1b6\xbd+\x12\xcb\xfe3\x1c\xcb\xed?{j \x1bWo+\xd8/\x03j\xf2xH\xaa\x8e\x8aB\x9a.e(\x882\x91\xe6\xd9\xb2\x9a\xb2\xe4i\xcd\xfd\x8f\x18\xa4&\x8cR\xb0\xae86Jku\xa5\x8c&^-\xed\x1f9Knj\x1f\xa0\xd9\xb2Y\x9dH\xad} asRs)T.\xb2l\x0c!P\xc9\x01\xb9\x1c\x92l\x9c\xb0\x94\x87\xebN\x97\xaejr\xc1\xc7\xdd\xd6\x04\xfc\xba\xe9\xa2\xa6\xaf\x9a\xafF\x95r\x1f\xf5\xac\x98\x91C\xb4\xf2b3V<\xac\xc3g\xe6\x0eRIl*y\x16H}.\xad\xd7D\x15\xdf\xf9\x01D\xe0\x96_\x81\x18\xcb\xa6\x1f\x0f\x99\xac\xafZ\xaa\x0d\xfb\x94\x88%\x15TW.\x85\xd0\xc1\xee\x8c\x8e~\xdf\x19=\x1bo\x8f\xce\xb7\xa7\x83\x87A\xf3\x98}8\x9d\xed\x8c\x9e\x9d\xff\xe5\xcf\x0f\x9bG\xed\xc3\xbf\xbb\xbf=\xfc\xed\xe1\xa1{\xb8\xf5\xdb\xc3\xc1\xec\xef\xbf\x1d\xfe\x96\x9e\xffe\xe0\xfev8\xfb;\xfc:\xac\x97\x02\xb3\x04\xe7\x0fgH\x9c\xaf\xe2\xcf\x17\xf1\xe7\xb7\xdf\xc4\xdf\xbf\x8b?\xff\xe5\x9ck\x03\xa1\x99\xf3B\xa4|\xef\x0c\xc9w\xcew\x90\x07q\x80E\x81\x04\xfeF\xf07s\xce\x07\xcd\xd3{\xe6|WV\x15\xd6\x00\xe6\x00\xf0\x1f\xa2\xf8C\xf1\xe7P\xfcy.\xfe\xfc\xaf\xb2\x90W+\x14C\xa1\x12\xfe\x7f95s\n\x1fFd\xb6-\x87\xf4h\xf4\xb7\x8b\xd1\xf9\x1f;\xc3'{_\xeb\xa3\xb0T\x83\x8f\x80\x0e\xdc\xf1_\x06u\xf85ja\xf8\xdftM\xa5!\x1b\xce\x958\x06\x80\xd3\xe0(j\xd6{\xabo\xff\x89\x05\xfa \x88\xcb\x84V.r,\x86\x89s[\x99\x05\x8f\x976\x83\xc8y`\xe3\xdf\x1ch\x84\xd3\x92\x99Zs\xe7-%Uk\xacEE\x83:\x87\xedF\x9d%\xfb\xe8Yri\x93q\xfc\xff\xec\xbd\xeb~\xdbF\x928\xfa}\x9e\xa2\x84\xec8@\x08R\xa4\xe4+mZ\xeb\xc8\xcaF3\x89\xedc\xd93\xbb\x87V\xf4\x87\xc8&\x89\x18\x048\x00\xa8K\xc6\xdeg9\xcfr\x9e\xec\xff\xeb\xaa\xeeF\x03\xe8\x06@\xdb\xc9dv\x07\x1fl\x11\xe8{\xd7\xbd\xab\xab\xe8\xfa:\x17<\x06a\xa6\\\x8d\xc9\xbc\xa2S\x95\xa6\xe4\xb5\xd2\x1b/4R\xa7\x94(\xb7\x1a@\xdde\x0e\xc7\xa1Q)I\xe9\xdb\xec3\xe2\x12\xbaF,-)\x05^\x05i\xb0f9K\xe1\xebm\x1a}M\x19\x05.\x19\x04\"gU-\x81\x80\xc9Q=,<\x01_.\\\xe7\xc81(s[\x94Q\x8b\x14g\\h\xd3\xea|\xe5xp\xc4\xe9\x02\x8c9a\xa8\xd7\x8f(S\xc6&\n\xf3\x9a\x97z4\x1d\x9e\xc3\x04\xff+\xaeV\xbd{\xb7\xbfD\xf2d\x18\xf0%\xa6\xfb\x99@4\xf89 \xe3Z{|\xf5x\x91\xcbA\x9e\x86k\xd7\xf3a\x0fS\x8d\xcb\xb4\xc54\n>\xe6\x06\xf3\x17\xef\xe7\x02&\x90\x91#\xc3\xa5Ew\xbd(\x07\xf0\x16\xcc\xff\xb2\xcc\xf9/\xeb\x02\xc3\x05J\xc1\x17\\\xf8>\x92\x81\xd0\xa4\xd4\xc1\xdfV\xa4\x8e\x1c\x8e\xe0V\x80\x9bV\x18\xc3\x96\xe6\xa9;\xf2T\x10n\xe3\x07(\xa2\xad\xc9N\x1c\xa7\xd2\xc5\xdf?\x8a82e\\\xac-\xfe5\xd7\xd6\xcd\x8b\x82\x91\xffl\x8by\x02\x13py\xe5\xeb\xe9\xf0\xdc\x1b\xe4\xc9\x0f\xc95K\x8f\x83\xcc\xe8>^\x15\x08O|\xa0-\x15\x13\xbb\xaey\x1f@m\xb4x\x19\x81\xab\xa6\x18\xc1\xf0r\xb0\xc6H\xea\xfb?q\x96=\xfd\xe9\xdf\xdf\xed\x9f\xf7\xfe]\xfc\xbfo\xbc\xef\xca\x87\x8dn\x83\xfb\xfb\x0e\xc2\x8e\xea~\xe8\xc3\x81a\xd4{7\xd4\xdd\x9d;\xb0\x9e^\xe3\x8dZ\xb74\xec\x03\xaf&\xd5V#\x91\xd6\xe7\xb0\x87m\xf1-,\x9a\xdf[N\xaf\xcd\x97t\x95&}\xe6\xc3\xb1\x8f\x9e\x87\xfd\x91\x8f\xde\x82\xc3\xc7\xf0\x0c\x9e\xc0F]\x85zfNP\xc6\x1f\x81\xec\xeeK\x1c\xbeD\xf4\xcd\xf4\xd9\xb9\x88/\xdc'tz\xcf\x87\xf4\x12\x9e\xc0{z\xcd\xfb{iP\xaa\xb8^J-\x1e\x13)\xa1\xcaGpY8\xffpJ\xf2\xef\x98\xa9\xbb\xf6\xd2\x87\xf7\xa2\xdf3ZO\xbcw0\xf4\xe1\xd8S\x90\x81\xaf\x8e1\xa1}YM\x98\xb3Y2go_\x9f\xaa E\xee\x99\xe7\xc9\xb5\xb1(\xbd\xda\x82-\xba,\x18_\xf2\x97\x8f\x8bi\x96\x17n\xf1y\x0bG\x15d\xb1K \xfce\xddG[\x95\xf7\x95Uy\xef)\x12\x94f\xec\xfb$\xcb]\xaf\xae\x14\x95\x7f\x7f\xf8\x00\x8e%\xb3\xd6+<\xd7&\x9c(U\x12\x8e\xe7\xce\xb9\xe9[\xe9\x974'\xf4adP\xd5\x11\xec_\x99\xef\x81+\x00\x7fS\x1d\xb2\xa0\xec\xfb\xef\x06\xfb\x9e\x0f?r\x82\x83\xbb\xe8\xc3\x1b\xb9b\xb4\xa1?6\xee$\x88Y\x9e\xc2\x04\xdeL\x9f\xb5\\\xa2?Et<\x15\xd4e\xdezq^\x0d\xffgA\x85_\xd0\x10_\xc3\x04N\x15\xa0\xbd\x80'\xf0\xfa1\xbc\xe0\xa3<\x1d\xccVAz\x9c\xcc\xd9\xb3\xdc}\xe1\xc1S\x18\x1d<\x80#\xf8\x19z\x13pn8\xcf\xc5?O\xa7/\x1a\xc6\nrY\x7f\xee\x97\x8b~ \x19\xc2\x198\x1e\xf4\xe0\xd2\x80\x15\xcf\x8b\x12\xedc\xb9LY\xf0\xbe\xb1T\xdd\xbc\xd4\xfc\xa5\xfe\xd6\x88GO\xe1\xe0\xde=\x99\xeeA\x1b\xbd\xe3H\xc9\xc0\x86\xe8eV\xec\xc3+-vvQ%\x1d\xe4\xc9\xb3\xb3\xe3\xd3\xd3\xf2\x17\xd3\x05b\x0e2\x7f\x93\xbd\xa0\x15\xe6\x08\x9c1\n\xa1\xea\xcd\x98\x83\xbeq\xbe\xdfu%D:\xe9\xfb\x0ez\xf07]\xe8\xeai\x8d\xf0))\x01\xc8\xba\nRb\xf2\xcd\xeb\xdb\x07\xce\xbb9\xccp\xea~)\x08\x9d\x06H\x97^+\x1f\xbf\x9a\x9e\x9c[.E\n:\xc5i\xd6\xac\xe06\xad\xa4\x8a/\xf5/\xbc\x8e\x95L\xf1\x8e\x05//\xb8\xd1/\x8d\xa8\xcf\x1b\xfd\x96\x8b\xd8q\x8dm\xfe\xd2\x80\x02\xdf\"\xc9\xff\x05\x97\x05\xabg\xb3`\xc3x_\x8a\x17!y\xfe\xc5#\x84\xfa\xd6L\xde\xeb\xf0^\x97A\xffR\xe2\xad\\\x92/\x18\xef_\xb4\xbd&\xcb\x9e\x92\xbe\xfeR\xe1\x8aC\x1f\xfeR\x05`\xde\xfc\xf7\xe5\xe6\x8f\xaa\x88\xaf\xad\xe9\xf7u\xf1]u\xf7\xbdW\x11\xb1\x8b/RH)\xc6*\xcb\x94\xa4||\xe9\xd5G\xfd\xfd\x8eb\xfdeQR\xd3A8\xb1[NO\x10\x90\xcb\xb8\xa1\x82w\xab\xd2\xa6\xfa\\9\xabj62\xbb\x18\x0d\xc8\x04e\x05e\xd0\xea\xd8\x04\x8d\xbf\xaa\x88\xb54\xc1&R t\xaf\xbfA\x0f\xfe\xda\x80\x89\xba\xba&\xf43\xfc[\x1a\x16+JP%^p\xdd\xc8i:eU\xd4\x05\x05P\xc3\xa0\x992~\xe2?\x06Lc\x9e\xa7\xc5\x199|\xb6\x1f\xfa\x9c\x88\x92 \x7f\x02\\N\xae\x03\xae\x8aM\xac4'\xec\xbbNhc\xf3&\xd4\x0b\xa6Z\xcc\xe2\x95\xadPh *\x1b @\x96\x87YP\xed#2\xcb\xdd!\xf5\x14+\xe6\x18#\xc1*\x9c\xd1\xb0.\x86\xe0p\xberD\xc0\xc7r]\x0ex\xfc[\x0f\x8f\xad\xb6r\xe2\x18\xa8\xabR\x94/\x14-\xca\x16ij\x0fB>Ht7/phz\xf4\xd5y)ZOSLQ#B\x96\x89\x8a\xc7\xe5E\xec{\xab:q\xber|p\xfexp\xe8\xe0\xd7\xd4FEL\x87<\x96\x83\x18\xdc\xa2\xf2\xe1\x8b~.\xe3)\xba\xd5\xd2\x97\xe1\xf4\xc7du\xac\x18\x1d\xcd6\x91\xdcl\x16\x85\xe24K\x1b\xa1O\xd4\xb0\x81\"\x97\xe2\xb7`\xbb\x14\xc2\xa5\x8aQ\x9e\x8f\x14e\xf8\x18\x02x\xa2\"\x84>\x86\xc0\x9ef\x1d\xfdO\xa6\x81\xc9\x83q\xba=\x17\x086\xdd\x9e7\x8c\x8eB\x93\nQ\x02\xbd&V>\x97\xaa\xc9\x96\xc89H\x11\x0cH\x1d\xf5i\xdc$\xae\xcb\x0eL\xe1\x1c\x85\x82\x90\xd4\xba\xd1\x9c\x93\xd5\xc3\xac\xa2Uu\xf8\x18\"x\x02E\xd6\xf9\xa8Y\\\x9c\xc1\x04\xb2id\x11\x17\x1d9\x16B\xb5\x19\xe1\xf1tF\xd1\x08f\x06\xf1\xd5z\\\xbe\x9c\xc6jf\xe2:zI\xc0\x88\xcb\xd2E\xacNN\xeb2\x86ya[6\xadXW@g_\xf5\x8bHU\xd3\xa2\xa3\xb4\xbe\x9c\x16u\xcem+Z\n\x96T\xdd\x9e\x0dm\xcf\xa6dB\xda\xb4\x1b\x1e0\x04\xf1t\xd3\xa0\xcc\xc7\xd39\xed\xc8\xdc\x12K\xcc\xf8\xb6\x11L;l,\xa1\x82f\x95-\x16\xc8\xe7\xb8\xc09\xf8\x87\x0f\xb0./\\i?\x99\xfaQ\x9f\\CD\xb7R@D\x97U\xc4\x16O\x9a\xf4\xf7\xb9\"\xb0\xd2X\xee\x9e\xcb\xa4\x8a\xb8\x1a\x90=\xc0\xabEx\x92O1\x83\xa2\x162*V\xd2E]V\xd6\xaf=$\x07\x1c\xa8VB+\\)\xe3\x03~]\xe9\xfe\xf8\xf5\xcf\xa5\xf5Y c\xc3\xbe!\xdf\xbbmC\x94\xf0\xcf\xc4\x9f\xbcM)\xff3\xfa\xcb\x17\xd8G4LL\x93+\x0b\xb14\x922\xfc\xc3\xd7\xb1tR\x999\x13\xeat,}+\x18\xfeQ\x9a\xc2\x87\x0f\x107H\xff @\xfc\xaa\x8c\xe8\x16\xc1R>x\x04\xd8\xa2\x03\xf0G\xd1\x90+\xe8\xc1m\x87\x05T\x18\xa1y\x99\xe8\x02\x91\xa2\xd4\x9f@\x83\xe4IU\x99\xce9\xe2(\xa1x[H3\xf5\x05\xb8(\xed\x173\xb6\xc4:\xb5t\x0d\x13\xb8\xe0\x8d\\\xd2\x16a\x9bD\x17E\xedz\x9d\x13\x98\xc0u\xfd\xf5MmR\xdad\nL\xe4\xfdL\x0d\x11\x17\xcf8\n\xafJ\xb4\xa0<\x90z\x1b\x1a\xb9\x06:\xfc\xd0X\x8bA9?\x13\x1c\xa5\x84\xa7\x1a\xdc\x92sN\xb1\x08\xae\xe0\xe77\x1c\x81\x8f\xe8\xbf\x89\xfc>\x86\x1b\x85\xb0\xf4\xca\xf34t\xe2\x0d\x97YM\x99@P_\xac\xdc5\xabu\xbd\xa2\xaeW\xd45\x93]\x17\xb4\x82\xa9\xae\x15q\xc2\x0c\x7f>n\xedu\xad-D\x135+^\xef\xc23\x13\x01)\xca\x90R\xa6\xba\x8e\x15\xb6[ B\xa9.\xbe<\xd2\x7f\x8c\xb5\xba>t%T\x1c\xbc*WY\x903\xf0\x8d]\xa9\x13[<\nso\xe8*\x8b\x0f7\x83M\xb2\xe1\x18\xc9\xdf\xdcH\x17\x96\x95\xd7\xb5[K\x7fx\x08\xffb\x1bE/\xd3\xb71Et\x9e\xbb\xb2\x19\xa3|\x8c\xe0\xe7\x95\x17M\xad\xfa\x8d\xe4A>\xb8\xaf\xb8\xd2\xbc\xe7\x16@H\x7f\x15\n\xed\xbf;\x1eyD\x17\xdf\x04b\xfc\xbb#\x8e\x92\x14\xf1~U4\xac:+\x0d\xe1U\xc1\xfd\x1a\x88`\x87\x85\xf2A.\x89[`=\x8eF{/\xe9?\xdf\"E\x93\xb5\xf2p\xa4\x13\x901g\xa2\xa8\xb1\xc9\x11\x1c\x15\x83\xc1\x8f\x9f*\x02\xee\xdd(xQ\x93\xdcT\xbd\xf6J\xbd\x8a\xb1\n\xad\xb5\x18D!\x9dJ\xd2\xd1*\xe9+\x99\xe5\x98v\x1e\x8dw\xfd\x91\x87^\xb0\xefiA\n\xca.\xff\xba)\x0c\xfaB_w\x06\x84e\xc7\x88q\x03\xf9\xcb\xd3\x10\xf0X\x9c\xef\xfa\xf0\x12\xfb\x92\xb2\xe6Kx\x8a\x12\xe8\xcb~\xdf\x03\xd9\x0e\x1e\xc0\xdeL_\x9e{\x9c\xd4!L\xcd\x98\xfbR\xdc\x7f+:\xe0J\x7f\xf9\xb3O\xa6\xe81<\xc3\x81\xd5>\xf6\xfb\x06Z\xbcG\xe7\xd5'\x16\xc3\xf7c^\xed1<\xf34*\xcb\xc7Pi\x89\xb2\x10\xead\x9a\xaf\x95\xb8\xfb\xf0\xf0\xfe\xdd\x07fM\x8ck\xfc\x87\xf7\xcd\xdff\x18f\xdc\xf8\x89\x83\xf9\x81\xa5\xda\x867\xf9\xd0\xfcm\x0e\x13xP\xbd\x13'\x1f\x8ez\x0f\x0e\xcc\xdf\xb8n9:\xb0\xb4\x8a\x91\xf1\xfa\x16]s\x89~\xc97q\xbf\xbfo.\xc0\x05\xa1\xfd\xe9O\xefn\x0e\x86\xfdw7\x0fN\xce-\xe5.\xb1\xdc\xbb\x9b\x83\x93w\xdb\xc3\xe1\xf0\xe0\xdd\xf6\xbb\xef\x86'\xfc\xdf\xfb\xa3\xf3\xfd\xa5\xb9\xd2\x855\x8f\n\x7f\x92+\x96.\xa2\xe4z\x0c\xceK\xf5'Em\x8c\x19\x9bgp\x1d\xceY\na\x9c\xb3%K3\xc8\x13\xd8\xa4\xc9\x8ceY\x83b\xed\xc4I\xde\xbf\x0c\xb2p\xe6\x8c\xc19\x8d\"\xb6\x0c\"\xd1*\x17\x1dn\x1e\x0e\xc1\x8d\x93\x1c\x02\xc0R\x80h\xb4I\xc28\xf7\x9a\x9a\x0d\xe3\xab \n\xe7}l \x9b\xa6\x17\xd4\xb49\xf1\x9d!\x9d\n\x08\xc55\x82>\xcc\xcc\x9f\xb9\x8e\xfac\x90\xaf\x06\x8b(\xb1\xe5\xae\xe4:\x01\x19\xb5\x07\x8b4Y\x1f\x0bo\x1a\xcd\x9dX>\xca\xad\xf8\xcc|<\x00*\xc6\xfe\xeb ^\n/\xdc\x8b)3\xdaE\xed\xad\x1f[o\xd4A\xd5\x1e\xaeB\x85\xa2I|z\xfe\x18b\x0c\xc4\x9eR\x84X\n]n1hI?\xe5\x9d\xc6\xf6\xbeql\xc5\xb0\n\x89\xc2\x0e\x07\xa9\xe1\x00P}\x93\x02y!\xef\x82<\xf8\x89\xb98\xd5\x03\xf4\xfbC\xceON=)\xf4\xe0\xd8\xa5\x13Su\xe6r\xe9s\xc9\xd6S6@\xca \xeb\x15N;;\xcd\xfe\x99}\xdf\xd5\xb6P\xac\x06\xda\x0e\x1f\xaf:\x0d}\xe1D-\x05\xef\x84\xae\xa9\xb9\xa4jk\xee[I\xaf\xe7y\x1c\xb5\xee\xdd;xt\x9f8\xc7\x93 \xdc\xbb\x7f8z\x84R\x0b\xaf\x08G\xfc\xc5\xc1\x10\xe3\xa2\xdc\xbf{ot\x00\xe24\xad\xde\x96G\x01\xce\xb8\xbc\xea\xba\xa3\xe1\xc1!\xdc\xe1\xbb\xf7\xe4 \x8c\x86(\xc5\x88w1\xffq\xff\xde\xbd\xc3\xfb(X\x89*9\x17\xa0\xb8r0\x06\xf5\xe6\x0b\xc2\xd2K\xfbj\x8a\xf6\x10\x13\x9a\x8f\xe4\xe4#O\x9el\x00\x05\xfa\xbd\xa1\xa78\xd7{\xa0\x0e}\n\xa3!\xdc\x01\\\x9e\x0f\xb4\x1dB\xa0\xa1\xb5\xff\x00b\xe5\x18\x1d*\xf2&\x0c!\xcd\x01\xcf\x02\x05\xb4\xed\x08l\xaf\x1aQM\xcd\xa5\x07\x07\x07\xd0\x83\x07\xf7\xe0\x1bp\x19<\x81\x83\xfb\x1e\xf4\xc1u\x87\x18\xcd\x0c7\xfb\xden=\xbf\xb1\xdd<\x90\xcf\x95\xb8\xfd`I\x89\x82\xb8\x80\x98 Gp\xe22\xd8\x879\x06\x95\x03\xbe\xae\xc2G\x81\xde\xe7\xdec\xdc\x8fk\xf8\x06\x16\xf8\xf91G\xe4 D\x1e\xae6\x95\xban\x06\xbb\x13\x97\xe3\xbe{\x8d~3\xf0\x0d\xf0*._\x99\x8d\xb7\xdb\xc4\x7f\xb4\xc3\x98\x86\xdaz\xce\x18L\x075\xf7a\xe9\xc3-9\xe2\x98\x8c\x9a\xf2\xb9\xd0I\xb6\xb5\xd4\xb5\xf9\x16\xbe|8\xbf\xba\xb2\x7f>\xae\x1b\xc8\xe4\x83\xfb\"(\x85\xeeA\xbd\xf6f\x82\x82\xd0\xf3\xe1\xc4\xbdF<\x86\xa7\xc0'xc\xe8\xea\x86\xf0\x9d\xca\xf1\x89\xfe\x11\xb3\x03_J\x0b\xd1u\xaf\x87\xa1\xa7n\xba\xfa\xfcA\x81\xfb/\xdd\xcb\xddp\xfc\xf4sq\xdc\x87\x0b\x9fC\x9b\xb8>QMr!\x1f\x04\xccK\xe9\xc3\xf5\x0c]\xb6\xa4\xb0\x96#\n\xa3\xa8$\x84\x83U\xc9{\xe1\x92c\\\xe0\x11tN\x83s\x8e\x9e\x02\xd5\xde\x13j\xdd\xb85\xaf\xa0R\xc7)\x06{\x99\xc0{\xd5g\xa2\xd5^{\x84\xd9\x97\xed\xa8\xc5\x91)k\x19\xdcS\x91\x81\xfc\x16\x9e\x88,\xe6\xbc\xd6m\x837\xa8h\xba\x0fy\x81\x1a1G\x0d\xf7\x02c\x82pBn\x02\xda\x98C\x12U\xe4\x84\xfe\x82\x96rk\x1a\x9f\xb5o\x10\xa6\xc7\xd2\xea\xe2\xf8{\xbd\x18\xa1\xb8\xde\xef-P\xda3\xfbb\xc9\x07g\xc6IK\xec\xa3\x8e\x1a=\x96\xc8\xcc\xd1q\xce\x919\x14\xc8<\xe7\x0b\x17j\xc8<\xc70(\xdec\x98\x0bd\xe68\xb8\x81>\x87<\xa9\xe8,\xfd\x02\x04^\xb9K.\xf3\xc2\x1f98\x0e=O8\x15\x9c\xb8\xc7\x0dF(O\xf9\xb4\x13OAj\xafW\x97\xf0\xf4\xe7c\xaf\x17\xf3R\xf5\x84S\xd0\x86\xc7\xef\x9b\x84\xa4\xea\x9b\xadU\x17\xbebi\x16&\xf1\x18\x1c4\xe6X\xb4\xd0\xed,;0\xe5\xb2\x96\x0f] \x1a\xc33;\x9b%\x1f\xb01\xbc4O\xd5b\xb4\x10\xed\xfeh\xfe,\xdb<5\x7f\x16.\xf6\xe3\x8e\x12\xb1\\\xd8\xee2\xb4V\xebv\x90\xb3,\xa7\x98|\xceM\xdc\xef;\xd0#\xd2iJ\x99-\x9f\x8f\x16\x02n\x9b\xcf\xdb8\xa4\x19w\x1b\xdfg\xcdh\xa9\xcd\xe8GW\xe6\xa6\xb9[\xb9k\xf8i\xf3\xab\x83\xac\x0fZ\xbeD\x94n\xac\xa6Y\xf9\x88qn\xeb\x8d\x15\xc1nP,g\x14\x02\xd3\xd5c}$\x15\xffC\xdd\xe3\xcf\x90\xe6\x86\xffy8\xb2d\xbb\xe9\x14\xdfC\xef\xbc<\x1f\xe9\"\xd8\xb6\xabb\xbe\xa6\x0c%\xe5\xb9\xf8\x95\xe6\xc9\x91\xaak\xf3\x16K\xab\x88\xf58i\xeb\xec\xc56\x8a:v%\"\x85vjR;1\xde\xad\xf5\x1dC\x89u\xda\xcb|@\x84 \x0d\xf8\xf2\x16z\xec>|\xf4\x88+\xb7\x03\"Kd\xdd\x97\xde\xc9@q\xaa\xba%\xf3.\xf7\xaa^+\x91,m\x8a5\xd2\x12\x99J%\xb1\xa9e\xf0\x81\x96\xb0\x87>\xd4l\xf8x\x84\x81G\x89w\x1cbzxC\xd8\x99\x18\xf2\x8a\x07\x86L\x90\xa19M1zC\x0c\x853D\xe5\xc89\xa8\xb7\x8cqE\xde\xf5\xf6+\xc29\xd3\x0ckU;\x8ct\x01\x1d\xb1\xc3\xca\x888\xac;1\xe6\xa3\xd1q \x1c\xac\x83\x9b?\xb3[\x14v0\x85\xa9zch:\xd2\xcdW\xa5\xaf\x99\x0c\xf5\x19I\xc9 \x13PV\x1bQ\xd61J\xa4\n3\x8c,\n\xbd\x9e1\x833zLJ\xa9{\xe5\xa3\xc9\x9eMg\xc5\xfd\xff-\xfaQ\x0fm\xc6\xc55\x17\xaf\xd5\x81\xa7)5\xc6\x1a\xed\xd7p\x04\xee\x02\xcb\x16gTk!D\xa9wk!\x8c\x8eEY\xfa\x8c\xc7\x94s\xf3\xed\xe1\x85\xe7\x83\xe5b\xf1\x86k\xd6n\xe0\xc3\xdc\xa3\xb0\xd3\xd39\x1e\xb4\xf3\xffI\x16[a\x1cTr\xe0\x9c\xf2\xff}X\x9d\x17\xafV\x16\xec\x87\x02a\x82\x02\x0f\x8a\x89\xe3\xf9\x97\xcc'6\x083\xfc\x9f\x83e\xab\x8by9Q\x90\xb8\xba[CJ\x19&\xb2\x1ecgw\x02\xa1\x8f9m\xf4IWYld\xf8\n\x030atO\x89\x94\xcdA>\xebpB\x95/)gTKm.)\xe5\xe9\x96a\x94\x8bE\x10e\xcc`\x8a\xa4\x06\x05>6\xe7B\xc9\xbe\x0b\xe30g$\xb1\xd0\xc1s\xbd\xbd9[\x04\xdb(ol\xc9q,@\xf3\xd1\xcc\xce\xeb\x84\xb2\x16sX\xb4l\xa7\x97\xbe\xc6\x0dA\xdef\"\x91\xc8\xb3\x1c\x7f\x1eA\xe8\x06(\x9b\xa8\x01\x046\xea\xc0I\xa4\xe1\x16F\xea\x06x\xb5\xc2\x90wW\x8c8qI\xe3\xe3\x9d\xf1\xbf\xba\x08\x92R0\x83\x9e\xb9Of\xb22\n\xa3/\x86\xc2\xb2\xd7\xe4c\xa9\xde\x1c)U<2W\xdc\xd24\x1bF\x84\xf0\xf2\xfb\xa2\x04\xe6`o&\xd6O\x0e\xfa\xeb`\xa3\xe5\x92\\\x07\x9b\x1a\xdb+\x9d\x85M\xcfKV\xcb\xe2\xb8%\xed\xf5<\x99\x035w\xd94\xe5\x05-\xfe*\xd5d\xa8\xa0q{\xcd\x81\xbfy\xbd\xae,\xf9O\xcba,\x99\xd7Y\xb6\xa1 \x97\xbfR\x1a\xd4\xda\xea\xef5\xeb*fb-\x9fn!0\xe5#\xc6\xee\x96\x82.\xe5\x82\xde\xc5\xec\x1ar\xb7\x80(\x97S\x8e\xcb0\x0e\xd2[\xc7\xf3\x8a\xd7\xcee\x90\xb1\xfbw[-\x07V\xa5\xe8\xde]O$M\xed$\xce^iY)\xcdA\xdd\x0f, \xcf\x0f\x87\xe6\x84\xe7\xf7;\x05\xf47\x1c\xc8(\xde3\x01\"\x9d1\x14\x19\x0bb\x91\xb1 uC7\xf6\xd0\xc2\xaa\xc4O_$ \xc6P\xacB\x17\x8e\xd1\xbeV\xb8\xe6 un\x81*}@\x9f6p\xc9 \x84\xbe\x8c\xd7o\x14\xc7`\xf0\x84\xe6\x81\xf0\xe0)\xad\x1a\xaf.j\xa5\x9eN\x14\xd4\x90\x13\xf4n\xc8p\xa5%\xfe5E\x84\x1f\xd57\xf3n\xdb\x86YfL\xb9\x16\xe0\x03\x84m2\x92\xde\xc0^C\xc3\x16\xed\nt2\x9b\x9bQ\xd0\xaa\xaf\xc8\x95-.\xfb\xf9\xb0?\xfd\x89\x02\xf2\xbd\xeb\x7f\xf5o\x7f\xbc\xf3\xf57\xbd\xc1\xbb\x9f.\xfe\xcf\x87\xff>\xdf\x0f\xa5m\xc5\x12\x88L\xfaw\xccVA\x1a\xccrtD\x81\x15\x0b\xe6,\x85E\xc8\xa29\xc4\xc1\x9a\x99\"h(\xf2_\xb2\xd2\x94\xd1\xda2\xe7\x8ef\x87\xb6iW\xf5msg\xa9\xb93\xc9 \xcc\xd4/f7\xba\x19\xc3F$Ak\x88I\x7fK\xbbqWL\xd0\xde\x16\x7f\xe6I\xcc\xc6\xba\x8d\xca\xe0\x10\xa8?\"6\xbb\xd9\xb0\x0b5Rk\x7fkH'%\x06\xbc\x1a\x849\x85\x88\xa7s\xf9)%/\xa5\xb7y\x92\x9e\xef`D\xab\x8f\x13\xe3\x97u\xda\xca\xc4\xbc\x95\xe8\x9f\xb8\x0e6\xa8\xf6\xfb\xe50\x81\x89\x0c>z\x12\xccV\xed\x81\xb1Us\xc1f\xc3\xe29%\xbb\xa9\x8f\x98n`\xa3G\xb5.\xab \x85\xc0\xd0]\x97\xbe\x18:\x98\xb3\xe9\xc8\xe4\x94T\xf4\x88{ \xc4\x93%\xcb5\xa1\xe4E\xb0f\x99\xcb\xbcz\xff\x9d\xe7:\xcd\x1b:\xef\xb4G\xa1\x9d\x9e\xb1\xc1e2\xbf}\x9b\xb1\xb9\x12\x1e_\xa5\xc9:\xcc\xd8 exC\xbaB\x9c\x9eE)\x0b\xe6\xb7\xc0\xffuL\x87jE\x8b\x18\x90\xad\xd3\x00\x83f[\x1e\xbb\x96\x83j\x0f\x02\x0e8\x84$\x8e\x92`\xde\x05\x05\xf8\xc3\xc5\xa6\x94e\xdb(\xb7Y\xe4\xb1I\xc6W\xa0k\x9b\xb1\xcb\x06X\xa1\xb3\x11\xbc\xdb^n\x9bI'_\xab\xef\xc2\x88\xbdFva\xa6R1\xca?&\xe7$I\x0f\x06|w\x9feZ\xb2c\x12\x97:\x8d0k\x826\x94\x9dj9\xef\xabn\xfdP\x99Q\x91b\xd8-\xa5\xe9l\x98A\xc6\x08t\xf5\xaa\x18\x82B\xa4j\xec4\x95\xa8)K\x05\xe2\xa9\x0e\xeb2\xdc\xd1E\x18\x87\xf9\xb7\xc9\xfc\xb6\x93P\xcf\xd7\x85\xaa\xf1\xb6N\xe3\x10\x19\x97\x91\xc6\xe9UL\x07\x01\x1e\x14\x0d\xbda7\xd8\x90\x9d\xf3i\x17\xc1.\xa3\x04\xc3\xda|\x1b%\x97\x9a~\x15f\xaf\xe4\xdf/\x17B^\x91\xed\xf3\xa2\x9d\xdb_$\xe9\xfay\x90\xa3\xf3\xf4w\xe2\xef\x8e\xfd\xc8\xe2\x9d\xfb\xa2\xcb\x05\x18\xcc\x15-\xaco_\xffp\xa6\xbd\xea\xd8\xad\\>M\x9d\xea\xd4{P\xa0\x0c\xe0\xf5d\xb9\xb4\xebJ\x07\x1an\xc1\x84\xe3\x8cL'\xeaC\x0d\x1a8\x1c\xf3\xf5v\xa7\xc6\xfa6\x97Uh\xbe\x07.\x1f\xbcXT\x1e\xf9\x87\x0f\xb0\xa7u\xd0\xb0f\x80WH+\xb2\xac`\x15\xdb8\xdbn\xb8\xa8\xcf\xe6\xf0\xad\x9c\x0d\xaf\xd9\x16\xfc\xada\x95\xecH!s\x94T\xb7\xd0\xe6\xe2H7(\x90Lf\x9ci\xbb\xce,\x89s\x16\xe7}\x1a\"\x1e\x1a\x9a\xb0LE\xc6\x11u\xb3Z]\x1f\x9c\x9c\xdd\xe4\xfb\x9b(\x08\xe3\xc7\\\x8c\xcfX>y\xfb\xe6\xbb\xfeCG\x05\x97-\xb0H\x86\x8cRo\x06\xbc\x95.\xdd\x18\xaayx\xd1\xf5\xd3\x91@\x8d\xa6qz\xc1f\x13\x85\xb3\x80S\xb6\xfd\x9b\xfe\xf5\xf5u\x9f\xa3x\x7f\x9bFda\x9bWgm\x94`\n\xec \nxI4\xa5\x95\xbf\xca\xeb9!\x8521\xef/\xf2\x1b[@j\xbdPy\x11\x0db\x90\xc8\x04P.\xd6\xa5=\x0dz\xad\xcd\xb6\xe2v\xa7\x9e$\x954`\xe1,\xd9r\x8d1\xc9QdS\xe4\x17x5\x082\xe0\x8bnC\xc8\x1d\xc6\xcc\xb1\xadj\x9d\x85BP-\x91\x97\x0e[\xac\xf3\xd8\x1a%8\x92;\xcfq\xd4\xbeO\xa5\xe5\x17X\xc7g\xebz\x83|\xc5bwk2D\x8b\xe1\xe6D\xfeZh\xd2m \x8ak\x05\x06\xc1Q\xda\xfb\xd85i\x88n^\x98\xf74Kx^\xb1\x84OQ\x956\\yq\xf3i#\xeb\x95\xda\x8b\xddU\x0b*+\xa6/D\xa7\x95\xfb\x0c\xb4\xe7\x00\xbe#\xda\x97\x91\xddB\xd1uQ\x8fj,\n \xae\x15\x9dt\xb4\xe7#\x94\xa8\xbah@\xd5\x9f\xb3$\xfe\x9c\xb6\xfft\xf6\xf2\x05\xf9qX\xa9W\xe9\xbdMY\x98Y-\x18\xf2\xcc\xc5U'\x80\x7f\xff\xe8\xa1\xeaP_\x7f\xa4\x15\xba\xb5\xc4x\xe6\x0f\x06\xf5\xddhK,\xab\xeb\x0d\x92\xd06%\xb7\x85m*S\xed\xccR6gq\x1e\x06QFn\xdf\xc5o\xaeF \xf9\x00\x8a\x00\xb7\xe2\x05\xa1X\xe22\xf9FE\xfe[\xb3|\x95\xcc\xb11\xfaS\xbe'\x87\x19\x86\x7f\xf8t*\xaa\x1cx4I\x18\xef\x1cC\xe9\x9d_\xb57\x18\xf6P\x13\x0ci\x96\xca`i^~\xc3\xec\xf3\xd2o\x19\x98\xb3\xf2\xceI\xd6a\xee\xf8\xb0W,NE\x98\xb2/Vn_\xacv\xd2W\x98;\xf3\xe4\xedfc\xcf\x04\x00\x05\x1a\xdc*\x8f\x0ftF\xef\x8f\xb8\xbcit\xe7\xfb\xe8\xe6r0r\xe2\xc5O\xe7?N\xde\xa8\xe8\x87k\xe9\xf8\x84\x7f\xa8\xc2\xe2\x87\x96\xc5)e\x0b\x96\xa6( \xd0[\x17\xdb)BRj\x1d|\x7f\xf2\xecy\xed\x0b]\xc7\xb7\xc0<\xaa\xdex\xd12\x8a\x92k6G\xb6\xf0\x1f'o I\x81\xb7\x06)\xfb\xdb\x96eyfB\x08\"rR\x83w\xe3nV\x99E\x07\xab\x8c \x83MV{L\xb1!/\xdf\xddq\x0cV\xc3F3B\xabxP\xbam8i\xbam\xc8\x9f\x94.\xdd\x93\x05]\xcb&\xd2\xc3l\"\xd0V\x1d\x0f\xf7\x04\xf3\x9b8\xc6\x06\xec\xcc3\x97\x16P\x83[\x10\xd7\x91\x0d\xaf\x13\x83\xf4 \x16S[W\xeb\xf6\xa6}_\x93\x86\x0d\x951\xf4\xd3\xa3w\xf1\xfe.\xbbY\xdb\xacq\xdb\xd5\xd0b\xa3\x08\x8a\xec\xe2C\xed\xb6\xbf\xfeH\x7f\x07\xb9qc\xa7\xb9A\xd0\xf7*\xf5\xab\x9e\xb5\xf2\xf9\x9c=\x98[\xf9*q\x84\\O\xb8B\xaa\xf3\x04\x1c\xe1\xea#\x95\xe4,\x0f\xf2-'\xb7\x0e\xfd\xe5`jLN\xf3\xe4\xa71\x1c\x0c\x87\xa2t\xf2^\xc5\x8b\xa5\x8fO'\xfc\xab\"\xe7\xe2\xed\x138TU\xe8\x95\xb49\x14\xbfj\x1da\x9118/\xff,\xc7f\xe7\x05\xbe\xce\xb5r\xfc_\x84\x9a\xab\x90\xa9j@\xd5\xd2/4\xf0\xb0\xc1\x82\xe5\xe68rW\"\x16\xa0\x19*tS\xc2\x18\x9c\x8a%\x01\xa7g\x08w\xc6\x1fy@5\x06\x87\x0e\xa7\xa80\xfaX\xcac*|E_\xcd\x8dp\x85m\x0cN\xa1\xd0h\x8dp\x0d\xa3\xf8\xd9*\x00\xf2'Oo[\xcca\xda\xa1\x03o\xdf7eO\x96\xcfG\x98\x05\xe8R\xd7\xd5\xad~odo\xcb\x8c8\xb6l\xc0R\xaa\xe6k#\xfel\xda\x0bM\xfd\x1e\x83\xa3)\x1aT\xa9\x8e\x9ef\xd1\xa8d&\xf4\x10r\xae0\x95\x9dtv:\x95\xfa\xd6\xb9\xe3\x17.P\x85\x1aV\x7f}\x1c\x05\xeb\x0d\x9b\xd7\xbf\x9e\xc6\xf9\xe8\xbe\xb9\x92\xe9\xfdi\x9c\x1f\x1e\x98\x8b\x9b\xde\x7f\x17%\x81\xfd\xc3\xfd\xbb\xe2\x83\xe5z\xea\xba\x93\\\x06\xba\xeb\xc6\x9d;\xc07\xe9/!\xbbn0\xbf\x99\x81\xc0<\x88\xa5\xf4K\x13V\xda0\xe3\x8d7;[\xe9\x8f>\xb4\xc2\x01\xb8\xd5E\x8d\xc4E\xf3@\xebP\x93h-\x11\x9b\xa8\xf8\xbbX\xd9\x11\xa3\x90\x0cB;\x8f\xdd\xd4\xc2\x82$\xcb\"\xf10\xd8L\x99\xe5\x8e\xa1V@$wO\xa0\x07\x8e\x8f\x81\xb1al\xba\x8f\xef\x97\xc6?g\x11\xcbY\xa7\xad\x17EU\x97|\"\x86\xbc\xda\xe5\xf6\x97,\xef\xd4\xb8\xda8\xb9@\xc4F\x82\x8c\x0e\xbb\xf5y\x8e\xcb\xa9R-\x1d\xaf\x82\x9d\x1c\xd0d\x07\x15\x07<77;w\x96\xfb\xca*\x93l\x80\x80\xf2\xea hk_\x08Ym\xb9Y\xe5SI\x96-z\xf4\xacs$\xe7B\xa6\xfc\xe1\xd4\x18\xe3s\xbaqT;\x957\x8c\x11\x9d\";\x98,\xa4u\xd1vkV\xdf\x8f\xba\x83A\xc3 9\xe0)\xb9p\x904\xa32\xfa\xde\x9bM\"\xfaT\xd0\xd5\xe57\x98L\x87\x99\xd8N\xef;\xce\x84\xc5y\x1a\xfe\x16S\xe9\xb6/S\x0eL\x06\xcf\x0fh\x99R\xc51H\x9b\xa1\xc9E\xc8\xb0\x00\x96\xb3\xf8[\xe4\xf3\xcfO~8ys\xc2\xf9%W\xd8}\xa1\x9e\xfb\xe0\xbc|\xf5\xe6\xf4\xe5\x8b3\xfe\xe7\xab\x97g\xf8\xe9\xd5\xdb7\x8ea\x81fZ\x97\xb3(\x89Y\x97\x15\xd7\xa4\xb2\x19ZP\xfc\x86\x15\xbcL\xe6\xb7\xfa)\xdbi\x1cZ\xee\xd8\x1aWP\xa4\xcb\xd7\xc6\xe9\xa9\x97\xf3\xd2\xcb\xf9gNe^9\xf9o\x9a\x14i\x0fc]\xdb\xb0k\x84\x85\xaa1\xae\xaa'\xf6JB\xeb\x18K5D\xd3M\x1a\x94\xcfm\x1a\x8d\x95\x9a\xb2\xc3*\xcf\x07\x9d\xfdi$\xba\xd1\x92\x91\xc5\xa8}\xa1\x1a\x82\x82\xe8\xcb\xe3X\"h5\x9b\xcf\x98R4q\x16N\xd5\xf3\x11\xcc\xd2\xd0\x95\x88c==\x1c\x8e|8\x1c\x1e\xf0\x7f\x0e\xf9?\x0f\xf8?\x0f\x0d\xe82\x1f\xa4l\x1e\xa6\x1d\xd2\x8d\xcb'\\\xa8\xfc.\x97\x9a\x95O\xb7\x96i\x11\xb7\x94\xbb\xa9Pjg\xc9\xdcz@_\x02\xdd\xae\xfb\xd0\x05\xe2\x9a\x95\xa7(\xa1\xa3\xe6\xc6\xcb\xc6;\x80\x1e\x1b|\xafT\xee\x84\xff|M\x06A\x98\xc0\x8c~f\x9b$\xc6{\x9ds\xfe\x1b5\xe7\xae\xab\xaf\xadQ\xcdi-n\x10v@\xb7\xbe \x99\xc3^\x9aml\xa1(\xfc\x9f?\xfe\xf0}\x9eo\xc4<\xec\xa6\x9apG\xcf8\xd0\xb0\xaf\xb9\x14h;\x1e\xb6\xd2\xa7r\x0dB\xc4\xb0\x13\x91\x92\x8f\x02\x9d\x8d\x1br\xc1\xf9Y\x14\xc9m\x13\x9b\xeb\x8a\xa8\xbev\x97\x110#\xa9\xfe0a|qR\xd1\xf8\xdb\xd7?\xa0\xca\x1c\xc2\x11\x84\x03\xed-\x8c\x81\x95\xfdI\xfe\xb3/\xf6\xa3\xcf+\xb5\xf8\xbcH\x93\xa2\xea\xc8\xd0\x0b\xe6\xe9\x97?\xf8257\x19\xbb\x82\xc7\xe0%x;\xe6\xf8\x08\x16\x9d\xa9\xb1|\xd2\xaak\xe8\x0b\x96_'\xe9{i^\x87E\x10Fln\xf2\xfd\x90\x8f\xe8:\x0f\xd7,\xd9v:o\x97\xcf\x17\xeb|\xc3b7Q\xc7Q \x9d\x7fa\xaa\x1d'\x8cg\xd1v\xce\xe8\xf0!)\x9d\xf6p\xc9*\x1c\\\x87\xf9\xea\xb8tND\x15\xd5\x16\xddn\xe46\x96|\xc1\\m\x17\x05\x17!/\x0c>\x00 B;\xf9G\xcb'\xe4\xea\x95\x80:B\x03\x8b\xbb\xb4|\xb8$\xc9+\xc5sWsoO\xb4C\xb7#:\x8a\x1b\xeb/mR\xa9\x99\xd8\"\xf9\x1cl\x92\xe8v\x11F\x91\xc9+X\xfd\xe5:[y\xd1_\xbfk\x90\xb1h\x01G\xf4\xdfXS\xb1>\xeb\xa2l\xec>\x1a\x9a\xae\xaf\xf0\xf7\x0f\xcd\x17\x92\x1e>\xb2\xdc<*\xef\n\x85!\xe6\x84\xb0\xdc\n\x1e2\x8f!)\xbfUQ\x02\xc6\xb5\x9c\xf7\x9f9\xbf\xc3\x87\xd5y$j\x1e\xf5\xf9\xd5!\xeb2\x0df\xef\x19\x9fHg\xd3\x00f\x84\x9b\x9e\xd7e*\x83\x0d+\x8c\xe7\xe1\x8c\x95Zo\xe7\xab\xd4\x01f\x96\xa3\xe4s]zJ\xd9\x86\x05\xad10@\xeb\xa5\xdej\x19d\xeb\xf7\xd2\x9e\x079+Y\xcdN\xcf^\x92\xe1\xac\\\xd6\x1c\x8dg\xce\xa2p\xcd\x15\xb31\xde\x0e\xae}\x97\xc1n\xf6\x0cR-}K\xc7\x90\x8a\xe0\x13\xb6\"\x7fA]\xfde\x1c\xdd\x8e\x8d9\x063\x96\x86A\x14\xfe\xc2\xf8\\vX\xad\xa0v{U>\x86\xbd\xc8\xde\x87\x9b\x17\xdb(\xca,c@p\xe6\x05\xbe\x0f\xe2y\x84\x91Q*V\xf3J\xa3\xba\xc6\x0eL\x04~Q\xf1\xc82\x1f\"\x9f\x8buE\x88\x04\xd3l\xa4%\xdb\xc0R\xd1\xdbZv\xa0{\x82F\x1eV\x89\xb8Xwe\xba !\xdd\x82\xaft\x7f\x0e\xbe\xb6Tq\xe36\xd6RW\xc2\xaf\x9a\x04\xfdP\xb9LQ\x06\xb4\x15\xa7\x93|D[\x01\x0c\xe8\xfbf\xb8\xe2\xcd\x9f+\xf4\x8fm\x81u\xb0{\x9c_\xa1\x84U\x8f\x97A\xefe \x80\xea\x87t\x10f\xe2V\xc1\x95\xa7\x0d\xff\x08\xa6s\x17#\xc4\xc3\xb8:\x07\x8f#\xfb\x84\xa3\xfd\xdc\xcd\xdc\xab\xd2\xa7s\x18\xf3\x9a\xb1^F\xb8x\\y\x9eA\xa5\xe2\x9b\xbd\xf6\xd1~n\xb2\xe0\xe0\x96\x15\xcc\xf0J\x0d\xd1\x10\xff\x8f\x97-\xdf7\x8a<\x0f\x8f\x07\"\xcb\xd6\xdaU\xdc\xdbJ\xda3\x13t\x808|\x98\xc1\x11\xdc\x0e\xb2$\xcd\xdd\x19\xdf\xe0. \x9a\x94\xa9\xf3\x92\xbc\xdd.\xe1 \xac\x95\xb7[\xafw\xd9\xa4\x7f_\xc0\x04\xd6\xd3K\x8b\xc1\x0b\xdd\xbd\n\x80\x9d^`&\x07wY\xbd9\xef^yp\x04K\x99S\x86\xb9\xbc\xa8\x0f FP\xf3Z\xd0\x96\xcf\xb3V5\x86\x1e\xb8\\8p\x06|\xe7/T\x9e\xd2\x0b\x95\x9b\xb4\xb9Q\x03\xd1\xaa\xbd\x91\xfb_&CfQ\xa0\x91\x99\xa9s\xfd:\xe1\x0b\x80n\xe5\xa6\x83 \xcb\xc2e\xec\xfe\xfd#606\xc6\xcdQ\x01\x99\x02\x89\x07x\x8aS\xdc\xf7-\xbd\xd7\xc8W!T\x05\x05\x810\xba\xd1\x9c\x88\xfa\xab\x00\x03\xa0_2\x08\xd4\xe4j9E\xaeD\xdc\x1b\x0do\x82\x81bjp\x04[\xed\xd7X\xffV_\x89\x19\n\xc4u\xe2\x11\x0c\xea\xcc\x01\x8e\xcc\xaf\xc7\xb05\xbc\xae\xf7\xb5\xb0\xf7%\xf9\x14u\xa1~a\xcb\xf2W\xbd\xc1\x8d\xb5A\x11\x18\xea\xa8\xf8s\xac\xa8X\xbd\x1d\xae\xa2\x1b\xb9N\xb1\xb1G\xda\xdfES\x86\x05]\xd9\xdb\xca(\xa5\xbc\xf8\x83N\x8b\xea\x0d\\\x15;K\xb0\x85\x9eU\xcf\x93\x1cy\x8e\xf6\xb3^u\xdd\xd0\xb7.n\xd0 Jop\xa5\xf57\xf5\xd6\x97-\xab]H<\xdaji/\x8be+^\xd6\x91\xad\x04\xd4$\xdc{\xea/4\xa2\x0bo\x93r\xd5\"\xf3U\xa7\xc8\x15\x89h0gi\xe6\x17\x1dY\xb0\xf3m\xfc>N\xaec\xa1k@\xb2A\xf1g\x93&W\xe1\x9c\xcd\x8d\xf8)\xc2\xb1\xe2\x80\x8b\xae\xa6\xb2\xa7\ni\xb7l\xda\"\x8c\x08\xa1\xd1\xa1\x95s\x12\xf9\xces1/\\\xfd\x06\xae*\x80\xba/&o\xd7\xab\xd5\x07z\xedc*\x82*oF!D\xc6\xc2)\xe8\x98\xee.:\xe1\xfd\x0bj]\xbd\xf8s\x8d\x9d\xa2\xff\xc2w\xb4h\xc2\xc0R~9\xe6\x8a?*&\xa8\xba\x07X@\xbc\xe1lF}\x1csE\x9f\xeb\x15\x8e^\xa7>\x9b\x1b\x98@8\xbd\xaeL\x06\x83\xc8\xb8U\x96\x1f{\x18\x0d\xeb\xce\x1d\xc9\xdc\xabw\x1c\x15\x0f?#\x1e~\x06O\xe0V\xe3\xe1g6\xe1\xf6\x18&p;=3\xf0\xefE\x89w\xc7\xd3c\xe2\xdd|\x07N$\xb7\xcd\\\xfe\x1e\xa3\xf8\xde(\x0e\nG0\x97$\x83C\xd6\xca\x87+\x9f\x0bV\x17>,\xab\x8c\xf5cm]\xdec\x07\xe8f\x16\x19\xcc\x9c\xcf\xd0P \x90.\x98\xcf\xff\x9f-Ko_\xa5l\x11\xde\xf0m8r\x0c1\x9e\xc4\xce\xbf/\xf2 \x0c\xe1\x08\x9eA\x0f\xdeW\"\xfc\xe0_\xbf\x8az\xdd\x82\xeb]\xf4nEN\xcd*\x12~Vn#\xb6B\x1c\xa4\x7f\xe0,v\x0c\x07\x06\xa5\x91\x1c(Qi\xa4?ME\x9au\xd29\xdb\xe4\xab1\xdc30\xc1 \x0d\xd6,g\xa9\x18\xc0\x88\x1d\x1a\nEA\x18\xd3j}1]0\xe8\x10L\x05\xda\xbce\xd5\x0ekl\xeeH\xcb\x92\xb1\xffn\xe0N\x7f\x1aL\xcf{\x1e:\xb2N\xffmt\x8e\xf7\xfa,\xbeW 6z\xdf}7\x9d\xfe4}w~\xfe\xcd\xb9gK\\\x03b\x16\xe5\xc2\x94h*m:\x86\xe3\xd4\x0d\xc5Gq\xa5\xda'\xb2\xc5n0!\x85\xbdb\xd6p\x8e\xcd\x97\xa9\x16\xcd\xacZ`/\x1e\xe8[ \x98/\x0c9Z\x15\x1504\x1a\xa5\xab\xae\xc0\xb0$\xdav\x83vF\xa7\xe2\x86;[`=\xfdQ\xc4R\xe4\xf6VB\xb3\x1b`\x08G\xb1\xa88\xa6\x08\x9e@<@\x90n\x0c\xf3\xcdg\x1cA\x0fC\xe7\xef2\xf3`::\x17[3\xf2\xa1/\x02v\x7f\xc6J\x04\xc6\xa0\x14`]\x0ci\xab\xe1\xdd\x8a&HQ\x92\x10\xa3\xc0E\xe8M\xd6\x01tA\xb0Ry\xb9\x0d\x1c\xa9r\xca\xf2\xa2%7\x1b\x89\xe4\x03\xc3\xc7\xd0\xef'm\x8d\x81@\xd0\x90\xa2\x98\xb3i\xd2\x90\xda[>(9LE\x0c\xb6\xc0Cl\xc44\x08\xd3sO\xb28\x9b{\x99\xfet\xb8M-\x1f\xb4\x18\x97\xc1\xe3H\xf2\x86Y\xca\x82\x9c\xa1\x0eg\xd2\xefl\xcf\x95\x08\xe5\xc7\xb7\x8d\xd8b\x91\x9f\x91+y\xe7\x95\xd7\x81\xb6\xc6\x1e\xc9\xd7\x1a\xfcq-\xcc\xbe\xc7\xd5\x87S 4_\x9f\xc6\xb9\xbb\xf5ad\n\xd9`z\xf6\xc2\xecE\xf0\xc2\xcdp\x88\x01b\x1f\x06\xbd\x17\x06\x9a\xcc\xc31\xe3\xab\x8c\xc2\x8c\x8a\x1c\xc8i\xc6P|\xcc\xe8\xd3\x13\xa4\xc7\x8a\xa9\xc1\x91\xda\xc0iv\x8eQ\xf0\xc7\x10N\xb7\xf8g\xeb\xc0\xcc\x18\xa2?\x1cT\xc3\xc6R\xcdm\x08l\xb3\x0f\xe5\xa3\x9b \xec\xa9\x15\xa9\x98\x9a?\xc3\xcc\xf0 \xf6\x84X\x88\x03U{B\xe9\xbd\xd1\x9e\xa0JX4\x96\xe7l\x07{\x02\x8ei\x10.\xe3$e\xba\xe4\xa7dB\xc3G\x1f\x87 \x8d\x0c\x13S\xacl\xbd\x80\xb0D\xbef\xcb\x93\x9b\x8d\xab}\xf10I\xa5n\xae\x085s\x85\xe4\x12\xbc\x83\xba\xe5S~\xc3?eI\x8c\x83=\x11\x9eZ\xc1\xa0\xf8\xe9#f\xb1\xcd\xb1\xf0B\x0e\x06\x17\xea'f\xa5\xc8f\xc1\x86\xbd\n\xf2\x95\xba0\x8b\xa5\x0c\xefy\xf1ml\xab`\xfcR\x1e\xfe\xd6\x90\xd7\xaf\xd5\xad^\xc0c\xbb\xcf\x01]\xd0\xbc\xccXzE\x1e\x9c\xd3syk\xf3\xf2g\xa8f\xfc\x80\xba<]\xbdQ\x17\xed<\xb4\xb6@\x95\x9cv]\x06\xb3\xf7\x14\xc8\xad4`\x98\x98\xa2mV\x07h\x8a\xfd=\xab/I)\x8b*\xe5\x9cJ1-\xb9\xa471<\x81\xf41\xc4\xbd^]\xcb@\xdb\xce4>\xa7e\xc3H\x0bd[\xb7N\x0d\x19VlQ\xb7/S\x16\xbco\x99\xd9\xc2\xcd\xe9\xbe\x88\xaf:\xe3\x7fm8\x14s\x11\x0b\xd3D\xa8\xdfR{E\xabJ\x81\xaaz\x1b\xa2\xa4\xe1\x08\x81R\xc8\x8a\xefF#q\xa8\x1b\x891\x94\xad,.`\x8a\x15\xfb\xa8n\xfc\xf0_n\x88\x89\xbf4jY\xdf\xac\x85\xab\xb2\x01\xd4,\x1a\x18b\x82\x92\xe9\x98\x96\xda(\xa4\xe7\x83<\xf9\xd3\xd9\xcb\x17@9X'\xea\x85k\n\x14\xa3\xe0\"D\x9epAK\xfdg\xce\x9ar\x8f\x84\xa1\xf2[\xe6\x91\x98\xb37\"\xde\x17\x94\xac3\x99\xb0\xced\xfd~\xa3X\x83\xe6\x18\xe4T\xd3\xec\xbc\xc1\xa2\xb8\x97\xd6.\x8e\xf9\xb0\xf1*\xd2g>\xdd\x9cWt\xd0\x08Mf$\xc0\x94\x8f\x98rO\xc5\xac\xb7\x9bg\x92\x0d\x1e\xd9\xac\x93+\xd6\x90o{\x13\xe4\xab1\xdd\x0c\xdc'\xf3\x98\x81\xe0\xb9\x1b\xfb\xc5\x1c\\HK\xae\xd7\x16\x03\xd2\x95\xc8\xf9\xc2\xe7n7\xaf\x18\xf2ADP$i\xa2\x1f\x86B3\xbd\xd0\x8c\x0b\x89.\x89\xa2\x1cJ[\xe7\xcb\x85\x1d2\x11`;\xee\xde\xd0o_r(\x96\x1d\x05\xf3\x86u\x87\x1d\xd6\xbe\xb9\x15\x11}9\xd5X\xa0;kr\x81\xedjF5\xfbEm9\xe0*j\xb2W`\x8f\xb9YDNMm\x08\x15\xb5\xcez\xbd&\xeb'\x07\x8e\x0d\x9e%f\x0d\xc0Q\xc3-f\xc3-\xae\xfau\xde\xbf`>\xff\x87\xed\x1d\x1fm\xd3\xf6u\xd8=\xcd\xc5X\xfd\xc5\xa5\x1c\xc1\x96\xdb\xeciZQ=+\x02\x97\x94:\xb6\x80\n,\x99\xbe\x9bE\x9cR\x08\xb3!\xf1\xf5\x82\xa1\xe7\x94`871tPL=\xd7\x98\xba\xd2\xe1\xf9\xeb\xf2\x9a\xd4\x02 \xf1\xda\x898\xdao\x95vJz\xb9\x90?\xb9bq\xfeC\x98\xe5,F\xfb\xa3\xed\x93\xeb\xac\x93m\xc6\xb6\x1b\x87\xac.\xd6b\xef\xd9m{!lk\x9e\\\xc7m\x05\xdf\xb3\xdb.\xc5f\xab ^2,\x85\x807Of\xdb5\x8b\xf3\x81\xfc\xe3$b\xf8;\xc8\xf3`\xb6\xc2\xda\xae\x93\xc4\xe59u\xad\xa5O\xb1k\x9d\xea\x8c\xbb\xd6+/@\xd7Z\xfazt0A\xc4\x15\xb9;\x16\xaa\x01iO\xb1\x99J\x9b\x80z\x86y[\x8c m\x84\xddV\x12\xa7\n~!R'\x1f\x03\xc9+\xf4\xc3\x12\xc9C\x9e\xadw%r\x80\xc7>\x8c,\x08\xc9 _\x87\xaehH\x02\xb1\x0d\x13\x0d_-\xc8h,i\xc0G{\x8bu\\\xb3\xb5\xa9J6\xe3\xdb\x9c}\n\xbeUju\xc27SO]0\xa7\xdeW1\xb5\n\xeap\x8eT\xc0\x01\x85n`\xd7@I\x99\xbcRD\xd6\x8fd\xad\x8aYJ&\xa8\x19\xff\x8dv\xbe\xb4\x9b\xa0bp \x91F\x90B\xb1Em\xbd\x9a\x01\xac\xc9h\xa8\xb4\xe3\xcfI\x02\xd69\xadW)\xe1\xafQ\xa9\xd63\x94\x1d\x95~\x8d!\xf6\x06\xd9*\\s\xf6\xdd:/\xb9dZ\xc6\xb7%\xeer\x86'\xf2v\xa2%\x06\xdd\x12q'\x90\xadi\x92\xa7\xd9DdH\xab#}!-Ck\x0d\xf6\xa3mo\xbd?C\xee\x17uK\xcb\xac\x82\xd2\xfb\xfa\xb1\x19\xd3\x8c=\x9d\x9ce\x99\x0f\x0e\xff\x831\x87\x1cij\xb56\xa2\xfciv\x12o\xd7\x14\x11\xc3P\xf7\xc3\x07\xdd\xa5\xec\xa3Kq4\x0b\xc8\x89\xe1\x08}\x0b\x12oPD\xb3\x9f@JVR\xfdUb\x04\x94\x9d|\n\x8d`JQ;p\xe12\x11F\xad\xfaQ\x85\xf4(\x1d\xa8Y\xf6F.y1ih\xba\xebU\xda\xd1\xe6\xf1\xb1\xc1,\x89\xb3<\xdd\xce\xd0\xc0=\x99\xe8\xdf\xd0t \x86\xabv \x8e\x8aI\x8d\x0d#3A\xb9\x1d\xea\xb4\x93\xcc#\x0ee\x11\xb6\xaa\x9fh\xf2\xf7\x1a_\x1c\xeb0:)9z\xd7\x8bR\xa2\xc8#Sz!\x07\xcf\xe5K\xed\xb5\xf4\x9b\xb6\xe1\x96!g\x8f\xc4e}\xc8 \x0d\x00\xb3\xc2\x8c\xd58\xb4/\x81[\xc9Bo\xea\xcc\x90\x7fG\xe9\\\xeb`\xe3\x86\xcdc5\xe4\xa4\x91\xf4\xdcz$,\xe9y\x15\xbdE\x80%7\x9f\xc6\xe7\x18W\x9dM\xe3Z\x10\xfc:\xb57\x8c\xca\x90\x87\xa6\xa4\\+\xbaZ\x18\x82G\x15\x83\xa3*2\x1d\x9d\xf3\xb5\xd4\x7f\x8eIX5;\xf0bT6\xb6\n\xae\xc2d\x9b\x8e\xc15\xf4u`\xed\xeb\xa0\xdc\xd7\xc19\x1e3z\x83r\xabx\xc5N\x9a\xd5J#Pg\xe4|\xeb\x9a\xad\x0d\n\xb91&u\xb9\x15\xcf'+:}\xf3\xa5\x13e\xc4\x85\\%\xf2F&Y\xb7\x94\xbf:\x9dF\xe7t\xda\xad\x1f\x91\xceD\xe2\xe8\xe1c\xd8\xc0\x13X\xa8\x067v#\x18o\x11#WL7\x0d\xa7\xe6+.\xf0L\xe7\x0d%\xae0\x97\xe3\xaa\xc1\x12\xb5\xc6\x12\xe1tn\x8b\xef^\xba\x8a\x80W\xde\xec\x12?\x96- \xe3\x13X7\xa9\x1b \xe6\x8a\x0e z'k8\x02>\xa8\x0e>\x83!%\xc0\xce\xd0\xebk\xba\xf4a\xeb\xae\xbcs\xa3\xbb\x99|D\x9clQs[\xbbz \x1fu\xadE\xa76m\xf3\xd7\x8av\x9a\xfb-\x1ex\xdb\x86 \x1f1V\x07O\xbd\x1d\xe1\x17VA\x13Z2\xe9+pk\xbe,)\x9f\xf2\x1a\xd8\x07\xa0\x97Z\xd5J\x18\xd5\\\xfd\xc0H5\xd3)\x17f#\xd5\"\x12$NA\x90\x84\x1dA\x8en\x1ecL\x1e\xcd)\xc1Hd6(R\x1a\xf0\x02\xe7zk\xd3\xd4,\xefg\xe4\x16Q\x8c\xdd/\x06=\x88\x93\x1f\xb7y\x907*\xe6j\xf0\xcc8\xf8\\\x0d^\xe6g\x18\x92\x1e\xcdH\x8f\x06\xc1\x07\x8a\x81V\x0f \xd5@\xc9\xbf\xd1<\xd2\xeb0_\xbd\xc4+R5\xdfI{\xba\xd5L}\xafl]\x8b\x8cg\x0f\x0c!\xf3\x8fC\xec>\x1a\xdd\xab\x10\xa0\x8b\x0b\x96\xfd\x98\xcc\xb7\x11^\xf3\xdf\xad\xcb\xd8\x1d=x\xc0\x17\xd0}t@\xff\x8d\xee\x8b\x9f#\xf1\xff\xa1\xe7\x97\x05[wt\xcf\x1b\xfc\x95\x05\xef\x7f\x0c6]\xfah\x10]}\x99\xc9\xf7p\xe4\xb9U?\x8ePtV\xbd,C^\x0e\xa3\x83\xbb\x95\xf7[j\xea~5Y0\x0d\xfa\xd1\xa8\x1a\xbb\"\xa2\xf2\xd5\xe6g\xf8\xfa^\xd5{d!\xbcG\x0e*\xef\xf1\xdcr\xb0d9_\x91\xf2\xa7y\xc1\xbb\xc2\xec\xe4&gq\x16^F\x95\xcb\x1e\x9c\xedd\x83\xed\"\xcb\x93\xb4\xf2\xe9\x8a,\xca\xa5w\xed\x01d\xab^\x076\xaa)Y\xb8\x88\x8ag\x904\x86%qbx\xaed\xd3V\xd7\xe3\xf2\x98\x97FYg\xc9:\x05\xd6\xc0{\x13(A\xdb\x89\xbf\xa4q\x1bcj\x06\xf9\x88 \x0b?\xe0\x1c\x8e`\xe5.\xc4\xec\x1d\x01\xcf\x8e\xe7a\x0c&\x94}1\xfa\xb6HU\x14\x16\xb37v`8\xf4\xab\x8b Yy\xca\xedAK\xb2\xc1\x9c-\x0c\x83\xf4\xd1?d\xc7m\xb8\xadj\xa8\xee\xa3\x83\xa1\xe7\xaaV\xf1\n\xde\x12o\xbb\xef\x0d1\x96Q\xb1\x963\xb7\xcd\x18\xf1\x00\xf6&\x80\x96\xa5[\x0fs\x7f\xc9\xbb,\x8b\x94\xb1_P\x18\xa4\x17\x9e{\xe5\xf9\xf0\x80\xd6Yc\xff\x1fI~\xdf\xba.\xa6l\xe3\x9f\x8f\x0b\xad\xd0]\x977I\xbb!\xb3\xf4|\x08\x06/NN\x9e\xe3\x01\xba\x0f\x89;u(\x8e\xae\xe3\x83\xb3\n2\xfe\xdf\x92\xe5\xfc\xbf\x8c\xe5\xce\xb9\xdf\x00w\x12\x96n\xb5.j\xeb\x8c>\xf2\xb5x\xc1!\xc6L\xd2\x1a\xcf\x0d^\x1c\xa0`:'\x03\xc4\x1c\x9d\x10\xcc`@\xb0\xb7(\xd2\x7f\\,\xc4\xe1TSP\xe3P\x065\xbeXL\xd99\x8d\xc2\\Zj\x86|U@\xe8\x9b\xbc&\x8c\x0d\x97\x18\xec\x0e\x91\"\xa8-\x02i^\x8b\xe5\xffQ\xdfc\xfa\xbbs\xa2\xf0G\xa3\x87\x96\xc8I\x8dh$\x07\xc6\xae]\xd4\xbe\xf5\x10\xaf\x9d\xf8b1\x82\x1a\x7f\x10\x1c\xab\xc6\x96\x04\xbbz\xe4\xb9N\xb6a\xb3\x90\x95\xd2\x84t\x93\xd8\x10\xf8\x8cb\nj\xe5\x1c?LW(\x84\xf1I3\xa2\xa0}\x8a\x9c\x85PJBHK\\\xcd\xce\xe5\xa9\x1c\x08\x82\xa6\xfb\x90\n\x90T\xe6\x10\xf2\x18\x9a\x86\xe7\x9e\xf2\x1f\x12\x85\x8b\x1c\xf1\x92\x96R7\xe3\xd6T\xf6\xdd\x85\x03Z\xe7\xe1}\xe3\xfas\xf6o\xe6\xba\xc2\xcd\xb3Z-0\xef\xa6\x10\x1a\x86UaBH:w\xab\xef#%\xaf\x18\xa5\x86\xaat\xd0$5DnU\x92\x9b\xe3\xdb\xea\xc8WxxT\x86\x93\xaeR\x00\x1b\\`\xea\x07\x17\xff \xd2\xb1\xae\x1e\x10\x94~\xae\xdbN\xcb\x90\xb2\x04hrojg\xd9\x86\xa3P\x8cr\xe3\xb2A\xd0D\x94+\xe5\x19\x17F\x10\xf0j\xa5\xaa\xd9\x90\x0b\x98Zk\xd6\xc3\xaa<\xd2A\x16\x91|a)\xe8\x9c5 \x94:\x83\xcb\xa7\xa3\xc6\x15Z\x05\xad\x01\xd2\xa4\xc8\xb2W\xf4\xda\xd4b7\xf9B\x1e;4\xcd$F\xe7yT\xf5r\x99\x021\x10\xf1\xa5Y=\xbete\x1c\xc4|\xdb&'WT\x043\xd6\x01\xa0M.\xca%\x00\x18\x9cv\x0d\xb3\x11\xb5\xfe;\x07\x99\x88%\x90\x07\xa2\xb9\x8f\x97\x08\xf6\xf6\xfe\xbb\x9aTF\xfd\xe57(fe!e\\#u>\x84\xb6\xa9\xa3\xdbc)J\xa35\xc4\xeb\x96\x7f\x8d\xb0E\xe7\"$g\xd7\x8b\x9c\xdcE\xd8\xe0\x82S\xbcU\xaf\xe7\x83@r\xa2\xcc~a$\x04\xbc|\x97\xb9)\x8e\x88M\xc3ss*|\xfb\xd2\xa5n\xa4\x8b\\\xe6av\xdbv\xf9\xa0Gg\x80\x92\xbd\x04\xf3\x91]x\x97@\x9b\xec \xe2s \xbeR\xd2s\xeey\"\x11\x03I\xf71_\x93\x99\x1b\xab\x9c8\xc8\xe4D\xfe\x85X\x89\xfd\xc6\xbe,\xee3\x1d0Z>\xff\x88\xd9\x8bD\x0f\xa6\xa9\x9bgi\x80\x10\x1f\xa2f\xcc_\xd4\x91\xc0\x86\x01)YK\xd1\xb7x\xcft/\xb8<\xa1\x14'\xc4H\xbb\xc8\xc5\xa5\x9bt\xcaP9\x9b d7\x0dM\xa8\xd8c\xb8*P\xfb\x0f\xf0\x05$\x94\xaa( \x04D\x8b9\xa3f\xb6\x08\xcc\xf6\x06\x12L\xeeU[\xc9,RQd\x91Wf\x16\xf9fa\x16\x876$uW\xc3\x9b\xce\xf1\xf5\xdd\xa17X\xd4e\x13\x8b\xf9\xe6\x8a\xea\xdcm\x15\x82%\xa5$\xed\xf3\xd6$\x13_\xe2y\x003\xd8\xe6/`\x02\x97\xf5\xd7\xd7\x9c\xbf\xe1!!\xa30;f?\xd4\x13\x98\xc0\x05G\x86\x8b&m\xef\xc6p\x1e%@\xf3\xcaz\xba\x89\xcd\xba\x18\xad\xe7D\xe5\x16\xe1Rx`W\xa5\xf9\x83*\xf4\x85'\x93*\xb8\x1ez\"\xb9U\x95\xca\x83#p/0\x91\x8b\xaen\x1aqm\xc6\xbf\\\xa0j\xea\\\xcc0\xeb\xe2\xe0b&\xa4\xc1K\x9dO a\xc0\xebsK\x1f\xf2\xe9\xf5y\xcd\xca\xc0)\xc0\xca\xe5\xcb\xe9\xa3\xc3\x94O\x04\xd3\x173\xf4\x97,\xf7WA\xe6g,\xf7\xdf\xb3\xdb\xcc\xa7<\x1f\xbe\x98\x8eO\xb7\x0f\x1c\x99\x9e\xce\xe7\xa3\xe9&&\xe0\x16\x82\xbcnZ\xa8\xacu\xb2\xc1 \x8c\xe1\x84\x9c\xcdq\x03\x1c\x1c**L\xa4Em]}\xc3K:{S\xa8uN\xb4e\x16 \xbe\x9e\x9cn\xa1LA\xfa\xd5\xc2\x8d\x0br\x8e\x06\x07\x1a\xae:\xaf\xb3\xab\xec*\x0f\xd1\xc5\x8c\xab\xec\x05\x05\x1frr\xed[\xd5})\x0f\x15z{R+W\x15\x89=\x9f\x82H\xcd\xcb\x8b\xe0d\xe1/\xcc1\xf1\xf6\xb2t\xdc&\x9a\xd1,\x06\xbc\xb5\xfaPjP<&(^W\xcd=dIY\xfap\xed\xf9\x90\x95G\x1a\xe3\xadOe\xf0\xf1|\xd8\xb8b;n(G\xd3\x85\x0f\x89\x9b\x0c\xfe\x03z\x90\x0c\xfe\x8a\xff~\xe7\xc3\x8d\x9c\xf9\x9a\xb3\x90\xb3\xc9J\x98\xa4\xcd\xb0\x16\xa1\x1eTy\xaf\xec#\xe72=O\xb5\xe7\xc3\xfe\xf4\xa7\xa0\xff\xcb\xb0\xff\xe8]\xff\xab\x7f\xfb\xe3\x9d\xaf\xbf\xe9\x0d\xde\xfdt\xf1\x7f>\xfc\xf7\xf9~8\xc8Y\x86\xb9\xd7\xcc\x81Wd\x82\x97\xd9*H\x83Y\xceR\xceW)\xcd\x00,B\x16\xcd!\x0e\xd6\xc6\x9c/\xca\xfa\x94'?$\xd72\xaftyq-sn\xb6\x84t\x9e6\xeb\xd4\x99\xc1\xf1\x11t'$#p\xc5\x98u\xa4\x95\xac\x82\xd6\x10\x93Iv[\x957{[\xfc\x99'1+9\x88\xb5$<\x11\xb7\xa2\xccI\xac\xc0\xa8\xe2\x99\xdf\x1a\xbcF\xc4\x80+i\xc3rS\xb2\xb0\xd6\xb5\x92\xb2C\xbd\xdf\xce\xd9~\x0d\xde}\xa0\xa5\x02\x14\x97sJ\x19\xf2\x13\x0c\xfd\xb1S\xbe\x0c2\x1eQ\xd6bs\x82\x0c\x91\xf9\xbf\x1e\xcd\x14\xbd\xeaL\xddu\xe9\x8bM\x87\xe7>0c\xe86\xadG\xdc\x03q\xee\xb6d\xb9\xe6\x1e\xf7\"X3\xae\xfd\xef\x90!\xaf:\xd7\xa9)\xab\xdcGS\xe6B\xdb\x1e\x19|\x13A]k\x90\xd9\xf8\x95\x04-\xb2 \x0dR\xc6\xe7S\xcd\xdb\xf2,JY0\xbf\x05\xfe\xafc\xba\xcc\\\xc9\xef\xdfi\x80\x06\x7fF(K0\xb5\xd4LM\x81\xec\xd8\x8eY\x93r\x97\xcf6\xdbF\xb6D)x\xff}\xb7\x8c;\xb1\xcb(aZw\x1bO\xa7\xa52\xf8n\x82F\xf1\xf8Z\x15\xb9\x97\xcdT*FW\xa9\xdc\xce?\xf2\x01\xdf\xddg\x99\x96\xac\x96\xdc}:\x8d\xd0\xe0\xc7 \n\xda0\x86\x8cvCP\x04\x9f1\x8cE\x9fQ\x91\x8f\x98\x03\xecm\xce~\xa0\x0b\xbb\x0d3\xc8\x18\x81\xae^\xd5C\x15\xfc\x12'\xd4i*QS| \xc4S\x1d\xd6G\xd54\xdf\xad\xa7E \x0f/JY\x05\xe9\"UC\x12\xa0\xd0\x9c\xdd\x81yZ\x0eE\x91\xd9\xdc\xa0\xa6\xcbG\xf9\x05\x16\x89\x8e\xbe\x8d\x92K\xcd%\xbf\x9a\xecXo\x9f\x17\xed\xdc\xbeL~\xcd\xfb\x90\xe1g:\xf6#\x8bw\xeeK\xcf\x7f\xce\xfb\xab$@\xef\xd8\xad\\>u\xc1\xa2I\x86\xd0z\xd7\xd2mC)\x87\xd4\xba\xd2\x81\x86[\xe8\xf7\xc9\x04\\\xca\xec\xc0:4\xc4\"\xb7\xb9;5\xd6\xb79\xbdB{\x00\x03\x90&\xf1\xf2\xc8?|\x80==S\xb5}\xcd\xd0\x00\xb3\xac\xc8\xb2\x82U\xe8\xd7-\xbe\x95\xb3\xe15\xdbr\xab5\xac\x92\x1d)\x84+hm\x0b\xab1\xa7\xe5\x83\x05K\xf9\xdffI\x9c\xb38\xef\xd3\x10\xf1\xf8\xd6\x12\x04\xadT7\xab\xd5\xf5\xc1\xc9\xd9M\xbe\x8f\x01\xa9\x1es1>c\xf9\xe4\xed\x9b\xef\xfa\x0f1\x04W\x05\x8b\xe4\xe1\x98z3\x10W-Z\xbb1T\xe3\xed\x7f\x0e\x12\xa8\xd14N/\xd8l\xa2\x90\x92<\xee\xdf\xf4\xaf\xaf\xaf\xfb\x1c\xc5\xfb\xdb4\xa2\xe8\xfc\xf3\xea\xac\x8d\x12\x8c\x96a\x8d\x88)\xd1\x94V\xfe*\x8d&!i\xcc\xe6\xfd\x0d)d\xb4\xe44\xf6B\xe5E4\x88AY\x12]\xb1j\xb1.\xedi\xd0km\xb6\x15\xb7;\xf5$\xa9\xa4\x01\x0bg\xc9\x96k\x8cI\x8e\"\x9b\"\xbf\x98t\x17\x82\x0c(\x93]\xa3e\xa2\xcb\x989\xb6\x9d\x9b\xb7\x99\x04\xda\x12&\xb7nq\xc9\xaaY\xa5\x04Gr\xe79\x8e\xda\xf7\xa9\xb4\xfc\x02\xeb\xf8l]o\x90\xafXl\x8aM\xfdQ\x92\xdf\x9c\x88G\xeb8\x7f\x13Pl\x17\"`G\x11P>vQP>\x15\x91\x90o\xb3A\x16\x94\xcf\xc7_\x0bM\xba-A\xc9\xf3\xbe&\xfd\x91\xbfzaS\xcde\xdc\x17\xf2\xba\x1f\n\xaf{u\xb5E:\xdf\x9f+\x1b\xc7`\x91&\xeb\xe3U\x90\x1e's\xe6\xe6\xd3F\xd6+\xb5\x17J\x99`\xcbk\xfa\xd1\xb2\x10\x9dV\xee3\xd0\x9e\x03\xf8\x8eh_Fv\x0bE\xd7E=\xaa\xb1($\xb8Vt\xd2\xd1>\xc7\xf37B\xd5E\x03\xaa\xfe\x9c%\xf1\xe7\xb4\xfd\xa7\xb3\x97/(\x06\xaf\x95z\x95\xde\xdb\x94\x85Y\xab\xe7\x0f\xf9\xf5\xd1\xfd,\x0fU\x87\xfa\xfa#\xad\xd0\xad%\xc6\x08\x94`P\xdf\x8d\xb6\xc4\xb2\xba\xde Q\xda\\F\xf9T\xf1\xcd\xac\x94)\x95\xe9\xbf\xb9\x1a%\xe4\x83\xc2Gv\xa5r4\xc7\x98\x8f\\e\xd7\xf5\xe4NQ\xd6VlL&p\xa5\xf7\xc9\x9c\xd1\xdbd\xce\xfcR\x82\x18`\x9a$\xcc\xbb\xc2l\\z\x06\xf6\x8a\xbd\xc1\xb0\x87\x9a`H\xb3T\x06K\xf3\xf2\x1bf\x9f\x97~\x7f\xf8P_\xa1\x0f\x1f\xc0I\xd6a\xee\xf8\xb0W,NE\x98\xb2/Vn_\xacv\xd2W\x98;\xf3\xe4\xedf#\xed\xbe\x8d\xc8}\xabe\x1a\x87\xa7\xd0\xa7{H\xa6\x8c\xdd\x1f\xdd\\\x0eFN\xbc\xf8\xe9\xfc\xc7\xc9\x1b\xc7+\xefcN\x7f\xa8\xc2\xe2\x07\xe5\x9d\xc1W)[\xb04EI\x80\xde\xba\xd8\x0e\x99V+\x1d|\x7f\xf2\xecy\xed\x0b\xf9\xcbZ`\x1eUoN\xf90&4\x9b#[\xf8\x8f\x937\x90\xa4\xc0[\x939\x873\x13B\x10\x91\x93\x1a|5\x8e\x8f\x0d\xf7\x17\x1d\xac2\x82\x0c6Y\xed\xd3p\xedz\xf2\x8c\xfe\x8ec\xb0\x1a6\x9a\x11Z\xc5\x03B\x1e\xd1~cxb\xfe\xe0\xf6H\x0b\xba\x96M\xa5\x87YT\xa0\xad:\x1e\xdc \xe67q\x8c\x0d\xd8\x99g.-\xa0\x14d\xf8\xed\xeb\xd3\"&\x19\xd7\x91\x0d\xaf\x93\xeeq\xe1:[\xb77\xed\xfb\x9a4l(\xad\xf4\xfe\xbb\xf4\xe8]\xbc\xbf\xcbn\xd66k\xdc\xb4\xda\xe5\x8d\"(\xb2\x8b\x0f\xdd2\xda\x8b\x8d\x1b;\xcd\x0d\x82\xbeWi\xed\x0e\x82|>g\x0f\xe6V\xbe\x9a+_\xfa\xbf\x17\x82\xbbH\xd0-\xae\xeeI%\x99R\xd5SXs\xfe\x17\xe6\nC\xf7\x0d\xf9i\x0c\x07\xc3\xa1\x8c\xfe\xfa^\xfa\x85\x88\x8fO'\xfc\xab\"\xe7\xe2\xed\x138TU\x8a\\\xf8E'\xfcW\xad#,2\x06\xe7\xe5\x9f\xe5\xd8\xec\xbc\xc0\xd7\xb9V\x8e\xffc\x8a\xfc\xaa\xa1\xb1j\x17)/7\x1axDZo\x1b4\xaf\xac\xc7n\xba)a\x0cN\xc5\x92\x80\xd3\xb3\xe4Q\x92\x07Tcp\xceD\xcc\x88P\x06\xa6\x90\xc7T\xf8\x8a\xbe\x9a\x1b\xe1\n\xdb\x18\x9cB\xa1\xd1\x1a\xe1\x1aF\xf1\xb3U\x00\xe4O\x9e\xde\xb6\x98\xc3\xb4C\x07\xde\xbe_=\xc3\xd0\x9f\x8f0\xc3\xe0\xd4\xcd\x94\x174\x97\xca\x91\xbd-3\xe2T\xa3\x1f\xcbGJ\xd5|m\xc4\x9fM{\xa1\xa9\xdfcp4E\x83*\xd5\xd1\xd3,\x1a\x95\xcc\x84\x1eB\xce\x15L`\xaa\xe2\xd5\x9cJ}\xeb\xdc\xf1\x8b(6\x85\x1aV\x7f}\x1c\x05\xeb\x0d\x9b\xd7\xbf\x9e\xc6\xf9\xe8\xbe\xb9\x92\xe9\xfdi\x9c\x1f\x1e\x98\x8b\x9b\xde\x7f\x17%\x81\xfd\xc3\xfd\xbb\xe2\x83%,A\xfbuP\xf9H^\xc0!\x94o\xd2_Bv\xdd`~3\x03\x81y\x10*[\xaf\xb0\xd2\x86\x19o\x9cS\x88\xdd\x87v\xa5\xc4\xc1\xd6\x10C$.\x9a\x07Z\x87\x9aDk\x89\xd8D\xc5 \xd5\xca\x8eP\x94D\xb5\x9d<\x83\x9a\xae\xde)?\xbeu\xb0\xb1:Di\x05`\x82\xa7\xd0\x18\xfd\xd4\xc7\xe8\xa706$\xff\xc1 ^\xc5\xf8\x85\x93z\x97\xad\x17EU\x97|\"u\x9f\xf6J\xfbK\x96wj\\m\x9c\\ b#\xe4f~T\x9a'\xa5{l\xebx\x154\xfbFU:\x96\x1d\xd4\xc2Bs\xe8h\xeb+\xabL\xb2\x01\x02\xca\xab'\x80\xa0\xad}\xe9\xf3\xdb\xe1\x1a\x14\xd4\x02\xdc\xc8\x1e=\xeb\x1c)\xdc\x8d\x88L\x95\xfb\xc5\x18\xe3st\xfc\xcak\xa7\xf2\x861b\xd0\xb2\x0e&\x0bi]\xb4\xe5\xfb\xd3\xf7\xa3\xee`\xd0\x92\xea\x8d\xc9\xc8lfT\xc6\x8b\x89f\x93\x88>\x15\xf23\xfe\xf5'\xd3a&\xb6\xd3\xfb\x8e3\x11\xae\xd2\xbf\xfeT\xba\xed\xcb4\xae\xdf\xf7\x92O\xd3\x94*\x8eA\xda\x0cM.B\x86\x05\xb0\x9c\xc5\xdf\"\x9f\x7f~\xf2\xc3\xc9\x9b\x13\xce/\xb9\xc2\xee\x0b\xf5\xdc\x07\xe7\xe5\xab7\xa7/_\x9c\xf1?_\xbd<\xc3O\xaf\xde\xbeq\x0c\x0b4\xd3\xba\x9c\x89\xf4\x17\xad+\xaeIe\xd2\x13\xdc\xbe\x82\x97\xc9\xfcV?e;\x8dC\xb3+\x96!\x16\xf5G\x1f\"Bnm\x9c\x9ez9/\xbd\x9c\x7f\xe6T\xe6\x95\x93\xff\xa6I\x91\xf60\xd6\xb5\x0d\xbbFX\xa8\x1a\xe3\xaazb\xaf$\xb4\x8e\xb1TC4\xdd\xa4A\xf9\xdc\xa6\xd1X\xa9);\xac\xf2|\xd0\xd9\x9fF\xa2\x1b-\x19Y\x8c\xda\x17\xca\x90D\xb7\\\x84\x96\xc7q,\x83nDm\xa6\x14M\x9c\x85S\xf5|\x04\xb34$/\xd5L\x0f\x87#\x1f\x0e\x87\x07\xfc\x9fC\xfe\xcf\x03\xfe\xcfC\x03\xba\xcc\x07)\x9b\x87)\x05\xd8\xed\xc4\xd2\xb8\xa0.RK]jV>\xddZ\xf6:\x88\x97UwS\xa1\xd4\xce\x92\xb9\xf5\x80\xbe\x04\xba]\xf7\xa1\x0b\xc45+OQBG\xcd&\xeb\xa4|,\xea\x93\x11\xf4\xd8\xe0{\xa5r'\xfc\xe7k2\x08\x02\x86^\xe5?\xb3M\x12g|{\xe7\xfc7j\xce]W_[\xa3\x9a\xd3Z\xd3%\x17\xd0\xad/H\xe6\xb0\x97f\x1b[(\n\xff\xe7\x8f?|\x9f\xe7\x1b1\x0f\xbb\xa9&\xdc\xd13\x0e4\xeck.\x05\xda\x8e\x87\xad\xf4\xa9\\\x83\x101\xecD\xa4\xe4\xa3@g\xe3bN\xa7gQ$\xb7Ml\xae\xeb\x91\xb1\xc4\xee2\x02f$\xd5\x1f&\x8c/N*\x1a\x7f\xfb\xfa\x07G&\xa2\x0f\x07\xda[\x18\x03+\xfb\x93\xfcg_\xecG\x9fWj\xf1y\x91&E\xd5\x91\xa1\x17L\x0f(\x7f\xf0ejn2v\x05\x8f\xf1\xc1$\x97\xcb\xe7\xa3\x8f`\xd1\x99\x1a\xcb'\xad\xba\x86\xbe`\xf9u\x92\xbe\x97\xe6uX\x04a\xc4\xe6&\xdf\x0f\xf9\x88\xaes\x8a\xfe\xfd\x0f\xe9|\xc3b7Q\xc7Q \x9d\x7f\xe1\xe5&'\x8cg\xd1v.\xe2\xd4%\xa5\xd3\x1e.Y\x85\x18\xa5\xec\xb8tND\x15\xd5\x16\xddn\xe46\x96|\xc1\\m\x17\x05\x17!/\x0c>\x00 B;\xf9G\xcb'\xe4\xea\x95\x80:B\x03\x8b\xbb\xb4|0j\xe4 c\xf1\\\x0f\xa6\x9ah\x87n*}\xa0\xf6\xd2&\x95\x9a\x89-\x92\xcf\xc1&\x89n\x17a\x14\x99\xbc\x82\xd5_\xae\x9e\xc1\x163[\x90lQ\x8d\x85\xf6\x07\xd1xiqv\xbai\x94\x9bn\x19\xdd\xbb\xeb\x0d\xc8\x98b\nd\x1b\x1a\xb7\xc0lQ\x14\\\xc0pLQ5\xd5J\x13\xa2Q'\x10\xcd\xa4*\x8d\x9b\xf4\xc6\xe5\x03\xd1|\x13m\xeb\xa9\xfe\xaa\xb6\xd0\xc6\xcd\n\xb5\x18\xef2\x89\xec\xdd\xf2`W\xf9Ml\xe9\x9eQF\xffE*KN\x910\xdc\x9a&\xe7J\xc4\x1b\xcd\xe0I\x11N\xfa\x88k\xd6\xc2\xbf\xe2Y\xee\xa2s\xfd\x8b\xe0E\x9d\xcee\xd7!\xae\x9a5\xdb\xfd,\xc8\x18\x0c\xc7V\xc0\x97\x0dX\x8f\xd7\xe5\x83\x0d\x1d>\xb0\xb7$\x1f-\xd9\x80\xb8z\xd5\x10Y@>\x98\x86\xad\xb9\x18\x0e\xe0\xeea\xfb\x00\xf0J\xac\xcb\xd7\xf4\xf0\xa0\x85\xdb\xc8\xc0\x86\xadm\x06\xd3\xa8\xd73'\xea\x94\x8fY\xf2\x82\xe6\xc9\xe1\xa4F\xf6\xfe\xb9\x0c\x1b\x92<6\x83\xa7\x13\xb8\xfb\x90On\xc6!\xeb\xde\x03\x0f\xd7z\x06}\xb8\xfb\xd0>O\xe5\x95\x8b\x0d\xdc\xbf\xa7\x1ax0,\x1a\xb8\x7f\x0fz0\xb2\xdc\x10\x86\x1d\x1ch\xa9\x97G\x0fT/\xa3\xe1Ac\xf0<\xf9\xa8\x15>|\xe0k\xcb-p\xab#\x045\x96\xb2o\x10\x08\xb0\xe5+\xf1\xe8\x01\xae\xc4'l3\x1f\xe8\x81}\xa0mPp\xd0\x0c\x05\x82\xc4\x98\xa0 \xfd\\(H\x7f\xe7P\x10\xea\x10\xf1\xeb\x83B\xfa\xd9\xa0\xa0F;\xba\x0f\xdf@\x0c=\x93Q\xfd\x0f\xf6_\x82\xdf\x05ER\xe2\x08\xfaz\xea\x94\x8f\xbe\xc6\xca\xf8\n\x15\xab\xa2XVP\xf2\xf2;\xb8w_2\xaa\xc7\xb0\x85'pp\xef\xfec\xe8\xf5\xb6\x1e\x04\xd3-\x86#\xfe\xa3\x03=p]\xfeqt\x1f\x8e\xc0\x19:\"]r\x0f\xb6\x05\x97\x1d\xdd\xf7<\x9b\x87\x8d\xcc\x9e\xd6hFo\xb8E\xd9\x9b\xf0\xfe\xca[\\\xf2ft\x9cR\xceP\xe1\xac\xc8\xb4T\xc5F\xcdRj\x94%\xb6j:I!\xf0=<$\xf9\x8fkNw\xefi\x7f\xdf/\xfe~\xa4\xbd\x1f\x1dh\x1f\x12\x0e\xfb\x87\x8f\xf8\x8c\x12\x0e\xfbw\x0f\xd4[B\xdc\x84\x10W\xbd%l\xc4\xb7\x8f\x86\xea-a\x0f\xbe\x1d\x1d\x1cX\x04xtd\x80>\xc4*\x1dh\xce\xd7P^(BE\x9b\x8b\xd3|K\x0f\x1e\x12\xbdO9T\xfb\x80\x05\x83ib\xb1\xdd*\x82\xc1\xeb\x1e\x0c\xef\x1a+\x8f\x1e\x1d\x00\x0e\xf7)\xdc?\x87\x1e\x7fs\xf0\x10>\xc0\xfdC\xb8\x03\x9dZ\xbew\xef\xe0\xd1}5\xe7{\x0f\x0e\xef\xde5utppWv4:\xd0{\xa2\xbe\xe1\x0e\xdc?\xdcm\x00\xcd\xd6\x87\xb0\xc1v\x80\x10\xd2\xeb\xe9pW2*\xbd}}*\x94\xb1\xb7\xafOa\x1dD\x8b$]3\xab\xdb!\x08\xfb\xc5hx\xc0\x07]\x81P\xdf\xb4\x18w\x87\xf0\x81\x12\xc5\xdd\xbfw\xef\xf0>b\xad\xa8\x9ex\xf0\xe4 \x8cx\x81\xd0\xf3p\xbd\x1e\xd6\xd6ktP[\xb0\xe6u4\x0e\xbc\x03\x01+\x02\x890\x8c\xfbT\x12qs\xe8\x15\x80\xea\x95c7\x96\x15\x95\x96\x88\x05\xd4\x97\xe5\x8e\n\xef\xd8\x94\xb9\x85#K\x98}\x17\xc6!E\xe4:\x02\x87\x93?,~\x99$\x11\x0b\xe2zSG\xe0\xe4\xe9\x96!Y\\\x04QF\x7f9\xfa\xb8\x0b:,\xf5\xa5hw}\xc9\xae\x1e5\xc51,8\x02F\x1e\x18vQ\x87h\xd1\xc2\xc5-&\x0c\xa4[+U\xa5\xc8\x9c\x0fX9\xf1:w\x04MF\x87UgR\xb9ht\xa5\x12\xfa\xd2\xd8\xca_\x89\x0e\xd8\xa2\x18%bD\xba\xe6H\x96\x03<\xb3\xa9\x7f\xe4\xf8B\x99b'\xf6d>\xa6%,qM=\xe3\x83\xcc1\x1c\xa8\x88$\\\xbd\xdbrvL\xd9\xf29GZ\x10+Z\xc0\x13\xd8r\x1e\xb4h2\xe1S\xaa\xe1EC\xa6\x879\xa5$n\xc9\x16\x11\xba\x19\xe6\xb7\xedU\xd3A\xca\x87\xafm\xf9\x12\xf8\xbcQ\x08Skp\x05\x13\x98\xab\xf9\xaea\x02W4\xdf%\xcds O\xe0\x8a\xcfs\xe9\xc1\x8c\xd3\xa4\x15\xf4p8\xf3\xe9\xf2\x9c\xf3\x1b^`-\xd4\xb0\xde\x04\x9a.V`\x08+\xbep\x91^\xdeLp\x88r\x97{\xe4\xdd\xb5W\xaf\x8bj\x02gf\xedDL\xc7o.v\xa1\x8f<\x024\x995\xbe<\xba\x04\x86\x88_\xa1-\xea\xc6\x87\x0f2[\x8fdFJ|,\xb7`\xa8\x9d\x17\"CM\xec\xba\x12)\xf1c \x08\xb5%$\x8fp\xdbW\x8e\x1b#vXn\x94P\xbdN\x8e\x93\xc1:\xb8\xf93\xbb\xcd\x94\xee\xae\xde\x18\x86\xc5\xd1m\x04\xfbU\xb5p\xa6\x84 ^`f\xa8\xb8\xc1m\x93T\xd2443\x15\xaa\xdb\xaf\xb0\x9b\x0d\x8e\xb3\xfe\xd1&\xc0r\xbc\xde m\n}D\xe1\xe9\xb9\x8f\xc86$,\x1b\n\x0c\xf3\xf1\x94\x99\x13\x96K\xf1\xff\x05\x9d\xc1\\\xd3\x7f'T\xe8\x86\xb0\xf1\xa6\"\x00\xdf\xd8\x04\xe0\xb3\xaa\x00|c\x11\x80\xcfp\x8c\xb9^tm\xa5\x1c\xbc\x82\x18<:]\xb9\x87\x0f\x10\x1c\xcf\xe0\x08\x07:\x821\x9c\xa8\x9d9+\xc4\xe0\xb3B\x0c>+\xc4\xe03RJ\xd5[\x12\x83\xcf\xa4\x12 G\xc0es\xe8\xf5(\xc2\xda5Y\x9b\xb1\x8f \x86\x91\xe6\xb4\xc7j\x0e\x035CJ\xba\xa2\xcdp\xd9\xaa\xa0\xf2\x8a\xbd\xde\x12\xabn=\xb8\x82'\xe0\xbe\x87 \xdc@\x1f\x96\\B\xa38\xd5\xb7\xba\x04~\xe5\xc3{N\xa2\xc4\x96]a\xf1^\x9bIl\x96\xc4y\x18ow=\xe6\x03\xe1\x0d7\xe4\x00\xf3\x9bo\xc5Ee+\xcc4\xdc\xf8\xf6\xee\xa1\x18'o\x077\x10\x8e\xc0\xe5\xebz\xa5\x86[]\xd6\x1b\x0f\xe3\xa9q\xd2\xf5\xc7\x83\xa1\xc0\x11\xea\xbfR\xf3\xd2T\xf3R\xaby-\x8f,\xd4\xf6\x188H\xa1\xb7\xf4zk\x1cn\xd6\xc4\xe5\x8f}\x90\xb0\xb1\xb6o8oN\xce\x97\xc3\xd3{\x1b\x04\xc1X\xfb^\x9d\x10B\x98\x8c\xf88\x81\xc8\xbd\xf5a\xc3\xdf]\x8b\xe2\xfc\xdd\xa5x'\x8e\xc4W\xeaH\xfc\xd6\xf3 \x98\xde\x9ec(KXMW\x82\x96\xf0\x17\x86\x9bY 4(\xf7\x18\xe5\x98\xdbsO\xbf\xa6\x85r\x06\x1c\xc1\xf1\xf4Xk\xe6\x12\xc6\xb2\x8b\xe9\xb1\x0f\x97\x16\xc5\x8c\xaf\x06\x06\xf5\xea\xf7\x17^\x93\xc1\x8cou\x99\x16\xdeb/D,\xd5.\x12UE\x8c\xa8\xef\xe7\x1f\xec\xbf\x16\nt\xaet\x95\xe5\xc3\x07X\xf2/^\xfd\x93\x0e\xb7\xe5\xdd\xe3;\xb7\x86'\x90\x19v\xce\xfb\xcc}\xe3Hb\xdd9D\x84\xcf\xd9\xa3\ns\x90B\xc5\x1f\xcak\xd69\x93\xc1#K*\x83\xc3\x87#\xaf\xfdtO\xba\x13\xc8\xebpp\x04\x7f\xffH \x0dAB\x8b\x91\xeb\xc7e\x9d2]\xea\x03\xaeF\xd5\x13\x03\x1e\xb6GI\xb4'\x85HE\xa7\xad~p\xa2|\xe2\xb2Z\xfa\xb3\xd6\xc8p\xd69\x8d\x0e-s\xba[M[D\x81\x05\x1f<\xea2U\xc3\x0cJ\xfaT\x7fD:\x94\x12\x16Qt\xfc\xfbG.\xad\x04\xa83\xd9D\x16\xbc\xf01\x0d,\x9a\x10\xe6\xe9\xe3#\x88\x0c\x82L\xec\xce\xf8\x07\xa0\x98\x81>\x84nDA:g6\xbd\x18\x8aU\xcfv[`\xf3\x19\xeb\xfe7{E\xdb\xdf\xc0,I\xde\x87L\x7fs\x9cln\xd3p\xb9\xca\xdd\x99\x07\x07\xc3\xd1A\xff`8\xba\x0b\xaf\x93u\x10\xc3\xd9*\xbf\x8d\xd6A\xdcT\xe1\x1e\x1d\x9e#\x0f\x99\xa3*O\xfcf\xc4\x99H)w\n\xc4\xd3\x0d\x95\xc3?&\xb0u\xe7>d\xed\xa1)M8SI\xe4\x9d\xb14\x0c\xa2\xf0\x17\x93~\\],E\xa0\xc4v\xd7WZ7O}\xf8P\xbdm\x88pY\xa8n\x05d\x86\x16\xc8L0\xa9\x1e\x88\x06\xc3\x0cB\xf2\xfe\xab\xee2\xeep\xd0\x12\xa8R\x81y\x1c\xac\x9b\x1a\x93\x1auX\x8b4A\x07|\x18\x9e\x9b\xfa\xda\xb6\xf6u\x15D-]\xe1uu\xe8\x813q\xa0\x07\xdbz\x8f\xc2R\x06)W\xb5\x9f-\xadW<#(\xca@\xdft\x18\x8b\xc7\xd4\xd9\x8b\xe0\x85\x1b\x99\" \x89\xaa\xd9\n\x831 \x0dxA&\x00\x03\x14g(\x98?\x86\x1f\x83\x9b\xfe\xb3%\xc3\xc1\xff\x18\xe4\xab\xc1\"J\x92\xd4\x8d\x9a\xa87\x1e\x87\x0c\xe6\xc9:\x08\x8d=\xe8o\xb0\xd7\xe4\x15$'(\xfa\x98\x9cUe\x9b\xea\xd3\xe6\xdd\xe0D\xc1\x8d\xb3C\x87?\x047\x9f\xd3\x9b\x90\xc5v\xe8\xf0sf\xd8\xeaF\xd4\x04\xf4j\xbfu\xa8\xaf\xb5\xd4\x81\xffj2k1L\xc9Y\xebF\xca\xba\x1aP?N\xa9\xab\x04\xfb\x8f\xe1\x9b\xfd\xf2k.\x9a\xed\xff4}\xb7\x1d\x0e\x87\x8f\xf8\xbf\x07\xc3>\xff\xef\x01\xe3\xff>\xa4\x1f\x8b\xc5y\xef\xdf\xf6M\xc7c\xdb\xdf\xeax\xac\x1a\x93\xb9\xfc\xd7'I\xf8\x1dC\xaa\x8b\xfek\xcb\xeb2-\x1c\xc4t\xefk\xd7\xfb\xe6|\x7f\xd9\x16\x8b\\\x1eK\xa0\xbbF\xc9\x9e;\xf4J^\x1ae'\x8d\xf2\xec\xdb4H\xbd\xe3n\xb3,\xb9i\xc8\x1c\xf32+\xb2\x92\xc7c\xbb<\x9eV\xcd\xd3\xb1E\xe4N\xd1U\x00\x1d\x07\xee\xdc\x81\x14m\x97\xf7\x0fG\xe8q\x11C\x0fF\xfa\xc9|\x83X^s\x08\xc1\xca\x16\xc1\x9a\x0e*\x9fbW\x07h\x1c\x12n\x1c\\un0\x1c\xcb\xe3\xcf\xd1\xf0\xe0.|C\xde\x1a8v\x0fz\x90\xf0\x1f\xd8^\x8f\x8e\xf2\xed\xe4'\xa7\xebp\x07w\x87ey(\x84}\xb8\x7f\xb7\xf8\xc7\xf3at\xf0\xd0Z\xc6\x83?\xc2\xfd\xbb\xd62\xe5\xcf!\xfeB\x1f\x84^\xa3\x1bg\xa3\xbd\xban\xf25\x9c\xc6Qh\x89\xbb\x0f1B\x04\xcd\xf4\xe0ny\x84i\xf3$S\xc3\x04R\x9a\x00\xe7\x97\xbc\x03\xfeR\xb5?zt`l\xa0^WTH;\xd8\x0d\xda\xd2O\xea\x90\xb2gw\xf3\xe7@\xc3la\xf9\xedF\xb2J\x91\x86\x0b\x96(\\\xa6z\xfe/\xcb\x19\xb2\xc4\x93\x86[d\xa1\xddAs\x9e\xb4`F\x80V!v\xc3f\x8d\xa9\xc5\x94\xb62\x99L h4\x0d\x83\xd2\xcbCx\x02\\\xbao)\x9c\x90S\xcd\xf0\\\x19\xa7\xc2^\xcf\x0c\xc8p\xbd\n#\xa6\x14'>\x14s\xbb\xd2v\xc7\x81N\xf3x\xe9\x8f\xcc\x19r\xfe`\xdfIK\x8a\x00\xd0\x9d\x04\x85v\xbaS\xbb\xc2\xach\xa3\x8eZz\x8d;\"\xbd\xc1\xd4\x99\xfet\xee\x9c\x97\xcd\x07d;\xe0\xa2l\xcd\x9e\xa3\xda\x12\xa4\xbd\xed\x92\xf0\x0ea\x81\xb0\x1a!%\x1bd\xc96\x9d\xd9\"Fx\xbe,\x18\xca\x82\xe48\x98\x0efI<\x0bD\x10Gv\x0d\xaf\xd9\xf2\xe4f\xe3\xa6\"\xe0\xcf\x07\xc7\xab\x99]\xc1H\xba\xd8`\x11\xc6\xf3\xe3U\x90\x9e\xc6sv\xd3fB\x93\x0f\x87\xd1\\\x87\x0f\x85\x89\xfd\x86\xb3\xa22\xceZ.>\x95,i\x89\xeb\xf9\x02E\x0b\xd7\x98X\xa2\x1c\xda\x1c\xdcx\x10\x05YN\xc3\x7f\n\xb9\xf7\xd8\xe38\xd0\xb8]\x86\xfc\xcc\xbeX\x8aoos\xb6\xd3R\xc8\xd9\xf0\xd5\xc0\x1b\xb4\xb4 \xe4\x95\x858\x83\xf5q&\xe6x\x8b\xc4\xc5\x9fu\xbe\x1a*\x17\x87n\xa6\xebc\xa6j\xf6\x0d\xe0\xd2\x0c\x9e\x88\xc6\xc6\xbd\xb3EY.\xe4\x1b\xe5\x98\xc9\x85\x8d\xea\x89\x88\xfe$\xe8t\x84\xfb\xd4\x92~KQ\xc6\x84\xeb\x8c\x94)?\x99\x0e\x8dq6tyg\x97\xd5j\xbd)\xa3?r\\Hc\n\xdc\x92(\xe8#\xb50\xee%\x7f>\xb6\xedA\x8a\x06W\xd9\x8b\xf1^\x0c\xd8D\xbc\x96\xa5$\xa9\xf2\xc9\x84\xbcA\x92B\xb4+\xcd\x89\x8f\x15}?\x87\x9e\xafdN\xe95\xca<\xa7\xd0=\xa8\x07\xee\xa2Q\xe0\x10\xde$\x9c\xf4\xbdJ\xc2\xb8\xc5\xe6!\x9f.\xb6\x0f\\\xdb\x99lW\xae\xb1\xc6=DjIU\xc4\x13\xd6\x12\xa1~j\xef\x1b\xa7o\xe1\xfajBo\x84\x85\xe8\x8bM\xac?\xb9\xcf\xd7\xf2\xf9w\xdf\x9d\x1b_\xeek\xbb\xfeQ\x1c\x16t=\x13\xf8\xba\xdf\xef\xbf\x8b1\x00\x96\xb3\xca\xf3M6\xde\xdf\xdf\xb0\x1c\xf3\xdd\x0f\xb2\xeb`\xb9d\xe9 L\xf6\xaf\x0e\xf6\xe5\xaf\x9f\xb3$v\xde\xc5\xf3d}\x11\xce\xc7\xe0|%>\xf4\xb7\xa1\xf3\x8e\x0e\xc1\x82\xd2>\xab\xa60\xf2\xc15-\x07\xf4a\xe6\xc1>$\x1dg\xa5?ie{\xb4\xa3\xc0\x0cz\x10\xc17d\xee\x1d\xdc\x83#8\xc08\x0e\xdf`$&\xfe\xbf{\x17\xfa\xf4\xd2C\x95\xd2\xa6\xe0\xd8\x9e\x02Py\x17#\x0e\xac\x08\\\xdf3t\xef\xf5\xf0\x00\xf2 \x10`\x0f\x88L\xd37.\xb1\xa0\x0b\x90\xbe\xd2\x81\x0f\x8f\x1eiPo\xc7\xce\xea\xf3\xd1\x87G\x1d\x8b\x7ft\x9b\xcb\xd9/%5\x90\x84h\x07S\x85|2wK\xf1\x9e\x8dG4\xf2\xb1\x84\xb4\x93\x8c\xc8N\xa4X\xbe\xdd\x8c\xbb[\xbb\xa1h\xd4\x1571\x91*y\xeap\x8c\x8fU|B\x87\xe6\xdcS\xc6\x9d\xdck\x8a\x1d)\x1f\xe1`\xf4|\x9b\x8a\x00\x90q;\xb8\xb3\xf9\x92\xbd\\,2\x96\x9bBz\xeb\xcf'\xed[\x9e\x8c\xc1\x92\xab\x80>\xff\xd7\xb8\x89\xd6\x85q\x9e\xfc%d\xd7\xe5u6]\x9c\xad>\x92Wc\x9c\xf0o\x93m<\x0f\xe3\xe5q\x14\xb28\x7f\xcdf\xb9\xeb\x0dV\x88'\xed+\x14H\x8a\xae\xf8Z\x0f\xc2\xf6j3YM\xe2j{\x95\xc5N\xbcc\xc3Q\x02zm\xa1n0\x05\xf2\x13Xp\x88\n\x91^<\x85\x19\x1cQ\xbc\x01Z\xc91\x04\xe2\xc3\x06\x8e s\x03N/\xf9\x9b\xa2\x00\xb1\xd2\x06\xccn\x80\x81\x19\x8bs\x96\xd6\xb60\xed\xb0\x8b\x99\xdb$]\x94I\xe1>\x1c@\x8f\xa3\x0b\xc7\xaa\x96]\xe7\x85=OL\xefS\xe6\x94\xe5\xc9f\x0c\x81\xbd\xc0:\xb9\n\xe3e\xc7\x0c\xfcP\xd0\x86\xbd\xbd\xfa!\x90|\x1a\xc6\xc3\x81f,\x80\xa7\xb1\x14.\xdfX[Jca\x833N\xbdUN\xb3\xa4\x14?\x90\x7f\x9cDl]s \x04\xc1G[\x17C,\x82\xd0E\x88\x9f\xfd\x17\x1a\x91\xc5\x8f7\xc9\xa6\xcb\xd0\xd0j\xef\x9a\xfb\xa0x\xd7j\xe0\xd4n\x18/\xc5\xc8yo\xea#/k^N\xa4\\\xddd\xe5\xd2l\xde$\x1c\x92wL]\x81\x9bkIN\xa9P\xa0#\xac\x95\x978\x8cc\x96\n\x89\x01\x97y\x86\xc8Bov\x1c\xa3\x00\xadn\x8b\"\xf5T+\xa2\xe6\xc9\x86\x93 \x14\xde\xe2A\x82,\xca\xb4\xfb`\x06W\x83\xb75\x06%\x0drv\x86\x1bQ\x8b\xeah\xa3G\xd2N\xd5\x08N\x96D2e(i \xcb\xaf \x9c\x03\xef\x8ek\xff_\xbb\xed>k@'h\xec\xe8S`M\xc9\xe7\xac\x04^~' \xdc\x15S>\x0d\nw\x86/\x01/\x7f\xa8\xbct\x82\xf9\xfc\xe4\x8a\xc5\xf9\x0fa\x96\xb3Xd\x0c*L.{b\xcaq\xf2\xff\xb2\x98\xcc/\xf8\x9a\xb9%\x9ac\xbc'&E\x1ag\x15fy\x92\xdeV\xad9\x9bm\xb6:\xcb\x83\x9c\xcc<\xa2\x90y\x9d\xb8L\x13\x92 \x08\xe1\xe05\xe3\x85Qj\xd4+\xd7%\x0b\xcaT*>\x0fj\x95\xf9\xe8\x82m\x9e8\x9e\xda\xdc\xea\x82\xb8N\x94\x04s\xc7o\x87 \xeakWE\xb1ql\xeb \xde\x06\x91%\x86=Wq\x1a\x86\xbdI6\x19\xaen\x9b\xe7\xb5|\x18\x86\xe8&K\xdc/,\x16\xdc\x8cRH\x15\x9f\x12T\xf1\xc4\x8bAQ\xce\x06\xf7\xb0\x87\x97\xf3\xc40e\xb0\xf7\xc1*\xc8\x10\x92v].iUL\x06\xa8\xd0\xb8\xde\xa0\xd0\x08\x9aO\x0dZ\xedC\xd2h\xa7 {\xc9\xa4x\xf0\xed\xed\xe9\xdc\xadM!e\x0b\x99\xc1\xef+\xc7\x9b\x8e\x9a\xf2\x05\x83t\x8ek\x1b\x05\xd4\x0c\x05$L&\x850\x99s\x1e\xc3:\x88\xdc \xe4\x98D\x08\xe9\x9c5\xb5+\xf4Cx2\x81\x14\xc8 \x1d\xd0\xff\xdc \x124\xa8\xa8\xd0\xac}\xd9\xa1\xd9D\xb6\xf6L\xae\xebW2\x8aO\xe1\x86\xe5\xb8?}x\xf7.\xf34J\xe5\xbe{\x97}\xf87\xcf\xe4\xc2i\xc5\x9aY\x14\xce\xdewB\x99\xd2\xb1!\x1b\xe4A\xbad\xf9c:\x89q\x9e9\"\xd8L\x1e,_\x04k\xf6\xd8\x13G\x9f\x9b eq\xfe\"\x997$\n\xdfs\xf7\x90\xb1\x8c(\xe0\xd7\xe0z\x15\xceV\xa4&`\x1a\xc8?\xb3[\xfa\xb5fy\xa0~\xcc\xf24R?\x82\x88\x97j\x8c\xfd\x82\x16\xc86h\x94\x90\xa8\xa8\x94\xa2\x10\xf5\x08d\xe52G\x95\xdf\xe3\x9a\x91\xbc\xfa\xc4\x1a5\xd1\x80\xb6\xb9R{\xca?\xd0\x88\xac\xb8\x96\x82\\\xc7\x8d\xeb\xe7k\xd5\xa7\x94\x02pW\x90\x06\xdd\xc5\x0b\xb3\x18\xe4y\x1a^ns\xe6:\x9cv8\"\x85A3\xd9\x12\xc6\xfe\xe2\xce\xf6W\x0e\xf9\xb7n\xc9C:\x1f\xcc\xa2 \xcb8\x90\xb5\x86\xfa\x91\x06\xdf\x06\xb7w\xf9D\x0d\x840-\xdcZ\xdcQ\x9b\x89\x10\x8fW\xber\xc4\xd1j\x87\xbdB\x0c\x88\xe4\xd1J;\xb9\xca$\xac\x10q\x8c>\x95.\x01egJ\x19'\x08\xcf\xc94\xd5\x06}W\xe2\xcac'\xd6\xa5?\x15^\x02\x93\x16c\x164\xab\xd3\xf2Y\xec\xcc\x19\xa9\x16]\xff,3\x9c\x0c\xfa\xb0@/\xeb;\"x\xd9N\xb3\x94(\xa7\xa4<\xf7\xef\\\xdet\x8c>^\xfa\xf3\x11C\xbb\xa2\x94\x91\xf9\"\x83\xf4\xac\xc1\xe8af'\x16V\xf2\x07{!\xe9\x07\xa7^~t\xcb\xdea\x18\x9e\xd1\x18J-\xc5[\xad\xc1f\x13\xdd\x92\xa7 \x8c9\xac\x7f\xf8\x00\xae~\xa2\x1c\x9a\x0f\xa0;\xdd\xc9\x13\xc1\x1b\xe9\x94\xb2\xc8\xc9\xe7\x83sq\xc1\xb2\x1f\x93\xf96\xe2\x92^y_0}\xdbX\xcf\xc8\xa0\xeb\x99\x926m\xdc\xd8\xbd\xeb\x19\x02\xa8\xf0\x0f\x07\xd5\x0f\xa1\xf8pX\xfd\x10\x88\x0f\xf7\xaa\x1f\xb6\xe2\xc3\xfd\xea\x07L\xf6\xe0\x0e+o#,^MJ\x85'G\xbc\x15\x94&\xf1\x0f\xb2\x88\xb9\x87\x0f\x1fT\x1b^P\x94\x17\xcft1\xd3\x90\xf4Y?\x83f\x83b=E\x9c\xd5:\xac\xcb\x9b\xb1-\x97/A,2E\xbdX\xb1h\xc3\xd2l\x90lN\xe7\xe5\xe1\xb6;\x02\xaa\xd1\x0b\x7f:\x0b\xfe\x91\x9c(F\xe7\x89Lj6\xcf:\xa9\x9e\xf1JA\xb5\x92\x9b\x0f..0\xfd\xd9\x05\xc5\\\x1b\xfa\x18\x19R\x16\xf2<\x91#\x11K\x93{g\xe3\xc1D8\xc8\x93\xe52bg\xab\xe4:\xeeJK\xa4\xb0\x1f\x0e6i\xb2i9c\xcc\x85\xd3\xeem\xb2\xcd\x9fa\xdb-\x15b!\xb7-\x9b\x8b\x91\x97\x1cG8$\xd5\xd5\xcd\xab>\xc25;\xc3\x896\x17E\xad\x96s\xae\xd7,K\xa2+6?\xdb^\xe6)k<\x0f\xc53P\xcd?'@;\xf9@$\xc6\xa95\x84!KV\xc9\xb5;u\xd4\x0c2\x87\xec\xd9\xe7>\xec\xd9\x9c\x9a)u\xcfq\x10\xcfXt\xccE\xe2\xae[\x869j\x04\xbdo\xde\xae\xf4\xf64\x7f\xb9\xcdO\xe2\xe02b\xf31\xec\x85B\xa7\xac|\xb1\xb6b\xc8H\x03\xc5\xd8\xdf\xa4\x1c\x10v\x1a\xfb'\x80[\xb6a\xb3\x1d\x80m\x13\x98b\x8a\xea\x0fA\x1be,j\x10\x0c\x7f\xcbU\xe60\x84.\x1b\x7f!\xbf$F\xc9\xc11\x87ejs\xab\xa3M8\xb9a\xb3m\xde)q\"\xec2-F\xed\x9e\xc6\xaf\xd2d\x99\xb2,\x1b7&\xf2n\x18c\x1d\xfb\xba\x0e\xf6\x13\xa1\xe5\x8cEl\x96'\xe9\xaf\x00/]\x08\x13\x1f\xc2\xab _\xd9aK\xdd\x07\xc0\xac\xf6\x1b6\xab\x12\x15.\x9b\xfd\xe9\xcc\xf5\xe8\x12\xb1\xa9\xc4\xd4\xe1\x03Wt\xa6a\xf9\xcdt\xebW\xde\x82_\x0da\x7f\x85\x0d\xb0\x10\xf6\xf2\x1eX\nu\xdf\x06R\xd1\x9b\xb2\x00\xd6 \xc9\xc8>[\x13zZr\x8a\xfb\xa6;\x97\xb57\xca\x11\xc1\x87\xad&\x85\xf8\xc2\x07\x81OA\x7f;5\xcf\xe3=\xbb\x1d\x83\xb3\x0e6Hb\xde$\\\x8c\xce\x1c\xf34\x84\xe8\xdc\xd9]B\x1aJ\xf2A\xb2i\x07\x98\\\xc8)\x1d\x89A\"\xc4\xb4\x9c\xdc\x1d\xe3E\xb8\xcc\xbc\xb63w\n&?Of'7\x9b \xce\xc2\xa4\x834\xc2\x85G\xb6\xf9!\x8c\xdf\x87q\x8bX\xb4\xa5\xe2a\xb6\x89\x82\xdb\x97]\xa5\xa3L\xaf%R\xd9I\xff\x8f\xe6\x9a\x11\xa9\xb6\xdb\x0d\xd7\xa6\x10\xc6\xd7a\xfe#\xa2]\xcb\xeaa'OO\x16\x83\x1f\x83M\xab\xd2\xfe\xb3\xd0\xf4\x17x\x13\xfcOg^\x0b\x8b\x03T4\xc6p\xda\xdc,\x7f\xf2`\xd9\xe9\x86\x05\xa7\xdfV\xef]\xfd\xc9\xa4\xee\x91[\x14-\xfa.\xf4,\xc7\xc2\xdd\xf4g\xce6)\x9b\x059\x17\xf1OI\xf3-^9B]3\xf6\xa5\x15\xa3\xee\x9a\xccS\xf2!\x0e4\x86\xa4\xbdh\xa1\xa7t\xb8JQ\xd6UZTi\xa8\xaa\x8a-j\x19\x96\xaf\xdb \xc4\x82u\xb7X\xb4\xf7R\xd2/;\\\xf0SzU\x8b.\ne\x15\xaaE\xf6\x80\xbaN\xd9B\xf2AW\x81Z\xf4O\xb0\xe8\xc6-\xda(4\xe8\xc7-B\x12X\xd5\xfd\x16\xce\x0ff\x89\x96\x04b<\xd2\xa9}mo\xb0f\xd6\xd5\x9a\xebzB\x04P\xf7_\xd7\x1fa-\x89\xa4\x89V\xb8\xb5\x0b\x8f\"\xf7\xc7\xb6\xabb\n\x9c\xc7\xf0s\xf3\x8c\nm\xba\xcdh\xdf\x11<\xba\x82\xb4v\xb6-\x96P{\xd3\\\xb5tR)*\x97\xde\xb5U\xd7\x0eiUu\xed][uqD\xa7\xaa\x8a\xdf\xcd\xd5\xa4<5\x86\xcb\xf6\x82\x82\x95\x8f\xe1\xba\xbd\xac\xe2\xe3c\xb8h\x19y!$\x8c\xe1e{Y\xad\xe5W\xcd\xa5K\xf2\xd0\x18\x8e\xbb\x94\xd6Z?k.\xaf Och\xd9\x9d\x92\xe44\x86g\xcd\xa5u\xc1r\x0c'\x1d\n\xa3T9\x86\x9b\xe6\xa2\x8bx\x0co\xac%l\x87\xab\xb5\xb7\x1f\xcf=\xbfrO\xe4\xa3\x9b\x0d^mSfJ1\xb9\x92\xe4\x02-\x1d\xb5\xb3\xa9\x12s\xda\xab84\x16t\x00\xdd\xc7J\xdf*\xbc\xa4Z\xd5\xc4\x0c\xaa\xb2\x84\x8d\xf2k\xc6\x05\xcc\x15#&\x00\x13\xa0\\\x14\xbf7\xc7\xaf\xc8\xe6\xf8\x15\xd9\x1c\xbf\"\x9b\xe3Wds\xfc\x8al\x8e_\xfc\xc3Pw\x1a\x8a\xc8\xb9\xcb\x92k\xfa\xb7\xf6\xd9\x9a5\xfadi\xfeX&k\x8cv\\ip\xc7\xf2?\xd9\xe5Jx\x18bq\x992\xa7\x9a\xd6\xc8\xe8\xd4\xf8\x19\x07\xa7d\xa0Z\xb2\xfc\x07$t\x06)\xbe\xab}j\x17\xdbT\xbe\x83\xaa\x1c\x9b\x14\xdf\xc1l\x9b\xa6\\\xbch\x10t\xd1>\xe9\xc6\x98T\xbc\xd1y\x0d\xef\xe8\xb6\xceO\xab\x90Yd\x1dg5r\xa4O\xeb\xd7\xf0\"\x11\xdc\x03D\xf0\x19\xbcS\xe0|\x8d\xe7\xf5_;\xf0ug\xd2Z\x86\x00\x93@\xd5bg\xfc\xa4=T@a\xb3\xe6\xb6\xac\x06\xa3\xa50\\\xfb(\xcf\xa7\xcc88\xd3\x90\xed\x99\x18\x87Nwg>\xccj|\x84Z\xff\x171\x16\xcf\xfftb\x8c \x8b(\x15\xfa\xd5|a\xb0\x8b\xd3\xac\xba\xf0\xc3WL\x91_\x15_?\x82 \xe5 u3\x8fr\xe8\x0f\x1f\xc3\x0c\x9e@\xf6\x18f\xbd\x9e\x07\xd1tv\xae\xd7\x9c\xce\x0ca\x01\xc5R\xc6x\xe1\xd1\xe6\x9c\x8b\x18\xd8\xca-fA\x14 \x96\xc1|\x98\xf2\xba\xe72\xf4b\x84IZ\xc3\xc1,J\xb2N\xeeV\xc2\xc5J\xb7\xfd\xa11\xfc9G\x85\x10\x7f\xbbU\xffz 4\xc3\x8bZ5\xa6\xc77\xe3\xb7\xe0\\_\x96\xe4ub[\x1d\x0d\x9eqwcj\xba\x03;\xa4\xd3\x15\x96\xa6\x1d\x86\x10\xeeb\xf1\x0e\x84\xf1t\xf0\xec\xec\x8d\xbd\x14\xdfm\xed\x04-\x90)m\x1b\xcc`\x98\x0e\x15\xa1)\xd6\xc1\xa9\x81sS\x8aT\x87\xaf]f\xcb\xd0\xd0\xc6\x8a\xe7\xe1U\x8dT\xeb\x8f\xbaV5\x06g\x1e\x06Q\xb2\xecoo\xacWq\xbfH7\x97\xc1\xec\xfd\x1f\xea\xe57Z<9\xa5>^\xcf\xff\x8d\xfaZ\xb1`\xfe)\x9d\xad\x0e\x95\x1c\xe8<\xbb\n\xc2(\xb8\x8c\x18\xea\xfbI\x1a\xfe\"\\\xb8\x9a6\xfbr\x9b\xe7h\xe0\xb5\x0f8\xbf\xdd P\x89\x92\x9d&\x86\xfc\xa0\x8f\xd3k\xa8\x91\xc4\xba\xb9 \xeb\xec\xbc\x02\xd9\xd5\xb2q\xf4\xd7\xe1<_\x8d\xc19\x186\x0cd%\xa2;\xf0R;\x8f`\x9b\xd5e5\xfdY\xa5l1\x06\xe7+\x9c_\xc3 n\xa20~\xff}\xa9\xb0\x05y\x91\xe9~Y\x00\x9c%q\xce\xe2\xdc:\xfbh\x80|\xee\x8c\xfd\xcd\xf5\x06\xeb`S\xcaI\xdex\xfd\xb7\x85~\xce\xda\xcc\xb6\xc8~[\x0e?\x9e\x9d\xbdi=\xf0\x98\x17,\xc1\x1a\xb7D>e\x13X\xcb\x19\x96\xce\"[\x0f\x81*\xa6\xb8\x96\x93\xdb\x92\x91\xaf\xc5\x00\\1{\xd6\xdd\xa1\xe5c\xb3\xb4y\xf8\xd4\xbe}9%\n\xdf\xfeK_\x12\xcf\xbf\xf4\xa5\xff\xc5\xfa\x92\xe0|]4\xa6\xce\x97S\xf2\xeez@\\\xd7/\x06\x1a}|\x93\xa8\x83g\x9bI&\xafim\xe6\xd4\x15\xffR\xda\xccO,\x80\xac\xac\x8dy\xa4\x8b(\xd9\xedU\xb2\xd9n\x1c4,6+u{{\xbb)>\x89\xa8\x13\x14\xee\xce\xde \x0b\x7f\xb1D\x13\xf9\x92:\x10\xef\xb2\x7f\x9d\x06\x9b\xcd\xa7\x08\xbc\x1d\xe4U\xad\xb3\x04\x8e\xc0\xb9\xccc%\x113\x88\x92\xd9{6w`\\\xfd\xb0\x8d\xc5\xa7\xae\xf2\xaa\xf8\xb5\xf3\x14\xb2M\x10kR\xbb\x1c@\xa3\x98\xfe\xcf\"\xe5\xe2\x82\x7f\xa5\xad\xf1W\x1d\x96U\x13|\x1b\xea\x9bG\x8c\xf4\x14\xddkm#\x8f\x85u\xf8_\x92\x0d\xfcK\xb2\x81\x7fI6\xbf\xbddc\xbd7\xc0\x06Y\x9el8\xd4\x07\xcb\x80\xf8\xb0\x99\xff\xc8\xcb\x05\xd2z,:\xb1\x88&\xe8lop\xa9\xff\x9f(\x8e\x94\x1c\xd5?\x8dy\xef\xc6R9\n\x96\x85\x94\x8b\x0b\xceH5\x9am\xf8\xda\x81\x0b8A\x1a\x06\xfd(\xb8d\x91c\xea\x06h\x9c\xd6\x8e\xe4\xf7\x0e]}!>\xfeO\xc2\x93\xd9g\xf2\xe4\x86\xfa\xe6\x11\xff/\xb4\"\xcc8K\xad\xf1\xd4D|\xa9q\xe1PV11\xdb\x99\x89\x0bo\xc5\x87\x1a\x17\xce\xc4\x87\x1a\x17\x8e\xc4\x87\x12\x17\x9e\xc9\xc8G3\x11\xf9\xc8\xc4\x8fg\xbf=?^t\xe5\xc7\xb6\xb0EU*l\xe5\xb9W\"\xafz\x95\x98[}g\x92:\x0fl W$\x16+\x18$1\xa7\xcd\xc7\xab ^\xb6g0\x02\x8d\xcf\xb1A\x1c\xac-\xbaXP\\[\xab\xb0\xe8\xbf\x7fDL`&\xf4\xe3\xfc.\xc3\xbb\xee|H\x9d\x06S\x0fb\xc7\x1b\xa9\x1f\xdf*\x15\xca\x0d\xc8\xe3\xd7\xd2}\x94,M\x91tv\xe8\xbfY8\x08\xda\x14t\x8a\xab\xd0\xc9@B\xc1\x154\x93H\xcd\xe6\xdd\x1a\x80U@\x819\xa25 \x1d\x19\xe4 \xc9w\x96\x99\xc5b\xcd\\s:\xd3\xa0~\xec\xbe\xc3b\x9a7\xb3\xe3Y|P\x84\xfa\xe0\xbf,8\x0ee\xd9)3\xcaN\xc1?@vj6\xe2t1\xf6\xc4U\x00i\x83\xa5\xee\x87\xeeyW\x1bR\x88\x85\xbb\x9d\xd0\x07t\xd2\xcd\x91\xff4g\xeb\xa6\xabH[*Jy\xe0\xda\x8cO\x19\x15\xfe\x96d\xc8\x96\xa3\xf6\xa4do\xb2\x97\xa5\xc0\x19\x8b0\xcaY\xfaIH\xb7\xb77\xc3k?\x96(\xea\x80\xd8g\xef\x7fc\xee\xbfc\xe7r\xe5D\xd4]\xbc~\x94\xdfnXC\x8c\xd8\xa6\xc1\xcc\xbf\xcc`&;\x0c\xa6Q\x8f\xb0\xdd\xbf\xd8\xdd\x088K\xe2<\x08\x9b\x0e\xd9\xf7\xf66h\x95\xe4b\x87\xb5\xdfE\x92\xae\x1b;Nb\x8a\xf2\"o\xa5(6h\xebvS\xa6\xf6mI\x97Z\x16&\xe8t\xc2\xd9v\xba7[\xb1u\xd0z`\x18\xe3\xf2\xb6\xb4\xb5\xd3\xe9\xa6.\xc3\x8c\x81\x95d\x9a\xe6\x9a\x81vy\xad\xe5\xdeK\xf9\x08\xf5\x13\x8e.\x0bN\xea\x7fA\x00\xbd\xcc\xe3VK\xb5\x00P\x8e^\x0b\xfa\xf3\xc8:\x82\xack\xef\\e\xa6\xa3yi\xa3\xee\xac\xcdjR\x96m\xc8\xce\x0fX\xc6\xf1`\xfciC\x15\x1e!\x84H\x1d=B\xeaS*\x00\xc4\xba\xb8e\xeb\xf8'\x8d\xb5e\x0c|\x8b\xe7I\xdc\xe4\x97\xb1\x83\x97\x8as\x8cn\x1bh\n\x9bs\xa25o\x03 \x01\x94t\x18\xf0E 7\x9b%\x1b\xd6\x9f\xb3E\x83/\x87\xa5\x9bMq,q\xc6[\xc9 H\x19l36\x87<\x81e\x1a\xc49\x041\x04\x9bM\x14\x8a\x80\xd3\xf3p\xb1`)\x8bs\x88\xd8\x15\x8b2H\x16\x10\xccf,\xcbx\x95y\x90\x07\x90\xc4p\xc9VA\xb4\xe0\xdf\xf2\x15\x03\x16\xcfy\xa3\xe9\x00N\x82\xd9\n\x9e\xbd:\x85up\x0bs6\x8bx\x7fI\xcc Ia\x9d\xa4\x0cp2\xd9\xa0i\xf7\xf5Q\xf3\xa6R\xf6\xb7m\x98\xb2\x0c\xbbZ$Q\x94\\\x87\xf1R\xb6\x04Dg\x80b\xe1'1\xcb\xe06\xd9\xc25\x9f\x9a\x9ac\x9e\xc0\x19\xa5\xd1\x85\xb7\xa7\x03\x07\xe3\x03\xef\xc6\x81?\x8d\xfb~\xac\xbb\xd64J<\x9f\xcb\x91A2\x9f\x06%\xc5\xbe\xf0\xdb\xb6\xa6w`\x00\x92\xbd\xb5\x05\x8dA\x10oR\xa9\xda\x19\x04\xa7z\x9ft] \xeal\xa3\xa2\xe4b\xbf7\x1b\xd5\xef\xf2<\xc8\xa7?,\x96\xa8\x7f\xb6\x93\xa1\xffy\x17\xb6\xbe\xa8\xda\xdd\xa6T\x8b\xd0\xaaH\x0b\x9aUo2\x905\xeb\xdc\xbb9\xbaw\x93kC\xe5\xe3\xd1\x16\x1a(\xd8\xc1}^h\xdc\xc1&\xfc3\xbb\xe5\xc3hR\xa4#*|\x19d\xe1\xac\xad\xecL9\xd17+\xdb\xb9\xce\x9a\xcc\xda_v\x1db\x06\x93E\x13C\x9a\x05\x19\x031\x0fgl-\x06bh\xb6\x83\x8dV\xce\x02\x1d\xb5&\xe8\xae9AW\xed j\xfaJ\x87\xc8\x1c:+\xec\x10\xf9c'\x0d\x0dHF\x15\x1a\x9a=\x8d&4\xe8\xf6\xf2\xb9LY`9V\x05\xb5\xbf\x08z\x9f\xb1\xbd\xd1\xbf\xb6\xf7\xf7\xb9\xbd\x92U~\xf2\xcev\x928A\xedn\xf3\\|p\xde\xc6\xef\xe3\xe4:Vas4'nTB\xc1\xf1a\xd1\xf5v+t8\x0bo\x1b?\x8d\x1bz\xe0\xf4\x7f\xde\xae7V\x15\xcb\x90h\xe6\x7f\xf8 \xe8\xefR\xba\xfc\x97L\xf9\xbfD\xa6\xe4\x82V\xd2@HU\x1c\x00\xd7A;E\x93\xd0\x14\x17e\xd7,\xcb\x82%k*\x9d\x16\xa5\xb3d\x9b\xce\xac\x02\xd4\xe7\x92\x1e\xdd\xc6\x83\xb3\xb5\x85m\x05\xcc\xd3}\x1b1\x13\xe4\xea\xcfe0{\xbfL\x93m\xd4)\xd5\xe7\xfbm\x80\x1e\xf5\x07\x97\xe7\x1f\x16\x98\xbay\xa7\xa1t#\xaa\xc9\x95\x16t\x7f\xea;w\x8a\xd4\x10\x9c\xe0\xe14\x1c[z\x9c\xfa\x92\xdbX\xd8\xef\"\x94w\x1b\xdc\x83.(u0\xb2\x81\x12\x95\xba\x99\xc4@\x19\xe6\xda\xf7.\xc44\x8d\xcei\xbc\xd9\xe6m1v\x03*\xfb:\xb9n+\xb9\xa5\x92\xc7I\xa3\xb0\x08*\xff$\x1e\x19\x9fp\xc1\xac\xad\xfc\x8c\xca\xff\x18\xa4\xef\xe7\xc9ukX`\xcaB\xe9\xfc C\x9d\xbe\n\xf2U\x9bO\x0e\x08\x17\x96\\\x04W\x12\xa4\xa9\xb9\xc2\x1c Y\x10E8\x85\xcc\xf5v;\xf0\x92\x8fdo$\x11\xf3%9\x9d;\x1e\x9e\x7f}\xba\xe9\xa2\xdb9W\xcb\x19\xea\xean{\x99Y2g\xaaT\xa2\xe2\x04\xbb\x0e\x07B<\x07t\xfe\xff\xff\x0f\\2pz\x8e\xbd\xa5E\x9b\x11\x84\xa2#OU\x16\x19\xcd\xe7\xce\xf1!9\xb7V\xc6\xb4\xb6\x9bF\x87\x98\xd5}\xc3\xf5\xb2y\xd3\x19j\xd0\xb62\xad\xb7\xf4I\xf7\x19\xcb\xf5\x9a\xb3l\x96\x86\x9b\x1c\xa3^7\xcf\xe5\x93\xc7\xa4\x1f\xfc\n\xbd\xa8\xeb\xd6\x96w\xf5\x8b\x8d\xe24\xde}\x0ca\xfc\xd9#\xa0;\x13j\x14\x88\xeec\x07\xc1\xa4\xc1\xf1\xa04\x18\x07\xbe\xc1\x07\x1a\x9dB\xb6mC \xdb\xc0Dx\x8ep\xe5\xabE\xcd*L\x9e\xf2\x92\x06\xfel\x82%\xcf\x87yS\x98\x8a\xae\xde\x83\x9f\xe4g\"\x1fT\xcd[\x0f\xb2\xa1\xfd\xe4\x1d\xc0\xea\xefD\x9f:\x0b\x1a\xa6\x80\xa9\xa6\xc3\xec\xf2\x907m\x97\xd3u\xc1\xa2N\xbbK\xbb\xa67e\xdd\x85+\x91\xfa\x8e\x15\x97\xbcZN\xe3\xc8[6\x0f\xd2%\xcbi\xe3\xede\xe5\xdd\xb7\x8a\xbf<#\x91\xbcmg\x85\xc0ega6\xf6\xc5\no\xfd\x10\xd3L\x87\xadz\xfc\xbf|\n\x8a\xe7\x93\xac\xbe\xffd>\x05\xb0\x9bN\xde\xe9f)\x88\x9e\x7f\x83\xc4\xdc\x0b*\x186\x8cb\xdb%|\x05\xdf\xd1m\xab\xde\x11a\xa9f\x9d`&\xf3a\x0b\xc1w\xb0\xcdXj\xbfP#v\xbfK\xf6RR\xce\x1b4o\xa9\x9c7\xccS*\xe7p\xd4Bs\xe4\xa8m\x8a<\x7f>r\xf0\xb4\x9a\x19\x7f\xeb\x94\xa8\xffp=\xbf\x8bc\x06\x94\\HZ\x95\x0e\xbaM,\xf5\xfcX\xd3\xf39\xda\xd8\xd6\xbe\xbe\xf0\xffK\xb5\xfdv\xed}\x978\x93\xf0;\xd0\xf6\xa3O\xd3\xf6wS\xdf\x17\xbb\x99\x08\x0c\xda\xbe\"z\xedj\x7f\xf2\xab\xaa\xfduc\xa3\xfetP\xfb[N\xccH#\xb1GH,\xd4~\xe7\xdb \x0bg\xe5\xe8\x88\x8e\xbdj\xab\xce\xdb\xac\xc3\xa7]tx\xfb\xb0\xad:\xbc\xadJ\xd0\xb6\x14\xad6\x89O\xd7\xe1?yLU\xdd\xf5\xad\xe4yR}\xb5V\xac\xa8\xaf\x8e\x0f\x1b\xfc\x9f\xeb\xaf\x0d~e\xcd\xc3\xf9\x82\xfa\xabpC\x9f#q\xa7?[j\x10\xafw$\xde\xfe*\xfa\xf1\x17\xdb\xa8WA\x96]'\xe9|\xe7\x8d\xd2\xed\x0c\xbf\xde>\xed\xbe\xfa\xc16O8g\x8bX\xcew!f\xd7\xfd\x8d\x98c\xb7}\xebXZ@P\xc7\xd2\x9f\xb6\xcb_\xc4\n\xf2Y\xde{\xff$V\x10\xd3\x11yy\xc8\x8b\xdf\xbf\x15$\xd5\xac \xf6R \xda\xf7;\x18I\xd2\x16\x99\x8d\x1c\x9b)\xb5\x176gf\xe0\xc14<\xe7\xb2\x85\xaf\x9b@\x9a\xe4V\x94q\x03\xf3n\xa2\xe5\x84Y\xa3\x0b\x94w\xf5\x9f\xc9\xc7aa\x8d\x1b\xb2\xb0\xf98,l>\x0e\x0b\x9b\x8f\xc3\xc2\xe6\xe3\xb0\xb0\xf98,\xc8\xb2R\xfe\xc0\x05Yw!M,\xfc\x8fGw\x1fxf#\xcb\xe2\xb77\xb2l\xbe\xa4\x91\xe5\xf7\xe6\xf80\xff]:>\x04\x9d\x14\xee\x85*\xd9A\xc3\xe3\xbb8\xe3 B\x17\xf8\xb3\x06\xc5\x07\xa3\x98\x0c\x8a\x04d\xae\xd0\xc8\xed5\xae`Bb\xf7\x86$\\%j\xb5f\x16]Wj\xce\xa2\x90\xc5\xf9\xa9H&\xba\x1a\xc8\xdfm\xed,\x8d\xed\x9c\xb1Y\xca\xf2r[\xf4\xae\xad\xbd\xdbJ{R\xacx\x8379\xb0\xb6\xc8Q\xd8\xbfL\xe6\xb7\xceg\xbb\xa7\x04\x9b\x0d\x9d\xb5\xad\x06\xe2O\xfb\xe0\xbe\x84+\x0b]\xdb\x1c\xc3\xf4\xbc\x01\x14\xc5\xe27\xa6\xdb\xd4W\xb51\xb9favkH\xea(\xd7y\xdc\xb8;\xfan\x8c\xe1\xd6X\xee\x1f\xe0\x8e\xf3\xab\x18\x9b\x9a%\xbd\xaeaU@\x85Vi\xa3?\x00\xbbEV\x81]\xa3\xab\xc0\x8e\x11V@\xb0\xe1\xbc\x83\xcdkKS\xec\x96/\x05\x8a0+\x9d\x8c^\"\xa9I\x07\xa3\xd7\x82Jv0zm\xba\x86y\x01\xe9J\xb2\x83\x85lE\xe5w\xb3\x90]Q\xa5\xae\x16\xb25\x9e\x1b\x84\xd9\xcbgg\x87\xcd%9\x89^\xbb^-\xfe\xe01\xd7c1\xea ^o\xc7\x9f\xcd-\xdd\x16-\x11\xf59N\xd9\x9c\xc5y\x18D\x19\xb5T\\\xa4oi\xea\xff\xb2\xf7\xef\xebm\x1b\xc9\xa28\xfa\xffz\x8a\x12fN\x06\x1c\x93\xb0(\xdf\x99(>\x89-\xef8c\xc7\xde\x96\x9d\xcc\xda\x1ao} \xd0$\x11\x83\x00\x02\x80\x944\x89\xdfe?\xcbz\xb2\xdf\xd7\xd5\xdd\xb8\xf6\x0d\x94l\xcb\x19c\xd6r(\xa0\x80\xbeUW\xd7\xbd\xe6\x98\x04\x06I\xfc\"6/\xeci\x0d\x8eu*I\xc8\xe2\xf9\xd9\x91\xc0\x9f\x14\xfc\x96\xfeSg\x98)\xba\x9d\xb9\x07\xdf\xf7\x0d/\x1e\xa1\x15\xe6Cj\x16\xe5\xc2\x82\xb8t9u\x80W\xc5\xdf;\xbaT\xa7\x9c\xad\x1fG![\xbff\x88\xbf\x08\x040\xf4\x0fsC\xe8;y\\/dK\x1dgT\x9a^\x99\xaf\x94?\x06\x07\xdc\x17\xdfm\xca\xd5\xc1\x18\xe8\xed\x16\x1a\x823\xd2\xb9\xbc\xacL\xca\x02\xbd\x0e\xd57\xe8P\xcb\xba\xca4\xe7Ft\x1e/\xab;\x0d\x9dj\xbd\xf5\xd0g\xa7\xff\xa5J\x9b\xc8\xde8\xd6\xb9\\mM\xc3\x14\xaaU\xd9Zj\x868\x86\xb3\x1d=\xbd\\'Z\xd3\x11F%\xc3\xcc9\xdd\xf8s\xfc\xb9\x1ci\xbf\x99\xf5?\xc9R}\xbcy\xf5l\x80{SRo\xd8\xea\x13o\xf2\x98\xe5F\xa9\x19\xd5~\xef\xea\x9f\x17\xd6\x1d}\x9d\xbe#\xac\x83\xd6\xfds\x1a\xb8\\\xd2\xd7\xab\xcei\x1b\xd4/s3F\x077\x88zm\xc7\xe0<\x89\xd3\xb3\xe13\xca6\x1e\xfa\"\xd6\x93\xb8\x87\x93\xf8\x10!5\x0e\\\x81i\xe7\x1b\x01*=\xb0~\"V\xe5:~\x82AB\x98\x01\xe5\xb4\x92\xb4\xb4\x13\xb2ij\xff\xcf\x068\xaf\xb57pe\xf9\x12;X\xf5\x19\xa3E\xa4\xf4\xe71\x15\x17\xa6\x9a\xf8y@UE\xf1\xaeL3\n\xa8\x1b\xa0r8\x11\xf2u\xa6\xdeDa\x7f>\x0dl\xb7\xb5\xb9\xc2 \xfd\xd2\x9f\xe0'/a\x83@\xfe\xd4JE\xfd\xb1\x11\xb0\xda*Z\x04\xcc\x9aV\x8d!\x08h\xe3=\xf9\xf9b\x9b\xa5\xb1b\x98i\xa3\x8dq\x96/}\x16\x18'\xc6r\x8a\xf94\xb4\x08\x87S6\x14\xd9\xda\xd4\xae\xa9d\xf8|(^\x81r\xafqR\x11 \xdb\xf3\xb9\x0bV\xbd6\xbf\xb8\x1bfiF\x98f\xdc\xbf@?B\xaeoi\xab\xe9\xb48\xf3\x8aA\x02B\xea\xf8\x95\x81=`i=\xb4M\xd7\x0e\x14W\xd9\xf0o\x1b\x92\x1b\xc6\xfc\xbf)\x08d~\xee\xafII\xf2\x02}\xe6)#\xc99E\xd4t\xaa9^|\xdce9\xbf\xfaJ\x8c\x19\xd9'\xc5\x96B\x1e\xd4\xdd;\xa3\x9f@f\xbc\x01'\x14\x8fZ>\xf5\xea\xe9\x0bk\xf642\x1cf\x15\xd8`\x02\xf3g=\xcd\xea\x89\xb3:\xc8,\xd8\xa6\x86\x9fA\x07\xbd\x0c\xda+\x86\xfa\x12\\\x1aB\xde*+\xc4\x87 m\xbd\xfduE{\xe9\xa3\xef\x93\x82YWl\xf6\n\x03\xfd\xb2_\xda\xfb\x85O\xe0n\x18\xcd,.W\xb5\xdfd\xf8\x7fl\xd3\xbdK\xec\x81=$\xfb\xa7\xf8\x8fe:W{-\x01W\xc2\xee\xb4\x92\x98\x9d\x9d\xe3 \xd3\xef\"\xe6\x9e\x0e\xcb^\x0df\xa5\xa1\xd1\x13\x12\xacS:]j\xe2\xa03y\xc1\x8a\x04\xef\xe6\xa9\xa2 \xb8\xb84\xadZEt1\x9cc^\xdfV\xe9\xc3\xe8\xdea9\xa2\x1c\xb8\x01s\xfc%\xba\x8a\xb7\x84\xfb\x8c\xd9PD\xaf0*(i\x08gpf\x06\xe6[\xa9\x9a\x19\xf3\x1b\xf5\xce ^\x9a \x1e\x19\xb6\x05p\xdd\xe4% 54\x89\xb5\xf5|\xed\xba\xd4\"\x9d\x8a\xb9OM\x0c\x8bJ]~\x170M\xc4.H\x8dTp\xe7Q\x9au\x94\xd0iO\xaf\x96\x03\xd6^r9\xbd(t\xdal\xea\xbfMM\x97\xf2\xb2\xd4\x15\x84$\xb5\xef\x18\x8e\xae\xc2\x03R5\xe0\xd0f\xb8\x1f\xcf\x03\xf2\x92\xf87<\xeb=\xb0\x859G\xc9H\xc7'eC\xda\xd6&\x887\x1e\xee\xbd\x0c\xf8\xba\x9e\xdb$\xc0\xff4}\xaf\xde\xd2v\xbf\x91\x15_\xb3\xfa\x97\x1d\x81Ej|\x18\x90\x1e\x1fx\xe7\xab\x14\xf9R(K\xc7\xddz\xcc*\xc7\xdd\xf0\n\x1cw{\xe5\x95\x94\x94\xa3\x94\x94W\"\xbb\x97Wj\xe3\x82i$\xc0GS\xd6n\xc3\xea%\x1b\\\x04\x8b\xe4\xb9\x112\xad\x1dq\xd0\x15O\x0d\x19\x0dq\xc1\xf1\xe1\x10R]\xe2\x92\x8d\x88\xf4\xac\\\x00\x15\x0en^\x10\x13?\xd7\xf8\x1f3\xc7\x82\x19\xe8Y2\xce]\xf9\xfa\x82\x1c\xc2\xd8\xcb\xe0\xe4h\xce\xbd\xb6\x02\x81\xc7#C\xdffU\xa4\xba\x16\x8c\xaf\x94\x96M\xad\x17T\x9b{6`S\xaa\xcd\x7fK\x9b|$\xe06\x8a\x91*\x11\xbc\xc5mZm3\xe1\x1covw\xcf\xd1q\x02\xb9H\x9doj\x8a`\x94\xc1/D\n\x019\x06E\x0bp\xb1\xcc\xf4d\xca==\x18K\xca\xcbJDIH\xce_,\xdctd\xf2\x97\x8b\xa0\xf72\xaf\xa0{\x92\xbe\xd5\xf8uXy\xd1C\xc3crx\x15\x1d qA`/g\x1e\xda\x8a\xf1\xc1\xb7t\n\x18\x84\xb9C\xa23\x9d\xcf\x0dv\xba\xa9\x9c\xc7\xf7\xb4\x89\x84\x94\xf5\x8148\xd8P\x04\\1\x0e\xb6\x91KOY0\xaa\xd5\x14\x9e\xe1\xcbsX\xa4cPE\xdf7\x16\xc9WO\x02\xe3\x98\xacF\xdf?\xe8\xd4\x1e\xe9\x89\xcdy\xc46\xaa\xd5y\xc4\xe6\xd3\xe6_\xfb\xe7\xca\xbf\xbe\xf2\xb2M\xb1r\x9d\x9c\x14Y\x9a\x14\x04\xed\xca\x87\xa8\xd3WP3E\xde|\xd6^ev\x1c\xd2\x1a\xba\x9c\xed\xd4\\\xdf\x95\xf8C\xcca\xcf\xf3y\xc8\xe0\xd8T\xb6^hS0\x87R\xa0d\xe9\xc0\xe1!\x92\xd1t\xc1\xa2X\xc4\xe7*C\xdd!\xaa\xff\x12\xfa\xc17\xaf\x9eV\xb2\x9e\x9bu\x03\xa5(A\xd9b.\x03Vr\xeb\x15 \xa3\x9c\x04\xe5\x9bZ\x9f\xd1\x13\xe8t\x0c+\xfe\xd1\xaf\x9c\xd1[\xf6\x93\x8bS\xa7\x95\x84\xe1\x8b\"9\xa6@\xb09\x8b\xe5\xd4\x19\x89\xba\x06\xa2y\x99Lp\xee \xcd\xe6q\x1a\xbc\xc3\x12\xeey\x1a\x9f\x9e\xceK]\x08c\xdbF\xc4\xff\x92B3\x0b\x11\xf1sI\\\x94\xb1\xde\x89\xa9\xce\xc9\xf5\xcc\xa1\x8aD_\x9a\x03\xe4Z\xd69\x19\xb3\x1f\x07X\x15\xd9\xbd\xf7y\x9c\x05\xd0\xd29\xad\x88\x1f\x92\\b\xf53\xed\x19\xbb\xe0\xc9F\x98\xa1\xa0=\xc0\x9b\xd4\x17\xb2\xce\x1b\xd9\xc1\xbb\x12L{\x81\xcc\xc9N\xea\xd1\x86\\d\xfc(\xc3e\xae\xe9\xa2I\xfb\xe1\x8e\xc1\x81u\xe1\xe8G\x1d\x1aGm8\xf3\xa1M\xa0%Y^\xc6;gr\xb1\xa9\xa7\x06=*\x06W\x9c\xdb\xa1X\xa5\x9b8\xac\x08\xe1\x9b,\xf4K\xdb|\xac6\x15\xcd\xeb$\x0e\x9e\xd0\xf9\xa0tI\xea?\xff\xf8\xa3 E\x0fq\x0e\x81?\xdbO\xd9\xf1\xcd\x9f\xf3?\xda\x10aTd\xb1\x7f\xc11\xeb\xb1P\x7f\xb07\xe4\x0f\xa5c\xf8\xdcR\xb2\x8a\xe9\xd4\xc3\x0eM\xca\x9a\xd6\xf0\x06C=T\xd5\x8e\xe5\x93\xac\x7f\xd3\xafx=\x0b3?T\xcax=\xc7\x07\xfc\xc8\x12\x98\xa2\x87\x0c\x98\xf3\x00\xba\\<\xdfPi8\x14\xe4\xe9!\xf8\xde\xbau\xebI\x9a\xbb\x9b1\x14#\x98\x81\xef\xe5\x9d\x9b\xfa\x86B\xa8\n(S\xa1{cL\xa9\xb0\xa2\xa7+\xcf@$\xd7\x974\xafm\xfd\xf9\xea\x10\xf1\xca\xf4\xc7cSE\x97u\xfdb\x92\x96\x8f\xd3\x00I\x12\x86\x87k\xdf[\xd6\xef\x11\x9b\xf4\x1d\x175<\xfa.\x1a\xc0\xe75x\xe3\x98\xd0\xber\xda\xb7{n-\xd2VlO\x1c\xca\x9f\x92\xa4\x9c`\xe4\xd8[JZ\xb6'\xce#~\x13\xa3\xc24y\x85\x80\xeb\x94\x12\xd7 ,\x16\xea\x9c\x81\x8a\x8d\xfb=\x0b\xcf\xd2\xber\x0c\x87]wm\xa3)\x1c,\x0enk_W\xe8p\xf9\x0c\xc3\xe2\xc8\xe8\xf5%.\xa4\x95z\xa7\\\xe0l=8\x98\xe3\xcc\xc1\x90\xf7\xed y\xcb\xa2\x15\xb5\xef\x9a\x92x<\xa2\xe24\x1e\x06\xc7\\\xe0\x96\x8b\x82`1iMn'\xd0E\xaa\x1c\x99f\x96\xd3\x0fm\xe2\xf6\xd1\x18V\xda\xf4\x06v\xcc\xd7\xed>\xf3\xf5\xe6\xd53-\xdf5\xd4)TD&\xd2-\xa0\x1e\x8f%\xa3\xb7\xd2\xa7Xh\x8e\xe7\x98\xe4[\x92\x83\xd8O\xda1a\xf0\xcc\xc0Q\xb1\xcf\x16\x13\xf6\xeeN#+\xe9~1\xafR\x99\xef\xd85\xb6\x1dw\xec[8\xa8\xd1 \x8d!H\xe3S\xd6d5\xeb\x13z\x8f\x1fk\xban8h$\xd4.\xd1\xd5\xf5\xc7\xca}\x9cv\xea1)\xfd(.\x0cy=J\x8c\xa4\xfdP\xab\xf8\xd1Vo\xe8\x92\x85cX_e(S\xd5\xfe& kfc\xa7\xd1G\x8d\xe0\xba7\x8d\xaf\x81S\xf9\xf8_1\xaa\xed\x84_K\xdd\xf4\xb5\xca\xf7\xb6\n\x8e\xc1\x0d<\x04\xe1\x86\xb8]\x95\x99\xae\x03\x18.4\x9f>7\x0e\x8e183\xb80\xb0\xc8\x0c\x8e\xa5'4\x04\x17m\xf2x\x06\x06\xe6\x9c\xf3\xa7\xda\xcc\x89\xf4j\xca+\xba\x98\xb1\xf7\xf5|<\xd2\xcc\x871\xb4\xb2\xea\xd7\xb1MS\x11=\x96\xe7\x97 k\x10|\xed\x0c\xe6\xe6\x06\xd5\xe1-\x97\xf0\x85\x97\xeb?C\xbc{\xdd\xf4\x9f+\xa5\xfe\x13\x9f\xf4\xb4\x96\x91x\"S\x80\xaed\x9a\xd1\x0d\x7f\xd0\xd3\x8c\x16\xfcA\xaf\x8d\x98?\xe8iF\x03\xfe\xa0\x97\x1dy!\x1a\xdf\x7f\xd0}\x94Q\xf1e%\xb4\xa7h}\xec@\x84\xa2\x83\x8a\x9aU\xab\x8f\xafO\xdd\xda\xda\xd6T\xa9\x94\xa5&*\x99\xfd\xac\x99B\xb9\xb0Q\xbcEm\xc5\x9bE\ne\xac\xd0\\\xc7]\xbc\xc9\xe3!\x96-\x9eU\xb9\xad\xce\x90\xcb\x19\xc2LG\xce`!z\xe9\x12o\x93\xc7.\xe6\xe5\x17;5N\x99\xa3\x00\x95\xe4\x99;\x87+\xd1\x14\xca\xe7*\xe5s\xd5\xd4\xe3\x8c\xdc\x91\xc7\x1d\x8f\xd2\xbc\xe7\xf3\x04`\x9d\xe3\x17\xc9|\x7f\xbaT\xba\x86f\x9b\xb3\xa6\xabd\n\x0f\xc1Y\x95eV\xccn\xdeL\x13*Q\n\xbf\x06/JoV\xef9 \xab\xaa\xd7K\x8a\xab\xb4\xb1\xc5\x0d\\\xa8\x15\xa6m\xcb\x9b\xd2\xc6\x16\x08z\xf9K\x14\xc7\xafH@\xa2-\xd2\xb6\xc2\xc2\xec\xa6\x94\xd3\x85\xe2}\xf8\x12\x81\x88;\xb2p\xac\xc7uB`\xdb\xa5\x02\xddr\x95\x03\x96K\x1eZ'\xf3\xb1o/\xa1\xec\xd4\xbc\"[\xa7\xd8\xa9t\xce\x1b\xba\xe3\xf6\xe4\xd3\xed\xab\x9e\x1a\xb1d\x99W\xf8t.\xffM\xde\xe41\xa3Bu\xb1\x83j\xf2TqF^\xb0\xc9s\x92\x94OXj\x08s\x85\x93-%I{\xcc\xf9\x03\x7f\xbb\x1b,4\x97f\x05\xff\xc6f\x0c\x18\x9f\x88~\x16{Q\xf1\x93\xff\x93\xbbB\xfd\xca\x8a)0\xc4K\x1b\xaf\x88\xa3\x80\xd0M\xb2\xd2U\xc9m\xf9dlzy\xc5|\x13\x9fDw\xc3F \x87\xeb\xa4\xd5:\xea\n\xba@=dU\xbf\xac\x12\x92\xb1\x9d]\xb5\x89\x89\xf5\x0c\xf5\xb5\x00\xb5 \xcb\x17\xf3_\xad\x12\x99\x95\xfeR\x9b-F\\\x9d\xdd\xa7\xcdB\xd3~\xa7\xca[\x93\x9a\xdf\xa8\xf7\x9f6\x8bC\x0b\xdc\xc2& \x8c\xe7\xe8\xae\xbei\xe9\xa1!,\xf0\xe5\xcf|L\xa3m|\x0d*\xb2\xc5\x8d\xc5\xe5*5:\xf1\x89+\xc5@M\x816\xcf\xa2\x82\x9e\x8b\xb4ez\x98&c\xc8u9g\xc4\xc5\xd1\x8f\xc7j\xba%\xaf\xa3\x85\xa5\xad2\x98\xc1bTi \xf3Q\xad\x16\xdc\xb9\xb0\xba\xb8XJ\xd1*3\xa4\x05\x9a\xd0\x8b\x9e\x1e/\xb1\xac\x90\x05\x96\xd0+\xcd\xac\xd0\x1b\xaarE\x169@\x01\x83\xb9\xe9JY\xa17T\xdb\xc7\x08\xaa\x91\x8c\xd8\xe3F>D%d\x13\x8a\"3\xa6\xb5\xfd\x06\xa6\xbaB\xde\xab[\x0d\xaf\x8c\x9fR\xa8\xc9\x17p\x856D \xce\xfe^]8\xe9R\x96mYy\xe6\xcf\xc9\xb2-\xad\xe1\x9b\xaaj\xf8F\xaa\x1a\xbe\xbe\xaa\x86\xefFU\xc3\xb7P\xd5\xf0\x8d{5|Y \xcf\x82K\x05m\xe8@\x04\xcb~\x16%~\x0d\\\xfb\xa7\xe4\xd8\xafi\x88\xe0\x10\xee\x9cq\xe6\x8c\x1bPC%\x02J\x0d\xc2\x8e\xb2`\x15\xc5aN4\x944\x1d\xc6\xa9GC\xb8t\xdf\x9aC\xdf\x0c\x90/\xb0p\xb2\x8e%_\xb0\xc38\x0d\x8e\xce3?)\xb4Q\x14\x19?\xb8I\xf6,J\xdeE\x89fFCQ\x04\xd8Y\xf8qAX\n\xfeL\x0dO\xb9\xf4\x0d\x96\xfd\x8c\xfd\x0c\x1dk\x95\xa0[\x06jSes\xcd@\x1f\xf3\x1e\xeb@\x97\x0c\xd4\x04V\x05\x164\xa1\x1aJ1\x9cb\xab\xb7\x15\xb5r\xc8\xe7yz\xa6\x19\xdcY\x14R\xd2\xe0\x1c\xec\xeb\xbccH\xb4\\\x95\x0cjpo7\x85>\x14\x88\xed\x08\\\xab\xbf\xc4\x14\xcf&\xd8\xe7 r8t\xa9\x9aw5\x9d<\x8f\xa3\xe4\xdd\x0f\x83>\xa6\"6:\xad\xa3\xb6\x86rT\xbc\xc8HB \xf6\x91j\x9er\xa3\xf9@\x92JC'xg\xe2)\x1a\xe6{\xce'BcX\xab\x9d\x16y\xba\xfe\xf1\xd8\xfd\xbd\x1b\xcd\x87\x1a\x0f\xa7\x9e\x94\xf7\xe3k\x97\xd0\xb4/\xd4g*\xa1>S \xf5\x99J\xa8\xcfTB}6,GS\xe6vc\x94\xa9\xe4\xeef:\x97\xf3\x05~\xed^sY\xb96@&\xecg\x1f_\xd8\xd7\x9b\xe9\xbe\x08\xfb\xe2\xfap\xc2\xbeP\xa4\xaa\xe1r\xcbT\x05)\x87\xc3@R\x0dc\xc9\xb4\x07\xe9r\x19\x13d1\xd5\xa0L\x82O\x93\xd79\x15\xf8\xf1\xb8T\x03o8\xf0#? Hl\x00.8\xf0\xd19 6\xba|\xfb\x0b\xa3\xe1.\x1b\xa0<\x08\xadU\x12\xabjq\x8cz\x8e\xed\x10s\xea\x1a\x81\xad2q/+P\x8b\xef^\xb0 \xf5\x8b[\xc6\xef\xce+P\x8b\xef\x9e\xb6\xdd\xce*\xc6J\xc3z`\xb8\xbd)w\x02\x15\x9f\xcf\xbc\x90d9 \xfcRW=\xe0\x1c!\xb98\xa4\x06;F0}n\x8bG\x08c\xcak\xf1\x0e\xa1R\x8dn\xe7;\x84\xd0*\xe0^\xf0\x8f\xf0\xe9\xd2\x95\x9c|\x89\xa0~\x1c\xa7g\xaf\xf3\x8b\xa7\xe5\x8b\x8d\x06\x83_\xb3y\x1b\x98-\xe49\xeb0\xff\xfa\x11\x13?\xd5\xe0O\x11\x9c\xb0\xbd\xf94y\x99\xa7\xcb\x9c\x14\x1a,\xf9\x15\x0e\xe1\x9d\xd7P\xea\xa8A\x7fB\xd0\xa6\xeeF\x0d\xfb\na1\xdd\xb7,\xa3\xb7\xb8\x1e#\xc6 %Q\x9ai\xb5@\xcf\xe0\x10\x1e3#_\x15\x02\xae\xd3\x8f\xbd\xa9\xe1\xb3<\x0d7\x81\x1e\xfc7\xee\x8f\x8c\xa9G\x9eEE9r\x1f\x8f\xe1\xc4iT\xd5\xd5\xf5\xee \x1c\xc2\xb6F\x9bc\x1c\xba{<\x86G\x9a\x97\xfe\xddQl9c\xf8n\x0c/4\xca\xab\xef\x9b\xbd<:/ \xeaI\x8b\x91\xfbX\xd3\xcc\xcf\xc8\x04\xd9\xcd\xda\x0f\x0c\xb6YKX\x0d\xfc\x0b\x03\xe6\xf8\xa6\x83\xfc\x91A\x06,w\x9d\x1a\xee\xbf\x19\x9c\x8d\xf2\xf5\x1f\x0c\xd4F\xf9\xfa\xbf\x18(\xc7G\x1d\xe4_\x19d\xe5\xd5\xc1\xb2,h_\xf9?\x9dW\x8e\xf4I^\xfe\xd9ma\xb3^\xfb\xb96\x17\xca\xfff\xaf\x98\x14\xc2\x84\xf2/!\xcf\xe9S\xe3\x86\xda\xa5\xf7\x19f\x8fe)d\xd1\xc4\xf9-\xec\x9b\xdc\x95\xd0\x9d~\xef\x19\xee+\x1e\x9a\x97{\xad\xec>,F\x87\x838\x9c{\xd3\xb9p\xe4\xe8\xe0R\xf43\xf1\x8c\xa1$\xb6\x16R\x10\x1e\x04\xb4\x7f't\xdfI\xd2\x84\x02\xd8\xe69\xb1\x12\xe6\x9b\xaa\xdb*\xe7c}2R\xf9\xf6\\\x06\xe2\xc0\x0dx\x047\xc0\x91\xe9x\xdbP\xea\xd5\x8e\xc2\x99F\x03\xfe\xefZ\x01\xaa\xd4\x80\xaa\xa6\xe0\x9fZ-\xb1\xc0[\x94ngp\xaa\xeea\x83S\xd5\xfa\x98\xb4}K4\xa7w\xab\x84\xd3Z\x0f\xd7\xf0\x9f\xd1\x1c\xf6\xb53\x84\xca!W=M\xffm\xa7x8\x1f:\xfdC0\xb0R\x8d\xab\xeb\xe2\xbf\x1f\xc3c\xba!\x1f\xb3-\xfe\xc7\x1f\xcc\xff\xe4\xf0\xf0\x10\x1e\xd7\xce(\xea\\\x13\x06?\xe8J\x15u\xeb \xd3\xd5S\x15z-\x03\x18\xbaU'\xee\xed\xe9TC\xe8d\x13\x10\xa7~\x18%\xcb\x89\x9fDk_c\x1f\x19\x8d\xe1H\x9bX\xc8`%\x91\xb5\x8d\xea\xcd\xd3$\xcd\xd7\xbe\"\x07\x10&x\xfa\xc5\xcf\x93(Y\xce\xe0qM\"Fc\xf8\xd5\"\xcf\xd1\xb0\xfe4\xd89}\xa9\xca\xab\xc6Bcf\x10M\x83\xff\xb01G\xfc\xaaX\xd4\xd1h\x0c?\xd1y\xfc \xc3=/\x91\xb6E6,\xc1\xf3N\xc24(v\x9f\xd1\x0f\x86YO\xa2$\x84u\x9a\x13\x08EF\x9f+^\xd8\xd6\x0c\x0c\x1f\xb91\xd0\xd5\xd8\xe6\xa99\xeb\xcceq\xeb\xa7\xa6\x18\xa4\xc23u\x1b\xff[\xd7\x86}\xb0\xac\xc5L\xc4\x91\xf6\x0bJ\x8b\xd6O\xda\xe8X\xf6\xb4\x91c\xa7yj\xa87\xd4\x0f\xbaa\xd7R\xc4\x0c~\xb3:\x85yA\x10;\xf1\xa3\xe2Ef\xf0X\x03\xc5+x\xff\x03\xdd%uj\xb8\xa6\xbaL\xeb\xaa\xdb\xd2\x95I\xeb]\x89\xab#\xb9\xcf\xe0\xb9\x86mi*\x12f\xf0R\x0d\xb9H\xa4Ev\xc4e\xcdP5\xb4d\xda\xecE-\x15\x996\x7fQ\xe6\x97\xab\xe7\xdc\xb1\x93q\xe1\x86nr\x17\xe4P\xb1\xe1*l|\xae\xc1\xc1\xbf\xeap\xd0z2\x98M\xfeX\x0d \x1cV5Ly\xda\x91\x1bgB\x03Q\x98\xe5H\xda~\xf5\xda\x16\x15b\x85;\x12\xda\x91\xe31T\x1f\xd1\xe9!\x96\x84\xbb\x83\x91\x90}l\x06s\xafh\xdd\xd1\xacs\xff\xe5\x0b\xafw\xd3\xf0>\x05\xf9\xd9\xcf#\x8a\xf0?3\xed;\xffH\xef\x89a\x18Mx6\x8ca_8Z,HPF[\">\x85\x9d\x11\xdf\xa9\x9e\xe2}3\xfe}\xf5\x15\xbc\xa4\xff\xbc\xc2\x7fLtq\xa7cV((T4Z\xd5\xd8\xff\xd2\x9eo\xec\xa33x\xf5aq\xdf\x96\x98\xf0H\x16\xa6!\x9b\xc1\x13\xc5\xcc\xd7S\x7f\x15S\xfc\xbcRu\xbc\xa4\x12\xf9\xbcL&\xcb<\xddd(ys\xfd\x95\x91\xb3{.\xdeW\xf5\xe8\x17+\xc9Y{Z\xd9\xce\xe20\x92|\xd9\xb5\xad\xec=3(\xacvJn\x9a\xaa\x1f\xb5(k9 \xf6C\xd3wz4\x86\xa7W\xb5\x97\x85 \x1aT\xc1dCw\xf3.\xcd)]'\xaaey\xa6\x19\xe0\xcf\xba\xd6*\xb5\xf1\x0c\x9e\xa9g\xbaJ\xea\xab\x89*\x11\xcc\x90(\xfb\xa0\x8d\xfd\xb0>\xb7[l\xc4Ul\x98\x86-N\x9b#\xd2\x1aK\xb9\xf5a\x06o\xcc@\xfc\x90\xda\x8a\x80\xbf\x97\xfc\xfe\x934w\x19C\xa59\xfc\xfb\x8c\xb4\x95\xce\xdf~\x1b\xa9A\xe4\x86\xad\x19\xbcV\xbf\x82\\\xac\x89\x9a\x10\xf4\xa0\xf8\xdet\xdc\xfe\x1f\x1d\x06\x93J\x17>\x83\xef\xad1\xce@2vq\x1bz\xb9\xc9\x89\xcce\xa8\xca|'w\x19j\x9c\x1c8)\xad\x87y\xb5\x99d\xcf\xf8\xa6\xec?\xaaQ\x85J\x8a\x0b\x8fY\xbc\xba>5\xcc6\xa1\xf3B\xfa\x12Z\xd4\x9e1\xa5\x17\xd2B\xee\x85\xb4\xa8\xbd\x90\xee5S\x19-4\xeeF_b\x8b\xfe\x03\xdd\x8d\xac\xfc~\x86\xc4\xfb\xe7\xf6\x0e-\xe9\x10\x87\x16\xe6\xa6\xd4\xb6\x13\xa9\xa1}K_\xaa\x0d\xd6\xd039\xa7\x14,\\\x9d\x91-5X\x80`QQ\x95=\xd5\xf0\x0d\x0b\x845\xb9\x9ed\x08\xa5s= Y\xd7V\xe9\xd9\xb1\xa9{+\xfe1\x0b\x17\x94-\x03\xcd\xa3e\x94\xf8\xf1\x0b\x9bW0\x12I8\xa2X\xbd\xb1\x84C\xc8\xcc\xb3z\x81K\xc4\xd5\x1d\xc1&\x8fJ\xadU{\xce\x12(Tu`\xab\xae|_j\x8d\xf9\xa7\x9d\xc4\x0b|:\x9f\x1b\x03\xbf\xcf\xe4/\xbe4\x04\x9a\xf3\x1a'?n\xd6\xd9\xeb\x14\x811;\xc4\x07\xb7.\xd7Z\x01\xd6O\xe8\xfc\x8d\x06b\x8d\x16\xb0\xae*(\x05\xd1\x08 \xa7\xba\x1e\n^P\xc5\xb9\xa9?{f\xaf\xa6\xd3\x05>v\x0c\xd0\x1a\xc3r\xcd\xe3\xc8\xe3\xc6ig\xc3\xab\x92\xfb\xba\xabcc\xafX\xd2\x83\xad\xa8\x99],\x8a\xedn\xe9\xdd\xd5\xc8\"{\xfen=\xab\x93\\D\x8a\x02\x04\xef\xc7 :Qg\xdc\xff\xea+\xb8\xf0\x82t\x93\x94\xae\xaeos\xbdY\xbc&\xb93\xd0d\xcc\x1a\x1e\xe3!N\xd4\x941\x94\x98\xef\x97JMT\"\x89r\xec[\xe1^\x982\x89 \x81\xae\x13\x06\x17\xae\xc2\x01\x05z\xacEu\xd7\xac\xb8\xd2V\xc8\xc9\xb4\x08{\x85B\x87!N\xa1\xbb\xcfL\"D\xb0\xb3\x08q=\x03\x19>i\xa6\xb2\x01\xc5\xa6?\xa32\xa3_\xc4\x04q\xed.&hK:\x9b\xb8\x8fK\x1d\x1b<\xb3\x8e\xf4\xdd\xf7c\x94P\xded\x19\xc9\x1f\xf9\x05\x91%W\xd9\x99P-\x86\x13\xaa\xfa\xbb\xe3\xcf\xa0\xc4\xf1g\xaa\xad\x10\x91S_\x94\x16\xff\xb1\xd4H\xcd\xc0\x95\x034\x11\x89Dc`\x14\xf5\xe9\xc6I\xac\xe2PR\x844\xc6\xa1D\x08\xa6\x8fC\xf1\x11F\x1b?\x82u\xf1\xed\x84\xf7\x82w\xecq\x9d\xc6\xc4\x18\xe1AO\xd8\xb2\x99G\xe4\xc3\x9f\x04y3'\x838\x0d\xe8<\x9d\x9e\xb6\x9d\x9d\xa5@\x83\xcd_\xdazUU\x02\x06\x9d\x02J$`\xd0\x98\xa2\xb2\x06\xdf\xca\x9ao\xfbO\xfbXy\x80J\xd8\x1b\x0d\x0e\xb2,\x0d\x91|\x84Wy\x04^7v\x99\x9e\xaa\xcd\x80\x078\xe4\xe5R\xfa\x87[D\xcf\x84\xfb\xb2\xd3-\xea\x96\xd0\x8f\xd8\xe9\";=\xa2\x8f\x7fz\xf8\x98\xc1\xa63J\xf5q\xb2\xad*\xca\xd7\xe6\xa6>\xe6$\xed\xd27b\xa5\xdb\xe1#\xaf\xd2\xb3\xee\xbe\xe6\x83M\x87j*\xa4\x0c\x9d,\x81\xcc\xfb\xf1\x95~\\Z\x9bS\xd7F\xb3\xb4i\x1d\xbb\xe2P^\xe3R\xfd\xc2\xf2\xa5*c\xbc\xaeC\xa2f*\xeb\x93\x1a\xacU\xe3T\x0d\x96[\xc0\xc8\xeb2\xaa\xcb~\xf6\x06\xe3<\x89H\x8cN\xe5\x1f\xb2\x114Q\xb3\xa2\xa1\xeafZECK\x8f$e~qL~\xc3\xec\xb7\xa6\xcc\xa0\xdbF\x8d\xa8f\x9d\x9f1\x1c(\x881=\xbb\xcb\x93}\x85\xb3!\xee\xe4\x93\xa9$ \xc8\xb0\xad\x12\xd5Q\x84\x0cUT\xa5\xdeT\xb8\x8a\x9e\xa3\xcb\xa9BAy\xfe\xb3\x1f\xcb\xf4<\x9d\x04\x96\xef\xdb\x05\x10\xdf\xcb\xcf\x04\xf6\x99\xebu&\xbcJ\xcf\x0c\xc7\xc2\xed\xe9\x9f\xe2X`\x03\xb59\x19(B\xc8\xcf\x04\xe2Q|\xe8?C\xa6\x14\x1eR\xa63\xfd\xf1\xb8\xfa\xe1\xa2\x92\x91+\x1a\x87\x9d\x14\xd6\x94\x88o]#1ap\x9d\xbd\x1a}&H\xdbG\xcc?Q\x02\x13\n\xf0\xe0\xee\xfe\x9f#g \n\x9f\x98\x949\x1a\xc3\xa6O\xca\x15\x82z\x1fp\x91\xe6\xe0\xd2\xaf\xd1 \xaf$p^Bn\x8c\x13\xceR\xff\x16\xa31N\xf4\xfe\xd7\x10\xc07P|\x0d\xc1\x8d\x1b#\x88O\x82\xb7\xcd7O\x02\xf5\xc1B\xb7v\xc4O\xb2\xbe\xb2\x00ei\xa3\xc2 \xf0\xe3\x98k\x0d\xc8\x18N\xe8\xbboE\x11\x87\x18O\xe1\xc8Cs\x85\x1fG\xff\xae\xa5\x07c\x19\x07zE\x1e\xa1\xe3\xed{?\xbfG\xadBz\x865y^\x936\xef\xab\xfa\x1a\xf3$\xaai\x00\xd7X\xe2\xbe\xa3\xdfc\x7f.\xa2\x98PN\x03S-\n\xef%\xaf|\x0b)Z\x0dY E\xac\xce\x9c\xc07\xacVa\n7 \x82o\x0f\x99;n\xc2\xe2\xbbqs\xf39}\xcc\xd6JV]u\xcc4\x19=E\x17\xdd}\x1fC[u\x95\xb5\xcf\x98\x9c\xbf\x8a\x96\xab\x98\xce9\xaf[I$\xc1P\x1d ]\xc6\xff\xf5\xbb\xf7&\x0b\xfd\x92\\\xaf\xfe}\x02e\xdfV\x1f\x90\xc1vV%h\xe87\x14\xa9\x88\x0f\x15\xc3\xb4:.,0\x86\xc4\xc4\xb9\"\x9f\xeaj!&A\x1a\xaa\xca2\x8eQ/v%\xed\x89\xa1Nx\xc5yY57q\xd5^\x1dt]\x9a\x14Z\xd5M\xe71\x07r\xcc\x96i'\xcb\xf5\xc9\x01YYN\xda\xb4\xe4\xc8\xd1\xf5\xfa\x97\x15!qU\x04KG\xd0\xd5_i\xcc\x19\x96=\x80uD\xbf\xa0\xae{\xfa\x9er\x00\xc6M\xd4W\xc3\x99Tpr\xa7\xd7\xe6N\"\x1e9\xcf\xd2\xbc,Z\xc7S\x9f\xbd\x85\x06\xe7\x99\x903\xf8>N\xe7\xee y+[\x83\xf2\"\xc3\x91ST\xa7\xfc@\xc4\x8ad\xdfL\x83\x92\x94\x93\xa2\xcc\x89\xbf\xeeH\xeb\x1d\xf6'ZT\xf5v\xf7\x0e\x0f\xe1,J\xc2\xf4\xccK\xfcm\xb4\xf4\xcb4\xf7\xd6\xc5\xb1\xbf%\xb4\x0f#\xddC7\xefsV$.\x88\x82k\xa3\x87\x1e\xff\xda\x9bW\xcf8\xc61\x0e\xfe\xcd\xabgn\xae\x91\xe9C\x9e\x0c\xa4\x8b\xa6\xbeL\xef\x1dyX/W\xb8\xb6\xc1!8I\x9aP|\x8e\xbcUN(G\x9c\xd2\xdf\x05)\xbf+\xcb<\x9aoJ\xe2V\x9b\xcfa\xb2N\xa3\x1cq\xcd\x00\xd13\xb3\xfb\x1ec$\x9cq\x15\xd3;\x1a\xd7\xdd\x9d\xa7\xe1\x05\xe5\xd9H\x12>ZEq\xe8F\xc8\xa6\x05t\xeb\xba=\xc0\x9c\xac\xd3-\xa9\x01\x1b\x93\x95\x93m\xfa\xae1Y\xa9\xea\xe8}/E\xc9\xeb L\xc9\x95\xbfR1+R\x89Y\xbeJ\xcc\xda\xa8\xc4\xacB%f\xc5\xfcAOb\nx\xca\xc7\xbe\x1cUKZYU\x12B\x98>+\xe0?\x81`\x95\x8f\xc1\x97\x0bV\xd1u\x14\xacr.Xml\x05\xabt\xa8`\x95{\"x\\\x84\xe1\xfc\xc2B\x04\xad\x84\x0e\xde\xd5\\T\x88\xac\xc3\x85\xbc\xa0\xf5QT\xa8\xba'\x02\x10M\x90\xd5k\xcc\xed\xe2-\xe5\x9f{\xad\xbcg]\x14\xf1T\x8f\x18\xfb\xf0\xfa\"#\xac\xd7V\xdd\xace#\xca~\xe4i\\|\x17\x04$+\x7f@\xf5\xaf\x89\x9f30})\xe6v2\xb0\x8f\x11\xba\xedY\xa5@\xf4\x11To\xa4\xdd \x8c\xceO\xa6\xac\x08\xbad\xea4EZ9\xd1\xd3\xe5\xb4d\xde{j\x00\xe1>\xbb\x91BH\xaa\x17\xbd\x1f3\xabs\xafp4\xdd\xad\x96\x82X!\x15\xc4|;A\xacX\xa5\x9b8\xacX\"ka\xc7\xb4/\x1a>M\xdd\xc0@\xe4NH\xff\xb6(\xbf\xcf\xde\xaab\xdb8x\xfdw\x1bN\x84\xd6q\xb0\xeaO9\x14n\xc6\x0e(\xbb\xd7\x86\x97\x07\xbc\xf1\x17\x15\x0f;-\xfa\xe5J4D\x7f\xb6\x9f2D\xe1\xcf\xd9\x1f}\xdch/\xffG\x92\x06\xf5$\xc1F^d\x1e\x19\xd5z\xe9)C\xd2\xc3\x03=yH,\xbdN65\xac!\xa5,\xf3\xd3\xb0\xcc\x13\x8bl\x841\xefm\xd2\xc6-5p\xc8\xdc\\\x06\xa6\x0d]U=\xd6G\xd5l\xf9\x11Zi\xed\x8e1\x89\xdf\xa34$#7\xd5x>\xac\xb1\x98\x8f\x13\xd4d\xd3T\xd1\xc6w\x9d8\xda\x12\xb1\x86\xa6\xca6~\x1d\xbbj\n\"\x91m\xf5\xaf\xbe\x92\xdd\x16Q\xa4\xb27f\xb5\x84\xf7\xb2\xf5D\xdd\xf8)\x1cB\xd1\xac\xf6\xc7\xa6rIJv\x82>b\xe7)\x95p\xc5\xb0\xe9\xacJ\xcd6\xe229\xee\x0c\xd1+T\x1b\xcc\x98\xd9\xe0J\x9a\xb3q\x01\x10\x971O\x16w\x05x\xd5\x88_n\xcf\xb5)q]\xec\xcfI]3\xc4\xe4\x08\xd5i\x0e8b\xa3\xcc\xad\xcb\xa6\xa5\xad\x16\xc3\x89\xab&(L\xb0\x97\\1\xa2\xe065\xc4\xa6\xde\x7f\xc5\x0c\xe6\x1a\xc0\xc6:\x89t\x17\xfc\xe5 \x8eQ\xbeJ#]\xc6\xabA\xc8Q\xe3b\x94\xe8\x92\"Df\xa5\x9a~E\xb5\xd5^\xea`i\xeb|\x94\x1a^\xae\x99y@\x93\x03\xaa\x93y@CP\x18\xf7\xd8a\x11\xcc\xbcd\x8fk\xd0\x1c'\x8a0}U\xfe\xa5\xe1\xdb\xd4B\xc9(\\k\x86b\x0e{o0=i\xbb\xe8\xa8\xc1\xf2\x1d\xba\xb4+\x8dS\xb8\xe1\x88K\xed\x8eS\xa1\xf0\x84\xde\xe39wU\xcd;\xf4 \xd7&\x03\xbc\xa2~\xd8\x04\xbb9\x8f\x1b@]j\xfe\xa1;\x18G\xc9;\xcd<=\xc3\xc7un\x07\xdd\x8c\xb5<\x9bR\xa5gS\xa9b\xa5\x81\xb3\xd3I\xdf\xc3\xa9T{8\x89\x0bYg\xa5\xa7\x93\xb8\xb0|\xc9\xc9\xd4\x00\x15\x027\x18F\xed\x0c\xcepx\x08)<\xac\xf1\xfc\x94'#A'_G\xce\xb8\x80\x99y\xb9\xd0\xad$\x08a\xc5P\x96\xb8\x8e:[\xb1\x1c':6\x15\xd0\x1d\xf8\xb1\xd0\xa6mQ\xafkh`\x91h#\x13\xa1\x8du\x1aZ\x8b\x90iH\x8cC\xaaO%M8/\x0c:I\x803\x07]u\xce\x8c\xa2\xc6\xe1\xa1.m30\xbe\xa4\xabK\x9aa\xd9\x0f\xa5\xaa\xc9\xdc\x15\x0e\xae\xe5\x87\xc0\xfeT\x85\xfeI\xad\x84U\x14\x85n\x15\x83\xde!\xa1K\x8d\xe7;$u\xe9'C\xeaGX\xd6\x99\x83\x98\x85\x98U\x8a\x1a\xb9'-\xfb\xcf\xaf\x85\xa4\x16\xa7\xea\xa0\xdf\x9b\xd6\x03\xf8\x1c2\xb9\x84*w\xacP\xe5\x8e\x15\xaa\xdc\xb1B\x95;V\xa8r\xc7\n\xa5\xe6\x8b\x98?\x91Z\x10\xdcP\xd8\n\xc2\xcaV\x80\xbf\xa6\xb7z\x05\xa4\x17R\x8b\x03\xaa\x07Te\xa5\xc3\x8fo\\X\xd9\x1a\x17\x88\xc4\xb6 C<\xb3hkjo);O)\x0e\x8d}\x914\xc1'+\xf2N%$n\x90\xba<2)\xb9\x12\xe6\xeb\xd3oF\xfd\ns%\x92\xd1m\xf9\x99\x8b*\xec\xe3\xd2/uJ\xeb\xbcO\xb2\xbbK/\xae\xf7h\xd82\n\xb4\x9a\x11\xc8\xcf\x9c\\\xd1Z\xef6\xfa{Q6\x84\xf4\xe8\xa5\xb8\xa4\xc3q\xfa\xac\x1d\xfd\x94\x02\xbf\xe1\n\xdd\x94\xaeF\xb3\xca\x08-Z\xe0RK\x1d*3\x9aP\xfeB\x0d\xc3\xac%\xe6\x02d\xccbb\xe1\x9a\x13\"\xa0Y\xaf\xb8B8\x9d\x12t\x8b\x10v\x9a\xdau\x0dk\xd0\xd4.\xab\xfeYhj/\xf8\x0cVx\xa4\x06\x9dW\xa0\xf6\xf6\xb1S8\x84\x95\x17%\x0b\x92c\xaeS\x8d\"\xe1\x0c\x0ea\xc9\xc5!5\xd4\x11\x1c\x82\xcf8u&\xe2h\x93\xfa\x9d\xd7\xd0\xe4\xdc_g\xb1>\x07\xe0q\x0d\xced%\x0d\xec#8\x84\xadU'\xdeqH\xe1P\xc5\xe5Q%\xfcw\x0c~\x9d\x86$>b\xbd\xd6\x81\xbf`\xe06%\x80^2\xd0*.\xd3TL\xe75\x83\xb7Tp?\x17\x9b\x16i\x97'\xa1Q\xf4\xc8\xbaPP\xf1\x05\xb8g\xee\xc8$/>\x15+\x84\xc5\xb2x\xc7\x9c1<\x7f;\xe6\x8a\xe7\xe7~6r\x7f\x7f\xdfe3\xba\xd7\xafp\x08O\xb9\xc4\x87\x88\xe9\xf4>\xa0\x16\xf1\xeaP?4M=ma\x98#\x94\xe0\x99W`m\xa0hq1r\xbb0T\xccf@KR\x1e\xe3M\xb6AF\xee\xaf\"\xec\xd70\x9b&A2J\x82x\x13\x92W\xc4\x0f_$\xf1E\x8b\xcb\xec^\xf4\xd0\xa3\xc7\xcd\xaf\xf0\x10\xcaJy\x95\xf0;\xa7U\x9fj\xc5V\xce\x9f\xb9\x8d\xcc\x89\xcd\x151\xf5]L\xfb[\xfaI\x85\xe6\x8d9T\xd1^\x9c\xba\xbe\xe8\x01k\xda\xf7V~Q\xad\x1d\x9d\xf2\x90g\xfb\xacnQ\xb9\x14\x07\x95T\x0b\xd2\x9b\xebd\x0c\xcfu\xf3(\x99C\xcdi\xc4\x80\x7f\xc9\xa3\x92hg\xfc\xbd\xde\xfcq\x8e\xbe\xcc\x94v\x9d[\x04\x8a\x89K\xb0\xc0\x94\x1d\xa2l/+&\xf5\xd7\xbf\xe6d\xe1\x08\x97.\xda\xae\x8a\xebQ\xe0;\xddu?Y8\xf05/a\xdcF\x0bTeo\x1a\x16\xff\xd6\xbc\x9a\xb1p\x0d3\xbe&\x16\xaey\xe5\xda\xb8\xb8\xe6\x95\xf2\x1893\xa4\xe0\xd0[{<5%V\xba\xa4YK\\\xc8t\xc9\xd9IqiMKw*\xcd]\xaeQ\xf2)\xe3\xfe\x9aW\xdb\xa4\xc2h\x9by\xf68[(\x8f\x19\x17\x97,v\xbc~V+-(J_\xd6^b\x1c\xeb\xf0q\n1A3\x06A\x05\xe4\x1b\x92\xa2\xf7\xf9\x18\xde\xed\x98\xdc`\x07M>8p\x03\xdc\x0ds#\xd7l,'\xf4K\x9f\xb9\x85+\x03\xff\xafN\xdd>D\xd7\x1f]\xa1\x9a\x7f\xb0n\x7f\xe7}-[\x8bn\xab\xa7\xa7z\x93\xa1\xaa\xf1\x17\xba\x86E\xd5\x1f_\x94)l\xd8&T\xa7\xc4\x18\xce\xcc\xbb\xcdj\xacL\x9dWQ\xf3\xe6\xd0\x1b6Y\xd3\xcet\x84@2\xf1Q\"\x11\xd6\xa8\x19\xcc5[o\xe84\xbe\xb60q\x1b8\x1e\xf5\x94\xb4\xec\xd7|-\x04#E9\x9b\xee-\xef\x1da\xc7(\x88\xc4\xd5\xc7\xe4\xb7^\xd2\xb9\xe6\xd51\xb1\xcb\xf4>\x8a\xf5\x1e\xc3\\\x9b\x83q\xed\xc7\xb5\x83\x81\xc3\x9d=\n\xd0E\xa1 \xe1\xa8^ar\xa43\x1a\x83\x03l\xe9\xbc\xda\x06Uq\x9b?i:\xf1\x9d\x16\xc5+K\x89u\x9a}MV\xfc\xa6Z^S{\xb1c\xa2\xd0\xd5^D>T\x88\x02L\xb5\xfd\"\x0fIN\xc2\x91\x9bhV\x94\x1fB3\xf8I\xb1p\xd5\xd4\x1di\xa6\xee\x91n\xea\xb8h;\x83#\xeb\x99\xd3\xf7e4\xae\x04\xfc+\xb5w\x0e0r\x1e\xc3C8\xf6\xcaT\xc6\x85v\xa2W\xba\x97\xe1\xc0}i\"T\xc8\xb5i\x14<\xf4JpP\x06 :B\xad\xfe\x11,\x17\x064\xa4p\xa4\xad\x87Yo\xdf\x9fR\xe0\xaa\x92j\x95{\x1f\xbc\x94\x05i\xa5\xb7 \xd5fCF \x85u\xe8\xf7\xf7]s\x89\xcc\x9a\xd7TL6T\xffm\x9b\xd0\xea\xbf\xf8\xcdke\x13Z)sG\xacTQ%+UT\xc9J\x15U\xb2RE\x95\xacTQ%+\xa5Mh%lB+\x8c\xc8\xbf-\xb5\x04\xb1g\xbd/W\xe6\xa0\xf6\xedP\xf4]\x91no\xf5\xf1\x0dE[[C\xd1\x97(\x94\x8e\xd1\xca\x14\x85\xa2\xb7\x88d~^\x90\x90oq\x85X\x85\x91\"\x1bt\xdd\x7f\xd9\x04\x1fd\xf2\x12!)\x9c\x1bSk3\x99\xff|\xa9\x16b)\x10S\x91@\x94\x14\xa5\x9f\x04$]\x00\x0b<4\xebC\x12\x1e,\xf9$\x8aQ=\xa52\x8f\x89+\xf1R\x16\xc6g\x91\xc3\xa0y\xe56\xe6\xb5\xe6\xd5] \xca\x0cobydn\xf3R\x9cD\xd5\xe31~\xca\x0f\xbf+^\x93\xf3\xd2\xd5L,\xd7\x1bZ\xf7\xbc\xd3\xe3\x92\xf2\x07\xac\xaa\xbbN\x03!C\xafO\x1b\xa4r\x95\xd9\x02PN\x90\xec\x15\xd7\xea\x88W\x07a\xec\x942@\xb9)\x95\xbd$b\x7f^\xa2\xabWc\xd5\xb4\xb4d\xd6\xc1g\x16YB\xad\xccu\xac^\xc9&\x97$T\x12\x17\xabR\xc2\xf9|5\x98_\x9b;Xz\x8d\x87\xf0\xfb{\xd0\xba\x0fo\x06d>-\xdav\xa3\xd6nT\xbf\x85\xf5A\x06X\xd5\xe8\xc1\\\xfb\xf2\xa1\xa6\x8b\x92\xcf\xc7~I\xb0\xbe\xe8\xebhMt\"\xf4\xba\x9a\x04\x8d4$\xc9\xf5\xd5\xbc(\xc5\xa7\xcb\x92\x8aL\x0d7\xffo\xc3\x87\xe9_\xad \xf6\x9b\x91W\x92\xa2t\x93\x11\x05\xf6O\x1c>#\x93\xc7Q\x91\xa5\x05f\xe6w\xde\xd2\xe3\xe3\xa6_\x96~\xb0\xa2\x07\xb5xI\x05.\xbe%4,\xa1\xdd\xb7\xa4\xe0\xbd~5\xb4G\xec[\xf4h\x82\xd7\xb9\x9f\x14\x0b\x92\xcb\xba\xd6|\xa3\xd75\xeb\xcfI\xdf\xd0(\x8f\xe9*8\xf4\x98u Jx\x9c\xb9\xe9$\xa4[\xf9\xa2\xca\xb1Q\x92\xf3\xf2\xe6\xaa\\\xc7\x16\xban\x0c\xce\xe9\x1e\xf0\xc2\xcaV%;(\xa5\xc9\x0ed\x17K\x80pa\x84\xed\xca?\xb2\xebT\x9f\x94`n\xf1\x8938\x84\x93\x0b\xca\xd0\x15\x9byQ\xe6n\xea\xc5~Q>MBr\xfeb\xe1:7\x9d\x11\xdc\x80\xe9h\x0c\xa7o\xbd_\xd3(q\x9d\x99n\x9b\x8a\x0b\xed\xfc*D\xd5l\x08=\x13\xd4\xc9\xfdpdZv\xe0K\x7f^\x99{\xc8y\x99\xfbA\xf9\x84\xe7oz\x92\xa7k\xde\x8fF7\x98W\xc4\xc8=2\x18\x84\xe8\x85!<\xb43\xcc\xeaG\xe7\xf3\xdc\xc0 i\x9fR\x1aTy]\xd6\x99+\xe8\xc7%\xb7yB\x8b\x17\xf9\x8b\x8c$\x1c3/eIq|\xa3\xc6\x16\xaa\xfa\xec\x06\x07\\\xd8\xa9\x06\x8a\xb88We3hw>\x863\xfd\xa4\x83q\xe2\x9bYf`\x11 #\xff\xb5\x9aM\x91\xcbc\x06g\x83\xc7\xa2|\x81\xb3\xdb\x14\xf1\x94\xe3`)u\xb8\xce\xa8\xfa2\xe7< $%\x96\xd6\x86\xf9\xa6\x84\x8bt\x93\xc3\xd7r/\xda\x99f\x96k\xda\xe7\x06'\x84\xa2\x81\xdbN~\xc8x\xd7\x9b\x14\xe8_7\xb3\xd8\x8f\x92\x9b\x8d\xd9\xff\xc8\x036\xf0k\xc2\x88\xa7\x181\xcc\xe0\xe6\xff\x8d\xd6\xfe\x92\xfc\xebf\x0b\x87\x12\x8f\xbb\xfd\x14\xaeSl\x97\x8e\xd6\xb0\xd1\xa4\xf9\x0e8\xa8Fv\xc0\xd1+\xdb\xd7K\xed!\x80\xf9\x9ed\x9a\xcb\xe6\xb5\xf6\xcf\x7f\x89\xc2r5\x03g\xba\xbf\xff\xff\x93c\" \xe5W7\x94\x073\x1d\xbb\xa8\xd0\xc8\xf0\xb9\xf37a\x94v\xe6\xce\xea\xb8P\x9f\x8d\xf4\x8bzC\x117G\xaa\x1d\xb1tA\xd1h\x1c\xd7O=\x9d\x11]\xado\x96\xacL\xb5\x89\xe8\xc48\xcc\x7f\x88n\x1f\x04O\x17P~\xfc\xbdQ\x9e\xcbtE\xe22o\x0d\xee\xe4\xf5-\xec\xc3C(lw\x80z\xf9\xad\xcd\x7f\x91:\x9c\xf1M\x92\x93 ]&\xd1\xbfIX\x99\x89p\x8e\xbf\x16\x81A\x94\x89\x10A\xee~\x81\xd4\xdd\xd3E\x8a~\xca\xd9/4\xa4\xf8\xd3M\xe4\x06K\x91@\x99\x8a)\xad\x8d\xf7Z\xb7\xa5\xe5\xa5q\xa4\xe1\xc5Vg,\xc0\xb0Tz\x9e*]\xab\xacm\x916UH\x98Yu'\xcb`\x95\xef\xd0}p\xf7\x8e\xc4\x88\xa7\xd7}\xd6\xbe\x9eY\x1c\x95\xeeM\xf7\x9b\x7f\xdd|x\xf2\x7f\xbf}{\xe3\xdb\xd1\xcd\xe5\xc8[DqIr\x0b\x0fK\xfe!\xc7\xa9\xb2\x0dEkY\"\xdc\x8e\xfa\xba\xdd\xdf\xc8\xb6\xbf7\xbf\xf9\xd7\xcd\x1b\xac\x9b\x9c\x11 \xda\x0f\xfb\xf6\x1f\xc6\xaf\xfe\xeb\xa6\xddw7\xb6\xdf\xb5\x9e@\xec\xc0\x9er\\\x80\xc8E0\xef\xf0^$~\xf8\xbdn\xd6\xf8!\xcf\x9d\xd9\xed\x850JuM|\xf0-Li\x13\x0d]Gm\xcb\x9b\xbe\x85\x87\xed?g\xf0\xbb\xe4\xdcg\xb1[\x82\x83\xed?G\xbd\xad'a\x89\xfb\xa01\x1c\xca\xf4\xa6\x01\x1c\xc2IGeSg\xb2\xa5\x7fu\xe2\xac\xe9x\x17c4\x07\xbb\x0b8\x042\x86\xd4]\xd8\xb8\x13\xf3uR)\xeau!]\xec\x14wK\xd6^\xe4\x96\x94uq\x1e\xc5i\x11%\xcb\xd7\xfe\xd2\x81\x19l\xf8\xdd\x17\x19I\xea\xbb>\xbf{L\xe2E\x1b\xdeyM\xe4\xb9\xbe\xe5\x01\x81\xed\xa3\xf7\xfdH\xe2\xba2\x86TeR\x8eLI\xeaX\xfdq\xa4\xe8\xbd\xe7\xad\x81R\x1e\xdf\xa7\x88\x15O&\xf2\x9e\xd2\xad\x95\xbb\xc9\x18b\x85\x92\x0fK\x89\xc3\x0d\x88\xfa\xef\xa3b\xb69\x83us7n\x8c\xa1\xd0\xd9Y(J\xa4'%L@\xe7\xbe\x1dVP\x07\nM\xa1|\xb8l\xb9\xf0\xef\x0c\xe7 ov\xbb\x1aV\x8f\x109\x1d\xac\x9c\x057 ds\x0f7 \xab~ET\xe8\xc4\x80\x05\xec\xcd\x18\xb0\xeb\xc6\xf0kh\xd0\xa6\x0eN\xb4\xc7\xc3\x81\x02o\x91\xe6G~\xb0\xb2\xdb\x1e\xd9 yK\xf7_\xf7\xe4\xa42jfw\xaa\xf0/\xed\xedu\xfc%F\\\xfb\xfb\xaf\xa6o\xe9%\x12\xb6\xde\xfc\xfb^\xdd\xc0\xdf!'\x19\xf1\xd1vB\x99\xbaoVe\x99\x15\xb3\x9b7\x97Q\xb9\xda\xcc\xbd ]\xdf\xfc5M\x8a`\x15G\xc9;\x92\x977[\xf0\xdf6\xbe\xd4\xfc\xe8\xa34\xbb\xc8\xa3\xe5\xaa\x047\x18\xc1\xc1\xfe\xf4\xf6\xe4`\x7fzg\x0c?\xa6 \x1cW\x1f\xf3\x9a\xef<\x8b\x02\x92\x14$\x84M\x12\x92\x1c\xca\x15\x81\xe7O_\x8b\xdbM\xd0\x9b\xd5od\x06X\xd4c3\xb3\x842\x7frw\xdeq\xe3\x08Ab\xaf\x12$\xc8\x08\xcaU\x9e\x9e\xa1\x9d\xe1\xf5EF\x8e\xf2<\xcd]\x87\x9cgL\xdd\xe6\x03\x7fI\x92\"y\x8a(]\x8e*^\xa3\x0fr\xd0\x05\x81\x1b]0\xe1\xa9@\xc4\xc1\xf4w(\xfb\x1f\xca\x19\xf7A\xa9~\xc3\xce\x98\x8fX\x16\xf4\xfe\xc4@S\x9d\x97Vg\xde!\xc5\x1b\xde\x97\xca\x1e\xb1O\xb1\xa9\xfd*z\xc7|\x8d\xa5\x00\xaa\x97\xd1\x0d\xe3[\x98~=\xa2''\x0b]qS\xb8q\x88F\xf8\x12\xbe\xfd\xf6\x10\xa6c:\xc4\xc3\xee\x18E\x8b\xf4P\xe2o\xb4\x1a\x1f\x86\xed5cxw:2\xe1\x82\xc2\xbb)w\xc9\xc8+\xd3g\xe9\x99\xa8D;\xac\x0f\x1f\xdd\x99\xed3,\xfe\xba\xa82\x1b\xd0_\xf7F\x7f\x8e\x82\xaf\xdb/\x05f\xd4\x05f\x84\x17\xfd\x80h8\x81\xe0\xb9\xaa\x8a\xf6\xa8\xe2\xa8\x8e\xceKM1\xef\xb4[\xb2;U\x97\xecN?\xbeZ\x88 t\x9d\xb1\x98-\x8b\xe6z\xddReh>t\xb7Jy\xa7\xd3Sr^\x92\xa4\xe8\x1d\xf6\xef\x99\xe7\xd4\x0c\x9c1\xf0\xa3)1\xd7\xda\x8e\xae\x1bB=e\x9ecG\xeb\xac\xbc0\x94\x89\xef\xc5\xd4\x8a*\xf1\x98S\xb5~'\x12\xfa\xc9\x88\xeb'\xafU\xc5x\xd5\xc8m\xf0\x10\xb1B\x85\x88Q\xc1\xbf(9\xea\x98\xf9S}\x02\xfb\xfc\x0b\x8f\xa3\x02)\x9d\x14\xa1\xf9\xb9\x8f4\x0f{\x8d\xda-\xf4\xf6\xbb\x0c\xaew\xf4\xa9-\xd4\xa7\xad\x9c\"\x0e\x9d\x96\xe9r\xa9\x11>B\xdesY\xfa\xe7\x9e\xeb\x86\xba\xbfQ\x92mJi#\xcc\x04\xee\x04+\x12\xbc\x9b\xa7\xe7\x12MY\xa3\x0b\xfd\x87\xf8\x1e\x1e!\xa8t\x90(tj^\xc9\xac\x9c\x8c\\Q\xc1\xda\xe3\x1f6\x1e\xb7\xa318\xc7$ \x01'\x95mL\xa7\xe7#\xf4Y\x95\xe8\xff\xa49\xa1\xe5&\x93Pj2Q\x94\x93T\xa4\x88\xbeu\xd0\xcb\x0b\xf0%\x17\xb4\xdc\xb0ag\xd4\xb0\xcd\x05-v\xe0.f\x82\xa1\xeeG_}\xd5\xfa[-F$&\x1bD\xc3\x02\x90TC\x18\xb9\x89'$\xc618\xcc9\x03\xad\xcb\x88\x13\xcc\xbaLD^\xc2\x84\xd5PB\x91\xbfOG\x9a\x96\x14\xebCK\\\xdbai\xb2\xad\x94\xc8y\xad\xc2W\x03\xa5\xd6\x9af\x1fS\x1aX\xc9\xb4\x9b\x1a\x94\x8a\xc4\xda\x05IxT6\xce\x15.\x04N\x1e\xe5\xe4\xdct\x0c\xfe\x186*S\x10\xe6\xf3\xe6\xd5*X\xcdA\x8b\x8c\x05\xc2\x00c\x9ci\xc6KX\xea\xf6\x13\x10u M\xd3\xc8\xca\xb5WHg\\\x18\xb5r\"\x19C\xae\x98\xdbF\xf4\"\x96\xf0`k!\x0e\xb3\xaf\xbe\x02\x07\xb5Y\xb8\xdf\xd2z\xa1t\xfa$\xc1\x9a\xe9\xa2\x96\x01\xcf\xc3\xa88>\xf3\x97K\x92\x1f\xa0N\xd6\x87\xaa\x8d\xf3I\x9d\xf9\xf6\x8f?\xd8]L\xcf\xcbi\x11\x8f\xed\xad\xefW w\xabT\x8aj\x88\xc67f\xd8\x0b\x9e=\xea\xab\xaf\xc0m\xf4A\xd1\x83\xddZ\xaa+`\xef \x07\xb0\x1e}tY8h\xb2Y\xcfI\xfe\x9a\xeb\xc7F\xae\xaf\x88\x93\xeb{q\xc90\xdd\x1d}\x9c|\xedU\x12\x86_\xa28~E\x02\x12m\x91;\x91\xd5\xdc\xb7\xce\xc5Ps\xea\x9fxw\x99R\x88G\x97\xda\x83Hd\xa2\x02 \x1b\xee\x84\x1cf*3\x9a\xcd\xeeJ\xab\xed\xe4F\xad|\xd4#q\xa8\x07,%\xf5h\xc4Q=\xd9\xac\x91w\xf5\x81\xe5b\x88:\xf7u\xad \x17\xcd\xc6{53lJoP\x18\x86\xd2\xd84\x1b\x8c\x03\xa1\xff\x9d\x893#'\xbfm\xa2\x9c\x84\x8cT\xe1\xae\xf2\xd9\x19L\xf72\xba\x89x\x8b(/J\xb7\xb3\x01\xb1\x90e\xc1?+jZ\xdam\xc7bTe\xd1\xee\xee\xb4\xfe\x86lo<\x99\x18\xf4\x01\xbc\x05\xec\xce+\xc3q\x9fX\xee\x8f|@V\x8e\xb4\x865\x98\xcb#.?sm\xaf\x9e\xd7 Z{\xfe\xa6%\xaa\x0b\x95\xb7\x1e#\xad\xe9M`Mo\xc2\xea\xb3\xe6\n\x0f\x85\x91\xde`\x95\x07cj\x11\xafX\xa5gGB\xdde(\xef\xc0\xa0\x1f\xa5\xebu\x9a\xd8\xbcs\x81^\xd9\xce\x8fE\x9a\xb0\xcc\xe7O\xd2|m*)\x9b\xbb\xcc\x98\xfc=\x0b\xaaQ\xc2\x9e\n\xc7\n\xc6n\xa8\x01\xcf\xe0\xb0\xc9\xa2\x9c\x9a\x0b\x98\xceM\xf6\xac\xb6\xc1\xc9`\x15Y$Zk6\xd4\xf6#\x83\x95)\xa8\xec3\x85W\x15S\x10\xd8\xea\x06\x06\xbbP\xd0\xf4\x8f\xa2\x9fh\xa4\xf3\xc1{\xf4\x135\xcd$E\xd9\xc8\\hot\x92\x91I\xbbwk\xf3\x93\xa1\xf4X\xc3\xc2\xa3\xc9\x05\x04\x83\x8b\xb65\x8dL\x81\x12R\x97\xe1\xe4\x88\xe1\xafm\x0d\x8ds\x06nSC\xe3\xb8\xb13\xb8\"\xddT&\xa4 \xde\x94!MEC\n-\x93\x12P\x89^\xfd\x81\xef\xea]\xb9H\xf3\xb5\xaf\xed\xe5\x0b8\x04\xf4\x81^!7Rv\x18\x11\xed\x86x \x87\xf0\x82\xbdP\x1a\x10\xf45%\x00\xb47\x8f\xfd\xd2wL5\xf8\x9eS\xe8'\x15t\x94\xd4\xa1\xe5\xea\x97\x9e\xd6\xc3\xae\x19\x0e5\xf8\xaf\xa2\xf3(\x0cD%Y\x17T\x16\xc0\x81t\xab\xc95\xaf\x9f\xe0\x10\xde\xc1Cx\xd7\xe5\xa1\x1cM$\xe7+8\xc4\xc0GW\xd4\xa2\xe8\x12\xf0\x91[Vy{\x95_y\x0c\x87\xb0n~e\xe0\xfb\xcf,\x12Y\xbd\xb1\x80\xf9\xcd\x02\xe6 \x1c\xc2\xdeT\xab)h0z\xcc\xe9\xfeY\x8dOl=:\xec\xe03:v\xda\xc1gM\xbew\x8c\xfd\xe1\xb7\x84(\x87\x86\xe37\xf5\xf7\x04h\xe3koh\x9bo\xea\xf0e\xda\x03\xec\xf5~\x1b\x8e\xf5\xed\xb7\xfa[U\x1b\xe3f\xccB\xd9\x15G\xb1\x02FWL\xd6z\xa4\xe8\xf3\xf6\xb3\xdc\xfbH\x17&\xa8\xb0\x99\xd9\xba$4\xdf\x8c\x12\xa7\xe5\xde }\xe9\ns\xf8\x0fq&\xba\nC\xffSx\xd82#\xd2\x06\xa1\xa2\x070\xeb=T\xf6\xa6=\xb9\xf8au\xc6\x00VF]\xddC\xabT\x0dA\x1ac\xbe\x10\xdaS\xf5\xd9\xa7\xea\xaf\xf3?\xff\xef\xefN\xc3\x8f\xee*f\xb39Y\x9a:\xe9cx9\x86_Q\x0fu\xe2\xc0\x0d\xf8\x15n\x80\xf3\xd6\x19\xc3w\x18\xc2\xb7\xf3\xac\xb5z\x92\xa7\xd9\x84\x9fg\xca)p\xffJ\x1b\x1d\x833\xd2o\xb5\x1d\xa7 $YN\x02\xbfT\xad\xcf\xfbq}\x96\xd6\xdb\xbf\xf1\x16\xc6\x846\xfe\xfep\xab\x15i\x9c\xe4\\g\xdcb\xdbq\xba\xc6\xb0\xa4}~%\x94\xe3\xaf\xae4G\xfa\xb1\x89\x9dgnW\x14o&\x14\x83\x0c\xeeR\xe7\xff\xb0H\xa9~\xfe\xb3\x1f\xeb\xcb\xb0\xc8g\xa8N\xa0\xbf\xa63\xf2X\xcc\xc8\xe3\xff\xf8\x19\xb9\xc2\x1a+;8wV\xdb\xa9\xe1\xe2\xa9!\xca\xe7Zz\xcc\xeb\x9f\xc8\xbei\xc2\x8a\xbd3\xd4\x0b\xc3\x1f\x7f\xc0\xde\x13\xb3$\xab\xed\x87\xca\xf9\x85\xb2+\xea\xb5\x14\xbdw\xbe\x89\xbe\xfdn\xebG1\xa6\xe2@V\xb4\xf8\xe6f\xf4-=\xe6\xe0\x06\xbc\xb1\x88\x8eo^\xc2|\xaa\xc1\x8f\xda7\x8f\x07\xf5\x8eU\xc9\xcd\xde\x8fZ3\xd5\xe0\x94~\xfb0s&\xd82\xbbi\xe3*A6i\x8d9\xfbM9\x98\xd7t,{\xcf\xb5'Z+\xcb\x13\xc6\xdc\xce\x0cY\xed*)\x07\xcb\xebP\x94\x8a\xcc\xd3\xa3\xad$o\xd0uX\xebM\xb8N\xf3'5\x84`\xabf\xf0T\x0d\xd4\xd8Z\xf2\xedVK\x9d\x8c\xd5\xa2\x14\x0f&\xd0p\xb9m\x83\xcfXx\xbd%\xef\xbb\xabV\x84\xd0\xc5+fB\xccc\x7f\xea\x1a\x12\xf5\\^(\x11\x087\xc3\x0b\x0d\xc5:\xd2-\xab\xf5\xba\xd5\x0e\x96\xdd\xba\x88\x06\xa4\xe0\x0e\xd9\x9a\xacVvZ\x1f{\x8d\x8f\x98\xb3\x8e\xd6A\xb3*\xa2\xf6\x8d<\x89\xa5\x84H\xefX\x01G\x816M\x1d\x8en\x9a\x84K\xda\xac\xa9\xc9\xa9\xec\xe0\xc7\xa4,\xa3d\xf9$\xcd\xdd\xa0'g4\x183\xcdD\xd4>k3\xf8\x89\xb96PY\xf5'\xe4U\xd4\xaf %\xa7~\xf6\xae\xca\x89\xf9\xfa\x97R T\xaeT\x81\xca\x95*P\xb9R\x05*W\xaa`\x98+U\xe0\x16\x8d\x8e\x06jO\xe2\xe0\xe3\xfb?-l\xfd\x9f\xbe\x04\x98\x0b@\xfb\x00\xf38\n\xde}j\x87\x17k?$R[?4goevS\xc30\xcb\xe0\x1aU\xferma\xe2m\xfd8\xe2\x85\x1e\xfcu\xe1\x9e\xa4c\xf0\x91\x02UO\xbe'\x8b4'\xfcp\x12\x00\xa8\xb7\xe3\xb3\xe4\xa5 \x7f\xca|::7\xdd\xd1\x18\x12\x8f\xf0?4\xc7\x82\x18\xb4\xf6\x04\xce\xf0\xf4\xd5\x9c\xa3kn\xe1\xe8\xfb\xec\x02\x12*\x837\xda\xcb<\x0d7\xc1\xb0\xb8\xfe\xca\xdb\x8f\x8d\\\x92r\x80\x7f\x94\x19\xc9O\x04 \xae^\xf5\x1a\xeb\xf8\xdb?i,\xbf)\xf6y\xce\xa2\xabme\x93y\x99\x00G)\x10\xe1G\xfc\xd8f\xa9\xa6\xae\xdb\xb1\x8d\x19X\xee\xab\xb2\xc6H+\xa0I\xd3\xc9\xf8\xaat2\x1bU:\x99B\x95N&\xe6\x0f\xe4\x15\xd0Z\xb9c\xaeY\xc6\x98\xfeG\x84\x1e\xfa/\x0f\x1e<\x90 \xe9\"M\xcac\xa6\xcfv\xa2\xd2\x8f\xa3\xa0\x1b\xa2\xd3\xfa34\xd2'\x03\xe3\x00m\x1a!)\x83\xd6\xab\xbb\xa4\xf6\x93\xee\x94\x1fc\xc72\x03\xaf\x18\x02#\xff\xdb\xe9\xd1\x8e\xa5\x9b\xc0L\xb9`\x00\xf5\x82\x81\xfeEP\xb1\x08\xc62@\xc0\x19\x04:\xac\xb6\x17\xd1\xc8u\xc4\xd6V\xf9\x05C#\x94\x06\x9ae\xe1wVyC\x87\xd0\xf2\xfe\xeb\xe39\x01\xf46&C>\x06\x90\xb7yz\xaaI\xca\x00\x9c>\xff\xc0\xcb\xa9\xea\xe3\xe4\x8dI\x06@\xde\x85\xdd\x86;$\xd3\xc0\xd0.M\xf2\xf4l\xd7^\xed\xd2\\\x90\xc6\xfa\x05\xb8l\x92\x02\xd8\xb1\xddV6\x82\x8f\xdf<\xf3\x1a\x1a\x90\x05\xa1\xf4HR\xe6\x17\xb2\x12\xb9&\xdd\xb1\xf0\x01\xee\xc8?d\x0c\x07\x06\xbf%\x10\xee\xbb'\xfb\x9ax\x10q\xa1\x0b\xef\xc9\xd4\xa2\xda\xcf\x9e$\x1f\x83\x1b\x8d\xaa<\x81\xeaL\xd5\xe2\x12N\xbc\x91\xd7\xf1\x19\x7f;\x12N\xb4\x1dOr\xee=\x02\xb3\xc6S\xa3G\x89\xb86\xb2\xa6Z\x0e\xec\xfa\xee\x9a\xd8W\x8b\xbd\x0c\xe2HJ\xb5`\x97\xf0\x0f\x10\xd7P|\x06\xd6lz \x13\x94\xb8vl:\x92(\xa3?]o|^Fb\xa39H\x13\x9b\xf6)\x97\x80\xb6CGx\xcb\x991\x95\xbe\x83\xa6D\x83\x97\xa0\x80\xe5\xdcb\xa6\x1f\x94F\xfdX\xc3t\x93CHS\xbd\x83\x94c\xeb\x88?x\xcbP\x82\xba)\n\x85x\xf7\xba\x89B\x9fT\x83\x19\xc8\x04\x1e* \xb9\x81\x10xP\xdc\xf93\xa8/\x1b\xfc\xbeDK\xd9g\xf9m#5m$\x90k\xaa/\x19\"m0I\x83\x84Q\x99\xe6F\x0d#SF\x92<\xb7P\\2md\xec_\xa4\x9b\xd2\x02\xbf\xb3p\xb9#\xcc \x884\xdcH\x18\xe55\xf8\xf3\xd5\x07\x84\xcaL\x04\x82gv\x8a\x8c\x04\xe6\xe1\x84W9\x9c+\xeb<\xf3\x0b\x93#\xc8h\xa7tj\xb6\xfc\xfc\xa2\xcdL\xeb\x93\xa7C+\xcc\x19gA>\x05\x0c?u\xc7;\x9e\x95\xa5\xe1h\x14\xec}\xd9<\xa2\x94V\xea\x9d\xf6jo\x9f\xaa\x8f\x9f\xf7c,Mgh\x86\xe9\x90\xf4\xa7\x87\xd031\x7f\x1fVg\xaf\xe9+\xcd\x99\x0fx\x08+\xb7\x03\xc5\x1c\xc3\x1a\xae_\x02\x16Co\xc4\xcd\xcc/W\xf8\xbe\xb2\x1f\xc5\xda\x8f\xe3F-F\xbf\x84\xee\xeb\x0d\x7fW\xf5gt\xce\xebFw\xff\xb3UT\x92\xe3\xcc\x0f\x98k;\x99\xe0\n\xabw\x95U\x15Gi\xaa\x01>\xb05)\n\x7fI\xb4\x07\x8b\x16]\x8cC\xc2\x8a\xa0\x93\x90\x04)3\x91;3p\xb0\x12\x8aah\xc1&/\xd0\xdc\x94\xa5QR*\xb9\x1f\xd9\xd8\xb0\xb6\xb5\x8e\xe6i\xaa(W\x07\x7f\xe2\xcd\xa3$t\x19:\xe4R\xbb\xb6\xf3\xe3f\x9dA\x99\x02\x1d\n\xc5\x96\xbc\xd6U\x88\x1fm\xb24\xd4\x04\xb6\x13m\x91C\xe5\xbc\x8c\x8f\x92ZtwJ\x8e%h\x9fEE\xe9E\x05\xfd\x8f\xdb\xd9\x0c\xf6\x9bI\xb2\x97\xb8\x9f\xb0\xc7v\xd5%>\xc4\xd2\x804\xc8!\xfa\xe3&\xe8\xe5\x91c\xcc\xa4\xdd\xa7\xd3\xa4Z\xc6\xd6\xe7v\xde\x19\x9f\x90\x90Z\x13I\x0c\x0fB\xc4\xfd\xc8$\xcd~3\xff\x99 \xd5\x95\xd2\xa86\xd6Z\xd1\xab\xf6+\x06\xda%\xd3\xd6\xad\x94\xda:\x17\xd3k9\xce\x88W\xa4t\xc0\xb1\xb1\x1d \x11\xfcd\xff\xadW\xa6o\xe8va\xf5\x8a\xe0\x06\x10\xaf\x88\xa3\x80\xb8\xd3N\xc7\x04-\x81^\x1d10\xa7\xccm\xf2\xa4-\xa51\xfb\xc2\x17\xbd.\xbf,\xf5\xbaA\x95\xbb\xefO\xa3\xe1\xfd\xe2\xa0jQ\x01\xe9\x12>\x87\xe2\x13u\x12O\xdc\n\xd7\xd0\x93\xb0\xca\x92\xf58\n\x9f\xa7\x9bD\x16Td\xab$\xaf\x95\xe3\xcdl\x1fE\x95\xce\xa837\n\xf0*?R\x7f\xb2\xda\xf3!;J>`\xea/\xd2\x1bT\xfbN\x9d\xe6\xa9s\xbf*\x9d\xcf+)0\x9dH\x13G\xa4\xc3\xbf\xc4\xf8?\x81\xb9\xa39\x04\x93\xb5\xa3\xe2\"M\xa6\x0e\xec\xaeV%\xddv\xb3\xda\x89\x89\x82^\xc8&\x8edR^dD\xb0\xb7\xc8f\xba ?\xfe\xa5\x9f\xd1\xe9\x11\x0b4\xd6\xec\xd4\x03s\xcd\xf4\x9c\xf5J\xab\xf7\xd5\xc4\x85\xa9\x06SZp6\xe22\xe9fR\xe6C`\xa5\x953\xe8\xdb\xf8\xa05\x81\x9bR\x8fm\x80\xaeE}\xc7\xda\xe9z\xa5\xdbB\xcf\x98I\x12@\x8fzU\xa9\xf9\x08\x93^~\x93\xe6\x16cI\xb5co\x91\xa7\xeb\x1f\x8fG\xee\x89C\x0f\xb5(@.\xff\xe6\xafE\x9a8o\x1b\x9c\xe3\xf8\xday:\xd3\x1e\xbd\x10!\x06\xcf\xa2\xe4\x9d&5\xfcug\x10\x13\xf7\xb6* \xfdg\xc9\x18^\x05?\x98H\xf9\xc1\xa8\xe2\x07\x93\x11\xe3|\xf6\xbf\x86\x0d|\x03\xc9\xd7\xb0\xa1\xfc`t\xb2i\xf3\x83\x1b ?(\xf8\xcd\x0f\xc5\x08F#M\x12i\xcc\xb2\xf8\xda_\xa2\x05\x17u1\xa7\x8d\x1bLx\xa5\xccn\xa1X,\xb8B\xe6\xad\xd9\xb2\xc5i\xaf3:5\x98\xb1\x96\xc7\x003\xfd)\xf2F\xb7\x87\xa8\xe6G\xe87^d\xd7\xb9\x87\x9f\x80c\x1a\x14\xadf\xed\xf4\x91\x0fq\xfaH\x07\xa4\xcad eK\x7f\xb9$aE\xb8\x0b]\xc6G\xcc\\lv 11\x0f\xf6\x8aB;\xee*\xdd\x92|\x1b\x913S\x8d\xc1\x17\x1c\xceA\xa1p\xb0\xf56\xad\xad\xb7U(\x9d6\xaa\x1e\xf8$\x9f4z\xe8/\x0bg\x0c\xa5\xc1Y\x98y\xcf\x08\xa7\x92\x08\x1dI\x8c\xb6\xe2\x9dye\xa86M\xd5OT\xc2*_\xb8\x84\x9f\x05\xec\xe4\xb6\x00\xf5(sF\x1d\xe8\x9cl\xd4\xee\n\x00=;F\xf7jbPL\xd9\x95\xe6\"\xe9}\xd3\x85\xef\xaa3A\xa7\x87\x1b\x0e\xf3\xa2S\xcd\x89o\x9a\x90\xda\xef\xc1\xe0\x93j\xf4}\x00\xd6\xc3t\x00\xab\x0f-\x0bN\x992\x86PG\x06\xc4U\xa7\xeb7\xc32b\xb36d\xb0\x15\x17\xf33\x8b, \xe9N1$G\x05\xce\xde%\x0d/\xad\xc6\x06\x1e\xc3\xc6\xd29}g_\x0b\x10\x1b\xcc\xa2\xa7\xc6\xf8[q\x898\\C\nSzE\xe1\x0c\xd2*\x19\x93\xc5\x0bt\x8b%Z/\x9c&\xe4\x8b\xec\xa9\x19u\x9b\xc0/s\xb2\x88\xce\xb1\xb0]\xbd\x0c\xc6\xb7W9Y\xcc\xc0\xf9K\xf5\x12\x8e\xc6\xa2\xd9\x8a\xde0\xda\xa1'\x1a\xb6\xfe\xdbR\xb0&\x08&\xca\x8f\xfeM\xe0\x1bVUDM1o5\x0c\xfa?\xa5u\x9cv\x01L*\x0b!J01\xc9\x1eHm&\xad;\x03\xe5[\x83SI_\xa4\xb3\x12D\xa4\x04\xc7Z\xe4\x10\xd2\xc6\xae^\xc9\xcd\xfa1\x1a\xbe?i$.H\xbcS\xfe\x077VQ!\xb0=\xaf\xff%\xf9\xc4\xe5\xf9}\xde\xea\xc7\xe5S\xf964\xb1\xa8\xed\xed*'\x91\xcc\xc3\x98\x8fb\xe4\x9e$\xc8\xdc\xc0\x1e{[V\xe4\xbf=\xab\xd7\x8a\x81\xd7\x1d8I#\xd7\x83\x89Y\xc7\xa1\x9b\x98tJ\xcev\xe2\x9fc\x8fnE\xdd\x99\xc3(\xa5\xe6\x0c1\x9a\x99\x81\x87J\xffB\xa2\xe5\xaa\x9cAN\xb9\x9dy\x1a\xb3,\xa4I\x9a\xaf}m\xfc\x9ez\xec\xb2\xe4\x00j\xf0\x96wl\x9c\x06\xef\xaad\x04\x94e\x1b\xee\x05l%z\x08\x9f\x0b;\xe9\x83\xce\xca$\xf6\xe7$\xc6\xf3HQ#|\x0cI\xdbT\xbc\xb3/\x03(\xdbW'\x1f\xb4\xb0=\xd8\x1c\x1b\xff\x05\xd7B\xcb\xf84Y\xa4o\xf2\x18\x8f'\xfa\xfb{\xbf /\xfdr\xa5Q8JS+\xa4\xaa\xd4\n\x91*\xb5\x82\xafJ\xad\xb0Q\xa5V(T\xa9\x15\xe2Vj\x05\xb4C\xb7\x01\xea\xdc\x0b\xdcR=\xdd\xbf\x16\xa9\x17zsn\xc5\x11h\xdc(\xbeD%5\xe1\x86\x9eY\xab\xb4\xd0\xe8x\xd8\xa95\xe7\x8b\xb5\xd3q3(\x16\x84\xb64\xd9\xe4jR\xe4\x9c\x00E\x1dx\xf3\xea\x19\x96\xc1-\xd1g\xc1\x81\xb7\xbb$\x80\xd11\xb6vn\xd1\x06\x0c\x85O\x8c\xa5\xd0\x9b\x05\xb8\x12l\x053\xc6\xc2\x00\xac\x85\x81\x98\x0b\x15\xf6\x86~i\x90\x89\x93\x01\x1aM\x00h:\x9e\xf3\x94\x9c\x7f\xfc\x01N\xb9\"\x10\x92-\x89\xe9\xc9c\x905\xd3\xfa\x0b\x14\x93-\x14|\x1c\x9a\xac\xfd\xc8\x08\xefc\xf2<\x87\xb2p\x16\xf1\x1fV\x8cL\xaa\x15/mX\x1e\xa3\x86\x8aq\x94.\x96\xf5*\xfc$*\xa3\x7f\x937y\x99%r\x90\xfb\xbb\x9d8\xc5\x14\x9e\x945\xd4\xb1\xf3L\xb5\xb9\xc9c\x1d\x10\xb3\xd3\x08\xee\xc4\xe4\xe5^\xa2\x0c\xa9\x83bR[S\xca\xd3A\xc7\xcc\xea\x83L\xee\x15x\xcdc\xee\x98\xbc\xcaV\xa8\xa6\xe1\xb1\x8e\x86\xd3\xdeh\xf99\xe4\x984\x829c\x085\x06\xbc\x9a\x19\xd4\x9cZ\xcd9\xd4\xba\x91\xb6\xcfA\x85\xa3\x8d\xfa\xa4\xb8\x949\xb9y8\xb0\xda\xfe\xd7\xedp(T\x87C\xa1:\x1c\n\xd5\xe1P\xa8\x0e\x87\x82\x1d\x0e2\x92_||\x92\xaf\xd7\xa0\x7f!\xf9\xe2\xb2%\xf9\xc2/v\x97 Z\xc6\x1cXo\xa1\xf8Zn\xa1\xeb\xc1_\xf5\xf7\xd6\x17v\xea\xcf\xb2\xb7v\xd6/4u\x0b\x8b4Ugp\xfa\x8f;\xf7\xae\xc7\xa6\x157\xffDB\xd1\x97\x94B\xda\x94BO0\x9f9K\xff`4\xe5\x03\x9fO\x1ed\xd7\xc8 $\x17\x06\"i\\\xf4&\x0b\xfd\x92\xb0\x86e\xc6\xdbO\x9e{\xe8\xd2d\xf2\x03K\x9d\x83\x82\xae\xa5\x96\xfdG\xa9\xd6\x90B\xe9\x8e\x13\xa7~\x18%K\x96\xd5\xb8\xf4\xf8\x9f\xc7\xa5_n\xb4B\"\xc5[g\xe1G1 \x07\xbf\x8bn\x85^\xb0\xc9s\x92\x94\x1cC\x0c\xd2\xeb\xef\xef\xb5\x82(\xba\xde\xb9\x1b\x0f\x0b\xea\xd1\x9e\xe5$tF\xdc\xdb\xb0y\xff/\xbe\xefk\xb3\xa07%W\xfa/\x8e\x0dmw{S\xfe\xbb\xaa\x1a\x7f5\x07$\x8e\x1f\xebU\xfaQ\xb2CN\xfa|XK rf\xaa'|\x9d\xce\xa3\x98\xcc`z0\xb4/N\x94d\x1b\xfbTCut$\x9f\x05\xfe\xba\xf2\xe5,\xf6\x03\xb2J\xe3\x90\xe43p\x18\xea\xc0\xfc\x02J\x7f\xa9y\xab\xbc\xc8\xd0\xbeE\xceu\xdf\xee%*j\x12M\xf5k\xd5\xc1_c\x8aS\xe6\x1b\xe2T\xd8\xe28\xa0U<\x84U\x81qs\x14\x94\xdcn\xf6\x81\x13x_O^*S\xf1R\x99\x8a\x97\xcaT\xbcT\xa6\xe2\xa5\xb2a%\xc53\xca\x15\xb4\xeeb`L\xa6\x89\x9cY\xe0\xc7\xa6\xfbR.,\xfb\xf8\\X\x08\x87\xf0\x84\xb7\xef!\xebAwO\xbb\xcf\xfa@\x1a\xe8\x84\xd7v\xf0\xa4yYse\xc0{\xa7\xe6\x96\xec8%\x11iK\xfb\xa4Wmn\x19|\xc4B\xa3K\xbf$\xd2\n\xae\xe2\x8a\x8a\xa30*\xbfO\xcfg\xb075\x12\x0bGI\xe4#\xc3.\x86+a\x80`P\x02F\x18\xc0\x13\x81H\x95\xc3\xd8?\xacq]4\xa7\xbef\x96\xac\xcdc\xaa\xd3dx\xb6E\x90\x8cD\x9boB;\x14U\xa2\xb7\xa1#\xf8d\xfel\x8c\xcf\x14\xe7\xde\xa34)6k]\xfeD\xa8\x9c\xd62?\xf7\xd7z@\xe6\xb5\x16\x15\xbcf\xb6\x1e8\x1a\xc2\x1eC\xe5\xb7\x96\xf9\xe5\xea\xb9E\x9a\x8e\xcd\x003\x0ep\n\xbfq\x9d\xefYE\x1c\x0dk\n\x9c\x82o\\\xe759/\xbf\xcb\x89o\x02\xcf\x18\xf8*Z\xae\xe2h\xb9*\x1f\xa5\xa1\xd1\x81,d\xef4R\xf0\x99\xde@\xef\xed\x08\x8bg\xe2Z\x91\x92\xe4\xbfD8[\xfe\xf7\x17OC\x92\x94Qy\xe1\xfa\xdc\xe7<\x1fyu\xd9\x94\xc2\x19s\xd3\xf7\xb3\xa8(Gn\xf7\xc8\xea^[,\xa7\xd9\xe8\x1c\xdb*\xae\xcf?\x9a\x93\xdf6\xa4(\x1f\xd9\xf7~\xddBb\xfai\xc4\xccN*Wq[\xf8,\xc8\xde\x98\xd5\x8c\x0c%\n\xd5\x03}\xfbK\xd1>\x12~=\xec\x05\x1c\xc2\x92\x89\xc7z\xc09\x02V\x07\x85\xd1[\xed\xca\xaa6\xcf\xd3\xf0b\x82X`\xf0zpB\xbf\xf4\x19\xe4\x04c6f\x907#8\xec\xdf\x8e\x92\xfa\xdd(\xd1\xd5\xfc\x1a\xc3\x9c.k\xaa\xa9\xae\xb9\xd8m\xb0\xa7\xa7\xc8\xf0\xc3\x0dpW\x0d\xeb\xa3\x03Q\xb2\xf5\xe3\x88e\x070\x0d\x8a\x93\xdf\x0b\x03\xadk\x8b\x0e+? c\xf2\x82\xdfT\x8f\x9d\xee\xbc\x0b:z\xd5\xc8\x8d\xce@\xaa\x91\x13\xab\n\xa3bp\x9a\x1ej\xca\xae\xee\x8e\x86\x13\x96\x91U_P[\x87\x11\x97i\x9b\x84Q\xa9mX\xd5h1\xa0\xc19\xa6\xa0(\x13\x08\xfc$ 1H\xd6\x86u\x04D%\xb50*\xd5PF\xeck\xa4\xa9(\xd3\xe52&O\x05\x99\xd1\xef\xbc\x87\xe0<\xc2\x1ebG\xe8+u\xd5\x02\xcd\xd2\xb3\x0c\x0e\xa6\xf9X\x95\xeb\xf8 \xd6q\xd8i\xbe\xdb\xf1N\xceKq\x8c\x89L\xb4\xc0\xca\x92\xa9?`\xf4U\xe3\xf8\xbf\xd5Oo;\xf1\xad\x89\xeb\xa9(\x81\xc1\xf9Z\x81\x9d\xad\xe4\xcb\x9a}\xa9L\xea\xd4\xbb\xab\xf0.k\xc7\x9c\xd4\x87\xd1\xaay\\\xf6D\x1eq|\n\xdf8m\x02\xe0\xf6\x04\xe0\xf8\xba\xef\xfd\xfe\xbe+\xbfW\xf3\x17\xca\x1f<\xaaz\x10V\xcf\xdf\xb7\x95\x03\xdb\xa6x\xda\xe5\x97\x9b\x98y\x05\x89\xd9\xfdY\xcdLDU\xde\x10T/\xa5B\xbd\xa4\xd0\x1cQ6\xf9\xe6\xf9:\xbe\x19y%)J*\xceJ\xe1(\x83\x8c\xcbf\x02D\xab\x08<\x84\x84\xc7\x80\xd0\x9e\x9e\x9e\xafYu\xb0\xe6M\x99\xe7P\xb4\x00\x97w~\xef\xf0\x10\n\x9db=\x86C\xd8C\x8e\x0f\x93\x17\xfe\xfe\x9e\x8e\xb2\x903M\xc4+HyLY5W'\x1c\xe1fW\xd4\xb0\x1e\x8d\x9b9\xf1\xf5\x9eH\xc5?\xd7\xb1V\xa1\xd7P\x06(\x12\x9cK\x94u@\xe2\x82\xe0\xdc\xb6\x92\xf3\x17x\x0c\xb8\x0e\xce\xb1\xaa[\xfa.i\xbb\x83L\x88\xacEMc\xda\xcf\xb5)\x0d\x17\xf8\xd97\xad7\x14\xd1I\xafXvK\xb7\xe3R\xae$J\xbcE\xe2E\xc9\x82\xe4\xc7X\xe2\x7f\xe4\xe6<\xdaF\x9dg\x8d\xbe\xb7\xa0h|\x8c=\x16/\xa6\xa8\xefT\xcc\x07+\xb0\xf0K\x1e\x95\xe4E\x12_H\xf3]*\xe6EL{kf\x14\n3\xa1\xf7Lj\x19B=~\n\xf4\xcf\xb5\xa44\x99q\xaf\xf0}\xa2\x90\x90\x0d\x8bOw\xd1i]bc\x0c\xa9|\xdc\xa7C\x06\xee\x92N\xed\x0e\xf8\xe3\x0f\x08G\x0c^\xfa\xf96\x03>\x14\xedl\xe8p\xde%\x98\x89\x82`\xa6\x1d\n\xac\x82\xa3\x84=\xa7Bl\xcb\xe0\xea\x95y\xb4vYA6\xbd!\xb6\xb1\x85\x95ek9\x99\xe8\xc7\xba(\xb0\xb3\xc3J\xea\x8eUh\xa8\xa6k\x0c3+\xd9\xf8;v\x8aURc\xbe\x14^\xc2\xfc\xa8\x0c\xc9\xef\xe5\x96\x8e\xeb\xe9J\x7f\xdd+\x10\xd0\x1f\x0f\xee\xdf\x1a\xfd9\x8a\x10\xfc\xf9\x1c\xc2\x189|\x92\x06\x9bK\x96 \xe2$\x88\x15\x94\xa1\x1cB\x98\x068\x0e\x8f\x9c\x93\xe0Q\xba^\xfbI\xe8:A\x9a]\x98Sd\xc9\xa8\xd4\x07\xf3\xcc\xf0\xb8\x12R\xcd\xb4\x95\x9ck\x88\xeb9%W\xe0\xfd\xae\x0e\xce\xac\x8bK:\x8fX\xee&\xd3\x17\xd5T\xb2]\xbf'\xa3\xd2dQ\xaa\xb3\xcb+\xdb)\xc9y\xe9\xe7D](\x11P\x14CTj)\xbb\xf0\x8ezrs\xe2\x87\x8c7b\xb6q5dk$tZ\xd4\xa0V\x89A[\xc52/\x91\x0bT\xb0E\xf2)\xfd\xa0\xe6\xf7\xebP0\xa7\x7f(m\xe8\xa14\x95\x9dJ\xf4\xc9\xf4\xbe\xecX\xa2O\x1eLUqlj\n$\xbc\xd1N$\xa5\x08(\xe3&\xab?U\xd9|\\gE\xfc\x90\xe4EW$\xa5\xe2h\xe9e\x9bb\xe52T\xc3\x84\x9d\xec\xef\xc9?\x9d\xb1x\x9d\xe5\xd1\xc5\x18N\xfe\xf8o\xce\xdf\xb0zf\x9d\xa1\x08n\xc0\xdf\x9c\xbf\x8dx|\xf4\x06M\x12*V\x93\x9e\xaa{\xfbrTC\xb1Wa@\x0e$9C\xc5U\xe6\x17\x8a\x8dP94.\xc6h{\xea\x9c\x1b\xdd)\xf2HR\xe6\x11)\xa8\x90\x04{.\x16\xba\xa1\xc7i\xe6%\xe4\xbctG#/L\x132\xfa\x9a\x8f\xc2d\x8e\xc4L`6\xd6\x91\x15\xefZ\xe3\xc8\x0d\xc7p`R\xcfS\x9e\xedd\xdfP\xa1b\x8dPS\x89#\xa6\xb8(\x12\xad\x1b\xab\xff\x038\xdd\xd5\xde\xc2\x0dpf\x98?m\xcdW[N\x0b\xfa\x84\x00\x02\xbf\x0cV\xa0>Yc\x86\x11\xb8\xc2}{\xc1{XD\x89\x1f\xc7\xaa\x15V\xaf=\xbd\x98\x12%\xf3\xf8\xa1\xd5\xf8\xed*\x06`h\x0e\xf8\xd6\x89GP\xae\xf2\xf4\x8c\xbb\x07u/\xc9<\xfc\x97\xfa/\xfaA\x8e\x8a\xf34\xbc\x90\xa5\xd6\xa1 \xcez\x13\x97Q\xe6\xe7\xe5\xcdE\x9a\xaf'\xa1_\xfa\xcc\xd1\nG\xe6\xbc|q\xfc\x9a\xfd\xdd\xdd\xbb\x1aNa\xa9\xd9\x8f\xc0-|:\xa7\x8e\xb9f_\x82q}\xaa\xfdy:\xc6\x8c\x1c\xf2\xfd\xc9&\x057\xe7\xc51\xf9\x8d\xefN\xdas\xf7\x14\x0e\xe1\xac\xbb;\x97\xc6\xdd |\xf4G\xfd\x8dw\xca7\xacq\xfb\x01\xcf\xf5qd\xdc\x82\xc0\xb7\xe1\x91v\x1b\x02\x9e\x08|\x0f>q0h>J\x8a\xd2O\x02\x92.j\xae\xdb{\x12\xa1\xb0\xd0\xda\xa0\xe7t\x83\x1e\xfe\xffq\x83z\x89\xbf&\xf4\xef\xaf\xcb\x8b\x8c\x1c\xb2{\xf4'\xdf\xb9(P\xf7\xde5\xeem\x90\xe25X\xedq\x10\x98\xb4?F\x8c\x91\xdb\x05m6\x9f\x1e\x9f\xe8\xb5\x87\xc1\xfcg\x8d=\x7f\xa6\xdf\xf3`\xd94\xf0}x!\xf6\xfe|\xe8\xabe\x0f\x1b\x94\xb7#E\xb5 \x84\x97\x13t\x07uo\xfe\xeb_\xc9\xcd\xe5\x18\x1c\xa7\xab\xd8\xe3\xe3/e\xe5\xac\xdb\x1c\x8d\xcf\xb9\x93[\x8aJz\x9b\x8f'\xc4^7F\xefK\xcc\xca\x97\x98\x95O\x11\xb32 Z%B\x95c\xb0\"k\xab\x9a\xd7\x0dp\xab\xcf\x0b\xf1#29\xd5 c\xa0.K\x1b\xb3\x072\xbeD\xc1/\xa0#\\U_\xb0\x1e\x19\xe2J~\x0dCiZ>\x98\x97\xad\xe3-Q\xde\x148\x01\n\xeb\x1f305\xd6\xff\x9aV\xf0n\xba\xa7\xb1\xd0\x17\x8e\x82H\x9b\xf8\x10\xebr\xdd*p\xcc\xa3\xdb\x1b\xb3x\xfd\xf2c\xff\x00\xca7\xbd\xd2\xad\xea\xbc~_\x91\xf64\xec\xa6\x993;\xae\xd4N+\xbcW\xc3\x95h\xc6\x94\xa3M\x1d\x17o\xc5T\x0e\xf2\x98wF[\x89\xc5\\\xe7[Q\x8c\xdb\xa8\xf6R\x16\x8a\xe1d\x16E\x92\x01u\xfcL\xebdY\xb2\x9b\xf7\xce\xa0Z`\x85\xbd\x95 \xb6%\xbbM[jw\x05\xdf\xf5\x8c\xaf\xf9\xc2\xf7} \xbe\xef\xcfg`\xfa\x14gF\xcd\"\x99\xce\x0d\xcb\xb0\x82|@\x90\x00s\xb1\xa8\xc2\x17\xf91\xac\xd1\x96D\xf8\x02'\xf6\xe6\xd8\xd8\x82\x04\x9b<*/\x1e\xd3}\x1d\x95\xa6Z\xc7t+\xe5\xc6x\xdf\x98A\xf9\x9br\x95\xe6\xd1\xbf\xc9\xf7%\xa5\xb0{\xdd@\xb6\xe6\x15\xb0W\xc4Qx\x05\xf60\x8c\xd4\xe5\xc5&\xff\xf8\x03\xfd\x9d\xae\xc4\xea\xc5\xbax\x890\xda\xcd\xb0\x96\x8a+\x89\xa3m\xce\x86z\"\x02m\xd7\x9a\\\x91>\x84\x94u\\\x9b\xdf\xaa\xb1\xad\xd4\xc6\xae\xcaAX\xb7z<~\xbaJq\xf5\x1f\x9b\xeb\xea\x93zo\xc8\xe3T\x03\xb7ht4P\x1f\xad\xd7\xd9wC\x15Xj\xad6\xd9~\xf8\x80\xd2\x88\xfbP\x89*\xf4\xa1\xc9\x87\n\x1a\xf94\xd2\xe45\xbe\xcchD\xfb\x9e+n\xac\xd3\x90\xc4\x942\x8da\x8f\x07\xaaz\xe4<\xf3\x93\x90\x84#\xa1\xea0\xb8\xc6\n\xf8Y\xff\x13\n\n\xd0\xdf\xc3\xf2\xe9\xdd\x98\xb4&\x18iW\xb5&\x87\x89\x11&\x10S\xc8\xe3\xc8\x94\x1a*S\xb8n=ZE\x9f\xba-\xcd F\x99[\xac\xfeK\xee$\xd8\x86\xeaOI7\x9a\xf7\xc3\xf0^6\x11\xbc\x1f\x8e\x0d[E!9&\xf1\xe2Er\x84\xd3j\xe2\xc5\xf4+\x0d\x15\x1bV\xa1\xb5B\xe7C\xf7D\xd2\x89\x07\xac\xf6F\xdes\x0c\x85!\x1a\x90\x0f\xad\xfd\x11s\x80N\xf0\xf5\x94T\xa3\x19\xb4cw\xd8\xaa\xb6\xf3\xf0 \xb8z\xd4\x82\x98p\x08\x991\x956P\x98|\xaa\xe8\xcd\xfe\xfc\xb2U\xe8b\xae.\xdcl\x88F'\xc1\x0c \xea\xf2\xb6\x0d\xb5\xde*\x8a\xc3\x9c$\x943\xfa(M\xebB\x0d\xcd\x0d\xc9\xc2\xcc\xaasM\xc3Q\xdaxi\x05\x9b\xbc@\xa5[\x96F\x892_\x1c\xf4\xb0\xb7\xba\xcb$\xe7?\xed\xe0v\x1fX\xab\x92\x04%\xaa\x1368\x8c\x8b\x95\xed\x12\x1eP\xe4\xd4\xc7\xa0\"|\x17S\xf6\xcb\xbf Ar\x985a\xbb\x87\xa7\x91J\xf5\x85\x02\x990\xb0h\x1d\xd1\x92\xe8\xb5\xee\xc1\xee\xfc\xeey\xde\xfb\x0e\x89k\xb0C\x1d\xaf\x0f$O\\\xf8i=\x10GO\x9b(v\xdc \xbb\x14\x87~\xbf\x1e\xd2\xf83\xf0\xf9\xbb\x96*\xc11\xfb\xa10\xdc_g\xe5\xe0\xe7!\xc1\xf8A\x19m\xc9k\x7f>\xc8VZ\x99aC\xbf\xf4\x0bR\xa2G\x8e\xfc\xc8\xb6\x92Q\xaa^\xa8\xd5\x12\xbd\xdb\x97\x13JP\x13\x98,\xa2\xa5\x02\x8a\x89%\x86\xc0\xce\x00\x13QW\xb9\x86\x9fS\n\xfc\n\xf9\xaa(Y*E\x18G\xc4\xef#\x8b\x18\xa0k\x1b\x12\xef\xc6\x0d\x97~\xba\x02\xb4HS\xd4\x98\xc1\x98R\xf9\xaa\x8d\x99\xc4\x83\xefc\x0b/W\xc9j7\xb2\xce\xb0-^\xffIg\xafq8\xb5\xe0ly\xef\xc6XG\xee\xc4\xd1\x90\xefG%Y#\x9fY\xd3\x9a\xc3\xc3ff\x9d\xc6\xd9\xf2\x10\x1c\xbe\xb3x^\x96\xc1}\xd3\x07\xadt\xba\x16G\xc9;U\x860\xa8\x92\xd9\xf0$8\x8e9\x9dJ[~\xa8\x86\xa5\x1aDD\xc7{\x14F%`\x8c)\xcb\xbe\xc1\x1a\xe1wX\x154\x8dqd\xd7\xa5\xe0\xe7\xc8\xf5Z\x08\xda\xb3\x88'\xe7i5n\xbbBlTW\xb6>l\xc7\xd6\xb9P\xcc\xb1Y<\x92\xcb\x8c\xe8_}\x05\xe9\x18\x8c\xcb\xa0\xa9\x84\xa65\x071b\xab\xad\x94\xd2.M\xa2\xa1\xf55 \xd5\xa6;h\x1d\x06\xda\xc4'\xa4\xa6\x993\xd0\x14\xb3\x14\x14Y\x97\xef\xb4\xf7\xc0(1~\xdef\xa4\x05\x15\xb1z\x12S\xca\x9f\xf4\xa4\xb2H\xbc\"\x13\xbe\x162\xa9l\xc3\x1f\xf4\xda(\xf8\x83\x9eT\x16K\x0dL(\xfe\xb8qS,W\x1b\x98\x16\x1f_<\xcbl\xc53\xbd\xcfn>\x06\xbf\x7f\x92wy\xdfk\xe3\xb3+\x92\x84ozb\xa2\xc2g7\xed\x8b\x8az\x9f\xdd\xbc6X\x1d\xb6\xb7\x8e\x8aG\xcde\x89\xe3\x01\xabE\xc92\xca\x17\xab\xf4\xcc=a\x94\xb3p\xc6@\xde\xd2o\xf7\xe9\xc0\x989Q\x8c\xbb\xe3\xa5+f\xe9\x0dSH\x85\x1a\xdfN\xa8\xb9\xe6\xbc\xbb\x0dc\x9c6\xf8V\xdd!\x1c\x19B\x9f\x9a\xda\xf8\xe6\x92V\xc7\x05J\xb2Q\xdb\xdb\xb7\x03\xe2E\xc5\xf1*=K\x9aK\xdf\x80\xa6\x1c\xc0[\xccB\xa0?\xa0\xed8\x12\xa6\"\x9d\xa7\xe7J\xdeX\xd5L:\xeejX~o\xa9\xfbu=h\x1e\xb4\xc6\xe3\x93\x84Z\x0f\x8e\x90\x9d\xae\x9ax\xb5ZYY2'P\xf6\xa7\xa9]~l\x97]C\x16\xde\xa7T\xa3\x9f\xf5\x06v<\xabc\xe3\x19\x9d\xe1]\xc3\x19\xed\xea\x1e\x82\xf2\x10\x07\xbe\xad\xd0^\xe2\xf06)g\n%\xc6\x9c\x89^\xcc\xa0c\x84\x16G5\xe7\x02\xfc\xa2\x88\x96h\x931\xeb,\xaa\xe3\x806<\xfd\x1aJ\xf8\xa6w*|\x0d%\xa5\xfcj4\xda\xf2<6\xf5\xa1Pj\x82\xed\xaa&s:\xb4d$\xba]%\xfd\xf6V~\xf1\xe2,\x11l\x0c\xd3\x16b\x04\x02\xeeZr\x92\xd3\x13(9\xc9\xdf\xdaF\xc2B\xe3x\xef\xe3D\x1f\x01S\x1bw\x89\xea\xc4&\xda\xc3\x06\x9aCN\xd8\x81\x9a\xc07PV\xb3\x9b\xe8g\x17\x1a+\\\x9e$\x860\xc6\xdc#\xc9fMr\x7f\x8e\xe7a\xebO,&1\xc6\x9a\x88t\xd3o\x04\xd0\xde\xfe\x18x\xf64\xba$X8\xd1\xcd\xbd\xb3<*+\x88\xd1X\xc1d\x12\xfa\xc1w\xe4B\x1a!\".\xdb\xa0<\xa8\x17\xaa\x9a\xff\x92\x87\x9fh\xa6\xa8\xe27(\xeb\xe66P\x89\xee=^ \x12\xd3B\xe5\xbd\x9c\x84\xe2\xea\xf7\xe5\xbd;\xeao\xb3\xc8\xa8\x8c\xae\xd0\"2\xd5\xb9\xb2\xe2U\x80G>\xee\xb9\xa4\x19\x92Z\x8eD$dB\xce\xe0\xf5EF\x8e\xf2<\xcd]\xe7\x91\x9f$i t\xcf\x80\xcf\x8e\x18\xf0\x0b\xf0\xab\xd6T\x825g\xcbT \xf8\xa014c\x87At\x9a4{\xf9\x8a,HN\x92@t\x956\x08+\xbfH\xfeV\xc2\x9c\x90\x04\xd0\xe5\xd4\x8f\xa3\x82\x840\x81b\x93\x91\xdc\x1d\xb5 \xe8\xb0H\xa8+\xb9\x0f\xf5\xfc\xee\x95h\x97N\x11m\x1d\xd8;\xc4\xcc\x9dt\xf2\x90\xc0V\x13\xd2z\xc2\x98}9\x8e@c\x9e\xdc\xa8\xcd\xba\xf2\xcd\xb1$\xe5K\x81|/\x16nd\xe9\x1e\x0dR\x0c\x1c\x82'\x18\xa5.\x1f\xd2W_\xb1\xc21\xa8\x84V\xa0\xcd1\x9dlz\xe0\xe6\xa4((\xf6\xae7E $*W$\x879a\x1fH\xf3\x06\x1e\x8d\x81\xe2\x99\x037\xaa\x86\x14\xabB\xea\xedX\x9fQ\x8c\x87q\xb1s\xad\xfd\xaaa\x97\xd2\xa4(\xf3\x0d\xe5\xcdL\x96o\xbb\xf8\x8c\x9a2\xea\x8b'\xd0K\xd0\xc2\x996b\x1fX7+\xda*M\xc9'.\x05M\x1cq\x87 \x97\xcfT\xd1\xc2(x\x08\xd2\xfb\x1c7f(\xb9\n\xb4<\x94\x8a)n4\x86\xa62b\x0c)\xbd\xa5-\xd7P\xac\xd2M\x1cV\xef\xbc\xc1l\xa5\x96\x95\x03\xb4\x019\x82\xf5\xc0\xed\xa1\x9d\xd7T\"\xaf\xc2\xb70\xa5s\xd5H\xeeY\xf3 \xd3\xb7\xf0\xb0\xfd\xe7\xacg\x1a\xef^Q+\x01;\xdd\xd7\xaa\x02P\xd0\xa03\xcc\x9f\x81\xa5p}\x910\x1f\x80\x9a$\xbc#\x17\x85\x9b#WNZu(F#\x8flI~Q\xb3\x8b\xdaC\xae\xd1b\xe2E\x05\xf2Ac\xb6y\xb2B\xc9\x0c\x01\xe2\x14\x1e\xfd\xedn\xa2\xb9I\xd1\xcf\x94\x9e\x03\xfd\xeeiW\x12:\xddKO\xa8\x9c\x1c\x9d\x10m\xc7\xe4{\xa0\x8f\xb4\x94S\xef\x18\x06\xbb\xc73\xf1\x9e\xae\xd7\x1b\xdc\xa5\xad$\xc3p\x08\xd1\x18H\x83\x89\x8f4\xbc\x8cNa\x06R\xa5\x19\xb4\x07\xf2\x9e%\x88t\xf7E\xdd\x1d|r\xdd\xb4z\xa14WR\xca\x9f\xdc\xef)\xe9\"\xfe\xa4\xa7\xef\xf3\xf9\x83\x9e\xbeo\xc3\x1f\xf4>U\xf0\x07=}_\xcc\x1f\xf4\xf4}\x81T\xdf\xb7@\xf0\xa0s7\xe3\x1f\xb9\xd7t*\x08\xd5\x8a\xc0\xf0\xe3+\x02\xf5e\x8c\x86(\x02\x15\xc1\xfb=\x97\x0c\xad\"0\x96*\x02\x83J\x11\x18\x8f\xc68\xd7\xfb_\xc3\x02\xbe\x81\xf8kXP\x81%8Y\xb4\x15\x81\x0b;E`a\xab\x08\x8c\xec\x15\x81\x01W\x04.yd\xb2\xff=\xaf\xa9n#\xc7\xf1>\n\xdd_\xcb\xaa\xe0E\xc5\x8b\xef\x8eoa\x01\x87\x93\xdak\xa0p\xc6<\x1e\xc7/\x1cz\xae\x9c8a\x1d1\xe5\xbc\xed\xb5\xf3\x9e\xf7\xeeQ\xc7\x13l@\xff\x1c\xe8\xab\x86\xf0\xb3,\x11\xde\x15h@\x15\x8aN\xce\x8f4\xe7G\xbc\xc0\x93\x1b\xbe\"E\x1aoIx\xbc\x99\x979!\xeeI\xb50\x1d\x85\xaed\x85\\\xbar\xf4\x900\xa5\x17(Z\nU\xdb\xf4\x02\xb1T\xa1\xba\xf9\x04\nU\xbd*\xd5F\xe5\xca\xb2\x1d:\xfaa3<\xcf\xfd\x80\xa0\x8d\x18\xb8#\xb9\xaa=F\xb8,\xa9\x90\x1dE\xb4\xebb\x94$$\x9f\x18z\xa7l\n\x1d&\xad\xdb\xda\x0d\xe1\x9c\x12k' z}\xa4\x99#\xa7\xcc\xb5\x9d\xb1\xcb|\x96\xc6\x98\xf8\xec/w\xef\xde5h\\\x17iR\x1e\xb3o:Q\xe9\xc7Q\xb0C\x9a4\xf5`\xc2\xfa\x90jp\x893GG\x99\x1a/\xa9`^h\xa7(\xdd\xe4\x01\x99\xc1\x91\xbc\xbb\xa3Q\x8d\x80\xe7\x94H\x9f\x8b<\xd0\xe7J\xc3\xb4\x95\x0fw\xc7i\xcf\xa2\x8e\x1b\x0bi2\xd9\xae\xd1=\xe9dj\x80\xa2\xf2\xe4\xa9\x8b\xa7\x8e/\xd8\xf2,'\x81_\xea\x99X\xe0\x02\xe6\nm\xa9^T\xa0I\xf5\x1d~\xe8\x9d\xc7\xad&\x85\x9b\x1b>\x91)\xf3\x1f5\xaf-\xe5\xdc\x03?\xfe.\x8e\x96\xc9\x0c\x9c2\xcd\x0c\xf8I\xaf\x8cr\xff\xc9\xf2\x15\xf7\x9c\xd8\xf7\x0e\xc8\xda\xc03\x1amQ,\x026\xf3(\xfe\xff\x82>\x19p\x08\xce<\x8dC=n\xeaw'\x08\xad\x84&\x0d\x04\xb4I\xca\x86G;Vk\xa5\xde~\xa6=\xa3\xef\x17\xa7\x1c\x99\xee\xfb9\xe7dv'\xcc`K\xa3\xa0A\xa7r\xdd\xb0AIy\x80\x1f<\x7f\xd7s:\xf6sc\xee\xb1\x0c\x81w\xef\xb9\xaa\xcb/\xc7\xddT\x00\x16(\xc7\x03\xbd\xd0V\x99\xc0\x0dp\xf0WN\x7f\x9d\xd2_\xbe\xae'F7\x07!\x0f\x1b-\xf1m\xbf\x00\x83\xd5\xab!\x9b\xf1:\x84\x0d\xcd\x00\x86+\x9a\xdb\xe2\x0e\x02\x81\xa1%\xeeIa\xf0 \xe0Q\xdc\x0b\xb8\xa1\xb3\xa8\x8dd\xd62\xf6\xa46\xa8U\x87\xcc\x99\xf1\xb8\xe7'\xe4\xff\xfc?\xa7\xfdV\xf9\xb1\x0f\xa4\xc4\xea@J\xf9\x81\xa4&\xb2\x18\x8dw>\xe1%b\xbd\"\x8e\x02B{s\xa0,\x08+\xae-/\n\x99\xc2CH\xbd2\xfd\xf1\xb8\xfa\x81S\x9a\xf2 \xb2\x8a\x80\xbc\x0c\x19\x07\xb1\xaf,\x1cU\xac\xc9\x074\x99\xb3{\xf7\xee\xe9i\x07h\xe9\x07\xd8\x1c \x0c\x97\x92K\x92G\x18:\xc6\xc1d\x12l\x86\xda\xf1\xfc\xf3U\xbb\x10\xd4\xbc\xaal\x7f\x1e\xd3\x13\xefX0\x816;\xd5f\xce\x9do\xe0\xef\xf0\xed\xa59]\xc9Q`\"\xd75\xa9\xd6EuZ\xd3\xe9>\x8d\x1e\xaa\x8c\xb5$\xd3\x82D\x1f\xabA\x8c\xe4\x19Is\xb5\xb2\xbf^\xe5z\xa2\x0e\x0c&\xdf\xda\xae\xe8\xaf\x1d\x8am\x88\x197\x91,\x1b\x1f)\xa4W\x9a\xd8\xed+E3\xb0F5\x18\x82n G9T@\xa2\x89\xd2\xdc\x8c\x19\xd5\xa0\x81n\x06\xa7 #\xca\x01(\x92\xad@W\xda\xfc\xe9*\xd1\x11U\xaa\x03\xd0\xf1\xa7/\xe8\xd8\xb8.\x89\x8eL\x9f\xfd\x99\xa3\xe3\xab\xabD\xc7$-\x07 \xa3\x01\xad>\xbf#\x11\x0d\x14Wv\x02\xbe\xba\xec XW\xff\xba\x94 \xa0\xaf\x08\x0e\xe2\xb4\xd0\x94K}\xef\xec\xe0G\x98\x19\xfd\x08\x99\xe1\xee\xba9Pe\xca\xcc\x90\x99\xd4M*\xe2O\xa41\xe4\x99*\x86^z\x971\xa8\xdc\xbc\xac\xdc\xc6\xa0\xf2\xf42\xbbR\x01W\xe1G\x83E\xffd&\xf4\xb7^\x94\x84\xe4\xfc\xc5\xc2\x95\xa4\x12j^\xa6\xd8\xa0%\xcf\xeci\xe1\xfa\x03\xdci\xac\x1c\xe0\xd6\x03\xdcw\xcc&y(p\xe7\xb1\xd2u\xc4\x81h\x02?\x83C\xd8R\xd2~\xb98\x17\xd8\xc5\xbb\x02\xe0\n\"l`wg\x06`\xedo/\x13\xe0d\xd5GK;3\xe8\xe7C\x1b\x9d\x0b\xb5\xeb\x82!\xc4\xaf\xf6L\xf0\xe1\x9bC\xd8\x18\xc8L\xbf\xc2\xd3\x89\xe7yo\xb5#pN\x9c1\xac\x85\xdem\xbd\x9b\xae\x1b:\xfa\xeef\x90\xa9Y\xdf\x0d\xd6:o\xa8\xcc\xb5:\xbd7\x98q\xc1\x18\x97\x05\x95\xe2\xb96\xe2\x98\xfbF\x8f\xd0\x7fX\xaa\xab)\xec\xcf~l\xb4R\nX\xceB\xc9+\x1d\x8aK\x91\xcb\x8a=\xaad\xce\x0c\x1e\xee\x1ej+\x0c\xfb\x1a\x13&m\xa9B\xa9K\xc5\x1b\xb6v\xa3\xa0\xda6C4\x11\x01=\xd4\xfc\x12\xe9\x8c\xc1>\xa51\xb4\xa4\xd8\x80K\xb1V\x078\x0bvN\xb4\x9ex\xd0\x10f\x0d\\\x87\x9dh\x0e\xb5\xe8\xeb\x1bU\x1fcpZ\xf17\xad\xe7\xbd\xbb\x1dy\x14o}\xb6\xb1mr\xc93UI\x9e\x91J\xf2\xf4U\x92\xe7F%y\x16*\xc9S]\xad \xeb\xc5qRy\xd4\xcd\xea0\x9c\xe9\xfe\xe7\"\x80\xde\x9d\xd3\xff]?\x19TR\x14\xa1/\xf4)e\xd0\xf4\x03\xc8\xa0;\xe6\xf8\x87\xeb\"\x83\xdaH\x89\xc9@i5\xddAZ5\xcb\x8a\xfe0Yqc+\xda\x16\x18D\xdb\x0d\x15\xd1{\x03\xb0d\xc4{\xe8\x9f\\E\xa4\x18J\x07\xa0\x06S\x9f\x0d$n\xc4yP\x81\xce\xc2K\x8d\x83/\xd2|\xedk\x95\xb6\xc0\xb7#\x7f\xe1|m\x94\xaa\xb654F\xaa\x1a\xc0\xd7\xd2 \x15\x9f\xfec\xc8\xa7\xb1\x1c\x1c|\x03\\\xa8d\xe1vKR\xd6\x0bG\xf7\xb6\xfeE\x94,\xafL\xf2\xc6\xa9\x19C%\x81\xf3\x95\xb8\x02\x11\x9cw\xf1\xa7\xb4\xdc\xb9\x97\x17\xde\xca/\xcc-\xe9\xe7\xeb\x14\x8fe\x18\x83i.)Y<_\xc7\xe8\xfa\xb7\xfa\x0f\xd9\x13vS\x07;m\x0c\xe3\x84\x83\x81\xf1h\xae\xbd\xf3?\xff\x8f\xfe\xcf\xc1\x14\xe2\xce\x0c\x9c1\x1c\x97y\x94,\xddT\xe7M\xdaL\x94T!\xe8Vw\xe6\x9e\x99&\x83K\xaa[\x03\xa7\xdf\xf2II4=\xbc\x9c\xc2\xcb\\\xfa\xeb:(\xbc\xc6Pz\xe2}I <}\x86\xa7k\x91\xe0I\x14Qj\x8d\xc3&\xd3\x13?\x1e\xfa\xd8\x92T\x8f\x7f\xf6%*\xd9\xb4z\x8c\x87\xc0\x15ef\xe2{\xb2\x97\x0d\xc9*\x05S\xd9\xd9yI3W\x92\x1c\xf9\xa2k\x80|}<\x8be:\xd5\x94?\xe8\xe9T#\xfe\xa0\xa7S\xf5\xf9\x83\x9eNu\xc3\x1f\xf4t\xaa\x05\x7f\xd0B\xf2X\x8d\xe4\xf1\xc7G\xf2\xe0\x8a\xb2\x14\xa5*\x05f\xcf\xbbF\xa6\xc0\xcc\x87+0\x95Y\x8a6R\xc5edR\\~\xb2,Ei\xf2:\xbfH7%\xa6\xdfV\x03'\x1c\xf8\x91\x9f\x04$6\x00\xe7\xcc\xab%\xf1\xe71 \xb5\x01\xfe\x86\xba\xdd\xea\xb3\xb1U\xa8<\xbf\x98\xa4\x1buT\xb7\xb6R\xfb|S\x96\xf6Y\xd1\x9dy\x99\x00o\xef\xf4\x94\xfe\x11\xe0\x84\xd8\x147\x97\x1f\xcb\x94\x0fd\x93\x8aa]\x1f\xaa\x9f6\x1dT\xd4\xfc\x1b\x83\xf3:\xbf\x80\xa8\x84tS\x82\xccdfp\xdd\xd4\x17\xf7\xaeX#V\x12\xaak?i\xe1\xe7\x0c\x9e\xf0\x1d\xd0\xa8\x86\xd6\x01o`\xa8\x19\x9c\xe3\xe8\x0c\xf6jc!&\xc8\xa8\x0f\x95\xebYp\xfc\xcb\xa1\xf2\xe5P\xb9\xbe\x87\xca\xfc\"\xf3\x0bC\x91\x16\xe2E\xc5\xf1\x99\xbf\\\x92\xfc\xc0t\x94\xb0\\?\x1a\x12\x86P~\\\xa4\xc7\xab\xf4L{\xe2\x94\xba\xc3\xa0\x19XP\x8f\xd6\x0bVQ\x1c\xe6$A\xa1\x0e\xcb\xfc\x98?bG\xa6\xb7$/\xa24\x99d\xb9\xbf\\\xfb\xca\x13,\x1d\x7f\x88\xe6NO\xd7\xa4(\xfc%\x01\xc5\xfd\xc9\xc4_\xcf\xa3\xe5&\xdd\xa8\x0b~X\xcd\xa5\x12hu\xab\x0e\x0ey\x83\xb4\x18\xca\x14\x18\xc6\xe2\n@]\xea\x06\x13\xc7\xa8>\x94\x99\xdb\n\xd2\x90\xd4\xad\x15\x0c\xf5X\"V? \xa9\xa4a\xf9j\x9a\x91\xc4\xcf\"\xf6\xea\"\"qXP6 IK\x98\x13\xc8rR\x90\xa4\xc4\x8a\xd4+\x02\x85\xbf&\xc0\xf1\x1c\xd2\x1c^d$\xf9\xee\xe5\xd3\xc6\xb8\xeeY\x8e\xdc9\xdedY\x9a\x97$\x14\x0b*z\xe7\xe7d\xc0\xf8\xf8\xd4\xa0\xf0\xf57\xe7\xc0\xdbw\xfeV\xcdR\xb9J\x0b\x02\xe5\xca/a\xed\x97\xc1j\xc0g\xf9\xb4\xcd\xe0\x96\xb7\xef%l\xf6\xdcE\x9a\x039\xf7\xd7YL\xc6\xbb~k\x1f\xbf5\xf2\x1c\x11\xd3BI\xb0\xc5\x16\xd5\xee\xf3\x0f\xb0\xdf\xae\xdf\xf6^GE\x11%\xcb\xcfgs;\xafWt\x87\xa5\xdb($a\xe3u\x08SR`\xad\xdd\"#A\xb4\xb8\x00\x9f\x1eoQg'X\xef$\xbe#\xa3$\x8c\x02\xbf$\xd5\xd7$\x1b\xb9\xdd\x00|\xd9\x83\x97\x11\x10Z5I\xed\x85\x04q\xf2\xcb<\x0e\xc5\xa6\x96=c|\xca\xe7\xc7\xfd_c\xd5\xe5\xe0\xdc\xf4l\x97\x0c\xd48\xae\xfd8\xae0Q \x96\xe5\xf2\x9cm\x12\x9a\xd9u\xb7\x03\x07\x13\xb6\xe3\x7f\xafY\x92v\x8a\xa0\x8f \xc9\x9eE\xc9\xbb\xcf]\xbd\xdd\x18\x87\x0d\xb2pq]\xa9\xde\x96F/1\xe1\xa0$\xe7\xe50$\xf3\x8d\xb8\x93\xa4\xa8\xe1\x96\x88V\xb5N\x05\x1e\x1a<5\xa11\xd9^\x96\x93-I\xca\xc7\xacG\xae\x84\x92*\xf3\x9b\xae\xb0\xa2[\x89\x15\xddn\xb2\xf4N\x0c\xb4\x8b\xd9&=>\xdbT\xe9g\xa9n\x1f\xe3j\xf7\x1d\x89)\xb6\xb9\xb8+F\xacLk\x0b\xa1s=B\xe7\xed\x19\x94O\x86R\x8a\xe6k\x1b\xd9\xb0RJ UU\xc1\xf3u\x9c\x143pVe\x99\xcdn\xde<;;\xf3\xcenyi\xbe\xbcy\xb0\xbf\xbf\x7f\x13_\x93\xbf\xf4\xcf8J\xdeI\xdf\x9c>x\xf0\xe0&\x16 \x94\xbc\xabM\xf0\x93\xa5\x05rc3p\xfcy\x91\xc6\x1be\xf9{^\x05QQ\xbcF\x94?\xdc\xef\xa3\x7f\x17\x99\xd5\xd3J\x16\x85\xc5\xbc^\xac\xe7i,\x9d\xdamD\xce\xbeO\xcfg\xe0\xec\xc3>\x1c\xd0\xff\x93\x0c\x06\x0bNm\x928\x0d\xdeu\xd3\xd3\xe9z\x97\xb1<\xe0\x12\xa4\x9b\x81\xf3|z\xc7\xbb\x0f\xf7\x7f\x98\xde\xfe\xf9\x8ew\xf7\xd1\xf46\x1cx\xf7\xf6o\xc1\xf4\xc0\xbb{\xf7\x0eLa\xba\x0fS\xb8\xe7\xdd\xbau\x1b\xa6p\x97?\xbd\x0bw\xbc\xbb?\xdf]\x1dl'\xde\xfd\xfd\xe9\xa3\xfbp\xcb\xbbw\xe76\xdc\xf7\xee=\xb8\x07\xb7\xe8K\xb7\x82\xa9w\xb0\x7f\x8b\x0e\x07\xf0\xd9\x01\x1cx\xd3\x07\x0f~\xbe\xff\xc3\xed`\xe2\xdd\xb9s\x0b\xf6'S\xf0\xee\xde\xbe;\x99\xc2\x14\x1fM\xef\x05\xfb\xe0\xdd\xb9\xfd\xc0\xbb}p\x9f\xde\xbb\xf5\xc0{p\x87>\xbd\xb5\x7f/\xa60\xf7\xbc[\xf7\xef=\xba\xe3\xdd\xbdw\x00\xd3\xfb\xde\xfd\xbbS\xb8\xeb\xdd\xb9\x03\xd3\x07p\xcf\x9b\xc2\xf4\xc1\xea\x8ew?\xa0\x9f\x80}\x98\xd2\xcfL\xe8W`J\xbf3\xa9>swB\xbf\x13xw\x0enO\xbc\xe9\xdd{\xde\x83;\xb7&\xde\xbd;\xec\x07m\xee\xee\xcf\x0fh\x97\x1eM\xef\xc1}\xdaG\x98\xde\xf5n\xdd9\x80\xfb\xc0&\xec\xdf\x9d\xf9\x1f\x8d>\xf8\xca_\x9bu\xff\x93\xac\xe0\xf3\xe9\x01\xdc\xff\xe1\xfe\xcfw\x10l\x10\n\x7f\x82\xd5\x97\xe4\xb9\xb8\xc4\xe2\xdf\xf6n\xdd\xbe\x0f\xd3\xdb\xde\xfd\xdb\x0f\x82\x89w\xfb\xee\x03\xfa\xff\x93\xa9wp ~\xdd}p\x0f\xf6\x9fQ4\x98z\xf7\xa7\x0f\xe2\xc9\x81w\xf7\xce\x94\n`\x07\xdaW\xf0Q\xe3\x1f\x04\xa0\x98B\x1f\xc7\x07\xde\xbd;\xf7'\xb7\xbc\xe9\x9d \xfd\xf9\x00\x7f\x1e\x04\xb2\x97\xee\x8b\x97\xaa\xdb\x80\xb7\xc5\xcf\xaa\x83\xf7\xbd\xe9\xfd[1vor\xcb\xdb\xbf5\x0dto\x80\xe8z\xf5\x9ca\x1a\xed\x1d\xf6\x89b\xc2\xf4\x0e]k\xf1;P\xbe\xf2)0AY,\xf7\x12\xf8p\xcb;\xb8\x03\xd3\xfdgw\xbd\xe9\xfe\x038\xf0\xee\xdc\x0f&\xde\xc1\xdd\xfb\x13\xef\xe0\x1e\xffqo\x1f\x17\xf7\xc1\xbd\x07\xe2\x81wo\x7f\x8a\xff}p\xf7\x01\xec\xc7\xf7\xbc\xfb\xb7\xe0\x9e\xf7`\xff~@!\xbc\x83{S\xfc\xef\xbd}:[\xf4\xc5x\xd2\x80\x99\x08 \xfa\xe9)\xb6\x83\xdf\x11\xed\xd2\x15\xec4\xfcL\xf4\xf3\xd3\xce\xfa\xa4\x1fyy\x89\xa9\xbf\xe7\xdd\x9e\xde\x07\x9c\xf8\xc0;\xb8w0\x11\x93\xc6~<\xb8\xf7\x00\xf6\x0b\x9c\xcc{\xfbS\x9c\xc8\xbb8\x91\x0f\xf6\xef\x03\x9d\xce\x00\x97@\xcc\x14\xfb\x81/q\xa0I\x05\xd4XQ\xfc\x14N8[\x81~\x93\xb8\xf3\xe9t\xc7\xd8\xc1\xc9=oz{\xfa\x81\xe6\xfd6\x1c\xdcV\xcd;/\xcbqe\xd3\xfd\x00\xeemo\xffp\xc7\xbb\x7f+\xbe\xe5!)\xba\xf3\xe0\xd9}\xb8\x1bO\xee\x02\xfb\xdf\xd4\xbb=\x9d\xd0\x7f\x9eQ(\x98\xde\xfa\xe1`\xfa\xf3\xbdO0t\x16\xf1~e#\xdf\x87\xe9\xfd\xd5\xed\xed\xe4`5\xb9\xbd=\xf8\xf7\xf3[pw{\xb0\x9a\xde\xff\xf9\xee\x0f\xb7\xfe\xbd\xbe\x05\xf7V\xd3\x83\xed\xe4\xe0\x87\xbb\xdb\xff\x8f\xbdw[r\xe4F\x16\x04\xdf\xfb+\x90l\x9d*\xb2x\xc9d\xd6E\x123\xb3\xb2\xd5j\xe9\xb4\xd6T\xdd2\xa9\xfa\xcc\xce\x90\xacj0\x08\x92\xa1\x8c\x9b\x10\x08ff 5\xd6\x0fk\xfb\x03\xbb\x0f;f\xbb/\xfb0k\xf3\xb2f\xfb\x0b\xf3)\xfd%kp\x07\x107D0\x98U\xea\xd3\xe7LS\xb2\xca\x08\x04.\x0e\xc0\xe1\xeep8\xdc\xcf\xeb\x9d\x1d|\x1c\xc5\x84Q\x18D\xfd\xf3O\x07\x13\x9a\xa6\xfe6\xaa\x9f+G\xfd\xe9\xd9Y\xd5\xa6\xd47\x1f\x9e9\xce\x95\xd5\x87\xe9s\xc7\xb9\xb2\xfa\xf0\xb4\xbaCK\xf1\xc3\xf3j\x13\x81\xf3F\xa5\xdd\x9b\xa9\xba\x9e}\xee0u\xdddA\x80\x9f\x9f\xbb\x82\xedxq\x18\xc6QH\xf9\x8d\xce4\xad\x1c\xc5\xba\xd4$\x9ekP\xd5\x0f\xce\x10R\xee\x91+\xf5\x19\xdeX\x04\xd1\xbb\xf5[\x0c\xd7\x95\xd0}\x8b~\xd6_D|\xc3\xe0\xc3|\xa9S\xfc(\xf0#\xf6*^3rEN\xa6\xa5T<\x0d\x85G\x9d\xbeR\"(\x1e\xba\xaa'\x9d\x8aJv\x86\xa7\xa7\xe6\xc5\xb4x\x9f\xc4[N\x93\x9d\xfe\\x/\xa0S\xbd\xf7\x1b\xe7-\xa9^\n\xe6y=rrE\xc4}\xc2\xe2\x0d\xea\x8c\xfa\xa0\xb1\x19\xc1\xc1qOOWoP\xedL\xc4nIV\xe9\x89J\xa3:\xcd\x8b\xb9\xc9\xe6\xd7\xbb\xa6\x92c\x93\x9c\x056-\xad\x8d\xba\xbd\x1e\xef\xc1\xd5\xc9\x8c\xb3~0gK\x03O\xcaD\x1f\xae\x1e\xfe\xfc\xbe\xba\xa4`\x08r\xf3\x11\x95\xb5UY\xc5\xfb\xc5\xa6G\x84\x15*\x1c\x95j\xb2\xa0tR~\xa9Z\xcb\xfa+\xb80\xc9\x06D\xecx|\x0b\xfd\xfe\x8a\xf3\x98\xf7{\xff\x81\xc7\xd1\x96\xfc\x993\x85\xdet\x15\xb0?\xe3\xa1\xa4\x18\x11o\xc7\xbc\x1b\xb8\x9c\x7f\xea\xa1\x13\x8e\xea\xbd0\x8b\x9f\x18\xabF\x8d\x8cM\x1a\x8c\x88\x02[\xab\xe7!\x87V\xe4\xdc\xb0\xfb\xb4_\xfc6\x98lb\xfe\x15\xf5v\xb9-{m\xd5`sy\x99y\xb4\x84i\xc4\xa6\xcd\x1b\xd7Z\xbf\xbe3+\xc4\xd2\xaa\x10\xc6\xa6\x01W\xd4\xef\x8a\xb4\xde\xf93\x8a\xb8\x82\xc1\x87zj\xaa1\xa1\xfcp\x9dj\x06#\x8d\x99\x9e\xae\x18\xf29\xd5\x91\x16\xedU3\x1eK\xd3~4\x18\x91H\xd3\x89&@\xf4\xa1Z\xb7\xde\x01:!\xb6W\xd6\x94~@\x14\x86\xcea=\xe5\xf5\xa4RZG\xe4\x1b\xb3\xbc?\xe2\xb8D\x15\xbax6\xfa\xa0\xa1\xea\x06\xe2\x03\x06\x0c+\xee2l\xe0\xf7+\xe6B\xd1\xa7M\xe1u\x92 ?H\x0dC\xfe\x15\xf9(|\xbd\x81\xa1?u\x1e\x07\xf85%\xa6%\xb1)D\xfeE!\x01\x9c\x8e\xc4\xa6\x97[&~\xcb\x19U\x14<\xb6/\x0ebZ\xec\xb6\xaf$\xa7nS\xe3\xe0\xba\x9b\x98\x93\xbe\xe9e\x0e\xe1Hk\xfc\x03\x16m\xc5n\x04B\xca\xd9\x08D\x92^\xef\x82\xc4\xe3\xf1\xc5\x80P2\xbc\"|\xce\xe6\xfeR1@\xb6T\x8d\xf8\xc3!\xb6\x84]r#\"-\xcea\x1d\xfa\x8f\x0b\xf7x\x9a\x03>\x1c\xfa\xe4\x92\xc4\x17\x03\xd2\xc3\xa5\x80\x8e\xf3m\x17\xc85\xf6\xaa\x80\xa0\x06\x19U\x16s\x0ej`\x9a5\x8c\xc1Q#\xf0\x91\xb0s\xb2\xa3\xa9\x0bC\xd5\xa7,b\xa9G\x13\xf6j\xed\x92=U\x0e\xce\x92\x80z\xec\xabH\xf8\xc2g\xa9K\x12U\xd9\xb0\x9a\xdf\x8b0\xa8\x8b\xa4?\x17\xb4\xfa\x19J\"?e\xb1`o!\xa6\xd5a\xed~\xef2/\xf3rQ\xd8\x88\xbe\x1f\x95\xeb\x03\x95QG\xb2\xd3\xbb<-\xd4\xda#C\x92b\xf6r\xed\x1eR\xc4.5\xb2\xb9Xj9\xeb\x9a\xf4.\x13\xce^^\xaa\xe2P9\xed\xc3g-\x17\xc0u\xe6\xcbS\xf8zy\xaar\x16\x00 3\xd2\xebR\xb02\x0e\x1b\x16y\xae\x85=R2`\xe0\xe2\x0f\xdeH\x91F\x08\x1d;\x17\x8ekjkX\x1b\x8e\xc305\xeb\x93\x80F\xdb\xef8\xdb\xf8wu\xc9)Q\xe4\x9a\x86\xa9K(Q\xdf\xc1\xc9\x0c\xf8\x9f\xd1\x19'i\x12\xf8\xa2\x7f\xbaH\x87\xa7\xdb\xc1@\x87\xf2\x86H\xde\xbc\x1f\xe0\x12\xc6\x1e\xbe\xf5\xb2T\xc4\xe1\x88x\xf3\xb3\xe5\xc0\xfa\xb1p\xe5\x99\xab,\xcb\xca8\xd4\xed\x17U7\x1f\xe3\xd1\xe3U\xef1\x19\x92\x1d\x0c\xbb\xdf\x8f\xfb\x9b\xc1@\x8d\xf8\xe3\xde\xe3R)\xa7)ia\xc6\xd5\xbc\xad\xd5L\xc1\x0c\xf6\xa3\xc9\xce\xdf\xee\x02\x88p\xf4\xe8\x11)\xbcj\xc3\xd5B\xca\x88\xcc\x133\xd90\xeb\x1e\x15}o\x80n)\xfa\xf6\xd3\xa0\x15\x83\x1c\x88\xa1\x87DK\xeb\xd9d\xc7\xe8\xda\x8f\xb6\xb5%\xd8\xbabv\xaa\x0d@\xc7\xdd\xb7l\xcf\x02\xecb\xb95S\xf1\x91k\xd1Yum\xad\xef\xbap\x00c\xda\x1bM\xeev\"\x0c\xfe\x98\xc1\xb1\xed\xe5\x8e\x93\xd3\x97=X\\;\xfe\x12<\n8\x87k\x95\x05\x01\x13o\x03?\x15\xdd T\x168\x08S\xa1\xa2#G#\x0b\x9a\xa7\x13\xea\xf3\x05\x0b\xbbC\x17\xf8\xd5Y\xca+\xa9A\xd6\x0cU\xe0\xd7;\x19s%\xaa\xad\xdd\xc3\xd5&\x98\xaa\xb9v2\xc0\xdee\x1c\xe8e\x03\x95\x93\x97dJ\xae\xc9c\x92\n\xca\x05\xaeP\xf3 \x96&FTu#L \xbc#'!n\x99\x04E\xb5`[\xdf\xa9\xcfE\x06!\x80\x0c\\\x93\x1e\xa2bR\x9d\x99\xbc\xe6N\xe0\x9a\xe1<\xe9\x17jW;\xe659\x07\xe1\xf1%\x05\x1b\x10\x03\x07R*\xce6\x06\x06\x0c\xf3\x15\xbb(\"\x8c\xc1\x11\xcb\x8cV+\xf0C\xba\xed\"\xb2\x9b\x01|LR\xee\x95 M\xb9\xa7\x01\xad\x8fS\xf6\xd0!oX\xbd~\xb85Q\xcf\xfa\x8f \x0d\xf4hc-4P\xf3\x80\xcc\xd5$\xa0]1.\xe1\xc7\xbd\xc7\xeaO\x86\xeb\xbfH\xbf\xc9i\xaf\xb0\xd0+#\x04\x11D\xbb\xd3C\xc8^'\x16X\xcb\x113\xd5T\x8f\xe2\x81G@\xa3\xb27\xd5r\x0c4\x0d\xf5\xac\xe2\xf5\xfd\x11\xd0\xa8\xecM\xb5\x1c\x03MC=\xfc\x08Pxm\x9e\xf9Q p\xd7\xa8v\xa2\xd8\x1d\xb8\x94\xd8i.E\x03\x7f\x1bi\x0eu\xaf\xd6\x8d`wb\x0c\xa93\xa43\x98\xa3\xca\xac\xea\x90\x1d\xd3\xb7]\xad|\x1d\xe5\x1e\xda\xb3\xf5G\xee\xd9qh\xbc\xae\x96O\x05\x8f\x1d\xa2jc\x15\x98\xbf\xa1\x96# q\xd7s\x8c\xe0\xc5BG\xe9# \xa8\x97_\xb3\xa0{\xf3k\x16\xb8\xca\x1f\x01\x80\xa3\x06?J\xbbC\xe0G\xa9\xab\xfc\x11\x108j\x08)\xaf\x0b\x15\x8d5\xa8\xdc\xce\x1a\x8e\x00\xc2UG\x9a\xad\x0e\xad\xb5\x1c#\xb3U\xf3f\x1e>V\xebN\x8e\xa8;i\xab\xbb&`\xee(_\xaf\xb4.\xf1\x90D\xa1\x1b\xa9\xec\xa4Vj'\xb5\x88P\x12\\9\x88l\x1ao\xc4\xd1M@\x81\x94\\whM=\xd6);\xbb\x13\x1d\x07\xad2T\x95\xf1\x11a`N\xcb\xbaTV\xac\xaa^\x93\xa0\xdb\x0f\xae\x87\xaeVu\xae\xd9R\xd3\xe3KU\xe2\xa0\x14\xf7\xf2\xb1\xa3\x99#\x16\x85\xca_SB\xc5\xb1\x88b\xc1\xder\xb69\x04\xad\xe1D\x7f\xc8\xc2\x15\xe3\x08\x9f\xbf&C2\x1dLD\xac\x1d\x938N\x97\x95\x88\xdb\xdbD\x9cm\xc0\x10\xdb\xc9\xc4P\xea\xcdV\xdf\xac\xc9Kr\x06G\xa6\x9c\x0c\xafHof\xf5\x0c\xf0u0\"\x8f\xd5\n2\xea\x1f\x03\xffX\xd5\xfe\xd2\n\xfd\xbf\xdeD\x8fuL\xdf\xc7=\xe2\xaf\xaf\xac\xc4\xff\xb8\xf7rn>\xf5\x96Jxw.:;.\x80Y]wD\xba3eI\xf8\xf1\xe5\x8eW\xc1M\xc7)Kz\xb0N\x14\x1fn\xce\xa22\xc0\xec_\xa6\x0c\x9a\xaeeSY.\xe3\xa0^\\m\xa1\xa1|k\xcf\x8e\xc0\x9f8PM\x9dj@\xeaT\xc4\xd6|\x14\xea\x07>\xcc\x0fNX;j\xe1l\xd6\xa6\xde\x17,\xac-\x0e\x0b\xcc\x11\x1dt\xe9Kl=4\xf2v\xf1\xc1CE\xb3Fr|o\xefR\xd7\xc5\x105-\x06\x92\xe3|\x01\xe3\xabC\xb4\xa2\xde\x0d\xac\x90\xbf\xfe\xaf\xffM\xe1|e\xb0\xd6\xc7\xc8(\x0e\xcd\xd9\xfa\x08\xcd\xdbZ\xd4D\x9c#\xf6^\xeb\x9a\xb0\xb9>N>rC\x7fL\x0d\xc2Q\xc3Q\x02\xf3\xba\xb2\xe9+\x1f\x03\xa5\xe4\x8ad\xc5\xf3\xc3.\xcb\xa8_\xe4\xa4\x84\xf5]\xc4\xa9\x90}8\x8c\xc8\xcb+\"\xf4\xe9\x1a\x19\x93s\xc5\xc7\x15\x9b.+\xcaP\x13\x05\xd6\x07F\x0b\x85/FmU\xd2X\x89\xb9B\xbf\x82\xc6\xea\xac\x9c\xac\x99\xa5iU\x15\xafh\xcf\x8a\xf5\x9c\x97\xda\xd4 Z\xab\x85=Tip\xc5\xb9\xd4\xcf\xf78P\x03ri\x8f\x0f\xa1\xa9\x8a\n\xd5*\xd9\xecya\xaf.\xa7\xe4SS<\xa8\xcd \xf5\x03\x0f\xfa\xea\xc6]1\xb9\"\xf3\xda\x94\xcd{@\xa8{\xe8\xdb\xff\xec\xf9\xc0q\xf03\xef)\xden\xb2\xbcpg\xe1l\xc38\x8b<\x08\x13\x0f\x19?ug\xd4S\xaa3}\xe6\xced\xe9\xa2\xa0~`\xf2~\xde\x0c\xdc\xb9\xce3=k\x82\x0e\x8e-C\x16 \x03\xdft\xea\xce\x9a\x86\x94\x0b8\x06\xb49\xcf\xdd9\x03?\xba\xf17\xf7&\xd7\xd3\xc1\xb2\x94iy\xc4q\xbf\xc3z\xaahd\xc5\xcb\x84\xdc\x1ej+\x92pvA\x18\xb9$\xb1F\xc6\x0b\xc2\x86\xc3A\xa1\n\x8c$\x12\xcf\xd9r~\xb6\x1c\x11x\x98.]\xa6W\xc5\x03vm\xe5Q\"\x10.n\x84Gi.\xf8\x04\x9a\x02D\xe66X\x01\xa2-\x13\xdfg\x01K\xfb\xbd\xde``\xe1\x16\xe4\x92D\x17D(\xf0\xf9\\,\xfb\xac\xd1\x84\xe3\x03n\xc3\x95,A\x1a\xbb\xc6\x8a\x160\xd7\x84i;\x17\x1c\xcb:\xe1SC6\xb3\xd4\xcae\x01\xa9\x830\xb1I\xca=s\x88\xde?]D\xa7[\xbc\xf6:\x11\xdc\x0f]\xe2m\xc0\xf6,p\xde\xdeRm\xa532?\x1b\x91\xa9\x03?\xf3\xbb\xd8\xf32^\x82CWm\xc2h\x0c\x8f\x14X\xa3\xa2\xbd$\x9b\xb0h?\xb2\x1d\xff\xd8\xc6\xafO\xab\xb6\xaa\xdaJ\xe6y\x93\x91\x0c3\xa7\xb6\xbe\x0b\x0b)\x9c\xe6\xa6#\x12\x8c\xe0\x18\xbb~\x04\xfd\xec\x9c\x9c(\x82<\xf1v\x94\x7f\x19\xaf\xd9\x17\xa2\x7f\x96\x9f\x17\x8f\xa7\xf5\"\x9fO\xebE\xa6\xedE\xb4G}f\x1d\xe4\xf7\x96\xb3^{\x11j\x96x\xa1\x8b#2_\x0eF\xa4\x9f\xc1\xd5b:\"S\xe07gDJ\xf2\xfc\xb3:T\x19\xc8}\x8d\xcd\xc0r\x0c\xc8\x15\xa1\x93$N_\xd1\xbb\x11\x8a\x01\x8a\xc1]\x90\x94\\\x92@\xb1\xb0\xe9\x19\xd4L\x01E\x0b\xb5\xa7\x83\x0b\x92\x0e\x87naR\x873\x0c|\x8f\xf5\xcfG$\x1b\x8c4[\x86C}\xf3\x05\x9a\x1a\x91\xd4\xa0\xb9Y\xf4\xe4\x9a\x8c\xa7dF\xfa>l7\xd9\xde\xa7H\x07\xa5\xac\xa7)\xda8\x18\xe9;\xd8\xd0F%\xc7\x1c%Xo 2m\xe3\xc7+\xb2\x19(X\x1c\x14\xb0\x1bq(\xd0=\xf0'\x82Q=p\xa1\xb8\xccF\x0b\xb4\xa4~\xc9\xd8\xd2\xca)\xd2J\x9aKM\xd3\x12M\xac\x954\x0d8\x85*Z=\xde+\x89R\xd4\xca%\x8dR\x92\xaa\xc0J[.a\xcf\xfc\xa0\x03jY\xd3\x82\xc6\xe2\x82\xf0\x82pt\xd2\xef\xab\xf5\xed\xf7\xf9\xa8`R]\xa56\x88\xe3\x83\x8b\x01\x10 \xaeQ'68S\xb7\xd40\xbfb\xc3\xaa\xe4(o\\\xe1Q>\x14 \xde\xa1=c\xde=\x9bx\xc8[\xef/N\xf9\\6W\xcf\xa6U{B\xaa\xd3\xab\x86\xf8h\xed\xff\xec\xfc\xccIA\xd3\x9c\xbc\xd4\xccp\x14t\x9apB\xe4\x80\xf5\x88\xecFd?\"\xe1\x88l\xbb\xd1\xc5\x03\xa4\xf4\x01t1\xa8\xd3\xc5\xd4\xd0E\x0f\xe8b0\"g\xedt\xd1\xeb@\x17\x13rE\x02K\x17\x15\xd1\xf2\x90.n\xc8%\xc6p\xe8?=G\x8a\xb6\x86\xac\x15\xea\xb8Ac\x9c)R\xa4\xf5\xe0\x82lj\xb4\x12\xc8\x80\xaf\x00\xde\x1c\x80f\x0fM(\xc1R\xc7m\x1ca\xfc)\x03\xa4\x82px\xa5(\xc3G\x04\x0fZ\xb6\xf5\xed`\x1c7\xea\x91\"\xc8\xe4\x9a\xf4\xc3:`\x16(%O@\x86^\x0fSw\x83\x02|\x1a<\x07d\x17\x03\x05\x8c\x93\xad\xd8\xd2\x9a)9J[\xde\xb1U\xbc\xacoX\xcdtD\xbcA\x99M\xa4\x93|s2\xdf\"w\xa8\xa6\xb9.\xbe\xe8\xb8\x9c\xa1\xc3\xe4\x0d\xfc?\xecK\xe9\x8a7m>\x1eS\xf1[\x99\n\x10\xccB\x17\xb4\xc7\x8eR\x92\xb6\xa1>\x92\xff\xf8\xc7\xf3\x9f\"g\xf1\x1b8K\xce\x99\xfc\x1agr\xf2\x1f\xffh\xfe\xe3\x1f\xe2?\xe9/\xc4\x7f\xfcv\xfe\xe3\xbb\xf8\x8f\xff7\xe5?\x0fA\xc1F\xfc\x83\x01\x8fpw\x07n>\xec\x0e.\"\x97\x84_\x90H\xed\xe0JX\x01\x08\x16\xcf\xa3\xe5\xc0\xce\xba\x99\x07\xbd\x03\x11f\x00]\xbb\x10\x91{\x8b\xfb\xd7\x1a\x0d\x90\xcaK\xdb\x0c\x18\x80\xfar\xc2{d\xb5\xf4\xa4b\xf8LJ\x0b\xd9\xaa\xd5\x816\xb1\xfc\xa2\x9a\xddx\xd6B}\xb5\xe8\xdfz\xc5c\x17\xa4\x06\x85\xf5\xc7\x8cB\n$t\x85\x8b\xe6F\x1cF2\x0f\xe8\x8a\x05#r2\x053\x1cGUE\xfdV\xb9\xae\xe9\x88$Z\xce\x0e\x14IMM5}`'z\xfb\xcc\x06#r\xb2\xa9^$\xd2\x93\x9d\x0f\x05\x18%\x0e\\\xdd\x04\x04\xa4\x96\xe4\x95K\x8c\x0en\xd6I\xbeaw\x9c\xc348Q\xd1\xdbpo8\xac}\x06/Q\xb9\xb2\x83:\x15\x1an0\xa0']\xe0%\x0e\x98[\xa0%\xfa\nmK\x90\xc3\x96\x0e\x11\xdd)\xdc% *^\x93>lG\xe7\xcbAG8+\xb4\xbf\x19\x12\x81\x0eh\xda\x82\xcdv\x006\xeb\x08V\xa3\x8e\xc6\xfc\xac\xae\xc6eEh~\x06\xa0\x96j\xac\xfa\xa50\x8c\x1f\x0c}\x95U~\x8cQ\x1d\x8f\xbd\x06\xb8\xe0\xe2\x8a\x82\x1eh\x02\xd0&\x886\xab\xd7x\xfei9\xc8\x97]\x91ji\x83\xf5l\x80\xf2\x8c\x9b\xd3\x9b\xdcs[,\x97@\xac\xf6<_$q\xd2\xcf\x03\xbe\xc4\xf9\xbe3\x8b\x04\x9cg]\x17\x13fJ\xac\xe1\xa8%\xe5p\xa3\x87p\xb5\x1c\x1f\xba\xe6\xf0\x98\xee\xe1\xab\x0e\x0e\xd6Z\xc3|\x1b\xccj\x98\x12\xb7\x14\xe2#G-\xf6\xc9\x1ft\xa3\x84\xc4\xd1\xcbC\xb8u\x10q\xea4\xb2\x96\xd2\x0567\x95n\x83\xae\x05\xb2\nT\x1f$W\xd9d\xbb\xbf\xe6\xcd^\xfdruo\x7f>\xee\x0f\x16\xf3\xc5\xf2\xe7\xf7\xc3\xeb'\x93O\x16o\xe4h\xf6\xeb\xcb\x93\xc5b9\x00E\xf0b\xf1\xc9\xb4\xf71\xf6\x10\x0ey\xa5\xb8\xbb\xef\xb0\xb7()\xcf\x1a\xb6\x0dy\xce\xef\xd9\xf6\xab\xbb\x04\xc4]\xb8&\xd4\x7f#\xe7=\x08\xd2\xb8\x88\xfa\x83\xf9\xf2\xf1\xa27\x19\x9d\\\x8f{\xfafO\xaf\x87\xc1\xb7\xb8\xb9\xdb\x83\xa6\x82\xcbA_\x95*_t\xaeC\xd31n\x97\x9d\x804[\xa5\x82\xf7\xa7\x0e\xbc\x1cL\xd2\x98w\x0cN\xaa\xeb+\x9ck\x9a\x13@W\xbd\xa5\xeeI\xec\xdf\xa0\xff\xc9\x03\xc7\xa5g\xe4\xa3\xc2h\xa3\x82\x04_\xfa\xeb\x11\xe9m{j\xe7\xbb\xb1\x92Q\x9e\x17E\x933$\x98\xbb\x92\xc0\x1e\xa3\xc0\xee\xa6+\xd5\xed\xdd\xce\x9c\xd5\xba\xf3\x93\xe2\x86\xb2\xafH>\x14\xb0\xd2{eo\xf9\x12\xe8\xb2\x18\x8f\x9bk#\x06\n\xc1\xee\x84\xdeLP\xbd\xd9\x1b\x1c\xdc\x1b\x9a\x9f\xd5\x80\x9f\x8d@OF\xf3\xdd\xc6f\x12\xd0T|\x13\xad\xd9\x1d~\xf7\xb4\x0c\xb7g\x81\x11\x8d/@|\xdfL\xd8\x1d\xf3\xfa\x19\xe8-\n\xa5^\xa2\xfa\xfc \x95-\xfe4e\x83N5\xd3\xd9\xe2\xcf\x8a%\x99\xde\x98\x06#\x92\xa0>\x8d\x0cI2\x9f.\xf5\xe0v\x08EG\x0e\xf1\x99\xe2\xef=\xb8q>\xbeo\xd6L\xadc\x07\xb5\xb6\xc5\xb1\xde\xb5\xb8\x91\xcc\xcf\x97\x1d\xa2\xe7\x91\xc3\xf2b\xf1\xf7\xd0\xee=d\xeaT\x0f\xba\x15\xf9\xdb\xcc\xce!>_\xfc\x1d\xe0\xf9\xc5\x9f\x82)\x80\x05\x93/\x921I\xe6O\x0d\x8a6\xabR\xcc/-ho\xfa\x01\xb9$Y!\xe1!\xfd}\xc8t\xd9\x95\xf6K,\xa9\x12aT\x04\x0d(\x8d\x91\x98}\xdd\xf4\xd9\x08\\\x1b\xa4#bR\x04\xea\xb4\xdb)\xe6\x07 7&\xd5\x1cZ\x9c.\x86c\xb9\x98,&rq\x8d\xff\xc9\x93\x93\x93\x139\x1a\xc9\xf1\xf8\xb4~\x98q\xba\xe8\xf7=)B\xc9e2X\x0cN\xb7~\xfd`\xa3>w\xde\x8c\xf4\xfe\xfb\x7fsL\x11W\x1f\xfe_\xc7\x87D}\xf8\x7f\x1c\x1fD8#\xbd\xbf\xfe/\xffw\xaf\xf4\xa5\xc1\xda\xa6\x8b4\x95\xcbQ.iIk\xab\x8a\xbe}\x1a\xe4\xa5\xd2\xde\xa8\xc8\nS\xcd\n\xd3&VXc\xc4v\xd3\x94v\xe7\xc7\x19)\x97;\xcc\x96I\x91\xed*,\xcd,\xdb\x85\x95 gQ9/U\xafx\xd0<\xc8Oz\xfa=<\xa3\xb9&\x01\x99\x91\xc0J\xc3\xf1\xa8\xdd\xf6\xac\xfa\xd3\xd2\x97?\x17\x13\x11\x7f\x1b\xdf2\xfe%MY\xbfbtS\xfc\xa9e\xc6'\x82\xa5\xa2O\x07\x16^Z0\xbf\x18\x8eA\xec\xfe\xef\xff_oPH\x9d\xfc|>z\x0f\x1f\xfe\xfa\x97\xffZ\xfc\xd2\x9f_\x9f,\x07\x7f\xfd\xcb\x7f\x85\x8f\x9fL'\x93\xfa\xd7\x9f\x9f\xe9\xb2\x9fL\xd5\x7f\xc5\x0c#[\xef\xa8T\xee\x8d\x9c\xbf\x19/\x07\xe3\xf1\xb8\xaf\x1e\xe4'\x83\xd3m\x085\xfc\xf5/\xff\xfb'\xe7\x95\xbc\x8bt0\x1e\xf7\x17i)\xdb\xffV\xcb6\x7f3^\xa4\xaa\xd2>>\xd5\xb3\x83\xff\x96\\mM?\x8an\xd5\x12\x8d\xf9\xe3\xde\xd2E\x1c }[\xa7\x08\xa7\xf3\xf1\"\xc5\xdd\xd1\xf2\xd4\xb5\xc3\xa2m\x16\x8a'}a\x0e\x02\x01\x7f\x8d`\x0e\xd3~\xe2#\x120\x85\xbc\x85N\xd6\xdb\xc8\x0e\x98^\xdb\xad\x04\xd0em\x10k\x13\x914WF\x91<\x80\xde\xf8\xceM\x9b=\x92\x1d\x91\xfb\x11Y\x8d\xc8\xdb\x11\xb9\xfd0\x82t\xab5\xbf\xab&\xc2\xb4\xd2\xc4`u.\xc5\x9a\xccFaK\xaer\x88a\xe8\xb60tx\xfct;\xdf\xea\x9c\xe4\xf2\x8al\x06\x17d;\x1e\xb7\x9c(\x99_a\x0c\xb6\n\xb9P\xae\xd2\x9b\x14\xd8_\xd9\x15<\xe8,[\xb1\x19v\xe1\x82(\xc1\xca\x03\xc2\x18\x97vAz\xe3\x13\xe3\x86\xc7\x1f\x0c.\xda\x87\xd9\xfc\xc0\xd7\x07\xb9\"'\xb4\xafPX\xefN\xc6d\xaa\x05\xc2\xd4\xeeW\xa6#rO\xaeH\xef1NL\n\xa6\x89\xa0:\xc0\xb2\x01\x1e[']\xe6\xc3\xfcT\xeb{U\xc3zDB\xf57\xe9\x06\xb5\xf9\xc1\xa0\xb4\xcdc_\xcd\x83\x9a\xcaQeJ\xc9f\xa0\xa7\xf4\xa8\x06\x89\x06z7I\xfdh\x1b0\x18\x8a{\xd5R\xa1r\x95\xb69f\x18\x8a\xbf\x1c\xe0{rM\xfao\xe7;\\j\xc5\xe3\xca\xcc\x91<\";\xb46\xc8\x89 Z\xc4\xce\xcf\x97\x15\xb6\x91\xf5\x0b\x02\x80\x9e`G\xb9\xa7K\xd0&\x7f\x0c\x10\xce\x1e\x08\xc2t\xa9X^qI\x1d^+\xae\x9fj\xca\x8f2V \xbe\xd1\xe5WW\x836\xfd\xf6\xe4\x9a\xdc\x1e\xb3\xcf1?\x18\xc5V\x1d\xb4\xeb\x97\xc4\xe9\xcc\x0e\xddQ%\x11ug\xc4\x11\x07\xbb\xed\xa7\xf7J\x9b\xce\x85\xc0j5T\x8b\x03VH\xff0\x02\xf4\xfe\xfa\x97\xff\xe2\x8a\xa0\xea\xfa\xbd',H\xd9G\xad\xfa\xa3\xee\xc1\xc0\xc0\xbc\xea\xf8\x15\xe4\xa9\xdb\xdb[\xf9\x1b\xb9\x98-N\x17\xa7N\xb9\xc9o\xd4L\x9f\xbe\xb9\\\x9c\xd2E\xfa\xe4\xe5\xa9\x91\x90\xda\xc5#Z3^7F\xe8s\x87^CX\x0b.7\x06\xab\xce&\xe82\xaa\xf9\x9c*\xe3\xc1\x8c\x9c4\xc4\xae`!\xf5[>\x8b[_\x08\xc6\x9b+\xd7\xf2\xf2\xd7Q!0g\xd3\xdd\x16\xf3Ko}\xe1\xed\x14\x92l\x99x}\x9f\xb0\xfeA\xa1\xc1\xa3)#\xbd\x8c\x07\xbd\xd9Add\xc7\xacy%\xb2\xccH4\x81\xc8dl\xfd\x9a\xddu\\\xf60\xaa\xd0\x83?\xf1\xc0\x11\xf9\xa6\xfak:w*\xfe\xe0\xc2n{6\x1c\x08\x98\xb5\xbf\xaf\xa1\xe8)\x90D\x0cjF\x18\x96\xafTB\xbf\xb0\xa3z\xa3s\x9c\xfa\xa3\x92[\x9b\xa6\x9f\xe3\x0c\xcc~j\xfcb63Sg\x8ez\xb9\xea\xb4\xe8\xf2\xf5\x11\x0b\xfc\xe8&\x9d\x11V\x1f\x12\x9a\x89X}U\xcb\xa4\x1c\x93\xda\x15L\xea\xd8\x8d\x0co:\x80*\xeee\n;\x80:|jg\x12eA\xab\xe2E\xdf\xc3i\xd8\xe3\x14,\x95\xee]\x96J\xce\xb1\xaemk\xee;\x1e|\x14\xb6+\xa0o\xb9\xffX\xe7\x1f\xb9\xdb\xa0\x1eXD\x822);\xea\x14\x04\xea\xd1\xb7\xd0\xb5\xdc\x9d\xabr\xb6 \x9f[Vw\xfa\xe6\x92\xce_.\xd2\xa5a\x0d\xdb\x01\x1a\x87\xea+\xa3\xbb\xf1xD\xfc~\x9a;\x18P\x89\xc3\xe1@\xc9\xc6\x90\x0bR\n\x9b\xaf\xbc\xad\x18k\xcc\xcbv\x01\x9e\xe8\x0e\xac\xe0\x90Q\xc9\xf9}\x85\x1b\x14.\x13(\xf4F\xa1\x7f5\xc91\xda\xee:l\xaf\xf6\xa5=e\x08\x05\xfb\x81\x82yo\x15\x06F\xbc;L\xf1\x88\x99tOo\xa3\xd7\xd0\x9a\xde\x11np\xc7\xba!\x97\xb6Y4\xbe\xcdM\xdf \xce%\x15\xec[\x05\xc6~\xbeYN2\x1e\xa0\xa6J\xdb%\x1b-\x1a|\xd4;T\xf5Y\xb5\xb4\x1e\x11\xef\x18\x12I\x1e\xa4\x0d'E\x8dx\x90\xab\xa5\x93\x8eJq\x92\x0b{\xebN\x05 \xb2\xc0C;f\x1d\x8c\x1d\xd1;m\xcc\xab\x87\xbf{9}`\xd5f&T\xfd\x99\x81\xe8p.E\xb4\x02\xf3\xa1#\xf1\xd0)\xb6\x98\xd6\xbd\xec\x91\xd3\xfb\xf0>\x15h\xe0\xd1\xd0\x8d\xc7\xdd\xe1\x0b\xd0\x92\x1eP=!\xc3|L\x0c\x91\xe8 \x0e\xa9_P8\xb4zh\x9f\x1f:\x8fG \xf2\xd1\xf3w_9\xbb\xcaJgWY\xf9\xec\xca\x1b\xd9\x834}vu\xb0\x9d\xf6m2\xee\xd5\x0eV\x82\xe7\x1e\xe3\xf1\x05pI\xadM9\xb9\xb2\x14\x9a\xe0\xadmC/\xe0Sf\xac\xd7/\x06\x8a-\xdb6:\xed\xe0\xf6:(\xe2\x88\xf89z\xc4\xfa\xe6+\x1a\xc0\xd9\xe2U\x8ew\xfa\xe4\xa4\xdc\xa1'\xe4\x0b\xcb\xc7&?\xa6\xd5\x8fg\x93\xe9\xf3\xc9\xd3Jj5\xd3\x97qr\xcf\xfd\xedN\xf4\xbd\x019?\x9b>'\xff\xcc\xd96\xe6\xf7\xe4\x7f\xa2^\xbcJ\xc9\xe5\x96\xb3\xedo\xd4?\xe3\x1f!e\xe2\xc5\xe1\xcbj5\xaf\xbeyM\xbe\xf5=\x16\xa5l=!\x85\x18\x86j\xdc\xd28\xe3\x1e\x83X\x86\x01\xe6IOC_\x8c\xf5\xcb$\xd9%\x07\xa0T\x15\xa6\xb3\xd3\xd3\xad/v\xd9JAp\xaa B\x80N\xdbF\xe1\xb4\xf4\x0e[\xd1Q\xd9\x80\xbd\xddF(\x9e\xfcI\xf8\x81q\xb0\xae\x9d\xe2W\xac\xc4\x9c\x02v\x9c_\x94v\x9fe\xc6Q*x\xe6\x89\x98\xcfH\\_\x88\x19\x0fR\xf7\xb6\xb5eG\x9b\xeff\x1d\x1f#v\xfb\x1f\xfch\x1d\xdf\xba?\x97\xb7\xda\xae\xcay\xa6\xd6.\x9b\xe9{3\xf5\x1c\xc5X\xac.'\xd0\"\x0c\xbe\xa3\x14\x9d\xf8\xe9\x97A\x9c\xa2\x13\x9ck\x18\x89WT\xec&!\xbd\xebGj\xaf2R\xd2\xfc\x0cvK#\xa2\x1d\nT\xfd\xd5\x17\x7f\xa0KC0\"\xe1\x8b{\x0b\xc51e\xf1\xeeV\xab.\x86\x98\xcb\x8bfz\xf5N\xf0\x07\xc1[\xdbP?\x0dJ\xd0\xb2OGX,\xcc\xce\x8cnV\xa5\xe9\x04\xb7F|\xb5\\\xef\xddX\x8d\xc0w\xc1mc\x8c\xa8\xb1\xfaU\xbe\xb6\nj\x0bf\x02w@\xa0,\xc8\xf3=\x94\xfb\x17\x1a\xe8\xa8\x03] s\x15\xef\x02#,=\xf74\x14\xc1\xb7j8bb\x19\x95\x93'\x1e\x0d\x02\x13%FS\xe9\xc1(\x8f\x86te\xa3! rM\x04\x99\x91\x13\xbco\n\xbe\\\xec\xe8\xa0V\x08\x8c\xc7\x05\xf1\xa3T\xd0\xc8S\x85\xe2\x89\" \xaf\xe9V\x15.\xfa\x83\x9a\xd9\xd1}m\x89R\x7f0Y\xa9\xa7>+\xfaY\xea2\x88%\xd23k\x16\x05\xcc\xcf\xa8V\x01\x86\x9c\xbc\xb6\x0e'\x83\xcd\xb1\xa3\x94 \xe0TH\x9a\xe4\xd0\x0cF\x8e\xb3\x0cw\x17^\x15i\xf8q}(\x90\xffc:Q(f{QH\x9b\x141\xbf\x99T \xcb\x85\n\xd5c3\xa9\xd5\x1c\x18r\xc2ssV\xcb\x91!\xb3~k\xce^b\xc2P\xa4\x90\xe2&.\x83#f\xe6u\x81q\x1e719\xcb=f^\xf2RvZ\xbe\x80\xdb\x11\x85\xc5\xd2<\x1f\x05\x81\x05j\xb3\xef-\xc3me\x14l_\xbf6\x17(\x88,H\x05\xcd\xfbQ\x83]Jy?\"1p\x99C\x9e\xb3H>n06}\x81j\xaa~U\xc0\x1c\x19t\xd6\xbe\x7f\xe2\xf2\xaa\xfd9\xcfPIS\xb2\xabS\xfa\xa4\xabTp\xea\x89WL\xec\xe2u\x07d\xc0\xa0f=S\xae\xd7\x05\xe1Ph\x9e\x1d\x1e\x04R\x94\xc3\"\xe2G*\x9b\x98\xech\xfa\xc7\xdb\xc8F\xa3\x8fP\x14a\xf3hI\xd0#X\x03\xfb6\xb8\xd8\x05Fv'X\xb4\xee\x08#\x80\x87\xf2\x1f\xcb\xc5\xfbf\xe4\xaan\xe7\xde7\xdc\xcc)m\x15\x1a\x16\x98\x91\x18AW]\x1b\x9b^a;\xd1\x1b\x00\x93*\xa4\x90\x0e\x13L@\xde)\x14\xd2\x81F\x90\x99R\xbe\xcd\xc01V\x83\x843(u\x01\xc2\x03\xb6\xce\x0d-\x81\x07q\x19\xe9$\xcd\x12\xc6a\x01\xe2\x0d\xe95\x0b\x98`\xe5\xae\x8c*;2\x8a\n\x84\xa8\xd3\\\x07\x81\x9f\xa4~:k\xdd\xa2\x17\x7f\xd6\xa4K\xebh^b\x90\x04\x98\x83(\x0b\x02%VD\xe4\x9a\xf4&\x93\x9e\x12~1\xbc\xa21\xf6Rl\x1f\xf4\xfcc\x12Y\xd5\xf1\x90D] \xb6V\xecvDN%\x0f\x7f\xc19\xbd/x\xe8\xd25\x0c\xf2\x8e\x18eq5r\x83\xf9\x15\x96\xa1\xdd\xeb\xb0\xceG\"\xc4\x9c\xbb\xc0\x1aU\xd2\x95m:j\xc5\x87q\xfd8\xcb1 p\xff\xe5\x8bh\xfd%MD\xc6\xd9\x11\x03s\"&\xdb ^\xd1\xc0\x11\x9e\xf1\xcfP\xed\xf7l\xcb\xee\xfeL\xc2,\x15dG\xf7\x8c\x88\x1d#\x8f\xb7\x8f\xc9&\xa0[\x92\xb2Z`F\xf3\xcbG\xac\xb23\xbc \xb8T\xc1@\x8a\x81\xcf\x00}\xb9\xb9\x80\x1f\xf1\x08\"\xe9\xad\xd9\xdd \xdf7Eh\xbf\x82\xe1(\x8c9\x94Jl\xb5\xdf\xb2\x1b\x8az#Pw}\x84\xeb\\\xc6H\xb9Wf\x99!}\xec\xe3m+W\xdc\xdc\xdb\x9d/X\x9aP\x8f\xc1\x08\xce\x08\x04dr\xec\x0f\x8a\xfa\x8e\xc3\xdb\x02\xb7\xde\xc5\x86+\x8d\x18W\xa0\x1a9#O\x90\xb2\x98\xf2\xfa\xd5\xb7\x9d\xf0\xcanw\xbb\x80V\xdc\x96\x08,\x86\xa1UE12\xa5\xf95\nb\x95\xe6\x8eiMJ\xd2\xeb\xc4\x81S&\xbe\x10\xe5\xbdb\x87\xbbkzC\xa3J\xa6\xfd\xc1\x9c-\xf30\xba]\x1a\xdd\xd6\x1b=\xba\xc5.\xed\xe8\xce\xa5]\x1a\xaa*xtK\xad\x0b\xa9\x82\x829\xfeu\x01n[\x07\xae\xcb PU\x06d\xe8\xc2\xebU)\x0c\xae\xf9\xb9G\xe4K\xc5>\xbb\x8cH\xb1U=\x92\xfd\x1e0\xdf^M\xc3I\x1a\xe4\xbb\xf5\xbass\xb9\x9a\x0d\xd5hf\"\xa0\x82\xfe`\x94\xc7^\xac\x10\x14\xd4\xaf\xe9\xb9\xd0\xdc\x0bo\x11D\xe0\xf8\x1d\xefDr\xb5\x13W\x94\x17\xef/\x98\xc4\x0b\x98\xf4l\x92\xee\xfc\x8d\xe8+\x12<&\xb8\xed\xf7QrP\xdc\x9c\"\xc1l\xe2\x88n\x1c\x9d\x189\x85\x16\x03\xcfu\xc5\x0e\xce\xc2x\xcf\xfe\xee\x07\x8f\x16oX\x95FR\x0de\xbbv\x13\\p\xe2 _\xc0\xa8\xc3\xb1\n\x8e\xb7j\xc1c\xfdtD\x1c\xd7m\xc9!\x8d\xd9G\x9d\x89m}\xc9tY1\xb5\xe6;\x93\xe4\x1dM;\xcf\xbb\x15\x8e\xd0\x9a\xa3GzdX\x9d|\xb8(\xdc+\xdc\xa5\x81LL'w\x81(e\xe2\x1b\xc3?\x8f\x80\xaa\xc6\x89\x8f\xe3\x80\xae&\x8fk\xb1\xf3\x90\x1b\x1d\\\x87\x96J:\x8f\xa2\x16\xbcE\xe5`\xb2\x83\xce\x0f\xb0\xe2\x07\xc1\x0f\xf0\x96y\xef\xb2\x87\xd1\x95 \xaa \xf5\xdcb`2\xd2{\xd9\xcb\xa3\xf8\xda\x91R+\xbdwy\x8a\x05{/{\xcb\xa3T\xc7%\xf0:\x0c\x05\x8a\xcd\x96\x0bYA\xbe\x1a\xc5\xcb\xfc\xaaC\xa7\xd7G\xfb\xc0\xcd\x97\x87\x84j\xe2G\x84\x0d\x08sk\x03\x84\x16\x98\xc9\x90<\xc6\x08\x0b\xb0\xf5\xc0\xa8`\xed\xf4<\xa7\x16\xf5\xd1+\xa5\xbcW\xa2xMou\x84\x88\xfcQD\xdf\xceS\xdc\xa5\x89\xa2\xd6\xc9\xc8\xfcm\xbe?\x8c\xb4\xda\xa3-f\x06\x14\xe5\x1d\x98\x7f<\x0d@\x14`\x85\xd3+T\xb5\xe3X\xfe\x9e\xb3M\x7f\xd0\x82 ~N\"\xa0R\xedoZ\xcf\x04\xbb\x13\xfdBm\xa8\xb7oROt\x19\xbd\x02\xcc\x1d\x05f\xb3On\x1e9bm\x87Dc\x1e\x07(\xe6g\xf9:\xc2\xf6e\x8a\xbcC\xed&\xdb\xe6\x95\x1b\x13u\xa3K1\x1b'\xabA\xd5\x190\xb6!\xb9\"\xbd\xb7\xab\x80F7\xbd\xae\xaa\x942<]P\xae$\x81[-k\xfb\x12\x85\x93\x9a\xa1\xa5\x8dC\xd2\x1b#s\x9bu\xa4\xfc5\x8c\xe9\x02\xa9Uek`\xd7\xf1k\xadF\xae*f\x89\xbb\xd5\xbc\xc0\x11\xcd\x19b\xa2uT\xf6X\xce\xa8\xb0\x15\xbb\xc3@\x1e\x93\xef\xfe\xf8\xc37\xaf\xbf\xf9\x97\xaf\xde~\xf3\x87\xaf\xbf\xf9\xc37\xaf\xffc7\n\xe6<\xd69\x82\x8c\xa9\xf2z\x8f\x0f\x1a\xfe\xd3\xfe\xf5\xac7\x7f\xd3[>\xb9\xee\xc9\xc7\xf37\x8f\x97O\xae\x1f\xcb\xf9\x9b\xc7\xbd\xab\xcb\x97\x7f^\xa4\xcb\xe1\xe0\x14\x19\xdc\xe9\xfc\xcd\"]\x9c\xf5\x1e\xbf\\\x9c^-\xee\xce\xa6\xe3\xc5\xdd\xf4\xeb\xc5\xdd\xa7_/\x87\xa7\x134\x0fQ\xb3\xdb\xbf\x9e-\x16\xe9\x93+\xf5O\x0foM\xdao\x83\xeb\xde\xa8\xe8\xcbd\xaer+Vy\xd9?\xf9\xdd\x1f\xbf|\xfd\x1f\xbf\xfbj\xa0^u\xeab\x91\x0e\xf3W1\"= \xeeQ\n\x15\xaa\xcf\x83'\x86\xdb\xe2\xbb,Tq\xd9?\x85F{\xe0o\xe6t~6\xfe\x9c\x8e\xdf}1\xfeO\xcb\xfcq\xb6|rZ\xad\xb3\x0c\x81\xb0\xad\xa8^\x9d^\x17\xda\xcb\xf9\xf7\x88\xf4\xb6~\xcfE\x0b\xd5\xa0\x7f\xb9\xa3\x9cz\x82q\x13Q\xddhZ\xfa\x8f\xa2U\x9a\\\xc8G\xbf\x9e\xbe8\xbb\x90\x8f\x02\xa1\x9e\xe1q\x8b\x8f\xe7\x17\xf2\xd1OY\x0c/O\x9f\xc1\xbf\x9f_\xd4\xaf\xdb\xab\x1f\x989tA\xd8\xd2n\xa4\xb0\xf7\xb0\xf8Q\xb2\x8c\x98//PUzb|]\x82\xf2g\xfe\xf4@nE\x10ON\xc4A7\x1bAE\x93\x1b\x8f\x88\xd0\x9a\xbaf\xab\x81\xc0\xaa\x87\x91c\xa91Ut\xe7\x8bh\x0d\x93w\xff\x87x\xcdR0'\xf6At\xd1Zv\x7fD\xa2\x81M\xec\x17h\xfeWh\xa4\xa1\xca\xf5\xb5\x8f\x81\x81\xd6\x0d\n\xab\x1b\xa4M>\x86H\xe3fJ\x89wq!@\xc9\xa1\xa9\xf0\xaa\xc3\xd12\n^\xb7Q\xf0\xdc\xa3pD'4\xed\xf4\xbbP\xe5\x06(\x8e\xc3x\xad\xdf\x8dr\xb2Y\xd1I[\xba\xdd\xbcp\xf5~]\xaf\x8f\xc8*\xd79Z\x0eA\xd0\xb1\xf3C\xd3\x01{\xf89\xef\xb02\xa29\x07/\xb2\xcd\xd3E\x0b\x92t\x01\xf3\xd4X!\xda)\x84\xcb\xdc\x99\xf2\x91\xecg\x0f\x99\xba\xbaX\xd4(m\x14V\xc2\xd1'85\xc3\x86\xe2\xb2j\x11|Adh9\xe1\xb3\x92q\xc5\xe1Ds \x0f\xad\xa8\xaa!\x83\xcc\xef\x18Q5\x1f\xfb.H\xdc8\x12\xf9\x0c\x1e\x1c\x88\x0f\x06\xd9\xe0\xd4\x87\x00l\xf1\xf2\xe3\x81\xfb\xabr\x06\x87\xb4\xa4\x1a^\x9e\x8e\xb4S\xb0I\xffz\xe6G\x82\xf1\x08\xbc\xf4\xd1@Z\xf2\xe7\xc7\x91z\x01\x92\x14\xf3T2\x95-\xe1~\xcaR\x99\xecb\x81^i\xeee\xc2\xe35fO\xe5&\xce\xa25\xd4$\xfd0\x8cW~\xe0\xb3H\xfa\xd1:S}`\xa9\x0ciD\xb7\xb0VU\xb9\x84q%tI\xc1\xbc]\x14\x07\xf1\xf6^z;\xee\xa7\"\xa4\xa9\xf4\xe20\xcc\"_\xdc\xcb\xb5\xcf\x99\x82\xe1^\xb2u\xe6a\xf5\xec\xa7\xccO\xa0\x1e?J\x85/2\xc1dH\xf9\x0d\x13~\xb4\x95i\x1cd\x08\xd1\x9eb\x81T\xae(\xdfR_=\xc4\x99\xf0\x7f\xca\x98\\\xa1\xa20\x95j\xfb\xaedf\xe9\x05\x8cF\xf8\x10\x8b\x1d<\xc4a\x92 \xc6\xe5\x9a\x85\xb1\xc7\xa9\x90k\x9f\x86q\xb4N%\xf4\xdf\xf7R\xb9\x8b\x83\xb5\x1fmS\x19\xf8\xdb\x1d\xb4\x9fP.\"Us\x12d\xe1\n \xca\x92$\x80\xber\xeaC\x13{\x16)y4\x95\xd4\xa3k\x16\xdeK\x8fr\x06\xd0\xc4aB\xa3{\xe9\xf1\x0c\x06{\x1d\x87\x007\xbbK\xe2\x94\xad\xe5\x06\x9aI\xe5&\x88\xd5X\xc9-\x0d\x02\xc6\xef\xe56\xf3\x05\xe5\x00\x8e\xbf\xa6\xf7\xf2\xc6WX\x11\xc9\x88e\xa9\xa0\\\xc67~Do\xa9\xe4\xcc\xf3\x13\x96J\xce\"A\x03\xf5w\xef\xb3\xdbT\xa6;\xff&\xddQ\x89\xce R\x009\xe6B\xa6\xf7\xa9`a*\xe9\x96E\xde\xbd\\1\x1e\xf8\x91\xf4h\xc88\x95\x1e\xa0\x85\xf4\xe2\xcd\x861\x85/\xeb8\x95\n\x05\xa2\xadd\xa9\xa0\x82I\xa6z\n\xe03.\xe4&\x13\xab8\x9074\xdb\xb0H\x06\xd9]\xc6\xefeH\xfd4\x8ed\x18G4\xdd\xc90KY\x16\xca\x88n\xe3{\x8a\xb8\xa6\xa0L\xa8\xcf\xd5\x1f\x80)\xf6|\x1a\xe0\xa8\xdeKA\x85\x88c)|\x16\xad\xa9\x1a\xe1=\x0b\xe4\xde\xa7?\xb2T\xee\xfd \xa0\xeaO\xaa\xd0f\x1f\x03d\xfb\xf8\x9en\x99\x04\xccF4P\xa3\xbfN\xa5\xb7c4\x91\x9e\xdaw\xc85\x8d<&a\xd1\xcam@S5\xb2Y\xaa\xd0,\xda\xc62\xf2\xa3\x1f)L\xb4^\x0e2\xdd\xc5j\xd4\xe2\x80r)b5\x03\"\xbe\xb9\x8f\xa5\x88\xe3 \x95\xb7j\x8d\xca\xdb\x98\xdf\xa4\x922\x1eK\xca\x13*i\xeaS\xb9b\xa9\x90+\xff\x86\xc9U\x00h\xf9\xee\x9d\x1a\xdeDzA\xb6\x92^\x1c\xabU\x19'rCy(7~\xba\x93[\x7f#\xe46\xe3\x99\xf4\xa3M,\x7f\x8cW\xa9\xbc\xf1o}y\xc3\xd9Z\x064Z\xcb\xc0\x0fc\x19\xf8\xd1\x8d\x0cY\x94I\xb5\x18e\x18\xaf\xa9\x8ch\xc8d\xa2\xf06Q_\x938\x15\xf2\xa7$\x8e$\xf7\xbd\x9d\xe4\xd9\x8e\xcb\x94\xdd\xddK\xe1'\xa9\x1a/\xa6\xfe\x89\xe5-\x8d\xb6\xf2V-\xe7[\xff\xc6\x97\xef\xe2\x88\xa9%%W\xfeZ\xae|\x05\xf0J\xad#\xe9\xb1Xa\xb0Z\xaar\x1b\xef\xa5\x1f y\xe3\x872\xf4\x03\x191!\xe3(\x901\xdf\xaa\xe5/\x93l%\x15\xc0\x82\x052\x8bby\xcb\xd6\xf2\xee\xeeN\xde\xdd\xbf\x93\xd4\x93t-)\x93t#\xe9VR_\xd2@\xd2P\xd2H\xd2X\xd2\x9f$\xe5\x92\xa6\x92\nI3Io%\xbd\x93\xf4\x9d\\Q\xb9Z\xc9\xd5Z\xae\x98\\m\xe4j+W;\xb9\xf2\xe5\xeaG\xb9\n\xe5*\x92\xabX\xae\xb8\\\xa5r%\xe4j/W\xb7ru/W\n|\xe9y\xd2[Ko#\xbd\xad\xf4v\xd2\xf3\xa5w#\xbd@z\xa1\xf4\x14)\x94\x1e\x97^&\xbd\xbd\xf4n\xa5w'\xbd{\xe9\xbd\x93k&\xd7?\xca\xf5\x8d\\\x87r\x1d\xcb\xf5;\xc9<\xc9\x98d[\xc9\xb8d\xa9dB\xb2Ln|\xb9\xf9Qnn\xe4&\x94\x9bXn\xb8\xdcR\xb9]\xc9\xedZn\x99\xdcn\xe4v+\xb7jb\xe56\x90\xdbPn#\xb9M\xe4\xf6'\xb9\xe5r\x9b\xca\xad\x9an\xb9\xbd\x95\xdb{\xb9\xbb\x91\xbbP\xee\"\xb9\xe3r'\xe4.\x93\xfeZ\xfaL\xfa\x81\xf4C\xe9G\xd2\x8f\xa5\xff\x93\xf4\xb9\xf4S\xe9\x0b\xf9#\x93?\x86\xf2\xc7X\xfe\x98\xc8\x1b&o\xb6\xf2f'o|y\x13\xca\x9bH\xde$\xf2\x86\xcb\x9b[ys/o\xde\xc9\x80\xca`%\x03O\x06\xbe\x0cnd\xc0e\x90\xca@\xc8 \x93\xc1^\x06j\xa9\xca\xd0\x93\xe1Z\x86L\x86[\x19\xeedx#\xc3@\x86\xa1\x0c\xd5\n\x96a\"\xc3\x9fd\xc8e\x98\xcaP\xc80\x93\xe1^\x86\xb72\xbc\x93\xe1\xbd\x0c\xdf\xc9\x88\xca\xc8\x93\x11\x93\xd1FF[\x19\xf92\nd\x14\xcb(\x91\x11\x97Q&\xa3w2\x0eeBe\xc2d\xb2\x91\xc9V&;\x99\xdc\xc8$\x90I(\x93H&\\&\xa9L\x84Lner/\x7fR4M\xf2X\xf2T\xf2L\xf2[\x99R\x99\xaed\xea\xc9t-S&\xd3\xadLw2\xf5e\xfa\xa3Lod\x1a\xc84\x94i$\xd3X\xa6\\\xa6B\xa6\x99L\xf72\xbd\x93\xe9\xbdL\xdfI\xe1I\xb1\x96b#\xc5V\x8a\x9d\x14?Jq#E E(E$E,E\"\x05\x97BH\xb1\x97\xe2V\x8aw2\xa32\xdb\xca\xecFf\xa9\xcc\xeee\xf6N\xee\xa9\xdc{r\xcf\xe4~+\xf7\xbe\xdcGr\x9f\xc9\xdb\x8d\xbcM\xe5=\x93\xf7B\xbe\xa3\xf2](\xdf\xdd\x0e\x16\xab\xd3\xaa\xe6\xb47\"\xe8\xffoq\xbb\x1c\xfc\xa6\xbf\xb8\xfdy:\x9a>\x7f?0\xba\xcc\xb2:\x14r_\xcf\xe6\x8b\xf1\xc5\xec\xd1\xd5b\xb8\xf8d\xb4\xb8]L\x96\xc3\xdf\x14\nD\xf6\x897Ub4\xa3\xb6B\x94\x19\x96\xf3\xf1dh\xc5\x87\xe5p\xd6\xbf>i\xfa\xb48]\x9c\x0e\xfa\xd7'\x8b\xf5pqz=\xe8_c\xca\xb5\x13\x90\xbaJ\xb7?\xb9>E\xa5\xaej\xff\xf6\xf6v19\xbadsG\xad\xf6\x17\xd4\xc5\x8b\xb1\x05|\xf8\xe87\xbf^\x9c\xfe\xd3\xd5\x7f~\xdb\x1f\xc8\xc7\x9f\x80@Tg\xe1O\xbc\x0du\xc8\x11\xb3@\x8c\x0f\xaf\x03y\x12=\x1a\x7f\xe2\x81&-''Y\xb7\"\xdf\xb3\x80\n\x7f\xcfl\xb9\xcd\x81S\xc8\xa3/\xfa\x117\x99$\x87NX\x9a\x87\xd0\xd2\xf7\x19I\x9a\xa1\xb54\x7fF\x1cZc\xf3\x0b\xb1\xdf\x0d\xc1~\xba\x10\xf7vj\xd4E\x08\x81\xdb\xe4\x03\xe3bX!\xf9\x17\xa2_\"W\x87\xf8\xb4\x00$\xc6\x95r\xba\xe8\x9fn\x0f\xdc\xb7\x8fJ\xf9\x07\xa7\xdb\x03<\x1b\xb9\x80\x0d\x0e#%9\x1b\x90K\xd2\x07\xf2\x14\x95\x92-!?9\xeb8\xa6$\x9fs\x87w8\x976\xf2UU0\xeb\xaa\x84\xf4#pK\xd5(X\xce\x17\xb7\xcb\x06\xc1rG\xd3\xaf\xb3 \xc8\x8b\x9a\"-\x12\xbf\xa3\x9a\x8c\xfb?x;\x16\xb2\x83\x15\xb8a\xf8\x0f1_\x7f\xa90d#\x18\xaf\x023\x9b\xbfY\xa4\xcb'\xd7\xa6JG\x15E\xe6\xdb]\x1e5\xd3S\x94\x06tM\x7f2\x1dR\xec\xca\xdcb\xc94!\xfa]\xcc\xd2?\xc4\xe2\xf7to)\xf6\x1f\xf9\xefb\xa1\xad\xd3Z\xb2\x7f!\xbee4\x15\x7f\x8c\x98\xe9q\xa5\x8c\x9f~S\x9b\xcc\x9c\x92\xf5]\xe7\xf1\xce\x13\x89r'\xba,\xd7\xea\x82\xd3](\xce\xeb`~\xb6,\x1f\xac\xb6J\xf1\xbd\x1f\xe9\x9e\xa6\x1e\xf7\x131Cg=0\xce\xbd\xfd\xaa\x9c\xd8\xa5G\x87\x86\xbe\xa3\x89\xa0\x9d\xf1\x13\x86\x8e\xe7\xd5\xfa\x07\xfb\x00\xc7:@\x9fw89c\x13A\xdb\x1avO\\\xded\xbbA^\xc7\x82\x87\x81\x7f\x827&NL\x0f\x9aWQ\xcdW\xac\xf99\x91\xa7\x0d\x05\xbb\xa0\x92\x01\xf3\x84\xd9\xf1m#Q\xcd\xc09\x88$\n#P\xf8\x08\n\xf9Q\xf6\xcf]\x06\xef\x01\xc7\xbc\xaf\x8abS\xd7C\xae\xc2\xbe\x18Jv\x84-7\xf5=\x06\xc2\xa2\xc1\xa6\xb3T\xe3<\xc1\x8e\xc3q\xf6W\x98\xc5\x8fs\xe6\x87\x1ej;\x8e\xc2W\xb8\x7f\xe9Zy\xbe\x1f\xecX\x7fq\x94\xbb6R\xf4g\xfb\xc0\x06\x1f\x80A\x0d\x8d4\xce\xa7\xde\x8a\xfd-fT\xef\xd5\xba\xce\xe9\xeb\xf2\xd6\xaek3E\x0d\x00\x96\xed\xd8\xde\x83\xe6\xd88N\xd3\x0d\x82\xe74;\xe1\x0f\x87\xe2\xb8\x89\xef\xfd\xa6k\x93\x8dh\xf0'\xfe\x80E\x9d\xf1\x00\xf7S\xb9\xc2\x13\xc6\xc3(\x8d\xfb\xa8\x00\xbe>uY\xc3VX\x91\xad\xa2A\x1e5\xf9\xbf\xe3,a\xd1\x9a\xad?\x96\xedI\xc6;S\x99?\xf1.4\xa6tO'\xe3\x0dJ\xa2\"\xb6:\xf7\xb8V\x80\xacn\x9ak\x1f\xec\x90\x94}\xc3d0\xa5=\xed+\x10\xcc\xbdGM\x05!\xf4}G\xaf \x0f\\*\xd0\xb2qv\x9e\xfb\xf4~D\xc3\xe4\x02\xe21=\xeav\xcd\xea\xd85R\xbd6\x05\xed?tN\x8c\xbe\xae\xa8P(\xe7\xc3\x05\xd1\x07\xe7XU\xb5\x83\xa3\xf8\x9f\xcc\x12\xc2\x12\xf6#^`}\xcd\xa9\x1f\xf8\xd1\xf6\x87\x80B\xcc\xf6.\xe3S\xae\xb6\x8bl\xe4V\xd1\x97\x17\xb7\xdb\xe1zS\xf3\xeeAy8,Nb\xd1\x19$\xc7X\x1e\x01J\xef\xb4M\xe1Q\xd4\xe0\x1a\x87\xab\xe3i'/F\x8a\xfa\xda\x94\xf7#\xedh\x11c$\xf16?\xa5\x1a\xb0x\x92\xfb\xe5\x84\xbb\xc0\xf9`\xbc7\xbeeFd\xbe\xc4(>\xfd\xa2\xdbx\x1d\x8a\xeaC\xa3a\x1b\x8c\xc8<\x0fa\xde\x1b\x91\x1e\x04\xa4\x86\xf02\xea-\xf0S\xd1s\x85(\x9d\x973Bm\x9f\x7f@m;\xaek9?\xfb\x80Z\xe0\x93\xaeg\xdaZ\x8f\xbb\xbc \xcbm\xea8\xaf\xd4\xd1\x00;\xa3k?\xda\x9aBO\x1f\xd0pP\xa9\xe3\x99{\xf6v\"\x0c\xa0.\x93\xef\xf9\x03\xda\x12t\x15\xd8\x1e~\xda\xa9\x87k\xb6)\x0em\x15m\xdc\x85\x8aPA\xb1\xcf+\x81\x0d\x97\xee\x98x\xd5\x05\x8a\x14<\x0b\xacW\xb6\x8a\xcb){\xdd\x81\xa1\x1b\x1bF.\x89o\xaf)\xb0\xe1pP\xa8BG\x92\x9f\xb3%\xc4\xe7\x82\x87\xe9\xd2%\x8e\xd1@\xcc\x08\xe6<\x87\xf3\x85\xf9r\xa0\xa9\xd2\xa0BzrJa\x9fh\xc1\xad\x11\x04\x82\xf0\xdf\xb1\xaa\x835\x87\xe6\xcd\xf6E{\xfb-\x00\xbee\xe2\xfb,`)\x1e\xa3\xa3\xa3\x04\xec$\xbaH\x10\xe8\x10\xe1dzA(\xb9\xd4GHl\x12\xf8\x91j\x98\"Q\xbd\xf1\x93\xaf\xc2D\xdc\x7f\xebG,\xedS\x08m@\xc9\xcb+\x12\xa1\x17\xfe\x93>\x9b\x88\x1fv\xfeF\xcc\xe9\x12\xae\xdb\xac\x82\x9bo\xa25\x8b\x84\xfb\xfa\x13\x00\xccq\xe0\xe1F\x08\xd4\x12\xcf\xf9Ru\x91\xc2\xf1\xe6\xc9tpA\xf8p\xe8\x90\x130\xea\x85\xf0\xb7;\xa1`\xcfF\x84M\xfc\x14@4\xb0[\xbe\x90\x19\xb9\xaa\x8f\x9dQ_\x07\xa6\xa7y1\xda\xa86W\x8da%#2\x1c\xdaAB\xaa\xa1\xb9RB9\x8b@\xe8\xad\xd7\xda\x12\x0e&\x1f\xe7\xda\xe7\n\x9f\xcaq\xa5\xcc\x0420S]D\x0bQ\x8b%\x99\x82q*W\x1f\xb3\xb3\xb3\xcf\x9e/\xe5|\x91\x9d?;\x7f\xb6\xc8\xce\xcf\xce?\xd3\x89\xd5R\x01\x94\xca\xce\xce\xe8\xd9i!,X\x111\xe1\x8e\x91\x03+G\x84W\xc7P\x81\xe8#\xa2\xb9<)\x03\x02\x94\x92\xe1>>\xb3\xc7\x02\xd5\x9b\xf3\xc0\xe55\xab7\xc2I0\x02'\x10\xb98\x9b\x8eHo\x11\xa9\x14\xabU\\\x88\xde \x8f^W.\x9f\x15\x18p\x93Z\x1b\xd6V}\x0e5\x94\xd3\xb3\x82p\xf2e\xbcf_\x88~4 \xd7:,,F\xf9\xf3t<\x14\x08\xfe\xa6P\xbf\xa7j\xe8i\xda\x00\xee\x85)\x19\x13o@\xfe\x89<3\xc7\xb5\x90\x08\xc5y\x95z\xe8\xd5\x8c>\x15\x99\xf1\x07k\xe6\xc1\xdc\xab\xd54\xa4\xef\x8f\x14q\xf3#f\xfe\xbe\xa2w\x05\x024*\x05\xb4Al\x1fz\x1epZ\x86U?@e\x18kM\x9a\xeb\xae\xae\x96\xab\xdf\x8a\x00\x9c\x0dj\xa8X\xac;\xdf7\xfd\xaa\x0e\x08/\xbaUD\x1e\xd6\x1a<\xa0\xb8Y\xc7\xfa\xe7li\xd5`(\x11\xb0\xa5\xa2\xbc\x85.\x14=\x9f\xbd\x1f\x95\xda,K\x1a\xadM\xd7]\xda\xeb\xfe\xa2(\x87g\x8f\xfdC\x90]V\x00\x1b\xa0\xe8w\xe1\xea%k\x83\xfa\x87\x84zGC\x9cr/\x978\x0d\xd0z\x15\xd9\x0c\x85%\xc8\x1e\x0c\xde\x97;\xca\xd3C\xaezKn1\x9d\x00F\xf6\xe4\xa9\x06\x19\x02\xfdA\xf0\xfd\x96z5w\xc2\x0e\x86\x0c\xd2\x1f\xb9\x04\x97\xf8\xa6n\x07\xdfP\x10\xbf$\x91#b/Z\xaa\x9d4\x0c\xf2x\xccr\xbb\x04\xa6\x96\xedq\xdd\xd92Q\xc7\xdeV \xa9j\x19\xa98]],b\xb0\x8c\x1a=\x14\xa9,\x81\x82\xb6\xe2\x92\xd4/\xaf\xffy\xa0V\x01F5\xf0\xf1\x10\xce,\x87`9\x02\xb7\xad\x8acpr]Z\x19Pjj\x1c\xc1\xdb\xc4Q>\x82(\xc7\xa8~\x0c\x1c\x93\x91iQ\x05|\xb7\xf6\x05\x19\x83\xe1\xac\xf6 \x1a(\xd4\xbf \x81\xa2\xbc\xf1p8\x80\x88ne\xc8\x06j*Ax\x03&?\x18\x01\x07;\xb3)gZ\x1c\xaa\xf54\xc5\xfe\xe0\xc8\xa8\x15&e\xf7\xcee\xf3xY\\\n\x8d}\xd4c\x9d\xd5}UUD+\xb4\x8d;J\xb42\xa9\xee\x90\x83\xee%b\xf6\x82\x0e,2c*\x96j\x12\n\"\xcd%y\x96\x9b\xe3L\x1ds\x18\x03^\\\x81\x8f\x9a)\xee\xdb\x9aVW\xbe\x03\xe2j-\xb9x~\x8b\xdd\x1fl\x02rHy\x15\xd2\x97W\xe4Y\xfb\xc6J\x81:\x1c\x1er\x06k\xf5\x9cZ\x86\xe3\xa3<\xf6{C\x8c*\x1d\x8b\nUf\xb5\xaf6\xe6TN\x05\xd4\x96\"\x1e\x91g\xe0\xe8\xc5va\x04[\xd2ZyP\xc2\xb8\xaf'*\x10\xd3\x19\x99\x8b\x91\x86\xd7\xa1<\xd1\xe1\xab\x18\xca\x8c\xa5\xcf\xef\x95\xf0\x96\x8bI\xef\x7f\x194\xecN\xdf\\\xc7F\xe8|C/^\xb1\x84\x11\xb3\xc8Z\xcf\xbe\x81\xec\xccd\xaf\xa3\xbaG\x86\xe4)yI6\x8dh\xadrM\xcf_\xa0\xd7\x96\x18u\x1def\xe0\xa1\x82\xe3s\xcc\x13\xb7\xd6\x04\x92\xf7\x08%\xe7\xbeg5'\xc0\xda\xfa\x9e\xda\x03\x0d\xc8\x98\xa4\x03rI\x9e\xb6V\xa45\x159\xc5\x01C\xf9\x89\xe0~\xd8/\xeej\xff\xac7\xb5\xad\x95\xf1\x82\x8d]\x03a\x16\x17\xe4\xa4?\x1cf\xa8\xd1A\xc1 :\x90\x16g$+\xcdH\xb6\x04\x9b\xbe\xd2$\xa84P\x7f\xd8<5]P\x03\xb5\xa8\x8d:0\xb1\xb8\xa2[\xca\\\x84\x00\x04\xf8\xe6\xd1\x06\xe5R9\x0b\x8aj0\xb5\x10\xb0\xbe\x81\n\x01\x9a\x9e\xb9\xe9\x0b\x90\x9en\xd4\xc5\x87vs<\xce\xc9MF\x86\x8ae_\x03\xeb\x81\x93\xbfn\xc4\x07\x94\xf1\x0e\xea\x93PN\xc3tFhG\xc2\x84\x8a\x85\x0c\x16\xa7\x93\x1c\xfd{\xa29\xf5\xb0\xbb\xc7Q\x9b\xf0\x10\xb5\xd9\x93\x97$l]\x89/\xce\xb5\xb1[\x05\xdb\xf7\xc3\xe1\xa0\xb5\xa0\x1e\\\x85\xeey\xac\xdf\x90\xde\xfd\x81\xa5\xc2\x8f\xb6\x1f\xb2\xfc\xf5f\xa3\x0e\x13\xac\xe4\xbd\x92\xc84\x11\xc8Y\x17\xab\xeaA \xeaaa,\x01\xc9\xf3\x91\xbd\"{\x14\xce X\xed\x9e\\\x92\x10\xc2\x11\x15\xd6\xe2~@fd\x0f\xd4,D\x81m^\x98\x0d\xa8/\x17[T\x1d\xe3b\x0b#\xcd\x0bP-TS|\x17\x8e6\x8cO)\x94`b\xb3\xa39\xe9\xf7K\xe8\x10\x97\xd0!^\x02`\xfd\x12\n\xc4\xcb\xc1\x00\x03\xa09IZ\xfb\\7\x8b=~\xabXc\x03+\x9fLGpW\xe7\x0c\xaf\xa6l\xec&-!\x97d}A\x92C\xb1\x0b6\xf3d\xa9/eE\xb0\xfa\xdbt6\x04\xaeA4SC\xf3sSE\xf3k\xf6\xd0\xb5k\xedtf\\\xfd\xdb\xc9Q{\x14\x93\x98\xcf\xd1\xa88c\xa0A{\xfa\xf4\xd3:\x8dF\xc1\xb3\x03\xde;\xdb-\xa2\xc8\xf1x}\x18\xe8\x12f\xc7K\xc7\x8a\x0dH\xf9\xc0aT>~\xb8\xaa\x9c{v\xe4)y\x99\xa6\xa0\xc1\x9a\x19@\x84g1\".wue^P \xed\xfb~0\xca\x97\xa8\xd5K#\x11\x8f\xbb3\xbf\x02\xa0M\xf1om\x9c\xdb&\xa6T\x190\xc5\x1b\xe6\xd3\xa5=\x1d\xd2K\x0b\x17\x13\xcd\x97\x16F\xac\xd6s\x93\x90!\x01Z\x94\xcd\x93\"}\xb2\xe9t\x9e,\xdd\x8a\x83\x12\xf9L\xff.xd\x99\x17:\x0cJ\x0eq\xbf~F\x86%9Gm\xd8\xd3V\xce\xf4\xec\xbcE\xee\xce\x80N>zD\x9e=G\xc9\x1b\xa4\xf0\xe7\x07\xa4pX jEN/HF.I\xea<|\xac\x88\xd8\xb5Vm{O\x11B\xda\xd8\x1e\x01\xbfrVT\xf5\xab(\xef\x9a\xfe\x93\xbe\x8f\x1b\x80G\x8fH\xff\xe4\x84k\xbb\x10-\x13j\xa1\xac\xe3b\xd8\xf1\xe6\x85\xfaaR\xdb\xa0z:}\x14N\xda\xe4\xcai\x90\x0b \xf5\xf9\x90s\xa9\xf4y\x9b\x90\x86\\9.\xa3\xe6\x80\\\x93\xb1\x12\xa8\x0dzE\xae\x89\xe6\x15\xf4\x02)\xe0\xd9S\xfd\xack\xe0\xe4\xb2\x84\x07\xf5Zlc\xbc0Z\xf5\xce\xc7\xad\x9d?N\x0e\x8d\x0f\xadD\xf0\x83\xa8F&_&c\xd7\x1e\xb3e\\.\xc9\xb3\xcf\x14ZF\xe4%y\xfeic5\xa8em\\b\xbc\x1d\x08b\x15=m\xa0\xa8\x1d\xdegj\x0e\"ry\xa5\x80i\x13\x9e\x9e\xa1\xee3R\xb0?{a\xa2\xa6\xb6\x88\x16\x16\xb4\xda\xd7\xa6\xe3\xf7B\xa9\x07\xa2\x87yj\xa7\xd7\xb534p\x87\xd9\xb2\x9b\x19)\x01c;\"\xf7#\xb2\x1a\x91\xb7#r;\"_\x8d\xc8\xdd\x88\xfc0\"_\x8e\xc8\xcd\x88|\xe1\x10\xe1\x00\x15\x94\x08\xa9q\xd4(\x14\xb6\x8e\xbc\x0d\x1a;=\x89\xaa\x12^\xaa\xa4\x95lB\x03\xd3\x96Q\xfe\xd0\x8dO\xe8B\xaa\xb5\xbe\xcf\xed\xb7\xef\x8aV\xb8gG\x12l\xace\xb6\xe4\x1a\xef\x017\xafV\xd8T\xa2\xffj\xad\xd4\xd07\xca\xd5<\x911I\xf0~fg\xfa\x1e\xf35\xe3l\xfd6\xf0S\xd1$\x97A\x9e\x19\xd972\x82\xdb\x87KlJz\xed\x08\xea*\x0b\x02&Z!\xfdpx\xac\xc9\xd2[\xbd\x07\xbak\xdb\xf7\x81\x81\xce\xe0\x82\x9c\xf4O\xfa`\xb6\x836\x98\xb0\x81\xea\xdfW\xd5AkD[K[\xe9Rkf\xee\xc9\x98\xac\x958\xf3\x0cX\xb6*\xadPhG.\xc9\xb4\x94\xa2\xa4\xa8uQ~\xa7\n?v\x9dg\x1b\xc6\xce\x17,<0\x80_}\xc8\x00\x06\xd5\xdd<\xea\xc5\xc0H\xc1\xec\xf5\x0b\x08\xbdq\xec6\x8a;\xf1\xfb\xeaN\xbc,\xdd\x82e\x965\x808\xab\xefU\xb4}`\xd3\xc6\x00\xf7\xa6y%j\xaf\xfe\x16f\x11\x88\x99\x1a\xf5\xb7Vn'c\"\xc8K\x9c\x14\xa7=X\x15\xba\xa0\xda\x9b\xb4\x08\xaeW\x83v\xf3\x80\xa9|\xf0&\x050\xbd\xb0'\xf9\n\xb7(tD\xee+\xd2:\xd1\xa6xj\\\x8a\xa6g\xf8~\xbc]\xde\x8d^\\?\xa0\x82\xe1KrE\xee\xec.\xe8\x07rI\xbe\xbc ?4)\x18\x14\xe9\xbd\x9b\xffP\xb4\xe3kW.\xdc\x1cP,4+\x15\xea\n\x05\xd5\xf8M#\xc7W_\xb7m\xf2C\xce\x08)HAg\x83&Eo\xeev#\xe7{\xe52\xee\xe6C\xb7\xa4\xb0\xd6\xf7\xf6\xeb\xad5\x1cXuAB\xc5\xaf\xca\x1c\x04q\x91T\xa8\xf5\x831\xf4\xd6bdn\xc7\xa8\xa4\x8cG\x8f\xda\xcd\x0cHY\xf2G\x1c\x07>?$\xe7\xf5q\x03\x9c\x8c\xf4\xde\xe8\xdc\x08\xcc%\xe6L\xc6\xe4\xbc\x14\xb7\xd3f\x98GKcAevi\xb9\x851\xd2Y\xad\x08\xca\xf3\x0bm\xc6\xd9\xcf\x13U\xcb\xcb\n!+\x14(\xa4G\xe8\xd8\xbc1k\x97\x82\xa1\x7fO\x9b\x8bv$\x08\x99\xb6g\x1b\x92sT+\xf43\xb3\x0b\xf4\x14\x17x\xfe\x99{\x08\x87\xc3lPVDd\xc3\xa1\xc2m\x16\xed'\xe6VCjn\xae\x94\xd2 \\c-\xeb\x84\xb3\x8d3?~\xd0\x85R+\x9a\xe3\xf1f\x80\x0b;S\xcb\xb8\xa1\xcey\x0f\xae\xf0\xa6Km\x1a\xd9\x8d\x04\xda\x9b\x19o9\xdb0\xce\"\xafY\xbdIW\x8a\xda9\xe2\xe1\x1f\x14\xa9\xe2*?\xae\x1d\xf9\xd1\x03RTI\x10\xcd\x06d\x8c\x82S\xf1\x08%+\x0b/\xc3+\xf2\xac.M\x15.\xa2\x14\x1b(1~C\xd9\xec\xd7\xe1U\xedx\xc7\xb6;.}k\xd1\xe0\xe6\x82Z \"Z\x86z\xac\xa1.\xf6\xdd\xaf\xf64\xfe\x90\xd9}03SR\xca\x07\xe9\xbcL\xea\x07Q\xe7\xe3\xe8\xf2A\xad,\x9c\xe8\xb7ka\x9f>o\xd3\xc2\xe2\xb5\xb5\x03\xd5\xe4ZW\xb3\x16\x1cd\xe6\x82<}\x9e\xf3`P\xce\x82\xca\x94\\^\x91\x17\x17\x03\xe2\x83\xf1Wci\x17\xd5;\xe9\xfb\xe4%y\x81\x10\xea\xfa\xb4.&.S\xb5\xd4\xae1kg\xd8OG\xe4\xa9\":\xf9\xcd\x90\xfa\xf7\xe7\xea\xbb\xda\xfae$7\xcc\xac\x01H\xf3\xcb&`=?(\x08DG\xeas\xf1:W\x13\x8d\xda}\x8bX\xec\xb8\xc9\xfd\x11\x94\xbev\x0c;\x02\xebG\xaa\x9dv+\xa8\x9c\xc6CH\x1fm\xc2r\x084\x18\xb3\x07u\xd1\xdb\xf9\xc1\x1a\x1ci\xcd\x97\xb5\x0ev\xec\x97\x99\x84&R\xd26\x0b\xbf\xacZ\xdd\xa4>\xc4\x12pd\xee\xe1\x88F\x8bV{\xa7K\xcb\x10\xcd{GG\x86\x8aa\x8e=\xe0\xe8\xf7K\xec\x91\x96\x88\x1a\xd5:|\xbfH\xc8\xe8R\xcb$\xfdg\xcf\xf3\x8b\xb8\xb5U\x17#mz\x81:_\x8eE\xe2\xf2B\xee\xc7x\x17\xc6BQ`\xb31l\xd7\xfcb\xb9F\xb5^\xe1>\xdc/\xb0\x9cM\x17\xb4\xbe\xe9\xfca\xa8\x7f\x00\xf7:\x82|\xdc\xa2\x06V\x9d\x1f\xbd|\xdc\xe5\xad\xa8\xea\xbf\xf2\x12\xef03\x87W\xfc\xe0# \x16\x85;\xdfg\xe7\xd5\xbb\xdd\n\x81O\xdf\\\xf6\xe7:x\x9fvu=_\xa4\x8b\xd3\x97U\xd7n>f^\x9c:\xb2\xbf\\\x9ev#4#B]\xb4&?\xa0\xa8H\xc5\xb5\xa1\xab\xd8o\xd63$e1\xba.\xbbxJvMF\xe4$\xdf\xdc\xedD\x18\xb4\xca;\x89\xa2M\x8apx\xb0[zyu\xc0<\xf4\xc5\x99{\xeb\xe4\xb5\xef<\x9f\xe2\xa6\xae\x9f\xb9H\x97\xa7w\xae\x8a|a\xbe\xaci_Y8{._rz\xdfv\x1c\xf3\xecS\x00\x1a\xa4\x96\x93\x96\x1b)\xe6g.\xa5<='\xb2z\xf5\xc0\xfc4\x18`t\xf9\xf9\xa7\xaaf\xa1d\xb7\xe9\xf9y-\xfb\xfb.\xdb\xdeg\x9f6\xf7\x9c\xd8c\xa5\xeaV\x11-a\xd1\x95\x9e?(\xb6R\x87\"W\xd2\xb5\xd7\x13\x0f\x0eC{\x82h\xc0\xe7\xe9|Zq\xd6\xb7o\x0b\xd5m\xfcm\xc6\xa1U\xb5\xb3e\x1c\x9fx\xa8\xfe\xee\xa6\xf0\xef9\xfc\xfb\x14\xfe}\x06\xff>\x87\x7f_\xc0\xbf\x8c\xae\xb1\xd4\xce\xc2\x03\x1e2z\xfe\x86\xd3P\xbb\xc1P\xff\x86\x14>\xc6\xe0\xd9\x0f\x9e\x00\xd28\x13I\x06\xef\xf09A`\x12\x1eo9K\xa1\xf3\xe8b\x12\x9e\x98g\xe0N\xc5=\x8e\xa6\xf1\x11\xd1\x13f\xd8\x04tY\xb0;A9\xa3\xf0\xbc\xc1\x0b\xaf=\x01~'\x04\xc7gF!g\x06p\xec\xfd5\x8b{\xcb\xc9&\xe6_Qo\xd7o\xb9\x808g\xcb\xf2\x0dP\xad\x95\xfa\x90\x1b76\xb9\x8b\xf9\x8aCr\xcc\x95)\xb5u\xc0\xdb\xb6\xecv\xf9\x16N\x8e\xc1BdL\"\x97\xb7\x88v\xf6\xdc\xf5\xcau\xd1\x8a\xa0\xce\xc8\x04\xb2\xc9\xc2];\x17\xbb\x0bJ[]\xe4\xd8Am\xd7\xd0RA\xbf\xa4\xfa\x08J\x12x\xb0,\x9f\xcc\x06\xcd\x14\xd7\x87\x0b\x1d\xa80\xd6\xbb\n\x87J#\xb7\xfb\x81\x1b\xbfZ;\xea\xb7\xd6J\xady\x030\xef\x1199}3\x1f\xcf$Y\x0e?9EW\x9b\xb4]$\x80\x1b\x08\x14C\xa9\xf6{\xb2\xa7\xf6\x1f\x10\x03\xb5M\xad\x92\xe8\xeb\xe7)Z$\xa6\xe4\x92\xe472[no\x9f\xc0\xb9\x947O\x97\xe6\xdaH\x1b\x9fE\xff\x05\xa0\xb8M\xe1\xd1+\xb9W2\xd7\xb2[\x05\x83\x83\xde\x98\x89\x01\xed\xf4\xcd\xecz<\x9c]\x9bq[\xb7\xb3\xdf\xe7\x9f\x01H\xeb\xd2\x81Y \xbek\x92 {se=S\xdf{\x18b\x0b\xce\xbe\xb8\xbf\xdd\x89\xde\x80\xcc\x9c5\x9f\x15\xaa\xeb\x05l\x839MB\xaf\xed\x06\xb7\xea\xdc\x18w\x0c\x05tq\xdc\xdb\x81\xb9o\xc1\x14D\x14\xeb\x9d\xed\xcdB\xca\x85\xfc\x04\xfc\xb3\xf5\x06\x05\x04\x1a\x91\xc4\x8c\xc3Ia\xd2Z\xeb\x8e\xdb-_:\x8a\x0b@\xe8\x0f\x98)\xec>\xc4L\xa1+\x1c\x8ao\x1c\x80C\xc1\x00\x8b\xf6\x97\x84\x83\xff\x92@4/\xfe\xae\xe0\xed\x9a\xc0\xa3\x81\xbf\x8df$\x99\xa7.\xc0>\x02\xec\x1d!<\xacw(\xd0\xb2\x8f\x00\xe9/\xa3W\x10\xbb\x87\x1e@|\xc0R\xe4\x0fm\xf3\x88n\xa9U\xf6\x8b\xb7\xa2d\xc6\x03\xcbh\x0f4\x05\x8f\x0b\x1fDW\x8c\xa0r\x8e\xdb+}\xfb\xa7Efy\xf4\xc88)\xcfiz\xe0\xa6\xe9p\x83\xbd\xd1\xaa\xa6;Q?4^\xa4\x0b\xdd!\x87F\x83|0q!\x058\x1a\x8909DdHW@7F\xa0\xc9\xc3\xf3+Q\x0f\xc4\x15\x95\\e\xe2p\xabrD\x9a\xf2\xc0{Y\x8a\xa8$\x91Y1\xc5j7\x8f\x19\x97F\xb2F\x8a\xa4\xad!\x8a\xca!\x8aE\xda\xa8\x16\xe9\xb8\xf8Hi\x12\x9b\xd689\xb4\xce\x89\x83\x8a\x11\xd8\xa2to\xbe\x99\x90\x91n\xcd\x97W{\xe9\xcdn\xad\x8e E\xbf8\xc1\x03!\xea\xc1\xad\xec\xd0\xfcj\x8f\x7f\x82QI\xed\xf3a\xea\x13\x9b\xdce\x03\\\xb0\xe2\xea|r\xedw\xd8\x06\xc7j\xd3\xe7\x1b\x13z{M\xdf}\x18d\xees\xe8\xbd\x1c7\xc5b\x14\xc7#\xd7\xe9\x8f\xce\x12\x95\xda\x89*\xe3F~\x91}\xb6\xb5\xd6o\x15\xd0\xfb,\xf7\x08\x06\x96\x85\x8f\x1e\xd9\x89x\xe9t\x9d\xb7)\xee\xc3\x8d\xaep\x03\x05\x87\xc3\xcd\xc1m\xbc\x9d\xb3\xcdQ{w\xdf0\xc6\x8d1\x81lm\x03\xd0\xf9h\x9b,m\xa7\\4\xfb\xeb\xbc\xd2\xd6\xc1\x01\xb9\"\xf8\x90\xbdJ\x866\xe9J<\xa8\xf8\xafc\xb3\xb6K2\xf0\xe9^\xdb\x0dn\xb5\xd1\xed\xa1\x1e\x91B\xaf\x1a-\xedIA$\xceF$\xfb\x10\xb6{\x04@\xdd\xb8]A\x03\xac`3\xd8Z\xf4\x8d2m>J$\x1d\x8f\x13I\xb7!\xf8\x98\xfcs\xddlKK\x0e\x11t\x82\xfc\xd3\x89'$_\x9d\x07A!\x05pZe2\x92\x8f\x8f\"k\xf3\x8d\x1b\xf9m\xd6C\xa8B\xf4x\xe1\xb5\x1b}\x9d`\x0d/\x86\x86\x8d\xf4\x89^a\xa6\xf7\xc5#>\xba\x1c\x81\xd2\xa0j)W4\xd9gE\x1f\x89E\xfb\x03\xd8\x12\x14\x13\x14M/\xdd\xc5\x18\x91\xf6\xab\x08\xb9\xb7b\xa7\x91\x1bu\xdfF\xd8\x82\x81\xd1\xbd\xb9\x8d\xb0\x05\xb0\xf4\xf15=x\x1b\xa1\x08\xee\xbe\x08`X\x83oW\x1d\x8adT\x1e\x8du7d%%\x0ciCX\xd2\x05i\x89\xd9F\xa0\x18\xb2\xb1\xfdW\x02\xfb\xcb\xfc\x02^\xd3\xb1\xe2\x01\xb6s\xb0\xac\x83\xf9\xb4\\\xf8\x03\x1a]_x\xb5\x14\xe4\xa5/\xdb\xee\x0f\xfa\xda-\xf0\xa6\xc8j\xb3f\xb7T\xa5\x8e\xd6<\xe3\xb4\x95\x82\x8d'\xd0\xc9\xc1a\x90J\x17@\x1e=\"t8\xcc/\x88t\x01\xadn\xec\xd3\x06\x9a\xef\xbe\xfdP\xca\xfc!\x92\xf8:x\xb8\x80\x1ch\x94,H\xc6\x9b\x11\xb9\xff\xc7\xfd\x04\xe7\xfd\x04\xef\xa3\x1d\xba6\x8a\xcb-\xdb\x87\xe2\xfd\x04\xb7\x91\x9a\x0f\x1e\xb6.\x8d,\xaf\x8f\xc5\x07\x95s\xf1\xd4\x11=\xceZ\xf37\xde\x14\xcc}\xce\x0fP\x13\x12\xd5\xaaE\x9dH#\x19*\xe8\x90R\x971\\\xdb\x0d(\xeb\\O\xc9\x7f>^\xba\x82%o\xd51>\xb9$\xf4\x82\xf8m^]\x88\xa1Is\x1f._\xa5]._\x99_\xdc\xc1\xbb\x0b9\xe8\xe1\x858i\xa9\xf9\xe9\xcdM\xd7\xfb\\\x9aN\xe0j*\xda\x0c\xa4\xcd\xd2b\xbe\xd0\xd3\x11\xe1f\xf1\x15\x97\xca\x01rSYzu\xa2\x03K\xc9\x1d\xf5\xa8\x8b\x19DY\x8c\xaaQ\xac\x8eP\x1eV\x96\xf3CMw\xb4\xc1\xfb\x85\xec\xef\xf2an\"\xeem\xe3\xdc6\x86\x1f\x8d\x88\x1d\x8e\xb0r\xfe\xf4\xb9#\xc0J\xd4?\xff\xb4\x92L\x1b\xe2\xae\x08vgbc<\x9d\xba#wD\xec\x16\xa7\x1as\x9d\xbbs\xb1\xd4\xa3\x89\xcd\xf4\xd4\x9diE\xbd\x1b\xe1{7&\x8a\xcb\xd3\x86`!k\x16\x98\x1c\xcf\xdd9\xfc\xc8\xd6\xf1\xc2\x9d#\xa4\xdc\xc4\x1ay\xda\x10Q\x86\x85\xc9\x8e\xa6\xbe\xad\xe93w\xb64[\x99\x1c\x9f7\xe5Ht\x8egg\xee\x1c\x81\x1f\xd9^?k\x18h{\x95\xc4\xac-\xcc\xdd0\xe0\xc5\x8b'&k\xc3\xb0S\x1d\x1e\xc8dk \xd1\"\xa8 \xe4\xf2\xaca\\Y$|qo2}\xd6%0J\xf6Q\x02\xa3\xe4^\x90\x9c\x81Q\xa8 \x8cB10JE\x11\x0c\xd9\xf7\x18\x81\x99}\xebG7\x8a@\x17\x16i\x1d\xea\xb4n\xe9\xb3\xb7\x81t\x91\xd8\xb7E\xcc\xd5\xbc\xc3\x1c\xc6\xabb\xbe9z\xf9J\x8d\xa1\xafXI\xf1\xf8f\xd63\xf1hU\x89\xb9\x0d\xa6\xdb\x1b\x15\xe3\xed\xf6\xc0H\x0bM\x9c\xd6T\xd0\xde\xd2\xd6 \xcc\x11\xce\xac7\x98\x9f-]\xe6:Y\xc5\xe7\xf5kE*[=\x86C\x9fG\xc6KLa\xd4KQ]j\x88\x02\x8ez\x8d\x8e\xac\xf6\x15u\xafI\x9c:4y([y\xd4\xdb\xb1\x7ff\xa2\xef\xc3\xe5\x97\xb3\x01\xe6W\xe8R\xd1o\xb9MP1l\x03b\x8f \x97$\xbe \xa2Mx\xe2s\x01\"\xcbI\xc1g\x08\x04\xe2\xd2\xa0\xfc\xa0@\x19!\x10\xce3\x86$N\xf1\xdeb={)w>\x17\xefG\xa5\xe90\x1b\xfd\x8e\xfe\xdb\x0fNIy\n\xf2!G\xf7\xf40\x98\x97\xc4o\xd6\nF8x\x91q1s\x02\xc3\xc9\xe7\x11\x8e\xd3t0\xc0}\x84{W\xd6\x18\xe8\x187z\xaa\xf5\x97`\xef\xd4z\xbb\x9dM\x12\x16\xad\xfdh\x8b7\x04S\xee\xcd\xf5H/\x1b\x06\x95\xe0d\xe8R\xa0\xf7P\xe4\xe1;L\xe8\x0f\x9aF\xff\xd8\x802\xcdaO\x1ct\xc7\xeap\xfcF\xa7\xdc\xd9\xaf\xc8\xb1bB\x9dd\xf1:\xc2\xa4\xb7\xbe\xf0v\xc4mw\xed\xd1\x94\x91\xe9\xd9\xcc\xfd\xe1\xf3\xf3\xa6\x0f/\x1a>m\x1a\xad\xa7\x9f65\xdf4(\xd3\xf3\xc6\x91o\x82\xebE\xd38>w\x8c\n)\x98\xd29vbk\xb6\xa1Y \xda\xcb5\xf9S\xeap\x94\xd5H\xec\"\xcb.\x80\x1c\x192\x06T\x89\xd7]7G\x83\xc1\xc5@\xd1&'G\x8e\xf4e\nE\x82\xd4\xb6L\xe8\xbb\xe2UJ\xa3\xad\xf4!\xa3Z\x87\x83Q\xce\x82\xca\xf6\xe2\x1f \xe2w\x1e\x8b\xaa2\xc8\xc9;\xa7\x0d\x17E\xe2v[?=\xbc\xd8\xff\x82\xf1\x81\xd1#\xe1h\x8f\xc8\x89p;\x9a\x85\xd3\xcb\xb3\xd2\xf5TSYyV\x9c\x88ck\x98\x1e\xacA\xbb(9\xa0\xc6\xb0\xf4\x19U^>\x9eS\x12\x7f<>\xac\xb9\xb0~\xd4\x1c\xcd\xfb\x9d\xd4\x189\"\x15\xab\xc9\xedE\xce\x14+\x1e\x92iC\xe8\xd9\xe2\xefC4\x1d\xec\x90\xfe\x9d\xe4[\xe1\x1d\xe5kh\xabE O\xdaw\xbd\xc5\xdf{\xf70\xd7Xzi|\n1SG\x87\x81\xd7\x80\xa7\xf1F\x1c\x02\xbc\x03\xd0N\xa3\x11\x0d\xeb\xc1\x13\xb7C0\x1ch\xdfiv\x17\x0f\x87\xe8\x19\x9a\x93\x96;\xdf\xb1\xa2rq\xe3\xfd\x1b$U\xf1\xc7RF\xd8\xa5\xc5\xb59\xb8\x0e\x9c\xa2\xc0<\x7f\xfe\x02\xfdP\x13\xbd\x19;+\xf4\xaa\xb7X\x9c,z\xbf\xfe\xe4\x9f\x1e=\xee\x0f\x9e\x0cG\x93\xd3\xd9\xc5\xe5\xd5\xcb\xeb\xdf\xcc\x97o\xde\xfe\xf9g\xf9\xfe?\x8f{f\xe3\xd2\x1bt\xbboQ6\xb4Z\x92\xabb$\xa9\xca\xe5\x8b.d\xd5\xd2\xd4\x96\xad\x8a\x92\x9bk\xa4\xf3\xf3\x06\xbf\x8b\x07(\xeep\x18\xe3\xc5\xdf:j\xf9\x8d\x8e1\xf1\xb6\xf0\xf9\xf3\x17\n)\xcc]\xb0(\xbf\x88\xd0\xc4\xc8\x8c\x8fg\x85\x10\xc3+r>r2w\xcd?\xb4\xc3J7\xca\xebM\x15\xf8\xf4\xea\xb6B\xbb\x90\x96N+\x14\xa2\xf2 \xb6\xf9\xc7/\n\xf3k]\x1c\xb6\xb1_5\xbf5\x0fuo\xb1\xe8\x99aV\x1b\xc1\x8f\xb3\xea\x8eE\xe4\xd29F\xb3\xa0\xa0c\x89\x1c\xe3*\xc8\xee \xb3\x11\x01\x0f=\xbc\xb4\xa1\xcc\x0c\xb5\xfa\xfcE\x93+\xa1\x8b\x81*\xe8\"w\xa4,rE\xe8\x12\xc3\xd7\xc1_\xb3\x0b\xb0\x84\xac\xdc\xa7)D \x81\x93\xbf\xe6\x8d,\x85sx\xb8\xceH\x0fAIU=\xd4\x85>>\\\xc0\x19+\xa8\xae\xf2\x00\xb6\xe5\xc5\xd7\x85_4\x84\xed!\xa4\xd9i\x85_\x08\x93?'\x8bh9\x04\x93]\xd2k7Q1\x91|\x9a,S\x0e1\xa6\\\xde\xa5\xb5u\xd2uU\xc4E\xca\x93G\xfd\xfd;Z\x1cJ\xb2\xadu>m\x91\xb1\xcf\x1b\xd6N\xdaN\xf2\xdb\xed\xd7R\xf4^\x06w\x91[\xb257\xfe\xcb9\"\xf3u \xce\x94\xbc$g\x18\\\xa0\xda6\xd8.\xcf\xc0)\x96\xd3\xa7\xb9\x82\xee|0\x02\x03\xca\xab\x83\xd7\xdcL\xaef\x9f\xe7~\xee\xed\x8c*\x9c\xd3|\xab\xb9\x00\xd0\x01\xaeC`\x9ec\xdc0\xb8\x99n\xda\xaa\x81\xcc\x15!\xa8\x05\x0d\xf3\xd1\xa74T\x93\xc7O\xb2\x08\xce\xc9\x98\xa4\xa3FF\xacWt:\"\x1c\x0f\x89\x1c@\x9a%\x97\xe2A~\x8c\x8e\xe4u\x0b\x10>.k\xf4v\xdd\xd8\x19TC\xb6\xf6\xd7\xb6\x80\xceH\x9c\xf7\x161\x0f\xda\x0dY[Xj\x96\n\\\xd2T\xc3\xea@\x11\x9b\x01\xd1\xc4\x82b\xef?\x9a\x8d\x17\xbc\xd8P\xa8\xd7$\x1e\x8f\xc9\xcc:\xc1/|\x84\xe7\x18\x1d6]\x82\xa7\xe7&\xa1%\xfa\xc0\x18J\x04wSxjou\xe6}\xd6\xc1\xd4;\"\xd7zF1\x06\xaa\xd6%T\xe6\xd8\xa2K\xbb\x15\nk6 m3\x8c{\xef\xf6\x98\xd6\xb6\xcb*\xb4\xf8@\xc3\x97\x02\xef\xb0\xdd\xd7\xd6qv02P\xa2\x90Y\x01\xe7A\xad\xfco\x963h\xdf\xfd\xff*\x8c\xa1\xb1\xed\x7f\x13|\xe1\xd9\xd3\x0elAg\xfa[p\x85g\x0d\xee0\xdb\x98\xc2\xc9\x95\xae\xe7\xef\x8e-4\xf5&\xe7\n\xad9\x8e`\n\x1a\x0b\x1f\xce\x13t\x05\xff` \x9dX\x82\x1f\xa5\x7fc\x96\xa0Z\xfc\x07K\xa8\xfcZX\xc2\x8b\x06w\xc3\x7f\x0b\x96\xd0\xd8\xf6\xbf \x96\xa0\xdd\x9e\xb5\xb3\x04\x9d\xe9o\xc1\x12tS\xffNXBSor\x96\xd0\x9a\xe3\x08\x96\xf0b\xfa\x81,AW\xf0\x0f\x96\xd0\x89%\x84\x94\xdf\xfc\x8dy\x024\xf9o\x8c)\xd8\xe46\xd3 \xb3f\x89\x0d\x00\xc50\x00\x14\xa8\xfaT\xea\x8b\xe76\xf5\xf33\x9b\x8a\x9e\xe9X\xd53\xdd\xd1Q\xb9\n\xfeR\xeb\x03\x9b\xa1-}-=mH\x0fZY\x98\xe7Z\xc6\xc2u4\x85\x97\x0c\x1a\xc8\xbb\xc8\xc9;\xeaZ\x03\x18\x89j6\x8a\xa1\x95=\x97\xaaU\x0f:\xdc\x16\x81\xd2`5\x0f\xf7\x9a\xfa\xa8\x10\x1e\xeb\xab\xa7\xcf\xc85\x8c\x02\xf4x\xaa\xf0\xe3i!\x9a\x1f\xb6\xee\x80\x91\x16U\x10H%bt;o\xda\xd1\xd5D\x85\x1c\x91u\xe1\x0c9>G\xa7\xb0\x1e\xc0\xc7\xfb\xda[\xad\xad\x80\xf7\xe3\xdc\x15\xf3\xc9t\xa0\xd0\xbc\xbe|<\x1a\xc1J\x9d\x91\xcc1!4\xc25\xe5t\x07\xbff\x81\x1f\xa63\xe27\x10\x97\x07\xd8Z\xe4RO\xf5\xdap+\xe2l\x9a\x0f\xce\x12\x17Nm\x06uF\xa9C*&\xb0\x01\xc0\xb1O>@\\\xfb\xbb\xdcW>z\x84\xfd\xd3s\xa4\xbax]7\xb7\xb0\x01\x05\x90\xad\xa3C\xea\xd3\xfe\x1b9\x7f\xb3X,\x07\xfd\xc5b\xb1\x18\x00\x83>9\xcc\xf9U\xb6(?K\xd5\xb1\xf8\x80\xcc\x18s\x08\xe3\xdc\xd4\xde\x07}p\xfc\xe1\xc0O\x9du\xe0\x87+2_\x0e\xcc\xee\xac\xfe\xbd\xe0V\xd4E\x0e\xe2\xc3\xe8Xv\x0cR\xa7\xcb\xeb\x87\x84\x8d\xac\xac\x1b\xdc=\xd6\x1c\xa1\xba\x17S\xbd\x93s\x7f\xa9\x06\xaf\xde\x03\xa8p\x96W\x9d&\xb8\x9d\xa9H\xfe\x95%ZXCqm\x07\x90\xd9\x08x\x1fc1\x1d\xbbhJa/\x9b\x17M\xcbU\x1d\xc5\xba\x9e\x92\x97\x07\x8c\\N\x1c\xf8ZM\x83 \xd6\xad\xb54EGo\xb9\x16\xd4\xa60\xc8~9K#k\xa7\x93\xe5v:\xf4\x82\xf0\xe3\xa3\xa3\xf3\xc3\x81\xd7\xa6\x0d\x02}\x87\xa2M\x81\xd5y\xf7\xc0\xeahG\x04\xfd\xd4\xe4\x8e\xab\xe1B\xd7\x8a}\xae\x96cT\x11k2\xe3\x05\x10\x05#-\x12\xe1\x1c5\xc65\x8f\x96\xcd\xe4\xaf\x1bMk\xaf\xfc\x12D9\xad\xaah%|\x0e\x82\x11\xbb \x86\x8e\x98\x1e\xb9\xb4\x08Y$f\xe4\xacN8\xda`\x84\xa8\xcd3\xe2\x82\xb1\x94\xb1\x99~\xcf\xe3\xe5\x04\xdan\xec\x08~\xd6\xd2\xc7\x87R\xf2\xd8\xc1\x80\xb3\xd57\x0f\xa0\xf1\x05\"\xcaK\x04\x94~\xc4\xc0\xe4\x05Y\xe4\xecY\xd5u\x99\xd1\x99|\xe6\xd0\x99\x14\xe2\x8a\x9e\x8d?\x9f\x9c\x80\xf2\xf4\xc9pqzum\x15\xa6\xc3\xdf\xe49\x96\xfd\xebY\xfe6^\xfe|6z1}_\xf8>\xb8\xee_\xcf\x16\x93\xa3J\x0c\x9e\x0c^\x9e\xd6\xf56\x05\xd8&\x8b\xf1\xf2\xe7\xe9\xe8\xfc\xf9\xfb\xc1\xac?\x7fs\xf9rqwv6^\xdc\x9d\x9f-U\xd9\x87\xf3\x91\x92n\xa7U\xc2z\xd1\xa8}\xd0\xd4\xa3_\xa5\x16\x9b\xa2\x13\xaa\x97\xbd\x82(\x04\xaa\x90H\xab\x0f)\xb8\xab?\xe9s\x9b9\xab\xc5\xa1,\x94U\xbb\xa1l~\xb6\xd4\x8dL\xf5\xd5~\x0f\xac\x08\x02\xb5\xe7:\xb1\x02C\xd1/W?(\x8ba\x1dd\xef\xd6\xfd\xc3\xc1]Be\x1d\x1c^\x96\x02|\xe69(\x8e\xd6[\xba\xc2S\xb2\xaa\xe3\xc3\xa3[\xed\xb2\xcb8\xb0\xb2\x87zF\xf2[\x98\x03E\xedN04i\x94\x874\xb5\x13\x986M`/\xa4~ b \x87m\x93\xe9\xfdc2K\xbf\x8f:\x99iu2?\x0e\x91.\xd2\xa6y\xcf\x8b1N\xe7:\xf6\xeb\x8e\xe8(\xa5\xfa\x0fD\xe6\xa4\xab\x18CwR\x0f\x0b\x99?>\x04\xd6\xf48\xfe\x05\xb7u\xf0\x17#\x94\xfa\x18\xffs\x0d>\x1d\xads\xbb\x8d\x80\xb2[\x16\xc3\x1f\xfdo\xb2\xd3\xd1E\x9f\x9ec\x04R\x81\xd9\xd4_(\xee\xd3;\xf8\xa3\x9b\xf6C\xfcW\xbfE\x1b\xa8\xc7O\xf0\x95\xfb\xa9\xf9;Y1f\x13'w\x89W|\xces\x05\xb7\xef\xd4s\xb0\xc6\nq\x19\xc0\x13\xf6-Lyb\xfeB\xa9P\xfc\x84 Y\xa2V\x85z\x8c\xd8-|\x8a6\xf8\xc7\xc7\x7f!\x16i\x14a\x7f\xe2\x84\xfe\x94\xb1 \xf6n`+\xa4\x92\x92\xd8DD\x85b\\\xa4\xf0\x9e2\xbe\xf7=\x86\x8fij\xe2\xa1\x9a\x81I}\xb6\xc7\x8f\xbe~G\xb8\xd2\x10\xffD!&\xc74\xb1C`_ \x0b\xfa\x84\xec p\xca\xa9\xfeD\x188V\xe8\x19\x12;?\x0dY\x9a\x82\x06\x8a\xf4D\xf4\xf4\xfc\xd33x\xc2\x16\x05\xccr\xc6\x01\xae=\x0bC\xe8/\x0e\xc1-\x86t\xbd\xf3\x10j\xf5w\x9c\xa5L#\xca]\x18\xf0\xc4\xb3`\x15^\xb1T\x88\xd3\xf8\xee\xe9\xe7\x93\xe7g<\x7fDd\\\xfbYx'8b\xe8&\xc1?\xf8 \xb1\x82j$\x16\x82z\xbb\x90E\xf8v\xab\xfe]\xb1tG1\xf4\xec\xca\x17^\xeccX\xde8\x80\xb9\xf6h\xa0g\xdd\xdb\xf1\x18\x83\xda\xe2\xd3\x98\xdd \x16\xa566o8f{\x16\x89\x15\xf7\x05\x1bS!X\xb4f\x98\x1d \x0c<\xee\x01\xa8u\x10\xd1q\x12\xd0\xfb\xd4\x8f\xb6\xda\xbf\xa3IR\xb9\xa9\x1f!\xea\xaf\x05T\xbe\xde\xaf\xd4\x1f\xb6>\xbfQ\x7f7\xd4c\xc2GX6\xcc\x84\xf9\x8d\xb6:\x84\xaf\x9f\x02zma*\xb7\xbe\xc0?\xef\xc28\xe1\xb1 \xc0\xbb\x154\x80\xbav\x1e\xae\x04=+~\x82\x7f\xb8^\x13\xde\x0b\xfd\x17\x97\x85@L\xfa\x91BK?\xe2\xdb\x0d\xbbO(\x16\x08h*60\xe0j\xd5\xe0\xa2\xa0[\x8dD\xa1M\xe17:%G\xa5\x10\xeb\n\xd3\xf1\x8e\x05zYE8wa\x16\xea8\xbf\xe1\x1e\xa0\x03\x19[=\xc4\x88; \x0dB\xfc\x9bPN\xdf\xbd\x03\xa4K\x02*L4\xe3\x84\xc7w\x10\x1f8I\xef\x01\xce\x9f2\xc6!\xc1,0\x96\xc6\x19\xc7\x95\xc5\x11iyz\x1fA^.\xf4\xb2a^\x1c\xad\x03\x7f\x83KL\xaf\x88t\x8bk\xf0\xe6>\xc1\xf4\x10\xa6*\x8d\x835\xc5\xc0\xc5I,\xfc\x0d4\x96\xe2\xc4\xa4\x82Q\x00+\xc5\xee\xa8\xd74\x01\xc7)\xb0\xc2\xa2-\xc0\x94\xad\xa1\x81,\xe2\x8c\xc2r\xcc\xc4\xf9\xd9\x19DaVx\xc6}D\xd0\xbd\xcfn\xc79\xf4\xb7l\xe5a\xf6[Aq\xf5\xdd{\xfe\xed= \xc3\xdd\xc6GD\xbf\xe3\xf0\xe9>L\xb7\xbc\xb7|8\xff( \xf9\x9f\x0e&\xbf\x7f\xfd\xea\xdb\xb7\xaf\xbf\xf8\xe7\xb7\xdf\x7f\xf5p\x01\xb8\xa2Eq+\x17+A\xf8I~CE+^\xc8Ic0}\n\xc7\x1aE3\x05\x14\x97\x9f\xea;\x8dN\x97\x0e\x06\x17\xa7\x15\x8d\\\x8a\xe5@u\x04\x98\xac3?\x9d\xbeW\x99\x1f\xce*\x8b\x97v\x1c\x04\xab\xc0\x0f\xeb\xfa\xf8\xa7\x9f\xb9\xb9\xa3w(Z8\xde8\xdd\xb8/\xa9<}\xee\xd6Iy\x9a}\xbai\xa6\xbf1f(9\x93\xf1\x0c'+\x1cI\xa0rA\xf1\xe7\xde\x1dF\xaa \xe6\xd3\xa5b %\xdd\x14\xb9&\xa0\xa1\xf8&\x12}\x95\xc1\xe85\x06#2}\x01\x01\xd6\x8b_Gd\x8aa\xb6\n\x97\x81\xfc~\xa4j\xa1}\xa0\xcc\xb4\xff\xe2\xf9\xf3\xa7OK;\xf2\xa0\xcc\xb6\xea\xc4\x1am6\xc0p\xa8\xb1k)2\xe9X\xf1\x01\x05J\xb5\xa7%\x98\xf8\\eY\xb6\x00\xe1\x14\x95\\\x0e\xec\x1e\xfd\xc2\xfe\xeb\xca\xb3\xac\x05\xb5\x99c\xf2\x95\xe0\xe1\xf6[v\xa7>\xfd1k\x88\xca\x01\x07*iC\xc4\x0e\x1am\xbf\xe3l\xe3\xdf\xcd\xd4\x8e$\xdaft\xcb\xc6.\xed\x8b\x1f\xdd\xf8\x9b\xfb\xc6\xf8*7\xaf)\xdf21sJ\x03\xe2>\x89!\xa8\x08\xe3\xee\n\x809\xa63\xd2\xfb\xeb_\xfe\xcf\xbf\xfe\xe5\xff\xfa\xeb_\xfe\x8f\xbf\xfe\xe5\xbf\xb8\xd4]\xfev\x17`\xfc\x91(\x0b\x1cJ\xa8\xfc\x8clF\xce\xab\xa7\x1c\xa5W/\x0e\x938b\x91p\x8e\xb5\x17s\xe6JW?\x9e\x05\x10\x8a\xa5\x07\x9e\xe4z\xa3<\xea\x8b\xda\x1c\x19+\x19|\x03\xc9E1\"x\xd7\x83\x88{\x1f\xca\x05v\xbb^\x8e\xaeV\xfc\\=\xd8\xa3\x0eA\xfd\xa0\xe7\x08\x83\xe8\x98mto\xd7\x05th\xbe72\xce\xf7\xd4\x06\xd9@`\x1aV\xcf;F\xd7\xc8 {;T2\x890\xb0}\x0f\n\x9fu\x90\xbeB\xd0\xa6\x91\x8e\xa5\xdb\x0dv\x1c\xc7\x83\xc0\x17\x02w\x94b\xa7\xe8\x00)\xc5\x00&y\\\x8e<\x14K5FH!\xc2\x87\x0dHR\x08\xef\x82\xbaP\x07\xfc\xbfr\xbf\xfd\x83,\x14?\xfe\xbb$\x0b-\xcb\xae\x0d\xab\xff\xce0\xc6q\x1d\xbe\x801\x8e\xaf\xff\xc0\x18\xf8=\x04cj\xe9\xe4(F\x82\x0c\xa1\x13\x0d\xfd8\xf4\xffCh~'0?\x94\xd4\x1f\xa2\xf1\xff\n4\x1d\xb6]\xf9\xd2\xe4\xc5}IU\x98w\xaffS\x0b\x83#&jf\x1e\xfez<\x8e\xeeQ?\xbf^s\x86\x07\x04\x943\xcc\xc5\x85\xef\xa1\xde\x97\xa6>N&\xcd\xd6>h=A\xc9\xbaZ\xfb\xf8\x07\x93|\x18\x99\x95\x1d\xda\x12:\xac\xe25\x8c&\xb6\xbc\xca\x84\xd0z{\x1a\xed\xf1D\xcb\xa3\x890\xca|\x16 T\xa6{~\x19\x9b\xbc8\xd0\x7f\xb6<\xce\xf0\xc4+W\xef\xe7\xa7]\x82\x1a\x1cZ\xe39\x18\xf3bNE\x8cZ}d\xe9k\xa6$ d\xf2\x1b\xd4\xf3\xfb\xf8\xdd\xc7\xc32\xcc\x05\xb5\xb0\x80\x99S\x0b\x06\x03\xb6\xf1Y\xb0N\x99\x8e\x11\xb5-\x00\xbf\xf1\xb7\x19\xd72\x01\x96P\xb2\x81>\x1b\xd0\n\xf1\xdd\x14\xfe\x05yl\x87\x87k\xa0X\xde=\x87\x7fA\xe9\xaf\xd6\x83\xf9\xab\x0f\xe2l\x9f\xf3\xf5\xa3\xfe\xc2,\xf8!\x0c\xbf\x1f%x.\x88a\xdbz7+\xa8\x04\xacw\xe0\x81mY\x84IP,\xa4x\xde\x12\x9aC6\x08\xe5\xa6\xfe\xfe\x94\xe1\xf1I\xc8\xa2\xcc\xfc\xf5\x05\xf6>d\xbaC\x11\x9e+F1\xce+\xceN\x9c\x08\x0bil\xc7%\xce\x84\x06\xcd\x9c\xad\xe1\x9fxk0\xef'\xf5\x0f\x9e\xe9q\xc8\xc8\xb3\x15\n\xb6\xf0\x0f\xb5\xe7\x00\xa6\xca\x94\x05\xfa<%\xdd\xd1u\x0c\xc7IiH\x03\x80\"\xd7\xc9\xa7 \xf5\x10\xdc4\xa1XPp\xff\x86\xe9\xa7\x18\x89N*\xee\x11\xdb1\x08]/\xcd\xc2\x90\xe2)\x05\x06\x9d\xd3R\xa7z0\xd8,`$\x05\x0b\x93@\x1f8*\"`V\x90P\x13\x0f\x0f(\xb4\x9a\x195gG\x82\xe3\xbf\x14)\xa0\x80\xbc0\xd6\x19\xf4`\x8f\xc7<{\x7f\x8d\x07\xb3\xb7+\xdes\x04\x8a\x03\xa3\xb0^\xba\x87^\xe0\xd2\x0d\xc46\xb8GQ\xd9<\xafQ.5\xaff&i\xe4\x87T0/\x0epm\xe8\xf706c\xac\x13\x04\xa7Qj\xd0\xd7\x92\x81\xc2\xea\xf5\xb9&\x16^\xe0' \xc5.\xaf\xd9F\x0b\xd1)\x9c\xe5\xb0 \xf0\x93\x14\x17\x87\x1f\xd8E\x81\xcb\x04\xcf\xcb\x0c\xdc\xf0`\x84\xe9\x1b\x86G\x9a\xda\xf6\x1e\xe8\xaf\xfdK\xf9\x96\xd3\xb5\xaf\x97'\x9cnq|J\x11\x97\x99\xa0\x862\x84\x06\xb2\xc2_\xa1+O\xe2\xe0~\x1b\xdbG\xcb5\xe9\xda\xa7A\xb1 n\x90N\xe01q\x8e9\x10\x01\n\x9e\xee\xc3U\xac\x0fq\xef\x84\xf9k\x1a\x05\xabzx\xd0\x1d\x14\x061\xed\\\xef}\x06\xe8\xbc\x87\xae;f=\x82Y\xdf\xb0\xdf\x06z=o\xd8\x97j\x12_Q\xc1\xfd;\x93\xa0\xc5\x88\xd70{z\xb819\xd5\x94U\xbdF\xfb8\xd8\xb3b\xc9\xdf\xf9\x9bM\x96\xb2o\x958\xa3\x99\xb2JL\xed\xde\xf3\x15\xd2\x0bH\x144\x12\x90\x13S\xbe\x0e\xe2XC\xf4u\x16y_\xe4\x8f\xbf\xcd\x1f\xff9\x7f\xfc\x1e\x1f\xff\x99fi\xea\xd3\xe8\xb7A\xa6\xe1|\xc5\xf8\x96\x15\x1e\xff`E\x8aW1Ovq\x10o\xef\xf1\xfd\x8f\x9b\x8d\xa1\xc5\xa87,\x80\xf3C\xc2\xbc,\xa0\xbc\xdc\x97\x1f\x92\xb8\x98\xe9\xb5\xb1\x84`\xaf3\xbe\xca\x02%\xb4\xb8F\x1d\"r\xf4B=\x8f!\x8b\xb4e\x89z\xe6\x1c\x97P\x08\"\x0f\x9a(l8\x05\xc4\x0f-^\xe3\xe9f\x08\x04\x99\xad\x91\x04\x84a\x16\xf8h\xea\x81\xa7\xb0H\x92\xd1\xd8!\xdektN\xe8z\xad\xabMv4\x121\x92b\xae\x89L\xc8\x91\x00\xea\x83\xdc\x04\xa8\x1e&\xfc\x84\xe44\xbc\xb7\x98\x1aj\"\x17j\xd2\xa6\xde\xcd\xa3%s!\x92\xb7\xd0\xa0p\xa8\xa1\xcd\"\xcd\x90\xf0 \x00t\x8cU\x0cc\xf5k\x14\x8b\x1c\xd2\x1a\n$\x9e\xc7\xb4m\x80%\xeb4\xf0\xb7\xfa\x01\xbfd\"V\x12q\xc0\xb4,A\xbd\x1b\xc5`\x10\xefW[K\xbcV1\xd7\x90y,\x08\xd4x\xe9\xf9V\xafj<\xcc\xeb\x8ey78\x94V\xc0\x08(2!/`Hvm\xad^\x8cB\x82\xfa\xab\x97\xa9\x17\xc7|\x8d\x89\x9a:A3\x8a!\x8cW4e\x86g\xd2\xd436>\xe6L\xcf \x84M00\xd3w~\x98!`\xaa\x8a\x8d\x9a \x16y\xf7&A\xd59Nw\xfe\x06\xea[1\xbd\xd2V>\n\x1e(!\x16\x96/ZB\xa9\xbfc\xc3o\xe1E\xed\xffz\x95u\x1d\xf3\xb1Z <\x89\x03j7\x1f\xf5\xe41\n+i\xfe9\xe1\xb11\x9e\xc3\x04\xce\x14)4\xf4\x05f\x07\xbb\x80\x8b\x1d\x12Pf\\#k\xf5\xe2\x08\x18'&\xf1\\\xa8]\x03\x97\xd5Y\xf7~\xaa\xf7,\xc8\x14\xd9z\xcbB\xcd\x06Y\xc0\xf6\x16j#\x04\xf8(\xfc\xaa\xbf\xe3XQ<\\\xf9\xf0nF\xa0 z)V=\xb6#\x82\xaf\xc5bq$\xc6\x1b\x1a\xfaA\xfejP\xdb\xbe\x8c\xe9\xfa\xc7,\x15y\x9a\xe0L\x8bA\xfa]c1\xbc\xed)\xf7i\x94\xe7\xbe\xb5h\xb6A\xd9\x03Z\xda\xc2\x06i\x0b\x1b$`\x9dc\x83?E\xb9\xd0\x08eY\xe4#\xe34 %i\xb5@8u9M\x1a\x950Y\x9e8D-?\x82va\x99\xdf\x00 7\x98\x00;\xb5\x1b\xd8\xa9)\xb1L\x17\xbaa\xf7\x89\x929R\xfd\x92&\x10X]\xbf)n\x00\xcf\x96\xd4\x02%\xcd\xc7,`\x8a\xd6\x8d\x0b\xecI\xd5\xcd\x82\xd0\x8ac\xf8\xae:\x99S\xe1@K3\xf9\xe4\x05\xb16P\x1c\xb3\x84\xef\xbc\x1d\x8d\"\x16\xa0\x00\x84=\xbdw\xa4Asw\xd0\x8f;\xe8\x07\xca\x1f*7\xfc\x03_\xee\xe1\x0b\x18|\xbf\x8b\xe3\x90Fk%09d\x94\xac \xa3\xf4P8\x81U\xaa\x97\xb4\x15{Vl\xcf\x02-k\xdbM\x9a\x17\x07Y\x18\xa56\x13\xbe[r\xad?kQm\xcd\xa28\xb4Y\xd7,\xd1:\x0d+\xcb\xe7l\x1a\x1es>\x07\xbbG\xf5\xc05ykbA\x81\xc2\x1f-q\x17H{\xc4\xc4\xce\xf7n\"\xad\x17\x0b\xecV.\xb0\xfaT\xb5\x05-\xef\x83T\x8a]g\xea\xc50j\xf5\\\xe0\xba!\xbd\xb3_\xfc\xc8>\xc6{\xb55\x81U\x03\x8dFqNL\xa3,\x1f\x07#\xad\xf3\xf8\xd6\xa6\xf1\xf8\xd6\x8e!\n\xcc\x06w\n\xe23\xb7\xbd\xe0\xb6\x17\xb8\xe7\x05\x03\xc5\xfc\xb5\x00\x95\xde\x13\xfb\xef\x98\xde[\xf8Z\x8f\x07\xe8e\xb5\x80 \xb5L\xc2\xbeh\xe2\x03\xa2\x88V\xe2\xe9 \xffV\x96L\xb3\xa4\x9ar\x1f\x86Lp\x1f\xe4\xf1}N}\x0e\x8b\xcex\x83\xe3.\xf0\xa3\x9b\x99\x99\xe3\xbb0\x98i\xebzH\xb7\xe2\xba\xfa`G\x03\xaa\x9cA\x8e\xde\xb2`?I\x8a&\x8f\x81\xd3\n\x89T#7\x9b\xab\x9d\x17$\x1a\x8f/\x06\xa8\xe8\x8c\xb6=ru\x05\xa6\xa6\xf1\x86\x88\xb9\xb9}:\x87[\x98\xeaO\xe5f\xd9\x88\xb0\xb9J^6x\xdf2\xa6\x9b\x95\x83\x0d7\xe4^\xbb-\xae\xebp\x93h\xf5\x16^\xa6\xad\xb7\xaf\xbdc\xfb\x11a\x03\xf2\xc7\xd5\x8f\xcc\x13\x85\xf0\xf2;\x9a\xfe\xf16\xfa\x8e+\xd1A\xdcO<\x1a\xc0\xe0i\xcf\xd1\xba\xd7l\x1e-\x1d\x9eT\x8c\xc9N\xc3\x91\x0d\xd1\x80o\xc0\xbb\xdc\xcf\x8b\x9f\xe7\x8bt\xf1\xc3\xf2\x89\xd4\x7f\x17\xef\x17\xefO\xb7a\xbdG\x89*p\xf9O\x95\xec\xff\xf4\xd2\x99y\x0d\xd6jk*\xe8x\xbe\x18/n'\x8b\xec\xec\xec\xb7\x9f\x8e\x17\xd9\xd7_\x7f\xfd\xf5\xf2\xd4q\xf2\x08%\xd4\x12\xc7\x12\xcb\xe1'\x8e\\{\xc8\xd5\xbf\x9e\xe1\xff\x1b\xb9\x13\x03\x91\xa4\xd7\x12o\xd6H\xc1\x02\x89\xd7-\xa4\xe7\xaf\xe5]\x98$\x83\x99\x9c\xbf\xa1\xe3wK9\xa7\xe3w\xc3\xc9b\xbc\x1c\xf6\xafg\x90\xa6\xdefK\xf9\xc9`P5\xb7#\xda\xb3\x154\xb6\xb8\x1d\xe2\"\x93`\x829se\xde\xaa\xccs\xd5\xcd\xb3\xb3\xb1\xfas~\xa6\xfe\xfd\xe2l\x91M_|\xa6\xfe\xfd\xec\xec\xabEv\x8e\x9f\xcf\xcf\xce?W\xff>\xdf,\xb2\xa7ggg\xcb\xd3m\xbd\xca{rEz\x06 \x8b\xf8\xff\x03hf\x15.\x18%m\xed\xe3D\xc9\x0f\x8a\x86\x90\xeb\x03\x16\xe5\xa4\x803XC\xdd\xa9\xee{2\xeb^\x0b\x03\xc0\xda\xe1f\x13\x10\xd1x\xa6\x18,\x18\xe1\x15\xbe\x81M\xa1\xee\x86]\x13\xe4:\xef\xec\xac\x05\xd2&\xea\xb3r\xc3\xedoH\xff\x0b%\xb5M\xfc\x14\xfe\xf6Y\xa3\x85\xa1%Sj\xd1\x9f\xe1=z]\xc6\x98\xb0_\x10\x01\x11\xe7\x0d \x13\xc3\xe1\x80Ds\x81\xebU,\xeb\xcb\x95\x14\xdc\xf5\xd5{\xd3\xb4\xba\x11\xe4\x0d\x8f\xc3vG\x80\n\xda\xb7m\x07\xae\x85:{J\x00\xd9\xf8\x11[\x17\xe7\xec\xd6\x8f\xd6\xf1-\xb9\x06{\x002\xd3\xef\xe5&\x9d6\x83v\xe4o\x9d\x8d*\xc8\xbe\"W\x84\xf2m\x06\x86`&\x92\xfcK\x8c\x0d_\xf0B`\xb3\xcc\xcf\x96\xe4\xba\xfc:#o\x9b\x02\x9a\xde\x95\x0c`\x9b&\x95\xe4\x10\xdfV\xc7\xd2\xfc\xde\xbb\xbd5\xdcM\xf6\x8c\xa7\xaa\x8bW\xa47\x9d\x9cM\xd4\xae\xfan\xc2Y\x18\xef\xd9Z\xc7\xbd>\xf9\n\x9ck|5Y\xc7\x1e\x80\xad^?\x87~\xe5i\x93(^\xb3\xd7\xf7 \xb3\xb6\x9bw\x13?\xfd!K\x92\x98\x0b\xa8\xead:\"wu0\xd4(\xfe@\x8aU\xb9\xc7\xe2\xcb\x06\xbf~\xeaw\xd3\xf2\xed\x8b\x0eu\xff\x11\xf2\xfcN\xe7\xf9\x9a\xd3ms\xde\xef \xef\xef_\xbf\xfa\xf6\xb5>p\xfc\nO\xa5\xdd\xd9_C\xf6?\xd4,\xad\xcd\xef\x95\xfd\xfe5\xe8\x83\xdc\xb9\xbe\xc1\\4dk\x95\xf5\x15M\xdc\xf9~\xb4\xfc\x1a(\xd27\xe4\xbaRLM\xddW\x93W\xf1;H\xfcB\x08\xae\x12g\xe4\x1bw}\x7f\x80v_\xb3\xbb\x86\xde}\x0f\xdf\xbfD\x8b|w\x96\xdf\xe1\xd8\xfe\xf1\xd5wp[\xda\x9d\xe9[\xc8\xf4?\xbf\xfa\xf6\xf7B$\xdf\xb3\x9f2\x966T\xf7\xa7r\x0f\xbf\x85\x1e\x96\x0b\x92\x19\xf9\xd6]\xf8'h\x86Ej\xff\xf6\xa7\xef\x1b\xfa\xfcu\xb9\x85\x9f\xa0\x05[\x86\xcc\xc8O\xee\xb5\xe4\xe4\x17\xdf5-Z\x85\xf6\xef\x14\xf5\xfd\xff\xd9\xfb\xda\xae\xb8m%\xe0\xef\xf7W\x0c~zR\xfb\xe05\x90\xa4\xb7\xed\x06\xc2!\xb0ii\x03\xe4\x02i\xdaK\xf3p\xcc\xaev\xd7\xc1k\xed\xe3\x17^z\xcb\x7f\x7f\x8eF\x92-\xdb\x92\xec%iz?\\\x7fHXk$K\xa3\x91\xe6E\xa3\x99`\x9c\x92\x8a\x88\xdc\xea\x18\xdb\x10\xc4\xff\x8f@\x98D\xd8\x16S\xfe\x08\xe8mBRI\xc1(c1\xc27\x94\xdb.\xd5\xc8\x87u\xf0\x15\xeb\xa0\x1eK\xbf\xc0\x0e\xbc\n\xa2\xc5\x92\xf7\x1b\x95\x14=\xe4\x8f\x08\xc9G\xc9\xa8\xf0P\xb0u=\xf4{\x84\x9e\x91\\ ${u\x7f\x1e\xce\x18\xb5\xea\xe1\x7fRZ\xef\xb7\x80\x7f\x83\x1d8c=\xa7in^\x97?\xa3T\xdc\x9e\x82\xe6\xae\xf6Kc\xa7\xffE\xf4\x85m\x10\xeat\xf0\xfdr\xaf\xdc\x88\x8e\xe8Ds\xf7\x8d!\xfd\x07\x8c\x8c\xa6\xed\xd4W\xb0\x03\x86\x95\xffo\xd8\x81\x89\xbe\xe8W\xd8\x81\xb9\xbe\xe8_\x18wM[D\x08\xec\x80F\xa4cON0(\xa0\xb6,aez\xcf;@F\x05;\x10\xbb\xffy\xf0\xe1\xe2\x03\xa3\xceq\x98\xbbW\x188\xeb\xca\xcd\xf1\xdf\x04\xffM\xf1_\xeay\x06\xdeH\xed\xdf\x89\xf4\xdf\x89\xb0\xd5\x10\xff-\xf0\xdf\xcc\xf8\x85\xd0\xfe\x85\xc2^\x9c\x11Cb\"\xc0[\x81\x96\xc21\xb1\xb0\xb3\xa9\xadpi+\x9c\xd8\n\xe7\xb6\xc2\x1b[\xe1\xc2V8\xb3\x15\xde\xdb\n\xafl\x18\xba\xb4\x15\xde\x12\x8bB;R\xc8\xa2r\xa0\x91.A\xd2\xa3\xa0\x8a\xf7PZ\x93T\xef\"\xe1\xe4\xc3\xbdD>\x98d7\xed\x97J\xcf\x12\xe1(V\xb9Gq\xa7\x1aSkg\xb5\xd6\xb8a\xb99}uh\xf8\x98R\xc6*\xb1\x97\x85ZI\xfb)\xa5LVB\xfaw\xde\x9d\x8d.\xdf\x9e\x9e\xbc>|3\x92\x9fz\xf2\x04\xa6\x81\xfa\xde\x17\x9b\x14\x0f\x82'\xfa}\xb9wz\xb8\x87\x0d\xfab\x9b\xaa\x17\x1f\xec\x9d\xcbb\xdc\xa8\xe4\xfbw\xc7?\x1f\x9f\xbc?f\x8d\x9f\x9f\xec\x9f\xbc9C\xa5a\xcb\xe7;\xd648\xdb{=\xba|}rz\xf9\xd3\xbf\xde\x8dN\x7f\x93\xa5\xcbF\xe9\xf9\xe8\xe8\xed\x9b\xbd\xf3QY}\xc2\x01\xde\xffx\xf2ftyp\xb2\xff\xeeht|.\x0b\x17\xbc\xf0tt\xfe\xee\xf4\xf8\xf2\xe0\xe4H\x16\xcc\x9a\x05\x97\xafO\xf7~P\xab\xde\xb7 \x0e\x8f\xde\x9e\x9c\x96\xe57\xbc\xfc\xf5\xc9\xe9\xfe\xe8\xf2\xd5\xc9A\xd9\xe3\xab\x1aR\xce\xf6\x8e\x0f\xcf\x0f\xff\xcd\xbav\xe4\x8b\x8dI\x96\xfd<\x1a\xbd\xbd\xdc?9>\x1f\x1d\x9f\xfb\x9ciV\xc4\xf1\xee\xf4\xf0\xf2t\xf4\xc3\xe8\xd7\xb7\xac\xe1\x9c *0\x0c\x11\x91i\xd5f\xfc\x05\xdfa7=\x9cZ\x0c\xecI\xb4\xbc\x0dy%\xa7OT\xdb\xf8Z\xb8%Uh\x80\xd8M\x88\x0f\x8c\xd7\xc6.%>D<\xb3\x97\x84\xcbnf\nX^\x82\x85\xe5_Y\xab\x02\xd7Z2\xa5^\xd2]\x8f\xed\xb3Gj\x97\xd2\x12\xb2P\xebx\xb8\x9a\x0e\xf8\xa2(\x87\xbe\xb3\xc3\xa4\x88\x12\x11c7!\x1e\xd6b-U\xf0UmF\xad\x08Oy\xed\x88\x94\xbf`\xecRQ\x9b\x12\x15\xbe\xaa\xcd&\n\xc9S6\x13\xbbgD[\xe8!\x01\xf0\x8e\x95.Wr\xee\xb8\x85\x94\x1b\x96RB\xfe \xb8*\xab\xb7\xc2\x82\xca\xcb\xdc\xa9\xe7\xf3\xadu\xaa\xdd\xfd\x0c\xdc\xed\x84\xf46\x18\x94J\xbe)&\x82\xfa\x08\xbf\xeb\xa1\xc6Z%\x9f\x07K\xce\xb1<\xbd\xb7\xf4\x04dv\x08\x92\xa0<.:\xb6?\x8f\xe2\x89\xc9\x9c\x01h\xd1\x1b\x87\xf9x\x8ey8\xbaZ\xa7ENR&\x92c\xe8rs\x93\xab \xfb-\xe9\xba\x9e\xac>\xdd8XiF\xd8S\xfa\xf0\x0c!g\x1a\xd3\x9e\xfc\xcd\xb0\xc8$\xea\xce\x16\xa6)]\x0c\x1bv\xf6\xe6\xf3\xd0c\x06\xac\x94\x06\x9f86\xb3p\xa1>\x9f:\x14\xf3\xc4\x89\xae\x97\xd85\x9a\xd8\xf4\x9d<\xef\xbf&\xa5a\x96K2\xf61\xdbNf\xe4\x13M\xc1\xbd\xe1\x1b\x12\xca\x04\xdb|$/\xb77\xc4\x1f\x0e\xac#7\xb8\xee\x9a\xbfn\xeae\x0f\xfb\xc8k\xdb\x92\x85&\xd1\x98\xd1\x0ej\xb4\x03r\x0b\xef\xcc\xc3dO\x1a\xa4$[\xd2$C\x1b$\x1b\xacT\xb4\x1d\x1f\xd2\x80.I\xe2:?\x8c\xce\x1dq/e\xc86\xe7\x0d\xc6\x18_\x8c\xe7a\x9a\x91|\xa7\xc8\xa7\x83\xef|D\x89/\xd2\x9a\x06\x19I&.#@\x8fGE\xa9>\xf3\x08Jb\xd3\xb1\xef\xf5\xc0%\xfb\x92\xcb\x06}\xe0\xf1\x18\x83\xafS\xba8\xc33D\xb6\xcf8e\xdf\x9d\x9ek\xd3\xdc\xa7\xf2v\xfc\x93'\x90\x97\xc6 !\xa8\xe3\x95y\x9e^\x94uIg\xdap\x1d\xc7\xf3\x82+:\xb9\xf7L[x\xa2\x16L\xa34\x93\xcdc1\x13\xc4k\xdb3\xa3\xc7\xf7\xfc\xbc0G\xe9oW\\\xb1\x81\xa1\xb8\xbf\xe4]l\xb6\xefw\x81\xde\xc8]7\xd70 \xd8v\x8c\x00\xca-\xads\xe2~\xbd\x9d\xdd\xcc^n\xcf\x80\xa2\x8f\xf0\x0e\x06~k\x0f\xd3\xf5\x9c\x97\xdb\x1b\xb3\x97\xdb\x1b\x0c\xfck\x03#$\x01\x86\xdb:\x13.\x19.j\x91\x18\x82\xc9\xbd\xe62\x82\xbe\x9e\x9d\\\xdczW\x97/\xb7Qo{\xb9\x1d-f\x90\xa5\xe3\x1dg{\xa3\xf1\xe6\x0eh\x82^\xf2;aL\xd2\xdc\xdd\xf266\x9c\x97_{\x9e\xa6\x83\xc0\xd4T\xae7\xed\xf3N\xea\x11o'\xb6\x07W36\x86\xe7\xa3\xfe{\xa3 \xd4\x1f\xc5Ir\xc3\xde\xf9\xe7\x9fl\xd1\x12\x1f\x8e\x82\xb3\x1fO\xde_\x8e\xde\x8c\xb8\xac/_\xec\x9f\x1c\xd5_\x9c\x8f~=\xf7\xbb\xa9\xa1\xf1\xf9\xa3\xe0\xf5\xe1\x9b\xf3\xd1\xe9\xe5\xde\xfe\xfe\xe8\xed\xb9y\xf5\xd5s.\xd5\x8b\xb4\xaf\x0fWFE\xa9\xfd\xee4\xb4\xdfs\x8d\xf6{\x8e\xb1l D\xe8U6&t\n\xe70\x14\x07\x9d\xa6\x86\x88\xa6!\xc2\xd5h')\x16W$UM\xdd\xa4<\x02\xe2\xc7\xba-\x9f\x07\x0ep\x1c.\x0c)O\xf5\x88\xf9\xd8\x12\xb3\x1a\x973\x9b\xcf\xcf\x17\x04]+\xd8\xff\xc1\x94\xa6\xa3pN<\x95\x0c\x8eQ\xfdT\xdf\x9cb\xe8/\x8d\xcfJ9\x7f\x86 \xce\x03\xc6\x99\xf6\xab\xe3 \xed\x91H\xaer\x07\xcewJi/S\xfb\xf1\xb1\xb3\x89R&\xb3@f\x8a`\\\x05\x969\xe1\xb9\x1al\xf9\x7f\xa5\xf4Q\x91m\xddA\xa7{J\x8a%M\x1a\x13\xc2\xe7\xa3\x83\xfd\xf3\xf3\x8e!\x18\x8eH\xe4\x13\xc61\xbd%\x93\xf3p\x96\x0d!\xb1\xa9f>\xac%\xe4\"\xfd\x80\x01\xff\xd8\x1f]\x8b\x80\x8d\x80\xab\xb2k#\xach\xc2/ \xa2$#i\xbe7\xf9\x18\x8eI\x923&\xdeG\xc4\x01\\i\xed\xba\xae\xb37\xcdI:Bg:\x06\x90p\xc1\xe0\xb3\xc9\x94\xcd\xf97c\xadk\xff]\x9b\x12\x1eT\xb0%\xd3\xf0\xd7\xca1]\xf9C\x0f\xbb\xb6\xb1\xbd1\x0br\x92\xe5.Q\x97\x10\x97\x0eV\xd2\x9d*M=\x18\xc74\xe1\xaa\xa0m\x03\xaba\x99'9\xa9:P\x06\xe8c\x1d\xf4\xc1y\x12\xe7/\x1c\xcf\x93\xa6*\x99\xeaA\xdd\xf7\xb9\xb8X\xfeS\x1fO\xd9\xde\x0f>8\xc0$G\xf9\xe2+\xfe\xc2\xafW\xa8\x82J~\x01,\xa8\xdf\xdd\x81\x84\x0d\x93-\xe2\x90\xd1\xa3}[\xddZ\x85\x0b\x9c\xae\xc8\x05V\xd6\x07\xedpiO8\xda\x13.\xea \x17\xf6\x84+\x1e\xcd\xf2\xca]\xbe>;<\x82j\xc5a\xba\xb6>\x86\xf4v\xcc\x15\xdd\xc3\xda\xe4\x1b\xb5.\xa0\x89\x0e\xfa\x970.z\x82_\x13\xb2d#\xd2\xc7ki>\x82\x15T(\x18\x0253\x04\xd0\xebJ\xea\x83\x8ebl.\xc2\xd2\x11\xac@_\xd6n\xb4\xc8\xec\x92(k\x84\x17\xc5\x07/H\xc2\x05\xf1\x91\xf4\xf2\x00\x0f\x98\x82<\x8d\x16\xae\xe7\xf3\xa0\x85u\xbe\xeaC\x16H\xd4\xf2\x04P\xfc7\"\x8f'\xeb\xc8\x02\x89\x1e\x91J\xb3\xc9m\xf7\x94\x18\x96hJ\xe6_W\x1a\x92\x07d\xb8\x85Q\xe4o\x87G?8\xca\x8e&\x05\x9d0\x88&\x1e\xd29\xfb\x8b\x13\x14w^\xab\xbc]1\xa0]\x10.\x97\xf1=\x1e.\xbf%.?\x8e#\xfcG\xc2\xff\n\xcbL\x12\x91\x07/\xa1\xe0\xbcA\x95PD\xb5\x88\xa3\xc9\"c\xc8\xc7\x90\x12Q\xf7\xa0\x93\xca\xe1\xf1\xdbw\xe7\xbaa\xf2\xbb\x0e\n:\xf0f\x1d\xb7\xb6\x0bs\xf9\x05E b\xad`\x7fy\x1eF\xc5\x8d\x92B\xe3\xc7\xa0{\xd8\xc8\xb0\xb9D3\xec\xc4\x07\xc7Qp\xd5\xd9\xa2\x9d\xcb\x83\x18\xaeB(\x18)\xf8\nY6\xf6d\xad\x1c(\xa7\x03\xfe\x9b\x0d\xcfM!J`\x8f\xfd\x8d\x7f]\x13\xcf\xe8P\xd9|\xd8G\x05#d\x04\x87\xff\xa4\x9dl\xcf\xc3\xa3\xb6'O\xe0\xdf\\\n\xa0^\x8f\x99\x079\xfb8P\xac\xfe\xebc\xaa\xf7\x1b\x18\x88\xc1\xad\x95d\xc0\xa9`E\"\x00\xd1\xcc\x19V\xee_\xa7\x1chN\xf8\x18+\xa4\x12\x82\xb4\xd3w\xcc\xa0\xb6\x86\x97~\x15RPn\x0eT\x04\xc1\x1d{\xaa,0\xdc\x80\xc8m7kw\xe4\xc2\xa4 |\xe8\xa6b\xf5\xc1\xb0\xa2\\\xe6\xfe\xd7g\x18#\xa8\xe3L\xaby\xea\xd5@\xf7\xea\x82N\xd3T\xf3i\xaf\xf8\xd4\xf3\xd5\x93\x01\xba\xb4\xc8h\xea\xb3\x82\xb8\x0f\x9d\x83\xb1\x97\xb6$@\xad\x94alb\xa5\x03\xa5\x03U2\x04b?\xd7\x92wM\xfa\xc8Tl\x13:b\xed\x99\xa9\x07\xf9}[\xa6:\xc3\x80>\x07'G\x0e7\x87\xb0\xc1\xbe\xc0\xef\xa6AB\xeer.X\xbf\xf0Z\x0c\x98W\x14\xa1B\x92R\x18;&n\xc2\xb5\x9a\xa4\xd4\x8f\x14\x8d\xff\x049CU\xe6\xf9p\xcajX:\xde\x9a ]\x97\xf5\xb3`\xbcxr\x17d\xa2\xb1\xbe'|}g\xa3\x8f\xf4\xddG\xf2\xee#u\x87\x1d\x924f#\xe4Qqa\x07\x9c\xdf\xef\x9e\x8d\xd7\x06\x83\xdf\xef\x9e\x11\xc6\x88K\xf3\xceZ\xa5\xeb\xe3\xdetH,\xf7\x0b\xa0\xed\x0b\xab\xd4\x0fr\xcaO1<\xc8\xe7)\xbd\xc5\x83\x1d\xa68\x8e\xd2\x94\xa6\xae#\x8b!\xca \xa19\x84%\xf2M\xce\xb0\xe5\xf7Z\xbd\xc5AU_t\x19\x0b\xd7~t\x12\xa5\xf9}\xf5E\xde\x90\x0f\xe1\x15M1N\x8d\x81x\x8c(]\xab\x1d9t\"J\xb5\xbd\xde\xbb#\xecp\x98GcnHa\xc2\x8a\xce\xec\xd2\x84\xeb\xb6\xe6\xe8\xec\xb1\xa55\xac\xde\x9c\xdb%w\xb2\xf6\x04\x19\x18\x1a\xa8NtV\xdd\x1b\xc1t\xb3M>f\xcc\xcf\x91\x9a\xf7\x08\xba\x916/1\xd4M\xdf\x1e\xf0,\xbb\\HK\xf8\x19J} x\xf5#\x06\xc5a\x98\xed\x04k\x9b\x9eW\xb7w\xbf:9\xf8M\x88\xcb\x95\\\xbd\xcb\xf7J\x18B\xc2\xb4\x03\x92L\xf8\x99Xj:$\xb2\x0bdH_\\\\_\x9b\xe0\x7f\x03\x99-\xb8\x14N\xb6\x1d%\x7f\xb7}\xd5\xac\xc9\x91\xa3\x80+\xea\xf0^\xf3\x9b2\x06W \xfd\x14\xf0\x93\xe6\x13\xb6}\xa3\x95\x8b\x1f\xef\xe9{P\xdeC*8kJ\xbc\x17\xb8\xef\x15u\xae\xc2\x0dL\xb4\x86h\xca]x\xd8T\x1f\x13\x97rnB\x8d\xdc\xe4\x80T\x85\x9c\x9dP\x91\x8c\x98\x1a\xfa\xc60\xb3\xb0\xdae\x18\xc4\xacCG\xc1\x11\xb2-\xf8'~\x9e\x904<\xf0_\x80\x8a\xa6\x17\x1e\x845\x02\xe9\x81C\x90\xf4\x82A\xfb\xcd0b^\xef\xb9V\xc2\x80\x7f\xe3]:\xf3e\xaaK\x1f\xc2\x15&Z4\x88G\xb3\xea\xd9-#\xf2\xd2\x94\xd8\xaa\xf9\xc0\xd6dF\xf2}\x9aL\xa3Y/\x1b\xd8\x1e7\xd2r\xdfdMly\xd6\"\x06\x8aj\xb7ij\xb2rW\x95.\xcf\xfaf\xc3\xc9\xe4GJ\xaf\xfb\xf2\x7f\xfd\xd9\x03\"\x1c\x8f\xa3v\xf8\xa9\xd4\x9f\x7f\xe2^\x84'Sh\xc6\xcc=\xcdU\x8cj\xf3ju\xc1\xf4\xfd\xda\x99\x97^\x90n4\x9b\xad\xd4\xae\x1c\xc5\x85F\xa7Q\x1a\xde\x8b\xe3V\xdb\xc6\xa6\xd1\x0fW\xdbZ\xed\xe5\x832\x16\x9e\xce\xb6\x0c\x8b\x9c\x8a\xa2G\xc5W\x16\xfev\xfcpS\xdeSvs\x1f\x9c\xcbK\x92\x1d\xd1 \x0f\xd3S\xef\xfc\x0d7\xe0\xa9\xa9\x02\x94\xd5)O\x8cb7q\x9f7o\x15PQ\xf0\xb4Y\x10\x89\x82g\xcd\x82P\x14|\xd3,(D\xc1?\x9b\x05\x99(\xd8T%f\xf6b\x8b\xbd(\xdf\x94:F\xdc\x9ey\xf5\x06, *T\xe0\xe9\xb1.\xa8\xaf\x88\xaf\xd6\xf4\x0dlF\xd8\x05\x81\x9f\xb1\x95\xee\xca\x9e\xe5\xb6k\x9e\xee\xa6\x0f4\x10\x1f\xf6\xdc|\x1ee\xdc]\x95\x15\x84\xcd\x027\x0f./\xd1Twy\x89\xccb\xd3\x87T\x01\xf2;\xd3\x88P\xd0%\xbb>\xba\xaf\xab\xe0\xc5\x82\x93\xb4\xb4\x88\x99 \"[/\xaa\x8554]\xc3\xe4`lM\x0dM7<\x01\x0f\x0e3z6\xa7\xb7f\x92[Zmh\xe6\x01,;\x87\x18\xf7Et\x94Li\xba\xe01 ;\x88\xc2\xd2\xa1\xb1\xeds\x0bz\x15\xc5d\x08[OWm\x96\x8aqz\x96\x91N:q1\xed\x84\x98wB\xc4rg\xf8D\x0cXx\x08\xc9\xaes\xba|\x0c\x9a\xc2\x1eh\xfa\xaf\x1e@Q\x0e@\xa7\xb3\xd5\xde<|\xf0|\xe5*\xc2\x83[\xb5Y\nS\n\xa3\xcbe)\xec\xc0\x18\xdf\xfe\xbd\n\x8d\x0fy\xf0SF\x13\x14\x15\xc2Kn\xa1D&\xad\xbc\xbd\xa24&a\xd2|\x8d\xe1\x03\x9b/\xb9\xe9\xb1\xf1\xf65M\x17\x1a.-u\xa8{\xa6*\xb5T\"*KZ:Q$JZzW(\xab\xe8\xb4\xa8{\x9d\xde\x95\x89\x82\xd67bQ\xd0\xd2\xbb\xb8\x94\xd7\x14\x88\xa6\x08>n\xbc]\x8aF\xb6\x9a\x8dp\x01\xed\xdb\xc6\xdb\xb9\x04\xdfj\xf5\xf3F\x16\xb5\x86\xb6\x90%\x9b\xdf\xb4\x061\x13\x89\x8a\xb5\n\xe1\xfd\x97U\x08\x97\xe5\xba`=\x08\xa2\xecT\x84\x85\xf6\x95\xa20\xb9\xf7\x1b\x90\x96bN\xad\x86\xa6x\xa1\x0f7\xe5\x9b8\xcar\x15\x82\x91\xb5\xedw\x98\xdc\xd7i\xf5\xaa\xe5*t\xa3w\xf2\xa1\xc9\xfe\xf9\x86\xb6]\xcd:\xff\x1c:\x7fK\xb5\x97:\x7f\xd6,\xd0\xe9\xfc\xaaF\xfe\xa9:\x7f\xac\xb4U\xe9\xfcuK\x80Q\xe7/\xd3J\x1dD\x93#\x1eG\xb6\x05\xf9\xd7\xa9\xff\x93([\x86\xf9x~\xc8t\x860\xe6\xceP\xc6:\xdc\npc\x07\xe2^\xd2\x92\xc0\xf5\x1a\x17\x1aCS7\xe9\xe4\x9d:\x16\xff\xf7\xd9J\x90\x84\xbb\xd0\xc3\x97Z\x17~:\x90\x18\xd5\x90h\x91\xd8W\xb0\xcb\x14\x08;5\x1c\x0e\xe4AN\x7f\xe2\xd7\xaa9{g?]\xd3a\xbb\xf4\x8b\xb4|.F\x17\xbb\xfc~i\xe9\xfe\x18a\xb8\x9a\xbf\xe0\xa6\x80>*\xa9\x0f\xb4=\xe3\x06\xc6\xd3\x06\xac\x9di6c\x02\xfa\xb88x\xa8\xc5\xc2\xe3\xf9\xaa7_\xc0\x18\xb6\xa1x\x01\xe3\xf5u\x0f\xe2\x8b\xf1\x07\xb5\xe6\xc5X\x13kQ\xc6Y\xc4S\xe5\x1d\x03\xf3\xc3=\xae\x93\x01\x8e\xc38\x16\\\x90\xf8p\xc1\xea\x96\xc1$\xb8\x9e\x96\x96\xdbQ\xaf\xc3\"\xe9\xae\xaez\x8er\x92\x17\xfbh \xa2`\x92\x80G\xec\x0e\x18\xa0\x88\x81X\xbeC\xba4,<\xd1\x9a\xec\x15\xe3\xb2\xf2\x9d\x90\x90\xb4\xc7Sl\x1c\xa3\xa4X\xac0\x16\x81\xe7\xd6\x17\xf5\x1f@\x9bvK\x14a\xf4\xf4%\xe4\x89\xbf\x81/\xf6c?+\x08\x0f]\x8c\x96\xf6b\xb4\x9c\x87J\x99\xb8\x8b\x87N\x08\x8f\xf3d\x8c\\\x07\x82\x85\xa6\x01I\x8a\x85\xd92\xcd:G93\xdd\x15\x7f\xb8\x1e\x0c\xf1\xac\xb7\xe82U#Ou\x1d~\"c\xf3s\xea`;V\xbe\x02u\x8b\x1a\x95\x91Jw\xc1\x89\x12\xcc\x07\x84\xd7\xab;\xee%`\x90\xa8Zm\xda\xa3\x96\xb8\x9b\x80\x82ff\xe5]P\xd1\xaceF@\xb69Z,\xf3{q\xa5b\xcd\xc2\xa2\xa0\xc6\xcb\x90\xc8\xd5\xfd\xc0X\xcft\xbb\xd3\xb8\x86b\xdc\xfch\xba8\x08\xf3Pn\x80\x11\xba\xbb\xaf\xb9\xce\xeb\xb2 JD\x0c\xda\x8e\x83\xa3\xdcu\x0e1\x91\xa4]\x10\xa9\xed\xb7b\x8b5Q\x89\xd5\x82\xc6\xea\x0eEs\x96\x9e}\x12\x1d\xadNC\xad\xa9\xeb\x92\x90e~\xaf!\xc4\xfa dk\xd3\x84\xa0\x85|\xdf\x03Q\xcb0\xcbni:\x91\xb8\xe7R-CFU2\x94\xb9\x07\xffk\xf0\xd9\xbd\xc2\x16Q\xf2\x06[\x1b\xda\xfcK'\xe4\x8a\x16\xc9\x98\x9cG\x0bB\x8b|\x08\xcf\xbe\xb1@+\xa1\xe7\xacb\xe9_0\xdb\xad\xd7\x9fU\x02\x95\x16\xcf^\x02(1\xdc]\xef-dJ\xf3\xe8c\xad\x1e<\xae\x06Bc_\xcc\xd1\xf7\xf5\xc2\xdf\xaa\xf2R\x1ady\x98\x0b!\xc0(\x9c\x1d\xe6D'\x9cY\x1c\xae\xd2 #\xf9\x19k\xba\xba\xdao\x8d\n :hg\x91ri\x88Kj\x19\xc9\xb98f\xacd\xf2\xefW\xb0g\x184w\x98b\x03\xef'\x8fj\xc6k\xbd\x1f\xb0\xcax\xe5\xa5<\x11\xce\xe4/\x19o8\x994\x07\xbb\xcaX\xfb\x04\xc4\x10T\x06;p\xe9J\x8a\xeb\x12\x8a\x04\x06\x048w\xcaslau\x1e\x8d\x80\xd5U\x10\x0d\x1az`\xa1\xdfx\xff\x82\x01\xe2B7^\x9c\x15\x1f\xaefF\xdbH\xed\xe5_\xa3-\x95\xd6\xd7\xf7Q\x1c\x9f\x921\x89n\xf0\xb4,\xeb\xa1@\x19\xe7J\x92\xde\xda\x8e\xd0\xa2\x94]\x8f\x89\x7f\xfc\x9d\x9cN\x9bB\xa0\x92\xa3~*:\xf9\xd9\x17\xb2\xa0\xdau\xc4>\xba$?=\xec\xa7KR\x84\xedV\xed\"\x84\xebR'C\x84\xeaR'\x0b\x842\x99OC\xbc\x11,\xb4\xbeP\xd5\xfa\xec\x06\xd4\"\x88\x92)I\xb9\xf8\xe0FA\x94\x93E\xd6\xedhV?Q\xe9\xe1s\xf6\x8ag\xf7\xef\xf0\x1f\xcbP\xb7\xb5\x88W\xd0\xa6h\xb3&\xbc\xec\xd2v\xe7\xd2\xd3\xed\x13\xb5\xddy\xd7\xc6\xaeH\xd5\xe1\xeaR5T\x92\xb5R;\xecQKf\xdf\xed\xbe\xb7/\xd6\x9c\x85\x96\xa1\xad=\x1b\xa2\xbf\xd7\xa0kz1\xfd\x9b\xf5\xe2\x8ey\x14\x0eW\xdc\xedc\x8dGC\x99\x04\x98]\x91\xfd-\xfet=\xd8\x86\xad\xea^\xca$X\x84KE\x10\xf2\x81v\x11^$\x84\xe6\xb4n\x96\xcf:.\x96\xc9\xd9\xb75\x0f\xe2\x13K\xdc\x10xZ\xd7\x9e\x92\x8b|J \x06\xaf\xf1\xf0[/\xd6J\xb6p\xab\x80'\xeb\x82j\xe5\x9d\x8f\x8b\xe5\xc5\xe6\x07\xbe\xe3\xc1:P\xcb\xdd\xe4\xce{Y\x1dsi\x1f-2\xa2\x0e\xa2T}\xbf>f4\x19\xf0\xed|\xc0\xf4\xeb\x01\xdb.\xad\x0e\x81\xa6\xeeY\xdd\xcd\xa0\xfbd\x05Z\xa7+\x1dF*)]\xf7]\x81\xfd\x04{\xf9\x94$\xa3\xaaO|)\xd8)\xc7\xde\x1dy\x9e\x13Y\x96\xbf\x19\xc7V\xf3\x124\xa6\xf6*O\xe0*O\x06\xd9\x02\xb4\xb3<\xe0\xfaH\xc7\x86K\x93\xfd8\x1a_\xf7\x10^\xd4\xa7\xc4^\xa5\x87\xb9]\x88\xb3\x11\x9d\x03\x03pL\x9e\xa8^\x90S~\xf4\xf3X\xd4\xad\x84\xb6p2\x01\x07\xd6\xab\xcd\xab\xc1\xf8\xb8\x1b\xa1\xf1[%B\x91#\x08\xbdM?06\xee\xbd\xc9\x04\xd8g\xb5\xc3\xef\xb4\xb4\xbc-R\xb2\x8a\xb5\xa5r;\xebeo\xf9\xdf\x81\xdf\xca\x07~\xabj\xa9\xff;(\xd3?\x7f\xd1AY\x97\xceB{\x1d\xa7\xd5\x0f\xca\x0c\xa7\x0bx\xf2%\xf4\x9b\xb4\x9f~\x13\xf69\xcc\xea\x10#\xc2\x9e\x1ba\xba\xbaX/Dz\xa5f\xda\xcfX.\x82\x08$\xb6\xdbFuA\x9d\xbb\xc6MS\xba\xf8\xe9\xccs)jYx\xff\xd3\xc9S\x9e`e\x1a\xc6\x999\xe1\x0b\xe8\xa5\xf9\xb2\x1d\xdb\x81\xd7\xaaB}\xb7I\xe1\xd3L\xe4\xa5\x07\xf1\xa3\xf7\xec\xde{\xb2\\\xa1\x9fl\x1f\xb7X\xc6\xd9\xc2\xc9H\x8esrN\xcf\xc2\xc52\xeee#\xaf\xbc\xbb\\\xf6\xe5\x19\xdb\x1cxm\x8e'\xcf%5w \xfd\xdd`\xa2\xb5\xcb\x1bEF\xd2\xf2\x990\xb4:\x0f\x93ILNVi\xfb\xa6\xccw\xdc\xed\xbb\xa1\x0c^\xe7\x03\xe8\x1b\xbd\x85\xe132\x80\xcf\xe9y\xb9V1\x81\x86\x9dO\x9d\xc3\xf2e\x9bdtw\xb4\xeb8\xf8B\x86\xbc\xffbN\x96\xbb\xce9\xb9\xcb\xf7R\x12>\x92\x9b\xd4\x0c\x0c& \xda\x93\xe50R\x9b+\x06\x04c\x1d\xf6\x08\x9e\xc4\xd8M\x16\xfda\x0d\xcfkF\xbddX\xac\x05d\xc3\x1fi\x94\xb8\x8c}x\xfd8\x97EGm\xb0\x89\xfa\x06\xa0\xad\xf5(w\xbe.\x11\x1f\x81\x1fu\xe3E\x1e\x86\xe2E\x87\x7fz\xc1\x818\x91F\xa7\x89\n,\xad\x17\xf0\x10\x92\xb58\x02\x8f\xef\xc2g\xbdt\xd3\xec\xa6\xe9n\x8c\xf8h\x98e\xd1,a\x8c\xcc.\xa6\xd7\x92>o\xf1\xfc\xceMuE\xe4y\xb6\xef\xf3\x95\xa6bJ\x03]~\n\x03'&=\xf3\xc2c(8\xb4Ta\xac\xe9\x1dH.R]\xa0\x89\xd6\x1b\xc9\x90\xeb$X\xa7x\xda\xc5\x9aK\xd1\x83XO\x9ck\x19\xfe7_@\x02\xdbj\xa2\x7f3\xf6@\x99\xb9\xfc\"1`\x0e\x90P\x99tG\xd2\xf0\n\x05\x8a\xdaO\x91|,e\n\xdb4\x9a\x15\x12hm\xb3L\xda\xc7P\xce\xe3\\\xa6\xc1m\x1a\xe5%D\x99}\xaaI\xa7\x845xM\xee\x19\xfe\xf5\x0b\xbe\xff$\xa8\xd6X>\xa1V\x85\x91\x07\x01u\x15\xd2\xe0\x99\xc3R\xf1\x9eG\x07l{\x157\xb6\x9b\xe6\xc5r\xa6\xd8\x14<\x02F\xbd \x14\x05[\x9b\xdf|\xab\x0f\x86Q|\x91\xbbOn{\x99\xf7\x92\x8a\xb5+{\xad\x9f\xb3\x04\x8f\xf5T\x8b\x80\x95\x9b\xc2\xa1\xed\x87IBs`\xeb\x12B\xce\xfb \xccj\xa1\xd8\xdas\xd2!\x90'}\xbd:\xb0\xa3D\xed\xd9)\x99\x92\x94$\xe32D\xdc<\xca`\x1ef\xc9\xd79\\\x11\x92@\xc4\xaf\xb1D\x19\x99\xc0\x00\xb2bIR\xd7\xabA\xb0\xa1\x90I\x87\xf8\xb0\x86\xc7\x0dJB\xc9Z\x10\x1fm8\xbb\\P\x81\x86F\x0d\xfa\x86X\x843\xc2\x98\x1f'\xfa\x93i\xcb-\xc7\xa2y$\xab9d\x93`I\xd2,\xcarSX\x05\xc9\x14\x92\xee\xd3\xbdd\xa5\xe3kU\x1f\xd0o,=s\xaf\xb0\x1e\xd2~=dO\xe9\x06\xf7\x92U\xe1\x82x\xe9\xcd\x86\xe1\xaa\x12\x9aGS\xbc\xe68,\xb7oxYU|\xf2\xa4\x02J\xf1\x88\xa8G\xbe\x066\xd8!\x08p1\xf8\xaeZP\xe1\xcb\x92\x91\x0e\xf4\xeayUd29\xb7\x89\x12\x13-%?\x93\xfb\x03zk7\xa0\xca\xa7\"\x0f\xa9C\x8a\xda\xfa pFI\xceS\xc20\xf1\xfe\x9a\xdcsdNi:&\xc7\x12\xed\xbe\xc85e0\x10\xb2.\xbe\x8a\x8b\xf4\x91\xfdcUM\xf4\xbbb?\xb8\x86\x80\xf0\x11\xe9\xd7\x1f\x1eQs\x1b6\xbd\x92\x86\xba\x84\x0f\xf9\xc8\x05^\xc4\x06/F\x83V-\x03\xfc\x8a\x84=\xb5\x0f'\xc1\x84\xf2\xf1Z*\xdb\x97^.L)\x8a\xed\xa5\x1b\x0d\xf2I\x82(\x13\xbc\x8e\xdf\xd1a\x02L\xd5)\xab\x9f\x19\xdb\x07\xcd\xcb\\\x87\xddGtg\xd3\xd7\xcf\xbf|\x90\x0e\xa6q\x91\xcd\xfbN#TS\x99\xf3\x9a\xb6\xb4\x13Hf\x8c!\xc7\xab\xb4\xafEk.\x1a\xb2}NOXz\xea\x97\x93\xd4\xa7cI\xc3\xc4$\xce\x18D|Z\xe5r\xad\xfeS\xca\xba\xec5\x9f\x98_\xa0\x86\x03\x1b\xc6J\x0c\xe3^$\x91d&--K\xec8\x81\x04\x0d\xb31\x7f!Wx\x14E\x9e\xa4\xac\x08\x0c\xa2X\xfe\xfeR\x0c\xe8\xf1i3{\x07\xdf\xc1\xa9\xee\xe5\"(\xdd\xe6\x98<\xd6f\x8c\xd8\x8en_\xa9Aj\xcd\x87\x9d\"\xa81r1\xb2\n\xf4=A\x07?\x83\xe8|\xc6\x84O w\xcb\x94d\x19\x93\xda\x17E\x96\x03\x89\xf29I\xe1\x8a\xf0\x06h\xaa\xc8\xd2>\x06\x1dv`\xbd\xfc\x90\x862I\xa5\"U\xba?\xe7N\xae\xc8\xdb\xa8\xe8Pz\xd4\x8ei\x92\xe5i1\xcei\xaaS[\xe4#g\xc0L\xef\x95F\xda\x8e8\xa0>R\xff\xb4\xbbA\xa9\xba\xec\xd0\x94\x8cICK\x92{\xbb\x02\x1bYM\xa2\x86]\xd0\xbe\x17\xf3>DUN\x8a\xe5l:\xeb\xa4\xc3t\xcf\xf2T\xa0a\xbd\xf2\x81\xf630\xbf\x8f\xe2\xf8S-\xcch\x95\xab\x8b!\xaeb`n\xdc\xbf\xe8\xb2\x97X\xac\xc9\x7f\x89K\xac\xdcH;\xb7\xd0D\\\xc6\xab\x8dF\xbf}\xe2\xe8k\x8b\xff\xcf?\xcb\x8c\x85\xb84+g[\xc5\x01\xb7Q\xd2[\x8f1\xddi\xf6!\xa9<}\xb5\x93Q~\xac1}I\xb7\x01\xb5\xe74\xbdK\x16\x9f\x83\xbc\xb8t#{k\x92Xzw\xf1o8\x97\x10\xb9\xbe\xec\xf4\xe5*\x91\x15J\x8a\x04R\xb1k\xbfM\x82\xec\x95\"\x9b\xbc\xbaG\xf5\xc6\xe68\xc3\xa3-TUNP\x1f\xb1\x9c\xef\x8a\x90\x0fB\xab2\x03\x16\x02\xd0\xde\\\x86PQ\xb2,\xf2S25\xc3\xc5}\xcd1\xf2\x916\x9c\xff\xf4I\x1aUZ\x7f\x89\x07y\x19\x96<\xf5\x98\xb8\xb3\xa9XA\xec&aR\x9a\x84\x13n\x12\xc6\xac\x85\xf6\xcfK\x1d\xca\x08\xf4\x80~/\x8e\xa0\x18\xc7\x07G\x12\x85S\x1aQ}pJ\xa2\xc0d\xd1u\xa2\xc0\x83\xfb\x16Q4\xde\xf2y\xe7\xed\x8b\xb9\xe5?\xe4k9G\xd6\xd3\xffqG\x0cKt\xf3\x86]\xcb\xdc\x95_/\x1d\x01\xc4o\xfd\xbe\x06C\x08\xfb\xb6g\x88\x17\x0eC#\x910\xba\x98v\x0c\x89\x95\xd3\x8e.0\x1c\x96\xe3a?\x8c=)z\xb5T\xadB\x99\xba\xb4(r\xaeueb\xe8\xba\"\xf3=\xd8\xd6\xdd\xd7\xad\xcd\x06D{\x93h\x8b\xc2\xad-\xa3\x0d\"w\n\xd9\xc1\n\x97\xf8W\xc7\x99\xa5\xe5\xae\xa0\xdc\xd3\x9d\xd1\xdd\x92\x8cs2QM\xfcmBIa\x07\x8e\xc3\xe3v\x01cz\xce\x85\xf0\xf09\xbb_\\\xd1\xf8\x83\xa6~\x04;\xb0\xf1\x7f\x7f\xcf\xd6\xff\xfc=[\xffjc\xd6\x86\x08\x11\xe2b\xb0\xfea\xf3\xeebs\xf0}8\x98~X\xffjC\xe3\xe6T \xe4\xe6\xd5\xc5\xe6\x96\x01\"\xe3\x10\xf4bs\xf0\xad\x01\x841A\xcc\xad\x7f\xa8\x93\x1d\xd8\xde\xaa\xa4f\xa9\xe9\x81B\xe7:\x11NM;R'\xc3\xd7\xed\xa6\xa6\xfa\xa62\x12OY\x0d\xf5\x7f}\x9b\xac\xa4\xdd,\xdb\x80\xc6x\xf6\xcb\xfey-\xe7\xd9\x91\xd6\xa7y\x949\x9e.\xec\xf2\xa4R\"+\x16,\xd3\xe4\xb4\xc1\xe7\xb0\x03Ga>\x0f\x16\xe1\x9dF\xac+K#\x8d\xf8\xd2\xef\xb6'\xef\xf028`\xdbNBou\xf2\xa7r^\x07\xea\xb9\xd8L\xaf\x7fH\xddC&\xba1\x1e\xa8\xac\xad\xf1\xac\x18\xb5 \xd2d\xddiz\xa7\xea{\xa3\x89\x9e\x08\xd2\xac\xa0\xc9\x97nK\xd3\xc2\xeat\xebX\xa2\xbe\x93\xe1\xba\xab5\xde\xed\x16\xd0hD\xa0BC\xaa\x066\xc0Z}\xf2\x04&B`\xf3@{i\xe5AM\x13\xa4\xb1\xcdc.\x15KF\xa9\x9b2\xa8PmBdF)\xdc\xbdQ\xe5/\xffF'U\x93\x17\x1a\xec\xc0\x8cm\x86\xbb\x90\xc3:\x8f)\xd6u\xc6\x0c\xcd\x0cJk\x9a)\xac\x12\xe6\x13\x18\xc2\xba\xe6\xf3D\xb8\xdc\xf2\x84~\x11\xe6\xf33\x1f\x97\x16\"\x1d\xb4\xe5,\x90\xcdp&\xc1`\x17bW\xe4!u\x9f\xa2\x86\xba\x0bOa\x08\xdf1l\x84\nX\x8a\xfdk\xd0\xb3\xfaK\xf5\x8ci0\x17\xed\xa1>\x1e\xd1\xf9\x10a6\x99\xc2\x87\x0c\x85\x13\xf4w\xd7\x0b\x1cSn\xb2\xd3\x96--e\x13\xb4\xd9\xebIH\x9fpLo\xa8K\xbc\xc6v\x02\xea\"\xbe\xea\xf6w\xb4\\_b|2\xb2Jv\x8ca*\xe9\xdbx\xa0\x17_\xa8x\xdcr\x9e26\xae\xa1Js\xa75\x91;\xe5#;M`\x00\xb1\xb5gJ\xc0\xbd\x98\x11W\xc2T\xb6\x9c\xff\xb5\xcdu\xb7%zB\xc0\x00\xc6\xac\xac\xad\x04\xd8\xfax\xdb\xa9\xf4/l\xe1\xff/k\xf9\xc6\x8c9\xca\x18\xd5f$\x17\x82\x99{\xeb\xf7\xdc\x05K_V\x18\x80\x8b\xb8\xea\xbe\x9c\xba\x84]\xb8q\x13\x1fBYi\xec\xa1\x05\xdf\xb8a\xae6\xab\xa3\xce\x9d?S\x08i\x02\x98\x1dk\x17\xae\xf89\x82\xdb\xa4\xb4b\xb5\xaf\xdf\xf5\x99/\xf3JHx\x1c\x06\xcb\x8cR\xd5\xa5\x8c\xe7\xe4\xe2.\x10L63EJQ\x1bP\x086\xf3\xdaV\xfe.\xb3\x86\xa80\xe6_k\x13N\xee\xf90\xad\xf0\xa9W\x14\x01g\xd6F,\xe2^\xb42c\xed\xcf\\\xb9\xa6\x00\xfb=\x17l\x86b\x8c\xaeq\xcf\xd7\xf4\xdc\xe8\xc5\x95c\xe4\xe8\x1ccbn\xfa0s\x85\x15\x06\xf7\xec\xb54\x88 \xe6f\xe0Y\xb0]\xb6[;\x8b\xf0\xee}\x18\xe5\xdc\xfd\x8cq\x98\xb9{\xef\xa6\x81x-[B\xc3{\xe8\xe3&\xee\xe4i\x18\xc5\xc8K\xd1em\x17\x9b\x96/a\x08\x13L\xe0\xd7\xffhT\xb1\x00#\"0)\x98\xc4B&o_\xf1\xebG\xb1X\x15\xd5\xd2ic\x87}\xbd\xf7\xb9\xafn2v\xa1\x80!\x8c\xdc\x85kH\xf0U{\xa9\xb8\x87IW \x1f\x12\xf7\xd9\x96\xa8\xdc\xa1\xe5I\xe7\xc2z\xf7\x9c`#\x8c\xe3\xe0c\xe6\x0c\xe1\xf9\xf3\xe7~\xab\xb0\xc8\xe7\x1b!6\x9aq\xa8\xa7\xcf\x9e\xea\xa1\xd0\x88\xc7a\x9e}\xffL\x0f\x93\x92I1&i&\xc1\x0c\x1f\xccd\xe2! \xf7\x8d\x01nI\xc6\x83\xdb4\\\x0ej]|\xf6\xfd?[\xf0\xfc\x10)k\x8e\xa5\xdd\x01 8'\xf1\xb2\xec\xe9\xd3g\xed\x01I\xc0\xda\xb8\xbf7\x82\xd5\x87\xfe|\xb3\x8dE \xd9\x18\xfd\xf3\xcd-3(C@mH\xcf\x9b&\x06'\xd8\x98\x10\xb2\x1c\xc4Qr\x1d%\xb3\xfa\xb8\x9eo\xb61[\x83V\x06\xf7|\xb3\x8d\x83\x1al\x1c\xde\xd3\"\x97\xc0m\xcc\xd6\x80\xcb|K\x83<\x9c\xe1\x1c.I\x1a|\xcc\xee\xb0\xf2\xb7}+7+\xb6'~Bo\x93\x98\x86\x93A\x91\xc6r\x96\xbekA\x914\xad\x93\xc6\xd6\xd3v\x1f\x18\x10\xdeG\x18\xe4i\x98dS\x9a.H\x9am\xcc)\xbd\x16-?mO\x95\xa1R\xedGB\xf3\x01\x9d\x0eP\xc9\x16\x0d\xb5\xc9\xa3OC\xcb0\x0d\x17$'\xe9\x80&\x84Nec\xed\x89\xeb\xd3\x18\xd3d\x96\x03\xe9\x0e*\xdbj\xcf+kK]\x04[\xedE\xc0@\x1ak\xffi\x9bN\x19Ts\xe9?m\x13(\x8f\x9dP'\xcd\xf6\x8c\n(\xba\xccxV* \xd9\xee\x1c\xa7\xdb\xc6\xce\xa0YF\x02N\x1d\xea\xd36\xbd \xa8\xe6h\xdb\xd4$\x00[\x03n\x0f%\xa6\x8dm\xe6\xbb6Rh\x98=knn\xed\xceq\xa8\"\x9f\x0f\xc8]N\x92\x8cAo\xe0\x06\xda\xdct44\x83\x95\xcb\xe3\xc5l\x83\xf1\xa0\xabp|\x9d\xc9\xd5\xa7\xc1F\xb3\xce<\xcf\x97\x03\xd6\x01YG\xc3M\x9au\xd4\x89\xd6\x90C\x13\xbc\xda\x1c\xd8vQ\xf6\xad\x8dVs\xc5\x8c\xa7X+\xfb\xd8\x8d\x8b\x94\xfc\xbf\x82d\xf9\xe0\x8aN\xee\x07d\x12\xe5\xb4\xdc\x93\x9e\xb5\xf7\x04[\xed\xb2\xc3m\x8aiV\x13\xdd\xac\xb2\x1d\x95\x9fl\x13\xaf\xa1n\xf9\xb5\xf6\xb2\xc0\x1a5n\xf1\xcc\x80\xfc\xda\x04\x19F\xdb`\x7f\xcf\x0d(m\x92\xe1s\x03y \xe3Sh\xb8E\xbe\xedmJ[OO\xfb\x86\x8f\"\xb0\x82C\\HQN\x16%\xde\x0d\x0b\xa0YQE\x98F\x04\xd1\xd6Q\xa38p\x1b\x93D\x91\x01\xe3\xcd\x06\x16az\xcd\x98\xa1\xfc\xaea2[\xd5\xe8\x84\xc4r\x80\xcf\x0d\x84\xd5\xacD\x938J\xc8\x00\xaf\xb6\x859M\x07W\xe1dF\xe4\x97\x0d\xb4\xd6l\xa4df\xd5B4\xac\x89f\xcd\x1b\x9e\x02r\x90\xe5\xe1bYV\xd6\xec\x00 \xd6\x8aINjs\xb2\xd5\x1ef\x86\xb71\xb3\x8d\xa9\xc0\xdf\xd6\xf7m\"\x910\xb5\xad\xba=\xbd\x8c\x06\x9b\xdcF\xd3\x18\x83R[\xd2\xec\x94\x08\xd3\xe04\x9a\xcd\n\xc1\x1aD\xfeT#U\"\x9cF\x9c~\xde&k\x99\xd5\xeecc\xb4m\xc8\"\x8f\xe2\xba\x8c\xdc\x9e\xc4\x9b\x88\xdc\xd6`\x9e\x1b`RJ\xf3A\x94|$\xe3\xbc\xec\xdcw%\xa46]\x0d5^\xd8I\xdc\xa8fly\xd0\xd4\x8e\xda\xb5\xa5\xad9\xbd \x8d[Z\xfc\x06M\x0e\xeb\xb0U\xbb8S\xbf43\x8d\x92 ,\xf8\x0d\xa1\xaf\x1dX\x07\x02\xeb\xe0|\x1d4\x0d\xbdR\xd7V\xfa'\xff\xa2\xc15\xb9\xb7\xe6O\x16\x95\xc5\x11\x0e\x83v\x95\xcb[\x0f>\xd0 %\x19\x8do\x08St\xeb\x17\x1d)+\x8d\x98\n\xbe\xb5\xf9\x0d\xc7\xee\xc3\x07\xef\x1f\x0f\xde\x8b\x7fll\xfc\x1f\xc8h\x91\x8e\xc9Q\xb8\\F\xc9\xec\xdd\xe9\x9b\x9d*\xc3\xe1\xe0\xaaH&1[\xe7\xc1\"\\\xfe\xff\x00\x00\x00\xff\xffPK\x07\x08-\xe3\xb5\x97=9\x05\x00\xf7\x0c\x1b\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00 \x00swagger-ui-standalone-preset.jsUT\x05\x00\x01\x80Cm8\xec\xbdys\xdc6\x9a0\xfe\xff|\x8aG|w\x152M\xd1\xdd\xad\xc3:,k\x1d\xc7\x9e\xf5\xbb\xf1Q\x963\xf3\x9b\xb7\xa3UQl\xb4\x9a1\x9b\xec\xe1!Y\x13i?\xfb\xaf\xf0\x00 \x01\x10 \xd9\xb2\xb33\xbb5\xacT\xac\x06A\xdcx\xeec\x0b\x16U\x1a\x95q\x96\xba\xa5\x0f\xc4\x83\xdf\xfe\x00\x00\xe0dW\xbf\x92\xa8t\xe0\xf4\x14\xca\xbb5\xc9\x16@\xbe\xac\xb3\xbc,`{\xdb\xf4v\x95\xcd\xab\x84\xc0\x19\xff#\x10\xb5O\x81\xb8\x1e\x1c\x83#\xba\x91?\x9a\x93E\x9c\x12\xda\"\xfb+\x08Ws8\xe3?\xdc\xd9\x05\x0e\xe8\xb8k0g\xe2\xaf\xe0\xfc6\xbc\xbe&\xf9\xcfo\xce\xcb0\x9d\x87I\x96\x92\x0f9)HY\x0f\xa1\xec\xab\xf3\x87\x07\xb7\\\xc6\x85\xdf,\x89X\x8e\x9c\x94U\x9eJK%^\xd0\xe7&\xcc\x81\xc0)\xfc\xf6p\xf2\x87\xbaPT\x85\xd4\xcd\xe5\xca\xf4\x89\x17\xe0\x92Y~\xe1\x89v\xe9\x0f\xb1b'JU\xdavLG7\xcb/h\x17\xcaKl\xeb\x18r\xbfU\x9a\x1c\xc3\xd6\xa4]\xcc\xbb8\x86\xdf\x1e\x94w\x0fj\xa7|T%\x1dU\x14&\x89\x1b\x8b\xc1\xf9\x10\xfb \xfdJ=\xfa3\x81S\xd8\x1aK/\xea\xd6\x9anx\x9bi\xb0\x82S(}H\x83\x88N\x8b\xfe1\x87S\xf5\x10\xfa\xd0Z\xb24\xc8\xf8\xf9\xbc\xbf\x87\xf7x\x1c\x02vL>\xe4\xd9\x9a\xe4\xe5\x1d\xff\xb2\xbdBQ\x96.\xe2\xeb*\x0f\xaf\x12bY\x96\xb4Z\x11\xf1~\xdc~\x7fM\xcac\xc8\xd5\x15\xf3\x9a9\xd29\xa4\xca\x1c\xf4\xd1\x8b\x13R\xd2\xa3^\x06\x97\x97\xa4x+\xeeK\xeb\xac\xc9\x8f\xd8 :\xd7\xb0JJu\x0cp<\xec\xeb\x01{\x9d\x06s\x97\xf8\xe0\x84\x0e]d\x1f\x88:\xbdL\xdf\"\xbd;\xde\x0c\xdf\x99u\x9e\x95\x19\xbd\xa9\xc12,\xde\xdf\xa6b\x8f\xd8i\xc2\xef\xd5\xf6\xd7p\n\xce\x93y\\\x94\x8e\x0f\xa9\x9b\x06\x14pL\xc7\x07\xac\xda\x83;\xd3\xceG*\xf7\xefT\x05\x81\xa2\xcc\xe3\xa8tN\x94[\x99\xc3)\xa4\xee\xfe\xd4S\xf7\x94^\xa8\x99\xf39N\xe7\x8e\x0fNN\x8a,\xb9!\xf4\xcf(K\x8b2\xaf\":\n'N\x8b2L#\xf2~A\x7f\xads2\x8f\xa3\xb0$\xec\x935\x05\x1b)\xd6\xe3[s^\xde%\xf8\xb2\xa0\x7f\xbcH\xe2\xb0 \x85s\xa1\xf6\x9ca\xcfE\x14&a\x8eu\xc9_+\x92F\xf8\xdd*\\\xaf\xe3\xf4\xda\xb9h\xe6PJ`\xb4s\xf9\xe9dS\x1f\xaa\x936\x9c\xa1\xb7\x8c^\x9a\xdf\x1e|\xb1=\x9f\xc9]\xe1\x12/Xd\xf9\xab0Z\xbau\xd3\xadvE+;\x138==\x858\x88\xd39\xf9\xf2~\xe1\x12\xcf\x83r\x99g\xb7\x90\x92[\xc8\xdd\xef~N?\xa7\xd9m\n\xd9\x1a\xa1\x9e\xf3\x1d\x8c\x80\xc0\x08\xbes .`EJ\x88S\x06\xd8c\xac\x90-X\x9d\x92\xd5\xf9\xcb\x8b\xb7?!l\x0f\xbe\xf3\xb4\x8b\xe6\x03\x05\xcaA\x19^3\xc8\x81\xbf\xe8\xe6\xd1\x99\xb1?\xee\xef!\xad\x92\x84\xbf\xe3\x1b\x8a\xaf\xc5\xdf\xf7\xf7\x83\xae\xca\xd6X\xed\x9c\xb7X\x9f\x0bl\xb3\xf9%\xb7\xda\xba\xf4`\xbd\x81\xbc\xd5\xe6\x80a\xb3\xd2Ou>\xf5\xd1\xc3j\xcd/}\xd6\xfcL\xf2y\x8b_j-\xf9\xb0bE\xa5@\xad+\x1fd8\x057\xc5\x0f\x94\xd2\xfa\x83\n\xf1\x9f\x8f\xbf`\xeb\xf4\x14R\n\xea\xe4\xf3\x96\x1a\xce\x9bq\xcd\xd2Yy1\xf0h\xd2\xa7\x9a\x9d\x97y\x9c^\xbb\xc4\xa3\x18\xb2lUzh\x1f\xa8\xca\xf3\x81\x1f\xe9\xac>\xd2\xf5\xb9\xb2\x1dm\xd0F%\x1e:\xba\xc8\x87\x85\x0f\x89\x0fk\x1f\x96\x8c\x06\x81\"x\xdd\xa6r\xe83\xaf+\xfc\xd1\\\xe1\xa6\xaepn\xaepWW\xf8`\xaep]W\xf8\xc1\\\x81\x12\x88\x94\x0b\xc8\xe1\x18n\xe8\xbf3\"N\x17A\x1a\xf8\x81\x12\xf3\xae(\xfe\xed\xc1k\xe8\x0ds\x8b\x97\xbc\xc5\x98\x9eB\xd1Z\\\xb7f\xfe\xe8\nN\xe1\xb2i\x19\xbf\x91\x7f\xe3\xa7'\xadO\xe9\xf5w#Dvx\x98\x10hz\xb8?\x94Lv]\n\xec\xb7\x96\xf4\xdd\x8a\xfe\xef&\x8b\xe70F\x90\xb9\x9aE\x17\x1e\xe5\xa0\xe0\x18Ro\x16]\xf8@\xe9\xa2kZm\x01g\x10\xba R\xc6\xc7p\x87L\x98\xe9\x0e'X\xef5\x7f\x83\xf4\x96\x0f \xfd&\xf1Y\x87\x95\xbb\xf2\xe9\xa1\xa0P\x1e\xb7\xe1g\xcf\x87\xcbYt\x01[\xa7\x90\xe0\xcdu/\xb1\xc6\xda\xf3YOW\xf2[\x17\x7f\x9dB\xa2\x81\xd5f)\xf2 bw9\xf6\xe9I\x83S\x98\xd0?\xfeHI:\xfa\xc79\x9c\xc2\x1e\xfd\xe3\x03\x9c\xc2!\xfd\xe3\x07Z\xe7\x80\xfe\xf5g8\x85]\xac\xf53\x9c\xc2\x01V\xfbH\xdfN\x0f}\xe5\xc6\x17\x9b\xdd\xce]\xe3\xed\xdc\xd3\x8b\xf9\xed\xd4\xef\x1b\xbd\x9dO\x9c'\xd7\xed\xcb\xa9\xf7n`]@b\xe38\xaa\xca\xdc\xd2\xb3\x1c;\xda\xa8\xf3\x8c\x02H\xd2>\\\x1c\xde:N\x83b\xdd\x10F\xa7\xe0\x00\xfd\"\xa5\x18\xe7\x14\x91\x0f\xef(\xf7(%\x90\x84\x11q+\x1f\x9c\xed\xbfVYy\xe2x\x88\x99\xbe\xf3|\x08a\x04\xces\xfamL\xffz\xf6\xc4\xe1d\x9b\xf3\xdc\xb1m\xeffD)\xe7\x8b\xe5\xf2\x94a \xe2\x86\x9e\x0f\xb9\x9b\x07\x1f`\x04y\xf0\x1a\xbe\x87\xd8\xed\xa4\xd2\x04\x1f\xe580+/\\:\x07\xeb\"\x11\\#\x12\x94\xd9O\xd9-\xc9_\x86\x05q\x91{$A\xb1N\xe2\x12\xbf\x0e\x12\x92^\x97Kx\x0e\xbb\xeat=\x1f\x1c\xb6\x86\x94!\xe9C\xdc}\xe8\xc9\xa9R\xc6\xac\xce\xe9\xce\x89\xbbz\x1b\xa7\xf3\xec\x96n\"\xfb+x\x1b\x96Kz\x97\xf1\xdf3\xf1\xfe\xd8\xf2yA\x92\x05\xfd\x98\xfe\xab\x7f\x8a\xef\x8eA\xc0\x01\xd7\x11\x84\xe82.\x1c\xcf\xf5z\xf0\xe05\xc7\x83\xd7\x8f\xc0\x83G\x9d\xa4\xca\xbe\x8e&\xd9\x8d;\xfa\xdfC\xaa\xd8\x89\xb8\x03\x9d\x16\xa0Kb\x90m\xc9\x1b[o0#\xa5\x91d\xe5\x7f\xf27\xed\xe5\xcc\xe9\\b\xfa\xbf\x01\xfb/\xaf^6\xf8p\xbf\xc8\xf3\xf0.\x88\x0b\xfc\xd7\xdcX:\xb8\xb1\xff\xe57E\x9e\xf2\xb0\xb3J9nN\x17\xd0\xbe\x04;\xf2\xe9nM^\xe5y\x96\xbb\xce\xcb0\xfd\xae\x04\x8a\xdd)k\xbd\xcc\xe6\x90\xa5\x00\xec\xac\x9aey\x9bB\xb0\xa6\x15E\xb4e\xb9Vt\xb5\x9a\x1e\x94\xf3\x95\xdfi\x9f\xd0\xf6\xd2\xce\xd3\x89wq\xec\x03\xb9 \x13\xcfuXq\xd3\xfee\xd9\xc7\xbf\xcc\xfb\xf8\x97\x9b>\xfe\xe5\xae\x8f\x7fi\x18\x9c?\xdb\x19\x9c\xe5\xa6\xec\x08\xe5aV}\x8c\xce\x15o\x99\xb2Ns\xc1:\xd9x\xa5.\xdee\xa9\xf1.\x8ckY#3\xa0q-W\xc8\xb5loC\x88\x8c\x05\xbb\xbc\x94\xd5\xa1,\x0b\xf2\n\xc7\x90\"3\xb3b\x8c\xc3Rc^\x9a\xd3\x8f\xb5\xcf\xb0\xb6`rh#Y\xcd\xf7\\\xd7\xdc\xc8\xe9)\xb2:\xdd\x92$\x90H\xc6F\x90d\xa7\xd2\xc5C\xaf'\x05: Dr\xecf\xda?\xa0Oq\x1b#T\n\xf3\xebjE\xd2\xb2\xe0\xb4e\xdfw\xf4\x89\xc2\x82\xc0\xf8\xb8\xb7\x1eH\x02{r\x0be{\x0b\xf5\x07[\x9el\xde\xb2K\x0c\x94\xb5\xfe`\xe3\xd3\xc74\xae\xd0\xd4\xa6\xe7\xa1\xf3m\xab1\xba\xa1\xd6/\xecm\xd5\xea\x95p\xbdN\xee\xb8\xf2\xaf\xde@s\x8b\x0f\xe6u\x11\\\x87\"!\x904!\xb2J\xa5n\xcaE\xce\xfc\xa6\x93\x9b\xcfl\xdc<~\xe6\xba\xab\xe0&\xce\xcb*L\xf0\xe25\xbf\x10\x96x\x9cW\x17\xbc\xfeG\xfa\xcd%\xfd\xdf\x16\xb2\xfc(\x0f`\xdc~\xe2yV\x8e\xfe\x1f\x85\x8b\x9f\xeab3.dk\x953\x1cu\xa8#4\x8a\xa2\x8c\xca\xc3f\xaa$X\xb06\xf7=83W\x96\xd5n\x16\xccE!H\xee\x96\x9e\x8f\xb0'\xa3gtk\x8c\xdc.jL=\x03Y\x04\xcd!\xaa\xeaf\xd5\x0d\x91 \x9f\x87V\x7f\xce5)\x1d\n\xbc\x91\xb8r\n\xf1\xcb@>\xbe\x88\"R\x14Y\xce\x08\x8a\xa2Z\xd3\xfd \xf3-\x0bA\xe1\xdc\x84IEx\xdb\xf4\xd0\x95\x0cY\xa5\x01\xbe\xf0\xfcMI\x0e\xf9\x08l\xa5\xee\xf4\xc8\xb3\xf3\xfd|\x0cO)\x9e0+~\x7f{\xe0\x8a\xcb\xf6\x82\xa2\xe6\xb6S\xa4 w\xd1\xbe\xa0\xea\xfa{A\xd8\xcc\xb3\x9f\xd8o\xe4\x1f\x9a\x1a\xb4\x8f\\\xb4\xebWS\xa3\x06u\xc8\x92K\x82j\xcb%\xda\xdd\xb3\xb0\x85\xa9\xbb7\xf5\x14dk>\xf4\x82\xc5\x0e\x16\xbcF\xecNh5\x99t\xef\xbf:\xb5\xf1\x01;b\x1b\x9f-I\xe67\xb1L\xa8\x9b0\xdf\xa2\x17\xb7}iT\x1a<\x05\xc6k\xd8\xaeL\xdf\xa0\xfb\xf8`uX\xff\x8d\n\x8dne\xba\xb2rCd\x82\x88\x9bc\x1f2\x1f*\x1fB\x1f\n3\xa8\xa4@d\xcbHc!\x03\xd0\xc6\xb9\n\x8fL\xc9T\x88\xe8\x1c\xc9-p\x18\xf76N\x99B\x8e|\x89\x08SJgQT\xe59\x99\x9f\x00\x9dd\xb9$\x90f\xe9\xceJT\x9c\x93\x1b \xe9M\x9cg)\xc5\xffH\x0e\xd3J\x8b*I\x80\xd0VaE\x8a\"\xbc&\x10\xa6s\x08\xe7sTe\x87 ,I\xb2^T \xdc\x86y\x1a\xa7\xd7E\xa0\x9f\n\xfa\x90\xa4 \x1dD*E;3}\xb1.\xcct>}(\x86\x1f\x9bi\x11W]\nR\xcb\x80\x9f\xfck\xf1\xe4\xda`\xdedz\xf8A^\xcc\x92\xd1\xe8\xc2X\xeb\xc1\xf3\xbc \x0dW(\x91}\x93\xde\x84y\x1c\xa6%\xfc)\xce\x92\x10)\x99\xd6WmJ\x8c\xdd\xb2(X\xe4\xe1\x8a\x14\x9f\xb2\x0f\xd9\x9aQ\x1a\xd1\x1f\xcc\x1f\x0e\x82\x01}\x16!OM\x9c\xae\xa4\xac\xeeW\xec\x0b\xb6bvaa\xa3\xd8\xa5\x8eS\xca8\x90`]\x15K7\xed\x10V\xab\xb35_\xacD\x9d\nW\xf2\xca@.\x0b\xe2tI\xf2\x98\x83\xed\xdd}O\xfd\x84\xb1\xe8\x93C\x1d\x03p\x1e}\xf2\xd4\xd8\x16e\xbf*\xe9M=?\xdaK\xec\x86\x0d\x91\xeb\xf9x\x0b\xc7'\x10\xc13\x10\x1c\xd0 D\xa3\x91\xbe\x88\xe2\xc8\x17\xb3H[\xc2\xa4io\xb6`\xcc\xb1Vt\n\xa1R \xa3\xc2f\x94|\xff \xb1\x80\xf9\x16\x8b\x97x\x9e\xccY\xd0\xef\xd4\x91U\x1c\xfb\"\x9b@\x89\xbbP/@\xa9\xec\x16\xb3,(\x83\x9c\x84\xf3\xf0*a@\x98\x1bi\xf0\x92S\xd8\x9a\xb4\xea\xdf\xe6q\xa9\xd6\xafKD}Z\x18&Iv\xfb\xefa\xb2x\xbf&)7\xbdS\x1bRk\xd4\xad\xb5>\xac\x9b\xcc\xd2\x88\xb8\x0eA\x83\xa8u\xf7r\xae[P\xc3\xd0\xf6\xfd=+\xbd\x14\x138/\xc3\x92\x04$\x9d\x13\xb4\xd6\xc9\x83\x94|)?\xc5\xd1gw\xc9\x86\xd0\xdd\xe9\xb2\xbd\x87%m\xcd5\x89\xf2\xccTb\"\xf3b\x8e\x18\xd7\xbf\xc7\xd7\xcb?\x87%\xc9\xdf\x86\xf9\xe7\x16 \xa9\x18\x06j\x86\x83\xfd\xa4\xa5$\xd5\xd4\x17b)w\xab\xde\xfdfB\x9e?h*sR\x94yvG\xe6\xad\xe1\x0f\x1e\xa2$\xcea\xa3\x15\xe7\x14G\xab |\x0c\xf3i\x8e\x98\xfaeP\x8f\x8d\xd60-D]Acu4a\xa12\x113@\xfe\xfd\xa7\xd0X\x9f\xd9&A\xabx\x1d\xdb)m\\p\xc9\xbf\xea\xa3\xfc\xb1C\x86?\xaa$\x11\x17\x16\xcf\xbe/\xdf#\xe2\xcb}\x7f\x13499\xda\xb3\xea\x8a\xec\xbb!\x8e=\xaetN\xd7\xb56\n\xeb\xa3\x8a7\x1c\xdf\xde\xc1\x9e\x01\x8f\xbf\x0d\xcbe\xb0\n\xbfv\xeds7\xde|\x02\xd2\x80\xcc\xe3\xd9\xb73\x88LZ2\x90\xb5\xfb\x87a\x10\xa7\x87\x1b/\xf0\xdf\x85A\x1c64!\xaci+\xc1J8\x93\xee\xa0\xcd\x19\xe3\xdb\x8f\xa8S\xc8\xb5\xb5U\xba\x1d\xf2-\xebg\x9a\x85\xeec\xf7\xdeb\xaeg\x16$\xee\xeb\x06\x96\x8c\x90>:\xf4\\\xa7\xc8#\xdd\xd4\x81\x92\xd3\xb5\xd0\xb6\xcc\x98\x1dI[\xfd\xe5:\x0e\x8c \xf4\xb8=\x8a#j\xca'\x06-\x08\x838-\xd6$*\xcf\xb3*\x8f\xc8\x90C \x08S\xe9f\xf96K \xc1\xa5\x87&\x12=\xb2Y`\xa4\xea\xa9\x8e\x10\x7ffn\xea\x83CYB\x07\xf5@q\xf3\x9b\x1e \x8a\xbc\xe8\xadm\x8c\x97\xa4\xcf\xaa\xe6\x8b\x8a\xd7;\x03\\\xa1\x92i\xb1\x8a\xe0\xd7,N\xdd\xda\xda\xd7\xc3\xf6\x90\xe2\xcd\xe1\xac\x86\x07p\x0c\xa1\xf8\xa9\x94\xc6\xcd\x818\x06wN\x12R\x12|\xefK\xaf\x14K\x8fF\xf2.\xd3[\xf56u0\xd2\xe2.\x1a\xef\x19e;894\xab\x90\xc1\x91\xf8\x08\xb9\xffot\x0d\x7fo\xc0\xb01\xd66_\xbd\x03\x93\xa2\xd9M\xdd\x83\x03\xcf\xc7\xf7\xe3\x86 \xb69\x98\x18\xaf\xe9\xe4@7\xf3\x0b\x8d\xaeT\x9f\xc9\x9d\xd9\xff''\x0b\xf3\x8b\xcb\xcb\x82$\xf6wx]\x8f[ \xcb\xe4%VX\xb7M&[\x83\x9c,\xa4\xcdh7\x13\x0dk\xe63\xb9\xd3\xf6\x14$\x96\xbc\x0d\x1ar!\x962\xc2\x88\xb6\xbc\x92>\xff\xf2/\xec\xf8\x1cC\xd5^\x1c\xfa\xea\x18\xca\xf6\x0b\xdc\x03\x83v\x1b\xb7 m\x97\xaf\xf3l]\x1cChX\xff\xec6%\xf917j\x12\x8f\xd9\xfbI\xb2]\x91\xc4\x1cA\x94\x93\xb0$\xaf\x12\xb2bn\x15}\x94 \x9e\xf1\xda\x17\xa25\xa2\x84\x9e\xc6*I\x0c\xb3\xe0o\xd4\xc1QZ\x83\xdfNY\xdc/\x1e\x14\xc3\xe4\x10\xd3\xc3CP\x03\xef\xae\xb9\xef\xc7\xc2\xf3!\x12\x85 3\x98\x1c\x01\xa1\xfb\xee\xf9 \x8bM\x03v\x84\x05\x1c8\xaeK\xda\xd5\x18\xf2Q+b\x19\x02\xa5\x8c\x810\xe6\xbb\xb7\xbd\x0d[\xa1v5]V\xeeV\xcc\x93\x11\xfd\x1fOZ\xcb\xb7\x84S\xd05\xe8\xb0\x03\xd3\xf6\xca0Y\xc7\xd2\x83*\x88\x96q2\xcfQ\xa4\xa1\xa1%\x94\xb9\xd2\xdaKx\x0e\x13\x13YQ\x0b\xb3\xe6\xc2\xac\xcd]\xd25bb\xac\x1bx\x06\xcb\x13\xb8\x19\x8d<\x98\xcfn.\xe4\xd1\xcdn`\x04S\x83\xfco\xec\xabc\x9a\xab'\xb05\x13\xee\x15\xc8=q\xe8z\xb5\x84\xe4\xc0\x97\x07\x8dO\x94\x9a\x16\xf1#\x9e\x8b;O\xdeD\\xi\x07\xee\xe8\x0et\x0cM\x08\x80\xe9ig\xee\x03c\xfc/\x0eP\x8a\x9e\x96\x14g7\x17\xc7\xaf/\xcc\xeb0*\xb3\xfcn\x90G\xa4v\xc9\x82\xab8\x9d\xbb\xdc\x07\xc9L8\x93@(\xd75/\xc5E\x10%YJ^\xa4\xf3\x8fL\xdc\xfd\x1f\xa4\x97\xb9n\xe6\x18p%\xbd\xcf\xa0,\xfd\x87\xdf\x03\xfa\x07?\xe7e\xc0\xa0\x8a\xcf4\xfb\xebB\x9f?\x1d\xc0f\xf0\xa2\xaa\x0d\x9brTd\x8a\x86\xdb@\x02m\x9b\xe8\x15n\xbfB\xc1\x03\x0e\xbb}j(\x12\xed\x9a\x8b\xb79\xd0\xa9\x14\xa03\x17@\x87\xdd\x9a\xfax\xc80h\xa9\xc3 \xb6\xde\xec\xe0#\x1e\x97\xcft\x0d\xb6\x0c\xef<\x0d\xdaT\x16h\xc3\xca\x15\x15\x11%\xb6T9P\x02g\xb0\xa6\xc5\xa7\x90\xd0\x7f\x8e\xc5/Z\xd7\x00\x9d\xee6\x84Nw\x1e\xac\x87@\xa7\xbb^\xe8t]C'\xbaz+\x06\x9dV\xf0\x0c\xeeN`E\xa1\xd3\xf5l\xa5B\xa7\x95\x05:)\x03\xba\x1et\xff\xf9\xddX\xfa0\x17@\xe0F\x95\x13\xd3\xc3\x1f\x17\x7f\n\x93xn:\xfe\x9bP\xa4\x8a\xbc\x88\x1d\x10AJ00&\xf7\xaa\x10\xc0\x7f\x80~\xe2T\xd2\x0e\x1f\x98Y\xc0\xdd\x83~\xa9@\x87\xb3\x03c%\xcc\xa0+wS\x8f\"P8\xe6\x87\xb0\x99\x8aq\xec\xfa\xc09%\xa6\xab\x8a\x8d\x04ef\x10\xd3\x0b\xc3R\xae!-H\xf9)^\x91\xac*a\x192\xb1\xc5\x15!\xdcK\x97\xcc\x9dn\x91|\xd5\xdfA\x94\x900\xff\x8a.B\xb3\xfc%\xc5s\xd0\x8c\xbe\xd6\xda4Et\xf9\xc6\x06\xc8\xc6\xbf\xcd(\xd3\xb5\x95\"\x880\xb4C\xf7\xb1)\xf6{\xda\xed\x94r\xa4\xec\x0b\xf5\x9a 9\x87\xd1\xa7\xd5\xdc\x1c\xb4l@8\x92l\xb5\x0e\xbd=\xb4\xdb\xe2\n,s[\x16\x10\xf1\xb0eg\x7f\xcdsHm\xb2\x04\xe9 \x9e\xc9?Z\xc4{\xa7\x80(\xad=\x18\xea\xfa\x03\x06\x95\xdb\x06\xa5\x1c\xde3\xf5\xe7\xb1\x04\x85\xa0w`\xb4\x8b\xca\xb6\x8a\xae\xa6\xa2-\x98\nu\xa6i\xfe\xd1\xfeV\xd3@Q\x0c\xb931]\xfe\xb6\x8e\x8e\xf9? J\xe4M\xd5\xeaY:9z\xe0\x83(K\xa3\xb0t#\xb4/\xc4\xb6}\x88D\xa5\xedmX\xba^\x9f\x96\xcet]\xb7\x166j\x96\"\x89\xd0]\x1b\xd4\xe28F\x83uC\x8d\x0f)\x01\x18\xd5\xfaerb;\xe7\xf8\x01\x85\x92\x91X\xd7\x13\x18\x8d\x12x\x86\xdf\xe0\x82\x14\xb3\xe4\"\xc8\xab\xd4\xb5X\xbc\x8a\xa5\x90\xbb\xec\xb9%\xc0%|\xec\x8e\x9a\xf6N\x865\xbc\x92\x0b[Jk\xbd\x1d\xdeP\x85 \x90\xf1d\xc6F\xe9\xa9\x95_\xf8\xc3\xbb\xb1\x830\xf1\xe4n\xd9\x864\xe2\xe9\x87^\xe2\xe9\xef\x08d\xb5\x83\x0c7\xed\xdd\xc3FC\x80V\x07\xc2\x1a\xa0\xbb\x03\xfb\xec\x8do\x1e\xf4\x05{\xe8\xbc\x89s\xbb*qQ\xa5\x92&3\xa44%%x;\x9b\xbbq\x15\x8b\xd3\xb8\xd6:\x0e\xe2\xf1(E\xc0hW\x03\xed<1`\xe9V5J\x1d\xdba\x01\x9d\xcf\xe4\x04Rx\xd6\"\xceO \xa5\xc41\x99\xa5\xb4+\x95@N5\xe28\xe2ZVr+\x96\xcf\xf3a\x82th\x0d\x05\xef\xef\x01\xa3s\x84\xeeR\xa1~\xe7\x92D2\xaf:=\xa6\xc4&p\x9bs)\xde\x06\xee\x85\xd2l\x1c\x94q\x89\xd6\x1f\xceU\x9e\xdd\x16$wh!\xff\xbb\x89\xba\x94\xde\xf0\xf0\x1bq\x10\xe6\xd77\x0c\x7f@\x1cp\xbbAd\xbe\xa4\xdfE]\x1b\xdf\xdd\xe0w\xf3\xf9OqQ\x92\x14\xdb\xbda/Q\xd9\xc0\xfe^,\xc4\x9f9Ye7D\xaf\xccJ_$\x89xQ\x887d\x15\x97\xe2\xefuN\xd6$m\xf5\xc4\x8b\xdf\xa7Q\xab\xddDj\xae\x97\xa1\x98]\xa8\xabw\x15\xa7\xf38\xbd\xeeVR\xe9T\xeb:\xcf\"R\x14\xf5\xc7\xb1f%\xedh[\x14\xdd\xce\x07x\xc89O\x1c\xed\xb3\xe5\x0f\x18\xd9&\\\x88\x91R\xe22y&\xc8\x81\xb3\xe1\xbd\xf9\xd3\xab\xcb7\xef^\xbfy\xf7\xe6\xd3_\xb0\xc6\x04\x9e\xd8V\x9a|)I\xda\x8a\x8bh[\x02\xa6\x9dk\xd3Q6\xf9-.\x0d[:7S-\x9f]\xe2y\x0d\xed\x04\xcf o\xd6\xae\x9c\xc5\x94\xc5\x9e\xa5\x17LD\x1a_|\xfb+$J%9\x9d\xd9]\xa5\x15\xd4\x8fYj\x8c=\xd35\xac:5v\x063n1\x95 N\xa3\xa4\x9a\x93\xa1\xa1\xcb(\xa7_\xf7\xa5\xbc~\xe0\xc6\x0fC[2D@3\x8c_<\x84\x85\xc7C\xe5.\xfdk{[\x84\xc6ce\xf8\xe7\xf66\xe4\xc2\x12\xbd\xd5\n\x1d_\xca\xde\xea\x9c\x06\xbeY\xc4IIr\xb7\xf3-IN(\x11\x17\xa2\x17\n\xfb\x06\xc11z\x0d, \xd4\xe3\xa740d\x0b\x08\xa1\x88\x96d\x15\x06\xf0F\xbcb\xf1\x0d)>\xc8\x16PT\xd1\x12[(Z\xc4a\xe0\x18\x8e\xe3\x12C\x1b\xae\xd6qB\xe6o\x9a\x95\xab8\x0b\xeb\x88\x018>\xcc.\xf4\x0f^}i\x7f \xd6\xd3\xf8\x01E\xcco\xc3u\x17E\nB0\xc4n\x90\xd1\xae\x80>l\xb1\x8e\x8dZv|\xcf\xc3j\xdak\xf0`\x9b\xf6\n\x8b0I\xae\xc2\xe8s+V.}d\x89{\xfdA\x07\xce\x17O:cW\xf1b\x86\xd7\x94\xf9P\x8a\x9e\x9a2C\x0c\xc3vw\x14\x90\x97\x0c\x90\x13\x83Z\xea\x04J\x86\xf9J\x0e\xbd\x1b\xc6W\n\xaf\xa8k\xff@\x12\x0d\xab\xe7\xc55\x9e\x16\xcb\x99\x90/\xb7\xf8+\x0c~|\xf5\xfa\xc5\xcf?}\xaa\xe5b\xa1`\x19:N\x848\x0d\xea07\xf1\xb5\xef\xf2\x80G\x01\xa4\x18\x97\xb6\x8e\xb3\xb1AyF\x9f\xab\x9c\x84\x9f\xdb\xaf\xba\x9c\xe1K\xada\xbd\xab\xc9f]q}\xa8\xa5/\x19\xc8\xfc9\xcf\xd2k`\x9e\x81\x08AD\x97x~\xce\x194\xe1\xbbP\xb3v]F\x01\xcc^\x81\x02vN\x0c\xd6N\xceM \xf3\xe5\x0b\xc8\x0d\xc9\xefz\x80\xa7\xc0\xb3\xb2\x1bN\xa8\x01*\x0dn\x9e\xd7\x916\x05XDn\x88\x83\xc6\x02\xdc,\xa7\x802N\xaf\x13\xc2g\xc8Mq=\xca\xa0\x95a\x9c\n\x98\xab\xbcm\xf9\xec!wA\x1e=\x8dl\xd3i\xd4\x81B\xb59P\xb8i\x9b\x81\xf4\xae5~q\x8f\xc9-\x84\xae\x01o1\xf4id\x89\x05\x1c?\xd6\x1d\xd3\x14\x11\x83\xcc\xa4\xb1M\x1bj\xab\xf8\xdb \xcaP2Ho\x05\xc6\xe4\x81Om\x16\xe9\x83}\xf9j\xcdl\xe9C\xac\x83\xad^},s\xee\x16\x06\xa1\x9b\xb2\xaf\x9a\x0e\xce\x0b\x8a$\x8e\x88{\xe8\xc3\xce\xa4o(\xdd\x0e\xf5{\xbb\xff+\x1d\xea\x87-\xeb?\x80\xd5\xf9\xb7:\xf7\xfb&?U\xe6\xdf\x12\xa7\x8f\xa3\xec\xb3\x9eC:@/+\xb7=\\7+\xf5\xf1\xa3&F\x1d4z\xfaQ\xcf\xd8\x91\x86\xda\xb8a\xfcJj\x19\xc3\xc1\xc8\xb21\xac`\xeaO8\xdc\x0e\xeeR\x81\x9e]G\xe6C\x1e\xaf\xe22\xbe\x19\xbcL*\xa1i\x04\x1d\xf8\xc2p\xbdX\xfc\xc5\xf6\x05a\xe5\xed#\xaeS\xb2FPW-\x16x\xe9\xcb\xfaG]\xed\xc1\xab\xddaR\xf7\xe0\xd0\x0b\xd8{\xb3@es\x0b\x06\x03\xe9\x8e\x1b(9-s=\x80\x08\x06\xf6\x97\x17o\x7fz%\xc2\xae9u\x82\xaa\xb0\xc8d\xdb\xc3U\x98\x7f\xe6\xa6?\xf8\x93\xc7V;mb%\xd1\xfat\xcd\xdc\x8a\xa7`be\x1ef\xb0p\x9bF\xcex\x02\x8c\xba\xa4\xc6b,\xf7\xa4\xe3\xf9\xf5\x90\xd7e\x95\x93\xf32\x8c>\x7f\xcaCth\xb4\xbc\x11\x86\x9cK9\x01X\x86q\x88\xb1\xac\xa05\xd1EYXhy\xbc\x8c\x0eY\xb2\xf6\xaa\xff\xca;,\x9c\xd8 \xe4HZ\xb9\xd5\xf2&W_\x8a\xb9\x0e\xa3U\xea}\x1a\x81s\x0c\x8e\x91f!h%\xd1\xb7 >l1\x07\x9dz\x1f(\x85C\x9a|$\xa6\xed\xd0s\x0b\xca\x94\xd6\xa0\x84\n\xbd\xf6\x026\xf7\x1d\x96\xcdK]\x95Z\x08>K\xdd\xe9x\xeaiV\xf7B\x01\x8a\xef\xf7w'\xe8\x88\xbe\xbf\xdb\xaa\xd7\xc8\xcb\xb1\xde.\xaf\xb7\xc7\xff\xdd\xe7\xff\x1ex\x92\xc5\xcbc\xc5\x9dv/\xc66(S\xcc\xda\xdc lCip,\xd4\xcc\xd6\xdc\xa9\xa5\x9ed\x00\xe7\xeeY\xeap3;Mm\xa0\xdd\x85!ru\xcd\xc4.\x17\x82\xcf\xb8\xa3Q\n#\xc8\xbd\xe6\x00\xef\x1e<>\xae\xce\xe3\x03\xfapV\xea\x11a\x89$%\x8a\x1e\xc4\x84\x87\xf7oE\x1f\xcax\xb9\xce\xb0n\x10=\x99\x05\x8c\xfdg\xf4\xe4\xea\x9bDO6\xdd\x8f\xbfOPa\xd3H\xf0ZF$N,7v\x91dY\xde7:\xcb\xd0\xe2\xe2]\xf8\x0e\x15\xce#\x14#\x8c\xe1\x18\\\xa1\xc1\xc81OZ\xbfD\xc1.\xaa\xe9\x0f\x10\xdcw@\xd5\x10\xb4|\xd4\x9a @X+\x18\xad\xb7\xba\xcc\x13xs\xf5h\xac\xe6_R\xe5\xb2!\x05\xdb\xf27\xfa\x18D\xd7]\xa6\x0b\xad1\xf4\xe4Nh\x0f\xc3\x1a\x9b\xdf6\x92\xdd\xe1#Ah\xb0\xe1`\x14E\xaf\xfc\x0c\x90N\xd6\x9dw0\x0e\"\x9b\x00\xb1\xa6\x12\xd8\x04\x1f\x0e\xbb.qoB\x99\xded2\x8f\x0dTf\x8f\xaefQ\xdaO\xc6\xbd\xb7\xce\x02\x0d\x1e\x15\xd6\xae\x8f^l\x85\xfc\xe2\xf2Z}\xf0\x0c+\xb62\x06VbNm\x19m\xea>\x16\xbe\xdc\xf0\xa8:\xa1k\xa4\xd7\xb0\xed\xca\x87\xc2\xe7\x99\xf0\x0c\x95(\x1e\x8efcC\x00\xe9\x04\xdf\xe8&G\xd9\xb0\xcc{\x1d\x9a/2+.\xba4\x9fZu\x83q\x80\xcf\x8c\x12xv\xbf\x96\xc5(\"\xcf\x98\x07\x00S\x1c\x17|X y\xc0\xe41\xf2\xab\xc2\x87)\x93\xb5\x9eu\xe3BhF\x96\xd4\xf8\x90q\x80\xfa@\xa0/\x16\xa9\xb1\x1d}6}\xc7Xn\x98\x91U\xbf=\x18\x15\xd0\x8f\xbf\x04\xc3.\x9f\xa2\xeb5y\xf01\xedo\x13p\xfd# \xa3\x92\x07L\xff?\x0e\xcf\x84\xec\x9c\xc0M\\\xc4%,\xcbr}\xfc\xe4\xc9\"\x8c\xc8U\x96}\x0e\xae\xe3rY]\x05q\xf6$\xa7\xdf=\x99gQ\xf1\x04?\xde\x99\x93(\x9b\x93>\x81\x9c\x999\xe6\xa3\x91\xc7,\xd5\x9d\xed0\xbf.f\x17X\x8f\xa4\xb4\x89\x9f?\xbey\x99\xad\xd6YJRY\xaf\x96\xc3\x08&\xba\xf2\x8c\xb5\xa1\x06\x7f\x17\xa2\x89,\x1f\x1e9\xbe\x89\x1a_\xf4\x87\x8b?i]\xff\x18\xe4\x10\xee\xba\xaa\x8e\xc1\xf4\xb83\xfa\xba\x0fq;\xacz\xdcs\xea\x06\x9d\x1b\x89\x82\xb2q4\x8f`\xe5\xebb\xf1I\x87\xf7\xcc <\xac^\xb8?\xb4\xff\x12\xeb,\xb7&\xc1\xb78(\x97a\xf9\x11[+\x98\xd8E)z\x1d&\x05Z>\xba\x18H[y\xf7)\xaf\xf8\xab\xb1\xfe\x8a+\x17r\x11\xcfW\xfdn\x19w\x9a\x8f\x88\xb9)\xf9\xf6\xb46^\xf0\x03>\x04\xa5\x9a\xfdO\xe0\x94\x1f\x94\x8d6P\x94v(\xa5\x9e|\xbf\xa5n\xd7\xf7\xf0iI\xe0\x8a 7W\xd9\xbcJ\x08,\xf2l\x05i6'\xc1\xaf\x85__D\xee\xf4\x1ah\xdf\xeb\xcd\xfd[X\x95\xcb,\x07\x80\xd7$\xcf\x8a\x02^\\e\xd5\xe7e8\x8f\x7f%Kx\xb6\xc0\xc2\x7fc\xff\x04Y~\xfd\x1c\x9e \x88\xd4\x94\xb5\x1a\x15\xf6H\x8aA\x12{\xf9\xa4uu\xb9\x1c\xaa\xc5?CC\\\xb4\xb2\xe4A\x93X\x0f\xef\x94\xf2\xb2\xbe\x10\xed\x98+\xd0le\x11|\xfa\xcb\x87W?^\xbe\xf8\xf8\xf1\xc5_.\xcf\x7f\xfe\xf0\xe1\xfd\xc7Op\x06\xd3\xc9\xde\xd3\xbd\xc3\xdd\x83\xbd\xa7p\x0c\x93\xf1\xd3\xdd\xa7{\x93\xc3\xa9\x96\xef\xd6\xd2ah\xc5\x95\x94\xe2\xa4\xc3yF_7\x86\x17\x1f\xc3\xf4Z\xf0\xc9\x14(%\xf1\x1cI\xd190Os\x865:\xcc+l\xb3p\x85\xbd\xd3\xcfqZ\x1e\nCc/\xb8\xbcDl\x7fy\x89!,\x1a\xf9\xea\xb1b*\x82l7o\x00}\x9c\xe8a\xe7\x18\x8c\xe5\xb8\xd3\xa1\x85y=\n\x1b\xc5\x06\xc2\x88\xcb5O\x80\x07\xc4\x97\x95 \x85\x9an\xa0i\xba\xbd6H\xde\x1b\x14\x0d6\x12\x0b\xeb\xb7\x15\x10\xcaN\x89MZ0\x1c\xc9=\x9d\x8b\xda,\xb9\\\x12\xe6\x86\xb2\x88\xf3\xa2\xac\x11?\xac\xaa\x02\xedgB(Z\xd1j\xe5G\x10A\xf6x\x08\x0f\xb63\x105\x01i\x0cr\x1c\xcb\xd6Db\xfd,\x0c\xaae\x0d\x89\xd9l\xe8;!\xb5Q\xe7\xcdm\x87BnR\xdf\x91~\xda\x9c\x89\x16\xcf-W\xe5lo\x03\x91\xcf\x83\xfc\xae\x1dK\xbb\x83\xedFW\xbf\xe0\xea\xae$?\xe1\x89\xf6\xd1\x0co\x0c\x98\xeb\xba)\x86g\x8d4K\xbf\xaa\xdfe\x8bEA\xca\xef\xe8\x11\xc8*4G\xbf\xca\xaat^\xd8vW\xef\x936\x0e#p1\xf7\xf0\xd8\xb3\xf6\xc3\xee\xdc\xf0~0\x00A#cI\xa5\x00n\xa7<\xf0o\x0b(\xd4F.\xd6*x\x81\x8fM\xc5t\x99\xcd#\xe9\x04L\xa4\x0b\x10\xd1\nk\x06H;\xaf\x8a\xc1\xd0O\xd9\xfdc\x93R\xb1\xc5\xd8tx \x1a>\xc7\x05\xad\xf3\xc9\xdf\xdf3\xe7P\xa7*\x17\x87][\xbfU\x04q\xf1\x8a\xc3\x0d7\xb58`\x7f\xe7\x08\xd0\xe2H`\x83!\x056\x94\x1a\xf6\x98n\x12H\xf8t\x0c\xf70g\x1bg\xf6\xd7\x02\x8e\\]\x16T\xa8d\x86\x8e\xb7y\\\x12\xd7\x02U\xd9'u\x96\x02\x97\xf9\x042#\xfc\xb1\x0f\xb1\xf7\xe8\xed\xf2\xfaL\x1f\xc5C\xd7\xb2\xa8\x15\xba\x141uH\xb3j\xd5\x08\xdc\xc3\xd2%\xc2\xe7\xc9\x166c\x08\x906\x9a]Iu\x82\xb8\xf8SLX\xda\xfdv\xb1\xc9\"L\xaa%\x8f\xb4!0\xdb\xa3\xad\xa9\x99-\xd5R\x0e\x11\x1dK\x1caX\xe2\x9b:\xd9f\xd7*pj\xb3\x1eIW(\xc2\x1c\xc3\xfb\x9d\x9cx\xb5\xa2\xcf\x8a Q\xbd\xe5\x84E\x14\xc7\x8eY\xc9\xc5j$a\x19\xa7\x93\xce*Wq\x1a\xe6w\x96* )w\xcd\xe8\x845\x82d^W/U\xb9\xd8\xe9\xac\xc1\x08\xed\xdeQ\xfc\xec\x96\x9eu\xc1\xa1\xe9.*\xa6\xdd\xe3\x89\x8a\x9d\x9e\x1a\xe5br\x90\x90\xbe:;\x1d\x95\xa0\x19\xf7\x14\xbe\xef^\xc1%\xf9\xd2\xdfJ\n\xcf\x9f?\x07\x83?\x114\xdb\x19\x16\xe4`\xaf\xbf\xa9\x1f\xfa\x16\xb2\xd37\x1c\xa0v\x0c\x19\xba1\xc0\x990\x96\xac\x86Ph\xf6SvK\xf2\x97aA0\x03\x19F\xa1k}\xaa\xebR\xcd\xe0\xeb\xa6\x8bc\x11w\xab\x9c\x11\x03\xec\xe7F\x14\x14\xfd\xf9\x02 \xe6\x83:\xbd\x93\x98*\x8b\xfe\xb8\x01\x01eM1\xf2\x05\xdb1l\xa3E\xdc\x92R\xee\x10\x85\x81\xdc?\x0eyNx.K\xe4\xce\xf0\x8d\"\xa2\xa3\xd8}\xa7.9D\x90F+Ie\x1ekp\x94\xfa\xdcB\x82\x852\xc6j1G\xce\xa5\x1ccQ\x88\x04D\xa5\xfa\xe5\x08i\xfd\x94\"\xc0\xb2#\x88\x82\x98e\xdc\xb9\x0e\xc0C\xe0\xc8]\xb7OF\x13\xf6h\\\x99\xc2J\x91\x86}\xda\x99\xc01\\k'\xcarB\x8c\xc2'\xde0\x81m\xa4u|\x8b\x9c\xc1\x86t\x1b\xf1\x85d\x10\xcac\xee\xc0\x19\x1e\x86\xae*\x8d\xe5\x0f\xe7Z\x8d\x95\x93\xb0(\xdfX>\xc0\xb9c\x12%\xfb\xec\x8d\xbc\xcbM\x98\xd4\x84\xbd`WD\xa0\x8a\x9c\x93W\xadP\x14\xe6\x1b\xad\xaf\xbf\x05\x98d,5\x8b%\xbc_(\x1d\\s\x8dB\xa2\x82\xcd[,\xa5\x16`\"\x05\x86\xd1\x18\xffM!\x01'\x04s\x0d\x8c\"=\xc4\x91\x1b\x17Za\x01\xc7ej\xd1\x8eTf\x95\x17\xc4,*\x91\xa0\xd8\xa7L\x18\xd8\xfc\xee\xbdWt\xa5\xa6>\x84\xf0\x04\xff-\xf8\xbf)\xfek\xb8o\xad\"M0k\x1b(\x1f\x06\x0b\x17U\x89\x8c]\xc7<{\xee\xcfo\xd2rr\xf0\xc3+\x97\xc0\xf7r\xb6\x11\xf1\x98\xef\xb9\xd5&H85\xda&\x8d4\x1d\xaaaN \x83g\x10\x9e@6\x1a\x99\x992\xe0\x9d\xe1\xf42\x0f\xc7\x1fQ\xf0\xc1C_-8\x1c\xce`\x07\x16\x9dr\x1d\xd1R\xfd\xa1\x88\xd2\x9dy>\xfb\x1cF|\x81\x8az\xdf\x16tA\xacMr \xbb\xc3\xc2\xd7\xb2\x163\xd89\xe5\xa3\xf1\xf9*X\x80\xb3}mR\x18A\x01\xcf!\xac1I\x08;P\xe08\xf9\xaa=Gf.\xdb\xd9\xe9\x9arM<'<\x88\xed\x9a\xf1\x80kx\x06\xc5 \xac\xbb\x16\x1d\x94\x85\x87\x11\xac=\x16\xa4\x97.\xfe\xbaw\xa5\x81\x9b\xc0\x98\xfc\xbb\xf5\x07\xe3\xeft\xd62\xcbq\x80\x0f1\xa9\xb7+3\xd6\xb3j@vt7k3\xe0[\xf5h\x07\xe8\x061o1J!\xdc\xdf\x9b\xf8\x18\xa1\x04\x97\x90\xb6\x81\xe2\xcd\x05-\xc3\x9b\xa3\x90\xe79\xc4x\x0chqLq\x01\xfea\xee!\xeb\x85\x9d\x19\xfc+L)/7\xb68r\x0bu\xe2\x92|\xe9P=\xe5\xf0\x1c2x\x02\xd3zh\xf8\xabK\xfeP\xb1\xb3W\xb1h\x87\xa3Q\xd5\x05>(\x9aX\x87yA\xde\xa4\xa5K\x82\xa2\xba*\xca\xdc\xa5|B\xe5\xc3\xd4\xf3ar\xd0!7g\xd4\x9a$(\xac\xccu\xcb\x19\xbdi\x98\x8a&\x1c\x00\xf4Dc\x83\x0e\xcde\xcf\xa1\xe1\x8d\xfd\xd5\xfd\x19s\nK\xc7\xc2C\x95\\\xdb\xa0\xd3\xd6\xd3\xd5\xd0\x9e\xec\x06\x03u\x9b\xb2\x11\xd2\xecB 8Q\xb3\xf2L\"\xc6\xb3\xed3\xc1Q\x19D<\xe4\xc4\x8b\xd2M{$\xfam\xc0\xf7\xc0dy\x9bL\xfav\xd8\xa4\x95\xb5\x19\xd4\xf0\x97a\x0d\xff\xd5\xfda\xf3A\x9f\x0fm{\x90VC\x0e\xec\xc0\x83\x93\xf2]\x93\xaeZ}\xb0\xb6\xb7a\xcbu \xc5NS\x0f9\x02~ \x19+!\xed_\xc5\xf9M\xcaO\xc3!\xcb\x84\x93R\xb0\xb1\x7f\xe0C\xc6\xb6=\xf6\xea?m\x9a<+H~\xf8\xda\x03\xff\xaa\x8b\x9fUY\x08\xf4\xe9TXL\xf4\xd5\xa7<\xc8\x0fw%\x91<\xa2[\x85\\E\x85\xfd\x0c\x1b\xd7\x8b\xaeq\xa5RL\xa1\x9af\x1c \xb2\xc5\x10\xf3\x18\x83\x1ab\x14\xddv\x81\xcd\x8c\x85\xf8\xf0E~\x93r\x16\x1bLS\xc5\x83N$\xc6L\x89\xe2A#V\xcaJ\xef\x1e\xc1\x19\xec\xc11\xfb5\xdd\x853\xd8\xe5\xbf&G\x138\x83)\x1c\xdbD/\x08\x91a\x04 \xad\x87[|\x83\xe1Z\x8c\xf8\xc5#\x8f\x8f\x81\x05\xf6kz\xe1kS\xc9p\xf4jY%\xcdh\xb2_\xcfh2\x85{p\xc5\x9c\xe4)Vt\x8a\xd3\xf1\xdeS\xfe\xdd3\xd8\xdf\x9f\x1e\x1dP\x92\x88\x92\xb3\xfbOw\xf7v\xbdo:\xff\xbd\xc7\xcf?\xac\x7f\xedn\xb0\x1ajYhY\xa1Cm\x85\xa4%\xab\xd4%\x0b\xe9\x92\x1d\xec\xef\xef\xee\x03\x06\xf4x\x06\x93\xc9do2\x99J\xcbd\x9c\xa2\x99$\xae\x8d\xb1(_\x84\x9f\xd3\xb6w}\xbc\xc9\x18tl!\xf7\xe7.(>\xa0?\x0f|\x11\xb5x\xc1\xc4\xa8c\xd8\x86\xc9x\xba\x0b\xf7l\x1397\xb3\x7f\xb0;\x1d\xc3={\xb5\xcd\x0c\xc2\xf9w\x1e\x05T\xa3SH\xda\x10\xdf\x06\xa5\xfb)\x12A\x8c\xd8\x15 \x14\xe3\x14\xbc\xbc\xafI>C8,\xee1\xc2\x13\x85\x1b\xf5\x16 \xe9.\x1c\xc7\x0e\x18s\xb32\x10\x04\xf4\x16\x06\xd3\xdcXz\xc0`8\xba\xc9}\xa6\x9a{\xdfCD\xa5\xedEv[\xe8S\xfeE\x82\xda\xb7\xbd\xf0\x81\x04\xe7Iv[\x97t\xef\xc3\xa8l\"\xab`,\xdc.\xbbBT\xdd\xb9#S\xa0\x837\xef\xce?\xbcz\xf9\xe9\xf2\xed\x8b\xff\xef\xf2\x87\xbf|zuN\xcf\xd3\xd8&\x8b;U\x93)\x9b\xcd\x82\xcc\xe5=\xb1\x13\xed\xf9\x8cn\xa4\x88o\x92\xc9\x92\x9e=G<\xb5\x02M\xb6J\xb2\xe3\xb4\xba\x96Y\x00\xd8\x81\xa8\xb3l@8H\xf1\xf0Q\xed\xb5\xe5G\xe21\xc3\x8e\x07\x1f\xf6\xa6\x9cVZd\x99\xebY\xc5\xa1%e\xc8\x98\xa5\xe9\xf6\xb6p\xeb\xad\xcb\xdc\x89\x0f\x13OR*\xb6\x8fjg\x0c4h\xe6\xb0e\x90\x9d\xa8\xe7\xca\xf5\xe8\xc9\xfa\xfc6\xfc\xc2-\xe4P\xc5L\xcf\xd4:\xcb\x92\xf3\xf8o\x14x\x1cN\x8e\xa6\xb4\xe82\xac\xae{M\xb6\xc1\xb6\xb1\x85\xe2\x0c\xa3\x1fo&\xd8\x1e\xe0u$\xb5\x1f5\xe9\x05\x0d\x16\x98\x1dBjW\x1a\x8b2F\xe3\xb9\xa237\xd6\xf1-\xf6\x93<\x9c\xcc\xf66\xff+@{U\xc2\xf3\xb8\xa9e\x17LbF_\x99\xc3\x9c\x16\xbe\xd6\x8a)\xe0)wh7S\xa3\x9d _\x1e\x98\x1a\x01\xc1\xcef\xab\xbf\x81\xed\xa7\xf8\x02Y>D4ca\xd6$\x1bB2\xf3\xbe3\x93\x05`\xde\xd4\x0f\x161\x0b\xea\x86\xc6\x86j\xa1Tb\x00\xf0}\xa7\x05\x17\xe1\xe7\xb4\x08\x17\x83\xe3\xafX2\xb5\xe9\xcdQl\xf1-\x9a\x94\"\xac\x0cjk\xcbmb\xa1\xdd\xdf\xc3V\x19\\\x8a&\x0c\xadG\xd9j\x1d\xe6\xa4\xcf!\x1bd\xf3\xca\xdar\x03\xdb\xd7\xf4QF \xd9\x8b:\xba\xb7P\xac\xb0/\x8c\xb6&\xcc\xf0Eu\\\xee2s\x90\x15{\x8c\x0d'\xf5\xaf\x98\xc5\xa1\xcfdN\x92\x99\xd2\"k\x98Q\x86\xde\xe2t\x8b\xc3\x98\xc5\x17xD\xc9,\xbe\xe8B\"\xa9\xe0\x1cY\xff\xad\x0c$\xf2c\x97\xddZ\x89>\xccw\"\x94zh\x8e\x04g0Q\xe2\xe1Bs^\x84\xf9k\xef\x89\x11l%W\xfe\x94-\xe5\x8fy\xc2}\x06\x06\xdf\xca\x84\xe3\xbf\xc1\x1ee\x80\x8d\xc3?\xa8\x01\x88) )\x0c1\xb3\x18L'\xf8u\xe6\xd5\xc1\xd0!\xb3\xa6\xbc\xfa\xceI\xe2\xa24\x99N\xf2\xe0{\x90-\x04P\xb0YQZ\x0c\x1f\x04\x01m\xa2\xb1\x11>\x98[S\x02$\x18W\x0b!\x0ca\x10\xa4C\xaa\x8b!\x89f\xe9\x85\x95\xdd\x12r)\x05=P\xbch\x86;f>IO\x1d\xa5\x8d\xc2N\x9cW\xdc\x18\xc5\xce\x06\xca \xbc\xfa\x9d\xf6\x8f>\x153\xe6FM8g|E\xf4\xd6\x9e\xb3\x08\xcd\xb9mEg+dg\x8fS\x98\xfb\xa0Pz\x12\xfa\xdc\x1a\xab\xef\x8a\xdbp=9\xe8\xf3\x0c\x17\x0c\x0e\xc6\x8c\xea\xd2\x13\x95F=\x91l\xae\xc9GRP\x12\xbb1\x1d^UI\x19\xaf\x13BWpr\xb0s\x15\x97F\xb4\xa8(\x1a\xc6'h\xbe[\x9e\xb0\xe37\xf5\xe0\x86\xbb&\x11Jm\x8dZ\xd9KA\"\xd1e\x17M\x10\x8b\xa8.\xcb\xee\xf4\x9b.\xcb\xdeW.\xcb\xee\xf4Q\xcb\xb2\xd7Z\x96]\xcfo\x8a\xe82\xb1\x7fLZ\xb8\x0dV\xeb`\xef\x9b\xae\xd6\xe1W\xae\xd6\xc1\xde\xa3V\xeb\xb0\xb5ZO\xcd\xabu\xa0\x15O\xd9?\xfbZ\xf1.\xfbg\xef\xf1kk\x8a\x1f\xd7\xb5\xbah\x9e\xdc\xb5\xc2\x8a\xa6\xa3\x8e\xaa\xc5~\xb6\x02\x08\x9c\xc1\x0b>\x9b1\xa5\xcc\x07\x84\x87\x92\xc7\x93wh\xf2\xe9F+\xf8\x07\x8d`\x98\xcd\x99\xb0\xfa\x1a#\xdb\xf4\\\x9eO\xe3Q\xe2\x0ck\x17\xfd\xa6R\xbd\x91\xda\xd4N*D3<\x8a7\xcda\xb69Y\xc1\x10j\x15\x06Q\xac\xe2\xe1\x9d\xbf\xd8\xa4\xf3.:W<\xbc\xdd_7i\xb7\x93:\x86a\x14\xb2xx\xff\x9f7\xe9\xbf\xd7v\x18\x9a\x86_m\xd2p\x075\x0e\x83(r\x18H\x95\xc3&\x9494\xb3y;l6\xbd\xc4:4v\xd1F\xc6\xfag\x1e\xf9Rx+\x1e\x83\xcd\xbd@~J\xe6\x8e8\x02\xc7\x19j6\x0dF\x9a\xec\x81\x8b\xe4\xd9dmA\xa5T\xa0N\xfeZ\x85Iw`\x170J\x1bzd\x0b\x122\x146\x9a\x9d\x88\x87\xe3\x80\xfb{\x0e,kY\x88\xd9/\\\x9bE\x9c\x16k-xr\x17f\xb2)F\x98\xffRK\xca\xdf9p\x81\x9f\x9es\xb3\xe9\x9a\xae\xa8\xddy\x10Fr\x7f\xc9`\x15\x96\xd1\xd2}\x12\xfc6}xr-2l\x80#\"\xe3\xd6\x8d\xf1\x10\x80,\xc8L\x10\x04\xe0x\x9e\x0f\xce3No\xd4\xe1r\x9e;]\xebb\x91'\xf5\x1a\xb5\x7f\xfb\xad\xd6y<\x05\xb3\xea\x9e\xdb\x0c!\xa2v\x84/\xc8\xb1^/\xaf\xed\xb6\xb4\x17\xcc\xd6,naT\"|\xdd\x11\x03\x8bv\xef\xefQ\x80\x83/b\x1d5\x9b)>\xee\x8f\x9e\xd3\"@\xfbh\xdb|sx\xce\xc7C\xe8_\x9dnBM\xfd^\x17\x02\xad1{-\xa4\x03|H\xeb\xbf\xf2\xfa\xaf\xb8\xfe\xab\xb9|\x83\xc4{\x19\xba\x0e\xec\xd0\xd3\x83!\xcd`\x87\x1e\xa7P\x96\xe8e>T\x1e7\xdf\xc0\x00\xc8B/\x18s\x15\xacb\x99\xc24\xbb\xe3\x13H\x98!\xedh\x94\xd8%\x80\xd1,a\x12\xc0\xc5,\xe9\x94\x00f\x18\xbc,\xe1:sZ\xdb\x0e\x83\x1f!\x01\xcc\xe0\x19\x1a!\xa3\x04\xb0\x82g\x90\xd9%\x802\x94\xc2(\xc2C\"\xbbI}q\xe3\\\\J\x91%\xd7.Ao[\xf7o\xd4\xd9\x9d\x1aR\x03\x03\xaavu\"\x99\xfc\x7fmG\x93\xce\x8e\xd0C\xdf\x0c\xc7l@L\x8b\xb9Y\x93\xb8L|$\xddt\x9f\xf3_\xadVj\x0f\x14\x1d@\x99\x83\xa6\xe4,J\xf9F\xad\x9b\x8f0\xc2\xe0\xb8x\x1d\xa7\x18\x97\xc03\x04d\xe1\xae\x92,r\x81p\x8c\x10\x84\x87\x0f,P\xc7\xcc\xe7\x91t.<\x16\xc9\x11\x92,\xbd\xa6\xfc\xaa\x88Fk\x0f\xa8q\xcf\x00\x85\x18D\xea\xc1\x19\x05\xcc\xac\xd8\x08\x899\x07Ay3\xd9\x9f\x89\xd5\x1db\x94_\xdb\x18K\xa8pGO\xea\n]\xacU,98\xc9\xc1{\x9e\xd7NM\"\xe2 \xe3\xef\xf0\xafA`_r\xeeeg1\xab\xca\"\x9e\xd7A\xa9\xec\xf1I\xf2:\xae\x805^\x86\x02^U'Q\xabJo\x08\xff\xc5/\xdbJ\x0b\x94c\xde\xf2^\xd6k\x18\xdb\xc5\xfb\xbc\xdc\xa0\xcf>\x8e\x8b7y\xb5A\x93_\xab\x8a\x80\xa6\xdb\xdb\x0d\xba\xed\xe5\xb1x\x9b_6h\xf3\x1fN\xd9q>h\xf0\xbd\xdc\x14Z\xf3o\xc4I\xd9,u\x01\x98A\x13s>\xd5\xbd\xa6\x98\xc2\xb1\xdf\xf9T\x97v\xfd\xdf\xf3\xf7\xef\xfa8\n\xbe\"\xe6\x1bJ\xdb9\x06\x11\x0c\xc4\xccr\xcc\xc32<\x06\xdd\x93\x0e\xe9\xa3&oFp\x19\xe6\xb9\x88\x0d\xe6\xf7\xc3R-\xf8*\x05,\xef\xe1\x14\xf6\xc6G\x07\xb6\x90q\xbfv\xe1l!A3I\x92\x1ec\x16\xac\x98\x03\xa3\xce\x97\xd9\x8c\x992@\xa2\xc1)js\xed\x0c\xe40\x87\xde\xcf\xff\xa8S\xfc\x16\x93{3drv\x1bDw\xcb&\xf5t\xb78r\x95\xd8\xa7\xbc\xc1\xb2\xa6+\xa9,\x82\xe3\xb0\xfbG\x98\xab\x1c.F\xe61}\xd3k\xb7\x9ce\x1dS\x8f\x07M\xfdm\xd7\xd4\x15St\x8d\xf1\x90\x877f\xc3\xcbk=^\xc659\xb1m\xd7\xf2Yv\x01#\x98\xee\x1f\xc0\xf7\x90\xcf2S\x90X\xd8t.\x9f\xba\xe6\"4\x12\x13\xd4H\xb0\xd8\x18\xf6H6\x0e#\x01E\x04\xef*NK\xbb}\xc7\x08\xc9 k\xdc\xb7O\xf9]\x9c^c`\x13Lj\x00W\xe4.K\xe7\x82\xf6ak6\xd0\x0b\xf7\xa5*\x82@\xa7\xc8\xc7K!\xbes\xd8\x18\x8ca\x80\xb8\xb0D\xc4\x0f\xb1i\xb2 \xba\xa8\xf1\xe3\x9fY\x03\x03\xe9\x91\xfe\xf4\xd8t\xb6\xe615\x88$t\xb0\xc7\xc1\x9c\x93/ \x8b\x17\x06\xae\xe8\x87\x1ef\x88\xd4>\xfd\x84\xdbS\xef\xe3\x86\x9b\xf5\x92\xca\xed\xd5\xadud\xaf\x17\x1f\xa6\xaa\xe1\x0ewG\x8b/\x00\xf5\x10\xdb\x18\x94\xe7\xd938\x84\xef)\xfd{\x061\x1c\xc3\x04v \xf6<\xb4\xd16\xbc\x184\xe1\x8f\x1bMxoz\xb4wt\xf0tz\xf4\x8df\xbdg\x9f5iOk\x17\xa7\xc5\x16c\xd0\xe4\xde\x0d\xbe\x1f_s\xb0lG\xb5\x03\x9e<\xfa|\xfe\xa4\xcc\xc88\x9dZ\xaer\x7f\xcf\x16`\xec\xb3\xa5\xf6!\xe6<\xae\xdc\xc6t\x97\xbd\xa3+\xb07h\x0c?>z\x0c\x87\x961\xecO\xd9;:\x86Cm\x0c\xf2\xafB\xa7\xeb\x86\xd8\xef\x08\xaf\xb8aJ\xeaS\xf8\xaf\xff*}=\x08&\xe1\xb9O\xfe\xeb\xbf\x88\xcf0\x05\x0bC9\xa2X\xbb\xbe!\xa5\x888RR\xc4^\x17\xe5^\x13\x92\x8c\xe5\xea\x92\xbe!\xe2\x1bR\x7fC\xa4o\xca\xba\x04\x93\x1d\x1b\x03\x985:\xcf\xda\xea\x1a\xd7\xc2\x1a s#\xf9IM\x81\xc1\x8e\x9eeE3\x86\x11\xec\xec\x101\xef\x13<\xda\xe3\x9e\xe9\xd2\x0f\xbe~\xc2\x87C\x00\x02o\x90\xd4s\x9c\xf8\x9a\x82\x83o\xdc\x90\x1e'\x07\xedc5\xa8\xd3\xa9\xa5Sn\xe9\x81\x8b2\xb9@\x9c?l\x1c\xed\xcd\xfe\xbaq \xb5\xa1\x0cf\xc88v\xa7\x8f\\\x8f=}\x1c\xae}A\xe4\xa2)\x16\xb18\x7f\x93\x83\xa7O\x9fN'\x94\x8b\xa8\xdf\xef\x0e\x1c\xf6#\x97\xaf5\xec\xd6\x18.D\xe2Li\x06\x93\x83\xf6\x14\x94Y\xed^t\x8a\xf0\xe9\xb0\xff\xd7A4x~\xca?\x9fL\x0f=.\n\xdf\xe1\xb4\xe3:\xbbu)\x95\x00\xdf\x03\x06\xf3\xec\x05\x07\x7f\x0f\xf0G\x94\x85\x91`[~q\x82\xe4e\x1b\nf\x1a\x14\xcc\xbb\x17)3,Rf]\xa4l\xc0\"}#\x90\x89\xbe\xd7\xf5\x89Gu\xde\xf7\x80\x11!v\xa4{0\x11\xa9\\\x07@\xd7\x0d\x80\xab\x15\x9a\xb5\xd7\xf1F\xf8UX\x81\x8bu\xedw\xa7O\x0f\xe8$S8c\x8c\xd0x\xf2\xf4`\x0c\xf7\x90\xc2q?\x05\xb2\x01\x8c~\xf4t\xd8$\xee\x15\x10\xfe\xfbM\xe7\xdb\x81\xfa\xcd \xbd\n'i\xd9to\xd0p\x87\xad\xfe\xf0\xe1b\xcf\xedA\x0f\x00\xee}\xc3}\x9dd\xa1\x01\xba?n\xb816\xd9(\x1a\xb6\xc6\x82\xeb\x1b4\x8co\xb5j\xadaL\x86\x0e\xe3\xc7\xac\xbaJ\xc8#\x97\xe3\xb0w\x1cc\xc1\x80\x0e\x1b\xc7#\xd7\xa3\x7f\x1c\x93!\xe3@\xe6\xd9\xca\xcdX\x848<\x9d\xa7\x82\xe0\x98\x15\x0b\xaam_\xea\x06\x04:2I=\x96t\xcc\xe6\x88\x12\xdbc\xfce\x1dN\x1fx!H\x13r\xba\x14\x94D\xdaB\x93\xac*#\"N\xa1\x84'\x1039\x90\x15\xbc\xd1\xca\x9dP\xac^I#\x99\xf0w\\\xc9\x14\xabXW\xd3`\xa4$\xad\xa6\x10\x9f\xd5+\xba\xb3\x13c\x808N*\x18\x964\x16K\x9a}\xb3%m\x11\x15\xdd\x16,\x86E\xd5\xd7\x92\x02\x8b\xfd}\x1f\xf5(\xd6|?\xb8;M\x06\\\xb7\xf4\x04\xb4\x96O\x197\xf9\x1f4\x11\x13\x05\xf2\xd5s\x99\xfaLr\xdc5\x9b3\xc3\xf5\xf0\x9b=\x9b\xb0=C\x11)\xa5\xa9>(\x1dl1\x1b\xfb\x91\x166\xd2>\xc9\xc1\x94\xf2\xef8I>\x1b}\x92|\xee\x86IN6\x9a\xa4\x89Z\xf9\xeaI\xee\xf9\x92H|\xd0L\x19\xcd\"f;\xdd\x93\xa6;m\xca'\x07\x96\xbd6\x1cg\xba2\x1f\xcd\xdb\xdfI\x16I+\xf3;l\xff\xe6+cY\x95\x89eU\xa6\xe63\xb3\xdb\xbd2\x93\xc1+\xb3!\x8a\x15\xd2cyY\xb6\xac\x06G\x02\xd4\xb7\xd0\x03\x86\x8e6\xcbN[\xb8%f\xa8d\xc7\xe0\xe6m\xb6\x07C\\lF,=Qz\x1f\x89\xc1+\x19\xdd\x08\x917wJb\x7f\nsL\x86\xdb\xe9\x84.\xf0\xcb\x10C\x14\xf9\x1a\xdew)\x96\xaa\xe0\xf9s\x18S<\x1a~\x13|\xb5!\x05\xf0?e\xa3;\xa8\x88\xaf\xdal\xb1\x17\x12\x81\x915\x04\xc6\xc6;>\xfa\xfb\xec\xf8\xefB\xa0L\xa6O}\xd8\x99L\x0f7\xa7Q\x14\x1d\x12]Z\xe6\x930\xf9\x1a\xfa\xe5w$_v\xa7O\x0f\xe8\\Q\x860\x0c\xb4\xff\x8e4\xcc\xefH\xc2\x04_K{0`\xca\xdd{;\x80\xc4QH\xa2\xaf\"h~Gz\xc6\xbeD\xea\xf5U\x8c$\xc4-\x1e\xb0\x8a\xff@\xc4\x8fE\xfe\xd4\xbd\x8a?i{\xd6\xe7U\xd1\xf4\xb4\xe9~i=M\x06\xf5d\x93\"uw\xf5\xe3c&e\x13\x14m\xd4U\xef\xac\xa2l}\xb7\x19\xdd\xd2\xa4\x9b\x1c\xa3Cd\xed\"\xd8\xd8\xd5\x97\x9a\xa7\x97\x94\xa5\xa41E\x90+\xd0\x0fI\xdd\"Wq\xe45 \x88\xce\x0b\xcc\xfb\xb2/\xbdS\xdc\x8a\x84\xd2\x0cP\x1eVO\x13\xa4\xcb\xf0\xa6\x0c\xf3kR\x9e\x97a^\xf6gC\xad\xcdx\x80\x19kj\xc30\xf7PdU\x1e\x91\x0dz\xc8\xbb\xc6\xcbZ{\x95\xce\xfb\xdb\xcaU\xe7\x8bz\xf5\xd5\x1d\x95\xec\xaf\x08\xc6^\xda\x916Jy92Z\xe5\"A\xcb\xf4[\xb99n=\x12\xc8\x8d\x1b*\x06]\xe6\xcaA\xec\xb1#$M\x0c,]\xc2\xe4\x04b\x9e\xd5`g\x07\xcd\xc2b\x18\x01\x03\x92\x14\xd6\xd1_\xa6\xb8/\xb5\x93\x11eA&d\x17X\x18\xaf\xcd\xb2\xfe\xb105\x9aY\xda\x06\xfd\x1b\xf3\xb9\x14\xa4\xac\xf3\xb8\x94\x8a\xa9N\xca\xcc\x9e2\xcf\x9c\x0bS\xe8\xfd\xba\x00\xc1\"\xc6\xf4\xf6\x1b\x00\x02\x83\xd3\xd5\xc6\x99\xadEz\x02\x0c\xa9\xc1\xd1\xa6vC\x8c\xe9s%\xb8\xd0\xfe\xc4\xe7Y7\xfa2#\x81\xec\xe2$\x07,\xb7Y\x1e\xd1\x87n\xe9t\xff\xa0F\xd4\x96\xf8h\xf6|\xabz\xb2\x19C><\x9b?{\x9d\xf1{h2o\xcb\xb2c\xbfj.\xe0\xdc\xe6Ul\xf3\xfch\xf5\xc7s\x97\x98\xf2\x9d\xf3\xc5b\xa9\x92\xacF\xbf\x1cF\xca\xe0\xe7\x19\xc3\x0dj\x91\xd5*\xfa\xfd`O`\x0c\xe7\xd1\xc4\xcf\xa3\xed\x9b\xa1Tf\x1bl\xe3\xcc\xab%\xba>SF{\xcc\x93\xc8\x8d}h\"{P,gL\x0bo\x87'\x06\x8b}\x04\"L\x93a\x01\"viB\x85\xb6|r\xacB\x96Q\xf8g7\x15)\xeds)\x01\xa6\xd7\x91\xbc\x99\xb2\xdc\"N\x95\xf9\x10\xd6\x13\xe0\xb6z\xe8\xa3\xacLB\xc0\xc5j\x96\xc1\xbfB\xb8\x81\xcd^\xd9\x8a\x91\xa3\x8e\x81N\xf6op\nOf\xff9\xfa\xe5\xc9x\xe7\xe8\xc5\xce\xff\x0bw\xfe\xb6sy\xf1\xe4\xda\xe6z\xf3\xba;\x84+\xa0r\xf6\x0c\x9c1:\xfd\xabiB\x8f\xb5\x02ul\x96\x0e\x7f\xb6*\x00o\xcc\x01\xda\x08\xf0\xa88\x13x\xd2\x9b\xe3\xb2q\x90\x89Ex~S^\x87\xee\x14*1\x0bl\xd3J\xec\xe0\xc1s\x8c\xe6\xbd/P\xf4\xfe\xd3\xdd\xbd\xbd.\x80\x1b\xf3\xfcp\xf6\x1aP_\xd2\xe7\xb0\x7f\xb0;9\xea\xabL\x1f\x96\x88b\x97\x8eggB\x07\xc3\x93ILw\x8f|\x98\x1cM|\x98\x1c\x1eu\x80u\xf1DYZ\xc6ie\xce\xa5$\x1e{\xf6 \xe0c\xaf@\xa4~\xb2J\xf5\xe4\xe7\x1fi\xf4\x98\x10\xaa\xb3Jo/\xdd\xd9\x95\xf0\x98\x1c\xecN\xad)\x04\xc53lU\xfc\xdfy\xc8)\xf7\xd18\x80\x11\xa5\xebvx\n\x82g\xcf`\xc2\x0c]v\xf8l\x8c-\x88\xb4\x89\x9c\xef\x190\x1f;&o\xeeo\xca\x12U\xf4\xdd3\xd6\xe1\x84eg\xe9K\x7f\xc0\x07\x93v\xcf\x83\xef\xdft\xbc7\xb0\xf7\xe9f\xbd\xc3\xf3\xe7\x98\xcb\x00\x03lcB\x83\x94\xfe\x9a\x1e\x0e\x1a\x16\xee\xd3\xb0q\xedn>.L\xba0\x9d\xee\xb1\x10\x1ep\x00\xdbt\x848\xba\x0d\xc6\xda\x03\x1aq\x1e(\x14!\x92\xb4&V\xd2\xdar\xf6\x99p\x86\x19X(i+\x93\xab\xfbu\xd6\x7fy\x8cw\xa6\xe3t'\x13>\xb5\x07\xbfS\xb8&h\xa8\xd4}\xea\x05,\xe8|\xd3q\x19\x90/\xeb,/\x8b:\x85\xf1\xe0\xd6\xf6\x0e5\x8a:f\xc5GZ1\xa5\xd3\x9cY\x86a\xf0y\xd0\xfb\x0b\xc7<\x02\xfb\x89\x15'\xa7\xc0\xefU\xc6\x8c\xae6\xfdb{\x1b\x90\x0d8=\x95\xee\xdd\xc3f\x93\xda\xdd\xf5\\\x16\xb1\xdf\x07'\xcaIX*~m_\xb1\\\xbbOw\x8d\xeb\xb5\xfbt\xcf\xb0`\xb4|_+\xafx\xf9\x81V\x1e\xf2\xf2\xa7\x9e\xc4\x0d\xd4\x07\xbbh/\xe6\x0d\x8f\x0e\xbac\xd0}\xa6\x1c?\x03\x0f\x9f)\xa7sV\xcfk\xad\n\x0d\xa2\x84\x84\xb9\x8b\x87\x9cX\xb3q\xddt\xa7\xd4FQ\x10)\xdd|6\xbe\xf0!\x9fMt\xbb\xff?\xb4\xffRd\xc0t\x0ctWT\x89\xd0\x9c$\x04c\xfc\xc4j\xf95\xa1\x102S\x0b\x97!\xdd\xd7J-,\xb0f\xe8+{_l\xb6\xf7O\xf7,gH\xf9\\_5c\xf8\xfb\x13HwvN\xda\xf0\x17\x05\xa8n9K/p\x01\xa5\xbc\xd1\x1aU\xc9K\xa5,\x9f\xe6+\"\x8ff\xf0\x90\x1b5\x92\x88y\xdad\xc9!\xf4/\xf2\xe8\x8b\xf9\xf4\xe81k\xd8,\xdf\xe5\xe5<,\xc3\xcbK\xe3j\xe4.\xf1\xe0\x0c\xd2\x99E\xbeW\x17\x1f\x83\xb3\x0c\x8b\xa5s\x01\xc7\x90\x06\xabp\xfd\xd8\xf9\xec\x8d-\xe0s\xa2_{\x06\x0e\xf0v\x8b\xa2\x8d`f\xc6D#9\xcb\xe8G!\xe5c\xc7<\xb1\x80\xb0\xc9d\xf7\xb1\x83CP#NH\xec6\xd2N\x8aY\xf3\xaf\x18\xeb\xd3\xb1a\xa8\x9a\xa8a\xd8Hmbbz\xbaY\x0c\x01q\xea\xdbb\x1bT\x12a\x14N\xe3\xb1s\xc6\xd8\"\xaa\x04\xe8\xd8\xe8\xbd\x81\x9d\x98\x1e\xb8\x9d1=l\x1b^\x17\xa7*XB\xf3\xa8\x94:lh\xc6\xd6\xf5\xd8\"\xc1\x0d\xc9\x0b\x8a'j\x0dS]TG\x86sn\xc6\x81\xe3u\xd7\x98\xd0\x1a\xb5]\x8b\xb9\xc6!\xads\xa6,{\x1bO\xa4\xe4K\xf9)\x8e>\xab\xb1\x98;bK\x82\xd8#Q_\x96B\x97\xb6\x08\x0f\x94\x8e\xba\n\xa3\xcf\xc6\x18\x0f\xa2%[\x98\xfb\x9b&\xab$\xb4\xc3J\x9b\xbf\x11\xb1\xb7\xc2.b\x1c\xa3&\x8d{\x02\xd5\xf6$\x80\x14\x16@\x81XI\xb7+X,\xb6\xd8\x93\xdf\xb1\xddb\xbd5}\xe2\x0f\xc0k\x86D+\xe7\xfa\xcd\xac\x83x\x1e\xfa\x86\xda\x93\xdb\xf1\x9b\x0e\xb5\x95{U\x7fzG\xdb\x93\x89\xf1[\x8f\xd6\xb7ir\xc4\xd35\xe0\xde\xd8Z \xcb\xc1\xe9}b\x1ci\x88\x16|\x8a\x1c6\x137\xc1\x83lV\x8dF\x17\xf2-\x99U\x1dq3\xe1[\xac\n\x8bX\xcc\xa5\xc4}\x0bb|\xdd\xc7\xe2? U\xdc\x801 N\xcb,\xda\xee\xde\xa6,\xda\x81\x89*\xc8y\x96B\x13y\x9f\xf5\x91\x8eqJ\x81 \x99q\xae3m\x14\x13\x0f\x86\xe6*\x9by\x86\xe0L\xeb\xf7R3\xe2\xaf\x98e{\xa3\x98\x9c\xa7\x1ek\xfe\xe4 \xb8\xf4\x02L\xa1\xa5\xa2\x84\x1c\x8e\xc1\xcd\xdc\x9cN\xcb\x9734V\x9e\x0f\x99\x1b\xb3H\xb0\xd5\xd0\xccr\x88\x1aL\x8a\xaa!\x01\x88\xd3\x8cc\x04\xde\x80gD\xe3\xa6E\xa1#\x1c\x9a~M\x19b/\xee2\xc5H6\x0fO\x1c\xab\xb8\x85\x01\xf8\xc0%5.1ghKYf\xe8\x98\x9fh\x9e\x13\x1a\x7fJ\x7f\x8f\x15?\xe4f\xee\x03\xb2\xae\xfd^so\xb6\xc6\xb4)\x03\xf3\xb7\xfd\xce\x83\xcb\xa5|\xa3\x1b\x93\xbafZO\xbeH\xa9\xbbwp\xe4\xb9\xce\"\xcb_\x85\x91\x08\xa5\xf5\xa8f%\x1e\xe0H\x17?p\x1e\xe0H\xe7\x0d2\xce\x1b\xe8\x10\x8d\x891\xf6\x9e\x1eJ\x8b\xe2n\xc6\xd0\xf9\x94\xfa\xe2 \xbd\x8d+\xdb\xca\xf4\xf1\x0c\xa6\x94~5\xd8)\x94p\xc6r\x15s\xf3\x8d\xd2g\xc9N\xab$\xa1'\xbcPP\xd7\xf4\xc2W\xa4#\xa8N\x0cy\xe2!\x16g\x15#\xd5\xa6\xa8P\x16v.N\xe4\xf0\x80\x91R\x19\xa1e\xa1Zv\x8b\x01\xd9##]\xcc\x93A\x1a\x12\xa2\xaa\x99 \xd3v\x05\x92V+\xc2_g\xed\xd7\xb7y\\\xb2\x97\xa1\xf2\xee\xc1\x87\x02\x19\xc7\xd8-\xe8\xb0\xe8\xcc\xa2\xe6\x90z\xc1\xf5\x90\xa8\xd3t\xc3\xf8V\xf9\xb00\xb3A\x96]\x89\x1a\xd3\x18\xf3\xe6D\xca\xe6\xecJ\x9bC\xc1\x99\x14\xba\xe8\x182\xce\xe1\xf3\xf7\x14\xae\xa5\xea\xfb\x149\x1c\xb9S\x1e\xc1\x87nh\xd4\x8cAz\xa3\x1d\x06q\x10\x8a\xe6 \x84\x86\x83P\xb4\x0e\x02\x8fa\xde\xde\xf4kR\x1a\xb7\xbc\xa0\xe5\x86\x9dV\x8fB\xd8}\x14Z\x89y\"\xbe\xdb\x11\x1d\x0ff\xc3\xf9\x16 I\x92\xe1\x1c\xdaD\xa9\xc1\x8f\xaf^\xbf\xf8\xf9\xa7O\x9c\xb0\xcc]\x0d\x0e\xb3 \xe7\xc70K\xdd\xfd]O\xcb\xdeO\xbe\xac\x938\x8aK\xfe\xfa)\xdd\x16w\x7f\xf7\x90\xff{\xe4I$\xcf \x18hgP\x05\x8d\x0c\xa9;m p./I\xf16\x9bWZ>\xd6AKG\xdb\x93\x05\\\x8a\xf5C\xea\xd6\x1abwz\xc0AI\xea\xee\x1eq\xaa;u\x0f<\xd7\x11&\x1b\x9f\xc2k\x01Z\x9c\x97\xe7\xe7\x1f\xab\x84\xfc\x14\x17\xa5\xff\xf2\xfc\xfc\xbc\xbcK\xc8\x8f$J\xc2<\xa4#\xa1e\x7f\xa2p\x85UHb\x92\x96\x1fIT\xe2\xcf\x1f\xdf\xbf\x95\xfff\x8d\x8b_\x9f\xb2\xcf$e?\xc22\xfc\x94\x87i\xb1 \xf9\x9b\x92\xac\xb0\xf0u\xcc;\xfd\xf7Oo\x7fz\x91$/\xb3$!8y,\xd1~\xbe\xce\xf2\xd5\xab\x84\xd0[\x8c\xbf\xcf }+J\xde\x92y\x1cbco\xe3\x15\xa1\xe8\x96\xa5\xe9}\x17\xae\xc8\xfc]6'o\xc3\xb5O\xff\xc5:\x1f\xc2\x98\xce\xe1\xaf\x15)\xd8\xd0?$\xd5u\x9c\xf2\x7f\xd8\x97\xe7\x7f\xfa#K&\x87\x15\xce\xff\xf4\xc7w\x88\xa5\xc5\xaf\x0fa\xb9<'\xd7\xf5\xcf,NK\xf1CZ\x85\xf3?\xfd\x91\xcd;\xcb\xd9\xa4\xcf\xd1D\x95\xa1sV@\x97\xfb|I\x08\xfb\xfc\x13eg\xf20\xfa\xfc\x92/x]\xc0~eU\x84#r\x82b\x9d\xc4\xa5\xeb\xf8\x02Z\x8cO0 ~X\xcb\x80\x8b\xd1\xc8\x04g\x11\x1e\xce\x8a\x8b\xf6\xbd\xa7\xe0%\x9fE\x867h0I\xe9\xf2E#\xf4V\xa14\xe6<\xdeJf\xd5\x05\x13\xd2%(\xf9\xa0@\"\x9bE\x94\xab\xc8\x02\\\xd7\x9e\x13\xaf3<\x14\x8e\xfe\xf6P[\x1am*\x96\x13\x02D\x0eH=\x1e\x86\xf5\xd0\x87\x9dI\x1f)e\xbb\xec\xdd\x94`m\"\xd7\x10\x80\x12\xf1\xf72L\xbf+\x81\x0e\x06V\xa4\\fs\xc8R0\xe6\xeaii+7\x1b$\x07-\x83Y\xca\xa9\x0d\xeav\xd2Y\xa8\xc7\xef\x13o\xa6\xbe\x1e\xa1\x87\x19\x16ZR\xa4s\xe3+\xb1\xe3B\xc8\x8b\x80Mlc\xd3\x9f\xa1\xe5\x8eF\x91\xbe\xff\xf4\xde1h\x1aeY\xcc\x83\xfa\xba\xd0^\xb7`\x0d\x1dl\xc9\xa9(w2=\xf4\\'^\xe4\xe1\x8a\xe8\x1d\x89'G\xe8b\x13\xab\"\x92$AA\xc1l0\x8f\x8bu\x12\xdeQ\xac\x97f)q|\x9c\xfb\xa1\x17\x84\xeb5I\xe7/\x97q2g\x99\xca\x83\"\xa7\x80\xd2\xf95\xbc \x8b(\x8f\xd7\xe5\xb1\xe33\xabV\x12DYZ\x92\xb4\xfcs\x9c\xce\xb3\xdb`\x9eEH\\zA\xb6&\xa9\x8bn\x03,j\xa7\xf3\x8c}\xfa\\T ^\x9f2\xc5\xf1\xb3_\x9e\xf0W\x98\x81)\x88\x92\x8cE\x8c/\xf08\xbd>\x81|g\xe7\xc4\x03\xae\x9a\x94t\x8d\xb3l\x96_\xd8\xad\x02\nWS\x89\x9a\xaf5O8\xcf\x94\xd7\x94\xa4\xed\xe7\xa7\x8c\xf0\x89\xabf\x04m\xdb\x0c\x93\xa2\x12\xb7\xf4\xfc:\xdce\xe8\x83\xfa\x9aK$)\xc68e\x0eX\xb4j\xe1\xaaY\x95\x08\xd2\xe0\xc7\x10\xbb\xa9/'\xe8\xed\x07\x87\x02}\xa0\xf7hDb-=~\xae8\x96\xf6\x01?\x9b\xa4\xabx\x17\xbe\xe3\x0e\xce\x1eW\x84\xbb%\xfa\xf5\xb0\x10\xa8\xa9\xb71\xcf.\x11t\xbb\x9e\xeb|&w\x85~\xf2\xd9\xa5U,\xcc7\x1av\x8e\xe1\xa3\xee\xc1\xc5?\x98\xec\xe7\xf1\xa34 #g\xce\xe5e\x94\xe5d\xe7\xd7\xe2\xb2X\x869\x99_^:\xa2O\xf3;\x8a\xe8\x1f;\xa1XL(f\x13\xfa\xed\xa1o:6\xc4\xe9DYZ\x94y\x15\x95Y\xee/\xc3\xe2\xfdm\xfa!\xcf\xd6$/\xef\xfc\xb8\xf8 \xce\xef\xfb\x85\xbf\xe6\xc5o\x8aW5\xbf\xe4\x97\xd9OY\x14&\x84a\x03_\xa0\x05\x9fc\x1e\x99j\xdbl\x95'{^\xb00\xcaTtQKf&\xf6\xfbV\xd6\xcc\x98\xa3\xcau+\xc6#\x9er\xdb\xf9\xb2\xb9\xc6\x18\xd0\x98\x99\xd4\xa0\xb8\xa5\x0d\xcdUfs\xcb\x10PA\xc8,\x94\x17\xbd\xfb\xb7!W9\x9d\x1cy\xee\x96\xec\xeeBq\xcb\xbe\xc7s\xde\xfb\xe0\xb0?\x1c\xbf\xe3\xb0\xa1\xfd\xc9%]\x8a:S>\xf7O\xbaD\x83\xaff\xc8\xbe\x1d\xc5I\xe8\x8d\xb7g\xb6\xaf\xe1\xed\x9a\xa1\xaebHvf\x17\x041@\xda\xee`\x9e\xa5*\xffI\x9f\x07\x06\xbc(\xe0\xc6\xe5m\xe66\x92\x8d\xeb\xad\x9d\x19&\xc2\xfb\x99X\xf7v\xc3[\xb071\xcb\x15[\x9cm\xebF\xd4r\xd7\x02\x89\xb7\xbc[]\xa4K\x08\xd5\xf1\xbb^\xefm2\xed:A\xfd[\xd5%d\xaf\xf3\x11\xff\x9c\xce\xc9\"N\xc9\xdc\xa1H\x84\xc9\x8f\xf8\xabwU\x928Fg1\xa4E;\x119\x0e8\xbf3\x94Jc)g\xc4\xe0\x98\x02QX\xa7\xe6\xd5\xf4\\\xe8\xd1\xca(\n\xbc\x12\xb1\xe7q\xac\x9d\xa1\xb0\x08\xb5\x00\x0e\xab\x80\xc3u+v\xca<\xcfFV\x03KBCP\xe3 m\xdd1T=\x80\xc1D\x02\x8c-\xa8?\x0f\xd3y\xb6r7\xdeM!\x92d\x86\x8a\xaeC \xc2(,]}\x17\xe9xK\x1f\x1c\xef\x92\xd2\x8e\xa3Q*\x92\x04q\xf8\xb1{\xf0x\xb4\xbbk\xbe\n\xfb^M\x8f\xb6/A\xee\xc6\x1c\\\xc7\x9c\xf4\xe3\xf2\x93\xc7\xae\x00\xdd_\xad)fA\xf4\x9bn\x8a7x^\x93\xddn\xaa\xe7\xa8\x9fS\xfd\xef\xa0z\xf6\x9fZ\xf0\xf1\xbe.\xf1\xcb\xcc \xaao\x12\xff\xbb\xf1\xf1\xc1\xc4\xb4\x00\xc1b\xc8>Rn\xc2^ $h\xdb\xe6\x92\x10\xa3\xad\xf3l\x15\x17\x843&\xa5+O\xc4\xea\xc5\xa4y\xb4\"\xd3$\xfdN\x0d\xd2\x9e\x1f\xc29|\xe0}Id\xa5=\xf3!\xea.\xd2\xdalX~\x1e\x04:\xceI\x91%7\x84\x03\xd0\xba\xf0W\x96\x858\xd7\xddZ\x1e\xbe\x82\xff\x98\xec\x99\xa5\x05\x93\xf1#O/\xb3?m\xb2JJk\xc5n\xc6\xffq\xd0L~\x04\x0e\xcc3R\xa4\xdf\x95\x98\xf7g]BN\xae\xc9\x97-\x8b\x8e\x94\x83\xd3\xaf\xba\xd0\xf4\x82b\x8e\xe4\xfe\xabiD\xeep\nO\x82'\x9a|\xc7\x88j\x9d'\xc1\x13\x07f\xe5\x85K\xb4\xbd\x128\xb6\xb5p0\x04o\x93Y~\x81J%\x1f\xb6\xac}@\x0f.7-\xef\xa6z\n\xf3\xe5'A\xa3\xfb@ e\x1b.Tn\xeaN\x0f\x0ft/\xdc\xb8~u\xa8\xbfB\xd2\xceD?\xc4\x01W\xc3 \x85\xd1\xf6\x08\xc8\xeb\xf7g=\xc0DPE\\\xe7\xa8\xed\xd8\xf1\xc0\xaf\xad\x84\x8e2\xd02\x90\xe0\x04\xcb*\xad\xbcFPS\x17I\xe2\x94\xb3f\x8e\xc7\x96\xa1\x9a\x0c\x83*+\x90\xe5\xc3\x91\xb6\x8c!\x9b\xf6\x0ckuWi9I\x0f\xd2\x11\x10\x93\xd9p\xd7N!s\xeb\x1d\xf3:\xb7\xccBPW2A\x9d)@\xb1s\x0f\xff\x1e\xfb\xb7\xc1\xd8\x87\\G\x82h5u\x0f6d\xb6L\x82\x9d\xd4\x9d\x1a\xc9\x9bC\xb3\x01\xc7dl\xf6CAi\xc6c\xc1l\xcc\x1d\x94\x98\xc0G\xfc8Eb\xf4\xb7\x0748j*\xfc\xa6[3:\x97l\xf7\xd0\xbd\x1bC`0\x0f\x84\x98\x87\x9f\x0e)\xf3[v\xb0\xb9U\xb0p\xb5\x08\x06\xbd\xd4Q{;\xb8\x00\xf6\x9a\x94\x92\x84\x89\x0d{C\xbf\x91\xdd\x03}K\x84\xcf\x90\x99\x12\xdd=\xd4\xad\xde\xb9\xcf\xd0\xa1\xceQp\x9f\xa1\xc3\xe9?}\x86\xfeA}\x86(\xaf\x94\xbaO=\x1f\x9c\xb7\xe1\xfa[9\xa1\x1d\xea\xde%\xdc\xebdj\xf6:\xd9\xdb\xd5\x0f ;P\xfa\xf1\x0by\xedG\xfb\x81\x18\xe1o\xc9\x11\x93|\xb628\x06'k\xe4\x0dR\xd5\x8a9\xba\xc4n\x89\xe7\xa1\xa4\xe7\x81\x82\x0c\xc6\xb6\x86\xfd\xc0U_3z\xae\x8f\xc6\xe3\xa7\x93\xa3\xa3\xe9\xfe\xde\xd3\xbd\xf1\xd1\xd1\xa4-nx\xf2\x9f\xee\xd9\xf1\xf8~6\xd99\xba\xf8e\xfe\xbd\xf7/O\xfa\xd6\xc0\xa2\x86\xc1\x10>|:FZxk\xcb%\xd2U\x13\xfa\x13\xc2\xb2\x9f\xc8F\xae13v\xe3hg\xeb\x94\xf9\xee\xe7AI\x8a\x12u\xba\x88\xb1\x84\x0b?\xcb\xffy\xcaC\x97\x96\xf0\xac\xd7\xefd\xc8J\xf5\xad\x82\xed$Xb\xeft\x0c\xf7T\nu:\x08m6\x17\xc2\xec\x84\xd5r\x1e\xa2\xb7\xe1\xc9/\xc1\xfd/3\xf7\xecx\xf6\x9f\xb3_..\xbe\xbfwg\xcew\x17\x9e{v\xec\x9em\xfd2\xf1f\xff\xf9\xcb/\x17\xf7\xbf\xfc\x12x\xdf\x9f\xfd2\xf1~\xb9x\xd2\xbe9O\xfe\xf3\x97\xdb\xef\x1fu@\xb8\x7f_\xa3o\xde\xd2\xc2\xdf\x8bm\xe8>A\x8a9k\xaa\x90bu\xc1U\x96%$L\x9b\x12\xc5Ik\x0bY1z\xbe*q\x9c0\xbaX&\xff\x12_\x10\xb6Cq*d\x88\x1b\xa9\xf9j|\xd4\x96\xe42\xf15\xb9!).\x9d\xf2\x13I\x03!\xe1^\x85_~\x8a\x8b\x92\xa4$o**\x855\xb3/\x8d\xac=\x84|C\xd0\xd5\xd9Xlo\xcc\x04\xda\x9a-8\xedi8\x1bD4k[\x00\xda9L}H\x83Wt-_\xad\xe2\xb2D\xdb{,k\x10\\\xb3\xf2\\\x0d\xa1\xbe\xd5\x16\xbd\xa9\xc3\xa9\xe3\xb7\xea\xfb\x89\xf6}A\xf4\x1av\xa8a3\xd1\x06\x91\xc9\x18\xdd\xc3\x99.\xd7$\x9cH%c\xeduV0K\x8cN\xabm\xf3\xb9\xf2\xd50N\x0f\xea\x8c\xc8*\xee\x8e\xc8 )\x11,\x96\xcd1\x8f&(\x1fsW\xbb\x06\xbf=Pr\x81\xd0\x999M\xd4AwK\xae\x16\xe0k\xee4\xdf*gF.\xedr\xe1\x97i\xa2\xd2x|\x0e\xd9\x14\x97b^\x91!9[\xb0\xb0\x1fb\xf1\x0dY7\xe9\xec\x17\\f\xc7\x1d\xf4~N\xa3\xb0\xba^\x96>Ti\xb1&Q\xbc\x88\xc9\xbc\x9e\x1b\x0e-\x00\xf7;\x9e}\xd7\xf1L\x927\xd6\xdf\x82\xd9t|)\x99 \xefB\xa9\xf6\xd0Z\xe3\xac\xc9\"\xcaW`V^\xd8\xc1.\x83\xcb\xa9\xe75\x0e~\x9a\xed\xb9i\xc9\xba\xfc\xf8\xd2&G\xbfE\x9ah \x7f\xd2\xe5\xca'5\xea\xab\xfb\xb4y\x17\x16\x17r\x82\xde\xb8\xaa}\x92\xb7,\"\xdcD4\xdb\xf6\x91\xed\x84\x92=\xa0J\x813)\xb9\xadG\xbf\xcd2\xe8!\xdct\x1d\xe9\x8d\x83\x0c|\xee\x92@\x0c\x89\x92\xfc\xcd/$\x87}\xfd\xfa2\xae@\xbb\xd2\"\xcaaS\xc4\xc2\x06\x11\x91\x9aOn\xe0\x14fZ\x91\x0f\xe4\xc2X\x91\xf8\xa6\xcet\xb0J\xbb\xbb\x0d\xf3\x94\xcc\x81\xa5\x0b8\xa5\xc8\xbb\x85ZP\xdbjD\x9b\xc7\x06D\x84\xddT\"\xf6\xb0\xde\x1d\xb7)x\x0e\x15vi\x19\x0dsa\x88\xb2\xb4\xc8\x12\xc2\x80\xbf\xeb\xb8i6'\x1e\xd0*\x18>s\x9d\x15E|\x95\x10P\xc8\x84\x15Ye\xf9\x1d$$\xfc\x0csR\x92\xa8$\xf3\x00\xfeu\x0eI=\xeap>\xa7e?\x17\x04\x08\xfbJ\xc7\xf6\xae\x07e\x06q\x1a\xe5\x84\x02\x9b$^\xc5e\xe0\xb4\xb6\xb4\x89\x93j\xa4\xbf\xc4\xf8\xcb<\x8c\x90\x08U\n\\\x91\x0e\xc9v\x932\x14i\x98\xaf\x96^\xb3?\xf9\xf67\xbaY\x82\xc2\xa7(Hy!\xd1\x95&dS25\xd2*\xbb!b\x0et\x98\xb1\xc7\xe3\xbb#\xc2\xa3\x9bNT\xf0#\xa0Y+\x82\x92\xfcKXi57\x10o\x00\xf6\xc9\x96#\xeeYkud}kyS\xfb\x7fQB\xe9w\x81`\xd8\x8c\x0e\xbf\xf4\xcb\xdb\x11w5^\xb0\xfbl$$j\x0c\x901a\x1a\xddQ\xa1s\xcc\xddT\x02k\x94\xea\x97V\xf5\x14\x83\xbdr\xd9T\x0b\x16)\x90T[Q\x15\x98\xaa/\x19<\xd5\xe3-\xab\xb8\xd0p\xa4jlX\x9d@\xb8\xb3C!\x8e!&\x0d\xf0\xc5Hg\xe1E3K\xfa\xab\x99\x17\x9d\xa5R\xc0'\xda\xeeS\xf5\xdf\xc4\xfe\xab\xf6\"I\x86\xf1Vf]{\xebz\xf4\\\x85\xad\x8e97!\xecYf\x1c\xddm\xf3Lg\xf4Q \xa0\xe3\xdc\xed\xed\xce{\xd1\x1e\x92\xb97\xebA'\xe8D\xaf\xccX\xdf\x1en8 \xb6\xb0\xbd\xd0nGLs\xdb'z'\xda\xf9\xc1\xe5\xd0`+\x18y\x9a\xdc\xc2\xd3X0\x83\x1e\xee\xbe Oi\xa1\x8bO\xea\xbbqbotV\xdf\x99\x1dh\xf1\x1d|%\xba\xb6\xd1v\xa8\x93Ag\xd9D\x96\xb6i$\x16'I\xbf\xc6g-\xe2\xcf@\xf9 \x1a\x1f\x8eav\xd17\xd6\x97Y\x95v\x0b\x04tv\xdf\xa6\x1e!\xed\x8dm\x9f\xb3\xc68\x83/\x83!u&z\xee\xd4\x15\x84\x05j?\xbc\xd1\xb8\x11\xfb\x0c;\xc2\x85\xa9_\xf5\x0b 5q.\xcf\xc5!{\xbeO\x0e\x9fz^p^\xe6$\\q\xd7\xdd\xe0# \xe7\xe1\x15Z(\xe0\xef?s\xbfg\xf6\xc1\xe4)\xfa\x86\xfcX\xad\x13\xf2\x85\xa9C1MLP;\xf9\xb1zGS,\xfd\x10\x16\xc5\xa7e\x9eU\xd7K\xa6\xfb\xd8?\x1c\xa4\x83\xed\x0d\xd1d\x0ett#\x92\x99\xb9\x18\x07MyW\x93\x7f\x06\x95?h\xc7\xc4$$\x89\x0b\x8c\xb4\x02\xc2o\x83!\xa1\xb4\xcc\xef\xd4\xa2E\x9c\xc6\xc5\xb2\xcf\xc7\x87>[\x9dK\xa0?\xb5\x96\x8fujG\xed\xa52*{=\x0e\x93r\xa3NQ~\x84\xd6%\x0fD8({\xa3\x80\xfa\xdd5I\xe7qz\x1d]\xed\xecP6\x8f't\x81\x1cW\xd0\xfam\x9b\xf2\x10\x0f \xa2,\xffL\xe6\xdcc\xb5x\x9d\xa3]\xac\xa9XlRIy\\\xd3g\xa7\x86\x00\xa8\xf4y@\xb5\xb7\xc1V\xa8\xe3r\xcb\xb7i\xd5fCB\xee\xe4N\x82\xab<\xbb-\x18\xf12sn\xc6\xc1d\xec\xf8@\xff8\n\x9c\x8b:\xfaW\x13\x0f\x8cA\xc9\xb1\x0f\xfb\x1e\x8f!\xcd\xbci\xb2:\xda\x8f\xda\xdb\xaa\xbe\xa6\xe7e\x88Z\xd9\xeb\xf6pP\xc8\xe2\xee\xeby\x04\xa3 N\x97$\x8f9L\xd8\xd5\xd36\x08\xb1\xa3\xf9\x90\xcc\xc9:'QX\x92c\xbc\xdeO\x0d\x0b\xd8V\x85'\x1c\xfa\xe8z%\xfa\xac\x99\xc6i\xec\xf1\x906\xed\x1aK4\x81h\xf2\xa6(\xde[\x1e\xfcfH\x0c0\xf7\xe1\x86\xf7i\x07\x0cw\xf8\xb1\xe5\xe5\xb5\x114\x03\x97\xaf\x85H\xb23X\xc8N\x1f\xaaW\xda\xf7D\xdcb\"\x0b~\x0dt:\x82\x12\xa6\xe5x\x9b\xcd\xd1\\l\xab\x94\n|\x16V\xd7m\xd7\xd3K(W\xb6\xc5\xfc\xf1\xe8\xf9x_\xbf1PZ\xb5~5X\xc6\xd7\xcb?\x87%\xc9\xdf\x86\xf9\xe7\xf6\x16\xd0'\xc2\x8a\xa2\xdd\x7f\xef\xff`a\x18\xdd\x19L\x0e\xe0\x18&\x07\xbb\x87{\x96UP\x86\x02\\k\xcbh\xd3\x18\xce \x86c\xbe\x16Q\xf3\"\xa2\xe4H\x04\xc7\xb0\xf0\xcd\x8d\xc8\x19\x15[\xef\xbd\x06\x94\x87\xc9\xcb0I\x98\xc0g\xe2\x0b4@\xe6?\xe6a\x9c\xca\x85\x0c\xe2i%\xeaw\x0c3\xa8esR\x94yv\xc7\x0b\xcd;\x92\xe0;\x9e\xe7fN\xa2l\xce\xbd\xablxJ\xa9C?N\xea\xdePB&R\xc1\x00kP-\xbb\xbf\x07\xa7*\x17\x87B\x98$spX@w\\\x9b*\x03\xb3R\x9d\xe2.\x8d\xb8\xb8\x04\x7f_\xe1U\xfe\x90g\x11)\n\xed\xe3,E_\xd1N:O<[\xdd\x94\x92\xfc\xdc41Moe\xd8h>\x9b\xe2\xc9\x99 \xfa.\x8d\xba\xeb1\xf7f\x1cxteG\x87\x94\\\xec\x9f\x95xJ}mE\x07\x0d\x85Q3\x07\xe2\xee\x91\x84\xa4\xbe\xf4\xb7\xe2\x86\xa5?\x0f\x88\x8a\x89g =\xba#G\x8aggGB\xee>\x1a\xe0\xbb\x0dNrc\x1fr\xcf\x97\xb0\x94\xfb\x8as\xe4~k\x1f\x98\xd0\x94 E\x85<\xb5\xe4\\=\xd3_\xd1\xc60f\xbfO\xc5\x1b\xcf\xf3!\x91T\xc5\x83\xf6\xf4R\x05\x8aL\x8en\xdae\"\x1f{\n>\xa4\xbbQ\x89\x9f\x1c\x9e\xa3\xe6@\xc2\x8b\xe8\xbc$V\x8aBN\"0!K*\xc1\xde\xb8\xac\xf7\xe6\x9d\xdc\xcad\xd0l\xae\xa4\xd9\x98&\x91B_\xf4\x03\xf1\x88\xb8\xc6\x1c\x07moc\xf4QA\x0ca\xda\x9b6q\xc4!\xf2\x9c\x969\x06(\xfc\xe0\x96\"\x86\xa5\xc26\xe6n\x03\xbb\x07\xcd\xf3\xd6:vb\xa4?\x0c\xd9\xb4\x04\xcd@t\xd0a\x16\x04\xd5\xdb\x87\xf2y\xa6\x8a\xa0\x98\xcf\xb6~5\xf1o\x84Lv\x82#\x069\x92ln\x89\x02\x02\\\xeao\xe2z\xcd\x98(k$\x05\xe6\nu|\xad\x90\x81\xcd\x82\xad\x1b\xda!\xc7\xa8\xae`&O\x98^\x0e\x95d\x05\x0b\xea\xc6\xa3^\xe0j\xf8\x10\xc2\xe8\xd4$L\xa3\x0f\xc69e\x88\x00\xcd\x7f\xfd\xfa\xf6\xb1\x1bSg4\xf3\xc1q(i\xc1\x10\x80z^F#\xac\xda\x81R\x18IB\xc9\x15\x8bP \xe3c\xcdd)\x8fg\x17\"0<\xc1\xce\xad\x0d\xcf\xb4\xcfz\x17\x05!d\xc4\x9d\xf2\x98\x9a\x8f\x0f\xa2e\x95Z\x18-\xf1\xa0\xb1P \xd29v\xd7M@\xc4\xeb\xe9\x16\xf0\xd0s_\xef\xd0\x04!\x93\xc2\xcd\xc11D\xf5\xa6E>e\xc0\x12\xed8\x98\x17\x8c\xde\xf9\x1a`z\x1b)\xa8\xe8S\xbb\x88\x0b@d?\x0d}2\x1e\x90@\x86\xf2\xado\x81$\xc3\xe0\xf0\x97n\xff(\xc1Abtx%\xab\xb10ld\x85\xfa\xb8\xd0d\xa2\xe1-\xd9O\xbe\x8c\x83\xc6un\x85\x9b%G\xa7\x0d\x0bc\x95Pj\xc0\x1b7A'\xc6SviU\x1aN\"\xda\xeb7\x8e\x05\xf2\xd3\xe7a\x182xe\x9d\x94\x80\xf1_\xbatM\xec\x10\x0d\xe46\xd59\xdd\xdf\x03Q$\x07\x14,Z\x88\x17N\xad T\xd2\x80\x99&{\x18+\\\xd59\xe7\xaa\x90;\x1a\xb8\xa4]\xa8W \xf6\x86\xe6fw\xc8\xd2j\xd3\xa4/\xd9\x94C\xeb\"5\x92EJ\xf2R0p\xad:\x8a\xd4A\xab;e\xe55\x16*\x85\x00I\xbb\x03,\x98\xc8\xec\xe2\x04\xca\x13\x8fN\xa3*\x96,4 \x12\x82t\xd9\xac;\xadyy\xb7\x81d\xaf\x18\xdf\xee\x96J\x1f\xee\xe6\xc4\xfc\xd7\x84\x9b\x93{-{\xac;l:\x8e\xc9\xe5J~0\xcc\xe9\"\xa8%\xae\x9b\x05|\x97U{\xf5\xd2\xbbv\xde\x10\x18\xc7\xe7hL7\x1b+\xc4E#\xf9\xe5\x96JZ\xc5f{)wC\xc2y\xe0\xf8\xe0\xfc\xf8\xea\xc3x<\xde\xb5\xa4F\x83\xf6\x05\xaf\x8b\xed.\xbb\xf8\xda\xb5\xb1\x08\xdc\x13n{\x9b\xff\x15,\xc3\xe2\x0d\xe7\xb7\xc0\xe6\xd3\xf8\x9a\x97IQ\xc7\xda__\xd0\x8bK\xef\xc6\xb0\xda\xbe\xe5,\xac|\xc3\xc8:\xdc\xef\xfa\xe5I\xb5#\xcc\\66-\x1b~\x93\xde\xf6\x15\xf0T\xcd\xdb-\xc9\x8a\xcc\x8f^\xf7a\xcb\x07\x84B\xf3^\xf1]\xedG*5^\xb6\x94\xf2>\xac$\x10\xb1\x8e\xd7\xa4\x0f:0 \x80\x8ah\x9a\x1c\x8a/\xc34\xcdJ\xa0\x0d\xf9\x18\xa7>\xe7\xeaM\x9d\x15\xd1zn\x8b$\xed\x1a:$\xebY\xe4Y\x03cn&\xbb*\xc6\x1e\x19\xdfa\x80\xe4X\xa6\xab\xea\x84\xfb>\xac\x9b\\\xce9nh./\xe8\xd2\x8e\xd2B$\x0d\xd6J*h\x91\xd9|\xf0\x91Zc>\x01\xdd\xfb\x13\x80\xe7\x10\xb4\\A6\x81T\n\x0eM\xa90\xca\x17\xb0\xf0\xd3\x02\x00Rj\x1b\xd1%sr\xd5$\xd3j\xeb[R\xf0}\xd1\xfa\x9d\xe7C\xcc\xe5\xeeg\xc3p\xb7\xa0\x06\xa4#\xc3\xb6>\\\x94$\x07\x92\xcem\xc1*L\xd4\x8d\x84\xa2\xf1\xb0\x98V \xefb\xca\xc3^\xeb\x9c\xb7\x9dK\x07I=c\nZ\"\x9e\xca\xa2H\x00\x89\xb8iH\xe53\xe6\xa9\xa8\x06\xe8\x7f\x1b\xde\xe1Ua\x0b\x81\xb5\x11\xf4\x14PfP\xa0\xb1\x80cM\xd6\xdf\x04\x05a= 9\xa4\xaa\xa3\\C\x9f\"\xd7i\x9a\xa5;\xac\xd9'\x1c\xd3 \x9f\x83\xc1\xbf\xb9A\xae\xb6\xee\x95\xba\xee9+\x89\x05\x1f\x1a[\xf7 f2S\xe6\xe6\xe7\xc6*\x01V\x19\xee~-\x0d\xb2\xed\x0f\xdaq\xf5*\xf1MM\xf7!\xf0R\xd7\xe8\x19\xd5A`\x8e\xdd\xdf\xdc)~}\xb1\xc7\x1e\xe9\xb4\x91<\x92\x9f\x87\xda\x08\xc3\xdeP\x8e\x06_U}A)\x11\x19K\x17\x9e\x99\x05T\x16\x8co\xbd\x03!J9Z|g\xde\x99Y\xaa\x16[\x8d\xac\x86\x91\xb4\xed\x02$ \xd73 \xaaf\xd0\xfc\x1d3\xdd\xd7d_c\xcb\xba\xa0\x05Q-\x18\xc4\xeb\xc1\x04\x0c}\xe7&b#k\xb3\xb5\x1d\xfa\n\x0b\x17\xdc}\xd8\xf0\xc6\x1d\x83A\xf3.?B\xacp\x0cq\x8f\xaa\x8c\"\x1cc\x1c~\xf9\x11\x92\x07c\xee\x05\xf9\xa17\x9d9;\xdb\x8f&\x0b\xd2\x1f Q\x8ey\x19\x8e\x8dL\xbe\xb1\xaeU\xc83:\x85\x89\xf9\xf02I\x8f,) \x1b\xf8\xd1 \x9e\x8b.\x88\x152\xce\x0f/\xb0/\x85\x82\x836 CO\xd5 \xe2I#\xdc\xd9i\x1c\x8d\xba\xda\xae\xd2!\xad+<\x9b\xda\x8bA\xa7!4a\x0c\xc8\xb3\x1f;;\xbe\xa4\x15\xa5\xe4\xab\xa4/\x93\xa4\x1e\xf8\xcb\xa8=k\x0bL\x98\xf6\x8c\x93\xc4\x9dD`A\xca\x1f[\x1a\xf3nZ)\xb6\xa5A\x14\xa4V\x19\x94\xd9O\xd9-\xc9_\x86\x05\xf3\xb0\xd8rg\xce\x92|\xa1\xdc\x11\xd7\xbb\xd3\x7fw\xf0\x8f\xb0\x88\xe2\x98\xfeq\x15\xa7a~\x87\x7f\x85\x059\xd8\xc3ZQ1\xe5\xff\xeeL\xf9g\x93\x83\x84\x88\x16\xc4\xdfyx+\x19\x19\xb9,\xd3\xa2\xa7\x8d\x03\xad\x8cp0\xb59\xe2\x90\xbbm\x8d[\xc1,\xae\x9bt5\x12{@ \xccM\x98 )\x10\xf7\xf6\xb6\x1c\x98\x8e\xb1\xb8\xb5\x8eZ\xc8\xbcr\x19\xde\xe4\x8d \x8bP\x1e3\x10\x8774\x17\xb2Y\xcan)@g\xc8J\x01\"\xe2\xc6>h\\\x0b7\xfdZX]\xb7y&\xd3\xb2)\xd3\x04fiDj\xa1[\x07\xe9F\x1a\x93\xa3\xb1/\x99f\xb5E\xd4 !\x95\xbc\xc5\xa8\x0c\xbc\x82\xb5\xe9\x92\xf1\xdamt\xad\xe4\xdd2\xa8\xb6k\x0bt\x1d\xa0\xf0\x01\xb4\xe7\xd6\xbe\xe6\x852\x1e+\x9fk\xe9\xde\xed\xec\x9f\x9e\xe1~1\x89z\xd3\x1a%\xf7\x8d\xf8[\xbb\xa6U*\xd7\xa9\x7fi\xb5\x9a:\xbd\xfc.\x93\x94\xa4s\xd7\xf3\x81\xb4\"8\xfd\xa1\x19\xa9\x9a\x9b\x11\xb3\xe8\x1f\x8d=\x8a\x0e\xdf\xacVd\x1e\x87%\xd9$\xb5~\x7f\x0e6\xfb\xbe\xf0\x03\xd2\x1b=\xe2\x9b\x0c#u\xf7\x0e\xf7<\xd7\x833\xee\xbf\x8c\xc9\x13\xd1\xb0\xf5p\xff+\xa6z\xd3\x84o>2\x87R\x99\x9a\xd3\xc2\xed\xea\xc1\xc3*\x83k5G\xec\xedPC\xfc\x1275\xb5h\xee\xca\x07\x850\x8a\x0c\xaf\n\xf5M\xf4Uy\x02n\xea\x90\x0d\x0b\x1f4k\xf4\xb8\x95=\xa5\xb2\xf8V\xaa\xdf\xa1B \xc5\x00\xb6\xcc\x1b\xd8k\xfc\\\x17Z\x84\x05\x86#h)\x0bo\xb1\x10Y\n\x16\xf0\xfc\x14\xb3\x14D\xee\x82\xa7\xfc^\xc6\x8d\x93\xd3\x0eDn\xe1.<\xef\x04X\xe4-\x18\x8d\x0c\xea(\xb4\xf3\x91\xa5\xac<\xccP\xc2Q\xe3\x8c\\\xf8\x90\xbb\x89\x94\x02E\xc3\x8f\xbc\xb47\xd3\xfc\xa0\x93\xa6xH\xb4\xb0\x91\x10Tj\x03\x18F\xd4\x9aDo\x96\x14\x8fHa\n\xc2\xc4\xeeA\n\x12]\xa5\xbcx`R\x82\xeeA5\x07\x8b\xd6\xad\xf3\x8b\xb0P\xcc\x9f\xc8\x97\xf2]6'\xaec\xcb\x99\x92ah\x01\xdbx\xb4\xb0\xb8]\x029\x0b\xfb\xcd\x1d\x858\x82g\xcau\x16#\x9bX\xf1w\xb7u\xa1\x90.\xb1!v0\xfdp\xaai\xe5\xc4c\x96\xa8\xa0\xcb\x9aJNY\xe4\xb8i\xe3\xc3\x08u\xfa?V\x1f1x\xe9Zf\x86\x176\x0e\xe6a\x19b\x98\xc2S\x18\x8d2\xf8W\x982s\x07l-(\x96\xf1\xa2t1\x04\x05\x17\xbf\x08\xafkN\xe1\x95\x06m\xd5\x83\x17dW\x05\xc9o\xd0R\xca\xbcx\xd12\xcc\xc3\xa8$\xf9\x8fa\x19\xb6\x82\xfe\xb3V,\x16\xeb\xbd\xf4\x02}X\x9a\x17\x0cai&X\x99\x94{F|(/P\xec\xc0\x15\x94\xa8\xbde\x04\xb0iq\x86\x88\xc5\x1e|3\x1c\xb6^\xe3v\xe4$$p\xec\xaa\xb0&\xc1\xb4\xe4\xf6f\xf6B\xe9\xe8D\xdcO\xdaM\x9d.\xa8C\x8cj\x1c\xca\xdb\xaa\xc4\x84|\xef\xd9\x8e7~\xb1\xb1\xdbze\xbf\x95\xc6\xa6\xffL\xae\xfe#.;:\xb0Th\x1f%\x1bH1\xdf\xa8\xde\xe0\xbb\x80\x8c_\xee\xea\xa2\n\x00\x16\xb8\xd5\xd8lA\xcaO\xf1\x8ad\x15J;\x0c\xdb!U\x182\x80\xa6\xba\xcb\x0e\xfb\xd8<\x98\x96T\xeeA\xba\xb2\x83\xe8\xcaoBeY3h\x9a\xb2f\xaay1\xa7l\\\xfb\xd3}\xfe\xef\xc1\xc6y1;F'\xd2S\x1e\x9a\x92\x8d\xa1\x86\x8f\xa7'P\xc3\x0e\xe7\xdda\x87\xd5X\xe9\x96|WV\xc8 \x84t\xed\x0e\x92,\xc2\xc3~\xdcJaF\x9fe\\\x94Y~g~\x99\xadI\xaa\xb2\x7f\x86J\x98\xf2\xab\xb7\xd6\xeb8\xd1+\xd9\xe6\x0b\xe2\x86K\xf1\x82\x9b3\x7f\x8b\xc9\xcal\x89\xfa\xccV\x1cta\xd8wmxr\xc3\x1dFm\xda\xb8\xb4C\xc5\x9b\xd7\xf1\xde\x0c\x82P\xab=Im\x08\x13\xf3\xb0Ih\x15$\x82B\xbb3\x87\xae\x95\xe3\x83\xf3C\x92]\xd1\x7f_g\xf9\x8a\"=\xe7\xc2;\x01\x16\x16\x13\x13\xf3U\x08\xc0]\xcf\x0b\xe6YJ\x90\xc4E\x8dE\x07\x92\x13z\x97\x98\xe5\x10\xb4\x93\x1f!\xc4)_3\xc693;QV2\x0b/\x86`5,\x91\x0d>\xec\x0b\x93;\x8c\xee\xe0P`\xe0\xd0k\xcb\x0b]=\xc9@\xaf;\xbb$\x1eW\xcf\\\x9f\xb8@h\xd6\xe7>\xdc\xf8p\xe7\xc3\xb5\xde|\x81y\x0f}\x98\x1b\xdc\x92W>\\\xfap\xe5\xc3m/\xbb\x08\x82\x83Z\x83\x08\xb6\xfa\xa2\xc6\x05/\x8c\xf1 \xe8#\xc2\x15v2\x00\x18\xef\x8fe\xec1\x87\xe0k*1C\x8a\x8ej\xd0\xacf/\xfbi\xf8\x86R8i\xad\xdd\xea\xfc\xca\xe2\xfce,\xdddD\xc3Gb\x00vmt\xf9\x05\xbd\xa5G\xe0\xc0\x1bq\xa0\xdb\x95\xce\xe1\xb4^[\n&n\xdaU^Y\xd0\xf1\x0bT\xca5\x82\xedV\x85\xf7p\n/f fNz1s\xfe\xed\xdf\xea\x8b\x85E\xe8\xfc\xf1bvcH\x1a\xfd+\x05\x86L\xdfxc\xe00?S\"\x00\xce\xe0\x1c\xce\xe0\xd6uHZ\xe61)\x10\xa2\xfd\n\xf6\xd4uoX2\xb7<\xbc\xc3\xa9\"\xa2z\x11\xf0\xafio\xef\xdb\x14\xd1\x1bD\xc5W\xf4\x96\xb8o\x18\x19\x8e\"\x0e\xcf\xf3P\xea\xae\x8b\ni\xf5+\xa6>G\xcfj\xf7\xca\x87/>%\x11(\xba\xa5<\x85\x89\xed\xb8\xe2\xabT\xd1\xea\x89\x0fK\xcf\xf3\xe1\x9c\xb6\xf0\x1e\xe1\x8c\xd8 \xec1H\xc3\x15\x93\xad\xbf\xe2x\xfc\xd7\x81P\xe6\xbd\xd5\x9f\xcb\xe3n\xf1[L\xf7\x8bW}\xeb\x15\xdb 1\xb4\x178\xb4_=\x1f\xc2\x19\xa1\x94\xc9\xaf\xf4\xaf/\xf4\xaf\xa5\x0f7f\x11\xdf\xcaj4\xc1\xe6t\x8c\x9bHw\xed\xd6\x15\xd3\xb4\xc8\x14(\x988\x86\xbb\xa6\xba)\xd3\x97x\xf8\xae\x1e\x83A\xb1\xe8\x9bl3A\x90\x89\x97\x14\xc2\xad<\xc0\x7f_\xd0\xa9gt\xea\x97>\xacf\x97\xa6\xf0\xa2,|\x91\x1b\x07\x1f`\x04q\xf0\x1a\xbe\x07wM\xbf{\xe5!\xfc]\x99c\x11\xad\xea\xc2A8\xf7FJH9\xb5\xd0\x0f]\xdfC\x1d\xa7\xa7\xd4\xd2\xe4\xda\x08{\x01\xc1\x8d\xba\xb9\xae\x08\xb3:\xcc\xeb4\xd2\x12}7,\xae\x05\xe4\xb5\x17\xbe+ mk\x0c\x1d\xd6\x81`\x1c\x06\xfd`\xa3\x91X\xe2\xd6\x9aF\xd2\xe30n\x1c\x8c\xd5\x1f\xb9+\xce\xca\x10\xf4S\xf7\xc64\x08DV\x1fX\x9a\x1etb\xe5\x93\xb9\x95\xba\x93}\x16\xa54u\xa7G\x9e]B\xccG\xf3\x14\xb6N-\xcaT\x91\xda{\x1e\xdf8\x9e\x0fN\xf8\xf5j\xd4\xa7m \xa1\xce\xdc\x0b\xc2f\xf2\x1b\x92\xfbS35|\xf4?3\xdd\xa2\xaa\xf6\x9bn\x9a\x19\xa8\x95s\x98\xab\xf1\xcc\xf9A\xa6\x93}\xcf\xdd\xd2)uc&\xf9\xbeu\xb1\xc7\xfa\x0cyB\xc76\")\xda @\x813\x163\x8d\xec\xe5\x9a\xb58\x85\xd0\x83\x94\x1e\xde\x8a\xed_\x88K\xb1\xbd\x0d\x11\x13^\xeb\xc1\x0d\xb8\xf3\"i\xc2\xe7\x16'\x1e\xff\x8e\x12p\xb3b4b\xf1}\xdd\xff\xca\xdc\x08[\xbb\xbfoZ3#\x97h\xb3M\xed\xdd\x9f}s\xaa\xe8\xcel\xfe\x95A\x93\xda\xc5\xf7\x06\xd7\xa4\x94\xb2d\xabV\"\x96c]\x8a\xbd\xe3y+\x91\xc5\x9de\x176\xf9\xae\x9ae\x8b\xf33\x8dW\x85\xf2\xf6L\xfd-\xd1x\xc7\xeag\x9c!?\x83J\x97\xe4n\xb8\xf8\x87\xe6\xc5o%\xe4no\xc5?s\x14\xd7\x03\xee\xcbu\xf8?;G\xb1\xf5\xec\x98\x12/\xfd\xcf\xcd\xa5\xdf\xb9\xcd\xbc\xb7\xf6.+\x16\x8b\xee\x04\xb6\xc1\x04\xd5\xb5<\xb6\xee\xd4RO\xd8,\xd1:{\x96:\xe6\x8c\xb7\x9b\xeda\x9f4m\xb2{\xd0N@\xbf\xfb\xf4\x9f \xe8\xa5\xe7\x7f@\x02\xfa}sR\xc4\x01\x19q-\xe7\xbf\xae`\xb3\x9f\xa4}\xf3@\xe6\xcd\xbe\xc7\x14.\x99y\xe6\x82g\x016\xbf\xa5TOhu\x14\xe1c*DJ\x9c\x82ns\x84 \xd6x6s\x8e\x03\x8e\xc1\xc5\x08\xdb\x98D\xf1e6'/J\xb7\xf0\xe4\xee\x9d\xe7\xc3\xdd\x1f\xa4\xa2e\xe7t\xa5\xdd\x91?r\xf8\x15\xc0!\xa4\xee\xde\xc4s\x13\x0f-i\xbb\x1aK\x1a\xd7\xcb\n\x83\xf4\xfa0\x91\xcc\xae\x1f(eI\xf7\xe1&H\xb3\xdb\xde\xd6\xb0\x96\xb5\xa19\x86\xce\x16\x06\x99\x94\xa2\x9c{\x01\x05zS\x1fb\xfcc\x12d\xe9\x8a]68\xa5\xd4\x07\xc6\xcap\xb3`\x9d\x15%\xbf\x85\x08h&\x18\x81i\x11\x84\xf39&\x1a\x94Se\x197Cj\x00\xc9\xbcE\x10\xafh\x8f\xe7Q\x1e\xaf\xcb\x82\x8e\xac{j\x0by\x0c\xdc\xa1\xdc\x07\xe7{)\xac\x17\x85\x94\xad\x11\xb9\x0e\x9f\x90\x83\xe4\xd4\x16\x1b9\xed\xcb\xc9\xd2\x9c\x84\xf3\xbb\xa2\x0cK\x12-\xc3\xf4\x9a [\x1d\xb9N\x81\xa3r\xbcNK\xf5\"\x08\xd7k\x92\xce_.\xe3d\xeeJ_yA\xbb\xe5\xbe3,\x123\xb1\xc6J\x16MY\xdcS\xab2\xb9\xd3\x94Q\xb2\xa0oN\x84bG\x8f\x99>%\xc4\xd7\xfa\xfe\x18\xd6\x1af\xa0\xb0\xfa\x18\x9a\xecC\x9b\xd1)\xf6\xc1\x9a\x95\x0fVy5},\xce\xf5\xf4\xb996{\xee\xa8\xeb\xd8i\xd7\xda\xdb\xb5\xc5\x04\x9bv\xdd\xd7q\xcf\xeamJ\xe9\xb4\x0c29\xa53\x1ed\xed\xa2O\xbe1u\x89]\xe6YH\x14\xe5\x1e\xea\x9bl\x9e\x857<\xb6U\x16,ZQ\xc4\x05!\x8c9\xc5sRd\xc9\x0d\xf10\x9c-F\xb1[\xc5\x05y\xec\xc2\xb4V\x80-\xcc\x9e\x9d\x04\\\xd1\xad\xef'\x00M\xd4\x9f\xd9\x99\xb2\x0en&9\x963O+N\xdemmQ\x02\xcf\xf9H\xae_}Y#h\x8c\x15\x0f\x9bAS\xb6\xdf\xd6\xda5#u\xa7\x87:A\xd7\xb8v(\xf2\xffA]\xca\x12V\xe3*\xeb\x9dq\x03\x84\xa3\xde\xc5\xb5Q\xd7\x88\xa1\x02\xae\x1b\xc6\xa46\x1eW\x8f\xb12J\x16\xb5\xaeX\x85\x84\x9d\xba5\x15\xcf\xfb\xcb\xb2A\xb9yp\x0e#\xc8\x91Y\xce\xba\xf5\xbc\xf4\x90(\x85\x98\xbf\x9dk*}9|\xd4\xa054\xcb\xae\x89\xecr#\xc2\xb5\xf3}\xec[(\x14\x8e\xba\x8a2\x9d\xd8B\xa9\xf0\x80\x84\x14\x97@\x08Q\x12\x16\x05\x84\x85\xe2%\xfb\xbbLG\x93\xd2\x0bO\xa4\xc9\xbe\xe9\xc4|{W$\xe3Z\xb6\xc8\n\xfe\x02J\xab^\xbc&oS\x96\x1a<\xc5\x18]\\\x9d\x03\xe9h\xd4E\xe8\xe7h\x89\x92Z\x08\xfd\"\xd2\x84\xac\xa0s\x01\x0f\xad\xaeB\xf6\x89\xe4\x95\xbd\x95\x07\x0b\xce\x97\xb1\x80J\xe5\x8c\\l\xb8_\x8f\x03%8WJY\x1d\xea\x1a\xdf\x98\xbf\xda\x1dO\xf5W\x19\x7fE\xe1\x8f\x9c\x86\xb0F|\x86\xdc\xa4\xb5\x89 \x0b\xd4,\x83\xa5\xb2\x1b,iA5\xfe\xd0\xfek#\xf8d\xb9\xea\";\xc1\x163\xc27\x12=\xe7\x14:\x01\xf9\xb2\xceIQ`\xd6\xa4\xaa(\x81\xc4\xe5\x92\xe4p\xc5c\xccf\xb9D\x05\xb1`\xcd\x0e\x8c6\x86J\x1a\xb8\x935s\xccc6\x96\xaa3\x8eJ\xc2\x8d\xed\xe5\x94\xd8-\xd3jC\xa7\xf5\x0d\x0c\x08@\x07\xaa\x91\x96\x85\x95\xd5\xcc\xbd\x0c1,\xd4\xdd\xc6\xfb\xc8\xa8\x11\xb1\xc7g8\xfd\\\xa1CD\xb2\xa1K\\\x83\xcbKJ!}\x93\xfb\xa3\x1aX\xef\x8e\xbfM\xfc\xa4\x03\x93}`\xea\xee\x99\xedz'-\xc5\x12zMS\xe09f\xe1\x07\x0e&\x9eb\x906e\xe5\xbb\xe3\x03\xe3\xf5\x0cMc\x06a\x97\xb6\xce\xb3u\xd1\x845\xa4\x98\xaa\xe4\x01HyIN\x16\x05K\x0d\xc5B\xcc\xad\xe7a\x89\xf9\x0f0Nr&\xad{\xbb\xef\xe2\xef\xd8w\xa4\xba\xdd\x87r\xf4\xa9\xe2# \xa3\xf2e\xb6Zg)\xc1\xbc7\xbf=\xf8J\x95\x82\x94\"EY'\x90\x91\x88\x11%n\xa69\xf4\x90\x04x\xd8\x8f\xdcu\x0e\xf7\xeb\xec\xef|~\x01I\xffZ\x91\x8a\x9c\xf31\xd4V\x15\xbe\x94\x87^\xab\xfb\x92\x87\xa2\x15\x11\x9d|p\xc4\x14T\x01\xa7<\xc9E\x96G\xe4gl\xa8[\xb6f\xe8\xf0u\xf3\xad\x906\x96\x03\x07W\xfa\xe0H]\xab\xe3\x8b\x14\xd8\x17\xcap\xaeP^Qp\x1d)\x85\xaa\x94 \n\x1fb\xb7\x90\x1b\x90Z\xf3\xd4/\xe3\xe2C\x95\x93\xd6\xa9\xe0 D,\x8cB]\xf3\x18B\xf5\xca\xd2\xc6\xa4\xb7\xc5\xb7\x00N\xa9{ ;\xaf\x0b\xf8\xa2\xe1\xbc\xe2mV\xa5%\x99\xf7\xc5\x0d\x14\x14\xb5fc\xa9NC\xdb\xbe6ae\xae/\x1d\x0dm\x18\xe6\xfa\x1f\xc9: #\x16\xa0ph\x1f\xe2n\x18\xea7\x8bm\x86\xec\xf9\xe3\xf7@,\xba\x1c\xac\xfe\x1b7\xfd\xdb\xb7\x1f\xb5\xfd\x04GU\x9e\xe3 \xdd\xdcu\xa2{\x16\xc3\xb2\x9a,\x98#H\xf3\xcburz\x05\x03\xc2\xd4\xf8\x0e\xfa\xdb\x1c\x8c'\xe3\xdd\xdfuQ\x9c\xf3W/?\xbe\xfat\xf9\xe3\xfb\xcbw\xef?]~xq~~\xf9\xe9\xdf\xdf\x9c_\xbe\xffx\xf9\x97\xf7?_\xfe\xf9\xcdO?]\xfe\xf0\xea\xf2\xf5\x9b\x8f\xaf~t\x86\xf4\xa9Q\x12\xd3\x897L*\xd1\x17!\xafu\x97\xcd~z\x14\xfc7T\xb7\xd1I\x8f\xd3\x7f\xba17\xa6\xbb\xba&\x14\n\xae\xb2\xf4\xd5\x97\x92\xa4\x94\xf8-0\xca\xf85)\xb5\x12RD\xe1\x9a\xfcH\xc8\xfa\xa78\xfd\xfc!\xc4\xa4\xcb\x84;\xbb\xb5\x8a\x8be\x98$\xd9\xed\xab\xbfVa\xf2\x1f\xe4\xae\xe0i\x05\xe3d.\x82\xbe\xb0jY^\xb2\xccz$\xb8*3^H\xf28L\xe2\xbf\x91s\x12\xe6\x11ko\x1d\xe6\x85\xfc\xfb\x9a\x94\xe7\xe1j\x9d\x90\xf3hIV\xec;L\xd1\x10\x96\xe4C\x98\x87+\xad\xa4,I\x9e*eo\xe3\xf4'\x91;Z*\x0d\xbf\x18J\xffX\xc5s\xa5\xe0\xc7\xb0$\x9f\xe2\x15Q\n\x99%\x8cR\xf4C\x96%$T;~\x1d'\xeawo\xd2\x92\\#\xad\xd3\x94\xbd\xabVWZ\xd1\xdb8\x8dW\xd5J\x1fn]Fi\xac\x97K\x12}\xe6\xdf\xad\xc8*\x8b\xff\xc6\xba\x8a\x8b7\xabU%\x84~\xa6\xd0>\xe2:_Q\xd6p\xfa\xd4d\xbd\x1e\xd7\xaf\x8fL\xaf3\xfe\xfap\xcf\xf4\xb6\x12\x1f\xef\xee\x9a^\x87\xf5kc\xd7\x05\x7f\xcd9S\xf9\x15\x9d\xdc\xff=\x7f\xff\x8e\xeb\x00\xfa\xec\x19\xec\x9eK\xc2*\x816\xc6\xce\x9b1\xb9-p~\x93\x85\xa4kb\x97\x0d\x11P\x15*+X+\xc6Z\x9d\xf4\xa4\x93\xb2\xa1\xf4:\xedD\xbc\xb8\xeb] \xde\xc8+\x17C\xd6|qy\xe4\x9a2\xfb\xbf\xe7.\xb2]\xaa\xdfj\xdd\xc3\xff\xcf\xde\x9fw\xb7\x8d#\x0f\xa3\xf0\xff\xcf\xa7(\xeb\xc9/C\xb6i\xc5r\x96N\x9c(\x9et\xe2\xa4\xdd\xd9z\xb2\xf42\x8a\xc6\x87\x96 \x8b\x1d\x89TH\xd0\xb62\xf2\xfb\xd9\xdf\x83\x02@\x82$\x00\x82\x8e\xbbg~\xf7^\x9e\xd3\x1d\x8b\x0b\x96B\xa1P{\x85i\x1a\xae;t@E\xb3\xe8\xd8\xaa\xfe\x8d\xbd\xbc\xf70@v4nv4K\x93\xe5O\xef\xdf\xa6S\x92\x125\xef7PO\xab|g\xabr\xe1\x11c*S(VN\xb1\x84,\xe5\x92\xf4\xd9\xbe\xb4}Z\xc0\x8b\x94\x19x\xa3\x8c\xcf\x04oM\x8a\xa6\xde\x93/\x1e\xf1\xfb\xcbp\xe5Q\xccd\x1fe\x14g[\xbe\"\xa6\xf5:\\\x95oB#\xc6 +;D\xf1\xf4C\xe2$\xa2\x80b\x16\xab\x1b\xb8\xa0jV\x0d\x159\xdb\xef\xcf\xa2\x05%J<\xa3\xb1 \x91hA\xefD\xa3\x8d\xf9\xf3\xd9i\x7f\x18N\xe6e\xeb\xc6\x1c\x01\xd2*0J\xc7h\x0dM\xc78{O\xe4^\xd7X#\x9a%\xfe\x18\xc8\xe2$]\xe2 \xc2qn\x08\xef\x03\xa4\x13\xcfcW\xa4m\xc9\xe8\\\xf4\x14e\x05\xdd9\x14}\xe4X\xfd\xf8\x9a{\x91\x13qj\xb6\x8a\x9bu\x97\x10A%^\x87+\x17t2\xa2LJ\xa6\xf9D)\xf2g\xcb\xfdP]W\xe2\xb1\x95\xe5\xa6\x9df&\xd8\xcb\xa0\x12\xd1\x08\xca\x90\xdfa\x97\x7f\xd9\xa8\xcfD=\xabr\xbc\x06\xcb\x9cP\xf7Z\x0f\x84\xa8\xed@\x88D\xa5\xa7\xdd\x00\xf2\xf2n\x1c@\xd4 L\xd9:\xa3d\xf9a\x9e\xc7\x9f_G\xd3\xe9\x82\x9c\x87\xa9]\xe4\x07\x9d\xe5\xce\x04\x13\xd2\x9fJ\xf7I\xc1\x85\xe9K*@\x97Fu/7\xf4H\x86\x0f\x8cyKc\x8fz\xe8\xbfE\x9c$\x8b\xe9\xc3\x1e/_\x8f\xff\xa9\xaf\xe2\xbd\xf1h\x05\x07\xb8v\xb7\xe1\x00\xf6`\x1f!|\x0f\x0e\xe0\x8e\xf8\x9b\xdd\xbf\x0d\xfb\xb0}\xeb_^\xe8\x9dd4\x0d't\xb3\x88\xc2l\x13O7\xd2y{\xc3\xf6\xec&\xf3\x96\x9b\x8c\xa4\xd4?\xd8\xe44\xf17'^\x98\x91\x0d9\x8d\xe2M\x92,<\x12\xc6\xfe\xc1&%\xe1\xe7\xcd\x9a\x12\x7f3\xc1\xc7\xec\xc0\xd9\xcc\xc3t\x83\xf2\xedt\xb3\x08\xb3l\xb3Hb\xb2I\x96\xab\xc5&\x893\xbaIb\x1a\xc59\xf17S\xe2\x9d\xe4\xa7\xa7$\xddL\xa2e\xb8\xd8L\x16aJ63\x8f\xed\xf1\x0dI\xfd\x83M\x14Gt\xb3\xf0\xc8iH\xc9\x86P\xe2\x1f\xf8\x9bi\xb2\x99&\xf9\xc9\x82l\x887\x99'\x9bEv\x10\xcd6\x8b\x8cx\xd1\xcc?`\xf3\x88\xb3<%\x9b8_n\xceHL7\x17\xde\x84\xac\xe8\x86L6+\x0fS4o\x92\x94\xfa\x1bJ\xbcx\x9amPs\xb2Ic\xdf\xf7Y\xd7\x8b\x05\x9d\xa7I~:\xdf\x84\x8b\x8cl\xb0l\xf9b\xcd\x86r\xc1\xa6\x93\x84\xeck\x8f\x84\x939\x9b}D\x18\xd8\x92\xe5&\x8f'\x1e\xdb\xbdl\x80\xa7\x8b\xe4$\\lN\x13\x9alN\xf30\x9dn\"o\xb6Y\xae<\x8e\x03\xd9F\x19D\xecEt3Y\xe4S\xe2\x1d'\xf1\x84\xf8\x07\x9bE\xc4\xa0\x95\xd3\x8d\x14}6\xd4#\xe9,\x9c\x90\x0dI\xe3p\xe1\x1f\xf8\x07\x9b\xcc\xdf,\xbcpy2\x0d7\x84n\x92\xc9\xe7M\x12\x9f\xfa\x9b\xa5\x17M\xd2\x04I\xe0\x06\xf5L\x1b\xaeK\xf07o\xc27\x9b\xd8\x0b\x97$[\xb1\x96B\x1a\x9d\x91\x0d\xb9\xa0\x1br\xbe\x89\x16\x9b\x84n\xf2\xc5\xc2\xdf$\x1e\xb2E\x9b\x15\x8f\xaf\xdc\xa4\x9b\x9cn\xceH\x9aFS\xe2oV^8\xf9\x1c\x9e\x92M\x98\x86\xcbl\x93Fgl]\xd2\x84\x92 %\x0c\x104\x99$\x8bM~\xb2\x88&\xfe&\xf5\xc2\x88a\x8c\x17N\x93x\xb1f\x0b7\xdb\x9cF\x19%\xe9fEB\xba\xf9\x92Gi9\xefl\x92\x93\x0d\xd7\xb3mh\xba\xde0\xaa\xe8\xfb\x9b\xcc;Y\xb3\xc5\x0f\x17d\xba!\x8b\xd9f\x9e\xa4t\x13\x9d\xc6d\xba\x89\xbe\"xB\x1aM6\xa8\xd3\xd9\xa0\xa9a\x93\x9fp\x97\x84M\xbe\"\xe9f\x1dO\xe6i\x12G_\xc9t\x83\xb1\xc4>\x83\xe8r\xb5`\x83\x9f\x93x3\x8f\xb2\xcd\xf7|L\xd1\xce\x06\x87\x11^\xf3z\x8a\xf6\xcc)E\xfb\x14\xab\xfc\xa2AB\xefGR\xbc\xdc\xf4\x86\x99\x06Pw\x06\xae_X\x8b\x8c1\xa6\xd6\xb7N\xf1\xadA\xcb[K\xc6\xd3z\xa7\x01\xc4\"\x83\xc9\x00K\xede\x84za\x00k[\x81\xe2&*H\xa1c\xc9\x84\x8e\\: .1\x19\n\x0fq[\xea\xb9A\x0d\xb1hMU\xdb(\x9a([0\x11\xa7\xc2\x9b\x8d{\x87\x95\x84\xbe$U\xa3\x81\x86\xb8H%\\\xa3\x08J\x80\xf6\xb5l\x12.\x9e\x86\x19\x1b\xd6\x93\xea\x9d\xe7b\x90\xad\xa0\x91\xeaG\x8f\xf6Sn\xe8\xf7n}\xea\x8f\xfe\xd5\xbf5\xfe\xee\xc6-&J4K\x7f\x92~\x16\xc6\x11\x8d\xbe\x92\x8f\xe9\xa2\xb5\x87H\xad_\xabz\xdb0a\xadW\x8b7\xd2\xc9\xd6\x8abp\xa6\xf6\xeck\x8f\xe0SB\x9fL\x18\x97\xcf\xb0%M\x16\x8b(>}G\xb2U\x12g\xed\xd0\xa8\x9dd\xa5\xc2\xbf\x1fe\x8a\xf6_Q\x87\xb0\xa51i\x0c\xaa\xc7\x9e\xfe\xcdR\xbf4\x8b\xe2\xa9\xd7\xaa\xac\x91Wq\xc2e4Li\xf6kD\xe7^o\xafW\xe8#U\x15*\x83\x89\xd7\x9b\xf0\xdd\xc3\xad\xf6\xff\xbe\xf4K,lz\xfe\x01\x98+X\x15\xaa\x1d\xaf'\xba\xe8\x89\xc4\x9b\x1a;\x89\xa1\x8d\x14\x9d\xe64\xe3\xd27\xe2\x17\xca7a\xea*\xb3\xa4\xc5\"O\xa2Y+\xc7\x9aM\x9bx2%d\xb5X\xbf\xa7i\xb4zI\xd65~\xcd\x927\xecZX\xaab\x99[\x94\x81:\xa7L=\xb6ut\xbb\xafZ51\x99N]K\xb7\xd9\xa8\xe4\x8f\xf1q\xb1\xcd\xd4&5\xef5e\xf8\xbf\x19\xb05d\xb1\x86\xa3\x91\xc6\xe4dVh\xe3\x98b\xee\xa1\x17a=D\xd4*\x8a\xc8mv\x87 5<\xa1\x0c\x15o\xe8\xd3V_\x9aU\x90\x91\x86\xec!\x15s\xb1\xa3F\x86\xa2\xdd\xa6\x94\xe2\x80^)\x0c\xb9A-\xeb\xcdp\xddp\xa6\x18\xad\x16\xb4m\xc1)\xb7Z\x94\xd5\x8dMn\xf5P%\xbeU7_n\xdf\xd3T\x94+\x98\x9d6\x83d\x91o\xb1\xd9\x84iM\x18L\xc4g\x1a\xd2\x1f\xa3\x03\xc6\x87\xa4p\xeapX#\xfe\x8da\x8d\x94\xde\x8chR3\xfdU\xdfc\x9bb\"\xfd \xee5\xfc\xfa\xa1\xc8\xbaq\xfbN=<\x05D\xee\x0d\xf4\xb0\xb83\xd0}\xba\x92-\x7f\xbf\xab{\xaa\x0f\x89\xaf\x16_e\x0f\xcf*\x07\x89\n-\xa3\x05\x19\xb3\x16\xf4\xa3\x18\xf5\xe3\x99\x17\x97\x0c\xb8N\xb7\x02\xaa'\x809:\xd7m\xa3\xc1\x01(\"A\x84A\x13\x11\x16Z5\xf2\\.hm\x8d\x95t\xf1<\xc0C\x9c\xe2\xa7Q\x93\x18p\xfe\xad\x9f%K\xd5s\xa2\x8d\xddd\xbd\xac\x95a\x8eb\xc6[\x8db\x8d\xdd\xeb\xb2\xbe%\x9a'\xdf[\x83\xdfc\xeb\xfe\x80\"\x10\xf01\x94\x02T\xef\x97p\x91\x13\x1e\xe8uB`A\xb2\x0c\xe8<\x8cA\xb4\xdck\x8e\xb1\xb9;\xfe0\xf8gv\x18\xd3#\xf3\x98NQ\xe5\x9e\x8aa\xf1\xc6\x9d\x86\xf5Y\xefI\xda~Z\xa0\xa4y\xeb_;\x07\x9f\xa6\xdb\xde\xa7>\xfb\xc7?\x90\xb6\x01EN\xad\x0d4\x04\xc1\xf8\xb8\x0c\xee\xc8\xe0\xfa\xdamt\x0e\x83\x8a!\xe2\x8d;\x0d\xeb\xb5\xceE\xd7mLx*\xd5\xf2+\xd4\xbc\n\xcd\x90\x9bE\x0b\xe24\xc0\x0f\x06\xbfb\xb71\xf6h\x9a\x13N\x1aD\xccR\xb8\xc8\xd4\x1b[\xbb\xca\xdf\x03\xc9\xca\x9bF}\xc2\xbbw\x1a\xf8S\xbd\x8f\xb4\xdb\xb8\xf9`5\n\x1f\xf3\xd8\xc4\xcb.C\xfb\xd9\xe4\xd3\xed68^\xb1\x9f}V\xb8\x0b[VZ6\xef4\xb2w:\xf7s\xb7QIqO\n\x1b}\x9a\xbcJ\xceI\xfa4\xcc\x88\xe7\x07\xb0u\xeb_\xa3\x7f{\xe3\x83\xd1\xee\xce\x83pg6\xfe\xf7\xfd\xcb\x9d\xe2\xef;\x0e\x7f\x0f\xf6.G\xfe\xe5\xd8\x890\xb0\x91;M\xf8\x8d\xd1\x0b\xdf\x9d\x98\x96\xbc\x89\x1b\x9d\xe7]8\x0d\xef\x951t\xa0\xfb\xf0:\x90\xfc\x0e#|f\x08xp\x1e\xdf\x16O\xebpzx\x81\x1e\xc9\xb6\xa5\x9d%\x8bEr\x0e+\xd1I\x0f\xb6u.\xec\xd53\xbc\x19\x9e\xd1:\xb2\xabr\xb67oV~\x9b\xb9Z\x13\xc7\x8b\xac\x1eR\x9e\x93d\xba\x16je\xae`\x8c\xe2\x1ew\x93\xc7_h\xc8:\xbeX.z\xc7\xd0\xf9LyS\xb0\x1e\x867\x17\xe5\x9b<\xc9\x85\xfe\xb5U\xf9\xda,I\x97!5\xbd8\xaf\x8cQ\xec\x00\xc3\xbb\xd3\xca(\xed\xef\x9e\x95\xef\n\xc4\xad\xa7\x1e\x01\x01G\xeet\x950\xa67\xb2f\xe6\\3\x91\xbdT\xcc\x0d\x01\xbf\x8c\xf4\xfd\x83Pe\xf4B\x99\xe0[\xbc_\x15\x9ay\x82\x97H\x16\xd306u\xackJot\x94MN\x92<\xa6&-:\xbbN0\x9c\x8fq$\xcal\xccl\x8d\xb9!\xd4eH&\xa1l\xcb\x8bx\xa6\".\x96X\x06r\xc1\xbe/\xb5i\x95\xcfw[\xbf\xc6\x94\xf1\x92\xf9\xeb\xfe\xf9\xa1\xc1\xc8\x0e\xd2\x00\xd7\xd0B,\xcc\x9e|V\xed\xaa\x9bdvhp\x08\x90\x17O\xef\xad\xd7\x11G6u\xac\xbc\x94\x80\xa7\xc8\x0fD\x7f\xc6/\xda\xed\xcf\xf2\x92\xb4\x88\x1b\xb8{H\xf7 ;\xde\xf88y\\bq\xf6\xe1\xf1\x80c\xe9\xf9\x81\xa1\xfc8h\xf5\xb9 \xb6\xe3\x13F\xd2\xd7\x01\x9c\x16\xb5#0\xb5\xfd\xfb\x00\x0e\xc75\xe1\xd5:\xf6R\xdf\xa4}E\xa7\xe6\x07\xb1\xd4 \xf2\xcfe\xf9 9\xf7w\x82\xd6\xc3,\"\x8b)D\x19\xe6\x0fY\xa5\xc9Y4\xc5\x13@G\xb1e\xa3g\xb6\xc1\xb2\x89\x7f\x85!<\xf3\xa2\x00\xce,N _\xd1\xc4\xc1\xc7\xf3\xd5\xd5\xd9\x00\xc4\x10\xe6\xe5\xd6\x99\xb7\x8d\xe69\x0c\xe1\x0d\x1b\xcd\xdc2\x9a\xe7\xcah\x9ew\x1d\xcd\xb4m\x08\x1fa\x08\xaf\xd8\x10\xea\xa5E\xd4\xeb\xa32\x84\x8f]\x87\x10\x96\x00 \xdbF\xf3\x03\x0c\xe1-\x1bMh\x19\xcd\x0f\xcah~\xe8:\x9aY9\x9aY\xdbh\xbe\xc0\x10\xfe`\xa3\x99YF\xf3E\x19\xcd\x97\xae\xa3\xa9\x1e\x89m\xe3\xf9\xdd\xe2\xb7$/\xe4n\xbc\xdfQC\x1eR\xb2C\x99\x1c\x85\xcd\xaf\xe0\x00~\xf6P\x85\xd6\xcb\x99\xb0Q\xdc}\xc7\xef>\xe5D\xd4\xcc\x17\xc9K\xcc\xf6w\x93\x1bKIf\xab\x07[\xdb\xfc~\x85!|\xf0\"\x0b\xb0qv\xbfv\x18\xe3\xaf\xedc\xac\x1c\x9emC\xfc\x05\x86\xf0\xb9}\x88\xbft\x18\xe2/\xedC\xac\x9e\xd0mc| C8j\x1f\xe3\xcb\x0ec|\xd9>F\x95\xc1j\x1b\xe1\x8b\x96\xa1\x1d#\xf3S\xb0a.\x03}!y\xd6\xa3\xd8\x1b\xf5\"J\x96Y/\x00\xceg\x8f\xfd\x00\xa2\xa6\xa1\xbb\xcd\xd7\x03\x14\xc1\xaam\xdb\xb1\xab\x82I/\xd0I\x82!\x0b\x06\xabV\x97P><\x12\x0fU*\xf0\x02\x190\xf6\xf4)\x13*\x03ap\xe7\xeb`\x1f,\xbb\xa2xJ.\xf6\xa1\xc5g\x90]$M\x93t_\x13/\xa7^\x97\x96x\xb0v\x9cP\x18\xe46\x94\xb8\x01Cx\xdd\x8e\xb47\\pA\x00\xeb\x86+56\xda\xbd5\xfe+\xcdl\nvNI:\x1a}\xbb\xbb\xb1\xc6\xd2 \xc2/\xa8\xab\xd8\xdf0h\xe9\"\xa0\x19\xbco],\x17BwE\x8c\xf2]\xc4\xbd\xae.\x96\x0b\xdc\xb6\xf8\x17\x166\xb2\xad9\xd7\xf3\xb0o\x98\x94/\xbe\xfd\xf7e\xc0\xbe\xbfq#%3\xd5\x1d`\xbdBO\x18\xda\xc7}\xcd\xff\x14%WD\xb9'\xda\x0f\xa7S\xf4M\x0c\x17?\x97O\x0e\xe0o\x8f\x0eX\xe3g$\xcd\xa2$\x1e\xf6\x06\xfd\xdd\x1e\x90x\x92L\xa3\xf8t\xd8\xfb\xf8\xe1\xf9\xce\xfd\xde\xc1\xe3O\xb1pl\x87\xdf^\xbf\x02r\x81K\x0c\x13\x9e\xe2\xf7\x84\xc0)\x89I\x1aR2\x05\x1e\xa4\xf47\xa3\xff\x93\xbc\xa4!LL\xa7\x8f\xa9\xb1\xbd[\x9f\xde\x7f\xf7\xe9\x96\xf7\xe9\xfd\xb6\x7f\xe3\x96\x05\xd9K \xc2\x10\xa2\xd1\xa0\x19\x8c\x08F\xc6B1\x16\x9eJK\xed\xf4)\xea\xcb~{\xfd\xea\x90\xcf\x8d;\x93\xb8\xf8\x80\xb0\x89$\xc2\xc3\xa8l\x8fo\x82\xe7i\xb2\xe4\x1bA\xb4\xd7\x9c\x91T\x8a\x99$\xbb\xa4M\xb2K\xb0\xbcm\xcd\x13&)=a`_\xc9y\x06Pxi\xaaYP\xac\x8e_g\xa2\x0eI=\xa9\x92\xbc\xd8\x12\x94\xe2\xfc\"\x99\x84\xac\xa9~\x86\x8d\x1b\xf4K\xa5\xde\xd2\xb4\xb5z\xa8\xa47\xee\x11y\xf0\x90~\x96\x9fd4\xf5\x06\xbe\xac\x17tS\xa7\x8d\x01\xd5C=\x85(\x86\xd8\x87\xb8^>%\xe5\x8e\x8a\x18g8J\xc7\xb2\xc5!&[\x1bM\xc9$\x99\x92\x8f\xef\x8e\x8a,]^:\xda\x1d\xfbc,\xdd;@u\xa1\xf6\x9d\xc1\x98\xdbU{.\xf8$\xb7us\xcd\x9a\xd9l\xec\xb4\xd5h\x15_\x86+\x07\x7f6\xf19\x12\x83\xea\x8c\x88\x0f\xdb\xd0\x1b\xa2\xb6\xb6\xf9\xb4\x9a\x99T^\x97~\xff\x8f$\x8aqy\x9aS\x13\x19{\xec\x83\x92\xf3\xa9d\xdd\xa0\"n\x17K\xd5yD1W\x04\xd0\xcb\xe9l\xe7~\xcf\xf7\xcb\xbb\xbd\x930#\xf7\xee\xe8\xc6Pf\x10jv\x9d`\xb8Y\x94\xc4\xd9{|\xcb\xe4\xb5\x13.V\xf3\xb0%\x97\xacz\x154\\j\x13\xe7=\x1f\xb7\xd0\x02S\xc1\x85)\xf1\x88\xfa\xccpd\xeb7\xe6\x92\xd0y2\xbd\xf2h\xf8\xe7\xa6\xf1\xc8\xa7\xceLDs\x8c4<\xfd\xb3\xc0Y\x1b\xb2\xf3 5\x98Y\xcb4\xe5\xc6\xce\xe8\x9cT\x94\x8c\xeeQ\x0cF\xbd\x91\xf4\xe6\xa5F\x0f\x11\x85m\xe1\xa5oz\xe5\xdf\xa2\xcc\xd1(\x0e\xd8\x06\x0dt\xfb3\xf5K\x9f\xfa\xff\xd9\xdb\xbdu\x1a@o\xbb\xe7\x8f\xc5\xfe\xd4-\xa9\x91J\x11\xdb\xa6\xd6d\xee\xaa\xac\xa4\xc1\xb1\xa6P\x9a1\xc25- W\xac8\xe5\xb4\xb9\x8ct\xf2\x18\xa9\x8e\xbc\ns\xa9\x143\xa4's\"\xc0:\x8f[d\xcaT:&\xcc\xd9\x98\xd4(\x8d\x96\x9e\xb2H\x9f2\\\xa3c\xb4\xd8\xf4z\xb6\xe1\x1a\x92\xab9\x0d\x93\xc1\xec\xb8\x84\xd9\xd7\xa6{Y\xa0I\xe7\xe6\xd44m\xe6\x9b\xb0\xecd\xf1\xd1\xad\x7f]\xec\x14\xccu\xeb\xb2\x05\xc6\x14t\x7f\xe6\x08\x85\xfdgS\xd8\x976\x85\xf5h#\xecb\x1ba\xf5r\x9f\xca\xff)\x1f\xf0\x94\xdfl\xa7x\xf7\xee\xfb\xfd\x1f\xf2\xd9\x8c\x08\x7fq[\xf5\xa3\xb3\"sSq\xf2\x95x\xa2\xa6\x19\xacX\x8c\xc0%S|o\xc49U\xfe\xe9\x18\x91:nT\x8cr\xca\x06\x89\x94\xae\x1cWjcD\xf59\x0eAaO\xf9T\x94d\xbc\x8bhBL^\x97\xc4\xb8\xbc<\xa4\xaa\x9aL[\xe4K\xe4\x14@-1\xe1c)+S.\xd9zZr\xfdP\xecx\x99\x97\xbe\xaf/\x9b%\xb9\xf4-\xa6\xd6\x16\xc3\xb2\xc5\x17\xae-F\xd6\x16\xb3\xb2\xc5\x1b\xae-&\xed\xb3\xbey\x13\xb6&e\xd3?\xba6\xadI-\xaf4\xbd\xe5mQ.\x87\x8f\x16c\xb7\x06C\xd7\x06\xeb\x898L\x0df\xae\x0d\xce\x1d\x1b\x9c\xb4\xaf\xf8f\x83\xdd:57s\x1d\xdf\xb41>\xf5\x17\xf1R^\x83\x85x\x91\xfc#\xe1\x7f\xc4\x8a3+\xcf\xd5\xcd\xee\xbc$kL\xcf\x17\x8a\x17\xe2)\xb9\xc0\x1b\x19\xbf\xf1$\xcb\x92I\x84\x99!\x00s\xb8\xc4e\x00\x1c`x~\xdc\x97m\xb0\xae\xfbe\x0bl\x00\xfd\xf7\x04k84\xe9\x07\xa6\x19\xf8\xfb\xdf\x8f\x8f\x8f^\xbf\xfe\xf8\xe1\xc9\x0f\xaf\x0e\x8f\x8f>\x1c\xbe\xc3?\x8e\xff\xfew\x8dji\xd5\xfc\xe2\xe5\xe1\xef\x87\xcf\x0c\xaf\xcf5\x1d\xbcyv\xf8\x9b\xf1\x83i\xf3\x83\xb7\xef\x9e\x1d\xbe3~p\x06C\xb8\xdb\xbc\xbd\x86!\x0c\xe0\xd1#]\xb5\xf3S\x18\xc2\x1av@\x93\xaa\x7fi\x90\xf7\x8f\xed5\xae\xf7\xeb\x89$A\xcf\xf9\x9f\\\xa5\x19\x13-?o9\xd8\xb9q\x18\x0b\xbb;\x92\xe4\x0b}\x8bT\x1c\x0dE\x83\xbbn\xdb\xe9=O*\xaf\x7fxh9\x89D\x84\x9bF\xaf^\xa9\x0e%\x0bH{\x98x\\\xa88w\xb0JH*r\x9e\xcb\x94\x05<\xd3\xc6\xeeCLw\x11?\x84h{\xdb\x87t\x14\xf1$\x89\x11\x13\xe8\xcd\xee\xf5\xa9\xd3l\xed\x01\x0d\xaa;:\x06\xa2\n\x98f<\\\x82\xf6\x8f\x8fy\xe9|\xe2\xfd\xc1OW\xf6\xc4\xa9\xe3\xb7\xd6Tb\x85\xf5A)\xe9a\x13\xc1P\xb9\x04\x8f\x1f?6\x995\x84\x92j\x1bb\x11C\xbd\xd9\xc0\x9d\xbd\x07w\x1e\xdc\xfb~\xef\xc1]\x9ca\x19\x99\xf8&|\xa3o\x85MZ\x93\x92\xcf\x04>\"\xcax#\x90\xb7Q\xf1\xe1\x06\x9c?l\xc5\xf2\xeb\xf9\x9c\x0dm|v\x90\xda<\x19jP\x16\x9d\xde\x92Q\x91\x14\x1e\x0da'\xae\x14,\x1cJ\xd0\xd5_&\xf0xXW\xc0\x9a\x06v\xd4\x96\xbd\xf1\x83\x18\xb9\xe3\x86}\xed\xda^\xbd\xaa\x8f\xa1\xbd\x0f\x0e\x80\xab\xc5i\xc4\x986\x97/\xb6\xba\xbf l\x03\x1a\xc5j\xb1\xb4\x8cC\x92\xe5\xe2\x99\xbc`\xac\xde\n\x02\xbf\x9f6\xabT\x83pd\xd6\x9c\x07\xef`\x08{\xcd\xdbo\x9c\xb3\xb6\xf3M\x9d\xa4\xcd6^\xf1\x93N\xbe\xa09\xda\x9e\xc1\x10\xde0\x1cye:\x02\xbe\x1a\x08\xf6<\xca0\xbb\x8833\xfe\\\xae\x94!\x99\xa7\xb4Z\x94\x0b\xc5\xb6\xe0\xa0\xb2l#\xf6\xbd\x85\x8a\xc2\x01\xa4\xc5\x19\x12\x89\xb2\xc0\xd6\xd3\xd0\xe0\x078Mb\xd3\x89\xebH\xab?\xda\xa8\x82uH\x1c\xfd\xac\xe3j\xad\xdcc\x18\xd4\x0fv\xees\xebWW6\xf6\x8b\x9d1\x00S\xd5h\x8a8\xe3\xd4\xc5\xefv5\xe0\xaf\xda\xf4\x1d\x05-\xe7Un\xb5\xc5\x96\xf5\xdd\xfdj\xef\x8e3(o\x90\xd6\x8e\xde`\xedR:ze\xcaM\xa4\x9d\xbb\x92\xb7\xdaiD\xbf8\xc0X\x13\xcc,\xb8\x14\xa7.^Z\xbb(\x92\x01\xa8G\x8e\xdc\x8e \xcf\x95-\x85\xe8>M0]\x83\xb5\x80\xb5\xbc$P\xd1y\xbd\x12\x167\xac\xd5\xe6!\xe7@\xa85\xc3\xfb\x96\xa9^\xd8\xe1\xc5\n3\xd3q\x06\x0d\x92\x14\")\x15 5K2\xe3[.\x0b\xd8\xd3\xcf(\xdd\xf0G\xfb\xe8.o\xeaV\xbb\x8a\xecj\xa6\x083\xc0\xfd\xc5\xb7\xc1\xbdO\x13\x94\xc5$\xc4\xc5\"\x84\xcd\xb5\xa0\x98\x9f\xfd0\xa6\xe9\xbax\x99\xba\x8e\xf2\xc6\xb7\x8dR30\xa2\x0e\x84\x8dSH\x91\xf2V\xe8<\xb6\x1f\xadc\xf3\xbe}pr4h\xe0\"\x14\xef\xd7F\xa6\xfe\xfa\xaa\xa8\xaa\xa8&\x1f\x81e\xb0\xbd\xd1\x918\xa0\xc75\x05t\x00_\xfb/\x0f\x7f\x7f\x0fCx\xca\xfe\xfe\xe5\xc9\xab\x8f\x87\xec\xd7\xcf\xec\xd7\xe1\x9b\x0f\xef\x8e\xf0\xe7\xbb\xa0\xd2\x7f\x14g+\x9e\xed\xbc6\xaa$O\xab\x99\xb9m\xf4\x85\x1d\xf0\xe6\xdc\x0bJ\xcb\xa3g\xe3\x0em\xd6\x1b\"\xdeK\xae\xb7x\xd9Of\x8e\xed\xbc\xf4\n'\x92\xc6\xc0^V\xa7L\xbe8\xb6\xa9\x1b\xdb\xcb\xab/*\x82\xef\xf8\xb84\x8e\xb2\x91\xfc\xbb\x17@\xef\xb2i\xcfQ\xfb\x99\x84\x939yG\xb2\x962\xc7JW[\xbc/\xfc\x10d\xc5\xafB\xd6\xfb\x18\xe3\x83)\x17\x06\x957\x87\xfc\xc5\x12\xeb\xcb\x8a\x0f\xa2\xfc\x99\x14\x1c\xcb\x8f\xc4\xd9\"^\xb0M\xa3\xe8\xdf%\x86HLdB\xcb\x82d\xbc\x02\xa8K\x0f\x89S\x00\xbe\xe8b\xd6\xda\x05\xf1^\x04\xf0\xd2\x0f\xe0Ee\xf1%\xbdu\\\x13=\xa6\xdf\xe0-\xdfp\xc7\xf4\x1b\x16L\xbfQ\x19`II\x1d\x9b\xd6\x0d\xf1\xc65#\xfc\x88!\xfc\xb8\x89\xf07\xae\x19S\xea\xb5\xdd\xf5=|\x13\xa64\xbb \xde\x8f|=\x7ft_\xcf\x1f-\xeb\xf9c\x8dr\xd1o[\xcb\x97\xfd(\xe3-D\x94\xfd\x92\xda[\x86\xdeB]\xcb\xc6\xaf(ro4\xb5\xb7?\x05\xf0\xcf\x00~\x0b\xe0\x1fM\xa5\xe9\xfb\xc3\x7f\xa0\xc2\xd4$9Rj\x11\x1d\x8fCQ+\x83\xd6\x88M\x17\xf6\x95\x18z\x90\xfc\xa50.}&\xebL\xcbC\xf2\x91$\xb26\x88\x1c\xca\xf1gQ\x0b\xab:4\xd2eh\xb1u\xf2Q\xa9\x9f7\xcc\x9f{\x16:+\xe8\xd2\xf6\xee\x84\xe1,\xa8\xdd{*\x0e\x83zm\x1fCG\x91\xa1#y\x16\x95\x06\x8c\x7f8\x1aX\x90\x1b36\xf8\x13k\xcd\xfbI\xe8Z)\xf5F\xe3Ff\x16}\xbby\x0brh\xd2\xe0\x88.\xa8\xdf\xe4\x9a\xbf\x94o\xa4\xfa7~(\xdf\x88\xf5oh\xa5\x9c\x83R\xc8)TOf\xcf\xbe\xabK:\xa3\xcf\x01\x9c\x8dAd\x8a\xed \xf1t\x92Y\xc3\x16\xa0gza\xee\xdb\xa7\xc7\x05\xb9k\x9aEfG\xf2_j\xd8\xa2A\x0f\x0d>\x14\xab\xeb4\x04v\xc29\xa9\xcb\xa8`\xcd\xf4@\x8dL\"xa\xe5H\xd8\x01QZ6\x06\x01\x864\xef>\x84\x1c\x1e\x0d!y\x08\xf9\xf6\xb6\xa9\x11\x10\xe3\x08\xd1S8f\xa2\x15\xec@\xced+\x83\x7f\x15\xc8\xc5\xe6z=\xe2\x85\xa3\xc18@\xc5]8\xda\x1d\xb3/\x03P\x02\xdas\xd8\x86\xa6\x12\x0e\x1a\xe2\x97\xbc\xe4g\x8d\x87\x96\x04s\x0dV\x99g\x83tZ\xa6\xd9\x9f\xbcL\xda\x152B\x96\xaf\x9c\x0d0\x0c\x1b\xbfzV\x96B^\xd2\xf9\xc3}a%\xf0\xb7\xb7\xe11:W\x9b\x1b\x077u\xa7\xbc\x8cjOy]\xc2>\xc7\xcc\xb9P\x1f\xa9i8s\xfbp\xa4E\xbe\xe2w5\x94r}\x8e\xf4z\xa8\xe9\x93j\xbe,\x03\xb8\x05\xbb\x85?\x8b\xf0{\xf1\x03\x89\xce\xf2C\xdb\xc1\xf6\xcfbh\xff\xd4#\xce?\x85\xcd\xa0e\xab\x99\xa0u\xda\x02-\xaa\xaa \xb8\x8a\xc0\xd1WhIm\xceB\xfa\xa5X\xd6\x96BiC\xbf\x1a\xa7\xd4\x13\xaeV\x01\xf4\x9e\xf2(\xde\x8c\x92\x15\x84\xf0.\x8cO \x9c\xaca\x17\x83\x1eAX'w\x83\xea*\xc9\xba#\xb8V~\xa0$\x01\xe0\x9eo\xa2\x1a#.ax\x92\xa1\xeb!\x81G\x82cco\xef\xc4\xd2\x84s\x8c\xc5\"T\xbd\x1f\x89\xa7\x8aj\xf3\x18\x87\x86\x83U\xb1FE\x0f\xfc{B\xa2\x85\xe7\x11\xd8a\x04\xf8\x16\xc4L\xb4\xf2\x99l\xde\x0dw~+`\xf9\x9b\x1ew~\xfb6\xdc9\xd6\xeb\x129\xbe(*\xa5'\xa2\xfaa\xdd2ah\xf6\x84\xda\xdcL\xcf\xadO/\xc4S\xf5\xa1b\xc6\x1a\xfdc,\n\x01\x11\x8f\xd2\x00n\xb0\x95S\xe3\x1eN\x89SIW\xc9\xb5\xb3U`\xe4\x91\xdb\xb4KM\xfb\xe8\xad4g\xf8c]\x05\xf3J\x9f\x9dL2\x15\x7fY\xa5G\xe1![Q-\x95\x1e\xb2CH\xb9\x8b\xac\x11W\x84\x8a\x88z\xf1\x88Q\xae\x14v\xd0\xa3+\x1a\xa3\xf0\xc7:*wf\xc4P\xd1H\xb5\x1bu\x1d\xb4\x93u\xb3\x0e\xe9&\xaa\x9dBc\xf2\xfa\x89\xea56\xdd\xb45\x05\x10\x1e\xa3\xfa\xc3\xc6\x819i\\\xac\xda\x16\xaei\xa1\\\x02/Wf{\x9b\xad\xcd\xf6\xb6C\x14 CuB\x03x\xc1\xe8\xd6\xd5Q\xbd\xee\xe5\xaaC}\xae\x1f\x1eQ-\xcaW\xfa\x9e\x87\xee\xf1lJ\xd3\xf5(wM}\xa2\xeb\xdcX\xbcS\xbe\xb3JSU \xd8ju\xa7%|\xa7%l\xa7E\x0f!1+q\xcfDY\xbc\x14\x173\x82\x1dH`\x1f\x12\x83\x9e\xaf\xb63\xf31V!\xae\xee\xc6D\xab\xb45\n\xa3\xcd\x14\n\xd7\xb5=\x05\xb8\x8c\xfbS\x01\xa1qw\xa6\xad{8\xb9\x8e=\xdcm\x15$\xe4P\xd3\x1a\xfdu{>g{>w\xdb\xe3\xca\"\x8e\xa6\xe5!\x17\x8bC.\xd6\xee\x8b\xc2[\xc5a\xad\x19*\x96\x121\xaeeEhR\x84\x0c\x03\xf7,\xb1\xe5w\xafj\x96\xb5\xd4\xb02\xe8$\xbex\xb1A\x06-vq\xf4\x10\xb6\xbc\x08O\x05\xb5*#(\xb9\xbc\xbdHT]\x84t{[\xec*]\xfdR1\xe5F\x8e -LK}\xf5\xb5\x025I;C\xd5\xa0\xce\xf9\xa2j\x89\xf9v\xf9hh\xd6\xb0\x02\xdd\xb7\x1aQ\xd6\xa1E\xcb\x81\x8b\xc4\x9d\xd1q\x0f\xe0\xd2\x08\x15\x9e\xd3F\xf0R\x81\xf2\xe9\x7f\x01\xcaW\xea\xc8\x17$\xb0\x08!\xe0\xb6\xaa\xa6\x83\x80z\xa0\x14\xc6\xa8\x87\x0e\xcc[4J\xc6\x01#T\x8dC\xc206\xb6KbEK\xc4w\x89\xb1\xf2\xbc\xa4\x9b\xb1M\x9b\x84&\xb6Q2\xe6\xe1\x90\xc5\xd8\xf2\xea\xc0NR\x12~n.\xa8 \xdb\x1a\xc7\x96vy\xffc\xbb\xaf\xb6\xb0F\x82\xa6[l=\x10\xafc\xef\xe1J\xc0\xe3\xf2XmS\x18\xb6oT\x90p\xe3En\x8b\x8dkQ,\xf2\xa0<\xb1\x87\xb5\xafY\xad\xcb\x92\xfdMG\xee\x0c\xefZ\xd0\x805\xbd\xba\x8b]M\xd0\x86\x03\xe8\xbd#+\x12R\x18\x8d{\xb0_\xfe\xe2^\x10\x8aZh\x1bz\xe5=\xfc\x96\xdd\xa1\xd1\x92d\xd0t:^_\x9d)\xd71\xe1|\x08\x1a\x06\xbc\xd2\x8f\xac\xf4\xe3\xca\x85O\xa9\xaa\xf8jFe\xd5\x9a\xc7\x94\x05.\x13\xa9\xec\x1f\x06*#\xca+1{|\xaa\"U\xd2\xba6\xb2\xd7\xa2\xba\xe4\x0e\x0f\xa6\xab3\n\xf5\x91\xa6\xe4\x8c\xa4Y\x177\xed\x16\xb8N\xc9\xc5\xdb\xd9\xd5\xc1\n\x07\xa81\xdc\x19X\xbbY\x84\x19=\xba\x86\xaeJ\x0cm\xed\xf2\xea\xc2\xd4\xeeC\x88\xe1\x91\xb2\xc4\x10;i\"*\xc3\x8d\xeb'ZlUB\xc4Ns\xe9.\xe5tbU\xbb\x11k\xc9f\xc2#\x88%\xc5)Y\xa0X@\xc27\xd6\xd9\x83\xeb\x12?\x1c(l\x05\x9a\xc2H\xe9\x88\x87\xb4\xaaz\x87\x83&f*S=k\xda\xfb\x19}_\n\xfa\xbe\xbcf\xfa\x8e*cI\xde\xf9\x0f\x85\xbas\xed\xee6\xf4\xfa\xfd~y\x97\xc4S\xd8\x06O\x08\x15\xf3B\xcd{\x00=8YW>'+\xcc{\x84I\xe74'\xc1\xf2zO\x029\xdcR\x17 \xdfU\x87\xd28#\x96W:#$\xe7\xe0Q\xd8Q\xfb\xf6\xe1\x96\xd2\x9fq\x7f`\x80\xf4.7\xc8+d\x82\xdf`k\x84:\xf1\xd9\"\xd1\xd8\x1ejCv>wj\x87J\xd1\xa9r\xb8\xa0K\x01\x9e!\xe5\xd3\x80\xdb\n\xf0\x8c)\xef\xfa\xf0hX\xf8\x96.\xa9\xb7\x1b\xc0\xae/\x8e\xa7\xa5@\xeeSB=\xd5* M\x06\xec>\xd1\xdcG\x905\xcf\xae\xe5U\x0e\x9b\xb3\"\xaa\xb2\xb2B\x0d\x85/\x18\x031.\xc3\x1c\xd4r\x07V\x87\x03\xe1Z\x89N\x96\xece\xeeSa\x19((x\xba\x0b\x1b\x93s\x14\x1e\xa1qY\x8d\xd3\x8b\xe1_C5G\xd1w@\xfd\x87\x0c1\x94\x9b\x0f}\xc0\xd7(\xdcR\xdf\xb5\x12\xdcC\xea9\xa5J\x8f\xea%]\x145b\x99\x9a\xffg\xaax\x99\xeb1\x0d\x94UxEG\xd4\x9e(\xb7\xea\xb1\xf2\x96ao\x00o8\xac\xdf\x89\x9c\x19\x14\xd3\xe1\xc0+\x9e\xe8\x1c\x9f3*\x8e\x8d\xb3\x83\xef*Y\x16`\x9fw\xd6 \xc7\xe7a6\x7f\x9aLU\xc8\xc8[:\xe5bT\xaf\nV~\xe8\x08B3\xe3\xf9\x9a\xd6\\M\x11~G\xdccM\xadPji\xa3\xfe5\x1d=\xa5c\xa7/\xb7>\x1b\xc7\x0d\xa6\xc6\xfb\xa2\xea\xc1\xfa(;\x8c\xf3\xa5\x08\xc0Bw8\xdd\x13\xa7\xb1\x98:k\x07\xaf\xfa\xb5p\x98\x8c\x93)\xf9\xb0^\x11@\xd2\x9e\x9dG\xbc\xfeYq\xbf\xad)vM\xc2\x8c\xc0`\xbf\xf5=Ph\x7f?\x8f\xa3/99zf\x9e\xa3\xbc\xb0\xf9\x07\x1d\x9b\x9f&\x13\x0c\x18>\\\x10\xf6\x0f\x9fl\xedf1\x06k\xd3z\xa56\x88-\xa5\xac\x96\xf6=\xfd\xd7l\xb9\xb6\xb7?\xd0@=\xfan\xc2\x07\xbe\xf7?\xe0\xde\xb7\x84\x88\xbc\xa6>\xc3\xfa\x8c\x18=\x1c\xc1\xc1\xd1\xb5\x8aB\x7f\xc8\xfa\xc8C\xfc\x81.\xcfu\x8f\xc1\xde\x9b$\xde!<\x95q\x19H\x98A\x98\x12,\xfa\x86\xd9\xb5\xc9\x14\xc2\x0c>\x93u\xd67\xd5=\x90\xdd\xb3\x0d%\xa2\x8dy9\x89\xd2#$\x80\xa7\xd4\x14W\"/R\xec\x9b}\xd8\xb2\x04x\xb1k\x92\xc4\xb3\xe84w|\xfb<\x8d\xa8\xdb\x9b\x82O\xd7/>\x80\xb9\xa4\x1e\xa8\xe5\x0d+N\xf5\xddH\x86`\x93\x95H\x12\x85\x83\xd7}\xe0\x1b\x1b\xb2\xab\xdb\xd4K\x95\xb5\xdd{\xee\x87\xab\xd5b-\xd8xCD\xbfz]\x06\x162\xc9\xce\xc0\x16\xc8\xb6\x13\xc1\x8aSzI\xf2\x1ax\xff1F\x08\xd1\x042B!\x84\x98\xed\x83\x12rr\x8c\x90\xc4bOXQ\x9f]T\xce\xc1<\xfb\x0e\xf4\xc4z\xeaw:\xed\xa5\xf2\xb5 k\x8caP2\xdah\xf3\x01\xd4\xa0\xc5\xcb)\xb3&y\xfddT\x93\x96\xa5y\x18\xf7@\xa6}G/\xd2\xb7\x06\xde\xbeP\xc7\x10\xce(\xa9\x16\niiG\x03\x05\xbep{\x00\xdf\xf1T\x85\xfd\xc9\x829\xf3Ld\x15\x16\xd6\x97)\xdc\xbdu\x9d\x11\xfcW6_r\x85\xa7\x92\x01\xeau\xb82\xa6<\xfb\xfa\x8d\x96\xc5\xe34IJ\xcd,\xfb\x81\xa2s\x11K\xc3\xf36\xf9:\x93b\xa5\xeb\xacS\xd7\xffP\x93B\xd9\xe7\x94\x11z\x14wh\x1a'\x92\xaf\xa6!%G\xf8\xf22h?c\xcd\xdc\x92}p)Y&g\xed\x92\xb6f\xd6K{\xc3S\xb2 l\x02\xaeM7f\xed:\xe5e\xd7)\xf3N\xea\x0bbO\x1c\xcdE\xc8F\x89\xcb\x03\xe1\n\xe2K\xe3L1\x81\x11\x1d\x8bF\x1d\xc6\xd2D\x0f\xc3h0\xd8\x15\x9d\"E,&Gq\x8b\x8flA\xa2]\x12I\x9c\x898P.\x80-\xcd:\xd1\xbc\xd5\x17\x8f\x91\xbb\\\xf8\xe1\x99\x89\xe2\x99H\x19\x93`\xf0Hk\xc5\xd8\x0c\x86\x10y\xb6\xb2\xdcb\xb92\xbe\\\xc2Y\xb7\x19C\x06F\xa9\xe3\x94z \x03\xb2\xc8\x1b\x9c\x11\x1a@/\x8ay\xb5\xfb\xcfd\xfd3V\x883Cf\x82%\x80-\x1e\xa8\xec\xa5\x99\x98\xf2\x92M\x19\xa9\xd5\x84\xed'\xf3\x07X\xa0\xd4\x9b\x95\x0bhU\x94r\xd6e&f\xcf\x7f-\xd9/\xb1\xdb\xbd \xc3W/)y\x19\xe2\xe3\xd91 `\xa1\xe1\x01\xc4\x9e\x8fc\xd4\xe9\x1a\"\x1eE\xdfi\xd1\x9b\xe0\x9a\xea\x96\xd9\xfa\x0e\x98,Hh-J\xa44\xdet\x8b\xa1\xdc\x1fB\x1c8\xc9yL\xd2\xa3gp BaE\x0c\xe3n\xa0\x9e\x14CQ\xb4S|\x83\xc1\xfb\xc3\xf2\xac\xe0w\xc3\x05\x15\xf5N\xb6\xc4M_pw\xd6\xc9,Iz\xda\xaat\x90\x90\"\x02\xae\xb2ks>\xc0f\x1f\xbfF\xd5\x92c\xb6\xf3\xa4\xe8\x08\xfd\x97\xea|\xd2\xa0\xe9\xc8\xd1\xec\xaeJ\xa0\xec\x86pM\x0fFl\xa9\xd2L\x12 \x84\x03\x07\xad\xaf\xf8\xde \xf0\xf3e8\x90\x7fI\x1d\x0d\x12\xd5}\x88Gj4^\xb3\xa8m\xcb\xf1\x81M>#\x18,\xdbi\x9d#\xd2m\x8dY\x1fN\xeb|%\xd0\x17\xc3J\x88\x87b\x85\xe3\x88\xfe7\xa2\x02\xae\xd6\x81\xfa\xebzQ\"KR\xea\xca\xe7\x1c\x11\xef\x17R\x98\xfd\xdb\xdb\xfda\xdd\x81uT\x1b'\xed\xedWd\xa0\xd6 \x14\xb2\x16[\xa90{\xcdu\x11:\x06@.)\"\x16\xe9\x9f\x87\xd9\x13NO=\x1f\x8f\xa1\xe3c\x12gyJ\xde2z\xedU\x89\xb7d\xa5\xac\x03/zw\xdc\x83\x8d\xf3\xa1zn\xa8\xa3a\xa2\xd8{;\xd8\xc2\xecHjb\xba\xf5\xaf\xf6\xd3\xb22\x05\xc8\xba\xf5 \xce-k\xdb\xdd\x1c\x9c\xa4F\x84\x9c\xc3\x0dw\x99\xa7\x93\x17\xda\xb7:1+\x87{\xe1m\x83r`3\xb3H\x0b\x11\xe1\xc1v\x1e\xc1\x043\x043\xca\xe8l\xee\x01/\xfb\xd4\x02\x01e\xb5[\xf7\x96\x9cI\xc9\xe0\xe8\xb0\x15\x0e\xe0\x9f\xb4dmT\xb6&(\xf3: K\x83\x1c^\xad!%\xf7\x83\xca\xe0\x0c\x04\x83\xa3\x99N\x941\xc9}\x08\xcf5\x9eC\x1fi\x00?\xd0f2\xe0\xd7O~6TO\xfb\xc2\xdeV\x81dR\x0f\xfenN\xfc\x81\xc3oNH$*j\x18\x1f\x8c5>\xac @\x0c\x9d\x9cDt\x89\xe0\x90\x90\x8f\x13\xee\x82\x1c;\xf5\xf9\xcbU\xfa\x9c$yL\xaf\xdc\xe5\xcb\xabt\xf9\x99\xac\x7f\xe4L1i@\xd7\xad\xdb\x17\xd7\xd7\xed\xda\xb9\xd3\x1b\xed\x9d\x1eS^j\xb4\xdc9E\x84M\\\xfa6\x87\x93\xcf\xc8\xbc\x14\x14\xe5'\xea\x89_n\xda\xd0\x1f[S<\xf2\nH\xa6}\xac\x0b\x025!\x0f\xad\xa9,$fGAA}\x10u\xa9FM\xd1\xd4Q\xf8X\xe4\x0c9\x84\x08w\x9bN_a\xc0G\x11%^\xe8\x97\xf8\x82\x06\x10Zy\x15&Qq\x89\xcd\xd3~\xba\xcf\x10Q\xac'e\xfc\xc8\x85\x17\xfa\x01\\x\x0cU\x18\xc4_\xc8\x1c\xae#\xf6\x99k:wB\xec;\xbeVy6\xf74\x9eEF\xf2\x92K\xa0En@\x8e\xac@.v=zm\x95j\x95\x9b7\x01\xb3\xb0V\xd4+<'c\x91\xd8\x97o\x7f7\xce<\xb1\xef\xeeR\x9433\x15\x002\\\x0cu\xf8Ue\x1a\x8e\xb7\x92\x8c\xba\xf2\x9c\xab\x84\xcc\x9ax<\xb9\x8a\xce\xadjx\x9e\x8d2\xf2\x85\x1e>jY9\x13@r\x97e\xe1\xdb\x1c-Cq\x7f\x16\xb1\x93\xc1\x01\xfd\x8a\x8f\xcb\xc4\xb9\xcdA\xfa\xbeb\xedb\x07\xb2\x9af\x17\xe9jy\x8am\x18\xa9\xc0\x94\x87\xca7W7\xb5\xa7\"\x1a\xaa\xf8\xc4\xb6\xe2\x80&pq\x1e\xa5U\xabi\xab\xf7pE\xfe^\x8a\x1a\xa3\x08x\xec\xd2\xf8\xad\xc6e\x02o\xabA0\xa6\xa5\x93\x17\x95n\x19\x86\xf4\xb1\x97\xd5z\xd2\x05A\xc3\xb2\xd2\xf1(\x1a\x17\x0e!\x9a\x81bf\xf2\xca\xd1\xe7\xc5\xa3]G\x89#l9iA\x84\x86x\xf7\xef\xde\x7f\xf0\xe0\xf6\x9d\xbb\x0fx,\xcf\xce\x10\x03ax\x1c\xcc\x9d\xdb\x83{w\xef~\x7f\xef\xae\xef3f\x0f\x1f\xec\xc1M(\xbeQ\xee\xdfa'\xd3\xde\xdd\xbd{w\xee\x0en\xdf\x0d\x80\xc2\xb6h\xea~\x00\x83\xbd\xefy\xf3\xf2\xde\xe0\x9e\xdb42\xe2(\x85\xa4\x02\xc5\x0fm\x15E\xa3\x11\x19\x0b\x01\xa3\xd6\xbb\xfa\xeb\x0b\xba\xba\x08\xde\xec\x0b\x15\xe6p\x18\xb2\xbf\xb9\x15.(\xffD\x9dz\xf1\xd2Q\x1c\xc0\xef-N\x11\xe6\xb9T\x0eCUz\x17\xc7\"g.\xa2\xf2X\x84G\x90\xf3\xd3\xd1HH\xa7\x88\x9e\xd1(\x193\xd4)s-\xb2\x1b\x03\xe7R\xe6\xb5Y\x19\xcd\xf0*\x1fi\x9d!\x16\x1b\xe1;6\xc0\xd3\xb9:\xdd \x9f\xee\x0c\xcfc9\xdd <\x02\x8cm\xda\x9abB\xe0l4\xc1I=\x84\xc9\xf6\xb6\x81![\xc0\x90\x7f\xa7\x17\xc8\x16p\xc0\x9b\x19\x8cq0\x11\xec3\xeeWQN\xea\xbf\xe3|\xb0\x17\xa2g\xd4\x02]\xc9.\xbc\x84IQaIH\xb3\x96\xec8\x18\xc4\x81\x0e~[!\xfb\x7f\xe1\x9a\xf0x\x08\x13]\x98\x8a\x15y\xe4\xc5\xa5Z\xe9\xb1\xf8\xdebp\xaf\xa0\x9b\xe0\xfah\x00\xe8\x88\x1a\xc0\x88u4\xf6+\x1c\x19q\xe1\xc8\xe4%\x9d\x0d\xc8\xc8\x94\x00O^\x11b\xb5 \xff\xb4\"\xa2\xe6\xa8h\xc9\x8d\xd5?@\xcbE\xc9K\"\xbb\x9e6\xb3\xae2\xabQ\x9eMa\x05\":LQ\xf0J9\xd3\xd81\x93\xf7V\x0c\xb7\x90\"em6\xff\x03\xe4\xaf'\xc2\xf6\xbf\x03\x038\x80y\x7f\x95\xf0J\x10\xf3\xd1\x84Q\xa3\xc6\x8d\x11\x1b9\xe3\xc7\xe7\x9c\xc1\xe4\xbf\xfd\x00{\xf6j\xda\xbfyi\n\x97\x02s\x00\xf36\x96\xf42\x80_\xafL\xce\xb4\xd1e\x88]\x86\xcd\x8aB=\x13W<\xafZ?\x9cG~R\x94}\x0c\x9a\x91D\xd2\x10\xae\xe95\x126\xd60\x93snr\xee\xae\x08\xcdF\xe5\xec($\xfc\x11fF\x1e\xf38..#\x11\x1d;Q\x07\xcf\x95\xe9b%3\xb4L\x00\xfd\x84z\xa9 T\x8a\x80H\x04\xcb\x13#\x90\x88E\xaa\xcc$|C\xfd\xf3I\x15\x86\xfa\x97f\x18S\xb95\x04o\x027A\x87\xdaH\xd7\x90PGue\x8e\x96\xa0J:\x1d\x12\xde$\x02_\xdf\xf9J\x8e\x10\x97K\xff\x0e\x1a\xdd\xe1\x00V\xa3\xc5\x18Z\n\xb1sE\xd9\x9c\x9b\xc5\xf8BW\xd7J?;\x1e%>w8(8\x1c0\x94|\xa5\x90\xf7\x99\x95\xbc[\xdc\xbc*\x15\xbf\x04C\xc0\xf63\xaf7\xb3\xf6\x03\xc4\x8c\xdd\x87\x82\xd5\x8f\x1fB\x88i~\x18n\x0ca\xe0C>\n\xc7\x88\x067Q\xb3@F\xc9\xf6\xf6\xd8R\xb3\x0e\x14\xa1t\x94\x8e\xb9\x8a\x8b\xf5\xc8M\"\x98\xe3A\x1f\xcc\xcf\x1e\xaf\x02\x98\x04\x10\x0605@R\x9c\xe7\xec\xffj\xb9z\xb5H\x7f\x93*\x11\xb4x\xb2\x04\xb6\"\x12\x0df\x81c\\\xeaWxS^q\x0eRQp.W\x88?{k\xe03V4\x1fc\x9ck\x0e\xdb\xc6\xd4\xb8\xd0~xs\xa8iA\xd6\xc2!\x15\x1c\xb6\x84\x9a1M \x14\nu\x84\xda\xb6@\xaa\xa8\x84\\!P\xb8\x80.\xa9\x80\x8e\xab\xd6\x10tb\xcf\x86\xf0\x08\"\xdc\xb1>\xbb%h\xbb\x97\xf0-\x1b\xf3\xd7w\x06\xa8\x9d\xe5\xf7\xe8(\x84m\x97rn\x86\xc2\x1f*\xee\x19\x8f\xcc\xe3\x82\x9d(\xac\xa8'5\x93\xe6y\x95\xbb\xe0&\xda\x93\x00\xce\x1b\xe7\xe5/\x7f-;aa$Z\xf8\x08\xce\x10Df\x11)\x81\x03Ht,\x82\xceo\xf2\x97\xffel\x82\x94\xcd\xb4/L\x1cNa\xc6&LF\xa1\x81Lg<\xf8\xc6\x911\xa0\xc4\x9bu=\xa2\x85#\xadC\x0f\x05O\x81\xf6z\xc3\xb1\xd2.\xc3\xed\xec\xac\xe0\x11,\xae,\xb7U\x08\xecn\xa0?\xe0cy\xc0s\xa1y\xc0%\xe5R,c\x14d\"\xce\xfc\x0c\x1e=\xc2#\xbf]L\x9b\xa1\x98\xa6[\xac\xca\x9beT0\x1e\xb3!\xfe\x89\xb4\xd1\x8b`3d\xc2T\xce\xf9 \x06yc[\xad\xf2ZIB\"-k\x01\x92\xbd\x98 \x87\x11\x1a\xcd\x8c\xab\xedm\xfd\x9a\xcf\xbb\x9e\xf2\x8cS\xcc\x88\xc7\x99\x99\x05\x93\x9c\x8cta^\x90K\xe9\x00\xb2\xaaQ\xcbi\x95ZrNj\xc5\x98\xa4:\xd9xyej\xf9\xdf\xacKz\xf9\x9f#\x86\x82\xae\xe9wy\\\xe6Z\x14\x86\xbab\x8e\xa1\x92\xc0\x8f+\x7f\xb8\xbe'&\x8a_\x1d\x0eZH\xe1\x9a1\x14K\xf2\xff }WXr\xee\xb3\x8a\xd5\xf4E\x99\x97P\xc0\x92M\x80\xb1\xee\x13\x93\xf1\xb4\xb3\xa6\xa5]\xcb\xf2\x1f\xd4\xb0\xbc\xd4\x00`\xde\xd8\xe0/\xae\xbc\xc1\xa5\x18\xc3\xa3B\x0b\x9f+\x86 2\xa2\x8e\xdf\x18\x8cu\x0c\xc9\x8b\xeb\xd9\x835U\xaev\x99\x90\xe4!\x06W\x87i\\./\xc3\xea\x19\x05\x12(\xf3\x08\xfd\xc6F\x0ce\xc0\n\xc3H\xd8\x87\x0c-\x01Z4\xaa\xac\x1a\xb68,\xca\x10\x89e\xd3\xe1\xadXv\xde\xa5f\xd7#\xd1)w~c\x91+\xba\xf3\xd2\xb9\xf6\xa5\xfeve\x0d\xac\xa4=n\xd0\x91\x94\xd3\x91\xa8V\xb6\xe8!\xa4\xa2\x84L\xea\x94\"9.\xea\x97\xa0\xe7\xc1X\xadwY\x9f\xdc\xaf\xfaY\xfcrm\x93\xe3L\xa6\xdb\xd4\x0c\xbcN!|\xd5\xe6\xa5\xe7w\x18(\x12(\xb3\xcf$\xfdJ9\x06\x13,@\xa7=}qE0H\x8a\xac\xa0k\x03\xad\x88w\x83\x06\xf0\xd5\x0f\xe0\x86\xdaKL.ZS;\x14P\xa6\x12\xca\xe8_\x19\x94A\x02\xdc\x99\xf2!\xd8\x8b6\x88\xfa\x13\x04\x17\xc9\xac\x0e\xc7\xd4\x98<\x0b\xaa\x8e#\x03)f\x8b\x89Z8\xd6\xa8\xa8\xadZ\n\xe1\xdcg3\xd5AI^\x97en\x9bT\xee\x96\xb6n\xb0\xbe\x99\xa8b!>Q\xf0\xce\xd7v\x1f\x91l\xc4\xc1'\xddS\x0f\xb0\xcc\x1e\xafy\xd6:6\xb5KD\xfbj\x87v\x95FR~f\x19\x83]\xd1\x91\xb4I\x0b\xf8\x92\\\xa6\n\x00\xe4]\xbb\x0cQ\xc3/\x18\xc2O\xd4K\x8c\xf6s\xb0\x8a\x0b\x93$\xa6Q\xdc\xa9\xf8C\xb3\x7f\xe5W\x9f\xfb\xcc\xb6\xecj(\xb7\xa7ic\xb4\xe6J5\xe6I\xad\x11\x90*0\xd9*c\x1e\xea5\xdc\x82;\xcd\x96g\xf2\xd9^\xf3\xd9\xa2\xf8\xce\xe4\xb9\xbf2x\x0c\x9c\x89\xd8\xa1\x0bc~=\x87<\x96\x9a\x88Z\xf6\xe5\x9cxJ\xcaI\x8d\xf0-O\x82\xc8\xa3\x96\x0c\xa3\xb1\xbd\xc6\x03\x1fL*t@\xde3~\\\xa7\xf0\x98g\x8dN\xe1\x11\xac\xe1\x00\xce\x89\xb7\x8b\x0c\xcfY \xe2L\xb1\x10\x04\xf1\xe2>M\xb8\xfc\xedcYZ\xd2\xd9-\x06\xfdD\xdeG_ \xf6\xacI\x03\xd2\xa6\xe9-4\xb5-\xfe&:/\x127O\x8b\xb9\xddaD\xc9\x032%-y@\xd8ArN\x19\x9bL\x1c\xf2\x80(\xc2\x87g\x8e\xb1\xe49\xbc\xc4\x11\xf7\xad9-^E\x19\x85Q/\x80\xde\xb8\x99\xd4\xa2\xd2\x93cR\x8bH\xd6\x8a/\x93\xe2\xfbEVrZ\xcdJn9M\x99\x00[\xb0\x96\xe8+\x83#O\xd2\xe842y\xb6I\x99\x8b\xf5\x14\xf7y\x99P\n7\xe1T\x13\ni\x02P#\xbbF\x05\x06\xdd\xb2k\xb8\xda/\x10d\x84\x83\x8c\xb3U\x95\xaa\xf9&\xbfo\xf4\x0d|\xac:\xb1\x11x\xa4d\x83\xed\xee\xb2\x06x,<\x82]8\x80\xb7\x82\xc7\xc3m\xb6+\"L\xdfJ\xa7\x04\xb4\x00\xf0gD\x1b]\x06`N\xb0Gp=\xe5b\xea\xdf)\xed9\xc74\x8c\x16v\x86J\xba\xf7\x1b_J\xac\x81\x02\x08\xc5\xcf\x18%0 W\xe1$\xa2kn\x10\x1f\xc2{t\xc2\xabG\x0dpy\x10E\xac\x88\xbf\x14\xd5^\xa2\xfd\xe3\x059#\x8b\xf2]\xf3\"n%\x8e\xe1\x06Q\xfa\xd0Z\xee\x00\xf8\xd8\xd6\xba\xd0\x13\x8e\xc6\xec$\xd3w\x13 \xbf\x0b\xae\x8a\xd4\xf7\"\xaa^\x98)y\x0e\xea(F6\x03\x16\x16\xa9\xcf\x19\xdd\xca+`F\xd8\xc2\x0e\xea8}\x1fG\x83o%\x15P5\xa9\xb2v\xc0\xdcJ\x169@9\x84!\x1c\x96\xb9\xb3\xf4\xf3\xdfJ\xf4*\x95\x8a\xe3\xc4\xeeC\xc8\xb8\x8bi\x86~\x92\x02\x16\xd9\xb8\x10\xbf\x8c\x049B7\x91\xb0\x80\x1e\xa3\xf1~\x00a\x9d\x82ip\xf4\xc9\x8c\x92\xc6\xf1\xde\x8a\xa2^\x15G1\xc8\xf8\x1b0UX?Q\xa8oA\xd8\xc8\x8e\xb0\xfaN\x9cp0\xa9\xe2\xa0\xc9\xa2\x848\x98b\xb2L\x86]*\x185(\x88/Ez\xc8\xa0\xf1\xab#r\xca\xcdbE9\xd1d.z\x13\xca\x8a\x08\x95|\x81\xf0k\xcb\x8bi2&\xca\x0f \xaf\"K\xf3x;%\x01,I\xc0\x98\x06[\x1a\xf5\x13\xf3iU\xf2\xea\xf2\x10\xd7BX(\n\x8b\x93]\xbf\x0c\x80J\xbe\xd4\x165\xc3\x0f}3|*\x89D\x04\xe3\xb0\xeb\xd7&\x06\x95\xb8g6\xb70\x00\xa3\x8d\xb5\xa2\xc7 +\xe5\xac\x0c\x9e&\xf2\x92\xc4$\x17\xfeK\x07\x12\xc1\xf8\xf1\xbe/\xa3\xdc\xf1\xa7\x99G\x05\xe1\x97\x92\x8b\xca\x87\xbb\xe8\x19\xbb\x03\xb9\xfd\x93 F\x9a\xee@n\xe0\x1b\xf1\x95\xc7\xb0F\xdca/\xdb\xec\xa1\x02\x08\xad<\xbc\xbc\"t\x9ce\xd3\x9e\x14\xfb\xe1\xd8Rt\x04\x14\xb5\x04V{\xdc\x99\xc0>\xa3\x9a\xf6OD\xcb\xe8\xd9\x15\x8e\xa8>W\nh\xb7\x1d\x80\x0c\xab\xab\xbb\xe5G\xa89nYV\x11 \xea\xbc\x80\x13$/\xd5\x05L\xe0\xf1c\x88\xec\xdf\xcd0\x00f\x9b\x1d\xeb\xf2\x03\xcb2\xcd\x8a\x05\x9d]\xf3\x82\xe2\xb9\xf6\xd0\xe8`\xa1^l\xed\xb5\x19]tW\xa1\x8b2 }\xf5+\x12E\xf6\x98\xa8\xd3\xa6\x90\xaf_\xa1P\x85\xb6\xbel\xb6\xe3\xcb\x8b\x0dcR\xf3%lCpP\x08&G\xf2\x19\xec\xc3\xa4\x0d\xc9A\x8c<\xe7\xae\xe8\x19f\xde\x8f\xf8\xa1\x940\xd4\x88\xd9\xa9\x1d\xf9f\xb7\x04\xb0N\xc9\xb27\x90.6\x1e\xbb%\x948\xd7&\xfb1\x1d\"a#;\xd7\x99E\xa3\x10J59;\x9b\xd98UU9\xfeTT\xe5\x04oH=y\x8c\xbf\xca\xacGa\xa1$\x8f\xf0\x87\"5&\xfc\x86\xd0\x97\xe7\xfcW5\xb9W\xe8\x04\x8a\x0bb\xd3\xa8\x9d\xa2i\xd0C\xc5\"\xb7\xeb3\xf1\xcd\xd1\x14\xfe\xbe e\x13\x88s\xee\x8f/\x92\xf3\xd8c*(w\x9a\x7f$\x89\x9bT\xcc6>@^\x18\xf1R\xf1\xa5\x88l\x1b\x93\xb3\x9c-\x9c\xdb\xa4F\\G\xa1%c\xce\x8c\x9b\xf8&\x1c\x0e|cHXX5I3~B\xc9\xbcQ\x9ed\xc3\xd0\xc6[t\xccXi}\xd8\xa0iE\xb3\xea\xc8\x8b\xe3\x9f\x96n\x99jWA\x05v\x1c\xf2(\xec4xK8(nJ\x13Y\xae\x8e\xb3\x19\x83`\xc2\x9bC3OW\xa8\xd9\xd0\x1f\xa0\x88\xc1\xa3\x8ag*\x15\x1e\xa8k\xe2\xf1\xfc\\\x82-E\xae\x94\x8d\x8a\x89\x97\x8d\x02P\xfa\x91<1\x8f\xa4\xb0\xa0\xd7l\xbf\xaaeU\xcf\x0f\xf2/\x1fq\x81F\xb2\x82\xb0\x0dg&\xa4\xab\xfarJ&R\xf0\xad\xf8\xf5C\xee\xb7\x80\xae8XXuX\xf80\xf0P\xad\x14=\x19\xd8G;C8\xb3\"^[\x99wcE/k\x92\x1e%\xe8EF\x9d\xf1r\xc7\xea\x13\x19\x7f`(o\xac\x98\xf5\xd5t;\x98\x9f\xc1\xcc\xb6\xb7\xb0\xff\x89\x0b\xfb\x8f1\x1e\xb0m*\xce\x10\x1623bc\x8c\xdc\xf4>\x9a\x8dv\xf1\xefm\x0c\x19c-h<\x16\x18>\xe4\xf5\xfd\x95\xb4\x91\xa9\x9c\xe1\x9e\x12s\xc0\x0d\xbf:N\xa5\x1a/Q\x88\x1e\x13\x15\x99f2\xe8t\x1bfl\xd4\x0f}|.\xf6\xd1\x84\x8dkR\xdd\xf1\x070\x92\xc6\xa3\xc9X\xec*&\xd8\xcd`[f\x1f\xc8\xd8\x9fg\xba\x11q\x99\x90=\x9e\x05\xbc\x8c\xfa\x8c\x1d\x00\xfc\xdf\x04\xff\xb5Md\xc1\xa5\xb1\x04#\x08\xf0\xcf\xd0\x7f\x08+\x06\x11\xec9c\xbb\xc9i\n\x95\xa1\xf3\xf1\xea\xf1n\xde\xe6N2\xc5 \x8aG\x18#\xc1\xc9F\xc8%\xee}60\xbc\xad\xa8\xb70\xba\xd1pda\x905\xff\xe6\xe6M\x8c\x03F\xd1l^SA\xb4\xd0\x8a5F\xb0 !\x9f\xf0\xe9-a\x08\xd9CX\xc2c8c\xff0J\xd0&K\x1c\xc3\x10\x16HA\x96z%\x89\xbcXwkAr\x8e\xc7\xbc\xdf\xf2\xb71\x81\x94\x9e\xbf\x93\x1f\xf2\x9e\xcf\x90v\xc1\x10\xe6-\x94 $\x83/A\xe6\xb1E\xc1(\xf6iEq\x92\"\x1b\x13\xfax\xd6=\x1e\xc2\xca\x87\x9c\x81c\x85\x8b\x86\xfff\xdcmaR8(4\x9a\x12z@\xde\x96.|\xb2pGf\xc2q\xc4(\x15\xe2\x87u\xe5\xc4>\x9cX\x85\x19\xb60'\\\xe8~\xfc\x98\x1d\xe8\xb6\x85a\x038A\xea\xba*_\xf7\xe1$%\xe1g\xf3W'BP\xdb\x1e\x82\xc7\xb7\x94\x0f\xdf\xc1 n\x92\x9d\x022b?\x8dN\xf4\xc2\xad~q'\x1c\xab\x1f\x0b5\"o\xa7\x0e\xd2\x8c\xad\xcc\x0e\xcc\xd8\x12M\xf8~x\xc4\xf7C\xe5\x83b93F \xc4\xfb\x92\xba\xec\x08\xaa\xb2\xa3\x8d\xa2\xec\x9c\x924D\xb5Fy\x9cp\xb6\x9bV\xd8\xf9\xb0\xd4\xed\x00\xc6q\x96\xeeU\x13\xd5\xbdj\xea\xea^\xc5\xc8\xc49\xf1r.\xee`\xa4f=\xba\xd1p\x1c\xff\xe1\x96/2U\xf3EV\"\xe8\xcb,k\xa1=\"\x04\x93b[\x99\xe0 Z\x01M\xe9{&\x1c\xc2\x8f\xc5\x9eMp}E\xa5\xbf\xdc\xcbxJI\xbe\xea\xd7\x9dR2\xe5\xf1h\x93\x0e\xe8\x91\xc0c\xe94y\xf3&O\x10Uz%'HR$\xe4\xebYn\x0c+\xf5\xb9-\xc5\x1cw\xab\xdeE\xa5\x9c\xd4Y\x9f\xb1My\xe6\xd4\xfe\x91\xbd}k\xa1\xc7\xa7\x9ce~M\xca\xfa\x8e\xecVg\xbf\x9b\xb3\xff\xf5\xf5\x1d_\xdb\xa1X\x94\xc2\x9c\xd5\x11\xce\xd4\xe0\x07\xd7\x94|U\xd5\xc3\x91bT1+!\xca\x14\xe1(\x02\xe1\x8f}\xb4\xdb\xf7\x8fy\xea \x9e;|\xc1\xed\xcb\x0e\xb9\xc3\x9d\xe6\xf4\xd4\xaaLXre\xc2\x92\x8d\xeb\x03\xf1xu\x9b\x0b\xe25B\xfd\x0c\xad\xffl\x970\x84i'\x90,\xbd1\xf5R.\xf8\xe0(3x\xfdb=6LIA\x0c\n\xff\xac\xe4\xf8\xd9\xd1\x1a\x9aT C\x9e\xb7I\x8f\xb7\\?\xd1\xa6(\xcc\x05y\x1cr\xedi\xf9s\x0f\xbe\x83D:n\xa2\x8d\x88\x1b+\x9b\xc9O\x0d\"\xac\xbcD\xff\xca|\x84\x8a\x05\xa55\xc3>\xf2\xfb4yI\xd6d\xfa\x9e|\xf1\xfc\xee\x94\x99\x8ev\x0d\\\x83\xdf\x9f-\xa2\x95\xc7:x\x1d\xf2|:\nn2\xa2\x9bVp\xb5\x8a\xb9\xaa\x933:\\\xa0\xf1L\x96}c\xd4%\xc2\xc3\x9c+1\x14\xe7\xde\\Q[0\"\x12J\xd1T\xa3\xbcTb\xcd\x8c\xb6\x99\x12\x01rD\xa5\xd0\x1f\x0d\xc6m\x8b\x9dr\xd5\x1e_G1\n\x9ej\xdd8\x08>?\xe1L\x9fK\x12Z\xb6\x90\x8bB)\xa2\x19#\xc90\xf1=\xa9,\xb4\")\x07\xf7\x0d\x17\x94#\xd2s2\x0c\x8c\x1f\x90\x93s\xcc\xbc\xfc\xae\xc5\xeb\x04\xdd\x95\x14\xaf\x93\xe3<#/\xc9:SJYH\x8a\xd7L\xe2k\xea\xf4\x8d\x81\xa6k{\xec\xde\xfc\xab?\xb7\xf9g\x7fn\xf3_[\xe2\xd8\xfeAl)b\x89:\x02R\xed\x9e\xdd`[\xbc\xcd\xabSi\x8e6\xb1?\xc0b\x8e\xb2xIkCgE\x99d\xf1\x91\xac\x7f\x86\xdeg\xb6\xbe\xdd\x07\x0b\xean\x12\xddx\x06F$\xd0U\x14as\x9a\x87Y\xab\x1b*\xa8\x1dE\xf1d\x91OIV\xafj_\xb4(_\xe8\xd6\xec<4\xb78 's\xf2\x8ed\xf9\x02\xf9\xdf8\x00\xc5\xa3\xf0c\x8c\x8f+e\xbbl\x11L\x85ZO\xebL\x01U\n\xd5\xa8g\xe5\xc8\x18\n\xafC\xf4\xb5\xa7fu\x84\xb1\xd8\x95\xe2\x9d\xdau~\\\xdf\xcb\x0e\x82wmR\xbd\xd4n\xca\xaex\xbbf1]\xb2\xf0nN\xac\xf2\x92v\xcd\xd4Z\xbeV^\xc8\xa5\xd0\xd6:\xb6\xf2*\xf7\x19\xba\xb9\x8ev[\xb2!\x01\x86u\xcaw\x95\x0f\x07\xe3@\xf9\xbb\xe1^X\xbf\xecfQ#\x19\x91\x97)\x8b\xb9\x1b>\xb2\x95\xc2\x15\xfe\x99\xc9L\xb0\x0f?\x1b\x11\xa9r\xd3D{\x9f\xb7s\xba\xad\x148\xad\x13\xdd\xb4;i1\xd3\x80\xb4\x1e\xd2\xe9RT\x99\x97%O\xcd\x85~\x0b\x19{(r\xd0G\x18&\x8c\xbe\xf6\xbc\xc4N\xaa\x15\xedp@V\x02\xe44\xbc\xab\x12\xa0\xa8\xc5\xd9\xa6J\x83R\xaf\x9c\x91\xfcXX\x04MD)j\x99\xb2\x9e(9\xcdY\xc5\xe1w\xe6\x14\xce\xdd)\x8d\x14_\x93V*\x83\x8ev\x82\xc0H\xf9\xd5\xfc\xf6\x99\xf0I\x8b8m\xb0\xbb\xa8\xa0o\x82\x95\x06I\xf9\x9dA+\x0c\x14d\xcb\x91\x02\x85\x0c\xdf\xb4\x0b\x00\x06uB\xa3*\xa2a\x8f\x7fl\xf7\\\xb3o\xf0Xe\xb1\xe2\xfan\x8f\xbb0G6.\x8br\xf6\x07-s\xce\x9c\x90<\x05\xbe\xeag\x00*w\xd5a\x9c\xa0\xeeE.%\x9a\xb6\x8c\xae\x8c\x07\x83J\x8dl\xd9\xd2 \x16=\xa1&@\xe4}\xdc\x19\xc0\x8e&\x855\x08\xee\xa1Nc\x8d\\A\x95\xc6V\x1a7\xb4|56\xae\x85;\x8c5\xbc\\\xac\x8f\x0e\xf9\x8f\xf3p-\xc5H.\x03\xd82\xc1N\x1f[d\x9b\x91\xf6\x8c7\xf7\xe0\xb4\xe5\x7fpU\xf9\xb5\x9c\xec\xb8\x19\xa3:\xaa\x19\xf1\xf8\xacH\xd4\xebv\xfcFxL-Y/[[%A\x8c,\xa7o\xf4\xe7\xb2\x03\xc5x\x9a\xbc\x80\xb0\xb5kJ\x0b\xf9\\\x87ia\nl\xde\x94gJ\x9c\x80\xf9\x8c \xf5Uy\xa1\x1d\xe1\x13\x8b[/H\xa9A\xe5\x13\xf0\x832\x91\xe2\xf6v\x00\x91\x87~ \x1c\x02hn6\xe7\xf9dS\xad\xfb\x84\x81\\<;\x1f\xe1\x04\xa6\x1a\x1f\x91X*/\xb6\x03\xad\x03\x9b\xe1\xe8\xfc)q.o\xe5F@\x06eT9\x92\xc4\xfe\x854\x84%.\\ \x08\x9bX6\xda\xb5X\xcd\xe4\x85\xd9,\xb5\x89A\xd5\xab\x8a/34\x15*9\x81\x9ecED\x91[\x1d\x91gfd8\xc1(\xf8\xe8\xf9\x1d7\xdb\xc0\x17W\xe2G\x0d\x11\xa7l\x86\x9d\xdc\x88\x98\x101\x80[\xe8\x83\x83\x81\x88\xe8\x93#\xde\xff,*\x98E\xady\x93\x18\xda\x1c\xf1:ff{\xc2k\xa4\x90\x86\x80\x1cF\xc0 \x81\xcd\x06r\xf6W^\xf4\xc8`\xd2\xa7 W\xa1+\x07\xb1\xe7\x97\x90\xd2\x0fJ8y\xe7\xb0\xa3\xc3\xcc\x0c\x86C\xee\xe9\xe7\xb1\xcd\x96 G\xa4]\xd8\xd7V\x9a8\x13^\x8d\xf6cg\"Y\xcc2\xdc \xc4\xcaZ\xd2\x18\x1a\x96\x06\xc4\x00\xb6\xf0\x94\x8a\xa4Y,,\xd2\xf8x\x93\xfaY\xe1p\x0c\xcb\x0c7\"\xdc\xb4L\nDDQE\xc9\xa4m3:\x89\xe9f4~l~\x00\x93o\xd3SEV\x1e'*\xb2\xea\x95\x8eY\x06B\x87\xd6\x81J8Nu\xfd\x95S\xc3\xa2\x03\x92\xd4\xd7\x12E\x9cqW\x02\xe3\xf3I+1\xbe\x12\xcb&|o7\x1b\xd8\xc2r\x90\xf9\xf66<\x82\xa4\xdcl\x13F\x83\n\xad\x9c8\xc7b,\xf8\x80\xe7X\x84h3\xe1\xe65\x031\n`\xa2\xa3G\x93oT\xd6 \x9b\x1e\xeb\xdfi\x89\xecz:\x896J\xabM\x15\x9fy}\x1c\x96\xf7\x9a\xcfR\xb9V\x0f}\x88ZOK\x06\xaf\xed\xed\x0c\x1e+(\xdfv\x12;E\xbfC[\x04<\xbb.\xedj\x024P\xb5N\xa1\xe0\xaa1 \x96\xd4\xe2Q\x0c\xb0'\x01\xaf\xa3\x13\x88'Oe\x92\\\xf4\xc6P5\x95]\x14\x04U\xac5\x1d\x98\xbf\xbb\x1e\x98v\xb2}M<\xb0\x99\x8c%.{\x84x\x16\x97\xf73\x11da\xa3S\xed\x88n\xe1\xb4'\xad\xa4\x8a\xa7\xe4\xc6\xd3\xb2\xceuO\xfc\x92je\x0d\xb6;\xb3\xb3\xdd~\x00\x9a@\xcbk\xe2\xb9\xbf}Y\x92\xd4e]\xba0\xf7\xdf~\xdet X\xb8\xc9q\x914\x89\xda\xe55MZ(R$\xb3\x0e\x86\x82V\xf8U\xd6\x1f)CT\xa3\x0cQ\xc0\x8f\xb0\xa8\x8d.\xb4\xcb\x0d\x8b\xd2\xeaa\x7f\x99q\xa2\x0b\xac\xe47\xc3\xbfX\x07\x9c\xcb\xcb*x;\x13\xf1L\x16\xf6\x1e\xce\xe7\xd1\x82\x80\xd1)\x0fTu\x00\xda\xae\xd4\x99'\xd8G'\x9a\xe7&$\xfcz-\x86\x8fo\xb6\x04X\xf0\x17\xe9\x94\xa1\xce\x91\x18@1\x1b\xeae-\xb4\xe7LT\x0d1oeve:\xca\x16\xb5(\x10@\xe1\x9e\xb7\xd0\xf3j\x02\x8f\xb0`\xcdM\xc8=\xac\xda\x87e\xf2'\x18\xa8\x0d\xfb2M7R\x84X\x94\x03HPR\xf4\x0bIbk\x17\x8bs\x9a\xf1\xca\xac*g\x0b\xcb\xben\x96P\xfa3L\x19\xa9Y\\\x03\xb1\x8a\xa3\x96B\xe7\xd7F\xa5\x04[\x958))\xa8\x93\xc9\x04\xe4\xb9%R\xcdw2\xcfN\\\xe9\x0d\x88^RA\x01\n\xf7\xeb\xd1`\xcc$T\xd4\x10z\xa1\x8c\xa7@\xecb\xc7h\xeeM\xca#3.\x08G\x1a\xf0\xf3s\xd2N\x16\xd9\x15r\xe7\xdcD\x94F\x9b4\x96\xd7\xda\x82\xf0\x8eJ\x90\xac\xa3g\x97\x19i\xdb(`\xdb\xaa]#C\xdb\x81\xa2\xba\x99\x99~\xb1RT\xee\x91\x89\xd1\xaa:\xf9E\x12\xdc\xd0\x986:2SK\xbe'\xa5v\xa3\xe2 HZ\x8a8 \xb8\x8fR\x1cy\xc4K/\x1e\x00\xffP\xb8\x97\x11\xa3\xfb`\x91e\xdaxD$\xfd,I\xa9\x9b4+>!\x1e\x1d\xdd\x1e\x07\x10\x8fn\x8f\x11\xcb\xe9ho\x0c;\x10\x8f\xf64\x19\x82\xfd\xb2 y-+\x83q\x97\x96;i\x08{\xcd6\xeb\x15\xfal\x0d1\xd0\x8f\x06\xba\x81q\xce\xf5\x85\xa8\xf1\xc1\xdd\xbao\xf0_?z5\x85\xa0 \xa7^Zq\x8a\xfb\xbb(x\xe5b7\xfa6\xed\x82,u\xe0\xdcRG\xe0\xcaK\x02\x99\xad\x0f;\x99\xe0w\x0fC\xd8K\x9fK\x86\xef\x96\x03\xff\xea\xfa6\x07\xf6\xbf\x03g\x88\xab\xd9*\x80\xa1n\x02\x973\xb9\"\xa0\x04\x16\xd8\x00\xc2\x13\x90\xf4\xb3dI\xae\xd2\x01C/K\xf3\xa2\xbe\xd4_\xc8H\xc9\xfc\x989\xe6\xc7\x14\xce\xbe\xa2\x1c\xc5U\xa1\x88\x03\xb4\xcd\xf2\xfa\x05\xe2\x1f[s!p\x13\x0b\xaf\xc9A\xfb\x93$\xceh\x9aOP\xb3\xecF\xdf\x7f28zGE6\x1b\x1e\x81\x84%F\xe8(6j\x0d\x810\x01\xc9\xcd\x818mI\x9c\xcc9\x88\x82\x04Zs\x8aq\x0bv\x14g4\x8c'$\x99)\x15\xcf-N\x11\x089D\x8f\xea\xa7\x95d\x9f\xa9gR=\x17MX9tv\xc5\xa8\x96j\xd7\xb2\xe6e(\xe5g\xb2\xce\x8c~\x89\xf2\xdar\xe3\xca\xd4\x8b\xa6k\x87\xb7\xd8E\xb4\x11\xaeN\x9d\xc8K\xcceJfQL~N\x93\x15I\xe9Zp\xbe\xee\xad\xb0\xeb\x94PE\xb4\xec2\x06y\xa9$\x88\x87Mvj\xe2\xb2\xdd F\xbd\xb2\xcax[\x8fo\xdduJk\x89\x98\x03\xe8=\x0d\xe38\xa1\xacuHb\x08c\x88\x8a\xf4\xbc)\x99$\xe9\xb4\xdf+H&\x8f\xb6\xb3\xb0\x98\xba\xab=s\x9b\xbc\x0c\xd1\x08\xf5\xeb\xb2\x7f\x12\xc5S\xaf\x8c\xbak\xff\xec\x12&!\x9d\xcc\x01\xc1f\x1f\xd0\xa5']\xd3\xe5\x11\x91\x0b\xfd\x04r\xfdq\x88\x81\xbcK\x93\xe5aL\xd35\xd7\x95*\xca\x9fv\\\xe9V(\x81\x0b\x7f\xc3F\x95\x04\x87\xfc\xda\xa4B\x14*\xdd\x1a\xcd\x08%!\x11KT\xfd\xc8\xbc\xacp\x00\x1f\x88p\xe5\xecPmA\x1e-D\xdd\xd9<\xef\x85F\xa2AHF\x99BH\x87\xf0\x9aT\xe1;\x9a\xca\xea\x06\x15\xa8\x17u\x0e4\xfb6\x00\xe2\xbd#\x01\xbc\xf0\x03xw\x05\n\xdc\x14\xfc\x90\x02\xeb0\xa1\xd2|-n\xa0\xb5\\\x1ao\x9b\x17M\xb36\x8c\xfa\x91\xf7\xe4K'\x9a\x81\x8d\xcb/\x9bt\xe1]\x15nN\xa1BgJEf=\xbe\xb1&>Jr\xb8\xa5K6X\x19\xa3L6\x80F\x0d\xe7i\xaa\xcd\x88yJ+\x8798\xfc\xd2o\x04\x89\xd6\x80\xc01\xb7\x15;T\xb2\xa8\x07\x02\xa3\x02\xcf+\x87M\x070\xa4W\x01C\\\x03\xc32\\i\xf0\x15\x04\x18\x1a\x85_\xde}\xdb\x19\x11XB\x94\x9a(Y\x1e\x13\xd5\xc9+\xe6<\x07\xc7e\xea\x11S\xcc\xd2%#P2\xdf\xf2?y7>\xcf\xd2S\xf4`T\x9d\x17\xcdG\x81\xc8\xd7\x1c\xc3>/\x06\xa4\xeb\xcao%\n\xdd\x8e&<\x1eT\xb0\xf8\x16\x08\xca\xe3I\x7f\\\xc4U\xddS\xc3\xa0aD\xdd:\xd8\x8c\x8b\xea\xa8\x90\x97\x96\xa1\xd8\xea}Q\x88 hP\xe1JCT4\xf3U\xc0\x82\xf8\xe8\x17V\x98Wt\xcba[\x8a\xf2$!\xde\x1b\x12\xc0\x0d?\x807\xeaR\xe9\x02\x01\x1d\x89x\x11\x0d\xd8\xa4\xe4o\xbems\xb5R\x1a\xf3\xfah7\x9d3o\x86;\x0cA\xee\xca\x92ig\xea\x86\xf7\xdf\x84\xb0\xd7\x82\xa1\xc4\x15C\x89\xc4P\"14\xe5\xa6\x10\x81\x97N5\xc3\x88\xf7\x8a\x04\xf0\xa3\x1f\xc0\xabo\xe7 ,\xc8\xf7\xeaZ\x90\xef\xcf\xc40\xe2\x8e_\xda\xc9\\\x1b~\xfd\x87\x91\xa8\xc4\x9f\x8e\x88\xf4Lp\xba\xcfT\xe8\x10!\xcc\xb4\xf1\x10\xcdu\x14,D\xbd\x9fg\xff\x95\x88\x84.1\xa6\x87\xec\xfa\x89x\xc6\"z\x8a\x93En}\xab@W,\xd1\x8f\xc2\x00:vr\xb1\xb5\xbc\xb9\xcbo\x1a\xa4Xv5\xf5rZD\xd7\x02\xfb\xbf\x06\xd1\x1d\"C\xdd\xf6\x02\x14\xe1\x95\x15\xb7p\x8b\xf3\xa4\\/\xd2\xe6e\x89\xde\x95\xb6\x11\x02G\x0e]\x18\xa0zI\xde%o}S\x0c\x1e\xf7r\x04\x07<\x91\x0bG\x89\x14Q\xa2\xbc9\xe07\x07\xcd|\xf9\xeaepYt\xa0 \x95s\xb8\x9a\x86\xe0\x9d\xf9\xd1+\xf3\xa3g\xe6G\x98\xa3\xcaK\xe3\x00N(\x13-b\xe5\xcdoT\xb0\x86\xb1\xe0A\xb7\xa1g\xd4\xb0V:\xec||V4\xea\xec\xf3\xb7\xe7qi\xf2\xb1w\xe6\xa8L\xe0i\x9e\xe6Eut\x1b\x9aW7oep#\xaa\x89S\xae\xcc\x85\x89\xaf\x07\xe5\xdfRg\xa1\x89\xd9\xac\xcf\xc4I\xf9[J&Z\x95\x15\xef\xff\xe6Me\x00\x15}\xae~\xb2R\x99\xa0\xda\x06\xcc\xd3\xec\x1f\x93\xe5\x8a\xaeQL.~\x0c!\x8f\x85\xa8\xfd\x1bm\xa6<\xadM\xd5Qc\xdc\\\xb4\xd2J\xcd-\xd4\x7fS\xacZy\xfc9N\xcec\xf8L\xd6\xd0\xfb\x1bl\x03\x85m\xf8[\x0f\x92\x18\xd8/\x89\xc7\x06#y\x05z[%\xf8D1\xfd\xb2\x16\x87\x16)\x1c\xf4\x86\x15cBu\x892\xa9\xd7j\xc1\xadJY\x08e4%\xce\xc1~\xb9\x0e\xcd:\xcc\x955pT\xae\x1b7\x8ey\xa6\xc48\xfb({\x8f\x9a\xf8I\xdcT\x01\xcd\xe2\x00\x16\x0c\xc7z\x7f\xff\xfb\xf1\xf1\xd1\xeb\xd7\x1f?<\xf9\xe1\xd5\xe1\xf1\xfb\xc3\x0f\xc7\xc7\x7f\xff{\xaf\xe9\x08\xb2bog\x0eJ\xa3y;\"\x18\xaa5\x91z\xb5& \x05Y([j\x88\x91\xcd\xe5\x87\xa6\xf4\x8eg\xa0^\xae\xe8\x9a\x87O\x17`tSDL\xdb\xf7bU\xc9\xb5\xb2\x04a\x94\xd9\xeck\xe5\xebb9-\xca\xb3z\x97kJ\\\x93p\x9fY\xe9\xd2\x0c\xf3\x0ex36\xdei\xec\xe9L5\x86v\xd7\xdf\xa0\xd2:\xe7*\xad\xd3\xb8\xd4d\x9d\xff\xbfM\x93uj\x87_\xa1\xee\xd3\x14XT\x7f\xad\xe2\xd1\"\x96\x0et+E\xa9\xb5*\x95Z\xab\xaa\x82I\xfe\xac>\x10\xac\xc1*VuV+\x17\x85\xcf\xca\xa6\xf0Y\xb5)|V\xb1\xdc\x870\x84\xb3X\xdc`[\x11Q2\x00\xe2\xadcF\x9c\xfc\x00\xd6\xd7\xa7\x11Z\xff)\x1a\xa1\xf5uj\x84\x84\xff\xbdM1\xb4\x8eK?}N\xb9O5\x94{\x19\x07p\xcc\xf6\xc9\xda\x81\x16\x9ft%l\xc7\xff!\xc2vn\x85\xe6\x92\x13\xb6%\x1b\xefI\xec=u/\xbby\xf1\x0d\x84\xed3'l\xef\x15\xc2\xc6n\xf5\xf38\x9bG3\xfad\xb1p\x8d\xe6\x7f\xef\xac\xe8~bWt\x1f\xc7\xa5\x83\xed\xb1\xba\xd7\xcecqC\xec\xb5\x13\xdck\x17q\x00\xe7\xd4\x0f\xe0\xe2\xfa\xf6\xda\xc5u\xee\x8a\xf74\x9c|\x86\x11\xdb\x10\xe3\xe6\x86\xb8\xb8\x82+H\xd5\x18?'\xe1\xb4\x89\xcf\xa8\xb7\xa2JRn\xea?\xe4\x89\xd7\xe9\xce\xceC\x1f\xbf\xe7^U\xe6\xbd\x00\x07 \x92\xd0\xe8\xe2\xfe*#_\x11\xf2\xb9\x13\x80\xd8\xa8K\xc3!\xfb\xa5\xc9\xde\xd1\xe8%\xcf\xe6m\xbd(9\xbe\xe5\xfa\xbai\x1d\nM_\xe1L\x82\xbb\x7f\xbb\xd1N\xa00\xc0l\xe0\x01\x02\xb3\xfe\x16\xec\xc0\x80A\xfc1W\x1b\xee\xec\xf8\xf8\x99\x89/\xc0\xcc*E\x1b\xa3\xd8\x90\xfb\x90-X}-\xd8\xa5I\xb4\\\xc5GC0e\xc1i\xe3z(\xf1V\x8d\x8a\xa1\xfcn\xad\xfc\xb9p\xed\xff#\xd6\x8b'\x8d\xc5{\xc2H\x91\x83`\"\xd4\xc9\x98\x1f\xda\xa3\xbe\xcf9\"\xfb\xfa\x959HZ\xa4\x16d\xc0\xf5\xd0m\xd9T\x05o_\x84\x07u\xe0\xd0\x08\xcf\x92gB\x01(\xd1\xc0P\xf5\x18\x8a\xf5o\xa6\xce\x87\x06\x19\xc5;E`\xaci\xfdIm\xfd\xe3\xab\xae\x7f\xd3\xfd\xba\xb1\xfeIke*\x15e\xb3E4!\xde\xc0\xde\xa68\xa6\xba\xb4\xcb\xd0\xd0Q\x1d\xa5\xeb\xca\x05\x83\xeb\xdd\xe9N\xd1Z\xeb\xdd\xa7\x91\xac\xae2\x8b.V\xa6o\x8d\xcf\x16(U\xc3\xa0.x\xc5X\x11;\xd8\x18\x92\xb8\x1c\x99\x8c\xa8|\x16\x8e\x1e\xc5`]\\\xc1b,.\xa2V\xe95h\xb8_{\x95\xa6\xab\x16\xaa\xa2\xa3sZ\x1f}\x99\xa6\xc7\x18\xe3W\x9cLi\xe5d\xc22gQ\x95d\xb1\x83\xe6\xa1\x8fw#\xfb\xe9n_\xc4\xb4\xb6\x88\xd1\x95\xd6\xef\x8fXWa\xba\xb6\x86\xdd\xd4V\x85.\xa9\xa9\xb9R\x10\x14\x0e\xf0L*\xa8\xbd2\x99\x8ea\xc8\xea\xcc\x06\x06=\xd4\xc5\x95\xb5\xa0\"\xee@]\x92\xf2hQ<\xbflH\x11\xf3=\x97\xd6\x10!\xad$\x13Le0H\xac$\x13\xc4o\xd2\x16&\xd0i\xb2n:R\xa7\xd9&z\x1db9S\xed\xd9\x97\xba\x9d\xdc\x8e\x91 \xad^\xff\x92\x9fH\xdb\xe2\x07D\xbf%\xa0\x03\xee\xd9\x8f\xcb`\xb2\xfa\xeag\xc8[je\x1e\xda\xb2\xf3Y3\xf3\xb9D\x05\\\xa0\xd6\x15\x85\x9a!\xbc\xd7H\xef\x87q\x00Otz\xd7\x0fO\x9e\xbe4h^\xdf\xb2\xf7/\x1c\xa4\xfd?\nw\xbd\x96\xfc\xa15\x8f=kF\x99\x92\x19\x8eTN8\xaa;\xeaE%\xfdK\xf9\xaf*upK\x19\xf8\xd9z\xea\x1er=\xc0!\x03\xc8\x1f\xb1\xd7pO14z\xd4..\x16ho4K*\x87\xd3\x08ut\xec\x9f&J\x18!\xa9\xa6\xef\"%o\x1c\xfb\x01\x94.\x93Jh\xc4\xfb\xf5\xf2$Y`\x85\x04\xdb\xf3z[\xb4\x06\x11\xf5\xd7\xdbx\xf4\xa4P/\xbeu\xd1\x06\xbe\xb5i\x03\xdf\xb6i\x03Y\x17\xaam\xed\x8b\x9aE%\x80\xb8\x7fT\x12\xc8\xaf\x01[\xa6X\x97\xfeK\xa4\xc4vH\xf3\xf5\x8cz6V\x04\xc4\x82S\x91\x1b\x97g\xda.\x8f\xf6\xcdFk\xa3\x87\x1acP\xe6{0\x98\xde\xac\xa6m*\xb0GOc\x1a+\x88w\x9b4\x81&G\xf1\x94\\\x90\xe9{\xf2\xc5\x010\n\x89\x7f#\xa2\xce\xddz\xf9\xe9\xbd{\xeb\x08\x1cm*l\x17\xcd\"W\x87pa\x84p\xefn\x1d{!\xa7,\xd2\x94]\xd2I!\x17;\xf6\xde\xa9\xdb\xec:\xbb\xed\xbcI^u\"\xa6\x9d\x9a\xcf\xaa\xb3R >\xce,\xac?/WY\xaa!\xe4\x9c\\ \x052\xae\xee#\xbc\xb86\xd0\xbf\x8a\xb2\x0eK\xbe\"\xd7\xd5/7C\xb8\xf7\xdc\x1b!\xc7r\xb2 \xe3\x9eK\x0f\xa5\xa9\xc3\xb1\xfc\x85Y\xbb\x04\xdb&\xc6\xf2\xba\x9f\xbe\xf2\x12\xc3\xcc\xb91\x8f\x97\xd9e\x94?\xc5\xb0\xc7}\xce\x14\xc2\x01\xe4\x98\x92|\x1fB\xea!\x7f\xd8\x8f2\xc1'J#\xe0\x88\x8e\xb5\x94[\xbd.}wOo\xf5*\x10\xc0\xe2\xf5\xad^\xa6\x8a\x1dP1\x16D\x0d+\x8f\xfd\xabA\xed+\xfb\xb8\xcfD%\x84h\xb4\xebP\xe79)\xed\xad\xb8\x08\xa1\x97\xa0\xc7\xae\x0c\xc4\xcd<\xa5\xd0j\xb3\xde\x96\xbc\xcc\xd9W\xcfD\x95(Q\xfdBW\xd7X^\x92\x92ci\xe9!L\xeaT\x14\xc7\xc4$N\xf9T\xd2S?\x90\xf7f\x8b\x90R\x12{[\xbb\xc2\x12\x83\xdaEM\xd1\x13\xebV\x00\x01\x1c%\xcd\xa8\x13\xba\xc8-\xc4\xfd\xa0\xec\xc0\x87f\x1fJ\x85X\xd86XN\xe4e\x06\xf8%\xaf\x8d\xd6,g\x8b\x0f\xa5\xfaV\xe3\x0e\xed\xc6\x8eH\x8f^\x97\xb4\xc9*\xbbV\xf5 v\x897\x98\xda\x12#k\x0b!4n\x91\x98\xa6Qe\xac.CU\xf4{\xef\xdc\xba9#\xe9\xda\xf1Lq\xe4\x82cK*\xf2\x16.8\x0d\xc0V\xf2\x13\x8a@s\x8e\x03\xbc\xd6\x11~\xa1\x14Z\xe3Z\xa2\xad\x81\x01\xf8uG\x12\xd0\x03\x86\x13]G\xc8\xd4O\xae\x1f\xd4|\x82\x9a\xf0'0\xf5\x19Ok=\xbaT\x8db\xc0d\x9fbNT\xcf`\xde\x00UOz\x80 M\xf4\xe5\xc15\xc3\xe2Z\xa1n\xb0\xa8 KP_q\xeei\x89y\xbb\x89\xaf/S\xa3\x19\x08\xe3@\\6o\xbd\xef\xc2\x92\xc2\xe9!\x1c@\x0f\x19\x1f\xd8\x87^\xd03c2#\xc1=\x8d\x1eU^\xdf\x82\xe96\x1c\x8fE\xa9\xfe\xad\x01\xba\xacn\xa3\xd2\x14\xffE7\xa3-YBJ\x99\x14\xaei\xe1E\x83gN\xaf\xc9Y\x82\xd8\x01N|\xdbg\xb2\xfe\x06\xf2\xf3\xd4iE\x97\x159\xd4\x01\xad\x8a-VM\xd9\xe9\xd4\x19?K;n\xb0\x00\"\xeb\x02\xd7p\xad\xe1\xa0\xf2\x08\xf60?\"\xc3\x14\xd8\xe7\xf9\x90\x1a\xdbAU\x03`\xcdZ\x1b\x01\x84\x03\xf0\"A\xe5\xb09_\xb4K\x8b\xd2\xb7\xbcb`b-\xc8\x9c\xba\x83\xec]t:\xa7\x1d\xe1& \x93\xca\x08\x95\x86(;}\x12\\\x8f0\xbd\xa7F\xbb;\x98\x06\x8d\xbd\xb8\xe3n\x81Tj2\\\xa7\xae\xd0\xb8|E\x0c\xfer\xb5C\x82q#\xddz\xe4yYx\xac\xdc\xbb\x18K\x85\xe9\xb2`\xe8\xbaJ\x9djL\xd4gf\x0c\xc8\x01}?(u\x7f\x03\xad\xf9\xd9\xa9\x97\x93\x9c\xbe\n\xbb\xa8\x07\xf8\xbeF\x0f\x99\xdd\x00v\x06N\xbdD\xd9\xe1rE]l\x0c\xa2\x17\xf5dR\xe4\xf4\xba\xe4\xbe/\x96\xb1\xca\x8c:\xf0\xa2&#\xa4\xd3l&I\x1e\xd7w~\xcb|\x9ex\xb4T%\xf1m/\x04X\xfeq\x07\xbd\n\xf6\xfe\x83+{*\xfaw\xa5R\xa0P\xaa\xaf\xd4\xf3K\x83\x94-\x03\x9eD\x0d\x1d\xf1nc]\xf1{\x917\xc1+\xeb\x94\xf3J\xe2lW\xaa9\x8f\x9d\xa46E\xe6\xd2\xb3\xbb\xf2\xb2\x94R\xc1\xb3@5\xb7\x19*\xe4]\xaa\xe7\xad\xcb\xea\x91/y\xb8\xe8\"l\x9d\xd1\x82l8\xb5/\xb2f:l5\xd5\xe1T\xbf\xb6\x18\xa8\xd5?\xc6ty\x95\xe2L\x94\x96\xf7\xed\x9cb\xb5z\xeb\xcf\xb1_S\xb5Z\xcf$\x0e\xc6A\x0b\x1d3\xc3@\xa2\xa0\x1b\x05\x8e\xaa\x94\xb7\xd5\xfc\xa4P\xb0\x00\x12OG\"\xe5e\x18\x7fgQc\x1ev\x913\x90\x0e\x89\x84\xcbK\x1eC\xb0t\xec\xe5\xa8\x0b\x0d\x97\xfdp\xaf\xd1.=E\xd9\xfb\xfc\xc4\xb1\xc0g!\x03\x0eM>aE\xa5\x14nu\xe6<\xba\xa2\x13r[\xda\xe2<.\x12\xe3t\xc8\xa7\xa5\x9f\xe2\x8a\xf1B]&\xe9\xd9f)`\xa6\xcc\xd2/n\xba\x9fj\x9f\xc9\xfa\xed\xac\xc3\x90\x8aC\x8d1s\x9d y\x0dFB\x1eq\xee~\xc4W\xb42lW?mH\xa9.\xdd.\xba\xab\xd1\x1a%\xbf\xfa\xc8\xcf\xba\xf7\xf7\xf2*\xebb\xe0\xbdq\x8d\xb5\xb9\xac\x9a}/\xc3\x8b\x0e\xbd\xbe$\x9dT\x18\xcb\xf0\xa2\xeb\x99\xfa\xb2\x92\x8f\xc8\xa9\x137\xa3Yc\x06p\x00ob\xee\xc2\xf2\xd5MPZF\xf1\xd5\xa7\xc3\xbb#\xbc;\xd7\xb9\xa5\xa43&jC\x1eA\xdf|\xf69Zu\x80\x9d\xd2\xfe\xeb\x90\xce\xfb\xcb\xf0\xc23T$6tV\x17\xbe]\xa5\x04\xc3\x1ecMzT\xb9\xe3<\x90_\xe7\xd1\xa2\xa3\x99\xa1\x18\xcc\xefW4l|\x8eV\x1fc\x1a-\xbau\xcb\x81.\x87\xdcM\x05\xc5\x13\x82u\xeb\xafi\xe5\xd0d\x06\x03}\x7f4\xfcL:,/\xad\x18 \xae\x80R\xac\xbfkF)\xd6dw\x94b_}\x0bJ]E\x92\xf8\x87\x13w\xab\x940\xfa\x18\xa3\x9a\xb7\x92\xbc\x0d#+[\x18^\xc9NS\xa3vY^L\xa4\x8b\xaa\xb1yJ\x81\x96J\x18\x08vlo\xedL\xd4\xf3o)\xfb_0n\x1a\xc1\x87\xa2J$l\x9b\xa1\xd2L)\xfd\x14\xdf\xde\xbc \xdb\xdb9\n\xa9\xa2AC\xa1ry]\xfa\x01\xe4\xc67.\x03P\xcb \xfd\x17\xadJ\x92vY\x16Z\xf1\xc6b\xdf\xd9\xe5Zv\x85\x16\x8f\x12y\x89q:FY\xaa\x17\xfaN\x85\xc5L\xdb?\x00\xf7\x88G\xf5\xb2F?\xaa\x97!VB\xbd\xa4\xe9&o-N%/\xae\xc3\xaf\x14\xa9\xb2x\xa9\xcaKF4R\x11\xc3\xdb\xfa\x01\xbb2\xe1\xac\xea\xf6\xf6\x04\xdf\x1e\xb4\xb8\xb6\x82n\xafM\x02\xc8P\xe3y\xc0H\xdbp\x08\xef\x84\x98\xf3\x9cad\x86/\xf04\x7f\xa1\xf0\x0c\xf9/X\xdc6\"`\xa5\x00\xda\x87\xdd5\xaf\xec\xe0\xb9*SQ\x1cZ\xdd\x98\n\x19C\xd0\x91/\xed.\x86\xcd\xc3l\xfe4\x99vpt\xa1\xf32\xbb\x00\xd6e\x9a\xab\xd9\x06\xday\x04(\xb6\x17wP\x1e\x0ea\x00\xb7`\xb7\xd8h\x16\xd2%\xcd\xa4\xb3V\x05\x9f\x9b+\x7f*\x8a\xdf\x0e\xf4Uo\x8b\xd7\xf8\xc0\x9c\x16\xbf\xf6\x0d\x1b\xed{\x14\xd2o\xdf\xb9\xbd\xf7`p\xff\xf6\xdd\xdb~P\xdc\x86G\x8f`p\x176@\xe0\xf1\xe3\xc7\xb03\xb8\x1b\xc0\x9d{\x83\xfbw\xee>\xd8\xfd\xbe\xfe\xdem\xe5\xbd\xdb\x01\xdc-\x9fc:w\x8f\xc06\xdc\xbe\x7f\xef\xce\xde\x83\xbd\xc1\x83{\xb0a0\xfd\x17\xdb\xd2\xff\x12\x9f\x0d\xee\x05\xb0\xb7w\xe7\xde\xfd\xbd\xbd\xbbE\xf3\x87\xe2s\xec\xa6x\xf3v\x00\xb7\xf7\xee\xdd\xbbs\xff\xc1\x83\xdd\x07\xbe\xda\x84e\xcby*\x7f\x10c\xad\xcb\x83\x8eP\x83!\xdc\x1e\xc0w\x90\xc26<\x8f\xbd'\x147\xcd\x13\xea\x11\xdfg32w\x0e\x8e\xbbS^\\+~\x85^\xaa\x93r\xe9\xa6\x98\x11v\xd4\xdaA\xb7\xc6\x1d\xdb\xf5\xb5\xe5\xac\xa1 \x88:RX\xb9SW\x06\xb3\xbd\xf8\x9a''Sr\x01\xa8o\xbc\x8eG\x0b\x19\xe0\xfd:\x1e=c\x7f\xbf\x16&\x8b\x8c\xdd\x12\xa1\xa3\xfc\xb6\x08\xac.\xee\xab\x81C0\x84W1>\x89\xe2l\xc5s\xe3\xe3'\xef\x93<\xad\xe6\x95\xd1\x81\xac\xa6D\x12\xee\xad\xd5\xd9a\xeb\x93y\x18\xc5\xbcma\xcb\xe4\xb7\x93\x98\x86\x11F\xa5\xe3\x10\xb8\xee\x12c\xc4S\xdd)9[D\x1dB#\x0b\x01\xe5+1\xae\x84N\xed\xb3:l\xb8\xf7\xbbZ\xff\xcdT15\xcb\x02V\xe1\xae\x93a\xb5\x90&\xa4\x93\xc4( \x1a\x9b\x8bO\x03p\xa3\xaab\x93t\x14\x1a\x97\xe1\xeae\xd5\x07\xd9\x15FW\x00\x02[\xf7:,\xda\xc4\x8c\x06,x4\x82\x05\x08\xd8\xc9Uv\xeb\x87\x18\x93\x9b\xb4f\xeexj\x06\x92<\xd5\xaa}\x19\xda\xf9\xb9\xb5\x9d\x11 \x80\x8e\x9d\x1a{g \x87\xf5\xb3\xb9e\xb3mQ\x97d\\\xd0\x84\xa7aXo\xaegX;\xd7<\xacW\xf6a\xf52\xa4\x81\x15\xe3\x07\x1c\xc0O\xef\xdf\xbe\xe9\xf3G\xd1l\xcd\xd5\xb6\x82Z:\xe6\x16}f%\xc0\x87\xc6L\x9e\x86\xe6\xbe\xb6b\x10\x85G\x05\x07G\xe11\xfe\xbd\x83\xec\x9cS\x07\xcf\x1d:`\xac\xcf6\xec\xdd\xbb{\xe7\xce\xed\xbb\xdf\xdf{\x00\xdb\xe0Q\xc6\x90\xdd\xf3\xf9\x9f\x8f\x1f\xc3^\xf3\xf4\xad.\x94h\xedCT\xaf\xc2h`\x95\xcb\xe5\x95|\xb3\xad\xaeu@J\x1b\xdeV\x82\xa5\x00\xf8\xba\xf2\xd0R&\xa2G\xbe\xaf$-\xc5f\xc5}k\xcb\x97\xac\xf7\xc0\x96GC\x85\xa8\xdel\xe7\x0c\xd2\x80[\xee*1~\xd8\x7f\xeb\xe4\xdd\xed\xa1W\xb0\x9f\x15\x90\x8d\x18ds\xf8\x1f&;\xb0\xad\xc7p \xa9\xb8\x00c\xcc\xef>\x7f\x07\x0e\xe09\x9b{\xce\xd3\x91\xa2\xd5F\xfe\x8cd\xca\xd86\xf0[\xad%\x86T\xe5%\x95p\xde\xc6\x0b\x12\x9e\xb9p^\xd2,7b]\x8c5\x87\xb2oY,\xb6/op\x02 \xf5/\x01\xdc\xe8'3t\xa65~\xc6\xf3\x93(\xde\xf9\xd6s\x96\x14\x1b\xdf+\x88\x81\xb8\xc7\xe8\x80\xc8H\x13\x94\x94\xc8\xcd\xc7\xa9\xab\xcb\xdd\x92z\xbbj\xcaj\x97>\xae\xe0_\xc7\x0e|\xc7\x08\xd5\xebv\xefq<\xf9\xbf^I\xafzC\xfe\xf1,\x0el\xc8\xe6<\x86_#:w9\xa7\xa4\xcc\xa3\xf6b\xc77\xc6\xd3\xc9\x00\x81\xe6\xf8M&\xcb\xca\x9dK\x9fQ\x842=\xec\\\xea\x1b\xd4\x9bE\xdd\x96#t\\o\x0e\xbf3\x8f\x85\x18\xc4kA\x0b\xb3\xb2\x93\x9cv\xd5|:\x9a\xaa\xd3p=\x9b\x0d\x9b/s\xb89@;Q\xf2l\xf3\x12\xda\x15+\x81\xfaX\xb1$\xa8\xb7+&\x85\x17\x81\xaa\xa4\xf5\xf1\xde\x8d\xca\xf2\xf1{?V\x9a\xe6\xf7N\xa8\xe6\xe3s\xaa\xf9\xfa\x82\xd6?oBE\xe6\x97\xdb\x87\xb8 W\x04\xea\xcb\xe6\xfd\xa7\xc9bA\x10\xd2\xfbp\xac)\x90\x81\x01b_5\x0f\xd4\xb4\x92G\x1a\xe7 \x9e\x97o\xa5y\"R\x05^hGI\xf7!\xd3\xe5{\xbb\xbb\xd3O\x9f\xf2\xe9\xfd\xdd\xdd\x1d\xf6\xefl6\xfb\xf4)\xdf\xbd\xcd\x7f\xee\xde\xbe\xc7~\xce\xc8\x1e\xfe\x9c\x91\xbd\x19~3\xc5\x9f{\xbb3\xfet\x97\xf0\x7ffc\xd3\xe0\xcc\x14\xad\x100(\xc9\xa8J\xc7.\xbb\xc1i\xb0\xfb\xa0\xc6\xeb0.\xb2wx\xb1\"\x13J\xa6\x10\x16\xed\xf4\x14c\x8f\xbc\x07\x89\x96\xb0G3\xf0\x94\xf8\x88-\xc5D\xb0\xd9\xc8\xecA\x1cE\xb4\xaf\x11\x1f\xe8\x9e\x864<>\x16\xd9F\x9bX\xa9h\xf1\x84\x14[\x83\x0c\xbb&\x9a\x1aTQP\xb9]\x14\x82M\xaa\xf7yQ\xc4\xbcz\x933\xc4a\xf5f\x86ofUB4\xe9\xb6:\xb7\x1f\xe8\x97\xe7\xce\x83\x96\xe3\x18\xa8\xc8\xcb\xc1Co\x1b\x8e\xeb\xca\xe6\x15\xc6\x0eOT\xe6\x04R\x9c\x80\xf2\xd1V\xc4\xb8\xab\x9b7\xd9\x1f\xb1\x8fJay8\xc6\xec\xaf\x98\x1dA\x95\xfe(\xeb\xf2\xca'\xfe\xed\x07\xb7\xb5\xb3\x1e|_G>\x81\x94\x0f\xeei\x90r\xd0\xc4\xc7\xbd6\xd2!k\xb9pG\xe1\x99\x0e\x15\x17\x98\xb5\xf8&\xe4\xcd\x03\x17\x0b\xb2\xca\xb2\x8c\x8d\xa7s\xc4H\x9dY\x8a\x11\xa8\x15\x03\xe4\x1c\x81\xec-\xd8?sx\x0c+;]F\x9d!\x0f\xd0\xf5\x9b-bAK\xfeX\xa9-6\xc5%n\xb6u\x06C\xd8\x194G\xbd\xe62t\xe3\xfe\xa9\x00C\x08\x07|'\x82\xf4\x8e\xae\xb6\x8dy\x01fx\xfc#\xa9\x0f\x80\xff \xbc\x06\xe8\xf6\xf6\x19<\x82\x956\x11\x00\x1b\xd6\x92\x81ttf\xe0n\x8e\xb1(\xcc\x99\xc6Q\x9c\x01 \xf3\xb1\x89\x13\x18\xc2\x02\x0e \xf3\x8e\x03X\x06p\xc6\x03\x91py\xf7!\xf3\x96\x01\x1c\xe3]\xbe\xfa3\x0d?SK\xe2{b\x92\xae\xd9{'>0\x018\x8aM)\x0b\x10\xa2\x03\xfd\xb3\x93\x94\x84\x9f\x1bO\x9a\xe7\n\xeb\xe8\xd46\n\xb6e;\xd8\x0c\xf0\x93\xc4;\xc5\xd7n\xde\x04oY\xe6\x8c\x9e0\x08Q\xb9-f~\x89K\xa7<\x16\xdf\x18\xdel\xeb\xd1\x06\x050B\x02\xb4\xd0\xb8\x04\xb2\xc8\x08Nb\x89\x0bt\x8c\xfbh\"\x96\xb6\x18\xb8a8\xdf\xba \xda\x13y&N\x10t\xba-~0\xfc_\xff\x9f\xea\x876n\xc8H\xa5\xeas\xa9\xd4_\xdb\x11 /%\x11\xa7\x98&o\xbf\xa0Ml\xdb\xc5\xf0\x08\xd2\x87\xcd\x95C\xd3\xb8GG\xf1\x18\x01\xa7r\x86\xbbZ\xfeOI\xef\xd4\x91\xcc\xdf\x19\xd4y\x83\xe2pkRyQ\x91\xa98^\x9b\xf4\x1e%\x19\xa5\\S\x93\xfc\xa3*\x08\x9f\x1de\x87q\xbe\xe4\x8a\x9f&{\x92\xda\xad\x1db\xe2\x85\xb8VE\x06\xcf\xf7\x85 \xde\xae\xec\x13\xad0\xe6\x9bak.X\xcc\x00z\xec\x0fBz\xfc\xc4\x0d\x9b\xf7\xab\xfd\xe9\x8f\xb4\xcce),\x99\xf2\x15\x06Qch\x10\xeb4\x18h\x9e%m*\x97-\xd2\x8f\x93)aB3\xdek6\x81\xab\x89\xa2w\xb3\x1d\xca\x8d\xd4\xac\x1dZiG\xa3sbk\x9es\xe0\x16\x90A\xc1\xe4\x00\xd2\xfe\x0f\xf9lF\xcaS\xab\xf95\x03\xa3\xc7\x8e\xb7\xb0\x1fe\xb5\xb7Q\x8a\x8d\xccJ\"E\xe2\xa9(\x89\xee\x0f\xfc\xc2X\xdc}\xdf\x1b\x988\xda?''\xabp\xf2\xf9\xe7d\xb1\x9eE\x8b\x05\x0fY\xe9O\xc9*%\x93Z\xedG&O0\x96t\x15\xd29k}4\xc6L\xf1\xf3h1MI,\xbe,~\xb2\xe7e\xb9\xb4)\x99E1\x91\xfb\x0bqr\x91\x84S2\xed\xe9\x14\xab\xa4\xd8a\xfbz\x0e\xa2K\xd1\x19\xda_4\x1e7\x95\xd4\xe6qF\x7f\xc9\x18#\x8716Wk\x08\x83J\x02\x9b\xced\xd4 #\x0c\xea\\t\"\xee\xdf\xd1p\xcb\xb8\xdf\x92~\x94\xb1\xfd4\xe5Q\n\x95\x97\xf8f:\x80\xc8\xcbQ\xe5\xa4\xa7;a\xb7\xb1\xdf\xdd\xbd\xaaZ\x91\xf2\x83\x8d\xd1\x81\xb4]\xb9\xd8\xbe\xb74g\xaa<\xc9\xe5;Z\x87\x17\xa9!\x10\xfa\x05\x91E\x90\x8e\x85;_\xcd\xdf\x84p\x8f\x92H\x16'\xf4\xe2\x9a\xa9\xeb\xf2\xaaX0\xb8_\x97\x818\x16|\x7f\xbf\x15\xc2m\xec\xc4.\xf72\xf0\xb8\x1a\x88\x07\xf1\x17\x9cD\xa1X\xe1\xd2\xe0#H\x1e\xfa<\x85\xe8(\xf2\xc8(\xde\xde\x1e\xfbc\xbdv\x8f\x7f!\x082-h\xebU!\xa0\xd7\xd9\x0d\x1a\xd8.v\xc1^\xfd`\xe3\x8a\x8c;\xdf_\x05^bJii\x18\x8c\xc4{\x07\xc0\x90a\x1f\x12/\xaf\xb8 9M\xae\x97g\x042\x9aF\x13\xaa\xa8\xf6*^X\x0d?\x11\xe9j\x13{\xdf?\xa8\xebF\x94\xe9\x1c7E@&\xbas\x98\xdd\xfb\xbe\xf6\xe5q\xff\x1d \xa7\x8cN\xbe\xa7\xfc@YV_`\x80\xbe\xeb\xf7\x0f\xcfHL\x0f\x97\x11\xa5$mv\x10\xb6\x81Q^%\xd1\x8f2Jb\x92b\xd1M\x8er\x8d\x0ft\x96{\xb1%\xea(\x01\"\xb88\xf6\xee\xef\xfa\x82\x03h\xbe1CA\xfdc\x14\xd3\xfbH\x07\xd9\x9e\xad\x9c\x9f\xcd\x99-85\x1b\xd4\xc0\xb6\xe8G\xf1\x9c\xa4\x11\x15J\xaf\xbb\x1a\xf3\xc0\x8a\xa3\xdd\xdd:\xb1\x06\xa12\xd0 \xd5\xec\xfe\x8am\x9fU\x7fJN\xf2\xd3Er\n\x07\xca\x0f\xaf\x97\xd1\x94\x84\xcb\x9e\x0f\xfbmC\x9f\x06(\xfb\xb3!\xd4w\n\x08\xe1\x88\x81\xb2\x8eK\xe5\xd4\x98X]7\xf9\xb3\x86O\x19\xf7\xd0#i\x9a\xa4=\xc6\xbd.\x92\x8c\xb0?\xa6$\xa3i\xb2f\x7f\xae\xc2\x9c\xdfKI\x96/Iol\x8a\xd6Y\x1a\xd1%\x01\xa1i\x8e\xbd\xbd\x81\xa8a\x81b\xab\xae\xbe\xa0$\x16\x04\xa28\xa3a\x94w\x86\xe5S\xdf\x0f \x13j\x85F\xb6?\x13 OJ\xe5\xb8)\xdaS\xe1!h\x0d\"M\xb0 \xdd\x147i{ym\x8f9q \xa8\xaa\xe2{X\xae\x93^\x89\xc7_\x14xfSJ\x9e\x15\xc5\xdd\xc4\xcb\xacu[*\x15\xce\xc3J\xaa\xc4\xa0N\x04\xdd\xe2\xaa\xd1\xd8\x0f\n\x9d?l\xb3\x86\xab\xd4\x17\xf6\x8b\xaf\x0dJT\xed]RR\xae\xdd\x00\x0e\xb5\x86I\x06\xba\x1c\xeb,zH\xb3\x11\xdf\x9d\xe0\x8aP\xd0\xcf9\xe5Uy&\x85F\xc4KQ\x15\x92\xaa\xdbf\x86\x94\xa6\x19}I\x94\xb8\x83a!\x0c\xd5NK\xcc\x12\\u\xaa\xe8\x1d\xc5g\xe1\"\x9aB\x9c\xc4;\xbc\xd9[\xe2p\x98\xcc\xf3\xf8s\xcf\xb7\xc5\xd3\x18&\"\xb6\xb5\x06n9: \x06\\*A\x02\xee\x15\\L\xc2\xe0\x99\xd7\x86,\x1c\x89\xc4*?\xc6\xc8\x1f\xcf4\xff\xfa\xc7e\xa5\xf9\x9f\xa5j\xf3\xed\xcc#<]\xb1bND\xd8\x10\xa7\xe4#bn\x13\x0c%\xd7\xe3\x06N0e\xa7\xb4z\xe45\xe7\xcb\x16B,\x02\xe7(\xfby\x9c\xcd\xa3\x19\xf5|\x08g\x94\xa4@\xe2)\x10\xc6\xf5\xf7\x10\xd7\xce\x11\xedd:;\x04\x16GU\x97\xb6q\xcb\xc8\x86\x0f\xdf>\xe7M6\x88C^\x1c\x19L\xfa\x8f\x19\xb4 &>\x92\x9b\xf6<\x8d\x84\xae\xbd\x0em!\x85\xcb\xb5:\xa8\x8cw\xc0z{[\xee\x9b\xea3\x9fW\x8fb\xcbP\x1d\x90\x0e\xfb\xea\xaa\x83\xb6\xb5\xda\xa2\x02LH\xb8\xab\xdc\x04n\x92\xa2HV\x8d9,\x99.j\xa4#\x97^\xeeF\xe3\xcf\x15\x1a\xaf\x1b0)\xb8\xa8\x9b7\xe5\x1eVh\xdf\x16\xe1l\xd1\x01\x9b\x02_\xebiHC\xb6\xd4\xa8\xf7b@\xf3v\xf9\x9a:\x12E\x8e\xa4\x05M\x95\xc8\x17\xb36t\x94\xb6\x02\xb8\xff?{\xff\xbe\xdc6\x924\n\xe2\xff\x7fO\x91\xc2o\xc6\x03|\x84h\x92\xba\xd8\xa6M\xeb\x93e\xb9\xc7\xd3\xed\xcbH\xb6\xbb{\xd8\xfa\xa9!\xb2H\xa2\x05\x02l\\(\xab\xc7:\xd1gw\xcf^#\xf6\x01\xf6\x9f=o\xb0O\xb0\xb1\x11\xe7MN\xef\x03\xec+lTV\x15P(T\x01\xa0,\xf7\xec9\xdf\x87\x88nS\xa8B]\xb2\xb2\xb22\xb3\xf2r\xef\x1e\x92F\xc7e\x8bJL\x9a\x16\xfa\xe85\x87\xe7\xd2}C.\xb8\x18\xd4\x9d\x1b\xa9\nU\x17$\x85\x7f\xb8wO\xf7\xba\xe0\xfc\xaaK\xac\x91\x81\xdb\x05\x0c6to\xd7\xf6OO\xf86F\xc3\xe7%\x83\n\xc1\x88\\\x8b\xdf\xe5\n\xe7Y(\xd7\xc9\xffRj\x15u\x1a\x0f3&\x0d vdA@\x11D\xe3\x06.7N\xeb\xb6ix]\x8es\xdf\xc8\xec\x08\xf5P\x19\xd1C\x91\xebN\x1b\xa9\x80.\x02\xd25f\xf1\xa6r\xf3,Hv\\f\xb8\xa9\xc0#\xc8>\xbbl'\x98\x99\xd1qyg\x8eK\x19\xb9\x92SB\xc5\x9fC\x81 \xdfs\x8d'\x0f\x9f\xa3\xd4<\x93 (\x87\xa2z\xc4+]\xf8\xc9[/K\xca.P5]l\xf5\x8b\x94_\n\x86r\xfaT\xd7YBd)\xa9\xd5\x9c\xda\xc91\x95\xcd\xa2\x885\x86z\xb2p\xc3j\x94G_U\xac|\x84\x11<\xdcy\xf8p\xbf\xf7\xd0\xa4/95\xa2n\xae>\x7f2b\xfe\x8dU:N\xf2#\xbb\x87d\xb6B\x9dS\xa6\xf0=(\x1f\x08\xd2\xa9\x9a\x93\xe6\x05\xf1\xa6]z\x08\x88\xb2aQm\x88a%\x80(\x07\x1ac\xa2U\x8dA3!\xcb'\xf6t\x04\x1fQ K\xff\xa5\x9dloSY\xeb\x13\x1d2F\xf7*\xfd5(\xfd\xb5[\xfa\xeba\xf9\xbb}\x17\xd2NG\x9bk\xe0\x86\x9d3\x08U \x0e\xe8!\x92CS\x9e9\xa9h\x0cz\x98\x9f\xb9\xd59}\xac\x87Bn(\xd7H\x8f\xaa\xbd\xf7\xe9\xe9\xa9*+(\xd6/l\x8b\xbe\x16\xef,\xb7XtG\xf7\x0d\x9bI\xce \xb0|\x1f\xef\xfc\xc9\xa5}\xc8#/\x1eV\xdceM\xf3<\xd4\xcf\x93\x0f \xc4$-\xe4.\x18\xc3!\xbf{\xd56\xa0\xcb\x1b\xe3n!%}\x08\xb2\xe0\xaa\x86\x04\x9d\x8e\xf2I\xfe\xa4u`2u\xfc\x93\xb1\xe3\xd2\x05Ln5FY,\xc1z2\x86K\xda\x7f[\xa4\xe0!I\xc10\xea\xf6\xd7\xc2\xb6\x96\xde\xf5\x05\xa1\xab\x86\xf3@\xf5B\xcf\x92\xd94\x17m\xfb\x8a\xce\x9d\xc7Ny0\x0d\xc0\x1a\xa9\x89\xbfL@\xb84\xaer\xae/\xa1\xe0M\xfd\xc9\xa5n\x9c\xad\xfax\xd9\xbc\xc2\x02\xdb\x99\xe6M\xd7\x13\xe2\xbb^1G\xaa\xca\xb4\x1c!Q\xb3\xcd\xd1\xd1\x05u\xc9\xa4\xe5\xdclJ\xaf>\x97\x08 \x8a-l\x8b\x8e\xa7\xb4\xad\x1f\x97\x07\x99\xa7R\xe6\xe3s\x1e+\x02\x8fi\x84\xef\x9a\x0e!\xe5\xe89`]!u\xac0J\xf9\x91\"\xc4\xcf!l\xa5\xec6\xf5i\xa9\x0d\xbb\xa4\xc0\x91\x0f\xa3\x9f\"?\xb4-\xbc\x13\xe9\xf3\x9eyI\xcd\xc1%\x0b\x1a\xdc\x9f\x92\x14>\xb1EQ@\xbc\xd8F\xd9&\xd4X\x94\xd6\xa9Z\x0c\x1a\x8a\x94\xed]\xf5\x00=\x00Lu$\x97H\x91B\\\xb9@[-u\xf2,\xc8\x1c\x06\x9a.\x88\x04\xe5p\x93\xf0\x96\x05\xc5\xa2\xad\xea/\"\xc4\x13Wmt\xd5\x07\xef1qlf\x15\\\n\xdb#\xf0\x8dDI<\x88\xed\x8f\x81\xc5r\xa4\xf4\xa46\xf7\x14\x08uf>\x80\xfa\x81\x82\xb8\x91\x81\xa7\x10\x15p\x8c\x8a\x13\xbf!\xb2\xb2?\x03;c\xd6I\xc5\xe7>\x95\x8e#\x18\xf2\x1f\xe5\x85f\x9b\xc7\xc6\xe9g\xb5\xa6\x96\xe2\xa9\xb4ow:\xb1\xcb\xc1\x81\xab\xbe`Zf\xfefX\xbc!\xdd\xd4\xf3\x03\xae\xe7\xe7\x02\xbc\xa8\xecr\x08A1\xc4\xcc\xa4\x91\x93\x1f\xb3\x85\xa7xn:\x1d}xc0jFA\xb2m\x17\x13\xddFw\xa0\xaam\x0e\x085)q6\x89\xab*p|\xd2\xf5\x82 \x9a\xbc\x0f\x13oF\xdaE\xe1m\xb1+(\xca\xd7\x98\xc5\xc6l\xa7N\xa2\xd55\xaa\xde\x04\xe7c\x97\x83\xe4\x8b\xe0\xbc\x1eSaS\x9c\xf7k\xc2]\xb8M\xc1\x974\xb9\xee\xf0+~\xde\xb9\xc5 K\x19E\xc3ev\xb9{\x13\x9bp\xf4\xb9\x8c\x0c\xbb\xde\xe1\x13\x7f\n=\xd95\x93)\x98\xffd\x910\x17Ql\xc7\x024\xa5\x9dB\x14\xe2\x9d\x02Y\xae\xd2k`J\xe8?i\xe6Bd%9\x13\x02\xe4\xfb\x17\x89\xfd\x7f\xabMrb\x8c\x1dj\xd6\\)=rU\xa1\x98$\xb3\xd2,_V\xf7\\\xce\xcbVD:\x9b\xce\xdej9\xa6\x93v\"I\x8fk\xbfr\xc9\x84\xd9\x93C\xd8\xe9\xe8/\xb20\x1a\xfa8\xe4vq\xc5\xbd\xaaQY\xb6\xadJ\x0f\xf2_\xb2B'f{\xb2^C\xc0\xa5 \x8b\x9d\x9d)\x8c`\xe5\xc5 y\x19\xa2[J_\x17\"e]\xf2;+\xe1\xa0\x9e\x12b\xa43=z\xf2\xf5\xe3\xca\x0d\x9dQ@N\xdd\x98\xffyE\x93-a\xf8\xa8\"\xd3}\xfa$\xd4\x0c\xc5\x8d5\x9f\xf1\x10*\xe2;k\xc7\xcd?qku@G\xec\x92\x18\x86pl\xf3\xcblJ\x10M\xf3\xe4\x04z$TP\x8e\xd4\x9ac`\xfc\xef\xdd\x13\xbd\x98\xdaF>\x99\xa5\x13-\x83\xc6\x88>\x0b\xdb\xa2\xf5\n%\x01\xe6\x15\x11#$\xd2N\"\xd2IS\x95\x97q\xfc\x0b\xdb\xe2u\x02\x92$\x90.\xbc\x10\xaeh\x8d\xa5\x17_Zl\\\xa8\\\x15`\xc3f\x85hw \xd6\x82\xfe\x11\xe1\x95\x19\xde!\xf8l\xe1\x91\xbf\xe3R\xf94\xc2\x01[\x8e+}_R\xa9pMQ\x05\x80:\x8dRI\xe3\xa8*\xd5\x1c\xb9\xc9\xbe\xab\x08\xc2l\x05C\\A\xbe*lic~\xc4\xf7\xe0 \x17\xf0\x86\xfc\x88<0\xe8\xb5\xd0\x0e\xc7\x91u\x7f\xdb\xa8\xec\xd4\xce\"\x07\xa0aFa\xb1\x95$\x85\x07\xc7\x1f1T\xd4\x8d\xe7\xd7(\xa5\xbb\xa8\xb8\x92w\\Q\x10\x9f\xb7\"(R\xc3\x9a\x0bM\x06q\x07\xfc\x04\xc2(\x05\x7f\xb9\n\xc8\x92\x84)\xa9\xd2a\xe5\x06\xc2_\x91\xd67\x10\xb5\x01\xd5\xa2\xb6\x97\x13\xc9\x95\x8f\xae\xc6\x91d8eb\xad&^B\xa07\xd4\x96\x01:\xe0\x0b{\xac\x1af\x0f\x99 }1\xb6\xdfo\xd3\xfe\x98\xfft!\xad\xc9\x13S\xd3\x15\xbfOi\xec\x8b] 5^wI_0\xd3\xb3\x0e\x95n\xe9\xce\xc7%\xc5 \xa0\xa3?N!Z\xa5\xc9\xe8\x8f?Yn\xa9\xb6\x9e\x1f\xa3\x8b\x8c^([\xcc\x90\xb0\xcf\x15r$\x9c\"YJ\xf9\x1dP\x92N\xa3,U\xde\x908\xa6\x92;\x0c\xe1\\\xb9%\x80\xb2\xc3\xb5\xce\x88X<\x0b\xdb\x8a\xc2,\xa4\x03\xb5\xd8m\x92\x08\x88\xca.\xdf\x99\x1e%\xee.\xbc\xe4=\xd6b7\xd8\xa5\x17\x8c\x06,lk\x12\x10/\xccVB\xa7\xb6\x8c\xd6\xdc\xf6\x8d\xc4vn\x1e:\xd7\x96\xce\xfc\xd0O\x16\x96\x0bKm\xf14\xf6\xfc\xd0r!\xd0\x96\x8a\xfdy\xad-\xe5\xb3saB\x89G\xf5\xe3\x90\x92\xeaYM\xd9\xb9\xb6\x8cS\x9b\xb5\xe3\xa2\x85/\xde\x82E\xb2\x96\x10\xaf\xf5\xcf\xafb?-]\xbcn\xa9/\x91\x08\xe6\x9f\x04\xfa\xa8\xf8\xe6\xf5\x9d\x19\xaf\xa2qm\x913d\x86{\xd3\xc68P\x808^2\x18\x91x_\xe4\x11\xc2n\x14N\x88\x00\x0dZ\xbeu\xa3\xb0\x04e=\x9e\x07\x8d\x14\x174v\x15Mrz;\x01B<|\xb3\xbe \x9fs|\x92\xd5\xba\x8e\xa2\xe5\xc5\xf3\xa7\xf8{{\xbb8\xcf\xca\xb58\xfc\x8c+\x8cQ1m\x886~(h\xc1\x7fc\xeb\x84-\x06\xe3b\x17\xe8A\x8cx\xa8\xd1-\xac\xb9+9-3#\xd2\xda\x9c\xab\x171\x89M\xd0\x05\xa1\x12\xe7\xd4*\xcd\xadq(\xfa\xb2\x83\xdd\xees\xa9\\\"\x97\xe8}\xc4\x89\xbb\xf0<.Ux\n}Z\x89\x87_=\xb1\x0b\xfa\xcf\xe3t\xae\x04\x135\xf3\x82\x84\x00v\x0b1IVQ\x98\x10\x17\x84\xady\xa8^\xc0\x96\x96\xb8\xa6\xb4\xd3\xe1\x93C.\xa4\x8b\xedm\xba\x1b\xaf\x1b\x80(H\x15q\\8\xb7\x1b\xa9\x19C8\x86`\xec=;\x17\x14\xc6D\x17L\xb1f\x90s\xe3\xb6j \xcc\xe7Z\nb\xeehYO\x9bx\xdb\x8d\xc7\xc5\xa6\xdd\x9e\xd7u[\x1cva\x97\xfdnw\xf6\x0by\x96\xed\xc4\x9c\xf8k\xbbi{;\x00P T%\x1b\xfb\xaeb\xb2\"\xe1T\x00\xa5\x08P\xae\x96\xb0h\xcd5*\xf4\xee9\x9a\xf0%\x0cy\xf8\x1fcr\x06\x07\x90\xd9\xf2\x0b\xf4n\x92\xfe.[d\x95>\x1d\xc18tK\xaf\xce\xb0\x8a\x08\x1e\xad'x\x12*\x8b\x03\x9b\x1d(e\xfe\x80\xbdS\xb8\x02\x86\xf4\xfc\x9c 1f\xa1 \xb4\xfcn\x0fY\xb1\xe2F.\xe4\xb7y\xb6S\xb9\xd4\xaf\x18\xc1T\x18\xf3Z\x9d\xd5&*\x03\xf3\xda\x17L\xd4P\xbdL\x15\x8f\xc6\xc9\xa5\x90\xc3I\x89\xa3\x17\xd8\xa1\x0d_O?\xea\xd7|T0\x97\xbc\x9c\x07\xccfV\x1cBb\xe4exT\x96\x1d3H\xc5+\xa3t\n\xf6\xb95\xbcX\xc4\x9c]Hy\xc4YnH\xaf\x1f\xf8Vmp\xd2\xb8\x18\x98Y\x83\xedCy\xe6\xfa\xcd\xb2\xe9\xac\xf4\xad\xe4\x8a4\x16\xe7\x1a\"x\x02\xfec\x88:\x1d\x07\xe2qtf\x82A\xad\xc2\xb6b8\x04Z2\xb5\xe61\xdcNlR\x9c\x9f5:8D\x89LZl\xfeY\x97eg\xb03\x17\x9d\x97K\x80\xd8F\xc9\xa7\x8aM\x9c\xf9\x11 \xe4\xbf\xc6\xbd3i\xf7\x9a\x16\xbensF\x95\x1b\xd7:\x899)}Y\xb8Ap\xc3\x0d=\x861\x8a\xce8\x13'gm\xcc\x06h\xb9\xeaA\x10\x18\x8dRY\x84,)lVD\xfb\xf5\xb8\xdcJ\xa8\x07\xbc+*+\x91c\x8d\xcb\x11\xdd\xb9\xba\xf7\xecB\xa4\xa2\xc9\x89\x0d\x0eM\xb1\xa4\xec\x8a%}\xceq\xae<\x94\x04\x85K\xbe\xa6\x9b\x1c\xabu\xeb\xefM\xf3\x93\x0eF\nf\xb8\x8a\xaa\x18m;Z\xc4cL\xdb\x02:?s\x95\xa3\xa68eR\x85\xddo\xc4T\xe0f)eC\x13a|T1?)\xdf@\xbc4GP.\xa2\x9c\xeb\xec\x0c\x15=\x14\xe5n\x9b\x00U\xa8Z\xe9.b\x1c6\xf0\xc92\x1dG\xcd\x16q\xdc\x96\xfb\x08\x0fnd\xde\x0d\x16\x94\xca9R(\xe6\xf8W-\xa6{\x15{\xab\x8dN\xf7\x9a\x1b\x80\xb6g\x7fl8\"\xf2\xe3\xc1\x07?\xe4\xa2\x1d\xd7B4\x89\xbd\x94\x9c,l\x8b\xcefE\xa6\xc0\x85\xfb\xb0\xec/!t\xf1\xf5\x92s\xca,\x1f\xda\xb9A\xf1\xb3[\xbe>0i\xcd\xc0x\x8dI$S\xed*\xf2\xe6\x9a\x04\xce[\xe7\xb00&\x1e\x94!!\x84\xd3\x12(l\xbf4G&\xa7\xfa\x14]\xb6B\xc5o$W*\xa3\xa6^\xb2\xde\xf7\x99Ho\xab\x1f`=a\x95\"\xc4~\x9c\x9f\xef0\xa2+t\xe3\xb9 \xa9\xdb\xb2\x0e\xdaLJ>S\x14\xbb\xc6\xfe\x19\x94\xe3\xd2JR\x01/\xb4EE \xa9\x9b\xdc\xed\x1b\xd1K\xaa\x9bR\xe6\x9f\x87\x81\xadM\xe5\x07\x065\x86\xaf\xbb.\xd7qF\xf3\xfc\x8a\x11\x19$D\x82\xf98:\x93vz\xf7\xc2\x0f\xa7\x9c\xba\xd1\xa2\x1a\x8f\x9cT\xf6\xa6l\x86\x8c\x84B\xe7\xfc\xfe\x908\xc2\xfb;\x16\x14\xa7\x10#\xaa\x13\xd5\xd3\x9e6\xee&\x82\x84\x94|\xbb\x9b\xa3\xd8hL\xaa6rM\xd1Q\xd8\xd2\xc5Qu\x8e\xe5\xd9\xa1\xdf\xc7\xf9,\x8e\x96\xf4T\x86\x11\xbc\xfb\xa7\xa2\xac\x1c1\xdb\xc50\xd8\xed\x02g\x97bpW\xa3M\xb4iB\x1fNc]\x84\xbaz\xa4\x8dI\xeakO\xea\x1a%\xcb\x8dv\xd0\xe5\xcf\xb9\x1bK\x0b\xbb\xa3[_\xf5@\x93\x1bQMd\x01\xfc\xac\xa2\x9c\xd6\xbc.Z3\xee9t\xb2\xce\x98\x9b\xde\x01\xfa\xe0\x14\xc6\x9b\xed\xfbA8\x97\xb8\xd9\x9c\xe7\xf1\x85\xb8 |,\xd0Z\xc7\x00\x91F\xcf&\xe9\xde\xb420\xbb\x16\x02\xe5\x8f\xf9k;\x8f(\xee\xb6Ppo\xf1$\\\x07\x94-\x97'\x18\xb2\xd9\x85\xbaA\xa9/\xcb\xb0\xc2A\xe1\xed+\x9e\xccZu\x96A\xcc*\xfd\x99;d5\xd0\x92[\xc3\xbd\xafg\xef\xe2j\xf4\x85\x8a\x0b\xcd\xb4\xb6\x05%\xaa\xc3\xe7,o_\xfb\xadf\x04\x95ru\n\xe5\nL\x95U\xdf\x86\xb2\xa8\xaaO\x95B~>?\xf6\x9f\xec\xa4\xc8\xb0\x12#H\x84\xec\xd4\x9a\xca\xe1\xf0\x13\x12\xcch\x15\xfc\xf7\xd3'\xb8\xf2\xc3itU\xa5/\xbe>\xb272\x12&_&}\x00\x7f\xc81\xcd\x9f\x16\xaeS\xdds4\xc4~\x816\xc8\x06\xf0\x00\xf2\x9a I\xdf\xf9K\x12eiK)'$W\x10\xd9>;\xc0\x8a\xaf1\x1cB\xc1\xff\xb8\x80\x03\xe0\x85\x15\xb5\x05\xf6\xfb2LI\xbc\xf6\x82[v,>\xd7\xf7,J5]\xcb#C\xfdK\xe9\x83F\xf1\x873\xf9\xa8\x88\xad&\x96\x8fJ\xda\xd2\x98\xcc\x94\xec/\xec\x8d<_\xe5#l\xb7 $\xa55f\x10\x89\xdd\x1c\x0f4s&a\x1c\x05A\x1b\xfd\x90\x0c\x1d;\xa5\xcd\x05\x84\xff\xf9r\x8a\xd2\x87\xfc\xaa\x8a_\xb4\xb7,\xd4\xf4w'\x9d\xa9\xd6p\xb4\xb7s\x84\xf3\xe1$\xf5\xd7\xe8'\xda\xf5\xc4\xcf\xcf\xe9\\\x7f?\xc8/R\xa5\xaa\x1a\x8dV\x91bQm\x15FPl\x99\xe6\\ri\xf7<\n\xc5\xe4\xd9\x9dD\xfe\xb7\xee\xb2G\xe3q\xe5bD\xab}G\xec\xb9\xe5\x92L}\x16\x9b\xa5\x99\x84\x95\xbfP\xb2e\xb2\x01\xa95(\x0e\xe6\xac\x8b\\\x98\xef\xbc\x0d\x87\xa0|\xa3\x1dD\xb5Ni\x18\xe5\xe2\xe2|\xb8M\xde\x9a&\xde\xd9\x14P\xcdGU\xa2\x9f\xc8Q\x88\xea\xd1S\xd8#\xe1\x8d\x82eA\x07R~\xab\x99F\xdfDW,W\x8em\xb4\xfeF\x13\"kA>Zz\xd3\x1eV\x8eq\x90\x1a*l\xd7\xd7\xf0\x92\x89\xef\xd7\xd6\xb8\xf0C/\xbe\xae\xaf\xe2%d\x7f\xb7~$\x93d\xd0Ta\xbb\xa1F:\xeb\xef\x07\xa4\xa9\xcevc\xa5\xd8\xbb2\x94\x83\xe4\x9fm\xc8+\xd9hq\x95\xfbwWwxys\x1b\xf2\xfc\xe8\x18\x19Ee+\x90\x0b\xf7\x07i\xeb\x07.(`3\xff.\xae\xa3\xf8T\x18\x9e5\\\x03\x91\xc7\x8f\x9db`u\xca\x97F\xdc\x85V\xf8+\x9e\x16\x83\x846h\x08\xadP\x11Z\xa2#\xb4EI\xf1H\xd3\xc0\xdaM3 \xbc\xd4\x0f\xfb\x8d\xbd\xd7\xee^\xf1\x88\xbey\x9bM]\xd7nwhEZ\xa0\x05\x8d\x13\x8fP\xe9\x98\x87\xd5\xb8'A8X\xd4\x87\xd8\x12\x0f\xa5\xd96'\xdaez\xcdbQl\xf5\xb4\x9f\xeb4\x84\xba{I\xbc/\x13\xd12\xb6\xca\xc1\xc5\xed\xd213\x1a\xf1X\x85,\xbdQ\xd5'\xc4z\x1f^\x86\xd1U\x08\x82\n\x0c\x81\x0d\xdb\xa8\xc7`\x07l\x99\x12\x15a\x1d\xf2\xb8t:\x8e\xab\x05\xdac#)\xf9(\x92\xc6\xb06)\xe74a\xa0\xd3Dh\x04\xb3\x89k#\xa9\xc0\x0ef~\x10|\xe3\xa1\x96\xce\xbb}/\xb5X-\xcfkV\x9aW\xc0z\xdc\xd9\xa8\xc7Z\x84\x95U\x98\xcc\xfek\x04+\x96f\xdc\x96:^\x98$g\x10\xe3\x0d\xbc$}MP\xce\x16\x81\x11\xe9\xabwQ\x8a\x82\x92\xfc\xeeh\xe11\x8f:\xd9\x1b\xb0\xa4\x0c\xcc\x7f\xe6gUV\x13\xd6\xfa\xc9\x08\xfa\x83\x07\"c\x03<}\n{0\x1a\xc1>\x1c\xc0@\xbc\xd9\xa5o\xfa\xbbp\x00;\xe2\xd5\x0e}\xb5\xd3\x83\x03\xd8\x15\xaf\xf6\xe9\xab\x01\x1c\xc0v\x1f\x86\xb0=\xa8\x1d\x92g8>\x852\xb0\x98\xfev\x19DU!\x7f\x13\x07h\xb4;\x19<\xa4{\xd9\xee?\x1a\xc0=L\x0f\xebH\xb6L\xe5\xa5\xb0\xfe\x9f\xff\xeb\xff4PY\xf40*\xaas{A\xc91\xac_w\xb4\xea\x06\xd27\x0d\xa4_;\x10\xd0\x0df\xa0\x0c\x06\xffV;\x1c\x98:\x1c\xf0\x0e\xdb\x13O\xae\x0f}\xacC2I\x90\x08\xd1\xbd~\xa8`\xfd\x13\xc9\xd7\x0c\xa3y\xa1Wf \xe5qY\xe5}@?t\x94}\x91\xa7l+\xf3[nuS\xb1\xa8`\xb5\x1d\x89\xcb4y?\xe7#\xde\x96\x02\xa0\xd5\xef\xbdD\xab\x01\xa0\xebe\xa7\x85'\x10q0!\xf9\x08\x1dWjt\xf2\xc5\x0cs\xf2n\xb6\"\xa9\x0f\x03\x80\x97\x91\x93\x85\x17\x1fESr\x98\xda\x92\x07\xac\x1aWZ<\xb4\xd1\x98J\xdd{{\x83G\xfb\x80f\xf9OF\xb0\xb7\xbf\xd3\x7fT2\xf8Rp\xa9B\xd0v\x95\x85\xe3)\x9a\xc7\x12D\x06gj\x9d~\xa5N\xff\xcc\x85\xb0pS\xd7\xe6\xd9\xae\xbc\xd1\x9bxh\x89\xa32\x93\xbef&\x83\xe6\x99\xf41\xe5\x85v\xe1\n4C\xa8\xd7\"R]\xaa:\x90\xef\xc3\x0f\xa4\x03\x89]~X\n\xe5@jQ\xdaH\x0d\xf7@fr\\\xc3\xbdtL\x9bS\x82@\xaf\x1a\x0eL\xb7\x12\xa4\x1623\xed\x16\x13\xe3\xafl\xb3\x1d-\x91\xeaq_\x93\x83\xd2ZqV\x83\xbb\x9d\xd9*F\xec\xc06\xde\x94\xa8X\xb1#\xec\xd1B\xb1\x1a\xb5\xf8Qj\xfa\xb3\xf6\x83\xe3\x1a\x86_\xc2\xb4\xb0\x81f\x05w\x87j\xda\xadtP\x8b\x1d\xf9\xa0{.\x02X\xc1\xd4a\x036\xac\xcc\xcc\x8e\xe1|\xa8\x07\xc6\xa2\x86yj\x82\x85\xd4\xb0\xf8E\xca\xd1\xdcX\xc6\xc7\xa8d\x1b\xe4\xa7\xf5\xc2\x7faq\x9b\x9fA\xb9`\xa8\x80\x1f\x97\xcdU\xdd\x9e[\xed\x7f\xbfHB\x87\x9e\x989k&\x98x&\xe7\x18:\x06\xd9\xba\xf12u\xbd\x84\x02>\x1e}\xae\x9a\xdeJ4\xb2\xbd\x8d\x83\xa1\xab\xb7=`bv\xdd\xc0\x90\xb1\x92F\xe6\xb4\x1e\xc3\xe0\xf7\x1f\x03o\x0bC\xef\x8cD\xca\xbc\xf2\xa8v\xf4\xa3\x12\x9d\x97\xb7\x8f\xd9\xb0\x98\xe9 \xcb[\xbeJ\x15E\xb8~\xf5\xeb\xca\xf9\x16V\xa9\x8c\x1c\x9e\x01\xb6\xc1\x0e+\x94[\xbf1\xb4,x\x8f\xf9M\xeb\x86FKL\x1bFR/\xd4S\xcf\xf2v|\xa2!\xa4\xfaq\xd5\xf3Bw*\xa0(+p\xeb\xe1\x14bLy\xd2\x92\x04\xa3\x9cR\xb7\xba\x99)e?/^\x17\x176\x035y\x1f\xcfq\xae\xcf\xcb\xac\xd1\xae#\n#\x04J\xd9T\xca9\x13\xa2j\xda\xf0\x92\xc9}n\x8b\x91\xc6^\x98\xcc\xa2x\xc9\x8c1tn1\x18\x17\xfc\x9d\xa8\xd7\xc2r\nT\xaeY\xe9E/T\x85\xdd\xbcV\xbd\x1fG!\xb5\xe1y3\xb90\x0bi[qY\x1c3\x06\x0e`\xcc\x06\x85\xd0\x857\xb9\x14qj\x96Y\x90\xfa\xab\x80@\xea/Ib\x8cw/\x06\xb2\xc8\xc2\xcb\xdcG%\x1f]\xf1\x86\xa7\xec*L\xadx\x1aWW\x93O[<\xe2\x80apl\xe1}\xe0+\x86;\xb6_ k.\xecc\xe1 \xf8\x9a\xa8\x1bEW\xb6Z\\\xe9\xf1\xa6\xb0\x01\xd58\xdd\xd1\x8e%\xc4\xd1\xd9H\xcak\xae\xaf\xc1\xc1\xc8\x82]\x98\x8a)\xe8kk\x14\xdafZ\xa9|\\\xe8\xad\x97t\x0154\xd5\xa4P\x1e\xb5\x89E\xf2\x89J\x06O\xc5\xbb\x91\\\xc3\x9cgd\x16d\xc9Bj\x80\xfd=\x12%\xc2\xe4\x1e\x0d\xb6W1\xc9\x1d\xf5\xb2&\xbd\xa8\x8e\x9d\x12\xbe\x18e<\xd3\x8fL\x1a\xcd\x81\xfcW)g\x9a\x96\x19\xf3r\xdaZ^\x14\xcaDz\x9c\\\x15\xfb\xa7~\x1e\x9e\x89\xeb+\xdd\xa4hLH\xabLB)\xb1`Z\xc4\xba\xaf\x84 \x10\xe7e\xe5\x9e\xe3\xc8\x0b\x02\xba\x0d\x8bE\x9eF!\x81\xab\x05 \xe1*\xcf\xa8\xb45\x82\x9e\xa5\xe9?U\x89f\x89:n\xd8]\x92\xfaAP\xdajj\x979d4\xbe\x00\x85\xcc\xe6W\xf2\xaa\xb9\xd2;;b\xdcJ\xb4adw\x99@\xab\x93.Q\x90\xdc\xe9\xa9\xdc~\xc5\x97\xac\x18yy0\xa5\xfd\xd6$(T\x00\\|m\x080c\xec\xb6*\xc9\xea\xbb,{\x9a\xd5\x9d\x99(\x9b\xc8\x07\x0c\x85J\xe9\x10J\xf37\xd2m;qa+V\x10I/\x1e\xb5>r\xecXY#<_\xbe\xd0\x89sc\x04\xb1\xeaYP\x7f\xa9R\x0b\xdb\xdc\xe7\x84\xc8\x10\xc5[\x04\x01p\x16B\xb8\xc4\xae`\x0c&\x95\x81\xe9U\xb8,[n\xd4\x15M\x16\xfc/\xe9\x96\xb9-f@\\\xdd\x06=#$Z\xe6i\x90\xf93\x95Q\xac\xb6\xa6l\xb1z{\x0c\x96{=\xe4D\x969\x90\xab\xc4]!.\xb7b\xb5%\x9eZ\x97\x89\x17sH\xcaBQ\x14\x1f{\x93E\xb9\xa2\x94\xe2|\x12\x93\x12.\xb4K\x8b+\xf0*bDSKU\xb9\x0din3\xda\x04@Lgz\xef\xde\x06\x8c\xb6\x9e\x15DK\x97\x10\xbd\xd9\x1c \x18\x04\x10\xd2qxV\xa9|c\xf3\xb4\xb8\x18\xc9X]+\xb7\xa4h\x84\xdb.\x97\x16\x9e\x0e\xfc\xfd3\x9a\x940`\xc7iZ93\xcd\xf5\xf5\xab\x96\xbc\xf6^\xdb\x98X\x16\x95\x18\x84\xa9/\xf0\xe2\xee\xde=\xae\xad\xd8\xc6\xc4\x0c>\x86\xb6\x1e\xe6\x8e\x95x#\xd4\x9c\x1d\xb9\xd5\x1c\xcb\xfe7\xbb\x0f\x06\x8eM\x87\xc4\x91\xd6K\x12\x7f\x1e\xc2\x10\x8bv>\xd7\xa2\xd0\x05\xdf\xc5Tr.x.\xcf\xe6:P\x13\xa4N\x9aH\x0b\xe8\xee+\xe8#\xe7\xcc\x8f\xaf\x95\xaf\xf4\xaeY\x13\x17x\x08@\xad\x07\xd6$\ng\xfe<\xab\xc9$.\x985\xbdl\xd1\xe4\xc1\xb5\xf6\x82\x8c\x0cA1\x02\x96\xd6\x15&^n>V\x9cN\xec\xcec\"]\xe5\xc6\x15\xc9\xba~\xe8\xe6a\x97\x87\\\x8c\x84\xc55\xd4B\xd1\xdd8\xa12\xa5h J\xa6\xb9*k\xc4s\x06\xa60\xa4\x87>B\x86\xb1\x14\xe8\xa7U\xacR,_\xaa\xe0m\x11\xcfn\xfc\xe8\xa1\xe3b:\xd4\xf1\x19\xcbl\xdd@U]\x9d\x02\x9cr>\xde8=\xcb\x99y\xfaG\xb9\n\x92=\x82\xfd<\x86t{\xfb\xb1#|\\-\xcf\x82\x0e\xd8\x9dN\xe8\x14\x1a\xa8\x9d}U\xae\x97\xf4(\xc2i\xc2\xb6f!K\x98\x8bE\xb9\xc4a\xd3\x06 \x0fq\xef\x82\xe5@\x87\xfe\xef\xef\xa2\x8dY(\xbc5\xf1\xec,\xdc\x06\x1e\xc3\xcd\xe32\xcb\xd8z\x8d4\x14\x1f\xe5\x1b\xc3\x9a\x15b\x8f\xc2\xe7\xe0\xa9E\x9c\x8a\xea\xa1\xba7\xe9\x93\xd9\xe8\nU\xde z\xf4\x07\xdd\xed\xf2\xcd\xe7\x12'&r\xe8\xb2\xad\xeb\x91\xbeTM:\xe7\xe7$}s\x15\x8aj\xcfI2\x89\xfdU\x1a)\xf6\xd3\x99\xe9\x83\xd7\xdeR\x0dh\xe2\x99\xea\x9e^//\xa2 iq2i\xd7\x98\x91`~4\xc76Q\xf1\x14\xe5D\xb9\x06\x86\x18\xc8\xec\xc4\x11\xccN!~kC\x0d\xeaW\x1a\x9b\xb6\x99\x87M\xc4\xc2\x14j\x14?\xf2\xd2k\x9b@\xee\xb2\xfa]\x19\x81L\xaa\x0e\x0f0\x82\xdb\x7fY3\x91\xed{r ]/g\xffS\xb9\x95\xcf\xdc\x15}\x1d\xff\x1b\xda\x0fUUs\xa4w\x03\xa3\xdc\xe9mq\x94\x9ek\x9a,xt\xfb\xe4\xc4n<8\xd3B!Fj\x85\x0b$w\xc4\xd8\x10O\xb7\x1a\xe18>C\x07'\xe1H\x91\xa1<\"\xbe\xa8\xacH\xd8\x00g\xb9\x8fv\xfc>\x1f\xfa\xd6\x16W\xf6\xb1\xf0\x03\xe5\x14r\x9f>\x19\xb4d\xc8\xd5\x9b\xf4\x83\x0b\xd24\xdaVX\xa1\xe7\xa3\x88\x0b\xd6\xf99I^E\xd3\x0c\x0dN\xd4\xa5D>G\x16+Yt!/N\xc8\xf7\xde28BnE\x93\x16\x7f]D\x88\x0e\xed\xbdAO\x83q\xc8\xfc\xb0\x80\x0dq\xb7\x18\x04\x1c@\x0cC\xcd\"\x0bSS5\\p\xd1\xa9n`\xb5\xa8\xaa'\x0f|-#\x91\xe3\xaf\x9bx3\xf2M\xe4M+ \xacjID\xce3\xb1\xd0\xc8q|\x88\x03I\xba!\xb9zG\x89@x\x1c\xc7v\xa1IB*\xad\x1c\x97\x1bz\x916\x11\x84\x9d\x87\x06q\x88\x8e\"\xb6\xcbs\xf0\xc3I\x90M\xc9\x10\xc6\xa1=\xe8\xed8g\x12\x12\xfcC\x07\xd3\x1f\x0c\x9c3\x85\xb0-W\x81?\xf1S,\xdf\x1b<\xc0P\x06{\x83\x87\xfc\xdfG\xec\xdf\x9d\xde\x1dM\xe2N7S\x10y\xcc[\x99t\xdf\xbd\xf9\xea\xabo\x8e\xcf\x8f\xde\xbc~\xf1\xf2\xabS|\xf5\xfe\xed\xf3\xc3w\xf2\xab\xda\x9d6\xe8\xed\xfdN;-[M\xbd\xaa\xf6\xd2@\x165\x07\xf3\xf5\x8a\x0c!\xab\x9e\x10+\xef\x9a\x02d\x08v\xcf-\xb6\xa0c\xff\xfdF\xd5\xe2\x02(\x9a?\xd2M\xa3\xf9<\xa87\x0ej\x18\x91&\xabJ>\xa2\xd4\xd4uy12\xfd\xbaYL\xb2K\xce\x19\xe4\xac*\xaf\xa8Y\xff\xfc#63K^\x81\x1cod\xad\x89n\xaeU\xad\n|\x1eA!2\x12\x8dJ\x0ef%l\xec\xef\xa9\x0c\xc8\x97\xc2F^\xa7\x85b'\xa7\xca~\xc8\xe2:\x94\xd1\x8c}U\x1d\x04\xdf\xbca\x83\xae@\xa3i\xd8H\x17\xa1\x18\xac\xa0\xa9\x16\x8b\xde\x19\xba\x9br\x87\x94\x1a\x10\xf9\x1c\x18\xdeQy\xa1\x8f\xb7\">\xdd\xd1\xd6%\xb9N\x90\x91&\xdc\xa3\xc2\xc2\x1d\\\xbc\xc3\xe47C\x16\x14w\x1c\x9e\x9d\x95t.\xa22\xdeZ\x1e\ny\x05%\x0c\x0e\xe9\xd8f]\xa0\x91\x86T\x1d\xc3\xd0\xa7\xb1O\xff\xd2\xe2O\xa3haT}7~\xb9\xd1\x01\xcc \x9a&\x18\xde4\n))\xda2\x1ew\xb7\x1c\x9d:4\xbf\x1cJyK\x96\x87\x98\x90\xfc\xeezE8o\x0c\x1d\xb0\xc4\xed\xaa\x977\xbae\xba\xafn\x18\xec\x86\x9b\xf8\x91~\x0f\xef\xedj\xb7\xf0#\x95\x05\xcbP\x18.\x1a\x0e\xed\xc1\xbecg\x94\xf2\xec;\xb6\xe5\xa7$\xf6\xd2(\xa6\xe8\xd3t\x94\xa7r\xf0\xb2\x1b\xa7F;\xa8\xbb\xba.h&\x8c \xa6#\xa8\xe2EH>\xa6t\x13i\x12\x91\xd3\xdd\x80m\xe3b\xbc\xcc\x87\xbd\x19\xb0%\xf5\x84\n?N\x1a\x1fh\xc1\xba\xdb3\x93\xc0=\xe9\xea\xa3\xc4\x94\xfb$i\xca%\xe8W\x14\x9dEf-\x17\xd7.B}\x04\xe5\xd02N\x81\x98\x06\xae\xf7\x18\x85\xbd\x07;\xbb;\xbc\x7fV\x1f;\xa2\xc8\x82\xce\xdf\xf4-\xf3\xc2L\\\xecd@\xcb2\xd8\xe6\xcdt\xe88\xb7\xf9\xa0\x9e<\x81~\xcf\x81\x0e\xec\xef\xed\xed\xec\xdf\xcd\xa6\xaf\x1c\xa9\xfc\xe0\x18\xf4\x8dg\xea\xc0\xe9\xceI*\x0e\xf9\xe6[Y\xa4\xf3\xeaIjd\xf1H\x03\x8b\x87<\xd1E@L\x0c^l\x13n{\xe4\xdcz'\xf6w\xf4\xd7#\nOV\xa10(\xa4\xb5\x03\xdb+\x92.\xa2z\x034\xc9\x8dl\x0b\xa3\xcd\x0b\x9a:\xf6\xcf0\xc0\xc5\xd8\xfa\x97\x7f\xc9\x87\x83\xaf\xa21\xa5Ng\x9b\xcd\x9b\xae\xf6\x0eJ\xbb\xfd\x1d&\xf5\x0evv\xf9\xbfLM:\xd8ej\xd2\xc1^\xaf\"\x0e\xf7\x1f9B\x14o\xd3Y#C\xad\xc3G\x99E\xf6\xc7\xa1\xddwlK\xdc\xc6\xbf\xf3\xe6\x96s\x06#\xb0~\xc1L\x8d\x1d\xba\xcf\xb7F`\x8d\xd9E\x0b\xfcrf1\x1d\xc1N\xcf\xe1VK\xa5\xe8\xbd\xa2\xa1\xba\xb0\xdd\x1c\xf2y\x9b\x16t\xe89\x80\x01L;`\x9d\x95\x9c\xe3\xb6\xda\xe9\x07d0n\x85\xf6\xee\x80%G\n\xed\xdd\x1d\xc7\x1cx\x8d\x8f\xe4\x01\x9d\xa2^\xd7\x1c\xda\x8f\x1e9\xb65\xf5\xd7Tl\xb0<\xad\x19\xccF\x81\x86\x1fT\n\xd5\x9b\xcc\xaeW\x00\xa0\xd5\xe4%]\xbf\x89\xd0\xd4\xb3\xe6\xe8\xaa\x81'\xb1\xdeV\x813\xe9~\x95\xea\x10\xd3\x95\x9a]\x8e\x13\xc0\x96#\xe6\xb1\xc7\x05I)|\xd1j\xe9\x99\xda(\xca\xd4of\x9b\xb7\xb9\xf5e\x86\xab\x92X\xeb\xc8\x0b\xff\x94\xc2$\n\xd7$N\x81\xa3y\x1a\xc1*\xf6\x97>\x06+\xc4)l*\xd25m\xf7\x81\xe1\xfc\xe9\xef\xe8%\xe8~O\xe5_\xaa\"t\xff\x01\x17\xa1\xfb\xff\xaaE\xe8\x87\x86\x83]}\xcf\x01\xbb\xab\x03,\x05x\xcf\xb1\xad\x97\xc7\xe7oO\xde\xbc{\xa3\x1ez\x9e\xaa\x9e*\x17\xab\xda\xab\n\x15U\xba/F\x8c>?\xf9\xe1>/b9FxXV&\x1e\xa7\xdd\x17\x8f!F\x8b\xb3) HJ\xe4\xac7\xe3h\x1c\x9fir\xa6\n.W\x8d\xed\xaa\xa7\xa3%c\xe5rP\xc7v\xa6b\xbc\xbb\xdc\xca\x1d\xefF<\x05\xdd\xd1\x80\x1b\xd8\x0d\xad\xe7B\xb9\x98{\xe3\x8c3\xb4'\xc6\xec\x93hzVX\xc0\x8c$}\xac\xcf\xb2\x19\xdf\x16\xf1\xf7\x0c\x14\xc5\x80\xf75\x1c\x1b=\x92\xff5(\x8f\xf6\xf4\xa4b_wEG\x99\xc2\xbeco\xb5\xa3\x16\xb78\xd99\x80<.5T\xe9\x00\x82\xa8\xfaz\xc2\xcc7\xab\x10Gsv\xcfaJ\xa2\x8c\x19Z{\x08\x8b{\xf7`\"\xfc\xb44\x1f>\x96\xa3@\xe1j\xe0w\x94,\xe0Z\xb0d!\xff.\xb2'\xd8\xda\xa7OEk\xfa\x05\x9a\xdcv\x81vM<\x12\xb7\xe3\xb3~\xb1\x1c\xba\xe1\x90\x01|\x99\x1c\xe7\xf7\x8ev\xaf\xc0\xe0\x12\xc2\x9a\x18\\\xce\nS.#f\x96\xec)&\x10Km\xcb\xa2\xfb6\xb7\xfa\xbf\xedT*H\xc5pmWg\x9c@ \xb6I\xb5\xdb8\x95\x92^\xe2\xdf\xf4\x94\xff\x15\xe9)\x0d\xe4j\xb0\xa3\xfa\x1dD-8\x18\xc9j7?\xb1j\xcf\xd19I\xdf\x8a\x8aof\xf5A\x92s\x90pZF\xf7\x94\x0b\x11n\xabqt\x06C\x93i\xdf$\n\x934\xce&i\xc4r\xe3\x83\xe4\xb7_.=(\xff-\x1d\xbb\xc3\xf2g\x9c\x08\x1c@\x06\x8aG\xf3\x86\xe0\xef\xdfzK\xcaV\xc7\x9b\xf5\x9e\x1f\x9d\xc2w\x07\xfdH\xf3\x03\xdc\x15\xda\x97\x9e\xe3\xf2\x93h\x8f\x1f\xad(\x0e\x08\xcf\x94\xdd]\xc7\xc5\xfdLe\x03\x177\xed\xa4,\"\x04\xecUI\xb9\xc0\xf2\x82'\xe2~wQq\xcc8:==\xc9XN\xbe\xaa\x19\xc7\xd1\xe9\xe9)eH\x9f\x93I\xe0\xc5\x1e\x9da\xd5E\xe3\xe8\xf4\xf4\x03\x15\xafx\x13ji\xe0\x930=!\x93T_\xfe\xfc\xcd\xab\xdaB6\x17c\xf1\xbb\xe8\x92\x84\xfa\xc1?\xf7R\x8fy\x11\x92\xf8eJ\x96\xfa6^\xf8\x81a\xe4\x7f~\xf7\xea\x9b\xc3 8\x8a\x82\x80L\xf4S\xa7U\x9a\xca_D\xf1\x92k\xbb\xf5\x15N \xfd\xdeX\xe5\x15\x99\xfa\x9e~\x86\xaf\xfc%\xa1b0.n\xf5\xcb\xd7\xde\x92L_GS\xf2\xca[iJ\xa3\xa9a\xd5\xdfz>]\xb1\x9f3\x92\x18\xd6\xe5m\x90\xcd}\xcd|\xd9{\xc3pN?|\xf5\x0d\x1eC\xfa6O?|\xf5:[^\x90\xd8X\xfc\xd6K\x17\xa7\xc4\x80\x0b\xb4<\xf2C\xc3\x80O?|U\x87H\xa7\x1f\xbe\xca\xfdM\x0d5\xa2,\x9e\x10\x16z\xdeP\x83n\x94\xd3\x05!\xa9\x1e\xaa\xef\xc8\xc7\xf4]\xecM.\x8fL[%\xafa(\x8e\xb2I\x0e\xbb\xbc\xe4\x86\xa5\x0b\xf7m\x0cY\xc98\xf05<\x81\xa9\x904a\xdd\xe9\xe8\xf8\xd4k\x17\xe60\x82\xe9x\xad\x18\x9d\xd2g #X\x8c\xe7\x9a\x92sd\xe7u%\x170\x82sJ\xf1\xcfu\xa7\x11\xf0c\x18\xdd\x89\xed\x0bz\xf6~\xfa\x04\x9e}\xe1\xc2\xcc\x85\x95\xe3\xc2\xc58(\xde\x05,\x07s2\x9e\x9f\xb1\xe8\xbaK\x8d/\x03R\xd6kz\xa2\xc7\x0e\\\x8c\xaf\x99\x1a\x99~~\xedB<\xbe>+\xf4\x99\xd0\x96Z7*}\xb4>9\xf4\xbd\xe1~_\xd5\x05e\x82\x954In\xfd\x9d\x07\xfff\xf9\xf4_\x8e\xe5\x93\x99\xd7pl+\x0b\x93I\xb4\xa2\xd2L\xa22o\x1a\xa7m \xdf\x84f\x01\xfcq|\xc6\xae\x00\xfa\x0f\x1c\xdbG\xef\x8f\xbf\x9b\xf5{\x15I~\x1c\x9f\x8d\xd33\xc5\x89^;\x11\x93~\xbf\x16\xf5\xf8\xa2\xea\xc4\x93\xbb5\xc4j\xbfMe\xb7^\xbe\xa1T\xa6;\x11lV\xe9-c\xae\xf6U\xab\xa8\x19\xbe\xae\xdc\xed\x04\x8ckS\xde\xae\xd8[U\xc3\xb0`M\xab\xaf\xa7\x9ct\xa8\xd6\x91k\xf6~W\x1d\xca5\x17,\xd5^\xe7\xfc\xfd\xae\xd3M\x88\xb2e\x97\xbc\xad=\xc7V\xbe:\xe7,\xb1*\xd5^\xf0\xd6T\xf8\\\xf1\xf7*\x01\xfc\x88\x1cf\xae\x8fW\x8eE\x91\x0c{B\x12\xc5\x91\xf0\x18\x8b\xf8\xfd[\xb9\xe8\x10F`\xf1\x8fp\x87\xcf\xecS\xa5\xd77\xf5\xea\xdb\x9f0\x92\xde\x08\xce\xbb\xb3r\x01\xa5\x84[[\xf5\xaa]\xb3\x7f\x9d\xa0\x8e\xc7\xdd\x98$Q\xb0&\xb6\xba\xa6\xf2CX ZY\xe6\x19\xd1\xdd\xcb\xaf\x01\x93\x15\x99 a9\xab\xdd\xc3\xea\x93\xdao\\xc\x96v5\xd9\xfaA\xb2\x0394zl\xf1\xa58!?1\x86\x163_\x8a\xac8\x0b\x12\xdao\x1cY*\xab\x8a\xe55\x1e\xb27*\xf6\xbdl\x9c\xf3\xba\x9aX\x05\xa4s\xc4\xde\xc2\x98\xaf\xe5\xc9\xe4w\xf1,p)\x0e\xdb\xc1)\xa8\x89\xb4J\x7f\xbej\xa2s \xae\xb4\xd2\xee\xb9Q B\xcb\x14\xc7\x01\xf9Y\xe7\xe1\xbc\xcf'\xfa\x1a\xcb\xe6\xa4U\xa0J\x94i\xf7|\xcd\xe4\xc9>.e\xf7\x1c\x00\xe9F\x97\x18\x94e\xe6\xf9\x9ahc\xea\x93\xe0\xc5\x03\xdf\x1b\xcd\xd5'\xbc:E\xb8\xe6\xda3\xac=\x8d\x96\x9e\xdf\x94 \xc4\xb8\x81\xe5\xc7c\xc1.>}b19)\xec0\xdc\xd8[\xc6E\xd1\xbfF\x18\xa4t\x8b)\xf9=d=Fh\xedoc\x0e\xadY\x97\x84)\x89m~\x81\xe0\xd91\x8a\xe6\x94\xc5\x9du\xc9G?\xb5\xb9P\xbf\xd5sX\x1d\x8c\xb4\xb3\xe2\xe6\xff\x070\xb1?\xda\x16\xdfw\xdb\x93\x85\xe7\x870\xb9\x9e\x04\xc4b\xa1\xea\xe9:\xbe\xb4)\x06\x1f\x087\xd0\xd0\x85\xc4\x85 -N\xb0d\x08\x13;6S\x03P\xf7e#Xp\xfc[\x19\x9f\x1f\x9f\xc4\xc4\x94f[<75\xf4\x08\xc2B\x19\x1d=v \xb3\xc3q\xd4\xe9\xe8\"\xc8\x8a\x87n\x12\x1e\xe1&p\xd4p\xad\x9a\xde\xde6\xf6\xb6)\xfe\xea\xb1QF\xac\x1c\xe8\x7ff\xaba \x9c\"\x1c\xa7\xf2\n|\xb9\xd8)\\\x83Rm\xd0I\xa0\x12\xddS\xad\xb7~\xedJ\x9d4\xc2n-\x05S\xab\xc2\x85t\xcf1S\xb4\x8d?X\x184\x84\x01\xe9\x9e_\xd1\x02\xe2t\xcf\xd7,F\x1d\xe9\x9e',{\x04\xe1+l\x13\x86y\xa4{>\xe1\xc6\x94\xf4\xa0xe\x13\xd4]\xd4\x8e\xfcu\xbb\x91\xbb\x86\xc8g X\x9a\xb0{\xae\x0d\x05\x0f\x18\xec5\x9f\x14\xde\x90\xf39\x19\x8e\xdf\xfac\x17\x03M\xb2\x00\xf6bc\x15\x87\x1fL\xd0\x88\xe7\x82\xeefd\x1e\xa6\xe0\xa7 f\xaa\xa9\xa4\xfc \x9c_\xa2%\xd5A[\xe6 $!\xbd\xf9,<\xbf\xd2zGV\xaaM\x87\xba\x84\x82\xf2c\xe0\xca\xc5\xd3\x8ec\x11\xe6\xa1\xf4<~\x8d\x07L\x1f\xcf\xe6\x13\xfe\xfb.\xd9\x80\x93\"\xf3\xed\xadO~g\x88y\xc39\xfa\x87\x0c\xfd\xfb\x14\xbfC\x17\xb6L\xe3m7N>\xbe\xfa\x89\xb4X\xbf\x86\xb5\xbb1\xce\xbf:o\x85\xc9(V\xfc\x12\xf7\xfaq\xed\x86\x9d\xf2\xa8I\xc7.\x88Ma\xb9`\x9d/,\xc7\xc5t\x14\xae\x1c\xd5\xbaU\x14\xa3\xd4F4a\xed\xe6\x98\"\xfeT\x88K-\xd0O\xca\xf1\xb4\xcb_\xe6\x7f\xdd\xb8\xec\x107O\x92\xa9\xf9r\xce\x0e\xff\x92O^\xf6&\x91U\x97\xe5l\xe5\xebJ\xe5\x85\\\x991\x8a\xc5\x80\x9c\xb2-\x8f=\xd8\xddw\xecc\xd9\x86V\x1d\x1f [\xc4\xfc\x16\xa2\xdcO\xb6\x88uu\xac\x0b\x97-\xac\x8f\xa8\x0c5\xd2\x8a\xa9\xec\xca\x19\xf7\x06\x15\xb0\xca\xb5F\xe5\xd4\x83\x94\x92s\xe9\x07\xd9\x18z\x16\xf3?\x87\nL&R\x08_\x0e\xe3<\xf0\xa8\xa7\x96a*\xdfW|\x1e\x98\xb8>\x14\x12Jy\x9d\xcb\xfb\x08\xd1\xa5\xce.\x03\xca\xd6\x89L\x85\x90\x8f\xd3\x88C\x8e\x12.\xcd\xa4\xa0\xc6x\x1a\x8f\xab\xd8%\xb8\xc2\"];?Q\xf0z\xf45\xc6[\xc8\xb3\xf33&\x05KNx\x89\x8c\xcd\xe7]*s\xfe\xd4\xe6\x828\xc5\x93\xed\x18\x97\x13\x7ff\x94\x83\xe6\xc1\xe9Q\x8d-\x1b\x9e8.\x04v\xd0\xfd\n:\x10t\xbf\xc5\xff\xbf\x80\x7f\x86\xadK\x15!\xdf\n\xa6\xe8\xb8\xf41\xb3&\xb5eZ\xc1\xad\xdd\x1f8\xb6\xfcJD\xa3\xcb\x0d\xddY\xc7\xa7\xa5.%z\xa3\xce\x8d\x82\xa7i\x91\x05\x83\xf4\x93\x8e2\x81\xa4z\xea\xb9\xb9\xb4\xef\xb0\xe8\x9bzD\xab\xc0\xa9\x18\xae\x8dl\xd3\xd6\xa5S;j\\\xef\xa6a\xf3Q]\xd9\xf9\xe6\xc8\xd7\xed\x98'\x93i\xc0S\x05\x92\xf6%\xd3\xd4\x0fv\x1fJV\xf0\x95\xbe\x8f\xbb\xcc\xc0\xb9\x8b;\xc8~#\xa3E\xdd\xb4\xbc h\x9a\x92\xcc\xaa\xeaO=F\xb5L\xf6BxsQ\xaf\xbe\xf1y\x15\xb3\xca&j/\xa9\n::\xd6\xdc'\xcaO\xa4\xb7\x9b\x93\x1f\x8a\xe8\x86\x14\n\xf4YSZN\x8f\x91\xf6zV\xb4\xb0\x82\x11D\x9dN3\x07\x98\xd4\xa4p\x10O\xc8(/#\x81tov:n\xa1-\xa3\x18\x81$\xb2\xfd\x08\x01;\xa6\xacE\"\x98\xf4\xb1w\xc6(\xdf\xf6vFKb;l\xe2\n\x8dB3p4\x97\x9a\xd2\xd6\xbb1o\xf9\xa8\x8bG\x97oG\xddu\xdb\x83%\xf6&\x8d{\xf7\xae\x10\xdd\x8c\xc5\xfe\x06X\xbc9nUW\xbd\xd8vP\xa3\xcd\xd3\x88\xb7P\xbf\x02>[\x81\xd8\xf6\xebV@\"A\xf8\xf3V\x97\x83L\xe9\xa5N\x9dgp)\xdd\x1c\xa0\xda^\n \xc84<S l\xc4\xe5\xb6\xa6m\xef\x97m\xe2\x81\x8d\x9fIN\xb38Z\xdaQ\x83\xad\x0c;7\x07F\x90\xe8ma[[\xd6\x17\x01T\xb6\x8a\xb4\xe3\xaa\x86Y\xe8\xcf\xd5\xf7z~A\x02\x9c\x9e\xd8\xa0g\xbf\x06\xa6\x90\x1f\xb9MP\x85:\x9f\x00\xf10\x0f\x80\xb0\xba\x00\xe2\xd1\x9cj.\x0el\x83\xee3]\x1b\xa9\x1d\xd5\xdczk\xe9\xfa\x9d\xa4\xa9\x90\xc8\xa5\x9e\xcbV=\x00\"-u\xe2\xf4\xa6\xa2.\xe4~\x0e\xbb\xfb\xd2\xba\xc5v\xdc}\x0b\x1d\x88\xbb'5wJ3?\xf4\x82\xe0\xba\xad\xba=\xe3\xb7\xc4~\x1e\xc1\x9aJ\xc2\xe2\x0f\x83\xae=4\xddjk\x98\xdd\xca}q(\xab&\x8d\x96\xd7\xfc3\x8fRGT\x84\x95/R\xea\xf8\xab\xca2\xcb\x8f\xce\x9a\x8c\x8al\x94\xad\xf8\xc2\xe3\xe2 u6\x1a\x96\xf9\xae\xf2\x0b\xa2n\xc5\x7fD\x84?\xd8S\xb0\xf1\xb4\x06\x0f\xd3\xb85\x0e\xd2C0\xd5g\xe0\x86<\xd1\x97\xce\x9eV\xdcB\x87]\x82\x86\xed\xfc\xee\x7fX\\\xc68v\x88\x97$\xcd\xd7\xd2m\xe0\x19\xda\x83\xbd\x01\x8f=\xb7\xc3\xff\xdd-\xc7\xaa\xdb{\xc0\xff\xe5\xb1\xea\xf6x\xac\xba\xfd\x1e\xff\x97\x7f\xbf\xcf\xbf\xdf\xe7\xb1\xed\xf6\xf9\xf7\xfb\xfb\xfc_\xde\xce>og\x9f\xb7\xf3\x80\xb7\xf3\xa0\xcf\xff\xe5\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=x\xa4\x8d\x9d\xc7|j\xdb\xc0\xa2\x11\x8b*\xbeNQ\x1ep\x13\x8f\xe3#\x1e\xae\xb2J\x10\xe5J\xd1\x94\xa0\x17\xb0\x82xH\x06\xd1z`\x8b\xd9\xb5\xf71\x9eJ\x1e\x16#\x8f\x1dR!\x8fr\xa3M\x08\x9a3\xb4\xdc\xe4r|\xe6\xe2\x9c\xf3\xccPy\xa4\x9c\x8c\xf9\xe9\xc6\xf0\x142\xb3v\x80g\xb9\xeb\x14\x99\xa52\x8c\xa2\xe3Sj\xd2\xef\xf7w\xfb\xfd\xbe\xc3r\xf7\x8a;\x91\x13/\x9c\xf3K\x11R\x8e-\xbe\xf6\x02\x7f\n\x93hJ`E'c2\xab\xe4w\xd4\x04\x9e\xb0H\x9dp\x80\xb1~0B,\x8b\xe4\xd9\x01\xdb&\xb0=b\xe5\x0e<}\n\xfd\x1e\xca\x14\x7f\x84~o\xb0\x0b\x1d\x16\xffS\x97|\xcc\xb4'C\x9eSP\xcd\x9c\xbb\xe1\x8ek\xc22CT -\xa52`D\xec]\xb5\xc7\x03\x16;\xa3\x1b{W\\\x10\x8d\num\x1dnP\xcc\xf1\x18\x8e\x84\xf0\x14\xbc\xc7\x0edl]x\x08Z2\xf6:\x9d3\x07\xe3D\xdc\x87\x9eF\x8a\xb0\x8e\xa2,L\x0b\xe7\xac\x90\xcc\xbd\xd4_\x13U|\xe0\xc1\xf8\"x\xaa\x1ar\xf1\xc7\x8e\xe0\xe9\xd3\xa7#\xe8;\xdc\x9b\xb53B\xc3#zb2\x07\xd7\x90\xbdz\xac\xac\xd3\xef\xa7\x84\xdb\x948\x17 \xda\x9a6aQ\xb3n\x1b\x16\xb5\x9a6\xa2\x8eD\x97\xfa\xd0\xad\x00\xe2\x88o\xe7\x84r\x93\x1d\xea\xe6\xe1DM\x99/\xe2[\x10\xd6\x18\x97\xad \xac!\x15\x92(\xec\x84E\x0b%\xac\xf1g\x11\x07\x93dBW\xc5\x0b'\x8b(\xdeH2\xa9\xe5\x06\xf9b`\xd4z+\xf4\x96\xc4\xaaK\xec\xf9\xd9\xc3\xbf\xf0\xe7\x1b\x8d\xbd\xcd\xd0Y\x9b\x16\xfe\xf7\x05G\x1e\xf8\xe1\xe5\xdd\x8f\x9d\xb7\xfa\xc5G\x1f\x05\xd3\xbb\x1f\xfc\xef0\xf0\x99\xff\x91\xdc\xfd\xc8\xd3\xf4\xf7\x18z\x14\xa6\x93(\xf8\x12\xbb\x956MG/\x9a\xff\x82;\x96v\x95\xf8\xbf\x90/7 \xde\xfa\x17\x9c\x83\x9fz\x81?I6\x9aB\x9b\x19\xf8\xbf\x03\x16mLvZ\xc1\x1e\xc9\xfd\"&\xb3/\x0b\xf8d\xe9\x05\xc1F\xa3o3x\xd1\xea\x97\x06=}}\xb9\x19\xe2\xb7\x1a\xbeh\xf6\x8b\x8f?\xbb\xb8\xfb\xc1g\xbf\x07\xd5O\xb2\xd5\x17\x18\xf9\xea\x8eF\x1e\xda\xfb;\x8em-\xbdt\xb2\xb0\\\xe8\xd7\xd7\x96\xc62\xce\xebi\x15\x9dz\x88\x88GH\x02i\xddE\xa2/+\x1aP\xcf\x90\xe7_\x0b\xc7\xc4\x9c\xdaB2\x9b\xf7\xe1@\xd8\xd81\xcf\xa8!\x9a\xb7q}n\xe8\x8c\xc9\x99P\xd8\xc7\x95X\x1f\x10n\x9a\xd5\x9f\x03\x93\xeb\x14-\x17\x06\xb7\x00g\xecV\xdd.\xa0\x15D\xa3&\x88f%\x88\xc62D\xe3\x96\x10\x95\x04\x88\x18C\x95\xf9\x08T\xf6\x86\x832rX\xe8\xa5;\x03hB\xbc\xf8\xdf\xd0\xf3\xce\xa0\xb9\n\xfcT\x8b\x9c\x15\xcbI3\x98\xc4EFh\xf7wUc=\x10z\x8f\xeakv\xb9\x867eU\x8d\x885A\xe3\x14\xcb\xbb\xb8\x98X\x92\x89mYt\x8e\x1a\xa4is\x1d\x02\x92%\x9a\xd0\x01\xe8\x03\x01@\xd9\xd7f$\\\x8bx\x12\x9d\xdc\xceMM\x86\"\x7f\xbb\xe5\xcb\xa9\xd3\x8a\xa8x8:\xfdgkf\xc2\x9f\xb80\xc1p\xd3\x01\x0b\x8b_\xe7u\xbe`\xa1;\xfdy\x18\xc5\xe4\xc8\xc3`}\x96o\xc1\x90\x1ey\xd0\xa1e\xcb,H\xfd\xc0\x0f\xb1hY*\xcaB\x1f\xaf\xda\x0f\xc0\xcaJ\x05I\xeaO.\xaf\xe9\xfbk\xfe\xde<\x84i\xbd\xd3\xfb\xba\xbc\x9a\xb4\xb3\xdd\xc1\xa3\xddG\xfb\x0f\x06\x8f\xf6\xd0\x8e\xff\xe9\xd3\xa7u\x0d`4\xd9b\xbf\xa7\xdd\x04\x83\x9c\xbb\xb0\x80\x0eXs\x93\x85\x00\xaa\xfaX\xf0\xaa\xb8\xdc\x02\xbb\xcb\xbc\xe6\xed\xd0F\xfe`\x1fl\xfd\xf0C\xe2X.,t\xd7\xd0\xf9\x83\x0e\xec\xd7\x0c\x17y\xc0\xce-\xdb\x9e`(1\xd4*C\x07\x92q\xef,\xc7\xf0\xa70E\xad\xe1\x8aG3\xe1*\xa4\xa9+>p\x1c\x17\xb6\xd0h\xbf\xa4\xe0\xc2\xc4\x1f\xbd\xb3\xfc\xe2-v\xebY\x9f\xd2\x83S\x0f0\xd0\x00\x04\xf0\xa4\xaa\xe4\xde\x86\xc1c\x08:\x1dG^\x99B\xa3\x16\xa0\x15\xaf\x8d?FZ\xe5w\xe9\xb9q\xdc\xea\xe098\x9e\x141\x15\xf1\xf2\x9f9\x00\xad\xe8\x07\x0c\x12}\x87g\x89\x90\xc0\xc6b\xc5O\\X\xe5\xad\x8e`\xed8\x8f\x1d\xb8\xee\x06^\x92\xbe\xc4\xb6\xf1>\x83\xf7s\xef\x9e\\\xa4\xc6\xf4\x16\x0f\xdf\x8cSv%S\x84\xf5\xde\x9a\xb1\x06(\xc9\xc4,<\x9f>\x01_1\x96\x93G]>:\xe8bp\xb0\x86\x03X\xf1\xb2\x9e\x0bk\xfc\xa42\x02\xc5,\x99\xb9*X=A\x1a\x85\n\xb3\xe7H\x10\xb3[Q\xb6\xf2\x99\xa9\x92+8\x80\xf1\x19\x0c\x05\x0d\xcau\xb1\xaa\x14\xa8\xd7iK,\x82\x81\xe5\xba\x05Su+>@b\xaa\xc2\x82\xa9\x8a+LU\xa8c\xaa\xe2M\xd9\x80z\xe5|f\x87\xf6\xe0a_U3\xfb\xbchg0P\x8b\"^\xb4\xd7\x7fHIL^&\xc6\x80A\xf1\xf5\\\x1a.f\xda=?'\xc9\xabh\x9a\x05\x18G\x1e\x86\x9a\xa5\x98\x92\x99\x97\x05\xe9P\xbd\x9f\xff\xa7\xea/q\xd2\x8e\xfd.\xff\xca\x85\xa8\xf8i\xa46|L\xd5\xbe'\xd1r\x15\x85\x94\x80\xe8F\x06\x98{B\xf8.}\xe3]GYJ\x17\x8fw\xd8\xb4Y\x8a H\xa8\"_Ny\xb7_S}\x8eW\xe2\x82U@\xbcr\x0b\xc2\x03\xc7\xcb\xe1\xea\x9d*\x9aLl\xca\xf9=\xd4\xa1 \x16\xed\xf5th\xc2\x8a*\xc8\x95\xe5E;j\x91\x97\x17\xed\xabEI^\xf4@>\xda\xf0\xd5\xfe\x9e\x1e\x15'\xbf?*\xcej/\x18\xf3\x91\x91:\xc1\x9f\xd2\xde\x1c\x9b\x1dN\xe8\x88\xe3bA\xa6\x16\xd8\xa4{~\x8e\xce\xe7\xe7\xe7\xc8&\xf4\xdc\x02\x1f\x1d\x9b8\x0e?\xadX\xf5\xfcxTE\x0c\x1d\x98h[\x9e\xd4\x96\x0b)\x1fFTz;\xae\xce\xe5\x92\\\x0f\xc1\x8aI8%\xb1\xe6\xa6\x94\xe3]#3\xb0\x96\xf3c\xac\xe2he\x88?\x03\"UFwN\xd2#\xb1\x85\xcduYd\xf0dE&,!P\x14\xd74\x1c\xb3\xd0\x1fq\xdc\xa2.\xdd\x13\xc4\xb6\x8e\xa20\xf5\xfc\x90T\x1cn\xe4'buO\xa2\xab\xbaZ\x99h1\xa8\xab\xe5\xb1Z\x18\xb57\xb10\x9c\xa9\xb9\xf2\x84U~\x17\xad.\xbc\xb8\xa9\xf2\x8cU~\xe6%\x9c\xde5}\x10\xb0\x0f\xa2\x90r\xeb\x1f\xbc\xc0\x9fzi\x14?\xf3\xa6s\xd2\xf4)&t\xe8\x06\x917\xf5\xc3\xf9i\xea\xa5Y\xa2F\xb2\x97\x9f\x05z/S~\x89\xdd\x9f7\xb0\xf7\x94GZP\x04\xb1\xad%I\x12oN\x90+\xb24J\x01(6A\"P\x9d;T\xf2\xdcQ\xb6o\xf2\x94\xa4\xcf$\xf0\x92\xe4\xb5\xb7$C\xb0\x92+o>'\xf1v\xe6[\xda\xfa7.L\xe0\xc0\xd8\xcf\xc4\xc5$l\x0eO\xc6\xe6\x82\xc5\xe1c!_\xb4b|\xaa\xfe[\xcc\xed\xddv\x9c~8\x8b\x8c#\xbc\x93\x1e\xf8\xc0\xb7'\xf9\xee\xf8=\xba3t\xe2`\xf8\xb7\x99\xe7\x07d\xfa\xaf\x12\x94\x8b\xdd\xd6\xbd\xa5~\x1a\x10c\x0f\xd6\x0b\x04\"\xa4\x11\xd0a\xc1\xe1\xdb\x97\x80l\x88Oi{\xd7r\xcc\x83\xf08rKkq\x84\xae\x95_dE\xcc\xe4\x013A\x9b\x18>\xf1,\xbd\x8f\xdf\xfa\xd3t1\x04\xeb\xe1\xc3\xde\xeacM{\xacz<\xf7\xc3o\xc8,\x1d\x82\xe5ei]\xffE\xfd\x13\x7f\xbeh\xf9AJ>\xa6\x87\x81?\x0f\x87`M\xd0\xdf_\xbfDP9\xdf\xf3\xb7\xff\n\xb01&\xcb(%\x85\xc7n#NZ+\xcb\xe5\xa4v\x8a\x88\xb9\xb5B\xe5_\x92MD,\x8c\x06\xcc\x9cq\xac6\xf7\x11\x89\x1eL\x15\xb2\xa6\nA\xbes\xaa:\x0dE\xea8+\x85H\xba\xb1\x8b&sNIb\xa9\x89(m\x1bl\x8a\x8a\x90;\x15\x8f\xa5\x81\xd3\xd5\xe6Am\xd3\xa2d\xdc\xa7\xcf\xff\xd6\xdf\x91\xad\x96\xa9p\xf2\xc8\xb1\xadrGV\xb3\xf4g\xe6\xd4\xa5J\xbe\x92\x86\x14\xe06\x17o\x83\x87{\x1a\xc1J\x02\x93^\x1ely\x01\x12\xabb\x9f\xa8^\x8c\xb3\xcd0\x8ba\xf5U\xeb\xce\xc2\xabk\x8b\na\x94\\\xb3qWvmy$C\\\x1d\xa7;\xdb\x10b2\x10*\xed3\x89\x8c\x02U\xbd\x8d($\xbaas\x0e\xb6\xca\"=b\x0ey\x0f\xf7\xaa\xfew\xbd}\xa7;\x93\xfd\xe8\xdb\xb4\xd8r\x12\xaa\x01\xeb\xe7Mb\xf0\x88\xbb!>\xe2n\x86|V\x83G\x0ft\x9b\xf4\xf4zy\x11\x05m\x9an\xb2\xf34\xd8\xe1\xaa;\x98\xdby\x1a\xbc\xad\x0d\xce\xd6\x03\xb5q>\xfeG}\xa7\xfb\xf5\xf1\xf7\xe5\xb2 /S>\xe1\xa9\xe5\xd4\x1eXj\xb9G\xeaxXn\xb9=\xf55\xcf-\xa7\xbc\x9d\xe6HR~\xbf\xe6\xefU4\xbd\xe6#T=\xe4\xe6\xfc\xbd:F\x9eV\xae\x82\xed\xec\xb5\x1a\xfe\x92\xa5\x94\x1b\xe83\xcaU\xb0\xed#\x9b\xa8\x1a\xfb\xee\x94\x81E\x95\xd6\x8e\xf9\x08\xd5\xea\x87|U\xd5N\xdf\xb0\xf7j\xf5\x9f\xf0u\xc5\x0d\xf5\x12Fp\xa8\xe6\x90{ #x\xa3\xbe|\x85i\xe1\x94\x97\xefP\x1ed\x18].9\xc2\x92\xbf\x9c\xbey]~\xff\x16FpD\x8f\xf2\xa3n\x82\xaaW\x7fv]\xaeqB\x05G\xdb:_\xf8\xd3) U\x11\xfc5+M\xa3\xb7\xb1\xbf\xf4\x99\xadv\xb9\xc67\xe8\x00\xa6\xcd\xb9_\xae\xf8\x9c\x92{\xdbJp\xf4\xdb1\x99\xfbI\x1a_\xab\xcd\xfd\"\xd7\xaa\xa4\xb9|\xc1J\xa3\xd5\xb6\xa1\xc2{M\x12\xf3r\x8dg\xa6\xf8\x01\xef\xca\xf5~F\x88\xfe\x955V.\xfa\x1eF\xb0\xf53F\x0e\xffY\xca\x08\xa0\xfc\xdd\x9d\xf9\xe1\xf4h\xe1\x07\xd3\xf2\xd7\xdf\x02\x8f\xf18\xa9w\x8d\xe3G\xdf\x03\xd8\x1a\xc1\xa9\xfd\xd2\xfe\xfb\x0d7\x0f\xd33\x91\xed\xe2\xb1@\xd1\xf0K\xd9\xe4\xac^0\xe0\xda\xac\x07\xc6J7N\xd7\xd3\x16V\xd9\xf2\x1bG\xad{\xe3\xc8\xd1\x0f\x0c\x8c\x00H\xa4\xf8\xd2~\xaf\xbf\x9dE\xd7\xd5) HJ\xe0\xfd\x98\x9c\xb9t\x92\xbc=\x1e8,\xc5;\x8a\xf7\xf4\xe7Kl\xa6\x12 \xf9\x06\x86\xf0\xb2\xbcd\x1fj\xb5\x9e \xd9\xd0\xff\xc2|\x0dO\xedw\x05\"\x98\x0d\xd8 K\xa5\x9bV\"|\x96\xbb\xff\x1aF\xf0\x8c\x8e\x98o\x8b\x12\xd6v\xc5\x91]\x02b\x0dBi\x1aI+\x00h\xd5R)\n\xf3\xbb\xba\x19|\xd5\x82\xd5+5<\x12\x8b\xf4\x95\xfd\"_\xc0%\x8b\xf2\x0f#\xb8\xe2\x19\x8d\xe8;Z\xe2\xdb\xbf\xe0\x9d\xdb\x01\xc6c\xc8 \x10f\xe4\xa3\xfd\x9d\xb0\xbc\x93\xe3\x93\xb31a\xb7\xa6\xe2\xf7\x88\xe7\xa8\xc0E\x0bM\x1b\xa1hr\x08\x1f\xed\x1e&\xb6\xd0a6\x0c\x8b\x0e?}b\xd8w\xe2\xc2G\xbb\x8fyv)\x7fR\xf4K\x87\xffm\x0e\x0d\xfa\xed\xcb*_\x0bU`\xfe\xa1\xcd]\xe3R\xeb8\x91;\x93\x87\xcca\xfc\x9a'\x82#th>K}\xc2\xa21\x8a|\xdf\x11<\x05\xff\xb1\x03_\xd9)\x83R<\xf61n\x00\x19\x87\xba\x10\x96b\x05\xeb&\xf0\xe7\xd6\xdb\xe9\x9b\xd2](.|\xcaRY\x19{\xde\xc2\xda\x05\x02!j\xb0\xbc\xa3[>E\xa6\x94\x19\x04\xd8[6#\xd9\x85\x0b'\xff\xf3\x17\xf1[\x94p\xecY\xf8 ]\xbc\xf4\x0c\x0b\xd5k\xd9\xf2\x14\xff\xd2f\x8d\xfc\x19s\xdc\xbd\xd0\xe0\xb5\xa0S\xf9\x90\x08\x1f\xd2\x0b\x16bY\x8f\xa7\xc2n\xe6\xd2\xae\xb1_\x11\x80\n\xab\x8dW\xb6\xca\xa7O\xca\x8e\xe2x[\x8d$sS\x07\x8e\xbf5\xae\xb8\x1a\xee\xe2\x95}\xc1\x9c\xa0c\x1e\xc1 \xe2\x11\x0c\xba\xa5\xdc\x8fl\xf4\x94\xd9b) qe(e;\xc9\x7f%,T#\x0bDa\xc6\x9b\xb8n\xfc\xdfm<~N\xc2\xd8\xf8_a\xe0\xa1\x170\x04>\xa9\x88OJ\x84\xee(&\x95=v\xc4\x9a\xe0f\xcb\xc4\xacB\x8e\xc1\xef\xc5jElJ\xbf\x8cI\xcd>\x8c\xca\xb3*\xea=\xc3\xa5\xf5l\xfb]]\x14,\xc4P\xba\x9ddB_\x0d\x99n1\x96\xb4\x88\x0f\"\xe5(\xaeDN\x17W^+\x9d\xcfX\xaf\xe43\xd6\x93\xbc:\xdd\xca\x14\x89\x94\xd3\x01\xc9\x19\xa9\xac4\xca=\x04\x9b\xf4E)K\xc4\xffOr\xd3\x87\x98\xb4\xe8/.\x15Q`\x04_a\xc4\xa1\xbd]\x07\xff:\xc6\xff\xff\x8d\xbe\xdb\xe7\xaf\xfe\x8c\x15z\x0f\xd9_\xdf\xf1\xf4\x97[\xa1\xfd\xf0!\x02\xd5\xa3\xb3\xb7t\xe2\x82\xe5\xd2\x8f\x91\xbcL\xbb\xf5\x17\xcd|\xbc\x1f\xecEIuE\xc7\x9b\xd9\x19&B\xca0\x11R\xc6T:\xcfTh3\x84\x1dJ\\\x8bl\x17\x90o\xe6\xbfRaa\xe1%/9\xfa\xbb~r\x14\x85\x13/=]\xc5\xc4\x9b\xa2\x90#\xf8/\x17\xcd\xce]n\n\xe623_\x97\x87rt\xd1x\xc8\x95\xe4(W\xac\xcb;o\xee\xca\x99\xfd\xb9\x9d\x91\xe5Z\xf4\x18H\x19\x85\xf8k\xb1E\xd2\xf4\xb1\x03\x0b\xfb\xaf\xe34-'\xbd-HP\x8a\xd9J\x16\xdd$\x8dbB\xa95o\x85\xa4E3!mfm\x93t\x1c*\xedP\x08\x9e\x96`\xc7\xf7w5\xa0Q\x14\xb7d\x15}\xfb9=\xd3:#4^<\x80\xe7tO\x0d\xd9?\xa3j\xea]\x85\xfc^\x92\xeb\x17\xcd]\xa19\xe7\xd7h\xceY\x9b\xd3\xc1\x03\xc6\x01W(\x13\x94\xc3\xed\xf8!<\xd7\xdb\xd3\xd1\x9e\x9e#\x177\x92\xe3\xbb\xd72\xf1YBNI\x9a\x92\xb8AJ\xfb^\x17I\xb2\xd2\x92\xbf\\\x05M\xf6\x05\xdf\x97\xb3\xd7\x01\x94\xf5\xba\xaen\xa1\x0d:O\xa6\x9ao\x91\xca\xaej\xe2F\x99\xf0S\x1b\x93\x96\xfd\xc1>e\x9cN\xedb\xab\xfa\xd5\xafj\x8a}\x92\x0c\xe1\x0f\xe5\ns\x92\xbe\xb9\n\xc5\xf7\xcfI2\x89\xfdUJ\xd1\xe7/u\x15_{K\xda\xd8\xdf\xea\xea\xb0m\x90\x0c\xe1\xbb\x12\x1cQ\xc1R\x06\xa6\xbd\x85\x07l\x8d\x88/\x8e\xc1wjxL!\xa6\x8d\xc3,\x08\xce0\xfe\xcd[[p\x9d\xd6\xdfo\xf8\x9b*\xec\xbd\x8a\x11\x8f\xf2 [\\\x85b:.X\x7f9}\xf3Z\xe3@\xce\xf5EM\xfb\xae\xc4\xfap\x86-=\xe3Y\xe4\x1f\xebb7P\x81\x82sd\xc5a\xef\xebSx\xf3<\xaf\x9c\x1d\xea\x9f\xb9`\x9f\xdb\x95\x94?\x9c\xc1\xffZ6\xe6\x9e\xf3j6i\xc3\x8c\x8b\xbe\xb4\xba!\x16\x1a\x08\xf9\xcc\x8au\xa6\xe3\xd2~\x89c \x03\xc0\x91\x84\x8e\x9dN\xc3\x85\xb7\xdc`\xe9\xa8\xaaz(\xa1\x95\xa4B\x18\xbfFV<\xb4\x07\xfb\x8e\xacZp\xe1u\xa9\x1eK\xc2\xf2f\x86\xd9\xe4\xde\x15\x84\x1b\xff~\xe5\xa5\x0b\x17,\xfa\x0f\xb7S\x81\xc0\xe6J\xc3\x1c\x07\xb6z\xad4\xff\xd2\x0d\xd6\x9ec[K\x92z\xba\xd0\xbb\x1a\xe5m\xa4\xd7\x9a\x8b`\xa4\x8e\xaa\xf3\xf4\xaav\xebI\xa1\xe4\xf3\x93\xe3\x8f) \x13\x9f\xca&\x9f>\xd5\x13D!\xf8\xd4R\xd7 \xa5\x9a\xa8]o\xa5\x9eK\xec\\\xddH\xd6$L\xf9p\xa20\xb1\xa9\xc0\xaf\xec\xc7rW\xf5<\x0e\xe0Q\x9c\xa2\xf7\x91I\xdaC\xb5\x9c\xbe\x90>\xfe\x10\xac7\x16t\xa0\xd3\xf1\xaa\xbc\xa4x\xae\x86j\xb0Z\xf1\xe8\xb4wu\xb0\x0b\x94\x1cR\xd5\x91}}\xfc\xbd68\xf9\xeb\xe3\xe3\xe7C\xd8\xeaWKf^\x92~M\xae[\x9c=\xa0u\xe9\xd0\xa9\xbb\xb85$s$e\x86Fr\x99u\x8a\xde\x14o\xd1\xcd\xc2\x90C\x81e\x01\xc0\xe51J\xe3y\xbd\xa44\xa0\x17\x06{\xac\xbcz\xe1\xb9b\x1d\xd7\xd4\x9d\xa9\\\x93x\xf4\x8b)x\xfcq|\xd6\xad\xe6\xce\xd7\x84p\x9b\x93\xf4[\xe2]n\x02\xf9[\x01dK\x1f\xe3\xa5\xa8M\x8c\x11\xab\xe5\xe73\xc0q\xd5\x06\x1cQ\xf8\"&\xe4\x97\xc6d\x82P4>\xa1\xc7F\xd0\xa5\xc8\x8d\xe6\x146?\xa68\x98\xe8\xef\x19rD\xed\x0c\xab[\xd3\xe4\xca\xbd\x93\x08\x19\xa4'\xc6\xfb\xa6\xe4G\xe6\x89\n\x05]\xac\xcd\xd4\x16\xb2\xc0\xba\xe5\xb5\xc2\x83\xbc\xbaB9\xf7\x90\xb9\xfc2\x94\x02\x84\xf6\x1eug,\xa1J\xef1x\x05\xf30y\xec@\x92g.\xa7\xe7\x867\x9e\xa0\x96\x04\xe5{\xe4*2=O%\x19\x89l\x06\xd0\x87\xfb\x06\x08\xb1\x08\xef~\xc2RY\xc9\x07\x90If\xb5\xb0*\x92\x9c\xd8\xbe}\xa6\xab\xca\xed'_\xe2\xbd\xea \x1a\xb1\x1b:!oV\xcf]+b\\\xbfD\x06\xaf\xfcp\x1a]Q\x88\x16\xbf\ns\x17\x95m\x86\x83\x9aB\x9b\xb5@\x05\x80\xb1\xce+\xa0\x9d\xa8\x8f\x81v\xad1\x1b)|\x8bM\x9e\xe1\x88\xf3Di\x8d\x17 \xe6\xbc7\xb9\x94\xaa!!\xcd\xf9\xe3\xc5\x10\xb9kQ\xa3\xbd\x92\xcdS8\x97\xedn\xf4\x08\xe0\xc0\xdf\x1b-\"\xfa\xbd\x07\x8emy\xc9u8y\xb9\x91\xfd\x86\xf8\x94%GA\x1dL\xab\xef\xda\xd9}<\xba[\xbb\x8f\x9d^\xaf\xc6\x08+\xf9\x0c#\xac\xaa1\x90Y\x12.\xf73\xc4q\xf51\xa7U1\x9fV0\x94\xb6\xb2J\x95}\xbd5D\xd4F\x8c\xa1T\xd6G\x12\xba\x15S\xf9\xe7\xde=4\xa3+\x07v.\x14#\x84eCe\x11\xd9\x12\x92\x82\x97@.Ml\xa9\xe1\x18\xf44\xb0\x02\xa0!h\x17\x05e1+w\xe6\xb0\xc0\x0f\xe1\xef7\xd5\xbb_m\xca\x1b\xf3\xde\xb5\xf9\"R\xd1\xe8\x05o I\x82\xcb\x0d6\xba3\xbbb\x12\x00\xd28XF2\x188\x0e\x1d\xc0\xf8\x8c\xdf\xc5(Yf\x91l\xdf\x86:\x10}f\x8a*W\xc2\xc9\x88\x0c\x0d\xa3V[(\x95Y%\x96\x0f5\x95\x1ceF\x10\xc2\x90\xe5\xc0 \xdb\xf0\x17h]\xb0\xd5wL\xfa\xf6\xc9\x82L.\x87\xd2uB\xabM\xdb\x8aN\xecT\"\xe2}.\x9d\xd8\xfdlKD\xc3!\x14s\x1bUVg\xb3\x81\xdd\x8e\xdc\x08\xc5\x1bZ*\x15\x1d\xb6\xa20M\xf6l\xbb\x06\xdb\xd3==\x97\xb8S\xb1\xf2b2\xfbN_\xb5\xf2bl\xdc\x8e\xfa:\xe1\xd5u\xe9\x89\xe9{\xb5\xf9\x19\x7f\xaf\x0e'\xe0\xcd\xab8\xba\xc2Li%+\xe2r\x85\x85T\xe1\x857I\xa3X\xb1\x85\x9a\xb2\nA\x14\xea\x1bXW\xe3@\\7\xca\xf0mn\xc4\xe7Za\x19\x8d\x87b\x12\x9aD\xfc\xa5\xb7\x1aB\xd4]z+\xbdp?\x8b\xe2co\xb2\xa0u\xf8O}\xbdI\x94\x85):\x1e\xd3\x1f\xfa:i\x84\x04\x90\xd6\xe2?\xf5\xf5\xa20\xb8\x1e\x82&\xe7Y\xb5zn\x9c=\x04\xbf[\xe3\xd3\xf66\x8bI\xa9n\xe9E\xb5~ \x03\x86\xa0\x01\x8e\xbc\xc2C\x98V+\xf8 \xfau\xe5U\xbcn\xf9\x8df\x90q\xb4\xa2\xc7j2\x04\x8d\xf7\x1c\x1b\xd2Q\xe0%\xc9\x10f\xa6r\x8e\x93C\xd0\xac\x13\xab\xf1\xca\xff\xe8\x87C\xd0\xc0\xfe\xf9\x9bWC\xc8\xaa\xef\xd7$N\xfc(\x1c\xc2\xa4Zv~\x9e\xe05\xd6\x10\xd6e\xe4\xd4S\xc8V\xa99\xea\x89\x8e\xacQ3\xf4\x12\x7f~/\x94V\xe9y\xaa\nM\xe2\x02\xb0\x81\xb2\xf5T\x0e\x96\xa5\x13M\xaf\xa2C\xae\xb6~\x1bE\x81\x9a\x8e\x14g\xd1\x9dEY\\W\x8bR\xbd\xfb?\xdc\xef\xdc\x9f\xeb\\{gFA\xc8\xb6,\xe8@\xea\x94\x82\xbd\xff\xe1\xde}K>\x8f\xaa\x0d\x06\xdas\x0d/|i\x1df\x85\x86\x7fN\xa20e\xb9\xb9H\xfe&c7\x88\xb5=\xact\x0b\x05\xd2\xb2\xa4\xd8\x93f\xb3a\x19\xefV\x91\xdb\x99l\xe7c\xc3)\x1b\x88\x9c?]7\x8e\x85\x18\x87\x86\x93\xc4\xe9\xc4$a\xde\x1fb\xc6\x97\xe4\xfamLf\xfeGi\xce\x1c(a\x05(\xf1F@\x996\x03\x85\x0d\xa7\n\x96\x0cK\xf3\xb1U+x50Md\x98j\xa8 ;\xe8(l\x13\x05\xb6\xe5\x05(\xe97\xec \x95\xb1\xd7\x14\xe3b\x84o\xd4M\x17^z\x82\x88\x99\x08d\x17\x8e\x9c\xb05b\n0\xdbW\xa8'm\x87\xbe\x9f\xa0\x9a\x08\x89\xf1a8=a\xf8\xfc5\xb9\xa6\x1dd\xd0\x01{kB\xe7\xcf,yP\xb9C\xff\xc2\xe4\xf2\xf8\xeb\x00,\x0b\x860\xb3\xf1O\x87\x8a2\xf7Qg\x1b\xa2\xe1\x10S\x05M\x9cztYK\xe8\xe2V#g\xacy\xd4\x0c\xd5\x89V\xcc\x90\xdd\x0c\xa1hf\x87b\x08U\x83\x17\xbaV\xe8\x9a\x8b\xa4`j\x13\x8c\x8c\x81\x1d\x96+\xa3\xc6\x7f\xea\x82\xe7\xb8\xb0\xe8\xc6$ ^Bl\xaf~\x0e\xd7&,\xe34\x83\x0eVj@\xfc\n\xa4\x8b\xa3)\x11\x06;u\xf6@\xa5\xad\x81\xee[\xca\xee(\xbd\xacl\x10\xba(\xdetJa\xe0\x87\xf3w\x91\x1d\x88\x89\xdej \xf9F\x96z\x95\xf7\xb2\xf4\xfa\x0e\xc7\xbcp!Q\x04\x8c*\xfb\x96\xb3^u\xa7\x98xP3J\xf1\xa9dM\xa0\xb9x\x10D#(c\x92.\xc9:\xe2\xd1\nS\x17@\x90\xe3\x91z\xdfX\xa6\x0c\xc8O~\x91\x01\xeb\"p S\x01\x9b]q\xb1U\x10\xa6\xda\x0d\xc3|\x19\xa6\xd1\xb7~\xba\xf8Z\xac\xf6\xcb0%q\xe8\x05CX+\xc7,\xe3m\x1b\xf5&B\x87G+\\s\xd7\xc3\xbaA\xe4\xfcp=\xf3/\xf4\xe4M\x00 \x02\x00z\x92Z1\x10/\xf0\xf3\x8b\xf1j\xa1\xbd\xaf\xd31\xdb\xa1M%\xaf\x86y\x0b\xc3\xc1\xae\xd0\xa0Pl\xad (\x07\x12\xac\xaa\xdf\xad\xa2\x95)\xf3\xb5\xc0=\xdc\xbd<\x12|\x15^P\xa7p \xc9\x15~_1B\xaa\xd5\xbfi\x95T\xb2\xc2\x08\x0d\x0f?}\x82\xd8\xb6\x06{h\xcb%\xd16\xdbq5\xf3\xe4w\x1cOx8\x90(\nN\xfd_\x880>V`B\x0f\xb7z\xb3\xa9\x0c\x934\x97^yZAS\xa6o-\xf6\nH\x96\xc6\x86\xebQ\x01\xda\xd2\x98\xb9\xd1kXP/\xb4\xeb\xf8\xf4 2\xfa6\x9f/3:\xce\xff\x1c\xb1\x8cp\xa1\xa0b0\xa2g\xa7\xc6\x02\xb9\xca\xe7P\xce\xa2\xc4\x83\x0fU\x80\xd0\xa7\xc2\xcf\xb7\x84\xc1m\x90\x1cd\xd8m\x82\xe8\xa0Cv\x11\xa8P\x07\x0e\xd0\xe2<\xe8\xf0\xbeb\x92\x05zp\xa6\x8b\x98T\x00\xda\xe6\xc0\x80\xcf\x84V|'\xd0\x8a\x19\xb4tG\x8cx\xda\x03\xac\xe2\xa5\x01z\x98U\xe5\xc0*\xc8\x0c:o\xf8L\xa8\xf9w\x025?\x87\x1a\xe3&\xaa\xb6\x03\xb0)\xe0*\x86O\xd5\x16\x0c\xe7\xdag\xc4\x0fk>\xd7\xfa\x05\x1f\x15?f${\x1f^\xd7\n\xb3\xe5\x05\x89\xe57\x05Ty\x17\xa4\xfb\x87?\xf0\x91\xd1wE\xfe\xf4\x99\xcd8V\xcb\xca\x93\x87y\xd0\x81 \x9dp\x0f\xc5`\xc7\x05\x8d\xc5\n\x9dqM8\xd65\x8a\x9bR\x93CLd\x93\xe8\xa1R\x96\xd0\x89\xc6\x1f\x01d+\x8bkfOq\x0dO\xf2$<\x8f\xe1\xba\xd3q`\n\x9d\x11\xa4\xf6\x8a\x9e\xc9\xe3\xeb3\x17\xd68\x97\x95\x0b\xd7\x0e_\xbd\xea\x0808\xa6\x99C\x98\xb3,\xa5\x06rC\x87?o\"bK\x17\xdd\xc0\xe7\x9c\xbb\xab\xa1\\\xd8\x1c\xbb\xe8\xec\x920\x8d}\x92\xe8\x81!\x9e\x1c(\x17\x0c([\xf6\x12Fp\x8e\xa9\xe9m\xc7\xe9N\xa3\x90<.\x01f\xc9\x0c,%\xd8\\t:f\xe8\x88\x87B\xa9y$\xc6\x01\x98\x01$\x1e:\x89\xabb|\xe6\x91\x88\x07\x0d:lifWhZ\xbbF\x03fN.\xae\xc6\xbd3\x87\"\x9e\x98kO\xcc\xb4\x1e\xac\x06[B\x86+\xb8\x91K[\xac \x01>\x1a\x92\x91\xc9\xcfi\x11+\xba\x0eCb\xdb\xda\xe9[naG\xc2n\xdd\xce\xd8HN\xe1@\xec~\xb8\xf2\xd3\x05\\\x92\xeb\x04\xfenAG\xdcg\xd3\x176qx\x9a[\x17P\xd9d\xddX0\x84S\x17>\xb65?3J\"\xd3R\xc1\x0d\xa5\xb8\x96\xa5\xf2\x1a\xadn\x1b\xeb\x8f@\xad\x8d3\xf7\xe1\xbaw\x8f\xff\xca\x1d\x8b\xabg\xa5\xf5/\xff\x92\x07\n\xd1\x9f\xd3f9)\x97\xf2\x80\xc5\xcdEg\xc3\x18\xcd\x9b\xd3\xb1\xafZ\x80\x1b-\xb2\x89\xc6\xdc\xfa\x0e S\x1e+\xdb\x08me|=\x1a[#k\x08\xd6\xa8g\xc0`k\x88\xc5\x83j\xb8\xa7\x1b\xa3\xc6\xc0\xfa\x03\xc5\xc9\xcaE\xc0\xfd\xf1hxv\x7f\xde$\x9aK\x0d\x91qzV\xed\xb7^\xa6\x0c\xef\x06(=\x9c\xb6 (\xa3\x01-\x1en\x02\x14\x06\x0e\xdb\xea\xb2\xcd\x9c\x8e{\xe8\xe8Ma\xc5\xfe\xee\x9f\xa1\x8dD\x92]0.\xc0\x1e\xd0#Z~\xd1w\x1c \x9a\xf6\xa8\xf7i4p\xee\x1e\xa0\x05\xbe\xea\xf7\xce\xdd\xdc\x80\x0d\x9c\xba\x9bn_\xaf\x07\x18R\x12Y\xb1\xe4\xc7\xa2\x8b\x8b\x98\x95^\\h\x83~z\xd3iL\x92\x84\xd5a\xbf\xb5\xd5b\xc2{\x89\x89\xbe\xa38\xf5'\x01\xe1u\xf0\xb7\xb6Z\xe2Oy%\xfaK[%\x9b\xfa\x11\xabB\x7f\xe9\xaa\\`\xf1\x85\xb6\xc8KX\xfb\xf4\x87\xb6\xc2\xd4g\xe5S__\x1c\xf1b}\xcf\xfe\x9c\x15\xfbsmq\x10M.\x7f\xce\xa2\x94\x8f!\xffS[9\x9a^\xb3j\xd1\xb4\x12P\x05+\xb0\xa5\xd3/\xdcE\x96\xa6Q\xc8*\xe0O]\xa5\x89\x17\xae=\xb6\xb8\xec\xa7\xbe\xd2*\xf5yS\xfc\xb7\xb6\x9a\xcfgE\x7fh+D|i\xe9\x0f}\x85\x80\x97kc\xc6N\xa2`\x1eG\xd9J\xd4\xc1?t\x15\xa7^\xca\x90\x91\xfe0U\x08\xfc$\xcd+\xd1?\xb4\x15\xa7\xac\xcaT[H\xd8p\xa7D;\xdc)I=?Hx\x15\xfc\xad\xad6c\x90\x9d\xce\xb4P\x9d\xfa^\x101\x9cb?\xf5\x95\xd6\xbc\xc6Z[\xcc\xc7\xa9\x1f&\x87\x82v\xfed\x89\x85d\xa9/\xbc S^~A\xb4 \x9a\xf9$\x98\xa2\xe9`l[\xe2\x0f}\xc5\xb9\x8cf\xc5\x9f\x86\xcaYLD\xc5,\xd6\"\xd3,\x8a\xd0+\x93V\xc2\x9f\xfaJ\xf1\x92W\x89\xb5s\\\xf4\xb1x\xd1\xd7\x16\x0eX\xe1@[\xb8\xc3\nw\xb4\x85\xbb\xacpW[\xb8\xc7\n\xf7\xb4\x85\xfb\xacp_[\x88V\x1f\xb4\x98x\xda\xf5\xa0\xef9P\xd8Om\xa5b\x97-\x8c{l\xc1[\xd1\xb7\x90.\x19\xca\xd1\x1f\xba\n\x8c\xc4j \xac?\x8b1\\&-\xc7\x9f\xdaJK\xb6%\xfc\xa5v?\xf8\xe1*c8\x87\xbf\xf4U\x12^A\xbb+//\x18 //\xb4p\xbc$\xd7s\xc2P\x95\xfd\xd4U\n\xbc\x0bN!\xf0\x97\xb6\n\x99\x93\x90\xf5\xc4~j+1h\x05Zp\x05~x\xc9\x8b\xc3K]\x85\xa5\xe7\xb3\x81\xd2\x1f\xfa\n+^\xae]\xe8\xa5\x17_\xf2\xf2X\xdf\x01 3V\x81\x84\x99\xa9\x82\x9frR\"\xfe\xd0W\xe4t[\xe7w\xc8+p\xec\xc5_\xba*\xa1\xc7Ha\xe8iIa\x181\xbfaV\x87\xff\xa1\xab\xc8\x04F\xac\xc6\xc5Z]%\xb6\xbc\xfa\xe3*Z\xa5\xc5F\x12\x7f\x18*\n\xba\x17\x19i^\x94\xa5\x02\xa7\xd9O]%\xd6\x97\xb6\x93\x95\x17{l\x05\xf0\x97\xb6\x8a?I\x05]\xe5\xbf\xb5\xd5D\x15Sq4\xcf9F\xf1\x87\xae\xe2\xcfX\xe3g]Q\xcc&\x12kg\x123(\xc4Z\x08\xc4\xd9\x05\xe3\x99\xe8\x0f]\x056.\xed\x80\x12o\xc9\xfa\xa5?\xb4\x15\n\xd41#NB&\xf9r\xf2\xdf\xfaj\x81\xc0/\xf6S[i\xe9\x05\x0c\xc5X\nN]\x15L\xa3\xc4\xea\xe0Om\xa5\x95\xc7\x07\xb4\xf2\xf4\xa3I\xe3(d$\x95\xfd\xd4W\xba\xe6\x0c<\xfe\xd2V\xc9\x18\xeb\x9ddZ\xe6;\xc9\x96K/\xbe\xe6U\xf0\xb7\xbe\x1a_\x07\xfd~IY\x1c\x95\xd8\xb6R\xe6\xdb\xa2\xa9\x92\xf3\xce\xa9\x89yN\x19\xd9M\xb5$7%\x1f\xd3\\\xa4\x11\x7fh+R\xde\x82\xd5\xa2\xbf\xb4U\x16\xac\\\x9br=\xcd\x8f\xec\xd4tf\xa7>?\x0e\xe9\x0f}\x85T\xc0\x03#L\xeb\xaa0\xaa\x99jIf\x1a{\x93K^\xeeM\xb44\x9e\x11x-u\xcf\x18\x82fZ\xec\\{\xac\xe3\xb5\xa7\xedy\xedO \x13\xa7\xf0\x97\xae\xca\x15\x17r\xae\xf4R\xce\xc4\x8f\x85T\xc9~j+\x05\xfe\xea\xad\xc7\xd7A\xfc\xa1\xab8%3\xc1\xaf\xcf\xb4$\x82\x04\x81\xbf\xe2\x02$\xff\xad\xab\xc6v\x92\x9e5Yzs\xce\xdd,1\x93C\xb5J\xe0\x87\xac\x06\xfda\xaa\xe0\xc5_\xc5\xde\xd4G3f^\xb5x\xa5\xfbh\xe9%\xe2\x1cO\xb4k\xbc\x12\x10Z\x19\xa0\xb3\xf2\xd2\x94\xc4\xa1\xa8C\x7fk\xabE\xc1\xf5\x9c\x13@\xfe\xdbT-\x9f\xa9\xf8CW\x91\xce\xc9\x0bJ\xb3-\xbf\xd2~$\x88kl\"\xadi\xc4\x89L\x1a\xe9\x89\xfd\x9a\xd3\xc3\xb5v\x1d)Q\xc8\xa9\x83\xb6BNtSFuK5\x0c:\"v {\x07:\xa2:\xbbvn3\xdd7\xb9\x07\xfb\xc2\x9e\xecs\xc7\xd1\xdf\xdb\xd8\x01Yx\xe4\xd0\xfe\xe4`\x8cw\xa0\x03\xd6\xd8\x83s\x8f<\xf5\xf6\x97[\x8f\xebcYT\xdckx\xa8\xe7}5V\xb0\xf0\x8b1\xf9\x18\xd7\xda\xa2\x08[\x92\xcfQ\xe9\x03\xb7\x08\xd6\xab\xf5E/3Z\xe3\xc9\x13/\x8c\xc2\xebe\x94%O\x9fj\xb4\xb7\x81Q\xe5\xeb1s\xb9\xb5m\xe1/\xddN\x00\xd4eQ^ym\xe7\xf7\xba\x86zt\xbaX/\x9f\xb7\xa1\"\xbb\xe0\xc5\xaa\xfc\xae\xd7PQ0\xf2\xeb:F\x1e\xf2\xc08X\x91\xdf'\x9b*\xf2 ck\x11\xcf\xd8T\xd1\x0b\xaf\x870\xb5c\xd9\xf6\xef5^`\x9bA\xf9f\xd6\xa4\x82\x17\x8f\xb8\\*\xe2\x99\x14\xe6\xce.DM\xf7\x8b\xca\x15\xccVal\xe0\xc8\xf6\x1d\x0b\xdb\x12n\xdf\xf0\xa3\x05\x1d\x88\xa0\x03\xd6\x8f\x10\xcd\x8a\x94s\xac f\x05\x0b/\x01?\\S\xea\x93{\xcf@\x18\xa5\x98\xc0\x82\x8a\xdd\xfe\x94\x88\xa9vM\xe9C\xc5C\x11\x14\x13I\x8dCC\xb2W\xf1`D\x89\xf2\xa5yV\x1b\xb0B<\xb4\x0b4\xad\xacD\x17\xd0=e\xc8\xbc\xe4\xf3\xa4\xd3\xf71\x16\x99\x02\"\x0c \x8d\xef\x12\xf6.\xc9V\xab\xc0gi>$\xa8\xb9@>\xae\xc8$%S\xf0B\x06\x9d\xaeu\x9b\xebX\xf1\xe4w\xe0<\xd0\xc2\x04\x9e@\x96\x1b\x06L:\x9d\xb6\xa0\x99aj\xc9\x0c\x93\xe2r\xcc\xa2#\x1e\xd3\xb1O\xe8\xaf3\xcb\x05\xaf\x05\xe4\xe8\x02\xcddCJ\xf4T.\x8c.>c\xb2:sx\xf5\xb91\xdc\xe2\xea\xb7\"\x11\x1eb\xf9\xde\xfa\x82;qC$O7@l\xef\xcb#\xb6\xd7\x1a\xb1!\xf1\xc3y@\xe0\x84x\x93\x94s&\x9f\x87\xe5\x9f\xb3\xf0\xa6\xack\x02C\x7fWB\xbce\xd3\xc5/\x99\x19\xb7^c\xe6P\x14zK\x16)K?+\xf5\xf1\x1a\x8d\x9eM\x0f\xc3\xc1\xae\x14\n\x16\xe3\x0d\x97\xde\xe0h\x8a\xad\xdd\x8c}\xe2\x11vp\x95\xc6Z\xb5pc\x1b\xa2W\xab\xcf\x97Gv\xb1\x92\xf4s\xac\x91a\x8d\x7f\x1c\xba\x1b\xb8(\xbc\x92\xbb%\x91\xabu\xb0R\x1fD\x9bk;\x1d\x933Ge0\xe4\x05\x88\x8b\x05\xf0\x0d\xc0\x0e\xab\x94\x05I\xca\xebhJ\x1a9\x8a\xcf\x81\xa1\x89d0\xbe\xf2w%\x18\xff0\xceM\xcc\xb5\x11\xd0\xf2\xa9\xd6L\x93\xdaq`%+\xb3\xad\xd1\x08\x92:T\xbaC\x8e\x8c\xf5\xd98g\x89\xeb\xf2C\xc8\xea\xf7:\xf0 e\xdd\x85\x97H\xd1\x95\xecI+\xd2\x0f\xf5\x0cZ\x17\x19\xb4v\xac\x19|.{\x06\xff\x00\xd2\x15\x85\x1b\x1c\xd1\x1a\xe9@\x8aTW\x11\xd0jL\x0d?o\xeb\x16Q\xd1\xc4\xce`\x810\x1f\x83\x07O \xcd\x19tO\xf6\x866=tR+\xba\xf2\xe9\xd8\x93\x89j\xed\x04@\x12y\xfer\xfa\xe6u\x91?H\x9bYB~6\xdcih\xb2*\x1f~-\xb6Z\x14\xe2\x89\x99o\xcf\xba\xf3\xf2\x16\xe8B)\xda\xef\x8e2R\xe8i\x16\xad\xbb\xb4\xd2\xa4Y\x14\x13\xba\xa0T\x9b\xa9_~\x8c'C\x98\x0f<\xb2\xb7\xfa.\xe4\xab'\xe2\xf4\x96\xd6&\x87U\x17\x8eU\xb1\x14\x8f\x8f\x05\x99\\\xe6`L\\\xb8\xc8R\x88\xc9\x84\xf8k2\x85?&\xe0\xa5\xe0\x87S\xf2\x11\xfe\x98t-\x17\xce1\x99\x0bA\xe7m\x05l\xe6\xd5\xfd]\xb6`\xef1d\xa5\xe5\xc8\x9a\x97\x03\xa4\x1d\x94\x8e\xb3\x86%\x01(\xfb\xd5&\xe5\xd1R\x02\xed\xb4\xa2\x8e\xd0\x9a\xc6\xb6\xd9\x9f\x86\xadxw\xfb-Y\xb4\xb0&\x15\xcfg.\xe9\x7f=\xac\xc6\x8f\xac\xc7\x1f7\xe44Z p9\xb30\x9e\xb4\xc4\xd9Y\x9bf\x817\x1d`\xac\x84;\xe1C\x82\x1c\xd4\xf5\xdb\x01\x1a\xb7D\xbb\x0dswL \xf9\xe8M\xd2\xdf\x11\xeb\x93\xd6X?A\xacO6\xc5\xfa\xc9g`\xfd\xe4\xce\xb1^\xa0p\x86q\xed\x18\xff\xd4\xc4\xb5\xe4;%\xa0;\xa5\x15J\xd3\xda+\xdc)A\xcb\x9d\xb2\xb5\xda\x0cN\x97\x84\xcbdA=9\xfe!|\xe6M\xf3+\x0cZ\xa0\xf0l\x0c\x06,\xc6\x80\x05\xdcs\xe5\x87\x10/\xff\xd0\xd1E\xfb\x95\xec\xf7\x92:\xa5\xef[l\xd35\xf7s[\xd9\x89\x0bAu\xb7\x07\xedv;\x85\xdb4\x07\xdb\xf4\x1f\xb4\x8f+oo$\xafM\xa8\x06B\xd2\xe1\x8f\xd0Z\xe5\x891x\xf2\x02\xf8\xf4 \xfap\x1f\x0b\xf0\x07\x81!f\x00c^2\x84\xfeR\x03@\xe8\xfb^\x18\x02\x13,\xfc\xa4\xbb$I\xe2\xcd\x89\x14\xf8(I\xbd\xc9%\xbaW\xb5j|j\xc8\xff \xcaC\x9b\x11\xa5\xc8\x85\xcc\x85\x04)\xbc\xd6\xe5\x93>6=\x883\xa6\x89D\xa23\xc1\xa4V.\xb0X\xa5\x9e\xc3S.`b&dE\x8f\xbc \xf0\xc3y\x11j\x0dp\xe7xi\x14'0\xf5c2I\x83k\x91\xe4\x85n\x94(\xa6D\xe3\xe2\x1a\xd2\x05\x81\x1fWq\xb4\xda\xa6D'\xf9\x11V\xde\xe4\xd2\x9b\x93.\xbcO\x08\xfc\x987\xd8E\x865\xff\xd3v~\xa4\xfbl\xe2\x05\x01mb\xd9\x85\x13\xe2Ma\x19\xc5\x84r\xae\x8b4]\x0d\xef\xdf\x9f]t\x97\xe4~\x96\x90m\xfcz\xbb\xe8\xc7\xb8I$<\xc48\xd0\xe3\xe8\x0c\x0e\xd0\xd93\xf7W\x15\xef\x18\x91x\xb7 \x85\xacS\"\x9a~\x82\x86\x97\x94\xf1N &?g~\x8cZEY\x9eb|\xb7\x9f&\\\xd4\xf2\x13\xf8\x91vD\xe9(\x0c\xbf\\\x1f\xb9\xbf\xae\xe8\x88Nn\x08\xa9]\xc2\x91&Op\x90\xaf\xe6\xbb\x17~8\xb5\x19\x19\xda\xeak\xc0\x9b\x8b]~r\"F\xaa~\xd7\xabF\x981`\xfc\xba6\xa4\xa3\xe9@v!3a\xbd\xb8k1_\xe1\xf0\xb6\xe7\xb6\xe7p\xe2p\xd0\xee\xa8(\x1d\xa9K\xfay\xdbS\x95\xbeM\x05[\xcf\xd7\xa9\xba(\xaa\x17\x93\x1eb\xd7\xb6\x96\xf2%W>\x8b\x92\x9b{\xef\xe9\xe13\xf1\x12\x92;e\x0fk\xaa\xf0\x9b\xf7\xba*\x85\xbb\xb8\xbe\x16\x14\xd06\xa5 `\x0d S\x84\xe6f\x0c\x9e\xb7\xac\x19\xce.\x99[\xd1\xbas\x8b\xb6I\x97\xacI|m_7x@\x97=\xdeS\xb9\x89\xbaD\x0bk5Bc\xa3\xa8\xb0.9r\x86\xcc\x913\xe4\x8e\x9c\x93\xa6\xdb\x95\x8d\x1c;\xd5\xe7\xa6\xd1\x0f|+n\x953\x82\xce\xc1\x17)O[9\x98\xc7\x8a\x83y\x1b%\xc2c\xd8\xb2}LhPv\xec\xae\xfd\x12\x8a\xbb\x10\x9fyuK\x0b\xd97\x83f\x03gs\xdd\x98Zr\xbd\x18Z\xa8\xad\xb39*\xaf1\xf1\xc5\xb5\x9d\x8d\xfbg\xad&\x02mt;&\x8c\x16\xe1\xa5\x1b\xbf\xaf\xf6\x7f\xd3\x8a\xcc\xcd\xeb\xbd^\xc5=\x8b\xf1|R\xf5\x85p\x00\xdc.\n9?I\xbd~B\xe6\xc7\x1fW\x85k\xba\x05-\xa3\x13\xf1\x9e\xa4\xfc7\x9c\xd3\x14I\xa1\x18\x95\x18[\xff\xf2/R*B\x0b7p\x835\x19\x91\x07\xc8^W\xe1\xc8\"q\xd1\x81\x8b\x11T2W\x1a\x80\xbb4\xc7\x14\x93\x12\xcb\xe1\\rjW\\i1\xb7\xe8*\xe4\xc5\xda\xcc\xb5\xfa\xebJ\\\x82\xfa\xa8O2\x00\x9e{\xa9\x94\xb1g\xea\xa5\xc4\x90\xb4\xa7\xf2%[\xdb\xe2\xdb\x98\xcc\xc9\xc7\x95\xc6\xeb\xd9\x84F\xed\xe0y^\x8f\xac\xfaT\xd1\xe2\xc4n8\xaa\x19\xd2\xd6\x1d\xc3\x8d\xc7\x9e\x98\xbd\x17\"gS{\x86\xd6\x1f\xc5\xac\x0e\xae@]\x05\x0e\xe6\x16#\xaa\x1bP[\x1a\xd3\x14\x89\xae\xfc\x17\xffH\x8a\x88 #v\xc5&g/\x08\x14I\x05F\x94\x95\x0e\xba\xf2\x8b\xc0\x055\xe8\xe7\xad\xccb\xebb\x01\xe5W\xfaw\xd4\xbe\xd5\xdf\xeb\xeewy0\x84[\xb5\xb6.\xc2\xec\xef=tLa\xc5\xfdV\xf6\xcf>\x7fu\xf8\xfa{C\xbc\x87$\xf5R\x7f\xd2\xae\xee\xaa\x08\xb4\xde\xa26\x8f\xf2\xba\xc1\x07\x0b?\x98\x1em\xfa\xd5\x9c\xa4\xcf\x199\xa0;P\xf9\xe6\xfc\xd5\xf1\xc9W\xc7\xcf\xcd\x9f\xbe\x0c\xfd\xd4\xf7\x82\xd3\x14S=l\xf4\xe9\x914\xdcM>\x8dI\x88\xfe\xbd\xe2\x8b7\xaf\x8f\x8e\x8d \xe4[\xe8[?\x08^\xb1p\xaa-@\x92\x7f\xf6\xdc\x9f\xde\xe2+\xda\xd9 \xbb)\xd4\x80\xd4\x84G\x8b(\xa3\xe0\xe0m\xbc_MK\x10m;I\xf5\xbb6\xe3}\xeeOo\xf3\x19v\x17.[\xc3\xe7\xfd\xeb\xd3\xc3\x17\xc7\xe7\xb7\\\x13\xdd\xd7\x1b\x03Y\xd7\xc8\x06S\xcf\xb0\xaa\x94\xcf\xc1z\xf3\xe1\xf8\xe4\xe4\xe5\xf3\xe3\xf3g\x87\xa7\xc7\x1a\xe6\xa7\xda\xce\xc4Htp#\xc6\xfe\x9aLq7\xbd\x88\xa3e\xcd\x8el\xd3\xd7\xcc\xd8\xd7\xd4OV\x81\x87I\xceZ\xb2\xe4\x80\x84W\xfa\x0eT\xbd\xaex\x0c\xd7F\x82\xa6\xb6\xee\x8d\xb2\x9c\x9a\xd8\x9e\xf2\x93\xdf{\x84\xec\x9e;,\x85\x86\x0b;\x1d\x87k\xb4\xc7\xe1\xd9Fw\\\x1aR\xdaz\xdci\xb7\xf25f\x1b\xfc\xfb\x8d\xab+\xd3\x060\x85\x9a\xa1\xddzT\x86\x01}\xc6X*g\xc7\x06\xc3Q\xbe\xc5\x00G\xea\xbb\x11L\xed\xca[ly\xa8\xad\xbd\x11BJ\xa7\xf1\x06\xc3^Il\xaa\x00a\xfenS\xf8\xe5\xccC\xeb\x01l\xb5\xaf\n\xed\xf6\x10\x94\xf7\x91\x1f6\xb7*\x1e\xc1\xe85\x1b\xf5\x8b\x07\xc7\xa3\xda\x02\x86\xadm\x01A\xe8\xbd(\xbb\x88W\x9d\xed\xba\xa5Odo\xf9.\xfc \xadhy6\x9b\xef\xa3\x0c<\xbc\x10I\xc9r\x95\xfa\xe1\x1c\xd2\x88gi\x07\x0fb\x92\x90xM\xa6\x88)t\xa4.\xfc\xf8\xc7\xe4G\x17\xd2\x85\x97\xf2\x03;\xfc\xe1O)\\\x10\x88B\xbc\xa9\xb1\xf8\x8aZpI\xae\xbb\xf0\x9c5\xe5cn:/,,\xa6E\x8b\xf8\x86x\xd3\xc7\xb4\xce\x95\x1f\x04\x90\xa4\xf4\xff\x17\x04\xbc\xc9\x84$,94o\\\xb6\x17\xff\x93>t\xbe\xe9\x11z/\x04\x9a!\xee\xb5\xeeA\xf5\xd7&\xab\x03\x12\xcf=\xa9.4\x1c\xc0d\x1c\x9eqE}\xfbq@!^F\xb6\xee8D\xbd\x87\xe7\x82\xd5z}\xe9RR\xc8^GY,\x19\x0b\xe3\x0dY\xba\xf0B\x88\xc2 \xe9\xc2\xbb\x85\x9fP\xc8\xcf\x02\x7f\x92\xc2\xd2\xbb\xa6k3\xcd\x08m\xc9c\x87Z\xd7ba\x99\xd7\x91?\xb5Q\x8f\x8ct\x0bo\xad\xe3\x86\x80\x93\xf2S\x7f\x01,?\xbc\x13}\x1ch\xf5in\xd6\\\xe3\x86Q\x99Mh\x9a\x97\xa5\xd1\x85\x1fN\xcb&\xf7\x1b\xdcA\xeb\xd3\xfd\x80d$\x98\xa8\x88E(b%cbF\xacs\xcd'\xf7\xeeQd*\xb3p,tm \x8f0?\xc3\xcc\x9b\x10\x13BEk\x12\xc7\xfe\x94\xa3\xd4,\x8e\x96\x1c\xa9\xe8\xd7\x90\xac\xc8\xc4\x9f\xf9\x13\xb40\xef\xc2q\x98d\x0c\xc3RVkI\xd2E4\x85\x10\x93\xd1N#\xbc\x01\xa6-\x06\xde\x8a\x85\xf2\xc4\x91\xf0jhjH\x1c\x97\xdd\\\x94\xb7\x82\x08\xbb\xfb\xe9\x93\x96a\xbc\xcd\xcc\xbe\xc8V!\xedn\xe3\x90q3\xa7\xf00\x11\xa5\xc8`\x1cZ%\x0d\x7f\xaaL7K(\xd9/&\xc8\x160\x8a\x8bAQ2\xceg\x02/\x19\xe9v\xe1\xa7,I\xf9\xb71\x99g\x81\x17\x17\xb6\xf4.=w\x08\xda\x86n\xde\xff\xc6\xbd\xe9 \xea:\xcf\xd7T\xa8\xe1\x8c;\xde\xc7\xfb\xa4\xf3\xf3\x98\x0e\xf60K\xa3g~8}\xeb\xf9\xb1&\x863\xc8\xac\x83G\x8f\x96P\xddf\x19\xcb\x14\xdee\xdc?.)\xff\xedh\xa3\xd0\x8b\x07\xd7Xm\x8c\x19Vxx\x8d\xd5x*\xad\xb9ch8\xf6Z\x98\x8e\xadp\xda\x95\xfe\x9a/\x02\x03{\xc5\x12\x01\xcd\xaa_;0\x1b{gt\xd2\x93\x86\x96jbQ\xcb\x0f\x9d\xd3BG\x00\x9bF\nu\x86\xd3h\xbd\x82\x01\xc4W\xe8\xe6\xd6g\xa4\xa2+(y\xbb\x13\x0c-\xf5\x9b\x16E~\xd6<\xa4w2\xf6Zr\x8f\x80\xfb\x1b\x03\x9b\x9b\x99\x80k\x95\x00\xf2\xd7\xea\x0e|\x1f\xe6V\x04\x94D\xc3*\n\xfc\xc95\xfc1A\x94\xbe$\xf8\xf3jAB\xb6\x03\xe7\x14\xbd\x8b\xadI?Ab|\xcdV\xbff8\x07\x10\x8f=\xc6\x13\xd0\x1f\x14\x19`\xa8\x1b!\x8b*\xcc\xea\xae\xf3\xba\xed\xa0\xcfCT\xf3\xaf'\xcd\xf0d\x11\xadY*\x16\x8f\xf6\xe3\xe6\x1f\xd7~[\xc3+T\x8f\xf8V\x84~a<\xef\xcbbIds\x8b\xb2\x9a\xfc\x01\x9a\xf7\xc4\x05kI\xe29\x11\x89\x97^G\xcf\xb3U@\x0fd\xf25\xb9Nlg\x08G^H\x8f]\xac\x06a\x14n\xb3f\x12$\xe0\xc4\x01\x8d\xc8\xc2r\xa7\x95.\xf5\x90\xe1k\xec\xeb]\xcc-ZXo\xe9U\xc4\xe9w\xc2\x8e{\xca\xe9'\xde\x92P\x14\x1c\xe2\xd1\xdb\xead}LA\xb4\xc2\xa8\xb3\xf4L`Vr\xa2\xea\xc4\xcb\x12nNv\x15\xa9j[\xdb\xa1G\x9c\"L\xdb\x8e\xe088\xdfMw@i\x9c\xf4p\\\xd0\xb7\x97\xe4:\x11,0gL\x0d.\xaa\xc2\x86\xb0\x15ZL\x9bL\x11e\xf6\xd2x\xee\xa1OI\xd7[\xad\x82k\xccE\xe2\xe6\xde \x89\xc1\xd1\x91>(\xd4\x1a\xbe2\xdf\x8f\n\x9b\xb8\xc2\x11%n\xae\\\x18{\x84\xe6\xd3\x1bC\x1ek\xe2G\x83t\xebf\xfbl \xf0\x87>\xd9I\xbb\xfd\xb8\xfel\xc0\x1b\x01n\x04\xea-\x87z\xdd(*\x10f=\xa7\xbb%\x16`WzR[\xd1\xe77\x06\xfd5A#h@X\xb4\x9e\x9f\xfb ~\x84F~\x9a$\xeb\xa0'\xa9U\xa4]6\x0f\xb0\xa4\xaa\xbf\xf5\x18\xf5\x06/\xad\xc6xn\x1c#\x8fY\xce/\x90Z+\xb7p|L\x1f\x1fwI\xf8sF2r\"5\xc51lc\xe95\x9fpK8 c\x9c-\x15`\xb7\x87\xd5\x859\xd90HV\xa2\xf6\x85|\xab.\xf3\xf6p\xae!m\x05d\xeb\xc8%Q\xaeT\xe3\x1a{P(\xd0\xa4*,\x88|p\x94\xf9o\xecY<%/\xc2T\xdb\xaekP\xf5Cg\x04\x83\xa6\xf6A\xd1Y6\x8b\x05\xc0%\"2\x0e\xa1\x03\xfd\x16|*&\x84\x181\xca\xe4\xdf6\x10\xc2\x0d\xa2\xaf\xc8\xb3\xb7\xe2\xda\xedj\x96c\x91\xd07&3\x0cj\xe6\x96\xf6\x850R\x0f\x0b\x93\xf9T\xe4\x172ODh\xef\xf0\x13\x85U\x80\x03\xedk\xdbiT\xe8E\xb6\x865\xf3\xd0\xb0\xaelO\x86\xcc\xf4\x1f5]\x0caI%_\x8e\xfe\xb9\xbf:\xe5]h\xd7\x16=\\\xe4\xeb)*\x050~\x9fR\xc1\xc4\x97.\xee,G\x81\x88\xa7\xdf\xad\x0d\x12o\x8c\xca\xf2\x92\xb5KH\xae\xe0\xc2\x95_\x96\x82\x88`\x8ef\xb9P\x87\xe2<\xd5\xa0'\x12\xdf\xdb+\xd9\x02\x9c8\x8e\x0b+\x9b\xb80\x17?R\xf1c\x89'\xacz-\x82\xbe\x08\xdd\xa9rS\xa2V\xb3\x1d\xd4U\xc8\x83c\x17\xed.XR\nx\xbb\xdb\xedR\x86\xb9\xaa\xdab\xcb\xe3/W\xcc\x1c\x05<\xf8\x915\xf0#\xe7$\x91\x99N\x1cy\xfe\xd3E\xa64'\x13\x8fJ\xb4\xfc\x83A\x14\x92\xffJ\xcb~ \xca\xad\x8d`p5\x80e\xd1\n5\xa9\xd3Y\x80BM\xc1\x0c#\x12j\nD\x04BM\x91p\xd8\xd3\x14\x89(\x83\xba\"\x1eWPS\x84\x91\x04u\xefE\xc8@\x8d\xd62\x8fa\xa6\xf9N\x0er\xa5\xf9\x94\x85\x052N\xcc\xf0\x15\x8f\xc8a*a\xc1\x174\xa5\xdcU\\7\x05\xe6N\xab\x98\xc3jy\xbe\xb0j:\x19\xbb\x10\x96L'C9\x9f\xeag\x10\x0e\xee>\xc9n\x00\x8a[\x13\x17\xac\xf3s\x92\xbc\x8a\xa6Y@,WA?4\xaa\x1f\xca\xd2\xcc\x0d\x1eI\xfc\xf0\xa9\xa3\x1e|\x8aUt\xce\x85\x98dh`\xef\xdeE\xab\x0b/\x1eB$\xfa\xa9\xd42Y\xad\xde(\x84\xd2\xcd\x89\xfc\x8e\x86*\xda\x94\x90\xfa\xa8\xf9\x89\xbb\x05\x14\xe0\x00b\xd0\x8dMX\xd9V\x1c\xb6\xe0\x1f\xbe(\xd5\x03be\x87v\x7f\xf7\xa1\x9a\x03\xd4\x17E{=]^QVT\xc9\x1c\x9a\xe5E\x95l\xa4^^\xb4\xaf\x16%\xdcfU=\xa8&\xcc\x0fWy;\xa3+\x82-\xed\xef1\x9e\x88\xae\xdb\xae\xa3\xb6\x1a\xf0\xf3l\xdf\xd1\xa5*]\x19\xcfg\xd4'\xa6\xe5uN\xeb\xd7\xd9D\xcdoJ\xd0^\xd4r\x07\xd2\xb9a\xba\xff\xb2{.\xf8\x02\xd7\x1d.\xe9\xea\x9c\x7fho\x88\xb8=\x172\xf5\x03\x9br\x9f\xc8v\x9d\x9f#\x13\xd6s!.*\x11\xc7a^E\xb9 \x1d\xea\\B\xc5\xa5|7\n\xdf\xc7\xc1\xd1\xc2\x0b\xe7\xa4\x95+V!\xe6\xa5^<'i\x9dCN\xd4MH\xca\xc4\x00\xb3\x80\x97\xc5\x81JE\xc5\xa3\xf1\x8b\xbeq!\xea\x06\x917=]\x91I\xab\x01GL\x0e\xebR\xa6\xf7\x10\xeb\nA\xeb}\x1c\xa0\x87\xb9\xae\xc64\xba\ni7j\xba\xf3|\x0c\x08\xb7S\xcc\x8e\xd0j\x18z\xb8\xa1\xe7\x9ax\xb3\x88\x89\xc1.\xa6\x98\xb2Mp\xc0\x14\xae\xd87\x99\xd2Y\xe0\xcdrw\x15\x935 \x85t`\x1b\x06.f\xf6>\x0eZ\x0d\\\xea;b\x82W7\x8b\x83\x0d:\xc4\xb1z\xf1\xa4~\xff\x88G\xc0\x89\xa2u\xd0]yqB\xd8\xd7\x8e)\x834\x19[Y\x1cPq\xdb_z1\n\x91\xd6Y\x1ew\xd2\xac\x9c\xa5\\\xd8\x95\x1fN\xa3\xabn\x10\xf1k~\xdcW\x93\x08#\x1f\xdc\xbfoA\xa7Rc\x11%\xa9\xe6\xf5\xcaK\x17\xe6\xeeXmJ\x98\xf8w\x0b?I\xa3\xf8\xba\xfa\x06/v\x98\xcc^-\x93un\\\xac\xb4,\x97\xc5\x1c<\xa0\x83e@KH\xec{\x81\xffK\x0e8]\x86\xde\x9b*\x1am\xb4>b\xd3\xccIz\x14\x853\x7f\x9e\xd8\x0eE\x8c\x84\xa2\xf4\xd8\xa0p\xc1I\x11I\xc7\xc4n\x86r\x899\xef^\xe7\x12Pj\x88v\xc5]\xb2\xf0B\xa7\x0d\xa5\x81<\xb5 \x99\xbe\x0c\xa7\xe4\xe3\xd0\x90\xc2\x1e8\x03$\xe1\xae1\xcb\xb1\x89FE\xe1\x0b?HI\xfc\xc5H+\x03\x7f\xe0]GYZ\xa6k\xacc\x9d\xfd [t\xae<\xd1\x0f\x02\xc9q\x8a\xb4\x90\xa1F\x14'\x14\xd8\xa6\xf8\x92\n@\xab\xfap\xdag\xe9\xa5\xd6\xf9\x88b\xae'\x9dbL;B\xdfF\xa5\xb7\xe3\xea\xa8\xf1\xbe\xcd2\x1a\x98kl\xc29g\xd5\xbc\"L\xd9\xd4\x8cYf\xa0\xb5\xc6\x992\x88T^\x10\xf4\xf3D\x9du\x8b \xd6a\\\xcau\x86f\xa5*\x11Z\xc5\xea\x8e7\x7f\xc4.q\x9a\x08\x02\xde\xa8\xd1\x1d\x1cr\xa2P\xb7\xe9\x0b\x15\xb0\x86\xe0\x9bU\x981k\x7fc\x1a\x03Hg0v1F\xc7`|e\x0bl\x10OkZ\x03z\x9ch(j\xbc\xb7o\x81D\xe2\x06\xec\x8ep\xe86g\x02\xe7\xd7\xa53\x816\x94\xf3\x1c\xe9\xb8\xd0\xf8vK\x10=C>\xe4\xf6@`Z\xce;\x9dy\xc3\x1eb\x80\xd1z\x07\xca\x0f\xbb\xfb.\x11\x13s\xe5\xb8h\x18!n\xae\x89\xf7!\xb6\xf5\xcc\x98pU<\x11\xab\xf8\x8d!i\x9fx\xd0\xc9\x8f\xae\x93\x1f\xce\xb9\x95b\x97\xffIwHVK\x1e\xbc\x9a\x9bqk\xe6\xf9\x01\x99\x1a\xda\xc4\xf3\xde\xebN\xa2\x00\x15\xf3V\x8c\xd9=!S\xdf\xff\xff<\xcf\xab\xb3\xac\x0b\xd0\x11\x80\xe1\xa7y\x9c+\x83\x0f\xa2x\x16\xb5\xf72<`\\=I\x9bb\x17f\xfa\x15TIW\xd3-+}\xa6\xccFh\"\x8eO\x9e\x9aYh\xadE:?\xdd\xfeP\x1f\xdc/5\xb6\x87\xe2\xe1\x1b'\xa50\xad'v.\xe7\xcek\xac\xa4(\x03\xb6j\x98\x03\xcb]\xd94\x054\x07e.S<\x9f\xdd6\xff\xb0\xf6\xb3E\xba\x0c^Dq\xfeQ\xd5uK<7.\x18\x87\x88\xf9\x95\xf2(f\\`\xf4\xf0\n\x86\xa2\xad\xf9;\xd6g\xd3\xdc\xfci1\xbe\xfa\xe9L\xfd\xc4\xbb\x08\xc8t\x08Y}\xc5(d<\xeb\x90\x116I\xd0\xad\xff\x8e\xaf~PO\xb0\xeb\x808uLL63{[\x08b+\xc9\xb0\xcdH\xc2\xd2\xac\xd6\x01RF\x10\xd1\xf4v\x16\x07\xdb\xfcS\xe3\x87)\xaa\x8dY\x9a\xad\x1az\xaa\x01({c\xfeFl\xa5\x02\x94Y\x1c\x98\xab\xb7Z\\\x9e#\xd1pi\xea4\xef7\xffV@\xe4\x19\xbek\xe1\x13\xf8\x93\xcbaem\xf5\x03u\xc1:\xfe\xb8\n\xa2\x984\x05;3\xa2\xc4\xd4_\xb7F\x88\x14\xb5\xd4\xfa\xcd_\xb7\xf17\xe9\xe3*\xf6V+\xf2\x85;a\x13\xd9\xbem_\x91 b\xe6\x8d\xb6\x9c\xd7\x0efA\xfc\xf9\"\x1d\x82\xb5\xd3\xab\xc1\x86+\x7f\x9a.\x9a*%\xf1d\x0831\x90\x1a6#\xa0\xfd\x9d^y\xf39\x89\xe1\xfdK\xc3\xack q\x89\x80'\xac)\xcb\xa9\xfb\x04\x13v\xb7]\x96\xd2^\x11\x8bS\xb7YN\xb3\x8b\xa5\x9f\x0eaaZ\xc1Uw\xe9\xad\xda3\x0b\x92\x04\x9et'A\x14\x8a\x898\xf4\xd3\xfa\xe3\x87q\x06f\x9an\x92\x7f\x1d\x1d\xa5W8\xf73\xc7\x95\x9a\xbe\x91\xa8R\xceCK\xdb_\xbe\xacb\x90Qojd\x18\x94\x02\x80`J~\xccxy\x7f\x15\xce\x1f_x \xd9\xdfu\xfd\x0f\xcf\xde\x9c\\\xf5\xbe\xfej\x1e\x1d\x1e\x1e\x1e\xbe>}\xbf8~??<<|\xb6K\xff&G\x87\xaf\xe8\xbf\xaf\x1e\x04\xfb\x7f\xa5?\xbe\x7f\xf1\xec\xd5\x87\xe3\xf7\xb4\xc2\xfb\xd9\xd5\xad\xfe\xeb\x05\xbf<\xbb\x1f\xf6\x9e\xcd\x16\x1f\x9f\xad~\xba>\xea}\xdc\xbd\x7f\xff\xfe\xfd\xce\xcf\xeb\xdd\xa3\xbf\xac\xfa\xcf{\x8f:\x9dY\xbast\xff\x97\xbd\xfb_\xf7\xf7\xef\xbf\xdfy\xf0\xe8\xfd\xec\xea\xf9l\xef\xe1\xfd\x9f\x1f<\xea\xbc\x8f\x07\xcf\x07'G\x97\x8f\xe8x\xfe\xfc\xdd\xc9\xe9\xbb\xe0\xd5\xe1\xf1\xf1\xe1U\xf8\xe8\xfe\xfd_v\x0e\xe7\xeb\xdd\xfb\xeb\xef_>\xbf\xaf>\xef_\x91\x9f\xfc\xfe\xe5\xe1\xe1\xe1\xf3\x87\xa7\xefO\x9e}\xf8\xf3\xfcY\xf0\xb7W/\x0e\xa3\xbf^=?|w\xf2\xf1\xe2\xbbg\x0ff\x9d\xf5\xdb\xaf\xc3\xe0\xbb\xc3\xbf\x85\xfb\x97\x83\xc9l\xe7\xf0\xd1/\xf7\xdf\xce\xde\x1c=|\xf9\xf2\xfb\xd0\xdf{\xb1\\\x1e>{\xf5\xf0\xc5\xab\xc5\xd5\xbb\xfe\x83\xc9\xa3E\xb8\xf0\xff\xf6M\xff\xe8j}\xfcM?]\xbe}\xde\xfb\xf9\xf4\xeb\x9f\xf7\xe7\xdei\xfa\xed\xfd\xcbW\xdfy\xe1\x87\xe5\xe1\x87\x93\xe7\xef\x83?\xf7\xdf\xac\xb3\xec\xdd\xcb\xd7\xd1\xfe\xe5\xa3\xde\xe9\xc7\xd9\xc3\x9f\x937\xe9\x8b\xfd\xf9\xeel\xd6\x8f\x92\xb7;o\xc2W\x93\x0f\x0f\xa6\xbb\xab_\xa6/\xdf\xa7Y?:\xdc\xfd\xd0{\xfe\xb7\xe8\xeb\xe5\xc7ep\xfc\xfd:}\xfe\xfe\xa7\x9fNw\xd2\xe5\xd7\xcb\x9f\x9fuV\xdf_?\\=\xef\x7fx;{\xf0\xd3\xdb\xe3\xde\xcb\xdd\xde\x9f\xff<\xf1\x9e]\x85\x19\xd9\x9f}\xf5\xcb\xfc\xfat/\xfd\xee\xe5\xfbG\xfbo?<\x88/\x9f\x7f\xfb\xe7\xd7\xdf|\xe8=\xffz\xf7\xc5e\xf4\xf5\xf2\xc5\xea\xf5^\xf4>\\\xfb\x0f\xbf\x8e\xc8\xe1\xe0\xfe_\xbeK\x96\xdf\xfd5\x8b.?\xf6\x12\xff\xa4\xff\xd5\xc3\xf4\x9b\xcb\xd7\xfb\xe4\xd9\xa3\xe4\x9b\xab\xbf\xac\xee__/'\xd7\xde\xdb\xfb\xef\xe2\xb7\x9d\x93\xb7\xcb\x8bW\xaf\xfc\x8f\x93\xbf|\x98\xbf;\xe9{\xef\xff\xf6h'\xfa\xea\xbbd\xfe\xdd_\x0f\xbd\xaf\xf6\x8f\xaf\xe8\xb2\x1c\x9e\xbe\xff\xf0\xe6\xe4\xeb\xbd\xa3\xef_\xbe\x1c}F\xd0\x19\xd2\xbd\xb8N\xc97Lj\xae\xd3.\n\xad\xe2\xc4N5\xf2\x18\xaai\xc6=\x8d\x84\xc34-\xaa\xe9\x1c'\x16;\xf0\xcf`\x87\xd0\x81\xd8\x81\xfb\xb0\x0b\xdb\xd2]\xe9\x8d\x0b\xa4\x9bF\xcf\xaeS\x82\xa6a\xf5\xd7f\xb9\xe9 \xb3\x10\xc4Q2\xcb\x17:*\xe6\xfc:\xee\xf3\\\x14!\xb9\x82\xa8\x92\xe4\xa7\xc6N\x03\xc7I\xa0C+\xb1q*f\xc3x{\xe6BF\xe99%\x06=\x97\x05q\x86\xa7\xd0\xc3\x0b\xe2m\xd8\x85!\xad\x120\xfb\xc5\x00\x9e\xc0\x8c\xfe\xd3\x19\xc1\xae\x83\x90\xf5\xc7iw\xb2\xf0\xe2\xa3hJ\x0eS;p\xce\xe0\xc9\x13\xe8?\x84O\x95\"\xe8@\x9f\x17\x0f\xf4\xc5\x03V\xbc\xaf/\xddq($\xc6I\xa7\x83\xe6\xfa\xf0\xf4)\xf4\xf7\xe1\x1e\x0c\xf6\xf6\xd4\xf7\x0f+\xaf\x07{{pO\x0d-5@)\x9bI\xcf\xe6\xc9\x18\x06K\xe7\xf2\xf4)\xecV;Q\x18\xb3~\xab^\xfa\xbdZ\x90\xed\x9a!\xf6\xf4)\x0cZ\x03\xc0\xd1\xa2\xb4WF\xe0Y\x1c-o\x87\xc2B\x97\xc5\x8d\x12\xe0\x8f\xb0\xc3\xc2=\x8e9>\xf782\xc36\xf8,\xc7\x83G\xff\xe9\x8c\xa0\xbf\xbf\xf3p\xc7\x81\x88\xb1\xe13\x8a\xe0\x99\x8b\xd1n\xb1\x04\x9e\x82\x07\x07\xe0\xc1\xb0x\xa7\xb2\xc0\x0c\xd2>\x1c0@\xa7c\xda\x0d\xdd?\xbc\xd1x\x8c\xc0\x19\x9c\xd1\xcd;&\x0c\xae\xf7`\x7f\x87\xbe\xb0F#\xcbq`\xc8\xb1\xc2\xcf\xd7\xcbf\xed\x0cp\x1d\x1e:\xd016\xdc\xef\x89\x96)b\xe4-\xf3\xae\x06RW\x15\xee=\xbf\x93\xfe)\xf2C\xdb\x92\xec\xb4$E\x91d\xc5\xc9 \xea\xf3\x7f)\x84\xa5\xf8\xab\x92\x9f\xdc{?L\x1f\xb2u<\x90\xff\x18\xb2\x90\x88lQ\xac\xc3gG\xcf\x8f_|\xf5\xe7\x97\x7f\xf9\xfa\x9bW\xaf\xdf\xbc\xfd\xeb\xc9\xe9\xbb\xf7\x1f\xbe\xfd\xee\xfb\xbfy\x17\x93)\x99\xcd\x17\xfeO\x97\xc12\x8cV?\xc7I\x9a\xad\xaf\xfe_\xea\xde\xb4\xc9\x91d9\x0c\xb4\xdd/k\xf6\xfe\xc2~q\xa4\x86\xdd\x99\x83\x04\n@\xdd\xa8F\xd7\xeb\xd7\xd3#55\xd3\xfdl\xaa\x1f\x9fH\x00S\xcaJ\x04\n9\x0dd\x82yTW\xcdT\xafQ\xd2R\xa2H]\xdc\x95(R\x07\x0f\x1d\xe4.IQ\xa4\xb4\x07wy\x99\xed\x9b\xf9#\xfa\x03\xfb\x17\xd6\xc2#\"32#\"\x13\xa8\xaay\xd4\xc2\xac\xbb\x00\xcf\xc88=\xdc=\xdc=\xdc\xafo\xbe\xec\xf5\x07\xbb{\xfb\x07\x87G\xc7\xed\x1d\x8b\xa7\xcbat\xa4\xc8g\xe9\xc1\x13HN\xa0\xdd\xf6\x1cqS+\xc3+b\xc18\x93Q\xd9s\xe8#O\xe7\xec\xe0\x9b\xa9z\x9e\x1d\xa4\xf4\x14\xc35\xc0O\xc0\x1e%c\x0e\xa4\x8b8z\x87\xc4\x13\xa3\xba\x15Q}\x99\xc3W\x178\x1bAO\xd0\x0b\x02\x1e\xac\xb2e\x1a\xac\x97\x98\xf0f\xaf\xaaE\xbb\xca\xef\xe7`\"\x95\xd7s\x9b.\xa6v-;\xfcN\"\xb0x\xad#\xbc\x03=\x0eq\xa3\xe4\xf1\xc8\x87\x8c0\xd3\xfeN\x8b%\xd7\xcc\xc3\xdcD\xf1s\xa4\xe0\xa1\x90\x85+.m\x90\xad@H\xff\xb4G\xb0\xeb \xc2\xd8)] Jr(\xf5\xec\x1f\x1c\xf6\xfb\x07G=\x8a\xd7\xf4 \xba\x8c#\xa6St\xdd\x1f\xf0'\x8c|\xb0\xe7\x03*\x9df\x02\xf3\xed\x88y\x18Q\xfc?\x92p>B\xc8\xa0\n9\x90\x00\x07\xbb\xf0\x08\xa2\xea\xad+>}\x99f+\xe4\xdf\x82\xb1\xd5\xb1d\x0c\xea!\x06\x1d\x0c(jY\xe7\xbaG\xbbZyC\x9eM\xd2\x8d\x897\xab\x0b\xbb\xa7\xa0\x02\x0b\xabM\xe7\xfa\x08>\x84\x80\xca\x02\x942\xa8\x12\x05\xdd\x17v\x9f\xce\xab\xe7\xe8K\xf80\x82\x04\xe7L}F\xd9r\xe7P\x85\xa3\x9f\x10\x9cb\xc3}\x18BO-\xb2\xe6E:\xf4\xb9\xa6\xea\x05K`\x04m\xa8\xe6T@\xc4B^\xbff\x14f\x01\x8f\xf8\x18:s6\x08X\xc0\xd3\xa7#\xe8\xcc\xa9\xe4\xd0\xa6;\x18\xe6t\xdb\x9d`\xf9\xc1\xfe\x01|\x88\xe1\xb2E\x03.\x88\xfa\xe6\xd0\x19\xc1\x91\xa3i\x91\"p\xa4\xb6\x14\x95[\x8a\xf3\x96\xb2\xbc\xa5l\xf3\x96(\x91`7 #\x07\xfb\xda\x87N\xf5\x06\xaa\xe1~3}5\xc2W\x8b\xcc3\x19\x9c\xc2+\xef\x15\x9da\xd8\x81\x1e\x15\xbc\x16\xf9\x9ck\xf44\xc8\xf0>\xf5\xd2Ew\x1d\xbd\xb3\x07\xec\xee[D;Z\xbe\xc8\xaa7\x17KU\xe3\xa8?,U\x15Q$\x94\xf6\x0ce\xe8\xef\xe2 \xad^\x93\xa9\xcdiBq\x9b\"6\x0b\x19\xcf\xd1\x9b\xd6\x1c\xe8\x91w\x9e\xa3\xb7o@o\xf4\xb00\xa07\xc5\xd1\xc1n\xce\xbc\xe5\xd1t\x06{\xb4\xc2\x12\xe8\xf0\xd0\xd1\xe3:\xc5\xe5\x98\x93\xd5H\xdf\x8d\x19/B\xa7\xaf\xa3y~\x85\x12\xd4\x13\xe8\xc1\xed-\xbf#\x8b\x8e\x1b,K\xc4\x13\x14\x8cq\xa7i0\x97\xce0v\xd4\xbbH\xd0-)H^y\xafl\x82>\xf2\xcc\x90\xca\xd0\xe3\x14lJ2\xf2\xc7\xbcJF\xbc\xe7tp\xb8\x0b\xb0\xae\xf92\x8ab\x1b\xbf.\xa3KZz\x87=\xf8\xe4\xd5\xc0q\x81P\\K\xa0\x8cM\x9d\xccq\xe0 \xf4\x91\xf3d\x9d\x0ee\xcb\x1f\x8e\x80\x96\xa7\x07\x82\x11\xee\x94%<\xa5\xfd9\x855\xec@\x02CXW\x10\x89n\x89\xa5CQ,\xa1E\x07\xac\xb6v\x9b\xd6\xb6\xc3j\xcb\xeb\x99\x8b1\xc9\x83(\xb5\x82Om\x82\xb5u\x18\xe6\xca\x8d\x05\xac\xb6\x11,q\xf8\xc8\xbd*E\x96\xe6\xf7F\xd0s\x9c\x13\x08hcG'(\x9f\xb5aQ\x88\xbd\x1e\xa5T\xed\x11\xcc(\xad\xdeAzA\x85\xa7:\x12\x94Qd\x0e\xe0\x96\xbe\xeb\xd3w\x83\x13\xf0\x19\xc5Q\xaa\xcf\x8a\xea\xb3\xbcz_W=\x7f\x15:0\x9b\xc2\xed\x08\xfa\x03\xba\xb1\xae*\x1c\xae\xe1P,+p\xca\xdb6\xf7\xea\x0c\xed\xdd\xc1Q\xe5\xc8[x\x85\x96\x1dk7i\xb2\xb8\x921\xd08\xdb\xc6\xdd\x9f<{\xfd\n\x1d2\xf9W\x9d\x87M\x9e\xe6fXI{S&yMW8\xccwS\xf2\n\xf9\x85\xdd@{[w\xa3\xf1\x9a\xf4\x0e\x92g\xed\xa8\x14\x0d]LPd\x87\xf6\xee\xae\xe2w\x1c\xf0GG{\x8e\xd6\xa57\xfa\xf1\xba\xf4n\xe3\xdd\xde\xa8KU\xd3(H\xf9\x185q\xbbh\xf9\x8a\xe3.\xf3\x11\xa7\xef9\x1b7\x0b\x924^g\xa5\x8eq\xa5j\x94\xcaxM\xd8\xfc\x9c\x12\x03\x161\xc1\xe0\xc3\x11\xdf\xd4(\x8a\x8bP3\xeclT\xf5\x83vN\xa0\x85>\xfaH\xf2\x92Rv\x00f\xee\x0fy\xbc\x0b\x9e\x94\xc0\x85\x16z\xce\n\xa7!\x96\x1f\xc19\xe1\xe34\x18\x85\xde\x83\xef\xb1\x84 u\xda\xf0\x88M\x15\xcb\\n\xa8g\x1e\x84\xderY7\xe4\xfa \xa1\x9f\x16\xfa\x13%]\xbe\xd4\xd2w\x83\xd3\x18l\xd84\x08\xf9L\x9c\xfb2su\xfa\xf1i\xa1\xda[\xf7X\x9ca\xa7:\xe7\xc5\xa9\xf3\xcd\xcd\x9aTN\x9e<\x80\x12\x0bV\xc5\xeeYf1\x8b\xe1\x11\xa4$\xf6.\x96E\xc0\x7f\xe5\xc2V\xd14{\xf2 \xbcb\xb7\x1a\xdb\xfa>\xbc\"\xb4\x8f\xf6\x1d\x17B\xfb\xf8\x00=\xa5\x8b\x0e\xd0\x96\x06\x1bu\xbb\xe07\xfd]\x1d\xc7 \xed\x03\xc7\xb6p\xb6\xd2(\xaez\xea\xb0\xeb\x80\xbb\xa6x\xe1\x94\x89u\x83\xe4\xa5\x98\xebM4\xc89\x85\xd2\x9eUyD\x15\xdc\x8a\xe3\x80\xa5t\xf8\xeew\xf3\xee\xe1\x9d[L\xb7U\x8d\xc9\x12\x97|k7\x9a\xde\x0dWt\xefAWtww_Y\xcb\x81\xd3\xe5w{\xbc$ .\xc3Mj\x92\xd7U\x9a\xca\xd8\x8e\xbbg\xd0\x86\xb8\xfb\xb1\x0b\x16\xabU1\"\xb2V\xd8\xe8\x0e\xa4I\xdb\x08\xa1\x9an\x9a\xeeU\xaf\x94\xf2\xa8\xef\xbd\xaa\x14\xc5p\xeb\xa0:\xbd,F\xfd~5v\xbc\xc7j\x19T\x8b'9J\xf1\xc9\xd3cj\x0b\xbd\x07C{p\xec\xd8F>-\\\xf1\xbe\xd2\xc4e \x068e\x9a,\x91\x88\xceQ\x0d}\xc8t\x9a?K\x8b\xfd<\x80\xce!e\xe9\xc9z\x19\xa4\xb6e9\x1a\xc7-\x1d\xeb!\xe3t\xaap\x9b\xf7\x8e\x0b\x87\xd0\x1aA\xc2\x82\xd5:<\xcf\x91\x9c\x1e\x91=\"\x8e\x93\xab\x89\xe8\x0b\x92%\x86\x1e\xabj\x85\x88R \xe6\x0cm/t\xces\x911We\xd3\xf3o\x9f\xd9F\x82\xee\x9cYC\xa2\xee\xfc\x84\x9e\x8b\xc0\xd7\xe4\x15\xcak^\xbbx&\xf5\xec\xbc\xd2\xb1\xdfnO\x1d\x17\xcf\xa1\xf4\xd0\x14\xdb\x0b\xa7\xebG\xa1\xef\xa5\xf6\xdc^\xa0\x02\x9a\xc2\\<\x89\xce\xf2>\xdc0\x0b\xcc\x15<\x85\x9b\x13\x07\x96\xec\x9e\xd3\xc2\xc5\xb3\xf3l|Cke\xe2\xc2xM't1^\x1b\xf4j\xd2MK\x18B\xb2\xc9\xe6\xd9\x90\xe4<\xe4\x81\x83\xd6w\\Cr(\x0elRO\xb1\xc3\x95\xbd\x19\x88\x8d\x7f\"\xb5\xda\xdf;vl\x8b\xd6n\xb9[\x88\xc65f\xb8\xc0\x8e\xa9`[Fp M7\x19E=\xf5\xda\xf9\xdc\xfe\x89A\xefv\x928\x1f\xda_xW^\xe2\xc7\xc1:\xbd\x9dy\xa9\xe7\xec\x04+u\xd4;\xe3\xcf'\xd7\x83^gr}\xf8b\xbasY-\x12\xb1:\xc7\x9f\x0f\xa7mg\xb8s\xb9RI\xdd\xd8\xeaZ.X;\xb2\xef\xb9\x19K\x12/\x0c\xd2\xe0K\xf2\x83x\xd9t\xf3@\xd8\x92\x98R5\x15\xd7~\xe8Y\xce\xd2y\xb4n\xb4\x12 k\x95\x85\xde>\x1d\xf7\xa6\x0e<\x85\x8e&'\x95\xed9\xdc\xd6\x84\x8a{\xaf\xbb\xa2\xd2\xb3\x1d9\x8e\xb0-1\x0bm\xdcMI\x922\x15\x8e\xe5]DY:\xbcXz\xe1[\x0b\x86\xe0a\xc4<\x19hB\x81M0\xa0\xc0\xe3\xdd=\xbd@\xb4\xbb\xbf\xeblc\x1e\xc6`\xf8\xdd4\xfa$zG\xe2\xe7^Bl\x0c\xd1\xda\xa6C\xa6t \x03\x96W\xe3\x9e\x1a$\xaa`\xbb!\xec\xe9\xc3:\xf4\x0f\xef\x1e\x98\x027Yy4[\xcaUE\xf7\x0e\xaa h\xf8\x04\xefU\xb98\x93\x05\xaad\x8f\x89\x02\x87U\x81\xc2\x03\xae\xfeS%\x81\x98N\xb8\x14\x93e\xc8\x05\xcarIf 8\x85\xa4+\xf2\x87\xe5\x05\xebg\x0d\xb3\x12V\xe6\x0d\x03k\xf2\xa4\x8e\xfal\x80\xaa\xc2<\x92\x93\x1b\x06<\xdfX\x1b,K-\x9a\xc9E}8\x05_\xa4\xfb\xa3\x9b\xa2\xf2\x82\xe0\xc1DS\x19\xaf\xc2\xeaa/\xc3B\x15;\x1aA\xc7\xa3\xdb\xae\xd3\xa3\xbb\xad)~\x80\x89\x9dm.!t\xfa\xdc7\x83\x07\xc1K\xb9\xa2\xb9l\xf2f\n\x90\xd89\x81v;\x84'\x10\x9f8\x10\xf0\x00\x83<\xbcv\xa8\xe6\xc6\x16s\xfa\xa0\x18\xcb9\xa5!~.Z\xed*\xc7\x11\x15\x8f\x83\x1c\xd7TdfX+\xe5\xb2\xdb\x10\x1d\xcd\x87\xac\x88\xdf\xde\xc6\xf0\xa4\xa5\x12 \xae\x86(qW\xf5\xda\x86\x94G$5\xe8m\xc4\xccUB\xd8\x95\xb4$\xef\x95.\x06h\xdbf]\xd4/`\xcc\x9d\x06NE\x07B\x18\xc2\x8c,IJ\x10R\x8ap\xd8\x8c\xa8\x02\xf5\xaa+\x99O\xfa\xb6\x13-D@1\x88\xbb\xe2\xdb\xee^\x95\xe8 \n\xaeO\x92\xb5\xbb\xaf\xcb\x92\x85\x8c\xe0\x8eC\xc8\x0bhu\x83\x04%zSx\x01:\xa5\x01c\xda\x11\xa3H:r+>\xcc]\xe5\x149>\xe5\x88hZF\xb3\xb2\xbe|\xc2\xcb\xc7v\xe8B_:\x9e\xd0w\x93e\xe0\x13\xbb&\x91\xb27N\xa76\xa5\xaaI\x193\xef\xbeR&-H\x93\xa8 0^\xefe!0)\xdfd\xdc\xd7\xe1\x14\x02J\x8dQK\xf9\xe8\x11\x84\xf0\x94\xd9\xf4R<\xd7\x88\xa6\xb6\xd8\x03\xdbv9f\xa4Z\x99_\xf3P\x98YOx\xfbt\x08<\xc5\x1eS\xda\x1e@\x1b\xbd6P\n\x0c\xf9\x03\x1c\xa0\x93\xbf\x84a\xfc\x02\x87\x91\x7f\xfar\xc8_\x0e\xa1\x83\xceXO\xa1\xe7\xb2/#\xad\xd9\xf0\x8aG\xbc`\xac#@\xd6\x11\xc3\x13\x08N\x1c\x88Xh\xb1t\x1c\xd3\x9e\xe8\xfd\x11\xa3;\xe3\xc6~u\xb76\xed\xe2A#.\x19\xe5\xb3\x94m\xb7\x94\x1dp\x1bIO3\n\x18ZJ\x0b\x15\xc4\x16M\x08\xb2`\x8d'\x93lv\xd4\xebu\xe8\xdf\xf9|>\xad\xb8\xa3\xc7\xa2Po\x97\x15\xea\xed\x1e\xcc'\x93lN\x06\xf8sN\x06\xf4\xe7\xa07\xc3\x9f\x83\x9eZ\x05\x9dd\x0b\x9b\xd9\xf5\xc7\xac\x99\x0bSs\xe8\xd85\xfe\xbc\xa1S\xe8\xc3e\x9f\x0e\xe5Jg\xe4\x00\x8b\xcf\xe6\xf3\xa9\xf3\xd5\xe0\xbd\xa52\xf0\xf2`/\xe6\xf3)\x02|sC o(\xcfk~\x9b\xe7Fw,\x16\x89A\x95Y\xb1\x999\xe9\x11\xf6g>=\x15i\xefm\xde\xe9A\xaf7\xe3\xb5\x8e\xb9G\xcd\x94\xd3\xcd[\x0bEL\xc7X\x87\xe5|XU\xff\xce\xa5^\x8e#\xd1\xd5S+\x0f\xed\xe6BX\xad\xbf\xd2\xef%\x8cx\xb6X\x1bGg\x9f\x8e\x8a\x91\xe2\xa0\xe7\xd0\x06\xdf\x05\xeb\xd2\xba\xeb\x9eH\xf9\xa9r\xe9\xb0+\xc2w\xdf\xc6\xd5s\x898\x10V\xa3\x01\x8am\xac;\xb1\xf0\xd1Z\xe3\xc7\xff\xe5\xe7~mj\xddkd\xf5\xccY\xc8JvdS.\x9c\x1f\xf13<\xe2;\x18\xb7\xc72\xdb=\x1a\xf7rC\x02U\x13\x9f\xd31\x8d\xa8F\xde\xd7Pr\x14\xff\xa2\xdc\xdf/\x1d\xb7\xdb\xc1\x14\xe9y\x00O :q\xd81\x87\n\x06\xe98\x98\xa2\xeb\x8dA\x92l:\xcf\xd4`\x83A\xcfU=s\xa3\x96g<\xb9\xf6{\x9d\xc9\xf5\xec`r=;\xeaL\xae\xe7\x07\x93\xeb9~\x99O\xb2^\x9f\x92\x82\xac\xd7?\x9cOw.kpf[zx\x1f\xe4\xb2S\x14\xdfR\xc7a\x96q\x81>\x11]\xdb\n2\xdd}\x12\x0f\x9dJ\x90\x03\xebG?g\x0d\xc1zV!\x14\xd6\x8f\xfe\x96\x1e\xfc\xb7\xf5\xe0\xbf\xa3\x07\xff\x8fz\xf0\xcf\xeb\xc1\xbfI\xc1\x9e\x02\xfe-=\xf8\xdf\xe8\xc1\xffV\x0f\xfewz\xf0\xbf\xd7\x83\xff\x1e\x05?W\xc0\xbfC\xc1\xbe\x02\xfe'\x14\\M\x91j\xfd\xe8\x0f)x\xa6\x80\x7f\x81\x82\xab D\xad\x1f\xfd}=\xf8\x17\xf5\xe0_\xd2\x83\xff\x17\n&\n\xf8\x7f\xd5\x83\x7fW\x0f\xfe==\xf8\x1fP\xf0K\x05\xfc\x0f\xf5\xe0\x7f\xa4\x07\xffc=\xf8\xf7)8P\xc0\xffA\x0f\xfe\x03=\xf8?\xea\xc1\xbfL\xc1\xaf\x14\xf0\x1fQp\xf5\n\xab\xf5\xa3\xff\x89\x82_+\xe0\xffY\x0f\xfe\xa7z\xf0?\xd3\x83\x7fE\x0f\xfeU=\xf8?Qp\xa4\x80\xff\xb3\x1e\xfc\xbf\xe9\xc1\xff\xbb\x1e\xfc\x7f\xe8\xc1\x7f\xac\x07\xff\x1a\x05\xff@\x01\xff\x0b=\xf8_\xea\xc1\xffJ\x0f\xfe\xbf(8S\xc0\xff\xb7\x1e\xfc'z\xf0\x9f\xea\xc1\xff\x9a\x82\xab d\xad\x1f\xfd\x19\x05\xdf(\xe0\xbf\xd0\x83\xff.\x05?S\xb7\xc3oS\xb8\xa7\xc2\x7f\x9d\xc2\xdf,\x14\xf8\x9fSx\xaa\xc2\x7f\x83\xc2\x93jH#\xebk=Y\xfeZO\x7f\xbf\xd6\x13\xda\xaf\x91\x88+\xe4\xed\xeb\xbf\xa3\x07\xff\xbc\x1e\x8c3\xa0\x10\xc3\xaf\x7fA\x0f\xfeE=\xf8\x1f\xe8\xc1Hh\x15\x8a\xfa\xf5\xdf\xd7\x83\x7fI\x0f\xfe\x87z0\x92 \x85,\x7f\xad\xa7\xd6_#eR\xa8\xf5\xd7\xbf\xac\x07#\x99P\xe8\xef\xd7\xffT\x0f\xfe\x15=\xf8W\xf5\xe0\x7f\xa1\x07# R\xf0\xed\xeb\x7f\xa6\x07\xffs=\xf8\xd7\xf4\xe0\x7f\xa9\x07\xe3\x9e\xfd\xab\n\xf8\xd7\xf5\xe0\xdf\xd4\x83\xff\x8d\x1e\x8c\x9b\xf3R\x01\xff\x86\x1e\xfc[z\xf0\xbf\xd5\x83\x91\xd9\xff5\x05\xfc\xdbz0\xca\x00\xca\xc6\xfc\xfaw\xf4`d\xb1\n\x07\xfb\xfaw\xf5\xe0\xdf\xd7\x83\xff@\x0f\xfeC=\x18\xd9\xb7\xc2\xd8\xbe\xfe==X\xcf4\xbf\xd6s\xc7\xaf\xffH\x0fFv\xf2\x93\n\x18\xd9\xc9\x17\n\x18\xd9\xc9_W\xc0\xff'\x05\xbfU\xc0\x7f\xac\x07#'\xf8D\x01\xff\x89\x1e\xfcgz\xf0_h\xc1\xdf\xfc-}i\xe42\xd5\x981\xd6\xd7\x7f\xaa\x07\xff\xb9\x16\xfc\xcd\xcf\xe9\xc1\x7f[\x0fF\xd2\xabH#\xdf\xfc\xbc\x1e\xfc\xf7\xf4\xe0_\xd4\x83\x91 (\"\xcd7\x7fW\x0f\xfe\x05=\xf8\x97\xf4`\xa4\xdf\x8a\x90\xf2\xcd?\xd2\x83\xff\x89\x1e\x8c\x84Z\x91/\xbe\xf9\xc7z\xf0/\xeb\xc1Hc?S\xc0\xbf\xa2\x07\xff\xaa\x1e\x8cT\xb3\x1a\x93\xc1\xfa\xe6\x9f\xeb\xc1\xbf\xa6\x07#\xa1>S\xc0\xffJ\x0f\xfeu=\xf87\xf5`\xa4\xc8\x8aT\xf0\xcd\xbf\xd6\x83\x7fC\x0f\xfe-=\x18)\xf2\x1b\x05\xfc\xef\xf4\xe0\xdf\xd6\x83\x91\xf4VC\xe4X\xdf\xfc{=\xf8w\xf4`$\xa6\x8aP\xf8\xcd\xef\xea\xc1\xbf\xaf\x07\xff\x81\x1e\xfc\x87z\xf0\x7f\xd2\x83\x91\xc6*\"\xe47\xbf\xa7\x07\xff\x07=\xf8?\xea\xc1\x7f\xa4\x07\xffg=\x18I\xef\x0f\x150\x92\xdew\n\x18I\xaf\"\xe3~\x83\xa4W\x11f\xbf\xf9c}i$\xbd?\xa3\x80\xffD\x0f\xfe3=\x18\x89\xe9\x97\n\xf8O\xf5\xe0?\xd7\x82\xbf\xc6\xd5y\xa92\x1e\x9c\xab@\xe1<\xdf\xb0\xe3\x9a\"\xb9|\x83\xc2R\xa4\xc2Q\xb0|\xac\x927\xe4\x1bI\xe1\xcab\xf2\x08a\x8ex\xdb\xab\xe9\xee\xa3Q\x945u\xdc(5\x84tL\xa6\xa5\x17\x9aT\x895J!\x83_\xc8\x81>\x1d\x89\xa2q\xcbx\xf1~\xa3\xeaKo\xde\x12zc\xbcK\x92\xf2\xe4\xdd\xdc\xf2\xc6\x9c\x92\xe4\x81\xa3}\x93\xdb]\xb2\xc2\xee\x82\x1aL\xa6x&\x9b)\x9euv\x12\xf4 \xeb\xf5:\x93\xeb\xc1|r\xbd\xebu&\xd7{\xbd\xc9\xf5\xfeEgr}\xd0\x9b\\\x1f\xd2/\x87\xf3i{\xe7\xae6j\xd1\xc9\xf0>\x9d\xf4:_N\xc7\xcf:?3\xbd\xc5\xff\xbf\x1a\xb8\xef\x11v;\xeeu\x8e\xa7\xf4+{\xc8\xbf \xf4v\xfc9\xfb\xd9\xeb\x1c\xc3t\xe7\x8e\xdd\x0f\x99g\xd8Vv\xae\xdc\x085\x99\\{\xfedr}\xd1\x9fL\xaeg\x87\x93\xc9\xf5\x9c\xfe\x87\nV:\xe1l\xc6q\xca\xd9\x9c\xe3\xa4\xb3Y\x9f\\_0\x85k\x8f+\\\x0f\xe60\x99\xa4\xf4\xf5\x8b\xc9\x84\xbe\xeb\xf5P/;\x9fO&\xe1d\x12c\xa1\xc1\x11\xfbs<\x99d\xfd\x83#Z\xa2\x7f\x84\xd6\x16Z\x11\xfb\xd3g\x7f\x06\xec\xcf.\xfb\xb3\xc7\xfe\xec\xb3?\x07\xec\xcf!\xfb\xc3\xea\xec\x1d\xb3?\x1ek\x81un\x9f\xfe\xd9\xed\xf5\xaaq\xae\x98y\xcd\x826\x0b\xecm0\x9d\xcd\xda\x96\xba\xe1P\x0b=8\xe4\xc3>\xbc\xd0[\xc9\xe8R\xd3I\x9d\xd3\x99\x9a\x1fL\x98\xb6{r\xad\xda\xba<\xad\xe9Mt\x0d-A\x95\x06\x8dU?\xeb\xfc\xcc\x84)\xdaQ\xd3\xceT\xed\x93\xeb\x191\xd9\xd7\xb60\xe4\xf9w2\xe4\xa1\x89l\xbcq\xbf\x96\x92E-\xcb\xed~\x9e\xcer\xb6\x96\x8a\xce\xeb\x8b.x\xd1-\xcd\x07\xb7&\xdb\xa9S\xb5>\xce\x8c\xd6\xc7\x85\xc1\xfa\xa8\xb5\xb5\xe2\x1d\xe8\x8d\x0c\x92\x0b\xbdA\xf2\xaad\x90\xd4\xd7G\x9f\xcd\xca\xaf\xdd\x14&\x96\xf1<\x8fs\x8f\xf3\xdf\xa6\xd3\x86\x96:\xfbt8\xbb].oW\xb71\xb9Mn\xd3\xdb+\xe28\xa7\xdc^9\x8e]\x98\xbb`}`\xa9\xf6NX+\x15}t\xfb\xc9'\xb7\x9f\xde~\xf6\xe2\xf6\xec\xf6\xcd\xedO\xbd\xa8T\x04mX\x9a*+\xfa\xb7\xdc\xa4\x7f\xe2\x8d\xa6\xe6-\x17\xf7\xfb\x87\xf6\xe9\xb0\x7f\xf6\xe6v\xf0\xea\xa3\xdb\xdd\xcf>\xba\xb5O[\xe3\xfe`w\xeaL&\xb37\x7f\xcd\xb1OG\x93\xc9\x05\x92\xf1\xf3\xa9#\xbf\x93\xa4\xb7\x83pv\xbb\x1b\xcfJ\xef\xa4\x8b\xfc\x9dg\x9d\x9fa\xef\x04.\\I\x03\xbb\x97\x8dJ0\xaf\x9b\xcd\x98\x97Y\xe48\xa8\xe6\xf4a\"\xc7a\xd5\x05\x98'@\xeb7:\xd0V;\xcc\x82l\x06_\x12vw\x9b\xe7\xc6\x9cy\xa9w\xae\xcf\x7f\xba\xf0\x92\xc5\x10o\xb6\xc5\xae\xf2p\xe5\xad\xf1\x99\x1d\xd1q\x07\x1a\x0f)\x91f\x0b+(=\xbd\xbb\\\xa6\\\xc6\x11rYU^\xe3\xf6o\xc55\x97\x0bf\x8a\xdb\x8b\xc7\xe1\x03\xed\x9d\xdd\xc4\xec\xc8\xa8\xb3%\x87\xdb\xd9\x92Y\xd6\xcc%\xf1b\x1b-\xc8\x04\x03\xb9\xe8\xa4_1\x13T\xd2U\xfd\xcaD\x18\x7f;f\x1e\xeb\xe3\xfe\xb4\xde\xb4N?\x89\x9c\x0b\x92\xf6\x81e\xed\x92\xc1\xdc\xab\x11\x13x\xca\xf0K\x82\xf2i\x19\xb8\xf0(\x12fe`\x82%\xbd\xf2\x1d\x8f-/u\x1c6\xca\xd2Z\x84\x970\xb5\x9d\xf1d\xfa\xd5\xfb\xdb\xe9\xce%\xd2\xf1\x0f\x1eYR\xb1r3\xb7\xf9}\x07\xa7\xfb\xe1)R\xf4\x89\xed\xdc\xe2\x06\xea\xb69`\xea`M\x1f\xf4\xbb\x1f\x9e2~\xf5\xc1\x9d\xe9z\xcbn\xa1\x0b\x1b%n\xc2\x03\x01o\x1e`\x18\x8d!x\x0e\x13\xfb\xb3\xd2\x8d\x9f\xcdQ'\xcf\xe5\xa6$\xbe\xccs\xb9\xed\x8c?\xefN\xdb\x1f\xect\xc95\xf1m\x8cR\x16\xe0m\xa8\xe2[\xf7\xe5\x8b\xf3\xef\x7f\xf6\xfa\xcdk\xbc\x87j\xe1\xa5\x15\x8b\xdf\xf6Kb\xdf9\xefw\x99\x03W\xd9\x15\x7f\xbb\x99hE\xcc\xd9%\x08\xb7M\xfa)\xed^gl\x9d\x9f\xfbQL:_$\xe7\xc9\xc2\x8b\xc9\xec\xfc\xdct\xa7\xe8\xae*\x05\x8dc\xff\xc6\n\x83\xe6C\xdbf\xb3&\x18\x03\xd2\x96\x85\x87\xac\xe3\xd1\xa3\xdc5\\\xa6I\xe3T\xef\xe6Y\x90\xa5\x0e\x0b\x1e\xc6c\xc6\x90;\xcf\xbe\xce\xfb\xd3:?_F3/Y\x9cSF\x7f\x9e\xc7\x94;?\xd7\x1c\xb9\x14\xbf\xf4\xf2\xf6\xdc\x16\xb5J\x93$\xa6\xa3<\x17\xc1\x1cl\xc5\x83\x0b\xa4\xb33Q\xa6\x0fJ\xde\xca<\xc4P\xbe\xdau\x99\xf4\x85\x7f-\xbf\xba\x82\xd7]N\xd9\x8dU\xe12\xfe\xa0s\xff\xe3\x9f\xce\xfc\xda\xc2i\xf9\n;\x8e0\x90\xc6\xfd\xa0\xe3\xac\xc1\xb1\xa61j\xf6\xb2X\xf9\xe6a\x16;\xa8]\xde\x89L\x18\xeb\xbb\x10\xb2\xdb\xc8\xe8\xc7')\xd7\x08\xf7\xfa&L8\xb8/uh\x12I\xc6\xd3\x07\x12B\xb42\x08\x0b\xd5\"\x89a\xebe\xe0\x93\xa6\x89\xdf\x08\xb9\xf4Bo\xccPH\xbb$-;\x14\xc1\xb6l\xba;\x8b\x04i\x1d\x8c\x1aE\xba\xebh\x8d\xa9\xda\x0bl\xc4k\x15.t:\xf9\x1c\xb9\xd0\xbb\x13\xbb\x15\x93\xf4\x974\xf8\x90\xc7\x13+T\xb6\xe3p:\xee7q\x9f\x87\x1cI\xee\x8b[\x1e\n\xa5t\xa5\x9b\xb1\x0f\xdf\x93Mw\xb2:\xad\x18q\xca\xae\xb9E\xc7\xa7\xd5n\xb7%\x0c\xe1at\xc6\xb4\xe1)^\xb3\x0f\xc7\x01\x9dm\x96\xe0~\x83}m\x1e\xed~\xe3hM\x18\x14\x8bT\xa5\x0e?P\x99n\x96\xdd\x95\xfb7\x12#3r\xb3\x1b\xa1\xa9\xb6;\xf2\xd5Q\x8clb\xb1\xac\xdb\x12\x80e\xcd\x96\x00\x17Q\xb4$^\xc8!\xa7\x94\x0d\xf0T\xae\x16\xb2\x9d\x94\xae \x93\xc8F\xf7\x90)\xb7_\x8c\xd2&\xc0\xb5\xb8$\x1b\xa8\xee\xbf\xdd.0\xd6\xf4-v\xa1f\x03\x16\xdd\xd0\xef\xbe\x101QO\xd3P\xd7\x80\x95\xbbe\x86\x1brv6\xcaoW\xf5\xef\xb7\xedv\x8f\xf6\x1c;\xb4\xf7v\x0f\x9c\xad\x8c\x90\xe63{_\x7f\x1f\xeaPw\x18\x0b\xed\xc3\x83\xc696,s^\x80q\xb3\xcc$\xd0zE\xe0!\xdd]F*\x0c\xb7\x02\xbci\xad\xbe/\xeaH\x04\xb5\xdc\xd5\xd4\x00\xfc\xaed\x84\xe1*\xc3\xda\xbe\xcb\x1f>\x8e\xc4\xf6\xc6\xe9\x14/lx\x86l\x17\nT\x85\xd0^\xfa\x94\xe0\xe4\xd3a\x14\xe0}\xe4Jp\n\xde8AQ\xdc\xa7\x82\xaa\xaf\x91\xc7\x01\xee\xa3Q<2\xdc\xa1P\xe2\xf8p\xbd\xeb\xd1\xde\xd6\xa8 \xc8l`\xa2\xf8\xfd\x928\xf4\xe8\x11\xa6*\x18\x0f\xa6\xec\xd6*\xfd\xde\x9b\xba\x0c\xd8\x9fR~\x96\xb7\xa5\x18\x8e\xa1z\x04J)Af<\xd4Ub<\xdcu\xd6\xfa\x87\xd5\xfbF\xe2:\xa1N\xe5\xd5W\xd5]\x83\xa69\x14wx<\xddd&H\x98\xf8]|e\xf8\x18\xba+`i3b=\xe5\xa3\x0d{\x0e\x96\xbc\xc1(M\x0b\x17f.\xac\xd9\xaep\xe1\xca@1\x91\xee\xca]\xbeAO\x8b\x99\x0b\x0b\x17\"\xb8\xe5w\x0c\xaf\xe8\xa6\xbc\xa9\x1fA\xcd\n\x8a\xb7\xee~\xfak\xbc\xad[]\x91\xeaA\x94Yy\xb6:\x8b\xdeC\xdel>L\x91\x8d\x85dZ\x96\xcb\xfd\x0f\xdea\xb91\xd1\xdf\xcd$\xc6\x07j\xeb\x9e\xa2\xa1>|P\xbf\xaf\xf7b\xea\xf7\xaaV4$\xd5\xbd\xc6 \x1f\x9b\x1e\xf04\xc4\x17D\xf4\xcbh\xae\xde\xd7\x04I8\n\x0d\xb5@.\x1dQF\xe7 &\xfa\x042\x16C\x9aO\xabW:\x13\x96\x11\xbd\xdd\x0e9\x06Q\xa8Z\xbd2\x0e\x10)z<\x13?\x85F1YH\xc9\xf7\x13\x8c\xcd\x8cX/\xc8\xee\x1e\xeb=\xd5\xf6zz\x83\xe8^\xbf\x8a\x12\xc8{\x95@H>\x17\x8e\xaa\x885\xe7\xf0*\".U\xb1\x00\xbdI\x84\xad\xeb\x99\x08\xa2WuOY\x94K\xc5\xdeM\xb5\xc4L.\xc18v\xb5\xc8\xd5\xfd5\xb0B>\xb9q\xe1\xd2\x85\x95\x0e\xfd)\x9a$\xdalT\x17\xf8\x84h\x9e\xbc\x83\x11\x9c\xc3),`\x08\x9e\xf6\xddk\x18\xc1E^BW\xc7\x19e\xf4\xb4\xa2wT\xacY\xc3)\xcc`\x08\xef\x1c\xfak\xa6\x16\x7fA\x8b\xd3Z\xaf\xe5\xe2\xd7\xa6\xe2\xcfD\xc5\xd7\xean~F\xf9\xb9\x8f\xd62u#\xe3&\xf5\xe5`Q\xad\xbe\xba\xd7\xcey\\\xe23\x0c\xd5\\\xb3\xbb\xf2\xf6Zgy\x85+T.\xae\x04;s\\8\xa7\x909S\xfc\x06\x9aU\x1bB\xc4\xa1\xefJ\x0f\xd4\xb1\xb5\xec\x10\x1ea\x90|=\x8dz\x0d#8Cer\x1e\xd9\xc8:?g\x89\x0eg\xe7\xe7\xa6\x0c\xd3_\xc0\x08^H\xaf\x91\xeakzj\x87\xf6\xbe/\xea\x0e\x83o)\x8e\xc3)\xa4,\x984*Vk2H\xbe\x84\x11|\x81Z\xd8\xa28\xd1\xcbD\xc6\xc9\xbe\xb4\xdf\xba\xf0R\xcc\xe3J=&n\"\x03\xb5pQm\xb5\xf6L]\xbe;3F\x95\xd3qc\xec\xb1\xfe\xd4\xb7{\xbc\xaf\xf5\x0b\xc9\xbe}\xbf\x90\xaa\x8c&;\x88`\x01o6\xb3\xd31\x99V'\x83~2\x89\xbey\xb3\x19\x06\xb5* \x94#2\xaf\x8eLq\xe0\x88\xca\xbe\x1a\x99v~\xab\x93\x1b\xde\xcf\xe2\xb3\x91D\xc4\x99i\xe8l\xc48\x7f\x9cbXs[f\xf3t\x8aM\x90\xa6&\x8c\x08m\x8acx\xac\x8fi\xac\xb8\x9ad\x06\xa9\x81\xbbE\x1d\xeb\xa5\x80\xbd^\x95\xdf\xfb*_\xa7\"\xc0@\xe5\xfe9\x8b\xfe\x1e\xd3\x15WytI\x1c\xf8\xc8K\x15G\xd5\x92$\x80a\xd7k%\x81O\xbd\xb5N\x0c\xc8\x9f\xbfB\xa5v\xb5\xc8\x8d\\\x849\xb6T\x8b\\\xcaE\xce\x88\"l\xacJ\xcfQ\x97^-r^*\x82\xca\xf4j\x91\x0bE\xee\xf9^6\x9f\xab\x1d~W\x996\xef\xa7\x02\xf2\xaeZ\xe8z\xe3@\x94g(\x17\x9c\xc25c\x0b\xaf\xe7\x1b\x07\xfe\x13\xb4:v\xe1\xda\x85\x17.<\xab\xa2~\xf2.\xc0\x08|Z\x1d\x96\xef%\x04\xde\x0d\x158p\x06\x98\xcayA[\xa3r\x9e\xd0\xdb[`\xcf_\xcf\xe7 I\x8b\xe7\xecw\xad\x00B?)\x06\x10\xbb\xc0 vy\xf4T\xf6K-\x8f\x1d\xbd\xd0w4\xb7|6\xf5\xb6\xf5\xc2\xa6\xc4=\xc0\xab\x1e\xec\x1bqtY\xbf\xb1\xb5\xa5\xda\x1a\xc2\xd7\x06\xf8Um\xef\"\xbb\x9d\xba\xd0\xd6i\x9d\xf1\xedE\xed\xdbi7\xf4V\x84\xe9/\xf1\x1b\x06jY\x91$\xf1.9\x98\xff0T\x7fc\xe8\xf4\xaa\xbeYfYR\x83\x88\xe6\xef\xcf\xf4\xef\x0bQ\xcd3\xbcvi~\xed\x0b\xe6.P\xcd\x1d&>\xb9Xf\xd3\xfa\x13\x0ch\x8d'\xbd\x96\xd0P\xa0\xb4\xfaE#\xf6 \xe9\xed\x19\xd74\x98\x9b{\x9b\xd7\xf5\x16\xe7\xc3 \xaf\xc1\xed\x08\xe6.<+\x0e\xa2\xe6\x86_b8\xc5\xd7\x88\x88\xaf\xd1T m\xe0Zy\xf0Y\xa1\xb1q\xe1\xa5az\xcf\xcd;\xba\x10\xe3\xcfD\xccJ:\xa83\x11M\xb6\xf4\xa2^v\xbc\xbb\x11\xdb\xe9\x16 3\xf5\x94\xed\xae.i\xdb\xca\x87<\xad\x0e\"\x8cA\xf5\xa5\x89\xb7\xaf v\x85\x15\x8e\xdbm2\x85\x11:\xf5\xa7\x95\xcbq\xce\xb7\xa11\xfbv\x86W;65\xa1@\xd3\xb0\x8cx\xb0\xd7\xd3i\xcc\xfa\xaa\x08\xf5@\xda\x03\x9ewO7\x89\xa8Q\x81G\x10\xa8\xf38gv[\xcd\x89\x123\xef\x19S\xa5.1m\x82M\x1c\xc9\xd2\xd4\xf2\x8d\xf4\xa8Hm\x00#X\x9e\xc0\xba\xc6\xe4\x81\xb9\xb9\xc7k\x83]\xa0e\xfb\xa8\xb1\xc0\xdc(C\xc9\xcbn\xe1lh\xe3\xa0m\xcc\xd03YG\x13i\x1b3\x96[\x88>\x96T\x0c3\x0d]\x14\xe6\x82V%Bg\"+\xea\xd8\x0f\x8dCO>+T4\xf4\xe9il\x0dO`i\x9c\x99K\xb4\xa7\x88\xf91\x98UV\xe8\xce\xb80L_\xe6\xe4\xfa$\x1fox\xae\xf0\xfc\xbb@,J\x11\x7f\x86\x90\xd9\xf4H\x8cP\x86^\x89\xc9\x8c,\x9b3\xce\xe1\x94\xf6p4b\xc7y\x8fW\xc2P\x13\xeb=7\x9b\x9cQE\xa3\xe7 \x171\xf1\xde*OT\x83\xf0\x0d2L\x94\xb2\xfd\xc2\xb7\x1d\xfdF\x16u\x14\x1f\x0dI\x88\xbf7\xa6\x89\xbf@!N\xaaU?\xf5\xefP\xba\x93\x8a\xa9\x03\xba\xa0\xfb\xe6\x1dm\xad\xdc\xc9\x80\xa7lS\xa0\x8c\xd3\xdb\x96\xd8\xf0r\xd8\xf5\x0b\xfa\xecBV{#D[\x16\xdb|'\x97}\xc7\xfc\xd0\xd9\xd4o\xc0\x12\x13\x99)\xe7?(\x82o\x99\x88P\xa6\x91\xfa\xeb\x0e{=}\x0c\xca\xbb\xfbN`\x10\xe1\xc8\x85\xe0\xce\xc7\xe2\xbd\x9e\xfe\xbe\xd0Qc\x97\xd4ZE\xcd\x11\x8b\xefnpHc\xaa\xc6\x08o`G.\x84\x1b\xdc\x0ehf\xb2\x1a\xbd\x816^=)\xc5\xa7\xcf5KR|\xfat\x1c@\x1bX\x8c\xfaqh\xf0>\xbf\xfbl\x9b\xf2\xae\xe8\x8c\x11\n\x0b]s\xe6\xf92y\x11f+\x96\xb0K\xd5R\xf0\xd7.I*\xf1[vfNT\xddEV\xca\x0c\xa4#\x15\xc2J#\xa9\xe5\xc6S\x18V\x0c\xfe.\xc46\xcb\x1b\x94\xd7\xa6\x0dO \xd5XD\xb8'\x1aMh5K\x0c\x0c!\xd0\xe3\xa4\xf7-#M}\x92\x83\x9e\xc8\xe9/c\x91\x9e\xe0f,\x0f\xbf\x86\x89a\x8cN\xf4\xe2D\xea\x15\x8d\x83v\x1b\x13\xc4o@\xc1\x9aB^7N\x84\x81\xb8\xdc\xfd\xa6\xe6\x9eAy\xdc?\xd4_B\xd4'\x0dQme<\x81X\xbf*\x82&\x06\x1b\x9a\xee.\xd7\xf6r\xa8\x8e\xc4\x85\"\xec\x84\xb2\x92\xe8D\x83\xa99\x02\xa3\x00\xca\x9e\xb7\xd0\x19$\xd3\x96ZWJ\xb5\x96(\xbci\xcb.P\x0e\xbe\xbd\x859\xfdoI\xff[\xab\xa5f\x98\xb3\xfc\x94\xb2\x8c\x1c}\x99\xae\x8d\xca0\xba\x9c\xa1r\xce-\xa3\x84\x87~)<\xbe}\xcb\xcf74\xbb\xeb\x8b\xf2\xb3m\xb1*\x90m\xdf\xb0.\"8BUS\x01\xb6\xd6^LB\x0e\xc0\xf7\xd7\xac S,I\x05\x0b\xd5P\x05\xf8Z\xaa\xd2a\xe2\xda\x8d\x0bW\x0e~\x9f1\x03\xf7\x8d\x9e/\xcd\xee\xbb\x8b6&'\"-\xac\xa0\x17\xe9\x89\x03\xb1\xc8\x8a\x12\xea{\x17\xdfy+\xeasS\xec\xe96\xa2\xce\xb6\xdc\xb4?\x0c\xb4#\xe0w\xbab\xae\xa3\xf8\xb6h\xd4\xdd\x15\x1a\xa6\xa4\x1d\xfd\xaa\xec\x16\xe9',\xc3d\x82\xc5\xf4d\xe3|\xfa>^F^\xba;\xe0\xb6w$\xe3\x95\x87\x07{\xfa\x87/\x85\x86E\xf7\xa4\x7f`|dj\xacP\xd9\xe8\x1f=_z\xab5\x99\x99K\x98\xda\xa4\xcfJ\x8db\xa6\xdc\xb1\x0e\x83*o\xea\xeb+\xe9\xeb+\xcfr\xf3G\x05^\xe8\xee\xd5\x07D\x01r\xfbGu58\xae(\x0f\xd0\x18R\x81 \x03H\x05,<(*`a\x0b\xa9\x80\xd1\xfeQ\x85q\x9bG\x05\xfcC\xe2\xbd\xcd\xfb\xd1\xea\xbb\xdbm\xc1\x88o\xc1 '\xf8\xf8\xb3\xd5\xca\xc6tW61\xf7\xc6\x1d\xd9\xec\xcf]#L\xa6fu\xe5F\xfb\xb8F\xf3Ul\xf1\xbeb\xf3\x03\xbe\xcf-6\xc3\xa5d_tr\x18\x1b#\xdd0\x9a\x9177k\x06S\xab\xc0tQx&U\xeba)\xca\xb1\x9e\xb4T\x8f\xc6\xb5\x80\xd2\x10vs\xb8\x98\xe0\x11\xaf\x1a-O>I4~\xba^\x1da\x14\x9f\xfa\xc4\xd3W\xb6+\\Q\x95\xfe\xb1\x98S\\\x8b\xb3\xfbG}'?Zn\xce\x15\xfa\x86\x03Z\x7f\xa3\x03\xdav\xb2eu\xe9P\xf7\x14\xcb \xe3U\x7fx\xa1=\x1eO\x0d\"YHE\xb2\"\x85\xbct\xc8\nq\xff\x97U1-\x9eF\x8e\xb9:\x98\xa4\x8fm\xeeU]\x19\xd2tm;\x19b\xa0<\xe5\xbfQ\xfd$\x99\xbbF\xa0W(\x11>\xc2\xdc\x92{{\xdb\x9cv\xa9\x06E\x8eD\x8e~\x0c0\xe0\xf2\xa1nu\xed\xa6\x99\xba\x9a=!\xf22uW\x1bR\x9b\xca\x92\xf7\xa2\xb1\xd2\x90\x07\x86\x84\xd0\x067\xd9\xbdA\xd5W\x92\xfbP\x0e\xaa'4\xeeC9\xa8\n]\x89^F\xe3N\x94\x8as\x06=t\xf9v\\\x81b0\x0e\xbb\x1axg\x8d\xd0\xa8\x02] 4\xab@g\x08\xad\xe6\xdf\xa3\x07#\x89 \xb2L'\x1a\xb1\x84\xee\xae+4[\xc7\xf8\xbf$\xe4\xd8}\x87\x1dJ\x82\xd2\xbb\xc8\xed\x8b\xd7\x02,\x12\x95\x8a|?\x8eVABD1J\xae\x93hyElV_V*\x8c\xc2FQ_\xc6\xceD\xa5\"\xb9\x90Q\x14\xf3\x9cB\x87\xda\xbcA\xf5\x87\xd2P\xe7c*.;\x96\xb6sM\xc69\xc4>8\x05\x9f\xa2\xba\x9a*\x93\xc7?\x10^\x12Z\xfb\x1e\xdaT\xe7\xb5\x96r\xcd\xca\xa9\xdc\xce\xe4V\xa0\xab\x07\xa7\xd3P\x85\xc6\x03AWE\xbe\xca\x86j\xea]\x0e\xca\xebo\xa8\xc2`\xfe\xafV\x91\xe3\x87\x81\x94\x80\x96MT\x92U_mGovw\x1d;\xb4\x0f\x1d\x17,\xb1&\xa6(5[\xdej\x94j\xe6S\xfc\xf0\x15\x9f\x91\xf4\xe1+\xe5\xcb\xf0@\x15\xf7\x8f\x0c\xa1\xd4\xb6\xb7D\xe4\x82\x87\xb8\xbf\xe7\xf2\xdb)B\xb5\x1e\xd6\x18E#\xaeeW\xb7>p\xa6\x91\x8e#\x9d\xba\x94\xa9Kx~\xb4\xd8\xce\x1cSX[\xd8\\\x8a\xa9\xb9B`\xba\x01\xa9\x0f_\xb57\xd0)\x0b(\xbb\xd4\xc5\xaf\xd2\xad\x86PhV\xcb3\xfewXe\x8bs\xd5\x04\xbf\xdc\xf0\n\xa1A\xc6\xc8\xf8\xe1\xd1c\x99A\x13\xdb\xc7\x95%\xcdW+\x85\x9e;\xd0\x05%\x90Z\x90L\xac\xec\xd4\x90\x07\x17\x89\xd8\x9bh \"\xb8\xc0s\xb8\x85\xe5\x03\xc92\xfd\xa3\x8dn\x83\x1bL[\xb8\xf0\xba@I,\x9d\xa7^|\x96\x86\x1a\xc0)\xa6\xc1mJ|k\xe8\xfe\xce\xf8\xf3\xeex2\x9d\xb6o'c\xfbthwN'\xb3\xb6}:\x9ct'\xb3\xb6s\xea\xdc\xdac\xeb\xf1\xd4\xb1\xe9\xb3\xd3\xd6d\xe0\x8c?\x9fL\xa6\xb7\x93I\xd7\xf9\xf0\xd4\x99\x0c\x9c\xc9\xf4\xd6>\x1d\xe1\x1b\xb7\x93\xf1d\xea\x14_o?p\x9cj^3:\xdc\x9d\xc9\xc4\x9eL\x9c\xd3\xea3\x81\xebGN\x83\x1b\x8a\xe9\xc8\x02\xc5\x0c\xed\x1d\xb0\x9b\xb8\x98N\xf6y4#\x98RV:\x98X\x16r\x14\x11\xfa,.O\x17s\xa2\x8cLGa^GLq\xab\x94C\xff\x83>f\xa2E\xe5y\xaa3A\xc9!%\x18D\x8f:\xd16\x8bH \x8a\xce\x89f\xbf\xf9\x1a\x99I\x06C\xec\xab_\x05\x90,y\"\xf8\x00W5\x84\"\xb4\xa2[\xf1\x14\x026 \n\x8c\x11x\xdf\xf3\x17\xfa\xb8\x07w\xa6\xb4{\xbb\xfa\x83\xc6\xdench\xc3\x1ab\x86\x1b\xb6\xc5\x8f\x92\xe2\x8eK\xdct\x00\xbc\xcf\x11\xad\xd4\")\x9d\xc8\xef:5}\xc35\xfc-mj\x8a\xedL\xd8\xd4\xf4,\xe8\xf0\xae~\x00\xb9X\xe0s\xcb\x07\xe5Q6)\x82\x009\xb9\x15j\xc9\xbcd\xa0\xdd\xf6\xe1 \xcck\xafg'6\x19\xfbS\xa3\xdf\xceR\x90g1\xf7\xd8\xbf5=k\xa1\xbf\x8d\xfa^\xca/s\x97\x1eh\xc5\x074\xac\xd1>\xb6F0\x87SX\xc2\x10Z-{\x0ef\x031g\xa1s\xfc\x9b\xd9k\x17\xe6\xdc\xbekKq\x13\xef\x8d\x87\x06$\xbc\xbb\x97\xc2\xae\xde'doW\xef\xbf\xa2\xca5\xd9\xa6\xc8c\xe8z\xc4\x9cD\x98G\x01\x06\xbcj\xde9w\x9e\xa7\xbc@\x9d\xc2Z,1)\x87\xa8\xaaz\x8c\xdeu\xca7\x91J\xee\xd3\xfd\xb8\x12\xb9\x0e\xee\xd3\xd9\xbd\xdd\xaa2T\xa8\x83\xf4\xa9\xb2\xf7vu\xc4\xe8S/]tW\xdeu\xd3\xb0\xcd\xc2\x98W\xb3\xf5TMA\xcb\xcb\xd5\xaa\x9d\x8aO\xde\x95\x88\x98\xc1+\x13I\xcb#\x93B4\xc9\x13\x9e'\xe8\x0d\xeeA\x1b\x12\x0c\xbc\xe62^\x1c\xd0\xf9\xdeu\\H\xee\x8f\xb6\xc2\x15V\xd1o\xe44V\xf6eb\xde(!\xb4\x01\x05\x9e>\x0c\xa1\xd3wN\xf06K\xd4\xe9\xc0\x10\xda\xed\x88%TW\x90\x85N\x13\xb1\xe9\x91\x0b\xbd\xca$Et\xa4\x9d\x86\xbb\xc7D\xdb\xdbm\xce\xc4_#\xec\x98d\x12\xf8 \xe8\xeb%\x12\xb1w\xe9\xd2\x12\xe8\xa0\x10N`\xd8\x18\xc2\xc1<\x82=\x9d\xa8\xd2\x87\x9d\xaa\"\x0b\xe3\xbbt\x0f\x8f\x0f\x0f\x8ew\xfb\xbb{G\x07\x83\xdd\xfe\xfe!\xd9\xed\x1dm;\x01\xb9\xaa\xfb\x94\xf9^1S\x01\x13\xe3\xa8\x04\x8b_;\x01{\xcc\xc2\xbeu\xe8\xfa\xf7\x1d\xf8\x10\x1d\xeeR\xb1SR:r\xfc7\x92!w\x9d\x0b%^3\xd7&\xe8\xb4\xc3\xaf\xbcW*-\xd8\xf9|\x92\xb4o'I\xfb\x83\xea)\x83Ex\x1ew\xda\xd3\xde\xf5\xb8\xd79\xf6:\xf3i\xfb\x83\x9d@\x15Vv>\xef]\x8c{}\xcdS\x9f=\x8d\xc6\xbd\xce\xa1\xe61\xe5\xe0k/N\xc8\xcb0\xddvI\xe8\x8e\x91\xa3\xbd #`\xbeqR\x95\x10\x05\xb6yc\xa1J\xd3p=\\\xe0\xbf\xd6\xc6\x91\xe6\xd7\xcfN\x8b\xef\xecJ\xb3^\xe8\x89\xd9\xc9\x9e\xdd\x10\xa2\x9b\xa1T\xea\xbd:J\x11\xe4\xae\xa5\x19e\x19\x8f\xda\x95&\xd9e\xb1r2j\x95\x00\x87,\xac6K\x14\xa3\xdd\xc4xN\xf3E\x118\x85\xb9\x9dv\x93e\xe0\x13{\x80j\xa7S\x18\xc0\x10\x8e\xe8\xa8=\xa9X\x84}\xba+r\xf7\x15uK\x03\xb7\xdb\xab\x8a\xd8\x99V \xe7\xa6\x8f\xbdf!\xc9\xcc\x01\x19\xf7a\xb2\x12\xe5W\x86iC)4\xaf\x86\xb2-\x8aGL\x8c\xa1VE\xf1\xfcc\xd3\x172.\xdaf\xf0\x04\"\xe6\xe8\xd4\xc7\xb8q\x81\xed\x8d\xb3)\xbbH\xe6\x9c\x98\xf5\xd1\xa6\xd8\xe7\xdb\xae\x84\x9eN\x18\x82\x0d\xa9\xea\x98L\x08T\x1b\xac\xa7\x86)\xe0\nd\xf2\nT\xef\x1f\x89\x83\x93\xf0\x8d\xd0\xd2\xdeV\xab$\xd5x\x18\x1b\x86\xb1\x8e\x08\xf7e\xae\xe0\x18\x96\xa2\xdfz\xb9\xbe+\xe4\xee\x9f\xe1\x98L\xb7\x8f\x99ne \xc1\xec8~*\x99/\xb9\xd3\x05\x0b\x97!\x9clx<\x18\x92|\x1a\xcd\xb2%\xb1\\\x85\xc1,32,E\x8es\\\xbcs\xbd\x8a\x82/\xc9\xec\xcc[\xad\x97\xe4\xe38Z\x9d\xf9\x0b\xb2\xf2`$=|\x1e\x13/%\x7f\xe3\xd3O^\\c1\x16J\x0d\xbf\xfe\x8d\xd5\xb2\xf2R\x10\xceI,\xfdN\xd4\x9a\xb9\xa1\x1bH\xd7Wk^\x9eh\xf0\xa9\xaf\xa4H \x90\xe7\x87\xf6\xde>=n*H\x85\x8f\x0ev\x9dM\xa3\xb1\xc8|\"\xed\x16\x13\xc9e9\x95\x1a\xcc\xc8\xdc\xcb\x96\xe9\xb0z\xab\xf4;\xea7\x81kj%\"\xf3Q\x8e\x04&\xaa\xcc\xbb'\x90L)\xf3^= \xb2\xa2\xe7d\xe5\x05\xcb-Z\xc8\x12\x12\x7f\x97\xb0\xd5\xe8\xfa\xd1j\xa3\xb6x\xbf\xceg^J:i\xb0\"\xd6\xe6-\xa2\xaf\xc5G^J\x9cn\x1a\xbd<{\xcd\xbc@m\x8d\x1dBs\xda\xc5\xcd\xb9y[\xbd\xcd+=\x9f/#/}\xe0\xaa\x830%\x97\x0f\xdea\x1eD{X#T\x88\x8fX\xe5<\xee\xb6t\x8c\xe9r\x94fQ1\xf8\x0f\xb5\xfd2\xba\xab\x07\xd0\xfaN\\\xe5\xfel#\xb0{.\xc4]\xe6`\x11\xcco\x1c\xadB\x03rC\x8b\x9a\x82H|\x02|>\x8f\xe2\x95g\x88\\EI\x827\xc6\xfc\x91\xe7\x16\xb4!\x98\xa2\x0b\x90\xf6\x12\x92\xc0K\xec]\x90|\x9c\x85\xbecGx\x82\xb2\xd1\x1ek\xfd |\x1bF\xefBxs\xb3&C\xa0\xf5\xa5\xd8\xbb\xba\xa9\xf1M\xc40\xa7J\xa9^u)\x0e\x85\x9e\xf0%\x17\x97\xb2\x9fB\x1f\x8a\x9c\x14\x94\xc9\xe7E\xc6\xfd)\x15\xde\xe4\x9f\x98\xc7\xca8{\xcaR\xe8\xe2\xc5\x81\xf0\xf9\xadY\n\xb4yw9\xfd\xd0\x17\xf1\xb0\x08\xbf\xc4\x17\x10\x8dg/\xf0\xf9\n\xba\xdel\x16\xd0\xc9\xf1\x96\xdfo(?\xc7\xf2AJV\x86\x02h\x14\xe9\x06\xa1\xbf\xccf\xe43\xe2\xcd^\x87\xcb\x1b}\xd1\xb5\\\xf4\x87q\x90\x12ZV/\xe8I\xd3\x9f9e\xdc\x99\x11\xb2^\xdePz\xb6\xfe\xeb\xe4\xc6\xc1#\xff\x07\x1f\xc4dnma\xa5\x94\xe5\x8a\x92ou7\x08g\xe4\xfa\xf5\xdc\xb6\xfe\x8aU\xc9\xcc >\xefM\x16\xa2H\xef\x7f\x1c\xb0\xe0\xb7\x91\xe4\x1a\xae\x176kb\xec\x82hc.f\xc3 \xaf\x8a\xdb6^\x1c{7*\x97\x01\xedy\x01U0\x85\xb7\xf9\xc8l\xed\xbe\xe2\xc1\x06\x14\xcc\xae\xba1\xca\x9fY\xe56\x8b\xfc\xc9E\xf5+*\xd8-\x1cX\x8c\xaf\xa6t%\xe8\xdf\xee\x8c\xacc\xe2{)\x99\xe1\x8d/\xf9Q\xccq\x0d\xd8\x05\xb6\xea\xe3w\x02\xbf\xf0\xf9\x1a\xef\xb9\xcfh\x81\x11\xa46-A\x85B\x83\xd0\x8f\x13\xcd\xb4N\xbe\x03\xb3\xcav\xe9\xd7\x8c\x06W\x90\xbe\xee\xebQ\x01\xaa\x11\x0c\x94y\xf4\x1d\x97\xc5,\xb0o\\\x8c\xb2\xb6\x82\x11\xf4O`\x05O`\xef\x04V\xed\xb6\x03\xb3\xb1U\xee\x12\xa5\x95+:\xb4K}\xb78\xd2\xcfTT6\x91i\x8e?\x0c\x19\xe0\x94\xa7\xb2 \x12v\xbdl\xde\xf5\xc2\x9b\xd7s\xd4\x92\xb1\xaf\xdd\x95\xb7.<5\x9a\xee\xe6\xb2\xf8\xf3:\x9f\x08\x18*ME!\x11M\xe1\xd7\x07lj\x9c\xdas\xfa\x94\xd2q\xd2%a\xb6\xc2\x10\x8c\x82c\xcb\xdf\x87|\xa9B\xca\x0e\x97\xc1\x97\x04\xbb\xe7\xd8\xec5g\xdc\xa3uX\xf3`IX\x8a\x8d\x08\x1d\x9b\xd0\xa5I\x17/_U\x12\xdbU\x19\xbf\x9e\x96\x89\xe1u\x13V\xfe\xd1#\xa6\xb6\x17\x00\xf4h)\xb8\x01{\x8e\x1cF\"C\x8aO\xc6{\xd7x\x04\xd9\x88\xa1\xb2K\xcb\xdf\x1aO\x8d\xb6\xe1\xa9x\xff\xa5\x86\xa7z\xf8|\x13\x86\x19m\xc90\xa3&\x86\x19\xd5\xb3\xf25c\xba\x9b\xf0\xd4\x85\\4\xe7\xa9\xfa\xb23l\x99#\xb4\xbe\xc8\x15\xd26\xfd\xb3\x9b\x9ag\x97(\x86]\xaf\x96\xfa\xc7\x94\x86]b|2\xfd\xf3s|\xbe\x8e\xc9<\xb8\xd6\x97\xb8\xc8kH\xd6\x9eo\xa8\xe6\x1d\x9b\xda0[\xe9\x9f_\xe7\x87d\x03\x03\xcfj\x188\x9a\x07\x1c\x96\xda\xfc\xc7\xc1\xc5\xb3&.\x8e\xd1Y1l\x8c\x15F\xa9wI'\xc7b\xfe\xb1\xf69\x9c\xc29\x15\xcb\x87\x16\xba\xb6;\x94A\xb8p\xc1\xf4\xf37c\xfa\xdc\xba^-\xc3\x043e\x9f\xd3B\xf8\x13o\x03^\x18\x04\x1c\x99)\xa0[\xe5\xdcD|i\xe99\xc5\x07J8\xf0\xef\xed-\\\xd2\xff\xbez\xef2\x08\x0f\\'\xff\xa0e\x18\x96\xc0e\x97\xc7\xe0\xcd\x85\xbf+\xee\x95;u+\x1cbIy\xc3R\x8dZe\xe4\x0c\xf43\x17;\x90\xe5\xa4\xa2\x953?>\xe4\x08U\xfd\xbe\xf8h\xf8\xd3\x8c\xb6>\xdb\xbau\xc1V\xb6n]L\x03/9u\x01%\x9c\xa2\ns\xab\xe7^\x9a\xc6C\xb81T\xee\xc2\x95\x1e\x1b)e?3\xb8XB\xc1\x8a4\xabb\xdfsY\xce6\x9a\x15\x17\xce\x0c\xebb\xdfsa\xb6j\x9f\x97R\nm nk\xd3\x12\x01\x9f\xfa\x17zq\xbbA\x9c~F\xc5ii\xcf\xd0\x9d\xb8\x14\x1b\xf0\x85Y:\xa5}{Q\xb9jh?ct\xa3\xf5b\xfcL\x12\xbcooa-?(Dn*\x8c\x1b\xa6\xab\xd4\x0e}\x8b\x11\x89\xfc\xab\xe8!\xff\xdd\xa58\x1b\\di\xed\xb2\x89\xcf\x15\x8f.YF\x05\xac\x0b\xa54\xda\xd9\xfc\x971\x05K\xf5\xf3\x85\xe8_-\xd3\xae~\xde\x8a\xb78F\x99)\xbd\xf8\xdc\x8c\xf3Q\x0br\xf8l\x9a\xb3,\x14\x9b\xbe\xa0#\xf8\x82>\x91\x80\xcb\xf13<\xf7\xe0\xdf\xf2\xa3\xb7\x14\xfe\x96\x0214f\x82sQ\xbf0\xb5\xa9^\xe4O\xb9\xb3#P;\xef\xca\xce\xe9\xf2\x0cV\x84A1\x00\xbbT\x86\xc1Mv\x19\xe9s\xc5\xe3f\xa6lt\xcd/\x94\xd1\xe3%\xa5\x14|\xa7 \x19\xf5\xa3\xd0\xf7R\n\x1fJt\xf5e\xc3\xb4\xd5\x91Fq\x98\xe4\x0d5\x11\xea\xb2\xb49\x04\xebYx\x93.\x82\xf0\x12|/\x84\x0b\x02\x0b\x12\x13\x83T@;\xedo\xca\x11\xaa\x0d%\xa6s+%r\x0f\xc8g6\xa0\x91|\xe6\xae\xcb\xf8\xbf\xe4\xae\xb1\x12h\xc63&\x94\x17\xf5\x1d]\xd4w\xecT\x96\xb0\x80kl\x85o\xe0\x14\xc6\xfa\xbe\x1b\xfb\xfd\xde\x85kZ\xd1u\xb5\xeb\xef\xb5v\x90\xa5\xd9\x17\x81\xca;\xeci\x19K\xd1\x08Z\xd2s\x05\x82n8vX\xb5:\x01\x1aJ\xfc\xa5\x17{\xb4\xc1!\xb44\xd7\x1b\x83pF\xc2t\x08\xd6$\xad\xdc\xae\xab\x9a\xcb\x00o1\xd4X\xa5h\x7f\xa2\xa2?\xcb&\x13W\xa5<\xc7\xa9\x06\xab\\\x0d\x87\x96<\x05\xf6\xabn1PxK\xec\x0f\x9c\xeeY\x1a\x13O#\xfe\xa3N\x8c~\xb1\xa4\x15\x83\x8a\xf5Jo\xf5\x04\x919\x80\xd24\xcd\xc9\x01=\x05\xd0\xa5\x11\xc7\x1e0\xd1!\xbf\x92k\xb3\xf7\x9c\xee\x17Q\x10\xda\xe8KgYU\xdb\x9a\xf8$\x94\x8c\x19\x84oC4\x08\x1b\xbdD\xd3\xb1\x142\xe0-\xb9I\xec\xd4\x19\xf7\xa6SdyI\xf7\x9c,\xc9\xaa0\xdbr\x80\xa0\xdc\x91\x9bC\x02?\xcaB*\xfd\x84\x12\x0c1\x89\x0d\xab\x0c\xa3-{20%q\x9c\xadS\xcc\x00'\xc0\xfa\x19\xf3\x99\xd3\xbe.4\x14\xf0S2\x957\x95\x87\xf9z\xad\xcd:\xde\xf24l-\x02\"y\xab\xf5m\xa8~r3g\x1b\x1e\x8f\xac\xc7\xd0f\x0epmxl=6\xbe\xf8\x1e\xbd\xa6\xc7dj\x14,7 \x93\xe2z2\xc7\x08%\x94\xad\xf8\xe0\xa5\\\x81B\xfa\xbb\xb9Pv\xc6\x18\xd1\xca\x0c\xf7\x1a\xc4'\xe9\"\xcd\xa48\xb6\xb6\xf9\x0f\x0cty\xee\xcf\xbc\x14\x95RK6\x9d\xb6\xf5\xa45~\xfe\xd1\xb37\xcf\xc6\xf4\xc0)J8\xb9\xe3\xde\xced:\x99>\xdd\xb9t\xc1\x9aN\xa7\xd3\xa7y\xf1\xa7xx\xb5\xa6\xd3\xa7\x16V\xcdW\x13Q\xdf\xe7\xa1k\x96\xd2=\xaed\xc3\xf8\xc5\xf2G\xbb\xb7N\xc1\xc2\x01!T\xd9YpJ1\x90\x0f\x19\x86\xa2\x0b9\x15\x816\xf4\xf1r\x81\xbdd\x89\xb5]T%\xb5zyo\xd1\x13\xd3,T\xbc\xc77no\xa5\xc1\xd5\x8865\x0b%L\xea\xc6w\xf3\xfe$\x9a\xee\x189\xb3~F)E\x19B\xa4\xdf\xd49}\x18\xd2U\xd3\x16\xc9\xc5\xfdd\x08s\x83F.\nS\xe4l\x06e\x13#aC\x08M\x9d@\xca5\x04\xaf\xeey\xd5e\x15\x94\xa9xo\xe0#^\x1d\x1f)\x11\xf2\xc2HL$\x97&\x8a\xcf\xba\x08\xf1\x82 \x12\x89\xcc2\x0f|\x0c\x9fK\xa7$\xbf\x9d`\xa6\x9a\x81\xd14\xce\xd3X*\x95\xd5\xed\x1d\xe1$W\xbc\x94,\x82yZ\x0d\xa8#\x7f*\xc6=\xadKX\xb5|d\x07N\xb3\xc2\x8c~p\xf25gp\xf1\xd1K\xe9z([\n;F\xed\xf5)\xce;\xe3yB\xa1f\xf3\x94\x0b\xa7`=\xd9\xa1T\x8d\xffn\x83\xf5\xd4\x92Kq\x06\xfa\xe8\x11\xb4BZz\x12\xf2\xc7\xe8W\x8c\x17\xc9t\x1b\xcf\xbc\x8aQ\xa3\xd9\xa3\xd5\x92\xf1\x04\x9dr\x8b\xdf]o\xbd&\xe1\x8c\x8a\x0d\xae\x8cO]\x06\x0cJ@\x11\x1d\xccn\xf5\x1c\x17Z\xbdMH\x04]4\x8e\xc9\xf9\xac\x95\xe7K\x9a.i\xa2\x8a\xdd/,\x07\xa7`\x01++=CI\xca\x02\xcb)\xde\x8dq\x85D\xf5|\xfaqo\x08\xd8\x8eiM\xc4\x02\x97\x96\xa5\x15W\xb7\xa4xC.\xa8\"#\xae\x0c\xde\xbd3]\x87\x82\x1a\xa7;-\xcd\xd0\xd0\x0bD\x1a\xf4H6\xa8_9\x0d\x0b\xd5\xb52Q\x16\xf41\xc5\x08\x00\xdd\x04eh8e\x99Px\xaax\xb3\xb5\xc3\xb2\xcc\"\x9c\x89\xcc\x0bW\x00>\xa3\xfc|,A\"\xda\xac\xf894\xb6\xb1\xe0q\xe4\xcd[ef\xe6\xfe\x0b\x863\xe4:}\x13\xf8o\x99\x13J\xba\xe5N\xbc\xaa\x95\x0f+\xc4\x0e\xf5\x1e\xf6\x1c\xda#\x96\x8c\x12\xf2\xd8\xab(\xc9 \xb7\xc79\xe7\xd7V{\xa2\xd0\xb2\x89\x08\xe3\xc1\xd2L\x1agv\xa3g\x94\xf8\xf8]\xb2\nR\xdb\xa2\xd2\x99\xa5\xb5\x9c\x8a\x0f\x15P\xd8\xfaoHT\xeb\xe6\xf1\xa6v\x1e=\xfb\x8a'\xa0[\xbb\x98\"\x91\xb2\xbd\x9e\xa3\x0f\xed\\\xd3\xca\xa5q\xf8\xccf\xdf0\xcb\xe9\xb75\xcb)\x95\xf58\x88\x843\x0b\x7f\xc6\xc4\x9by\x17x\x00\xa7\x04H<\xf7\x97QB\x0c\x91\xee@\x7fl\x00\xc3rT!\xc2M\xa0y\x1c\x0b5=$p\x94\x08\xbb\x92j\x02q\x1b\x8f\xee2\xd4\xc5s\xae\xbe\xe6+\x12'\xa8\xd3\xb0\xfa\xdd\x9ea\xd7\x93\xd0\x8ff\xe8\xe1\x19w\xc5wFr)\xbd\xfa^\x8a\xd9\xd4%K\xb2b*\x85\x02\xf6\"\x87\xd5b\x9f\xd8\x87\xfa\xe1\xa2\xc2a\x08\x99\xcd\xb4\x81E\xecD\xbc\xc8\xc5\x82\x15\xe6\xbe\x06&%\x0c=\x0dm\xe2\xf5 \xc2\x9a\xcb\xf2@\xa2L\xe5@\xba\x88\xa3wH\xc61(\xacm\x85Q\n^\x92\x04\x97!\x99A\x1a\x81\x07,\x14uK'?\x88\xcf\x95\x94\xaa\xbb\xde\xdePdG\x96\x143\xe6\x8a=[\xea-'\xaa\xa1[\xaa\x81\xa9\x80\xdaT\xc0\x10\x94V\x0e\xbc\xdfD\xdb\x08\xaf\xdc\xd6\xc9\x8a\xe2c\xa2R\x86#\x1f\xa5y\x9b.\x89\xc4p\xd9\xee\xa1Ccv<\x91\x01\x9a\xca\xb9\xe2 \xed\xe9\xc6$S\x9dW!$\x96\x91=\xffU\x8a\x1a\xba\xbbg\x88\x18*\x0fG\xb0\xf3\xf2\x00\xadG\xd6\x10\xacG\xdej}R!\x8a\x8f\xad\xc7\xf4\xc9\xcffQZ}d=f/\xad\xa3Dy\xf4\x04\x1f-\xd5w\x9e\xe2\x83\xcb\xf4\xa4\xa0\xa3\xd2\xb0\xb7\xbal\xc5\x89\x17\xa7lH\xbcru\x8f=~d=y\xfax\xea\xec\\\xd6LF\xa5\xc2pL\xaaI\xb4`\xb8m(\x8a\xd2%\xba\x93\xd2\xbc\xf3[\x11\xfd}\xa7\xfb\xe2\x8a\x84\xe9\x8bU\x90\xa6$\xd6)\xf9\xd5\x83t\xccc\xa1.\x02\xe5Z>\xfd\x84\xf6\xee\xbec\x07.&\xd3\x0d\xba\x9f\x15\x14\x93\xb6x\x80\xc0\x1f\xc6A\x9a\x03\xf7\xf6\x8f\x11\xf8Q\xb6^\x92k\x06:\xe8!\xe8M\xec\x85\xc9<\x8aW\x1c\xdaG\xe8\xf7\xbd$y\xb3\x88\xa3\xecr\xc1\xe1\x03\x843\x9d8;\xd8\x05r\xc2\x8f\x00\x9d\xc1j'\xffJ\xca#o\xd2\x9c\x07\xfa\xd3h\x8a\x06a\x1c\x0e\xbb0\xc5X\x0dZ\x89\xe9\x1b\x18\x1bh\xede \x91\xbe*\xc7&}\x93\x91\x96\n\x85\x05\x1f\xc2\x1ac\x92d\xab\xd2\xf7\xdaSY\xd8\x8d\xc2\\$\x0b\xd0\x81\x0e\x01\xb1\x17\x84\x96\x0b\x11B\xce\x83\xe4,\x9d\x05\x11\x957\xe4\x81\x11$*\xb7\xb7`\xb3j\xa8\x18\xe7\x82\x87\x02\x11\xfd\xcd\xc46\x17\x92\xaa\x16\xef\x8a\x874k\xf5M\xf3\xebi\x07\x9bac\x19\xe7\xb8)\xa3c\x9b\xcd^\xb2A\x85\x86{\xe03\x92\xa4qt\xc366\xff\xb1i\xb3\xbe\x9en\xa3\xaf\x90\xed\xb8\xdcN\x1cw\x97A\x92\x92\x90\xc4\xcf)\x1f\xc2\xfd\xe4\x82E(3\xb5\x1c\xc1_\xab\xf4V\xdf\xe2\xdc\x88&\xab\xe8\x8a|\xc2\xdb\xa9\xac\xb9\xf2PZ\x7f\xf5Uy\x9d\xab\xcf\x8a5\xd7\xbe\x89#\xa2\xc2\x92\xaeU\xf9\xa9\xa9\xd5ym\xabsm\xbd\xc5\xd3\x9a\x9d \xc8-\xc3\xe4R?\xab\x10\x19\xdb\xe7\n\xb6\xcf\xf3w\xca\x10v\x94\xa1\x04\xc8b^\xceM4\xdca\x8ec5d]\x7f\xab\xaf\xa0\xeaG=\xa7\xcb\xc2\xe3\x96\x19\x9e0\x1e6\x86\xc8\xa9\xa2R\x8ee\xa9\x16\xcbZ\xcd\\\x0d\x84\x00i\xa7 %\x19#\x8e,E\xbe\xb9Y\x13.I>\xf7B*LR6\x03\x1e\xf8K/I\xc0K\xc0\xcb[\xd2\x1c\x0b\xdf\xf3\x0d\x94\xcb>\x0b\xe2\xcd\x80E\xa3\xe1\x90\xd4\x0b\x96e\x08?\x0e\x8c\xaa^\xcb:$I\xd5\x8c\xe6\xf5r\x9a\x10m\xf5\xf3A\xb7\xa21S~H\xaeS\xa6\x8eR\xc7\xa9\x8af\xf2P\x9eb\xc0\x92|\xb8\xa8\xf5\xc1\xdb\xc0\xc3\xd2\xac\x90\xf2\x94\x10\x17\xdam\xa9\x9a\xf2l\xb8\xa5\xb1g!\xea\xbe\xbf\xfd\xe1\xe7\xfd\xddd\x0ex\xec\x0ci&\xd0\x11\\\x1ec\x051\xb6\x19\xb32b\x13}\xe7\xe2xQk\xddy5\x15'\x1a\xda\xa3.\x9d\x91Z\xbf\xc3\xbe2\xc4\xd3\xd2\x80\xaa8^Y\xf2\xa2%:\xbd.t:RU\xda\x98\x85u3\x82\xb1\x0e\x9bf\xa4\xaew\x0d;\xb0\xdc\xda\x17Q\x106\"\x1c\x9b\xffQu\xfe\xc5E\x0f\x8d\x17s)\xean\xdeY\xe6Zl1m<\xae\nO\xcdM\xe7\xed\xc4\x81\x10\xda#4\x81\x13\xc3\x9a \xaeR;\x7f\xe8{u\xcf1\xc5]o\xb9\x8c|\xbbg\xf0cV0\xa6\xd0\xf57\xa0]13xj\x0eXl\x08\xde\xde\x0f\xc2\xc4\x9b\x13;\x85\xa7O\x9f\xa2v2+O\x9fG\x97\xf3\x04\xb2\x13\x07'.\xc36\xd8\xacF\xfc\xe2\x04^\xde\x8e\xd67,\xb0\x01}\xa5-\n\x96\xa2\x18dl\xd2MS\x1c)S\x9c\x03\xdeSI\x0b\x03s\x06\xdd L\xd6\xc4OK?\xba~\x96\xa4\xd1\x8a\x91\x89\\9\x93/\xd0\xb8ZpZ\x87\xecb7\xe7/i\xd4jlXC0\x92\x1c}\xb8\x1e,.\x05z\xcfMo\xec\xe2h1^\xe3\x89{c\x7f$\x1d\xfb.sw\xbd\xddF+\x90\x88\x0fS\x1cu\x13\x92\xbe\\\xad\xc8,\xf0\xcc\x1e\xae\xdc>\xc3|\x8cx\xcab5&\xb3\xfc\xf1k\xaej\x007\xdb\x98L3\xc0M7iw\x16\xf9\xa8(3\x97[\x97\x12B~_ \xc9k\xcc*\xa7}`\xcc\xa7N\xab\xc2\x8clk:'o\x82\x15\x89\xb2\x14NaM\xc9\xb5[D\x8c\xe7yk\xa6\xccq\xfa\xab\xf7\xdd4bW\xdb\xf9\xe9[$\xb6aQ\x8b\x9a\xe8\x88\xf8Hf\xa0Z\xca-\x7ff\xb6&\xaa\xaf\xf8\x98\xf4[0\x94Q\xa7\xae \xb4\xa1v\xd7Q\x92~\xca\xb3\xf9\xb3\xac?\xc1\x8an\xc93?\x0e\xd6\xa9\xd1\xddG|\x04\x11\xd79\x08V?x\xcc\xefF\xe1\x8a5Woh\xcf\x85\xbf\xbc|\x13\xd3\xab~\x88\xde\x84 \x7f\x18o(f\xc0\xb6,\x17\xac\x0f-~\xa8(\x1a\x0e\xab\xa1\x94K\xb5\xe8W\xc2vP!\xc5\xab~\xbe\xf0\xc2\x90,\xe1\x14l\x1b\xa3\xa7\x90wP~\xe4t\xe9\xbc\xf7\xf5\x03\xaeE\xae\x99\x9d\"\x057\xa9<\xb7\xc0\xd3\x08;1(M\x8a\x01\x0bQ5\x86\xc6E+\nc\xe2\xcdn\x92\xd4K\x89\xbf\xf0\xc2K\x82i\x92\x97\xa3\xddvD\xbe\x8b\xe2\x0e.Z\x06\x0d\x97\xbd@r\xfb\xaa\xdf\x85\x94\x1f_x\xfe[\xe3qV|\xbc\xf82\xd1\xf9\xdb\x89\x8f\xe1\xae=\x14l\xc8\x1f'S\xa6\xdf\x8e\xed\xc4q!i\xb7M\x08\xb7fG4y\xed\x16J\xd9:\x1f\x82\x85y\x89Yzw\xf0\xab\x81\x9b\xa1\xa1\xca\x1a\x1f\x15T\x8e::\"\xa1\x9f\x94\x86\xbb;\x02[h\x17\xeb}\xf4\x1a}\x9e\xe7\xdc\xf5\xa6\xaeL}\x9a@\xf1im\xb8{\xe4O~:\xed\n4k\x16p\xc4'\xc6\xf7(\xd6\xd5\xf7^|\xf2\x14P\x0d\xba\x0b\xdd\x07\xfd\xae{f\xdf[\xdd\x87\xd4\xf9O\xea>\x0d^\xda\xd5\x0f\xf6\xa9\xbfm\x9f\xe2qo\x93\xbbU\xf2\xe7.\xfd\x1a\xdc\xa5_.\xc4\xe3\xfe\x8f\xa3w\xbbw\xef\x1d\xfd\x7f\xf0-\xf7\xb1\xd1\xd5[\xf7A{\xfd\x12U\x0e\x1aw\x0f\xddG/Q\x97J\x98\x84\xa3\xbc\x00\xcc\x83\xd0[.7\xa1\x0f\xccp?\xdf\xe0\xbc`|\xba\xa9\xdfoE\xb7g[Y\xc8\x02\x02\xcedY(!\xcby\x11\xa9?\x0fN\xbc\x08\x12\x0c\x83=\xc4\x02\x92\x0d\xb8\x949\x14y\xb1\xd9\x15`\xf3[Q9\xfb0\x90M3\xf1E\xdd\x03\xe9.#\xdf[\x9e\xa5Q\xec]\x12)\xa2\xa3:)r\xfeTm\x855\xef*\x10aQ.\xb7\xaf\xe5GBa\xc8sn\xa07\x99\x95\xc6\x19a\x87\x7f\x1e\xd2.t\xbai\xf4I\xf4\x8e\xc4\xcf=\x8d\x01Y\xfe\xb5q\xf0R\x10wal+\x8c>\xe2A\x88\xd0\xc0b\x8a\xbd\x0d\x92\xb1\xa9\x1a\x15\x13\x8a\xb14\x9eapm\xb4ai\xe5\x12\xa1m\xa1\x85\xa8\xd2\xb5\xaa\xef\x91\xee\x1e\x81\xf8\xd0*b\xcf'\xa5*\xe0\x14\xfc(L\xa2%\xe9\xe2C\x16\xc0F\x80\xdeyq\x88g%\x1c\xa4\x1aD\x0f\x8c;-W\x170R\x93\xa2I\xaap\xc4j\xda\x87\xc6\xad\xb4\xd1\x1e\xd2+\xe2J\x19\x96\n\xb0\xe4\x06r\xac\xcb\xa3\x14\xda\xfb}\xed\xad\xcfH\xdd\x1e\xdc\xb6G\xe9\x82d\xde\x8b\n\x1c\xa2+\x15\xa9\x01\xc9\x0bG\x12MpS\xac\xb8\x1b\x84\x0b\x12\x07\xd8yt,q%\x98\x1d1'\x93H\xd2\xab\x9f\xa7\x92\xcbH\xddd\x01\xa2\x06\xb7DT\xdb\xde\xc2\xb3\x86.\xcf\xe1F\xcbS~k\xd0\xbf\xc3K\xfd\xfe\x81S8\xc5\xdc\xf1}\xc9}f\x93\x1a\x9a\xec\xcd\xfdc}\x16\xc4\xfe\xb1>\xcf\xcd\xdeAs\xac\xf6\xeaBqK\x04\x0bH-\xc7P\xd2\xeb\xcc\xb3\"zU\x8c\x97R\xd1*g\x13)\x8a5\xe6\xd6\xcb\n\xebWau\xe8z\xc9M\xe8\xf3\xe4\xadYw\x1d\x07\xab \x0d\xae\x08\x9c\xe6.0pZn\x02\x87u\xbc\xef`6\x0c\x1e\x03\xca\xd6\x948pl\x82w\xe5*\xcf\xa4zi\xb1C\x07S\x0e\xc8\xc0\xfd^\x9f\x01\xe9\xd7\x01V\x93w\x15\xfd~\xec\xfd\xde.\x82\xd6,!\xa7\x00\xee!p\x16$\xeb(\x07\xf6\xd1f\xd3]y\xd7\xcf.sX_\xc0\x04\x80\xbd\x19\x939\xba\xa7\x90X\xc0\x0f\xe8\x8e\xa3\x88\x92m\xb9k\x9a\x10i\xef@\x17\xb9\x1du>\xdeE\xa2\xa2\x12>\x99/#9\x97\xf5f\xe8\xc4\xd1$H^y\xafl\x8c\xfb\xcf\xd2x \x96\xa40\x82W\x18\xc3\x153H\x0d\xd8\x9e\x92\x07\xc6\xcb\xc9l\xfd\xe4\xe8\x02\xd9]\xb1 v\x89\x0b~y\x81\x03L\x9dBe\x1f\xbb\xc8?_&\xb9\x8eDv\x04\xb9\xd1\xb8\x83\xbf^\xd3\xc6\x13x\x8c\xa5\x1f\x83\x17\xce\xe01/\xfe\x18|\xe6\xe2sA K\xd0]\xfc\x92\xa4\x0b\x12W\xb5\xe5|\x19\xcbazr\xd1\xc8:?\x17\xd1\x19\xce\xcf-\x16\xaf>\xec\xce\xa3\x18\x9dp \x0cYf)\xcf.B\xe3\x93\xfc[X\x0c#\xe24\x9f]\x0c\xcbh\xd5 s\xd7\n\xa8\x8c\xd1(A\x87c\x82q]R\x1e\xa8\xddW\xee\x13\xb1T\xce\xe7\xe7\xeb8\x9a\x07K\x12\x9f\x9f\x03\x8f\x14^@0$\xa6\xdf\xcd\xd63/%/\xc2+\xbcJ\x9d\x87\x9fx\x90\xbd\xd3\x88\x93\xbb\xba\\\xbcBU+\x89Y\x17A8S\xb1TS\x90.\x95\x8a\xb6r\xe2\xff\xd2\xc3\xa4x(y[\xf1u\x7f\x99\xbc\x08\xb3\x15\x89\xbd\x8b%i\xa2\x07\x9b%j\xd0\xde\x84\xa2\x934g7\xd3\n\xbc\x1f\x18\xe27\xacK\xa5vk\x0ew\xc5n\n\xec\x90\xa58\xf3\xf9q\xdf\xb3)\xae\xa1Ux\xdeM\xa28\xb5\xb5\x04v\x8d\xa9W\x11\xf9\xd7\xb8\xdc\xc3\"\xfbL\x83\xc6}>N\xa7\xc8\xcf\x99\xc4\xed\xd2\x01\xca\x93e<\x88\xf1\xde'\xecE\x96R\xf8T\xd4\xe3\xbb\xb0t!\x1c\xa7S\x17R\x91gD{\xa3\xdctX}\x10\\\xde;\xacRR!\x81\xea\xf3E\x1c\xe9\xd3E\xec\x1d\xf5\x9d\xee\x8a\xa4\x8bh\x96\xe8(\xed\x9e\xf2\x1eg\xd6\xc7\xba\x04\xd3\x9a\xbd\x80g\xc2r\xc9\xf9\xa6\xbbfYl\x0cff,?\x96\x1c\x14J\x89\x1d\x94\xf0\x9d\x0b\x94\x81\xa3J\xcc\x80\x19B\xc9*hL\xdd\xa5?H\xa1o\xb7\x0bW.\xdc\xb8p\xe9\xc2\xca\x85s\x17.\\x\xe7\xc2\xb5\x0bg.\xbcp\xe1\x99\x0b\xaf]\xf8\xc2\x85\xb7.\x86\xb1Z\xe2\xe9KO\xf0\xaf\x98T\xdc\xe2\x020%\xe5\x9cw\xe7\xbai\xc6\xabS\x89\x9eK25\xc5\xfb3\xcct*\x831\xb8\xd3\x08\xce\xba\x97$e\xd1\x87\xcf\xba \xfd\xba\xc2\xaf\xcc\xac\xe1b\x94\xce3f>q\xdcB+\xd3\x8dI\x12-\xafH\xcc\x82\xcc\xbe\xe5\x9c%\x87\xd2=\xfd\x05\x8f\xbc\x144\x04a\xe1\xfc\x97\xfbU\xe5\x04D\xa5\x1e\x94\x1fcp3\xb4\xd6\xbf\xb5#\xa7\xe8\xd2\x88\xf1\xe8\x1b\n\xa4Et\\\xf2%]\xad\xfc\x1c\xfe\x82\x16\xcb\xb8W\xf2%I-\xdc\xb4\x11\xf3\xc5s\\x\xa9\x8dhO\xfb\xc0\xd2\xf2a\x94\xe4\xc2\xfbp\x9e\x93\x13v\x86\x8f\xc6\xbd)\xeaQ\xaap\xd1\xe7\x11\xcb}c\xd6\x08iF&D\x8b\xd8\xb6\x9e\x07\xb1\x9f-\xbd\x18\x82\xf0*\xe2\xaa\x1c\x17\xac\xe7/?{\xfe\x83O\x9e}v\xfe\xf2\xd5O\xbd~\xfe\xec\xcd\xcb\xd7\xafLVwZ\xeb\xa5\xad\x89_\xfe\xbe\x08i]3\x8d\x0f\xd4\x13\xbe\x1a/\x99=2p\xe1\x99\xbc.\x89X\x17n\xc1\xa7bH\x99|\xbap\xe5\xe4y\x07\xe9\xfe\xa8\xd5\xb6\xe1\xe1Y\xbf\xaa\x86\xa1\xb2{\x02\xb5h#\xae\x12\xe4\xa8[\xe0\x90\xc1\xa5\x10\x8dm\xba\xa0\xc9\xa7\n\xbe\x14\n3\x18V\x90\xccqMh\x9ew\xfa\x81\x17\x89\xf9\x03\xa0\xbf\xb0f\x99\xf2\xfb\xe3\xb8VD\xcdu.\xa7\xfa\x7fXR \xdf\xefD\x8e\xc7\xf5\xc4\xb8\x0b\x8d\xd3\x14\xd4.kP\xa6\x06\xba\xcc]\xb8M\xefK\x0dj:\xf7\xc0\xcb7\x0e\xe8\x1e\x0b\xb5\x8b\x17\x88u\xa3\xe2\x97\xe2\xae\x9bi-\xffQ\x1c\\\x06\xa1\xb7\xd4Z\xfb\x85\xb0>\x84/\xd4\x87\\\xd2\x7f\x85\x91\x83\x90\xdb\x8b\x9fj\xd9K\x92nr\x0d\x94\x0f\xf2m.\xe7\xbd\xb5S\x07\xb9\xdc)\xdc\xb0@\x0f\x1c)R\xba\x18*\xd5S[^x\xc9\x16-\x1b\xd6Q\xe3\xda\xa3i\x8a\xf1\xdbMZ3\x900`\xfd\xd5\xf7\x00\xe7\x04\xfd{W\xccM\nF\xf0\x12EU\xee\xbe\xc0~\xbc\x96\xd1\x82=\xb1P\x9a%\xba Q\xea PL\xd8 #\x8fP\xac\xbc\xd4\x0f\x03\xcf\x83\xe7\xf4\xc8'\x89Fn\xde1l\xc5\xdatb\xa3R2\x9f\x9aK9B\x9dC7\x7f\xae\x0ey\x81F\x0f\xccI&\x83\x9f\xe5`>K\x85\x1b\x95\xfdZD\xf1X\x94T\xfa\xfa\xb8\x15j\x7f\xe9\x18\x870S\x1f\xe4g\xe1\x0d&8e\x92-\xdf\x9ej\xb3\xd5\xed}\xa1\x8aj\xe6{,n9\x87\x8e\xba\x86l\x0b\x86\xb8\x05\xc3\xb2\x8cFP\x92 \x99\x8c\x96q)\xb3j7\xde\x92\xa7\xe7\x8an^\x1bg~\xe5*\xa1iki\xc8G\xc1T\x18\x17\xc9[\xa8\xa6=w1\n}P\xefF\x8cH\xdf8w\xbc\x1b\xc5\xd09\xcf\x1d\n~'Mk\xcaW\x8dNhA\xddB\xd6Y\xba\xa3U\xbd\xcb\xf5\xb7\xd6\xcf\xac\xbb\xf0\x121\xf7\xda\xee\x16XP\xd3q\x8e\x18\xb4\xaeT\x93pum\x7f\xa1\x0b\x8c*\xeb\xbe\x86\x10a\xd8*#\x89\x8d\xec\x0b\xcdSN\xbb\";\x13\xa7\x1d\xb5\x15\xe4D\x91\xfdN\xf7\x0cyEd_\xab}\xcer\xc8\x83\x9c\xf0\xfb\xc7\xba\xfc}\xf4\xe4\xaf?\xe1\x0ft'|\xd4Kv}o\x9df19K=\xff\xed\x9b\xd8\xf3%\xb6B\xe48\x1d\x8d\xf6\xa8\x90;#2u\xa7.\xf7\x98\x07\xe5\xfc\x1fj\x89\xa4\xa2c\xd2\x9e\x85#;\xe1\xa1\xb6<\xc6\xd4x4R\x91\xb8\x1f\xed1\x89\xc8\x14\xc9n\xe1F\xa2l\xd8\xf5\xa3\x19\x8a\xddxO\x87\"\x1a-CJ\x02\xcf=\xd6hs\xa3\x02\xe3\xc0\\I\xc1\xe2\x84ln[`\xb1l\x88\xad\x8f\x882\x8f\xa2!X\xb1\xf7\xa5U\xa5Qj\xd9\x0b\x8a\xf1\xd6\xec\x9d\xb7A\xd94\xfe\xf2f\x08\x16\xfdS\x0d-\xecb\x80\x9a\x08s\xb7]x1\xcb\xe1\x16\x7fy\x83\xb4\x81ve\xf6\xce\xc3\xf7\x1eXo\xbbgH\x8d\xaaU\xdc\xa2\x11g\xe5]o\xa0\xd41\x18\x08\x8a[8\x91\xe2o\xeb\xc2\xa0\"w\xa3\xa3n*+:Q\x1a-yhk5\x8df\x17\x9et\x1cS\xf9\x9d\x8cc\x8d\xabi\xa3\xbfN\xc8\x02\x15\xd0}\xdd\xe8{\xc1\x04\xfe\xfe d\xf0\x04\x92\x13h\xb73v\x7f\xad\xd8\xa0\xd9\xd4\xc5\x80\xb7yh\xa2jv\x82J\x1c\xb407\x8bh1\xfd\xdb0\x1c\x1e\xee3\xc3\xa1\xa4ag\xa6\xc3\xc3\x83o\xdbt\xa8_D>V9\xae\xac\x95\xdb\xd4-\x8c\xb4X^\x87\xdaE\xd5;`=\xb0>Y\xe1\x1eA\xd9d\xd1\xb4\x9d\xaa\x1d\x17\xe6f\x8c\x84\x9b\xaf\x0d;\x9em\xebzr\xa7\xbek(&oB\x1fR\x9d]A\x1b*Ks\xc7\x81\xe3\xb0\x1f=\x82`,\xec\x12\x98\xbe\xa1\xf5 f\xd6*\xfe\x1f3\xfc\xe7w\xe5J\x17nS/\x08\xf9n8\xea\xddc7\x88\xd9\x96\xc9\xfc\x96{\xa5\x8e\xd7\xc5E_1\xe7\x88\x08\x17\"\xa06r/\x91\x9d\xbb\xfal\x1eE\xd6\xc3\x18\xda\xc50\x95\xa9\xe4wa\xee\x8a\x0d\x95#b\xc9\xb6\\NDy\xdf\xceW\xee\x92\xba\"\x18\xbb\xc6\x04\xb4\xd4[E\xd7\x1b[r\x16\x9bZrf\xf5\x96\x9c+\x83%\xa7\xd2\xdc\xcd\xa6\x06\x9fK\x9dE\xb5\xac4)\xbf\xb0\xd2\x12\x0c?\n\xe7\xc1e\x86\xb6W=\xd1 \xb9mV\x1f\xf5Z\x04I\xaa#+j\x9akJ\xa2\xe2&a\x05\x84\xc0b<\xb3-\xd1\xa5\xe1RF=\xeb\xfc\x9c\x10t\x1b8\x95b\xcb!\x8c\x1e\xe5(h\xd5\xc5\xbc\xe70\x82\x99P\xc8\\U\xdeva\xe5\xb8RA^,\x1c\xa7S8\xd5\xc5[\xe7O\xe8\x1f\x16\xac\x0d=O\x11:\x821\xb3\xa5\x92i\x01\xe2\x91:\xca3V\x11\xf5B\x9f\x0c\x91\xd0o6K\xae\x1c\x0eL|J\x13\x15\x88\x88|\xcan\x0d7\xb9\x9f\xc8\x8d\xd4\x01{\x03\xaf\x91 \x97\x8df\x8fX\x8c\xadCg\xf7u\xe8\xe7\xf1|\xce\xcf7\x9c\x8a\xf9|\x88\xa2\xef\xa63\xc1i\x84^\xcd\xcd&\xa3\xa5G\x9bR,\x05\xfd\xfb-\xbb\x82X\xce8\x9dn\xf0\x9e\x8a6,\xb6(}[\x9d1\x10\x92w\xc4n\xbe\xd1\xc5\x8b\xc7\xd1\x94\x8a\xb0\x91\x03A\x11\x927\xd0\xcd+{J\xe5\xe4\x81\x88K%4\xfa\x1c\x05\xe3q\xc4]\xe40ie\xdcM\xd6x\xeb1r\xa1\xaf\xbb\xb7\x87\x96\xb4\xb8h6\xaem\x96kc\xc3:\xcf\xf8\xa6eg\n\xc4\xac\xf1~\xe2U\x1e\xd1\xa2v\xdd\x0dt\x82r\xe3\xa0\xbc\xa0\xe6\x15\xd1\xafc}\x1cx\\\xc5Pc#c\xb6!9\xd5\n\xbb\xebH\xd8\x89\x85\xc0\x13\x08\xe9r\x13\x07\xa21\xa1\x0f\xcb\x17\x1dI\xcd%8l4\xc0\xe0\x15\xec2+\xaf\xb7w\x82\x847\xa0/\xb3\xaa\xf9.\x8e\x0bC\x8e\xb6RnJ\x15\xb7\xc9\xaac\xa9\x9b\x80Mnl-\n\xe2\xb2\x08\x92\x86{F\x0d\xf7\x8a6\xb9\x89Un\xaf\"\xaf\xdc\xbf\xf5\x86\x9bVu\xad\xbb%\xdd\xd1\xfd\xfa\xb2\xd1\x8d\xaa\xbf\x14\xfc\xa4\x9fue\x16L\x98\xf7\x1d\xfd\xaf\xf7\xba@\xcch$\xb1\xab:O\xc6K\xe7vP\x85S\xc62\xb7#GGx\xe6\xb6\xec\x0b\xcd\xbc\x08o\xec\xaf\xde3]\x9c,\x1d\xd7_\xa1\x16\xaeb\xccU\x02\xad.3\xdbgq\x88\xf3C#\xadTn\x8c\x08\x9f%:\xa3\xdf\x81\xfb\n\xcc\xdc\xd5\xa9\xea\xd3_\xa3W\xd5\x88\xcd^\x9e\x9b\xb0\x12\x99\xb8h\xaf>p\x80D\xf7+i\xb05\xdeG\xd2\x0b\xe8,d\xa7\xe3\x10-\xcf\xf4o\x19%\x1c\x91\xf4\xce+\x19\xa5\xd5\xeb\xfb\xef\xdd\xedN5\xa8\xf6B}\xd7\x86iy\"~(\xce\x14\xcb\x8aC\xa5\xae\x8b ,\xc5]\xb9\xefQ\x88\xadS\xffX\xa3\x1d(%\x94\xbb\xe3\xa1.`\x9a\x8d\x94\x8a\x07\x0f\xd4\xed\x8d\xce\xd1B\xb3\xcc\x04S6\x92y\x1cUrq\xd5\x9d\xb6Y\xe8v\x14\xddq\x0d\xc7\xa8Gv\x99\x8ax\xea\xb8\xf0\xbd(Z\x12/\xb4Q\x94!E\xb8e,\xc0LA\xe8\x15\xfd\x10c\x96\xf4\xbcG\x07N7HI\xec\xa5\x91>\x90\xe3\xb1\xde}|O\xb9\xcd\xc5\xf6\xe8\xa0\xba\xa3=\xfd\xd6M\xf4\xead_\xbf\xff\xe7\xbc\xcdj\xe5\xcb*^mt\xacV\x0f\xcb\x8b\x878\x8cj\x9e\xcb\x87Q\xf5)\x1e\xe64\xf1\x17\xdf\x1bO\xf2\xe5\xa3\xfa\xb6\x9b\xa8\x10K\x8d\x1e\x94\x8d\xa6\xa4\x17\xb5\xa6$\x0c\xb2T(\xe6\x13\xa6\x98\xf7\xed3\xa4A\x9e}\xc6\x83#\x02\x8f\x16\x8eh\x8e\x0bG!\x11\x0b\xf6\xec\xe4q\xf2\xca\x95\x1bb1\xe0 \xe8\xcc$\xee\xa1S!\xde\xa0\xe1\xbb\x93y{\xda\x97P\xc4\xe9\xa7$\x85a\x11\xbf\xb9\xcdo\xeb\xd1\xf3\xb9}S\x928\xfa\x0e&+\x1bA\x8a\x17\xd1o\x0c\xd2\x10;\xd5\xd1V\x1b\xa4\xf0r\xed\xa5N\x95B\x8c\\R\xb1&t\xe0\x86\xf9\xf2\xa5Z\x07J\xf1\xe1#5$\x0cU\xa0*\xe4\x06\xb3\x05~\xc7\\\x08\xe7|\xa9\x98\x91A\xb5M\xd8\xef\xb0\xbb\xf1\xd48\x178\x0f\xe7\xe8\xe5\xfa\x8e_Ge~4\x94`\x8a\xf9\xa1\x07\xe4\x0b\x18\xc19\x06\x16\xb3\x8b\xc9i]tgQHN\x1c\xb4\xbf\x9f\xc1\xa9\x10\xe2\x983\xf0\x05\xd3\x98p7\xf6\xfc\x17\xe5\xdf\xf6\"\xd7\xa6\\\xbb0\xb3opg,\xf0\xae\x15\x9f\xe6\xebj\xa3\xed\xb6!a\x16]9Mv\xa0\xc2\xdbs^\x83\x0d8\x03\xf2\xda\xebF\x8f\xe3uQoW\xc1\x89k\x8e\x10\xbfz7\xa4\x82]#\x05\xbb*\xc7\x92\x1c\xa9\xb6\xc0\xa2\xd8vx0\xdb:\x9bt\xd5\xd8\x0c| f\x8c\x07\xd8\xb3\xa2\xfbn\x8d\xccW\x89\xb0\x1b3\n8\x1b\xa7,\xcb\x1f\xcb\x9e<=q\xa0\xdd\x8e\xb5\xd4\x0b\x8b\x8e\x80\x17\x9d\x8a\x9c\xab\xf6\x9a\xa9]\xac\xef~\x17\x03\xab\xb9\xe0u/\x13.:\xd5\x1fI\x0bo V\x13\xd3\xb5\x10\x17<&.\xe2\x93~\xf5\xb4Zry\x97\x83\xd8F\xb52/J\xa4J\xc4\x08}y\xfa\xf9\xf9\x8c\xb00\x94A\x14\x9e\x9f\x0f\xc1\xc3\xd0\xa2D\xe7\xccw\x1ez+R\x94\xb9\xb2\xab\x0e\xd0\xef\xcb\xea\x91\xb9\x1dT\x9b\x9cG1}\xbd\x1e\xcb\xf8\xa0\x17\xcc\x0e\x86\x7f\x86\xec\xcf\x08\x02;'\xe8\x8aR\xa4\xf4\xfb-\xb9\xf9x\x93\xc6\x0c\x8e\xe3\xb8\xf9\x08\x04!$(\xd3.\xcc:\xfc\xc5\x98L\x99\xa7s\xce\xc1Hm\xd7\x16^\xf2\x92c\x89\x98\xcb\x98YA\xa4'\xcc\x9f\xcf\x92 J\xaa\xf4 y\x8e\xaa\xaa\xb3\xb5H\xf6R\xa9N-\xc0kU\x1f\xa8\x95s6V\xad\x92\x83EE\xfc\xa7\xf2\xfa\x8a\x92\xc3\xca\xbb\x08\xe3/\xe2w\xe5-\x9e\x13\xa9\xf2\x9e\xc8\x9a\xc4\xde\xe4\xbf\x94w\x13\xe2\xc5J\x93\x0c\xc8\xdfd?\xd4\x17\xd7\xc4\x0fHR}\x93A\xc5\xab\xec\x97\xe6\xdde\x90*o.\x834\x7fo\x19\xa4\xca[\x92\x08PyWz\xc2k\x90 \x9azrAA\xa9'\x7f\x92\xd7\x93C\x94z\xb20\xf1\xa35E\x83\xea,HOx=\x12\xa4\xe4E\x82$F\xa2J\xd5\x9d/\x119\xdaFU{.\xba'\xda\xaf\xb5 \xcb\xba_A\x95*;\xae\xd2\xb1\xc0\xdc1\xb9\xe5MZ\x15\xe4\xdb\xc6\xec\xedL\xef\xd1\xad\x90Qh\x83\xe5(\x0e\xa1\xa5\xdfx\xa4x=\xdf\xb4\xd5\xa4\x92M\x0b\xd4Q.\xcb\xa3\x0cddr\x9b\xa6U\\>\xe1\xed\xe8\xb5\xa3\\\xee\xae\xe4\x86\xc7\xe0\x189\xc6\xd9r\xa7\xf4\xbd\xca\x11\x11{\xe5[\xae\x98S\x8b\xbd\x105\xbf\x10\x94\xe2\xf0\x97\x04f}\x15\xe5\x99\xd0UQH\xe5\xf7\x89\xa5%\xe9g\x8f{[G1b!\xcfP\xdf\xa0\x93\x1cR\x8c\xea\x9f\xcb\x0d\xfac\x90\xd8\x1c\xc52\xdc}4\x9b\xf5:?\n\xb1\xab>Z4\xb9\xbd\xa5\xcf\xe54\x05\xac\xecY^\x16#\x98V\xb3\x18\x9e\xf2\x8b{\xb4\x1d~'\x8ecj\x87\x87\xfe\xb0\xa3b\xd1=\\\xf4\x80\xa2=\xf3\x93\xc5X&\xe3\x1e\xf7q\xc7\x07\xf4E\x17\xbcq\x9f\x03\xbf\xc5\xae\xe7}\xefO\xc7\x11\xe2xvr\xaf~;\xae\xa8\x8c-\xe0\x1d\xf0\x97k8\xb5\x99\x16\xd5\xa1n\x17\x1b\x83\x07\x8f\xa9\xc1\xe4\xac\x1e\x93=\xee^^\x8f\xebyn>c)\x1f\xd9\xc1\x06{\x81\x0b[\x19\xc5.\xf3f\xa0\xaf`\x1a\xc0q\xb2 =\x8d$,\xdd\x9c\x9eJ\xd2\x7f\x86\xe8\xe0\x8d#\x89\x9e\xd6\x93R\x9f!J\xc6\xe24\xb1\xbe\xf6\xa7\xe3\x00\x91.\xba\x03a}\x90\x9e\xe5\x17q\xf3\xce\xd0\xf7\x85\xdf~\xe0\"B\xd3g%\xd0 \xb4\xb0\x18\xb7\x7f?z\x04\xbe n\x0e2\\\xbf\xbb\x8e\xd6\xb6\xe3\xb2E\xe1\xbf\x9c\x0dj\xdeb\xbbH\xd7\x016\xd9'\x9b\x86_\xe1r\x8a,\x97\xa8\xd5\x7fG\xff\xeb\x1eRY\xc5\xf0\x7f\xcco'\xb2\x90\xb4]\x0ci\xc7\x83:\xdf\xe7B\xe2VB\x9c\xdc\xf66G9\xb4w\xa7\xf6W\xef\x91P\xa6\xf6+\xef\x15\xbb\x83\x98\x16I\x1e\xe0\xe1fk\x03\xa9\xbf5z\x18=XYt\xbe\xe3\xb4n)\x1bW\x89\xe4C\x88\xc5\x12\xb9 .:\xc2\x19\xbc\xe0\xca\xc2[PHi\xe18\xd8h\xd7\x95\x85\xac\xa6\xe0\xa1,_6K\xac\xe3B\xc8~\xb5\xdb\xa9\xf3\xed\xf0BIc\x85\xf9\xa3\x90\xf1\xb7p\xa0\xec\x0c_&Va\xe9\xb7\x86*<\x0c\xd1\xd1\xc8+\xdf\x02\xbdy\xc8S\xa0^\xc9\xa0G\xf5\xd0(\x8a\x9a\xe48\xcd|hJF\xf7\n\xc7\x15\xcd\xe09\x82\xb8\x10\xa1\x7f\x01ECM\xd8\xe4\x0dh\xe1F\x18\xce\x8e\xb9L\xcag\x83\xa5d\xc9G5\x00\xe1\xc7\xbb;\xe3<;C\xf9x\x86j\x16M\x136#\x9e\xcb\xf3~\xf3S\x1aC\xfel\x0b\xe4\xe7\xbdi\xd5\xf6\xa6\xe1\xc8@\xe4\xe6=U\x90\xf54\"\xb2W\x16\x91\x93\xb2\x88\x9c\xe4\"\xb2W\xfc\xd2\x88\xc8j\xcd\xc6\x9er\x89\x98\xae\xd4\x86\xd3s\x0f\x96e&\xe4p\xc7\xed\xe5\xcaD\\\xed\xeaw\xf4\xbf\x1e\x86\x07j\xef;\x85v\xff\xb8\n\x8f8\xfcH\x7f\xbfM $..\xcfT\xef\xe0$\xa6\x8bo\xe5b\xdb\x05\x0870mL\x15\xc1\x93\x184\\x\xe7J\xd3\xa5\x0bk\x17\xfd+\xe7\xdcAQ\xa5/u\x0f\xaf\xd0\xba!\xc2\xce\xa9\xcfo\xf0\xb9\x08\xc1X\xc6\xe8\xe2=\xf4\x08\xaf\x97\xe5\x84\xa4QD\x17\xd6\xe2V\x8c\x91\xa1DJ\x07\xbcVj\xd4\xd4\xebC\xad\x80\x88\xd7\x1737\xbb$\x17\x9f{.t\xfa\x945\\\xf1\xcb'\xcb<&\xc2\x9a6\xab\xda\x9c6rX\x8eli\x02\xe1\xaa\xc6o\xf9}e\xfa\xa2P\x04\xe9m\x9e\xbb\xda\xdb\xed\xda\xfb\x93\x90\xbb\xbbI\x11\n\xb4s&;\xee\x8d`\xbc\xc0\x88\x15\xa1p\xe2c\xd4=t\x98\x0d\x0e\xa7V#\xbd\x89O\xcc\x18\x12\xdd\x95KF'\xd6LZ^b\x96|\xe1\x92\xdf\xe0D#>(\x7f\x98\xe9\xa8.R\xec\x8c'4@~=c\xc17\x8a\x80\xc8\xb8\xb7X4\xd8\x88\xf1+\x1e\xcb8\xc6T\nQ\x98\x92\xeb\x14\xf30\xc5\x97\x89\x93\xfbo\xc6,yD\xc00%*P\x88\xae\x89)Et#id\x99\xbe\xf9\xdej\x8a\xc2q\xc5\xeeEr\x9fp\xe3\xa6\x08\xe9\xd0\xd3rV-\x1e\xfeCT\x0f\xa9\x19a\x84\xfc\xccD\x8a\xb4\x1b\xcc\xcc\x9a?\x1e \x13jS\xf9\xd3\x82\x9c\xdd\xd1\xdaXO\x16\xe3\xa4\x08\xda\xcb~\x04\x85MF\xe9>\xbf3\x86X\xa1\xf4\x8a\xffX\xe2\x8f\x9cq\xc5\xdb\xf5e\x81\x0eZZ\x94\xc6\x1b 6-\xc0\x88\x8e\xc3\xa9\x0es*^8\x90u\xe9\xcf\x0dD\xa1\xc4\x9esa\x85\x8b\x14Z \xa5qJ\x12{\xad\xe3\x0fj\xefs\x1a\xc2\xa8\xa2\xe8\xaf\xf9x\xa6\xbd`\x9b\xe1M\xfb\x0d6\xc5g$\x8d\x03rE\n\x8a3\x8b\x08#D\xc1j\xbd$T(\x12h(\x90\xf8\xb1\x96*\x89\x0fk\xda\x9e\xbb\xa0\x1bqe|9\xb5\xff\xafq\x9c\xe5\xcdj\x1aoM\xdf\xf8\xfb\x0f\xd6\xbd\xbc?\xdb\xf5P\xac\x08\xe6n\xe0oh\xd1\xb1\x04)\x04\xaf\xaa\x8a\x81\x85\xca3q\x1a\x93\x8a\x01\xf9`\xbb\xad\x0f\xeaW\xe3\xe7D\x19\xc0R\xfb\x12\x88\x03\xfe\xa64I\x7f\x8e\xc7\xc1\xe8\xe9\x8e\xbeM\xcf\x8e\x1c\x93\x8c\x1f\xe1\\cVF\x9ct\x84x\xb3\x03I\x1elH\xf2\x7f\xd5\xefa\xe9\"\x1asj*\xee\x84y\xccO\xb1\xd5\xe9x\xe2\xe4R:\xac\xb4z\x98\x9fP{]L\xc3\xbf.I\xfa\x19G\xd0\x1f\xd38z\xc5 <\x16LV\xb3\xfd\xef\xa7\xd4\x92\xd2\x0f\xe96X\xe8B%DsXD\xecm\xf1\x88\xbd\x04\x86\"\xa5b#s@\xaf\xb2\xee\xf3\xb33\xba\x1c\xf8\xa5K\x12\xdf[\x17\xfaT\x19\xa8N\x95`,\xcd,H\xc4dP2z\x19\xbc\xd8\xfef\xd1\xec\xdf\x84\x98\xfcl\x16\xc4$\x01\xaf\x08}g\xf4X*\xc5\xbb\x96\x82L\xf1\x10La\x9ea\x81\x12\xcfN\x9f\x1d\x83)ya\xa2t)[\xc2 \xb4\xdb\x01<\x81\xf8\xc4\xc1\x19\xe6\xf9{\xe4B\x01\xde{\x8c\xa0Mg\xff\xe9\x08\xfa(\x05S\x01d\xb7\x8ftgp\x08\"\x03!N@\xc0\n<\x1d\xc1\xdeQ^v\xff\x10\xcb\xd6=\x7f\xf4\x08\xf6\xf6i\x81\x8c\x12\xc6\xc9\x04\x83F\x15\x96\x89\xfe\x01Zr\x80\x12K\x1b\xfb\x1a\xb0*[\xfdJ\xd8\x01\x82uup\xc4\x1f\x88\x0e\x1e\x17_\xf5=D\xe8\xc1~\x0e=\xee\xe5\xd0\xe3\xc3\x1c\xda\x1f\x0c\xf02(\xce\x13\xce\x11\xa5\xe0\xac\xcbe \xce\x9b\xf5\xff\xfe\xc5\x9fY\xb5\xfbPuz\xd78Q\xc8\x18\x8b\x1a\x18\xf6\x0dO\xdan \x91Y\x8a\xcfJt\xe5r\xec\xeeX\xd6\x1b\xbew\xf2\xdb:\xa1\xdd\xef\xdf'\xb0\xa76p=\xad\xd8:?'\xc9\xa7\xd1,[\x12\xabJ\xb5y\x9a 9\x8d\x82\xc3T=\x98K\xaf\xceQ\xc5x}9I\xbd\x94|\x7f\x99]\x06a24l\xdadM|\xd33\xfa\xf1\xb0\xcdd\x08\x99Y\xc8O\xc8\x92\xf8i\x14'C0\x04c\xd2\xbf\xcbR/\x19\xbb\x068\xb6Y\xe6\x13Zs\"\xa6\xc2\xdc\x8f\xbc\xaf\xd1F}\xf5\xf4}U\xf1\xf0;\xfa_\xefU\xf9mn\x87\xf6~\xffX\x89\x90\xcd\xed\x0c:\xbb\x84o\xd3'{J\xa0e\xfeh\x7f\xaf_}\xe4\xe5\x8f\x06J\x90i\xd1\x87\xbd]\xc79\xf9N\xfeL\xe0\x0e\xf8z\xc5O\xca\x98C\x81\x9f\x05s8\xa9\xa0)\xe3\x06_U6\xa7|+G\xa3\x10\x93b\xe6\x05!=\xb65\x1c\xac\x0bC\x1d\xa7eEF$\x93\x19\xbc\xd8(i\xd9\x8fC\x9d\x84\xb9\xd1\xbdB\x99\x07\x1e\xb4X'a\xb1\x1c\x97\xd5 \x93\xdfQ\xbf\xd1q/\x95[B\x97$\xfd$\xf2\xbd\xe5s\xdc\x04\x9b\xc5\xfa\xb3{\x18\x8c\xd8\x8b\x13\xf2\xd3\xde\x8a\xbf\xea\xd8\xb1\x18\xfcv^\x0erC2]|\xdc\xe9t&a\x16/\x87`-\xd2t\x9d\x0cwv\xd6$M\xd2(&\xdd\xe4\x9dwyI\xe2n\x10\xed\\\x0dv\xc4\xaf/\x92(\xb4&\xe1,Z\x9d\x07\xb3!X\x7f\x85?\xe8d\x815 \xd11\xddK\xa3\xf8\x07\xa5:\xa3p\x19\x84\xe5\x1aEAk\x12F^\x96.\x06\x9f\x91Y\x10\x13?-\xde\x1c\xee\xec,\xe9\xbc-\xa2$\x1d\xee\x0ez\xbd\x1dV\xb2\x13\xf3\xa2\xddE\xbaZZ\x93\xf0\xb1v\xd0\x1bQp\xc9\xb5c\xd07hR\xe3\x87\xa9^\x7f\xdc\xdb\xdf\xebi\xb7od\xc4\xdcZ\xf4Q\xbcH\x85\xb5\x120\xfe\xa6\x88\x15=#\xeb\x98\xf8^Jf\xe0\x853\xc9\x91&K\xc8\xac\xdb\xe0C\x03\xf2\xfct\xa9\x98\x87#\xe9\xc9IK\xbbg\xfe\x82\xac\x98uu\xf7\xa8\xf4\xe4\xe3g/?9{\xf6\xf1\x8b\xf3\xb3\xe7\x7f\xed\xc5\xa7\xcf\xb8\xc1vP*\xf3\x93g\xaf_\xc9\xcf\x07\xbd\xdd\xd2\xf3\xe7\xaf?{Q~^~\xff\xa3\x17\x1f?\xfb\xc1'o\xce\xab\xed\xec\xefj\x8b}\xfc\x83O>\x91\x8b\x1d\x95\x8b-#o\x86\xa1\x02\xe8\x97\xea\x83g\xf4P\xc1\x9f=c\x17\xce\xc4\xe3\xc4\x9b\x93O\xc4\xbb\xe2\x87\xae\x80\xa8C\xfa-\x17\x9be\xab5\xc6\x0c\xa4_\xaa\xef\x7f$\x1e\x8a\x1fr\x81\x9f~\xf6\xe9'/\xae}\x82!\xe89\x1e\x96\x86\xf6\xe9\xcbW/?}\xf6I\xddZl8\x87\xe6\xe9K|/D\xd5\x81E\xbfY\xa5gH\xe1\xd8C\xfcZ~\xeaG+\xee{\x12\xd9\x16\xffQ.\xe1\xcdf\xcf\xa5\xf0\xe1X\xb0\x0c\xb3\xee!\xdfI\xfe}\xd5\xab\xfcA>\x9b%0\xbfD\xa5h\xa0\xb3|\xeaJ`/\x9f\xaf\x128iVH\x97_\xf0U\x85\xf2\x1cF0(\x83(\x92\xed\x96A\x14u\xf6\xca\xa0\x85Z\xd7L\xad\xebJ\xad\xeb\x86\xb9\xc2]\xf7z\x9d\xc9u\xefhr\xdd\xfb\xde\xe4\xba\xf7|r\xdd{\xd1\x99\\\xf7?\x9e\\\x1f~\xdc\x99\\\x1f\xedM\xae\x8f\x0e:\x93\xeb\xe3\x8f'\xd9\xc7\x1f\x7f\xfc\x02\xff\xffxz;\x9ed\x1f\x1d\xd1\x97\xb3\x8f\xbe\xf7\xf1\xc7S\xfb\xb4E!\xcf\x19\x84\x96pn\xed\xd3\xe1\xf8\xf3r\xb1\xdb\xcf\x9dJ\xb1\x9dr\xb7.y\xb7\x8e\xf6\xcb\x1ez\xe5R+,\xe5N\xc6\x93\xe9\xe4\xab\xc9\xfb\xea\xe3s\xfa\xf8s\xfbt\xd8\xbam\xb5n[c\xaf\xf3\xe5\xa43m\xb7\x9c\x0fv\x82r\xc9\x8b\xa2\xe4\xf8\xf3\xa2>\xc7>\x1d\xfe\xc4\xb8\xd79\xf6:\xf3\xe9W\x83\xf7\xb7\xec\xfb\x97\x93\xce_9\x99\xecLN\x87\xdf}4\x9a\xb4'\x1f\xb8\xe7\x93n\xeb\x7f\x98|\xf8xbO\x1c\xfa\xf6\xd4\xf9\xf0\x83\x9d@\xc7\"\xde\x19YD\x9f_B\xc33\xe3.\xfb.\x11q\xb5\xaakcU\xc7EM\xbb\x83\x0dj:\xdb\xa6&\xec\xdf\xb6}}alao\xaf\xa8\xea\xb8/}\xdf\x95\x9a\x18\x94~\xeco\xd0\xe03\x83yG+\x9e\xee\x1d\xa1\xb9\x02\xa5K~\xd2>\xc5 9{G0\xa4\xc7\xea'\\\xef\xb0;\x80[`\xc9\x9c\xd91\xbb7@}O\x87\x16j\xd3i\x19B\xa7_\xdb\xb1\xd7\xe6\x998\xca\x15]\xd6\xa4g\xb1\x96s\xc8\x7f\x87\x00\xb9\xc8\x05\x85\xf4\xfb\x07\x12(\xc5BU@?_.\n\n\x19H\xae\xe9\nA\xbd\x81\x04\x9a\xb3R{\x12(f\xa5\xfa\x05\xe8\xbf\xa7\x90]\xe95\xd4}\xec\x16/=\xb6\x1e\xc3\x10\xf6\xa4a\xec`\x0f\xe5\x96&\x14r(u\xe7\xff\xf9y,\xb3/A~\x13\xcb\xc8#E\xaa@\xa1G\xbd\n\xf4\x98)\xabk\x17\xe1\x8b\x9a#\xc6\x93\x11\x1c\xec\xef\xef\xee\xc3)W\\a\x96\xe9\xe7\\\xdfd\xa7\x85\x03j\xf9\x01K\xe9\xd9\xa6\xa7\xb5\x0e\xd6p\x00O\x9fB\x9fJX\xfb\x07\xbb\x83^\xf9\xd1#:\xdf\xbb\x8a\x11\x15\xe4\xd3\xd8[\x90\x13\xd3\x0e\xf6\x0f\x1c\x17^j`\x9f\xb2\x84r\x9f\xc2\x13\x18\xec\x1f\x9c\xc0\xa7\xed\xb6\x03o\xc7\x9f\xd23\xd9k\xfbS\x87\xc7\x19\xe8\xb9\xf0\xb2\x00\xea\x88\xd3\x1b\xad\x1e_hb\xc9;\x08P\x01C\xdeQI\xb7;\x0f\x96$\xf4V\x84\xb2\xf6 \\g)\xde\xdb\x8f\x92 \xc5;\x96i\x97\x9e\x1fd\x18t8\xf0,\xf5\xe2\xb2\x9b\xbc\xda\x97\xe7\xda\xbe0Q\x99\xf7\xb3\xf6\xfd\xef\xeb\xdf\xefF\xe1\x0f\xbd8\x0c\xc2Kv\x96\xcc\x7f\xf2\xeb\xea\xe8y\xca\xeb\xd7-\x0e]\x97\xcf\x94\xd3\"\x15\xd9\x86\x8d\x16\x1a\xf1\xbe1d\x0b?\xa2\x8f \xed^\x918\xa1\xc3x\xf4\x88\xcd\x845\xcb\xd6\xcb\xc0\xf7R~3\xf5'h\x93\xc0\x8eT\x98Q\xca\xe5\x91\x0fC)`\x15{\xb3\\\x12<\x9f\x8a\x96 \x90k\xcfO\xf1b*\xc9U\xba\xb4\x9a\\\xe3n\xc7\x8c+R\xa67m;\x93\xae\xf8\xf6\xc1N\x97\\\x13\xdf\x0e\xc7=\x1e\x03\x8d5\x14,\x97\x9dy\x14\xafdw\xffh\x0e\xe9\x82\x80\xda[*\x8b\xa1\xf4\xf82L\xedx\xdc\x9f\xbal\xafDe\xf8@\xc0\xa5\xb8\x8e\xac\xb5,d#\xc1lhX\xbf\x983\xde\xe6,\xf2\xf3A\x15\x13:\x82\x90E-\xef\xfa\x0b\xe2\xbf\xfd$\x08\xc9\xf7b\xe2\xbd\xa5\xe2[Dw\x90h\n\xef\xdc\x0e\x8a\xaf\xdf\xe7\xad&\xd9\x9a\x8a\xb1d\xd6\xd0hiu+*\xb67\xcf\xfe\xeav\xe8\xa2\xe2\xca\xc0\xb0\xdao\x9e\xfd\xd5\x9a\xc5N\xdfE\x85\xfe\xdf\x12\ny\x16\xd1\x0e\xbf\xd1u8\xef\xa6$I\xed\x18\x03@(K\x9bz\x97\xb0\xf0\xc2\xd9\x92\x80=\x0f\xe2$\xcd+t\xc4$\x94\xfa@[\xc9C*\xa4\xde\xe5\xa7\xde\xda\x85\xb8@\x9b\xc7\xe9\x82\xc4\x84\x1ep=X\xc7\xe4*\x88\xb2dy\x033\xe2/\xbd\x98\xcc \xc9\xe6\xf3\xe0\x1a\xa9\xa2\xf5\x18\xda\x10C\x1b\x1e[R7\x1e;.\\\xb0.\x07\xe6.\xafcB\xab\xb1\x13\xe2G\xe1l\x83>\x8b\xce2\xbf\x87r\xe0\xfc\x92\x96Q\xa5=\xaf\xc4\x92\xe2@U)\xa4\xc8\xdf\xaa\xaa\xe9\x08<\xd1\xa3\x02\xbac\xb0\xd8;\x94\xd8\xf2+\x1e\x888\xb4\x19\xa5<\x08V\x120sz$E\xf5f\xf9\x08\"\xfa\xa7=\x82\xbe\xc3e\x06t\x0e\xf0\xaa\xb6\x15&\xfb=\x19AF\xd7,C\xb9\xa7\xdf\xdf\xeb\xf7\xfb\xc5d\x93\xeb5\xbb\x83\xcf\xa2\x1c\xfc\xe4\xd9\xebW@\xab\xf1\xfc\x94(\xb90A\xdc4\xbca\xab\xe6I4\x84.E\x92\xc6\xc4[\xa1\xc3\x81\x17\x84 \x84Q\xd8Y\xc7A\xc8\xb6z^m\xa2\xab7\xed\xc6$\xc9\x96\x98/\xd53\xad\x99f\xc9>)\x96Lqo\xb9\xe2 \x04\xd0-\xac\xe2,\x833\x1cw\x83\x84\xa7\xdb\x0f%\x0c\xe4\x1a\x9a\x15\x89/ \xac\xbc\xf5:\x08/\x93\x13\xc4\xb6u\x1c]\x053\x8a\xddQ\x16\xfb\x84\xe7o\xa6\x9b@&k\x96\x93\x87\xd8\xa4\x87E[\xf2*xKn\x12;t\x9c|A=x\x02>\xfd\xc3\x164\xc3\x80\x8f\xde\xd4\x95\xe2\x9ce\xd87\x9b\xb0\x90\x94!\xfa\xdb\x04\xecG\xabW\xcfM?\x920Z\xce?\xac\x9b*\xdf\x85\xb9\x8a\xd7Aa\x08\x0cd.\xc3S\xf2\x08#\x91\x95z\x97\xc3\x1bo\xb5\xecF\xf1\xa5;\xe8\xf5\x06C\x9c?\xe6q\xabAsZ7\xbb\xeb\x18$L(2E>\xc0\xa5\xe2\xae0\xf4\xa0\x1d\xe5s\xe7\xc3\x13\x98\xd3?l\xee\x04.Dc\x1fS\x90\x1b\xb07/\xa6\x96\xc1\xe7)\xea]\xe9\x94'y\x8cb\x9e\xde\xa9X\x13\x06\xb0\x99\\\x04t\x8f\xdd\xde\xeaD\xa7\x11x\xecI!`\x95\xe5\x022\x13(\x06o\xc9\x0d&\xe0#\xe3`\xcaB$\xe5\x97~\x83\xe6D>\xea\xe2\x7f\xb9\xd1Y\x8a\x1f2p)\x05\x8d\x92(I\xd1s\x87\xdd\xe8\x12?\xdbmz\xac\xd8\xe5\xc8p\n\xb6\xfc\xc8\xcd\x8f\x9a\xb552Y\xaex\x8d\xca\xe8lz<\xc0\x89\xbd\xa0,\x9en/A\xa8\x18\x85\xc7gmt3\x92$S\x1c\x80\xa8\xacvf>6\xf1\xee\\\x86\x97s\x0e\xd5\x0e\xe1\x84;\x10\x04\xda\xb8\xac\xdc+\xeb\xda\x0e\x1c\x1e}TS[\xbb-\xd7\xa7\xdd)\xb8\xdbv\xd9\xd1\xca\xe0!7\x8bj\x0c~\x9b\xb4\xac}\xf9=\xbc[\x04Td\xe8\xf7\nA\xae\xbf[|\xe7`C\xbf[\xef\x90\x15\xe12\xaa%pv\xbeD\x07\x83\xe6\x89v!\xa6x\xc5\xd6\xfbe8\xa3R*\x9e\x9f\xf8A\x96.\x80\xfc\x90\x16\xdez\xd8\xefu\xbb\x8c\x87\xb0\x0d\x8b\xe1\xc6\x0cq\xa5\x9e\xcd\x0c\x99\x06\x8f{\xc16\x08\xe3\xbe?\xc5\x89\xfb\xd2\x85V\x1f\xbd\xe3\\\xd1\x94@\x0e\xa7\xdc\xbfM\x1aw\x0bf\x8f\xb4 g\xf7|HO\xb9\x83\x10\x9f`\x87\xf3\xb1\x0bo&\x13\x01zj\xf1 !?\x9b\x91\xd0'@\xc24\xbe1\x8a\xd9\xcc\xc7\xacDd\x88\x96\x96\n\x12\xd0\xf28\x8e\xd0\x83\x13Kd$p\x07\xc5\x89\xb4\xfb6\x08g0\x02K\xf4\xc0r\x8b\xcd\x841\xc6\x9a\x04\xca\x9f6\xd3\xa8\\\xc4D\x8c\xd6\xef\x80*\xa6\xd3!\xee\xee\x16\x11\xc2\x1b\x04\x90\xdc\x7fBW\x8f\xb4a\xe8\xf8M\x1a\x18\x8f\x1f+\x99i\x87R\xe5\x03.\x01m\xc2-0\x12m\xc41~\xb3\x17\x86\xb0\xcb\xa4\xa4@D\xb1\xc58\\t\x19Z-k\xf3Z\xd8\x1b\x16\x0b6 \x0b\x94\x91N\xf20\x8a\x03\x9b4\xa7\xbc\x98\x8b\x01\x92\x14p00\xb2~\x89r<\xc9\xb3\xf8\xd1\xd1\xc7\xba\x83pi\x97m\xd2\xbdBL\xcc\xc2\xfc\x04K\xc2\x99\xd0 \xf0\x83\xe8\xbb ]\x04!xpE\xe2\x0b/\x0dVt\xe5\xab\n\x1eS\xa8#.\xb9I\xe3m\x9d1)._M\x96D\xe0T\x9c\x80\xbdK\xa1\xf3\xe0\x07H~\x10\x06r\xed/\xbd\x15C\xc0\x95\x17\xbfM\xac<\x0eqe.X\x16\x85\n\xdd\xcd\x15;\xf2\x195\xf4*:\x9dJ\x9bI\xe6/JGn\xe6\xa5I1\xaf\x8c>\x8c\xb4o6\xef\xeaB7\xaf\xe7*WJ\x15\xba\x02\xe3L\xcd\x97\xd1;J.\xe9v\x8d\xe2R\xff\xcb\xab\xa6#\x7f\xc8\xc8Z\x17\xfa\xf60\x99u\xfd\x1c\x0d\xd1m#F]\xe6)\x08\"\x1a\xc3PU\x83\x85\x8eT\"W8\x85STs\x0d\xe9.\xe5\\\xa2(Ea\xe2\xa9\xee\xb1z~\x16\xe5\x99\xb6-\x0bs\xcd\x9a\xb4\xea\xa8Y\x0bQ\xb3\xf6\x18=\xc1k\x89\xf7\x0f\xcd\xc4[C\x96\x8f\x18Y\x0e\xefA\x96\xcd\x82\x8c\x9e4\x87\xc0K\xc8\xe4\xd9\xd0\x81\x12fV\xb1Zl\xdc\x90o\\v\xd4l\xbd\xb0C\x07\x93\xc76\xd7\xa8\xe5\xb0\xd2\xb6\xc9u \xc5~,\x0f!\x8cf\x04VYR\xe0\x9b\x97\xc2\x92xI\x8a\xaa{I\xcbVb\xd3\xf5\xbb\xa9a\x81\x7fJ\xd2\x86i\xf8\xc2U~I\xf2\xc6\x85K\x17V.\x9c\xbbp\xe1\xc2kf\x8c\xd20\xed7\x06f\xfe}\x033\x97\x16{\x19$) I~Vb\xbfl+Zc\xd4\xd9T\xe8j\xa1\x88\x1e\x9d\xcf\x82\x00pyE\xfc\xcc%\x15\x06@\xb5'\x8c\xd0\x19b]\xc8eLA\x85A\xeb\x1f=R\x04Q\xfbM.\xaf\x96\xc578e\x93\x00\xc3\xca!\x93\x9f:\xd0\\W}\xf8\x84+\xc2>E\x97x\x07\x0d\x1e\xf4\x85O\x0d\xde\x9a'L\x82\xba\xbd\xc5\xcdx\xe2\x94\xbbwZ\xf4\xee\x86\xc9c\xdfJ'a\x88\xd5\xeb\xd6\x8f\x07j\x80\x11\xbc\xa1\x9d\x8cr\x0b\xce\xa7\xf4\xc1\x9ao*z\xea\xbb\x80\x11\xf8\xc5\xa4\xcfs\x92F\xf0<\xd6\xa6\x9c\xecu\x99\xd5\x94\xec\x88\xf9L\xc1)\xbf:\x8eg\xaf\xd789\xdb\xd8X\xdcB\xc9\x9b\x98Og\xc0=w\xcc'4\xe0^;_\xd5\x8475=\xcb\x91T\xfb\xf4\xaa\xf6\xe9M\xed\xd3K\xc3\x06\x04\xeeG\xa3\x0b\"|\x87\xf3\xe3\x92\xab\xac7;?z\xc6$D\x18\x84\xa8\xa9\x1e.\xd6D\xd2\xa1-\xab\xc8\xb4\x07\xecP\x80\x07\x9a\xfd#\xfe\xfd\xf6\x96\xd2\xf2\xb8\xf9\n%\xd2\xc1\xd0\xc5[\xaf\xec\x08h\xd4A\xc9\xefI\x07<\xadL-\x7fX\xaa\xdf\xa6\x91:'pm{t\x9f\x1b\x8a6\xc8W\xf2\x87\xf6p\x9f\xf9[x\x0e\x9c\x99\x1a\xafH\xca\xb9\xc4\xe8Q\x11\xfe\xffc\xee[\xbb\xdb\xb6\x95E\xbf\xf7W\x8cx{\x1c2\x92\x15I~$Qlk\xa5i\xd2z7ur\x9a\xa4\xfbt\xcbj\x16-A6\x1b\x89T\xf9\x88\xed\xbd\xdd\xf3\xed\xfe\xb1\xfb\xcb\xee\xc2\x0c\x00\x82$@\xd2N\xd2\xd6k\xb5\xa1@\x10\xcf\xc1`\xde\x93\xb2d\xe3\xcf\xb5\xdbG\x97\xad\x82\xbf\xe4%\x9c\x82\xfe\xc0\xae\xb7\xd1w\x02\x12\xb6\xf1c\xa4\xc6\x149}\xb6\x8a\xe6\x1f\xa4\xd4\x9a__\xc8l\xb9\xa8kX\xf5\xf2\xa88Z\xc4\x9b\x8f\x02K\x8b\xa2\xb5@r\x02\xb8\x91\xf8\xe4\xff.\xd4\xf9\xc5/$\xc2\xaf_\x97\x86\x9c\xcc\xf2\x0f\x01c\xad\xb9g\xd1\xd5\x93\x14\xee\x9d9\x07\x96\xfa\xee\xf8\x9f\xd2\x13aD\xd8\x98\xf9\x0b~\xf1\x07kN\xcd\x04\xa9\x12\xe8o\xfc ~\x02>\xcc\xa3U\x14\xf2\x95^\x07IR \x9bW\xfe3\xbbKC\x1d\xb3\xa2\xff}\xaey\x9a\xe6X\xdcz\x12_\xf0 \xae\xb3U\x1a\xe0\xd9\xf9\xc0\xaea\xed_\x830q\xd6W\x05\xd5\x1b\xf6\xb9\x19\xdf\x88\x19\xef\x13\xcb\xe5\xf3\x0b\xf2\xd3\x80Mp\xed\xe42yN\xedi08\xc8Y\xcb \x9cG\xeb\x0d\xea_\xd8\x95ec\xf9l\x91\xceS{\xfb\x04\xa2\x18\x96\xd1j\x15]\xb2\x05\x9c]\x83\x8fj\xd0\xd4?\xcbV\xa8\xeca\xebMz\x8d\xca\x0d\"\xfcr\x9c\xa8\xbc\xa6c\xf3\xc6P(\x11\x0dEYeP\xae\xa4\x037DZ\x04T\xca\xa7\xab\x1f+A\x06hB\xb1s\xbc\xd9+k{-b\xd9\x1b\x97\xb7(Hk\xc6\x88\x9e\x81\xa8Qr3\xbfVnV\x80;\x9b\x17c\x93\xe8\xac\xf2Q\x15\xf2\xc4\xd1AH\xb3\x01\xda\xba j\xab\x9c\xae\\\xd4&\xf1d\x81~\xc5\x16\n\xfd\xfe\x81\xc4O\x0f\xce\xbc*\x01d\xa3~\xcaZ]\xccY\xb3\xd4\x93\x88u,\xf9\xc6\x17\xf5\x84\xd2\xc7FB\xe9\xda\xe0\xad\x04\x02H\x859\xa8\xbbi\x86\x05\xd2\x89=\xde\xe9 98IbM\xe9\xc9k0\x1f\xefs8\"\x82ac\xe5EUmN>\x8f\xf6D\x8f\x03\xea\xf1?M\xfeip7\xb2*\xf6(\xc3T\xd3=- \xabM-a\xa5\x8e\x1a\xf3z\xad\x96W\xe8\x0b\xab\xec+i\xd2\x08v\x17\x05\xd8\xfd\xa8\xc1.\xc7\xb7\n~al\x13\x1b\xc7\xf6\xcb\xe4\"\xa7?\x08?\xc2>9\xc5\x9f\x04\xe1\xf9\x8a\xc1\xefY\xc4\xab\x8a\xbdGZ\xa2n\x96\x86\x83t\x1b6\xc3\xdc\xe9\xe78):\x83a95\xbb\x04\x1e-\xc4t\x9f\xff\xd4`\xe2m\xf3\xa9i1\x9eZ\xc9\x88\xf0]\xf5\xd5\xa0\x8d\x18m\xe0\x95\x87d\x03|\x14c\x8dd\x9b-\xce\xa2\xa9\xab\xcbv*\x1aO\x87~\xfb9TrM\x9f\xfcE9\xd0\x7f\x98\xfa3\xafp\xc1\x1c\xa3\xef\x88>\xc9\x16-Rp\xd1\x910\x83\xe3\x1c\x8b\xcf\xcf\xd2\x08]\x89\x1f*Vf\x17\xc6\xf0hO\xfd\xe4l\xc3\xc0\x83#\xfe\xbf\x16\xba\xb2\x80\x14\xda\x11\x19m\x07\xfc\xbb'\x10lo{\xd8\xfb\xd3\xb6k\xc5\x99\x14\x0c\x1b\x87~5\x07\x07\xb0\xebA\x172\xc5R\xa9\x13x\xc1\xae\xfc\x05\x9b\x07k\x7fU\xef\xd2\xa4\xff\xe9K\xf9\x9b\x1b\x95\xe0\xc5N\xb7\xd0ZJ,\xf0!\x8c.C\x10\x11\xd3\x94\xcc\xac\xa6\xeb\xea\xc9\xa8\xc7\xa4~\x8eI\xe9\xe8\xdb0i\xb5\xe1/\x84I\x17Qv\xd6\x06\x93\x96\x06\xd3\x82\x96\xb8\x0dj5\x8f\xc2\x88Z51NGC\xb26\x0c+\x0c\\\xcdXu\x97d\x18\xcd\x8a\xef6X\xd5\xd2H+s'2\x81{#\xac\xdf:\xcf\xdd\x98\xa3\xcd6-V\x07s+\x93\xa7U\xe0'\xb7\xb2x2\x18?\xf6\x8a\xa6N\x9aH\xbd\x14\x8eE7\x84\xbc\x97\x85J\x0c\xb0\x10\xe3(\x19\xc5iw\x92.\xa6\x0fge\xddU\x95\\\xe5`rWS\x14\x94\xba.\xa5\xbc\x95\xdf\x94v\xe1\x9c]\xd1\xcd\xc1\xeb\x8d\xbbl\x06,\xbe\"\xcf\xdd%\xb9}\x12\x92F\xa6w\xe7Q\xfe\xbc;\xd2\xcaw\xf2g)\xe8\xc3\x1f\xfbz\xa5\xc7\xda\xb3Vg\xe7\xa1V_+\x7fL\xa1\x1e\x96\xb5P\x8e7\xce\xbe\xd6\xbd\x10\x9b-IF\xff\xa6\xf9\x18 \xee\xec\xe6\x86\xec\xfb8\x98\xb78X\xcd\xe4J\x80\xbe\xe4ErWX\xad\x8b\x03\xb6\xac\xa5B\x84u\xc6\xb2\x89b\xb8\xe3\x14k\x98g-\x8f\xef\xce^\xdbA\xd4\x0f\x00}eZ\xf4\xd9$\x95h\xbcj\xf29.\x9b\xa5\x8f\xbc\xcdK\xac\xd8l\x05\xe1+1\x8bT\xd3h\xc6gsU@\"\x13\xed\xe6DdP\x14\xdc\x1c\xda\xb3t\xe9\x7f\x99\xc6\xbf\xdfYZ%\xfej\xe3\xb6\xcb?\xbb\xc0\x04\x8af\xf8\xc2\xff\x83\x8c\x078~\xd2wB\xe8\xaf\x0b27Kr\x01\xf9w\x179\x8e\xb9\x14\x15`D\xcb\x10\xfe\xec\x0c%-#\xc6\xbb\x0d\xbeWw8\xbd\x1e\\ \xcc\xe7\x16k\x08C3\xcbv4\xb8<\xd8n\xc4\xf2P;\x1d\x85F\xc8%X\xa0\x99\xa2\xc5\xea\xa6*Q!R\xa4'\xad( \xfd\xbd\x16 \x94\x07\xd0\x96\xde,\xca\xd8\xc0\x998(\x9b\xaa\xa9\xab\x95\x08\xcdnn\x07\x96\xdf\xd5\xc9E\x94\xad\x16h\xabs\xe1\x7fd\xe0\x87\xd7\xd2\xf2\x1a\x95\xb0\xd2\xdf\xbb\xb5\xba[\xe9\x15s\xd1\xd9\x8fjVh\xe4)l\xe1h\xf5\x91\xb9\xda\xd4\xeb\xf1\x84\x06\x13\xef\xfbs\x19;OwM\x93\xfb\xfc\x9e4\xccw\xdc\x82\xcf{~\x05\xb2\xcf=!\xae7\x8c\xbaFh\xbf\xb9\x01g\xe9\xafVg\xfe\xfc\x833\xeb\xc9\xed\x99\x80X\xb7\xda\xeaS\xac=+\xccT\xac\xd1\xd6\x16\xbc\xa7O\xa8\x18\x1f\xcd\xa1d\x10\xa2\xf1=\xdf\xfe\xce\x01\xc6\xe0\xc4\x95\xec\xc2\xbd#H\xfds\xd4< \x98?\x13\xbe\x13\xa2uN+\xf6\xf0 `i\x9a\x97\xdeC\xff\x9b\xca.\x93\xc3{\xd3N\xdeq\xebr#4\xa1'\x13\xdd\xa31\xd9\x82!\xbfS\x9a\xa1s\x94+\xe1\xd0\xcbI\xf7\x91\"~\x94W,\x7fdI(\xd5\xc2\x8a\x7f\xbe\x8a\x12&\xcc\xf8K'\x99_\xe8\x95\x89\xdf\xdc\xc0\xeb\xafr\xf8R\x8f\xcaw\xe1\x87v\x9e\x85\x1a\xfa\xaf\x00\xa9\xc9\xc3P\x90~Z\x18!\xe1KP\x0d#\x94\xf6W\xec\xdc\x9f_\xf7\x94K\x8f\xc8l\xa6m\x18\x99=I\xb1U\x0b\x97E\xdc\xf1\"\x9f\xd1\xfcU\x0f:nIs4\x10tw\x07-z\xcc\xd20\x9ck\x06\xed\x9d\x13m|d\xc1\xdf\xadMC5\xbc\xect\xd63\xfa\xba\x15\xd8=\x19\x0f\x05\x0e\xc8\x8d[\xb8\x07\xa9xH\xc8k\"kiR\x1b\xeb\xe6\xcc!PKNCd\x06\xf8L\xd1\x19\xa0\xa8\xa1\xad\xcd\xb1\xd4\xa8\xa3m3\x04;\xd26\xf8hR\xfc\x05\xfbUPC\xdd[gZ\x1b\xd2\x01\xe4\xb2~1\xc0\xe2\x7f\xb1t\xe7\xae\x81\xa8\x16\x04\x9d6&\xd2;\x8b\xeb\xed'\xe1\xe1\xf7\xd34\x9cI\x19\x1b\xc7\xa7\xaf\x85\xc4\x81\xf0\xa9\x12\x82\xe5`Z\x90<|e\xef\xbc\x88\x0f\x06\x1ak$\xce{\xee\x9e_\x8f(\xdaV\xa4x\x0e\xed+\x8f\xbcbD\x17\x11\xe1A\x1f7_\x90\xccpV\x13\x14\xd0\xad\xfd\xb8\x12\xb7\xe5\xe7\x9c\xa6\x17\xd3D;\x8d\x8df\x9cV\\\x98*\x92\xde\xda\x82sr\xf0,\xee}T\xdc{P\xa18\xc2(\xdc~\xfa\xe6\xd9\xf1\xb1\x16O&\x01?f\x10\x84)\x8b71C\xc7\x87\x04\xd9-\x15tNnmR \x1b\xd0\x82\x9f\x9d\xc0\xee~\xf3\"{\x82\x14hXa\xad\x82\xe6I\xbd\xadc\xc9\xaa<4\x8aQ\x16*\xc03\xf7\xe0(\xecG\xede\xfc\x9dk\x8c\xc2XL\n\xc3d\x86(~G\x0e$\xbd\xa0\xe2\xda\xc9\x901\xa5\x05\xc8\xa7\x80K b\xc9\xd4Wrs\xf3\x82\x1e\xec\xef\x8d\x1e\x8aX\xa9\xfaG\x03Y\x93\x97\x8b<\xfa^\x19\xf7Q\xb2\x04\n\xc5\xd9\xa8YK/\x82\x84\xb6\x100\xfd\x01\xfe\x96\xd131!\x92\xfa!H\x1eQ'\x91\xf1\xd8\x99|\xbc\xb9A\x9e\x9b\xbf\xcc\x03Y\x1eb\xda*\xf9\xab\xd8\x04Q\"XE<\xde\xdc\x90\xd5\x02\x7f\x8b\x01\xaa\xf8;\x19\xa9J\xbdQ\xe4\x1a~)\x7f\x14\xdb.01|j\xf9\x981\nx\xb0b\x8bcQG|\"\xe8wK\xe5\xb7\xf4V\x0d\x1d\xf7.\x07\x06Q\xae\xc9\"\x06j\xb4(\x8e\xd0\x7fJ\x89\x84^\xa6\x1b\x02a\xa1:\x9fH_\x14\x11-m\xa7\x81\x08\x0c\xc5^\"$\x0d\x1c\x158(\xac\x1e\xd3P\xbb\x80<\x08\xf5A\x90\x9bFX8\xb7&\x92\xf3\x89^\xe7 \x0f\xf8\xb8\x0d\xc3'\x1e\xfc\xe0Z<\x8c\xc3|n\xb5\x07\xf4k\x9b8Z\x13E\xc3!\x9d\xe3rW\xc8G\xcb\x96\x1c\xcc-B\xf9\x88\xf3\xfc$\x91aFZH\xac<\x04[\x0c\x07\x10\xf0\x7f(\x04\x1bs\xa3i<\xab\xc7-\xdf\x1b\x0f\x9c<\x99\xdf\x99\xf6/XJ\xaa&T\xc9\xaf\xaa\xe7\x95\xd7\x1a\x8a-\x95\xb5\xe4\xb2N\x07\x06\x9f\x82<\x81C\xe0\xe6\x8aC\xa5\xa1W\x184\x085\xec\xda\x83\xb3,\x85e\x94\xf1[.\x8a\xd9\xad\x128\xe4I\x0c\xbe\xeeU\x93\x1e|\xdf\xb3\xe6+h\xd2B\xb4\xd8S\x04\x99\xb8\xcf\xaeR\x16.\xdc\xea\xf2\xd1\xa1\x1eCV\x9c\x0f\xef\xac\xb4\x1d\x12\xf8\xee\xd8\xd8W\xdaOc\x02\x87Z\xcc,f\xf3\xfd]gS\x8d\x0f\xfc\xe9\xe9\nL\xc1D\x03\xb7\x10z\xb1r\x97r<&.\x12\x89e\xcf\xb2\xe5\x92Pw\x15e\x86E\x94\x19\x8b\x9f\xf3h\x95\xad\xc3B\xa0\xd3\x1c\xee\x02-\xa3\xc19K\xdf\x84\xc1f\xc3\xd2\xa6\x05\xae\x98\xabW\xcfbG\x1b\xae\xa7\x0b\x0dL\xbc7\x88\x00\xf0\xbb\x1a\xc5\xf0pOD\xc0\x91\xf1o\xf4\xd9\n\xeb\x00~\x9do\xd3yvN\x07\xa7\xf1i\xf8\xff\xfe\xaf\x9eU\xc0\xe9\x07\xe1\x82]\xbdZ\xba\xdah\x10\x8b?M\xdd\x80\xf4\x17\x96\x90U\x01lS\xf0\xc0\xc2\"oc\xbf\x0c\x1e\xc0\x88(\x0f3\xb3\x86\xe3\x86~\xbf\x0f8\xf8\xee!\xec\x99\xb9\x946\xeef\xb8Dz\x1e\xbd\xd2Jd\x9c\xec\xd3\xa6\x97\x93Ww^\x9a\xcc\xba,n&\xd0\xf8vieZ\xacJ\xa4\xafJ\xc6\xd7\xf7\x13VE@\x94/\xd7CL\x80\xa8\xba\x80\\\x11sSJ@1\x94\xe0\xbc|4\x00\xefR\xc0\xfcn\xb9\x16t\x0d{\xde\xd5\xee\x8b.8\xbf::\x82\xd2\xcf\x90L\x19\xd86\x1b\xb5\xe3\x18\xef\xf8\xfc\xe8s\x82\x15)\x88{A($\x8f\xea\x1dFK\xbe\x87\xaarN\xb1\xf8)q0\x0e\xc6\xa3W\x98\x00\xf9\xba.\x9f\x9b\xc0\x04\xf9{Q@*\x10\xd2M0\xb9\xa096p\x85\x88\x8az\x19\xd3\xaa1\xde\xad\x11M+L\xf3\x89Hs\xa0])z\xe3\xfc2\x8e]C4\x9c$\x8d+\xd9\xfd>\x04\xe1b\x9c\xabs\x0b\xef\x94\xf7\xd7lu\xdb\xc6\xcd#\xaf\xdb\x17\x91\xe7\xf1Mz\xbdbcp\xd4z9\x7f\xf5q?\x8b\xa2?\xf5\xb8\x1bL\xa7Z\x1f\xf7\xc2\xb1N\xe3\x8c\xe9\xc7\xf8m\xf9\xf7O\xef\x9e\xcbc\xcd\x0b\xf6\xf4\x8f\x97\xfe*)\xd4~Q)x\xfa\xf2\xcd\xf3\xbb\xa2\x85\xbas|\x9b\x81\x7fN\xfc\xe1LE&\x81o\xa2h\xc5\xfcpF}T\xf2\xd2I\nT\xa8\xe1k\xe7^\x8bmL8\xc1\x9a\x82\\\xd2\xad0\x91\x0b4\x06\xb1KmN\xb1 E\xb4\xea\x8b\x16{,\xf7\xbbM_&\x8c\xd1\xae/9\xaf\x17\x96y\xfd\x1d\x10\x88%3\xe2m\xb3\x9aV\xf2\xa6\xed\xe5\xe344\x94\xb5o\xe8\xa1\xd6\x90|*c\xba\xc0\x84\xe9\x820\xfd; :\x12\xd7\xe8\xb2k#\xe0\x04v\x87zS\xc3\xca\"\x17\xee\xe4FU\xe8\x1a_\xe7\xbfD3\xeed\\\xbc\xc7\xf3\x1e\xa8\xf2\xe9i\xdf\x9d\x8c\x83pys\xcc\xff;y\xe1\xddPQ\xe8\x877'\xfe\xc9\xcd\xc9\xd3\x13\xcf\xfbZ7\xb9\xc7\x80\xfc\x98\xadW\xeb\x9c=\xb0K \x8d\xbc\xf3r\x15\xf9_\x84{\xd6\x85\xdb\xa4\x15\xe1\x88\xd6\xedD\x82\x80\xf1t\xda'\x9d\xeaf{\xb3\xcfN\xd2\x18#\xc1\xc8\x11\xc2!H2BX\x1eW\xa8\x91~\x1a\xbd\x8c.\xe5\x89\xe6\xa4\x04L\xf8=>\x06\x11\xfcw:\xeb\x81\xd3\xdd\xceu\xe7\x0c\xe9\x95#q\xc1\xb8d\xf2\xa7h\x91\x1e\xf0\x9a\xcb\x9c\xf4\x10\xa6G0\x11wY\xff\xf5\xab7\xc7o\x8f\x7f~\xfe\xfe\xf8\xe4\xc5\xf1\xc9\xf1\xdb_`,_\x9d<\xff\xeei\xf9\x95\xd3\x0f\xfd0o\xee\xc4?\x811\xb0\"\x85!0\x9b\xcb\xeeFf\x04E2\xe3\x05\x07\x9cZBCX\xe7\xc5Dh\x04\xb7\xe8\x8aIB#\xe6\x9f\xdb \x8d\x10\xees\xb2y\x8c\x0f\xda\xa8\xd8\xdf\x89\xd4p\x89\xd6\xe8\x1c\x92\x1b\x86\x81\xd4hKk\x14\xf0\xa4\x0d\xe2C\xb3l(HN\xfc\x13\xde\x17$\x97A:\xbf\x00\xd7*;\x98\xfb \xd3\xe5\x90cc-\xd0\x16\x07\x81\xcf\xcc\x1dQcJ\x8a\xdb\xa6\xb1\x93\xa7'\xb5\x8d)1m\xab\xc6\xfc\x13\x83<6\xf7x\xb6\x1e7!\xf4\xfb\x12\xab\xc5O\xfeg[\xad\xe3\x93\x17\x9fo\xb5\x8e\xc3e\x9b\xd5\xaab\xa0/\xb7Z\xdb\x9fu\xb9\xb6?\xebzm7.\x98\xe9\xb4\xe7\x9f\x0f\xfa\x03\xc3X\xb4{\xa9H\xf6\xf6 S\xc9\xbc&\x10\xaak\xcaa\x0e\xbfP(\x02fX\x87L\xfe,]C\x99\xfc\n*\xe4\x97\xa2\x8e\xb4\xffy\xdb\xae\xed\xc7\xd7N#A\xd7\xd8\xe2\xa4\xf4\x8b\x93no\xd3\xd9\xcd\x14NO\xd3Y\xd7+\xbc\x1c\xeb\xbd\x17~\x10}H%\xf7=\"\x10\xb1\x85\xfb\xee\xbfn\\N\x8by\xe5n\n\xdf{\x13\xcf\x9b\x14(\xb9V\xea\xdc4X\xb3$\xf5\xd7V+\x96\xcfN\xac\xe5\xe1\xca\x83>\xbbbsA\xb3\xa9\xd2H\x96~\x01r\xcd\x10\x07\xc5\xa23\xd9\x08\xb7L\xf3\xb5\xa7\xf47H\x81\xa9yx\x8a(\xcb'\xa1\xe7'\xf74\xf3\xee\xe7q\x1c\xc5\xae\xf3\xad\x9f2\xe5K\xcbx\x99)(S \xf2\x89v\xd9t8#\xda\xa7\xcb\xa6\xa3\x19y+e\xf4sg\xd6\x83\x0e\x9b\xee\xcer\xf3Wv \xbc\x03\x97\xff\xaf\xff\xee\xed3W,\x83\xc9\xff.\x10\xe1)\xba\xbc \x8aN\xd1e\xd3\xbd\x19\xc5\xa5\xe8\xb2\xe9\xfe\xac\x07l\xfapfC\xc2(p\xc5\x80\xb7\xd3\x873A\x94\x0ez\xb0\xe3=\x81U\xeeK\xb9\xf3\xc4\x83\x15\x1a\xf6\x99\x90\x14\x88\xa8\xd1\xddU\x15\xfd\xd9\xc0\x8bM\x1f\xcfp\xe1\xf9\x9e\xed\xb3]\xb8\x0f\xee\xfe\x00\xee\xe3j\x0df\xd0\x85\xae\xcb\xa6\xc3\xe1\x8c\x83\xd9@\x8a\x00qC\xf4/\xb77\x9e\x88\xcb`]6\x0dzV\x1eFS\xdf\xda\x82e?a\xe9\xdb`\xcd\xdce\xff\\\x93?\n\x0d\xda\xa5\x0b\xce\xd3o\x9e}\xfb\xfc\xc5w\xdf\x1f\xff\xe3\x87\x97?\x9e\xbcz\xfd\xdf?\xbdy\xfb\xee\xe7\x7f\xfe\xcf/\xff\xf2\xcf\xe6\x0b\xb6<\xbf\x08~\xfb\xb0Z\x87\xd1\xe6\xf78I\xb3\x8f\x97W\xd7\xff\x1e\x0cG;\xbb{\xfb\x0f\x1f=\xee>8<\x0dOc\xe7\x96\xec; x\xbe\xc4\x86\xddY\xfbm\xc1\xd3A\xa3b\x9cc\xc7\xc8\xa2\x1e\n)\xf2_H\x1eCa\x9d\x8e\xa8\xe3\"b\xcfr3vi\xbcN1\x00a\x7f\xb7Qk\xc4\xe0\x00\x06\xad4?(\x13\xdf7\xbe\xb6\xe2\xc1\x18\xfe\x0b\x1e\xa1\xf0\xb9\x08\xf6\x9f|q\x06E\xe9\xc5\xf44>\x0d\x0fgB\x86a_\xf4\xa0v[|\x8c\xffc|\x95\xd8\xb7{n\xd1\x07)\xff\xee\xc1\x13\xe0\xab\x9c=\x01\xd6\xedz\xc0\xe0\xbf\xd0\n\x8c\xe4%\xa4\xce\x99\x8b\xfc\x10pt\x04\xc3}\xd8\x82\xd1\xde\x9e\xd7\x03\xbd\xf8Q\xb9t\xb4\xb7\x07[\x90p\xa4\x9f`\x12\x90\x83\x03\xd8\x87\x1b\xf0\x158\x04\x12\x1c\x98\xe9r\x15[4\x00\x19\x087\xc3\x81\xdd\x87}T\xd1|\xd2\x90`\x0c\xc3GJ\xd0Slk`lk$J\xf1S\xe1q\xc8\x97F\xaf\xb3\xab\xbe\x8c1\xe9\xc62\x8e\xd6\xea\xc1\x9d#O\x80\xe8\x1e\x1f\xe7u w[\xa9\x08\x06\xf6\xe0,\x0e!\xd0\xf6Z\x93\xb6\x00\x1d\x93s\x8b\x15\xa1X\x80/k\xc45~\x0d\xae\xb1@\xe7N :\xf1\xe4\xfb\xd3\x00\xb7\x8fo\xfa\xfe\x0eR|Z\xe9\xc8T\xba_*\xdc\xdf\x81-@s\x1c>#7\xe0\x10\xfb\xc8\x83.\xa4SfW\xa8\x16\x01t\x87\xf4\x87\x9fyD0\x86Q\x0e\xae\x85v\x06\xa6vv+\x85\x07\x07P\xeeq\x7f\x17\x1b\x1e\xe6\xc0\\h\xb9:\xc0\x83\x83J\xc3\xfb\xbb\xc5\xf6z\x10\x17\x01O\xfd\xfad\x02\xc2\xca\xceVd\x7f\xc58\x93U\x02\xc1*,\xbc%\x89\x16\xd5x2X\x9c9>\xf1\xca\xb7\x19\xf2\x97\x985\x12\x83[o\x03C\x80\xca\xfc\xb8\x91>z\xae\\\x83\xf9\xe1\x0b\x9f\x90 \xd8\xea6\x16\x88|\xa1\xf3)\x9b\xe5I\xc0\x94\xa8\x96\x16|\xe6\x08f\x15E\xb2q\xb3=\x87\x08\x84\x13\x84\x10\xd7\x1b\xf0\x04\xa2Id\xd3j\x08\nY\xdfo\xecZ\xfe\xdd\xc9P\x07i\x9f\xe6>x5a\x81\x90\xa8;1k^\x16\x11\xce\xa2U\xd2\x0e\x058\xc5SyG\xfa\xa6*\x9c\xf8\x93<\x8cZ\x1c\xfa;\x9e\xe1\x8d\x1f\xc4\xc9\xdf\xeb\x10\x0b\x7f\xdd\x9a\x83\x9a\x89\x19=\x8dc\xff\xda\xf5\xa5\xdb\xa3R\xf4\xf0\x13\xec\xdf\xed\x04\xfbx\x82\xcd'7h}r\x03\xf4\xe1G\x93!\x0d\xe1~`\xd7 \xff\xba\xec\xd6ok%\x9b\xb2\x19Ge\xd1t\xc0o\x19\xfcw6\xfb\xd3\xa1\xde\xb2\x8f&\x9a\xfac9\xd4\x99\xf0\x06\xb6\xeccT\xd8\xc7\xcc\xb8\x8f\x99m\x1f\xf9ne\xb8[Ae\x89{\x10\x89\xb5\x0b\xc4\xda\x05\xb8vV\"&\xfa\xeb\x0fp\xf1\xd6\xbe\xe51N\x98Uun\xf6)\xfcrg\xb8\xf6\x82\x0dB\xb0\xc4\xfe\xd2\xee\xb1\xb0'L\x10\x15\xa2\x0d\xa7lV{\\>/\xc4\xdb\xf0\xfc\xdf\xcd\x8f\xf2\xb7\xe4A\x16.\xd82\x08\xd9\xe2\x13%/5\xcbp\xfbE\xf5*\x19\xe6o\xcb\xcf}\x8c\x82\x85\x8c(V\xd7\xbb\x89\x93\xab\x13\xfa\xfd\xcd\xbc\xa1\x7fK\x1e\xc4\xec\x9c]}\x11U\xca-\xe4f\x01F\xa6\xc1zm.'\xe5Mg\xa6\xb19\nxp\xfa\xc0\x9d\x9e\x07\xeb\xd9}\xef\xeb\x07R\xb3a\xae\x1e\x1bb\x0c\x80\x18\x94\xf3@\x8a\xdd\x07V%\x02i:\xa4\x05o8\x1d\"\x1b&\xd5\x07G\x9c%mq]\xf3\x9e\xd0\x9aw\xcar\x03\xa0\xb8`\x0b\x947Si\xe5K\xdf\xc1\x7f\xce\x8a\xcbS\xa2-:\xa9\xdf\xca\xab[0\"\xea\x81e\xc5P\x93\x95kFY\xaf\xcc\xc7|\"\x92PT\x1au\xd0\xd6\x14\xe6\xb6\xf8\xa4vC\xf8Zu!\xed'Q\x16\xcf\x19ty\x81ua\xd3\xfe\xf9*:\xf3WB\xe7\xd7=\x04\xe7\x9cB\xf5\xe5\xa9\xe7\xf3Wkz\x15\x9c\x87Q\xcc\x9e\xf9\x89\xfe.\xe0\xef\xd8\x97BfO\xb4J\xea~\xd1\xa21]\x06\xe1\"\xbaT@A?\xfb,\xd9\xc4\xc1\xda/\x19\x06\x06\x8d\x98\xd1\xa8N\xf8-y \x07\xff\x17\xe3\xc6\xaa\xbaF\xfe)\x18p\x11\x06\xf8\xe6{\x16\x11!\xc8\xf48}4\x0e\xe3g\xa1\x9eM\x8f\xfd\xf0\x9c\x8dkyo[TQq8^\xc7\xd1y\xec\xaf\xe9P\x84\x18\xfb\x8e\xef\x98\x0c-v\x16-\xae\xb58<\xce\xf3+\x0e\xf9I\x10\x85oR?ek\x16\xa6\x8eVu:\x98\xa9&\\\xe7i\x1cG\x97/\xc4\n\xe7_\x96?`\xea\x0d}\x8bN\xcf\xb7\xfd\xca\xc0\xe6\xebZ\xb1\xba5hD\xd4\x9f\x84\x8eEt\x9c\xe6\xcd\x0f\xb4\x8d\x0f\xeb6\xbe~\xd3\xff\xb0`s\x9b\xc3\x0b\xdej\n\n\x88\x81\x95\xdb0\x14\xbfu(\xe0\xbbc\x84\x82\xbc\xaa\x82\x02^\xd7\n\x04\xc5\xfae \xe0\xc0v\xeb\xaf\x0cf\x10/\xfc`\xc5\x16\x90F\xca\x16B!\x0c\xbb6\xc5\xd8\xc1\xc6\x8f\xfdur\x0b\xab\xd0H\x06T\x0d\xfd\xb5 >\xc5\x0di\xec\x0cW\x1c7\xba\x07\xce7\xabh\xfe\xa1t\xde\xec_\xe1\xf2Mp\x0d\xe4\x02\xbaQ\x0fB\x199x\x8a\x96\x0b\xfc>\x9e\x0egt\x01\x0b\x95\x8b^\xdd\x91\x08\x02#F\xe5\x9f\xd2g\xf5&4w\xbe\xa1\xe5\x00\xfe\xd4;Z\xdd\xba\xcat\xed\xcb\xda8X<\x00\xf6F&\x8b1\xf7\xd1N\xa98\xa3\xda\xe5b\xbfN\xdaW\xac\x9a4\xcb\x15J\x08\x0f\x0e\xe1q\xb1h \x870,i\xb3Vp\x08;\xa3\x12(\xf0\xb2\x9db\xd9\x05/\xdb-\x96-x\xd9^\xb1\xec#/{X,\xbb\xe6e\x8f\x8ae\xe7\xbc\xac4\xbe5\x1c\xc2ni,\xefyY\xa9\xdf3^V\xea\xf7\x12\x0ea\xaf\xd4\xc7\x15\x1c\xc2~\xa9\xbd7\xbc\xac4\xb7\xe7\xbc\xac\xd4\xc7S\xbe|%7\xc4W\xbc\xac\xf4\xedo\xbcl\xbfX\xf6\x01\x93\x15\x96*\x1eca\xa9\x97\x1f\xb1\xb04\x95\xb7ph\x80\xf8\xc1\x18\x9c\xd3\xd3\x81\xe1\x1ez\x88o|\xc3\x9bG\xf8\xe6\xcc\xf0\xe61\xbeI\x0do\x86\xd4Qhz5\xc4W\x1fM\xafF\xf8jiz\xb5\x83\xaf\xca\xd4\x1c\xff\x1b\xd1\xd0\xcbBh\xfe\xb7\xb3;\x86{\xa7\xa7\xce=\xc3\xd8\xa9\xaf\xd3Scg\xd4\xdb\x89\xe9\xdd>M\xed\xbdi\xa5F;\xd4\xeaK\xf3Kj\xf5uI\xc6P\xac\xfa\x8c_\xd6\xce\xb5\xd3\x03\xe7\x17\xfe\xbfk\x96\xe0\xb3\xf8\xe7\xf9\x1b\xfe\x0f\xd2\xbc\xce+\xfa\xff \xff?>\xd2S\x84\x8f\xf4\xffWX{\xb9\xc4\x8a\xe2\x9f\x17/\x9c\x99)\x90\xc6\xeb*\x92\xcc\xc5\xb5%\x0d4Y\x9e\x1c\xd6z\x93\xf5(X\xc6ho\xcf#B\xe8\xca\xa1h\xbd\xa3b[\xca\x02\x19\xab\xef\xef\xed\xed\xc8\x0f2\xf1\xc1\xae\xe1\x033\xc9\xde\xa1FvG\x8fw\x1f\xef?\x1c=\xde\xf3\xbcb\xf8\xdby\xb4`\xb0\x89\x82Bz\\\x8av\xb8\xf6\xafe\xda\x85\xf3\x98\xf9)\x8b)\xf3\xc2\xe0\xea\x85\xf83\xd1\x0d8\xd0wb\xa0\x8f\x8a;[\xf8%o\xbc\xd3SG\xc4p\xcc\x836\x0e\xf0\xfbm\xc5'{\xd0\xd5\x987S\xb0\x92\x9f\xaa\x9b\xa5\x85\xac\xc6\x9d\xc9crG2\"\xb6\x0c0\xfd\xa3\x9f^\xf4\xd7\xfe\x95\x8b\xf9\xc1E\xf1\xcd\x0d\x8c<\x19\xda\xfbC\xb09\x0e?\xfa\xab`Ami\xbf\xf58\xdc\xcbUt\xf9\x92}d+\xa4`\x83\xe4$\xe2kz\xee\xa6\xf9\x1bO\xfa\x1fie\xb2\x97\xf4z%\xe2m\x17\xaeU\x1bE]\xcd\xffkH\xdfU\xe0\xdcrw\xfe\xff\xfca\x919\x87\"\xfb \x19iP\xc6\xd5\xb8\xa40`J'C\xce\xff\xd1\x13\x8a\x88:\xa4\x8c\xe4\xf14\x10Z]q\x16\xd84C\x0f\xeeN\x87\xc8\x99,7]\x1d\x91A/\xff\xcc\xc0\xd5r\xd0\xc8\x94\xff\xb6\xd7\x03\x97\x12\xb8\x95B\x90\xf7eV!\xde\x0foOdt\x98\xf7u7\xcb\x1e\xf8\xd4\x99\x8f\nk\xfd\xd5\xd4\xe7\xe3\x0b\xa7\xd9\x0c\x0e\xcb\x91oA\x13p\x17\xe1\xd9\xd5@\x8c\x03\x0e\xb6\x98H\xf3H\x05;Q\x9c\xfe\xc0\xae)\xd5\x8c\xfaQ\x8c\xde\x1e\xb2\x7f\x06\x0b\x19=]\xfd\xba\xb9\x81G2\xf6y\x18\xfd\xc4\x96\xd4\x86x\xd4[\x08\xa3g\xd1z\xe3\xa7?\xf2\xe3Lu\xb4\x02\xbd\xe6<\xe2\xd0\x8d\xeeV\x97b)\xb5\x02\xbd\xe6\x1d\xe2\xc5\xcb\\Du\x9f<\xbf*\x86\x98\xc7\x9cWa\x1e\xa6\xbe\x98I\x9a\x97,2\xfe\x85\x9f2a\xa7@\xa5Y\xc2\x16\xdf\xeao\n\xc1\xfdL8\xe2\xc4x\x98\x10\xe8\xc5i\n\xe0\xb0\x14:\x96y\"w1)\xe6\xb6\x87\x04\xd7|l\x89f\xaa\xf4\x04\"8\x80\xe4\x89\x879\x1a\xd0j]\xa6\xe6\x17n|\x98\xf8?\xf2\xd0\xda\x87\xfcCD\n\x0b\xd1A\x82\xa9\xdd\nox\x97\x14\xc65Bc!z\x0eu!\xc4\xa9\xe0\x03C\x01\xd7\xddC\x08<>\xc4\xeea\xd9\x9dL\x80\xb0_\xbbD/\xebbo\x9bc\xebJty\x1f4\xce\xce\xd4\xf6\xb7U\x14-\x19\x0e\\\xb1\x15\x87>z\x9c\xd76\xf4okC;\xa3b`\xaa\xe1h\x1f\x99\xf7\xfda9\xf2\xd5\xe8\xf1\x1e\xff\xc5)\x94\xdcm\x82\x93$\xe2\xd7\xcd\x0d\xec=\xdc\xd9\xdd-~\xc7/\xe3\x1d\xfe\x8b\x92Q\xa8\xaa\xbc|\xbf\xd4\xf5p\xb8;\x1c\x0ek'\xf2\xc2:\x11\x9cb\xa9\x1fl\x99?\xbe\xcf\x1f\x9f\xe6\x8f\xaf\xf2\xc7\x0f\xf9\xe3\x8f\xf9\xe3e\xfe\xb8\xa8\x1d\xd6;\xeb\xb0\x1e\xfcz\x1a\xde\x07\x19\xc8D\xdfn\xf9\xc4\x0f\xd27\xd5X#\xbfs2\xa7X\xf4\x0b\xe7U\x8aE\xff\xe4\xb4M\xb1\xe8g\xc0\x88\xd2\xd5A\xfeP\x1fg\x9d\x8f#\xd2\xed\x9b:\x86\xe8'sK\xf9\nO:\x85\xfa\xa8\xbe}Kx\xa0R\xce)\xd5\x7f\x8b\xec\xa3\x85\x04%\xa5\x9d\xc4x<\x9do]\xba\x8c|,;\xcb\x1f\xdf\xe4\x8f\x97\xf9\xe3\xfb\xfc\xf1i\xfe\xf8*\x7f\xfc\x90?\xfe\x98?.\xf2\xc7\xeb\xfcq\x9d?n\xf2\xc7\xe3\xfc\xf1*\x7f<\xcf\x1f/\xf2\xc7\x8f\xf9\xe3\xf3\xfc\xf1713{V\x17C\x82\x07\x839\x8a\x97\xbf\xed\x10\x0bb\xf2\x06\x0e[\xff\x13a\x05c\xdd\xef\xd7\x9a\xcdS\xff\xe3m'@\x91\xdd\x9a'\x02\xe2\xe6\x8a\xa7\xa3\x861\x83\xca\xffB\xb3\x9c\xa3\xfa'\xe2'=\x81.\xe7\xf50\x9b=_\x07Q\x01&\xfcqL\xc9\xeb\xa0\x0b\xffp\xe7\xc4L\xa2\xd2\xa2\xb63{\x98K\xc8A1\xb2V\xfa\x83\x83g\xe65A\xfb\xcf\x8d\xd0~\x0f3\x934+\xf7\xe4\x9fb\xa4s\xaa\\p\xcaV\x1aI\xc8LK\x84\xd0\x111h\xfb\x80\x0e;\x9c]\xdb\xdf\x19\"\x11P\x8dO\x1a!WL\xdf\xec\xef\x8c\x06\x90\x07+\xdd\xd9\xdd\xe1\xcc6\n\xa6^\xbb\xc3\xc1\x08\xbd\x96\x19lS\xeb\x949f[|\xd6%\x1e\x8e/\x1b\xa7\xdd\xc6$\xf3z+\xcce\xbb\x87\xd0AJ\xe6\xdf\xfc\xe2\x99@:\x8df0\xa6[\xee\xb5\xd9\x1bM\xff\x93\xba\xd4\xba=\xf3(}\xa8\xb9!\x11\xfc\xc1\xbee\x05\x99n\xb0\xdeDI\x12\x9c\xad\x84\xb7\xfb\x18\x02!\xaa$\x0b\x10\x8a=\xe64\x11v\x7f\xb8\xf5\xfc\xfc\xd7\xf64Rp(\xe95)\x00\xc4\x90k\x06-@\\D&\x85XRF\xf9E\xc8\xcf\x1b%\xd46\x7f7\"|\xa4\xde\xf1Q8]\x07\xb7K\x1e\xcam\xbalNC\xa7v\x86\xdf[\x19a\xdb\x909l\xe4(u{\x88\xb9/\xa9\xf4\x85a,\x8a\xf8\x99\xb2\xf1/E6\xfe{G\x98\xa2_\xd0\xfe1\xf8\xf39\xdb\xa4 \xaa\xde\xf0\x06^QN0\\\x81{M7MqZ\xd3\xd5\x8cff\xbfy\xecW\x8ad\x87cc\x95\xda\x90\xd3\x06\x83,#\x9b\xdf\xa9\x97\x8f\xfeOA\xc6G\x87\xbe\xcc\xb3\x17\xf4\x07r\xc8a\x8f\x8er\xd8\x83\xce\x10C\xdf\xa8\x9f\x03Cj\xe0\x04\x14\x94P\x13\xe5$\xad\n\xf9\xe9,\xed\x01E\x85+r\xb9\xe5\x14\xa6\xbc\xf9y\x0fV=\xb4\xff\xa8\xbaIq\x00Ea\x87z\x85\xbe=\xf2MU\\\x86\x02;W\x93P\n\x8dX\xae$Q\xbbM\"@-al~\x13\x18\xda\xd1\x8a\x1aZ\xd4?.\xa0:\xa5\xee\\g Z\x12\xf8pF\xa9n([y\x9d\x05\"\x14D\xacDB,\n\xfa\xb6\xec \xf1`C\x0fE\xf6\x9c\xd5\x10\x1b\xceW&\xe2@\xedb\x1c$\xa1\xd6\x12\x91%\xc2)'p\x16\xd3h6\xeb \x1cCf\x80>\xe5`\xa7\xff\x08\xee\xf1t\xb58A\x02\xf8\xf1l\xf0\xa7\xdc\x9b\x823\x1e2\xeb\xbb\xac\xb3\x14[\x875\x8b\xc9\xcc'\"r\xd3\x84\x13\xaa\xe2\x11\x1c\xe5\xf1MS-\x1d{?\xf1\x97\xec\xdb\x92\xb5B\x8d\xe5\x1eM1\xee\xb3\xab\x94\x85\x0b\xb7z\x8e\xc8Fs\x0cYq\xb7\xf0\xc6/\x8d\xeeN>?\x02\x90\xc85V\xba\xd6\xf0\x83\xed\xbc\x7f\xcf\x92\x1f\xa3E\xb6\xaa\xc6.\xfd\xe8\xaf\xb2\xa2w\x1f:\x8a\xf5\xcfY\xfa,\n\x97\xc1\xf97\xd7\xefb\x0c\x86\xdb_D\x97\xe1*\xf2\x17T\x0e\x87\"\x1eB>\x80\xdc\xe9h4\x18j;h\xf8\xd4\xae\xf1*\xdb\x16\x18\x15\xbd\xa2\x92;\xe0C]\x86\xfd%K\xe7\x17^\xc5E+\x9f\x93qJmvU\xd51\x92-\xca\x97\xb8\x9fl\xd8\xfc)\xd6L\xccH2\xf7\xe7\x0dJ\xcb\xe1\xa6^?\xbd`\xe8\x07\x17\xe9\xe9F\xe5\x9f:E\x91y\x14\x80\x9aSM\xbe\x8c\xce\x88\xa8.\xed'\xa9\x9ff \x1c\x1d\xc2\xee\x00\xd3[\x04\xfdl\xb3\xf0S\xf62\xf2\x17Ax\xfe\x06\xdf\xbb\xce\x12\x1d\x17i@\x9c\xb3\xb8e\xb5w\xf1\xcaux\xc1<\n\x93h\xc5\xfa\xa8\x14se\xffo\xd9U\xaa\x91'Y\xbc\xe2@\x86\x17\x07R\x89\xcc\xe5[)\xdcQ\x7f\xf1\xd7+\xea\xc1s\xc3~\xca\xae\xca!\xb4\xa1\xaaF\xfb[\x9d\x1f\x1d\xf2\xcfY\xda\x12\xd2R^\xf78t\xcbw\x15L\x80\xc1\x18\xa6l\xf6\xf7\xc2\x12\xa5s\xaf\x08w~\xfa\xf7\x0c^\x84H\x91\xcb\x1b<\xef\x0b&\x10\x83)9\x93\xd4\xc7\x96\x83\x17\x16[F5\x9a;\xdc\x7fT\xea1\x11#\xd9-\xe2!j\x93\x02I\x92\x0b\x06\x07\xbcL\xbe\xf0\xdc\xa0\x07I\xff\xdd\xebo\x9f\xbe}\xfe\xfe\xd9\xab\x93\x17\xc7\xdf\xbd\xe9\xb5\xdc>\x0c\x0e\x8d\x80\xeccp\xd1\x7f\xbc\xf1\\\xd6\xdf\xf8\xd7\xfc\xa8\xeb(\xde3\xf7\xfa\xf6\xd5w\xdf\xbdl\xdb\xab\xbc9U\x07f\xb5/\x02UEt\xa2\x86\x9c\xf0\x97=\xe8\xc4\xc5\xd1\x05\xc2\xf3t\xe6}\xc5\xf7\xf9\xc1\x83\xff\x03\x14J\xe2G\n\xdb\xf4\xee\xa7\x97\x87\xc9\xa5\x7f~\xce\xe2\xed,\xd8\xe6xg\xe1\xaf\xa2\x90m\xa3N$\xed\xff\x96\xf4\xd7\xfe\xe6\xff\x07\x00\x00\xff\xffPK\x07\x08v\xf2\x8aA\x86\xba\x01\x00\xc5\x87\x08\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00 \x00swagger-ui.cssUT\x05\x00\x01\x80Cm8\xec\xfd{s\xdb8\xb27\x8e\xff\xff\xbc\n=\xbb\x95\x9a\x99\x1dS!EQ\x17\xabf\xeb\xc8\xb1\x93q6r\xc6\xcem\x92\xad\xad)\x8a\x84$\xda\xe0\xe5\x90\xd4\xcdz\xf6\xbd\xff\x8aw\\\x1a $;s\xf6\xf7\xad\xb3\xd9dl\xe2\xd3\x8dFw\x03h4\x00\xb2\x9bl\xed\xe5\x12\xc5\xda\xda;\xfc\x9fN\xe7\xe5\xdf\xfeo'\x08c\xdf\xc6\xde#\xea:I\xd2\xd9\x0c\xbbzW\xef\xfc\xbf\xce\xec\xfac\xe7\x9d\xe7\xa0 A\x9d\xff\xd7Yz\xe9j=\xef:\xa1\xff2@N\x88\xed\xe4%M\xf7\xb7\x97\x8b0H\xb5\x85\xed{x\x7f\x9e\xd8A\xa2%(\xf6\x16\x13'\xc4a|\xfeWs\xde7,\xe3\xdfD\xfd\x9dU\xea\xe3\x03\xf6\x02\xa4\xad\x90\xb7\\\xa5\xe7F\xd7\xb0&\x9a\x9fh)\xda\xa5Z\xe2=\"\xcdv\xef\xd7Izn\xe8\xfa\x8b\x89\xb6E\xf3\x07/\x85K)\xce\xf3\xd0\xdd\x1f|;^z\xc1\xb9N\x95\xd8q\xea9\x18\x9dQ\xcf\x12\xcf\xa5\x9f,\xc20E1\xf5h\x85l\x97y\x14\xd8\x1b\xea\xf7\x049\xa9\x17\x06\x07\xd7K\"l\xef\xcf\xe78t\x1e\xe8\x16\x1b\x87\\K\x99\xf0\xe7=\xe4OJ\x19\xbb\x83!\xf2;\xb4\xa4\x0bo\xe9\xd8Q\xc6\xf0\x8cy\xbc\x8eii}\xdb\x93UZPT\xea0\x90\xdf\xe9\xeb\xd1\x8e\x96+>T\xca\x9d\x87\xbbL\xe4\xdd2\x1f:\x16a\xec\xf3\xca\xfbg\xba\x8f\xd0/1JP\xfa\xaf3\xbe Y\xcf}\x8f)\x01*\xcbf\xb5\x92\xa2(\xfdW=\xb6\xdaQ\x84\xec\xd8\x0e\x1ct^\x14\x01\xd5\x974\xe7\xe7\x9a\x1f>j\x8b\xd0Y'\x9a\x17\x04\xcc\xd4C\x8a\xaa\x04-\x85o\xc1\x16\x95\xf3 \xde\xeb&\x91\xed\xba\xd9l\xa0K\xda\xd0\xb0\x89\xbd`)n@+\xae\x92^\x02,E\xa7\x11\x87p\x9df\xbevnD\xbbr\xec\xed\\\xe4\xc0\x8fh\x972\xb3$\xc2n\x82\xd2C\xd5\xb0\xaei!\xbf\xd3\x1d\xe6\xff\x0e\xb8a\x01\xa3%\n\\h\xda\xac\xe7\x14j\xd6$\x9e\x16\x83a5\xacW\xdd>\xb5\xe7\x18M|{\xa7m=7]\x15\x1d\xa5\xd6\xf2d\xbb\xf2R\xa4\xe5\x83\xf4y\x11y1Sl\xb8\x8cQ\x92\x80\x83\x8f\xd2(Xw\xe1\xbaw\xd9\xeb4\x04\xac\xeb\xac\x90\xf30\x0fwP\x1f\x89m\xd7\x0b\xffu\x92Vd\x0e\x15\xac\xfd9\x8a3\xef-\x19\xe7^\xa9%\x91\x17h@\x17\x14\x10\x85\xeb\x94&:\x94C\x90\xa0\xa1 \xb2cg\x05v\xdfLY\xb9\xc7LJ\x0f\xd3\xc2\xc5\"A\xe9\xb9\xd6cB+\x8aU#K\xf1@s2nX\xdc\x06\x11]\x13\\@\xd2q#[C\xbf\xf00\xd2\xd6\x11\x0em\xb7R\x82pt\xcaG\xed\xcaO\xe9X\x00\xa5\xb6\x87\x13:\nE\xc1Z\x12\x85&k\xdf\xb7\xe3}\x8d\xc0^\x92j^\xca\xf4*\xc7\x0e66\xec\xc4\xb4V\x8b \xed_\xcc$\xe4G\xd8N\x115\x93Rd]\x17\xcd\xd7\xcb\xce\xdf\xa8q! \xb1\xe7v\x96!v\x01\xac\x96\xf7;\x90\xe2\xaf\x8b\xc5\x02\xa2\x98c\xdby\x80)\xd8\xf8\xa7\xa4X\xc6\x9eK\x04Ndx\xdbY\xc7\xf8G\xd7N\xeds\xcf\xb7\x97\xe8e\x14,'Y\xf7\x1d\xf4\xcf\xbc\xcf\x17\xef\xef\xb6\xfa?\xde,\xc3\xe9t:\xbd\xf9\xf0iu\xf5i\x99\xfd\x98\xffs\xfdj\xfau:\x9d^^]\x0e\x07\xef\xb2\x07o~\xbf{\xfd\xe5\xd7\xbb\x8f\xf3\xde7\xdd\xed\xbd\xde\x7f\xbb\xbd\xb8\xf8\xf6f\xec}\xfbp\xf1v\xfe\xe5u\xf0\xed\xf3[\xfc\xf5\xcb\x9d\xe58\x18\xff\x96\x11\xecW\xd1\xe7\xd7+\xfd\xcb\x951{\xef\xdfl\xe6\x1f\xacU\x81\xb7\xfa\xf3\xdf\xa7\xc5\xff.\xb7/\xd1\xaf\x17\xab\xaf\xbd\x14\xbb\xaf.\xbco_\xdch~\xaf{\xc3\xe1\xfa\xe5\xb5w\x11}\xbb\xd4\xbd\xcf\x8f\x9fofW\xc6\xf6\xb6\xf79\xb4?\xad\x06\x8e\xff\xf9#z\xb0>}5\xa3\xf8\xeb#~\xb8\xbe\x1f\xfd|}\xb9\xeb\xbf\x0fV\xa9\xf3\xc6\xc0\xee\x9b\xab%zc$\xf3`6@\x97\xba\xf7\xf5\xcb\xdd\xe6\xab\xffi\x90\xfd>\xff\xf2Y\xff\xfaa\xe4]\xff\xba\x1c\xa07\xc6\xd6}\x93\x8c\xaf\x1f^?\xcc{o\xf1\xf5\xeb\xd5\xcd\xa7W\x17\x97s\xf3-\xbe\xbe\xfc\xb4\xbe\xf1\x8c\xfb\xd9\xc7\xab\xdd\xf5\xa5c\xbd\xbb\xbf2\xde_\xce\xf67\x1f\xb6\xcb\xd9\xfdtw\xf3a\xb4}\xffa\xb4\x9b\xbd\xd2\xb7\xb3\x8f\xe1nv\x19\xeeg\xaf\xa6\xcb\xeb\xea\xef}\x7f\xf9\xdb\xafo\x1f\xbe\xddG\x1f\xee\xae\xbe\xd6\xf28\xfe\x9d\xff\xdb\x87\xb7\xa1\xfb\xeb\xdd\xf6\xbd7\xda\xb8\xa6k\xbe\x0b\x9c\xc7w\xfex\xffm?\xda\xbd\xff\xf8`\xbd{\x9c\xee\xdf=^\xef\xdf\xfd\xfe\xf6\xe1\x9bg<\xa2/\x96\xfe\xf5\xf7e:\x0ff\xf7\x04\xdf\xabo\xbf\xdf\xdc;>\xde\xbao\xf0f\xee]\xec\xbf\xbd\xf9:\xf8\xfa\xe5\xed\xc6\xfd\xfdv|\xed]7:xcl?~\xd2\xc7\xd7\xfeJw\x7f\x9d\x0e\xde\xed\xc7kg_\xdb\xe2~\xde\xd37\xe8\xcd\xeb\xed\xbb\xc7\xab\xf5\xec\xd58\x9d\xe7\xfaY\xa5\xf37\xd6\xe3\xfb\xe0F\xff\xe4\x7f\xa6d\x9e\x07\xb3u\xa9\xd3\xf5\xd7\xde8}g\xaeV\xce\xab\xd1\xee\xdd\xfdt\xe3\x18w\x96\xf3\xe6\xd3\xe6\x93\xff\xf9qn~\xde\x7f\xed}\xfe\xf0\xed\xcb\xd7\xfbk\xef\xa2?\xff\xb2[;\x8fQf{EY\n9\x9c+\xe3\xe6\xfd\xc3\xdd\xe6\xab\xf99\xfd\xf6\xc5\xd2?|\xba\x1d_g\xb6~e=\xd8_n\x07\xb3\x8fw\x97\xef?~\xed\xdf\xe8\x9fz7\xfa\xe7\xd7\xb3\x8f\xaf_\xdf\xdc/{\xb3\xc7o\x97\xb7\xf7\x0f\xdb\x9b\x87\xdb\xfe\xec~\xb9\x9d]]\x13\xfc\xf0\xda1\xefVs\xff\x06\x13\xfc\"\x9a\xdf\xad\x1a\xbf\xcb\xe8\xd2\xf1?\xaf\xdc7\xe3\xfd\xe77\xe3\xcd\xfcR\xf7n\x0b\xfd,?\xbdYm\xdc7\xe3G\xfb\xcdx{}usy}y\xbd\x9d}\xfc\xb4\xfc\xc7\x95\xb1\xfa\xda\xc3\xeb\xbc\xec\xd5\x83\xf7\x9b7\x1d\x95v\x1a\xdc\xbd\xf9\xbc\xb7\x7f\xff\x86\xbf]}\xdb\xcf{\xfa\xd21\xef2\x1d\x0e\xec/\xd6\xa3\xfb\xe6\xf5\xfak\xef\xf3\xdb\xbbK\xdd\xcb\xf0\xef|\x1c}\xbb\x0c\xcd\x9b{g\x7f\xfbpk\xde\xdc\x7f5o\x1f?\xedf\x9f>\xf5n\xef\xdf\xbe\xba\xd5?\xedo.\xa7\xfd\xd9\xc7\xe9vv\x7fe\xce>\\\xd7\xfc\xbe\xbd\x19\xdf\xbb_\x0c<\x0f\xee\x08~w4\xbf\xc7V~\x9bL\xf6w&\xe0\x93\x99\xaf\xbe\x1a\xe7~\xf9\xe9\xe1\xeeM\x81+\xfa]\xde\x0f?\xf6\x97\xbf]\x8e\xfb\xce\x9b\xd7\xf7v\xef\xb3~\xfd\xe6\xf3:\xeb\xef\x8ew\xfd\xf2\xb7\xe4\xe2\xc3\xcfof\xd9\x08q\xff\xe1\xd3\xdd\xc5\xe7_\xef\xed\xaf\x9b\xc7\x97/\x1fG\x97\xef\x92\xcb\xfe\xd2y\xf3\xbb\xf7\xf5j\xfa\xe6\xe2\xfa\x1fo.\x02\xf4\xf2\xe5\xe2u\xb4\x9d.\xb7\xd3\x8b\xf1hj\xbf\xeeE\xf7\xf8\xd3mF~\xf1\xf6\xee\x93u\x15?\xbc].\x97\xbf\xfc\xf2S'F\x11\xb2\xd3\x8e\xde\x11\x8e\xa4\x9a1x\xc6\xc1\xf4\"\x1f\xe6n\x8b\xc1t\xba\x18\xbd\x1c\xaf\xfew0\xfd\xdf\xc1\xf4?u0}\x7f\xf9u\x7fw\xbf\xba\xba\xbb\xcc\x06\xd3\xaf\xfb\xd6\xc1\xafe0m\xf8\xdd\xaa\xf1\xfb\x0f\x1aLo?\xb6\x0e~G\x0d\xa6\xb7\xed\x83\xf3\xf7\x19L7\xaf>\xe8\xc6u6\x18\xcd\xea\xc1\xd4\xbf\xeb\xbf\xb4~\xbex\xfd\xdb\xc5b:{\xed\xbf\x9c],w\xa3\xbb\xe9\x9b/\xaf\x02c:\xf5?,\xcd\xfe\xed\xe0\xe1\xe2\xf2\x1f\xb37\xb3\xcbW\xdb\xebWhv\x8d\xfc\xd7/\xad[{{\xe5E\xd3/\xdbO\xab\xed\xd5\xfd\xecr3\x9f~\xc1_\x1e6\x9f/\xb6\xeb\xd1\xe6\xf6zz1\xbd\xda^\xbc\x8aV\xa3O\x03G\xcf\xc7\xa5+\xfc\xfa\xe3\xc3\x87\xf5\xad\xff\xea\x95\xd2\x00<\xd2\xf2x\x97\x1c\x85\xb3`\x99\x1d~\xef#T\x8f\xbf/\xc7\xf7/\xfb\xb7\xd3\xafw\xbf\xaf\xa2o\xcb\xe9\xf4\xc3\xa7\x87\xff.\x03\xd9\xe6\x7f\xbf\xbdL\xa6\x17\xaf\xaf\xdc/71\xba\xcdF\xe6\xdbj\xe0|\xd9\xbf\x9d\xed\xec_\xeft\xe72\xdc\xbc\xebY\x8f\xef\xfcb\x1c{\x97\x8f\xb5\xe3\xfe\xd7\xdf\xa7\x9b\xd9\x87\xfe\xf6\xddv:\xfa\xcd\\m\xbf~\xb9\x89\xbf\xfd~\xbb\xfc\xea\x7f\x0e\xec/\xfd\xf1\xf5\xfa\xe7\xe1f\x7f\xbd\xb4\xbf\xdc\x8e\xaf\xb1c|\xfcxq\xe3\\\xdd`\xfb\x0d\xbeF\xc1[\xfc\xc9\x8c\xde\x7f~s3\xb0{3\xeb\xdb\xab\xeb\x97\xb9\x8f^f\xfd\xf7\"\xfd\xf6\xfb\xdd\xaa\x19#\x96\xe3\xeb\xb2\xee\xf7\xbe\xf5\xf8\xde\xcf\xc7\xe0M\xd6\xe7\xf31\xf9\xd7\xbb\xf8\xb7\x0fo\xab\xb9\xe2\xeb\xc7\xcf\xd3\xe5mo\xbc\xff\xf6aj\xbc\xbb\xff\x9a~}\xbc\xda\xcd>L\xcd\xf7\x1f\xfa\xbb\x9b\x8f\xcb\xc7\xd9\xfd\xa7\xa4\xec'\x9b\xd9\xe5\xc3f\xf6q\x9a\xce.\xaf\x06\xb3\x8f\xd3\xc1\xec\x9e\x18c_]g\xe3~\xed_\x8d<\x99/\xea^\xad\x1b\xd35\xdd\xbde\xce\xf6\xd6\xc6\xf1\x9d\xcd\xec\xe3\x83\xf5\xfe\xc3h;\xf3F\xfb\x99gd\xf4\xa9cf}\xf1u\xff\xdd\x17\xeb\xf1z\xdf\xf0\xbd{\xf3\xf9\xf1\xab\xf96r~\xbd\x8b\xe6\xbd\xfe2\x1b\xbf\xdf\xfb\xaf\xbd\xb9\xf9Y\xff\xed\xc351Nf\xe3\x00Q\xa7\xcc\x1e\xfb\xff\xc0\xb1\xf9\xf7\xe9\xe0\xd6|\x8b\xbf\xfe~\xb7q\xf0\xddf\xde\xdb\x12\xf3\xe2E87\xef6No\xb5q^]\\\xde\xee\xa7\xfb\xd9\xe5\x95q\xfdju\xf3\xf5\xcbM4\x0f\xb2\xb2eT\xf0\xb9\xb8\xf9\xf81z;\x0fn\xf4\xaf_\xac\xfbo\x9f\xf0\xd5o\x1f\xdef\xfc\xd7\xf6\x17\xfc\xf0\xfe\xe1z7\xbb\xbf\xd6\xdf\x7ft\x1eo\xee\xddW\xb3\xc7\xab\xdd\xdd\xc7o\xaff\x0fo/\xef>^\xeb\xb3\xcb\xe5nv9\xdd\xcf>:;\x82\xdf\xd5\xbcwc\xcc\xbf|^\xbbW\x0d\xbfoo(~z+\xbf|\xee\xac\xe7\x13\xec\xf8\xb8\xf7\xed\xcb\xdd\x1b\xc7\x1f\xa7\xd7\xbf\x16\xba|\xef\x8b\xe7\x85\xdb\xfb\xab\xfd\xec\xfe\xd6\xbay\xbc\xea\xdd\xe8\xd7\x8f\xf9\xbc\xf0p\xbd\xbf}\xb8y=\xbb\xbf\xdd\xbe\xbf\xbc\xda\xce.\xafw7\x8fW^\xc3O\xde\xfa7\x97\xa3\xf0\x1f\x97\xe3_\x7f{\xfc\xf4\xb2\x8d\xa6\xfd\xef\xe2\xe5v:\xbd{5\x9d^O\xa7\xcb\xcb\xe9\x87\xeb\xe9tuu1\xdd]]\xbc\x1c\xddN\xbfd\xe3\xe6\xed\x14\xf8\xdf\xd7\x8b\xe9\xed\x15\xf0\xfc\xfa\xeajzu1\x9d\xce.\x98\x82\x8b\xe9\xe5\xd5\xab\xa9~u7\x9d^]^\xf0<\xef\xae?\xbe\xbe\xf8\xf4\xe5\xea\xc3\xf5\xe6\xa5=\x9dn/\xa7\xb7\xd3WW\xb7\xb3\xbb\xe9\xe5h\x1a\xbe\x0f>~6n?^\x0e\xdf\xbeMV\xbf\x99\x9b\x0f3\xf3\xb7\x97/\xbf)\xcd/\xc6@m\x829*\xbe\xcf\xe6\xd7W\xb7\x0f_\x96\xbd\xe9\xff\xc6\xf7\xff\x7f\x1d\xdf\xab\xce\x01t\x1c\x9e\x8d\xad\x8asV\xcfH\xc9y\xab\x8c!U\xe7\xad\xc7\xcf\xbf\xe2\xed\xb7\x0f\xe3\x0f\xdf~\xbf\xd9\xb8\xbf\xbf\xbd\xcf|\xe9\x9b7{\xb6\xf8Y%\xae\xbfy\xfcj\xce\x1e\xde^\x15I\x97\x99!\x1f\xbf\xdb\xd7\x1d\x0d\xbf\xaf\xad\xfc\x9e-\xbeoOn\x1c\x15\xdf\xdf]\xb6\xf2\xfbN\xf1=\x1a\xbc5\x1f\xb2\x11\xe2\x91M\x96\xe8\x9f.\x93\xd9vv\xff\xe1.\xfc\xfa\x9b\xf5\xe6\xbf\xfb\x1f~\xbb\x99\xdf\xdd\x7f\x9e]\xdd\x1a\x8bWw\x97\xcb\x9f\xbd\xe0\xe5\xe0\xe7\xb7\xc6\xf4\xed\xa7]\xb2\x9c^\xbd\x99NM\xe3b\xfav\xf6A\x7f\xf3\xb5\x18\xcf?|\xfa\xfc\xfe\xee\x1f\xd6\xab\xaf\xd7\xd7\x92\x04J\xb3\x15C\x1f\x8e\xa1\x7f\x03\x8e\xcf\xccCwO=\xe0N\"\xb8\xf4A\x04\xd7\xa3\xcf\xcd\xb8\x98\xfe\x95\xdeZ\xae6\xe6\xe8\x87\xfc\x01\x9dE\x18\xfb\xf4F\xacA\xff\xda\xa3\x7f5\xe9_\xfb\xf4\xaf\x16\xfd\xeb\x80\xfe\x95?\x0b\xb4J}\xba\x15\xf9Nu\xb1\x89\x83|\xdb\xc3\xff\x12\x95\x96\xdbT\xa2\xe2\xc8N\x92m\x18\xbbB@\x8a\xc4\xbcS\xb4K\x85\x85\xeb\x98!,\xb64\xe9G\x1e\xbd\xc7c{\xf4.UH7\x9a>'\x101\xe7\x94\xca\xf3Q\xd4\xb3|\xd7\x93~BKPmK\xd2\x0fW\xf4\xaf\xb4-\xd6\xf8\x94\x0dH\xba7\xd8I\x84\x9cT\xcb\xf7\xd8\x0e\xe2\xf3%b\"M3\x06\xbbq\xb5\x9b\\\x9d0\xb2\x06\xdd\x9e\xf5BF5\xde\x19\x03\x96\xca\x18\x0e\xbb\xc3\xa1\x94\xac\xbf3Y\xaa\xa1\xbc\"s\xd7\xe7\xea1\xcd\xaeiJ\xa9\x06<\xd5`\xd0\x1d\xb4\xc8\xc6\xb7\xc8\xd2\xa5$\xa3\x9d\xc5U\xd3\xeb\xca\x1bd\xedF\\5\x03y5C\xbe\x9a\xa1\xd1\xed\xf7Z\xea\x19r\xf5\xf4\xe5\xf5\x18;\x83#a\xcf,2$\xc5\xc9\xb5C\xedq\xf6< \xf1:E\x934\x8c\xce\xf5I\\zd\xc9M\x9f`\xb4\xc8~'\xce\x0eT\xe7k\xb2\x9f\x1f5/p\xd1.\xfb\xe5\xdf\xff\xe5#\xd7\xb3;\x89\x13#\x14t\xec\xc0\xed\xfc\xe8{Ay\xea\xc0\xd4\x91\xff\xd3A,W\x90<\xa17d\xd4'u\x08\x80P\xadO\x00\x84\xed\xdd\x02\xaaM\xa9g\x00\x84*\x9d\x03\xaa\xaf\xbd\x7f@\x95)t\x11\xa8\xb2\xf6^\x02\xe9Q\xa5\xa3@\xb5\xb5\xf7\x15\x88J\xa9\xbb\xe4\x84\xcf\xdfc\x14\xbaL\xf9\xb0>\xbd3h\xe9G\xfeS\xba\x91\x7fb/\xe2\xe8\x14;\x11G\xa7\xd0\x87\xf8\xba\xd4\xba\x10G\xa7\xd4\x83\xf8\xda\x14:\x10_\x95J\xff\xe1\xabR\xe8>\xbc\x06\x95z\x0f_\x97B\xe7\xe1\x89\xd4\xfa\x8e\xff\xe7w\x9d\xb6^\x82\x9f\xd2K\xf0\x89\xbd\x84\xa3S\xec%\x1c\x9dB/\xe1\xebR\xeb%\x1c\x9dR/\xe1kS\xe8%|U*\xbd\x84\xafJ\xa1\x97\xf0\x1aT\xea%|]\n\xbd\x84'R\xeb%\xf8\xbb\xf4\x12\xb2^\xcf_\x1e\xe8c\xa0\xb4XN\xb8A1y\xce>?W\x9d?\xfd\xbf\x9e\x1f\x85qj\x07)K\x12\xa4\xb6\x17\x00D\xf9s\x82\xac}\xa6;\xf0\xc2d\xd3\xee)\xf2\xc0t\xacH\n2)\xcc\xbe\x85\xa0\xfeirBd\xc7\x89)\x94\x08\x9f&\x11D\xc6IDQ\xce\x97\x9a\x83\x82\x94v\x9d\"\x19t\x1e\x84\xe5O\x13\xa2\xac\xf6sn\x90\x98/\xb54\x8c\x8e\xe6\x93\x86\x11\xc7'\xef4Gs\xe2;\xc5\xbc\xea\xc7G\xf3*\xc88nY\xe7=\x9a\xd7\xf1\x8b\xab\xda*L_P\xaaN`\x98SX ms\n3\x89yNa'\xb1\xd0)\xec\xda\x82\x12\xd5\x11\xa51\xdd\xf1N'\xb2\xdc\xf1\x9c\xc4\x86;\x9e\x97\xccn\xc7s\x93\x99\xedxnmV\x93\x1a\x08\x1f]\x9d\xc8@\xc7s\x12\x1b\xe8x^2\x03\x1d\xcfMf\xa0\xe3\xb91QL\xb7<\xfe\xce\x1f\x83\x07a\x1aqL\x1389O\x94\xc2\xe4zMt\xfc\x18\\\xf1\x08\x92\x13\x84\x05\xa9\x14\xe4%\xe9\xda|[uD\xaa\x98\xfb\xa7\xb4\x03 Ri\x86\xaf\xdc\n\x89\xc0\xf8\x14\x81\x01\"\x15\x811)0\xed\xfb6}\xcf-g9)\x1f\x95\xd18s\xbb\xa7;O+\x9alt\x00\xe8\xb2\xc7\"\xda\xfa^]1\x1e\x00\xd4E\x81\x88~N\xdf_\x86\x18\x94%\"\x0e\xb8\xe2\x90wz\x80>\x7f.\xa2\x0e\x80{\x81\x94\xba\x8e\xef\x8bs;\x9f\xd2\x8f7\x03Av\x8a%\x08\xf2S\x8dA\xb08\xdd\x1e\x04\x93\xd3L\xc2\xa9\x0f\xb2\x8a\x82Y\x14\x86\x9b\xb9\x9d\xcd\xe3'\x98\xca\x7f\x92\xa5\xfc'\x1b\xca\x7f\x06;\xf9O4\x93\xffT+\xc1\x06\xc1'\x19\x04?\xc9 \xf8\xc9\x06\xc1\xcf`\x90'\x0ee\xac\xe6@\x83\xd04Zq\xd5\xaf\xa2\x13\xbc\xe3 \xc3\x05\xc8\x8eA\xb0a\x18\x1c\xd8\xb5\xe3\x07m\x19\xdb{\x06k\x9a&\x87\xf5=\x17\x82Z\x96\xc5A\x01\xd8p8\xe4`\x89\x877\xcd\x85\xef\x128\x1e\x8f9 .\x8c\x0d\xc1m\xdb\xe6%\x0d\xc3\x00\x92\xc1q\x1c\x01k\x00\x8c\x10\x82u\x9b\xdf\xd2d\xc0\x8b~\xf6\x87\xc3\x83P\xf6&g\x85\xd3\xc6:\x0d]%\xd8\xfeQ?\xd3_\x9ce\xb1\xf8Yw\xfc\x93\x80p\xd4B8\x12\x11\x0e[\x08\x87\"\xc2A\x0b\xe1@Dh\xb5\x10Z\"\xc2~\x0ba_Dh\xb6\x10\x9a\"\xc2^\x0baODh\xb4\x10\x1a\"B\xdd\x92\x13\xeaB\xed\xe8\xbd6\xd2\x9e\x98\xd6h%6 \xea|\x8c\xe1\x9c6^\xces\xda3\x1dt\xd8\x82\x88uX\x92\x08p\xd6\x82\x88uV\x92\x08p\xd4\x82\x88uT\x92\x08p\xd2\x82\x88uR\x92H\xa8\x08\xd6AI\"\xc09\x0b\"\xd69I\"\xc01\x0b\"\xd61I\"\xc0)\x0b\"\xd6)I\"\xc0!\x0b\"\xd6!I\"\xc8\x19K*\xd6\x9f(2\xb1+\xf1\x8eH\x11\x82N\x98O`1r\xd9\xc1{\xa8\xf7u~\x9c\xe5\x81\x8bE\xdf0\x07\x82Y\x01\x82\x0f{\x16?\x89\x84\xb1\x1d,\xf9\x81~`\x02\xf3\xf32\xc4<\xd7\xf9\x10@\xee\x11\xc6\xe1\x96\xc6\xf2\xaf\x0e\xa8\xa5\x85\xe0\x7f]\xcc\x17\x86\xcdO\xa8\xd1:\x8e0+\xb0\x85z\x8e\xcdO\xe6\x05w\x90\xc2\xee\x0f\xccE\x0f6J\xe4\x05l\x04\xe2Z\xba>\xe2\xad\xb2\nS\x08\x9d\x99f\xce\xcf\xa9 r\xa4\x0b\xa7v\x10o\x9b.\x1f\x8e\x94\xc1\x10B\x01\x837\xcc\xe1\xd0\xe2\x9b B\xc7\xf6x\xc8\x0b]E\x19<\xc1\x18\xa1\xb9\xc3\xeb$\xb07l@\xa2\xeb\xc6\xbc\xcf\xb3\xce\xa5\x9e\xe35k\x1b]\xef\xf7\xc7|\x08\x03 Mk\x88\\\x91W\x01\xf8\xf1\xc0q\x80 &\xc7\xa3\x04$q\\\x04\x91l\xedd\x85\\\x88`1X,\x16\xbc\xf4%\x01\xa4H4Z\xb8\x0b\xde{K\n\xb8s,\x16\x0e\x9a\x8bH\xa0\xde\xef.\\\xbe\x15d:\x91\"\x10f\x88\xe6\x9aV\xbe\xea\x84&\x80\xde\x7f\xd2\x9d\xc7\xf5\xd0\x1d\xdb\xae\xb7N\xce\xd9\xa1\"6\x18@\xd7\xe8Y1b\xd3\xadq\x8f\x85\x81(\x93EA\xa0>\x032\x00\x8cf\xe8\xac\xe4@R9\xd6\"\x0fc\x067\x1e\x8f\xc7\xc0\xea\xaf\xdew+\xc0y\x92<[iUz!\xd7\x90\xc5:P\xa41\xad\xd8U,\xe0UV\x1bbU\x96\xb5q+\xf7\x16[\xe4\x82*\xe2y\x15\xdb\x81\xa2\x96\xc8\x05kO\xb6\x1cX\xe7\"\xd3Q\"\xff\xe21\"\x17\x03\x90\xb0\x97\x01@\xd0\xd1x\x9c\xc8\xd7\x00\xa4\xc8\xddx\xa8\xdc\xe3\x98\x8c\xdfS\x9c\x8eO\xdd=\xd9\xefT\xa4Sw=\x86\xdb1\xde\xa7\xe0~*\xb9\xbeX'\x12oB\x97d!B\x8f\xe4\x80\x02\x87\xe4p\xb0?\xb20\xa1;r@\xa17\xb2\xc8\x16g|\xb6\x01\x90\xcbN>\xdd\x15\xdbe;\xc2\x13\xfd\xef\xe3\x88\x02\x9fc'!\xc0\xe7X\x88\xd0\xe78\xa0\xc0\xe78\x1c\xecs,L\xe8s\x1cP\xe8s\xc7M\xb9,\xbc6oc \xa2\xa0<\x9e\x06\xfb\x1c\x9b\x80}\xba\xcf\xe1\xe7\xf49|\xb2\xcf\xd1\xfc4\xadx d\xc5\xaeH\xf5\x02/\xe5-\x82\xf8,\xe4d\xa0\xf93\x0eZ\xdeF&\x91\xc0&f\xb6\x84\x08\x03D\xe3\xf2w\xd4\xb5\x0f\xd1\x07\xb8!\xdcn\x8f\xb4-\xd8\x92a\xb5\xc8(\x1cDd\x17\x1e\x08\x9b\x86\xc7\x81\xd6\xe1`\xa0\x818\x14l#&\xee\x15\x9a\x89\xdb\xbe\x17Z\x8a\x0f\xf5\x85\xc6b\xf7\xe2\xebm\xc0v\x83\xa9\x0cl[\"\x1a\x15\x1a\xd1W\xb4!\x8b\x13\x98\x90\x85\xc1\x16\xf4U\x0c\xe8+\xd9\xcfW3\x9f\xafj=68\x16\x1b\xcf?\xc1v\x023\xe1V3aE3\xb18\x81\x99X\x18l&\xacb&\xacd&\xacf&\xacj&6\x9e\x14\x9b \xc3f\xa2\x80\xc9\xcav\xc3\xadf\xd0\xd7\xba\xf3\x87\xe7zG\xef\xf4\xa3]\xa7\x17\xed:\xf4\xa6\xcbD \x05\xd6\xd4\x13\xd54R\xaa F\x815\x99PM\xbd\x92\xbe\xbd]r$Xc_Vc&\xb9\xaeP\x1f\x84\x03k\xb3\xa0\xda\xfa\xa5\xc4m\xb5\xc9p\n\x83\xf0\x01t\xa2lT\xff\xd3\xfcHR\xd9\xf3\xbb\x92\xa0\xb2\xef\xebM-\x95\xb6\x99\xf8x\x87\x12T\xf8,>\xa5\xe0T\n3{\xedi\xfe\x9f\xe8h\xc2\xba\xbe\x83\x9f\x81u}g7\x93\xd6\xd9f\xf4\x13\xbc\x0c\xac\xefOp2\x99?\xe1?\xd1\x9f\x84u}\x07\x7f\x02\xeb\xfa\xce\xfe$\xad\xb3\xcd\xbe'\xf8\x13X\xdf\xf3\xf8\x13Ua\x14\xa3\xfa\x0b\x1e\xda.\xff\xb4E\xfdq.m_~\x08\xa8\xf9\\W\xe2\xc4!\xa6?%\xd2\xcdb@=\xff\xe6\x11\x13\xb0\x15Q\x9f~\x80S\x89E\xa4\xa7W\x9fRb\x8a\xf3\xf0N?\x14\xe9I\xbe>#\xaf\x8f\x0fa\x8b*\x8d\xb2J \xc4-j5\xaaZyD^\xb1QT\xcc\x97fu\xf7\xf2\xba\xf9\xc8\xb8\xa8\xbbW\xd6\x0dD\xceE\xdd\xbd\xaan\x1e\x91\xd7\xdd+\xea\xe6K\xb3\xba\xcb\x86k\xa2\x96\xd7M\x07\x10e\xfdM\xe3\x01L.A\xd5|\xa0<\x97\xa1P\x80&\xd2@\xad\x02\x00Q\xc9P+\x01\xc0\x142\x94j\x00\xca\xab{\xd4\x9a\xb6\xf00>HoS+\xcc\xd0\x07\xde\x99\xb3\x98\x01\xf0\xe7\xc2'\xb3B\xc8-Ko\xcf\x8a\xa5\x0e_\xa4 \x9f\xcf\x1d\xbb\xaa[\xe4\x99u\xf5B\xe7o$\x10\xfb?!\x84\xc0\xc9+9D^Z\xcb!\xec\x08\x8d\x1c\xe2\xbe@\xc8!r\xf8J\x10\x89\xcf75\xc9\xdc\x9e\xa8K\xec\xf9u\xb3\x84\xce_\xcb#\xf6\x7fB\x1eI\x17 \xe5\x11\xf6\x82F\x9e\xb6\x8eP;\xad\xb0/(t\x06\x85p\xb5\xe8!\xbe\xa4\x83\xf8\xd2\xfe\xe1\xb7t\x0f_\xda;|y\xe7\xf0\xdb\xfa\x86\xdf\xde5\xfc\xb6\x9e\xe1\xcb;\x86\xdf\xd6/\xfc\xf6n\xe1\xb7\xf6\n\xbf\xb5S\xf8*}\xc2W\xe8\x12~[\x8f\xf0[;\x84\xaf\xd2\x1f|\x85\xee\xe0\xab\xf6\x06\xffI\x9dA\xe8\xf7X\xe2\xf7X\xea\xf7\xb8\xc5\xef\xb1\xd4\xef\xb1\xdc\xefq\x9b\xdf\xe3v\xbf\xc7m~\x8f\xe5~\x8f\xdb\xfc\x1e\xb7\xfb=n\xf5{\xdc\xea\xf7X\xc5\xef\xb1\x82\xdf\xe36\xbf\xc7\xad~\x8fU\xfc\x1e+\xf8=V\xf5\xfb\xb6\x80\x88&v\x16\xe7\xf6\x82}5j\xf6t\x8e\x16a\x8c\x0e\xe5\xc7{\xcf\xff\xd2\xf9\x0b\xfd\xe5A\x98\xcd\xc1\xc1\xc8\x8e\xcf\xe7a\xbab\x01\x87\xbf=\x86\x99o1\xcfqI\x92I\xc7\x14U\xdc\xf2\x960esqMAYt\xd2N\xb9\x93O\xa3b\x91\x9aRP\xaa\xa6\x18\x12\xac)U\xd8 V\x9d\x8e\x9dl\xa8\x93\x08\xecK\xe5\xf5e\xe2\xfa\xea\xd2\xc2\x82\xc9\x8c[\x17\xc2\x82a\x99`\x98\x12\x8c*u\x03\xd9\xe7\xfc<\xe6S\x81L\xf1\\\xf2A\xc2\xae\xeb\xcd\xdb?4\xd8u\xbd\x94E\x01\xfd\xc5m@`\xa9C\x17k\x0eb\x17\xddn\xaa\xc5\xe1\x96\x81\xc5\xe1\x16Bi\xcb8\\G<\xb6x\xceQ8!^\xfb\x01+A\xfeP\x80\x05+ \x8b8:m\xe1\xed\x90{(\x90\xd8\xde\x87\xeb\xf4<\x7fD\xbc\xfeJ\xa1\x7f\x1c\x18\xdbg=Lf~\xb2\x1c\xf6\x00\x12\x01;\x01\xcfC\xe0\x07\x00\x1046\x89\x83\xbd\x81C\x08\x1d\x82GJ}\x02\x84K\xdd\x02\x10\xa5\xdd3DDR\xe7\xc8\xd73R\xffPp\x10\x85\x01\xd4\xcd\x06:\xa9\xd3\xf8m>\xe3\xb7\xb9\x0c\xcbA\xe41\x1c\x0ev\x18\xbf\xcd_|Uwa\x81ro\x01\xd0rg\xe1\xe4P\xf0\x15\x98F\xee*\xfe\x93<\x05v\n,w\n\xdc\xe6\x14\xb8\xcd)X\x0e\"\xa7\xe0p\xb0S\xe06\xa7\xc0\xaaN\xc1\x02\xe5N\x01\xa0\xe5N\xc1\xc9\xa1\xe0\x140\x8d\xdc)p\x9bSPt\x0b\x8cvu%D\xee\xbd\x0e{5?\xd12\x10\xf9,\xfb\x9dfS\x9a\x08\xe4V\x99\x99aJ\x90\x90E\xc4c^R\xcd^\xa7!\xb5E\x90==7&\x95\x94\xe7F\xc7\xe8\xe4\xd9|\xfa\xb7\xc6\xeb\xf5\xfc\xe7\xea\x85\xa9@\x15\xf9\xe1S\xae\n\xbd\xa9\"\x7f\xe7A\xfd\x13\xc0\xa1\x8c$H\x1ea\xece\xeb\x89\xea\x0b\xe3\x13\xb2\xcc\xf5\xe2\xe2\x95\xff\xe5\x17\xcb\xeb\x9a\x88\x92\x82\xe5\x04|\nH\x90\xc5H@\xf5\xab0\xf6\x1e\xc3 =A\x808\xdc\xb2\xb5s\xfd#/\xdf\xc6vt\xa8\x19d\xbf\x9dg\xffL\xe8_A\xbd\x03\xa4\xc5\xc3 \xfb@P\xaf\x16\xa3\x0d\x8a\x13\x04\xd4_\x15M\xe0\xc7B+6,\x8f\xb6fU\xa3\xd0\x9c\xb4L\xa2R\xd8\xbc2\xb9Z\xcd,\x91\x8c`\x0d\xd8\x1b\x96\xc9K\x91\x9fhIj\xc7)%N\xf1\x19\xfd\xfcyS\x15\xf90\xff9\xff\xbcy\x92\x8f)\x05\x0f\x889\n\\\x805\n\\\x96q\xf6\x88c\x8b\x02\x17bZ\xbe\xe8\x93\xe7[\x14\xb0\xac\xcb\xa7$\xf7\xe2\x11\xc4{n'(\x1b\xc8\x00\xeeU\x11\xcb\xbf~N\xd6P=\x845\x1e\xa3\xd4Y\x81:\xcfKx\xad\x17\x8f\xc9\n\xcag4\xff\x04\xe1Ee\xd0\x8aE\x06\x07\xac\x97A\x85\xc6\xcb\xf9\xe4\xb6\x03\xb84\xa6jxp\x96\xca9T\x86\x02\x98PF\xc9\xf9@6\xc9\xb94&\x01\xf80\xca\xcf9\xc1\xba/uS\xaa\x1e\xd4\x0e\xa9\xe5\x9c\x13\xa8\xe4\xfbu\x92z\x8b=\xd0q\"\xdby`\xfb\x0d\xf1\xac\"\xac\xb2T\"\xedW8\xb6\xf3\xe4\xac\xa8\xbeS?\x01YsF\xa9Q|\x07\xca9\xb1\xfd\x87|\xc8\xd6\x00\x99\xab\xc2\xccQ\xbaE(\xe0+(\x01L\x0d\xd5S\xb6\x8a$\xb2\x1dT1\x83k\xb2\xf3\xd74\x1eh~\xae\x97\xa4\xb17_\xa7H\xc0\xb2\xa0\xa29\x96\x08\xb6\xf7\xe4A\x0da\xc3\xc29\xda,X1\xa3\xbaP\xc3\xaa\xe9Ar{Ul\xd8~\xd4p\xa2\xba\x91\xcc4\x15\xab\xda4<\xaf\xca\x0c43\x89\x11*\x9e\xac\x11\x1a\x96\x84% \xaer;0=\x95\xb4\x04\xd9Qk\x96P_-\x0e\xdf\xea\xccl\xebz\x81\x8d\x8bh\x9c\x88A\xb5\x1c|\xaeO\xca\xffB\x9c\x0c \xa7\x1e\xcb\xc9(9\x19\x10\xa7\x9e\x84\x93\xc9r\xea\x95\x9cz\x10'S\xc2\xa9\xcfr2KN&\xc4\xa9/\xe1d\xb1\x9c\xfa%\xa7>\xc4\xc9\x92p\x1a\xb0\x9c\xac\x92\x93\x05q\x1aH8\x0dYN\x83\x92\xd3\x00\xe24\x94p\x1a\xb1\x9c\x86%\xa7!\xc4i$\xe14f9\x8dJN#\x88\x13\xb6\x93T\xe6\x9cz\xf6?\x96\xe38\xfb\xdf\x84\xf8\x19\x085\x97Y\xd4\xa7\xcb\xd6C\xe5\xbbm7\xe8\\\x9f\xd4$\xe0\xca*\xe7e\xc8\x96o\x0d/\x83\xe0e\x00\xbc\x92U\xec\x05\x0f\x99d\x15i\x80\x966)F\x81\x00\x05)\x89\x0d\x80\xd8\xa0\x88\x0d\x85\\\xdb\x81\xe7O\xe4\xfd\x88\xc6\x9e\xbe\xa4\x86\x18>\xf7\xaaZc\x0e\x0c/\xbe\xcb\xc2\x1a\xac\xe5\xf8\xb55\xcbFmA\xf6\x9c\xcbk\x81\x04\xadK\xafgZa\xe7\xd5W<\x8e^d\xf3\xd4\xa7\xad\xb3a)\x9e\xba\xd4>\xcd\xb8\x7f\xcaj\xfbT\xab\x7f\xbf\x057+\xd1\xf3\xae\xb9a\xee\xcf\xb2\xec\x86Y?\xe3\xca\x1b\xae\xe0\xb9\x17\xdf\"\xfd?\xd7\xfa\x9b\xeabOY\x82\x8b\x18\x1d\xbb\n\x17\xf19a!.bu\xdaZ\\\xac\xa9\x13\x96\xe3\xacY\x9f\x7fE\x0e\xd6\xf0|\x8br\x90\xfd3\xaf\xcb\xc1:\xbe\xd3\xd2\x9c\xb2\xee3\xad\xce)\x9eO^\xa0\x0b\xb8\x9d\xb6F\x170;u\x99.`\xf7\xc4\x95\xba\x80\xeb\xd3\x17\xebB\xc3\x1c\xbb^\xe7\xe7\xeb',\xd9\xe5\xcc\x8e\\\xb5\xcb\x99\x1d\xb9p\x973;r\xed.gv\xe4\xf2]\xce\xec\xc8\x15\xbc\x9c\xd9\x91\x8bx9\xb3#\xd7\xf1rf\xc7/\xe5[\xfc\xf6\x89\xaby\x96\xfb\xe2i\x0bz\x90\xddS\xd6\xf4T\xf7?aY\x0f\xd3\xb3+{\x85\xa5\xbd\xc21\x9a\x9c\xa7\xff\xcc\xcb}\x9e\xdf\xb3\xaf\xf6\xfd?c\xb1\x0fTr\xc2Z\xdf?a5\xf8\xacK}P\x80\xd65\xdfs\xad\xf4\xfd\xa7,\xf4Y\xe2\x13\xd7\xf9\x90\x0cO^\xe6\x9fb\xd7?g\x95\x7f\x9a\xc1\xbf\xe3\"\xdf\xff\x9ek|\x88\xf9\xf3,\xf1!\xce\xcf\xb9\xc2\x87\xf8?\xfb\x02\x1f\xd6\xfd\xb3\xad\xef\xfdgZ\xde\xc3|\x8e^\xdd\xc3lNY\xdc\xc3\x9cN\\\xdb\x8b\xb4t\xca\xd2\xde\xff\xde+{\xa0\x82g\\\xd8\x03\xdc\x9f{]\x0fT\xf1\xbd\x96\xf5\xfe\xf3\xaf\xea\xfd\xe7\\\xd4\x83\xccN\\\xd3\x83\xbcN^\xd2\x83\xdc\x9e\xba\xa2\x07\x99>\xc3\x82^`\x93\xa3\xd7\xf3\xec\xcc\xfc\x94\xe5\xbc\x8c\xd7\xb1\xaby\x19\xafc\x17\xf32^\xc7\xae\xe5e\xbc\x8e]\xca\xcbx\x1d\xbb\x92\x97\xf1:v!/\xe3u\xec:^\xc6\xeb\x84e\xbc\xd4]\x9f\xba\x8a\x97\xae\xae\x8e^\xc4K\x17\x84'\xac\xe1\xfd\xa7-\xe1!\xf2\xe3V\xf0\xa2\xc5:~\xe6\xc5:\xcf\xef\xd9\x17\xeb\xf8\xcfX\xac\x03\x95\x9c\xb0X\xc7',\xea\x9eu\xb1\x0e\n\xd0\xbav{\xae\xc5:~\xcab\x9d%>q\xb1\x0e\xc9\xf0\xe4\xc5\xfa)v\xfds\x16\xeb\xa7\x19\xfc;.\xd6\xf1\xf7\\\xacC\xcc\x9fg\xb1\x0eq~\xce\xc5:\xc4\xff\xd9\x17\xeb\xb0\xee\x9fm\xb1\x8e\x9fi\xb1\x0e\xf39z\xb1\x0e\xb39e\xb1\x0es:q\xb1.\xd2\xd2)\x8bu\xfc\xbd\x17\xeb@\x05\xcf\xb8X\x07\xb8?\xf7b\x1d\xa8\xe2{-\xd6\xf1\xf3/\xd6\xf1s.\xd6Af'.\xd6A^'/\xd6AnO]\xac\x83L\x9fa\xb1.\xb0\xc9\xd1\x8buvf~\xcab]\xc6\xeb\xd8\xc5\xba\x8c\xd7\xb1\x8bu\x19\xafc\x17\xeb2^\xc7.\xd6e\xbc\x8e]\xac\xcbx\x1d\xbbX\x97\xf1:v\xb1.\xe3u\xc2b]\xea\xaeO]\xacKWWG/\xd6\xa5\x0b\xc2\x13\x16\xeb\xf8i\x8bu\x88\x9c[\xac3\xf4\x87\x05\x0e\xed4\x7fG\xce\xe4\x0fz-\xcc@\xe3\x12\x9a\xbf1\xa7\x05\x1b\x94\xd8\x93\xde\x82\xb4\xc8\xdf\x82\xa4.W\x83V\x12\xad\x81+\xbcYH\xfd\xfc\x81\xe6\x1f#\xb2\x7f\x94\xc4\xbe\xba\xc0\xb0l\xc7\x98\xb9\x06\xab\xc9\x86)\xd9\xa8\xd2\xc4\x0e\x12-A\xb1\xb78,\xc2 \xd5\x16\xb6\xef\xe1\xfd\xb9fG\x11FZ\xb2OR\xe4\x9f]`/x\x98\xd9\xce\x87\xfc\xd7\xd7a\x90\x9e\xd9\x1b\x14xq'@\xbb\xea\xe7\xb3\x15\xc2\x1b\x94-r\x9b\x9f:\x01Z\xa3\xb3\xf5|\x1d\xa4\xeb\xb38\x9c\x87ix\x16d\xff$h\x19\xa2\xce\xda;\xb3c\xcf\xc6g\x8d\x14\x8ct\x9c`K\x14\xc6K\xcf>\x83\xc0\xb9t\x9a\xa0E\xc2*J*\x9e\x80\xc7:\xa1\x8b\xa8\xf7\xa0e\x0f(\xa2Wa\x90\x84\xd8N\xce\xfc0\xb0\x9d0\xfbO\x98G\x13,\xa3u\xec\xa1\x98!\xcd\x9fun2\x95\x96\x00\x11}\xad`\x8a\x03\xa3\xf6\xc6\x1e\xa2\xb6\x17\x86\xa3x\x00v\x15R\xa7+\x84\xed\x84&/\x9e\x9dI\xccT\x16\xa9Z5\xf5|D\xd7\x91?\x81\xa0\xf3\xd0\x0d\x03\x8f\xc2^\xe4\x8f:\xb3\x8f\x10\xde\xb1\xb1\x97\xa4!m\x85\xe2\x99\x80bi\xc7\xb6\x1f\x06.-|\xf9\x10\x14\xc9N\x1eP\xbc\xf10\xa6\xfd\x84x\x0e\x91\x95\x8d(>\xa1\xe5\xa56\xf6\x98\x0f_/\x12\xad\xc8\xc3\x91\xc0\xe2\x89\xc2`I\x8f=\xf9;\xafT\xebc\xb0e\x95\nu*\x0c\xd0^6\x88\xaa\xca\xe1\x1f-\x06X#V\xaf\x11\xd25\x8d%M\xb2-r\xc8}\xee\x93\xefT1\xf7E\xf8\xc5\xd6\xa0\x00\x06\x0f\xe8Q\x80\x1e\x0f0)\x00\xf7y\xfa\xc5\xb6/\x17q\xb1\xb5(\x80\xc5\x03\x06\x14`\xc0\x03\x86m\xcd\x1cQ\x80\x11\x0f\x18S\x80\xb1~\xfc\x9b\xba\x19\x8f\x15Z\x84E@Fa1\x90]X\x0cd\x1a\x16\x03Y\xa7U\xe2E\xf1\xb9\xb36\x1b\xb1\x18\xc8L\nm\x1f\xb1\x18\xc8X,&\xb3\x97\x82\xc1\x14F\x05\xba\xbf\x8b\x8d\xe8\xb7\xb5\xc3` \xa0 \xfdv\x0b\xfa\xed\x06l\x11v\x91\x7f\xed\xac\xd5|~\xbb\xf5Z\x1b=b \xa0\xed\xfc#M'\xb6R\xdb\xe0\xc7\x00@+\xe1v+\xe1v+\xe1v+\xb5\x08\xbb\xc8?v\xd6j%\xdcn\xa5\xd6F\x8f\x18\x08h%\xcc[\x89\xc2xA\xb4N\xb5\x18%\xa8\xb9\xdfnG\x11\xb2c;p\x8a/qN4?|d\x1f2&Z\xa7i\x18\x14l\xce\xcfs\xfc\"t\xd6\x89\xe6\x05\x01\xfb\x16`\xa2F\x1eZ~\x86\xed\\\x9fD\xb6\xebz\xc1\x92]\x18\xaf\x8cC\xb9\xd1\xca\xbf>y\xd5\xab\xca\xf8\xd7\x19\xaf\xcc\xaa\xac\xcf\x97\xf5\xab\xb2\x11_f\xd5\xf5\x0d\xf8B\xadW\x17\xf7\xac\x17l\xa1\xa5W\x85\x16\xfb\xa9\xe5\x956\xac)\x87<\xa5\xa1\xd7\xa4\xfcg\x9a\xf3\xcd\xe6\x1cBl;\xf3\xb0\x0d-\xddf\xc5\x15\x93\xf2\x01\xc5\xa4\x84@1-#\x0b\xc8D\xdb@R\xb2\xc0U\xf1\xce\xb9\x12\x90\xfd\xcc\x96{\xc1\n\xc5^ZA\xca_\x15\xe6\x89\x03\xe39\xd9t#q\x1e\xa2\x18\xf2\x1f\xa2\x18r!\xa2\x18\xf2\"\xb2n\xd8\x91\xc8\xea!_\"\xcaAw\"\xcaa\x8f\"E\x10;U\x86j\xf7+JX\xd0\xb5(qA\xef\xa2\x04\x86\x1d\x8c\x16Y\xecc\xbc\xd0\xb0\x9b\x11\xfc$\x9eF\xa0*gS\xf06\x85\xa8d\x95E\x132\x0f\xf4\xa5\x0e\xe8K\xfd\xcf\x97\xba\x9f\xdf\xe6}\xbe\xdc\xf9|\xb9\xef\xf9-\xae\xe7\xabx\x9e\xaf\xe2x~\x9b\xdf\xf9mn\xe7\xb7z\x9d\xaf\xe6t\xac\xbc\x02\x9f\xf3U\\\xce?\xce\xe3`\xe7\xc2R\xe7\xc2R\xe7\xc2R\xe7\xc2R\xe7\xc2m\xce\x85\xe5\xce\x85\xe5\xce\x85[\x9c\x0b\xab8\x17Vq.\xdc\xe6\\\xb8\xcd\xb9p\xabsa5\xe7b\xe5\x158\x17Vq.\xcc9\x17\x05Lc\xdby@\xee\x01\xa34E\xb1\x96D\xb6\x93E^]\x83\xfb>E\x01\xd4\xd2\x8c\x19\x0b\xd7\xba\xba%\"\xf0\xd1\xd2\xe6\xd8\xf72x\xfb\xb8z\x009\xe6\xdf/:F\\\x80\xa2Mb\xa8\x92\\h\x05\xa9\x15f\x83\xba\xaac[\xc2\x11\xb46\x84\xafB\xa1\x1d\x12\x91\xf1\xb1\"s\x04\xad\"\xf3U\x14\"S\x14x\xa5%!\xf6\xdcC\xbe\x8f^u\x16\x0e\x93z)F4\xa6\xdb\xb38\x98\x13F{\x06e)\x98\xfa\x00\x8a\x94;O\xbbT\x1cL$\x18\x0f\xb4\x9e\xc9\x0fk\x89}%\x81}EyY\\\x9b\xb82\xc9\xb0\x92dXQ2\x16g\xb1^\xe5\x05\x0f\x87\x14\xedR\xcdEN\x18\xdb\xe5 Vv\xd1\x9b\xc1\xce\xb8'\xe7\xb6\x93z\x1b\x04\x14\xe4\xcb\\\xe0\xf9*\xdc\xb0k\xe4\xfc\xb9\x80\xff\xc6K\xbc\x145o\x1cMc;H\xbc\xea\\g\x18w\xba\x86\x95t\x90\x9d \xcd\x0b&\xd2R\xbe=\x85\x90\x87p\x9df*:7\xa2]\xc7\x0d\xd3\x14\xb9\x1dg\x1d\xc7(H_eLX\xba$=d\xff\x14Yn-\xddGP\x8e\xc0\xdf\x16\xab\xc1\xda\x15\x81\xd9zk\x90\xe5\\,\xe1o{D9\x1f\xc6\xf8[\x93(\xe7\x03\x19\x7f\xdb'\xca\xf9P\xc6\xdfZd\xfd|0\xe3o\x07\x04\xc0\x84$\x18\x92\x12@U\x8c\x08\xc0\x00\x92qL\x00\xc6\x90\x0c\xc5+\xd4\x1b\xd0I\x9b\xf1\x859\xf2\x85\x93\xdc\"\x0c\x042\n\x0d\x01\xedBC@\xd3\xd0\x10\xd0:\x8c,\xa0\x81h\x0cl#F\x1a\xd0L4\x06\xb6\x14\x8d\x11\x1b\x8b\xc6)\xec\xf6\xab\x8e\xdd\xa5\x15\xfdV#\xfa\xad6\xf4[M\xe8\xb7Z\xd0o5\xa0\xdfn?\xbf\xdd|~\xbb\xf5\xfcv\xe3\xf9j\xb6\xf3\x8f3\x9d\xd8J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xddJ\xb8\xddJ\xb8\xddJ\xb8\xddJX\xcdJ\x98\xb3\x12\x05\xdb\x1a\x07\x91Z\xb7\xbd\x83H\x9f[\xf3 R\xe4\xb6\x7f\x10ipk\x1d\x84\xaa\xcb<\xa1*e=`\xab\xf5\xaa\xb2\x1ePVq\xe5\xd6\xd0[\xcd\xac\xe8L\x9e\xce\xac\xda`\x9a|Y\xd5\x08\xb3\xcf\x95\xf5+\x9e}\x9e\xa7U\x95q\x0b\xf6\xad6\xa8\xca\x06|\xd9\xb0*\x1b\x02eU\xfb\xb8U\xfeV\x1bUt#\x9en\\\x95\x8d\xf9\xb2,\xe0\x10\xf5\xb7\xad\x96\xae\xbc\xd8\xad\x95\xd35\xb3\xff\xf1\xa0mX\x00\x93\xaaY\x83\xee`0\x18\x0c9d\x9e\xc7.0\xf9b\xbc}\x80?0.\x9aM\x13b/mJ!GmJ!_mJ!w%\xea\x85=\x96\x00@NKH\x06\xf9-Q\x0c\xb9nS\x0cz/Q\x0c90Q\x0c\xf90\xa1\x16\xc8\x8d\x9bb\xd0\x93\x9bb\xd0\x99\x9bb\xd0\x9f\x89b\xc8\xa5 \x9b@^\xdd\x14\xc3\x8eM\xdaD\xe0\xdb\xa4\xeaZ\xdd\x9bh\xab\xcc\xc3\x1bX\xee\xe4\n^\xae\x10\xc6\xe4\x01\x8a\xc4\xf3}\x99\xe3\xfb2\xbf\xf7en\xef\xb7x\xbd/uz_\xea\xf3\xbe\xd4\xe5}\xa9\xc7\xfbR\x87\xf7\xa5\xfe\xeeK\xdd\xdd\x97z\xbb/uv_\xea\xeb\xbe\xd4\xd5}\xa9\xa7\xfbrG\xf7[\xfd\xdc?\xc2\xcd}%/\xf7\xd5\x9d\x1c\xf6g,\xf3g,\xf3g,\xf3g,\xf3g\xdc\xe2\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xee\xcf\xb8\xd5\x9f\xf1\x11\xfe\x8c\x95\xfc\x19S\xfeL!\xc2\x0d\x8a\x178\xdcj\x1b/\xf1\xe6\x18\x1d\xaa\x07\xe7\xe5\x03\x01|\xe5\xb9.\n\x1at\xf1\xbb\x00\x9c8q\x88q\x03.~\x17\x80\xf3H\xaa\x86\xf2;\x1b5p\xc7\xc9\xac\xedZ\xa4\xde\xb1rk;\xb9\xe4;Vvm'\x97~G\xcb\xaf\xedd-\xd8\xf3-\xd8\xb7\xb4`\xcf\xb5`/o\xc1\x9ek\xc1^\xde\x82=\xd3\x82\xfdi\x01-\xebXY\xe8p\x94oQ\x04\n\xeeE\xe1[=\x8cB\xab8\x19I\xa0\xecg\x0c\x91\x92\xab14\n\xde\xc6P\xa88\x1cE\xa2\xeas\x0c\x91\x92\xdb14\n\x9e\xc7P(\xcc\xc1\xaa\x81&\xe7\x92\xfe\x91\x1e\xe9\x1f\xe7\x90\xfe1\xfe\xe8\x1f\xe9\x8e\xfe \xde\xe8\x1f\xef\x8c\xfe\xb1\xbe\xe8\x1f\xed\x8a\xfe \x9e\xe8\x1f\xef\x88\xfe\xb1~\xe8\x1f\xe9\x86*\x1e\x87\x8f\xf48|\x9c\xc7\x1d3\xc7\x92`%\x8f\xc3'x\x1c>\xde\xe3\x8e\x9dki\x02%\x8f\xc3'x\x1c>\xde\xe3\x8e\x9dsi\x02 XKR;\xf5\x9cCq\x055\xcc\xdf\x8d\x91\xb2\xb7Ob\x84\xf3;\xa2\x0d\xaazB\xe3\xecy\x12\xe2uJ\xe0\xaa'4\xae\xf8\xa8~\x0d\xca\x7fU\x18\x8e\x0f\x80\xe0\xd9\xc8\xae$;\x05\x94\x8bOA%-\xa0pE#\x14Z\xa10\xa9\x94M\xf3\x15[\xe6+7\xccWk\x97\x7f\\\xb3\xc4-\xc0\x8a-\xc0\xca-\xc0j-\xc0\\\x0b\xe8N\x92'r\xc3\xc8v\xbct\xcf\xbdu@\x1b7e\xdd1[8\"\n\xd9\xbb\xe9\xda\x90(d/\xc1k\x03\xa2\x90\xbdm\xafYD!{\xad_\xeb\x13\x85\xec\xfb\x034\x93(d_T\xa0\xf5\x88B\xf6\x8d\x08\x9aA\x14rJ\xd0\xad\xa6P\xe7$\xd2{d1{0\"\xd4\x1a\xce\xccy\xfb8L\xed\x14i}\x8b>o\xb0\x08c\xff\xbc(\xfb\xb1o\xb9h\xf9\xd3D\xf0\x1cd7\xd6\xc5\xec\xc6:\xcc\xaex\x0e\xb23L\x89x\x86)\x90\xaf,\x809\x8e$\x12\x1a#\x81\x88e\x01\xc8\xb1\xd7\x93\xc8\xd8\xeb d,\x0b`\x8eC\x89\x8c\xbd\xa1@\xc6\xb2\x00\xe4h\x1a\x12\x19MC cY\xa00\x96\x1e`\xd7\xd2\x88\x0f\x1c<\x8fwI9\x9e\xe6`R\x96\xa7\xfa\x98\x9c\xe9\x89n&ez\xaa\xa7\xc9\x99\x9e\xe8lR\xa6\xad\xfe\xa6\xe0p\n\x93w\xe3\x85\xfes;\xa1\x84\xe1\x89>(\xe1x\xb2\x0b\xcax\x9e\xea\x81\x12\x9e';\xa0\x8c\xe7\xa9\xfe'\xe1\xf9D\xf7\x93z\x1a~nO\x930<\xd1\xd3$\x1cO\xf64\x19\xcfS=M\xc2\xf3dO\x93\xf1<\xd5\xd3$<\xdb=\x8db:\xc7\xb6\xf3\x90EP\xf9y\xce\xf3x9\xb7\x7f\xd4\xcf\xb2?\xdd\xf1O\x10t\x04AG t\x08A\x87 t\x00A\x07 \xd4\x82\xa0\x16\x08\xedC\xd0>\x085!\xa8 B{\x10\xb4\x07B\x0d\x08j\x80P\xdd\x02\xa0:\xdb\xae\xed\xca+\x02\xde\x02\xbbJp\x8e}qf\xe8\xfa\x0b\xded\x05|$\x82\xb3f+\xe0C\x11\x9c5]\x01\x1f\x88\xe0\xac\xf9\n\xb8%\x82\xc3M\xed\x8b\xe0\xac\x19\x0b\xb8)\x82\xb3\xa6,\xe0=\x11\x9c5g\x017Dp\xd0\xa4%\xf6\xaf:{\x93:@v\xacQ\x10\xc3`V`\xae\x1d?h\xcb\xd8\xdeW\x08\xd3dVw\xbe\xe7R\x00\xcbb\x96ad\xe1p\xc8\xacG\x13\x0foP\\\x15s\xefB\xc3\xf95\x0b\x1ad\xdb6#A\x18\x06\x94\x08\x8e\xe3@lH\x08B\x08\xd0E\xae\xdd\n\xb2\xe8g\x7f\x00\xf5\xd7\x80\xc5\x02PV\x8c\xdc\xba\x92\xa1\xde\xd7\x19\x0cQ\xbcX\xf4\x0ds\x00IJ\x81\x86=\x8biN\x18\xdb\xc1\x92\x10c\xc0]\xe9_\x86\x98\xe00\xe7\xae\xd9\xef\x11\xc6\xe1\xb6Dd`H\n\n\xf4\xd7\xc5|a\xd8\x8cy\xa2u\x1c\xe1Z\x10\x0b\xf5\x1c\x9b\xbd\x9c\x90s\xa2qv\x7f`.z\x80\xea\"/\xa8=\xd1\xb5t}\xc4\xe8n\x15\xa6\x14&S\xe0\x9c\xb1\x10]>\xd2aW\xa0Q\xb6\xe9\x0eA\xb7G(\xa8{\x869\x1cZ=\xd6\xb3I\xc0\xd8\x1e\x0f\xfb\xb0\xdf\x11\xb01Bs\x87iW`o\xf6M'5\xe6\xfd> \xcd\x1c\xafQ\x03\xea\xf7\xc7\xec\xcb\n\x88r\xd3\x1a\"\x17\xb4)\x89\x1a\x0f\x1c\x87u\xe1\x1c\x85\x12\x1a\xe8\xb8\x88\x03n\xedd\x85\\\n\xb6\x18,\x16\x0b\x04\xc2(\x15\xa0\xd1\xc2]X \x8eq\xb9\xc5\xc2As\x10H\xf5\x10w\xe1ro'\xc3a\\_\xb1/\x80\xd5-AZkK\xad\x8e<\xe6\xb6\xf3\xb0,\xde\x91ZPH\x83\x90\x8ap\xd4B\xc8\x85$\x15\xe1\xb0\x85\x90\x0bP*\xc2A\x0b!\x17\xaeT\x84V\x0b!\x17\xbcT\x84\xfd\x16B.\x94\xa9\x08\xcd\x16B.\xb0\xa9\x08{-\x84\\\x98S\x11\x1a-\x84\xdc\x0cY\x11\xea\x96\x9c\x90\x0b\x81\xe6K\xad\x8e\x828\xca\xb6\x80\xa8&\x86\xdc\xa7-<\xaa\x89!\x17j\x0b\x96jb\xc8\x8d\xdaB\xa7\x9a\x18r\xa5\xb6@\xaa&\x86\xdc\xa9-\xac\xaa\x89!\x97j\x0b\xb2jb\xc8\xad\xdaB\xae\x9a\x18r\xad\xd6\x00\xact/\x9e\x92\x0f\xc7\xe6K\x8d\x88\xc8x\x02.8\x9b/\xb5&>\xe3\xf1\\\xa86_ju\xb4\xc6\xc3\xb9\xc0m\xbe\x14A\xb90n\xbe\xac\x824\x1e\xcc\x05u\xf3\xa5F\xc5u< \x17\xe2e\x92\xd7Q\x1e\x8f\xe7\x02\xbe\xba\n\x01\x01\x17\xfeU\xba/\x02<\x9e\x00\n\x06+\xc7\x80\xe0\xect9_\x16+\xe4\xc8\x8eQ\x90\xf2\x14D!l\xe3l\xc2\x03\xda\x01D\x98\xf3\xa5\x00\x0c\xc5\x9b\xb5\xa2D$|\xf49_je\x00\n\xe1\xf9X4s\xa3,\x1c\x85\xd0|d:_VA\x00\x87\xe7\xe3\xd4Zz\x11 \x18\xb5\xce\x97U@\nt\x02 \x86\xadk\x11RA\x11me\xb8<\xd4\xe4I\xa0\xf8v\xbe\xd4\xea\x10\x176\x1f\x1b\xedfM\x11\xa1\xf9\xd8\xb7i\x88\x88\x86\x8f\x84\x9b1&\x8b\xe0\x80A \x88\x8b\xf3\x81C\x00\x07\xa2d\xa2\xb3\xc2DP\xcc\x9cu\xd8,l\x86\xc6U>\x82\xaeZ\x91\x87\xab\x10 \x10O/Eh(\xba\xae\xdb \xa0\x81b\xed\x8a\xa6\x0e\xb7\x81\x81\x0d\x88\xbc\xb3a\x87\x08\xbe\x013\x02qxC$R2\x14\x957T\xe2\x0e\x06\xc4\xe8\x0d\x99hT\xe1#\xf6\xf9\xb2\x0e\xd79\x020r\xcf\xef\x97\x17s%t\x07\x9d,\xce\x7fn\xd6N\xec\xbb\xd7rd3\xf3\x8a\xb9\x11\x18\x8a%71\x17\xf0zn\x16sl \x14Cn\xe6.\xd0\xd5\xe4-\xe6W#(v\xdc\xcc^\x80\xe5\xacx6\xdc\xac_\x00\x8bY\\\xcc\xa8,\xa7Xq1A\x01%\xc3\x021C\nE\xb1\xe5\xe2\x86R+U\xe8 Q\\\x0d\xa1\x18r\x81\x05)\x81\x9c#\x81\xa1Xr\xa1\x07\xe1[y8\xd1\xe2\x7f\x05\x86b \x05'\x05E\x0bC\x88\x17;\xdc\x10\x1dI\x1b\xeb-]-C\x90\xecd+h\x92l\xd4\xcax$f\xcc.\x8fH\xb2a+\xe3\xa1\x981\xbbt\"\xc9\x06\xad\x8c\x07b\xc6\xec\xb2\x8a$\xb3Z\x19[b\xc6\xec\x92\x8b$\xeb\xb72\xee\x8b\x19\xb3\xcb1\x92\xcclel\x8a\x19\xb3K5\x92\xac\xd7\xca\xb8'f\xcc.\xe3H2\xa3\x95\xb1!f\xcc.\xf1\x88\xae$\xed 5\x82d\xdc\x96' Ie\x9d\xa4F\xc8\x98\xc3\x1d\xa5J%\xb41\x1f\xca\x99\xc3\x9d\xa5J5\xb41\x1f\xc8\x99\xc3\x1d\xa6JE\xb41\xb7\xe4\xcc\xe1NS\xa5*\xda\x98\xf7\xe5\xcc\xe1\x8eS\xa52\xda\x98\x9br\xe6p\xe7\xa9R\x1dm\xcc{r\xe6p\x07\xaaR!m\xcc\x0d9s\xb8\x13\x95\x81\x9e\x98w\x05 Y\xcb\xa2\xc3e[HW#\n\x8e\xd0\xd2\x00\x0c\x17\xa9\\\x8d\x94=\x174\x02\x8b\"8~$\xd3;\xd2*\xd8(\x12X\xb2\xc0\x01%\x91\x10\x92V\xc0\x84\x95\xc0\xb2\x19\x8e0\xcb\x0c\x92\x94\xb7\x94\xaf \xe4\xac\xd3MR\xceT\x84\x08,\xc9\xe0\x18\x94\xc9NIk\x00\"Q 9\x00\x07\xa5dJK\xae|&4\x05V\x89p\x94J%\xc1\x14\xda!\xadC\x10\xb6Ry\xb3\xf6~@\x06\x9c\xc0\xbaP\x18\xc7V\xa96i\x0d-\xcc\x05\x81-\x95\x98\x93\xf2'q\x82Z\x84i\xbc\x9a\x89B \xbddci\xae\x1a\x85\xb0z\xa9\x12Y/\xd9\xe0ZZ\x93 \xce^\xaa\x84\xdaK6\xda\x96\xd6$\x08\xbc\x97*\xb1\xf7\x92\x0d\xbf\xa55 \"\xf1\xa5J0\xbed\xe3qiM\x82\xd0|\xa9\x12\x9d/\xd9\x00]Z\x93 V_\xaa\x84\xebK6b\x97\xd6$\x08\xde\x97*\xf1\xfb\x92\x0d\xe1\xa55 \xa2\xf9\xa5J@\xbfdcziMpdBl\xf6\xb5\x8fA\x92\x9e\xab\x16\xef\x13\xbb\x83\n\xb5\x89{\xaf\xda\x02\x80\xd8NT\xa8M\xdc\x83\xd5V\x04\xc4\xfe\xa3Bm\xe2^\xac\xb6D 6,\x15j\x13\xf7d\xb55\x03\xb1\xc3\xa9P\x9b\xb87\xab-\"\x88-Q\x85\xda\xc4=ZmUA\xec\xa1*\xd4&\xee\xd5j\xcb\x0cb\xd3U\xa16q\xcfV[wT;l\xe2\xaajDQO\x15\x14\x01\xdbo\x05^\xca\x8c\xe3\x03\xed\xcc\x15\xd0zsN\xcc\xad\x810<\xf9\xad\xbb\x82\xa0\xd8\xbd\x133,\xcb\x19n\xfc\xc6^\x81^\x86X\"\\^\xcap\xe27\xfd\nl\xb1\xc7 \xe6U\x96\x93\xdc\xf8-AR'm\x0c)\x14-$\xb0mX\xd0\x14{\x80b\x9ee9\xc5\x0d\xdaT$%h\xe3I\xa1(\xce\xd0\xc6#\xe1\xb0\x91\xe0\x05\xbd,\x84\xe2 \x9f\xbc\xcb\x08\xaa\xcdI1\xcb\x1a\xc1\xb97\xbbsYjK\xca\x0d\xe2\xc4\xefjR:\x92\xf2#0\x0cW~\xdf\x93PQ\xbec\xd6\xa2\xc6\x02Cq\x85vF\xcbN!g\x08\xf1\x02\xb6M\xc96\xb5p$A\x14_hg\xb5 \xec\x8dd\xcd\x98\x97R\x9c\xa0]WB?s\xbc\x968x\x03ax\xf2\xdb\xb2\x05\x81\x9c\x1d\xcf \xda\xb2%U#\xe7G`h\xed\x01\x9b\xba\x04E\xb5\xaf\xdb\xc2\xb8\x86Q\xbc\xa1\x9d\xdf\x82\x88\xd8\xfc\x15s&A\xb4\xaf\x03\x9b\xc3\x14I\x8b+Q(\x8a3\xb4\x81L\xd1\xb4\x0d\xc74\x8c\x96\x1a\xd8e\xa6\x88\xa43$\x81a\xb8\xf2\xfb\xd0\xa5\x07-\x15b\x02\x12T\xf0\x05\xd2&\xc2\x08\xa18\xa6#\xe5.c,\x0e\x19\xc8#=R\xf6l\xe0\x00U\"\x8a!\xeaC@\xd2\x1a\xa8H\x02b/\n*\xca3CR\xe6Dh\x01\xb1\x16E\x19\xf5\x01#)s\xca 9\xf6\xa2\xb0\x839\x8f\xa4\xa0}y=\x928\xa4>\xc4$\xad\x84\x8a\x19x\xf6\xe2\xc0\x849\xf3\xa4\xd0\x92\x96\xaa\xc4\x91\nyP\xaa\xbd\xb3\x11\xb37_\x898t!\x8eVI\xeb`\x02\x18\xb8\xdf\xc1\xb1Ly\x16Kn\x0f9kQpC\x1d\xdcR\xb1\x85\xbc\x1aQ\xb4C\x9d\xf5j7\x059\x07\xf0\xd5\x88\xc3\x9f\xeax\x98\xbcw\xcb\x99\x0b\xe3!\xfa0\x99\x82\xae\xe4\x15\x89\x03\xa4\xf2\x00\x9a\xb4\x06\"L\xe2Y\x8b#&\xf2\xb4Z\xbb\x19\x889\x1e\xaaD\x18B-\xdb\xf9KY\x8bc*\xea0\x9c\x82 \xa4\xd5\x88\x83,\xf6\xfc\\{ML\xa8\xc5W&\x8e\xba\xe8Sw\xd2\xaa\xf8\xd8\x0b\xe8\x84\xc20\x8c9\xa9\xa7R\x93\xdc\x85\xc5q\x19{\xbcO\xa5\xae\xb6 K\x18\xa8Q\x87\x02Uj\x92\x07&\x92\xc8\xadu\x17\x99\xc0\x08*\x00\xf7\x94#[?\x08\xbe\xdf\x1a\xd9F]\xd4\xedY\xdc{j#\xbb\xd7\x94C\xc5f]\xcc\xbfY7\xb2\xfbu)\xffj\xdd\xc8\xb6\xeaR\xfe\xdd\xba\x91=\xa8K\xf9\x97\xebF\xf6\xb0\xa9\x97\x7f\xbbn\x84\xeb\x06k\x18-R\xae\xd5\xd8\xa0\xcb\xc1\xa6\xe3\x1e\x03\x820&\x8d\x01\x94\x80\xfb4\x04\xd0\x04\xb6h\x08\xa0\x0e<\xa0!\x80N\xf0\x90\x91\x05PL\xdc(&\xce\x06\x16N3\xb1\xc1\x00@\xd5\xc4=\x16\x05\x81L\x06\x04('\xee3\x18@;\xb1\xc5`\x00\xf5\xc4\x03\x06\x03\xe8'\x1e\xb2\xf2\x00\n\x9a7\n\x9a\x87i\x1a\xfa\x9c\x86\xe6\x06\x8b\x00U4\xefq0\x08e\xb2(@I\xf3>\x0b\x02\xb44\xb7X\x10\xa0\xa6\xf9\x80\x05\x01z\x9a\x0f9\x99\x00E\xa5\x8d\xa2\xd20\xe2\xb4\x94\x1aT1\xa8\xa2\xb4Gc \x88IA\x00\xe5\xa4}\n\x01h&\xb5(\x04\xa0\x96t@!\x00\x9d\xa4CZ\x0e@!\x1bF!\x93\x16?\xda@\x1ab\x89@\xbdm\x00\xbdq\x84\x10\x1d\xafL\x96\x0cP\xf0\x86W0K\x05(}\xc3+\x9d\xa5\x02\x0c\xb1\xe1\x0d\xc1R\x01\xc6\xd9\x00\xc6\xe1\x1a\x06Xl\xc5\xce\x125\x11<6\xae\xc0Y\x83!\x02-\xb6\x82\xa6\x12\x96\x10\xa2\x03\xa6\x17\x86\x0c\xb0\xd8\n\x98q\x18*\xc0b+`\x12b\xa8\x00\x8b\xad\x80y\x89\xa1\x02,\xb6\x82\xa6*\xb6a\xc0\xc7\x85l\xfd\xe0\xdb\xf1\xd2\x0bX\xdb\xf8\xb6Q\x95@\x06\xf0\xed^]\x0c\x95\x9aU)\xf0\x95'\xbb_\x15\x02\x9fU\xb2\xad\xaa\x10\xf8Z\x92=\xa8\n\x81\xaf-\xd9\xc3\xbaN\xa0\xa1\xb8j(\x18\xbf\xf8\xd8\xa0\x8a\xc1&\xe3\x1e\x8d\x81 &\x05\x01\x1a\x8f\xfb\x14\x02\xd0\x00\xb6(\x04\xa0\x06<\xa0\x10\x80.\xf0\x90\x96\x03PH\\+\x04\xec\x9b~l\xd0\xe5\xa0J\xe2\x1e\x03\x820&\x8d\x01\x94\x12\xf7i\x08\xa0\x95\xd8\xa2!\x80Z\xe2\x01\x0d\x01\xf4\x12\x0f\x19Y\x00\xc5\xcck\xc5\xc0\xf3\x8c?7\x18\x00\xa8\x9ay\x8fEA \x93\x01\x01\xca\x99\xf7\x19\x0c\xa0\x9d\xb9\xc5`\x00\xf5\xcc\x07\x0c\x06\xd0\xcf|\xc8\xca\x03((\xad\x15\x04\xc4)~j\x90\xa5\xa0j\xd2\x1e\x05\x81\x10&\x89\x00\x94\x92\xf6I\x00\xa0\x91\xd4\"\x01\x80:\xd2\x01 \x00t\x91\x0e)\x19\x00ElhEL\xe4n\xb3\x01\x143Qp\xa4\x0d\xaf-\x96\x0c\xa2\xe248i\xf5\xb4\x0d\xa7\xd4I\xab\xe7m8=OZ=q\xc3\xa9~\xd2\xea\x99\x1b\xde\x1al\x83\x00\x0b\xad\x98Q\xbf\"\x81\x87\xbc\x154 \xd0$\xa0\x85V\xc0\xc4\xc0\x90AT\xfc\\A\x13\x01\x16Z\xf1\xb3\x07M\x03Xh\xc5\xcf'4\x0d`\xa1\x15?\xc3\xd04\x80\x85V\xc0\x9c\xc34(\xb7P\xfb[-\xe9\xd7\nFv\xfer\xce2\x96\x01\xf2-d\xa9 \xe5BA \x84I\"\xc0\xc4\x0b \x00s/$\x00L\xbf\x90\x000\x03C\xc9\x00&a\x08\x84(\x0f\xc3A\x04\xa9\x18\x1e\x07\xc1L\x0e\x06&d8\x14\x98\x93\xe1P`Z\x86C\x81\x99\x19^.09C\xc2D\xf9\x19\x1e#H\xd1\x00@\x08g\xf280Q\xc3\xc3\xc0\\\x0d\x0f\x03\xd35<\x0c\xcc\xd8\x00\xb2\x81I\x1b\x12'\xcc\xdb\x00 A\xea\x06BB@\x13\x00\x82 \x1c\x00\x07\xe6p\x00\x1c\x98\xc6\x01p`&\x07\x92\x0fL\xe6\x90@8\x9f\xc3\"\x04)\x1d\x0e\x06\xa1L\x16\x05&vX\x10\x98\xdbaA`z\x87\x05\x81\x19\x1eN&0\xc9\xc3)\xaa=\xcf\x03kN1\xd5\x03\xeaS-\xdb\x03)Y)\xe1\x03)^)\xe7\x03\x19C)\xed\x03\x19H)\xf3\x03\x1aM-\xf9C\x92*\xe6\x7f8\x92cR@<1D\x0b\x91\xc2\xd3\x9aJ\"\x88#T\xcd\x05q\x84\xaa\xe9 \x8eP5#\xc4\xb7Q9)\xa4\xe5\xdfs\x8f\xe1\xbc\x10Q(H\x0d\x91\x08\x08`\x12\x000AD\x94\x839\"\xa2\x1cL\x13\x11\xe5`\xa6\x88\xac\x1fL\x165\x00Q\xbe\x88E\x08RF\x1c\x0cB\x99,\nL\x1c\xb1 0w\xc4\x82\xc0\xf4\x11\x0b\x023H\x9cL`\x12\x89@\x89\xf2H\x1cD\x90J\xe2q\x10\xcc\xe4``B\x89C\x819%\x0e\x05\xa6\x958\x14\x98Y\xe2\xe5\x02\x93K\x04L\x98_\xe21\x82\x14\x13\x00\x84p&\x8f\x03\x13M<\x0c\xcc5\xf100\xdd\xc4\xc3\xc0\x8c\x13 \x1b\x98t\"pp\xde\x89\x01\x08RO,\n\x02\x99\x0c\x08L@1\x180\x07\xc5`\xc04\x14\x83\x013Q\xac<`2\x8aUPk>\nT\x98ZJ\n\xd2\xa2RV\n\xd0\xacJb\nP\xb6Jn\n\xd0\xbfJz\n0\x89J\x86\n\xb2\x92R\x92\x8a T\xcbS\xb1\x04G\xa4\xaa8R\x80\x12\"\x04\xe7(\x85\x84\x15K\xa6\x98\xb3b\xc9\x14\xd3V,\x99b\xe6\x8ak\x9b(y\xa5\x90\xbdR\xf8&Kd\xeb\x9a_\xc5fPF\xab)\x14%\xb4\x08\x04\x040 \x00\x9c\xcej\xca\xe1lVS\x0e'\xb3\x9ar8\x97E\xd4\x0f\xa7\xb2|f\xad\xc0\"\x0c\x16!Jd\xb10\x08e\xb2(8\x8d\xe5\xf3\xb1=\x0b\xb2X\x10\x9c\xc4\xf2\xf9\x98\x9d\x05\x0d9\x99\xe0\x14V\x83\x12f\xb0X\x88(\x81\xc5\xe1 \x98\xc9\xc1\xe0\xf4\x15\x8b\x82\xb3W,\nN^\xb1(8w\xc5\xc9\x05\xa7\xae\x1a\x988s\xc5aD\x89+\x1e\x08\xe1L\x1e\x07\xa7\xad8\x18\x9c\xb5\xe2`p\xd2\x8a\x83\xc19+^68e\xd5\xe0\x04\x19+\x1a JX1(\x08d2 8]Ec\xe0l\x15\x8d\x81\x93U4\x06\xceU1\xf2\xc0\xa9*FA\n\x99*Hc\xaa\x89*@\x8f\x8ay*^\xb9ji*^\xe1jY*\xde\x08jI*\xde0j9*\xc0X\x8a)\xaa\x86R5C\xc5P\x1c\x95\xa0bi!R\x88\x12\x9c\xae\x94\xd2S\x0c\x9drv\x8a\xa1SNN1t\xca\xb9)\xb6}\xea\xa9)\xbf\x8c\xd4\xa0\xccT]&JL5\x00\xa8\xdcl\xca\xe1\xb4T]\x0cg\xa5\xeab8)U\x17\xc39\xa9\xa6n8%\xe5\xd3k\x04\x16`0\x00QB\xca\xe7\xc3\x7f\x16d2 8\x1d\xe5sq=\x8b\xb1\x18\x0c\x9c\x8c\xf2\xb9\x88\x9d\xc5\x0cYy\xe0TT\x0d\x12f\xa2\x18\x84(\x11\xc5\xc2 \x94\xc9\xa2\xe04\x14\x03\x82\xb3P\x0c\x08NB1 8\x07\xc5\xca\x04\xa7\xa0j\x948\x03\xc5BD (\x0e\x07\xc1L\x0e\x06\xa7\x9fX\x14\x9c}bQp\xf2\x89E\xc1\xb9'N.8\xf5T\xc3\x04\x99'\xaa\\\x94x\xa2A\x10\xc6\xa41p\xda\x89\x82\xc0Y'\n\x02'\x9d(\x08\x9cs\xa2e\x81SN\xb4b\xda3N\x80\xa2\x14\x13N\xbc\xf6\xd4\xf2M\x9cF\x95\xd2M\x9c\x92\x95\xb2M\x9c\xde\x95\x92M\x9c)\x94rM\xbcu\xd4RM5\x9db\xa6\x89\xc6\x1f\x93hb(\x01B\x88\x0e\x9a{T\xd2L4\x95j\x96\x89\xa6RM2\xd1T\xaa9&\xa6]\xa7\xa5\x98\x04\xd9$\\\x85SP6\xa9)\x14e\x93\x08\x04\x040 \x00\x9cMj\xca\xe1lRS\x0eg\x93\x9ar8\x9bD\xd4\x0fg\x930\x13\xd7\xb3\x08\x83E\x88\xb2I,\x0cB\x99,\n\xce&a>\x16gA\x16\x0b\x82\xb3I\x98\x8f\xb2Y\xd0\x90\x93 \xce&5(a6\x89\x85\x88\xb2I\x1c\x0e\x82\x99\x1c\x0c\xce&\xb1(8\x9b\xc4\xa2\xe0l\x12\x8b\x82\xb3I\x9c\\p6\xa9\x81\x89\xb3I\x1cF\x94M\xe2\x81\x10\xce\xe4qp6\x89\x83\xc1\xd9$\x0e\x06g\x938\x18\x9cM\xe2e\x83\xb3I\x0dN\x90M\xa2\x01\xa2l\x12\x83\x82@&\x03\x82\xb3I4\x06\xce&\xd1\x188\x9bDc\xe0l\x12#\x0f\x9cMb\x14\xa4\x90M\x824\xa6\x9aM\x02\xf4\xa8\x98M\xe2\x95\xab\x96M\xe2\x15\xae\x96M\xe2\x8d\xa0\x96M\xe2\x0d\xa3\x96M\x02\x8c\xa5\x98Mj(U\xb3I\x0c\xc5Q\xd9$\x96\x16\"\x85(\xc1\xe9J)\x9b\xc4\xd0)g\x93\x18:\xe5l\x12C\xa7\x9cMb\xdb\xa7\x9eM\xc2eP\x06e\x93\xea2Q6\xa9\x01@\xe5fS\x0eg\x93\xeab8\x9bT\x17\xc3\xd9\xa4\xba\x18\xce&5u\xc3\xd9$L\xaf\x03X\x80\xc1\x00D\xd9$\xcc\x07\xf9,\xc8d@p6 s\xf1;\x8b\xb1\x18\x0c\x9cM\xc2\\l\xceb\x86\xac{U\x1fl?w\x15\x1fV\x00w\x17\x1f\xd4\x00w\x19\x1fR\x01w\x1b\x1f\xd2\x01w\x1d\x1fR\x02w\x1f\x1f\xd2\x02w!\x1fT\x03}\xe7\x1e\xd6\x01}\xe9\x1eT\x00}\xeb\x1ej=}\xed\x1ej:}\xef\x1ej7}\xf1\x1ej4}\xf3\xbelq\xfb\xc1\xcb\x033f\x90\x17UD\xa3\x1d\x05\x01\x07<\x12\x01\x8ey$\x00\x1c\xf6H\x008\xf2\x91\x00p\xf0\xa3d\x00\xc7?\xf6\x00\xabh\x08\xe4q\xe0(\xc8\xc1\xc0\x81\x90C\x81c!\x87\x02\x87C\x0e\x05\x8e\x88\xbc\\\xe0\xa0H\xc0\xe4\xe3\"\x00\x04\x87F\x1e\x07\x8e\x8e<\x0c\x1c y\x188F\xf20p\x98\x04d\x03GJ\x02\xd72XBHp\xbc\x04\x80\xe0\x90 \xe0\xc0Q\x13\xc0\x81\x03'\x80\x03\xc7NH>p\xf8$\x80\xb2\x11\x94\x83\x81\x83(\x8b\x02\xc7Q\x16\x04\x0e\xa5,\x08\x1cMY\x108\xa0r2)l5\xaa\x9ef\x0f\xc8\x83W\xc2\x81\x96@\xc0\xe3l\x03\x80\x87\xd9\xa6\x1c\x1ee\x9brx\x90m\xca\xe11\x96\xa8\x1f\x1eb\xe9\xfd[\xe1\x08\xcb\xc2\xe0\x01\x96A\xc1\xe3+\x03\x82\x87W\x06\x04\x8f\xae\x0c\x08\x1e\\Y\x99\xe0\xb1\xd5gF\x1b\xd1\xd0\xca\xe1\xe0\x91\x95\x85\xc1\x03+\x8b\x82\xc7U\x16\x05\x0f\xab,\n\x1eU9\xb9\xe0A\xd5g\x07\x18\xd1\x98\xca\x03\xe1!\x95\xc3\xc1#*\x07\x83\x07T\x0e\x06\x8f\xa7\x1c\x0c\x1eNy\xd9\xe0\xd1\xd4\xa7\xc6\x1a\xd1`\xca\xa0\xe0\xb1\x94\x06\xc1C)\x8d\x81GR\x1a\x03\x0f\xa44\x06\x1eG\x19y\x14\x86Q\xc1\x88\x89\xeb\xe1F4b\x12\x08x\xc4l\x00\xf0\x88\xd9\x94\xc3#fS\x0e\x8f\x98M9\x96\xdc\xca\x05\xfajr\xc1\xa8\x10\xa6\x95C\xdb7\x12Kf\xae\x1d?\xb4\xf2\x92}I5\xe3\xf3\x80\x0e)\xda\xa5\x9a\x8b\x9c0\xb6S/\x0c\xce\xb1\x17 -]\xc5\xe1z\xb9\xa2 \xd6\x81\x8b\xe2\xac\x98\xa3\xa9K\x18\xc7\x0b51M\x10\x06Ha\xe9s\x00d\xce\xd6Q'\x88\x0d\x91)H\x0e\x91\xe5\xc2+H\xaf\xb0p+\x9b\xe4\x9f\xd4\"\x9eJ\xa5A<\x95B{\xc4\xa2\xe3\x93D\xe7\xa9TD\xe7\xa9\n\xd1)\x8a\xb4D\xd9\xd8[\x06\xe7YT\xc0\x94\xc7dy>Q2\x00\x87\x048(HQ\xac`\xed\x03#E\xed9bA\x18\x08(\x0b\x83)\xc5Q\x90G\xc1\xfbR\\y\x83DF\xbf]D\xffh aaZ-G#`a0$\x0c\x0d\xaa,\x9c\x7f!~\x11\xc6\xfe\xb9cG^jc\xef\x11\xb1P\xccBq\xb8E\xb1c'\x1cr\xcd\"\xd7Q\x04#\x03\x16y\xd2p\x98\x12\xce\xa1\xd4\x12\x00-n\x0c\x00\x16\xb7\x07\x00+\x0c*\xcan\xda\xb8\x98Z;9\xb0\xa4\x99\x1cV\xd2J\x0e\xab\xd0HA{8\xb7\x92\xb5\xe7\x08\x1f\xe4\xb1\x92\xf6pX`8]h\x833\xe6\xc1\n\xd9n>\xab/\xc2 \x8b\xf5\x1e\xd19\x1fR/4\x8b\xa5K\xd6s\x80\x94\x0f\xa1\x17\x06Ql\xf2\xc5=\xa2\xb8\x07\x05\xea\x0b\x93@\x18@\x90\xbe\xe8S\x00\x88\x85E\"\xf8\xe2\x01Q\xdc\x1d\x0d\x01\x06C\x12Q\x00\xda{\xc3\x81\xd5\xbd\x16$\"\xf5g\x9d\xae\xc5\x02\x005a\x04\x9a\x01d\x07\x1a\x01\x99\x82F\x08\xacA\x83`\x83\xb0\x18\xd0&\x0c\x080\x0b\x8d\x10X\x86\x01\x15\x18\x05\xeb(\x8cU\x99\xc9|\xa1\xc5\xfcV\x83q\xb4\xa4\xbd\xfc6s\xf9m\xd6\xf2\x15\x8c\xe5\xb7\xdb\xcaW0\x95\xdff)_\xc1P\xfe\xb1v\x12\x98\x04\x0bM\x82[M\xc2\xd1\x92&\xc1m&\xc1m&\xc1\n&\xc1\xed&\xc1\n&\xc1m&\xc1\n&\xc1\x80I(\x8c\x8f\xecd\x1d\xa3C\xd3O\xb2\xce\x03b\xb2r\n\xd8\x17\x01\x03;\x8e\xc3-\x01\xedq<\xbd\xc0EAZLi\xc5\xcf\xe7Fs\"+m?\xcf\x98\xf86\xc6\x9acG\xe5\xe8\xb0\xb1c\xcf\x0e\xd2\xf3\xe69\x8dO\xe3u\xe0\xd8):\xe4\xc9\x81<5\x82\xce\x83p\x1b\xdb\xd1$\xdc\xa0x\x91\x7f\x9c\xcfs]\x14Lr\xa9\xea\x87\x08c/J\xbcDa\xcc9\xc0\xeaH\x94\xd5\xcb`[4L\xa3EJ\xae\xe3\xbd'\xea\xb9\x1e\x88UU\x9d\x11\x9c\xaem\x05u+\x0c\xf1\x95\xc2|u\x13\xf8\xc7X\xc0W1\x80\xff<\xfa\xf7\x8fT\xbf\xff\xdd\xb4/Q4VW4>F\xd1XE\xd1\xf8y\x14\x8d\x8fT4~\x8a\xa2)\x96U\xb9\xe6\x84Aj{\x01\x8a\x0f\xf5\xa3\xfdy\xe2\xc4!\xc64E\xb1h\xa6\xb7\x12\xecu\x1aN\xc8\x9d\x96\xec\x01\xa3\xddX\xcb\x1e\xf2t\x0c\x0cS\xb0\x86Y{\xe7<\x00bj\xec\xd9\x1buIARPX\x8d9\xf4\x94\x03\x15\x04V\x18M\xcaV\xf8'7\x02\xa0\x84\xdb\xe0\x1f\xdb\x04\xb1\xb4\xf8di\x01JXZ\x0cHK\x8b\x82\xbd\xe8\x10\x85\x89\x97'\x02\x17\xde\x0e\xb9\xff\xd7\xf3\xa30N\xed \x9d\xfcQ\x97\xd8\xf3$\xc4\xeb\x14\x11\x85\x19\xe9y\x8c\x9c\xf4G#\xdau\x88\xbf?\xd1Eg\xc4\xdf\x9f\x14\xcc}\xe0\x04\xcc\x1c\xe7\xcf\x94QAH\x15\x9f\xcc$\xf7\xff\x83\x04\x17\xc9\x88\xff\\\x19)\x01\xb6\x89\x16\x84\xb1o\xb3#u\xf6\x88F\x16\xa370\xa0\xd3\xb0(\xa6#\xc9(>>'X\x0b\xc5\x07J\"\xb9\xe0\x90\x8a\x13\x8d\x85e\xd2)\x88\xa7\xe0m\x8d\xcclt!\x14\x19\nCx\x89\xfd#\x05\x96\xca\xa6jfp\xe6\xe6e\xc3\xbcl\x14f\xa3\xcd\xed\x04\x1d6(N=\xc7\xc6e:;{\xc6\xef\x91l4\xdfsY\xa8\xef\xb9.\xe6\x80i\x18\xb1\xc04\x8c\xb8\xaaS\x9f\xab9\x0fp\x14\x0c~\x00\x9a\x91\xf9\x8ezK\x00\xb4\xb01\x00\x16n\x0f$B\xd1$\x856)8q\xd9P^o\x92vr`q39\xa8\xa0\x95\"\xbb\x1d\xed\xf8e{\xf01\xed\xe1\xc0\xe2\xf6pPA{\xf8\xfa\xcb\xf6PX\xd7\xf3\x0fad;^\xba?7\xb8\xa23\xf6\x01\xf41\xfa\xecq\xf1\xfdym\x8b\xe6\x0f^\x99\x15/f\x90\x92w\xa7kXI\x07ez\xf1\x82IK9'\x86\xbc\xd6J\xfc\xae\xc5\x13\xdaN\xeamP\x03\x19M\x94d\x0c\xd7\xa9\\\xc8p\xcd\xec\x9e-q\xb8=\xe3\x9e@\x82\xe7\xcf\xbf\xa3\xbe\x14\xea\x15\x18|\x95-\x03\xf3S\x11\x9dn\xfe\x9f\x1a\xa8\xab\xa9\xedXQ\x9b\nKC\x95\xf5\x9e\x89Py\xb3\xda@y\x1b\xd9\x16\x18\xdf\xa7\x05\xcd\x06{^+\xa4w\x16R\x98 _\x7f\xb6\xef\xe1/\xe3p{\xd0\xfc\xf0Q\x0b\x93\x9dVd\x0f\xfd0LW^\xb0<_\xc6\xf6>ql\x8c\xea\xb6\xcdm\xe7aa;H\xdbx\x897\xf7p\xd6\xf2r\xc1+)\xa24\x93of\xe5?a;E\xdf~\xd4\x7f\x9a\x88\x9e\x03\x1a\xe5Xu\xba=A\xa7:\x02z:\xe4\xac\xa5\x16^\xdb`\xd7\x89\xe1.\x9b\xeb$\xb7\xc0\x8fFW\xb7HM\x11O\x81:\xcaaI\xc4\xac;\xe6Yu\xc7\x00#\x0d\xdb\xf1\x12\xfd\x7f\xc5A\xbc\xe0\x18\x1f\xe1\xd1OEI\x9d\xa5\x80\x88L \xf2\x9a\xb2\xb4\xcdwz\x90\xeb\xf4\x84\x06o\xf7\x1f\xc0\x17\xb3\x87L0\x1dzAZ\x8fH\xce:N\xc2\xf8\xbc|H#\x93\x95\xed\x86[\x0d\x02N\xea\xc5b\x8c\xb0\x9d\x89\x05\x99\xdd\xc6\xb8\xd3\xb5\x92\x8e\xb3\x9e{\x8e6G\x8f\x1e\x8a\x7f\xec\x1a\x03\xeb\xac;\xea\x9fu\xfb\xfd3\xe3\xa7\xc9\x91x\xb1\x88\xe7\xf6\"\xcd\x04\x0d\x83\x14\x05\xe9\xf9_\xfe\xd2\xf8\x7f\xb8\xd3\n\xe4\xb9\xde\xd1;\xc6 \xdauz\xd1\xaeC\x9e\xf7\xeb\xfd4Q\x86\xe5\x07;c\xdb\xf5\xd6\xc9\xb9\x17\xacP\xec\xa5\x93f\xd2\xe4\xd6\xd1\x93\"\xf3\x99\xe7e\xf4I\x11A\x1a\xba\xfeb\xb2ByN'\xff\xf91\xcf\x98\xee\xce5\xf9\x9cu\x846Ui$\x1a\xcd\xfd\xbb\xd0\xeb\x99\x18Ej_\x10d\xcc\x97\x9a\x1dx\xbe\x9d\xa23\xc1s\xa8/\x11\xa5\xc2\xd0\x89=\xc4IM\xdb\xec(\xd0\n\xa6\xa5~\xd4\xf4Ce\x17\x9d-2\xea\"\x83-\xea\xd5E=\xb6\xc8\xac\x8bL\xb6\xa8_\x17\xf5\xd9\"\xab.\xb2\xd8\xa2\xf1x\\\x17\x8e\xc7c\xa0\x98*\xe7\x00\xbe\xbdk\xa45\xfa\xc3\xfe\xc8\x1c\xf4\x87,\xaa\xf4\xf2\x1aY\xfe\xce\xc3\xbc\xd4\xb3q\x0d\xe3\xb3\x95\x8f\xda:HP\xc3(\xff\x8d\x86\x04(IQf\xa0h\xaf\x15\x11T\xdeM:!\xb3\xaf,\xc2Ej\xb05>\x10\xbf\x9e\x1b\xecB\xa2\xa4k6\xae \xda\x95\x01\xd6\x01c{G`\xcd#\xb0\xfd#\xb0\xd6\x11\xd8\x01\xa3\x17\xe8`\x7fA\x8f\xbd$\xd5b\x94 \xa1q\x08\xc4\x9a{\xf1\x1c\x99\xaf\xd6'94I\xf7\x18i\xe9>B\xc5\xd1*\xa1%\x8b\xed\xa5N\xf4sDm7u\x8f\xdbo\"9&(B\xb1\x9d\x86q\xce\x94\xe0at-A\xfb=\x7f\xd9\xf1\xfc\xe5\x81\x18\xd2\x9b\x9cG\xfe\xab\xeb%\x11\xb6\xf7\xe7s\x1c:\x0f\x02\x1d\x06\x0fI\xc7>\x94\xe7\xe1Mk\x88\\\x17\x9a\x02\xf8\x01k\"-\x95\xd5\x06\x0d\xb6\x0c\xa2\x9c\xf5\x0b\xa9\xc6\x03\xc7Y,\x9e_\xaamlG\x11\x8a\x05\n\xec\x0f\xf4hW\x1a\xf0\\\xef\xe4\x9b&\xa5\x0b\x9d\xeb\x9d^VH\xcd\xf0\xdecVRN\xcf\xf3p7\x01\x9f\xd2\x12\x84Qn\x1a-\xb5\x97Z\x82\x9cL\xeaCe4\x82ymH\xcdO\xb4\x05F;\xf2Y\xf6;%I\x18{\x993V\x99\x18\xaa\xcc\xf5\xe2\xa2\x9a2%:\xa98\x12%N\x88\xd7~0\x01\x9f\n\xc5\x7f\xba\xd8\xe4 \xe0F,\xeai\xfe\x8b\xe6\xa5\xc8O\xaaG\x95E\x0c=\x0b\x97\xb2\x7f\x8c\xea\x9f \x134\x8aB\xc4^\xc2E\x81\xbddR\x9b,\xef\xb9F\xb4\xeb$!\xf6\xdc\"\x1c\xb3\xc6g\x03\xebld\x9cu\xcd\x9f\x84*)\x9d\xb8\x99\xf5\xa9\x1b\x1e:\x1bj\x93\xca$\x8e\x18\xf5I'\xd4;V\xb4\x9b\xe4\xa5\x0b\xdb\xf7\xf0\xfe<\xb1\x83DKP\xec-&U\x1f\x9e\xf7\x0d\xcb\x10\xf2\xee\x06\xa1\xe6\xa2\xc4\xe9$\x91\x1d\x1cH\x03d\xfa>7j\xd5\x9f\x1b\x93\xe2?BV\x9dd\xb3\x84\x82\xa2\\\x85}^\xab\xfdD\xc2\xca\xb71u\xde\xa9_5t[\xcc\x04}]\x9f\xa8HK\xf4\xd1\xdc \x8eWVd\xc7\xb6\x8fR\x14\xff\xf1G6\x15\x90B\xf5\xa2]\xcd\xdf\x8av\x1d\x9db\xef\x87A\x98o\x10P\x82\x0ft]V\xdb\xc6C[\xad\x9a\x06\x1f\x0e\xfc\xca&\x9b\x04\xcch7\xa9\x0e>\x90\xfe`\xa9{\xb9\xc5\xdb\xc3\x82\xedq \xdc\xcd\xc8j(\xba\x02\xd1\x07\xfe\xaa\xeb:\xb3\x10\xe9\xb3\xc3a\xb3\x921\x99E\x8c1\xe6\x16;\x00\x04\x14\xad\xd3M\xedy\x1e8\xa0\xf8\xe9#\xceQ\x0eOV]\xfc\x9c\x8dC\x87\xc6\xdb\xfa\xfc\x90s\x04\xa3\xf3\x85\x17'\xa9\x16.\xf2\xf0\x83a\xdb\xd1;\xfa\x11\xbc\xbaebs\xd5/:9\xe7S\xa7\xf3*\xd7Y\xfc\"\xb3\xbe\xad\x999L\x1eSY\xfa\x8bj\xb5\xd9kV\x9b\x99\x9f\x00kd \x9b\xf3\xfb\x8f\x9a\xa5\xbf\x00\x13=U\x111\xb4.c{\x0f6\xab\xeb%Z\x18\xa1\xa0\x19n\x92\xb5\xef\xdb\xf1\xfe \x1a\xe13\xef\x16h\xa8fQL\x8a\x95'V\xd6\x1a\x95s\xd0\xc4\xf7\x82*\x82\xb5\xb2\xdf A\xd9\x1b\x83\xa3\x9f\xe0~c\x00\xcb\x7f\x83\xe980\xe6(\xd9\xcf\x8e\x01w\xb0=G\xf8\xe9\x1d\xef\xa4\xa9\xfe\xa8f\x95\x922C79,\x0fu\xbd\x1eG\xb9\xc30'\xcc\x1aJ\x02\x95\xfd\x91\x9a\xa1$\x9d[\xc0j\xd5g'J\x95Q\xadi\xeds4\xae\xe8C\x9a\x8f\xd2U\xe8\xca\xe6\xed\\\xcf\xf5\xd6\xe5H'f\xd0A\x16\xa8e\xe3\x05w\x03\x8c\x99\\L\xba\x0b\xe5\xd3ONC\xf5\x04\x9d\xed+\xf2v.\x16\x0b\xc5F\x86\xf9\xd2,3\x80\xe7\xb6\xf5\x97\x92$\xb2\xd3\xd5\x11\xd0?\xfepQ\x14#\xc7N\x11\xa5\xccAD\xf4\xacS{[n~\xbdq\x08\xbdc\x16\xab\x19\xfa\xb7'w\xd0\xc96\x8c]m\x1e#\xfb\xe1<\xffW\xb31\x96\x85c\xaa\xf1R\xb9\x19N\xec\xe8\x0f\x07\xa3h\xc7l\x81\xff\x07\x9a\xaf\x17\xed\xd8\xd3\x9d\xcal\xd8\xcd:,\xbc\xa6\xab\xd4p\xa6\x8b*r\xc8\x16\n\xb1\x17\xe5\xebR\x82\x81\xa9:\xe4<\xdfH\xf3?4\xe9\x90\xd1\xbeZp\xc7\xc8\xad\x18\xe0\xf7\xea\x00\x9f\x98\x95\x9e=\xb2\xe7\xa4\xab\xf6\xad\x19\x19\xcb\xb0m\xc4,5\xe0\xf8\xaab\x19\x85IJ\xbc\x8f\"3p\x7f\xec8c}\xc2\xae\x80\x87\xe6YO\xef\x9f\x19\xfd\xbe0\\\xa1\xb8\n\xa7\x1drN(\xea:\x81\x19(\xb3\n\x1f\xf5p\xf9h9\xd7\xac&\x17\x8em\x98\xbc&{V\xef\xcc\x18\x18g\xfd\x91\x82&\xd7j\x8a,\xaa:\x9e\x17(\xb1\x02\x9b\xd3\xd4\xa8\xc2\xdeE\x18\xa5\x88\x95kl\"\x13\xf1\x9a\xec\x8f\xcf\x06\xbd\xec\xff\xad\x8a,\xd8\xaa\xe92\xaf\xec$v\xa0\xd8j\x9cN\xd4\xa8B\x0dK\xc4:\xe6\xc0\xb0\x17\x0b^\x9d\xe3\xe1\x991\xb4\xcez\x96B\x17_\"5\xc7,\xaa:\x9e\x17(\xb1\x02\x9b\xd3\xd4\xa8\xc2>\xb2Sg\xc5\x88e\xe9\xc8tz\x9c\"G\xfaY\xaf7<3\xc6\n\x8a\xcc\xd9*\xa9\xb2\xa8\xec\x14n\xa0\xd4J\x8cNS\xa7J\x05\x19WF\xae\xb1n\xf4\x00\xb7\xcc\xa6\x1cc\xa4\xe6\x96\x19W%e\x16u\x9d\xc0\x0c\x94Y\x85\xcfi\xaaT\xe1\x1f\xe6\xb1^\xc2H\xa6\xbb\x96m\x0fym\x9agc\xfd\xcc\x18\x0c\xdb\x95Y\xf2U\xd2gQ\xdbi\xfc@\xc1\x15Y\x9d\xa6U\x95*\x88\xb0\xbe>\x15:\x98\xd0\xa2\xa2y\xf6\x07\xce\x14\x8d{\xc0\xab\xa5\xc4\x95(i\xb9\xa8\xefd\x96\x07Hzun\xa7\xe9ZR\x0b!\xa0\xb3B>J\xb8\xa4\x9c\x1aY\xa7[\xfe\xa0\xa5^\x8aQk\xaef\xe1\xe14kD\xb3\xd6*\x9eh^\x90Eq\xd4\xd6b\x1eI\xe7{T:\xb5oU%\xd8{M\n\xd2\x1d\xb9.b\xbc*\xb5\xe7\xa7\xad\x82\xa8\x9a\x8bex\xdd,b\xe3\x1b\xd8\xf3N\xedy\x07{l\x1a\x8d<\x89N\xf1b\x16,\xc7\xaf\xfe\x8a\xfa\xd8\\8\xb7bbv\xf2\x99\xcf\x96\xf5X[C\\\x85\x89\xecb\xdf\xbe`5\xa8WeF\xb4\xa3\xceK\x11)l\xc1\xfe\x1e\xbb\xbdW\x08Q\xfa\xf8\x81\xc9\x90\x81\xbeI\xae\xbe\xb5r\xaf\x1aLJhh\x97\xa28\xb0\xb1\xe6\x86N\"\x87\xe6^\xfdGy\x13\x8a\xb5+\xbd\xcdX\xbb\xa8U\xa5\xb5\x8f7\xa8\xa4)\xdc\x11\x12ik\x84h\xb2ALf\x14h\xd3\xf3\xb6 :\xa6\x01\x020%\x7f\xc4fR\x9f\x9e\xb3\x15\xaa\x939\x0fC\x13\xa3\x1dr\xd6)\xaa\xe0\xf50\x98\xbb\x81\xfc\x9d^\x0ci\xa7;O\x03r\x1c$\xc7\xe5>7.\xcfCw\xaf\xe5;\xb0u,r\xd2\x98\xf7?s \x82\x97\x9ez\x86\\/=P'\x16\xf4V\xfab#\x83T\x9a\"M'A\x189i\xb5\x9bkB\xb3W\x8c\x92(\x0c\x12\x94h^\x100f\x96\"\xb9\xee\xc8\x95[\x82\x9eXN\xa3\xa7u\xc6\xaa\x96,\xec\xf8#I\xedt\x9d\x80{\x0fOeJ<\\\x07n\xe8\xac}\x140\xb9]\xe3\xd8d\xf6X\xcf\xfeH\xaa\xce\xcf>1\x9f\x0f\xcd\xcf\x93UY\xef\xbe\x8e\xfc\xc9\xf36\xb78o\xf5?\xd1Zb<\xfd\xe3\x8f\xc2g\\o\xd3\xf5\xed\xf8\xc1\x0d\xb7\x01\xec]2\xca\x18\x05.\x8a\x91;+9\x80\x9b\x7fE\xa0\x93\xbf\xb9\xcd\xa1\x8f\xc75C-\x10\x9a\x91\xa7\x1c\xa8d\x9e\xd1\xef\xf7\xd1q\x9a\xe1\xf6\x9dT\x1aW\xa9\x85\x9dEThY\xc5t\xa2\x038\xad|g\xc9\xedg\x90\xdc>\x1c%\xf0h<_\xe8\xfd\x89\xe2\xbd'\x15\x89\x9a\xd6\x14\xa9\xf3\xe7h\x13}\xd8qd\xcc\x0d\xddy\x82d\xec\xce\x95\n1'T\xba:N\xd3\x8b\xc5BxbN\xb8\xd3\xaaeSW\xf3\x1b\x0e\xed|\xe4+\x0e\xdd\x93G!\xa9\x0ej6gl\x9b\xfd\xfa\x96\xb7TP\x15F1w\xa6\x0b\xee\xfb\xcc\x95\xef<\xa2)69\xb3\x9f\xca=\xce\xecwx\xe7\x93{\x98C\xab\xe0c\xb5\x8fV(H\n\xf1\xb3\xa0\x83z@\xfd\xa24\x06\xd5/\x89ae;\xd6\x8er\xcd\x15'\x18\x1at\xf3\x96\x86\x16\xban\xb1\xdc\xcf\xba\xddAr.y\xe5-W\xc5{\xc0\x9d\xd0\x05\xd6~2\xf4\xdf\xbb\xbe\xe7\xc4a\xfe\x80|iN\xe9!\xbb\xeaHN_g\xce\xe8\x0c\xd8\x13\xd6Y\x1f\xc8\xdcQ+\xd7y\x89\xf8\xc4S\xee)\xe5\xca\x138tJZj\xe8\x8ezc\x138\xed@n2\xf2\xc6&\x0d\xf8\xd1K=\x8c\xbd\xb5\xdf\xf9\x82\xe6g\xc4\x84/\xe9\x97L\xc4P\xb6\xd9\xd4\xeb\xc5\xed\x90\xdb\xdb+r \xc4+\x88\x88eT\x8f\\\xf3\x9bE6\x83\xdaG \x8ej\x83\xa7\x95\x98s\x1a\x96\xe0P\x13\x07\x93\x8bX'n\x9e\xbe^8i\xa7XQ\xba\xbf+\x1dLzr\x13\xbe\xe7\x92\xa7\x1a-\xb5\xe2\xb8\xb5U,,N\x88D[\x94T/`\xeat\x93a\xd6\xcb\xcf\xe6T\xa0\xe0\x85\xb9\xd5l\xd2\xf8p\xe5\xb3\xe5\x89J\xe2x\x7fq\xd1\"\x9bW\x9a1\xc1x\x8e\xa37\x91\xed\xbc_'\xa9\xb7\xd8W\xe3L\x8d}\xaa7\xfei\xce\xd0\xa2\xf4\xfaQ\xdbH.\xa6,3uD\x8f\xd1\x81\x1e\x03'\xf2,\xfdEs\x18\xb5\xce\xd9\x95\x8c\xa5\xa7O\xf3\x13\xa6g\xc2\x13\xa8T\xb1\xc0\x1fO\xe8\x11\x12-\xcc\xd1\"\x8c\x91 aI\xb5\x93\x8e\x9a\x88Dm5\xdb\x11G\xc8\xb5\xbcG\x01\x07r\xeb \xec<\x0e\xd3\xfc\x87\x8e\x91t\xbc`\xe1\x05^\x8a:\xd94n\xc7g\xc4%\xcf\xc9\xf1\x14\xcd{\x12\xb8\x04x\xb1\xf7i\x9d\x15\xff/\x0e\xbe\xe6\xf3b\x1aF\xe5\x9e\x039;\x0c\xd8{\xb1y\xa6\xa9\xf6\xf3S.\xa0\xff\xfb\xbf*\xf2\x07\xb4_\xc4\xb6\x8f\x92N\xd5\xb0C\x1a\x02\xf7\xa0\xf3R\xf4\xa3\x91\xae\xe3\x80t\x1a\xea\xf9\xbf\xff\xfd_\xcf\xccO\x14\xec\xe7&\xa5N\x93W\xc3\x9c\x02I7\xfb%\x0eq\xa2\xd9\x8e\x83\xa2\xb4\xda\xac)\x87dj\xf3g\x19#\x14<\x85g~\xf5\x83\xe0ED,\xdd!\xf2!K\xcc\xb1\x17<\xa0\xf8`\xe9/\x9a\x17\x86P\xba\x15 H1\xcbc\xb5\x9d\x95y8\xba\xab\xda\xdd \xcc\x93 u\xb8\xe1\x05\xdc\x92\xb2\x06\x9d\x81O\xcf3\xa7\x83\xce\xfaU\xb7\xba\x8b\xea\xeb\xdf$\xc7\xcf6(N\xbc0\xd0\xa2\xd8^\xfa\xf6\x81\xdc\xaa\xa8\x83K\xe4\xb3\xe9?\x9a\xea\x8f?|\x94$\xf6\x12==\x82:u\xde#\xe5&\x06\xfcn\x0f\xf9@\xd8\xcc\\\xa0E>q\xd8\xb4\xcb\xc5\xf4\x82\xc6\xfe\xdd\xf56\xc4\x8bE-\xcbY)\x9dmTb\xde\xc9\x171Mt\\m\x97\xba(\xfbS\x8b\xdb\x8fv\x9d~\x11\xf6\xb2\x8bN\xba\x9ay\x1a\xb4\x9d\xb5&\xaf'\xf5\xc8\x83\x9a\xec\x19A\x93?6h&\xfcH\xbc\x8c\xed\xbd|\x05\x9as\x89\xec\x18\x05\xe9s_e8a\n\x9d\xa7A\xf6WK|\xd1\xc5\xad~\xa9\x19\x8e\xee\x9f\xae\x97\xd8s\x8c\xdc\x7fU\xef\x9b\x08\xc2\xcc\xe5p\xb8En=[uM\x8e\x90y?\x00s\xb9\xc9b\x9aer\xd7\x9fx\x04\xdf&\xc7\x0e\x1c\x84\xd9Sa\x8b\x81> \x97_e\x01i\x12\xb9\n\x0b\x0e|u\xf6:]\x85\xb1\xf7\x88\xe8\xeb\xd8\x13z\xb4\xab\xb8T\x07=\xe5\xa7?y\xe1$\xf5\x16\x89\x86\x05\x0e\xed4\xff\xb6\x0cm>p/\x9e\xa1\xdf,\x0f\x0b\x0fc\xf8\xc8e\x86-w\xaa\x80\xfe\xd9\x1f\x8fu\xd4\x03\x92[T9\xc7Q\xcb\xb8D\xa7\x0d\x9f\xe4\x8aZ\xc0\xb8\xe8\xff\xc7\x0fN4\x83r\x1f\xbcxU\x15\xd7\xb13\xadv\xb8\x03\xe2\x0c\x07l\x0b\x18\xe4\xa4\xf9_F\xdd\x95Y\xec\"\xf3\x98\xb5\x83\xb9\x18P\x0e\x0e\xca\xa2\xd3\\3\x0f\x95s\xce}\x98\xb8\xf7Y\xf6B~w\x8ef\xcc\xa8V\x06-\x0f\x80\x13}E\xcf\xfe\xb4\x89-\xbc\xf5\x0bO*\x05\xeb\xa1\x9e\xfd\xa1X\xcf\xd7i\x1a\x06\xec\xdb}\xc2u\x9a\x0d.\xbc\x02\x0bx\xd7\x0b66\xf6\xdc\x03\xbfVIV\xf6\x03\xeat\xfbI\xc7\x98\xc0O\xdb\x0e\x03\xffu\x81\xb83Fe\xd0{\xc4\xc4\x9b\xa7\x18\xac\xea\x1e:\x7f\xbc\xa7\xcc\xd9\xca\x13\xbb\x8ba\xf6\xa7\xb3\x8e\xf1\x8f\xae\x9d\xda\xe7\x9eo/\xd1\xcbd\xb3\xfcy\xe7\xe3\xc9\xdcN\xd0\xa0\x7f\xf6\xdb\xaf7\xbdo\xfb\x8b\xfe\xfc\xcbn\xed<\xea\x9e\xfd\xeb\x9d\xee\\\x86\x9bw\xa6k\xba{\xcb\x9c\xed\xad\x8d\xe3;\x9b\xd9\xfdt;{5~t}\xc7\xbb\xfe\xf5[\xf4\xedw\xf7\xd5\xdc\\\x8e\xaf\xef\xa7\xcb\xd9\xab\xe9\xbe\xf8{\xfd\xf3\xf5\xab\xe9\xf2\xfar\xb7\xfd\xfa\xfb]x\xfd\xe6v|\xfd\xa0\xeff\xfb\xbe>\xfb\xb8\\\xde\xec\xfb\xfd\x9b\x8f\xf8\xfe\xdd\xfd\xb59\xfb\xa0\xafg\xf7_\xfb\xef\xee\x9d\xed\xfb\xfa\xe7\x07\xf3\xfd\xab\xe9\xf6\xfaU\x7f\x7f\xb3\xef\xefo\xee\x97\xeb\xd9\xbd\xb3\xcf0\xb3\x0f\xf9s\xeb\xe6\x1e'\xef>\xce\xd6\xef?N\xfb\xd7\x97\xb3\xf5\xfb\xcb\x9b\xfbw\x1fj|\x9aa\x9b\x9f\x1f\xcc\xf7\x1f\xa6\xdb\xf9+\xfd\xf1\xdd\xfd\xc3\xf6}\xfe\xdf\xe5\xe3\xd7}V\x9f\x93\xbe\xbb\xbf\xee\xdd\xd4?\x17u\xbc\xfb\x90\xd5\xf1\x90=\xdb\xe5|\xef\x97\xeb\x9b\xc7\xa9U\xfd\xfc\xfe\xa3\xd3\xbf\xbe\xbc\x98\xcd>N\x97\xb3\x8f\xaf\x93\xb2m\xe9l\xdf\xdf\xdd\\\xbe\x1e\\{\xa3\x9f\x7f+\xf4\xf4\xf3O\x9d<\xaf[\x9c\xfc*b\xceN\x10j1\x8a\x90\x9d\x92\xf3ZqS\x9f{#\x84<\xa3\xd9SK|f0\x95(\xa8Y\xb9G\x11\xb2\xe3,Z(F\xa4\xfcEm\xecC\xe6w\xc0\xdd\xff\xe9\xafq\xeaE\x18\xfd\xabJ\xfeZ\xd4\xc15\x0b\xf4V\x80\xd1\x9f\xde]\xe9\xbd\x07.\x89\xd8\xcbg\xd8\xa3\xee\x94 8\x19#\x9d\xbd\xe0\xa5\x94\xdd}\xea\x99\xa4\xfch\xe1?\xb3%\xf5/\xc8\xb7=\xfc\xaf3A\xe9\xc2\xc3HX\x18\xd9I\xb2\x0dcW\x08H\x90\x1d;+aq\xb6\x1e\xa3\x0b\xb3'v\x8clRE:\x91l\xa2\x1dh\xc4\x0c\x8f\xc4\x86\xa1;\xce\xfe\xb4\x0d\x8f\x8b\x85\x9a\x15\xff\xf3\xd5\xd5\xbct&\xdf\x8a\x91\x1b\xbb\xeaO\xd2V\xb4\x81\xea\xd6\xb4\x01\xcbV\xb5\xc1\xf2\xd6\x81\xa0\xaa\x95\x7f\xca0\x00d\x8ar6\x07C\x7fq6\xd6_\x00Y\xb6:\xa5k\xba?jF\xb4\xcbF]0\xe5K\x96\xff\xbb\xa7\xbf8\x1b\xb5\xf2\xeb\xc9\xd9U\xc5\xff6\xf5\x17g\x96\xfe\xe2l\xd8\xcaQ\xeb\xb7HX\x95\xff\xbb\xaf\xbf8\x1b\xb4\xf2kaWs#3k\xff\xab\xd1g\xd1(8\x1403\x07y|\xbc\xd9\x9a\xeaQ\xb7\xe8\xf9\xd5\x137l\x92\x01u\xcb\xbb(\x8e:-\x00\xccMUK\x8aw|\x1d\xf8\xd0\x17\xb8\x1fU\x0f\x11\xce:\xe6\x0f%\x13[r\xe4d\xc2\x9c\xd5\x88QN\"P\xc0\xb3\x9f\xd9rV\xc8y\x98\x87\xbb\x03\x19\xf5\x97+Y`mD\xeez\x08\x1eW*\xd5\xb3?peOx\xfd\x86\x80aD\x1dD\xef\xeb:\xf1\xd1\x8d\xc2\x0e\xe4y\xb9J\xf3,HU\x8bP\xba\xae\x16\x85\x98L\xaag\xff\xaa\x9b\xca/\xa5\xa5t?\xe7\x8a\xfa{\xb7xC\x8f\xf0\x8dJt.K#\xf7\xcb\xf27/Tn7 \xcf\x91\x8f\xca\xedn2\x0ef\xcf|\xd0[Q\x8c\xff\xa1Q\xf6G\xf4\xb2$=_\x02T i!\x97\x08\"\xde\xf1\x90\xf7\x83\xfa\xa7\x13U\xd7\xfe\xca_\x85WFKk;\xcf\x7fB.e0^Y\xf9\x1a\xf8/\xc0\"\xd8Y\xd9q\x82\xd2_\xd6\xe9B\x1b\x9d\xbd0_%\x9be'\xb7\xe0/?\x18\xfa\x0f\x9d\xc2\x82\xbf\xfc0\xfa\xa1\xb3\xf1\xd0\xf6\"\xdc\xfd\xf2\x83\xd9\x19v\x0c\xbd3\xfa\xa1\xb3\xf3q\x90\xfc\xf2\xc3*M\xa3\xf3\x97/\xb7\xdbmwkv\xc3x\xf9\xb2\xa7\xebzV\xc7\x0f/\xcc\xab\x17\xe6\xab\xc8NW\x9d\x85\x87\xf1/?\xbc\xe8\x99}\xa3?\xec_\xfd\x90?\xd0\xe25F\xbf\xfc\x806(\x08]\xf7\x87\x8e\xfb\xcb\x0f\xb3A\xd74\xcd\x8ea\xbd3;\x86\xd1\x1d\x0c\x86\xd8\xc8\x9eh\xd9\xbf\xfdN\xaf\xd3{W<\xce\xc40;\xa3\xac\xec\xf1\x87\x97EMY\xa5/\xcc\xab\xbf\xfc\xd4\xb1\xf4\x17\xcdZ\x93\xd6\xa8\xeb\xd98\\j\xeb\x1d\xf35\x9d \xf9\xa2U\xea\x1e\x8b^\x1dV\xaa^\x03,`\xd8\xe9f\xbaw\xe30\x02\xb8K\x19\x8an\xc1\x8c~\x12V\xe5\x87\xae\x8d\xa9z\xea-m\xae!\xd4\xfe63)\x16\xbf\x9a\xe5\xdcP\x7f\xf3\xc3\xe2\x86\xe2\x937\xf8\xf9\x05JuY\xafm\x81\"\xc8\x07\xe8\xd1\xaeS\x9c\x9c\x92\xbe\x04Z\x8ckUj\xb5\xb1&;\x06g\xf5\xc90\x82O*J\xd8\xd2\x17U\x80{6U\x9e\x9c\x9fk\x95V\xb8\xd2\xba\xe9K>#f\x81=h\x16\xd8O8\x9a\x04\xd5\xff\x94\xd7\xce\xd5\xb1J\xaf8/':*[:\x16\xe96'\x9d\xffQmM\xa7\xeb\xe00AZ\xfe\xf8\x88\x94\xfc\xf3e\x9bd\xc2\xad\xc8\x0f\x83\xf7\xd8c?\x03\xf2\x0d^\x8d\xe8\\\x1eN\xb4Ir\x82[\xf8\xa1+O\xef\x98\xfa\x91g\xea\x85\xb5t\xba\xc4}\xd9$\xb2\x99\x1b\x11<&u\xabc\xb9\xb6\x9e\xfd\x11\x9d\xcc\xe5(\xff\x9e\xba\xcc\x8dK\xf5w\x0f\xe5\xcc\xb44\\.1b\x8fh\xc1\x81\xd7@\x14x\x95\xa6\xccF\xa9N\xd7D\xbe\xc2\xebo\xb8\xe1]\xf8*`u\xe4\xa9\x08\xe8C\x0e$\x03~**\xcf\xf1\x8cu\x17-\x81\xf3=\xe5s\x8eN\x0bc/\xcf\xa6\xe9/\xb2(a\"*\x10\x1b\xaa\xeb\x84\x18\xdbQ\x82\\\xf1\xa9#\x81P\xf9c1\xe7\xf2\xac\x1et\x02\x8d\xdd\xc0\x12\\\xa1=*\xd2k\x0f\xe0\xaa`\xb0\xd7o\x82\xc1\xec\xe7:\x1a\xcc\x83\xea~\xa7\xd7'c\xbd,\x8c3\xf4\xce\xe0\xdd\xa8k\x8d;\xc3n\xdf\xe8\x18f\xd7\x18v\x8c\x1e\xd6\xfa]k\xd4\xe9w\xad\xf1;C\xef\x18#<\xd0\x06m\xf1\x1b\xb7W\x90\x05/\x90\x16\xef\xd7~\xa4\xa5a\xfe60`\xe1\";\x01\xc43\x10\xbfz\x8a:;\xa8u\xfb\\g\x03-\\\xdc\x87\x97\x1f\xe3$\xa0\xd5\xbb\xa5\x8aG+/H\x0f\xc4!\xbb\xfcG\xf6cc\x04T \xab\xd1\x1d!\x7f\xc2\x9f\xe3\xab\x86\xff\xae\x81\xfcN~\x14\x08\xf8\x1eo9<\xaa\x04od\xb85\x84\x1c\x9e\xb8D\x95\xad\xfb\x99\xc3F\xe5\xc9\xb2\x02\x9a\xd4W0ub\xf2\x97\xbdR\x9a\x97M\xc2\xbdz\xc1)1{\xeb\xfc\x0b\x0f`\x9a,\x96b\"7Qh\"\x7f\xef5\xcd\x9e \xd1\x9e\xe5-\x86'\x85Ap\xb2\xe8Y\xdf\x13.\x0f\"\x06:w\xbc\x86S\xd5\x13_\xa3\x0d\xf0;\xe9\xcd\xde\x1c\x9f\xe3\xde_\xce\x92[\xac\x07\x90\xddEo\xdd\xf6\x02\x0e\x0b05\xa8\x0d\x99\xf9\xeaQ\xda\x17*F\xc0e\x97\xfa\x82\xc3Q\x1f\x1c\x02\xde\xc6\xa7>\xd8\xb0\xdf\xeej\x91\xb5\xc5F\xc3\xe3\x98\xd1Q \xf1\xda\x90\xa3\xb8\xe4\xa7\x83\x18&\xad#\x12\xc7\xa6|\x90\x08\x0cLM\x0b\xa3\xfa\nVf\xab\xe6\x15;\x96B\x85\xf3pw\x90\x1e\xdai`T\xc2\x19\x8ca\x95\xcd\xcc\xbe\xcc\xa7\xae\xe4\x08\xb7\xe6Ni\xd5L\xba\xd0\x0b\x87,\xf1\xa4\xce\xf4Ty\xcf\xb4\xf4\xec\x0f\xc4\xac\xa9U\xdb\xdaq\xe0\x05K\x903\xb7|\xab^\xdcR\xddn\x17\x1fV\xe4_Q\x97\x8du\x7f\xcf\xfe)\xa7\xe5\xee<\xb6\x1d\xa4\xe5\xabZjF\x84\xceBEq\x18i\x81\xed\xb3\x87\xb8\xa9\x15I#\x1d@\x9c\xfbx\xa5\x18\xcb\x06\x10(X\xfb\xb2\x0b\x8f9(\x0b\xb1\xed\xf4 \x9e4\xba \x8a7(\x16\\\x1f{\xb6\x0bYd%\xa2\xebW\xf47f@\x06\x9dU\xbf[\x9d%\xaf\xee\x1e\x94\x01E\x8fUcE\x92\xdas\x8c:i\xf55\x16So\x01\xba\"\x9b\xd5\xd2eQ \xf8\x85\xdb u\x1f\x82H\x82i\xc4\x9dNy\xe5\xf0\xeb\xfaKWik\xa3\xdb\xe1^\x0eE\x1c|\x87I\xbbN\xe8G\xeb\xack\xadc\\\x0f\xcd\xfc\x91~\x10_\x1cC\x07\xf5E\x9c\xaa\x9d\x88&l\xce\xf5\x978\x9c\xdbX+\xea\xfa\x8f\xbe%*\x90\xb4\xd6S9\x00\x92g\x9c{\xd50$~=S\xf5\xaa/\xc0\xdd\xcb1C\xe0\xed\xb9\x03@/\xc3\xa12nZ\xb5>?\xaf~\xe0\x99\x94\xc3]\x9a\x9fLJ\xe3\xac?\xd4\xbcX\xafg?\xd6,`\xc0\xf8tu\"\xa5O\xbe\xe2\xab\xd8\x84\x82ZU\xde\xefN2IZ\x12dp\xa7|j\xda\xac\xec\\\x80B\xaa7\xb7)\xe9E\xa2\x91fl\xe9Q{\x0f\x03\xe2\xe6 \xf0V\x9f\x92m\xfe\xea\xc6\x9c\xed\x99\xact\xd5vz\x8cI%\x13\xd7b\xf2c\xf2\x8a\xeb\xb7\x9e\xda\xa9Bf\xae\xaa\xbe\x8c\x93\xb0/\x93\xe0\xce\x02\xc1\x1f\xd52\xf9\x17>Ix\xd2\x97\xcdJ\x86B\xfa?\xfe\xc8grI\xc4\xd1\xd7O\x99\x14\x99\n\xba1\xfa\xef\xb5\x17W\xaf\xc7\x11\x0d\x12\"*\xf86+\x1c\xe0i\x03\xfasCM\xca\xac\xe2\xf6\x97R\xf0\xf2e\xd0V1\n\x0e\xd8o\xae6\xb2\xa0]\x8a\x82\xc4\x0b\x99l2\x81\xf0\x14^\x9csLW\xe5?\xccBT&|m\xfe\x13+\x8d\x91+V\x81\x1f\xa5\xfb?66^\xa3?\xf8\xc4\xb5ID\x03\xe5\xda\x91\x8b\x0e\xb8\x17\x0cJ\xb9\x97\x93=\x15L\x0e\x8f\xe2\xd0\xad\xee%5\xc1<\xffjH\x8c\x80\xab\xee\xfc\xa6^\x1aFs\x9b\xfeb\x0dpE\xa7|s\x0eDZ\xfd\x17~\xcd`\x89\xb1O\xdb%{r\xbe\x07\x14\x98:U\x95\xe7\x06\xd9!U%WB\x8eb\xf9^3\xbbIR\x1c\xb9\x90\xaf_\xd8cD\x95\x84E\xca\x06\xd8\xcc\xe2#\xd1\xca\n\xf5+J\xd61\xae_\xd3\xf7d\xad\xe7m5\x9b\xd6\x9b\x93\xea \x01\xca/r\xa2\xc0e\xaevfO\xd8{\x9dy)\n\\\xf56\xb4\xcc$\xa5\x86\xf8seV\x7f\xb8\x80\xbeJV]h\x12\xdf*\x91\x8b\xd3-f!\xed\xf4\xb3WOw\xeb 8\x99\x0e\xa8\xe3p\xa76\xa9\xbcgG\xcf\x9aJ\x1d\x82\xf6\xd2<\xc0\x92\xbf\x19\xf2\x18\xa1\x8a\xa9\x9f\x93\xa3\xd7\xc8\xd1\x9b\x94\xff!\x94#t\x0b\xea\x04$\xb0\xee(\xcf\x0dR\xbf\x1f#<\xf5\xb4\xbc\xd5$\x89D\xc88\xae_\x1e\xf2\x90\x9c\xe1$\xae\xd5Q\x8b\xa8\xb2qG\x0e:^\xb0\x08\xeb;\x1d\xc0K(\xb3\xf2\xce*\xbf\xee\xd7\xf5m/`\x97urt\x87=\xc4\n\xc0\xb1w\xc6?\x8c\x80g\xc5z\x89\xe0w\xda+\x0f\x0b\x19\x0d\xa0\x02\xf6\xf3\xc8\xc5C\x13z\xd8\x87\x1eZ\xc7\xbf9\xa0\xa0,\xdenU\xad\x8f\x8b\xdbb\xea\xe9C\xdd:\xf2\xa4.\xf4\xee\xf7\\\x0e\x9b\xd5\xeeQ\x1b\x11-\xb6\x80\xae\xc9\x16\xb5\xd2\xef\xbc3\x16\x83\xb1\x03xay7\x9f\xdc\x9f\x02\x98u\xe7v\x824\xe0\xe80\xa9\x0b\x93:\xdbZ\xcf#G)Qh\xcc.\x9bF5\x07O{w/\xc1\x95\xff2\xaad\xc1`\xb5\x1c\xae(\xd6\xef\xe4\xcb\x9d{\xc5\xc0\xc2.\x8d\x93u\xc4\x1dd\xb5\x86\xcc\x01\xb7\xa1;\xea\x8f!\xf3\x92\x92\xe7\xaf\xdbST\x057T\xd9\xebt\xa5\xcd\xd3\xe0i\x01\x0e\xbd6\x7f\x8e\x17U\xc8\xa5,\xeeK\xbba\x80\x0e\xf2\x14rN\xf8\xa4\xa6)M\xd4\xcf\x1a\xbb\x912w\x88\xd7\x040)\xd0&4\xd1\x9a\x97\xe3\x01\x9c\xc0\xe4\xa1\xc1\xdeo(\xd2\x89-\xa7\xe6d\xdc\xe1M)a\x1dl8E3#v\xcd\xcbc\xffV\xb4\x13\x1d\xb7bH\xeb\x8f\x8e\xf3\xc1\xbe\x94\xae\xf5&\x9a\x84\xa0\x08\xa3\xd9\x1b\x90R)Q\x1c\x87q\xc2\x0e\xa8\xd4\x06\x18?Y=y0M\x9c0BIg\xd5{\xfa\x94\x9f\xb3\xd2\\\xb4\x90\x1f\x8b(\x1b\xaa1V\xe9\xc1\x0eXu$\xe2\x92\x9acc\xf4)b^\x80E>\xe5C\xd2\xea\xfaZ\xebd/\xf9&\x15-v\xf9;\xdb\nx\xd3\x0b$e\x8fl\x08\xdf=\x7f\x92]\x05U&\xc4\x8b\x9f\xc0M/\x86\xae\x882\x9f>P\x9e\xb4\x06S\x90\x8c\xd6a\x8f\xba\xac\xa44P+\xb99t\xc7\xb1\xf0\xb7\x03x9\xad\xbc\x971\x02\xeej\x8c~\x9a4\xaf\xc6\x02\xdfAV\x00\x0d\x9e\xd6hH\x0d\xfav\xe0\xff\xb4,\x94\x9d\xee\xf2kaq\xb7\no\x9aTZ\xe5\x1d\xf9J\xef\xff\xbc\xfc\xdb_;I\xb8\x8e\x1d4\xb3\xa3\xc8\x0b\x96\x9f\xee\xde\xfd\xd20\xea:I\xd2\xf5\xed\xe8o/\xff\x7f\x01\x00\x00\xff\xffPK\x07\x08_;\x94/\xe8Y\x00\x00\xa8X\x02\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00 \x00swagger.yamlUT\x05\x00\x01\x80Cm8\xec}\xe9r\xe3\xb6\xd6\xe0\x7f?\x05J\x99\x9aN*\xb1-\xc9\x92l\xb9&3\xe5\xb5\xdb\xe9\xf1\x8d\xd3v:\xf7\xe6\x8f\x1a\"!\n\x16 \xd0\x04\xa8\xc5\xa9T\xcds\xcc\x9fy\xc5y\x84\xaf\x08p\x01I\x90\")\xc9q/\xfa\xbe\xcauK8\x07\xc0\xd9\xcf\xc1\xb6\xbf\xbf\xbf\xc7\x16\xd0\xb2\x90w\nZ\xdd\x83vk\x0f\x93 =\xdd\x03`\x8e<\x86)9\x05\xad\xa3\xe0k\x008\xe66:\x05o!\x86\xfb\xff\x1bs\x04&\xd4\x03\x17\x949\x94\xed\x01`\"fx\xd8\xe5\x02\xe4\x0c|\xb8\xba\x7f\x00\x98p\xe4M\xa0!\x9b2\x0e9\x02O>\xf20b?\x01\xeeA\xc2\xa0\x11\x00\x00\x0b\x11\xe4A\xf1'$&\x18{\x14\x9a\x06d\x1c\x13\xeb`\x8fC\x8b\x05\x03\xda\x07\x04:\xe8\x14<$\x80A\xc7\x99\xae\xef\x11\xf4\x8c\xe9O\x00\x11\x83\x9a\xe8'@\xbd\x04\x9d\xda';PQ\"b\"\xcf\xc1\x84\x83\x0fw\x17y\xa4\xca\xefgw7\xec'\xc0|c\n \x13\xb3Y\x81\xb1M\x8dYzJLLd\x0emlBN=\x86\xb8\xd2\xdd\x99\xcf\xa7\xf9N\x82o\x11\xe1\xd8\x08\xc8\x04\x0d\x83\xfa\x843\x05\xea\x1c\x92Y\x1e\xea\xc2C\xa2\xbdJ\xb6\xd4@\x14\x0c\xf7\x1c\xce0\xb14D\xe3p\x86\x80CM\xdfFb\x86\n\xd0[:G\x1e\x81\xc4@y\xb8\xe4\xb7\x02\xe0{\x1b\xb2\xa9\xbe\xcb\xf0\x97\x02\xc0K\xcc\xb8\x87\xc7~\xd08\x0f|\x8d\x100\x95\x16E\xbd\xfb\xaek\xaf4}\x8b\xef\x0b\x80B\xb9W\xbe\xb9\xc5\x84\xe7\x91\x04\xdf\x16\x8f\xff\x163#\x0f\xf3\x9b\x10\x17\xe8\xbaq/\xcc\x98\"\x07\x85\xf2=\xe5\xdce{S\xca\xf8i\xa0-\x9e\x059:0\x84\x86\x1d\x10\xc4\x17\xd4\x9b\xed1d\xf8\x1e\xe6\xabK4\xc1\x04\x0b\x0e\x07\xc03G\xfc\x0f\x00|\xe5\xa2S0\x86\x0c\x1b{.\xe4S\xf1\xf5!\xa1&\x1aE\x9a\x0d\x80\x85\xb8\xfc#3\xbe\x1b2\xa1\x9e\x13*\xe2\x98\xfa\x1c\xf0)\x02\x06%\x04\x19\x1c\x99 @\x13\xc21\xdfq\xa0\xb7:\x05\x0fS\x04\\\x8f\xba\xc8\xe3\x181@'\xc50\x91&\xcb\xcf\xbeN\xed@\x80\xcb\xf4\x0d\x94j\x08]\xd7\x0e\xf4\x02Sr\xf8\xc8B\x89\x00\xc0C\xcc\xa5\x84\xa9m\xbb\xedv\xf2\x8f\xcc\xec\xfeEM$\xac\x90\xcf\x94&\x82\x03P\x05\x8a\x88H\xc7\x8f\xc8\xe0\xa9\x1f\x92\x89\xa6\x01\x80:\xc4Qd:3M\xca\xc0\x83\xcf\xd8\xc7\xb69J\x13I\xfd\xc8Q\x05R\x1f*T\xfac\xd8\x18\x11>\x12\xf2\xd7\x08\x9e:\x0e\xe6\x8d@-\xda\x08\xac\xf1P\x19\xf2\xe6\xc8k>\xd5B\x06\xad\x81\xcd\xa8\x91\xfa)g-6k\xf7\x15|\x1cJ\xf0\x0cy\x8d`\x01@K\xe8\xb8\x81\xcb\x8e\xdd\xd0~@1M[\xd7\xa3\x9c\x1a\xd4.\x96\\\xb0v\x8a\xa2E\xd7-\xfa\xa9\xc2x\x81:\xe6\xe3\x82&\xc2\xd7n\xab\x93N\xbb\xa0\x0dt\xb76\x11]\x17\xa11\xdf\x94\xafV\x10\x8auu\xaa<\x85\x84 \xbb\x99\x1d\xb11\xe3\x88\x8c\xa0in,x\x9da\xf7\xa0389\xe8\x0f\x0e:\xa7\xdd\xc1\xa0?\xa8\xab\x8cEaX\xe2\xa5\xf3\x9f\xea\xe3k\x1ft\xfa\x07:\x06Q>-R\xbb\xd4\x88\x1c\xea!\x80\x15\xafII44V26\x8dg\x89>\xeb\x95\x8c/G\x98\x98h\xb9-\x01-\xa0\"\x00\x9ek\x08)@\xacp,u\xfb\xe2\x86{zx\xd8>\x10\xff'$\"\xd1\xf3~\x89\xeb\xbe\x86\xd8F&\xe04\x8c\xb8I\xca\x95\x1f\xb2\x1510\xb1$\xb8\x12\xdc\xc4A\xca\xbdl\x10\xe6 tR;*I\x87\xbd\x88\x03,\xe3\x1c1\x10\xcc\x80\xe1{\x1e\"\xdc^\x01\xb6\"AO\x0b\xcc\xa7R\x8cD\x9bH\x1av\x1d\xdd(\xf3\xdcE\x94\x93\"\xb4\xfa \xc3NJm\x04I%\x96\xde\x0b\x1f.sD\x02m\x80<\x8fz\x013e6uhC\x8e\x18/fi\xc0\x84\x80\x03\xb2\x9d\xf4\x0bu8\xba;N<\xe8G\x05\n\xd8\xf0\xdf<49\x05\xad\xef\x0e\xcd$\xa4?<\x0f\x00E\xba\xd0\xda\n5\xff\x9a\"lM\xf9\xdf\xe5\xf4\x84r\xc0\x00\x06\x7f\x1a\xc8\xe3\x10\x13 !wDZ\x17z\xd0A\x1cy\xa9\xc6\x98\x9c\x82 yQf+\xd3\xaa\xd4X@\x96\x08\x82h\xf96\x1ez\xf2\xb1\x87\xccS\xc0=_\x0d\x7f\xa4\xd0\x12\xdf\x19#O\xf9z\xb9\x9f8\xb0\xe6\x12\xa0P\x92\xb9\xc8\xc0\x13l\xe4\x87\xb6\x91<\xf4\xda\xbd\xc2\x11|@O~,\x80a\xbf\xc0\xa4\x88\x917\\AP<\x85\x1b\"\xa2\xc6\xec\x90\x1b\xc9\xa0Z\x06\xa9\xad\xd810\x90E\x14\xb0\x03)l\xc0\xde\xd4\xb0\x026gmQ5f7\xb0\xc1\x02\xfbHb/2\xc4Z\x7f\x9c\xb0\xa1\x08\x0cz\x1e\\\xe5~\xc3\x1c9\xda\x08@+\xa9 />F\xfdmh\xc2\xd2\xe2S\xd5\x92e\x18\xf4\xcd\x9cmf\xcer\xf2\xae\x98\xb5o\xf2^$\xefe&\xfa,\xb3?\xaf\xd1\xba\x9c\x00*Zw~q~\xd5m_\x9d\\\xf6\x06\xc7\xfd\x93\xf3\xe1\xe0\xec\xaa\x7frrt~<\xec\x9e\xf4O\xba\xc3\xc1\xd9E{p\xd5\xef\xf4\x8e\xfa\xbda\xfb\xfa\xfc\xf2\xe2\xec\xaa\xdb?;\xee\x9e\x1f]\\\x1c\x0f\xce\x1b*\xedR\xe6 \\\xd6g\xe7\xd8DfvR\x95\xc3\x8f\x87e\x8dX\xf4&\x12\xaeP\xd8\xae\x14\x19\xcb W\x05\xe1I\xb28\xb1\xb6\x93]\xdd\xc8\xf5\xafi\x16H,\x9a#\xc2\xd9V\xe5J$\xa39\xc1r\x10c\xd0B\x07\xb2\xef\xf5\xa2\x92\x1a|KU 9\xe4x\xb5\xe9M\x1a\xf3\xcf\x0c\x11\xf3\x0dXL\xb11\x0d\xa4\xc3\xb79\x03\x98\x08\x8eO\xa8m\xd3E\xa0P\x88\x98.\xc5\x84\x9f\x827o\xaf\x1e\x04\x13\xfe\x97\x0eOK/\xbc\xad\xe0\xc7V\xady3a\x117\x99w \x14Rz%\xae5c\xff\xef\xe9\x9e\x7f\x96K&\x9d\xc1r\x85\x1c\x179\xae;\xec.\x87\xd3\xd5\xf3\xf3p\xe1Y\x93a\xcf\x1b<\x0e\xa7\xfdI{\xe0.\x97\xf3\xc2\x89\xd7\xc2R\x8dB.\xb4P\x11\x01\xee\xa0\x85\xf2\xce[\x92.0\xd7\xd6:\xa7^\xde\xb5\x8d\x1d\\\x18i\xdc\xc2%v|'\xec\x1e\xd0\x89\xf4\x81\xc0E^v\xcc5\x06T\xd3`\x9d\xd96\xe0K\x06\x1c\xc8\x0d\xb12\x98\xb2\\R\x15\x14\xd8\xca\xb6\xeb\x0eZ\x98@\x8eLa\xc2\x1e\x96Lu\xcf\xeb\x9d+\x93\xd6$\xd3\x7f\x13\xfb\x07\x80KY#\xc3w\x1e\xaf\xecB\xc0\xb0E\x90 \xf8rO\xd3\xb5\xb6!\xe0\x14@0\xf1m[-{\x19\x940\xdf\xa9f\x00\xb7a+\xc7\xd4\xccK%_\xc6#.\xa2f\x10|\xf2%p\xfc \xb1B\xc9\xbc\xee\xb9\xf9\xb0<\x10?3\xdfu\xa9\xc7\x91\xba\x04\xeeP\x13\x05\xd6\xd0\xb0}\x13\x81O-\x11E\xb6>}\xef!\xee{\x04\xc0 G^\x80W\xaez\xfd\xf0\x13\xf8\xd4b+b\xa8-\x90\x07.\xa6\xc8\x98=,\x7f\x10\xeb\xeb\x9fZ0\xdd\xc4\x13q\x1b\\\xc0\xd5\x0f\x07\xca\xf0\x0bC\x85-\x05\xc4\\S\xfa\xd5J\xbe Q+\xd36 LQ<\\P\xc6\x8d5[-g\xd5\xd4\xee jT\xb6u\x84\xfe\xaa\x89>\xc7\x12\xf3\xb0\xbc\x10\xcc\xfb Pm\x1e\x9b\x1c\xca=#\xa7\x1b\xa9\xea\x95\xc0\x91 m9\x15\xc6\xec\xcc\xc1\x84\x82\x05\xf6\xc4\x86\x18\x07r\x9d\nk\x11|\x1f\n=\xf5\x824\xe1\x070\xf1\xa8\x03~\xb9\xff\xf5_\x01\xea1dh\xd0\xdb\x97\xa37\xc3^\x18\xf20\xb4\xf1s\xa0\x14+\x1e\xd7\x9f_\x89\xd6\xafQvN\xc3\xfd;\xaf^\xab\xeaj\x81\x9c\xdf\x02\x8a\xa0\xce@\x8c\x05fy\x05L$y\x17\x98\x19\x0fE\xac|\x99IVS}Q\xd2\xd4\x08\xda~V\xd0\xc4^/.\xe6\x19c+\xf3\xb3\nI\x1chK\xbdP\xa6\xde8\x99\x95$\xddL\x99/\x91F\x17\x85\xeeUVg-\n\xad:WR\xe3@5\x02\xbd\xff\xdc\xd4Yr\xe3\x1fV\xe7j\x92~??\xc7\xffF\xbd\xf7wO\xf8\xf1?\x7f\xd2\xf7\xd7\xd7\xef\xae\x9e\x7f91\xba\xef\xee\xce&\xf3\xee\xd5\xf5\xef\xc6\xcdt\xd9^\xddAkq5}X\xb5\xe7wg?\xbe};\xbd\xb8b\xf6\xfb\x7f\xc3\xde\xd9\xa4\xed\x9f\xff\xe8L\xee\xa7\xf4\xf6\xc2\xfa\xf8l\xbe\xbd\xf6\xfe\xfcpsy\xfbp\xb6\xb8\xb2~\xfbm\xf1\x0b\xbd\x0d{\xdf\xae\xf5XC\xc4\xf5\xc6\xec\xe5\x15u\x0c\xc9\xecp\x0cmH\x0c\xc4\x0e\xff\nW\x9b\xd7\x94\xa0\x02\xdd\x0b\xf7G\x82\x08\xb6@\xb9\xe3=\x93[\x92\x7fm!)\x1cu\xd1\xe4\xcf\xc2\xa1\x86\xcd\x82\x0c}\x8c\x8c\xe9Q7m5\xc0fE\xa6Z\xd9j3\xf1;\xd3\xd3\x1c\x94*m\xbe\xc4\xaa-\xafj\x85\xf3\x82bR-\xac+\x17\xb0h3m\"`\x87\xc2\x1aOb\x0e\xab\x0eB)7\x11\x13\x18\x14\x13&\x0d4%\x89\xdc\x05)\x15\x11\xcb\xfb\xeb%\xef\xa5\x8d\xf4\x97%\xa4\xa5\xae'dG\xd1\xacDr(jB\"\xb2\xe2Ku\xafN\x95)m\xc9\x19\x05\xae}\xe4\xa1\xa7\xbcK\xd2g8\x90\xa1\x0f\xe8)\x9b\xb9A'\x98k\x91[\xdb\xc6Z\x86\xaapZ\xe3\xd0-\xf6\x0e\xaa_\x92n)\xdc\xd5\xbfs\xc7\x14Uj<\xb9\xe6\x1d7kd0\xa0\xcf\xa7\x1a\x83Q\xdd#ev\x83\x89\x94\xd9\x98B\x1c\xc9[\xd6P\xc4\x87\x01^\x8f\xf6W\xd1\x8c\xdd({C\x8f\x94\xa19\x8f\xb6_\xa8t\x07\xdbSg\x01R\xa0\x86E+\x91~!D\xc1f\xc0\xf2\x8d\x80\xa1\xb4\x8dd\xc5V\xd7bM\xb8\x0b@\xe9\xd6\xbe5\xb0\xc2+\x96A\xea\xad\x11(\xb3H\xa0\x8aUR?\xae?\xb6\xb11\x9a\xa1\x95\x1e\x9d\xbe\x1a,\x80\xde\xa3\x95\x0e#\x0b,\x081\xeal*\xafld\x90bd\x98<\x88sh\"\x1bYb\x85\xfa\xf0\xaf\xf8\xef3\xd3\xf4\xfe\x8e~\x8a\xcew\xe84^\xa3\xefR\xdbS\xa8\xf6\xb4C;\x97\xce\xfd\xcc0\xceB\x8fO'\xe02\x82\x8ba\n\xd4_K\x89\x8dT\xbfp\xb9\xd9\xb6\x81B\n\x19\x88\xc1d\x86!L\xd6\xa8\xaa'\x9dj\xd9\xd5\x9a\x06\xe8\xd7\xf7\xca/\xbb \x82/\xe3\xd9\xd7\xf3\x861\x89rV\xbdI}\xb4(D\xf6\xc7\x0e\xe6\n\x87\"\x8a\xd7\xab \xe4\xe0s\xe3\x12\xa7\x8c c\x0b\xea\x99\xd1\x19#%\x16\xf7\x90C\xe7()\xcd\xbc\xbf\xbd\xaf\xc4\x98Zf\x7f;Q\\\xcc\x97\xe2\xbd\xd5Zt\xa1\x9ef\xd1\xc5\x9b\\j\xa2\x8b7\xab\x14\xe0MXR\x11\xa1j\xa5\xcb\xd5q7\xf9\xd0\xb65\xb7\xd9\xdaC#\xcd\x04\xd4S\xe8\x1d\xc5\xb1iU\xe9\xb5;\x85\x88\xdf\xa3U\xa2\x1c\x98\x81\x85G+z\xa8\xc2\xe5\x90z\x1e\xea\xf0\xaf\xb9*N\x7f\x7f\x0d\x1e\xabd6)b\x94\xce\xe6W7\xc8\x90b%\x0c\xa6\x14\x03ogJsh\x07\xf6l\xed\xcc\xba\x8b\x1e\xe9\xda\x02\x8f\xce\x17\xcb\x93\xab\xe2d\xa7<\xe9\xa0\n\xec\x18\xf1\x05BD\xf5\xcb\"\xdf\x86\xb9\xc9\xbcZ?\xbd[\xd7\x1b(x\xb2\x81r\x1b\xfe\xb8\x8a\x82\xfadL\x89\x89\x895\xfa\x16L\xc6\xc1dL\x94\xaf<\xac\xfc=\xa2\xc3\xd6\x84|#y.\x8f/!\xd1\xf2-\xe2\xc3\xb7`\xf33\x0f6\xd9\x14z\xba:G\xb5\x05\xbbV\xa7\xdd\xfe\x16y6\xd2\xd9\xc01\xe94\xebs\x89A\xb5.\xee[4\x9a\x9a\xcd\x17\x1b\x8d\x16\xbb\xf3/5 \xd58\xed;\x88\xbd-\x18\x81\x1dE\xa7\x1e\xaa\x1cz\xa6\xb7-g\x14qKJ8\x816+\x15\xd9\xe2\xa1$\xae/\xf0\xfb\xa5\xe3\xf9\x08me<\xf7\x9e\xf1\xb1D\x89\xb62$Nk\x0c\xe8\x92\xf1\x0d\x06T\x16[\xa7\xb8\x0d\xbe\x9f`\x9b#\x0f\x8cW\xe1\xa1}\xc1y\xf6\xc3k\xd7\xbc\xcdc\xeb\x0f\n\x1d\xaa\xed_X\xabH%>\xb0\x86\x8e}\x19\xbe\xae4SH a$L\xbbH\x10\xaa\xec+\xf8:r\x01\xe6\xc5\xf7\x84T\xc7\xba.%H\xd0\x9b\x8c\xd7\x1c\xf1:\xdc_U\xba\xf1\n6fh#\x0eUO\xf5\xe9\xc6\xae\x0cf\xf6\\\xf0\x97m-\xcb\xe3\xe7\x84\x16\x80O\xc5\xa9\xee\x84Y\x98\x81 \xdc\x14\xf7\xeeT\x92\xf7\xdd \xf1\x0b8m\xed\xe9\xed\x06\xb2\xfd\x82\xe2\xfb-\xd1M\xcd\xa6z\xa2\x9b \x88\xb7;\x9b\xed\xe6\xb8Jf\xf6Y+\xe8Nun\x87\x19l\xd6Y\x94\xe5?\xc9\x10\x0cH\xcc\xe0O\xc4\x0e\xc0\xf9\n\x98h\x02}\x9b\x03\xcc\x81<:\xc8\x00%\xb6\\O\x0b9\x98\xf4\x13\x9fP\xafy\xec\xb3\xd2h`X\xd4M\xb1\xe1\xfa&\xc3\xc4\xb2\xd1g^\x04m\xe84v\xee\x1f\xb2\xd2\xb8\xd1\x16\xce/P2K\xb6s~6\x02\xb9\xb95l\xba\xdc\xfe\xf2\xe2\xbb\x9d\xed#_\xb0 \x97n%\xf9\x8aDz\xe3\xad$;\x92m\x97R\xfb\xb4\x94\x8b\xea~\xb6\xf8j\xe0\xe0\xcb\x10\x05\x08P|\x1e\x0c\xacUP\xb6)eh\xc4\xe9\x0c\xe9Nq\x94\x94Ae$\xdf\x04\x12\x93\x89-H1\xb2!\xe3#\x8euW\xf7W\x81\xaf\x05\x15\xa4`\xb2Cq\xcf\x0bc\xc1\x00<\xc4P\xbd\x9b\x04]\x0f\xcdG\xe1\xdck\x15\x8f7\x93\xdf\x8c\x95\xad(\xc5Rp#X \xce\x1e\x15\x9d\x8f\xfe\x9c\x858\x91(/\xe0\xb21\x85\xc4j(S#\x07\xd6\xbb.@\x81\xc4\xf5$\xd2\xa2\xd0\x0eE\xa9\x16\\\xe2\x8dk\xab\x8e\x03\x97\xa3l\x19#\x0f\x9aOSA\xa8\xf0#\x13\x11\xeaT\xec\xb2\x89\xc4\x7f\x07\x1e~\xbd\xfc\xf5\x14\xfc\x81\x00A\xf2\x9a\xf7\xb0\xe80\xc1K\xc0\xa7\x98\x01\x8f\xfa\x1c\x81\xc5\x14\xc9\xd3}\x89\xc7\xc0L\\\x9c9\xa1>\x11\xf7i@\xd3\x0c\x12\x1d\x1b\xb2\xa9ZU\x89\xee\xc53(\xe1\x1e48\xe0\x88\x89\xeb\xbc\xbe\x0b\x14.|\x8bH\x1f\x0d\xdd\xf9\xe3\xf7h\xf5\xf7!\xc3\x16 \xe8\x1f\xbd\xff\xf1\x1dHt\xf2;9\xdb\x94Z\x06\xedE\x12\x168\x15\x0b\xcf\x11I\x05\x05\xdfi\x08T\x1dLU\xd5\xef\"bk\xb55\xfc5\xd2|\xa5\xb1\xf28S\x845eq\x94\xa6\x19V\xc7\xbf\xe8#\xb9\x84\xea\xf2\x88\x1e\x98\xa1U\x1a*\x13\x1bJ\x12\xa7\x9b\xe4\"=\xe57%\xd6T\xbe\xd5\xc5{\x06%\xcc\xf5\xc7\x9dg\xe3\xd1\xf4\x91\xfb\xd4\x9e\xfb\xddgkf\xcdzC4\x81m\xf2\xb4x&&$O}\xa7g\x1c\xbb\xf0\xc8\xefA\xf7\xb9gu\xbd\xa1\xc5\xdc'k`\x0d\x0dv4\x1b\x1a\xfe$\xe9+e\xfb\xe2\xfeC\xf3WD\x1aa\x01\x95\x1f\x13#\xa8|Y\xb4\xe4&%\xef\x86LhK\x05\xe8\x95w\x99\x0f\xaf\xf4\xec\xe8\xafCS\xe4\xa7\"\xb5Q5c\x8d\xaf\xd2Hwz\x19jO3\x82\x1c\xa0\x16\xa4\x86\xf7\xca\xb9A\xf5\x99\xb2\xfa\x95\xd7\xed]\xebXx\xdcz\xbb\x85\xcc-\xdc\xf7Xe\xa4\xfd\xbd\xa8\xed.\x82\x85MR\x96\x8cF\xc9O\xbdT%\xd1%q\xe3\x15%q\xf2\x90\x93\xccf^q\x8d[\x8a\x92\xf4G\x88\xc3,G\xbb/\xe6w\xd1\x00@\xf0(\x9fP\xc9\xe6\xa5\xa9\xa1\x88\x1bO2\x17\xd7\xf9k\x10\xecf\x93C#\x0d\xad\xb2\xe0\x91sQ\xf9;\x0f\xca\n\x17%\x82\xaf\xb9|a\x1b\x15\x08 \xa6\x96\x9aC\xab\x95\x1b\xadd\xf3yz;\x93f\x87\xd3+\xbb\xe9d\xa3\xbb\xf4\xb6\xbc\xb1e+;\xecsr%\x1e \x0d\x89\x12\x03of\x0e\x1a\xe5\x85\xd1s\x9b pEM\xab\xae\xb35\xf9W\xd1\xcc\xd7\x12\xbf \xd5Asl\"b\xa0\x11\xac\x99\x0e\xcaK\xf9F\xf2\xc5\x9c\xd1\x02\x13\x93.j!p0\x19\x85H\\\xe45\xc1`R\x7fl#\x81d$3\xbe\x91\xe9{\x0d\xea\x1etA\x82\n\xc8\xde\xfa\x04\x0cH\xc0\x18\x81O-\x8e\x96\xbc\xf5\xe9\xa7\xa0I\x846,\xae\xc8o\x19\x9d\xf0\x05\xf4\xd0\xc8w-\x0f\x9a\xa8\xf5I\xe1O\x18\x10S\xc6Gq\x07\xe3\xcf\xcd+\x15l\xa0\x95\x0f`W\x13[\xf9Q9P\x07.\xc5\x9bZ\x90\xea>U\xc1H-f\xdd\x8dAu\xf6\xfe\x8a\xdf\xa1=2\x91K\x99\xee\xcd\xd8\xa2\x08\x1dl\xffJ\xb2\x97\x0b\x10\x1a\xec|\x8d\x18\xb9\xf9\xc6\xd6\xb2\xd5\xfe\xd8\xd4\xedi\x10f\x9a\xa4\xb6\x05\x88'\x16r\x11\xc1\xee-Sq\xda:\xa7<\x95f\xa6mX\xf0c\xe9%e\xe9\xc3+\x05\x9aR\xd6\x7f(\xd1\xb4p\x0cq\x83\xdd\x8e#\xb7\x99+5\x88X\xacd\xb3\x9fT\xeb\xce\x12K\x1e\x8e5\x08F05\xa5\xf5\x9eS\x8e\x89\x95\xfa\xca\x85\x8c\xa1\xf0o\x0f=\x8ag\xbbSF\xbd\xd6\xbcj*i\xc5(p\x93d\xff\x01-\xf9]H\xb1z\xea\xab\x9c[R\x15\xa4\x99\x06\xa7\xa3\x12\x19\xc5\xa7V-\xb4!\xca\xdb\xd0b\x05\xb1F\xbc\xa6#\xa1\x121P\xa2\x93=\xcd\x88\x1a\xe2x\xbd\xc1\x8c\xdc X4\x93\xc0\xd6\xca\xcd\xb2\x06%\x1cb\xc2D\xc10\x0b\x90O\xf9\xbf\x85-\xd1G}\x07\xe7.\xa0\x1b\xb8\x90\x11`\xa6e\xd3\x00'\xdd\xc3\xef\xae\x19H\xa7\x03\x97J\xedl7\x91\xcb\x0bG,\xd1'\x94\xb8]v+\xd8\x94\xe6RMS,.\xf8V\xf2\x9c/'x\xca\x98\xde\xbf\xa2?o\xcc\x92\x8b]\xa3\x0d\xf8e\xb9a\xb6\x0d\x18\xaf\x00\x8e\xe8\xb3{\xa3X\xa0a\xa15\x8b'\xa9\xfc\xd4\xb0z\xd9\xea6\x94\xa9\xb5\xee}\xcb\x1e;f\x04\xaev3}\x03\x899L[\xa2ua9\xd2V\xdae\x8b\xe8\xa9\x8c\xa8\xa5\xf8\"'q\xdf\xe4\xa8\xa9\x1c\xdd\x85tm(C7\x97;\x93\xa1\xd0\x0f\xb1u2\x14\xb5+\x96\xa1\xa8E`zr\xac\xfa&:\x15Dg\xf3\x0c\xe3R\xf2\xa0\xa1\x98mh\xaa\n\x12\x87pL@\xee\xd5\x93o\xc0\x95\xb92]\x99\xd3\\\x8f\xe3U% U\x16\x00ud\xdf\xad\xbcVY\xbf\x13\xa9G\x94\xaf\x7f)\x99G\\+\xa9\x88\xa6 f\x7f\x05\xef\x1el`]v\xb7\xd6\xa8H\xb2\xbcAV*\xeb?yeW\x05\x8fw\xf8W,\x16k\x83\xef\xb0\xe5\x9ef\x08\xa9\x06i\xdf'\xee\xe4(\xaa\xd3}\xcdF\xa8\xca\xc8\xc2\xfd\x11ee\xce\xe2Ji\xc3Q69\x05\xfe\"j\xba\xa9_W\xd4RC\xc9\xb2\xc7\xe1\xaf\xc5~VB3*\xb0}\xb5\x9cS\x8e\xd6F\xa1\xa2\xf0^\x12\x83\xca\xdfSK\x0b\xaf*\x1a\xfd\x87uo\xdb\xb2\xbay\xc0\xfa\x91r\xd4X\xaa7\x92\xc5\x82h5\x18P\x83\x00u\xae\x05\xfb\x16\x93\xae\x15\xc9\\L\x9a\xdb\x1f@\xc5\x0f\xadO`\x82\x91m&\x8bJ+\xc4\xe4R\x11\xa1\xd1\xff\x8e\x16\x98OGs\xc4i\xebS\xf4R\xf2\x98q\x88I\xd1\xde\x80\x80o_L\x98+\xac_E\x14\x05!\xae$v\x1eG\xc5\x95\xfe\x80'\xe1\xcf\xdb\xb65/\x16\xbe\nU~\xa5\xb1\xabp\x92\x87\x7f F\xaf\x0dZ\x83V{\x9a\x8e\x93_\x8b\x1c%\x08cW\xdd:\xf7\xd7l\xa8\xaa\x8c,\xda\xd7[\xb0E@\xbf\xbb\xa0\xe1\xe8^m\xbc\xba\x91[\x8f\x94\xb0a\xa0\xaa\x88\xfd\xf6\x15\x90C\xdb^\x15+\x9e8\x91\x1d\xcf\xe5\x0d\x03\xa2=\x90o\xcc\x03\x98\xde\n\xcb\xb1\xa3\xd5\xcf\xb7\x88\xb3zX\x0e\xc0\xcdD\xa9\xdf\x07Td\xc0E\xd1\x99\xf0\xb0.\xfb=>@\xe1F\x0d\xf0&\xcc(\xee\xc4\xf6\x8b7?\xa87\x02A\x02\x90\xe3\xf2U\xaa\xdb\x83\xaf\\\xfd_Dm\x1e\x02\x82o\xe8\xc2\xb6 \xfa1[\x0eS\xab\xd4\xc5\x9e\xc6\x8a9\x1b\x17Br{U4.\xa8\x14\xec \xba\xe5h\x94\xde=\x04|\x12\x083\xf4\x02\xef\x05\x08$\x94!\x83\x12\x93\xedBB\xb7\xcd\xf5\x06\xa1\xa1\x83\xc9Koo\x8c>y\xe2\x17\x8d`m`x2\xe8\xb5\x93O5\xe1\xfe\x1f\xe2Y\xe3Q\xa0\x9d\xff3:^\x1b\xdeg\x11n\x88\x8an\xebL)p%'Q(\xa6\xdb\xd1\x1ba91\xb1j(\x8e4\xb65\xd5\xa6\x00\xe85\xab@\xb1\xa4\xf3\xa9\x87\xd8\x94\xda\xcd\xa5\xac}\xd0\xd7\xc8\x98\xfc\x04Y\xe1\x06\x88\x8f\x8ez\x05\x88\x13v\x8c\\D\xa0\xcd5\xaf\x80V\xee\xa6\xddy=:R \\\xdb\xd1\x10\xb9\xfd\xb3\x86~H\x80\xba\n\x92\x83\x92n%\xb5\xf9\xf4\xb3\xf6(\xc5\xea\x94\x9acc\x91|m\x86\xbbH\x0c\x1aJ\xa5\x89\x03\n\x8c}\xc1\xc7\xd2\xbb\xed\x17\xd03C\x1a\xe7\xe3\xd6\xd7\x7f\xb1\xed\xf1b8\xe0\xe6\xdc\x81\xcfpf.f\x8b\xae\xdf?\xeev\x8f\x91\xe9\xfb6\xec\x1a\xab\xfeq\xd7\x9e\x14jct\x8a\x8fS\x0em\x10\x12\x03\x8c\xa1-\x94L\xde4\x95\xbeQM\xa7\x9d\x11\x16\xe6;\xd1\xe1\xf9\xe0\x9f\x11:\x04=\x82L0^\xa5\x9fPY%\xf7\x05f\x9f\xe1\xd8@1/\x15\xc6\xefH5\xcb\xae]\xa3\xdeC@\xca\x0fr\xea\xd5\xd4j77=\x17\xd4\xc1\xff\xc0|jzp\x11s)\xee\xf5\x0dK\xbf\xcf$f\xa0cw3\x14\x15\x18\xb5\x9b\xb2z\xf1 \x11\xed\xe3\x0c\xf1\xec<\xdd\x95\xf1u\x8d\xf5f\x05\xe0\x17\x91\xdc\xad\xd4Z\x8be\xf7\x85\x8b\xac5\x0d\xff\xc67\xbc\xbe\x1aGP\xa7V\xf85]\xa6\x18\xed\xa0\xce\x19\xa6=\xcd\xe4\xa2\xc6i\xbf\x94\xc0H\xaf\x95uW\x15L[\x0d{\xb5m\xa5\xdf|17]C\xd8\xcc\x1c4Q\xea\xb5\xae\xac\x1as\xf3\xed\xf5\x1e\xab\xe6e\xc6\xdf\x1c\xd9\x17\xed\xc82o\xa7\xff\x93\x0b\x88U}\xdb\"\xe4|\xfaU\xa3\xcf\xd1\xa9m'\xbb\x89\x12\x91\x88.\xd0\xce\x98%m6\xa3$+oJP\x1c\x80\x87)f\x01\x87\xc5+\xbe!10\x01\x8b)6\xa6\xe2K\x9f!\x0f,\xb0x\xc0\xce@x\x8e\x94Q\x81\x89O\xea\xc4\xc85\xec\xc5\x8b(]n\xbfA#%\xdbH/\n\xdc\xc3\x07\xe4\xda\xd0@\x0d$@\x85\xac(\x05\xe1\xc1\x1a\x82\x16\x80\x92\xf8\x8d\x86\n\xfc\xfc\xe6*\n6\xbd\xe8\x8d\xd8Zl\x19y|\x11\x1d\xd8\xb2\xe3\xa1^<\xf9W\x95M%Gg7\xce\x9a\xbe\xc0<#~5\x02\xa8D\xd3\xbc\xdb\xa8I8\x84\xa1)\x80\x12\x15\xb5\x0db\xd1\x1aV\xe3E\x94%\xa6S0\xd6M\xeeG\xdc\x86\xeb\xa8*\xe0\x87\xd4\xe7\x8cCy?r\xd3\x9a\xf1\x17(\xf4\xd7(#\xb8\n\x9dbo\xf9\xf9\n\xf0\xb6S\xe7\x9d\x8a\xe87\xb1\x8c\xc5\xf2\"\xbe\x8b_lwd\xc8\x9e\xec\xe7\x0b\xd3\xa5\x82Y`\xa5\x8d\xca\x98c\x845\x82\xc1/H\xd4_\xde\x96\xaf\xab\x12\xa5n\xce}\xc3*\xadpda\xb2\xfc\x0ed \x11\x89,\xce\n\x1c\xff\x16\xfe\x7f\xb6\x95\xa2b\xe9\xfd'\x83\xf4@\x1a}\x82\xf9jT\xfe:\xcdE\xd4NS\xdd\xa0\x0eM\xd0j\x01 _\xd7.z\xdf\xac\xb0;\x9bZ\xa5\xbf\xa7\x85F\x97\x0b\xe4\xf2\x00\xad>\xbf\xffx\x07qxw[$\xe0*\xd1@[%\x90\xf8\xaf2\xc2\xe0?Y\xfa\x04\x1dVMK4\x08S\x8a\xddz\xe8\x8c|F\xf0S\xc8\xa6k \xdfA6\x8d\x9b#lMy\xb1\x00I\x9eU\x9e\xf9\x0c\xadJEIDm\x85-n\x99\xa5\xf6\x14\x7f\x7f\xa6\xaeF\xe7\xb0\xa6l\xfaXV\xcd\x11 $\xcaLU\x89\xb2\x1b]L\xe4\xce\xfa=\xc3\x87\x8f\xd6\xec\x19\xc1\xc1\xb3k\xcd\x9e\x8e\x06\x9c<.\xcc\xe7y\x0fN\x8c#\xb3{\xbc\x07\x92U\xc6\x9d\x8c\xa3v\xf9=\x08/*3$\x937j=l< \xc6\xe1,\x8aJ\xb2\xf7\xb3\x95C\xb6\xfa\xe28\xcb\xbbX\xf8r\xcd\xe3\xa6WW\xfd\xeb\xa3^\xbb\xd7>\xea]\xf4\xbb\xbd~\xbb3\xe8\x0e\xcf\xfb\x83\xab\xf6\xe5\xe5\xc5\xd1\xc9\xf5\xd9\xe5\xa0\xdf\xb9n\xf7\xf6\x00xX\x8aE\x80\xca\x93M\xcb\xfe\x9a\x11_\xb6O\xfa\x9d\xa3\x93\xcba\xe7h8<\x1av\x86\xdda\xff\xfa\xbaw\xde>\x1bv\xda\xc7\xd7\x9d\xeb\xee\xc5\xe5U\xfb\xf2\xe8\xf8\xec\xe4\xf8\xe2\xaa=\xe8\xf5\xae\xba\x9d\xe3\x8b\xf3\xeb\xa3\xf3\xdep\xd0\x1f\x94kP\xe6q\xc0\xb8\xdb\xa3\xc1I\xf8\xe5Z\x05\xcf>\xa3\x15[ \xa0\xa3\x06(\xac!\xa4\xcc;(\"\x8c\xde\x9f\x944Wi\xd9\xcd\x1d\xe6\xcb\xbb\xb0\xaa\xa8\x06G\xfd\x9e\x8a)m\xaeA\x81\x07\x02\xb5\n\x91\x89'\xba\x83V\x102\"SH\xda\xc3\x92U\x166\x91L\x8c\x0c\x9d\x96\x141?z\xe4\xb1\x11\x90\x0b-4\x92\x8d\x1a\x81*\xd9cuH\xf1\xe0dU\xa0\xa3\xc8\xe5\xf2\xe5V\xe2\x85P\xfd\x036 ]\xa8\xcc\x1a\x87\xe5\x02\x9a&\xfd\xdf2+\x12\xc4 \xcay\xadJ\xbagA\xad\xec\xe64@w\x1b\xe6\xe6b\xae\xd6\xdb\x1d\xe4\x94G\x81\x0c[\x04r\xdfk6Q\x0dtA?\xf2\x13\x0b\xcd\xed\xd5\xef\x177\xbf]\xb6\xbb\x13vy\xe7\xc1\x93[>\xfe\xc0V\xe7\x9d\xc5\xf1\xf8\xe9\xe1\xb6\xdf\xff\xc3\xef\x1c\x9d<\xff6\xbe6\xfeX\xf6~\xbc\xb8^\x9d\xddX\xa8\xff\xc7\xbf\xee&\xefo\xfc\xf9\xf3\xf9\x9f\x83\xe1\xed\xea\xe9\x1d{\xba<\xb9\xef\xdc,\xf0\x95\xfb#\xfe}<\xf8xor\xdb\xb5\xfe\xf3\xb3\xd2\xab\xeb\x8fG\xa9\x00\x05\x14\xcd\x11\x94\x16d\x05H\xe6\xbb\x92\xa9\x82\xcc\xfbM\xc4D\x9e\x83 ?\x94\x0f$\xdf#\xc3\xed\xf6\x07\xb3Nv3^&V\x8a>\x15\xfb9\x9b?\xb7{\x1f\xa7\xfc\xfd/\xd3\x93\xb3\x8b\x8b\x8f\xcf\xf6\xcd |\xa0\xec\xed\xaa\x8dg\xd7\xff~\x7f\xf3\xf1\xddoG\x8f\xefo=\xca\xde\xa9=CCX\xa7\x9c\xa5)\xedZ9u\xad\xe2b\xe8\xc9G\xc4\xa8-\x13\x12\xcb\xb9M\x8d\xd9\xcdee\xad\xaf\x19\xf9\xba\xd0\xe393UI\xd63\x96\x14\x14\x19F\xa0\xce\xa9\xad|\x9d\x1e)X7ZA\x88w\x08\x9a\xa8z .\xea}#\x9cK\x0d\x8b\xc2!\x19\x8bN\xfd\xf1~7\"g\xad\xb8&r\x18\xe9G\x00\xcb\xfblu\xdb\x9d\xe3\xfdNw\xff\xa8\xfd\xd0\xee\x9f\xf6\x8fN\xdb\xc3\x83\xee\xc9\xf1\x8f\xed\xcei\x12M\x10\xdf\x19i\x1cJ\xd1@\":\xdb\x90q\xf9\xeac\x8a\n\xfa\xa5i)iQ\x8f\xd2\xb3\xd7\xe8\xf3\xa8\xafv*\xf6&\xf0QMq\x0c\xb2\xdd\xba0\xc9\xc6\xa4\xba\x90\x04-\xf9\xa89\xb8A C\x84\xf9\xb5\x01\xa1\xeb\xd6\x05\x114\x95\xe1o\xed\xee\xe2WCk\xc2\xc5k\xa2\xb9}\xd0U\xf6?\xcf\x91\xc7\xb0z\xf1_\x0d\xdb\"$\xb6\xae\xbd\xec\xa8\xc6\x05\xban]\xf8vdd*\x9b\x97\xa9b\x8d@\xa9ZI\xbb\x15\xabV\xed\xc8P3\xfa\x88\xab\x9bcR\xf4\xb59\xb7R\xf6\x05T\xb41\x12'\x92}o\x92\xdf\x14\xc6/e\x11\x8cb:\x8a\xb7\xfa\xaf 5\x12\x0c\x98\x98H\xb3>\xbc\x06\xbe0j\x90\x9f\xac\xfbI>\x9b`\xf5\xa8O4\x0b\xcb\x9b!\x0d|\x1e\xe3\xd0q7B\\\xc9\x19f\xf0\x16\xf6\xa7\x89D\xe4'\xee\xaf\x9b\xfbQ/\xcc\xf2SU\xa4\xe5\xa7 \x19\x90\x9f\xca\x049\xf6\x1f.\x8e{\xbf\xd93\xf2\xf4\x9f?\xae\x16\xd6\xf1G2\xb8=\xf9\xd59\xbe\xf6\xffl_\xfd\xda\x1b?\xce\xfd\xc7\x81\xb7x\xd7q\x1e~\xff\xc5\xfb\xe0\xdf\xde\xfe9?;{z\x18~|\xfc\x97u\xd7\xfepv\xf8p\xe9\x0e\xfc\xc3a\xf7\xec\xc9\xfbs\xf2\xef_\xee\xdd\xf3\xdf~\xfe9\x0e\xa9\xea\x15\x97$y\x1c\x94\xaf\xddW2\x15Y\x8b jXM\xb0\x91\xa9\xc9\xb8\x94b\x90\x96\\\xf5\x08\xf7Y\xc6\xe7\n?(\xfb\x82*\xd0\xa9\xc4\xb2h\xbb\xceVW\xa3ag\xb7#U\xb2\xf1\xa5i\xb0\xf6\xba\x90\xca\xf3Jm\xf5\xdel@\x85DNE\xa0\xdb\xe8)\x9az\xb8\xe1\xb3\xf2d'^\xf5\xaaq+\xac\xa7[C8\xf5\x06\xcb\xe9\x94\xf7=\xe7i\x8e\xc8\xa0{Bf\xf6\xd2\xf6\x9fW\xf3\x93\xe7\xe1\xe3\xd3\xa3\xe1\x18\x89L\xa7\xea\xe5\xf7\"-V\xcf\xff\xbeG\xab1dH\xac\xba\x03N\xe3\x87\xea\x00\xd4\xbcj\xb9\xb6\xba\xa1\x8e\xf7\x1e\x11\x0e\xe6\x18\x82\x0b1p\xf0\x91\xae\xa0\x85<\xf0\xff\xff\xdf\xff\xfd?q\x84[3\x7fjI\\\xfb\xef\xfcq\x1c\xeb\x16d\xd2k\x10\xc5\xb6>\x9f=\xaf\x81\x8c+\x08\xa9\xaa\xd3\x1a\xa0t\xe9\xd6\x82l\x04\xcdG\x9fq\x07\xd5\xa8\xfew\x0e\xe2\xbb='\x08mEG\xd4\xda\x15\xc3\x8eoC\x9e\xa3\xc4\x98R\x1bA\x92\x1fP\xfaE\xdb\x94\xa0]1\x8e\x9d@\x8c,\x18\x1d U\xaf\x9f\xff\xde\x80\x84P\x0e\xc6\xe2\x04\xb1 0 \x92\x9dG\x9f\x84\xaf'b>\x8d%qD\x89\xbd\xfaa\x0f\x80\x87\xb8\xa6\x13\x1b\xb3\xca\x9a\xb6\x99\x91\xcc\x95\xb4\xca\x19\x15\xaf8\x05 \x9c\xeb\x8f;\xcf\xc6\xa3\xe9#\xf7\xa9=\xf7\xbb\xcf\xd6\xcc\x9a\xf5\x86h\x02\xdb\xe4i\xf1LLH\x9e\xfaN\xcf8v\xe1\x91\xdf\x83\xees\xcf\xeazC\x8b\xb9O\xd6\xc0\x1a\x1a\xech64\xfcI\xd8ItA\x1a]\xd4\x10\xf5\x8e\"yq\xca\xe5z\x98z\x98W\x9eS\x8cE}_\xb02\xf9\xdd\x10@\xa3\xea\xe9U\xf4\xcc\x83\xab\x9a1\xa9bV\xd6.\xee2\x1d\xc2\x95\xb5\x94\x17\x0d\x97\xb6\x9d`\x12\xa0\x84\xb6\xbd\x1ae\x17\x8b\xf4\xd5\xf5\xfc\xfd\xb8\xcc\x1f;\x98\x8f\xd6\xd6pd\x81$w\x91\xeav\x94=\x94$\xc6\xa1\xb7f(\xd1C\x80\xdb`\xb6\x86\xee%\x82|\xa9N\xbdB\xc7\xfa\xc5\xd4M)Uu:\x9a\x17\xbb\xd6\x951\x14\xe1\xa8<\xc9U\xde\xf0\x17;\xb9\x83\xfc=\x88\xe1\xeb\x12\x1b\xe1 \xd5\xa3\x00=x\xf2\xeaEcD\x1fi\xe4\xa9*\x10-\xf3\xccD\x99\x11X\xc3\xe5\xeck\x13\x99&\xf5=\x13\x0dO\x1en\x18\xc7'\xb5B\xd7\x1f\xbf\n_\xf5\x08\xb1\x9d\xdf4\x95\x0e&\xf4\x167\xe3\x12\xc4\x03\x8akT/\x8c\xefGl\n\xbd5\nR\xe2@*\xa5\x98\x0e%xVq\xcd\x06\x9b\x88p\x9c\xbd^\xb7\xa0\xf1\x02\x8d\x19\xe6\xd5\x96q\x182\xfc\xc0}\x8f\xc43\xed\x86vM3\x07d\"\x0e\xb1\xcd\xd6\xb6\x1dSb\x8e\xf4\x0b\x13\xeb\xe3i\x01\x8c \xf7\xe0\x88/\xe5\xc2}^\xf5\xd2\x1c\xd6\xac+\xf8$\xc0\x13x\xa8\xa6\xe3H0\xacu\xb4\xa90gx\xdc\xdeow\xf6\xdb\x9d\x87v\xfbT\xfc\xff\x9f\x89\x8eE\xc7!\x1b \x8e\x07+2\xb7\xb0\x10\xe6\xc0\xe5h;X\xe49\x95- \xf3\xc5\xfb\xf3\x19\x1aWDTD\xeb$q\xaflE\x13\x0b\x903\xa3\x9a\x81\x94\x14O4\xad+\xd8\x94\xf0Z\xd95\xb6;\x8a*~\x8fD3\x99h\xad\xed\x7f\xbb\x9c,\"\xdc\xc3\xdb\xc9-\xe3i^I\x9c\xa9\xa9_\xa9\xfdT\x98\xb3\xc0\n\xedQ\x8e\xd2U\xb8\xa1icxH\x1e\x9d\xaa`_\x1cL\xca\x8d\x88\x86\xa1\x95'\xb6Kf\xbe0\xd1\xd2V\xbd\x88jI\xab\x0f\xc8|9z1\xcf\xa8 a2^ b\x8b*\xa3R\xa4\x95\xa1P\xa01\xd5\xeb\xe8\xb5Xe\xd0\xc0\"\x8b\xe6\xe5\x1c\x03;\x10*i^\x03j\x176\xcb]\xacS\x99\x0c[\x8a\xae\x19\xb2'\xe2\xbc\xe4h\x8b\xf5\xe9T:.69\x16\x85\x17\x9b`\xbf\xf3\xc766\xde\xa3\xea\xa2#\x9a\x94q\xac|{\xf9=\xb6\x08&V-6\xc92D\x05S,\x16AGt2a\xa8\xbc\xa1\xcc>F>\xe18W\xe2\xcf\x18w\xc6\x909\nO\xb6\x16\xc4\xab1\xc4\x1d\xf4\xa0s\xa1\x1c\xf2\xad29\x7f\xcc\\X\xa3\xc2\xcc8\x9ca\x12\xef\x8a\xac\x91\xcd\xb5n\xe12\x96a\xa6\x14\x9c\xea\xe0h\x95\xb19\x9e\xa9<\xceV\x99\x08[^k\xf9\xaf\x00\x00\x00\xff\xffPK\x07\x08\xa7j\"\x13n \x00\x00}\x0d\x01\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xd4`4t\xc7\x01\x00\x00\xbd\x01\x00\x00\x11\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00favicon-16x16.pngUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(6B\xc8\xd7\x7f\x04\x00\x00u\x04\x00\x00\x11\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x0f\x02\x00\x00favicon-32x32.pngUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xb9\xb1\xf1mT\x02\x00\x008\x05\x00\x00\n\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd6\x06\x00\x00index.htmlUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(]\x12r 9\x03\x00\x00T \x00\x00\x14\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81k \x00\x00oauth2-redirect.htmlUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(-\xe3\xb5\x97=9\x05\x00\xf7\x0c\x1b\x00\x14\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xef\x0c\x00\x00swagger-ui-bundle.jsUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(v\xf2\x8aA\x86\xba\x01\x00\xc5\x87\x08\x00\x1f\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81wF\x05\x00swagger-ui-standalone-preset.jsUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(_;\x94/\xe8Y\x00\x00\xa8X\x02\x00\x0e\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81S\x01\x07\x00swagger-ui.cssUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xa7j\"\x13n \x00\x00}\x0d\x01\x00\x0c\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x80[\x07\x00swagger.yamlUT\x05\x00\x01\x80Cm8PK\x05\x06\x00\x00\x00\x00\x08\x00\x08\x00E\x02\x00\x001|\x07\x00\x00\x00" + data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00 \x00favicon-16x16.pngUT\x05\x00\x01\x80Cm8\x00\xbd\x01B\xfe\x89PNG\x0d\n\x1a\n\x00\x00\x00\x0dIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x01\x84IDATx\x01\x95S\x03Luq\x1c\xfd\x8c\xf1\xc3\xec0\xa7)\xcda\xb6k6\xb2\x9b\xf9\xb2k\xc85/\xdb\x8dqx\xc6\x94m\xcc{\xef\x7fO\xff\xf3l\xdc\xed\xf2\xe0\xfe\xf8\xc9\xffP\x14\x11/\x14[\xa3P\xc4\xa1\xbc?\xf1t>7\x12s\x13\x03\x85\xca7IR a\xb5j\x8f\xa71\xbe]\x88\xf6\xb9L\xf0\x1c\x93\xcf\xda\xe3)\x10\x93f\x8d\xe4\x06\x13\xcf\xde<\x9b\xd14\x95\x8a\x92\x81OA\xcfF\x89\xdd<\x9b M\xe6}L\xe4\x07\x15\xc5\xf5\xe3\xffI\x0c{\xd6\x8d\xffs\x994\xbasfh\xae?\xafk\x1aprw\x10 <\xb9\xdb\xc7\x86\xa6\xd1\x19I\n\xa8\xb1\xd7\x84y3g\x171T$\xb5c\x7fq\xfbbq\xbfk\x8e'\x1dQ\xb0\xc2,\x92\x0bx|;F\xe5\xf0\xef\x00\x83\xf2\xa1\x1fx|?q\xbd\xcb\xc2\x16\x80ZF\xf0\xc4J\xf3\xe3\xe4n1\xcc\x17k`:}\xcby\xe8\x98\xcbB\xc7|6z\x97r\xd14\x9d\x06\xd3\xf9\x8a\xe4\x94\x90\x8b\xb6\xd9\x0cP\xebc@\xd0|\xbe*\xc94\xc8\xa7\x98'\xcdh\x00\xe3\xd92\xa6vK}\x0cB\xa4\xf0+D\n\xc7\x81)\xb0\x10\x9a\xe3\xa9\xd8\x8bx\xe4(\xa2\xbb\x8dl\x0d\x01\xb6\x8a-\xf378\xbe\xdd\xc7\xa6\xb6\xc9\xd9\xc6d\xd8\\m\xf4\x0c\x92 uQ\x0e\xd2\xf5\xb3\xd1\xf1w\xdfQ\x16\xb34a$\xa1\xc4\xc4(V\xbcF\xd9\xdf\xa4\x91\xe9\xb0&,\x12+\xcd\x93\xcf\x1c\x1cb\xdc\xca\x00qt\xeb\xcc-\x14\x89\xfe\xfc\x0fm2j\x88\xec\xccs\x18\x00\x00\x00\x00IEND\xaeB`\x82\x01\x00\x00\xff\xffPK\x07\x08\xd4`4t\xc7\x01\x00\x00\xbd\x01\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00 \x00favicon-32x32.pngUT\x05\x00\x01\x80Cm8\x00u\x04\x8a\xfb\x89PNG\x0d\n\x1a\n\x00\x00\x00\x0dIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\x00\x00\x04|ID\xc4\xcf\xd0@\x04&%\xad\x1e\x16\x0f\xf7\x8d\x97AR\xfa\xca\xe7l\x87\x05\xf8\xd2\xfb\x0c\x84\x1d\x0dLVY\xdc/ju\x13\x1a\x88\xd2\xa0\xaaa\x82|nzp_\xf4\x03\xc8 \xd4;^\x8a9}\xeeu\x9a\x91 `\x04\x14s\xec\xe1\x0c\xc6]\xa3\x05``\xd1w\x12*~ \x00\xf3\xae\xd3\xa0\x9cb\x82\xa2bx(\xb3n\x1fqx\xd2\xf2\xda4\x1d\x8a}\x1ck\xd4>\x9cI+\xeb\xb3\xf4k\xc8u`L\x93\xf3]4\xb5\xd0\xc3\xe33\xd9\xee\xd7\xf2\xd9\x19\xea\x18\xc9\xc1Y:\x18\xfb(-\xadN\x82\x06e\xd5\x1f0\xa2\x1dV\xf8\xbe0\xc1\x985\x01\xf8\xd2~\\\xa6\xa5\xb5)&\xf6\x98V\x80l\xe4\x03\xf8\x03\x04\x00s\x9a^\xec\x85\x00\xf4+\x0b\x00\xe1:G\xf2p\x96\x0e\xc4,\xe46\x1e5\xbbP\xdd\x15J\x80}\xce\xa4\xe2\xc8{m\xa4\xe2\xc3\xc2\x01\x07\xc0\xdb\xa4\x18-\xa1\x931\xba\x10S\xfa%\xb6P`\x10\x19v\x99#|Gg\x9b \x10W\xf6\x8dI1\xba\x92\xd66\x17E\x12\xfa\xd9\xa8\xf3UTe\n\x1b\x95\x9d\x81f\xe5\x18\xa5umc\x81\x86\xa6\xeb\xec \x804\xcbg\x17\xa19\xfa\xc6\xf7<\xa3\xbd\xf2\x0e\x7f\x02\x80\x97Y\xc7\xac\x184$h\xa3v\xba! \xcc{\xcd\xb4!\xb1\xd8\x92%h\xe3\x93\xdc\xd3_\xda1\xe6\xaei\xcf\x83\xa6p\xbc$\xf0\xb2\xda\x94\xa2q\x14B@\x13\xdb\xff\xf3\xd7\x0d\xfaA\xb9\xc5n{\x8e\xd6Y\x08\x01u\xc1'~\x16\x8e\xe9\x04\xa2\xfbA+\xc74\x0c\x98\xab\xd7:\xfc0\xd1v\xaf$\xa2#\xb7\xf1\x08\xfdm!OXh8\x10j|g\xd1\xe0a\xb2\x99\x04\x9a[y\x9a\xbdk\xf24C$\xa0\x9e#\x9f\xa3\xa8\x001\xc6\x1a\"\xc0\xe4i\xa6\xcc0\xf3\xf7\xb7\xf5XE\xb8\xe0\xa1\xc9\xc2\x0c\x90\x83\x80$\x838\xdf\xd6\xe3\xd4\x82FNG\x0f\x876\x8a\xbf1\xa8d(\xa7@\x8cQX\x90\xdb\x19\x9f\xc5YG\xe9\x9e\x00\xa5y3]\x9aJ\xe1\"\x00\x00\x00\x00IEND\xaeB`\x82\x01\x00\x00\xff\xffPK\x07\x086B\xc8\xd7\x7f\x04\x00\x00u\x04\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00 \x00index.htmlUT\x05\x00\x01\x80Cm8\x9cT]k\xdc:\x10}\xdf_1Q\x1e\x92\\\"\xfb&\x81p\xf1\xb5\xfd\x90\xa6\xa5\x81\x94\x06\x92}(\xa5\x14\xd9\x1a{\xa7\x91\xa5E\x92\xf7#!\xff\xbdX\xf6\xae\xb7\xdd\x90BYX\x8f\xe7\x9c9\x1a\x1d\x8d\x9c\x1ep\x0e\x1f\x1f>\xddBe,8/<\x95 \xc9yKE\xeb\xc9h(Z-\x15B\xd1\x92\x92\xc0y>I\x0f\xae?\xbf{\xf8r\xf7\x1ef\xbeQ\xf9$\xed\x1e\xa0\x84\xae3\x86\x9a\xe5\x13\x80t\x86Bv\x01@\xda\xa0\x17P\xce\x84u\xe836}\xf8\xc0\xffc\x03\xe4\xc9+\xcc\xef\x97\xa2\xae\xd1\xc2\xf4&\x8d\xfbL\x8f*\xd2\x8f`Qe\xcc\xf9\xb5B7C\xf4\x0c\xfcz\x8e\x19\xf3\xb8\xf2q\xe9\x1c\x83\x99\xc5*c\xae\xd7\xe0-E!\xbb'A\xa5\xd1\x9bbjD\x8d\xf1\\\xd7\x9b\xeaJ,:\x9c_\x9c\xaf.\xce\xa3\x008zB\x97\xb1\x90a\x10\xff\x9d\xde\xd9\xe5\xea\xec\xf2\x17\xbd\x90\x19\xf5\xc2\xc6\xfa\x18\x82\x9bC\xf8<<\x01\n\xb3\xe2\x8e\x9eH\xd7 \x14\xc6J\xb4\xbc0\xab\xff\xb7\xb8Y\xa0\xad\x94Y&\xc0\x1b\xf3\xc4]i\x8dR\x85\xb0\x8e/\xd0z*\x85\xda\xe7\xf2u\x02=q\x83\xbdL\x86\xe0\x9f\xd3M\x90\x14X\x19\x8b\xe3\xbb\xa8<\xda7\xfb#=CK~O\xb40r\xbdW\xd8\x08[\x93N\xfe\x1d\xdb+D\xf9X[\xd3j\x99\xc0a%\xba\xdf(\xd5\xfd\xa7\xf1\xd6\xaf4\xee'\xac\x0b;\xf9\xc1OI\x0b \xb9;\x0e,OcI\x8b|2\x18^Z\x9a{p\xb6\xdc%\xf1~\xc6\xa3\x1f\x8e\xe5\xdd*\x81\x94\xbfY\xe1\xbc\xd0R(\xa3\x91\xcf-:\xf4o\x14\xf7/K\xd2\xd2,#\xa3\x95\x11\x122\xa8Z]v\x17\xec\xf8\x04\x9e7N\xc51\\\x85{&\xc0\xad\x9d\xc7f\xc8\x97F;\x0f-A\x06\xc3m\x99\xde\\\x85\x9e\x8fGG[\xab\x12`Q\xeb\x8c\xd8v\xfb_}K7\xd3F\xfe]\xb1\xa1\x82h%q{\x8b\x9b6\x88/\xc4i }\xc07u~}\xe5\xad\xfd\xc9\x98\xe7q\xd8_}o\xf1\x92%\x9dx\x15\x9f\xd3yO\xbdX]\x1aA\xc9>t\xd6o\x93\xd3\x92\xf2\x04l\xc5\x8d\x92jz\xc1jN\xd6\xf2\xa9\x87\xfa\xb5]\x05\xcc\xf9\x1acB\xa9,\x9f\xd0\x08\x05\xb7\x962\xec\xdb\xb6\xe2\x16b\xc6\xd5\x942H\x05KfI\x06\x7f\x9c\x98\xa8\xc0\xd5\x9c\xa2\x0c\x13\xa3\xe7U\x8e\xb55;'Nk\xe6\xd0\x9d;\xd4%^\x14\xbd\xd5\xf7\x92QN\x8e.\x1c`\x079m\xe3\x9e\x8a\xfe\xed\xa2\xad\xe0y>\xe6\xe23\xdc\xf8u\xa7=\xa3\xf6\xa1\x98\xb4\x17g\xa9\xf4\x1dA\xa8Z\xe4\xf6\x88_\xfc)\xf8\xd5N\xcf,\xea\xb4\xabS\xf2\xd2\xe0v\x10\x90\x82\xbd\xb3\xe1\xc1g\xc8>\x120\x0c{\x1d\xbd\x1c\xd1\x7fd\xb4\xbf\x82|\xf7\x9f\xd0\xa7\x1e\x82\xc5`H\xc0\x94F3p0$H.\x0f]v3\xaa\x9b\x1c\x83EW}\xba4\x12O`_\xb5!H5\xd1 \x9a\x0c\xaa\xcd\x04\x8cE\xe7M:\xe1\x08\xfe\xefQ\xab\x02\xfe\xb7A\xeb\xb6k\xbb\x05{\xef\x8e\xde\x84\xcb\x9c\xb2\x8f\x04\xd7U\xf9\x9aQ:\xbe\xf51\xf1\x1a\xaaW\x97uR\xdd\xe7\xf59\x974\xb7\xfc5s\xd0\xc4P\xdf\xdd\"\xd7\x96\xc2\xdab7x\xb8;\xfc\x01\xfa'\x00\x00\xff\xffPK\x07\x08]\x12r 9\x03\x00\x00T \x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00 \x00swagger-ui-bundle.jsUT\x05\x00\x01\x80Cm8\xec\xfdyw\xdb6\xf68\x8c\xff\xffy\x15\xd7\xfa\xf6\x9b!kZ\xb1\x9d\xa5\xad\x13\xc5\x93\xc5m\xb3g\xe2\xa4\xcb\xa8\x1a\x1fZ\x82,6\x14\xa8\x90\x90m\xb5\xf2\xef\xb5\xff\x0e.\x00\x12$\x01\x10r\xdc\x99\xf9<\xcf\xc3s\xdaX\\\xb0\\\\\\\xdc\xfdn\xc1tI\xc7,\xc9h@\"`!\xfc\xf9?\x00\x00\xbd\xec\xf4w2f=\x18\x0c\x80\xad\x16$\x9b\x02\xb9\\d9+\xe0\xd6-\xd3\xd3y6Y\xa6\x04\x0e\xe5\x1f}\xf5\xf6\x00X\x10\xc2\x01\xf4T7\xfaG\x132M(\xe1-\x8a\xbf\xfa\xf1|\x02\x87\xf2G0\x1c\xe1\x80\x0e\\\x839T\x7f\xf5\x8f/\xe2\xb33\x92\x7f|\xfedI'));&\xe6'\xffs\x15\xb0YRD\xd5\xf4\xd5\xd4s\xc2\x969\xd5\xc0\xa2\x1e\xf0\xeb<\xce\x81\xc1\x00\xfe\xbcz\xf0?\xe5M\xf5*\xd0 \xd7_\xe6W2\x85\x80\x0d\xf3Q\xa8\xda\xe5?\x14t\x1e\xd4^\xe5mg|t\xc3|\xc4\xbb\xa8=\xc4\xb6\x0e \x8fZw\xd3\x03\xd8\xdak\xdf\x96]\x1c\xc0\x9fW\xb5gW\xf5N\xe5\xa8\x08\x1f\xd58N\xd3 S\x83\x8b \x8b@\xfbEC\xfe3\x85\x01l\xedj\x0f\xca\xd6\xaand\x9b\xb4?\x87\x01\x90\x08h\x7f\xcc\xa7\xc5\xff\x98\xc0\xa0\x8ep\x11\xb4@F\xfb\x99\xc4\xc5\xf5\x1a\xde\xe2\xd2\xf7\x05J\xbc\xcb\xb3\x05\xc9\xd9J~\xd9\x86\xd08\xa3\xd3\xe4l\x99\xc7\xa7)\xb1\x80\x85.\xe7D=\xdfm??#\xec\x00\xf2:\xc4\xc2j\x8e|\x0e\xb46\x87\xe6\xe8\x15\x86 Z\x93\xfe\xc9 )^\xab\xbd\xd1\xc25\xfdR+\xc1\xe7\x1a/SV\x1f\x03\x1c\xf8}\xed\xb1\xd6\xb4? X\x04\xbd\xb8\xc7\x81\x1c\x01\xabO/k.Q\xb3;\xd9\x8c\\\x99E\x9e\xb1\x8c\xef\xca\xfe,.\xde^P\xb5F\x02\x9b\xf0\xfbz\xfb\x0b\x18@\xef\xf6$)X/\x02\x1a\xd0>'\x12w\xef\xde\x13\xaf]\x05\xc3\x06~P\xbd\xff\xde\xb2 P\xb0<\x19\xb3^59\x9d\xdc\xd0\xe0\x1b\xd5T\xd4D\xb5ZS\xf5\x8f\xbe\xbdw'\x0c\xbc\xbe3\x0f\x81\xe9+-\xb6\x08S+\xd9\x05PN#\xb6\x02\x02 -XL\xc7\x9c\xbe\xb10\x046\xcb\xb3\x0b\xa0\xe4\x02>\xac\x16\xe4(\xcf\xb3<\xe8=\x8d)\xcd\x18p\xe0B\x0c\xe34.\n\x88\x0b\x88\xcb\x1ezacG\xde\xcct\xaaG\x1c\xc1\xf3\x08)\x15\x0d\xf6\xef\xef\x87\xf5M\x94\xc0\x00\x82\x1c\x06\x90\x85|\x07\xe4\xf5\x1d\x90\xc3\x81\x01y%\x9cZ\x1bO\x1f\x8f\x01\x96M8\x96t\x98\x18\xc1\x8c\xafd9\x04|\x06|\x13\xef>\x00\n\x0f\x81\xf5SB\xcf\xd8\xec\x01\xd0\xedm\xd3G\xa0f\x8d\xc4\x99\x8e\x1e\x18\xdf\xc8\xfb\x15m\x81A\xfd\xe7z\xcd\x89\x11\xe4}\x9d@I4\xe9\x9d\xc7\xe9\x92\xf4 \xa1\x90s\x88\x05y\xff\"OX\xf9F\x18A\xb0\x1bA\xa2 \x10\xf2\xc9\xe5\xfdOd\xc5igk(\x0djo\xda\xb9%\x009.\x18\x08\xb0\xf6*E*\x16h\xdb\\\x1c\x04\xb9\xbc\xcf\xbf\xd6)H\xbd\xcf+\xbf\x1d\xa5\xef\xc4\xfaHJ\xc4\xa0\xc17\xf7\xef70\xadB,N\xca\xff\x9dX\x7f\xf7\xde\x7f\x0e\xe9\xad\x04\x84\xe8\x14\xe3=\x99\x92\x9c\xd0\xb1\"\x1b\x9c\xd7\x81Y\\\xd0\xbf18%\x84BB\x13\x96\xc4iR\x90 \xec@\xb1\\\x90<\x08kop\x12C&\xbd\xd0x\x86l1\x8e\xd3%c\xb65\x18@p\x9e%\x13\xd8\x85\x01\xe7\xd2\xe0\x10zK*N\xedI\x0f\x0e\x9a(\xcc\xe9\x1bg$+\xaep\xab\xe4\xed\xf8\xc7\x04\x0e\xf4s\xe9\xaf[R\x18@\x1cp\xec\xfa6l\xaci&\x1f\xdd\xb9\xfb]\xf3Q\"\x1f\xdd\xbd\x17\x86&>0n\xb3\x05\xea|6p\x05\xc4\x8d\x1e\xc4\xb6\xb9\xae\x87'\x16\x90\xdf\xba\x05t\x99\xa6\xb8\x92\xccr\xf6\x1cs,\xe1\x8ceN\x8a\x82\xcfs\xbe,\x18\x90\x84\xcdH\x0e\xa7D4\x90\xe5\xdaa\x14\x01?\xacz\xb0\xbd1v4\xd0\x8eT\x04\x88o5d@\xab\xd7\xf9\xe8k$\xca\xc8\x19\x16,_\x8eY\x96\x9b\xa0\x0d\x88\x0f\xe9\x92\x1c\x00i3\x85\xd0d\x1c\x0d\x8c%\xbf\x14\xdd6\xb3\x96\xd0fPw[/5\xc87'\xae\xf2PPk|\x88\xd3\xcfk\xc7\x01\x13\x92\xce\xc9 \xc2\xe0\xe4\x84\x1fT\x1b\xf2\x01\xb8\x1b*\xa0\xe7\xae\x83\xd6\xbc\xd5T+|\x85\x1e\xe7y\xbc\xd2x\xc3\"M\xc6D\xdb*\xa0o\x17f=\xae\xc5\xdc\xeb\x8b/\xf9\xceqNbV;\x99\xc20\xd2\xf1\xa4\xaf-9\xe7\xc7\x1b\xdb\xc8<\x14\x03C\x0f\xd5\xee\xc5}-6\xec\x8b\x80\x84^-\xe6\xce\x16\x97U\x8b\xbf\xfa\xb6\x989[,\xaa\x16_\xfa\xb6\x98t\xcf\xfa\xd6-\xd8J\xab\xa6\x7f\xf0m\xda@\n\xb5\xa6\xb7\x82-\xc1\x1c\x91\xe1t\xe4\xd7\xe0\xd2\xb7\xc1\x85g\x83\x85o\x83\x13\xcf\x06\xd3\xee\x15_\xaf\xb1[\xaf\xe6\xc6\xbe\xe3\x9b\xb5\xc6\xa7\xffbA.X7\x16d\xea\x8fD\xfcA\xfbI\xf1\x9c\x95\x9ck,\xee\xbc$+\xc2\xc5\xf5\xa5|\x81N\xc8%\xde(\xc4\x8d\xc7E\x91\x8d\x93\x98%\xe7\xfc\xa3T\xdc|\x9bOH\x8eo\x8d\xf9\x0d\xd5\x06\xef\xba_\xb5\xc0\x07\xd0?&\xfc\xbcJ\xda\xf4c\xca\x05\xc4\xbf\xff\xfd\xe4\xe4\xf9\xeb\xd7\x1f?<~\xf2\xea\xe8\xe4\xf9\x87\xa3\xf7\xf8\xc7\xc9\xdf\xff\xdekS\xd6E\xfb\x8b\x97G\xbf\x1e=\xb3\xbc>1t\xf0\xe6\xd9\xd1/\xd6\x0ff\xed\x0f\xde\xbe\x7fv\xf4\xde\xfa\xc19\x0c\xe0^\xfb\xf6\x1c\x06\xb0\x07\x0f\x1f\xc2\xb9A\xf1\x00\x03\x98\xc3\x0e\x18\x8e\x96\x15*\x9c\xda\xf7O\x8dZ\"\xa8\x8e\xb2\xad\xbd\xd6SC3'\xd7i\xc6F\xcb/\x9c\xd8J\xfa\xd8$g\xc4\xf6\"O\x92|dn\x91\xc8\xa3\xa1lp\xd7o;]\xf2\xd3\xcc\xf6\xf0\xd8q\x12q\xbee\xbd\x86\xdd\xb6\xf4W\x13*_\xc7l\xd6\x9f\xc7\x97\xfc\x90&R\xb2\x84\x1dT\xb4\xf0c\x88\xb3Tx8\x06\xa8O\x13Rh\x06\x0f\x81>\x80\x8c\x8b\x9f\xf90\x1b\xf1\xe3j\x98\xc160\x83\xac)A\x99{\xcd\xf6\xa9s94\x9e\x8c\xf4\x8b\xe4\x0f\x05S\xfcs\x80\x0cE\xc2\xe9\x02#\xc1cq\xba\xf2'^\x1d\x7f\xb2B\x12\x99P\xba\x9c\x9f\x92\xbc\xc6\x82\xba$o\x8a\xd0\x7f\xf4\xe8\x91 \xfc\xa0\x1a\xe5|&\x15\x1c,_\xa9\xbb\xfb\xdf\xdd\xfd\xee\xfe7\xfb\xdf\xdd\xc3\x19\xd2R\x05\xfb&~cn\x85/2m\xe3\xba\x0d|\x0c\x1e\xc2.\x1c\n o\x03\xab\xc9,\xe0\x00\xcec\x97\n\xaf\xc1\x14\xda\xdaxkb\xe2\x1aM\x05rm94\xe4Zs\xe8\x08\xa1\x1e\x1e\x0e`\x87\xe2\xc9^g\xce\x0d/3x\xc4\x01\xe85\xb0w\xd6\x95\x97\xa3z-G\xee\xb9a?\xf8\xb6\xc7\xfc\xda{\xed\x018}c\xc0!P\xce]\xcb\xc5\xd6\xf77\x83m \x9c\xf5n\x087\x9cC\x12\xef%\xa8di\x9d\xf4\xfa/\x8e\xdf\xcf9\x1dhS\xe6\xdf\xf9y\xd1\xbe\xfd\x06\x06\xb0\xdf\xbe\xfd\x9e\x9fR\x95tW\x19K\x8eW\xf3\xd3,\xe5\xeb(\xfe\xea\x8bM\x9d\x19\x8c \xcf\xc4I\xa7^0\x1cm\xaf`\x00\xef9\x8e<\xb3\x1d\x01\x1f\xcd4\x87\xcd\x92\xa2O\xc9%\xf3f\xc6?\xab\x95\xb2\xe8\xa8\x94\xc1\xa4Z(\xbe\x05\xf7j\xcb6\xe4\xdf;\xa8(\x1cB^\x9e!\x19\x1c \x91v\x9e\x86\x99Y\xb2\x9bd\xd4v\xe2z\xd2\xea\xef]T\xc19$\x81~\xcequJ\x9a\x96A\xfd\xe1\xe6>\xb7~\xf4ec\x9f\xb8\x19\x83\x866H\xb3\xf4!\xcexu\xf1\x93\xb9\x0be\x91\xe1C\xb5\"\x82\xd4!\x08\xa3\x85\xdf\x8c~tw'\x0e\xd3\xf7Hk\x87\xefG|\xcb\x90\xe1\xb3\x91a\x08\x0d\xb5\xcc@?\x13\xd5\xf0\xbcF\xf4\xb3\x07\x8c\xd5\xc9\xabCXp)^]\xbcpv\x81\x1a\xa0\xe6\x91\xa3\xb6cB\xd0 \xab\x84\xe8>\xcb\x8e\xc9g\xbc\xa5Z7\xb7\x0d\x1aP\x0b\"\xc5'\x93M\x18\x95X\xe4\x02\x181\xae4(M\xa9M\xbfut\xb9 cF&\x82A\x83,\x87DIE\xa27\xc8\xa6b\xcb\x15\x11\x7f\xfa \xa5\x1b\xf1\xe8\x00\xb5\\\xb6n\x8d\xab\xc8\xaf+_d\xfb\xf5\xcb\xe0\xdeg\x19\xcab\n\xe2r\x11\x96\xed\xb5 \xfdi\x9e\xcd\x8f(\xcbW\xe5\xcb\xc4w\x94/\xbfl\x94\x86\x81\x11} |\x9cR\x8aT\xb7\x96\xdec\xfb\xc19\xb6\xe0\xcb\x07\xa7F\x13\"4\x19\xdeo\x8cL\xff\xf5QSU\xb1\xec\x98\xe5 =s)\xdd\xb4\xc1\xf6\x86\xcf\xe5\x01=\xea\xd5{\x88\xe0c\xff\xe5\xd1\xaf\xc70\x80\xe7\xfc\xef\x9f\x1e\xbf\xfax\xc4\x7f\xfd\xce\x7f\x1d\xbd\xf9\xf0\xfe9\xfe|\x13\xd5\xfaOh\xc1Q\x1f\x06\xcdQe\xcb|Le\xf2\xd9\xb3M\xd3\xd8^\\\x7fQ\x11|''%\x00{|$\x7f\xf6\"\xe8]\xf5\x9cc\x1e\xc7\xe3\x19yO\x8a\x0e\xeb\xa8\xd6\xd5\x96\xe8\x0b?\xc4sOt-e\xbd\x8f\x14\x1fL\xf0\xfc\xd2\xdf\x1c\x88\x17+\xac\xef\xb3L\xc8\xb2a$\x1eI\xc1Q\xfbH\x9e-\xf2\x05\xd74\xca\xfe\xbb\xac\x18\xdaDR\"\xbdx\x04\xa3\xd8\xd2\x01\x98{\xc8\xf2\x0d\xba\x18wv\xc1\x82_#x\x11F\xf0km\xf1\x15\xbd\xf5\\\x133\xa6\xbf\x14-\xbf\xf4\xc7\xf4\x97\x0eL\x7fY\x1b`EI=\x9b6\x0d\xf1\xe5\x0d#\xfc\x90#\xfc\xa8\x8d\xf0/o\x18S\xf6\xbcz\xf8\"Liw\xc1\x82\x1f\xc4z\xfe\xe0\xbf\x9e?8\xd6\xf3\x87\x06\xe5b_\xb6\x96/\xfaI!Z\xc8\x08\xff\xa5\xb4\xb7\x1c\xbd\xa5\xba\x96\x8f_S\xe4\xbelko\xbf\x8a\xe0\x9f\x11\xfc\x12\xc1?\xdaJ\xd3\xe3\xa3\x7f\xa0\xc2\xd4&9\x12\xe2\x10\x1dOb\xe4\xca\xd0\xa3L'6\x1b\xb1\xaf\xcc\xd2\x83\xe2/\xa5q\xe9\x13Y\x15F\x1eR\x8cDr\x83\xd5PN\xf8\x07\xc2\xc7\xadF\x077\x19\x1auN>\xa9\xf4\xf3\x96\xf9\xa3\x80\xe1\xaf\xa0\xcb\xbb\xbb\x93\x86\xb3\xa8q\xef\xa9<\x0c\x86#\xaf\x8e2KG\xea,\xaa\x0c\x18\xff\xf04\xb0 7fm\xf0+\xdeZ\xf0\x95\xd4\xb5\x12\x12\x0cG\xa1_\xbbq\x07r\x08\xa3fR\x883\x0fy@\xd9\x05 \xdb\\\xf3\x93\xea\x8d\xdc\xfc\xc6\x1f\xd5\x1b\xd4\xfc\x86Q\xca9\xac\x84\x9cR\xf5d\x16*\xbfL\xd2\x19~\x8a\xe0|\x04\xfc\xb8O6\x92x6\x92Y\x97\x1d@/\xcc\xc2\xdc\x97OO\x08r74\x8b\xc2\x8d\xe4?7\xb0\xc5\x80\x1e\x06|(W\xd7k\x08)\xf1T\x97\x11\xc9\x9a\x99\x81\x9a\xd9D\xf0\xd2\xca\x91\xf0\x03\xa2\xb2l\xecE\x10\x0b3F\x0c\x0f\x07\x90<\x80\xd8\xeeF\x07r\x1cK\xde\xc6\x90r\xd1\nv \xe6\xb2\x95\xc5\xad\x0e\xd4b\x0b\xbd\x1e\x0b\x96\xc3\xbdQ\x84\x8a\xbb\xe5pw\xc4\xbf\x8c\x80\x84\xa5\xa6$\x86mh+\xe1\xa0%~\xa9K}\xd6zhU\xfb\x936\xab\x8c\x9et~Df\xfc\x17/\x93q\x85\xac\x90\x15+\xe7\x02\x0c\xc7\xc6\x8f\x81\x93\xa5P\x97r\xfe\xf0_X\x05\xfc\xedmx\x04 \x1c:\x1a\x07?u\xa7\xba\xacjOu]\xc1\x01|F\x07F.\xcaKL\x12\xe8L\x86{\x8d\x93\xa8\xfc\xa8}\xdb\x03M\xb2\xfc\x1ax2\xb5;\xb1*\xca\xa4y\x94\x0b_L\x8eR\x11XQ\x83\xe3M\xfd\x0c\xa3\xd5\xbe\x91\xba\xcf\x0c\x9bx\x19\xd0\xb0?\x8f\x17\xd5\xba\xbb\xda\x05m\xd2\x08Q\x0c\x1d\xa06\x10:Ts\x13b\x1d\xd2\xaf\xff\x81!\xa9-\xd0^t\xb4\xeaD\xd0\xeb\x99|\xcd\xf8\xd5\xeb5=\xf7\xf0;N\xd3\x17\xde*\xab\x85\xfbT1\xf0#/9\x1b\xc1\xa1\xb4 \\:\x7f\x95\x14\"\nfB\xc4\xf3_\xeb\xcf_\xc7\x0b\xa1\xbb\xf2\x1a\xce\xc4=\x1ce=\xae\xf9]\x0d\x14O\xdd\xd4\xaa\xe9\xaf\xf9Acf\xdf\x11\x1cwHe\xbe$\xb0%\xf5\xef\x0c-\xcc%Fm\xd9\x18%\xc1\x82j/\xeem\xa0\xa6\x97N\x08o\xa7V#\x06So\xb8\xb6f \xb8y\xf9f\x10\x868\xa1\x00=\x0f\xf4\xbb\x9bN\x10\xec\x93\xf4\xa7f[f\xc7Q\xd2'\x9f\x97qZ\xa0J\xde\xf4\x02\xd3^\xd8Ro\x07\xcc\x93#?\xf7Z\xf2\xee\xe5\x8d\x03\x11M\xa4\xd9\xb5+\x87\x07\xed&+o\xca\xc7\xda\xcd\xe6\xe7''\xb3\xb8\x98\xb5\x1a\xa8n\x97\xaf\xd4\x1e\xac\xd7B\x7f\xcco.\xe5\xb0\nu\xa3\x907\xc6\xea\xc6\x18=\xa5;\x90\xb2\xe9\xc1!\x0d\xd1\xf8\xdb \x1b\xe5Z\x81\x9e}\xe6\xb6\xf9H\\\xac\x06J\x88})#\x04\x1d\xe6\x8f>9'\xf9*\xe8T\xa8\xa8K\xb1B9\xda\x00\x83P\xec\x82Nv\"\xe3@\x98\x91 CNQ8/\x06\x94\xc3\x15o\xeeb\\\xa1\xed(\x00\xf4\xdf\x97\xfdq.\xc2c\x8f\xa8q\xda\x16\xa8\xe5gc\xee\xbc\xf1\xaaZ@\x0b\xcd\xd1\xd5\xbe\x88m\xda\x0d\xdbB\x90\xb4 \x0exg\x0d\x0f\xf9\xe6\xa5xK\xc7\x12\x10\xa9\x05\x81\x01$f\x08\x1b\xa17\x15\xc10\xc6/\x16 \xb6\x8frE*\xd1\xc7\x14<\xa8_\x1c\x9e\x9c\x13\xdd\xc2\xd8\xb4\x00\x9d\xa43\xfe{\x86<\x01\xe9\x9f\x11\xf4\x8a\\\x85\xfc \xbf\xab\xddB\x1cQ\x185\x95\x1ek\x06\x8a \x885V\xf1q\xaa\x11\x13\xbe\xa8\x0b/\xba7w\xd3\xbd-T4\xea\xf1bsM\x02\xe2\x1c\xbbj\xc0\x8c\x8fB\x9f\xa3\xbc\x1e\x1a\xfa\xa4\x86/\xcb\x1e\xdc\x86\xdd\xd2\x9fE\xfa\xbd\x84\x91zC}\xe8:\xd8\xfeY\x0e\xed\x9ff\xc4\xf9\xa7\xb4\x19tl5\x1b\xb4\xce:\xa0U\x8b\x8c\x11*\x02O_\xa1\x15q9\x0b\x99\x97b\xd5X\n\xad\x0d\xf3j\x9c\x91@\xbaZE\xa0\xe2\xfb\nF\x16\x10\xc3\xfb\x98\x9e\x118]\xc1n/\x8cpo\xe19\xb4\x1b\xd5W \x0d5\xe8[z\x1bv\xc3\x08i\xba\xf6\x02\xc5e\x94K\x18\x9f\x16\xe8z\xc8\xe0\xa1\xe4\xd8\xf8\xdb;T\x99pN\n\x16\xe75\xdd&\xa1\x13M\xb5y\x82C\xc3\xc1\xeaX\xa3\xa3\x07\xfe=&I\x1a\x04\x0cv8\x01\xbe\x0d\x94\x8bV!\x97\xcd7\xc3\x9d_JX\xfeb\xc6\x9d_\xbe\x0cwN\xcd\xbaD\x81/\x9aJ\xe9\xf1i\xc1\xf2x\xcc\x9a\x96 K\xb3'\xc4\xe5fz\xe1|z$\x9f\xea\x0f53\xd6\xf0\x1f#\x15`\x1a\x10\x12\xc1K\x8e\x19z\xdc\xc3\x19\xe9\x0c\x04\x82\x86\x15\x86\x93G\x94\x0f4M\xfb\xf0\x932g\x84\xa3\xb6gc\xa3\xcf\x8dL25\x7fY\xadG\xe9![S-U\x1e\xb2\x03\xc8\x85\x8b\xac\x15W\xa4\x8a\x88\x04t\xc80\xecn\x07=\xba\xb2\x11\n\x7f\xbc\xa3jgf\x1c\x15\xadT;\xf3\x9a\xac\x9fu\xc84Q\xe3\x14Z\x937\xbe\x95\x9956\x9bikJ \xaa7\xbd\\M\xa8/\xf4\xc3CbD\xf9Z\xdf\xb3\xb8p&\x02\x80\xa6\xa5S4\xdd\x08\x93o\xa9\x02\x1a\xbd|\xe9\xc6\x12\x9d\x8a\x9dU\x99\xaa\"\xc9V\xeb;-\x11;-\xe1;-{\x00\x89;\x16:\xe6\xdf\xe3bf\xb0\x03 \x1c@b\xd1\xf35vf<\x8a n\xee\xc6\xc4\xa8\xb4\xb5\n\xa3\x89\x17\xc8\xae\xb3=%\xb8\xac\xfbS\x03\xa1uw\xe6\x9d{8\xb9\x89=\xbc\xd9*(\xc8\xa1\xa65\xfb\xf7\xed\xf9\x98\xef\xf9\xd8o\x8fk\x8b8\x9cU\x87\x1c\x95\x87\x1c5\xee\x8b\xd2[\xc5c\xad\x91\xf7\x0dk\xbb\xb2&4iB\x86\x85{V\xd8\xf2SP7\xcb\x86v\x94\xb1\xe8$\x9e\x04\xd4\"\x83\x96\xbb8{\x00[\x01F\x9cKyT\x08\xa4\x18\x8b\xb7'\xb4\x10A&d\xe2\x08\xf2\xedm\xb9\xab\x1e\xd8\xa5\x91\xbc s#L+}\xf5\x8d\x025\xcb7\x86\xaaE\x9d\xf3D\xd7\x12\x8b\xed\xf2\xbd\xa5Y\xcb\nl\xbe\xd5\x98\xb6\x0e\x1dZ\x0e\\$\xe1\x8c\x8e{@,\x8dX(\xaf\x8d\x10\xe4\x12\xe5\xf3\xff\x02\x94\xaf\x0e\x15\xfd\x14)C\x08D\xca\xa2\xb6\x83\x80~\xa0\x94\xc6\xa8\x07\x1e\xcc[6LF\x11'T\xadC\xc226\xbeK\xa8\xa6%\x12\xbb\xe4A\x17\xdd\xa4.m\x12\x9a\xd8\x86\xc9H\x84C\x96c\x8b\xeb\x03;\xcdI\xfc\xa9\xbd\xa06lk\x1d[\xc6\xe5\xfd\x8f\xed\xbe\xc6\xc2Z \x9ai\xb1\x8d/\xdf\x08\xab\x8a+\x01\x8f\xaac\xb5Ka\xd8\xbdQA\xc1\x0d\x11\xa5\x02\x9eC\xb1(\x82\xf2\xe4\x1e6\xbe\xe6\xb4.+\xf67\x1f\xfa3\xbcsI\x03\xe6\xe4\xfa.v\x0dA\x1b\x0e\xa1\xf7\x9e,H\xcc`8\xea\xc1A\xf5\x0b\xbd \x98\xa6\x16\xda\x86^u\x0f\xbf\xe5wX2'\x05\xb4\x9d\x8e\xe7\xd7g\xcaML\xb8\x18\x82\x81\x01\xaf\xf5\x93\xd0q\xba\x9c\x10o.|Ft\xc5W;*\xab\xd1<\xa6,\xf0\x99Hm\xffpPYQ^\x8b\xd9\x13S\x85\x03\xa5\xad\xab\x8d\xec\x83\xb0\x13\xc3\x8e\x08\xa6k2\n\xcd\x91\xe6\xe4\x9c\xe4\xc5&n\xda\x1dp\x9d\x90\xcb\xb7\xd3\xeb\x83\x15\x0eQc\xb8\xb3\xe7\xec&\x8d\x0b\xf6\xfc\x06\xba\xaa0\xb4\xb3\xcb\xeb\x0bS*UT\xb9\xc4\x98+\xcaJ\xb0\xca\x03\xa36\\\xda<\xd1\xa8S A\xbd\xe6\xb2\xb9\x94\xb3\x11\xab\xba\x19\xb1Vl&<\x04\xaa(N\xc5\x02Q \x89\xd0\x98\xf0F]7\"~xP\xd8\x1a4\xa5\x91\xd2\x13\x0fI]\xf5\x0e\x87m\xcc\xd4\xa6z\xde\xb6\xf7s\xfa\xbe\x92\xf4}u\xc3\xf4\x1dU\xc6\x8a\xbc\x8b\x1f\x1au\x17\xda\xddm\xe8\xf5\xfb\xfd\xea.\xa1\x13\xd8\x86@\x08\x15\xeaE\xb2\xe0\xed\xc1\xe9\xaa\xf69Y\xf0\x86{!\x9e\x07\xed\x93`u\xb3'\x81\x1an\xa5\x8b\x84\xaf\xebCi\x9d\x11\xabk\x9d\x11\x8as\x08\x08\xec\xe8}\x87p[\xeb\xcf\xba?0@zW\x18\xe452!n\xf05B\x9d\xf84\xcd\x0c\xb6\x87\xc6\x90\xbd\xcf\x9d\xc6\xa1Rv\xaa\x1d.\xe8R \x02\xb2\xcb\xa7\x91\xb0\x15\xe0\x19S\xdd\x0d\xe1\xe1\xa0\xf4-]\x91`7\x82\xddP\x1eO+\x89\xdcg\x84\x05\xbaU@\x99\x0c\xf8}f\xb8\x8f k\x9f]\xab\xeb\x1c6\xe7eTemy,\xf6-\xf8\xbf:\x92\x0c\x06|.vi@d\x17p\xaf3\x94\xf6D\xb5\xd0\xb5\xf3 4\x13mp\x89\x03\xed\xc3j\xf5\x85\xe7#\x0eGB\xd4@sV7s\x16V\xd8\x8dz\xc3J$\xe0\x90\x93\xf2`k\x03S\xf8\x1a\xf3\xe0iw\xeb*G\xeaT9\xd6%\xc4\x08\x12\xa3\x06\xd1\xbcl\x19l\x8b\x11\xed\xf0\x01\xe4\xfe\x0b\xd4\x92\xd7\x8c\x00\xdc\xfc\x00\xae\x80g\x1co\x03\xa0\x969\xf9\x02\xd9\x0c\xce\x9b8\xec\x95 \x9d9\xd5!\x0d\xe8\xf3E\x7f\x84\x16\xc9\xbf\x98\x03P\xca\x17\x94\xd7c\x1f\x91kuC\x0c\xc1\x8a4\x16F\xf8}\xc8\x1fe\xb8\x1d\x9aU\xc5\x13\xfegy_\x92,\xf9 \x9eq\xe7ed\x91\x81\x8f8%*\x9d\xd3 \x89\xe0\x94\xe0\x9f\x17\xd5\x9fG\xea\xcfSRF\xf4\x887\xb5@\x1e\xf1\xbe\x0c\xf29jH0|\xa1/\x89-\xbb\x04\x9el\xc9|\x89 &v\xf6\xab\xd3\x8e\xdf\x0b\xaa$,\x11\xec\x87*\x7f\x06\xbe~\xe0\xbfk\xee\xdf\xbbw\xe7\x1e\xdc\xe2\xe7\xd9\x9a\x13s\xfb\xc6)\xdfd\xe2M;\x92\xe3^\xd9F\xb7\xbbG\x8f\x1e\xc1\xde\xfdP\xde\xe1O\x02V\xde|\xf8\x10\xf6\xee\x8b\xdc3!\xac\x9b\xce\xf8\xb6P\xa6\xe3._Il\x1en\xc1\xde\xee7w\xbe\xb9\xbb\xf7\xed\xfe]X\xc3\x9d\xfd\xfd\xbd\xfd\xfd{w\xbf\xe1O\xfc\x9c2\x9fZ:\xd2)&\xac\xd7\x8e\xe0\xeb\x92\x86Z4\xd5\xdd>\x8f\xaa\xa3\xb6\x07\xa3\xbb\xe3\xae\x9e\xb7\x9a#4Px\xc5\x18\xa8qY\xe6P\xa5=\x18\xd8}\xce\x12\xf4)\xdc\x92C\x15\x0e;\xc2\xa7\xc21P\xd0\xf0t\x17\xd66\xe7(q\xec\x8d\xe0\xbd\x80\xf5\x1b\x993\x83`:\x1cxF0\xf1\x19>\xe7T\x1c\x1b\xe7K}\x9d,\x0bp :\xdb\x08\xc7gq1{\x9aM\x88\x06\x19u\xcb\xa4\\\xc4\x96\xaa\x90-\x1d\xa4\x9e \xb43\x9e\x1f\x9a\xbe\xaa\x08\xbfw\xc2c\x8d\x84a\x97\x1a3\xa9\x9c\x0b\xcb\xaf\xc9\xf09\x19y}\xb9\xf5\xd6:n\xb05\xceOS\xb4q?/\x8e\xaaT\xd8\xe8\x0egz\xe25\x16[g\xdd\xe0\xd5\xbf\x96\xa3\xa0\xd9\x84|X-\xf8\x96\xdb\x0d\xa1\xb8H\xd8x\x06Au\xbf\xab)~\x8d\xe3\x82\xc0\xdeA\xe7{\xa0\xd1\xfe\xfe\x92&\x9f\x97\xe4\xf93\xfb\x1c\xd5\x85\xcd\x7f\xb7a\xf3\x93l\x8c\x01\xc3G)\xe1\xff\x88\xc96n\x96cp6mVj\x83\xdcR\xdaj\x19\xdf3\x7f\xcd\x97k{\xfb5\x89\xf4\xa3\xef\x16\xbc\x16{\xff5\xee}G\x88\xc8\x07\x12r\xac/\xa4,z=G\xd7\x06\n=V6\xd5\x01\xfe@\x97\xe7\xa6\xc7`\xefMFw\xc8%#\xb4H\xaa@\xc2\x02\xe2\x9c`\x92\xe38M\xb3\x0b2\x81\xb8\x80OdU\xf4\x9b\x89\xb3\x9b\xdd\xf3\x0de-n\xf1\xdc\x98\xc3X\xbf|\xd2\x11\xab\xab\xbb*\x86~iI\x8c;\xde\x94|\xbay\xf1\x01\xcc~\xb1\xea\xc2\x15j\xac\xc3\xa6$C\xb2\xc9Z$\x89\xc6\xc1\x9b>\x08\xad\x0d\xb9\xd5m\xfa\xa5\xcb\xda\xfe=\xf7\xe3\xc5\"]I6\xde\x12\xd1\xaf_W\x91\x83L\xf23\xb0\x03\xb2\xddD\xb0\xe6\x94^\x91\xbc\x16\xde\x7f\xa4\x08!\x96AA\x18\xc4@\xf9>\xa8 \xa7\xc6\x08\x19\x95{\xc2\x89\xfa\xfc*\xe7`\x9f\xfd\x06\xf4\xc4y\xeaot\xda+\xe5kI\xd68\xc3\xa0e\xb41\xe6\x03h@\xeb'4]\xf1&\x85\xd6\x14\xd5\xa4c\xe1\xd4{J\x80s\x0fd\xd2\xf7\xf4\"\xfdd\xe1\xedKu\x0c\x13\x8c\x92f\xa1 \xf5b\x16\xfc\x85;{\xf0\xb5HU\xd8\x1f\xcf\xe2\x9c3/\x8fY@Q\x98\xb1\x8aG\xc7\xa4\xed#\xad\xff\xe2\xbd?&U\xc6\x84\xa48*ic\x9bj\xbc\xf5\xdaa,_9\xf0V\xa9;\x8d4\xf3\xcf\xab\x08z\x7f\xefE\x82]\xb4\xea\x04\xc6\xb18\xe2]{\\\xf6cs\xf57\xa0Y\xd8\x16\x97\xdf\x91\x08>XE\xe6\x9fI\xfc\xe9u\xdc\xd02\n\x06/xGd\xe6\x02\xf9\x92\xa1qqF\xb6\xa1\xfc\x1c;<9I\xe6\xf3%\x92p\x8em''\x8d\x14\xed\x1d)\"\x03lE\xfc\x0e\x9e\x93&\xd2\xf3\xfe\x7f\xe7o\xec\xdd7$\xa6\xe4\x0f\xf6\xef\x192\x1f\xbf\xb7\x0cY\xb2\xf86)\xfa\x95e\x03\x9c\x91@\xc4f\xa1tV\xb9\xcd/H>\xcd\xf2\xb9P\x7f\xc7\xa2\x8d\x8b\x84\xcd \xa6\x90\xd0iB\x13F\xa0H\xfe \xbe;\xf0\xa3[\x8cw&\x0d\xfbE$\x0d\xfb\x8cMp\xfeb\x1c\x94\xf9\xd3\xf9\xb3>\x1f\xd9\xeb%\x8byO\x85\x16\xd6\xd2\xa5\xab\xce\xad\xe9\xed^\x91\x80*-?\xedO\xb3\xfc(\x1e\xcfj\xf1V\xc6@\x06u)R\x8a\xdc\x15m\xa9\x9b\xd4e\x8a\x82\xf6\x03\xe7g\xef\\ \x7f\x90\x8el\xe6\x1fI\x04'|\x9e\x1f\x89G2\x9d\xd2| B\x8a\xcb\x038r\xa9\x88\\\x8bd%!\x1d\x15\x86`{\x00\xfb]\xa2\x14\xda\x85\xe1Q\x95@\xc6p,\xbfN\x8a\"\xa1g\x82 \xc3^?\x91\x95\xc8f\xc1\x86\xd4\x94fR]\x82y\xe6/E\xfcU\xde\x97-\xdc\xbds\x9d\x11\xfc\xd76_\n\x85\xa7\x96\x01\xeau\xbc\xb0\xa6<\xfb\xf8\x85\x96\xc5\x93<\xcb*\x959\xff\x81\xa2s\x19K#\xf26\x85&\x93b\xad\xebb\xa3\xae\xff\xa1'\x85r\xcf\xa9 \xec9\xdd\xa0i\x9c\xc8r1\x89\x19y\x8e/\xaf\x0c\xd5\x0cm\xdfn\xba\xb29\x99g\xe7\xa4S\xd26\xccz\xe5nxBR\xc2'\xe0\xdbtk\xd6\xbeS^m:e\xd1IsA\xdc\x89\xa3\x85\x08Y\x92\x17\xa5G;\x94\xae \xa12\xce\x94\x13\x18\x92\x91l\xd4c,m\xf4\xb0\x8c\x06\x83]\xd1)R\xc6b\n\x14w\xf8\xc8\x96$\xda'\x91\xc4\xb9\x8c\x03\x15\xa6\x8d\x95]'\x1aw\xfa\xe2qr\x17K?<;Q<\x97)c\x12YM\xcbb\xd6RW\x01\x03\xc8\x82\xa5\x83\x06\xca\xe5*p\x02K\xe9\xac\xdb\x8e!\x03\xab\xd4qF\x82\x04cH\xd0p\xc3\xf7n\x04\xbd\x84\x9e\xc7i2\xe1\x94\xf8]\xccf69\x88\xcf&\x85\x01\xc4.\x0fT\xfe\xd2XNy\xc5\xa7\x8c\xd4*\xe5\xfb\xc9\xfe\x01?\x07I0\xae\x16\xd0\xa9(\x9d\xe2\xec\xc7r\xf6\xe2\xd7\x8a\xff\x92\xbb=H9\xbe\x06I\xc5\xcb\xb0\x10\xcf\x8e4\x82\xa9\x81\x07\x90{\x9eR\xd4\xe9Z\"\x1ee\xdfy\xd9\x9b\xe4\x9aZu\xd0\x1a;`\x9c\x92\xd8Y\x94Hk\xbc\xed\x16\xc3\x84?\x84Ym\xc0:\xea\x8d\xb3\xee\xf6k2P\xe7\x04J\x8b,_\xa9\xb8x-t\x11&\x06@\x8e\x86 b\xb1\xfeE\\<\x16\xf44@\x1f\xb6\xfe\xc9 \xa1\xc52'o9\xbd\x0e\xea\xc4[\xb1R\xce\x81\x97\xbd{\xee\xc1\xd6\xf9P?7\xf4\xd1pQ\xec\xd2\x0d\xb6\xb8x\xae41\x9b\xf5\xaf\xf7\xd3\xb12%\xc86\xebA\x9e[\xce\xb67spR\x1a\x11r\x01/\xfde\x9e\x8d\xbc\xd0\xbe\xd4\x89Y;\xdcKo\x1b\x94\x03\xdb\x99E:\x88\x08\xba3\x93\x80a\x82\x19\x86\x19eL6\xf7H\x94}\xea\x80\x80\xb6\xda\x9d{K\xed\x98\x8a\xc11`+?\xd2\xfeI*\xd6Fgk\xa2*\xaf\x03\xb24\xc8\xe15\x1a\xd2r?\xe8\x0c\xce\x9edp\x0c\xd3I\n.\xb9\x0f\xe0\xb3\xc1s\xe8{\x12\x01\xb2W\x8dd\xc0\xaf\x1f\xbf\xb3TO{\xc2\xdf\xd6\x81dS\x0f\xfedO\xfc\x81\xc3oOH&*j\x19\x1f\xac5>\x9c @,\x9d\x9c&l\x8e\xe0PN\xb14\x13.\xc8\xd4\xab\xcf\x9f\xaf\xd3\xe78[Rv\xed._\\\xa7\xcbOd\xf5\xa3`\x8aY\x0b\xba~\xdd\xfezs\xdd\xae\xbc;}\xd9\xdd\xe9 \x13\xa5FK\xa7\xe6*\xc2\x86V\xbe\xcd\xf1\xf8\x93H\xd3\xa9(\xcaW$\x90\xbf\xfc\xb4\xa1?t\xa6x\x14\x15\x90D\xc6\xaaVRJ[\xb3_u6k\xa6m\x1ce\xac\xe5o\xd1\xab\xf8\xc0\xe6\x8eyr\xb2\xc8\xc9\xb9\xc9\x14\xec\x97\x85\xe5\x9f\xbeIQ\xeb\xc5_\x9f8\xf2\xf6fJ\xaa#\x11d\xa5H\xc7\xf0\x87F\xe9\xa8\xb8!\xa5\xbb\\\xfc\xaa\x13\xbd\xcck\n\xbf8\x93R\x7f\x8fz\xed\xe0{>\xa0\x7f\x92`\xd73\xff\xdd?\x9c\xb8z.k\x92\x9b\x8d\x9c\n\x15-\xab\xadt8\x17\xc1\xa9\xc5\x9d\x12d~\xd8\x8b\xe0\xc4\xa1\xbc\xc1\x04pL\xf5\x86\x91/\n\xbc\x11h\xcaU\xb1\xb8I\x04q\x18\xc1\x96T}T~U\xe6\x0eD\x1e\\\x19~\x18$\xb2P\xd7!\xe7\x02\xa4\xf6`g\x0fK~\x1d4\xab\xc9\xf1\xeb\xcae\n\x17zvl\xc6g\x14{U\xf9\xc6\x9fp\x9bW\x93\x1cZ\xa1'\x8a\x8f\x19\x1f\x9b\x82@m\xc8C\xea*\x8b\xb2>c\x16\x95\xd4\x07Q\x97\xb4\xd5\x14\xa4\xa5\xa3@O\xb8\\p\x08\x19\xee6\x93\xbe\xc2\x82\x8f\xd2\xe9\xa6\xd4/\x89\x05\x8d`\xe9\xe4U\xb8D%$\xb6\xc0\xf8\xe9\x01GD\xb9\x9e\x84\xf3#G\xc12\x8c\xe0(\x881\xeb\xc3\x05?'D\x0e\xd7!\xff\xcc7\x9d;cn\x1e\xaa\x95\xa8\xf4W\xe1\xf6\xd9\xba\xff\xc2\xcf\x13\x976\x80c\xea[l\xcc\xf2\x08\x1b\x0c\xf8\x02h\xac\xf3\x8br\xa6\xb2\xbaP\x04\x99\xc9\x96\x83\xbbW$\xde\x0e\xaa$_U\xcb\x07\xda\xdf\x8f\x1e=\xe2\xf4\xe3\x16\x9c\x99\xf7\xf9\xb2\xde\x08\xba\xe9k\x1fY),\x1f\xef\x8f8^\xaci\x1b\xc3Z\xfc\xb1\xc4qI\xbd\xea\xb0\x82\nl\xc3\xb9\x84\xccH\xe8\x15\x07\xf5\xd5\xcdB\xfe\xe5C\xf1\x1d\xe1+\x0d\x070L\" \xbeK\x9e3\x17\xbd\xac\x12k`\xf5\x82Z\x86\x02Z\x9a\xe8:\x12\xdfph\xd1a2\xb2\xd3\xcc\x02M\xb46\xeds\x1c,\xd1-:\xe0\xaf\x15\xf5\x8c\xc6>~ \xd3V4\xa1\xba\xae\xc2\x90\x1f_\x8be1\x0b\x0c\x9eEV\xf2\x12+\xa0e~@\xce\x9c@.w=zmUj\x95[\xb7\x00\xb3\xb0\xd6\xd4+\"'c\x99\xd8Wl\x7f?\xce\x12\xc1S\x82\xc9h\x87\xbc\xa3QX\xe3\xc8\x98\x0fG\xa6.\xe5l\xc0\x86\xb6\x04x\xea\xca\x10\xab%\xf9'5\x115FEKl\xad\xfe\x01F.J]\n\xd9\xcd\xb4\x99wU8\x8d\xf2|\n\x0b\x90\xd1a\x9a\x82W\xc9\x99\xd6\x8e\xb9d\xb7\xe0\xb8\x85\x14\xa9\xe8\xb2\xf9\x1f\"\x7f\x9dJ\xdb\xff\x0e\xec\xc1!L\xfa\x8bLT\x82\x98\x0cSN\x8dZ7\x86|\xe4\x9c\x1f\x9f\x08\x06S\xfc\x0e#\xec9hh\xff&\x95)\\ \xcc\x11L\xbaX\xd2\xab\x08~\xbc693F\x97!vY6+\n\xf5\\\\ \x82z\xfdp\x11\xf9IP\xf6\xb1hF\x12EC\x84\xa6\xd7J\xd8x\xc3\\\xce\xb9%\xb8\xbb24\x1b\x95\xb3\xc3%\x13\x8f03\xf2H\xc4q \x19\x89\x99\xd8\x89&x\xaeM\x17k\x99\xa1U\x02\xe8\xa7$\xc8m\xa0\xd2\x04D&Y\x1e\x8a@b\x0e\xa9\xb2P\xf0]\x9a\x9f\xa7u\x18\x9a_\x1acL\xe5\xd6\x00\x82\x14n\x81 \xb5\x91\xae!\xa1\xce\x1a\xca\x1c3AUtz\xc9D\x93\x08|s\xe7\x0b5B\\.\xf3;|\xef\x8d\xe1\x10\x16\xc3\xe9\x08\xdc!\xeb3\xa1(\x9b\x08\x0b\x8cX\xe8\xfaZ\x99g'\xd4\x04\x13\x8f\x83B\xc0\x01E\x97\x85F\xde\xc7N\xf2\xeep\xf3\xaaU\xfc\x92\x0c\x01\xdf\xcf\xa2\xde\xcc<\x8c\x103v\x1fHV\x9f>\x80%\xa6\xf9\xe1\xb81\x80\xbd\x10\xe2\xe1r\x84hp\x0b5\x0bl\x98lo\x8f\x1c5\xeb@\x13J\x87\xf9H\xa8\xb8\x84/|\x80 \x05\xb7\xb1\xda\x98\x81\x90\xf0\xc7\x8b\x08\xd2\x08\x96\x11\xcc,\x90\x94\xe79\xff\xbf\x08S/\xa1\xc4\xe5?\x16,\x86{\xf0/\x98j\x9c\x8b\xba\xe3h\x0f?\xde357\xab\xda\x99\x99\x11\xf1tSr\x7f\"\xd1m\x86\x14\xfc\x00R\xf8\x17\x92\xfd\x14\xd6`\xc1\xd0\x0b\xed\x93\x82\x05\x8b\x08\xa6\x11\xcc\"8\x0d\x9b\x01\xf8\x1d\xe2\xc7yY\xed\xa3\xf2\x80\xb0\x1f\xb5B\xbdZ\xa6\xbf\xc9\xb5\x08Z!\xc5P\x80O\xb9\xa7\x1eb\x99=Q\xf3\xacslz\x97\x88\xf6\xf5\x0e\xdd*\x8d\xa4\xfa\xcc1\x06\xb7\xa2#\xe9\x92\x16\xf0%\xb5L5\x00\xa8\xbbn\x19\xa2\x81_0\x80\xafH\x90X\xed\xe7\xe0\x14\x17\xc6\x19e \xdd\xa8\xf8C\xbb\x7f\xedW_\xf8\xccv\xecj\xa8\xb6\xa7mct\xe6J\xb5\xe6Im\x10\x90:0\xf9*\xa7|\x06s\xb8\x0dw\xdb-\x8f\xd5\xb3\xfd\xf6\xb3i\xf9\x9d\xcds\x7fa\xf1\x188\x97\xb1CG\xc6\x80a\xe4\x9b\xbb\xf3XZ\xe4\xea \xe6\xc9+\xa9\x9d\x99/\xa4\x18:\xec\xaa\xe7D\xdd5\x1e\xc4`r\xa9\x03\n^\x89\xe3:\x87G\"kt\x0e\x0fa\x0e\x87p\x81\x99\x07\xf2\x08U\x0c\x18g\x8a\x85 X@\xfb,\x13\xf2w\x88ei\xd9\xc6n1\xe8'r\x9c\xfc!z6\xa4\x01\xe9\xd2\xf4\x96\x9a\xda\x0e\x7f\x13\x93\x17\x89\x9f\xa7\xc5\xc4\xed0\xa2\xe5\x01\x99\xb1\x8e< \x0b\x16\xc1\x05\xe1l2\xf3\xc8\x03\xa2 \x1f\x81=\xc6r\xc1\xb4#\xeeKsZ\xbcJ\n\x06\xc3^\x04\xbdQ;\xa9E\xad'\xcf\xa4\x16\x89\xaa\x15_%\xc5\x0f\xcb\xac\xe4\xa4\x9e\x95\xdcq\x9ar\x01\xb6d-1I3\x8e<\xcb\x93\xb3\xc4\xe6\xd9\xa6d.\xde\x13\xed\x8b2\xa1\x04n\xc1\x99!\x14\xd2\n '\x0c6\xcb\xae\xe1k\xbf@\x901\x04\x99d\xabjU\xf3\x1dE\xa00\xb1\x7f\xe5\xc4\xc6\xe0\xa1\x96\x0dvs\x975\xc0c\xe1!\xec\xc2!|\x92\x19\x0cq\x9b\xed\xca\x08SqsW\xa8\x1f\xf7\xc43f\x8c.\x03\xb0'\xd8c\xe8\xfb\xa4\x16\xd3\xfcNe\xcf9aq\x92\xba\x19*\xe5\xdeo})q\x06\n \x14\xdfb\x94\xc08^\xc4\xe3\x84\xad\x84A|\x00\x97Xo\xbb\x195 \xe4A\x14\xb12\xf1R\xd6x\x89\xf4ORrN\xd2\xea]\xfb\"n%~\xe1\x06\x89\x08\x9b\xa8BL\xcbuV^\xf6b\x14\x1c^\x9b\xb8\xdc;7\xd3\x05\x82E\xac\x14~\xad \xa4\xcf13z\x17^\xb9\xe2,k\xdbj\xb3\xf4-H \xcaJ\x1c\x9aU\x03 \xcb,\x992T\\h2\xaf\xcah\xaf^R\xba\x0d\xf1p\x91&c\xe4\xdb\xf6lQ\xbb\xb5\xc1&\xb4 \xf9&d\xa0\xd1\xcbn'8\xfe\x0d\xc9$tjZ\xfeTK\xab'\x9b\xc0\x15\xe6\xf8\xd3\xc8>!%%\x81j\xd7NE\xc1\x19)'(\x16\xcbb\xd6\x05 %\xbcU\x11\xfa\x96]\xae\xc1\xc9\xca \xe1\x1b\x16\xbai%\xe0\x9f\x90\x11\x91dQ\xd9R-;\xbe\xe6\x16\xbc\x8b2\xbb\x96\x16\x11%w*\xe8*l\xe3\x1e\x1e\xe6^%\xd9\xea`\xcb|\xf3:|R\x87\xecn\x04;{\xeeV\x97\x14wWW\xcb\xad\xf5\xb8\x16\xb0\xad\xa1a\x9f\xf0\xc8\xd9\xf1\x05\xb3#\xfbd\x99HnH7\x07\xb1\x17(\x9a@\xee\x00\xf0&\x89W\x1e\xfb'^i\xf7\xe1\x95\x90\xa3\xd9\x91o\xe2\x95vw\x1b\xe4\x19y\xec\x97g\xc4\xdc\x87\xd7\xb4\xce\xaf\x93\xd7\xe3qg\x9e\x91&\x9fx,\x08\xad\xd7\x89\xa6o\xc2v\x11\x8dz\xcb\xbe\xf5\x97\xce\xbf\xa8\xee_9\"Y\xe2\xaf\xac\xfa\xe7\x1e\xddfI\x19\xca\xedi\x17gOJ\xe4\xb3\xaf\xcd\x06\x05a0\x14\xb1\xabB.\x9e\xa8\xa7\xec\xdfW\x04\x86b\xd1\xd6\x8d)\xd0F\xd9)\x9aur\xa5\xfe\xd8 _\xbc\x02\xa1s@\xa1\x04\xc1\xa2\xd7w\xa6\xd7\xad\xec\xdc\x98\xc8_\x92d\xe2\x82\x05:\x9b\x135\xb8\x9c\x1a\x87\xa3s7\x91\xc6\xdcl\x94\x90\xc2\xb4\\I\x81\x12\xf6\x00&\xac\xad\xc1\x9a\xb1v\xe2\x89W\xcf\x8f?X2O\x9c\xa3\x05]\x83\x9cM\x7f5gV<\xc0\xb1\xa3h\xac%-\xa8f\xd2\x8cn\xd3\x7f\x9d\xb3\xe1\x8c\xa9`\x90sV\x05\x83\x9c\xb32\x18\xe4\x9c\x95\x89\"\x9f\xc8\x9c\x91\xda\xbbx\xbf|[\xbd\xa5~\xe1\x8b\xa5\xfd\xed\x89\xb2\xc5i\xb7\xd5\x17\xea\x17>\xaaR{=)\xf3|U\x0f\xcadOOj\xd9\x9f\xf0\x85f\xe2\xa0'\x0d\x89\x19_\xd2\x93\xf4<\xd1r\xf6\xc8\x87z\x0e\x9d'\xb5\xa4:\xa2\x0b=\x03\xce\x13=#N\x04\xf3\xb6\x08\xf4\x84L\xb3\xdcd}\xb4iZh\xe9\xd0\x84\xde\xcc\x0c#\xdb\xca\x8d\x81\xeb\\\x86^hL\x97Y\xbb\x88\xfaC\xe1\x13e\x0e\xad\x15\x0e\x80\x8f\\\xadK=\xe1p\xc4O2s7\x99\xf4\xbb\x10\xaaHs/LT\xbd\xb0S\xf2\x18\xf4Q\x0c]\x06,,R\x1fs\xba\x15\xd7\xc0\x8c\xb0\x85\x1d\xd4q\x86!\x8e\x06\xdfJj\xa0jSe\xe3\x80\x85\x95,\xf3\x80\xf2\x12\x06p\\\xe5\xce2\xcf\x7f+1\xabTj\x8e\x13\xbb\x0f\xa0\x10.\xa6\x05\xfaIJX\x14\xa3R\xfc\xb2\x12\xe4\x0c\xddD\x96%\xf48\x8d\x0f#X6)\x98\x01G\x1fO\x19i\x1d\xef\x9d(\x1a\xd4q\x14\x83\x8c\xbf\x00S\xa5\xf5\x13\x85\xfa\x0e\x84\xcd\xdc\x08k\xee\xc4\x0b\x07\x93:\x0e\xda,J\x88\x839&\xcb\xe4\xd8\xa5\x83\xd1\x80\x82\xf8Rf\x86\x0c\x1a\xbf6DN\xb5Y\x9c('\x9b\x8ceoRY\x91\xa1\x92/\x92~mq9M\xceD\x85\x11\xc4udi\x1fog,\x82\x15\x8b8\xd3\xe0J\xa3~b?\xad*^]\x1d\xe2F\x08KEay\xb2\x1b_\xc2\x04-,\xc8\x1dQ3Ryf\x87O-\x91\x88d\x1cv\xc3\xc6\xc4\xa0\x16\xf7\xcc\xe7\xb6\x8c\xc0jc\xad\xe9q\x96\xb5rV\x16O\x13u)b\x12K\xff\xa5C\x85`\xe2x?PQ\xee\xf8\xd3\xce\xa3\x82\xf4K\x89e\xe5\xc3]\xf4\x8c\xdd\x81\xd8\xfd \xaa\x18\xf9k\x16\xbe\x11_y\x04s\xc4\x1d\xfe\xf2\xdca\x0f\x95@\xe8\xe4\xe1\xd5\x95\xa0\xe3,\x9fvZ\xee\x87SG\xd1\x11\xd0\xd4\x12X\xedq'\x85\x03N5\xdd\x9f\xc8\x96\xd1\xb3k9$\xe6\\)`\xdcvx\x97/a\xd1t\xcb\xcfPs\xdc\xb1\xac\xc2\xa9\xd5\x7f\x01S$/\xf5\x05L\xe0\xd1#\xc8\xdc\xdf\x8d1\x00f\x9b\x1f\xeb\xea\x03\xc72\x8d\xcb\x05\x1d\xdf\xf0\x82\xe2\xb9\xf6\xc0\xea`\xa1_|\xed\x8d\x19]L\x97Z\xf4\xa5M\xe8k^\x89,\xb2\xc7E\x9d.\x85|\xf3ZJUh\xe7\xcbv;\xbe\xba\xf80\xd2\x86/a\x17\x82\x83.\xf5#\x92\x8f\xe1\x00\xd2.$\x079\xf2X\xb8\xa2\x17\x98y?\x13\x87R\xc2Q\x83\xf2S;\x0b\xedn \xe0\x9c\x92co ]l=\xf6K(qaL\xf6c;D\x96\xad\xec\\\xe7\x0e\x8d\xc2\xb2T\x93\xc3\x0e\x17\x92\x96\x9a\xaa\\\xfc\xd4T\xe5\x0co(=9\xc5_U\xd6\xa3e\xa9$\xcf\xf0\x87&5&\xe2\x86\xd4\x97\xc7\xe2W=\xb9\xd7\xd2\x0b\x14G\xcc\xa5Q;c\x18\x06}\xc6\x07$\xec\xfa\\|\xf34\x85_\xb6\xa1l\x03q,\xfc\xf1er\x1ewL\x05\x11N\xf3\x0f\x15qS\x8a\xd9\xd6\x07\xc8\x0b#^j\xbe\x14\x99kc\n\x96\xb3\x83sK\x1b\xc4u\xb8td\xcc\x19\x0b\x13\x9f\xb4\xe5\x89\x8d\xa1`\xe1\xd4$\x8d\xc5 \xa5\xf2F\x05\x92\x0d\x136\xde\xb2c\x18\xc0\xd8\x1c6h[\xd1\xa2>\xf2\xf2\xf8'\x95[\xa6\xdeUT\x83\x9d\x80<\n;-\xde\x12\x0e\xcb\x9b\xcaD\x16\xeb\xe3l\xc7 \xd8\xf0\xe6\xd8\xce\xd3\x95j6\xf4\x07(c\xf0\x88\xe6\x99J\xa4\x07\xea\x9c\x05\"?\x97dK\x91+\xe5\xa3\xe2\xe2\xa5g\x1a\xc3\xa7\xf6\x91\x94\x16\xf4\x86\xedW\xb7\xac\x9a\xf9A\xf1\xe5C!\xd0(V\x10\xb6\xe1\xdc\x86t5sD\xc9DJ\xbe\x15\xbf~ \xfc\x16\xd0\x15\x07\x0b\xab\x0eJ\x1f\x06\x11\xaa\x95\xa3'\x03\xffhg\x00\xe7N\xc4\xeb*\xf3n\xad\xe8\xe5L\xd2\xa3\x05\xbd\xa8\xa83Q\xeeX\x7f\xa2\xe2\x0f,\xe5\x8d5\xb3\xbe\x9en\x07\xf33\xd8\xd9\xf6\x0e\xf6?\xf1a\xff1\xc6\x03\xb6m\xc5\x19\x96\xa5\xcc\x8c\xd8H\x91\x9b>@\xb3\xd1.\xfe\xbd\x8d!c\xbc\x05\x83\xc7\x02\xc7\x87\xb8\xb9\xbf\x92.2\x15s\xdc[j\xd8\x86\x86_\x13\xa7R\x13\xfb+\xd1#\xd5\x91i\xac\x82N\xb7a\xccG\xfd \xc4\xe7r\x1fa\xf5\xac\xb4\xbe\xe3\x0fa\xa8\x8cG\xe9H\xee*.\xd8\x8da[e\x1f(\xf8\x9f\xe7\x86\x11\x8d\x85L\xc8\x1f\x8f#QF}\xcc\x0f\x00\xf1o\x82\xff\xba&2\x15\xd2X\x82\x11\x04\xf8\xe72|\x00\x0b\x0e\x11\xec\xb9\xe0\xbb\xc9k\n\xb5\xa1\x8b\xf1\x9a\xf1n\xd2\xe5N2\xc3 \x8a\x87\x18#!\xc8\xc6RH\xdc\x07|`x[Soat\xe3\xc4\xbc\xb2X0]|s\xeb\x16\xc6\x01\xa3h6i\xa8 :h\xc5\x1c#X\x90\x90\xa7bz\x9c\xdf(\x1e\xc0\n\x1e\xc19\xff\x87S\x82.Y\xe2\x14\x060E\n\xb22+I\xd4\xc5\xbb\x9bK\x92s:\x12\xfdV\xbf\xad \xa4\xcc\xfc\x9d\xfaP\xf4|\x8e\xb4\x0b\x060\xe9\xa0L\xa0\x18|\x05\xb2\x80/\n\xc6\xac\xcfj\x8a\x93\x1c\xd9\x98e\x88g\xdd\xa3\x01,B\x8898\x16\xb8h\xf8o!\xdc\x16*\x07\x85VSR\x0f(\xda2\x85O\x96\xee\xc8\\8\xce8\xa5B\xfcp\xae\x9c\xdc\x87\xa9S\x98\xe1\x0bs\"\x84\xeeG\x8f\xf8\x81\xeeZ\x18>\x80\x13\xa4\xae\x8b\xea\xf5\x10Ns\x12\x7f\xb2\x7fu\"\x05\xb5\xed\x01\x04bK\x85\xf05\x9c\xe0&\xd9)!#\xf7\xd3\xf0\xc4,\xdc\x9a\x177\x15X\xfdH\xaa\x11E;M\x90\x16|ev`\xcc\x97(\x15\xfb\xe1\xa1\xd8\x0f\xb5\x0f\xca\xe5,8%\x90\xef+\xea\xb2#\xa9\xca\x8e1\x8ar\xe3\x94\xa4KTkT\xc7\x89`\xbbI\x8d\x9d_V\xba\x1d\xc08\xce\xca\xbd*\xd5\xdd\xabf\xbe\xeeU\x9cL\\\xb0 \x16\xe2\x0eFj6\xa3\x1b-\xc7\xf1c\xbf|\x91\xb9\x9e/\xb2\x16A_eY[\xba#B0)\xb6\x93 F \xc6\x9a\xbe'\x15\x10~$\xf7l\x82\xeb++\xfd\xc5A!RJ\x8aU\xbf\xe9\x94\x92\xb9\x88GK7@\x8f\x04\x1e)\xa7\xc9[\xb7D\x82\xa8\xca+9A\x92\xa2 \xdf\xccrcY\xa9\xb7])\xe6\x84[\xf5.*\xe5\x94\xce\xfa\x9co\xcas\xaf\xf6\xdf\xb9\xdbw\x16z|.\xdc\xe1>\xb0\xaa\xbe#\xbf\xb5\xb1\xdf\xcd\xf9\xff\xfa\xfa\x8e\x1f\xdcP,Ka\x8e\x9b\x08gk\xf0\xb5oJ\xbe\xba\xea\xe1\x9dfT\xb1+!\xaa\x14\xe1(\x02\xe1\x8f\x03\xb4\xdb\xf7OD\xea \x91;<\x15\xf6e\x8f\xdc\xe1^sz\xeeT&\xac\x842a\xc5{|\xcd\x02Q\xdd\xe6\x88\x05\xadP?K\xeb\xbf\xbb%\x0ci\xda\x89\x14KoM\xbd\x14K>8)\x1c\xfc\xbcHI\xc1,\n\xff\xa2\xe2\xf8\xf9\xd1\xba\xb4\xa9\x12\x06\"o\x93\x19o\x85~\xa2KQ\x18K\xf28\x10\xda\xd3\xea\xe7>|\x0d\x89r\xdcD\x1b\x910V\xb6\x93\x9fZDXu\xc9\xfe\xb5\xf9H\x15\x0bJk\x96}\x14\xf6Y\xf6\x92\xac\xc8\xe4\x98|\x0e\xc2\xcd)3\x19\xeeZ\xb8\x86\xb0?M\x93E\xc0;x\x1d\x8b|:\x1anr\xa2\x9b\xd7p\xb5\x8e\xb9\xba\x933:\\\xa0\xf1L\x95}c\xa10\xfe)%\x86\xe6\xdc\x1bkj\x0bND\x96J45(/\xb5X3\xabm\xa6B\x80\x18Qi\x19\x0e\xf7F]\x8b\x9d\x0b\xd5\x9eXG9\n\x91j\xdd:\x081?\xe9L\x1f+\x12Z\xb5\x10\xcbB)\xb2\x19+\xc9\xb0\xf1=\xb9\xfc\x9e(\xca!|\xc3%\xe5\xc8\xcc\x9c\x0c\x07\xe3kt\x7f\xf7\xcc\xbc\xfc\xa6\xc3\xeb\x04\xdd\x954\xaf\x93\x93eA^\x92U\x01U)\x0bE\xf1\xdaI|m\x9d\xbe\xb7\xd0tc\x8f\x9b7\xff\xec\xafm\xfe\xd5_\xdb\xfc\xc7\x8e8\xb6\x7f0W\x8aXV\x1bA\xbd{~\x83o\xf1.\xafN\xad9CR\xe6\x08\x8b9\xaa\xe2%\x9d\x0d\x9d\x97e\x92\xe5G\xb2\xfe\x19\xfa^9\x15b\xfe\x83\x05}7\xc9n\x02\x0b#\x12\x99*\x8a\xf09\xcd\xe2\xa2\xd3\x0d\x15\xf4\x8e\x12:N\x97\x13R4\xab\xda\x97-\xaa\x176kv\x16\xdb[\x1c\xc7\xe3\x19yO\x8a%\x86Q\x12\x1aaE3\xe9Q\xf8\x91\xe2\xe3Z\xd9.W\x04\x93\x12C\xcc\xce\x14P\xa7P\xadzV\x9e\x8c\xa1\xf4:\x14\xbc\xa1]\x1da-v\xa5y\xa7n:?\xa1\xef\xe5\x07\xc1\x9b.\xa9^i7UW\xa2]\xbb\x98\xaeXx?'Vu)\xbbf\xee,_\xab.\xe4RHg\x1d[uU\xfb\x0c\xdd\\\x87\xbb\x1d\xd9\x90\x00\xc3:\xd5\xbb\xda\x87{\xa3H\xfb\xbb\xe5^\xd8\xbc\xdcfQ+\x19Q\x97-\x8b\xb9\x1f>\xf2\x95\xc2\x15\xfe\x9d\xcbLp\x00\xbf[\x11\xa9v\xd3F{?ws\xba\x9d\x148o\x12\xdd|s\xd2b\xa7\x01y3\xa4\xd3\xa7\xa82\xc6\x81bbz7\xc5\xadj\xa6d\x18&\x8c\xbe\xf6\xa2\xc4Nn\x14\xedp@N\x02\xe43\xbck\x13\xa0\xac\xc3\xd9\xa6N\x83\xf2\xa0\x9a\x91\xfaXZ\x04mD)\xeb\x98\xb2\x99(\xf9\xcc\xb9\x86\xc3o:\xeb*o@i\x94\xf8\x9atR\x19t\xb4\x93\x04F\xc9\xaf\xf6\xb7\xcf\xa5OZ&h\x83\xdbE\x05}\x13\x9c4H\xc9\xef\x1cZ\xcbHC\xb6\x18)\xd0\x92\xe3\x9bq\x01\xc0\xa2NhUE\xb4\xec\xf1\xef\xbb=\xd7\xdc\x1b\x9c\xea,\x16m\xeev\xba s\xe4\xe2\xb2\x88`\x7f\xd02\xe7\xcd \xa9S\xe0\xa3y\x06\xa0sW\x1b\x8c\x13\xf4\xbd(\xa4D\xdb\x961pW\xa8Yj\x90-W:\xc1\xb2'\xd4\x04\xc8\xbc\x8f;{\xb0cHa\x0d\x92{h\xd2X+WP\xa7\xb1\xb5\xc6--_\x8f\x8d\xeb\xe0\x0e\xa9\x81\x97\xa3\xe6\xe8\x90\xff8\x0f\xd7Q\x8c\xe4*\x82-\x1b\xec\xcc\xb1E\xae\x19\x19\xcfx{\x0f^[\xfe\x0f_\x95_\xc7\xc9\x8e\x9b1k\xa2\x9a\x15\x8f\xcf\xcbD\xbd~\xc7o\x86\xc7\xd4\x8a\xf7\xb2\xb5U\x11\xc4\xccq\xfaf\x7f-;P\x8e\xa7\xcd\x0bH[\xbb\xa1\xb4P(t\x98\x0e\xa6\xc0\xe5My\xae\xc5 \xd8\xcf\x98\xa5\xb9*/t#|\xe2p\xeb\x05%5\xe8|\x02~P%R\xdc\xde\x8e \xe3\x0d\xe5\x12\x02hn\xb6\xe7\xf9\xe4Sm\xfa\x84\x81Z<7\x1f\xe1\x03\xa6&\x1f\x918*/v\x03m\x036\xc3\xd3\xf9S\xe1\\\xdc\xc9\x8d\x80\n\xca\xa8s$\x89\xfb\x0be\x08K|\xb8\x12\x906\xb1b\xb8\xeb\xb0\x9a\xa9\x0b\xb3Y\x1a\x13\x83\xeaW\x1d_\xc6h*\xd4r\x02}\xc6\x8a\x882\xb7:\"\xcf\xd8\xcap\x82U\xf01\xf3;~\xb6\x81'\xbe\xc4\x8fX\"N\xf9\x0c7r#\xe2B\xc4\x1e\xdcF\x1f\x1c\x0cDD\x9f\x1c\xf9\xfe[Y\xc1,\xeb\xcc\x9b\xc4\xd1\xe6\x9d\xa8cf\xb7'|@\ni \xc8\xe1\x04\x0c\x12X\xaf!\xe6\x7f\xc5e\x8f\x1c&}\x96 \x15\xbav\x10\x07a\x05)\xf3\xa0\xa4\x93w\x0c;&\xcc,`0\x10\x9e~\x01\xdfl\x85tD\xda\x85\x03c\xa5\x89s\xe9\xd5\xe8>vR\xc5bV\xe1\x06K\xac\xac\xa5\x8c\xa1\xcb\xca\x80\x18\xc1\x16\x9eR\x992\x8b-\xcb4>A\xda<+<\x8ea\x99\xe1\x86\xc9p\xd3*)\x10\x93E\x15\x15\x93\xb6\xcd\xe9$\xa6\x9b1\xf8\xb1\x85\x11\xa4_\xa6\xa7\xca\x9c\xe09\x96!\xda\xa4\xc2\xbcf!F\x11\xb4\xdd\xe5\xaf\xf45\xbe\x9e\xb2N\xda\xf4x\xff^K\xe4\xd6\xd3)\xb4\xd1Zm\xab\xf8\xec\xeb\xe3\xb1\xbc7|\x96\xaa\xb5z\x10B\xd6yZrxmo\x17\xf0HC\xf9\xae\x93\xd8+\xfa\x1d\xba\"\xe0\xf9u\xe5V\x13\x10T\x13tM\xa1\xe4\xaa1 \x96\xd2\xe2\x11\x0c\xb0g\x91\xa8\xa3\x13\xc9'\xcfU\x92\\\xf4\xc6\xd05\x95\x9b(\x08\xeaXk;0\x7f\xf2=0\xddd\xfb\x86x`;\x19K|\xf6\x08 \x1c.\xef\xe72\xc8\xc2E\xa7\xba\x11\xdd\xc1i\xa7\x9d\xa4J\xa4\xe4\xc6\xd3\xb2\xc9u\xa7aE\xb5\x8a\x16\xdb]\xb8\xd9\xee0\x02C\xa0\xe5\xcd\xf0\xdc7\xb0,Y\xee\xb3.\x9b0\xf7_~\xdel@\xb0p\x93\xe3\"\x19\x12\xb5\xabk\x92uP\xa4De\x1d\\JZ\x11\xd6Y\x7f\xa4\x0cY\x832d\x918\xc2\xb2.\xba\xd0-7L+\xabG\x07\x8f\xcf1\x04+\xf9\x8d\xf1/\xde\x81\xe0\xf2\x8a\x1a\xde\x8ee<\x93\x83\xbd\x87\x8bY\x92\x12\xb0:\xe5\x81\xae\x0e@\xdb\x95>\xf3\x04\xfb\xd8\x88\xe6\xf9 ?\xde\x88\xe1\xe3\x8b-\x01\x0e\xfcE:e\xa9s$\x07P\xce\x86\x04E\x07\xed9WUC\xac[\x99_\x85\x89\xb2e\x1d\n\x04\xd0\xb8\xe7-\xf4\xbcJ\xe1!\x16\xac\xb9\x05q\x80U\xfb\x90(\xa7\x18\xa8\x0d\x07*M7R\x04*\xcb\x01$()\x86\xa5$\xb1\xb5\x8b\xc59\xedxeW\x95\xf3\x85\xe5_\xb7K(\xfd\x15\xa6\x8c\xdc.\xae\x81\\\xc5aG\xa1\xf3\x1b\xa3R\x92\xadJ\xbc\x94\x14\xc4\xcbd\x02\xea\xdc\x92\xa9\xe672\xcf\xa6\xbe\xf4\x06d/\xb9\xa4\x00\xa5\xfb\xf5po\xc4%T\xd4\x10\x06K\x15O\x81\xd8\xc5\x8f\xd18H\xab#\x93\x96\x84#\x8f\xc4\xf9\x99v\x93E~-\x85sn\"K\xa3\xa5\xad\xe5u\xb6\xa0\\\xb4\x90\xac\xa3g\x97\x1di\xbb(`\xd7\xaa\xdd C\xbb\x01E\xf533\xfd\xec\xa4\xa8\xc2#\x13]@M\xf2\x8b\"\xb8Kk\xda\xe8\xccN-\xc5\x9eT\xda\x8d\x9a\x83 \xeb(\xe2$\xe1>\xccq\xe4\x99(\xbdx\x08\xe2C\xe9^\xc6\xac\xee\x83e\x96i\xeb\x11\x91\xf4\x8b,g~\xd2\xacb\xa2\x022\xbc3\x8a\x80\x0e\xef\x8c\x10\xcb\xc9p\x7f\x04;@\x87\xfb\x86\x0c\xc1aU\x90\xbc\x91\x95\xc1j\xb1I\x86l\xa4v\xd2\x00\xf6\xdbm6+\xf4\xb9\x1a\xe2\xa0\x1f\xee\x99\x06&8\xd7_e\x8d\x0f\xe1\xd6\xfdR\xfc\xfa!h(\x04m8\xf5\xc2\x89S\xc2\xdfE\xc3+\x0f\xbb\xd1\x17\xe2 \x1fJ\x89\x1bV\xbc\xc8\xc9d9\xde@\x87![\xff\x15=+\x05;G\xd1\x87S(*,\xf9\xf2\xdd\xb6\x0c\xd4\x8a\xe5&\xdfWG@\xca&\x03\xaf\x0f:\x12\x89\xf9\xcc\xc3\xf5\xf4|\xff\xd5\x8b'\x13\xf5s\xec[N%\x8f\xbfu\x0b\xa8\xa6\xbf\xad\x85M\xae\xd7U4\x82\xf8\x05[\x03\xde\xedz-b[\xbd\xc6\xfb\xb2\x8a\xbf\xf8\x02\xa1Y\xea:\xf91OH\x90\xfbz8\x97k\xd6\xf2\xb3\x04\x81\x84\xf3\x84\x06u\xcb\x14\x0c\xfc\xf6u3\x0b\x9f\xf0\xf3\xac\xce\xc4\xdfE\xbcv&Bx\xb6T\xfd\x0bM\xa2\x81Z\xfa=i\xa9\x10\xe4\x95\xd9\x92\xf0\x81\x06\x94\xf6|\xba\x05Y\xe2\xc1\xb9\xe5\x9e\xc0U\x97\x022_\x1f~2\xc1O\x01\x86\xb0W>\x97\x1c\xdf\x1d\x07\xfe\xf5\xf5m\x1e\xec\xff\x06\x9c!\xaef\xa7\x00\x86\xba \\\xce\xe4\x9a\x80\x92X\xe0\x02\x88H@\xd2/\xb29\xb9N\x07\x1c\xbd\x1c\xcd\xcb\xfaR\xffFFJ\xe5\xc7\x8c\x11\xbb\xa5\xb3\xaf,Gq](\xe2\x00]\xb3\xbcy\x81\xf8\x87\xce\\\x08\xc2\xc4\"jr\x90\xfe8\xa3\x05\xcb\x97c\xd4,\xfb\xd1\xf7\xaf,\x8e\xdeI\x99\xcdFD a\x89\x116\xcb\xb3\x0bD\xf1\x0f\xab\x059\xca\xf3,\x0fzG\x97\x0b2fd\x02\xc3\x97\x11\xfc4\x02\xb6\\\xa4\xe4\x00z\xb0\xdd\xcaHk\x19\xc3?\xdd\xd1U\xaf\x88\x8cG\x08#x\xea\x1b`\xf5\x8b\xbb\xcd\xa5\x00[^\xb1A\x19\x17x\xbd\x9a\xfe\x87\xbb\xe9z\xc4V {\xfaUc\xb88\xb7\x15j\x81\\^\xbd\x12\x8f\xea\x1c\x9c\x14\xd7\\zT\xee\xf6\xd6\x13\xb41\xce\x9aY\xdd\xf1-\xe9\xa4/\xf3\xac\xbf\xd0\xb3\xcbW\xdf\x0bm\x13k\xa7.\xb5\x8c\x9eu\xe6\xba'\xf0Hf\xa3<\x10\xc5>\xe0\x10v\xf8\x0f\xbfs\x9fZ\xb6\xf2\xb9\xf4E\xfb\xc9x\xe0\xa3\x14m\xe7\xa5\xf9\xd3\x9f=0\x1f\x8f\xc0\xd3\x94@\x96\x03\x06E\xef\xa4\xc9\xa7r\x0f\x98I\xbc\x18\x14\x1f\xb5\x81@X\x97\xd9\x0b\x16yG\xe2d\xc1A\x94$\xd0\x99SLX\xb0\x13Z\xb0\x98\x8eI6\xd5*\x9e;\x9c\"\x10r\x88\x1e\xf5Ok\xc9>\xf3\xc0\xa6z.\x9bpr\xe8\xfc\xa2\xa8\x96\xea\xd6\xb2\xc6U(\xe5'\xb2*\xac~\x89\xea\xda\xf2\xe3\xca\xf4\x8b\xe5+\x8f\xb7\xf8\xc5\x8c\x11\xae^\x9d\xa8K\xceeB\xa6 %\xef\xf2lAr\xb6\x92\x9c\xaf\x7f+\xfc:#L\x13-7\x19\x83\xbat\x12$\xc2&7j\xe2\xaa\xdb F\xbf\x8a\xdax;\x8fo\xd3uF\x1a\x89\x98#\xe8=\x8d)\xcd\x18o\x1d2\n1\x85\xa4L\xcf\x9b\x93q\x96O\xfa\xbd\x92d\x8ah;\x07\x8bi\xba\xba3\xb7\xa9\xcb\x12\x8d\xd0\xbc\xae\xfa\xa7 \x9d\x04U\xd4]\xf7gW0\x8e\xd9x\x06\x086\xf7\x80\xae\x02\xe5\x9a\xae\x8e\x88X\xea'\x90\xeb\xa7\xf1\x9c\x94\xa1\xc3\x9fD(^\x8c?&d\x1a/S\xf6\x13\xe7\x960\xe7\x8c\xb5\x1b\xfb\x00\xc4\xea\x88\x80\xc3\x8f\xa4\xa9\x98P\x97\x05q2\x94)\xcaS\xab\x15C\x9d\x99t]\xa5\xe4\xa7\xb1P\"\xda\xb1\xa9h\xd3\x7f\xb1\xe0\x1d\x8b\xe0#gL\xde\xdd\\\x95\xaew7Y\xa5\xebm>!9\x99\xbc\x8e\x17\xf0g/\x82\xdeU\xbbV\xd7\xbbk\xd4\xea:\xd7k\x04\xf0\x95\x125\xfc\xed\x90\xadyh\xc9b:\x18F\x8a\x1f\xd2PT\xa6m\xd5\xd0z\xf7o\xaenS\x96\x9d\xe1S\x92I\x95\"}\xb4\xb5{\xa1\xcc\x88\xe0\x1c\xf5f\x95\xbf~g\xae\xdaG\xef\xae_\xfbHo\xb8]\x06\xb5\xd6p-\xf5\xb8\x0f\xb0+\x90U\x9f\x06\xa8\xb8\xd1 \xa7?rv\xbf\x91nDGD+\xf2i\xa30\xd8\xd2\xba\xdc\xe8E\xbe\xb9\x80\xa1\x0e\x90\xa1\x05\xd6\x12\xde\xe57/\xbf\x12\x17\xed\xa1O\xf3l~DY\xbe\x12\xbaRM\xf9\xd3\x8d+\x9b\x15J\x10\xc2\xdf\xa0U%\xc1#\xbf6\xab\x11\x85Z\xb7V3BEH\xe4\x12\xd5?\xb2.+\xdf\xd5\xaf\x99t\xe5$\xfe\xd5\x16\xd4\xd1\xc2\xf4\x9d-\xf2^\x18$\x1a\x84dRh\x84t\x00\x1fX\x1d\xbe\xc3\x99\xaanP\x83zY\xe7\xc0\xb0o#`\xc1\x1b\x16\xc1\xafa\x04o\xaeA\x81\xdb\x82\x1fR`\x13&\xd4\x9ao\xc4\x0dt\x96K\x13m\x8b\xa2i\xce\x86Q?rL>oD3\xb0q\xf5e\x9b.\xbc\xa9\xc3\xcd+T\xe8\\\xab\xc8l\xc67\x0e\xdf\xef\x159\xdc2%\x1b\xac\x8dQ%\x1b@\xa3\x86\xf74A\xd7\x1d\x89y*+\x87=8\xfc*l\x05\x896\x80 0\xb7\x13;t\xb2h\x06\x02\xa7\x02\x9fk\x87\xcd\x06`\xc8\xaf\x03\x06\xda\x00\xc3<^\x18\xf0\x15$\x18Z\x85_\xde|\xd9\x19\x119B\x94\xda(\xa99\xe0\xd6&\xaf\x99\xf3<\x1c\x97I\xc0l1KW\x9c@\xa9|\xcb\xff\x14\xeb\x10\x8a,=e\x0fV\xd5y\xd9|\x16\xc9|\xcd\x14\x0eD1 SWa'Q\xd8\xechB\x1b\x9f\x0e\x96\xd0\x01Au<\x99\x8f\x0bZ\xd7=\xb5\x0c\x1aV\xd4m\x82\xcd\xba\xa8\x9e\nye\x19\xa2N\xef\x8bRL@\x83\x8aP\x1a\xa2\xa2Y\xac\x02\x16\xc4G\xbf\xb0\xd2\xbcbZ\x0e\xd7RT' \x0b\xde\xb3\x08^\x86\x11\xbc\xd7\x97\xca\x14\x08\xe8I\xc4\xcbh\xc06%\x7f\xffe\x9b\xab\x93\xd2\xd8\xd7\xc7\xb8\xe9\xbcy3\xdca\x08r_\x96\xcc8S?\xbc\xff\"\x84\xbd\x11\x0ce\xbe\x18\xca\x14\x862\x85\xa1\xa2\xda\x96\xc2K\xaf\x9aa,x\xc6\"\xf8!\x8c\xe0\xd9\x97s\x10\x0e\xe4{v#\xc8\xf7Wb\x18\xf3\xc7/\xe3dn\x0c\xbf\xfe\xc3HT\xe1\xcf\x86\x88\xf4Jr\xba\xaft\xe8\x10)\xcct\xf1\x10\xedu\x94,D\xb3\x9fW\xff\x95\x88\x84\xc7\xa5\xed!\xbf\xbeb\x81\xb5\x88\x9e\xe6d\x11;\xdf*\xd1\x15K\xf4\xa30 \xaa\x12\xa3\xd8Z\xdd\xdc\x157-R,\xbf\xdaz9#\xa2\x1b\x81\xfd_\x83\xe8\x1e\x91\xa1~{\x01\xca\xf0\xca\x9a[\xb8\xa3\xa2\x86Z/\xd6\xe5e\x89\xde\x95\xae\x11\x82@\x0eS\x18\xa0~)\xde%\xee|S\x0e\x1e\xf7r\x06\x87\"\x91\x8b@\x89\x1cQ\xa2\xba\xb9'n\xee\xb5\xf3\xe5\xeb\x97\xc5e\xd1\x83&\xd4\xce\xe1z\x1a\x827\xf6G\xcf\xec\x8f^\xd9\x1fa\x8e\xaa \xa7\x11\x9c\x10.ZP\xed\xcd/T\xb0.\xa9\xe4A\xb7\xa1g\xd5\xb0\xd6:\xdc\xf8\xf8\xaci\xd4\xf9\xe7o/he\xf2qw\xe6\xa9L\x10v\xd0YY\x1d\xdd\x85\xe6\xf5\xcd[\x1b\xdc\x90\x18\xe2\x94ks\xe1\xe2\xeba\xf5\xb7\xd2Y\x18b6\x9b3\xf1R\xfeV\x92\x89Qe%\xfa\xbfuK\x1b@M\x9fk\x9eli\x1f\xd7l\x03v\x9dT\xff\x84\xcc\x17l\x85br\xf9c\x001\x95\xa2\xf6/\xa4\x9d\xf2\xb41UO\x8dq{\xd1*+\xb5\xb0P\xffM\xb3j-\xe9'\x9a]P\xf8DV\xd0\xfb\x1bl\x03\x81m\xf8[\x0f2\n\xfc\x97\xc2c\x8b\x91\xbc\x06\xbd\xad\n|\xb2\x98~Y\x8b\xc3\x8c\x14\x1ez\xc3\x9a1\xa1\xbeD\x85\xd2ku\xe0V\xad,\x846\x9a\n\xe7\xe0\xa0Z\x87v\x1d\xe6\xda\x1ax*\xd7\xed\x1b\xc7OCZ\x9f\xa9\xccS\xea\xca\xac\xd8\x9a)\xeb\x9ci\xfb\xe8\xae\xcd\xf4\x86\xb4\xfd\xce>\xae\xcf\x1eX!\x91\x07\x06\\k:jZ:\x00])e1Y_uk\xd8\x8dS\xbc9v\xf3\xdf8C\xe25\xc1\xff\x84 \xa1\xbeA62\x0dT\x1b@\x06\x0d\xf8\x1a\x04\x1ap\xa8w\x82\xcc\x16z\xd7j\xc0\xb1\x15\xa8\x8c\xc5\nuxO\xd7\xed\xd3\xf2\xd7\x19a\xefT\xf3o\xa7\x9c\xb4\xd8\x11E\x1b\x7f\xde\xcc\xe4\xed\x17(\xb2\xec(\x99--\xfe\xebu\xdd\xcb\xb0\xaf\xee\xf6\xde\xa3\x93D\xcf\xab\xb3\xc2\xdd\x993'\xfd9E\xff\xde\x94\xcacgk\x1c\x94\xc9\xe9\xf9\xb3k'\xa7O\xae\x9d\x9c\xde\xc5\xc1\x97\x92t<\x99\xd8\x8b\x11\x18\xb6\xa6\x17 S7 \xb7\x82-\x04\xe1\x16\x19N\x9b9\xa4\xeb,zF+[UFK\x0bUy\x1b\xeb`\x97\x0f\xda\xe5\xb73*Jdk\xd5\xb2\xab\x9b?'\x18\xd4\xa2\x1e\xf0\x9f\xd5\xc3V\xf9m\xf5\xe0\x19!\x8bF\xf1\xed\xfa\xc3F\xb3\xeaV\xfd%c\x01\xef\x8c\x1aJ\x8dg\xd4XA\xbc\xbc\xdd\xae \x9eQ\x8f:\xe0\x19\xed\xdb\xeb\x80\xe3CW\x1dp\x16\x144\x82#\x8ey\x05\xbd1\x07\x93\x82\xa2-Yf\xd0\xf6\x96D\x02Nq\xfb\x9f\x88\xb0?\x9bZ\xbd1\xa9\xaawL\x98U\x9a*\xbeH\x9a\xaa\xb8Vg\xbb\xf1d\xe2\xdb\xee\xa4\xc0\x9aq\xac\xac\xbcC\xb7\xb7CH\x026\xa4\xa3\xb0}\xec85\x8a\xe5\xb1\xcd\x8f\x1d\x8b\xfa\xc6x\xec(\x07\xa9Z$\xc1p\xb7yx4\x96>\xa1\x8c\xe4\x05\x19\xb3\x9b]\xfe*\xa3\x12\xf3\xab\xbd.0\xc4/\xbeC6\x94\x98NeS\x18\x9f\x17\xcb~-,0\xf0\x14N\xbfg\xd6'\xe7$_y\xb4\xac\xae\x12\x1dJ#\x8cE\xf5\x0b\x02 \x90\xcd\x93\xa4\xc5\xa6$\xeefZ\x1aHR,OY\x1e\xff\x7f8\xf2o\xc2\x91\xeb\xc6ry\xa2\x08&\xb2\xbai\x14Q<\xa4\xcf1\x85`\xc43G\xab\xe5\x10\x81\x93\xebi\xf4$9H7I=/K\xaf6\xd1q\xafCM\xd3\x1e\\[\xe7T\xdf!Y\xce|y\x819\x0d~.\xbdw:Nf\xde\xee\x93\x95\x8f^\xc2\xd08\xebn\xff/\xd2 \x15\x7f\xadz\x85iZ\x85\xb61\xcf#3t\x90c\xcc\xb9\xafa\xd88\x1d?\x85Xk\xc4\x9b\xea\x80L\xf9\xb0;\xd5[\xc5\x7f^\xfb\xb3\x99\xc2G\xf65\x8f?\x91\xe0\x0bu>8\xfb\xa48FM|J\xdb*\xa01\x8d`\xcaq\xac\xf7\xf7\xbf\x9f\x9c<\x7f\xfd\xfa\xe3\x87\xc7O^\x1d\x9d\x1c\x1f}89\xf9\xfb\xdf{mG\x90\x05\x7f\xbb\xf0P\x1aM:\x11\x81X\xaa5\xb1f\xb5&\x05\x05U([j\x88\xb1\x1c\x9c<4\xa5w<\xae\xf0|\xc1V\"|\xba\x04\xa3\x9f\"b\xd6\xbd\x17\xebJ\xae\x85#\x08\xa3\xcaf\xdf(_G\xd5\xb4\x88\xc8\xea]\xad)\xf3M\xc2}\xee\xa4Kc\xcc;\x10\x8c\xf9xg40\x99j,\xed\xce\xbf@\xa5u!TZg\xb4\xd2d]\xfc\xbfM\x93u\xe6\x86_\xa9\xee3\x14X\xd4\x7f-\xe8pJ\x95\x03\xddBSj-*\xa5\xd6\xa2\xae`R?\xeb\x0f$k\xb0\xa0\xba\xcej\xe1\xa3\xf0Y\xb8\x14>\x8b.\x85\xcf\x82\xaa}\x08\x038\xa7\xf2\x06\xdf\x8a\x88\x92\x11\xb0`N9q\n#\x98\xdf\x9cFh\xfe\x97h\x84\xe67\xa9\x11\x92\xfe\xf7.\xc5\xd0\x9cV~\xfa\x82r\x9f\x19(\xf7\x8aFp\xca\xf7\xc9\xdc\x83\x16\x9flJ\xd8N\xffC\x84\xed\xc2 \xcd\x95 l+>\xde\x13\x1a<\xf7/\xbby\xf4\x05\x84\xed\xad l\x97\x1aa\xe3\xb7\xfaKZ\xcc\x92){\x9c\xa6\xbe\xd1\xfc\x97\xde\x8a\xee\xa7nE\xf7)\xad\x1clO\xf5\xbdvA\xe5\x0d\xb9\xd7Np\xaf\x1d\xd1\x08.8\xb5<\xba\xb9\xbdvt\x93\xbb\xe2\x98\xc5\xe3O0\xe4\x1bb\xd4\xde\x10G\xd7p\x05\xa9\x1b\xe3g$6\x14\xaaG\xbd\x15\xd1\x92r\x93\xf0\x81H\xbcNvv\x1e\x84\xf8\xbd\xf0\xaa\xb2\xef\x058\x04\x99\x84\xc6\x14\xf7W\x1b\xf9\x82\x90O\x1b\x01\x88\x8f\xba2\x1c\xf2_\x86\xec\x1d\xad^\x96\xc5\xac\xab\x97J\xdbP\xae\xaf\x9f\xd6\xa1\xd4\xf4\x95\xce$\xb8\xfb\xb7[\xedD\x1a\x03\xcc\x07\x1e!0\x9bo\xc1\x0e\xecq\x88?\x12j\xc3\x9d\x9d\x10?\xb3\xf1\x05\x98Y\xa5lcH-\xb9\x0f\xf9\x825\xd7\x82_\x86D\xcbu|\xb4\x04S\x96\x9c6\xae\x87\x16o\xd5\xac\x18*\xef\xd6\xcb\x9f3\xe9\xda\xff\x98\x9a\xc5\x93\xd6\xe2=\xe6\xa4\xc8C0\x91\xead\xb4u\x05$\x0c\x05G\xe4^\xbf*\x07I\x87\xd4\x82\x0c\xb8\x19\xba\x1d\x9b\xaa\xe4\xed\xcb\xf0\xa0\x0d84&\xb2\xe4\xd9P\x00*4pT\xa7\x10\xeb\xdfN\x9d\x0f-2\x8aw\xca\xc0X\xdb\xfa\xb3\xc6\xfa\xd3\xeb\xae\x7f\xdb\xfd\xba\xb5\xfeYge*\x1de\x8b4\x19\x93`\xcf\xdd\xa6<\xa66i\x97\xa3\xa1\xa7:\xca\xd4\x95\x0f\x067\xbb3\x9d\xa2\x8d\xd67\x9fF\xb6\xb8\xce,6\xb12}i|\xb6D\xa9\x06\x06m\x82W\x9c\x15q\x83\x8d#\x89\xcf\x91\xc9\x89\xca[\xe9\xe8Q\x0e\xd6\xc7\x15\x8cbq\x11\xa2\x7fe\xd6p\x7f\x08jM\xd7-TeG\x17\xa49\xfa*M\x8f5\xc6\xaf<\x99\xf2\xda\xc9\x84e\xce\xb2:\xc9\xe2\x07\xcd\x83\x10\xeff\xee\xd3\xdd\xbd\x88yc\x11\xb3k\xad\xdfcj\xaa0\xddX\xc3\xcd\xd4V\xa5.\xa9\xad\xb9\xaa\x10\x94\xe3\xeacZMH\x9f\xcc\x86a\xc8\xfa\xcc\xf6,z\xa8\xa3kkAe\xdc\x81\xbe$\xd5\xd1\xa2y~\xb9\x90\x82\x8a=\x977\x10!\xaf%\x13\xccU0\x08\xd5\x92 \xe27y\x07\x13\xe85Y?\x1d\xa9\xd7l3\xb3\x0e\xb1\x9a\xa9\xf1\xec\xcb\xfdNn\xcf\xc8\x84N\xaf\x7f\xc5O\xe4]\xf1\x03\xb2\xdf\n\xd0\x91\xf0\xec\x17\xcb`Q\xd1\x98g(Z\xead\x1e\xba\xb2\xf393\xf3\xf9D\x05\x1c\xa1\xd6\x15\x85\x9a\x01\\\x1a\xa4\xf7c\x1a\xc1S\x93\xde\xf5\xc3\xe3\xa7/-\x9a\xd7O\xfc\xfd#\x0fi\xffq\xe9\xae\xd7\x91?\xb4.\xf3\x7frf\x94\xa9\x98\xe1L\xe7\x84\xb3\xa6\xa3^V\xd1\xbf\\\xfc\xaaS\x07\xbf\x94\x81o\x9d\xa7\xee\xb1\xd0\x03\x1cs\x80<\xa6A\xcb=\xc5\xd2\xe8\xbbnq\xb1D{\xabYR;\x9c\x86\xa8\xa3cCjH\x84k\x85\xa4\x9e\xbe\x8bU\xbc1\x0d#\xa8\\&\xb5\xd0\x88\xe3\xd5\xfc4K\xb1B\x82\xeby\xb3\xadf}|\xfd\xd7':|Z\xaa\x17?\xf9h\x03?\xb9\xb4\x81\x9f\xba\xb4\x81\xbc\x0b\xdd\xb6\xf6D\xb7\xb5E@\xfb\xcf+\x02\xf91\xe2\xcbDM\xe9\xbfdJl\x8f4_\xafH\xe0bE@.8\x91\xb9qE\xa6\xed\xeah_\xaf\x8d6zh0\x06U\xbe\x07\x8b\xe9\xcdi\xdaV\xd8c\xa61\xad\x15\xc4\xbbm\x9a\xc0\xb2\xe7tB.\xc9\xe4\x98|\xf6\x00\x8cF\xe2\xdf\xcb\xa8s\xbf^^\x1c\xfb\xb7\x8e\xc01\xa6\xc2\xf6\xd1\xccc\x82\xdf\x9e\xfa\xa4\x07\x9c\x85Y-H6\xc5\xfc\xda/\x8eQ\xe7\xc8\xff\x10\x16\x1e\x0b\xf8P\xbb\xc4\xdf\xf1\x9d\xde\xdb7\xff-\x13|\xfb\xa6\x9c\xe2\xdb779\xc9\x97du\x0dAC\xf8\x13\xd8\xfa\xa4\x93F\x8f\x1eU\xa3\x10\x98\xfcS\xcc\x89\x1aX\xcc\x1b\xa0\xebI\x0f1\xa1\x89\xb9<\xb8aXB+\xb4\x19,j\xc8\x125W\x9c\xa1\x84\x8ay\xbbYh.Sc\x18\x08\xe7@|6o\xa3oRZR\x04=\x84C\xe8aE\x028\x80^\xd4\xb3c2\x83\x01\xf4\x0czTu} \xa6\xbbp\x9c\xcaR\xfd[{\xe8\xb2\xba-,%\xfc_t3\xdaR%\xa4\xb4I\xe1\x9a\x96^4x\xe6\xf4\xda\x9c%\xc8\x1d\xe0\xc5\xb7}\"\xab/ ?\xcf\xbdVt^\x93C=\xd0\xaa\xdcb\xf5\x94\x9d^\x9d\x89\xb3t\xc3\x0d\x16A\xe6\\\xe0\x06\xae\xb5\x1cT\x1e\xc2>\xe6G\xe4\x98\x02\x07b\xc3\xb6\xb6\x83\xae\x06\xc0\x9a\xb5\x0e\xe4\xc8\xe0\x10\x82LR9l.\x94\xed\x92\xb2\xf4\xad\xa8\x18\x988\x0b2\xe7\xfe {\x9f\x9c\xcd\xd8\x86pS\x84Ig\x84*C\x94\x9b>I\xaeG\x9a\xdes\xab\xdd\x1dl\x83\xc6^\xfcq\xb7D*=\x19\xaeWWh\\\xbe&\x06?\xb9\xde!\xc1\xb9\x91\xcdz\x14yYD\xac\xdc\x1b\x8a\xa5\xc2LY0L]\xe5^5&\x9a3\xb3\x06\xe4\x80\xb9\x1f\x94\xba\xbf\x80\xd6\xfc\xee\xd5\xcb\xe9\x92\xbd\x8a7Q\x0f\x88}\x8d\x1e2\xbb\x11\xec\xecy\xf5\x92\x14G\xf3\x05\xf3\xb11\xc8^4\"\xae\xcb\xe9M\xc9\xfd@.c\x9d\x19\xf5\xe0EmFH\xaf\xd9\x8c\xb3%m\xee\xfc\x8e\xf9<\x0dH\xa5J\x12\xdb^\n\xb0\xe2\xe3\x0d\xf4*\xd8\xfb\x13_\xf6T\xf6\xefK\xa5@\xa3T\x1fI\x10V\x06)W\x06<%\xe5\x98\x88w\x17\xeb\x8a\xdf\xcb\xbc AU\xa7\\T\x12\xe7\xbbR\xcfy\xec%\xb5i2\x97\x99\xddU\x97\xa3\x94\n\x9e\x05\xba\xb9\xcdR!\xefJ?o}V\x8f|^\xc6\xe9&\xc2\xd69)\xc9\x86W\xfb2k\xa6\xc7V\xd3\x1dN\xcdk\x8b\x81Z\xfd\x13L\x97W+\xceDHu\xdf\xcd)\xd6\xab\xb7\xfeN\xc3\x86\xaa\xd5\xcd'\xd6\xaa\x1at\xf9\x8e5>&\xc6<\xa0\xea\xba\xf2\xe4\xf7\xc4.}\x93m\xb8\xdf\xa5\xf8\x81;|\xa3\xd3\xa5\x14Y6\xe7,,\xd5\";xn\xea']V\xc2%m\n\x97\xbc\xefa\x16\x01\x1d9\x05L/\xd6\x8aO\xff%\xf1%n5o\xf4M\x84=T\x8dQc\xa9]\xf3\x98\x1agd\xc7\x8a\xe8 7\xb3z8\xda\xb2\x99MF\xb1!rx\x0e\xa5\x02\xdc\xa6\xe3\xf1_-\xcf\xa1\xbc$r\x05\xfdF\x91o\xcc\xbc \xe8\x1f\xfb5\x9f\xc6\xec\xf5\xb5\xa51\xdf5\x02m\x13\xffb\xae\x93\xa4\xae&m\xabk\xea\xbb6\xb2\xd6Bn8k]\xc7\xa1\xae\x895o\xf1\x8d%O\xd9\xe2\x06ga \xd9\x1f5)\xc1WD\xd0\x8f\x12\x7f\x8c\xe1\xa7\xdd\xab\x0d\xcc\x90\xf5\x82y\x1e\xd8R\xa1\xa4.\xef\xfa\x14\x1f\x9fa]m\x9b>5\xaa\xfcd}\x07\xfe\x9cz\x0e\xddTnZ\xf8\x03c\xa1MUa:\xabU\x98\xee\xcc\xb6\x9c`\\\x90GV\xe4\x00}\x1a\xb1Z:\xc6-\xa9\xa4\xc4I\x04+\xceJ\xafB\x14\x13V\x95\xbf\xa7\x19D\xaee\xf1:\xad\xce\xf2l\xb9\xf8w\xb0\xe2~6\xbc@f\xbb{\xc7P\xd5\xc5\xf9wO\x06\xde\xc8\xb9w\xe9\\\xf8\x95\xb59w\xfe\x99\xe0\xdc\xbb\xf7\xb5~I\xf0\x04\"\x04r\xbd\x86\xe1(\xc4\x18\x06\xccY>\x8c#HFp\x00\x89\x87q\xd0A\xc7\xec0P(\xe8G\x81\xb3:\xe5\xed4?U\x14\x8cD\x90\x04&\x12\xa9.\xcb\xf87\x165f\xf1&r\x06\xd2!\x99py%b\x08V\x9e\xbd<\xdf\x84\x86\xab~\x9e\xd3M{J\x8a\xe3\xe5\xa9g\x81\xcfR\x06\x1c\xd8|\xc2\xcaJ)\xc2\xea,y\xf4J'\xe4\xb7\xb4\xe5y\\&\xc6\xd9 \x9f\x96y\x8a\x0b\xce\x0bm2\xc9\xc05K 3m\x96ay\xd3\xffT\xfbDVo\xa7\x1b\x0c\xa9<\xd483\xb7\x11$o\xc0H(\"\xce\xfd\x8f\xf8\x9aV\x86\xef\xea\xe7-)\xd5\xa7\xdbts5Z\xab\xe4W\x1f\xf9Y\xff\xfe^^g],\xbc7\xae\xb11\x97U\xbb\xefy|\xb9A\xaf/\xd8F*\x8cy|\xb9\xe9\x99\xfa\xa2\x96\x8f\xc8\xab\x13?\xa3Yk\x06p\x08\xef\xa9pa\xf9\xe8'(\xcd\x13z\xfd\xe9\x88\xee\x98\xe8\xcewn9\xd9\x18\x13\x8d!\x8f`n\xbe\xf8\x94,6\x80\x9d\xd6\xfe\xeb\x98\xcd\xfa\xf3\xf82\xb0T$\xb6t\xd6\x14\xbe}\xa5\x04\xcb\x1e\xe3M\x06D\xbb\xe3=\x90\x9fgI\xba\xa1\x99\xa1\x1c\xccO\xd74l|J\x16\x1f)K\xd2\xcd\xba\x15@WC\xdeL\x05%\x12\x82m\xd6_\xdb\xcaa\xc8\x0c\x06\xe6\xfeX\xfc\x89l\xb0\xbc\xacf\x80\xb8\x06J\xf1\xfen\x18\xa5x\x93\x9b\xa3\x14\xff\xeaKP\xea:\x92\xc4?\xbc\xb8[\xad\x84\xd1G\x8aj\xdeZ\xf26\x8c\xac\xec`x\x15;\xcd\xac\xdaeuq\x91.\xab\xc7\xe6i\x05Zja \xd8\xb1\xbb\xb5sY\xcf\xbf\xa3\xec\x7f\xc9\xb8\x19\x04\x1f\x82*\x91e\xd7\x0c\xb5f*\xe9\xa7\xfc\xf6\xd6-\xd8\xde\x8eQH\x95\x0dZ\n\x95\xab\xeb*\x8c \xb6\xbeq\x15\x81^\x06\xe9\xbfhU\xb2|\x93e!5o,\xfe\x9d[\xae\xe5\xd7\xd2\xe1Q\xa2.9N\xcf(K\xfdB\xdf\xa9e9\xd3\xee\x0f\xc0?\xe2Q\xbf\x9c\xd1\x8f\xfae\x89\x95\xd0/e\xba\x89;\x8bS\xa9K\xe8\xf0kE\xaa<\x1c\x1aUD\xa3\xac\xdf\xeb7\xd1B:\xab\xfa\xbd\x9d\xe2\xdb{\x1d\xae\xad`\xdaki\x04\x05j<\x0f9i\x1b\x0c\xe0\x8d\x14s>s\x8c,\xf0\x05\x91\xe6o)=C\xfe\x0b\x16\xb7\x8b\x088)\x80\xf1\xe1\xe6\x9aW~\xf0\\\x97\xa9(\x0f\xad\xcd\x98\n\x15C\xb0!_\xba\xb9\x186\x8b\x8b\xd9\xd3l\xb2\x81\xa3\x0b\x9bU\xd9\x05\xb0\x8a\xf3L\xcf6\xd0\xcd#@\xb9\xbd\x84\x83\xf2`\x00{p\x1bv\xcb\x8d\xe6 ]\xcaL:\xeeT\xf0\xf9\xb9\xf2\xa36\x16\x0ea\xcf\\\xf5\xb6|M\x0c\xcck\xf1\x1b\xdf\xf0\xd1^\xa2\x90~\xe7\xee\x9d\xfd\xef\xf6\xbe\xbds\xefN\x18\x95\xb7\xe1\xe1C\xd8\xbb\x07k`\xf0\xe8\xd1#\xd8\xd9\xbb\x17\xc1\xdd\xfb{\xdf\xde\xbd\xf7\xdd\xee7\xcd\xf7\xeeh\xef\xdd\x89\xe0^\xf5\x1c\xd3\xb9\x07\x0c\xb6\xe1\xce\xb7\xf7\xef\xee\x7f\xb7\xbf\xf7\xdd}Xs\x98\xfe\x8bo\xe9\x7f\xc9\xcf\xf6\xeeG\xb0\xbf\x7f\xf7\xfe\xb7\xfb\xfb\xf7\xca\xe6\x8f\xe5\xe7\xd8M\xf9\xe6\x9d\x08\xee\xec\xdf\xbf\x7f\xf7\xdb\xef\xbe\xdb\xfd.\xd4\x9bpl\xb9@\xe7\x0f(\xd6\xba<\xdc\x10j0\x80;{\xf05\xe4\xb0\x0d\x9fi\xf0\x94\xe0\xa6yJ\x02\x16\x86|F\xf6\xce\xc1sw\xaaKh\xc5\xaf\xd1K}R>\xdd\x943\xc2\x8e:;\xd8\xacq\xcfvCc9k( \xa2\x89\x14\xd6\xee4\x95\xc1|/~\x10\xc9\xc9\xb4\\\x00\xfa\x1b\x1f\xe8p\xaa\x02\xbc?\xd0\xe1+\xfe\xf7\x07i\xb2(\xf8-\x19:*n\xcb\xc0\xea\xf2\xbe\x1e8\x04\x03xF\xf1IB\x8b\x85\xc8\x8d\x8f\x9f\x1cg\xcb\xbc\x9eW\xc6\x04\xb2\x86\x12I\xba\xb7\xd6g\x87\xad\x8fgqBE\xdb\xd2\x96)ng\x94\xc5 F\xa5\xe3\x10\x84\xee\x12c\xc4s\xd3)9M\x93\x0dB#K\x01\xe5#\xb3\xae\x84I\xed\xb38j\xb9\xf7\xfbZ\xff\xedT1\xb7\xcb\x02N\xe1n#\xc3j)M('\x89a\x12A6\xb2\x17\x9f\x06\x10FU\xcd&\xe9)4\xce\xe3\xc5\xcb\xba\x0f\xb2/\x8c\xae\x01\x04\xbe\xeeMXt\x89\x19-X\x88h\x04\x07\x10\xb0\x93\xeb\xec\xd6\xd7\x14\x93\x9btf\xeexn\x07\x92\xdaI\xf5\xbe,\xed\xfc\xde\xd9\xce\x90E@F^\x8d\xbd\xb1\x90\xc3\xe6\xd9\xdc\xb1\xd9\xb6\x88O2.h\xc3\xd32\xac\xf773\xac\x9d\x1b\x1e\xd63\xf7\xb0z\x05\xd2\xc0\x9a\xf1\x03\x0e\xe1\xc5\xf1\xdb7}\xf1(\x99\xae\x84\xdaVRK\xcf\xdc\xa2\xaf\x9c\x04\xf8\xd8\x9a\xc9\xd3\xd2\xdc\xc7N\x0c\"\xf0\xb0\xe4\xe0\x08<\xc2\xbfw\x90\x9d\xf3\xea\xe0\xb3G\x07\x9c\xf5\xd9\x86\xfd\xfb\xf7\xee\xde\xbds\xef\x9b\xfb\xdf\xc16\x04\x843d\xf7C\xf1\xe7\xa3G\xb0\xdf>}\xeb\x0b%[{M\x87\x0bu$\xbe\xae\x8eD\x19\xa8\xc5\xef5\xceD\x91^\xa0|\xd08\x14;\x89\x9a\xec\xb6\xb1\xb0\x0c\xa3o\x0f0\xfc\x161\xa5>p<\xd82s\xf2\x93/M\xdf\xe0\xa73\xbf\xd1\xc0\xa9=\xbf\x93b\x9a\xd0 JO\x9e\xdd~\x817\xdd!:\xd3\xc1\x01\xec\xb4\xfd\xffLfN>*?\xc3\xd5\xb9\x9e>S\x99\xa8\x9c\xa3\xd1\xd2\x0c\x97{\xc7\xcb\xd53\x8d\x0b\xf6\xfc\x9a#+\x8dq\x7f\xd9\xe8n\"~\xc3\x13qn2~\xc3\xb7\xcb\xc5\x06}*Dm\x86\x15\xd9\x9d\x98\xf9:U\x96\x02.u\x8a\xa0Z\xb1\x10\x98\xf6j_\xfe\x89\x15\x8c;\xb23\xf2\x8b\xa8\xec\x8c\x9c`\xef*\xe7~t\xce\xafRDt\x04\x85VI\x15\x959\xa3\x03{J0\xef\xc9\xd1\x1eB\x0e\x07\x90\xab\xd0\xfdc=\x02x_94\x88\xd61\xc7\x81gP\xb0r\xee\xfc\"\xf2Qz\xab\xfe\x15$\xe4:\x8e\x9f\xa2\x9a\xbdW\xeb7\xe4\x9a\xe8\x89\xfd\x1b;\x0d6\xd2k\x87\x88\x82\xaa\x14]]\x0b\xa5e^\xafG\xd3\xdc\xba%\xf8\x8b\x99\x96dU\xe1\xed\xb5\xfc\x11EUmKV\xa5M\xdd\x117s^j\xc1\xe3\xd1\x00v1\x07\x85%\x90\xc8\x02(d\xbefUt\xd1\xce^\xf5\xa5<\xb4Z\xd5\x14\xc1v\xc61\x92/\xb2b\x13\xd3\xe6\xf5\x93|\xf8\x99\xf5\xaa\x12\x03%\n\xec\xc3\xd7\xea\xd7\x0e\xec\x89\x02\x03\x0e\xcb\x9f-\xf5\xa1~)\xa3\x01s\xca\xe5\xeaJ\xbe\xd8V\xd79 \xad\x8d`+\xc1R\x00b]Eh)\x17\xd1\xb30\xd4\x92\x96b\xb3\xf2\xbe\xb3\xe5+\xde{\xe4\xca\xa3\xa1C\xd4l\xb6\xf3\x06i\x84\xb0\xaa\x19\xd0~\xc7\xfe;'\xefo\x0f\xbd\x86\xfd\xac\x84l\xc6!\x1b\xc3\xff\xe5\xb2\x03\xdfz\x1c\x07\x92\x9a\x0b0\xc6\xfc\x1e\x88w\xe0\x10>\xf3\xb9\xc7\"\x1d)Zm\xd4\xcfL\xa5\x8c\xed\x02\xbf\xd3ZbIU^Q \xefm\x9c\x92\xf8\xdc\x87\xf3Rf\xb9!\xefbd8\x94C\xc7bq\x1e\xe5\xa5 \x00J\xff\x12\xc1\xcb~6EgZ\xebg\"?\x89\xe6\x9d\xef}\\\xc3\xbf\x8e\x1f\xf8\x9e\x11\xaa7\xed\xde\xe3y\xf2\xffq-\xbd\xeaK\xf5\xc7+\x1a\xb9\x90\xcd{\x0c?'l\xe6sN)\x99G\xef\xc5\x8do\x9c\xa7S\x01\x02\xed\xf1\xdbL\x96\xb5;W!\xa7\x08Uz\xd8\x89\xd27\xe87\xcb\xba-\xef\xd0q\xbd=\xfc\x8dy,\xc4 Q\x0bZ\x9a\x95\xbd\xe4\xb4\xeb\xe6\xd31T\x9d\x86\x9b\xd9l\xd8|\x95\xc3\xcd\x03\xda\x89\x96g[\x94\xd0\xaeY \xf4\xc7\x9a%A\xbf]3)\xfc\x1a\xe9J\xda\x10\xef\xbd\xac-\x9f\xb8\xf7C\xadiq\xef\x84\x18>\xbe \x86\xaf\x8fH\xf3\xf36TT~\xb9\x03\xa0m\xb8\"P_\xb4\xef?\xcd\xd2\x94 \xa4\x0f\xe0\xd4\xe0\x03\x81\x01b\x1f\x0d\x0f\xf4\xb4\x92\xefX\xfb\xb9\xc8\xcb\xb70<\x91\xa9\x02\x8f\x8c\xa3d\x07P\x18\x1e\xe8Y%\xe7\x86\xe7\xef\xc98\xcb'\x07\x90\x9b\x9e\xc5\xf4\x8c\x1c\xc0\xca0\x89\xf7dAb\xde\xa4\xe1YR\x1c\xc0\xccp\x7f\x9agsLmkK\x97|\x15\x01\xe9\x93\xcbE\x96\xb3\x02\x93\xc4 \xac\xbcr\xfb\xb4\xf5\x96\x05\x81\x82\xe5\xc9\x98i\xf9i\x94 ]\xdbn\x9a\x0f\x8d\xdeQ\xb3u\x15\xfb\x16G\xb0\x8c\xa0hn$L\xc6\x1e\xb00\x82-\xe3\x1e\xe6]\xa7m\xfa\xa7\xa5\x01C=OX&L;\xca\xf3,\x0fz\xaf\x13\x9aL\x132\x01r9&\x0b> \xc8\xc6\xe3e\x9e\x93\xc9\x03\xe0\x93d3\x024\xa3;s\xf5\xe2\x84\x9c\x03\xa1\xe7I\x9eQNu1\x02\x8b\xbf4]\xa6)\x10\xde*\xccIQ\xc4g\x04b:\x81x2Ix\xb3q\n3\x92.\xa6\xcb\x14.\xe2\x9c&\xf4\xac\xe8\xf7\x0c\x14\x9b\xa4\x05q\x90\xfc1\xe7i\x9a\xc0r\xf8\xf7L\xed\xfcfP\x07\x05\xeb\xe7d\x91\xc6c\x12\xdc\xfe\xbf\xc5\xed\xb3\xa8\x9b\xa8AE\xd8\xc6\xc3\xe9\xf6v;\x84\x17\x90\x8a\x85a\x9f\xc6s\x0c\x8dxN\xcf\xe3<\x89)\x83\x9f\x92,\xc5\xe4\xdb\x86\xfc\x92\xad;l\x96g\x17\x90\xf6\xa7y<'\xc5\x87\xec\x1dV\x91\xd9k\xa6b\xd3\xb0\xfa\xcb\x91\x98\x06w\xee\x86f\xdc\xcd\xaf\xdf\xba#K\xa2L~>!\xd3\x84\x12\x95\xfc\x9c\x8bE\xbd\x93\x13R\xbc\xce&\xcb\x94\xf4L\xa4T:I5\\\x9e0\x8f\x12\xe7\xbb\x9ef\xf3yF\x8f.\x19\xa1\x85\xcc\x7f\x8e\xf7\x1bwH1\x8e\x17XS\xf1UB?\xbd\x8b\xb1\xae\xa2J\x9d\xdf\xba]\xcc\xe24\xcd.\x8e>/\xe3TV#d\xfd\xd3e\x92N\xbe\xcf\xf2\xf9\xb3\x98\xc5\xe2\xb5,g$\x97OY&o\x92<\x89\xd3\xe4\x0frL\xe2|,\xda[\xc4y\xa1\xff>#\xec8\x9e/Rr<\x9e\x91\xb9\xf8\xee\xaf\x17\xc7o\xdf\x88\x9d\xd1\xe9\x01\xc6\xf2U\x07\xb3\x8c\xb6*D5\xab\x8eF\xe8\xa8o\xdd\x82^\x86\xbd\xf6D\x11\xb2\x86\xb1\xa0\xb7\xa4b\x9fNzp\x00\\\x82*\xf8\xc6\x8d\x97)\x0b\x03\x16\x86\x8ex\xd7+\x18\xc7l<\x03q8\xb6\x1e\xcb\xef\x1a\xd9\x1b\xae\xf8^\x16\x03J\xa6\xabNH\xc8F\x8e\x05\xc3|$\xf9f-\xa9<\x1c4\xfb\xc6\x1e\xe2<\x8fW\x1bt@d\xb3\xe8]\xa3\xff-\xeaI\n+\xefp\xd4\xeeH\xb0%\x92O\xd2z\x03b\x0eM\xe3\xabr\x84\x1eT\n\xae\xe6\xb3\x9eAB\x0b\x16\xd31\xc9\xa6\xb0RK\xd2\xe7[\xd2\xf5i /\xc6\x01U\xcf\x86\x8b\xb7\xd2\xb2)\xce\xb8\xcb\xb4\xbc$\xec\x8b\x8c\xce8\xdb\xea\x95\x8a\xd9\xac\xde4\xd5Nd\x98`\xf0Cv\xcc<\x0b\x05)\x15\xa3)\x87\xbb\xd2\xfd\xecF\xb0\xacP\x91\xb4\xb3\xf3v [\xe6\xf0\xc5!3$\xe80\x14\xbe\xeb*\xc6N\x879\x17\x0f\xc90\x1f\x89\xf4\x8at\x99\xa6fMt+\x13&\x82\x8cf\xf9\x1c\x0f\x0f\x81s\x03\xb8\x8c\x90N|O}\x91\xd6<\xc1vOIQ\xd2\x9dc\xd9\xc7\x92\x8eo\xbe\x175\x11\xaff\x9b\x99\x9a\x8dT\xe2u\xbc\xf0A'+\xca4\x93\xfa\xba\xf4\xa2\xf5ue\x01_Y\xa1\x8a5\xe5\xee\x84?\xdb\xa5\x84p\xc8\xef\xb1\xcb\x7f\xdb\xa8K\xc5x9^\xa7\xee$s\x1e\x08Y\xd7\x81 U\xda\xfcn\\\xdd\xa5\x18r\xb1\x01\x98\x8aU\xc1\xc8\xfc\xc3lI?\xbdN&\x93\x94\\\xc49\xf1E\x9c\xee\xfd\xcf\xfa\x93\xa4X\xf0\xb3I2\x8eH\x97\x9cp\xe9n\xd4\xf4\xb2\xd3\x82\x05\x1d[\x08\xcd\x93\x01 0\x959\x0b,\xbel`\x14#\xccw\x0d\xe7\xa0\\#\x0e\x80e\xf14\x9btC\xf9\xbcL\xb2\xa5\xaal[I4+55\xc1\x05?[.\xf8D\xfc\x93\xa8+\xe0\xec\xf7Ty\xd4m\xe8\xf5Bc\x06\xa5\x10\x19pK0\xf3\x95\\f~\x82\xf9l<\x8c\xce\xa9N9\xa5\xc0\xe1\xbc\xa7\xfc3\xd0\x8a)V/\x8a\x13\xb2\x0d\x0eu\x9a\x11\x99\x83\xc0p\xec2\xce>\xb0\x91\x1d\x96\xf5^\xfaI\x81\x9dQ\x91\xf8\xfe\xa05\x88\xf6\xfcg\xc9\xd9,M\xcef\xdd\xdc\xa5Z\xe1I6Fu\xab\x99\x01\xd9\xaa\xf8\x8c\x9e!s\xaf\x08N`\xe4\x92=\xcd(#\x94\xa94\xac\x8f\xe0\x1e\xb9S\xc5\x03\xe9\xafX'\xdf\x8d+\xb5\xec0\xba\xd2@\xa4\x83\xab\xfa\x88\x90\x0b\xdf\x8dP=\xb2\x1c\xee\x8e\"\xd44\xecE\xa8@ \xfd\x84R\x92\xff\xf8\xe1\xf5+\x91q\x18\x16\xa8V\x10r\xb2\xa8g\xbb\x80\x87\xf0\x0d\x92\xc9\xdf~\xc3\xfdJ\xa5\xe7\xdc\xd8\x99m\x86\x03\x84\xf7\x94\xaa\xae\xb7\xb7\x8b\x910\xafM+\xd8\xecE\xb05\x86\xf5\x1a\x16\xf0\x08\xbe\x15\xbd\x08\xaa\x80w\x87\xb7\x7f;\xbe\xddg\xa4`\xc18\x8c\xf8\xdb\xfc\x83\xdb\xc3\xaf~\xbb\x18i\xf7\x83\xdem9\xb2\xf5\xbal\x80\"iN\"\xf8[\xefo\xa0\xdcN\x92\x08z\x7f\xeb\xe9?\x97\xc3\x02v\xe0\xee\x08\xb6\xd1)\x9e\xf2g\xbd\x9d\x9d\xdf.\xefp\x99\xbc\xba\xf5\xf5\xed\xdeh\xb8\x18\xb9\x8de\xb8,SQ\x98\xa1\x1f/\x16\x84N\x9e\xce\x92t\x12\xc4\x9a\xc8}\x94\x12\x8efA\xafX\xc4\xb4\x17\x86\xfd\x82\xb0\xc7\x8c\xe5\xc9\xe9\x92\x91\xa0W\xb0\x15\xaa\x03\x86\xbdq\x96f\xf9\x01\xfc\x9f{\xf7\xee=\x80iF\xd9\xce\x05\x11 qO\xb3t\xf2\xa0\x17\xe1\x8a\xe1\x7f\xfa\xabxo4\\\xc0!\xae\xdd\x1d8\x84}8@\x08\xdf\x87C\xb8+\xff\xe6\xf7\xef\xc0\x01l\xdf\xfeW\x10\x07\xa7\x05\xcb\xe31[\xa7I\\\xac\xe9d\xadL\x0fk\xbeg\xd7E0_\x17$g\xe1\xe1z\xc9\xb2p}\x1a\xc4\x05Y\x93\xb3\x84\xae\xb3,\x0dHL\xc3\xc3uN\xe2O\xeb\x15#\xe1z\x8c\x8f\xf9\x81\xb3\x9e\xc5\xf9\x1aE\xdb\xc9:\x8d\x8bb\x9df\x94\xac\xb3\xf9\"]g\xb4`\xeb\x8c\xb2\x84.I\xb8\x9e\x90\xe0tyvF\xf2\xf58\x99\xc7\xe9z\x9c\xc69YO\x03\xbe\xc7\xd7$\x0f\x0f\xd7 M\xd8:\x0d\xc8Y\xcc\xc8\x9a0\x12\x1e\x86\xebI\xb6\x9ed\xcb\xd3\x94\xacI0\x9ee\xeb\xb48L\xa6\xeb\xb4 A2\x0d\x0f\xf9<\xb0\xf6\xe8\x9a.\xe7\xebsB\xd9\xfa2\x18\x93\x05[\x93\xf1z\x11\xa4\xc98a\xeb,g\xe1\x9a\x91\x80N\x8a5*M\xd69\x0d\xc3\x90w\x9d\xa6l\x96g\xcb\xb3\xd9:N\x0b\xb2Nh\x9c\x06\xe9\x8a\x0f\xe5\x92O'\x8b\xf9\xd7\x01\x89\xc73>\xfb\x84p\xb0e\xf3\xf5\x92\x8e\x03\xbe{\xf9\x00\xcf\xd2\xec4N\xd7g\x19\xcb\xd6g\xcb8\x9f\xac\x93`\xba\x9e/\x02\x81\x03\xc5Z\x1b\x04\x0d\x12\xb6F\x95~p\x92\xd11 \x0f\xd7i\xc2\xa1\xb5dk%\xfa\xacY@\xf2i<&k\x92\xd38\x0d\x0f\xc3\xc3u\x11\xae\xd3 \x9e\x9fN\xe25a\xebl\xfci\x9d\xd1\xb3p=\x0f\x92q\x9e! \\\xa3\x8ai-\xd4\x08\xe1\xfaM\xfcfM\x83xN\x8a\x05o)f\xc99Y\x93K\xb6&\x17\xeb$]gl\xbdL\xd3p\x9d\x05\xc8\x16\xad\x17\xc2\x10\xbe\xce\xd7K\xb6>'y\x9eLH\xb8^\x04\xf1\xf8S|F\xd6q\x1e\xcf\x8bu\x9e\x9c\xf3u\xc93F\xc6\x8cp@\xb0l\x9c\xa5\xeb\xe5i\x9a\x8c\xc3u\x1e\xc4 \xc7\x98 \x9ed4]\xf1\x85\x9b\xae\xcf\x92\x82\x91|\xbd 1[\x7f^&y5\xefb\xbc$k\xa1b[\xb3|\xb5\xe6T1\x0c\xd7Ep\xba\xe2\x8b\x1f\xa7d\xb2&\xe9t=\xcbr\xb6N\xce(\x99\xac\x93?\x10<1K\xc6kT\xe7\xacY\xbe\x1c\xb3\xf5\xf2\xb4\x18\xe7\xc9\x82\xad\x97\x0b\x92\xafWt<\xcb3\x9a\xfcA&\xeb\x8b\x84\x8dg!\x87\xe8|\x91\xf2\xc1\xcf\x08]\xcf\x92b=\xcb\xb3\x8b\xe2p\x9d\xc7\xb4H8\xd2\xe4K\xb2\xceW\xeb\xd5\x82\x041\xee\x8f \x99\xae\x93\xc9\x9a\xc6s\xb2\xce\xa6a\xb8^\x064\x18K4\x9f\x90i\xc0\xd9E\x8e'\x19]\xa7\xa4(\xd6\x85\x18#K\xd2p]\x90u\x91\xf0\x05:\x0f\xe2|\x9d\xe4l\x19\xa7\xeb,\x99\xacQm\xca\xd7\xe7\"\x18\xcf\xe2\xfc\x84\x89\x01\x91\x9c\xacgIJ\xd6 \x9b\x85\xeb\xcb,_\xaf\x12\x92N\xc2\xaf$\x01\x9cr~iw\x14r\x16T'9\x8a\xdc| \x97\xecM6!\xc14\x0cC\x91Al\xc1)\x94\xa0\xeb\x9cF\x1c\xf0\xf3c\xaa\x1d\x00{{\x0f`k\xb8\x17\xc1\xed\xe1o\xb7\xff\xbc\x1a\x06\xbf\xedl\x7f=x\xf8\xe8\xe0\xc1\xfa\xb7\xdf\xfa\xd1\xe1\xd6\xad\xbf\xff\xfft\xfa{{\xf8\xdb(\xac\xdfhPhI\xa0\xc7\xbc\xe3\x0cS\x93sR\xff\xb0\x07[x\xceH\x12=.\xa9\xf3\x98\x1fS\xdb\x90\xc26\x12\xe8m\xd8\x1b\x95\x7f\xee\x8f\x90 \xffvyg\xbc\xb5\xb3\xd3So\xf2{\xb7\xbf\xae\xff\xbc\xcdi\xe1\xff\x11-\x8e\x86;;\x8b\xd1\x03\x87\x07\xcf\x14\xb6\x070\xf6e.\x8d2\xda<^|\xc8\x1a|\x97M\xf5as\xb1\xe4\xc7b#\xc9~\xf9\xcapo\x04\x87\xf5\x9f\x07\xd0\xfbDV\x06\x96D)\x06\x0d\xed\xef[\xdb\xdf\xaf\xb7\xbf?\xaa1[\xaf\xe3\x85\x89\xe1k0\x90\xaf\xe3E?)\x84\x96\x04=\x81\x84\xf7\xc3\x06\x1cd\x9dc\xa4\xa2\x82\x0dE\x0b\x89\x89g\xe4\xfd\xd3*\xef\xfd^\xa5\x11\xea\xcfI~F\x02\x93\x14x.\xa3\xe5\xbbG\xc3\xdf\xe4\x8c\x155V\x07\xe2O\x0bK\xf4\xbc2\xecl\xed\x99\x9fM-:]p*=K\xe6o\x11\xc1\x04\x06(~&\x9a\x96RE\x06\x04!\xa6 \xe4\x83\x0b\xf8\xb6\x9e\xd4\x1c\x85\xc2\x07r\xd8..\x8e\xf72\xe3\x14\xc3'8\xfd\\\x8e%\xab\xc62C\x17Y\xe7Ws\x0e\x83\xceP\xf63|k\xaf\xe3\xad\x15\xe7i\x83\xb3\x08h\x99m'\x82\x9c3X\xc12\x82yS\x0d\xad_mTPB\xc7\x8a\x0b\x1d\xb1r\xfe\xc0\xec\x87\xb1H\x9a\xb72s\x83\x06b\xa1\xab\x86\x8d\xdf\x8c\xa5k\x05r\xe5\x86\xef\xa7\x9c\xfbHm\x18a\xc7\x15~ma \xdeI_n\n\xedo[\xe2\xe6\x8e\xee@\xf1\xf7\xa14\xe0M}\xe1\xd0\xba#\xc7\x14\xb7I)\xb9D\x8e\xf4\xfb$%o\xe29\xf9>\xcf\xe6R\xa6y\x96\x14\x8b\xac@\xe3\xeb\x8f$\x9ex\x94\x95W\"\xde\xedi\x92\x12~l\x0fz\xc1\xf0_\x0fF_\x87\x0f\x0e{\xb7\x93>\xb9$c\xa3\xe1\x00\xcb\x9e\x08\xdb\x00g\xea\xebm\x94MT-\xd8\x88\x93\xaa\x9e\x82\xcdh\xb2\xa1F\xaa\x8c\xf9\x19\x94\x12n\x99\xa6m\x08-\xe2b\x1c\xa7O\xe3\x82\xc0\x00\x9e\xd6\xef|/\x07\xd9 \x1a\xd9\xc3\xd3\x80Tf\xe2\xdf\xfa\xc3\x7f\xf5o\x8f\xbe\xfe\xea6\x17%B\x93\xc6*\xa6 K\xfe \x1f\xf3\xb4\xb3\x07\x0e\x802vlK\x8b\x1d\xe3\xc2\x9a\xd0u\xb8ekM18\xd6{\x0e\x8dG\xf0\x19a\x8f\xc7\x9c\xcb\xe7\xd8\x92gi\x9a\xd0\xb3\xf7\xa4Xd\xb4\xe8\x86F\xe3$\xab\x14\xfe\xfd\xa4\xd0\xb4\xff\x9a:\x84/\x8dMcP?\xf6\xccoV\xfa\xa5\xbaCx\x97Wry\xc2\x15,\xceY\xf1s\xc2fAo\xbfW\xea#u\x15*:\xe9\xf5\xc6b\xf7\xf4\xf04\xfd\xf3*\xac\xb0\xd0V\xa8\xc1LlK\xd5N\xd0\x93]\x88&\x8dv\x12K\x1b|\xcb\x06\xd40.s#a\xa9|\x93\xa6.5v\xa1\x0d2CVA\x887\x9b\xb7\xf1dB\xc8\"]\x1d\xb3\x8e\xbaLmJ\xf3\xdeP\x86\xffye\x0eLi\xe0hf09\xd9\x15\xdaU\x1cQ\x1edC6\xc2\xbdr\x08\x13\x92\x12F\x80\xdf\xe1B\x0d\xff\x87\xf3\x03\xe2\x0dj\xcce`\xcaV\xabl\x03\x06\xb2\xa7\xa2!\xbd\x08\x89)`\xd6\x95\x19HV We=\x95Y\xd7r\xa6X\xad\x16\xa4k\xc1\x89\xb0Z\x94\x87\x12 \x1d\x0c\x84F|s\xad\x89\x08\x84}o\xdf\x00R\xc5\xect\x19$\xcdQ\xc2\xe0\xe2\x13\x88#\x15\x03\xebS\xf4\xbd\xf8\x90\x95\xfe\x1c\x1ek$\xbe\xb1\xac\x91\xd6\x9b\x15M\x1a\xa6\xbf\xfa{\xe7\xb2\x92\xe7I@\x83oL>\x12ctH\xba\xf7\xcd\x9e\xe1\xd9T~x\xef\x1b\xa3{\xc5B\xb9f|\xbbkz<)\x1f\xdf5=\x9e\x95\x8f\x8d\xe3:\x97\x8f\xef\xdf36>W.%\xbb\xf7L\x8f\xcfpV{\xdf\x99x\xff\x95\xfc\xf4\x8eqR\xa7\nX\xfbw8\xe2\xd7\x9e\x97\x04\xfa\xa4\xc3w\xe1\xd6-\x0c\xe1P\xbeU\xd2\xb5\xd8\x8c\x8b\x12\xa5M\xa5\xea\x9bQ\xf3\xfa/\xbe\xb0\x170\x80\xf2\x08lO\xe5\xc8\xe0\xc0\xd3\xad\xd9o\xc9\xc8fsL{\xb06`]ndv\xae\n\x047&on\xfc\xd8\xd9\xf8\xd6\x16q\xdaW}(\x95c\x0dtO\xa9\x89\xfa\xc8\x06\x86\xa7\xce\x91\xf2~\x17U\xbf\xfc\xe7\xd4\x7f\x18u\x07\xaeN\x16\xce\xa1\xf8\xd9\x8c\x8b\x18Z\xc4a\x0b\x8br\xc7\xda\xf8\x9dz\xe3wD\xe3NN\xbcn\xa2\x97} \xefQ\x7f\xc8\xca\x87\xeb5 `\xcfk\xc7\x88\x0e-\xab\xfd\x18\x9d\x84\xab\xfc\xdf\xb4b\xbfM\x9a\x15\xd0\xfd\x00\x86\xd4\x92\xf6\xces\xa3\xc1!h\x02AR\x04\x182\xc5Q\xd5\xcaq\xf9\xa05\n?\xb6\x06|\xfc\x0e\xf0\x08'\xf8i\xd6&\x06\x82{k\xd4l\xeb*`\xb3\xc5{\x99k\xc3\x1cR\xceY\x0d\xa9\xc1\xeau\xd5\xdc\x12\xeds\xef\x93\xc5\xe1\xb1s\x7f\x80\xb2\xa7\xc2#\xa8\xc2\xc4{?\xc5\xe9\x92\xc0|Y08%\x90\x92\xa2\x006\x8b)\xc8\x96\xbd\xca\xd9?\xb68fn0\xa6\x87\xf61\x9d\xa1\xc2=\x97\xc3\x12\x8d{\x0d\xeb\xad\xd9\x85\xb4\xfb\xb4@9\xf3\xf6\xbfv\x0e\x7f\x9bl\x07\xbf\xf5\xf9?\xe1\xa1\xb2\x0chRjc\xa01H\xb6\xc7gp\xef,>\xaf\x9b\x8d\xcecP\x14#\x01\xcf<\x87\xf5\xc1\xe4\x9b\xeb7&<\x95\xb6\x02\xe2\xf0)\xb4Cn\x9a\xa4\xc4k\x80\xaf-\x0e\xc5~c\xec\xb1|Iz\xb2n0?D\xa7qZ\xe87\xb6v\xb5\xbf\xf7\x14#o\x1b\xf5\xa9\xe8\xdek\xe0\xcf\xcd\xce\xd1~\xe3\x16\x835\xa8{\xecc\x93/\xfb\x0c\xedw\x9b3\xb7\xdf\xe0\x92\xe2M\xfc&\xe0\x9f\x95\xce\xc2\x8e\x95V\xcd{\x8d\xec\x8d\xc9\xef\xdcoTJ\xd8S\xa2F\x9fe\xaf\xb2\x0b\x92?\x8d\x0b\x12\x84\x11l\xdd\xfe\xd7\xf0\xcf`t8\xdc\xdd\xf9.\xde\x99\x8e\xfe\xfc\xf6j\xa7\xfc\xfb\xae\xc7\xdf{\xfbW\xc3\xf0j\xe4E\x18\xf8\xc8\xbd&\xfc\xde\xea~\xefOL+\xde\xc4\x8f\xce\x8b.\xbc\x86\xf7\xcc\x1a3\xb0\xf9\xf06 \xf9\x1b\x8c\xf0\x95%\xd2\xc1{|[\x94\\\xc0{rvt\x89\xfe\xc8\xae\xa5\x9dfi\x9a]\xc0Bv\xd2\x83m\x93\x03{\xfd\x0co\xc7et\x8e\xec\xba\x9c\xed\xad[\xb5\xdfv\xae\xd6\xc6\xf1\"\xab\x87\x94\xe74\x9b\xac\xa4RY\xa8\x17\x13\xda\x13N\xf2\xf8\x0b\xcdX'\x97\xf3\xb4\x87\xee\xf2\xda\xcd\x9eEU\x99T\xea\xce\x9c\xa0\x9b\xc2\xc4\xf6j\x0c\xc2;J\xbe^`\x84\x8b\xe8\xc8\xa2\"\x8e\xcb\xd5\xca\xedv\xc7X47\x97|\x8e\xa5\xf3\xb1\xf6\xa6d=,oN\xab79q\xb6\xbd\xb6\xa8^\x9bf\xf9\x8f\xe0,\x82\xd3\x08N\"\xb8\x88\xe0(\x82\xcb\x08\x8eG\x0d\xe1\xd59\xf6J\xdfd|\xc5V\x92\x0eYB\xe4\x9f\x9f\x86\xcd\xb9\xbf\x97\xb4\x1e\xa6 I'\x90\x14@3\x06\x8b<;O&x\x02\x98(\xb6j\xf4\xdc5X>\xf1\x8f0\x80WA\x16\xc1\xb9\xc3%\xe1#\x1a8\xc4x>\xfa\xba\x1a\x80\x1c\xc2\xa4\xda:\x93\xae\xd1|\x86\x01\xbc\xe7\xa3\x998F\xf3Y\x1b\xcd\xe7MG3\xeb\x1a\xc2\xf70\x80g|\x083\xc7\x10\xbe\xd7\x86\xf0\xfd\xa6CXV\x00q\x96\x1d\xe1\xa3\xf9\x03S]a\x91\x11\xfbh\xfe\xd0F\xf3\xc7\xa6\xa3\x19W\xa3\x19w\x8d\xe6 \x0c\xe01\x1f\xcd\xd81\x9a'\xdah\x9el:\x9a\xfa\x91\xd85\x9e\x9f\x1c^K\xeaB\xee&\xf8 5\xe41#;\x8c\xcbQ\xd8\xfc\x02\x0e\xe1\xf7\x00Uh\xbd%\x176\xca\xbbo\xc4\xdd\xe7\x82\x88\xda\xf9\"u\xc9\xd9\xfedsb\xa9\xc8l\xfd`\xeb\x9a\xdf\x8f0\x80\xd7\x81\xab\xda\n\xce\xee\xc7\x0d\xc6\xf8c\xf7\x18k\x87g\xd7\x10\x7f\x86\x01\xbc\xed\x1e\xe2\xcf\x1b\x0c\xf1\xe7\xee!\xd6O\xe8\xae1\xbe\xc0\xec\x8d\x9dc|\xb1\xc1\x18_t\x8fQg\xb0\xbaF\xf8k\xc7\xd0N\x91\xf9)\xd90\x9f\x81\xfe\xaax\xd6\xe74\x18\xf6\x12F\xe6E/\x02\xc1g\x8f0\xc9N\xcb\xcc\xdd\xe5\xe9\x01\x9a`\xd5\xb5\xed\xf8U\xc3\xa4_\xd1E\x82#\x0b\x86\xaa\xd6\x97P=|'\x1f\xeaT\xe0Wd\xc0\xf8\xd3\xe7\\\xa8\x8c\xa4\xb9]\xac\x83{\xb0\xfcJDVKC\xde\x95\xe6\x85\x995\x0e,\x99\xc4\xd4\xe5\xac7\xdb\x89\x13\x1a\x83\xdc\x85\x12/a\x00\x1f\xba\x91\xf6\xa5\x0f.H`\xbd\xf4\xa5\xc6V\xab\xb7\xc1{\xa5\x9dF\xc1\xcd))7\xa3/w66X:Az\x05m*\xf6\xb7\x0cZ\xa6\xf8g\x0e\xef\xdb\x97\xf3T\xea\xae\x98U\xbeK\x84\xcf\xd5\xe5<\xc5m\x8b\x7fa~\x12\xd7\x9a\x0b=\x0f\xff\x86K\xf9\xf2\xdb?\xaf\"\xfe\xfdW_\xe5d\xaa;\x03\xac\x16\xe8\xb4F\xfa\xb8\xaf\xc5\x9f\x0b\x91\xcf#!\xf2w\x95\x16\xe6]\xf5\xe4\x10\xfe\xf6\xf0\x907~N\xf2\"\xc9\xe8\xa0\xb7\xd7\xdf\xed\x01\xa1\xe3l\x92\xd0\xb3A\xef\xe3\x87\xefw\xbe\xed\x1d>\xfa\x8dJ\xb7v\xf8\xe5\xf5+ \x97\xb8\xc40\x8e)g>O \x9c\x11\x8a\xc9\x19' B\x94\xfef\xf5~R\xd7yY^\n\xa7\xd3\x9fsQ \xb8\xfd\xdb\xf1\xd7\xbf\xdd\x0e~;\xde\x0e\xbf\xba\xed@\xf6\n\x88\xb2\x84\x94'*C\xddXx\xa6,\xb5\x93\xa7\xa8/\xfb\xe5\xf5\xab#17\xe1J\xe2\xe3\x01r.\xcb\xaa\xd5\xdb\x13\x9b\xe0\xfb<\x9b\x8b\x8d \xdbk\xcfH)\xc5l\x92]\xd2%\xd9%a\x08\x87M?\x98\xa4\xf2\x83\x81\x83F\x8eJ\xe9\xa3\xa9\xa7?q\xba}\x9d\xcb\xcc\x86\x7f\x1at\x85 \x93\x17V\xe2|\x9a\x8d1\xcbN\xbf\xc0\xc6-\xfa\xa5Joi\xdbZ=\xa1\xa4w)MD\x16\x94byZ\xb0<\xd8\x0b\xfb\xc5\"MX\xd0\xbbe\xd2\xc6\x80\xee\x9f\x9eCB\x81\x86@\xfb\xb3\xb8x{A\xcb\xdc7\xb9pS\xc4(\xc3a>R-\x0e\xb8XE\x86\x132\xce&\xe4\xe3\xfb\xe7O\xb3\xf9\"\xa3\x84\xb2 \x1f\xee\x8e\xc2\x11\x0c \xe7T\xe8\xd6-0\xbe\xb37\x12v\xd5\x9e\x0f>\xa9m\xdd^\xb3v\x1a\x1b7m\xb5Z\xc5\xfd\xca\x97\xab\x81\xd0\xd6\x8cD\xca\xfdA\x0f\xb6MO\xc9\x90\x19\x0d\xb3\xfd\xdf\xb3\x84\xe2\xf2\xb4\xa7&S\xf5\xb8\x07\xa5\xe6S\xcb\xb9\xa1r\x17Sr\x01$`\x9a\xb9\"\x82\xde\x92Mw\xbe\xed\x85au\xb7w\x1a\x17\xe4\xfe]\xd3\x18\xaa\xd4A\xed\xae3\x0c6K2Z\x1c\xe3[6\xaf\x9d8]\xccb\xcf\\\x83\xa0\xbb\x8f)m\xe2\xac\x17\xe2\x16J \x07h\x9c\xf3)i\xcf,G\xb6yc\xce \x9be\x93k\x8fF|n\x1b\x8fz\xea\xcdD\xb4\xc7\xc8\xe2\xb3\xbf\n\x9c\x8d!{\x0f\xd2\x80\x99\x8d\x14S~\xec\x8c\xc9I\xa5\x8a\x8d\xe6\xe4\xc7z\xfa+_^b\xf5\x10\xd1\xd8\x96\x1c5\x88\xbd\xeao&x\xbb!\x8d\xf8\x06\x8dL\xfb3\x0f\xb5\xc4k\xfb\xbb\xb7\xcf\"\xe8m\xf7\xc2\x91\xdc\x9f\xa6%\xb5R)\xe6\xda\xd4\x86\x94]\xb5\x95\xb48\xd6\x94J3N\xb8f\x15\xe1\xa2\x9aSN\x97\xcb\xc8F\x1e#\xf5\x91\xd7a\xae\x94b\x96\xbcd^\x04\xd8X\xa0\x063\x8ektL\x9a\xb31\xa5Q\x9e\xcc\x03m\x91~\xc3\xecx\xbd\x13\xb4\xd8\xf4z\xae\xe1Z\xb2\xaay\x0d\x93\xc3\xec\xb4\x82\xd9\xc7\xb6{Yd\xc8\xe3\xe6\xd54ig\x9b\xe8N\xc2z\xfb_\x97;%s\xdd\xb9l\x915\xf7\xdc_9Bi\xffY\x97\xf6\xa5ui=ZK\xbb\xd8ZZ\xbd\xfc\xa7\xf2?\xd5\x83\xb2\x90\x16\x0d\xee\xdd\x0d\xfbO\x96\xd3)\x91\xde\xe2\xd7\xca\x06hN\x88\xd9\x9cfI\xa9\x8c\x92\x99\xc8\x15\x0f\xff\x7f\xf2\xde\xbc\xbbm\x1cK\x14\xff\xbf?\xc55\xa7_\x8a,\xd3\xb4$\xaf\x91\xedx\xb28\xdd\x99\xc9\xf6b\xa7\xea\xd7\xa3\xf2xh\n\x92\xd8\xa1H\x15\x17;\xae\xb2\xe7\xb3\xff\x0e.\x00\x12\x04\x01\x92rR\xd3\xfd\xde\xe3\xc9\x89E\x12\xc4r\x01\\\xdc\xfd\x9e@\x15\xcb\xf2\x13\xf1\x83\x9c\xc7\xa2\xfc\x17$\x0b(\x81p\x047a\x16\xe6\xb0\xc8\xf3\xd5x{{\xe6\x07\xe4:I\xbex\xf30_\x14\xd7^\x98l\xa7\xf4\xbb\xedi\x12d\xdb\xf8\xf1\x16#\x9fRo\x91/\xa3\xd3P\xc4nd\x94\x86\xcb\xf3\xb9A\n\xc7\x90\x1fA\xba\xb9\xe9@\x0c\x9b'`=\xf1\xd3y6\xb94Q$\x157\x97\xa2\xcb\xaeB\x1f\xb2:\xeaq5ED\xcd$\xed\x1f\x94\xb3\n\xc8\x99uG\xe2l\xa2\x99\xa4\x16\x1dS\xe5\x15\x98C[\xd2\x1a\xd8\x12\xc58j\xc4\xca\xca\n\xef\xbb\xc4\xa8'\x14\xd8\xe7\xa4\x1f\xac\x932\x1a\xf1#\x9a\xacB\x19\xcbcf\x1d\xa8nz\xf5#\xcb\xfd\xe0\xcb#\xba\x80\x11\x98\xd9\xb8\xe9/:r\xfa\xb7W\x9b!\xb7\xd0}D\xb3\xc2\xb8\x17[\xd6\x18\xfd\xf6j?\xc5H\xcfk\xb5^\xd4\xb3\xbd\x88\xa8=\xad\xca\xa8\xf2\x84\xc84'\x04\x8b\xac\xc3\x8c\x102x\x06{p\n\x19l\xc1\x1e\x8c1\xf3R\x00'\xb0w\x04\x01\x1cCv\x04\x01E\xe3\xd1$\xa0\x05.\xe5\xda&AKb\xf0\x1b\xee\xa5n\xb6\xa3\x86R\xdb3\x93\xe9\xac\xd4c\xc1\xb0\x8d\xe2:q\xd1\x16\xd0\xd4\xc4\x9eux\x8a\x03\xb75 \xdb\xe5\xdf\x1c\xdcR,h\x8a\xc3\xa3p\x8afOSzb\xc2\x7f\xd1\x9f\x05\xfd\xf9_\x90\xcc\x90Zd\xcfV\xecYV\xacV\x11=\x7f\xf2\x84=O\xf0\xb9\x0b\xe4\xeb\n\x03\x9c\x80\x1fC\xe9\xd8\xe1\xfd=\xe3\xa1\xbf=\x8d\xe8A\\z)\x19\xc8\xb3\xbch\xe5X\xc4EK\xde \xe7\xb2\xe8H\xe9\xde\xa9\x8b\x16\x97\xb0\x8d\x99\x95\xd9\x03\xdb\xacN\xe4\x0b\x1d\xf3y\x1eJ\x91~h\xb2taQ\xaeo\n9\x8f\xc2pQfP\x88\xda<\xf1\xc5E;?/\xe5W\xf3\xd6\xf2f\xd8\x1a\x82\xc5\xf5\xda\xe4\xd9\xc2_\x911\xac\x9aoD\xa07\xed\xcb\xa5\xbfzY\xbe\xef\x8d\x1ef\x88\x9c\x1ew\x06F\x18\xe5>\xb3\xf5\xe7\xb6\xb6\x87X\xbc\xd9Z\xdb\xf9\x8a\x9f\xf4<+\xb5'#V\xd0<\xeb\xdaN6\xb9\xcd\xae\xb3\xcap2\xb1V\x0dg\x8d\xae\x9f\xbf\xf2~\xfe\xca\xfb\xf9+\xf6\xf3WM\xd9\x94\xc7\xfb\xcfl\x8b\xed\x7f\xcb\xed?\xe1D\x87.\x9b\xb3\xadi6,S,d\xf6\x9a\xc7\x99\xec&&z\n~\xb3\xaf\x82+\x11|t}\xbb\xf2\x11h\x9c\xc7\x84\xfeu\\\x1f\x1e\xb3R\xa5\xef\x85\xfc}\xac\x8e_\xf4\x97\x16\xaa0+r\x1ae\xcen\xbb\x14>\x03\x06F\xac\x05\xdf}\xd0\x8c\xac\xd00]\xe2]\xce\x8f\xe1\xb4\x0c\x9e\xa7\x9b\xb0\xb5N\xe0}~\x02\xefK'\xf0\xbe\xee\x04\xde\xef>\x81\x05\xd5\x00'\x80\xa6+)\x0b\x9e\xc7\x8c\x1c]\xe1\xbd\xcb\xe2\xb3\x9e\x02QQpm`2\xe2\xe5\xc9\xe8\xa5\xe3\xb14u\xa2\xc0\xf6\x1b\xe7\xe3\xad\xcfl\x9f\xb2\x15 \x18S\x16\xc6\xac@\x88\x05<\x94\x97\xb0\x86\xebk\xad\xb1\xa2\x98&A\n\x0f\xbc1t\xb4++\xf6\xc2\xac\xec\x96\xfa\xcd\xa0\x16\\U7\xed\x99\x96\xfco\xd2ar\xf4D\xed\xec\x8b\x89\xa7P6\xa9X\xec\xac\xd5\xe44B\xda\xa6#\x87\x8f\x81X \xdb\x89\x95\xa8/\xb1\xf2_\xa5\xac\xe0\xbft\x14\x8aQ\xec\xd8\x8c;\xe2\xb4\xc2=2\xc9\x1b\x9b\xa0\xaf\xe0\xaeI\n\x02\xf2\xc6\x8b\xb4\x1b/(7^\xc4I\xdfH\"}g\x8c\xf4\x9d\xc11DG0\xa3\x1b/\x98\xcc\x9a\xa4\xef\xcc\x10\xd0i\x85\xaa\xa6\xc44\xe7\xb1\xbdj\x9ds\xbaf\x0b3\xfd\x84F\xd0\xf6\xeaQKB\xa2_3\xcd\x92X\x18\x96D\xd8E\xbf\xa2K\x00#\xd5\xfa,\x10fW\xc1'S\xef\xe7\xa3\x19\x00-#\x1ce\x0d]\xc4y_\xa5\xc9\xea\xa2\x1cS\xd6\xe8{\xb9\xe2\xb4\x99V\xca\x95s\x83\x91\xab\xca\xc8\xf5.\x92\xb8\x03\x97\xd3\xac<\xa1-,\xe1\x18\xe6G\xb0\xa4\x8b\xc4<\xa5\x18ZJE\xb27.,\xcbEL{9\xa1\xfd]\xd2_\x97V\x89t\x03\x13\xb5K\x81x'\x9f\x82\x08\xae\x12\x80w\x1d\xf3\xd0\xb1\x19\x85xC\x17.\xbb\xb9\x1f[\xb7`\xa2\xdd\x82a\xb9\x05\x13\xc7\xe5 \x10\xc1\x87cH\x8e\xc0\xa7\xd0\x0c'~}\xbb\xf9\xe6s\x0eQ\x07vU\x01r\x88:]\x16\x7f \xf3\x8d\xb8r\xb7\xab!\xa2[\xae~\xfe\xcaq\x84\xdaq\xf8\xe58B\x8eJB \x95\x14\x0c\x95\x14p\x0c\xe1\x11\x14t\\\xfe\xa4h\xa2\x92\xc2\xa4E\xe2(\x8cLrC \xe3^\xca\xda\xf6\xd2\x17r\x97]H\xfb\xc9NV\\\x08\x9a\x91 \x89\xa7e\xd7\x9c\xe6V\x8bM[\xad\xc9\xe6\xb6o5\x90\xa1\x8b\xe1~\xe5H=\xe5\xbe\x9b\xb1}G\xb1jP\xee;\x8a\x9cW\x1c9\x9b9T\x81N3u\xef\x05.\xcc\xca\x99G\xa4\xb8\xf5\x8c\x02\xc5\xa6\xe3\x08&\xb3K\xfa\xcc\xa9v\xa1\xdf\xc6s2\x8bi\xe3Nl\x92\xe5\xa0\xc5\x8a\x0fNs\xf5\xea\x0f\x98l\x9d\x9d<3\xd3\xe7\x92\x05\x8bb\xb7U1\x060\xae\xbdk\x9eK\xb1\xa9\"\xb4\xd1\xd2r\x15\xb5:G\x97Z\"\xee\xff\xa5\xd3\xfe\xb1\xc7y\xd1~\x9cO\xff\x87\x8e\xf3\x9b2\xcec%\xffi=X\xbb4\xebK\xc4x7-\x18o\xd9\xb5\xeb\xe9)\xbdTw\xfd\xc2\x85\x9b\xda\x89\x8b\x1c\xe2M\xf7Y\x0b=%J\x9d\xc6\n\xed[u\xd5\xdc\xaa\x95|G\xfeT\xfc\x925\x85\xcc~\xecQ\x8a\xa3\xed\x1f\xcb\x9f\x8c\xc3\xde\xf2\xb3,\x9cWl\x92\x1d8p\x1e\xc6\xd3\x94\xc0y\x92.\x8a\n\x01\xfdk\x14\x06$\xce\x08\xbc{sQ>\xfcq\xbb\xfc)tR<\x8d\xd9\x9c\xe4\x92)\xd7\xf9\xdd\xf2:\x89\xb2\xa6\xae\x8a\x97\xae%\xb9\x94\xbek\xea\xae\x1a\x1fp\xcb\xca\xbb7\xd9Y\\,\x19\xda9\xd2\xc2\xcdH\xc4\xe8=\xa9pS\xf3\xe6\x18\x94Z\xc3\x89\xdcp\xbb<\xba\x83\x85u\x93\x7f\x1d\x98|\x11\xc9\x04\xb1\x8e5%\x96\x0b\xd6\x1e\xb34\xd4\xc2\xee\xbd\xbf$\x99M\x9c\xc9\xe0\xb2\xb5\x0355\xf1\xef\x0fL)<8\x82\x18\x8eaH\xffR\x84\x97O\xac+\xba\x15X\x0f1\x0f\xd3\xcb\x85\x9f\xbeL\xa6\xc4\x8e\xd1t.\xd6\xf7\xd7\x1a\x0cG;\xbb{\xfb\x07\x87O\x99}KK_s\xc5\xa6\xadK\xc4\x95\xabq\x84\x00$\x0b5\xab=\x8c\x8bXw-I\x91\xe8\xc9p3\xb4\xb6\xb2\xd2\xb6\xc2\x94\xd7\xc4\xbb\x9aE\xfe<\x83'PPZ\xe5\xa5\x1f,\x08K\xa5@[\xd1\xcbxo\xcaLG\x154\xe8\x17)\xd1$\x80\x06\x11\xa7\x82%m\xc2\x82M\x9c@\xc6\xb2\xb8\x02\xed\xe7\xb55!zV\xed\xea\xc3Vm\xfb\x0d\x8fx\x1fO\xc2\x8e8\xea\x19\x02\xddw\xbc\xabi\xb2|\xf3\xaa\x9d\xa2f\x16\xb2Z\xaeN\xbepTGU\xd4\xd1\xe4\x08\xa1\x91`P\xfa\xf3\xf0:\n\xe3\xb9Yy..\xda`d'\x94\x8b\xecjP\\3\xdbw\xa1\xcd\xa3K\xbe\x02\x9e\x91FC\x08\xa8\x97Y\xe7L\xaf\xd4\xb6vF\x16\xed\xa7\xb1\x98A5\xdd\\\x12bi\xde\x9f\xe8\xd7\xe6\x9f\xf4\xdf\xeb\xb6\xc0\xb4\xb9\xb5\x19\xd1\x9aU4(\xbd92\xec~&qa\x96\xd7\xb0\x81%M\xc4\x03w\x7f#\x98\xda\xdb[\xf9)\x89q\xc3:\xb2vA\xb3\x01p?U\xc5\x0d\x83\x83jI\x91\xd2U\x11\x87q\x84U\xa4\xde*Y\xd9\x8e\x83\xd8\x8a\xf6Y\x98U>y\x02+z\x96\xaa(E\x90\xac\x7fj\xb6%\xb8\xe3\xfa8\xe7$\x7f\x19%\x19\xc9rq\xc6\xbcN\x93%\xed\xf2\x18\xa6\xaeZ\xb4Y\xa6\x9d\xfc\x12\xf4\xfeT\x1b\x97^\x82 \xca\x0b\x99I\xba\x84\x13y\x18\xc2\x9c\xfb\x87\xd5\x81\xd8\xe8\x1c\xfd\x86vLt\xb2\xabsa=\xfb:\x91Z\xc6\x98\xcc\xd6\xce\x0e\xba\xf2T\xcf%7\xba\xf2Y\x07\xa7\xc3V\x98T\xdc\x11V\xf7\xa4\xaa\xfb#\xae\x13\xd4\x8f\xda\xd6\xce.\xb6\n'\xf5\xb7\x86v\x8e\xca@\xfcl\xc5\xe4b\xc5\xe01!\xf7\xdd\x08\x7f\xa9P\x1b\x84W) \xe8\x96\xadvl\xc3nD\x14\xe1KC!ub\xf9]\xafe\xd3\nf&L\xe7\xd1\xb2\xe9\xc9Y\x1b.\xdd/E\x14\x19\x8d\xa5\xf5<\xf8\x02\x9f\xaa\x04\xa4\xdc\xc5\xea\xb0\xac\xbeR\xce{\xe6\x1d9\x06k\xe4\xedy{\x96\xaeMM\xc0\xe6\xab+\x86\x01\xe8\xdf\x13q^~+);\xd0\x19\xe0N\xac/a<\xa5|}J\xb2$\xba!,\xf7Z\x9ca\xae)z#D\xc8\x1ff\xf4n\x95\x92i\x18\xf89a\x9f\xacR\x92\x91\x18\xcbq\xf3\xffs\x9e\xec\x8de}{\x1e\x85~F2\xeb\xb2I.O\xac,\xf0#?\xc5\xb2\xe4\xd7\x82\xc4\x01~\xb7\xf4W\xab0\x9e[\x97\x1d\x92\x11#y\xe5\x82__ \xe1\x8c\xe5\xb9\xc8\x85'\xac\xcc\xe1\xe6}\xc3\xb4\xd3Z\xb6x\xd8 \x0f\x9d\xc1?\xcc\xd0w\xb7b\x1bS\xfb\x87\xcf\xf1\x978\xb9\x8d\x81\xa9.\xc0\xfa\x81\x13\xa8?X\x10f\xb0$9%\x80\x90KD\x03oHf\xac\x0cae\xfe\xf6\xfc\xdd[\\\x04\xde\x0f\xcaju\\\xc8\x17a\xe6\xe5\xfe\x9c\xae8~G'\x0f7:\xfe\xe0\xf1\xed\xf9;>\xa1\xf8Z\xfc\xbe\xbf7\x8b\x96@b\xd3\x15\xb3\x07^c\xb9.\x98[Ky'\xd7\xda\xea*\xa1\xad\xb5Z`,\xbctu[\x1fO\xb9\xf4\x18f+\xef\xd4Q\xf35\xc9\xc7-\xee\xea\xa5\xe4\xc5\x8a\x05k\x0f\xeae\xe5\x85\x8c\xec\x1cs\x1e\x95\x9f\x96\x1f\xf8B\x9e%hB\x8c1 \xaf\xb7\xb8\xaf\x08'\x9e\x90\xcb\x9eK\x93^\xfe\xa4d\xc6LR\x9f\xc6\x82\xf2\x1d\x17\xf8\x92\x0e\xab%-\xd6\x95ii\xe3Rc\x0b\xbb\\\x82b\x81W\x165\xf4@\xea\\\xd9\xbdx\xf4\n\x85\x8dvG\x8em\xdd~\xc9\xd4\xf8j\x8c+\x1f\xee\x1b\xd8\xf2\x1d\xc7cR\xdd&s\xaeM\xdc+\x99\xe3\xda\xfd\xfc^\xf8\x02G\x91\xdb\xfd=\xd8\\\xf6\xe6\xd3\xd9\x0f\xc5C\x1f\xf5\xb0cH\x1c\xdbb\xfda\xc6`\x92\xb3\xd4\x83\xe3ey\x82\xa9\x92\xd3>\xb0\xd1#\xfd\\\x0e\x15_\x0f\xdc%\x80\x19\xda\xb1\xbd\xb7\x7f\xa8\x06\xacO\xf8\xab\xa7CG+7\x08\x8dC\xef\x1f\xa3\xde\x10\x9f\xfe\xe1O\xcd_\xe5\xbel\x13\x89\x0bmD\xdb\xc1\x00\x1c\x81\xab\xf6}\x15\x11\xa7\x17\x81)\xce\xf1\xa5\xf0\xae\xfa\xb0\xb3Y\x90\x08\x05S\xb0Gz\xa5,_\x96\xf1}\x88!\xe1\xcc\xef\xfd\x8e`*\xed1\xd8J:\xb5`bH%\xeb\x19\xc1\xbck\x98\xe3\xa6@\xd5u-\xef\x1a\xe3V\x18%[\xb0\xbcj\x94EbHW\x8e\xa4\x9e;G|\x9c\x06\xe6\xb5_`\xb7\x90\xa7\x16\xf3\xb5\x88\x0e\xa0_\xbe\xaf\xee\xa0t\x1b\xe8\x18\x9bIi\xc6\xb2\xf64c\xd0\xb3i\xe0\xcb+\x14(\xd67W\xa7\x1f\x9f\xf6\xa9\xe0\xa1\x1a/\x1f\xd8\xea\xd4\xd0\xcd:\x91\xb7\xd0\xe6\xfayN\x96\xab\x1c\xf2\x04\xa6\x84\x1d\xf5E\xca\xbc\xd9\x84\xbdni`\xa0*\x03\xaa\xcdl\xf7\xa2^%:u\xbf\x1d\xc9\x0f\xf7\xb5H~4\xfc\xbf\x16\xc9K\x07\xa0^\x1c=\xdc\xd3\x82d\xf7\xa9F\x1a\x1d\xdb\x0d!u\xc1\x1e\xab\xa9M\xfaz]\xa3\xf2\xc1\x05f\xbd\xb2\x02\x0c\xe0\x0d\x99\xf7Z\x8f\xaa\xa6e\x81\xbf\xe8\x0b,\xca\x02\xe7\xfa\x027e\x81\x8f\xfa\x02\xcb\xb2\xc0\x0b}\x81yY\xe0g}\x81;8\x81)\x9cB\"\x92.\xd1\x99\xe5\xd9\x97~7e\x11\xbb\xc6h&\xa5\xb6W_\xe8\x8a\xd7\x9c\xc2\x18\x16\xf4/\xcb\xecd\xa7\xbc\x95\xdf\x1f\x9c\xaa\n\x03\x9b\x8f\x9a\x9ei)\"\xca\x1d:1\x98\x9a|\x03\xf3\xe0^)\x11\x8a\xae&\x11\xd3\xb1\x14\xf6\x1d\xaa\x7f\xe8h(\xb1\x1d\xc0)\xbe\x841\xaa\x81\\\xb8c:!\xac[k\xbf\x85\xa5O\xb14\x8caI\xcb\xd1JB{\x86&yc\x98c\x07\xb0\x9a\x13\x98\xc1i\x07c\x00\x12\x83_\xd1\xb8z\x0b?\xf9B\x96n\x11f\xb5x\x1e]\xe2\xd3\x0c\xf3#\x83\xad\xea\xd6\xba\xbe\xa3W\xe0g\x04\x06\xe3\xcerP\xb7\x8f\xd1L\xa1za\xcd\xc3\xf5k\xb6u\xf8\\\xbd\xb0\xf2\xd1c*\xd7\xc60\x92\xaf\x0ea\xb1Z\x996W\x99\xb8\xccu\x95b)f5C\xe7\xdc\xad\x94\xa3\xfa\x1a5\xdau\x90\xc4\xa1\xd5\xfebr\xd9r\xc3\xea\x02\x88\xb3d\xd47\xca\x86\xa8N\x91\x19\xae\xfe\xd7\xfc\x0d\xaa5]\xc0of.\xfb\xcc\xb6\xef\xbc\x1b\x96\x14\x1b7^u\x87\xb8\xc4a[n\xe6r\x8c\xf4\x89~sM\xff\xdb\xb8\xa6\xaf\x9e<\x01\xdf\xbev\x01\xab5\xa7(\xc9\xbc\xd7\xcci;\xf3\xfe\x02'0\xa2?\xce\xe1\x04v\xe9\x8f\x8fp\x02\x87\xf4\xc7\x0bZf\x9f\xfe\xfa\x19N`\x07K}\x86\x13\xd8\xc7b\x9f\xe8\xdb\xd1\xa1[\x93\xb70Q\xfc\xbaR09\xeeT\x85=n\xc3x\x9a\xdc\xd2!\xb1_\xde;\x0c2q\x82ZL8\x15\xef\xc7\x86\xcf3\x12a\x10e\xfaW\xfd\x14\xdf\x8dAL\x84m\x89\xd9^\x84\x99\xe5\xc8\xa6_Zq\xdb\x9c\x8b\xdb\xe6\xdf(n\xeb\xe2\xbc\\~b\x8f\xf6\xd5\xd3\x16\x03\x81\xd1S\x9eE\xcaN\xeb\x9cT\xda\xceI\xa5\xa6e\xa1e\xa0\xda=\x1aPBEx`\xb0\xb0\x96\xd9(w\xb5\xc7\x7fT\x901h\xd4\x83\xa44r\x1ak9\x9b \x89g\xe1\xbch)q\x9b\x86\xb9x[\x1f\"\x86\xa0g\x07r\xec\xd6T\xb1\xd0=wfym \xd1\xd8\xde\xdb\xd9Q\xa6\xa8\x9a\x91Z\x7f\xf4M\xeavH\x8d\xfb\xd4\x8b7\xe3>\xfd\xff\xc6\xb5\xa7\x8e\xeb\x8f_z\xe52j\x17\x15\xd6\x94%\xc3#\xc8\xb5\x860\xb9\xde\x10\xe6F\xcd\xd4\xa0\xb5NoDr\xeb\xb0\xea+\x0dUx\x8072I/\xb9\xf7\x94\x89\xe3\x01\xbd\x89\x00=\xa8\xde\xef\xef\x0d\x06\x07\xec\xfd\xfe\xde\xde\xce\x1e]I\xfc\xd7\x13`\xf2&z\xb7\xaby.*\x1c\x94\x95\x1d\xb2\xe7\xc3a\x95]J\x14\x1a\xee\x96\xa5v\x86\xb5\xcf\x87\xa3\x83\xf2\xd5p\xef\xa9\x03<\xbf\xd63\x18\x0e\x87\xbb\xc3\xe1\xd0a\x97\x04\xd3&T4\xbe\xba!\xcf\x02\x87\x9d6\xa11\x8a\xfe\x18\xc06\xc1\xb6 l\x9d`\xf9}\x07\x9e=\x83\xa1\xca\xbe\x8b\x8b\"\xbf\xbd\xfd\x9d\xd1\x80~5\x1c\x8cv\x10&FM\xaf\xce\xac\xb6I\xf5k\xd1\x9a\xeeS\xad)\xf8\x0dw6\xdd~bO\xfc\xad\xdf\xfe\xe5\x92\xfe?\xd8zz\xf9\xfb\xd0\xdd\x19>8G\xdbs\xc5\xe0\x8dR\xc5\xdb\xff\xf9/\xb6}:\xfe:\xf1\xb7f\xbc\xf0\xe1\xc3\xfd\xa4\xfc\xe98\xdb\xcaW,\xe7\xec\xeep_+\xb4n7\xc5R\xc4\xa5|\x88\x89\x1d\xf0\x14\xcc\x01\xe3\xd0w\xf6PO\x92{\x01\x1f\xf1\xf3\xdc\x1e\xe0\xb2\x88Dx.F\xabc|\xab\xaf\xcc\x946\x9f\x0c/\xeb\xb9\xaf\xe0\x140\x80\xea\x9b8\xb7\xf3\xd2D\xcf\x85\xe1>\xa5h\x1a\xaf\x86\xf4\xd5\x00\xe3\xb4\x16v\x8cD\x8f\x01\xcc+\n\xb8\xc9\x93\xe3g\xd6\xe5v\x1d8S\xe9\xcd\xbc\xfe\xaai\x02B/\xeb\x895\x06\xeb\x89\xbf\\\x1diB#[\xc7\xf86\xca\xb5/\x9f\xe1\xcb\xb9\xf6\xe5\x0f\xd6\x0f\xf4\xe5\xafE\x92\x1f5b\xd15\xa7\xed\xc6\x88S\x16\xb2\x11\xb6\xac-\xe0V\xba=\x84x\x93K\x06a\x86\x1eK\x9a\xc1\x85\xe1:\xfa\xe0\xd6dVR2Lq\x0c\xe6z#c\xb4`\x149H\xf8W\x06\xe6\xbeKum\x0coH/2\x89/y\xe4\x1bm\x19]\x0c\x91\xfa<95Z\xdb\xc5l\xc0=\xd2\xe9q\xa0[\x1368\x8e@.y\x04\xf3V \x11\xff\xb4q<\nSW~\xbe5\xcd\xa9\xeb\xdd\\\xf8xN\xd3\x9fE\xcc\"\x1d\xbek\xcfgWJ\x1e\x84b\xd4\xfa\xe5\x17\xcb\x81c\x18p\xcd\x16)\xe3,\x86.X\x7f\x1eZ\x8e\n\x99\x9f\xfc(\x9c\x9e\xc5y\x98\xdf\xbddf(>}\x81x3\x99\x92\x8fI\x88j\xea\xc2e\x9ajZ\x17\x96\x0eI/A\xb4\xd4\xb5'\x86\x9ee\xae\x9c\x18\x08\xbb\xc5\x06\xff\xd7\x1c\x03\x84w\xb6\xb1\x12I\xd80\"\x83\xa8v\xea\xc2\x8d\x0e\x19\xb51Ak\xc9\xd8\xa5\xa0\xd6U\xe0\xcbS)\xc1;\x8c\xf5\xf2\x98\xae\x1e\x19E\xeb\x0dn\x8f1K\xfb\xeai\xcbD\xeb{\x87Z\xd1\xfa\x81Z \x13\xad\x0fGj-\x8f\x93\xad\xbb\x92\xf4\xdc ^_t\x89\xd7o\xba\xc4\xeb\xcb.\xf1\xfa\xbcK\xbc~\x07'L\xb6\x8d\x923.\xe3f\n\x13!A7\x8a\xbc\xcd\xa2\xf5\xc5\xba\xf2\xf8+8\x81kI\xd8G\xbf\xb9\xae \xff~\xd7\xa5Q\xaaD\xechY)\x89\xd8\xd1+\xd3f\x82v\x14\x91\xdfA]\xd0~\x87\x82\xf6S\xb8\x831\xc4\x0eJ\xd4\xe9\xb1\x8c\xc2\xa5\x00\x8fp!&G\xc9\xb9Q\xa0X\x98\x04\x8aw\x8c\xc4\xb8c\xe2@!2\xfc\xec\xb8\x80\xb2\xc2\x0d\x9ee,\xe4\x02\xc3\x15\x06\x08\x10\x02y\xf1\xd6\xbe\xe2\"G\xa301\xf5\x02\xa6\x9eJ\xdc\xffi\xc1\xa2Y\xf5\xa5*\xb3\xb8\xeak\xa0\xaa\xc4\xf8\x06Uw\"\xdd\xa0\xdb\x96J\x00\x15\x9a}hP=\xdc\xf0\xa8\x01\xdc\xcc&\xc4\x1c\"\xda\x85W``KtM0R\xdf<\xf22*\x95\xed\x82\x85\x11\x15~\xec?\x9c\xa0\xe1\x0coH\n\xba\xec\xbb%\xf9\xe4\xa0U\xcd\x0f\x0e\x8fF\xf6\xactu?\xde.}\"\x9e\x19\x03\xfe\xaegP\xa7\xf1X\x8b\x99\xea3\xb7\x0b\xc7\x85\xd4N\xbd\x8f\xb0 \xa9\xf7\x1a~\x84\xa4=\x02\x83\xe0o,\x0b&\xe4\xd2\xa6c0\x02)gF\x03\n\x05}\x7f\x0f9w\x88\xa3_K\xd9\xe0\xeb\xc3u0 #\xc6O\xae\xb15\xddG\x15\x8e\xba\xeaU\xdc\xc3\xfa$_\x84\x95\xd1\xfa\x83,on\x9a\x19\xd0\xfab:\x0c\xa3\xb4\x1aq\xd5\xc0\x05r\xe3G\x8em\xb1\xc7U\xf5F# \xcd\xb1Y\xc9\xdc\x11\x93\xb1[\x1d\xaf\xf6\x9d\xa4\x905Q\xe3S\xdd\xe6\xfc\xfe\xa2\xc6^\x9e\xb37\"\x19E\xa3\x01\x91xb\xacMT\xb1\x08\xb3SV\x160\xf1\xf0j\xb9\xd0\x84\xe7C\x91\xd89\xf6\xb2\x15 \xceIDh/2\xcd#\xbc\xfb\xb7,i\x15\xf7\x89\xa3\xcc\xf4\xad. \x8e\xb8x\xa7}\xbb\xa0\x0cmi \\\xd7\x1e\xd25\xa8XH\xff\xfe\x80\xb1lb\x9d\xa5\x80|}H\xc3\xb1\xc6\xdeF\\\x0f\x18\xd5\xd3\xd4l\xeeB\xd8\xf7x\x85j0\xe2\xd4\xb8\xf5\xd3\xd8\xb6p\x95\xde\xa6\xfejE\xd21\x04I\x11M\xe3\x1fr\x98\x13\x16\x17\xd4r\xdc\xa6\x9fa\xb3 \xad\x17\x99@dt{\x0c\xfe\xa1\x86\xf4\xcd\x86[\"\xe3\xf2\xcdGiZ\x7f\x15\xaa\x9bO0\xae\xcd\x944\xcc\xf9\xae\xbe\xc9v\xbc\x81g!\x8d\x9fW\x0c\xdan\x17\x13f\xe6\xfe\x0f\x9d.\xeeU\x1d\x15:\xc1\xa7h\xe3\xcf\x08\x91J\xde\x8eqCE\x02l?\xe6\"\xf7\x0d\xc3\x88\x1f-R\x1c\x1d\xa8RBLy\xd1\xe4\xd1d*\xa0\xa4\x06\x18\xda\x96\"\xb2\x887M\x8e*\xa5\xfcb\xd2\xcaQ\xea\xa1\xa7\x0f\xcf$\x8f\xa6\x1f\xaco\xfa\xc4V\x16\xae\xbdL\x03[\x03\x03\xed\xba\"\x0d[s\xa9tx?\xd6\xfc\xb2\xdb\xcc\x7f\xae\x8b\xf9E\x92D2\xb3\xd9\xab}I\x90\xac\xda\xa7\x0b\xab\x1bu1\x84\xdcv[uZ\xf2+k\x80\xfa\x99-\x9f\xb23\xa6\xf1\xdc\x95\xa2\xe6\xd4\x0b\xab\xd1s4\x87\x13\xba\xb4\xa3\xeb1\xda\xe8P\xb4\x8a\xe4Qj\xc7\x8ekN\xdb_\x1e\x0d\xa2\xdaZ\x89\x1a\xe1\xfe\xd0h\xcf\x9a\x93\xdcb\x91j\xe8\x9cg\xe2\xae\xb9I\xad\xe7A@\xb2\x8c\x9e\x7f\x18\xab\xb9X\xd19#S\xd36\xb5\x90d\xe1u3\x86\x8c\x99\x87\x95\x0e)kn\xe4~Vb\x0dw\x84\xb5\xac\xc4\x1e\xd7\xa4\xbab\xbe\xa5\xc9N\xb7a\x83\xcb\x81\xce\x88,\xb6w\xf6v\xb5\x8a\x91}Uz[\xf0\xe2\xaa\xe7\x02J\x9f\xecCu\xafD\xac\xd1]u\xe4L\xf1\xaf\x96\x9ei\\\xadV\x18\xb0\xb3\x0eS\xb4L\x9b\x93\xfcc\x92Dd\xaa\xe6\x87Xh\xe4\x1a7%2)\x1f\x97'\xeb\xb2\xc1\x1d\x9cy\x98\xde\xea\x13 \x928\x08#r\x91\xfaq\xe6\xb3\xd2O\x9e\xc0\x0d0'\xff\xe1h\xc72YOP\xeem\xa2l\xdb8\xccY6\xcfq;\xe3\xc5<]\xc34\xbf+i\xdb\x8ce\x18\xc3\xbc\x18\xecX\xae}\xa5\x88\xa54\x82\xabu\x1a\xd98\xa9\x9a\x81S\xb0g(\xb5\x0d\x08%\x19\xcd\x9f9.\xdc\xdaH\xfe\x95\xdf\x9e\x18\xc3\xb0?\xa8t\xe6z\xc0 \xfc(\xba\xf6\x83/\xff\xbb \x05\xf1R\x92\x91\\\x11{<\x16\"\xf5\x9a\xe3$\x0fgw\xcf\xa3H\xad\xbd\x1a\xc8\xa5nI\xdd5\xe3\xff1\x1f\xe7j\x98\xd2\x9a\xb2\x9d6\xb8\xf2\x95\xebj\xfa\xd7\xd8\x07\xa2\x19\xcd\xba=i[\xd5R%\x1b\x83v\xdb\xa8\xeb6\xe35\xe2]-\x93\"\xce1\x15\x06lA.\xdf\xb7V{\xd5F\xdej\xe1\xa2\x88G\xeb\xab\x96\xc5\xfe\x18\x8ev-\xc4\x9c\xe2\xb9C\x7ffI\x9a\xdb\xd7\x8e\x0b\xab\xcd\xcdz%Ud\xba*\xaca\xce\xa3\x1a6\xd7\x0b\x17tR\x04:\x9b\xc4\x06\x0fQ\x1f\xe7\xe8jE\xe2i\x18\xcf_\xf2\xd9\xcb\x9a\x0c\x1c\xba\x156\x0b\x96\xb3_xQ2\xbfHVo\xc9\x0d\x89>a\x88'c\xa0\xa3\x1b\x1e\xbd\xd6\x90\x9e(\xf4\xae\x82\"MI\x9cs\xc6\x0c\xf3\x89c\x9e\x03?\xc8E\x1b?3\x16\x0b\x8f\xe4\x88\x8d\xa2\x11g\xcba\n\x03\x8be\x03,VS?',\xb8WD\x97\xd4{\x7fI\xe8\xaa\x14\x0c\\\x1e.\x89\x9dt\x19\xab\x00\x87F\xe6\xadH:K\xd2\xe5g\xac\xf7\xcd\xec=\xa1\x84\x85\x9f\xde\xd9\xa1\x8bF\x0d\xcd\x85\xcct\xa7 *n\xa5F\xcf\xe2)\x8b\x0c\xae\xe7>{D\xbe#\nf \xf1\xaf\xf4\xaf\xedO\x82K\x97\xef\xc2\xe2:\n\x03\x11\xb8\xc6V}>\xfe\xd4\xfc\x95\xd8\xb2\xdf\x19D*R\x9c\x93\\\x1a\x1b\x9f\x90\xac\x03\x8d\xf1\xad8oC\x87\xc2-4I\xfb\xe0\xc4v\xb4\x14z)\x89\x88\x9f\x11\xbb\x89\xa0\x1c\x03\xd6b_\xb6!\xa4Z\x9d\xba\x99\xee@v]\xa1\x86\xf8\xd2\xea&\xb6\xa1\x02i$\x16$\xcf\xd1\x89>M\xc6N\x88\xc2-E\\\xd0\x93\xe2\xd5R\xa1k\xd6\xf3\xa7S\x8a\x9c\xc3x~\x91\xd8w\x8a8\xef\xb6M\xcc\xc9\xa3\x0b\x95h\xf1\xfe\x1e\x16\xc6(Y\xb3\x0e\xb7:\xa1\x88\xbb\x93\x8f\x1c=\x86!b\xf0\xf6\x95HKO\xd7\xc2]9\xad\xba\xd4v\xdaN\x19{\xc3\xa8<}\xf3\xe2\xe4\xd0\x04\xb5\x03-\xfd\x08\xb9|\xd4\xd7\xd6tWG\x8d\x82\xa4\xb3\x06/`\\\xed,2V}\x81^Sn\x8cL\x19\xee\xcb\x9a\xeb\xb4\xcc\x17\xd3\xb2`\x97t,7^\xbd\xaaf\x05m\xfb\x84\xe3\xb9\xcf\x1c\xb5\x97\xe75\xd1\xdbP\xf2\x16\xc3\xec\x05m3\x8c\xe7\xbcQFFb\xa0\x81\x9c\x0b\xe8PZ\xe0]\xb1C\x03\x8b\xbfGm\x08\x17Ji^\x9c`N\xbc!\xd2\x98\xdaQ\xb5\x8ed\x16\x15\xd9\xe2\x85\x02\xd5[\x85\x19\x8a)G\xceT\xca\xcd\xe5\x88/\xf5\xf3g\x16\xb1\x88\x8b\x94L\xc3\xbe\xe5\xb4\xe2>\xbd\xb6\xb0I^\xb0\xfe\x08@\x9f\xe7\xa9\x9f\x93\xf9\xddz}9\xa0}\xd1gOQ\x00\\\x92T\x87\xf8\xc95\xdd:\xbe\xf2Es\xda\xc5GO\xe9G7\xfa\x91\xb5M\x9a\x9f\xf9\xab\x1e\xa9T\x03[\xb3\xe6\\N\x97\xf0[\x8f\xd5\xf5\xd2\x8f\x7f\xc8\xc5\xb2\x06?\xc6&@\x1cP\x10\xc6\xe0c\xe8E\xf25\x87\xdb\x05II\xc1\x87\xe2c\x08\x85\x1c\xaeI\x18\xcf\xc5\xf6\xf4\xe8\xb8\xa6%5\x80\xfds\x19n2\xb2>z\x81\xd6\x19>]C\xce\xb0\x11\xdb{C\xc7l\xb4\xc3q\xc0\x01\x9d!\xbd*\xe9\xf7\x07\x17,\xbf\xa1B\x02FytP\x06r\x13]s\xeaxU\x9c\x8c\x87G\xa84\xc5\xd3.O9\xcc~@\xc1\xf2T\x17\x1f\x07_\x8d\x86\xea\xab\xd0\x14h\xa2\xd4b\xa0\xcd_\x861!\xe4\xf7\xa5\xf6\xa4\xd3[^\xc8tUSWz=@\xd7\x8e\x95\xf5\x0b\xdd\x1d%U|\xaf$\xe5Q\xcf\xe4\xd7,\xe2i\xa9\xa0\xa9\xcc*O\xab1\x8e\x0d]]\xcf\x83\xe8\xbb*D\xc4/\xd9;\xb1\x1b\x18\xd2\xac\x9d@hW\xfa\xae\xd6)\xe3\xfd\x97\xc3JR\xe8H\x86\x00c\xd4\x03U\xddk\x9d\xc3\x7f\xc4\xfc\xad\xd1\xf7\xc7oG\xb3\xd4\x93\xb3\x97J\xc4O}S&\xfc\xd6 \xd0\x9a^Bgx\xfe=\xc6( T\x0d\x86\xe6\xaa\x84\x94\x0bTu\xf2T;\xb6\x9f:.L\xaci\x98\xad\xe8\x01\xf2\x12=\xa9-\x17\xac\xab\xdcOylVz\x1b\xfbyx\xc3\xfc+1\x96c\xf6\x8a\xcd\xf7\xc7\x94\xd0gd\xca\x9eRT\xee\xcf\xd1\x08\xee\xa5\xa94B\x1f\xca\xdd%j\xd8p\xdf\x18K\xdb\x10\x1d\xad4\xfb\xd3ft\x03\\\xd4\xa7\xd8i\x96\x01\x8e{\xe3Y\x0c\x00\xec`\xf0y \x8f=D\xc5\xecX\xfa&\x9e\xf8\x9a\xdc!\x0d\xe8\x08Y\x1d\xe6B\xf5\xd4Y\x87S\xdd\xc31l\xb08\x8e1\xb7\xde\xfb\xa9i\xbc(i\x84\xbd&\"\x80\x13\xa0\xdcU\xd8\xb0\x9aR\xf6\x1bZY\x89\xc8\x9d\x1a\xc4\x81<\xb1\xbe\xfc\x9f\x9acN\xedL\x96\\\xd5\xa7l\xc5\xfa\xf6J\x9c\xea=$L\xcdAmh&\\H \xd4\xd5\xda,\xc9t\xd5\xc4\xabw\x05}\xa1\xea\x8fl\x87\xd9\xf8a\x88\xcc:7#M\x08\xafM~r\x02h\xadf\x9e\x95\xc6\x8c\xb4r\xa7Y\x9e\xac\xa4I\xe9\x00\xda\xfa\x80P\xeaGH(\xcfZ@\xc1\xb0\xea\x0bD\xbd\xbc\xc2\xda\xa3\x13\xa6\x80\xee\xbd\xb8:\xc1\xb1\"i\x86\x99\xc4\xbb\xd7N\x98}d\x85\x19\xdaj\xb4\xd3\xd6\x8c\xfc\xadv\xbf\xd4J\xf7\x96\x9a\xd6\xa6\xa7\x07\xae\x84z\x0c\x0d\x96\xd1\x0c\xf1\x0f\xd3\x84k\xa3\xd3\xeb\x94\x15\x95\xd0\x9aebB\x146\x89//\xb5\x12\xd1j_;.dU\xe7\x98kc\xe6\xf9\xc5|I\xe2\xfce\xe4g\xbd\x1dNd\xb8\xa8\xbe'5\x1f.\x84\x8d!b\xda\x0d\x8fn\x10\x93[\xf5\x18J\x99\xec\xbf\xfc\xd0\xa9\xdda\"\x16\xf9A\x9d\x98\x06\x8c\xa6.\x8f3E&\x18\xfbR>f<\x9e\x8b\x98\xa4\x19\x908H\xa6a<\xafgD\xc8\x17$\xc6\x8d\x87\xc9\xd2\xca\xc3\x0fD\xe0\x17\x1fx\x03\x06e\xb88c\xb9\xc1@/\xd57\xffF\x18\x19\x18\xcc\x04\xf4S\x13\xb5\x88\x85\xc0\x0cCC\x8c\x9b\x1f\x84}n}\xdc<\x9b\xa6\x0f\xac\xa2\x16gp\xbd\x03\x1d\xae\xdb\x17\x0c\xdb=y\x82LO\xb9\x1e\xe4w\xcdC\xbe\x85P\xc3\xd0>\xde\xf5]N\xde\xf2l\xdd1FWA\xcf\xf3\xea1\x1cWv\xcb\xeaV\xfd!\x99\xcd2\x92\xff@\x97@R\xe4\x90\xcc\xe0:)\xe2if\x9a]\xb5MZ9l\x82\x8d\xb6\xfd\x03\xc7\xd8\x0e\xdbs\xfd\xdb\xc9\xeb\x99\xd1\x99!juO!\xd5@\nuE\x80\xae\x08n\xe0\xb1\xee1\x05\xb3\xbe'\xad\x88)oCD\xb4\x00\xcf|\xd8\xbaU4J\xe2\xda\xec\x8f\xf5\xde,\xdd\x04\xa1\xb84\x9f#@\xcb\xe8\x0e\xf7\xf7\xcc\xed\xde*\xf2\xd9a\xdb\xd4od^\x98\x9dq\xbca\xc7\x8ei\x13 \xd4bIh\x83\x1d\n\xac+%\xee\xd1\xed$\x90\xce\xd3\x01\xdc\xc3\x82M\x9c\xde\xe2\x10\xf8\xe1\x8a\xd3\x81\xc7V\xea8\xdem\x1a\xe63/HX\xa7\xdcL\x8d\xe1\x98\x11\x91\x84rZ$\xb9)\x1bUJi\x08\xfag\xf3\x04\x86t`\x18\xbax\xb4\xb7\x07O \x9f\xa4\x1a=\xd7Z#\xd4$^\x85r\xdd<;\xa1\xbc\x95\x89jy^e\x96\xf1#\x0c\xbfB\xf8\xce\x82\xc8O\xe7\x842\xa8~\x0cK\xffk\xb8,\x96\x90\xa1;\xc7\xe0+\xe5\xb3}9\xcd\xf5p\xdfAWNJ6i)\x9e\x12a\xdf\xf7\x1c\xd4\xa2u%J'\x8b\x9c;JH\xcb\xf5\xdb\xb4\x0f\x92\xd6\xdasHe\xbc0\xfb)$,\xd0H\xf31\x9d\x88\xfb{ \x06\x14/\xf7\xb4\"0\x9b\xbd\xd5\xb8\xd6W\x8c\x9e\xa5\x13r\x80\xb4\x9c\xdb\xa1\xc0\xa9\xcd\xb2'\x9a\xedU[\xbe\x1b\xc3\xa3#\xa7\x14\x0d\x1bOB\x14\x88Z~\x16\x84\xa1\xa5\x17\x8b\xb2\x12\x91\x9f\x87\xf1\xb0\xb5\xc8u\x18\xfb\xe9\x9d\xa1\x08H\x12(\xfdq\xc2*A2\xaf\xad\x95\"\x9fm\xb5\x96`\x84vg/^\xdb\xc41\x02\x1c\xaa\xe6\x82l\xd4\xde\x9f \xdb\xea(\x91\xcf\x86\xfb\x11\xe9*\xb3\xd5R\x08\xaa~\x8f\xe0\xc7v\x08.\xc8\xd7\xeeZbx\xf6\xec\x19\x18\xac\xb6\xf9t\xfa\x19\xd9\xdf\xed\xae\xea\xb7.@\n\xa32cE\xa8\xedpzO\x0cp&\xcc\xc6\x1d\x95;\xf5\xe8f.\xcf\x8f\xd6\xf8T\x95\xbe\xeb\xd1\xd7M\x1b\xc7\"\xf6\x16\xd1F\xc6\xe7riz\xfc\xb9\xe2\x10L{5\xba\x94\x98*\x83\xc6\xa1B\x01\xa4\xa4\x189\xc0\xb64\xd3h\x10\xb7\xc4\x94;L\x99\xf0\x1cOn\xe49\xe1\x99,\x91;\xc575\x11\x1d=\xdd\xb7\xca'\x87 b\xa1I\xcf\x1cV\xe1f\xecB\x98\xbd\xf7\xdf\xdb\xb1S\x16K\xf8\xe1\\\xca\xb7\xb6`\xe8\x08\x91\x80(T\xbe\xdcDZ?\xa6\x07 \xe9p\x84@\xcb\x95V8\x00\x8f\xfe$7\xdd\\\x19@\xa2\x8c`m1\xa3\xd7\xcc\xcdm\xf4k\xafk\xf9A\x8bH\x8c\xd9\xdd#\xcf>K\x93%\xe5\x15S\x07\x15\xc35\xae\xac\xc6J\xe5\x15\xfb\xb45\x841\xcc\x95\x15eX!Z\xe1\x13\xaf8\x87'H\xeb\xb8\x069\x83\xe9\xd0\xad\xc4\x17\x92\xf6\x97\xc7\xd9\xc5\x08\xa4\xa7\xadE*\xf5\x04\xe7Z\xb5\x85#?\xcb\xdf\x18>\xc0\xb1O\xf2\xcb\xb6\xd1ky\x97\x1b?* {\xc1\xae0\x08Q\xce\x843Z\xfd\xe8q\x15\xfe\x06d\x12\xb2\xf0l\x86\xd8o\x85\xb4p\xf5%2\x89\n\xd6O\xb1\x14\\\x95\x89\x14\xd8\x89\xc6\xf8\xef\xb4\x8a\xc6\x99*h\x14\xe9!~\xb8q\xa1\x15>\xe0gY\xfd\xd1\x96\xf4\xcc(/@\xb2\xb6\xa2\xd8GL\x18X\xddw\xee+\x9fEO-`\x9bEQ\xe5\x7fc\xfc\xab\xd9o\x8dG\x8a`\xd6\xd4Q\xde\x8dai\x92FX\x00{\xe2\xa5\xc4\x9f~~\x13\xe7\xc3\xfd\x17gv\x0e?\xea\xdc\x18\xf5\xfb\xdc\xa8E\x16\xce\x8e\xa6A#M\x87j\x98#\x08\xe1\x18\x8a#\x0877\xf5L\x19\xf0\xc6px\xa1\x83\xfdG\xad4OQ\x1cp<\x1c\xc2\x16\x04\xadr\x1dQS\xf9!]9\xb4\x9b\xa1\xe3\xb2\xcfa\x93\x03(+\xe7-\xa0\x001V\xc9\x91\xec\x16K\"\xc1j\x0ca\xeb\x84\xf7\xc6\xe5P0 g3lb\xd8\x84\x0c\x9eAQ\x9e$\x05lA\xe60\x7f`\x84\xda3d\xe6\xc2\xad\xad\xb6!\x97\xc4\xf3\x8c\x07\x0b\\1\x1ep\x05\xc7\x90\x1d\xc1\xaa\x0d\xe8P\x03[{>\x1cCz\x04\x9b\x9b~\x1b\xfa\xa0\xc7\x84\x9c\xf7\xa2\xb8\xce\xf2\xd4\xa6|\x82\xef\x02O\x8d\xa1_X8H\xa4\xd6\x8a\x8a\xa0\xf0\xf5e\xc9\x84\xee4f\xba\xdb\x03\xe9\x89\xcaz-\x9a\xeb\x8eE\xc3+{a\xbf\xa6\x1bJ^\x16\x0e\xaa\xe4\x9a&@\xa6\x96\xae\xfa\xb6d6\x18(\xeb\x94smM.]Y\x14V\xb2\xf2L\"\x963\x87K&8\"r\x02\x94\xb8C\xa2\xafK\xa8\x98\xaf;\xe8\xdb~\x83\xae\xc1\xa6W\xc5g\xfd*~a\xff\xb6~\xa7\xbf\xf6\xad\xbb\x97V\xa3\x92W\x96\xde\xb6|\xd6\xa4\xadF\xa4\xa0\x15\x1b\xb6\x9d\xd3\xd3i\x84i!\x1c\xbe \x19+!\xcd\x9f\xcf\xf9M\xcaO\xc3!\x8f\xdaL\xd1\xc6\xde\xbe\x0b!\x9b\xf6\xc4)\x7f\x9a4yF\x94\xfc\xf0\xad\x0b\xfe\xbc\x8d\x9f\xad\xb3\x10t\xd8q\x8d\xc5\x84SH\x91\x07yq\x97\x13\x91\xf1\x9dbU\xf5!WQ\xe5u\x9b\xae\xb6~\xbdl\xeb\x17\x05\xf3;?_x\xcb0.i\xc6\x1e\"[:\x9f\xe8\x1aq\x04 \x8an\xdb\xd0&\xa5\xbd]\xb4\xafu1F\x07\x99$-\xc9\xe5\x03\x11,\xc1X\x82\x9e\xe0\x11e\xa5w\x9e\xc2)\xec\xc2\x98\xdd\x8dv\xe0\x14v\xf8\xdd\xf0\xe9\x10Na\x04c\x93\xe8\x05iE\xd8\x84\x19\x1c\xa3\xb0O\xc8\xeffm4D\x9f\x04\xb8\x11\x1c\xc3ptX\x12rQ\x8b^ \x04\x9da.\xd2'-.m\x8er\x19\xc3\xa7#x\xc2\x88X2\xa1\x83\x1b^:L8@\xd9\x17{g\x08O r\xe0\xf8\x18\xf6\xe1\x1e\xf6w\xe0 %^\x9f\x89\x0cb\xd8\xdd\xec;t\xd7`\xf6).\xb9\x7f<3>\xde\x8d.]e(!\xf6\xbe\xfe\xcc\x97F4\xdc+G4\x1c\xc1=\xd8bL\xf2\x10}:\xc4\xd1`\xf7\x80\x7fw\xcc\x13\x96\xdd\xdf#9+%x\xfb^\xe3\xdf}\xfc\xf8\x8b\xf2ng\x0dh\xd4\x9f\x15\x06\x08\x1d*\x10\x92@\xe6\xd7AV8\"\xef\x1b\xad\x89\x82\x8c\xa5\x92\x1bI`\xd2\x0eQO\x12\x97\xc6X\x94/\xc2\xcfi\xdd;.\xee\xe4!\xc5s\x81\xdc\x9e\x1d\x94i\xe4\\H\x19>\x0f\x98\x18u\x00O\x00\xf3\xc5\xdd\xb3I\xe4\xdc\x0c\xcb%w\x0f<\x95\x1cer\xc4w\x18\x1bg\xf3\x04fM\x8co\xc2\xd2\xdd\x14\xc9M\x19\xa7\xa9M|\x8a\x8aq\x8a^\xbe\x94$\x9f&\x1d\x1d\xb71>\xe7b\x10\x9d\xde\x02$\xdd\x85\xa5\xc9V&\xaeT\xaf\x0c\x04(\xc3\xa2\xa4\xa8=\xa4\xc7\xeb\xe6I\x9f\xce\xf0\xe3&u\x99j\xeeK\x07\x11\x157\x81l7\x8eO\xf9.\xf7\xb8b\xe9\x84\x1e\x0e\xb9w\x1e%\xb7\xe5\x93\xf6y\xd8$U\x84N\x82\x12V\x0dC\xc0\xba\x95y\xa8\xba\xb37\x1b\x1e8\x90{o\xde\x9f\x7f<{yq\xf5\xee\xf9\xffw\xf5\xe2o\x17g\xe7t=\x0dL\xb2\xb8\x139\x89\x0e1\x98\x05\xe9\x9fwy\xf6\x18\x83\xdf\x0b\xdf\x1a\xc5di\xd8a\xa2R\xb3J2\x9fie)\xbd\x00\xb0\xe5\x18N\x92\x1e\x01\x13\xc4\xc5{\xb5\xdb\x94\x1f\x89K\x8f;\x1e\\\xd8\x1dqZi\x96$\xb6c\x14\x87\x12\xca\x901K\xd3'O\x84'x\xf9\xcc\x1eb\xc2\xbcJ\xa9\xd8\\\xaa\x9d\xd9\x0d\xf8\x1864\xb2\x93\xfa\xbab\xf1u\xbe\xbc\xf3\xbf\x96\x91\xa3|\x1b\x05\xcb\xab$\x89\xce\xc3\xdf\xe8t\x1e\x0e\x9fb\xf2\xa1+\xeea\xd3\xb9\xe2\xb5\x13[sJT=\xbf\xb8`\xbb\x87\x1f\x8cT\x7fd\xf3\xf0EZ\x0b\xcc\x16!\xb5\xec Y\xeb\xa3v]\xd1\x91k\xcb\xb8\x06\xfb\xc9st\xf5\xa7\x0d\xb1_\x18\x1cJ+!\x13\xdetY\xa9Xa_hmM\x98\xe1K\xdd\xd5\xad\xcd\xccAV\xec16\x08\x02ZGc\xdf\xd43\xd0\xc9\xb5\xd5\\j\xb5\xd0B\x0c\x933\x0c\xd2\"\xd5\xa5\xbc\x07\x99\xc4\x97FvK\xc8\xa5j\xc7\x83\xad\xcb\xb3\x0f\xdcV\xdc\x84\xee\xcc\xbd0\x13\xe7>7F1\xb3\x812\n\xf7\xff\xa0\xf9\xa3\x97\xcf\x8c\xb9Q\x13\xce\x19_\xe1 \xdf\xb1\x16\xa1Z\xb7is\x91J\xce\x1e'\xb0p\xa1F\xe9I\xc7\xe7\xc6\xa0\xfe.\xbb\xf5W\xc3\xfd\xb6x\x9d\xa0\x06\x0fh\xd3\x13\x11\xad\x9eH6\xd7\xe4=\xc9(\x89]\x99\x0e/\x8b(\x0fW\x11\xa1\x10\x1c\xeeo]\x87\xb9\xf6X\xac)\x1a\x06Gh\xbeK\x8e\xd8\xf2\x1b9p#\xe2\x9f\xba\x98\xb4R\xc7\x7f e\x82\x1cB\x04\x04\x10\xeb`\xd9\x19}W\xb0\xec~#XvF\x8f\x02\xcbn\x03,;\x8e[=\xa2`b\x7ftZ\xb85\xa0\xb5\xbf\xfb]\xa1u\xf8\x8d\xd0\xda\xdf}\x14\xb4\x0e\x1b\xd0:\xd0Ck_y\x9d\xe8\xda\xf9\x83F0\xcc\xe6LX}a\xfc\x16x&\x8f\xa7\xf2(\xb1\xfa\xd5\x8b~S\xb1Z\x890\x90\x90\x1f\xa2\x19\x1e.\xba>M\xa0\xd9(\x96>>\xa1\xbd\xe5w\x9d\x1f\xe3\xeac \xa4\x89\xe4\xcc%\x19(\x1b\xa5\x1b\xd0\x83\xee\x14\x17\xef\xc5\xc7j1\x9b\x9c\xac\xa0\x0f\xb5\n\xbd(Vq\xf1\xc6_\xae\xd3x\x1b\x9d+.^\xef\xf3u\xeam\xa5\x8e\xa1\x1f\x85,.\xde\xfe\x87u\xda\xef\xb4\x1d\x86\xaa\xe2\xf3u*n\xa1\xc6\xa1\x17E\x0e=\xa9rX\x872\x87j4\x17\xfdF\xd3I\xac\x03\x94v\xd1Z\xc6\xfa3\x8b\x0eUz+\x8e\xb51\x14\xd4\x8b0w\xc4M\xb0\xac\xbef\xd3\xa0\xa5\xc9\x1eD\x0c\x12\x1c\xac)\x0cI\x1d\xa9\x93_\x0b?j\x8f\x1f\x01ZiC\x87lA:\x0c\x85\x8df\xeb\xc1\xc3\xcf\x80\xfb{\x8e,KY\x88\xde/\\\x19E\x18g+L+\xd6\xefd2)F\x98\xffRC\xca\xdf\xdaqq>=\xe3f\xd3%]Q\xba\xf3 \x8e\xe4\xfe\x92\xde\xd2\xcf\x83\x85\xbd\xed\xfd>z\xd8\x9e;\xde\xdf\x930\xb6-\xb0Dx\xb0\xb22\x9e\xec\x89\xa5P\xf7<\x0f,\xc7q\xc1:\xe6\xf4\x06\xae+]6\xf4:\\\x0c\xf2\xa4N\xa3\xf6\xef?\xd5*\x8fW;YU\xcfmf{\x8e\xda\x11\x0e\x90\xb1Z.-\xed\xb6\x94\x17\xcc\xd6,i\x9c\xa8\xb9\xf0u\xa7'pY\xef\xfd=\np\x06,\xd5\x9cr4\xeb)>\xee\x8f\x9e\xd2G\x80\xf6\xd1\xa6\xf1\xa6\xf0\x8c\xf7'\xa7\xbfZ\xdd\x84\xaa\xf2\x9d.\x04Je\xe6RH\x07\xb8\x10\x97\xbf\xd2\xf2WR\xfe\xaa6_/\xf1^\x88\xae\x03[t\xf5`\x0e,\xd8\xa2\xcb\xa9\x90%z\xa1\x0b\xbe\xc3\xcc7\x10\x9c\xa5^0\xe1*\xd8\x9ae\n\xd3\xec\x0e\x8e`\xc6\x0ci77gf `4\x991 `0\x99\xb5J\x00i7ia\xd6KZ\xda\x8c\x83\x1f!\x01\x0c\xe1\x18\x8d\x90Q\x02\xe8\xc31\x84f \xa0\x8c\xa5\x82\xa8\x98\x92>\xb1\xc6\xa4\xb6\xb8q.\x82\x92\x9b\xe3\xdbf z\xd3\xba\x7f\xad\xc6\x96\xf5\x90\x1a\x98:\xaf\xad\x11\xc9\xe4\xff[\x1b\x1a\xb66\x84\x1e\xfaz\x0cf=\xbdp\xdf\xd4E\x10\x86\x1cm}\xa5\x10?X\xac\x0f\xda0@\\X\"\xe2\x87\x984\xd99\xba\xa8\xf1\xe5\x1f\x1a\x03\x03\xa9\x91\xfe\xd4\xd8t\xa6\xeacz&IB\x07s\x1c\xcc)\xf9\n\xb2x\xa1'D\xff\xde\xc1\x0c\xe5\xa5O\x7f\xce\xed\xa9\xf7p\xc2\xf5z\xc9\xda\xeeU\xadud\xaf\x17\x17Fu\xc3\x1d\xee\x8e\x96\\\x02\xea!\x9e`P\x9e\xe3c8\x84\x1f)\xfd{\n \x8ca\x08[\x908\x0e\xdahk^\xf4\x1a\xf0\xfb\xb5\x06\xbc;z\xba\xfbt\xff`\xf4\xf4;\x8dz\xd7<\xea\xbc9\xac\x1d\x1c\x16\x03F\xaf\xc1}\xea\xbd?\xbeea\x99\x96j\x0b>y\xf4\xfa|U\x1bQ[J\xc6\x90\xeeB\x04\xc0\xc0e\xa0v!\xe1<\xae\\\xc7h\x87\xbd\xa3\x10\xd8\xed\xd5\x87\xb7\x8f\xee\xc3\xa1\xa1\x0f{#\xf6\x8e\xf6\xe1P\xe9\x83|\x97\xa9t]\x1f\xfb\x1d\xe1\x15\xd7OI}\x02\xff\xfd\xdf\xc4U\x83`\xe6p\x8a\xa9Z\xfe\xfb\xbfs\x97\x9d\x14,\x0c\xe5&=\xb5\xcb\x1dBD\xc4\x11B\x0f\xf6\xf2Q\xeaT!\xc9\xec\\\xf9&\x17\xdf\xe4\xe57\xb9\xf4\x0d)\x9f\x10\xc7`\x03\xecT:\xcf\xd2\xea\x1aaa\x0c\x90\xb9\x96\xfc\xa4\xa4\xc0`K\x8d\xcb/\xae\xb8\x0c\xf3\x9b\x08q\x86\x81\xbb\xa81\xe7\x9cNH8\x19\x13S\"\x80\x0d\x04)\x00\xd2\x95\n\x07\xaa\x85V\xf7\x80P\xd8\x0f\x11\xd5\xe0\xedYO\xb9\x1a\xe1\x92\x19!\xb8A\xaaM\x90\x13\xb2|\xa3\x05\xf7\x89\xe56!\xdcgoX\x12G\x9b\x9bt\xd89\x17\xae\xffxB\xe9\x1e\xe7\x88\x13\xb5\xec\x1b\xd8\x84\xf0\x12~\xd4\xb9v\xebIY\xfd\x88_\xfccF\x0c\x9b\xb0\xb5\x95\x8bq\x1f\xe1\xd2\x1et\x0c\x97~\xf0\xed\x03>\xec\x83\x10\x84\xc6\xa9\x1c\xe3\xd0U\x15\x1cl\xe2\xfa\xb48\xdco.\xab^\x8d\x8e\x0c\x8drK\x0f\x04\xca\xf0\x12\xcf\xfc~\xfdhN\xf6\xb7\xf5\x03\xa9\x8dZg\xfa\xf4cg\xf4Hx\xec\xaa\xfd\xb0\xcd\x00\x91\x1f\x8d\xf0\x11\x8b\xf37\xdc?88\x18\x0d)\x17Q\xbe\xdf\xe9\xd9\xedG\x82\xaf\xd1\xedF\x1f(gc+#\x18\xee7\x87P\x1b\xd5\xcee\xab\x08\x9fv\xfb\xff:\x8c\x06\xcfN\xf8\xe7\xc3\xd1\xa1\xc3E\xe1[\x9cv\\%\xb76\xa5\x12(X\x1d\xc7\xedF\x07\xff\x10\xf4W\x03\x8c\x84\xdb\xd2\xcb#$/\x9bX0T\xb0`\xda\x0e\xa4P\x03\xa4\xd0\x08\xa4\xb0\x07\x90\xbe\x13\xcaD\xdf\xebr\xc5\xa3:\xefG\xc0\x88\x10[\xd2>@\xaf\xd3\x9e\xd8u\x0d\xe4j\xc4fM8\xde\x88\xd8\xaaF\xe4b\x84\xfd\xce\xe8`\x9f\x0e2\x86S\xc6\x08\x0d\x86\x07\xfb\x03\xb8\x87\x18\xc6\xdd\x14\xc8\x1a8\xfa\xd1\xc3a\x83\xb8\xaf\xa1\xf0?n8\xdf\x0f\xd5\xaf\x87\xe9\xebx\x92>\x1b\xed\xf6\xean?\xe8\xf7\xef.\xb6\xdc\xect\x0f\xe4\xde\xd5\xdd\xd7Q\xe2k\xb0\xfb\xe3\xba\x9b`\x95\x95\xa2ac \xb8\xbe^\xdd\xf8^Pktc\xd8\xb7\x1b\xaf\x92\xe2:\"\x8f\x04\xc7ag?\x06\x82\x01\xed\xd7\x8fG\xc2\xa3\xbb\x1f\xc3>\xfd@\xe6\xd9\xc8\xcd\x18\x848\xc8\x86n\x92\xda\x01\xc7\xacXPm\xfbF5 P\x0f\x93\xd8\x81-\x8a\xf2M\x8e(\x899\xc6_\xd8\xe2\xf4\x81\x1b\"\xafBN\x13AI\xc4\x8dc\x92\x15eD\xc4 \x10\xd8\x86\x84\xc9\x81\x8c\xe8\x8d\x16n\xc5b%$\xb5d\xc2?\x10\x921\x161BSc\xa4$AS\x88\xcfJ\x88nm%\x18 \x8e\x93\n\x1a\x90&\x02\xa4\xe1w\x03i\x83\xa8h\xb7`\xd1\x00U\x85%E\x16{{.\xeaQ\x8c\xf9~pv\x10\xe4\xb3(IP\xd2\xcd\xb1\xb5\xbc\xca\xb8\xc9\x7f\xaf\x81\xe8(\x90o\x1e\xcb\xc8e\x92\xe3\xb6\xd1\x9cj\xb6\x87[\xcd\xd9\x90\xcd\x19\x8aH)M\xf5\xf7Z\x03,G*=|z\x0e\xb27\xa5\xfc\x07\x0e\x92\x8fF\x1d$\x1f\xbbf\x90\xc3\xb5\x06\xa9\xa3V\xbey\x90\xbb\xae$\x12\xef5RF\xb3\x88\xd1\x8ev\xa5\xe1\x8e\xaa\xe7\xc3}\xc3\\k\x963\x85\xcc{\xfd\xf4\xb7\x92E\x12d\xfe\x80\xe9_\x1f2\x06\xa8\x0c\x0dP\x19\xe9\xd7\xccN;d\x86\xbd!\xb3\xe6\x11+\xa4\xc72X6\x8c\x06G\x02\xd57\x8e\x07\x0c\x1d\xad\x97\x9d6\xce\x96\x84\x1d%[\x1a7o\xbd=\x18\x9e\xc5\xfa\x83\xa5#J\xef#Op_:n\x88\x10y3\x89z\xc1~\nsLv\xb6\xd3\x01]\xe2\x97\x05\x86(r\x95s\xdf\xa6\xa7\x94\x0f\xcf\x9e\xc1\x80\x9e\xa3\xc5w9\xaf\xd6\xa4\x00\xfeO\x99\xe8\x16*\xe2\x9b&[\xcc\x85D`\x84\x15\x81\xb1\xf6\x8co\xfecf\xfc\x0f!P\x86\xa3\x03\x17\xb6\x86\xa3\xc3\xb5i\x14R\xd3!Q\xd02\x9f\x84\xe1\xb7\xd0/\x7f \xf9\xb23:\xd8\xa7cE\x19B?\xd4\xfe\x07\xd20\x7f \xf3\x88\x81\xfe\x81t\xcc\x1fH\xc6T\xf9\x10\\%\xedA\x8f!\xb7\xcfm\x0f\x12\xa7F\x12}\x13A\xf3\x07\xd23f\x10\xd5\xb7o\xcdHB\xec\xe2\x1eP\xfc'\"~\x0c\xf2\xa7v(\xbeR\xe6\xac\xcb\xab\xa2ji\xdd\xf9RZ\x1a\xf6j\xc9$Ejo\xea\xedc\x06e\x12\x14\xad\xd5T\xe7\xa8\x82du\xb7\x1e\xddR\xa5\x9b\x1c\xa0Cd\xe9\"X\xd9\xd5\xe7\x8a\xa7\x97\x94\xa5\xa42E\x90\x0b\xd0\x0f\xf3\xb2F\xae\xe2HK\x12\x10\x9d\x17\x98\xf7eWz\xa7\xb0\x11 \xa5\xea\xa0\xdc\xad\x8e*\xf26\xc3\x9b\xdcO\xe7$?\xcf\xfd4\xef\xce\x86Z\x9a\xf1\x003\xd6T\xba\xa1o!K\x8a4 k\xb4\x90\xb6\xf5\x97\xd5v\x16O\xbb\xebJ\xeb\xce\x17%\xf4\xeb3*\xd9_\xe5\x18{iK\x9a\xa8\xda\xcbM\xadU.\x12\xb4L\xbf\x95\xea\xe3\xd6\xe3\x1cTn\xa8\x18t\x99+\x07\xb1\xc5\x96\x904 \xb0t \xc3#HxV\x83\xad-4\x0bK`\x13\x10I\"\xae\xa3w\xba\xb8/\xa5\x93\x11eA\x86d\x07X\x18\xaf\xf5\xb2\xfe\xb105\x8aY\xda\x1a\xedk\xf3\xb9d$\xaf\xf2\xb8\xd4Lubf\xf6\x14:\xfa\\\x98B\xef\xd7\x86\x08fa\x14\xad\x87\x084NWkg\xb6\x16\xe9 0\xa4\x06?6\x95\x1d\xa2M\x9f+\xe1\x85\xe6'.\xcf\xba\xd1\x95\x19 $\xde\xaa\x16\xb0\xdcdy\x04\x18\x80\xe8\x18m\x8c\xc5Am\x88\x8ff\xce\xb7\xaa&\x9b\xd1\xe4\xc33\xf9\xb3\x97\x19\xbf\xfb&\xf36\x80\x1d\xdb\xad\xe7\x02NM^\xc5&\xcf\x8fF{\x95\x12`:-\xc9\x9b)\xcb-\xe2T\xe9\x17a9\x00n\xab\x87>\xca\xb5A\x08\xbc\xe8OB\xf8_P\xaca\xb3\x977b\xe4\xd4\xfb@\x07\xfb\x19N`{\xf2\x9f\x9b\xbfl\x0f\xb6\x9e>\xdf\xfa\x0f\x7f\xeb\xb7\xad\xab\xcb\xed\xb9\xc9\xf5\xe6\xd7\xf6\x10\xae\x80\xca\xd9S\xb0\x06\xe8\xf4_O\x13:V\x1e\xd4\xfbfh\xf0\xb5Q\x01x\xa3\x0f\xd0\x96\x03\x8f\x8a3\x84\xed\xce\x1c\x97\x95\x83L\"\xc2\xf3\xeb\xf2:\xb4\xa7P Y`\x9bFb\x07\x07\x9ea4\xef=qD\xef\x1d\xec\xec\xee\xb6!\xdc\x90\xe7\x873\x97\x80r\x93>\x83\xbd\xfd\x9d\xe1\xd3\xae\xc2\xf4b\x89(vh\x7f\xb6\x86\xb43<\x99\xc4h\xe7\xa9\x0b\xc3\xa7C\x17\x86\x87O[\xd0\xba\xb8\x82$\xce\xc3\xb8\xd0\xe7R\x12\x979{\x10\xf0\xbe\xfb R?\x19\xa5z\xf2\xf5O\xd4{\\$\xed-u\xb6\xd2\x9e] \x97\xc9\xfe\xce\xc8\x98BP\\\xfd\xa0\xe2\xfe\xc1]\x8e\xb9\x8f\xc6>lR\xban\x8b\xa7 8>\x86!3t\xd9\xe2\xa3\xd1\xd6\xc0O\xc5\x84\xf3==\xc6c>\xc9\xab\xfd\x1b\xb3D\x15]\xfb\x8c58d\xd9Y\xba\xd2\x1f\xf0\xce\xc4\xad\xe3\x10\xf37\x1a\xec\xf6l}\xb4^\xeb\xf0\xec\x19\xe62\xc0\x00\xdb\x98\xd0 \xa6w\xa3\xc3^\xdd\xc2y\xea\xd7\xaf\x9d\xf5\xfb\x85I\x17F\xa3]\x16\xc2\x03\xf6\xe1 \xed!\xf6n\x8d\xbev\xa0F\x1c\x07O\xd9\xa0\x8b3 \xd2i\x05\xc9\x94\xc0*1x\x91\xc9U\xb2\xf1\xee>b\xbc\x87t\xbc\xbb\xe4\xeb*I\xf3\x0cN\xe0\xf7\x07\x89v,\xc1\x106<\xd2\x1b\x9b7#\xf9E\xb8$I\x91\xc3\xc2g~\xa0\xd7\x84\xc4 B\xe6W\xf0~\xd04\xe0w7\x10D\xc4O\xbf\xa1\x89\xa2\xb9\xe0\x19n\xc5\x18`e\xef\xab\xe8\xc2\xe5#\n>\x95o\x16T\xe3\xc9 \xf3\xe2\xda`\xf9\x8e5\xf5\xd0C\xb6z\xecv\xd4\xab\xcf\xb7!\xaab_\xd4\x97\x81\xc8\x0f\xa17\x955\xa6\xef\x10U\xb2\xa5SF\xcb\xd79\xfc\xb7\xb6\xd0\xac\xab\x94\xd2v\x07\x0f\xa8&l\xa3Z\xac\x8d\x95\xa0\x1d\x03f\x9d\x11\xdf\xc8\xbc\xa6\xb4\x10O\xe5\x9b\xb1\x8av[\x13k\xd0\xeaU4-\xdf\x19\xe6\xc9\xd4\xa9\xda\xe2=\xad\xdf\x8e\xd5,\x89\xad\x1d\xa3M\xa8Y\x15\xcb_\xb6\xb4\x9a\xe8\x1e\xe7\xa9\xcd&Jb\xb3\x00C\xbf\xd4\x9f\xcdx\x12\xda\xe6\xc6Y5f\x04\xb3\xb7b\x1a\x0b\x9bW\x05\xa5X\xe0\x14[\x14\x01\xc4\xed\x08\xc3\xa7b\xdd.D\x92\xecuj;\xed\xfbu\xdah\x16\x89\x88\xc0\xc4L\xd2\xb3\xad\xb0W\x1a\x8a\x01\xfb\xd8\xc6KR\xa6S\xf4\xed\x083\x11\xe9\xd79~@\xb1d$\xe0\x8aA\xc4x\xf6\"\x9e\xf2cv\xe9\xa5El\x9b<\xfc8(\xe4&;v \xf0D\xcfl\x8f\xea\xe6N\\\xfd\x8ev&T\xa7\x98K^\x86U\x1a_\xe9\xa1\xdd\x16P\x12Q \xab\xc8G\x14\xc8b5h+\xa5\xabV~\xe1\xf6o\xc6\x8c\xc2\xc4\x95\xda\x06\xf9\x12\xf4\xc2^\xe2\xean\x08d\xf2K\xc6\x9b\xe6\xe6a\xad.@\xa3\x01\x8eL;\x1a0\x8f^\xfb\xe6A\x05\xd8C\xebN\\h\x858(\x0b\x9c\x15(9\xe1B{\x96\xe6\xe8D\xcaZ\xaa\xab\xee\x86n\xec\xaa\xc5\xc4\x8b\xc9\xd7\xfc\"\x0c\xbe\xb4\x12\xa7b\x9fR\x8a\x80\xd1\xbc\x8d\xb8\xcdM\x93!\x94W\xa8\xc5\x9e\xc1\xb0 \xce\x12\x17\xc4\xcc'\x93\xb2*\xea\x97G\x10onRr-f\x86XR\xe8\xe8F\x98\xfd\x883\x1b\xe4V\x80\x0fe\xf7\x98\x15Z\xa2\x07\x03\xfa_aO%T\xe8\xc2B\xb6\xabG\x00\x9b\xcfF> <\x1c+[\x8e\xd5\\\xd4\xaaM\xbc<\xcc#\x0cJz\x9d&\xb7\x19I-\xfa\x90\xff\xe6a\xf2\x13\x8f\xc47H\x07\xd2\xdf~:\xbf\x11y5\xbd\x1b\x92ft\xfeX$\x93\xf2>+K\xe3\xbb\x1b\xfcn:}\x1bf9\x89\xb1\xde\x1b\xf6\x12\xdd\xd1\xd9\xef\xd9L\xfcL\xc92\xb9!ja\xf6\xf4y\x14\x89\x17\x99xC\x96a.~\xafR\xb2\"q\xa3%\xfe\xf8C\x1c4\xea\x8d\xa4\xea\xccK\x8d\xef\xc0\xc9e\x1dz\xd7a\xdc\x99\\\xa5A\xb5\xae\xd2$ YV~\xccC\xa4HA\xf1\xea\x8d\x04\xb7\xd3\xb6\xf9\x16\xac\xd2\xb6\xa5|\xb6\x98\x86\xe9\xe3z\xc6>\xed\xeaW\xb1\xf4\xb3/=z6\x90\xb6>h\xb8\x10E\xc5o\x15\x19AEO\x90KL\x9c\xcc\x90\x98G\x84\x1a\xa0\x8a\xd8\xda\x90Uu:}\x0f\x06\xb1\x15\x03\xf5\xcb\x8aU\x19C\x83k|\xc4@\x9aH/\xd5\xe2\xd0\xca\xbe\xe6\xa4\x0bk&f\x94\xd8\xc0p\xc7'0\xa4\x88E\xd2\xdeT\x98jx\xc9\x835\xc8\x8f\x9a\xf4DlLx+duZ\xb0\x19\xd7\x07\xa8\xc2{\xb5\xd7Lt\xcfP{\xea\xa8\x02|\x9fb\xdep\xe2\xd7\xb1\xaeof\x961\x17\xd6\x86\x88\xa2\x19\x0b\xd0 \xc3&\x91\xa1\xa1GnHzW\xcb\"\xdd\x95\xda\x0c\x19\xb7x\x92^j\xf8\x1bts\xb1\x19W\xcdp2\x9b\x04\x17B\xc7a:\xb5\xd05s\xf2Z\xde\xbb1\xf15\xc2\xb5 \xc7\xb8\x84cN\x0f;8\xc5\xe0\x14C\x1e\xd98e\x07\x1c\xcb\xb9 )\x85k3\xa9\x9d\xe4-\xa0\x16\x97\x00]\xfb\xa6\xef\x03}6\xc4Y\x9a,[Yv;4\xcc\xc3\x83\xf1\xb8\x8f\xbc\x94dE\x94\xbf.\xe2\x80\xae%\x17\x9f\x04\xc9rU\xe4~\xce\xd9\x94\xce\xcd&6Z\xe3\xe5\x03\xab/#\xf9\xa7GWJgH[q\xed\xa1L\x0c\x88_\xb9wuE\xb2w\xc9\xb4@\xf6\x8d\xf2i\x98:\xd6/\xa2\xfc\x1dY&,soB\x9f\"\xda$\x02\x8b\xbedH\x94\x11\x1d\xe5\xcb<-\x82\xbcH\xc9\xb4D\xb6}\x18\xefGP\x99\xbeBe6\x99s+\xc1<\xb8F\xea]\xc8\xfeM\x1dg\x87C\x06\xb30\xcd\xf2*^\";\x18\xfc\x18X\xf5p\xbb )\x01\xe2\x07\x0bX\xf1\\\xbb\x94\x11\xf0A\x9c%\x9a\xa3\xc3Gk\xb0\xb2SG\x0d\xa0\xd0\xbd\xc6\xd3\xf8~!wYC\x88UR\x8bq\x1dU\xb5\xf9\xc3\xd3\x0dY_\x0e\x8e\xdb\x93\xe4\"Z\x84\x9cW\x08\x81\xd3~\x03F\xfb\x11N\xfb\xe5\x93\xb4\x9d\xee\x03i(^J\xa6E@l\x85\x13\xea\"\x98\xc9\x84R\xcb\x97\xcc\x18R\xa3\x8es\xe1\xf7\x07E %\xb1\x9fu\x91\xb6\x8f\x04L}\x99\xd3\xf5m'z\xb5\x97\xc2\xa7 \xee#\xb6\x87\xc3\x03\xe5@D\xc6\xc6\x1e\xed\xee8zV4\xb6\x87\x83\x01\xa5\xfc\xda\x1a\x00Y\x84'\xd2'$6Z\xabK\x83\xea\x91TLZ\x12\xcc\x18tM\x96\xb4\x1a\xea\xc1\xaeaD\xed\xcc\xf5\x86\x1c\x0b\xd5\xc4G\x8b=\xb6\xf1H>Z\xedq\xac*$\xeb\xfb\x8e\xc9\x9c\xc6`\x8d\xbc=o\xcf\xd2\xad\x12\x8d\xfd\xe1\xd5\x153\xd4\xa4\x7fO\x84\xdb@o\xf0\x8d\x0e\x0e\xd6\x86\x9f\xcc\x85\xca)\xe7j\xb2\xeau\xa7Q\xbf`\xf7\x0ev\x95\xe7!\x7f\xbe\xa7<\xa7{\xc7\x9ap\x9c\xf8\xbe\x88\xa2K%Tx!\x17\xf8,\xd2\x9d\xab\xa524n?E\x13\x04f\x0fx\xe1\xcf\xcb\xcc\xde\xdf\x01R\xd2\x89Bo\x0b\xcc|2\xe6\n\x16\x08c\x8ev\x99q'\nF\xc6\xc8&?\x16\xb0{OGz\xc8>\xdd\xeb\x9cx\x0d\xbd,\x96q\xc2\xdej\xb7E\xca\xb2\\\xc4%\xd8\x1e\xdb\xf7\xd1Su\x96Y\xdf\xf7w\xd41\xb1Uqp\xd89$\xc3\x0c\x85\x0c\xde)\x83w\xb26\xbc\xf5\xb2> !\xef\x0e4#\x91NXJl\xb4\x93\xd4\x82V\x99h\xce0\x89s c\xa42\x84U\x98\xf9\xbc\xab\xbdx0\xc0\xad>\x96\x90\x1f\x14\xfbR\xb5\xa1\x17\xc6\x0b\x92\x86\xfc\x149\x1c:\xcd3-\xb6w\x06\xeaL\x16\xac\xae\xda*\xac\xea\xb2g.\xf8\xd2\x9br\x80\x19\xae\xbd\xa2\xd2\"\xf0\x14I\x83#\x88\xe0\x18*uFD \x80\xe6\xda\xa5\x04t6\x89\x14\x18\xce\xaa\xfa&\xc1%\x8a\xb9\x94G\x94)\x93\x1f\xb4\xebwg\x86C\x879\xc7\x88@\xda\xc9\x0cfU~IJ\x12\xce\x1a\x84\x96_W\x95\xb9P\xa8\x0f\x10\xfbo\x08\xd7\x89\x94\xf8S\xff:\xe2\xb1c\x17aV=9a^\x80\xf5\xf2\xb7i\x98\xd7\xcb\x97Oxy\xa6q\x89\xa2\xe4\xf6\xaf~4\xfb\xb0\"1'\xd3\xeb\x15\xd5K\x94\xb55>,\xabL\xe2\x80\xd8\x16\x89\xa7\x96\x0b\xabvp6\xb5\xf4\x9a\xba\x85\xc3\xc1\x95\x18\xc0y\xee\xe7\xc4#\xf1\x94L\xe9\xcb\xb4\xd4\xc5\xd9S\xd6\x85.\x1d}c\x0e\xb16[E\x0d\xf4\xe2;\x99\x1d*\x1f9\x19.\xaf!\x17,\xd1\xaf\xbf\x86\xf3\xc5\xcf~N\xd2w~\xfa\xc5r\xd56\xe2bIRZn\xdc\xd0\x85\xcfI>n\xa7\x98\xc5\xe6\xd6\x00b!7[\xdf\xfc\xd5\x80\x1c\xb7\xd7P\xa6$\xcb\xd3\xe4\x8eL\x1b\xdd\xef\xddE\xc9\x9f\x86\xf5V\xacS\xec-]@\x8d\x12\xb5\xf1TK\xac\xfe\xa5W\xf6\x0d\xbd\xce4\x80(\x0b(d\xb9B\x08\xd4\x06\xa2\xc7\xc8\x7f\xfc\x10*\xfd\xb3i\x10\xb4\x88Q\xe1M\x19,I\xe1z\xc5\xbf\xea:\xe4\xb1Av\x80\x14Q$6,\xae}W\xdeGyM{\xff]\x0e\xca\x9d\xe1\xc8\xb1\x1f{\x8a\x93\xca=\xabT\x91t\xd1\xe8k\xf6o\xff@w\x90\xb3\x10\xf7\xfe\xd7G\xf6;\xb1\x07.\xd2\x1e\xdf\x00\xccu\xcbk\xa9\x94\xa1flvl\x1f:]\xf2\xbe\x90;~z\xe2l\xfb\x98$\xc2\x16\xc0\xc4@\x0b\x82\xa6\xf9\x1d*8\xf4\xb2;\x19\xc1 \xc3Pz\n6\x05\xd6F\x0bez\xd0\xd2\xef\x1b\x86\"\x1a\x9a\xb2}\xd4D>\xca\xf1h\xa7\xe7\x8cm\x8d\xf6,t\xb7\xc5\xedVP.\xde\x16\x9bH\x03\x1f8\xe6\x1b.I\xa2\xf3\xf07R\xe2\xad:L\xe8vl\xa4o\xad\xdd\xfa((\xab=*\x1a\\&\x16\x9cNi\x9d\x94\xb9I\xc6\xed\xa8@\\%\xfb\xda:-q\xad\xcf\xdc\xba\"\xf6\xe6$\xa7\xf7\x88\xac\xd0\x01\xca\xa7O\xcb\xf1\xa2czu{\x02\xc3\x81C\x0b\xa4$\"~F\x98\x84\xaf)\xa1}\xd0\xa8oc\"\xd2\xa9b\x83\xe9X\x05\x08\xbd\xf2\xdbD-\xd5\x0b\x06\x8fY\xe4 \xeb\xa6\xd6Y\xe8\xa0[\xec1\x8b\x10\xe0\xe8\xc0\x01\xda5\x0f\xbauO\xab\xe8\x03\xce|\x91\x92\x06@\xbbD;\xe2\xfa\x16h\xa5\xdf\x05Zi\x19G\xa9\x114Z\\\xfd\x01\xd6\x88\xc8\x00z\x98\xcd\x92\"\xed\x02Y\x8bT\xf1[\xa0\x96|\x17\xa8%R\xf4\xa9\xd4Q\xf5\xf9\xe2Z\x0bp\xae\xd6\xf1\xb8\x8e\xca\xf4Gg\x81O\xdb\xe4ju\x03\x7fmq\xb3\x98tO\x95.%\xfcy\xb7l\xc4p\x94\xa7v\xb2\xfe9.\xf7\xe8\xd1-s\xb9\xd1#\xc8\x08\x89\xfa\xda\xd1\xcb\x8a\x0e\xb5\xe2\x96\xe1P}\xce\x98\xfd\xe1\xfe\x81c[Y\x1aX\x1a\x9e\xff5\xefH)_k\xca\xdfX\xfe\xc1\xc2\xf1\xb2U\x14\xe6\xb6%J\xcaR\xd8\xd8\xde\x1f8\"a\xf99F\xca\xe8\x03$\xce=\x93\x9a\x05\x98m\x94~\xe1\xda-tr\x84\xc8d\x0d\xafx4FH\xe4\x87\x14s[\xb1\xbf$\x16\x1a\xd1$\xd5=7\x9fDIxi\xd2cK\x9f\xf9\xd5\x17>/\x87\xf2\xd6M\xf6{\x0c\x19\xb3H\xe0\xde\xcb\xb9\xe3\xb0\xa8b,\xb6\xcbi)c\x871\x14\xe2\xb6\xf64\xa9\xd6\xc4\x18\xec)\x89HN\xf0\xbd+\xbd\x92\xd7\x94c\x97\x93(3\x85\xe54\xb5hu\xf84h!\x87\x04\x14\xa7}&>Ja$a\x87\xdc\xfeZH\xa1sM\x94z:9\xf4\xc1\xa9\xc4A\xc0\xb8\xcb^\xa5\xd76\xeb\xa4\xbe\xf5\x9bo\xb4o\x10\x81\xef\xeckw\xdf\xde\xaeJ\xc53Q\xdb\x81Z<\xe3\xc5UYj\xc4\x9f\xab\x12\xbb\x80?W\xeb\x99\xf1\xe7*2X\xa1\xd0\x8ci\xb3\xce\"B\x0f\xc4z\x81\xa9T\xe0\xb5O\xc9\xe4\xbbz\x81\x05+\x10%\xb1\xbe\x82\x1b8\x81\xb4\xfeh\xd9I\xb47t7\xd0<\xc8\xe7Z\xb2\xf9\xe5\"\x8c\xa6)\x89\xc7\x86sx\xe9\xaf\xc6\x10zK\x7f\xd5$\x0b\x80 1\xcf\xfc`A\xcb\xf0\x9f\xfarAR\xc49-\x85?\xf4e\xf2\x045\x9f\xb4\x14\xff\xa9/\x97\xc4\xd1\xdd\x18f\x8dw\x1a\xca\xe5e\xb2\\%1\xa1M'^y\xd3,\xf7\xb1HI\xadl\xedA\xb3|m\x05\x8cA\x03\x1cy\x86\xc7\xa0\x81J\x98\xfd\xe4G\xe1\xb4,Rx\xf5'\x9aN\xa6\xc9\xea\x82\x99De\xa6.\xbd\x8c\xfc,\x1bC`z\xcf\xd7\xe4\x18\xa6\xa6\x12\xef\xc2\xafa<\x86e\xf3\xfd\xab\x0f\xef\xc6\xe07\x9f\x97J>\x8d\xf1\xe9\xd5U\xb6J\x89?\x1d\xc3M}q\xea)\x829>\xfdc\x90Nc\x93\x87L\x12\xf0\x94\xb2\x1e\xf6h\x7f\xbf\x12\x14V\xe2\xa5\x85\x9f}\xb8\x8d\x85\xc8P\x8b\x9cF\xfb\xaa\x9eO\xcf\xa1~!wc\xd8\xd0XA\xa6d\xa6\x7fqu\x95\x91\xc8\xfc\x0e)\x84\xb1\x9a\xbeX\xeb\x10\x9a\x19O\nI\x9cG\xbc\x94T\xbbJ'?\x8e\xfaU\xf3\x85\xdcI\xd5\x88_BU\xa1\xe1\x1cX2C\x03Y\xd2\xd4*\xd3\xeb\xcf\x7ff'\x96vE\xe6\x98^\x994_\xe0\x1ch\xb6\x16NA\xdc|\xbeJ\x93U6\x86B\x03\xff\xe46\xa6|PhZ\xd6P\x01\xa7\x8a\x0b#\xbd\x0f\xea\xc7\x88\x060:`\xa4\xcc\xd0\xfaw\x1d\x97\x06&\x0b\xf0\x15\xe8,\xc0\xd1\x9b\x96\x11\x04:\xde\x19\xd5S)\x84t\xf1\xe4,3\xcf\nm9R2s\\\x88\xc4\xc3\x19:\x98\xc0&\xa0\xd2\xcfqky\x06=\xb6\x84\x05\xe91.\x9f4\x8b1z\xb7^\x10\x9f!\x1d\x14\x96\x921\xe6\xb5\xb6Q([\xd3\xe6\x99\x87}f\x1f\x93OR5\xe3.\x05\xdfTg\x18\xb5\x05\xa3&d\x98\x0eh\xea\x80\xef\x05\xfc\x8c\x84Fl\x8f2\xe2\xc3\x14\xbd\x944\xcb\xb4T\xf2-J\xc3\x9e)\x85\x11S\xef\xdd\xc01L\x8f\xe0fs\xd3\x81\xc5\xe4\xa6n\xd8s\x83\x811\x9b\\\xee\xc0\xad\xf7\xa9\xee\x8f\xf8\xd0\x18 \n\xdf\x88\xb0?\xa3\xf0\xcat=\xa5\x9d\\\xa21\x87\\\xb2\xd9|\xb5.\x96N\xcd\x96\x8c\x02^\x9a\x81e\xc3\xe0\xfeA\xb77\x02\xba\xdag.\xac0\xa9&z4\x05E\x9a\xd2\x03\x10\xfc\x1aK\x13\xd4\xc9\xaa^Fp\xca&C\xb7\x9e\xd2 P\xbbWs\x8f\"\x0f\xae\xa4P\x9a\xa7G\xfa\xf3x\xfa\x89\xc5F\xf8w\xd2\xa9t\xa8\xc6\xe81\x86\"w\x19\x96\xa5\x7f\xf8>\xa0?\xf8:'\x1e\xc3*\xf4\x17b\x1eu\xfc\x12M\xd1\x13_\xf8\x0c\xb8\x94\xa8\xb4\x7f\x7f\xa8*n\" \xd4\xba\xd0-\xdc|\xb5\x00~8h\xce~\x0cj\xdd2\x16\x8d\x87_\x17\xd2\xf1kHg!\x90\x0e\xdb5\xe5\xf2\x90q\xd0T\xc5A\x0c\xdel\xe1\xe39.\xaf\xe9\x12mi\xde9\n\xb6\xf1\x0d\xd8\x86=\xb7e$F\xf9\xbb\xba~\x8c\xe2\xbd\x15\xf3\x81\x99\xd1?cqG\xcbj\xb0\xd3rM\xec\xb4t`\xd5\x07;-;\xb1\xd3\xbc\xc4NK\xc7\x85;\x86\x9d\xee\xe0\x18\x96GpG\xb1\xd3|rW\xc7Nw\x06\xecT\xeb\xd0\xbc\xd7\xfe\xe7{c\xea\xc2B \x81\x9b\xba\xfe\x9c.\xfe:u\xfch&\xb8\xa6Gc\x0bD\x90\x12\x0c\x8d\xc9\xad\xca\xa4i\xf0'\xe8&M%\xb1\xd3\x81\xe3\x9d\xdf-\xaf\x93HO\xe9\xa6\xebU7:\xd4\x9b\x0d\x0d\x0f\xbf\xcd\xd6m\x83C!\xa9\x0c\xd0q\xc1\x7f\x8b\xdd\xdb\xc8 \x81|\xaa\xaa\x19\x19\xd3\xbf\xdf\xb0#bt\xf5\xfe\xb0sdf\x94+E\x12\xe4f]p\n\x13r\x89\x96g\xfe\xb7\xc8\x131\x1e~cxJ\xf8\xbb~\x13\x11\x1aB\x972\x95\x1b\xa9\xechH\x13W`\xe0b\xd8lD\xe1\x11k\x7f\xc0j\xa4\x93I\xfbF\xe8\xddV\x02\xa7`m\x0d,J_u\x8c\xbf\xc6p\xe9$E\x9cUb\xe7+F\x1c\xea9C\xc4\xcb\x8a\x15I\xaf\xb8yq\xc5lU\xd6c\xacR;\x97eqM\xec\x15$\xb1\xd0E\x9a\xc4\x17\x98\x98_\xcb @\x87]\x8a\xb8\x84\x89\x82\x9e\x0b\x03\xd6\x8dY8/D=\x1a\x9f\x81\xda\x93\x87\xbaU\xf1\xa3\xc0\xd6\\\x0e\xaa\xd7\xb9\xc2\x88\xc45(\xd7\xe0Z\x9f\x80\x98\xdc\xa2\xe9r-.w f\xf8\xfe\xb6\x07\xfb\x9d\x9b\\\xb7kj\xa6\xceJ\x98\xd8\x97~\x1c'9\xd0\x86\x11\xc5%)\x14q\x19sH\xbb[\xbe\xcb\xa0\x1a^\x1f\xcaxyt@\xfb\xa0\x81@P\x10\x91b\x04_\xba_S\xb9\"\xe6\xfb\xdb\\\xdd\x9ch\x19\xab\x99c\xe5\xfe\xf02\x9d\xd0\xec\xe3\xc9\xf4\x87x.\x89\x93\xa8>\x04\xdd\x0c\xd9\x03\x17B1 g\xed\xc3\xa9\xe7\x8c\xb9\x06\xa0\xb5\x18\x0d\xab;M\xf2\x99\x16f\xab\x18\xff\xf7\xc3\x8cr\xa8\x98X\xe6\xfe\xbeK\xceT\xc6\xd6\xe6Lm\xccX*\xd2dj\x1b\x10|\x048\xca\xc7\xa5\x9c'\xed\x92\xf30S\xef\xfb{a\x06\xde\xc4\x0b \xefg/\xcc\xde'\xf9\x82EcH\xdd\xda\x0b\x06\x8a>\x04K7=W\xf5An\x83\x0b\x93\xfb4\xa1\xee\x04NBpjbB\xc9\x079\xd5o\xad\x99\x94\xac\x88\xdfo\xdd0\xcf\x1e\xf5\xe8\xc6\xa5\x133\xda;f^\xd61lb\xd4L\xccP\x85\xc5\\\xefL\xcf\xc1\xe6F\xf4[e\x81\x1a\xcby1\x18/\x8c\x83\xa8\x98\x12\xa1\x95\xe9p\x1fG\xef\xe0\xb2\xad\xda\xeb\x07\xae\xc9\xed[S\xb3\\\x9bEM\xee\xe5\xfe\x9c\x9b[\xd3_O\x9eP\x1e>\xa4\x8b\x88\x89\x92\xe9O<\x13M!a\x1f\xd0\xaeJkJ\x86ofa\x94\x93\xd4n]\x91PAn\x8b\xc7J.\xb1v\xaeV*\xad\x93\xe6\x84i\xa2\x16r\xf3\x15\x9c\x0e\x14:\x88\xdf\xf7\xf7hK\xc6\xde/WQ\x18\x84,\x1dIy#\x97 _\xa5\x12\xe5\x8d\xae\x8e\x9e3\x85\xb2A/J\xfc\xe9\xbfs [Y\xe0G~jq1\xbex%\xd3Y\x89m]\xa0s&\xbac\xc6I\xbc\xc5\xbeA\x84LO\xbc|A\xa0\xec\x7f\x14f\x18\x07\xdf\x87,X\x90\xa5\xef\xc1\x1b\xf1*%Y\x12\xdd\xd0\x13!\x99AV\x04\x0b\xe6\xed\xdf\x08l\xe3Y\xcdIe\x86=\xc9r\x15Fd\xfa\xa6\x82\x9c\xcf]\x08,\xd1\x01\xcb\x85\xc9\xa5\xfa\xc1\xd9\xd7\xe6\x07\x02\x9e\xda\x0f(m\xf9\xce_)\x14v\x03\x9etK\xf2\x1d\xa4\xd5X\xd0\x8b\x01k\xac\x95\xdf\xe3{\xf2kA\xe2\x80\x98K,\xfd\xd5\ns\x1f\x98\n\xcc\xfc(\xba\xf6\x83/c9h\x97\xb8\x1e\x94H\xf3\xd0q\xea\x8b+\x9e\xb0\xadx9\xc1m\x8af\x16\x9eh\xa9z\xa6\xf1\x15m6GQ9a\xa8\\\xe7\xa7|\x84q\xed\xf3#\x16,v\xe8H2'R!!U\xae\x08Fj\xd2\xd6\xae\x16\xc3\x9aP\xc9Jz\x15\xde\xab\xb3\xd7\xcf?\xbf\xbd\x10\xfa\x95R\xc1\xdf\xb6\"\xc4j\xa8w3\xbb\x0d1\xb2\x9c:h\x1d\xdc\x03?#0\x1ck\xe7\x03\x83'\x8a~)p\x9c\x0c\x0c1\x02\x0c\xf1\x96\xb1\x9d\x91\xb9\x1d\xb9b\xb5)\xd5G\\\\\x86\xa6\x04\xd3\xa2\xfd\xa6\x86d~N\x93x\x0e\xcc3\x141\x88h\x12\xd7\xcf9\xc3&|\x16J\xe9D\x9b\xba!\xe4y.SA\x0e\xa2\x83u^{\x92;.l\x90^\xf1_\xc49+[K\x17\n\xa2R\xf0\xe6\xf9\x8a\x04\xe1,$\xd3\x12-\"C\xcfQc\x06v\x92RD\x19\xc6\xf3\x88\xf0\x11r_]\x07\x83\xc6\xfba,pn\xed\xad\xa72\xb5k\x84\xb1\xd1\x0d#\\w\x18\x7f{\xfe\xee-\xc7\xde\xb51P\xbci\x1a\x81\xf4\xae\xd1\x7f\xb1\x8f\xc9-\x14\xb6\xe6\xdcb\xc7\xa7V\xaa#\xf0\xf8X\xf5\x05\xac \x93\xbb\xad1\xd7$\xf6\x86\xc3\x9a\x19\xdf\xa1\x96\x96K\xda\xe4\x956\x81'\xf4\xa5\x1aXLn+\xd4\x1e+\xef>\x9f_\\}>?\xbb\xfa\xf8\xe9\xc3\xc7\xb3O\x17\x7f\x1b\xeb\x92\xa1\xfe\xf5\xf9\xf9\xd5\x8b\x0f\x1f\xde\x9e=\x7f\x7f\xf5\xd3\xf3\xb7\x9f\xcf\xc6\xb0\xab/\xf5\xfe\xf3\xbb\xb3Oo^\x8aR\x87\xfaR\x1f?\x9c\xbfA\xd6@)>2\xd4\xfa\xe1\xa7\xb3Oo?<\x7fu\xf6J\xed\xc6\xce\xa8\xf9E\x18\xd3\x85\xf1\xea\xc3;\xc1\x10\xbfD\x19[\x97\xf3\x12H\xb2\xd1P\x7f:\x02'v\x89\xc7\xab\x0e z8\x98NS\xe0\xe2h\xe2\xbd\xfa\xf0\xeey\x9e\xa7\xe1u\x91\x93\xf7\xfe\x92d+?\xe8\xfe6\xd3\x7f\xdb\xf5Y$>\x13\x00\xe8\xf5U \xbez\xc7\xe3\x9d\xbc#\xf9\"\x99\xf2\xef\xf4\x98\xba\x94W\xccP^\xe1\x85\xd9\xcb\"\xcb\x93e\xd9_J\x18\x16\xdeU\xe3\xb9\xb0\x97\xe4^U\x9a/\x9d\x16\xba\x1f\xf0`]\x95s\xa0\xea\xd7fL\x12f[\xbb\x87\x96\x0b\xb3\x16co\xdaw\xa4\xcd\xbc&Y\x98\x877\xc4X\xa7\x1e\xcb\xf5\xab\xfc\xc3\x0dI)\x07E\xa6\xc6\xe1\x9b\x90b\x93\xc9\x95/\xc3F\x06~\xf2/<\x05\xe2\xb0 \xf8L\x1e\xa5x\xa6\xefd\x19*(\xb5\xad\xbd\x01\xee?\x174[\xb4ms\x03\xdf\x9a7\xe8\x9c>\xeb\x08[\xb5\xf0j{\x02N\x14sA\xf9\xd2\xbbi\x00:\x96k\xb1\x88\xad\xd4\x8e;\x0es|\xcd(\xaf\x17\x19\xbf\x92w\x1b\x9c@\xc4\xca\x07\xc6\xf2\xf5\xcd\x06'\x10\xb0/dD7\x99]6lv\xc4\xa5\xe1\xd7jO4\xbeq\xd6\xf8\xf9\xd6\x7f\\\xf9[\xbf\xfd\xf2K1\x18\xbc\x1cl\xe1\xdfW\xfb\xec\xcf!\xbb}\xcdn_\xb3\xdb\xd1\xeb\xd7\xf4\xcf\xce\x01+\xbcs\xf0\x8a\xfdyMo\x87\xaf\xf1\xedh0x\xb9\xc5\xfe\xbe\xc2?\xac\xf0hx\x88o_\x0e\xd8\xed\xeb3z\xbb3\x18\x0c\xe9\xed\xab\x03\xfc\xf6\xf5S\xf6\xf6\xf5\xab\x97x\xfb\xea5\xbb}\xfd\xfa\x95&|Is\x05\xbdyu\xf5\xfc\xe2\xe2\xd3\x9b\x17\x9f/\xce\xae\xde?\x7fw6\x06k\xea\xe7\xfeVJ\xfc \x0f\xa7Vs\xfb}\xfa\xf0\xe1\xa2\xed\xa34Ir\xcdg\xf5/\xae\xce/\x9e\x7f\xba\xb8z\xf9\xd7\xe7\x9f\xb4F\x85Ji^\x0e6\xc1\xfa\xe5\x97-o\xb0\xf5\x14\x81\xfc\xe2\x00\xa19\xe0\xc0\xddg\xd0\xdcy\xcd\xa0\xb9;\xd0t\xa3Z\x1cz\xae\x1e]\x0d\xb3,d\x8e\xd2\xf1\xd4O\xa7\x0c\xff\xeb\x91y\xcbQ=n\xa4\x16\x00\xb4DV\xca\xf7\xa1\xb3\xea\xfa \xa6\xfai'\x13jj!3\xe2\xc00\xf5\x03\xb7\xbd\xb2I~\xe9\xc8\nr\x8d\xd6\x15\x8c\xa8B|3ln7\x13)\x8a\xe6\xcdFS\xcf\xef\xceO\x1c\x1c\xee\xd4\x18\x8a\x1df\xa3\xfc\xd4\xc0W4x\n\x8a\xef\xfc`\xf1\x89\xcc2.\xe1Bi\xc7\x157\x9d\xe264:a\x87\x9e\xcfX&E\x9cK\xf6\xf1\xea\xd8P\x98\x1f\xa2\xb5\x94^.V eZ\xaf\xc6\xae\x7fi\x94\xe7\x10\xb5\xdf\x92\xce\xa7\xf9\xd2K\xc9\x8cI\x91\xe7$\xffD7\xff;\xda\xea'\xe2O\xefl\xc7#\xf1\xaf\x05)\x08z\x04R\xcc\xdc\x86_\xe7$\xffk\x92\xe5\xef\x93i\xe7\x8e(\xbb*}c\xb7:6\x17q+P\xb5\x8dxSRN+3\xb1S&\x94>S+n\x08\xb0\xeb\xfd\xe0\xf1\xf3Z'74M+\xe3\x8c\x94^4'\x12\x95:(T\xc6\xc4\x13!\x97/_\x05I\x9c\x93\xafF\xdfdM\n\x10\x90\xd6S\xeae\x8b\xa4\x88\xa6\x9fWS?'\x08\x14_\x9ft\x18\xf0\xacA-B\x1d\x82\xbe\xc3\xec1\xeb \xb0\xc5\xa8]\xf6\xd5\xe3\x16`\xdcc\x016\x11P\xdbT\xadH:K\xd2%\x1b\xef\x9b\xd9{\x12\x90,\xf3\xd3\xbb~\xfe\xcb\xc4\xbb*\xf0\xcb\x17~\x1e,\x98\x86\x8f'\x8a\xc51\x9ajo\xac\x9f\nk\xe81`\xf8=0\xe0\xc8\x10\xedo\xb8\xfbT\xab?\x1b\x19\xfc6w\xf6\xd4\xf2\x183\xad2\x08\x91\"YN\x93\xa0\x10\xd3\xab J'^{\xe2\xc7\xbb\x84)q\xf4\xb5\xc5\xfeM8\xc7h\x9erf\xe5\x93\xe6{\xaf\xc8H\xfa|\xce\x1b\xde\xfe\xe5\xfal:'\xbfl\xff2\xdd\xf6r\x92\xe5\xb6\xa6\xa0\xf6\x1c\xd0\xf8x\xd0\x8d\xd7\xf0\xa9\x00\xd9\x82\xcc\x8b\x93\xa9\xc1:*\xe69V\x995\xa7~W\x8b8\xedz\x8e\xa5\x16?\x9e\xc7\xb1\x8cK:\x00\xc3Y\xb2,h\x93\xf4\xd2\xc5\x1d\xa5\xd9\xbch\xc5Z\xed\xb6E\xbe\x8c0\x8a\x1c\xda\x8e\xd1;\x07\xc6\xd2{\x8aP(\x1c}V\x00\xf1\x8bi\xfd\xd6\xd6]\x84Q)\xbbv\xd2p\xc8=\x16(\xdc\xf0?\x94db\x02\\\xdd\x0b:\xf7\x95\xd9B\xed=\xa5\xe1\xea2\x0bf\xeb\xc1\x03\xeb\x89\x92\x82a\xf9\xfc\xe9\x0d\xc6\x83\xd2C\xe1\x1c+\x10\x85\x84\xd2\x94A\x8e\xb7\xaf>\xbc\x93\x7f\xb3\xca\xc5\xddE\xf2\x85\xc4\xec\xc6\xcf\xfd\x8b\xd4\x8f\xb3\x19I\xdf\xe4d\x89\x0f_\x87\xbcQ\xba\x9d\x9fG\xd1\xcb$\x8a\x18\xc7\x8bO\x94\xdb\xd7I\xba\x14\x0e\xca\xf4\x9e\x85t\x16O\xde\x91i\xe8ce\xef\xc2%\x1e\x80\xcc\x8d\x9b\x9e\x03S\x8a\xce\xde\xf9+\x97\xfe\xc52\x1f\xfd\x90\x8e\xe1\xd7\x82d\xac\xeb\x1f\xa3b\x1e\xc6\xfc\x0f\xfb\xf2\xfc\xa7\xbf\xbc\xc5\xb5\x8e\x05\xce\x7f\xfa\x0b#\\\xc5\xddG?_\x9c\x93yy\x9b\x84q.n$(\x9c\xff\xf4\x176\xee$e\x83f\xd15^\x14\xb3\x99\xa8\x8b\x82\xfb|A\x08\xfb\x9c\xa2\xa1\x8b\xd4\x0f\xbe\xbc\xe4\x00/\x1f\xb0\xbb\xa4\x08\xb0G\x96\x88\xe7\xe1\xd2y\xcc\x18\x99\x93\xa1(Dl\xd1L\x1f\xb4\x93\xee\xccb\x92iv&\xddK)\xdd\x89\x8d73\xe0\xfb-\xa8,G\x15t\x81\xce\x1b3\xee\x8a\x94`\xc8Q\x17\"\xba\x10'\xd1%\xdd\xee\x1e\xc2\xb5c\xcd\xab8\x91\xa1\xa62\xbcI\x17\x024\x1c\xe9\xb1\x08T\xe2eQ\x18\x10\xfb\xd0\x85\xada\x97!\xafi\xbb\x9b[\xeb\xce3\xd5\x99c\xea{\x04\xc7\xeem\xd8o$xj\xee \xf6\x10\x9e\xd0s\xbf\xb9\\\xea\xee\x07\xf6\xc8PNrd\xb0w\x0de\xb8\xbb\x84\xa2;_\x0fAJ\xb8pG\xe5\xbd8\x0f\xb7o\x8a\xd8\xde;xp\xe5\xe5\xe3B\xd2\xb5\x84\x8c\x1d\xdc\x1d8\xdeL\xd7\xc3=},\xe6&\xee\xee\xda z&\x82E\x99M\xd0\x1e%\xe6&\xc6D\xf6\xc9\x08\xb9\xf6\x93\xa0l\xac\xb92T\x97\x93\xbe3\xb9&\xa4\xba\x98\xf4\xdd\xbd=\xc7\xde\x18\xd4D\x95\xa3\x9d\x03\x87\xc7\xedq\xc1jF\xcf\xd1\x9bG^QR\x8eG\xfb!\xc2\xfe\xee\xaa\x9e\x82\xe3\xa1%\x06\x8f\xb0\xb6\x12\xd1\xc2\xae4>\xfee\xb8\xba\xabPooRK\xfe}\xaa\xa5\xa8\x10\xa8<]L\xe3\xf54\x895\xe1\x18\x90\xdbB\xff\xdb\x9c\xf1Wbl\x9b'\xa5\xaf\x84n\x8e\xcd\xaeK\xbc\x9d\xa1qn\x1d\xed\xe4\xfe\x13!\xf5\x162n#\xb6\x87\x83\xa1c\x1b\xa7\x9a\xb7{@\x11\xbb>\xae\xef\xef\x0f.X~#\x8c/\xf4\n\xe5+7\xd1x\xa9\x88\xe7\x1c\xcf_\x07\xe8\xfd\xe0\xda\x9aQ|c\xa3!Vn\xcf>\xadU\x8ftat#\x89\xddk6e\xb3(\xdd\x01\xc0\x02\xcb\x86\xf1#\x17\x1c\x81g0@\x1e#ET\xf1t08\x18>}:\xda\xdb=\xd8\x1d<}:\xa4,\xc7\x9a4\xfd\xb7d\xb5lM\xa1\x07[0d\xe6\xc0\xd6\xbb0fVs(\x12\x06B\xc9\x0f\xf8\x17\x0cyFi\x90#\xb8 \xb30\x87E\x9e\xaf\xc6\xdb\xdb3? \xd7I\xf2\xc5\x9b\x87\xf9\xa2\xb8\xf6\xc2d\x1b\x15\x99\xdb\xd3$\xc8\xb6\xf1\xe3\xad) \x92)ar\x9f\xd30\xbe\xf1\xd3\xd0\x8f\xf3\x13\xac\xb2\x96:\xa6L\x1bHQ\x8e\xf5\xc4O\xe7\xd9\xe4\x92\x95\x8bi\x15\x9f?\xbd\xa9d\xdfRb\x19\xd8\x84\xa1\xeao\xc4\xea\xc0Qc\xae\xb6\"\x8a`I\xb2\xcc\x9f\x13t\xb4\xcb\x08>\x8f\x93xk)F<%7@\xe2\x9b0Mb\x14\xaf\xd2\x8f\xf1C\x1cG\x06~<\x05\x7f:\x0d)\x80\xfd\x08\x16$Z\xcd\x8a\x08n\xfd4\x0e\xe3y\xe6)n27<,d\x95oHM \xc0\xa8\xbc\x04\x85d\x14\xf6o\x04p\xe0\xa70\x89\x90\x9d\xc2\x8c\xb8\xb3\xd4_\x92\xec\"\xf9\x98\xac\xe0\x84\xceT\xf2\xc8\x8d\xd1\x87\xbe\xe3IC)]CJ\xb7\xeb\x1c\xc9\xd3\xf5Vk\x8bI\xa7x\x03\xedj\xaa\x86\xf7\x998\x03\x1a\x91\x04\xa1\x81\xf4r\xe1\x1d\xd5\xba+\xa4\xc6j.Up\xdat\xb1\x1aW)L\xf0\xd9%\x93\x94\xc6\xcd\xc8\xc0\xd887T\xe9\xdb\xbcu\xcd\xca\x9b\x932\xf2z\xdf\xa3\xdc\xb5_\xa5\x1a\xaf7\xa5\xa6\x0fi\x99\x8ee\xcdJMu2}M\xbf\xaa4\xda\x0bm\xadl\xd6{\xd7\xaaqU\xd7\xd6\x8aa\x0f\xfa\xd7\x8a\xc5;k]\x1b\x9e\xb2\xab\xa2\xae\xc2Od~\xf6u\xd5\xb7\xb6r\x8d\xb2\xcf:\x16i\x0f\xa7F\xb9\xee\xfe\x8e\x8dR\x1b\xaf\x14\x0f\x84^\xbd\xa7\x1fu\xf4\x1dq\xea\xda\x15\xe3WR\xcd\x0c\xcfIf\xe5X@\xd7\x9e0\xea\xe8\xdd\xa4(\xd5\xb9d>\xa6\xe1\x12\x0d\xfc\xfaV]\xedk\xd4\xeb\xe9P\x07\xbe\xd0l/|n\x88\xe5\xa0[\xe2P\xcf\xc4\xa7\xed?\x93O1\x970~S\x16{p\xca\x185\xb1\xbd\xb7\xebx\xec\xbd\x9e\n]\xdf\xfdWs\x8e\xe1\x04J\xc1K9'#\x0e\xd9\xbf=\x7f\xf7\xf6\xeck@V\xfcx\xc5\x97)\xf13\x9cY\xc2\x1f,\xfd\xf4\x0b\x0b\xfc\xc0n9\xe9pR%v\xa1\xe5)\xcc\xec\"\xfe\x12'\xb71\xb0g\x8e\xe5\xc0&/\x85\x95\x9c\x82\xc52\xfe\x89'\xe5)f\xe3\x99b9n\xd9\xe5U^\xa4\xe4<\xf7\x83/\x17\xa9\x8fQ\xc6\x0codk\x19)\xee\x01\xad\x10\x9fe\xb4$\x86\x0d\x14\xc4\x87\xc3\x9f\xd1.K\xe9\xcd\xca_iK|\x0b\xd6 9\xedOj\x8c\xbb\x90\xd6_\x8a\xb1\xb6\xae\xec\x1b9\x1b\x01\xce\xd3&Xc\xd0G\x0c\xc9)e\xd79 .lT\xc1\xfcq\x1e0\xe1\x07\xa3\nM\xd3\xe1(\xa1\xb4\xd6\x8e\x83\xd3%\x8884E\x91\xa0\xd3\x94*>$\xa5\xff\xc8$\xb6wv\x07\x8e\"h\x15\xbe\x83\xf8\xfe`o\x88\x96W\x07{#\xb5\\\xe5j\x82\xe5vx\xb9]\xfew\x8f\xff\xddw$w\xf1G\xecN\xf1T\xe6\xaat\xe9:b{\xd4Hu\x11r\x13\x08\xf5\xb90\x8dP\xa5\\E\x15\x103\xf5\xe6L\x14NX\x0c\xaf&\x92\xc8L\xd2-\xd1\xd3\xb61\xaaeso\x1af+\xca\xc82O\x0fo\xb5\xf032\xfdD\xe6a\x963\x05\x08Z\xeeNbs\x14\x89\xc2&\x8d\xa0\xec\x0f\xf4Y\xdc\xb4\nJ\x99\xaa\xdd\xbb\x12\xcd\x8a\xa1\xa2\x01\x8b\xf6\x05\x8b\x1c/\xbdy\xc3\xcf\xb6\xc6'\xe5\x0b\x17\xeaq\x86\x9a@\xd4\x04\xd4\x14\xe1\xfaz\xc1\x03\xa5\xfc^\x9e\xfa7$\xcd\xc8\xc5m\xf2\x91\x96\xb3\x89w\x95\xfb\xe9\x9c\xe4\xb4+.dJN\x9bf?\x02\xbd\x18}\xad\xbe\x98\xe6\x97\xd9\x99\xc8\x1dj\x14\x03!\x9e\xa3|=\xa6\xd6@\x05\xb8\x00$\xd3M7#X\xd2K3\xfaX\x1d1@]\xe6\xd1\x1c\xff\xcc\xb4H\xd1\xc8\x85\x99s)PH\x95\xf1\xb7-\xef\xce\x8f\xf5 \xa1\xfb\x9a\xafj\xcd\xc0\x1f\xb3\x84\x93o[\xc2\xd0 \xc8U\xdf\x05\xadB\x80\x16\x9a\xa9\x0bw\xa0I\xc6\x04\x1c\xae\xd3\x86\xce\xd7\x0f\x82bYD~^.\x85W\xbcM\x92u\x19pb\xf0\x83\xa8\xd5R\xb2\xad\xfa\xf3/\xe1\xea\x02;\xde\xab!U\x15nj\xe8U\x98\x92 _s\x14\xab\x9e\x95\x9f\xc59I\xdf\x12\xff\xc6\x00\xa6\xd2\xb4W\xd7R\xb5\xed\xaajlf\xcd;\xe3 ]L\xabF\x7fRO\xf1\xe97\x1f\x8d\x86\x93Q\x1fy\xaeyb\xf2\x88\xceC\xdd\xc9\xa8;I3\xc3I\x1aUI\xa6~Ws0a\xcc\xf9\x86\xc9\xd1\xacK\x8c\x04b+\xd9\xa1G\xbe\x92\xa0\xc8\xa5y{\x13\x7fH\xa7\x84\xd3\xedh\xfb\x95}$i\x86\x1b?\xb7\x193&\x13\x94\"\x0f\x91\xdd\xd8\xdd\xf5^\xf5f\x8f\x11\x81n\x0cZ+\xeb\xcd\xb9\xb3\xca\x86\xad\x95-\xfaVfy(\xe9\xf4\xae\xd2$A\x93\xaa7\xaf\xea\xf5\xd6\x17\xd2M\x03\xadH\x1e\x00\xcdF\xd8\xcb\xb3\x1b\x12\xe7\xccl\x01\xe7a\x0c\x89\xa7\x7f\xd3D\xf4\x8dr\xd9\x0b\xee\xde\xa7\xa9\x83\xbfk\x9d\xb2\xa2\xa4\xdb\xfa\x19\x06ku\xe51S@ZOw-\xfcR<\xd6\x1cD7\xdce`\xd1H\xf4I/;\x9a\xe4,\xfbh\xc4\"\x81\xfd\xfe\xe08\x93\x10#H\xe8\xeb\xc2\x94_\x8d\xf3\x81\xd9\xebd\xda0b>\x1a|z\xd3p\xfa\xb1\x1a\xbc\xeeY \x866\x00J\x84o\x0f\xa3|\xa1I\x8b\xb4=\xa3\xe4C\x9f9\x00)6\x84v1\x8b\x0b\x835XI\xfc2\n\x83/\x96>\x90B\xa3\xdcK\xc6\xe6\xf6(\xfe*)\xae#\xd2\xb7r\xa9t\xff&\xde%EF^%\xb7\xf1:e\xd7\xac\xfe]r\xb3V\xd95\xab\xff\xbc\xea_\xb2\xbbj\x90\xf4t\xf6\x06\x92\x8a\xfeu\xc4\x12\xbcbT\xc0\xdc\x05\xeb\xba\xc8s\xb6Cy2H+\x8cWE.?\xc8\xd0\x14K~\x92\x93\xaf\xb9\x9f\x12\x9f?sZ\xbc\xa8[#s\x88K\xf4\xb2\xe98\x05\xa0\xea \xc4\x85\x87s\xe3\xcd\x03\xb3\xceV]'DDJ\xf59\x8bY\xed\xc8b:=\xeeH\x8dx\xa8T\xf2SZ~\x92^\xb6a\x00\x96/\xe8\x11H`=\xb4\xc5\xf9\x8a\xdb0\x8a^\xd5Z4=g\xed\x9bG\xae\xc7AX\x1dO\x81\x94N(tz\x0c\xfey\x14\x95lC\x17\xd5)\x98<=\xe0\xeby\xbc\x15\x12[\\\x14O6\xfcpc\xb4\x82\x89&\xf1\xe5$\xbflC\x8ab\xfcf\xf0\xeb\xc4\x06\xe2B\xf8\xa4\x86i\xd0=\xb7\xb9\xa1<\x87)\xef`\x8f=\xf1\xa0J\x90\xf2\xd4\xe7\xc7{\x7f\xca\xbb\x84g\xe8\xf2\xa3r\xc5H\x83\x9a\xfd\xa1\xdff\x7f(.a\x87\xe8O2\x03|p^\xba@O \xda\xc8\xab\x8dF\x1e\x83\x19\xf2\xccv8D.7\xa4\\\x91~q4\x11K\xf3 \xdf\xdea+\xbc\x99\xebU\x13\xdefR;\xc0\xbe\x05\x1a.X!\xba\xd2$ Y\x86U\xffo\xdaHW\xf5b\xcf\x04M\xe8\x94\xfc\x01d\x88%\xe1\x14V0\x86\xa9\xe32\x80Q\xaa\x0c\x93\xb1\xfa^JP\xd5\xfd\xd2/\xe6\x8b\x9c\xe9\xc2[\xbbyu\xb5*\xd29\xe90\x81\x89*S\x0fc=\x12\x91\xf4\xc2\x8f\xbf\xf4\xcb\x8f\x1d\xd5\xeb,\xef\x0c,!\x0b\x01\xf0\x8d,a#\x85\x97` \xd5$A\xfa\xe8:7!\xb9\xed\x9aK(\x83\xe9\xd1\xd2U\xd0n\xbc\xd5\xaf~1\xfd\x89\x16e\x82\xf0\x99\xf4n\xc3x\x9a\xdc2\xcb\x81\xb2b\x8d\x87%H\x87P\xeea\xe2\x85W\xdcKM_\xb8<\x0eO!\x16!o\x7f\n\xc9-\xc6t\xe5\xfe'?\xb3\xc6\xc7\xc0z\xd1\xdc\x85MffJr?\x8c\xfa\x00\xac\x04\x12\xfb\x84\xb6\xdb\x199\xbb5B\xa6\x0b\x89\xda\x16oCRZIy@\x1bf\xa3\xf8\x85\xe7\x17s\n5\xcc\xa3e\xfb\xcc\x0bT^\x94\xfe\xb7/J\xb5\x93\xcb\xe4\xa6\x13_\x10\xcc\xa7\x1e\xe4o\xe2\x9c\xa4\xb1\x1f \x01\x1d\xdd&\xa8El\xdb\xae=\xc4R\xe5t\xe8\x9bi\xab}\xe1w\"\xd3\xbaF\x9e{\xff\xae\xdd\x90\x92\xbe\xde$#1C\xcah\xd7\xac\xc7?\xbdTS8\xa9\xd5\xf7\xdb?nH\x8d\xbcLVwi8_\xe4`\x07\x0e\x8c\x06\xc3}\xf872\x85\x9f\xfd\xdcT\xec\xefdz\xcb\xea\xabl\xc5\x02\xbaz\xd1E\xb0,\xff\xe3\xf6\xffQ}\xdc0\x1f(\xfa\xcd\x05u\xab\xd6:)\xa9D\xbd,\x91G3t\x02\xc8\x14\x16\xe1\xd9\xbe\xa5\x10\x17\xcdh\x95-\xe1,\xc4\x86\xafl\xeat\xf49plo\xcc\x9f\x0c\x92\x90\x85\xcbaR3Q\xa5$\x958\x81P1Y8\x81\xd0\x01\xc2\x9c\xfe\xda\xa8\xb32}L\xddb+u\xca\xaf\x13\xcf_\xad\xa2;\x9eP\xa9\x95\xbf,+\xaby\xc3\x86z\x82O\\\xe5D`F\xa0\xd4\x11\xc6\xc6\xa9\xc8\xcb\x93rG\x17\xde\x1f\xff\x9b\xe9G\xc2\xf2\xceZ\xd0\x1aKR\xc6c\xacy\x814\xeai0\x92\xd2\x85\x0eGk\xd7\xb4\xa2-x\xb2\x9e\x9e\xfa\x81C9\xc7\xd8\xb4(\xcb\xade\xf7\x95T\x9e\x0f\xf6zV\xc8\xdc.\xb8\x0f\x8a\xe3\x9e\x1b:\xd5\xf3?\x81A\xaf\xda]\x16*\xbc\xde\x9a\xe8i\xea\xc7\xd3diw\xfan\x18\xbak1\xf36\xdb\xf2\x82$\x0e\xfc\xdc\xae\x85\xc4\xc74\xc6cJeX\xce\x95\xe5\x82\xbd\xb9\x19\xc3&\xa4Ne\x0e\xb1\xb3\xff\xf8\xe43\x8dh\x06<\xb5e\xe39Sp\xec6\xe6\xcb\x07\x83\xd5|\x05\x8d\xdcc\xd9o\x87\x83\x81\x03\xa7\xfa\xd2\xd0-ZF\x94V\x06Y\x0d\xe9\xf2\xdd\x188.\xa46\xe5\x9d\x13\xa7\xdd\xd0\xdd\x14\x8c\\\xb6v\x7fh\xb4g\xcdInQ\\\xc1\xacW2q\xd7t\xfc\xb2\x9e\x07\x94aKR%\xdc\xb4\xc9\xf3\xcbBw\x0c^7\xe5\x0cE\xb2i\x0f_P\"\xf1\x11KTsP\x89\"\xeb\x9a\x17\xc7e\xce\x88F\\\x9f>=\xc1\x9d\x11\x9002l\x9aY\x94$iW\xef\x0c]\x0b\xb3\xf7\xfe{\xf4\x81\xd9\xc44\n\x03\xe6\x12\xc3v}\nc\x88\xd7O\xe8!\xe1\xa4Q\xaf\x87J\xe3>\xc3\x99\xa6\x91\x1b\xb4\xc4qn\xf4\xc1 \\R\xcaK\xddh\x98\xd6\x88\xcb\xd4\x93\x9d\xfe=\xd1\xb0n\x9aO\xea\x9d\xa91p\xf2\xa5\xf0\x8c\xba\x05\xd9\xe7\x0c&\xd5\xa9[\x92ofC\x08X\xe3\xd05\xef\x97\x7f\xa0\xe7\xaa\xd9Gr_\x9f\xc8b\xcf\xe4\xc3\xd9\x89\x0eR;Y?\xffZ\x97\x98gO/\xe69\xd0Iy\x98\x87Y\xf3\\\xc4A\xd5\x1f3\xbd\xff\xb0;\xc7\x9e\xd9\x14.cF<\x1ao[\x96\x94\xdeGk%\xcb\x82 \xb9\xd4\xb9\xf7\xa2\\\x7f`\xf0\x06\x8f\x1a\x11\xd8C\xb3\xe7\x1cH\x82']8`!^\x9ad\x97]\x84\xaaT\\\xe3%\xe72\xef<6\xa6f\x02\x0ds\xc21X\x1f,\xd8\x84\xcdMM\xf2oq\xddj\x93l@\xe3\xdc\xc1'\xad\x92\xf9\x99H\xeb\xa2\x8dfB\xaf\x7f?\xfb\xdb\x184\xf6#\xef\xcf\xce^\xe9\xd3\x17\xce\xfc,\xffw\xa2\x86\x873mg\xcc\x1a\x90\xc8A5\xb5n\x0b\xcc[]\x9f\xb6\xf2\x14\xacs\xca\xfdX\x1f\xd1X\x9f\x98e\x1d\x1b!NOk\x04a,\x97\xd5:\xf4\xdaj\x97{lT\xd4\x9bu\xd6R6P]_\xc4\xa5\x9fLq\x86N\xd2K/lNl\x13\xf2s\x92\xffL\xfc/\xeb@\xfeQ\x00\xd90\x84H\x84&<6\x86\x7f\x088zi\x05\x92\xf8uJ\xc8o\x9dBn\xa8*\x8f\xd0\x1e\xd4\xa3\x8b\x9b\xfe\xc2\xd8vO\x9e\x80\x00\x13\xfd\x1d\xd8u\xb6K\\:\x02\xb0\x8d6c\xfc\xee\xef\x0fe\xb8\xe77\xd9Y\x19yC\xfb\xf5Z\xb4\xc9\xef\xdf\"]\xd6W\xadw{\xcf]\xb0\xaa\xc8F\x0d\xf7w\x8e\xf2\xe4xG\x947\xf7^\xbe={\xfe\xe9\xea\xc5\xdfPs\x847\xf8\xeb\xfd\xd9\xcfW\xcf?_\xfc\xf5\xea\xecS\xf5\xe0\xfc\xe3\xd9K\xfa\xe0\xea\xc5\xf3\x8b\x97\x7fm<.\x1f\\\xfc\xf5\xd3\x87\x9f\xdfkJV/J\xc5\x05\xedCLn/(}\x1b\x9f\xa5\xed\x9eg|u4\x97\x0e\xc5A\xda\xa8\xcd+\xff.J\xfc\xe9\xb8%\x83$\xd4\x89y\xb5C\x18/\xf3[z\xa59@\xca^\x91\x8e^\x9c\xafH\xf0\x8d@\xc9\xbe\xbd\xf9o\x06\x81&\xbe^\xef>\xbf\xba\xa6;\xd7j2\x01\x0d\xc4]~\x9c\xadH\xa0i92\x1f\x02\x8dO\xb5\xad\x06\xbac\xa5\xfc\xd4/\xf2\x85\xa6\xd5Y\xedT\xc2\xd2\xb8\x80\x95b\xab\xaa\x18;\xc9\xaa\x92W\xd7w\xcc-\xb37_\xb6\xaf2X\\\xc6\xaeK\xdcY\xba?3\xa5\xc0\xe5\xda\xe1C\xdaH\xed\xfb{\xb4\x0fa6?\xc4\xa1\xef*\xeasMfs\x7f\xc7\xe1\xec\x96\x0b\x16s?5E\xaf\xeaE\x98H5\x0f\xf4\xee\x88\xfb\x0d\x19\x0bO\xf7?\xd03\xb0\xfb\x03\xbd\xf0e\x7f\xb0\xdb7\xdc\xb1\x10nli\x98\xa1\x98[U\x01W\xd3\x0c0\xe6\x16W\xe2\xd6\xd7\\\x92r?c\\@\xb6s\x04\x9b\x9b9\x1cCl\x0c\xb3\x99\x1a3\\3\xafa\x92\xdb)f\xcfK'\xc3\xcbv)\"\xbd2\xd9\x0b\x98\x9f@\xa9[{\xccm\x0fO \xa9?\x9f\x13\x96\xfc\xaa\xf6p\xe1\xa3\xe5J\xfda\x86%\x8b\xbauK\xb6\xde\xdc\x0f\x07{}$c*\xd8$\x93\xd0\x13)_x\xbc\xb5u\xd4\xe4C\xb8\x94~\x12_\xb2\xfc\x83\x92\x19\xb0\xf6\xac\xd8\x1a>z\x8f\x0c\xba\x93\xd1kFS\x0d\xe4\xeaj\xea\xe7\xfe\xd5\x95\xb6_\xa9\x9d;p\n\xf1D\xc3:\xe7\x94u\x16\x8f\xc7`-\xfcla\xd1\x134\xf6\x96\xfe\xea\xd1\xe31\xb8C\xed7\xe2\xf2\x89\xf0v\x06w\xa8]\xfd\xc6\xec\x11\n\xd7\x84\xeeD \x9dlA\xde\xa5!\x85\x86.:\xc6)\xf86*\x93\x12\x9b\xe0\xba tg\x89T\xddc\x94\xb8v\xc0M\xee\xdbZ\xbd'\xde-\xb9^\xf9\xc1\x97\x8fIt7\x0b\xa3\x88\xab\xe4\xa7d\x95\x92\xa0\x99\x17\x14=\xdeW~\xbe\xc8\xb8=I\x15z\x99\x7fY\xde\x9e\xb0\xf4\xb3z\x06\x8f\xb8`\xb1dM\xda\xd8f\xb5p\x91\x9a\xf0tk\xc5>#^\xd4x\xad0\xd6\xad\xfd\x0c\xffG\xfa\xa8\x11\xc64\xfa\xd8\x9c\xad\x13\x18>R_\xab\x9a&\xd4\x07@w\xdd\xf6\x7f\xda\xa7\xe3\xc1\xfdd\xb8\xf5\xf4\xf2\x97\xe9\x8f\xce\x9f\xb7\xbb\xb6\x88\x01\xa3$\x95\xb1\x8f>\xef\xfb\xc6\x86\xfd\xff\xb3\xf7\xef}q\xe3\xc8\xe20\xfe\xff\xbe\x8a\xc2\xe7\x9c\xac=\x18\x03I&\x97\xce\xb0,\x03\x9d\x1d\xce\x06\xc8\x0f\xc8\xcc\xce\xaf\xc3\x971\xb6\xba\xdb\x1b\xb7\xddk\xab\x9b\xb0\x9b<\xaf\xfd\xf9\xa8$\xd9\xb2,\xd9\x86\xb0{.\xcf\xd7\x7f@[\xd6]\xa5RU\xa9.T9\xd3\x18\n\xc9`\xc4*{\xf2\x04\\\xd5EI\xde\xf0A\xb2\xb1\xc7M\x87\x0b\x1e]\x80xX\x80\xc0\x1f`k\x97\xff\xfa\x0f\xf4e\xcfi}\x8c\xc5\xfb\x80\x99\xd2]L\xf5\xcd\x82\xed(\x17\xfa5\x8a\xe9\xa2\xf9z\x8b+\xd8\x18\xf1\n\x86\x03P\xba\x82*\xae}\xc8\xa1\x83\x90\xd2\xb1\xa1`\x1f^Y\xc8\x9dg\xfa\xfd\x99 w\x9e\xe9\x0e\xc6\x05V}\xa6\xd3\x99\xa5\x99*M\xc5%\x81^\x0d^\x18\xb9\x85\xd7&\xa4S7\xf7\xdats\xea&Zj\x8c\xa9\xa1\x96:\xc7\xd4\x95\x96\x8a\xe1\xdd\xea%q\xb9\xe1\x91\xe2m(\xfc9!\xb7W\x08vk\x97\xbb\xe3`\x7fQ\x97\x8c\xbb\xacqw=\xae\xd5\x947\xca\x9e\x84K\xb5X\xee\xf1\xd01j\x96\xf7E\xbeHJ\"\xb3%\x01\x0f*N\\^_\xd8\xc8|A\xa8Z_\x88YV\x8d,\xbf\x90\xf0\x93\xd6\xec\x8ao\x0fw=\x08ZK\xe3=_\xa62\n|c\\9r\xcf6\xfd\xbc\xd8\x9d\x8b\"\xf4\xc1>\xa4n\xc6\xdd\xdbh\xd7~\\\x81P*)\x18/\xf7\xf1Z>\xea\xbc\x967\xac\\\x9b\xa6\xc5z\xa6\xc3\xea\xc1\xe9\xb4T\xb1\x1cVE\xb5\xca\x96j\xe2a\xd5\xe0\xfa[\xaa\x98\x0f\xab\xa2\x82\x8fFn\xa3\x8a\x81\x8235\x05\xf2AV\x0d\n\x89\xfd\xecu/\x95e\xbf|\xce5\xaeG\x88nF`\xb4%\x13}W\xb4arq\xaa\xf49F\xb4v\xbf%T\xe1\xd8\xf2\xd5\xce\x90Au\xf2\x0d;\xdc\xb9>\x1e\x82\xe8[\x97x^\xcdJ\xc8x0l\xf3f\xf0\x03$o<\x94i\x91I\xee\xd2I\xb6\xb9y\xe5]\x19\x07\xcf\x8d\xf2\x90\xd7\x16\xf4\xa8\xa6_?h\x02\xccr\xfb\xfaZ\xb45\xb4\x0d\x1a\xacIQ&\xdc\xef\x92PE\x92IA\x92\xc5\xe4\xf3\xd9\xd4u\xd6;\x81\xe3u\xe7\xd8e9\x9e<\x11\x02:s\x8eW,\xcf~\xcf\x85cF>\xd3\xcb$\xd2n\xb1z\xf4u\xfaUX\x18V\xad\xd5X~\xefDa\x9a\xde\x84\xd1'\xa7\x92\x1eb\xf8Y\xb8!\x8aZ\xcb\xef-\xaa\xc5ka\x07\xc7c(\xb4\x94\xb3\x8de$\x8e4\x06F\x92\x0f\xa2\x85\x9d\x1e+_\x8b\xc2\x97|$*\x08\xe4LZ\x8d}\xa0G}K>\xed\x1a{ie\xf5\x11\x1aT\\]\xdb\xa2X&\x1f=\x10\x89\xfat\xe9w\xc9\xe7Q\xbbjU>\x93Ooo\x9f\xffk{k\xd5N\x93OW\x87\x07\xd9b#.D\x12SRS\xee\n\xb6\x90\xb3 \xb9\xb9B\xc8\xd0\x9e\xdc \x1e$\x93ps\xf3\xaaa\x8d\x10\xf6D\xe5\xfd\xe6YQ\xcd\x03zt\xfd\xbf\x0e\xbd\x81\xd68<\x14\xe3\xd5hL=wU\x07\x89\xdf{f\xcdx\xbb\xa6\xb5\x89\xcc/\x84\x97E\x93<2\xe9;\xb2\x92\x0c\x91\xe0$\xbb\xc2s(S\xfc\xc2u\xd9\xb5Y\x84\x10y\xf5]\xa9F\xfe\xca\x83i\x91/\x00\x9d\x83\x85i\x9aG\xca\xcf\x0fY\x19NI+\xe1\"\xcdo\xb5#\x81\x91\xa3n\xe2\x16\xdc\xa7\x0c\x0d*w\x94\xa1\xe7C\xe2\xe6<~b\xc8\xdb\xea\xa7G\xf0h0x\xce4\x1f\x0c\xceA\xe34\xc8rq\"\x88\n\xcc\x94\x8biRX\x0f\xf9\x1c\xdc\xb3\x8b\xbdg\x97\xd6\xc5\x8e\xeeI\xb0j\x9b{6I\xae\x0d\xc1\x14\x98\xc2\x05\xc2>\x14\xc14\x91Z\xc1\x8c\x86\x13\xaf\xcaoT\xb07\x8c],z\xaf\xf2\xe9?a\xec\xf5\xd2\x98\x16E\x01\xbe\xff\xc2\xce\x15\x01\xeb\x81`G{\x05\x87\x83h=u#e\xee\x8b\x97\xdf{\xae3\xcd\x8bq\x18\xcd\x9dA\xa8\xa8O\xe3\xf5\xd9\xaeY\x10\xf1\xcc\xe2\x06r\xf7\xb5.)\x10\x82\x88W\xaa\x18\xd7\x1dL\x8c#R\xc3\xf8$+T\xcfL\x8d3\xdb\xbaC\xfe\x01\x9e6\\\xe5n4\x84\xban)\x9c\xc3r\x97\xb1D\xb0/\x0c\xc2\xcb\xc6\xd1\xf5T\x04\x8c\x94\x8c\x0dFO[\xa1I\x13\xe7\x0b6\xd0n\x08\x93\xc3J\x7f\xd3\x89\x1c\x11\x93KI#2\x04\x97\x92v\xebx\x9e\xcf\x0d\xe1\x1b\xa3\x82Z\x91\xc6\xe0\xc6\xb0\x19\x96%kgP\xc5\x9fI\xfbs\x1d\xa2G\x8fK\x0c%\xdb\xfen\xee\x96\xac[ld\xb5x\xf6\xab\x17\xcc\x86\xf2\x83b\xa9|\xdd\xef@u\x0di^\x15\x945\xf1@\x06\xe6\xc5I\x1b\x8b\xf3LY\x1c\x86\xceh\xa5\xec\x03#H\xc4=\x88\xf8\x8e\x16\xe8\xcd\xef\x19\xb7qS\x1a\xe5\x1fqA\xd3\xba\x0f\xca\x17\x0d\x18$ \x945 \xac\x0c\x80P\xb6\x00\x01},\x98\x16\x1d\x05\xd3\x86%G\x9bd\xc3J7A\xc1\xa0\x01\xa4\x82B\xa9\xafv*V;\xf5D\x0c\xbd\xe8~(\xa9\xc6\x12\xadp\xb9\x02I<5_\x01={f2\x18\xcb\\\x8b\xb0rwW\x17nrt\xb7\xfbB\xc7M\xdc\xa7D[R\xa9\xaa\xbd\xb8TS\x82\xd5\x87\x88\xbe\x05\x97&\xb8\x8e}\x98\xfb\xb0\xf6a\xe1\xc3\x0c\xf6`\xa9\xaa\x89\xdbhU);n}dD\xa5Y\x94w\x87\xc2\x06\xde\x11\x06\xd9Oa\x04:\xbae\xcf\x0d\x92\xe0\xcd \xb6q\xc6\xb3\x1e\xe3\x8e\x84r8i\x99v\xb0\x1a\x13wf\xd4\x19E\xba3\xe6\xa6\x072F\xef\x1b\x88\xe1\x0fp\xf3\x06n67\xcd\xd46\xab\xd1]\x08G\xacwn\xe8\xce\x91T\xbd\xb9\xf2\xf0\x8em.\xee\xd8\xee\\L\xf3P\x06\x81\xb7_\x0b\x1e\x0b\xb2\xba\x9a]4!\x1a\xcd\x7f\xcd}\\\xc3\x1eTq'\xde\xc0\x066\xb9F\x8e\xc3\xf5\xbc \xce3b\xb8\x14\x06\xb5\xb3\xb9\xbb\xf6\xe1\xce\x879\xb7\xc5\xe3w\xc4\x03\xba\xf6\xd5\x0b~<\x1f\x1f\xfc\x99\xc7j\xa5\xc1\xf9\xf8\xf2\xc3\xf9)\xec\x89\xdd\xf6\x8d\xe7\xb3\xd5'u\x11\x1c\x8d\xdf\x1e|xw \xfd\xfe\xa9ww^\xf5\xf8\x9d~)\xfcL\xbf\x12\xff_\xdf\xdb\xdf\xb4BR<\xb7\xdcm\xec\xe8\xdb<1\\\xf1\xdc\xdf\x94\xd1rH\x85Fm\x8aD1pD\xee\xc5\x0d\xb1\x18\xddd\x83\x00\xad6a&\x1f\xec\x96\xd6+W\xa8\x869O_\xeaGCU\xcchc]}\xb5-\xdc\x0e\xa7}\xd9\x7f\xdep\x05\xa7\x07\x82\xc9\x8cxp\xf8\xda \xb39FQ\xde\xe2(\x10\xa6I\x16\xa6ig\xd7:;\x0eP\xb9&\xeb\xcf\x08r\xa4Q\x9a\x97b\x00\x9d\x05\x9aF\xe6\xdcu\xc5\xe0\n\x86\x0c\x0e\xba\xe6\xde\x93\xa8\x15{\x1a@\xba\xd2\xb0\xd9)\x81d-\xb0\x11s\x03a\xdbu\x8b|V\xed\xab\x05\x90\xd8\x81\xfb\x83GM?\xae\xff\x93U\xbcNh\xe7u*\xcffA$\xa0\xf8\x80\xbaa\xa7+\n\xae\x01\xd6\xa3T\xc5\x88,\xe7\xc9\xdfV9}\xd3\xe1\x8b\x83=7\x05 ?\xd9\xb3\xf0\xd6^\x0di-\\,\x1f\xa5\xb1\xd7C\x1a\xfb\xb7\xcfO_>Fk/:\x14\x0d\xa1j-}\x94i|\xd1\xa3b\xc8\xdb\x9a}k[\x83t\xd8\xa2<\xa3I\xb6j\xdf\x0c\x81\x95\xc5\xe3|0j\xf6\xbb l2\xfcX\xaen\xf8\xb5\xb5\xbb\xf2!\xf4\xe4e>\xe3@\x19+\xbc\xa9#:s\xe5b\xaf\xca\xfa\xf7Y\xc9v\xe50\xd2C\x0c<\x92\xbaH\x83\xea2\xfa\xa67\x851\x0b\x852\xb5\xd9@\xaf\xcd\\\x96\"\xbf\xce@ [\x92\x96FId\xb8\xb5\x9d\xa2p\xa1\x99\xb6l\xa3\xabvx>\xf6\xd0|yp\x93\x17t\x04N\xc8\xfe\x1b\xd0\x1f\xcb\x92%\x0b\x0c\xe11\xce\xe2\x11\x94\xae\x13\xca\x04\x92\xc5\\\xff\xb9\x99\xd4]\xcb1%<\"H\xb3\xaeD&\xeb5\xd6\x1f\xba\xeb\xbd\xa0!\x1b\x89Zg\xc9\x92\xf4\xfax\xa2\xb1\xae\x1f\xd3U1\x02\xe7&]\xe9&\xed\"\xc3a\x98\xbdO\xc3\xbb\x118Q\x98-\xd3\xf0\xae3\xdb\xe5\xbc\xc8W\xb3y\x9d\x9b\xf2\x04K\xa1y\x98\xcd\x08\xcb\x8c?,\x99RT\x01w\"\x8c e\xce\x92/\x96y\x99T\x0b\xe6Du\x82uu\x94Bb\x1e\xd5b\x1dS\xa6\x14\xfc\xb0\x8cQ&\xa0\x96\\a\x9a\xadhF\xc9gzB\xb2\x15\x16\xc2\xb7\x05\xc9V\xb6\xecK\x9c\xf8|i\x9b\xf5\x15v{e\xe9\xa9\x12\x1ek\x04N|\x93v\xcc\xe1Q\x11\xceX\xa6\"\x9c\xd93\xf0\xd9ey\xac\xd3\xca\xb3QRT\x19)\xb1\x80\x16f\xfd\x9cP\x99\xf3sb\x1bG\x11\xce0\xc0\xa3\xc8\x99\xb2\xdf\xf6\xacg\xeb\xaa\xf5|\xdd\xd5\xb8\\w\x96\xb3c\xc1\x8f\x8a|\x89\xb9\xf2\xa5%\xc3\x8ao\xd7\n\x9ec\x91\xd0\x05\xd7\xe3\xc5\x92&\x84\xcd'\xe1\xbf,\xd9\xb2\xa8\xb8[R\x9eQ\xfe\xb6e\x8dE\xb6\xd8\x9a\xa5(r67\x84\xfd7gy\x9bG\xabr\x04\xce\x94\xfd7g9\xce\x96\x08x<\x02\x981\xcb\x9f\xc9\xddQ~\x9b\x8d\xc0\xf9D\xee\xe2\xfc\xd6\x82\xca\xfeL\xee\xde\x17\xa4,y\xbe%\xfbi\xcd\xf8a\xc9s\xad,\xab\xf0\x0e-\x93\x19\x0f2\x92f\xca\x8cs\xe9\xca|Bh\x18\xab\x05\x16\"\xc1^H\xc2\x0c\xcb\xdf\x013U\xe0\xb8\x118\x0b\xf6\xdb>\x07U\x108\x99\x95qW\x1dY\xcfp\xee1gn\x9b~\x9e\x91\xef\x03\x9e\xd3\xba\x11D\x988\x99\xd16\xbb\xef\xc3\x121\xdd\x92\xfd\xb7eY\x95<\xcb\xaa\xb4e\xe1G\x89\xfd\x1ca\x19\x92l&\xf2$\x99\x05\x19\xbd/\xf2\x99\x80\x9b\xa5\xf8i\xcex\x1eRRm\xcb\"\xa4\xa4kKr \xdb\x08\x9c\x12\x7fX2\x11\xf2 \xb7Y\x89?\xec\x99\xf80J\xfe\xcb\x96-\xe5\x91=\xab.\x962\xa5\xb3\x9f4LS\xde\x07\xfe\xcb\x92mU. b\xec\x92\xff2g\xbb$\x9f\xa9\xdc\xd1T\xfe\xb6dM\x16\xa4:\xf3h\xb2 ]\x87\xdde\xbe\x8a\xe6\x87a\x16\x116\xa5\x94\xbdE\xf8\xd6\x91\x9d\x1f0\x98\xd7\xde_\xf6U\xec\x17\xcci\xdf/\x98U\xeeX\xcc\xdb\xb1e\xf1\xda/Q\xa9>Z\xa5\xd4d_3\xcdX\xd1\xcfy\xbaZ\xd4P\xb7\xc6\xd7\xae\xf5\xfc%L(\x87\x96[\xfe\xcb\x92mNp*o\xd9\x7f\xcd\x04\xb4Y`\xcex(\x1e\x85\xa6\n\xa2w|\xe4\xc0\xa6\x90\x18\xb9\x8d8\x04^P\xa6ID\xdc\xa7^\x93\x1dX\xa3j\xdb?\xbe\xa2VE\x93\x94>'2\xd2Z\x1d\xa4\xb0}\x990 p\xad\xa9\xa2~\xf99:\x8f\xf9)\xcc\xe2\x94\\\xe6\xcbwdMRw\x1d\xcc\x1b \x9e\x0f\xeb\xa0]=\xec\xf5{ll\x8e\xa2$t\x9ca@\xcc\xbe\xae\x19\xdb{\xf2\xc4\x98\x1e\xd4\xd5\xb6\\\x01j\xb3X\xb6\x9b7\xb5.5\x88\xdc\x0dc?\xbe|\x01\xe3\x87\xa0\xaa\xdf\xed\x0e1\x97b\x81\xcb|\x80S\xd1\x86\xa4\x98\xfa\xd0\xed;O>b\x00=j}\x95\x16\xde\\D\"\x99\xcc\xaf`\x0f\x96\x9b\x9b>D\x13\xf6&\x82\xfcV\xaf\xed\xe5\xe6\x11 `\x0f\x92V\xc0\xc6#\xc20%\xc9\xa2\x84\x94\x13r\xd50f\xcb\x87\x08\xb3P\xcb\x9d\xed\x1c\xabu[\xa1\xc7\x99\\\x89X2+\x1e\xa7\xd8\x91{\x9d\xcb\x86Wht/v\xbd\x07\xfbfp\xa2E\xb8\xfcqu\xc3\xd6\x11?(\xb5\xf8\x12e\x08\xb3\x9d\xd4\xe5G\xfd7\xd5\xa8\xd4 \xaa}@%Gg'H~\\\x88\xf3\x96W\xe4TGqc\x02\xe4\xa1\x0c\x1b;\x9d}\x16\x01o\x95\xf6\xaa\xea\xeb:\xee\xd9cC\x0d\xc6\xc2\xbf\x1c\x9f\x1e\x9d\xfdr\xfd\xd3\xc1\xe9\xd1\xbb\xb1\x1c\x0bR\xd4r(x\x86p\xbe\xbb\x1e\x9d\x9b\xba\x92\xde\x16\xa3s\xef1\xbc\xb7\xa2dUEf\xc1}\x96\xf2\xd8\x17_\n\x01 \xf3\x04\x90`uI\xe6\x08\x15\xd7\xc1\x93\xd5\xecO\x92\xf5\xf5\xa8U\x81\xec\x10\x96G\x1a\x97u\xca\x87\"\x10\x1f\x85N\n\xbeck\x98\xc0\xba\x1d\x9b\xf7\xd6\xb0\xb6W>\xc4\x93\xd5\x15\xef.n\xc7\xbdVHy\xe8;.\xf4Z\xfb\x03\xd5\x80b\x867\xa8\x9f-\x85bK7\x1aK\xfd8\xfdhB\xcf\x90\x8e\x88\xc86<4\xe9\xfbpF\xfe\xf2k\xcfA\x86\xb7\x17\xfa\xad\x1e+\xdd\xe9Kz-\x9c\x86\x9a\n\xba\x0e\xa2\x19\xfcm\xd2\xe3\x92\xf7$\xaa\xd3\x06UQ\xa0k|$+W\x85\xc0`?\x87\xe9\x8a\x9c\xe4YB\xf3\x02 \xba\xdeq*\xae.\x90T\xc0K\xdcu`\x984\x97\xed\x80\x0d\xcc\xb41\xed:|\xd8$\xac\x82\x82L\x0bR\xce\x95~\x95\x96\xfb@\xd3R/\xf8\x18\x94\xd2\xe8\xebzZ\x87\xecR\x1fm?To_-\x06\x08\x83<\x904\xc5\xd4Ur\xa5\xd1P\xb4\xe6\x94k\xb4^\x17\xab\x94\x94\xd7\xd7\x0d\xdd\xf0\xeb(\x8c\xe6\x04\x13-\xd7\x8b\x85Bp\\_O\x93,\xc6\xdcv\xaa\xa5\xad\xf7W5-\xc8\x04~\x8d\xb7\xb5\xfb\x06\xa8\xd5\xb1`\xb3\xe0ds3\xbbB\x85\x01\xae*s\x0fO\x83\xbe6\x82(_,\x93\x944\x07a\xbaB'\xa2\xfb\x06\x96\x83M\xa1\xe3hT\x0cQ\xc6)\xecI\xddn\xda\x8e\x04\x84\x13\x98\xfc~\xe3\xf5\x18\x07\xa8\x95\xa2\xae\xfe?\xd0\x07q\xaby[ OY\x92\xc7\xda\xe2\xae\xf3:\x86oD\xa9\xec\xc9\xd4)p\xd1!X\x86\x13!\x07G\xf9\xe0\xbe|\xd1Z\xe5#\xcd\x82if\x88M\xdd\x1a\xad\x0d\x1cB:\xd0\xf2\xa5\xa8a\x99o\x01\xa3\x11\x1a^\x12\xb1\xbe\xea>\xa3\x19Doq\xb5\x81B\xb5\x8c\x16V\xd1\xef\xc3\xa2$\x05\xb0\xe9C\xc3\xb2i\xbeB~\x1f6A7K\xd7\xf6Eq\x15L\xa5\xf1g\xebK\x98b$c\xfc\xff\xe5\xcb\x90]\xdf\x9c\x9d\x1b2\xcd\x0bb4\xf7k\xb9\xb1ZK\xcfx\xbd\x93\x94Hm\x9c\x8eI\xca\x1fs\x92\x82r\x89l|\xee\xc3\x8e\xc9\xf5!C+F\x13R\"\xd9K\x93C\xc4if4/\x0dS:\x82\xa4\x9e\xf2\xd6\xb6\xbb\xd7\n\x84SJ\x8a\xff=\x0b\xc0o~\xff\xa7-\x02\xc34\xf7@\x13F\x04\xa0M\x08\"/\xdb$\x18T[z'\xc10q8 \xc5cM\x02\xefA\x9f\xf2\x17\xcb\xd0\x0cJ\x8b\xae` \x8c\x00e\x06\xdc\xe3cs.\x86\x1dy\xf5Y\xd9\xd2\xa0\xe7\x87\xd9\xb0j4\xba\xa4\xda%fU!\xca\xce\x1e\xc3N8g]\x87E\x98\x853R\x8c \xc9\xd6a\x9a\xc4bg0\"\xc5\xb4'\xa0\x8d\xbd\xe9\x95:*=\x84\x13\xe6\xbe\xef:\xc5I\xd9Z(}\"\xdc\xeee\xf2\xfe\x17\xcc\xe5\xeec\xcc\xe5\x8cP\xde\xbb\x01jo\xc2\xcb\xc1\x9e\xdeB\x0d\xef\x15\xe1\xe9\xb6\xfa1!W\xda\x1e\xfd\xea\xdf\xdf\xf3{\xbf\xbb\x93\xce\xbd\xbb\xe6nC\nn1hq\xd6\x8e\x16\xc0\xc12/O\xc2\xcf\xed\xaf+\xf9\xb5\xfd\xa9\xc4OIy\x9c\xbd\x0boH\xda>x\x94\x8f^M\xc7\x9b\xf2\xa5,\xcf\x87l\x11\xd2hN\xe2\x8b(_\x92\xb2\x8e\x0dj\xfc\xbc\xb5\xe5\xb7*C>\x05{\x8bf\xf5x4)\x9d\x10\xa2\x14F\\\xed\xbe\xe1\xa3\x82\x1f 4z\x9ag\xfdz\xcd\x0fN7\x07\xa1\xca\xaf\xea\xecaq\xcf\xf3 \xdb\xdclCr\x15\x82\xfb\xf53\xe1\xdb\x11\xbd\x04\xb2\x9f[[V\xd2\x99\x0b{\xcc\xbc+\xea\x80\xb5\xbe\xb4u\xabP)\xb7$EP~J\x96\x97\xf9'\x92\xd9\xc3\xef\x80\xa2\x11\x0f\xfb\xdc\xc5\x19_l\xcb\xa4\xc3\x1e\xf7\x0cb\xfd\x9a\xc1\x16\x9ft\xbe\x06+}\xfeK\xff\xe1a\x15^\xdb\xa2`r)\xba\xeb\xfc\xdd\xf1\x8cq\xa5\\%\xb6r\xa7V\xaa\xd4w\xbd\xa8=B\x15\x02\x8f\"\xc1C]\xc7a\xc3\x17\x0d\xf6j\xa3\xa9\xf5\x0f\xd3\xb8m\xc8IL\xa1H\x9d\xc30\xfb=\x85(LSX\x10:\xcfc\xc830b\xd4\x96\xcb\x8d{\xcew+&\xa20S\xd8\xf5\x02)x\xd2no\xd0a\x87\x08\xe0\xe2\xe6M%\xf5^\x1f\xa4\x96\xc5H`\x1f\xb4\xaa\\\xf4:\xaf\xd8\xb1\xdd\x7f`}\x9d1 S\x14\xd5\x15jD8\xcdW\xb8\xc0\xb6y\x1b\xc1!\x8dd\xf2\x97\xedr\xedt\x19\xae\x9c\x87]+\x10\xe1\xc8\x18\xd3^\xdd\x9e\xa1\xe6\x8eJ\xd1?\xc7\xd9\xf4\xfeun\xfcs\xbak\x83\xe4<[\x93\x82\x82p\xfbKsX\x16\xc9\"\xa1\xc9\x9ap\xefON\xdf.\xd3\xd6\xb9\xe9\x0c\xec\xfb\x9d\xfb\xfa\xe5\xd0\xadpd\xd4w\xdd'\xb8\xf0\xf4\xf5B\xd7\x1f\x0dE\xfa\xae\xe7:\xc7\xe3\xeb\xf7\xe7g\x97gz\xd0\xd1U+jA\xe3s\xd9%\xc8\x02)\xcc\x12\x8e\x99\xdc\xdd\xef_x\xae\x93L\x8bpA\xf4\x86\xe4S\xe0\x05\xa0\xcdS+\x8f\xc2\x12\xa0I\x10#7\x97ix\x07{\xe0dyF\x1c\x1f\xa3R\xecx\x0d;\x17\xee\xa4\xb0,\"\x96\xed\xaf\xe1:\xe4VE#\xc7\xe7\xa4(\x0dP\xe3/\xa3\xbf$Y\x9c\xdfV\x08\xc3\x0b\xf2%\xc9\\\x1e*\xa0H(q\x9d\x1fx\xd1?T\xc2\xec\xb7{\x1c\xbf\xfe\xf0q[|r0?\x1a\xbc\xba\xc2\x95\x14 \xde\xbe\x81bk\xeb\x8d\x07\"<\x8b\x12oe\x92L\x8a+\xc3\x8d\xa4\x00\xcc\xd2\xd5\x0e\xc4\xaecE\xa0\x1eP\xa3\xb6Zi-#\x02\x16\xa2v\xe9.Kq\x8e\xcf\x8f\x17N\x91\xa0\x03t\x1f\x9a\x9f\x85\x93\xd3I\x88n,\xd1\xfe\x04=\x9fka\xd4\xa5\xe3h7\xfb\xff^D\xfa\x17O=\xd7\xf9D\xeeJs`\xdf\xdd\xdd\xfe83\x96\x8e\x17\x82\x86w\xf1\x07w(\xf9\xe0~>5\xd9$\x17\x13\x871\x11\x05\xd9\xfaky]\xce\xc3\x82\xc4\xd7\xd7\x8el\xd4\xfc\x0d\xef\xfb\x1f8\xa2\\\x8e(\xe7#\xfa\xc7\xd7\xbe\xf1\xd8\x10\xab\xa38\xd2\xf7\x9b\xd7\x90~R\xbe\x97 |6\xf5M\x04\x99O\xf3wy\x14\xa6\x84\x9f#\xbe\xe4\x9e'\xb0u\x82~\x07\xd1\xa1\xacsVG]B\xbb\xb2\x02\xcd\"-T\x18;\\\xc34%8be\xe9F\xc2\x12\x19\x1e\x008\xde5#8773\xd8\x84\xc2\xab\x18\x13F\xc4\xf7\x9dl\xd6\xbd\xf0\xd2\xe2\xea\xf7\xd9\xffx\xb6\xf7y\x0f\xa9\xf4\xe2\xe5C{\xfb\xa8\xa4\xd2\xee\xeeK/\x98\x9a\x899\x93\x07\x17\x13\x9e\xea\x1b\x87\xf9\xbe\x07\x95a6r$V3!='5A\xeeC\"\x03\x84\xa2\x03\xb6\xf6foz\xa25\xdd\xecH\x87\xc6\xcd\x8d~\xcf\xb9\xea\xf5\x80\xf3t\xd74\x03\x18{\xbdw-\x19#b\xcf\x04\n\xcem3X(\x03_\xf2\x18B\x82\xa7!\x0d\xdf\x11\xc6XI\xa0\x13L\x8c\xa5\xf9\xf2Eu\xd4\x9e\x19$a?\x86\xb1\x8cW\x04\n9ju\xcf\xc7=)g\x95\xec]}\xaa\xcb3\x11\xd5J\xa0\xd1*\x11e\x13\xe8\x8eVc\x1d\xbf\x81uy\xfa\xbdY\xd4\xf0\xbdM\xce\xd9\x07\xbe F\xefd\xc8\xbf5W|k\xfc\x9b\x03\x9b\x90\xa1\xbf\xdb8'e\xf6{\na\x14\x91%\x85\x82\xcc\xc8\xe7\x96\xd3[\x01\x11\x02\xa9~\xdb\xa6f[\x14\xa5\xc5\xfd\x9b\xd3x\xc6\xc3\x1el\x07\xdb\x9aH\xc9x\xe2:\xdb\xc1\xb6\x03\x13r\xe5jnu\xaa\xa3\xd6(\x80\xef=\xbe\xe9\xa4\xb8\xe2\xf6\xb8\xb0am\x03z\x8et\xd3\xfcn\xdc3\xe0\x11\xc5\x8d\x8c\xb4\xfd\x90\xec=L(\xb27F\xac\xda2Q\x16\xa2\xad\xd6 \xc9M\xa0\x9f\xefx\xc1\xf4\xa1k\x9b\x07\xfc\xcc\xe7\xec\xa9|\xe1\x81\xa1\xfe\xf1\x15\x83.\xd4\x19\xfe\xa1Gtq\xae\x91\xc4!xAs@\xdd\x1d\xd4\x97'\x90d\x1c\x93\xac0f\x95 c\x0b|\x1c\x06\xd3\xd65I\x1f\xac\xb7\x97DH\x8cf\x84*\xfc0\xef\xb6\xd9\x8d\x07\x0fXz\x7fT\xdf\xa1\xcd\xb5\xfd\xddFs\x90\xdf\xc1\x1fc\xc2\x05iI\x9e\xc19\x89VE\x99\xac\x89\x94\xb8\x92\xcf\x94dq\x92\xcdZ\xc5\xc2\x15\x9d\xe7\x05\xfc\x9c\x84\xd1\x9c\x94i\xb8\x86w9-\x17a\x96\xaf\xe1\x87T\xfe|\xf5\xfa\x8f\xb3E\x98\xa4A\x94/\xfe\xd0\xaa#M\"\x92\x95\x04N\x8e/\xb5oz\xd6\xcb9\xe6\x82w\xa2\x84{r|\xe9\xf5\x949\xcc\x97wE2\x9bSp#\x0f\x9e\xee\xec>\xdbz\xba\xb3\xfb\xca\xd8\xe5\x9e\xaa\xde\x93b\x91\x94\x18\x14,)aN\nrs\x07\xb3\"\xcc(\x89}\x98\x16\x84@>\x05\x06_3\xb6L9\x84\xd9\x1d,IQ\xe6\x19\xe474L\xb2$\x9bA\x08Q\xbe\xbc\x83|\xaaW\xcf\xce\x11(\xf3)\xbd\x0d\x0b\x02a\x16CX\x96y\x94\x84\x94\xc4\x95\x1e/Zf\xc04II .\x9d\x13p.D \xc7\xc36c\x12\xa6\x90d\xed\xca \xc8\x9cp\x9b\xd0y\xbeb(\x9d\x83M\x92g\xbe\xf0s\xcdz(?\xa7\xc9\"\x11\x0d\xb2\xe28\x8b%\xd0\\\xaf{U\x12\x1f\x07\xe5\xc3\"\x8f\x93)\xfbOp\x0e\x96\xab\x9b4)\xe7>\xc4 k\xe9fE\x89\x0f%K\xc4\x05\xf4\xd9(\xb7\xf3\x02J\x92\xa6\xac\x86\x84\x94\xc6\x89\xa9\xfb\x8eE\xf0\n\x80-\x06\x15\xd3\xcbz\x05\xb7\xf3|\xd1\x1cgR\xc2tUdI9'X&\xce\xa1\xcc}\xbd\xfarU\xdd+\xb0\xd2\xd3>\x1a\x1f\x81sp\x01\xc7\x17\x8e\x0f\xbf\x1c_\xfet\xf6\xe1\x12~98??8\xbd\xfc\x15\xce\xde\xc2\xc1\xe9\xaf\xf0\xe7\xe3\xd3#\x1f\xc6\x7fy\x7f>\xbe\xb8\x80\xb3s\xbd\xe6\xe3\x93\xf7\xef\x8e\xc7G>\x1c\x9f\x1e\xbe\xfbpt|\xfa'\xf8\xf1\xc3%\x9c\x9e]\xc2\xbb\xe3\x93\xe3\xcb\xf1\x11\\\x9ea\xfb\xa2\xe6\xe3\xf1\x05\xab\xfbd|~\xf8\xd3\xc1\xe9\xe5\xc1\x8f\xc7\xef\x8e/\x7f\xf5\xe1\xed\xf1\xe5\xe9\xf8\xe2B\xaf\xff\xed\xd99\x1c\xc0\xfb\x83\xf3\xcb\xe3\xc3\x0f\xef\x0e\xce\xe1\xfd\x87\xf3\xf7g\x17c88=\x82\xd3\xb3\xd3\xe3\xd3\xb7\xe7\xc7\xa7\x7f\x1a\x9f\x8cO/\x038>\x85\xd33\x18\xff<>\xbd\x84\x8b\x9f\x0e\xde\xbd\xc3\x96\x0f>\\\xfetvn\xea\xfd\xe1\xd9\xfb_\xcf\x8f\xff\xf4\xd3%\xfct\xf6\xeeh|~\x01?\x8e\xe1\xdd\xf1\xc1\x8f\xef\xc6\xbc\xe5\xd3_\xe1\xf0\xdd\xc1\xf1\x89\x0fG\x07'\x07\x7fb}?\x87\xb3\xcb\x9f\xc6\xe7\x98M\xf4\xfd\x97\x9f\xc6,\xa957\xa7pp\n\x07\x87\x97\xc7g\xa7l\xcc\x87g\xa7\x97\xe7\x07\x87\x97>\\\x9e\x9d_V5\xfdr|1\xf6\xe1\xe0\xfc\xf8\x82\xcd\xde\xdb\xf3\xb3\x13\x1f\xd8R\x9c\xbdeY\x8eO\xdb\x9d>=\x1d\xf3J\xd9\xaa5\x17\xf7\xec\x1c\xdf?\\\x8c\xeb\x9e\x1e\x8d\x0f\xde\x1d\x9f\xfe\xe9\x82uH\xcd\xacC\xcdv\xe3]\x9e%`!\xf7\xa5\xf4\x02\x92\x8c\xc1g\xc4\xe3\xfc\x8a\xf3\xb5J9\x12\x97$\x8d\xc4s2\x1b\x7fn:\xf1S\xe2oAS\xc7\xdd\xd88\xea\x874Z\xb6q\x10R&AE\x04\xaa}\xf9\xab\x0e\xca\x00#dI\xa8\x12\xa6\xc1XU\xa5x\xc26<\x1a\xd0\x19\xbc\x92\xf7w\x95M\x89\xa7\xb2U,\xc1E%\xa4\xcbdA\x1a\xd2.k%|\n\x1b\xd5\xf0$\xa3ZVK\x17\xebCF>/I\xc4N\x992\xa1+\xe1\x83e\xd0\x8a\xe4VI\x97\x14\xd3\\_#o|}\xedT\xf7PUh\x99\x96\xb0\xab9ak\xe1\x94\xcbH%\xda\x00\xc1\x10\xe0h\x17\xad\xccd\xd4\xfa:\xd0G\x1d g\xe7\xaa\xd3\x96\xc6R\xefS\xaf%\xab\x9c\xec\x18\xae\x14\xe5M,7\x9e\xec\xce+*\xe4jz\xb5N\x1aZ$\xf3\xeb\xf3\xaa\xbc\x0f\xbb\x06\x9d=k\x14M\xc3\x04\xa0\xf9]%\xe0\xc4\xb7\xa6~\xe0\nidA\xb2~\"w\xa5\xbb24iu\xa1\x0f\nc\x84\x12\x9f\x90\xfb\xa2G\xe1I\xee\xa2gz\x1e\x19$T\xc1\xc2\xd0S\xd2\xe8\xa9\x8c\x9c\xeb\x86\x93\xb2\xba\xf54h6\xaay*\x90%f\xeb\x06\xf5Y\x0b\xa5\xea\xc9\xd0x\x8cm\x03\ntN\xd5\xdd\n\xa8\x8b\xa2\x85G\xaf\xee\x83\xd9~i\x8e\x0c\xa35\xe5\xe2\xba\x97\x8bw\xb3F\xa2\x90\xf9\x8a\xb7\x04-\xd6\xd5\x94\xb6\xf7-\xf5\xf9\xea\xf9\x90[s|E\xdd\x96\x11?\x06\x9a\x13\\\x88O\x86\xd5\xa3\x8d\xd5\xa3m8\xa3ze\xbc\xd7\xbc\xc2f:\x0f,l\xec\xa0!d%\x1bMhA1\xcd\x80\x94\xcf=\x11Oq\x10\xbf|\x1f\xa5K\x9b\x00\xbb\xbd\xf4D\x89\x92\xc4\xd6\xd6b\x94\x88\xcc\xba\x01u\xb4\xd4{qZ'W(\x11n\xe7\xcf\xb8>\xba\x1et\x9a=\xea\x8e\xa7\x86\x1do\x0d7,Q6\x9d\xe4\x96\xbdc\x0c\xb9\x94\x08\xffqO\x9e\x98\xa6\x85\xf1\xf7[\xbb\\\xc6W[\x08M\xf2+6\xbcb\x92_a<\xf7\xc3\xa4\x88ViX\\90\x92\xa9\x04\xb3\xf9\x90 \x97\x0e;\x08P\xe2\xa3!\x00\xaa)\n\xac!\xf6#\xe56ih\x9f(\xcc\xd3D\xda\xd0\xf2\x0bR\x96\xe1LV!\xdf\xf6\xea/C+*i\x18}\x12\xd5\xf0\xdf{2\xd5P\x85\x14\xc57w\x04\x03\xf0 \x06\x922\xde\x06\xe1m\xca\xe4\xad\xf8\xc2-?\x84\x1f_\xe0~\xd5\xf2\xecn\x91\xafJ\xc7\x83Mpp\xfe\x1f\xacP\xf8\xfd+\xf35\xe3\x0bc\xc8#\x96n\xf2|\xcc\xd2\xf5k\x80\x95H\x7f\xed\x99\xcc'K\xbb\xd8\xc9\xa4\x10\x8d\xda8J\x84\xbb\x1d\xae\xf0j\xd0\x9d\xe2zS\xdc\x19? \x0b\xd7{\x03\x9b\x9b\x14~\x80\xcc\xa8S,g\xa2\x1do \xa4\xec\xbc$\xd4-0\xfeW1\xd9\xbd\xb2\xe9\xed\xd6\xbf\x14\xa5'\xde\x07\x86\xac\xfdF\xb2P\x8f\xc2`\x1ceS\x15\x9em\x94f\xe2{\xe9\xf9\xe0\x9c\x84K\x9b\x10x\x90V\xbc\"Un\x85\xd0\x13\x10e\xf1\xea\xf8\xc2\"\xd2|\xd1\x12\x81\n\x88\xda\xd5E\xf4\xa5H\x7fi\x84\xb4\xd4\x0ei\xc2< \x0ei\xc8\xad\x140\x1a\x99\xd1\xca\xaaL\xfe\xce\xf1\x05\xfbaX\xf4\xd4\xb0\xe8\xb9\xdfH\xae\x16=i\xa6\xf3E\x0f\x9b\x89|\xd1W\xcdD\xbe\xe8es\xd1S\xe3\xf2\xa8C\x1e\xacN\xdb\xf0\x9b\xb2\xb5\xcb\x1d\xa7\xd0\xca\x9c\x98\xeb\xdcK\x1f$\x9b\x9b\x19\xfc\x00\xc5\x1b\x0f\xc8$\x87M\xc0\xf81\xed\xb05\x92o\xd3\xe6l08\xbdx\xaa#\x1c\xa1\xf2\xfcZ\x07\x1bcL6\xa3\xaaS\x0b\xda\xba\x84\xc4m\x18\x0c\xd5\xe0\x8a]\xec\xb9\x8a\xb1\x90,@B\\Q\x1e(\xdc\x90\x1b\xb6[E\xc7Z\x8dj\x10\xb8V\xbe\xaf\xba\x03\x1dF\x83\x9a\xf7\xf4\xea\xbe\x8b`>%\x9e\xebkcZ\x83\xf6t'\x9a\x97\x8c\xf6\x14'\x03\x16\x0eq\xd37\xaa\xb6\x08u\xc7A\xab\x99\xb3\xaf<\xe8L\x15E\x15\xd56\xb8\x87\x92\x8dU;\xbd\xd9\x9ey)\x06!\xed\x0e\x1b\xb1z\x95\x9e\xe9\xab\x015\xf2m!e\x90\xbaB\x16\x8e\x08\xffl\xd0 \xcbcry\xb7D\xd2\xc9d\xfe\x88\xf7Af:\x92;\xa4\xc7zH\xa3\x1e\x83\xe9%\xdfW8\xbb\xd5\xd4\xec\xf1\xab&\x19t^\xb0&&\xbf\xe0l\x1e\xdd\x15\xec\xc3*HJ-7\xb2\xd4\x9a\xde{{\xfeAgPv\x9f=\xf7\xaa\xcb\xd5!z7\xafwv^\xee\xbe~\xfd\xf4\xfb\xe7/\x9f\xef\xbc~\xbd\xfbP6\xc5\xe4\xbf\x1d\xe7\xf1\x0f\x8c(\xc7_\xff\x81\xbe\xf1\xb93\x02\x02?\xec)\xa2\xb0\xfek\xb1{\xf5\xa6\x1b1I\xdc\xde\xba\xd4\xed\xe9\xceC\x80\xfb\xe9K\x9d\xc0\x04\x01\xdd\xdf\x08\xc1l\x13\xe4\x8f\x00\xc1\xd5NH\x1a\x10\x8cU\xa3\xb9cDJ\x83\xc5\x9env\xd0\xca\x00\x9d\xf7\xe0 \xe5]u\xeb\x05\xf9\xdb*)H\xe3\xc5uV4I\x1d/`\x03\xb3xb\x01U\xae\xfc\xe5\x8b\xdc\x8e7 \xdeD6^du\xc6zz\x02[}u=\xfbf\\=`3v(W\x99\xaf\xd6[FT\x0c\x04\xb6?\x06_>N\xdc\xfd\xd1\xe4\xffL>^]}\xf7\xc5\x9d8\xbf\xbf\xf2\xdc\xfd\x91\xbb\xbf\xf1q\xd7\x9b\xfc\x9f\x8f\x1f\xaf\xbe|\xfc\x18x\xdf\xed\x7f\xdc\xf5>\xea\x81Yx\x00\x98\x8f\xb7\xdf\xfd{oH\x07\x8b!S\xc3\x8eI\x17\x8bV\x92t\x01\x98F\"k\xc3\xad\xb0\xc7\xc6\x1ed\x08\xd4%R1JB\x158B\xa64\xdc\x0em\xa0F .?\x8f\x05\xc2\xa3\xc8n$\xea\x9b,A\xf9\xf6H\xa4\xd3<\xf7^\x86\x0e\xf7BD\xf7\xa4\x1f\xcd\xf2\"A\x99pm\xd3\xcaE\x17\xf5\xc1\xb9\xbe&\xe5I\x1e\xafR\xe2\xe8\x1a B\x1bAU\x08AC\x9b\x05Y\xe4\xc9\xdfI|\x11.\x96)y[\xe4\x8b\x8bhN\x16\xa1\x90*\xf0\x8f\x87\xa8,\xf8\x97\x93w\xe3\xcf\x98\x8d\xb3\x10\xf8\xf3/\x8bT+\x94dSR(\xefe\xbbfq\x00\x824\x81i\xd4\xac(z(\xec\x98\x89\x1b\x0b\xdd\xcc}\xf1\xfd\x0b\xcf\xb0\x0f\xf0\xd3\x8b\xd7\x9e\x91\x97\n\xed\xeb\x83\xa0\x10\xd4\xf3(T\xf5\xdaXKFF\xd0\xddZ\xfd\xae\xfdk-|\x19\xb6+\xe1\xa2\x99\xe1qm\xa5,\xa7\x95\xc7\x10F\x8bg\xbd&\x8b0I\xef\xd1\xc2\xaa$\xc5\x1f _\x8c \xca\x17\x83\xda\x12\xfdb,(\xd9\xa2\xc9\x828\xc3[t\xe5\xf5\x95\x17\xd0\xfc\xf8\xe2L\xa8\x84\x19\xf8\x02\x83<\x05\xd1\xc4\xf0\xb6\x06\xc5u\xe3\x95^O\xd3<\xa4\x8f\\u\x92Q2{\xf4\x0e\x0bT\xd8G\xff\x83\xb2\xca*\xf6\x94\xb88\x10 \x8dW\xad\xf2\xa5\xdd~\x13\xdc\xdb\xbcLw'\xa4\xcc\x82mt\x17\x9d\x0frr%\x99\xdeyF\xff3 \xc4f4h3a\xf2AO6\xc14/\x16\xa1\x812\x02\x81\x12V\x13\xd4O\xbcv`\x13\xb8\xa9\xcc\xca\x18\xd5S\xc2%\xf6.)\xdf\xae\xb2\xc8s\x13\xc6c%\\O\xda\xf9\x90}\xca\xf2\xdb\x0c\xb5 \x85K\x1b\xec]\xd7\xd4\xa46\\Xa%\xcb\x0d\x93<2[7\x89\x7f\x00\xa4\xa3\x15U\xd6\xfa\x8ep\xf7\n\xf6\x9b\xaf\xa3\x96)\xa8|r\xd3RP\xcbR \x99\xd9\xb1\x14\xca\x97\"P\xe1\x8035V\xb3Vg\xaa9\xef\x1c[\x16\x00m\xce\xb26\x844\x93\xcf\xa2\xe3\xdb\x0c\xc9\xb0\xcf\x0bC\xc0f\xf60\x1c6\xc3;j\xf3\xf7\x1b\xfc\xbe,\xc841x\xb4b\xcfuU\x03F\xab5g\xba\xe5S\x9b\xad\x16\xe6\xef\xe3\x8aG\xb6\x1c\xe0a\xc7\x01\xceN\x90\xd4C\xa8\xfa\x97\x9c\xe2a\xdf)\xee\xb2Y\xbd\xc3K\xff,\xa7\xe1\x8cM\x8e\xc3\xcd\xa5\xdc\x1b\xd8\x87\x1bF\x96\x8f\xd0>\x16u\x01\xee|\xb8\xe6\xde\xd2\x17\x13\xf6\xdd\xf9\xbcH\xb3r\xc4\xce\x8e\x1b\x96 _\xd1_\xc1\xb5\x85\xc0Q\x0f\x05\xc48\x91\x0d\xf9\xb2\xdc\x11\x83\x07\xd8\x03\xfe\xff\xcb\x17\x98qK\x10\x9f\xa7HU\x0d\xe5\x85\xe5\xe1P\x023\x11\xa9>\xae\x88\xbf\xf5$\x93nn\x9b'\x04\x9e\x0d\xd3\x81ns\xe5\x13\xc9\x1d\xc8\xfd\xb6\xb2\xca\x85\xdf^v\"\xe4V\x9d\xa6\xd6\xf94g\xad\xcf\xef\xdd\xba|\xb6\xac\x8b\xfb\x8d\x0bs\xaf\xf6E\xaeV\xa6\x01\xe4\xb6U;\x91M\xfd\x85\x99\xdc\xee!\xa7\x0f\x199\xad\xec\x19\xb4$\x95\x1b\xf0\xc2N\x9d\xb2\xbe]\xe8q\n\x0e9\xde\xd8\xb8\x98\x1c*\x84\xf7\x97/\xb0T?\xd4$7#\xc6-\xd3\xd5h\x87\x95\xe2H\xa2\xfa){(\xde\x03\x06\xb3h\xa9\xd2\xb5l\xf2a\x03\xff\xd4R\xbc\xc3\xba\x90Jc\x9d\xad\xde&;Wv\x96E}\x0ed\xff:\x0fm\xfd9\x93\xa5\x04D\xd91\xbd|\x16\x93j\xd4\x12\x1d\x1e^UG\x16\x92M\x07l\x04\x07\xd04\xb5\x9dN\x0e\x91\xef\xc1\xff\xcdOg,\xfd\x8c%~b\x7fJ\x9c\x8b\xee\x85\xf9\xdaw\x80\xc9\xa7\xd9\xd9=hw\xbe\xe1\xf3H\x9dA\x8d\x18\x94\x03p\x1byx\xba\x05\xce\xd5\x87\xad\xfa{d\x99.\x86\x15h\x82\xc7{Tw\xe5;\x05\xd1\xa8pa\xf0^\xa2[\x8e\x04\xde\xf7L[\x17j\x94\xcc\xa4h\xa8\x0fQ7\xa9\xcd\x118\x07\xd9\x1d\x9d\xa3\x0dT\x98\xc1\x0dAc7\x0bU\x80\xe1Q\x86\x9e\x08zC\xa5\x8doeH\xee\x11\xcf\x99\x018R\xcc\xdc\xb8 \xffSv\xd4W,\x15&\xcd\xd9\xf9\xdbB\xff\xb7lQo9WV\xa2]\xb8Xa\xc6\xe1M\xcc}\xb7\xf6\xfb\xab\x0fcV\xd1X\xef\xfaW\xe3=\xc8\xd4x\x89'\x05\x8e\x11\xff\xda\x84R\x86\x0d\xb3\x86\x9c+\x97x\xc3s3\x93\x19lL\xa24\x94\x81{M~\x0b\x92,\xc6\xc0*\xceG\xaa\x85c\xd3\xaf\xe1\x00\xcda;.\xa5X\x7f\x92\xba?\xd3\xbe\x1b.-\x7f\xda\xaf&Q\xcd][t\xcf\xd5\xf0\xc8\x9aq\x87\x95V\x9ex\x15\x87\x05O[\x84\x9f\xabxrU\xc6Fb\x85\x1b\x95 hw\xc1`\xd7$\x85\"2OCl\xd8YY~?\x8ds\xd5\xd8\xa0\xbb\xe2\xc4Z\xb1\xeaz\xc5\xb0\xd2\x0dGY>d\x01\x06W\x19/\x12\xca\xdd\xdcc\x9a\x12\xac\xa3\x9ayy\xbb\xd8\xf8\xaaMz\x9dG\xac\xfeI\xf3\xfb\xaeV\xbe$z\x0e\xbb\xd4\x03\xa9&\xe5\x06\x9b*\xc6(D\x06\xa8\x10\xbe\xebL\x1e\x152X\xacJ\xca\xd0g\x08<\x1e\xf2\x9a\x88[)\x8b\x1b\x05#\\\x11\x0eo\xf5\xcc6GD\x16 \xed\xb7\x9f\xe7\xfe\x8f|X\xf9P\xfa`\xf0\xc4\xac\x83\xb9\xabm\x03\x0c!'\"\xe5\n+\x1c$\xc4\xd4l\x01~F\x05'\xb7\x9d\xce\xd5\xd2\xda\xe9\xd2\xd0\xceDo\xb1\x9e\xa1\x8b#U^\xe3\xa9\xc6oc^5\x9f|\x03\xcd\xc3F\x1f eZ\xbe.\xbf\xff\x90E\xe1j6\xa7>\xac\xb2rI\xa2d\x9a\x90\xb8\x1a\x1bv-\x00\xf7\xf7\xb0\x89\x0e\xa2\x1d\xcf\xe4.\x84\xb7\x17\x05\"j5\xa7\xde\xa3&\xdak\xcdq\x82^\xa2\xd4\x19\x98\x90+\xbb\x92\x05\xd7\xc2\xc8<\x0f\xca\xdb\x04UXt9\x97i\xca\xa2\xb0$\xb0k\x8e\xf4/\\\xb0\xa2[t3\xd5\x82>\xa4\xdb\x9f\xb0\xd2\xa7\xbd\x95\xfa\xcdu\xba\x7f\x13\xcf\xee\xd9\x84\xfa\xf6\xf4\x9e\x0d\xca\x9b\x7fc\x99UE\xd4\xf7[\xe1\xb1\xfd\x18.\x97\xe9\x9d\xe8\xe0J\xd7{\xad\x84\xf4\xb9k\n\\\x83,\xd4\xfd\x1a\xc4C/\xc5\xeb-n\xda\xe2y\x95^t\xc9C4r\xc7\xe5Pnnz\x90N\xca+\xad\x8bF\xfc\xa3j\x954\xb1L\x18\xc7J\xcc\xd0N\xe5!\xb6\xe3\xc26$oX\xfc\xce\xa4\xb2\xda\x1aYV\xa7^\x17\x96\xecAU\x0d<\x93\x91[5\x02)~cx\xd3u\x94/\x0e\xfa\xff(\\\x1a\xc8.y(\x90\xaf:8\x02\xaaU\x94\x04\x08/\xa5\x9f\xf6\xae\x074\x87$\x8b\n\xc2\x90\x0d\xfa\xb7\x08\x9c\xd6\x92J\xe4\xea\x9b\xe9/\xd9\x7fZ\x84\x11\x1e\x82\x8d\x04\x0cL\xd7u^\xe7h\xe6\x00\x1b`\x15\xb9&<\xfa\x8du5\xd9\xc3\x03\x88d\x12\x83\xee\x83[\xfd\xdec\x8c\x8dyU\xd0\x08[F\xd8J8M\xf0\xad\xeb\xd4\xbf\x13\xfb\xb7\xdaA\x9a\x0e\xe3\xad\xd6F\x07\x81\xad\xed\xd1\xb3\x156:\xc6\\\x15\xe5\x9ci\xeb\x8ax_g\xf4\xd1\x87\x98~\xe6>y\xd2\xb9/\xda]2\xb7f\x05t\x8a\x0e\xc8\x1a#\xd6\x97G8\x02\x90K\xd8\x9eh\xa3\x0d\xb7J+\x19\x8a\xe8\x8dh\xf0#cC\xaa\x0b\x0eF\x9e\xa6\xb0\xf04\x96\x93!\xb3\xa1\x03\x83\xc6\x04N\xd0\x9bjo\xbc\xb1W:\xa9\xf6\xcc\x16\xb4\xf8\x0e1\x13]\xcbh\x03\xeat\x10,\x9b\xc8\xd26\x8d\xc4\xdd\xf1\xea\xdbx\xbfE\xfc\x19(?I\xe3\xc3H\x8b\x16e\xea\xeba\xbe\xca\xba\x05\x02:\xbboS\xae\xa0\xed\x85m\xc3YRy\x94\x14\xd3`q\xa0R\x87+\x96\x16\x9c\xfd\xf8F\xe3F\xec#4\x1c\xe6\x95\xbaJ\xa3T\xbfI\x80n\x0cD5\x0f4\x99\xfbl\xe7{\xcf\x0b.hA\xc2\x85\xa0H\x82s\x12\xc6\"\x02\x1b\xbe\xffR$T\xbcg\xee\xee\xeb\xefQ\x80y\xb4Z\xa6\xe437\x80\xe3)\x97E\x98\x95\xd3\xbcX\xf0\x8aww0\xf5}X\x96\x97\xf3\"_\xcd\xe6<\xf3\x8b\xe7\x83LMz\x1d\x01\xf28_&T,\xdc9>\xdf\xf1l\xf4\x9fA\xd7\x1e481II\x12\xc6|\xa1|\x84\x07\xaa\xe0\xa7PF\x8b\xbbf\xd24\xc9\x92f\xc0E\xdb9\xbd\xd19\x07\xfa#-\x0f\x08o\xd4~\xb6\x93F\xaf\xec\xf9\x04R*\x8c\xe6\xfb\xea\xb3\x16^d\nd\xe0o\xc2\xc8 \x82P\x1f\x1a,\xb9\x93\xc5\xe8fk\x8b\xf1y\x18v\x1d+`3h-k\xbe\x07\x02\xac1\xca\x8bO$>'\x7f[\x91\x92\x96o\x0b\xf4\xe9mJ\x96\x8bDP/\xcdPlO\xd3\xdb\x92\xcfW\xee\x91\xa5\xf5\xedk\xc7\xeeV\xb7\xd3]\x9b\x0fYq\x11\xc6\x06\x0dn\x8a\xfc\xb6\xe4\xd4\xcb\xc4Y\xef\x04\xbb;\x8e\x0f\xec\xc7\xeb\xc0\xb9\xaa]\x81\x04kR\x94I^y\xf9\xf0\xe1{\x8fk\xd2\n{\xda\x04\x87w\x99\xe8KpW\xed\xd3\x0b\x1a\xa2-\xfc\xac\xdd\x9dT\xd8\xad\xbc\xd0\x8e\x954H\xb29)\x12\x81\x15^\xed\x1aX\xaa\xc8h-\x02(|\x12z\xa6#\xdc\xe0\xcf\x06\x99IL\x05\xfe\xd1=\x0e\x80\xd4uvw\x9f\xefJG6\xed,\\u\xebC\x92\xd1W(i\x025`\x8d\xd7R1e\x03\x98\xfb\xa8\xa1\xc5\x1a}iE\x0d\x0b,l\xf983bg\x10\"6\xee\x82\x8a\xa3C\x0420\x84Q\x05e\x1fSU\xf6k \xd5\x11\x99\xf0\x8b\x8e\x93\xd9\x15\xfc\xeaz\x7f\xea/\x10\x19z\xb7\x0f\xbb/`\x04\xbb/\x9e\xbdzn\x99\x85FW\xd0\xaa\xf4\xcb\x17A\x0c\xe7\xb0\x0f9\x8c\xc4\\\xa4\xf5\x87\x94Q$)\x8c \xf2\xcd\x95\xd4\xb1~\xdc\xf6w\xafF\xe6az\x18\xa62,\xa7/\x0f\x02\x12\x1f\x15a\x92\xa9\x89\x1c\xe7i)\xcdr\xfclh\xa6\xc5\xa4\xa4E~'\x12\xcd+\x82\xf1\xf99\x7fE\x82\x98Dy,\xa2\xc9\xd8N\xaaF\x1eVxZ\xb5\x86B\xb2q\x16\xe5\xa2\xb7\xa4\x95\xf6\xe5\x0b8+:}%\xe5I*\x13\x87 l\xc5\xb5\xa1rD\xab\xe4)\xef\xb2HJL\xd8\xfb\x0dn\xe5\xf7\xdcZW+\x9cg\xa8\xff\xd2\xab\xb8\x0b\xedC\xb3\xef\xc4\xe4A\xdc\xaeoU\xec\xd8\xad\x84RpY\xf4]\x16u\xe7\xe3\x81\xe0\xb0\xe3\xd1\x8d\xfd@d\x14c\xff\xa8\xe4C\xb4\xb9%\xb2\x81\x8a\xc6 \x15\x7f \xf7\x1eII\xe6+\xbf\xd9\"X\x1b\xf9\x8a\x871\xf5\x0c\xc4\x87\x99\xa6\xd2\x9f\xad-\xe5x\xf71r\x80[\x9fJn\xeeC\xe1\xf9\xca9\xe5^\x08\xa6\xdco\xad\x03\x97\x9br\xb9\xa8\x14\xa9\x12\xc1\xd8\xf3+,V\x19\xe3\x15\xdc\xdc-\x1e\\\x81\x0f\x17\x1cT\xecZ(\xe89\x8aO\x00es\xd0A\\\xf5+\xf8\xe0\xad\x01\xec\xc1\xd8\xd5YD\xfd \xf1\xcc\x90{\x07\x7f\xb7\xb6 C\xde2\xb9\xa2dX\xea-gB}\x8cfZ\xba\xd78\xcd\xfcj4gsv\xed*\xef\xf6\x91\x1b\xbfXi!\x05\x01\xa8@Y'\n\xf8kl\xfa\xba\xdb\x8d\xfciX\xd2\x1f\xbb2T`\xa6\xd4\x88\x8a\xcem$\xaa\x03\xc2\xae\xb9\x03\x92\xdf\xdai`-\x8d<\xcc\xc8-\x84\xfcf\xb11\x016\xba\xe0\xce\xbc\xad\xb9\xe6s\x930\xd8p\xe7\xfc\x12\xec\x8ew\x00\x8d\xbe\xd9\x8f\x06-\xe05\x1c\xa0\xdeY|\x9f2n\xf6V#\xfaX~N\xa6(\xe1\xa2ok\x0e\x0e7\x08\x9e\x94f}\x0c\xbe\x86\xca\xc5\x87\xc4\xcb\xe2\x8b\xed\"A|^\xeb%\xd7u\xd1\xb5\xbd\xac8\x01\x95\xc22e\xaf\xfej/\x8eg\xb4R\x98\xbf\xef\xc9/\x9e\xe7\xc3T\xb9-\x1e\xb4\xa67M\xa4\xc8E\xe9\xc6k\x03\x15\xec\x19\xfaP\xf6F(_\x05>\xc7\xcb\x03\xe5\\\xc4\xa8+r\xa6\x18\xe6\xa4\xf2$\xe4a\x87\xf9\x17\x97\xb7^\x7fSk\xd9\x1d4\x9ake4\xa6Ad\xd0\x17\xf0Q>\"\x06\xa3<\x83\x9e<\x01\xaa\x10C\xb8\x06-\xe2Hb\xe4\x98\xa59\x06,\xfc\xd5\x15\x07\x84\xc68\x16n\x8d\xbb\x07\x8d\xf3\xd6\xdawj\xa4?\x0c\xb6\x0c\xeb\xca\xb1\xb2\x86:\xcc\xb2\xa0j\xf9PD\xcfo#\xd8\xc9g\x9b\xbf\x8a\xf87b&;\xc1\x91\x8b\xcd\xcd5\xf4\x8a\x0e\x83AtZi@l\xe6\x93(\xa9e\x05\xe6\x0c\x95R\xf4\x8a\xa3\xcd\x92\xcf\x1b:\xfd\xcb\xf1\xc6\x82k=\xa1w \xbc'\xc3\x1c\xbb2\xd0'\xce\x86\x0f+\xd8\xdc3\xc9\xd3\xd8\x93\x07a\x9a\xf2\x83\xa0\xe4^\xd8\xe4\xee\xe3;\xa6\xf2\x92\xe6\x83\xe30\xd2\x82\x1f\x00Mx\xd9\xdc\xc4\xac\x1dG\n'I\x18\xb9b\x11\x0b$\xa2\xaf\x89*\xe7\xf1\xecb\x04qN`?l\xe7L\x1b\xd6\xbb(\x08)&\xee\x94\xc8T\x9c|\x10\xcdW\x99\x85\xd1\x92\x0f\xea\x0b\x05DP\xf6\xddy\xb99r\xbf\x88\x87\xc1}\xb5B\xbb\x88\x99\x1a\xdc\x1c\x8c \xad\x16-\xf5\x19\x036\xd5\xc0\xc1\x0b\xae\n\xb9\xa3\x81S\xdau\xf4\xca\x83\xbd\xa6\xb9\xf9\x1e\xb2\xd4ZW\xa9\x87\x0bhn\xa4Z\xb4\xc8H^\x86\x06fM\x07\x9d\xc2\xa7\\\x8f\xb4\xbc:\x85*\xf1\x96\xb6\x07xx\xf0\xc9\xd5\x1b o<6\x0c\xb4=\x92\xa28\x9c6\xebJk\xe1\xe9\x0c\xc2\xca>A~\xb7\x171\xb3s$e\x1e|p\xf8pZ.\x92\xf4gF\xe8\x08\x0d\xad\x84\xc8\xb5\xdbI\xa3\xfe\xa8\xb7{\xd5\xd4\x1b\xdc\xda\xa8\xcfW\x1f\x1c\x8d\xe9\xe6}\x85\xa4\xacE\xbfBYI\xcbX//\xe3nH\x18\x07\x8e\x0f\xce\xd1\xf8\xfd\xce\xce\xce3\x8b\x8f3ho\xf0*\xb9\xd7\xfd\x99\x85E\x10\xb1\xb4\x9e<\x11\xbf\x82yX\x1e\x0b~\x0bl\xa1C\xa5\x9b\xe8z\x99&\xed\xd2Wh(\x07{\x03s\xfb\x16X\xb8\xf3\x0d=\xeb\x08\xe0\xd5/O\x92Z\x90\x1bsU\xdf\x94\xd4\xfc&\xdb\xed\x9c\xe3\x92\x0e\xa6\x9a\xbc\xa4\xc2\x8f\xce\xfaN\xcb\xaf\x88\x85\xe6\xbd\xe2;y\xce5\"\x9c\xb4\xee\xe5}P\x15G\x97\xc9\x92\xf4a\x07.\x01h\x1e4uP\x90\xc30\xcbr\n\xac\"\x1f\xd8\xafB\xdcp\xea\xac\x88\xd6r[$i\xbf\xa3C\xb2\x9e\x1b\xf0\x1b\x18s\xbb\x8d\xfd\x86\xc1#7\x88\x0b\x85\x8d\\\xa5\xab\xd01:W\xa1_V\xae8\xdd\x02\x17\xb4P'4\xb6\x1fi+$\x0d\x94\xe2\xdc\xed\xaa;L\xf0**Y\x06\xd3\"_\xe8\xf1\xe3\x00DH\x05\xcb\x16D\"\x85\xebWpT\x8dT\x18\xe3\x0b\xf6\xf1U\"@FmsEX\xbc\xe1\xd1$\xd3\xcd\xdak;\x86\xac\xaa}\xe1\xf9\x90\x0b\xb9\xfb\xfe\xb0\xb3[R\x03\n\xc8\xf0\xa5\x0f\xa7\x94\x14@\xb2\xd8\x16d\xd3D\xdd(G\xb4\xc5y\x86\xd8\x8b\x19\x9e\xdc\xab\x16\xe7m\xe7\xd2A\xb9\x9e1Y-\xc9'\xb4\\$\x80B\xdc\xd4\xa4\xf2>\xf7\nN\x1az\x80'\xe1\x1dn\x15>\x11\x98\x1bQ\x0fF'+Q_\xc0\xf1\x8c\xd1\xa3\xb9,A\xb1\xa3\xc989\xd4\xbc\x8er\x0dm\x1eg\xeb0Mb\xc8\xf2l\x8bW\xbb-N\x1a\xe4s\x1c\x0f\x95\xc5\xb9/\x8e\xe6\xbc\x87\xcdy/xJ.\xf9\xd0v\x10\x10\xb9\x069\x97\x99\xf2\x00\xd2n\xde$\xc0B\xc3\xde\xaf\xa4A\xb6\xf5AU\xae\xdek|S\xd5}\x078\xd1o\xf4\x8c\xd7Axw#\x17E\x8b[\x82{Jl_\xda\xe1\xc2G>F\xf2H}\xbeVz\x18\xf6\x8a\n\xee\xb2\xa4\xda\xa0\x8c\x88\xcc\x95\x0d\xcf\x15\x03,\xce#\xcc|\x9e\x94F\x18\xf8\xce\xc2\x18\xb9@>\x95\xd8j\xd3\xaa\x1b\xc9\xeaF\x0b\xb8:8\x12m\xde\x0c\x9a\xcb \xed\xfd\xa6\xeck\xa7\xc3GR-\x18\xc4\xed\xc1\x05\x0c}p\xc3=\xb6\x19\xd8Z\xfb\xfc\xdb\xb8\xe0n`\xc3\x1d7\x02\xc3\xcd\xbb\xfaH\xb1\xc2\x08\xf4P\x84\xda\x83\x07\xce\x08\xb2\x1eY\x85\x90<\x8c \xe9\xce\xc8v:\x8fgo\x07M\x1f-\x86S)\xca1O\xc3\xc8\xc8\xe4\x1b\xf3Z\x85<\x9b{\xd0vs\x06\xb5\xa4G\x95\x94\xacj\xfc\xd1\x89\x9e\xcb.\x8c\xb5\xf2A\xa2\x8cvL\xa0& \xc3\xa0j\x10\xf1\xa4\x11\xee\x1c\x1a77\xbb\xea^eCjo\xf0l\xcdV\xda3 \x1b\x16H\x9e\xbflm\xf9\xca\xad(:\x82\xac\xef\xcb\x14\xa9\x07\xbe\x19o\xcf\xda\x02\x13\xbc=\x93$q'\x11X\x12z\xd4\xba1\xef\xa6\x95\xd0\xd6\xd2\xe2\"O\xb8\x99\xa2\xf9\xbb\xfc\x96\x14\x87a\xc9\x8d,6\xdc\x893'\x9f\x19w$\xee\xdd\xd9\xff-\xfc\x11\x96Q\x92\xb0\x1f7I\x16\x16w\xf8+,\xc9\x8b\xe7\x98+*\x9f\x8a\xff[OE\xb1\xdd\x17\xe8k\x17k\x90\xbf\x8b\xf0VQ3r l\x82\xe3xZ?P\xcf\xa8\xb2\n\xd0Ng\xe9`\xb2\xde\xf3\xe8d\xb2G]W\x83+\x83\xf2\x81I3\xd7\xca&5X\xe6[\x93\xda\x89\x91\x83&U\x9c\x83\x91\x91\xe2F\xae\xba\x97\x93\xee\x18W\xe3\x80h\xef\xdd\xe6\xe8\xbc&\x84]\xdf\x87\xcf\xc8\\\x85J\x15\xd7C\x1e\xe3\xc4\x19\xb1\x96,\x96)Y\x90\x8c\x92\xb8\x87\xb5\xa9/\xe7\xb8h\\\xfdF\xb2x`g\xaa\xbb\x8c!{\xdb\x1a\x90 \xa9\x02\xc2\x055\xe2\xeeW\x11\xbd\xdf\x8b\x99\xa8\xcd\xbf\xa1\xe9$\x83{\xa8\xaf\xee\xa8\xa5\xcc\xabP\xf1MQ\xab\xb0\xc8\xcbc\x8e\xe2p\x87\x16R6\xcb\xd8\xad\x06\xd2\x192S\x80\x07q\xad\x1f\xb4S 7\xfdJX]\xd5\xb9\xaf\xd2\xb2\x19\xbf \xcc\xb3\x88TB\xb7\x0e\xd2\x8d\xd6*G;\xbe\xa2\x9a\xd5\x16Q\x83r\xa8\x14-Fe\xe0\x16\xacT\x97\x8c\xdb\xee^\xdbJY-\xd3\xd5v\xa5\x84\xae#\x14\xd1\x81\xf6\xd8\xda\xdb\xbcl\xf4\xc7\xca\xe7Z\x9aw;\xdb\xc7\xd8\x8d\xf7\xdc\xf9\xf5%\xf7Z\xfe\xd6\xb6\xe9*S\xf3ToZ\xae:O/\xbf\xcb%%Y\xecz>\xd0V\x0c\xf8\xdf\xd5=U\x03\n~\xcf\xa0\xd4}\xb6\xf3\xcac\xc7\xe1\xf1bA\xe2$\xa4\x04\x13w\x87\x85\x0ex\x8c(\x83F\x04\xf2\xbbf\xe7\xbf\xb9\x1b\x99\xfb\xe2\xf5\x8e\xe7z\x95\xdbN\xc6-a\x98\xc8\x17\xafw\xbfa\xa8\xeb\xcam\xfc\xcb\x1ds\xf0\x84\x17\xa6\x88?\x99\xfb\xea\xa9!\x86\x97n]-\x0e\xf6f\xc6\x95)jSWx\xa0R*E\x867\x9a\xff\xc5\xb4\xa1.y\xdf\x05\\W^\x1b\"_u\xa5\x0f\xb51\xa2\x12\x9f!\xb4\x98W6\xcb\xe1\x85@\x86\xc1W\xb9A\xb0W\x9b\xbaF\x9a\x93\x05~F\xa0sI\xf4p\x11y\"\xce]\x04\x7f\xd8\x83\x1d\xc6&\xb0\xb4\x914H\x96vN[\x90\xba\xa5\x1by\xde\x1b\xe0a\xee`s\xd3p\x1d\x85z>\xaa\x94\x95rq\xc2T\x1c\x8d\x13z\xe5C\xe1N\xbdz\x8c\x1a\xbf&R\x15w\xc9\xdf\x00\xcd\x0d#\x89\xd6i$\x05\x95Z\x07\x86\x11\xb5&\xd1\x1b1\xd3\x8bHaJ\xc2\xc4nD\n\x8aT\xb8\xf1\xe1+\x97\x12tw\xaa\x06,\x967\xce#\\r\x11\xc0\xe1\x92|\xa6\xa7yL\\\xc7\xe9p\x1cn\xd0\x00QT\xaf\x06\xdc\xaf \x83\xd3\xc1\xe6{\xf2\x80\xe7\x97\xeb\xdc=\x16\xb5\x9d\xdfC\xfc_f\xfd\xfe/\xb11\xe3W\xb3D\x05\xad\xd6\x9a\xe4\x94E\x8e[;Z\"B\xf3\xa3\xca\x8f'8\xd1c\xd0\xc8\x077l\x1e\xc4!\xe5\xe1|\xf6`s3\x81\xff\x80\xa7\\\xdd\x01k\x0b\xcay2\xa5.z\xa1\x10\xe2\x17ix-(\\6\x82 \xad\x96qH\xc9\xbb\xf0\x8e\xcd\xf3\x00*\xd7@\xb2cD\x0f\x83\x80u\x19\xde\xa5y\x18w\x84\xfb\xa9;\xf06I)\xe9>\xe5{:`\x10\xc9\x0e\xeb@9\xcfo\xfb\xc9C\xc6\xa0\xb6|B\xf5\xf8>\xe7\xc1\xb4\x94\x04#UE*\x17\xb0\xba\xfby\x06\xc5\xb6\xe1\xae:\x86ke\x1b\xb3\xd9\xc8\x14\xbf\x8e=l\x16\xb2\x91\xe1.\xc5f]\x88s\x17\xcd\xc3lF\x84UW\xff\x0c\xdes\xfe\xda\xbe\xe3\x1d\xe7\x11\xa70|\xe4)\\\xe41\xb9\xd7\x0c\x9a\xb8/c\xd0\xae\xf6\x06vR\xdc\xb1\xd7|\xf7\\\xf37\xa7\xcd\x9f\xb5\x91\x81Vr\x8a\x1b\xcfi\xb3p:Z\xd1\xca\xb1\xc1:m~\xae\xc2J2;\x83+\xee\xa2\xf2\xbf\x1ea\xe2\xf5mH\xc9\x8fd\x9a\x17d\xfc\x99D+\x14l\xd2 \n3\xf1\x8a~.y\"k\x0cOR%m\x1e\x96?\xe5\xe2\x12\xa6\xfa\xfeKB\xe7'\x84\xf2Y[\x86E\xb8 \x94\x14\xe6\xd4\xe3,JW%\xab\x94P\x9ad\xb3\xb7ya.\xf6\xe3\xddqL2\x9a\xd0;\xfc\x1e\xa6i~{Y\xdc\x1d\xd3\xb3\x15\x95\x85\x16\xec\xa8\xafn\x0ddj\xa1\xbf\x96\xcb<+\x89\xb9P\xa9\x16)\x1b\x05\xf8\x1b\x0dg3\x12\x9f\xc9\xb1\x96\xcd\xa1\x97\xac\xbb\x97\xe1\xac\xca{Dh\x98\xa4\xd5\xab)\xfby\x9e\xd3c\xaet\x87r)\xca\xa3Z\x88\xf6\xe6rzo\xc2\x92\xbc\x0f\xd1\xacO\x00@Rw`\x9ad\xf1Q\x95\xc6+!\xd1\xaaH\xe8\xdd\x91\x96U\xa6\xf3i.\xf2x\x15\x89\xa6\xa2<+W\xb2\xdd\xbc9\xc2eH\xe7\xb2\xfcb\xcd\xfd!I\xe3g\xfcM>SRdaz\x94G<_\x92M\xf9^M\xca\xb3\x83\x8bg\xbc\xec\x92D\xd5\x8f\xff,9\xa8\x9c\x932O\xd7$\xbeX\xdd\xd0\x82\x88\xe6Y\x06\xedC+\xbdQS\xf5r\x91\xaf\x8a\xa8\xce|Ay_WE}\x19\x8b,\xaf!>\x82\xa2\x15\x94\xb9\xafLA\xdaQ\xa5'GyA\xd1\x0c\xf1Wt\x87\xf8+\x9aH\xafn\x13cm\xbf\x97\xd0nVa\xb0\x1c\xfd\x08\x17\xecL\x9d\\1\x96bF\xe8q\xe6N\x9c\x05\xa1\xa1\xe3\x83\x83K\xe6T.\x9e5G\xb5\xd4\xf3a\xe2T\xdb\xact\xae<\x1f\x0f\x8d\x12Eh\xffy\xe1\xb9\x93+\xcfC\xc8\xea\xb1\x87\x94\x97\xa0\xc1I\xb8\x0c\x92\xf2$\\\nE%\xec\x93\xeb`\xb0\x06\xaf\xd6\xf4\x16\xc9I&\x12\xb5\xb9A2\x81\xf7\xe4$\\z*9\xea\xab\x98\xe1g\xae\xe0\xd2\x7f\xf7a\x9a\xae\xf7Bj%)\xbf \xb1O\x94\xe7\xf1\x0e+\x93%\xa7\xea]RR\xcf\xf5\xbc\xa0 l\x1f\xb9\x8d\xaet\xdd\xc1\xc8\x08\xa4\xb1\x081A\x959\xd9\x97o\x88\xb8\xaf?/R\x87[5\xd4\x89]r\x19F\x9c\xbbj}\x9b\xe0\x04\x0el\xca\n\xf8r0\xb0j\xce\xbb\xbe\xfc\xffP\xa3\xa87\xa7\xbe<\xe6AX\x8e\xb3\xff\x1a:\x87\xf1\x84|\xf2\x83\xa4d\xffT\x81$ \xca|A\xbe\x11f+\xe0\xd4\x94\x8d\xfbf\xe4\x92\x07\x1d\xba\xf49>\xa5$\xa3,\xc9\x0c\xabz\xc7\x14\x08}\xd3\x9aH6\xd5\xb1K\xbcj\x9f\xf7\xed\xef\xd6~f\x0b\xda&\xd5\xb8\x8b\x92\xfb\"\x8f\x81\x953Tz\"n\xceZ\x1fQ\xa7\xac\xb5\xb5x\\]r+vW\xbb\xd8\n\x1d\x93`1yb]\x8bM\x811\xd2\xcd_Fp\x89\xd1\xf30j\x15\xcb\xe8,V)M\x96aA\xb7\xa7y\xb1\xd8\x8aC\x1a:u\xb6\xbcX\x1c\xb1\x14\xcc\xcapE\x12\xe1q\xb8\xfdy\xeb\xf6\xf6v\x0b\x8b\xac\x8a\x14\xaf\xd7I\xecT~\xda\x8d\x04\xb96U\x06h\x14\n*\x15\xc0\x189\x1aI\x894\xf2\xe5\x9d\x00Z\x1d\xe3\x87\xf5\xe1\xde \x83&dy/\xb0c\xc7\x8a\x9c}\xc3\xa1\xd2\xc6*\xd1\xaa(HF\xdf\x0bR\x84\xd3e'\xcdS\x19A\xc5\xfd^\xbfrY\x99y\x04~1\xf4\xd2k\xd6\xc1\xce\xff\x893#\x14\xe1{\xc5\xff\xe5%\xfe\xe7\x1e\xba\xd8\xaf|\x89D\x0f\xfb9'a,\xf6B4g?\xd0\xcb\xa6\xa3E\xd2\x88z\xc5\xde\x15Wf;\xd7\x00Z\xf7\x9fS\x1e%M\xa5VX\xd1P\x08\xcb/HJ\"\x9a\x17\x9e\x1b\xf5\x05\x82\xac\xb0\"\xee\x8b\xaaBM\x9d\x9fs\x04\x9cHz\x94\x86V\x85\x1e\x15\x9d7Q\xd3d\x8f\xd2\x0c\xab\x8e\xa3\x0cG\xf7\xfc\xef\xeb\x04\xe1\xa35\xc8k\x14\xcdf9\xdd\"qB\xf3\xc2\xd6\x01A\x9e>J\xf3\x7f-\xf3\xac\xa2>8\x18\xe9\xb3\xacm\x86%\x87$\x8dp~\x94\xce\x14\xa2\xbe\x9e\x0e\xf9Vz\xbe\x97\\R\xdbC\xecSh\xccB\xf7\x11\xc5Qr\x8b\xce\x91\xcd\xca\x80\x89\xc3\xe8\x03~M\xa8\xa6d\xdc\x8f1\xce\x05\x8f\xca\x8a \"~b\x19\x9c\x151)H\xccg%X\x90bF\x18\xc3S\xd3\xa9#\xdd\x16K[\xbbx\x08\xb3\xf4mK\xd9\xdd\xd3\xa5\xdf\x00<\xcf\xd7\x97\xbeZ\x87\xf6\xaa7\xde\xe7*\xff7\xa8c\xd3\x96\xbaC\xb3\xc6\xb5\x88#)\xb9K\xf34\xcc\xfd\xee\x0b\x16\xd1\x98n\x0f\x8a0+8\xd8\xfe\x8a\xbb\x86\xf1Wi\xaf#\xc8\xcai\xde\x9e*m\xae\x16|d\x1aG\xfd\x98\xddP\xab6\xac\\\x83\xb57\xb7\xbb\x1e\xd8\xae\xda\xaa\xa8\xb3u,h\xc3\x9f \x84%\xe5\x0c\xe6\x0e,\x06v`{\xbd\xefNv\xb6^_}\xe7}\x0c\xda\xbf\xb6\x93\x80|&\x11#p\xb8\x0b\xb7]\xd3lH\xe9\x87\xb9+\xf1\xc0\xae\x10I\xeb2\x02\xaag\x12\xee\xdaB\x18s\xe3\xb3\xbe\xc6\xf1\x0e\x9a\x07\x0e \xca\xe4\xef\x04~\x80]\xaf\xb9\xfb\x05\x17\xdbf)%\x03\xd7\x93\xad\xb9\xd6\"\n\x1d\xec\x83K\xda!\xe9H\x87\xca]\xdd\xd5\x8d\xaad\xd5Uk\x18bc\x1bV\x83\x1c\x10F\xae\\\xb3\xb6\xf0d0\x15\x97K\xd9\xf0\x9a\xb7\x8f\\W\x1f\xb6\x9a\xbd\x9a\xf2\x0bB\xe7y\xdc\xab\x9f_-\xb7U\xa6.\x9f\x84U\xc6\x18\xfb-\xc6\xd8\x9bU\x07\x80\xc3\x95\xe5J\xdat/\x8f\x87\xf0\xa8\xb9\xda\xfanh\xbc\xdf\xe8r\xc3oCR\xbc\xe1\x0bB=\x974\xd9\xb8\xbe\xe3\xe5Z\x97f>vGd\xd5}\x1d\xb9\x95\xc8\xab\x12\xb2~[O$\xd5)\xeak \x9e\x0c\xc8\xca,\xf8}\xd4n(U\x1b\x89\xfc\x968\xba\x97\xd0\xab]\xbfY)=d\xd3\xeav}\xa0W\xbe\xd031\x82xS\xb0!\x08g[\x15v\xb5\"\xd4 F\x99D\xeb\xa6\xdcoI\xe2\x1fe\x96\xd5.\xda\x85\xa1P\xcd\xb6r3\xf0(\xed\xcb\xfa\x8cK+\xee#\x1e\xa5!V\x97\x99I\xac.@\x1e\xa5\x1dQ\xdd\x006\xa5\xfbf\xc6\xdc\x99;\x1fn|\xb8\xee\xbe\xceku\xac\x11\xd8\xdd\xaa\xc5Qe\xe7\xd7\x8c\xaeSu\xd0\xe9\x9b\x02\xf9\xa0\xd7\xa3\xae\x0c2\xd3FS\x18\xda\xaf\xb5\x06j\x07o\x13:\x97\xaa6\xe5\x80\x91\x19+\xd1p>'Z\xe4\xd0\xab\xf4\xa1#W\x1f\x03b\x17|\x8ekP\x11\xd5\x9f\xaf5\xe3S\x1f\x04\xcd\xdeU\xe9\x8f\xdc;\x83E\xb2\xfe|m\x85\xb6o\xe7\xb0~\xb6\xfbpnt\xca\x80|\xe4c$%\xb4\xbd\xa5\xa1h\xae\x97#\xeeC\x1fe\x8b\xb3\xbaz\x0f\xc7\xc6\xfbg\xd9\x87\xfa\x8a\xb6\xf7\x94\x92S\x82~\x81*\xc4\\]\x02q\xe5\x01W\xd9G\x83\xee\xcf\xa05\x1a\xe5\xc6\xcc\xa0?\xd1\x89\xc6\x9a\x83\xbc\xd0\xd8\x08\xe5z\xda<\xed\xb7>\x8c\xfd\xc1\x13A\x06\xdf{\x81r\xc6+`N\xab\xf3YEl|5\xaflJ\xb7\xf2d\x0e\"\xf4\xab\xcfH\xf8]\xf4\xcc'\xf7\xa2\x10\x02\xe9\xf0\xd0\x07QZ\xfdD\x06\xce\xb2@=\xc6A1\x8c\xbf\xd32\\G\xe8\xd9\x03\xfb\x08C\xfb \xf6\xed\xff\xd5\xea2\xf4^\xcbZuC\xb9w\x94w\x8c\x1d\xfb\x11TPn\xc8\x9fz6\xee!'\xb1\x0d\x8a\x18\x83\x10F\x95i\x10\x9c\xe2x\x0e\xf3l\x9a\xccJ\xb6<\xf6\x85\xc5\xcb,\x06\xb8\x17yAM>\xd0\xe5\xc3\xfd\x10\xd7{\x92\xe7\xef\x04\xf5\x0b\x94O\xe4\x05\xfd\xf1n\xd8\x9a(e\xcd\xee\x00\xba\x02\xd4\xea\x8f\x9c\x0f\xa3\xdej!t\x1fV\xd8?R\x94\xca\x1cL\nK\x14}P\xe9\xeb}\x90]\xe8\xb0\x11\xff\xea5)\xa6>\x0f\x0c\xf2\x9e\xdd\xd8g\xe9\x83\xbc\xee\xb3\xbe\x1a\x93\xbc'^z\x02{8t\x8aU\xb8\x05^\xd0\xf7\x0eV\xc1\xdb\xdd[\xbb>\x96F\xdc\xd9[\xd6\x01z\xa0\x8a\x0e\xca\x11$\xf7F\x04\x86\x9d\xd9\xdc\x82\xbe\xa6\x07e><\x86\xca\x9ck\x192\xaf\xf0~\x17\x1a\x9f\xf0LST\xb4\x1e\xa93\xbc\xbe>&\xa1\xf1~\x80]ik\x90=J\x8f\xb4j\xef\xd5\xb13\x8e#\x9b\xban\xf7\xe0O\x0e\x95\x1b_\x96U\xb2\xc9&\xa8P\xb4\xeb\xee\xd1\xc2\xa7\xc1-\x98\xb4\xfa\xee\xd1\xd0\xc1\xe0\x86\x0c:\x85U;\x1d\x0dh\xc6)M\xbd\x10\xa3\xfa\xe2\x90\xdeK\x04v\xef\xbbw\xa3JW\xf3|5\xa3\x92\xfcA\x8a \x03\x9b\xb4\xcaW\x8a\x81\x9c\xb0\x14E\xe7\xb89\xb2\x06\x9d,\x15\x9c2y\xc9\xe2\xd8\xc6\x08\xe2\xa4\x1eX\x0b\xa6\xcd\xc3r\xce\xc5\xac\xf8\xf30\x8f\x89q@\xa0\xe3y\xc3\xa5\x9aXq\x93\x11\xca\x03Y\x85JQI\xed\xb6Y\xf7NMi\xb7o^\xb7N,\xf3\x9ec\x99\x1ee^\x1d\xda-\xc2y\xe9)+\xab\x16\xc2@\x13\xa9c\x7f8\x98^'\xb2\xa3\x0c\xab\xe6\x0cf7\xf4{\x1f\xe3.\xbe\xffh\xfe\x19\xdb\xf7\x1b\x01\xa5\xb0\x80\xc7P\x90\xb0\xae\xca\x99\x98\x93\xdc0\x95&\xe5\xf0oD\x83\xbc\xd0\xd5c\xa1\xb8\x07T\x97\xd4\x9ah]\xba\xa1\x0d\x04\xd7y1\xa5N\xa4<\xac\x0c\xb8\x02p/Z\xd7\xc1\x8e}\xd0\xf7\x17\xf2i\xcd\x0e'\xfa>W\xf5\x93k\x1d\xff\x07Hj$\xdanH|\x8d:r\x06\x17<\xdc\xcc\xb1V\x1a\xc5\xf8\xcf\xce\xb6\x08K9\xd9Q\x02\x12\xaa\x11\xa2do\xe0\xd2\xde\x9f\xff\x81*\xa9lRz\x95R\x0d\xb3p\xf2\xaf\xd155\\\xa3\xa0\x99\xb2\xf4\xf1\xd2\xb9\xbd\x1f\x88\xd0\x85\xccU(y^y\x9d\xf7A\xb9T7\xe5#\xaa\xe5\xb5;\xbd\x97@x\xff\x83A\xac\x1a\xaa\xa0x\xa7\xd4\\\x8a\xdf\xb5\x7f\xb11\x1e7\xe5p\x95\x05M\x1f\nl\xcc\x8fP\xaa\x0b\x16!\x8d\xe6\xee\xf6\xffq'\xe1\xd6\xdf\xaf\xd8\x9f\x9d\xad\xd7\x9b\x1f\xb7\x82\xab\xef\xbc\xd1\xb6E\x0b\x97\xbb\xa0HJ\x19\x90\x80\xb1\xed\x1c\x92\xb3V\xd0\xc1\xd6)\xcb/P$\x8a\x14\x92\xef\xd6G\xe7Z\xac\x0f\x1f\x9e\xc33\xe6\x9ar^\xc3\xf6\xc1`h\xd47%\xa2s\x13gN\xe9\x12\xd54)]\x96\x8a\xb7\xac\xe3\xaa$\xf7\x90U\xb7\xdce\xf4\xd4)\x0d\xe9\xdd,zd\x8a\xc7\xa1S\xecF\x19-\x8d\x07\xdb\xe6Rp/z\xdf,M\x96\x03\x02\xcfJqj\xe5\xfa\xd1\xa0\x0b\x93\xa9\xeb\xd8\xc65\x7fm\xf7\xc4\x8c\xd6\xf61\xde#W\xf3> \x97\xda\xb6\xf9\xaf\xb7\x8d#\x8a5\x9c\xf8\xddp8\x98\xcf\xd4\xd7\x92p3\xf3\xa6W\xc2\x92\xd0\xd6+\xe7\xc7\xb9E\x12J\x80\xc7\x8b%\xbdC\xfb\x9f\x8az\xc6\xaf\x12N\xf1\x93\xb4\xa8\x92\x89\x9a\x16\xe0a\x18\xcd\xd5:M\x86S\x82O7\x7f\xc2\xb4\x0bi\x9c\xb5\x0c\x8b\x92\\\xe6\x95U\xd5\xc5\xf8\xf2\xfa\xe2\xf0\xa7\xf1I\xc3\x9c\xfa||q\xf6\xee\xe7\xf1\xd1\xf5\xc5\x87\x1f/\xcf\xc7\xc6oj\xda\xd9\xfb\xf1\xf9\xc1\xe5\xf1\xd9\xe9\xf5\xc9\xf8\xf2\xe0\xfa\xe7\x83w\x1fx\x99\xc3w\xe3\x83s\xf6~\x8c\xf9\xde\x1f\x9c\x1f\x9c\\(_\xce\xc7\xff\xbf\x0f\xe3\x8b\xcbF\xca\xc5\xfb\xb3\xd3\x0b^\xfc\xdd\xd9\x9f\x1aYXoO>\\\x1e\\\x8e\x8fZ\xe9\xedw\xa5\"S\x0fD\xdf\xc7'\xef/\x7f\xe5\xe9\xd7\xc7\xa7\x87\xef>\\\x1c\x9f\x9d\xaa\x19\xf0\x93\x9a\xf0\x9f\x17\xcd\x0c\x1f\xce\xdf\xa9\xaf\x17\xef\xc7\x876\x034\xd8\x83\x1b7s\x9f~\xaf\x93\x9d\xb9\xf8\xf2\xea\xb9\xfe%\x91e\x9e\xe9_B\xf1\xe5\xf9S\xfd\xcbJ\x96\xd9i\x15*\xc5\xa7g\xcf^\xe9\x9f\xd2\xea\xd3k\xfdS$\x9b\xfa\xdek\xd0\x8f\x1c&/\xfaT?%\xb6z\xc7\xe8\x8e\x82,\xd30\"\xee\xf6G\xba=\xf3\xc1\x01\xd0\xf1\x96\xcdkc\xad/\xd6Fsh/q\xdd>\x1f+3g\x8d\xaej\x9e\x1c\xcd\xbd\xf5-\xb6\xf9\xa7\x1d]\x18\xe0\x1c\xe0\x03j\xe9?\xb8\xf5\xdbok\x9d\xa1\x85\xde\xc5\xec\xe9\xc2\xf8\xa1]\xe0\x06\xf6\x88\x13\xcd\xbc\xb8! bO_>w\xf4\xc5\xcc\xa9q\x95?\x8b\x86\x9e8P,\xf7?x\xb4\x9f\x86\x0b2\x02K\xf0\xa8%?\n\xac*\x85I\xf9\x97E\xaa[\xfd\x00\x0crL\x80\xf3\xd6)\x89\xb4\x1b\x9b\xfe\x8b\xa6\x0f\x87o\x9d\x1c1\xb9\xddSS\xdcsjR\x12\x16?\xeb\xa7\xed\x83A\xfb\xf8A\xf3q\"\x14D\xdbj\x1c\x03\x96U\x9av\xa1\x91a\x1f)\xdb\xd3\xfd\xbf>\xa8\xfb}\xbb\xc1\xb2\x9c\x9f\xc8\xdd\x08tS\xbd\x87\xcc\x80\xb4\x1d\xfb\x1f:\x03\x1a\x1f{\xcf\x19`\xf0\xab\x10\x96\xdf2\xf6\xcb\xc7\x1d\xbbT{\xbe\x87\x0f\x10eD\x92r\xfe\x96\x01\x9d\xfc\xb7\x18PI\xe8}\xd9[\xdb\x80\x8e\xee= \xce\x9ew \\6^\x0bx\xca\xf1\x1ad\xc3\xb6\xf16\x89\xd9iEd\xbe4\xd9\xa5e\xaen\xd1\x19W\x05Z\xf4\xe5\\|\xda}\xd9\xfa\xb4\x96Ti\x9b\xcc]\x88O/_\xb4\xc8\xdcY\xf5\xa9Ej\xdfI\xc3R\x13\x93{c=\x14dh\x1e\xd51\x04\xe9v\x0ca%w\x1a\xf3xm`\x1e\xd0\x14Q\xfa\x9fA;\xc8\xe6\x18n\xdb\xfcG\xa3\xc8\xaaH\xb5\x12c\x03\x07\xd3(\xc2\x95\xa8\x1be>\x9b\xd8\xa0F!<\xd2\xb5R\x83\xb8\xabF-\x84\xf1\xc9\xbc\xae\xfa\xfaF\xab\xf5\xd0\xc2\xc7\xf1\x8a$\xf3l\xec\xd0'\x13O\xc8\xcb\x95\x84^\xcb\x8bt\xad\xd4\x81\x81\xb3T\x0b!\n\xd3\xca\x9cup\xa9uYq\xe9m\xa9\xe3\xbd\x81\xf3\xe5e\xd3|f)ca\xa0y1D\xb9\xb6Q\x9e\x18\x99\xf1fAS\x8b\xc7\x9d\xec\xbdZ\xbesi\xfe:@\x8a\xd0\x00\x95J\xccz\xbd 4\x14\x87j\xb3\xceS\x8b\xb4\xa2QOm\xde\xda({\xde#\x051\xd6q]r\x81\x8bV\xd7Q\x05\x0c\x95\x80\xc5a\xcb/e\xaa\x8d\xcc\xef\x86\xaa\xb8\xb9;>\xba\xa8\x16R\xc5J\xdc\xa6\x9bH\xab\\zS\xe8\xd3K\xfeV\x19:\xad9\xb8\xc5\xe7\x01\xe6,\xcdGLQe\x937J\x96\x8c\xdc\x99\x10)\x8a\xce\xea\xf8\x95\x9c027g \x85{R\x83\x1c\xd4\x1a\x16\x10\xc3@\xc0\x97/\x90\xb8\x18\xb0\n\xc1\xb6C\x87\xabD\x0bqF\xda\xb1i-\xda$\x1d{\xbez\"h\x91\\\xaa\xa0\x0c\xa7\xe4]\x1e\xc6\xc6h]j4=\xf3T\xf2\xa5a\xf4t\x9e\x8aX\xfb\xe8\xf1-\x0f2r\xcbx\xf6qq\x9fN\x9b\xa7\x8f=)Y\x93t\x042\xa0\x935\xdf\x82\x94e8c\xc4GP\x90\xb0\xcc;\xcc\xe4\xd2$\xc3|\x8b\xb0\xf8\xc4OQ\xf6+`\xc9\xa8\xdb[\xbfmb\xe4 .:\xb3\xcck{\xf2l[\x05\x03\x1d)\xde6\xf7\xc0Uba\x85\xb0\x0f\xce*\xe3\"et\xf2\xc1\xb6VTo\xad\xd0\xe3&\xe0M\xd1\x88\x1bz\xec\xd0\x1fH#}0\xc4\x95\xfb[\xa5\xbf\xa5Hf; a0\xecM\xab\x86d\xe5\x85\xa8\x7f\x7fBus6`\x8f\x82t\x83\xde\xbbO\xa1\xf2\xff2\xed\x00\x8a\x15\xecA\x18L \x8d\xe6\xf6L%f\x12S\xd5\x01`\x98\xed\xe0\xc2\xc0\xe3\xc8'\xaaD\xb2\xb8\xfa)\xec\xc3?\xbe\xc2\x08R{\x91\xa9\xbcT\x14:\xc2f\xb5\xa0\x0fh, 7\xe6mXd\xdc\x91\x84\x98\xa2\xc6:7\xc2tB\x99d\x11\x81\xf5\xb3`w'\xd8\x810\x8b\xe16IS\xb8!P\x90E\xbe&1$\x19\xac\x9f\x07;\xc1\xce\x1bX\x95\x04,r~\x11\xd0s\xc3\xf1|\x0ep\xb6XW\x0c4\x18i>\xedRv\x8e10\xd9\"\x8fI*/ZN\xc2\xa8\xe8\x88*5\xc7\x12\xd5\xcdVO\xee5\xe6\x16C9\xce()\"\xb2\xa4y\x87R\xf5B\x94\xe0\x04\x8cR\xc42\xcaz\x95\xeb8?y\xe5i\xc1\xad\x9dG\xf0\xfb\xf6\xca%x\x1e\xac\x8a\xd4\xaa\xfe\xc5&\x8fq\x15\x11\x83\x88wIFNW\x8b\x1bR\xbc\xcd\x0b\xb4\xcf\xdb\xb7}h\x86\xdd0\x84\xc2\x90\xcf]\xd5\xcd\x0bZ\xd8\\w\xcb\x1b\xb7\x0eT\x8f[\xca\xe8cH>\xac\x8dN3\xe4\x9b\xb0$Gyd\xe5\x1dA\xb8\x00mB\xc8\x08b{\xf6&x\x8c\xa0c\xd3\xb7ac\x04\xeb\xae\xec-\xc0\x18\xc1\xc2\x98\xfd\xab\x17\xd09\xc9\x06\xe8WA\xe3\x8e\x95M\x98\xbd\x03\xec\xe1\xf6\xad\xfc\x1a\xd6\xae*\x9eL\xc1Mz \x0c\xa8$\x02\x0e\xba\xf3\xcf\xcc$\x06\x082\xa3y\xfb\x9f\xe1\x1do\xa6(\xd6t\x0d\x11T\xe5\xbc\x81\xda\x9a\xeac%K\x08?\xcf\xd9\xa4LWi*\xb6\xc8\xcc\xbd\xf3\x95\x14i\x15\xc0\xd2\x96\xdc\xc8\xb5\x91\xbd~ \xfe\x9a'\x99\xeb\x04\x8eZ\x04)\x15FU\xcb\xd8\x93$\xa0\xdcE\x9b\x9c7\x1f\xb5s\x84\x8b iu\xccr\x9a\xef\x93\x89\x0f\x8e kz\xa3?\xcb\xa7\x11\xcf\xaa#\x10\xa8\xfa\x08\xb9! Dc\xbd\x85\x86X\x01\xda\xa1\x8e= #\x13/qV\xc6E\xf1#j\x99\xe4\xdf`9XhWfvS\xaaVr\xcb\xfc`r\xa5\x1dGo\x85>\xda\xa2&\xc6\xd8kZ\xbf\x96\x15Y\xcdh\xc7\nh\x81X\x03\xdfQ5b\xa8\x0f!\x0f\x80\xe2C\xec\xc3\xdc\x87\xb5\x0f\x0b\x1f*k\xdf[\x1f\xc6V\x85\xa1\xba\xed\xdbb\xd0\x86\xc1p\x0bo\xdexP\xde&\x9c\xca\x0f\x96\x05F\xfc\xe2\xc1\xd0\xbb6Z\x14\x96\x04vF\xddk;\xe5\xe7\xd7\xdf\x82\xf2\xae\xa4d1d\xe3\x12\x19\x8c\xf1y7\xdc\xb0\xe7\xa6 a;\x92\x9a\xfa\xd8\xc1\x05lH\xc2\x89\xc9\x8d\x00\x1e\xe9\x05`\x04q\x9e\xfd\x9e\xc2<\\\x13\x08\x81\x0f\x06h.\x0c`\x08\xe4\x99\x0f\xe1M^\xd0$\x9b\x05\xdcaQxS\xac\x96h\xe2\xc1\xda\xb0\x05\x07\x069\x93\xcf\xfbg2\xd3yQ\xc1\xc6\x92\xa2\xa8)d\xc1\xb1N3\x1fi\xe2\xbc\xa2\xf2\xf8P8\xef\x97#E\xaaS\x9e\xa1\xa4\xfc\xade\xee9\x04\x94\xd6\"R\xe8`\xacK\x0dw\xf3\xb6\x87U\x1eb\xe8\xd4\x14\x91\xf0\x12\x91\xf0\xa2\x1fh\xe1\x1bp\xb0\xe9\xf9\x16\xbclz\x86\xe0j\xd3S)\x14\x8au{\xeaw\x99\x1b\x9a\x1el\xf9\xe9\x83[\x0e9\x91K2\xea\x0b\xb6\xbc \xe5*\xa5'\xe1\xd2\x17\xbc5\x83\xf2_\x12:?\xe4\x0e=%\xcaV\xa0\xed\xa5\x0f\x89\x9b\xe2\xf9z\xbfi\x93O\xc5tL9\x1f6\x8c\x96\xd2\x1f\x13[r\xf7\xb0\xaat\x96\xe5\xe6a\xd5\x98\xd8\x19\x83\xa2\xd2\x90\xc7\xc8\xea\xdc\xde\xbb\xaa>bQ\x7f\x10\xbc^>\x18\xbc\"\x05\xbc\x96\x88x9\x9f\xc4\x8f\xba\x88sWP\x04a\x9a\xe2 R\xba\x1e\xf7f\x86\x8c\xcc\x10n\xc9\xf6\x0c\xe4\xa2lO\x9b\xbbZ\"w\xb5\xd4\xcc\x16\\.\xa1\xb8?\xfbdz*l`b\xa0\xe6\xee\xfa\x7f\x1b\x03ez\x1e\xc2T\x99\x9e{3Z\xa6\xa7\x9f\xf92=\xa8Pm`\xba\x16\xd2\xbd\xf6\xac>WW\x885\xe3\xf6\x87\xb4\xfa\xd0\xa2\x83\x1e:\xbd\x15f\xef\x94\x10u=\x96\xa3`\x04\xf6\x08\xf0\xb6\xe7A\x88h\xf7\xfb\xfba\",\xe4\x90,v\xeeW\x0e\xd4\xcdX\xd2|i\xf1\x91cz\xba\xa9g\xf9|\xc5\xe8\xf1&G\xb6\xc6\xdc6\xc9\xa4\xfa\xb4\xae\xf0z|)\xa8O5Xs\xd0\xcf\xde:\xba\x07\xfd\x95Q\xc3\xab\x8an\x13\xb8d\x00bW \xd6\x9d\x9a\x9c\x0d\xbb\x93\xab\xcac\xcfR\x9a\xd0\x074\xff\xcf\x8b!D\x84\x15\x9c\xa7\x8a\xc8X\xd4\xd6=\xc0\xae\xf5\xe1\x90\xdb\xc3~\x8e\x95\x83\x92{-\xafxz\x1f\xaf\x8dx0\x10I&>\xed\x06\x07\xe4\xf1\xfaz\xf4\xba\xbbG5c\xf1\x1aO\x87\x1d\xec!^V\xba\xbb\xbb\x9e\xafK\xfe\x02j\xbb{\x80\x8aL\xed\xa1Sc\xb3\xa1\x83\xcb\xc6>\xae \xd3\xdef\x9e\xd9\x9b\x19\x8a\x11\x86\xec\xfe6\xd0\xab\xbb\xda\x87\x89\xb1\xd4\x841j\xbb\xaf\xafZ\x1f\xaf\xda\x0e2\xe0\xd9\xf7\x0d\x9d{\xab\xb5\xc77^\xec\xffM\xc6\xc1\xf4+\xa8\x03\x0cC\xfaV\xf7LX\xbd}m\xdb\x02\xdc\xd3\x11x\x8fJ\xdcy{\xff~\x8b\x8e\x9fT\xd8l\xaf\x99m\x80\xfe\x10\xdb\x1c+o\xfdO\x1a\xdd\xc4\xe2\xc0F\x0cO\xc5\x83\xf7\x1bi\xcb0\xe9[\xd6\xee\xf0A\xa3\xab\xb4\xa5\xcdC\xe4.\xc1\xef\xbd\x84]\xf6X\xdf\xae'\x7f\xf1\xcf\x18\xe9#\x98\x13\xf0\xb058\xea\x9f\x85\xe9\xc2\xf0iS\xb7v\xd3\xbc\xed\xc1j\xae\x03&\xa5_=\xd7\xfc\xb9`'\xb6\xc9\xcd\x81e\xc9>uAK\xc3\xb8\xef\xbf\xe7h\xffv\xaf\xd1\x1e\xf4\x8c\xb6e\xe0\xf8\xbfa\xd0g]\x83n\x18y\xf6\x1e\x9c\x1d\xe34\x8c\x857\xff\xbe\xab\xf9\x96\xd9io\x17\x86*\xe5\xd9Tn\x8aa*{\xf9P\x95\xbd\x95&\xeb6\xe7\x12\xf1\x06\xc3\xf2YOu)\x12\x96\x0c<\x18\xca3\xe7\xe1r$qW`\xcc1\xc5\x1c\x95\x8e\xa8\x05m\xc2\x1e\xacl\x9c\xc1\xfd\xb4S\xac\x9a)\xe6\xec3\xbc0\xe0\xacD\x9b|M\xa6\xe0\xce\xe0\xc9\x13\x98)\xa1\xc7\xf4w)y\xd2\x93\x85{\xd2~\xf1\x93\xa4iY\x0d\x1bBK\x86{\xc7\xaa\xcf\x89\xf6\x1e3\x98\xa5w\xc6\x0b\xcf;\x1d\x07\xb9\x93\xd4\x87\xe8\x8am\x84\x8c\xad6\xd2X^\x17\x9bJ\xd4)\xd9k\xbe~\xf9b\x8d\x1f\x00\xca\xd6P\xcbLx\xc3\x1d\x1e\x0c\xdd\x0dt\x0e\x8e\xa1\xfcv\x84\x8b\xa52\xf9;w\xda\xe1\x9a\xea\x82=p\x0c\xbe\x97\xc0\xcc#\xa0H\x07\x83\xc8}\xa6\x1f\xaa\xc8Lq-\xfa\x91\xcaH\x01\xcd/\xd0\x12\x96\xb1\xcf\x02<*\x00?\x8eQ\xc8\xa7\xbe\xefi\xdfG\xbcP\xca\xfeD\xa2\xf3\xcd\xfcY\x90/\x8fcw\xc6\xefc<\xd4)\xe5d\x96k]\x136\xa97\xb0\x07)l\x823r`\x13\"\xf3\\2v\xb6\xe0\xb1>\xca\xa0D\x1c@\xe2\x0bLro\x90ko%w\xe8_]\x8bjX\xbe\x9f\xc3\" oR\xd2\xa5\n\x05\x18,\x9d\xe5\x1eU=\xe9\x96\x08\xb0\xa5,\x97aDFpc\xcd\xf8\xb5_\xbap\xfb\x08=\xedo\xbf{\xce\xabv+\xf7>\x15t]{\x12\x91\xec\xc35\x8c\xe0\xd6G5^=R\x1d\x0e\xa2\x9d\xec\"\xa0\xf0\"\xad\xa8u\xa2L+\x9d\x17B\x87!\xdfm\x7f\xe7\xd8\x17y\xac\xb6\xfac\x1es\x9c\xc4\x8b\x9bK\xb1\xc1\xdd\x05I\xf9\x9f\x17g\xa7\\0\xed\xb9cT\x8cW\xab\x81=`\x19\xb86\xbc;\xf6F0f\xfba\x8csi\xc8<\x16\x93\x0c\xa3\xf6\xa7\xf6\x86n\xa5\xb0\xa1|\x163\xaf\xb8\x01\xf9\x07z\xe6m\x8f\xe33\xee\xc4\x9bU\x92J2\xcc\xfd\xec\xf9P(\xc4\xa8\xab\x1c\x90\xf5A\x08\x9f\x0d\xb5\x11\xc3\x11\xa6R\x19\xbd\xfeq\xd7\x0d!\xe0\x84\xea*:\xea\x93\x9bG\x99u\xab0\x16m\xc2\xd32\xc0\xbc\xe1\x9bD>_U\xf8k\x0e\xd3p\x97\xcc\xc6u\x01{p\x14R\x12d\xf9mG\xa8\x9bLRg.\xd1\xd5\x05\xad\xd3F\x83x\xc5Qj\xa3\x0d\xd8\x82\x8bj\x0dyO-c4\xa8O}\xf5\x84\xa0\xad\xbfyuJ{\x1a\xea8c\xb9\xf6F\xd7}\x0b)\n.^\x98\xab~m\xccg\x9ei@\x8d$\x0b\xafI\xdan{\xf4aK\xf5\x04\x83\xa3\xaf\x1d\xab\xa3\xaf\x9d\xa6\xa3\xaf\x9d+T\xe37P\xef\x15%\xda\xfe\x96uR\xa0\x89\xd8\x07\xb9b\x9e\xc3}\xfeP\x0c1\xc9\xcb9Wf\x1fi\xdd\xa4\x9bT\xd2$\xc14\xebR\x9a\x0f+}\xd5\x01\xf4;\xe9\xe7\x07\xca\xea\xf6\xdf\x16\xa5\xce\xed>\x0c\xb9\xfa\x80\xe6\x1d\x8b_K\xd8\xa9\xfc\xb0\x1d_W8x\xednl\x8a\xf7\xc9\xed\x03\xcb\xce\x08D\xa6\xa3\xca\x9c\x9d\xd1J\xdb\x9f\x17\xe9v\x12P\x86\xac\xa6\x96N\xccq\x00\x15\x81\xd8\xe8\xbe\x0f\xb1\xfd\xec\x16\x80\xb0\xd2\xb8C\xd4},\x9a\xb85\xb1md\xa1\xfcm\xd1\xbf\xe7\x8a\xdf\x96\xa5\x96\xd8\xa2\xdfb\xd8V^\x92\xc4V\xednS,\xdc\xa9\xa5\xab\xc2\xb4\xd9b\x9fa\x0c\x97\xbb4\xa0\x1c+\xce\xc1_=\xce\xa8H@>/\xf3\x02\xfd>7\xe7\xbb\xb2\xf1\xcd\xdc\x97\xcf\x9ej\x90P\xdb\x087\xbdO\x19\x9b\xb4\xb57@,\x89\x91]\\n\x00\x12f\x11\xbaUD\nKA\x80\xe8\x11\xb4\x80$\x03\xe2\x01\xde\xea\x03\x9b,T\xb4p\xd1\x1f\xeb\x08\x92,\xca\x8b\x82D\x14\x92l\x9ds\x07x\x1b\x16W\x8e\xe4~3hv\xe7U\xd9(\xb9\xaf\x9f+\xcdT\xc3\x0f\xa6CD\"\x19\xb9\x1d\x805Y\x8f\xda{\x8d\xd15\xc1\xb2\xc8\x17 \x8a4YUdX\x9096\xe9\xca\xfcRm\xbe\xb3\xf6,;?\x861\xbc\x17mEyV\xd2b\xc50\xb3M\x97\x11O \x1f\x0f\x1b\x83\xbc\xd6\xf3y\xe7\xc5\x05*\xcb\x84\xbe\xe5D\"\xa3~1M\x0b.\xf3U\xb5;\x1c\xb4t\xf5\"}\xbfcZ\xa4\x01bB\xd4\xb0\xe3GW\x921\xd8D~\x9aLrv\x16\xe3\xbf=\xa0\xec\xdf\x08\nVG\xee\xe3\xeb\xbf\x04\xf2^>\xdf\xb5\x8c\xaax\x8c\xea_\xbd\xb0\xd4\xce@M\xd7g\"\x9f\x97i\x12%t\x04\x13\xd6\xb1\xe7\x8c\xe0u_>\xff^\xfc\x7f\xe1\xa9\xdeP\x1f\xde\xbb\x0eJR\x99\x97\x17\xbb\x167\x93\xec\x9b\x8e\xea@\xd0=\x9a\xc7\xca`s\xeb\xea\xbb\x91\xb7\xef~\xdc\xfe\xb8\xed\xed\xbb\x93\x8f\x17\x1fK\x0c\xc9\xd9.\x1eb\xf1\xc9\xc1\xd6\xff\x1f+\xe0\xffw\xb6^on\x05W\xdf\x8dX\x05\xdb\xedB\x8c|\xb1\\\xad:\xff\x86\x9e#\xc3r\xae\x87\xf3\xae\xb3\xec\xb3,\x7f[\x91\xe2\xce\x9eg[\xfatDG\xca\xd6l\x7fd\xd9\xc2\x15\x92x\xbb\xb6\\\xa7\xe1)\xeb\x13\x8fH.\xaf\x86w;\nl\x8f\xdc\x8f\xf1\xa6\xf7\xef\xdb\x18\xc8\xbch\x14\xebo\x04{\xac5\xd4*c\xa8\xa6}\xce\xc9\x87M\xe7\x08v\xcd-\xe3D\x8e`\xb7\xf5Q\xf5# \xaa\x9b\x8d\xd4\x8e\xaf3\xaepo\xb3\x94C\x015\xfa\x83s+\xc3m\x1a\xa4\xe2\xd4\xe2\xc2@\x8bp\xd5\xb9I\xf3\x9b\x91#d\x9e\xcb\"\xa7y\x94\xa7\x1e\x87{v\x96\xb8\xab\x8c\x94Q\xb8\x94\xbc\x13\x9bF\xcf7WH\xd2\x92\xe8\x8e\xea\xf6t\xf7\xd8\xf2A<\x981\x1cX\xb7E\xb0b\x1fJO\xeaz\x14\x93\xcc \x91\xac\x1bR-\x99\xad\xda\xd6uS\x84\xa1\xdb$\x03\x94\x90\xba\xacr6_\x93LG\xaf\xf2Ql\x14\x8a\xa0L\xc3rNP\xfc\xec\xd6o\x8c\xb0\xa5\x9cQ\x9f\x17dj\x8a\xfa\xd3J\x91\xbc\xe9\xef\x9a\xd9\xccp\x11u{;\xad\x02\xfaZ\x89g\xf3\xa4\xc8\xb5\x1e\x01\xe5\x0e\x9f\xd9\xbf\x80\xe6\xef\xf2[R\x1c\x86%A)\x8fc\xb1v\x17\xa3\x1f\xc1\xc6\x06\x9d<\xb5\xec\xbe\x82\x94\x94U\xff\xac\xbd\xd1\xf4+V\xf3\xd0\xa7\xb6C\x14*J\x8f\x1d\xf1*\xb17\xad\xbdPW0E\xcd\x82\x176\x83\xdc\xec\xa9\x94\x1a\xf7sn\xc1\xb0\x12\xc1\x91-\xdc\xcc\x02j\x97\xdd\xe6\x1c3\x96c\x9eX\xb8\x8a;\xd8\x83\x9dv\x7f\x10L+\x88f\x84\xd3\x02\xad\xf5\xe5f\xaaR\xb8=\x8e\x8f\xcb\xcf\x1d@s\"B \xfe\xb3Q\xf50\xabJ\xe4\\\xcc\xe7\xf1\x82)RH\xec\x9c\xdap\xd9q\x13\xb9\x84{.\xf6\xbc\n\x0f\xe0\x85H(A\xdd\x87Y\x03\xea\xe5\xef/_ \xe1\x1eu\x95\x8cU\x15\xc8\xf8\xc9\x17DL\xea\x9b\xe3\xf8\\l\xc1h7\xea7ku\xd7\x93\xa7l\x83N\xb6\xdd\xe0;o\xbbq\xf4xo\xe0\x0e~\x80\xb5\x10s\xbc\x81\xbb\xcdM\x0f\x91\xb5\xcbx\xd8\xf5\xe4\xee\xca\x9b\xec\\\xf9\xdc\x12{\xb2{\xe5C\xc9f\xa5\x84}\x98M\xe6\xb8\xef\x19|\xb7]j\xb2\x1c\xff\x8f\x1b\xa3,@\xfaX.=~\xc9\xe1dh\xfe\xa2f_\xb2>\xee\x83++\x15\xa0\xb3#tT\x95\xa4\x1861\xb7\x87A\x87\xb5\xfczf,\xcfs\xc6(\xfc\x15\xbb\x9c\xf7C\x14\x8eq\\z1\xdek\xcf\xf3\xe5@\xf1\x9f\\\xa5\xe5\xe4\xd9\x15\xae\x96Hd+\xb0\x9c<\xbfR\xebe\xff\x9a\xa8\xc0\xb0}8`\xcd\x02<\xe9\x90\x14\x12\xbf=\x84+\x15 @\xf1c?\xab\x8e\x91 \x9a\x87\xc5\x01uw\xc4\xdc\xea\xdfy\xef8GQ\x9f=\xa2\xd5*\xd3\x00?\x11\xa0\x92\xdd\x18\xe9\x0c9\x14g\xdb\xf1\x82r\x99&\xd4\xe5?\xe5\x0cn\xedz\xd2a5Q2x\xbep\"\xc1A\x8e\x1b\xbce\x93\x02\xb6\x18\xfd\xc1\xb7\xd2.7s\xdby\x03\xc5\xd6\xd6\x1b\x0f#{\xe0M\xd9\xa4\xb8B\xcf\x19\xac\xba\x08#\x13\xec\"~\x0d\x9a\x19\xdcf\x0e\x1fB\x06\xd6#\xee\xb7\xc3\xdd\xa9\x03Z\xb8 \xf7j\xe0C\xab\xc4\xd6V\xb7\x94\x19\xd7&\x0bVY9O\xa6\xd4u\x1c\xcf\xc7~\xb2\x89\xceq\xa9\x82\xea\xed\xcb\x17\xc8\xb8\x0e\x1cf\xcb\x84\xce\xfc\xb6)\xa2\x8a\xb2*\xbe\xbabl\xde\xd8\xb7\xbc\xa0*f\xe0\xfa\xa93\x19a\x97\xff\xe0\x85yf~{\xc8\xdeV%)\xc4b\xb36\xca\xf26/b\xfc\xcc\xbe2B\x13\xa7d\x89\xdf\xd9\xab\\\xb5Q\xab\xfcr\xb2S\x81}\xa3.\x86#\x04\x02d_\xf2\"\x99%\x19oP\xc1\x86\xa2\xbb\x88l\x93\x94\x8c*\x98\x95y\xf6\xd5\x97Mp\xb6\xb7\x1d\xd8\x94\xc5F\xe00|\x8dM3b\x01\xab\xaf/3\xb53Q}\x9b\xf2J\x85)B\x1b\xc4KBG\xbd\xac\xa7|\xf0\xe0\x13'\x94\x19R*\xeb\xaf\xae\x0bh\xae2\xca9\x86n\xa5\xd1\xdeX\x17\xd2\xdd\x84\x8b\xd4\xaa<\xa8x\xa0\x85d\x82\x17\xc9=\xe6_C4{9\xd7\xd0c\xee*Zc0K}H\x14p\xdd\x17~1\x12 \xb2I\x05\xb2\xd5\x95/\x0f(o\xc8Q\x8d\xc3\xe92\xd7\x84\xa1#\xa98\x9a\xa1\xa3I\xf8\x96\xe2\x13\xbd\xb9'\xba\xcbS\xd9$\xcb\x1e?\xc64#O7\xb4c\xdb\xa3\x8f\xf1\xe6\xbfos\x1a\x9a\xb2Yv\x85\xffxe\x0b'\x12!\xd0`\x99/\xdd\xaa\xc3bSS\x81\x96F\x8e\xa7\xcc\xbf\xfc\xa8\x14\x7f\x9c\xc9\x97 \xd17F\x95\x08\xa2\xcd\xf3\x94\xf5\xa9\xa6\xa56z\xa2N\x0f\xeb\x95\xa4\x8d\xfa\x94\xbcQ\x0c\xd0o\xf4=\xc8\xd6\x13\x0dW\xd9\xc4V\xad\x0b'3\xfbx\xe0\x8f\xc0\xf97\xcb\xb5\xb6\xfaHhP(\x82\x0da\x16\x1e\xb2M\x05&\xe5V\xf5\xf9*X\xc2\xc7@\x15R\x8c=\x08~\x8d\x99\xccF\x1f\x15\x05Rr\x02\xa1\x84\x1f`U\x91\xaf%;\xe7\xed\xf3\xcd\xca10ZM\xca\x0e\x0d\x9dT\xd2q\xc9$\x9d\xec^\xb1\x1e\x8a_\x1a5w\x8fnK\xa2\xa1>\x11\x93\xc6\x89\x98\x18O\xc4D=\x11\x13\xc3\x89\x98\xe8'b\"O\xc4\xa4\xa1\xde\xd3\x0e\xeei\xba\x9f\x14\x05F=\xb2o@\xd7vMNI\xf1\xa5\x8f\x04\x89\xf0\x8c\x84\xf5%\xd3\xbb\x0e\xcd\x1b\xca\xe5\xd1v>\x0f@\xc6\xc9\x95\xe3\xb7\xd0e\xd8%1s\x85\xdc\x04\x85<\x1c\xb7\x18\xa9\x88B\x07\x81\xb8;\xfa\xc4\xe3\xb4n\"\x1d)\xd0\xcb>\x9f\xf2\x91\x1d\xf9U\x97\xfc\x15\x9d\xc4 \xcc\xcd=%\x8d\x11\x7f\x15\xb9T}\xe7\xc7H\xfd\x05I\x7f\x96\xfeGG\xfe\xcc\xf8J\xf3\\\x92\x10\xcf\x87\x8d4X\xa6\xabY\x92\x95\x93\xec\xaa\x0biR\xb9\x86\xe35\xc9h)\xeby)\xeaQ\xab\xe9>5\xe4)G\x03\xb2\x167\xab\x1d\x1e\xad\x14D\x9fd\x10z\xb0r\xc3Iy\x85\xeb\\z\xb2\x17\xaf\x1c\x94;\x19<_\x82\x11\x17\xab\xd7\xb4\xed\x95\\\xd9h\xfe\x94w\xf94\\\x90\xa3\xa4\\\x864\x9a\x0b\xedd\xb6\x19\xcen\xb3\xcaP\x99{\xc9b]{\xed\xa0*BGY!8m\xceA\xad\x8f\xb1\x9c\x87%\x89\xcf\xc9,))\xd7q`uhS\xc6A\xcd\xb0|\xd5\xfc%l\xfe\xacR]\xaeS\xab\x0d\"\xf1<(\xdd|\x92\\\x89\xe9\xe8\xd9\xe9P\xa3?=\xae\xed\xefLy6HPh\xc3B\xfcR\xba\xed\x0f\xa2\x07>c\xd3;\x17\xaf\xb4/\x9e^'\xbfB/\x19\xf5\xc1\x17kwg\xa7\x02\xe7\x8e\xccH\x06\xb7s\x1c\x91%\xc9b\x92EI\x95M\x01\xf1Iv\x15\xc4J\x0ee\x10\xf2\x97\xa4K\x9a\xfd\x16\xfb\xaam\x95e\x83\xa7\xb6\xda\x91e,\xfd\x19\xd5!\xb5s/\xf3\xb2LnR\xd2\x82M\xe1\x01\xa0 \xa1\x19;\x9e\x10y\xbc\xc7\x11a\x8c\xc9>\"#\xafVf\x97\x9d\x81u0\xba\x8a\x83\xe7\x92&~0\xb0\x95\x0bu\xd6\xbf\xa7\x1b\xe5\x8fw\\)e\xc0M?\n\xa5,\xb2f.\x0e\xc3k\x11\xeb\x0e#m4\xd1G\xa7\xe6\xe2N\xc5\x8e!\x133\xeeI\x10\xadH\xb9\x93\x8b\xafr.\x9f\n\x9c\xc4\xf3\xe0\xad8\x17\x80\x0dD\x9fH\xa1\xf6L\xf4\x8c\x88 \xe6\xc0\xf66/p\xd2\x87\xce3 \xe2\x06T\xb7\xc7\x8flUk\x13V\x17\x16\xf6\x1d\xdc.\x84\xb2*\xb3[g]\x1b\xc3\x86\x8e\xbbNqn83\x08\x8f\xcb\xa7\x02)\xd4\xac1`^\xf9\xe0\xc9\xaeC@\xd1 V\xa0\x80\x96}\x96\xb2Iq\xd5\x01uP\x1f:b\xc2\xdbQ\x85\xe4\xd3u\xfe\xcaG\x92\xcd\xab4\xed\x82\xaa\xeb\x82\x94\xa4\xb1}Gv5Nh\x11[\xb9\xb8\xe4A\x8fg\xad\x8d\xc3\xe5\xe1\xe2\xb2\x94\x91]\xed\xe1Wd\x8e\xe4'\x8c\x97O\x12\x88\xedg~\x1f\x12\xa1\x1e\x0f\x9e\xdb\xde\xd7\xa2{\xd4\x88\x13$Yk]\xd6\x8evC\xbc>\xf6\xa0\xd0\xdb\x0d\xd5v\x8bI\xd8\xbc\x804j\xd9\xaa\xf4;_\xcf\x87S\xe9\xdc\xa3\xa2\x99VG/\xd0\xee\xd3\xdd\xa7\n\xdd+Hw\xf7\xb51\xfe\xc6\xaaC\xdd\xad\xa6\xb9P4\xfc\xe5\x0b8\xab\xecS\x96\xdff[\xb8\x8e\x9a\xf0\x85\x04\x11w\xe9p\x19\x163B\xf1biF\xe8i\x1e\x93\xb7E\xbe8\x16\xf7\xa8n\x81\x97\x84\xfb\x10\x06I\xb6\xce?\x91?\xad\xc2\"&\xf1a\x98\xa67a\xf4 }Cp\x7f\x99\xd8-\x82W\x14\xe6\xbcU\x16\xdf\xd0zc\xef4\xa9\x8a\xb6\xdeER\x8e\xb38)\xe7}\xf8X\xecK\x87\xe6\xcb\x93|U\x92\x0fK)\x94b\xd3C\xf3\xe5e\xbe\x8a\xe6\xe3,6%\x1f\xb2\xf1\xa7\xe2K\xd7\xb6N\xca\x93|M\x1e\xd0\x1dV\xcc\xd4\xb2\x92\xde\xdd\xee\x05\x0d\x0b\xfa\x80\x86\x8f\xf2\xdb\xcc\xd40\xd67\xa0e\xa1\x82{\x94\x14$\xa2\x129\xf4u\xa2>\x1c\xaf\xe5\xe9\xf8.))\xc9\x88M\x0b;k\xe6\x960i\xc0\x03M?T\x94\xd3\x10\x8cXx\xe6\x18\xa1\x8dA\xb4\x19\xde3\xcf\x18\x18\x18\x14\xfc\xc4\nS\x97\xd83J\x95<#\x90\xfb\xc6 0}\xac\xc6[},\x06-\n/M\xca\xe36\x95j\xb9\x16]WV\x80C\x97\xa6\x18\xbc4\xec\x9c\xd5\x9d0w\xe8\x01I4\xb6\xf3\x06r\xf8\xa1v\xd5\xfc\xe4 l\x90 )\x19b\x0fg\\[\x9e\xe6\xcb%\x89]\xef\x0d\xe4\x9b\x9b^\x8d\x1d'\xf9\x95\x0fE[U\x12\xa4\xc2\x10^X7\x90\xa9!\xe3\x03W\xe9!K\xc4Fr@/\x8b\xd5`J\xbe_\xbay\xff\xed\x06\xf7\xdar`\\[\xdaI\xbc)\x84!\xbf\x19\x87\x1f\x1a7\x7f\x1d+\\lnv;\x18B\x8azR\\\xb1Ue\xe4\x9f\xa2\xfd3)\xdajG\xa0\xdc\x15\xa0\x87\xe0'O\xd8\xa6\xe6\xc1\xb3e\xc1n!\xa9\xbe\xd8Xe\x97\xfaU\xe7\xde\xee\x847\xda\x05U\xf3\xb0\xac!\xaa\x0f\x80\x14\xf1E\xbb\xbd\xaeV0\x9e7\xef4C\x98\x0cq\x0el\xab\x08\x0ce\xf5@/\xed\xd6t\xd4|\x9f\xd6Zh\xbd\xbb\xb5\xa4<`k\x81\x0e#{\x91\xa5\xe4\x18\x82\xba\x14\xcf\xdb3\x9ew\xf9-Zw,\x16y\xf6\x90\xe6,U\x0cj\xfb}\xc8\xce\xa1{\xce$6\xd9,\xd93\x8f\xb4\x08\xd7\xa4(\xc9\xe5m\xfe\x9e1\x8c\xc3\x14\x11\xaa\xe6\xf4\xe2U\xa1!m\x8e3J\x8aw$\\\x1bZE\xd7\xe6FYu\xab\xed\xba\x1a\xadp'\xfc\xa0\\&\xc93\x93g\x0f\xfe\xf10_,\xf3\x8c\x11\x03\x05\xe9]\x00\x90'l\x1b\xbf\xb4Q7\xaf\x9fU{\xc9\xc7\x10\xa6C\xea\xcf\xcd\xf5\xff\xce\xfcfa\x8f8\xc6x8{\x042 U\x95\\\xf1:\xb9\x0dd\xcc\xb1\xaah\xcb\xa4\xa33j\x14kUQ\xa1\xc2\xc9\xee6\x86\x02\xe5^M\xe3FL\xccN\xcb\xca\xac\x9b}je/\x08\x1a\xca\x1c\x86\xab\xd9\x9c\n\xd7\xe1\x9d\xb2\x02v\x8aY\xcdr\xd6\xc2&\xd4\x12\x14\x86\xdb\xe4\x14\xf5Y\xf4\xadp\x91<\x1c.\xcc\x164&n\x97S7\x94\x13\xd7_\xbe\x00 \xca\"\x1a\xa7dA2|\xbfM\xb28\xbf}\xa3O+\xdb\xef4@\x9b\xaer\x99gq\x92\xcd>\x94D\x96\x93\xfaG\xd6\x1c\x9e\x0f\xcfxh\x9c \xcbc\x82F\xfd\xfb<\x8c\x1c\xc9\xf0\xe0i\xe8(|\xab5\x8e\xd0-t\x9f\xaa\x163y\x10\x85\xd9\x87\x92\x1c\x9d\x9dT\xe0\x1b\xe7\x11\x1a\xef\x06\xc9b\xc9{\xca/'\x9f<\xb1}\n\xe6a\xf9\x96\x84tUH\x7f'\x1b{\xd6z\x94\xcc\xae\xe3\xf8\xa8\x1d\xdc\x98\xd9\xed\xef\xbekB\xcdwp8'\xd1\xa7\x92Af\x98q\x81?$%\x94\xab%[_\x1e\xc0\x89\xce \x08.IP\xc7\xe82=['E\x9ea7\xb4J\xf56N\xcf.\xc7#\xb8\x9c'%\x8f\x0f\x95\xe5\x14n\xf3\xe2\x13\x08\xa3\xbd\xf4\x0e\xa9\xce,\xcf\xb6f\x8c\xc6I\"\xde\x13\xd6\x8fh\x0ea \xbf\xf1H\xca\xbf\xf9z\xd5\xbf\xa1\xb8\xee7\x1f~K\xf30f\xff\xd1\x08\xfc7\x1f\xa3Q\xfd\xc6\x1ds\xfc\xd6\xd7\xc1\x1f\xf3\xa2\xc8oK\x98\x16\xf9\x02N\xf2\x98\x14Y\xf2\xf7\xa2\xaf\xd4\x1f\xd1^\x14\xfe\xc1\xb5\x0f\xbe\xd6\xd7%\x17\xab\xe94\xf9\x0c(D\x84L\x98\xaf\xcf\x02p\xa24\x89>9z\xbdUE\xfb7y\x9e\x920chq\x89K\x8e\xab\xc3\x16\x07\xd7@$\xa2\x9c\xb7\xb1J\xed\x1a\xa51AU#c\\dE\xedenW\x90\xb036\x0b\xd3\xd6\x874\x89HV\x92z\x9a\xe0Y\xb0\x13\xec,\x0b\x02\xee\xe1\xaa\xa4\xf9\x02~\\%i\xec\xc1\x1789\xbe\xd4\xcao7\xde}\xbb-\x9e\x8eL\xd0~@\xddS_\xbe\xf0[\x82\x0d\xd7 \xe3\x18\xe7Z\xd2\xc8\x0e\x83Z\xb9GjVA\xbfY\x91\x1c\xb5\x93g\x0el\x9a\xfc`\xa1PP\xad\xecM\xbbOF\x92e-\xae\xa0\xab\x8d\x1a\x15$\xa4\x12=\xb9N\x9c\xacM\xea\x1daP\x12z@i\x91\xdc\xac(q3\x1f\x84\xb3\xe47\x8e\xd0\xfe7\xaa\xc2\x84\x93\xcc&2\x05\x85\x9d@Mb\xae\xbdr;'\x95\xd8\x0c\xa4~\xf2\x10\xac\xc2\xef\xe6\x03^\xde\x07\xe7Y\xb0\x83\xaa\xd6\xc9\xa3!\xd3\xd6\xd1}\x90\xd2\x118aJ\xffL\xee\xf4\x90\xbayF\x8b<\x1d\x81\x13\xd1\"m\x7f?!4\x1c\xa1\xdb\x82\xb0\xfd\xf1b\x9eLY\xcd\xa8W\xcd>\xd7C\xb0\xd0:\xb6\x03\x0e\x0dW\xb3\x90&k\x82\xf3\xd3\x86\x12\xf43v\x92\xc7\xc94!\xc5\x05\x0di}\x8d\xd4\xfe\xd4bO%\xa0\x16\xad\x1b\x83\x8aS\xc43dc\x83\xaa\x90PC\xc1\xb0\xf3\xbau\xcd\xf2\x08K\x99\xb9\xaf^\x1b\xd4_2\xf7e+=\xe1j1\xbb\xdcv\xf4\xd9k\xfc\xf7t\xf7\x95\x1e\xfd\x9a\x8b\xe4w\x9f\xeb\xe5W\x98\xfe\xec{\xb3X\xbe4b\x151d\x93h\x92S\x18\x93\xdd+!\\\xa7\xe8\xb5\xf8\"\xb9I\x93l\x86\x1eu\xa6IQ\xd2\xc3y\x92\xc6\x86)_\x8b\xab\xf6\xc4\xedc\xafH\x90d%)\xe8\x8fd\x9a\x17\xc2\xb1D]\xa1q0\x91\xad\xaeB\xd4\xc58\x0dQ_\x8b?3\xe94XM\xb7Z3\xb3ob\xdcl(07+\xeaTaK\xec\x840\x8fI\xa4\xcc\xb8]\xb8\x95\xba\xdc\xee\xba\xe0\xd7\xf7\xdc\x82\xbdCk4\xafh_\xf5\xd1\x88g\x1c\x1cZ$Q\xb4\xdaA\x91s:l2\x97\xd6\x03l\x88\x1c\xae\xba\xcf\x9d\xec\x1a\xee\xdfb\xac\x1b?\xef\\\xf1;v\x12\xf0`\x9b\x08\x89-\x0eK\x0355+\xed\x1eFl\x83\x89\x8e\xe5\xab\xc4\xef\xddK\x87|P\xcfR5\xfbZ\x0cc\xfc\xe6\x0861\xa3\x15\x8b|U\xa6w\xe7d\x99\x86\x11a$?\xe3\xe3N\xc2\xe2\xd3j\xd9DS\xeb\xb6k\x8c\x9e\xf2-\xef \x05\xcfuD\xd2d\x91P\x12_\x92\xcf\x03\x0d<\xe4\x84\x11\x8571K~\xf9\xbda\xe7\xb4\xe6\"\x1c\xe8>\x17\x9e\xa7n\xe1\xeb\x14\x08\xeb\x19\x8a\xf6\x18\xe4\xe4x=\x02\xfb\xe0\xae\xf0\xde\xcf\xf3!v\xf9u(E\xd5||\xeb\x95]-\x8b<\"e\xf9\x01=\x14\x97\x03\xc4e\x0d\xeb\xae\x9d7\x90)\"\xe67\x90\xd9u\xab+\xf0\xb2\xea\xabHS\x98\x02oXm\xf5@\xa5]\x7f|z1>\xbf\xbc>98\xff\xf3\x87\xf7=j\xf6\x88u\x0b\xe9\xd8\xc7\xe7GJ\x11\x84SJ\n6\xa7}\xd1\x0d\x06\xd9\x05\x9c\x9c\xfd<\xbe\x1e\xff\xe5\xf8\xe2\xf2\xf8\xf4O=\x1d\x9a\xf2\x0eL\x85\xb8\xf6\x9f\xd4\xa3\x8b\xf1\xc0\xf9 \x1b\xf3\xf3\x18M_\x8e\xffry}xvz9>\xbd\xeci|\xf5\xe8\x8d\x9f\x8fq-N\xcf\x8e\xc6=m/\x9b\xeb0T\xc9\xe9\x9e\xf2\x9a5\xa6>\x88\x1a\xb3{\x01\x9a\xd3\x05#\x9f\xe7\x94.G\xdb\xdb\xb7\xb7\xb7\xc1\xed\xb3 /f\xdb\xbb\xaf_\xbf\xde\xfe\xcc>kd\xf3\"\xa4s{\x99W\xdb'!\x9d\xe3\x9f\x93wZ\xc9r=3\x16{\xba\xb3\xb3\xb3]\xaeg\n\x01\xfe8C\xed%u\xd5\xe8\xe9\xb5\x0d\xf6\xc9\xc5\xc1r\xc9\x10(\xfe@S\xde\x0f\x19\x0f~\x1f\x85\xe9[y>*\x94P%\x826\xaa\xbfvV\xd3\x1f\xd6N^L\xa9\xad\xb4aI\x17\xac\x8e\x1e\xdb\xdb\x8cQ\x8d=s_\xed\xbc4\xd0\xf1\x99\xfb\xf4\xc5+\xcf\xcd\xdc\x97\xdf{AR\xfe\x1c\xa6I\\\xc9\xe6\x1a\xb9CE\x19\xdee4\x7f{\x12nV\x94\xe6\x99\xd9\xaf_4'\xd1\xa7\x9b\xfc\xb3\xf9k\xb2\xc0\xf8\xfe\xa6O\xf3$\x8e\x89\xa5\xd2\"\x8c\x93\xdc\xf2\x89\xa0\xed\xa6\xe9S\xb9\xbaY$t\xd4\xd2L\xb6i \xe9\xeb\x8d\xe2\xee\x0dv\xc8\xe3\xa0H\xfc.\xc9>10\xac?`x\x04\x99\\\xb8\xce\xab\x97N\xaf\xae\xb2\xde\xcc\n\x95X]\xadR\xa9\x9f\xc8\x93\xf2\xec\x10\xe5mR\xc7\xfc\xd5\xab\x9ev\x0c\xdePZ\xed\x88Q\xf5\xb4\xf4\xba\xd1\x92\xfc\xc5\xc002\x9a\xd2\x8a\x88\x11Ch-P\x18f2\xa1\xa8\x93\x19N\xb8.\xd6\x15\x17N\xcb\xee\xf0\xb7\x82\x84\xf1Y\x96\xde\xf1\xb78)\xc3\x9b\x94\xc4\x8c\xbcb\xfd\x1f\xa1\xcb\n\xe1 \xeb\xd7|%\xc3\x83\xc6\x10\xc2o\xd8\xad\xdfX\xd2\x12h\x0e!\xa3y\x160MH\x1a\xc3mB\xe7\xf9\x8aB\x98\xc1o\xb2\xc1\xdf`\x1efqJ\x8a@\x91\x93\x16$\x8bI\x01!\xb0\x8el\xe5\xac'XC\x00\xc7\\\x90\xc7\xeb+\xe7\xf9*\x8d\xe1\x86\xc0bEY\x171\xd4\xfeo\xc22\x0e\xbd\xf7\xfd\x16\xc0\x19\x9d\x93\xe26)\x19\x99@(\x90\x84\xbd\xab\x1d\xc8\x0b\xf8M\x8e\xf8\xb7\xc0d2n\xd9~$~\xf8\xfc?\xe2\x94\x8b\xbe\xfc\xb7\x98\xf4C\xd1\x97\x7f\xd2\xb4\xcb\xd2#H\x026\xf3\xbf\xeb\xc8?\xb5\xda\x13-\xdb\x9b\x16u\xc8m|\n\xbf\xcb\x99\x11\x94q\xdb\xfc\xbf\xd3J\xb0\xe5\x08\xe95\x9b31\xa9\xdc\xff\"\xe4S\xf8\x8d[~m\x82\xf3[\xd0\x0ckh\x94]::m\x00\xa2Oq\x0b) \x18\xbc/\xf2%\x1aE\x0c\x83\xcc\xa62td\x03^6\xbe\xc8\xa4\n-%\x16\xd1\xa4\xb8b\xc74\xe7\x9a\x1c\x06\x88\x8e/\xee\xeb\xf2\x0e\xcb\xa9D\xf5\x89\x83\xe0\xcd%\xdb\x89\x0c\xfb\xc7\xba5\xedV\xdb\x99T\x99\xafP\xd5\xdeN\xde.u!\x81|zI\xd4&d\xcd\x08\xfdY\xc7\xbe\xa6.V\x9a5\xf5\xf1\xb5\x8f68(\xbc\xa8\x12\xff_\xf6\xfew\xbdm\x1cY\x18\xc4\xbf\xf7U\x94\xf9;\xa7\x0f9\xa6\x15\xc9v\x9cD\x89\xe3\xe3v\xdc\xd3\x997\x89sbg\xfa\x9d\x9f\xc6G\x0f-A\x16'\x12\xa9CRv<\x93\x9c\xeb\xd8o{\x0d{\x01\xfb\xec%\xed^\xc2>(\x00$\x08\x14H\xcaq\xf7\xf4\xec;\xfc\x90X\x04\x88?\x85B\xa1\xaaP\x7f\xc4_\"X\xf5\x8d\x15\xc4\xdf\xee\xfb\xc4\xa6=\x8d\xbd\xeb\xa7\xea\x11\xaa\x8d\x84\xd9a\xf5Z\x1f\x81|\xdd4\x06i)vVn\xc6V\xc1\xb7+$T\x94Ql\xd7/\xe4\xfd\xa9\x1c^m|M\xb3q\xb4\"\xab\xc8vJ\xf2{\xa4\xfd\x10\xce.*\xf8\x1aFI\x10?\x1c;\xd5!\xb1\x08\xe8\xfd\x12|\xa7\xe4\x18\xb7\xcc2\xfb\xe2\x1f*\xf5\x8c\xa9\xc4\xb1]\x88\xa0\xd2f\xa0\xda)cI\xa9\xd5\xa0k7Z\x95T\x15N\xab\xcb\xd26|UO\xe5\x98\xb4/b*\x90\xb3@\x92L\x96\xc8h\x18\xc4\\@\x06\x8f#\x8a\xc4M\xb6\xc1\xc1\xaa\xa7\x95<\xd0X\xf0\x0dv\x06\n\x0bd\xae\xd6\xca%\xabN\x83\xdd\xa6)\x0e\xb9\x8f\x95\x8a2q\x9f\x8e\xcc\x87\x16\x0du\x00\x8f\xb0\x0e\xfeQ\xf0}\x82\xdc*\xda\x1f\xa2\xa0Xa>9\xe5FB\x80N-\xa2\xa4\xba\x9a\xec\xdbwFZl\xb1\x9a\xcf{i\x16#\xec\xc2\xedZE\xadV\xd1z\xff)\xa1\xfb\x89\xdd!%\xb2q\xdc\xa8cjW\x84\x87\x90\xb4\x10\x15\xe1\x04\xc4\x0fg\xcf\x9aK\x08*\x00#\xcd\x8a\xf89\x06Q\xb2\x071\x03\x7f+\xab\xdc\xb3G\x91H\x99\xb9\x95\xfal\xc4\x7f\xa1\xaa\x1e\xffp\xdf\xf8\x96\xd06\xd6\xef^\xc8\xd9y\xc1\x15\x9c\xeb\x0b\xb75\x10\x7f\x132\xa6^\xb7\xd0\xea\x12\x17\x8b\x18\x81'\xab\xaca\x85\xbd\x94\xbd\xceU\xd0I\xd7=\xb7B\x1e\x12b\xf5\x10\x91\x88wUl5\xfe\xe6\xa8^%\xb6\xaa\xc40\x84Z\xfcG\xbc\x8dV\xe9\x9a\xd1T\x07\xff\xc4\x97\x9f\xd8\x9d|\xf7\x89\xdd=\xc4Z\xd17\xcb\"Tf\x1bAV\xac/M\xaa\xbdCo\x08\xdea\xdf\x11y\xd1\x1bb\xf1\xae\x9d\xba\x9bH\xf8\xa3\x80\xfd/\x9c9\xf6=4J\x08\x14u\xf7\x1f\x8d\x0e\x87\x97\x8f\xae\xc3\x0e\xe7\x87\xbaZ\x1e1\"\x96c\xa3._\xc5\x0f\xfdV\xa0\xf4q\xda.\xa0\x1c\xee\xf2\xe2\xe1&@\x11\xe0\xf0U\x8466\xea\xa3\xb7)\x87\x95\xf8\x8dQ1Y/__ D\xf4w\x05\x83S\xbd\x18\x04\x81\x06M\xff\xb0\xff\xe5p7xx\x80V\xf8J\xd3\x8a\x07 \xce\xec\xe2\x8a\xf6\x0fP\x916\x18\xec\x9a\xd7\xe6\xf2z]\xde\xab\xef\xef\x05\x9d=\xda\"BN\xec\xb1\xe4\xbf\xd6l\xcd\x04\xdfP\x8f\xccm\xb7@h\xbbJ\xdb I\x94\x1a\xcf?\xfd\x14+\xe8C\x0csQ\xa9\xb8\xe4\x82\x8ah/z*B!\x11\x014\xb3\x8e@\x92\x04fF\x8a\x8e\xf2\xf7\x0b\xd8\xed\xe3\x95\xdb6x\xe0\xf3&\x86\xc0q5\x93a\xaeB\xf0\x02^\x16x\xa0g\xffs\x87\x16p\x9d\x1fh\xeb\xed\x1a^\xa2\x0e}\xad\x03\xbd\x01\xdb\xed?\xce\xdf\xa6\xeb\xa4h\x97\xa0\xd4R\xd1\xfd\x83n\x86RH3\x94\xdeXH\xfclZ\xdaT\xd77\x89!I d\xaa\xecr\xbb\x08\xed\x8b2\xd9k\xe9\xbc\x88U\xed\xe1\xa9mc\xaf-\x94\x9cEu\x84\xd2\xeeb\xbd\xf1\x8a\xa1\x95\xa9\xea,\x87#\xea\xad\x08\xbf\x88\"\x13\xf5\xcd!\x8c\x8a\xcb\x10\"\xebB\xbb\x11 \xaf\xa51^\x07\x11\x93\x91\x03%\xdej\x03\xa5\xbe)\x07\xda\xecM \x07\xfac\x9aM$-\xe8\x8aM\xf4bH\xe3\xder@Z\xc3(\x98\xf0\x11\x15fJ\x0crH\xf2\xe6\x1e-\xaa\xba!T3\x9aH#\xf4rd\xd8\xf0\x7f\xf0\x9e\x14\xac\xaa2\xbdo9l=\xc1\x82\xa6\xd4\x97\xbf|\x02\x99\x85\xf5_\xd5\x90\x17\x84\x9b\xa2a\xd2\x80\x86\xc9e \xf0\xb0\x0b0\xcfYA\x01\xd2\x05\xc5\xc4 E1[?\xa1\xc0\xf8\xe5\x0b\xd0\x05\x870\xba\x0c\x02\x85\xb0|\xd4\xa6{\"=jy\xe3\xe4\xd8=\x0e,\xa86\x8327\xc7h,\xac7\x96\xc9\x0e\xf9\xf9\xdb\xbe1\xcc\xe5\xec\x0093\xd6\x99.\xf7I]\xc0\xee\xae\x87#\xe7\x07\xea\x86l\xc77x\xc9'\xfe`/\xa0\xb8\x90\xbd}\x9a\x0b\xe1<\x86\xee\xaf\xa9\x8f#\xbd\xff8\xba\xdd\xed\xdeT\xc1\xdeP\x928I\xa7\x8c\x16j&\xf3(\xe3\xa5h/\xccP\x1b\xc0yI_(\xbaU)^M\x0d\x84?ARZ\x06\x0e\xf6\xf8\xde\x92\xc8P\xc0\xcbC\xd8\xdbE\xd5\xc1^\xa9[(`\x08\x1bJ\x9a\x15h\xad<\x15\xd2\xc5`\xf7)y\xdd\xbao\xde\xc2b\x98\xc7\x91`\xa1${si\xb0\xe3k8\x04u\x0d]\xe9V\xeaurB\xfbR\xaf\x81q\x0e\xcb \x80\xf5\xb2 \x86,\xa8+k\xec\xdb\x89\x85\x90\xeae\xde\xc3M\x97[\x18a\xf3\xf7\x18\xaa\x8b\x05|\xdfD\x8dJ\x0fdf,\xf2\x84\xe24\xa15\xe9\xd3\x0c\xe7\xa4\xd4Ex\xb5\x8c8\xa8$\xd2yO\x1a\xf7\xaam~X\x0f\xfe\x9e\xe8w\x01\xc2\x8eK\xf4\x94\x04\xbc\xea\xec\xbe\x08\xb5\xfb\xecI a\x8c>\x83j5\xcff!4\x82\xbe\x93\xbc\xa2\xf7\xe3\xcaJ\xd3\xb2eA&1\xd2a\xe7\xb3\xde\xd5]\xc1\xde\x08u\x12\xcd\xf8b6\x9a\"\xe8\xe5\xac\xf0\xc5\x0f\x0cb\xdd\xe6\xdec\x8e^\x05\x87\xc4\xf5\x9b\xc7yo*\xe6\xa5R \x0e!\xe2EJmm\x16\xba\xc1\xa0\x00\xaam\xfc\x01n\xf2G\xfa\xc6\xff\xef\xbe\xd8\xf8\xfa\xbeG\x94\xc4\xa8\x0b\xc5\xfc\x03\x9b\xac\xb3<\xc6$\x86\xebP\xf8r\xf1\xf7mWB\xb8w\x8d\x8dk\xedX\xc5\x95H\xaabs\xab\x9e\xa7|(\x84s\xb8f\x1c%\xe84z\xda\xce\xd2u\x82~\xbcY\x9a\x16\x8e\x9c\x98\xe6~\xc6I\xce\xa3\xfc\xa3BhmB\xc0\xec`\xf3q\x15\xc4\xb0\x99{\x16&B$fuq\x8e\x01\xcb{ \x94\xfe&u\xec\xc5c\x90\xfc\x1a\x14\xf4}\xe4\xc0\x02\x02\xd9\xd4\xf3\x95\xcc\\V^\x94\xb9\xc6\xa7\xae\xdbb\xdf\xb4u\xd5\x9f\x08\x15\xaar\xd4\xeeyjg|\xd4qV\xe9(\xb9l\x99\x18\xb9\xdb\xaa\xe4w_\xeb\xb2~3\xef^\xa2E\xa1\x19(;\"yH\xc3\x12\x91\x92\xbdL\xf9\xa9l\x9cD\x96,\xe1K\x89\xb9 \x12\xf9\x13\x0fl.\x89\xc8\xdfe.fyh\xf0wE\xc6\x98\xe5\xd8EN\x14\xcd\xb5Y]B\xf0q\xdbh{\xa3\xe8!w)l\xb1:\xc6\xd0\xa8d \xcb7Q\x08\xef\x83\xc7\xa6\xbeD\x08\xefOLY_\xba8\x0e\x1e\x93.\x8e\xcf\x06OZ%\xac\x86k\x04\xce\x06Q\x97\xc0\xbc\x81]G\x19\x17\xf2\xf7\x1ce\\\xc8\xdfw\x94q\xf1\xfe\xc0Q\xb6\x82Cx\x0c\xea:\x9cH\xa2<\x05y\xfd\xbd&iV9\xd9\"\xe4\xb4w\xde\xc8D\xdf\x84\xb0\x0c1\xd1\x1bnKL\xea\x96\xfa\xd7A\x08W\x98kv\x8d\xd9\xe4\xf6\x82\x10\xc6\xfcL\xf1\xef*6\xfbV\x90\x99S\xf4\x05?\x82)\xefo\xccE\xa4\\\xfd\xeaW\x06R\xcfa\x0c/\xe1\xf69\xdc\xba\xb6*\xdf\xa6\xfe\nc_p\xa2,\xa3\xe4/\xe1\x10\xae\xfc\x1b8\x84\xbb\xd1\xede\x08\xb7!\xf0\xc1\x99Z>\xb3\xa1$\x80\xd3\xd1-\xe7\xf5\x974\x11\xe1OI\xc5\x96A\xb7TA\xa0\x18\x9a\xbdf\xbf\x17\xd0\xcfjw\xff\xa0\x9a{\xdc\xb9\xb9\x9b\x0e\xad\x1dtn\xed\xb6Ck\xbb\xed\xad\x9d\ny\xe5\xc6\xbd$\xda\x891i\xe4\x7f\x14\n\xc3\x11\x17K\x86\x80\xd9\xf5&p\x04\x13\x18\xc2i\xad\xba\xe9\xeax/\xcd\xa9\x14\xdb\xc4a^j$\x8a\x10\xbc*\xd3\xb7g\xfa^H\xd3z\x9d\x0d\xe3T\x13Sv\xa5Y\xfcW\x95\xde\x1d\xcf\xdf\xf2\xe5\xf1\x04\xed\xca\xa4-\xda\x0fQ\x1eO\x8e\xd7\xc5\x9c%E\\\xa6bpV\xff1\xcd\x96\xef\xa3,Z\xe6F\xad\xd5jA~\xfe\xbeJ V\xf4V\x19;V\x05\xaf\x97\"!1\x16\x9c\x9c\xbd\xfb\xf1\xf5\xef?~8\x1d\x1f\x7f\xbc\xf8 _\xfd\xf1\xf8\xcd\xebW\xc7\x17\xa7\xf8\x83\xbf=\xfb\xf0\xfa\xff\x7f:>\xe3\x7f\xee\xe2\xcb\xf7\xb2\xbaU\xf0\xe6\xec\xf7g\x1f/\xea\x1f\xe2\xaf\xf3\x9f\xce~\xc6O\xc6\xef\xcf\xde\x7f|\x0f\x87\x8a(|W\x81T\x86\xcf\xf5\x13\x7f\xff\xb1yE\x9f\xca\x92\xdd=\xea\xf2\x1e\xbf\x19\x04\xb5C*\x9f\xa7\xb7\xaf\xf8\xa2\xc6\x1c4\x9d|\x9e\xecm_`\xea\xf9 A\xa1\xa3\xbbE\x1aM\x87\xcdbG\xb9\x16\xdf\xd2;A\xfe\xbb\xf5\xbeH\xaf\xd3u'V\xdf\xd5\xf5\xea\xbe]\x97\x13?\xe3\x7f\xed~\xcb\x18\xa6\xf7\x1d\xc3\x04\xa3=\xaf\x05\xe2\x7f\xcb\x08\xe6\xf7\x19A\x1d\xb1#\x85\xbe\xfdg&\xfe\xaee\xd1\x9ee\x96\x92\x0bV\xa7OZ\x9e\x10nEJn\x13&\x1e\x15\xf5\x92\x8a\x1c{zJ\xacv\xcf\xa26\x89\x89c'{|\xab\x8dW\xe9j\xbd\xf2\xec+\x8c:%\xf0J\xcc0\xaa\xae\xea\xf4\xc3\x13\xc8kT\x9ab\xcaK\x17\xf9\xf1V\x19\x1b\x97\xed\x8fSD=/\xa4\x89\x98gU4\xa0?\x17}i\xc4\xd0S\x17\x97\xd8\xa6E8\xbd\x12\xe1p\x10^\x8d\x1a9\xe8o+NV\x9c\x1c\xc5\x95\x94\xcay\xdcp\xc7X\xb3!\xe2m\xd1cY\xd6XKx\xd2\xf3\xc6\xe8\xf2H\xc4,K?\xb1\x84\xae ,\xa8\xa5[#]e!\xf2RM\xe6l\x19\xd15&\"\xc2E\xb4t\xf8\xfb\x8b\x9b\xb1kV\xf8\xdel\x91\xdeR\xe1\x82d\xc4\xf4uO\xe2x/\xbf\x8d\xae\xafY\xf6\xf1\xf5\x076\xc5\xb8\xcf\x822\x85\xe0E\xe51+t\x063\xcep\x88\x1c;\xbd\x84\xdd\xf2e;\xcd\xcc\xa4\xfe\xea\xe1\x8d\xbc\x9e\x92G\x04\x7f\xf2t\x9dM\xd8P\xe5\x90\xa7\xe1\xc1n\xd8b\x08\xdem\x94%qr\xed\xa8%%\xc1!x\n\x8f\xc4\x91\xbf\x8c\xee\xe0\x8a\xc1\x1a\xddgCXEy\xce\xa6\x90\xa3y\xc5m\x94\x83\x88\x0e\x86J\x8e\x9ce7,\x83\xf7F\x95\xe4\xdf\n\x89ml*\xc2|a\x1eRQ\x9b\xb0C\x0cB\x88z\x18J\x0c\xed+~M\x10a\xafm\x00\xf2\xfb!\xc4j\xdd\x03?\xa2<\x821\x13\x97qH5\x0c\xdf\no\xa8\x1e\xdc C\x88\x88.\\$U\xa7\n\x14\xaf\xf6\xeb\x92\x04\xd6\xb8\x11c\x11X\xc3\xb9\x11\x059(\x13\xab\x91u\xd62\x84\x87\x98\xa0\x9b$Tu.\xac\x8bt\xf5L\x84zu\x11\xb3\xa4x\xedhk\xa6\xd59g\x93\x8c92\x9b\xaf\x9c&\xba\xfc\xb9\xce\xa2\xa4\x18\x8b\xf3\xdfS\x03s`\x1e\x7f\xf2I\xca\xabrp\xa6+\x96K\xfbF |\x16\x01\xac+A\xf5\xa0\xc7\x9e\xa3l.}\x15\xcd\xf7JKy\xc5\xa5 A\xc0\x16p\x04\xf3^\x9dL\x1c\x82\x87\xf2\x06\x9a_\xf2\x1d\x92\xf7\xae\x8a4\n\xfc\xa8\xcc\xf8\xba\xc6\xbbM^\x96V\xbbgEy\x9d\xf3G-:\x89\xfc\xae\x8f\x14 \x87\xb0&\xe9\x8a\xcc\xc1[\xce\xc2\x9f\xa0\x06`*\x97s\x1cs\x08M\x82\x10f\xf5\xf79\xae3\xdf<\xe8\xba\xd5y\xf2\x93r\xf2\xb3\x00\xd3\xec\x99\xf2\x9b\x83&\\\xa5\xd3\xbb\xa1ji\x1d/\xa6\\8{\x15\x15Q\xe0\xaf\x1c\x8a\xcdu\xb6\x18\x8a\xe0\xce\xbe\x87T\xe3c\xb60Y\x0e\xf5\x08\xb8\xc6\x0eD`\xd1\x94e9\xc9\x96\xf2\x07AH\xb2\xcdPR3\xe2N\xdcI\xafB\xb7\xb0\xf9[\"U\xa9\xac\xc1w\xdf\xb7\x10\xb3f\xe2\xb2\xeeH\\l\x93b\xfd\xa9a\xe7\xb0\xcb\xce\xdc\x84\x8a\xd0\xc1\x00\xd4S#lr\xfbL26eI\x11G\x8b\xbc\x9d\xc4\xa5m\xb4\xcdI\xa3\x1eb{M\xee\xb3e6\xd9{r\x83\xb4\xec=\"r~\xc7\x0d\xe4\xd6\xe9\xb4\xdb\x00\xb98\xf3D\xba:\n\xc6\xf6c\xb6hV\n;m\x8f\xb3\xb2\x8fV!\xa1h\xe5\x1b\x8a\x96\xadVt\xd8j\xc57o\xb5\x1a\xbaG\xfa\xbe\x1bO8\xc7\xefF\xf7 f\x08(z\x13g\xd81\xac\xa5\x0e\xa6!8`\xa1\xd5\x12\xc7\xd4\x10\xd6\xee\x9aj\x11\xc7\xeb,\x1e\x12V\x04\xd0\xb8\xc3\xb2\x07\xd8af\xd2U\xf5\xb4\xef\xb0t\x93\x1df'\x9c\xbe\xd7\x0e\xa2\x95\xa8\xff\xdcJ\xb5\xe7a\xb6\xd2o\xe6\xd4\xfa\xbbm\xe3\xbf\xff\xe6\xbc\xff\xf1\xb7\xd9\xe6\xfc\xa5\x8e\xbf\xeaZ\xe4\xc1x\xc7\x99C\x13%\x90\xfe\x9a\x152\xeb\x1f]+\xef\xc6\x7f.:i\xcf\x84\x824\x8d\xf2\xbds\x0c\xae\x9e\xbaR\x15 \xbdh\xbeb\x93\x96\x8a\xabrx-\x15\xa7Ho8\xe68\x96\x0e\xcbQ6\xa0+\xdc\x94W2(}\xcd\xe1\x08\xfe\xf6\x15\x9cR\xc6\x12\xdb\x93\x08AW\xb9\xae\xb7\xb8T-.\xe9\xeaw-\xec\xf9\x95\xd05dD\xa4 \xfe\x8c[4\x97\xb7p\x08\xfeJ\xc3\x07\x1f\xad\xe2\xff\xf65\xe8E\xd3)\xde\x11E\x8b\xff\xe0\xf0\x11\xd6\xfa\x82-\xa3\xdb:%\xae\xaf\xf4\xb2Y/\xce\xcf\x8e\xcf\xf7\xfc\x80\xcb\xb0\xfd\x10\xa2J\xa0\xbe\na\xd2\x13\xb1\xf7\xd9\xf4\x1cul\xbe\xc8\xac\x0cC\xa2\xee\x8c\xcfXV\x08\xeb^\xe2\xbaU\xd1-\x1c\xd5\"\xf6\x89\xa6\xb2\xaa\xa9\xdb@\\\xa6\x9f\xca\xb4\xf4\x87`\x08\xfa\x7f\xfb\x1a\x82,\x0c\xe1\x96\xb2\xe3\xe3[\xee3\x1c\xc2i\xe9\xd1\xe0;\x88\xc89\xd1\xbc\x93\xa8\xf2\xf3|\x85a\xcc+\xd9\xf2\xd1_\xf24 \xa1`\x9f\x8bG\xabE\x14'!\xfc\xee\xd1\xef\x1a\xa8\xbcw\"\x82[\xee\\\xdc\xad\x98g4\xf6y\xe7\xf6\xf6vg\x96f\xcb\x9du\xb6` ?\n\xa6\xb6b\x13\x04\xb5\xba\xa6\\\xb3z3VL\xe6\x8eY }\xfd\xec\xd8'\x18\xd6i\x08\xde*\xcd\xcd\xdb\x0c\xf5\x94d\xf5\x9c.\x97\x12\xfd\x8dc_\xe0i\xe18\xf9e\x9c\x1bt\xf3\xe2`N\xb3!\xac\xfd\xa0g\xbfw}\x9f\xaf\xd2$gD\x03V\x81\xd5\xc0\xd7\xa0\xc7\xf92\xbf\x99[\x02\x8d+\xd3,KYo\xcaO<\xf7\x92#\xf5\x97.\x91B\x1b\xfd\xe5\x0bx\xaes\x0d\xd4\x15\x88\xfc\x02;9\xd5>\xa3\xed X/\xfd\x84\x0e\xcc_\xbe@\x06G\xb0hWw\x83\xa6\xf2v\xd0Z\xe8\xa8\xd2\x86\x8e\xeaqhP\x7f\x13\x16\x85\xa0T\xe0yG\x158\x94\x8c\xc1\xd8=\x00\xa9\n\xb7\xf9zP\xdd\xfd\x03\x00\x8f\xf5\xf2\"*\xd6\xf9\x05\xfb\xec\x9a\x08\x85\xe6\x98\xaai\x03<\xaf\xacQY\xa0l\xfch\x04D\xcb\xc5r\xb7\x89\x9b]\xf5K\xec\x90\x06\xae\xf9\xa6\x0c\x00P\xfb\xc4m\xf2C\xe7\xa6\xd2\x1f%\xdbh!M*\x17\xad#}\x03\x8bL\xa4\xcd\xe6E\x99\xdc\xb9\xc2sp\xfb\x10\xbc\x10\x98H\x16%\xc2\x04\xe0\x0ft\xee\xc5\xbf\xc6S\x96O\xb2x\x85b\x9e\xfe\x91\xf6\xbe\xf6\xa9\xfeA\x93m\x92\x96k\xcb\xf6\x0e\x02\xa0|\x86\x00\xfd\xec\x7f\xf3\x18\xbd\x01\x1a\xd7^\xfd\xf6l\xab\x10\xad\xfe\x14-\x17\x82\x81s\x99\x10\x95\x19\xa7\xc8\xe8\xbb\x98k*\x15!U\xeb&\x12Y\xb3\x89\x84\x91\xbb\xb6v\xb7o\x0d\xac\xd1\xd8\x94\xdedR\xea\x89\xab\x0bk\x0c\x87\x1cM-g\xea\xc6\xc4p\xb2\x19\x91\x0fT\x13X8\xa2^\xcc\xb3\xf46\xe1\xa8\xaa\xd3\x9f 4q\xfe\xb7\xb7\xf4\x8b4\x9a2a\xc8vq\xf6\xfb\xdf\xbf9\x1d\x0b\xeb\x8bs|\xf5\xf1\xfd\xab\xe3\x0b\xfdU3^\x98\x16\xc5\xbf\x14Z\xacUh\x86Flh\xb1=\"\xb4\x11\xa5\xed\x91q\xd2s\x0e\x9e\xd9 *PrH\x16\xe9\xf5\xf5\xe2\x9b\xcc\xd1\x08\xe5\xe5}\xac\xa1\x88e\x93\x064\xf9X@\x8ep\xc9&\x96\xbf\xfcH\xcc\xcc\xd3W\xa0D\x9br\xb2m\xba\x86\x1a\xfd\xbf\x07\xf6\x97\xafK;\xadL}D\x07AG\x03\xfd<\xc3\x8bmi\xae\xcf\x92\x9b\x9aA\x7f!\xcd\x17\x95\xc9?\x92\x1b\xe4e\x95}?\xe7\xbcr\xcd\xe0\x7f\x95\xe6\xc20[\xfdz\x1bq\xc1M\xf5%\xed\xb7e1\x9e\x9e\xd6Z\x90j\xe3\xf1U:\xbd\x1b#\xf6y\xb6,e5&\xb3T\x8d/\xfe\xf4\x9enN2Vx\xbfk4\x18\xd5\x1b<\x7f\x7f\xf6\xee\xfc\xb4\xa9E\xb1\xd3\x9b\x9a\\\xd7\xe1\xc5\xc14\xfe\xe3\xf1\x87\xd7\xc7?\xbc9%\xe6,\xa06\xbe\x91\x08/\xa7\x8d-\xde\xeb\xd8\xbf\xd1\x02\x95R1\xc2\x12\x7f\xb7O\xba\xc2\x0e\x1e\x9b\xf1\xad\x84/\xecc\xb3\xbap\x85}b\xbe\x16\xee$\xfb\x8f\xcd\xf0\xa8\x0b\xe19kjK&b,\xfbf\xf5\x99\x18\xcc\xb3\xc0\xf7\xe2\x82e\x11Fv\xaaWYq\xfe\xdf\x1f]b,\x14\x8c\x9c\x91p\x8e\x1a\xe2\x04\xe4K\xdf\xf4ui\x94\xd2@Sl\xcc\xe3\xbc\xbe-*\xc8:\xdd}Q\xfa\x9a\x87\xca\xd3\xd5l>\xf7\x13\xacdFQ\xe2+u\x17\xc2U\x08c\xe1\xea\xda\xae\xe0\xc50\x10\x98 \x0b\xf3R\x9c\x94\x9e\x8e'V~Z\xf5tr;\x15148\xe4\x1a\xf2\xad\x89J\x88\x9fM\xd5\x80\x96{\x1b\xebk\xdf$\xec\x16\x12\xe9\xa7\xee\xc8\xe7\xa6\x9eMT\xa9\x9b\x8c\xa8\xfbH\xec\xbe\x08\xf3\x13\xf4P\xc4\x10\xb5\xaf\x15B\xdb\x95>K\x07 \x0e[8<\xa4n\xe3\xce\x85\xd8k\xbd?\x11\xdc\x02\x1d#\x8e?\x9f\xe0\x10NF3\xcc\xfas2\xf2\xfe\xfd\xdf\xcb\x8d\x85\xafn8>\x9d\x8cn.\xed/\x8f\xe1\x10>\xa1\xc3\xb4\x7fC\xdc|\x9d\xc1!\xdc\xc0\x11|\x86#\xb8\xf5=\x96\x14Y\xccr/\x80!\x1c\x97~\xd9\xf6g\xe8\xd4\x85\xb1&\x84~\x1f\xfb\xef\xc9\xafyoF\x82@\x8e\xf5\xefQ\x1f?\x86C\x98\xf8\xefeT6v\x0b,\x08\x02\x8c\xe5i\x86\xbc\xe2\xd5\xc7\x98\xb3\x13?\\\xf8\xe3\x10N\xe55\xb7\xb8\x93S\xa8\xa0\xdf1\x8c%\x94\"^}\x16\xc24\x08B\xf8\xcc[\xc0\xbc_\xe5\x02\xf1\x1e?\x89X \xbc\xf5s\x19i\xf4\xb8#\x95\xf9T\x05c0\xb4i8\xba\xef\xbf\x87\xadk\x0c>\x8f[}\xeb\\,\x90\x1a\xda \x0e\xed8\x08a=*\xb8\xa8z\xcc\xff:\xe5\x7fMC |\xa49\xfc\xee\x9c\xf6ObNC\\D\xbej\xb7\xbe\x9a\xa6\xe3\xaeS\xc4Y^V\xd5\x91n8*\xcbU\x1d\xc2\x19\xb1U\xe0\x9a\xdeV(\xd8_I\x1f}\xfc\xff\x84O=\xe6S\xbf\n\xe1ntuI\\\xa8\xa2\x03x\xea\xa7\xbd\xf7\xb0\x0di\xefG\xf8\x1d\x08o\xff\xf3\x00\xe9\xef\x1d\x1d\x80e\xc3(\xf7\xfa)\xb0\x95\xf8\xfb\xfb\xa8\xd5\xddJ\xfc\xc7\x83\xc0\x9dQP\xf6\xf5\x04\xb6\x0e\x1d\x829?\x80\x0f\x02\x99\x9f>\x04/\xb2ds\x10\xc9w\x86\xedDL\xf5f\x83\xdc\xc0\xb6^\xe5\\!\xefg:\x07\xdaxLG\xc9|B\xe5\x85\xe1l\xc1^\xe0[9cd\xb0\x8d\x83A\xe0{\xafO\xc7\xef?\x9c]\x9cy\xf7\x0e\xb0\x11\"g\x92\x92\x894\x84\xc2\xd2z\xbdp\xc5M\xc3P\x82\xeb\x00\x12\x0ci\x89z{\x7f\x8d\xb0\xc0\xa8\x902\xc4/\xf1\xe1\xf32 \x0e\xbc\x84\xfcy \xbf\xe3G\xc0(\xdf\xde\xbe\x14f2\xff\x1d\xfb\x0bl\xed\xcb\x97\xaa5\x1a=\xcd\xa8\xe2\x9d\x17hw\x10\xf4T\nb\x1a\xa4\x99\xb8\x8fP\x95d\xd0\xdd\xcdzq\xa1\x01u\x0bb/\xb5\x8d\x0e&\x1d\xa7GN\x06\xd3\xac\x07\x8btj\xe4$\x8a\x08\xcdy\x8ca\xe8F\xf1%\x0c\xe9\x13\xc1\x0en\xaf\x07 \xad\x97\x1e\x19\x91\xef\xab\xc3hX\xffL\x86\x88:\x82\x08\x86T\xe4\xf8\xce\xd0\xdf\xdb#\xa0\x9f\x8d\xbc\xf1x\x92fl\xe7/\xf98\x9fG\x19\x9b\x8e\xc7\xe2\xa8\xf7]e\x87\xf0\xb7\xaf\xad\x1b\xcf\x01\xd2t$r8\xfa\xa9\xd0\x9c\xfe\xedk\xd02\x1f\x17=\xbd\x9fF\x91%\xeb%\xcb\xb8\xf04\x84-\x7f\x00\xdf\x03E\x01\x94\xf7\xb4\xaa\xb7\xeb\xa8w\x9b\xc5\x85\xaa\xb3\xef\xa8\xa3\x14#\xb5\x82o\xba\xd8\xa9Z.\xb7\xef\xfe\xe3\xc0\xdf\xd2\xb5\xd4\xfc\xddA\xe0\xcbh\xbf\xe0\x89?\xbc\xa6$\x1a\xa8g\x1e\x17p\x08\xd2\xa2\xaeT\xca\x8f\xe3\xfa\xcdG\xe8>U\xf8\x98\x98L}/\xda\xb3!Rj\xe0\xc71I\xc5\x12xyXQ\xc6#b\x15%L]<\xe34M\x98\x9d\xe0\x15\x86\x18\xcc\x0d2\x91\x7f\xa0\x9a\xdb\xf6a\x19V\x8f:Feg\x04\xaf,\xfb\x19\xd4\xfb\xd1\x10z\xc3cr0\xa0\x03R=\xde\xbb\xefv++4\x05\xd3\x8fC\x88\xc4y(\x17>\xf5\x0bS&V\x0f\x1e\x05~\xe2(\x15A\xa6]\xd1\xd2\xe4\x98rx\x01}\xe1\xd7\xfeR\xb8V28\x02\xcf+\x85\x00\xbeP1\xb6\xa4\x05/\xcc\x83\x00^\xc0\xe3\xc7\xbb\xcf\x0e\x90\xbd\x83\x97\xf0\xf8`o\xf0L4\xb4\x0d\x03\xe9\xa8\xc9iKd}\xcc+\x88\x06\x0e\xf6v\xb1\xf3\x887\xf0do\x7fO\xf6/\xeacG0\xc44H\xe2m\xbe\x88'\xcc\xcfC\xec\x04s\xd5D\xb0#\x9b\xd9\xe6\xe3\xdc\x91\x83z\xf1\x02\x06\xfd\x00\xb6\xe1\xe0\xf1\xe3\xbd\x83_v\xb7\x9b\xfa\x11\xa9\xab1\xb1G\x86-3\xe9\xbeT\xd5\x98\x1a\x9c\xb5\x0c\xf1a\x9e\xc6RWs@\xebj\x06\x96ng\"\xeb\x9b\x83\x94\xca\x9a'\xffT\xd6\x10\xcf?\x955\xfa\xf3Oe\x0d>\xffT\xd6\xfcSY\xf3Oe\xcd/\xa6\xacqjj\x06duw\x18\xd1\x03\xc7\xdd\xc9\xe3\xbe\x83o\xd3\xc2\xb3w\x12DQ\xfcL\xdb$\xa5\x0d\xf9\xca\xb7Q1\xef-\xa3\xcf6\xcf J\xe2\xa4\xc3 \xe9\x18\xb0d\xb4\x19\xf2\\}8\xe2b4l\x83\n\xc2\x19\xfb\xcc\x88\xc9\x0f\x1b\xac\x8f\x9e\xc8#4\xb2\x96\xc4\xb9\x9e1c%_\xbf\xceOK\xb9/,\xd27\xe9$Z0)\x1b\x95)Qpo\x9c\xcd\xbc^\xbeZ\xc4\x85\xef\x85\xde\x86\xec\xfb\xde\xde\xaf\xa2Dq\x04\xad\xdd\xa5\x95i\xc8o\xe5+6A\xfa}\x8f\x15\x95\xea\xb2H.hk\xca\x14\xcd\x13,\xc2CH\xfd\x16Q\x923?\nF\xf1e \x13\xef\xa4z\x92\xf3\xeeh-b\x17\x87J)h\xddR\n^v\xff\x89 \xab\\nL\x07/{`\xf2\xc4\x13Zs\xc2Y\xd9\x89\xca\xcdl\xb3\xb0\x93^\xce\x8a\xd7\xcb%\x9b\xc6Q\xc1l~u\xd2\x9b,X\x949j\xcc\xb1\xc6[a4\x7f2\x8f\x92\x84\x19~\x867X\xe3U\x9c\xaf\xa2bb\x98},m\xe5\xe55\x11\xca\xe7\xae\xed@CA\x1e\x0ea\x9b\x9fe6I\xe6'\xcf\xb5\x99:\x85\xce\x90\x01\x9a\xe1\xc5\xb5\x93\x9b\x95A\xd2x\x85\x10\n\x9f\xf0 \xa8\xbd1\xa6s\xd5\xcad\xdf\xc9\\ \xc2Q\xa5\xdeV5\"<\x96\xa7(D\xae\x1a\x9b\xac\xa5\xfd\x18]\n\xad\xed\xe09D\xd95n\xed\xbcR\xec&\xcf\x03\x95C\xa3,\x1d%\xdb\xdb\xe6I'\xf7\xcf\xf5h{{y\xd9\xb6\xd0\x02(\x7f\xe5\x0c&_\x87\x9b^\x92\xde\xb6\xb6\x86\xb5\x9c\x0d\xcd\xe1H(\x13|$\x93\xec\x16\xe6A\x8f\xd3\xbd\xdd\x10R\xfcc\xd0K\x93*\xb4\xf9\x95\x08T\x1f\xf9qo\x95\xe6\x85\xdc\x85Hk\x06\x18\xcfi\xd2\x8b\xa6\xd3\xd3\x1b\x96\x14o\xe2\xbc` C\x9aN.\x86\xd6\x00r{\x93^\xbc\xe4=\x9e\xa3\x17P\xceG\xd6<\xb5\x89>\x06<@=/\x04\xefw\xf54\x07\xf6\x88|ON\xc8C\xaejK\x8c\x1c]\xa5\xd2$c\xd1\xf4\x0e\x03\xee\x89p|(]/|O\xf8&a\xaa\x15\xf7\x88\xf2^\xb4Z\xb1d\x8a\xf9\xe8}\xed\xab\xa0g\xb7\xdc\x86\xc3y/c\xcb\xf4\x86\x89\xc6\x90g\x0e\xcb}\xea\xf4\x1c\x80\xa6\xcc\x959+.\xe2%K\xd7\x85\x86\x11\x9c\xe9\xa8\xbe\x0f\xeaF\xb3\xd6\xf7V\xa4Y\xa4\xd5C\x98VM\xe0_]\xb9\x15\xf7`\x1b\x9doh:\x8a\xeaF\x9a\x1f\xbf\x19\x02k'\x9b]\x1cv\xdc]\x13\"\x1f\xc8\xae\xdb:n\x81\xde\xa6\xec\xce\x13:D\xff\xe0I{V3G\x9e\x8f\x0cie\xea\x17vj8\x91\x90\xa8-\xb5q\xdc\x9b\xb9\xb2\xfe\xfa\xfd\x10\x92^\xc6\xf2tq\xc3\x02\x8cl\x8f\xa9\xfc\x96\xb1\x96\xdfjC\xc0X\x10\x10\x80yF+\x01\x91\x0dDg\x86v&\x90\xe2\x00\xe9|\xf3\x98\xc7\x8f\xcb\xc9Z\xdaT\x91wF\xb2x[[\x9c\xc9\xf3>\xb0\xeb\xd3\xcf+\xa4\x8di-%\xe6\x86s\xb6\xf8<\x95\xb0\x81\x9c\xf3\xe3{\xe1\x82ZN?\xed\xc9\xab7\x11\x9aA^\\\x89w\x9cK\xb10>\"\xc2\"F\xd2A\xc0O\xf0\x161\xeb\x9d\xa3C(\x17ac\xb7\x05\x00\x88l\x9e\xb6\nA&\x8c\xf1B\x88\xee\x0d\xc4g\xae\xdb\x84Zf\x97Nr\xa9\xa6\xeb\xc9\xea\xc9\xc57\x1a\xd1\xee\x9eC\xa69\xd8Cyc\x12\x15\xbe'\xf8)O0\x1dB\xc2\xab\x875\x9e\xd5\xeez5\xbe\xf4]\xb4d\xbf\x8e\x9c\xbdk\"\xa2\xdc\x934~Z\xe6\x0fR\x9aylj\xce\x854c\xdd\x9eKaf\xcf\x14Z\x16.@\xbc\x92\x0e\xc8\xba\xe4&\xe0&lS\x8e`\x01- peF$\xcc\x98'\xae\xf9\"\xbf\x90\xda\xb7\xd2\xccL|`\x1eH_\xad\xaedN\xa5\x92\xf4\xa6\xfeV\xd6\x9bii\xfdB`\xa3\xe2\xb2m\xc5\xcc\xe5Jp\xa7\x96\xb1C\x1el;\xa8D\xae\xf8\xc9\xa5\xe0\x8a-~\xa6\x13R\xb9Y\x94\xd2\xdd3\xf1\x1f\xef\x99\x18Ty\xeb\xd4\xfdr\xbat\xd9v\xed\xf4\xec\x80\xde\xa4O\xcc\xf7\xb1c3\x08\xf4\xb6\xac=\xe4\xbd\x93\x95tGS\x94Ey\x1e_;\xd4Q[\xb8\xb5[L\xaa\x944KE\xb4-\x1c\xef9\x92\x9c\xdf-\xaf\xd2\x05\x15[\x06\xb9\xe9\xe8j2e\xb3\xeby\xfc\x97O\x8be\x92\xae\xfe+\xcb\x0b\x8f<)e:\xd1'!dJ\xbf\xe4\x05\xbdY\x9a\x9dF\xad\xd1\x1a\nq\x86\x18\x0e\xadA(,\xc4r\xe1l\x1b\xf0\x0e\xca\xf3I\xdc\x95\x89\xa2\"\x08d\x98L\x0f\x93\xeeVn\x16_\xeb\xcc~\x9b\xd7\\\x84{\x9e\xc3\xdc\x94rC\xa49\x83PFK\x9f\x85\xa8!\x89{\xb3\xe7\x90\xc3KX<\xb7\xf9\xd2\xb2\xe5\x95\x90=\xd7\x9ap\xbc\xe0\xc2q(\x14!\\\xfe\xf3\xa7\xe510\xf1\xa7B\x98\xf1\xa7A\x88\x8a\x90y9\x86\xa5H\xc2u\x03/a\xf9<\x00I&\xa6!\xead\xe6\xa3eiQ\x95\x8cV\xa8S\x1f\xad\x1c2\xb8\x96a\x0d\x86\xdd\xb2J\xb5\xed\x9eA\x9f\xe6\xd7\x06\xa6nI\xec\x9e\xdd\x03j\xf7\xf8\xbc\xe0\x80s\x8f\xfe`\xf7 \xa8\xd9{<\xc5\xd7\x8f\xf7\x1e\x93)\x1a\xd6\xd4\x98\xa1t\xd7\xcc\xd2U\xae\xb9\xfdV)\xd4\x95_o\xc6f\xb9\xcc\xe2\xc7\x7f\n\xafh\x9c\x19\xea\xef5Jc\xf7\x9d\xff\x1d\xfb^\xd4\xdd\xa8\xd7\x9aof\x9c\x7f`\xd1\xa4\xd0\xf3\x10\xf2\xed\xa2W\xc9e>\xfd6\x9e\xb1\x8c\x85e\xe4\x82wg\x89\xc7\xbc\xbe[\x87e\xca\xf8\xa7\x8f\xbd\xa0>\xbf\x9e\x91\xd3\xbf\xbc\xaf\x0ceD\x05\xa2\xae\xcab\xafR\xb7\x85\xe0\xa9)\xd4u\x06\xfa$gi6a\x1f\xed\x00\x01\xe4j\x19\x1d\xfeX}\xab\x04x\xd6qp,\x04O\xeb\xba>\xbeE-\xab\xf1Z\xcfj\x9c\xd7\xf3#\xb3[X\xd4^\x1a)\x97s.\xd3\xe5z\x03ZkA\xfd\xcb8\x7f\xbf\xce\x98\x85\x15[\xfd&\x95AY\xd3r\xe5\xe2\x8di\xa5\xb9\x86\xa8p_\x82\x92\xf8\xcf\x02\x9b\xbc\x18\x0bc\xf5l\xfe\x90\xae\xafa\x861\x0c\xba\xfe\x07\x91\xcb\x13q\xb5k\x1fjk\x10\xf5+X;nb\xee\xbf\x04\n\xe8z\xc2\xb0\x07n\x9aT'\n^\x84\xef.\xf1\x17\xdf\xb8\xf5_\xbe\x97q\xdc\xed1q\xaf\xe4\xa1\xc9\xf0A\x7f\xd0\xdf\xfb\xc5F\x9a\xf8\x8f\xf7\xefm\x9d\x86\xe2\xd6\xd6`C\xd6\x98\x1eP\xed\x82\xf0\xfc\xf4\xe4\xc3\xe9\xc5\xf8\xd5\xd9\xf8\xdd\xd9\xc5\xf8\xfd\xf1\xf9\xf9\xf8\xe2\xa7\xd7\xe7\xe3\xb3\x0f\xe3?\x9d}\x1c\xff\xfc\xfa\xcd\x9b\xf1\x0f\xa7\xe3\x1f_\x7f8}\xf5\x0d\xees\x0f\xe65O\xc1u\xd7\x12\x0f\xa51\xe0\x01\xed\x92\xf7\xd82\xd0\x92v^\x074\xc3\xbd\xfb\xe4q\xdd^\xf4\xc9\xbe\xfe\xbb\x87)\x13=\x91k\xfe\xbcH3\xe65\x98}\xaa\x05\xed]i\xb3\n\xabV\xd2\xe5U\x9c\xb0\x0fl\xba\x9e\xa0\xd7gkKi\xcd\xdb\xa0j\xe9*N\xa6\"\x8c\xd0 \x1fY\xda\xa9\xb1\xd8\xd1X\xb4Z-\xee\xde\xc6\xd3\xe9\x82\xddF\x9d&\x189Z\x9ap2\x9fwia\xbd\xb1\x1b\x85\xe3 Ps\xe8\xd0g\\\x1bs\xd1\xd3o\xcb\x80\xc9|\xb0V\xf46\x8e\x8aFJO\x92.a\xf4\xb3\xda\xad/\xe7\xb1\x11\xf9\xc4\xb5\x98(38m-\x15\xf1\x16\xff\x88:\x9f0\xa5/\xc5BED*\xe5\xd3\xcf+\x8c\xf9\x00\xc5\x9c\x01K\xe6Q2a\x19\x14)\\1\x88\xca\xe9\xf6\xa8\xe8\x8ajq}\x16\x08C\xd9Z\x0d[+A\x8e\xa9h\x1bS&\xb0\xbf}H72\x99/\xa1g\xc6{j\xfb\xf5\x84pM\xe1\xef\xf1\x9e\xda~\xbd\x92\xa7W\xad\xa0D\x88)\xa9\x8e\x9c\xe1\xda\x8a\x1c(\xe2\xfa[X\xc6\x06&\xb0\xe8F\xe7MVS\x8bNM\xdc\xd0L\x8csAX\xd3\x82,\xd4\xe5]\xebj\x80v}M\xa5O\x95s\x98\xfaA\x08\xb32\x9a\x8dU\x0d\xb4\xa94\xda(\x8a\xd4\xdb\x0d\x15@\xea,\xb6\x06!\xef\xd5\x1e\x91\xfe(\xd9}&\xb23\x9f\xd9W\x14\xe63C\xfd\xc4\x84\xf9I\x08\x03\xda\x8a\x0b\xac]A\xbfu\xad\xe4\xd2\xbd\x92[Y/B;\x02k\xe9d\xf08X\xae\xf3\x82/\x19\xc6\xe2\x05!x\xe5=\xf8\x983\x98\xac\xf3\"]\xc2\xb2\xa4\xe8\xa8e\x88\xf2\xbbd\x02\x91\xf8\x9c\\^#-:\xeb\xa1l`\x0d\xe1\xdf\xca!Dw\x98\xb2}\x1e\xdd0\x88\x12(\x83\x1d\x83\x87jiPvG=\xf8\x89W\xb9K\xd7\xb0\x8c\xf3|\xc5\x16\x0b6\x85\x08PD\x89\x92\xe2\xe8\xdf\x1c\xa3Y\x11\x00P\xa7g\xd9\xfdT\x1a\x804\xce\xcd\x1dFs%E\x1bNSr\x7fA\x9a\xc2~\x85Y\x9cD\x8bEc\x1b\x03\xfb3\x9b|\xe8\xf6\x12\x9c\\\xcd\xc4\xd9 \x93\xa6k\x89\xe1\xb7\xb7]\xc8\x7f#3\xb6\x17\xa3\xc4aD\x92\xb6^\x80\x82\xa6\x92\xfb\xce]m\xe9\x0c\xc8\x15\xf7^\xbf{}Q\xff\x94V\"\xadI\xc3L\xb5hd\xec\xf1|}\x95O\xb2\xf8\x8a\x91\x11\x96\xafKq\x87\n\xf5\"\xe4'\x89$m\x92\x1f\xdc\x9bp\xf2\x93,a\x9f\x8b\x0f]O3\xf5H\x1d\x0f\x05Y\xf58!\xac\x1e*Th})BX\x8f\xd2^\xd4j?sS\xf9)\x11I\xacu+Fz\xb8\xdaJ\xb5C\x1a\x14\xb4 5\x91\x0e\xeb\x8b\xbb\x15\xa3\xe0\x9d^\xc9t\x89\x12\xd8\x8a\xec!\xac\x9d=\x96\xe4\xb6\xddJ\x9f\x95\xf6\xd4\xe2/\x7fn\x9e\xeb\xfaC\x93~@)\xa2\xe1pQ\xa2Ma9\xc3\xeaO\xa3\x0d\x82z\xd6\x89\x06\x7f;l\x90z\xba\x9cQ\xf8&\xe8\x843P\x0d\xcf\xf2&\x01\x81|\xcc\xc2\xc6\xf2\x05\x11)\x87\x0b]\xb4K\xecc\xeb\x0e0&Q\x91\xef\x94!x\xff\xfe\xef\x9c\xb9\xfc\xfc\x88\xff\xac\x07\x93\xff\x06\x89Z\x17\xf1\x1d~i\xd6\x9d\x8d\x14E\x1f\x9bWB\\\x1a(o\xc7\x84\xd8|I\x84\xc2Qfk.\x9f\x87\x9cp\xfa\xad\xd7\x10\x1eh\xa5Mo\xad\x8c\x1f;\xb9a\xb3X\xaf!\x92\xb9\xe2\xb5\x81\xe8\xa6v\xc1\x1c5\xea4\x90{\x89\x91{\x01\xcc\xd7\x8a\x7fm\xa1hS*\xdal^\xbc\xc0\x1b\x93\xc8b\xcbxs\xa8$\xe6\x1cIQ5\xd1\xb7\x9bH\x90\x1d\x17\x8e\x07a\xcd:\xda\xb3mY\xc8\xa3\xca-\xd7%\xba+2\xbe\x91\xf0I\x02^uV\xa1\xf7\x83 \xda\xe3~\xd0\x8bzB\xa3e\x82~cm\xd5\xa6\xf5\x9dkm.u\xc9\xcc0\xf2.\xacP\x97\xc7x_\xa6q9exIq\x19\xa8Y\x83^\xda\x8b/xQ\xc5\x18\x95\x08\xd0|\xda\xd0\xac\x8d\xdd\xf8\x80n\xbc\x18\xf5/I\x04)zBz\xf5k\xb0l\x18AWB\xca\xfc\xa2\x87j\x18\xc9\x80\x87\x15T\x88\x13\xc88\xec\x1fDq\xf8`J\xbc\x10\n\x15\x00\xb9\x8b\xf2S\\\x10\xd5(\xb7&}\xc0\x11xq\x12\x17q\xb4\x107P\n,*\xabr\x91\x82\xae\x9b\x83!\xa6\x1c\xbf\x89\xd3u.\xd3)gl\xc2\xe2\x1b6\x85\xab;]\xffP\x8b\xec\xaakM\xcb\xd1w\x81e\xb5g\x9f8\x9cQ-\xdb{y\xb1i\x1e\x19\xca\x84\x9frG\x1d\xc0#\xd3\x98]\xb8Q\x1cA=b\x02\xe5\x90\x86r\x0d\x1cA^\x1e\x07e\xc5j\xf5)}5GJ\x8a\xba\x13y\x06\n\x97Q \xaf\x1f\xfb5\xcb\x95\x82KXh\xc3kW\x8d\xf4\xaa\x0bL\xee!\xe8y\xc0\x17\xd6\xa3i~A4\xa6\x08z_\x18\x9fp\x1c\xe3@,\xf8\xaf\x9d5\xc7\xaa\x9d>G\x96d\xb3\xadS\xed{\xa7\xbd\x9c\x96\x0f\xa8\x84\x0e\x9e>\xe2\x08\x92\xb6t\x87\xa5G\x1f\xbe\xae\x0f^_\x0cm\x80Ay\xb6%\xfe\x9e2\xf0\xde\xdc\xfc\xb6\xcd\xbcag l\xbf\xe5\xa9\x8b\xb6\xf4}\x18j\xb1\x01\xd2\x92\xb0g\xc1s\xd8\xde\xe64={\x1e@*\xe8y\xe1\xb3Qr\x89\xcaT\x87\x1dh\xba\x19\xd4\xb5\x83\xf1\xc9A\xe0{E\xfaq\xb5b\xd9I\x943\x97\x15'}Hv\x02\x0eqA\xaf\x06\xb0C\xd8\x1c\x8bh\x97\x94\xaf\x7f\x81>_\"%\xc6!\xec\x14\xf0\x12R \xcb\x14\xb6\xd1h\x0b]\x81\x12Y\x90r|\x0c\xca\x8f\x12\xd8>\x844\x10\xe0\xe6\x1f'\xf2\xe3\x04v\xf8\xef\x97/1v7\xff\xe3\xd0\xcczU.h\\.U\x8aK\x95\xc1\x0bH\x9f\x07\x10\x8f2\xb4\xa5\x19e|$\xf4a\x17\xb7\xac\x92\xb9D|.\xc2\xc2\xd5\xf7F\x7f\xfe\xf3z\xb7\xdf\x9f\xfe\xf9\xcf\xeb\xe9\xd3~\x7f\x87\xff?\x9b\xcd\xfe\xfc\xe7u\x7fO\xfc\xec\xef\x1d\xf0\x9f3\xb6\x8b?glw\x86\xdfL\xf1\xe7n\x7f&J\xfbL\xfc7\xbb\xdc\xdc`W\xce#\xe9\x15,/\xdaM\xcf\xbabG\x08\x19\x85 \xa9\x03A\xe2\x86\xbdD\xac\x1a\xdee\xc6\x12\x03\xf8\nmo\xa7\x97\xb8v)\xbc\x80\xf8y h\x9e\xcfw\xd7(\xbdD\x0f0\xc76\xdb\x90\xb8U\xdbl\xf0\x9420\xae\x84\xf1J\xcdA\xc6\xd7\x8fI\"\xe3\xd6\xb3\xa0\xe1\x9a4\x04)\x9c\xf6\"\x05\xad\"H\x89[\x83\xa4M\x84US-\x99,ZQ-v\xde\x11(\xdeLXldhx5\xea\x13\xa6\xcf\xa0\xd6[\x04*\xb7\xc5{<\x0f\xb9\xec\xe5\xa7\xd5A\x17c\x1eHs\" \xc7)r`\xd7\x07`\xd7,q]e\x00\x88{9o\x14/\xb4\xbe|A'\xc1\xdaG_i\x94)\xbfO\xd8\xad\x1f\xf7N\xf0\x17\x97\xe38\x0bo\xe0\x13\x7fT\x15\xcc\x8e\xa0\xef\x9ax3\x94\xb3ng\x05\xfbd\x19\xf5\xc6\xba\x04}\x9c\xdf%\x13%,\x9b\x82tM\xd6vUZ\xeb\x95~\xcf\x12\x116\xc0U;\xd7k\xbf\xcf\xd2\xcfw\x97\x8e\xab\xf7\x16\xf9\x18\xad\xff\xdb\xc4\xe1\xcc\xe5F\x81\\\x0c:\x95\xe2_\xeb\xf2\xaf\xb8\xfc\xab\xcd\xc8\x86\xa2\xdd\xb6\xd6\xa1\xc52\xb8y\x92\xa5i\x17\xb5\x01\xdd\xeax\x0d\x11m\xff'\xfe\xb4d\x86jmY\xf8\x8fm\xd2\xecWj\x11\xf4\xd4\x10\x1b\xa2\xfa\xa0\x1f\xf8\x89\x7f\xb0\xff$\xd8\x88{ih\xd0\xdc%b\xf3\xec?i92\xcbKo\x19\xfa\xc8q\x80\nv\x15\xad\x0c\x95.\x06\x8a\x92h\xab\xa2-\xe53\xb4\x95\xfa\x89\xf0kV\xf4\x1c#\x02&h\xae\xaa\xf7\xc7x\x97m\xa7r\xc3\xacim\xdc\xee3\xda0\xe4\xc0\xca2\x14\xa1\xb1n\xed\x15\xa7\x07\xbbm\xd8\xae\xd8\x80<\x84E\x08\x13\x8a\x19@g\x02\xf8\x9e\x0c \xaf1\x8cv\xa9\xc8\xa8Dq\x07x\x1f\xc6\x019E \xfb3@\x1f\xdd\x97\xb0j&%\xc2\x8f\x9a\x9f0\x94nm\xce[\x11\xc5\x9a\xe85\xc7%\xb6\xdb\xbaq\xf08Kq\x87f\xbd\xbf\x96`\xe0\x12\x17?\xb63B\xf4\x04\xc5\xf9\xa0\xbb\xb8\xa0N\"!k!dE\xce\xfb\xdc\xc0\x0bX=w\x1d\xe5\x98\xa7\x96\x8c\xef\x02\xd2)\xba\x18\xdd\x10we\x1c\x00y\x80M\x8c\xf9\ns)\xd9\xbf\n\xe1\x0eC\x1d\x15\x88\xa1\x13\xcc\xca\xe8\x8b8F7\"\x9d\x13\x7fK\xb7\xa6\x99r\x8c]*\x1f^o\x1c`\xea\x9a8Y;\x92\x0c.\x0d\xcb:\xfd\xb9\xcaX\xf4\xc9*\xb1I!:\xa77\x8db\x0b\xa5\xf1V]V\xed\x93\xd8\xbf\xc6j\x9cA\xbd\x13\x9a\x1a\xbe\xfb\x17\xd2\xcdTl\x8bIP\xe1\xd2\xb50\x06p&\xbdl\xea\xb1 \n\xe0\x84\x04\x90\xd0\xf8*\xe2\xa7\xc4\x18+\x86/\xd0\x15\xee\xa3\x85\\\xdar\xe0\x8e\xe1|\xeb\x82\x90\x87\xc8\xa4'<\xcaQCZ\xfe(\xeaN\xe9\xf8\xd7\xbd\x84\x95o\x92\xf35\xc9\x9e\xc4\xac\x9a\x98\xefT\xcc\x97\x84\xa9e>N2\xbf\xf7$\xe8}\x8c\x93\xe2)\x8a\xb1\x0fr^\xee>\xa3B\x80r\xb1\x87\xbe\xc79\xd8\xbf\xaf\xe8)\xe2\xa5~\x93/\xddSz\xac\xbb\xedcr\xeb2b\xa1\xa5q(g\xf8l\x8e0\xf4_\xe6\xc7!$\x1dp\xa4D8x\xfc8\xf03\xc7\xd6M7\xebc\xd0\xa7\xa3RqN\xcd\xbf\n!'&v\x0d\x870\xf2X\x96\xa5\x99\x17\x827Y\x08\x7f5o\xca\xf2\"K\xef0\xb0N\xb4\x16\xef2\x96\xaf\x97\xcc\xbbt\xb9\x08\xdd9\x11&\x06y\x1b\xc3a\x88\xde\xe0ROf\xce\x154\x1aU\xe8F\x86\xb1]\x0f\xbd\xc9\xc5\xed\xd3\xdbt\xca\x9b\xdc\xdab\xda\x0b\x19Z\xd9\xb7\xeb\x99o\xbe|\xc1O3\xb9\x7f\xce\xca\x12\xc7\x1d\xa40r\x98\xc7\xd7\xf3\x9f\xa3\x82eo\xa3\xec\x93\xbd& id\xd5\xeeO\xed\x1f\xac\x89\xd1\x1d\xc1\xe0\x00\x8608\xd8{\xba\xef\x80Bm(\xfc,\xe0S\x12'\xa42\xa5\x10\xb0\x88\xaa\x82(\x90\xd9c\xd6!\xdd\x08\xc6\xfb\x9d-\xd24\xf3\xedr\x15\x96@\x08\x8a \\\xeeo\xca\x84\xed\x18\xe4R\xcb\xd8\x1e\x8b<\xe9\x9c\x8f\xd5_\x9d\xa4k\xf4\xa5W\xf5f\x8b\xf4V\xa4\x1a\xd7j\xb2D\xa4\xc8/\xf3\xb5\xb3d*\xe8W\xed-\x87\xb2\xf8\xb6|\x85.>\xc2\x9d\x05\x7f'\x8cM\x15\x91\xac5(Z\xa3\x8a\xd4\xda\x89 \x8aF\xfbbC\x9cO\xe6l\xba^\xd4G#\xf7\x8f\xf9\x12-\xe9N\x93I*\x87\xca\xacw\\\xae^\x17\xb3\xa7*\xe3|t\x1b\xc5\xc5\xab,\x8a\x13\x0dNr\xaeo\xd3\x8c\xd5\xdb\x9f\xa4S\x96\x99\xe0+{\x13oY\xf5\x8a\xa3\xc4\x1c/\xb2\xe6\x92\x82<\x0bzBE\xf1J\xb4\x15\xd8M\xb3[\x98\xfbU#\x81\xdd\x8fVX\xc3W\x97\xe7\xd7\x95\xdb\xf3\xcb\xa4\x1c[\x88\x8b:e\xb8\xaa8\x08>\xb4+\xd2\x95\x0dG8\xce\x8c\x03\x92\xd7\x17DK\x04\xa9\xa8\xad\xb8\n\xf1 \x14\"4\x03\xcc\xebV4\x06\xdb/w|\x10\xba\xd8f\x89\x1b\xda\x87\xea\xcdaU\x1a`\x14\nW\xdcx\x07 \xc7\xd5m\\\x16B\xeab\xe9%\x17\xc1\x0c\x88\xd8`\xabL\xcd\xe1\x08\xfc\xc8\xd8c\x9d\xf8\x04\xd4\x8d\x8b=\xac\xd6\xc9\xee\xa7\xaa(\xf1\xcc\xd5\x1ah\x9c{Y\x99\xb7\xde\xe4b\"\x94\x01\x8a*!\xd4%\xddRy\xd3\xc2*\xb1\xd06o\xb8N}aX\xb1\x91d'\xf6\xed\n\xa0\xb9xI\xb9\xfa!\x9c\x93\x97\xf7\x1ct\x11\x86.\xf2\x91f#\xbew\x82+B\x81\x9es&\xa2\xe4,zq.\xd8'?\x13\xce\x07\xfa\xb6A\xcd%e\xbb\nztn\xa5*1NKa\xa8W\xf7Mz\x9d\xdcD\x8bx\nI\x9a\xec\x88f\x1f\xc9\xc3a2_'\x9f<39\x9dz\xf0\xb8wLDnk\x02n\x11F\xb0\n!F\xe1\x93\x13p\xbf\xe4bb\xcc\xc7c\x0cY\x1a\x9c\x96\xf1\x97\xfb\x1c\xa3]\xf37?&\x93\xc5qi\x16\xb3\x0bi6\xc7\x1c6\xcdv\xde\xc6\xdc\x16\xbdY\x96.i\xdc\xc0 f\xfc\x94\xd6\x8f<{\xbe\x9aC\x9e\xe0({\xeb$\x9f\xc7\xb3\xc2\x0f \x9a\x15,\x03\x96L\x81\xdd`\xf0\x8f\x00s80\xb48\x10!\xfa\x10X\x02U\xbb\xb4\x8d[F5|z\xf6\xa3h\xd2\"\x0eQyd`nK\x0em\x8c\x0bXn\xda\xdb,\x96\x97{&\xb4\xa5\x8e\xaeJ\xf5\xa5\x8fw\xc0{\xfbT\xed\x9bz\x99\x0ci\x8c\xe9\x9ej\x03\xa2\xb0\xcfT,\xb6\xad\xd5\x16\x93`\xe2$\x84\xd5\xb9 \xdc$r\xc0/L\xe6\xb0b\xba\x98\x93\x8e|\xf5\xcd\xf8\xe3\x0e\x1a\x7f\xab\xd1xj\xc0E\xc9E}\xff=\xd4\xddEp)\n\xc1\x16\x1d\xf1)\x88\xb5\x9eFE\xc4\x97\x1ac s\xa0\xf9}\xb1\xa6\x1d\x89\xa2@\xd2\x92\xa6*\xe4Kx\x1b\x14\xa5\xad\x01\xee\xfb\xef\x914\x06\xa1XT3\x10d\xed\x17\xed\x94q\xa5\x87q\xf2J\xc6\xeb\xdb\x93\x9f\xea\nc\x82\x7fP\x01\xad\xea\xaf+\xce\xcf^bB\n\xae\x8d\xc7\x89\x80\x8e\xee\xfd\xc6\xfe\xf9 \xdf\xee,\x13\x82\x06\xbf^\xc5\x88,\xd5\xdf\xf5\n\xe3u\xa2\xd7)\x7f\x19\xb5\xaa:\xad\x87\x99\x90\x06\x10;\xd6\x8b\x05G\x10+\xccw\xbdq^\xb7K\xc37\"EE\x06\xe4\xf29\xc9AVG\xf4\x04\xcfoC{Th1\xdb|\xa4kxld&7/r\x15eu\x86\x9b\xa1;\xa1 \xfb\xc2\xba\x07U\xac\x9e\xf4\n\xc3\xa0\xa9\xe3*\x1c\x1a\x126;\xfcH\x1d&r\xcf\xb5\x9e\xe4\x97/_\xc2\xa0\xf6k\xb7\xf6k\xbf\xf6\xebi\xfd\xbb\x83\x10\xd8\xf6v`:]\x83\xe0\xb6\x03T>\xbd\xa8q\x17\x0c\xe7\xab\xa0\xa9\xcf\xbc\xb04\x06\xfd\x10\xfa\x1dc\xdb\x9c\xd3PPW*\xed\xc2\x97\xdd;\x97\xf3-e\x05\xc7\xfa\xa9\xef\xf1\xd7\xea\x9d\x17V\x8b\x1eP\xdfH\x9d\x88\xe2\x04\xd2*\xf5\xc6 \xba\xa3\x0d\xe1\xa4f\xe6\x02\x0d\xf3<\xa1\xe7)\x87\x04j\x92\x9e\xc8\xb0\x80\x0c\x87\xfe\xee\xc2N\xea@\xf7\xf3\xc9}\x82\xd4\xf4!\xc8\x82\x9b\x1a\x92~\xa8O\xf2X\x10\xd6\x8e\x13\xbb\xca!\x864\"\x01\x0bXV\x9c\x16\x17\x10\xce\x9c\xab\\\xeaK8x\x8bx\xf2\x89\x1ag\xa7>\xde\xb7\xaf\xb0\xc2v\xa1y\xa3zB|w(\xe6,eZ\x85\x90\xa8\xd9\x96\xe8\x18\x82\xb9d\xdarn6\xa5\x8bo%\x02\x88bS\xdf\xe3\xe3\xa9m\xeb\xe7\xf5AJ\x0b\x01\xa5|\xf2\x83\xe7\x86\xc0\xe3\x1a\xe1\xdb\xb6C\xc88z\x8eDWH\x1d-F\xa9{\xaf\xe3\x98\xdeu\x13I\xfaB\xfbU\xb9\xb0\x08\x07\x16\x0c7D\xe2\x15_$\x91\x93\xa4\x16^\x8a\xb8g\x92%;\xa6\xf4\xa0\xff\xd2\x15:\x99\xd8\x93\xcd\x1a\x02)Mx\xe2\xecd\x9a\x91$\x9f\xef\xc0\xb4\x95\x02\x0d\x01 \xa5\x0dM 1\x8a\x00\x8d\x9er\xfd\xa4r\x832\n(\xa9\x9b\xd0\xfeZ\x9al\x0d\xc3\x0f-\x99\xee\xcb\x17\xa5f\xa8n\xac\xe5\x8c\x87`\x89\xef\xa2\x9d\xb0\xfc$l\xd4\x01\xbd\x16\x97\xc40\x84s\x95q\x81\x13D\xd7<%\x81>T*\xa8@k-p0\xfe\xdf\x7f\xafzq\xb5\x8d|\xb2\x0c\xd0Q\x03\x8d\x13}\xa6\xbe\xc7\xebUJ\x82\x10C|\x18Q\xae\x04\xe4\xaa\x93\xc6\x96\x97q\xfcS\xe5\xf6\x00\x0b\x96\xe7P\xcc\xa3\x04ny\x8de\x94}\xf2\xc4\xb8P\xb9\xaa\xc0\x86\xcd*\xd1\xeeH\xad\x05\xff\x91\xe2\x95\x19\xde!\xa4b\xe1\x91\xbf\x93R\xf94\xc5\x01{A\xa8}_S\xa9HM\x91\x05@J\xa3T\xd38\x9aJ\xb5@or\x10\x1a\x82\xb0X\xc1\x04WP\xae\x8aX\xdaL\x1e\xf1}8*\x05\xbc\xa1<\"\x8f\x1cz-\xfe\x7f?\xd0u\x7f;\xa8\xec$gQ\x02\xd01\xa3\xa4\xdaJ\x9a\xc2C\xe2\x8f\x1a*\xea\xc6\xcbk\x94\xda]\x14?\xb0\xea\xa7\x9b\xa1 \x1ew\"(Z\xc3\xc4\x85\xa6\x80x\x00q\x8e\x81s\xe3\xe5JdH`6\x1d6n b\xcc2\xd2\xca\x8c\x96\x82\xd6\xf7B\xb8#\x8b\xa7Y\x14'^\x083\xb2T\xed\xcf%Y*g\x17\xc2\"\x109S\x8d\x8f\x13N\xaa'\x0deWd\x99\xa467AX\xc6\xbd\xde\x8au-!^\xeb\x8fo\xb3\xb8\xa8]\xbcn\x99/\x91\x08\x96\x9f\xcc\xa88\xb9_\x1b\xd6w\xe2\xbc\x8a\xc6\xb5E\xceP\x18\xeeM;\xc5\xb2\x8e\xeb\x06#\x1a\xef\x8b\x04\xf2\x8c\xab\x8cQ9^\\X\x17\"\xea!|\xeb\xc9X\xc6\x02\xc6\xd5.\xa0A\xac\xb20Pes 24\x00\xd4\xb2!8O\x05\xc4$1\xc1P\xb6\x14*j\xc5Jk\x1c\x8e\xbeBt\x91\xd1@k\xe4\x12\x1d&%qW\xa1\x0ej\x15^\xc2\x80W\xda\x11\xcd\xbe\xf3+\xfa/x\xcc\xad\x95b\xa2f\xd1\"g\x80\xddB\xc6\xf2U\x9a\xe4,\x04ek\x9e\x98\x17\xb0\xb5%n(\xdd\xde\x96\x93\xeb\x8bl\xca\xbc\xbdMw\xe3\xb2\x05\x88\x8aT\x15A\x08W~+5\x13\x08'\x10L\xbc\x17\xe7\x82\xc1\x98\x10\x11!\x9a\x06y\xed\xdcV-\x84\xf9\x8a\xa4 \xee\x8e\xee\x9ai\x93l\xbb\xf5\xb8\xd8\xb4\xdb\xab\xa6n\xab\xc3.\xe9\x89\xbf\xbb\x9d\xfdJ\x9e\x15;\xb1$\xfed7]o\x07\x00\xac`n\xba\xb1\xef*c+\x96L\x15P*/=\xb3D\xe4\x98iP\xa1\xf7\xc6h\xc2\x97\x0b\xe4\x91?F\xc5%\x1cA\xe4\xeb/\x02\xb4\xe3\xab~\xd7-\xb2j\x9f\x1e\xc2( k\xaf.\xb1\x8a\xf0\\J\x1c\x04OCeu`\x8b\x03\xa5\xce\x1f\x88w\x06W \x90^\x9e3|3\xc7%\xa1\x95w{\xc8\x8aU7r\x89\xbc\xcd\xf3\x03\xebR\xdf2\x82\xb1\x18\xf3&\x9d\xd5F*\x03\xf7\xdaWL\xd4\x90Jz\xc1\x1f\xc2\xc9%\xd6b9\xeb\x1c\xbdR\x11\xce\xe3\x9c\xfeh\xe0\xfe\x88U\xcc\xa5,\x87#lIXq(\x89Q\x96\xe1Qi8f\xd8^\x19\xfa)8\x90\xd6\xf0j\x11KvA\x18\x13%R\x92%p\x18\x9d\xfd\x9c\xfcB\xe9\xf0#\x0f\x0b'\xa8S\xa8\xcf\x9c\xde,\x9b\xce\x8an\xa5\x163\xb4\xff\x1cb\x0c\x15\n\xf1\xf6v\x00\xd9(\xbet\xc1\xa0Qak\x19\x0e\x01I\xa6nd\x9c\xc3w~Q\x9d\x9f\x0d:8D\x89H[l\xf9\x99\xca\xd9\x13\x850\x08\x0c@\xec\xa0\xe4cc\x93d~\x14\x08\xe5_\xa3\xfe\xa5\xb6{]\x0b\xdf\xb49S\xeb\xc6\xb5Ib\xcek_Vn\x10\xd2p\x83\xc60A\xd1\x05g\x12\x94\x82\x98\xdb\x00\xadT=(\x02C\xf0l*FRe\xb3\xa2\xdao\xc1\xe5.B=\xe0]Q]\x89\x9c\x11.G|\xe7R\xef\xc5\x85\x88\xa5\xc9\xc9\x1c\x0eM\x99\xa6\xec\xca4}\xcey\xa9<\xd4\x04\x853\xb9\xa6\x9b\x1c\xabM\xeb\x1fM\xcb\x93\x0e\x0e\x0d\xcc\x08\x0dU1\xdav\xb4\x98\x19\xde\xc8@\xfb\x9d\x00]\x9e\xb9\xc6QS\x9d2\xcc`\xf7[1\x15\xa4YJ\xdd\xd0D\x19\x1fY\xe6'\xf5\x1b\x88\xf7\xa4\x01\x12\xe0\xd9*\xd1<\x08(;CC\x0f\xc5\xb9\xdb6@U\xaaV\xbe\x8b\x04\x87\x0dr\xb2B\xc7\xd1\xb0E\x82\xb0\xe3>\xc2\x83\x1b\x99w\x87\x05e\xfd\x1c\xd1\x14s\xf2\xab\x0e\xd3\xbd\xcd\xa2\xd5F\xa7\xbb\xfb8\xef|\xf6g\x8e#\xa2<\x1eR\x8c\xc7\x83\x0c\xa5\x10\xa7[\xc5^NN\xa6\xbe\xc7g\xb3bS\x90\xc2}R\xf7\x97P\xba\xf8f\xc9\x99 \xcb\x87nnP\xf2\xec\xd6\xaf\x0f\\Z3p^c\x16\x9a\xa9\xb6\x8d\xbc\xa5&A\xf2\xd6%,HW4\xfe\xe8\x90P\xc2i\x0d\x14~Z\x9b\xa3\x90SS\x8e.[\x89\xe17R*\x95QS\xafY\xef\xa7B\xa4\xf7\xcd\x0f\xb0\x9e\xb2JQb?\xce/\x0d\x04\xd1U\xba\xf1R\x90\xa4\xb6l\x806\x93\xba\xcf\xd4<\xceG\xe9%\xd4c7kR\x81,\xf4UE\x0d\xa9\xdb\x1c\xee[\xd1K\xab\xcb8\xf3/B%3=\x85F\xc7\xf5\xfe\xca\xe1\xdc\x80\xfa\x1agt]^1\"\x83\x84Hp=\x8a/\xb5\x9d\xde\xbb\x8a\x93\xa9\xa4n\xbc\xa8\xc1#\xa7\xd0\xbd)\xdb!\xa3\xa1\xd0X\xde\x1f\x16\x81\xf2\xfe\xce\x14\xe7Z\x89\x11\xf6Di\xda\xd3\xc5\xddD\x91\x90\x9ao7\xe9z\xc2\x92\xf5\x92e\xbc.\x97\x13lj\xb3\x91k\nEak\x17G\xf6\x1c\xeb\xb3C\xbf\x8f\xf1,K\x97\xfcT\x86Cx\xfb]UV\xcf\xac\x10b\n\x1eG\x82\x05C0\xae\xe5j\xb0\xe3Mti\xa2-\x1b\x90\x88\x99Q\x16\x94\n\x83\x94<\xaa\x1b\xb4,_\xc9Q\xd7?\x97~,\x1d\x0c\x8f\xee}\xd7\x03m~D\xee\xd0\x02\xe23K;M\xbc\xaeZsn:\xf4\xb2\x8e\x84\x9f\xde\x11:\xe1\x94\xd6\x9b\x1b\xf4\x83p\xae\xb1\xb3%\xd3\x93*yA9Y\x08s\x9d{\xba6i\x17\xa7\xd6\xc0\xfcF\x08\xd4?\x96\xaf\xfd\xf2\x04 ;h\xb8\xb7\xe4=\xce\x11\xe7\xcb\xf5 &bv 5(\xf3e\x1dV8(\xbc~E\xd0\x92\xfa,\x87\x9cU\xfbYzd\xb5\x10\x93{\xc3}@\xf3w\x99\x1d~\xc1\xf2\xa1\x996\xb6`\x84u\xf8\x96\xe5\x1d\x90\xdf\x12#\xb0\xca\xcd)\xd4+\x08]Vs\x1b\xc6\xa2\x9aNU\x06\xf9\xe9\x9ca\x87\x0c\xc8\x96\x95\xa1g\xaa\xfbvDd\xafL>\xabG\xcf\xca\xd9B\x04\xb5\xe4\xff\x7f\xf9\x02\xb7q2Mom\xfa\x92\xd2\xe1\xef\x91\x93p93\xd1Y.\xa0\xc4\xb4xZ\xf9N\xf5\xc6h\x89\xfd#\xd2K\x07x\xf0\xcb^\xce\x8a\x8bx\xc9\xd2u\xd1Q\xccI\xd8-\xc4~*N\xb0\xeak\x8c\x87P1@!\xe0\x00d\xa1\xa5\xb7\xc0~_'\x05\xcbn\xa2\xc5=;V\x9f\xd3=\xabR\xa2k}d\xa8\x80\xa9}\xd0*\xffH.\x1f5\xb1\xbe\xd5|\\S\x97fl\x86\xb6\x91\xba\xec=3\xe6k|\x84\xed\xb6\x81\xa4\xb6\xc6\x02\"YX\xe2\x011g\x96d\xe9b\xd1EA\xa4C\xc7g\xbc\xb9\x05\x93?_OQ\xfc\xd0_\xd9\xf8\xc5{['D\x7f\x0f\xd2\x99i\x0e\xc7{\x1b#\x9c\x8f'E|#\xb4\xaf\x91\xfa\xf3[:\xa7/\x08\xe5M\xaaV\xd5\xaeW\xc0\xcbC\x99S\xc9l\x15\x0e\xa1\xda2~+/\xcaz\xe34Q\x93\x17\x97\x12\xe5o\xea\xb6\x87p\xb9\n1\xa4\xd5n\xa0\xf6\xdcr\xc9\xa6\xb1\x08\xce\xd2N\xc2\xea_Ta+*Rh\xd5\xe08X\xb2.za\xb9\xf36\x1c\x82\xf1\x0d9\x08\xbbNm\x18\xf5\xe2\xea|\xe8\x94\xe0lc\xe6\xd9\x11S-Eeb\x9c\xebq\x88\x9a\xf1SY$\xe1\x9d\x82\xe7\xc16\x17\x82q\xbeE\xfa&\xbd\x15 \xc9|\xa7\xfd7\x1a\x11ys\xf6\xd9\xa3\x8d{D9FBj\xa9\xb0\xd3\\#\xca'q\xdcX\xe3*N\xa2\xec\xae\xb9J\x94\xb3\x83\xfd\xe6\x91L\xf2\xdd\xb6\n;-5\x8a\xd9\xe0`\xc1\xda\xea\xec\xb4V\xca\xa2[G9h\x1e\xda\xfd{\xda\\\x95\x1e\xde\xf6\x16\xaf\xefnG6,\x8a\x931\x08\x95B.\xdc \xac\xab'\xb8\"\x81\xed\x0c\xbc\xba\x90\x92S\x11x\xd6r\x11T<\x7f\x1e\x94\x03s\xb6\x0c]p\x17:\xe1\xafz:\x0c\x12\xba\xa0!tBE\xe8\x88\x8e\xd0\x15%\xd5\xa3M\x03k\xb7\xcdd\x11\x15q2h\xed\xbdq\xf7\xaaG\xf5-\xdbl\xeb\xbaq\xbbC'\xd2\x02\x1dh\x9cz\x94\xba\xae\xc1\xe8\xa9mO\x82r\xb1h\x0e\xb2\xa5\x1eN\xb3}I\xb4\xeb\xf4ZD\xa3\xd0R\xd8\xea\x0f\xa5#\xa4n&\x1d\xd1{\xc5\xe5b\xed\x989<\x94\xd1\nE\x120\xdb+\xc4\xfb\x98|J\xd2\xdb\x04\x14\x15\x18\x82\x18\xb6[{\x88V{uJT\x05v(#\xd3Q,W\x07\xb4\xc7F\n\xf6\x99C)/\xdb\xe4\xac\xd3B\x80\x8e\x88\xd1\x08n#\xd7VR\x81\x1d\xcc\xe2\xc5\xe2M\x84z\xba\xf5\xfd{i\xc4j}^\x93\xda\xbcf\xa2\xc7\xbd\x8dzlDX]\x89),\xc0\x0ea\x15\"\xe7\xe4k\x1d\x9b\x92B\xed\x17\xd6[Dy\xf1\x8e\xa1\xa0\xadB#\xf2W\x17i\x81\x92\x92\xfe\xeed\x1e \x9f:\xdd\x1f\xb0\xa6\x0d,\xff,\xcf\xaa\xc8&\xf3\xa5\xa9\xc5\x8bC\x18\xec>QIb\xe0\xe5Kx\x0c\x87\x87p #B\xe3\x9b}\xfef\xb0\x0fG\xb0\xa7^\xed\xf1W{}8\x82}\xf5\xea\x80\xbf\xda\x85#\xd8\x19\xc0\x10vv\x1b\x87\xb4v\x1c\x9fJ\x1bXM\x7f\xa7\x0e\"[\xca\xdf\xc4\x05\x1a-Ov\x9f\xf2\xbd\xec\x0f\x9e\xed\xc2\xf7\x98\x14<\xd0\xac\x99\xeaK\xe1\xfd\xdf\xff\xd7\xff\xe9\xa0\xb2\xe8cTU\x97\x16\x83\x9ak\xd8\xa0\xe9h\xa5\x062p\x0dd\xd08\x10\xa0\x06\xb3k\x0c\x06\x7f\x9b\x1d\xee\xba:\xdc\x95\x1dv&\x9e\x85T\x88>\xa7\x90L\x93$\x12t\xb0\x1f\x1aX\xffB\xf36\xc3x^\xe8\x97YCy\\V}\x1f\xf0\x0f\x03c_\x94\x89\x0d\xeb\xfcVho*\x11\x17\xac\xa9\xa32\xc2\x99\xbe\x9f\xcb\x11\xefh!\xd0\x9a\xf7^N\xaa\x00\xf8z\x95\xd9T8\x8a\x07\xf0\xaf\xb0\xcb7P\xbfI)_\xa5n\xf4K\xf2\xee\xb6#i\x0e\x04\x80\xd7\x91\x93y\x94\x9d\xa4Sv\\\xf8\x9a\x0f\xac\x199Z=\x18b\x9f\x8b\xdd\x8f\x1f\xef>;\x004\xcc\x7fq\x08\x8f\x0f\xf6\x06\xcfj&_\x06.Y\x04m\xdfX\xb8Q_\xa4-\xd6 \xb2{i\xd6\x19Xu\x06\x97!$\x95\xa3\xfa\xce\xe0\xfeF\x1e\x14\xde\x9a3\x19\x103\xd9m\x9f \x1f\xa5c\xe1*4C\xa87\"\xd2\xc2M1\xeb7\xe2G\xda\x81$n?\xa8\x9c\xec\xf5\x8d\xd4r\x11\xe4&\xc7\x0d\xdc\xcb\xb6ksj\x10\xe8\xdb\x01\xc1\xc8\x95h\x84\xcc\x84\xdcbj\xfc\xd66\xdb#\x89T_z\x9b\x1c\xd5\xd6J\xb2\x1a\xd2\xf1\xcc71b\x0fv !\xb0bOY\xa4%j5\x1a\xf1\xa3\xd6\xf47\xed\x87 t\x0c\xbf\x86iI\x0b\xcd\x9a=\x1c\xaa\x91[\xe9\xa8\x11;\xcaA\xf7C\x04\xb0\x81\xa9\xc3\x16lX\xb9\x99\x1d\xc7\xf9\xd0\x0c\x8ci\x03\xf3\xd4\x06\x0b\xada\xf5WQ\x8f\xe7\x06\x87\x10\xd75\xd3\x8a\x91t\x0b\xff\x95\xcdmy\x06\x95\x82\xa1\x01~\\\xb6\xd0t|\xee\xb4\xff\xe3*\xef%\xfab\x96\xac\x99b\xe2\x85\x9c\xe3\xe8\x18t\x03%\xd5Mhs\xbb\xf5\xbd/\xec\x14\xd1\xe5\x9bD\xa3\x04c\x92V\x00\xd71\x89\xf3\xfc\x9c\x10$\x81\xe2/\xeao\xf0:I[\x91:\xd4\xa5\x88\xd0xK\xf5\xc0\xf8\x8f\x1cV\x1d\x9d\xebc\x92RL\xe3]\xc2\x8d\x99\x17\xbd\x81\x01\xae\xec\x93+\x8aAs\x0e\x19\xbc\xe0M(\xd2hW\xba\x91\xd9\x03\"\xbf\x18e\x97\x0e\xfe#E\x0d}\xd9L\x8a\x8e\xbcB_\xaf\xa1@\x8aG_\x08)\xdd\xc8\xce\x0e\x0e\x86\xaf\xde\xce\xae\x10\xb3\x9b\x06\x86\x8c\x956\xb2\xa0\xf3\x18v\x7f\xfd1\xc8\xb60\xf8\xce\xa1\xca\xd2Y\x1f\xd5\x1e=*\xd5y}\xfb\xb8M\x8bQOhly\x9b*\x96\x01\xfb\x8d\xaf\xad\xf3-\xb1\xa9\x8c\x1e\xa0\x01v\xc0O,\xcaMn\x0c\x9a\x05\xef\x0b\xcfijh\xf5|a\xf5\x0d\xa3\xa9\x17\x9a\xa9g};\xbe \x08\xa9C4h\xe4\x85\x1eT@\xa9C\xeb\xde\xc3\xd1\xc4\x98\xfa\xa45 \xc68\xa5\xeeu5\xa3\x9b\x1ei9Nn\xb4\\Pt\xa63LcS\x164\xa9\xd7\x11\x87\x11\x04\xb5\x84*\xf5\xb4 \xb1\x9d\x01\xabfu_Zc\x14Y\x94\xe4\xb34[\ns\x0c\xca3\x06C\x83_\xa8z\x1dl\xa7\xc0d\x9b\x8d^h\xa9*\xe9\x95\xb5\x9a]9*\xb1\x0d\x0f\x9c\xc9\x95[J\xdb\xca\xea\xf2\x983v\x80\xe068\x84\xae\xa2\xc9'\x15\xaaf\xb9^\x14\xf1j\xc1\xa0\x88\x97,w\x86\xbcW\x03\x99\xaf\x93O\xa5\x9bJ9\xba\xea\x8d\xcc\xfaW\x94W\x852ut\x88Y\xf8\xdc\x93M\xbb\xda\xc5\xf3'5Lw\xfc\xd4\x8al\xaeLd\xe1\x05\xa4D\xe0\x8d\xaa+\xdf,\xb6z\xfcZ\x99\x81Ri\x04\x19\x9bj\x88C\x99I\xeakN\xd7\x90`\x14\xf1.\\\xc5\x1c\xf4\x8d5*u3\xafT?/h\xfb%\xc2\x13\x83\xaa\xa6E\xf3h\xcc-RNT3y\xaa\xde\x1d\xea5\xdc\xa9Ff\x8bu>\xd7\x1a\x10\xbf\x0fU\x89\xb2\xbaG\x9b\xedU\xc6J_\xbd\xa8M1J\xf1S\xca\x1d\xa3\x8eg\xe4\xc8\xf4\xd1\x1c\xe9\xbfj\x99\xd3Hnl]\x12\xd7\xfa\xa2p.r-\xc9U\xb5\x7f\x9a\xe7\xb1v\xb1}\xb5\xab\x14\xc2\x88\xd4\xe6\x12j\x99GY\x15\xee\xde\x8a\x14\xa0\x0eL\xeb\xa2\xe3$Z,\xf86\xac\x16y\x9a&\x0cn\xe7,\x81\xdb2\xa9\xd2\xd6!\xf4\xcd\\\x86B\x8bi\x10\xcd\x1au\xdc\xb0\xbb\xbc\x88\x17\x8b\xdaV3\xbb,!C\xb8\x03TB[j\xa5V\x0b\xb5w~,\xd8\x95x\xc3\xe0\xee:\x816']\xa3 \xa5\xdfS\xbd}\xcb\x9d\xac\x1ay}0\xb5\xfd\xd6&)X\x00\xae\xbev\xc4\x98qvk\x8b\xb2t\x97ug\xb3\xa63\x13\x85\x13\xfd\x80\xe1P\xa9\x1dB\xac|\xa3]\xb7\x17!le\x06\"\xd1\xf2Q\xe7#\xc7\xcf\x8c5\xc2\xf3\xe5\x17:q\xbe:Al:\x174\xdf\xaa4\xc2\xb6t;)t\x88\xe25\x82\x02\xb8\x88\"\\cW0\x0c\x93\xc9\xc0\xf4-.\xcb\xd7\x1b\x0dU\x93\x15\x03\\\xf4\xea\xdc\x960!\xb6\xb7A\xdf \x89\x8e\xa9\x1at\xfe\xccd\x14\xed\xd6\x8c-\xd6l\x90Q\xf8\xc2fZ\x10Y\xe1Cn\x12w\x83\xb8\xdc\x8b\xd7\xd6\x98j3\xeb$G_\xcc#\xa9KEiv\x1aM\xe6\xf5\x8aq\x95\xdf~\x92\xb1\x1a.tK\xdf\xab\xf0*\x16D\x93\xa4\xaa\xd2\x8a\xb4\xb4\x1am\x03 \xe7\x069\x8eug\xb4iV\x10M]\x12\x99`\xbe\xc08\x80\xc0F\xc9\xa5U\xf9\xab/\xf3f\xa3\\`\xaeUX\xd34\xc2}\x97\x8b\x84g\x00\x7f\xfb\x86&5\x0c\xd0Sen\x92\xb7\x16\x89\x1d\xb9jq\xfe.z\xe7c\xfa_\xd4b\x14B\x7f\x817w\xdf\x7f/\xd5\x15;\x98\x9b!\xc5\xe8\xd6\xc32\xfc\n^ \xb5\xa7O\xef4\xc7\xba\x0b\xce\xc1\x93\xa7\x81\xcf\x87$\x916\xca\xf3\xf8:\x81!\x16=\xfbV\x9b\xc2\x10\xd2\x10\xb3\xc9\x85\xb0\x0eA\xf5h\xec\xadNv\xbd\xd6\x85\x05\x7f\xb4\xb8 Evg|E{g-B\x90Q\x00I'\xacI\x9a\xcc\xe2\xeb\xb5r\xc3\xea\xd3\xcc\x7f\xe4t\xd2js\xe2\xc2,\xd8C0\xcc\x80\xb5u\x85IT\xda\x8fU\xa7\x93\xb8\xf4Xhw\xb9\x99%Y7\x0f\xdd=\xec\xfa\x90\xab\x91\x88\xd0\x86$\x14\xc3\x8d\x13\xd4\xa35\x0cJ\xa6\xa5.\x0b\x1d!ez\x0d?\x13\xf9\xc1\x05K\x81\x9eZ\xd5*e\xfa\xad\n^\x17\xc9\xd4\xd2\x83\x83 \xc4\x8c\xa8\xa3\xcb\x10\xe2v\xaa\x1aR\x1ap\xce\xf9\xacG\xec\xb2d\xe6\xf9\x8fz\x15${\x05\xf6\xf3\x1c\xd8\xce\xce\xf3@\xb9\xb9z\x91\x07\xdb\xe0oo'A\xa5\x82\xda;0\xe5zM\x8f\xa2\xdc&|o\x96\x88\x9c\xb9XTJ\x1c>o\xb0\x90Q\xeeC\xf0\x02\xd8\xe6\xff\xfcM\xb51K\xa4\xc3\xa68;+\xc7\x81\xe7\xf0\xf5y\x9de\xec\xbcF\x04\xc5G\xf9\xc6\xb1f\xaeD\xf2 \x9eZE`\xa9\x1e\xec\xbd\xc9\x9f\xc8OB3\x01\x95\x03\xfd\x81\xba^\xfe\xfa\xad\xc4I\x88\x1cT&u\x1a\xe9\xeb\x00\xaa\xaa]\xb3\xe2\xec6Q\xd5^\xb1|\x92\xc5\xab\"5\x0c\xa8#\xd7\x07\xef\xa2\xa5\x19\xd3d\xed\xaa{~\xb7\xbcJ\x17y\x87\x93\x89\\cA\x82\xe5\xd1\x9c\xf9\x85\x89\xa7('\xea50\xca@\xe4\xe7\x81bv*\xf1\x9b\xce-G\xae4\x7fpOg\xa1H\xba\x9eQ>\xb6\xfa\xd2\x93M\xa0\xa1\x86\xfd]\x1d\x81\\\xaa\x0e\xcc\xe7\xbe\xfe\x07\x9b\x89n\xe0SJ\xe8\xb4\x9c\xfd]\xbd\x95o\xdc\x15\x8f)\xfe7\xf1\x07\xfb\xe6n\x89iO0\xce\x9e\xde\x17I\xf9\xc1Fd\xc2\xe3\xfb\xa7\xa4v\xa3\xddK\x12\x0c\x19\x92+\\!\xbd#\xc1\x87\xac\xa9\xe5HF\xd9%\xfa8)_\x8a\x08\x05\x12\xf5\x85\xb5$I\x0b\xa0\xf5>\xba1\xfcr\xe8[[R\xdb'B\x10\xd4\xd3\xc8}\xf9\xe2P\xe0![\xefR\x10\xceY\xdbh;\xa1\x05\xcdH\x15!x\xe31\xcb\xdf\xa6\xd35\x9a\x9c\x98K\x89\x8c\x8e.W\x06\"\xde<\xda}v\x81\x88\xbdX9\x17\xae\xdf/\xd6\xd7q\x92\x0f\x1d{\x8be\x99\xab\x08\xb0\xed\xe9z\xc2\xb2|\x08~\x9f\x0b\xbar\xe9\xcd\xe2E\xc1\xb2\xee\xc4\x80\xf5>\xb1\xbbs\xf6_~\xd0c7,\xd3\xc8\xb4\x13\xb4`u_\xb4d\x0bD\xa9mT4d6Q\xb2?z\xb8f\"\x16aw\xb2\xefDg\xd6[\xb2\xec\x9a\xf9N \x19\xc5T\";\xdc\x06X0\xfe\xe1O\x0f\x8d\x08\x9a\x1e\xa3\xf2 N~\x0dtH\xe8pZ\xbf\x06\x805)\xb2.\xc2\xc5B\xe5\xb6k^\x97\x89\xcb\x0f\xf3m%\x94\x0f:\x0b\xe5j2\xa6\\./e\xec\xc9\x95\xaa\x03\xc3{\xfa;\xfb/>\x83\x85uG\xc5\x19\x9b!\x18WS\x0bv\xc3\x16\xc32`|\xadl\xc9\xf2<\xba\xe6Go\xe9\xe6\x8d\xb5\x8c\x1e\xff\xbe\xa2\xb7K\xaf\xd5\xa4\xe1\xb4`\xfb\x97\xfc|\xc5&C(z\x9c\xc98W\xda$\xfc\xf5\x87\x04\xd6\x91\xb28f\xf35\xe8\xc0\xb1\xaaok\xa2\x80\xd8\xa1\xf8b\x15 \xbe\xc4l\xba\xc2G\x87\xf6\xf0\xc9\xae\xa9\xd4\x7fH\xed!Er\x08\xf7\xf8\xff\x15\xf4\x80 \x87\x8e7\xd3\x11\xd2\xe4]q\x8f\xc6\xff\xdc\xab\xfe\xdc\x0f\x02a:\xf3\xf7'_\xb4!\xa3\xeb\xc0\xe8\x80\xc67e\xb41\xc4ZI\xc7\xbd\xa0\x17'S\xf6\xf9l\xe6{\xd2\xe21\x9dA\x84g\xbd\x9f\x07\xa6\x11)\x947\xd1/a\xc7\xe9\xf6\x7fS:q\x1b] \x07ft \xa3:S\x96\xb6\x98\x05\xa1\xf0\xbd\x90\xea\x1e\xf4i\xe7z\xfb\xa1\xab\xc3>\x92\xd8\xed\x0ebB\xadqq3\xe1\x9b\x88\xd0\x90\xd7\xcdh\"\x91i\xdc*'4\xb1\xab\xe5\xef\x970\xc0\x83}\x1b\xbc4\xc3\x18)\x05\x0c!\x1b%\xb0\x0d\x83K\xa3\xea\xae\xac\x8a\xc0\x0b\xc1\xd3kj%X\x80\xbf\x9c\x03\xfc\x1a\x82\x97\xcf\xd3\xf5b\nW\x0c\"\x97Z\xc3O6\xc9$\xe0&~\xbf\xe9\xfdD\x9c\xbdEO\x1c\xfc$\xa1\xd1nu\x1dD}\xb0\xf7TCZ\x071\x0f\x91_\xfcMC\xe6\x1b(\x8dkw\xfa\x14\xf9\x11&@\x9e\xf2s\xeay\"e\xeaj\x11M\x98\x9f\xb0[\xf8\xc0\xaeO?\xaf\xfc$\x04\xef\x9aW\xf7\xbc\x80\xd2\x1b({\xa2\xdf:\x1e.\xa2\xbc@ss\x11Yr\xb1\xc0\x1fy\x19\x16\xd6@+R\xb4\x10\x98\xf6\xd8|\x1d[M\n\xa5\x8b0{U\x0cl\xd0q\xf5\xea\x80l\xd3\xb1\x94k\xae\x8b}JXU\x9a\x16cm\xaa\xa9\xd6\xc1B\x8f:n\x1aB\xd9=oG\xe3\xc8\xbf\xc5$\xe9A\x97\x9d\x90F\x1cs\xb0a\xdb\xe5\x92}\x11\xdd\xa5\xeb\xa2\xdb={)\x88\xfc\x03\xdc\xafS8\xfeP\x1c2}\xbf\xbe\xdb\xef\xbb\xef\xd7\x9fv\x16\xe5\xffW\xe0\xab\xff\xbe\xdb\xca\xc6\x99P\xaahvM\xa3\xa8HaM\xfc\xd0X\xb3& \xb4\xb0\xab\xe6\x98\xa4\xd3\xb8\n\x96hm\xaen\xe7\xa3J/\x90\x86\x90\xf7>\xbe\x7fu|q:~s\xfc\xa7\xb3\x8f\x17-\x8a\x82\xfaQ+\x88\x00\x9e\xa0R\xb9\xa7S\xc2\xc6\xde~|\xfd\xe6\xe2\xb4M\x91\\\xefM\x08\xde\x9b\xf5v\xfe\xd3\xd9\xcf-\x9dX\n\xca^>Oo\x13\x9b\x0e\xa9\xa3b]j\xed\xabO\x8ay\x9c\\\xbb\x1c\xe0\x94\x16\x1f\xdb\x95\x87T\xd5\xc8\xdf\xf8\xd8;\x1ev\x1c\x0e\x19\xe1\xd8\xd8\n\x07 \xf5\xb7g\xafN7\x06\x07\xce\x8d\x06GUi\x99N\x99c\xfa\x18\xea\xdc\x1fy\xbcJ\xee]\xaa\xfb\xab\x84\x0f5\x13\xb1C\xd0\xc6\xd9\xabO#\xfd\xad\x1c\xa5|\xd9\xce\xd7\xcbe\x94\xdd\xe1\x94o\xe7\x91\xc8\x0f\xc4\x7f\xc4\xf99_U\x11\x86}\x9de,)~D<\xd5\xdf\xb8\x98-u\xec<\xdd\xfbUO\x1d\x82\x95\x13de`Z\x97\xe5\x92\xda\xe8T\xa5\x9aS\x07\xf6\xe8Z#\x13\xda\xf2\x86\x04\xb4\xba\xb6&\xc9\x80S\xdd\xb50\xd6\xa5 {\xb4\xd6\x8brw'i\xb6\x8c\x16\xf1_\x19\xba{\x05\xd2\xfe\x1d\xfb\xd6wp\xae\xef\xe0\x00\xcb\xeb\xaf\xf9w 9\xcc\x1a\x0eu\xda\x8d\xa5\xdd\xab.\xa0\xd7SX\xe9\xa6\xb1pT\xff\xe9\x8e\x9e\xd3>kj\xef\x1a\xea\xe5\"0\xa6jo\x1bA\x94\xbaK\x06\xb6\xfc\xdb\x81\x1d\xdfBf\xc3c\xd3\xb8Hk\x18\xd2\x89\x94T\xf2\xcf\xdeAG\xd7/N\xa5\x8c\xa1\xd0jt9\xc0\x14\xf3\xe6d~\x12\x8c\xfa\x97!$\xa3\xc1%zc\xfa&EoTm\xab\xbb!\xd6\x13\xcd\xda\xc2\xa90\x14\xd7\x90#\x16\xfec\xd2\xc8Y\xa4\x0e\xac\xf7\xf8]\xfd\xaf\xce\xb0zb\xd2\x0c\xa9\x96x\x16\xf8^\\\xb0,\xc2\xa5\xb0\xc9\x9b\xe1K\xd9\x06o\xc7\x8a\x9b\xa1\xf4\xfd\xac\x87\x0dk\xc9\xc71{\xdaa\x8d\x9f\xddp\x8a\x8dsI\x8d\xb0\"\xf6\xfa\xab\xe5\x1a=\xb9\x1ce\x97f\xfe\xbdX.b\x93\xa4\x06\xaa\x1f#*Q(\xa1\xc8)NM^\xa5\x1a\x108\xb1[oA\x83 \xedx\xd3\xd9r_\xc4AB?\xe6*\x84\x93\x19oE\x913\xf3=\xbdi4\xc0\xd1R!?\xccb\x02\xa6X\x86Y\x97\xda\xa0\nMr\xb0z\xa6i\xc2\x86b\xdc\x9d\x83^\x878\xb0\x0d\xba\x8f\xa86\x98\x1f;\x08\x03\xeb\xe0\x1e\xd5\x05\xcb\x7f\x05\xfe\xe9\x97VE\xe4xk\xea^\xbe\xdb,Z\x1d+\xfdBC\xee\xe8\x7fH\x85\xc5\xde\xaf\xcb:.Paa\x99\x94\xaf\xcb\xa2\x81Y\x94\xcb\xa2\xbd\xfd\x03Z\x97AD_\xfd\xa7.\xe3\x97\xde\x97$:\xadHw\x81X\x95\xec\x99%\x91,yj\x954i),!c!\x9b\xd9\xb3\xba\x9eH\xb5\xc6\xc0x?\x93\xefwI\x84j\x08S\xfaK\xd8\xb9\xd4\xf4,\x99\xa6g\xd1\xac\x0f\xb3\x10fJ\x06?\x7f\x7fz\xd2M\xefQ\xe6G\xd0\xa2\")\x81\x1b\xa3\xe9\xa2Z\x04-Ru\xa5\x08\xe8\xa3V\n\x01\xc7`>~x\xd3m,\xb2\xb3u\xb6\xd0\xfb\"\xc4\xf6\x86\xce\xfep~\xf6n\xa3\xde\xfe\x92\xa7\xa6\xb4u\x96MY\xc6\xa6\x9a\xee%\xe8\xdc\xff\x87\xd3\xf3\xb37\x7f<}\xb5\xc1\x18P\xf8\xc9X\x9e.n\xd8\xd4\xbb|\xf8\xb1\x8c\xcf?\xfep\xf1\xe1tc\xad\x0c\xad\x8fI\x84\x13\xbd]\x98J\x13\xdab\xde\xa2\xa4Qs=__\x15\x193e>]\xad\x14\x04\x0ehd\xdd\xa1\xf0\xfe\xf8\xc3\xf1\xdb\x87\x9a:\x9f\x9d{\xe6Y\xb4|\x17- \xd0\xc4U\x85\xd7\x84\xd6o]\x15\xdb\x85y\x13\xcc1\x9cg/\xce\xff\xe7\x92\x88 7!tB\xea\xbd\xf0T\xe6\xe7\xcf\xfc$\x9d\"\xd1\xda\x8a\x05g\x0dG\xb0\x16\xaa\x88$Z2\xa17\xeby\xb0\xad\xde\xc6\x89|\xc7?\xde\x11\x05\xaa\x1d\x1f\xf3\xf7\x97_\xc4\xf61\xca\xe9\xea\x02\x8e\xc0\xc3\x19\x8d?/\x17\x1e\x0c\xe5/Z\x7f\xa0i\xf7\x18\xe6\xf3F\xeb$7\xd6dA\x08#\x0f\xa1\xc9\n\x86Wv\x93\x10f\x97A\x08yg\xac9}\xfb\xfe\xe2O\x02w\xc6\xaf\xdf\x9d\xbc\xf9x\xfe\xba\x95\xb0l\x84EoY1O\x89\x1a\x0f\x83Kq2Y\xac\xa7\xect\xb9*\xee\xfe\xc8Ak\xf3-\xc2\x1cx+.y\x1ee\xc2v\x1be\x89\xef\xfd\x1ce \x06\x1el\x02\x08L\xd0\xe4\"I\x0b\xb8f \x17^\x19D\x80c\xfb\x1f\xec\xae\x87\x16d6\n\xe4\x18\x1d\xd7\x81#\x0f\xb3\xe8c\x04@\xce\xd9g/\x84\x9c\xaf\xfd\xba}\xed\xffx\xfc\xe6uE3\xce\x7f\xbd\xe5\x8e\xf3\xb3\xe3\xf3=z\xad5\x05YGH\x04\x84\xfa\x9f0\"\xe7\xb4\xe3\xd1\xe7\xe5\xe2Q\xdc+X^\xf8\xb1\xd8\xde\x1c\x0d\xd6K\x96\x8f\xc5\x96\xa4\xbe\xe4{x\xd2\xe3\x9ca\xc4\xa1\xf3s\x8c\xf3\x8bd\xcc\x10ArB\x18\xb1\x86!6\xdfcl4]c\xb7_R\xd3\xefx\xfb1S\xd6\x8f\x1a\xed\x10m\x95\x8e\x15\x94\x01\x95K\xecV\x18\"\x8e\xb0\x9bh\x11\xf3\xc9\xbd\xe7\xad\xa3\x91\xfb\"\x84\xb4\x835\x18\x87FAR\xe4\xa2\xa2\xc8!(\x0b\x85Ks\xfe\xa4\xd1\x93\x1d\x15\xa5}\x7f\x08\x93\xfco\xdc%\xdavx(\x1cH\xdaq`t\xd9\x15\x07\xbaX\x03\x81\xc5F\xd6\xacCj\xdd\x12\xb0\xdf\x18\xf0\xe7\xa7\x17\x9c\x9b{\x7f\xf6\xee\xfc\xc1\xb8\xb8\xcc\x8c\x07\x035\x1e\xce.\xc3k\x9d\xde\xd2A\xc8\xd6\x0ef\xc3_\xa3\x13\x1d\xc2\x07\x8e\xc0\xd0\xea\xdb\xa0\x15\xd6\xd2dP,\x8e\xfcC\xd1V/!\xcf\xc6\xd2\x90_T\x92? \x9e\xaa\x88\x8au\xce\x19\x16U\xb5zS_\x9bP\x96g,_\xa5I\x8eY\x02\xb2\xa07g\xd1\x94\xa19\xd2\xba\xfc\xfb\xcb\x17K?\xc0\x17c\x824\\\xe3}\xb1\x1d\x8e*i\x08\x91\x8b\xdd_;(\xe4B\xc1\xae\xf7\xc3\"\xbd\x12\xda\x97iTDzPm\xbb\x8e?A\x8a\xed\x1aD\x08^\xc1>\x17\x9cr\x88\xd6\xf8\x112\xe9\x88\x95\xff\xf1\xf1\xf4\xbc\xedJ\x7f\x03\xa4\xfc\xaf\xcd\x902\xd6\x90\xb2U\xec\xf8\xaf5\xcb\x0b9\xe9\xd8\x05\xf9.\xa2\x05\x9f\xf9\xdb\x8f\x17\xc7\x17\xa7\xaf\xfe\x91 \xb0\\\x17Q\xc1\xa6\x1f\x1e\x0e\x10\x929<{\x7f\xfa\xe1\xf8\xe2\xf5\xd9\xbb\xf1\xdb\xd3\x8bc~B||0:\xd5$r9\xa4\"\x01\x92O\xec\x8e\x96\xa6F\xad,\x85\x83[\xeaz\x1eYN\xa0\xe5J(V\x0e\xb5\x0e\xae\xcf\xf3 \x080{dY\xbd\xd2\x0el\xfcI\xab\x90\x8d\x9f\x1eUX\xe2\xaa\xb7\xe0\x87ll\x9f\xaci\xd0M\x1b$\x98\x87\x87>\xc5\x9a\xb0\xa3qOL\xd9\x82I&C'\x87Y\x08\xe9e;\xde\xab\xc9<\xe8\xd6\x7f\x98\xb9\x94{\xbb\xe3T8-;?\xf9\xe9\xf4\xed\x83\xadI>\x993\xeat\xfe&*\x96\xf2s,\xd6\x11\xd5\x13\xfdTT,\x13\xca\x87/_\xb0\x9e\xbc\xb6\x1dR\x1fxc \x83s\xf1\xe6\xb2\x9e\x97$(\x7fv\xbe\xbf\xdd\xa3c\x99=\xdb'4\xdd\xf2\xb67_\xb1I\xccr\xaf\x8b\x1d\x00\xb9\x16!\xb2d\x99\xcf\xd0_?/\xb2\xf5\xa4H3\x12zZ*\xa8HK\x0f\x7fx\x08~\x82mD\x01\xdf\xdb\x98\xdbh\x08\xa9n+\xd0\xe9*\xe1\xa6\x16\x87\x15\xe7\xb8\xff\x8cV\xd8\xef\x99 \x91\x86\x85\xfb\x94\xce>\xf1\x07V\x948\xa9\xb1\xa7\x14\xf6\x93\xde*K',78\xdbU\xc9\xfd\x94\x89\xf6k\xe5S,\xafg\xc0\xaf\xd7\x98c\x8d\xb7\x82\x9f<\x99GI\xc2\x0c\x85\xdb\x0d\xd6x\x15\xe7\xab\xa80\xc35/1\x1di\xed\xd55\x11\x80\xee\xae\xed*\xf7F\xa67\xd8\xb6\xc3_\x83\xd4\xea\\\x1bWJ>s\xe6\xbeW\x97Z\xd7V(R\xf5\x08\xba\x82\x15B(|B\x92\xa9\xbd1\xa6s\xd5h\\\xc1\x1fu\xe1%x\xcez[\xd5\x88V|\xe7O1\xc6\xc1\xaa\xb1\xc9*G\xba\x8c\xd6\xcaQ{\xf0\x9c2lJ\xaa\xe8\xaa\x95\x11S\xb2\xbd\xed\xb8g\xbb\x1emo/[o\xda\xd7\x8e$\x1a\xf2\x06\xe8\xc7j\xe0\xa1\x15\xae:\x84\xcc_\x06!,\xbf\xd3^5\xc7\x86\xd7VG\xff\xc8\x93[\x00\x87\x90\xf8\xcf\xf6\x02\x7f\x16\xe0\xb5l#\xec\xd0\x94\xe1\"\x9e|\xf2#\xff\x0e\xe3\x94\x0ct\xfe\x0f\x86p\x83\xc6`\xbd$\xbdmm\x0dk9\x1b\xc2\xd0\xc2\xb12\x19N\xd8-\xcc\x83\x1e'{\xbb\xfct\xe2\x7f\x0czi\"\x8578\x84\xab\x10\xbb\x8b\xfc\xb8\xb7J\xf3B\xeeB$5\x03d>&\xbdh:=\xbdaI\xf1&\xce\x0b\x96\xb0\x0c\\\x01\x0b\xb5\x06P\xdb=\xe9\xc5K\xde\xe39\x86S\xcdU\xd0c\xf7\xd4&\xfa\x18|tt\xe3\x07\xca\xef\xea\xa6\x87\xf6\x88t\xa7\xa1\xab\x10\xb6\xc4\xc8y_^\x9ad,\x9a\xde\xa1\x1d\xc2d\x1e%\xd7\xcc\x838\x81\x85\xef\x89 \xaf\x1e_>\xf7\x88\xf2^\xb4Z\xb1dz2\x8f\x17S_\xfb*\xe8\xd9-\xb7\xe1p\xde\xcb\xd82\xbda\xa21\x91 \xa7\xdc\xa7\x06\xce\xd6\x16\xb5a|\xac\xb8\x88\x97,]\x17\x1aF\x84\xd0\xaf\x1f\xb8\xfa\xd1g}?\x84\x95q\x06pZ=\x84i\xd5\x04\xfe\xf5\xedq2\x1bM\xebh:\xea\x08\xc2\xcd\x9f\x9b!\xb0v\xb2\xd9\x18\xc9\xb5\xb5kBQ\x02\xb2\xeb\xb6\x8e[\xa0\xb7)\xb3\xb3\xfb\x94dvv\xfb\x8f\xef\xc3\xe2`\xb2\x10\xa4\x95\xa9_\x88|\x1b:\x9b#\xed\xedJK\x08[\xf1\x82\x91\xa2{3;\xa5\x98\xf8\x82\xf3\xc2\xa8\x05\xe3b\x92\xb4\xa4\xe5\xec\xc32\xce7\x8cs[\x8fu\xffd\xef[\x02\xda\x17\xba\xe5\xc0!l\xb9\xcc\xb9w\xfb\xbf\xa4Q\x8e>\x1eY\xa7\x8b\xa5d+\xf3\"\x9c%\x1d\xa1\xc5]\xa8\x8f\x89\xe1\xd40j\x8aw2\x9a\x13\xd8\xe3\x81\xccOC\x88\\\xb5\xa112\x85zn\xa4\xb3}1J/\xfd\x88\xd0\x10\x98\x8f\xd0\x0e\xa2\x8a\xc2Y\xb7=\x8a\xb3ztF\x9e\x0c$\xa3\x1e\xdb\xe0K=x\xeb\xb7\xeeM\xd3\xa4\xda7%`\xd5N\xf0\xf3\x00c\xfav\xd0\x80\xab'\xf3=\xce\x15\xcb\xc8\x1b\x89\x88\xd7 \xd2'\\\xb6exq\x918\xc2^\nM\xc0\xb7R_\x84\xc9\x8e\xe5\xff\x98\x0d\x87\x8b\xdb\x9b\xa1Q5\xe9\xc1>}\xca>1\xe5j\xa9R\xd83St\xca\xfc\x15\xe6\xa1,\xc4\xf0\xa7\xfd.g2\xba\x1f\xe4\xd4\xc9\xbc\x15\xa1d\xa9TP\xf5\x8dX\nb\\\x84\xdf\x19\x84(\xb2\xa3\xa7|\x8aQ\xe2\x82@Jb\xa1\x90\xdaa\x07\x06!J\xe9\xecy\x99o\x12\xc5\xbe\xed\xed\x05\xbc\x80\xc9s\xd7\x81\xc2%\xa4\xb5_\x8c\x16\x97\x0e\x82\xcc\x05w\xc2y\x81O\x01{\x995I\xc7\\\xa6_\x8d\xa6\x0e\xe9XO\xaf\xcd\xbb\xe1\xc2C\xee\xdf\x840\x0da\xc5\x99{QA\x98r\xceQ\x80\xb9\xe1\x9c\xfc\x0d\x0c!\xe6c\xc6@\x17\xfc\xcd\xe8\x92\x9f\xceT\xf8!\xebM\xe6\xaf\xb0\x83y \x00\xc6\x87\xf7\x9d\xfb\x13\xb5>\xf7E\xc2\xbd\xfdN\xbc\x1bq\x14{\xe31\x9a\xb9\x8e\xc7b\xaf\xe0\x9e\xe0\x8c\x88\xfc\xc0\x86z{V\x9cZ\x12\x19\xa2\\Z\xa1\x12V1Zb\x1a\xc3\xbf\x01\x95\xd7\xa3\x82\x0b\xf7\x1b\x9a\xb5k\xf4\xc9\xe4\xc5\xd261\xab9\x10\x16C\x95\x9c0\xc4\x0d\xc1\xab\x9b\xe2\xb6\xc5\x8f\xc10\x94\\&E\xb3\x07B\x06p\x9b\xf7\x7f\xf5\x1d\x8b\x9dv\x81\xc7/lN\x1cBQ7\xa1\xc8Q\x17\xcd>\xb3\xc9\xba`\xf2N\x0b_ \xfb\x81?\xe4ir\xbeb\x13\xed\x95\xfc\xe9\nJ\x11\xfb\x89\xbfO\x862\xe7%\x83=\x87\xa3<\x91\xecX\xad\xc5/c\x0b\\\x9bL\xa3\x0cU\xa9\xec\xf3\x15\x9bH\x07\x05R\x1aj\xc4VfX\xf6TL{(L\xd1rv\x91rx\xcbz\x89^\xc55\xa1\x90Z\xa9_c655\xa1\xa9\x1b\x0c+\xc71\x14 #\xcc\xe5\x04\x11\xbc\x80\xe29D\xdb\xdb\x01\xc4\xa3\xe8\xb2\x96&$\"\x0e\x08\x13d1\x82*N\x14\x06\x7f\xa8_\xcf\x9dD\x939\xa3\\\x8c\x94\xd4\x11\x8f\xfa\x0e\x07\xa5\xdc\x0eP\xbf\x0e\xab;\xce\x80\xb2K\xe0\x8f_\x8f\xb9I\xe5\xacq\xf2\xe9F\x7f9\x1a{\x05\xbd\x7f\xc9\xd8\x8c\xa3<\xdeb\xf3\xedh\xcc\xd2W\xa3\n\x81]n\xc2\x80\x87\xd4F\x7fh\\!\xcd\xb8\x94\x0c\xda[\xa4\xd7\xb2k\xe1\xb6\xea\x9b\x1a\xdc\xfah-J\xb5\xc1h\xcb\xb0\x8c\xf7\x1f/\xc3`\xc7\xd2\xae\xd0\x8aRcP\x95\xbf?]\xef\xa2c\xb8\xd1c\xbd\x9d\xa4\xcbU\x9a`VJ\x0b\x04e\x94\xb6\xf3\"\xcd\x1c\xd6\x01Z\xa0b\xbb\x02\xde\xaa\xd5z\xb1\xeb\x08\xab\xa6\x8c%S\x96\xd9\xa5\xb9\x0c\x1c\xfe\x89\xbd\x8dV+6=I\x93\"\x8a\x13\xaa\xea\xa2\xdc\xbeK\xb6L\xe3\xbf\xb2\xc0\x8fDvr\x91>:F\x1e\xdcJ\xa2\xe5T\x0bfiZ\xbcN\xf8\xda8\x9d\xd9\xf4\x99\x0d\x810\x1c\xe7\x0f1\xf8\xa19\xd0\xdc\x1e\xe8\x02\xc7J7)\xa05\x84\xb5\xfdYd\xdd\x88\x80\xc5\xcb\xba=\xd5Z/\x9a6r\xf6\x02\x0d\xd9(\xc2\xd9\xe2\xf4\x05\xbf\xa8\xe3\x17Tk\xeft\xfe\x02d\xe58\xf3\xfe\x94bf\xd0=\xea7\xb2\xf1uTD\xfa'p\x04\xff$0\xb0\x81y\xbb\xe6\xcc\xdbcj\xbe\xd7$[\x17\xcb\x12\xda\xe5\x0cK\xac\xd6\xd6\xaa5\xca\x01\x11?1\x0b\x16\xb2\xc0\xead\"\x0b\xac>f\xb2\xe0\xc0,X\xe1\xd2\x99\x97\xe4S\xac\xbe2\xde\xcee#O\x9eXC\xbd\x11\xe2\xffc\xf3\xfa|)?y\xfa\xf8\x19\xcd\xe6^\xff\xbal._W+\x1d\xb4C\xe5k\x13\x81\x06\xa3l \x8eR\xa7\"Y=\x9a&\xb9\xad*\xd4\xaf\x18\xf2\x8aM\x12\x1a\xefL\xda\xe1L\xcc\x02?\xeb\x952\xb3\x8a\xe8\xbf\xae\x19\x9594\xe7n\x0d)\x90:\x04\xfd\xd1F:\xab\x19\x06%r\x98\x8b\xda\xdbQ\xfb\xdc?\xb1\xbb!xb\x1f{\xf4A\xa0?\x9224r\xec\xd4#\x07>-\xf5\xd7\"\xee\xc7\xa9Hl\xcf\xe9\x91a\xbf\xf67\xf4u\x0fdn\xf3U\x96\xaer\xf9\xf7$M\n\xf6\xb9h\x81#\xb4\xc2\xf2\xebe\x10\x12\xe1\xd8\xcbb\x7f\xd5+\x89\x9dK9\x8d\x98KC-\x95\x9c\xc2\x0d\x1fp\xc2&\x85\x16\xdb\xa4-\x80\xeb\x8dL\x8eo\x9a_\x7fE31\xe6S\xd1'\xd5\xa3PD?\xbe\x96\xd1\ns\xd0_\xa4\xfc\x04@\xdb\xe7v\xa9\xc1h\xb0}\x9d\xf1\xde\x9a\xba\xc7\xd4\x1f\xf7\x9a|\x0d\xfc\xa4\x8c\xf1D\x146d\xf6Ij7\xee\x0d\xd4d#J\xb2\x01\x15\xf9\xadP\x107t\x1f\x96rl@5\xeeC1Z\xa8\xc5M\xef}\x96\xde\xc4\x9c\x97\xef\xd0\x18 j\xa6Y+j\x82\xe0\xb16\xa3Qn\xf2t_:\xdf@\x97Zh\xd2W\xb1\x81`h$\x0ci\xb4\xf4j\x8c(]r\xc6)\xe7\x8c\x1b=\xa7by\xd9JS&\xd2\xba'\x1670\xc9(\xbd\x0c!\xc3\x7f\x19\x99\x88\xa6i6c\xbc\xacp\xb0\x9f\xc44\x85\xcdc\x830\xde,\xb1C\x9d0\xb8x\x1c\xf58(\x82\x9b|\xeb\xa4\xff>\x14C\xa4\xac\xc5\xda8\xb6\xf6\x93\xe2\x8a\x03'\x12Z~\x8c\xb2G\xa3^\x13=\xb5\xa9J\xb1)U\x11\x14e\xa2\x90\xfb\xe7x\xb1\xf8\xc0&,\xbeA\xa1%o 2&\x81id%\xf9\xa3M\xb8\xda\xbd\x9b\xd2\xd4\xafM\xa4\xa7#y\xdc\x944\xaa\xcb\x06\x0e\xd8e\x1d7\x14 \x8a\xa4\xd3\x96\xa6\xee\x8b8A\x18\xb9n\xdc\xf4\xa7@a#\x0e\xc1\xcb\xd2\xb4p\xdd\\\xa8\xa7\x9d\xa5\xdb\xd8\xec\xc1A\xfa\x1a\xc8\xde\xd7P\x97B\xc9\xedn\xc5c\x03\x8db\xa9\xaaY\x08\xde\xf1j\xe55\xcc}\xde\xabl/x\x7f\xbek\xe6q\x88\xb7\xa2\x81\xc5\xcc\xb4\x1aUTJ\xb3$Z\x12z\x8e\x16\x90{\xd3\xf8\xc6\x92\xe5\xd5\x93\x17w\x0b\xd6\x14\x14i\x15M\xa7\xe8B\xee\x0d\xd8\xb2\x01k'\xe9\"\xcd\x86\xe0\xfd\xff\xa2(r\xe4\xbd\xb3W0\x04\xef\xff\xf9\xdf\xff\xb7\xff\x03<\xf7\xf9\xea\xc5\x9e\x00\\\x08\xdeI\xe9\xa8.\xd7\x96/\x0c\xe6\xbf>\x84\x02\x8e\xc0\xe38\x0f%\xb5\xf0`\xc8\x17\xd1\x0b!g\x0c\x8a9+\xbd\xe3=+\xe4w}b\xb7\xad\xca(\xb5&\xdd\x18f\xb9B[>\xab\xd8o!oW\xdcx\x9c\x7f`\xd1\xa4h\x17.\x9a\x0dI\xf5\xa7\xf3\xd1\xa5\x9e\xf2\x08k\xa7:\xd0\xc2\xdf&N\xfe6i<\xad\x92{\xf0\xb7\xd0*\xd5\xd1'RB\x9eHI+\x9f\x0b\xdd\x89\xb9z6%\xea\xea\xa9\xae\x02:\x9cI\xea\xe9 \xe1&n\x1a\xdcI\xc2\xc5\x1bwz\xda\xd2\xbd\xa8Dl\x01\xa3\x06\x0d\xa8Y\xb5\xed\xde\x1dZM\xfdJ\x06\x95\x91\xb7\x83Yy;\x88\x96\xa9\xe2v0\x85\x17\xc0\x9eC\xba\xbd\x1d \xd7Y\xbb\x1dt1\xb0\xa0\xdf.\xe9h\x9b9 \xd7\xc9TP\xb6XOG\xc5\x87\xea\"\x92\xe36\x89G:d;VL=\xc27\xbb\xc0c\xc6\x8d\x1f\x8e\x99Q\xd4\xddPgW0\xb4\x94\xc6\xf6\x19\x9d\x86\x10\x9b@\x8ag\xe0\x97\xc6[U\xe2\xbf4\x90A+\x13v\x0b\x17w+v*\x12x\xbdcl\n\x11\x88\x0fB(R\x981\x0e\xfd\xa8:#z\xf0s\x94\xc3u|\xc3\x12\x880\xd5\x8d\xaf\x99\x04\xa5\xfcPY'BM>\xe5\xe7\x89q\xe1\x9aZA08\xd6 \xa3-3*\x84\\U\xce\x8b\xc5\xbc]\xe4(\xb0\x1b\xfe\xf3N\xb1\x9f>\xfa\x14\xe0\xcf[?\xc2\x1f\xb7\x82[\xf3\x99\x1f\xf4\x16\xe9\xb5\x0c\xeeR\x9d\x86\xb38\x99j\xc7\x1e\xe70$\xb3Q\x0e\xa0\xd3%\xa1\xdb|_Nx\x08\x89\xff\xe4\x89i\xc8W\xe9\x8c\xeb\x97\x03]\xba\xa4\xaf'\xdc\x03\x99G9^\xb3\x0bG\x89w\xe9\x94\xe5C\x18\xddX\x12\xc2:\x04\xe1V\xa4\x90\xd5w\x10T4\xdb\x16\xb1\x93\x1c'\x838\x94\xd7x\n$x\np\xc4Jz\xf2,\x80\xa1\x8a_\x87\xb1\x89\x9d:\xee\x05\xca\x11\x92\xfd\xec)\xa4\xc6hl[\xfd\xc6\x03\xd0\x81\x8e\x8dwR4,\x0b\xa1U\xd1\x1b4\xb8@\xd26[g\xd0\x84\x1b\xec7\xf1\\\xf5Q\xcbKC\x93\xceO\xd1b\x8cz[\xc4K\xa2\xc4SE;\x8bt\x12-<\xbb\x06[F\xf1\xc2~\xbdL\x93bn\xbfN\xd6\xcb+F\x8ck\x15\xe5\xf9m\x9aM\xed\x92\x8c\xef\x07\xfbu\xce\xa2lBtP0b0\x9c\xef'\xde\x923^gD\x03\xb7\x8c}\xaak`\xdb\x94tN.W\\N*v\xb6\xfe\xab\xce\xb5\x92\xac\xae\xce\xe5\x16p\x04[[\xd9Hp\xce\x98b\x8e\xcf4\xcaX$+T\xe3}p\xfc\x12\xa9\x03\xcf'\\\x8c|\xc3f\xc5\xd0\x0c\xe1U\xabq\x91\xae\xac\n\x19\x9be,\x9f\x8b\n\xb8m\xf3\xb6}\x98\xf5\xac~Q:\xf8\x1c\x9aE\x17)\xfaK\xf7\xeejm\xb4\xee\xc3\xec\xdb\xe1\xe4R\x83\xfa\x83\xc7\xa6u\xbatM\xb7B\xc1E]\xd4W\x9c\x82\xb7\x86\xd6f\xbdY\x9c\xe5\x05\xaa\xf4\xddZ\x1b\x94\x9f\x12\x112\x06\xd3ic}\xferO\x8aS\x1cC/\xeeV\xd5\x89s\x93\xc6S_\xbc\xc7\xa5\x83\xc3v\x0f\x15@`k\xeaX\x8bU\xd2V\xc5T\xfbvW\xf9r\xae\xba\x15\x82{\"a]918\xe2\xc4]\x04\xd3AMy}j\x15\xde\x04F0\xa6o\xa0\xdc\xdd(\x07}\x1f\xcbz\xb3t\xb2\xce\xcds\x86v^~\xf0\xdd\x1f%\xf1\x12c\xdb\xbf.d\x90\xfb\x93t\x9d\x104\xf6*\xcd\xa6,{\xbd\x8c\xae\xd9\xd9\xba@\x06\xbf\xa1\xca\xf9\"\x9e\x10$Y\xab\xf1s<\xa5\x8e\x95\xab\xf4\xf3\x8f\x0b\xf6\xd9Y\xf0\xfb,]\xaf\xc8\xd2\xb3l\x1a'\xd1\xc2Qa\x92.\xd6K\xd7\xdcDan\x17\xcc\xc8\xa1\xcc\xc48n\xe9\x92\xf7i\x1e\x17\xf1\x0d1{^z>\xcf\xe2\xe4\x13]\xf6\x8e]G\xee/1\\\xb1]t\x9d\xc5\xd3\x0f\xd4Xd\xc1iB\x1c\xc5\xb2\xec|\x15%\xee\xc2\"\xca\x08X\xf1\xd2\x13\x84WS\x99\xb3WQ\xec\xeeX\x96\xd3}\xcf\xd2\xa4\xf8\x99\xc5\xd7s\xa2l\x11'\xecd\x11-\x89\xb5\xe7E?9>KW\xd1$.\xee\x88\x02\x1a\xdci\xb6\x9aG\x14\xaa\x14\xd1\xd5y\xfcWb\xedn\xe3izK|\xf0\xd7\xd7\xc9\x94\xc2\xae\xbf\xa6\xe9\x92\x98z\xbcX\x9c\xb9\xc6:[\xa4\xe9\xd4Y\xca\xb9\xd9\x86\xc2,\xfd\xc4^E\xf9<\xca\xb2\xa8\xb1B:\x9b\x91\xdb^\xd4x\x1b\x17,[\xc4\xcb\xd8Y\xa3e\x0c%A(\xcb\xbe\xda\x17p#\xefgv\xf5).\xbc\x10\xbce\xce\xff}\x9b\xfe\x95\xffw\xe6i\x9a\x1e\xa9\x89\xf9\xc4\xeer?\xeb\xe2\xee\x9d\xdauh\xa7\xe3Q\xeba\x0e\x9a:\x11\x13WL\xe6Qv\\\xf8\xfd\xa0W\xa4\x1f\xb90+5\x99\xbc,__ \xc3\x0b\x7f@\xd9\xa4\xa3!\xe8%gf\xf4\xd0\x97X\xa6\xa98\x8d{\xca\xd8\xa2\xf1q\xfe1\x89\x8b\x05\xcb\xf3w\x92i7\xdcs\xf3y\x9a\x15\xf3(\x99*\xad\xd5\xe9\xe7U\x94\xe4\"'\xa3=\xc5\xabh\xf2\xe9:K\xd7|\x8f\xd3\x00\xa8j\x1c\x17E4\x99/\x19Ev\xed\xda'\xb4\xaccW\xc4#\xa4KEA\x8d\xd3\xe4\x7fnR\xf9O]*\x7f`+\x16\x15C*\x8d)\xa1:\xb1;i\x87\xdd\xfd\xc7\xdeiD\x92\xc29F\x81\xa5\x8eC\xba^\xe9\\\x98\xc76W*W\xb6\xfb\xd0~H\x8b\x82\x93\xc2\xa6\x01\x8a:\x9d\x86)\xaav\x1a\xac\xa8z\x8f!\x0b\xf1\xa9i\xc0\xbcF\xa7\xe1\xf2\x8a\x9d\x06\xcb+\xdec\xa8\x1f\xc4y\xd84V\xac\xd2i\xb0X\xb3\xd3h\xb1\xe6=\x86\x8bbg\xd3`/\xd2U\xa7\xa1^\xa4\xabN\x03\xbdHW\x1b\x0d\x93\xf3&\xae\x11\xf2\xb2\x96Ny\x95?FY\x1c5\x11\xca&\xfeG\xafC3\"\xeaib\x87\xd4\xc3[\xf91Z\xc6\x8b\xbb\xae\xf3O\xd7\x05o\xd8\x05\x02Y\xdc\xb2D\xb2V\x0b\xacd\xad\x86\xe5\xf9\x8e\xfe\xe5P\x15\xc4\xf8\xf6\x9b\x84\xaa\xc4\x7fj\x06\xe3K\x85a\xd0`\x1f\xe3\x02\xee\x89\xf0\x80O\xfb\x96\x83\xbc4 \xc2rv\x0b\x1f\xd8\xf5\xe9\xe7\x95\xef\xfd\xe7\xc8\x83m\xc8z\xc7\x17\x17\x1f^\xff\xf0\xf1\xe2t\xfc\xee\xf8\xed\xe9\xf8\xfc\xe2\xf8\xc3\xc5\xf8\xe4\xa7\xe3\x0f\xb0\x0d\xde%]\xa9,\xfe\xdd\xbfXi\xcd\"\"\x1e\xfbZ\x06\x80(_\x96w\xa5\xb9\xf3\xaetkkmG`\xc7\x00\x81\x11\xf1\x9e\xcb\xfd2\xfb\x1a\x1a\xb4\xf9\xeb\x11\xbb\xc4\xb0\xaf\xa8\xdd\x85!\xf8\x91\xf6\xa6\x16H\x9bNs\xdc\xc5\x9e\x10\xf3\x84\xcc\xa3\xfc\x874]\xb0(\x11:\x80\xef\xbf\x87\xad\xaa\xe8\xddz\xc9\xb2xR\x16\xc5\xf9\xbb\xe8\x1dg\xfeT\x05%\xce\x99\x15\x0bx\x01\x83\xb2\xd6\xd9\x0d\xcb\x16i4eS\xab\xaf\x01\xa9\xc0\x03\x89<\x13[\x1f\x87V\xcbo\xa3\xec\xd3z\xf5c\x9a\xbd~\xd5\xaaJ\x13\xd3\xcez\xaf_\x8d\xeb\x88\xc0q\xe0\x90cHj\x85\xb4\xae#@\xce\x8a\xe3\xa2\xc8\xe2\xabu\xc1\xac>\x1d\x8c.f\x9b(\xbf\xf2\x89\xee\x89\xe0\xefM3\xfd\x90\xa6m\xd7\x95\xe5T?\x9c\x9d]\xd8\x93\xfd\xb7C\xcf\xfb\xb7\x0d\xe6i\xf4HB\xd7\x9a&\xd1uXK\xdcK\xf4k\xccT\xed\x8c\x0ePV\xea?\xbc\xfc\xe6\x1f\xc5,'\xf6\xd7Q\xad\xc2\x08U\xc8\xb4Q\x15j ]\x82\x0bF\x8b\x14.\x1f\xa5~\xd0\xf3huc\xe9\x07\xd6\x8b\x14tl\xb3\x0e\xf5\x94\xf6\xff\xe6n\xfc\xf2E\xbcl\xd8@\xfdRE\x1e\xab5\x86!\xfe\xad\x90\xbb\x93\xbe\xb2\xc4\x9d8?Y\xe7E\xba\xac\x16\x15\x01X\x91\x0d\xbc\xc1\x1a\xa2\xf8V\xf5 \x01\xba\xc1*\x1b\xbdtXl9\xc4\\RL\x15{\xa7\xc00#\xc6`<\xaf\x05\xd1\x11\x80ndk\x880\x92\xb6\xe0[a\xe1[\xd1\x8co\xa4\x1f!h8\x94\xf60cW\x9c&T\xbeD\xf5\xf0\xa6\xe2@hw]\x06~l\x913GgP\"x\x8a\xee\xbd\xba\x02\\\x98}\x89\xabb\x13pb\xb9\xe8\xeeT\x9b|\x02y\xf11/\xed>\xd0$Q\x81\xe8\x8eo\x8cK:@\xabzZ\x06\x0e\x9a\xbdQZ\xdfq4\x93\xa4?k\xfb\xa3|\x15M\x1c{\xb5\xfa\xea\xc8\xa0~\xef\xce\xfd\xb5\xc8\xa2\x877\xbc\xe8.O\xed\xe8\xb4\xd3\x8eN\xac\xf6}l:P\xa9\x8c\x8c\xf7\xd8\xa5s\xc4\x8e+|\x9b0\x08Hc\xd0}\x82\x14\x14\x06^Lz\xdaV\xd2(\x86\xdcA\x1d\xf7\xa0\x8b\x0886a.\xf3\x00\xf8\x8a& P\x89\x84\x15\xfaXmH\x15%\xa4\x1a\xc7V\xc7\xf4Mh\x145\x8c\xee==\xf0\xc9\xb71%r\x9e|\xa5\x85\x7fgJ\x94\x06\x9c\xad\nU\xf0\xe3\x06r\x84\x1d\xdb\x04\xc2\xbd\xd9\xab\xa3U' \xee\xddj\x1f\xabG\xc0F1\xb2\xd3\x03\x0c\xfb\x8b\x7f{\x0e\x9fc1J{a\x8d\x93\x9d8d\xc5\x97\xf4>\x12\x17\xe2m\xc8R\xfer\xc8f\"9\xe77\xcaf\x03*lq\xe2\xef\x0e\x1c\x11\xc6\xcdp\xeb2\xcf\x97\xd9\xca\xba\x92\xdc\xb6\x06\xa4\x91lnq\xb1x\xd7\x8bV\xccY\x9a\xa25\xcd\xebW\x95\x0dv\xcd\xdci\xc5\x92i\x9c\\\x7fD\xa3\"\n]\xda\xbe\xc1\xe5\xb7\xb1\xc6\xf0.\x10w\xed\xf2\xcaU\x06C \xf1\x04\xc3\x9aW\xf6B\x94\xfdL\xc5\xb1|\xff=(\x03>\x89\x98>\xeb-\xd7\x8b\"^-\xa8\xb4P\x15\x1e8\xc5=\x82X\xde\x94\xd9\xd8\"\xcc\x81B\x1b(\xf5\xd2UaGEu\xde\xba\xa3\xbbA&\xc4d\xdd\xe5 \xa9\xbb\x1cd#AhG\xe9\xe5\xff\xcb\xde\xbbv\xc7\x8d\x1b\x0d\xc2\xdf\xf3+J\xcc\xacCF4\xad\x8b\xc7c\xb7G\xd1\xeb\xb1\xe5\x8d\xb3\xe3\xcbZ\x9e\xe4\xeci+Z\xaa\x1b\xdd\xcd\x11\x9bdH\xb6de\xac\xe7\xb7\xbf\x07\x85\x0bA\x12 \xc0\xb6<\x93d\x1f|\xb0\xd5$\x88K\xa1P\xa8*\xd4\xe5\xac\x93\xc0\xa4\xd5\x92\xd2B\xdcn\xc1L\x89X\xd0\xcd\x0e\xb1\x8b\xa7\xf9\x197\xa4\xd2\x93\x02\xacPaLU2\xc7[\xf1\x0d\x9e\"\xed\xe7Gj\x82xQ:\x1a\x13\x137\"A\xc3\xa6\xde\x02O{r\xda\x01R\x907\xb3@&\xa0l\xdb!t\x87\xba\xa3#\xac\xb1\xe2k\xe2\xc7\xd3\xbd\xee\x17F\xcc\x12\x7f\xe9\x05\xef%\xa9\xff\x9cW5\x06Mq8\x9f\x84<\xc1b\x19\x99\xecA\xf3\x8c\xd9\x01Nz\xd6\x8c\xe2\x8d~\xb3q_xv\xb8\xf4\x97k\xf0\xc8]\xe7\x9b\xac\xfe\x1b\xeb\xcba\"\xe2\xa0U\xf6\xb6\x8e\xdd\xed\x8c\xbf\x07>QZ$\xc8\x9c1*\xc9\x92:\x89Sn\xb9*\x08\x07et2\x984!?\xf1\xbdI\x8f\xc9\x12\x8eU\xecs\x83\xaeP\xc2\x7fX\xcc\x17EXw\x8d%\x8e\xa20@\xf2\x10\xceoy\xe7\xec\"\xcf|~\xeb\x0e\x04\xdf\x85\xba\x9b\xd8\x0eP\xcd\xb9\xe3*.|\x1ec\xcb\x18\xd5\xe0\x96\x85\xaa5\xd9\xf9_\xc7\xd5kN\xbc'\x92\xa0\xd7\x0dA\xefch\xa8\xa6\x8d\xa8\xf9\x8eW\x13r\x1eu\x16\x99\xbe\xdc\xa0\xc9\xcfF\xb7\x8d\xc3\xee^e\xc1\xa3\xf1\xd3\xe7\xcc!\xc8\xb6\xc6\x06/\x0f\x15\x13\x87\xfa,\xf2\xaaf\xa0\xd7\xec-\xd3\xc6bVmZD\xb2n\xb1\xd6\xc8\x0cY\xe7\xa1e\"\xd6\xfe\\Y4{_Je8\xd2-\xb1\xbe\xdf\xd2N8\xc4\xde.\x99\x7f\xb6\x8da \xd9q\xaf\x19A\x08%Ztex\xb6i*42\xd3N\x0f\xbb\x8e\x07\x9amW\xa5]\x0c\xd5\x15?D>\x13\xaf\x17)G\xfe\xfa\xaaLm7\xb0m\xae\xe7u\x19O\xfbx\xbf\x1b\x91\x80g\xcdy\xd45q\xdc\xf0\xe7\xdd\xfb\x8c\x8a;:\xd3\x0e\x809<3\xdewx\x13 \x19\x93N<==\xb4\x96m\xd6\xab\xf7\x11\xcd\xfb<\x1c\x97\x91\x8fxz\xa2}\x91/\x8f\xee\x88\x98\xc7\x00\xf1\xd3\x0e^J\xb9\xccc\xd9\x92Zi\x8e\x86\xf4b\x86\xb3\x88)\xb1h\x03z\xb9S\xeb:\x84A\xfc4\xa1:z!=D\x11|\x8bI%\xbb\x17\xc2\x0cv]\xbc@Ax\xf9\x0eU\x80\x16\x0d\xa3\xbcu\xbc\xd6\xe6nP\x0bg\xab\x85\xf2\x18\x9e\xaf\xc8\xec\x12\x03K\xf1\xc05,\xf55\xe4\x0b\xf8\xbf\xe8\xa3\x05\xbb\xe0\xfd\xdfH/\x9a\x82Q\xb1\x03\x8a!\xb5A\xac\xf5\xf3\xe8<\xbf\xceHI \x87\xef\xed\x1f\xeeyMX\x89\x04\xd5\xc9\x13 \xf2\x10f6\xae\x98\x16MV,\xb6\xec\xc8\xb7\x1c\xc1\x86#\xdc\xab\xac&e\x16\xa72|\x8b\x8f\xc1%]<`\xc4\xac\x1a\x8cQ3p\xdd\xbb'NPf\xf5\xda\n\x95\xa5\xffF\x8dfK9\xc3&\xa4\x8c\xcb'%\x0b%(?\xea\x03\xc9g\x10\x088\x082r\x0d\x15\x9b\xae/~\xb3\x1a~\x1e\x04\x11\xe7\xb2)\xa3\x83\x87}\xd6zr\x04\x19C4\xbcr\xcb\xe7]r\xc16\xae)7\x99\xc7\x9c\x12\xba9\x89\xdb\x0b\xc3\x9d+s\x0c\x1c\xe1#\xb5G\xec\xd8\xf7\xc2\x86\x02\xb4q\\\xde^\x9c#\x00\xd1p\x8fy\x8f\xcbGk\x96\xc1\x97\xb9)w\xf3+\xd1\x92\xfb\x95\xea\xbf\x98t\x05\x86s\x16\xc9\xa1N0g\x8a\x1a\xe4l\x02\xcd\xadC7\x81,{\xf3uN\x92\xef\xbay\xd6\x94P\x17}\xd4\xfd\xf3\xdb\xd3\x0f=\xc7\x00Z\x9e\xbf}\xfd\xee\xed\xe9\xab\x0f'\x13\xd0\x88\x02'\xaf\xdf}\xf8?\x138\xe8\xbfY\x92\xfa\xc3M\xe1\xc4\xb8\xb7/~;'\x01\xdd\xe8\x11v\x83\xea\xea\xa4\xfak\x9c&s\x11\x15\n\xd1\xd6\xb0 \xf8\xbeN\"9\x05\x98@\x12\xd1\x99\x8a\xa4g\xa5\xef\x1d<\xd2'o\xec\x88\xd4\x067\xf1/\xb5=`\"x\x1f, f\xc68Y\x17\xf5\x8dD\xa4\x97\xf1\xac\xce\xcb\x1b'\x88R\x92o\x9bR\x1f;\xfa\x8d\xb1]\xe7\xd4\xa5\x90\xa7\xed\xb0l`\x90Dl\xa2\x94k8\x82<\xbcS\xd8\x9a7\x07\xdf\x05,Ve\x0f\nm\xf5\xf3\x95\xd6K\xdcpL\xd8\x00\xc5\x81\x94S\x04\xa7Tk\x9fR-\x86\xa9\xdc~\xc4v\xd5\xaf%\x83\x8e\xddb\x82ZK\xfbI\xf5\x01\xdd;\xc6M\xa8\x15\xc8&\x19l_\xac\xb7\xce\xd2\x88\xbd\xfc\x9f$#e2\x93cx\x9e\xc6\x95\xd5! \xf8\xd2j\xb0\xbeO\x9bX?\xad\x89:w\x92\xb8l-\xf9\xeb\xeby\x19\x9aQ\xfb\xe1#\xc6\xe1\xef\xf7rj\x08YB\x97\x81S\xec \xff\xa0\x9fiD\xd1\x94{\x91\xa7\x11,\xbc\x89\xe7.\x08H\x9c\xa1\xfc\x8b\x86\x7fW\xef\xceItIn\xe0\x18\xe2\x88T\xb3\xb8 >>\x08P\xc5T\xe7,G\xaa\x7f\xf8H57\x12\x7f\x8d\x89\xd9\xd51=\xa2\xc7\xc6\x9e\x92+\x9e\xa7\xa9\na\x16\xea\x13q\xd2E)BLr\xc2gQ\x1b\x04 %\xd2\x1e\xe5\x00\xd1\xb7\xcb\xbb`\x92\xaaxD\xf9\xaa\x9a\x13\xa2&\x94\x9a\x88\x94\xd10O\xbc\xae\xc26\x89'\x0dTy\x17u\xf4\xcd7|d\x18\xf4Or\xf83\x7f\x81 \xf1\x85p\xa2\x07\x8b\xc6\x0e\xa3\xf7\x84\x13\x94U\xeb\x05\x86\xda\xf0\xbc\xae\xb9\xc5\x97\xfaA\xb2\xd0\xa9h\xcb\xb2 \xa1\xc2tn3v(\xeeuo\x7f\x17\xec\xf6\xf7Q'\xe0%S\x7f\xe9N\xad\xc2\xec4\xfe\x92\xd7Q\x04lq\n\xf5\x177k\x02\xe4\x98\xf2\xa9\xf5?\xa2G\xbb\xb4!\xf6\x98\x07\x12\x06\x89\x0c\xa2\x92\x14i<#\xfe\x83\xe9\xc7\x8f\x7f\xff&\xfa\xe3\xee\xb1\x1fL?\x9e\xfdr\xfb\xf9\xec\xc12\x04\xef\xe3\xc7o\xeeyJ\xb5vW\x9f\xa5oT\x10\xfd\xf1\xd8?>\xfa\xf8\xf1\xa3\x1f|\xc6m\x1b\xed\xf2\x07g\x01\xb6\xf4\xcd~\xf4\xc7c\x86\x18\xdft\x03\xc2\xeb\xbd`\x85~\x8d\x8fV\xa7n\x96\x06|hF\xdc\x0d\x10?\x184X\xd8,\xef\xb7\xbf\xf9]\xff\xaf\x8e\xb2\xae\xe1*\xd8\x11\xb3(\xf3\xb5Qm\xf2:\xc6T\xde\x85\xff:.Z\x06|\xaf\xe3\xc2AQ\xd3\xaa\x85\xdbL\xb6\xd6y\x1e\x18\xdb8%5\xfb\xe8\x94\xd4\xad!\x9c\x92\xdaa\x08\xadZ\xca\x10\xfa\xcf{q\xa4\xaex\x92r*#\xbc\x8e\x8b>b\xae\xf8\xcbS\xd2am\x9c\x12\x9a\xcd\xa3\x8a\xd4\xecm{\x0d\xc3v\x0e\xea\xa1\xe5\x9fGK\xd2\xd7@\xb3D\xb8\xc3\x0d\xcc\xb9i\xa0\xe6\xe3\xd8\x16T\x8ew\xde\xe0\x8f?g4\xb4g\xa1\x85l\xf2\xf0@VQ<\x9fkF1\xecx\x0e<\x07\x83a\n\xd6\x98\x94\xfd)\xac\xf4Sh6\x94\x8e)\xba\xe2\x99\xe6\xbb\xee\x07\xc0\xb3\xf2\xe9\x9e/\xad\x13\x03Eg\x1a\xe9C\x1ai\xda\xbd\x19\xd3.&~~\x95\xd5>\xe1\x1e\x9b\xfe>ej\xf74\x8a\x8a-P[\\\xdf-\xb5T\xef\x8ae\xc8\xac\xc7c\xbd8s\xf4\xed\n\xab\x8bi}6~?\x0c7\xcd#.\xe9\x9av\xdd-*\xafq\x15D\xeb\xb8\xf0o\xb6\xd8.\xc3\xe3\\\xb3l\xf8\xddD\xf9.\xbb\xc9 \x00k\x0d\x00\\\xf7\x9a\n\x80\xb5\x1e\x00\xbf\xeb\xffE\x87E\x05\x85\xe9\x99\x8e/97\xf3%yo\x1eF\xf3\xa8+\x99\xc2y\xb6J\xd2\xf9\xab\x17:\x99\x0c\xc3Oe\xd2\xab\xfa|\x8c\xb5\xd7\xb5E\xc8\xf6>f\xd8G\xc6B\xd13\xcd\xffO\xd9e\x96_g\xc8s\xf8h\xc2\x0f~\\\x03c\x80\x16I\xca\xa2\xf2H\xd6\xe6\xef\xd1\x1f\xa7\x1f?~|p\xf6\x80Y\x1c\xef\x827au\xd3$#\xccM\x9a>\x0c<\x14<\xb19\xa69\x9b\xc3\xc5\x0d6\x9b\xc9\xf7\xaa\xf3\x87nB'}\xb8k\xf4\x05\xde\xef\xc9\xba\xa8o\xb0\xc1q\xf7\x1b\xde\xefk\xf2\xa96}(\xd4\xd8\xfc\x8f \xff#\x9a'U\x91\xc6hY\xca\xdc\x98\xf0i\xc6\x7fJ\x80\x0e\xce\xec\x93\x01\xa3B\xc4\x90Sz\xde\xbeh\xba\xd1Z\x97\x94\xa2b\xa3\x91\xefW\xcaE\xa5\xb7\xd7\x19)_\xbd\xe8a\xab\xd4\x8b\xa2\xe5\x8c\xae\xef<\x08B\xb8\xc6\xfc\x91\x80\xb1\xc8\xcf\xab|S\xce\xda\x1cE{'\x9d\xf6\xb4\xb6yvJXH\x9d\x92dcL\xab\xf4\xd6\x92\x14\xd03\xdf\xdb\x7f\x88\xd1\x923\xb9\xa1\xe8\xee\xeaW\x97\x92z\xc9$\xf5\xb2\xa5\xbe(\x87-\nY\x8e\xb9\xd2\x90Z\x1f\xb8\x0e/\xf7\x13\x93m\xa1\x1ck+:\x7f\xdc\x8cY\xaf\x8c\x8b#\xc2\x83\xf9(\xcch\xeb!6\xbaO\x1b\x8d\xa3\xa4z\x9do2\xba\xc9Xo\xdf\xed\xb7;+\xe2\x92d57\x90R~\x1ea\x8cr\xe5\x01^\x8e\xca\xd6\x0f<&\xec\xc9\xf7.\x176\x1d\xd5h\xf6\x03Y\xe4%y\xdd\xbaAu3\xe7/}c\xb8H\x0e\x87 h2\xaf\x03FSc\x03\x9e@\xa6\xaf\xc0\xec\x9e\xcc\xf6oby&05\xac\xbd\x84\xb9\xd9V\x8f\xc55\xe4\xc1s\xc6Z#\n\xc8\xfd\xc4\x1b\xd1\x83n\x9b\xddC1JA\x194\xfe\x91\x98\xd5\x8bb\xd5\x1b\x96y)\x87N|\xfd`\xea\xf6V\xae\x95a1\x97Va\xf1\xa6b\xf0\xc6r\x95\x92g\x030\xdbf\x8c\xa8\xc7m\x01\xac\x8e\x94\xb5\xdd\xdd\xb5\x8c&[\xdf)\xc8X\xa4\xc7\x16\xa4\xf6\xf5\x90\xaa|\xa2K\xc7x!\x82\xf7\x0f\x8d\xbb\xd8\x94K\xc2\x87N\xe6r\xf0\x95\xc5\xd5\x14\xc3j\x9eF\xe7EI\xaeHV\xbf\xdb\x94\xcb$3*j[\xc9\x94\xf6\x9e\x02\x81\xef\xe1B\xd2fb\xa6\xcd\xb4\x9c\xfb\x17Sr\xe6\xaa8\x03\x9c\xf8@\xd0\xfa\xe1[\xdaf\xb7\x7f\xc9\xe2 \x85\xcaN\x17\xa9\x86\xfa^\x92\xfa9\x8f\xecW\xc7\xb3\xcbg\xf39\xc9\xe6\x9b\xb5\xebHtVO\x836L\x82~\x9c\x0c\x86\xaf.\x99\xe5$Z\n\xe9\xcf\xbe\x1av\x8f\x18\xeb@\x1a\xae\x81s\x11\xd2*\xcav\x9e\x80\xa2\xe4Z\x88\x08\x87\x06\x8aL\xc1N\x9b\xcf\xa3\xf39\xb9\xd8,_\xbd0\xae\x00\x8e\x0d\x99\x9d\x16L\x7f\xb8y\xf5B\xc4\x9c\x17EcB\xdb\xfd\xc4\xb6\x14\x12\xcd\xf9z\x00y\x1a\xb0!|B\x8e\x9f\x08\xce\xeb\x1d\xdf\xbcC\xc8\xd3\x15i{\xb8\"\x8f.7\xfc\x18\xc4T*\x124\x12\x0b\xa6\xf5\xb4t\xaf0\x8f\xae#\xe8\xf0\xb1\x83\x839q\xf3)n\x1at\x1d\x84\x03\x18\xc4\x19\xe9\xd4=g\xb9]\xbbw\x87\x01\x12\x0e\xb6\xefpT\xecO\x89\xf2n\xa3{'\x19$\xb7\xe19@G\x1e\xcfk$Gi\xff\x15Y&UMJ\xc2\xe8U\xdc\xe5@\xaa\xd5\x9b<;\xad\xe3l\x1e\x97\xf3\xbf\xc5e\x96dK$\xbe\x0e\\\xb0\xf1FB\xa4>,I(\xf2\xc2N\xaat\xd8\xecH\xa2N2\x94;\xb5/\xc6\x86\xda?\xc5\xa7\xdb\x1b\x010G\x97\xeeu\xbf\xde\x9e\x969\x1b\xba\xe9{\xa09gH\x14\xcf\xe7'T\x80\xfc\x91{+2'\xa8\xeeSn\x1e\xb6\xb3\xaf\xb5\xadn\x1a]\xe7Wc\xd2\x8a\x08\xff{C_c1\x90\xc5\x9b\x881\xa4'6\xc9'\xd3<\xf0=\x8a\x00\xbb\x0c4w<\x959\xd1w\xb3\xcd,L~\xb5\xfd\xed?\x8b\x8bzS:\x06\xee\x80\xedW~\xef\xae\xc15\xb0\xf2\x9a\x8bKQ\x06`f\x1f]\xa9\xff\xd8\x05\xcc%\xe7\xa0^\x88$\xba\xeaL\x8d\xe6\xdf\xad\x84kwA\x0d\x1e\x1f\xe8\xc2\xf8\xd1\xe7\xfaP\x11\x87\x8f\xba\x99\x00\xb8[\xddw\x07A\xbb\xfd\x8d.M/\xf3aM\xf2\xecy\\\xc4\x17I\x9a\xd4\x89=u\xc2\xd5\x97&\xa0\x80\x8e\x14\xe6\xb7SQ\xdc\xbb\xc7\xb2Ox<\x8d\x00^\x1b}\xfe\xdcKI\xc1\x9e\x95\x1b\"*\xceXL\xff\x93yR\xc7\x17]\xa7`\x93\x03o\x92g\xaf\xb2E^\xb2(\xf4\x16\x0c\x17\x1a\xb6x`Jz4\xc5\x18\xfb\x04\xdd>\x8c)\xbe+1\xa0\xf7\xccc\x1c\x03\x1cj\x97\xc8G\xb7\x91M\xa4\xce\xc2'Zy\x1el'nI\xaa:/\x89l\xc7i\xf9\xd9\x05[lJ\xda\xc3tZ\xca\x9c\x0d\x13\xc6j\xedi\xeb\x14\xed;G\x9c\xe9\xc7\xab\xb52\x84\xdc7\xe5l`\xa1\xe30!\x90\x19z%\xd6\xd8D\x95\n\xbe2\x84*\x08!\xf1\xcb\xe1\xd0E*\xcc\x9d`\xa5\xd7\x1azr\xda\x18l\x1e\x13Q\x90\x007\x96\x1e\x83*\x16\x93^\x81\x17~\xa8\x87,\xc9\xe6\xad\xaa'\xd9\xbc\x8f\x15\xfd\x81I\xebP ^\xd9B\x7f\xb3\xab\xbb\xd6\xb4\xf1m\x12a\xbf\x1f\xee'\x87\xb8`\xf2\xf5\xcc\xb8\x8eD\x08*\x01\xf7\xb4\x12\x18b>)8\x10\xefg\x11=1\x10\x80\xbe7[\xc5e<\xabI\xe9\x85p\x9f\xa7\xf9\xe2\n\xee\x01\xb1\x04A\xcc\x1b\xa2\xcc\xe3`3\xdaV4Y\xfa\xb9\xddR-\xd2]\xbd\xc5\x98\xf7\xd5\xb0*\xe1\xf3\xe7a\x941\x98\xb8\xe3\x04F\xaa\xef+\x03\xf2[n\xd0\xea\xa82\xe3*3\xbb$\x99&\xd6\x15E\xc5V\xaa\x7f\x91\xb6\x9b2w\x86\x1d\xd4\xdd \xb4v\xd8\xd9\x0bp\x04\xaf\xe3z\x15\xad\x93\xccG\xa7\xad\xd6b\xfd\xc6\xfb\x02\x1dt\xf86\xf8@>\xd5\x83[!\x89fy\x9a\xc6EE|d\xe1\x12\x13bg\xf2e\x0fYs\xb8\xcf_\xb3Y\xe9\x12\xcf\x8aH[\x95\x82\x93CQ\x94\xf4<\x12\xcb/\xb8\x15\x8f\xe4\x96\xe2\xa6\x830>\x01\xee\x8d\xd9q\\\x11\x02\xa2XO8n\xfe\x14\xdcy\xd0\x84\xe2\xeb+B\xf5\xea\xa5\x86\xf7\x9e\xd5\xc9\x15Q\xf2\x08\x91\xe8\"\x9fwRH \x81z(\xbc\x8f\xee\xbb\xdf\xb5\xff\xda\n\x9cW6\xef\xdb\xc7z\x86\xb3\x17f:\xd6\xfb\xea\xb2(\x0e\xfb\xdfv\x1b\xafZ.^}\x0f\xaf\x94\xf5\xf2\xb0+\x15\xcf\xf8\xf3n?\xcc8\xfe\xf0\xdb\xee\xf3\x82\xcf\xad\x1bub\xce\xfa\x17\xe1\xb0\x1f>\xea\x0e`\xc5:z\xdcy|\x85\x8f\x0f\x0e\xba\xe3Z\x8364\xdb\x92u\xdf\xcb\xdfu\xc3\xb9\xf6n3\x17\xaa\x03\xdb\xfe\xc3'\xddQ\x9d\xf3\xee\xbb\xd3\xb9n\x1c\xdb\x92~\x00\xe4N\xe5\x13\x8cQ\xa6\x8b\x1f\xdc\xaa\xf6 \x8e\xba\x9e\xd2\xa7p\x04O\xda\x8f\x9e\xd3Z\x9dj\x97\xc68\xde\xcf\x8c&h\xcc4L&\xcf\xa2\xbb\xf6\x14\x1fu\x93qMZ)\xc8\xba\xac\xae\xce:\xec\xad\xb9Sz\xb6\xca\xa0\x80\x8c\x84\xabO\xfck\x96\x8ew\xd8\xfa\xec\x9d\xd8n!\xf2\xa4\xdd\xbe\x90\x96\xb7\xa9\x06%O\x8b\xa8\x9f5\xdbtv\xc6\xe6\xe8=\xec.\xd1\x14\xf2\x03\x8e\xc0C/~\x16\x8ck\xc2L\x155w$1\x1cC\x0c\x13\x88\xbb\xf6x1\x9a\xe2\x05\xa1T\x95\xd5\xc9\x9a\xf4\xaet{\x13\xa6\xfb~\xd5\x89\xf3@\xc1\x94\x85<6\x01w\xa9D\x07\x98n\xf8\xa8DU\xcd\xd1\xfe\xe8Q\x95`\xc8\x81s\x16\xbdC1\xa0\x88\xcek\x0eD\x1e\x0e\x89e\x87\xffQ\x8d\x88\xf0*\xabsLa\xbd\xc1\x85\"\xb8P\xd9\xb0\xb5\xe4\x07eUuKJ\xc9\xe3:B\xe0\xbe'\xb3<\x9b%)\xf9P\xc6Y\x153\xfeuI\xeawy\x9e\x92\xb9\xbf\x83\xcc\xc1,\xdaT\xe49\x9e\xe6|\x01;\xb3\xce\xa3\x82\x94T\x02\xf5\xdf \xb1\x11\xe4|\x10\xe1`\x7f%I \xe5)\xf2\xe1i\xbd6\xe9\x8d\xf0*d/\x84U\xb4\xc94\xeb\x86\xd6D\x9d\xed)\xf8\xec\x9e\xf4\x15<\x85\xbaI\xfb\xf74\x80\x9a\xab\x81\xf0\xb7\xaf\xbc\x1b\x1e\xec+\xb3\xa5\xf0\xb3\xf1\x96\xc2U\xa4\xcbj\xae\xf3Q\x13f%t\xe9>\x7f\x86\x9d,:_\xe5\x15\xbf\xdb\x18cC\xfc\xb3\x91\xf4\xec\xf8;\xdc\xdeU\x02u\x07\xfd\xde$\x1f)\x9f\x9dj\x9e=\x1f\x06\xdc\x1b3\xe0\x1c$U\x0e^=\x9b\xce.\x88\xef\xdd\x1b\x0fN\xdc\x06mX\xf20{\xfd\x9bW\x93e-\xbb\xf6\xc2\x16\x9e\xe7Y\x1d'\x19)_e\x8b\xbcO\x05z\x07\x83\xf8\x8bN\xf1}\xffl{a\xb3\x88\xc7\x08R%^\xbe\xc2\x11\xbc\xefZ\xa95\xc3}\xa1\xf8(%U;\x88\n\x0f\xe7\xf9\xa2\x15\xd9\x06\xe3\x11\x0d\xf4.\xe6N\x07\xa0\x10\xfdfn\xb4A\xde\xd3\x87\x1e1T#\x82\xd2\xb9\xff\xd8\x93\x8c;\xdfL\xe0E\x87\xeb\x10A\x11\xaa\x1fn\x18\x01B(L\xe0\xb2\xc3\xd4a\xa2\xd4\xd7y\x96\xd4\xb9K\xc4\xc7\xae\x84\xd1\x112\xcf\xd9\xbd8\xedl\xc0\xd2U\x7f\xe8B\x03\xb6\x1f\xa3\xd6\xb8\xfc2\xb4\xab\xaf\xaf\"\x92\xfdcC6\x82T\x8b\x00\x19\x92x\x86L\x08\x95\xf5\x9e\xc7iz\x11\xcf.\xd5\x8a\xb9F~\xa2\x87\xd8\xe0\x9c\x196\xbc!\xd7\xd6ik\xe7\xfc3\xcf\x19R\xfa\xde\xe1w^\x10\xc2&\"Y\xb5)\x89\x92\x14\x97\x03\x02\x93J\xf77\xab\x10=1\xde<\xc6\x13\xee\xd6XG\x17T`!sf\x0dQ\xf9\x1f\xd0\xacY\x8cJ\xdf$\x0b\x8c+1\x89o$#\xad\xb8\x9c\xc6g\xf4\x8bp8\n\x07\x83\xd6\xe9\xe6\xa2. \x9e\xf2\x92(8C\xacc\xc6\x82\\`\x11\xadbT\xaerH>\xa6\x90\xfcQ0\x1f\xba\xee\xd4N\x1c\xd6\xf7\x8bF|\x15]\xc5i\x82&#\x1c\xeb\xfc<\xe4|\xde\x8b\xb7\xaf9A\x11\x96\xec\xad0C\x0dr<\xf1B\x93\xad\x8c\x07\x94\xaa\x93\x18\x83\xa3\x15qU%\xd9\x12b`\x95!M. \xfca\x9e\\\xfd!\xc4\x97\x80\xfdr=\x85\xe8\x07\xdf\x07\x90\x97\xf0\xfd<\xb9\x82\x07\x7f\x8a\xd0-DL\xd0\xb1\xc7YJ\xdb\xc7\x0e_\xe6\xf9@w/\xf3\x9cu\xf62\xcfEg\x99\x1a\x03Z\x89U\xc6\xf9f\xec\xf5\xc3*\xa9`\x1d\xdf\xc0\x05\x81Y\xbc\xa9\x98W\xcd&K\xf0\x02!\xc9\xb38Mo \xcd\xe39\x1dP}\x9dC\x92\xcdIA\xe1\x9b\xd50\xcb\x8b\x84Tt\xc8lL\xdc\x07\xc7\xb0\xa5\x98\x9fX\xdc\x19\xf9\x0b\xd3m\x1bR\xf8 h\xe2\x9ci:\xb0\x9a\x9fRq\xbb\xe0n\xa7\x06\x05\x122H\xe7E\x99\xcfHU!o\xc6\xc3\x99\xfaUt>c\x7f\x1a\x15B\xf4\xeb\xa5~\xe2T\x92\x7f\xe3\xeb\xf2d`\x12\x8c\xa1QSa?\x1d\x12{\x0cSY\x80\x7f\xee\xcf\xd8\x15\x80Y\x07L{X\xb0\x1e\xfaB\x05\xe5\xde7\x17i2\x93\xf1\xbb-\x96)sa,k=[\xd4\x9237\xf3\x85\xf9\"\x14@\xab\xa1\x17E\x9eq\xba\xc3\xd2O1\xac@\x82\xa4d\x1e\x84\xb0\xd0\xb6\xa3\xbfk\xfd\xb1'\x07<\xc3\xd8xvS\x0e\xe0\xc0]!\x1f\x99\x19\x00\xb7\xa6\x12\"r\x84;o}\x93\x82\xfd\x06\x8e\xe0\x95\xb1\x89\x0b*\x82a\x13)\xfe\xab C\x00\\9\"\x89w\xf7d\xa5\"a\x16\xc2E\x08I\xe0\x88\x08\xc6C\x8b\x1bK\xe3\x92^\x07!\\\xdb\x8f.\xb7\xfb\xfcf\x95\x07N Ud\x1c\xce\x08\xa2_X\xdb%\xd6\xcf\xcd\x81\xf8p\xcfD\xe6j\xdc\xed:\"\x83\x8e\x0c\xc6T\xb5\xaf\xd0n{_Q\x96\x7f\xe0\x01\x020\xd4D\xa3\x9191\xd0/!V\xed; '\xaf\xcb\xddc/\xa7u\x8f/9\x0b\xfb\\\xcek\xa1;@\xeb\x98\x9e\xb7n\xeb\xa7F\xf7\xa0;\xde\x93\x10b\x1dD(\xac\x14N\x8e\xb9\xa5\x0d\x86c\xdd\xe0^\x1b\n\xee3\x8ffq\xf6\x9el*\x9e\x19\x8a\x8eb\xd3\xc92C\xc5\x0b2\x8bg+\xc2v:\xad\xa1oQP\xf6M[_6\x8f\x9e\xff\xf9\xe4\xf9\xff:\xfd\xe95\xaa\x16\x99\xf6Q\xdf\xc2\xa6\x97\x93c\xc4\xc7\xe2t\xd8D\xf9\xa6&\xe5\x9f?\xbc\xfe\xd1\xd4Ke\x1b_\x08\xdd\xa8\xbc\xa2\x88\x13b \xb5Q\xe1\xe2Y\xaf\x16\xe9\xba\x90\xa9\x97O\xe2\xce)\x94\x9e\x94A\xa8\xfaWf\xcc\xb1r\xb0e\x10\x8c\x80H\xf5\\\x06\x9c\xe1\x91\xbf\xe5j\x1b\x1c\xec\x85P\xc0.\x1c\xec\xa1S\xf4\xc7\x0c\xfc\x8a\x94W\xa4d\xd5g\xe6\xea\xfa\x99\xe9tWtg\x1dx!h\xaee\xfb4\x03\xb5K\x86F\x0e\x19\xaf\xdd\xd3\xef\x19P\x81\x07\x98r\xd5\x90\xe9'\x94GIV\x91\xb2\xfeP\x12\xc2\x1c\x1b}F\x9d\xe81`\xe4\xd3.X\n\x80P\xb3\xd3kE\xab>\xf2:\xefG|\xfa\x85\xf7O\x87\x8f\xbe\x0d\xf4\xcd\x9b\x8f\xa5\xc6\x0fH\x03$TM*\x1a\xe37|\xed\x98\x95@\xd9DS}\x1a\xa01\x8fN\xb9l\xd0A\xb1\x060\x00\xeb\xb1\xf6;\x98\xc8Z,\xe4+\xcf\xeb\xd7\xb3\xf8\xfb\x82\xab\xbb::?'\xd5\xeb|\xbeI\x89F\xcd\xc3C\xb2f~\xf7\xea\x0d\xc3\xe7b\xbc|4\x7f)\xd5f\x8e\xa1\xd4Z\xd8\xcd\x859\\\xdb\xb4\xeeV\x1d\x0d\xaf\x83r>\xff;\xaaVqA:f\xd3t\xe7\xce\xca\xe4\x82L\x94\x8at\xfa\xa8\xc2\xfa\xc7&)\xc9\xbc=\xe2yR\x15\xf4,v\xfe\x80\xf9\x94\xd5C=4+\x10\xdc\xe1\x12\x84-8\x98\x11W\x7f\x0b\xcd\xaf<\xc0\x14\x16I\\\x89\x90\xb2\xccK\xf5\x8e\x04\x1f\xf4\xb8.\xfd\xddt\xbd*\xf3k\x8c\x80t\xc2\xbfj/\xa9\xde\xbc\xdb O\x95\xcb\xe4\xc7\xdd\x1bJ~\x9b\xdc\xb3S\x14\xa9\xae\xba7\xa41\xaf\xdf\xc5\xde\x0d\x7f\xdem\xbf\xe2\xcf\xbb\x17\xc0\xfc\"\xb9\x97^\x80_$\xf7\xd2\x0b,\xf8\xf3\xee\xc5/\xbbH>x\xa2\xbbH\xce\xfc\xc3\xc7\xddy\xb1\xfb\xe3\xfd\xc3n\xfbW\xbc\xfd\xee\xb5\xfa\x9a_\xabw\xdbY\xf2\xe7\xddy\xb1\x1b\xe4\xde=\xf4\x05\x07\x7fw\xba\xe7\xbc\x99\xeep\xae\xf9\xf05W\xc4\xb4zw\x94\x9f\xf0y\xef\xda\xfa\xb4\xafN\x7f\x0eG\xddh\xda\x97p\x04\x0f\xdb\x8f\x9eQN@\x04\x00|V.\xf1\x12\xa9:\xebD\x18|\xab\xd6\x12\xa1\xeb\xba\x95\xde\xa9\x950\xf4n\\\xe7\xa5\xa9\xf6\x07\xb5\xb6\x88<\xd8\xae\xf2\x9a\xdfb\xcb\xdf\xd3gg\x94g\x9b*\x03.\xe3\x9b3O\xf7\xf4\x87\xcdbA\xca\xde\xbb\x17q\x1d\xff5!\xd7\xbd\x17<\xc7\x87\xee\x03\xd2{\xf82\xcd\xe3\xfa\xf0@\xdf=\xbe|\xf4P\xff\xf2UV?6\xbe\xd9\x7fd|e\xea\xecu\\\xf4\x9e1\x17\x14\xf1\xf8C\xe7-\x8b \xd8\xfb\xe8\x94\xd4\xfdg\xc8\xdf\xf5\x1f\xdf\xac/\xf2\xb4\xf7\xf8\xa7\xc487|\xf5<\x8d\xd7\x05\x99\x9bk\x98\xa6O\xdf\xb5\xe6O\xc9\xbc\xf2\x1e\xc9\xa8\xf8\xeam\xe7\xe3\xbf\x91\xf8R\x02ig?\xd4262,\xef\xab\x10~\x0e\xe1M\x08\xefu\xb7w/B\xbc\xbb\xc9\xe0\x1e\x9c\xf6\x99\xeb\x9f\xf8\xab\xe7\xfdW\xff\xe0\xaf.\xdb\xe7\x03ei_\xe1%\xee\x0b*\xb5\xc31\xbc\xa2\xe3\x90#\x98\xd0\xdfA\x10\xaa\xda\xd3\x17R\x84x\xd1ol\xe7Z\xcd[\xdaa\x9e\xe8\x0c^\xe2\xbdBWJ\xa5\x9f\xbe4\x89\xc1thW~M%\xee\x1fe\xd3\x18\xd5\xf7E\xf7\xe02\xc4\xbf\xa5\x1d\xff\x13\x8e`E[\xe9\xbd\xa5\xe5\x078\xa25\x8e\xe0-\x15\xb8\xf1\xafwz\x05\xc6\x85:\xc1\x8a\x8e\xe2G\x83\xaa\x03[\xf9 \xdb{F\xff\xfa\x01\xb5ToLr\x81\x98\xeeO\xac\xee1\xfcr\x0b\x13Xv'\xff\x13\x1c\xc3\x82v\xbd\xf1_0\x1d\xe7\x04f\xf4w\xcc\x7f\xf7\x1a7\x82F\xf4\xba\xf3z\xfa\xcf3\xd9\xc1\x1b\xee/\xfb\x8bA\xefH\xc7\xb8\xa6\x1d\xfe\x93N\xbf\xdf\xdb\xef\xcc\xbf\xde\xa3\x0d\xde{`!\x18\xcb\xa0\x8f\"\x7f\x85#x\x8f\x9aj\x1d\x9a\xfcU\x0e\xf2\xaf\xfd\x97\xef16#bF\x88~\xed\x0d*\xca\x08`\x92}\xe9\xd9t\x00\xde\xdcbXC\xbf\x14\xbb\xb1D&\xe7}\xd7\x12<\x08u\xe8\x7fn\xeb\xd2p\x9f\xf3\x02\xc7\x9d\x87\xa0t\x9c\xbbvLa\xf6g8\x82\x7f\xc01b\xc6\x1c&P\xc0\x04\xff\xbe$7\xd5\xab\x0c\x03\xe2\xf6:\xfd\x1b\x1c\xc1K8\x16{{\x02\x7f\xee\x01\\h5\xfd\xbf\xd1U\xab\x15\xde\xcf4\x93\xbf!5)1\xc6\x13z\xe8\x9e\xa1%\xfd\x0b\x9c\x8f\xdb\xec\xe4\x93\x91\x1c\xe7\xc1\x93.\x87$8N}\"\xaa\xef\x1e\x8f\x9669<\x12\xe6u\x81W~;\x18Z\xbc\x95\xeb`\xe4\xb8\xf7\x1f\x1b\x92\xc2\x1ety2\xce)?\xd6g\x85=x\xd2}\xbei\xc2\xf62\x0f[\x11A\x97\x1d\xa0\x15%#\x83\n\xdfV\x94\x8d\xe9\x19\x8b\xb2\x81\xce[\x14\x04<\xcc\xc6\xb0{{{}a\x02\xb1\x1e\xe8N\x06\xc1\xeab\xeb\x81v\xd8cX\xb9{\xd4\xf6\xab\x8d\xcb\x9c\xb4\xaeuG\xae\xf0\xe3\xc7z\xcc<\xec\xc9H|\xb0\x8f\x0f\xb7\x1dl\xe2+\xa9\xa0\x99\xc9\x18&\xec\xf7\xbe`\xf0]4\xcc\xa5\xde2\xfed\x1b\xa6\xfeF\xa3Q\xa3@\xaeZi\xd7\xa8L\xe1Z\xc6\xfb\xb0\x0f\x13\xc0\xe0\xfd}\xe2e\xbdc\x93\xa8KA\x1a\x0b\xb9\x82\xc5\xfd\xbc\xbf\xcf\xaebs?i:c\x1d\xa1\x14\xc9\x82\xf7o\x82\xa7\xb0\xbb\x1b\xc3\xf7\xb0y\x1a@\xc5\xcd\x11\xa65\xecB|\xa6?\x17Y\xe3\xfawr@\xa9\xec\x816\xb5/{\xa9\x9f\x06\x90\x8a^L=\x08\xf6\x87\x05\x0c\xcd\xfc\nS\x8a\x11\x96S3\x04\x9d\xdeo\xfb\x85\xefn%a\x0f\xbe\x1f\xf8\xa5\x01A\xbf\xc0\xf7\x91S*\xa6\x15i\x12\xab\x87\xe05*\x16\xaf{Y\xce\xb3\xd3*w1\xb7\x81A\x05c@B\x0d\xd5\xcbzZ\xae\xa6\xf5\xa7=H\x99\xf7$\xea\xe2\xd9\x0dV3\x05\xc9\x1f\x90\xfe1^w\x04N\xd1\x884M\xe9/\xafr\x9b\xc0\xbc^,q\xdayTs\\\x11\xb4\xdedQ}\xc94;3\xd8\xdb)\xb0\xa4k\xd9\x80\xc2\xcf\xfc\xfd'\x07\xc1\x17h\xcf\xbe\xf6\x92\x1bM \xf54\x03\xc3\x88\x18\xbd\xa4\x92l\x91k3\x87\xd1\x92\xe6Km\xee0\xc0\x94\xb5e6\x81C\xfdKT\xdcM\xe0a\xef\xa5\xc659\xb3\x1ao\x82\xb2nSrF\xb9\xb6\xfb\x9a\xfb\xd0~\xd3\xccOs\x96g\x8bdYEi\xbeDs\xc0~=F\x02J5\xdb\x00\xa8f\xa7\x89\x8d\x91`\x97Z\x92 \xcb[\xafDR\xc5\x12\xfe\x04\xfb\xa8\x87f'\x00\xa5\xca\x94\xb0\xee?\x05J&\xcb\xa7\x10\xef\xee\x06\x94F\xd2\ngjkZ\xb2\x89\xa0\xfa\xd3\x91\x12\x92\x95+M\x83)9\x8b\xe2\xa2H\x11\xe5\x06\x0d\xda\xc5\xe9\x1a\xd1\xb5D\xfd6&)f\x17\xee\x1e}\x88\xf7\xb3\\/\xdb}\x8fOY\x05\x8aD\xbd\xf7\xf4!{\x8d\x18\xd8{\x8fO=\xad[>^Vc\x0e\xa8\xca\xe4\x17\x8f\xa8\x99\xf4\x91\xc00]\xa7S\xc2\x9a\x07\x8e21]M\xe3\xd7\xb9vpc\x8f\xc4\xc6\x978\xae\xa5u\xfa\xb3\xc0\xc0`\x90\xce}\xc4:\xbe$\x7f\xae\xeb\xc2\xa7\xc4\x97\xbc\xa4\xaf)Y*\xf2\xaa\xc6\x1f\x06\xd5\xc3\xc5&I\xe7\xef\xc9?6\xa4\xaa\xd5\xe6\xd4\xe7\x06\xd2\xc1r{\xab\x1f\xf1G\xfa\xfa%\xa9\xf2\xf4\xaaU\x9f?\x1a\xac\xcfMM4\x9f\xf17\xfa\xaf+R&q\x9a\xfc\x93\xbc'\x95\xfa\xad\xfa\\\xffe^\xbc\x9a\xab_\xacHZ\x90\xb2\x8a\xe8\xf3\xbbEc7\xdc\x91\xc4\xad\xd6\xeb\x0c\xf0\x84\x9e\x96\x8d\xfa\x84\xfe\x10-\xf7\xe9\xd1\x15w\x1d\xa1\xb5\x8cGQ2\x81\xd2p\xd2\x98\xa3\xe3\xf2.'\xba\xa8<\x1aM\x8e\xe0C\xe8h\x91+\xc8\xc5\xa0Q>W~\xa1\x97N\x94r\xcd\xa7|a\x00=\xf0If\x1anF2\x15k\xceNDx\x0d\x83\xe7wGp\xd0\xb9\xdd\x00^\xb9\xe5\x9c\x7f\xf9\xfc\xd9\xc0A\xb0\xaf\xf5\x90e\xfb\x7fS\xc6\x17)\x19\x00e\xb6Y\x13Q\xc7\xc0\x10,I\x8f.\x01h\x82\x10C\x1d\xd9On\x01\xb0\x1e\xbf\xa8\n\xe9\x96#\x9f\x88-\xd3\x1f\x138Dl\x11\xad\x8c\xc0\x9d:\x9a\xfbY\x08^\xcc\xfd\x8a\xb3\xfe\xd4s\x17\xfb\x18\xde\x9c+\xef\xdaO\xbdRG\x05KL\x05\xb5_Gt?\x1f\x1c*\"\xaf?\x1d\x1c\x82J\x072\xff\xe1\x81\xf2e8<\xf8\xce\x97\xdfn\xfbek\xb4\xe3\xbe\xdc\xba\xcf\xc3\xc3\xc7\xe6O5R{\xfb\xd0o\xbd\x92$\xb2\xd4c\xb7@-\x0dr\x13c@\x1fy\xf6\xdb\x93T\xea\x07\x93\x1b\xf1M\xec\xb6.\x1f\n\x7f\x82\x83\x8e\xb5x\xc3\\\x1e\x9c\xc1q\xfb\xe7\xc4\x98\n\x8d\xb29\xbe\xa6\xf5Cc\xeb\x87\xed\xd6\x0f\xcfP\xff\x1eDW\x07o\x0bRbL\x9aWh^\x12\xd7 \xc6/\xb9y\x9d\xcf5\x1e\x9f*\xa8[\xa9\xddTE\x0b&kP,\x10&\xe8\xf87\x13\xf4#\xf0I\x10\xb0(Qy\xd39s\x84U\xd2r}\xac0\xc7\x96\x174\x86a\xab\xf6'\x01L \xe1W[\xfaE\x1e\x9e\x9e\x9e\xbej\xfd\xc5\xcc\x02\xc9@8K\xdd\x12\x8dC\x00\xfb\x12\x99\xc8\xad\xc0A\xbfnG\x84\x80]\xf0\xce1}P+QZ\xb5\xf3\xff\xfd\xfe\x9b\xff\xf1\xf7{\x7f\xf4\x83\xf3\xdd\xa3\xe9/\x1f\xcfn\x9fN\xbe\xff\xd3\xe7\xe8\xe3\x83\xe3\xf0\xe3\xc7?x\xde}\x96<\xed\\g\x99\x0b\x0df\xb0\\\xe8\xcc\xf3\xb0\xb1\xa1\xdbo\xfa\xad\x95~}\xff<\xf8\xe5 \xbc\x0dD\xd3J\xe6\x12\xff<\xf8\xa3@\x80\xe6\x83\xe9\xf9Y\xf0\xc7o\xf8s\xcb\xc6UF\x851X\xe7~M\x87\xd1\x0f\xa4nX\xdc\xd8v\xa0\xf0\x06\xbd\xfb\xfdtL\xa667\xb66+N\x1fw\xf6\x90\x03q\xc6\xc4\xcaDWA\xdc\xc1\xb1\xe0Vb\xcf\xeel\xb3g?\x7f\x86\x1d\x12\x15q\xbd\xaa\xfa\x8du\xaa\xb3jC\xb1-@Qs\xf1\xea\xfd\nR\xb6\xcf!\xc9\xa0\xd4\x9b\xa8*\xeaXZi\x9a\x1b\xa2\xcc\x03\x87\x85\xf7\xee\xd9\xfbg\xafO>\x9c\xbc?e\x83O\xa2:\xff\xa9(laSD\xb9\xe2\x0eg\xb4\xa7ibP\xa6\x8aB;\x8c\x07\xe9el\x83}\x1cX\x87\x04\xd0\x18j\xdbk\x8aR\x15df\x8c\x13\xa6+t\x95XX\xd1\xdc\xfd\xa35\xa9W9\n]-(\xbb7 i\xfed \x9c\xa8Z4:(]\xc1\x0c4\xbe\xc9\x06]-(\x85\xa1W\xb2D\xe8\xcd\xe0Gz\xa7\x97\xfe\x9b\xf6\xaf\xadT\x96\xa0U[b\xe3\x9a\x0bp*g\x95~\xe6\xef?\xee\x06\xff\x00n\xb6\x86o\xbby(\xea(\xa9\xde>;=t\x125\x98.$/H\x16\x17\x89\x91\x89\xe0Y\x15(\xae\x17\x0d\xae\xd3\xc9\x1ez\x1a\x16<\xa9N\xaf\xe3\xe5\x92\x94\x07#\xc6P\xb1O\xb6\x18\xc3\x81n\x0cy\xf1j\xce\x12\xf0\xd7Q2\x7fY\xe6\xebwq\xbdz\x8d\xf8\xcd\xdcI\xeb(%\xcbxv\xf3\xaa\xff6\xa6o\x97\xa4\x96\xc7\xf9\xfb\xf8z\x84\xf8\xc2\xd9[F}\x8f\xd9Ib\xd7\xd7J\xc9/\x12[\xd7\xbc5\x18!f\xbb\xd5\\+\x11\x8b\xcb&\xa1\xdf;x\xe2$\x83'Nb\xa3z\x89\x12\x19i\xc7p\xef%H^\xa2\xf2\x85\x83\x0c\xca4\xf7\x13\x19\xf0\"\xf6\xf9\x1f\x9b\xb3\xa8\xca\xd7\xc4\xb7\x03\x14\xba+\xc2\xee\x16\xb5uu\x91\xd7\x0c\xd9\x10\xd0>>\x9bK\xdc\x80#\xd8\xd0\x87$\x9e\xad\xd4\x87\x15\x8b\x93Q\xaeQ\xcb\xc5w\xc4\x98\x0dQ\x90\x99~mY\x005D/\xb3\xd4\xa1\xb3\xd9\xc1\xb5F\x96\xaf\x8e\xbe\xf9F\x8emn\xba\x8b\x82\xde\x89m\x0c2+\x0e\xda\xccx\xca\"\x9f\xbd\x17\xc2\xa2uZ\x0e\xac\x9d\xc0\x18\xcc\x92\x15\xafIMJ\x0d\xdb!\x8a\x1cgE\xc7\x19\x07\xb0\xe3\xb0\xe7D\x91r\xe0\x948\xf0\x08;\x9did\x0d\xf6{\xb3<\xab\x93lC4\xa9a\xd4r\xc5]qs\x9f9\x7f\x99\x9cqE\xa1\xddj\x83\x02uK9\xad\xa8tB\xffc\x91\xca3\x8a\xc6\xf8\xf4\x08\xa6\x99ev\xc0\x87\x86\x87\xcb\xb4r\xa8M\x076k\x84\xa6\xfd\x00f}{'\x13\xbd\xd4\x15\x12\x9d\x9f\xe7e\xb2L\xb28U\xc4)\xe6\x96\xa1}\x83\x12\x8cBT\xc2\xf6O\x96\xb7\x9f%L\xe7W\xed\xd6\x81\xe8\\\xab\xbbE\x86\x00Td\xc4\xac-\xf4\xba\xcd\x98\x02\xbc\x80#\x98M\xf7\x1c\x00NKa\x84\x91\xe9\x0d\x15P\xda0*:0\xaa\xac=\x9b\x19%\xfb[\xe4\xe5\x9bm\xcc\xce\x18\xeb\xb6\x04\x0e\x9d\xb9%U\x84ZV\x06\xda\xd7-\x92^\\QzQ\x07\xe0\x15e>\xdf\xcc\x08\x1f\xdc\x15\n\x02\xb3<\xab6\xeb\xf6\xb3\x8a\xcc6eR\xdf\x88g\x9f?\x83\xbf\x9a^\x9d\xa1\xb1\xdb\xd5Y\x08s\xb6\xf3V\xba\x0ca\xddB\x01\xb3A\xc6f\xa5\x909v\xa64\xed\xd0\xbf\xb97\xa0\x03\xc8\x80\x83m\xcd\x14\xf5N\xf5\x81{\x18\x98\x14\xe1\xbar\x03G\\Ab\x9f'X3pt\x8b\\\xa0\x8b\x10\x9d\x16(\xd1M\x1b\xa2;\x0f\x9e\xc2\x8eO\xa7\xe8_\xc0\x11\x9cG\x19\xf9T\xfbA\x10\xcd\xf3\x8c\x04O\xf9\xe4]\xc1%\n\xed\x8f\xb2z\x17,\x00\xa8\xdb\xbcD\x91#>\xa1(um'3\xdd\xc2n\x90N\xce\xc6\x8eZ\x94\xde.\xa3\x0c\xcf\xc9\xb6\xad\x01\x87\xc7\xa7\x91h\xa4+\xa7#QKW\x9e\x8fD7]\x19\x87\x82\xba\"\x17\xf92D\xa7\x95\x0eZ^\xd3\xe5\xa3\x98I\xa1\xe6_\xc2\x11<\xebb\xe6'\x8e\x99;\xf6\xab\x981\xe5\x8a\x87\"\xbf\xdc\x06uu\x85bb\x87\xd7v>\xc5mE\xde\x1be\x1e\x81\xb7\x19*p\xc4\\\n\xc4\xbcq\xfe\xd4q\x9d\xac\xb5\xb6\x150n\xfdJ\x0f\x1b\x8d\xf9K\xef\x89<\x89T\x85\x08G\x8e\xceMQ_E\xbb\xe0J\xd8\x87\xdf\xe9T\xb4\x85P\xd1\xf6\x82Z\x03\xf7\x17\xb6k(\xf8\xf0\x98\x07\xa4b\x11\xa1\\\x15rs\x08\x8d\x06\xab\xdf\xe9jL\xa7D\xb9w\xfc\xfb\xc7\xeb\xb3\x07\xcb\x84]\xfe\x0d\x80u\x9c\xe9\xc1\xe3'\x036\x16\xffo\x98\x1e\xdc\xcd\xd5s\x9a\xc7\xf3S\xa3\xc2\xb0\x94\x9c3\xd3R\xd0\xe6\x0d\xe9\xdb\xf5\xc9\xc6\xe4\xdb\xcb \x90(\xbf43\xf2\x9b2\xa5U6e\xca\\\xc5\x8c\x15\xab:\xae7\x15\xe6$\xc1\xbfl5Y\x8aPQ\x9b\xfe2\x7f\xb1\"\xf1\x9c\x94\xd5\x04\x12\x9fD\xfc\x87\x81B\xe8\x1b\x89\xe1\x08r\xf1\xe5\xd4\xe3y\x84\xee\xd3\x9d\xe7\x19\xf4\x10\x1b\xccC\xf9\xf93\x9c\xfb\xb1\xd9\x0f\xca\xdf\xa0kKM>\xb1\xf8\xe5\x17i~\xc1\x14X\x17\xe8'\x1e\x88\xcd\x1c\xd5+\x929(\xb9)\xc9\xceY{hH\x97G\xf3\xb8\x8e\xd9\xdf\x9b\xc0r\x00]\xf5\"\x01;(\xea\x84\xa63.\x8a4\x99\xa1\x02\xe9\xc1\xcf\x15\x8bO\xc1\\w\xfer\xfa\xf6MT\xc4eE|LA\xb4l\x8c>\xe3\x05\xf91\x8f\xe7C\x0c\xf4-\x1d\x85\x0e\x84\xa2\xe4\x98\x01\x01\x8e(\x85\xc8\xa3\xfc\xe2g0j\xf5\x9dX\x83\x9c\x8d\xf5\x84\xdbl\xeb\xb9\x01\xfd\xe9\xc3a\x91\xf7\xa9\x83\x9b\xe1B2\x9cT\xaaO\x19\xf6\x8c\x94a\xafM\x19\xf6\x18e\xd0\xe3\xaa\xce\xbf\x04\x94\xa5\x15\xe3SC\x8e\x10\xa1\xd6e\xf6@:\x1d\xaf\xf9r@ \xba9\xcd\xe8@\x85\xbf \x9a\xfaGI\xc5\x1d\xa1\xa6\xd9Y\x00\xc7\xac\xd2\x04\xa6\xf4\xff\xb3\x10\x7f\n\xb9\x8b\xe2\x93\xf0U\xd1@\x1d\xf1\xb7\x1b,s\xc0ld\xe0\xa4\xd0Gfy\x99\xf0#C\xc4\x89\x13\xcfd\x9c\xd1\xa3\xadl\xaeVm\xfb\x0dS\xe0\x17\x12\x15I\xf1\xa5\x06,\xcdM\xe3,Oy\xd6\x9a\x97\x98\xf0\xcc||\x90(N\xd3\xfc\xfad]\xd47\x18;\xd8|||\xd9\xcc\x8fE\xf2\x1dJ\x1f\xf5WX\xdd\x04@es\xfdb\xc8\xc8\x1f\xfb9\xcb\xdfp\xc1\xa2k\xa8 \xcd\xe5\xd7y\xff\xe3+\x91~'\x9b\xe5s\xf2\xd3\xfbW\x86\x80P\xa0p\x92\xa8\xcdM\xb8j\xe8\xa6\x99]\x1eX\x1dma\xd0\xfc\x16l\x81\x19\x95\xcf;\xf7\xe4:\xee0\x08\xcdW\xbe\xb9m\xa9rfd\xd4\xde\xbf8C\x97G\x18\xfe\x1d\x8e!\x8f\xd6q\xe1'A\xf4s\x9ed\xbe\x17zt\xf3z\xebMZ'\x0c}\xd4J0\xe9\xd4\xd7\x03`V]M\xc0\x0b\x0d\x06\x99\x15\xbe\xfd\x1f\x07{\x86\xf75{\xbf\xf7\xc4\xf0\x9en\xbfj\x02\xdeg\xaf\x0fP\xa4^\x94\xe9\xc0\x14\xd0\x9e\xe7\xb4M\xab\xe1{\xe0\xceU#\xda\x02\xce73U'7Dx\x85\xd1\xd64\x1b\xb8>\xa1\x9bvg\xa7\x8c\xaa\xcb\xa48\xa1\x88\x9ed\xcba\xab\x82\x9c\x87\xeb\xefo\x0bc\x88V\xe0l\x95\x1d\x83EQ9\xf6/\xa2)\xc6^ny\xe2\xbf\x9d6\x82v\xa3Q\x88\"6\xf84\xa1\xc7\xcf\xc6\x8f\x8d\xeeJ\xa2pc\x1fC\x1a\xd2\x10\xf2 \xd4\x05v\x0e)Oo$0\xeb\x86\x9dB\xa90Y\xa0\xe1\x91~\x14l\x85\xcc\x0e\x0eI6Of\x14\xa3u\xf1R\xbb9o`\x00\x8f\xd3\xdf\x8e\x95Aq\xc3*\xf9\x08\xee\xd4\xf3\xd0\x9d\\[=\xc7\xd6\xfe\xb1!\xa5!\x8203\xa9Y\xe4\xe5Z\x7f\xd0\x0c\x86fM\xfb\xfb9 \xc6X\xb3@\x83\x04\xb1\x9fL\xc9\x19;)\x07\x10|`3\x168\x15\x83\x8c\xc3d\x12\xf9\xf29\x7f\xf9\x01_\x9a\xed;P\xe8{\x80\xf4\xbb\x88\xcb\xfa\xe3\x03\n\xa9\xfbT\"y\x90D5\xa9j\xbf\xb0\x9a|\xf08j\xa6\xf8\x9d\x80J\x04.\x01d\xe4\x1a\xe6\xa1\x06\xa8=\xf6\xd4*\xd6\xb06\xa3\xb8(H6gAu\x92i}\x86\xf6\xbdC\x00\xd6om\xa6\xf4\x94\xe3\xac\xfc\xc40\x1d\x1ez\x98\xe1T\x7f\x07j\x91L\x1bq\x058\xf8V\x98)\xb2*\xd2\xa4\xf6\xbdco\x00\x01\xae\xa0g\x0b\xbc\n\xa1\x1b\x8aB-K\xba\x9b\xa6{\x03G ^ O\xf7\x07j\\\xa0=\x86\x19\x85nl\xf8q\x8e\xe9\x96\x04 db\xe6\xcd\x00\xb2t\x90#\xd7 \x87\xeb\xa6\xe3\x8bu>%f%6e\xab.ZCl\xa8\xf4\xf9PFmP\xa9u?\x0b\xa7(&\x8c3\"\xc4\xb5-\x9d\x8d(\xf2fSG\xb0C\x96\x0c\x08\xcfG\x12\xb0l\xbf{O!\x83\xef\x81<\x85lw7\x10bYC\xb8\x87\xac\x8d\x04gRG\x8b$\xadI9~1\xccZ\xfb[\xc1O\xde3\xb9@@\xd3LI\x8f\x84c\x0fv\xf1(\xf7\xfal\x1d \xa3p\x11BE\x99^}{L\xe1u\x04K\xd8\x85\xeb\xb0\xd9\xd4x\x928\xecj\xed\x94\xbe\xb2\xc1q\x08uT\xad\xf2M:\x7f\x91_gi\x1e\xcf\x9f\xa1Z\x8deg%\xe9\xc2p\xdd.\xed\xc3\xfc\xcc?\xe8eK\xa4Eh\xc5\xf7\x86\x94\xe2Z\xa3\xe6\xb9\xd0\xa7\xeb^\xae\x1a\x8b\xe7\xfe\xcb+\xf1Rc\x0f\xad\xba\x1a\x0b\x9b`\xf9\xec\xcf\xec\x8c\x136\xc1l\x07Ri\xf8m\xf9\xbf\xe9\xea K\xce5)\x97\xe4U\x86\xcf\xde\x96\xb4\x02\x1cA\x8ao\xb8\xc3\xb7C\xc0\x1bh\xd6Zz\xdf\xd8\x11\xdf,\x11\xb2]Y\x7fq3\xda\xfa\xb2E\xad\xfb\xad(B\xf2\xeeg\x90a \xbaK\xab\x9b\x03\xaa\x8c\xf5,2\x08\x82\xaa\x01\xbf_\xf2\xc8\xe85\xfe\x95\xf9\xa4\x97\xa8[6\xd1F}Z\xf9\xe0;\x8d\xc5\xfdZ\xa0\xb5\x169\x97\x02\xc5\xbe\xd5\xbd\xbd\x11\xdf\xf6Ru\x02?\xf5\xe4\xae\xd2\x83\xa3\xed(op\xda\xe8\x83a\x02\x9a\xf4\xee\xdd\x1d\xc0\x8f\"\xdbI \x88?=2\xaf\x14S+y\x94\xad\xe3\xf2RRj f\xae\nUL,!\x17Kn\xa0\x97\x01\xf6\x8d2\xc0~[\x06\xd8?\x1b\x08C(Ng9\xcc\xeb2.\x1c\x0f\x14\x16\x82\xfdi\x00\xd5u\xc2T\xc5QQ\x92+\xe4\x8d3\xf2\xc9\xca6\xce\xe2\x8a\xc0\xded\xb0\x0e\x08\xd3,\x93\x10[\xdb\x84X\x91\xc2\x1e5\x02\x14\x96u@O\x1c\x0c6\xbf\x92\x04\xac\xf9\xfb\xf3gL.\xa7\xdd6q\x10\xc2N\x1c\x95,\xa4\x04\xa6)\x9b\x91\xa2\xce\x07w\xb9Z\x18`\xe0\x08\xf6\x1d\x0d\xb1.J\x12_Zk\xda\xef\x87\xe5\xb5$\xef\xff\x11\x9d~\x7f\x1e\xda\xfb\x17\xb5\xe0\x9a=r[3\x12\xd5{\xcc\x1c\x9fdu\x08\xf4\xe7h8=\xf9u\xc1\xc4\x87\x1c;\x00\xe1\x89\x1d\x08,\xe3lmYjlm\xdfa\x1f(\xa7_<$|\xc6&\xe13\x1c\x96/y8+\xce\x81\x19\xbb\x90<\x9a\xb1\x1f~\xb8\x88\x08z\x92,\xec\x1f\x86\xca\x0ex\x14\x82\x8f\xf9\x1eJ\x8c\xed\x82\x071\x06y\xa1O\xcbt\xf8\"\x0b$\xe0\x1c\x90Q\xb2\xab*2\x8aa<\xa1{]=@|\x16\xaf\xd4\xadw\x07,\xa0[A\xed\x1a HU\xe4YE\xbe\x84\x82\x1c|\xf7\xebn\x8d.\x0598d$\xa47\x13\xa3\x0eP\x14\x84\xdc\xc1\xa1\x1b\xe4HT\xef\xb7\x89\xc8\xfexP=\xfauA\xc5\xc7l\xc9\x0f\xc3\xc0\xe0\x82\xbe\x8c\x8c\x18\x9c\xc3Da\xcd}goN\x82\xe5\xd0\x01\x83\x10$.\x1d;n\x04I\x0b\x0e\x9e\xe0b\x1e\xb0\xbb\xb4\xb8\x9e\xad\xfc\xfd\xc3\xc0\x10\xafFW\x9ai\x1c\xda\xa7\x01w\xb8\xba\xcc\xc4\x8b\x8e\xdd\x01.\x87\x0eh\xce\x1a\xf4s\xae\x94c\x19%J\xc5Z#\x08\xf8\x8f\xe7\xf9\x1c\xc3\xc5\xf2\x9fL]\xc5L@ \x97{Q\xde\xc6G\xf5A\xa8\xbb\x99S\x0b\x1b\xa5\x03\xda \x19\x8b\xf2\xcb\xd1\xeb\xf3\xd0\x02'Q\xeev}\xf0\x16\xd1\x0d\x9c\x89\x0e\x9c\x89\x04'}\x1cv\x93\xcfw\x0b\x82\xf1\xe1\x81\x1d\x8c\x92\x8c\xc6\x17\xe5\xa6\xa8}\x8f=\xf0\xc2^ \xefna]X\xf0 +y$\x9b{#\x86R\xd5y1`\"\xa9\x07\xf9-K\x93\x871S\xa7\xc6o\xa7\xf4\xcc?x\xa2\xd7\xf9i\x02\x18\xdc\xea\xd4D|\xa0v\x85t\x03\\\x16\x92\x10\x07'%![(\x8d\xdbnVB\xa125*{\x06%B>\x98\x07\xfe\xcfU\x9e}\xfe\xb4N?\xdf\xc4\xeb\xf43\xa6\x00\xfdx\xf1\x80\xf1\\_|\xb9\xd3\x8d\x10\xb2\xad9\xe1\xc3\xfd\xffxk\xc2\x81\xc1\xb4/1I\xa0\x06Q\xfe\x1eCi\xe2\xd5\x97\xf7\x00\x83\xa0\xe0M\xba]F\x16\xe6\x04\x99`\x02\xddkTS\xe3\xb3\x01\x13)#\xa3\x85\xbaR\xba9\xd8\xbc\x9b\x00\xcfti\xce\x95\xa5\x19GZ5S\x991+g\x9d9\xaa#i]\x0c3\x19\xeeW\xa4\xfc\x0b\x85\xf1\xd2\x8d\xcaiL\x85\x9d\xf1\x19i\x94ua6\xca2\x0db\xee0\x08Q\xb9e&\xeb\xd4\xfaJ\xdf:zAY\xf6\xb8\x88\x9b4x!\xe1\xc5\xf3\xb9\xb0\x8a\xff\xfc\x99\xb2#\xeb\xfc\x8a\xb4\x9f0\x06\xc5\x10\x99\xc6\xb8/;\xc6Z\xa6 ^\x0d\x82\x0f\xa7\xff\xf93\xd0\xb9\"$\xd7\x9b:\x16\x90D\xc9\xfb\xc6\xd1\xd4x=\xd8\xcf\x15o\xdfo\xe0AA\xd7\x07\x80|\x8a\xb7\x16\xbag/\x08)\x9a\xe7n8\xb4t\xc0\xa1\xaf\x8e\xc87Fcl\xb3\x87\x06\x1f\xe1\xa9\xbc\xd6Z\x92\x1aM\xaf\x7f\xb8y\x97'\x19\xa5\x08\xfd\x18\xb8\x00.n\x0f\x82\xbcw\xb2\x86\x86\xda\x88\xd1\xbf3\xff\xbas\xa3\x84\xbe\xecz1t\xeb\x7f\xce_\x1ej\x0d\x06\xae\x87\xec\x10N\xc4\xa7\xda\xdb\xdcO\xe26W\xf7\xf2T|\xaa\xb5~x>d\xc3p)>\xd5:\x0c>\x13o\x1f\xf7\x8d\x18\x9a+\xdc>4\xe3\xf9|2,'\x8b2(3\x81\x90\x9b\xe8>\x1d0\x1c\x1c\x92\x9b@\x91\x9d\xb4\x154\x08\xd6o\x89\x93\x85 $\xbaw\x94\x8a\xde\xe9|9a\xb6Ny\xfb !\xf5\xba\xab1S\xba\xe8\x1a'\x8a8\x899\x19\xca\x86\xa3\xe5\xdc\x06\xdd %\xad\xb7!L\x87\xb6\xa3\x89\x9a\x9b\x0e\x1ae=\xdb\x8a\x0b\xdd\x9a\xdaV\xf1\xaa!\xb6\xe6\x11f\xcc\xeb\xf85\xa9c\x1c\x1d\xa9\x00\x83}\xadI\x8d\xaa\xcd\xb5_3\xd5B\xc7\x8f\\\xd0\xfc\xcf\x9f[xEk^\xe9)\xd7U\xc8\x9b\x15\xe9l\xafl00\x9e\x85\xf5Y\x10\xde\xf1\xc8m\xc0\\v\x0e\xc7a<\xbb\xd0\x83`)A0\x1ee\x14\x06\xe0\xc2\xc8\x00h\x9f\x8a\xdd\xd7{\xa9a\xcf\x8a\xb8$Y\x8d\xa1\xba5<\xda\x10\x83\xd6\xf1\xf0\xac\xed\xf1\xaa\x95\x84\x9aG\x98B\x17\xf1\x95]\x9b0\xbf\x97\x92\xf9\xbd\x18aE\xfbE\x9f\x18\xd4\xc3\xa2s\xb0\xa5O\xf1\xba\xef\xfd\xa3\x01\xc6\"\x8d\xeb\x9ad\x13\xd0\x04}Yl\xd2\xf4\xe6\x8d\x08g\x84s\x1e\xe1;\xbe\xf0g~\xea\x93\xae\xf6\x1a\xf4\xe3\xc8:\xddh<1\x93\xea]\x99\xaf\x93\x8a\x8c\x18D\xc1\xb5\x86s\x9f`,\x14\xa7\xb1p\xcf\xae7\xe4\xda\x117\x86\xe3\xa3\xf0\xa1\xe0}m\xa5U\xb5\x01\xb8\xa8\xdb`\x08\xcf\xc1U\xc4j&\xf7\xaeL\xd6I\x9d8kA\xdcg\xb9\xf9\xcdg\x99T\x7f\xa9\xf2\x8c\xcb`+\xdd\xfb\xe7L\xde\xed\x89i\x16\x84\x92jn!/\x9b\xb4\xdc`\x1a\x18\xefQ\xe3\x1b\x9fT\xaf\xb9&b\x02W\xba\xd7\xcf\xe6s\\\xb0\xa6\xdaZW\xed\x7f\x92\x8c\x94q\x9d\x97#\xe6\xf5\\\x92d\xe5\xfb\x97\xcd\xd7ns\x13\x1fL@\x93P \xa9\x18\xdb=\x81B\xf7\xf2\x84\xe5\xaeu\x1eq+x\n~\xdc\x1fc\xeb \x95\xdf\x15C\x1f\xa9\x0c\xfd\x9dRap#t\xa3\x8e}A\xae\xb4'\xdb~\xba?\x94fm\xf8\xd3'{\x03\x86M\xb6O\xb7\xcebw\xb0\xf7\x9d\xf9\xd3\xff`s*q\xbfw\x07\xfeJz>\x8c\xe5o\xe8;\xae\xe8k\x97\xbcv\xcfF]_\x9d\x850\xb8N\xea\xd5\xf3\x92\xccIV'qZ\xc11xI6K7s\x82&`U\xbc&\xf7Y\x9cx\x8d+\xb6`\x03\xc4z\xdb\x14yd@hB\xe7\xbe\x81Pm\"p\x9d9\xbd&`G]XML\x01\xecX\xf5\x1e\xb0\x8cyTA\x8d\x177,\xfc=\x9b\xd1\xb6&\x9a\xd0g\xc6\xcf\x06\xd2\x1b\xcd\x9a\xe5\x99h\"\x88\x01\x8aw\xaea\xe0@\x95c/\xf2\xb9>x\xa7.\xcb\xc9\xef\xcc\xbf~\x85\xdb\xbdd\xe8\xb2,\x1e\xf0\xe9]\xc7\x97,\xb7\xf2_N\xdf\xbe\x11N\xbd\xb3\x94\xc4\xe5\xf3x\xb6\"6\xbb\xd6**\xd2\xcd2\xc9\xaa\xa8$\x8bJ\xf9\xb0cB|\xeb\x9aQ\x1eT\xc2R\x9b\x17J\x10\x97z\x95\x18\x92\x99\x9c\xa0X\xd8\x19\xe0<\x9f\xe1\xf0X\x14]\x12\x84\xdd\x19,TX\xf8\xd7C\xeae\xddf2\x84;\x01\xd3f\xba0\xe0\x97~JB\x8c\x9a\xb6\x07m\xd0i\n\xeb \x01N\xd5\xb0cI\x81\x931MM\xd3X\x13\xf2>\x08\xf5\xdf\xad\xf5\xdf1\x9cN\x08~\xc7\x8f.$\xec\x85\xb6~\x9c\xa6o\x17A\xd8\x8d\xf9n\x06\xb55k\x9b\xbc\x11\x1a\xa6<\x17qE^\xe4\xb3 \x9clCi\xf8\xf0\x07IfW[\xa1\xe5\xbdE\xa1\x82\xfe\x8b\xa4\x9aQ1$c\xec\xaa\x86\xebmj\xf3\xd5y\x1d\xcf\xca\\\xcb?\x8b\xb2\xce\xe7$\x15\x94\x86W\xefGE\x01\x854\x9e\xbb\xe4E\x86\x8eos\xdc\xac]b\xf4mv\xd5\x1b&\xdb\xb8\x1d\x8b\xf2\xa5\xee\xc7\xa2\xb8\xba!\x8b\"\xcf\x8a\x9e\x07\x87\xc9\x16\xb4[\x98\xeb\xa0[\x8fc\x1c:D\x91#\xb48v\x882\xac\xf2\xe6\x8e\x1e\xe6f\xb4>\x1b\xa283D\x9d\x0f\x9c}8D1(\xd2\xfd\x00&0\xeb%\x13\xb3\x9d\xe6\xa0\x90^\xc2N\x083\x8b9\x94pl1\x1cd\x8bE\x92\xa2{W\xff~\xde\xc4\x8fT(\x8c\xbe\xee\xaa\x1d\xb0\x0b3\x17\x19R\xdc\xb1]\xd2\xa3E\xfa\xcak9\xc66}\xd1\xd7^\xf2\xa6U\xc2\xa5\xaf\x89\xf1\xe3\x9dy\xf9\x0b^\xdb\x91\x97?g\xebr\x99\x14B\x97\x87<\xa7\xbe\xf25\x8b\xe7U\xd7\x1a\x19\x1d\xb8\xc1\x13\x89\xf8Ibd\xfai\xad\x13tc\x0e\xb1E\xbc\xd5\xbe\xa6\xffl\x04\x9d\x0b1fN\xed\x97\x18\x91\xd1\xcck\x8c\xe03\x1cy\x8c\xdb\xc0?\xe1t\xbf\x9b\xfa\xbd\xcfZn8\xf7\xa8\xb5\xb4\xe2\xd2\xfc\xbe\xe6\x15K\xbbY\x19Rnf\xfe\xd6\xba\x83\x83\xbd\xad\x93\xbb?\xd9Z\xfe\xdfZ\xfa\x1f\x18\xabU\xf6W\xdf\xdc\xb9\x10a\xe2\xc8\x0d\xfaOy\xa2\x9b\xd9\x03TAE\xb3\xb8\xa87%9\xad\xe3\xd9\xe5\x872\x9e\x1186\xbd\xe1\x04\x9d\xfe\x1b\xcd\xf2\xac\xaa\xcb\xcd\x0c\xdd\xdf'\xecYEkR^C\xfan\x06\xec\x99\xe5\xaaA\x1fx+k\x05\xde*Y\xe0\xad\x92\x05\xde*ww\x03\xc8\xa6e;\xf0Vi\xe0\xacqpkRU\xf1\x92`\xae\xc6\xbd\xb3\x90\x99\xd0\xd4\xad\x93J\xa7l7\x11\x8c\xac\xb9\x8bW\x9dUC\xf5\x05\xcf\xedC\x8f`\xf5\xa9\x02:\xfai\xd8q\xa8\x1a\xad\xf5\xfb\xed\xf12\xa9^\x96\x84\xa47o\xe25\xb1\xe7w\x90\x86\xe4S\xd2\xf2\xc7\xd1\xae\x1d;\xc4\xa5\x0b\x9d\x91\x80\x97Q\x92\xcd\xc9\xa7\xb7\x0b\xca\xa5\xfc \xee\xefS\xda\x9d\xcb\x87Y\xf30q\x0d=)WZ4BX#}$\xb1\x12e\xf4i\xf2\x1a\xb9K\x17M?\xc7:\xb80 \x1dX\xe5\x85\xa0f5\x0b\xc1\x13\xe7\x05\xfe\x10\xf9\xf8^\xb4\xbf\x98\x89\x90\xb4\xd5\x83j\xb6\"\xeb\xb8\xfb\xb4\xd5\x88\xf2\xbc\xdd\x95\xda\x0c\xef\xe8\x946\xa7\x1f{\x82cg\xfd= \x9f\xe2u\x91\x12\xefl\x0c\xc6v\xc8\xf7\xc3/ \xc3\xadW\xff\x96*X$G\xc6\xedp\x07\n\xda\xfe6B\xf3\x86~03\n\x87\x8cG\xf9\xc3`\xef\x8c\x9c\xed \xc5T\xef3r%\x91>\xb9F\xab\x8f~'\x1d!TP\xdd~E\xb1g\x90r\x97\xa4\xca\xd3+\xe2w\xb5\x82\x96}[G\xf3\xa4\x8a/R\xc6]-\xe2\x19\xc1\x00Q\xdd1\x84\x18]\xfb\x92<+\x92\xeaC\xbc\x94\xd9C\xfd:\xd0G)\x1e\xa2A\xb34!\x99\\\xc1Nt\xb7\xdfL\xcbxh\xd62\xfah\xed\xffm\x80\x91\xe4\x1e\x05\xba\x8a\x82\xa1\xd4\xa7\xf3\xa9\xc4[\xad\xb7A\x8a\xbb\xf9;\x03SY\xfa\xa9!\x8cb\xe6\xef?2\x06Q\\\x0cEP\xd4\x86\xb0[17\xf9'\x86\x00\x8a\x99\xff\xad\x8e#^s\xbe\xb7\x0d\xd8\x1ce\x0d48\x94\x82A\xae\x06CL\xe5\x8f\xe8\"\xc9\xe6~\xb6I\xd3\x90\x7f\x16\xf0X\x1f\x14\x9f1m\xad\xd2\x04\x7f|\xba\xb9\xa8KB\xdf\xce\xd5\xb7\xe4\x13\x99mj\xb4\xd0\x11\x7f\xd3\xc7\x9d\x18\x8fi\xebA\xabB\x13\xf01\xed=\xa4\x15\xdbJd\xe5g\xc82\x85\xb0\xb3\xe1\x87M\x92\xf2f\xae\xa2w\xcf\xde?{}\xf2\xe1\xe4\xfd\xf9\x0f?\xbd\xfa\xf1\xc5\xc9\xfbS\xd3f\x82#Xi_\xd0\x0f.h\x9b\xef\x99\xd4\x84\xed\xaa\x0f\x10r$-X\x9f\xfd\xdd\x90\x17\xaf\xe6\x13Xc\xe2\xfb\xf6\x86\xc0q+-\xc8\xac\xd1\xe2\xf1\xffY\xd8\x17\xfe\x00\x9d\xfc\x98 \xc5\xfe4\x99\x8e\xdao [\x14\xa5\xbd\xcbm\x17o*n\x0d \x84`\x1d(.\xe8y4\x96fe/l\xf4R\xc8\xc3xt\xef{\x83\xbe\xbb\x94\x08WRi\xcf\x02\x88\xd7\x06\xed/\x89Vy\x85\xbe\xba>\xff\xf3\x082\xfc#@ 3I\x80\xbf\x17\xbf\x8e`\xca\xc5\xdcY\x9e\xca\xe8(\xde\x84\x8a\x13^p\x86_^\xc4\x15y\x17\xd7+\xfe\xa9\xfcy\x04T\xba\xb3/\x80\xaa\x03\xc9\xc7\n\xca\x16e\xd3\xde\x80\xd01\xfc\xe9\xfe\x17\x98\xb8l\xadW{\xb2\xf7h\xdbO\x0f\x1fn\xad\x1f{\xb27` \xf4\xef%\x9a\xa9\xbf\xee\x9c\x1bG\x9bdv\x01\x89\xb8I \xd5\xeb\xb8\x18\x08.\x9e\xc3@\x84\xf0d\xc8\x1dX\x1a\x0chu\xbe\x9b![\x83j\xc8W8\x15\xedj\x87$\x82\xa1\x1fj\x9d\x85\x17C\x9e\xc42C\xa86h\xb4\xe0\xe5\x0f\xf6\x86\xdc\x81\x87Y2E\x14\xbd\xf6I@E\xc1\x02\x8d\xb6\xad\xaa\x1a\x11n\xfdP+5\x89x\xeb\xda\x81\x8b8\xda\x87\xda\xb7\"\x8e\xf6Cm\xc3\"\x8e\xf6C\xed2 o\xf0\x87Z\xafm\xe1\x0e\xfeP\xeb\x98\xed\x94\x08A\xb9\x00\x1e<\x80;\xf9\xb5\x98\x98K\x82^.\x12\xf6b\x98\xcdd,\x92g\xf1'\x99\x93\x8b\xcd\xf2GrE(\xe7\x98d\x8b\xdcR_\xde\xfaO-\xael\xac\xe2\x9f\x93\xaa\xce\xcb\x1b\xb3\xd5\x9a(\x8cy\xb07+|s\x1d\xaa\x16\xcc:|.Y:\xdb\x07U\x1dSi\xc46\xd4\xc2\xb5\xbd\xc6\x0c\xc3\xd2\"\xaf\xf8\xa1$d\x82\x9b\xea\xdc,4\xa9\xa5Z\xe5\xd7/\xe8\x02\x9a31\x89\x12\xa7\xa93\x1c\xd8\xd2Q2M\xa5 FY-h\x91&\x17\xafI\xbd\xca\xe7\xd5\xa4\x8b\xab\x9dd0\x14u\x035\x10\xbcu\xdc\x1d\xc6\\\x93RJ\x14\xca\xc1\x04\xfc\x06eI$\xb7w\xbe$5S\x16\xf0\xceE\x05n\xf3\xad\xd6\xe3\x8f\xfa\xd5Wq\xf5~\x93\xc9\xaa\xecg\xbf\xdau\x19\x17\x05\x99\xbfk\xce&\xfaT\x98\xfa\xac\xe3\xc2\x97\xd5X\x1d\xa5\x89@\x84\xe4\x91\xc0\x89\x1a\x13j\xd1\x01\xc7>fD\xd4T\x8c\xe7s\x7fz\x166\x1cp`\xf9\x80\xe3\\\xf3\x11\x7f \xbf\xdb\x14\xf3\xb8&\x1c\xec\xbe\xda\x94\xde\xd2`\xd0\x11\x87\"\xc1\xbcA\x02\x12\xc2\xd4L\xbd.\xc9\xcd\x04<\xa4L\x03h\xc7Y\x03\xbb\xee@\x14\xe4\xef\xe94\x1a\x9a\xc7\x8c\xf5m\x1f\x82z\x9bV\x87Z-1\xbbBc\x17j\x19\xaa\x8c\x8f!\x83\xfb\xb0\x0f\x13\xd8\x0bBd?\xf6\x9fB\x0e\xdfC\xf6\x14\xf2\xdd\xdd\x00\xcai\x8e73\xadK\xb6\xdc\xc1%\x17\xdd\xbfy\x94\x95 J\xf3e\x13\x86Jc\xbd\xa1\x16\xb39\x8b\xc1Fd\xe8\x90a\xcbtE\xca\x8b\xbc\x1a\x8a\x04\xb1\xd5B\xc9v\x99\xf3_{\xd9l\x0d\xc0\xbf\xcf\x82M\xbd)\x06\xce\x84]\xf0\xce(C\x7ff\x8b\xca&\xcaWX\xcb\x86*\x8dYNKx\x05P\x04dAE\\lk\xd4\x827\xb9\x83*\x13Qr\x83\x08\xd0-B\xfa\x99*\xf4\x99\x9ex\x98F\xb8d\xd70h\xf4\xde\xab\x10\xc0\x04t\x04\xda\xc7\xb0m9\xbf\xc9Qk0\xe9G\xc4\xab\xca\xad\xdcu\xb7\\m\x93P[\x14>\xd1\x9d^\x889\xcc\xc5G\xaeHy3\xce\xb1Y-R\x86<\xe2I\x98\x9d\xbe4$\x1bkU\xb1o*\xde\xb7T\xd4tL-K?\x0f\xc1\x988\xb1[0\x16D\x08\xb3\x10\x16!\x14\xe8\x14\xbf\na\x8d\xee\xab7\xf6\xb1\x80n\x85p\x1a\xc2\xf3\x10.Cx\x16\xc2\xdb\x10\xde\xb9A\xbe[,+\x11o;~\xd0\xadL,V&\xdeje\xbae\xdb\x95\xea\x16\xcch\xdd\xa7A\xf9\xa8\x00\x16C%\x96\xf9r\xb6[\xa4nq\x0fk1T\xec!*l\x85\xa5b\xb8$7x\xd3\xbf\x98.T#\x9a;\x07\xde\xc3\xff,\xe0\xf1\x9d\xd7L\x0f\xe3D\xe3\xd9\xe9\xa3>\xf9\x92\xdc \x0d1%.u-,\xe2\xff\x97o\x93f\xa4\x8f\xbfl@\xe0\x96\x11\xc4V\\\x93H\xd9\n\x9a\x89)\x98\x1b\xa2\xe2m1\x9d\x9f\x85\xa8G[H\xab+\xd5l*\x08Q\x8d\xa6>\xc2\x93\x1dC\xa9\xcc\xf1\xcfu\x88\x87B\xa2\x0dD1\x9b\xe6\xd17\xdf\x94dq\xc6\xb2\x95\xee\xec\x85\xa8=\xdb\xd9gf\xbf\"\xed\x91\xa4\x99\xfb\x0fC\xb4\x0d\xee\xb8\xbe\xd0\x9fU\xf3\xd3\x98 \xd3\xb58\xa7C\xb2\x15J\x1c0\xce\xc5'8\x82\x13\xc4\x1d?\x08\xa2y\x9e91r.Eb\xe4\xe1\x7f\x18m\xc0\xe8&p\x04\x9fD\x10\xf9\xe7p\x04\xf9\xf4\xf4,\xc4\xf8\x95\x0b!\xf7\x9c\x06!\x86\xac\xd4\x9c^\xcf\x83\x10\xdeb\x96\x17\xc4\xb2\x10\x06\xd3\xfa\x8e)\xf1\xd8\x84H\xb6\xf2\xaf\x04\xf5\x9dg\xff\x0d&K\x91^W:\xb2\xf6\x16\xe5\xb6\xd9\xf4\xed\x19\xd2\xb4\x80Y\xb8\xa5d\x19\xd7\xe4\xff$$\x9d\xfb\xa5\xcf\xd8\xd6\"\x08\xc1\xab\xf7\xbc\x10\x0e\x1e\xdd\x05\xcdr\xc9\x81e+\x18x\x9aJ{\xa7,d\x0c=\x83\xef\x1c\x1f\x0e-)\xb8\\\xcb\xbf\n>P\xa0\xbd\xc3\xcc\x06\x19\x8b\xd0\x96a$\xbbw\xff\x0d8K\xe9r\x80\x87\xfb\n\x0b\xf8\x1c%\xbcK\xcc\xddZ\xdc\xc5\xfe8tt\x15\x1c*\x82Q\x89\x9b\xf4\x8b_62\xb8CV\xf0\xf0Ny\\\xc7\xcc\xaaC\xe5\xce&v\x07\x94M\xb2\x91\x87\x98\xb3\x153\x0b\xc6\"c\xde\xc3\x80\xf3\x9e{\x8c\xf7\x8c\xadi\x02m\x85\xc9\x1cw \x9b\xcbq?Ty\xe1\x87\xfb!\xec\\P2s\x12\xf1]\xa4\xfc\xddM\xc05\xb68\xa5Hs)\x9426c>\x0ca\xe7\xfc\xce\x89\xe2\xc3;\xd8\x81\xf0/D\x14Y\xde\xbd\xeb/\x9b\x14[\xc1;\xd86\x92D/\x92,\xa9V\xfe\xc3\xc3;\xc1-\x87D\x89\xb6\xd2\x1b\xd9\xde\x9d\x8c\xec\xf1\x97\x8dl\x1b?sS\x913t\xf4?7\x95\xedp\xf26\x84\xd8\x9e\x98\xd0V\xa6Tj\xa7$\x97\x92\xaf\x87\x8f\x1dB\x1a\x9b\xca\x94\xd2\xbc\x10\xa9\xc8\xc3\xef\xdc\xee\x0e\xba\xc5\x10\x15r\xa8\xdc\xb2\xc4\xf1\x9d\x8b\x83\x9b D\x9b+\x0c\xc9\xcb\xcf\x8d\x82\xeb.\xe6\x8a\xeeBj\xe2\x1f\x852f\xac\xa2\xba\xc8uw\xf8\xdd8mc\xf5\x19\x88\x81[`1\xa5\xd5\x18\x84x\x8d\x1e\x02w\xa1\xae(%\x97\xb4\xa5zb;\x9a<\x1e\xdf\xf9N[\xc2\x11\xac\x85\xc6\xa1\xec\x88m7\xfeR\xbcZ\xf28\xa3K)\xc1\xed\xefo\xb3J\xfb[p\xa4\x02\xdd$l\xb7\xd0En\xc1\x97\xb1\xf1n\xc1`\xcaq\x1el\xc1Pn=\xd0-N>\xb9W\xf7\x1fQ\xe8\xb2\xd4\xd3\x9cA|\x14\xf0\xfd\xbd\xc7\xf6w9\x9a?d\x12\xfa\x16\xfc\xa0\x1c\xd6\x81JO\x0e(\xff\xb7\xa0<\xdfJ\xe1\xffV[\xf2\x7f\xce\x99\xc4\xbb\x85%3\x16c\xa2\xfc\xdd\xd6\xf7}\xe5\x97j\x8b~-Z\xc1\xf8\xb3\xf9\xb8An\xad\xa0\x91\xee\x8c\x9c\xcb9\x18\xcb\x7f9\xe73\xef\x96^\xcfc\xf9+\xd6\xf3\xc8\x93\xe8K\xf8'9\xe2\x91\xfc\x92\x1b\x0e\xdc\x86P\x8e\xe7\x87\xa6\x8fB$(t\xf7\x1e\x8ca\x7f\xa6\x07\xc8\xee\xd0Mu\xe0\xc8\xee8\xb07\x16k\x8a[\x9f\x04}\x03\xe2\x9c\x99\x1d\x96\x81\xcd\x8a\x18\xa4=\xe8\x9bxM&\xc0\xa3.|\xfe<\x14~Q\x94V\xe8Y\x95!\x92\x8f\xfd\xdc2\xfa\xd1Q\x8d\xecVN\x94(\x8d\xb6r\xb2\xd1@\xbbw\x9b(\x8aE\xe4\xaam\x16\xdb1\x1eU\xbc?\x9c\xcc\n\xa4\xf7\xd6\x92\xd4\x82\xd3\xac^\xe6%k\xce\xaf\xd5\x8c\xae\xbf\x0d\xd0U\x83\xec;\x84\xbd4\xec\xecX|\xb72\xd8J\xc9K`\xa1\x0c\xb9\xd2\xfb\xcc-u\xa7Z$\xe8q\xe8\x16\xe0~\x05\xe8. \xc7hno?\x02\xb8\xd6\xf9\xa9Q\x13\"\xd9\x11\xa5\x06>\xb1\x1c\x1f\xaa\xd7n\xcb\x1f`Z\xf3\xfc3_\x11\x14\xef7\xd9\xf3|\x93\x0de\xb0\x1a\x0d\x0buB]\x98\xfbDl\xb0\xaf8)\xde\xd7\x87d\xc8 \x7f\xf4\xb4\xf4K\xdc\xcc\xcbm\x951\xe2\xcf\xb4V\xedeX\xf2\xaa\xaf\x08\x0fA\xe7^es\xf2\xe9W\x03\xc9\x87\xa4\xc0\xe4\xcbj\xe7N0\xf2\xb2\xcd\xfa\x82\x94\x1e\xec4\xbe\xd9p\x0c\xf7\xf7\xc1\x94&\x0d\xee\x04Lt\xb7\xde%t$\xbdkX\x83\xbb\x1f=w@\xd8\x96\xae9\xd8\xc8\xb6\xcc\x92\xc7\x916_C\xd4\xb2\xb3\xb6\xbf\x87\xf2\x9c\xa7TG\x1f\x8c\xa1x\x91_\x08+v\x80}E(\x0d\x03\xa5a\xf1\xda\xe9;\xe8f\xe1y&F\x1e\xach\x8d\xd7\x0b\xec\x1f@\xc6\xbd\xcd\x19Dm\x8bE\x0bf\xd8\x19NY\xa1\x16\xb4\x9b\xd0\x1aqKV\x025\x82\x19sK\xf0\xbb+\x00\xde\xff\xcck\x88!\xcb\xb3\xfb,\x0f0\xf3\x1b\xf3Bp\x19-\xf0!d\x91\xf4\xf1b\xb1\x83\x1b?.1\xf5\xb0\xc5Ys\x1e\xcb'2=\x91\xf0\xd5\xec\xb19\xcd\xf7l\"\xad\xf7\x1fV$s\x82+h\x8cM\xd5\\\x1a\x1a\x88U\xd2\xcd\xca'\\\xed&\x86\xbb]\x7f\xe2\x14\xd0\xf4\xc5\x96E\xb2\xc3\xba\xcc\x15\xdd\xe2\x96\x93D-\xfd\x8c\xc7]\xfc\xb463,\xb0~\x0d\x8e\xbc\x03\x991D\xc3\x06\x97v\xe6\xebvL\x16\xb1\xd2hO\xd1qJP^!\x19\xd5\x19\xe3\x88Z\\\xf5\xae\xc8\xb4\xbf\xdc6xdA$q\xba+\xfesM\xe2)\xe6BW\xc75\xc1\xf0\xbev\x14p\x0c\x1ebY\xe1\xe1\x11\xb3\xc0\x14\xd8\xaet\x81mvp3dJ\xa7\xbf\x02\xb2\xb0\\\xc6\xdb\npV\x84iq[]:\xd5\xc4\x07\xb4\x81\xe8{\xd8\x13!n8U\xfeP&d\x0eu\xce\xf3;C\xdc\xf6\n\x86z\x15\xd7\x90T\xd9\x1fj\xa8W\xa4$;\x9e\x0c\xb7\xd9\x1dFU\xa4 \x95\x18C\xd8\xff\n\x00\xee\x11\xdf\xaf\x05^'>\xb5\xd9c\xfc\xafN\x14\x19''!\x11eN\xb7M]\xb6\x154S\xcd\xac\x95m\xfb\x070\xbe\x81\x06\x8d\xd9\xfe\xe9x\xbb\xda\xdc(\x03~\x890\x0e \xee\xfdkB\xa5\xaa\xe5k\x1c\x07\xaa\xd2h\x0c\xee90\x90\x8d\x97\x18\xa0\xe6p/\xd4\x0bBH\xe1\x04\x15h\xa8\x1c\x93'\x05\x95k\x9eW\xb8\x1f-\x01\xd8\xbf\x00\x1c\xcf7eI\xb2\xad\xa0\xe2\x08\x11!w\xe8\xb4u\xfc\x15\x1f\x04\x7f\xfa\x95tG\xfd\xfeG\xccu\x14\xf5\x89\xf4\x92\xbb\x95\xb6\x9b\x00\xe6\xd7\xb0\xfbU\xe8q\x17\xf4#\x00b\x83\x87:\x97\x99\xda\xc7W\x99\x05')o\x17\x1fn\x8aQ:\x80\x11\x1b[\xd8<|\xa5\x8d\xf8cr1b\xe0\x8e\x83F\xf07a+\xee~\xe0\xe7K\xf25t\x8f\x0d\xcb\x8a\xc9\xf1\xdb\xdc\xeaW\x80\xbf\x12\x14\xe3+\xcc\x86m\x82&\xfc \x9d\xd4\x90\xb8\xb4\xf54\xaa\xadf\xe1\xbe\x07z\x13\xa9\xe8D\xbe\xce\xd9\xc4\x83\x8f\x8c\x99\xc8\x98Y\xf44\xe8\xc6\xc3\x08\xfe\x04>;\xd1\xbf\xc6,gi\x9e\x8d\xa2X\x8e\x93\xfc\xcb\xe9\xdb7<@\x1feMsE6\xfd\x1a\xe7\xab\x88\x8d5b&\xb6\x89H\x97lb\x9f4-\x84 \xce-\x81W\x93\xcc\x97k.\xda\xac( a\xfbH\x14\xd09\xfe\xedW\xc6\x99sM\x19\xc0\xba\xb9\xcf\xb5\x19\xc9\xa0R\xcf\xc9\x11_D\x8ck:h\xf1\xec\x0e\xc2\x06\xed+\x97\xda\xa8\xdc1\xb8v\xb7\x88}i\x8a\xb0\xa6+}\xe9\xe4\xeb\xf6f\x87\x85\x88\x96\xed6\n5\xb6+\x9ekN_\x89\x00b\xf8\x1d\xfba\xfd\xce=\xca\x04\x1b\x8d\xaa\x8a\xf5\x13\x11\x0eI\xa0I\xa3\x9a\x0dB\xf5\x9e\x99\x07\xb3M\xbed\x131]0\xbbV@\x9a\x8c\x11C\xd5\xdfx\xd3\x16\xb6\x1f\xb2\x0c\x1e~\xef\x19Rl\xca8k\xea\xff \xf6\xf7\xb4\xd7\xe5\xd6\x98\xbc\xa2\xb0\xf5\xcb\\\x17O,\x9cT\x99r?P\x99\xf4\xc3\xf7\xfeF\xfepE\xa0$\xf1lE\xe6\x10\xc3*.\xe7\x90&\xeb\xa4\x86|A\xc7\xcbMT\xa0\xdcd\x95g\xa3V\x0eD\xa2DW\xb9>\x87.5\x93zK\x03\x97}&\x92\x08i\x9b\x19oy\x00\xe3\xac\x0f\xc0\x01\x00\x00\xd0_\xfe8M\xfd\xcd\x97\x8e\x0fi\xa0\x88\x97\x13\x82\x0cmfm\xe56p\xcdN\xd0-\xdb\x91\xb4/\xd8\xa9\xbc\xc3Q\x03\xcd:Xv\x04\xa5}\x89\xc4\xb9\x9aE\x1a]\x85o \xab'J\x8e\x0dtu-p\x1f\x1cla\xc7]\xa6\x95\xaa\xd9\x97\x0bPD\x11\x87\xc7P&_]\x89\x99\xf1\xfe\xa8o6\x8e\xd1\xa3\xd4\xe2\x0e\x06Qdh\xb2\x8a\x99 w\\\x08J\xbf\x0e\xd9\xaa\xfe\x98\\\xf8A\x10<\x85\x1d\x9fB\xc0\xaf0\xa9A\xcb\x8c\xff)\x87M\x00\xc4\xaf\xf8\xe5\x87\xf3`\xc6\xdft\x89\x12s\xcbi\n0;\xc5\x11\xe5\x16\x16I\x16\xa7\xe9X\x80\x8d\x071-; %\xd7\x85bL]Hc\xeaQ\x8dm;l\x10\xeer\x01\xb70\xde\x8c\xfa\xdc\xcd\x86\x15\x9ck\xde\xb2;p\xd2G0\xeb\xe7\x12Q\xac\xe2\xb0(\xed+Q\x8ck\xeeO-\x91A\x9d\x8cQEa'\xfe\x04\xfaY\xfeu\xe56p\xb1\xa4\x1d\xb9\xceRTj\x99K\x95cf\xd12!2%\xec\xee\x16\x97\xf8i\xd6\x1a\xd2,\xc0\xf1`\xbc\x1dxo\x90\x8d1&}\xef\xd5\xad\xeel:1J\x07%YT\x13X\x0b4\xd1\xd3sL\xa1<\x81\xe5p\xad&\x05\xd7\x04n,Ue\x04\x9c \\\x88\xaa\xfd\xa9\xb4O 5\x0c\xf9u;By\x93ay\\<\xf8\xc3\x87\x03\xf1\xe0\x87?=x\xfc\xdd\xb6\x9f>\xde:\xa5\xe4\xc1\xf6\x91\xef\xf7\xf7\xb6\xfdt\xff\xbb\xed\x13\x04\xec\x7fIF\xca\xd6+\xa9\x94\xf9\x8d\xe2\xed\xeb\x07\x93\x1b\x95\x98,2LT\x93\x8aY5\xe9\x07\x80\xb5jq\x80Q\x99\xecm\xebV\x9d\xe5Z\x8a\xa1$i\\'W\x04~z\xffc\x08\xd7I\xbd\xca75\xac\xe2\xab$[B\x0c\"\x13E\x84Y\xbe'\xf0\x07\x19\xf4\xf4\x0f\xf2\x1d\x7fZ\xe3S].Bh\xa0\xf8\xa9'\x97\xd6Z\xf5w\x9f2\x89ep\x82^b\x84\x9e \x9f\x0c \xcf\xf3M:\x87,\xaf%DJ\xb2 %\xc9f\x04.\xc8,\xa6X\x93/&\x80\xb3\x16\xb92\x11\xc3:c6\x0d$\x1e\xc4)\x1f!\xe9\x05h\xa3P\xfb\xde\xef=\xb7V7\xc6\xe9 \x9b\xbfwS\xa2\x89o\x8b\xda\x084\xe09\xd5\x98\x9eeA0\xc0\xb1 \xab\x80\x14\x99\x90\xe1U\xa6\x0c\xc2E\xc3 ,{\x8b>\xec\xbfr~\xce\x15\xabz\x1eA\x97\x91\xc6\xca\x10\xf3\x91\xa9C\xe1v\x81\xee\xb8W\xf9\xa4+\xce\xda\xfaKM\xf8\xed\xb6\xd0\x95\xbe\x03!B\xeaWY\x88\xcep\x0c\xbae\xae\x038\x86\x1a&\xd0_\x96:\x80 \xf8\xb4U8\x82W,G\xf8_N\xdf\xbe\xe9\xcf\xdb\xc8O\xf2\xcey\x1b\xb5>U`\x88\xef\xdd@\x90Zq}\xa6\xbd\x85f\x9a7.\x17\x7f\x0f\xfbR5V\xf7\xeb\n\xdc>\xed\xde\xd1\xe91\x1d\xcd\x18\x9b\xac\xe4e\x87\xca\xf6\x89J\x91'YMJNG\xe8\x9e\x87yN*\xacC>%U\x0dI\x06\xf3|\x86\xa1\xa9\xb5\xf9Th\x91\xadh\xce\x14\xcd(\xf9t\xbb\xc9\x16\xf5P\x9e\xe9\x11\xad\x95\xfe\xb21\xf9 \xea\x8c?\xdc\x14\x84\xeb\xfbN>\x15dV\xa3\xaa\x8f}\x14\xc2\x12\xadi\xe9\xbcU\x90\xd1\xc3\xd3\xdbd,\xaf\xcc\xdc\x03\x96|\xe0\xaau\xa3c\x9e\x92\xf7\x80Y(\x92\xe9\xde\x99\xbc!!Q\xb5\xb9\xa8\xea\x12s\xc1\x80\xe7\xc9~\xa6g0\xc1\x0cXHb\x1fx\x01\xd3\x86\xb9a\xdfb\x90~\xeb@\xc3\xd9\x82\x13\x89J\x9b\x8cT\xb3\xb8 >\x91\xc9\x9f\x1e\xfc\xd7\xfe\x83e\x88\xb9\x9d\x94g{\xf8\xec\xbf\xbazP\xd3\xd0\x8a\xc1\xa15\xfdkzg\x1d\xed\xa9\xbd\x7f|\xc0\x1e\xee\xbbv?\x1fdP~\xf6\xeb\xc6\xa4wG\xa3\x95\x11\x9b\x97D\xb3U\\>\xab\xfdZ\xda\x0b\xe9\xe9\n\xcb^\x86\xa6C\xf7u\x1e\xfe\xbc/\x8e_j\xdac\x8a!;\x98\xb9^ \x0e\xfb\xf1{\xfe\x03k\xd0_;t3;M~%\xf8\xcc\x10\xb4:1q\x0d\xf5\x01\xef\xc5K\xcdpsL\xf5\x95\xf3\xc0\x15\x1f\xf0\xda\xb9\x0cA\x1b2Sh\xd2\xec\xa7\x0e\xf4\x01\xc1)\xe01\xdd\x12\x13\x84\x00\xb22q\xe1\x17A\x93@Z\xdb\xda\xad\x9f\x19V#\x86#\xf0\xf1\xee\xc2\xfb\xbe*\xc8l\x1d\x17\xf7);\xf8'/\xa0\xd4\xed\xf7\xd8\x89\x9ep\xd6p\x84\xce\xfc\x1d\xdb\x81\xe9Y\x80i\xcf^\xe43\x0cZ\xea'\x98\xca\xd0\x86B\x1b8\x02\xcf3Q\xffq\x19\xadi[\x1b:|\x84Q\x81\xb7\xaa\xf9t\x83$\x86\xfe\xef\xda\x9c\xd2$n\x92\x18c\xb6\xcf\xfd\xd8h\xe8\xa1\xe3h\x86\xe7\x9eO\x13\xbc\"\xc2\xff\xb9\x93\n\xbf\x7f\x89\xbb\xfbW\xfdu\xe7 \xbd\xdaC\xa3Kr5\x94\x93k=\x94Xk9\x98\xb0K\xa6\x82\xd2~{1\x94X\xeb\x9c%\xba\xd5e\xb3\xbd\x16}jSH\x9d\x88>\xb5\xcd~\x1aL\xf2{:\x94\x13\xeb\xb9\x18\xae\x16J\x97B&\xef\xbfz\xc6\xd3\xea\xbf'\xcb\x93O\x85\xef\xfd\xdd\x9f\xc6\xf7\xffy\xb6;y\xf0\xe0\xf3\x83\x07\x81\x17\x82\x97x\x9a\xef\xder}\xf5\xf3\xe6\x8c\xf5(k\xf7\x9e,\xf0\xf0\xf6\xec2\xb4(x\x03&2M\xe2\xc7,_\x7f\x87\xebGk\x00\xe0\x17\x9c:\x04\xef\x0f\xf2\x1d#\x87\xbd\xe7\x1f\xf8\xa4\x07\x94?\xaf\x8d\x8a(f\xcd\xf1MI\x16\x06K\x0e\xa1\x91\xec\xce\xdf@\xdbE\xc1\x8b\x00\xbc\x86a\xa7\xd2^\x08\xda\x83I\x14\x94\xc8i\xad\xcb(\xa9^\x96\x84\xa47o\xe25\x99\x07~e\x0d\xeeN\xfb\xc2\xb4sJ\xf6#?\x93\x14\xd3~1\xaag\xe2\xda\xc20\x05\xd1\x04\xd6\x9b\xaa\x86\x0b\"Y8\xf0)\x9a\xdc\x7fO\x16\x81\x913U\x0bk\xc5\xe1\xfe\x98\x8f}\x02\x0e\xd9A\x16\x1b\xbc\xa3_\xd9,\xcamW\xa4\x14\x8e\x0b8B\xb1\xdc\xdek\x81\xa1\xb7\xf7\x1c\"E`\xd8\xee)\xf3\x9b\xb5en\xa3\xe5\xca\xf1\xbe\xca\xed\x02\x85\xb6\x96\xd2\xae\x0b8\x86\xdc/BH\xa9 gL.+\xca\xb8\xdb\x01\x8e, =-\xec\xb5A\x15X\xe6v\x88\xc0\x18\xd4\x01\x8e>\x0c%\xae\xdc>p\xc5!\xd0\x1f\xc8\xad\xd7V$[6\x91\xc7\xac\x9d\xdd8\"\x03\x12\x90\x95?\x0f\xe1*\x84\n\xcd\xbb\x1c\x16\x029\xa1M\x9aR\xb6\xeb\n\x8e\xc1\xbfA\x91y.\xfc\x07\x19\x9f\xe8/\x05u\xf1o\x02\xc62/9\xd1\x1dV\x93q\x99\xf6_\x06%\\)\n\x8c\xc6\x88\x80\xee\xa9%OhD\xe9(Bh\xe3_\x850\x0f\x82\x88+\xad\xe0\x18\x96\xf2\xef ,\xbb&]N[\x0ddl\xa3\x11\xbb\x0d\xb6\x00/\x8c\x051l\x01f\x18 j\xb0o@\xe0j\xa4\xa5\xc6\xc5\x98\xd3\xa9\xe9\xa9\xa2\xdeZ\xe7W\x84\n3\xb0t\xc8\xfaE\xf7\xefEK\x1b$\xa4\xe4\n\xd3\xdf\xb8-\xc77\x1c\xae\xd6\xca\xb63\x0b\x84\xc6\x89\xee\xca+\x14R\xd3f\x96\x17\xa12N\x91\x1b\xd0\x9acT\x14\xb9\x94W\xd6\xea\xb7\x81\x03\xe8\xdc\xce+\x10\xc4l\x9c\xc5\xb6Z\x84\xfa@\xab\x005\x15iST\xc4\xf5**\xc9|3#\xfe\xd6C\x00\xf52\x96ytNk\xbc:\x9d\xd6nA\xa2h\xc1\x8c\xfd\xee\xfb\x08F$\xa55\x15>hU7\xcc\x9d\xe4\xb9\xb2$S\xb5'\x7f:\x82=\xd4U\xec\x85\xcdmn\xe0\xd7AG\x1cv\xf2\xa4\xd3\x15q\xb1\xe3\xd7\xd3\xcc\xe1\xb2\xbf[\x86\xe2\xf2\xe8\xca\xad_\x8f1\xb7\xb9\xf5K\xe1\xa5q\xd1\x88\xe4\x17\xd6o\xed7\x12\xdd\"p\xc9\xc6\xb5\x81\x95\x011\xbf5\\\xf8\xf7\x9ejd\xb0W\\\x80T$\xbc\xd7&23\xcfg\xcf\xe3\xd9\x8aL\xe0\x9d\x1e\xb5\xe3\x8b*O75I\x167\x13\xc8\xf5uf)\x89K\xde\x8c\x9b\xd2\x85\xf33;\\\xf1;')\xa9 \xbb\x8a\x98t\xf1\xf7\xdd6\x91-\x94\x16\xcd 6\xa8x\xf4\x93TE\xf0 \xbc\xd5W\xba.\xe3\x82\xd7H\xf45\x96\xa4F2n0\xbfG\xdd\xf7\x04b\xfd[\xf2\xa9.\xe3Y\xfd\xb2\xcc\xd7\xd8\xc8F_M\xde\x06\xb9.\x87r\x19x\xce\xee\x920\x81\xec0\x88W$\x9e\xa3\xa1\x87}\xd3<\x9b\xcdHQO\xc0\x8b\x8b\"Mfh\x8f\xf3\xe0\xe7*\xcfBP\x9f\xdc\xc4\xeb\xd4\x1b\xde/\xc3\xf47\xcd\xe3\xf9)\xdaF\xef\x98\xe3\xaf\xdd:\xdf\x0c\x8a\"\xe8^\x84G\xf6\x80\x91\xce\xb6-_K\x02_\xc5\x0b\xf2c\x1e\xcf\x07=\xb4F\xe1-\xc7\x19#\x0fH\x97\xe1\x1dcF?\xe4\xe8\xa42\x81\x99\xbe\xaa\xb8\x1f\xf9\x8b\xfa\xc9%\xc9&\xb0\xe8\xd3\xa5\xa0k\xb9\xc3\xa7\x08G\xf0\xaa\xaf\x8a\xfc\xd9\xaa4\x17*V\xa2^\x0f\x10\xf5z\xa0cp\xd0\xeeD5J\xa9{\xe6FcMZ\x1enm\x0ds\xf0\xed\xf6\x9f>\xfa\x02C\x1a\xf5\xcd\xaf\xa0Z.\xad\xeb \xdb\x1a\xec\xc0\xb0\xd1\x0e\xe8\x8fI\x93\xc29\x17\n\\3\xba\xf6\x87\xc1\x14\x95h\x12\xa7Q!\x99\xb5\x94 ^1\xe8\xa7\x85lv\x1c\xadI\x1dS\xa4\xe6\x7f\xb24\\6\xe5\xe6f\x1b\xe5f\xdeUnn\xacZ\nf\xd0\xd4Isk\xfb\x08T\x0dl\xfb\x16\x1a!\xd8\xe813\x88i\x9b&\xc3$\xb5\x08;\x8fH\x88\xabL\xb1m\x89\x003\xf8Vhn],\xdag\x98\xee\x04\xb7\xc3\xf0X7[\xf0.\x80\x1d`B,8\x82Y\xcf\xfe\xa2[\xa8x\xcd\xf8\x1d\xfc\xc0\xdfca\xd89\xfb\xf4\xcbm\x08\xb3 \x88\x10\xd6n:\xd7i\"\xe5\xe8M\x08\xbf\xdc\x062c6\xe9\xf8\xa78\nb\x887I;\xc4\x97\xfd+\xe0_624\xe5\xb8\xed\xb8A\x0b.\xa4\xa3\x8b\x81\xa0W]\x13\x89\x94`\xfeqH2h#*\x8b\xbdT\xb9\xe0)(\xe6\x1d\x1d\\\xb5\x9bU;\x9b\x18'\xd1\x9a\x94K\xf2\x82\x90\x82\xae\x98E`\xba\xb5\xc5n\xe2\xad.\x98\xac\xdci|\x16\x04!\xcc\x18]\xa2\x84J\xd6\xe2\xba\x9b\xa9D\x96M\x08\x1eV\xf3\x02\xfaM\x9fG\x10\xc5Y\xd6i=\xc1XTc\x0eu\xeb\x19\xd9z%e\xf7\xdf\xc8\xd8T\xfd\xf5+\x1c\xd8\xf9\xd0\xadl\xd2\\\x90\x8e?&\x1b\x9b\xf0Qgei9+{\xd9\xd6q\x1d\xec^\x82\xe2\xbc\xec8\xa6O\xcf\xec\xea\x9d\xfe\x1d\xa2E\x1c\xe9wC\xa9q\xd2\xb1]+\xa3\xaa \xb3\x10\xaa\xa1})e\x90\xfey\xe2@\x84\xdd\xb4}\x9bi}\xa6,h\x19\xc9\xa5{\x1d\xcf\xca\xdcO\xed\xa4e\x94.E\xe0]\xe3\x87j\x0bR\x03\x0d$\xf2\x0e9\x1dv\xec\x18P\xb4\x04\xea\x8a\x88s/\x0bac\x10\xb3\xb4O%!\xd64d5\\\xfdoJ\xf6oB\xc9\x9a\xa4\xcd\xa3(\x99i/\xd0\xd1\xc6z\x1aa\xda\x08\xd2\xb1qC\xd9\x122d\x06NK<\xdd\xb4w\xf4:\x9f\x93T\xc0\x9d\xedjZ\xc7\x80\xeaN\xbbY\xe5\xed\xed\xbbx\x14\xe3>~\xaf\xc5\xff\x8f\xef5\xfd`\xcc.*\xd2T@\xdf\xf3l\x95\xa4\xf3\x92d\x13]\x8cq\x16e\xb0v3BM\x86l\x95\xe4\xe1&b\"\xca`\x0b$*\xca\xbc\xce\xff\xca\x9fgp\x8c\xbbe\xd3\xde-\x99R\xab\x89P\x8a\xc6\xc4W\xec\x99\xbf\xa7\x04\x8c\x08|\x12\x89\x99i\x94\xcb\xc6\xd3T\xb5\x84e_Ok\xc3\xa5V\xab\n\x1cAB\x913\x13\xa3\xd1\xba\x19t=\xf9~u\xc2\x19\x0fY\xfcm\xf8\xcbC\xdd\xcbJ\x98\xd7i-\xe8RA\x90\xb5\x0d\xcfTM\x91 \xf2\xae\x17i\x9d\xb4\xf6\xcc\xb0M\x86o-\xf3\x9cR\xc1\xdc7\x9a\xba\x81\x8d\xe8t\x1c\xc9I\x08S\xf3hd\\\xac\x11\x81\x89\\\xb8\xb9\xabnP\xf5\xb8$\x19\xc6\xc2\xda\xb1\xa5\x1bB\x1b\x13[\xfb\xa0\x08\xc5dJ\xd4t\x03v\xd5\x08p\xa3\xe3L\xee\x00;K\x17O\xcb38\x86\xc4\xa7\x7f\x0821a\x8fq\xbd\xe8\x83\xc1V\xb8\xe7u\xe2\xcb\x85f\xcdl\xd2t@\x91\xae_\x7f{\xc0\xa9;\x8e;G\x17\xc5\x97\xb1;\xa7g\x81\xd6\x19FL\xccE\xed$\xd9\x04\x19\x15\x92\x81$S\xd3,*\x7fS\x9ei\xef)\xe4\xf0}c\x87~\xef\x1e\xf8\x0c\x03\xf2\xb3\x10|D\xb8\x86lN\xcb\xb3\xe0)\xe4\xbb\xbb\x01\x0b\x911--\xd7\xfbb\x1a\x18\xe0E\xa1\xd7_eu\xd8\x8e\x18\xb3F\x0e\xdb\xaeu\x03A\x945\x82cfi4Q\x9f\x1e\x888\xc9Hu\xd0\xafE\x11\x1cu6\x0dN\xfb\x12Ui\x8dA\xa8\x05\x0f@\xdd\xc9#6\xa4\x98j9\xcd\xd0\xa8\x9eE\x8e-Y\xfe\x85\x1c\xad\xd4\xd0\xe8?\x04\xfalxg*\xc4w\xf4V4\xfa\xb7\x9b\x99\xf7\xd9X\x06o\xf8\xd6\xe5p\xc0\xf1\xf9\xdf\x8b5T\x7f\xfd\n\xdc\x84\x10\xc3\x1e\x0e\x89aZnB\xf0!\xfbZ\x8b{\xc1\x88\xeck\xe5;\xc9\x89<2q\"\x99\xff\xed\x00\xf6\x0cr\"W<\x03Y\x87\x99\x94\xa2\x1bKs\xab\xf2*\x03\x9b\x1a\xb7%f\x0b\x9e\x85\xb0\x08\xa1\x08a\x1e\xc2\nMF\xd7h\xbdv\x03G\x10\x97Kt5T2m\x1d\xa0uYc@!\xabL\x0f\xe8!\xda\xfaI\xf9v\xfdn\x97Z\x141\xf6\xeb\xd29\xf2\x14\x9e.O\x9f\x06P]'L>\x14\xd9, \x86\xce\xb1\xd11LW\xe8\x90\xd5S(\xce\xe1\x08nx\\\x99\x93\xacNJ\xf2\xa1$\x84\xa5\x18\xbe\x11\x86\xf5,\xb50\xad\xf6\x8f\x0d\xa9\xeaWYM\xca\x19)\xea\xbcd\xc9\x86\xe9\x9b\xaa\xc8\xb3\x8a\xb4^\x15\xf8\xaa\xad\xe7b\xd9Jo4\xb22\xcbGl'\xd2\x80\xa10\xea\xd5\x8b\xa4\x9a\x95\xc9:\xc9X~\xbe\xcc\x8d{\x92\xa6~\x06+\x90n\xe9O\xd9x\x83\xdf-\x1a\x98L`\xe1\xf6m\x1bh\x13(\xdc>\xebCu\x02s\xeb\x97\xb7!\xda\xce3\xf6[\xa6\xbe9\xbd\x8e\x97KR\x06\x0e!\xf3\xa0 {h\xadKe\xb15\x86\xf2d\x8aY\"\xb2\xac~\x1bv%\x8cN\xea\x0d*\x8c\xael\x863\xa2\xb0\xe1\xac\xdd\xc0\xd6\xcf\x80\xe1\x1a\xad\xab\xbaL\n\x11\x85\x14\xedl\x06\xadcD\xb1^\x12\xe1&\xfe\xd6y\x13/\x99\xe3/\xc9\xea\x10vJJ\xc2\xda\n|\xe6\xdb\x99\xa9\xcc\xe7\x12\xc1\xcfW]\x91\xf8\x97|Y2\xf4\xd6C\x16\x9f\xaeQ|Qn\x8a\xda\xf7X\x87^\x08K\x97\x19X2\xad\x8e\xc9\xac*\xb5\x18\x96L\xaaF\xc6\x960VI\xebb\xd8\x9f\x8a\xb8\xa5\x93j\x8b\x81\xc3F\x0e\x0d\x93\xb0p\xb9X\x9e\x14V\x9d\x99\x1f\x8ce\xaa\xfe\xbdX#\xfd`\xf2A&@s2\xef\x19O\xe6\xbd\xf6\xc9\xbcg:\x99{kjSE1\x0b\xe97\xf1z\xc0+\x809d\xaf1\n\xbb\xb9\x16\xc6\xe2\x8d(Yf\xe1\xb2\x0c\xb9\x9a\x9dG\x08|\x94\x89\x1eV\xfbFX\xed\xb7a\xb5?\xc4\xc5\x80\x8a\xdb\xe4\x13\x99mj\x16rZa\xcf\x86\x891#\xc2\x04I\x8ay\xc7\x86]\x1aDB\xf0\xfa\xe7\xae\x87O{G*}\xbc\xa9H\xf9\x92\xd4\xb3\x95g\x8d\xc1&V\xd4\xca0\xb0%\x9d@9\\M\x0d\xcaeI)\xac,\xffP\xa8\xb4\xdb\x10\x12\x831\xb7\xf5\xd6\xde\xac\x1f6\xed\xb6\x9a\x1d\x1d\x94\xe6k\xbb\xe4*\xd9\x0b\xfd\xdbF\xcd\xc1\x03\n\x1c\x03\x95\xd4\x0d\xa0\xcd\xb1-\xbe\xcc\x1f\xe2\xa5\xbeV\xd2n3\x87c\xf0\xf87\x1e\x18\xcd\xa4c\x96\xec\xe7\xe0m\x03\xe4\xe7\xf9\xba\x88\xeb\xe4\"I\x93\xfa\xe6u>7\xec\xe2\x8d\xc1\xdb\x96\x96\x05\xbe3\x92\x12\xc6\xaf\x90x\xb6\x92\xdd\x06\xf4\xa8\xb0s\xfa\x8d\xb6\xdbNb\x18\xd8l$&\xc5Z\x12\xc7\xf4[\xdaO\xa3:^Vp\x0c3\xfeg\x00\x13\x98&gc\xcd\xc0[\xce\xb4G\xaa3\xad]\xbb\x8a1\x1cX`\x1c\xfc\x8f\xddF\x0c~\x06\\\x97\xcd\x00\x9e\x17\xaf\xe6\x81\x9f\xe2\xfd_n\xdb\xf0\xa2\x0c\xa3\xc6\x04bk+:W\xedn)PDv\x1b\x11\xe7\x98\xed\x8d\xc2\x18\xba%\x8a\xa0_\x86\xfd\xd2-\x12q\x9c\xfd\xd9Z\xe4\xccL\xdeE\xb1\xf9wQ\x8c\xdaLgg\x01\xd0\x7fwwCH\xa6\x9e\x07\xbb0\x83]|D\xf1\xa5\x18n\x83\xa9\xa9\x9b\xb0D\xf4\xecK\xb0M\xfb\x8aP\xcc\xa4\xa2)\xed\x8a\xa2\xa4C\x04a\xacz\x04s\x16\x8a|\xfcp\x81wK\xe5^:L{m\xeeyA+\xb7:\x9c\xd3\xde\xcc\x89\x9bAQ\xe2\xb31\x17\xc6\xba\x06\x06Z\x7f\xa9\xd66;\xfb\xcaj\xb0\x10\xea\xa8\"\xe9\xc2\xe0'\xac\xde\xb2\x1d\xf6-\x10\xd6\xf1%9aL\x0c\x1cQ\xb2\xc1\x1e=+\x92\xeaC\xbc\x94\xb4\xa1\x92\x7f5\x95\x9d\xf4Vw\xc0\xb2\xea\xf7\x1dj\xce\xd4\xe1\x1b\x9d\xf63^\xb3hMh\x80\x1a\xd9h\xe2v\x07*t8?s\xad\xd9\x85Ic`\xa2\xb5\xa5\xe1@\x96w29$\x99\xe9>KVJh\xa5r\x9a\x9f\x0d*\x9c$\x81\xab\xb47\xf4\xc0x\xb5l\x9a\x9f\x05\xd8Xs\xf8V,,\x8d\xb9i\xceMO\xf0\xebi\xa2W\xf2\x9b\xf9\x0e}\xc3q\x91T\xba`\x81=\x1b\x0d=\xe6\xffK\"\xfaV \xf8\x8f\xd9\x03nK\xd9\x9e*=K\xfa\x84Q(\xf6\xbf\xd5\x9a T\\u\xdf\x7f\x93\xda\xb0\x02\x9a%\xd1\xbalj\xd6z6\xc6}\xa5g\x89\xca\xb4\x12:\xd7CMW\x0b\x16.\x8d\x1d\x1a\xfa~\xba\xf03:\x17*\x88\xa9\x13\xdf\x9a\xa5\x19w\x07\xf6\xe4` \xce\xf1\x7f\x86\xa6\xe7\x0b\x85O\x85\xd14\x1f\n>\x89*2\xdb\x94I\x9d\x90*\x04\"\xee*0JPV\x7f\xb8)\x08{\xca\x14\x08\xcac\xc3I\xc3\xa4\xaej\xb6\"&\xd9\x8c\x89\x9c\x9a;\x11m\xed\x8a\xd7\xee\xdf\x93h\xab\xcf\x98\xdc\xcd\"\x19\xfcT\x1ax\xf2\x05\xd6\x92\xea\x0f}\xa5\x82\x81\x87\x0f\xf4\x87|~\x13\xa2\xb6\xb8\xbc\"\xa5a\xf2s\xaeP\xa6U\xfe\x1a\x97I|\x91\x12\x83S\xed\n\xab\xae\xea\xdapE\xb1\xe4R\xaeP\x93\xe8k\xdd\xb4k\xfd\xb0I\xd2\xb9\xb1\xb2\x08\xe2\xf5)J\xaa\xb7\xcfN\x0f\x03\xbf\xd6\x1c\x147\xe8\xaeO\x1b~\x0b\xc7p.\xef!\x95\x88\xe8\x86 \x83\xef\x8c\xc4bS\xa6\x13cd\xa3YI\xe6$\xab\x938\xad&\x80Z\xf6Ut\x9d\xd4\xab\xe7\xcds8\x06/\xc9f\xe9fN0\x0ca\x15\xaf\xc9}\x16C\xcc\xd0h\xe3\x08l85gy~\x89q\xdeuF\x84\xfd\xf9\xc5\xa8\xfd\x7f\xa7A[z\xb4\x07!T\xb2B\x0fS\xe1\x08*\xca\xf4\xf3\x1a\x12\xed(=7\x80\xf2\x83\\\xaa%\xa9%\x91}\x1f_\x07CQew>\xa8\x91U\x9f\xfb^\xc3\xa4P\x89'\xc3\xd0\xb1Y^\xc3\"\xdfds\x9d\xab\x10\xed\xfb5F\x9e\x94\xd4C\x0f\xbeWmm\xd3k8\x86_na\x02\xaf\xf5\xd5\x7f\xc66\x87t1o\xb0\x86\x10\xd7\xf5\xf3{\x17m\xca\x14v\x8f\x8c\xa6\xa1\x83\xaa\x01F\x93\xcc\x01\x03$\xcd0\xdeT\xb2\x8dm\xbcU\xec\xec{c\x18\x9dF'\xf1\xc6pdr\x1d\xc4\xcf}\xcc\x0cB\xd8\xc9\xa4\xa5\x8d\x88(\x10ql\x0e\xe1]\x1fr\x12joBx\xc7\xd7\x80\xa2\x17J\xc1?\x07Q\x9d\xffT\x14\xa4|\x1eW\xc4\xc7\xa08G\xb0d\xca%=~\xbc\x97*\xfej\xfa\xe6\xccT\xb3\xe4\xd8\xce7b\x14\xa3\xbb=e\xa7\x0ch\xf7\x02\x8e\xe0\x99\xe2\xa9u\xea\xbfR\xc8_\x104\xcf\xdf\xb7\x9ek\x9a{1B+'4\x8a7S\x12%\xd9\x80-ai\x89\xb3\x85\xaa\xbd\x8b|~\xe3\xc9\x18\xb2\x8ca@\xbc\x8b\xd5\xbf\xa3\xc6h_Z\xb4-;\x11\xb5\xd0:\x8a}\x94\xc5k\xfck9e\x7f\x9fQn\xce\xf0>\xc1M\x1e\xb10\xadX\x19&p\xe9\xb3\xbfCx\x11tn;D\xc2\x96\xeb\xb8\xcc|\xef\x9d\x80+\x8f\xd4\xcf\x9a\xc6p\xfdI\x05\xf1\xfa\"Yn\xf2M%\x83\xdb\xd7+\x02<\n3\xee=X\xc5\x15\xac\xf3\x92\xbe\x893\xc83\xd2(\xfa1;\x00~\x91!\xee\xf7z\x88\xb39\xbe.\xe2\xaa\"\xf3\xfbI\xa6|\x8b\xba\x8d\n\xe6 \x8b#\xc6\xfa\x848\x83?$\xd9\x1f\xd8\xdb\xc8\x0bB\x11\\\xebh8\xf6bG\xd5%u\xeb\x8a8\x86\x91\xb9\x1bsCy\xf2\x85\xbd\n\x8cCHJ2\xa7\xbfvH\x84\xb7\xe2'\xeb\xa2\xbe\xf9+3\xf9nH2\xf7\xe2|/>h&\xd8\x06\x06\x856\x9dgQ\xe6W\xc9\x9chI\xb5:\x99\xb7]L\xf3\x98;\xa8@E\x8ev\xf5M\x81\x88\xa2\xd1@\x976\xaf\x0d\xe0[@I\xa3:\x90.\xdf\xcdK\x03d\xa02\x058M\xb48\xec\x85;\xb6vqA\x84\x97\x8c+\x1c\x91!\x041\x18\x15s\x80l\xf2\xbd{\x90Y\xb4\xce%\xf9\x871\x0e\x8d(rl\xd6@h\"3\xc1p-E\xa9\xfcj\xb8\xa6\xcdz\xc4\xd9\x9c\\\xa7f\xa6\xa4\xf1\xc7\xbe\xa9\xc3/\xcc*@\x0f6u\xe8N\x9d\xa0\x9d\xf1;\xcem\xd2\x9e\xae\x9b\x9e~\x0c\xe1]\xc0\x83\xef\x9ct\x1e\x07\xe2\xcc\xc3M\xda\xb6\x80\x97\xe7a`\xf1\xbd\xa43\xfc\xa9\x9f\x8aM\xf9~l\x98/q\x9c\xc8&\x8c\xde\x18\xa0J\x96\xbb\xe0cP\xfb{\xc8\xdeb\x18\xec&goE\xca\x04M\x8b\x06l\xceoC\xfa\x99\xbe\xa7\xe6\x10~\x8ec\x82#\xf8\xa9\xbf6\xfd\x13\x9c\x0d\xee\x9d\n\xe8>\xc3\xc1\x02#\xa17\xf6\xab\xec\x7foHy\xf3\xb6|\x99\x97\xeb\xc0\x7f\x17\x84\xf0\xeew\xed>Z?m\xf7\xac\xcama#\xb20\xb9\x97\x9e\x80ng\xbbMV\x06)/\xdbo\x14K\xa7\x1b\xc5\\\x11\x02\xcd\xb5\x12'A\x15\xa4\xbc\xec$TB+\x99!\x12\xffXp\xe6\x03\x86{\x15\xdf\x02J\x92\xb6:\x84\xa9\x87<\x9e\x87\xf7\x85~\xc9\x82\xd3Rv\xf1\xc7\xfc\xbaa\x17=6\xb0\xca;\x0bD\x9c\xb7\x81f\x1cj75\xcc\x03N1n\xbb\xf9\xfd\x8c\xc7\xd94sj9\xc5fDi\x97,\xae\x14\x91\n*\xc6\x8dL\x85*\xcd@6\xa59*\xdb\xd0\x0d_!c\xe9\xe5\x01\xfc \xee#\xcf\xe6\xa7\xec&\x86\xce\xb2\x9a\xaaUL>\x93;io\xba\xb2\xa1j\xbawF\xc7'\xda\xdb;\x0b(1\x14\x8dz\xbfxM\xcfn3o9zL\xcf\x98\x87\xc7\x83_\xfc\xe9\xdfo\xcfv\x83\xdb\x07K\xd5\xcf\xe3)\x0bs\x81\x862> \x9e\x06T\xb6\xd8T+\xbf\x9c\xee\x9f\xd9}6\x0d*`?\xdd\xe6f~\x16]\x89\xfd\x85\xbcq\xf3sJ\xac\x97\xa1b\xc2\xed\xaf\x86\x8fo\xe0\xc4g\xc3\xef\xf3\xa5\x0d\x9b\xfd\xb3\xb2\x13\xc9\xfd\x17\x99\x1c\xe6\xd6\x0b\xc1[\xda\x02\x81\xd0\xa5O\xa5\x97j9\xe8\xccd\xba\xdb\xd4\xf7\xd0\xb5\xc6\xb2m\xac;\xb9\x1c\xb1\x85\xcd\xae\xef\xc2\xe2\xcb\xd6 ]\xca\x95<\xb6\x19\x93l\x8b\xdfPj\xbe\xa9-\xdf\xd0\x13\xe6\x9d\xcf\x1dLgy\x8a\xb4\xf4\x9d_\xb6\x1f\xd8F\x9b\xe0\xbe[\xe5\x15z\x1e\x96\xf8\xd7\xf0\x17\xcc\x85\x8e\x92s\x14T\x1c\xfap\xc9\xac\xcb\xf1E\x84O\xf3\xe97H\x9e\x138\x86\x9cb\xf4\xe4\x01\xe6\xd4\xf0\x13\xd8\x85\x18\x9d\xf0\x82\xe9F\xf5\x00\x84c\xd8\xb4\\\x99`b\xc8\xbaz\xeb\xa7!hr\xb2\xdf\xfa\xe8\x9bk\xa7\x15\xe3x\x8a!=8H\x8e\xc2\x85\x0b\xc8\xdb\xc7z)R\xb2XX\x8c.j\xe5\x03\xa8E\x97\xb7}oT\xf3 T\x98\xf4K\xfc`;\x0e\xfd\xad\x8cma\xf4/\x8a!1\xc3\xcd\xa4\x83\x9b\xab\xba.\x06p\x87\x19\xf4\n\xdcL\xe4_C\xf8\x96\xe27\"\xb0\xbb\xad\xf6\xcc\x82\x99]\xac\x9caz\x17>\xc9\xae\x99+\x96\xf6\x89\xf0\x1b\x17&\xc6\xf2\xbfy\xf80E\xdd\xc4n\x98e\x8di&i\xa2\xe6nU\x03\x82\x7flH\xf9\x95V\xc86{ &\xb3\x8e\xbd\x8ep|\x08\x03\xf6\x17\x87\xc0\xce>w{\xbbw\x0f\xbc\x8b'?\xbd\x7f\xf5<_\x17yF\xb2\xda\xcf4\xbe\xa7:\xcb\xea\xbc\\\xbf\x88\xeb\xf8_\x12\x00~\xc64\xc1=\x0b\x16F\xa5\xe8\xd8\x11<\xf8\x87D\x13\xfa\xcbiC\x89-a\x1ee\xa7\xe3I\x7f,\xe6o]\xb6\xab\x1ei\x1d\xfc\x05\xfe\x93\x03\x0d\xa8\xbf\xee\x9c\xc5\xe8\xcb\xf9\xf9\x90\x12P\xc4`\xd2\x8a\xc8B-\xf9\xed\xe3q\x81r\xff\x05\x08\x8e\xb9bC\xa9\xcdu\x10*QU\xdf\xa4\x03\x95P/K\xd14\x1d\xf6\xae\xe9\xabr\x86%\x18\x8c_g\x1b!8moZp\x16\x13HP?_%\xeb\x82\"\xd4\xe0\x17|J\x13\xd8\xd0ol\x990X6\xa0 \xec\xec\x1b\xab\x99$\xcb!\xfa\x9f\x0b\xd2\xaf\x0bL\xf2\x1f\xc9\x98\x99\x19\xb06K5\xcc\x88l\xfa\x91\x0e\xbcM\xc6mF=n\xdb\xa5\x04+\xd2\x99\xb6\x8b\xe2\xcd )\xde*\x86\x8d|Op\xc3\xb1\\me\xa4\xb4\x0f\nq\xca\xacY!\xdb\\$\xc5\x8c\xa9\xbc}?\xf3\x86\x0fAQ\xf8n\x19\xb5\x15E\xc1-\xe9\x98r\x95\xf7\xe3\xe8\xce\xcew\xa7\ni\xb7\x0f\xc5\xb6\xe3\x07\xf6{\x82f\xb4\xf0\xd0IP\xcd\xc6\x1dJ\xee;e\xf4\xa1\xd0\xdf\x1e\xad'\xb7}U\x0b]\xdf\xa9\xc7S(K\xe6\x8c\x12\x9e\x9a\xbf\xec\x9ad\x11\x14\xbb\xa6g\xae\xdd\x81\xeat!\xc1\xb0\xff\xa8\xe3\xe5\xac\xdf`[t\xe2\xfd\x0f\x14\xfcM\xed\xfd\x9c'\x99\xefi\x9c\x13\x95w\xd0E\xd8_]#\x9b\x0cid\xe3F#\xdb\xd5\xb9\xb2[\x90\x17I\x85\\!\x99S\xfc\x88g5;\x01\xf3P\x1f\xc3\xdeb\xb8i8_\xb5VF\xf5X/\xb0Krcc\x04\x9cTl\x16M,3\xfd\xb42D\xcc\xafk\x88\x1e\x00W\xeb\xda\xe7(\n\x87\x13\xe6\xd6\xb2Ku\xe2(\x1c\x8e\xe1h8\x8f\xa0\x7f\xe6\x88\xc2\xa2\\2\xa6\x92\xb15M\xb6\xdc\xf1{lc\xca;/7Qhrv\xc1\x81\xa4\xf1\x05I\xbb\xe3`.\xf2_e4\xd1\xe0h\xd6q]&\x9f\xbe2X\xc6&r\xe1M\xb2,2 \x1c\xd3\x83\x84\xb9\xfbQ\x06\xef)\x05U\xcdX=\x0c#2a\xaa\xce\x10\x7f\xe9\xc70\xe0\x8e\x8a``\x8a\xb4#\x9b\xa7\xbe\x90`\x13\xee\x1c\xdb\x8ccB\xfb73\x9e[\xc0\x15\x1c`\x0b\xcaBkn\x02\xc0(\xed\xb3-Q\xc43\xf2\x82\xa4\xc9:\xa9)\x93\xee4\xfd\x94O_\x99\xf8o;o\x0f\x83\x15\x18RX\x0d\xcc\xbeH\x8a\xd1\x93\x9f\xfd\xcbM\xfe3\xc6\x0eu\x9dh\xde\x0d H\xeb\xa1AE\xc7\x1d\x92\xbe}\xc2\x1c\x92\x1e\xe9\x1d\x92\x985\xf9#]~\xff\xd4i%\x05\xec&\x0f\x8e\x7f?=\xfb\xffv\xbe\xb9\xf7\x07?\xf8\xe3n\xf8\xf4\xc8\x93\xf7\x19\xdcp\xb6?\x15\x8d&~L\xa7\x0f\xfe>\x8d\xef\xffs\xef\xfe\x93\x8f\xf7\xa3\xf3\xff:\xdb\xfd\xe6A\x12\xd5\xa4\xaau,\xd7\xb6~\x01O\x0e\xf7\xb7\xb7\xd1?\xd8\xfe\xd3\xc3/0\xefo\xbd\xfa\xb7\xd4\x8a\xca\x00\xa9f\x95\xa6\xdd5\xb5\xec[ a\xcc\x9a\xc1\x84(\x96\x08\x95\x9a|(\xd8\xe6`\"\x14\xb3\xdb\xef\xa2\xef=\x8bw\xa3\x86\xcbbtR\x8c\x84\xc2\x9d\x18\xdc{\xe7\xed1\x16b\x8c\x06\xdfeLx \x80\x89F[q\xeb\xd7\xd4\x10n\xe4\n\xb3-\xdc\xbb\x07;;\x1d\xfd\xea\\D\xc8\xd2\x7f\xb8\xee\xc7\xc6\x8aC\x98z3a\xf6\xac:\xfd\xde\x9c\xb2\xf0\x00<\xb6\xcfP*)\xe5\xa6l\xd1\xbd\\]H\xe3\xb4E\xdb8\xad3\xf42P\x14\xd8W\xf4\x1f\x16\xd3\xa6s}\xd5\xc0\x0bG\xd5\xfc\x94a\x7f\x8e\xc1_il4\x06X\x13\x19\xe0&\x83$\x1bN\xde\"8\x98\xf9t(\xb6$p\xa4^O\xb3\x01{\x0f\xb4\x07\xb0\x9d\xd3R\xa1\xcb\xf3\xd6\x7f\xfel\xbb\x10\x03\x8e\xfd9zN\x0c\x9b\x9b\xb0!X\x9bCy?.\x92\xffEx4\xcc8\x00\x0f\x17\x93\xdf3\xf2\xe0\x98\xfeB8\x19\xc8\xeb\xf0$\x08\xc1c(\xd1\xab+.\xcf;\xb5\xd9\x9dp\xaf\xb6\x08\xc0\xa6\xd6\x1e\x9e\x1d\xa8>\x18\xcc/^\x8c\xde\xce\xf2\x80\x8c\x01\x1aW\xc9L\x8c\x86\x85\xccp\xfd\x1e\x14\xae \xc1@\xc1\xf6[\xcfnAuYT\xc4Uu\x9d\x97\x03a\xcatE\xc8\xb3\x8a\x7f,\x0buA\xd9\xa3\xca\x01z\xa2\xc8\xb5\x8a\x9e\xa9w\x8ep\x04\xde\x0f\x14\xfcN\xf1\xbf\xbc\xe5\x81*-R\xae>R\xa1\xe0r\xf9\xb9\x87a\xdf\xe9\x06\x8eVq\xf5\xf6:\x13'`{x\xb9-_\xb2d\xb3 \xcf)Bi\xfa\xdeS\xa8\xe1{8\xf8\xf6\xd1S\xd8\xdd\xad\x03 ,\xda&\xf3\xca\xa1t\xff{\xd8\x7fD\xb9\xb1=\xc5\xf2\xb1\xe5\x17\xd4q\x0c2\xab\xef:>:\xbeR\xb3\x8ebJ:?\xe4l\xca\xb6\xb3V\x91\x18\x8e\x00s\xce\xd5Q\x91\xc6I\xc6>\xa7\x9c\x1a\x87\xdd\xac$qM\xfcl\x93b|y\xca\x0b\x96l\xda%|/\x1d\xb8\xe8\xdc\xcb@UV\x91iy\x86\xf8\x98\xd1?\xd8\xef\xee\x92sS\xe9f\xcd1)6)\x97\xa43\xfe,\xec;\x92\xa2\xba\xb6IC\xd9\xe1\xc3\xd9\x0d\x99T\x7f \x9d\x9b\xd6\x03\x81\xd6\xed\xc6\x0e\x96\xeb\xa8\xb3\xa5E*gVDk\xfa%r\x9cS:\x1d\x83\xe8\xe5\xe7\xedE\xf8\xfc\x99\x8a(i\x9a_\xbf\x13\x18\x8c\x0fw\xcah\x16\xa7\xa9\xdfEo\xba7\x18\x11 S\x0cv\xbb\xb37b\xc3\x0fy\x809LK&\xcd\xecBLp\x87D\xbb\xfa\xbd\xa0\xcd}\xef\xdf\x8c\xcd)A'\xd0\x16\x9aS\xdc@m\xa7\xae\x95^#\xc7\xe0g}\xc1:\x0b!\xd1*\xc0\x18\x8c \xbe>\x062M\x10\x9f\x15\xad\xb6\x84\x02}\xc5k\xfc\xff\xec\xbdk\x97\x1c\xc7\x95 \xf6]\xbf\"P3KU\x0d\n\x8d\xee\x06@\x11MAt\xa3\xbb\x014\xd4\xe8n\xf6\x03 \x00a\xa0\xac\xcc\xa8\xaaDge&\xf2Q\xdd\x8d\x11\xe6\x90#\x8a\xc2\x83;\xb3\xde\x91\xa8\x91=cy\xd6$H\x00\xb3^\xdb\xeb\xb5\xd7\xf6\x8e\xf7\x1c>\xd6>Gs\xa8\x99\xbf\x80?\xb0\xfe >\x117\"2\xf3\xde\xc8\xac\x02 R\x9c\x1d\xd59\x12\x1by\xe3\x1d7\xee+\xee\xbdqFcp[\xfcSc\xeeB\x81M\xe2o(X%\xf9B\x8e\x97\xbe\x9cjS\xf7\xf8a\xda\x0e\xada4\xd6\xe1j\xd2\x1b^\xf7\xebc6ms\xc2#v\xf4\x88\x01\xe8t1bT\xde.\x01\xbe\x90\xa6\xfe \x9cDs\xd4\x18\xca\xf3\xcb\xa6\x0f\x13\xd2H\n\x88\x9d]\x0foX\x06\xc6\xd1\xc0<.$\x95F'A\xfb\x8b\x93\xaa7\xa8_\xc9\xb1X\xce.|Tf\x17f-\x946\xc0<e\xbe\x9e\x9e5_O\x7f\xc7|\x9d\x9b\x9f\x97q\xc5G\xf5\xc0\xe4\xa0\xd8\x82\x80\xb2\xb9\xf9W40\x12\xd8\x0e_\xe7gO\x96>\xcf\x9d\x9eg\xb2\xd9\xef\xb1\x97o\xb0\xa3\xe2\xcb\xfc+\xecG\xec\xe5\x13\xec%f\xea\x9c:5\x7f\xfae\xd3\xff\xa9\xef\x9c8y\xb2hb~\xfe\xa4nbn\xbe\xdc\x06\xb4\xca^b/\x9f\xb07\xddND\x0bs]\xb9\xb0/\x9f:u\xe2e)S\xcc\xcd\xce\xcb\"\x1d\xf6\xdd\xef\xb2\xb9Y\xf6#\xa6\xbe\xa0\xb5\x97; C89k\x86\xf0\n\x19\xc2\xdc<\x19C\xf3\xd0:\x0d\xac\xc2\xce\xd5\xddh\x14;ns\x14n\xf5\xcd6\x8aaQ\xefV\xdd\xc5Cd\xbdr\xa0\xe2g\x9cD\xf1\x02kE\xd5\x0c{\x96fI\xeef\x91zH\xbb\xf4\xa1\xe8\xab\x16\"4\x85b|\xdfb_VaU3/\x16C \x1bTS=\xfe\xcf\xe6g\x8f\x0f\x8a\x16\xca\xf7\xc4\xd5\xc50\x97\xb2\xad\xadsK'N\xbf\xf22J\x1f\xd3\x97i\x89\xe1m \x8a\xbd[\xe7\x96\xe6\xbes\xe2\x95ib\x8c\x88\x90\x19uY\xeb\xa8-\xf3\x04\xa5\x13jh\xcf\xd1\xcd\xc4+\xe6j'f\x1e-\xf5W\x8b\xc0a\x00f\x95\x9eo_\xf5\x0e\x02E(6P\xbe\xbdF\xb7/l\x9f\x9e\xc3a4\xbe\xfa>\x8f\xbe\x9b0W\xb5\xbd\x93n\xfdY\xe9\x04H\xef\xc8P\xbf{\x02O\xb9H\xc7\xac6/;\x9b,;\x99<\x13\x19\xf9\xf8\x1a\xe33\x03\x9e\xed\xf8#\xde\xee@\xf5\xd2\xbf\x17T\xbc\xfe\x11x\x19\xcf\xa2!Vt\xa6\xe2\xbb\xcc\xf62\x03\xe7@\xca\x9f0\xb0\x05\xf9\x97\xfcc\x9aY2\xb5\xf0A\x97\xb9\xf5t;oC\n\x97\\\x12h\xb52G,~f\xba\x02/\xf6\x0fhp\xf1\xef\xa9\xea\xfb\xd2\x80\xa0\x0b\x1e\xf1\x85\"\xa03\xe3\xe8\xd3\xd1\x01\xf3\x91\xfag\xd6\xe92\xc7\xcc\xb4\x81\x07\xa5\xb2\xe9z&#\xad\"\xe94\x13ef\xb2\xca\xbc\x083E\xbaDSm\xc9\xd0\x02`bA\xc5\x18\x14\x1c=\xda|\xe7);\xbe\x1e\xdcP,.\xb81U\x87\xba\xc8\xb4\xe9\xfeX\xad~\xa7\x7fc\xf5\xe8W4\xf1\x8d\xd4X\x96\xcaj\\\xf6\xb4\xc67M\xd2\x8c\xba\xe4s\xb5{\xde/v\x88\xc5\xd3n\x90\xdc\x9c\xfeL\x1a%Y\xbb\xd3e\xb1\xf9K\x06\xea\x95\x9e\x88\x14{\xf7=\xd8\xc3c\xc7\xeawM\x0e\x04v\x8c\xc5\xd3l\x98\xc1\x8e/\xd8\x99\x8c\xed\xbb\x1e\xdc\xe8\xb2#N\x9b_wotY&\xff?\x9c\x8c\xdbZx\xd14\xa8\x90yi\xfa\xfd\xbb\xc5\xb1\xab\xc0\xee\x96\x1c\xa6\x8c\x7fR\xde,kHu\x9c\x15Y\x17\xcfT\x1e\xce\xbaki0\xadm\xf0H\x1bH\xab\x95\xa8\x8a\xef:\xffV\xe9\xbbA\x0e\xe9\xcc\xa9;\xa9(\xfb3n\x14\xcb\xb7\xf8j\xc0\x92_I\xf1\xa8\xa0\x0c\xea!d[\x8f\xd7go<\xaf\x04\xa49%=(\xc0\x0e\xe8u\xb3\x8d}\x9e8=ka\x9f\x13/\x98\xd5\xe2Fj`H\xad\xbbK\x19o\xd8\x9e?1[1\xb4_L\xa3pS\x1cw\xfd\xa0\x9b3S\xfc\x13\xacN<^\n\xa2P>*=s\xd3\xfc\xb3*\xee\xe5\xd6%p#\xfe[G\xc8s\xa9+\xd4\x11\xa2\\&O\xa9;\xdc\xf9\x8c\xf8o\xf5@\xd9\x14\xaa\xc0*\xa9Kw\x03\xd0K\xean5\xb5\xd5\x9e.\xa7d\x02\xa2w\x0b\x17P\xd4\x1f\x8f\xab\xfcO\xc3i\xe4Mt\x97\x85\xb0q\xa6\x8cM\x8bs\x95\x93JR\xe3\xa7R ~\xd3\xd2\xcf\x91\xb9\"\xbc\xeb\x8cN|.\x1f\x98?2\xdb\xe9\xaa\x82V--a\xaf\xb1Dp\xc2\xd9.\xe3\xf2\xeeDH[l\x81\xc5\xf2\xa3\xcc\xb8\xdcR\x179\x00\xa2\xab4V\x99\x0d\xed\xe8XAE\x8b\xa5\x95\"=x\xb0{\x9e\xee7\x8a\xcd\xce\xb93\xa5\xe6\xe4\x1d\x8a:\n\x16\x9b\x9dlF\x9d\xc7\xe7jJ\x8bl\xe2T\xd6\xb7,\xa5C\xd3\xacT\xa3\x05\x8eO\xd1\x93D\xd4\x10D\x94.\xc3\x0d\x89\xad\xaa\x0c\xa1S?\x06ql\xca\x1d\xdaw@\x9a@\xe4\x11cg\x04\xf75\x88\xd81Od\x01\xb8\xc3\xb2a\x12\xed\x8b-#\xcai\xbb\xb5#\x1a0\xce\xc1\xac\xef\xf8\x01\xf7Z]\xd6\xdaY\xd9\xde\xb9\xb9\xb1\xb9\xb2\xb5\xb8\xb3\xba\xb1~\xf3\xdc\xe2\xea\xda\xcarK\xa2T\xd8e|\x82\x18\x86\x16G\xac8E\x92\xba\xcd\xad\xae]i\xc5\xab[\x88\xb7:\x0f\xecf^\xd9\xaa<\xef\xb4\xcd\xb0\x90\x18j\xeb&\xcd+h\x1e\x81g?\x8c\xe2\x1f\xca\x8bL\x9ed\x87\xccOY\x18eL\xa8\xf9Q\xbfX\xe2\x94\xa9\xa8J\xe6\x87l\xeb\xdc\xd2\xb1\x97O\xcf\xce\x8b\x05/\xd6zc\xf3\xe6\xea\xfa\xe5\xc5\xb5\xd5\xe6\xf5\xd6\xcbR%V\x95\x7fE\xca\x92\x8fT)\x8eU)m\xe6l\x03=`\x90WW2\xd0\xac\xdd:\xde\xb2\xd8>a\x17\xc8\xe7!;\xc3,\x8f\x16\x8cKv>\x0b\xb31!b\x146h\x80\x1d\xd6\x84\xe3J\xd3\xe2\xa1|\x1a\xae\x8e:\nb\xf8\xaa\xf5\xcaWl\xf9@\xda\x16\x877\x14\x95-\x11a\x08\xde.\xc7\xb3]\x1f\xdc`\xaf\xc9)\xf4\xc18\xd6\x9e\xed\xb2\xa1N\xc5z\\f\xe7\x1b\x8a\xee\xc7\xec\x18\xe4\xe2o\x8f\x98\xa1\xbc\x95\x00^\xd9\xf8aA\xb8G\x82R\x0f\x8f\x1e\xc5\xf7\xc8^\xad\x89_\xe2\xfa1@\xf4AG.\x9e\xa7\xad\xee\xd6\n\x0d\xae\x8aL\xe3\xbf\xb4\xf6\x95\xa5\xd2A\xa7\xf9H\xac\x1c\xc4\xdc\xcd\xb8\xc7\x9c\x90\xe5a\xea\x0f\x04\xba\xf7\x9c\x94\x1f\x9b\x9be\xea9d\xa6\x08\xf3\xc8\xd9\xf3\xc3\x01\xcb\x86\\6\x96\xf0>Ox\xe8r\x0f\nH\x80\xf4\xe9c<\xe0\xf2\xa8\xef\xfb\xd9P~\xbe\xc3\x93\xe8\x98h\xd6\x03\x81\xb5z\x8a6\x17w.\xdc\\][[9\xbf\xb8vsqkk\xf1\xea\xcd\xd5\xf5\xe5\x957\xd4\x99\x02\xed\x8e5\xbd\xe5W\x9d\xb2\xdc9\xb1\xa0\x7f\xfc\xc7\x83iu\x1b\xa6\x96p\xc8\xbew\x86\x8d'\xdd\xcb\xc8\x85\xae\xf2H\xf1e\xc0\xbeg6q\x021\x1fr\x19\xc6\xe1\xf7}\xbd&\xec\xd2\xee\xf6\x0e[\xdf\xd8a=\xce\x06\xd2W7a\xd9\xd0 a\xc5\xa5\xc1V\xd0'\xb5\xb8\xa9\xa0Jf\xc9\xab\x0bzyqmw\xe5\xe6\xc6\xee\xce\xcd\x8ds7\xcfn\xec\xae/oO\xbf\x96\xf2\xde \xd8\x92\xb4\xdc\xa7\xd7\xc5\xf4n\xc0\xedV\xd8e^\x97\x0d\x04\x99\xeb|\xfd<\x8b\xd5\xd1R\xfd\xb3\x08\xccE \xc3@\xb9\xc5\x1c9\xc3\x06E\xaa\x83?n\x15\xf8\xe2\xcc\xe4!\xe4\x9a\xdct\xb2a\xe1)8\x90\xa7\xbb\x113\xf0\xaa\xe5\xdf\x9cU\xab]1\xbaZ\x1e\x032Y\xc3\xa8l\x02s\x7fz\x81\xd9&\x16\x13\x07\xe1\xe6\xa5\x91\x7f\xb3\x94\xdf\xce\x05\xe5a\xa3<\xcd\xc4qq\xc2\xe2\x18l\xaf\xbc\xbe\xbb\xb2\xbe\xb4rs}c\xe7\xe6\xe2:\x10\x14\x1c\xe12-\xbb5\x9e>\xf2F\x9f\xef3\x1d\xd6\xa4\x0e\xb9\xf2\x00\xebB>Msk\x9a\xb3\xef\xb2\xf4U\x96\x1f=\xdaa\xfe\xf5\\\x86`\xcau\xba\x9e\x0bN\x05\xf7\xf7\x12R\x16\x8d\xac\xda\x8bO\x054\xbfqC\xe2 \x1bRw\x0bU\xbd\xf6\xa2^\xf4\xd3IVJ\x96rB\xa6\xba\xa9\x10&\xb5%\x1bg/\xae,\xed\xb4\x00k\xc5z\xbcJFy$\xbf\xce\xc5\x01\x9a\xb6\xdf\xafD\xa2\xab\x1f\x9eq\xbe-_\xd9\x81\x826\xe5xEa:b\x87\xa9\x86-\x0cr\x8aa)\x9f(9\x92\x82\xc4\x1d\x07\x12\xa7>\x177\x81\x8dc\xfdv\xfdX\xe5\xa9K3'Q\x1c\xbeu\xbc\xf5\xed/6\xde\xb2\x1a\xc7\xa9\x1a\xc7\xa5\x02 X\xadm\xb9\xa5\x027\xedr\x8b\xc2t\xb9\xe3\x84\xa7\xe2X\xb5U\x88\\/\xe0\x025~(F\xf5C\xe6\x84\x1e\xfb\xa1\x18\xcd\x0fK(\xd4\xa9n\xcd\xb9\xad\x8dK7\xb7V^\xdf]\xddZ\x994W#/\x98\xa9V\xd4c\xf3\xb5P+\xcd\x02\x94o\xa1\xb5Eq\xca\x99\xcb\xd2\xd3O\xdd\xf1\xbc\x1fv\xd9\x0f\xd5\xc8\xd4\"\x88\x115,\x02\xc8\x1b_\xfd*83C'\xdd\xd5\xc9n\xdaz%\xbeyK\xb1\xb4\xb8.H\xdd\xd2\xc6\xfa\xce\xe2\xea\xfa\xcd\xdd\xf5\xe5\x95s\xab\xeb\x13\x96\xc6r%Q6\xc5\xa8e\xa87cB\xa0\xb4<\xe3\x85:\xd8\x98_\x83)kxD+\xd8E 1\x1e_\xd2\x98\x94\x1d\x05\x15I\xfd\xb3y\x0f\x96\x9cP.4OdT\xb2\xa3\x16\xb7$\xe48\x99\x14f=\x9e\xfa \xf7\xa4u\xcfB\x03\xd5\xba..\x97W\xb2I\xe6\xab\xc1\xad\xb2\xe5\xc2|,\x0c\x0fM+\xed\x83W\x99\xa3\xdc\xac\xa2\xe7\x9a\xb8\x98be\xce\x8e\x9c\xa9\x10\xf33\xe6E\x1c\xf0\x91\x1f\xf8if\x99\xfd\xee\xfa\xd6\xca\xf6\xc6\xda\xe5\xc5\xb3k+\xd3\xce\x7f\n\xfaZ\x8fQ\x81\x10\x07\xdb\x16\xff}\xfdk2\xd0\xea\x1f\x18j\x81\\O\xbc\xa3\xab\xc9}.~wo\xd0c\xa3\x7fb\xaa\xd2\xeb\xbdq\xc9\xe4\x9c\x03\x99\xf9\xe2K\xec\x9a\x98\xc7\xd4\xfb&\xd9\xc3\xd4\xfb\xd6(\xd7yZ\xae\xc3;f\xf7\x8b\x93B\xd4\xf3Iq/J\xb8\xd6\xdd\x87\x1d\xd6oW\xe4\xeb\xb0\xd3\xc5\x02\xb7\xd0\x03~\xf4#\xa1\x11\xd0F\x1aL\x1e\x89L\x19\xf6\xa3\x1f\xd5\xe5\x01\xac\x84t(\xd7\xfc\xc2\xab1\x12\x82y\xd2\xe6\xd7\xa3\x1b\xd2\xb79\xd4\xc6\x9dI1\x0b\xcd\xee\x81\x926\x94\xfdn\xf1\x1a\xd7]\x81\x88\x1f\xecLm0\x99\xf9K:\xed\xca\xf7\x92\xcf\x1enF~\x98I\x0f\xfa\xc0Du\x17\xfc\xee\x0cs\xcdW\xd8\xdb3\xaco\xbel\xc9p\xbd\x04\xc7\xe7\xe2y\xe9\x0b2u\x8bb\x91\xd4A\xebM\xbe>\xc5V\xadaR\xd6\x8c\x8a\x85\x12\x13\x1c;\x81\xef9\x99\xf4\xe9\x8aK\x1f\x84\xd6\xe5}K\x15\x9b\xc6\xb3-l\xcf\xbfR\xea\xbd\xd6w\xdb\xa6h\x1dI\x94\xb72\x9f\xb9\x99\x81{\xac^\x9e\x9d\xc3\x98\xab5Y\x0de@U\xe6\x0b\xa9#\xe1.\xf7\xc7<\xe92\xf3\x96\x84L)\"x\xe2\x11|\xcc4*!\x1c\xf9BQ\x0b_(\xad\x0cM)SN'Sr\ni\xcf\xcfw*\x8ew\x96<25\xbe\x93\xf4\x909\xfd\x8c'k\x91\xe3M\x13a \xafk\x93(\xcaVC\x08\xc4>C?\xe9w\xc9\xd1\xf7\x19?\xf4\xb3\x8d\xc5<\x1bB\xb2\x98<\x1b.\xca\xde\xd2\x197\n\xfb\xfe O\xb8\x80Zj\xc6 7)\xdc\x16e*(is\xee\xf9\xa1\xd7\x86\xcb\x0f\xe94\xdeT\x0d\xf2\x1a\x9dan\xb5\x16%O\x94\xa5\xa6\x99\x93\xf1\xcd \x1f\xf8\xa15\x0eD\xfcD?u0&W_\x12\x87t\x81Ez\xb3\xeay\xb7\x03\xcb\xd2\x185\x96\xf2\x80\xbbY$Z\xb4\xbf\x0fY\x93\x95\x16r\xdd\xd4\x0ft?q\xe2E\xdd\xbf\xfdQ\xae\x89\xee!U\xdaa\xdd\x05\x0c(v\xb5\x8a\xf0\x91B\xf8\x13\xa7O\xe2\x9c\x19>\xbc<\xd4\x9e?A\xb2M:\nt\xe2\xf4)\x0c\xca\x0dH\xe6\xd90\xb0&\xb7c`C(\xdbc\xd3\xed{&\xa3J(iWQW6\xbc#\x89\xea&$\xe80\x91D*\x05@\x06\xd1\xdf\xfczX\x93K\xa2L$x9\xff\xa7M6\nj}\xaf\xa7\xcfzY\x93\xf1\xb2Y(s5\x89\xb5\x18\xdb\n\x9d\xacL;\x0c\nQ|/\x1e\x0d\xd9\xd6\xa7\x85\x16\xca\xa5\xcdR\x14\x12\xdc\xd5r\xfaMz5?\xddX\xdc>\xd1\x91 \xcd&>\xb2\xc1\x16\xd8\xf5\x96%\xd3b\xcb\x12\xa6*\xd4\x82\xbc\xdd\x11r\xc8j\xd8\xben\xd2E\xa4]v=\xbbA\xd2\xc1\xc0F\x04\xec5\xe6\xcb\x07\x99\x13\x94\n\xb3![\x99\xfd\xdc\xebdq\xb5\xae5:u\x9c\xcd\xcf\xd2F0\xc5\"8\x0b,\x98\xc9\xa2\x8b\xdb\xe8=gHS+NB#\"\xf4\xeb\x1c\x8d4U\x98\x1a\x0b\xfci\xb0\xc0\x81\xb7[j\xb1 7O ~eX \xc3\x98-X\x907aA\xca^c\xd1\xf3b\x81\x0d\xcb\xd5\x96\xa5So\x19\xfb\xa6\x89F]\xed\n-\xa5#\xca+$\x84d^r\x14d\x8e<\x00\x90Kq\xf5;\xe8+$\x1b\x9e\xc3\x11\x16\x81\x8a\x87\x98\xb7\xf2\x14\xf7\xeb!\xa7\xfa\xaf2\xa9\x97\xfeT:'kT\xca\xc9\xdae\xc1\xcc\xf6\x85\x8d+7\x17ww.\xdc\xdc\xdc\xd8\xdc\xdd\x9c\x90oY\xfb\x95e3\xb1-\x9f\x9f\x9e\xd1L\xca\xb3v+\x1dF\xfbe\x84\x17\xa8Q\xda;\xfbx\xc4P6\xb6V\xaf\xad<\xefH(B'&Op?\x89F\x17\xb7;BW&\xa5\x80\x90\x0c\xc4\x80\x8b\x1c\xc1-x8CV\xbe\xe4\xc4\x1d\x1c\xf8n\xd4%\x1ef\xc9\xe16\xbf\xdd\x9e6\xe3\xba\x96\x0dP\xbaN\xdee8\xb0U\xff\xe4,\xaf\xcf\xd6\xe46H$t\xae\x06\nIe\x159i\xc1 \x17T*\x939\xcfjl\x0c\x95T\xab2\xc7H\xe9\xa5\x1d\xbf#W,\x92[\x1c\xda\xcdG\x85\xa9\xac\x94\xdf\xd4\x9a\x97\x87\x95\xc2}\x8aq\xca\x93.\x86\xa9\xb9R\xebFC\xfca`\xaf\xab\x19\x96u\x9aLm|\xdb\xccET\x0e\xbbL\xd5ot\x9f.xe^?*H3\xb7P\xce\xa6\n\x8f\x93\xf5\xb2\xc8)?\xdaS\xf7Ls\xa7S\x1e\x96\xda\xba\x1b]\x98j[\x7f\x98\x98\x11B\x066\xc3y,\xa1\xb7\x10\xad\xa6?\x8a77\xc4\x9f\xf3/\xe6D\x86\x92Q\xdb\xcfaX\x97,\xd9\xa9\xf1u2\xe7\x10\xde\xeb!o\xfd\n\xaa\x17u \xcfH\x95\x14$z]$\xd6T\x96\xc6\x81\x15\x96\x88\xd7\xb9\xd1-\xe7\x05\xac[\xaa\xb5\x8d\xf3\x1b\xbb;/f\x81,\xc4hf\xdf\xcf\x86\x97\xf2\x0c\xaeG\xa6\xc8\xa8h\xc9\xe4\xd5\xf8\x8c+\x9f\x81\xc0\xb2\xda\x10^\x0b\x9a\xd5\x98N,\xb8\x96L^\xc0\xa5\x8d\xf5s\xab\xe7w\xb7V$/z\xde\x85l\x1a \x18\x16,\xdcG\x8d\xea\xb7+\xc0t\xc1\xf6\xb8\x04\x83\x94s\xf2\xd3E\xb3x\x90\xd4\xad\xfaO\xaf`\xa9\xe7\xa2d\x0bLY\xe0\xbe\xa4\xd2\x0f\x94\x98\xee\xd9\xc3ug\xc4S\\q'2}H\x90`\xd5a\xa9\x9a\xe5\xb8i\xdbS\xde\x0e\xdb'\x89t\x15)\x08\x95\xa1 o\xc3),D9J\xb4z\xbe8\xe2\xafDV\x1a\xab\x04B\xf5\xc7\x8a\x9a\x05\xcb\x967\xcb\xe2\x01\x19\x82\xec\x90Z\xe5\xe8\x08enr\x1f\x8a\xbc#\xd9\xa9\x83p\xa6v/'\xf7\\\xd3\xf1tb\x0b\xd2\xa2l\x0f \xb4\x8d\xec\xe4\x80\xecT\xfb\xcaQh\xe4\xa05?\xcd\x88\x90\xc5\xca\x96\x8b\xe7\x16\xb4\x18\x12\xb6\xa2\xa9\x84-fD\xaa:\x81\x8b)\x9c\xae\x17\xbaXIYt\xac\xe2c\xb9T.\xc9T\xd2\x95/%\x86\xe0\x1b\x9b\xa7\xc3vn#\xb9]\x9c\x17\x91\x92\x12\xeb\xe1o$\xa7S#@H\x11\x80\xce\xcb\x8d\xc24\n\xf8\xcc\xbe\x93\x84\xed\xd6\x95\xc5\xad\xf5\xd5\xf5\xf3\x0b\xcc>2?e\x1e\x8f\x13\xee:\xe00\xeb\xb1}?\x08X\x8f\xeb0\x1e\xed\x91\x19\xf2\x83\x8c\x8d\x9c[Q\xc2\xc6\\g\x9aB7\xe2;\xd3\x04\xbb\x11\xe7\x99\xce`,I\x98?\xa1W\x1b\x8f\xc1\xbf\xca\x9b\x039PF\xa9\xba(\xd7\x95T\xd0\xbc\x97^b\xed6\xbcp\xa1$\xe3(\xe6i\xab\xd3\x99\xd9\xe3_h%\x99\xf4~v\xa30s\xfc0U\x17N\xb2\x87T\x8bI\xdc\"w\xeb\xdf]\xe5\xc1\x98+I(\x08\xa2}\xeem\xc3\xa8\xba,\xed\xa8\xe46\x99\x84\xfb]f9\xe9\xba\x1d\x1f\x9e\n\x95\xb9\xcd\xec\xf4\xc0\xaf\xa3\x07\xddI\xa2B\xfdbh|u\x92\x81\xbc\x08L\x0b\x07\xb79V\xcd\x15f\x8a\\\x9f\xbb\xc1^\xab\xfes\xa1\xe9TMEtT\xa16\x18\xfa\n\xaec\xe7~e\xc6\xa3\xfa\xecL\x9f\x84\xdc\x1c\xf14\x1a\xf1)\xc5fSG \x1e/\xe1\x9b\x9f\xa4Y\xbb\x06G\xac\xb2t\xd3.V\xe4\xbf\xc9\xfc}\x82da3rh\xa2\x84\xb8 \x92D_$\x13\xa9\xeeg1\xa6\x06\xe2\x0b\x9b:\xe3\xa7\xe2?\x10\x1b|\xe4H\xa6\x8c\x95\xcf\xbd\xcf*\x97#2\x9b\xf2\xce\xcc\xc8\x89\xa7h\xa5\xd4\xd2\x91#!\xec\x7f\xddv\x1b\xaf\xd1#s\xb6\xad\xd7\x87\x0b\x99W\x19E\x84\x8a\xa2\xf0\xa5\x11A+F\xe5]\xff\x16\xfbFhD\xfc\x80\xbb\xb9\xf4,\xb0j!]\x95\xe5f\xfe\x94E\xd7\x90\xd6\xceH2\x88\xa4\xaa($\xcd\x8aB5^\xb8\"\xe1\x17\xe3\x99R/\xad\xa0\xb7]\xcd\xcf\x9a\x04)|\x9aj\x9f\x83\x89\x94\x1a\\\xe7\x8e\xe8\xa8\x0c\xd6\xd90\xaayr,\x97%\xa6x\xc1M,C\x968\x0d\xcf\xc9\xd6\x1f\x95\xe2\x80/(\x03\x90>\xeeb\x9f\xaa_\xd4\x89\xae\x97\x1eJ\xd4\x7f\x81%5*\x88\xdc~+hb\xfb\xe5W\xdd\xca\x1d\xe0VMS\xf6s_K\xc8x\x1b[\xa9\xac\x0d\x80\x93_\xcd\x1by\xb0\xa3\x0b\xcc\xb1\x83K\x0f\xde\xd4\xd8(\xcb\xaf\xe6X^\xbf\x95rJ\x1d-\xfa\x86P\x89/\xe3\xf1\xd2\x0f\xebnB\xd3\xa1\x94\xd8Vn\xe7N\xf0}~\x08(\x86\xbe\xd1\xf5\xaa[*j?\x917G\xdf\x80\x15\xa4#K\xdba\xfb$y\xe7:2>\x16\x13\xfd\x8dj\x05I>\xd3\xb7\x10\x16{\x82\x02\xf1\xf3\xa2\xfd0\x98\xd2\x1d\x89Y\xc8emj\n\xfd+\xf4D\x9e$\xea\x02\xb9Y]aZQ\x9at\x8d\x8c\x7f\x8e\xa94u?\x10\xf8Tp\xfb\xc95\x02I\x9f\xfb\xa0\xc4v\xcc\xddv6\x93 ~'\xf4\x8a< \xda\x9d\"\x93\xbf.\xb6\x9b\x04u6\n\xfdk\x1e\xbbL\x14#8\xac\xea\xa2[7\xc6\x00\xfe ,\xdc\x0d\xb8\x934\xbc\x8d\xa1\x7f\xcf\x83dB\xfe\x0f\xa6h3O\x82\x05[\x9e\x16\xfc\x13\x03\xde\x96^\xd1G\x1a\x1e<\xd4?\xf5 \xe9j\x98\xf1\xc4\xe5q\x16%\x0b2=\x0f\xfe*\x96j:\xf9\xb5\xfc#w\x8du\xbf\x1a\xef\xee\xf2/\xe1i\x1c\x85)'C%\x9f\x7f\xfbcu\x13\xee\xf10\xf3\x9d ]`\xad\xd4\x19qEg\x1b\xe2\xe0\xf4O\x91\xb7&\xa7\xf6\xf2OP\xc98[\xa8\xbe\xe2y+\x8d\xc2\xee\x1f\x1c\xff\x83\xc9\xe4\xad\xf9\x94\xdc\xed\xccdC\x1e\xb6\xfb]\xd6o\xb8$\xb0Bj\x96\xc9r\xc8\xa6\xd5\x8c\xb4@x\x1d\xa2\x1d\xcc\xd1\xec\xb2V\x11*\xa4i\x8a\xf9\x08zG\xab\xe1\x0d\xf4\xaa\x1553&Nx\\N\xdf\x01r\x95\x11G\xfcg\x01\xc4p)\x90Ws h\xdf\xa8\x92\x1d6\xebLdT\xd9a,\xa8\x85\x90\xb5n\xc2\x02\xddT\x93\xbb B\xf8\x04\xbcQ\xae#\xb6\x04n\xfaW\xb3I\xe4\xab\xcd\xff\xb9V\xb7\x0d\xaa\xdbh7\xe3N\xb7\xb9\xc6)\xa2\xce\x8c_\xfe\xddm\xb2\x0c\x97\x7fU+qe\xb8pc@\xcc\xd4\xfag\xbb\xd9\xb0\xda5i\xe7\xd3\x04\xd8L\x8a[113\x8d\xd9!u\x10N3v\xd5\xa3\xd5B\xb3\x0d\xd8\xf6S\xb3\xb6\xbc.g<\x98 \xd1)]\xf0nQD\xe6;m&=\xf5\x98\xdc`\xed,\xa2\x88j\x1e\xa0\xa2\x9b\xfa-\xfb\xbf\x90\xb5k\x82\xe7O\xf5\xab \xca\x99\x9f:&\xe7\xab\xf2 \xfa\xed\xda\xe5\xbe\xace\xf3\x85\x9e\xa4\x1a\xf32\xab\xe2M\xdf\x8e7\xf6\xba\xea\xdai\xbaH\xb9t\xe6EG\xca}\xe9x6j7u\xdba\xfb\xf4 \x12\x9c\xa6\xee\xa8N\x9c\xb0\\R\xc9\x00NZ\xc5Q\xa0\x93\xb3\xb3\xb6P\x04\x00\x11\x0bm\xaa\xc6pr\xb6\xe6\xecXB\xb9\xfe\xe9\xc5\xb3}\xcd\x01\x18c\x95T\xb2\xda\xc8\x80gk\x91\xeb\x04 `-4\x9b\x03\xb5\xf7\x834K\xc4N\x92\xf2\xab\xceHU\xed\xb4\x0bi\xa9q,\xbf}bf\xec\xd8g\x0fw\x130Tk\xfb>|op6\x85\xf3S\xb9v\xc0U'^w7_\xa2\x96\x169\x9b\xe9\x87`C\xef`E\xb9\xee\"^O\xe9\xb9\\#\xac\x06*}\x99[\xb9*\xa0\xf2\xb7<\xb7\xe6\x9cFh9\xda\\)\x1f~\x97\xf96\x03\xbf9\x0d~\xfd\x1dIh5\xe2\x87U#>{\x8d\xb5\xa3&\xfb\xbdR!:\x02w\x9f\xab\xd8n\x12\xb4[\xe2CU\x89\x08KV\xfd\xc2\xa8?\x93'\x81@2x\x81]HH\x99\x8a\x84#\xe7%\x04\x03\x89ED\xfd\x06\x9f\x9f2\xe6\x0fx6%\xa6q\x15\x0d\x83\xdf\xdf\x94\xf6\xfc\x05\x19J\xf8\x0d\x9d\xa5v\xef\xe8*\xe1q\xde\xf6\xda\x9f\xf4\xf0\xf0\xbf\xbc\x87\x07e\xb0u\xb1~\x82U\xdb\xef>e\x00\x91\x8e\xad+\xc5sE]\x96\xce\xecn./\xee\xac\xdc\x84\xd8\x86\xed A\x0df\xef\xe0\xb9\xf1j\xb4J\xa1\x04\xd0P\n\xdc\xeb\xce\xc6\xf9\xf3k\xd3\xf6\xfa\\1)8U\x89\x19\xb2\x8a\x05;\x82\x02=\xa2o\xc2=\xf7\xf3\xc9\xd3\xd7\x0d[\xb5\xd9\x1f\xa6\x91\xad\xa7\x90o+ \x16\xea\x8b1e-\xe0\xf8\x15\x8d\xe7\xd09\x9f\xfb\xbe\x91C&\x1b\x95c\xb4[xtNa\xb2f%\x84\xda\xf7C/\xda/.3\x86NZ\x93\x00\x0d\xff\xb2\x99\xc09\x8c\xf2L\xc7uKJ\xbe\xccy\xbc\xe6\x87{\x17\x9ct8\xcd\xfd\xd2\x04\x1b]-\xf4K\x98|\xc4\xae\x9a\xfc\xb6\xb5\x1b[\xf2\xcc\x99\x90\x06\xc4$\x1d\xdaq\x06\x0b\x85\xbb\x10\x1dJ\xe5\xcb\xdd\"\xd1\xacEUq\xa4\x9a`UU\x00\xf4\xb2-|\x07@\xdf\xb1+\x17\xce\xd7'W\xff\xf6 \x89\xbc\xcc\xd8v\x93(\x08v\xc0\xf5.U\xffPw\xe0\xf2[\xc2\x1d\xefp'\x82r\x8a\xb8\"\x1c\xae\xd45!X\xcd\x0e\x8f\xfd\xda\xb8\xf6\xbe5\xf2\n\x0c-'g\xb1\x97d\xaej\x9c>AR\xa34\x86\xb6c\xde(\xdf\xa0l\x07V\xac\xe8\x7f}X\xc1\xd4*\xc5\xe5e\x9cH/\x0b\xc67\xc9\xcf\x06\x9c5\x81&5\xc4\xbdLKp+\xef\xf8c\x0f{\xd8h-\xafU\xde\xc2\xcfT\xee\xe3\x08r\x1f\x17\x9e\xf6y\x8d\x99\x1e\xb2*V\xa9y\xd4\xe9\xb2\xb0\xdd\x91\x8f0\nT\xf4\xc3Ag\x8aG`\xc5\xfeG\x13#D\\Yj\xae\xe1\xd6 0O@k\xa14\x10Bi \x84\xd2\xa0\xa1\x9eV\xa6\x13!\xef\x8b\xe3#+\x9fK\xa2\xd1j\xba=\x8c\xf6\xc3\xef\xf3C\x89\x88u\x0d\xc8\xdca}\xf4:ls\x7f1\x8d&\xeeO\x8e\xa5\xf1\xd8\x19\x16O\\\xa9\xa1,\xd5\xb4Rr\xc0n\xa7\xac\x9e:B\xcc\x12\x93\xef\xc8\xa4\xa2\xf5u\xe7\xe5\x9d\x8cyX\xf65\\\xbb-\xe3\xd0\xe1\xcaA\xd3\xa4M'\x83v\xd9Q\xe6Iw\x16\xf1\xd7P\xaaTs\xd5\xf6^z\xe9\xb9\x1b\xac\x8b\x84\x98\xea.\xbe\xaa\x07N\xff\xb2Z\x95hT7\xc4\xc3\xf4\xb7\xf9j\xa4\xd6\xd8\xca\x8a\x8b( \x107\xa1\xcd\x9bYTs\xfdd\xae\x9dp\x1eIE\x06\xafs\xfaTW\xe3T\x86\xb5\x0cf\xaa95[GX\x85RV\xe4\xb2z\x0c\x9f\x92`2\x85\xe6`z)\xa8p\xa7J\x9f$\xbbh\xc2\x8f\xb1\xc9\x06\x04\x0f\x90\xcc5\x1c\x8d\xd6\x11\xf08\x13\xc4\x8c\xe9\xcc\xf9\x91\xa9\xd8\xe9J\xc4o*\xd1L4|\x9c\xf9w\xfah\x12\xfd\xd3'\x9e\xebwhT\xba\xdd\xf6\xf1\x9b\xc7\x07]\xd6b\xad >\x1c\x13(\x94#\xe9\xa8o\xe8\xa6\xa0\xa2\xbb%\xaa\xda\xf6\x1b\xe6\x18J\xfe\xdav\xba\xf0\xdc@h\x8eP\xdby!\xe7rl\x95\x9f&2\xf3\xa9,l\xac\xe2\xf7\x8b\xd0S\xe0\x9f\x96\xeb\x043\xa9Y\x03\xd7xi\xf9i;\x01\xfd;0Z:\xef\x80\xe1:D\x1a\x0c\x92\x11%g\xc7e*\x92\xa5-t\xacq\xddF5\xb2\xe8\x8b[\xb9f!A\xca\xbd`&\xec\x87\xc5Zn:\x89\x98/\x17\x92\x8cY9u\xd7-\x0b\xc8G\x1eg\xb2\xa8\x96\xac\xff\xd68\xc4@\xae(\x96\xf7\xa7\xb1\xd7O\xc3%d\xbb\x8aWP\x87\x1340\xbb\xe5\xa9\xda\x8d=\x9e\x01m\xc4\x94f\x04M\xf0\x8d\x97\xaf\xfeC\xe1U3\xe5\x97\x84|\x14\xe7\x19\xf7\xb6\xb3\xc3@\xe6#\xae\xad \xd6\xb4\xe5\xf4\xd2(\xc83\x95S;\x99\x89\xa3T\xc6\xea\xd4W\x93\xf1\xf7\xec5v\xbc\xed\xe4Y\xf4#X\xc7\x1f\x0d}\xcf\xe3a\xe78[\xa8\x02:\xc7\xeb\x99O\xab\xef\x1fp\x0f\xf7\\\xbc\x90f\xafidx\x99^\xf0U\xf9\x1fG\xf0\xe0b\x91^\xad\xa7\xd221\xbdm\xa5\x9cN\x97\xb5\x8f\xc8wTZi\xe6d\xbe\x0b\xae\xd3\xe5\x81\xbd\xf4\x12\xf3eZ\xe0v2\x13\x8dy\xd2\x0f\xa2}v\x94\x15\xff\xb8Z\xf9\xd7\x1b\x9d\xc2\xdd\xde>\x17=\xd3IX\x88\x14\xc5 \x960\xc0\xf3\xdaT\xa9\x93\x8d_\x88\x96-\xb0\x86D\xe7\xba\xec\x02\xab\x89q\x13\xbf\xcaQ^`\x83\x06,.\xb3\x9f\x056\xae/I\xa4\xae\x056\xb4\x13\x1f{\x1b\xa5{\xe9\xfa\x95\xa8r\xa6i\x1d\xbf\x18\xc3\x9e\xccM\xef$\xf5UZ\xac\xed\x01\xb4_\xd4{\xa44\x8b&\xa9\x1e^;\xf1\xbb,\xb7SgDX\xb2\xa1\x9fvY\x9d]\xd5\x08\xc1\xa9\xd5\x90\xed\x1aCv\xda\xe9J\xeb\xed\xec\xab\xac\x0f\x8f\xf8\xf5\x8f\x1e\xed0\xf7z\xbfj\xc8\xee7\xbf\x16/\xd8\x9cO3\xa7\xc2 \xe5\xbb\x83\xc1\xcc\xcd\x9b\xd2\xb9\xec\xe6M\xed\x12]\xf2)\x0f:\x1d\xe9a\xa6L\xe2\xbc\xcb\xae\x8b\xba&\xc9\xb2\xdb\xe9\xc8\xf0\x99(\\\x8b\x1co\xa2\xfdL\xff4\x07\xf6g\xe2$\x8a\xd3\"\x93\xc2L\x16\xc1\xc1j\xca5\xc0\x14\x17F\x92G8\x939\x83\xae|\x04U}]\xf5\x1a8*\xbe2\xadH\xb0\x82?\xd4\xe9\xc4p\xc3\x10\x12G\x02{V\"J\x96K\xe6\xe9\xbc\xb4\xd2\xf06<\x92I\x82.\xaby\xf6hO\x88=\xad\x84\x87\x1eOj\xcc\xa6\x8a\xdaL\xbc]a\xc5\xa0Rdq0Q\xaai\xec\x84\x84\x9c\xd1F\xfa\x0b\xf0\x9c\x04\xe0Cm\xe1\xbb\xdd\xda\x9e\xb8z\x90B\"F\x1d?\xa7\xab|\xa3\xd3E)\x19\xee\xb6\x8b.\xcc\x15\xf37\xda\x87\xe7\x1bG\xfaCi\x176\xff\xfc\x1d\xd9/\xfd~G\xf6\xbf8\xd9\xb7\xe8\x85\x9a\x13d\xce\xe0\x0b\xd3\xec\xf0w4\xfbw4\xfb\xab\xa6\xd9\xcf\xe7\x1ag!?\xb5It\xa28='\x13\xb2=\x87\xe3R10\xc4Kt\xba\xaf\x93\xb3\xa7-L\xe3E\xe5\xfb\xfa\xe6\xeeG\xa3\xb7(\xc9{gy/\xa5TA\xbe\xd5~\x86\x85&`\x13\x87\x0f\xfc\x97\x85\xa1\x93\xcc\xd4l\x8a`\xa8)\xed\x19\xcc\x04\xeaB$\xf9tlD\xff\xa6\xf5\x1e\xc2?U/\x91\x0f\xc0w\x1b\xbc7'\xb6f7\x9a\x19h\xb3\n\x03\x13\xbf\x98F!\x9e\xfc\x146L\xf6%\xe6os\xe3jwf\xa2P\x90\xdc\x80g\x96G!m?\xb3\x8c/\xbd\xc4Zz\x10\xe5@\xcdP^\xec\xa6<\xdb\xf1G<\xca\xa5\xbb3<\xb8\x7f\x86\x1d\x99\xeb|\x95+_\x0b\xad1s\x92\xaf\xd3\xd2Y9\x15\xeb\xa1/\xefF\xf9\xbd\xc6\x96\xe7d\xce\x82?r\x06\xfcx:\x1e\x1c=\x18\x05\xaf\xf6\x9c\x94\xbf|\xb2\xbbya}\xfe\xda\xe1\xd9\x13\xce\x95\xadYgy\xd6\xbftkq\xdf\xbd0\xf0W\x97\xceF\xd7\xae\x04\xa1s\xe1\xf5\xd3\xab\xb7V\xf7/]8{r\xd5_\x1c\xf0\xf3si/\xbctzu4\x9c\xf5.,\xbe\xbcvx\xfa\x84w\xc2\xcd\xbd;\x97\xf2\xde\x89\x8b\xe1\xda\x9d\xd5\xfdK\xcb\x8bc\xf7\xc4\xb5p\xd5?;\xef\\\xb9|\xe2\xf5\xd1\xe9\x93\x9b\xdb\xab\xfb\xab\xcb\x8b\x83K;\x8b\xfb\xab\xcb+\xfb\x97\x96V\x07\xee\x85\x8b\x81;\x7f\xf9\xd0\x1b]>\xeb\x9e8\x1b\\=\xb1\xb5}\xf5\x8d\xad\xb8wg\xd6\xe7+s\xf1\xb5s\xc1\xbas\xe5u\x7f\xf5\xfczz\xf5\x8d\xf5;\x9b\xdb\x17\xd3k\x17.e\xee\xe8t\xda;\x1f\xe4\xd7\x0eW\x07\xee\x89\xadS\xbd\xf3\xbb\xa7WG\x17\x87W\xe7\xb3\xd0\x1d\x9d\x9e\xeb\x8d^\xcf\x9c+s\xc3k\xf3\xbb/\xaf\x9e?5\xee\x8dv\xbf\xb3z\xbe\nw\xcf\x9f\xbe\xe3\x88\xbe\xe6O\xbe\xbcz>\xc8\xc5\xdfW\xaf\xec\x0f\x9c+\xa7b\xef|0\xec-\xa7\x83\xab\xa3s\xb7\x9cy\xef\xb0w\xe2r~mi\xee\xf0\xda\x1bg\x83\xabo\xbc^W\xde\xdf\xbcup\xcby\xe3\xe2\xad\xde\xf9\xdd\xc1\xd5\x13\x83\xd3\xab\xb7v\xf7W\xfd\xb3\xb7\xf8\xce\xac\xbf\xbe\xb3\xe8\xaf\x9e\xbf\x16\xf7\xce\xef\x9f^\x1d\xc91\xf9\xab\xe7O\x85kW\xce\xcdz\x17V3\xf7\xc4\xd6ao>\x0b6\xb7/~\x87\xcf\xaf\x8f{\xa3k\xf1\xb5\xc3S\xb7z\xf3\x07c7\x9c;\xbd\xea\x9f\xcd\xaf\x1d\xce\x0d\xbd\x0b[\x87ko\xac\xcf\xba\xa3\xd3\xc9\xb5\xed9\xb3o\xfcDv\xab7\x7fj\xe4\\qso>\xd8\xf3\xce\x0fO\xf7\xb7W\x07\xbd\x91\x9b]}ck\xd6\xf5\xe7\x0eQ\xdb\x87W\xafl\xc5\xde\x1b\xeb\xb8\xdc\x1d\xef\xc2\xc5\xb13\xbf\x9b];\x7f\xee\x8es\xfe\xdc\xa1;:w\n\xd5\xdd\xbb\xfa\xc6zt\xf5\x8d\x8b\x87W\xdf\x08d\xfdb\xfc\xab\xb7\xd6wv\xe7\xc4\xffV\xfd\xb3\xa6-\x18\x93X\x93\x15\xb1&\x87\x9b\xdb\xabw\xd6K\xf5\xd6\xael\x0d\xdd\xf9\xe1\xd0\x0d/\x0e\xc5z]\xda\xb9:\xbbvk\xef\xce\xa5;W\x0f\xd6\x97/\x1d\\\xba\xf3\xfa\xfc\xfa\xf2\xca\xdc\xea\xf2\xee\xfc\xda\xad\xbd\x13\xebw\x06'.\xed\xbc~g\xfd\xce\xe0\xf0\xd2\xce\xa5\x93\xab\xb7N\xber\xf5\xca\xa9\xb8w\xe5\xdc\xec\xb5\xcb[\x87W\xaf\x9c\xbasmt\xfa\xb0\xb7}V\xae\x99s\xe5\xe2\x9cw\xfe\xf2\xc6\xd5+sb\x8dg\xdd\xd1\xb9\xdc\x9d\xbf6vG\xb3\xfe\xea\x85\xadS\xae\xc0\xa1\xf0\xe2\xd8;\x7fn\xf6\xda\xf6\xea\xe0\xea\xfc\xb9\xf4\xea\xec\xdc\xf8\x9a\xc4\xad\x83\xb87\xbau\xf9|\x90]{\xe3\xd2\xe9\xd5[\x8b\xdf\xb9\xb4\xbd:\xb8v\xe1\xb2\x98\xf3\x81{\xb8:\xb8:\xba\x1c:WN\x9e^\xbdu\xf6\x8eX\x0b\xc0\xab\xade\x81g\xde\xf2\xac\xef\\9\xb5w\xed\xca\xb5\xb87\n\xc4X\x8en.\x9d\x1e\xf6F\x81\xd8\x9f\xe0\xf2\x85\x8b\xc3^\xb8>\xea\x9d\xb8\x98m\xde\xda\x1f_\x9d\x0f\x0e\xaf\xce\x1f\x04\xe2oq\xe66\x07\xd1\x99\xd67D\"X\x8a\x82\xc0\x89Sx\xbab\xcd\x0f\xf7\xe4\x1f\xe0\xcb#\xff\\\x0d\xe3\x1c\xfe\xda\xe1\x07\xd9b\xc2!\x0d\xea\xd9<\xcb\"\xe0\x16[\xd2KX6\xa5\xfe+\xb3}\xcb\xb7{\xeb\x82\x11\xa5\xff51Ch\xcf\xecW\xac\xafS\xf6mF\x10G7f3i\xf4mF\x90T\x01H\xef\x81\x02\x10#\x88\xab\x00\x15#\x88\xf4\x13\xb7\x9b\xbf\xbf&\x87m\xdaqLx\xbd\xb10p\xab\x85!3\x16\x06\xae^L\x98}\x95\x85\xec\xbb\x8c\xbf\xca\xc2\xa3G;L\xc5\x0d\x17\x16\x86\x10\xa9\xe1jb\xd9tI\xa3U\xe9#G\xd0\xac:3\xb7\"?l\xb7X\xab3\x93%\xfe\xa8\x8dEg&\xb5\xfc2f\xd5wd\x96#\x9b\x14\nLl \x99R\xdbSb\x1c\xc9\xa8a\xa4|G\xdc\xe9(\x99\x05\x8a\x17\x12K]\xec+\x1aIPj\x0b\x9e\xdfE6\x85\xccj=\x98`9\x98\xd6j\xa0\x11\xa4\xd0\xd6\xebET\x95\x834\x0f\x82\xd4M\xb8\xed\x81)\xfd\x0bM\xc9\xfa2\x96\\q\xbc\xcb\xae\xb7\x8a\xf6e&\x9d<\x08j\xdf\x1e\x93\xc9\xec\x8cg\x8e[k\xf5\xe0 \x88B4\xaf\xad!\xed\x84\xd4J\xf7\x9d\xc1\x80'\xc7\\\x8dn2\xabN\xc8^c\xadcr(l\x81\xb5\xea\xbc\xc6\xa7\x1fG\x9b>3\xe97\x99e\xdc\xc0I\xd3u\xf9XZ\xdc\xf6g\xcc?+\xafj\x95\x7fw'\xbb>\xde\xe8Tb\xfd\xdb\xae\xc5\xceR\xa5\xde\x1e\xf1\x97\x1bE=?\xe0bI\xaa\xfb\x9c9\xbd\x80g\x0b\xacu\x0c\xfeB`\x8f\xa7{Y\x14\x0b\xb8\xfa\x13\x15\x08\x9cd \x9a=6\xf4JW\xb3\xafV\xe8A\xf0;J\x00\xbf\xdf\x1a%\x18\xfa^CV8\xa0\x01{\x9c\xc7K\x90\x8d\xb3\xa1=I\x0b\xf8\x0c\xa0\x93\xd0\x02\x01m\xba\xd2\x9bB\"\x88\xf8Sb\x05\xf1\xdb\x90DC\x0cE\x90\x8brw\xe2\xdf\xd0\xa2|\xabQ!\"k\x19\x94c-\xd9b\x8b< k\x86%\x93\xf1\xbe\xf4\x12;\x12NAe\xc0\xb6*C\xe8\x9b\xa9\xcc\xf5\x1a{\xb6\xe1\xd89\xf3C\xe65\xbb>z(\xedG;\xefL\xd2\xf6\xf5u\x83W\x1b\xec\xa4\x7f\xa2\x83\x1c\x1e\x0d2F\xdc)L :\xc8\xa9\xa85\xb1'\xa6z\x0b\xd8w\xd9\xdc4}0\x99\xd4Q\xbe\xe5\xd2\n\xa3\x90\x0b\x02=mT\xad\xa0\xea~\x98O\x91hob =\x84^\x10\xb9{0\x86\xae\xf9\xe8F\xc11\xf9(\xa5\xfc\xde\xd8\xd6\xf3\xda%t\x0cW\x8c\x0c%\xd7K\\\xc1\\\xca8u\x88=\x11\x97\xbf0\xa7J\xb3\xc3\xa0\xf6yl\xfd\xf3\xfc4\x0e\x9c\xc3\x05\xe9}\xacv\xd1\xf2nG\xf9\xd7`9+1\xc7\x9a\x14J/\x86\x19v\x8d\xc2\xf3;\xb6\xf3\xe2\xd8\xce$T\xf4\xfc\xb1\x1d\x0dK|jZ\xc9\xa9\xa8R\x16\xa1Z\xfb\x89\x13\xc7<\xa9u\xd2{!\xd8S\x1c\xc4vI\x85\xfe\x1d&}}\x98\xd4\x93\x8b\xfeU#\x93\xea\xe5+\xc5\xa5\x8e\xfe&\x98?\xcd\x91Y\x1af\xabF|.\x19t\xeaQp\xd2\x82f\xfc s\x12\xee\xb4*\xb7\xec2\xb5\x936\x1d}\xf1\xc6}\xd1\x02j\xb9r\x86\x8c\xa1j\xaa3Tw\xa1Ws\x80(\xdb\xd4\xe6\xab/z\xb0dV6(-\xc7b\xe9b\x08\x85lo\x81\xeb\xe8\xcc\xba\x17 \xd4jB\x00\xa7<02\x15&\xfc\xb5\xc0\xf8\xcc(\x0f2?\x96V\xa7\xeb\xad\x96\xf4\x0bo\x89S \xaf\xf6j\xb3\xac\xaa\xa3\x17Q\xa4\xedZ/~\xf5\xef\x1bC\x13\x9e_\xa9Q\x0f\x0d^\x16\x1d4\x14\x06\xedF\xafj}\xb9\xa4hte\x14g\x87\xb2\xdd\xfa\xe2\x91\x1e\xab\xdc\x17\xd8?\xf9<\x12{\xcd\xfe\xbd-\xb3u!\xc8\x17\x15\xfa\xc4\x81jt\x0f)Q\x16+\xf9\xab\xad\xa8\x17\xaa1\xab\xac\xc6\xb6\x86\xe5 \x97\x86N8\xe0\xc6?\x05\xfei-/P\x94\xbdV?\xdd(V\"n\xfdt\xd5\x80Z\xf6d\xd6w\xbb\xacu\xecX\xab\xa3DWA\xf6\xaaq\xca\xd3\x054|\x99\x012}R\x1a\xa2 Y1\x91m\x999\xb7)}\xfd\xddnQ\xe8\xb7\xc9\xc2\n|92\x87\xac\xfe\xd5\xa3T\xbd\xd7\xa8\xda\xab\x86\x93BM\xcb\xd4\x81\x9e\x99\n\x8a\x95\x9b\x9a\x18\xf2\xc9'\x91\x1a\x08\x9e\xd6m7\x93\x83p\n*\xe3K\xab\x02\x84\xd7+N3\x939\xc9\x80g3\x80Ei\x83\xf3\xb43\xe1\xa5\x1b\x01\x8f\xd8k\xcc\x9f\xce\xd0\xaf\x7f\xc6\xb7\x06\xe8\n\xb7\xfb\x91\xdd}\x9e\xe0~\xd3\xa4\xc4\xe7\x9a\xf6\x04=\xd4\x93\x97\xe5\xba\x103\x04\x81!\x13\x0f\xbbS\xd3l\x17\xdc\x1a\x12[\x88>\xc2\xff\xeaR\x8f\x85\xd0`.\xd8\x9a':A\xe8g\xbfe\xc1\x9f\x91\xb9\xb2\x17\xc2\xec\xd9d\x86\xcf\x9e\x83\xe9\xb3)\x88\xab\xf3e\xf4\x00\xe8 X`\xad0\x8ab\x1e\xf2\x84\x85Q\xc2\xfb\x9fCe\xd5e\xb0\xce\xb6\xd1\x8c\x98c\xf3\x04\x9d;\xf4\x03/\xe1\x96\x90\xeeIK\x0e\x9a\xbc}U'\x9a\x8d\x86\xdc\x1f\x0c\xe5c\x13ymR\x18\xf1\xebE\x89\xc7\x93\x05eUj\x10H\x9cd\xe0\x87\x0b\xac\xe1\xa1\x92\xd8\xf1\x95\xfa\xf2O\xc9\x04\xb0\x1ee\x8b\xa1?r2\xee} \xc9_\xdfN\x17'\xccO7\xc4Y\xf5\x1a\x84\xc2\xb1\x8e\x19,\x1fL\x85\xf0\x82\xb1\xd4\xe2v\x18\xa5n\xe2\xc7\x99\xbe\x00\x98@6\xef\xda\xce\xc1oO\xe5Q\xab=I\xdb\xd1\x0b8I\xdb\xa9'\x11\xac\xb41\xec5p:\x0e\x95\x8f1,\xfc\xc4\x9dI:F\xe3!\xe8by\xb3\xe3\xc5\x8b\xa6z\x15,\xa2\xa9\x1a\xc6\x82v\x00d\xec\x9b\xe1\xffK\x9dp\xbcZ'\x1c\xcf\xe6j\xe3\xeb*6\x1f\x1c\xcf\xe6j\x93+\x8057\xa2gs\xb5 \x14\x80\xe4\xecw\x15\xe0\xf4+\xa71\xa8\xaf@sd`\xb1\x86\xd8\xfdt\xbc\xaf\xc7OG\xffE\xb4\x91\xe7\xa5\xf5E\xfcQ\xd2\xb5\xa5 \xc1d\xbc\xd6\x8c5!\xee(\xa8\xc4\x1d\xb9\xe0\x15\xe4B\xdc\x91{\xf4h\x87\x05\xd7\xdd\xaaW\x90k\xb9\xe0SK)\xa8\x866\x99\xe5\x84\x11\x81\xdf\x19aF\x115\x9b\xd5\xc5\x1c\x052\xe6(\x99\x19\xf0\xecR\xe4\xf1@HO\x13E\xec\xd2\xf8\x94\x17?7^\xfc\xad\xdf;^z\x15\xfbxKf\x93+2\x87\xfd\xe1\xcc\x1f\xfc\xde\x0f\xca%~p\xfcx\x97\xb5\xa4\x05\xc0\xd6\x96k\xd2\xd8\x1eO\xdd!\x1f9\xa4\xc9\x9aB\xbaQ\xd0\xca\xc8\x14\xee\xaaIo\xf1\xfe\xb6\xac\xf2<\x93N\x14[\xab\xbc\xbf;\xd3\xf7C\xafx\xde\xdbf!\xb8\xdb\x85\x9c\x14\x84\xa1'\xc4 \xa5V8H\xad\xc2\x81\xf3<\xc2\xc1\xd7\xca\x18Uj!\xb9=\xcdJ:\x9f\x98\xff\x94)2\xca\xa7}\xf9\xd8\x81\xc2r\x83\xebK\xe5\xb2T\xc2o\xe7~\xd2\xc4\x99SY.l4\xd2\xb9\x8a\xcbo\xf1~}\xa1\xbe\x99\xc3f\xeds\xf9L\x11`>\xa3nz\x9b\x8d\x832\x8dd\xbb\x05\xecN\x9e\xe4V\x83\xb9b\x08\xa5%\x95\x9aXx\x0c\x857\x13\x7f\xe4g\xfe\x98O\xac0bgX+\x92#i\xd0\x1e\x06\x82\x04\xc2\xab\x902)\xd0\xef\xff~\xc2\xfbuna2 \xa9|\xccx\x00\xe1\x0f\x1a\x07\xcbt\xab=\x10\xb4\xec\x88S\x14sJ\xc5\xccIo\xa7P\xcc\xb8\xa3\x04\xb5\xd6\xdcI\xa1~\xe5[\xa2\x91\x18\x06\x93\xff\x7f,\xf3\xb3\x80\xd7Z<_`\x7f\xd0\xd3\xcd\x9b\x19?\xc8j\xfb\x8b\x05_\x10\xbc\xa8\xb6c\x7f4h\xec7M\xdc\x05\x16\xb6O\xce\xcd5!\x95V/\xe7g\xe3\x83\x86\x8d\xdf\xf7\xbdl8\xb9\xd8Du\x96\x19\x15t\x8d\xf7E\xbfs|4\xe9\xa5=\x95\xbcL\x92\xc2\xc0\x11\xd8<\xa1F/\xca\xb2h\xb4\xc0Zb\xb0\xb5%k\xe2_\xea\\G\x04\x15=\x94\x89\x1a\xfctcq\xfbD\xbbS:\x07\x1e\x8f\x13\xeeJ\xcd\xad\xa6z\xba\xef\xcbL\x84\xae1:J\xbe\xe9\n\xa5\x8c-\xb0#G\x06]y\x06\xcb\xa7+;\x8c9\xbc\x997j2\xf9\xb8N\xca\xcd\xd9]h\\\x99 \x87\xc7\xa3\xb6\xa1\xc6\xe6\x18Bo5\x86\xc6:\xcfelb*\xc0N\x90\xdc\x05\xd6@\x9d\xf5\xaf\xe0F\x8d\xf7)\xfa\x07\\\xa6\xf1\xa12\xfd\x0b\xe5\x14\xa7xL\xbf\xc0\x85\x05v8\xb9\xb8d;\x0b\xccm^\xb4\xa6\xcc\xb1\xb0\xff\x8e\xe0\x0b_n\xfb\x87_r\xfba\x08/v\xf7\xff\xf1m\xa8\x96I\xea\x1e\x8b\xd3\xbf)\xf6T\xbd\xf8X\xbf\xa9P,\xccG=\x9eL,\xe6\x87\x19\x1fLQ\xae\x17E\x01w\xc2\x86rZ\x03\xfc2\xc86\xfe\x92vh\xa6\x91C\xc9\xa9\x13\xef\x02\xd9\x7f\xe9\xd8d\x85O\x8c\xe7\xac\xb5\x0c\x95\xb0s(\xb7d\xe70\xe6\xd4,\xa4\xd7\xa8o\xf6YZ\xa2\xb9w\xc9\x89\xa5Lm\x93\xd0\xab\x1b\x17\x9b\xaaB\x97i\xae\xa46o\xca*\x15\x95\xa3\\\x0b8Um=\xd8\xcd\xa28\x1c\xc4j\x99\x92\x88?\xa9\xa8\xa2\xf1E!q\xc4\xaaE\x8a}n*\xc5\x0fbG(\xac\xb1`\x87EA \x00hx\xd3\x14*\xf1VS.\xf0\xd3\xf2\xc2\x14\xa8Q\x8d\xa6\x87L\xa5\xbf]\xfb\x9e\x18Q\xea\x08\xdd\xfd\x8e\x0c\x90\n\xa8\xc1/\xb7Y\xd6\x84\xe6\xda\xce\xc1J\xd6\x95EN\xce\x9d\xea\xd8\x8c\x7f\xb2\xd0\xec)\xab\xfdO\xc2\xe6N\xd8\x0dm\xf9\xd7kh36\xb0\x19\xc7\xf3.D\xd1^\xbb\xd5\xe3\xfd(\xe1\xdbjy\x14\xd9M\x1b\xd3:\x9a{\xe6a\xc2\xfb0\xcc\x94g\x8bY\x96\xf8\xbd<\xe3m!\x80\xb7\xba\xf6\xdb\xbfN\xb74LlzM\xa7q\x89;\xfe\x87\xd7\x17\x8f]\xfbA:{\xec\xf4\x91\xd7~0s\xe3\xe8\xef\x1f\x1f\xa8d\xc5Ug8\xba\xda\xf5i\x98\x8a\x85\xd1\x88\"\xf0\x94\xae\xf5\xe2\xf2\xf2\xcd\xc5\x9d\x9d\xad\x05v\xbd\x05\x97\xe8\xadj\x86P\x92\xda\x82\xd5\xe6c\xc2C).\x11\xd3(O\\\x8bE\x00\xee\x19\x1a\xfc\x89\xfcBm8s\x06\xee\x0eZ\xd2w\xbc*B\x08\x95;mgE\xd6\xe6\xa4N{\xac\xbb\x94\xach\xabN\xb2\xe7E\xfbaU\xa4\xbbK\x0d\xac\x10\xbbq\x86\x85|\xbf\xb0c\xd6\x08\x8f\xc3l\x14\x88clg}\xd9a\x1c\x0d\x12'\x1e\xf2\xa4\xbeP/\xe1\xce^Z\x0f\x0f\xfcp\xcf\xef\x1f6\x17\xd8\x91\x9b\xbc\xc0Z7{\x81\x13\xeeY\xd2\xa8w\xd4EK;\xb3(\xd0\xae\xcc\x12\x96\xa3\x850w\xff\xafI\x15\x05\xf8\x9fq\x8d\x91\xe3\x8aa\x7fJ\x86\xa6\x01\x04\xb1FN \xd6\xeb\xd9Gx\xd7\x17/m.\xb0\xd6K\xa4|l\xf9\xba\x18J\xccy\xfc\xe7\xb84|\xbf\xf7!\xfd\xae@\x8f\x7fNA\x00\xf8K\nH\x83H>)\xf1\xec\xf1_P\xe0X\x02\xfe\x1b\x02\x90\xb3\xbbGvDz\xa6\xb6\x9e=z\x9f\x02d\x94\xac\xb5\xca(\x85\xf9`,\x02\x90\xe3\xc8\x16?\xb2\x03{\x12\xf8\xd8\x0e\x94\x07\xf2\xd1\x13;P\xf6\xf9\xe8\xa9\x1d\x08\xb3\xf8\x1b;P\xe2\xfc\xa3\x7fm\x07\xca\x85y\xf4?\xda\x81\x12#\x1f\xfd\x1b\nL2\xb9\x02\xbf\xb2A\xc6r\x8e\x0f\x08]\x01\x18L\xe3\xaf(0\x05\xfc\xbfGhE8HEo\x9f\xfc\x84\x02\xee8\x89\xc0\xe7g\xff\xfc?`T\x8c\x06\xd2\xee\xfa)9\xd0\x1a\x80[[\x8c\xe2>\x1c\xf5\x7fO\xaa(\xc8\xcf\xff%\x86\x88S\xf0\xec\xfe=\xf2Y\x10>\x89\x88d\xe9bID\x1fcJ\xe6\x00F\xdf\x7f@\xbe\xfbr\xc1\xee?$\x80(]`\xado\xe3Y\xc4qpxN1#+\xa9s\xe28\x89\x0ej\xc6-@\xfc\xb6u$\x8b\x89\xf4\xac\xb2l\x83\x06|\x80k\xa4.\x10\xcf\x7fI\x0e\xb1\x81\xfco\xa4N\xea\x0f\xe4\xc0\xef\xff\x8cT\x12X\xf0\x07\xe4\xeb\xe1\xa8f\x17\x04DM\xe6\x9f\xe3n2?\xf0$\x8d&L\xd1@\xfe\x07\\'\x17\x02G\xeb\x13\x82Q\xea;!!\xfbn\x14\xfa!\x1c\x14\xcc2\x9d}\x05\xf9\x08S\xf5\x9e\xe3\xee\xb9\x11\xd0\xab\xfb\xefZ\x80Z\xcf\xee\xbdG\xa0\x89\xa4\xbaO1}\xef9\xc9\x98\xcb\xb1<\xc0\xfd\x9du\x92}.1\xfb]\xcc\xbb{\x05\x08\xa3\x1a\x80\x80dS`/\xd9\x13\x80?%\xf3\xee%{\x99\x06\x92%\xab]\xeb\xb3 s\x90\xfd\x81\xcf\x98\xe7\xf6\xbc\xdby$\x97\x1dK\n=\xee:y*W\x0e\x8f\xec\xac\x04q+\xac\xd7\x08\x1b\xc5\xd9\xa1\\\xf4G\x98\x92\xf4\x04~X\x91\x83'a\x94\x8b:oc>qV\x82\x82\xc0Ok\xc0\x99\x9430\xf9\xeb\xa9\xef\xff\x0b\xfd\x0e\xa2\x0c\x1dB\xb6\xcf9\x1co\xd2\x89\x96\xb4\xc8\xbej\x00f6=\x7f\xe0\x02\x05~\x88\x05O\x01\x02\xd1\xf3\xd9/0 \x16\xb0\x1c\xaa\xe1\xc3\xdf\xf3\x07\x91\x17\xc1\xb9\xc4\xb2\x93\x80\xc5\x01l\xe4GX~\x12\xc0\xcc\x1fq\x80ZF\x93\xdeV}~D\xd0\xdd\x1f\xa4\x99#\xb9\xc5_\x90\xa9\xfb\x83,\xf1\xa5,\"\xf4&Q\xe6=rr\x8b2\xd0\xc3{\x98\xd6\xf4\xfcAnF\x8e\xa9W\xcf\x1f\xa83\xfa\xd02)s\xda\x1e\x92\xe5\xd8s\x92h_\x80\xde\xc7\xd4\xa2\x178\xee^\x10\xdd\xe1J\xb8\xfa\x10\xcb,\xb2@z;w\x12 \x7f\x0f\x0b<\x12\xae'%K`5\xa1R\xc2,\x0d\x968*\xa5\x02\xb8\xb5}\xf6\x0b\xb2;\xe5R\x89\xbaT~\xf6\x1e\x96\x02\xa4\xae- \xff\x023\x86^\xb077/\xeb\x90\x03\x12\xec\xcd\x9d\x94\x10BE\x82\xbd\x13\x00\xc1\xc2\xb2LO !\x98\xa1\xf5B\xb1\x18g\x9e\xfd\x183\xda^\xc8o\xe7\xbe$\x07\xf7\xff\xda\x02^\x07\x94~\x8a%\xc0^\x08\x80w\xb1\xbau\xd6\xc8B\xff\x07\xaebd!2nh\xeb\x01\xe9]_i\xdb@\xfb\x99\x0f\xe8E\xe6\x1a\x1d\xf4@J\xf9\xf0>\x05-\xaf \xc8\xcf\x7fa\x81\x04\x12\x82YT/:\xf0\xa0\x0eV4\x04D\xd6\xf9\x19^\x04\xd1\xda\x96\xac\x83%\x11\x01\x91\x07\xd6\xb2\x08\x07\x1e\xd4!\xa8\x10\x1dx\xb2\xce\xcf\x08O\x8f\x0e.\xc8*\x96\x01H2\xfa3r\xf6\xa2\x83\x0b\xcb\xb2\nVo\x05D\xb2\xce\x9fciD4\x06u\xe8.\x1c\x0ce\x9d\x9fa\x92,Z\xdb\x95u\xb0\xbe\" \x92\x95\xfc\x9c\xf0\xfc\xe8`\x08u\xb0\x02$ \xb2\xce\xcf\xc8i\x8e\x0eF~\x08\x04\xea\x01\xa1\xf2\xd1\x81&^\x0f\x08k\x8d\x0e\x0c\xd5}\x80\x15\xb5^t\xb0\x0b{\x8e\x95\x0d\x01\x01<\xc1\x82i/:\xc8\xa1\xce\x7fk\x81\x00\x9e`\xa5S\xb4\x06{\x8e\xb5N\x01\x01<\xf9\xa5\xa55\xa8ci-\x07<\xb1`\xddeY\x85\xd0\x92\xe8@\x9e\xfd\x9f\x11\xca\x16\x1d\\\x06\xd4\xb2\xec\xece\x89[?'\xb49:\x18C\x1dB\x95\xa3\x831\xe0#V\xb6Dk\xb0j\x844F\x07\x97a\xa5\xb1V'Z\x83:XA\x11\x10Xi\x0b\x0e_\x86U\xb3\xec\xf5eXi\x0b\xfa\x8c\xa1\x8e\x05y\xc6\xb0\xd2\x04\x0b\xeae\xe8\xb3\xca\x98\xf6k\xb2o\xf5\x80qO\xb2\xf7\x8f\xf1a=\x0bZ\x10\x95\xb7zF=\xfa\xdf \x84\x8f\x84p\xf7\xec\xad?#\x90:\xc9>Us!R}/\x8d\xc4:\xff\xe0\x07\x96\xefR\x85\xff\x90\xc8#i\x14\x0c\xd3\\\x02\x7fEHv\x1e\xc8m{\x93lu\x1e@j1\x1bH)o\x7fj\x01HM\xf9 \xb6L\x08\x08\xe8\xcax \xce\xe6F\xdf\xb35\xa7@\xb8\xd6\x92\xb6E~\x8a%3\xd7@~J\xea\x80\xfc\x88\x89\xbc\x12G\xefar\xe9:\xb16ta\xf9\xcbu\xe2^\xa2d\xc3\xc7\x98\xd5\xb9N\xac\x9a|\x8c\xf5\x7f\x01R\xb5\xf0\xe8\\'VB\xecc\xcc9\x96\x9c\xd8\xcf\x9c`\xd9\xef\xf7y\xc2\xc3\xccw\x02\xc9\x14~\x82w\xdaubPY\x1e\xff\xe7\x7f\x8f\x1bq\x9d\x04\xb6\xf3-,1\xbaN\"\x15\xd3_\xd3\x05;\x0c\xf8!h\x17X\nqu_\x8f1\x82.\xe9\xf6>\xc5<\xd35\x10Z\x87{\xbe\xd4\xc7\xc9\xb2\x18\x08\xe6YKJW\xf8\x14\xa3\xb4\xab\x01xc\x96J\xaa=V\xc0\\7W\xf3\xa1\xa3\xce\xe34\x95\xc7\xf41f\xf6K\xb0e\x9fb\xb3\x8b\xab\xbe\x93\xfdW\x93\xf9\x18\xcb\xa9K\x02\x1086\x90[R\x1b\xb1\xce\xe6J\x7f\x86\xd6\xc7\xf8\x84.\xf10\xe3\xc9\xb2\x1c\xc4\xc7\x98\x1c\xb9\x12\xe8\xd9\x81K\xfd\xc4\xbe\xdfZ\x9f\xc3D|\xe9\x02\xa8\xd6x{\xdc\xa1\xfc\xfe\x0fdC\x87\x1c$\xe5\xbf\xc4b\x98\x84\x8c\x9c\xc4\x0e]\x1a\n\x12\xfa9\xedF\xaa\xcd\xa4\x17\xb0\xe4\xfd\x82l\x00\xa0\xc6\xaf \xd5\xf0\x13W\x91\x1a,\x9f\nP\xc0\x9d$\x89\xf6\xb56\xf2\xce\xffY_\xc6\xe8\"\xef\xfc_\xd6B\x1eX\xc4\x9e=\xc0\xb2\x8a\x02k\x0d\xf8\x01\x96K\x14\xdcS\x06\x9d\x07X>Z\x92\xf0e%\xd0c\xd9E\xd5\x16L\xf5cL\x9c\x15l[T\xfcs|\x9a\xa0\xd9KF\xd2\xc3B:\xc07\xb5\xb0\x87%u\x00\xef\x18y\xcf\xb2\xba\x92c|\x88\xb5z\xd7\x07=\xd3\xb6\x1f}}\x8c?\xc2\x07\xd2\xf5\x93\x11\xd8^\x9fb\x0b\x82\xeb'\xa9B\x8b\x0f\xb1\xcc\xb5$\xd4\xb7}?\xe5KQ\x98Ey\xb2\x1af|\x908\x923\xde\xc3\x87n)\x88R\xbe\x94'\xc1\xe1r\x94\xf7\x02\xfez\x1ee w\x90-1%\x8b2dc\x82\xbc'\x97\xe6\x97X\x0c\x93\x90\xdc\xcf\xac\xc0\xa5\x08\xac\x89\xcf\xee\x91\xe3\xad \x0b\xb6\x1ap\x03\x83Ey\xd7\x80\x88\xfd\x16@\xb7k`\xa3\x91 Y]\xdbw1\xec\xff\x8a\x02\x80\xd5\x12\x16\x14\x8d\xe2>L\x07Kb\xae|\x19a\xc4\x15\xdd\xb6\xd5\x0c\xf8\x01`\xd7\xdbx_\x8d\x99\x90p\xca(\x1chv\x8bI\xddR\x14\x0e\x92\\ux\x1f\x0b\xbaK\x05\x0f!\x18V\x80\xf0\x11\xb3\xe1\x15-#\xb5t\xdb,\xb4\xfaNw N\"\xb8\xd6\"\xacI\x82r7\xb3C76\xaf\nR@d\x9e(>\xac\xfb\x9e\x02g\xc0\xe7q)\xca\x05?i%\xa2e\xa6\x90\xec!\x99M\xee9I\"W\xe7}26 \x93\xeb\xf3>^\x1f7\xe7\xb1\x84<$s\xcdy*9\xc7C\xacM\xb9y\xa0\x97\x1b\xdbv\x01$\xa7\xf5>\xd6A\x96\x94\xbd\x95\xf0i\xf8~\x0f\xab\x9an.\x84b%\xf9\x126\x92\xc7J\xfe&\xd7:nn\xe4e\xc2\x96s#/\x13\x11+\xd7\xf2\xf2\x03K\x83\x11\\\xe4\x91c\xaf\x84\xbc{O,\x02rn\x90\x92\x90T \x92\"\xe0\xfbX\x8dv\x05y\xe7\xb7\xe3\x84\xbb5\xdb\"\xe1i\xee\xd6mN\x12\x1cjc.\xd6\x80$\xb00\xe7\x12\\\xcd\x93D\x1a\xe6?\xc6J\xb7\x9b'c$\xb3\xd0\xad\xd7E\n\x91\x85N\xbc~d\xea\xba\x87\x0e\xaa|\x83F\x04V}\x83v\x0f_\xc5\xb8\x87\x81\x9b \xda\xf3\xec]L\x90\x97e\xaep\x01z\x13Sc\xaf\x00a\xc1\xd4s\x02}\xa3\x81\x0f\xd8\xb2\xdeh\xd2\xdc\"\x00~\x8aq\xde\xd35(\x00\xc4\xb171QXv\xd2!\\\xb0\xe1\xbd\xf14\xe4\x01f\xea^\xc9>\x8f\x97\xd5\xeb\x05\xd2\xd3\xe0\xd7X\xc8X6Z\x15\xde#\xcf@pc\xcb \xb3cv\xe2\xc1g,\x1e,\xdb\xb5M\xf0\xf5\xf8 >\xb3\x9e\xd7\xb0]z\x1d\x7f\x8a\x8f\xf3\xf2r\x94%\x0e\x984\xdf\xc7\x94\xd7\xf3\xa2,\x05!\xe41FQ\x8f\x0b\x0e\xff1\xd6\xe7\x969p\x1e\xac\x18,\xf3\x00\xae\xbf\xc8\xdc5\x00\xcf\xde+\xe9_\x18i\xbd\xbe\x9f\xc2\xd1\xf9\x00\xbb\xe0,k\x85 \x8f\xc0\xd3\x00\xb28\x17\xe0B\xe9\x03l\xeb\xf5\x86\x0ep\x8a\x9fb!Y@`=\xb1\xcc\xb0\xec;n\xe2g\xbe\xeb\x04\x8bun[\xa52\xa06\xfc\x1a\x0b\xa7\x95\x12B\xd6\xd5mQ,,J\x9eW\x9eT?\xac/\xb2\xa3\xae\xeb\x7f\x8d\x8dx\x9e\xefH2\xfb\x10[\\\x96}g\x14\x815\x86\xc0\xbc\xc90#Gcs\x9e\x80\xa75\x10\xb9h\xd8 N\xad0\xe4\x00\xf8\x03\x07\x04\xe3\xdf\xe0U\xf2\xfc\xd4\x97b\xeeCL\x18=y\x13\xf4 \xc1n\x7f\xec\x83c\x83\x1d\x12\x85\xc6\x94\xfe\x90 \x9a?\x8e\xc2\x03+h\xf9\"\x9ct\x8c5\xde-P\xda\xb1\x1c\xe3\x05n\x94\xc8\x81\xbf\x8b\xf9\x9b\x17\xb8\x89|b\xe0\xd9\xbb\x98\x0f{Q\x10H\x94\xfe}\xdc\xbd\xb9\xa9\xc2:\xb2gD]\xacH*c\x06\xde\x0e\xaf\x06q\xa3Li\xc2?&(\x16eJ\x9f\xc1$[B\x94Pq\x1f\xd3\xa0\xe5([\xb9\x9d\x83>8+:f\x01S\x0c\xae\x01\xd8Z\xc1\xb5\x9d\xf4\xd9}\x8c\x1f+\xb0hX\x0d\xe5\xb0fX\xca\xe1\xcbJ\xd2 \xaa\xc9\x8a\xba\x05\xc2\x83\xd5Fz\"cpU\x01\x1fR8\x9f?\xc1R\x1c\xef\xeb\x860cZ\xd1:\x066\xc3p\x0d\xc07FR\x8bz\xf6\x04o\xc5\x8a \x8b -\x19\x08fy| \x89\xf7\x132\xedA\xaa\x8e\xca\x13l\xe4\x05e\xed \x96\xe2VJ\x86_\xd2\x7f\xe0\x87\x19OdW\x7f\x86 \x13\x87K\xed\xb71\x93\xe2\x01\x0c\x0d\xef8\x0f\xcc\xd0\xf0\xda\xaf\xe8\xe8\x0b\xbc\xc6\\\x03H'B_\x94c\xc6\x04IBR\xb8\x86%@\x99ky{\xe4\x04\xc1\xb6\x91\x08\x7f\x81\xe5\xe3B\x17\xb5\xd7\xbf\xcc\x13\xdc\xc6{\xd8Y\x84\x8fRI{\xdf\xc4\x9cS\x00\xe6NH\x10V\xa3$H\xba\xbe\xbdI\xfa]?\xbf\xc0Z\x9f\x91\x83'-\xef\x9f\xe1\x0b8\x1e\xaa\xce1G^\xd1.\xfe\x0474\x80`\x87\xd1\"\xb0M\x8e\x1b-\x82\xe0`\x0cT\xf4!\xc1\x80\xd8IR\xe0\n\xd8*\xc3\xb5\xf4\xfe\x18Sx\xe5\xb4\xfb9&\xd6+\xc6\xd9\xfbs\xda\x8f\x01\xe1Z\x02$\xb6\xf67\x04p[_\n\x12\xba\xc7o\xd7\x931~[y\x97\xdc\xc7k\xcdo\xa7\x81\x13f\x83,\xb1\x1fT\x00\x07<\xb5\x9f\x16\xa3\x07=\xa6#\xcd\x1dy\xc4\xce\xd8\xaah\xad\xdf6\xa0\x9c\xc3\xb5\xe8}\xcc\x92Vn\xe7~\xe0\xf7\x12?\x97s\xf9)\x16\x18JN\x946\x08\xd8\xae\x1ec\xa5\x81\xdf\x1e\x17\x1b\x8e\xa5h\xaeY\xe0\x07d\xc3\x13Mq\xf1\xa1_\xd1nA\xd8\x10\xc55\x00\xf3m\xaeI\x0e\xd1&W\xd4\xbe=\xc6\xd7&\xbcnCW\xc0tE\xf8\x06|&|i\xe7\x82\xa0\xdb\xb8[\xb0\x96~\x82'\xb0\xa2\"%\xc8IV\xdf y\xc9\x13\xe9R\xff'\xd8A\x8a\x1f\xb8\xa2\xc2\x11\xf2\xd9\x87\xad\xbf\x87\xe9\xd1\x8a\x80\xa4V\x10?\x88\xb9\x9b9:^\x86\xac\xfa\xca\x01${\xf0\x9d@^/S\xdeY\x14\xb03\xd7\xbe\x13\x04\xbe\xbc$T\x96G\xc2d\xcf\x81\x98\x80\xa5\xe6>\x88 \x98\x82\xf6\xf9Hu\xf5K|\xf3\xd0\xef\xfb\x10\xf8\xf8\x9f\xff\x06\xcf\xb3\xdf\xd7\x10Z)\xd0 \xdc\xd59\xcd\xe4\xb1\x9c\xd6\xd7\x00L\xe2\x8a\x01`5\xe2\x9c\x1f\x04\xdc\xc3l \x13\\(ec>X\xec\xea\xdf\x82\x9e\xfa\xb70 p\xc0B\x87\xc5\xaeb\x9e\x18\xeb\xfbA\x16J\xf4x\x0f\x9f\xd3~\x18 \x06\xf0\x9f\xc8\x96\x19\x96\x81\xf5\xb3\xbea\x19\xf8\x10\x9d\x8b\x92E\x10'\xee\x91=\x88\x12\xa7\x1e$\xfdX\x1eb\xc3\x87\x00\xc0\xbd\x00\xe6g\xe7\xa2<\xf1y\x92%p\x0bL\xe6\x14;I\xa6\xfd\x1e\xb0\x10\xdaO\x1cW\xba\xb3\x7fL&& \x92\xa9\xff\x04\xd3, \x12L\xfdc\xbc\x9f\x12rJV\xc2\xc4_\x82^\x96 <\x01 zE\x82\xb0\xe0.@\xf30\n\xb2 \x02\x04}aF$@\xd2\xe1\xfec\xac(I\x08T\xc2\xfb%A0\nl\xfa\x13\xa0\x93P\x0bK\x19\x02t\n\xa6\x85e` \x82\x06\xb1=W\x80\xbe\x03 l\x13\xe8'\x0e\xb0\x97\xb7\x08%HT\xe8\xc3\xbbX\x08?\xa7y\x05\xd9{\xa3\xfbb\x81p\xa0U\xaf\xff\x07\xf3\xe2\xf3\xca\x08\xfd9\xdevm\x9d\xfe\x1c\xb3\x17Y\xc3\x13\x12\x08^\xb8\x81\x81\xe0\x15\x18\xc0\xcd\xed\x13l\x970\xa2\xc9\x13L\xd6\x00$\xf9\xfb\x13L\x8e\x15\x0c\xe6\x8a\x91~\xc0S5Yz\xf3.`0\xc8'\x988\x9c\xd7\x1c\x0b\xab\x17\x03\x0d\xc0\xec\xf7\xbcTd\x1fb\xda4\x00? ,\xac\x0c\x065\xc5\xfd\x11l\xce\xdbXx:\xaf\xaeN0\xa7\x1e\xa8\xab\x13\x82qpc\x80\x9b\x19Hg\xcfgO\xc8\x1e\x83\xbc\xf2\x04s\xaeApK~\xc7\xd3\x1d\x84\xea\x00\x92\x05\n\x8b\x98a\x0b\x10\x10\x98\xec\xc5\x9ckud]\x96U}\xaf\x82\xcf\xb4\xaf\x01X\xc6\xf0G\x0eh^\xb6\xb6\x06~\xe8$\x87\xab\xf6\xd5\x199\x83@\x9d\xe8\xb71j\x0b`\xec@\xca$\xbaw#\x99\xc5\xb4\xf5)\xd6\xd4\xfd\x91\xb4<={\x80Y\xb8?\x8a\xa5\xc3\xec\x7f\xc2\xf8\xb4:\x8a\x03\x1f\xd4\x1f\xe2`\xe2\x87l\xc1v\xf9\xe5\x87\xae2\xb0\xbd\x8d\xafc\xcc\xde\xdd\xc3\x8a\xb7\x84\xa8\xd0\xfd\x0f\xb1\xbe\xec\x87*\x87\x06\x99\xd1\xaa\xc2\x12\x82q\xea;\xd9\x8d0s\x81\xc6<\xc0B\x9c\xca\x08\x0d\xb1\x1a\x98\x81V\x9c\x97,\x8d\xf2\xa4\xae\xd9Uy\x11\xc8M\xf6$\x92X\xc4\x0f\xb3\xc0I\x86\xd2 \xf7\x11\x16\xda\xfc0\xd3A\x14\x1fa!q5\x1c\xfb\xa9/\x1d\xac\xc0fb![\xba\x88\x89qz\x0bK\xe5\xab\x1b@I\xb0m\xd5\x8f@\xf4!X\xabo\xbc0\xc1\xf35\x00\xdf%\xac\x1a\xae\x86\xf9\x92o \xd8\xac\xb5\n'\xf9s\xcc\x07\xd5 \xff\x1c\x0b\x16~\xed*\xf9Z\xca\xfe\x18\xb3\xf9U\xcd\x15\xc9\xe12\\\x11k?\xdaC\x92\xe2|\xea\x87Z\xf0&49\xf5A\xc8}HF\x9d\xfa`#~\x88\xbd_%DZb\x1fb\xca$@c\xfb 2\xfb\x0e\xeb\xfcS\x9f\xe2\xcbp\xdf@\x08\xc1\xcc\xf7\x00-\xb0\xee\xe1+\xc0?`s\xe8\xaa\xbaq\xc1\xac\xdbW\xdf1V\\\xd4\")\x9e\xfa-\x0d\xc0\xeb\xa8l\x1b\x18%\xc0\xb4\xf1\xf7xm/j\x06\x86y\xff-\x0d\xc02\xca-E6\xff_L\x1d/\x1a4\xc5\x87\xe4\x96\x81`}\xea\xa2\xc1!,\x94\xde2\x10\x8c\x90\x17S\x9e\xc0d\xf0\xce\xde\xd2\x90\x7f\xc0\xf2\xc4E\xbdQ\xd8\xa6uKo\x14\xe6\xf8\xdfw\xe2X\x9e!|\xe6\xf64\x00\x930 \x90\x97\xbfX<\xf9\xbe1\x8abo\xa5=\x03\xc1\xab\xf9}\x18/\xe9\x1d>\xe3\xbe\xbf\xafw\x0b\x0b^{\x1a\x80\x91zo\x90@B\xa8O\xb1\x90\xf5}\x15\x0d\x8cwdOE\x03cn\xf5}\x85qX8\xd9S\xd64,\x7f|\xdf`\x03\xa6\xf1{\x06B\xea\x18l\xc0\x82\xd6\x9e\x86\xfc9&\x9b\xc1\xa2\xd6\\\xf0\"\xae\x99\xfc\x02\xf88\x04\x06\x82W8pJ1\x04\xf80\x06\xce q\xe0\x16\x13\xb3\xff5g\xd4\xf3$\xbe`\xdc\x0f\x0c\x04\xabOk*k\xe6\xaf\xb0\xf8\x14h\x00\xdeM\x01\x80\xfc\x8e\x98\x11\x05\xc6\xb3\xccR \xcc\x8exC\xd7\x1c\xf9\xe2\x9a\xbe\xc4\xc23\n\x1cH\xb8\xf61f\xf0kZ\xab\xc7RK\xa0\xed\x00\x98\x85\x98\x986\x1b@\xc6\xf6\xfd\x14\x8b\x18\x12\xd2\x97\xec\xe0}|\xf9 `\n\x84e#\x01\x02\xe1\x81\xa8\xa2\x02\x14\xc8\x95x\x07\xcfH\x06\xd6I\x81\xe5}\x8a)\x89\xb6\xe7|\x80y\x8f\x80e\xb2\xda;\x98\xcb\xa8\x1b\xd2'\xa4\xa7\xc5\xcc\xf1\xa1'\x8a'\x06\x84\x89z\xe0@D\xf2\x13,\xfe\x0b\x00\x98\xa8\xfe5\xb5\x18\x05g\xd5\xb2\xbf\x8f\xa9E\xd0\xd3\x10|\x98\x03\x9d\xe4\xef\xaf\xb0n\x10\xf4\x12\xb0:\xfc\x91\x0d \xea\\\xa7\x80=9\xecGX\xd1\x16\x904\x00D\xc6\x1c\x12`2\x8f\xd1#\xcc\xac\xd6\x8c\xb7!V\xd0\x03\x03\xc1B\xca\x9a!\xbd\xf8\xf8\x05\x06\x82\xa5\xa4\xc0\xe5\xb0\x13\xefb\xd6\x13\xb82\x16\x15\xaf\xc1\x1a\x90F\xb2\xa5\xf0\x99t\xec\xb9R@}\x1f\xb3\x89\xc0\xe48\xc4\x84QB\xc0\xe2AN\x9d\x97x\xda\xe1\x143\xf1\xc0K\xf2T\x03\xc9.x`\xd2x\x87l5\x18!1 \x06\xf2r\x1f\x9fT\xe9\xf2/\x88\xcfY\x81\x07\xe01GhP%.\x80\x90\x81\xb5\xb2\x0d\x89R\x8f\x8a\x85\xc9V\xb7\xec\xedN(\x89)\x80\"\x04\xb0,g\xba\xd1\xc7\x90\x1cj\xd1\xd2\x12\xf7\x03H\xc7J\x91C\xc0\xc1\xf9\xbf\xbc\x14x\x19\xa1\x94t\xd7.\xf9\x8dc\x0b\x85.Ur\x1b\xc7\xb6\x9ej\x11\xed5\x8ei\x87(u.\x88\xa0\x8dw\xb1\xe9VLZy\xe0\xeb,\x7f\xc4\x1f\xbeT\x06\x02|\xdf!\xe7\x85\xf73\xb3|\xa0\x1ec+5\x0d\xf8 FaQ\xa4j+$\xf6\x99\x80\x14!\xadT\x8b\xa4\xb5[-\xcb\xa8iA)r>t\xa9\xf4v\xee\x0f\x8a\x1e1\x11\xb6\x05'`\x8a[\x8a\x9e!\xa1\xa4\nV,\x8c\x0d\x83\xab\xd8\x82%\x1d1\xd4l\x98p^\x84\x98\xe1\xd9\xc8FJ)\x1f\x1f\xe0S_.\xa0\x90\xe9CL\x9c\xcbe\x8c}\xf2\x01\x16\x93D)\x08\x92)\x0d\x19\x0b,P\xa8:-|\xa7\x0feJ\xa1\x1aXG(\x17\xd0\x07\x00\xeb\x04(\xda\x03\xe3.\x8d\xf4 \x82\xd0\n8\\S\xfc\x80\x0bi\xba\x19p\xc1CD\x1a}\xf3C k\xc9'\x80\x9e\xbe\xb4\xee\xbb\xba\x99#\xf2\x9e\xf1 x\x8c\xd7+(\xf9\x04`\xedM\xc1\xe4\x1a<\xc1\xb4&\xe0\xa9\x9a\xacE\xce\xe0\xa9r\\x\x82o\xd4\x03\x9e\xa6\xa5\xab;,\x81\n\xb0\xb6\x13`\x0dZ\xc0\xf8m\xe5\xf7jYc\x01\xd5`\xb25kO\xaa*\x14\xa1U\xa2\x08\x12\xb0 \xe1\x8a\xeeHrA\x94\x80\"\x95\xb8\x0d&\xcdC$\xc7x\x00k\xd9\xb6|\x06\xd7\x92GD\x18\xd0~:T\x1eOJ\x04\x92X{\x12\xa5\xc0R\x01=1\xb4\x91\xec\x00\xa4\x00z\x93X>\x12E3\x1f\x10\xca\x98:Z\xf9\xc6\xf8\xb9\xa6\xafF\x88dh\x8c\x92X\x98ZS\xaa5\xa1\x95\xb5\xdfk\xa4\x81\xc08}ac\x88\x80\x80`J8vz\xbbg\xb3\xc7\xa4z\x82\x041Rc] B\x92vb\xf8\x8c\xc8\x8b\x06\x82\xed\xbbk;\x0b\xac\xf5]\xfcQ\"\x05\xe5\x9a\x99\xa5l\xa0\x9d\xce\x08\xdd6Ng\x84\x86d\xb5\x82\xa4T\x8c\x16l:QP\xa8K\x84=e\x9a\x9d\x7f@hQ\xc9U\x8d\x98v4K&t$K\xe0:\x97hK\x81\x0e1&\x89\xf3\x83,\xd1\xeerdRy\xe2\x19\xc3\x0e9\xb3ybB\x90\xc9\nV|\xd0>\xb2H\xf3\xda\x07\xcd\x02S\xb7\xfa\x1f\xe3\xdb+\x13.\x83g0r\x80\x16\xfc%\xd6\xec\x04\x80\xc3\xe3\x1b\x04v \xc4\x89\xf71\x91\x1e\xc1\xf7w\xf0\x94\n\xfeT\x032\x96\x0dl\x1e\x03\xb0a)Xa\x03\xb0\xb2y\xe0k\x92\x91\x93\xec\x01\xc5z\x0f\xdf\xfd\x8et\xb6\xc5g\x1fa\x99\xf9\x12H\xa0\xd8\xbc7\x82\xcf\x98\xbd\x8eL\xca*l\xe5\x18\xe9H\xe6{\x98\xb1\x8f\xb8\x93\xe6 \xf7\x8a\x07\xb6\xb0\xf2q\x89{~>2Ndoa\x82{\x89\x07\x81\x1f\xeak\x01l\xf4\xbe\xa4\xd5\x01l\x88\x1bi\x00>\xe2\xa3\xa1\xdc\x9c\xb7\xc9\xea\xfb\xae\x0c?\xfb\x18K:*-\xe8=l(\x19\xf9\x9e\xfd\x8d\xa2\x91\xef)\xba\xf0\x14\x13\xd6\x91\xef\xd5\xa4\xcf-\xb2\xc0`\xb2.!\xf0\xc6\x16^\x1b \x82\xd1a \x0e@R]\xf9\x08/\x81\xcc\xc9\xaa\x13\xaf\xde\xc3\x8cq\x14\xb8\x90\xad\x10\xdb\x8fG\x01\xb3\xb4g\x1e\x1a\xa3\xb0\x0c\x1e9\xf8%\xa6M\x12\x02f\x85:\x18\xf8\xfc`\x1f\xbb\xb0'\x9d\x8c?\xc6\xd4:,R\xcc\xd3\xb1\x97r\xc9S\xa0\xce$\x89\x97}]\xdf\xe5|\x86\xb7*4\x10lz_\xd7w9\x9fa\xae\x11\x1a\x08\x96:C\x93r\x96\xf6S\xce9k\x19\xb9Jt\x89Q|\x1d\xc88\xd6\x14B\xf8\x8c\x15\xca\xd0Pw|\xbaT\x82_\xb2\xd4\\{F\xbd\x8fYU\xc8\xf5\xdd+V*D% y\xc7\nQ\xaa\x02\x85\x99\x88g2\xfdu>p2\x7f\xcc\x11\x1fy\x13KW\xba\xdc\xce\xd0w\xf7\xa6*\x16N.u\x99'\x87\xcd%Ko\xf5`KS\xc8S\xaer\"a[AX\x04l[&\x9cf\xdc\xa3A%$\x82\x02\n\x96-\x7fD\xde]\xe7\xfb\xca1\xf9\x07!\x19\x82 \xaf&\xf4\x86\x17\xf1\xd5\x18\xb6\xae\xf9.6\xb8\x85\x1a\x80\x87\x19\xea\x988\x8a\xd9*,\x0e;\x16\x86:\xce\xcd\x06\xb8]\xdfX9\xd6\xcd\x06O\xeb@:4\xccRI\xef\x13\x96\x1aB\x1d\xd6b!\xc9\x03\x00a\xb95\xd4\xc6[\x028\x9f\x01\x06=\xa5\x030\xd1\x0eX\xb7\x0cM\xb8\x03!\xacCexx\x8a\xd5\xbbPj\x0b\xf7\x08\x0e\xc3Cq\x0f1\xf3\x0b}\x10>\x1eb\xa9/\x04\x8c'\x0d\xad+\x93'V\x11Be\xf2\xc4\xea^h|8\xb0\xba\x19\x1a'\x0eZGI)XD\x0e\xf5E2]Du\x97\x8c\xa5\xb5\xb0z\x13L\xc7P\xb9\n&\x03\xb1\xdc \x92M\xb2\\!\x92\xed\xd278dx\xc5\x15\x8emJ\xe5[\x1c\x1b\x19jM\xdbr\x0e@\x1b\xa3\xddh\xb5\xf5!&W\xa1\xd1[\x1fbkZ\xb8\xa6\xce\xc8\x13:8-\xc1c6\xb5\x1e\x9dM\xb8#Y\xd8[\x98\xbb\xadG\xa1\x04\xfa\xe1@\x13w\"l\xac\xebX\x11\"\x9d\x18\x01\x16K\xec\xfam62|\xd0\n\xf0\xe7\xf5(\xab&\x95\xc7\x86\xc9_\x01.\x06\x81)\x7fQ\x06\xc5b\xda\x86b\xe3\x9d\x0d\xe5\x0c\xf7\xc4V\x9e\xa2\x08\x0e\xcclh\xadX&\xcc2\xd6\xa3\x8c\x86\xe2\xd8ZB\xf18\x14\xe1\xa3L\xb9B\x13I\\@\x8c/\xb4\xbd\xa2r\x87\xb6\x03\xc7N}\xbb\xf0\x10\xf4C\xac\xd9\x02\x0cr\x98c\xe3\xd5z\x94aO\x00r\xe8Q\x19\xe3\x0c`[\x19\xabG\x00\xa1\x15\xb2`\x0d\x8dS\xb0by1\xd5U\x05\xca\xc8c\x1dHY\xea\xb2\x0f\x95^\xac\xd6\x95+p\x06\x93\xd7\xf5(\xab\x93\x07\x9f\xfc+[sT(|\xf2\xd7\xb6\xadV\xa2\x00\xf6\xc8\x93\x10\x85\x04v\x18 \x01\xd6\xa9\x01\x06H\x805\x8f\xf5(\xdbL\xb8\xcb=\xf5\xd2\x0b\xb6\xf3\x95\xe0f\xad\x9e\xfc\x1b\xdb\xe4t\xb1\xea\xba>\xb4P\xac->\xe6I\xca\xcbD\x0fOG\x94\x92\x195\xcb\xc8IdlTHc\xa7EOA%\x8b\xe1Y\xa86\xe4\xc1\xd9\xce{*\xe7\xdb\x03+\xb6\x97K\x15\xcdYX\x84.\x18\x8b9C\x83\xd6\x01V\xcb\x15Mb\xd3\x97(Z\x8c\xedO(k7\x05\n\xb7\x1c\xa2#\x8b\"\xae\xcb\xb9\x07\xbb\x8e\x0d\xfa%x\xb1\xeb\xd4XQ*\x86v\x1d\x1b\x1aK%\x8b\xf3\xf4\x1f\xed\x0d\x96\x16\xea\xc75\xb3Ck\xf4\xc0\xc23\x8bn,\x93\x93\xc0\x82\xccXx\xa2,Qeg\xc4Z\xa4J\x15=Y\x86\x81\x99?\xd1\xd6\xe3\x1a\xa9@\x00\x9c P \xf1mPH\xcd\xf1\xf4o\xe9+\xb4\xa1\x8e\x80\xbbG\xa5\x810\x8e\x02\x1d\\\x88M\xc9!?}\xc7Z &Id\xcc4\x8f\x1b\x88\xb2\x02\xabI\xd6T\xd6\x93\xb4\xf4\x9b\xa9|;D\xc8\xd7qx\x9f\x10\x8b\x96\x81\x10;T\xa6\xbc\xd1h/\xe8yr\xaa\xe2\x96K\xc0d\xa8\xaeK\x9e/\xa7\x07\xbfRD\xb5C\x04\x0dy\xa5A\xec\xc3\xf2+1\x0f\xcb,\x9a\xbfG\xbfrH\xda\xf86\xbe\x13\x0es\x9d-\x96\xd8\xb3\xc7\xfa='\xcb.^^\xd6\xcf\x14\x12+\xd8e\xf3\x82!\xb1\x18\x8cM-B\xe6\xc6\xa6\x16Y\xc6\xb1N\xbbe\x19\xc7\x18\xf2\xcf\xd8 \x17t\xb8\n9\xbc\xe3\"\xfe\x1d\xdf\\\x85cm\xcbz\x1f\xdb\xe9\xc3\xb1\x8ee\xb0\xf5\x06. v\x88\xb9\xc4\xb7\x815\x0b{\x9f\xd0\xdd\xb1\xe1\n\x0f\xfe\x9d\xad\xa6~[\xf8?X\x80\xfb\xc6\xe8Oh\xda\xbe\xe6\x99\x04\x15\xf65\xcf\xb4B\x14W\xa3\xb0P\x9b\xc7\xf1\xd5\xe1\x86I\x11\x81\xef*\"\x03\xc1W\x81Q\xdd\xf3\x99\x91\xba\xac%\xeffn\xe8\xf4\x11XF\x894\x00kc*\\\x1b\xef=Dk\xff=\xd6\x89\xa2\xda\x1797\xf4\x9bM\x9f\xe1k\xed\xc8@05\x8a\xe0!\x98g\x1fa\x9a\x13\xe9\xd7\xce\xb0\x93V\xe4\xa5\x91\n{\xc2\x96\xdd\x8d\x15H\xbd\xf0\x19\xde\xff\x88+\x00Y\xf8\xbeZ\xc6G\xd8\x95iC\x1b\xfeI[\x1a\x80\x0f\xa6\nV\xff5\xde\xa9\x0d\x93\xc4\x824e \xd8\xa4\x1d\x81\xb1\xfdC\xcc\xba\"\x9d\xa8\xe7\x116\xc3DC\x81\xfd\x9fc9&\xaa{\xa112\xa6hl\x06\x8f\x02\xbd&d\xeb\x03\xf3(\xe1#\xec\xb4\x13\xe9\xc4\x12o\xd2Z0\x17,\xcbn(O\x98\xcf\xb0\n\x1bi\x006]o\x8c\xf8\xc0\xb1\xceR\x01~\x83\x19\xe8\x86\xf4\x8f\x90\xe9\xa7\xb1M3*@x\xef#%R=\xc2\x86\x9fhT\xfb.\xec\x861\x9e\xe2+\xd2\xc8@\xb0\n`\\)\xb1\xf1i#\xe6\xa1\xf5\xc5U|\xbdo\n\x16E\xb0_Z\x14sx\xf0\xf0\x11\x96\x11\x8c\xef%y\xc5vC\x0e\xeb1\xa1 N\xe2k\xbf\xc8(\x17\x04)\xc0\xb3\xf01\xa6\x14Q\xe2\x81\xb5\xe7mL\x8b$\x04R\x8a\xd8`2\x13\x17\x16>\xa2\xc4\x13\xb8\xff1A\xe4\xc4\x1f\xa8\xec$d#\x13\xf5b\"\xde\xc6(I\x83\x08D\xb9\xc7\xf8>7J$\xa9zLH\xb1\xfd%\xe1\x0d\xa3\\\x90\x01k\xc7\x0fB\x89u\x8a\xa4O\xc8.\x1a\x08!\x94\xeau\x8f\x07\xb8\xca\x86\x11\xf4\xf0\xf6F\x06\x82\xa9\xc8F\xe1s\x8bq\xb2p\xc7%\x8f\x1a\x03\xc8\x81zx\xa97T\xb6\x06\xb2\xd2\xea;\xd9\x9a\xb1\"q\xefbanc\xccu|\x11!2\x12\xa6\x82k\x9f\xfd\x19fe\x1a\xaa\xc2 \xff\x94\xac\xfb\x98'\x9bN\xc2\xc3l\xc8S\xb86\xfc3|\xd4\xb42\x85M\x06B\xd7\x13\xd8\x87\xe7Q\xd1\x01-\x95\x94\xb8\xf2\x14s\xfc\x92}\x82B\x94m\x02\x016\x9d\xc4<\xcfF\x81\xc0\xc61\xf9\x8b\xe13&}1O\\\xc91\xfe\x19\x05\xf82\x1f\xca\x0c\x05\x8c \xd6\xf3Mlt\xd6\x94\xe7\x01\x99>O2\x1eJ\x81\xecM\xac\x85lj\xfe\x8ayu\xac\x01XX\xde\x84\xa7\xd2\xb1\x96\x1b\xc3S\xe9\x98\x1c\xc7Cxu\x00\x1f\x8ax\xa8^q\xa6\xfeX\xf1P=\x17\xfd\x17\xf8&tS\xf6\x8c\xe9z,;\xc6\xfc.\xf63wX\x9b';\x86Q\xe1S\x12\x07N\x08\xef\xc7\x93\xa4i\x00\x82\x84jx\\\x02\x06i\xb7-\xd5$\xd1?j\xf9\xec(\xc6\xff\x11\x16\x92\x05\x104\x7f|\xb2\x04D\xd7\xc2\xa6\x04\x01\xf3\xa4\x9aE\xde\x81\x93 p\xf3#\xb8\x11\xe4\xe0\xd3\xfa\x18\x0bE\x9bA\x9e\xea\x87\xd9?\xc6h#\xaa\x8d\xc2:\x88:l\x1f\x11\x1c \xf24\xdb\x97c\xfc\x08\x8b\xeb\xf1\xc8\xd6\xdaf\x04\xc9\xa8\xc4\n\xcba\x92\xcc\x83\xb1\x90\xb9\xb4\xa1\x10c\xd9\xa6\xbe|\xc5bml\xa4\x04l\xbf\x8a\xa3\\>\xf6\xf81\xde\x95M\xb9\xecO0\xd3\x05S\xe4}\xcc\x0d\xe3DE\x18a\xc2nL\x94\xf7\xb1<\x1d\xc3[\xf5O\xc8y\xd0\x96K\xfa\xdd\xad\xe9\x9b\xbb\xa50&:\x02\xee\xaaw\x83\xad\xe3(\xdf\xb3\x90\xb6-\x97,5%\xaa\x96\xf6\xda^\n\xab4f2e\xe3\xab\x05T\x8e\xd4\xc2\xb2\x96\x84+;\xce\x13\xccu%P\x87Ya\xe9J\x00\xb5\xc5\x10\x0fh3Q\x16\xc37\xe9\x16i\x08>E\x12\x92\xdaq0\xd1Qht\xf8p\xc1j\x19z\xc3\xc0\xd5S\xed\x98\x02m\x96\x1ej'\xd4)\x89\xfaN\xa0\x04\x00\xac\xb3\x08\xa0V3\xde\xc5\xca\x94\x00\xa698\\\xbfKx\x87z\x7f\xed\x1e\x96D7\x93(\x8e\x12\x9dI\xed\x1e\xc6\xcc\x02\xac\x12\xb5\xe1\xfa\xa2a\xf0\x9b\xb7\x80\xea\xb6-N\xf2\x04\x04\x83\x07\x98en\x1a\xa1\x11\xdb\xc6bc\x91\xc6\x86\xc9Mx\x95\x87\xac\xbf\xfc\xfc\x1b,\x96\xc6y\xe8*\x13\x17\x06\xbd\xae9,&\xd7\xb75\x00\xef\xc8\xed\xbal\x8b\xafk:\x87\xcd\x13\xb7\x0d\x9d\xc3\xec\xe2\xb6\xc1\xd9\xb7\xb0\x80\xf9\xbaY\x15\xact\xdf6\xab\x82\xf9\xfc\xed\xdc\xc9x\x12\xfa*3\x01\xc9\x8c*\xe0z\xf4\x98\xeb\xea\xd8\x94\xd7l\xdf\x15\x91\xc2\x02\xd5\xeb\xbb\x1b;\x0b\xec\xdb\xado\xe3*Qf\xf9\x9c\x98\x84KX\x9b\xd0B\xec\xbd\xbf\xfd;\xcc{\xb6\x8c/5\xde\xa0\xc4@0\xc3I\x1c\x0f\x12\x90\xde\xc3;\x91\x94\xb34a\xfa\xb1\xa5c;1\x1a&\x1a\x80u\xf0\xc4\xa4U\xc2'S@\xe4\x94\x1ea^\x9f\x14 \x97hs*s\x12fo[Z\xd9\xc4R\x97\xb9\xfc\xa2\xfd\xab\x1a6\x00\x10\xbc\x0f0]KLR%:\xe6\"\xa9\x12\x19Bq\x97f\x81\xa8JX\x84J\x8atKXQL\x8atK\x18\xf1\x13\x93n\xe9\x03L\x0f\x92R\xba%\xac\xe9l\x99tK\xefc\xa4O\x8aLLX\xd2(]\x03\x92E7 \x97\xb0\xc2\x94\x14\xb9\x98(\xeae>\x10M\xac5IH\xa8\xfd\xe7q\xbd-\x93\x8d [\x18\x13\x03\xc1\x1c%1y\x9a0\x05HL\x9e&\xb2[:O\xd3]\x1b@\xd4\xb9A\x01*O\x13\xa6\x84I)O\x13\x16\xd3\x93R\x9e&<\xa3-\xe3\xa7\x8f\x15\xfb\xc4@0\x03\xdf2~\xfads\x0d\x04\xd3\xd6\xc4\xe4i\xc2\xc6\xb3\x04\xf24\xe15\xd8\x02\xcd\x91\xe0>8\xc3b\xad'\xd1y\x9a0kM\xbc\xc0\xa4\\\"\x87\xdf\xe4p\"\xf8V\xe4p\xa2 \x15\x17Jh\x19\xc8\xe9\x04?9\xf0t+@g\xc9%\xd4\x99;\x81\xc9\x92k\xab\x08\x88K\xc6\xc6A\xdey\x0f\xeb\xae[+\xe7\x05\x91\xc3|5\x81W\xfe\xf1g\x8b\xff\x0fvV\xd6E\xd03r5\xc5vcT\x90<\xb7\x9a\x14\x890\xb0=\")\x12a\x90\xe6U\x0eh\xb2BZ\x90 \xdd\xe8\xc4\x16\xf8\x16\xdb\x84'\x93\x17\x7f\x13\x9d\xd8\xe2\xa7\x04\xe7\x8a\xc4\x16\x98ln\xc98\xba\xcf\xb1\x8e\x95\xc8\xcf\xbf\xa1]DR+'\x8cX\xc6\x88\xe3|]\x18\x8bQ$9\xe6>\xc8}\x820\xa7\xaa\xf7\x84\xb5v%g\x17fTE\x89J\xd4\xfbO\xf1\xfd_\xd1\x91I\xda\x85\xe9\xbfl\xaa\x9c\xb5\x0b\x93\nY\x80\xa6\xed\xc2*\xb5*\x86\xf3v\xe1\xd3b\x8a\x95\x12wa\xb3\x16*\xa3\xf3\x0ea\xf1G\x16;W\x8b\xa7\xe5\x04V:\xc2\x95\"Z\xa9\x10\xf8\x06P\x8c\x13EP\xf6.\xeb:\x97\xf2\x80A)\xc2.D)\x9c{\x8bPf\x9ff\xd4\xb2.\xa2N\x97\x85em\x0d,\xb0\x13[F,\xcfr\x13Z(\x8a\xa0\x8cYx:\xc4\x17\xf1\x01\xa1\xceVG\xc4\xa6B\x85\xf7\x1a\x96\xdad1\x925\x0bK\x04\xaaTur\x98R\xa9B\xa5\xa4WX\x8b\xab\x94\xd0\xf8\x87\x05s\x94\xd3\x8c N \xae\x9b\xc0\xbak\x02\x87\xee\xd7D\x88\xf2\xd3\xea\x83\x8d\xa4\xa2I\xa6CP1\xd0\xe9 \x08\xfa\x05\x90\xf3\x81HQEf\x1bL\x0c\x93jf\x1b\x02\xd6\x81\x0cO \x933 d0WLL\x02\x19\xbc\xe8\x89I \x83iKbn\xd3\xb0&\xb8\xa5uQ\xc2\x95\x8d.J\x04\xde\"/ \x1duqGB\xf0/\xcaC\xaf\x94\xe0\xfe\x03\xac\xde'0\xc6\x8e\xe53\xdc\xf8>\"\x9a]\\r;$<\xc2d\x03!\x04\x19\x85\xf0\x90\xb3[d\xea\xc0\x06\xb5-};E\xebh]\x1b\xfb\xc6l)\xc9\x8b\xec}\xedw\x99\\\x83\x08\xd1&\xb9\x06\x16l\x93\"\xb9\x06\x01\x15\xa9)\x082\x17t \xc7ni\xdf\xc3\xf7\xb0\xa5\xab\xe4db\x81H\xc2zE:\xe2\xc5\x93\xf7d\xbc\xb5\xe8:\xf2a0\xefR\x88\xdc\xc9'd'G*\xaf<65\x08\x00\x84\xaa\xfd\x0d\xcd\x02\xb5\xbdqn\x07\xce*\xa9\x16\xf538\xadX\x9c\x01G\x9f\xe3\xf4\xab$\xe3\x1fb!_\x00\xd4E\x1aa!F\xf0\xc5rQj d\xc9bG]\xc1\xfe\x92\xa0\x99\x04\xe9w\xfd,\xd0\xc4z\xf0\xd3\xdbJ\x96x@\x98\x9f\x80\x80\xaf\xd1\x9f\xd3\xb5Ko\xab\xdc!\x0f\xb0\xb0,!P\xefg\x965\xbf\xad\xfcg\x88\xd4t[\x076`\xb5\xa7\x08\x94x@(\xce\xedR\xf8\x82\xb5^\xe1\xd7o\xab\x0b3 \xb4\xd4D_<\xc04P\x82L \\\x0dPuH\xebJK\xd9{\x98\xd5\x97^\xae'R@=\x08j\xe1g\xa8\xc8.\xd2p\xc0\x86\x02\x85R\x8f\x17\xcb\x16\x06\xd8X\xa4h\x8a\xb0\x11Yn7\xd4#\xa6\xf8\x93;p\x83L\x1e\xf2Oo\xe75\x80\xda\xeb\xa5msk\x89u\xc8\xd4hR\x98#\xa7\x0d\x02I\x03mJ35\xee\x87\x98jogp\xfa\x08 U\x80\xbf\xb0\x01d[\x7fAD\xc6,q\x04\x9f\xe6q\xea\x07r \x7f\x83\x95$]D9_as\\\x9a%\xd2\xeeE\xb2\xdfm\xc3\x01|H\xf0Z\x1dL\xc2r\xf3\x9e~\xb3\x9b\xa8\x0e&\x16\x89\x02\xe0d\x91\x19\xe7=\x9d\xaa\xe7)\xe1\xbayo\x94\x83\x07\xf3S\"[\xe7=\x90\xfa\x9fb\xbb\xa2\x80@_\x84\xc0\xe6=\xcdE\x9f`\xb2\x9c\xe6=\xc3E\xb1^Z\x1c#\xdb\x1a\x990*+H\x11\x05\xcb\xb4\xcb\x11T\xd6\x0e\x8b\xb3d\xaf\xad\x12\n\xdb\xa6 \xd0\xdbu\xeb\xa3\xfd\x1f\xb1-A\x80`\xd3\x9f\x12\xec\x11 \xc8\xf2F8\x86\n\xf6\xa2\xfaj\xee\x96]\x8f\xb0\xd6*\xc0e\xd7#\x8cL\xe5`_\xd2\xb6%\xd2\xb7\xa6\x04r=\xaa\xeb\xa5\x14\xe1k\x19\xa7\x0eY\xb3\x80\xca\xaeGD5\x15p\xedzD\xd4S\x01\xacUPs\xb7^\x0b\xcd\xdd\xe1\xce\xd0\xb1_Bm\xc3e\xd2=\xc2\xf7j\xbf\x83!\xf0\x97\x98\xb8n\xc3v?\xa4\x15\x80}\xd2\xd3\x1a\xcf \xf2\x82OO\x9a\xc7\xf3\xe2;\x91M\xf3\xf8\x84\xf8N\x84\xc7<\xd6\xe4\x05[ \x05H#(\x11XM\x84 \x05\x009\xa0\xd8\x1e\x1b\xd2\x83\x05\xb8j@w\x0d\xb08\xa0\x96\xa6\x87\xca7\xfcWXQ\x9405 |!\x9c\xe6\xb1I\xdbJOSl\xa8!\xa55\xb1\xa2\x86Dp\xcdcE\x0d)\x1d\x8855|J\xc45#\xed\xd8\xb6\xbfn]*b\x90eI\xca\xe1\x94V\xa8\xa6h\x96\xa1\x96)\x9ae\x8e\x9a\xa2\x11\x9e\x9e\xc7z\xad\x89\xc0!@@\xd1\x08\xbb/b\xd6\x88\x19\xc6\xc4\xacachjb\xd6\xac\x90\x9a\xbc\xd7\xe9~\xa8\x8d'D\xba\xb9\x03\x91S\x9f`=q\xc7\x113\xfaA\x86>gN2\x80\x9dy\x17Oh\xc7\x91!\x9aX\xaf\xc8\xe4\xe7\xdf`\xe4\xcf\x94\x9d\x9f\xf8\xea\xef\x18k\"i\xc9@\xb0\xa6\xb1cl\x80\xd8\xfe\x92\x19\x08\x96\xa9\x94zF+H\xdd\x0c#\xbf\xce\x9c\xfcclw\xcdx\xa0\xbcb\xdf\xc5\xeclG\xdb\x8b\xf0 \xcc4\x00\xdb\xcd\xb3!O\xf8I\xd1\xd8=\xb2,\x02\xd4\x8f@b'\xd0\xac\x11\xba3\xe4\xf0\x06*\xa6g\x99\x06`\xb6)\x01\xe9\xa1\xc0\xf7\xdf\xe0\xc3)ac;\xc4w\xf7J\x197\xf1A\x91\xf0:cJ5\x03\xe2[\xbf\xa2/\xf5gC?T\x9e\x8d\x98\xdeU\xb3\x1dbh6\xdcS\xb1\xbdtD\xf5\xe3\xb9\xb0\xb1\xb5.N\x066\xc7d\xc3(\x11X\xf8 \xe6\x1c\x86\xbb\x93\xb6t<\xce\xaf\xb1%\x1a\xa5\xdb\xc0\xc4\xce\x92k\x03\x8bq(\xd1\x06\x99\xa0\xba!\xf9\x84\xe0\xa0\x00\x80\xec\x8d\x15z\x00\x01\xc1\xf8\x88\xa0\xa8\x00\xc2\xbb\xb9XP\xc9\xea\x1e\xe0\xce\"\x0e>B\xd8n\x99\x81\xd7\xee\x03r\xd2\xa3\xb8\x07\xe7\xed],\xd0dQ\xac\xd3\x18\xe3\xa1\xed\x18\xdb\x06\xa6\xed\x99\x81`\xca! *d\xe3)6\x1bdQ\n\xc3\xc6rSVx_\x93\xa3\xb6\xb5\xb8,\x99\xe4\xdb\x84\xb0$\x0e\xec\x91\x05R\\\x9f\xbf\x87\x15.\x0d\xd4\xde\x0b\xefaA\x0d\xc7\xee\x93\xac\xea4t\x9f\xa4W\xd7E@F\xc6HJ\xe2\xfa\xc9\xa5\x9a%\xac\x9f\\\xafe\x89zU\xe5\xd9/\xb0IL_\xc9\xd9z6\xb6\xc1\x8f\xb0\xdc\xbb\x93\xf8q\xc0\x97\xeb\xe8\xb2\x80\xaa\x9a\x96\xe1\x02\xea\x7f\x88]\x06\xb3\xc4\xcf\xd4\xd6~\x84e\xa3,\x89\xf9\x1d\xe5F\xf5gx\x0fw\x8c-\x00k\xbe\x99\xb1\x05\x10\xa2\xa5nz0\xfb\xcf\xd4U\x0f\x96_v\xb4\xf9\x9f\xa0\xb7\xb6\xff\xe3E\xd81\xcf\x0f\xd0>4\x04_\xc0d\xfb>\\\x8c\xdc'\xdb\xb4\x1f\x0d\xb9\xe3U\xf3K\x12\xea\x08\x85\x90w\x13&1\xbb& \x1e\x1f\xba\xdc@\xf0~\xefj\xd1\x07\x8b*\xb9\x96\x960?\xcau\x0d\x0c\x10M\xe9\x00\xfb\x0f\xf0\xb6\xec\xf6\xd4\x93\xca\xf8\xa67W\x80\x7f\xc0s\xde\xed%\\\xc6y\x7f\x86\x97,7\x10L\x13wu\xb4>\xde\xb3\\\x030\xfe\xed\xc2\xa8\xb0\x1c\x93\xc3\x98\xf0\xa9\xcf=\xed:\x809\xc6\xae \xd6\xc7\x04<7\x10LZs\xe3\xca\x89M]y\xe1?\x88\xf9\xe1\xae\x16s\xb0\xd8\x91k\x00V\xd7vM\xc0<\x16as\x03\xc1\x879\xd7\x9e\x85da\x86N\x02\xeen\x98d\xe6& -\x1ern\xde\xc5\xc2\xdaJ.\xdf\xa7\x12\xa0w1\x95\xca\xcbOWY\x80*6\xe5]l\x1e\xcd\xcdC\x18X\xfc\xda\xd5\x11\xf2X\\\xcf5\x00\xbb\xedC\xb0\xed\xc7\x98\xc1\xee\x86\x9e\x8e\xa9\xc5\xef\xe5\x00\xc8\x84\xd4\xe2Ce\xc0:\xa6\x16\xd3sY\x00\x07\xd5\xe2{(c\x8a}\x88\xf1SBt\xb6\xff\x07\xf8\xa8\xed\xaad\x0b\x9fa\x0c\xc95\x00k\xf4\xbb\x86\xc5c\xcd-7\x10L\x04\x9b.\x1cw\xe3\xc2\xb9\x86\xd0\x95\x02f\xa9Wv\xda|\x1f\xdb\x8c\x15\xb8r'KOh\\\xbd\xb3\xc5\x8a\xc5n,\xa4\x81b|\x18\x9eW\xe1\x96\xfa\xd8+\x98\x9c\xeaX91\x9aw?\xc8\x19\xd2%\x8a\xa7\xa4\xc8a\x8ak\xb77\x8e\xf1[MX\x9b\x94E\xd0\xad1\x96awU\x08\x14^\xe4\\}\xc7\xeb*\xbe\x0fm\x15v\x8d\xc1\xfbs, \xe6\x85-\x9cn\x93v\xbf\xc4\x95$\xa4\x187mSa\x10x\x7fb\x99=O\x0c\xa9\xc1\xe7)/?\x02e\x01jRC\x16\\9\x19~F6Z\x03\xb0\xd8\x92k\x0f\xaa_`\x82\xbbkD\x1d\xc2?\x8c\xa8\x83U\xb7\xdc\xbc<\x84\xeb\xecj\xdd\xe83L\xbbr\x03\xc1\xf2w\xae\x9d\xbb0M\xca\x8d\x0b\x17\x96ps-\x0b\x90\xd5\xdeUy\n\x08\xe1V\xdf\xb1.\x97\xef\x1ba\xfd\x11\x96\x9d\xc6N8\x80;\xc8G\xb8\xb9\xb1\x934\\\xab\x8c\x9dD(\xce\xd2c\x01\xaf\xd0\xd8I\xc2H\xe8\xbe\xf0\x9a\x06\xc6\xc2\xb1\x93\xd4\\\xc6\x08\x88o\x0b:\x17\x80\xfa\xb8\xc6\xb1\x16\xa7,\xed%Vz\"\x00\xe0`\x8f\xe5\x86\xb1\x93\x18O\x0clR\x11\xb0\xea\x1d\x03\xbd\xd2-\x97Q7\x0d5\x85*\xa6\xbd\xe62\xca\xc0g-\xa4-\"\xc4\xb6!`H\xd3\"\xaf\x03\x97\xca\x18\xaaH\xfc\xa1/+\xcd\xfa)f\xe1c\xc53\x9e\xe2\x83 \x002\x8a\xef)>\x08\x97A$\xc4\xe4l\x0c\x9f\xf1\xf0\x8a$f\xb8\xeb\"\x87\x19\xee\xa1HaFFe\xea`]H\xb6&%\xaf\xa7\x98\xe3^V\x9e\x9c\xf8\xa6m\x0c\xdfI\xea\x991\xe7j\xb9\x1e`qx\xcc\xb9\xd2W\xb1\n1\xe6A\xe0\xc3\xbd\x02&w\x97y\xa2\xda{\x93\x1c\n\x0d\xfa\x11\xad\x93\xd5\xd5\xc8j\xca\x97\x13\x9bb\xb9T\xc3\xd5\x13\x17u\xd5\xb7y\xec$\x8e\xf2+\xff+,B\xebR\x85\xe5\x07#3}\x04\x04\x13\xe5\xcbZ\x0c\xc7\xc2\xf6X\x030\xee\x8e\xb5\xc4JQ\xdf\xe4\x8e\xb4dz\x1c\x9b\x9c\x8b\x96\x0c\x89\x97\x8dx\x86\x95\xf1\xb1\x81\x10:[\x1b\xef=6o\x17\x92sg\xd8\x16!R\x86ma\xc5z\\\xba\x01\xb6\x90\x8b\xd2-\xb0\x15j\xeeKj\xa0\xbc\x8eZ].\x0e\x17\xd6\x00\xc6w\xfc\xc1\x1dG\xb2\x82G\x18\xf1\xafh\xbfV\xcc\xfd\xf65\x00\xf3\x9d}\xee\xa9\xf3\xf0\x18+\x00W\xb8\x07Q\xbd\x0f\xf1\xe8\xf65\xe4\x1e\xde\x17 \x81C\x89qj\x9f\xfb*[\xcc\xdb\x18\x97\xafht\xc3\xf3\xd9\xd7\x00<\x9f+\x063\xb0\xa0\xb3o \x98\x94\xec\xdb;\xdfO\xac\xa7g?\xe1N6\xb4\x82\xae\x18D\xc2\x87`\xdf \x12\xd6A\x0e\x94'\xd4C\xcc\x04\x0f\xd4\xce<\xfb\x05\x16\xc0\x0e\x94\x13\x14\xd1\x9c\x0e<-\xfe\xe0k\xe67\xf4za\x9b\xc2\x81\x06\xe0\xfd?\xd0\x0f\xb5\x90\xb7o\x0f\xb4\x8eL\x9e\xbb}Cf#\xc06\x90\x03\xf9\x15\xab\x00\x07:\xbd$y\xcb\xf7@\xdfA\x927|\x0f\xd4\xf3d\xe4!\xdd\x03\xfd\xe2\x0bf\x05\x07:\x99\xe0Gx\xaf\xde0\xe8\x80\x95\xef\x03\x03\xc1,\xef\xa0\x88\x0d\xc1l\xea 2\xd6A\xb2\x91:<\x9d\xbc\xdc{\xa0}>\xc8\x83\xbdo\x18L\xc2\xc4\xea\xc0`\x12&\x8a\x07\xc6;\xee#l\x1f<0\n\xd7G\xf8\xb6\xed\xc0\x88\xcc\xa4\xa7q\x0dK>\xd8\xaf%\x00W\x8d\x8d\x0e\x93\xdfC\x03\xc1\xb8yu\x11\x84\x12\x8c\xe6\x87\x0e\xd8\xaf\xf0\xfe\\\xd5$\x0b/\xda\xa1\x06`\xbc\xbc\n\x1d`\xd9\xe6\x10\xda\xc7\xa4\xfd\x90\xcbdBX5\xbb\xaaO\n\x96\xdf\x0f5\x00\x8f\xe7\xea*\xf4\x8b\xef\xa2\x0f}\xe8\x18+\xadW\x0d\xe2a?\x9fC\x03\xc1D\xff\xaaA\x14L \x0f\x0d\xa2`JxU\xd9\x0b\xb1\x08t\xa8\x0c\x86\xa4<\xe8;\x9f\xe1\x83z\xa8\xf4 l\x00\xb8fBQ0\xc2\xdf1\x10LT\xae\x99\x1b\\\x8c\x1ew\x0c\x04\x93\x90k0\x0d\xbc\x8cw\xe03F\x82k\xea\xe5vL\"\xee\xa8\xef\x98\xa6\xdc\xe1\\?\xe2\x89\x19\xc65\x9eDW|/\x1b\xd6?\xa3vM]\x9fb\xc9\xf0\x8e\xfa\x8eq\xe5\x9a\n\x9b\xc6]\xdd\xd1\xc8E\xa6\xa3,\xfe\xa4\x030\xf8\xff=\xee\xe0\x8e?0!c\xf8l^\xd3ar\xf8\xb6\xed\x8e\xc1;|v\xae\x19\xbc\xc3D\xfa\x8e\xc1;|p\xef\xec\xdf\x92k\x85 \xd7\x9d\xfd\x10\x00\xef\xb6\xcc\xf7\xbb\xf2\xaf\xbb]\xd6\xcfC\xe9g\xda\xe6]\x96uY\xd8a\x7fd\n\xb5\xf2\x94\xb34K|7k\xbdj\xbe\x8e\x9d\x84%\xec\x0c\x0b\xdb'\xe7^\xe9T\xbb\x8a\xe4\xf7\xf9\xeftf\xf2\x90\xa7\xae\x13\xf3K^Q\x93\xcf\xf0\x838J\xb2\x94\x9d\xa9\xf6[\xeeTw\x11v\x99\xdfeN\x97\xe5\xec\x0c\xcb\xaa\xdd\x88\x9fh\x84\xcf\xc4Qz\xc99x\xb5\x02\xf5\xfb\xac\xfd\xf2,;sF\x14H\x13w\xc6\x1d:\xc9R\xe4\xf1\xc5\xac\x9dup_\xe2\xd7\x8f\x12\xd6\xce\x8e\x1e}\x95e\xec\xbb,}\xd5VF\xb7<\x07-\xb7Cfo\xbe\xc3\x12\x9e\xe5I\xc8\x8e\xcc\xbdZ\xdb\xc8\xcb\xf3\xb2\x91\xd0\x14v\xd8\x19\x96\xb4\xa36\xb4\x98\x06\xbe\xcb\xdb9;\xca\xe6\xc4\xeat:]v\xe4\x08\x9f\x89\x9d$\xe5\xc9\xcc\xd8 |\xcf\xc9\xf8\x9a\x1f\xee\xb5\x9d\x0e{\xe9%\xd6\x96+!\x16\n\xea\xf0\x99\xc0\x0f\xf7\x96\xa20\xe3a\xc6\xce\x88e<2\xdb\xb1\x8f\xe7\xb4\x1a\x8bhGV\x17K\xc0^\x13\x7f\x9fa\xf3l\x81eG\x8f\x92\x8aw\xc9\x173\xebo\xd5\x97\x93\xeb\xec\xb33lV\xad\xb4\xe8\xf3\xc4<;\xd2\xb4\xa0\xa2\xcc\x91v\xc8\xbe\xc7^\x11\x7f\x86\xec\xbbl\xeed\xe7\xd5\x0e\x19\x81XX\xebd:j.t\xfe\xfe\x83\xf4\xe8\xf1A\x97\xb5X\xab3\x93E\xf2\x0eg\xc9Iy\xfb\x85\xe0\xf0F\xef\x16w\xb3\x19\x8f\xf7\xfd\x90o&Q\xcc\x93\xec\xb0\x9duY\xeb\xe6M\x9e^\x8a\xbc<\xe0\xad.\xc1\xd6 \xe7\x0b\xec\xc8l1\x82N\x97\xc9V\x9c<\xc8\xca\xd3\xac\x99%\xc5\x147\x1a\xc5Q\xc8\xc3,]`\x8en\x89\"\xfb~\xe2\xc4K\xa5\xa2y}\xd14s2\xbe\x19\xe4\x03?L\x17jXA\x1as\xb7\x0e\xc6Tw\xdb<\x90\xb9&\xd2\x05\x96\xd0^\xf4/-J\xf9\xd6Bw\xedu\x9d<\x1b>\xc7\x08\xa2\xe7i;r\xd2\x13Mm;r\x8f\xd2\x05\x96\xd6\xcf+\xe1^\xeer\xd1\xb5[\xbf\xd4\xfaWZ\x84\xc0>P\xf2\xf5n\xcd)\xbcK\xe9l\xdc\x0e\xdb'\xe7\xe7;\x16\xc9\x14@'0\xc87\xa0\x93\x18$\x88W_\x82NaP\xaeA'H\xadT58\x7f\xe2e\x0c\nt_'\xc9\x08]\xdd\xe0\xc9\x13\x9d\xce\xab\xdf20}JX\xbf\x9e\x1c\x08\x02\xc6g\x8a\xc3\xc8^c\x9c\xd96Um\xce\x02\xe3u+j\xe98\xa6\x1d\x0b\x92Mz-\x88t\x95\xd4j\x0e\xfeGw)\xbb \xf3 `G\xce0N\xe59\xc9P$\xcfc~\xc8xG\x93\xa18\x89\xb2(;\x8c\xf9\xcc\xd0I7\xf6CM\x90f\\'\x08\x04Q\x0bA\xd6\xc9\xae\x877\x04S\xb9\x1e\xde@|N\x0d\xb3L\x8b\x04-,-\x02\xfbF\x90J?\xdd\xdew\x06\x03\x9e\xcc\x0b\x8e7\xe3\xa7\x1b\x8b\xdb'\xe4\x9f)O\xc6\xb7\x1b(\x82\x103y\x91\x942\xc5#KtY.\xddJ\xa4\xec\xaa\x93\xe6\xc7\x03&\"\x99\xb0\x90\x00\n\x17^l\xb1\x97{fz\xaek\xcd\x03\xcc\x9f9o0\xefp\xde\xa4=/2+vD\x00\x01 \"\x80$)Y\xd5}\xb0\x96\xad$\"\x10\xd7\x1d;\xf6}'a\x00\x9b*\xfaf\xe7\xbe\x92\x1bl\xbf\x0d\xf1\xed\xd6\x8e\x12\xc6}-\x8cW[\xd1\xde\x07]=\x1d\x13W\x0d\xd8;#\xc5\xe1U^\x10z\x91R\x1c_aP\xfc\xeb\xbb\x9c6\xa2&\xday_\xf6\xa6\x0b!\xdf\x16\xc7\xce\x1cz\xec\xcb\x85\xcdc\xa7\x851\xd5\xf8\xec\xa3\xcc\x94\xf7t\xc8\xb0/\x9fq\x03\xf4\xc5L\xd94s\xb7\x89\x85\xf1o E\xe3\xdf\x12\xfe\xc6\xbfk\xdc\xce\xfe\xac\xd0\xfe\xddLI,e\xffvUw\x8f\x91C\x1d\x82\x83)\x84\x13\xbcXn\x86\x7f\x95\xb8\x17\x87\xed\x85\xf9K\x1f\x89\x15F\xfe\x18\xcee=\xbd\xce=\xfb\xb9MP\x0c\xed6\x93\xc4_\xbf?=#\xe1\x9f\xa3\xe4IY,\x92,\xfc\x99\x18\x88\x8a\x9cR\xd1JZ\x9e\x96\x8c\x1e\xa8Hy\x05!\xe2+ \x91\xd2D\x88\xe4\x9f\x86\xd8\x16\xbf\xe8\x84#\x0d\xaan.\x95-\xee\xceP\x7f7k\x87.\x83}\x7f\xed6\xccvq\xab\x8c'\xdc\x01\xc2+>t\xdf{\x11\xe6\x85\xd3\x06\xfe\xeav#q\x91]\x1d\x92\xbf\xdb\x8e7O\xb2\x03\x7f\xb60\xcc\x0d\xa4[\x93\x1d\x06\xbe\xee\x0e\x1d\xc7\xd8Q3\xa2\x14R\x8a\xe9\xe6\xb1\xba\x14u\x0e\xd3\x91\xa6\x94\xe2\xdf\x92Q\x01\x94\x0d\xb1\x14g\xd8J(\xcb>\xb6P\xbe\x84bn\xfe\xc1c\x7f\xf6}D\xf7|\xd2\x04\x00m\xfdk\x0d\x03\x11#\x03\x92\x96\xf9\xc2\x8e\xc9\x05\xf8\x14\x81\xf3\x1b\xbd\xda\xd6_\xaeQ\x056\xf3\xe6aT\x90l\x00|@}\x88\x18FE\x91-Q\xd6\xbdv\x1cG\xc1v8.X\x8b\xa2H-\xfc\x14!\xd7\xf2\xd3\xf0\xcf\xe4J\xbc\xa1\x84\xc2\n\xc3/;\xfd\xd0>\xe2?\xc8\x7f\xadt\xe5*\x99\xbfJV@o\x8d\x8a\xad\xf2\"\x12\x9f\x15\x0b&2\x7f\x92e\xfe\x95\x9d\xc1c\x18\xc1>d\xb0\x01#\x98\xc0\xa6\xe3\".\x18=\x82\x10\xbe\x82\xec\x11\x84\xeb\xeb\x0e$\xd3\x90V8\x96[\x9b\x86\xc7\xdd\xcd\xa4}\xfaws\xd9\x97\x155\xe3\xd3\xcb=j1\x8b\xd3\xe2\x98\x92\x8b3\xbf\xb0\x13\x87r\x93mV3\xd1^\xff\xac\xe0\xf7\xbf\xff[\xf2\x8c\x9a\x9a\xbdK\xa1\x82\xdc\x06W\x1f\x0f\xe3\xebVe\x91\xef\x84\x8d\\\x99\x81\xbd3\xd6y \x03+\x13%\xf5\x86\xa1Z\xa7GB\xa0\xd5\xe4E\x1d\xde\xd6\xc8\xd7\xe6m\xbev\x18\xf1\xb2\x12\x8f\xe3\xf6*#\xccK[\xe1\x9fB\x89\x7f\xe2\n\xff\x14\x1c\xff\x14\x12\xfe\xc9\x18\xfe\xc9\xe0+(\x1eAF\xf1O<\xcd\xba\xf8'\xd3\xe0\x9f\x04Ug\xb7\xc6?\x127E\xf1\x8f\xdfB/1\xc59]\xd1\x8e\xe9\x88\xaf\x84\xd7?)+E>gV\xa9\x8b\x07\x99\x0e\xa2\xa3MH\xaa\xa2\xfb*N\x88\x15u\x98\xa4Z\xa9\xf1P\xaf\xd4\xd8T)5X\xd1H%\xcdcEz\xa5\xc6\xd6\xef\xab\xd4\x10\xbfd\x91\x7f\xb3\xa1\xa7~\x14\x9d\xfa\xb3\xf7\xf9\xa4&b\x9as\xf9\xb6(\xd2'\xa8\x88\x8b\xd4\x15\xde\x12Lc\xf5u\x12\\Mj\xfa\xbcY\xe7\x90a#\xad\xfa\x92\x97?M\xe2\xc2\x0f\xd1\xdfL\xa3\xbc\x94:;\x08B\xf4V\xc8\xd55_\xa7\x84%\xff\xa9\xfa\xd6(\xe9\x12Q\xf1E\x18\xbf\x9f@(j}\xe6\x87\xc3\xb7c\xbb\xab\x9fKxI\x07\x90C\xbc\xbe\xec\xd8\xa6p\x8cUF\x14l\x91\xa8XQ'\xf1\xd1A\xb4\xff.%\xa8\xf5B\xc0\xedr-\xb1\xb8\x18*ex\xb7\x0e7\x0cI\xc9\xec\x8d_,\xba\xe5LJbU@TA\xa6\xa5\xb0)\x0b\xe7`\xaf\x15\x95\x1e\xb0:\x03\x9cH\xe0\xe9ul+O}J\xf5\xd0\xdb\xc4\x05\xebU\x02\xd5$\xda\xcc4\x9d'SI-\xfd\xb4\xa6-z\x94@\xda\x8e\x83\xf0\xbc\x03e\xe2yO\xae&\x12c\"\x9ekW\xdf\xdcb\\\xcd\"\xc6\xeb\xaf=\xc8\\\xc7\xaa\xf1\x81Z_|\x91\x91\xb9\x10\x13\xecc[0\xb9\xd9\xf8A\xcc!W\x16_\xab\xc6\x17\x99XI\xba\x9b\xf2\x00\xa3jc\xe90\xd5\x8c-\xf0=\x9bUR\xaaa\x02\x83\n\xf7LZ\n\x0c\xf9\xd1q\xd3\xd0\xbf\xf3\xa5\x0b\n\xfe\x94\x98\xd6\x12pX\x13\x98\x99\xc5\x01\xb8\xe4Q\x8f\xc8\x00\xfd\x86,s\xa5%)\x16I\xd0\xdbV\x8a\xee1=\xa2\x15q\x9e\xe9=\xc3\xd8t\x17r\xba\xdd=\x12\x99(J.\x8e\xb2\xab\xe7\xc5\xeb\xb2\x98\xb4\x8d9\xe5\xe7Z!<\xd0\xbdo\xbfko\xe3\xb0C\xcb\x8eY\xfey\x194uo\xa3Pu\xe7\xd0\xcb\xc8\x0e\xc5\x9d\x13\xf6\xdf9\xe1\xe7}\xe7d5\xf1\xa1\xbbu\xa4*\xdf\xd3\x85\xeb\xd6\x0b\x07\xdfNX'\x9e\x87g\n\xa8/\xab\xfb\xabb \xba\x95\x98\xb1\xf8<\xee\x96D\xec\x0ee\x06\x84GW\xa9b\x9c3\xac\x12\xe6\x07\x97dV\x16\x8a\n\xf3\x9e+4\xc5\xf2$~\xba\xf0\xe33\xc5\xf7\x01\x82\x8d\xf5\xd2\xcf\xde\x07\xc9E\xac\x92?.X\x95e\x12\x90\xe8\xe0\xd2_\xa6\x11QU;g\xd5:\xb4\xa1\xaa\xee\x12\xb85q\xc1\xe4\x01\x01\xc9gY\x98\xd2\xad\xb7*]f\xf7\xb3\xb3\xd6g|\xe9\xf8'\xe4\x02\x12\xefu\x16\x90\x8c\x04/\xfd\xb4y\xce\xe9ZG\xb4\xda\x99\xf7\x9e\x08\xe1w\x98\xe5E\x9bu\xa3\x80v\x05{p\x86]\xa8\x90\xd6)\xec\x81\x95\xe0)fw\xd3U\xcd\xef\xa3\n\xdar\x81\xc9f\xdb\xb6?H\xa2\\\x19n2\xbc\xf5(\xeb\x1b\xce\xf0B\xba\x97\xcc\nRl\xe4EF\xfc%\xbf\x08\xe9$\x98\x91k\xe4\x85q@._\xcfm+\\\xfag\xe4\x1e[\x88N\xa1_\x06a\xa2+<\x0f\x03B\x0bu,\xf0 \xdb\xd6\xe7qZ\x16*m\x03\x9f\xcb\x0c\xf6\xeb\x0b\xae\x85DOt7\x1d\x93f[\xf3\x90b\xecK\xf3;\xc1\x0e\xa1\x82V\x98t\n\xb5\xa3)\\lL;(.'\xd0\x8f*/\xae\"b\xb2^\x07\xf4\x1a\x880\x98\x07\x1d\x9d\xb6b\xf72\x026F\xeb\xdf\xfe\xf5\x8f\x96\x90}\xdf\x14\x07\x81\x0e:NN\xf0p\xea:/]\x88(\xc0\xdf|\x85\x1a\xbdfI\xba\xc1O\xb8v\xba\xf6\x17\xfc^p,\xe7#L7 iFf~\xa1\xdb\x0b\xca\x95\x0b\xbcQ\xd5\xa4\x97\x82\xfc\xb7\xd8\x0d\xd3\xf8nw\x88dj\xb8w\x9c\x12\xe1\xec\x1a\xa9\xb0\x06+\xab\xabta\x1a\xf6<6\xf2\xfeA\x98\xa7~1[<\x8f\xc3\"\xf4\xa3\xef9\xcb\xaa`J\xc4\xc3n\xff (\xf8\x12\xf1H\x13\x9c\xa0\x9f\x94\x05\x1b`\xc1\xbaz\x01\xb4\xcd\xc8\x9c\xde\x04B}E\xcehs\x13\x06\x8a\xcf\xe7\xb0\x0f\x01L`\xae\xffhU*\x15\x18\xa5\x8azu\x83\xfd\x86z\xef\x9d\n\x1f(\xa5\x1dZC<\x18p\x07\xc9 \xb24\x9d\xfd@\x05'yRf32\x81es\x04\x86\x83\xb2P5\xd3\xbbW5K>\x01_\xc1p\xcb\xfc\xf8\x04\xcan\x0dr\x99\xfaq\xf0\x8c\xa4\xc5b\x02#\x85t@\xf0\xdbJ\x01\x9c\x80\xda+a\xb8\x83$\xac\x02\xf8jA\xd8\x9c \xc2d\xe2WQ\x9f\x13&z.\xe4\\w:3Y\xfb\xa3!\x12j M\xd5\x15\x90\xd58B\x96L#\x06\xec\xdd\x19\xe8]\xe9 \xefz\x8c\xa7\x15\xe9\xa2\xad\xd2\x90\xbc\xc5\x14\xeb\x95\xb0\xaf\xad\x9e\x18g\xcc\x89\x9d\xee\xed\x05B\x98\xc8\x996\xedh\xd2L\x12\x03VJn\xf8\x17\x0b\x8dW-\xfa\xaf~\xb2\x19\xff\xd4\xd4\x81\\\xc9zS\x818X=f\xaf\xf2\x83\"i!\x04Y\xdbCQd2\x87Z\xd1nY\xbd\x8a\xd1\xc2\xcb\xd3(,l\xeb\xc7\xd8r\x86)\xd3\x15\xad\xc4\xf0\x186a\x9f\x1b\xb3\x11X\x87\x91\xe3\xfd\x94\x84\xb1m\x81\xe5\xc0:\x14`V\xe0\xf2\xcat\x10\xeaM\xa3\xb8\xaa\xa5\xa9\xf5\xc5\x06\x8d\x1d&/\xfa\xe5z\xd8\xb6\xa8\xa8\xf3\xe6=q\xdc4,\xb4#\xafF\x91\xb2\xe5#\xef\n\xf6 \xc5\xb7\x9f\x1b\xf13S\x918 /\xe8\x908!/\xe8\x908>/Pz\xbb\xcfT$N\xce\x0b:*\xcf\x88\xdb\xe9\xd6c\x9d *gf\xa0rf\x9f\x9e\xca1;e\xf6P9x\xa5\xbb=\xc2\x90U\xa1'L\xce\x18\xd3\xd3k\x88M\x9f\xd0\xcbI\xc1\xbe\xaa\xd5Hx\x06\x14gY\xee\xe3{?\x0b\xfd\xd3\x88\xa0\xc8c\x85\x0e\x85R;\xec#\xc8bn\xb3^(\xfa\xd3\x7f\x951O\xfc2\xcbH\xcc\xbf4\xd3j\xd5\xa4\xcfH\xf1\xa4(\xb2\xf0\xb4,\x88m\x05~\xe1o\x9c\xf3>\xfb\xe8\xac\xe6\xc2\xa9\xaf\x06K,\x8d\x05{\xd5\x8d\x82\x91pb\x83\xa9\x0e3\xa66\xc68AZ9\xd1\x97\x9f\xfb\xd1\x04|e\xf1\xb5f\x8f\xabE\x1f\xb4\xa3\x8c\xe3\xc0\xddd_R.\x97\x04\xac\x85\x8e\xe9/\xef\x04\xcd\xdc:\xdc\x00\xfa\xafh\x90\x08\xb4\xbd7T\x9cE8\x8c\xb3\xa8\\\x8b\x9f\x85\xc1\xcb\xa4\x8c\xdb\xc9\xff\xe0\xa32\x19\xdcB^\x0d'\xa4 \xbcH\xf9\xd3\x96\xebcZ\x08%>#\xc7\xcb,\xb2\xfa/^\x15Y\xd7Z\x8b\x1f\xc2(zKf$<\xc7\xcb2\x1f\xb0&\xbd\xa7|\xc8\xa2\xc4\xb2sJ\xdf\xc9^\x15\x1f$\x955{\xe3+\xf5\xdaS\xba\xaf\x1eqk#\xd0\xb5\xab\xf9\xceD\xc4\xd1\x15@/\x19o\x1e\xc6\x81D\xfc\x0d\xa4\xfc\niwyl\xc5F\xdf\xda6LF{h\x8c\x11Vdl\x0b\xb0b\x15`\xe9\x1b\xb3CVO`\xc9\xdc\xaa<>\xa2\x96:zu\xfa7\xb1[\xf3\xc5o>|\x80\xac\xc7\xb0\x11$\xac\xd9n\xa2\xf7Cf\x92\xda_\x0fqj\xa1P\xb7Zz\xe6\x0e\xd4\x08\xb7\xa7Ha\xb31\xf4`\xdf\xa9\xf8\xc4\x8c\xd3\xee\xfc\x98\x0f\xdc7\xcd\xe9\x1e `9\x98\xcf\xc9\xac\x08\xcf\x89\xf8\xd2\x88E\xd0\xfb\xaa}\x92{\xd5\x1d\xb2k\x94|\x92MgW{\x82\x06\x1e5\xb3\x04\x87\xc7\x14\xf4\xf2\xf0g\x0d\n\xe4c\xceo*\x14\x91\xd5|\xc2\x13L\x0d\xd8\xae\xbe\x93\xc8?%\x91\xb1\x9bE\xb1\x8c\xbeA%\xf3\x8d;aa\xd1\x8c\xbd\xd4\xea\x03\x04\xf0&y\xad\xeb0fT 3\xb7k\xda\xa2\x98\x00\xa6o\xe1\x13&p\xeb3\xa0\xe6g[\x8693:C\\!W\xd7\x03\xa7\xdb\xa8\xa7\xb3G\xf6\x8a\x841N\x8e\x905\xf5\x00\x1374\xbe\x0b\x88\xa3\xb4LY\x90`\x83\x8eP\xb7A\xd6S^\x0b\xde\xbd}1\xb1\x0c]7Dg\xa1\x9d\xe1\x8c\xb4\xb5\x17\xdb\xb5d\x8b\xd3\x0c\xd2y5|\xd8\xb4s\xd2Wk\xd89\xf9\xab\xdd\xa9}\xe0\xd5c\x89\x03z\x7f\x0d\xf1\x98\xce\x1a\xda\x06\xd4~\x1bC\xea\xf1\xdb\x95\xc4\xe5\x12\xcd\x11ns\x8e\xe9\xd3\xe2\xe8z\xaf\xf9\xfa\xec\x13\x13\xcfkZ\x8e\xc6\x14V@\x050`\xbf\x06\xa2\x03\xa8\xe2?\x92`B/\xf3\xbd=Hl$\xa6\xfa\xa9\x1c\x86\x1a\xfa\xeb \x9cc\xacH\xb1\x87\x89\xfaq`\xa2\x9fm\x88\x96\xb8}\x93\xe5\xa6\xb5\x05\xb9T\xf1s\xf2\xc3G\xccW\xa2\xcf&\x0e\x86\x83\x83\xb9\x91.\x0c\x9a\x16D\xeb\xf0Q[Ctj\xf4\x88[\xeb\x05\xee\x13\xbb\xce\xf1\xed\xe7&v\x8dtb\xd7H'v\x8dtb\xd7H'v\x8dtb\xd7\x88\x89]\xebQEL\xc0\xaa\x12\xabF\x9f^\xac:\xbb\x8dXU\x12\xac(\xa4\xa7]\xad\xadVy\xdc\x92Z\xdeJy|+\x11\xcf\x9dr?}\xbcM1\xc4)F\x19\xe9\xa3\xa6Q4\xb7\xa5\xeb\xb5\x10\xb2\xa5\x98\x81I\xdbMk\x1f\xa1w\xee1+\xa4p~\xe5\xd8\xed:\x15\xd2\x17\xb0>GI8\x962\x0fE4\xe5a\xf3\xe8\xe3\x9d\xb9\x8b\xdb\x0fYX\x90\xd7qt\xd5\xc0\xbc\xedG\xa7\xabp%\xb0\x1f\x0c\x08\x83\xa1\xb7W\xcc\xc0\x80\x96\xe9\xee\xaa\xd3g\x02\xd9\x85\x1f\x07\x11y\xbd\xea\x88[\xa0;\x14\xd0(\x10\xdf\xfb)O\xe2{\xa1W\x90\xbc\xb0\x0b\x16\xc0^\xb6\x1d\xe0yf`2\xc8\xa6\x00VY\xbe\xf6\xe17m\xaf\xbc\x91vlX\xc1\"9;\x8b\xc8\xf3\xfc \x08\x8b\xaf\x93K0$\x99\x91\x1f\x19\xbf\xb2\xb1\x0f[y\xe9\xdb~\xb9W(F5\x815\x8c'\xc0\xfe2~\xa7\xb6\xc0\x84\x1e\x98\xc7\xa46\x9d\x08W\xf2#\x8fE\xe1|!\x9e\x0e\x82\xd6W\xe5\xa7A\xa3p\xa4\xc3\xea\x14t'w{f\x1bV\xb2\xa9\x80\x15\xf8o\xfa\x08\x05u\xe3\x16\xaa/\xf1\xc1*S\x1d\xf6[\xdd\x02\x02V\xb1\x82\x001\x85\x16\x9e\xe0\xb6\x04\xf5\xdf_~\xa9\x9e\xaa-Ur\\X\x93\x1a\xab\\N\x18\x11\xd8\xf8\xb3\xd2\xeb\x0f@\x0b2d\xae\x8e\xf1o\xbc\xd4\xcf\xc2\xe0]\x1a\xf8\x85.\x08\xc2M\xd7X\xa2\x11\xf8*\xcbo\xb4\xeb\xac\xda\xa5;\x9a\xb2V\x10\x05+\x1e\x86a\xeaxXA%\x0f\x15ie\x88\xb6\"?\x99P\x9f\x0f\x101A\xa5\x9f\x1fx?\x86\x98O\xce\xfa\xba,\n\xb3c#p\xba+\xb3\xad#rY<\xc9\x88\xd2\x15M~JV}\x11\x9e-\xa2\xf0lQ0\xb0\x9a\xf4T\xe1\xee\xab\x97\x9ef\\zz\x13W\xe0\x81\xd2\xd3\x94U\xcc\x0c\xa3@\xf2\xad\x8f\"\x1f\xaa\xf0\xd5SK\x91M\xcer!9\xee\xd9'\xc7\x85s\x13\xa3a-vk\xab\xe7*o^`\x19XS\xbfo\x99fC\xe6%b\x11\xa8\x82R\xf4\xcf\xe9\xc6c\xab|\x13\xf8\x94\xdfqH\x9bX\xb8Rz\xfe\xb4\x15\x01\x15,\x17\xce\xf1_\n\xa2\x06 \x83y8\xbd|\x1e\xacd\x17\x0b\x9ck 3\x12\xe0\xed&\"b\xf6~\xc5\x08\xa2\xfa\xe0\xf5\x7f\xd1q\xae\xe8\x91\xc7\x00\xdb\xbb\xbb\xdc\xbc7~\x9e_$Y\xb0\xf2\xe6\xfd\x11\x9fO\xb1w7\xdb\x0d\xbf,\x12z\xddG\xa4\xa0\xbb\x12\x93\x8b\x8d\x94\xcfu\xc0\xd7\xb1\x08\"8\xf8\x0b\x0ea+|q\xf3\xdd_\xe8\xfdkz\xc2z\x88\xa7\x07\xdd\xe7C\xf6\x85>\x84^\x9e\x83,\xe4\xa1\nf\xda[\xd5\xe0\"\xc8\x8a\x0dF\xf4\xda\x12\x11\xb6\xe4\x94\xf8\x19\xc9\xf8\xbdj\x82\xf7\xdf\xe9\xc6\xc3\xe1\xdd\xea\xca\xbb\xf1u\x87\xd7B\xf0\xd9]u7\xba\xe6\xee\xf6\x8ac\x16\x89\x16.\xcf\xe7\x86\"\x87_m\xab\"\x9c\xbb@6w\x81h\x86#\x99\x01\x08\xc6\xe8\x7fl\xda\xa9a\x08\x81,\xfb\xeb\xd4\x11\xab\x12\x0c\xf6\xfe\xed\xd1\xd1\x1b\xccLK\xe2\x82\xcbR'P\xc6y\x99\xa6IV\x90\x80IR\x08\xa5\x97\xac\xffh\xc1:\xa4\xb0N\x7f\xddN\xfc[\x0f\xaf\x16\x017W8\xed\xb3e\x919\xf6.{\xd1\x002\xb9)c4r\xc6\xab7-\x98\xf4\x1b\xcf\xb4\xab\xccLH_+D\x0b\xb5\x1e\xd5$3c33\xf1e\x95\x82\x92\xaf\x1d\xcf\xe9\xc3\xc4e\xfd\x02$w\xb3\x00\x9d\x99\xa8\xb2\x92\x1b\xb3\xbe\xd1;'O}J\xe3\xd6\xab\xa7\x96\x1e*s\x9d\xd1\x01\x9d\x99\x00\xca\xb4\x9cd\xc8r2Q\xbby9\xd9\xc5=h9\xd9\xeau\x86l\x17\xd5\xec\x15\x06\xb7\xf54\xe5\x15\x87\x9e\x94\xbf\xe2\x11\xa4E\xefT3\x96g\xbe\x17r\xe2\x95\xa7*\x0f\xdbp\xdbK\xd0\x90\xd5\xd0\xa0\x1fL\x15\xe9G\x0d0tM\xb4k\xa9r\xbc\xfa\xf4\x07q\x05LT-\xa7j\xe4\x03\x82\xc8\x19h;\xe5)T\xc7\xa9Q\x07\x8d\xcb\xebxn\xd2\xd5\xe17\x12\x08B\x87\xa0\xba\xbd\xfa\xf2ws\xf6MZY~\xfbp\x03\x85\x82\xde\xaaYGW\xa7\x06 \x96\xf7\x95R>k\xf1\x80$\xa1\xe7\xbc\x8d+u\xe5;pKo\xea\xa2\x11[p\xb8;t\xdb\xa1\xba\x9eT6(\xc2\x9b\xd6\xa3Z4\xa4*U\xef\xfe\x8d\xe2Yw\xe5J\xffhB\x83\xed-\xbd\xd4`\xab\xc3\xd3\x87UQ\xc7\xad\xd9\xaf\x8a\x1e\xe8d\x07\xdb[\x0fu\xd2\x83\xedme\x8ckV\xf4yX\xf2\xc9\xfb\xd9lHX\x8dHym\x9aSyR\x16\x8b\xe7\x05YJ\xb9\xc7\x9b\x15\xea\xec\x0c\x93ZR\xd0\xacR\xa7\xa26\xa6<%3\x1e\xb6\xd0\x9ba?\x98\x90\xeb\xeb\xab\xe7\x01\x89\x8b\xb0\xc0\xa06b\x08\x7f&W\xa8*\xc2\xbe;\x8db`mQ\xf5i\x12\xe7\xe5\x92\xe4?0\x01\xd1JB\xfb\xdea\x17\x8aa\x8b\x0eQX\xe0\xd8Ek\xd0\x9a\xe12_\xcf#\xfft\xd0\x00\x05\n\x97\xd2\xf2\xb1\xbc\x0f\xb0\x8f\xd1\xe0z-%\xea\x0f\xbf\x0f\xf3\x10\x85'k\x9bj*\x8d>\x14FN\xfd\xd9\xfb\xba\xb2:\x1c\x14\xa2QK\xd4^uP\xdd^\x0cCR\xcd\xc00(FO\xab\xd7\xde\xec\xc2\xa5\x98\xbbzT\xca5U\xf6\xa8A\x1f\xf0\xb9j9\xf4\xbb04z\x04\xd3n%\xf1Qv\x95\x94\x05:\x07\xeb+'\xbc2\xf3g\xee\xa9\x1cr\xbd\x99X{}M\x96\xe5\xd2\x8f\xa2\xe4\xe2(\xbbz^\xbc.\x0d\x96P,\x87e\xc1\xeb\x1d\xc4\xfei\xa4\"\xd5\xc4\x83\xf1\x1f\xbc\xb9A\x0b\x12\xad\x10\x0e#\xa8\xebb\x1ag}\xcd\x05\xd6\x1c\x18L\xf6\xbc\xaa\xdc\x1b\x1fv\xc9\xb6`H(\xd9\xb3\xaa\xea\x80!\\UZ\xce\x97\xa8\xc5\xd4\xd7<\xad\x06\xfb\xc6\xa8\x13=a\xdd\x0b\xad\x8e\xbe\xe2\x05\x86e\xaeQf\x8f\xc3\xd8\x01\xab. \xa5?\xd2\xc8%\xfb\x80\x07\x85;BZZ_\xfb\x90\xd5~Z\xa1\xca\x1e\x0f\xb0\xa7\xac\xfe\xdb\xdaM\xbc\xef\x8b\xf7\xb0\x07%\xa5m\x0c>\x7fO(Q\xe5\x859e\xbe\xf4\xb5^\xc3\x1e\x9c0\x16ArS7\xcd\xee\x0d\xec\xc1\xa9\x97G\xe1\x8cP\x9c\xb51rx\x82\xef\xc6\xf7F\xe5\xdf\x8dS\xad\x1a\xb4oZ\xcd\xcd\xc7\xe8\xacO\x05w'}\x0eP\xf5\xdd\xb8\x9f\xd5\x838T>~\x155\xd3\xcc\x1c\xac\xfdX# \x02\xc5l\xc3\x82,\xc1\x82u\x9e}\x8b\xd9\x93v\xae^\n\xf7\x96\x8f\xaa\x1b]2S\xc3\xca\xac\xa0\x13\x1c\xa6\x04\xd5\xf6\xc4#2W>F\xf5ZQv\x86\x1f\xba\x9a\x9er\x0c\xd9x?\xd1~J\x83\xf9h\xdb\xd9\"\xb9\xfe17\xb3F\xedR\xcce\x17\xcd\x9bu-\x1c\x98\x06J\x18\x0d\xa2\x14\x8b\x88\xa7A3\x193=6H1]r 9K\xb3\xf1\xb4\xdd\x02*\xe5\xf5\xaf\x1b\x1e\x10r=\xf4fI\x19\x17\xf6\xad\xceD\x0b\x1c#2\xa0cmg\"7\xcf\xb0\xee$\xc4\xb8zO\x14\xe7W\xa0\xa6\xaf\x96\x0d\xa8\xb3\x18<\xe2Y\x12\xc1,\x89N\xd8\x85\x03\x8d\xdd\x8aN\xd0IK7\x13\xeb\x15\xbap}\x8aq\xc8nO\xda\xe1<\x93}\xa3\x1c\xe3\xb8\x1a\x99\x94\x06\x99P\x82\x8c:%\x9f \xee7\x9fV]\xbd\xf4S/\xcc_\xfa)\xf3\x17R\xd8\x1f\xd2\xe7\xda\x0e\xa5\x8e\x07&o\xd2\xcd\xe7\xa2\xcf\x8fh\x1e\x1bc\x95@G\xcaj\x88ZB\x1fA\xc1O\xe0\x94\xd1\x80}\xd9\x84j\xb6g\x02\x06\xfe\x80>\x99\x7f\x81W\xe6\x04z\xe2T\xa4\xac\xd6\xa2F]?\x84\xc8\x82\xf8\xb5|\xc9\xbe\xc2\xf4%\xc6v\x98\xdb\x94\xec\x94h\xae\xdf\xcc\x04\xd4\xe7\xa3#\x7f!\xa4H\xf2\x97-QV\xff\xbaK\xb2t\x03\x07%jsNo\x02\xe7}\x8b)\xb8\xb7 \xf4\x04\xd7\xaeBEN\xe0\xbd\xb6\xa2.^h#;\x1c\x06\xd8\xbb\x0b,\x7f\x13\xe31m\xc7i}\xdd\xbfJ m\x90o0\x01\xcbj\xdc\x9bm\xb2\xe6\x8e\xee\xad\x8a\"\xab\xef.\xb8\xcbY\x1e\x1a\x07\":\x9f\xf0\xb0\xe2\x98Z\xb2K\xb8\x1a\x0e\x8a\x8c!\x14,c\x1f\xc1y]-\xf5\x13\xdb\xa1\xa4\xe2\xeb:t\xab\x9e9\xb8\x93\x95\xff\x87d/oJ\x0f\xd7\xe0}\x82w=\xa3\xda_\xd7r\x01\x8c7\x80; \xfd\xa9\xbd\x81\xb9$\x03#%\x1a \x83\xa6\x87\xb1\xae\xda\xa5iN\\\xe6y&\xe2\xfb>\xade4\xdc\xff\xe8\xccmk\x8a\xafL + y\xf2 \xf05\x10\xe9\x00\x1c\xef=\xb9\xc2\x1b\xdfH\xa8\xf3\x8b\xa1_\xd8/\x9e\xa5\x97\x93\xe2mg\x06\x03r\x1c\x8bh\xf8fd\x0dm\xdcn\xacmr\x0f\x1e\xc6\xfeI\xd1<\xf9\xd2m\xa0\x06Zw\xcaM@r\x93\x83t\x17\xb8\xf1\xa9\xd1,\xb7Blo\xf4+\xd2\x08\xfc\xf8zP\xbd\xef[\xe0\\\xbd3\x01s\x9d\xf8\xa1/\xf9\xaf|i\xaf\x06\xc1\x03\xdc\xdc\xb5\xa6T\xedG\xa85W\x9be?\x84\x03W0\xcck\xea\xdb\x8e)\x0f\x19C\xe3\n3D\x9d\x12\x0f'\xb5\xe5sY\x0dr\xc0\xa9\x84\xd5h)\xf1\xf0\xc3\x9c\xd0^\x9f\xc7L5\xd4\xfba_\xa4\x90\xc1\x88g\x95 ~Fh\xa7F\x97\xab_\x03Z|t\x03\x8bo\x95\xa5\xf7\xb9\xe8M\x1dD\xb6%\xa9\xe9\xcb\xb5\xd4\x12\x01\xf5Uoi\xb8\xba\xda\xcd\x86\xbe\xac\xab\x92\x95\x94\xdb\x13\x98\xd6!SZ\xf1h\xe9\xaa\x06\x06\x1b\xaf\xf3\xcf\xd0\xa8\xc6e\xa6\x0b\x1d\x03\x16\xcc)\x95\xc1\x1e$H\xecdM\xd3\x91\xccl:\xd2\xf4\x93k\x81\xac_[\xe8\x89W\xab\x98)\x0e4\x94SZ\x83\x85\x83\x84\x9a\xbaZ\\?\xadod\xe9G\xea$\xedyq\x15\x11\x9de)%\xfb\xcf\xb2\xa4\x8c\x83\xa7I\x84\x19\xdc\xff\x7f\x0f\x1e\x9e\xce7\xb7\xbb\xf7t\xeb\xe4\x19\xc6\x92fj\x19\x9dL\"\x9c3\x1bx\xab\xdd\xa8E\x17\xdf\x92O\xfegj\x0d\xd6\x03E\xd9\x10(\xd2\xd8K5\x0dj?\xcf\xe9\x07\xdax\x16\x81\xce\x18.\xd0\x19\xc3\x05:c\xb8@g\x0c\x17\xacf\x0c\x17\xa8\x8d\xe1\x82\xda\x18\xae\xebd\x93r\x0f\x81-\xa5\xb1[\xf0\xe9\x8d\xdd\xcc)\xfe$c7\x15\xed'\x19\xbd(L\xde:\x9e\xc2\x83M\xdbn\x95Q\xf8\xf31\xbf\xe93\xae)jO\xe0\x1es\x11JPO-t\xde\xd98M.\xadc\x03}O!L\xeb%\xcc\xd7i\x8d\xf9M\x88\xe0\xc2\"\xeeX\x9a\x91\x99_\x08i\x80\x1dsI\x8e\\\xc0.\xd7>U\xda0\x86\x8e\xcd\xa7n}\xe3\xc2\xcf\xe20>3\x89\xffE\xdd\x89uW|e\xec\xfd\x94\x84\xb1m\x81^\xe8\x91\xe8{J\xbd\x97t\x16\x1d\xfa\xf3\x97kW\x86\x01\xc3Pd\xb9\xb9\xc9\xb6\x88\xa4\x94#5d\x0b#\x97\xa9\x1f\x07\xcfX\xbd\xbaoOzO\xcf\x9b:\x01\xd4\xcd\x1c!\xfb\x1c \x19_\xa6\xbf\xb3\x16\x9f\xe75\xf4\xef\x0e\x1a\x9f\xad\x83\x86\xc15C\xaf\xa8\x890\x91c\x97\x89\x02~\x93\x87\xde<\xc9\x96\xbe\xa2_\xee\x92\xc1\x03\x9a\xab\xfd1\x84K\xd7\xda\xde\x1eD\x18\xd9\xfb4\x8c\xfd\xec\x8a\xbd\xc1\xecB\xd6\xa9\x9f\x93\xddm\xf1F\xef\xa9\xc1@_\xef\xd2\xa0\xf4\xe4\xe0\x01\x12\xe7\xa12\xdd\x90\x84\xeaJ\x1eS\n\xf6\xc1\n\xe3s?\n\x03\x8b\xc9\xe0\xbbm\x86E\xd4\xfc\xa2\xd4\xd4\\E$\x9a\xdbU\xcaK:\xda|\xba\xa9\x08\xd2\xaf\x90\x07\x04a\xce\xd9\xdc\xc2\x0b\xf3g\xfc\xaf\xe6a\xf8\xcch{\xb7\xca\xbd\xdfL\xef\x0duR~\xe1\xe8\x9e+\xde\xd5u3\x92\xa7I\x9c\x13I\xea\x01R\xa6\\\xcd\xebJ\xde\xc3\xdbnEN\xd2\xb9\xcb\xc6\xf6}\x05\xd6\xd3\"\xb7P\x8b\xdc\x8c\x84R\x15\xf0\xacP\x06<\x8b\xab\x80g\x94\x88\xccX\xc0\xb3\x0c\xbe\x82\xe2\x11d\xeb\xeb\x0e\xc4\xd3\xac\x19\xf0,\xd3\x07<\xab\x15\xf0&\x92\xadJzwx\x95\x17di;M\xdb\\\xfc\xeb\xbb\x9cN\xc7HW1Z\x96\xd9e:v\xc6r\xbf2j\x96\xad8?\xde\x0d^L<\xad\xdb\xf6\x0f\xdd_\x8a\x8d\x0c\xcd\xd1J\x854\xb6\x80}\xc0\xd4\x18\xcd\x06\xacc`\x81t\x9b/\x95x\x0e)\xd5\xe7\xb1\x1d\xf3\xec\x05-XW\xc0]kl\n\x03\x88V\xd3Sag\xfa\xcc/|\x8b}\xe22\x85\x03\xcbZr\x8c}\xb78YWw\x18\xee\xaa\xffn\xe3\xa6\x81\xa8N\xeb\xdd\x8d\xa4\xd3\xba~(j\x84\xd2?\x14q\x1eT\xae\xcc\x98\xb8\xa1\xbe\xf0\x84\x0f\xb3\xd6\xc9:\x91P\x9b\x9are~\x00Ul*\xc59\xc6\x80\xa2\xfb0\x0d\x11|;s\xc2\x98\xcf.\xc4\x02\x94\xf5\x15\x9a\xe7\x0bH\x94\x13\x15S\x8b\xbc\x96\xa6\x9d\xa2\xdb\x8ei\x1b\xb3a{\x93\x0f?\xc8\x9f\xc9\xa6\xc4C6\xc5\xbc#\x03\xb7#6n\xc7\n{\x11W\xaa\xb4\xcc{\x9dq\x17\xf5\xd4\xb1\x1d\xe5\xd6t.\xed!\xfb\xe3Br\xbb\x9d {w\xc6\xef\xdb\x99\x84\xc5\xddeq>\xf7k\x84\xe2\x9b6\x8a%#\x17\xa8G_M\xb5e\x08Mn\x9d\x82\xa8\xa7\x89G\x9de\xa3\xb4}\xa2\xbcrl\xdah\xac\xd9\xb6\x81\xb1\xbai\xeb\xa5\x97\x914\xf2g\xc4\x8e\xc9\x05\xbc%g\x07\x97\xa9m\xfdb\xc1:`D\xc6k\xcb\x05\xeb\xccr:*9\n\x11\xa5\x04\x1f\xf8\xf3\xf7\xa5+\x95\xca\x8e\xd2\x8e\xedqG\n\x1a\xf2\x92Q'4\x0fSX\x8c\xb7v\x95T]\xf9;\xb2\xac\x14\xfb\xfer\xed\xb6\xa5\x82\x99\x0b\xbe\xf7\xee\xcd\xb3'G\x07'\x87\x07/\x0e\x9e\x1e\x1d<;9}\xfd\xea\xe8\xe0\xd5\xd1\xc9\xd1\xdf\xde\xfc\xfbZ\xaa\x88\xe0\xd5\x16\xf5\xf0\xcd\xebW\x87\x07\xbf\xcf\xaa\xeadR\xaa\x98\xac=\xeb\x91\xb8\x10\xeaH\xf1U\x16\x84a\xaf\x93\xef\x9f\xbc}\xfe\xe4\xeb\x17\x07w{du$\xc4 \x0c\x16{\xef\x89\xc2\xa8\xc5\x17K\xad\x069 \xef)\xef\xfe\xcc\x85\xd0H\x11b\x05\xe3V\x94.\xf8\xcd\xf5\xcdnq%\xd72\x8fQ[\xbd\x97\xf0\xd7;\x0f\xa4\xfb6\xa1\xcb\x82y\xf4\x92\xec\xc0\x9f-l\xbdh\x01\xe9>\xef^\x18\x07\xe4\xd2\xfb)gr?-\xd5Gw4\xb1U1\"\x88G.\xd3$+\xf2)#\x80R?\x9f\xf9\xd1S?'\xdf\x84\x11\xa1\xdb\xe8\xd8\x85s\x8c\x1b#.\xd1}\xe9w\xdbAH\xba~\x07-\\loo\xefR\xb2H\x8c\x03\xd7eg\xb43\xe8k\xc3\xb2\x0b\x1b\x8d\xad\xb1L\xd0\xd4\x11\xbd\xecU\x0c5*Z#\x93\xa6W P\xdfd\xc92\xcc\x91r\x89\xed\xed\x9d\xfb\x8e\x0b\x87H\x91\xd7\xa65^^\xf8Y\x91\xff\x102\x0dIlo?\xd8\x1d4\xc3\xd8~8FM\xef\xc3\x07\x9dU\xda\xde\x19\xd6F\x1fpno?TB\xe7\xf6\x8e\xca\xc0%\xb6\xef\xb7_3b\xef\xfeHZ\xe9\xe6H\xc7[\xf7\x1d\x1b\x05n.X\xf8\xaf\xd5\x83\x87P\xbbt\x82\xd2;\x9b\x08'\xb3\x13\xda\xff\xa6\xf8\xe3=ES\xf5~\x18\x92x4T\xa6'\n!|\x15\xac\xe0Da\xd7\x18W\x85\xe1\xfa\xba\x12{\xac\x11\xdcTxL\x19\x94J\x9cm\xd7s\x10\xa2\xb9\xc4\x1e\xa1MzB\x0f\x9bE\x0f;\x8b\xd3\xc6\x8d\x0cYZ\xd9\xfa\x1d\x992\x99C\xec\xe2O\x89;\xbav\xab\xcah]\xf3D\x08*Q\xd7\xc0W:\xb3Y\x17\x0e\xfe\xac\xabg\xb6E\xe2\"\x0b\x890\x9co\xc3\x8f\xbc~\xf2F\xca\x0b\xac\x8e\xd0\xd8\xfb\xa5j\xaf\xf9*\xaaP\x17\x8b\xb9\xda\xdd\x93 \x89)\xdb\xb2f\xa6\xfdoy.F;\xeas\xf1\xb0\x1d\x95\x91\x1d\x8b\x87m\xc1\xb6\x8f\x9c\xc6#\xe9,\xeflb4\xf3\xd8\x1e=tl+,H\xe6\x17\x98CV\x0f\xbb|q(,\xd5\xb3k\xa1\x82>y\x1b\xa9\x11\x11\xc6\xef\xf6U:\x9e\x98\\\x16\x142Gn;u\x00\xed.\xc4\xb6)+\x0b\xcf\xaba\xaf\xb6\xdc\x12\xc2Q\xdf\x86[\xbb\xeau\xdd\xd5\xe2\x95\xedm\x07\xf6\x95\x9coHr\xe81@N\xecv\xa2\xa1Jk\x10\xbb\xb8y!\xaa\x07\x90\xda\xadT\x079S\x16\x94\xf0\x18\xf2G\x0ed\xde\xdc&\\\x182\xcd\xd7\xd7\x8f](\xa6q[\x08!\xa8\x8c\x9b.\xd8\xfd\x91\x9a|\x18\xa9!q{g[\xb3duw\x1a8\xab)\x0e\x96wFGQ\x94l%\xf4q-#$9\x84\xcaES U\xa3\x14\x1c#\x05iBI\x1cv\xa9\xc2\xda\x9e\xde\xb5\x117\xed\x11D\xf0\x18f\x8f\xf46\xc0\xb45\x9bne>\x9d\xad\xaf\x1f;\xb4\xcd\xd2\xa9\xcdU:\x1f2\xe1S\x7f\x970[_\xef\xe9\x16\xaf\x87\x19\x841\xe4Ho\xe4\xd3\xd91\x0b+\xea\xd4r\x0f\xac\xf2\xe1\x03j\xa2\xaak\xe5\xcb/a\xa3\x19\xbbhE\x1c'a\xb3]\xd5\xa9{\xe9\x17\x0bo\xe9_v\xc1\x88\x95\x84q\x1f \xe9\x11\xba\xcd\xb0\x0dq\x1c\xf8\n6a\x9f\x9e8X\xa7C\xdc\xa4\x97 C)7F\"\xea\xf9P\xac\xbds'\xc0\xaf\x83\xfc\x10\x83\xb8SHbD\x9eM k\x0d|\xb3#\xa2\xf3k\x8dPp\xc8\x0e\x88B+\xc1\xc6\x94\xe3\xda}\xf8\x009%/\"\x14\x87\xf1X\xb4\x9c\x9a\x9d\x80\x8dr8o\xb6\xf0\xb3\xa7I@\x9e\x14v\x8ek\xbe\xb33~\xb8K\xbf\x0d\xe11\xec\xecn\x8d\x1e\xb2\x86\xd6a\x84\xe0\x87\xb6\x04\xb6\xdf\xf9\x98V`\x0d\xecn\x8d\xb1s\x9f6p\x7fk{\x8b\xf7\xcf\xeacGt'a\xc2\xdf2/\xbd\xdc\xc5N\xc6\xb4\xcc\x87\x0d\xde\xcc:\x1d\xe7\x06\x1f\xd4W_\xc1h\xd3\x81u\xd8\xdd\xd9\xd9\xda\xbd\x1b\x08\xef\xdc\x1f\x1c vu\xd8\x90\x02\x8b\x83\x12e~\xa5\x0d\x8a*\xdc\xbd7\x90\x19\x13\x1f\xb6\xc4\xf0\xc5\"K.\x802\xef\x98%\x1dO\x80\x05a\x0eqR\x00R\x00\xa7\x11Y\xd3X~dv\xc1\xa2\xf0\x11g\xc5sB/\x81\x07\xc88\x8c\xb7\xb7\xf1\xdf\xed\xdd\x87\xec\xdf\xfb[\xec\xdf\x07\xfc\xfd\x83\x9d\x0eg\xb1\xbb\xe9\x08\xaefHg\xbd\x84\xd4\xaejgd\xd2(\x99\xc6\xf6\xe8\xbec[E\xc2N\xd5\x91\x7ff!\xdbi\xfdlQVn\x9d\x82\xfc\xda\x1eX\xd3\x04o{\xf8\xf9\xd8b\x0c\xd7\xfd-\xc7\xe6\x14@\xed\xc9\x00UCV?mU\xb5\x89\xe9j\x90l\xa7\x90i\x1dK\x1ah\x0c\xa94d-\xe4\x85\\\xa3\x1c\xfe\xa6\xc32\xac\xd8\xa3\xcdQ\xbf\x0d\xf5}:I\xb5(\x9f\xae\xe3\x03\x87Y\x1e:.X\xbe\xd2\xfe\x10\x83ik{i\xf7\xd6)l\x99\x088\x9e_\xaf\xc1\xa0\xf9KDK?\x11\xa2\xb8;0)\x0d\xbb4\xc4\xd5\xf8\xa8s\x0c\xd5z0Le#\x9d\xc3*\x02\xb6\xcdTG\x02$\xd8\x86d6\x13U\x89\xf3U\xf5\xa7\xd2\xb0\xe9\x1bE\x1e\xe5\xf5|\xf56\xd7>\xcep\xdb\xf8\xc6z\xea\xc7\xff\xb1\x80Y\x12\x9f\x93\xac\x00\x0e\xe9E\x02i\x16.\xc3\"<'\x8c\xcdZ\x95\x9a\xef;\xf3\xdb\xbbm\xc91\xc3\xc6\xe3\xed-%\xcd:RJ\x15Z\xec\xd3\x03\xc1>\xdd\xff\xef\x99}\xd2\xb0\xa5\xdb\xbb\xea\x95\x1dw\xc48>\xc7\xca\x94 }~p\xf2\xe6\xed\xeb\xa3\xd7\xed\x80\x15e\x9b\xdfo\x16\xb7\xc5\x01\x9d\xf58g\xb9+\x0b\xde\x15E\\\xe1<3D\xc6@+\x0c-5\x84$w\xe1\xa1S\x90\x17\x84y\x1a\xf9W\xf4v\x88\x93\x18\xf3E\xdb\xe3\x9d\x11\x9a\xf5\x938x\xba\x08\xa3\x00Y\xb7\xc2\xcb3\xcacX?\xf9\xe7>\xf3\xe9\x9dXU\x16J\xee\xfb\xf7C\x18\x07\xc9\x85\x17$3\x14\xa18^\x92\x92\xd8F\x18\xb9\xc8\xc2\x82\xd8\xd6W\xec\xd3\xc7\xa2\x8a\xf7\xcd\x1eC\xd1_\xfdx\x8f\x17\xa1j\xd7\x9bEI\x8e\xe9\x0ds<\xc1\xdf<\x82lc\xe3\x91\x03\x01\x89HA \xaf\x01i\x1aN\xb3c\xbdMYn\xb7`H\x8dI\xf9E\xc1,8)\x9dfD\xad\x889\x95tF\\F\x11J\x90)\x15g\x97-x'\x0ecpcrA\xf9\xbef1s\xff\x8aYZ^\x82\xa6g\x98\xd5\xc2qei\xab\x90p%v|+\x9a\x7f\xa46\x1e\xec\x9c\x08\x0e\xf9\xdb\x0f\xf4\x94\x1f\xbd\x98\xff{\x90\x1d\x8cF\x0f\xd4d\xf1\xb8\x8d\xa0\xb9\xf0`w\xd7\xb1\xd7\xda\x02\x075\xca\xb8\xc1\xfd\xce\x97\xa8\xe4\x84t\x17\x17\xe0\"u_Sfiz\xacX\xf3\x98\xf2\xd5\xa5\xc3\xa4\x04>\x8a\xf31%<^\x9b\x91\x88,\xa4\xf8\xf0\x11\x14BX\xcb\xf7\x03\xbf\xa3\xa8\x01w\x83\xb9\xa8\xfc\xa7\xd0\x8e\xb0\xb5\x0f\x1f\xea\xd6\xd4[\x14\xddt\x8b\x1e>\xd4\xac$\x83N\xdb\xfa\xd9r\xd0\xd5\x82\xd2\x81\xcf\xf3\x83\xb8\\2\xbe\xc1\x96`\x18L\xe6\xd1\x82\xd2=\xac\x93\x83\xd0s\x8d\xe6;y\x1a\x85\x85ma\x8e}\xde!\xb9\xf9 \xed@\x95\xd0ti.\xa7m\xdd\xdc{'\xd3\xe0\xd6\xff]T\xf5\xdf\x92\xa8J\x83\xb2\xb6w\xdb\xef\xc3\x01\x94\x8c__\x94\xd5\xc5e\xbcN\xcfH\xf1FT|=o^\xab\x1aX$\x02\x9d\x01fp\x0e\xf1dMQ\x1b\xad\xa2\xf0)\xa9\x90\xc4y\x91\x95\xb3\"\xc9\xd0\xe4 \xc28/\xfcx\xd6-\xddo\xfe-\xdd\xbe\x93\xe6g\x1c\x0f\xec\x83\xdf6\x00_q\xfdw\xb6nz&9\xfe\xc8V\x17XT\xf7'g\x1f(;P\xb1\x0c\x0f( \xcd\x98\xca-\xc7\x15\xde\xf0[\xfc\x82E\xc6\x80'\x8f\xb5G\x9bc\xc7\xe5>\xb5\x94Z\xc0\x83\x1b\xb5\xb8\x05\xf6\xaa!kp\xd1s6\x17\xba\xb3\xa0\x13m\xe1\xe9\xe1\xe1\xdb2\"/\xc2\\\x11\xec\xe0\xe9\xe1\xe1!%M\x9f\x91Y\xe4\xb3x\xd3\xdd\x80 O\x0f\x0f\xd1\x14\x817\xd1.\x8dB\x12\x17o\xc9\xacP\x97?{\xfd\xd2X\xc8\xe6\xa2->J\xde\x93X=\xf8g~\xe1\x1fe~\x9c\xcfI\xf6\xbc Ku\x1b\xdf\x84\x91f\xe4\xdf\x1e\xbd|\xf1$\x8a\x9e&Q\xc4\"P\xa9\xab\xf4\x95\x7f\x93dK\xee\x85\xa4\xae\xc0\x9c%\xb4U^\x92 \xf4\xd53|\x19. e\x89qs\xbb_\xbe\xf2\x97$x\x95\x04\xe4\xa5\x9f*J\x93@\xb3\xebo\xfc0\x16\xe1O\xd4K\xf3&*\xcfB\xc5|\xd9{\xcdp\x0e\xbf\xff\xd3\x0b\xbc\x8a\xd4m\x1e~\xff\xa7W\xe5\xf2\x94d\xda\xe27\x98%X\x03\x0b\xb4< c\xcd\x80\x0f\xbf\xff\x93 \x90\x0e\xbf\xff\x13\x83\x94$\xd3\x80\xc9!f\\\xfb\xba\x9c\xcf\xb5\x03\xa4\x07\xe5pAH\xa1^\xd5#rY\x1ce\xfe\xec\xfdS\xddQ\xa9jh\x8a\x93rV\xad]Ur\xed\xa2+zb\x07\x945a\x94\xf89|\x05\x0b\xc1s\xc2\xf9\xfa\xba\x8aZ]\xba\x18\xc9~1=W\x18\xbcQ&4\x98\x9e)JN\x91\xacW\x95\x9c\xc0\x1e\x9cR\xa4\x7f\xaa\xba\x90\x80_\xc5'H~\x9e\xd0\xfb\xf7\xc3\x07(\xed\x13\x17f.\xa4\x8e\x0b'\xd3y\xfdn\xee\xc2\x19E~\xd33\xca\x80\xa5.\xa8\xe2\xd2 r]\xd2[=s\xe0d\xba\xc4\xcfC\xfa\xf9\xd2\x85l\xba<\xae\xc5\x9b0\x14a\xf7\n\x804J\xcb\xed\xfbj\xbe\x03\x11w\xe3\xbd_Q\x94:&n\xbc\xbd\xfb\xefv%\xff8v%z\x82\xef\xbec[e\x9c\xcf\x92\x14\xbdU\xda$\\\"\xfc\xf5T\x07\xa6\x123@2\xcd\x8e\x99R`\xe7\x01\x1a\xaff.\xfc\xa2\x97\xf6u\x98\xfaiv<%\xf4\x18\xc9\xf6\xf0\xca\x99\xe8$\xfeF\xd8\xfb\x0c\xed\\\x84\xb1\xa9/(\xa9\xf1v[\xc2\x92W\xc4V\xe35\xa7\xb0\xc6\xaa\xb8%*\x8d\xcf\x9c5\xdf\x16\xd4\xb0p%\xf7\xb7[\xaf\x03\xdez\x1b\x85,8\ni\xd7?\xe7\xef\xdb\xf6\x10K\xd6\xebN\x1b\xb5\x9c\xf1\xf7[\x8e\x97\x93\xd6\xba_\xb1\xb6\x1elvb\xe1\x9dr`m\x8f\xea\x84\xb7\xd6\x1e\xd5\x05\x7f\xdf\x1e\xd5\x01R\x9a\x95\x8c\xbeYx\x89\x85i\x96\xccH\xde\xf2D?\xc4\"\xae\x98k\x16=\x85=\xb0\xf8Gx\xceg\xf6e\xab\xd7\xf7f\x89\xee\x13\xb4\xb0\xdd\x83So\xde,xM\x0f\xc4\x9aY\xda[dW\x1a\x9eW\xe0\xc8C/#y\x12\x9d\x13\xbb\xbdz\xf2\x83\x1e\x1aM\xf6g\x8f\x1ea\xa1\x1e\xccS2C\xfcr<(\x1b\x96x\x88\xfd\xde\x85\xf7z\xd6\xf7\xba\xcb\xd2\x83d\xc7\xf0\x14\xfdQU|\x1c\xdf\x8b\xb7\xe4'F\xd9\x1e\x9c\x93\xb8p\x98\x0fK\xb1 \xb1\xfd\xde\x919\xb4\xa2\xd3\xcd5\xcc\xfcb\xb6\x00\x9cCK\xf9\xd6\x06\xbf7\xbdsF\x15\xb5V\xa8\xbcf\xaf\xa5\xf4\xbb\xe6d*m\xb5\xcd\xe21\xd0a;8\x85\xe6h[\xe0r\xd4\x87\xed@\xe8\xb9\x88w\xa2\x95\x88\xd02\xc4\xb7\xea\x0d8\xe7\xb6\xcb\xc4;\x99\xa9k\\\xe95\xaa\xf2\xd3\xe0.\x89wr\xcex\xcb\x11`\x8c\x9a\x93\x9c\xb1\x97\x9b\x8c\xb5\xac\x05K}p\xc5\x85\x995\x02M`\x1f\n/y\x0f\x13(\xbc\xb9\x1f\xf6\x84@\x87*A\x14?\x1c\xfd\xd5#^\x9d\x02\\\x7fm\x9649H\x96~\x18\xab\x17P<\xfa\x13,?%\xa5?\x124\x1b\x19\xf3\xb5[PP\xf9 \x89)\xfck\x0fF\x8e+\xe2\xff\x94H\x81\xec\xa1I\xb5\x8d\x81*f\x1e\x89\x0b\x92\xd9\\\xa7P\xda\x19\xf2\xe8\x98\xa1\xd8#\x97aas\x06\x7fm\xd3au\xf6\xd0\x1b\x81\xdbX\xefCd\x1f\xd8\x16?w\x1b\xb3\x85\x1f\xc60\xbb\x9aE\xc4B\n\x08Ma\xde\xd8\x14\x82\xf7!d\xda\xd2\x18\xfdK\"Z\x9cc\xc9\x04\"[\x91\x1dP~\x1a\xe7\xb2wYp\xfck>\x9f\x1f\x9fDd\xf7\x84\xdf\xbc6\xe0#\x88k\xd9t\xf8\xc8\x01\xdf\x8e\xa7\xe1\xfaz[9 ?\xf4\x90\xa0\x90\xdc\xad\x8e\xd5\xc8\x05\xd42\xaf\x89}z\xa9\x1b\x93\"z\xe6\xb5\xe9\xf8\xbf\xec\xc5Egl\xf1s\x03\xfd,\x1eD[(\xc4\xe5f\xfbxB\xb5\x13\xa5[\xfc\xbc\xa3\x80\xa9J\xe7\x14\x08(|\xc0C\xe0\xf0\xa3c\xea\xed\xa7\xde\xdeV\x85_54\xca\x80U-\xfa\xb7l7,\x01S\x05\x87\xa9\xaa\x02\xdf.v\x0b\x9b\x92u\x0e\x00'\x01J\xf4L\x0d>\xfa\xc6\x9dz\xd5\xbbv\xc2T\x8er\xaa\xddu)\xbc\x93\x00\xaf\x10\xfcA1\xbd\xcb\xd6\xa0\xf0N.hA\xe1x'\x94\xa2\xa7d\x85wB/\xc81\xfe\xf2\xc5W\xccG\xfdd\xc6\xed\x0d\xe9Eqd\x17(\xc40\x8e\xfc\xed\xb0\x91\xbb\x15o\xaeV\xf5\xac\xc5\xdeI\xa0\x03\x86\xb8\x9e\x14*\xcd\xf9\x9c4\xd7\xaf\xf9\xda\xa5\x9d\xb1\x1b\xb0:X\xf5\xe5\x073\xb4\xec9\xa5\xa7\x19\x89\x87\x00\xc2\"'\xd1\\\x97?\x8f>\xb8\xceo\xd0\xbcj\x7f(\xf1\x04\x12\xaf\xde\x7f\x17\x9e\\L\xc0\x90l\xb1\xaa\x16h\xd3\xb2\x8aGC\x95\x8bg\x18\xc5\"\x0c(\xe9}\xfc\x16/\x98\x11\xde\xcd\xaf\xf8\xef\xbb$\x03^\xb1\xbe\xb2\xde\xc0\xdb\x86\x9b\xdf\xa1wL\x05\xfe1\x03\xff\x11\x85\xef\xd8\x855\xddx\x87\x8d\x93\x8f\xcf<\x91\x01\xfb\xd7\xb3w\xd7\xda\xf9w\xe7\xdd\"2\xea\x1d\x7f\x8dg\xfd\xd0x`\x17<\x82\xe7\xa1\x0b\xe2PX.X'\x0b\xcbq1\xd4\xa9\x0bY\x9d\xc5\xbau*\xd4\xe0Cl\x04\x13\xd6n\x05)\xe2\xcf\x16r1.\xfa\xabf\xfe\xec\xe6\x97\xd5_\xd7.\xbb\xc4\xf5\x93d\xd2>A\xd9\xb1\xbf\xe4\x9b\x97\xbd\xc9e f h?\xfc\xeb\xbcSy!Wf\x84b= \xa7i\xdeco?\x189\xf6\xa1l[\xdb\x1e\x1f\x89\x07\x84\xfa\x17\xac\xdc\x13{)v\xcd\x9cS\xfc=\xec)\xd9T\xa6\x7f\xc6\xb3A\x19\xacf\xad\x9a3G\xba\x97br\xce\xfd \x19C\xefb\xfe\xe7\xa4\xb5&\xb3*\x07U\xb5\xc6\"Y\xcc\x89\xdf.\xcbi\xd9\x11\x9f\xc7\x1a\x05\x93Xp(\xcd}n\x9e#\x04\x97\xbe(v\x92\xc5\"\x13!\x88q\xeaa\x88kG{\xe5\xd41\xb9\x80\xecQ\x17\xba\x04U\xc8n\\\xfa\x86\xdf(\xa8'}\x8b \xd5GNU\x84Z\xe6=v2\xb0D\x86\xe6SoNwy\x88\xb2\x98\xe0\xcdv\x88\xdb\x89?}JA\x93\x0b\x16\xf4m\x82\n\xf5\xc6$\xe7\xf6\xdc\xfb\x13\xac\xc3\xdc\xfb\x01\xff\xff\x0d\xfc\x11\xd6^\xb7\x01\xf2\x8d \x8a\x0e\x1b\x1f3\x13S[\xc6\x15\xdc\xfe}\xec\xd8\xf2+\xa6v\x90L\xe0Y\xc7\x87\x8d.%|\xd3\x9e\x1b]\x9e\xbeM\x16\x04\xd2\x13\x15f\x02I\xf4\xb4\xe9V\xdc\xbe\xc3\x14\x16j@\xeb\xacS=\\\xbb\xa4+\xbc\xf6\xda1\x8e\x1a\xf7\xbbo\xd8|T\x17v)\x0eG\xb5o\x870\x81>\\\xd7\x19\xda\x9a\xfd\x9a\xc9\xeb\xb7\x1fl\x99\xa2\x85\x1ez\xcc\xea\xd9\xc3\x13d\xbf\x97\xc1\xc24-?\x8a\xfa\xa6$\x93\xaa\xea[\x8fa-\x9d\xf1\x10\x8b\x86`\x14\xdf$\xbc\x8a^d\x13\x0e\xe7T\x05\x1e\x9d\x1a\"4\x03o\xd2\x90$\x1f\xb8~m\xa4\xa7\xb1\xce).\xa7\xd7\xc8p9\xeb9\x0f\xb6\x14\xae\xaf\xf7S\x80\xe8!a\xe8\x1f\x90\x98F\xcc\xcbP =\x9b\xeb\xebn--\xa3\x10\x81(r\xf8\x08\x01;\xa6\xa4E.\x88\xf4iy\xcc0\xdf\xc6\x062\x18\x99\x1d\xf7Q\x85Z\xa6\x198\x98KM)\xeb]\xeb\x8f|\xe8\xa1-Ub\x87\xde\xf9\xd0\x8b%\xf3g\xbdg\xf7\xae\x00]\x0f\xc5\xc9\nP\xbc:luw\xbd>v`\x90\xe6i\x93\x08jw a;\x90\xd9\x89i\x07$\x14\x84?o\xa4\"dB\xaf\xf6\xd4\x91\xc7\xb4\x1b\xb6]\x05\x8a\xed\xb9\xaasmo\x0f\x98\x84\x07\xc2\xb8f\x0dk\xa7\x8f\x18\xd6\xc1\x9a@\x18\xcf\x92,\xa3\xb7u\x18\x9f'34K\xd2\xb9\x9a\xdd\xdc\xbe\xb8\xa3\x02\x14z~\xb5;\xf7\xf6}\x95\x9f\xbc\xc2\x86\xbb\xe4f\x01m\xcdc\xce\x9bi\xdb\x02F,\xb0W\xe3\xdd\xac\xe5C\xc2u\x1c\xa6\xdd\x98\xbb\x90\xaa\x08\xa8\xc0\x85\x85\x0b\xe7\xae\xb0\x07Ia\xbf_2\xd4Y\\\xf1\\\xa30Ze\xff|\xc5|Fq E-p\xeb\xd4;E\x13\x96\x0e\xdc(I\xe6\xb3\x9b\xfa!\xa20\xd5>sT\xf3C\x9dJ\x802|a\x9d\xe0<\x82\x00\x1e\xc3\xe9#8\xd5Y\x9a\xa2\x95\xe9\x92\x07\x8c\xbd\xb2}\x9b2#dzz\xecL7\x8f]XLG\x18+\xf0\xca\xc6wN\xed\xa7\xba\xc4\x9f\xb3\xca\x0cu\xd9<\x8ej\x13X\xa6\xf7\xc1da\xdcq\xea\x11\xaca\x97\xe7^L.\x0b\xdbq\xbc \x89\x89\xc6\x1a\xb7\x1alb\x9f\xbbp\xe5\xc2\x82\x07\x82\x82b\xd8\xd0\xae\x1d\xef\xeb\xb7\x07O\xfeL\xc9ezq\xbd=8z\xf7\xf6\x15\xec\xc1l\xb5C\xb6\xd3o%-\xe07\xe90\x90JFW\xe0:\xd8\x87\xc2\xa6\xf7\x14.\x7f\xcc\x97\xbfh_\\\x15\xafk\x8c,I<\xd6\xacB\xe6\x87\xe0'\xe1\xaf\x90\xa1\xd8\xb0rhs\xdb\xfa\xc6?4\x7f\x0d^\xab\xae!QR\x1b\x99Hf\xa0M@7Y\x98\x0c3\x1f\xe1+*\xcd\x11\xaf\x11;cv3L\x8c\x87\x86W\xd3\xe4\x98\x0b\xf5n&:\x8d\x1c/a\x98\xc3NuY\xa1f\x0b?\xf3g\x05\xc9\x9e\xf9\x85?Q\xba\x94q\xfb\x9c\xde\x85H\xbd\xc0/\xd0j\x8aNe\xde\x03\xdfJ$\\\xf5\xa1\x9a\x85'\xde\xdc.\xd0TOA\xf0a\x82\xb4\x12\xb9\xe0\xaeK\n\xac\x1aX\xa5\x90\xe3M\x88\xa7u\x14nLo\x18\x89\xfc\xa4%U\xed\xde\x7f\x82Y\x9b\xde?\x9ef\xc7m,\x1br\x16\xae\xef\xec'M3y`\x13`,\xd4\xac\xd3q H\x04\xe3\xaaB:\x1d\x1c\xc5\xd3\x12t\xfc\x01\xb8\xf3C#t\\fg\xde\x1bX\x87\xcc{kP1\xcd\xc3\xd8\x8f\xa2\xab\xa1\xd2w\x9f+\x8d\x93*j0\xe5\x88\xc5\x1f\x1a\xd1{\xacSr\xab\x92\xd9\xb4\xd5\xc7\xb1,\xa7\xd4\x1ab\xf3\xcfJ\xcchj;m\xbd\x8a\x89\xcc\xeal\xb4\xfc\xa8\x8c\xcb(\xebF\xa9\x8b\x8f<.\x86`V\x1b\x96^u\xf9\x11\x81\xb7\xebP\"\x02\xf7l\xb7\xc0\xf1\xd0\x00\x88E6\x18\x08\xf1\"\\\x84\xb9\x01\xdcB\xa5}\xad\xd0J\xc7\x1eACwn\x0b0\xa9\x953\x8e\x1d\xa3\xd2\xa4_M=dAc{\xfb\xc1}\xae\xa5\x7f\xc0\xff}\xd8\x8cj\xc7\xc3co?\xe4Q\xed\x1e\x8a\xf7;\xfc_\xfe\xfdC\xfe\xfdC\xf6\xfd\x0e%G\xf0\xdf\x11\xffw\xcc\xff\xdd\xe2\xffn\xf3\x7fw\xf8\xbf\xbb\xfc\xdf\xfb\xfc\xdf\x07\xfc_\xde\xde\x88\xb77\xe2\xed\x8dx{#\xde\xdeh[\x19e\x8f9\xdb\x0eY\x8b^0\x1aw\xc2x\x87U\x90J\xbc\x92\x9f\xf2\x10\x8f]\x94(WJ\x02\x82\xfe\xc1-\xc8CD\x88\xe6\x04k\xcc\xd0}\x84\xf1V\xaa\xa0\x19Ul\x91\x0e\x82\x94\x1b\xed\x83\xd0:o\x9f+\xb4\xdc8\xe9n\n?_$\xed{\x0c\xbeVL\xc0\xa2\xc2\xed\xc1z\x9d\xc8\xcf\xc78; \xc5'\xa3\xd1h{4\x1a9\"v>C\x18o\xfd\xf8\x8c\xebH\nYG\xe2\x03\xa6\xb3\x84Y\x12\x10H\xe9dtv\x96\\i]\xc0W,\xba%\xecc4 \x0cy\xca\xa2_\xae\x83m\x17\xb0\xb1\xc7\xca\x1dx\xfc\x18\x10~\n\xf8\x0f0\xda\x1co\xc3:\x8b\x99\xd9\x9b1\x17$\xfc\xcb\xb3\x0c[\xb7\xc3a\xbd`\xa6\x8b\x1b4\xda\xdcR`+\x0dPd\xfe\xc5pP`\xb15\xbc\xcc\xbf\xe0LiX\xcbnM\xe0A\x81\xa7d`\x12\xc3c(\x1f9\xc0-\xb9x\xe4\xd6bZ\xae\xaf\x1f;\x18F\xe2+&kiV\xa8\xc1\xa6<6X\xab\xf9w\xb3\xf4\xea\xeb\x83\xe2\xacM\xc7\xb6\x8a,\\Z&\x85y\x9b\x9bV-\xaa`\x059\x15\xb2u\xbb\x01\xf7\xc2\xca\x8e&\xd6\xdf\xa6:\xbc\xd4\xf6\xc3\xf6{\xba}\xd6\xd4\x82u\xf0YD\xce\xaeXS$\xdb\xfa\xff\xd3Z%\xff\xcf\xfac\x9b/\x8a\xea\xaau\xa5/\xda\xb5f\x03\xb8o\x90\x85\x12\x8aT\xb2\xc0\xc7\x1d\x0e#S\x04k\xb2\xe6O\xc9\xb1\xcd\xbc\xf3~\xfb\xf5\xff\xf8\xb7\xff\xc2\xe2\x9d\xf2\x9fX\xa6l\xe3Zs\x8b\xd3\xb5I\x98;s\x89J\xbe9\x86\xe3\xed0\xca\x807\xfe\x97_\x82\x9dLcZ;GWnA\xfbR\x94_\xca\x07\xb9e\xf9\xd2Z\x809\xec\xc1\xcc\xa3\xb0\xda\xc7\xa0\x81\x04\x8er0eT\x05\x8e\x803\xef6\xe1jE\x96]-w\xc1\xc2\xbc\xeccM\x85HTh\x11\x1ej\xc1\x82Z\x0b+\x8fT\xaem\xfdX\xfc\x18\xffx\xfe\xe3\xfc\xc7\x0c\xfe\xed_\xff\xeb\xff\xf5\xeb\x7f\xfd\xd7\xff\xf3\xb7_\x7f\xfd\xed\xd7\xff\xfc\xdb\xaf\xff\xc3o\xbf\xfe\x8f\xbf\xfd\xfa?\xfd\xf6\xeb\x7f\xf9\xed\xd7\xff\xf9\xb7_\xff\x97\xdf~\xfd_\x7f\xfb\xf5\x7f\xfb\xed\xd7\xff\xfd\xb7_\xff\x9f\xdf\xfe\xf3\xff\xfd\xff\xfe\xfa\xeb\x8f\xe5xs\xfc\x00\xff\xff\xf0\xc7rN\xe6sk\xc8\x19\xbb!M9\xde\xde\xc1(n-vF\x8f\x91g\xe2\x8a~\xd2{I\x0b\xd5q\xafm\xf3 $r\xc3 \xea\x02\x8a\x8d:\xe1%(n\xb1,\x8f\xc4\x01\xe6_Q1x\x14\xc8\xe9\xa7[\x8em\x89z\x96\x81\xa6\x11u\xfaVJ\\_\xa1X*\x17\xe4\xf6\x95\xe76V\xdcg\xf0\x18F\xb0/\xa5#\x1e\x1d\xd7\x06\xcc\xcaV2\x96\xf1\xc7\x1c\xd3\xacl\xe9Iy\xee\x1b\x11\xf9\xddN\xd0\xe493 \x18~j\x0d\xbc\x82O\xc7\xcdM\xe1\xd1\x0f\xb3DM \xf7\xdc)a\x03\xeaK\xbbd6\x15\xf9\xef\x02O\xf7\xc7J\xde_\x06\x8d0\x9eEe\xc0\x82]\xe8@C\xd4\xe9\x03\x8d\n\xed\xff\xa7D\x02\x8e\xba\x07\x0fS;\xbd\xc6\x08\x91\xab\x80\xc3\xed\x0ecc\x99\x06\xe3\x8e\x8c\xa4\xc4/&x\x83\xef:+v\xd9\xb7_\xa3\x91\x96\xb6\xb8\xa9\xb4\xb8\x0e\xdcO\x99`\x05x\xa3\xc0E\x91\x89>\xe4\xf1P[\"S\xf48\xe5a\xfaC\xd8\xdb\x83\x11\xdc\x83M\x05Ca=M\xca\xb8\xa8\x1d\xb7br\xe6\x17\xe19is\x12\x0f/\xc9\xdd\x0f\xbd(>\xc9\xd8\x93\xb8\x98%\xd1\xc78\xb2\xb4i:|\xd1\xfc\xc7<\xb6\xb4\xaf<\xfc\x99|\xbcY\xf0\xd6?\xe6$\xc2\xc2\x8f\xc2Y\xbe\xd2\x1c\x86L!\xfc\x14\x80\xb42\xf2\x19\xb4\xfa\x88\xf6\x17\x19\x99\x7f\xe4\xa5\xcf\x97~\x14\xad4\xfc!\xa3\x17\xad~\xf4\xc5\xa7\xef\xdf\xaf\x06\xfc\x83\xc6/\x9a\xfd\xf8\x13(O\xef~\xf4\xe5'\xc1\xfey\x99~\x84\xa1\xa7w4\xf4\xd8\x1e\x8d)\xb9\xbc\xf4\x8b\xd9\xc2rad\xae.\x0dfZ\xd5S\x8a?\xd5k\"\x1e\xc1\x19\x10\x93\x921\x91e\x0f(z\xa8\xd2\x99\xc5\xd3B\x9f\x19C2\xafO`_\xd8\xe11/\xaa \x9a\xc0q)o\xecL\x8bc!\xc8\xcf:qA >\xbe\xe1jrQ\xa3\xe5\xc2\xf8\x06\xeb\x99)<4`\xd0\x92\x86}K\xea7\x964\x93\x974\x1b\xb8\xa4\x12?\x91a\\\xb3\x04W\x95\xbd\xe1k\x19:,N\xd3\xdd\xadhN\xfc\xec\xdf\x01\xf4\xee\x963\x8d\xc2B \x9e\x1d\x03K\xfd: \x0dGl\x8fw\xda\xbe& D!\xdd\xd7L\xef\x86J\xb4\xae\x90\xc4\x9a\xa1\xf1\x8a\xe5\x9f\x9e\xce,\x9ew\xe2\x9e}\xea\xfc\xf1\x9eC\x99\xe3\x0f\x1f`\x1bu\x1e\x05\xc9\x8b\xba|\x7f\xe2\xdcsac$\xc2:\xd1zc\xac\xe7\x9f\xca\xb5|lH\xaa\xc4\x1a\xf3\xea:\xde\xbeC\xffkT\x92\xcb\x1d[*\xa3\xdc;-\xaf\x8a\xbd\xfd\xaaP\x05r\xe7\xdc\xf7Y\x12\xa8\xde\xb3\x9d\xfd\xfd{\x1e\xb9$3\xdb\xb2\xe8\x1c\x15P3DO\x02\x92\xad\x9a\xd0]\xaa\xe3\x06@\xd3'gOx!\xf14<\x95%\\;\x95\x8a\xfc\xedZ\"\xa7_\xab\x83\xe8\xe1\xe8\xd4\x9f\x9d3K\xff\xdc\x85\x08\xc3T\xcfY8}\x93\x93z\xc0B}\x86gq\x92\x91\xa7>\xc6\xf6\xb3B\x0b&\xf4\xda\x83uZ\xb6,\xa3\"\x8c\xc2\x18\x8b\x96\x8d\xa22\x0eQ\x11\xbf\x0fV\xd9(\xc8\x8bp\xf6\xfe\x8a\xbe\xbf\xe2\xef\xf5CX\x98}\xe4\xcf\x9b\xbbY\xc0>l\x8f\x1fn?\xdc\xbd?~\xb8\x83\xe6\xfe\x8f\x1f?65\x80\xd1g\xeb\x03O\xbc\x1c\x83\xa3\xbb\x10\xc0:Xg:\xfb\x01\x94\xfea\xd0\x06t\x8e\x90Z`J\xce%o\x876\xf2\x85\xbd\xbf\xf6\xe3\x8f\xb9c\xb9\x10\xa84\xd4\xd5\x83\xfe\xeeK\x06\x8b<\xbe\xe7\x9amG\x18y\x0cE\xcd\xb0\x0e\xf9t\xf3\xb8\x82\xf0\xc7\x80\xf1\xd5\xec\x94\x07?\xe12\xa5\x85+>p\x1c\x17\xd6\xd0\xb6\xbf!\xf1\xc2\xa4!\x9b\xc7\x95F.s\xcd\xe4O\xe3\xc1\xa9\xcf1.\x01\xcc\xe1\xab\xae\xe4{\x03\xc6\x8f`\xbe\xbe\xee\xc8;S\x8b\xd8\xe6h\xe8k\xe3\x8f=\xa5D\xbc\xf1\\;nw\xf0|9\xbe\xaaC0\xa2]\x00s\x14J\xe9\x07l%F\x0e\xcf.!-\x1b\x8b1\x1f\xb9\x90V\xad\xee\xc1\xb9\xe3|\x00\xbec,\xa3O{\xfb\xe8\xa0\xeb\xc1\xc19\xecC\xca\xcb6]8\xc7O:#hY.3\x8f\x06kS\xa0F!\xd3\xdct\xa4\x15\xb3\x07a\xb6\xe6\xa5\xd9FW\xb0\x0f\xd3c\x98\x08\x1cT g\xdb\xdc\xa0Z\xcc-\xd1\x08\x1a\xa2\xeb\x06d\xd5\x8d\x08\x01\x89\xac\x8ak\xb2*\xeb\x90U\xb1\x8a\xac\xcaV\xa5\x03\xcc\xf2\xfa\xd4\x8e\xed\xedQ[\xec\x9c\x88\x92q\xbb$\x14%;\xed\x12\x9f\x97\x8c\xee?h\x17\x95\xbchgk\xb3]\x94\xf3\xa2\xadNO\x11/\xb9?\xden\x17\xcdz\x03\xf7U)\x98\x88wrB\xf2\x97IPFD\x97C\x14$\x99\xff/\nW\x10\x8c\xbb\xc7r\xe2\xe9B\x99\xd5\xf9\xdex\x0c\x86v\x8a!o\xe1\xe7\xaf/b\x91\xbe\xb5\nC\x17s\x95\x0d3\xb6 \xdd\x84oP\x83\x10&\xa6\xf3\xcb\xa8\xe0\xa1\x99\x9a\xa0A7e\xbb\xb3Ts\xae|q\x1e\xfd\xa1z/\x96\x0eR-\x8b\xdaY;\xcc\xf4<\x18Y\xa3.E\x92\xd6Y0\xde\xdd\xd9\xdd\x1c\x05-E\x1b\xbdv\xad-o\xf4\xc0\x1b\xb7J\xe8}j\x9d\xfa\xf1OI\xab\xe0\x8c\x16\x1c\xfa\x85\x0b\xe3\x1dxR\x9e\xc1xs\xf4\x006\xefOv\xc6\x93\xf1.\xfc\xe9\xe5\x91t\x10\x86\xe9\ns\xb1\xf4\xde9\xc9\xf20\x89s\xbc*;/?|\x80_\xae]E\x89\x97_\xf8gg${\x17*\x9d\x97x\xb5 (\x02\xdd\x9e\x85\xc5[r\x1e\xb2\xf2\x85\xb2\xfcY\x98\x15W\x13\x08\xba\x85\xa7e\x18\x05G\xe1\x92\xe4\x85\xbfL'p\xd6\xad\xb2\xf4g\x8b0&\x93v\x0c\x85.\x07Ph\x1d\xaf\x82dy\x12\x06,\xcf\x94\x1ao\x06\xc9\xf2U\x12\x10S\x95<%\xb3\x89\xde\x88*\x8b&J5,/\xccMMG\xfeUR\x16\x13\xb0\xbe\xf6s\xf2\x02\xff\xd0\xb4\x14$\xb3\x83\xcb\xd4\x8f\xd9r[Q\x98\xebj.\xfd\xcbg,\xf5( \x8e\xfc3c\xff\xf30*Hf\xaa\x81\xe6\xa4~\x91d\xefp\x9e\x8b\xa2H\xf3\xc9\xbd{IL)^\x01=^\x98\xdc\xab*j\x86\xc5|\x97r\xfdB\xce\xca\xbcH\x96\xfar\x9eO\xf5uJX\xea\xaa\xe7A7\xa9N\xab.\xcfz\xf4\xac\xd4%\xbb\xaa\xea\x13\x92\xbe\x08\xe3\xf7a|\xa6\xaf\x94\xb1\xd6\x9e\xc7\x05\xc9f$-\x92\xacOc[\x7f\xc9\xb0\x97\xb2\x82f\xba\x19\xc9\xd3$\xce\xc9'\xea._$\x17\xe8\xd3M\x02\xbejj\x073\xa8q\xeb\xcb$ \xd1[\x12\x07$\xc3u\xb3\xc8\xa5\xbfL#\xa2\x83`\xe9+\x04\xe5\xe0\x19I\x8b\xc5\x04\xb4{R\xd7\xcf\x87|@\xa7ppY\x10<#\xb9~\x1fi\xbd\xa7\xc9r\x99\xc4\x83j\x97)\xc5\xc3$8,O\x97a\xc1\xa2M\xe4\x13\x98Zg\x04\xd5.i\xc9\xfeIr\xfc\x97e\xd1\xa5\xbf\x92\x94nU\x8e\xfa\x01\xe2\x07X\x89\xcb8\xad\"\xf3g\xc4\xd20\x9eiFrR\xd0>\"\x81\xb0u51C\x17\xad\xa9\xa9\x10\xc6a\x11\xfa\xd1!\xddX\xfd\xd1\x9a\xc7\x86c\x99,\xd3$\xa6|\xcb\xa4\xed<\x05jp\xa2\xfc?%\xd3\xe7^\xeag99D\xb9Y'M p\x82\x89x\x1c\x057\xf1:OF\xac)\xa5X?\xe5\xdd\xf8b\x8d\x1c\x9b\xdeq\x05\xd2\xde\xb1\xa2\xb7+\xed5\x91_\xe5\x05Y\xaa\xc8\x08\xf1T\xd8+\xf5\xf8\xcfU\x0eW\xb5M\xa9\xc7\xf7V\x03kl\x9b\xda\xb3\xd2\x8eJ\\\x1ff~U\xd4J=\xf6K\xdd\xb7x\xc4\x95\x90z\xec\x97\xb6\xb2f\xaeP\xdf\x98\xc6~X\x1d\xdd\xc5)\x1e\xbc]S\xaf\xcc\"\xfd84;\x01\xa9'C\x7f\x97@V\xc4&\xe8\xfb\xa4\xa2\xa7O)=\xdd\xaa\xdd\xfa\xbbEZ\xdb\xa7HRK\xfdS\x15\x9a\x078`\xb2\xdc#\xa5\xc0\x86\xb0\x073\xc7\x85\x13/'\x05\x1bCn\x97\x8e\x0b\x17\x02;=\xc1\x99\xe7^\x94\xf8\x01 0\x8fI\x9d=\x9d6\xb5\x16\xd3CE\x7fZ \xf2\x84\x16KQ\xb0\xe9BX\x8f\xb2\xc4y3^p\xd3\x85\xa4S\"%|ck$:.\xd3\xc0/\xc8\xbb,\xb2-\x0b\x07\xd6-|\x91\xf8A\x18\x9fQ\xe8/s\xdb\xca\xcb\x19\x06~\xd1\xd4>L\xc9\xcc\xa6\x83\xc8:\x83\xc0d)\xcdo\x82\xe4\"\xa6s\x07\x0c\xea\xc1g\xaa\x1d\"\xd6\xe8\xf4+\xda\xe0\xc5\xe8\x81#6\xc0\x81\x0b/C\xd2\xa7\xde\x14\x17\xac'i\xaa\x93\x97V\x91J\xb0\xfeI\xa8\x0d\xcd\x0f\x1c0s9\xb2\xc6\xdfK\x92] \xf8\xab\x9b\xd0\x8bR\xab\xe1\xe5bXj4\xc9\xa3\x89P\xe0\xc0T8\xbceL\x06\xd0x\x89`\xf7\xe1\x03\xf04\x1e\"k\xc7\xe1\xfb0MI\x00YM\x07\xc6 \xfc\x0bk\xe5_ \xc9\xf07\xfd\xf8_\xe0\xc2\xcf\x11\xed\x87\xf3\x90\x04\xbau\xe2x\xe8\xa2\x8b\x18\xba\xe7\xeb\x92bB\x0e\xf2L\xa6\xc8~\xbf\xcb\"\xa5\xac\x0d\xe5\x98\x8dM\xee\xbc\xa0G\x9b\x9d\xa8\xaf\xaf\xdeq\xb0Y3\xd6\xf8\xf0\xc1\xd8\x82\xe2\xfa\xc6K\xed\xb2;\x1d\nlo\xc92)\x08\xfb^M\x81\xab\xd8\x90\xd4\xeb\xbeU}\xa9`)\xe8\xa7\x9d\xd7M\x1c\xec\xc2\x01fb\xb0\x8d\xf3\xbc\xa4\xd5\\\xb8\xa0\x87\xf1@r\x03\xba\x96\x91,\xe9\xa5E\x1c2\xe1\xd8\xde\x19=\xe88\xf0\x8ev\x1c\x8f\x8b\xfd\xde\x93\xab|HC\xf5\xcau\xac\xa0\x99\xb6\xf5\xe1\xae4\xe1\xd8\x1e\xef\xdcwx\xbaM\x03\x95\xd1631\xbb\xed4\xb3s\x03\xacnX\"/C\xb3\xa3J8\x18\xdb;\x9d\xc0\xb0\xb5pq\xd2\x9fb\xb3\xb3\x03\xdc\x83\x1b\x1d\xbe[\xfbp\x7f\xdb\xf1\xe6rL\x94!-\x0e\x9cD{\x9bn7\x89\x9d1\xf3\x07\x1f\xdd\xe7~\xe4c\xeeW>\xbe\xaf\x04\xaf\xc3\xab\xe5i\x12\x0di\xbb\xd7J_\x9d\x8e\xb7\x13\n\x83G\xe9m\xe7\xb2\xe4\x913\xda[\xca\x83\xf4\xee\xb4\x83\xf1\xf2\x19\x8c\xb7\x1d\xef\xcf\x07\x7fk\x96\xb1\xd4\xa1;\xed\xf1\x88\xcc\xa1\xed\x011\x81\xf6\xc3vX\xa1\x94{\x87\xb4\x8d\x13x\xea\xd0\xb6O\xc2\xa2\x82\x94\xe6\xfbs\xfe^\x9d9tg\xdc\xae/2\x87\xb6'\xcc\xb2\x86n\xb5G\xc3R\x86\x8e\xdb\xb5Y\xc6\xd0N\xdc\x87\x0b\xbe\x9a\xed\xb9\x1e\xb0%h\x8f\xf1\x92Wo\xcf\xf5\x90\x8f\xbd]\xff)\x1bL'X\xca{\xb6\xe5\xed\xd7O\x04Bj\xbe~\x0d{\xf0\xb4\x9d$\xf4\x0d\xec\xc1\xfb\xf6\xcb#\xcc\xfb\xd9z\xf9\x12/\x08\x06\xd7\xcd\x92\xe7\xd5\xd5\xd1|\xff\x13\xec\xc1sJ.<\xafQz\xb3\x06\xbd`\x02\xdb:Y\x84A@\xe2\xb6\xca\xff-+-\x927Y\xb8\x0c\x99\xbfM\xb3\xc63\xd4\x03y)g(\x9f\xe7\x07q\xb9d!\x91\x9b\x15_\xd0\x1b\xd2\xb6r\x1c\xfd\x06c\x05\xb3\xabvs\xef\xe4Z\x9dd\xc6\x7fg\xa5I\xba\xa1\xa9\xf0\x0d\xecu\xb4I\xcd\x1a?\xeb\x02\xc2\xbcl\xd6\xfb\x1aW\xf4/\xac\xb1f\xd1\xf7\xb0\x07k_cf\x88\xaf\xa5\x8c/\xad\xbf\xbdy\x18\x07O\x17a\xd4R4|\x0b<\x82odvr\xe6w\xce}X\xdb\x83K\xfb\x0d\xf2fh\xd7\xab&\xd0\x87\xc5\xd8\x82\xba\xe17\xb2\xad\xb0Y*\xc2\x93,\xdf\xd7V\xbav\xbcn\xd0#P\x8aA\xae\x9dv\xddkG\x0eg\xa3\xb1]\x03 !\xbf\xb6\xbfQ\x9b\xd3d\x92\xac\xe2\x9biq\xec\xc2\x9b\xaa=\x1e\x10\x92 \xb7\xf9\x0d\xfd\xf9\x06\x9b\xe9\x04\xc0\xbf\x86 \xbcin\xd9\x0f\xbd|\xbb\xe0\xd9\xdf1\xaf\xf1K\xfbe\x0d\x08&\x1d%fL\xef\xaa'\x9b\xdd\x7f\x07{\xf032\xc5\x0c\xea\x1bP\xeb\x89\x9b\xbb\xb1\x88\x06\x80R4B:\x0b0\xa8\xa5F\x94\xfd\x97\xa6\x19\xfcm`l\x80\xaa\xe1=\xb1I\x7f\xb3\xff^m\xe0\x15\xcb\xe2\x02{p\xc13\xd6\xd1w\xb4$\xb1\xdf\xa1\x91\xc4>\xc6\xd7\xa9\x10\x10f\\\xa5\xfd\xbdby\x85\xa7\xaf\x8e\xa7\x053s\x11\xbf\xf7x\x0e\"\xdc\xb4Xw\x10\xea&)\x17\xb1\x89\x89\x8bT\x90\x0d\x93\xba\xc3\x0f\x1f\x18\xf4\xbdr\xe1\xc0\x1ea6uJ\xa6\xd4\xfd\xd2\xe1\x7f[\xad\x06\xfd\xb6\x86V\xd3b\xfey\x88q\xc8\x95\xd2\xf5\xad\xd6\xbc\xb3\xe0\x1fK\x9e\xe8\xb3\xa0CKXj+\x16e\x97IP\x98\x1fe\xf2\xc8\x81\xbf\xa1\xfe\x1d\xc3\x05&\x18\x06\xa60j\xdf\x8d)7\xfe4\xf88=k\x18\xaf\xe0\xc6\x13\x96\xaaP\xdb\xf3\x1a\xd6\xae\x01\x08A\x83\xe5\xf7\\K(0\x11f\xc1e\xaf\xd9\x05\xa2\xec\xda\x17\x9f\xff\xf9N\xfc\x16%\x0cz\xe8o\xbay\xe4\x18\x0b\xdbv4\xcd)~1d\x8f\x98\xdd\x05]\xff.\\\x0b)\x11\x89\xa9\x9e\x94\xff\xc8\x11{\x82\x87\xcd\x17\xb3\x8a9\x04\x7f#v+dSz7-\x0c\xe70l\xce\xaa\xae\xf73nmi\xdb/M\x81\x0d1\x08\x14=N2\xa2\xef&\xc4\xb0\x18IZ\x87{\x92\x92\xd0w\xf2b\x9c\xf3\x8cj\xa9\xca\xebw\xb3\xe1\xf5\xbb)\xf9\xe6\xbb\x9d)6\"B*\xaf\x13\xe0Y\xdajl\xc0SZ\xfe\x9d](\xcd\x03\xce\xfe\x9a\xbe:\x16\xf8\xc2\xae\x8f\xbc\xb8'\xbe\xad\x0d\xe9\x10\xa9\xab\xd2\x1d]+\xa5|H\xf2}O\xff\xf7-\xdd\xc3N.@\x18\x14I5\xa7T^\x8bXp\\\xf8\xa1\x99\xeeM\xce8h\x15I\xe5\xe3\xdd'\x04)0C\xdf\xfb?\xc8M?\xc5\xa4t_\xb8\x94E\x81=\xf8\x1bF\x90\xdby\xe8\xe0_\x87\xf8\xff\x7fF\xae|\xbc\xc3\xde\xfd\x89\xf1\xe8\xbb\xec\xaf\xbf\xf2\xfc\xc6k\x94\xdf\xdc\xc6e-\xe9\xfc-\x15\xc3`\xb9\xf4kD0\x0b\xfc\xbaWR\xf5\x83\x1d4$2t\xc4\xbe\xedc\xaa;\x1fS\xdd\xf9,[\xda\xcf\xed\xf5f ;\x91\xe8\x16Y\\V\x1d\xe7\xbfPva\xe1\xe7\xcf\xf9\x01p\xc3\xfci\x12\xcf\xfc\xe20\xcd\x88\x1f \x9b#(0\x17\x9d\x85\\n\xbd\xeb2\xd7\x0c\x97\x07\xe8u\xd1\xde\xd3\x958)W\xec\xcc\x91\x7f\xe6\x96q>KR\xda\\.LC-\xd7\xa2\x17\x01a8\xe2/\xf5!!\xe4\x91\x03\x81\xfd\x97)!\xcd\xb4\xe65\x12\"\x98\x8f*\xf0\xf2\"\xc9\xe8\xe5\x12\xf3V\nR7\x13\xd3f\xce\xed\x82L\xe3V;t\x05\x0f\x1bk\xc7Ox7B]\xbf\xfdG%;{Ao\xb5\xf5=\xb47\xdf\x87\x17\xf4TM\xd8?{\xdd\xe4\xea-\x04\xfc\x9e\\}\xd3\xdf\x15Z\xe0\x7f\x87\x16\xf8\xc6\x9c=>0\x1a\xb8\x83\x9b\xa0\x19<-\x8c\xe1\x85ZCA{z\x81t\xdc\x9e\x9c\xba\xc3H\xc6\x9799$\x05\xaa\xb1\x8d|\xda\xf7\xaa\xf0\xc0\x9d\x96\xc2e\x1a\x91!-5\x93\xcd^w\x8eJk\xa3\x19\xc3\xdb\x8dq\x84A\xd4\x07$+\xedZ%\x17\xb0\x0f\x976\xa6\xa5\xfc\xb3}\xc9h\x1d\xe3f\x07d\x1e\xc6D\xa8\xa8'\xf07CqH\xf2 \xfc\xb9Y\xe1\x8c\x14\x92\x8a\xfb\x19\xc9gY\xc8\xd4\n_\x98*\xbe\xf2\x97\xb4\xb1\x7f6\xd5a\xc7 \x9f\xc0_\x1b\xeb\x88\"\x96\xe6b\xdakx\xc5\x1a\x98|q\x11\xbel\xc7<\x16\x8c\xda4.\xa3\xe8\x18c\x99\xfdd\x0b\xba\xd3\xfa\xe5\x9a\xbf\xe9\xae\xbd\xdf1,m}\xc26\xb7\x851\x1d\x17\xac\xef\x0e_\xbfR\x04\x01\xa9\xb4\x0c+\x10?\x9cd#\xc7\x8c\xa3\x18=R\xc5\xe0\xa1,\x05\xa7\xc9\xea\xeb>ib!\xf1\xf0L\xde\x9c \x1a\x1d\xbb`\x9f\xda\x9d\xa4n\x9c\xc4\xffN\xf6\xbf9\xe3\xd5\xecb\x089.\xfaRJ\x87X\x987\xa44;\x06\xf5\x8eK\xfb-\x1c\x0d\x1a\x00\x0e$t\xect\x1a.\xfc\xc4\xb5*\xcf\xbb\xc2\x87\x06XIB\x84\xe9[$\xc6c{g\xd3\x91\x85\x0b.\xbcm\xd4cI\xb6^\xcf1_\xe8\xcb\x1aq\xb3\xbf\xfdb\xe1\x82E\xff\xb1\xf8=;\xe7j\xa6\x1a\x06\xd66\x07\xa9\x00j\xe9xG\xca)\xa2B\xa9\x93\xd8QBaU\xbd\x94\xe0\x073e\xda\xb7\x98\xc5\xe5\xed\x1a\xce(2HV\xa0\xea\xbb\\\x00O\xf1\x11\xed=\xf4\xe6,/\xcb\xe6#(kH\x8d\x1e9\x90W\x16\xe8\x94`/\xa7\x11\x12\xe5HN2\x10V\x1f`Ia\xb8\xda\x8av\x84\xdb\xc2\x9b\x90\x92]\xdd5\xfd\xe5\xda\x13\xa4D\xb3\x10\x83\x03\xd5\x86\x14\x02\x96/\xc28H.P\xc9\\\xfd\xe2BS\x05F\x84}C\xa1\xcdZ\xa0\xb8]v\x8b\xab\xb5\xa3\x83\xa88\x0c\x8akM\xd9H\xe1\x07l\xf2\x18G\\\xe58\xeb\x95n\xe9\x93\xd5T\x04\x88\xca\xda\xaa7\xf9\xbb\x18\"w\xf4Q4\xd1<\xc06\xcf\xbf\xdc\xd4\x14\x0e\x02\x00\xa6K\xb1-?\xbf\x8ag\xcfWR\xc8\x89OY\xfa\x12\xa4\xa5\x07}\xa7\xd6|\x15\xde\xe9UA^\xb0#0\xe4\\F\xdas\x89\xe9\xa5:%\x19\x96\xb4}:\xf9Ro\xd1\xdb\x13\x83/9p\x0f\xb6aC\xe2\xcd\xaf](\xbc\"\xf9\xfa\xaa <3\x9catm\x9e\xfd\xa4\xb0\xe7\xce1|\xf5\x15\x8c\x1e\xc0\x87N\x11\xac\xc3\x88\x17\x8f\xd5\xc5cV\xbc\xab.\xddr\xe8JL\xf3\xf5u\xbc\xa60\xb2\xf2.| \xe3\x9d\x9d\xf6\xfb\x07\x9d\xd7\xe3\x9d\x1d\xf8\x12Z\x89\xa4\xc6<\xc5\xb5\xb8:\xd5\x93\xd1\x0c\x96\xce\xe5\xf1c\xd8\xeev\xd2\xc2\xb6\xa3A\xbd\x8c6\x8dK\xb6\xad_\xb1\xc7\x8fa\xa6\x87wZ\xb0u\xfd\x12v\xb7\xe8\x0bko\xcfB)\xf7\x98\xb7\"\xf6\xcbf\xed\x8cq\x1f\x1e8\xb0\xaemx\xb4)Z\xa6\x80Q\xb5\xcc\xbb\x1aK]Y\xed\xa1\x0b)L7\xdc\xf4\xb5\x82\x7f\x16B\xc7D\x12>Ze\xcc8\x8f@N\x0f\xfb.\x8c\x8b\x07l\x1f\xf7\xe5?&,\x9f\x0b\xdb\x14\xeb\xc9\xd7O\x9f\x1d|\xf3\xa7o\x9f\x7f\xf7\xe7\x17/_\xbd~\xf3\x97\xb7\x87G\xef\xbe\xff\xe1\xaf\x7f\xfbg\xfft\x16\x90\xf9\xd9\"\xfc\xe9}\xb4\x8c\x93\xf4\xefY^\x94\xe7\x17\x97W?o\x8e\xc6[\xdb;\xbb\xf7\x1f<\\\xbfg\xf1h\xdc\x0c\x8f\xf8\x95t\xbe\x84\xaf \x7f\x04\xeb\xeb\xa5\x03\x19K\xc6\xedOK:\xf0\xa9/\x83r\xe9`,c\x95[[\xa4\xc7\xea\x02\xd8\xba\x84U\x01\xff\x01\xb6)\x1a\x13\x8c6E\x9e\\\x16\xf8\xc1vn\xc2\x84!f:^9mfw\x1df:\x8c_g\x8cB\xf7S9:z\xc1v \xa6\xff\xac\xef\xc1\x96\x83\x00c\x13\xba\x13\x14\xe5P\xec9\xda\xbd?\x1a\xed>\xd8d>\xf6\xd3\x92\x9e-\x06\xe9\x14\\w\xc6\xbc\x84\xa1\x0fV>>\xa6\xac\xb9\x80|;\xc4\x8cZ\x08\xff\x0f$\x98\x0f\xf1\xcd\xb8\xfdfWz\xb1\xbb\x05_B\xd8\xe6\xa9*\x8a\xa6{\x14\xaa_\xc9\xd4\xda\xb0d\x08\xdaD\x08\xda\x1dS\xd0\xb2NTE[JzC^\xcd\xc2\xcb\x88\x1f(T\x81<(\x8a\x02\x0cCW\x10\xea\x0f\xe0\x8f\x90PZ\x80b\x06\x85`\x94.\xfc\x88\xaek\xe9\xa8k\xa0\xbf>\xaeY\xb7\x8c^\xcb\x1b\xf7\xbb\xef\xd1~\x06\xf6\xb1\xe3\x11LT\x01\x0bR^e\x83\x96+\x9a\x0e\x10QR2a\xde\"w\xb8\xc3\xfe\xfa\x1e\xa4\x0c\xc3\x04\xf0%\x9f\xc3\xc6\x8cM\x02\x02x\xfcx\x0f6f\x94rX\xa7'\x18f\x18\xd8\x14\xeb\x8fwv\xe1\x8f\x10\"\xc2d\x1d\xb8 \xda\x9b\xc1\xc6\x1e\xcc_\xf9\xaf\xb8\x8c\xa7\xc0\xb6\x18x\xec\x83\x8dY\x04D1o\x92!\xef\x19j\xe9}\xd1\xd6R5\xcf?\x85\x0dX\x1c\xc3\x87=\x18\x8d\xe9\xc1:o\xddp7b\x8a\xb9\x10\xa4)\x9c\xb6\x0b\x17\xac\xda\xac\xb5#B\xe5\x96S\xb2\xb1\xab4bAj^)\xa3G$\xbcd\xac\x8c+\x81%[\xaa\xb8\x12X\xa2\x8a*A\x0b:_\xe4\xbc\xa0\x13l\x82\x99\x9a\x8e\xef\xb7U\xaf\xcc\xd6\xb4mf9\xc7ff\xad\xb7)o\\\x11\xe6\x82\xd9\x9a\xee\xec\xb6\x03]/\xaaO\x1e\xb6?\xe1\xf6\xa6\xe3v\xdfK1\xb7\xce\xac\x99\xc5\xa9&\xa0\xc3\xd5\xa7\x0f\xe8p:D\x1a&%\x1bm\x82\xca\x89IU_M\x8b(UA\x92t\x9e\xb15J\xe5{\xed\n\xb8\xd6\x88\x0d\xb4y\xdc\xd5\xcb\xab\x82\x7f\xb4\xdc\xc9\x84a\x8d\x8b\x05i\xbb@-p\xcb\xcd^\xc1\xbd\xce\xc5+\xb8\xcd\x9a\xbc\xe3L\xde\xc7\xd0\xf1@\xd6\xd7\xcb\x92\xa4x\x1eS\xd4\xd1S\x11\xe7\xfdF\xccN\xe1\xd4\x0c]M\x99xN\x932\x0e\x0e\xc5\xc45\x95\x8a$\x89N\x93K\x8d\xc34bz4\x00\xa8\\\x18\xe9\x1d\x81\x16\x01\xd5\x1b\xef4\x8c\x03\x1e\xf0\x87\x95\xa1\x82\x99\xdd<{p\xeaVn\xd63\x14r|w\xc8\xf6\x9ayUr\xe1[\xb3\x93\xfe\xb0\x85\xe2\xa9\x18s\xda\xfe\x99\xc7\xf6\xf9hQ\xc6\xef_\x86A\x10\x91\x0b?#\x8e\x1d;\x86\xc0i \x06\xf2\x12\xe1FNN\xde\x1e<{\xf7\xd7\x93g\x07\xdf\x1f\xbd~\xfd\xe2\xf0\xe4\xe0\xafG\x07\xaf\x0e\x9f\xbf~u\xf2\xf4\xf5\xcb7\xaf\x0f\x0fNNP\x87\xc7\xbcGsE$\x1c\x90\xc8\xc6M\x97\xd6D=\xe9!\xaa\xdd\xf9\x84\x12;b\xfa\x9ez\x98\\\xffS\xa5*wTf$6?\xaf\x8eXk\x0cO\xc2\xbdK\xd1\x1a\x05\xdfVN\xb5\xf8\x17?\x1e:\xadRk\xbce}$\x89\x0b\xd3\xee\xba\xbf'W\x13\xb0\xe8f\xd1\x19)\xdc\xa2\xf9\x05gTCC\xcb\xc2\x04a\xa6;\xdf\xe6\x90U\xe8\x81\x8dFLx\xc0hz}l\xd7\xd4\xa9\x07txp\xc4t\xb0\xf2\x0b=\xb0\xc9y\x80\x81\xd8&\xd0\x16\x0f\xe5}\x18t\x879\xa37\x1cJ\x91b\xc09\xfe\x1a\xc5JNC\xdb\xa8\x06KU\x9b\xdf\x94\xf1\xac\xf1-\xb1\x0b4\xa0\xd5y\xf9\xaa\x1aQ\x8c\xc0[\xfai-:\xd7jW\xe5\xa7\x1e@\xc7\xde\xb5\xfd\\;^F\x82rF\xec\x0b4\xa35\x0f\x957\xacA\xa0\xc0t4mTg\xeb\x02\x00^p\xfc\xc5qU\x8c,\x01\xb7\x06m\x1cH\x85\xfe\x03\x9a\xd7r\x1f\x00\x08\xfcF\x9b\xd6O\xf1\x9c\x07\x17U\xc0\xedX\x0b\xb7\xe3\xe6\xfd=>\xeeq\x0d\x07Nd&\xde\xc2\xcf_\xa0\xb7\xb6yD(T\xd0W\x19\n\xd3\xa8\x07T\xa9\xdf\x0b\xcf\x9f\x17${\xc1\x9d\xa7\x91\x83X\xdbt\xe1\xc0\x96J\x1cY3\x1f\x9bB:\x9a\xcf\x84\xdc\x0c?\x1e}\x1e\x12\xd52M\x14\xd9\x9f\xc5c\x82\xdc\xbb=`\xcd\x99dB\x18\xd1\x7f*\x07\xcd\x03\x00TY\x80\xeb\"\xfd4\x85\x95\x18\xb0z\xd3\xc5\xbb\xa1\xad\xf0\x18T\xba\xe3\xd13\x02\xceG\x16\x82K\xe2o\x06u\xfe|9\x81\xb9XZ}\xb5\xb7\xc4\x9f\x15\x93:H\xa2\x1as\nn\x8cqi\x12\xcf \x18\xc6\xe5\x96p\xce\xa7u{p\x92\x07\xa9\x8bX5xdw9\xb0\x01\xc2\x82!c\x87\xce\xf8\xbbo\x0c3\xcaW\x99\x91\x96\xb7Q\x0c\x14\xf6\x14q\xf7\x06\x0f\xab\x894\x07\x0c\xcdxE2b\xc4p\xef {(b`\x0bLmW\x97\x18\x9f\x99,.a\xbea\x8c|JN\x7fz\xe9\xa7\x0e\xbdA\xfa\x97\ndZ\x89\xf1\x18\x99fW\xb9\x87V+\xd6\x0f\xa9X\x93\x9a8\x1bB\xe6\xf7RH<\xc6-F\x82&\xd3\xf8x\x85H\xe0\x82\x10Y\x91\x0c\xe9J\xf8br\x013\xef\xa5\x9f\x9a\x19\x05\xe0\x84\x89\xcc\x15\xf7s\x93k\x99)\xc2\xb0\xfc\x08\x93\x80lZx\x94\x1d\x18\xd0x/\xa3\x0d\x12'u`\xc7\x8e\xc9_N~\xf8\x88\xab D \x97\x0c'\xc6/\xf5\xac(\xa8\xc4\xbe\xed\x07aO\x0d\x95\xc8\x0f\xbbm\xa8,\xe4\x08X\x9b.\x04\xde,Y\x9e\x86\xb18M\xb9\xc3r\xea\x9f\xf6&\xc97\xa3\xdf\xa3\xabt\x88L\xa8W\nC\xa6\x9b\xc7^\x91\xbcKS\x92=\xf5sb\xa3\x11P\x15+\xbeW\xec\x86\xa7\x9e\xcd\xcd\xb1\xf5H\xa2\x1aP\xacH\xe7!?\xe7<\xb6y\xac\xcc\xf8-\x1eTT;\xf28\x92&}\x9c\xc1:\xc5u\xa1\x9aU\xba\xcd\xa5L\xc9\x13A+\x0f\xd8\x80!\xb72\xdfN\xdb\xca\xab\x86o7@N\xef\xdfbx\x02\x915\xc7\xe7\xf3v\x07\x82\x05^\x06d\xc5\xcb\xa0\x03T\xc4`\xd6\xa2z\x1a\x02\x06\x8a^\x1c\x13\xa0\x14\x9dL\xe0\xf2\xa3a\xb5o ?j\xeel\xc0n\xf5\x9ef\xba]\xc3\x98\xd1\x06_\xa8\xf2W\x07\xdd\x86\xc6\xcd\xfd\xe8\xbfpi\xaf*\xac0\x8d\xeb\x0c\x0e\x1b\xf7\x9dc\xef\"\xf3S>\xa4\xdeK:\xe3\xf8U\x03h\x03\x04\xbe\xe2\x0e\xca\xa6q\xcf\xb5\xc6\xbbD\xe3K\x14\x10 A\x91\x9d0\x1f\x17\xb4UL\x8e\x1d\n]m\x9ad\xc8P@Z\xaa\xde\xa3\xd9~\xc4\xbd\x88\x87\xa3!\xaci\xa9:\x14Q\xc4t\x8fB\xbf\xd8~\x90\x90\x90\xcfY\xe6\xc8\x16\x89\x92\x87\xb2\xb4\xad\x10\x13\x12\xe4P$\x954\xaa\x96\xd2\x16\x0b\xbf\xe0\xafs\xf0\xb1\x91\xaa\xcc\x0e \x14\x0b\x02\x17\xec\xe4\x00CD\x8e\x0e\x11\xc9\x0f\xef\xe8\xc0\xcez$\xdd<\xf0\xe67\xbcO)\x88\x08\xbd\xafM$\x82\xb6\xf8n\xf1\xc4*\xd7\x8e Q\n\xa2\xce\x8c,\xb26\xb2\xa8%D\xfd\x01\x0e\x9a'S\xce\xa5\xa3J\xe7%?\xe2TN3 9<4)\x16A\xb87)qL\xc2\xd0J5\xf8^\xc4\x12v\x10K\xb1\xc2\xf0A\x16\xcaO\xb3a\x88\xc5\xef\"\x16\x9f!\x16\xb4x\xf5\x99M\xaa\x82\xd9\xe9\x1d\nH\x14\xd5\xca\x88\xa5\xb2\xbe\x0d\x15\x1c\x0d3Mb\x83\x0d\x1dn#\xcdlr\xc3GP\xae\xaf;h\x0e\xdd\xe0M\xca\x9e\xe5\x10\x8f@\xf1\xc8\xcf\x990\xda\x94\xcb\x8b\x9e\xc7v\xe2\x1cS\x8e{\xe6\x17\xb6\xaf \xad\xdb\xcfM\x10\\hBp\x02\xc0~?\x0c\x17\xf6\xa1\xb7\xc2\x80\xde\xd4<\x0e\x08\xf4\xa6a\x81n\x87\xdeP\xca7\x08\x99\x0d\x90\x94fM\x0b\x17\x15.X]^\xd0\x14\x08\x10\njL\xec\xad^\x0e\xf7v\xe2\xbe\xa6|\xfd\x1fg]\x06#\x16\xc1m\xb3C\xabr\x11\x15\xcf\xf5G\\\xe3o\xe2\x01K{c\x99\xe5\xc4+\x93\xc7z\xeaV\x83\x92\xaa\xb05<\xb6\xf9\xbe~\xf4\xd0\x96,\x8b\xb2[m\xce\x9d\xd2jJz\xaa\xd2\x98T\x14\x99\xb3\xa2\x84EEa\xf5RFz6\xb0\x97\xc1\xe1-\xf4\x1e/\xf9ix\x84u\xc9\x8f\xb0\"?2\xa7\x8a\xe6\xe4\xc3W\x90=\x02\x9f\x92\x1f\xe1\xd4o\x92\x1f\xfe\x00\xf2\xe3\x9c\xa7C=\xb0cAl`*$\x0d\xa9\x11\x1a\x93W\xf2\x87O^i\\\x81\x89(m\xd6c\xe9\xd8\x85\xcd\xa2\xca\x1b\xdb4X\xd7|\x14q\xc5] )\x08\xc6\xe6\xfa\xf0\xa1\xa3\xf1\x13jt\xf5R\xcah\xca\xab\x85[\xed\xc8\x1d\xe2Q\x9f\x18\x99\x84\x1f\x80nl4(<\x0d\xc5\xbc\x9ff\xc4\xa7\x07\xcd\xa9\x10\x17\x90\xc1\xa6 \xd2\xc6\xd7\xce\x8b\x85\x99\xcd\xe8k\x1a\xe4\xeb\xb4\xe8\xb3\xe1\x82\x017\x9b\xfc\x08\xe9\x1f\x05\xfd~\xf8\xd6\xbb\xff\xb7\x1f\x94(\xdeB*!\"\x06\x0cZ\x1e\xe0\x1d\x0e\xabI\x1f\xba5\x138\xf7^\x1d\xfcpr\xf4\xed\xdb\xd7?\xbc:9x\xfb\xb6_\x03#\x1e\xcc\x80\xa0\xcf\x92\xa5zR\xff*J\xfc\x80\xa5\xf8Y\xc8j\x84AM\x98\xb5\x1bX\x03\xe6a\xecG\xd1\xd0-\x12@\xd5[\xd9\xdc\xb5\xc9\x02\xb0p\xb42\xd7[b\xaa\x97~\xca(\xe8\xe4M\x96\xa4C\x90\xd5\x10\xf9\xb7\x11\xcf\xf4\xb6\x04M\xac\xd2\xb2\xe3!\x03H\x9a\xdb.\xc93\x8e^\x87\xaf\xca \x92q\xd8\xb2\x0c!\xee\xec\xa6\x87\x02\x8a\xe5\x0dVL\xc8\x81\xd5VG:P\xea[\xb6c\xfam\xf5\xea\xdaV:\xaa\\hCG\xddZ\xc5\xab2\x02-\xd4\x0d\x9b\xac\xa2\x1b\x0d\x8fT\xde!\x0dA\x860\x03\x95\xb4\"\x83\xea\xcbF\x9a\xcd\xea\x05\n\xd8j\x96\x04)\x9a\xd6\xd5\xd6\xaa2\x80Z\x15T*\x91\xc8r\xe6\x1a$\x91\xf0*\xf9\x1a\x067\xe8H\xe9\xf7\xc1n}\x89&\xb6\x9c\x8c\x9b\xc6\x14\x18x\xf4\xea\xf6`\xa7\xd91\x86\x95\xc1yu\x1b\x99&.\xc4\xc7\xc6\xaf\x9bp\xa7\xd0\x19\xb7\xbe\x91\x13\xfdk\x9a\xd5\xba\xee\xcb\x8c}w[\xdb\xbb\xaa\x8a\xa1Y;\xddC\x18\x9b]B\x98\xa261$\xe5ow\x18V\xa9\xa3\x1aoe\xd5\x8f6\xc2.\xc8\xb2\xd5a\xca\xa2j.%\x9d\x8b\xdfG6\x9c\xf3,K~\xaf\xa8\xb2 `9\x93\xd6\xd2O\xa7\xf9\xb1+$\x9fye\xb1\xde\xd8\x96\xee\x9bir\xac|)O\xb2\xb7\x02\xed\x13\xe3z\xf4Ub\xf3\x13\xb0\xdfW\xdd LU_\xf2}\x88W\x8d\xf4I#2\xa1*J\xc4\x81>Z\xc6\xaa\x9e$*\x9c\xe9xQr\x86\x02]\x850$\x96\x93\xa9\xef1Ij\xcb\xf7\xc3D\xec\x0b'F#\xb1\xa0'\xa3\xa5\xb0\x98*N8\xab8\xe1B\x84\x12\x7f\x04 |\x05\xc5#H('\x9cQ\xf8\x92W@wb\x05\x82GcpN\xa7\x13\x17\xa6\xf4\xba\xaf\x00&SY\xae\x0c\x8d\xe5\x85\x11C\x9a\x19\xc3\x08\xcfE\xd7\x036\xd7\x7f\xe8\xfe\x92\x13\x8d\x9f\xe0\xdb\xdeX];[c\x85\x17\xb0\x9c\x14\xa9.U\x07\xc8S{\xca \x9dE\xdbI\x99\xb4\xa3\xca_\x0f\x19g=\xae\xf1\xa64\xdc\xcc\xce0\xcce\xc6b\x86\xb2|7\xda\xb8\xa1\xedX\x9e\x98+\xc5\x9b\xd7#q\x86\x0c\x85.\xd9\xb6)\x87\x94\x9f\xe7\xe1Y<\xa4\xa9\xfeY\xe9'\xc3z\x99`\"\x98-g\xc59\x98\x93\x0c\xc9\xa7\xf2Z\xbd\xfb\xd9\xed{\xa1\xeb\xd8\xf6\x9ef\xb1\x055\xc1\x1a\xb7\xd4\xb9\x8cv\xb6\xdaYyJ\xcc\x1aP\\$O\xf8\x01\x7f\x93$\x11i\xa5{\xc3Yx\xf3\xa4\xccL\xb5\"\xd8\x83{?\xde[\xbfw\xa6\"\x86gZ\xbfi\xdb\xb2`\x1d\xd0\"\x13MG\xed\xc8\x05\xeb\x8b/\xefYf\x94>W\xca>Q\xd0C\xeb\xf0\xfc\x1c\xf4\xcfY\x12\x17\xe4\xb2`1<\xf9\x9b2\xa6\x7fo\x1a{Hu\xe7Ul\x0b\xc1\x9e\xba\x18_\xd0\x9e\xd8m\x0b\xd33_\x99\x84\x19\x0f\xb1\x81\xac\xaf\x9bg\x1aHaI\x94\xf3\xcdH\xce\xf0\x98\x98\xf1{r\xf5&#\xf3\xf0R\x9a3_\x94\xb8\xb3(\xd9J\x8b\xb2\xe8_\x146\x9c\xee\xb2\xf8XZ\x8d\xad[\xa14\xaci.\xafi\xb7\x98\x02_\xc9\xd66o\xadms\x03\x9a\xc4WD\xa9\xfbs\nq\x19\xaeo\xe8\x15\x0b\xbfx\xcb\xd4\xac\x02\xd8)\x05\xcf\x13\x9e\x02\xcb\xe1\x98xa\xfe\xbd\x1f\x85\xc1ADh\x0d\xda\x0e}\x1f1\xc6 Jb\xf2$\x0e\xde2x\xfe3\xb9\xa2\x1d\xf8\xb0\x0e\xf6ZD\xe7\xcf\xe2\x9e MF\xff\xa2T\x01{\xbf\x0f\x96\x05\x13\x98\xd9\xf8\xa7\x03\xeb`\xdd\xb3\x1c\x0cU\xe8\xb8\"\xf0n\xe4\x98\xc1\xe5\xdc\xee\x0f\xcf\x04{`Y\xcd\x85\x113dq\xb9h\x8d\x19e\xc0\xd9\x10\xba\x1c\x03\xdd\xab\x802\xd2\x88\n\x02\xbb\xc0([\xd8a\xb3\xb2O\x87\xb3p\xa1\xa4\\\x92\x97\x91\x88\xf89\xb1K\xf3\x1c\x96=We\xe3\xce\xaf\xef\xf4\xb9\x14P7 \"\x95\x81I\xcd\xd88\x1a(\xaco\x9d\x8e\xc6\xcb\xce\x01\xa1\x9b\xe2\x07\x01]\x830>;J\xec\xb9\x98\xe8\x8d\x06R\x1dd\xa9W\xf9,K\xaf\xefp\xcc\x81\x0by\x8b\xae9\xeb\xc8>\xe7Iv\xe0\xcf\x16\x93^b\x06\x84-7\xb3\xb5\x96\xa2\xac+\xec\xc5\xabk\xb4 I*\xb7f\x84\xa3\x94\x85\x84\x9aWp\xd4\x8e\xc3\xdc\xc4\x0cK?\xfdH\x03\x9e*\xa8`\xfe\x15\x9e\xbf\xcc\x15\xbb\xc0\x9c\x8f\x8diJ\x96~\xfa<.\x92\x1f\xc2b\xf1g\xb1\xdb\x98?5\xf6\xa3 \x9c7+\xe3\x8e\x0e\xd0\x00\xf2\xd1\xe0\xb2-\xd9h\x8ckU$\x88\x12\xfb$y\x82\x95\xe8[\x80B,\x80\x1a\xa5vRg\xd5\xf0\xa9\xa6\xa2\xce\xf0\xed-\xa9\xa8\xd1f\x9b.\xc2\xc0\x7f\xb1\xfd\xc0\xe9\xb34\x16)U<\x91R\x85B+g\xa3\x86H<\x9b\xdf\xa5I\xda\xa3\x83b\xa7\x17\xfdjY(\x16Epr\xdd\x06\xc4\xe4\x02\xbf\xef$gP\xd0\x8a\xe6Y7R\x85\xd1&1)\x8fm\x8dw0\xc7\x85\x84\xdb*\x1fN\xc5\xfaPv\x92\x16\xa5I\x12\x1d\x86?\xd7n\x9d\xcd5\xa1\x97\x9b9\x9d\x04\xa5 \x92.\x01\xdb\x1d\xb7\x8c\xdf\x06\x9c\x15\x90\xc5`\xc6m\x89\x1bc\xe61%\xe3\x1a{\x01g\xf0}\xfa\xb6\x9a/K\xc7T\xfd\xb9\x07#L\xc6$\xb0\x18\xec\xd1\xbbS\x91\x9bIAZ\xc6\xa4I\x83O\xda\x0bB\x9f\x0e=?p\x0dn\x02\xe4 \xad\xddJ\x80\x0e*`\x8fyl~\xd5r\x80\x12\xe6A\x05\xf7\x9dT\x15\xa0^\xceb\x91\x91\xce\x82\x0e\xb90\xe0\x96\xab\x95\xdd\xc9je\xae\xf0\xcb\xeb\\1\xe2\x19\xbe`\xcax\x1e\x8a5\xeb\xf2\x81\xdd%3\x98\x91\xdcf\xd5\x92;Y\xb5\xa4Z5FM\xa8\x9d\xc0VZ\xb8NB\x88n\x0b\x9a{\x8d\x99k|\xac{m\x9b\xa5Z\x1e\xef\xdeW\xc5\xa2\x8b\xed\x9d\xadv\"]\xbf\xbe\x10c{g\xbb\x13^\xaed\xe5\x0f\x1d\x17,\xaf\x9d\xc6\x95N\xc8\x9aX\x9ax\xc5\n\xc4#\x08-\x0c \xd2\xcdx\x80\xef\x05cB8\x8b\xe4{$\x9f\xf9)\xb1 c\x92&\x18Z\x9e\xe5Q\xb0\xb7v\xdb\xd22\xb8\x990\xae\xa2\x06y\xdc\xccj\"\x84\xc7w\x9a\xb90\xd7\x11H\xa9\x8bq\xf2\x84\xb9F\x1761_I#05\x86\x91\xfd\x12\xacSz\xa2\xfcX\xbc\x12YP\x90|sk\x07F\xbcd,\x16\xab\xd9\xc27X\xd7\x8a\xcb\xe5)\xc9\xe47\xf5\xaa\xf2.\n\xef\x8b/\xf8\xc8\xd0\x15\xb2\"wg\x94{)\\\xca\x83\xb2\x00\xcd\xfbP\xc2: \x05\xb2\x89L\xb0\xe3\xc2HM\x13/0\xc6\xa5\xf2\xc8\x9c#\xb3)59\x81\x18\xd6A\xa1y\xa1\xab\xd2\xe4\xcf\x0b\x8d\x06\xa1\x92j/\x99\xc4zII\x8c*\xbc\xf6r}\xdd\x81\x05\xac\xef\x01\xb1S\xba\x0f\xd3\xe5\xb1\x0b\xe78\x97\xd4\x85\xa5\xc3w\xaf;\x02Ml[\x90\xd8\xa2P\x99\x8d\x10\xf8\xf0\xcf\xfaP\xd8\x95\x8b\xd1\x04\xcf8m\xd7\x13Z\xe6\x0c\xc1\xa0\xf0H\\d!\xe91s\xa9\x16\xe5\x84-\xca\x9a}\x05{p\xea\xc5\xe4\xb2\xb0\x1d\xc7\x0b\x12L\x1d&-\xcc\x15K;#\xad\xcd\xc9\xfa\xba~u\xc4CW\xa9\x7f$\xda\x01\xe8\x17H\x91i\xd2\x8e\xe1\xae\xcdSU(\x92P\xdd\xc1\xca4\xc7\xca\x0e\xc2P\x0e_\x0d\xc6\xd6\x9e5\x01koS\x03\xc1\xd6\x04\x8b\xc7V\x17J\xb4\xf2\x02\xeb\x0b\n\x93\x1d5\xc0\xbd\xe9\xde\xe4\xf8\xdeY\x1fc.5TL\xc9q\xb7_#GY\xc6w\xb3(\x9b8m\xdd\xa2\xec\x8di\xf1d\x95Ea\xcba[\x1e;\xccd\xba\x89\x1az\xbaV\xeco\xd4D\x13//O\x19\x15`\x8f\xd1\x97Pz1r\x1ci5\xed\xbd\xcd\x0f{c\xe7\xee\x17\xb4\x86W\xf5\xd9\xb9\x13\xfd\xd7\xfd]\x87\xc7\xe8\xfc\xc6\x9f\x15Iv\xd5=\xc5\n)\xc0\x84\xa2H\xbfM\xa5b\xd1\xe9i\xc6JOO3e\x85 \xc8H\x9e\xb3:\xec\xb7\xb2ZFx/\x19Qw\x94\x15\xe1,\"\xbc\x0e\xfeVV\xcb\xc3\x80W\xa2\xbf\x94U\xca LX\x15\xfaKU\xe5\x14\x8bO\x95E~\xce\xda\xa7?\x94\x15\x82\x90\x95\x07\xa1\xba8\xe1\xc5\xea\x9e\xc33V\x1c\x9e)\x8b\xa3d\xf6\xfe\xefeR\xf01T\x7f*+'\xc1\x15\xab\x96\x04W\xca\nl\xeb\xd4\x1bwZ\x16E\x12\xb3\n\xf8SUi\xe6\xc7\xe7>\xdb\\\xf6S])\xa5\xe0\xcak\xe1oe\xb5\x90\xcf\x8a\xfePVH\xf8\xd6\xd2\x1f\xea\n\x11/\x8f4\xc5gYR\xa6\xa2\x0e\xfe\xa1\xaa\x18\xf8\x05\x03F\xfaCW!\n\xf3\xa2\xaaD\xffPV\x0cX\x95@YH\xd8p\x03\xa2\x1cn@\n?\x8cr^\x05\x7f+\xab\xcd\xd9\xca\x06s\xe5\xaa\x06\xa1\x1f%\x0c\xa6\xd8Ou\xa5s^\xe3\\Y\xcc\xc7\xa9\x1e&_\x05\xe5\xfc\xc9\x12\x0b\xc9R]xJ\x02^~J\x94K4\x0fI\x14`\xd2\xe7\xcc\xb6\xc4\x1f\xea\x8ag2\x98\xd5\x7fj*\x97\x19\x11\x15\xcbL L\xf3$\xc1\\\xb5\xff\x1f{o\xda\x1d7\x92$\x08\xbe\xdd\x8f\xf5+\x9c\xf1\xaa% \x03\x0c1H\x89\x94B\xa2\xd8J%\xb3[\xdd\x99\x92FRVMw0\x8a Fx0PB\x00Q8xdQ\xef\xf5\xcc\xec\xdc\xf7\xee\\=\xf7\xd9\xb3;\xf7\xb1\xc7\xec\xce\xf4\xf4\x87\xce\xfc#\xf3\x07\xf6/\xecs3w\xc0\x017\x07\x10$\x95U\xbbo\xf1\x81D\xf8\x05wssss3s3Q\x08^\xe9B\xc9R\x16I\xc81.\x86\x90\xbd\x18\x92\x99\xdb\x98\xb9Mf\xee`\xe6\x0e\x99y\x1f3\xef\x93\x99\x0f0\xf3\x01\x99\xb9\x8b\x99\xbbd&\xf7qB\xc4\x8b\xad\x80\x04\n\xbe\x92\x85\xcaU\xb6\xb0\xae\xb1\x85l\x85n![\"\xca\x89\x17\xaa\x00\x92X\x92\xc0\x06\xf3\xc4_\xe2\xe4\xe2+Yh\x89K\"X\x92\xeb!\x88V9\xe2\x1c\xbc\xd1ERY\x80\\\x95\xefO\x10\x90\xefOH8\xbe\xe7\x97\xa7\x1cQ\x15_\xa9B\xa1\x7f\")\x04\xbc\x91E\xf8)\x8f\xf0K\xf8J\x16Bh\x85$\xb8\xc2 z/\xb3\xa3\xf7T\x81\xa5\x1f`G\xc5\x0b]`%\xf3\xc9\x89^\xfa\xc9{\x99\x9f\xd0\x1f\xe0Q\x8e\x05x\x94\xdb\n\x04\x99$%\xea\x07]P\xd2m\xf1b) \xb1\x17\xde\xa8\"\x91\x8f\xa40\xf2IR\x18\xc5\x18M\x19\xcb\xc8\x1fTA<0B1y\xac\xa5\n\xe1\xf4\xd2\xdbU\xbc\xca\xca\x85\xa4~X\n*\xba\x17[i^\x9cg\n\xa7\xf1\x95*\x84\xdf\"?\xb2\xf2\x13\x1fg\x00\xde\xc8\"\xc14StU\xbe\x93\xc5T\x11[v|Zp\x8c\xea\x07U\xf0gP\xe2gTV\x82\x03I\xc8\x91$\x08\x85\x84\x84@\x92\x9f \xcf$^\xa8\x02\xd8/\xb2C\xa9\xbf\xc4\xef\x8a\x17\xb2@\x89:v\xc4I\xf9\xb4\x98N\xf9N\x17\x0b\x15~\xe1+Yh\xe9\x87\x88b\xf0F\x16\x89\xf3d\x8a\x13\x82\xafd\xa1\x95/;\xb4\xf2\xe9\xdedI\x1c!I\xc5W\xba\xd0\xa5d\xe0\xe1\x8d,\x92#\xeb\x9d\xe6$\xf3\x9d\xe6\xcb\xa5\x9f\\\xca\"\xf0N\x17\x93\xf3@\xaf\x97\xcc?\x91\xfd\xc80R,Q\xa4\xe0\x9d3\x1b\xf3\x9c!\xd9\xcdH\x92\x9b\xf1\x8b\xac8\xd2\xa8\x1fdA\xc1[`)\xf1F\x16Y`\xfe\x82\xceT[vf\xdb\xb3\xb3@n\x87\xe2\x85.\x90)x\x887\xb2\x08R\xcd\x8c$\x99Y\xe2O\xdf\xcb|\x7fJ\xd2x$\xf0$u\xcf\x11As\x12;\xcf|\xfc\xf0\x99O~\xf9,\x98qW\xfc\xfa\x9c$\x11<\x0c\x83\x95<@\xcaw\xaa\x18\xae$\x9a5Y\xfa\xa7\x92\xbb\x11oT\x910\x88\xb0\x84x\xb1\x15\xf0\x93_K\xfcY\xc0\xa3\xac(Z&Q\x95\x96~\xaa\xf6\xf1\x94\x9c\xe3\x95\x82\xd0\xca\x02\x9d\x95\x9fe<\x89T\x19\xf1N\x16\x8b\xc3\xcbSI\x00\xe5\xbb\xadX1R\xf5\x83*(\xc6\xe4\x87\x95\xd1V\x93\xc8J\x8a\xb8&6\xd2\x9a\xc5\x92\xc8d1M\xec\xcf$=<#\xe7Q\x10\x85\x82:\x90\x05\n\xa2\x9b!\xd5\xad\x94\xb0\xc8\x88P\x05{\x0b2\xa2\xaa]f\xb5w2\x1a\xfb\xae\x1e|\xac\xd2 eMv\xc3~\x18\xc6\xd7\xf8\xe1\xba\xe95j`)\xfdk\xe4\x0c\xeb\xe1\xb5r\xd9\xf7zq\xb4\xa8\x7fp\xff\xbeeL\x8df\x1f\xcal\xe3&\xf2s&\x8doi\x19\xba\xfa\xcaT\x94x\xf2\xc4\x8f\xe2\xe8r\x19\xe7\xe9\xd3\xa7\x84\xa8tn\x95\xaf\xfah\x99v\xe6\xf4\xe0\x8dB;\x06\x82#\xc1\x98\x9e9\x85\x12\xd5RN\x0c\x17\xca\x15\xe3\xb6\x14Dm*\x14\x95\x8aUKA\xc55\x9f5q\xcd\x0c\x19\x8e@0\x1cg\x8eR\xde\xda\n\x02\xd0\xb1 \xbc\xda\n\xfa\xd1\xe5\x88-\x9cD7\xb3{ \xdab;(_\xcd\xdb\xe4\xdd\xeaQ\x9a\x9c\xaa\x7f\x1fk|\xcc\xfaS\xd3wh\xb7\x9a\\\xdd\x94b\xe6\xf4\xd4U\x13\xf6u\x8f\xf5!8j\xefk\x16\xcf\xcbx]\x98\x91`\xc6\xc2OY \x03\x16\x8b\x9a\xef.W\x9cEq\xe6\x83\x8a>\x88\xd2`\xc6\xd5P\x07m~\xb0\xce\xe4\xbd\xc0\xac\xd5\x99#\xdcn\xad;[k\x83\x01\x93\x9f\x00+F\xc7\xef\xee\xf4CBF\x05f\x16\xc3\x8f\xc5\xf0\xeb \x12 \xc5\xb4\x14\xd3\xd2|\xb5\n\x03>cY\xacC\xcdc\xfcb\xc5\xa7\x19\x9f1?B\xe8\x0c\x08g\xb1\xfa\xd3|Q\xbfP8\x87\xa8p\x0e\xd9\x13-\xc8u\xd8\xefw\x05\x0d\xdc\xd6p|\x8f\x85\x05f\x89\x1e\x8fE\xdfC\xf16\xe9y,\xef\x0091AS\xddf\x11.\xe5\x95\x16\x0e7\x18,ey^\x7fl>T\xe8\xa5\xc8q\x93\xea\xe0Q\x80\xdd|%\xae\x89\xe4|\x0d\xc4\xce?>b\xe7\x9d\x11\x9b\xa5At\x1ar\x8c\xbf \xd9\x80\x9ba\xf9M&\xde\x16^Ja\xe8\xf7J\x887\x1cp\xba\xa6\xad\x0e\xdey\x8e\xf1\xeeN\xe4/\xc1\x98\x95\xb8\x9fC=y\xab}\xb1\xedA\x1c\x1cL\xe3\xa8\xb8;qu\xc5\xaa)\xd0\x9bri\xb7c\x9fz\x94\xd1\x99\xd1X\xa7\x16>\x00\x14\x7f)\x90]\xcd\xa4\xa8\x0e%|(\xf1\x8bCw\x0b\x17\x05\xfa\xafk\x12\xb9\xc6\xbbL\xf5\x07\xd0f\xe9\xf0q6q\xeb\x0c\x86>\x01I9\x01\xb1\x05\xd8\x91IY\x80\xa4\xbc\x8cg\xbc\x95\xa3\xb8 \x0cm$\x03\xf9\xca\xef\x95`\xfc\xc2875\xd6V@\xeb\xbbZ;M\xea\xc6\x81UL\xba6*\xf1\xec\xd7_\xcb\xebpd\xf8\xcd\xd61k\\\x17\xf8\xa5h\x1d\xb6\x18\x90?X\xf8\xe9\xab\xf3\xa8\xb8[\x1ev\"\xfd\xac\x99A\x1b\x00\x83\xd6\x8d5c7e\xcf\xd8/\x80t\xc5\xd1\x1a[4q:\xd0<\xe5\x18\x07\xb4\x06\xbb\xbe\x9b-\xdd\x02A\x8a\x95\xa1{X\xe6\x05\x83\x9e\xeb\x17\x8fm\x8f\x18\xd4J\xcc<\x07\x7f\x1e:\x8c\xdb\x97\xa6Xp\xbf\xf1\xf6\xd5\xcb\x01\x9eu\x83\xf9\xa55\\\x80z\xd6\\i`\x1f\xaao~\x1d\x96Z\x1c\xc1\x8eY,\xcf\xa6\xfd\xf2\x1a\xe8\xf2\xee\xb2\xdd\x9cL=\xb7\x862\x157\x1f[\x8fYV\x99\xe9\xac\xfd(\xa6dAb\xef\xec@\x1f\xa9\x9d!*:\x1e8\x1bC\x8f\x15\xb3\xa7\x9c\x87T\xe6\xa6\x80\xd5\x80\x1d\xd6\x8f\xa5\xb0},\xf8\xf4}\x01\xc6\xd4c'y\xc6\x12>\xe5\xc1\x19\x9f\xb1_I\x99\x9f\xb1 \x9a\xf1\x0b\xf6+\xe9\xa0\xe7\xb1\x13\xf4\xed\x05\xf7\xa4k`\xb3\xcf\xee\xf7\xb2\x04\xa5o\xd1r:\xfc\xf6\xe9`\xda\n\xe2\x9d\xbc\x8f\xeaWX\xd3jo\x05\x81v;QG\xd6\x99\xc6vY\x9f\x96\xa5x{\xeb-]t0\xddT\xcf\x0d\xa7\xf4\xff;\xac\xc6\xd7\xf8\xc5\xaf\xd7\xe44:\x1d\xe0\nfa\x1cv\xc4\xd9i\x97f\x99lz\x0en n\x85\x0f\x99\x17\xa0\x9e\xb7\xd6i^\x12\xdd\x16\xcc\xed1%\xfc\x02BK~oX\x9fv\xc6\xfa\x10\xb0\xbe\xee`\xae\xfe\x18X\x1f\xde\x00\xeb\xc3[\xc7z\x85\xc2>:\x93\x04\xfe\xa9\x8dk)V\xca\\\xac\x94N(-J\xaf`\xa5\xcc;\xae\x94\x8d\xd5zpz\xcf\xe5\x99l\xdeL\x8e\x8f\xa2O\xfdY\xa1\xc2\x10\x195\x9e\x0da\x80\xd7\xf9{L^\x139\x8a@\xd3\x06\xb7J\xc8Z\xfa%\x13\xe5\xa7K\xd6\xef\xb0L\xcf\xe4\xa5\xb2\x95\x93zln\xae\xf6y\xb7\xd5.\xe0\xb6(\xc0\xb6\xf8\x05\xadc#\xf5\x83vE\x92\x99>\x87(\xfcQR+y\xfd\xef\xa0pR\x7fu\xc5\x86\xec\x1ed\xc0K\xc6F\x8c\xc3\x85I\xb8\xed\x07\x0cZ\xa5\xb5\x0f\x96o\xcfhJ\x02\x17g\x97J\"\x81\xe8\x84\xe2=\xf0\xd8\x1c`\x92\xa37\x1ep\xb1\x13#+\xfa\xdc\x0f\xc3 :-D\x0e)\x83\x95\x03\x8e\xb9\xd9,H\xf84\x0b/Y\x90\xb2(F65N\x04\xd18\xb9\x84\xc0*_\xaf\x92x\xb5)\x88N\xfa5[\xf9\xd3\xf7\xfe)\x1f\xb0\xafR\xce\xbe.\x1a\x1c\x00\xc3Z\xfct\xdc\xaf\xc5:\x9b\xfaa(\x9aX\x0e\xd8\x1b\xee\xcf\xd82N\xb8\xe0\\\x17Y\xb6\x1a\xdd\xbb7?\x19,\xf9\xbd<\xe5\x9bP{\xb3\xfc\x8eu\x91hx(f<\x19\x07\x13v\x007+\x8b\xcb\xa1*\x0d\x89\xc4\xbb\x05/\xcf:\x15\xa2\x19\xa4`\xe5(\x18\xef\x94%\xfcgy\x90\x80TQ?O!\xdf\x1dd\xa9$\x067b\xdc\xa9\xe0H\xdb\xa5k\xa6+\xe61\xbc3\x92\xa1\x0d*\xb4^\xba\xd6B\x1co\x10\xd7\xdd\xd5#\xc6\x10c,\x91\xa4\xdbm\xee\xa4v\x9b\xbb\x8b\x10\xe11\xdb\x80\x10\x91A\xed\x16ucMV\xeaBb\xbcB\xadM\xe4\xd0\x0e\x9a5nvS}\xea\xc8\xf5\x82\x17\x9f\xae7\xbbAx-\xf0cc\xe9\xf8\xe3\xe1\xa4\xd3@X\x17\xd9\x8e\x0d\xa3\xa5[\xd8\xf6\x05k~\xbf\xeeu\x96&s\xa7\xcdWL\x95\x9e\xc5\xba?\xd5\xe5\x85\xec\x80I\xbb(\xe0\xfc4\xf1\xfa\x1b~zx\xb1*\xef\x81\xf7XGG@\xf2K\xca\xf4\x08\xaf\x9c\x82;\x89\xb7ZJ6\xee\xfd\xea\xaf*\xd7\x1b\xef\xfc\xd3\x1e,\xe0\x16k\xb2L\xef &\x9bpD\xa7W\xa2\xe3\xaa\x07\xf58r6\xe0^\xda\xddwiN\x98a,\x05\xb5+UZx\x07\xd9\x84\xbc\x9a\x9bSR~m8\x01ht\xb0T\x99\xa1\xcf\xfcL\xfb\xfa\xcc\xcfx\x8f\xc6J\xa3&\xcemY7\xe1\xa7\xfcbE\\1\xb6\xa1Q7x\x9e4#+-\xd0/v\xec\xe6\xad\x1a\x91\xb6i\x1bn\xdd\xf6\xd4\xe8\xfd\x088\x9b\xc6=\xb4y+\xc620\x03M\x05$\x98;\xf4\xa8\xa9C]iL\x9b\xd3\xb7\xea/YIs>\xc9\xf6Q\xc5V\xa6xl^;\xa9\xb0}\xc1J\xcf\x07z\xc2\xdc\xd3\xa4b7\xf0C\xd0\xe4x\xa7P\xe9\xdfR\xfb\xbd\xe1\x83\xc1\xee@z\x1e\xb8Vkg\xa5\x8f\xe9\xdd\xfb\xee\xa0\x88\x98@Y\xf3\xb6\x19\x1b\x07\xb2\x9d\x07\xa4}\xef\x83\xfb{\x16\x83]\xdfQ\x92\xb9\xdb\x18\x87aG\x8c\x9d\x1fn\xd3n\xa3\xeb&\xca\xa2\xb3\xbdep\x11Di\xc7I\xad/xuf\x19\x13\xd2\xc3\xd4j\xef\x8b\x9f\x1c\xb1\xdeg\x87\x9f\xbfxyx\xfc\xe5\xb3\x97\xbfe\xf1\xad\x90f~\x16L\xbb\x95])\x0c\xefTZ\xfaS]\xa3\xc2\"\x08g\xcf\xd7\xadu\xca\xb3\xcf\x90\x1a@\x84\x9dj\x9d\xe3/\x0f\xdf\xfc\xda\xe1g\xf6\xaa/\xa2 \x0b\xfc\x10\"\x17\xadY\xf5\xb9\xd6\xddu\xaa&<\x82\xbb\xb4\xaa\xc6\xab\x97\xcf\x0f\xad \x94+\xe8\xc7A\x18~\x89\x8eK;\x80\xa4\xa8\xf6Y0\xbbF-\xf1\xb17\xa8($@j\xc3\xa3E\x9c\x0bp\xc86\xbeZ\xcd*\x10\xed:\xc8z\xbd.\xfd\xfd,\x98]\xa7\x1a|.Zv\x86\xcfW/\xdf>\xfb\xfc\xf0\xf8\x9asB\xd5^\x1b\xc8T#k\x0c=\x87\xa2\xc5\x1c\x8dX\xef\xd5\x8f\x0e\xdf\xbcy\xf1\xd9\xe1\xf1\xa7\xcf\xde\x1e\x12\xbc\x8f\xd9Nh%:\xb0\x10\x93\xe0\x8c\xcf`5}\x9e\xc4\xcb\x86\x15\xd9\xe5[S\xeb\xb7fA\xba\n\xfd\xcb\x97p\xe3\xbb\x13G\xce\x80\xf0j\xf5X]\xac\xab\x1e\x8b\xd6H\xd1\xd4\xce_\x13\x1cgK(\xb9B\xed\x11\xa1\x9a;\xaa\xb8a\x8b\xfa}W\n\xb4\xc7\xd1d-\x15\x17AJ;\xf7\x9b\x0f\x8c\xda\xe2\x88.C\xa6\x19y\xa4\xabP\xd6\xd0\xb5k\xf7\xca\xd2\xa1\x1b\xf4\xc5\xd8;\xd6\xe8N\xad.8\x13\xaa\xa7\xed\xb3\x85c\xa4B\xcb#\xb2\xf4Z\x08\xa9\xed\xc6kt{\xa5q\xa9\n\x84E\xda\xba\xf0+\x98\x87\xce\x1d\xd8\xe8^\x94u[C\xac\xba\x8e\x82\xa8\xbdU\xf5(>\xaf\xdd\xa6_=\xd0\x9f\xba)`\xd4\xd9\x14\x90)\xb1\x97\xe0\x16A\xd3\xd9\xed\xb3\xe2 \x9c\x8d\xd8cw\xc1\x88\xf6y\xe8\xa7\xe9\x88\xfdV\x9c3\x1f\xf4!\x19_\xae\xb2 :eY,C\xcf0\x9f%<\xe5\xc9\x19\x9f\x01\xa6\x88\x9ez\xec\xeb_I\xbf\xf60\x16>n\xd8\xd1\xd1\xdd\x8c\x9dp\x06\x11\xf2A\xb4\x0b3\xdac\xef\xf9\xe5\x80}\x86M\x05\x19\xf3S\xe6G\xa5\xc1\xb4j\x11R\xb8?{,\xca\x9c\x07a\xc8\xd2L\xfc=\xe1\xcc\x9fNy\x9a\x06'a\xd1\xb8n.~\x97vRo{\x94\xd8\x0b\x80\xd6A\xea\xa5\x1e\x90~\xad3;L\xe3\xb9Cs\xa2\xd9\x01\x0b\xc7\xd1D\xca\xe9\xbb\xf7\x83\x95\xa7\xcb\xc0\xa1\xb6C\x10{\xe4\x1e\xebu\x9e_1\x95\x02\xb2\x97q\x9eh\xb6\xc2\xa0 \xcb\x16~\xc4\xe2h\xca\x07\xec\xdd\"H\x05\xe4\xe7a0\xcd\xd8\xd2\xbf\x14s3\xcb\xb9h\xc9\xc7Mm\xd0C\x07\xc8gq0s8\xc6\x95_\xc0\x8b\xc7\xa8\x80S\xb6\xa7Y\xff\xab?\xf2#\xb4\xc7\xe5\xfa\xd3\xde\xac\xbd\xc4\x07\xa42\xeb\xd04?\xcf\xe2\x93 \x9aU-\xee\xd7PA\xd3\x81u\x98f#\x98\xd6\x11+\x13\x88\x95\x8e3;b\x9d\x10U\xee\xdc\x11\xc8Te\xe1\xd0Ml\x05\x8f \x12\xc2\xdc\x9fr\x1bB\xc5g`\x87Q\x9a#\x86eXj\xc9\xb3ENDg\x9f\xe5Y\xfci\x10\xcd^\xfbAb\x89TY\x8dR\x19\xd5\x97\x99\x0f\xcbl:@\xee\x1f\xa6T\xbe\xbb\xa4\xbfw\xf5\xc0\x1c\xd7\x1bC\xbb\x8a\x1cC\"\xb6\xedJg\xf2^h4\xce;X\x8e\xad`\xd8\xc6\xf7\xda\xf5\x80sg\x85!w\xa6fm\x97M\xc7\xf9D\x0c:li\xa9\xc1\xef\xb3\xfe\x881\xcd(\x02\xd8\xd6S\xd6d7\x0d\xc6+\xe0\xac{\x05\xb7\xdc\x86H*\x06\x8a\x92w\xdb\xc1\xc0P\xbfmR\xf4\xe7L\xba\xcfN[\x03\x96\xeaO\xe0\x80\x13q;\x13\xb0\xac\x13@\x99\\_\x81_E\x85\x11\x81 \xd1l\x15\x87\xc1\xf4\x92\xfdJ\n(\xfd\x9e\xc3\xeb\xf9\x82G\xb8\x02O\x81\xdd,\x96\xa6\xa8\x02\xc4x\x89\xb3\xdf\xd0\x9d\x03\x96`\xe4\xd2\x85#^\x042\xb0\x11\xd5C\xf4\xe0\x8be\xcf\x8a\xb2\xdd\xa0/\xddA\xcb\xda\x1d8+(\x1ec\xd0\x93\\|\xc7+*7\xd6m\xe0\x15\xcc-\xbe\x13\xa1\x9fY\xf7\xfb\xea\xb1$p\xa4AY\x83\xaf~\"=\xf3Xo\xc9\x93S\xaeB\x1c\xbd\x8c?\xcbW\xa1\xd8\x90\xf9o\xf2\xcb\xd4qG\xec\xb9\x1f\x89m\x17\x8a\xb1(\x8e6\xb1\x99\x14\x08x\xe62\xe2\xc8\x82Q\xca*:=`\xf8Z\xbf\xf5.\x91\x06-\xf8\xb5\xec<\x96\xf4;\xc5\xed^p\xfa\xa9\xbf\xe4\x18\x06]l\xbd\x9dv\xd6\xc7\x02D+\xf0\xf0*\xf6\x044\x92SE\xa7~\x9eJk\xb2\xf3\xb8.\xb6u\\\xb1\xc5\xd5\x0e\xd3\x8e\xab8\x0e\xc9w\x8b\x15P\xe9\xa7\xd8\x1c\x17\"\xf5=\xbfL\x15\x0b,\x19S\xcb\x0dUeB\xd8 -\x16m\x96\x88:{i\xdd\xf70\xb04F\x83\x15\x10\xf1\xcaH\xb2\x96{\x8e\xe2\x81C\xad\xa5\x96]=\xaaL\xe2\xca{(I{\xe1\xd2\xd6#\xb2\xef\xde\xe0^\x98\xf0\xd5\xcc4\xa5\x9b\x13\xe3\x14\xc0\x0b\x1dV\xa4\xdbz<\xbb1\xe0\xad\x00\xb7\x02\xf5\x9a]]\xb6\x1e\x1524\x9e\xa3\x94\xc4\n\xec\xb5/\xd5[1C\xd1\xa9\x87P\x13\xb4\x82\x86)\x83\xd6\xe3\xe3 \x85J`\xe3\xb7\xb1E\x96&H\xaa\x89\xb4\x97\xed\x1d\xac\x88\xea\xaf\xddG\xda\xde\xa5S\x1fO\xac}\x94\xfe\xc1\xa5\x02\xa9\xb3p\x0b\xfa\x87\xf2\xf8d\xc0\xa3\x9f\xe5<\xe7o\xb4\xa6$\x86\xad}z-\x06\xdc\x11N\xca\x16g\xa3\x0e\xb0\xeb\xc3\xea\xd8\x1e\xd6\x97iF\xa2\xce\xb1\xaeT\xd7y{vB\x90\xb6\x12\xb2M\xe42\xab\xa9T\x93\x06sPV\xa2\x89yXP\x91\xd7\xee\xdc\xe9\xf0e\xf5T.\x11r\xb2]\xcf\"\xeag\xfd}\xb6\xdd\xd6>\xab\xc9,\xdb\x8f\x05L\x9e\x88\xb2q\xc4\xfal\xd8\x81O\x85\xe0\x0b\xfbH\x99\xe2\xeb\xfaA\xf8\x00\xe8\xab\"\xda\xad\xa4t\x9b[C\xe7&|\x0e\x0e\xc4\xbc\xca\xbaP6\xeaQi1\x9fq\x19\xcb\xc7>\x90\xc2\xcaWT\xa9\xb1\n\xec\x80Lv\xdcV\x81^\xe0\x10\xacY\x0evuUs2`\xa6\x7f\x85\xf8\xc4\x88-\xc5\xc9W\xa2\x7fq]]\xf0.\xe2\xd3=\xb1\xb9\xe8\xea)q\n@~_P\xc14\xd0\x14w=\xb7\x06\x91\x9c^\xad-'\xde\x04\x84\xe5\x15c\x97\x88\x9f\xb3cOO\xac\xf8\x10\xc1h\xc8Z&\x85\xe22\xa8_>\x90!O\x9d\x95n\x00\x9e\xb9\xae\xc7VN\xe6\xb1S\xf5\xc2\xd5\xcb%\xec\xb0u\xb5\x08\\EP\xc1\xe6\x0bMI\xbd\x98\xe3\x82\xacB\xef\x1c*\xda=\xd6\xc3\xc0\x07pnr\x06\x83\x81`\x98M\xd1\x16NO\xb0\\\xa15\n\xf3\xd9\xd7\xd8\xc0\xd7\x92\x93\x04f:u\xf5\xf1\xcb@%N-I\x86\x9bj\xe4w\x9a,\x93n`\xd0s\xd6\x12\xd3\x0c\x0co\xca\xe2\x91cs\xe6g\xa7zr\x00F\x0cg\xee\xca\xe0\x96\xc3\xfb;\x10\xdd\xf2v\xc7\xb3\xbdG\xdb\xe2)\x1b\x00\xb1\xd5\xc5.Ek\xfd\x12*5Z\x0b\xc1X\x1f\xeby\x96#$\x8f\xf2%O\xd0\x01\xfe\x86%\xd0\xe8)\xef*]Q[\xf3\x80\x96\xb5\x13b\x82\xc6\xbe\x07\xdf{\xbf\x83[\xe9\xb7D\x93\x8e\x9d'\x1b\xcf\xea\x08\xc4\xf6\xd9\xd0Bv\x18uz\xb8\xc1\xfao\xa3E\x80\xb7\x9e\x14A\xe3M\xa3*\xca\x927\x95\xe0&\xf5 >Iyr&\x86.\xce\xdcp\x0bXK\x1a\xc9\xa0\xbc\xe2P\xad\x12{\x10\xd1]+\xb4\x8fvr\x19:\xc7\xd6\n\x92;\xf0\xf7\x02\x91\x8a\x80\xc7\xf0\xcf\x00Bn\xa4\x98[\x8fYP\x11\xf0\x04\xb4\xcb\xa2\xb3\xc2)N@\xc8f\xb6<\x1a\xc4|\xecO\xf0\xe2\xa7xA\x07G\xb6\xbd\x8ai\"\x11\xbd\xc7u\xeb\xab-\x93\xd8\xa6\x16F\x8a\xe6\xbc6:\x08\xca\xaa +\x04\x04E\xc5F\x91\xe9\x99\xe6a\xabY\xf2\x85\x07C\xec\xbamm\xeaO\x06\x1e\xc7\x04;\xfb\xe2\xe5\x8bw\x8d\xc5?\xb4\\Q\xd5No\xb1\xcb\xb2E\x12\x9f\x83P\x05n\x119w\xdf\xf0Y>\xe5 \xeb\xdde}\x96\x81\x1b\x90\x9e\xc4`>c\xc5V\xc9fy\x82*[\x90 \x05\xdfH\xe3\x9b\x17sT\xaf\x81\xd8g\xe5\xa7)j\xe2DZ\"[\x0e\xd2\xb2\x19\x8f]\xc69\xca5\xf8\xc5*\x0c\xa6A\x16^\x16\x0bf\xc1U\xfb\xd8\xe0\x80\xbd\xab'\x81\xfe-\x8a\xc1B\xb0h\x15\xba!\x1a\x9e\xc5\xd1\xdd\x8c\x9d\xfbQ&:\x91\xf2\x8c\xf9\xd2\x01\x81X'\xa0\xbf\x93\xbd\xc2\x8eL\xfd\x08\x0c?\x80\xb9\x91\x86\x83,\x9ek-7\xb9\x96\x11\xd3\x1f -\x10\xad^\xdc{\xfd\xe6\xd5\xa7\x87\xc7_\xbd\xfc\xcd\x97\xaf~\xfc\xf2\xf8\xd9\xf3w/^\xbd<\xee\xb1>\xfb\xd2\xcf\x16\x83\xc4\x8ff\xf1\xd2q+\xa1\xcd\xb5\xe0\x9e{\xee ]\x85A\xe6\xf4z*\x80o\xe3\xe7k\x93\xdb\x15\xbd\x10\xb5\xe8\xed\x86\x01>\xdd\x00K@\xbb\xbfJ\xe2\x13\xf1\x1ed\x0b\xe63\x1c6|v\xc0>\x83 \x12\xcb5\x8b\xd9\xc2\x8ff!z\x99P\x98\xce\xfa\xec.\x8b\x13\x16g\x0b\x9e0\x1f\xd6 \x88\x18z\x08\xe1Ozh\xd6\xb5\xf2\xd1<\x8a_\x82\x8d\xd54\x06/\xa3 X\x96\x06g\x80:\x85yO\x81q\x1a\x9aM\xf3$\x01\xa3\x03\xc0)\x81\x1c~t\xc9\xf2\xe8}\x14\x9fG\xea\xbb\x1e\xcb\xa3\x90\xa7)\x0b\xb2\x1a\x12\x07\x11;_\x04\xd3\x05\xde \xa4>PAZ\x8f%\xfc\xd4Of\xd0X\x8c+\x06\xbf!\xc1\xd2\x0d\xcd\xd1\xa9\x86\xc0\xd9\x13D\xd9\xc1]\x8b&\x86\xd0\xfe95\xd3\xa0\xca\x01\xd3(\x0e\xc2\xf1\x06\xfa\xddEo)\x96\x87\xd83\x0b\x9d\xa4\xd2`\xc6\xb2\x12\x14\xc9\x80\x8f\xb2\xf8*/\xbd\xbc\x88\xceb4\xdcz\xed'>\x84u\xff\xb2\xf0\xb1\x9b\x15\xac\x84\xf4\xf4@\x124\xf0\x16$\xb6\xae]\x97\xd8\xbbD\xd6\x83]#+(\xb2\xf6\\\xf2X\xeb[\x95\xba\xd2v\xa4\xb2\xfey\xf3\xfa\xb7\x1e\xc0\xb5\x05_\x1bj\xa2\xe6\xd8[\x0bd\xb1^\x8d\x82\xff/1\xe9\x15\xbds\x04\xe5%\xa61P3L\xcdU\xf0}\xcf\x15E\x9c\xed\x8e\x9f\x82\x1a\x89\xa6\x0e\xb5\x1b\x81\xa4\xb9\xa5'\xbb\xb7Y\x9cp6\x8b9zc^\xf8g\x1c%\xf3\xc1L\xc9\x1c\x06\xecK\xff=g\xf2*//#\x8c\x94J\x85\xfa\xe6\x1b\xa4\xday\xf7|\x11\xa7\x1c\xa7&\x05\x99\xb0l7\x1d\x10\xc1k}I'\x0b\x14s\x0d\xed\x13\xba\x0d-\xb6\x84\x17\x19\xaaM\x07A\xaa^\xf5\xb8.\x85\xbbd\x1f$\xd8A\x8aB\x91\xe2\\\x9e\xd5\xa2\xa2\xa8\xc1e18&\x88*\x81\xdf^,\x979\xc4\x83/\xbeZ\xdec\x9a\xc7a\x18\x9f\x07\xd1\xa9rx\x10\x80S\xaa\xbb\xac\xcf\x02T\x1a\xdc\xedy\xacw\x17eL\x83\xbb\xe6\xd8\xe1\xc0%f\xef-\xff\x19(#\xf0\\\xe8\x0e\xe6A\x98\xf1\xa4\xe5\xa8 \xc7\xbba\xdc\xdf\xaa\x1da\xeaZ)Y/\xd7e\xc0\x07\xac\xa7]\x19\x04\x81\x04^\x94,J\x1d\xb0\x9e\xf2\xeb\xd0c\xa3\xe2G\xc0S\x14\x97\xe1\xc0ss\xe0l\x1e\xe7\x118\xa5\xbe\xab&E\x03\x7f\x16\xb3y\x10\x15a\x83\x04\\Q\xf0\xaf\xe4_\x853 \xbcC.\xc5\x1a\x0dp\xd6\xef>\x96\x9dD\xff\x13'\\J\xeaf\x83\xbbuw\xca\xb7\xbf\x1b\xde\x1aE\xf3\xd6\"\x0euo\x9c]tH\xa4d\x13UH\xa0\x1a\x12X\xaed\xa7\x97+)\x0bEQ\xe7\xad\xc8?\xeb\x02(M\xb6y+\x13\xa4W\xacB\xab\xa0\xd0b\xd7\xae\x07\x00/\xe7\xa9:#]>\x199\x8fP\xc4\xfd\xe8\xa1[\xedy\xe4<\xd8\xdb\xead\xe0Y\x1e\xa1\x87\x86\xafC\xe9l\xf0\x91\xeb\xf4\x8a\xd8\xe0\xa4\xad\xf3\xde\x96\xc5\x8a;r\x86\x0f\\\x8d\x8a\xaeq*\xb0\x1d\x084ER6\x8e\xd1c\xad\x16\xbb\x1c\xee\x14@4\x81:\xcdJ\x1c]~\xd7 \xc0\xcdV\x86\xf7~\xe2\xfc\xca\xf6\xd6\xd5Q\xea~\xe2\xfc\xd4?\xf3\xd3i\x12\xac\xb2\xab\x99\x9f\xf9\xee\xbd`i\xc2\xf2\xde\xf8'G\x17\xdb[\x9bG\x17{\x87\x93{\xa7\xf5\"\x01\xb69\xfe\xc9h\xd2wG\xf7N\x97\xe6qk\xdc\x1b\x08Bt\xaf7\xa1\xe1]\x05h\xeaGA\x16|\xc3\xbfJ\xc26a\xd5\x99\xb4\xb5\xf1\xe4\x8e!\xaf\x95\x89cA\x8fRKw\x12\x10j\x05\xfd\x010\xec\xaf\xe6\x0e\x1foM\\\xf6\x94m\x12\xee\x97\x9d\xdc\x95&\xe7N\x04\x12\xc0\xa5\x9fM\x17N\xe0\x8ad4\xd9\x11\x873\x96\x0c2\x9ef\xe8\xb6\xa4\xe7\x9f\xc4y6: \xfd\xe8\xbd\xd86r\xb8\x1d\xae'V\xbe\xb3\xa6\x15e\xb9<\x1e\xd8\xec\xff\x1f\x0e]#\xdci\xc3f\n.\xa2\x07Y\xfcE|\xce\x93\xe7~\xca\x1dpG\x02\xfa\xa3\x03&\x90\x94\x8d\x0c\x1f\x1f\x96\xe5\x15\xaf7\x84]\xca\x9e>r\xb6\x1f\xda\x96\xaf}z\x95\xb0\xdbI\x1c\xeeVG\xb3\xe6\x1a+\xbb\xb7W\x17]|/\xa6\xe4`H\xdelF\xde\x0d$g\xff\xbf1y1\xc7\xf5 \x8e\xba\xd9\x8cw\x03t!d\xb9\x96\xe5\xb8\xbe\xa2)\x84\x13\xeb\xc1r\xa3g\x8f\xf2\xaf\x0b\xcb\xea\x9aCh\x96\xf5\x80\xc5\x03\x19\x94@\x814F\x12\x18 \xd1\x90\xe2y\xa34\x93\xa8\x0e\x96\x91hd\x91\x0d\xa6\x0b?y\x969[\x16%L*\xcb'N\xe4\xb1\xa1\xb2P\x82\x08!\xd9 \x0d\x83)w\x1a\"\xb0\xe4c>\x01\xc5wU\xd8\x7fm\xda\xbb\xfd\xb0\x1d\xc4\xf6cl\x0c;\x9a\x14\xdf\x93\x98T,2\xe9\x02\xea\x80\xc5\x82w\xf7\xd8\x06\x98\x01D\xec\xe9>\x8b\x95Ux\xf1\xa9\xeb\x8e\xe6\xc1^\x9d l\xc1\xbb\x9b\xd0g\x8e\x08\x02\x97\xb4\x92\xf6\xc5b\xe3h[\xbf\xc4Ks\xb65>\xa1\x10\xb97>:\xcag\x0f\xb7\xb66\xc5\xff\xf9|^\xbf\xf4\x96\xa8B[;Xhkgw~t\x94\xcf\xf96\xfc\x9c\xf3m\xf1s{k\x06?\xb7\xb7\xcc&\xe0\xc6\x00|fg:\xc6\xcf\x9c\xd8>\x07\x86~\xe3\x9f\xb4t\n.\xf49\x07#\xbd\xd1\x19\xdf\x85\xe2\xb3\xf9|\xe2\xfe|\xfb\x03y\xc5Oo\xf7d>\x9f@\xc2\xd4\xfe\xa1T~\xa8\x08\xe1sU\x84\x01r\xc5[\xef\xa0V!T\x9f\x99\xf3-\x8e\xff\xe6\x93\x03\x15\xe1\xc9\x91\x9d\xde\xde\xda\x9a\xc9V\xc7\x18\x93)\x9f\xc8\x95~\x85A\xe2\\k\x1b=\xf7\x93\xfaY`\xaa\xf5r\x1c\xa8\xae\x1e\xf4\xf0\x1a<(\x08\xa3z\xfb\xb5~\xcf\xd9\xbe\x0c\x8c\xe0\xc0\xe8\x9c\x83\xfdr\xa40\xe8)F\x8a\xec\x9d\xf6\xae\xbb&\xb8\xe4*\xe7p_t<\xb9\xee2\xde~hc\x08m\xcb\x98\xf2%/G\xdb\x1b\xdf\xfdo\xbf\xf3\xbb\x93\xde\x8dF\xd6\xbc\x9d\xa8\xdd\xdd \x1c\xb1o\x14,\xbe\x0f,\xbe\x0b\xce\x1ez\xbd\x1b\xdd9\xd2h\x9c\x058\x06\x0b\n\x87\x9e\xf1\xd1\xc5T\x1c\x8bf\xbbG\x17\xb3\x87\x9bG\x17\xf3\xdd\xa3\x8b9\xbc\xcc\x8f\xf2\xad\xa1X\x19\xf9\xd6po>\xb9w\xda\x00\xc2u\xc9\xc3M`\xed\x80\xd0\x1a\xa4\x82 \xa9U\xd0\x0c<\x96\xd4a{} \xdew\x9d\xea\xd7{\x7f\xf8;\xbd\x11\xeb=\xab\xad\x9b\xde\x1f\xfe1:\xf9\x8f\xd3\xc9\x7f\x82N\xfe\x1f\xe8\xe4?I'\xffC\x91\xec\x1b\xc9\xff\x88N\xfe\xc7t\xf2?\xa1\x93\xff)\x9d\xfc\xcf\xe8\xe4?-\x92\x9f\x1b\xc9\xff\\$O\x8d\xe4\xbf\"\x92\xeb\xde\xf1{\x7f\xf8\xefD\xf2\xccH\xfe3\"\xb9\xee;\xbe\xf7\x87\x7f\x96N\xfest\xf2\x9f\xa7\x93\xffg\x91\xcc\x8d\xe4\xff\x85N\xfe\x17t\xf2\xbf\xa4\x93\xff\x82H~a$\xffE:\xf9/\xd1\xc9\x7f\x99N\xfeW\"90\x92\xff5\x9d\xfco\xe8\xe4\x7fK'\xffU\x91\xfc\xd2H\xfe\xf7\"92\x92\xffG\x91\xfc\xcaH\xfe\x9f\xe8\xe4\xbfF'\xffu:\xf9o\xd0\xc9\x7f\x8bN\xfe\x0f\"96\x92\xff#\x9d\xfc\xbf\xd2\xc9\xff\x1b\x9d\xfc\xbf\xd3\xc9\xff\x89N\xfe]\x91\xfc\x95\x91\xfc\xb7\xe9\xe4\xbfC'\xff]:\xf9\xff\x14\xc9\xb9\x91\xfc\x7f\xd1\xc9\xff\x99N\xfe/t\xf2\xdf\x13\xc9\xf5\xd8\x01\xbd?\xfc}\x91|i$\xff\x01\x9d\xfc\xa7D\xf23s9\xfc\x9eH\xf7\xcd\xf4\xbf/\xd2\xdf-\x8c\xf4\xff*\xd233\xfd\x1f\x88\xf44\xad\xa7\x7fK\x93\xe5oi\xfa\xfb-Mh\xbf\x05\"n\x90\xb7o\xff\x04\x9d\xfc'\xe9d\x80\x80A\x0c\xbf\xfd3t\xf2\x9f\xa3\x93\xff\x02\x9d\x0c\x84\xd6\xa0\xa8\xdf\xfeY:\xf9\xcf\xd3\xc9\x7f\x91N\x06\x12d\x90\xe5oij\xfd-P&\x83Z\x7f\xfbW\xe9d \x13\x06\xfd\xfd\xf6\xaf\xd1\xc9\x7f\x83N\xfe[t\xf2\xdf\xa6\x93\x81\x04\x19\xf8\xf6\xed_\xa7\x93\xff&\x9d\xfc\xbbt\xf2\xdf\xa1\x93a\xcd\xfe\x9a\x91\xfc\xf7\xe9\xe4\x7fH'\xffc:\x19\x16\xe7\xa9\x91\xfc\x0f\xe8\xe4\x7fD'\xff\x13:\x196\xfb_7\x92\x7f\x8fN\x06\x1e\xc0X\x98\xdf\xfes:\x19\xb6Xc\x07\xfb\xf6_\xd0\xc9\xff\x8aN\xfe7t\xf2\xbf\xa3\x93a\xfb66\xb6o\xff%\x9dLo\x9a\xdf\xd2\xbb\xe3\xb7\xff\x9eN\x86\xed\xe47\x8cd\xd8N~j$\xc3v\xf2\x9bF\xf2\xff!\x92\xdf\x1b\xc9\xff\x89N\x86\x9d\xe0\x0b#\xf9?\xd3\xc9\xbfO'\xff\x01\x99\xfc\xdd\x1f\xa3K\xc3.\x13\x1a\xc9\xff\x85N\xfe\xafd\xf2w\xbfC'\xffq:\x19H\xaf\xc1\x8d|\xf7'\xe9\xe4?M'\xff9:\x196\x01\x83\xa5\xf9\xeeO\xd1\xc9\x7f\x86N\xfe\xf3t2\xd0o\x83I\xf9\xee/\xd1\xc9\x7f\x85N\x06Bm\xf0\x17\xdf\xfde:\xf9\xaf\xd2\xc9@c\xdf\x18\xc9\x7f\x83N\xfe[t2P\xcd\xc4H\xfe\x9bt\xf2\xef\xd2\xc9@\xa8\xdf\x1a\xc9\x7f\x97N\xfe\xfbt\xf2?\xa4\x93\x81\"\x1b\\\xc1w\x7f\x8fN\xfe\x07t\xf2?\xa2\x93\x81\"\xbf3\x92\xff)\x9d\xfc{t2\x90\xde\xccH\xfegt\xf2?\xa7\x93\x81\x98\x1aL\xe1w\xff\x82N\xfeWt\xf2\xbf\xa1\x93\xff\x1d\x9d\xfc\x1f\xe8d\xa0\xb1\x06\x0b\xf9\xdd\xbf\xa4\x93\xff5\x9d\xfco\xe9\xe4\x7fO'\xffG:\x19H\xef\x8f\x8dd \xbd\xe7F2\x90^\x83\xc7\xfd\x0eH\xaf\xc1\xcc~\xf7\x9f\xe8\xd2@z\x7f\xdbH\xfe\xcft\xf2\xef\xd3\xc9@L\xbf1\x92\xff\x0b\x9d\xfc_\xc9\xe4oav^\x98\x1b\x0f\xc0*0v\x9e\xef\xf0\xb8fp.\xdf\x01\xb3\x14\x9b\xe9\xc0X\xde5\xc9\x1b\xec\x1bi\xa9\xd9\xb5)Hi\x8f>\xd7\x16rw\x12\xb0\x11\xce\xd4F`\xa3[\xa9p\x03\xc9Z=\xf6\xa3\x12;R\x96\xdf\x84\xc4M\x9am?l\xf7\xbcG\xabT\n\x0b\xc5}\xd0+x\xba\xea\x04u\xf4\xfa\xc0AA%\xd5\x10~\xa9\x86\x80\x00T(\x87\xcd\xba\xc9a)\xb5\x01\x18Tlmm\x1e]l\xcf\x8f.v\xfc\xcd\xa3\x8b\xfb[G\x17\x0fN6\x8f.v\xb7\x8e.\xf6\xc4\xcb\xde|\xd2\xbfw]%\xa3\xeadt\x93N\xfa\x9b\xdfL\xc6\xcf6\x7f{r\x05\x7f\x7f\xbe\xed}\x80\xb4\xab\xf1\xd6\xe6\xa3\x89x\xc5L\xf9\x02\xa9W\xe3\x9f\xe0\xcf\xad\xcdGlr\xef\x9a\xdd\x8f\xd0Pb-\xb5O\xa1\x939:\xba\xf0\xa7GG\x17'\xc3\xa3\xa3\x8b\xd9\xde\xd1\xd1\xc5\\\xfc\x01\x01\xab\x008B\x1c@\x8e0\x07\xa0#\xd4\x8f.NP\xe0\xba%\x05\xae\xbbsvt\x94\x89\xea'GG\xa2\xae\xbf\x05r\xd9\xf9\xfc\xe8(::J\xa0\xd0\xf6C\xfc\xf7\xe8\xe8(\x1f\xee>\x14%\x86\x0fA\xf9 \x1a\xc2\x7fC\xfc\xb7\x8d\xffv\xf0\xdf}\xfc\xf7\x00\xff\xed\xe2\xbf=\xfc\x87mn=\xc2\x7f>~\x01;\xf7@\xfc\xdb\xd9\xda\xda\xaa\x11\x18\xd46\xf5X\x9fE\xac\xcfz\x16M\xd2\xac\xdf3\x17\x1cH\xa1\xb7\xf7\xe4\xb0\xf7Nh\xa5\x91\x98j\x01\xd4\xb9\x80\xd4|\xf7\x08\xa5\xddG\x17\xa6\xea''5Q\xaak\xa0\x18\xa9}\xd0\xda\xf4\xb3\xcd\xdf>BA;H\xdaQ\xd4~t1\xe36u\xd3\x1az\xad\xf0Zz-\xd0\x18\x8d;\xf7k\xae)\x98\xfcB\x0d\x96S\x8a\xa4\x95Vt\xda\\t&\x8b\xae\xa9>\xb8\xb2\xa9\x12\xdd\xba2naU\xc6\xcd,\xca8R\xf5\xc8R\x8f\x85\x9d\xf4s3Z?wV\xd1\xcf\xd1\xed\x89\xbc\xda}\xcbe\xa9b\x19OQ\xa3\xa7\xe0\xdf\x17`\x03\xc5\x95s0\x9a]\x85\xe1\xd5\xf2*\xe1W\xe9Uvu\xc6]\xf7@\xaa\xef\xc6\x89\xc7\xa6\x1e\xeb\xfd\xb0g\xaa\xff\xd8\xcah\xe8\xb3\xab/\xbe\xb8\xfa\xf2\xea\xcd\xe1\xd5\xdb\xabwW?:\xac5\xc4\xfalnk\xac\xec\xdf\xbcK\xffT\x8d\xb6\xcf\xf79\xc0\x1d\xeb\x87\xd7\xa6\xec\x1b\xce\x06\xd8t \xea\xa6l\x10\xc0\x14\x97\x1d\xb0\x15\x18A#\xe3\xef\x17\x0eG\xd9Z\xa8S\xdc\xb5~d\xbdk}o\xfc\x93\xc1\xa4\xff\xc3{\x03~\xc1\xa7N,z\x10\xc35\xb1\xf2m\xf0\xe2\xf0\xf8\xf5\x9bW\xef^\x81\x91~\x0f\xac\xb8{\xe8\xc8\xd1I\x93\xa9{<\x1c\xa0E\xd3\x88\xf5z\xd7\x85\xc4F >\x18@`\xd6k\x8c\x14\x91~\xcf\x1d\xf7\x8e\x8f\xa7q\xc27\x7f\x9a\x1e\xa7\x0b?\xe1\xb3\xe3c\x9b\x95\xfdu\xa5\nv\xdf6\xed2\x83\xf6s[7\xb0\xa9\xad\x01\x88\xcb\xc2\x87\xcd\xe3\xce\x1de\xde[!JcN{\x05)\xe9\xd2\xe6>\xcb\xd8\x01\x1b\xb2\x11l\xda\xd7\x05\xbf\xa0\x9e\xc4 \xeb\xf88\x8cg~\xba8\x16{\xfdqqg\xe8\xf8\x988v\xb5\xb8OX\x17\xb9*PR\xf0\xa8\x02#\x983\xc7pZ\xcc\xb4\xf3sf\xc0\x8fULN\xf7\xd1\xa6\xb4\x98\xee\xa6@J\xb2VPx\x15\x86\x95.\xbeP\xd8\xfd\xde.\xf0\xbf\x7fx\x16\xc6\xe7\x07\xd5+>0\xc4X\x1b\xf8\xed\x0e\xb4\x01\xcb\xda\x06\xd9\xe4=\xacu\x9c\xe5\"\xeaW\x17#rdC\x8fEb\xe8\xfbh\x8d\xaf\x89\xd82i\x9d\x9c!\x83pS\x02\xd1\xc6\x96\x8c'\xb7\xc4\x88\x0cw(\xf6\x18\x83\xd7h\xcc\xd8*\x0c\xa6\xbc\x0d\xf2\x9d\xd0\x8bf}\x13D\"rN6\x9c\x88=A\xc7\x11N\x04\x9e\xa0\xd4\xd5\xd4M6\x14\xebm\xb0\x8a\xd1WD\x89\x8f`\x1e\xef\xb1\xcd\xcd\x02H\x1e\xdb\xba\xd6\x9e[@\xe9\x174z\x1c\xbb.\xba\x1dG\x93\xf1\xb0m\x0b\xba\xd5\xa1\x146\xaa\xd5\xb1\x08rW\xb91\xf6\x11\xba\xd2u5\x9b\x80\x8d\x01\xb0\x91\x15\xb0\xb1\x04\xac\xd3\xefkH\x12a\xec\xd0\xb1\xf8\xf0\xc4\x85\x08P\xe3X\xc0[F9j_\xdb\x0d\xc3\xddn\x1d\xae\x0d\x89\x12\x15\xf9\xcd\x95G+\xdb-\xa1\xebr\x01\xad\x14\xc9\x8e\xdf\xd2S\x1d\xd9\x9d\x1e\x9e\xe8\xd1\x81\x1b\xf0\x9bQ\xbe<\xe1\x89\x96\x90\x02\xe7\xa9%\x9c\xc4q\xc8}\xe9\xf4M\xf0\xa6\xc7\xc7@\x89\x8e\x8f{2\x10\xc0Hs\xce\xf7}\xceFe\x1d\xc0d\x9c\xf2\x0eb\xfc\x8f\xdc\x07\xdc\xa1>f\x1f\x1a\x16a\xd9\x0fz\x05F\x80\x8c4e\x03\xc1\x034\xeeU7\xdeHnk\xc8\x8a\xc9\x8d\xf7fK\x8f\xb6{7\xae\x8eI\xe5\xdc\xfdV\x90X\xa6\xa5(\x80{\x10\xe9u\xef\xac\xe2w\x9d\xbcI\x06\x8e/b's\xa9\xfa\xaa\x8dT\x11\xb8\x1d\xa2\x05&o\xaa\x05\xe0{(j\xec\xbb\xfe\xc8q\xa4N>\xe6\x13\xb8|\x90wu3k\xa6\x9cI\x8f\xbc\xbc\x00\x87\x95\xf3\x0ea'a\x07,\x1f\xa7\xc0C\x87\x82\xc1\x0c F\x9a\xb1\x1bH\x03w\x87\xf5[ \xf2\x02\x84!`AL\xd8~\xd4*A\xb2\x12\xc6\xd8F\xa3\x87\x15&\xe6\xce\x1d\x96\x8d\xb7&\xe3\xed \xde\x19\x14\xef[\x82\xbd\x13/\xc3\x89\xd8\x82\x8ao5\xdd`\x8e\xa4\x13Q\x88\xb6\x16QAB\xaf\x0d\xb5\xa1qwF]\x8d\xa3\xa064%U\xdbm0\xc4\xaf\x0bd#\x80\x99\x02\x1d\x91n4\x8d\xe1\x0b\x04K\xcd\xe4)\xdbg\x1b\xb9y8,\xce\xf4\x85\xdf\x98\x8dZ\xfc\n\x10\xb0\xf2\x8a\xc7\x03\x96nnZ\xa5\xabs\xd1\xbdqjq}=\x85`\xa18\xbbs\xc1G\xc0\x166\x9e\x8f\xb7&\x02\xb97\x1c\xf1\x06b\x92\xd2\x93\xcdFS\xac\x0f\xe8\xdec\xd6\xef\xa7\xec \x0b\xad\xbdZ\xb1}\xe6\xa8\xae\xb9V\xe7i3\x10\x0d\xaf,\xb9\x0b1IV\xaf\xde\xc5\xd0l\x04\xa5\xe6\x90\x04B\xdco8\xab\xe6\xd1\x8aG\xc6}\xb7\xd3\xbe3\x86Q)\x1bBQ\xe7.\x94\\\xb2}\x96;3\x8f-<\xb6\xc2U\xe1\xb13\x0b\xc5\x04\xba\xabwy f\x12\x0b\x8f\xcd<\x16\xb0+y_\xeeL,\xcae\xf3\x08\x1afP\xd5\xba\xc1\xa1\xad\xf5\xeai}J\xea\x07HT\xd1\xacu\x86\xbc\x01\x8b\xd8~\x04\xca:\xf3\xb5\xa2\xac\xe4\xd5o\xbd\xc3\xfa\xc7T\x7f\xbb\xf1x\xb7\xf4\xad\x9b\xf2r\x16\x8d\xe0C\xea~\x9fH\xaf\x97\x07b\xbd\xd5\xead\xa1\xeb\xa9\x8c \xbfLy\xd9\x8a\xe7ft1\xa6\xb1G\x91\xa5\x15V\xf0Gb\xab+\xdcT=a>\xdbd\xc3bM\xe6\x95\x83\\\x15\xd3\xfb\xfdH\xa2\x90H5\x9b7\xc6!\x17L\xe0\xe4\x1d\\M[\xf8Z\xc5\xd6\xde\x90\x93\xb5n\xc5u1\x9ade\xb7\xa9x\xa7\"\x9d\xd2\x1c \x14\xaa\xab?Sl\xbf\xaeq\x08ew\xea\xcdL%\xdfTO\x9f\x9b\x9c\xc1J\x0f\xac\xfaLy\xf0\xac\x9b\x97\xcc\xaa\xa5\x12\xff\xb2^b\xa1\x97\xc0M\xbb^\xe4\xec\xe6\xc2S\xc5\xa2,=v\xea\xb1K\n\xffO\x04+\xe2PG\xa1c\xc8\xc9\x88\x9cs\xb6\xcfN\xd8\x01\x9b\xb1\x11\xcb\xc9\xba\x87l\x9f\x1d\x17%\xa86.\xc4^/\x1a:\x17\x9c\xcd\x8a\x1d\xb0\x05\x1b\xb1sW\xfc\"8\xa6\xb7\xa2\xb8h\xf5P/~h+\xfe\\5|h.\xe7\xe7bK\x0fA\xd7e\xaedX\xa5!\x9cb\x8a\x8d\xd2\\l'\xe0+\xc5\x83A42>\xc5\xf76.\x8a\x06/A*x\xa964\xd7c'\"e\x8a\"\xdb\x98\x98\xb5\x11\x0bd\xeay%\xc3\x1c\xdb\x86\x13\xb1;lN\x0eM\xcc\xf6{\xb6\xcf.@\x0c\\\xb8\x96\xe9\x1d\x1f\x9f'\xfej\x05\x82jb\xa2\xc4\xf3\x8c\xed\xb3\xb7Z\xb5\xac^\x8d&w\xef\xc5\xb8\x9e5\x9d\x07_\xb1}\xf6\x9e\x1d0>\x00Wr \x11mp\x9a\xfe\x9a\xed\xb3g >-\x8bg4[d\x05\xf6\xa9\xf3\xcac\xaf\x15\x1c/\xdb|^\xd3l\xd0\x06L\xaac\xb6\xee\x9b\xd3w\xfd\xad\xd1\xd8\xea\xe4\xc1o\x9b6\x96\xd9\xdd\x1ev\xf5\xe3zv\xcbf\x1du.M\xb7\xef\x80\x02\xfel\xe6\x80w\xe1\x1a0\xc4\xe3k\xf4\xcd\x9f\xcd\xc0\xabP\x99\"\xb6D4\xca\xf0\x0d\xfb\x8b\xa0jj\xe1\x93\xf0\xad\x037\xba\x99\xae\xa6\x13O$w\xd3\xc8\xed\xb4s~\x9f\x8cX\xfb\xb7\xec\xbae\x00\xbb\x93\xb5}\xc2\x8a\xd06/I\x86\xb9\x93d\xf5\xb6(7\x17\x14\xdf\x90K\xfc\xafo\xf8\xa9L\xaf\xb7\x13\x9a\x1b\xbb\xe0\x01\xb6\xcd\xed\xbf\xd8\xa3?E o}\x93\xae\xf0\x03\x9f\xf9\x99aiZa\x05\xc0\xa3e#+\xf0\xa5\xbf\xa2\xf8\x00-\xd8\xfb\xf2\x84\x1bM,\xf5\"h\x97R/r\xaa\x17y\xcb\x0dn\xe3\xb2\x92\x0f\x12\xf0z\x91\x93J\x11\x10\x81\xd7\x8b\x1c\x1b\x8c\xcf\xa7\xf9|nv\xf8\xbc\x066\xffG\x01?\xaf\x17:,\x9c\xaa\x15\xeb\xde\xe2\x9b\xea\x02\x18\x83\x03v\x88\xfb\xc2\xabyg\xd7k\x8aX'\x1e;\xf4\xd8[\x8f=\xaf\xe3~z\x1e\x80\x0f4R\x8e\x05q\xdc\xceGF:\x93; \x1f\x9c\\f\xfc\x0bd\xf77\xc41P\xfb}u\xc50\xff\xd5|\x9e\xf2\xac\xcc\xc7\xdf\x8d\x1c\x88x8x\xa3:\x01\x00{\xd2\x1b \xfe2\xcbCG\x8f\xe9\x8e\x16:\xcb\xb6\xden\xbcu\x04u\x8f1\x18\x0c\xbce\xaeKl\xfe\xf0\xb5\xb9\xf95H_Y\xd2\xcf\x1a{\x178}\xee\xb1>%y\x86\xda\xb3\xc6\xda|\x10\x81Oq1&x\x03O+K\xe53\x1c\xc2\x9d\xe0\x0fK\xf3KK\xa7/\x9b?\x8b\xfa\xa0~\xc5(\xa9R\x7fA\xd7W\xbcZn\xa9vj\xaf\xf6\x0c5\xfd,\xb4\x8b\x8b\x80/sD\xfb)x{\x85\xb3\xde\x86\x12R\x00\xbb\xfa\xac\x15\xfb\x14\xfb\xf6\\\n\x1b\xec\x9f{U\xb4\xf5\n\xe0aa\xd8\xd8\xd5>\x9bz\xecyy\x14\xb5\x7f\xf858\xb4{\x0f\x88\xf8\x1eC\x15\x94\x0b\xb8\x91!|^\nm<\xf6\xda\x02\xde\x13\xfb\x8a.\xf9\xf8\x0b\xe55P\x0cJ\xfe\xb0J\xaf\x99\xb6\xce\xda\x94\xcf\xed[\xf4\xba\xec\x9c\x0c\xe1\x04\xd3K\xcb\xaa\xb8\x195\x82\n\xa5\x0e\x0d\x8e\xfb\xfdl\xc2\xf6\xc1\x86\x9e\xd7\xee\xa2\xb9\x1fC\xc4\xf5q\x86\xd786\xbe\xf6\xb0\xecv\xb3\x8f(\xf1\xc7\xd0\xe4xn\xe9\xb0\x8f\xf2\xde\x94\x02\"\x08@\xd8\x1d\x16\x9bp\x9c\x82f\x8e:\xcb\x0b6hJ\xf2\xffb=\xcc\x05\xe1H\x9c\xcc\xd5tC\x1b\xa1\x95z\x14\xd1\x8a\x04\xe34\x7f\xccV\x0dJ\n\xc1:M\xc7+\x8b$\x7f\xc3 A\xc0\x00^\x9aG\x9aA\xdb\xcc\xed\xa8\x95\x10\xdfX\x80\x190E\xc1\xc47`4\xa9\x0c\x87R4\xba \xa8\x98\x12\xf0o\xd4\xbc\xab\xa6\xba`-U\xf1P\xea\xdf*\xa0\"\x18\xb9P\x1c\x9eV\xec \x9b[!s\n\x1a\x10\x05\x1f\x8b\"\xe4\x12,\x07g\x16\xf0\xf9n!\xfe \xe1B\xe5%\x1cWg\x80E\x1c\xf0g\xc4|G\x9c`!\x15\xd1+\xb5)~u\x05\xc4 ;\x10=\xdc\xdf\xc7\xd3w.\x1bA\xd4\x84vO\xecJb\x90\xa8\xd0\x14\xfc$\xe1\xfe{#\xc7T\xe1.a{\x03\x9exZ\x1a\x92\x83m\xc6\xac\x89>\x83\xea\x07\xf0wi\x03\xfc1\xb0\\Z\xab4\xe8\xcf\x81\x17\xd3\x8a\x99\x03:\x16\xeb\xe6\\|\xad\xda\xc9@F\xec0R3\xd4D\x91\x01\x06\x8fE\xde\xb1.\xa6\x86\x14\xb2,|\xf3\\/{\x8eF\xdf\x08\xfa\x0e\x1bX\xaao\xa1\xc5\x0f\x81\xe0g?\xa8V\\\x9f\xf4\x13\x87\xcfJ|\xc7\xcd!F\x83\xb5 (\xd0\xdc|\x0b\x03>\x8e'b)E\xec K\xacK\xc9\x87\xa5T\x8fZ(\x9e\xcc\xf1\x01i\xd1\xac\xd9 \xc6q\xbf\x0f\xb1\x0e;\x80(\xf8\xde\x00\xa1\xa23\xaa\x91\xf2\xc7.K0(cf\x04'\x91\xbdKZzg7E\xa0\x05\xf9\xf7\xa9\xfb\xe2\x94\x94\xbcm\x0b\xb3\xc8\x1dbiZ\x9eHf\xeb\xc6\xd0\xb5|\xa7\x953[\x170C\xcbMz\x03`>\x84)-\xc1\xe3\x8f\x0b\xf0}\x1e\xc6~\xb6\xb3-\xb5\x08\x80\x80\xb5\xcc\xdd\xfbt\xe6\x8b({h\xcd\x19\xeeZ\xb3l\x1f\xfb*\xb06\x08Y\xcfC\x7f\xb9\xe23{ \xdb7E^\xe5\xa3\x1b[\x9e\x9e\xafaP\xad&\xdd^E\xf0P\xcb+\xe48\xb5\xf4R\x08afp#Q\nr\xea\xb3!q\xc5\xc8\x00\xa9N-MIrj\xc9J\x17TKVB\x9dZ2\x08r\xeaiRxSK\xfe1\xf7\xdf\x17\xfd\xd8\x18z\xeb-\xc1@.\xc1\xd8\xe1E\x94&\xb1\x1fm\xf8c\xb1*o`\xdaK\xfb\xa0\xd85\xac\xdfn\x81C\xae\x8f\x0dc5\xe9\xf1\x98L\xfb'u\xf6\x18O,,[$6\xe7\xc2\xec\xc6\xd5\x9c\xf6G\xae\xb9\x91o\x00\x03~\x87e\xa8\xea\xb5\x10\xe86\xcb\xd7\x86\xb3\xc6\x9e\xebh\x81\xb6<\xd93\x8b\xe9\x05}\xfd\xc8N\xe5v\\\x07\xae8y\xac\xa7\xd6\x8b\xed\xe2\xd9\x0d\x9a~\x9d\xc4\xcb \xe5\x1f\xa1\xe5\xb7<\xfb\x08\xad\xca\x95uK-o\x1b\x97v\xe5\x8aX\xdf\xc0\xb3\x12\x856.B8gE\x00\xda\xa8\xe1\xf4\x15\xc0\xf1!\xb2\x1c.\x90m\n(\xb6 \x99\x0f\xe9\x06\x96\x95\xd2E0\xcf\x9c\x06D\xd5.\xfe\x03k\xd1\xb64E\xf9\xc0\x89\x8b\xbd\xcb\xde\xb2x\x00\xf8q\xc3\xa2\xa2)-\x99\x8aS\xe1$\xec\xa9\xf4%\xa6\xf6\xbc\x91\xd8\xc0Y\x9f9\xd2\xc8\xfd\x80\xf5\x9e\xdc\x13TM\xfe\xee\xb3\xde\xd3\x9e^Jn\xa0\x82\xa1\x8aD\xe9\xa3Hf\x83\xa6\x10\xe4\xa0\xd4\xc2\xb3\xcfb`\xdf\xc2\xd4)kC\xc7\x138J\x96\xbf\x07\xfej\xc5#\xf0\xef\xe0\xe9\xf84\xc0\xc4\xb8\x92\xa8\xcc\x18\x9c\x0dq\x06\xdd\xd8\xeaB\"\xe0N\x06br\x01\xb5*\xbc4pi\x80*W\xbf2s=`=\x86e\xb5\x072\x0e\xd6\xabN/\x8a3\xe6\xa7ip\x1a\xf1\x19\xcbb\xe6\xb3\x95\x9f\xf0(\xdb\xa0\xf8\x07\xf5\x9ci\xfe\x91\xe8^\xaa\xa7\xf4H\xa3 f\xec\x0d\xe7\x8e\xd6[IT#\xaf\xd2\x02\x8a\x80\xfa\x82\xc1P\x94\xd6\xf5\x9agE\x7f\x14{\xe9P\xbc\xa2zlT\xca\xc2f\x08\x9a\xd7uJ\xb4\x0d\x17\x0d<\xc4\xd0\xe0\x84\xcb\x95\xd7\x1d\xc1\xe7\xaa\x1c\xd1\xd3\xce$\xd3*\xfa\xac]d+~}pK\xc7\xc3\xce\x83\x07\xf2\x80\xdd$\xe8W\xdbyu\x80\xbd;\xbd\x11\xeb\xdd\xf1\x97\xab\xc75\xa2x\xb7wW\xe4\xfc,\x8f\xb3zV\xef.VZ\xc5\xa9\x91\xf5\x04\xb2B\xb3\xceS\xc88\xcd\x1ek\xc1\xfa\xda\x04\xe3\x16\xa9\xb8$^\x92\xb2\x01\xf1*\xc4=\xce\xf8N\xef\xc9\xd3\xbb\x18c\xa1U\xd8\xa6\x04\xccFP>\xe0\xd9\xca\x8e\x92\xd0\xad\x91G}\x08\xf1\xe3\n\xdc\xa5\x19\xc1\xa3\x1dwpx\xc6\xa3\xecp\x19d\x19O(o\x1f\xe6A:\x913\xbd\x08\x0cu\xb5x\"\xe7\xe1\xd0ub\x0f\xfc\x97\xc4\x837%\xc5\x14_\xbc\x0f\x89?N\x82\xacH\xdc\xdd}\x00\x89\x9f\xe5\xab\x90_\xc8\xa4]Hz\x97\xf8Q:\x8f\x93\xa5L\xdd\x83\xd4\xd7~\x9a\xbe[$q~\xba\x90\xe9\x0f!\x1de\xe2x\xb0\x8bu\x97\x1f\xc1\x8a\xb7\xe97\xce4\xdf]6\xc9yL\x9fF\xf9\xe0\\\x0d\x07U \xb8\xd5\x88D.j\x80\xd5\xd8\xca\xcfS\xae\xbd\x1a\xc7&\xfa\x93\x01I\x85\xa2r\x1f\x82\x16\x13\x9e\xe6\xcb\xca{\xe3\xa9,\x1a\xc4Q\xc1\x92\xc5`,\x08 \x89\x1fD=\x8f\x05\x90r\x1c\xa4o\xb3Y\x00r\xfcL\x1b\x18\x1e\x9e\xc1\x119\xd4\x12l\x9c\xc7r`\x88\xc4od\xdb<\x96\xd6\xa5xg\xd2Ztch\x83oN\x0e\xd6\x87\x8f\xf9r\xc7\xe5H\xc7\xbaA/\xed\xd0 y\xa9\x8d\x0ff<\xcd\x92\xf8\x12\x17\xb6\xfc\xd1\xf5\xb3!M\xb7\xc5\x16:u\\OZ\x02$\x830H3\x1e\xf1\xe4\xb9\xd8\x87\xa4\x13\xe1\x1e\x17\x9bi\xcfU\xfbk\x9d\xde\xd2_\x9cZ\xd1d\x19\x9f\xf1/\xe4wjsndj\xf3oV\xd5\xe7\xb9\x9eW\xce9Y\x13F$\x98%\xea\xabz\xae\xed\xab\xd3\xc6\xafN\xc9v\xcb\xdc\x86\x95\xa0\xc8-br\xa5\x9f\xf5\x14\x1d\xdb\xa7\x06\xb6O\x8b:\xd5\x14<\xca\x08\x02\x04gL\xaf\x95\x86\xbb\x10`\xa9\x89\xac\xf7\x04!I\xb3$\x98f=\x92\xaa\xdf\x1f\xba\x03\xbc\xadDZ\x08\xec\xb6z\x9c\xaf\xe3R\x81f\x9cD\xb3\x8d\xf6m\x8d\x15\xa6\x91\x9ci7E3Wg#\xdf]\xae\xb8d%\x9f\xfb\x91\xe0&\xc5>\xc3|6\x0d\xfd4e~\xca\xfc\xe2K\xc4\xb9\xf0C\xe9\x86\x1b\x19\x9e\x05\xf7g\xd2LK\xa6d~\x10VS\xe4y`\xdf\xea\\\x99i\xbb\xbc\xe9E\xaa\x99QS\xbc\xad\xe5h\xe9g\xbe\xd5;Y\xc4/2\x94G\x99\xe34y3}(O\xc1\x16\xa9\x18.\x88}@Q>\xaa@%\xab\x82$\xf3\x98\x8c\x01\x80\xcdT\xa1\xe1U\xc6\x9eG \xfc\xfe\xf8\xc3/\xfa\xdb\x05\x062\x06\x89\x06 \x10\x06\xebc\xac!\xc6:c6Fl#\xf0R\x00V\xb6\xdat`\xe5\xeaH#z4\x10\x10\xa1\xcf3\x12\x01\x87\xc6\x10\x0f\xaa\x03\xaa\xe1x}\xca\x8b/ \xf0\x16\x91A\x949\x05a\xce\xde\x04\x11\x15\xf5\xae\x11\"M\xbdkY\x81\xd5\xaf\xfd4\x0e\xda\x1d\xb8#\xfc\xf7\xeb\xf0\x97\xd0\xa3|\xe6Tn4\x15\x9d\xc5kM=\x14\xc7\xc3\xacHoH\x02n\x8f]\x16\xb1\xfe>\xe8\xc03\xcb\x9c\xd1f\"5\xf8\xc5\xd1\xd4o_D\xcdcJ\x06~\x18\xc6Sg\xcbb\x8an`LQ\xb3\x0d\xedJ\xc8\xc0\xb19F\xb3)\xf9\xbd\xaf\xa2\xd4\x9fs\x87\xb3\xa7O\x9f\x82x\xd2\xaf\x82/\x17\xd3\xf9\x98\xf9\x8f]\x00\x9c\x0f\xdf@\xa8\x06x\xa3>\xf7@\x97\xb6\xbaD\x9b\x1fQ\xa5\xaf\nV\x0c||\x04\xba\x0d\xc4\x81\x01\xe2\"\xe1\x83`\xb5d\xf4\xb7 JW|\x9aU~\x0c\xa6y\x9a\xc5K \x13\xa5t\xa6\x98\xa0q\xbd\xe0\xa4 \xd9\xd5j.*\x11r5\x1c\xd6\x88YI\x8e\xe5\xf2\xa6(\xae]\xfa,to\xa0/\xd2\xc6k=rw6H\xa2\xb6\xef\xea\xeeN+nH\x8eD=\xb0\xefC0\xcb\x17\xcb%\x9f\x05~f\x95jH\x05\x0d\x1a\x19I\xbf3\xe6}7\xfd \xe1\xa2\xbb=\x7f\xda\xa0\x9baRw\xc3\x07\xb3x\n\x922{\xb9Uitt\xca\xb3\xd7\nI^\x81R\x83\xcc\xb0\xba\xb0\x12M\xad\xc0\x92D\xc0\xe4]\xb0\xe4q\x9e\xc9\xe8\x88\xdc+\xfd\x1c\xac\x92x\xca\xd3t\xd2\x835\xfc\xf3\x0fEpIy!x \x0b\xa0\xb1m\x1b\x1dQ\x8f\xa6\x07j\xa4\xdc\xfa\xb3p\x88\x0b_\xea\xb1 \xb8\xd8HG\x9d\xa6O\x80\x12u\xb0\x8a\xd3\xecK\xe9@M\x9c6\xf9 X\x8a%\xf9v\x9a\x04\xab\xccj\xef\xa3\x1eE\xc47\xb6\x9a\xa5\x88LJ\x12\x05\xb3nu\xd1\xa6?\x05\xf3W\x94o\xdb\xf4\xeaOF\xeb\x10\xf4\x07\xf7\x86\x12\x02N\xaf\xe7\xb1\xde'=y\xaa(?\x1c\xd5o\xd9UZ\xa1g\xc2qA\"%\x9b~\xbe\xf0\xa3\x88\x838\xdb\x01{J~\xce\xaaY\xee@\xc0}H\x0f\xb8\x11\xb9\x16\x0e\x07\nn\x93y\xae\x81\xa7\x01tb\xbb\x02\x14\x0b\x16\x82l\x0c\x16b/\x8e\x12\xee\xcf.\xd3\xcc\xcf\xf8t\xe1G\xa7\x1c|\xdd\xcc\x07\xd3\x84\xfb\x19\x97\xa2w\xa7\x97\x02R\xf5\x04`\xc0\x8eq^\x90\x00Yd\x9d\xae*\xd4\xb3~\xc5\x8e`\xd9\xc0\xec\xf1:\xe8%E\xbdt+\xc8d\xc5\xf2d\xfc|\x11\x8430s\xced\x9e\x1d\x8fD-\x94m\xabZv\xc0w\x87SI\xed\x9c\x85\xc7\xb6\x8c\x1bF\xea\x11\xa4\x03\xc43=}\xcf\xf8\xa1\xd8\xed\xe0\x16P\xe2G\xb3x\xe9\xc8@\xb5\xc8m\x14=h4a\xcc\x06i\x9c'S.ob\x08\x8c\xd1\x83sI\x1b\xa5\x812\xe9\x93|\x172%A4\xe3\x17\xaf\xe6\x8e\x0f\x02\xbd\x85\xd3\x97\xe9\xa0pq\x14\xd3b3q\x14\xeb\xd8\x9f\xcd@\xd8\xaad\x14\xb0*\xeb\x89NO.\xba\x1el\x7f\x1bC\x10\xfc\x0e\xfc,\xf3\xa7\x0b(\xe9\xf4\x8a\x85)\x052Ig\x00T\x89\x8c/XX\xa43\x96\xf9\xf5p\x93*&\xa1\xf3\\kR\xb5\x8d\x9a\x19/\x97DGy7q\x80\xd1\xe6MF\x7f\x156\xbd48.\x14\\\xea\x10\xb1 \x11\x0f#\xe4>#\xf6DwM\xd0\xef\xbb\xca\x97@Qo\x0c\xaaA\x8b\xdd>\xd3\xec\xbe\x9aW\xa1\xd8\x8fO\xfc\xe9\xfbF_\xe3\xe2\xf1\x93\xd3\x942\xb8S\x0fq\xacU\x8f\xdc\x86\xc2q:A\x01w\xe2\xa4\xae\xc7\xd2~\xdf\x86p+<\xa2\xe9sG\x1c\xa4\x1b\x8c\x08f\x0d\x16%\x18\x947\xac\xdfhd-M6\x18\xa9\x80t\xd4\xa5\x88\x04\x0d\x94\x86\xe88L#\xca!\x19\xebV=p\x85\xad\x8d\xc8N ?|\xf5'K.;p\x02\x1b\x1dW\x8f\xfe\xa8\x81\xa0RW\xa0Y;\x83\xa3\x9e\x04\xea \xack\xee\xbdz\x94\x91u\xd2\"\xbb\xa0\x1e0\xbc\xde\xb2\x1b\xdfRO\xa3\x01%\xf5\xb4\x98i\xd7\x1f\xe8\xd3p\xdd>%\xe3-\xeajw\xd3s\x9d~m_\xa7_\x1eK\xc6\xc3\xef\xa3w;\xd7\xef\x9d\xf8\xbb\xfd\x91\xfb\xd8j\xebM=\xa0\xb0\x0fA\xe4@\xd8{P\x0f\xcdQWJ\xd8\x98\xa3\xa2\x00\x9b\x07\x91\x1f\x86]\xe8\xc3\x0c\xd8\xb9i\x87\xf3\x825\xb7\xab\xe1oM\xb6\xe7\xf4\x8a\x98\x05:/\x94\xf2p^^aW\xf7W\xb3E\x90\xc2\x0d\xd7\x11\x14\xd0\x94\xc0\xba\x11\xc0\x0e\xec\xc5v[\x80\xee\xd7\xa2\x8a\xed\xc3B6\xed\xc4\x17\xadV\x06a<\xf5\xc3\xb7Y\x9c\xf8\xa7\xbc9\xe6\xda\xd4\x07\x02\xd8\xe6\x15\xa45\xda\x19\xd3U\xca\x95\xef7\xc6^\x97>#\xc0\x9c\xac\x97%9\xc7\xc3?\x9e\xfb\x9d\xc8\x1dd\xf1\x17\xf19O\x9e\xfb\x84\x06Y\xff\xd5\xf9^\x1fS\x97a\x9c^\x14\x7f\xc6W \x9f\x82\xe9ZO\xbb\x97g\xf6Wi\x9b(\xd7\xaa\xf5\x9b\x82M\x1b\xfe\x06ycS/\x119=\xd0\x10\xd5\xbaV7>\xb29\xf7f`\x90\xd0\xcb\x12\x7f\xca+M\xb0\x036\x8d\xa34\x0e\xf9\x002\x1d\xf0w\xa4\x92\xce\xfd$B7\xe0\xb0\xf7w\\SL\x17\x17 \xa9\xc9@%UZb\xb5\xadC\xebR\xea\xb4\x86hA\\\xc5\xf9N\x99\\j\x0cw\x86\x96+\xe5[\xbbd\x00\x98\xc0\\\x1f\xa8\xdc\x03\xc2\xa0\xe9\xf7\x82\x12\x890v\x98\xe1N\xbb4%!\x02\xe8\x8b'\x1e\x04\xd1\x82'A&\x1d\xc1\x0c\xc1\xd2C\xa59\x01\x9a\x99\x04\x9a`\xfd8\xd3\x8cF\x9a\xa0\xc5\x007\xf0\x94\xdc\xea/\xa4\xc1\xb6&r\x86\x8f\x1et\x9a\x9fj\xad\xdd\xebT\x1a>\xba\xef\x96f1\xd7\xac\xaf\x19\xd0ti\xa1M\xe3\xbc3\xa4\x02\xe8\x8bt\x8bK\x82\xbd\xf6[\xea\xf5\x89\x92\xaa\x08\xbc\xac]\x1e\xe0\x0c^H\xa2\x9b?\x88\xe2d\xe9\x87\xc17<\x81k\xa9\xa0\x96s2\xed\x8678.+\x95\x0d\xa5G\x0c\x7f\xe0\xa7\x97\xd1\xd4E\xcf\x04\xfe`\x95\x04\xcb \x0b\xce\xc4\xd6\xa7\x8c`\xd8A\xf5\x13p\xb1z\x0b\x0e\xeb\x19\\\xb3\xc0\xaaF\x89m\x17<\x7f\x8f\xea\xb5\xb5vE\xb1\x1d\x17bQU\x13\xf70Q\xbc>\x84f\x8a\xae\x82\xe5\x8f\xb3\xb7\xf5\xc8\x95Q\x8d\x96\x8146r\xf6\x86\xa0\x9f\x19\xcc\x82t\x15\x97\x89\xbb\x90\xb8\xf4/\x9e\x9d\x16i{*M&lc\xcd\x84\xcf\xc1@\x85'*}[\xac8\x81(\xfe\x9a\xab\xa6\x0d\x91v\xf7(D\x02\xa1\x8f\x7f\x92\x9a\xa8\x049\xf30\xd6\x1dbwC'\xa5>J_\xfa/\xd1_\x05\xba\xe8\x00,\x11Get\xa7\nN?\xee\xdcaA\xfay\x10\x05\xe0\xa2\x1a\x1c\x0dq\xf0\xf2\xe1\xc4\xd2\xdfP\x9bQG'0\xd4\x88\xc3\xde\xb6\x0b\x82[\x18c\x1a\x9cF0\xf5\xbb{;\x9d\x88F\xfb'\xac\xfb\xb3Re\x15\x1f&\x17\x18m6\x05h/\x0d\xe0\x9c!z\xa5\xdbT\xbf7\xb7\xb7\xd6u\xe7\xb1\xc60\xec\xb6\x99\xdadz\xe5\x8c\x03Q\xd0=\xb2pi:\x81>pn\xa3\x9f%b?\xa0\xbd\xd2\x0e\xef\xd7\xfd\xdaH\x02Y\xf7\x98$\x03V\xee\xd1\x01+\x05\x9dm\x86\x0e\xe3\xb4\xb3\x81\x08oCUgX\xec\xe5\xe8\x10\x03n^I\x97\n\x15\x9a\xebjtG\xd1\x1b\xc2\"\xfc\xd5J|\x1d\xf3 l\xe8\xca\x9f\xf4\xb4\xe6\xce\xa8\xe5\xcc\x9bbEt\xd8z\xa0\xda =6\xf7X4\xe6\x13\x88\xe9\x81Nx\xc8K\xe5\xb6\xe3\xea\xad\xe0\xf2\xae%\x16\xe0\xce\x90\xf6K9\xbco\x89 \xfcp\xcf\x1d,y\xb6\x88g)Ejw\x0d\xff\xc0\xa9\xe4\xec\xeaG\xa8\x90^\x0cp,\xac\x96\x9cv]6\xf3re\xa0\xa6\xb1\x9a\xad\xd9(\xa0(G\x12\xcb\x80\xd7\x86\x82!1\xe3\x9a\xdf\x80\x05\xa4\xf2e\x90uXX\xc4Q\n\xec\xbb=vVD*\xf5\xd8\x89\xc7\x8e!\xc8\xec\xa1\xc7.0\x9a\x96\xc7\xde{\xec\x99\xc7^y\x10tk\x0e\xe7/\x9a\xe2c\x00\x11y\xa1\x14i\xb9\xdc\xbd\x0b\xf14\xee\xd6\\#\xe8\x1aW-\x10\xff\x02\x9cu\xea\xc9\xae\x07Qq.\x06\xa7<\xf3 \xf2\xcd\xc5 \x15\xaf\x97\xf0\x8a\x9a\x0d\x0f\x02\xd9\\\xa0\x06\xc5\xf5J\xc1\xcc \xe1i\x1c\x9e\xf1$\x85\xe6_\xc9\xad\xa5H\x15\x8b\xfa\x19SA\xf3\xed\"-Vn\xc0\xd2\xb4\xaa\xa0 &\xf9\x10\x1b\xf2+\xf8\x1e\xf8\xbeq\x02\xb7\xec\xd2>n\xd2K\x91\x08\x8aIb\x9b|-f\xab8\x89C\xe0]_Z&\x9f\xf2\xac\x07\xab6@s<\xd7c\xaf\xc9\xe8%\xa2\x0f\xe8tO\xf0LAi\x808-\xe8 \x9e\xe2\x83\xf1\xd6DP\x80\xb0\x9e\xae\xfa\xbc\x8f\x9e\xa1\xecB!bd\x8a\xb7H\x9c\xde\xf3 \x99\xe6\xa1\x9f\xb0 :\x8b\xa54\xc7c\xbd\xe7/\xde<\xff\xea\x8bgo\x8e_\xbc\xfc\xd1\xab\xe7\xcf\xde\xbdx\xf5\xd2\xa6x\x17\xad\x9e:\x01!\x8bA\xa5\x92\xe8C\x03\x18o\xa9'r6^\xa3J2\xf6\xd8s}^R5/R\x89/\xf8\x90*\xfd\xf4\xd8\x99[x\x15\x14\xeb\xa3Q\xe0\x06\xc7gzV-C\xc5\xbb\x02\x8dh\xa3\xae\x13\x14\xa8[\xe2\x90\xc5\xaa\x10\xf4m:\xb2\x97xT\xc7\x97Rf\xc6F5$s=\x1b\x9a\x17\x9d\xbe\xe5IB\x93\x000\x19&\xa6\xa9\xb8C\x8eV\xad\xa6'l\xdd\x93\xfa\xed\x92\x02\xfd\x8e'lyRT\x0c\xab\xd0\n\xa6\xb8qZ\xe3*5\xa0\xfc\xda\xc12\xbd)5h\xe8\xdc-O\xdf8\x16k,\"'/V\xf3\x16U\x82\xf21\\c>\xa9\xfc\x8f\x93\xe04\x88\xfc\x90T\xf8+n}\xc4\x9e\x99\x99\x92\xd5\x7f \xde\x83`\xb7W?\xcd\xb2\xa7<\xebr\x15T\x0e\xf2U\xc1\xe8\xbdr\xb8\x0b\xbb\xdc\x01[\xa2\xb3\x07\x89\x14\\L\x86I\xf5\xcc//\xfct\x8d/[\xe6\x91r\x12o~\n\xf7\xdb._\xb3\x900\x86\xfd\xa5{\xc00\xaa\xfa\x9d;\xec\x12-\xa5\xd8>{\x0d\xbc\xaa\xb4`\xc0\x1f\xefu\xb4\xc0\x9c\x1e\x86\xa8\xa3\x1cE\x99\x83\x006a\xd4\xae\xf2P\xa2\x15\"N(\x83\x80\xc8w\xee\xb0\x13q\xe6\xd3X#\xaf\xe8\x18|\xa5\xd7\x15\xb0q4j?\xb52M\xa0#\x16\x7f!\x10y\x0bz\x0f6\x02\x1b\xac2\xf9y\x91,\xa1TZRA\xfcW\xf0\xe41\xab\x08\xf5i\xdf\x15f\x7f\xc5\x18Glaf\x14\x87\xe1\x0e\x00\xe6\xc8\xd9\xca\xe5i~\xb6\xbe\xbc\x8fMV\xcd~\x95\x05-\x8b\x1a\x883.A8\xe5\xe1\xf1\xae\xe4d2\xe0d\"\xe4\xd1\xfc2\xc6]\xbdC\xeb\xec\xe9\x85\xa8[\xb6&7\xbfj\x93\xacmi\x11\xe4\xa3\xdcTp\x17\xf1\xcb\x00}\xf5\xfe\x9e\x83\x14\xbd\x95\xf5\xe0\xad\xb0\x93\xdd(\x87.\xf7\xdc\x91\xda\xef4\xb0r9k\x02\xa0%u\x8b\xb0\xb3bE\x9b\x82\x97\xc3\x8f\xd6O\x1f\x82\xd8K\xd8\x93\xdd-\xb1\xa0\xa1\xe3\x1210\xe6\xbe\xd9\xff\x95\xf3\xcc#\xfa\xac\x0b\xbfF,\x00\xd7UV\x12\x1b8\xc7D\xae\xa4]\x81\xe3\xab\xd3\x8e\xf9\x15\xd8\x89\x02\xe7\x9c\xca\x83\xbd\"p\x0e\xcd>\xfbE\xca\xad\x1c\xf1w\x86T \x10q$\xb7h\x99\xea\xe2-\xb1\x97\x83`r0\xf5WY\x9e\xf0\xb7\x99?}\xff.\xf1\xa7\x9a(\xa9\xe2\xab\xa3U#\x15I{D\x94wR\xd1n\xf3\x8aphH\x88\x90\xd2\x9a\x90\x89<\x0b\x07N*\xddm\xe5\xb8\xa9I\x8f\xa4\xca\xa9=hdR\x19\xd50\xc2\x9b\xb8\x81*\x1b\x0d\xa6\xf1L\xe0^\x0eWu \x08D\x84\x8c\xea\x9a\x0e\xa8\xd7\x90\xc7\x93j\x05\xdc\x81\xa5\x90\x02}\x85t\xd7.H\xf7n\x0e\xed\x15e\x1e\xc7#\xd6K\xfcozu\x1ae\x96=\x11\x18\xdf\x9b\x9d\xfb\x1d\xcaf\xc97\x97#\xd6\x13\xffz\x06\x8a\xf3\xc1<\x8eY\x9f\xf1\xc1\x89\x9f\xc0\x7fQ\x0eh\x83\xe8\xca\xec\xdc\x87z\xb7,\xb8\xdd5\xa2B5Hn\xd7\x08\x9c`\xd1\x10\x94\x17q\x02\xc3\xe4\xd6c\xdb5\xbe\x1blu\xb9.\xe9\x04n\xb4b\xa4M\x8a\x1a\xedV<|\x9c@\xfc\xd1qBX\x9b\xb6\x9a\xecD\xe8\xac@\xac\xebV\xf3\x0bd\xf8\x87\x8f\x99\xcf\x9e\xb0\xf41\xeb\xf7}y\x85\xadX\xa0\xfe\xc4\xc3\xf8\xd4\xca=Q\xee\x9a\xea\x13\xcd5KT\xe8EHL\xff\x18\xaa\xc3\x87CT\x1dj\"vT\x1e>\xdc\xfe\xd8\xcaCz\x12\x15\x8f\xa1\xf9\x96\xed\x15Z\xf5\x1ex[\xac\xceC\xe3\xa4\xd26X\xb7-P\xa6\x94#\xda\x00\xda\x96S\xbd\xe3\xb2\xd31x\xc3-\xe6\x06\x8fg\xeb\x1a\x9f\\\xab\xef\x04\xc5\x94\x9f\x18\x91\x97\xa6\xf0\x16\xda\xc8\x98\x9ak\x0e\x1c\x86}\xe7\x0e\x8b\xc7J11\x11\xebr\xdd\x10\xb9\xed\xa8)\xd0\xfc\x01\xe2\xbf\xbc.W\xb9s\x9b\xf9A\xa4V\xc3\xee\x0dV\x83\x82\xb6N\xe6\xd7\\+M{]R\xf6Ulz\x1b\xcae\x88Ju`\xf7R\xbe\xeb\xeby\xf38\xee\xdd\x8e\xaa]\x0d\xd3\x00\xa5\xbc\x0es]l\xa8\x1d\x11+\xcae\xf6\xf46\xf5\xef\xb5\xeb\xa4\x9er\xc8N\xe9\x80\xe6\xb4^t\xd5Y\x953\xeb\xaa\xcaY4\xabr\xce,\xaa\x9c\xda\xe7\x96]5>\xa7\xed\xc1n\xab\x15.I\x8a1\x8d\xa3yp\x9a\x83\xf6\x95\xa6\x1a\xbc\xd0\xce\xd2\xae\xaf\x95\xa7\xa4&\xba\x92\x1b\xdf\x164*i\xe3V\x98\xe2X\xac\x87\xb69\x185\x9c\xea\xb8\xd7;>\xe6\x1c\x0c\x07\x0e4\x07s\x90&\xcer\"\xe9rp\xe6\x87\xb9\xe0h\x16J\"sV\xab\xed\xb1K\xd7\xd3\n\xcab\xd1\x98O\xd8\x01\xe5t]\xe6\x88\x7f\xe8\xb1\x0d\xacO!u\x9f\x8dQ\x9b\x9aM\xca$\xe9\xad\xa3\n\xb1\x1a\x8d\x8f\xa6|\x04\x94\xbe\x1b\x94<\xdd'\x98z*\x80\x8a\x95[>c\xb9F]\xee(J5u\x8c5\xe0*\x992\xdah\xb7\x8a\x05\x07;\x02\xba\xaf\xa2i\xe1\xd4\xe7\xf8\xb8#(\xe6\xf3\x11\xf0\xbe]!!\x89\x04-\xe7F`l\xd0hS\xf1\xa7@\xd7\x97q\x80J\xc4r\xc7|\xd2\xa1\x9e\x896\xe8`T\xd46!\xc6\x14\xeb\x1d\xe0\xed71y\xc98\x98\x08\x1e6pY\\\xfa\xe5\x8d)\xb8b\xae`\x94\xb7\x95s*%\xd2\x97(\x98\x8c\x03i%7\x14\x88\x99\x0c\xd2\x15\xdc|\x0c<6\xa4\xee\xee\x81*-)?\x9b4~V\x8ac\xa3&\xeb\xf8\xb6iG \xa2\xdfzG\xf1\xac\xf0j\xd18\xef\x16:!\xb6\xe3\xb8:\xa1\xf6\x19\xa1\xe7\xb1\xd9\x19<\xccbD(\xc9d\xac6-\xde\n\xdew\xcc\xf0\xc8\x92\xb1',\x12\xd3\x9d\xb9,\x18g\"\xb3z\xd91k\xb8\x08\x07\x1f\x8d\xc1\x81\x05^h\x95\xedn=\x06\xc2\x1b\x8b\xca\xd8\xb4\\\xc5I\xa9\xc9!\x1b\x95\xbaTu\xa3\xac>\x96&\x00t\xb9\xb55+\x88\x0b\xe8\xa9\xec\x03c\xedw\x8b\xba\xdc\xc6\xaa~\xaf\xc6\xb0\xdc\xfc\xeb-\xb7\xad\x9a\xbe\xeeU\x84G7\xebK\xa7[U\xbf\x10\xfc\x14\xcf\xaa\x06\x05\x1b\xe6\xfd\x80\xfe\xf5\x81\xf2\xc6,8\x8b\xa9S\x17z\xe2^:u\xe2z\xba\xd8X\xa6N\xe0R\x84g\xea\xe8\xe6\xd0hG\xb8t~\xfe\x01\x85q:{\xdc\xec\xf5G\x19\x8bi\xa1*\x17N\x88\xce\x88\x8bSc5T\xa4\xc72e\xb4\xc4\xf6Y\xfe\x03vS\x8eY\x9e\xa3\xea\xb1~\x1b\x04\xab\x04\xdb,\xf88\xd2=q\xf9\xbdf\xe7\x01\x1a\xdd\x1f,\xfdU\xbb#hU\x81\x1d\xb0\xcc\xe1\xe3\x08T\xcf\xe2\x7f\x15%\\\xe9|\xc9\xc9+Zi\xf3\n\xff\x07o\xbdc\x0d\xc8\xbd@\xe0\xd516O O\xc5\xbe\xa1Zq\x05\xd7u\x12D\xb3\xf6P\xb6\xddg\x16\x8f=\x8f(S9\x9c\xa8 \x85\xff\xd7<\xd5\xc5(\xda\xe0\x10\xce\xfdv\xba\xdd\xe9 \xadD\xcb\xc8\x98\xe2H\xe6I\\\x0b\xc8\xd5t\xdcF\xff\xed\xe0]\x00\xe6p\x0c\x82d\x0fe\xc4\x13\xd7c\x9f\xc6q\xc8\xfd\xc8\x01V&+}.C\x01\xd4\x05\x81]\xf4m\x8cY\x13\xe4<\xdav\x07A\xc6\x13?\x8big\x8e\xc6\\\xca%\xfa\xc8fAN\x1a\x90\x1bK7\xa5\xe5\xc9!\xbd\xfe\xa7\xf2\x9bur1\xaf\xe3U\xa7c\xb5yX\x9e\xdd\xc6a\x94\xc8\xd7\x0f\xa3f.\x1c\xe6\x08\x1f\x8c\x1f\xac'\xf9\xeaQ}\xddET\xb2\xa5V\x13\xcaV]\xd2\xdbF]\x128Z*%\xf3)J\xe6C\xe7B\x06\x08\xbf\x90\x0e\x12\x99t\x19\x0eh\x0e\x13'R\x02\xf4\xf8\xec\x16\xbe\xf2\xaa\x8d[\xfc1\xc0 \xe8\xc2zF\x9c3y\x89F\xaeN4\xf7tN\xb5\x10\xc5\x82\xa4 \x16\xc9\xdb\xdb\xf2\xc2\x9e8\x9f;\xcb\n\xc71t!b\xd9>\xe3p\x19}i\xe1\x86\xf0T'\xbe\xda\xc2\x85W[\xaft\xaa\xe2f\xe4T\xb05\x91\xcb\x96h\xcc\xc7I\x0bJ\xf5\xc8\x91.\xc9\x02\xe6\xa5R3e !\x03\x7f`/\x040\x9f\x1bzdf*'\x9cs\xe8n2\xb1\xc2\x02\xe0p\x02f\xae\xe7\xf2J*\x1a\xd2\x08\x82\xa9\xe0#\x0e\xc8\xe2l~\x02\xce\xc5\x9c\x128\x1b\xc7\x83Y\x1c\xf1\xc7.(\xe0/\xd8\x81b\xe2\xd0\x1a\xf8\x18%&\xd2\x90\xbd\xf8%\xf6ogVHS\x0e=\xb6p\x96\xb02fp\xddJ\x82\xf9\xb0\xfe\xd1~\xdf\x125K\xcc\x1c\x11\"\xa84\xf7\x9c6`\x03@\xe0\xb4\x123\xdb\x1c=\x8c\xd7\x03\xb9]\x0d'\x0e%B\xc8Py\"GZ%\xed\xb3\xc3\xc1t\xe1'\xcf\xe3\x19\x7f\x969[\xae\xcb\x9e\xee\xb3\x07\x0f\xb6\x1f\xed\x82\xc5\x12{\xb2\xcf\x1e\xec\xee\x0c\x1fA\xf9Cp:9\xee\xf7\xa3\x89\xb4g0\xc0y(\xedG\x0e\xad <+Ax&A\xd8\xef\x9f\xd9\x81v\xd6\x82\x8e\x1a:\x89=\xf0\xd4D\xb8\x02z\xbe\xa3\xad\x9d\x1a\x00\x9dS\x97^P\xe40%4\x15o\xd7\x1d_H~\x00\xbb2\xab\xc8\xee<\xb6,/\x89B\x8c\x90\xa2\xe6\x0d\xf6\xf5\x9a\x96\xe2\xd1\x8e\xd4R\\.O\xe2\x10U\x12\x8f\xee\xdf\x82J\xa2v\xc2)\xf48\xb5-\x1e>[\x91\xc3\xb6\xe9vH\xbe\xcb\xdcb\xc8{(8J\xcd\xf9Bm\xf7`\xfb\xb2\x88\xd3\xcbx\x9a\xc9\xee\xd5\x8d:i\xf5\xa22o\xac\x9b>\xddD\x89\xa8\x97\xd9H\xc6\x95Q\x14,\xd9\x04\x953F~\x16\xbfV\xdaM(B\x95\xc0N\xbf\xf3O'\xb7\xc74\xea\xba\x0e\x8b\x8aC!_\xfdZL\xd8\xac\x90\x98v\xd54\xcc\xbbi.V\x84B\xc2d\xfa\xc2\xfa\xed\x90\x1az\xed\x1b\xe8U;\x97\x14X\xb5\x06\x1a%\x8e+=\xda6i\xa5\xeb\xeaf&\xe7`\x81\x9b\x80\xb3(\xbb\xef50}57\xbb \x92\xc0\xc5\x98c\xac?\x8c\xa1q-wF\xe3\xca)\xb4z\x98\x8f\xbb\\\x8f5\x89[\xbd\xb3\xfc\xd6:\xeb\xc3\xcdrP\x04\x01\xf4CG\xf3j!\xc5h\xda^\x0b\x01\x1a{\xa5\x15\xa1\xe0B\xa6ND[ \xce8\xfa\xa2\x0c\xe2\xe8\xf8x\xc4r\xf0/\x9aQ\xe6|\xc7\x91\xbf\xe4e\x993\xa7n\x02\xfd\xa1*\x1f\x99:q\xfd\x93\xf38\x11\xd5\x9b\xb1L\x0ez\x86\x8a0\xf87\xc2\x7f\xfb,v\n\x8anHE*\xbf\xdf\xf3\xcb\xcf\xbb|\xccb:\x0e\x8b/cA\xc4R`jgv!\xfel\x9cM\xd0\xd6\xb9\xd4\xdc4vm\xe1\xa7/$\x96(X&\xa8\x06\xd1r\xd0\xa2\xaf\xa7\xa5\x18\x01\xd3\x83\xf49\xc8\xaa\xde\xaeT\xc8\x97Zsf\x01\xd9\xaa\x99a6.\xf7\xb1z\x932Y5$\x7f\x1a\xd5\x97\x82\x1c\xd6\xeaB\x9a\xac\x08\xefF-\x19\x19\xa9VO\xc5N\xc2\x9a\xf2\x97Q7\xe5~b|\x12\x13eM\xfcaV\\\xf1i\xc0\xd3zMLUU\xf1\x17Q7\x0c2\xa3f\x18dE\xbd0\xc8\x8cZ\x1a\x0fP\xab\xab\xe5\xc8\x16\xb4\x14\xa2\x9d\x82S0\xda)r\x8av\x8a\x14\xa3\x9dW\xddS\xdfoT!\xeb\xc2_E\x95j+\xae\xd6\xb1\xd8\xde1\xfd\xcb]\xbe\xaa\xc8\xb7\x031\xdcQ\xf01\xa8\x91Q\xd6g=\xd70 \xad\xfc\x863\xc5\xaby\xd7\xaf\xa6\xb5\x98Z\xcc\x1c\xe5\xbc:\xcaXG&\xaf\x0d\xac\xea\xfa\x89\xfc\x0e-\x1e\x95\x8cw-B<8\xc8(0\xce\xd1;E\xf7\xaa@D\xe8\xd5\xb4\xe7)\x98\xf6\xb0B\xd0^!\xae8\xe3\xafp\xcct\x13UHPM\x94l\xf9M\x1cj\xe9\x02\xda\xdd\xb5=\x19\xa1\xdf3\x108P\x9c\x03\xba\xf6/\xf8\x06\xfa\x1c$'\xeb\xd6\x8dG[E\xfc\x1b\x1bx\xd9\x87D\x93\xab+\x91\xaf\xc7*\xc0\xb2o\x8b\xb2\xe0\xc6\xb4\x1e\xca\xe0\xce\x1dV-2\xae\x16\xaa\xce\xfcm\x0cYM\xa0a\x12\xa5>U]\xc6`K\x81\x12\x88.\xcb\xb8\x10\xc0V\x17\xb2\xe3\xae\x8d*Uk9\xee\x02x\xe2_,\x04\"gg\xb8}\xed\xa1\xd8\xdd\x06\xfdR\x0d\xb2\x12\xf2|\xbd\x01\xa6\x86CqX\x18\x88\xe6\xa6)\x88\xf2\xcf\xa1\x1d)\xb0o\xa2R\x0d&\xee\xedY\xcc\x9e\xe9^`\xd6\x1d*\xc1N7O\xef\x01\xb1XR\x9e\x91\xd7g\xe1\xaeQ-\xea\x9d8\x12\xd1\x91\xa4\xa0t\xe2\xf0\xc1)'.\xd3i\x01R\x07)\x071a\x06/\xfbP'\xe5\x10\x9d\\\xdenC\x15\xa0\xfa\x81%\xf0\x07\xdc9\x93\x01\x8f\xb0\x90\n~$\xca\xe0\xad)\x88\xd1\x0d\xfd\x94\x1f\xc8\xd0\xc1Dv;\x14k\x8d\x89)\x04 J\xdej\x1eb\xb5\xa0\xff\xbd\xff\xbeW\xcd\x97\x87\xa2\xfd\xf2\xd20\xc8e'\xeec\xb6\xb9\x99@D\x9f\xfe>\xeb\xfdw V\x00q4\x89 \xd9\xf77j\xb5\x19\xea\xf7%Ik\xbfB\xd8\x12\x95\xc3\xcb\xf0\xd6`\x82\xf2{A\x02\xb8\x18h\xac\xc2<\xe1@\xb3q\xbf\x9f48\xf61\xd0\xb5\xcb>Q\x8b'\x7f\xcb\x17\x18\x86\x86\n8\xae\x8b\xf8Z\x00mc\x1f ]i\x06*)3=\x82\xd3\xbc\xdd\xc5\x8beA7\x9f\xe6\x99f\xc2JwG=\x01\xd8\x8bZ\xb3}\xeb\"QOPD\xdf\xf2\x8b\x15\x13\x8c}\xb8\xba Fe\xaf%>-J\xda\x06\xc0\x14>>f1{\xc2|\xb6\xc9\x86\x8f\x9b\n3\xd9\xb0t\xa7\x07\"\"\xb9?\x04\xa0\xed\xe4\xe3x\xe2j\x0eW\xad\xdd+Z\x83.\x0e'\xa0C\xe9\xf7ckaS\x05\xa9\x1e\xf9\xad\x96>\xb1\x03\x15\x8eN~N\x81\x8fl\x97\xfe\x9a6*#\x9f\xb8M\x9eV\xd0\xc8jo)\xd0(@ao\x03\x1a\xe5\xcdh\x04\xd2\xc4\x8eh\x94\xba,\xc7\x10\x0e\xfd\xbe%\xf0PK`\x03@\x1ah\xe3\xeaJ\xbe\xec\xb3q\xe3DS+\xb3\x9ao\xcd\x9e\xc8\xab{\xe2;\xf2V\x9c\xc4\xd4M\xe9\xfc\xc3 \xcaI\xcfa\xd2c\x81\xf6h(\x1b@\xd5-i\xe4\x0e\x19\xa2\xa2\xc7\xf2\xf1P&~\xc4\xae\x17}\x1fN\xc6\x01\xe0\xb8\xff\xf8F\xfdv=\xd5\x18N\xe05\xf0WJ8\xc9p\x8b\xe6P\xd7\xf3\x8e!\xdd\xc74`\xb2\xdf\x8c\xc9\xb9\xb4/o\xc6\xf5\\\xe9\xc1\xad\xa5B\xd8\x0e:\xac\x05\xc9l\xf9\x02\xbb\xec\x8bAT\x81X\x80\xe3\xb4\x0b=\x0d4,\xedNO5\xee\xdf\x07t\xc8\xc7\x81FO\x9bIi\x88\x88\xe2\xa3\xa7&\xec\xebp2\x8e\x01\xe9\x82k\x10\xd6[\xe9Yq\x15\xb7\xe8\x8c\xa8\xaf\x0c\xf7c\x0f\x10Z\xe4U\x92\x1e\xb3\x0d(&\x15\xe0w\xee\xb0P\x117\x176\xdcp\xb0\x8aW\x8e\xeb\xe1\xa4\xc8_n\x87\x96\xd7X.\xda}\x80.\xeb\xa4\xab\x03\x16\xc9\xa7\xe8|\x89\xd9\xfc\x0f\xe8_7\xe0\xca\xaa\x9a\xff\xbd-y?\x11\xdd\xd2\x0e\xc0\xa9\x9dt\xec|\x93+\x89k1q\xfa\xb7\xd79\xca\x81\xc2\x9b;?\xff\x00\x84\x92;/\xfd\x97x\x0b\x91;;\xf7\xbf\xcf\xb3N\xc1\xf5o\xec\xdf\x8e\x1c\xac\xca:_\x13\xack\xf2\xc6u\"y\x1bl\xb1F.2\x0f,\xe1,fpU\xe6-.\xb9\xb4h\x1cwZuU&\xab\xcd\x7fh\x8642\xc1\x03W\x84\xbf\xfa}\xee~\x9c\xbdP\x93XA\x10)\xd8\xf87`\xa0x\x86\xaf\x12\xab\xa8\xf2\x9b\xa0\n\xb7Ct\x08~\xe5#\xd0\x9b\xdb<\x05\xd2B\x06\x1a\xd5#++j\xe3\xe3\x08x\x10%\x83\x1b\x1e#\xad\xbe\xaf\n\x89@\xc1:\xa1\xa142\x11\xbc\x95\x89h\xdc\xa6\xb3\xca6\xddr \xeb\xc434\xb2\x96-\xfd(\x97\xb7\xfc\x8c\xf5\x10\xd6\xba\xd2\xad\xc7\xa9\x02\x9c\xd2\x00i\x0b\xaf\xdcD\x8fY\xae\x81\xb3\xe0\xc0\xfd\xb2\xa7\xa9\xe4\xc0s\xc5\x81\x8b\xbcT\xe3\xc0surH;\x9c\x1c\x9aN\x0d\x96\x13\x03\x9c\x16R\xf8\xe8p\x02N>\xfa\xfd\xbc\x0b\xdd\xbc\xce(\\O}\x06\xce\x11\x99\xc7\x02\xb0/\x10hHxN\xee@\x0b;a8\x1es\x91\xcb\xc7\xc1\n\xb2\x14\x82\x18 \x93\xc7\xbbk\xe3<\x9e\xa1B8C\xb5\xb3\xa6)B$W\xc1\xbf\xe5)\x0d\x91\xdf_\x03\xf9eo6\x1a{\xd3rd\xc8\xf4\xcf\xe7&#\x9b\x13,r^e\x91\xd3*\x8b\x9c\x16,r^\xfe\"Xd\xb3ekO%G,f\xaa#xn\xb0e\xd9 9\xbb\xe6\xf2\xf2t\"nv\xf5\x07\xf4\xaf[\xda\x03m\xbe\xc1\xe9\xcb3;C\xfa\x82\x9b\xe9K\\\x1aY\x1a\x17_R\xdb\xcd\xb7j\xb1\xf5\\\x84[6m\x88\x16!\xe3\x18\xb4\xdcx\x97B\xd3\xb9\xc7V\x1e\xd8WN\xa5\x81\xa21\x1f\x8b\xa6\xcc3\xd0n(\xc7sf\xfe\x12\xf2\x95\x13\xc6*F\x97\xf5\xc0$\xbc\x99\x97S\x9cF\xe9_\x98\xc4\xad\x04|C\xa9\xa8\x0ep\xaf\xd4*\xa9\xa7\x9d\xad0\xe5\xb1/A3\xbb\xb4`\x9f\xb7<\xb69\x14[\xc3\x99\xbc}2/\x9c\"\xac\xc4\x9b\xa9s\xead\xb1\x1c8\x1a\x00\xd9Y\x83\xe1\xf2\x87\x1a\xf8\xe2H\xb9\xe9m\x87]\xe3\xf5v\xf2\x02%+\xcc\xdd4\x17\x05$\xcct\xc3\xbd}6\x9e\x81\xcb\x8aH\x19\xf1!u\x8f\\\xd4\xc1\x01h \xeeM= nH`\x91\x89tb%}L@\xa8|e\x93\xdfbD\xa3\x1e\xe0?\xect\x94\xf2\x15\xbb\x901\x0d`\xbf^\xa0\xf7\x8d\xd2%2\xac-\xf4\x07\x1b\xe0~%\xbd\x19'\x10M!\x8e2~\x91A,\xa6\xe44u\x0b\xfb\xcd\x04\xe3G\xc4\x88)A\x89BbNlq\xa2[I#\x86\xfb\x96k\xab\xcd\x0d\xc7\x19^\x8c\x94F\xe1\xd6E\x11\x89\xa1\xf3jd-\xe9\xffC5\xcf\xb8\x1da\x14\xff\x8c,\x05\x1f\x043\xbb\xe4O\xfa\xc2d\x8d\xf1\xfc\x01\x03q\xbb\x13\xadaOf\xe3\xb4t\xdb\x8b?\xe2R'ct>\x03W\x9a\xa9t\x80\xc8\x0e\x98\xd2\xec:\xe0P\xdcY\xa0\xe0\xdc\xde \x86\xf6lbnG\xb8\xe2\x1b\x8bbh\xe7\x06Q_\x89Ri\x89R\xa9G\xaf\xaeXF6\x88\x8b;\xc9nCI\x14\xc3\xd5/\xc7C\xf5n\xd7\x90\xf5Gk\x8c\xb7\xdc\xb4gr\\\xe8)\xdc\xc2\xb5\xa1\x087wBy\x9b\xd9\xf4\xfeB\x1d\xb6q+\xa6\xa8\x00\x97\xbc\xb4\x94\xb3\xca\xae.U\xb3\x1c\xe2\x03NOp\xc9E\xb8\x00}\xcd\x05\xf9\xb2\xc5\xfd\xcc\x07OR\xd9\xb4\x03\x95\x85\x95#I\xe1\x1adr0=\xa9Q\xca\xc1\xf4\xc4-\x0d\xa0\xc5\xcf\x02\xd7\xf1G4\x08\xc4\x96)\x9d\xef\x001e\xa3\x12\xa9\x89\xeb\xe38\x8a\xc2\x9bu\xfbvA\xb0\xeb\x14\xb1\x9c\x01\xb1\xbc\xba\x02BY\xec\x9c\x0b\xdd\xabv\x95\x84b\xa2FEU$\x19 \x98 n\xb1\xf5^\xb9\xbcn\xa7r\xa2\x0bD\xff5>\xa6\xe8\x0f4\xaa\xba\x13\x0b\x8cl_\x1d\x92\xce\xc8\x9e\xf3\xa2\xe7&\xea\x1ac)~\xde\n3k2\xad\xc8\xcc\xee\x191\x18\x03\x99^\xbf\xc4\xed\xcb\xf4\xba7]\x15K\x8c\x0epc2\xb9\x1dn\x0c\xc5N/[p\xf0\xd8/\xfe\x8fd$d\xb8X\x1fG\\\xfd/\xd2\xdd:[\xabB\x19val\xb5\x0b7\xc6\xac\xc4M\x99s\xea\xa6\x11S\xa62[\xca\xec_]\x0e\xac\x96)\x14T\x1c\xfc\xa3\n\xf2\xb3\x01\x91\x96\xe8k!w{\xac\x0f\xde\x1eX\x9f\xf5\xee*3\xcf3?\x0cfL\x0dv\x19\xcf\xb8q\xf1\x8d\"I \xee\xeb\xb65\x11Z\x02\xf4\xc2\xb0r\xc7/ES1:X\xf5\xa5\xc9\x14\xb1Q%\xf4\xe14\xc2\x8aC\x8f\xcde\x13f\x19\xd1\x95i\xabS&\xbd4`\xee\x98\xb2\xb7Q\x8f\x18BH\x04\x9c\xfb\x12yj\xce\xb8\xf8=b\x9f\xf1\x8cO3>cy\x14'3\x9e\xf0\x19\x13\x88x%\xb0\x8e\xdd)\"sC\xf8\x9e\\t\xcec\xe7\x8b`\xba`A\xc4\x002K\xff=O\x19F\x1fc3hMpC\xf1\x9c\xa5\xf9t\xca\xd3\xf4\xde\xdc\x0f\xc2<\xe1,X\xae\xe24\x0dNB\xce\x9c\xf3\x05\x8fD\x13wu\xec\xbe\x0b\x13\xeb\x1eE\xcf\xe3(\x0df\x80N\x04m3*?\x1c7\x1f\x1b\xc6 \x15\xbd\xc8\x02\x89\xb5N\x0e\x84'T\x9dc\xac\xf0\x96:\xbbh9S$k\x9d)H\x13\x97\x8fz\x8a\xa8\x8b\xa6\xa5\x90\xe0#\xe9\x89\x9b\x14\xb7JOY\x06\x90k\x06[\x86\xe7\xe3\xfa\xc5\xfc\xea\xe5\xf3\x9b\x03\x88p}\xa5NYm\x91\x96\xad\x86*\xe8\xf9\xfdV\xe7Q\x9c\xca\xd6\xbf\xbd\xd1\xe8\xa2\x1f\xaf\xe28\xe5\x15\x19p\xe8\xa6]\xfc\xd3\xa2\x895H\xad\xcd\x89\xa3\x0eC\xaf\xfd4\xe5\xb3B\x10\xa3\x05\x84\xc6K4\xc1\x9c\xcf\xea\xf1\x8cn\x17~{\x86JG\xcc\xf3\xbd\xf1Qt\x94\x1c\xe5\xdb[\xdb\x0f\xe1\xef\xa3\xc9\xbd\xd3u\xc1\xac\xd0_\xcc:\x89\xfb\x85\xc2\xe2)\x1bnm1\xe5\x80.\x93\x0eX\xb7<\xf6\xe8\x11\x1c\x13\xff\xdb\xef\xfc^O\xde\xff\xcf\xd4=iAq\x9b\x97\x8a\xfc\xcao\xbc}\xf5r\xa0\xc0y\xe9pW6?\x04\xc5Fm\x19\xdd.p\xff_\x83\x9cJ\xcf1~\x19G\x9b\xd3\x98'S<\xc6e\xb1DD\x17o\xf2N>\xea\x85\x8d\xdb\x88\x11o\xd3&\x96\xdf\x0b\x06\xb3 ]\xc5\xa6L\x85p\xa9)\xfaV\xb3\x81\x08 6\xa5\xa2\x9dg\xa7]W\xe0\xcc\x03\xa7B\x1e\xab\xf93\x05\x89#\xf8\xe4AY\x0b\xdbg+\xc5\x96.@\x89P,\xd0\xd4\xb2@\xd3\xe2\xc7\x01\xeb\xe1za#\x06\xbea\ny#\xeb\x8b\xcf\x17\x1d%\xf1u\x86\x0e\xd6R\x9e\xbd\x0b\x96<\xce\xb3\xf6sO!\x00\x8aH\xe1\n\xb7\xe9\xbb\xc4\xa7\x06y\x94\xf0\xb9\x18@\xf9\xcb\x81\x88\xa7\xe0UNt\xe6\xce\x1d\xd6\x8b\xf8E\xf6.\x98\xbe\xef\x81u\x90J\x86\x05\xa4\xba)\x12E\xc5\xf5\xfb/\x8f,\xcb\xbasa\xd9\xff3[\xff\x97\x95\xfe/\xb5\xfe\xb7hpj\xf3@.\xfb\xca\xd8f\x18\xef\xbf\xd0\x98\x8a\xb3\x15B\xc8\x80\x0c\xa7 \xa3\xd7^\x92A\x15\x05.\xf1\xcf\xb9\xd8XE\xb3g\x18\x1ct\x7f\x7f_\xcf\xb9\xba\x92Q\xdb\xcb4\xb1m\x0fvvv\xd8\x88M\x9d\xb9\x83\xa6\xe8z>\x1aGmI\xcc^\xb2}\xf6\xf3\x0f\xd2\xaf\xd6\x90m\xb23\x97}\x82\xd2M%\xaa\xa8\x03\x07t\xde9\x05\"\x18\xec\xd5\x15\x83\x01\xb2}\x0dK<\x16\xb4O\xbbE\xda!\x1e\x0d\xaa\xfb\x1aT\x1d\x0d\x84\x9e\xae\xb0\xabl\xa1h\xbb\xe6\xc4\xae\x8b\nA\x08\xe8W\xb1\xb3\x91\xc6\x03\xd2b\xae\xb2\x8c}'@Hu\x12O\x84\x1e\x0b5 \x05\xfc\xa4$\x9c\xa6\xdf\xa7\xea\x1eT\x839\xbd\x0d\xcd\xdaP\x96\xd5\xd1\x96\xdc\x8b\xd0\\I \x01bp\xec,\xbb4\\Ctn`\xb9\xe5c\x88q\xc6\xf8\x8b\xdf\xb7\xb2\x05\x1a\xbe\x98\xd5\x11\xf3\xd1\xda\\\xb3\xe0\xca\xa4\x01\x87\xd8\x0e\x9e\xb2\xb8\xc9\xb7\x08\xbf\x98r>K\xd9\xd2\xbf\x08\x96\xf9\x92\x15z\x8b\x0c\xa1\xf2}9\x1b\xd9\x1e\xde\xdf\xbb\xffpg\xf7\xfe\xde\xf5\xdbk\x07\xe76\xad\x17\xdd\xd5\xafx\x04bG\xee\xb8\x1d\xcb8R\xc4^\x9c\x14{q.\xdd\xc0Kk\xf258\xe5\xe6\x8d\xd8G\x13\x9bf\xc4\xd7\xdd\xfb\x02\x8b0X\x04\x99\xeaZ\xbb\xc1\xc0i\xf9)b\x0b\x12\xa3W^\x11\x0cr\x00\x99\xd2\x1d\xc2m K\xcb\xe46(\x9f\x83\xf6xW\xeb\xae\xb1\xb32\x044q\xf3\x01\xc2F\x9a\xc9y)\xff23\xd3\xa6\xcc\x10\xda*R\x1f\xed\x15\xa9\xc3\xedm\xb8\x0f\np\x02\x18 \n\x8e]\xae&\x02\xdcz\xff\xf7\x1f\xfc~\xafq\x1d\x9av\xef\x84\x1d\x85\x8e\xb1 \x82\xc178j{\x15D\x96a>\xabK\xb5\xea\xbe;\xd1\x05\x87\x1f\xdc\xe2\xc2N\xe4\xec\x0co\xe2\xdb\x93\xf4]/\x1a\xee\x1d\x1f\xf3\xf4\xcbx\x96\x87\xbcW\xa7\xda2T\x90\x1eJ\xc1EY\x0f\xc4\xd3k\xb2UQF\x00\x89*\xec\xb1X\xbd\x96\x1b\xd0\x07\x93\xdd\x08\x1cq\xb8}Pw\xf3\x1b\xcb\xac\xfb\xdb\x10\x95\xb3\xc8S\x1d\xc0\x90cd\x1f8\x12\x99r\x9c\xd2\xef+\xb5Ca\x9c\xc0\xba\x9f\xbe\xf5\x88\xe9/\xc7\x04\xa8}\x87&\x8b\xd3x\xb9\x8a#A\x0e)8\xa8\xe7\xd9j5b\x97\xc5\x0cZ\xcb\xf9y\xb6\x88\x93\xe0\x1b_\xf4\xe4u\xbc\xcaW#v\xd2\xbd\x1a\xff4\x8bF\xecx\x8d\n\xafV<\x81\x8fA\xcd\xf3n5\xd3\x11;l/\xf9,\xcf\x16/2\xbe\x1c\xb1\x8b\xf6\xc2\xa2\xd9C4{{\xdb^:\x16\xc5\xb7G\xecY{Q\x7f\x15\xfc&\xbf\x14}\x19\xb1\xe7\xed\xc5O\xfc4\x98b\xe9\xf7\xed\xa5\xe5\x91\xe4U{\xc908\xe3ox\xba\x8a\xa3\x94\x8f\xd8\xeb\xf6\nA4\x8fG\xec\x8f\xb4\x17|\x11\xcd\xe3\xe7\x18\xd8\x9d'#\xc6y{\x95\xdf\xc8\x97\xabw\xf1k_\x8c2\xebP>\x8e\xc2 \xe2?\xf2\xc3`\xe6gq\xf2\xa9?;\xe5#\xf6\xaeCE\x85]\xe9\x88}\xb9F\xf1\x11\xfbi{\xe9\x02u\xdf\xe6\xcb\xa5\x9f\\\x8e\xd8\xcb\xf5+} A1G\xec\xcd\xfaU\x11~\x9f\xb5W\\\x04\xa7\x8b08]d\x82\xe1\x18\xb1\x9f\xb5\xd7H$\xa6\xa4#\xf6y\xf7\xd2#\xf6M\xf7\xc2\x9f\xc6\xb3\xcb\x11\xfb\xb4\xbd\xc2\xcaO\xfc%\xcfx\x92\x8e\xd8\x8f\xd6(\xfe&>\x1f\xb1\xdfh\xaf\xc0/\xf84\xcf\xf8\x88\xfdV{\xd9\x05\xf7g\xd0\x91\xdfl/\x0bF\xb4\xe9\x88\xfdZ{Q\xb8\xc5\x17e\x82y\x1d\xb1\x1f\xb6\x97\x8f\xcfxr\x16\xf0\xf3\x11\xfb\xed\xf6\xc2\xf38\xce\xc4\xc2\x8c:,\xb4\xcf\x830\xe3\x89\xb6\x9a\x93\x0e\x95^\x0b\x88\xe3t\xc6\x1d\x8aO\xf3$\x1c\xb1\xa0C\xc9t\xba\xe0K\x81\x83~\x87\xc2o\xb1\xb0\xd6\xf7\xbcC\xade<\xe3\xe1\xe1\x85\xbf\\\x85|\xc4\xc2\x0e5\xbe\x145~\x9c\xf8\xab\x95\xf8\xc6\xb4k\x8d\xe7q\x18\xfa+\xb1F\xd2\xaeUFl\xde\xb5h:b\xab\x0ee\x0f\xa3|)\x9b\x9eu(\x8e\x8c\x8e\xac\xb0\xe8P\x01\xcc6e\xf9\xb3\x0e\xe5\x0bg\xf7\xb2\xce\xb2S\x1dd\xb8F\xec\xb4C\xe9w\xc9\xe5\x8b\xecU\x9e}\x9ag\x99 \xeb\x97\x1d\xea|\xe9'\xefg\xf1y4b\x17\x1dJ\x7f\xea\xa7\xfc\x0b\xff2\xce\xb3\x11{\xdb\xa1\xfc\x8fx\x92\n\xde*\xf1O\x97>\xae\xb7\x11;\xe9^\xf1m\xe6/W#v\xdc\xa1F\xb1a\x1c^d#\xf6\xc5z\x15\x80|~\xd5^\xe7\xb5\xa2\xb7\xf0\x91__\xa3\xc2\x8bh\x1a\xe63~\xb8\\\x89\xd9\xfcq{\xcd\xa2{\x10i\xe4\xc5\x1a\x154\xaap\xda^\xed3\xceW_\x04\xd1\xfb\x11;\xef\x00e\xc1\xff|%H\xda\x1f\x1d\xc8\xd7\xe6\xb2\x02ap\xeb\xc6\n\xeaw\x03i;;}\x96\xa6\\p\xf8\x87E\x87\xc8\xd2\x9d\xe4\xd8\xb4\x9frV;K<\xef\xa4F\x88:\xb5\xf5\x9eh\x8b\xd4\x1c\x8dg\x05\xbc\xd9\xbc|M\xcbW\xbf|\x0d\xcaW\xeal\x8az@\xf9\x8a\x87\xbb\xb0L\x88<6-\x7f\xad\xca\xd7E\xf9zV\xbe.\xd5k\xe3\x89\xf7\x15\x87\xe0\x03\x8f\xa8#/\xe6m\xef\x1a\x11\x8e\x8a\xbc\x9d\xedz\x9e_\xe4\xdd\xdf3\xa2\xe5\x14y\x0f\xef\x1b\xf1\x80\xca<\xe3\xf8\x1d\x96yF_\xa6E\xde\xa3\x9dz\xde\xbc\xcc3\xfa\xb2*\xf3\x1e\xd6\xf3fe\x9e\x01\x97\x85\xca\xbb\xbfe|\xef\xac\xcc3\xda\\\x16y\xc3\xadz\xde\xa9\xca{\xb4c\x8c\xef\xb2\xcc3\xc6pR\xe6\x19\xdf;.\xf3\x8c1\x9c\x17y\xf7\x8d\xbe\x1c\x96y\xc3z\xdeE\x99g\xcc\xfb\xdb2\xcf\x80\xcb\xf32\xcf\x98\xf7\xf7e\x9e1\xef\xcf\xca<\x03.\xaf\xca\xdaq\x07\xdc\xebv\x11G\xab6\xcd5\xd9\x1amW\xc7\xceQzs\xa8\xc5\xe8=}\x10\xa0\xad\x1a\x04D\x10\xa0\xadj3b\x1a5w\xc9\x807\xbfU5\xb2\xf5x\xfd]ugDN48\x81\x1eD\x837\xf0\x03tX7#\xd7\x12\x8e\xa3\x00X)\x8d\xb3\xdb\x87.>\xaa\xdd\x02\xb2\xaaM\xf1\xc1\xaf\xf3\x14Y\x11\x8f\x84)\xc3\xf6\xd4j\x82\x10\xaf\xb4F\xf5\x98\x06z\xc2\xff\x8c\xf9H\xf5-\\j6\xaf\xbe&\x13\xc9\xd0\x19\x14&\xc5\x1b\xd3\xd1\x0c\xc6\xc2\x82D\xff\xda\xaalar\xad\xaf\xb54\xe7\x05ab\x9b\xe7\xac5\xd6\x1a\xec\xe4Y\xe5\xae\x1d\xb1s\xdd\xc7\x01n\x96\x06\xb8\xa9\x0c\x106]\xb7_$\xa9\x86;\xb8\xbfg0\x14.\xe7\xac\xa9\xcc\xb93D|\xc1\x83\x0c\x83\x9b\xd1\x1b\x98\xa3!G\xe2\xac\xf3\x00x\xcf!\x85\x97\xb0|\x0e\xcb^\xcf\x05\x8c\xea\xbe\xec\xc3\n&p\xed\xac\xa7\xcbY\x1f\x96\x8c\x8c\xb0\xaf\x86\x10+\xe6^\x99\xf4-\x0e\xc6\xb5p\xf7\xc7A<\x87\x0e:f,\x06!\xbdM\x1d\xd7E\x0f\n\xcd\x10\x88\xb3@\x17\xadi4\xc0\xab\xe8>\xb0\x01q\x8b)Q\xa4\x19\x944b\x924}\x9f5W\xc9%\xa6\xe0\xfd7!\x1b\xd5\x8d\xcd\xc9\xc6\xb3\x9d/<\xc10{6;\xc9\xe3\xc1B\xd4\x89\x9c!\xab\xc8\xa6NyT\xeb\x07\x12\xef\xd0\x19\xed\xed!)\x15\x14\xf5\xd9\xa6 \xac[\xe2\xef\x9e\xf8\xfbTKh?p\xf3\xc46]Y\xc0\x95\x87\xcd\xec\xcb0\xbf\xb5\x88i\xbc\xcb\x9a\x83A\xa0'\xd0\x92$VI\xe8BO\xb8\xd7\x82u\xa9\x14\xcf\xf9zU\x87r)\x1a\xa9\x96_\xf3N\xb7\xab\xe5+A\xe7\xab\xe5KQ\xbe\xe3\x0e\x12ZQ\xcb\xde Z\xbf\xe3:U^_\xf4^\x9d\xda\xb9h\xad*Y\xde\x88\xf2*;u\x88\xb1ws+\xb3\xf2\xc3[\x1eI;\x8e<\x9aT\x82q\x9e\xe0#\xb1\xee\xe5G\xaf\x18\x05\x17/!\x01\xf7\x9c\xdb*w_1\x0f\xa9(b\x0f`\x1fw\xc9\xc5`Q~p\xcc\xd8\x97\x8e\xdd\x04T\xef\xcf\x0e\x8a\xdd\xc9\xc9\x00\xa3\x8f]S\xa7\x8aG\xea\x87QC\xa7\x9cZ\x17\xed\xa6\xa6\xa13z\xe6*\xb9\xcbg\xad\xac\xfd\xe4\x87:W}\xb82\x1b\xc3\x1b\xa2\xe1\x08\xc2\xe5\xbcb\xf4]{>\x8a\xb5\xf8H\xff\xe0\x11\xd3\x0e\xafi\xc8M\xdb(w;\xbbr\xd5\x94\xa7\x9a\xa0\xf7\xe6 \xc8\x9f\xab\xe8\xf7\xa1q\xce\xd7\xf5\x8c\xa5P\xcc\xa3\xe3t\xd6\x0e\x8fi\xa9\x8b\xea\x84G\x11\x1f\xb6p\xa2)\x0f\xa7<\x98\xd3\xa6`\x85 M\xf0\xe9\xe0\\\xebM\x0bH\x83\xcfCt\xa7\xd4/\xc0\xb5\x08xH\x07\xe7\x9e\xbe\xc6]\xb3\xc5-\xa8\xd2#O\x18z~\xcd\xcd.\xd1\xd0\x91\x0e\xce\x93RZ\x8c\xbcE\xa37\xb9\xfc\x08c\xd8\x82|F\x18\x817\xba\xc2\x98\xa5\x0b\xe2[nq\xe4'\x11\xf1.ps4W\x0fDu\x86p\xcd\xb5=\xac=\x8fV\xc4oH\xede\xde\xc1\xea'c\xf2\x0c\x1at:\x9b\x02v\xe8\x14\xfb\x07\xda\xb5\xe2\xaf}tj\x15\x0e\xb2\xac>\x97\x83\xc6\xe0\xa0\xb9\xbd7\xa0aJcG\xf0\x1f\x19\xba\xbap\xdfPo@o\xfd\xd4\x11\xeed\x9d\xa1\xcb\xeb\xb0\xdd\xa6\xd8\xe2\x07\xce\xa1\xd3\x15\xfbn\xc3\xbb$~\x08\xde\x9d\x17\xd0.\x0fI\xcd\xd6\xf1\x83\x13rk\xd8<1N\"\x9cA\x13\x87\x9f\xd8\x81\x13\x9b\xa9\x01T\xf7e#Xp\xfc\x1d\"\xe6'&\x11\xe8\xdc.\xd5\x8f\xde\x95\x07\x9f\xd4\xf8\x8d\xc8\xb7\x08\xaf\xec\x89 O\xec\xa08uR\x94D\xad#\xff\xd8n\xe4\xfch\xd2\x0f\x9e{\x15\x0e\xce\x8d\x01=\xc3bR(`\x8b9\x19\x8e_\xfb\xb1\x8b:q\x19\x98\x99o\xac\xe2\xf0\x03\x8f\x84\x8f1\x8c\x98`\x1e\xe6\xe0\xa7 \x0d\x16\xb60\xba\x08\xe7\x0f\xe8&=i\xcb<\x81\"Z7\x9f\x85\xe77c\x08\x9b9\x93\xf3\xf9X\xcd\xf1\xaf\xfb\x18\xb8r\xf9i\xc7\xb1\xa4\xf9E@\xe0|\x14\x01\x9e\xd9\xf7#\xf1\xfd[\xb2\x01Gy\xbe\x8c/?\xf9]v\xc6\xe4\xe8\x1fr\xf4\x1f1\xfc\x0e\xfb\xd01\x8d\xb7\xdd8\xc5\xf8\xec\x13i\xb1~\x0dk\xf7\xd98\x7f\x8deQy\xbb*\xfe\x11\xb8\xd7O\xac\x1b\xf6RD.>\xe9\x83\xdc\x14\xdd>t\xcf/\xbbn\x1f\xe6\xdc\xd5Jx\xcc\\\xfaU\x17;=\xfaP\x07\xd1\x84\xb7\x9bc\x8a\xfcY!.V\xa0\x1f\x15=\xd7\xe0\xa1\xa8\xbb\xfa\xfc\x107O\x925Ppv\xfc\x97z\xf2\xf2\x92\x84\x8b/\xfc\xc7\\\xf2~\xf8\xeb\xbaV\xf9R\xad\xcc\x19\xc5b@nq\xa5&\xd4\x1d\xbb\xaes\xa2\xc4\x8c\xaa\x8d\x8f\x86\xe3fQP\x8ar\x07\xceJ\xae\x9ak\xd3\x15FWe\x9dtGI\xce\xca\xcey\xb67\x98\x80e\xd4\\\xe3\xd9\xc9jq\xe9\x07\xd9\x18v\x16\x8b\x9f\xe3\nL\xbc\"\x97\x8f\x841k\x80\x7f\xad>K\xd8\xb3S1\x8f\xceH\x0dTS^\xe7\xf2>Bti\xd2\xdc\xcb\xebH\xd6\x11\xaa\x10\xe48\xcd8$\x82\xe8\x18\x89\xb9\xd4\xc1\x84\xf4\xa6\xea\xb8\x89\xdd\x14\xe9\x07\xa8\x98\xa18Q0\x04\xecG\xbc\xaf\x1a\xb9\xf9#\xc6\xa4\xe0\x93#\xf1D\xc5\xe6\x8b\xc1\x82\xad\xb2\x15\xa5\x8b\x08\x0f\xfb\xfb\x80>r\xfc+a\x1c4\xbd\xe1\xbe[c\x0c-R\x9a\xe4\xc2Y\x0c~\x82\x1e,\x06\xbf\xe1\xffx\xbfr\\E\xc8\x0f\x92):)\xbd\x1c:\xcf\xf6\\G%\x15B\xbb\xba\xeb:j\x11\xa9*Xy\xbf'\xa5\x1e\x15rS\x9d\x1a\x83N\xd3\x1aK\xfe\xe8@G\x98@\xd1<1\xf4\x14\x10w\x1d\x1e\x8aD\x8bg50\x15\xc3u2\x06\xe0\xce\xb1k\x1d5.w\xd3\xb0\xc5\xa8n\x9cL\xee\x8d|\xd9Nro_+\x9aV \xe9\x1c\xb3\x86\x1ao\xc8N\x06x\x84\xbb\x03\xdc@\xce\x95\x8a\x15\xb6i\x91 h\x9a\x92\xca\xa9\xea\x0f=N\xb4R\x83\xd2\x92\xbb\xf2Z\xb57\x91\xa8b\xd6\xd8\xf8\xed\x05UIFm\xb9 A4iI\x90\x0f2\x96\x8b\x99\xc5\xbaf\xa4\x9c\x9d\"\xed\xd5\xac\x18|\x01\xf6\xc1\xef\xf5\x9a\x19\xc0\xc4\x90\xb6C\xfd\x88\xec\xc9\x9c\x02\xb2\xbd\xd9\xeb\xf5\x0be\x19\xc3\x88\x96\xa9\x0e\xd4O\x82\x9cE\x92'q\xc8D\x12\x89\x8d\x0d\x94/b'lb\n\x8d23\x084W\x9a\xd2\xd6\xd3eG\x90.\xc6\x03\x1e}\xc2\xf1\x07\xd7m\xcf\x95\x98x\x8d{\xf7[!\xba\x19\x8b\xa3\x07`\xf1\xc3q\xab\xbe\xea\xc5\xb6\x03\x8b2O#\xdd\x82}\x05\xa2\x81\x08\xc0\x1b\xd9V@!A\xf8\xf5KmMtgu\\\xdcuc\x94\xc1\xf2P\x93\x1b\x1f\xb9\xce4\x8f\\P\x87\x9cG\x12\n\xc3\xb1~%e\xb8\xa1 P\x8c%L\x85\x9aT\x03\x12lg\xd4\xa2\x9dt:\x9c\xa9m\xf5!\xd5gd\xc7\x167[\xb6\xc8Z\x19i\xda\x15\xe5\x86\xd6\xb7\x1e\xd4:\xfb\x7f\xd3\xd8\x87xj\xe8i\xfb\x0bzb\xffo5\xf4'\xea\x180N\xe9B\xc4=\xc66\x94SQ\x8b\x91f\xbb\xb1\xea\x8d\\d\xb9\x1d\xc5\x14\x84\x83\xf7Y\x8a.1\xc7\x17 \x8d\xaf)\x06v\x88\x07\xbf\xd1\x8b_\xfc\xb4\xfa\xac\xfc>O#\xad\xbd\xde\xcc\xf0\x91\xf6z3\xa9^o\x86\xce\xb3-\xd7!M\xd7\xf9ZNX\x1ay\xb5\xca+\x19\xf7ui\x13\xf0> \xa5\x00\x94\xde\x88\x90*\xa4\x06\x16o\x00\x9e\x035&\x98\xe6J\xeeE\xd8G\xbe\x9c\xa2\xdd\xc5\x97(\x88\"M\xd2\x0cPEScl4\xc8\xa3\xd5cl\x1c$\x04\xa9\")\xb6\x8d>V/)\xb5\"\x00\xc2\xaf|\xca\xf8\\\x9e\xaf\xbf\x00'qy\"D\xdb\x9a\x90\x81\x0cv\xe9\x04\xd6\x06\xf3D\x1e\x1d\x9fcgH\xae\xfd%I\xa5n<\xff9HR\x12\xceI\x10\x85\x1a\xad\x05\xc6\x7fC\x83\x1ey\xda\x98\x00z-\xf2\x7f\xe5\x15\x1d\x83\x1a\xaeq\x8a\xf2\xe3\x89\xc8\xa5\xadu)|\xce\xad\xda\x8frU\x95.M\xb5\x06\x92\xfa\xdd\xb1\xe0\\\x94\xb6\x8b5\xec\xc3<\xf2x\x94\x1c\x1e\xff\xeb\x94\xde\xa6G\xd1\x9c:]\x9d\x8e\x92\x8b~\x81;\x888\xe5p\xd6\xba\xb0Q\xec\xe3]\x92\x98x)\x8d_\x93\x94\x8c\xaby2@J|m\x00\xb1\x1e\xccI\x8a\xb7\xbel*\x8b\x06\xfc\xd6\x12\xe1\xbc\x0f\xedf\xbb\x16A\x08\xf5\xdd/\xc21\xc4\x06~\x0cS\xb2\xf2\x9d\xd4\xb4D\x80\xfb\x8e\xc7\xb2b\xef\xc1>\x86\xcf\xa5<\xfe\x0c\xcf\x0e\x1a\xa2\x9e\x1c\x1f\x19\xe6\xd4\xea\xdch2\xbd2\x9c&5\x93J_o\xa8\xc5\xc5\xef\x9a!\x8fLA\xae\xda\x804\xd0\xfe\xdaN\x95,\xb0>\xc1,\x8f\xa8\x15\xf1\x88Zq-D!W\x07\xe1ej\xcaD\x06\x8cf\xbapR\x0c\x93\xaaa\xc0\xa2p\xe1/\xb3\x98\\p#\xdb\xfa\x12/i\xda\"\x0c\xa0\xa2\x0djB\xcd\x07\x9e\xff\x8d\xeb\xa87\xa13\xaccm\xd5\x89\xc1\xf2*\xcbm\xa2\x8aNc'\x1e|\x80\x1e\xc4\x83\x8f\x16i^\xa4\xf7j+\xe8\x10\xa1\x9e\x8b$G\xc1\xf6\x82/\x7f\x18\xa4\x9c\xd0\x84\x1e\x9a\xa0c5E]\x08\x93blF\x93\x17\xf1\x1aOH\xe0\xb8U\x11\xd6v H\xe5\xa8\xb6\x82\xee\x1a\x8f1\x99}\xf8\xee\xe3\x12\x91\xd3\x1e4,\xb3\x96\xe8;\"o\xddt\xcf\xcfM\xf7\xca\xe8xbA\xc44n\x8d\x84\x11#\x11\x987\xda\x88n\xbe\xd6\x92A*\x00\xc3\x01E\x93\"\xa1u\x1d\x17r\xb0\xeb\x84(\x9f6k\x04\xdb\x00T\x82\xce\xba\xde&b\xf4\xd9A\xa32\x99_\xc2\xe9*\x15\xbb5+J\x0c\x01?\x88\xe9\x92\x864f\x0c\xd8\xc7,L\xfd\x15\n\xdd\xc2\xa9gIS\xc5\x95\xe7\x88\xach\xe2\xc4\xee\xc0\x0f\xe7\xf4\xf6x\xc1\xda\xaf\xbe\xdcu\xe1eM\xe3\xe5\x83\x08c\xa7\xeb\xae\x809&{\xd1\x0d\xa8\xe0c\xcb\xd6\xb7{\xec\xd4\xc2\xb4\xec\xfa\xb7\x94\xc8\xf9\xc8;\xd5yx\x11}S\xf7~\xb1p\xc6\xeb%\xeb`\x8b\xf7\xb5\xeb\xae\xb6\xa5\x18u\xd6\xeel\xf4;\x0c\n\xa37tU\xaf\xf8`\xd5\xb1\x9c/v\xd95\xab^\xcb7\x91\xdd\x93\xbb\xd5E\x14\xc0D~\x19\xd7\xccVA\x9c5\xfe\xc0O9@\xd0\xbe\xf1?\xffS\xfe\xec\xd6\xeb\xa3\x8e\x92\x87}}[~\xa9T\xa6y3\xc17e\xb0\xc3S\xb2\x14\xef)%\x9a\xb7\xf0\x92*BX\x95\xce\x94zMOX\xf7\x99\x91\x15\x04\xc2z.\x04\xc8\xf0\xa9\xa8\xe9\xb9\xad8w\xc7\xd4\x0d\xecC\x80\xb9\xa6d\x93\x0c\xde\xee\xe0&&\x8c\x99?\xaf\x93))\x03t\x93,Y\xd3pN\xe7')\x89S\x0d\x0c@H\x04E\xcd\xbf\xfa4\x98\x1bj\xa2C\n\x8f\xa9\xe4\x87:\x90\x820\x06\xefz\xd1j\xcd\xf6\x92\xa9\xa5k\x9ePA\xfbl\xa5qC\xc4\xf2)\x995\xd1Bhb\xce\xf4\xc0Z\x16\xbbfI\xd3\x0fr\xe3\x1c/\xf4#\xbc\x83}X\xb2e^:K\xe7\xbd3\x9d\xb9\xbaKS\xf48\xb9C\xb3(\x14n\x85pw\x87I\xb3ej\x91;\xcd\x8blD\x17h\x9c\xad\xde\xf9\x1e\x96~\x95\x028;+M+\xb7\xa5\xfa\x17\x15\xeb\xed\x93>\x9cT\x8an\xfbp2M\x18\x88o1MW@\x90\xc6\xb3\xe5\xfcIb\xa4(\xbf\xf8\xa5\xcf\xd7mp6\xc3\x83\xd2\x19\xb2\x0fW8m\x8c'\xaeu+\xb5!j$n\xe8\xaf\x9cs\xf5\x0d{dh\xed\xde`\xa7\xf9\x04\"t\xca\xe2\x1e]\x0f\xb9'\xcbU\xcb\"\x9f\x0e\xe5\x8e]Jk\xfa%\xd0\"\xf7+\xc4\x8f\x8b*vuY\xd97 \xb2}\xb8\xc8O\xe3\x074\xd6\x9d\xf2\xd3\x18\xf2\x01Ur\x1e\x82\\\xe0+z\xd7\x9c\x8a\x04\x14R35\xa46\xa8\xf9\xaf\xa7\xd2\xa8\xc4\xba\xbe\xec\x94\xbe\xa6qB\xab\\\xb4\xfa\x91\xa3\x83f;>\x91\xd9@\xde\x1d\x19\x15\xd4\xeaG\xca\x06\xe9`\x1d\xadMZM\xf5\x83\x0c\xb5\x98fn\xd0\xc3\x91\x08\xd3h\x84\x1c\xb5\xb8\x91\x92^l\x94\x1f\xb3\xa5\x1c(\x02q\xde\xde\xd0\xd6\x9e\x96Hx|`l\x91\xdf\xf7\xe1\xb4D\xe8\xf4\xa0Q\x0e\x8c1\x9c\xeaW%\xa6 m\xb4\x02\x91\x1f\xccz\xc1\xedp\xe8\xb5b\x9a%\x14y\xf2gBCy\x81;8\x17?B\xf1L\x81'\xffM\x03\xba$\x18\xa5\x84'\x92\xc4\xd2\x15\x86 \x95\xd9\xc0\xba\xa2\x94\xc4K\xa5\xa54\xbe;\x0c\xd3\xd8\xa7\x89\xcc\x97\xec|p\xfb\xd0i\xb0h,\xa2\x9d\xb3uG\x91\x17\xbaiWxo\x88P\xdbCW\xe1N\xb8v\x86;Kux\xea\xb4\x9eL\n;\x12 \x86X\x1d\xe1[i :z\xf0'i\xb4n\xa1\\\x03i\x00\x95\xa3\x8f\x19\xb7\xa5\x0dU\x05H\xd3\xe1l XP?\xb2\xb8\xd8`*}\xd4\x93p\x98\xd0\x01\x1eJ\xf2\n\x86-\x82\xf9eU\xd3\x14_\x93zb\x020\x83\x821\"L\x8c<\xbc\xf5\xe8:\xc5\xa8\xb4\x0f\xc4J\x06\x9c|\xa0v\x00\x156\xdf\xcd\xb4*vL\xa9\xf6\xd5\x8f\xd4J\x0d\xc4\x96\x140\xecC&\xf0\x16m\xc4\xc5NA\xef\x11\xae\x04\xaf\xa3\xba\xc4s\x86\xcc\x1d\x8b_\x85y\xe4\x12\xc5\xfd:\x1aHg\x9d\x0d\x18=\x07\x1fU\x11\xcfacC\x1b\x17B\xfd\\\x8b\x1c\xffU\xac\xf2\x1b\xcc{@H\xb1\xa4\x15\xf2\x81D\xc08\x8a\xc4\x9e$\xac\xb7w\x91\x97\x13\xe8\xd8\xe9\xd2pn3\x1d\x97\xad\xc8W\xe1\xc5>\xe4d\xabi\xa2 &\x8b\xb9kD6\xf4>tQ\xc3\xf1.\xf2\xba\x96\xd3M\xfd\x04\xe5\xd7\x85J\x18\x1bhw,\xe1\x9dm\xd0f\xb4P\xa3\xcc/0=/\x1f\xb0\x02\xb7\xa2\x10\x1d\x10\x9a\xc7\x01\xda\x96\x8b\xb9\x94\xdaV\x8a\x1b\x1b\xfe\\\\z&\xdfs\x8a\x8d\x0d\x7f6i\x1et\x1f\xbc\xa3\x0d\xd4\xfc\x1b\"\xf7F\x1a\xdfA\x92\x92\x94b\xd6\xf4\x1b?\xbd\x8c\xb2T(\xc5\xa2X\xde\x07\xb4Yy\xf8n\x10\xb7\xd6\xb0\x98\xf9?\x84\x84\x93\x8b8[\xa7-l\xac\xe5G\xe15\xed\x94*\xcc)\x95\xf1Z@~r&\xb0B\xa9B\x03\xbf+?\\\xb9\xaa\xa1\x18\n+\x10W\xb6rny-\x96*.-U3VI\"m\x10\xe8\xd5\xcfEL\xc9\xd57]D@}&\xa6)\xc5\xc6\xc5y\x8f\xfa\x02\x99>\xac+}z\xf0\x16Q\x01\x0e\xc8\xd4%\xbe2el\xcc\x17\xac\x9c\x05\xdb\xe5a\xe2s\xd7\xd7\xfc`@-^#wA\xe4\x11K\xfb@\xc4a\x99\xf6\xb11\xc7\xc2=\x8a\xa3W\x1do\x1f\xae]a\x0e,GA\x1d\xf2 \x06N\xbe\xf6\x00\xa4\xff\x16\x1cVi\xc58<4\xcb\xc6\x1fLJ\xf3\xc7\xf6a\x0c\xe2\xea\xa3R\xd3\xc9Y7\xb9\x83\x04\xf3\xc2\xfe\xd6\x98s\xd1D\x19\xc0\xfctf=\x84Q\xbc\"A\xa9\x07y5\xed\xa8o\xa4n\x1f\x0c\x1e\x7fz\xa0/\xfc\xd0O\x1a\xfd\x13\xf2\xda\x05\xc7o'2iNd\xda\xf9\xd3k\x88L\xda\x82\xc8\x84\xea\x8e\x11\xdbKe\x9csL\x0c\x95\xad\x81\xc9\x89\x17)\x8d\x19e\xe9\xa3\xe3\xb8 h\xf0P\xb2\xdd\xca\xdbC~\xfe\xfd\xa0)\xa8\x92\x80d;\xa2\xcb\x8d\x84\xdb\xb2\xa4\xa0\xd9\xb5\xb1\xd8\xb5\xcd\xfd\x81\xa26\x8b\xed\xbb[\xfd|0\xd9d\xab\x1f\xfb\xb1\x0e\x05\xc10\xcb\x11\xf0\x85GG\x8d\x0b\xf2\x03&\xca\x07\x82\xef!iJW\xeb\xb4\xfb j*\xb5\x01x\xe32\xae\xea%\xad&\x82\xea\x0eR\x94\n\xf6\xe5\x91Woc\x8c7`\xe7\xecc\x9adAzDVt\x0c\x0d\x01-\x18]{\x17yc\x83m\"p\x85\x0e?\x9d\xb8\xe2A\xa1\xab9u,\xc4@\x03q\xac\x95VM\xc0J?sy\xf6\xbcA\xcd+q\x95\x9f\xf1\x8a\x9eI\x89\x0fs(\xf2\xe6\x1d\xea\x01Q\xcb\xa7\xe9D\xaa\x82[\xfb\x0e\x11Z\xe5S\x07\xef8\xa7:[f\xb1\xc8\xfe\xe0\xdc\x0f\xaf#\x8c\x02j\xb3\x15P?\xb9\xdd\x80U\x8b\x99\xb7f\x8a\x95(?\\s\xc8\xd6n\xae\x11\x08rm-\xf8 \x90 \xa6d~\x07q\x16\x86~\xb8\xb4\x89\x01E\xabZc\xf9jU\x95\x1e\xe5\x19\xc6\x0d\xd9\xf0\xe5GL\xf4\xadA9\x0e\xcd\x9a\x85\xb0\xe0\x00\"<\x96\x10O\xfd\xe7\x8d*Z\xc9\xf6\x85\xf9\x06m&\xef\xa4\xa9Q\x10\x0dg\xe8\x14B\x18\x064\xd3W4\x96m\xd32\xc8\xca\x08\xe3\xeb\"\xafns\x1f\xa0(\x85\x1a+\x7f\xa9x\x06\x12\x13\nZ\"\x97\xc7\x85Pjb\xc3B\x0d\xdb|\xfe\xe4\x92\xb9\x8a]E\xa3\xcd0+\x90x!q\x92m\xbc\xcb~\x9b\xde\x01\x9d\xa9j\xba@\x07_m\xf0v\xe2C/1\xb6\xa1BU\xc3\x01\x97O\x9d\x82o\xe5\xad6l\x18\xd8\x87\xb9\xbd\x8a\xd4\x17\xdd\xe4D\xa8\x19\xb1K\xdcq\xd2\x9a\x99\x10\xc0\x957 \x13\xb8\x841\xac\xfb \x8e\x8b\x87\"i\xe3u\xa6\xfa\x11I\xfd\xb0\xabvZ06\xc6\xb1\x18k\xe3\x0b_\xb3\x07T\\MrQ\xc3\xc9\xf1\xae\x90Y\xa4ZV\xd2\xad\xc4\x8eX\x06F\xbaV\xfa\x99-}\xd8\x07\xe2\xf6+\xc97M\xc7\xf0\x8d\xed\xc42;S4\xaeX\x8ai\xb5$z\x99\xd7\x89\xc4\xcb\xdc\xb3\x07\x87\xd1v\xa6\x8d\x11\x1c\xda\x0eQ,E\xc3\x08\xdb\x0e\xab\x15\xd0\x0f1\x9e\xa0\xe1\xe1\xad\xed\xe1\x89\xed\xe1+=0\xa6R\x01\x91c\x9d$=\xb3\xfc\xce\xcal\xd8&?\"hg;\xf1Le\x83\x05\x93\x84v\xb2\xadW\xb7j\xee\xaa\x9f\xf0\x95\xc5\x9a\xb4Nu\xd4\xd1\xa83\xb1\x19\x1a\xe4]\xf9\xad,\x8d\xe9\x8dt\xa7W \xda\xc0\xc3A\xc9\xb2\x90\x07\xbc\x8ey\x90\xbc\xa6\xd7@\xe1:n\x1c:\x0dg\x18a n\xc9{Hr\xd5\xd9\xdf\x177Fm:\x04\xe5\xa8\xc9\xda\x13a\x10\xd7\x11 \xbf@n\x1e!\x14pE\xcb=\x8dE`\xa0(E\x03L\x05\x8bV/]\x17&r\x1dr\xef\xa2` \x9e>\xc8\xb8\xa3\xfaI\x1d\xb9\x99\xa8X\xa2V\xaf~~\x88\xeb\xae\xfaI\x9d|\xd3>\xacC\x17\xc6u\x10|\xd5\xd4\x93\xdc$\x01C\xc9'-\x07\xd2j\xc8\xcd\n\x04\xe2d-x/\xb1w\xd2Z\xb0\xf8R\xad\xb6T\x08\x14J\x06\"K;\x87\xa0\x8f{z\xcc\xa8B\x9dv\xb5\"]\x07\xd6\xc8/<\xec\xa6\xd4\x0bL\xe5\xfd\xacF\x11U\xb0\xb9F\x99\x13or\xea&\x0e*\xb3\x92\xb6`\xac}L:/\xc74\x10\x80\xa9^\x1f\x17\xca\xd8\xc2PB\xcc\xd5\xd0e\xaev\xbc6\xd3\x84T\xc3:\xe5\x1d\x943\xd0\x9f^\xd2\\\xa1\x02\xf3\x88&\x10F)\xac\xe3\xe8\xda\x9fS \xf0\x18\xdf\x7f\x0c\xbcA\x93b\xc8\x86\x0b\x9aH}\xdaE\x8c\x90*\xc7}e%\xc5\xa85\xf4\xb9&H\x0bz,\xf1\xcf\x02\x80Hh\xc5\xebK\xac\x81\xa8\xbc\xeb\x89\xf4B\x90Tm\xe0\x95\x88\xe0\xed\x9dt\x8a4D\xe8\x9dfx}!\xe2\x99\xa7\x85B_\xa8\x9b\n\xee\x02\xcf\x95\xb4\xa4P\xb2\xdb\x19\xe8f\xc0\xb3\xcd\x8f\xcb\xef6\xa0@\xbe\xfc|\xd0\xe0s\x1c !\x88#\xc4\xd4W\xab\x9d{lwa\xd1o \xae\x1d\x1e\x03\x9d\x0egu\xf4\xa9\xaf\xc3\x88\x9b\x9ar\xa0\xc9\xcbd\xcc\xc72\x9a\xb9}\xd8T\x1f\xabz|\xa0\xdc\x1d>\xd7\xd2c\xd1\xd6\xcc\xad\x9b+\xa19]\xdan\xce\x1f\xecs\xa6\xea\xed\xd9\xfd\xbd\xf6\xfa,\xcdMR\xa4L \xbd:R\x8e\xbf\xa5F\xf6\xab\xd1\x94\x0d\x03;\xd5\x0f\xac2W\xd8\x87\xa9}]\xb8\xa9G}e08\xacd\x92\x8f9\x10\x8b\xc8N M\x9d\xea\xfd\xbei\xa4\xef\xf5#E\xaaj\xd3\x16\"|\xa7\xc4p\x07\x81\xb4]\xa1\x12|\x7f R\x9fom\x8fJ\xcf_\x1d\x7f<,?/eU\x1a\xbc>|s\xf0\xe9\xdd\xe9y\xb5\x9fQ\xa5\x1fY\xef\xcd\xa7w\xefJ\xf5\xb6wJ\xf5\x82\x88\xcc\xf1\xc2\x94}\xa9>8\x08\x82\xfc\xd9\x01\xe3 \x8a\xc7 Y\xd0w\xf2]\xf9CWA\xb6\xa1\xfcV\xab\xcd\xb3\xd5\x1a\xb95\xf6\xa5\xfa\xfek\xf9P\xfeP+\xfc\xf5\xe0\xfd\xbb\\q-`\xb0W\x9a\xdb\xfb\xb7Go\xdf\x1f\xbc\xb3-G[0Z \x98x\x84\xbb\xedv\xd9\xb7n\xe9\xd9\x9a\xc4\x18F\xd1w\xba\xf8\xb5\xfc\x14\x93\x19\xcb\xe7\xe2G\xb9\x06\x99\xcf_\x95<\xa5|\xa7[.\xeb~\x93M\xfc\xb4\xea\x06\x1d\x15\x00-\x95\x8b\xb4Z\xdb\xfaDq\x08\xbdRyV\x80\xacT\x9eh\x9cE\xad^\xa1\x01F\xbd-\x15y\x18\x07\xbaL\xaba\x1f\xb6\xcaE\x0c\x81\xb6\xcbE\xf3z[\x97\xf5\xb6\xae\xebm\xad`\x1f\x9eL\xcfn\x87\xc3\x8d\xb3\xdb\xe1\xd3\xb3\xdb\xe1\x8fg\xb7\xc3Wg\xb7\xc3\xc3\x8d\xb3\xdb\xd1\x9b\xb3\xdb\xbd7\x1bg\xb7O\xb7\xcfn\x9f\xeen\x9c\xdd>{s\x96\xbdy\xf3\xe6\x10\xff\x7f3\xbb\x9f\x9ee\xaf\x9f\xb2\x97\xb3\xd7?\xbey3s&\x1dV\xf2\x8a\x97\xb0\x1a\xee\xbd3\x19O\x7f/W\xbb\xff\xdd\xadT{R\x1e\xd6R\x0c\xeb\xe9\xceY\xb69\xdc|\x8a\xff?\xab\xd6\xba\xc3Z\xfd\xb3\xe9\xd9\xec\xec\x1fg\x9f\xab\x8f/\xd8\xe3\xdf\x9d\xc9\xb8s\xdf\xe9\xdcw\xa6d\xe3\xefg\x1b\xb3^\xc7\xfd\xf3\x13\xbf\\\xf3\xbc\xa89\xfd\xbdh\xcfu&\xe3\xff\x98\x0e7\x9e\x91\x8d\xc5\xec\x1f\x9b\x9f\xef\xf9\xf7\xbf\x9fm\xfc_\xcf\xcf\x9e\x9cM\xc6\xff\xf9h\xff\xacw\xf6\xe7\xfe\xf9\xd9\xa0\xf3?g?<>s\xce\\\xf6\xf6\xcc\xfd\xe1\xcfO|\xddYqc<+F\xc3\xc2\x8an\xb4\xc5\xbf+\xd4\xbc\xde\xd4\xa1\xb1\xa9gEK[\x9b-Z\xba}HK8\xbe\x87\x8e\xf5\xc4\xd8\xc3\xf6v\xd1\xd4\xb3\x91\xf2}K\xe9b\xb3\xf4c\xa7E\x87\x1a\xbd\xbaF\xc5,\xc7\xf0\x14^\xec\x0bgI\xf6mg\x0f\x13Zn\xb0\x07cx\xb6\xc7\xca0\xaa\xf8\xd6&\xdc\x0b\x9bF4a\x1c\x0d7\xd1\x9ca\x83U\xea1\xb0\x8cacd\x1d\x98F\xff]\x8c\x82Or\x02\xdd\xb3a\x97\xf7\x9c\x97\xfc\xff\xb0@\xadr\xc1JF\xa3]\xa5(\xc5J\xd5\x82Q\xbe\\\xac(\xe4EjK\xd7X4\xdcT\x8a\x16\xbc\xd6\xb6R\x14\xf3Z\xa3\xa2\xe8\xff\xcfJ\xb6\x94\xd7\x00\x0b\x8a\x97\x1ew\x1f\xc3\x18\xb6\x95i<\xc1\x11\xaa=\x9d\xb1\x92=e8\xff\xe7\x7fc\x9d\x1d\xa5\xe4\xff\xc6:\xeaL\x91*\xb0\xd2\xa7\xc3J\xe93V\xda\xedZ\x17\xe1\xc0\xb8\x08\xb8\xfe\xbb;;[;0\x01\xeet\x87y\x0b_]\x92\xf8U4\xc7\x9c\xa8c\xed\x83\x9d\x9d\xcdg\xbb\xd0\x03\x87!\x0eka\x17^\xbe\x84\x11\xe3uvv\xb76\x87\xe5G\x8f\x18\xbc\xb7\x14o\xd9\x82_\xcb\xed\xe4\x8e\x85\x9a\x043\xee9\x9b;\x8c5\xfb\xa0);\x054\x97;\x85\x17\xb0\xb9\xb3\xfb\x1cN{=\x17\x8e\xa7\xa73\xd8\x87+\xe7\xd4\x85 \x8c`\x0c\xc3>|(\nu\xc4\xe9\xbdV\xc1\xa9\\\x94Dx\xdf\xc7\xc3\x17\x0f\x16~@C\xb2\xa2\xa8,\x0b\xd7Y\x8aN\xb4Q\xe2\xa7huH\x07\x81\x1fR\xb5\x0c6D!:\xd0\x97\xe6^\x1f\xcb[\xedX8\xcf,\xc6i}\xff\x0f\xed\xfbt\x10\x85\xbf\x918\xf4\xc3%w\x8d\xce\x7f\x8a@\x85\xa8U\x12\xed\xeb\x16\x87\xad\xcbQMe\xc4\x18\xb7\x9a\xd1\x99V\xb9{]$\xa4\xab\xcb\x8e\"7\xf0>\xd0\xc15\x8d\x136\x8dG\x8f8$\xba\xf3l\x1d\xf8\x1eF\x1d\x84h\x01\xff\xc1\xba\x84\xb9\x1fS/\xf5\xaf\x91\xc7\xe2IC\xf2\xa4:\xf9\x9b\xe5\x9a@<\xc6`&@o\x89\x97\x06w\xc0d]\x99\x03\x12\xe3E\xb3A\xb0-\x85w\xe0O~w\xd8\xa17\xeb\xb9g\x03\xf9\xed\xcfO\x06\xf4\x96zN8\x1d\xce\xb8\x17\x1b\xef\xc8\x0f\x82\x8dE\x14\xaf\x98\xa4\"\x1a\x04L\xb0I\xa1>Z\xc6\x8e!\x03\xf96L\x9d\x18\xc3B\xe2^\xf1\xcb\xe5\x9b\xb2\x9c\xcf.*z\xcbB>\x13r\x11\x88\xf6%\xccD\x9f20\x1b\xe7?\xe5\xc3}\x081\x12%\x1dx\x97\xd4\xbbz\xe7\x87\xf4\xc7\x98\x92+\x0c{\xc1v\x90\xec\n\x0d\xdc7\x8b\xaf\x7f\x88^\x93l\xcd8Y:o\xe8\xb4\xb4\xba\xd5\xccb\x07?=\x0c]\xea\xb8\xb2iX\xed\xd3\x83\x9f,\x8b\x9d\xdeDE\xc2O\x06\x988\x07\x08\xf2\xc7\xb8\x0e\x17\x83\x94&\xa9\x13\xa3\xa8][\xda\x94,\x81'o\x01g\xe1\xc7I\x9a7\xe8J \x94\xc6\xc0zI\x84\xeef\x90\x92\xe5{\xb2\xc6\xcb[9\xe2\xc7\xe9%\x8d)\x9a\xbb\xc1:\xa6\xd7~\x94%\xc1\x1d\xcc\xa9\x17\x90\x98\xce!\xc9\x16\x0b\xff\x16\xa9b\xf71\xf4 \x86\x1e<\xee*\xc3x\xec\xf6\xe1\x9c\x0f92\x0fy\x1dS\xd6\x8c\x93P/\n\xe7-\xc6,\x07;\x8dg\xb6xr::\xfa\xd1b'\x89\xb7\x0cy>\xb5\xf2\xba\xa2f\x10^\xe8QA\x18\x93Ib+\xdcH\x11q\x8c\xd1\x81\xf1(\x89\xb8\x83\xad\x8fw\xbfB\xed\x06\x11\xbc\x00\x9f\xfd\xe9\xed\xc3\xc8\x15<\x83C\xb0\x8e'\x8e\xb4\x03\x06PW\xf0~/\xf6y|8\x82|\xcfh\xb4=\x1a\x8d\n`\xd3\xdb5\xf5\xd8\x9e\xb8&\x81?\x87\xbf\x9c\x1c\x1f\x15\x11\x0cuv\x8bhp\xb5\xe2\xab\x96)4\x84-E\x92\xc6\x94\xac\xd0\x16\x89\xf8a\x02a\x14n\xacc?\xe4[=o6\xd1\xb6+n=\xd8\xbc2\xd3\x9ai\x96\xecu\xb1d5\x87M\xbc\x7f\xe1\xeb\xd5\x87\xa0\xdc'B8\x1e\xf8 \x17\xfd\x9cP\xc1@\xa1\xaaY\xd1xIaE\xd6k?\\&\xcf\x11\xdb\xc4\xdd\xd6\x1c\x92(\x8b=*.9\xd8&P\xc9\x1aC\xc3\x8c\xaf\x1e\x13\x16\x1d\xc58\xf6\x8a\xdea\xa2\xb7|A3x\x01\x01\xfb\xc3\x17\x14\x9dd\xa6\xd9,\xdf{)\xda&`r!\x1e\x95 \x9c\x12\xb6\xeb\xf9\x0fU#\xae\x03\xcf;\x05\xa3\xd5t\xaa:P\x05}\xf0\xeax\xcd\xb0\x90\xb3MN\xa4\x9e2y\xc4\x11\xf8\x07\xe6\x83N\xc9r|GV\xc1 \x8a\x97\xfd\xcd\xe1ps\x8c\xf0\x13\xa6\xf3u4gm\xf3\xf4\xd2~\xc2\x99\"\xdf\x96\x958\xe0\xe0\xf4\xf0BL\xc2.\x80\x17\xe0\xb1?\x1cv\x12\x17\xfci0\xd3\x9b\xe4!\xf6\xe6\xd5\xeau\xf09\x1d\xfc\x91\xf0\xbb\x95$\x8f\x82\xcc T\xa7X\x13^\xe0p\xbe\x08\xd8\x1e\xc3\x0c_5\xd6i\x1f2\xfe\xa4`\xb0\xca|\x01\x9dK\x14\x83+z\x87!M\xd2i\x84\x17\x7f\xf9\xadM8\x8dfZ\x01(\xb5.\xfe\xa7V\xb2\x94\x102D\x8aMN\xa3\x14JR\x8c\x1c\xf32\x15?{=&Vl d\x98\x80\xa3>\xea\xe7\xa2\xa6\xb5E\xce\xcb\x15\xaf1\x1e\x9d\x83\x87\x00\x02\x16\x9d\x9e\xd8\xf6\x92\x84\x8aSx|\xd6\xc3\xe4C\ng\x8a\x13\x90\x8dY!\xf37\xd3\xd9]J\xc69\x94\x19\xfflSx.\xb2~GZchqyr\xe8D\xees\xd7\xd4Z\xaf\xa7\xb6\xa7\xdd)\xb8\xdb\xb6\xb8he\x08\xf0?\x8f,\x979mz\xd6\xbe\xfc\x19n.}\xc62\x8c\x86\x05#7\xda*\xbe\x8bb\xc3\xb8;7x\x14\xe12\xd6k t>a\xf2\x90f@\xf7!fx\xc5\xd7\xfbm8\xe7\xe6\xcd\xc3\xe7R\x90e\x0b\xa0>d\x95\x1f<\xed\xcf\xba]\xb6!8\xf4b\xba1G\\e$/\xf8c\xcel\xce\xe9\xc2\xf7|V\xec\xe3S\xe4\xfe\x91k\xb3b\xe5\x1b\xc3~\xed\x8bD\xb3r\xc8ZR\xd0q\xb6wpl\xa6\x8d,2\xe7n\xefr[\x01\x0c\xfd$\x84\x96z]\xe81\x82\xdaTe\x93\x13\xc1\x90m\xc5\xad\xbe\x80MC\xff\x9d['u\x1bd\xc8\xbfke\xc0QNjTf\x81\xeb.R\xcc\xda\xcfc\xce\x15\xcf\xe2AL\xd7\x94\xa4N\xf7\x0c\xcdd`\xa3\x94(K\xd7\xf5\x8f\xda\xae\xafE\\A\x89Q)\xd1X\xe2\xf9\xdck2\xf4.\xaby\xb3A\xa8\xa5u\x99Q2M\xae\x11\xeetQ\x08\x95\xbcM1=\xfe\x831\xb8\xf2;;,\x88\x90 \xda\x11+lk\x9b\x93\x13\xfc~\xebX_Dtp5\x97\xbe\x92\xb9\xed\x0c\xfbP\xa6\xffHbY\xf1\xc6\xc8\xad\xef\x96}\x06c\x99\xbb*\x0b\x82v\xa3\xafu\x9f{.\xf0\x0d\xc2O\xdf\xdf\x04q_\xf0<\x1e\x1d\xcc\xce\xc2\xbb\x92\xc8\xe1\x96\xc7\xd7\xa6\xf3~q\xd8#-\xc8\x8f{1\xa5\x97\"^\x8c\x00\xb0+\xce\xb1\x0b2W\x89\x00\x93Z\x08$\xf4o\x19\x0d=\n4Lcm\x94\x80|b\x15\"\x93ji\xa9$\x01\x9dL\xe0\x08\x13\x9c\xd0W'\xc7\x1dd'\xe8\xe0\xca\x0f\xd1\xaaG\x8e\xa0\xdb/6\xd3>\xe3\x0c\x9b\x18\xca_\xcd4*g1\xf95\xbev\x07T1\x9dMq\x8b\x9f&N\xf3\x11P\xd8\x0f\xe8\xdaQ6\x0c\x9b\xbfI\x03C\x84X\xc9\xafv\x18U\xde\x15\x1cP\x9b\xd3\x82\xf1@\xc8\xcfw\xcc\xdcA\xe5\x851lq.)b\xef\x12%\x01g\xb7\xd3\xe9\xb6o\x85\xbf\xd1\xedC\x99\xd11\x98<\x1b\xd9\x816\xdd\xd5^\xcc\xd9\x00\x85\x0b\xd8\xdd4\x1e\xfd\n\xe5(lF\xd8\xecc\x9d \\\xdaem\x86W\xb0\x89Y\x98K\xb04\x9cK\x9d\x80\x10Do\xfc\xf4\xd2\x0f\x81\xc05\x8d/H\xea\xaf\xd8\xcaW\x15<\xa6p \x82sS\xe6\xdb\xb9\xe5\\\\\xbe\x9al\xaf\x11\x98H \x98,\xa5\xceC\x08\x90B\x10\x06z\xeb\x05d\xc5\x11pE\xe2\xab\xa4\x9b\xa7k\xae\xc0\x82\x1dP%\xf1\xa1\x87\xc9\xed\x84bG\x95QCR\xd1\xe9T\xfaL2\xef\xb2$r\xcb\xcc\xe5U\xf4\xe1\xa4\xbd\x1d\xdc\xeb\x0b\xdd\xbc\x9ew\xb9R\xaa\xd0\x15\x18!\xb5\x08\xa2\x1bF.\xd9v\x8d\xe2\xd2\xf8\xcb\xab\xa6#\x7fx\x90u\xce\xf5\xfd1x5\xc0h\x8c\xf6\x1b\xb1\xcb\x03KH\"\x1a\xc3\xb8\xae\x06\x0b]\xa5F\xaep\ng\xa8\xe6\x1a\xb3]*N\x89\xa2\x16+\x93Ou\x8f\xeb\xf2\xb3\xac\xcf\xb5mY\x98k\xd6\x94UG\xcdZ\x88\x9a\xb5\xc7\x98\xda\xdeJ\xbc\x7f6\x13o\x0dY~\xca\xc9r\xf8\x15d\xd9\xcc\xc8\xe8Is\x08\xa2\x86J\x9e\x0d\x03(af\x15\xab\xe5\xc6\x0d\xc5\xc6\xe5\xa2f\xe7\xc4 \xd9\x0en\xd3\xa2\xf6\x84U\xb6M\xae\x03)\xf6cy\na4\xa7\xb0\xca\x92\x02\xdfH\n\x01%I\x8a\xaa{E\xcbV:\xa6\xed\xbb\xa9a\x81\x7fS\xb4a\x9as\x01\xddqQ\x1b\xb6\xea\xc3\xb2\x0fw}\xb8\xe8\xc3y\x1f\xae\xf8e\x94\xe6\xd0~o8\xcc\xff0\x1c\xe6\xcab\x07~\x92\xd2\x90\xe6\xb2\x12\xff\xe5t\xa35\x0d1\xbfx?\xc7~~}\xa3@A\x16\x08~E\xfe\xcc9\x15^\x80jO\xd8Gc\x88u\xc1\x97-\xf8W\x11q\xad\xca\x88:\xefs~\xb5\xcc\xbe\xc1\x84\x03\x01\xd3_\xa9B\xa6\x90:\xf0\xba\xae\xfa\xf0\x85P\x84\x9d\xa2\xf1\xa5\x8b\x17\x1e\xec\x85\xd3\xfa\x19*N\x14\xe4\xa0\xee\xefq3>w\xcb\xc3\x9b\x14\xa3[q~\xec\xbb\x0c\x12\xc6\xd8\xbcn\xfdV \x832\xbfg\x83\xf4\xf3\x1b\x9cS\xf6`-6\x15\x93\xfa\xce1\"w\x0et/'i\x98\n\x80\x1d+}\xb8*\x1f5\xa5{\xc4\x1cR0\x01\xde+\xca^W\x08\x9c\x87\xdc\xb1\xf4\x0b%ob\x96\xce@X\xee\x98%4\xf6YXBr\xcf-\xcf.%Nj\x9f^[\x9f\xae\xacO\x97\x86\x0d\x08\xc2\x8eF\x97\xa7\xf2\x0b\xe4\xc7\x85PY\xb7\x93\x1f3\xa3\xe7\xbf\xf4Vn\x16'\xfbB`\xe6B\x1b\xa9\xf0\xb4\xbb\\(@\x81f\xe7\xa9\xf8~\x7f\xcfhyl\xb5\x84F\xad\x13\xd2\xc1\xb0\x0f^.\x02\x1auP\xea{\x8a\x80\xd7\xe8F\x880n\x03\xb1C'c\xfb\xdcP\xb5\x81\xbfR?l\x84;\xdc\xde\"s\xe1\xd6\xd4y\x85S\xce9F\xc2X\xf8\x94&k\xe2)\xa7\x8f\xaa[\x05td@\x0e\xfa\x8a\xdemp\xd3\xea\x84\xae \xf7\xf0\xc8\xd9\xe9\x8b \xf2\xae\xa4\xd6\x9a\x1d_(l9x\xd7\xb0\xe8\xc3\xbc\x0f\x97}\xb8\xe6w\x05n\x1f\xf7\xc6\xb5\xa0\xd2\xa2\xe8N\x109\x81\xdc\xc8|\xb2\xbf\x97\xf9\xfe\xc57$\xc1\xb7\xc3\xa5e\xf2+\xa6\x04\x88\x97vF\xe9\xba\x91Q2\xe5'a\x80\x17\xe6\xa0\xce\xba\x19\x17\xf8\x9d\xd8\xb3\xad\xbe\xd0\x83sM\xac.P\xbd\x85\xf2\xb1>G\x9b\x9caX\x1beQ\xf9a\x1d\x8e6wD\x8fC\xde\xe3?\xda8\xf4|\x01[\x15\xbb}0\x80\xa1|\xf2\x0b\xfc_[\x19\xab|\xab\xb1\xbd\xda\x06\xbc\xe2\xbe\xb0.\xbe\xf2\x9b4\x8e\xbb\x97%\xdc\xbdVp\x97\xd1\xdb\x1c\x7falR\x1b\xc7\xe6\xc3d^\xf0\x1f\x9c>\x82\x17\xadV\x04.hzC\xa9P\xf8xQ\x10P.\xc0R\xeeD\xc8H\xa3\xc7\xb6\x95H~\xc9\xc5=\x1f\xef\xd99\x9a\x88\x13a\x0dm//@F*%\xf6\xeb\x8a\xd4\xcdU\x0e\xe5\xeb\x84@\xb9N\xf0\n>%Q(h\xa9\x19\xe3\xc2\x97\x05z\x02\xf9\xe5H!\\ \x8ew\x8d\xe4Xj\x9b\xdb\xe0Qe\x04\xba\xb1/\xca$\x9f\xad1\xd2\xb8\x18\xe9\xbc\x874d\xc1]\x81'\x10\xf3{\x13\xac\xc0\x17A\xa9\xc3*\x89\nI\xb5ga\x1e\xde\nI'\xe0\xcc\x1f0G\xd6-\xd6\x1f\xb5\xd8\xb3\x0fQ\x13W\x90\xb1\xaasd-\x9d\xb3\xd1\xa2\xee\x83 \xd9<\xfdn[R]\x15T\xe7f!\xd5$\xf0y\x96g\x0b\x0c\x8a\xab}\xb4\x86Z\xfe9\xf9\xd1\xe9\x01 \xa7\xa9b\x11I\xf3\"\xba\x82\x87\x7f0\xe1\x16\xb7\x08\xa4\x15\xddntP\x04I\xa6\x95\xab.\x8f\x04$.S\xacnW\x12\\b\xf0deC\xdb\xde\xb2N\xbf.h\x89\x1bU\xe22\xfc\xdcg\xe4k\x82+-\x1a\"\xc8\x7f\x8d1\x80\x17\xc7K~=\xcd\x99\x1b\xef2Z!w\xb3B\x86\x92q-\xfe\xc2\xd7[\xe1A\xb3\xd8\x83b\x80\x83\xc4\x83\xbbI\xa0\xbc\xc8\x93ne\xb9\xb3D&\x9d%6F\xbfF\xf1`\xdf\x18\x11\xbe\x8e5\x0c^\x87\x0e1\xea\x16\xac\xe65m0D?\x0ey\xaf\x86]\x9b\xf9\xfe-\x89Y\xc6!X\xc7\x07_3FP\xc7\xd9\xb9q\x88r\xcf\xad\x19\x90aC*\x1b\xce0P\xc5\x1a\xa8j\xe4\xd37\x8d\xbe\x9d\xf2\xc4\xe9x5Y\xe9\x05;\xe4\x1e=\x92\xd6CDc=\xd4\x06b\xe6%\xebxP5{x \x0bdC\x169{\xc1\x1f\xb8}\xb8A\xd4[\xf7z_\xbc\xd9\xeb\xb3\xb3\xe3C\x82\xf3\xbe\xae\x98\xd3TLf\x02\xf4A\xe9\xc1\x1a\xc6\x8c\xb5\x1e\x8b\xb70\xc4\x88\xcc\xf1\xa8\xd8\xe2\x9c\x85M)\x0f\xecA\xed\xcd\xaa\x0fa\x11=\x01\xb6Q\x18\xc7\xb0\xca\xd9\xb8\x96\x83\xe7Zo\xf9\xe6\xc8\xfa\xe6Z\xf0\x8ccA\xed\xd60\xd1M\x17\x90\xee\xd8\xdaix^\x1e!\xb7\x16\xee\x0c%\xe9\xea\x8b\x83\xbbj\xfe\x05\xd5M\xf8\xdc\xfd\n\\e\x9f\x8fB_\xaaj`;\xa3\xb6\xa4\xd3(@W\x8ek\xc9A=P\xbc\xd53'[\xcf\xbe\xfez\x12\xdar\x0bUi!\xc6\xec\xbd\xfb\x9a\x0b\xc76\xe3\xb1\xb0\x1c[\xdc\xa0\xdf\x9a\xf2\x82\xd5\xfb(8\xf6\xd2\x821\xee\xbe\x01,e\x9e\xa5\x00\x8cE\x17\x18\x97\xe6Y\x85D\x19\n\x863\x0e\xa9\xd7\x8d\x83\xb7\xe6\xf9\xd0#1b4\xf6\xe3\xb2\xc3H\x88_u\xf0\xf2}\x94Kt\xfb\xfb\xfb%\xc3\xdfG\x8f\xb8\xf1\xe4\xc4\xca\xefK\x1f\x9f\x82\xe3O\xfcp\x19P\xf8[\x16\xb1\xaab\xedEBJ\xf3,5\x1b\xe9!b\x86\xbe\xd3o\xb1ST\x01\xc3\xb0k\xb69z\xb4P\xd3}\xfb]\x13\xa29\x85v\xd7\xb4\x18\x8fU3\"|W\xb3|\xd0Z\x8a6t\xabC2!>\xaa\xb16e\x9b-\xf6\xa2\xae\xab\x9bvW4\xae\x8a\xfd\xe6}\x98\xeb53\xee/\xca\x90\xfex\x9a\xcd\xdc\xd2\x01\xf3\x01}G\xd4I\xb6h\x11%\x9c\xd1\xa60\x83\xc3`\x93l/m\xa2+\xf1^.\xcal\xc3\x18\x9e\xee\xe4?\x99\xd80t\xe1%\xfb\xaf\xc5]Y\xc4/\xb4}n\xb4\x1d\xb1\xf7\x9eC\xb4\xb1\xe1b\xef\xaf\xda\xc2\x8a )0\xc1f\x1c\x1f^\xbc\x80m\x17z@r\x91*\xdf\x81\x97\xf4\x96\xcc\xa9\xe7\xafH`wiR?*(\x0f\x1c\xbf\x82/f\xbe\x85\xc3RR\x81\xab0\xba \x81&\x1eY\xd3\xdc\xd8\xd3\xd6u}g\xd8)iVPR\xbe\xf5M\x94\xb4\xde\xf0w\xa2\xa4\xf3(\xbbhCI+\x83i\xc1K<\x84\xb4\xeaG\xa1%\xad\x8a\x1aG\xc95o\x0e\xbd\xc6!\xad\xa7\xaa\xdb\\\x87\xd1|\xf1\xdd\x86\xaa\x1a\x1aie\xee\xc4M\xe0n\x85\xf5[\xe7\xc4\x89\x19\xd9l\xd3b}0\x0f2y\n|\x92<\xc8\xe2Ic\xfc\xd8/\x9b:)*\xf5J8\x16\xd5\x10\xf2q\x16\xe6j\x80\xb9\x18G\xc5(N9\x93T5}8\xab\xde]\xd5\xd9U\x86&_j\x8a\x82ZWO\xea[\xd9IiV\xce\x99/\xba\x19z\xdd:^3b1\x88\x9c8\x1ew\xfb\xe4D\x1a\x85\xde\xad\xa7\xc5\xf7\xedM\xa5|\xab\xf8.\x15}\xf8cW\xad\xf4L\xf9\xae\xd4\xd9\xdaS\xea+\xe5\xcfx\xa8\x07\xcf\x8a\xe5x\xe2\xec*\xdd\x0b\xb5\x99\xc7u\xf4\xb7\xcd\xdbHHg\xf7\xf7\xdc\xbe\x8f\xa1y\x8b\x8d\xd5\xcc\xaeD\xe8K^fw\x85\xd5\xba\xd8`\x9e\x95\x0b\x11\xd6\x19\xd6Dp|A\xbfh\x8a\x16\xe1YI\xaf\xb8\xb5\xd3v\x10\xf6\x01\xa0\xafL\x8b>\x9b\xb4\x12\x8dGM1G\xafY\xfb\xc8\xda\xbc\xc1\x8a\xcdV\x10Y\xaef\x91\xd74\x8a\xf1Y\x90\x17p\x95\x89rrn\x8cjw\xd4\xfb\xf6\x04o\xf2C\x14\xf9\xfd\x8b\xb5U\xe2#S:X+\xda\x839\xab\xc0\xe7\xfe\x1f\xdcx\x80\xd1'u%\xc4\xfduI\xe7\x16|{=\x8e\xbe\x14/\xc08/\xc3\xe9gg$y\x191\xde\x0d\xc8\\\xdb\xe6t\xfbp((\x9fS\xae!\x0c\xcd\x0c\xcb\xd1\xe0\xf2`:\x11\xabC\xedtr2\xc2]\x82\x05\x99Y\x94\xe8\xcb\xba\xaeQ\xe1\xacH_ZQr\xf2\xf7\x87@\xa1\xdc\xd1:\xf7f\xc9\x8d\x0d\xba\x93.\xea\xa6,u\x95\x12q\xb3[\xd8\x81\x15gur\x19e\xc1\x1cmu.\xc95\x05\x12\xdeI\xcbk\xbc\x84\x95\xfe\xde\xad\xaf\xbb\xf3{\xc5Buv\x9a\xcf\n\x8d<\x85\x8dg\xa5i1\xean\xa7[\x14\xe8\x9d\xcd\xba\x93n1S\xab&y\xc9ugw|\xed\x85\x11\xd2\xe9\xdd:OZ\xf7\x1c\x96\xf0\x02\xee\xd8\x1f\xf4\x1f\xb7\xd2\x1c\xe7\xa2\xde\xcet9s\x072\xe0\xbb2u;\x9dPp\xe2b\x90'lW]\xd3\xe4:_\xf0\x1b\xe6/\\\x82o\xbb\x7f\x05\xb1/\xb1t\xe7\xb6`T\x0b\x86N\x19\x13\xbfw\x16\xc7\xdb\x91\xf0\xf0;\x9a\x863\xa9cc\xf4\xf4\x0f\xa1q\xe0\xf44W\x82\x15hZ\xd2<\xfc\xc9\xdcy\x99\x1e\x0c\x15\xd1H\xec\xf7\xc2=\xdfN(\xdaV\xe4\xf1\x1c\xdaW\xdet\xcb\x11]D\x84\x07u\xdc\x0c D\xb3W\x13T\xd0\xadH\\\x8b\xdb\xf2[\xc1\xd3\x8bi\xa2\x9d\xc6Z1N+\x03\xa6N\xa4\x1f=\x82%w\xf0,\xaf\xbd_^{\xc8Cq\x84Q\xb8qp\xf2\xea\xed[%\x9eL\x02$\xa6\xe0\x87)\x8d\xd71E\xc7\x87\x04\xc5\xad<\xe8\x9c\\\xda\xa4\x166\xa0\x85<;\x81\xed\xddf \xbb\x82\x15h\x80\xb0RA\xf1\xa4\xdeP\xa9d]\x1f\x1a\xc5\xa8\x0b\x15\xe8Yxp\x94\xd6\xc3z\x18\xff\xd5\xd1Fa,bAQqv\xa0\xcc\xc3\xce\xc8\xa1\xe4\x17\xf2\xb8v2d\x0c-\x03\xa0\x98\x02\x82@\xc4\x92\xb1Wrhn^\xd0\x87\xdd\x9d\xcd=\x11+U}i(k\xb2r\x8e\x15#\xb7J\xfb\xaeE\xde\xe9\x90\xde4\xdf\xaca\xe6 \\B\xc0DL\xf8[F\xcfds/~\x08\x96G\xd4Id\\\xf6T~\xbd\xbfg27>,\x02Y\xb2\xe7\xc5\xafr\x13\x9c\x13\xc1*\xe2\xeb\xfd=W\xeb\xb3\xa7\x18\xa0\x8a=\x93\x91\xaa\xf2'9\xbb\x86o\xca\x1f\xe5\xb6KB\x8cL\xc2\xcd\x07\x8a\x81\xc0\xfd\x80\xce\xdf\x8a:2\x97 \xe7\xdf\x0d\x95O\xf9\xd3|\xe8\xb8v\x052\x88rE\x171\xccG\x8b\xea\x08\xf5\xa7\xd4H\xa8e\xaa!\x10O\xf7,\xf7'\xf2\x17eB\xcb\x97S\xc3\x04\x86b-\x11\x93\x86\xdd\xaev\xe5\x97s\x93t\xf2\xdc$EZ\x12_3#%$V\x11\x82-\x86\x17\x10\xb1?<\x04[\xea\xf8\xd3xf\xa7-?i7\x9c\xdc\x99\x7f\xd5\xad\x1f\x1b\xb1p\xe8\x96\xd9P4\xfb\x95\xd5\x1a\x89%\x95\xb5$X\xa7C\x8dOA\x91\xc9!r\x8a\x8b\xc3\xfc\x86>\xa7\xa0~\xa8P\xd7>\\d),\xa2\x8c\x9drQL\x1f\x94\xc9\xa1He\xf0K\xbf\x9e\xfa\xe0\xa7\xbe1kA\xd3-D\x8b5E\x94\x89\x07\xf46\xa5\xe1\xdc\xa9\x83\x8fo\xea1\x90\xf2|Xg\x95\xe5\x90\xc8\xf7\x85\x8d\xfdI\xf9\xa9M\xe3`\xa5\xccb6?}\xe9l\xea\xf1\x81\xbf>c\x81.\x98h\xe4\x94B/V\xa7\x81tL\x1c$\xf2l\xb9\xc8\x16\x0bN\xba\xeb$3,\x93\xccX\xfc\xf4\xa2 [\x85\xa5@\xa7\x05\xde))\xd8\x07K\x9a\x9e\x84\xfezM\xd3&\x00\xd7\xcc\xd5\xeb{\xb1\xa3\x0c\xd7U\x95\x06:\xd9\x1bD\x00\xf8m\x85c\xd8\xdb\x11\x11p\xc4\xadKi\xb6\xc2:\x80\x1d\xe7\x1b|?w\xcf\x86g\xf1Y\xf8\x7f\xfe\xb7\x9aU\xa0;\xf0\xc39\xbd=^8\xcah\x90\x8a\x1f\xa4N\xc4\xef/\x0c!\xab\"\xd8@2^\x06\xf2\x06\xf6\x9b\xc2\x13\xd8\xe4\x9c\x87^X\xc3q\xc3`0\x00\x1c|o\x1fv\xf4RJ\x1bw3\x04\x91/ A\xea\x90 \xf0B\xc5\x0d\x85\xbd\xfab\xd0\x10#X\x1c\"\xc8\xf8F\x052-\xa0\xe2\xabP!\x0c\xbe_\x01\x15\x81Q\x99\x84\x87\x98\x00\xe7\xea\"\xee\x8aX\x98R\x02\xaa\xa1\x84\xe4\x95\xa1\x01x\x8f\x07\xcc\xefUkAO\xb3\xe6=\xe5\xbc\xe8A\xf7\xf7\xaeJ\xa0\xd4=\x94F\x9c\xfb\xb5\xe6\xe6UB\xf6u\xbb\xda3\xbe\xd8\xfa\x8caE\x0e\xe2\xb1\x1fr\xe1\xb1x\x86\xd1\x92\x1f\xe3U9\xe3XH\xca%\x186)\xa7\xa0\x04(\xd7\xf5\xd8\xdc\x04%(\x9e\x8b\x02~\x05\x82;\x10\x85r|VP\x03G\xa8\xa8x/c\x0e5\xd4]j\xc9tNi\xbe\x92h\x8ev\x953Em\x9d\x9d\xc6\xb1\xa3 \x87\x93\xa4q\xb7_\x81\xf5\x95\x1f\xce\xc7\xc5}n\xe9Y\xae\x90\x1d7\x98w\xd4t\x9e\x98D\xa2\x94\x8b\x00\xca\x07\xbb\xfb/\x82\x00\xfd\x9b\x11\x02\xb9c\xde\xb7\x85A\x95\xb9\xfe\x97\xc3`E\xd6&\x18\xe4\x8e\xb6\xdf\x16\x04\x15\xd7\xd0\x7f=\x08\xd8\x08\x1f\xb4\x13\xc4\xedA\x13\x00|\x19\xbe\x07Ek\xabm\xf0u\x9e\x8cR\xc8\x01&h\xca\x98\x9d\x8f\x1eA\xf7\x7f\xc4\xcd\x1d\xf2\x02E\xb9\xd3\xc5 \x15\xcf\xbaG\xd5\xdf\x9f\xde\xbd\x13\xbf+\xbcv\xf3R7\xac\xb4\xad\xb9uL1\x10Y#\xe0T\xcc\xc1Q\xdaZ\x8d\xe9:\xa6 \x0d\xd3\xb1\xa6%\x8f\x84Q\xe8{$h\x98\x01\x14\xbdv\xffG\x93J\xb3~5\x12D74\xf6HB\x1f\xd02\xaeK\x9b\xc6\xb3\xf5\xfa\xc1\x8d\xe3\xa2\xb6i\xdc#+\x1a<\xb4q\xfd\xc8m\xeb2\xa7\x0b\x92\x05\xe9Iz\x17\xd01tsxu\xff\xe5\xfb\xfd\"\x8a\xfe\xa9\xfb]c?\xd5z\xbf\x97\xf6u\x1agT\xdd\xc7\xa7\xd5\xdf\x1f?\x1d\xca}\xcd\nv\xd4\x97\x17$HJ\xb5\xdf\xd4\n\x0e\xde\x9d\x1c~)]\xb0m\xe4\x87\x0c\xfc[\x12\x90\xeeT\xa4\x13\xf81\x8a\x02J\xc2\x19\xef\xa3\x96\x9cN\xb2\xa12\x03\xed\x17\x93\x1b\x1dQ0&\xc8\x95\xf6\xa00\x91\x00\x1a\x83X\xa56\xdbXG#Z\xf5\xc5\x81=\x96\xeb\xdd\xa6/\x1d\xc9h\xd7\x97\x9c\xd7\x1b\xc3\xbc\xfe\x1d(\x88)C\xe2\xee\x03\x93\x9c\xd6\xb2\xa7\xed\x14\x03\xd54D\xda7\xb4\xa74$\xbfUI]\xa4#u~\x98\xfe;P:\xae\xb4Q5\xd8Z\xcc\x89\xccn\xf5\xba\xa8\xde \x95'q\xa3ylw\x83\x1bB\xf1[\xd4i4C\x19\xad\xdb\x13y\xdesY\x8eN{\xbdh\xe6\xf6\xa1;\x14\x99\xfe\x8d\xe29j=z\x82!\x8b\x1b=\xbfp\x14\x17\xbcQ\xb5+S\xfb\x90\xbby\xf4z\xa4\x9fb\xe6\xb7\x959\x8ev\xddA\x1a}b\x02\xe9+\x92PG@\xa2\xb1\x9a\x0526\x1c\xab\xc8\x85b*\x15I&aO\x0f\x02\x9f$4\xb1\xe1\xe2t\xb3\x0f\xdd\x0b?\xecjR \xe4\x98>\xedC7\xf2R]\x95\x1c\x8e\xd3\xd1\x10\x13Uy\xbaZ%\x88OG\xbb}\xe8^\xd2\xdb\xee\xf7\xbd\x0b0\x8b\xb5\xe5b_\x08\x90\x1f\xe9\xf2\xf0v\xedt\x7fw&\xe3\xe9Fo6q&\xe3\xe1\xfdt\xb4\xf1l\xc6\x8e\xd8\xf3\xd9\x0f\xae3\x19\x9f\x9d\x0d\xe4/VaJ\x0fgXY\xa4\xc4\x9d\xdc\xe7\x15z\xda\xc7\xc5/\xd1\x8c3\x19\x97\x0f\xf2\xa2\x07^\xf9\xecl\xe0L\xc6~\xb8\xb8\x7f\xcb\xfe\x1d\xbdq\xefyQH\xc2\xfb#rt\x7ftp\xe4\xba\x7fV-\xef1.?&\xedU:\xa7O\xcczB\xad\xf0\xbc\x08\"\xf2]\xc4gU\xbf\xcdoF\x18\xa5u:\xbe\xe0`\\\x95\xf9\xa1S\xd5zo\xf6\xcdy\x1am@\x189B\xd8\x07\xc9G\x08\x03\xe4\x1a;2H\xa3w\xd1\x8d\xdc\xd2\x8c\x97\x80 ;\xc8\xc7 b\x00Og}\xe8\xf66\x94+tdX^\x8a\x13\x86\xdf\xa1\x16\xccH\x1fX\xcdE\xc1{\x08\x0b$\x98\x88\xc3l\xf0\xe1\xf8\xe4\xed\xe9\xdb_\x0f\xcf\xdf\x1e\xbdy{\xf4\xf6\xf4\xaf0\x96\x8f\x8e\x0e\x7f:\xa8>\xea\x0eB\x12\x16\xcd\x1d\x91#\x18CZf1\x04is\xd2/\xe33\xa22\x9f\xf1\x86!\x8e\x95\xd3\x10\xb6w1\xe74\xa2\x07t\x95JN#f\xaf\x9b9\x8d\x10~`|\xf3\x18\xbf(\xa3J\xff\x9dx\x0d\x873\x1b\x9d}\xee\x8d\xa1\xe15\xda2\x1b%Bi\xc2\xf8P\xaf\x1c\xf2\x93#r\xc4\xfa\x82\xe4\xc6O\xbdKp\x8c\xca\x03\x8f$T\xd5D\x8e\xb5\xb5@\x01\x0e\"\x9f^<\xe2\x8d\xe5z\xdc6\x8d\x1d\x1d\x1cY\x1b\xcb\x15\xb5\xad\x1a#G\x1a\x8dl\xe1\xf8l\xdcnB\xeb\xf7=\xa0\xc5v\xfe7\x83\xd6\xdb\xa37\xdf\x0eZo\xc3E\x1bh\xd5)\xd0\xf7\x83\xd6\xc67\x05\xd7\xc67\x85\xd7F#\xc0t\xbb\xbdx}8\x18j\xc6\xa2\x9cKe\xbe\xb7\x0f$\xcf\xe95\x810?\xa6\xba\xb4\xcb\x0e\x14\x1e\x083\xb4\x11\x93\x7f\xd6mC\x8d\xff\x8aj\xfcW\xce\x1e)\xff\xb9\x1b\x8e\xe9\xc7\x9f\xbb\x8d\x1c]c\x8b\x93\xca/\xc6\xbb\x9d\xa6\xb3\xfb)\x9c\x9d\xa5\xb3\x9e[z8V{/\xfd\xe0\x0c\"/\xf9\xc1\xe5\x1c\"\xb6\xf0\x83\xf3\xdf\xf7\x0ec\xc6\xdcj7\xa5\xf7\xdd\x89\xebNJ\xac\\\xab\x1b\xdd\xd4_\xd1$%+\xa3)\xcb7\xe7\xd6\x8a\xb0\xe5\xd1\x80\xdeRO0my\xa9/K\xbf\x03\xbf\xa6\x89\x87b\xb85Y\x0b\xf7L\xfd\xb9\x97\xdf\xe0 \x0b\x96\xcf\xc3\xcd\xb9\xb2b\x12j\x9erW1\xf3>\x8c\xe3(v\xba\xafIJs\x9fZ\xca\xcat\xc1\x99|\x91W\xb4\x97NG3\xce\xfc\xf4\xd2\xe9\xe6\x8c{-\x11\xfesk\xd6\x87N:\xdd\x9e\x15f\xb0\xf4\x06X\x07\x0e\xfbo\xf0\xe9\xf4\x95#\xc0\xa0\xf3\xc3\xf3E\x98\x8a\x1ek\x82G\xa9\xe8\xa5\xd3\x9d\x19\x8fO\xd1K\xa7\xbb\xb3>\xa4\xd3\xbd\x99\x89\n\xa3\xca\x15\x03\xdfN\xf7f\x82+\x1d\xf6a\xcb}\x0e\x8b\xc2\xa7r\xeb\xb9\x0b\x0b4\xf0\xd3Q)l\x87u\xb7\xa8\xd3?\x13z\xa5\xd3g3\x04<[\xb3]\xba\x0d?\x80\xb3;\x84\x1f\x10Z\xc3\x19\xf4\xa0\xe7\xa4\xd3\xd1h\xc6\xd0l(\x95\x80\xb8 \xea\x9b\x1bkW\xc4g0\x82M\xc1\x9e\x85\x8bQ\xd5\x1f=\x02o\x90\xd0\xf4\xd4_Q\xc7\x1b,\xc57\x1760\x88\xa6gCa?LR\x12z\xf4x1\xc6\xeeZph\x96M\xc6\x88\xfa\xdb\x93cA\xd7\x8d\x8e\x00\xdf\x8a\x10?\x90\xcc\xf0\x04\xfc\xdf\x8f\xc4t_\xbcP\xac\"L\xe6O\xdf\x0e\x0c\xc5\xcf4\xbe\xab\x0c\x8b\xc3hg\xdb\x1d\xfc\x88\xb6\xc2E\xaf\xe0\x11dd\xd8L>\x97\x1a\xb4(\x18\xba\x07?\xbez}\xf8\xe6\xa7\x9f\xdf\xfe\xe5\x97w\xef\x8f\x8e?\xfc\xd7\xc7\x93\xd3O\xbf\xfe\xf6\xbf\xfe\xfa\xdf\xe4\xc2\x9b\xd3\xc5\xf2\xd2\xff\xe3*X\x85\xd1\xfaoq\x92f\xd77\xb7w\x7f\x1f\x8e6\xb7\xb6wv\xf7\x9e>\xeb=\xd9?\x0b\xcf\xe2\xee\x03%x\xae\xe4\xf9\x1e+\xf6\xc57\xe0\x06J\x1d5^\x8e3\xfa\xe8\x1b\xae\x88B\x1e\x030\xe4\xbeC\xa1\xed\x9e\xa8\xe3 i'\xb9\xfcK\xa5\x19;\x8f\x06\x08\xbb\xdb\x8d7G)\xbc\x80a\xab\xdb\x1f\xd4\x8b\xefj\x1f\x1b)a\x0c\xff\x01OQ\x01]\xc6\xfb\xaf>:\xa3\xb2\x02cz\x16\x9f\x85\xfb3\xa1\xc60\x03=\xb2.K\x86\x91\x80\xb4\x8f\x12\xf3r\x07\x86;\xa1\xdc\xd3{\xf8\x1c\x18\x94\xc9sH{=\x17R\xf8\x0f4\x05\xe3*\x13~\xa5\x13\x88L\x11\xf0\xf2%\x8cv\xe1\x11l\xee\xec\xb8}P\x8b\x9fVK7wv\xe0\x11$\x8c\xec'\x98\x0e\xe4\xc5\x0b\xd8\x85{\xc8rt\x88$:\xa4\xba\xe3U,\xd1\x10dH\\\x82\x03\xfb\x01v\xf1\x9a\xe6\xab\x86\x04c\x18=\xcdu=\xe5\xb6\x86\xda\xb66E)\xbe*|\x0f\x19h\xd4:\xdb\xf9\x9b1\xa6\xdfX\xc4\xd1*\xff\xe2\x04(\x16 \xbd\xc7\xaf\xdf\xd4~\x15C|0)\x87S\xd0\xf67'm\x11:\xe6n.F\x82b@>\xd2Hk2\x0b\xad1`\xe7V\x05;q\xe7g\xd3\x08\x97\x8f-\xfa\xee\x16\xf2|J\xe9\xa6\xaet\xb7R\xb8\xbb\x05\x8f\x00Mr\xd8\x8c\x9c\x88a\xecS\x17z@\xa7\xa9\xf9R\xb5\x8c\xa0[\xfc\x0e\xf1\x1b\x8f\x08\xc6\xb0Y\xa0k\xa9\x9d\xa1\xae\x9d\xedZ\xe1\x8b\x17P\xedqw\x1b\x1b\x1e\x15\xc8\\j\xb9>\xc0\x17/j\x0d\xefn\x97\xdb\xebC\\F\xbc\xfc\xd7Ws\x10f\x89\xb6\xa6\xff+\x87\x9c\xacs\x08F\x85\xe1\x03\x99\xb4\xc8\xe2\xd1`\xf0\xea\xf8\xca3\xdfd\xcf_\x91\xd7\xb8*\xdcx\x1cP\xdb~\xe3\x97\xd2A\xee%\xccv_\xf8\x9c+\x83\xcd\x1ed\"uh0MgE>\xb0\\]\xcb\x01>\xeb\ny\x15\xd5\xb2q\xb3Q\x87\x88\x89\xe3\x87\x10\xdb\xadx\"\xd1$Jj\x16\x8eB\xd6\xcf\x1a\xbb\x96\x9f/\xb2\xd6A\xe6\xa7\xb9\x0fVM\x98!$\xf9\xa1H\x9a\xc1\"\"[\xb4\xca\xdf\x91#Ny[~!\x83S\xd7O\xfc\xb3\\\x8dZ\xec\xfa/\xdc\xc4k\xe2\xc7\xc9\xbf\xd7.\x16\xbe\xbb\x96\x9dJ\xc4\x8c\x0e\xe2\x98\xdc9\x99t\x81\xcco{\xd8\x16\xce\xbel\x0bg\xb8\x85\xf5[7j\xbdu}\xf4\xe7G\xc3!\x85\xe2^\xd1\xbb\x84\xbd]u\xf17\xb5B\xa6\xe9\x8c\xd12\x7f:d\xe7\x0c\xfe\x9d\xcd\xfe\xe9hoXG\x1dW}]\x0d{&R\xd1\x18\xd6\xd1/\xad#\xd1\xae#1\xad#[-\x82\xab\x15\xd5@\xdc\x07_\xc0.\x12\xb0\x8b\x10vF6\xc6\xff7\xd8\xc1\xe5s\xfb\x81\xfb8\xa1\xc6\x0bt\xbdw\xe1\xf7\xdb\xc4\xd6#\xd6\x0f\xc1\x10\x08L9\xc9\xc2\xbe\xb0D\xccIm8Mg\xd6\xfd\xf2mQ\xdeD\xe9\xff\xed<*\xffH\x9ed\xe1\x9c.\xfc\x90\xce\xbfR\xfbb\x81\xc3\xc3\xa1\xea\xd6\xf2\xcd?T\xa6\xbb\x8e\xfc\xb9\x8c/f\xeb]'\xcd\xd94\x7f\xffn\xae\xd1\x7f$Ob\xba\xa4\xb7\xdf\xe5F\xe5\x01\xca3\x1f\x03\xd5`\xbd6\xe7S\xeeW\xa7\xe7\xb3\x19\x11xr\xf6\xc4\x99.\xfd\xd5\xec\x07\xf7\xcfO\xe4\x05\x87\xbez\xac 9\x00\xd2z\xfa\x89\xd4\xbe\x0f\x8dw \xfc\xc2C\x9a\xf2\x86\xd3\x11\xcab\xf2\x16\xe1%\x93K[\x9c\xd8\xac'4\xeb\x9d\xa6\x85!P\\\xb2 *\x9a\xa9\xb5\xf2\xbd\x8f\xe1\x7f\x0e\xc4\xe56Q\x80\xceo\xe1\xaa\xd0-\x19\x13\xf5\xc1\x001\xbc\xd0*.H\xd3~U\x96\xf9J*\x913j\xbc\x83\xb6&1\x0f%(\xd6\x05a\xb0\xea\x01\x1d$Q\x16{\x14z\xac\xc0\x08X:X\x06\xd1\x05 \xc4\xd5_o\x1f\xbaK\x1e\xb9\xaf\xc8D_\x11\xf5\x9fV\xca3\x9b\xd2\xaf\\5i\xd6.\x94_\x08`\x1f\x9eU\xc8 \xec\xc3\xa8r\xad\xb5\x80}\xd8\xda\xac`\x03+\xdb*\x97\xcdY\xd9v\xb9\xec\x92\x95\xed\x94\xcb\xaeY\xd9^\xb9l\xc5\xca\x9e\x96\xcb\x96\xac\xac2\xbe;\xd8\x87\xed\xcaX.XY\xa5\xdfsVV\xe9\xf7\x06\xf6a\xa7\xd2\xc7!\xec\xc3n\xa5\xbd[VV\x99\xdb +\xab\xf4\xf1\x8a\x81\xaf\xe2\x93x\xc5\xca*\xef\x1e\xb0\xb2\xddr\xd91\xe6/\xacT\xfc\x80\x85\x95^N\xb1\xb02\x95\xf7\xb0\xafA\xfa\xe1\x18\xbaggC\xcdQ\xb4\x87O\x88\xe6\xc9S|r\xa1y\xf2\x0c\x9f\xa4\x9a'#\xdeQ\xa8{4\xc2G\xd7\xbaG\x9b\xf8h\xa1{\xb4\x85\x8f\xaa\x0c\x1d\xfbl\xf2\xa1Wu\xd1\xec\xb3\xb5=\x86\xc7gg\xdd\xc7\x9a\xb1\xf3\xbe\xce\xce\xb4\x9d\xf1\xde\x8et\xcfv\xf9\xd4\xceu\x90\xda\xdc\xe2\xad\xbe\xd3?\xe4\xad~\xa8(\x1a\xcaU\xdf\xb2\xf3\xba{\xd7\xedC\xf7\xaf\xec\xbf;\x9a\xe0w\xf1\xe7\xf0\x84\xfdA\xb6\xb7{\xcc\xff?b\xff\xe3W\xfe-\xc2\xaf\xfc\xffc\xac\xbdX`E\xf1\xe7\xcd\x9b\xeeL\x17U\xe3\x8f:\x9d,\xb4\xb6\x95\xabhn\x82\xb2ou-\xeb\xf3\xc8\x19\x9b;;.\xe7\x85n\xbb<\x80\xeff\xb9\xad\xdc\x1a\x19\xab\xef\xee\xecl\xc9\x172\xf1\xc2\xb6\xe6\x05=\xd7\xde\xe1\x8dlo>\xdb~\xb6\xbb\xb7\xf9l\xc7u\xcb\x11q\xbdhNa\x1d\xf9\xa5\x8c\xb9<\x00\xe2\x8a\xdc\xc9L\x0c\xcb\x98\x92\x94\xc6<\x19\xc3\xf0\xf6\x8d\xf8\xe8X\x07\x1c\xe8'1\xd0\xa7\xe5\x95-\xfd\x92\x87\xde\xd9YW\x84u,\xe28\x0e\xf1\xfd\x8d\\Vv\xa1\xa7\x08p\xba\xc8%G\xf5\xc5R\xa2X\xf3x\xe1y\x98n_\x06\xc9\x961\xa7\xdf\x93\xf4r\xb0\"\xb7\x0e\xa6\x0c\x17\xc5\xf7\xf7\xb0\xe9\xcah\xdfW\xfe\xfamxM\x02\x7f\xce\xdbR~\xab\xa1\xb9\x17At\xf3\x8e^\xd3\x00\x99X?9\x8a\x18L\x97\x0e-\x9e\xb8\xd2\x17I)\x93\xbd\xa4w\x81\x08\xc1]:YMLu=%p\x93Ym\xe1\xdb\xff\x8f\xcf\x06\xcds(\x12\xa2pk\x0d\x9e\x845\xae\xdc\x1b\xa4\xf9\xd5\x0c\x8f\x04\xe0?\xe7ARG\x90\x89\x86X?\xac=\x91\xe4!\x18\xa8>\x97}\xc8xg\x19^\\\xab\x8f\xa6\x19\x1b_8%3\xd8\xaf\x06\xc3\x05E\xcd]\xc6gGA1\x868\xd8b\"\x0d%s\xdc\x89\xe2\xf4\x17z\xc7\xb3\xcf\xe4?\xca\x01\xddC\xfa\x9b?\x97\x01\xd5\xf3_\xf7\xf7\xf0T\x86C\x0f\xa3\x8ft\xc1\xdb\x10_\xd5\x16\xc2\xe8U\xb4Z\x93\xf4=\xdb\xce\xbc\x8eR\xa0\xd6\xf4\"\x86\xdd\xe8zu#@\xa9\x14\xa85\xbf \x84\xbcLOd{\xe5\xf0\xb6\x1cu\x1e\xd3`\x85E\xe4\xfaR\xb6F,\x99g\xec\x0d\x92Ra\xaf\xc0K\xb3\x84\xce_\xabOJ\xb1\xfet4\xe2\xa3v3!\xd2\x8b\xdd\x14\xc1~%\x9al\xea\x8at\xc6\xfc~nc\xc4\xf1\x9a\x8d-Q\x83\xa5\x81\x0f/ y\xeeb\xda\x064`\x97\xd9\xfa\x85K\x1f;\xfb\xc1w\xd1\xec\x87\xfb\x8a\x88\xac\x16\xa2\x83\x04\xb3\xbd\x95\x9e\xb0.ydW\x1f\xad\x86\xf8\xf7P\xd5C\x9c Q0\x14x\xdd\xdb\x87\xc8eC\xec\xedW]\xcb\x04\ngV\x10\xbd\xb6\x85\xe3\xd6\x87\xdb\x95\xe4\xf2\x07H]k\xdb\xef\xea$Z\xca\x1c\x08\xb1\x05\xc3>\xfe\xd5\xbe\x8e\x9f\x8c\x0dmm\x96\xa3T\x8d6wQ~\xdf\x1dU\xc3`m>\xdba\xbf\x18\x87RxP0\x96D\xfc\xba\xbf\x87\x9d\xbd\xad\xed\xed\xf2{\xec0\xdeb\xbfx~\x8a\xbc*+\xdf\xadt=\x1am\x8fF#\xebD\xfef\x9c\x08N\xb1\xd2\x0f\xb6\xcc\xbe^\x14__\x15_\xaf\x8a\xaf\xc7\xc5\xd7\xd3\xe2\xebM\xf1\xf5\xd2:\xac7\xc6a=\xf9\xfd,\xfc\x01dT\x13u\xb9\xe57\xb6\x91\xfe^\x0f<\xf2#cs\xcaE\xbf2Y\xa5\\\xf43\xe3m\xcaE\xbf\x01\x06\x99\xae\x0f\xf2/\xf6\xd0\xebl\x1c\xbej\xe7\xd4\xd1\x84B \x0c\xe5\x0b\xdc\xe9<\xeeG\xfd\xe9{N\x07j\xe5\x8cS\xfd$\x12\x92\x96r\x96TV\x12\x83\xf3t\xde9\xfc0\xca\xb0\xec\xbc\xf8z[|\xbd)\xbe^\x14__\x15_\xaf\x8a\xaf\xc7\xc5\xd7\xd3\xe2\xebe\xf1uU|\xbd+\xbe\xae\x8b\xaf\x1f\x8a\xaf\x87\xc5\xd7e\xf1u^|\xbd.\xbe\x9e\x14_\x0f\xc4\xcc\xcc\x89^49\x1f\xd2\xbaJ(7y\x18r\xba\xaaP\xd9^\xcfv\xb3\xd5\xf9$\xc8\xae\xd2\xbf\xafD\x05\xfaM\xaf\x04f+\xf7\x96\x8d\xfdoZc)\x13\x83\xfd\xc5\xc3\xd4\x0e\x12 \x9f\xe7rd\x1d\xf6a\x01hQ\xcdX\x15\xe4Ya\x03\xde\xe3\xe9\xf2\x92[\xf1vA$\xd2\x9c\xbeg'\xc3\xac\x8f\x88\xe9\x1b\xf4\xdc\xb9P\xc1@\xf4\xb5\x00\xd1n$\x1c%\x0e\xbaq\xa8\x7f2\xb7&\xc6\x85\xdcM\x00\x13\x08\xe1%<\x83\"\xed\xd2o0\xc6\xf2\x9fa\x0c\xbf\xc2\x98\x8f\xb2\x13\xf1\x87\x7f\x871\xfch%m\x7fU\xa8Fu\x85\xe8`\x9e\xadJ\xbc\xb7\xe9.\x84\xdf\xfe\xa6\xd5\xdb\xdf\xee\xe3\xc7\x86\x9b\xd9N\x85!\xe3\xa1\xfd\x19H\xde\x16!\x08\x14W\xd3\xc7\x18\xa0\x1dz\xec\x9b\xfeF\xd9\xcf\xb9\x0b;\xe9\x94\xfc\x17'\xed\xf3$\xc6\xbeH\xdeL\x14\x85\xa3\xd1eY\x80\xb0Q~\x92\x1f)G\xe97\x02\x94\xdcYd\xc0H}\xa6\xd9\x90\x87D\xe3\xd9\x82\xccv\xa8 p\xa2\x9ah6\x9c\xe5\x19H\x15T0\xc5n\x04\xeb\xbd\x0d@\x9e$\xa9\xbe{\x8d\x96\xaf\xe8Q\xfd\xf7F?jM\x06{\x90o\xff\xd8\xf8\xb6\xc0\xed\xc2\xe7\xe51z\xbb<~\xdcuM\xf8\x0e\xb2\xf5_\x9b[\xbfg\xad\xff\xc2\xf3\x04r\xbca\xcd\xfe\xe4|dE\xbe)M\"\xb6\xfess\xeb/\x8d\xad\xb7\xc67(\xcb\xee\xb0\x0fO\x9c\xb3\xb0\xe7:\xd3\xdf\xcf\xc2\xd9\x0f\xee\x93\xa5~W\xa9\x1f\x94\xc9\xb3\x9a|\xe1r\xd9DP\x96\x0c&\x90\xa1\x9aA\xb8U@4\x08H\x92\xbeeo\xf0\xfc\xe0\x7f\xce#\xd3\x0d\xfb\x98\x7f;u\x0d{Z\xfd\xa0\xa8~\x16\xcaP0Ct\xffd$^\xfe6c,\x88\xc9k$l\xf5#b\x0c\xc6\xaa\x0b\xb01\xc1\xa7\xfaam'\xc0\xc3\xbc5O\x04\xc4\xc9\x15O7\x1b\xc6\x0cyJ\x18>\xcb\x00o\x80|\xb6\xd3\x13\xe81Y\x0f\x13\xdc38\x88\n0a_\xc7<\x9f\x1d\xf4\xe0\xcfN\xc0\x85I\xbc\xb5\xb0vf\x8ey \x05*\xfa\xc6J\x9f\x19z\x12\xb7 \xdb\x7fk\xc4\xf6\xc7\x98\xac\xa4\xf9~O~rA\xba\xe0\xca\x85\xa4l\xe4\x91\x84\xce\xb4\xc2\x08\xbd\xe4\x02\xda.\xa0\xe7\x0e\x13\xd7v\xb7F\xc8\x04\xd4\x83\x95\xfa(\x15\xf3wv\xb76\x87PD.\xdd\xda\xdeb\xc26*\xa6\xfepF\xc3Mt`Na\x83\xb7\xce\x93\xc9l\x88\xd7z\\\x86c`c\xbc\xdb\x98\xeb\xbc\xde\x0b\xab\xd9\xde>t\x90\x93\xf9\xe4`Zh:\xf5g0\xe6\xa7\xdc\x1fz\xb74\xf5#\xafSmk\xe6\xf2\x8c\xa2\xfa\x86D \x08\xf3\x92\x95t\xba\xfej\x1d%\x89\x7f\x11\x08\xc7\xf71\xf8BU\xc9\x8d@x \xb2n\x13c\xf7\xd9\xb1\xcb\xf3\xbf\x983K\xc1\xbe\xe4\xd7\xa4\x02\x10\xe3\xafin\x01\xe221)\xc5\x95\xd2\xea/B\xb6\xdfx\x8em\xfd{\x9b\x9c\x1e\xe5\xcf\xd8(\xba\xbd..\x97\xdc\x94\x1b\xfc\xb09\x0b\xbb\xd6\x19\xfed\x14\x84MCf\xb8Q\x90\xd4\x8d\x11\xa6\xf7\xb4\xf6\xf1g-\x14\xd1\x1aAq\xbcV\xc9k\xce\x1bTl\x87UE\x96\xe2CY+:\xae2\x90\x85*\x9d\xc0\x0b\x08\xd8\x1f=\x07\x89\xa2\xa3\xe31)oJf\xee\xa0\x88s\xc0P\xc4\x1b\xe4\xf6\x06\\\xcb\xdd\xf1*5\xba\xdc\xbc\x80aR\x9e9\x90\xd3XY/Z\x80\xfaR\xdeN\xder\xa5#F\xfal\x82.\x95\xea]\x98\x80\x87\xdf\xc7\xd0\x9dt\xfb\xe0\x0dr\xbb\x04\xdb\xb1\xc2\xdaXp\x95\xa8\xb8\x1a\x99b33>\x0e5>N\xdfh>\x91\xf1\xbb\x00\xb5K\xee\x13\xa1\x94\xb03sa\xa1\xe2\x06\x0d\x80\xfaA9/\xa9\xf5\x85\x11-\xca\xf4\x99'\xe8\xf7D\x82\xfe\xc7/1k\xbf\xe0\xfdc \x9eG\xd7i\x82Wo\xfc\x04\xe6i\xc2\x10\x02\x8f\x9bN\x9a\xf2\xb4\xa6\x8b\x19\x9f\x99\xf9\xe41OY\x8a\xc3\xb1\xb6\x8a5\xfe\xb4\xc6&K+\xe6w\xec\xfa\xd1\xffU\xd2\xf1\xf1M_\x95\xd9\xd5\xfb\x83|\xc8a\x9fo\xe5\xb0\x0f\x9d\x11F\xc1\xc9\x7f\x0e5\xd9\x82\x13\xc8\xb1\x847Q\xcd\xdb\x9a\x13?U\xa4}\xc1#\xc4\x95\xa5\xdcjVS\xd6|\xd0\x87E\x1f\xed?\xea\xdeR\x0cAQ\xd9\x91?B\x17\x1f\xf9\xa4\xae.C\x85\x9d\xa3h(\xc5\x8dXqI\x92\xcb\x04\xa1\x8b7f\x85o\x06\x02\xeb\xd1#\xb6\x05\x95\x02T\xdb\xdc\xdf\x83P\x84K\xa5\x02\x12\x86\x97 R.\xfb\xa8*u\x85Z\x8aVn_\xa6\xc1\xcc-\xa0\xdf\xfd!\xa6\x8bs\x86\xe3\x15\xf1\xderQ\x8d\xd3\xc2\xb6;\x9a\xc6q\x08\xba\xf2}\x9eR\xdc\x00W\x97\xaf\x1c\xcf*\xab\xde_\x8aU\x96\xc7\xcd\x04\x9cN\xcd\x96I\xa3!\x92\x9f\xb2r\xb9\xaf.\xb0\xc5\xa2\x95\xdf\x1c\xa7\xc4\"\xe0]V\xeeYM\xb9\xf1\x91\xd6H\x1f\x04y\xa5\xe8\xc2%~w\x9aT\x80J\x0e\xd9\xe2$\xd0\xb4\xa3\x145\xb4\xa8\xbe\\\"u\xf9u\xe7*K\xd0\x92\x80\xc0\x05O|\xc3\x13\x98\xdb\x8c\x10\xa1\xa4b\xe5,\xc4e\xe9\xbe\x8d<\xe72\xd8\xc8E\x95=\x135\xc4\x823\xc8\xf8\x0c\xa9\x1d\x0c\x89$\xae\xb5D\x88\x89p\xca\x18\x9c\xcb\xa9?\x9b\xf5\x05\x8d\xe1\x96\x80\x19O\xcb\xce\xffq\xbc\xc7\xdd\xd5b\x07 \xe4\xc7\xbd\xc1\xbe\x15\x1e\x15L\xf0\x90\x89\xe0e\x1dO,\x1d\xd6,\xe77\x9f\x88 N\x13\xc6\xa8\x8a\xaf\xd0\xc5\x8d\xd7\x93\xaf0\x0e\x83S\x81\xd2\xdc\xd4\xa9$|\x1a\xc1\x17\xf4<.z\x1eC\x97\xe1uo_\xed\xdd$\xedHZk\xa2\xee\x89}&g\xe4K\xda\xe2\x14t\xe4QNG\x90\xc9\xe3\x9d3\xd9\xac\xbe[m[\xb5b#\x914\xec\xd3\xa0y\x9fz-\xf7i5\xa7\xb6\x97\xa3o%\xa7vV\xbf\x8a\x9f\xa0\x00\x8eR\x93\xa0`\xfc\x18\xc2\xbb\xddn\x1fq\x02\x95 S\xb6?\xbci\\`3N\xb63\xe2\x87_\x01\xd22N*\x8dq\x04\xcb\x8a%f2\x96q8\xc8x\xa3eF\xbd\x0e\x17\xaf\xb099\x14R\x1e\n\xb2\xe6Y{lR\x8f\xf5\xee?X\xaf \xeb\xbf\x11\xa3\x9a\xd0\xa9\x0b]\x05\xa9\xeac(\xa8\xa5\xf6`.\x1d-e\xf0~\xc9iRx\x00\xdb03\x93\x98i\xc16\xc5l'4\xd9\xe8\xa8\x84\"D[\x1d\x95\xe4)$4B\x12J\xcad\xa6%1\xc1\xb7\xba\x1b\x0c!\xc4W\x9e5\xb8Xy\xfb\xc2g\xca\xc2\x13\xce!\xcd\x9a\x16\xfd\x9fAF\x1a\xd6\x88\xb4X#\x85\"\x84&\x8a\x90\xf3\xbe\xd3xV\xdeA*1\xf091h\xd8\x8c\xae\xd0U\xb6\x82;Q7\xdc\xb4+S-7\xc2\xbe \xf0\xad6\x9cY\x94\xcc\xb7!\xd7(\x89@\x03I\x93\xf4X2\xd5k\xf4m\x84\xaa*-\x0b\xb98F.\x02\x8a\x9eT\x10-\x801/|,i\x048W$Kz!K/'\x95\xf9\x87G\x8f\xf8\xc5\xa4DbT\xe0\xd6\xc1]+i\xe2K\xca\xab\xc1\xc5N*\xc4\xce\xeeKu=\xfed\xee\xa8.\xd2\xe9D\xb5\xff2+\x03sm\x94.\xd4\x8c\xce\x1d\x87\xc7\xbb\x94-\xa3\xfb\x97\x89~*\xb4\xb3\xbe\xa2\xb9\xe5c'O \xa6\xd1\x80\x98}\xec7\x94\xc0\x14\xa1zO[Xy\x15ia|\xdc\x9c1\xf7ui\xbc\x85\x0fy\xbd\xd4\xed\xf3ce\xe0'<\xb4C\xaa\x89\xce.?Uf851\xc3\xd4I\xa7\xfeL@\xcd<\x12{G\xd5X\x11\x15K\xb8\xc8\xd6y\xc4y\xeb\xb0\xee\xc4\xca\xd0$\xe2dZ\xb9R\xf5\x0d\x97\xa8\x90\xaar-\x82,\x9a\xfa\xd3p6\xabL+\xd5\x98\x03\xe6\xe12b\xbb\xd2\x8fR\xab\"\x9b\xb5s\xc43\x02\xb0S\xe8\x1fUOB\xa9\x97V\xcc2q3\x84\xc8\x03\x85}6GZ\x9c\xb0\x13\x08%\x8b\x85\xda\xcbR\x0e\xf2b\xe7\xe5n\x9fr\xfbR\xaadh\x1f$dA_W\xac\x15,\x96{|\x8a\xf1\x80\xde\xa64\x9c;\xf5}\xc4m4\xc7@\xca\xab\x85'~et_\xe4\xf6\xa3z\xb1Z\x07,\x0d\xe9\xd5\xac\x07x\xd9\xd6q(\xecC\x8f\x9aC\xcaX\xa3\x99\xf3h\xe1\x97i\xba\xd6\x04\n\xe7\x0fo\x12C\x0cq\xd1\xdfS\xc1\xec\xd57T\xd1\xb8\xae \xd9zC\xf3\xdb\xdb[\xf6\xf6\x17\xda\xb1+-l\x8e\xec\x0d,\xa3\xf5%\x8d\xedm\xec5Lr\xe1\x07\xa6P\xebzs\x04\xeda\":\xf9\x16\x98%\x1d\xca\x1a\x83\xc4\xd47~d\xbc\xde\x99S/\x9a\xd3O\x1f\xdf\xbe\x8aV\xeb(\xa4a\xea(Q:\xcfzh\xb2\xc0\x18+\xcd\xceM\x07\xdc\x7f\xc2_\xdc5!{NT\xaa\xf1\x05$\xed\xd1\x9e\x8c\xdcQ\xdc\x0f\xa1\xcb;R\x9d\xcd\xf95\x0dZOO\xd0#\xde\x85X(6\xd1H\xf2\xd1#\x10G\x0f\x0dkS\x8cP\xb2\xdbG\xb6\xa0\xfe\x94'\xf03\xd0\xbe\\\xf4I\xd1O\xf2\x8f\xc8\x0f\x9d\xee\xa3\xae[!o}H\xb9go 2U\xb0\x94.\x92\xd1@b\xfa\xfb\xfe\xe4\xd1\xac\xe7\xeeO\x9c\xe9\xef\x8f\xb8\x95\x04\xae\xfa?>?G(\x86V3\x01i0\x159\xe8\xb4i6\x8fb\x156\xabg\x0b \x9b\xe2\x87\xfc\xba\xd7\x89\xa7\xfe\x8c\xb1\xc9-x\xa6\xf8a\x08^\xf8FnU}\x1a\xb9o\xe4\xde\xee\xb6\xd67rk\xb8\xa9\xf1\x8d\xec\x1e\xde\xae\xa9\x97\xd2\xb9\xaag+W\xcb\x14\xdf\x97\xf2\x93$\x7f\xe2\x87-\xc8\xb8\xe1\xcaL\xdc\x94\xf5a\xdd\x87y\x1f.\xfb\xe8\xc9\xa8\x89\x01\xba2X\xe2.\x0d\xe5w\xa8\xf9-\xafSE\xb5Yl\x8a\x92?\xf4\xe9\xdd\x9ar\x9fh\xa2\xe6R\x06\x950\\\xe8\xcf\x10\xb9+\x03=\x02\xe1\xddK\x1du\x04.\x04\xec)\xec\x8bh=\x1c\x10)W\x1a\xd3\x01Y\xaf\x83;'\xeeW#>}6\x0c\xf0\xdc\xech\x8f\x16\x12\xb0\x01\xe6\xfc\xedJ\xbc\xa0Kn\xb7\xf2R\x90\xa1P\xdei\xa0\xe8\xc0Z\xb9f\xcf\x16\xad\xc6t\xa35\x97dC\xa2\xb8\xb3t\xbbj\x01\xce\xb9\x9ac\xe3\x90\xed\xe0Z\xb59\xec\x83\x08\x05\x1fe\xa9s\xd3oa\x94\"A\x91\xc2\x068\x08\x0f{\x00\x88%L a\xdc\xdaB\xbep\xed\xd6\xf3s\x00ga\xabn\xdf\x06\x88\x1cZ\x1d\xad\xe7\n2\xa0Av\x00\x13\xb8`\xaf\x8c\xf9\x9d\x8e\x8a-5 M\xdf\xe3m\xd3\x1a\xe81\x97\x01\xea\\\x0bz\xb6Bl,$^f+\x1a\xa6 \x0f\xe4\x9f^\xfaI\x1fo+\xa8Ei\xc2^V\x90\xad\x10\xbf\x9b\x97\x0f\x14t\xe5\xbd\xd4\x91\x80 $\xab\x02fkmC\x9f\x1d\xd3\xc2\xb3\xd1-]u5\xea\xcd_8\x97m\xe4\xf0\xfa\xc6BSyG\xd7\xa8\xdb\xaf\x8cT{r`\xaa\x0bF\x85\xee\xefQFrB\xae\xfbA:\xd9a\xe7-\x99\xfb\xe1\x92g\xdap\x18\x95\xec\xae\xc8\xedo\xc4O\xbbty\xbb\xb5PS\xe5~p\xa2{#\x97u\xff@ *\xdd\xeb9\xe1-]B\x0f\xab\xac\x05\x82\xe43\xa1\xaf\x0f\x9d\xd8\xa9\xc4\xcd\xccs\x08\x15\x0c\":`\x8c\xc1#\xe1\xe3\x94\xcd\x0dH\x02\xb9|\xd9\xa9\xd8O~\xd6\xef\xd0\x1a\x80\xc6\xa0]\x14\x14-\xba\xe7\xe7\xd8\xfe\xf99R\xe4\x7f|\x86I\x15LZ-\xa89\xe8\x16\x8fC\xe7l?s\x1di\x15\x85\xe2`\x9f\x81vw\xe8\x0e\x16NUp\xee\x832\x0c\\\xbc>l\xba.\xeb\x7f*\xc3\xd9u\x1c\xaa\xda\x8c\xa1\x9aM\xe78\xd5\x14y*\xd5G\xcd6\x9e\xb0*0\x8cl\x87\xa8\xebK%\\\x8aFx\xf9\x9c\xd0\x1cM\xd0@\xf6\xb8\xae\x06\xad\x9a\xc1\xfe\xe33\xbf|\x19\x8b\x83\xa6\x82z\xde%\xf5\xae\xc6\x8aEv\xebM\xab\x92\xf5\x02\xe5\x8b\x8d\xdb\x82\xe8\x1b\x8f\x1d\x0fC6\xf0:\x0f\x1b\xd9\x97\xed}\xde\xdf\x18\xc7\xff\xcc}\xe0~oV\x1a2p\xed|E[\nx\xab2\xb4\x90\xad\xf7\xb4I\x88\x9d\xad\xbd-m\xdc\xa1\xa7\xba\xb0C\xa1\xb3]\xad\xcd\x07\xfft\xbbZ=\x10\xe5\xd5\x83\xc0\x13\xbdVG\xb9\xe0\xf5w\x86\xa5\xd3\xf0\x99\xf2+\x1a\xf8![\x1a\xa7\x82U\xeb\x1a\x19Z\xf8\xe1\xfc\xf5\xf1\xfb\xa3hN\xc7Ui6\xa6\xe1\x9c\xc6c\xf0\x07\xfc[e\x92\xe1*\xca\xc24\xd7\n\x1d\xa4\xbc\x11\x7f\xa0\x7fR~\xfb\x9a\xc6\x89\x1f\x85cH\xaa\xad&x\xc3v~\xc1\xe8\x05\x9d\x7fZ\xcfIJ\x931d\x83r\x89\xe15>\xd2\x93\xec\"\x8d)}\x1b\xa6\xd1\xab(L\x89\x1f\xb2y\x14\xc2\xabB\xa1\xf5\x91\x1a\xcf\xcf?\x1e\x1e\xbc:=\x7f}\xf8\xeb\xe9\xf1\xf1\xbb\x93\xf3\x9f\xde\x1d\xffx\xf0\xee\xfc\xe7\xe3\xe3_\xce\xd1CWk9e\x7fM,\n{\xbbU\xc5\x8ar>\x87\xe7iL\xa9.i\xf8\x92\xa6\xaf\x82(\xa1I\xfaV\x10\xe47q\xb4\xe2\xab\x12\x0f\xccO5\xba\x16\x8aK\xc6*\xc8\xcaM1\xc3@\xb9b\x18\x88e\xa0\xf3|\xcc\xfc\x02\x921\xfbR/\n=?`\xcb_\\h|\xaepH\xeboAL\xf6\xf6\xaa\xd1\xca$5\xa9\xeewNM\xf6\x9e\xea4u\xac\xbc\x1a\xdd,\x13\xe5U\xaa$\x88\xe1\xd3j\xbf\x81(\xaf\xf6\xcb\xe9\xc9\xde3==\xa9\x11\xc35'3\xa3*Y\x9a\xf3\xf2\xcd\xea\xe1w)\xcaG\x95\xf2kQ^\x9d\xeeJ\x94W\xc9\xe4R\x94W\xc1p'\xca\xab`\xb8\xe0\xe5[\xd5\xf6\xcfEy\xb5\xfd\x1bQ^\x9d\xef!*\x18\xdb\xf0n|{6\xc4\xce>D>\xeeP\xb8p/\x07\x87\xd74L\x0fW~\x9a\xd2Xl\xf0\x8f\x94x)\x96\xbf\xf3\x93\x94\x864vVn^\xf7C\x90-\xfd\xf0\xe7\xecB\xd4V\n\x8f\xe39\x8d\x1dR\xad\xfb)\xf5\x83D\xd4.Q\x0bga\xab\xcaj\x9c\xc6\x84\x91d\x12\xa0\x80\xde<\x82\xe4\xc7\xbb#\xb2\xa2\x9a\xfbC\xf69\xf1W\xeb\x80*\xd5\xc7pS\xa72\xecs\x18\xa64~G\xc9u\xb9v\xa6\xaf\xfd\xea\x92\x84\xcbrMCv\xb3\x13\x1a\x94\x07<\x86s}\xcd\x1f\xe9\"\x8a\xe9\xdbp\x9d\x95\xab\xd7]\xb4>#d~\x8e\x92\x02\xb8\x020?\xb1\xb5\xf3\xbd\xbc\xf8U@\x92\xc4\xf1\x8c\xf5O\xe9mZ\xa9|\x89\x95_\x1f\xbf\x97\xd7T\xa2\xaaR\xf2*\n\x17\xfe\x1235\xb4\xab\x99\xb4\xaey\xc1\x17}\xb5f%\xe5\xb1\x96\x0b\xdf\x10/\x8d\xe2\xbb\x16\xb1>\xa5\xc2\x81\xde\xc0\xba\x1a\x98\xb2\x80\xa68\xcd\xf3\x0d!\xc8\xf5iL\xc2\x84\xf0\x1e\xee4\x15\x7fd\xbc\x80\x1f.O\xd2\x98\xa4ty\xe7\\c\xa5\xda\xd8\xc3k?\x8e\xc2\x15\x0dS'0K\xf3\xf8\xed\x8b\xc8\xbf\x99F\x08\x00\xfb\x8cw\xa9\x03\xa8Kb\x9flxY\x1c\xd30\xed\x8eu\xf7 \xbc\xca\x9c\xa6\xc4\x0f\x12k\x15?a\xac\xcf\xdcV\xe7\xd2\x9f\xcfih\xab!\xfc\x02mU\xae\xe8]r\x19\xc5\xa9\x97\xa5\xd6\x01\x05\xe4\x82\x06\xb6\nq\x14\xd09M\xbc\xd8_#\x07e\xa9J\xb24\xf2\"FMRj\xab\x87\x92\x97\x1d\x06\xf4vM\xc2y\x03\x9cH\xb2\x8e\xd6\xd9\xda:=zm\x9f\xde*\x9a\x13{\x05\x19\xb5\xbc\xb1R\x82d\x8c-\xaf\xadj\x14\xfb4LI\x13,\xf1\xce\xfa2\n\xe64\xb6V\x8bi\x92\xd8\xc1\x14S2\x8f\xc2\xe0\xce^\xe7o\x99\x1f\xdb\xdb\xe1\xd3k\xa8\x13\xc5\xd6\x1drM\x82\x8c\xae\xc8ms\x1d\xdf\n\x1d\xac\x13F7\x8duRzk\x1d\x10I\xa3\x95\xef\xd9j\\d\x89\x15t\x81\x7fm]\xef\x98\x06\xf4\x9a4\x10\x0eF\x7f\x16\x0b&\x9f[j-crqa\x87?\xa3\xc2\xd7\xb8]i8o\xe8\xd4\x8b\x02\x8f\xf1\xe1\x0du\xd0P\xae\xa1N\xb2&\xd6\xe5\xf2\xa20\x8d\xa3\x06\xca\x884\xe6\x82\xce/\xac\xe0F\xcf\xe8\x15M\x12\xb2\xb4\x82}\x11D7id]8F\xf9\x82\xa6\xfe\xa2\x9b\xd0:\xecu\x94\xf8aB\xadP\x8c\xa3\x9bFH\xc7\xd1M#\xa4\xe3\xe8\xa6 \xd2 M\x13\xff\xef\x08\x99R\x8d\x8a\x00\xf6\xfa\xf8\xfdA\x9a\xc6\xfeE\x96R\xc6\x1a\xb2s\xaf^E\xf2\x1dy\x8d\xbc\xc2W\x9c\xc2\x8aFgX\x95V\xc4\xd5\x81^\xa3\xb3\xb7W\xad.e\xb0\xaap#e\xb0\xaap\x83q\x08\x9f\xf5a\xb4\xd5\x87\xcd\xbd>lmV,[\x990\xb6\xb9\xa9 \x14\x1d\x0d<\x12~J\xe8\xeb\xe3\xf7\xa8O@\xde%\xf1\xd9\xcc\x91\x0fE\xbd/O\x11Q~\x19\xc5\xb5R\xda\xfcjS\xf3\xc8\xc3+\xda\xf7\xd1\x9cb3\xb2\x00\xa4\xc3\xa0,\x18\xa8U\xab\xca\"~\xd3Zm\x9c\xf1\xae\xd5\x01\xb2\x07\x1d\xee\xb2\xe7\xd4\x0dk1\xf5\xbbHv\xc1V\x9f\xb8F\x05\xcaz \x14C\xac\x06\x9a\x07\xbd\x0dS'/u\xdc>\x8c\x86.\x8f\xe7\xa7\x11?+cu:\x1e\xc8HT\x0b\xc0\xec\xbe\xec\x0b\x86\xe4\xabL\xf6Z\x13\xa6{\x95G-\xc5t\xbc\xaf\x84W\x03\xe35K\xf5\x96\xdax\xd2\x17\x85\\\xa1\xe3\x00\xd9g}I\x12:\xffH\x97~\xc2\xf8X?\n\xe5\xb6\xd0Vg\x9f\x8b\xec\x82\xf1zc\xe8F\xa1\"\xb9X\xbc\x10<\xb2N\xb3\xb8\xfe\xca+^^\xb7\xe5\x87\xfa\xde\x96\x9f9]\xd3pNC\x0f\xd9\xdai7\x8d\xd6*\xda\x86\xf3n\x1fX\xe1/\xf4\xee\x03\xe3\"\xc4O\x862b\x98\xf8\xfb\x03IR\xda\xd5$\xe5\xab\xf7\xea\x95\x9a\xffN\x80\xac\xce\xa1\x1d,\xcbo}#p\xfe\x18d\xb1\x80\x92 \xb2\xaf\xa3\x9bP\x0f\xe7_\xe8\xdd\xa7\xb5\xf8\xfe>\xca\x12\x8aU\x1f\n\xe7\x93\x94\xc4\xdf\x0be_U\xba\xf9\x02X\xe3{\xdf\x15\xdabd\xff,xs\xc9\xf6\xfb\x03\x9c\xf7\xf3\x05\x10\xe7/~W\x90\xcb\xb1}C\x98\x97J*\xe3\xbb\x13\xaa\xbe\xbc07\x9b\xba\xd0^\xa5I{r\xad\xb2\x83[C\xe7C\xb3ZD\xd7r\xf7\xa2G\xc5\xab\xf2\xe1\xabk\x18gim:o {\xd0D\xd3S\x9b\xe3\x105\x19\xa8\x97@k\xa9\x84ki\xb7\x00\xd7\xc4\xac\xb3F0j\xb2\x1c\xd7ymhL \xafe\xde\xb7\x01W\xa0\x94G!:1\x05A\xe9\xceIJ\x90\xbbIa\x02\xe9\x80\xfd\xac\xdeI\x14#b]\xdd\xe4,Y}t\x87\x92\x8f5\x84\xa6\xcd\xfa\xba\xd8\x0e\x1e\x86l\xb3\x99FC\x13^\x82\xbaT5\xf2\xd6\x18\xf3k9\xa8\x9e z\xe39]\x17\xec\xbczX\x07\x87\xe1\xbc}\xf3\x82Z<\xac\x07\xfeR\x13\x9d\xe0\xd7O7\xdc\x96\x10\x85\x8fG\"J|u\xb8h=\xd7df\"1M\xd9\xc4\"\x92\xd3\xa3G\xca\x8e-\x07\xba\x16\x031\xf7\x8e\xab\xe1\xf6AI\x18^\x16\x08\x00\xf9a\xf6.\xc6q\x17\xe1{kMp\x1c\xab>:\x0c\xd1j\x8f\xe7\xa9c\xf2\xcd\xcd`I\xd3\xd7$%\x8e\xcb\x81\xb3\x0f>\xdawEQ@\xe7NTu\x05`X\xbd\xc0,\xc4E\xa5\xac\xd8\x03udO\\X\xf0]V\x8bsbp\x05\x95\x97\xd9\xe7Z\x7f\xfb\xdc\x92GDH\x91m\xb7qn\x8c\x07\xc4\xf3\xb2U\x16\x90\x94\x9e\xdeD\x1f\xd8\xf1\xfb\xdaO\xd6x\xf9\x9c\xe0E\xca\xc2J\x8dn\x1b\xf6;\xa9\xcf\xbf\x83\xd1\xa2\xe6U\x13\x9fo\xb6\xe3[m\xc7s\xa7\x1a\xb0F~\xda\x1c\x1c\xf2\x93\x1fF7\x97\xbew\x89\x8bp\x0d\x13\xbe\"cp\xee\xc4u\xd8\xaa\xa9\xabBd0\xf7\x95\x1bv\xe3\xfa\xea\x1b\x04\xe5&\x02Q\x1dc_\xdf\x15C\n\xf5\xef5\x86\xd9S\xf6]3M\xc1\xad\xdc\x82\\0d\xb81\xad,:5\xd4\x17\xb6\x88\x0c\xd7\xf1\xd8\xdc\x04\x07cj\x05\x14\xc0)\x1b\xbb\x11z\xfe \xa6\x01% un\xdc~~\xe0\xf5\x0d\x01,\xf5\xae\xce\xeda\x06\x0fBu.O\xb6Z\xabo\x8e\xe1\x8f\x1eA\xa7\x85iD\xe5m\x87\x0e\xbc4\x0e~\xa1w\xb8\x1ayJ~\xd8\xd0\xd1\xa2\xcf\xd1s\x80\xf2\x83\xf7\xba\xf9\xbe\xb9t<]XD\xa8\xb1\xa8\xf8*\x1b \xba1\x8b\xdcQ\x1a\xda\xd6HX\x01J\x810\xc1\xaa\xac\x96\xbc\x0d\x1d\x9c\xdf\xc4d\xbd\xa6\xf1I*\xb2~\xa4\xe5\"\xf3\xd5\x01gT0\xd0\x980\xd7\x0d8\xaf\xd3\x0d\xb3\xd5\x05\x8d\xf3\x95c\x0b`\x19\x0b(\xacw\x97\xe7\x8c\xc3\x03\xcc\xdc3`\xf4\xb5%Ms\x93TG\x9cyn\x112\x17\x1d\xefk\x15\xb4+\"?\xfa{\x8dz)\x9eB\x81\xd1\xe1D\xafp}\x8f\xa5_)*\xef=\xd595\xab)\xde#q\xa4\x8a$\xe2V\xb4i\x197\xd5@\xe0\xf8\xe5\\L\x17\xf5\x85\x928\x18\xd60\xd7\xe2\xce\xaf\xcfV\x00\x13\xa0\x0e\x0f8\x92]\x04\xbe\x97SMd\x02\xe2\x01\x99\x17n\xa8\x07\xc9G\xba8\x8d0m_\xbf\x1ab\x0bp\xe1B.\xc8\x0d\xce\xa3\x9b\x90Vc\x96\x16K\xc8\xc4\xb7\xe42\xca\x02!\x06\xb5\x81\xa6\x84I]r\x03\xa9\xae\xac]a\xe4\xd0\xa7\x06\xe8c\xb9\xc8\x86\x16\xd3\x85LL)\x86_\xbf\x0f\x89\x8c\x03\xf0\xb5\x03P.W\xecX\x90\x13\xcb\x94\x8f\xc3\xc7\xafb\x1c}\x08\xf1m\x0c#\x9eG+,\xde\x8e\x90\xc0\xf1\xbdY\x062g\x89\xdb\x80\xf7\xff5\xc8\x8a<;\xe2fLW\xd15-\xa3';\xf9\xbf \x82~\x075\\)\xe2\x80Q\x03iP\x8a\xfc\xe6\xc1^\x0b\x13G\xedR\xa7\x91Xh\xf3\xfb\x1e\xe6\\\x9a@d\x89\xfc\xe2\xac\x8d\xc1V\xd8\xe73_\x81 W8z\xe6!\x8b\xf0\xa0\xfb\xfb\xe0\xb5\xc4\x94\xb9h\x16D\x92\xe4\x04\xc6|\xb05\xf5G`\xb8\x96\x07\x19uD\xb4\xe2Y[\xf1,\xad\\WlZ\xc9\xa0 P\x88\xd0\xb8S\x0ds\xc9ov\xf0\x9d\x80S'V\xcc\x17\x0c\xd3`]WVq_\x17\x95\x17\x04dV\xfa\xd1 \x81\xc60\xca\x96\xd1\x08\xd0\xaf\xca\x83\xa2\x9c\xb6\xb3\xe2\xbc\x7f\xf6\xab:\xa8y\xd9\xce\xa98D\x95{\xa9\xeb>\xac\xf8&w\xfb0e\xbf\x1a \xa9\xfe\x8c\xcf\xb0\xf4+\x0f\xd2Z\xf4\x1bv\x8e\xca\x00+~\x14\x0e\xde\x7f:9=\xfftrx\xfe\xe1\xe3\xf1\x87\xc3\x8f\xa7\x7f\xad\x9f\xafj\xf5\x9f\x0fN\xce\x7f<>~wxpt\xfe\xeb\xc1\xbbO\x87\xf5c\xb7Z\xfd\xe8\xd3\xfb\xc3\x8fo_\xe9\xaag\x9a\xea\x1f\x8eO\xde\x9e\xbe\xfd\xf5\xd0\xf6^\xa2y\xef\xf8\xd7\xc3\x8f\xef\x8e\x0f^\x1f\xbe\xb6\x0d0\xd0\x9eR~\xf2*K\xd2h\x95k;\xc6\xf0\x91.\x0fo\xd7J\x94\xfc\x94&\xe9\xe0\xc2\x0f\xe7NHo\xc4c\xa7\xfb\xbb3')\xb9'\xb1O\xdc\x0d\xcc\x01\x14\x0f\x0eNO?\xbe\xfd\xf1\xd3\xe9\xe1\xf9\xd1\xc1\xfb\xc3\xf3W?\x1f|\xc4\xbc@?\xfc\xb9\xab\xcb\x1ao\x0f\x85\xc1><\xb3\x8e\xd6\x07\xb9x\xfc\xea\x92\xc4\x185\xd1R+I~\xa1w\x96\x1a)\xc6\x1c3=\x0e\x82\xe8\xe6M\x16\x04'^L\xa99\xb6\x0c\xd6\xc3\x08%xjx\x96\x0e\x03\xcbp\x13\xcb\xa3\xbb\xd03w\x9f\xa5\xd1+\x11\x12\xc3\xdcD\x96F\x1f\x02rglE\\\xec\x9b\x9f\xd3 \xf8@\xe6s?\\\x1a;auN\xd6\xc4\xb3\xd6\xb9$\xf1\x89e\xd5\xbcK\x12\x04\x14-\x1c\x8c50\xb4\xc7\x18\"\xb87\x8e\xd6\xb7\xc0\xc2\x0bH\x92\xbc}m\x7f\xceYLS\x8d(H\x8cA\x89\xbc\x88\x01\xc1\x8cV^\x14\xa64\xb4@\x80??\x9c\xfb\x18\xe8\xc3^\xef6}O\xc3\xccZ'\xc6\xc1\x9a\x00%*\xbc\xf3\x13\xdb\x88\xa2xnFO/\x8e\x92\xe48\xf61L\x92\xa1\x0e\xb7\x0c2?\xa4\xa7\xbe\x05\xdey|\\\xc3,\xe6t\x81\x81 \x0dO\xfd\xd8\xdc\xb2\x08\x96c~9\xba \x83\x88\xcck\x91 \xf3\n1Y.\xad\x0bEC\x8f \x04\xc6\xe7\x8b(^Y\x1f\x1e\xd8\xe9\x14\xabr\xd8\xa2\x8f\xf74\xbd\x8c\xe6\xd6*G\xd1\xaf$\xf0\xb9\xff\xa9\x01 \xac\x1a\xe7\x0f\xcc-\xc5dE\x7f\x8cb\x8c\x16i\xa8sI\xc9\x9c\xc6f\xa4\xba\xa4\xfe\xf2\xd2\xdc\x05\x0f`d\x1c\xe4\xa5\xbf\xbc4\xbf\x1b\xd3\x85\xf5\xe1;b!`\x97\xe9*x\x13Y&\x96\xa6\xeb\xc3\xbfe\xfe\xb5\xb1\x86\xefY\x16\xd37/\x10\xden\xbd\xc7\xf0\x8d\xc6\x1a)]\xc6~j>\x81|3\xc4\xaf\xe8\xdd\x07\x12\x93\x95\xb5\x86\x15\xc9\xae\xfc\xd0d\xeet83ov*nd\xd9$e\xba]D(4\x7f2\xec\"~]\x19\x95\xea3\x08a\x08|\xda\xd7\xed\xbe\xca>3$WK\xbe\x052\xd5\xd0C\xe4\x87xVE2\x11\x9b\xf4\x99>?\x84.\xd9L\xac\xac\xe8\xa40\x9d\xe7\x89x\x04\x85r\xbas\xff\xfa\xffa\xefM\xdb\xdb\xc6\x91E\xe1\xef\xf3+`\xde9ij,)\x96\x9d\xc5Q\xe2\xf6u;\xce\xe9\xdc\xc9\xf6\xc6N/\xa3\xf6\xf8\xc0$$\xf1\x84\"8\\d\xbb;\xf9\xef\xef\x83\x02@\x82d\x81\xa4lgf\xeey.?\xd8\"P\x00\xb1\x16\xaa\n\xb58\xfa\xbe\xb7\xb9\xf2\x1e\xfe\xfd\xb7\xf4//\xdc\xdf\xae\xb6\x07\x0f\xf1Q\xe8\xa5\xdbX\xbb\xca\xcf\xc5\x9a\xa2\xee\xd6\x04\xd1DL:\xfd[\x91\x8ab\xf8\x8af\xde\xd2M\xdb/>\x01Ug\xb3\xc9yU\x1f\xbc9\xf1\xa8yVH\x94np\xe0\xd6u'\xe1\x82\x1bkd4\x0e\xa2\x88%b\xbb\x08\x9c<\x9b\x9c\x93m\xc2\xc86 g\xbb\xc8\n/B\x1a{\x00\xbds\xfe\x9cx\xa3\xd1\xf3\x81\xd4\x0c\x1d\x874\xcd`\xe1V\x17\xa6\\\xda\xd5O\xb1\xe6\x90\xce\xb5B\x98\x9a\xf4\xf4\x87\x9b3\xba\x80H\x0d\x8e\xf4\xb7^?a\xe7:`\xb3\x8c\x16\xadgkH\xb8;\x1f\x8c\xe7<9\xa1\xde\xd2\xcd\xeaF\x80E/br \x83~\x81\xfa\x89\x1b\x8d=\xd1x\xb1m\xd3\xc1s\xb3?\xa2\x87Z\xdfQn\xe42\x0f7\x99,\xf1\xfc\xd7\xfb\xd8\x7f\xfb\x96\xcdm_\x82\xaa\x1d\xedkT+7nI\xcd\x1cTC\xb7\xaa\xd0x`\x86#~\xf0\x808r\x06\xc05\x03T\xb2\xe5:)\xcb^G\x19K\xd64\x94\xe9\x83\x8a\xde\xbc\xa9\x13)p\xb3 \xcd\xe1\xf3r*\x82\x14\xfe\x8b\x06\x8bO{4\x0c\x19S\xf5\x83\xa9G\xc6V\xaa\xda\xea2\x13%\x0eI\xa3\x12 \xa2\xc0\xf6\xbf\xdb\x98\xa3\xdc\xaf6\x7f b'\xe1\x0d\xd5c\xb7U\xd5n\xb6\x85r\x86\xc3\x08\x16+20\x99\x91\xad\x0c.\xc1x\x81\x8c\xc8\xa4\x18 ]\x1c\x9d\x9c\xb1\x1c7\xa3\x9ez(\xf9AK\xbc=\xb5.d?\xcb[v\x18F\x15\x87\x1d\xc1Jf\x9c\xbc&UX\xec\xbaH\xef:7\x13[U\xfa\x9e\xe0\xe4\x05\xc9\x9e\x13\xbe\xbd= \xd1\x8c\x9f\x8bI\x98q\x04\x05i\xf5\x9c\xe6\xdcO\xc9\x8c\x9d\xdf\xef\xb6\xb3\x1c{XP\xa4\xbb\x1ec\xa0\x13\x89h\xed\xcd&C\xf2\xdd\x0b\xc9\x1f\x16\x02\xec\x03'Kr\xe6|\xff\xdd\x908/\x1e\xca\xcc\xef\x9d\xf3\xe6\xc1(J;/\x80\xb1\xfc\xde\x01`\xf5\x1b\xf1\xf4=\xdb+a_d\x97\xdc\xbf\xf9\xfeE\x96\xe8b\xc9\xf7/\x1e\xaaDK\x1d^\xd9\xda\xf5\x82\\\xaf\xc2(=\x00\x8eo\xfa\xf0\xe1\xd5\xd5\xd5\xf8jo\xcc\x93\xc5\xc3\xdd\x9d\x9d\x9d\x87\xe9zQ\xb4~\xbdhT5G\xa9x\xe7/\xceT\xf6\xe8\xf0\x85\x1f\xacU\xcb\xe0\xd7y\xf38\xa4 \xa3\n\xfc\xc5\x8a\xc6\n\x1a~!\xd0\x1e\x0f\xa7d\xb6\xdb\x1c\x01\xddi\x8f\x87\x8b\x84\xe7\xba\x9e\xe2\xd56\x1a\xe2 \xd9\x82E\xben\xc4<`\xa1\x9f\xb2L\xd5P\xbe\"%c\x9a\xd0\x95.(1\x8b*\xa6_\x90BY\x82vAM`\xeb\xdc\x11y\xb7\xb0\x90\"wDn\xcacy\xad\x8bdyT\xe5!l\x92\x1e&4\x13\x9a\x84\xe7\xcc9\xcf\xf0\x9c%\xb3\xdcog~#\x08\xa0,0\xad\xbb\xa7,w\xfa\xcc\xf1\x82\xc4\x0b\x81\xc5\xf5\xc2 \xfe@\xb3\xa5\xf8\xed\xb39\xb8n`a\x18\xc4)d/\xc4\x9f`E\xa5\xaf\x07\x08\x80\xa2\xfe\xd3\xe4?\x13\xea\x07,\x02-\xdd\x15M\xc1\x03D\xac\xaaR72\xf0\x93\x877\x0b^\xfc\xd4u\x88\xc244\xebHddJ'\xcd\xb8\xf4\x0d\xc1\xae\xa5\x060\x84;8/(\x1b\xfba6\x07\x0f>\xc4\x1b\x12*\x7f\x99\xc1xk^N:i\x88@\x9c6\\\x9e\"\xf3\xda)\xa2N?p!\xe4\xfcEpV\xd4\x02\x11T\xe8?\xe7/\xa5m\xb5\xf3\"\x0c\xa2\xcf\xe4\xe1\xf7\x0e\x99\x12\xe7\x85\xa3HP\xe7\xfb\x17\x0f\xcb\xdfN\xd9\x95`<\x0f\x12M}\xa9\xe4C\xd9e\xd4\xd3\xed]\x0f\x01T\xc8`Qwoe~q\xe1BO\xeeW\x1f\x9d\xb8\x82(\xe6\x83\x99\x80\xab\n%\xfb\xd0\x0e/\xa2>\xac$Nl\xde\xc1<\xa2S,\xd1p@\xa3\x19\xc9z$=-\x97\xa8\xcfI\x8eK7R5\x85x\x9c\xc1\x86\x02\xa6\n[\xfa\xa4\xce\xbe\xaa0\x83\x0dW>\xb1\xaa\xbe\x9e.\xe3\x0cN\x1e\xd7;+\xe3\x0c\xee=\xae\xc3\xaf\xf1\x15\xa5\xc2\x0c\xee\xd4;\xab\xc2\x0c\xee\xd4 \x91\x1b\xd5\xfc\xfa`\xaa0\x83\x0d\xbb\x8d\x0b)\xb5\xd9{6\x18B\xb8\xc4\x9d\xba\n\xa4\x8a7\xd8\x18\xbe\x13U\xf0\x11\x14\x9c\xf8\xeb\xebB\xa2`r\x0b\xa2\x85\x16{\xf7\xa8\x10\xf9;\xe4l\x19\xa4D\xd0\xf6\x82c%W4%:L,\xb9\xbc!\xff%\xce\xa9H\x9cS\xff5Fn6\xfed\x7f\xd3\x1f(Ka./\xde\xa1'\x83\xb4Z\xfd?36\xbe\xc8\xe8\xe2\\\x1a\xd7(s\xcfl\xac\x97\x85\x1e)\x99jY\x0c\x8a\x1fu&{O\x1dA\x1d\x88\n\x87\xf6\xc1?$\x0e\x81\x0btA\x8f\xa9\x91P\xaa;\x84\xcf \x9c\xda\x96\xb2\xe5\xc0\x8b\xe1\x1a\xc3\x91\x0f\xf6\x89]M\xb4uO6\xfc\xc9\x0eHu\x11\x9b\xd9\xb6\xfa\xce\xc0\xa3\xa4\x15B\x8a\x94\x9fL\x9cA\xa5\x81p\xcf^1\xd158\xf72W\x14\xddu\x86\xb0\xec\x07\xed.M>\xb6x\xdc\x90N\xb6\x133P\xfd\x15\xea!\x19\xf1\x88\xa8m\xa6\xd9\xf8b \xa1!\xda[\xe4\x05\xac\xf2\x07\x0f\xf4\xcfRN#h\xb6\xd7`\x99#a\xa6\xe2W\x87 \xd3\x91\x9b\x0dI\x00>\xb2\x16L\x06\x8e\x85\x88\xc7\x1f\x19\xf5o\xdc\x81v\xa6\xe5\xbe\xc4\xee\x0e\xa0QQ\x9aM \x12\xeb\x99\xa0\xb6v\x16\x97\x9a\xa1:3\xa6\x88\xdf\xe7\xafVKQd\xb6^6\\ \xcd\xc7q^\xc6\xc1\x05\xe7\x92\xa2\xcd\xca\xcfd\xbd\x85*Y\xb7\xa7}i\xbci|l5\x8ey*G\xf0g\xe9\xca\x02\xbe\xd8^\xcd\xa7F5\x97\xb7\xa9\xe6\x1f\x8dj\x16\xdd\xd5\xe8_b5\xbej\x1ca\x19\x8f\x8f.y\x02w\xd3\xe2\x7f\xed\xcc\xcbx|L#i\x0e\xe0x4\x8aCzc\x05)\xfc\xe1h\xc8L&4\x0b\xbc\xcc\xe5|\x1c+\x0f\x85\x8e\xaf\x12<\xcc\xab`\xc6\xe3\x93U\x9c\x05\xe0K\x90\xc9_\x08H\xe4%7q&\x81\xf4o\x0c\xccW >\x9a\x9d$p\xa3\x0e\x91\xfd\x9a\xd9o8\xf5\x99/\xfd\xd6:!\xbc@\xc8\x0f\x0b\xe0[\x96Q\xdf\x04^\xa9\x04\xbc\x80\x8a\x9f\x04\xb0)\x12\xe4\x08\x1c\x96\xe7\xa9\x18\xb0X\xfcG\xb2\xe5L\xe1\xd3$2\x81\x88\x80\xfc Z _$\xa0X\xe6\xc4\xeag\x13\xe8#\xcdX1s \xcd\x98m\xd6N\x19\x03\xf3\x0b'\x85\x1f8\x80lQ*\x7f! \x19\x0d\xa5\xcf\xc9T\xfeB@\xf24\x06I\x8f\x93\xca_M\x90\xb3`\xc5t\xb4$'\x0bV,\xc7B\x1ae<\xfe\x89\x87\xf9\xaa\xec\xdd\x1a^m\xfd\xfb\x99\x06\x99l\xfe\x95\xfce\xd0\x11\x18 \xf6{c\xff^\x8f\xb3\x84z\x9f{\xec\xfd\x1f\x1aeK_\xcb\x82\xe0~\xfdR\x1f\x98{\xf5\x8b\x1a\xb1\xf3\x199 \xea3\xd5\xcc\xc2W\xbe.\xfe\xc8)<\xf4ft\x81\x1du\xd2\xd3{\x00\xba\xfb\xd6 ?\xeap\xc6\xdd\xb5\xcb\xeaMW@\x05>\x06\xb9\xa9/\x86%\xfeA\xba\x1bU\x0e\xdc\xd4\x1e\x01\xb9\x8f\xfc\xcf\x06\x96k\xe0\xcb\x84\xd1\xcf\xcd,\xd9\xb0u\xe03nm6\xcd\xfd\x00\xcb%\xa6\x0c=+]a\xdb\xfbp>$\xaf\x06\xe4U]\x1e\x93\x01\xb1\xd7Vx\x1c\xe7\xe9\xd2E\x86 \x1b\x92W\xb3\xec\\t\xdcB7\xb7v\\j\xac\xdd\xef\x8c\x9cH4Y\xe0\xcb[\xceI\xb0Z|\xf3v\x0d\xc9\xb7\\Us\x9e\xac\xee\xb7\x0b\x1f\x19h\x88\x11'Q?Z\xbap\x9a_\xae\x02)\xb4\xd4\xbfn\xd7\x8d\xc0\x128E\xad \xe9*\xce\x1a\xd7\x8b]g4a\xf4~\xc7\xe1\xb5\n/>\x14\xad\xd3?\x99=$\x01\x82;\x7fj\xe0\xce\x1b\xa0\x9b\xe4\x89\xd0\x87p\xfa\x11\xe5\xfd\xe5%\x07&k\xb8\xa4\xe2\x94Fs\x12<\x1d\xae@\xb0\x0c\xb6\xba\x14\xc7\x1f\x96\xb5\xb4\xd4\x15\xac,\"\x90@\xc6\x14\xc5\xb2>\xb3\x9b\x05\x8b\xf0\xbc0\x88>\xe39\x82\x9e\xc1s\xd4\x1d\n\x96\xa5Ug\xb1<8\x0e\xf1\xac\xab\xcbN\xe1\xcd\xcf\xe84\x89Uf\x95\n\xc5\x89\xad%j5w}\xf3\xff\x80\xff\xbe\xe6WW,\xca\x83\x8c\xad\x90\xf2\xe4\xc7\x9ap\xedW\xd0\xa2\x99\xd1\xd1\xefG\xa3\xbf\x9d\xab\xff\xd3\x8b\xdf\xc6\xbf\x8d~\xf3\xcf\xff\xf2\xe7\x87U\xf0\xbf\"\xb7\x95\xff i\xb5\xd3\x06#B\xfe\x8cJ3\n\xedJ\x1d^\xd0\x199\x03\xf2\xfd\x01\xd9\xa9J0\x02[\xa4\x92\xbfA\xb0\x01\xe4{\xbf\xb4\xc5\xd8\x13|{\x15\x17u\x85\xc4\xf9Oy\x03\xfeW\xf03\xfb\xe5\x0bq\x7f\x05\xf3su\xcf!\x08\x98\xc7\nW\xfeU\xdf\xbd4\xdc\xbc\x16\x04NUFb\x86\x03\xc9\xe8\x824\\C\xea\xcc\x88\xaeX\x1aS\x8f}\xfa\xf8\x9aT\xe3ph\xb9\x94\xbee\xa8e\xc7 [\x07r\x9e\xb9e\x9dRZ[\x1a\xa4\x05,u%\xa99\x17\xb4\xbe\xa5\x9d*\xbcv\xee\xc6\x16\x08\xd5s\x18\x92\xd7Q\x90\x054\xd4t\xbb\xa0%\xe7C\x92\x0c\xc9\xd5@\xfa\xd8o\xfa\xf4\xfb\xda\xe6fP|\xfd\xa4\\\x98\xf0\x8d\xf71\x8b\xce\xe8B\x9a\xdd\x1cE\xfe\x87\xf2\xda*\x85\x0f\xb6,\xf6\xebZ]JA@\xd6\xa5[k\xe9\xa7h\xfe\xd6\xb5@)?\xce\x8a]yN\x0e\xc9\x89X\xdeR\xf3\xebD\xaet\xb2M\xae\xc5/\xb9\xfc\xadKC\x02\xf7@\xe0\x1b\x92\xaf]\x14O\xc7\xc9\xf2\xa68\x82\xe6c\x9ag\x1c\xc2\x88H\xd3\xba\xd6r\xc1x. M\xfe\xe3\x9fr\x14w4\xeb\xd3\xbfSwZ\xa9\" r\x99gY+-\xf7o\xd0\x8dNz\xb3\xa3Q\xff\xe8O\xbc(\x99J\xab\xbeN\x0f\xcc\xd0CCQ+\xd6\xc8\x03l\x83\xb3\xb0\xb8\xd2H\xe0J\x03?\xc7@\xa7\xa7~\x8f\x91t\xc6\x89\x06/\xee\xb3\xa4\xc5T\xcf\x0c)\x11\xd8\xcfP\x0d\xfa\x1ek\x03x\xa7\xfe\xa8N\xa1\x04\xe2\xa2\xd8\x0e\x04\xfdt8\x87\xd5\x8f\x03\xba$\x92\x96\x01\xcb.7P\x7f5&\xc6$6\xdc\xfd\xe3\xebP+\xa2\x08\xa2-\x80x\xf6r\x9a\xe5\xfc\xbe\xe2 \x94H\xdd@-\xa6\x8e\x06\x135\xa29\xc1\xdc\xeccOA'\x9b\xf4\xe4\x9fK,\x0c\xeb\xe8\x90\xbcm\x8e(\xc8\xd4\xc4\x87\xbcz\x9bk~ ]1\xd8\x10(\x01\x85.\xab\x94\xda'\xb9\xd4 \"\xdb\x07\xc4\x01\x15\xa5\xbc}\xc2\xfb\xc6\xcb0\xcc\xc2#\x9f%g\\\xf0\xf9\x81'\xdbA\x0eID\xa6\xfa\xf4\xa9\xd2\x1cf[\x1a\xad\x07\xfa\x03\xf4\x8eZ\x80^\xbfT\x15\x83\xech\xd0\xea\xd3\x1d;\xb5\xfb\xf9s_\x17\xe1Kp\xe2\x80\x93\x16\xb5\xad\xe6J1\xf7\x1c\x1f\x14\x0b\x85\x8f\xa5\xce#\xccRB\xca\x04divP=b\xc1\x7f\x98\x15\x1aYZUL\xd0\x1b\x86\xe2\x98M\x01R?T\xadu\xc0\x0df\x84p]\x83\x9d_)Q\n\x0c\xdc\x89\x1b\xb4\xd1\xc5f \xda\x86\xd3\x12\xbd\xef\xa5\xfcQ\x13\x8aT\xc5[\x18\xff7\x0f\"\xd7qng\xa7O\xca\xa5\xfc\xb3I\xa3 \xce\xf37\x15\x02,\x19{K\x9a\x1ce\xee\x8e\xd8\xbb\x90\xbcM\x1225\xe2^\x10\xeb\xca\xab\xd1\xb7\xbd\xa5\xa6Z\x89\xed~\x97X>\x86\xd3T\x94\x17\x08\xe2\x7f\xc6bs\xa4\x83\x89\xc0\xe8 \x84\x86\x06\x0c\xd8{\x05Z\x1bY\x9c\xd5i\xfbB\x94\xec\xca\xces\x12\x92\x17$\xd5\xb6\x94$\xdc\xde\x1e\xe8fI\x0e6\x19\x92t\x16\x9ew\x912\x8d\xe8\x14\x1e\x0b\x8c\xf0\x14\x9ba1\x8c6i\x0e\x0d\x06e\xdc\xceHv\xb0h\x81\x9b\xc1\xc9\xdf\x8czR7\xe8\xab\x16\xbb\xc5\x16\x00\x19=\xbe\x8c\x82o+\xd7\xefb\x8c\xb8M\xdc\xcb\x15 \x82f\xda\x96%\xb9\x17J\x9a\xdb\xa4\xb3\xbaMh\xe6\x9d\xda\xd4)\xba\xe56\xf1\xacn\x13\x9ay\xa76\xf5\xe0\x03\xb9M\xec\xaa[\x85f\"$\xb3\x9d\x01\x7fW\x14j\x13\xaapE@7`\n,\xa3 \xc4V\x19v\x8b\xf8\xfa-\xde\x95\xda\xd1\x15M\x8c!\xb9\xc6\x83\xe3\xde\x95\x03\xec1\x1f\x97X\x83\xee\xf0\xc9\xcee\xd9\xc1t\xfe\xd4\x8f\xe9\xac\x9f\xfc\xc8\x0co\x80\xade\x8cI\x0b\xcf\x98 >\x00\xf4\x03:\xf3\x08\xc3(Y~4Y\x1f\x7fl\x96 \xe7\x91Yq\x85+\xeb#YN\xed\xecZ;\x1f\x05\xfd\x0cD?\xd3\x01I\xeb\xed\x0e\xa4\xec\x1fX%pU\xf2\xc7\xd7\xc1,8\x07B\xbd\x83\x9d\xb33\x8f\xedW\x8e\x92Z@\xb8`r\x08\x03G L\xad\xdc\xe6\x89`\xcc*\x0c\x1fka\xf8f\xd8A\xecB\x11\xd1\xed9\x90\x81q\xc5dfn\xaa\xd1\xc4\x83M\xd6x\xebZ\x12\xe0\x10\x98\xa6\x87Pb.\xa6\xb0}\xf1\x0dI\xdc\xb5\xa7Hek\xc4\x03\xb2\x15#{\xe3\xcb\x172\x87\xb1\xc0\xf3n\xb5o\xaa_\x9e\x0f\xd0\xca\x1f< \xb1\xa8OL\xc1\\\xfc\xb0\xecR\x91\xd7!\x81\x90\xfbM\x14E\"\xfb\xe9\xa7\xa0\xe0Q\xe9\x94\x98\x1aC85\x07|;\x95k\xa3\xdc\xaa=j\xaf\xc9n\x06\xf6\x9d\x9c\xb2\xacm\x1b\xb7\xdf\x8d\x17\xdf\xdb`\xa3w\xa3`\xdf\xa6|^\x7f\xca\xddrX\xedI\xd1K_u\x81L\xed\xd8\xc5\xdf0\x10k3\x05\x84U\xd4l\x80\x12\xd8\x15\xe3\x98c'\xb2\xf5\xfc\xbd5\xd7]\xb0\xb6\xac\xc2\xda\xb2~\xac\xed\xdd\x99c\nZz-6|\xd6L\xc5\xd1\xe3\xd5\xe6m\x02\x05\xd0\x8f\xbfU\xb5\xa9\xc1\xc6\xf3\x92\x8d/G\x0b/\x16vq\xffx1\xaf\xf25\x03\xbd[\xbc\x07\xcf+\x9f1\xe0\x11\x1aKg\xa5\x05q\xa4B]e\x06\xff\xabIr\x89\xb8#uF{\xa2\xc8\x16 _\x03\xf8\x8c]gJ\xf8\xe8V,>\x03PF(\xe4\x16\xd6\"d\x9b\x04\x03\xe3\x98\xcc\xc9!\xa1P.\xaf\x95SW\x92\x8e\x14\xf2\x1aE\xc2\x1a`\xd1\x81\x10\x0bg]\xdbL\x8a\xffy\x07\x0e\x85\x8b]\x84\xed\x1d%F\xab\x1b\xd5 u\xe6\x91]\x95\x10\xabyC\x9e\xfd\xff\xe9\xe2\x19\x8f\xd6\xf9\x95c\x87[\x01\xd8\x0f\x07iV\xdezvT<\\\xed<'\x11yA\xb2B\xfa\x15mo\x0fH6\x8b\xce\x95\x0e\x87\xcd\xf2\x9c\xf4a\xe7\xda\xf8\xd9\xde<\xe6\xf58\xcdx|\x96P\xefs\x10-\xbaN\xc7\xce6\x81\xc3\x82\xb6&-\x19\xf5\xdboo\xb9\x7f\xd3\xd2\xde\xc4u\x9e6\x1f\xe93\\\xf6\xd9i*C\xea\xa7\x8f&\x8bA6\xe0\x07\xa2\xf4h|\xc7\x03\xf1\xe9\xb3\xba\xcb2\x0e\x86\x87\xa3U:\xea\xf4\xdc]_\xeaj\xeb&n\xe1e\xdd\xe5C\xe2\xac\xd2\x913\xa8\xe3\xda;\xb5\xfb\xe1\xc8\x1d\x0f\x1e.n\xd9\xbe\xb2u\xc9\xb0\x1b\x85kW\xe0\xe3\x8c\x7f\x12\x14$\xe2\x02\xfc\xeb\xbdv\xceF\xa5(\xaa!\x19\x07\xe9\xa7(\xc8B\x96\xa6\xef\xc0\x7f\xd9\xa0k\x1cZ]\x19iQ\x02h@9\x97\x9c\x87\x8cV\\\x17\xcb\x0c\xa5\xc0_z\xe0\xaa\xed\x04\xady\x11\xa4\xef\xe8;7\xab\xa1\x07\xbd2DU \xe80\x9c(s\xc4?\xe5\x83\x07\x84K/\x922\xd2\x05\x99\x82\x08\xbc\x11!\x80HG\xe3`\x96\x99\x04+\xd0\xcf\xca\xc4y\x13_7N\xf7;N\xca\xfe\x0e6)\x0f\xff~\xb7\x8d2\xa8\xec\x94\x11l\x95\xfbl\xf7Cwv4\xfa\xdb\xf9=m\x16g\xf4\xe7\x893\xb08\xc3\xbfCk\xfb\xb5H\xcb\x0b\xfe\xf8\x8a.\xae\xa2 z\xe6\x17\xdb\xb8\xb6\xd8\"y\xf9\x90\xcd\"pq-M\x89\xa5\x14>\x82\xd54\x8b\xec~\x05\xc8m;lpg\x8fw:\xf7\xafej\xbes\xbe#\xdb\xb0\x88\xc8\xb6x\xb9\xe7\x86M\xcc\x86i\x92\xa9\xda\x10q\x08\x87\xecL\xd9\xfcb\xa2l\x8e\xcdE\x97A7\x01?\xa9\xea\xa6\x1b\xdc>\xa4 !(|\xa7B\xda\xff\x07\xf7\xe0[\x13\x84\x9ft\x931\xbb\xce\x12\xeae\xbat\xd9\x1e+s\x8e\xcf\xc2\xbd\x84~\xd9}2\xc0\xec\xe09z\xe8h\x9e\xc1\xb2\xcc\xa3\x19\xabn\xc0s\xcc*=\x9a9?\xb3\xcb\xcfA\x06\xae\xff\x80\x1c\xb9*\xde3\xc8\x7f\xcb\x7f/3W\xf2E\xe6\xac\xd22\xe3\xedi\x99\xfe\xbeL\xe6\x90\xda\xf8jm \x12\xe3`hN3\x8d\x82\x15\xb8\xf8\x02OM\xdcu\x8et\x823$\xe5\xcbI\xe4c|KQ:\xc8\x98\xf4\x14\xd6R\xc7k\x0d\xd3Z\x93\n\xf5g\xad\x05\x9cqa5d\x89\xa0?\xcd\xae\x9c\x15)\xa2\x86\xf2\x0d:S]\x81My\x02\xe6v\xde\\\x0d\xa6k{q\x00\xe6\xfd\x18\xf6\xca\xa0\x8a}\x01Q\x1b\xae\x82\xc8\xe7W\x80\x04\xa5\xa8\x8d\x04csf\xca\x97!i\x02\x14\x83\xdf\x0e\x06#[\xbe\x0e\xaac\x82\xb4\xa5\xa8\xa22\xb4\xc6[o\x9f\xd9\x82\xc6\xa13v^P.\xe2\xe5y\x03d+0a\x90h(\xe2\xe4 \x1aE\x0d\x113\xce)\xa2\\b$5\\D\x91\xbc\xd2.P`\x88\xce\xd1\x8d_qIJ\xee\x8e\x946s\xfc\xdct\xc1,%_\xbb\x93\xba\x0f\xe3\x1c\x97:J\xc7\xcf\x8f\xf6\x8cCE\xbb#~\x86b\xc7\xb0\xdb\xbd\x19h\x13 zY\xc6@5\xeb\xf5\xac\x07\xaa\xe3-\x99\xf7\xf9\x92_\xebHU:,\x1c\xb8\x84\xe7\x95\xd4\xc3R;d\x0c\xc5\x98oj\x8c\x8c!R\x9b\x05\x1d6\xa3)\x98\xaa|\x1b\x88\x95\xe8x\xa1$ nf\x11\xed$\x1a\xecX6\xb2A\x9a\x93\xb2\xff\x98\xcf\x1a\xf1\xc8\xb0\x9aR\xe8f\xb9f\x850\xa8m\x10\x10(\xba\x15\x80^k\x80F\xfeWX\xddx\xe3Tx\x7f\xd5\xbd\xf6o(\xd8\x9fd\xd8\xc16H\x15\x99P\xcfg\xa4\xccFX\xed\x9e*\x90*\xf4P!^\x91\xa7\xdb\xa5\xabJ\xc8!h\xe8[\xaaR\xfd\xc0++\xddc\xd6K\xeb\x9c\xe6\xd0\xb5\x9e6\xa6\xd9\xff\x06\xeb.\x1b\x9b#\xd9\\O\xac\xa7\x8b\x8dj\x9f\xcb1\xca\x8a-uh\xfc\x9e\x96\xdfm\x1d%sR\xcc:aN\xa1F\xf9kJl\xb7\xffU\x8f\x1f]s\xd1M\xcc\x92\xc6m'\xa6\x11\xde.\x9b\x95\xfb\x9d]3/\xcf\xd8{\xf5q7k\xb7mK\xc74\xa5\xb1\x1bv\x1aI\xae\x0b\x85\xf6\x88\xaeZ,\xe4Azh`Ce\xfbk\xe8k\xa2\x14\xbf\xf9\x14G\xa68Xr\xfb=\xd1\x10\xee0\x82\xe7\xc43\xc2\xf7=\x1f@j%\xa9\xdf\xd7\xe6P\xec\x1f9KnNA\xf7\x96'Ga\xe8\xca\x9b\xdb\x99\xe8\xf5\x81\xa0i\xff\xcf\xe9\xfbwc)i\x08\xe67Re\x01D\xd8\xdf\x9d\x83\xda\xcc\x81\xea\xfd\xf9w\x03\xe9\x02`\xe79\x89\xc9\x8b\"\xf4\xd9s\x12oow\x0d\x01Q#\xee\x83\xd6Y\xdc!\xb3$j\xdc\xfdR'\xc3\x1f\xcfy\xb2\x82\x19\x08\xe0g\x9f/\x12\xf5\xd5\xa5\x1ew=\xdeb\xec\xe1\xd2\xb5\x1e;\xcd\xf6,\x95c\xadg\xe0\xe4\xbb\\d\xcbn\xc9*.\xfa\xec\xce\xb5\xe7\xa0\x01\xa8\xf4\xf3u|\x19D>\x1a\x9eO<\x1e\x8f\xb2\x84Ko\xb2\x1e\xa6N\xd0\xaaM]\xa1<\xba\xf0\xc0\xda\xea@\xbfe\xf3Kd\xab\x10`sn\xca\xe3\xe9\xc1\x03\x12\xa0\xdaq\xf8\x06\x13\xdc\xb4\xa3\xaa\x85;\x1b\x88}\x8b\xcc\xbe&\x17\xad\xd5\xe0\xb8\xb1N\x9b4+\xaeZ\x84\xe1x|N\\)'\xe4pG\xa1M\xde\x00{\x0f\xf4\x0f\xc1\x8d\xeeX\xc4\xf2\xc5MD\x11\xd2\xad\xc4Y]\xb8\x1aD\xec4I\xe5]\xa1\xab\xbe6$\x93\x1d\x90\x18\xb5\xdc\xc9\xb8\\\xeai)\x8f1RcK\xb7VbH0\xa9,\xdb/\x91\x0c\xbe\x80e'\xca\xe2\x1a\x1c\xaf\x039\x8b!\xd6\xa3\x16\xf2*x\x03_W\xcfr\xd9\xd4JJ\xf1\xc9&\xa4[\x03E\x01\xb5f\xd9\x81y\xaec\x0d8.\xf3\xca\x8au\xe2\x01\xd9\xda\xaaC\xb6\x926u/\xe8\xdfl\x7f\xda\xb6Fs*\ne\xb1\xd6\x05\xa8\xf4\xab\xa4\xd7\xd66\xed\x1c\xe9\x05\xb6\xc5d\xa5KA\x08\x02\xbd\xb7~\x02\x9a\x06\x1a\x85\xdc\xa3\xed*I+\x1ee\xcbv=\xaa\xae\xaf]1f\xd3n#\x10a\xb5\xdc2C\xe3-\xea\xa0i\xf5\xd32\xaa\xaa\x82>\xdf\x8ej\x0c\xa2~\x9a\xc7\\\xc1\xb0[(3eb*\xdd\x11H \xa99?,\xbbdl\xa2zZ_(\xfc3u\x05\xcd\xe2\xcd\"M\x9dC\xea\xad\x04\x17f5\xce\xe9\xc9\xf1\xc7\x93\xb3\x8b\x97\xef/\xde\xbd?\xbb\xf8ptzzq\xf6\xe3\xeb\xd3\x8b\xf7\x1f/~}\xff\xe9\xe2\xe7\xd7o\xde\\\xfcpr\xf1\xea\xf5\xc7\x93\x97\xce\xed\xbfi\x08K\xeaR\x11\x15o\xb9\x1e\x0d+\xc0\x85\x1f\x94\xe0q\xa0\xf2\xf2^\x0f\x8e\xdf\"\xb3\x90V\xa4\xf6{\x90\xfa\x15\x9c\xe6\xe2\xc7Z\xad\xae\x88K\xc7\x86\x1d\xc8\xaf\x90[\x10\xe9\x9f\xacq\xd3&\xc5 \xe5)Z\xa6\x1f\x92\x8cl\x8b\x92SiN\x01\xd2\xc8\xad\x9d\xba\x9c}0$Y\xb9:*#\x1c\xe2\xee\xd9\xb8\xe9K\xc2\xd0\xa5\x96\x94\x8b2\xf6\xab\x17,d3\x92!\x01\xc4\x03\xea\xd5\xd7\x99[\xbf\xa8 V\xe4\x10\x0c[\xbc\x80\x98=\xb7X@\x08\x90\xc0PDo2\xca\xdbb\xf7OI\xea\x96\xfa\xef\x03\xf9\xd1\xad\xc9\xb0\x16\xe0\xb7]7\xa9\xe0\xc6\x0c{\xf4\xa4b\x8fn-J4\xf7 .\x0ef\xe1\xb9\xe4~\xfa0>rEv\xb36\x80\xda[\xa1,\x8a\x1b\xa5Y\x90l\x9dl\xda\xed\xe5\"r\xbd\x08\xa6$\xefX\x04\xdf\x96\xe8\xb1s\x1c\x06!\x19X\xe8\x9f\x8a\x037\xd7\x01xg\xa8K\xb6\xd2n\xb7\x14\x87&\x16\xf9e9\x9cm\"\xbf2l[\x8b\x14\x12\xa1\xeaJ\x99oU$\xa7\xbf\xaaN\xcc\xe2\xd5\x0ei\xe1\xbf\xc0\xe7\xa3\xb9\xf7\xec\x02\\\xf5-\xaft5\xcd+\xd7r\xa4\xcf!-U\xee\xeez`nt\xbb\xd0\xbcE\xa0\xf8A\x9aoz\x8b\x90\xf6\xbaE\x08;n\x11\xf4/\xfc\xb8\xdap\xb9j\x81E\xc9\xff\xd8\xad\x9e\x12\xd7y6q \x82\xfe\x1fmRp%\xaf\xbe\x1f\xe1w\xb9\x13\x1c\x159nC\xa1\xf7\xbf\x8b\x9c:\xe8\xbe\x1f\xb1\x9c\xf8\xa6fT+\xc5@\x1b\xe2p\xbb\x187$\x07\x9d\x0ed*\x96QnE\xd7V\xac\x85]\xb1\x16\xaa'n(\xc5 \xa1:F\xc9\x8b\x032\xd1\xf2\xb9=G\xf9~ g;\xe7\x03\xe9\xdc\x16\xe644\xb8r\xa9\xc8K5\xd7\x00\xc2\x9b\xe6\xfc4R\xfa\x1efUq\xbc\x94S\xfc_&w\x0f6\x95\xbb\xab-\x9eK\xc9hZ8m\xec\x10Rv\x8c\xfa\xbfD\xfcH7\x92\xfc%\xf5]\xd7E\x92v\x10\xe3\x92\x9e\xc2\x07Z\xda(F%%\xe2\x96\xfc5\xafH\x9d\x1ar\xab\xa8.\xb7B\xa4o\xcd\x15o\x17\x995+\xac\xc9\xc0\xda\xe6\xf1\xb6D\xdbf3#E\xc9Yi\xc1\x89P2\xea\x82\xdb\x8e\xee\xa1\xafY)\xc5\xd8\x90\xfd\xff\x96\x94\xc5\xee.f\xcf\xe4\n\xf8]\x19\xe4X\xda\xf2l\xaeg\xa3A\x9f*v\xc3\xa85\xfd\x90\xf0\xa1\x9dQ\x04Y\xbfv\x90\xd6\xd6\xec\x14\x1cGgC8;i\xdd`\x99\x0dE-\xc5\xe7\xa4\x06\xa9\xbd\x86\xf28B\x17V\xc7\xaa\xe0bU\xd0\x86\x05q\x04\x12T\xd8\x0fQ}M\xf0\"\x9a\xf6d\xdffg\xa5\x95\xbeg\xaer+h_DR\x1d\xca9;\xf9\xe5\xec\xe2\xf8\xfd\xbb\xb3\x93wg\x16G\xacD]1\xc3\xd0X\xa2 \x8bg\x0e\x07\xb8\xcf\xae\xbb\xbcR\xce\xd5M}\x17\\\xc6{UG\xe7\x19K\xca\xfaP\xb8\xaf\x03\xcc\x1d\xa4m14\xdd\xd8\xfe\x8f_\x07\xa7'g\x17o\x8f>\xfe\xf5\xd3\x87\xff\xb7\nH\xdeq\x1c\xdbVCf\xf8\x16\xbc\x1dIp\xdb/\xd7\xcf\xc9\xea\"\xb4\x8f\x1aG\x14\xb5\xcd\x87v\x9c\x809r6W\x89\x19Wz0\xa5\x92\xa0\xb0\x9f\xcf\xe2\x1c\x84\xab\x97V\xe7wp\x0c\x0d\x0b\x973\xed'\x1f(6\xb5\x83\xf8\xdd \xcbn\x90\xb5\xf5\xe6B?\xb0\xe1=\xa9*\xddZ\x15\x0cC}\xcb{\x9d\xe4\x00Qc\xb3\"\xeav3\x99y=\xe8\x02\xf1,\x04E8\xf3z\xa8oIU\xad\x059$\xee\x1c\xa4\xb9su\xe4\x97\xc1cVC\xb2\x1eB$\x9e\xc1@\x86\xe3yK\xb3\xe5xE\xaf\xdd\x95y\xc0\x0b\x80!Y\xd5\xce\xfc\x18|\xf1\xad\x80\xb1h/\xabB:\x95M\xb8(\x11\xe8\x91\x04s\x17CBg\xcbs\xdd\xa2L\xd9B-\xb7\xb7\x07C\x12\x0b\xf2b\xad\xf9|\xed\x81\xc7E\x9c\x7f\x98\x8f]\x7f\xab\x9c`>h\x1a\x03zR\xbaUk\xb2\x89\xf5]\x980\xc2g\xde\xf9\xa0\xcdm>\xf8?\xd2\xe8}^\xfa\x0fi\xd2\xb5\xcdK\x17\x82\xf6\x00\xc3\x7f\x91\x95\\o=\x087<\x05\x9b\xe7^f\xfah\xb5\x84\x9c\xec\xd3\x81bA\xf6vLF\n7\x05\xe6\x92|!\x80\xeb\x96y\x1d\xa8\x98\x94\xf4g\xfb\x9eU'\xef\xdb\xf7?\x9d\\\x9c\xfc\xf2\xfa\xf4\xec\xf5\xbb\xffl9|\x89y\x00w#?\xe3\x1c\xae\xf4\xa9\xbb\x94{\xcd\xae\x11\xaf\xac\xc7E\n\xb1L\xed}\xcd\xeb\xc7\x13\xd8\xc3\xef\xde\xbf<\xe9;\xab\xdd\xe3\x7f\xd7\xfd\xdbB\xa2\x93\xfeT5\xe9IY\x93\x8em\xdbkV\x9bg\xf8-$a\x85\xc5w\x95\xb4H\xd4\xa9b\xe0\x05Qe\xd4\xbbm\xe6Q\xd5s\xcd\xe9\x0b<\xf8\xb0\x19b\x8f\xe1w\xf0\xc4\xde\xfcH\xbaBl\xb6\xf4O\xf8\x9bEt\xedA\xea\xadD\xd7\xa5\x9b'\xd4\xd6W\xb9\x17\xa8\xfb\xe1 \x86\xa7\xae\xfa-8)\xa5\xdb\xbb\xbb{ \x97\xde\xdd\xdd\xad\x0b\xb4\x89\xa1x\xb6_\x1b\xb4\xdau91\x85\xccy\xc7\x81\xbfV\xb6\x1b\x86\x17&\xd60Z$\xe6} \xa8\x89H\xa1\xb7\xb4\xb3\xe7\x82^i*\x89U\xc7FV\xbfu\xa0*x\x0fN \x11\x15\x0f\x81=.N\xde\xfd4%N\x9cp?\x87^ \xe8\xe4\xe7\x93\x1f>\x1c\x1d\xff\xf5\xe2\xf5\xbb7\xaf\xdf\x9d\\\x9c\x9e\xfd\xfa\xe6\xe4tJ\xb6&\xd5F\xd4FJ\x8b\x0b\x9b\xdfE\xa4\xd8\x1b\x13M\xfa\x8e\x8a\x0dL\xb5\x80v\xb9j\xdd0\\?Z\xbc.>\x9d\xcb@\x01\x1b\x88\xf1\xda\xba@\xa1\xc2\x14\xa2U{\xe0k\xd7\xde#\xf0\xe9\xd1y#+\xf8\x9c\x0e\x9e/n\xf1\xbd\xa4\x1f\xd4\xba6\xee\xcd\xf3 \x06\x15\xd8%\xb8\xd8b\xb3\xf8\x1c\xb8\x0d\xbf~G\xda\x8f\x1d\\\x83\xf5n_k\x1e\xbd9@?(p\x97C\xb2\x1e\x0cH2\xae\x07Sq}`\xc3\xf2!\xf8b\xca\xa4\x1f\xa2\x96\xb1\xd3O\x0f\xbfJ\xfa\x91*JTV\x9dT\xa8W\x1f\xdc.\xd4\xbd\xa2\x8a6mM\xfa\xc4(#\x06w\xcd\xdd5l\xfa~\xa5TOW\xfd\xa0\xc57\x16\xd0\xfaZKW\xf5\xa5\xdb\xaf\xbeH\x8a\xcf;\x98Z\xd2\xca\xd8\xb6\xe7\x96k\x9c\x0d\xc8V\xc3\xc7[\x0cV&\x80\xf8\x90\x05.\xcd\xf5\xc1[[|.\x98\xf5\x8d\xa7\x0em\xd7]Y\xdc\x96\x13\xbdj(o\xf1vG\x88\xc5\xe3]\xd4\xb9\xa55r\xc4O\"\xf3A\xc6\x84\xa3\xb4\x8c~\x90Q\xa9\xa4\xd4\xd0\xb1I5\x94\x17|_\x07\xca\xb5\x8c8\xac\x1f?V\x13p+z\xa2\xf3*\xdc\xa2d\xd7PV\xa7\x96\x8bs\xa5dW\xf7\x89\x99*U\xbd\xba#\x80P\xb5\xa5\x9e\xeeU|h\xee=y\\'P\xe68\xe5\x13\xcb\xfa\x1a>9}Y\xdf\xbe\xa2w&\xf5\xea\x96\xaa;\xf5v\xacK%\xfbzO\x05Z\xaa9\xce\x14Xd\x17\xbb\xd2\x07\xc7T\x7f`\xb7\xf2\x97\xe8\xca/\x15H\xcb\xe5rS:\x7fU\xd1 M\xdf\x15\x18u\xc8\xc8\x01 \xc5\xbe\x96:\x89xX\xe8\xc6\x02\x85\xbb\x0b\xe9\x94Z\xaa\xf7(\x12^*\x97Wbf\xd5c\x0d(*B\xf5\xa9\xa2\xb5_]\x82\x17\xcd\xb1\xbbB\xe9$\x8fGi\x96\xe4^\xaf\xebALM\xcb\x88\xf3eq\xf7\xeb\x89\xad\x9c\x06\x19;\xbb\x89YA\xf4\xcb\xbc@i\xc6\xd4\x92\x8d\xd0\x8f\xcd\x8c\xca%l-_\x0e\xdb\x0f4\xf3\x96\xd2\xffZ-?f\x91\x1fD\x8b\xb2\xedH&h\xd6\x80\x03#<\xff\xa3\xf4\xb9\xa5\x15\xeb\xb6&\xb5\xfcW<\xf1\x98\xbc-\xa8dk\xc1\x9f\x18!d(\n\xb9\xa0\xc6|\xb5|\xb5>j\xa9\x80,\xdf'r\xb1\x16C\x9e)\xafOJi \xef\xc71\x0d\xc3K\xea}N\xeb\x1f\xa2ah4\xe3\xe7 \x0c?I\xa4\x0c\xddi\xac\x0c\xabZD[\xe46\xab%z\xbd\xb3\x1c\xed\xe9\xc5\xf66\xbaV\xb2\xd6\x85b'\xdd\xe9\xd0\xb8\xf3\xe9\xaf\x83G\x14\xe6U\xe3\xaa\x14}\n+\x11{!\xcf\xf61\x1ce\xe8g\x0eJ\x82\x0b\x96\xc9\xe5%\xbdl\xb5|\xc6o\xf5\xbeS\x7f\x14v\xd9r\xb7X\x89\n\xc1\xfa\xd8x\x1f\x07)\x04\xbe*f\xb7\xe5lv\xbd\x96\xb6-\xcb!\xd08\xa8B\x08I\xca\xd0F\x13\xfafD\x86%1LV\x97\x1ay\x1f\xf6\xf2eF6\xe8\xf8\x87\x9d\xe9\xb3tl\xb2\xeb\xb6N\x05\xd2\xb8!\x91\x1e\x06b\x1eD\x99-\xa0\x07\xee\xaa^?E\xd4Vl\xa5V\x9b\x83#f\xed\xda>o=\x0e\xc6 \x97\xa4\x91K\x07u\x1c\x86\xee=7o\xd9\xf9\xa0\x96]\xadC#\xa7\n\xdd\xf0\xc1(Y/`2\ne\xaa\xc2\xc2\x83\x016\xbeV\xba\xb2\xc9bo\xed\x808\xa2\xd2\xeb;\x0fu\xdbZ\x0dn\xb9\x1ao\xb5\xf8\x8aq\xd6\xe3f\xa7IZ4_\x83\x12\x83 \x8a\xb8@|.\x96\xe1v,\x87\xa0\xc7\n\x08\xf4\xa4\x07\xe5<\x0f\x86\x15\xc1~\xa1\xaan\xce4\x90\x0543&\xdc\xb5 \x03\xd7\xca\xe5\xbd'\x90\xb78\xecQ\xcf\x18\xa4\xa1flp0H0,b\x08\xe6\xcd\x81\x07a|\x95|\x02i8\xdc\"x\xe3\x93\xb7\x1f\xce~m\xbf>\xb2,hI\x85\xcc\x11\x15\xdeD/\x92*\x81\xbe\x0cB\xdf\xa0\xd2\xb1(\xde\xc8z\xec\x1f\xd2\x8a\x187\xb3\x15\xb1\x9f\xa5\x03\xbd>\xbfi\xf4+\xa2E\xf0\x96ov\\\x02d\x8dmc\x97\xdcII\xbf\x87q\x8c\x0f\x1e\x90\xad\xac\x8d\xa7\xecs\x87\xd0\xc1\x92\xee\x0c\xdb\xef4\xf4S\xb9\xb8, \xbam\xe2\xa0mw\x07\x1d\x01\x05\x08\xe8w\x07\xd1\x9a\x7ff\xff\x99\xd3\xc4g\xbe\xe6\xa9A\x05\x00\xadU\x9a\x93e-!E )\xac\xd6\xf1*\xda\x82a\xd9\xb6\x08\xe8i51\xbf\x05\x1c\xd3W\xba\xa5\xd8\xa2&\xe1\xf9\xf6\x14r%\xdb&\xe3h\x95\x03\xe1\x92\x16\\\xb8e\x93\xb4\x84:p\x99\x8dE\xec\xb3\xe5/V4\xfd\xac\x10U\x9f\xed\xben3\xa7\x04\x1eVuM\xcc\xa3%\xec\x07\xf8\xdb-C \xc4v\xfc\x8e\xf9\xc1\xd6O5~N6 \xd1,9o\x0d`c\xf5\x14\x87\x8dKU\xd2\xb2\xf9\xd0\x18\xe3j=\xf2\xf4\x99\xb3Q\x83\x8c\x93\xa5w\xabL=\xfb\x8d\xa4AM\xca\xc6>\xa5\x81t3[6\x8f\xe8\xe8\x0c\x8d\x1c\x19\xa8\xa1\x0d\xa1VC\xf0 \\\xb5\xf2rpl\xac\xb6\x82\xa5~\xba9K=\x90\x1f\xc2j\xd5B\x8f\xfd\xcdj\x15g\xbe\x1d\x89\x96.w\xbf\x02\xdf\xdb{\x0f\x13\x83\x1d\xeb\xb5n\x80`7;\xd4_\xab\x0f\xf3\x81\xd1H\xaa_X\xf7\xaf~]Q\xbd\xef{\xe5\xceM\xa1\x9e\xe8T\x1b9\xd9\x86\x84\x95\xdeCyP\x011\xc7@I\xaa\x9f\xaa\xa4b\x1f\xe4\xd9\xf0z\xfe\x8e\x89\x0dJ\x93\x9b>\xfb\xb2P\x8e\xc1\xdayH\xe6ME\x80\xcc\xb0\x14\xab\xc2\x0f\xcb\xfb\x11M\xc7\x97\xce\xa8\x0f\xac\xa7\xe1\x97/\xf6\x83\xee\x10\x1f\xa3\xf2;\xd5\xd9jO\xad\\;\x99M\x94 \xb6\x1b\x95>SPk z\x0f\xd0a\xfdI{\xe2\xb8\xc8\xf4\x97 0\xc2\xde\xa6\xa2\xbb\x16\x16i\x08\xbc\xcc\xd6\xa4m1\x17D\xc3\x81\x0c\xd2\x9b\x83\x11\xb8N\x9dJ\xd7[jF\xab\xf7\x04\xc1@\xd5o\xd3\xbeX+\xc7&\x9dW\x11\x10\xe2\xd8\xe6\x1d\x88\xc0\xd5#X\xe5\x03\xeeW\x9f\x1cJ\x17\x98\xb4Ji~\x94\xeb\x1b\xbc\xa6td\xbb\x9e=\xa6\xd9Z\x07\xfe7\xfb]\xe1r\xa1\xb0\xbdGq\x8bw(\xeb\xf6\x80\xf8h\xe3t\xc9\xf3\xb0$K\x8b\xad\x13\xc3\xc4\xa0\xb9\xa25\xf3\xa1\x8c\x82\xacg\xb5\"\n?8 \xd2\x8c\x03\xda\xe5\xbb\xe1\x90x\xb0\xac\xb6|\xf1E\xd1\xa3!\x99\x03\x9f\xde\xbe{\x86$&\x87\x9a7\xeb$e\x01\x91\xd5\xdb\x1aI\x9d\x19\xb8(ab\x17\x81\x95 \xb6\xd5\xc57\x9b\xb4m0$\xb4\x10\xea{\xe2E\xcb$\xe6Cc\xe5\x1e`\xa6=-$\x909\xbb=\xd5O*|Y\x0f)My,5\xd0f\x1fb \xe1,\xect\x93\xb5\x08\xc6m \xcc\xccVii\x11\xb5]dHGo\x0f\x1e\x90\x89r\xa4+\x1d\xc6\x14\x85\x93\xd9\x8e\x85p6\x88\xb1\x03E\xb2\x08\xfc#\n\x88sF~T\xb9\x84\x13\x19\x132%;\xcfI^\xf1\xee\x96\xb7\xfb\xc5^\x1bf\xd9v\xb2\x89\xbbtH\x1c=\xe5\xa6'\xc2\x94\x1c\x92T\xea\xd8H\x8dE\xb9\x1c\xa6$\xbd\x05e\x85\xf8\xbf\xc1\x96#\xbakn\xa1y\xad\xaf\x87\x87\xda\x13A\xdfe*\xb0\xf1\x0f2d\x9b\x1bV\xee?d[,8\xd3#\xda\xe3O\xa8%\x809\xbc(\xf4\x02\xbe:\n\x91\xe0\x90\x845\x19\x81D \xe07\x0b\xc9(\xee\x03p\xaa\xc0\xd4\xe6\xa8\xa0\x8a\xb0@\x15\xd9P\xb7E\xe2\x95\xd0@\x15I\x15\xef}\xac\xcb\x06\\\x18\xe8\xa1\xec#o\xbf2\xc2\x86L\nO\xc2B\xe9Ut\xbf\x1fv\xb24\xe8V\x18\xaa).iEU\xd1m\xc8g\xbb,\xb7\x1d\xc5\xd9\xa4\xd7s\xe2.]\x10\x95\x0f0\xf2URb\xacMP\x9a\xd9\xa4\xc8\x1d\xca\xac\x1a5U%\xa16{Y\xf1 r\xaah\x88\xbb@\xd7OS\x92\x8d\xb9\xdb\xd6Ou\x1a\xbb\xa5\xd9d\x03\x896\xef'\xd1&-\xb2\xba\xd6\x90\xac\x9a\x18\xc4\xc4\xdd\xc5\xfc\x95:1fJ\xcd{E\xdbT\x8bm\xda\xddp8\x0d\xc5\xf0\xfd\x1cdK\xe9]@\x1c\x01!\xca\xa2\x91\xdeR/\xb4\xe2\xfe\x9c+\x1d\xe3-c\x1b\xd8\xd9Y\xf7\x9fy\xb9\xfb>i\x8az\xda0\x08\xeb\xc9\xcb\x14\xc62\xb2\x11\xee\xddZ\xdc\xb7q]4P\x95\x14\x16+|\xd1F2\xe4c\x85\xf4T\xa7[VS\xeb\x95\xafx\xba\xaf\xb8\xd0iA\x06N?_\xc9<\x88h\x18v}\xd9\xec\x05\xca\xf5\xea\xa7\xd5\xf9\xec\xad\xdb\xdf.*\xd5\xdaA\xcc\xd0\x0eb\xa8v\x10+\xb5\x83\x9em\xc8\x16\x0f\xfbI\xb2h\x96Qo\xf9\x91\xcdos\xa2.X\xf6!\xbf\x0c\x03\xafp\x94f\xe9\xb9\xe6\xf2#\xcd\xe5Ov\xda\x18w\x194\xa7w\xedn\xa4\x14\x99\x0e\x0e\x80=\xd3\xaf\xe4\x8f\xaf@I\x8b\xb7\x81\x0c\x04\xd7\xcbv\xc7g\xc8\x98\xd8\x06D\x05\xd5\xb3\x8d\x07||\xc6\xce\xfb|W\xcdl\xdf\x8d\x7f;\xe1s\xf3~\x10\xcc!*)\xe3B9\x86[\xdcQ\x15\xa8\xae\xa6\xae\xa6l+j\xa9\xacPbS\xf9\xfa\xb5\xaf@\xaa1\xb0\x1b\x8fQ/\xcc\x8d!L\xedc\x02\x96\xf0\xb4\xdf\xa6\xb2\x93\x19\x88\xcd\xaa\xc56R*X\xdd\xc9\x96a\x82\xd7l\x1d9\xcd\xb2no\x17\xc9_\xef\xde\n\x94\xb1<\xbdY]rp\xc7*\x7f\x8d\x057\\ys\x9dD\x8c\xdc\x98\xc9U\xed\x00\xba{\xb23\xd9\xd9\xc3{\x95\xfc\xb3Z*\xa3s\xf2\xa4:\xed\xe0W\xf3\x7f\xffo\x9dy\xeb8\xcc*\x04\x0c\xa8\xe6\xcd\x92s\xd8=3~^\xc3|\xe0\xb3\x1dkmy\x01X\x0f\x0cp\xab\x91i\xb1\xb2\x95V\xb2\xcf\x1b\x9d\x90F4\x9b\x19\xc7\xf2\x0e%;0_\x12CR\\Y\x19\xc1\x12\xda\xf6?\x18/\xb53^\x86^\x0e\xb7\x9a9\xed\x0c\xa5\xa9md\x1a\xdf\xba\\\xda\xddvG\xb8\xaa\x0e\xd2\xbf\xca\x04\xd7\x16\xdc\xd5r\xda\xe3\x96\xb4\x08\x02m\xbbS\xd6(\xc5\xd57@-\x8e\xd3\xbf\x891\x17\x1eb\xe4I\xdd3\xba\x0e1\xf2\x14\xb1\xe6*\xcd\xad\xf6'\x0d\x07\xa79x\xa4\xaa~\xbai\xd9\xacd#\xd5S\xabb\x1e_\xfc.6E\xd8D\x12p>%L9\x8f\x0d~g\x10\xef\x97\xaa\x1a\x87:_\x90\xaag\xfc4\xa3Y\xe0I\x1e\xca\x10\x0f\xe5);6\xa3\x19\x9b\xf2\xd0\xbc\xb4NP\xea\xe5\xb4\xd5k{\xd3\xdd\xa9\xe0\xe2\xcb6)\xe5\x8a\xb4\xe3\xb4V\x8b\xa4\xea!\xa8v\xac6EN\xfd*M;*5\x0c2\xfaUX\x1f\xa8\xb6\xfa}\xa6\xa9\xa8\xda\xccW\xc1J\xed\xcfV0\xad\xe6\xd9\xb2\x8a\nP7,\x0d \xc03\xaa7\x18\x12>\xa6\xbe\xff\x81\xf30\x88\x16g\xdc\x0dk\x18\xe1^\x1c \xef\xee>2\x10\xbfD\xfa&\x14o#@\x8a\xb5\xcf\x9a\xe7\x0d\xa9\xc5\xb8o\xe1Q@\x15\xc6eD\xd3|p.\x0eH\xb6L\xf8\x15\xacjA\xd8I\xfd_\xe7\x98F\x11\xcf\x88\xc0<\x84\x12/\xa4iJhJh\xf1%\x07\xc1\xee\xea\xd6\xb8\xd0\xb5\xca\xca%/\xce\x83\xea\x92\xa8\xce\xa1\xa6\x9bM\xf3\x14X\xd3\xac\xdb\xe6G\x9b\xbb\xd4\x10\xfb\xb0R\x9dB5Z\x81\xaa\x8e\xe9-\xf2\x97z7\xc6A\xfa:\xaa`\x17\xe0\xdc\xea\xb5\xe3\xb2\x19\xbcE\xd5k\xb2\xf6\x9en\xd8\x1c\xa3\xea\xba\xc3w\xbc-\xb5\x0b\xa1\xceU\xb5a{\xcc\xea\xdd\xa6\x1e\n\xde\xa6S\x96}\xab\xf6\xe8\xaa-m)1\x88\xc9a\x9b\xa8\x81\xdf\x07j\xb0\x9c\xc5\xfb\xb6\xb3\x189\x8a{\xac\x1a\xe4\x0e\xb5f\x87\xfa\x8e\xfbu\xa5\xc5[\xdb\xad\xfa|%\xf5\n\xab\x83jbbjb\xe2j\xa3\xbb\xcd-\xad\xbeb\xa8\xbc\xa0\x08\xfcc@\x1e\xc9\xf6v\x93\xf8\xaa6\x91\xa2\x9d\xdd\xd4\xf0R\x0b\xec\x1d\x02\xec\xd9\x88\xad\xe2\xecfJ B\xa5\xf1\xb9m\xe2\x10D\x0bW\xfa!\xa8\x93 m\x14|*\xfb\xc9\xaf\"\x96\xbc\xe4^\x0e\x12\x0e\xe55\x89\xaf@HfSb\xd06\x0b\xe38a\x1e\xf5\x96\xacP\xe5\x967P\xdcEn1\x9b\xf2\xc0\x9aT\xb7FX\x1d\xca0^\xceo\xd7{\xde\xd6h$\xc6!\x17\xbd\x1f\x8d~\xbb\xdecNm\xaf\xd5\xce\x02\xab\x8eW\xf3\xf0\xef\xaf\xc4^t\xdb\x1a\x04\xba\xadQ-\xda\xea(\x930\xce\xa3\xea\xd8\xd6j/qK\x8d\xda\xa0\xf7\x82R&\x15b\x03\x0f\x1b\xc0Q4\xea\x14\xb8\xc0\x01\xe7\x19J\xd0\xba\x07\xd1]j\x99\x99\x91Y]k\x86\x07\x0eP.\x06\x86\xf39\xe1\xcfI3\x80\x1d\x89\xea\x9b\xb4\x12\xb5{G\x1a\x03e\xcf }\x0e\xbfh\xb5t\x80\x96~N\"2\"\x01\xf9\x9e\xec<\x1f\x80\xbc\x8bU\xaf\x91\xa2\xd1\x08-\x16\x90\x11\x89T1@\x04\xd5b\x01ZL\xef\xfe\xe89\xc9G\xa3\xe7v^\x1dB\x02\xb71\x8dHK\x1b\xad\xb0\xac$R\x15\xa5\xff\xa9 a\xae\xb3j\x0b\x83\xf4(\xf2XZ\xa5\xc8m\xa7\xacm\x89$\xc9lr\xbe\x89\x96W\xdb\xdc\xf5gIk\xea\n\x06\xea\xb5\x88\x08\xda8\x07i\xe8\x88\xec\x0e\xbcS\x05\xd1\x01*\xf1v\xa6x\x1c\xb1\xeb\xec4\xb8\x0c\x83h\xf1\xdcJ\xa7\x93\xda\xc5X\xa6\x14Z\x9e\x14\xd6q\x12\xe9\x0e\x86d_2A\xe3H\xab)>x@j\xf8\xcc\x80\x90\x11\x0d[\xbeJ\xcaE\\\xc7 \x16c-\xfd\xb4G\xe0\xb6;\xd3\x94\x04\x981,=\x17\x8d\x9e:A\xe1U\x0fx\x1c\xab\x9d[\xcedVWa\xba\x9b\xa8\xe2vD\x81\xc0\xd0\xb7\x15q\xdc\xcb\x85\x8aEj\xfa\x08'\x07\xf1\x1bL\x19h\xb1:x\x16\xef\xcb\xfafqJh\xf3\xb0\x15\x83\xd7\xb5\xd7 (\x02\x07)\xd8\xce\x04\xd1B\x85M\xb4\xb8\xa0k\x9b_Qfv\xdb6\xf2\xf1<\xcc\xd3%\xb4\x82)-\xf4T\xaa\xa1\xf3\x86\x04Gv%+\xbb!e0\xc9`\x08\x85A\x17m\xee\xd6<\x91}%W\xcb d\xc4\xadKT\x8cX\x82 \x97\xe1\xe4E\xa5n-b\xe1 \xa1\x81\xc5Qd\xce\xf8\xf9\x90,\xc7\xcaC\xd7\x99\x9a\x03\x97U\xa6C:\xb53\x87j\xd8\x18;\x1c\x17\xc7v.\xde\xa6\xa9\xd1\x18&lu\x18$Du\x81\x18\x19\xf5\x01h\xde\x19\x96M\x06n\xb1\xa2\xaa!\xf8\xc5qv\xc5\x8f\x92\x05\xf0\xb5\"\xa7\xe2dx\xad\x1c\xefW\x1b|\xc1\"z\x192\x7f*0d5\xa7:\xc4X\xdc\x95\x9f_\xbf{\xf9\xfe\xe7\x8b\x1f\x8f\xde\xbd|s2%\xc1\xd8\xa3\xd1\xa7\x94\xbd|\xff\x96\x1c\x92\xab \xf2\xf9\x15\xc1\xca\xa5,\xfb\xb1Vy\xbb\xe4\xa81\xe1bQT\xc7\xa6\xf1\x85\x13\xdd\xb1\xce\xaa\xd5\x10\x88Sb\xab\xb5\xd6 mV\xdar\xfc\x96U\xb7U\x9a%4\xfeAJ\x1faQ\xf4\x13V\xeb\xdb\x0drH\xf8X\x06\xf0W\xb1\x89\x96\xa0Z-\x0e@\xa8N\x124r\x99\xb1\x81\x16\xd7v5\xe8X\x892o\xdb\"%\n\xbd\xaf&\xadx\x14d<9\xf5\x12\x1e\xca\x88\xe8]\xd3\xaaQf;\x94x\x98\xeb\xb9r\xad\"\x8e\x9b\xbeV\xdb\xda$<\x8a\xc1\x97U\x0c\x89\x93B#\x1dD\x8d\xa2\x8aN\xcc\x11\xe9)\xd3(\x17T\x1b\xd1$0f\x0c\x86\x06\x02\x05\xb4\xc6\xeei\xb7\xcfI\xc7U\"\xce\xf5\xedr\x81\x1eF7\xf18a!\xa3)so+\\(\xde,$\xd7\x12RoEr\xf5S\xc1.\xc4`?K\xe4\x067\x1d\x86\x0eY\x91q\x88\x8c\x03\xc4\xc5\x8a\xe9\x82\xfd\xf2~>O\x99\x0c\xd82\xf6\xb5\xc6\x82\xfe\xa1m4\xe4:z\xc3\xe6\x88\x00\xf5FW\xf5\xeb\x06U\x9d\xf1\xaaX\xf0+\xc1\x82\xceC+;\xbfm\xa9\xf1O\xd5_\xb7\x9a\x89\x92\xf8\xdd\xaf3\xaa\xea\x9acb!~\x1b\xd7\"\xed\x81\x16\xf6\x9e\xe0\x91\x16&\x8f\xeb\xf5\x84\n\xbe\xde\x1e\x0f\xa7\x97q\xbe\xc9\x10B\xd0q\x10\xfd7\x83qi\x8e\xef\xcb\xf7ou\xfc\x8d)I\xda OVqvcT\x9b\xb7\x02\x0b<\xf3!\xcc\x17A\xf4c~)\xb8\xdf~\xc0\x9f\xb2 L\xc5\xd9\xde\x05~\xb2\n\xb2\x8c%S\xf0\x9bg\x05\xfd\x11t\x88\x8a&\x87m\xb0\x05\xef\xe8\x95P\xd5\xf5\xf6/\xe0\xbc\x1e\xd7\x99\xa6\x00g\xb1\xa8e-\xa9\xb5\xf7\xb4\x9e\x9eV\xd4\xc8'\x8f\x9e\xd6\xd5\xc8\x15\x17\xb6[\xff\xbe\xd7-\x03\x01\x8e\xe0\x94\x85r\x08_G\x82\xd9\xa5\xf8\x98+\xd9H>N\x80\x16eE\xa9\xea\xc0c\xf1\xb9\xcd/v\xca\x7f\xb4\xbc\x97\x8e\x0b\xa2\xaa\xc3&\x92\x8eK\xa2\xce\x85X\xe3\xbd\x0c\xad\xea\x02)+\x1dP\xa9\x1f \x94S\x17D\xddu\x04\x94\xa4\xa8\xa2\xb0.F\x9da\xc6\xad=:\xb6\xd1w\"\x9e\x05\xf3\x9b\xa30\xc4\xbeU\xed(*\xf8B\x98\xfbv\xc9W\xbb\xe5Aa^Pk'\xa8Q\x94\x94Ldx\x99D\x8c\x14\x0c-\xd5\xca\x86\x8e\xef\xd5\x06\xc1\xab\xad\x83z\xc5\xb7\xb2A\xc0:\xdf\xf1\x9d\x8d\xcd\x12Z)l\x9b\x81\xc1&\x0d\xae\xf8\xa8n\xfb\x18b\xa6`W\x18hl\x11\xed\xca\xba\xa1\xc6]y\xed\xcd\xae\xf3\x82,\xc5>7\xb0.\xcc&\xcfR.\xbf\x12\x91%\xee\xdc\x14)\xa4C\x12\x0f\x86$\xa8\xf2\xee\xf3\xba\xe1\x15\x14\xbf\xe3\x01\xd6\x90\x05*]\xea\xddz\xdc\xa7@\x1dl{\xa8\x18\x8f\xb6h)\x94\xd78\xdap[*\xa8%\x96\x8d\x98KO\xe6\x85\x90\xe0\xc1\x03\xe2\xa4\xfa\x80\x01\x85/M\xb9\x8a\xac-\xd71\x8f-\xc8W\x8cZ\xf3\xe8l\xce\xeb\x82e\x928N\xa7$'\x87=N\x00\xcd3\x16tt\xd16u}\xff\x91F\x8b\xd6\xa0,`\xdb1\xce\xd8u\xa6d8vP\xb8\xb3\x1d\xfby\x1c\x06\x1e\xcd\xac\xd7\xb5 \x84\xaa?\xe3\n\xcb\x9dI\xb7\xa6C\x92\xc8\xd3\xca\xff\x00\xbb\xcd9\x89|@\xaaI\xe6\xd8\xb9=-rK\xcc\x16\xb6\x9e\xb9-\xbc\xa1\xf8VC\xed\xcf|X\xe4OA\x03\xa5\xe9\xf7\x95\xe0\xcc\x1e\xe9\xc2\x07\xc4\x98$\xb9\x12*\x84\x8dX4H\xb2mh\xe5-\xb1`\x9dv\xd4-k\"\xe6\x174mz\x86\x05\x95\xf3M#o\xc9!\xdep\xd7tKH\xb9,\xed\xb0\xd2\xb7\xc1\x9c{y\xda^iP\x02v\xd5\x99k\x7f \xb0\x86\x8f2\xd7\xe6\x91\xb0]$\x90\x8fa\xe2\x0b+\x80\xe2\xeazH\xf21\x8b\xfcf\x06>\xf9:XC\x9f\xd8=\xa8\x07\x00\x82.!b\x98\x04P\xb723\xf5\xd1\xaf\x8cpu\x14\x07\xe4\x90\xec\x10A\x04g\xfc\x14\xd40\xdcA\xe7~\x0eA\xf2\xee\x85<\xd2h\x02\x1f\xdfPa\x15\xf1]p\x06\x12e)\xec\xe8P\xedh\xb7>\xc6C=\xea\xaau\xf6\xe5\xe8)\x0d\xa7z\xf9\xd0,/^\xcd\x99R\xef\xd5\xae\x87\x9bt]\xf0\xbb\x1e\xd9&-\xee+c\x13\xadV\x90)\xde\x9bX\x0c\x06\xe03W\xb94\x8b\xf5\xf0p\xbb\x03#\xad\xd2\x14\x8f=\x1e\x864N\x99%`k_\xf4\xe6\x8bs\x83L\x89\xd7\x81\xe6\x04\x9c'\xd0W\xcfu\x8a\x90\xf3\xa9\xf5\xb8\xear\xb52\xd4\n\xcb]\xe7V\xf7icX\xbagbQ\x90CIL\x00\xf2\x801!\xd3\xe2\xd7\xf7\x05\x8c+\x01X\xe4\x0f\x15\xa2\x03\x08\xf0Zi\x94\xd5\x99,\xf2\xc1\xd4\x14?\xd9d\xba\x9c{\xc7[\xd2\x84z\x19K\x1ci\x19\xce[\x8e=^\x14\x16\xcb\xa4R4!\xa3\xa2\xb8\x18\x1a\x8c\xeb!=\x84\xb0D\x1d\x1b\xc8)\xd3\x86\xc8\xf4Q\x81\x1eN\xf6\xa5E\xd4\xb9\xc1f\x81;8\xef\xdc\x86DI\x1d\xde\xd2l9^\x05\x91[\x0e{\xc7G\xf2\xaa\x93\x03=\xad\x94L\xcd\xca\xe4\xf4\xb6\xa9\x95\x89\x035\x1a\xb3\xebL\x94\x7f\xf0\x80P\xf2=i\x0d\xc7C\x0c|\xdd\xe2\xa0\x8d\xa86Ri\xff\x92Z\x01\xed\x9aJZ9\x15\xb4\xd6i\xc7xx\x1a\xd0f7FTo\xc1\xe9\x87\xd7\xa7\x87\xf3\x0d\x11\xa0~\xe6%\"\x0c\xe1L\x15\xe8\x9aK\\=\x04\xc7Eb\xc1\x1f\x85!\xd4\x96\xba\x10/\xe8{\xc0 n$\xb8\x0c\xf9\x959\x00\xcb\x99q=U\x91\xa7+\x82\x8d:\xd7\x08\xb6\x91-\x8a\x1a5\xe1\xc2{b\x1d\xfeN\xb1>.\xc5\x93\xb3\xbc\x11\x13T$\x17\xdcKbWB\x00\xe1\xfdx\x1e$\xa9t\x91_(\"\x18I\x95\x82\x9a\xdb)\x12\xb1\xdb{n\xff\xa0\xdd\x16\xca\xd4\xa0+\xf5\x1a+\xea\x86\x8d\x82\xb2\xad\xa5\xeaCuH\xff\xd4\xfc\xd5\xdb\xb3G\xc5`-\x01\x9cl\x18\x9f\xed<'\x91\xb5'{\x92\x13,\x88\xbf6\x1cJ\xc1i\xed6\x89\x80\x1bQ\xa4\x90Fr$ /\x94\xea$%\xdf\x9b\x86b\xf6\xad\x16\x81\x96)\"\xd3\xd4\x8f\\\xceS\x92\x91\x11\x12\xa6\x8a\x90FHi\xfd\x04\x851b\x05\xb8\x91\"\x07\x8c\xbb\xd1\xe0\x9b\x9a\x7f\xec\xef\xedX\x8c\xb0\x8be(\xd5\x9c,\xfc\xfa\x96b{\xb6\"\xb0\x01WVe\x11$%n&\x13\x137\x1a\x14\xfaR\xc6:\x13\xb8\xc2\xf1$\xf1\x98*\xbb\xb6C\x88f#\x93D\xb1)\xd9\xda\x92\xf1mhR(\xda\x7f\xe0i\xa0\xb9\xb4\xad-w\xf2\x84< V 1\x84\x0d\x15\x8d;\x0f\xdb\xa4c\xd8\xac\x17~\x80F\x1e< {\xe0\xe9\xa6\xc9\xdb\xdc\xa1}\xfd\xda\xa1\xb9^\x97\x899\x19W\xec+\xe0\xf2\x8fL\x8b\xe3e0\xf6\xd9\x9c\xe6a\xf6S\xc0\xaeD\xa6$;Pd\xb6\xe5nI\x17\x83\x16_Qc0\xba9\xac\xder\xaa\xd4)\xeak \x84:\x118D\xaf\xa4W\x95\x9c\xa5v{\x13\xe0\x1d]\xb1\xfb\x9dwg\x99e\xf1\xf4\xe1\xc3\xab\xab\xab\xf1\xd5\xde\x98'\x8b\x87\x93g\xcf\x9e=\xbc\x0e\x83\xe8\xb3\xd3\x94\x90!\xf0\xbf\xbc}#\xca\xec?\x8c\xe8\x8a\xa51\xf5\x98\xd3\x94\xa05\xf1\x12\xf5<\x16e?\xb2`\xb1\xcc\xa6\xc4\x91\xaf\xa3%\xbc#>\x9a\xa8\xe7\xe5\xab<\x04O\xd6;H\xb6\xef\x07Y\xb0\xb6d\x86\xc1\"\x12s\xff\x03MY\x18DL|O\xa7\x8d.U\"\xf6\xd10\xe4W\x1f\x19O|\x96@\x99\xf2\x15\x85\x8e\x97\xf4\x92e\x81\x87\xb7b\x15\x87A\x96\xfb\x966&\xf42\xf0^\xf1d%>\x04/\xa39OV\xd8wR\x0fn\x07\xb1Z\xb2, .\xf3\x8cI7\x88N\xe5\x1d\xabJ\xe7\x8b\xa5g\xc2\x8bw\x0c>\xcf\xf8G\x06\xc6\x92\x02\xba|\xc3`\x7f\x0fVy\xb6D\xdb)\xc6\xfcU\xc2\xfe\x91\xb3\xc8\xbb\x99\x12\xa7\xf2\x8e\xd4%\xf2?$|\x1e\x84LA\xab7\x0b\xac\x98\xcf\xd3e0\xcf\x14\xb4x\x1f\xa5\"\x01+p\xc9\xaf\xf1V\xb2E\x10\xe19\x01M\xf1\x8c\x1b4\xd9\xa3\xa1\xf7\x16\x0e`G\xffD\x1a\xe2\xd1\xb8\xd8\x0f\x1e\x8d\xed\x9b\xc1\x0b\x83\x18\xffN\x18\xc4\x1f\xa8\x18tG\xfc\x1c\xc54[Z\xca\x7f\xcca,\x01,\xc9\xd1\x91\xd4\xb5}\x8a\x02\xc1w;\x95w\x0c\x9e\x87\xb3#\x1b?\x98\xcf\xf3\x94\x1ds\xe9\xabsJ\x9cZ\n\xd2\x1b?H$go\xa9\x11\xbc\x9eZ\xf2\xd6\x81m |\xbe\n\"Z\xc1\xef:\xa9\x0d\xbd\xfb\xb9\xa5:|\\}\xbca\xcc_0\xb5\xb7\xf5O\xe4[,dkj\xed\xb8\xd4[\xfb\x81z\x9f\x17 \xcf#_\xd4\x05I\xa3\xcb\"\x0d\xab4\xc2'U\xd0L\x91m\xda\x04\x9b\x9bD4\xfc\xc8R\x9e'\x1eK?\xb2\x7f\xe4A\xc2\xe0\xa3\xb6<\xe4\xe3\xf3 \x0c\xd1\x0f\x88\x8c\xf71\xf5\x02\xf0k#\xdeF\\\xbeZjQ\xa8\x08 -\xa8H\xeew\xdb\xe72\x96|d\xa9\xacB\xfe\xb6V\xa1q\x99\xf1\x86\xc1\x86\x9c\xfb\xc7\x02\x13\x08P\xf12\x02\xbc`\x035\xba\x0b\xc0-\xfd\xe5^\x9e\x8a\x99\xc5\xfb\xc2\xa3\xec\x15]\x05!T\xc5\xa3l4\x877\xb4\xa2(;\x05]\n \x98\x06\xbf\xa3\x03\xa7\xc0\x8e\xfc\xff\xce\xd3\xcc\x04\x1eQH\xb2\x95\xc9\x12\x96y\xcb\xa2\x80|\xb5\x02\xdf\x84eC\xc4\x8b\x05\xf0'\x9a\x04\x12U\x00\xe8Z\xbeZ\x80\x7f\xd6g!\xc0^\xd9\x0eC\xa9\xae\x83\x0fg\xc2Wx\x06\xbe\xc3\xe7\xf8\x0e_L\xf0\xe4]<9\xbc\x89\x97\x8a\xfe\x82\xdf\xa3\x08'\xbe \xf3}\x12\xb0(\x03\xcc\xf0#O\x82\xdf\x05\x9f\x18\x16%y\x99;Z\x16\xd9=\xea\xfa\x89%Y\xe0YjZ\xabL[=\xe0\xb8\xdb\xd1?1\xa8\x84\xfa\xa2:\xd0\x12\x99K\x9a\xb5\x91\xd6RNo\xc2\xca;\x02\xbf\xa4\xd1\x02Ned\x98a8\x8e\xfc\xf5/S\xe2\xc0\xef\x11\xf5\xd7\xa3k\xac\x16\x91\xfb> \x16AT\x02sxG\xe1\x03\x9f\xf1EB\xe3\xa5\x85\x90\x0fVt\xc1L\x92\x01\x12ZI\x86 \"xU\x11\xbe\x86\x80\xd8\xf1X\x8c/\xeb\xcfx*\xbeJ?\xe3_\xf8\xbc\x87'?\xc2\x93Y\x12\xb1\xf0-\xcd\x92\xe0zJ\x1c\xf3\x15\xe9\xad\xcc\x16\x93\xfa\x06\xe4UE\x892\xc9R\xca6\xd9\x9f\xd9\x0d\xdci\xa4P\x95\xfa\x8d\xd6qs\x1a\x8b\xd3^\x01\xaa\x17\x1c\xf2,Xi8\xf8\x89@Iy[\x81;\xcdW\x14:\xcbXr*p?\xac\x0b\xf9>Je\x02V@\xa040\xa6\x95'\x8d~\xb7\x1e6`\x8f\x0e\x05\"v\x14-\x00\xe96\xd2\xb0r\x1cp\x012\xb2+\x9a|f\xc9 \x90\x1c\xf2\xf7\x88\xa1\xb4\x86\xcc|\x1b\x18\x80\xab\xc0\x0ex*\xaf\x085h*o\xa1,\xc0\x05\xd7c\xbeZ\xa15\xf60\xde\xac\xb0?\x07>\xac?\xe3\x0d\x85M\xf1=U\x84\xcb-qV=\xc9R\x9d n\x87\xcb\x96lE\x15\xa2\xc6>\xcf-\xd2\x82(_\xbd\xf72\xba\x86\xf5[\xbe \xdf\xd0R]\xa4\x12\xae\x89\x164O\xbaa\xc73\xa5<\x04\xcd ld\xa7q\x00\xd9\xf2m\xdc6_\xb3d\x1e\xf2+k\xa6\xd8\xe4Z6:%\x8eN\x1a\xc5*\x0d\x1b\x17\x05s\xb6\x0c\xbc\xcf\x11KS\xb3\\\xa6\x13\x91\x821\x0d\xa2\xec\xbd\x92\x08\xc1\xcb\xc8&\x10\x8ai\xc4S6\x018\xf1k4A\x81\xb2e\x81&\xcb\x17\x1cRP\xe7\xb5\xf5\x88\xa4\xda\xcb\x9a\x07v=\xc9^\xaa\xf6)\xeb78\x1c[\xa0\xee\x0e\xe0\xf2}\xc4 \xc1V\x00\x97\xa3\xc8\xac\xa3\xec\x17]\x8f\xf8m\xad\xe2(\xfb\xd5\x80\xfb\xb5\x05\xeeo\x06\xdc\xdf0\xb8\x84\xa5,Y\xb3\xa30^R\xf0\x1bo\xbc\xb7\xc1\xa71\xf3\xb2\x8fby\x9b\xa5\xcaT\xb4,`\xee5+\xc6\xb7\x92\x80\x94\xc07\x9d \xa2r|\x18\x136\x17#(\xfea\xd5\xb1\xf9\xaf2\x17\x1b\xb2\x82\x9ey\x0d+\x0b\x00U\n\x08cP\xba=a1\xa3\x19(\x89A\x81\xe2\xcd\n\xfbR0\xe1N\xf1\x1b\x85\x93<\xe8\xc9u\xc6\xa24\xe0Q\n\x05\xea\x89-%_1\x9a\xe5 3\xcb\xe9$\xb4\x94\xd2oA\x074\xcdCK\x16\xcflR\x94\x04g7\x12\x1c\xf7\xa6\x1e\xb5\xb0\x87)c8\xc3\x9f.i\\!I!\xa1\x95$MC\x1e[\xbe\xa2 \x184\x8fyyH\x13C\xe8SO\xc2\xbe\xa5@N\n\xb9\x84SO\xc2K\xd9\xba\x1b'\x8c\xfaoY\xb6\xe4>\xd4U\xbeb\xf5\x94\xda]\x02\xb8|Ca\xfd\x97l\x1dh\xe1\xa5\xf9\x8aB\xb3\x15.\xe0\x169kKN\x90y\xcb\xb3 \x84\xe5h\xbc\xa1\xf5\xf3X\xd3\x86\xe2\xb7\x95.\x14\x99\xa5\x0c\x02@\xed\"\x884K\x82\xcf,[&<_,\x8dc\xb3\x92\xdevvV\x00\xcd\x03\xb4ZC\xdb)*o\xb8,\x03\x94\xf0\xcf\x96\x95 Y/i\xba\xa4IBeWE\xca\xc8\xd7I\xf8\xa7T!^\xae\x81\xa2\x14\xb7\xaf\x04\x01\xf3&\x88\x98G\xe3\xb2L(\x13Z\x0b\xfc7\x0f\xa2j \x91b-\xf26\xc8\x04\xdd\xb1\n\x8c\xa6\xad\x8a4k1s\xbe\xa1L\xeb\x8c\xf3\xcfL\xd3\xc2\n\xfc\xcaB\x0c\xa7y2\xa7\x1e;\x95X\xc81_1\xe8\x1b\xb1\xd4\xdf\xd0h\x91\xd3\x05\xc0W\x12\x90\x12\x19\xbd\x0c\xa5\xb7&\xb1d\x8c7\x146Y0 \x02\xd4/+\xcc\xaf\x05\x0cv\x96e\xec:;\x02\xfdV\x01\xc6\xae\xb3\x91\xd4v\xb5\x80\xbed\x1eO4\x0e\x00p\xbfH\xb1\x141\x91/\x94h\xc3\xbd\x02\xa0\xa0\xf9\xca\x17\x0c\x92\xa3\x1b!+\xe98$7\xc7%\x019. \xc8E;k\x14t\x91\xd6\x86\x06\n \x13\x05\x94%\xdb\xb6\x7f\x1e\x05\x9e\x8d\xb7Qy?\x04~\x00\xf5\xc1\xdb\xe82\xf0\x03{E\xa0|e@\x83\xaa:\x0e\x9e\xa5\x1fXr\xb2\x92\xc0Y:\x8a\x05\x85\x8a\x11\xbf\xeb#\xe3>\xd7Y\x8f\xca\xeb]\x0c\xf8G-\xaar\xd6#%\xb6\xc2\xc0^\x9b\xb2%g=2dM\x18\xf8\xdb\n\x87\xe8\xacG&\xcb\x88\x15P\xdb\n\x19\xd65\xf32\x9e\x9c\xcc\xe7\xcc\x13xF\xbe\x8e\x18\xbcc5\xb1$\xb5\xb1jk\x96dG\xfe\xfaW\xa8&\xc9@\xf0\x86\xa1\x1d\x91Y\xca\xdd\x00\xb4E\xecVB\xffZ\x83F\xeb\x0e\xd8\xd5\x0f\xfcZ@\xca_\x16\x983\xc0 \nL\xbe\xa0\x90ip\x19\x846n\x18P%>\xacW<\xf1K\x89\x8fxk\x91\xf7\\% \xa9Q\xb7E\xeam\xb4\xc2o\x8cp\x9a\xf1\xba\x90\x95\\\xdb\xef\x87\xafq\x04p\x8d#\x80\xeb\xe3%\x8d\"\x16J\xad[@\x91\xf5$\xec\x1ba\x10}>\xf2\xb2\x1c\x88^\x07^\xa7T\xbe[\xc1\x13/\xe1\xa1\x01.\xdfm\xe0?& \x88\x96\xb0\xcb\x04\x15EC\xe6G\xb3\xd2\xb6\x1aO\x97\xfc\xaa\x00L\x97\xfc\xca\x06x\x16dF\x95\x99x\xb3\x82\xca\xab\\\x05\x89_\xe2^\xaf\xc2\x1f\xc0\xd3\xb6s\xbd\n\xa7\x97\x14U\x98\xb8^\x85\x11\xbe\xc8 \xe7\x17\xf8\x00\xd4\x10\xa5SLAG\x81\x8a\xb3W})\xa4\xe8:\xbc^\x85b\xcd\xea\xf6`J;D\xfa2@\x1as\x83/\xae\x1b|q\xdd4\x17W= \xf9\xf2\xefh]\xbfs\xbe:\x8a\xfc\x0fT\x1cQ\xe5K\xab\x7fT\x8a*\x1f)\x17\x02\x81\xc0\x95\xf5@\x11Dz\x1982Ug`\x84R\xcc!\x04il\x85\xa4Y\x1dil\x806 \xb9\xec\xdb >v\xd6!\x17z\x1b\x84Z\xe1\xad \xb0\xb2m\x10zI[\x8c\xdc\x8a\x85h\xcfWk\xb0WH\xd9\xc6\x8cL\xcd\xc8]\xa4\xaa\x9d*#\x02\x8e?\xb3\x9b\xd4\x0d\x06\xe39ON\xa8\xb7t\xed\n\x84t\\\xae\x08\x19\xe7vgH\x02\xf1\xeb\xc1\x03\xe2\xd2q\xe3\xeb\x12H@\x18\xeax\xdf$@\xc7N\xddu\x02\xc7\xedW[\x82\xfe`\x0e\x15\xa4\xa3\x85Guk\xd7T\x81\xef\xe2>>\x1e\xe3>>vw\xeb\xd5\xcf\xc16\xbdj\xcb\xaa50\xdf\xea\xf8\x05\xa69k\xc3;\x8b\x80\"/\x0e\xc8\xa4\xe6=\xb1i\xaeN@2\x12\x02]\x83o\xd0xIS\xe6\x7fd\x8b \xcd$\x15\xaf\x97\x10\n.\x1e\xe5\xf1~J\x1c\x1eID\x85\xa0)\xfdh\xd7\xf6\x06\xb4r\x11\xe5\xa0e\x90\xf5M@\xd9&\x16LC\xe4\x01^\x9a9\x19\x8f\x7f\x08\xf3\xc4\x19\x12\x07\x04\x01\x10\x1b\xfb-\x8br\x95\xf2\x8a{y\xaa~\xff\x95\xdd\xbc\xe4WQ\xf9\xf6)V\xbf\xdf\xf2\x06\xe8I\xe47'\xab\xa9\xa2\xbf\xa1EV\x8b\x05q\x87\x0b\x12\xfbf*\x0dM\xa7=\x0d\x82Mc\xd4io\xd3\xe0\xc2du\xda\xcfB\xd8\xb0j\x9dV\x8d\\\xf1m\xdb\xb17\x88\x1a\xed\xa6\xa5a\xab\x85b\x0f\xdb\xc4[\x8e\xbb\xb4KP&\x84\xd3\xc2PA\x07\xc7o\xb1\xf3\x92Q\x12\xa4\xf1I\x0b\x14\x8f\x05\xd0%\xcf#\x1f|5\xc4v\xd8\x90\xcd3\x13\xf8\x0d\x9b\xdfn\x94\xbf\xba~m<\xc0\xb2n\x0d\x8a\xfa\x9e\xbb\x16\x07,6\xde\x80~\x9a\x03\xa9\xcd\xfes\xc3\x93J\xac\xe6aH\x96Cbq\x10\xa7\x06\x9fC\xb4xr\xa0]58C\x91\x04|\xa6\x98\xd7!I\xc6\xa5\xea\xba\x8e\xb8\xf3Ry\xb7c\xa9\x0bf\x99\xd5\xfe\xfd \xf9\x8c%N\x93h\xfce3X\xee\x9aE\xa0\x84\x9aNImF\xd8u\x96P/\xd3wtu\xca\xa4%|\xf4\xd6\xa2\xc3\xea_\x0fdF\x0em\xb1\xd3\x06d\x8a\x9a[\x88'\xbd\n\xdam\xde=\x9a2\xe3\xd8\x9bZW\x9a\x1b\xba\x1c\x82\x9d;Y\x923\xe9#\x9e\x8f\x95\xaa\xed\x89\x1f\x80\xc8Q\x9a\xf1\xf82\xb6\xc7R\xfa\xa2\xd5\x07T\x8b\xd1!\xb8\x82\xc7\xb3\x8b\xf6\xc1\x99mo^qd\x96\xc7d\xf1\xe5\xbb}\xb8<\xe9\xed_\x87\xe3\xd6\x12\x17\x8b\xf4\xfc\x8eI\x89\xe0_\xaa6\xe9S\xdc\xd2 \xb5\xa6\x14\x19@n\xa4E{G\x0b\xeaT\x8b\xbdz\xb1t\xe7\x83^\xdd\xd2$TG\x97$m\xd5\xd9!\xd5\x91\x0edFZ\x1c94\\b\xfa\x1f\xf2\xec\x0d\xf8\xd3d\xf5\xe8k\x16\xaf\xa3%\xf1*M\x97a\xd1\x03u\xb5c\xb5\xc1\xc3\x8d\xaf.!\xf5\xae\xcc\x0c\x1e\x99\xc9\xe6\xaf\xbb\xc9\xfbP\x9c\xc9\xc9\x95\x05\xdbc\x94\x9b\xd9\xdf\xab\xf3J!\xce\xfc(\x8f\xdd{u&g\xae\xd2\xeb\xf0\xb1jM=\xdd\x97\xf0\x8f\xea\xbdZ\xaa\xf4\xfa(\xacUz\x9d\xe9Z\xa9A\xab\xc3/\x14|\xdd\x07\xdf\x8d\x1c\xcd\xfa\xe8\\*\x1e\xad>\n\x17e\x84\xaa?\xbe\xd6\xf2\xaej\xe1\xe8g\x0e\xbd\xe4\xe0G\xc0\xa1Q \xdd\xe3\x9dD~\xe5\xfdu\xc6\xf4\x15\x89\x91\xaa\xfd\x0f8\x97\x8a\x95\xf1h\xf4!\xa47\xc6\xcf3ya\x08)a\xe0}\x86\x1fUn\xc7\xe3\xb1,\x91C]>\xcf/Cv\xac\x81\xfd\x84.\xf4\x7f\xd5*\xf9S\xfa7\x90/\xd7A\xa6\x7fC\x8c7\xfd\xf2~]\x02\x15\x8d\xf5\x13\x0e\x1c\x92\x9f\xcb.)<3$\x0e[\xc5Y\x00Q\xcc\x1c\x16y\xc9M\x9c\xe9\x17_\xfdH\x12\x0e\x15\xce5{\x16D\xb1lv\x10\xadi\x18\x00\xd4\xe7\x92_\xfb\xccn>$pO\x02\xbf%k\x16r\xea\xeb\xff\xcc\x7fI3Z\xbe\xbde\x19\xf5\x8d\x94\xa2\xd5+\x93\xd5\x83\x97\xb7\\v\x14^\xde\xe7%\x94\xee\xf5\xaa\xe4\x06c\x9afL\xfe\xc8S\xf9C\xcd\x93\xf8\x0f\x12m\xe2\xc4 _\xe8\xc6&4c\xe5\xc0\x80s>\xc7t\xf1\xeb\xa4\x8c}\x96\x83\"~\xa9\x1a\xd2\x8c\x86\xa1J\xcd/WrV\xd2<\x8d\x99\x9c\xb9,X\xa9P\xd4\xf0\xc6soy,\xc8\x87\xb0xUS\x0c\xbfu\x07\xe1\xa5\x18\x08\xb8\x1f\x0b\x8cE\xba\xe6a\xbe2\x1a{EA\xf6\x0e?\x97\x8c\x85\xcey\x0f)\x91f\x8d\xd8l\xe7|\x9c\xf1Oq\xcc\x92c\x9a2w@\xb6\x05c\x16\x06\x1es\xeb\x9b\x95(\xcbg\x87G\x10\xe3\xb7\x99\x0bv\x98\x19\x8f-\xd9\x1c\x15x\x90;\x8a5Z\x0c\xc1KiFD\xb6\x89s\x0f\x92\x8c\x04\x91*T\x0f\xe3\x0b)P\xe3Cr5K\xce\x8b\x80\xd9\x00Y\xf3\xd2~\xa2PS\x91X\x08\x07\xae\xad\x16\xca\xce\x18\xe2P\x8d/\x12\xce\x81.}\xfd\xb2\xac\x1f\xa9\xe9\xd4^\xd3e\x9ee\xd2\x0c\xf8@\x06\xe0T\xdb\xdbHH\x8d#W\xa6\x08TF\x13FU\x9a\xf1m\xfdK\xf4\xec\xb8\x95\x92\xbf\xd8\x90\x92\xe7(\x13D\x13B\x87pR\\\xcd\xd89.-\xd8\xba\xe9 \xf5\xfb\xd3\xeaGpjtPT\xc7\xeaD\xe8\x07\xa6O\x8b\x0e\xe8\x97U\xcc\xdd\x01}\xa2\xb0z\x17X\x81\xf1;\x01\xfd\x1e@pRt\x00\xbd\x86\xd5\xd5 $\x0f\x96\x0e\xb07\xe2P\xe9\x01\xa3\x0e\x9c^\x90\xc5a\xd4\x03Z\xe2\xe7\x0e\xc0\x0fp\xfat\x01\xf5X/\x1f\xd4\xa9\xd5\x05\xa6O\xb4\x0e\xb8\x8f\xe5i\xd7\x05 'a\x07\xd0\xa9<\x1b{@\xf5\xe8\xc3\xa9:S\xbb\xc0\xe4y\xdb %\xcf\xe2\x0e\xb0\xb3\xf2\x9c\xee\x80\xfc\xc9<|;`\x7fV\x07\xb3\x9d\xbf\x12<\xc0\x1d\x19\xe5\xbfj\x8a\xab\x9do\x94\xfe\x9e.\xdd\xa8M\x82\xac\x9f\xfbf#!\xb8\xd3\xdd\xba\xd9\"\x88(`\xba\x84)\xa2\x19\xde\xdd\x9a!\xc9\xf4\xf6\xa1\xdeU\xaeq\xe4\xe9\xba\xc9p\xbf4X\x81\x8e\xbev\xc9G\xaa\x80@Y\xf6\x01\xb4Nc\x15\xec}7\x1a\x7f[P\xe6\x1d\x80\xdd\x12\x18\xa2\xe6.\xbe\xdb\xdc\xbd\x14\x9cUGc^*\xae\xab\x17X\xd6\xdd\xb9\x97\x9a[\xeb\x01'9\xb9\x1e\x80}F\xf5e\xc1\x01v\x02\xf2\xae\xadkq\xadHz\x8e\xfb\x99\xc1\xf6t\xe1a\xcd\x12\xf5\x81\xeb\xb3\xa8\xcfJV\xaa\xbd\x8f\x16\xef\xb8\xa4g\x1f\x8fLABG\x9b\x8e\x9aB\x86\xbe%\xfa\xf4\xa4\xc5\xbb^\x9f\x9e\x9cU\xd8\xcd\xf6O\xad\xef\xf6)\x19\xe4\xa7\xe3\x1b\xab\xbb}\xe3g\xe0\x88\xdb?\x81\xf8\\\xd3O\x9fO\x1c\xf3\xb8\x93~;\xeeF\x98\x1f@d\xd1\xde\xd2\xa6?\xc4\xa6\x08\x96\n.-q\x9d\xfd'\x0e\x1e\xc8H\xf0M\x17\x10\x90\xa1\xbc%\xba)9\xadf\x01u\x80\x05\xed\xb7?\x17\x83!\xb9\xa8\x94\xbd\x07\xa1/\xdcV\xf3H\x1e\x89\xa5\xdcw\xeb\xd4e\xe3\x8b\x8c.\xd0\xdb1b\x08j\x05\x1fm\x17\x0f\x04z\x18\x90`\x83\xf8\xac\x9f\x08\x96\xfe\xcb\x17\xe2\x9e(\xde^G\x85\n\x0c\x89\xdf\x0d\x16_\xaamh\xae\x820|\xc9B\x961\xcb\xf0\xdc\xfb\xd8Djll\xbd\x8c\xce\x95\xc3Iw0$>4\x0dR\xbb\xfaU\xbcYd\xef\xc7\x90zG\xd9\xfb\xa3}\xd4\x81=o\x11\x18h\xf7nc\x8f\x86\xa1\x8a\xacn@\x97\xcd.~%c\x9aC\xbc\xf8\xe3\x90\xa6\xa9\xcb\xeba@\n\xa9\xb0\xf4\x8f\xd0\xd4\x06a\xd2/\xb1\xe0-\xb0\xec8e\xb9\xcf\xcb\x0b\xed\xca\xadhM\xfd\x8a\xdf\xd3\xa85o,\x9a+\xc4\x0b\x83\xf8\x92\xd3\x04\xf8\xe6>~\xda\xb54\xa9RP\xe9\x94\x1c\x126\xae\xa4\x17\xb7\xa6\xd5\xe4\xaee\x85Mw\xf0-\xa7;\x90^\x86\xcdI\x08\xeec\x12&\x93\xc9\xbf\xc1\xdaM\x98@\xe2\xbeV(\xff\xf6k\xafy\xf1\xc3-79\xb8\x87\xbd\xcf\xecf\n\xf7V\xf5[4\xa2<\x02d\xa0\xe0\xdf\xdce\xe2\xf1\xb2$\xfc+T\x80f\x83/\xb5\x96|\x1a\xb6\xe5\xaeXF[\xb2\xa51\xa8-\x17|\x19\xa0\xd8\x81\xc8\xb8\x16o\xb9\x1f\xcc\x03pA\x90 8wwR\xbf\x18\x14\x8f\xb7\xa4\xc9q5\xf4~\xe7v\xfd\xccnb\x10\x1cH9\xae\xd4\xfd8\x94nm\xa7\xb5x\xa4\x04\x17\x8f\x7ff7\xb7\xf8\xaa/\xb8V\xf3\xa3_\xbe@z\x1e\xd7\x9a\xc2\xc6\xea\x03}\xdbs\xb5\x0c\xbc\xe5\x86\xadi\x19\x83\xfbll%\x05Eg\xf4[b\x00:$\xc1\xb7P\xe9m\xee_\xfcP9I\xbd)qNR\x8f\xa26\x05\xa0=}I\x93)q\x08\x92\xfd\x06\xf4\xad\x9c\xa3$\xe1W\xe27\x02\xf2)\xd6\x00\x9f0\x83\xc6\x8f\xca\xd0\x04 >ZLM^\xf2\xabH\xc3\xc8\x9b\xc7&\x08\x0b\xa7\xc4\x91\xa4\x1a\x92\xfd3\x18K\xbe?E\xb2\xde\xb2(\x9f\x12\xa7\xa2\xf9\xda\x00:\x8a\xe3\xb4\x13H\xb2MS\xe2\xc8\x1fo\xb8\x87\x19O\xbc\xe5\xbf\x7fH\x82\x08\x14\x84\x00?9\x9f\xa2\xc0gQ&\xf0\x89\xdfjg\x80\xa3\xe0\xfd)q~\xa0\xdeg\x9b\x85\xc5\xb3)q\xce\xe8%\x923\xd9\x15}\n\x19\xc5\xcc#&{ba\xc8\xdb\xedf\xe6\x13\xd1M\x8b\xaf\xcb\xc9S5T \xc7\xec\xc7&\xa2\xc1G!ZR\xb4U\xca\xe6\x9b\x99\xbb;S\xb8(L-\x03\xbb\xfb\xb4m%\xef\xedZ\xd6\xf0\xde\x1e|s\xc1\xd0\xf5\xb9\xf7H\xe5Z\xd6\xdd\xdec\x18%\xcc$|O\x8c\xd1\x8f\x1cu\xcb\xb5\xf7\xb4c\xdb\xec\xed\xb7n\x9b\xbdg]{\xe6\xd1N\xc7\x8ey$Z\xfe:J\x19\xea3\xe7\xd1\x93\xb6\xed4\x81\x95\xf3\ns52\x81u\xf3j\x17\xcd\x12\x83\xf9j\x0f\xcd\x12\xady\xf5\x08\xcd\x12My\xf5\x18\xcd\x12\xc3\xf8\xea \x9a%\x06\xf0\xd5S4K\x0c\xde\xab}tC\x88Q{\xf5\x0c\xcd\x9a@\x97w\xd0<9\x1c\xe8x\xec\xc2xL\xd0\x01y$\x06\xe4]\xbe\xb2\xac\xe8 \xccQ+6\xd9\xdd\x15U\xbce\x19\xada\x0e\x9c\xcb\xb3\x9f\xc0\xd2\x0b\xfegvc\xbb\xd1\xcd\x04\xc99\x03\x90s\x19\xec\xf63\xbbir\xa9\xc0\xfcV0\x1ah\xc8\x97\xde\xe3\xab\n\xb9_\x1b\x8d@\xcf~[\xa3\xb4\x7f|\xabld\xa2\xfc\xe1\x93C\x8d\xcc\xc8\x94\xc8\xb0:\xe3y\xc2W\xc7\x8a@\xab\x07DF\x15d7\xa2;\x82YAy\xc0x\xd5\x06eJ\x9cr\xc6\xee\xc1\xc9\xb6\xd4\x11\xfb\xd7s0>\xcd\xa8t\xf7\xc3\x92\x7f\x1d\x03\xd3\\-\xa0\xbb\xc3R\x1bI/\xb5\xa9\xcf\xda\x81<\xb8]\xf4;\xa0\xee\xc4\x96\xdc\x91%\xb2q&\xd5\xb5\xfd?\x86i\xff\xb7X\xf1\xb1\n\x15\xfd\x7f\x8b\xb8\xe9\xdf\x04O\xb00\xa3\xbft\xf1\x84\x1a\xf1JhCv%\x13\x04\x16\x05\xd5\xba\x97\xd5\xfc\x11\x1b\x1b\xc9\x0d\xc6\xaf\x11\xa74\xcc\xe8\xaf\x1b5\xe5\xd7zS~\xad6\xe5W\xbc)5(\x1c\xa8Ws\xff\x86-%\xc8\x91\x86\xff\xdfj\x19 \xce\xf2\xf1\xa0\xb9\xac\x9eu\xd1\x1b\x88\xac\\\x1f\xe0\xcd\xb1\xbe\xc8x\xfc\x86\xadY\xa8\xe2\x02O b`u\x11\xf8\xe0\xf5KdO\x90\xecJ\x84\x8e\xa9\x8a\x91R\x84\xc0\x80 \xa9\" \xc2\xa9U\xa3y\xd8\xb0\xeb\x85\x8co\x83\xe8O^dta~B\xe0\x82q\xc6\xdf\xf0\xabB{\xd3^\xa9\xb6\xfd\xfe\xf4\xf1uQ\x87\x91F\xa6\x88\xda\xfesl{F\xb5}x\xab\x196\xa7\xaf:3\xf5x\xcfS\xb2U3\xa0\xcfS\xf6*\xb8\x14\x13\xb25\xb9\x8f\xb6\x18\x91c\x1e\xd5\x15\xe6\xc51\xff\xf0\xb7\x87\x87\xdf?\xac\xa6\x0b&\xf9\xe1\xdf_\xfc\xb6\xf5\xdb\xe8\xb7Q-\x0f7\xd4?\xfe\xf1\xe4\xf8\xaf\xa7\x9f\xde^\x1c\x9d\x9d}\xbcxw\xf4\xf6dJ\x1cA\xc7\x8c \xe4\xf0\x08b*\xa79\x1a&\xc3\xf7\x8fU\xee\x19\x97\xb1\xb4\xbb\xf0\x081\xe8i\x9ct%\xe6\xd5^\xc6\xd2LTt\x08\x01f\xd88aqH=&\x10\xaaC\x1c\xb2M\xe8\xb8\xd9~\xb2M\xbe;p\xbe#\xdb$\x13?\x9d??\xf8\xae_@s\x1a}dy\xca\x9a=\xe9\x8a\x80\xa8c\x9b\x16\x16\xec.\xd6\xae\xf6\xce\x8aJ 6QL\x93\x94\xbd\x8e \xf0\xe4dg0\x94\xc1\x7f\x80\x8eo\xf6\xc2\xb6/\xeeY\xa4\xf6\xe4\xf1\xe3\xddI\x17\x92\xab\x0fQ\x11\xc7KL\xf6d\x08=\xdc\x91\x91\"wdH/V\x84\xdb\x12ks\xf4\x88< \xc1s\xc2\xc9\x0bB\xd1\x10_E\x8d\xb9\x19f\x90\x93m\xf2h\xe7\xd9\x93!\xa1\x03Y:\x17\xff\xb6\x0f\xc8\xa3\x01\x89\xc4\x7f7\x13\x7f\xd9X\x0b\xa4\x8f2\x97\x0f\x06d\x1b\xcd \xdbd\xd2\x96\xb9\xdb\x96\xb97@f9#\xffq@\x121\x00\xffa\xc6\xa6&\x8d T\x91\xdaD\x17\xc48lo\xab\xf6c\xcdGq\xa0+?5 _\x88\x1b\xa9\x9f/^\x90\xc9\x93\xfb\xc0G\xe6\xac;\x93\xc7\xe3'\xe3]\xe7\xf6\xb5u\xd8,\xb9\x91\xfb\xe8\xc9`(m\x91p\xdb\xa5I\xdd\x9aG{bx40\x8f\xec}\xa8\xe5\xd9\xc6\xa1\xb7\x04;\x1e)kw\xd6\xa2/'\xe0&\x8a\xfb-\xe3\xce)pV\x85\xd5\xbb\x01\xac7\x1b\xe8O\xd4T\x8a\n\xdcL\x06\x11\x1e\x08\xf4\xc7\xed\xe6\x9e\xcd\x16\xa1\xa1\xb4\x04\xf2\x8c|&N\xfd\xc4u\x1e=rDY\xf1\xeb\xb13\xac\xb8\xf3\xb8\xe7\xf8WbB\xf6,\x83\x9f\xa86\x9d\xe6\x97Y\xc2\x04\xd2\xe3EX\xe0\xdb\x7f9\x1b_\\\xb0\xf4-\xf7\xf3\x90\x81!\xdeP\x86\x87\x8b\x98\x97\x01\xa6\xfe\x90\xf0u \x86BG\x1dm\xb6:p#w\xff\xf1n}\xe5\xf1\"\xeb\xd1\x00e#\x02\xabY\x83\x8a\xf7h4M\x1ejM,\xa7\xa2\xa7MIwL\xc5J_\x12\x1dw\xad\xda_\xae\x93\xefyDU\xad-\x83\x18\xb9u\xfb<\x0eK:r'\xd8\x96\x16\x19{O\x1f\x9b\x18T&=\xc1\xc7\x9a\xfes\xc7Z\x9f;-\x07\x9en\x99\n\x1a\x8d|o\xab\x1fU\x016\"n5\xe8\xdd`@\xb2e\xc2\xafH\xc4\xae\x88@2`\xdc\xe0:\xc74\x8axF\x04oJ(\xf1\x04\xc3IhJh\xf1%\x07\xa1~\x14\x17\x8b\x99\xdd\xaf\x95\x95y\xff\x862\xb3e\x1f\xd9\x9c%,\xf2t\xf3\xc4\x87\xc8\x92\xa6\xd1w\x19\xb9d,\"A\x14d\x01\x0d\x83\x94\xf9dD\xd2\xd3\x05\x1b\x93O)+\xeb\x1b\x83\xb4\xa2xu\x07$\xe3\xf2d\xcc\x96l5&\x1f\x19\xf5\xc9J`m\x9a\x11\x15hu~9^\xb1\x87y\xca\xa4\xa8cT~\xc5\xa9\xdf\x8a\xe1\xa3\x91\xb5-~\x1b]A`\xd0\xcb\x95 \xb8\xe1&\xaf\x80\x0b\x08\x95kn\x04C^r\x1e\xa2\x19\xa2\xb1h\x86\x8c\x94\x8bf\xc9\xa3\x15\xcd\xd2\xce\xc5\xb1\xac\x9b\xd5\xa5\xa5\x114\xc2[\x0d\xfdy?Ge\x8bLK\xdb\x90r\x9a:\xb2\x14\x95\xf2Jk\xc7,\xa5xd\xab\x0fr\xa4\xc7F$\x17\xe2\x01\xe0]\xb8\xa6b\x18kW\xbf(\xff\x1e\xd5\x160\x91r\x83\xb1\x99 \x0e\xec\xa2\xec\x1d\xf0F\x83\xa8o\xa2\x14u\x82\xd14\x0d\x16\x10\x9e\xbb\xaf\xb0\xe79\xc9\xc8\x0bB\x93\x05\x88\x94S%\xe6yN\xb2\xedml\xaf\xe8\xa5^\x14\x98e\x88\xe1t\xf1\x89\x84\x04\x91\xe8\xa1j^y,-i\xfa\xfe*R\x8e&o$-')qqN3\xa9\x1b\x1f\xcd\x92\xf3\x1e\xd7\xdd\x86 9~\xe8\xb4\x8d8Q\x9d\xf2\xccN\xa9Q \xdf\x93=\xd1\x1e\xc95\x01\x8e,\xfb\xbdwN\x0e\xab\xaf\xb8\xfb\xd4\x159 ?p\x1e2\x1a\xa1\xa6\x04\x0b\xa2\x0c\xe3\xe7\xcd\xbc\x1b\x84e\xd3\xe9x\x14n}S@\x0e\x89\xbb#\x0e=5\n\x03)\x81\x88\x9b\x88\x0b<\xa2\x80\x8b\xc0\xe6\xf7\x05\xbd\xe3\x8d\xe3H\xf2z\x1dNb\xdc\x99^u\xcd]Y\x8a\xe6\xd58\x00\xe5\xdb\xbdp\xd4\xeeJ\xcb\xd3\xe8\xcb\x17\xb2%\xe8oZ\xd2\xdf\xba\xce\x12j e$\xf5\xb2\x07\x82\x0d\xa8\xbb\xb2\xd5\x0f: \x95\x11\xbd\x8f1\xa9N\xd1\x1d\x87\xc5\xaf\xe0\xad\x96\x91\xa9\x00\x9a\x83\xe3\xd70\xdf\xa6\xe3\xf3\x96%\x0b\xe6\xdfit\xba$OX9\xb1_/\x8b\x02\xed\xacf\x8b\xf3j\xd2\x85\xa1H\xc1N\x1a\xcb\x08\x1b\xd3\xcd\xa6oKV\xb9*\x07O\xcc\xc8)L\x0b>\x81\x06\xa89}f\x0d\x9bL^\x90\x9e\xe6\x97\xa9\x97\x04\x97\xfd\xe7K\xb5\x1d\x97\xa9\x89\xc6\xe4Q\xaa+\xed\xd3\x86,\xb9)\x1a\xd1\xb7\x0d+p\xbeQ\xffZ9\x1ef\xe2\x81q\x1f8.\x92%\xdc\x92F~\xa8\xa8\xe2\xf1e\x10\xf9\x90<\x18\x0cI#\xdbE\xfc\x8c\x10\xb47\x9f*\x1f\xef\xd5\x9f^=qu\xb3\xaa\xbd\x13\xecd\xaf\xa6\x15\x92\x83\x97\x81\xff\x96\xe7Q\xe7]\xab~\xe0\xa3\xe64\xb9\x9b}\xef\xe7 \x0c?2\x8f\x05k\x84\x93h\xfb\xf0U\xcbN\x90[\x0c\xdc\xc3\xa8\xb9j\xf2@M\x7f\xe5\xfaik\xea\xa7hu\x9b\xd1\xf9\x84\xcc\x94)\xb3\xe8\xd5\x8e\x02~\xa3\xaf\xd7\xb17h\xa5\xd7\xcf\xc2jz\x15c\x18\x19\xb6q,\xb2\x9b\xecd5\x7fm\x9c\xf7?0\x16}H\x98GC\x0f\\\x19\xf9\xca[\x7f\xadi\x06H\xc0#\x10\xa3T\x1b%o\xe6\x99\xaf\xb4\xd4\xab\x99v\xa2\x0b\x01\xaa\xf1%\x0d-|\xfd\xd4&\xc6\xc4\x04}\xa7\x06\x14\x1fk\xfb\xb5\xcf\xa1VCY}\xf9[\x02:\xb9\x07\xc6\xd8\x8eK\xe9Z\xfb\xd9\x07\xec\x8b\x14'\x00\xd1\xd9\xd9L]\xe8\xaa\xc4\xc3m\x1c]\x9f\xea\x08&\xcd\xef\xa2\xf2\xebO\x96\xdcl\x00M\xcc\xab \x1a\xc7\xe1\x8dk\x11\xe2`\xcfW\xe2\xd1vo\xc6\xb6G}s9\x06y\x9a<\xb0\x97\xbdk\xb0\xcb\xb3\xccGQ+6r^\xee\x8a\x0e\x8aI?\xb0<\n\xe7\x9a\xfd\xcaDp\xd3\xb5\xc4\xc8o|\xb7\xab\xd1\x18\xf4\xc7#\xedb?\xd2k\xa8z\xe1\xb4T\xef\xc0~\xd3l\xca\xb4q\n\xc8|\xbe\xb6\xaf\xb8\x16\xe9e\x1f\xbc\xb5`\x99\xb4\xb7\xf2\xb5zu_\xec\xa59\x8c\xea\x15\xc7\xf5\x908g\x9cP\xcfci\n\x97\x12W\xb2\xfa\xe2\xf6kHnxN\"\xc6|\x92q\x88\xe0\x1f\xcco\xc8\x1fD]kNI\x96\xe4\x8c|%T\x16\x9f\xf3<\xc9\x96\xc5\xe50\x01\"\x12\xeeF\xe0~q\x00\xf7HcgP\x1c\x04\xf3t|U\xedQ\x9fq\xe8\xa7\xda\xa5\x1f}\xcdi;\x10\xdb\x11qT\x96l\xae\xab\xf6\xa2\x81\xf9\xd1\x96\xe5\xdf^\x0b\xad\x9c\x02\xb6=\xd7^G\xae\xeb\xa8\x1d\xbd\xf6\xdd_\x1cw\x16\nb\xd2AAL\xfa\xef\xfc\xcd(\x08\xaa\xefih\xbb`-\x95{\xbeuX\xc2\x8e0Hp \xe6\x80\xf5R\xad, /e\xba\xce\xc8!\xd4m\xc2\xb6\n\x88:\x84\x84\x1e\x12\x1d\xb1\xfe\xccU\xb4D[~@\x0ee=;dJ\x803u=\xbd*l\xe7\x8a+x\xa7\x10`\xe7UXT\x82\xe2\xb6]\xc5\x16L\xf2\xd6\x96\xeb\x81\xd6\x07\x8c\xe6\xa0\x18\"\xab\xe8\xc1\x95\xbcqN\x0eIN\xa6jY6i\xc8k\xa5\xf9\xc1\xd5\xf5\x99\xca\x01\x1e#q\xff\xf8\xda$\x95\xbb\xee\xd3d\xe0\xe9\x1a~\xc2#`\x10\xc0\xfd\x03\xd1\x88TX\xc7j\xc5\xd5U\xb4l\xac^um^\xb5\xdf\xaf\x16Z\x93\x03\xe5!\xe0~\xb4\x1e\x87v\xa5\xbez'\xc1K\x90ti[\xdcR\xd5\x8f8\xcd\x98U-\xea\x9a\xc7KR\x83\xa9#\x19\xb0>\xd4\x1a\x83\x82\xd3L\xd4K\xf9\xe5\xda\x81T\xa8G\xf2\xb2j\x9bj\xa44\xbf\xddyN\x02\xf2\x82D\x85zf\xb0\xbd\xdd\xc4\x91\xc0\xd3p\xa5\x194$\xd1,8\x07a\x12\x9b\x89\x9f\xe7\xf2\xeeE\xfe\xb6\xb6\xad\x18\xac\xda\x0e\xf9\xb6Sh\xd9\xe7\x05\x00\xca0\x1b\xd4|\x02\x82\xce#\x00\x06\xdb\x7f\x9e\xa4\xf2\xbc\xe9\x89&\x957\xc2\xa7J\xb4\xd6\xd1[(QV\xd0J\x83\xe3#C\x0c\xb9\x08\x8e\x04\x1a\xd6\nv5\x12\xaf\x17\x94\x1aw8v[\xa0\xcaS\xd2\x0e\xb4`\xd9\xcb^\xb5\x01`\x12\xac\x99\x0fd\xd5\xab\x84\xaf:J\xac\x82\xeb j\xc9/\xceS;H\x06\x8a\xdf\x08+\x8dh\xe7f\xd6\xf1\x8fZG@\xee\xc3\xd6f\xca\xed\xdc2k4\x0c\xc1\x05E[~K\xf9B\xf7\xb8\x0d$\xc8n\xfa\x0e\x85\x81\x0b}6\x0f\"V\xa0\xa0\xe6\xce+A\x17,3\xb0\x15\xc4\\k\xc2s\x1b\xfc)\x98 %\x02[\x89\x97,\xf5\x92 \xce0^\x8fV\n\x19\xdaMMPA\xcaPAEP\xa5'\x85[\xe9\x17\xb4H\xea\x86C\xe2\x0d\xc9\x1cCD\xa0['\x0d-L\xcd:\xcf\xc6\x8e\x0bx\xd4\x0eG?\x023\xc4`g\xeb\xb5\xf0\x12\xb1h\x7f\x0cX\x1d\xb83hc,\xda\x88\x16\xc1e+\xe2S>\xb8\xf8\xb0}\x8a\x13\x1d\x1d\xd8\x17\x84\xb1G3\x97\xbb\xde\xc0\xc6\xe5\x14\x87\xdbR\x9e[K\xf2\x82\xf8\xc5\xb9\xb5\xbd\xbd\xec\xea\xb8 \x1b\xfc\xd9\x121+\xd0\x8fRN\x9e\xad\xc1a]\xa6\xfe\xcfE;\xe7\xb3\xf5\xb9\xd5o\xbd~\xc4WV`\x1f\xee\x0d\xc9\xbaC`\xd8O\xfc\x1a\x89\xb1_\x0f\xc9\xaaC\xf2e\xcaW7\x16\x83\xa1\xa9j\xa56%\xfeMp\x14\xd48\x12\xab\xde\x97\x12\xb7\xd7Y\xd8\xed\x81\xa2^\x1aL\xd1\xf8\x90\x04\xb8A\x9a\xd6\xdcn\x0e:\x084\x9a\xb3%\n\x18\x96\x08\xd9@\xc6\xbaeWD)\xaf\xbe\x0d\"\xf0fH\xd8\xb5\xc7b\xd8\xcf\xdc\xf3\xf2$a\xfes\"\x9a\x9f-\x19\x89x4Zi@\x9f\xad \x8b\xd6A\xc2#\xe0\xab\xc5\xa2\x06\xc9^\x1e\x86\x04\x82\x9a\x92\x15KS\xba`\x84F>\xa1\xbe\x0f\x11OhH\x96,\x8c\xe7yH\xaeh\x12\x05\xd1\"\x1dc\xda\xe2,L\x99eQ\x89>\n\xcehV\x1f\xa6s\xbb\xe0\xc3\x83\x9d\x86f\xbb\xd5\xa1\xc8\n\xbf<\x0f\xff#}\xb8\x18\xf6\x13\x1d\xeau3\xf3\xb6\xb7\x9b\x01\x1c\x88d\xfa\x07\xd2\xee\xe1\x808\xaf\xa35M\x02\x1ae\xe4\xa7\x80K\xe1\x15b\x00\xd1H\x91\xf2\xact\xd2\xec\xcc\x1f_\xf1\x1d\x828Hi\x02\xea\xd5\x87\x89\xd0\xa4#\xa8l\xd8A\x95\x13C}L\xbaE\x91\xf6\xd1!\\k\x83<\xb04\xaf\x9a\x0c\x86\x98\x8d\xff`Hr\xd1QO0d\xa0h,\xc5o\xa2\x7f\xdc\x8d\x86\xe4\xe9\x90\xa4\xd8\x01T\x1c>s\xe3;\xcf\xc9|4z> \x01\xa8\xfc\xcd\xe6\xe7-R\xa2\xeaR\xb3\x99\xdd\xa2\x0b\xcf\x1c\x8c\xde\xbe\xe5\x8a\x06\x8b\xae\x8d&C\xa2E\xbc0U\xe4\x90\xec\x80Nvy|F\xe4\x05I\xe0\x86R\xe9\xd2\xb9l\x16\x9dK.~\xf0\x1c\xa7b\xea1V{o\x99\xc6\x9a\x96;\xe6\xc9\xa3.{d\xac\xab\xa6\xec\x06\xd6\x11w\xb3AE\x90u?\xad\xdb{\xba\xffo\xd1\xbcF\x88t\xd9\xbcI#\x02\xbbB7O\xea\x88\x82vK\x07\xba\xfa\x89\x9e\xad\x89\xcb\xca \x8eA\xc3\xb7\x91\xbe(\xe2\xa84D\xac\xd3\xd9\xb9E\x9e\x91\x835\xd0\xc0u\x0c\x1b\x0c\xa0\x88sP\xe0\x83\x8b\x00*\xe5\x13L\x9c\xfc \xd1\x8e\xc6q\x9e.\xdd\x1c_\xbb]\x06\xb4\xdd\xbb\xae>\x06\xba\x7f\xf5^\x14Hr\xeb\xa0.]%\xd5\x9d\x1aDj^` 3\xd9\xfe\xba\xaa\x9e\xc6\x81\x9b-\x9f\x8e\x88\xdb\xdaM\x1321\x1c\xe2j+c\xb3\x83\xaay\x8f\x8c\xebdx\x95\x14i8\xd3\x05\xd4>R\x8f\x14\xb9B=\xacR\x0ff%N\x943\x81\xa0\x9c\x90\x03Q\xf5!I\xc6?\xe4\xf39K\xc8T\x99}\xdaX\xb3CB\xc74\x0c\xb9\xf7)J\xe9\x9c\x15\xf0\xd5A\xee\xbd\xbb \xa9;\xed\xd21\xca\x91\xc3`]h\xa4+e\xe4\x06\x04QL0\xdc\xc6\xb8\x11h\"\xb3+\x02z\xdez\xe1\xa3\xba\xe3\xc5\xc7=\x1e\xdf\xb8\xc9`h\xf52\xf7uP\n\xf2\xdc\xc9\xde\xa3A\xe1\xeek\xf3-\x80\x0c\x88q\xe64\x1bi\xf4\x1d\xd9\xe9\x99TP#\x07\xe4(I\xa8\xe8\xc5\xa08\x99\x9e\x0fH6\x8b\xce!0|t~\x1f;\xa2\x13\xdfO\xf6\xefr\x1c%\"\x13P\x9d)+\xbc\x9f\x96\xed=\xedt\xdcqO-\xab7+\xba\xff\xa3C\xa3M\xfb\xa6H\x14\xabQ\xdd\x05\x16\xc9\x8a4\x82\xd5B\x13\x03\xcf\xccv\xce\xe5\xa9\xa0\x8f '\x88|v\xedH\xcd\xe0d\x0co\xd0\x0e\xf85$\")\xce3\x95\x14\xe7YeSm8\x93\xbb\xbb8\x93\xb0\xff\xb4N\xae\xabS\xfb)\xee\xdap\xff\xe9\x1e\xca%\xec?\xad\x9f\xf2b\xd4\x9d\x99D\xb8\xdaQ\xc0\xb9\xd3d\x19\n\x98\x974cu\x00\xcf\x04xK\xe3z\xfe\xdc\xcc\x7f\x07\x8eD\xea \xb1 \xf2\x91-N\xae\x1b\xb5\xf8&\xc8)\xcb\xea\xf9\xcbJ>Lm\x1dd]\x01\x01\xe9_\x1dde\x82\x00\x86\x91GF\x1dnQ\x1b\x14\xfaS\xc0\xae\xea@7&\xd0\xab\x90\xd3lo\x17\xea\xac\x03^6\x00\x9f\x01\xd4\xb1\xbbA\x1d\xe2\xef\xc4Z\xd3\xde\xc65\x89\xbf\xbb\xbd\xbc\xe7j+a1\xd6\xb7]\xa9\xfb\xb6\x1b\x90G\xf8R\x9d<\xc3tk\x04\x1b\xdbzH\x90\x9aL\xcd\xc9\xb8\x143;-\x91\x0c*^\xf5\x9aHH<}<\xfb)\x83\x07\xc1~\xe0\x00\xa6\xbb\xbf\x06@\xcd\"V\xb0i\x01\xbe\xf3\xf0\x18`\xdd\xbb\xc5\xb2O[93\xbd\x04,\xab\xa4{\xe3j\xd6h\x7f\xa76\xb2bYL\x9e4\x97\xc4K\x9a\xb1q\xc4\xaf6\xc5:\x9a\xdeA&0hj\xbf\xf5\xe9\xfbZ;\x02\xb5\xf9 \xc8\x01{\x8e\x88K\xc9\x08\xf5O+\x98L\x88\x86#\x0e\xa7\xef\xc9\x0e\xf6\x15\x0d\xb7\xbd\x9d\x91\xef\x0fHapnx\x8e\xdei\xaa\xd4}\x95\x1a\x82\x19\xae\xd7W\xdb\xb8\x9a\xcd,j\xbc'\x89\xe1\xe4\x11.\xe3hluEn?\xc3\xc9\xed\x06S\x9a\x93\x03T\x0d&\x85\xf4\x86\x16L\xd8}\x95Y-\xe0\x011\xde\x89G@ \xdb\xcd\xe0\xf0\x92\xb1\xbb\x80\xc6L\x95\xd6Os\xd8\xc5\x94\xa0\xf3[\xd5\x0c\xc9\x06$,\xf1\xb1\xe6|\x80D\xcafQ\x1d#[\xa8+o\xb3\xa9\xda\x7f\x86\xc7\x93\xd8\xdb\xe9\xbe\x1a\xb7R\xbc\x05\x08v\n\x13\xe3\xfb\x18iG\xf4\xbahU\xa1\x90\xfc\xaf$\xbf\xa2YPeL\xec\xbbR\x14\xd9\x85\"\xbb\xe7\x16\xc5\x10\xa2\xe7\x85\x1aW\xd6\xda\x9f;\xea\xe6Ip\xdan0\x1a\x81mu\xd1\x06\xa9Y\xcf]\xf3`\xcd\xe5U\xb4l\xfc\x0b\xb2g2\x06T\xdak\x81^c\xb1p\x05\x95A\xb6\xb7\x13\x08\x16h\xc3\x12\x9aP\x8ef\x89E\xf5\x1d\xcc\x95\x81\xdcNe4\x8f\xa6\x92\x92U\xb8V\x0bip\xeb\x83\xbeyp\xab\x95fa\xc2\xf7\xf6m\x11\xe5\xfap\x83\x81\xab\x83='bS\x92m\xe28\x1b6\xbd+\x12\xcb\xfe3\x1c\xcb\xed?{j \x1bWo+\xd8/\x03j\xf2xH\xaa\x8e\x8aB\x9a.e(\x882\x91\xe6\xd9\xb2\x9a\xb2\xe4i\xcd\xfd\x8f\x18\xa4&\x8cR\xb0\xae86Jku\xa5\x8c&^-\xed\x1f9Knj\x1f\xa0\xd9\xb2Y\x9dH\xad} asRs)T.\xb2l\x0c!P\xc9\x01\xb9\x1c\x92l\x9c\xb0\x94\x87\xebN\x97\xaejr\xc1\xc7\xdd\xd6\x04\xfc\xba\xe9\xa2\xa6\xaf\x9a\xafF\x95r\x1f\xf5\xac\x98\x91C\xb4\xf2b3V<\xac\xc3g\xe6\x0eRIl*y\x16H}.\xad\xd7D\x15\xdf\xf9\x01D\xe0\x96_\x81\x18\xcb\xa6\x1f\x0f\x99\xac\xafZ\xaa\x0d\xfb\x94\x88%\x15TW.\x85\xd0\xc1\xee\x8c\x8e~\xdf\x19=\x1bo\x8f\xce\xb7\xa7\x83\x87A\xf3\x98}8\x9d\xed\x8c\x9e\x9d\xff\xe5\xcf\x0f\x9bG\xed\xc3\xbf\xbb\xbf=\xfc\xed\xe1\xa1{\xb8\xf5\xdb\xc3\xc1\xec\xef\xbf\x1d\xfe\x96\x9e\xffe\xe0\xfev8\xfb;\xfc:\xac\x97\x02\xb3\x04\xe7\x0fgH\x9c\xaf\xe2\xcf\x17\xf1\xe7\xb7\xdf\xc4\xdf\xbf\x8b?\xff\xe5\x9ck\x03\xa1\x99\xf3B\xa4|\xef\x0c\xc9w\xcew\x90\x07q\x80E\x81\x04\xfeF\xf07s\xce\x07\xcd\xd3{\xe6|WV\x15\xd6\x00\xe6\x00\xf0\x1f\xa2\xf8C\xf1\xe7P\xfcy.\xfe\xfc\xaf\xb2\x90W+\x14C\xa1\x12\xfe\x7f95s\n\x1fFd\xb6-\x87\xf4h\xf4\xb7\x8b\xd1\xf9\x1f;\xc3'{_\xeb\xa3\xb0T\x83\x8f\x80\x0e\xdc\xf1_\x06u\xf85ja\xf8\xdftM\xa5!\x1b\xce\x958\x06\x80\xd3\xe0(j\xd6{\xabo\xff\x89\x05\xfa \x88\xcb\x84V.r,\x86\x89s[\x99\x05\x8f\x976\x83\xc8y`\xe3\xdf\x1ch\x84\xd3\x92\x99Zs\xe7-%Uk\xacEE\x83:\x87\xedF\x9d%\xfb\xe8Yri\x93q\xfc\xff\xec\xbd\xeb~\xdbF\x928\xfa}\x9e\xa2\x84\xec8@\x08R\xa4\xe4+mZ\xeb\xc8\xcaF3\x89\xedc\xd93\xbb\x87V\xf4\x87\xc8&\x89\x18\x048\x00\xa8K\xc6\xdeg9\xcfr\x9e\xec\xff\xeb\xaa\xeeF\x03\xe8\x06@\xdb\xc9dv\x07\x1fl\x11\xe8{\xd7\xbd\xab\xab\xe8\xfa:\x17<\x06a\xa6\\\x8d\xc9\xbc\xa2S\x95\xa6\xe4\xb5\xd2\x1b/4R\xa7\x94(\xb7\x1a@\xdde\x0e\xc7\xa1Q)I\xe9\xdb\xec3\xe2\x12\xbaF,-)\x05^\x05i\xb0f9K\xe1\xebm\x1a}M\x19\x05.\x19\x04\"gU-\x81\x80\xc9Q=,<\x01_.\\\xe7\xc81(s[\x94Q\x8b\x14g\\h\xd3\xea|\xe5xp\xc4\xe9\x02\x8c9a\xa8\xd7\x8f(S\xc6&\n\xf3\x9a\x97z4\x1d\x9e\xc3\x04\xff+\xaeV\xbd{\xb7\xbfD\xf2d\x18\xf0%\xa6\xfb\x99@4\xf89 \xe3Z{|\xf5x\x91\xcbA\x9e\x86k\xd7\xf3a\x0fS\x8d\xcb\xb4\xc54\n>\xe6\x06\xf3\x17\xef\xe7\x02&\x90\x91#\xc3\xa5Ew\xbd(\x07\xf0\x16\xcc\xff\xb2\xcc\xf9/\xeb\x02\xc3\x05J\xc1\x17\\\xf8>\x92\x81\xd0\xa4\xd4\xc1\xdfV\xa4\x8e\x1c\x8e\xe0V\x80\x9bV\x18\xc3\x96\xe6\xa9;\xf2T\x10n\xe3\x07(\xa2\xad\xc9N\x1c\xa7\xd2\xc5\xdf?\x8a82e\\\xac-\xfe5\xd7\xd6\xcd\x8b\x82\x91\xffl\x8by\x02\x13py\xe5\xeb\xe9\xf0\xdc\x1b\xe4\xc9\x0f\xc95K\x8f\x83\xcc\xe8>^\x15\x08O|\xa0-\x15\x13\xbb\xaey\x1f@m\xb4x\x19\x81\xab\xa6\x18\xc1\xf0r\xb0\xc6H\xea\xfb?q\x96=\xfd\xe9\xdf\xdf\xed\x9f\xf7\xfe]\xfc\xbfo\xbc\xef\xca\x87\x8dn\x83\xfb\xfb\x0e\xc2\x8e\xea~\xe8\xc3\x81a\xd4{7\xd4\xdd\x9d;\xb0\x9e^\xe3\x8dZ\xb74\xec\x03\xaf&\xd5V#\x91\xd6\xe7\xb0\x87m\xf1-,\x9a\xdf[N\xaf\xcd\x97t\x95&}\xe6\xc3\xb1\x8f\x9e\x87\xfd\x91\x8f\xde\x82\xc3\xc7\xf0\x0c\x9e\xc0F]\x85zfNP\xc6\x1f\x81\xec\xeeK\x1c\xbeD\xf4\xcd\xf4\xd9\xb9\x88/\xdc'tz\xcf\x87\xf4\x12\x9e\xc0{z\xcd\xfb{iP\xaa\xb8^J-\x1e\x13)\xa1\xcaGpY8\xffpJ\xf2\xef\x98\xa9\xbb\xf6\xd2\x87\xf7\xa2\xdf3ZO\xbcw0\xf4\xe1\xd8S\x90\x81\xaf\x8e1\xa1}YM\x98\xb3Y2go_\x9f\xaa E\xee\x99\xe7\xc9\xb5\xb1(\xbd\xda\x82-\xba,\x18_\xf2\x97\x8f\x8bi\x96\x17n\xf1y\x0bG\x15d\xb1K \xfce\xddG[\x95\xf7\x95Uy\xef)\x12\x94f\xec\xfb$\xcb]\xaf\xae\x14\x95\x7f\x7f\xf8\x00\x8e%\xb3\xd6+<\xd7&\x9c(U\x12\x8e\xe7\xce\xb9\xe9[\xe9\x974'\xf4adP\xd5\x11\xec_\x99\xef\x81+\x00\x7fS\x1d\xb2\xa0\xec\xfb\xef\x06\xfb\x9e\x0f?r\x82\x83\xbb\xe8\xc3\x1b\xb9b\xb4\xa1?6\xee$\x88Y\x9e\xc2\x04\xdeL\x9f\xb5\\\xa2?Et<\x15\xd4e\xdezq^\x0d\xffgA\x85_\xd0\x10_\xc3\x04N\x15\xa0\xbd\x80'\xf0\xfa1\xbc\xe0\xa3<\x1d\xccVAz\x9c\xcc\xd9\xb3\xdc}\xe1\xc1S\x18\x1d<\x80#\xf8\x19z\x13pn8\xcf\xc5?O\xa7/\x1a\xc6\nrY\x7f\xee\x97\x8b~ \x19\xc2\x198\x1e\xf4\xe0\xd2\x80\x15\xcf\x8b\x12\xedc\xb9LY\xf0\xbe\xb1T\xdd\xbc\xd4\xfc\xa5\xfe\xd6\x88GO\xe1\xe0\xde=\x99\xeeA\x1b\xbd\xe3H\xc9\xc0\x86\xe8eV\xec\xc3+-vvQ%\x1d\xe4\xc9\xb3\xb3\xe3\xd3\xd3\xf2\x17\xd3\x05b\x0e2\x7f\x93\xbd\xa0\x15\xe6\x08\x9c1\n\xa1\xea\xcd\x98\x83\xbeq\xbe\xdfu%D:\xe9\xfb\x0ez\xf07]\xe8\xeai\x8d\xf0))\x01\xc8\xba\nRb\xf2\xcd\xeb\xdb\x07\xce\xbb9\xccp\xea~)\x08\x9d\x06H\x97^+\x1f\xbf\x9a\x9e\x9c[.E\n:\xc5i\xd6\xac\xe06\xad\xa4\x8a/\xf5/\xbc\x8e\x95L\xf1\x8e\x05//\xb8\xd1/\x8d\xa8\xcf\x1b\xfd\x96\x8b\xd8q\x8dm\xfe\xd2\x80\x02\xdf\"\xc9\xff\x05\x97\x05\xabg\xb3`\xc3x_\x8a\x17!y\xfe\xc5#\x84\xfa\xd6L\xde\xeb\xf0^\x97A\xffR\xe2\xad\\\x92/\x18\xef_\xb4\xbd&\xcb\x9e\x92\xbe\xfeR\xe1\x8aC\x1f\xfeR\x05`\xde\xfc\xf7\xe5\xe6\x8f\xaa\x88\xaf\xad\xe9\xf7u\xf1]u\xf7\xbdW\x11\xb1\x8b/RH)\xc6*\xcb\x94\xa4||\xe9\xd5G\xfd\xfd\x8eb\xfdeQR\xd3A8\xb1[NO\x10\x90\xcb\xb8\xa1\x82w\xab\xd2\xa6\xfa\\9\xabj62\xbb\x18\x0d\xc8\x04e\x05e\xd0\xea\xd8\x04\x8d\xbf\xaa\x88\xb54\xc1&R t\xaf\xbfA\x0f\xfe\xda\x80\x89\xba\xba&\xf43\xfc[\x1a\x16+JP%^p\xdd\xc8i:eU\xd4\x05\x05P\xc3\xa0\x992~\xe2?\x06Lc\x9e\xa7\xc5\x199|\xb6\x1f\xfa\x9c\x88\x92 \x7f\x02\\N\xae\x03\xae\x8aM\xac4'\xec\xbbNhc\xf3&\xd4\x0b\xa6Z\xcc\xe2\x95\xadPh *\x1b @\x96\x87YP\xed#2\xcb\xdd!\xf5\x14+\xe6\x18#\xc1*\x9c\xd1\xb0.\x86\xe0p\xberD\xc0\xc7r]\x0ex\xfc[\x0f\x8f\xad\xb6r\xe2\x18\xa8\xabR\x94/\x14-\xca\x16ij\x0fB>Ht7/phz\xf4\xd5y)ZOSLQ#B\x96\x89\x8a\xc7\xe5E\xec{\xab:q\xber|p\xfexp\xe8\xe0\xd7\xd4FEL\x87<\x96\x83\x18\xdc\xa2\xf2\xe1\x8b~.\xe3)\xba\xd5\xd2\x97\xe1\xf4\xc7du\xac\x18\x1d\xcd6\x91\xdcl\x16\x85\xe24K\x1b\xa1O\xd4\xb0\x81\"\x97\xe2\xb7`\xbb\x14\xc2\xa5\x8aQ\x9e\x8f\x14e\xf8\x18\x02x\xa2\"\x84>\x86\xc0\x9ef\x1d\xfdO\xa6\x81\xc9\x83q\xba=\x17\x086\xdd\x9e7\x8c\x8eB\x93\nQ\x02\xbd&V>\x97\xaa\xc9\x96\xc89H\x11\x0cH\x1d\xf5i\xdc$\xae\xcb\x0eL\xe1\x1c\x85\x82\x90\xd4\xba\xd1\x9c\x93\xd5\xc3\xac\xa2Uu\xf8\x18\"x\x02E\xd6\xf9\xa8Y\\\x9c\xc1\x04\xb2id\x11\x17\x1d9\x16B\xb5\x19\xe1\xf1tF\xd1\x08f\x06\xf1\xd5z\\\xbe\x9c\xc6jf\xe2:zI\xc0\x88\xcb\xd2E\xacNN\xeb2\x86ya[6\xadXW@g_\xf5\x8bHU\xd3\xa2\xa3\xb4\xbe\x9c\x16u\xcem+Z\n\x96T\xdd\x9e\x0dm\xcf\xa6dB\xda\xb4\x1b\x1e0\x04\xf1t\xd3\xa0\xcc\xc7\xd39\xed\xc8\xdc\x12K\xcc\xf8\xb6\x11L;l,\xa1\x82f\x95-\x16\xc8\xe7\xb8\xc09\xf8\x87\x0f\xb0./\\i?\x99\xfaQ\x9f\\CD\xb7R@D\x97U\xc4\x16O\x9a\xf4\xf7\xb9\"\xb0\xd2X\xee\x9e\xcb\xa4\x8a\xb8\x1a\x90=\xc0\xabEx\x92O1\x83\xa2\x162*V\xd2E]V\xd6\xaf=$\x07\x1c\xa8VB+\\)\xe3\x03~]\xe9\xfe\xf8\xf5\xcf\xa5\xf5Y c\xc3\xbe!\xdf\xbbmC\x94\xf0\xcf\xc4\x9f\xbcM)\xff3\xfa\xcb\x17\xd8G4LL\x93+\x0b\xb14\x922\xfc\xc3\xd7\xb1tR\x999\x13\xeat,}+\x18\xfeQ\x9a\xc2\x87\x0f\x107H\xff @\xfc\xaa\x8c\xe8\x16\xc1R>x\x04\xd8\xa2\x03\xf0G\xd1\x90+\xe8\xc1m\x87\x05T\x18\xa1y\x99\xe8\x02\x91\xa2\xd4\x9f@\x83\xe4IU\x99\xce9\xe2(\xa1x[H3\xf5\x05\xb8(\xed\x173\xb6\xc4:\xb5t\x0d\x13\xb8\xe0\x8d\\\xd2\x16a\x9bD\x17E\xedz\x9d\x13\x98\xc0u\xfd\xf5MmR\xdad\nL\xe4\xfdL\x0d\x11\x17\xcf8\n\xafJ\xb4\xa0<\x90z\x1b\x1a\xb9\x06:\xfc\xd0X\x8bA9?\x13\x1c\xa5\x84\xa7\x1a\xdc\x92sN\xb1\x08\xae\xe0\xe77\x1c\x81\x8f\xe8\xbf\x89\xfc>\x86\x1b\x85\xb0\xf4\xca\xf34t\xe2\x0d\x97YM\x99@P_\xac\xdc5\xabu\xbd\xa2\xaeW\xd45\x93]\x17\xb4\x82\xa9\xae\x15q\xc2\x0c\x7f>n\xedu\xad-D\x135+^\xef\xc23\x13\x01)\xca\x90R\xa6\xba\x8e\x15\xb6[ B\xa9.\xbe<\xd2\x7f\x8c\xb5\xba>t%T\x1c\xbc*WY\x903\xf0\x8d]\xa9\x13[<\nso\xe8*\x8b\x0f7\x83M\xb2\xe1\x18\xc9\xdf\xdcH\x17\x96\x95\xd7\xb5[K\x7fx\x08\xffb\x1bE/\xd3\xb71Et\x9e\xbb\xb2\x19\xa3|\x8c\xe0\xe7\x95\x17M\xad\xfa\x8d\xe4A>\xb8\xaf\xb8\xd2\xbc\xe7\x16@H\x7f\x15\n\xed\xbf;\x1eyD\x17\xdf\x04b\xfc\xbb#\x8e\x92\x14\xf1~U4\xac:+\x0d\xe1U\xc1\xfd\x1a\x88`\x87\x85\xf2A.\x89[`=\x8eF{/\xe9?\xdf\"E\x93\xb5\xf2p\xa4\x13\x901g\xa2\xa8\xb1\xc9\x11\x1c\x15\x83\xc1\x8f\x9f*\x02\xee\xdd(xQ\x93\xdcT\xbd\xf6J\xbd\x8a\xb1\n\xad\xb5\x18D!\x9dJ\xd2\xd1*\xe9+\x99\xe5\x98v\x1e\x8dw\xfd\x91\x87^\xb0\xefiA\n\xca.\xff\xba)\x0c\xfaB_w\x06\x84e\xc7\x88q\x03\xf9\xcb\xd3\x10\xf0X\x9c\xef\xfa\xf0\x12\xfb\x92\xb2\xe6Kx\x8a\x12\xe8\xcb~\xdf\x03\xd9\x0e\x1e\xc0\xdeL_\x9e{\x9c\xd4!L\xcd\x98\xfbR\xdc\x7f+:\xe0J\x7f\xf9\xb3O\xa6\xe81<\xc3\x81\xd5>\xf6\xfb\x06Z\xbcG\xe7\xd5'\x16\xc3\xf7c^\xed1<\xf34*\xcb\xc7Pi\x89\xb2\x10\xead\x9a\xaf\x95\xb8\xfb\xf0\xf0\xfe\xdd\x07fM\x8ck\xfc\x87\xf7\xcd\xdff\x18f\xdc\xf8\x89\x83\xf9\x81\xa5\xda\x867\xf9\xd0\xfcm\x0e\x13xP\xbd\x13'\x1f\x8ez\x0f\x0e\xcc\xdf\xb8n9:\xb0\xb4\x8a\x91\xf1\xfa\x16]s\x89~\xc97q\xbf\xbfo.\xc0\x05\xa1\xfd\xe9O\xefn\x0e\x86\xfdw7\x0fN\xce-\xe5.\xb1\xdc\xbb\x9b\x83\x93w\xdb\xc3\xe1\xf0\xe0\xdd\xf6\xbb\xef\x86'\xfc\xdf\xfb\xa3\xf3\xfd\xa5\xb9\xd2\x855\x8f\n\x7f\x92+\x96.\xa2\xe4z\x0c\xceK\xf5'Em\x8c\x19\x9bgp\x1d\xceY\na\x9c\xb3%K3\xc8\x13\xd8\xa4\xc9\x8ceY\x83b\xed\xc4I\xde\xbf\x0c\xb2p\xe6\x8c\xc19\x8d\"\xb6\x0c\"\xd1*\x17\x1dn\x1e\x0e\xc1\x8d\x93\x1c\x02\xc0R\x80h\xb4I\xc28\xf7\x9a\x9a\x0d\xe3\xab \n\xe7}l \x9b\xa6\x17\xd4\xb49\xf1\x9d!\x9d\n\x08\xc55\x82>\xcc\xcc\x9f\xb9\x8e\xfac\x90\xaf\x06\x8b(\xb1\xe5\xae\xe4:\x01\x19\xb5\x07\x8b4Y\x1f\x0bo\x1a\xcd\x9dX>\xca\xad\xf8\xcc|<\x00*\xc6\xfe\xeb ^\n/\xdc\x8b)3\xdaE\xed\xad\x1f[o\xd4A\xd5\x1e\xaeB\x85\xa2I|z\xfe\x18b\x0c\xc4\x9eR\x84X\n]n1hI?\xe5\x9d\xc6\xf6\xbeql\xc5\xb0\n\x89\xc2\x0e\x07\xa9\xe1\x00P}\x93\x02y!\xef\x82<\xf8\x89\xb98\xd5\x03\xf4\xfbC\xceON=)\xf4\xe0\xd8\xa5\x13Su\xe6r\xe9s\xc9\xd6S6@\xca \xeb\x15N;;\xcd\xfe\x99}\xdf\xd5\xb6P\xac\x06\xda\x0e\x1f\xaf:\x0d}\xe1D-\x05\xef\x84\xae\xa9\xb9\xa4jk\xee[I\xaf\xe7y\x1c\xb5\xee\xdd;xt\x9f8\xc7\x93 \xdc\xbb\x7f8z\x84R\x0b\xaf\x08G\xfc\xc5\xc1\x10\xe3\xa2\xdc\xbf{ot\x00\xe24\xad\xde\x96G\x01\xce\xb8\xbc\xea\xba\xa3\xe1\xc1!\xdc\xe1\xbb\xf7\xe4 \x8c\x86(\xc5\x88w1\xffq\xff\xde\xbd\xc3\xfb(X\x89*9\x17\xa0\xb8r0\x06\xf5\xe6\x0b\xc2\xd2K\xfbj\x8a\xf6\x10\x13\x9a\x8f\xe4\xe4#O\x9el\x00\x05\xfa\xbd\xa1\xa78\xd7{\xa0\x0e}\n\xa3!\xdc\x01\\\x9e\x0f\xb4\x1dB\xa0\xa1\xb5\xff\x00b\xe5\x18\x1d*\xf2&\x0c!\xcd\x01\xcf\x02\x05\xb4\xed\x08l\xaf\x1aQM\xcd\xa5\x07\x07\x07\xd0\x83\x07\xf7\xe0\x1bp\x19<\x81\x83\xfb\x1e\xf4\xc1u\x87\x18\xcd\x0c7\xfb\xden=\xbf\xb1\xdd<\x90\xcf\x95\xb8\xfd`I\x89\x82\xb8\x80\x98 Gp\xe22\xd8\x879\x06\x95\x03\xbe\xae\xc2G\x81\xde\xe7\xdec\xdc\x8fk\xf8\x06\x16\xf8\xf91G\xe4 D\x1e\xae6\x95\xban\x06\xbb\x13\x97\xe3\xbe{\x8d~3\xf0\x0d\xf0*._\x99\x8d\xb7\xdb\xc4\x7f\xb4\xc3\x98\x86\xdaz\xce\x18L\x075\xf7a\xe9\xc3-9\xe2\x98\x8c\x9a\xf2\xb9\xd0I\xb6\xb5\xd4\xb5\xf9\x16\xbe|8\xbf\xba\xb2\x7f>\xae\x1b\xc8\xe4\x83\xfb\"(\x85\xeeA\xbd\xf6f\x82\x82\xd0\xf3\xe1\xc4\xbdF<\x86\xa7\xc0'xc\xe8\xea\x86\xf0\x9d\xca\xf1\x89\xfe\x11\xb3\x03_J\x0b\xd1u\xaf\x87\xa1\xa7n\xba\xfa\xfcA\x81\xfb/\xdd\xcb\xddp\xfc\xf4sq\xdc\x87\x0b\x9fC\x9b\xb8>QMr!\x1f\x04\xccK\xe9\xc3\xf5\x0c]\xb6\xa4\xb0\x96#\n\xa3\xa8$\x84\x83U\xc9{\xe1\x92c\\\xe0\x11tN\x83s\x8e\x9e\x02\xd5\xde\x13j\xdd\xb85\xaf\xa0R\xc7)\x06{\x99\xc0{\xd5g\xa2\xd5^{\x84\xd9\x97\xed\xa8\xc5\x91)k\x19\xdcS\x91\x81\xfc\x16\x9e\x88,\xe6\xbc\xd6m\x837\xa8h\xba\x0fy\x81\x1a1G\x0d\xf7\x02c\x82pBn\x02\xda\x98C\x12U\xe4\x84\xfe\x82\x96rk\x1a\x9f\xb5o\x10\xa6\xc7\xd2\xea\xe2\xf8{\xbd\x18\xa1\xb8\xde\xef-P\xda3\xfbb\xc9\x07g\xc6IK\xec\xa3\x8e\x1a=\x96\xc8\xcc\xd1q\xce\x919\x14\xc8<\xe7\x0b\x17j\xc8<\xc70(\xdec\x98\x0bd\xe68\xb8\x81>\x87<\xa9\xe8,\xfd\x02\x04^\xb9K.\xf3\xc2\x1f98\x0e=O8\x15\x9c\xb8\xc7\x0dF(O\xf9\xb4\x13OAj\xafW\x97\xf0\xf4\xe7c\xaf\x17\xf3R\xf5\x84S\xd0\x86\xc7\xef\x9b\x84\xa4\xea\x9b\xadU\x17\xbebi\x16&\xf1\x18\x1c4\xe6X\xb4\xd0\xed,;0\xe5\xb2\x96\x0f] \x1a\xc33;\x9b%\x1f\xb01\xbc4O\xd5b\xb4\x10\xed\xfeh\xfe,\xdb<5\x7f\x16.\xf6\xe3\x8e\x12\xb1\\\xd8\xee2\xb4V\xebv\x90\xb3,\xa7\x98|\xceM\xdc\xef;\xd0#\xd2iJ\x99-\x9f\x8f\x16\x02n\x9b\xcf\xdb8\xa4\x19w\x1b\xdfg\xcdh\xa9\xcd\xe8GW\xe6\xa6\xb9[\xb9k\xf8i\xf3\xab\x83\xac\x0fZ\xbeD\x94n\xac\xa6Y\xf9\x88qn\xeb\x8d\x15\xc1nP,g\x14\x02\xd3\xd5c}$\x15\xffC\xdd\xe3\xcf\x90\xe6\x86\xffy8\xb2d\xbb\xe9\x14\xdfC\xef\xbc<\x1f\xe9\"\xd8\xb6\xabb\xbe\xa6\x0c%\xe5\xb9\xf8\x95\xe6\xc9\x91\xaak\xf3\x16K\xab\x88\xf58i\xeb\xec\xc56\x8a:v%\"\x85vjR;1\xde\xad\xf5\x1dC\x89u\xda\xcb|@\x84 \x0d\xf8\xf2\x16z\xec>|\xf4\x88+\xb7\x03\"Kd\xdd\x97\xde\xc9@q\xaa\xba%\xf3.\xf7\xaa^+\x91,m\x8a5\xd2\x12\x99J%\xb1\xa9e\xf0\x81\x96\xb0\x87>\xd4l\xf8x\x84\x81G\x89w\x1cbzxC\xd8\x99\x18\xf2\x8a\x07\x86L\x90\xa19M1zC\x0c\x853D\xe5\xc89\xa8\xb7\x8cqE\xde\xf5\xf6+\xc29\xd3\x0ckU;\x8ct\x01\x1d\xb1\xc3\xca\x888\xac;1\xe6\xa3\xd1q \x1c\xac\x83\x9b?\xb3[\x14v0\x85\xa9zch:\xd2\xcdW\xa5\xaf\x99\x0c\xf5\x19I\xc9 \x13PV\x1bQ\xd61J\xa4\n3\x8c,\n\xbd\x9e1\x833zLJ\xa9{\xe5\xa3\xc9\x9eMg\xc5\xfd\xff-\xfaQ\x0fm\xc6\xc55\x17\xaf\xd5\x81\xa7)5\xc6\x1a\xed\xd7p\x04\xee\x02\xcb\x16gTk!D\xa9wk!\x8c\x8eEY\xfa\x8c\xc7\x94s\xf3\xed\xe1\x85\xe7\x83\xe5b\xf1\x86k\xd6n\xe0\xc3\xdc\xa3\xb0\xd3\xd39\x1e\xb4\xf3\xffI\x16[a\x1cTr\xe0\x9c\xf2\xff}X\x9d\x17\xafV\x16\xec\x87\x02a\x82\x02\x0f\x8a\x89\xe3\xf9\x97\xcc'6\x083\xfc\x9f\x83e\xab\x8by9Q\x90\xb8\xba[CJ\x19&\xb2\x1ecgw\x02\xa1\x8f9m\xf4IWYld\xf8\n\x030atO\x89\x94\xcdA>\xebpB\x95/)gTKm.)\xe5\xe9\x96a\x94\x8bE\x10e\xcc`\x8a\xa4\x06\x05>6\xe7B\xc9\xbe\x0b\xe30g$\xb1\xd0\xc1s\xbd\xbd9[\x04\xdb(ol\xc9q,@\xf3\xd1\xcc\xce\xeb\x84\xb2\x16sX\xb4l\xa7\x97\xbe\xc6\x0dA\xdef\"\x91\xc8\xb3\x1c\x7f\x1eA\xe8\x06(\x9b\xa8\x01\x046\xea\xc0I\xa4\xe1\x16F\xea\x06x\xb5\xc2\x90wW\x8c8qI\xe3\xe3\x9d\xf1\xbf\xba\x08\x92R0\x83\x9e\xb9Of\xb22\n\xa3/\x86\xc2\xb2\xd7\xe4c\xa9\xde\x1c)U<2W\xdc\xd24\x1bF\x84\xf0\xf2\xfb\xa2\x04\xe6`o&\xd6O\x0e\xfa\xeb`\xa3\xe5\x92\\\x07\x9b\x1a\xdb+\x9d\x85M\xcfKV\xcb\xe2\xb8%\xed\xf5<\x99\x035w\xd94\xe5\x05-\xfe*\xd5d\xa8\xa0q{\xcd\x81\xbfy\xbd\xae,\xf9O\xcba,\x99\xd7Y\xb6\xa1 \x97\xbfR\x1a\xd4\xda\xea\xef5\xeb*fb-\x9fn!0\xe5#\xc6\xee\x96\x82.\xe5\x82\xde\xc5\xec\x1ar\xb7\x80(\x97S\x8e\xcb0\x0e\xd2[\xc7\xf3\x8a\xd7\xcee\x90\xb1\xfbw[-\x07V\xa5\xe8\xde]O$M\xed$\xce^iY)\xcdA\xdd\x0f, \xcf\x0f\x87\xe6\x84\xe7\xf7;\x05\xf47\x1c\xc8(\xde3\x01\"\x9d1\x14\x19\x0bb\x91\xb1 uC7\xf6\xd0\xc2\xaa\xc4O_$ \xc6P\xacB\x17\x8e\xd1\xbeV\xb8\xe6 un\x81*}@\x9f6p\xc9 \x84\xbe\x8c\xd7o\x14\xc7`\xf0\x84\xe6\x81\xf0\xe0)\xad\x1a\xaf.j\xa5\x9eN\x14\xd4\x90\x13\xf4n\xc8p\xa5%\xfe5E\x84\x1f\xd57\xf3n\xdb\x86YfL\xb9\x16\xe0\x03\x84m2\x92\xde\xc0^C\xc3\x16\xed\nt2\x9b\x9bQ\xd0\xaa\xaf\xc8\x95-.\xfb\xf9\xb0?\xfd\x89\x02\xf2\xbd\xeb\x7f\xf5o\x7f\xbc\xf3\xf57\xbd\xc1\xbb\x9f.\xfe\xcf\x87\xff>\xdf\x0f\xa5m\xc5\x12\x88L\xfaw\xccVA\x1a\xccrtD\x81\x15\x0b\xe6,\x85E\xc8\xa29\xc4\xc1\x9a\x99\"h(\xf2_\xb2\xd2\x94\xd1\xda2\xe7\x8ef\x87\xb6iW\xf5msg\xa9\xb93\xc9 \xcc\xd4/f7\xba\x19\xc3F$Ak\x88I\x7fK\xbbqWL\xd0\xde\x16\x7f\xe6I\xcc\xc6\xba\x8d\xca\xe0\x10\xa8?\"6\xbb\xd9\xb0\x0b5Rk\x7fkH'%\x06\xbc\x1a\x849\x85\x88\xa7s\xf9)%/\xa5\xb7y\x92\x9e\xef`D\xab\x8f\x13\xe3\x97u\xda\xca\xc4\xbc\x95\xe8\x9f\xb8\x0e6\xa8\xf6\xfb\xe50\x81\x89\x0c>z\x12\xccV\xed\x81\xb1Us\xc1f\xc3\xe29%\xbb\xa9\x8f\x98n`\xa3G\xb5.\xab \x85\xc0\xd0]\x97\xbe\x18:\x98\xb3\xe9\xc8\xe4\x94T\xf4\x88{ \xc4\x93%\xcb5\xa1\xe4E\xb0f\x99\xcb\xbcz\xff\x9d\xe7:\xcd\x1b:\xef\xb4G\xa1\x9d\x9e\xb1\xc1e2\xbf}\x9b\xb1\xb9\x12\x1e_\xa5\xc9:\xcc\xd8 exC\xbaB\x9c\x9eE)\x0b\xe6\xb7\xc0\xffuL\x87jE\x8b\x18\x90\xad\xd3\x00\x83f[\x1e\xbb\x96\x83j\x0f\x02\x0e8\x84$\x8e\x92`\xde\x05\x05\xf8\xc3\xc5\xa6\x94e\xdb(\xb7Y\xe4\xb1I\xc6W\xa0k\x9b\xb1\xcb\x06X\xa1\xb3\x11\xbc\xdb^n\x9bI'_\xab\xef\xc2\x88\xbdFva\xa6R1\xca?&\xe7$I\x0f\x06|w\x9feZ\xb2c\x12\x97:\x8d0k\x826\x94\x9dj9\xef\xabn\xfdP\x99Q\x91b\xd8-\xa5\xe9l\x98A\xc6\x08t\xf5\xaa\x18\x82B\xa4j\xec4\x95\xa8)K\x05\xe2\xa9\x0e\xeb2\xdc\xd1E\x18\x87\xf9\xb7\xc9\xfc\xb6\x93P\xcf\xd7\x85\xaa\xf1\xb6N\xe3\x10\x19\x97\x91\xc6\xe9UL\x07\x01\x1e\x14\x0d\xbda7\xd8\x90\x9d\xf3i\x17\xc1.\xa3\x04\xc3\xda|\x1b%\x97\x9a~\x15f\xaf\xe4\xdf/\x17B^\x91\xed\xf3\xa2\x9d\xdb_$\xe9\xfay\x90\xa3\xf3\xf4w\xe2\xef\x8e\xfd\xc8\xe2\x9d\xfb\xa2\xcb\x05\x18\xcc\x15-\xaco_\xffp\xa6\xbd\xea\xd8\xad\\>M\x9d\xea\xd4{P\xa0\x0c\xe0\xf5d\xb9\xb4\xebJ\x07\x1an\xc1\x84\xe3\x8cL'\xeaC\x0d\x1a8\x1c\xf3\xf5v\xa7\xc6\xfa6\x97Uh\xbe\x07.\x1f\xbcXT\x1e\xf9\x87\x0f\xb0\xa7u\xd0\xb0f\x80WH+\xb2\xac`\x15\xdb8\xdbn\xb8\xa8\xcf\xe6\xf0\xad\x9c\x0d\xaf\xd9\x16\xfc\xada\x95\xecH!s\x94T\xb7\xd0\xe6\xe2H7(\x90Lf\x9ci\xbb\xce,\x89s\x16\xe7}\x1a\"\x1e\x1a\x9a\xb0LE\xc6\x11u\xb3Z]\x1f\x9c\x9c\xdd\xe4\xfb\x9b(\x08\xe3\xc7\\\x8c\xcfX>y\xfb\xe6\xbb\xfeCG\x05\x97-\xb0H\x86\x8cRo\x06\xbc\x95.\xdd\x18\xaayx\xd1\xf5\xd3\x91@\x8d\xa6qz\xc1f\x13\x85\xb3\x80S\xb6\xfd\x9b\xfe\xf5\xf5u\x9f\xa3x\x7f\x9bFda\x9bWgm\x94`\n\xec \nxI4\xa5\x95\xbf\xca\xeb9!\x8521\xef/\xf2\x1b[@j\xbdPy\x11\x0db\x90\xc8\x04P.\xd6\xa5=\x0dz\xad\xcd\xb6\xe2v\xa7\x9e$\x954`\xe1,\xd9r\x8d1\xc9QdS\xe4\x17x5\x082\xe0\x8bnC\xc8\x1d\xc6\xcc\xb1\xadj\x9d\x85BP-\x91\x97\x0e[\xac\xf3\xd8\x1a%8\x92;\xcfq\xd4\xbeO\xa5\xe5\x17X\xc7g\xebz\x83|\xc5bwk2D\x8b\xe1\xe6D\xfeZh\xd2m \x8ak\x05\x06\xc1Q\xda\xfb\xd85i\x88n^\x98\xf74Kx^\xb1\x84OQ\x956\\yq\xf3i#\xeb\x95\xda\x8b\xddU\x0b*+\xa6/D\xa7\x95\xfb\x0c\xb4\xe7\x00\xbe#\xda\x97\x91\xddB\xd1uQ\x8fj,\n \xae\x15\x9dt\xb4\xe7#\x94\xa8\xbah@\xd5\x9f\xb3$\xfe\x9c\xb6\xfft\xf6\xf2\x05\xf9qX\xa9W\xe9\xbdMY\x98Y-\x18\xf2\xcc\xc5U'\x80\x7f\xff\xe8\xa1\xeaP_\x7f\xa4\x15\xba\xb5\xc4x\xe6\x0f\x06\xf5\xddhK,\xab\xeb\x0d\x92\xd06%\xb7\x85m*S\xed\xccR6gq\x1e\x06QFn\xdf\xc5o\xaeF \xf9\x00\x8a\x00\xb7\xe2\x05\xa1X\xe22\xf9FE\xfe[\xb3|\x95\xcc\xb11\xfaS\xbe'\x87\x19\x86\x7f\xf8t*\xaa\x1cx4I\x18\xef\x1cC\xe9\x9d_\xb57\x18\xf6P\x13\x0ci\x96\xca`i^~\xc3\xec\xf3\xd2o\x19\x98\xb3\xf2\xceI\xd6a\xee\xf8\xb0W,NE\x98\xb2/Vn_\xacv\xd2W\x98;\xf3\xe4\xedfc\xcf\x04\x00\x05\x1a\xdc*\x8f\x0ftF\xef\x8f\xb8\xbcit\xe7\xfb\xe8\xe6r0r\xe2\xc5O\xe7?N\xde\xa8\xe8\x87k\xe9\xf8\x84\x7f\xa8\xc2\xe2\x87\x96\xc5)e\x0b\x96\xa6( \xd0[\x17\xdb)BRj\x1d|\x7f\xf2\xecy\xed\x0b]\xc7\xb7\xc0<\xaa\xdex\xd12\x8a\x92k6G\xb6\xf0\x1f'o I\x81\xb7\x06)\xfb\xdb\x96eyfB\x08\"rR\x83w\xe3nV\x99E\x07\xab\x8c \x83MV{L\xb1!/\xdf\xddq\x0cV\xc3F3B\xabxP\xbam8i\xbam\xc8\x9f\x94.\xdd\x93\x05]\xcb&\xd2\xc3l\"\xd0V\x1d\x0f\xf7\x04\xf3\x9b8\xc6\x06\xec\xcc3\x97\x16P\x83[\x10\xd7\x91\x0d\xaf\x13\x83\xf4 \x16S[W\xeb\xf6\xa6}_\x93\x86\x0d\x951\xf4\xd3\xa3w\xf1\xfe.\xbbY\xdb\xacq\xdb\xd5\xd0b\xa3\x08\x8a\xec\xe2C\xed\xb6\xbf\xfeH\x7f\x07\xb9qc\xa7\xb9A\xd0\xf7*\xf5\xab\x9e\xb5\xf2\xf9\x9c=\x98[\xf9*q\x84\\O\xb8B\xaa\xf3\x04\x1c\xe1\xea#\x95\xe4,\x0f\xf2-'\xb7\x0e\xfd\xe5`jLN\xf3\xe4\xa71\x1c\x0c\x87\xa2t\xf2^\xc5\x8b\xa5\x8fO'\xfc\xab\"\xe7\xe2\xed\x138TU\xe8\x95\xb49\x14\xbfj\x1da\x9118/\xff,\xc7f\xe7\x05\xbe\xce\xb5r\xfc_\x84\x9a\xab\x90\xa9j@\xd5\xd2/4\xf0\xb0\xc1\x82\xe5\xe68rW\"\x16\xa0\x19*tS\xc2\x18\x9c\x8a%\x01\xa7g\x08w\xc6\x1fy@5\x06\x87\x0e\xa7\xa80\xfaX\xcac*|E_\xcd\x8dp\x85m\x0cN\xa1\xd0h\x8dp\x0d\xa3\xf8\xd9*\x00\xf2'Oo[\xcca\xda\xa1\x03o\xdf7eO\x96\xcfG\x98\x05\xe8R\xd7\xd5\xad~odo\xcb\x8c8\xb6l\xc0R\xaa\xe6k#\xfel\xda\x0bM\xfd\x1e\x83\xa3)\x1aT\xa9\x8e\x9ef\xd1\xa8d&\xf4\x10r\xae0\x95\x9dtv:\x95\xfa\xd6\xb9\xe3\x17.P\x85\x1aV\x7f}\x1c\x05\xeb\x0d\x9b\xd7\xbf\x9e\xc6\xf9\xe8\xbe\xb9\x92\xe9\xfdi\x9c\x1f\x1e\x98\x8b\x9b\xde\x7f\x17%\x81\xfd\xc3\xfd\xbb\xe2\x83\xe5z\xea\xba\x93\\\x06\xba\xeb\xc6\x9d;\xc07\xe9/!\xbbn0\xbf\x99\x81\xc0<\x88\xa5\xf4K\x13V\xda0\xe3\x8d7;[\xe9\x8f>\xb4\xc2\x01\xb8\xd5E\x8d\xc4E\xf3@\xebP\x93h-\x11\x9b\xa8\xf8\xbbX\xd9\x11\xa3\x90\x0cB;\x8f\xdd\xd4\xc2\x82$\xcb\"\xf10\xd8L\x99\xe5\x8e\xa1V@$wO\xa0\x07\x8e\x8f\x81\xb1al\xba\x8f\xef\x97\xc6?g\x11\xcbY\xa7\xad\x17EU\x97|\"\x86\xbc\xda\xe5\xf6\x97,\xef\xd4\xb8\xda8\xb9@\xc4F\x82\x8c\x0e\xbb\xf5y\x8e\xcb\xa9R-\x1d\xaf\x82\x9d\x1c\xd0d\x07\x15\x07<77;w\x96\xfb\xca*\x93l\x80\x80\xf2\xea hk_\x08Ym\xb9Y\xe5SI\x96-z\xf4\xacs$\xe7B\xa6\xfc\xe1\xd4\x18\xe3s\xbaqT;\x957\x8c\x11\x9d\";\x98,\xa4u\xd1vkV\xdf\x8f\xba\x83A\xc3 9\xe0)\xb9p\x904\xa32\xfa\xde\x9bM\"\xfaT\xd0\xd5\xe57\x98L\x87\x99\xd8N\xef;\xce\x84\xc5y\x1a\xfe\x16S\xe9\xb6/S\x0eL\x06\xcf\x0fh\x99R\xc51H\x9b\xa1\xc9E\xc8\xb0\x00\x96\xb3\xf8[\xe4\xf3\xcfO~8ys\xc2\xf9%W\xd8}\xa1\x9e\xfb\xe0\xbc|\xf5\xe6\xf4\xe5\x8b3\xfe\xe7\xab\x97g\xf8\xe9\xd5\xdb7\x8ea\x81fZ\x97\xb3(\x89Y\x97\x15\xd7\xa4\xb2\x19ZP\xfc\x86\x15\xbcL\xe6\xb7\xfa)\xdbi\x1cZ\xee\xd8\x1aWP\xa4\xcb\xd7\xc6\xe9\xa9\x97\xf3\xd2\xcb\xf9gNe^9\xf9o\x9a\x14i\x0fc]\xdb\xb0k\x84\x85\xaa1\xae\xaa'\xf6JB\xeb\x18K5D\xd3M\x1a\x94\xcfm\x1a\x8d\x95\x9a\xb2\xc3*\xcf\x07\x9d\xfdi$\xba\xd1\x92\x91\xc5\xa8}\xa1\x1a\x82\x82\xe8\xcb\xe3X\"h5\x9b\xcf\x98R4q\x16N\xd5\xf3\x11\xcc\xd2\xd0\x95\x88c==\x1c\x8e|8\x1c\x1e\xf0\x7f\x0e\xf9?\x0f\xf8?\x0f\x0d\xe82\x1f\xa4l\x1e\xa6\x1d\xd2\x8d\xcb'\\\xa8\xfc.\x97\x9a\x95O\xb7\x96i\x11\xb7\x94\xbb\xa9Pjg\xc9\xdcz@_\x02\xdd\xae\xfb\xd0\x05\xe2\x9a\x95\xa7(\xa1\xa3\xe6\xc6\xcb\xc6;\x80\x1e\x1b|\xafT\xee\x84\xff|M\x06A\x98\xc0\x8c~f\x9b$\xc6{\x9ds\xfe\x1b5\xe7\xae\xab\xaf\xadQ\xcdi-n\x10v@\xb7\xbe \x99\xc3^\x9aml\xa1(\xfc\x9f?\xfe\xf0}\x9eo\xc4<\xec\xa6\x9apG\xcf8\xd0\xb0\xaf\xb9\x14h;\x1e\xb6\xd2\xa7r\x0dB\xc4\xb0\x13\x91\x92\x8f\x02\x9d\x8d\x1br\xc1\xf9Y\x14\xc9m\x13\x9b\xeb\x8a\xa8\xbev\x97\x110#\xa9\xfe0a|qR\xd1\xf8\xdb\xd7?\xa0\xca\x1c\xc2\x11\x84\x03\xed-\x8c\x81\x95\xfdI\xfe\xb3/\xf6\xa3\xcf+\xb5\xf8\xbcH\x93\xa2\xea\xc8\xd0\x0b\xe6\xe9\x97?\xf8257\x19\xbb\x82\xc7\xe0%x;\xe6\xf8\x08\x16\x9d\xa9\xb1|\xd2\xaak\xe8\x0b\x96_'\xe9{i^\x87E\x10Fln\xf2\xfd\x90\x8f\xe8:\x0f\xd7,\xd9v:o\x97\xcf\x17\xeb|\xc3b7Q\xc7Q \x9d\x7fa\xaa\x1d'\x8cg\xd1v\xce\xe8\xf0!)\x9d\xf6p\xc9*\x1c\\\x87\xf9\xea\xb8tND\x15\xd5\x16\xddn\xe46\x96|\xc1\\m\x17\x05\x17!/\x0c>\x00 B;\xf9G\xcb'\xe4\xea\x95\x80:B\x03\x8b\xbb\xb4|\xb8$\xc9+\xc5sWsoO\xb4C\xb7#:\x8a\x1b\xeb/mR\xa9\x99\xd8\"\xf9\x1cl\x92\xe8v\x11F\x91\xc9+X\xfd\xe5:[y\xd1_\xbfk\x90\xb1h\x01G\xf4\xdfXS\xb1>\xeb\xa2l\xec>\x1a\x9a\xae\xaf\xf0\xf7\x0f\xcd\x17\x92\x1e>\xb2\xdc<*\xef\n\x85!\xe6\x84\xb0\xdc\n\x1e2\x8f!)\xbfUQ\x02\xc6\xb5\x9c\xf7\x9f9\xbf\xc3\x87\xd5y$j\x1e\xf5\xf9\xd5!\xeb2\x0df\xef\x19\x9fHg\xd3\x00f\x84\x9b\x9e\xd7e*\x83\x0d+\x8c\xe7\xe1\x8c\x95Zo\xe7\xab\xd4\x01f\x96\xa3\xe4s]zJ\xd9\x86\x05\xad10@\xeb\xa5\xdej\x19d\xeb\xf7\xd2\x9e\x079+Y\xcdN\xcf^\x92\xe1\xac\\\xd6\x1c\x8dg\xce\xa2p\xcd\x15\xb31\xde\x0e\xae}\x97\xc1n\xf6\x0cR-}K\xc7\x90\x8a\xe0\x13\xb6\"\x7fA]\xfde\x1c\xdd\x8e\x8d9\x063\x96\x86A\x14\xfe\xc2\xf8\\vX\xad\xa0v{U>\x86\xbd\xc8\xde\x87\x9b\x17\xdb(\xca,c@p\xe6\x05\xbe\x0f\xe2y\x84\x91Q*V\xf3J\xa3\xba\xc6\x0eL\x04~Q\xf1\xc82\x1f\"\x9f\x8buE\x88\x04\xd3l\xa4%\xdb\xc0R\xd1\xdbZv\xa0{\x82F\x1eV\x89\xb8Xwe\xba !\xdd\x82\xaft\x7f\x0e\xbe\xb6Tq\xe36\xd6RW\xc2\xaf\x9a\x04\xfdP\xb9LQ\x06\xb4\x15\xa7\x93|D[\x01\x0c\xe8\xfbf\xb8\xe2\xcd\x9f+\xf4\x8fm\x81u\xb0{\x9c_\xa1\x84U\x8f\x97A\xefe \x80\xea\x87t\x10f\xe2V\xc1\x95\xa7\x0d\xff\x08\xa6s\x17#\xc4\xc3\xb8:\x07\x8f#\xfb\x84\xa3\xfd\xdc\xcd\xdc\xab\xd2\xa7s\x18\xf3\x9a\xb1^F\xb8x\\y\x9eA\xa5\xe2\x9b\xbd\xf6\xd1~n\xb2\xe0\xe0\x96\x15\xcc\xf0J\x0d\xd1\x10\xff\x8f\x97-\xdf7\x8a<\x0f\x8f\x07\"\xcb\xd6\xdaU\xdc\xdbJ\xda3\x13t\x808|\x98\xc1\x11\xdc\x0e\xb2$\xcd\xdd\x19\xdf\xe0. \x9a\x94\xa9\xf3\x92\xbc\xdd.\xe1 \xac\x95\xb7[\xafw\xd9\xa4\x7f_\xc0\x04\xd6\xd3K\x8b\xc1\x0b\xdd\xbd\n\x80\x9d^`&\x07wY\xbd9\xef^yp\x04K\x99S\x86\xb9\xbc\xa8\x0f FP\xf3Z\xd0\x96\xcf\xb3V5\x86\x1e\xb8\\8p\x06|\xe7/T\x9e\xd2\x0b\x95\x9b\xb4\xb9Q\x03\xd1\xaa\xbd\x91\xfb_&CfQ\xa0\x91\x99\xa9s\xfd:\xe1\x0b\x80n\xe5\xa6\x83 \xcb\xc2e\xec\xfe\xfd#606\xc6\xcdQ\x01\x99\x02\x89\x07x\x8aS\xdc\xf7-\xbd\xd7\xc8W!T\x05\x05\x810\xba\xd1\x9c\x88\xfa\xab\x00\x03\xa0_2\x08\xd4\xe4j9E\xaeD\xdc\x1b\x0do\x82\x81bjp\x04[\xed\xd7X\xffV_\x89\x19\n\xc4u\xe2\x11\x0c\xea\xcc\x01\x8e\xcc\xaf\xc7\xb05\xbc\xae\xf7\xb5\xb0\xf7%\xf9\x14u\xa1~a\xcb\xf2W\xbd\xc1\x8d\xb5A\x11\x18\xea\xa8\xf8s\xac\xa8X\xbd\x1d\xae\xa2\x1b\xb9N\xb1\xb1G\xda\xdfES\x86\x05]\xd9\xdb\xca(\xa5\xbc\xf8\x83N\x8b\xea\x0d\\\x15;K\xb0\x85\x9eU\xcf\x93\x1cy\x8e\xf6\xb3^u\xdd\xd0\xb7.n\xd0 Jop\xa5\xf57\xf5\xd6\x97-\xab]H<\xdaji/\x8be+^\xd6\x91\xad\x04\xd4$\xdc{\xea/4\xa2\x0bo\x93r\xd5\"\xf3U\xa7\xc8\x15\x89h0gi\xe6\x17\x1dY\xb0\xf3m\xfc>N\xaec\xa1k@\xb2A\xf1g\x93&W\xe1\x9c\xcd\x8d\xf8)\xc2\xb1\xe2\x80\x8b\xae\xa6\xb2\xa7\ni\xb7l\xda\"\x8c\x08\xa1\xd1\xa1\x95s\x12\xf9\xces1/\\\xfd\x06\xae*\x80\xba/&o\xd7\xab\xd5\x07z\xedc*\x82*oF!D\xc6\xc2)\xe8\x98\xee.:\xe1\xfd\x0bj]\xbd\xf8s\x8d\x9d\xa2\xff\xc2w\xb4h\xc2\xc0R~9\xe6\x8a?*&\xa8\xba\x07X@\xbc\xe1lF}\x1csE\x9f\xeb\x15\x8e^\xa7>\x9b\x1b\x98@8\xbd\xaeL\x06\x83\xc8\xb8U\x96\x1f{\x18\x0d\xeb\xce\x1d\xc9\xdc\xabw\x1c\x15\x0f?#\x1e~\x06O\xe0V\xe3\xe1g6\xe1\xf6\x18&p;=3\xf0\xefE\x89w\xc7\xd3c\xe2\xdd|\x07N$\xb7\xcd\\\xfe\x1e\xa3\xf8\xde(\x0e\nG0\x97$\x83C\xd6\xca\x87+\x9f\x0bV\x17>,\xab\x8c\xf5cm]\xdec\x07\xe8f\x16\x19\xcc\x9c\xcf\xd0P \x90.\x98\xcf\xff\x9f-Ko_\xa5l\x11\xde\xf0m8r\x0c1\x9e\xc4\xce\xbf/\xf2 \x0c\xe1\x08\x9eA\x0f\xdeW\"\xfc\xe0_\xbf\x8az\xdd\x82\xeb]\xf4nEN\xcd*\x12~Vn#\xb6B\x1c\xa4\x7f\xe0,v\x0c\x07\x06\xa5\x91\x1c(Qi\xa4?ME\x9au\xd29\xdb\xe4\xab1\xdc30\xc1 \x0d\xd6,g\xa9\x18\xc0\x88\x1d\x1a\nEA\x18\xd3j}1]0\xe8\x10L\x05\xda\xbce\xd5\x0ekl\xeeH\xcb\x92\xb1\xffn\xe0N\x7f\x1aL\xcf{\x1e:\xb2N\xffmt\x8e\xf7\xfa,\xbeW 6z\xdf}7\x9d\xfe4}w~\xfe\xcd\xb9gK\\\x03b\x16\xe5\xc2\x94h*m:\x86\xe3\xd4\x0d\xc5Gq\xa5\xda'\xb2\xc5n0!\x85\xbdb\xd6p\x8e\xcd\x97\xa9\x16\xcd\xacZ`/\x1e\xe8[ \x98/\x0c9Z\x15\x1504\x1a\xa5\xab\xae\xc0\xb0$\xdav\x83vF\xa7\xe2\x86;[`=\xfdQ\xc4R\xe4\xf6VB\xb3\x1b`\x08G\xb1\xa88\xa6\x08\x9e@<@\x90n\x0c\xf3\xcdg\x1cA\x0fC\xe7\xef2\xf3`::\x17[3\xf2\xa1/\x02v\x7f\xc6J\x04\xc6\xa0\x14`]\x0ci\xab\xe1\xdd\x8a&HQ\x92\x10\xa3\xc0E\xe8M\xd6\x01tA\xb0Ry\xb9\x0d\x1c\xa9r\xca\xf2\xa2%7\x1b\x89\xe4\x03\xc3\xc7\xd0\xef'm\x8d\x81@\xd0\x90\xa2\x98\xb3i\xd2\x90\xda[>(9LE\x0c\xb6\xc0Cl\xc44\x08\xd3sO\xb28\x9b{\x99\xfet\xb8M-\x1f\xb4\x18\x97\xc1\xe3H\xf2\x86Y\xca\x82\x9c\xa1\x0eg\xd2\xefl\xcf\x95\x08\xe5\xc7\xb7\x8d\xd8b\x91\x9f\x91+y\xe7\x95\xd7\x81\xb6\xc6\x1e\xc9\xd7\x1a\xfcq-\xcc\xbe\xc7\xd5\x87S 4_\x9f\xc6\xb9\xbb\xf5ad\n\xd9`z\xf6\xc2\xecE\xf0\xc2\xcdp\x88\x01b\x1f\x06\xbd\x17\x06\x9a\xcc\xc31\xe3\xab\x8c\xc2\x8c\x8a\x1c\xc8i\xc6P|\xcc\xe8\xd3\x13\xa4\xc7\x8a\xa9\xc1\x91\xda\xc0iv\x8eQ\xf0\xc7\x10N\xb7\xf8g\xeb\xc0\xcc\x18\xa2?\x1cT\xc3\xc6R\xcdm\x08l\xb3\x0f\xe5\xa3\x9b \xec\xa9\x15\xa9\x98\x9a?\xc3\xcc\xf0 \xf6\x84X\x88\x03U{B\xe9\xbd\xd1\x9e\xa0JX4\x96\xe7l\x07{\x02\x8ei\x10.\xe3$e\xba\xe4\xa7dB\xc3G\x1f\x87 \x8d\x0c\x13S\xacl\xbd\x80\xb0D\xbef\xcb\x93\x9b\x8d\xab}\xf10I\xa5n\xae\x085s\x85\xe4\x12\xbc\x83\xba\xe5S~\xc3?eI\x8c\x83=\x11\x9eZ\xc1\xa0\xf8\xe9#f\xb1\xcd\xb1\xf0B\x0e\x06\x17\xea'f\xa5\xc8f\xc1\x86\xbd\n\xf2\x95\xba0\x8b\xa5\x0c\xefy\xf1ml\xab`\xfcR\x1e\xfe\xd6\x90\xd7\xaf\xd5\xad^\xc0c\xbb\xcf\x01]\xd0\xbc\xccXzE\x1e\x9c\xd3syk\xf3\xf2g\xa8f\xfc\x80\xba<]\xbdQ\x17\xed<\xb4\xb6@\x95\x9cv]\x06\xb3\xf7\x14\xc8\xad4`\x98\x98\xa2mV\x07h\x8a\xfd=\xab/I)\x8b*\xe5\x9cJ1-\xb9\xa471<\x81\xf41\xc4\xbd^]\xcb@\xdb\xce4>\xa7e\xc3H\x0bd[\xb7N\x0d\x19VlQ\xb7/S\x16\xbco\x99\xd9\xc2\xcd\xe9\xbe\x88\xaf:\xe3\x7fm8\x14s\x11\x0b\xd3D\xa8\xdfR{E\xabJ\x81\xaaz\x1b\xa2\xa4\xe1\x08\x81R\xc8\x8a\xefF#q\xa8\x1b\x891\x94\xad,.`\x8a\x15\xfb\xa8n\xfc\xf0_n\x88\x89\xbf4jY\xdf\xac\x85\xab\xb2\x01\xd4,\x1a\x18b\x82\x92\xe9\x98\x96\xda(\xa4\xe7\x83<\xf9\xd3\xd9\xcb\x17@9X'\xea\x85k\n\x14\xa3\xe0\"D\x9epAK\xfdg\xce\x9ar\x8f\x84\xa1\xf2[\xe6\x91\x98\xb37\"\xde\x17\x94\xac3\x99\xb0\xced\xfd~\xa3X\x83\xe6\x18\xe4T\xd3\xec\xbc\xc1\xa2\xb8\x97\xd6.\x8e\xf9\xb0\xf1*\xd2g>\xdd\x9cWt\xd0\x08Mf$\xc0\x94\x8f\x98rO\xc5\xac\xb7\x9bg\x92\x0d\x1e\xd9\xac\x93+\xd6\x90o{\x13\xe4\xab1\xdd\x0c\xdc'\xf3\x98\x81\xe0\xb9\x1b\xfb\xc5\x1c\\HK\xae\xd7\x16\x03\xd2\x95\xc8\xf9\xc2\xe7n7\xaf\x18\xf2ADP$i\xa2\x1f\x86B3\xbd\xd0\x8c\x0b\x89.\x89\xa2\x1cJ[\xe7\xcb\x85\x1d2\x11`;\xee\xde\xd0o_r(\x96\x1d\x05\xf3\x86u\x87\x1d\xd6\xbe\xb9\x15\x11}9\xd5X\xa0;kr\x81\xedjF5\xfbEm9\xe0*j\xb2W`\x8f\xb9YDNMm\x08\x15\xb5\xcez\xbd&\xeb'\x07\x8e\x0d\x9e%f\x0d\xc0Q\xc3-f\xc3-\xae\xfau\xde\xbf`>\xff\x87\xed\x1d\x1fm\xd3\xf6u\xd8=\xcd\xc5X\xfd\xc5\xa5\x1c\xc1\x96\xdb\xeciZQ=+\x02\x97\x94:\xb6\x80\n,\x99\xbe\x9bE\x9cR\x08\xb3!\xf1\xf5\x82\xa1\xe7\x94`871tPL=\xd7\x98\xba\xd2\xe1\xf9\xeb\xf2\x9a\xd4\x02 \xf1\xda\x898\xdao\x95vJz\xb9\x90?\xb9bq\xfeC\x98\xe5,F\xfb\xa3\xed\x93\xeb\xac\x93m\xc6\xb6\x1b\x87\xac.\xd6b\xef\xd9m{!lk\x9e\\\xc7m\x05\xdf\xb3\xdb.\xc5f\xab ^2,\x85\x807Of\xdb5\x8b\xf3\x81\xfc\xe3$b\xf8;\xc8\xf3`\xb6\xc2\xda\xae\x93\xc4\xe59u\xad\xa5O\xb1k\x9d\xea\x8c\xbb\xd6+/@\xd7Z\xfazt0A\xc4\x15\xb9;\x16\xaa\x01iO\xb1\x99J\x9b\x80z\x86y[\x8c m\x84\xddV\x12\xa7\n~!R'\x1f\x03\xc9+\xf4\xc3\x12\xc9C\x9e\xadw%r\x80\xc7>\x8c,\x08\xc9 _\x87\xaehH\x02\xb1\x0d\x13\x0d_-\xc8h,i\xc0G{\x8bu\\\xb3\xb5\xa9J6\xe3\xdb\x9c}\n\xbeUju\xc27SO]0\xa7\xdeW1\xb5\n\xeap\x8eT\xc0\x01\x85n`\xd7@I\x99\xbcRD\xd6\x8fd\xad\x8aYJ&\xa8\x19\xff\x8dv\xbe\xb4\x9b\xa0bp \x91F\x90B\xb1Em\xbd\x9a\x01\xac\xc9h\xa8\xb4\xe3\xcfI\x02\xd69\xadW)\xe1\xafQ\xa9\xd63\x94\x1d\x95~\x8d!\xf6\x06\xd9*\\s\xf6\xdd:/\xb9dZ\xc6\xb7%\xeer\x86'\xf2v\xa2%\x06\xdd\x12q'\x90\xadi\x92\xa7\xd9DdH\xab#}!-Ck\x0d\xf6\xa3mo\xbd?C\xee\x17uK\xcb\xac\x82\xd2\xfb\xfa\xb1\x19\xd3\x8c=\x9d\x9ce\x99\x0f\x0e\xff\x831\x87\x1cij\xb56\xa2\xfciv\x12o\xd7\x14\x11\xc3P\xf7\xc3\x07\xdd\xa5\xec\xa3Kq4\x0b\xc8\x89\xe1\x08}\x0b\x12oPD\xb3\x9f@JVR\xfdUb\x04\x94\x9d|\n\x8d`JQ;p\xe12\x11F\xad\xfaQ\x85\xf4(\x1d\xa8Y\xf6F.y1ih\xba\xebU\xda\xd1\xe6\xf1\xb1\xc1,\x89\xb3<\xdd\xce\xd0\xc0=\x99\xe8\xdf\xd0t \x86\xabv \x8e\x8aI\x8d\x0d#3A\xb9\x1d\xea\xb4\x93\xcc#\x0ee\x11\xb6\xaa\x9fh\xf2\xf7\x1a_\x1c\xeb0:)9z\xd7\x8bR\xa2\xc8#Sz!\x07\xcf\xe5K\xed\xb5\xf4\x9b\xb6\xe1\x96!g\x8f\xc4e}\xc8 \x0d\x00\xb3\xc2\x8c\xd58\xb4/\x81[\xc9Bo\xea\xcc\x90\x7fG\xe9\\\xeb`\xe3\x86\xcdc5\xe4\xa4\x91\xf4\xdcz$,\xe9y\x15\xbdE\x80%7\x9f\xc6\xe7\x18W\x9dM\xe3Z\x10\xfc:\xb57\x8c\xca\x90\x87\xa6\xa4\\+\xbaZ\x18\x82G\x15\x83\xa3*2\x1d\x9d\xf3\xb5\xd4\x7f\x8eIX5;\xf0bT6\xb6\n\xae\xc2d\x9b\x8e\xc15\xf4u`\xed\xeb\xa0\xdc\xd7\xc19\x1e3z\x83r\xabx\xc5N\x9a\xd5J#Pg\xe4|\xeb\x9a\xad\x0d\n\xb91&u\xb9\x15\xcf'+:}\xf3\xa5\x13e\xc4\x85\\%\xf2F&Y\xb7\x94\xbf:\x9dF\xe7t\xda\xad\x1f\x91\xceD\xe2\xe8\xe1c\xd8\xc0\x13X\xa8\x067v#\x18o\x11#WL7\x0d\xa7\xe6+.\xf0L\xe7\x0d%\xae0\x97\xe3\xaa\xc1\x12\xb5\xc6\x12\xe1tn\x8b\xef^\xba\x8a\x80W\xde\xec\x12?\x96- \xe3\x13X7\xa9\x1b \xe6\x8a\x0e z'k8\x02>\xa8\x0e>\x83!%\xc0\xce\xd0\xebk\xba\xf4a\xeb\xae\xbcs\xa3\xbb\x99|D\x9clQs[\xbbz \x1fu\xadE\xa76m\xf3\xd7\x8av\x9a\xfb-\x1ex\xdb\x86 \x1f1V\x07O\xbd\x1d\xe1\x17VA\x13Z2\xe9+pk\xbe,)\x9f\xf2\x1a\xd8\x07\xa0\x97Z\xd5J\x18\xd5\\\xfd\xc0H5\xd3)\x17f#\xd5\"\x12$NA\x90\x84\x1dA\x8en\x1ecL\x1e\xcd)\xc1Hd6(R\x1a\xf0\x02\xe7zk\xd3\xd4,\xefg\xe4\x16Q\x8c\xdd/\x06=\x88\x93\x1f\xb7y\x907*\xe6j\xf0\xcc8\xf8\\\x0d^\xe6g\x18\x92\x1e\xcdH\x8f\x06\xc1\x07\x8a\x81V\x0f \xd5@\xc9\xbf\xd1<\xd2\xeb0_\xbd\xc4+R5\xdfI{\xba\xd5L}\xafl]\x8b\x8cg\x0f\x0c!\xf3\x8fC\xec>\x1a\xdd\xab\x10\xa0\x8b\x0b\x96\xfd\x98\xcc\xb7\x11^\xf3\xdf\xad\xcb\xd8\x1d=x\xc0\x17\xd0}t@\xff\x8d\xee\x8b\x9f#\xf1\xff\xa1\xe7\x97\x05[wt\xcf\x1b\xfc\x95\x05\xef\x7f\x0c6]\xfah\x10]}\x99\xc9\xf7p\xe4\xb9U?\x8ePtV\xbd,C^\x0e\xa3\x83\xbb\x95\xf7[j\xea~5Y0\x0d\xfa\xd1\xa8\x1a\xbb\"\xa2\xf2\xd5\xe6g\xf8\xfa^\xd5{d!\xbcG\x0e*\xef\xf1\xdcr\xb0d9_\x91\xf2\xa7y\xc1\xbb\xc2\xec\xe4&gq\x16^F\x95\xcb\x1e\x9c\xedd\x83\xed\"\xcb\x93\xb4\xf2\xe9\x8a,\xca\xa5w\xed\x01d\xab^\x076\xaa)Y\xb8\x88\x8ag\x904\x86%qbx\xaed\xd3V\xd7\xe3\xf2\x98\x97FYg\xc9:\x05\xd6\xc0{\x13(A\xdb\x89\xbf\xa4q\x1bcj\x06\xf9\x88 \x0b?\xe0\x1c\x8e`\xe5.\xc4\xec\x1d\x01\xcf\x8e\xe7a\x0c&\x94}1\xfa\xb6HU\x14\x16\xb37v`8\xf4\xab\x8b Yy\xca\xedAK\xb2\xc1\x9c-\x0c\x83\xf4\xd1?d\xc7m\xb8\xadj\xa8\xee\xa3\x83\xa1\xe7\xaaV\xf1\n\xde\x12o\xbb\xef\x0d1\x96Q\xb1\x963\xb7\xcd\x18\xf1\x00\xf6&\x80\x96\xa5[\x0fs\x7f\xc9\xbb,\x8b\x94\xb1_P\x18\xa4\x17\x9e{\xe5\xf9\xf0\x80\xd6Yc\xff\x1fI~\xdf\xba.\xa6l\xe3\x9f\x8f\x0b\xad\xd0]\x977I\xbb!\xb3\xf4|\x08\x06/NN\x9e\xe3\x01\xba\x0f\x89;u(\x8e\xae\xe3\x83\xb3\n2\xfe\xdf\x92\xe5\xfc\xbf\x8c\xe5\xce\xb9\xdf\x00w\x12\x96n\xb5.j\xeb\x8c>\xf2\xb5x\xc1!\xc6L\xd2\x1a\xcf\x0d^\x1c\xa0`:'\x03\xc4\x1c\x9d\x10\xcc`@\xb0\xb7(\xd2\x7f\\,\xc4\xe1TSP\xe3P\x065\xbeXL\xd99\x8d\xc2\\Zj\x86|U@\xe8\x9b\xbc&\x8c\x0d\x97\x18\xec\x0e\x91\"\xa8-\x02i^\x8b\xe5\xffQ\xdfc\xfa\xbbs\xa2\xf0G\xa3\x87\x96\xc8I\x8dh$\x07\xc6\xae]\xd4\xbe\xf5\x10\xaf\x9d\xf8b1\x82\x1a\x7f\x10\x1c\xab\xc6\x96\x04\xbbz\xe4\xb9N\xb6a\xb3\x90\x95\xd2\x84t\x93\xd8\x10\xf8\x8cb\nj\xe5\x1c?LW(\x84\xf1I3\xa2\xa0}\x8a\x9c\x85PJBHK\\\xcd\xce\xe5\xa9\x1c\x08\x82\xa6\xfb\x90\n\x90T\xe6\x10\xf2\x18\x9a\x86\xe7\x9e\xf2\x1f\x12\x85\x8b\x1c\xf1\x92\x96R7\xe3\xd6T\xf6\xdd\x85\x03Z\xe7\xe1}\xe3\xfas\xf6o\xe6\xba\xc2\xcd\xb3Z-0\xef\xa6\x10\x1a\x86UaBH:w\xab\xef#%\xaf\x18\xa5\x86\xaat\xd0$5DnU\x92\x9b\xe3\xdb\xea\xc8WxxT\x86\x93\xaeR\x00\x1b\\`\xea\x07\x17\xff \xd2\xb1\xae\x1e\x10\x94~\xae\xdbN\xcb\x90\xb2\x04hrojg\xd9\x86\xa3P\x8cr\xe3\xb2A\xd0D\x94+\xe5\x19\x17F\x10\xf0j\xa5\xaa\xd9\x90\x0b\x98Zk\xd6\xc3\xaa<\xd2A\x16\x91|a)\xe8\x9c5 \x94:\x83\xcb\xa7\xa3\xc6\x15Z\x05\xad\x01\xd2\xa4\xc8\xb2W\xf4\xda\xd4b7\xf9B\x1e;4\xcd$F\xe7yT\xf5r\x99\x021\x10\xf1\xa5Y=\xbete\x1c\xc4|\xdb&'WT\x043\xd6\x01\xa0M.\xca%\x00\x18\x9cv\x0d\xb3\x11\xb5\xfe;\x07\x99\x88%\x90\x07\xa2\xb9\x8f\x97\x08\xf6\xf6\xfe\xbb\x9aTF\xfd\xe57(fe!e\\#u>\x84\xb6\xa9\xa3\xdbc)J\xa35\xc4\xeb\x96\x7f\x8d\xb0E\xe7\"$g\xd7\x8b\x9c\xdcE\xd8\xe0\x82S\xbcU\xaf\xe7\x83@r\xa2\xcc~a$\x04\xbc|\x97\xb9)\x8e\x88M\xc3ss*|\xfb\xd2\xa5n\xa4\x8b\\\xe6av\xdbv\xf9\xa0Gg\x80\x92\xbd\x04\xf3\x91]x\x97@\x9b\xec \xe2s \xbeR\xd2s\xeey\"\x11\x03I\xf71_\x93\x99\x1b\xab\x9c8\xc8\xe4D\xfe\x85X\x89\xfd\xc6\xbe,\xee3\x1d0Z>\xff\x88\xd9\x8bD\x0f\xa6\xa9\x9bgi\x80\x10\x1f\xa2f\xcc_\xd4\x91\xc0\x86\x01)YK\xd1\xb7x\xcft/\xb8<\xa1\x14'\xc4H\xbb\xc8\xc5\xa5\x9bt\xcaP9\x9b d7\x0dM\xa8\xd8c\xb8*P\xfb\x0f\xf0\x05$\x94\xaa( \x04D\x8b9\xa3f\xb6\x08\xcc\xf6\x06\x12L\xeeU[\xc9,RQd\x91Wf\x16\xf9fa\x16\x876$uW\xc3\x9b\xce\xf1\xf5\xdd\xa17X\xd4e\x13\x8b\xf9\xe6\x8a\xea\xdcm\x15\x82%\xa5$\xed\xf3\xd6$\x13_\xe2y\x003\xd8\xe6/`\x02\x97\xf5\xd7\xd7\x9c\xbf\xe1!!\xa30;f?\xd4\x13\x98\xc0\x05G\x86\x8b&m\xef\xc6p\x1e%@\xf3\xcaz\xba\x89\xcd\xba\x18\xad\xe7D\xe5\x16\xe1Rx`W\xa5\xf9\x83*\xf4\x85'\x93*\xb8\x1ez\"\xb9U\x95\xca\x83#p/0\x91\x8b\xaen\x1aqm\xc6\xbf\\\xa0j\xea\\\xcc0\xeb\xe2\xe0b&\xa4\xc1K\x9dO a\xc0\xebsK\x1f\xf2\xe9\xf5y\xcd\xca\xc0)\xc0\xca\xe5\xcb\xe9\xa3\xc3\x94O\x04\xd3\x173\xf4\x97,\xf7WA\xe6g,\xf7\xdf\xb3\xdb\xcc\xa7<\x1f\xbe\x98\x8eO\xb7\x0f\x1c\x99\x9e\xce\xe7\xa3\xe9&&\xe0\x16\x82\xbcnZ\xa8\xacu\xb2\xc1 \x8c\xe1\x84\x9c\xcdq\x03\x1c\x1c**L\xa4Em]}\xc3K:{S\xa8uN\xb4e\x16 \xbe\x9e\x9cn\xa1LA\xfa\xd5\xc2\x8d\x0br\x8e\x06\x07\x1a\xae:\xaf\xb3\xab\xec*\x0f\xd1\xc5\x8c\xab\xec\x05\x05\x1frr\xed[\xd5})\x0f\x15z{R+W\x15\x89=\x9f\x82H\xcd\xcb\x8b\xe0d\xe1/\xcc1\xf1\xf6\xb2t\xdc&\x9a\xd1,\x06\xbc\xb5\xfaPjP<&(^W\xcd=dIY\xfap\xed\xf9\x90\x95G\x1a\xe3\xadOe\xf0\xf1|\xd8\xb8b;n(G\xd3\x85\x0f\x89\x9b\x0c\xfe\x03z\x90\x0c\xfe\x8a\xff~\xe7\xc3\x8d\x9c\xf9\x9a\xb3\x90\xb3\xc9J\x98\xa4\xcd\xb0\x16\xa1\x1eTy\xaf\xec#\xe72=O\xb5\xe7\xc3\xfe\xf4\xa7\xa0\xff\xcb\xb0\xff\xe8]\xff\xab\x7f\xfb\xe3\x9d\xaf\xbf\xe9\x0d\xde\xfdt\xf1\x7f>\xfc\xf7\xf9~8\xc8Y\x86\xb9\xd7\xcc\x81Wd\x82\x97\xd9*H\x83Y\xceR\xceW)\xcd\x00,B\x16\xcd!\x0e\xd6\xc6\x9c/\xca\xfa\x94'?$\xd72\xaftyq-sn\xb6\x84t\x9e6\xeb\xd4\x99\xc1\xf1\x11t'$#p\xc5\x98u\xa4\x95\xac\x82\xd6\x10\x93Iv[\x957{[\xfc\x99'1+9\x88\xb5$<\x11\xb7\xa2\xccI\xac\xc0\xa8\xe2\x99\xdf\x1a\xbcF\xc4\x80+i\xc3rS\xb2\xb0\xd6\xb5\x92\xb2C\xbd\xdf\xce\xd9~\x0d\xde}\xa0\xa5\x02\x14\x97sJ\x19\xf2\x13\x0c\xfd\xb1S\xbe\x0c2\x1eQ\xd6bs\x82\x0c\x91\xf9\xbf\x1e\xcd\x14\xbd\xeaL\xddu\xe9\x8bM\x87\xe7>0c\xe86\xadG\xdc\x03q\xee\xb6d\xb9\xe6\x1e\xf7\"X3\xae\xfd\xef\x90!\xaf:\xd7\xa9)\xab\xdcGS\xe6B\xdb\x1e\x19|\x13A]k\x90\xd9\xf8\x95\x04-\xb2 \x0dR\xc6\xe7S\xcd\xdb\xf2,JY0\xbf\x05\xfe\xafc\xba\xcc\\\xc9\xef\xdfi\x80\x06\x7fF(K0\xb5\xd4LM\x81\xec\xd8\x8eY\x93r\x97\xcf6\xdbF\xb6D)x\xff}\xb7\x8c;\xb1\xcb(aZw\x1bO\xa7\xa52\xf8n\x82F\xf1\xf8Z\x15\xb9\x97\xcdT*FW\xa9\xdc\xce?\xf2\x01\xdf\xddg\x99\x96\xac\x96\xdc}:\x8d\xd0\xe0\xc7 \n\xda0\x86\x8cvCP\x04\x9f1\x8cE\x9fQ\x91\x8f\x98\x03\xecm\xce~\xa0\x0b\xbb\x0d3\xc8\x18\x81\xae^\xd5C\x15\xfc\x12'\xd4i*QS| \xc4S\x1d\xd6G\xd54\xdf\xad\xa7E \x0f/JY\x05\xe9\"UC\x12\xa0\xd0\x9c\xdd\x81yZ\x0eE\x91\xd9\xdc\xa0\xa6\xcbG\xf9\x05\x16\x89\x8e\xbe\x8d\x92K\xcd%\xbf\x9a\xecXo\x9f\x17\xed\xdc\xbeL~\xcd\xfb\x90\xe1g:\xf6#\x8bw\xeeK\xcf\x7f\xce\xfb\xab$@\xef\xd8\xad\\>u\xc1\xa2I\x86\xd0z\xd7\xd2mC)\x87\xd4\xba\xd2\x81\x86[\xe8\xf7\xc9\x04\\\xca\xec\xc0:4\xc4\"\xb7\xb9;5\xd6\xb79\xbdB{\x00\x03\x90&\xf1\xf2\xc8?|\x80==S\xb5}\xcd\xd0\x00\xb3\xac\xc8\xb2\x82U\xe8\xd7-\xbe\x95\xb3\xe15\xdbr\xab5\xac\x92\x1d)\x84+hm\x0b\xab1\xa7\xe5\x83\x05K\xf9\xdffI\x9c\xb38\xef\xd3\x10\xf1\xf8\xd6\x12\x04\xadT7\xab\xd5\xf5\xc1\xc9\xd9M\xbe\x8f\x01\xa9\x1es1>c\xf9\xe4\xed\x9b\xef\xfa\x0f1\x04W\x05\x8b\xe4\xe1\x98z3\x10W-Z\xbb1T\xe3\xed\x7f\x0e\x12\xa8\xd14N/\xd8l\xa2\x90\x92<\xee\xdf\xf4\xaf\xaf\xaf\xfb\x1c\xc5\xfb\xdb4\xa2\xe8\xfc\xf3\xea\xac\x8d\x12\x8c\x96a\x8d\x88)\xd1\x94V\xfe*\x8d&!i\xcc\xe6\xfd\x0d)d\xb4\xe44\xf6B\xe5E4\x88AY\x12]\xb1j\xb1.\xedi\xd0km\xb6\x15\xb7;\xf5$\xa9\xa4\x01\x0bg\xc9\x96k\x8cI\x8e\"\x9b\"\xbf\x98t\x17\x82\x0c(\x93]\xa3e\xa2\xcb\x989\xb6\x9d\x9b\xb7\x99\x04\xda\x12&\xb7nq\xc9\xaaY\xa5\x04Gr\xe79\x8e\xda\xf7\xa9\xb4\xfc\x02\xeb\xf8l]o\x90\xafXl\x8aM\xfdQ\x92\xdf\x9c\x88G\xeb8\x7f\x13Pl\x17\"`G\x11P>vQP>\x15\x91\x90o\xb3A\x16\x94\xcf\xc7_\x0bM\xba-A\xc9\xf3\xbe&\xfd\x91\xbfzaS\xcde\xdc\x17\xf2\xba\x1f\n\xaf{u\xb5E:\xdf\x9f+\x1b\xc7`\x91&\xeb\xe3U\x90\x1e's\xe6\xe6\xd3F\xd6+\xb5\x17J\x99`\xcbk\xfa\xd1\xb2\x10\x9dV\xee3\xd0\x9e\x03\xf8\x8eh_Fv\x0bE\xd7E=\xaa\xb1($\xb8Vt\xd2\xd1>\xc7\xf37B\xd5E\x03\xaa\xfe\x9c%\xf1\xe7\xb4\xfd\xa7\xb3\x97/(\x06\xaf\x95z\x95\xde\xdb\x94\x85Y\xab\xe7\x0f\xf9\xf5\xd1\xfd,\x0fU\x87\xfa\xfa#\xad\xd0\xad%\xc6\x08\x94`P\xdf\x8d\xb6\xc4\xb2\xba\xde Q\xda\\F\xf9T\xf1\xcd\xac\x94)\x95\xe9\xbf\xb9\x1a%\xe4\x83\xc2Gv\xa5r4\xc7\x98\x8f\\e\xd7\xf5\xe4NQ\xd6VlL&p\xa5\xf7\xc9\x9c\xd1\xdbd\xce\xfcR\x82\x18`\x9a$\xcc\xbb\xc2l\\z\x06\xf6\x8a\xbd\xc1\xb0\x87\x9a`H\xb3T\x06K\xf3\xf2\x1bf\x9f\x97~\x7f\xf8P_\xa1\x0f\x1f\xc0I\xd6a\xee\xf8\xb0W,NE\x98\xb2/Vn_\xacv\xd2W\x98;\xf3\xe4\xedf#\xed\xbe\x8d\xc8}\xabe\x1a\x87\xa7\xd0\xa7{H\xa6\x8c\xdd\x1f\xdd\\\x0eFN\xbc\xf8\xe9\xfc\xc7\xc9\x1b\xc7+\xefcN\x7f\xa8\xc2\xe2\x07\xe5\x9d\xc1W)[\xb04EI\x80\xde\xba\xd8\x0e\x99V+\x1d|\x7f\xf2\xecy\xed\x0b\xf9\xcbZ`\x1eUoN\xf90&4\x9b#[\xf8\x8f\x937\x90\xa4\xc0[\x939\x873\x13B\x10\x91\x93\x1a|5\x8e\x8f\x0d\xf7\x17\x1d\xac2\x82\x0c6Y\xed\xd3p\xedz\xf2\x8c\xfe\x8ec\xb0\x1a6\x9a\x11Z\xc5\x03B\x1e\xd1~cxb\xfe\xe0\xf6H\x0b\xba\x96M\xa5\x87YT\xa0\xad:\x1e\xdc \xe67q\x8c\x0d\xd8\x99g.-\xa0\x14d\xf8\xed\xeb\xd3\"&\x19\xd7\x91\x0d\xaf\x93\xeeq\xe1:[\xb77\xed\xfb\x9a4l(\xad\xf4\xfe\xbb\xf4\xe8]\xbc\xbf\xcbn\xd66k\xdc\xb4\xda\xe5\x8d\"(\xb2\x8b\x0f\xdd2\xda\x8b\x8d\x1b;\xcd\x0d\x82\xbeWi\xed\x0e\x82|>g\x0f\xe6V\xbe\x9a+_\xfa\xbf\x17\x82\xbbH\xd0-\xae\xeeI%\x99R\xd5SXs\xfe\x17\xe6\nC\xf7\x0d\xf9i\x0c\x07\xc3\xa1\x8c\xfe\xfa^\xfa\x85\x88\x8fO'\xfc\xab\"\xe7\xe2\xed\x138TU\x8a\\\xf8E'\xfcW\xad#,2\x06\xe7\xe5\x9f\xe5\xd8\xec\xbc\xc0\xd7\xb9V\x8e\xffc\x8a\xfc\xaa\xa1\xb1j\x17)/7\x1axDZo\x1b4\xaf\xac\xc7n\xba)a\x0cN\xc5\x92\x80\xd3\xb3\xe4Q\x92\x07Tcp\xceD\xcc\x88P\x06\xa6\x90\xc7T\xf8\x8a\xbe\x9a\x1b\xe1\n\xdb\x18\x9cB\xa1\xd1\x1a\xe1\x1aF\xf1\xb3U\x00\xe4O\x9e\xde\xb6\x98\xc3\xb4C\x07\xde\xbe_=\xc3\xd0\x9f\x8f0\xc3\xe0\xd4\xcd\x94\x174\x97\xca\x91\xbd-3\xe2T\xa3\x1f\xcbGJ\xd5|m\xc4\x9fM{\xa1\xa9\xdfcp4E\x83*\xd5\xd1\xd3,\x1a\x95\xcc\x84\x1eB\xce\x15L`\xaa\xe2\xd5\x9cJ}\xeb\xdc\xf1\x8b(6\x85\x1aV\x7f}\x1c\x05\xeb\x0d\x9b\xd7\xbf\x9e\xc6\xf9\xe8\xbe\xb9\x92\xe9\xfdi\x9c\x1f\x1e\x98\x8b\x9b\xde\x7f\x17%\x81\xfd\xc3\xfd\xbb\xe2\x83%,A\xfbuP\xf9H^\xc0!\x94o\xd2_Bv\xdd`~3\x03\x81y\x10*[\xaf\xb0\xd2\x86\x19o\x9cS\x88\xdd\x87v\xa5\xc4\xc1\xd6\x10C$.\x9a\x07Z\x87\x9aDk\x89\xd8D\xc5 \xd5\xca\x8eP\x94D\xb5\x9d<\x83\x9a\xae\xde)?\xbeu\xb0\xb1:Di\x05`\x82\xa7\xd0\x18\xfd\xd4\xc7\xe8\xa706$\xff\xc1 ^\xc5\xf8\x85\x93z\x97\xad\x17EU\x97|\"u\x9f\xf6J\xfbK\x96wj\\m\x9c\\ b#\xe4f~T\x9a'\xa5{l\xebx\x154\xfbFU:\x96\x1d\xd4\xc2Bs\xe8h\xeb+\xabL\xb2\x01\x02\xca\xab'\x80\xa0\xad}\xe9\xf3\xdb\xe1\x1a\x14\xd4\x02\xdc\xc8\x1e=\xeb\x1c)\xdc\x8d\x88L\x95\xfb\xc5\x18\xe3st\xfc\xcak\xa7\xf2\x861b\xd0\xb2\x0e&\x0bi]\xb4\xe5\xfb\xd3\xf7\xa3\xee`\xd0\x92\xea\x8d\xc9\xc8lfT\xc6\x8b\x89f\x93\x88>\x15\xf23\xfe\xf5'\xd3a&\xb6\xd3\xfb\x8e3\x11\xae\xd2\xbf\xfeT\xba\xed\xcb4\xae\xdf\xf7\x92O\xd3\x94*\x8eA\xda\x0cM.B\x86\x05\xb0\x9c\xc5\xdf\"\x9f\x7f~\xf2\xc3\xc9\x9b\x13\xce/\xb9\xc2\xee\x0b\xf5\xdc\x07\xe7\xe5\xab7\xa7/_\x9c\xf1?_\xbd<\xc3O\xaf\xde\xbeq\x0c\x0b4\xd3\xba\x9c\x89\xf4\x17\xad+\xaeIe\xd2\x13\xdc\xbe\x82\x97\xc9\xfcV?e;\x8dC\xb3+\x96!\x16\xf5G\x1f\"Bnm\x9c\x9ez9/\xbd\x9c\x7f\xe6T\xe6\x95\x93\xff\xa6I\x91\xf60\xd6\xb5\x0d\xbbFX\xa8\x1a\xe3\xaazb\xaf$\xb4\x8e\xb1TC4\xdd\xa4A\xf9\xdc\xa6\xd1X\xa9);\xac\xf2|\xd0\xd9\x9fF\xa2\x1b-\x19Y\x8c\xda\x17\xca\x90D\xb7\\\x84\x96\xc7q,\x83nDm\xa6\x14M\x9c\x85S\xf5|\x04\xb34$/\xd5L\x0f\x87#\x1f\x0e\x87\x07\xfc\x9fC\xfe\xcf\x03\xfe\xcfC\x03\xba\xcc\x07)\x9b\x87)\x05\xd8\xed\xc4\xd2\xb8\xa0.RK]jV>\xddZ\xf6:\x88\x97UwS\xa1\xd4\xce\x92\xb9\xf5\x80\xbe\x04\xba]\xf7\xa1\x0b\xc45+OQBG\xcd&\xeb\xa4|,\xea\x93\x11\xf4\xd8\xe0{\xa5r'\xfc\xe7k2\x08\x02\x86^\xe5?\xb3M\x12g|{\xe7\xfc7j\xce]W_[\xa3\x9a\xd3Z\xd3%\x17\xd0\xad/H\xe6\xb0\x97f\x1b[(\n\xff\xe7\x8f?|\x9f\xe7\x1b1\x0f\xbb\xa9&\xdc\xd13\x0e4\xeck.\x05\xda\x8e\x87\xad\xf4\xa9\\\x83\x101\xecD\xa4\xe4\xa3@g\xe3bN\xa7gQ$\xb7Ml\xae\xeb\x91\xb1\xc4\xee2\x02f$\xd5\x1f&\x8c/N*\x1a\x7f\xfb\xfa\x07G&\xa2\x0f\x07\xda[\x18\x03+\xfb\x93\xfcg_\xecG\x9fWj\xf1y\x91&E\xd5\x91\xa1\x17L\x0f(\x7f\xf0ejn2v\x05\x8f\xf1\xc1$\x97\xcb\xe7\xa3\x8f`\xd1\x99\x1a\xcb'\xad\xba\x86\xbe`\xf9u\x92\xbe\x97\xe6uX\x04a\xc4\xe6&\xdf\x0f\xf9\x88\xaes\x8a\xfe\xfd\x0f\xe9|\xc3b7Q\xc7Q \x9d\x7f\xe1\xe5&'\x8cg\xd1v.\xe2\xd4%\xa5\xd3\x1e.Y\x85\x18\xa5\xec\xb8tND\x15\xd5\x16\xddn\xe46\x96|\xc1\\m\x17\x05\x17!/\x0c>\x00 B;\xf9G\xcb'\xe4\xea\x95\x80:B\x03\x8b\xbb\xb4|0j\xe4 c\xf1\\\x0f\xa6\x9ah\x87n*}\xa0\xf6\xd2&\x95\x9a\x89-\x92\xcf\xc1&\x89n\x17a\x14\x99\xbc\x82\xd5_\xae\x9e\xc1\x163[\x90lQ\x8d\x85\xf6\x07\xd1xiqv\xbai\x94\x9bn\x19\xdd\xbb\xeb\x0d\xc8\x98b\nd\x1b\x1a\xb7\xc0lQ\x14\\\xc0pLQ5\xd5J\x13\xa2Q'\x10\xcd\xa4*\x8d\x9b\xf4\xc6\xe5\x03\xd1|\x13m\xeb\xa9\xfe\xaa\xb6\xd0\xc6\xcd\n\xb5\x18\xef2\x89\xec\xdd\xf2`W\xf9Ml\xe9\x9eQF\xffE*KN\x910\xdc\x9a&\xe7J\xc4\x1b\xcd\xe0I\x11N\xfa\x88k\xd6\xc2\xbf\xe2Y\xee\xa2s\xfd\x8b\xe0E\x9d\xcee\xd7!\xae\x9a5\xdb\xfd,\xc8\x18\x0c\xc7V\xc0\x97\x0dX\x8f\xd7\xe5\x83\x0d\x1d>\xb0\xb7$\x1f-\xd9\x80\xb8z\xd5\x10Y@>\x98\x86\xad\xb9\x18\x0e\xe0\xeea\xfb\x00\xf0J\xac\xcb\xd7\xf4\xf0\xa0\x85\xdb\xc8\xc0\x86\xadm\x06\xd3\xa8\xd73'\xea\x94\x8fY\xf2\x82\xe6\xc9\xe1\xa4F\xf6\xfe\xb9\x0c\x1b\x92<6\x83\xa7\x13\xb8\xfb\x90On\xc6!\xeb\xde\x03\x0f\xd7z\x06}\xb8\xfb\xd0>O\xe5\x95\x8b\x0d\xdc\xbf\xa7\x1ax0,\x1a\xb8\x7f\x0fz0\xb2\xdc\x10\x86\x1d\x1ch\xa9\x97G\x0fT/\xa3\xe1Ac\xf0<\xf9\xa8\x15>|\xe0k\xcb-p\xab#\x045\x96\xb2o\x10\x08\xb0\xe5+\xf1\xe8\x01\xae\xc4'l3\x1f\xe8\x81}\xa0mPp\xd0\x0c\x05\x82\xc4\x98\xa0 \xfd\\(H\x7f\xe7P\x10\xea\x10\xf1\xeb\x83B\xfa\xd9\xa0\xa0F;\xba\x0f\xdf@\x0c=\x93Q\xfd\x0f\xf6_\x82\xdf\x05ER\xe2\x08\xfaz\xea\x94\x8f\xbe\xc6\xca\xf8\n\x15\xab\xa2XVP\xf2\xf2;\xb8w_2\xaa\xc7\xb0\x85'pp\xef\xfec\xe8\xf5\xb6\x1e\x04\xd3-\x86#\xfe\xa3\x03=p]\xfeqt\x1f\x8e\xc0\x19:\"]r\x0f\xb6\x05\x97\x1d\xdd\xf7<\x9b\x87\x8d\xcc\x9e\xd6hFo\xb8E\xd9\x9b\xf0\xfe\xca[\\\xf2ft\x9cR\xceP\xe1\xac\xc8\xb4T\xc5F\xcdRj\x94%\xb6j:I!\xf0=<$\xf9\x8fkNw\xefi\x7f\xdf/\xfe~\xa4\xbd\x1f\x1dh\x1f\x12\x0e\xfb\x87\x8f\xf8\x8c\x12\x0e\xfbw\x0f\xd4[B\xdc\x84\x10W\xbd%l\xc4\xb7\x8f\x86\xea-a\x0f\xbe\x1d\x1d\x1cX\x04xtd\x80>\xc4*\x1dh\xce\xd7P^(BE\x9b\x8b\xd3|K\x0f\x1e\x12\xbdO9T\xfb\x80\x05\x83ib\xb1\xdd*\x82\xc1\xeb\x1e\x0c\xef\x1a+\x8f\x1e\x1d\x00\x0e\xf7)\xdc?\x87\x1e\x7fs\xf0\x10>\xc0\xfdC\xb8\x03\x9dZ\xbew\xef\xe0\xd1}5\xe7{\x0f\x0e\xef\xde5utppWv4:\xd0{\xa2\xbe\xe1\x0e\xdc?\xdcm\x00\xcd\xd6\x87\xb0\xc1v\x80\x10\xd2\xeb\xe9pW2*\xbd}}*\x94\xb1\xb7\xafOa\x1dD\x8b$]3\xab\xdb!\x08\xfb\xc5hx\xc0\x07]\x81P\xdf\xb4\x18w\x87\xf0\x81\x12\xc5\xdd\xbfw\xef\xf0>b\xad\xa8\x9ex\xf0\xe4 \x8cx\x81\xd0\xf3p\xbd\x1e\xd6\xd6ktP[\xb0\xe6u4\x0e\xbc\x03\x01+\x02\x890\x8c\xfbT\x12qs\xe8\x15\x80\xea\x95c7\x96\x15\x95\x96\x88\x05\xd4\x97\xe5\x8e\n\xef\xd8\x94\xb9\x85#K\x98}\x17\xc6!E\xe4:\x02\x87\x93?,~\x99$\x11\x0b\xe2zSG\xe0\xe4\xe9\x96!Y\\\x04QF\x7f9\xfa\xb8\x0b:,\xf5\xa5hw}\xc9\xae\x1e5\xc51,8\x02F\x1e\x18vQ\x87h\xd1\xc2\xc5-&\x0c\xa4[+U\xa5\xc8\x9c\x0fX9\xf1:w\x04MF\x87UgR\xb9ht\xa5\x12\xfa\xd2\xd8\xca_\x89\x0e\xd8\xa2\x18%bD\xba\xe6H\x96\x03<\xb3\xa9\x7f\xe4\xf8B\x99b'\xf6d>\xa6%,qM=\xe3\x83\xcc1\x1c\xa8\x88$\\\xbd\xdbrvL\xd9\xf29GZ\x10+Z\xc0\x13\xd8r\x1e\xb4h2\xe1S\xaa\xe1EC\xa6\x879\xa5$n\xc9\x16\x11\xba\x19\xe6\xb7\xedU\xd3A\xca\x87\xafm\xf9\x12\xf8\xbcQ\x08Skp\x05\x13\x98\xab\xf9\xaea\x02W4\xdf%\xcds O\xe0\x8a\xcfs\xe9\xc1\x8c\xd3\xa4\x15\xf4p8\xf3\xe9\xf2\x9c\xf3\x1b^`-\xd4\xb0\xde\x04\x9a.V`\x08+\xbep\x91^\xdeLp\x88r\x97{\xe4\xdd\xb5W\xaf\x8bj\x02gf\xedDL\xc7o.v\xa1\x8f<\x024\x995\xbe<\xba\x04\x86\x88_\xa1-\xea\xc6\x87\x0f2[\x8fdFJ|,\xb7`\xa8\x9d\x17\"CM\xec\xba\x12)\xf1c \x08\xb5%$\x8fp\xdbW\x8e\x1b#vXn\x94P\xbdN\x8e\x93\xc1:\xb8\xf93\xbb\xcd\x94\xee\xae\xde\x18\x86\xc5\xd1m\x04\xfbU\xb5p\xa6\x84 ^`f\xa8\xb8\xc1m\x93T\xd2443\x15\xaa\xdb\xaf\xb0\x9b\x0d\x8e\xb3\xfe\xd1&\xc0r\xbc\xde m\n}D\xe1\xe9\xb9\x8f\xc86$,\x1b\n\x0c\xf3\xf1\x94\x99\x13\x96K\xf1\xff\x05\x9d\xc1\\\xd3\x7f'T\xe8\x86\xb0\xf1\xa6\"\x00\xdf\xd8\x04\xe0\xb3\xaa\x00|c\x11\x80\xcfp\x8c\xb9^tm\xa5\x1c\xbc\x82\x18<:]\xb9\x87\x0f\x10\x1c\xcf\xe0\x08\x07:\x821\x9c\xa8\x9d9+\xc4\xe0\xb3B\x0c>+\xc4\xe03RJ\xd5[\x12\x83\xcf\xa4\x12 G\xc0es\xe8\xf5(\xc2\xda5Y\x9b\xb1\x8f \x86\x91\xe6\xb4\xc7j\x0e\x035CJ\xba\xa2\xcdp\xd9\xaa\xa0\xf2\x8a\xbd\xde\x12\xabn=\xb8\x82'\xe0\xbe\x87 \xdc@\x1f\x96\\B\xa38\xd5\xb7\xba\x04~\xe5\xc3{N\xa2\xc4\x96]a\xf1^\x9bIl\x96\xc4y\x18ow=\xe6\x03\xe1\x0d7\xe4\x00\xf3\x9bo\xc5Ee+\xcc4\xdc\xf8\xf6\xee\xa1\x18'o\x077\x10\x8e\xc0\xe5\xebz\xa5\x86[]\xd6\x1b\x0f\xe3\xa9q\xd2\xf5\xc7\x83\xa1\xc0\x11\xea\xbfR\xf3\xd2T\xf3R\xaby-\x8f,\xd4\xf6\x188H\xa1\xb7\xf4zk\x1cn\xd6\xc4\xe5\x8f}\x90\xb0\xb1\xb6o8oN\xce\x97\xc3\xd3{\x1b\x04\xc1X\xfb^\x9d\x10B\x98\x8c\xf88\x81\xc8\xbd\xf5a\xc3\xdf]\x8b\xe2\xfc\xdd\xa5x'\x8e\xc4W\xeaH\xfc\xd6\xf3 \x98\xde\x9ec(KXMW\x82\x96\xf0\x17\x86\x9bY 4(\xf7\x18\xe5\x98\xdbsO\xbf\xa6\x85r\x06\x1c\xc1\xf1\xf4Xk\xe6\x12\xc6\xb2\x8b\xe9\xb1\x0f\x97\x16\xc5\x8c\xaf\x06\x06\xf5\xea\xf7\x17^\x93\xc1\x8cou\x99\x16\xdeb/D,\xd5.\x12UE\x8c\xa8\xef\xe7\x1f\xec\xbf\x16\nt\xaet\x95\xe5\xc3\x07X\xf2/^\xfd\x93\x0e\xb7\xe5\xdd\xe3;\xb7\x86'\x90\x19v\xce\xfb\xcc}\xe3Hb\xdd9D\x84\xcf\xd9\xa3\ns\x90B\xc5\x1f\xcak\xd69\x93\xc1#K*\x83\xc3\x87#\xaf\xfdtO\xba\x13\xc8\xebpp\x04\x7f\xffH \x0dAB\x8b\x91\xeb\xc7e\x9d2]\xea\x03\xaeF\xd5\x13\x03\x1e\xb6GI\xb4'\x85HE\xa7\xad~p\xa2|\xe2\xb2Z\xfa\xb3\xd6\xc8p\xd69\x8d\x0e-s\xba[M[D\x81\x05\x1f<\xea2U\xc3\x0cJ\xfaT\x7fD:\x94\x12\x16Qt\xfc\xfbG.\xad\x04\xa83\xd9D\x16\xbc\xf01\x0d,\x9a\x10\xe6\xe9\xe3#\x88\x0c\x82L\xec\xce\xf8\x07\xa0\x98\x81>\x84nDA:g6\xbd\x18\x8aU\xcfv[`\xf3\x19\xeb\xfe7{E\xdb\xdf\xc0,I\xde\x87L\x7fs\x9cln\xd3p\xb9\xca\xdd\x99\x07\x07\xc3\xd1A\xff`8\xba\x0b\xaf\x93u\x10\xc3\xd9*\xbf\x8d\xd6A\xdcT\xe1\x1e\x1d\x9e#\x0f\x99\xa3*O\xfcf\xc4\x99H)w\n\xc4\xd3\x0d\x95\xc3?&\xb0u\xe7>d\xed\xa1)M8SI\xe4\x9d\xb14\x0c\xa2\xf0\x17\x93~\\],E\xa0\xc4v\xd7WZ7O}\xf8P\xbdm\x88pY\xa8n\x05d\x86\x16\xc8L0\xa9\x1e\x88\x06\xc3\x0cB\xf2\xfe\xab\xee2\xeep\xd0\x12\xa8R\x81y\x1c\xac\x9b\x1a\x93\x1auX\x8b4A\x07|\x18\x9e\x9b\xfa\xda\xb6\xf6u\x15D-]\xe1uu\xe8\x813q\xa0\x07\xdbz\x8f\xc2R\x06)W\xb5\x9f-\xadW<#(\xca@\xdft\x18\x8b\xc7\xd4\xd9\x8b\xe0\x85\x1b\x99\" \x89\xaa\xd9\n\x831 \x0dxA&\x00\x03\x14g(\x98?\x86\x1f\x83\x9b\xfe\xb3%\xc3\xc1\xff\x18\xe4\xab\xc1\"J\x92\xd4\x8d\x9a\xa87\x1e\x87\x0c\xe6\xc9:\x08\x8d=\xe8o\xb0\xd7\xe4\x15$'(\xfa\x98\x9cUe\x9b\xea\xd3\xe6\xdd\xe0D\xc1\x8d\xb3C\x87?\x047\x9f\xd3\x9b\x90\xc5v\xe8\xf0sf\xd8\xeaF\xd4\x04\xf4j\xbfu\xa8\xaf\xb5\xd4\x81\xffj2k1L\xc9Y\xebF\xca\xba\x1aP?N\xa9\xab\x04\xfb\x8f\xe1\x9b\xfd\xf2k.\x9a\xed\xff4}\xb7\x1d\x0e\x87\x8f\xf8\xbf\x07\xc3>\xff\xef\x01\xe3\xff>\xa4\x1f\x8b\xc5y\xef\xdf\xf6M\xc7c\xdb\xdf\xeax\xac\x1a\x93\xb9\xfc\xd7'I\xf8\x1dC\xaa\x8b\xfek\xcb\xeb2-\x1c\xc4t\xefk\xd7\xfb\xe6|\x7f\xd9\x16\x8b\\\x1eK\xa0\xbbF\xc9\x9e;\xf4J^\x1ae'\x8d\xf2\xec\xdb4H\xbd\xe3n\xb3,\xb9i\xc8\x1c\xf32+\xb2\x92\xc7c\xbb<\x9eV\xcd\xd3\xb1E\xe4N\xd1U\x00\x1d\x07\xee\xdc\x81\x14m\x97\xf7\x0fG\xe8q\x11C\x0fF\xfa\xc9|\x83X^s\x08\xc1\xca\x16\xc1\x9a\x0e*\x9fbW\x07h\x1c\x12n\x1c\\un0\x1c\xcb\xe3\xcf\xd1\xf0\xe0.|C\xde\x1a8v\x0fz\x90\xf0\x1f\xd8^\x8f\x8e\xf2\xed\xe4'\xa7\xebp\x07w\x87ey(\x84}\xb8\x7f\xb7\xf8\xc7\xf3at\xf0\xd0Z\xc6\x83?\xc2\xfd\xbb\xd62\xe5\xcf!\xfeB\x1f\x84^\xa3\x1bg\xa3\xbd\xban\xf25\x9c\xc6Qh\x89\xbb\x0f1B\x04\xcd\xf4\xe0ny\x84i\xf3$S\xc3\x04R\x9a\x00\xe7\x97\xbc\x03\xfeR\xb5?zt`l\xa0^WTH;\xd8\x0d\xda\xd2O\xea\x90\xb2gw\xf3\xe7@\xc3la\xf9\xedF\xb2J\x91\x86\x0b\x96(\\\xa6z\xfe/\xcb\x19\xb2\xc4\x93\x86[d\xa1\xddAs\x9e\xb4`F\x80V!v\xc3f\x8d\xa9\xc5\x94\xb62\x99L h4\x0d\x83\xd2\xcbCx\x02\\\xbao)\x9c\x90S\xcd\xf0\\\x19\xa7\xc2^\xcf\x0c\xc8p\xbd\n#\xa6\x14'>\x14s\xbb\xd2v\xc7\x81N\xf3x\xe9\x8f\xcc\x19r\xfe`\xdfIK\x8a\x00\xd0\x9d\x04\x85v\xbaS\xbb\xc2\xach\xa3\x8eZz\x8d;\"\xbd\xc1\xd4\x99\xfet\xee\x9c\x97\xcd\x07d;\xe0\xa2l\xcd\x9e\xa3\xda\x12\xa4\xbd\xed\x92\xf0\x0ea\x81\xb0\x1a!%\x1bd\xc96\x9d\xd9\"Fx\xbe,\x18\xca\x82\xe48\x98\x0efI<\x0bD\x10Gv\x0d\xaf\xd9\xf2\xe4f\xe3\xa6\"\xe0\xcf\x07\xc7\xab\x99]\xc1H\xba\xd8`\x11\xc6\xf3\xe3U\x90\x9e\xc6sv\xd3fB\x93\x0f\x87\xd1\\\x87\x0f\x85\x89\xfd\x86\xb3\xa22\xceZ.>\x95,i\x89\xeb\xf9\x02E\x0b\xd7\x98X\xa2\x1c\xda\x1c\xdcx\x10\x05YN\xc3\x7f\n\xb9\xf7\xd8\xe38\xd0\xb8]\x86\xfc\xcc\xbeX\x8aoos\xb6\xd3R\xc8\xd9\xf0\xd5\xc0\x1b\xb4\xb4 \xe4\x95\x858\x83\xf5q&\xe6x\x8b\xc4\xc5\x9fu\xbe\x1a*\x17\x87n\xa6\xebc\xa6j\xf6\x0d\xe0\xd2\x0c\x9e\x88\xc6\xc6\xbd\xb3EY.\xe4\x1b\xe5\x98\xc9\x85\x8d\xea\x89\x88\xfe$\xe8t\x84\xfb\xd4\x92~KQ\xc6\x84\xeb\x8c\x94)?\x99\x0e\x8dq6tyg\x97\xd5j\xbd)\xa3?r\\Hc\n\xdc\x92(\xe8#\xb50\xee%\x7f>\xb6\xedA\x8a\x06W\xd9\x8b\xf1^\x0c\xd8D\xbc\x96\xa5$\xa9\xf2\xc9\x84\xbcA\x92B\xb4+\xcd\x89\x8f\x15}?\x87\x9e\xafdN\xe95\xca<\xa7\xd0=\xa8\x07\xee\xa2Q\xe0\x10\xde$\x9c\xf4\xbdJ\xc2\xb8\xc5\xe6!\x9f.\xb6\x0f\\\xdb\x99lW\xae\xb1\xc6=DjIU\xc4\x13\xd6\x12\xa1~j\xef\x1b\xa7o\xe1\xfajBo\x84\x85\xe8\x8bM\xac?\xb9\xcf\xd7\xf2\xf9w\xdf\x9d\x1b_\xeek\xbb\xfeQ\x1c\x16t=\x13\xf8\xba\xdf\xef\xbf\x8b1\x00\x96\xb3\xca\xf3M6\xde\xdf\xdf\xb0\x1c\xf3\xdd\x0f\xb2\xeb`\xb9d\xe9 L\xf6\xaf\x0e\xf6\xe5\xaf\x9f\xb3$v\xde\xc5\xf3d}\x11\xce\xc7\xe0|%>\xf4\xb7\xa1\xf3\x8e\x0e\xc1\x82\xd2>\xab\xa60\xf2\xc15-\x07\xf4a\xe6\xc1>$\x1dg\xa5?ie{\xb4\xa3\xc0\x0cz\x10\xc17d\xee\x1d\xdc\x83#8\xc08\x0e\xdf`$&\xfe\xbf{\x17\xfa\xf4\xd2C\x95\xd2\xa6\xe0\xd8\x9e\x02Py\x17#\x0e\xac\x08\\\xdf3t\xef\xf5\xf0\x00\xf2 \x10`\x0f\x88L\xd37.\xb1\xa0\x0b\x90\xbe\xd2\x81\x0f\x8f\x1eiPo\xc7\xce\xea\xf3\xd1\x87G\x1d\x8b\x7ft\x9b\xcb\xd9/%5\x90\x84h\x07S\x85|2wK\xf1\x9e\x8dG4\xf2\xb1\x84\xb4\x93\x8c\xc8N\xa4X\xbe\xdd\x8c\xbb[\xbb\xa1h\xd4\x1571\x91*y\xeap\x8c\x8fU|B\x87\xe6\xdcS\xc6\x9d\xdck\x8a\x1d)\x1f\xe1`\xf4|\x9b\x8a\x00\x90q;\xb8\xb3\xf9\x92\xbd\\,2\x96\x9bBz\xeb\xcf'\xed[\x9e\x8c\xc1\x92\xab\x80>\xff\xd7\xb8\x89\xd6\x85q\x9e\xfc%d\xd7\xe5u6]\x9c\xad>\x92Wc\x9c\xf0o\x93m<\x0f\xe3\xe5q\x14\xb28\x7f\xcdf\xb9\xeb\x0dV\x88'\xed+\x14H\x8a\xae\xf8Z\x0f\xc2\xf6j3YM\xe2j{\x95\xc5N\xbcc\xc3Q\x02zm\xa1n0\x05\xf2\x13Xp\x88\n\x91^<\x85\x19\x1cQ\xbc\x01Z\xc91\x04\xe2\xc3\x06\x8e s\x03N/\xf9\x9b\xa2\x00\xb1\xd2\x06\xccn\x80\x81\x19\x8bs\x96\xd6\xb60\xed\xb0\x8b\x99\xdb$]\x94I\xe1>\x1c@\x8f\xa3\x0b\xc7\xaa\x96]\xe7\x85=OL\xefS\xe6\x94\xe5\xc9f\x0c\x81\xbd\xc0:\xb9\n\xe3e\xc7\x0c\xfcP\xd0\x86\xbd\xbd\xfa!\x90|\x1a\xc6\xc3\x81f,\x80\xa7\xb1\x14.\xdfX[Jca\x833N\xbdUN\xb3\xa4\x14?\x90\x7f\x9cDl]s \x04\xc1G[\x17C,\x82\xd0E\x88\x9f\xfd\x17\x1a\x91\xc5\x8f7\xc9\xa6\xcb\xd0\xd0j\xef\x9a\xfb\xa0x\xd7j\xe0\xd4n\x18/\xc5\xc8yo\xea#/k^N\xa4\\\xddd\xe5\xd2l\xde$\x1c\x92wL]\x81\x9bkIN\xa9P\xa0#\xac\x95\x978\x8cc\x96\n\x89\x01\x97y\x86\xc8Bov\x1c\xa3\x00\xadn\x8b\"\xf5T+\xa2\xe6\xc9\x86\x93 \x14\xde\xe2A\x82,\xca\xb4\xfb`\x06W\x83\xb75\x06%\x0drv\x86\x1bQ\x8b\xeah\xa3G\xd2N\xd5\x08N\x96D2e(i \xcb\xaf \x9c\x03\xef\x8ek\xff_\xbb\xed>k@'h\xec\xe8S`M\xc9\xe7\xac\x04^~' \xdc\x15S>\x0d\nw\x86/\x01/\x7f\xa8\xbct\x82\xf9\xfc\xe4\x8a\xc5\xf9\x0fa\x96\xb3Xd\x0c*L.{b\xcaq\xf2\xff\xb2\x98\xcc/\xf8\x9a\xb9%\x9ac\xbc'&E\x1ag\x15fy\x92\xdeV\xad9\x9bm\xb6:\xcb\x83\x9c\xcc<\xa2\x90y\x9d\xb8L\x13\x92 \x08\xe1\xe05\xe3\x85Qj\xd4+\xd7%\x0b\xcaT*>\x0fj\x95\xf9\xe8\x82m\x9e8\x9e\xda\xdc\xea\x82\xb8N\x94\x04s\xc7o\x87 \xeakWE\xb1ql\xeb \xde\x06\x91%\x86=Wq\x1a\x86\xbdI6\x19\xaen\x9b\xe7\xb5|\x18\x86\xe8&K\xdc/,\x16\xdc\x8cRH\x15\x9f\x12T\xf1\xc4\x8bAQ\xce\x06\xf7\xb0\x87\x97\xf3\xc40e\xb0\xf7\xc1*\xc8\x10\x92v].iUL\x06\xa8\xd0\xb8\xde\xa0\xd0\x08\x9aO\x0dZ\xedC\xd2h\xa7 {\xc9\xa4x\xf0\xed\xed\xe9\xdc\xadM!e\x0b\x99\xc1\xef+\xc7\x9b\x8e\x9a\xf2\x05\x83t\x8ek\x1b\x05\xd4\x0c\x05$L&\x850\x99s\x1e\xc3:\x88\xdc \xe4\x98D\x08\xe9\x9c5\xb5+\xf4Cx2\x81\x14\xc8 \x1d\xd0\xff\xdc \x124\xa8\xa8\xd0\xac}\xd9\xa1\xd9D\xb6\xf6L\xae\xebW2\x8aO\xe1\x86\xe5\xb8?}x\xf7.\xf34J\xe5\xbe{\x97}\xf87\xcf\xe4\xc2i\xc5\x9aY\x14\xce\xdewB\x99\xd2\xb1!\x1b\xe4A\xbad\xf9c:\x89q\x9e9\"\xd8L\x1e,_\x04k\xf6\xd8\x13G\x9f\x9b eq\xfe\"\x997$\n\xdfs\xf7\x90\xb1\x8c(\xe0\xd7\xe0z\x15\xceV\xa4&`\x1a\xc8?\xb3[\xfa\xb5fy\xa0~\xcc\xf24R?\x82\x88\x97j\x8c\xfd\x82\x16\xc86h\x94\x90\xa8\xa8\x94\xa2\x10\xf5\x08d\xe52G\x95\xdf\xe3\x9a\x91\xbc\xfa\xc4\x1a5\xd1\x80\xb6\xb9R{\xca?\xd0\x88\xac\xb8\x96\x82\\\xc7\x8d\xeb\xe7k\xd5\xa7\x94\x02pW\x90\x06\xdd\xc5\x0b\xb3\x18\xe4y\x1a^ns\xe6:\x9cv8\"\x85A3\xd9\x12\xc6\xfe\xe2\xce\xf6W\x0e\xf9\xb7n\xc9C:\x1f\xcc\xa2 \xcb8\x90\xb5\x86\xfa\x91\x06\xdf\x06\xb7w\xf9D\x0d\x840-\xdcZ\xdcQ\x9b\x89\x10\x8fW\xber\xc4\xd1j\x87\xbdB\x0c\x88\xe4\xd1J;\xb9\xca$\xac\x10q\x8c>\x95.\x01egJ\x19'\x08\xcf\xc94\xd5\x06}W\xe2\xcac'\xd6\xa5?\x15^\x02\x93\x16c\x164\xab\xd3\xf2Y\xec\xcc\x19\xa9\x16]\xff,3\x9c\x0c\xfa\xb0@/\xeb;\"x\xd9N\xb3\x94(\xa7\xa4<\xf7\xef\\\xdet\x8c>^\xfa\xf3\x11C\xbb\xa2\x94\x91\xf9\"\x83\xf4\xac\xc1\xe8af'\x16V\xf2\x07{!\xe9\x07\xa7^~t\xcb\xdea\x18\x9e\xd1\x18J-\xc5[\xad\xc1f\x13\xdd\x92\xa7 \x8c9\xac\x7f\xf8\x00\xae~\xa2\x1c\x9a\x0f\xa0;\xdd\xc9\x13\xc1\x1b\xe9\x94\xb2\xc8\xc9\xe7\x83sq\xc1\xb2\x1f\x93\xf96\xe2\x92^y_0}\xdbX\xcf\xc8\xa0\xeb\x99\x926m\xdc\xd8\xbd\xeb\x19\x02\xa8\xf0\x0f\x07\xd5\x0f\xa1\xf8pX\xfd\x10\x88\x0f\xf7\xaa\x1f\xb6\xe2\xc3\xfd\xea\x07L\xf6\xe0\x0e+o#,^MJ\x85'G\xbc\x15\x94&\xf1\x0f\xb2\x88\xb9\x87\x0f\x1fT\x1b^P\x94\x17\xcft1\xd3\x90\xf4Y?\x83f\x83b=E\x9c\xd5:\xac\xcb\x9b\xb1-\x97/A,2E\xbdX\xb1h\xc3\xd2l\x90lN\xe7\xe5\xe1\xb6;\x02\xaa\xd1\x0b\x7f:\x0b\xfe\x91\x9c(F\xe7\x89Lj6\xcf:\xa9\x9e\xf1JA\xb5\x92\x9b\x0f..0\xfd\xd9\x05\xc5\\\x1b\xfa\x18\x19R\x16\xf2<\x91#\x11K\x93{g\xe3\xc1D8\xc8\x93\xe52bg\xab\xe4:\xeeJK\xa4\xb0\x1f\x0e6i\xb2i9c\xcc\x85\xd3\xeem\xb2\xcd\x9fa\xdb-\x15b!\xb7-\x9b\x8b\x91\x97\x1cG8$\xd5\xd5\xcd\xab>\xc25;\xc3\x896\x17E\xad\x96s\xae\xd7,K\xa2+6?\xdb^\xe6)k<\x0f\xc53P\xcd?'@;\xf9@$\xc6\xa95\x84!KV\xc9\xb5;u\xd4\x0c2\x87\xec\xd9\xe7>\xec\xd9\x9c\x9a)u\xcfq\x10\xcfXt\xccE\xe2\xae[\x869j\x04\xbdo\xde\xae\xf4\xf64\x7f\xb9\xcdO\xe2\xe02b\xf31\xec\x85B\xa7\xac|\xb1\xb6b\xc8H\x03\xc5\xd8\xdf\xa4\x1c\x10v\x1a\xfb'\x80[\xb6a\xb3\x1d\x80m\x13\x98b\x8a\xea\x0fA\x1be,j\x10\x0c\x7f\xcbU\xe60\x84.\x1b\x7f!\xbf$F\xc9\xc11\x87ejs\xab\xa3M8\xb9a\xb3m\xde)q\"\xec2-F\xed\x9e\xc6\xaf\xd2d\x99\xb2,\x1b7&\xf2n\x18c\x1d\xfb\xba\x0e\xf6\x13\xa1\xe5\x8cEl\x96'\xe9\xaf\x00/]\x08\x13\x1f\xc2\xab _\xd9aK\xdd\x07\xc0\xac\xf6\x1b6\xab\x12\x15.\x9b\xfd\xe9\xcc\xf5\xe8\x12\xb1\xa9\xc4\xd4\xe1\x03Wt\xa6a\xf9\xcdt\xebW\xde\x82_\x0da\x7f\x85\x0d\xb0\x10\xf6\xf2\x1eX\nu\xdf\x06R\xd1\x9b\xb2\x00\xd6 \xc9\xc8>[\x13zZr\x8a\xfb\xa6;\x97\xb57\xca\x11\xc1\x87\xad&\x85\xf8\xc2\x07\x81OA\x7f;5\xcf\xe3=\xbb\x1d\x83\xb3\x0e6Hb\xde$\\\x8c\xce\x1c\xf34\x84\xe8\xdc\xd9]B\x1aJ\xf2A\xb2i\x07\x98\\\xc8)\x1d\x89A\"\xc4\xb4\x9c\xdc\x1d\xe3E\xb8\xcc\xbc\xb63w\n&?Of'7\x9b \xce\xc2\xa4\x834\xc2\x85G\xb6\xf9!\x8c\xdf\x87q\x8bX\xb4\xa5\xe2a\xb6\x89\x82\xdb\x97]\xa5\xa3L\xaf%R\xd9I\xff\x8f\xe6\x9a\x11\xa9\xb6\xdb\x0d\xd7\xa6\x10\xc6\xd7a\xfe#\xa2]\xcb\xeaa'OO\x16\x83\x1f\x83M\xab\xd2\xfe\xb3\xd0\xf4\x17x\x13\xfcOg^\x0b\x8b\x03T4\xc6p\xda\xdc,\x7f\xf2`\xd9\xe9\x86\x05\xa7\xdfV\xef]\xfd\xc9\xa4\xee\x91[\x14-\xfa.\xf4,\xc7\xc2\xdd\xf4g\xce6)\x9b\x059\x17\xf1OI\xf3-^9B]3\xf6\xa5\x15\xa3\xee\x9a\xccS\xf2!\x0e4\x86\xa4\xbdh\xa1\xa7t\xb8JQ\xd6UZTi\xa8\xaa\x8a-j\x19\x96\xaf\xdb \xc4\x82u\xb7X\xb4\xf7R\xd2/;\\\xf0SzU\x8b.\ne\x15\xaaE\xf6\x80\xbaN\xd9B\xf2AW\x81Z\xf4O\xb0\xe8\xc6-\xda(4\xe8\xc7-B\x12X\xd5\xfd\x16\xce\x0ff\x89\x96\x04b<\xd2\xa9}mo\xb0f\xd6\xd5\x9a\xebzB\x04P\xf7_\xd7\x1fa-\x89\xa4\x89V\xb8\xb5\x0b\x8f\"\xf7\xc7\xb6\xabb\n\x9c\xc7\xf0s\xf3\x8c\nm\xba\xcdh\xdf\x11<\xba\x82\xb4v\xb6-\x96P{\xd3\\\xb5tR)*\x97\xde\xb5U\xd7\x0eiUu\xed][uqD\xa7\xaa\x8a\xdf\xcd\xd5\xa4<5\x86\xcb\xf6\x82\x82\x95\x8f\xe1\xba\xbd\xac\xe2\xe3c\xb8h\x19y!$\x8c\xe1e{Y\xad\xe5W\xcd\xa5K\xf2\xd0\x18\x8e\xbb\x94\xd6Z?k.\xaf Och\xd9\x9d\x92\xe44\x86g\xcd\xa5u\xc1r\x0c'\x1d\n\xa3T9\x86\x9b\xe6\xa2\x8bx\x0co\xac%l\x87\xab\xb5\xb7\x1f\xcf=\xbfrO\xe4\xa3\x9b\x0d^mSfJ1\xb9\x92\xe4\x02-\x1d\xb5\xb3\xa9\x12s\xda\xab84\x16t\x00\xdd\xc7J\xdf*\xbc\xa4Z\xd5\xc4\x0c\xaa\xb2\x84\x8d\xf2k\xc6\x05\xcc\x15#&\x00\x13\xa0\\\x14\xbf7\xc7\xaf\xc8\xe6\xf8\x15\xd9\x1c\xbf\"\x9b\xe3Wds\xfc\x8al\x8e_\xfc\xc3Pw\x1a\x8a\xc8\xb9\xcb\x92k\xfa\xb7\xf6\xd9\x9a5\xfadi\xfeX&k\x8cv\\ip\xc7\xf2?\xd9\xe5Jx\x18bq\x992\xa7\x9a\xd6\xc8\xe8\xd4\xf8\x19\x07\xa7d\xa0Z\xb2\xfc\x07$t\x06)\xbe\xab}j\x17\xdbT\xbe\x83\xaa\x1c\x9b\x14\xdf\xc1l\x9b\xa6\\\xbch\x10t\xd1>\xe9\xc6\x98T\xbc\xd1y\x0d\xef\xe8\xb6\xceO\xab\x90Yd\x1dg5r\xa4O\xeb\xd7\xf0\"\x11\xdc\x03D\xf0\x19\xbcS\xe0|\x8d\xe7\xf5_;\xf0ug\xd2Z\x86\x00\x93@\xd5bg\xfc\xa4=T@a\xb3\xe6\xb6\xac\x06\xa3\xa50\\\xfb(\xcf\xa7\xcc88\xd3\x90\xed\x99\x18\x87Nwg>\xccj|\x84Z\xff\x171\x16\xcf\xfftb\x8c \x8b(\x15\xfa\xd5|a\xb0\x8b\xd3\xac\xba\xf0\xc3WL\x91_\x15_?\x82 \xe5 u3\x8fr\xe8\x0f\x1f\xc3\x0c\x9e@\xf6\x18f\xbd\x9e\x07\xd1tv\xae\xd7\x9c\xce\x0ca\x01\xc5R\xc6x\xe1\xd1\xe6\x9c\x8b\x18\xd8\xca-fA\x14 \x96\xc1|\x98\xf2\xba\xe72\xf4b\x84IZ\xc3\xc1,J\xb2N\xeeV\xc2\xc5J\xb7\xfd\xa11\xfc9G\x85\x10\x7f\xbbU\xffz 4\xc3\x8bZ5\xa6\xc77\xe3\xb7\xe0\\_\x96\xe4ub[\x1d\x0d\x9eqwcj\xba\x03;\xa4\xd3\x15\x96\xa6\x1d\x86\x10\xeeb\xf1\x0e\x84\xf1t\xf0\xec\xec\x8d\xbd\x14\xdfm\xed\x04-\x90)m\x1b\xcc`\x98\x0e\x15\xa1)\xd6\xc1\xa9\x81sS\x8aT\x87\xaf]f\xcb\xd0\xd0\xc6\x8a\xe7\xe1U\x8dT\xeb\x8f\xbaV5\x06g\x1e\x06Q\xb2\xecoo\xacWq\xbfH7\x97\xc1\xec\xfd\x1f\xea\xe57Z<9\xa5>^\xcf\xff\x8d\xfaZ\xb1`\xfe)\x9d\xad\x0e\x95\x1c\xe8<\xbb\n\xc2(\xb8\x8c\x18\xea\xfbI\x1a\xfe\"\\\xb8\x9a6\xfbr\x9b\xe7h\xe0\xb5\x0f8\xbf\xdd P\x89\x92\x9d&\x86\xfc\xa0\x8f\xd3k\xa8\x91\xc4\xba\xb9 \xeb\xec\xbc\x02\xd9\xd5\xb2q\xf4\xd7\xe1<_\x8d\xc19\x186\x0cd%\xa2;\xf0R;\x8f`\x9b\xd5e5\xfdY\xa5l1\x06\xe7+\x9c_\xc3 n\xa20~\xff}\xa9\xb0\x05y\x91\xe9~Y\x00\x9c%q\xce\xe2\xdc:\xfbh\x80|\xee\x8c\xfd\xcd\xf5\x06\xeb`S\xcaI\xdex\xfd\xb7\x85~\xce\xda\xcc\xb6\xc8~[\x0e?\x9e\x9d\xbdi=\xf0\x98\x17,\xc1\x1a\xb7D>e\x13X\xcb\x19\x96\xce\"[\x0f\x81*\xa6\xb8\x96\x93\xdb\x92\x91\xaf\xc5\x00\\1{\xd6\xdd\xa1\xe5c\xb3\xb4y\xf8\xd4\xbe}9%\n\xdf\xfeK_\x12\xcf\xbf\xf4\xa5\xff\xc5\xfa\x92\xe0|]4\xa6\xce\x97S\xf2\xeez@\\\xd7/\x06\x1a}|\x93\xa8\x83g\x9bI&\xafim\xe6\xd4\x15\xffR\xda\xccO,\x80\xac\xac\x8dy\xa4\x8b(\xd9\xedU\xb2\xd9n\x1c4,6+u{{\xbb)>\x89\xa8\x13\x14\xee\xce\xde \x0b\x7f\xb1D\x13\xf9\x92:\x10\xef\xb2\x7f\x9d\x06\x9b\xcd\xa7\x08\xbc\x1d\xe4U\xad\xb3\x04\x8e\xc0\xb9\xccc%\x113\x88\x92\xd9{6w`\\\xfd\xb0\x8d\xc5\xa7\xae\xf2\xaa\xf8\xb5\xf3\x14\xb2M\x10kR\xbb\x1c@\xa3\x98\xfe\xcf\"\xe5\xe2\x82\x7f\xa5\xad\xf1W\x1d\x96U\x13|\x1b\xea\x9bG\x8c\xf4\x14\xddkm#\x8f\x85u\xf8_\x92\x0d\xfcK\xb2\x81\x7fI6\xbf\xbddc\xbd7\xc0\x06Y\x9el8\xd4\x07\xcb\x80\xf8\xb0\x99\xff\xc8\xcb\x05\xd2z,:\xb1\x88&\xe8lop\xa9\xff\x9f(\x8e\x94\x1c\xd5?\x8dy\xef\xc6R9\n\x96\x85\x94\x8b\x0b\xceH5\x9am\xf8\xda\x81\x0b8A\x1a\x06\xfd(\xb8d\x91c\xea\x06h\x9c\xd6\x8e\xe4\xf7\x0e]}!>\xfeO\xc2\x93\xd9g\xf2\xe4\x86\xfa\xe6\x11\xff/\xb4\"\xcc8K\xad\xf1\xd4D|\xa9q\xe1PV11\xdb\x99\x89\x0bo\xc5\x87\x1a\x17\xce\xc4\x87\x1a\x17\x8e\xc4\x87\x12\x17\x9e\xc9\xc8G3\x11\xf9\xc8\xc4\x8fg\xbf=?^t\xe5\xc7\xb6\xb0EU*l\xe5\xb9W\"\xafz\x95\x98[}g\x92:\x0fl W$\x16+\x18$1\xa7\xcd\xc7\xab ^\xb6g0\x02\x8d\xcf\xb1A\x1c\xac-\xbaXP\\[\xab\xb0\xe8\xbf\x7fDL`&\xf4\xe3\xfc.\xc3\xbb\xee|H\x9d\x06S\x0fb\xc7\x1b\xa9\x1f\xdf*\x15\xca\x0d\xc8\xe3\xd7\xd2}\x94,M\x91tv\xe8\xbfY8\x08\xda\x14t\x8a\xab\xd0\xc9@B\xc1\x154\x93H\xcd\xe6\xdd\x1a\x80U@\x819\xa25 \x1d\x19\xe4 \xc9w\x96\x99\xc5b\xcd\\s:\xd3\xa0~\xec\xbe\xc3b\x9a7\xb3\xe3Y|P\x84\xfa\xe0\xbf,8\x0ee\xd9)3\xcaN\xc1?@vj6\xe2t1\xf6\xc4U\x00i\x83\xa5\xee\x87\xeeyW\x1bR\x88\x85\xbb\x9d\xd0\x07t\xd2\xcd\x91\xff4g\xeb\xa6\xabH[*Jy\xe0\xda\x8cO\x19\x15\xfe\x96d\xc8\x96\xa3\xf6\xa4do\xb2\x97\xa5\xc0\x19\x8b0\xcaY\xfaIH\xb7\xb77\xc3k?\x96(\xea\x80\xd8g\xef\x7fc\xee\xbfc\xe7r\xe5D\xd4]\xbc~\x94\xdfnXC\x8c\xd8\xa6\xc1\xcc\xbf\xcc`&;\x0c\xa6Q\x8f\xb0\xdd\xbf\xd8\xdd\x088K\xe2<\x08\x9b\x0e\xd9\xf7\xf66h\x95\xe4b\x87\xb5\xdfE\x92\xae\x1b;Nb\x8a\xf2\"o\xa5(6h\xebvS\xa6\xf6mI\x97Z\x16&\xe8t\xc2\xd9v\xba7[\xb1u\xd0z`\x18\xe3\xf2\xb6\xb4\xb5\xd3\xe9\xa6.\xc3\x8c\x81\x95d\x9a\xe6\x9a\x81vy\xad\xe5\xdeK\xf9\x08\xf5\x13\x8e.\x0bN\xea\x7fA\x00\xbd\xcc\xe3VK\xb5\x00P\x8e^\x0b\xfa\xf3\xc8:\x82\xack\xef\\e\xa6\xa3yi\xa3\xee\xac\xcdjR\x96m\xc8\xce\x0fX\xc6\xf1`\xfciC\x15\x1e!\x84H\x1d=B\xeaS*\x00\xc4\xba\xb8e\xeb\xf8'\x8d\xb5e\x0c|\x8b\xe7I\xdc\xe4\x97\xb1\x83\x97\x8as\x8cn\x1bh\n\x9bs\xa25o\x03 \x01\x94t\x18\xf0E 7\x9b%\x1b\xd6\x9f\xb3E\x83/\x87\xa5\x9bMq,q\xc6[\xc9 H\x19l36\x87<\x81e\x1a\xc49\x041\x04\x9bM\x14\x8a\x80\xd3\xf3p\xb1`)\x8bs\x88\xd8\x15\x8b2H\x16\x10\xccf,\xcbx\x95y\x90\x07\x90\xc4p\xc9VA\xb4\xe0\xdf\xf2\x15\x03\x16\xcfy\xa3\xe9\x00N\x82\xd9\n\x9e\xbd:\x85up\x0bs6\x8bx\x7fI\xcc Ia\x9d\xa4\x0cp2\xd9\xa0i\xf7\xf5Q\xf3\xa6R\xf6\xb7m\x98\xb2\x0c\xbbZ$Q\x94\\\x87\xf1R\xb6\x04Dg\x80b\xe1'1\xcb\xe06\xd9\xc25\x9f\x9a\x9ac\x9e\xc0\x19\xa5\xd1\x85\xb7\xa7\x03\x07\xe3\x03\xef\xc6\x81?\x8d\xfb~\xac\xbb\xd64J<\x9f\xcb\x91A2\x9f\x06%\xc5\xbe\xf0\xdb\xb6\xa6w`\x00\x92\xbd\xb5\x05\x8dA\x10oR\xa9\xda\x19\x04\xa7z\x9ft] \xeal\xa3\xa2\xe4b\xbf7\x1b\xd5\xef\xf2<\xc8\xa7?,\x96\xa8\x7f\xb6\x93\xa1\xffy\x17\xb6\xbe\xa8\xda\xdd\xa6T\x8b\xd0\xaaH\x0b\x9aUo2\x905\xeb\xdc\xbb9\xbaw\x93kC\xe5\xe3\xd1\x16\x1a(\xd8\xc1}^h\xdc\xc1&\xfc3\xbb\xe5\xc3hR\xa4#*|\x19d\xe1\xac\xad\xecL9\xd17+\xdb\xb9\xce\x9a\xcc\xda_v\x1db\x06\x93E\x13C\x9a\x05\x19\x031\x0fgl-\x06bh\xb6\x83\x8dV\xce\x02\x1d\xb5&\xe8\xae9AW\xed j\xfaJ\x87\xc8\x1c:+\xec\x10\xf9c'\x0d\x0dHF\x15\x1a\x9a=\x8d&4\xe8\xf6\xf2\xb9LY`9V\x05\xb5\xbf\x08z\x9f\xb1\xbd\xd1\xbf\xb6\xf7\xf7\xb9\xbd\x92U~\xf2\xcev\x928A\xedn\xf3\\|p\xde\xc6\xef\xe3\xe4:Vas4'nTB\xc1\xf1a\xd1\xf5v+t8\x0bo\x1b?\x8d\x1bz\xe0\xf4\x7f\xde\xae7V\x15\xcb\x90h\xe6\x7f\xf8 \xe8\xefR\xba\xfc\x97L\xf9\xbfD\xa6\xe4\x82V\xd2@HU\x1c\x00\xd7A;E\x93\xd0\x14\x17e\xd7,\xcb\x82%k*\x9d\x16\xa5\xb3d\x9b\xce\xac\x02\xd4\xe7\x92\x1e\xdd\xc6\x83\xb3\xb5\x85m\x05\xcc\xd3}\x1b1\x13\xe4\xea\xcfe0{\xbfL\x93m\xd4)\xd5\xe7\xfbm\x80\x1e\xf5\x07\x97\xe7\x1f\x16\x98\xbay\xa7\xa1t#\xaa\xc9\x95\x16t\x7f\xea;w\x8a\xd4\x10\x9c\xe0\xe14\x1c[z\x9c\xfa\x92\xdbX\xd8\xef\"\x94w\x1b\xdc\x83.(u0\xb2\x81\x12\x95\xba\x99\xc4@\x19\xe6\xda\xf7.\xc44\x8d\xcei\xbc\xd9\xe6m1v\x03*\xfb:\xb9n+\xb9\xa5\x92\xc7I\xa3\xb0\x08*\xff$\x1e\x19\x9fp\xc1\xac\xad\xfc\x8c\xca\xff\x18\xa4\xef\xe7\xc9ukX`\xcaB\xe9\xfc C\x9d\xbe\n\xf2U\x9bO\x0e\x08\x17\x96\\\x04W\x12\xa4\xa9\xb9\xc2\x1c Y\x10E8\x85\xcc\xf5v;\xf0\x92\x8fdo$\x11\xf3%9\x9d;\x1e\x9e\x7f}\xba\xe9\xa2\xdb9W\xcb\x19\xea\xean{\x99Y2g\xaaT\xa2\xe2\x04\xbb\x0e\x07B<\x07t\xfe\xff\xff\x0f\\2pz\x8e\xbd\xa5E\x9b\x11\x84\xa2#OU\x16\x19\xcd\xe7\xce\xf1!9\xb7V\xc6\xb4\xb6\x9bF\x87\x98\xd5}\xc3\xf5\xb2y\xd3\x19j\xd0\xb62\xad\xb7\xf4I\xf7\x19\xcb\xf5\x9a\xb3l\x96\x86\x9b\x1c\xa3^7\xcf\xe5\x93\xc7\xa4\x1f\xfc\n\xbd\xa8\xeb\xd6\x96w\xf5\x8b\x8d\xe24\xde}\x0ca\xfc\xd9#\xa0;\x13j\x14\x88\xeec\x07\xc1\xa4\xc1\xf1\xa04\x18\x07\xbe\xc1\x07\x1a\x9dB\xb6mC \xdb\xc0Dx\x8ep\xe5\xabE\xcd*L\x9e\xf2\x92\x06\xfel\x82%\xcf\x87yS\x98\x8a\xae\xde\x83\x9f\xe4g\"\x1fT\xcd[\x0f\xb2\xa1\xfd\xe4\x1d\xc0\xea\xefD\x9f:\x0b\x1a\xa6\x80\xa9\xa6\xc3\xec\xf2\x907m\x97\xd3u\xc1\xa2N\xbbK\xbb\xa67e\xdd\x85+\x91\xfa\x8e\x15\x97\xbcZN\xe3\xc8[6\x0f\xd2%\xcbi\xe3\xede\xe5\xdd\xb7\x8a\xbf<#\x91\xbcmg\x85\xc0ega6\xf6\xc5\no\xfd\x10\xd3L\x87\xadz\xfc\xbf|\n\x8a\xe7\x93\xac\xbe\xffd>\x05\xb0\x9bN\xde\xe9f)\x88\x9e\x7f\x83\xc4\xdc\x0b*\x186\x8cb\xdb%|\x05\xdf\xd1m\xab\xde\x11a\xa9f\x9d`&\xf3a\x0b\xc1w\xb0\xcdXj\xbfP#v\xbfK\xf6RR\xce\x1b4o\xa9\x9c7\xccS*\xe7p\xd4Bs\xe4\xa8m\x8a<\x7f>r\xf0\xb4\x9a\x19\x7f\xeb\x94\xa8\xffp=\xbf\x8bc\x06\x94\\HZ\x95\x0e\xbaM,\xf5\xfcX\xd3\xf39\xda\xd8\xd6\xbe\xbe\xf0\xffK\xb5\xfdv\xed}\x978\x93\xf0;\xd0\xf6\xa3O\xd3\xf6wS\xdf\x17\xbb\x99\x08\x0c\xda\xbe\"z\xedj\x7f\xf2\xab\xaa\xfduc\xa3\xfetP\xfb[N\xccH#\xb1GH,\xd4~\xe7\xdb \x0bg\xe5\xe8\x88\x8e\xbdj\xab\xce\xdb\xac\xc3\xa7]tx\xfb\xb0\xad:\xbc\xadJ\xd0\xb6\x14\xad6\x89O\xd7\xe1?yLU\xdd\xf5\xad\xe4yR}\xb5V\xac\xa8\xaf\x8e\x0f\x1b\xfc\x9f\xeb\xaf\x0d~e\xcd\xc3\xf9\x82\xfa\xabpC\x9f#q\xa7?[j\x10\xafw$\xde\xfe*\xfa\xf1\x17\xdb\xa8WA\x96]'\xe9|\xe7\x8d\xd2\xed\x0c\xbf\xde>\xed\xbe\xfa\xc16O8g\x8bX\xcew!f\xd7\xfd\x8d\x98c\xb7}\xebXZ@P\xc7\xd2\x9f\xb6\xcb_\xc4\n\xf2Y\xde{\xff$V\x10\xd3\x11yy\xc8\x8b\xdf\xbf\x15$\xd5\xac \xf6R \xda\xf7;\x18I\xd2\x16\x99\x8d\x1c\x9b)\xb5\x176gf\xe0\xc14<\xe7\xb2\x85\xaf\x9b@\x9a\xe4V\x94q\x03\xf3n\xa2\xe5\x84Y\xa3\x0b\x94w\xf5\x9f\xc9\xc7aa\x8d\x1b\xb2\xb0\xf98,l>\x0e\x0b\x9b\x8f\xc3\xc2\xe6\xe3\xb0\xb0\xf98,\xc8\xb2R\xfe\xc0\x05Yw!M,\xfc\x8fGw\x1fxf#\xcb\xe2\xb77\xb2l\xbe\xa4\x91\xe5\xf7\xe6\xf80\xff]:>\x04\x9d\x14\xee\x85*\xd9A\xc3\xe3\xbb8\xe3 B\x17\xf8\xb3\x06\xc5\x07\xa3\x98\x0c\x8a\x04d\xae\xd0\xc8\xed5\xae`Bb\xf7\x86$\\%j\xb5f\x16]Wj\xce\xa2\x90\xc5\xf9\xa9H&\xba\x1a\xc8\xdfm\xed,\x8d\xed\x9c\xb1Y\xca\xf2r[\xf4\xae\xad\xbd\xdbJ{R\xacx\x8379\xb0\xb6\xc8Q\xd8\xbfL\xe6\xb7\xceg\xbb\xa7\x04\x9b\x0d\x9d\xb5\xad\x06\xe2O\xfb\xe0\xbe\x84+\x0b]\xdb\x1c\xc3\xf4\xbc\x01\x14\xc5\xe27\xa6\xdb\xd4W\xb51\xb9favkH\xea(\xd7y\xdc\xb8;\xfan\x8c\xe1\xd6X\xee\x1f\xe0\x8e\xf3\xab\x18\x9b\x9a%\xbd\xaeaU@\x85Vi\xa3?\x00\xbbEV\x81]\xa3\xab\xc0\x8e\x11V@\xb0\xe1\xbc\x83\xcdkKS\xec\x96/\x05\x8a0+\x9d\x8c^\"\xa9I\x07\xa3\xd7\x82Jv0zm\xba\x86y\x01\xe9J\xb2\x83\x85lE\xe5w\xb3\x90]Q\xa5\xae\x16\xb25\x9e\x1b\x84\xd9\xcbgg\x87\xcd%9\x89^\xbb^-\xfe\xe01\xd7c1\xea ^o\xc7\x9f\xcd-\xdd\x16-\x11\xf59N\xd9\x9c\xc5y\x18D\x19\xb5T\\\xa4oi\xea\xff\xb2\xf7\xef\xebm\x1b\xc9\xa28\xfa\xffz\x8a\x12fN\x06\x1c\x93\xb0(\xdf\x99(>\x89-\xef8c\xc7\xde\x96\x9d\xcc\xda\x1ao} \xd0$\x11\x83\x00\x02\x80\x944\x89\xdfe?\xcbz\xb2\xdf\xd7\xd5\xdd\xb8\xf6\x0d\x94l\xcb\x19c\xd6r(\xa0\x80\xbeUW\xd7\xbd\xe6\x98\x04\x06I\xfc\"6/\xeci\x0d\x8eu*I\xc8\xe2\xf9\xd9\x91\xc0\x9f\x14\xfc\x96\xfeSg\x98)\xba\x9d\xb9\x07\xdf\xf7\x0d/\x1e\xa1\x15\xe6Cj\x16\xe5\xc2\x82\xb8t9u\x80W\xc5\xdf;\xbaT\xa7\x9c\xad\x1fG![\xbff\x88\xbf\x08\x040\xf4\x0fsC\xe8;y\\/dK\x1dgT\x9a^\x99\xaf\x94?\x06\x07\xdc\x17\xdfm\xca\xd5\xc1\x18\xe8\xed\x16\x1a\x823\xd2\xb9\xbc\xacL\xca\x02\xbd\x0e\xd57\xe8P\xcb\xba\xca4\xe7Ft\x1e/\xab;\x0d\x9dj\xbd\xf5\xd0g\xa7\xff\xa5J\x9b\xc8\xde8\xd6\xb9\\mM\xc3\x14\xaaU\xd9Zj\x868\x86\xb3\x1d=\xbd\\'Z\xd3\x11F%\xc3\xcc9\xdd\xf8s\xfc\xb9\x1ci\xbf\x99\xf5?\xc9R}\xbcy\xf5l\x80{SRo\xd8\xea\x13o\xf2\x98\xe5F\xa9\x19\xd5~\xef\xea\x9f\x17\xd6\x1d}\x9d\xbe#\xac\x83\xd6\xfds\x1a\xb8\\\xd2\xd7\xab\xcei\x1b\xd4/s3F\x077\x88zm\xc7\xe0<\x89\xd3\xb3\xe13\xca6\x1e\xfa\"\xd6\x93\xb8\x87\x93\xf8\x10!5\x0e\\\x81i\xe7\x1b\x01*=\xb0~\"V\xe5:~\x82AB\x98\x01\xe5\xb4\x92\xb4\xb4\x13\xb2ij\xff\xcf\x068\xaf\xb57pe\xf9\x12;X\xf5\x19\xa3E\xa4\xf4\xe71\x15\x17\xa6\x9a\xf8y@UE\xf1\xaeL3\n\xa8\x1b\xa0r8\x11\xf2u\xa6\xdeDa\x7f>\x0dl\xb7\xb5\xb9\xc2 \xfd\xd2\x9f\xe0'/a\x83@\xfe\xd4JE\xfd\xb1\x11\xb0\xda*Z\x04\xcc\x9aV\x8d!\x08h\xe3=\xf9\xf9b\x9b\xa5\xb1b\x98i\xa3\x8dq\x96/}\x16\x18'\xc6r\x8a\xf94\xb4\x08\x87S6\x14\xd9\xda\xd4\xae\xa9d\xf8|(^\x81r\xafqR\x11 \xdb\xf3\xb9\x0bV\xbd6\xbf\xb8\x1bfiF\x98f\xdc\xbf@?B\xaeoi\xab\xe9\xb48\xf3\x8aA\x02B\xea\xf8\x95\x81=`i=\xb4M\xd7\x0e\x14W\xd9\xf0o\x1b\x92\x1b\xc6\xfc\xbf)\x08d~\xee\xafII\xf2\x02}\xe6)#\xc99E\xd4t\xaa9^|\xdce9\xbf\xfaJ\x8c\x19\xd9'\xc5\x96B\x1e\xd4\xdd;\xa3\x9f@f\xbc\x01'\x14\x8fZ>\xf5\xea\xe9\x0bk\xf642\x1cf\x15\xd8`\x02\xf3g=\xcd\xea\x89\xb3:\xc8,\xd8\xa6\x86\x9fA\x07\xbd\x0c\xda+\x86\xfa\x12\\\x1aB\xde*+\xc4\x87 m\xbd\xfduE{\xe9\xa3\xef\x93\x82YWl\xf6\n\x03\xfd\xb2_\xda\xfb\x85O\xe0n\x18\xcd,.W\xb5\xdfd\xf8\x7fl\xd3\xbdK\xec\x81=$\xfb\xa7\xf8\x8fe:W{-\x01W\xc2\xee\xb4\x92\x98\x9d\x9d\xe3 \xd3\xef\"\xe6\x9e\x0e\xcb^\x0df\xa5\xa1\xd1\x13\x12\xacS:]j\xe2\xa03y\xc1\x8a\x04\xef\xe6\xa9\xa2 \xb8\xb84\xadZEt1\x9cc^\xdfV\xe9\xc3\xe8\xdea9\xa2\x1c\xb8\x01s\xfc%\xba\x8a\xb7\x84\xfb\x8c\xd9PD\xaf0*(i\x08gpf\x06\xe6[\xa9\x9a\x19\xf3\x1b\xf5\xce ^\x9a \x1e\x19\xb6\x05p\xdd\xe4% 54\x89\xb5\xf5|\xed\xba\xd4\"\x9d\x8a\xb9OM\x0c\x8bJ]~\x170M\xc4.H\x8dTp\xe7Q\x9au\x94\xd0iO\xaf\x96\x03\xd6^r9\xbd(t\xdal\xea\xbfMM\x97\xf2\xb2\xd4\x15\x84$\xb5\xef\x18\x8e\xae\xc2\x03R5\xe0\xd0f\xb8\x1f\xcf\x03\xf2\x92\xf87<\xeb=\xb0\x859G\xc9H\xc7'eC\xda\xd6&\x887\x1e\xee\xbd\x0c\xf8\xba\x9e\xdb$\xc0\xff4}\xaf\xde\xd2v\xbf\x91\x15_\xb3\xfa\x97\x1d\x81Ej|\x18\x90\x1e\x1fx\xe7\xab\x14\xf9R(K\xc7\xddz\xcc*\xc7\xdd\xf0\n\x1cw{\xe5\x95\x94\x94\xa3\x94\x94W\"\xbb\x97Wj\xe3\x82i$\xc0GS\xd6n\xc3\xea%\x1b\\\x04\x8b\xe4\xb9\x112\xad\x1dq\xd0\x15O\x0d\x19\x0dq\xc1\xf1\xe1\x10R]\xe2\x92\x8d\x88\xf4\xac\\\x00\x15\x0en^\x10\x13?\xd7\xf8\x1f3\xc7\x82\x19\xe8Y2\xce]\xf9\xfa\x82\x1c\xc2\xd8\xcb\xe0\xe4h\xce\xbd\xb6\x02\x81\xc7#C\xdffU\xa4\xba\x16\x8c\xaf\x94\x96M\xad\x17T\x9b{6`S\xaa\xcd\x7fK\x9b|$\xe06\x8a\x91*\x11\xbc\xc5mZm3\xe1\x1covw\xcf\xd1q\x02\xb9H\x9doj\x8a`\x94\xc1/D\n\x019\x06E\x0bp\xb1\xcc\xf4d\xca==\x18K\xca\xcbJDIH\xce_,\xdctd\xf2\x97\x8b\xa0\xf72\xaf\xa0{\x92\xbe\xd5\xf8uXy\xd1C\xc3crx\x15\x1d qA`/g\x1e\xda\x8a\xf1\xc1\xb7t\n\x18\x84\xb9C\xa23\x9d\xcf\x0dv\xba\xa9\x9c\xc7\xf7\xb4\x89\x84\x94\xf5\x8148\xd8P\x04\\1\x0e\xb6\x91KOY0\xaa\xd5\x14\x9e\xe1\xcbsX\xa4cPE\xdf7\x16\xc9WO\x02\xe3\x98\xacF\xdf?\xe8\xd4\x1e\xe9\x89\xcdy\xc46\xaa\xd5y\xc4\xe6\xd3\xe6_\xfb\xe7\xca\xbf\xbe\xf2\xb2M\xb1r\x9d\x9c\x14Y\x9a\x14\x04\xed\xca\x87\xa8\xd3WP3E\xde|\xd6^ev\x1c\xd2\x1a\xba\x9c\xed\xd4\\\xdf\x95\xf8C\xcca\xcf\xf3y\xc8\xe0\xd8T\xb6^hS0\x87R\xa0d\xe9\xc0\xe1!\x92\xd1t\xc1\xa2X\xc4\xe7*C\xdd!\xaa\xff\x12\xfa\xc17\xaf\x9eV\xb2\x9e\x9bu\x03\xa5(A\xd9b.\x03Vr\xeb\x15 \xa3\x9c\x04\xe5\x9bZ\x9f\xd1\x13\xe8t\x0c+\xfe\xd1\xaf\x9c\xd1[\xf6\x93\x8bS\xa7\x95\x84\xe1\x8b\"9\xa6@\xb09\x8b\xe5\xd4\x19\x89\xba\x06\xa2y\x99Lp\xee \xcd\xe6q\x1a\xbc\xc3\x12\xeey\x1a\x9f\x9e\xceK]\x08c\xdbF\xc4\xff\x92B3\x0b\x11\xf1sI\\\x94\xb1\xde\x89\xa9\xce\xc9\xf5\xcc\xa1\x8aD_\x9a\x03\xe4Z\xd69\x19\xb3\x1f\x07X\x15\xd9\xbd\xf7y\x9c\x05\xd0\xd29\xad\x88\x1f\x92\\b\xf53\xed\x19\xbb\xe0\xc9F\x98\xa1\xa0=\xc0\x9b\xd4\x17\xb2\xce\x1b\xd9\xc1\xbb\x12L{\x81\xcc\xc9N\xea\xd1\x86\\d\xfc(\xc3e\xae\xe9\xa2I\xfb\xe1\x8e\xc1\x81u\xe1\xe8G\x1d\x1aGm8\xf3\xa1M\xa0%Y^\xc6;gr\xb1\xa9\xa7\x06=*\x06W\x9c\xdb\xa1X\xa5\x9b8\xac\x08\xe1\x9b,\xf4K\xdb|\xac6\x15\xcd\xeb$\x0e\x9e\xd0\xf9\xa0tI\xea?\xff\xf8\xa3 E\x0fq\x0e\x81?\xdbO\xd9\xf1\xcd\x9f\xf3?\xda\x10aTd\xb1\x7f\xc11\xeb\xb1P\x7f\xb07\xe4\x0f\xa5c\xf8\xdcR\xb2\x8a\xe9\xd4\xc3\x0eM\xca\x9a\xd6\xf0\x06C=T\xd5\x8e\xe5\x93\xac\x7f\xd3\xafx=\x0b3?T\xcax=\xc7\x07\xfc\xc8\x12\x98\xa2\x87\x0c\x98\xf3\x00\xba\\<\xdfPi8\x14\xe4\xe9!\xf8\xde\xbau\xebI\x9a\xbb\x9b1\x14#\x98\x81\xef\xe5\x9d\x9b\xfa\x86B\xa8\n(S\xa1{cL\xa9\xb0\xa2\xa7+\xcf@$\xd7\x974\xafm\xfd\xf9\xea\x10\xf1\xca\xf4\xc7cSE\x97u\xfdb\x92\x96\x8f\xd3\x00I\x12\x86\x87k\xdf[\xd6\xef\x11\x9b\xf4\x1d\x175<\xfa.\x1a\xc0\xe75x\xe3\x98\xd0\xber\xda\xb7{n-\xd2VlO\x1c\xca\x9f\x92\xa4\x9c`\xe4\xd8[JZ\xb6'\xce#~\x13\xa3\xc24y\x85\x80\xeb\x94\x12\xd7 ,\x16\xea\x9c\x81\x8a\x8d\xfb=\x0b\xcf\xd2\xber\x0c\x87]wm\xa3)\x1c,\x0enk_W\xe8p\xf9\x0c\xc3\xe2\xc8\xe8\xf5%.\xa4\x95z\xa7\\\xe0l=8\x98\xe3\xcc\xc1\x90\xf7\xed y\xcb\xa2\x15\xb5\xef\x9a\x92x<\xa2\xe24\x1e\x06\xc7\\\xe0\x96\x8b\x82`1iMn'\xd0E\xaa\x1c\x99f\x96\xd3\x0fm\xe2\xf6\xd1\x18V\xda\xf4\x06v\xcc\xd7\xed>\xf3\xf5\xe6\xd53-\xdf5\xd4)TD&\xd2-\xa0\x1e\x8f%\xa3\xb7\xd2\xa7Xh\x8e\xe7\x98\xe4[\x92\x83\xd8O\xda1a\xf0\xcc\xc0Q\xb1\xcf\x16\x13\xf6\xeeN#+\xe9~1\xafR\x99\xef\xd85\xb6\x1dw\xec[8\xa8\xd1 \x8d!H\xe3S\xd6d5\xeb\x13z\x8f\x1fk\xban8h$\xd4.\xd1\xd5\xf5\xc7\xca}\x9cv\xea1)\xfd(.\x0cy=J\x8c\xa4\xfdP\xab\xf8\xd1Vo\xe8\x92\x85cX_e(S\xd5\xfe& kfc\xa7\xd1G\x8d\xe0\xba7\x8d\xaf\x81S\xf9\xf8_1\xaa\xed\x84_K\xdd\xf4\xb5\xca\xf7\xb6\n\x8e\xc1\x0d<\x04\xe1\x86\xb8]\x95\x99\xae\x03\x18.4\x9f>7\x0e\x8e183\xb80\xb0\xc8\x0c\x8e\xa5'4\x04\x17m\xf2x\x06\x06\xe6\x9c\xf3\xa7\xda\xcc\x89\xf4j\xca+\xba\x98\xb1\xf7\xf5|<\xd2\xcc\x871\xb4\xb2\xea\xd7\xb1MS\x11=\x96\xe7\x97 k\x10|\xed\x0c\xe6\xe6\x06\xd5\xe1-\x97\xf0\x85\x97\xeb?C\xbc{\xdd\xf4\x9f+\xa5\xfe\x13\x9f\xf4\xb4\x96\x91x\"S\x80\xaed\x9a\xd1\x0d\x7f\xd0\xd3\x8c\x16\xfcA\xaf\x8d\x98?\xe8iF\x03\xfe\xa0\x97\x1dy!\x1a\xdf\x7f\xd0}\x94Q\xf1e%\xb4\xa7h}\xec@\x84\xa2\x83\x8a\x9aU\xab\x8f\xafO\xdd\xda\xda\xd6T\xa9\x94\xa5&*\x99\xfd\xac\x99B\xb9\xb0Q\xbcEm\xc5\x9bE\ne\xac\xd0\\\xc7]\xbc\xc9\xe3!\x96-\x9eU\xb9\xad\xce\x90\xcb\x19\xc2LG\xce`!z\xe9\x12o\x93\xc7.\xe6\xe5\x17;5N\x99\xa3\x00\x95\xe4\x99;\x87+\xd1\x14\xca\xe7*\xe5s\xd5\xd4\xe3\x8c\xdc\x91\xc7\x1d\x8f\xd2\xbc\xe7\xf3\x04`\x9d\xe3\x17\xc9|\x7f\xbaT\xba\x86f\x9b\xb3\xa6\xabd\n\x0f\xc1Y\x95eV\xccn\xdeL\x13*Q\n\xbf\x06/JoV\xef9 \xab\xaa\xd7K\x8a\xab\xb4\xb1\xc5\x0d\\\xa8\x15\xa6m\xcb\x9b\xd2\xc6\x16\x08z\xf9K\x14\xc7\xafH@\xa2-\xd2\xb6\xc2\xc2\xec\xa6\x94\xd3\x85\xe2}\xf8\x12\x81\x88;\xb2p\xac\xc7uB`\xdb\xa5\x02\xddr\x95\x03\x96K\x1eZ'\xf3\xb1o/\xa1\xec\xd4\xbc\"[\xa7\xd8\xa9t\xce\x1b\xba\xe3\xf6\xe4\xd3\xed\xab\x9e\x1a\xb1d\x99W\xf8t.\xffM\xde\xe41\xa3Bu\xb1\x83j\xf2TqF^\xb0\xc9s\x92\x94OXj\x08s\x85\x93-%I{\xcc\xf9\x03\x7f\xbb\x1b,4\x97f\x05\xff\xc6f\x0c\x18\x9f\x88~\x16{Q\xf1\x93\xff\x93\xbbB\xfd\xca\x8a)0\xc4K\x1b\xaf\x88\xa3\x80\xd0M\xb2\xd2U\xc9m\xf9dlzy\xc5|\x13\x9fDw\xc3F \x87\xeb\xa4\xd5:\xea\n\xba@=dU\xbf\xac\x12\x92\xb1\x9d]\xb5\x89\x89\xf5\x0c\xf5\xb5\x00\xb5 \xcb\x17\xf3_\xad\x12\x99\x95\xfeR\x9b-F\\\x9d\xdd\xa7\xcdB\xd3~\xa7\xca[\x93\x9a\xdf\xa8\xf7\x9f6\x8bC\x0b\xdc\xc2& \x8c\xe7\xe8\xae\xbei\xe9\xa1!,\xf0\xe5\xcf|L\xa3m|\x0d*\xb2\xc5\x8d\xc5\xe5*5:\xf1\x89+\xc5@M\x816\xcf\xa2\x82\x9e\x8b\xb4ez\x98&c\xc8u9g\xc4\xc5\xd1\x8f\xc7j\xba%\xaf\xa3\x85\xa5\xad2\x98\xc1bTi \xf3Q\xad\x16\xdc\xb9\xb0\xba\xb8XJ\xd1*3\xa4\x05\x9a\xd0\x8b\x9e\x1e/\xb1\xac\x90\x05\x96\xd0+\xcd\xac\xd0\x1b\xaarE\x169@\x01\x83\xb9\xe9JY\xa17T\xdb\xc7\x08\xaa\x91\x8c\xd8\xe3F>D%d\x13\x8a\"3\xa6\xb5\xfd\x06\xa6\xbaB\xde\xab[\x0d\xaf\x8c\x9fR\xa8\xc9\x17p\x856D \xce\xfe^]8\xe9R\x96mYy\xe6\xcf\xc9\xb2-\xad\xe1\x9b\xaaj\xf8F\xaa\x1a\xbe\xbe\xaa\x86\xefFU\xc3\xb7P\xd5\xf0\x8d{5|Y \xcf\x82K\x05m\xe8@\x04\xcb~\x16%~\x0d\\\xfb\xa7\xe4\xd8\xafi\x88\xe0\x10\xee\x9cq\xe6\x8c\x1bPC%\x02J\x0d\xc2\x8e\xb2`\x15\xc5aN4\x944\x1d\xc6\xa9GC\xb8t\xdf\x9aC\xdf\x0c\x90/\xb0p\xb2\x8e%_\xb0\xc38\x0d\x8e\xce3?)\xb4Q\x14\x19?\xb8I\xf6,J\xdeE\x89fFCQ\x04\xd8Y\xf8qAX\n\xfeL\x0dO\xb9\xf4\x0d\x96\xfd\x8c\xfd\x0c\x1dk\x95\xa0[\x06jSes\xcd@\x1f\xf3\x1e\xeb@\x97\x0c\xd4\x04V\x05\x164\xa1\x1aJ1\x9cb\xab\xb7\x15\xb5r\xc8\xe7yz\xa6\x19\xdcY\x14R\xd2\xe0\x1c\xec\xeb\xbccH\xb4\\\x95\x0cjpo7\x85>\x14\x88\xed\x08\\\xab\xbf\xc4\x14\xcf&\xd8\xe7 r8t\xa9\x9aw5\x9d<\x8f\xa3\xe4\xdd\x0f\x83>\xa6\"6:\xad\xa3\xb6\x86rT\xbc\xc8HB \xf6\x91j\x9er\xa3\xf9@\x92JC'xg\xe2)\x1a\xe6{\xce'BcX\xab\x9d\x16y\xba\xfe\xf1\xd8\xfd\xbd\x1b\xcd\x87\x1a\x0f\xa7\x9e\x94\xf7\xe3k\x97\xd0\xb4/\xd4g*\xa1>S \xf5\x99J\xa8\xcfTB}6,GS\xe6vc\x94\xa9\xe4\xeef:\x97\xf3\x05~\xed^sY\xb96@&\xecg\x1f_\xd8\xd7\x9b\xe9\xbe\x08\xfb\xe2\xfap\xc2\xbeP\xa4\xaa\xe1r\xcbT\x05)\x87\xc3@R\x0dc\xc9\xb4\x07\xe9r\x19\x13d1\xd5\xa0L\x82O\x93\xd79\x15\xf8\xf1\xb8T\x03o8\xf0#? Hl\x00.8\xf0\xd19 6\xba|\xfb\x0b\xa3\xe1.\x1b\xa0<\x08\xadU\x12\xabjq\x8cz\x8e\xed\x10s\xea\x1a\x81\xad2q/+P\x8b\xef^\xb0 \xf5\x8b[\xc6\xef\xce+P\x8b\xef\x9e\xb6\xdd\xce*\xc6J\xc3z`\xb8\xbd)w\x02\x15\x9f\xcf\xbc\x90d9 \xfcRW=\xe0\x1c!\xb98\xa4\x06;F0}n\x8bG\x08c\xcak\xf1\x0e\xa1R\x8dn\xe7;\x84\xd0*\xe0^\xf0\x8f\xf0\xe9\xd2\x95\x9c|\x89\xa0~\x1c\xa7g\xaf\xf3\x8b\xa7\xe5\x8b\x8d\x06\x83_\xb3y\x1b\x98-\xe49\xeb0\xff\xfa\x11\x13?\xd5\xe0O\x11\x9c\xb0\xbd\xf94y\x99\xa7\xcb\x9c\x14\x1a,\xf9\x15\x0e\xe1\x9d\xd7P\xea\xa8A\x7fB\xd0\xa6\xeeF\x0d\xfb\na1\xdd\xb7,\xa3\xb7\xb8\x1e#\xc6 %Q\x9ai\xb5@\xcf\xe0\x10\x1e3#_\x15\x02\xae\xd3\x8f\xbd\xa9\xe1\xb3<\x0d7\x81\x1e\xfc7\xee\x8f\x8c\xa9G\x9eEE9r\x1f\x8f\xe1\xc4iT\xd5\xd5\xf5\xee \x1c\xc2\xb6F\x9bc\x1c\xba{<\x86G\x9a\x97\xfe\xddQl9c\xf8n\x0c/4\xca\xab\xef\x9b\xbd<:/ \xeaI\x8b\x91\xfbX\xd3\xcc\xcf\xc8\x04\xd9\xcd\xda\x0f\x0c\xb6YKX\x0d\xfc\x0b\x03\xe6\xf8\xa6\x83\xfc\x91A\x06,w\x9d\x1a\xee\xbf\x19\x9c\x8d\xf2\xf5\x1f\x0c\xd4F\xf9\xfa\xbf\x18(\xc7G\x1d\xe4_\x19d\xe5\xd5\xc1\xb2,h_\xf9?\x9dW\x8e\xf4I^\xfe\xd9ma\xb3^\xfb\xb96\x17\xca\xfff\xaf\x98\x14\xc2\x84\xf2/!\xcf\xe9S\xe3\x86\xda\xa5\xf7\x19f\x8fe)d\xd1\xc4\xf9-\xec\x9b\xdc\x95\xd0\x9d~\xef\x19\xee+\x1e\x9a\x97{\xad\xec>,F\x87\x838\x9c{\xd3\xb9p\xe4\xe8\xe0R\xf43\xf1\x8c\xa1$\xb6\x16R\x10\x1e\x04\xb4\x7f't\xdfI\xd2\x84\x02\xd8\xe69\xb1\x12\xe6\x9b\xaa\xdb*\xe7c}2R\xf9\xf6\\\x06\xe2\xc0\x0dx\x047\xc0\x91\xe9x\xdbP\xea\xd5\x8e\xc2\x99F\x03\xfe\xefZ\x01\xaa\xd4\x80\xaa\xa6\xe0\x9fZ-\xb1\xc0[\x94ngp\xaa\xeea\x83S\xd5\xfa\x98\xb4}K4\xa7w\xab\x84\xd3Z\x0f\xd7\xf0\x9f\xd1\x1c\xf6\xb53\x84\xca!W=M\xffm\xa7x8\x1f:\xfdC0\xb0R\x8d\xab\xeb\xe2\xbf\x1f\xc3c\xba!\x1f\xb3-\xfe\xc7\x1f\xcc\xff\xe4\xf0\xf0\x10\x1e\xd7\xce(\xea\\\x13\x06?\xe8J\x15u\xeb \xd3\xd5S\x15z-\x03\x18\xbaU'\xee\xed\xe9TC\xe8d\x13\x10\xa7~\x18%\xcb\x89\x9fDk_c\x1f\x19\x8d\xe1H\x9bX\xc8`%\x91\xb5\x8d\xea\xcd\xd3$\xcd\xd7\xbe\"\x07\x10&x\xfa\xc5\xcf\x93(Y\xce\xe0qM\"Fc\xf8\xd5\"\xcf\xd1\xb0\xfe4\xd89}\xa9\xca\xab\xc6Bcf\x10M\x83\xff\xb01G\xfc\xaaX\xd4\xd1h\x0c?\xd1y\xfc \xc3=/\x91\xb6E6,\xc1\xf3N\xc24(v\x9f\xd1\x0f\x86YO\xa2$\x84u\x9a\x13\x08EF\x9f+^\xd8\xd6\x0c\x0c\x1f\xb91\xd0\xd5\xd8\xe6\xa99\xeb\xcceq\xeb\xa7\xa6\x18\xa4\xc23u\x1b\xff[\xd7\x86}\xb0\xac\xc5L\xc4\x91\xf6\x0bJ\x8b\xd6O\xda\xe8X\xf6\xb4\x91c\xa7yj\xa87\xd4\x0f\xbaa\xd7R\xc4\x0c~\xb3:\x85yA\x10;\xf1\xa3\xe2Ef\xf0X\x03\xc5+x\xff\x03\xdd%uj\xb8\xa6\xbaL\xeb\xaa\xdb\xd2\x95I\xeb]\x89\xab#\xb9\xcf\xe0\xb9\x86mi*\x12f\xf0R\x0d\xb9H\xa4Ev\xc4e\xcdP5\xb4d\xda\xecE-\x15\x996\x7fQ\xe6\x97\xab\xe7\xdc\xb1\x93q\xe1\x86nr\x17\xe4P\xb1\xe1*l|\xae\xc1\xc1\xbf\xeap\xd0z2\x98M\xfeX\x0d \x1cV5Ly\xda\x91\x1bgB\x03Q\x98\xe5H\xda~\xf5\xda\x16\x15b\x85;\x12\xda\x91\xe31T\x1f\xd1\xe9!\x96\x84\xbb\x83\x91\x90}l\x06s\xafh\xdd\xd1\xacs\xff\xe5\x0b\xafw\xd3\xf0>\x05\xf9\xd9\xcf#\x8a\xf0?3\xed;\xffH\xef\x89a\x18Mx6\x8ca_8Z,HPF[\">\x85\x9d\x11\xdf\xa9\x9e\xe2}3\xfe}\xf5\x15\xbc\xa4\xff\xbc\xc2\x7fLtq\xa7cV((T4Z\xd5\xd8\xff\xd2\x9eo\xec\xa33x\xf5aq\xdf\x96\x98\xf0H\x16\xa6!\x9b\xc1\x13\xc5\xcc\xd7S\x7f\x15S\xfc\xbcRu\xbc\xa4\x12\xf9\xbcL&\xcb<\xddd(ys\xfd\x95\x91\xb3{.\xdeW\xf5\xe8\x17+\xc9Y{Z\xd9\xce\xe20\x92|\xd9\xb5\xad\xec=3(\xacvJn\x9a\xaa\x1f\xb5(k9 \xf6C\xd3wz4\x86\xa7W\xb5\x97\x85 \x1aT\xc1dCw\xf3.\xcd)]'\xaaey\xa6\x19\xe0\xcf\xba\xd6*\xb5\xf1\x0c\x9e\xa9g\xbaJ\xea\xab\x89*\x11\xcc\x90(\xfb\xa0\x8d\xfd\xb0>\xb7[l\xc4Ul\x98\x86-N\x9b#\xd2\x1aK\xb9\xf5a\x06o\xcc@\xfc\x90\xda\x8a\x80\xbf\x97\xfc\xfe\x934w\x19C\xa59\xfc\xfb\x8c\xb4\x95\xce\xdf~\x1b\xa9A\xe4\x86\xad\x19\xbcV\xbf\x82\\\xac\x89\x9a\x10\xf4\xa0\xf8\xdet\xdc\xfe\x1f\x1d\x06\x93J\x17>\x83\xef\xad1\xce@2vq\x1bz\xb9\xc9\x89\xcce\xa8\xca|'w\x19j\x9c\x1c8)\xad\x87y\xb5\x99d\xcf\xf8\xa6\xec?\xaaQ\x85J\x8a\x0b\x8fY\xbc\xba>5\xcc6\xa1\xf3B\xfa\x12Z\xd4\x9e1\xa5\x17\xd2B\xee\x85\xb4\xa8\xbd\x90\xee5S\x19-4\xeeF_b\x8b\xfe\x03\xdd\x8d\xac\xfc~\x86\xc4\xfb\xe7\xf6\x0e-\xe9\x10\x87\x16\xe6\xa6\xd4\xb6\x13\xa9\xa1}K_\xaa\x0d\xd6\xd039\xa7\x14,\\\x9d\x91-5X\x80`QQ\x95=\xd5\xf0\x0d\x0b\x845\xb9\x9ed\x08\xa5s= Y\xd7V\xe9\xd9\xb1\xa9{+\xfe1\x0b\x17\x94-\x03\xcd\xa3e\x94\xf8\xf1\x0b\x9bW0\x12I8\xa2X\xbd\xb1\x84C\xc8\xcc\xb3z\x81K\xc4\xd5\x1d\xc1&\x8fJ\xadU{\xce\x12(Tu`\xab\xae|_j\x8d\xf9\xa7\x9d\xc4\x0b|:\x9f\x1b\x03\xbf\xcf\xe4/\xbe4\x04\x9a\xf3\x1a'?n\xd6\xd9\xeb\x14\x811;\xc4\x07\xb7.\xd7Z\x01\xd6O\xe8\xfc\x8d\x06b\x8d\x16\xb0\xae*(\x05\xd1\x08 \xa7\xba\x1e\n^P\xc5\xb9\xa9?{f\xaf\xa6\xd3\x05>v\x0c\xd0\x1a\xc3r\xcd\xe3\xc8\xe3\xc6ig\xc3\xab\x92\xfb\xba\xabcc\xafX\xd2\x83\xad\xa8\x99],\x8a\xedn\xe9\xdd\xd5\xc8\"{\xfen=\xab\x93\\D\x8a\x02\x04\xef\xc7 :Qg\xdc\xff\xea+\xb8\xf0\x82t\x93\x94\xae\xaeos\xbdY\xbc&\xb93\xd0d\xcc\x1a\x1e\xe3!N\xd4\x941\x94\x98\xef\x97JMT\"\x89r\xec[\xe1^\x982\x89 \x81\xae\x13\x06\x17\xae\xc2\x01\x05z\xacEu\xd7\xac\xb8\xd2V\xc8\xc9\xb4\x08{\x85B\x87!N\xa1\xbb\xcfL\"D\xb0\xb3\x08q=\x03\x19>i\xa6\xb2\x01\xc5\xa6?\xa32\xa3_\xc4\x04q\xed.&hK:\x9b\xb8\x8fK\x1d\x1b<\xb3\x8e\xf4\xdd\xf7c\x94P\xded\x19\xc9\x1f\xf9\x05\x91%W\xd9\x99P-\x86\x13\xaa\xfa\xbb\xe3\xcf\xa0\xc4\xf1g\xaa\xad\x10\x91S_\x94\x16\xff\xb1\xd4H\xcd\xc0\x95\x034\x11\x89Dc`\x14\xf5\xe9\xc6I\xac\xe2PR\x844\xc6\xa1D\x08\xa6\x8fC\xf1\x11F\x1b?\x82u\xf1\xed\x84\xf7\x82w\xecq\x9d\xc6\xc4\x18\xe1AO\xd8\xb2\x99G\xe4\xc3\x9f\x04y3'\x838\x0d\xe8<\x9d\x9e\xb6\x9d\x9d\xa5@\x83\xcd_\xdazUU\x02\x06\x9d\x02J$`\xd0\x98\xa2\xb2\x06\xdf\xca\x9ao\xfbO\xfbXy\x80J\xd8\x1b\x0d\x0e\xb2,\x0d\x91|\x84Wy\x04^7v\x99\x9e\xaa\xcd\x80\x078\xe4\xe5R\xfa\x87[D\xcf\x84\xfb\xb2\xd3-\xea\x96\xd0\x8f\xd8\xe9\";=\xa2\x8f\x7fz\xf8\x98\xc1\xa63J\xf5q\xb2\xad*\xca\xd7\xe6\xa6>\xe6$\xed\xd27b\xa5\xdb\xe1#\xaf\xd2\xb3\xee\xbe\xe6\x83M\x87j*\xa4\x0c\x9d,\x81\xcc\xfb\xf1\x95~\\Z\x9bS\xd7F\xb3\xb4i\x1d\xbb\xe2P^\xe3R\xfd\xc2\xf2\xa5*c\xbc\xaeC\xa2f*\xeb\x93\x1a\xacU\xe3T\x0d\x96[\xc0\xc8\xeb2\xaa\xcb~\xf6\x06\xe3<\x89H\x8cN\xe5\x1f\xb2\x114Q\xb3\xa2\xa1\xeafZECK\x8f$e~qL~\xc3\xec\xb7\xa6\xcc\xa0\xdbF\x8d\xa8f\x9d\x9f1\x1c(\x881=\xbb\xcb\x93}\x85\xb3!\xee\xe4\x93\xa9$ \xc8\xb0\xad\x12\xd5Q\x84\x0cUT\xa5\xdeT\xb8\x8a\x9e\xa3\xcb\xa9BAy\xfe\xb3\x1f\xcb\xf4<\x9d\x04\x96\xef\xdb\x05\x10\xdf\xcb\xcf\x04\xf6\x99\xebu&\xbcJ\xcf\x0c\xc7\xc2\xed\xe9\x9f\xe2X`\x03\xb59\x19(B\xc8\xcf\x04\xe2Q|\xe8?C\xa6\x14\x1eR\xa63\xfd\xf1\xb8\xfa\xe1\xa2\x92\x91+\x1a\x87\x9d\x14\xd6\x94\x88o]#1ap\x9d\xbd\x1a}&H\xdbG\xcc?Q\x02\x13\n\xf0\xe0\xee\xfe\x9f#g \n\x9f\x98\x949\x1a\xc3\xa6O\xca\x15\x82z\x1fp\x91\xe6\xe0\xd2\xaf\xd1 \xaf$p^Bn\x8c\x13\xceR\xff\x16\xa31N\xf4\xfe\xd7\x10\xc07P|\x0d\xc1\x8d\x1b#\x88O\x82\xb7\xcd7O\x02\xf5\xc1B\xb7v\xc4O\xb2\xbe\xb2\x00ei\xa3\xc2 \xf0\xe3\x98k\x0d\xc8\x18N\xe8\xbboE\x11\x87\x18O\xe1\xc8Cs\x85\x1fG\xff\xae\xa5\x07c\x19\x07zE\x1e\xa1\xe3\xed{?\xbfG\xadBz\x865y^\x936\xef\xab\xfa\x1a\xf3$\xaai\x00\xd7X\xe2\xbe\xa3\xdfc\x7f.\xa2\x98PN\x03S-\n\xef%\xaf|\x0b)Z\x0dY E\xac\xce\x9c\xc07\xacVa\n7 \x82o\x0f\x99;n\xc2\xe2\xbbqs\xf39}\xcc\xd6JV]u\xcc4\x19=E\x17\xdd}\x1fC[u\x95\xb5\xcf\x98\x9c\xbf\x8a\x96\xab\x98\xce9\xaf[I$\xc1P\x1d ]\xc6\xff\xf5\xbb\xf7&\x0b\xfd\x92\\\xaf\xfe}\x02e\xdfV\x1f\x90\xc1vV%h\xe87\x14\xa9\x88\x0f\x15\xc3\xb4:.,0\x86\xc4\xc4\xb9\"\x9f\xeaj!&A\x1a\xaa\xca2\x8eQ/v%\xed\x89\xa1Nx\xc5yY57q\xd5^\x1dt]\x9a\x14Z\xd5M\xe71\x07r\xcc\x96i'\xcb\xf5\xc9\x01YYN\xda\xb4\xe4\xc8\xd1\xf5\xfa\x97\x15!qU\x04KG\xd0\xd5_i\xcc\x19\x96=\x80uD\xbf\xa0\xae{\xfa\x9er\x00\xc6M\xd4W\xc3\x99Tpr\xa7\xd7\xe6N\"\x1e9\xcf\xd2\xbc,Z\xc7S\x9f\xbd\x85\x06\xe7\x99\x903\xf8>N\xe7\xee y+[\x83\xf2\"\xc3\x91ST\xa7\xfc@\xc4\x8ad\xdfL\x83\x92\x94\x93\xa2\xcc\x89\xbf\xeeH\xeb\x1d\xf6'ZT\xf5v\xf7\x0e\x0f\xe1,J\xc2\xf4\xccK\xfcm\xb4\xf4\xcb4\xf7\xd6\xc5\xb1\xbf%\xb4\x0f#\xddC7\xefsV$.\x88\x82k\xa3\x87\x1e\xff\xda\x9bW\xcf8\xc61\x0e\xfe\xcd\xabgn\xae\x91\xe9C\x9e\x0c\xa4\x8b\xa6\xbeL\xef\x1dyX/W\xb8\xb6\xc1!8I\x9aP|\x8e\xbcUN(G\x9c\xd2\xdf\x05)\xbf+\xcb<\x9aoJ\xe2V\x9b\xcfa\xb2N\xa3\x1cq\xcd\x00\xd13\xb3\xfb\x1ec$\x9cq\x15\xd3;\x1a\xd7\xdd\x9d\xa7\xe1\x05\xe5\xd9H\x12>ZEq\xe8F\xc8\xa6\x05t\xeb\xba=\xc0\x9c\xac\xd3-\xa9\x01\x1b\x93\x95\x93m\xfa\xae1Y\xa9\xea\xe8}/E\xc9\xeb L\xc9\x95\xbfR1+R\x89Y\xbeJ\xcc\xda\xa8\xc4\xacB%f\xc5\xfcAOb\nx\xca\xc7\xbe\x1cUKZYU\x12B\x98>+\xe0?\x81`\x95\x8f\xc1\x97\x0bV\xd1u\x14\xacr.Xml\x05\xabt\xa8`\x95{\"x\\\x84\xe1\xfc\xc2B\x04\xad\x84\x0e\xde\xd5\\T\x88\xac\xc3\x85\xbc\xa0\xf5QT\xa8\xba'\x02\x10M\x90\xd5k\xcc\xed\xe2-\xe5\x9f{\xad\xbcg]\x14\xf1T\x8f\x18\xfb\xf0\xfa\"#\xac\xd7V\xdd\xace#\xca~\xe4i\\|\x17\x04$+\x7f@\xf5\xaf\x89\x9f30})\xe6v2\xb0\x8f\x11\xba\xedY\xa5@\xf4\x11To\xa4\xdd \x8c\xceO\xa6\xac\x08\xbad\xea4EZ9\xd1\xd3\xe5\xb4d\xde{j\x00\xe1>\xbb\x91BH\xaa\x17\xbd\x1f3\xabs\xafp4\xdd\xad\x96\x82X!\x15\xc4|;A\xacX\xa5\x9b8\xacX\"ka\xc7\xb4/\x1a>M\xdd\xc0@\xe4NH\xff\xb6(\xbf\xcf\xde\xaab\xdb8x\xfdw\x1bN\x84\xd6q\xb0\xeaO9\x14n\xc6\x0e(\xbb\xd7\x86\x97\x07\xbc\xf1\x17\x15\x0f;-\xfa\xe5J4D\x7f\xb6\x9f2D\xe1\xcf\xd9\x1f}\xdch/\xffG\x92\x06\xf5$\xc1F^d\x1e\x19\xd5z\xe9)C\xd2\xc3\x03=yH,\xbdN65\xac!\xa5,\xf3\xd3\xb0\xcc\x13\x8bl\x841\xefm\xd2\xc6-5p\xc8\xdc\\\x06\xa6\x0d]U=\xd6G\xd5l\xf9\x11Zi\xed\x8e1\x89\xdf\xa34$#7\xd5x>\xac\xb1\x98\x8f\x13\xd4d\xd3T\xd1\xc6w\x9d8\xda\x12\xb1\x86\xa6\xca6~\x1d\xbbj\n\"\x91m\xf5\xaf\xbe\x92\xdd\x16Q\xa4\xb27f\xb5\x84\xf7\xb2\xf5D\xdd\xf8)\x1cB\xd1\xac\xf6\xc7\xa6rIJv\x82>b\xe7)\x95p\xc5\xb0\xe9\xacJ\xcd6\xe229\xee\x0c\xd1+T\x1b\xcc\x98\xd9\xe0J\x9a\xb3q\x01\x10\x971O\x16w\x05x\xd5\x88_n\xcf\xb5)q]\xec\xcfI]3\xc4\xe4\x08\xd5i\x0e8b\xa3\xcc\xad\xcb\xa6\xa5\xad\x16\xc3\x89\xab&(L\xb0\x97\\1\xa2\xe065\xc4\xa6\xde\x7f\xc5\x0c\xe6\x1a\xc0\xc6:\x89t\x17\xfc\xe5 \x8eQ\xbeJ#]\xc6\xabA\xc8Q\xe3b\x94\xe8\x92\"Df\xa5\x9a~E\xb5\xd5^\xea`i\xeb|\x94\x1a^\xae\x99y@\x93\x03\xaa\x93y@CP\x18\xf7\xd8a\x11\xcc\xbcd\x8fk\xd0\x1c'\x8a0}U\xfe\xa5\xe1\xdb\xd4B\xc9(\\k\x86b\x0e{o0=i\xbb\xe8\xa8\xc1\xf2\x1d\xba\xb4+\x8dS\xb8\xe1\x88K\xed\x8eS\xa1\xf0\x84\xde\xe39wU\xcd;\xf4 \xd7&\x03\xbc\xa2~\xd8\x04\xbb9\x8f\x1b@]j\xfe\xa1;\x18G\xc9;\xcd<=\xc3\xc7un\x07\xdd\x8c\xb5<\x9bR\xa5gS\xa9b\xa5\x81\xb3\xd3I\xdf\xc3\xa9T{8\x89\x0bYg\xa5\xa7\x93\xb8\xb0|\xc9\xc9\xd4\x00\x15\x027\x18F\xed\x0c\xcepx\x08)<\xac\xf1\xfc\x94'#A'_G\xce\xb8\x80\x99y\xb9\xd0\xad$\x08a\xc5P\x96\xb8\x8e:[\xb1\x1c':6\x15\xd0\x1d\xf8\xb1\xd0\xa6mQ\xafkh`\x91h#\x13\xa1\x8du\x1aZ\x8b\x90iH\x8cC\xaaO%M8/\x0c:I\x803\x07]u\xce\x8c\xa2\xc6\xe1\xa1.m30\xbe\xa4\xabK\x9aa\xd9\x0f\xa5\xaa\xc9\xdc\x15\x0e\xae\xe5\x87\xc0\xfeT\x85\xfeI\xad\x84U\x14\x85n\x15\x83\xde!\xa1K\x8d\xe7;$u\xe9'C\xeaGX\xd6\x99\x83\x98\x85\x98U\x8a\x1a\xb9'-\xfb\xcf\xaf\x85\xa4\x16\xa7\xea\xa0\xdf\x9b\xd6\x03\xf8\x1c2\xb9\x84*w\xacP\xe5\x8e\x15\xaa\xdc\xb1B\x95;V\xa8r\xc7\n\xa5\xe6\x8b\x98?\x91Z\x10\xdcP\xd8\n\xc2\xcaV\x80\xbf\xa6\xb7z\x05\xa4\x17R\x8b\x03\xaa\x07Te\xa5\xc3\x8fo\\X\xd9\x1a\x17\x88\xc4\xb6 C<\xb3hkjo);O)\x0e\x8d}\x914\xc1'+\xf2N%$n\x90\xba<2)\xb9\x12\xe6\xeb\xd3oF\xfd\ns%\x92\xd1m\xf9\x99\x8b*\xec\xe3\xd2/uJ\xeb\xbcO\xb2\xbbK/\xae\xf7h\xd82\n\xb4\x9a\x11\xc8\xcf\x9c\\\xd1Z\xef6\xfa{Q6\x84\xf4\xe8\xa5\xb8\xa4\xc3q\xfa\xac\x1d\xfd\x94\x02\xbf\xe1\n\xdd\x94\xaeF\xb3\xca\x08-Z\xe0RK\x1d*3\x9aP\xfeB\x0d\xc3\xac%\xe6\x02d\xccbb\xe1\x9a\x13\"\xa0Y\xaf\xb8B8\x9d\x12t\x8b\x10v\x9a\xdau\x0dk\xd0\xd4.\xab\xfeYhj/\xf8\x0cVx\xa4\x06\x9dW\xa0\xf6\xf6\xb1S8\x84\x95\x17%\x0b\x92c\xaeS\x8d\"\xe1\x0c\x0ea\xc9\xc5!5\xd4\x11\x1c\x82\xcf8u&\xe2h\x93\xfa\x9d\xd7\xd0\xe4\xdc_g\xb1>\x07\xe0q\x0d\xced%\x0d\xec#8\x84\xadU'\xdeqH\xe1P\xc5\xe5Q%\xfcw\x0c~\x9d\x86$>b\xbd\xd6\x81\xbf`\xe06%\x80^2\xd0*.\xd3TL\xe75\x83\xb7Tp?\x17\x9b\x16i\x97'\xa1Q\xf4\xc8\xbaPP\xf1\x05\xb8g\xee\xc8$/>\x15+\x84\xc5\xb2x\xc7\x9c1<\x7f;\xe6\x8a\xe7\xe7~6r\x7f\x7f\xdfe3\xba\xd7\xafp\x08O\xb9\xc4\x87\x88\xe9\xf4>\xa0\x16\xf1\xeaP?4M=ma\x98#\x94\xe0\x99W`m\xa0hq1r\xbb0T\xccf@KR\x1e\xe3M\xb6AF\xee\xaf\"\xec\xd70\x9b&A2J\x82x\x13\x92W\xc4\x0f_$\xf1E\x8b\xcb\xec^\xf4\xd0\xa3\xc7\xcd\xaf\xf0\x10\xcaJy\x95\xf0;\xa7U\x9fj\xc5V\xce\x9f\xb9\x8d\xcc\x89\xcd\x151\xf5]L\xfb[\xfaI\x85\xe6\x8d9T\xd1^\x9c\xba\xbe\xe8\x01k\xda\xf7V~Q\xad\x1d\x9d\xf2\x90g\xfb\xacnQ\xb9\x14\x07\x95T\x0b\xd2\x9b\xebd\x0c\xcfu\xf3(\x99C\xcdi\xc4\x80\x7f\xc9\xa3\x92hg\xfc\xbd\xde\xfcq\x8e\xbe\xcc\x94v\x9d[\x04\x8a\x89K\xb0\xc0\x94\x1d\xa2l/+&\xf5\xd7\xbf\xe6d\xe1\x08\x97.\xda\xae\x8a\xebQ\xe0;\xddu?Y8\xf05/a\xdcF\x0bTeo\x1a\x16\xff\xd6\xbc\x9a\xb1p\x0d3\xbe&\x16\xaey\xe5\xda\xb8\xb8\xe6\x95\xf2\x1893\xa4\xe0\xd0[{<5%V\xba\xa4YK\\\xc8t\xc9\xd9IqiMKw*\xcd]\xaeQ\xf2)\xe3\xfe\x9aW\xdb\xa4\xc2h\x9by\xf68[(\x8f\x19\x17\x97,v\xbc~V+-(J_\xd6^b\x1c\xeb\xf0q\n1A3\x06A\x05\xe4\x1b\x92\xa2\xf7\xf9\x18\xde\xed\x98\xdc`\x07M>8p\x03\xdc\x0ds#\xd7l,'\xf4K\x9f\xb9\x85+\x03\xff\xafN\xdd>D\xd7\x1f]\xa1\x9a\x7f\xb0n\x7f\xe7}-[\x8bn\xab\xa7\xa7z\x93\xa1\xaa\xf1\x17\xba\x86E\xd5\x1f_\x94)l\xd8&T\xa7\xc4\x18\xce\xcc\xbb\xcdj\xacL\x9dWQ\xf3\xe6\xd0\x1b6Y\xd3\xcet\x84@2\xf1Q\"\x11\xd6\xa8\x19\xcc5[o\xe84\xbe\xb60q\x1b8\x1e\xf5\x94\xb4\xec\xd7|-\x04#E9\x9b\xee-\xef\x1da\xc7(\x88\xc4\xd5\xc7\xe4\xb7^\xd2\xb9\xe6\xd51\xb1\xcb\xf4>\x8a\xf5\x1e\xc3\\\x9b\x83q\xed\xc7\xb5\x83\x81\xc3\x9d=\n\xd0E\xa1 \xe1\xa8^ar\xa43\x1a\x83\x03l\xe9\xbc\xda\x06Uq\x9b?i:\xf1\x9d\x16\xc5+K\x89u\x9a}MV\xfc\xa6Z^S{\xb1c\xa2\xd0\xd5^D>T\x88\x02L\xb5\xfd\"\x0fIN\xc2\x91\x9bhV\x94\x1fB3\xf8I\xb1p\xd5\xd4\x1di\xa6\xee\x91n\xea\xb8h;\x83#\xeb\x99\xd3\xf7e4\xae\x04\xfc+\xb5w\x0e0r\x1e\xc3C8\xf6\xcaT\xc6\x85v\xa2W\xba\x97\xe1\xc0}i\"T\xc8\xb5i\x14<\xf4JpP\x06 :B\xad\xfe\x11,\x17\x064\xa4p\xa4\xad\x87Yo\xdf\x9fR\xe0\xaa\x92j\x95{\x1f\xbc\x94\x05i\xa5\xb7 \xd5fCF \x85u\xe8\xf7\xf7]s\x89\xcc\x9a\xd7TL6T\xffm\x9b\xd0\xea\xbf\xf8\xcdke\x13Z)sG\xacTQ%+UT\xc9J\x15U\xb2RE\x95\xacTQ%+\xa5Mh%lB+\x8c\xc8\xbf-\xb5\x04\xb1g\xbd/W\xe6\xa0\xf6\xedP\xf4]\x91no\xf5\xf1\x0dE[[C\xd1\x97(\x94\x8e\xd1\xca\x14\x85\xa2\xb7\x88d~^\x90\x90oq\x85X\x85\x91\"\x1bt\xdd\x7f\xd9\x04\x1fd\xf2\x12!)\x9c\x1bSk3\x99\xff|\xa9\x16b)\x10S\x91@\x94\x14\xa5\x9f\x04$]\x00\x0b<4\xebC\x12\x1e,\xf9$\x8aQ=\xa52\x8f\x89+\xf1R\x16\xc6g\x91\xc3\xa0y\xe56\xe6\xb5\xe6\xd5] \xca\x0cobydn\xf3R\x9cD\xd5\xe31~\xca\x0f\xbf+^\x93\xf3\xd2\xd5L,\xd7\x1bZ\xf7\xbc\xd3\xe3\x92\xf2\x07\xac\xaa\xbbN\x03!C\xafO\x1b\xa4r\x95\xd9\x02PN\x90\xec\x15\xd7\xea\x88W\x07a\xec\x942@\xb9)\x95\xbd$b\x7f^\xa2\xabWc\xd5\xb4\xb4d\xd6\xc1g\x16YB\xad\xccu\xac^\xc9&\x97$T\x12\x17\xabR\xc2\xf9|5\x98_\x9b;Xz\x8d\x87\xf0\xfb{\xd0\xba\x0fo\x06d>-\xdav\xa3\xd6nT\xbf\x85\xf5A\x06X\xd5\xe8\xc1\\\xfb\xf2\xa1\xa6\x8b\x92\xcf\xc7~I\xb0\xbe\xe8\xebhMt\"\xf4\xba\x9a\x04\x8d4$\xc9\xf5\xd5\xbc(\xc5\xa7\xcb\x92\x8aL\x0d7\xffo\xc3\x87\xe9_\xad \xf6\x9b\x91W\x92\xa2t\x93\x11\x05\xf6O\x1c>#\x93\xc7Q\x91\xa5\x05f\xe6w\xde\xd2\xe3\xe3\xa6_\x96~\xb0\xa2\x07\xb5xI\x05.\xbe%4,\xa1\xdd\xb7\xa4\xe0\xbd~5\xb4G\xec[\xf4h\x82\xd7\xb9\x9f\x14\x0b\x92\xcb\xba\xd6|\xa3\xd75\xeb\xcfI\xdf\xd0(\x8f\xe9*8\xf4\x98u Jx\x9c\xb9\xe9$\xa4[\xf9\xa2\xca\xb1Q\x92\xf3\xf2\xe6\xaa\\\xc7\x16\xban\x0c\xce\xe9\x1e\xf0\xc2\xcaV%;(\xa5\xc9\x0ed\x17K\x80pa\x84\xed\xca?\xb2\xebT\x9f\x94`n\xf1\x8938\x84\x93\x0b\xca\xd0\x15\x9byQ\xe6n\xea\xc5~Q>MBr\xfeb\xe1:7\x9d\x11\xdc\x80\xe9h\x0c\xa7o\xbd_\xd3(q\x9d\x99n\x9b\x8a\x0b\xed\xfc*D\xd5l\x08=\x13\xd4\xc9\xfdpdZv\xe0K\x7f^\x99{\xc8y\x99\xfbA\xf9\x84\xe7oz\x92\xa7k\xde\x8fF7\x98W\xc4\xc8=2\x18\x84\xe8\x85!<\xb43\xcc\xeaG\xe7\xf3\xdc\xc0 i\x9fR\x1aTy]\xd6\x99+\xe8\xc7%\xb7yB\x8b\x17\xf9\x8b\x8c$\x1c3/eIq|\xa3\xc6\x16\xaa\xfa\xec\x06\x07\\\xd8\xa9\x06\x8a\xb88We3hw>\x863\xfd\xa4\x83q\xe2\x9bYf`\x11 #\xff\xb5\x9aM\x91\xcbc\x06g\x83\xc7\xa2|\x81\xb3\xdb\x14\xf1\x94\xe3`)u\xb8\xce\xa8\xfa2\xe7< $%\x96\xd6\x86\xf9\xa6\x84\x8bt\x93\xc3\xd7r/\xda\x99f\x96k\xda\xe7\x06'\x84\xa2\x81\xdbN~\xc8x\xd7\x9b\x14\xe8_7\xb3\xd8\x8f\x92\x9b\x8d\xd9\xff\xc8\x036\xf0k\xc2\x88\xa7\x181\xcc\xe0\xe6\xff\x8d\xd6\xfe\x92\xfc\xebf\x0b\x87\x12\x8f\xbb\xfd\x14\xaeSl\x97\x8e\xd6\xb0\xd1\xa4\xf9\x0e8\xa8Fv\xc0\xd1+\xdb\xd7K\xed!\x80\xf9\x9ed\x9a\xcb\xe6\xb5\xf6\xcf\x7f\x89\xc2r5\x03g\xba\xbf\xff\xff\x93c\" \xe5W7\x94\x073\x1d\xbb\xa8\xd0\xc8\xf0\xb9\xf37a\x94v\xe6\xce\xea\xb8P\x9f\x8d\xf4\x8bzC\x117G\xaa\x1d\xb1tA\xd1h\x1c\xd7O=\x9d\x11]\xado\x96\xacL\xb5\x89\xe8\xc48\xcc\x7f\x88n\x1f\x04O\x17P~\xfc\xbdQ\x9e\xcbtE\xe22o\x0d\xee\xe4\xf5-\xec\xc3C(lw\x80z\xf9\xad\xcd\x7f\x91:\x9c\xf1M\x92\x93 ]&\xd1\xbfIX\x99\x89p\x8e\xbf\x16\x81A\x94\x89\x10A\xee~\x81\xd4\xdd\xd3E\x8a~\xca\xd9/4\xa4\xf8\xd3M\xe4\x06K\x91@\x99\x8a)\xad\x8d\xf7Z\xb7\xa5\xe5\xa5q\xa4\xe1\xc5Vg,\xc0\xb0Tz\x9e*]\xab\xacm\x916UH\x98Yu'\xcb`\x95\xef\xd0}p\xf7\x8e\xc4\x88\xa7\xd7}\xd6\xbe\x9eY\x1c\x95\xeeM\xf7\x9b\x7f\xdd|x\xf2\x7f\xbf}{\xe3\xdb\xd1\xcd\xe5\xc8[DqIr\x0b\x0fK\xfe!\xc7\xa9\xb2\x0dEkY\"\xdc\x8e\xfa\xba\xdd\xdf\xc8\xb6\xbf7\xbf\xf9\xd7\xcd\x1b\xac\x9b\x9c\x11 \xda\x0f\xfb\xf6\x1f\xc6\xaf\xfe\xeb\xa6\xddw7\xb6\xdf\xb5\x9e@\xec\xc0\x9er\\\x80\xc8E0\xef\xf0^$~\xf8\xbdn\xd6\xf8!\xcf\x9d\xd9\xed\x850JuM|\xf0-Li\x13\x0d]Gm\xcb\x9b\xbe\x85\x87\xed?g\xf0\xbb\xe4\xdcg\xb1[\x82\x83\xed?G\xbd\xad'a\x89\xfb\xa01\x1c\xca\xf4\xa6\x01\x1c\xc2IGeSg\xb2\xa5\x7fu\xe2\xac\xe9x\x17c4\x07\xbb\x0b8\x042\x86\xd4]\xd8\xb8\x13\xf3uR)\xeau!]\xec\x14wK\xd6^\xe4\x96\x94uq\x1e\xc5i\x11%\xcb\xd7\xfe\xd2\x81\x19l\xf8\xdd\x17\x19I\xea\xbb>\xbf{L\xe2E\x1b\xdeyM\xe4\xb9\xbe\xe5\x01\x81\xed\xa3\xf7\xfdH\xe2\xba2\x86TeR\x8eLI\xeaX\xfdq\xa4\xe8\xbd\xe7\xad\x81R\x1e\xdf\xa7\x88\x15O&\xf2\x9e\xd2\xad\x95\xbb\xc9\x18b\x85\x92\x0fK\x89\xc3\x0d\x88\xfa\xef\xa3b\xb69\x83us7n\x8c\xa1\xd0\xd9Y(J\xa4'%L@\xe7\xbe\x1dVP\x07\nM\xa1|\xb8l\xb9\xf0\xef\x0c\xe7 ov\xbb\x1aV\x8f\x109\x1d\xac\x9c\x057 ds\x0f7 \xab~ET\xe8\xc4\x80\x05\xec\xcd\x18\xb0\xeb\xc6\xf0kh\xd0\xa6\x0eN\xb4\xc7\xc3\x81\x02o\x91\xe6G~\xb0\xb2\xdb\x1e\xd9 yK\xf7_\xf7\xe4\xa42jfw\xaa\xf0/\xed\xedu\xfc%F\\\xfb\xfb\xaf\xa6o\xe9%\x12\xb6\xde\xfc\xfb^\xdd\xc0\xdf!'\x19\xf1\xd1vB\x99\xbaoVe\x99\x15\xb3\x9b7\x97Q\xb9\xda\xcc\xbd ]\xdf\xfc5M\x8a`\x15G\xc9;\x92\x977[\xf0\xdf6\xbe\xd4\xfc\xe8\xa34\xbb\xc8\xa3\xe5\xaa\x047\x18\xc1\xc1\xfe\xf4\xf6\xe4`\x7fzg\x0c?\xa6 \x1cW\x1f\xf3\x9a\xef<\x8b\x02\x92\x14$\x84M\x12\x92\x1c\xca\x15\x81\xe7O_\x8b\xdbM\xd0\x9b\xd5od\x06X\xd4c3\xb3\x842\x7frw\xdeq\xe3\x08Ab\xaf\x12$\xc8\x08\xcaU\x9e\x9e\xa1\x9d\xe1\xf5EF\x8e\xf2<\xcd]\x87\x9cgL\xdd\xe6\x03\x7fI\x92\"y\x8a(]\x8e*^\xa3\x0fr\xd0\x05\x81\x1b]0\xe1\xa9@\xc4\xc1\xf4w(\xfb\x1f\xca\x19\xf7A\xa9~\xc3\xce\x98\x8fX\x16\xf4\xfe\xc4@S\x9d\x97Vg\xde!\xc5\x1b\xde\x97\xca\x1e\xb1O\xb1\xa9\xfd*z\xc7|\x8d\xa5\x00\xaa\x97\xd1\x0d\xe3[\x98~=\xa2''\x0b]qS\xb8q\x88F\xf8\x12\xbe\xfd\xf6\x10\xa6c:\xc4\xc3\xee\x18E\x8b\xf4P\xe2o\xb4\x1a\x1f\x86\xed5cxw:2\xe1\x82\xc2\xbb)w\xc9\xc8+\xd3g\xe9\x99\xa8D;\xac\x0f\x1f\xdd\x99\xed3,\xfe\xba\xa82\x1b\xd0_\xf7F\x7f\x8e\x82\xaf\xdb/\x05f\xd4\x05f\x84\x17\xfd\x80h8\x81\xe0\xb9\xaa\x8a\xf6\xa8\xe2\xa8\x8e\xceKM1\xef\xb4[\xb2;U\x97\xecN?\xbeZ\x88 t\x9d\xb1\x98-\x8b\xe6z\xddReh>t\xb7Jy\xa7\xd3Sr^\x92\xa4\xe8\x1d\xf6\xef\x99\xe7\xd4\x0c\x9c1\xf0\xa3)1\xd7\xda\x8e\xae\x1bB=e\x9ecG\xeb\xac\xbc0\x94\x89\xef\xc5\xd4\x8a*\xf1\x98S\xb5~'\x12\xfa\xc9\x88\xeb'\xafU\xc5x\xd5\xc8m\xf0\x10\xb1B\x85\x88Q\xc1\xbf(9\xea\x98\xf9S}\x02\xfb\xfc\x0b\x8f\xa3\x02)\x9d\x14\xa1\xf9\xb9\x8f4\x0f{\x8d\xda-\xf4\xf6\xbb\x0c\xaew\xf4\xa9-\xd4\xa7\xad\x9c\"\x0e\x9d\x96\xe9r\xa9\x11>B\xdesY\xfa\xe7\x9e\xeb\x86\xba\xbfQ\x92mJi#\xcc\x04\xee\x04+\x12\xbc\x9b\xa7\xe7\x12MY\xa3\x0b\xfd\x87\xf8\x1e\x1e!\xa8t\x90(tj^\xc9\xac\x9c\x8c\\Q\xc1\xda\xe3\x1f6\x1e\xb7\xa318\xc7$ \x01'\x95mL\xa7\xe7#\xf4Y\x95\xe8\xff\xa49\xa1\xe5&\x93Pj2Q\x94\x93T\xa4\x88\xbeu\xd0\xcb\x0b\xf0%\x17\xb4\xdc\xb0ag\xd4\xb0\xcd\x05-v\xe0.f\x82\xa1\xeeG_}\xd5\xfa[-F$&\x1bD\xc3\x02\x90TC\x18\xb9\x89'$\xc618\xcc9\x03\xad\xcb\x88\x13\xcc\xbaLD^\xc2\x84\xd5PB\x91\xbfOG\x9a\x96\x14\xebCK\\\xdbai\xb2\xad\x94\xc8y\xad\xc2W\x03\xa5\xd6\x9af\x1fS\x1aX\xc9\xb4\x9b\x1a\x94\x8a\xc4\xda\x05IxT6\xce\x15.\x04N\x1e\xe5\xe4\xdct\x0c\xfe\x186*S\x10\xe6\xf3\xe6\xd5*X\xcdA\x8b\x8c\x05\xc2\x00c\x9ci\xc6KX\xea\xf6\x13\x10u M\xd3\xc8\xca\xb5WHg\\\x18\xb5r\"\x19C\xae\x98\xdbF\xf4\"\x96\xf0`k!\x0e\xb3\xaf\xbe\x02\x07\xb5Y\xb8\xdf\xd2z\xa1t\xfa$\xc1\x9a\xe9\xa2\x96\x01\xcf\xc3\xa88>\xf3\x97K\x92\x1f\xa0N\xd6\x87\xaa\x8d\xf3I\x9d\xf9\xf6\x8f?\xd8]L\xcf\xcbi\x11\x8f\xed\xad\xefW w\xabT\x8aj\x88\xc67f\xd8\x0b\x9e=\xea\xab\xaf\xc0m\xf4A\xd1\x83\xddZ\xaa+`\xef \x07\xb0\x1e}tY8h\xb2Y\xcfI\xfe\x9a\xeb\xc7F\xae\xaf\x88\x93\xeb{q\xc90\xdd\x1d}\x9c|\xedU\x12\x86_\xa28~E\x02\x12m\x91;\x91\xd5\xdc\xb7\xce\xc5Ps\xea\x9fxw\x99R\x88G\x97\xda\x83Hd\xa2\x02 \x1b\xee\x84\x1cf*3\x9a\xcd\xeeJ\xab\xed\xe4F\xad|\xd4#q\xa8\x07,%\xf5h\xc4Q=\xd9\xac\x91w\xf5\x81\xe5b\x88:\xf7u\xad \x17\xcd\xc6{53lJoP\x18\x86\xd2\xd84\x1b\x8c\x03\xa1\xff\x9d\x893#'\xbfm\xa2\x9c\x84\x8cT\xe1\xae\xf2\xd9\x19L\xf72\xba\x89x\x8b(/J\xb7\xb3\x01\xb1\x90e\xc1?+jZ\xdam\xc7bTe\xd1\xee\xee\xb4\xfe\x86lo<\x99\x18\xf4\x01\xbc\x05\xec\xce+\xc3q\x9fX\xee\x8f|@V\x8e\xb4\x865\x98\xcb#.?sm\xaf\x9e\xd7 Z{\xfe\xa6%\xaa\x0b\x95\xb7\x1e#\xad\xe9M`Mo\xc2\xea\xb3\xe6\n\x0f\x85\x91\xde`\x95\x07cj\x11\xafX\xa5gGB\xdde(\xef\xc0\xa0\x1f\xa5\xebu\x9a\xd8\xbcs\x81^\xd9\xce\x8fE\x9a\xb0\xcc\xe7O\xd2|m*)\x9b\xbb\xcc\x98\xfc=\x0b\xaaQ\xc2\x9e\n\xc7\n\xc6n\xa8\x01\xcf\xe0\xb0\xc9\xa2\x9c\x9a\x0b\x98\xceM\xf6\xac\xb6\xc1\xc9`\x15Y$Zk6\xd4\xf6#\x83\x95)\xa8\xec3\x85W\x15S\x10\xd8\xea\x06\x06\xbbP\xd0\xf4\x8f\xa2\x9fh\xa4\xf3\xc1{\xf4\x135\xcd$E\xd9\xc8\\hot\x92\x91I\xbbwk\xf3\x93\xa1\xf4X\xc3\xc2\xa3\xc9\x05\x04\x83\x8b\xb65\x8dL\x81\x12R\x97\xe1\xe4\x88\xe1\xafm\x0d\x8ds\x06nSC\xe3\xb8\xb13\xb8\"\xddT&\xa4 \xde\x94!MEC\n-\x93\x12P\x89^\xfd\x81\xef\xea]\xb9H\xf3\xb5\xaf\xed\xe5\x0b8\x04\xf4\x81^!7Rv\x18\x11\xed\x86x \x87\xf0\x82\xbdP\x1a\x10\xf45%\x00\xb47\x8f\xfd\xd2wL5\xf8\x9eS\xe8'\x15t\x94\xd4\xa1\xe5\xea\x97\x9e\xd6\xc3\xae\x19\x0e5\xf8\xaf\xa2\xf3(\x0cD%Y\x17T\x16\xc0\x81t\xab\xc95\xaf\x9f\xe0\x10\xde\xc1Cx\xd7\xe5\xa1\x1cM$\xe7+8\xc4\xc0GW\xd4\xa2\xe8\x12\xf0\x91[Vy{\x95_y\x0c\x87\xb0n~e\xe0\xfb\xcf,\x12Y\xbd\xb1\x80\xf9\xcd\x02\xe6 \x1c\xc2\xdeT\xab)h0z\xcc\xe9\xfeY\x8dOl=:\xec\xe03:v\xda\xc1gM\xbew\x8c\xfd\xe1\xb7\x84(\x87\x86\xe37\xf5\xf7\x04h\xe3koh\x9bo\xea\xf0e\xda\x03\xec\xf5~\x1b\x8e\xf5\xed\xb7\xfa[U\x1b\xe3f\xccB\xd9\x15G\xb1\x02FWL\xd6z\xa4\xe8\xf3\xf6\xb3\xdc\xfbH\x17&\xa8\xb0\x99\xd9\xba$4\xdf\x8c\x12\xa7\xe5\xde }\xe9\ns\xf8\x0fq&\xba\nC\xffSx\xd82#\xd2\x06\xa1\xa2\x070\xeb=T\xf6\xa6=\xb9\xf8au\xc6\x00VF]\xddC\xabT\x0dA\x1ac\xbe\x10\xdaS\xf5\xd9\xa7\xea\xaf\xf3?\xff\xef\xefN\xc3\x8f\xee*f\xb39Y\x9a:\xe9cx9\x86_Q\x0fu\xe2\xc0\x0d\xf8\x15n\x80\xf3\xd6\x19\xc3w\x18\xc2\xb7\xf3\xac\xb5z\x92\xa7\xd9\x84\x9fg\xca)p\xffJ\x1b\x1d\x833\xd2o\xb5\x1d\xa7 $YN\x02\xbfT\xad\xcf\xfbq}\x96\xd6\xdb\xbf\xf1\x16\xc6\x846\xfe\xfep\xab\x15i\x9c\xe4\\g\xdcb\xdbq\xba\xc6\xb0\xa4}~%\x94\xe3\xaf\xae4G\xfa\xb1\x89\x9dgnW\x14o&\x14\x83\x0c\xeeR\xe7\xff\xb0H\xa9~\xfe\xb3\x1f\xeb\xcb\xb0\xc8g\xa8N\xa0\xbf\xa63\xf2X\xcc\xc8\xe3\xff\xf8\x19\xb9\xc2\x1a+;8wV\xdb\xa9\xe1\xe2\xa9!\xca\xe7Zz\xcc\xeb\x9f\xc8\xbei\xc2\x8a\xbd3\xd4\x0b\xc3\x1f\x7f\xc0\xde\x13\xb3$\xab\xed\x87\xca\xf9\x85\xb2+\xea\xb5\x14\xbdw\xbe\x89\xbe\xfdn\xebG1\xa6\xe2@V\xb4\xf8\xe6f\xf4-=\xe6\xe0\x06\xbc\xb1\x88\x8eo^\xc2|\xaa\xc1\x8f\xda7\x8f\x07\xf5\x8eU\xc9\xcd\xde\x8fZ3\xd5\xe0\x94~\xfb0s&\xd82\xbbi\xe3*A6i\x8d9\xfbM9\x98\xd7t,{\xcf\xb5'Z+\xcb\x13\xc6\xdc\xce\x0cY\xed*)\x07\xcb\xebP\x94\x8a\xcc\xd3\xa3\xad$o\xd0uX\xebM\xb8N\xf3'5\x84`\xabf\xf0T\x0d\xd4\xd8Z\xf2\xedVK\x9d\x8c\xd5\xa2\x14\x0f&\xd0p\xb9m\x83\xcfXx\xbd%\xef\xbb\xabV\x84\xd0\xc5+fB\xccc\x7f\xea\x1a\x12\xf5\\^(\x11\x087\xc3\x0b\x0d\xc5:\xd2-\xab\xf5\xba\xd5\x0e\x96\xdd\xba\x88\x06\xa4\xe0\x0e\xd9\x9a\xacVvZ\x1f{\x8d\x8f\x98\xb3\x8e\xd6A\xb3*\xa2\xf6\x8d<\x89\xa5\x84H\xefX\x01G\x816M\x1d\x8en\x9a\x84K\xda\xac\xa9\xc9\xa9\xec\xe0\xc7\xa4,\xa3d\xf9$\xcd\xdd\xa0'g4\x183\xcdD\xd4>k3\xf8\x89\xb96PY\xf5'\xe4U\xd4\xaf %\xa7~\xf6\xae\xca\x89\xf9\xfa\x97R T\xaeT\x81\xca\x95*P\xb9R\x05*W\xaa`\x98+U\xe0\x16\x8d\x8e\x06jO\xe2\xe0\xe3\xfb?-l\xfd\x9f\xbe\x04\x98\x0b@\xfb\x00\xf38\n\xde}j\x87\x17k?$R[?4goevS\xc30\xcb\xe0\x1aU\xferma\xe2m\xfd8\xe2\x85\x1e\xfcu\xe1\x9e\xa4c\xf0\x91\x02UO\xbe'\x8b4'\xfcp\x12\x00\xa8\xb7\xe3\xb3\xe4\xa5 \x7f\xca|::7\xdd\xd1\x18\x12\x8f\xf0?4\xc7\x82\x18\xb4\xf6\x04\xce\xf0\xf4\xd5\x9c\xa3kn\xe1\xe8\xfb\xec\x02\x12*\x837\xda\xcb<\x0d7\xc1\xb0\xb8\xfe\xca\xdb\x8f\x8d\\\x92r\x80\x7f\x94\x19\xc9O\x04 \xae^\xf5\x1a\xeb\xf8\xdb?i,\xbf)\xf6y\xce\xa2\xabme\x93y\x99\x00G)\x10\xe1G\xfc\xd8f\xa9\xa6\xae\xdb\xb1\x8d\x19X\xee\xab\xb2\xc6H+\xa0I\xd3\xc9\xf8\xaat2\x1bU:\x99B\x95N&\xe6\x0f\xe4\x15\xd0Z\xb9c\xaeY\xc6\x98\xfeG\x84\x1e\xfa/\x0f\x1e<\x90 \xe9\"M\xcac\xa6\xcfv\xa2\xd2\x8f\xa3\xa0\x1b\xa2\xd3\xfa34\xd2'\x03\xe3\x00m\x1a!)\x83\xd6\xab\xbb\xa4\xf6\x93\xee\x94\x1fc\xc72\x03\xaf\x18\x02#\xff\xdb\xe9\xd1\x8e\xa5\x9b\xc0L\xb9`\x00\xf5\x82\x81\xfeEP\xb1\x08\xc62@\xc0\x19\x04:\xac\xb6\x17\xd1\xc8u\xc4\xd6V\xf9\x05C#\x94\x06\x9ae\xe1wVyC\x87\xd0\xf2\xfe\xeb\xe39\x01\xf46&C>\x06\x90\xb7yz\xaaI\xca\x00\x9c>\xff\xc0\xcb\xa9\xea\xe3\xe4\x8dI\x06@\xde\x85\xdd\x86;$\xd3\xc0\xd0.M\xf2\xf4l\xd7^\xed\xd2\\\x90\xc6\xfa\x05\xb8l\x92\x02\xd8\xb1\xddV6\x82\x8f\xdf<\xf3\x1a\x1a\x90\x05\xa1\xf4HR\xe6\x17\xb2\x12\xb9&\xdd\xb1\xf0\x01\xee\xc8?d\x0c\x07\x06\xbf%\x10\xee\xbb'\xfb\x9ax\x10q\xa1\x0b\xef\xc9\xd4\xa2\xda\xcf\x9e$\x1f\x83\x1b\x8d\xaa<\x81\xeaL\xd5\xe2\x12N\xbc\x91\xd7\xf1\x19\x7f;\x12N\xb4\x1dOr\xee=\x02\xb3\xc6S\xa3G\x89\xb86\xb2\xa6Z\x0e\xec\xfa\xee\x9a\xd8W\x8b\xbd\x0c\xe2HJ\xb5`\x97\xf0\x0f\x10\xd7P|\x06\xd6lz \x13\x94\xb8vl:\x92(\xa3?]o|^Fb\xa39H\x13\x9b\xf6)\x97\x80\xb6CGx\xcb\x991\x95\xbe\x83\xa6D\x83\x97\xa0\x80\xe5\xdcb\xa6\x1f\x94F\xfdX\xc3t\x93CHS\xbd\x83\x94c\xeb\x88?x\xcbP\x82\xba)\n\x85x\xf7\xba\x89B\x9fT\x83\x19\xc8\x04\x1e* \xb9\x81\x10xP\xdc\xf93\xa8/\x1b\xfc\xbeDK\xd9g\xf9m#5m$\x90k\xaa/\x19\"m0I\x83\x84Q\x99\xe6F\x0d#SF\x92<\xb7P\\2md\xec_\xa4\x9b\xd2\x02\xbf\xb3p\xb9#\xcc \x884\xdcH\x18\xe55\xf8\xf3\xd5\x07\x84\xcaL\x04\x82gv\x8a\x8c\x04\xe6\xe1\x84W9\x9c+\xeb<\xf3\x0b\x93#\xc8h\xa7tj\xb6\xfc\xfc\xa2\xcdL\xeb\x93\xa7C+\xcc\x19gA>\x05\x0c?u\xc7;\x9e\x95\xa5\xe1h\x14\xec}\xd9<\xa2\x94V\xea\x9d\xf6jo\x9f\xaa\x8f\x9f\xf7c,Mgh\x86\xe9\x90\xf4\xa7\x87\xd031\x7f\x1fVg\xaf\xe9+\xcd\x99\x0fx\x08+\xb7\x03\xc5\x1c\xc3\x1a\xae_\x02\x16Co\xc4\xcd\xcc/W\xf8\xbe\xb2\x1f\xc5\xda\x8f\xe3F-F\xbf\x84\xee\xeb\x0d\x7fW\xf5gt\xce\xebFw\xff\xb3UT\x92\xe3\xcc\x0f\x98k;\x99\xe0\n\xabw\x95U\x15Gi\xaa\x01>\xb05)\n\x7fI\xb4\x07\x8b\x16]\x8cC\xc2\x8a\xa0\x93\x90\x04)3\x91;3p\xb0\x12\x8aah\xc1&/\xd0\xdc\x94\xa5QR*\xb9\x1f\xd9\xd8\xb0\xb6\xb5\x8e\xe6i\xaa(W\x07\x7f\xe2\xcd\xa3$t\x19:\xe4R\xbb\xb6\xf3\xe3f\x9dA\x99\x02\x1d\n\xc5\x96\xbc\xd6U\x88\x1fm\xb24\xd4\x04\xb6\x13m\x91C\xe5\xbc\x8c\x8f\x92ZtwJ\x8e%h\x9fEE\xe9E\x05\xfd\x8f\xdb\xd9\x0c\xf6\x9bI\xb2\x97\xb8\x9f\xb0\xc7v\xd5%>\xc4\xd2\x804\xc8!\xfa\xe3&\xe8\xe5\x91c\xcc\xa4\xdd\xa7\xd3\xa4Z\xc6\xd6\xe7v\xde\x19\x9f\x90\x90Z\x13I\x0c\x0fB\xc4\xfd\xc8$\xcd~3\xff\x99 \xd5\x95\xd2\xa86\xd6Z\xd1\xab\xf6+\x06\xda%\xd3\xd6\xad\x94\xda:\x17\xd3k9\xce\x88W\xa4t\xc0\xb1\xb1\x1d \x11\xfcd\xff\xadW\xa6o\xe8va\xf5\x8a\xe0\x06\x10\xaf\x88\xa3\x80\xb8\xd3N\xc7\x04-\x81^\x1d10\xa7\xccm\xf2\xa4-\xa51\xfb\xc2\x17\xbd.\xbf,\xf5\xbaA\x95\xbb\xefO\xa3\xe1\xfd\xe2\xa0jQ\x01\xe9\x12>\x87\xe2\x13u\x12O\xdc\n\xd7\xd0\x93\xb0\xca\x92\xf58\n\x9f\xa7\x9bD\x16Td\xab$\xaf\x95\xe3\xcdl\x1fE\x95\xce\xa837\n\xf0*?R\x7f\xb2\xda\xf3!;J>`\xea/\xd2\x1bT\xfbN\x9d\xe6\xa9s\xbf*\x9d\xcf+)0\x9dH\x13G\xa4\xc3\xbf\xc4\xf8?\x81\xb9\xa39\x04\x93\xb5\xa3\xe2\"M\xa6\x0e\xec\xaeV%\xddv\xb3\xda\x89\x89\x82^\xc8&\x8edR^dD\xb0\xb7\xc8f\xba ?\xfe\xa5\x9f\xd1\xe9\x11\x0b4\xd6\xec\xd4\x03s\xcd\xf4\x9c\xf5J\xab\xf7\xd5\xc4\x85\xa9\x06SZp6\xe22\xe9fR\xe6C`\xa5\x953\xe8\xdb\xf8\xa05\x81\x9bR\x8fm\x80\xaeE}\xc7\xda\xe9z\xa5\xdbB\xcf\x98I\x12@\x8fzU\xa9\xf9\x08\x93^~\x93\xe6\x16cI\xb5co\x91\xa7\xeb\x1f\x8fG\xee\x89C\x0f\xb5(@.\xff\xe6\xafE\x9a8o\x1b\x9c\xe3\xf8\xday:\xd3\x1e\xbd\x10!\x06\xcf\xa2\xe4\x9d&5\xfcug\x10\x13\xf7\xb6* \xfdg\xc9\x18^\x05?\x98H\xf9\xc1\xa8\xe2\x07\x93\x11\xe3|\xf6\xbf\x86\x0d|\x03\xc9\xd7\xb0\xa1\xfc`t\xb2i\xf3\x83\x1b ?(\xf8\xcd\x0f\xc5\x08F#M\x12i\xcc\xb2\xf8\xda_\xa2\x05\x17u1\xa7\x8d\x1bLx\xa5\xccn\xa1X,\xb8B\xe6\xad\xd9\xb2\xc5i\xaf3:5\x98\xb1\x96\xc7\x003\xfd)\xf2F\xb7\x87\xa8\xe6G\xe87^d\xd7\xb9\x87\x9f\x80c\x1a\x14\xadf\xed\xf4\x91\x0fq\xfaH\x07\xa4\xcad eK\x7f\xb9$aE\xb8\x0b]\xc6G\xcc\\lv 11\x0f\xf6\x8aB;\xee*\xdd\x92|\x1b\x913S\x8d\xc1\x17\x1c\xceA\xa1p\xb0\xf56\xad\xad\xb7U(\x9d6\xaa\x1e\xf8$\x9f4z\xe8/\x0bg\x0c\xa5\xc1Y\x98y\xcf\x08\xa7\x92\x08\x1dI\x8c\xb6\xe2\x9dye\xa86M\xd5OT\xc2*_\xb8\x84\x9f\x05\xec\xe4\xb6\x00\xf5(sF\x1d\xe8\x9cl\xd4\xee\n\x00=;F\xf7jbPL\xd9\x95\xe6\"\xe9}\xd3\x85\xef\xaa3A\xa7\x87\x1b\x0e\xf3\xa2S\xcd\x89o\x9a\x90\xda\xef\xc1\xe0\x93j\xf4}\x00\xd6\xc3t\x00\xab\x0f-\x0bN\x992\x86PG\x06\xc4U\xa7\xeb7\xc32b\xb36d\xb0\x15\x17\xf33\x8b, \xe9N1$G\x05\xce\xde%\x0d/\xad\xc6\x06\x1e\xc3\xc6\xd29}g_\x0b\x10\x1b\xcc\xa2\xa7\xc6\xf8[q\x898\\C\nSzE\xe1\x0c\xd2*\x19\x93\xc5\x0bt\x8b%Z/\x9c&\xe4\x8b\xec\xa9\x19u\x9b\xc0/s\xb2\x88\xce\xb1\xb0]\xbd\x0c\xc6\xb7W9Y\xcc\xc0\xf9K\xf5\x12\x8e\xc6\xa2\xd9\x8a\xde0\xda\xa1'\x1a\xb6\xfe\xdbR\xb0&\x08&\xca\x8f\xfeM\xe0\x1bVUDM1o5\x0c\xfa?\xa5u\x9cv\x01L*\x0b!J01\xc9\x1eHm&\xad;\x03\xe5[\x83SI_\xa4\xb3\x12D\xa4\x04\xc7Z\xe4\x10\xd2\xc6\xae^\xc9\xcd\xfa1\x1a\xbe?i$.H\xbcS\xfe\x077VQ!\xb0=\xaf\xff%\xf9\xc4\xe5\xf9}\xde\xea\xc7\xe5S\xf964\xb1\xa8\xed\xed*'\x91\xcc\xc3\x98\x8fb\xe4\x9e$\xc8\xdc\xc0\x1e{[V\xe4\xbf=\xab\xd7\x8a\x81\xd7\x1d8I#\xd7\x83\x89Y\xc7\xa1\x9b\x98tJ\xcev\xe2\x9fc\x8fnE\xdd\x99\xc3(\xa5\xe6\x0c1\x9a\x99\x81\x87J\xffB\xa2\xe5\xaa\x9cAN\xb9\x9dy\x1a\xb3,\xa4I\x9a\xaf}m\xfc\x9ez\xec\xb2\xe4\x00j\xf0\x96wl\x9c\x06\xef\xaad\x04\x94e\x1b\xee\x05l%z\x08\x9f\x0b;\xe9\x83\xce\xca$\xf6\xe7$\xc6\xf3HQ#|\x0cI\xdbT\xbc\xb3/\x03(\xdbW'\x1f\xb4\xb0=\xd8\x1c\x1b\xff\x05\xd7B\xcb\xf84Y\xa4o\xf2\x18\x8f'\xfa\xfb{\xbf /\xfdr\xa5Q8JS+\xa4\xaa\xd4\n\x91*\xb5\x82\xafJ\xad\xb0Q\xa5V(T\xa9\x15\xe2Vj\x05\xb4C\xb7\x01\xea\xdc\x0b\xdcR=\xdd\xbf\x16\xa9\x17zsn\xc5\x11h\xdc(\xbeD%5\xe1\x86\x9eY\xab\xb4\xd0\xe8x\xd8\xa95\xe7\x8b\xb5\xd3q3(\x16\x84\xb64\xd9\xe4jR\xe4\x9c\x00E\x1dx\xf3\xea\x19\x96\xc1-\xd1g\xc1\x81\xb7\xbb$\x80\xd11\xb6vn\xd1\x06\x0c\x85O\x8c\xa5\xd0\x9b\x05\xb8\x12l\x053\xc6\xc2\x00\xac\x85\x81\x98\x0b\x15\xf6\x86~i\x90\x89\x93\x01\x1aM\x00h:\x9e\xf3\x94\x9c\x7f\xfc\x01N\xb9\"\x10\x92-\x89\xe9\xc9c\x905\xd3\xfa\x0b\x14\x93-\x14|\x1c\x9a\xac\xfd\xc8\x08\xefc\xf2<\x87\xb2p\x16\xf1\x1fV\x8cL\xaa\x15/mX\x1e\xa3\x86\x8aq\x94.\x96\xf5*\xfc$*\xa3\x7f\x937y\x99%r\x90\xfb\xbb\x9d8\xc5\x14\x9e\x945\xd4\xb1\xf3L\xb5\xb9\xc9c\x1d\x10\xb3\xd3\x08\xee\xc4\xe4\xe5^\xa2\x0c\xa9\x83bR[S\xca\xd3A\xc7\xcc\xea\x83L\xee\x15x\xcdc\xee\x98\xbc\xcaV\xa8\xa6\xe1\xb1\x8e\x86\xd3\xdeh\xf99\xe4\x984\x829c\x085\x06\xbc\x9a\x19\xd4\x9cZ\xcd9\xd4\xba\x91\xb6\xcfA\x85\xa3\x8d\xfa\xa4\xb8\x949\xb9y8\xb0\xda\xfe\xd7\xedp(T\x87C\xa1:\x1c\n\xd5\xe1P\xa8\x0e\x87\x82\x1d\x0e2\x92_||\x92\xaf\xd7\xa0\x7f!\xf9\xe2\xb2%\xf9\xc2/v\x97 Z\xc6\x1cXo\xa1\xf8Zn\xa1\xeb\xc1_\xf5\xf7\xd6\x17v\xea\xcf\xb2\xb7v\xd6/4u\x0b\x8b4Ugp\xfa\x8f;\xf7\xae\xc7\xa6\x157\xffDB\xd1\x97\x94B\xda\x94BO0\x9f9K\xff`4\xe5\x03\x9fO\x1ed\xd7\xc8 $\x17\x06\"i\\\xf4&\x0b\xfd\x92\xb0\x86e\xc6\xdbO\x9e{\xe8\xd2d\xf2\x03K\x9d\x83\x82\xae\xa5\x96\xfdG\xa9\xd6\x90B\xe9\x8e\x13\xa7~\x18%K\x96\xd5\xb8\xf4\xf8\x9f\xc7\xa5_n\xb4B\"\xc5[g\xe1G1 \x07\xbf\x8bn\x85^\xb0\xc9s\x92\x94\x1cC\x0c\xd2\xeb\xef\xef\xb5\x82(\xba\xde\xb9\x1b\x0f\x0b\xea\xd1\x9e\xe5$tF\xdc\xdb\xb0y\xff/\xbe\xefk\xb3\xa07%W\xfa/\x8e\x0dmw{S\xfe\xbb\xaa\x1a\x7f5\x07$\x8e\x1f\xebU\xfaQ\xb2CN\xfa|XK rf\xaa'|\x9d\xce\xa3\x98\xcc`z0\xb4/N\x94d\x1b\xfbTCut$\x9f\x05\xfe\xba\xf2\xe5,\xf6\x03\xb2J\xe3\x90\xe43p\x18\xea\xc0\xfc\x02J\x7f\xa9y\xab\xbc\xc8\xd0\xbeE\xceu\xdf\xee%*j\x12M\xf5k\xd5\xc1_c\x8aS\xe6\x1b\xe2T\xd8\xe28\xa0U<\x84U\x81qs\x14\x94\xdcn\xf6\x81\x13x_O^*S\xf1R\x99\x8a\x97\xcaT\xbcT\xa6\xe2\xa5\xb2a%\xc53\xca\x15\xb4\xeeb`L\xa6\x89\x9cY\xe0\xc7\xa6\xfbR.,\xfb\xf8\\X\x08\x87\xf0\x84\xb7\xef!\xebAwO\xbb\xcf\xfa@\x1a\xe8\x84\xd7v\xf0\xa4yYse\xc0{\xa7\xe6\x96\xec8%\x11iK\xfb\xa4Wmn\x19|\xc4B\xa3K\xbf$\xd2\n\xae\xe2\x8a\x8a\xa30*\xbfO\xcfg\xb075\x12\x0bGI\xe4#\xc3.\x86+a\x80`P\x02F\x18\xc0\x13\x81H\x95\xc3\xd8?\xacq]4\xa7\xbef\x96\xac\xcdc\xaa\xd3dx\xb6E\x90\x8cD\x9boB;\x14U\xa2\xb7\xa1#\xf8d\xfel\x8c\xcf\x14\xe7\xde\xa34)6k]\xfeD\xa8\x9c\xd62?\xf7\xd7z@\xe6\xb5\x16\x15\xbcf\xb6\x1e8\x1a\xc2\x1eC\xe5\xb7\x96\xf9\xe5\xea\xb9E\x9a\x8e\xcd\x003\x0ep\n\xbfq\x9d\xefYE\x1c\x0dk\n\x9c\x82o\\\xe759/\xbf\xcb\x89o\x02\xcf\x18\xf8*Z\xae\xe2h\xb9*\x1f\xa5\xa1\xd1\x81,d\xef4R\xf0\x99\xde@\xef\xed\x08\x8bg\xe2Z\x91\x92\xe4\xbfD8[\xfe\xf7\x17OC\x92\x94Qy\xe1\xfa\xdc\xe7<\x1fyu\xd9\x94\xc2\x19s\xd3\xf7\xb3\xa8(Gn\xf7\xc8\xea^[,\xa7\xd9\xe8\x1c\xdb*\xae\xcf?\x9a\x93\xdf6\xa4(\x1f\xd9\xf7~\xddBb\xfai\xc4\xccN*Wq[\xf8,\xc8\xde\x98\xd5\x8c\x0c%\n\xd5\x03}\xfbK\xd1>\x12~=\xec\x05\x1c\xc2\x92\x89\xc7z\xc09\x02V\x07\x85\xd1[\xed\xca\xaa6\xcf\xd3\xf0b\x82X`\xf0zpB\xbf\xf4\x19\xe4\x04c6f\x907#8\xec\xdf\x8e\x92\xfa\xdd(\xd1\xd5\xfc\x1a\xc3\x9c.k\xaa\xa9\xae\xb9\xd8m\xb0\xa7\xa7\xc8\xf0\xc3\x0dpW\x0d\xeb\xa3\x03Q\xb2\xf5\xe3\x88e\x070\x0d\x8a\x93\xdf\x0b\x03\xadk\x8b\x0e+? c\xf2\x82\xdfT\x8f\x9d\xee\xbc\x0b:z\xd5\xc8\x8d\xce@\xaa\x91\x13\xab\n\xa3bp\x9a\x1ej\xca\xae\xee\x8e\x86\x13\x96\x91U_P[\x87\x11\x97i\x9b\x84Q\xa9mX\xd5h1\xa0\xc19\xa6\xa0(\x13\x08\xfc$ 1H\xd6\x86u\x04D%\xb50*\xd5PF\xeck\xa4\xa9(\xd3\xe52&O\x05\x99\xd1\xef\xbc\x87\xe0<\xc2\x1ebG\xe8+u\xd5\x02\xcd\xd2\xb3\x0c\x0e\xa6\xf9X\x95\xeb\xf8 \xd6q\xd8i\xbe\xdb\xf1N\xceKq\x8c\x89L\xb4\xc0\xca\x92\xa9?`\xf4U\xe3\xf8\xbf\xd5Oo;\xf1\xad\x89\xeb\xa9(\x81\xc1\xf9Z\x81\x9d\xad\xe4\xcb\x9a}\xa9L\xea\xd4\xbb\xab\xf0.k\xc7\x9c\xd4\x87\xd1\xaay\\\xf6D\x1eq|\n\xdf8m\x02\xe0\xf6\x04\xe0\xf8\xba\xef\xfd\xfe\xbe+\xbfW\xf3\x17\xca\x1f<\xaaz\x10V\xcf\xdf\xb7\x95\x03\xdb\xa6x\xda\xe5\x97\x9b\x98y\x05\x89\xd9\xfdY\xcdLDU\xde\x10T/\xa5B\xbd\xa4\xd0\x1cQ6\xf9\xe6\xf9:\xbe\x19y%)J*\xceJ\xe1(\x83\x8c\xcbf\x02D\xab\x08<\x84\x84\xc7\x80\xd0\x9e\x9e\x9e\xafYu\xb0\xe6M\x99\xe7P\xb4\x00\x97w~\xef\xf0\x10\n\x9db=\x86C\xd8C\x8e\x0f\x93\x17\xfe\xfe\x9e\x8e\xb2\x903M\xc4+HyLY5W'\x1c\xe1fW\xd4\xb0\x1e\x8d\x9b9\xf1\xf5\x9eH\xc5?\xd7\xb1V\xa1\xd7P\x06(\x12\x9cK\x94u@\xe2\x82\xe0\xdc\xb6\x92\xf3\x17x\x0c\xb8\x0e\xce\xb1\xaa[\xfa.i\xbb\x83L\x88\xacEMc\xda\xcf\xb5)\x0d\x17\xf8\xd97\xad7\x14\xd1I\xafXvK\xb7\xe3R\xae$J\xbcE\xe2E\xc9\x82\xe4\xc7X\xe2\x7f\xe4\xe6<\xdaF\x9dg\x8d\xbe\xb7\xa0h|\x8c=\x16/\xa6\xa8\xefT\xcc\x07+\xb0\xf0K\x1e\x95\xe4E\x12_H\xf3]*\xe6EL{kf\x14\n3\xa1\xf7Lj\x19B=~\n\xf4\xcf\xb5\xa44\x99q\xaf\xf0}\xa2\x90\x90\x0d\x8bOw\xd1i]bc\x0c\xa9|\xdc\xa7C\x06\xee\x92N\xed\x0e\xf8\xe3\x0f\x08G\x0c^\xfa\xf96\x03>\x14\xedl\xe8p\xde%\x98\x89\x82`\xa6\x1d\n\xac\x82\xa3\x84=\xa7Bl\xcb\xe0\xea\x95y\xb4vYA6\xbd!\xb6\xb1\x85\x95ek9\x99\xe8\xc7\xba(\xb0\xb3\xc3J\xea\x8eUh\xa8\xa6k\x0c3+\xd9\xf8;v\x8aURc\xbe\x14^\xc2\xfc\xa8\x0c\xc9\xef\xe5\x96\x8e\xeb\xe9J\x7f\xdd+\x10\xd0\x1f\x0f\xee\xdf\x1a\xfd9\x8a\x10\xfc\xf9\x1c\xc2\x189|\x92\x06\x9bK\x96 \xe2$\x88\x15\x94\xa1\x1cB\x98\x068\x0e\x8f\x9c\x93\xe0Q\xba^\xfbI\xe8:A\x9a]\x98Sd\xc9\xa8\xd4\x07\xf3\xcc\xf0\xb8\x12R\xcd\xb4\x95\x9ck\x88\xeb9%W\xe0\xfd\xae\x0e\xce\xac\x8bK:\x8fX\xee&\xd3\x17\xd5T\xb2]\xbf'\xa3\xd2dQ\xaa\xb3\xcb+\xdb)\xc9y\xe9\xe7D](\x11P\x14CTj)\xbb\xf0\x8ezrs\xe2\x87\x8c7b\xb6q5dk$tZ\xd4\xa0V\x89A[\xc52/\x91\x0bT\xb0E\xf2)\xfd\xa0\xe6\xf7\xebP0\xa7\x7f(m\xe8\xa14\x95\x9dJ\xf4\xc9\xf4\xbe\xecX\xa2O\x1eLUqlj\n$\xbc\xd1N$\xa5\x08(\xe3&\xab?U\xd9|\\gE\xfc\x90\xe4EW$\xa5\xe2h\xe9e\x9bb\xe52T\xc3\x84\x9d\xec\xef\xc9?\x9d\xb1x\x9d\xe5\xd1\xc5\x18N\xfe\xf8o\xce\xdf\xb0zf\x9d\xa1\x08n\xc0\xdf\x9c\xbf\x8dx|\xf4\x06M\x12*V\x93\x9e\xaa{\xfbrTC\xb1Wa@\x0e$9C\xc5U\xe6\x17\x8a\x8dP94.\xc6h{\xea\x9c\x1b\xdd)\xf2HR\xe6\x11)\xa8\x90\x04{.\x16\xba\xa1\xc7i\xe6%\xe4\xbctG#/L\x132\xfa\x9a\x8f\xc2d\x8e\xc4L`6\xd6\x91\x15\xefZ\xe3\xc8\x0d\xc7p`R\xcfS\x9e\xedd\xdfP\xa1b\x8dPS\x89#\xa6\xb8(\x12\xad\x1b\xab\xff\x038\xdd\xd5\xde\xc2\x0dpf\x98?m\xcdW[N\x0b\xfa\x84\x00\x02\xbf\x0cV\xa0>Yc\x86\x11\xb8\xc2}{\xc1{XD\x89\x1f\xc7\xaa\x15V\xaf=\xbd\x98\x12%\xf3\xf8\xa1\xd5\xf8\xed*\x06`h\x0e\xf8\xd6\x89GP\xae\xf2\xf4\x8c\xbb\x07u/\xc9<\xfc\x97\xfa/\xfaA\x8e\x8a\xf34\xbc\x90\xa5\xd6\xa1 \xcez\x13\x97Q\xe6\xe7\xe5\xcdE\x9a\xaf'\xa1_\xfa\xcc\xd1\nG\xe6\xbc|q\xfc\x9a\xfd\xdd\xdd\xbb\x1aNa\xa9\xd9\x8f\xc0-|:\xa7\x8e\xb9f_\x82q}\xaa\xfdy:\xc6\x8c\x1c\xf2\xfd\xc9&\x057\xe7\xc51\xf9\x8d\xefN\xdas\xf7\x14\x0e\xe1\xac\xbb;\x97\xc6\xdd |\xf4G\xfd\x8dw\xca7\xacq\xfb\x01\xcf\xf5qd\xdc\x82\xc0\xb7\xe1\x91v\x1b\x02\x9e\x08|\x0f>q0h>J\x8a\xd2O\x02\x92.j\xae\xdb{\x12\xa1\xb0\xd0\xda\xa0\xe7t\x83\x1e\xfe\xffq\x83z\x89\xbf&\xf4\xef\xaf\xcb\x8b\x8c\x1c\xb2{\xf4'\xdf\xb9(P\xf7\xde5\xeem\x90\xe25X\xedq\x10\x98\xb4?F\x8c\x91\xdb\x05m6\x9f\x1e\x9f\xe8\xb5\x87\xc1\xfcg\x8d=\x7f\xa6\xdf\xf3`\xd94\xf0}x!\xf6\xfe|\xe8\xabe\x0f\x1b\x94\xb7#E\xb5 \x84\x97\x13t\x07uo\xfe\xeb_\xc9\xcd\xe5\x18\x1c\xa7\xab\xd8\xe3\xe3/e\xe5\xac\xdb\x1c\x8d\xcf\xb9\x93[\x8aJz\x9b\x8f'\xc4^7F\xefK\xcc\xca\x97\x98\x95O\x11\xb32 Z%B\x95c\xb0\"k\xab\x9a\xd7\x0dp\xab\xcf\x0b\xf1#29\xd5 c\xa0.K\x1b\xb3\x072\xbeD\xc1/\xa0#\\U_\xb0\x1e\x19\xe2J~\x0dCiZ>\x98\x97\xad\xe3-Q\xde\x148\x01\n\xeb\x1f305\xd6\xff\x9aV\xf0n\xba\xa7\xb1\xd0\x17\x8e\x82H\x9b\xf8\x10\xebr\xdd*p\xcc\xa3\xdb\x1b\xb3x\xfd\xf2c\xff\x00\xca7\xbd\xd2\xad\xea\xbc~_\x91\xf64\xec\xa6\x993;\xae\xd4N+\xbcW\xc3\x95h\xc6\x94\xa3M\x1d\x17o\xc5T\x0e\xf2\x98wF[\x89\xc5\\\xe7[Q\x8c\xdb\xa8\xf6R\x16\x8a\xe1d\x16E\x92\x01u\xfcL\xebdY\xb2\x9b\xf7\xce\xa0Z`\x85\xbd\x95 \xb6%\xbbM[jw\x05\xdf\xf5\x8c\xaf\xf9\xc2\xf7} \xbe\xef\xcfg`\xfa\x14gF\xcd\"\x99\xce\x0d\xcb\xb0\x82|@\x90\x00s\xb1\xa8\xc2\x17\xf91\xac\xd1\x96D\xf8\x02'\xf6\xe6\xd8\xd8\x82\x04\x9b<*/\x1e\xd3}\x1d\x95\xa6Z\xc7t+\xe5\xc6x\xdf\x98A\xf9\x9br\x95\xe6\xd1\xbf\xc9\xf7%\xa5\xb0{\xdd@\xb6\xe6\x15\xb0W\xc4Qx\x05\xf60\x8c\xd4\xe5\xc5&\xff\xf8\x03\xfd\x9d\xae\xc4\xea\xc5\xbax\x890\xda\xcd\xb0\x96\x8a+\x89\xa3m\xce\x86z\"\x02m\xd7\x9a\\\x91>\x84\x94u\\\x9b\xdf\xaa\xb1\xad\xd4\xc6\xae\xcaAX\xb7z<~\xbaJq\xf5\x1f\x9b\xeb\xea\x93zo\xc8\xe3T\x03\xb7ht4P\x1f\xad\xd7\xd9wC\x15Xj\xad6\xd9~\xf8\x80\xd2\x88\xfbP\x89*\xf4\xa1\xc9\x87\n\x1a\xf94\xd2\xe45\xbe\xcchD\xfb\x9e+n\xac\xd3\x90\xc4\x942\x8da\x8f\x07\xaaz\xe4<\xf3\x93\x90\x84#\xa1\xea0\xb8\xc6\n\xf8Y\xff\x13\n\n\xd0\xdf\xc3\xf2\xe9\xdd\x98\xb4&\x18iW\xb5&\x87\x89\x11&\x10S\xc8\xe3\xc8\x94\x1a*S\xb8n=ZE\x9f\xba-\xcd F\x99[\xac\xfeK\xee$\xd8\x86\xeaOI7\x9a\xf7\xc3\xf0^6\x11\xbc\x1f\x8e\x0d[E!9&\xf1\xe2Er\x84\xd3j\xe2\xc5\xf4+\x0d\x15\x1bV\xa1\xb5B\xe7C\xf7D\xd2\x89\x07\xac\xf6F\xdes\x0c\x85!\x1a\x90\x0f\xad\xfd\x11s\x80N\xf0\xf5\x94T\xa3\x19\xb4cw\xd8\xaa\xb6\xf3\xf0 \xb8z\xd4\x82\x98p\x08\x991\x956P\x98|\xaa\xe8\xcd\xfe\xfc\xb2U\xe8b\xae.\xdcl\x88F'\xc1\x0c \xea\xf2\xb6\x0d\xb5\xde*\x8a\xc3\x9c$\x943\xfa(M\xebB\x0d\xcd\x0d\xc9\xc2\xcc\xaasM\xc3Q\xdaxi\x05\x9b\xbc@\xa5[\x96F\x892_\x1c\xf4\xb0\xb7\xba\xcb$\xe7?\xed\xe0v\x1fX\xab\x92\x04%\xaa\x1368\x8c\x8b\x95\xed\x12\x1eP\xe4\xd4\xc7\xa0\"|\x17S\xf6\xcb\xbf Ar\x985a\xbb\x87\xa7\x91J\xf5\x85\x02\x990\xb0h\x1d\xd1\x92\xe8\xb5\xee\xc1\xee\xfc\xeey\xde\xfb\x0e\x89k\xb0C\x1d\xaf\x0f$O\\\xf8i=\x10GO\x9b(v\xdc \xbb\x14\x87~\xbf\x1e\xd2\xf83\xf0\xf9\xbb\x96*\xc11\xfb\xa10\xdc_g\xe5\xe0\xe7!\xc1\xf8A\x19m\xc9k\x7f>\xc8VZ\x99aC\xbf\xf4\x0bR\xa2G\x8e\xfc\xc8\xb6\x92Q\xaa^\xa8\xd5\x12\xbd\xdb\x97\x13JP\x13\x98,\xa2\xa5\x02\x8a\x89%\x86\xc0\xce\x00\x13QW\xb9\x86\x9fS\n\xfc\n\xf9\xaa(Y*E\x18G\xc4\xef#\x8b\x18\xa0k\x1b\x12\xef\xc6\x0d\x97~\xba\x02\xb4HS\xd4\x98\xc1\x98R\xf9\xaa\x8d\x99\xc4\x83\xefc\x0b/W\xc9j7\xb2\xce\xb0-^\xffIg\xafq8\xb5\xe0ly\xef\xc6XG\xee\xc4\xd1\x90\xefG%Y#\x9fY\xd3\x9a\xc3\xc3ff\x9d\xc6\xd9\xf2\x10\x1c\xbe\xb3x^\x96\xc1}\xd3\x07\xadt\xba\x16G\xc9;U\x860\xa8\x92\xd9\xf0$8\x8e9\x9dJ[~\xa8\x86\xa5\x1aDD\xc7{\x14F%`\x8c)\xcb\xbe\xc1\x1a\xe1wX\x154\x8dqd\xd7\xa5\xe0\xe7\xc8\xf5Z\x08\xda\xb3\x88'\xe7i5n\xbbBlTW\xb6>l\xc7\xd6\xb9P\xcc\xb1Y<\x92\xcb\x8c\xe8_}\x05\xe9\x18\x8c\xcb\xa0\xa9\x84\xa65\x071b\xab\xad\x94\xd2.M\xa2\xa1\xf55 \xd5\xa6;h\x1d\x06\xda\xc4'\xa4\xa6\x993\xd0\x14\xb3\x14\x14Y\x97\xef\xb4\xf7\xc0(1~\xdef\xa4\x05\x15\xb1z\x12S\xca\x9f\xf4\xa4\xb2H\xbc\"\x13\xbe\x162\xa9l\xc3\x1f\xf4\xda(\xf8\x83\x9eT\x16K\x0dL(\xfe\xb8qS,W\x1b\x98\x16\x1f_<\xcbl\xc53\xbd\xcfn>\x06\xbf\x7f\x92wy\xdfk\xe3\xb3+\x92\x84ozb\xa2\xc2g7\xed\x8b\x8az\x9f\xdd\xbc6X\x1d\xb6\xb7\x8e\x8aG\xcde\x89\xe3\x01\xabE\xc92\xca\x17\xab\xf4\xcc=a\x94\xb3p\xc6@\xde\xd2o\xf7\xe9\xc0\x989Q\x8c\xbb\xe3\xa5+f\xe9\x0dSH\x85\x1a\xdfN\xa8\xb9\xe6\xbc\xbb\x0dc\x9c6\xf8V\xdd!\x1c\x19B\x9f\x9a\xda\xf8\xe6\x92V\xc7\x05J\xb2Q\xdb\xdb\xb7\x03\xe2E\xc5\xf1*=K\x9aK\xdf\x80\xa6\x1c\xc0[\xccB\xa0?\xa0\xed8\x12\xa6\"\x9d\xa7\xe7J\xdeX\xd5L:\xeejX~o\xa9\xfbu=h\x1e\xb4\xc6\xe3\x93\x84Z\x0f\x8e\x90\x9d\xae\x9ax\xb5ZYY2'P\xf6\xa7\xa9]~l\x97]C\x16\xde\xa7T\xa3\x9f\xf5\x06v<\xabc\xe3\x19\x9d\xe1]\xc3\x19\xed\xea\x1e\x82\xf2\x10\x07\xbe\xad\xd0^\xe2\xf06)g\n%\xc6\x9c\x89^\xcc\xa0c\x84\x16G5\xe7\x02\xfc\xa2\x88\x96h\x931\xeb,\xaa\xe3\x806<\xfd\x1aJ\xf8\xa6w*|\x0d%\xa5\xfcj4\xda\xf2<6\xf5\xa1Pj\x82\xed\xaa&s:\xb4d$\xba]%\xfd\xf6V~\xf1\xe2,\x11l\x0c\xd3\x16b\x04\x02\xeeZr\x92\xd3\x13(9\xc9\xdf\xdaF\xc2B\xe3x\xef\xe3D\x1f\x01S\x1bw\x89\xea\xc4&\xda\xc3\x06\x9aCN\xd8\x81\x9a\xc07PV\xb3\x9b\xe8g\x17\x1a+\\\x9e$\x860\xc6\xdc#\xc9fMr\x7f\x8e\xe7a\xebO,&1\xc6\x9a\x88t\xd3o\x04\xd0\xde\xfe\x18x\xf64\xba$X8\xd1\xcd\xbd\xb3<*+\x88\xd1X\xc1d\x12\xfa\xc1w\xe4B\x1a!\".\xdb\xa0<\xa8\x17\xaa\x9a\xff\x92\x87\x9fh\xa6\xa8\xe27(\xeb\xe66P\x89\xee=^ \x12\xd3B\xe5\xbd\x9c\x84\xe2\xea\xf7\xe5\xbd;\xeao\xb3\xc8\xa8\x8c\xae\xd0\"2\xd5\xb9\xb2\xe2U\x80G>\xee\xb9\xa4\x19\x92Z\x8eD$dB\xce\xe0\xf5EF\x8e\xf2<\xcd]\xe7\x91\x9f$i t\xcf\x80\xcf\x8e\x18\xf0\x0b\xf0\xab\xd6T\x825g\xcbT \xf8\xa014c\x87At\x9a4{\xf9\x8a,HN\x92@t\x956\x08+\xbfH\xfeV\xc2\x9c\x90\x04\xd0\xe5\xd4\x8f\xa3\x82\x840\x81b\x93\x91\xdc\x1d\xb5 \xe8\xb0H\xa8+\xb9\x0f\xf5\xfc\xee\x95h\x97N\x11m\x1d\xd8;\xc4\xcc\x9dt\xf2\x90\xc0V\x13\xd2z\xc2\x98}9\x8e@c\x9e\xdc\xa8\xcd\xba\xf2\xcd\xb1$\xe5K\x81|/\x16nd\xe9\x1e\x0dR\x0c\x1c\x82'\x18\xa5.\x1f\xd2W_\xb1\xc21\xa8\x84V\xa0\xcd1\x9dlz\xe0\xe6\xa4((\xf6\xae7E $*W$\x879a\x1fH\xf3\x06\x1e\x8d\x81\xe2\x99\x037\xaa\x86\x14\xabB\xea\xedX\x9fQ\x8c\x87q\xb1s\xad\xfd\xaaa\x97\xd2\xa4(\xf3\x0d\xe5\xcdL\x96o\xbb\xf8\x8c\x9a2\xea\x8b'\xd0K\xd0\xc2\x996b\x1fX7+\xda*M\xc9'.\x05M\x1cq\x87 \x97\xcfT\xd1\xc2(x\x08\xd2\xfb\x1c7f(\xb9\n\xb4<\x94\x8a)n4\x86\xa62b\x0c)\xbd\xa5-\xd7P\xac\xd2M\x1cV\xef\xbc\xc1l\xa5\x96\x95\x03\xb4\x019\x82\xf5\xc0\xed\xa1\x9d\xd7T\"\xaf\xc2\xb70\xa5s\xd5H\xeeY\xf3 \xd3\xb7\xf0\xb0\xfd\xe7\xacg\x1a\xef^Q+\x01;\xdd\xd7\xaa\x02P\xd0\xa03\xcc\x9f\x81\xa5p}\x910\x1f\x80\x9a$\xbc#\x17\x85\x9b#WNZu(F#\x8flI~Q\xb3\x8b\xdaC\xae\xd1b\xe2E\x05\xf2Ac\xb6y\xb2B\xc9\x0c\x01\xe2\x14\x1e\xfd\xedn\xa2\xb9I\xd1\xcf\x94\x9e\x03\xfd\xeeiW\x12:\xddKO\xa8\x9c\x1c\x9d\x10m\xc7\xe4{\xa0\x8f\xb4\x94S\xef\x18\x06\xbb\xc73\xf1\x9e\xae\xd7\x1b\xdc\xa5\xad$\xc3p\x08\xd1\x18H\x83\x89\x8f4\xbc\x8cNa\x06R\xa5\x19\xb4\x07\xf2\x9e%\x88t\xf7E\xdd\x1d|r\xdd\xb4z\xa14WR\xca\x9f\xdc\xef)\xe9\"\xfe\xa4\xa7\xef\xf3\xf9\x83\x9e\xbeo\xc3\x1f\xf4>U\xf0\x07=}_\xcc\x1f\xf4\xf4}\x81T\xdf\xb7@\xf0\xa0s7\xe3\x1f\xb9\xd7t*\x08\xd5\x8a\xc0\xf0\xe3+\x02\xf5e\x8c\x86(\x02\x15\xc1\xfb=\x97\x0c\xad\"0\x96*\x02\x83J\x11\x18\x8f\xc68\xd7\xfb_\xc3\x02\xbe\x81\xf8kXP\x81%8Y\xb4\x15\x81\x0b;E`a\xab\x08\x8c\xec\x15\x81\x01W\x04.yd\xb2\xff=\xaf\xa9n#\xc7\xf1>\n\xdd_\xcb\xaa\xe0E\xc5\x8b\xef\x8eoa\x01\x87\x93\xdak\xa0p\xc6<\x1e\xc7/\x1cz\xae\x9c8a\x1d1\xe5\xbc\xed\xb5\xf3\x9e\xf7\xeeQ\xc7\x13l@\xff\x1c\xe8\xab\x86\xf0\xb3,\x11\xde\x15h@\x15\x8aN\xce\x8f4\xe7G\xbc\xc0\x93\x1b\xbe\"E\x1aoIx\xbc\x99\x979!\xeeI\xb50\x1d\x85\xaed\x85\\\xbar\xf4\x900\xa5\x17(Z\nU\xdb\xf4\x02\xb1T\xa1\xba\xf9\x04\nU\xbd*\xd5F\xe5\xca\xb2\x1d:\xfaa3<\xcf\xfd\x80\xa0\x8d\x18\xb8#\xb9\xaa=F\xb8,\xa9\x90\x1dE\xb4\xebb\x94$$\x9f\x18z\xa7l\n\x1d&\xad\xdb\xda\x0d\xe1\x9c\x12k' z}\xa4\x99#\xa7\xcc\xb5\x9d\xb1\xcb|\x96\xc6\x98\xf8\xec/w\xef\xde5h\\\x17iR\x1e\xb3o:Q\xe9\xc7Q\xb0C\x9a4\xf5`\xc2\xfa\x90jp\x893GG\x99\x1a/\xa9`^h\xa7(\xdd\xe4\x01\x99\xc1\x91\xbc\xbb\xa3Q\x8d\x80\xe7\x94H\x9f\x8b<\xd0\xe7J\xc3\xb4\x95\x0fw\xc7i\xcf\xa2\x8e\x1b\x0bi2\xd9\xae\xd1=\xe9dj\x80\xa2\xf2\xe4\xa9\x8b\xa7\x8e/\xd8\xf2,'\x81_\xea\x99X\xe0\x02\xe6\nm\xa9^T\xa0I\xf5\x1d~\xe8\x9d\xc7\xad&\x85\x9b\x1b>\x91)\xf3\x1f5\xaf-\xe5\xdc\x03?\xfe.\x8e\x96\xc9\x0c\x9c2\xcd\x0c\xf8I\xaf\x8cr\xff\xc9\xf2\x15\xf7\x9c\xd8\xf7\x0e\xc8\xda\xc03\x1amQ,\x026\xf3(\xfe\xff\x82>\x19p\x08\xce<\x8dC=n\xeaw'\x08\xad\x84&\x0d\x04\xb4I\xca\x86G;Vk\xa5\xde~\xa6=\xa3\xef\x17\xa7\x1c\x99\xee\xfb9\xe7dv'\xcc`K\xa3\xa0A\xa7r\xdd\xb0AIy\x80\x1f<\x7f\xd7s:\xf6sc\xee\xb1\x0c\x81w\xef\xb9\xaa\xcb/\xc7\xddT\x00\x16(\xc7\x03\xbd\xd0V\x99\xc0\x0dp\xf0WN\x7f\x9d\xd2_\xbe\xae'F7\x07!\x0f\x1b-\xf1m\xbf\x00\x83\xd5\xab!\x9b\xf1:\x84\x0d\xcd\x00\x86+\x9a\xdb\xe2\x0e\x02\x81\xa1%\xeeIa\xf0 \xe0Q\xdc\x0b\xb8\xa1\xb3\xa8\x8dd\xd62\xf6\xa46\xa8U\x87\xcc\x99\xf1\xb8\xe7'\xe4\xff\xfc?\xa7\xfdV\xf9\xb1\x0f\xa4\xc4\xea@J\xf9\x81\xa4&\xb2\x18\x8dw>\xe1%b\xbd\"\x8e\x02B{s\xa0,\x08+\xae-/\n\x99\xc2CH\xbd2\xfd\xf1\xb8\xfa\x81S\x9a\xf2 \xb2\x8a\x80\xbc\x0c\x19\x07\xb1\xaf,\x1cU\xac\xc9\x074\x99\xb3{\xf7\xee\xe9i\x07h\xe9\x07\xd8\x1c \x0c\x97\x92K\x92G\x18:\xc6\xc1d\x12l\x86\xda\xf1\xfc\xf3U\xbb\x10\xd4\xbc\xaal\x7f\x1e\xd3\x13\xefX0\x816;\xd5f\xce\x9do\xe0\xef\xf0\xed\xa59]\xc9Q`\"\xd75\xa9\xd6EuZ\xd3\xe9>\x8d\x1e\xaa\x8c\xb5$\xd3\x82D\x1f\xabA\x8c\xe4\x19Is\xb5\xb2\xbf^\xe5z\xa2\x0e\x0c&\xdf\xda\xae\xe8\xaf\x1d\x8am\x88\x197\x91,\x1b\x1f)\xa4W\x9a\xd8\xed+E3\xb0F5\x18\x82n G9T@\xa2\x89\xd2\xdc\x8c\x19\xd5\xa0\x81n\x06\xa7 #\xca\x01(\x92\xad@W\xda\xfc\xe9*\xd1\x11U\xaa\x03\xd0\xf1\xa7/\xe8\xd8\xb8.\x89\x8eL\x9f\xfd\x99\xa3\xe3\xab\xabD\xc7$-\x07 \xa3\x01\xad>\xbf#\x11\x0d\x14Wv\x02\xbe\xba\xec XW\xff\xba\x94 \xa0\xaf\x08\x0e\xe2\xb4\xd0\x94K}\xef\xec\xe0G\x98\x19\xfd\x08\x99\xe1\xee\xba9Pe\xca\xcc\x90\x99\xd4M*\xe2O\xa41\xe4\x99*\x86^z\x971\xa8\xdc\xbc\xac\xdc\xc6\xa0\xf2\xf42\xbbR\x01W\xe1G\x83E\xffd&\xf4\xb7^\x94\x84\xe4\xfc\xc5\xc2\x95\xa4\x12j^\xa6\xd8\xa0%\xcf\xeci\xe1\xfa\x03\xdci\xac\x1c\xe0\xd6\x03\xdcw\xcc&y(p\xe7\xb1\xd2u\xc4\x81h\x02?\x83C\xd8R\xd2~\xb98\x17\xd8\xc5\xbb\x02\xe0\n\"l`wg\x06`\xedo/\x13\xe0d\xd5GK;3\xe8\xe7C\x1b\x9d\x0b\xb5\xeb\x82!\xc4\xaf\xf6L\xf0\xe1\x9bC\xd8\x18\xc8L\xbf\xc2\xd3\x89\xe7yo\xb5#pN\x9c1\xac\x85\xdem\xbd\x9b\xae\x1b:\xfa\xeef\x90\xa9Y\xdf\x0d\xd6:o\xa8\xcc\xb5:\xbd7\x98q\xc1\x18\x97\x05\x95\xe2\xb96\xe2\x98\xfbF\x8f\xd0\x7fX\xaa\xab)\xec\xcf~l\xb4R\nX\xceB\xc9+\x1d\x8aK\x91\xcb\x8a=\xaad\xce\x0c\x1e\xee\x1ej+\x0c\xfb\x1a\x13&m\xa9B\xa9K\xc5\x1b\xb6v\xa3\xa0\xda6C4\x11\x01=\xd4\xfc\x12\xe9\x8c\xc1>\xa51\xb4\xa4\xd8\x80K\xb1V\x078\x0bvN\xb4\x9ex\xd0\x10f\x0d\\\x87\x9dh\x0e\xb5\xe8\xeb\x1bU\x1fcpZ\xf17\xad\xe7\xbd\xbb\x1dy\x14o}\xb6\xb1mr\xc93UI\x9e\x91J\xf2\xf4U\x92\xe7F%y\x16*\xc9S]\xad \xeb\xc5qRy\xd4\xcd\xea0\x9c\xe9\xfe\xe7\"\x80\xde\x9d\xd3\xff]?\x19TR\x14\xa1/\xf4)e\xd0\xf4\x03\xc8\xa0;\xe6\xf8\x87\xeb\"\x83\xdaH\x89\xc9@i5\xddAZ5\xcb\x8a\xfe0Yqc+\xda\x16\x18D\xdb\x0d\x15\xd1{\x03\xb0d\xc4{\xe8\x9f\\E\xa4\x18J\x07\xa0\x06S\x9f\x0d$n\xc4yP\x81\xce\xc2K\x8d\x83/\xd2|\xedk\x95\xb6\xc0\xb7#\x7f\xe1|m\x94\xaa\xb654F\xaa\x1a\xc0\xd7\xd2 \x15\x9f\xfec\xc8\xa7\xb1\x1c\x1c|\x03\\\xa8d\xe1vKR\xd6\x0bG\xf7\xb6\xfeE\x94,\xafL\xf2\xc6\xa9\x19C%\x81\xf3\x95\xb8\x02\x11\x9cw\xf1\xa7\xb4\xdc\xb9\x97\x17\xde\xca/\xcc-\xe9\xe7\xeb\x14\x8fe\x18\x83i.)Y<_\xc7\xe8\xfa\xb7\xfa\x0f\xd9\x13vS\x07;m\x0c\xe3\x84\x83\x81\xf1h\xae\xbd\xf3?\xff\x8f\xfe\xcf\xc1\x14\xe2\xce\x0c\x9c1\x1c\x97y\x94,\xddT\xe7M\xdaL\x94T!\xe8Vw\xe6\x9e\x99&\x83K\xaa[\x03\xa7\xdf\xf2II4=\xbc\x9c\xc2\xcb\\\xfa\xeb:(\xbc\xc6Pz\xe2}I <}\x86\xa7k\x91\xe0I\x14Qj\x8d\xc3&\xd3\x13?\x1e\xfa\xd8\x92T\x8f\x7f\xf6%*\xd9\xb4z\x8c\x87\xc0\x15ef\xe2{\xb2\x97\x0d\xc9*\x05S\xd9\xd9yI3W\x92\x1c\xf9\xa2k\x80|}<\x8be:\xd5\x94?\xe8\xe9T#\xfe\xa0\xa7S\xf5\xf9\x83\x9eNu\xc3\x1f\xf4t\xaa\x05\x7f\xd0B\xf2X\x8d\xe4\xf1\xc7G\xf2\xe0\x8a\xb2\x14\xa5*\x05f\xcf\xbbF\xa6\xc0\xcc\x87+0\x95Y\x8a6R\xc5edR\\~\xb2,Ei\xf2:\xbfH7%\xa6\xdfV\x03'\x1c\xf8\x91\x9f\x04$6\x00\xe7\xcc\xab%\xf1\xe71 \xb5\x01\xfe\x86\xba\xdd\xea\xb3\xb1U\xa8<\xbf\x98\xa4\x1buT\xb7\xb6R\xfb|S\x96\xf6Y\xd1\x9dy\x99\x00o\xef\xf4\x94\xfe\x11\xe0\x84\xd8\x147\x97\x1f\xcb\x94\x0fd\x93\x8aa]\x1f\xaa\x9f6\x1dT\xd4\xfc\x1b\x83\xf3:\xbf\x80\xa8\x84tS\x82\xccdfp\xdd\xd4\x17\xf7\xaeX#V\x12\xaak?i\xe1\xe7\x0c\x9e\xf0\x1d\xd0\xa8\x86\xd6\x01o`\xa8\x19\x9c\xe3\xe8\x0c\xf6jc!&\xc8\xa8\x0f\x95\xebYp\xfc\xcb\xa1\xf2\xe5P\xb9\xbe\x87\xca\xfc\"\xf3\x0bC\x91\x16\xe2E\xc5\xf1\x99\xbf\\\x92\xfc\xc0t\x94\xb0\\?\x1a\x12\x86P~\\\xa4\xc7\xab\xf4L{\xe2\x94\xba\xc3\xa0\x19XP\x8f\xd6\x0bVQ\x1c\xe6$A\xa1\x0e\xcb\xfc\x98?bG\xa6\xb7$/\xa24\x99d\xb9\xbf\\\xfb\xca\x13,\x1d\x7f\x88\xe6NO\xd7\xa4(\xfc%\x01\xc5\xfd\xc9\xc4_\xcf\xa3\xe5&\xdd\xa8\x0b~X\xcd\xa5\x12hu\xab\x0e\x0ey\x83\xb4\x18\xca\x14\x18\xc6\xe2\n@]\xea\x06\x13\xc7\xa8>\x94\x99\xdb\n\xd2\x90\xd4\xad\x15\x0c\xf5X\"V? \xa9\xa4a\xf9j\x9a\x91\xc4\xcf\"\xf6\xea\"\"qXP6 IK\x98\x13\xc8rR\x90\xa4\xc4\x8a\xd4+\x02\x85\xbf&\xc0\xf1\x1c\xd2\x1c^d$\xf9\xee\xe5\xd3\xc6\xb8\xeeY\x8e\xdc9\xdedY\x9a\x97$\x14\x0b*z\xe7\xe7d\xc0\xf8\xf8\xd4\xa0\xf0\xf57\xe7\xc0\xdbw\xfeV\xcdR\xb9J\x0b\x02\xe5\xca/a\xed\x97\xc1j\xc0g\xf9\xb4\xcd\xe0\x96\xb7\xef%l\xf6\xdcE\x9a\x039\xf7\xd7YL\xc6\xbb~k\x1f\xbf5\xf2\x1c\x11\xd3BI\xb0\xc5\x16\xd5\xee\xf3\x0f\xb0\xdf\xae\xdf\xf6^GE\x11%\xcb\xcfgs;\xafWt\x87\xa5\xdb($a\xe3u\x08SR`\xad\xdd\"#A\xb4\xb8\x00\x9f\x1eoQg'X\xef$\xbe#\xa3$\x8c\x02\xbf$\xd5\xd7$\x1b\xb9\xdd\x00|\xd9\x83\x97\x11\x10Z5I\xed\x85\x04q\xf2\xcb<\x0e\xc5\xa6\x96=c|\xca\xe7\xc7\xfd_c\xd5\xe5\xe0\xdc\xf4l\x97\x0c\xd48\xae\xfd8\xae0Q \x96\xe5\xf2\x9cm\x12\x9a\xd9u\xb7\x03\x07\x13\xb6\xe3\x7f\xafY\x92v\x8a\xa0\x8f \xc9\x9eE\xc9\xbb\xcf]\xbd\xdd\x18\x87\x0d\xb2pq]\xa9\xde\x96F/1\xe1\xa0$\xe7\xe50$\xf3\x8d\xb8\x93\xa4\xa8\xe1\x96\x88V\xb5N\x05\x1e\x1a<5\xa11\xd9^\x96\x93-I\xca\xc7\xacG\xae\x84\x92*\xf3\x9b\xae\xb0\xa2[\x89\x15\xddn\xb2\xf4N\x0c\xb4\x8b\xd9&=>\xdbT\xe9g\xa9n\x1f\xe3j\xf7\x1d\x89)\xb6\xb9\xb8+F\xacLk\x0b\xa1s=B\xe7\xed\x19\x94O\x86R\x8a\xe6k\x1b\xd9\xb0RJ UU\xc1\xf3u\x9c\x143pVe\x99\xcdn\xde<;;\xf3\xcenyi\xbe\xbcy\xb0\xbf\xbf\x7f\x13_\x93\xbf\xf4\xcf8J\xdeI\xdf\x9c>x\xf0\xe0&\x16 \x94\xbc\xabM\xf0\x93\xa5\x05rc3p\xfcy\x91\xc6\x1be\xf9{^\x05QQ\xbcF\x94?\xdc\xef\xa3\x7f\x17\x99\xd5\xd3J\x16\x85\xc5\xbc^\xac\xe7i,\x9d\xdamD\xce\xbeO\xcfg\xe0\xec\xc3>\x1c\xd0\xff\x93\x0c\x06\x0bNm\x928\x0d\xdeu\xd3\xd3\xe9z\x97\xb1<\xe0\x12\xa4\x9b\x81\xf3|z\xc7\xbb\x0f\xf7\x7f\x98\xde\xfe\xf9\x8ew\xf7\xd1\xf46\x1cx\xf7\xf6o\xc1\xf4\xc0\xbb{\xf7\x0eLa\xba\x0fS\xb8\xe7\xdd\xbau\x1b\xa6p\x97?\xbd\x0bw\xbc\xbb?\xdf]\x1dl'\xde\xfd\xfd\xe9\xa3\xfbp\xcb\xbbw\xe76\xdc\xf7\xee=\xb8\x07\xb7\xe8K\xb7\x82\xa9w\xb0\x7f\x8b\x0e\x07\xf0\xd9\x01\x1cx\xd3\x07\x0f~\xbe\xff\xc3\xed`\xe2\xdd\xb9s\x0b\xf6'S\xf0\xee\xde\xbe;\x99\xc2\x14\x1fM\xef\x05\xfb\xe0\xdd\xb9\xfd\xc0\xbb}p\x9f\xde\xbb\xf5\xc0{p\x87>\xbd\xb5\x7f/\xa60\xf7\xbc[\xf7\xef=\xba\xe3\xdd\xbdw\x00\xd3\xfb\xde\xfd\xbbS\xb8\xeb\xdd\xb9\x03\xd3\x07p\xcf\x9b\xc2\xf4\xc1\xea\x8ew?\xa0\x9f\x80}\x98\xd2\xcfL\xe8W`J\xbf3\xa9>swB\xbf\x13xw\x0enO\xbc\xe9\xdd{\xde\x83;\xb7&\xde\xbd;\xec\x07m\xee\xee\xcf\x0fh\x97\x1eM\xef\xc1}\xdaG\x98\xde\xf5n\xdd9\x80\xfb\xc0&\xec\xdf\x9d\xf9\x1f\x8d>\xf8\xca_\x9bu\xff\x93\xac\xe0\xf3\xe9\x01\xdc\xff\xe1\xfe\xcfw\x10l\x10\n\x7f\x82\xd5\x97\xe4\xb9\xb8\xc4\xe2\xdf\xf6n\xdd\xbe\x0f\xd3\xdb\xde\xfd\xdb\x0f\x82\x89w\xfb\xee\x03\xfa\xff\x93\xa9wp ~\xdd}p\x0f\xf6\x9fQ4\x98z\xf7\xa7\x0f\xe2\xc9\x81w\xf7\xce\x94\n`\x07\xdaW\xf0Q\xe3\x1f\x04\xa0\x98B\x1f\xc7\x07\xde\xbd;\xf7'\xb7\xbc\xe9\x9d \xfd\xf9\x00\x7f\x1e\x04\xb2\x97\xee\x8b\x97\xaa\xdb\x80\xb7\xc5\xcf\xaa\x83\xf7\xbd\xe9\xfd[1vor\xcb\xdb\xbf5\x0dto\x80\xe8z\xf5\x9ca\x1a\xed\x1d\xf6\x89b\xc2\xf4\x0e]k\xf1;P\xbe\xf2)0AY,\xf7\x12\xf8p\xcb;\xb8\x03\xd3\xfdgw\xbd\xe9\xfe\x038\xf0\xee\xdc\x0f&\xde\xc1\xdd\xfb\x13\xef\xe0\x1e\xffqo\x1f\x17\xf7\xc1\xbd\x07\xe2\x81wo\x7f\x8a\xff}p\xf7\x01\xec\xc7\xf7\xbc\xfb\xb7\xe0\x9e\xf7`\xff~@!\xbc\x83{S\xfc\xef\xbd}:[\xf4\xc5x\xd2\x80\x99\x08 \xfa\xe9)\xb6\x83\xdf\x11\xed\xd2\x15\xec4\xfcL\xf4\xf3\xd3\xce\xfa\xa4\x1fyy\x89\xa9\xbf\xe7\xdd\x9e\xde\x07\x9c\xf8\xc0;\xb8w0\x11\x93\xc6~<\xb8\xf7\x00\xf6\x0b\x9c\xcc{\xfbS\x9c\xc8\xbb8\x91\x0f\xf6\xef\x03\x9d\xce\x00\x97@\xcc\x14\xfb\x81/q\xa0I\x05\xd4XQ\xfc\x14N8[\x81~\x93\xb8\xf3\xe9t\xc7\xd8\xc1\xc9=oz{\xfa\x81\xe6\xfd6\x1c\xdcV\xcd;/\xcbqe\xd3\xfd\x00\xeemo\xffp\xc7\xbb\x7f+\xbe\xe5!)\xba\xf3\xe0\xd9}\xb8\x1bO\xee\x02\xfb\xdf\xd4\xbb=\x9d\xd0\x7f\x9eQ(\x98\xde\xfa\xe1`\xfa\xf3\xbdO0t\x16\xf1~e#\xdf\x87\xe9\xfd\xd5\xed\xed\xe4`5\xb9\xbd=\xf8\xf7\xf3[pw{\xb0\x9a\xde\xff\xf9\xee\x0f\xb7\xfe\xbd\xbe\x05\xf7V\xd3\x83\xed\xe4\xe0\x87\xbb\xdb\xff\x8f\xbdw[r\xe4F\x16\x04\xdf\xfb+\x90l\x9d*\xb2x\xc9d\xd6E\x123\xb3\xb2\xd5j\xe9\xb4\xd6T\xdd2\xa9\xfa\xcc\xce\x90\xacj0\x08\x92\xa1\x8c\x9b\x10\x08ff 5\xd6\x0fk\xfb\x03\xbb\x0f;f\xbb/\xfb0k\xf3\xb2f\xfb\x0b\xf3)\xfd%kp\x07\x107D0\x98U\xea\xd3\xe7LS\xb2\xca\x08\x04.\x0e\xc0\xe1\xeep8\xdc\xcf\xeb\x9d\x1d|\x1c\xc5\x84Q\x18D\xfd\xf3O\x07\x13\x9a\xa6\xfe6\xaa\x9f+G\xfd\xe9\xd9Y\xd5\xa6\xd47\x1f\x9e9\xce\x95\xd5\x87\xe9s\xc7\xb9\xb2\xfa\xf0\xb4\xbaCK\xf1\xc3\xf3j\x13\x81\xf3F\xa5\xdd\x9b\xa9\xba\x9e}\xee0u\xdddA\x80\x9f\x9f\xbb\x82\xedxq\x18\xc6QH\xf9\x8d\xce4\xad\x1c\xc5\xba\xd4$\x9ekP\xd5\x0f\xce\x10R\xee\x91+\xf5\x19\xdeX\x04\xd1\xbb\xf5[\x0c\xd7\x95\xd0}\x8b~\xd6_D|\xc3\xe0\xc3|\xa9S\xfc(\xf0#\xf6*^3rEN\xa6\xa5T<\x0d\x85G\x9d\xbeR\"(\x1e\xba\xaa'\x9d\x8aJv\x86\xa7\xa7\xe6\xc5\xb4x\x9f\xc4[N\x93\x9d\xfe\\x/\xa0S\xbd\xf7\x1b\xe7-\xa9^\n\xe6y=rrE\xc4}\xc2\xe2\x0d\xea\x8c\xfa\xa0\xb1\x19\xc1\xc1qOOWoP\xedL\xc4nIV\xe9\x89J\xa3:\xcd\x8b\xb9\xc9\xe6\xd7\xbb\xa6\x92c\x93\x9c\x056-\xad\x8d\xba\xbd\x1e\xef\xc1\xd5\xc9\x8c\xb3~0gK\x03O\xcaD\x1f\xae\x1e\xfe\xfc\xbe\xba\xa4`\x08r\xf3\x11\x95\xb5UY\xc5\xfb\xc5\xa6G\x84\x15*\x1c\x95j\xb2\xa0tR~\xa9Z\xcb\xfa+\xb80\xc9\x06D\xecx|\x0b\xfd\xfe\x8a\xf3\x98\xf7{\xff\x81\xc7\xd1\x96\xfc\x993\x85\xdet\x15\xb0?\xe3\xa1\xa4\x18\x11o\xc7\xbc\x1b\xb8\x9c\x7f\xea\xa1\x13\x8e\xea\xbd0\x8b\x9f\x18\xabF\x8d\x8cM\x1a\x8c\x88\x02[\xab\xe7!\x87V\xe4\xdc\xb0\xfb\xb4_\xfc6\x98lb\xfe\x15\xf5v\xb9-{m\xd5`sy\x99y\xb4\x84i\xc4\xa6\xcd\x1b\xd7Z\xbf\xbe3+\xc4\xd2\xaa\x10\xc6\xa6\x01W\xd4\xef\x8a\xb4\xde\xf93\x8a\xb8\x82\xc1\x87zj\xaa1\xa1\xfcp\x9dj\x06#\x8d\x99\x9e\xae\x18\xf29\xd5\x91\x16\xedU3\x1eK\xd3~4\x18\x91H\xd3\x89&@\xf4\xa1Z\xb7\xde\x01:!\xb6W\xd6\x94~@\x14\x86\xcea=\xe5\xf5\xa4RZG\xe4\x1b\xb3\xbc?\xe2\xb8D\x15\xbax6\xfa\xa0\xa1\xea\x06\xe2\x03\x06\x0c+\xee2l\xe0\xf7+\xe6B\xd1\xa7M\xe1u\x92 ?H\x0dC\xfe\x15\xf9(|\xbd\x81\xa1?u\x1e\x07\xf85%\xa6%\xb1)D\xfeE!\x01\x9c\x8e\xc4\xa6\x97[&~\xcb\x19U\x14<\xb6/\x0ebZ\xec\xb6\xaf$\xa7nS\xe3\xe0\xba\x9b\x98\x93\xbe\xe9e\x0e\xe1Hk\xfc\x03\x16m\xc5n\x04B\xca\xd9\x08D\x92^\xef\x82\xc4\xe3\xf1\xc5\x80P2\xbc\"|\xce\xe6\xfeR1@\xb6T\x8d\xf8\xc3!\xb6\x84]r#\"-\xcea\x1d\xfa\x8f\x0b\xf7x\x9a\x03>\x1c\xfa\xe4\x92\xc4\x17\x03\xd2\xc3\xa5\x80\x8e\xf3m\x17\xc85\xf6\xaa\x80\xa0\x06\x19U\x16s\x0ej`\x9a5\x8c\xc1Q#\xf0\x91\xb0s\xb2\xa3\xa9\x0bC\xd5\xa7,b\xa9G\x13\xf6j\xed\x92=U\x0e\xce\x92\x80z\xec\xabH\xf8\xc2g\xa9K\x12U\xd9\xb0\x9a\xdf\x8b0\xa8\x8b\xa4?\x17\xb4\xfa\x19J\"?e\xb1`o!\xa6\xd5a\xed~\xef2/\xf3rQ\xd8\x88\xbe\x1f\x95\xeb\x03\x95QG\xb2\xd3\xbb<-\xd4\xda#C\x92b\xf6r\xed\x1eR\xc4.5\xb2\xb9Xj9\xeb\x9a\xf4.\x13\xce^^\xaa\xe2P9\xed\xc3g-\x17\xc0u\xe6\xcbS\xf8zy\xaar\x16\x00 3\xd2\xebR\xb02\x0e\x1b\x16y\xae\x85=R2`\xe0\xe2\x0f\xdeH\x91F\x08\x1d;\x17\x8ekjkX\x1b\x8e\xc305\xeb\x93\x80F\xdb\xef8\xdb\xf8wu\xc9)Q\xe4\x9a\x86\xa9K(Q\xdf\xc1\xc9\x0c\xf8\x9f\xd1\x19'i\x12\xf8\xa2\x7f\xbaH\x87\xa7\xdb\xc1@\x87\xf2\x86H\xde\xbc\x1f\xe0\x12\xc6\x1e\xbe\xf5\xb2T\xc4\xe1\x88x\xf3\xb3\xe5\xc0\xfa\xb1p\xe5\x99\xab,\xcb\xca8\xd4\xed\x17U7\x1f\xe3\xd1\xe3U\xef1\x19\x92\x1d\x0c\xbb\xdf\x8f\xfb\x9b\xc1@\x8d\xf8\xe3\xde\xe3R)\xa7)ia\xc6\xd5\xbc\xad\xd5L\xc1\x0c\xf6\xa3\xc9\xce\xdf\xee\x02\x88p\xf4\xe8\x11)\xbcj\xc3\xd5B\xca\x88\xcc\x133\xd90\xeb\x1e\x15}o\x80n)\xfa\xf6\xd3\xa0\x15\x83\x1c\x88\xa1\x87DK\xeb\xd9d\xc7\xe8\xda\x8f\xb6\xb5%\xd8\xbabv\xaa\x0d@\xc7\xdd\xb7l\xcf\x02\xecb\xb95S\xf1\x91k\xd1Yum\xad\xef\xbap\x00c\xda\x1bM\xeev\"\x0c\xfe\x98\xc1\xb1\xed\xe5\x8e\x93\xd3\x97=X\\;\xfe\x12<\n8\x87k\x95\x05\x01\x13o\x03?\x15\xdd T\x168\x08S\xa1\xa2#G#\x0b\x9a\xa7\x13\xea\xf3\x05\x0b\xbbC\x17\xf8\xd5Y\xca+\xa9A\xd6\x0cU\xe0\xd7;\x19s%\xaa\xad\xdd\xc3\xd5&\x98\xaa\xb9v2\xc0\xdee\x1c\xe8e\x03\x95\x93\x97dJ\xae\xc9c\x92\n\xca\x05\xaeP\xf3 \x96&FTu#L \xbc#'!n\x99\x04E\xb5`[\xdf\xa9\xcfE\x06!\x80\x0c\\\x93\x1e\xa2bR\x9d\x99\xbc\xe6N\xe0\x9a\xe1<\xe9\x17jW;\xe659\x07\xe1\xf1%\x05\x1b\x10\x03\x07R*\xce6\x06\x06\x0c\xf3\x15\xbb(\"\x8c\xc1\x11\xcb\x8cV+\xf0C\xba\xed\"\xb2\x9b\x01|LR\xee\x95 M\xb9\xa7\x01\xad\x8fS\xf6\xd0!oX\xbd~\xb85Q\xcf\xfa\x8f \x0d\xf4hc-4P\xf3\x80\xcc\xd5$\xa0]1.\xe1\xc7\xbd\xc7\xeaO\x86\xeb\xbfH\xbf\xc9i\xaf\xb0\xd0+#\x04\x11D\xbb\xd3C\xc8^'\x16X\xcb\x113\xd5T\x8f\xe2\x81G@\xa3\xb27\xd5r\x0c4\x0d\xf5\xac\xe2\xf5\xfd\x11\xd0\xa8\xecM\xb5\x1c\x03MC=\xfc\x08Pxm\x9e\xf9Q p\xd7\xa8v\xa2\xd8\x1d\xb8\x94\xd8i.E\x03\x7f\x1bi\x0eu\xaf\xd6\x8d`wb\x0c\xa93\xa43\x98\xa3\xca\xac\xea\x90\x1d\xd3\xb7]\xad|\x1d\xe5\x1e\xda\xb3\xf5G\xee\xd9qh\xbc\xae\x96O\x05\x8f\x1d\xa2jc\x15\x98\xbf\xa1\x96# q\xd7s\x8c\xe0\xc5BG\xe9# \xa8\x97_\xb3\xa0{\xf3k\x16\xb8\xca\x1f\x01\x80\xa3\x06?J\xbbC\xe0G\xa9\xab\xfc\x11\x108j\x08)\xaf\x0b\x15\x8d5\xa8\xdc\xce\x1a\x8e\x00\xc2UG\x9a\xad\x0e\xad\xb5\x1c#\xb3U\xf3f\x1e>V\xebN\x8e\xa8;i\xab\xbb&`\xee(_\xaf\xb4.\xf1\x90D\xa1\x1b\xa9\xec\xa4Vj'\xb5\x88P\x12\\9\x88l\x1ao\xc4\xd1M@\x81\x94\\whM=\xd6);\xbb\x13\x1d\x07\xad2T\x95\xf1\x11a`N\xcb\xbaTV\xac\xaa^\x93\xa0\xdb\x0f\xae\x87\xaeVu\xae\xd9R\xd3\xe3KU\xe2\xa0\x14\xf7\xf2\xb1\xa3\x99#\x16\x85\xca_SB\xc5\xb1\x88b\xc1\xder\xb69\x04\xad\xe1D\x7f\xc8\xc2\x15\xe3\x08\x9f\xbf&C2\x1dLD\xac\x1d\x938N\x97\x95\x88\xdb\xdbD\x9cm\xc0\x10\xdb\xc9\xc4P\xea\xcdV\xdf\xac\xc9Kr\x06G\xa6\x9c\x0c\xafHof\xf5\x0c\xf0u0\"\x8f\xd5\n2\xea\x1f\x03\xffX\xd5\xfe\xd2\n\xfd\xbf\xdeD\x8fuL\xdf\xc7=\xe2\xaf\xaf\xac\xc4\xff\xb8\xf7rn>\xf5\x96Jxw.:;.\x80Y]wD\xba3eI\xf8\xf1\xe5\x8eW\xc1M\xc7)Kz\xb0N\x14\x1fn\xce\xa22\xc0\xec_\xa6\x0c\x9a\xaeeSY.\xe3\xa0^\\m\xa1\xa1|k\xcf\x8e\xc0\x9f8PM\x9dj@\xeaT\xc4\xd6|\x14\xea\x07>\xcc\x0fNX;j\xe1l\xd6\xa6\xde\x17,\xac-\x0e\x0b\xcc\x11\x1dt\xe9Kl=4\xf2v\xf1\xc1CE\xb3Fr|o\xefR\xd7\xc5\x105-\x06\x92\xe3|\x01\xe3\xabC\xb4\xa2\xde\x0d\xac\x90\xbf\xfe\xaf\xffM\xe1|e\xb0\xd6\xc7\xc8(\x0e\xcd\xd9\xfa\x08\xcd\xdbZ\xd4D\x9c#\xf6^\xeb\x9a\xb0\xb9>N>rC\x7fL\x0d\xc2Q\xc3Q\x02\xf3\xba\xb2\xe9+\x1f\x03\xa5\xe4\x8ad\xc5\xf3\xc3.\xcb\xa8_\xe4\xa4\x84\xf5]\xc4\xa9\x90}8\x8c\xc8\xcb+\"\xf4\xe9\x1a\x19\x93s\xc5\xc7\x15\x9b.+\xcaP\x13\x05\xd6\x07F\x0b\x85/FmU\xd2X\x89\xb9B\xbf\x82\xc6\xea\xac\x9c\xac\x99\xa5iU\x15\xafh\xcf\x8a\xf5\x9c\x97\xda\xd4 Z\xab\x85=Tip\xc5\xb9\xd4\xcf\xf78P\x03ri\x8f\x0f\xa1\xa9\x8a\n\xd5*\xd9\xecya\xaf.\xa7\xe4SS<\xa8\xcd \xf5\x03\x0f\xfa\xea\xc6]1\xb9\"\xf3\xda\x94\xcd{@\xa8{\xe8\xdb\xff\xec\xf9\xc0q\xf03\xef)\xden\xb2\xbcpg\xe1l\xc38\x8b<\x08\x13\x0f\x19?ug\xd4S\xaa3}\xe6\xced\xe9\xa2\xa0~`\xf2~\xde\x0c\xdc\xb9\xce3=k\x82\x0e\x8e-C\x16 \x03\xdft\xea\xce\x9a\x86\x94\x0b8\x06\xb49\xcf\xdd9\x03?\xba\xf17\xf7&\xd7\xd3\xc1\xb2\x94iy\xc4q\xbf\xc3z\xaahd\xc5\xcb\x84\xdc\x1ej+\x92pvA\x18\xb9$\xb1F\xc6\x0b\xc2\x86\xc3A\xa1\n\x8c$\x12\xcf\xd9r~\xb6\x1c\x11x\x98.]\xa6W\xc5\x03vm\xe5Q\"\x10.n\x84Gi.\xf8\x04\x9a\x02D\xe66X\x01\xa2-\x13\xdfg\x01K\xfb\xbd\xde``\xe1\x16\xe4\x92D\x17D(\xf0\xf9\\,\xfb\xac\xd1\x84\xe3\x03n\xc3\x95,A\x1a\xbb\xc6\x8a\x160\xd7\x84i;\x17\x1c\xcb:\xe1SC6\xb3\xd4\xcae\x01\xa9\x830\xb1I\xca=s\x88\xde?]D\xa7[\xbc\xf6:\x11\xdc\x0f]\xe2m\xc0\xf6,p\xde\xdeRm\xa532?\x1b\x91\xa9\x03?\xf3\xbb\xd8\xf32^\x82CWm\xc2h\x0c\x8f\x14X\xa3\xa2\xbd$\x9b\xb0h?\xb2\x1d\xff\xd8\xc6\xafO\xab\xb6\xaa\xdaJ\xe6y\x93\x91\x0c3\xa7\xb6\xbe\x0b\x0b)\x9c\xe6\xa6#\x12\x8c\xe0\x18\xbb~\x04\xfd\xec\x9c\x9c(\x82<\xf1v\x94\x7f\x19\xaf\xd9\x17\xa2\x7f\x96\x9f\x17\x8f\xa7\xf5\"\x9fO\xebE\xa6\xedE\xb4G}f\x1d\xe4\xf7\x96\xb3^{\x11j\x96x\xa1\x8b#2_\x0eF\xa4\x9f\xc1\xd5b:\"S\xe07gDJ\xf2\xfc\xb3:T\x19\xc8}\x8d\xcd\xc0r\x0c\xc8\x15\xa1\x93$N_\xd1\xbb\x11\x8a\x01\x8a\xc1]\x90\x94\\\x92@\xb1\xb0\xe9\x19\xd4L\x01E\x0b\xb5\xa7\x83\x0b\x92\x0e\x87naR\x873\x0c|\x8f\xf5\xcfG$\x1b\x8c4[\x86C}\xf3\x05\x9a\x1a\x91\xd4\xa0\xb9Y\xf4\xe4\x9a\x8c\xa7dF\xfa>l7\xd9\xde\xa7H\x07\xa5\xac\xa7)\xda8\x18\xe9;\xd8\xd0F%\xc7\x1c%Xo 2m\xe3\xc7+\xb2\x19(X\x1c\x14\xb0\x1bq(\xd0=\xf0'\x82Q=p\xa1\xb8\xccF\x0b\xb4\xa4~\xc9\xd8\xd2\xca)\xd2J\x9aKM\xd3\x12M\xac\x954\x0d8\x85*Z=\xde+\x89R\xd4\xca%\x8dR\x92\xaa\xc0J[.a\xcf\xfc\xa0\x03jY\xd3\x82\xc6\xe2\x82\xf0\x82pt\xd2\xef\xab\xf5\xed\xf7\xf9\xa8`R]\xa56\x88\xe3\x83\x8b\x01\x10 \xaeQ'68S\xb7\xd40\xbfb\xc3\xaa\xe4(o\\\xe1Q>\x14 \xde\xa1=c\xde=\x9bx\xc8[\xef/N\xf9\\6W\xcf\xa6U{B\xaa\xd3\xab\x86\xf8h\xed\xff\xec\xfc\xccIA\xd3\x9c\xbc\xd4\xccp\x14t\x9apB\xe4\x80\xf5\x88\xecFd?\"\xe1\x88l\xbb\xd1\xc5\x03\xa4\xf4\x01t1\xa8\xd3\xc5\xd4\xd0E\x0f\xe8b0\"g\xedt\xd1\xeb@\x17\x13rE\x02K\x17\x15\xd1\xf2\x90.n\xc8%\xc6p\xe8?=G\x8a\xb6\x86\xac\x15\xea\xb8Ac\x9c)R\xa4\xf5\xe0\x82lj\xb4\x12\xc8\x80\xaf\x00\xde\x1c\x80f\x0fM(\xc1R\xc7m\x1ca\xfc)\x03\xa4\x82px\xa5(\xc3G\x04\x0fZ\xb6\xf5\xed`\x1c7\xea\x91\"\xc8\xe4\x9a\xf4\xc3:`\x16(%O@\x86^\x0fSw\x83\x02|\x1a<\x07d\x17\x03\x05\x8c\x93\xad\xd8\xd2\x9a)9J[\xde\xb1U\xbc\xacoX\xcdtD\xbcA\x99M\xa4\x93|s2\xdf\"w\xa8\xa6\xb9.\xbe\xe8\xb8\x9c\xa1\xc3\xe4\x0d\xfc?\xecK\xe9\x8a7m>\x1eS\xf1[\x99\n\x10\xccB\x17\xb4\xc7\x8eR\x92\xb6\xa1>\x92\xff\xf8\xc7\xf3\x9f\"g\xf1\x1b8K\xce\x99\xfc\x1agr\xf2\x1f\xffh\xfe\xe3\x1f\xe2?\xe9/\xc4\x7f\xfcv\xfe\xe3\xbb\xf8\x8f\xff7\xe5?\x0fA\xc1F\xfc\x83\x01\x8fpw\x07n>\xec\x0e.\"\x97\x84_\x90H\xed\xe0JX\x01\x08\x16\xcf\xa3\xe5\xc0\xce\xba\x99\x07\xbd\x03\x11f\x00]\xbb\x10\x91{\x8b\xfb\xd7\x1a\x0d\x90\xcaK\xdb\x0c\x18\x80\xfar\xc2{d\xb5\xf4\xa4b\xf8LJ\x0b\xd9\xaa\xd5\x816\xb1\xfc\xa2\x9a\xddx\xd6B}\xb5\xe8\xdfz\xc5c\x17\xa4\x06\x85\xf5\xc7\x8cB\n$t\x85\x8b\xe6F\x1cF2\x0f\xe8\x8a\x05#r2\x053\x1cGUE\xfdV\xb9\xae\xe9\x88$Z\xce\x0e\x14IMM5}`'z\xfb\xcc\x06#r\xb2\xa9^$\xd2\x93\x9d\x0f\x05\x18%\x0e\\\xdd\x04\x04\xa4\x96\xe4\x95K\x8c\x0en\xd6I\xbeaw\x9c\xc348Q\xd1\xdbpo8\xac}\x06/Q\xb9\xb2\x83:\x15\x1an0\xa0']\xe0%\x0e\x98[\xa0%\xfa\nmK\x90\xc3\x96\x0e\x11\xdd)\xdc% *^\x93>lG\xe7\xcbAG8+\xb4\xbf\x19\x12\x81\x0eh\xda\x82\xcdv\x006\xeb\x08V\xa3\x8e\xc6\xfc\xac\xae\xc6eEh~\x06\xa0\x96j\xac\xfa\xa50\x8c\x1f\x0c}\x95U~\x8cQ\x1d\x8f\xbd\x06\xb8\xe0\xe2\x8a\x82\x1eh\x02\xd0&\x886\xab\xd7x\xfei9\xc8\x97]\x91ji\x83\xf5l\x80\xf2\x8c\x9b\xd3\x9b\xdcs[,\x97@\xac\xf6<_$q\xd2\xcf\x03\xbe\xc4\xf9\xbe3\x8b\x04\x9cg]\x17\x13fJ\xac\xe1\xa8%\xe5p\xa3\x87p\xb5\x1c\x1f\xba\xe6\xf0\x98\xee\xe1\xab\x0e\x0e\xd6Z\xc3|\x1b\xccj\x98\x12\xb7\x14\xe2#G-\xf6\xc9\x1ft\xa3\x84\xc4\xd1\xcbC\xb8u\x10q\xea4\xb2\x96\xd2\x0567\x95n\x83\xae\x05\xb2\nT\x1f$W\xd9d\xbb\xbf\xe6\xcd^\xfdruo\x7f>\xee\x0f\x16\xf3\xc5\xf2\xe7\xf7\xc3\xeb'\x93O\x16o\xe4h\xf6\xeb\xcb\x93\xc5b9\x00E\xf0b\xf1\xc9\xb4\xf71\xf6\x10\x0ey\xa5\xb8\xbb\xef\xb0\xb7()\xcf\x1a\xb6\x0dy\xce\xef\xd9\xf6\xab\xbb\x04\xc4]\xb8&\xd4\x7f#\xe7=\x08\xd2\xb8\x88\xfa\x83\xf9\xf2\xf1\xa27\x19\x9d\\\x8f{\xfafO\xaf\x87\xc1\xb7\xb8\xb9\xdb\x83\xa6\x82\xcbA_\x95*_t\xaeC\xd31n\x97\x9d\x804[\xa5\x82\xf7\xa7\x0e\xbc\x1cL\xd2\x98w\x0cN\xaa\xeb+\x9ck\x9a\x13@W\xbd\xa5\xeeI\xec\xdf\xa0\xff\xc9\x03\xc7\xa5g\xe4\xa3\xc2h\xa3\x82\x04_\xfa\xeb\x11\xe9m{j\xe7\xbb\xb1\x92Q\x9e\x17E\x933$\x98\xbb\x92\xc0\x1e\xa3\xc0\xee\xa6+\xd5\xed\xdd\xce\x9c\xd5\xba\xf3\x93\xe2\x86\xb2\xafH>\x14\xb0\xd2{eo\xf9\x12\xe8\xb2\x18\x8f\x9bk#\x06\n\xc1\xee\x84\xdeLP\xbd\xd9\x1b\x1c\xdc\x1b\x9a\x9f\xd5\x80\x9f\x8d@OF\xf3\xdd\xc6f\x12\xd0T|\x13\xad\xd9\x1d~\xf7\xb4\x0c\xb7g\x81\x11\x8d/@|\xdfL\xd8\x1d\xf3\xfa\x19\xe8-\n\xa5^\xa2\xfa\xfc \x95-\xfe4e\x83N5\xd3\xd9\xe2\xcf\x8a%\x99\xde\x98\x06#\x92\xa0>\x8d\x0cI2\x9f.\xf5\xe0v\x08EG\x0e\xf1\x99\xe2\xef=\xb8q>\xbeo\xd6L\xadc\x07\xb5\xb6\xc5\xb1\xde\xb5\xb8\x91\xcc\xcf\x97\x1d\xa2\xe7\x91\xc3\xf2b\xf1\xf7\xd0\xee=d\xeaT\x0f\xba\x15\xf9\xdb\xcc\xce!>_\xfc\x1d\xe0\xf9\xc5\x9f\x82)\x80\x05\x93/\x921I\xe6O\x0d\x8a6\xabR\xcc/-ho\xfa\x01\xb9$Y!\xe1!\xfd}\xc8t\xd9\x95\xf6K,\xa9\x12aT\x04\x0d(\x8d\x91\x98}\xdd\xf4\xd9\x08\\\x1b\xa4#bR\x04\xea\xb4\xdb)\xe6\x07 7&\xd5\x1cZ\x9c.\x86c\xb9\x98,&rq\x8d\xff\xc9\x93\x93\x93\x139\x1a\xc9\xf1\xf8\xb4~\x98q\xba\xe8\xf7=)B\xc9e2X\x0cN\xb7~\xfd`\xa3>w\xde\x8c\xf4\xfe\xfb\x7fsL\x11W\x1f\xfe_\xc7\x87D}\xf8\x7f\x1c\x1fD8#\xbd\xbf\xfe/\xffw\xaf\xf4\xa5\xc1\xda\xa6\x8b4\x95\xcbQ.iIk\xab\x8a\xbe}\x1a\xe4\xa5\xd2\xde\xa8\xc8\nS\xcd\n\xd3&VXc\xc4v\xd3\x94v\xe7\xc7\x19)\x97;\xcc\x96I\x91\xed*,\xcd,\xdb\x85\x95 gQ9/U\xafx\xd0<\xc8Oz\xfa=<\xa3\xb9&\x01\x99\x91\xc0J\xc3\xf1\xa8\xdd\xf6\xac\xfa\xd3\xd2\x97?\x17\x13\x11\x7f\x1b\xdf2\xfe%MY\xbfbtS\xfc\xa9e\xc6'\x82\xa5\xa2O\x07\x16^Z0\xbf\x18\x8eA\xec\xfe\xef\xff_oPH\x9d\xfc|>z\x0f\x1f\xfe\xfa\x97\xffZ\xfc\xd2\x9f_\x9f,\x07\x7f\xfd\xcb\x7f\x85\x8f\x9fL'\x93\xfa\xd7\x9f\x9f\xe9\xb2\x9fL\xd5\x7f\xc5\x0c#[\xef\xa8T\xee\x8d\x9c\xbf\x19/\x07\xe3\xf1\xb8\xaf\x1e\xe4'\x83\xd3m\x085\xfc\xf5/\xff\xfb'\xe7\x95\xbc\x8bt0\x1e\xf7\x17i)\xdb\xffV\xcb6\x7f3^\xa4\xaa\xd2>>\xd5\xb3\x83\xff\x96\\mM?\x8an\xd5\x12\x8d\xf9\xe3\xde\xd2E\x1c }[\xa7\x08\xa7\xf3\xf1\"\xc5\xdd\xd1\xf2\xd4\xb5\xc3\xa2m\x16\x8a'}a\x0e\x02\x01\x7f\x8d`\x0e\xd3~\xe2#\x120\x85\xbc\x85N\xd6\xdb\xc8\x0e\x98^\xdb\xad\x04\xd0em\x10k\x13\x914WF\x91<\x80\xde\xf8\xceM\x9b=\x92\x1d\x91\xfb\x11Y\x8d\xc8\xdb\x11\xb9\xfd0\x82t\xab5\xbf\xab&\xc2\xb4\xd2\xc4`u.\xc5\x9a\xccFaK\xaer\x88a\xe8\xb60tx\xfct;\xdf\xea\x9c\xe4\xf2\x8al\x06\x17d;\x1e\xb7\x9c(\x99_a\x0c\xb6\n\xb9P\xae\xd2\x9b\x14\xd8_\xd9\x15<\xe8,[\xb1\x19v\xe1\x82(\xc1\xca\x03\xc2\x18\x97vAz\xe3\x13\xe3\x86\xc7\x1f\x0c.\xda\x87\xd9\xfc\xc0\xd7\x07\xb9\"'\xb4\xafPX\xefN\xc6d\xaa\x05\xc2\xd4\xeeW\xa6#rO\xaeH\xef1NL\n\xa6\x89\xa0:\xc0\xb2\x01\x1e[']\xe6\xc3\xfcT\xeb{U\xc3zDB\xf57\xe9\x06\xb5\xf9\xc1\xa0\xb4\xcdc_\xcd\x83\x9a\xcaQeJ\xc9f\xa0\xa7\xf4\xa8\x06\x89\x06z7I\xfdh\x1b0\x18\x8a{\xd5R\xa1r\x95\xb69f\x18\x8a\xbf\x1c\xe0{rM\xfao\xe7;\\j\xc5\xe3\xca\xcc\x91<\";\xb46\xc8\x89 Z\xc4\xce\xcf\x97\x15\xb6\x91\xf5\x0b\x02\x80\x9e`G\xb9\xa7K\xd0&\x7f\x0c\x10\xce\x1e\x08\xc2t\xa9X^qI\x1d^+\xae\x9fj\xca\x8f2V \xbe\xd1\xe5WW\x836\xfd\xf6\xe4\x9a\xdc\x1e\xb3\xcf1?\x18\xc5V\x1d\xb4\xeb\x97\xc4\xe9\xcc\x0e\xddQ%\x11ug\xc4\x11\x07\xbb\xed\xa7\xf7J\x9b\xce\x85\xc0j5T\x8b\x03VH\xff0\x02\xf4\xfe\xfa\x97\xff\xe2\x8a\xa0\xea\xfa\xbd',H\xd9G\xad\xfa\xa3\xee\xc1\xc0\xc0\xbc\xea\xf8\x15\xe4\xa9\xdb\xdb[\xf9\x1b\xb9\x98-N\x17\xa7N\xb9\xc9o\xd4L\x9f\xbe\xb9\\\x9c\xd2E\xfa\xe4\xe5\xa9\x91\x90\xda\xc5#Z3^7F\xe8s\x87^CX\x0b.7\x06\xab\xce&\xe82\xaa\xf9\x9c*\xe3\xc1\x8c\x9c4\xc4\xae`!\xf5[>\x8b[_\x08\xc6\x9b+\xd7\xf2\xf2\xd7Q!0g\xd3\xdd\x16\xf3Ko}\xe1\xed\x14\x92l\x99x}\x9f\xb0\xfeA\xa1\xc1\xa3)#\xbd\x8c\x07\xbd\xd9Add\xc7\xacy%\xb2\xccH4\x81\xc8dl\xfd\x9a\xddu\\\xf60\xaa\xd0\x83?\xf1\xc0\x11\xf9\xa6\xfak:w*\xfe\xe0\xc2n{6\x1c\x08\x98\xb5\xbf\xaf\xa1\xe8)\x90D\x0cjF\x18\x96\xafTB\xbf\xb0\xa3z\xa3s\x9c\xfa\xa3\x92[\x9b\xa6\x9f\xe3\x0c\xcc~j\xfcb63Sg\x8ez\xb9\xea\xb4\xe8\xf2\xf5\x11\x0b\xfc\xe8&\x9d\x11V\x1f\x12\x9a\x89X}U\xcb\xa4\x1c\x93\xda\x15L\xea\xd8\x8d\x0co:\x80*\xeee\n;\x80:|jg\x12eA\xab\xe2E\xdf\xc3i\xd8\xe3\x14,\x95\xee]\x96J\xce\xb1\xaemk\xee;\x1e|\x14\xb6+\xa0o\xb9\xffX\xe7\x1f\xb9\xdb\xa0\x1eXD\x822);\xea\x14\x04\xea\xd1\xb7\xd0\xb5\xdc\x9d\xabr\xb6 \x9f[Vw\xfa\xe6\x92\xce_.\xd2\xa5a\x0d\xdb\x01\x1a\x87\xea+\xa3\xbb\xf1xD\xfc~\x9a;\x18P\x89\xc3\xe1@\xc9\xc6\x90\x0bR\n\x9b\xaf\xbc\xad\x18k\xcc\xcbv\x01\x9e\xe8\x0e\xac\xe0\x90Q\xc9\xf9}\x85\x1b\x14.\x13(\xf4F\xa1\x7f5\xc91\xda\xee:l\xaf\xf6\xa5=e\x08\x05\xfb\x81\x82yo\x15\x06F\xbc;L\xf1\x88\x99tOo\xa3\xd7\xd0\x9a\xde\x11np\xc7\xba!\x97\xb6Y4\xbe\xcdM\xdf \xce%\x15\xec[\x05\xc6~\xbeYN2\x1e\xa0\xa6J\xdb%\x1b-\x1a|\xd4;T\xf5Y\xb5\xb4\x1e\x11\xef\x18\x12I\x1e\xa4\x0d'E\x8dx\x90\xab\xa5\x93\x8eJq\x92\x0b{\xebN\x05 \xb2\xc0C;f\x1d\x8c\x1d\xd1;m\xcc\xab\x87\xbf{9}`\xd5f&T\xfd\x99\x81\xe8p.E\xb4\x02\xf3\xa1#\xf1\xd0)\xb6\x98\xd6\xbd\xec\x91\xd3\xfb\xf0>\x15h\xe0\xd1\xd0\x8d\xc7\xdd\xe1\x0b\xd0\x92\x1eP=!\xc3|L\x0c\x91\xe8 \x0e\xa9_P8\xb4zh\x9f\x1f:\x8fG \xf2\xd1\xf3w_9\xbb\xcaJgWY\xf9\xec\xca\x1b\xd9\x834}vu\xb0\x9d\xf6m2\xee\xd5\x0eV\x82\xe7\x1e\xe3\xf1\x05pI\xadM9\xb9\xb2\x14\x9a\xe0\xadmC/\xe0Sf\xac\xd7/\x06\x8a-\xdb6:\xed\xe0\xf6:(\xe2\x88\xf89z\xc4\xfa\xe6+\x1a\xc0\xd9\xe2U\x8ew\xfa\xe4\xa4\xdc\xa1'\xe4\x0b\xcb\xc7&?\xa6\xd5\x8fg\x93\xe9\xf3\xc9\xd3Jj5\xd3\x97qr\xcf\xfd\xedN\xf4\xbd\x019?\x9b>'\xff\xcc\xd96\xe6\xf7\xe4\x7f\xa2^\xbcJ\xc9\xe5\x96\xb3\xedo\xd4?\xe3\x1f!e\xe2\xc5\xe1\xcbj5\xaf\xbeyM\xbe\xf5=\x16\xa5l=!\x85\x18\x86j\xdc\xd28\xe3\x1e\x83X\x86\x01\xe6IOC_\x8c\xf5\xcb$\xd9%\x07\xa0T\x15\xa6\xb3\xd3\xd3\xad/v\xd9JAp\xaa B\x80N\xdbF\xe1\xb4\xf4\x0e[\xd1Q\xd9\x80\xbd\xddF(\x9e\xfcI\xf8\x81q\xb0\xae\x9d\xe2W\xac\xc4\x9c\x02v\x9c_\x94v\x9fe\xc6Q*x\xe6\x89\x98\xcfH\\_\x88\x19\x0fR\xf7\xb6\xb5eG\x9b\xeff\x1d\x1f#v\xfb\x1f\xfch\x1d\xdf\xba?\x97\xb7\xda\xae\xcay\xa6\xd6.\x9b\xe9{3\xf5\x1c\xc5X\xac.'\xd0\"\x0c\xbe\xa3\x14\x9d\xf8\xe9\x97A\x9c\xa2\x13\x9ck\x18\x89WT\xec&!\xbd\xebGj\xaf2R\xd2\xfc\x0cvK#\xa2\x1d\nT\xfd\xd5\x17\x7f\xa0KC0\"\xe1\x8b{\x0b\xc51e\xf1\xeeV\xab.\x86\x98\xcb\x8bfz\xf5N\xf0\x07\xc1[\xdbP?\x0dJ\xd0\xb2OGX,\xcc\xce\x8cnV\xa5\xe9\x04\xb7F|\xb5\\\xef\xddX\x8d\xc0w\xc1mc\x8c\xa8\xb1\xfaU\xbe\xb6\nj\x0bf\x02w@\xa0,\xc8\xf3=\x94\xfb\x17\x1a\xe8\xa8\x03] s\x15\xef\x02#,=\xf74\x14\xc1\xb7j8bb\x19\x95\x93'\x1e\x0d\x02\x13%FS\xe9\xc1(\x8f\x86te\xa3! rM\x04\x99\x91\x13\xbco\n\xbe\\\xec\xe8\xa0V\x08\x8c\xc7\x05\xf1\xa3T\xd0\xc8S\x85\xe2\x89\" \xaf\xe9V\x15.\xfa\x83\x9a\xd9\xd1}m\x89R\x7f0Y\xa9\xa7>+\xfaY\xea2\x88%\xd23k\x16\x05\xcc\xcf\xa8V\x01\x86\x9c\xbc\xb6\x0e'\x83\xcd\xb1\xa3\x94 \xe0TH\x9a\xe4\xd0\x0cF\x8e\xb3\x0cw\x17^\x15i\xf8q}(\x90\xffc:Q(f{QH\x9b\x141\xbf\x99T \xcb\x85\n\xd5c3\xa9\xd5\x1c\x18r\xc2ssV\xcb\x91!\xb3~k\xce^b\xc2P\xa4\x90\xe2&.\x83#f\xe6u\x81q\x1e719\xcb=f^\xf2RvZ\xbe\x80\xdb\x11\x85\xc5\xd2<\x1f\x05\x81\x05j\xb3\xef-\xc3me\x14l_\xbf6\x17(\x88,H\x05\xcd\xfbQ\x83]Jy?\"1p\x99C\x9e\xb3H>n06}\x81j\xaa~U\xc0\x1c\x19t\xd6\xbe\x7f\xe2\xf2\xaa\xfd9\xcfPIS\xb2\xabS\xfa\xa4\xabTp\xea\x89WL\xec\xe2u\x07d\xc0\xa0f=S\xae\xd7\x05\xe1Ph\x9e\x1d\x1e\x04R\x94\xc3\"\xe2G*\x9b\x98\xech\xfa\xc7\xdb\xc8F\xa3\x8fP\x14a\xf3hI\xd0#X\x03\xfb6\xb8\xd8\x05Fv'X\xb4\xee\x08#\x80\x87\xf2\x1f\xcb\xc5\xfbf\xe4\xaan\xe7\xde7\xdc\xcc)m\x15\x1a\x16\x98\x91\x18AW]\x1b\x9b^a;\xd1\x1b\x00\x93*\xa4\x90\x0e\x13L@\xde)\x14\xd2\x81F\x90\x99R\xbe\xcd\xc01V\x83\x843(u\x01\xc2\x03\xb6\xce\x0d-\x81\x07q\x19\xe9$\xcd\x12\xc6a\x01\xe2\x0d\xe95\x0b\x98`\xe5\xae\x8c*;2\x8a\n\x84\xa8\xd3\\\x07\x81\x9f\xa4~:k\xdd\xa2\x17\x7f\xd6\xa4K\xebh^b\x90\x04\x98\x83(\x0b\x02%VD\xe4\x9a\xf4&\x93\x9e\x12~1\xbc\xa21\xf6Rl\x1f\xf4\xfcc\x12Y\xd5\xf1\x90D] \xb6V\xecvDN%\x0f\x7f\xc19\xbd/x\xe8\xd25\x0c\xf2\x8e\x18eq5r\x83\xf9\x15\x96\xa1\xdd\xeb\xb0\xceG\"\xc4\x9c\xbb\xc0\x1aU\xd2\x95m:j\xc5\x87q\xfd8\xcb1 p\xff\xe5\x8bh\xfd%MD\xc6\xd9\x11\x03s\"&\xdb ^\xd1\xc0\x11\x9e\xf1\xcfP\xed\xf7l\xcb\xee\xfeL\xc2,\x15dG\xf7\x8c\x88\x1d#\x8f\xb7\x8f\xc9&\xa0[\x92\xb2Z`F\xf3\xcbG\xac\xb23\xbc \xb8T\xc1@\x8a\x81\xcf\x00}\xb9\xb9\x80\x1f\xf1\x08\"\xe9\xad\xd9\xdd \xdf7Eh\xbf\x82\xe1(\x8c9\x94Jl\xb5\xdf\xb2\x1b\x8az#Pw}\x84\xeb\\\xc6H\xb9Wf\x99!}\xec\xe3m+W\xdc\xdc\xdb\x9d/X\x9aP\x8f\xc1\x08\xce\x08\x04dr\xec\x0f\x8a\xfa\x8e\xc3\xdb\x02\xb7\xde\xc5\x86+\x8d\x18W\xa0\x1a9#O\x90\xb2\x98\xf2\xfa\xd5\xb7\x9d\xf0\xcanw\xbb\x80V\xdc\x96\x08,\x86\xa1UE12\xa5\xf95\nb\x95\xe6\x8eiMJ\xd2\xeb\xc4\x81S&\xbe\x10\xe5\xbdb\x87\xbbkzC\xa3J\xa6\xfd\xc1\x9c-\xf30\xba]\x1a\xdd\xd6\x1b=\xba\xc5.\xed\xe8\xce\xa5]\x1a\xaa*xtK\xad\x0b\xa9\x82\x829\xfeu\x01n[\x07\xae\xcb PU\x06d\xe8\xc2\xebU)\x0c\xae\xf9\xb9G\xe4K\xc5>\xbb\x8cH\xb1U=\x92\xfd\x1e0\xdf^M\xc3I\x1a\xe4\xbb\xf5\xbass\xb9\x9a\x0d\xd5hf\"\xa0\x82\xfe`\x94\xc7^\xac\x10\x14\xd4\xaf\xe9\xb9\xd0\xdc\x0bo\x11D\xe0\xf8\x1d\xefDr\xb5\x13W\x94\x17\xef/\x98\xc4\x0b\x98\xf4l\x92\xee\xfc\x8d\xe8+\x12<&\xb8\xed\xf7QrP\xdc\x9c\"\xc1l\xe2\x88n\x1c\x9d\x189\x85\x16\x03\xcfu\xc5\x0e\xce\xc2x\xcf\xfe\xee\x07\x8f\x16oX\x95FR\x0de\xbbv\x13\\p\xe2 _\xc0\xa8\xc3\xb1\n\x8e\xb7j\xc1c\xfdtD\x1c\xd7m\xc9!\x8d\xd9G\x9d\x89m}\xc9tY1\xb5\xe6;\x93\xe4\x1dM;\xcf\xbb\x15\x8e\xd0\x9a\xa3GzdX\x9d|\xb8(\xdc+\xdc\xa5\x81LL'w\x81(e\xe2\x1b\xc3?\x8f\x80\xaa\xc6\x89\x8f\xe3\x80\xae&\x8fk\xb1\xf3\x90\x1b\x1d\\\x87\x96J:\x8f\xa2\x16\xbcE\xe5`\xb2\x83\xce\x0f\xb0\xe2\x07\xc1\x0f\xf0\x96y\xef\xb2\x87\xd1\x95 \xaa \xf5\xdcb`2\xd2{\xd9\xcb\xa3\xf8\xda\x91R+\xbdwy\x8a\x05{/{\xcb\xa3T\xc7%\xf0:\x0c\x05\x8a\xcd\x96\x0bYA\xbe\x1a\xc5\xcb\xfc\xaaC\xa7\xd7G\xfb\xc0\xcd\x97\x87\x84j\xe2G\x84\x0d\x08sk\x03\x84\x16\x98\xc9\x90<\xc6\x08\x0b\xb0\xf5\xc0\xa8`\xed\xf4<\xa7\x16\xf5\xd1+\xa5\xbcW\xa2xMou\x84\x88\xfcQD\xdf\xceS\xdc\xa5\x89\xa2\xd6\xc9\xc8\xfcm\xbe?\x8c\xb4\xda\xa3-f\x06\x14\xe5\x1d\x98\x7f<\x0d@\x14`\x85\xd3+T\xb5\xe3X\xfe\x9e\xb3M\x7f\xd0\x82 ~N\"\xa0R\xedoZ\xcf\x04\xbb\x13\xfdBm\xa8\xb7oROt\x19\xbd\x02\xcc\x1d\x05f\xb3On\x1e9bm\x87Dc\x1e\x07(\xe6g\xf9:\xc2\xf6e\x8a\xbcC\xed&\xdb\xe6\x95\x1b\x13u\xa3K1\x1b'\xabA\xd5\x190\xb6!\xb9\"\xbd\xb7\xab\x80F7\xbd\xae\xaa\x942<]P\xae$\x81[-k\xfb\x12\x85\x93\x9a\xa1\xa5\x8dC\xd2\x1b#s\x9bu\xa4\xfc5\x8c\xe9\x02\xa9Uek`\xd7\xf1k\xadF\xae*f\x89\xbb\xd5\xbc\xc0\x11\xcd\x19b\xa2uT\xf6X\xce\xa8\xb0\x15\xbb\xc3@\x1e\x93\xef\xfe\xf8\xc37\xaf\xbf\xf9\x97\xaf\xde~\xf3\x87\xaf\xbf\xf9\xc37\xaf\xffc7\n\xe6<\xd69\x82\x8c\xa9\xf2z\x8f\x0f\x1a\xfe\xd3\xfe\xf5\xac7\x7f\xd3[>\xb9\xee\xc9\xc7\xf37\x8f\x97O\xae\x1f\xcb\xf9\x9b\xc7\xbd\xab\xcb\x97\x7f^\xa4\xcb\xe1\xe0\x14\x19\xdc\xe9\xfc\xcd\"]\x9c\xf5\x1e\xbf\\\x9c^-\xee\xce\xa6\xe3\xc5\xdd\xf4\xeb\xc5\xdd\xa7_/\x87\xa7\x134\x0fQ\xb3\xdb\xbf\x9e-\x16\xe9\x93+\xf5O\x0foM\xdao\x83\xeb\xde\xa8\xe8\xcbd\xaer+Vy\xd9?\xf9\xdd\x1f\xbf|\xfd\x1f\xbf\xfbj\xa0^u\xeab\x91\x0e\xf3W1\"= \xeeQ\n\x15\xaa\xcf\x83'\x86\xdb\xe2\xbb,Tq\xd9?\x85F{\xe0o\xe6t~6\xfe\x9c\x8e\xdf}1\xfeO\xcb\xfcq\xb6|rZ\xad\xb3\x0c\x81\xb0\xad\xa8^\x9d^\x17\xda\xcb\xf9\xf7\x88\xf4\xb6~\xcfE\x0b\xd5\xa0\x7f\xb9\xa3\x9cz\x82q\x13Q\xddhZ\xfa\x8f\xa2U\x9a\\\xc8G\xbf\x9e\xbe8\xbb\x90\x8f\x02\xa1\x9e\xe1q\x8b\x8f\xe7\x17\xf2\xd1OY\x0c/O\x9f\xc1\xbf\x9f_\xd4\xaf\xdb\xab\x1f\x989tA\xd8\xd2n\xa4\xb0\xf7\xb0\xf8Q\xb2\x8c\x98//PUzb|]\x82\xf2g\xfe\xf4@nE\x10ON\xc4A7\x1bAE\x93\x1b\x8f\x88\xd0\x9a\xbaf\xab\x81\xc0\xaa\x87\x91c\xa91Ut\xe7\x8bh\x0d\x93w\xff\x87x\xcdR0'\xf6At\xd1Zv\x7fD\xa2\x81M\xec\x17h\xfeWh\xa4\xa1\xca\xf5\xb5\x8f\x81\x81\xd6\x0d\n\xab\x1b\xa4M>\x86H\xe3fJ\x89wq!@\xc9\xa1\xa9\xf0\xaa\xc3\xd12\n^\xb7Q\xf0\xdc\xa3pD'4\xed\xf4\xbbP\xe5\x06(\x8e\xc3x\xad\xdf\x8dr\xb2Y\xd1I[\xba\xdd\xbcp\xf5~]\xaf\x8f\xc8*\xd79Z\x0eA\xd0\xb1\xf3C\xd3\x01{\xf89\xef\xb02\xa29\x07/\xb2\xcd\xd3E\x0b\x92t\x01\xf3\xd4X!\xda)\x84\xcb\xdc\x99\xf2\x91\xecg\x0f\x99\xba\xbaX\xd4(m\x14V\xc2\xd1'85\xc3\x86\xe2\xb2j\x11|Adh9\xe1\xb3\x92q\xc5\xe1Ds \x0f\xad\xa8\xaa!\x83\xcc\xef\x18Q5\x1f\xfb.H\xdc8\x12\xf9\x0c\x1e\x1c\x88\x0f\x06\xd9\xe0\xd4\x87\x00l\xf1\xf2\xe3\x81\xfb\xabr\x06\x87\xb4\xa4\x1a^\x9e\x8e\xb4S\xb0I\xffz\xe6G\x82\xf1\x08\xbc\xf4\xd1@Z\xf2\xe7\xc7\x91z\x01\x92\x14\xf3T2\x95-\xe1~\xcaR\x99\xecb\x81^i\xeee\xc2\xe35fO\xe5&\xce\xa25\xd4$\xfd0\x8cW~\xe0\xb3H\xfa\xd1:S}`\xa9\x0ciD\xb7\xb0VU\xb9\x84q%tI\xc1\xbc]\x14\x07\xf1\xf6^z;\xee\xa7\"\xa4\xa9\xf4\xe20\xcc\"_\xdc\xcb\xb5\xcf\x99\x82\xe1^\xb2u\xe6a\xf5\xec\xa7\xccO\xa0\x1e?J\x85/2\xc1dH\xf9\x0d\x13~\xb4\x95i\x1cd\x08\xd1\x9eb\x81T\xae(\xdfR_=\xc4\x99\xf0\x7f\xca\x98\\\xa1\xa20\x95j\xfb\xaedf\xe9\x05\x8cF\xf8\x10\x8b\x1d<\xc4a\x92 \xc6\xe5\x9a\x85\xb1\xc7\xa9\x90k\x9f\x86q\xb4N%\xf4\xdf\xf7R\xb9\x8b\x83\xb5\x1fmS\x19\xf8\xdb\x1d\xb4\x9fP.\"Us\x12d\xe1\n \xca\x92$\x80\xber\xeaC\x13{\x16)y4\x95\xd4\xa3k\x16\xdeK\x8fr\x06\xd0\xc4aB\xa3{\xe9\xf1\x0c\x06{\x1d\x87\x007\xbbK\xe2\x94\xad\xe5\x06\x9aI\xe5&\x88\xd5X\xc9-\x0d\x02\xc6\xef\xe56\xf3\x05\xe5\x00\x8e\xbf\xa6\xf7\xf2\xc6WX\x11\xc9\x88e\xa9\xa0\\\xc67~Do\xa9\xe4\xcc\xf3\x13\x96J\xce\"A\x03\xf5w\xef\xb3\xdbT\xa6;\xff&\xddQ\x89\xce R\x009\xe6B\xa6\xf7\xa9`a*\xe9\x96E\xde\xbd\\1\x1e\xf8\x91\xf4h\xc88\x95\x1e\xa0\x85\xf4\xe2\xcd\x861\x85/\xeb8\x95\n\x05\xa2\xadd\xa9\xa0\x82I\xa6z\n\xe03.\xe4&\x13\xab8\x9074\xdb\xb0H\x06\xd9]\xc6\xefeH\xfd4\x8ed\x18G4\xdd\xc90KY\x16\xca\x88n\xe3{\x8a\xb8\xa6\xa0L\xa8\xcf\xd5\x1f\x80)\xf6|\x1a\xe0\xa8\xdeKA\x85\x88c)|\x16\xad\xa9\x1a\xe1=\x0b\xe4\xde\xa7?\xb2T\xee\xfd \xa0\xeaO\xaa\xd0f\x1f\x03d\xfb\xf8\x9en\x99\x04\xccF4P\xa3\xbfN\xa5\xb7c4\x91\x9e\xdaw\xc85\x8d<&a\xd1\xcam@S5\xb2Y\xaa\xd0,\xda\xc62\xf2\xa3\x1f)L\xb4^\x0e2\xdd\xc5j\xd4\xe2\x80r)b5\x03\"\xbe\xb9\x8f\xa5\x88\xe3 \x95\xb7j\x8d\xca\xdb\x98\xdf\xa4\x922\x1eK\xca\x13*i\xeaS\xb9b\xa9\x90+\xff\x86\xc9U\x00h\xf9\xee\x9d\x1a\xdeDzA\xb6\x92^\x1c\xabU\x19'rCy(7~\xba\x93[\x7f#\xe46\xe3\x99\xf4\xa3M,\x7f\x8cW\xa9\xbc\xf1o}y\xc3\xd9Z\x064Z\xcb\xc0\x0fc\x19\xf8\xd1\x8d\x0cY\x94I\xb5\x18e\x18\xaf\xa9\x8ch\xc8d\xa2\xf06Q_\x938\x15\xf2\xa7$\x8e$\xf7\xbd\x9d\xe4\xd9\x8e\xcb\x94\xdd\xddK\xe1'\xa9\x1a/\xa6\xfe\x89\xe5-\x8d\xb6\xf2V-\xe7[\xff\xc6\x97\xef\xe2\x88\xa9%%W\xfeZ\xae|\x05\xf0J\xad#\xe9\xb1Xa\xb0Z\xaar\x1b\xef\xa5\x1f y\xe3\x872\xf4\x03\x191!\xe3(\x901\xdf\xaa\xe5/\x93l%\x15\xc0\x82\x052\x8bby\xcb\xd6\xf2\xee\xeeN\xde\xdd\xbf\x93\xd4\x93t-)\x93t#\xe9VR_\xd2@\xd2P\xd2H\xd2X\xd2\x9f$\xe5\x92\xa6\x92\nI3Io%\xbd\x93\xf4\x9d\\Q\xb9Z\xc9\xd5Z\xae\x98\\m\xe4j+W;\xb9\xf2\xe5\xeaG\xb9\n\xe5*\x92\xabX\xae\xb8\\\xa5r%\xe4j/W\xb7ru/W\n|\xe9y\xd2[Ko#\xbd\xad\xf4v\xd2\xf3\xa5w#\xbd@z\xa1\xf4\x14)\x94\x1e\x97^&\xbd\xbd\xf4n\xa5w'\xbd{\xe9\xbd\x93k&\xd7?\xca\xf5\x8d\\\x87r\x1d\xcb\xf5;\xc9<\xc9\x98d[\xc9\xb8d\xa9dB\xb2Ln|\xb9\xf9Qnn\xe4&\x94\x9bXn\xb8\xdcR\xb9]\xc9\xedZn\x99\xdcn\xe4v+\xb7jb\xe56\x90\xdbPn#\xb9M\xe4\xf6'\xb9\xe5r\x9b\xca\xad\x9an\xb9\xbd\x95\xdb{\xb9\xbb\x91\xbbP\xee\"\xb9\xe3r'\xe4.\x93\xfeZ\xfaL\xfa\x81\xf4C\xe9G\xd2\x8f\xa5\xff\x93\xf4\xb9\xf4S\xe9\x0b\xf9#\x93?\x86\xf2\xc7X\xfe\x98\xc8\x1b&o\xb6\xf2f'o|y\x13\xca\x9bH\xde$\xf2\x86\xcb\x9b[ys/o\xde\xc9\x80\xca`%\x03O\x06\xbe\x0cnd\xc0e\x90\xca@\xc8 \x93\xc1^\x06j\xa9\xca\xd0\x93\xe1Z\x86L\x86[\x19\xeedx#\xc3@\x86\xa1\x0c\xd5\n\x96a\"\xc3\x9fd\xc8e\x98\xcaP\xc80\x93\xe1^\x86\xb72\xbc\x93\xe1\xbd\x0c\xdf\xc9\x88\xca\xc8\x93\x11\x93\xd1FF[\x19\xf92\nd\x14\xcb(\x91\x11\x97Q&\xa3w2\x0eeBe\xc2d\xb2\x91\xc9V&;\x99\xdc\xc8$\x90I(\x93H&\\&\xa9L\x84Lner/\x7fR4M\xf2X\xf2T\xf2L\xf2[\x99R\x99\xaed\xea\xc9t-S&\xd3\xadLw2\xf5e\xfa\xa3Lod\x1a\xc84\x94i$\xd3X\xa6\\\xa6B\xa6\x99L\xf72\xbd\x93\xe9\xbdL\xdfI\xe1I\xb1\x96b#\xc5V\x8a\x9d\x14?Jq#E E(E$E,E\"\x05\x97BH\xb1\x97\xe2V\x8aw2\xa32\xdb\xca\xecFf\xa9\xcc\xeee\xf6N\xee\xa9\xdc{r\xcf\xe4~+\xf7\xbe\xdcGr\x9f\xc9\xdb\x8d\xbcM\xe5=\x93\xf7B\xbe\xa3\xf2](\xdf\xdd\x0e\x16\xab\xd3\xaa\xe6\xb47\"\xe8\xffoq\xbb\x1c\xfc\xa6\xbf\xb8\xfdy:\x9a>\x7f?0\xba\xcc\xb2:\x14r_\xcf\xe6\x8b\xf1\xc5\xec\xd1\xd5b\xb8\xf8d\xb4\xb8]L\x96\xc3\xdf\x14\nD\xf6\x897Ub4\xa3\xb6B\x94\x19\x96\xf3\xf1dh\xc5\x87\xe5p\xd6\xbf>i\xfa\xb48]\x9c\x0e\xfa\xd7'\x8b\xf5pqz=\xe8_c\xca\xb5\x13\x90\xbaJ\xb7?\xb9>E\xa5\xaej\xff\xf6\xf6v19\xbadsG\xad\xf6\x17\xd4\xc5\x8b\xb1\x05|\xf8\xe87\xbf^\x9c\xfe\xd3\xd5\x7f~\xdb\x1f\xc8\xc7\x9f\x80@Tg\xe1O\xbc\x0du\xc8\x11\xb3@\x8c\x0f\xaf\x03y\x12=\x1a\x7f\xe2\x81&-''Y\xb7\"\xdf\xb3\x80\n\x7f\xcfl\xb9\xcd\x81S\xc8\xa3/\xfa\x117\x99$\x87NX\x9a\x87\xd0\xd2\xf7\x19I\x9a\xa1\xb54\x7fF\x1cZc\xf3\x0b\xb1\xdf\x0d\xc1~\xba\x10\xf7vj\xd4E\x08\x81\xdb\xe4\x03\xe3bX!\xf9\x17\xa2_\"W\x87\xf8\xb4\x00$\xc6\x95r\xba\xe8\x9fn\x0f\xdc\xb7\x8fJ\xf9\x07\xa7\xdb\x03<\x1b\xb9\x80\x0d\x0e#%9\x1b\x90K\xd2\x07\xf2\x14\x95\x92-!?9\xeb8\xa6$\x9fs\x87w8\x976\xf2UU0\xeb\xaa\x84\xf4#pK\xd5(X\xce\x17\xb7\xcb\x06\xc1rG\xd3\xaf\xb3 \xc8\x8b\x9a\"-\x12\xbf\xa3\x9a\x8c\xfb?x;\x16\xb2\x83\x15\xb8a\xf8\x0f1_\x7f\xa90d#\x18\xaf\x023\x9b\xbfY\xa4\xcb'\xd7\xa6JG\x15E\xe6\xdb]\x1e5\xd3S\x94\x06tM\x7f2\x1dR\xec\xca\xdcb\xc94!\xfa]\xcc\xd2?\xc4\xe2\xf7to)\xf6\x1f\xf9\xefb\xa1\xad\xd3Z\xb2\x7f!\xbee4\x15\x7f\x8c\x98\xe9q\xa5\x8c\x9f~S\x9b\xcc\x9c\x92\xf5]\xe7\xf1\xce\x13\x89r'\xba,\xd7\xea\x82\xd3](\xce\xeb`~\xb6,\x1f\xac\xb6J\xf1\xbd\x1f\xe9\x9e\xa6\x1e\xf7\x131Cg=0\xce\xbd\xfd\xaa\x9c\xd8\xa5G\x87\x86\xbe\xa3\x89\xa0\x9d\xf1\x13\x86\x8e\xe7\xd5\xfa\x07\xfb\x00\xc7:@\x9fw89c\x13A\xdb\x1avO\\\xded\xbbA^\xc7\x82\x87\x81\x7f\x827&NL\x0f\x9aWQ\xcdW\xac\xf99\x91\xa7\x0d\x05\xbb\xa0\x92\x01\xf3\x84\xd9\xf1m#Q\xcd\xc09\x88$\n#P\xf8\x08\n\xf9Q\xf6\xcf]\x06\xef\x01\xc7\xbc\xaf\x8abS\xd7C\xae\xc2\xbe\x18Jv\x84-7\xf5=\x06\xc2\xa2\xc1\xa6\xb3T\xe3<\xc1\x8e\xc3q\xf6W\x98\xc5\x8fs\xe6\x87\x1ej;\x8e\xc2W\xb8\x7f\xe9Zy\xbe\x1f\xecX\x7fq\x94\xbb6R\xf4g\xfb\xc0\x06\x1f\x80A\x0d\x8d4\xce\xa7\xde\x8a\xfd-fT\xef\xd5\xba\xce\xe9\xeb\xf2\xd6\xaek3E\x0d\x00\x96\xed\xd8\xde\x83\xe6\xd88N\xd3\x0d\x82\xe74;\xe1\x0f\x87\xe2\xb8\x89\xef\xfd\xa6k\x93\x8dh\xf0'\xfe\x80E\x9d\xf1\x00\xf7S\xb9\xc2\x13\xc6\xc3(\x8d\xfb\xa8\x00\xbe>uY\xc3VX\x91\xad\xa2A\x1e5\xf9\xbf\xe3,a\xd1\x9a\xad?\x96\xedI\xc6;S\x99?\xf1.4\xa6tO'\xe3\x0dJ\xa2\"\xb6:\xf7\xb8V\x80\xacn\x9ak\x1f\xec\x90\x94}\xc3d0\xa5=\xed+\x10\xcc\xbdGM\x05!\xf4}G\xaf \x0f\\*\xd0\xb2qv\x9e\xfb\xf4~D\xc3\xe4\x02\xe21=\xeav\xcd\xea\xd85R\xbd6\x05\xed?tN\x8c\xbe\xae\xa8P(\xe7\xc3\x05\xd1\x07\xe7XU\xb5\x83\xa3\xf8\x9f\xcc\x12\xc2\x12\xf6#^`}\xcd\xa9\x1f\xf8\xd1\xf6\x87\x80B\xcc\xf6.\xe3S\xae\xb6\x8bl\xe4V\xd1\x97\x17\xb7\xdb\xe1zS\xf3\xeeAy8,Nb\xd1\x19$\xc7X\x1e\x01J\xef\xb4M\xe1Q\xd4\xe0\x1a\x87\xab\xe3i'/F\x8a\xfa\xda\x94\xf7#\xedh\x11c$\xf16?\xa5\x1a\xb0x\x92\xfb\xe5\x84\xbb\xc0\xf9`\xbc7\xbeeFd\xbe\xc4(>\xfd\xa2\xdbx\x1d\x8a\xeaC\xa3a\x1b\x8c\xc8<\x0fa\xde\x1b\x91\x1e\x04\xa4\x86\xf02\xea-\xf0S\xd1s\x85(\x9d\x973Bm\x9f\x7f@m;\xaek9?\xfb\x80Z\xe0\x93\xaeg\xdaZ\x8f\xbb\xbc \xcbm\xea8\xaf\xd4\xd1\x00;\xa3k?\xda\x9aBO\x1f\xd0pP\xa9\xe3\x99{\xf6v\"\x0c\xa0.\x93\xef\xf9\x03\xda\x12t\x15\xd8\x1e~\xda\xa9\x87k\xb6)\x0em\x15m\xdc\x85\x8aPA\xb1\xcf+\x81\x0d\x97\xee\x98x\xd5\x05\x8a\x14<\x0b\xacW\xb6\x8a\xcb){\xdd\x81\xa1\x1b\x1bF.\x89o\xaf)\xb0\xe1pP\xa8BG\x92\x9f\xb3%\xc4\xe7\x82\x87\xe9\xd2%\x8e\xd1@\xcc\x08\xe6<\x87\xf3\x85\xf9r\xa0\xa9\xd2\xa0BzrJa\x9fh\xc1\xad\x11\x04\x82\xf0\xdf\xb1\xaa\x835\x87\xe6\xcd\xf6E{\xfb-\x00\xbee\xe2\xfb,`)\x1e\xa3\xa3\xa3\x04\xec$\xbaH\x10\xe8\x10\xe1dzA(\xb9\xd4GHl\x12\xf8\x91j\x98\"Q\xbd\xf1\x93\xaf\xc2D\xdc\x7f\xebG,\xedS\x08m@\xc9\xcb+\x12\xa1\x17\xfe\x93>\x9b\x88\x1fv\xfeF\xcc\xe9\x12\xae\xdb\xac\x82\x9bo\xa25\x8b\x84\xfb\xfa\x13\x00\xccq\xe0\xe1F\x08\xd4\x12\xcf\xf9Ru\x91\xc2\xf1\xe6\xc9tpA\xf8p\xe8\x90\x130\xea\x85\xf0\xb7;\xa1`\xcfF\x84M\xfc\x14@4\xb0[\xbe\x90\x19\xb9\xaa\x8f\x9dQ_\x07\xa6\xa7y1\xda\xa86W\x8da%#2\x1c\xdaAB\xaa\xa1\xb9RB9\x8b@\xe8\xad\xd7\xda\x12\x0e&\x1f\xe7\xda\xe7\n\x9f\xcaq\xa5\xcc\x0420S]D\x0bQ\x8b%\x99\x82q*W\x1f\xb3\xb3\xb3\xcf\x9e/\xe5|\x91\x9d?;\x7f\xb6\xc8\xce\xcf\xce?\xd3\x89\xd5R\x01\x94\xca\xce\xce\xe8\xd9i!,X\x111\xe1\x8e\x91\x03+G\x84W\xc7P\x81\xe8#\xa2\xb9<)\x03\x02\x94\x92\xe1>>\xb3\xc7\x02\xd5\x9b\xf3\xc0\xe55\xab7\xc2I0\x02'\x10\xb98\x9b\x8eHo\x11\xa9\x14\xabU\\\x88\xde \x8f^W.\x9f\x15\x18p\x93Z\x1b\xd6V}\x0e5\x94\xd3\xb3\x82p\xf2e\xbcf_\x88~4 \xd7:,,F\xf9\xf3t<\x14\x08\xfe\xa6P\xbf\xa7j\xe8i\xda\x00\xee\x85)\x19\x13o@\xfe\x89<3\xc7\xb5\x90\x08\xc5y\x95z\xe8\xd5\x8c>\x15\x99\xf1\x07k\xe6\xc1\xdc\xab\xd54\xa4\xef\x8f\x14q\xf3#f\xfe\xbe\xa2w\x05\x024*\x05\xb4Al\x1fz\x1epZ\x86U?@e\x18kM\x9a\xeb\xae\xae\x96\xab\xdf\x8a\x00\x9c\x0dj\xa8X\xac;\xdf7\xfd\xaa\x0e\x08/\xbaUD\x1e\xd6\x1a<\xa0\xb8Y\xc7\xfa\xe7li\xd5`(\x11\xb0\xa5\xa2\xbc\x85.\x14=\x9f\xbd\x1f\x95\xda,K\x1a\xadM\xd7]\xda\xeb\xfe\xa2(\x87g\x8f\xfdC\x90]V\x00\x1b\xa0\xe8w\xe1\xea%k\x83\xfa\x87\x84zGC\x9cr/\x978\x0d\xd0z\x15\xd9\x0c\x85%\xc8\x1e\x0c\xde\x97;\xca\xd3C\xaezKn1\x9d\x00F\xf6\xe4\xa9\x06\x19\x02\xfdA\xf0\xfd\x96z5w\xc2\x0e\x86\x0c\xd2\x1f\xb9\x04\x97\xf8\xa6n\x07\xdfP\x10\xbf$\x91#b/Z\xaa\x9d4\x0c\xf2x\xccr\xbb\x04\xa6\x96\xedq\xdd\xd92Q\xc7\xdeV \xa9j\x19\xa98]],b\xb0\x8c\x1a=\x14\xa9,\x81\x82\xb6\xe2\x92\xd4/\xaf\xffy\xa0V\x01F5\xf0\xf1\x10\xce,\x87`9\x02\xb7\xad\x8acpr]Z\x19Pjj\x1c\xc1\xdb\xc4Q>\x82(\xc7\xa8~\x0c\x1c\x93\x91iQ\x05|\xb7\xf6\x05\x19\x83\xe1\xac\xf6 \x1a(\xd4\xbf \x81\xa2\xbc\xf1p8\x80\x88ne\xc8\x06j*Ax\x03&?\x18\x01\x07;\xb3)gZ\x1c\xaa\xf54\xc5\xfe\xe0\xc8\xa8\x15&e\xf7\xcee\xf3xY\\\n\x8d}\xd4c\x9d\xd5}UUD+\xb4\x8d;J\xb42\xa9\xee\x90\x83\xee%b\xf6\x82\x0e,2c*\x96j\x12\n\"\xcd%y\x96\x9b\xe3L\x1ds\x18\x03^\\\x81\x8f\x9a)\xee\xdb\x9aVW\xbe\x03\xe2j-\xb9x~\x8b\xdd\x1fl\x02rHy\x15\xd2\x97W\xe4Y\xfb\xc6J\x81:\x1c\x1er\x06k\xf5\x9cZ\x86\xe3\xa3<\xf6{C\x8c*\x1d\x8b\nUf\xb5\xaf6\xe6TN\x05\xd4\x96\"\x1e\x91g\xe0\xe8\xc5va\x04[\xd2ZyP\xc2\xb8\xaf'*\x10\xd3\x19\x99\x8b\x91\x86\xd7\xa1<\xd1\xe1\xab\x18\xca\x8c\xa5\xcf\xef\x95\xf0\x96\x8bI\xef\x7f\x194\xecN\xdf\\\xc7F\xe8|C/^\xb1\x84\x11\xb3\xc8Z\xcf\xbe\x81\xec\xccd\xaf\xa3\xbaG\x86\xe4)yI6\x8dh\xadrM\xcf_\xa0\xd7\x96\x18u\x1def\xe0\xa1\x82\xe3s\xcc\x13\xb7\xd6\x04\x92\xf7\x08%\xe7\xbeg5'\xc0\xda\xfa\x9e\xda\x03\x0d\xc8\x98\xa4\x03rI\x9e\xb6V\xa45\x159\xc5\x01C\xf9\x89\xe0~\xd8/\xeej\xff\xac7\xb5\xad\x95\xf1\x82\x8d]\x03a\x16\x17\xe4\xa4?\x1cf\xa8\xd1A\xc1 :\x90\x16g$+\xcdH\xb6\x04\x9b\xbe\xd2$\xa84P\x7f\xd8<5]P\x03\xb5\xa8\x8d:0\xb1\xb8\xa2[\xca\\\x84\x00\x04\xf8\xe6\xd1\x06\xe5R9\x0b\x8aj0\xb5\x10\xb0\xbe\x81\n\x01\x9a\x9e\xb9\xe9\x0b\x90\x9en\xd4\xc5\x87vs<\xce\xc9MF\x86\x8ae_\x03\xeb\x81\x93\xbfn\xc4\x07\x94\xf1\x0e\xea\x93PN\xc3tFhG\xc2\x84\x8a\x85\x0c\x16\xa7\x93\x1c\xfd{\xa29\xf5\xb0\xbb\xc7Q\x9b\xf0\x10\xb5\xd9\x93\x97$l]\x89/\xce\xb5\xb1[\x05\xdb\xf7\xc3\xe1\xa0\xb5\xa0\x1e\\\x85\xeey\xac\xdf\x90\xde\xfd\x81\xa5\xc2\x8f\xb6\x1f\xb2\xfc\xf5f\xa3\x0e\x13\xac\xe4\xbd\x92\xc84\x11\xc8Y\x17\xab\xeaA \xeaaa,\x01\xc9\xf3\x91\xbd\"{\x14\xce X\xed\x9e\\\x92\x10\xc2\x11\x15\xd6\xe2~@fd\x0f\xd4,D\x81m^\x98\x0d\xa8/\x17[T\x1d\xe3b\x0b#\xcd\x0bP-TS|\x17\x8e6\x8cO)\x94`b\xb3\xa39\xe9\xf7K\xe8\x10\x97\xd0!^\x02`\xfd\x12\n\xc4\xcb\xc1\x00\x03\xa09IZ\xfb\\7\x8b=~\xabXc\x03+\x9fLGpW\xe7\x0c\xaf\xa6l\xec&-!\x97d}A\x92C\xb1\x0b6\xf3d\xa9/eE\xb0\xfa\xdbt6\x04\xaeA4SC\xf3sSE\xf3k\xf6\xd0\xb5k\xedtf\\\xfd\xdb\xc9Q{\x14\x93\x98\xcf\xd1\xa88c\xa0A{\xfa\xf4\xd3:\x8dF\xc1\xb3\x03\xde;\xdb-\xa2\xc8\xf1x}\x18\xe8\x12f\xc7K\xc7\x8a\x0dH\xf9\xc0aT>~\xb8\xaa\x9c{v\xe4)y\x99\xa6\xa0\xc1\x9a\x19@\x84g1\".wue^P \xed\xfb~0\xca\x97\xa8\xd5K#\x11\x8f\xbb3\xbf\x02\xa0M\xf1om\x9c\xdb&\xa6T\x190\xc5\x1b\xe6\xd3\xa5=\x1d\xd2K\x0b\x17\x13\xcd\x97\x16F\xac\xd6s\x93\x90!\x01Z\x94\xcd\x93\"}\xb2\xe9t\x9e,\xdd\x8a\x83\x12\xf9L\xff.xd\x99\x17:\x0cJ\x0eq\xbf~F\x86%9Gm\xd8\xd3V\xce\xf4\xec\xbcE\xee\xce\x80N>zD\x9e=G\xc9\x1b\xa4\xf0\xe7\x07\xa4pX jEN/HF.I\xea<|\xac\x88\xd8\xb5Vm{O\x11B\xda\xd8\x1e\x01\xbfrVT\xf5\xab(\xef\x9a\xfe\x93\xbe\x8f\x1b\x80G\x8fH\xff\xe4\x84k\xbb\x10-\x13j\xa1\xac\xe3b\xd8\xf1\xe6\x85\xfaaR\xdb\xa0z:}\x14N\xda\xe4\xcai\x90\x0b \xf5\xf9\x90s\xa9\xf4y\x9b\x90\x86\\9.\xa3\xe6\x80\\\x93\xb1\x12\xa8\x0dzE\xae\x89\xe6\x15\xf4\x02)\xe0\xd9S\xfd\xack\xe0\xe4\xb2\x84\x07\xf5Zlc\xbc0Z\xf5\xce\xc7\xad\x9d?N\x0e\x8d\x0f\xadD\xf0\x83\xa8F&_&c\xd7\x1e\xb3e\\.\xc9\xb3\xcf\x14ZF\xe4%y\xfeic5\xa8em\\b\xbc\x1d\x08b\x15=m\xa0\xa8\x1d\xdegj\x0e\"ry\xa5\x80i\x13\x9e\x9e\xa1\xee3R\xb0?{a\xa2\xa6\xb6\x88\x16\x16\xb4\xda\xd7\xa6\xe3\xf7B\xa9\x07\xa2\x87yj\xa7\xd7\xb534p\x87\xd9\xb2\x9b\x19)\x01c;\"\xf7#\xb2\x1a\x91\xb7#r;\"_\x8d\xc8\xdd\x88\xfc0\"_\x8e\xc8\xcd\x88|\xe1\x10\xe1\x00\x15\x94\x08\xa9q\xd4(\x14\xb6\x8e\xbc\x0d\x1a;=\x89\xaa\x12^\xaa\xa4\x95lB\x03\xd3\x96Q\xfe\xd0\x8dO\xe8B\xaa\xb5\xbe\xcf\xed\xb7\xef\x8aV\xb8gG\x12l\xace\xb6\xe4\x1a\xef\x017\xafV\xd8T\xa2\xffj\xad\xd4\xd07\xca\xd5<\x911I\xf0~fg\xfa\x1e\xf35\xe3l\xfd6\xf0S\xd1$\x97A\x9e\x19\xd972\x82\xdb\x87KlJz\xed\x08\xea*\x0b\x02&Z!\xfdpx\xac\xc9\xd2[\xbd\x07\xbak\xdb\xf7\x81\x81\xce\xe0\x82\x9c\xf4O\xfa`\xb6\x836\x98\xb0\x81\xea\xdfW\xd5AkD[K[\xe9Rkf\xee\xc9\x98\xac\x958\xf3\x0cX\xb6*\xadPhG.\xc9\xb4\x94\xa2\xa4\xa8uQ~\xa7\n?v\x9dg\x1b\xc6\xce\x17,<0\x80_}\xc8\x00\x06\xd5\xdd<\xea\xc5\xc0H\xc1\xec\xf5\x0b\x08\xbdq\xec6\x8a;\xf1\xfb\xeaN\xbc,\xdd\x82e\x965\x808\xab\xefU\xb4}`\xd3\xc6\x00\xf7\xa6y%j\xaf\xfe\x16f\x11\x88\x99\x1a\xf5\xb7Vn'c\"\xc8K\x9c\x14\xa7=X\x15\xba\xa0\xda\x9b\xb4\x08\xaeW\x83v\xf3\x80\xa9|\xf0&\x050\xbd\xb0'\xf9\n\xb7(tD\xee+\xd2:\xd1\xa6xj\\\x8a\xa6g\xf8~\xbc]\xde\x8d^\\?\xa0\x82\xe1KrE\xee\xec.\xe8\x07rI\xbe\xbc ?4)\x18\x14\xe9\xbd\x9b\xffP\xb4\xe3kW.\xdc\x1cP,4+\x15\xea\n\x05\xd5\xf8M#\xc7W_\xb7m\xf2C\xce\x08)HAg\x83&Eo\xeev#\xe7{\xe52\xee\xe6C\xb7\xa4\xb0\xd6\xf7\xf6\xeb\xad5\x1cXuAB\xc5\xaf\xca\x1c\x04q\x91T\xa8\xf5\x831\xf4\xd6bdn\xc7\xa8\xa4\x8cG\x8f\xda\xcd\x0cHY\xf2G\x1c\x07>?$\xe7\xf5q\x03\x9c\x8c\xf4\xde\xe8\xdc\x08\xcc%\xe6L\xc6\xe4\xbc\x14\xb7\xd3f\x98GKcAevi\xb9\x851\xd2Y\xad\x08\xca\xf3\x0bm\xc6\xd9\xcf\x13U\xcb\xcb\n!+\x14(\xa4G\xe8\xd8\xbc1k\x97\x82\xa1\x7fO\x9b\x8bv$\x08\x99\xb6g\x1b\x92sT+\xf43\xb3\x0b\xf4\x14\x17x\xfe\x99{\x08\x87\xc3lPVDd\xc3\xa1\xc2m\x16\xed'\xe6VCjn\xae\x94\xd2 \\c-\xeb\x84\xb3\x8d3?~\xd0\x85R+\x9a\xe3\xf1f\x80\x0b;S\xcb\xb8\xa1\xcey\x0f\xae\xf0\xa6Km\x1a\xd9\x8d\x04\xda\x9b\x19o9\xdb0\xce\"\xafY\xbdIW\x8a\xda9\xe2\xe1\x1f\x14\xa9\xe2*?\xae\x1d\xf9\xd1\x03RTI\x10\xcd\x06d\x8c\x82S\xf1\x08%+\x0b/\xc3+\xf2\xac.M\x15.\xa2\x14\x1b(1~C\xd9\xec\xd7\xe1U\xedx\xc7\xb6;.}k\xd1\xe0\xe6\x82Z \"Z\x86z\xac\xa1.\xf6\xdd\xaf\xf64\xfe\x90\xd9}03SR\xca\x07\xe9\xbcL\xea\x07Q\xe7\xe3\xe8\xf2A\xad,\x9c\xe8\xb7ka\x9f>o\xd3\xc2\xe2\xb5\xb5\x03\xd5\xe4ZW\xb3\x16\x1cd\xe6\x82<}\x9e\xf3`P\xce\x82\xca\x94\\^\x91\x17\x17\x03\xe2\x83\xf1Wci\x17\xd5;\xe9\xfb\xe4%y\x81\x10\xea\xfa\xb4.&.S\xb5\xd4\xae1kg\xd8OG\xe4\xa9\":\xf9\xcd\x90\xfa\xf7\xe7\xea\xbb\xda\xfae$7\xcc\xac\x01H\xf3\xcb&`=?(\x08DG\xeas\xf1:W\x13\x8d\xda}\x8bX\xec\xb8\xc9\xfd\x11\x94\xbev\x0c;\x02\xebG\xaa\x9dv+\xa8\x9c\xc6CH\x1fm\xc2r\x084\x18\xb3\x07u\xd1\xdb\xf9\xc1\x1a\x1ci\xcd\x97\xb5\x0ev\xec\x97\x99\x84&R\xd26\x0b\xbf\xacZ\xdd\xa4>\xc4\x12pd\xee\xe1\x88F\x8bV{\xa7K\xcb\x10\xcd{GG\x86\x8aa\x8e=\xe0\xe8\xf7K\xec\x91\x96\x88\x1a\xd5:|\xbfH\xc8\xe8R\xcb$\xfdg\xcf\xf3\x8b\xb8\xb5U\x17#mz\x81:_\x8eE\xe2\xf2B\xee\xc7x\x17\xc6BQ`\xb31l\xd7\xfcb\xb9F\xb5^\xe1>\xdc/\xb0\x9cM\x17\xb4\xbe\xe9\xfca\xa8\x7f\x00\xf7:\x82|\xdc\xa2\x06V\x9d\x1f\xbd|\xdc\xe5\xad\xa8\xea\xbf\xf2\x12\xef03\x87W\xfc\xe0# \x16\x85;\xdfg\xe7\xd5\xbb\xdd\n\x81O\xdf\\\xf6\xe7:x\x9fvu=_\xa4\x8b\xd3\x97U\xd7n>f^\x9c:\xb2\xbf\\\x9ev#4#B]\xb4&?\xa0\xa8H\xc5\xb5\xa1\xab\xd8o\xd63$e1\xba.\xbbxJvMF\xe4$\xdf\xdc\xedD\x18\xb4\xca;\x89\xa2M\x8apx\xb0[zyu\xc0<\xf4\xc5\x99{\xeb\xe4\xb5\xef<\x9f\xe2\xa6\xae\x9f\xb9H\x97\xa7w\xae\x8a|a\xbe\xaci_Y8{._rz\xdfv\x1c\xf3\xecS\x00\x1a\xa4\x96\x93\x96\x1b)\xe6g.\xa5<='\xb2z\xf5\xc0\xfc4\x18`t\xf9\xf9\xa7\xaaf\xa1d\xb7\xe9\xf9y-\xfb\xfb.\xdb\xdeg\x9f6\xf7\x9c\xd8c\xa5\xeaV\x11-a\xd1\x95\x9e?(\xb6R\x87\"W\xd2\xb5\xd7\x13\x0f\x0eC{\x82h\xc0\xe7\xe9|Zq\xd6\xb7o\x0b\xd5m\xfcm\xc6\xa1U\xb5\xb3e\x1c\x9fx\xa8\xfe\xee\xa6\xf0\xef9\xfc\xfb\x14\xfe}\x06\xff>\x87\x7f_\xc0\xbf\x8c\xae\xb1\xd4\xce\xc2\x03\x1e2z\xfe\x86\xd3P\xbb\xc1P\xff\x86\x14>\xc6\xe0\xd9\x0f\x9e\x00\xd28\x13I\x06\xef\xf09A`\x12\x1eo9K\xa1\xf3\xe8b\x12\x9e\x98g\xe0N\xc5=\x8e\xa6\xf1\x11\xd1\x13f\xd8\x04tY\xb0;A9\xa3\xf0\xbc\xc1\x0b\xaf=\x01~'\x04\xc7gF!g\x06p\xec\xfd5\x8b{\xcb\xc9&\xe6_Qo\xd7o\xb9\x808g\xcb\xf2\x0dP\xad\x95\xfa\x90\x1b76\xb9\x8b\xf9\x8aCr\xcc\x95)\xb5u\xc0\xdb\xb6\xecv\xf9\x16N\x8e\xc1BdL\"\x97\xb7\x88v\xf6\xdc\xf5\xcau\xd1\x8a\xa0\xce\xc8\x04\xb2\xc9\xc2];\x17\xbb\x0bJ[]\xe4\xd8Am\xd7\xd0RA\xbf\xa4\xfa\x08J\x12x\xb0,\x9f\xcc\x06\xcd\x14\xd7\x87\x0b\x1d\xa80\xd6\xbb\n\x87J#\xb7\xfb\x81\x1b\xbfZ;\xea\xb7\xd6J\xady\x030\xef\x1199}3\x1f\xcf$Y\x0e?9EW\x9b\xb4]$\x80\x1b\x08\x14C\xa9\xf6{\xb2\xa7\xf6\x1f\x10\x03\xb5M\xad\x92\xe8\xeb\xe7)Z$\xa6\xe4\x92\xe472[no\x9f\xc0\xb9\x947O\x97\xe6\xdaH\x1b\x9fE\xff\x05\xa0\xb8M\xe1\xd1+\xb9W2\xd7\xb2[\x05\x83\x83\xde\x98\x89\x01\xed\xf4\xcd\xecz<\x9c]\x9bq[\xb7\xb3\xdf\xe7\x9f\x01H\xeb\xd2\x81Y \xbek\x92 {se=S\xdf{\x18b\x0b\xce\xbe\xb8\xbf\xdd\x89\xde\x80\xcc\x9c5\x9f\x15\xaa\xeb\x05l\x839MB\xaf\xed\x06\xb7\xea\xdc\x18w\x0c\x05tq\xdc\xdb\x81\xb9o\xc1\x14D\x14\xeb\x9d\xed\xcdB\xca\x85\xfc\x04\xfc\xb3\xf5\x06\x05\x04\x1a\x91\xc4\x8c\xc3Ia\xd2Z\xeb\x8e\xdb-_:\x8a\x0b@\xe8\x0f\x98)\xec>\xc4L\xa1+\x1c\x8ao\x1c\x80C\xc1\x00\x8b\xf6\x97\x84\x83\xff\x92@4/\xfe\xae\xe0\xed\x9a\xc0\xa3\x81\xbf\x8df$\x99\xa7.\xc0>\x02\xec\x1d!<\xacw(\xd0\xb2\x8f\x00\xe9/\xa3W\x10\xbb\x87\x1e@|\xc0R\xe4\x0fm\xf3\x88n\xa9U\xf6\x8b\xb7\xa2d\xc6\x03\xcbh\x0f4\x05\x8f\x0b\x1fDW\x8c\xa0r\x8e\xdb+}\xfb\xa7Efy\xf4\xc88)\xcfiz\xe0\xa6\xe9p\x83\xbd\xd1\xaa\xa6;Q?4^\xa4\x0b\xdd!\x87F\x83|0q!\x058\x1a\x8909DdHW@7F\xa0\xc9\xc3\xf3+Q\x0f\xc4\x15\x95\\e\xe2p\xabrD\x9a\xf2\xc0{Y\x8a\xa8$\x91Y1\xc5j7\x8f\x19\x97F\xb2F\x8a\xa4\xad!\x8a\xca!\x8aE\xda\xa8\x16\xe9\xb8\xf8Hi\x12\x9b\xd689\xb4\xce\x89\x83\x8a\x11\xd8\xa2to\xbe\x99\x90\x91n\xcd\x97W{\xe9\xcdn\xad\x8e E\xbf8\xc1\x03!\xea\xc1\xad\xec\xd0\xfcj\x8f\x7f\x82QI\xed\xf3a\xea\x13\x9b\xdce\x03\\\xb0\xe2\xea|r\xedw\xd8\x06\xc7j\xd3\xe7\x1b\x13z{M\xdf}\x18d\xees\xe8\xbd\x1c7\xc5b\x14\xc7#\xd7\xe9\x8f\xce\x12\x95\xda\x89*\xe3F~\x91}\xb6\xb5\xd6o\x15\xd0\xfb,\xf7\x08\x06\x96\x85\x8f\x1e\xd9\x89x\xe9t\x9d\xb7)\xee\xc3\x8d\xaep\x03\x05\x87\xc3\xcd\xc1m\xbc\x9d\xb3\xcdQ{w\xdf0\xc6\x8d1\x81lm\x03\xd0\xf9h\x9b,m\xa7\\4\xfb\xeb\xbc\xd2\xd6\xc1\x01\xb9\"\xf8\x90\xbdJ\x866\xe9J<\xa8\xf8\xafc\xb3\xb6K2\xf0\xe9^\xdb\x0dn\xb5\xd1\xed\xa1\x1e\x91B\xaf\x1a-\xedIA$\xceF$\xfb\x10\xb6{\x04@\xdd\xb8]A\x03\xac`3\xd8Z\xf4\x8d2m>J$\x1d\x8f\x13I\xb7!\xf8\x98\xfcs\xddlKK\x0e\x11t\x82\xfc\xd3\x89'$_\x9d\x07A!\x05pZe2\x92\x8f\x8f\"k\xf3\x8d\x1b\xf9m\xd6C\xa8B\xf4x\xe1\xb5\x1b}\x9d`\x0d/\x86\x86\x8d\xf4\x89^a\xa6\xf7\xc5#>\xba\x1c\x81\xd2\xa0j)W4\xd9gE\x1f\x89E\xfb\x03\xd8\x12\x14\x13\x14M/\xdd\xc5\x18\x91\xf6\xab\x08\xb9\xb7b\xa7\x91\x1bu\xdfF\xd8\x82\x81\xd1\xbd\xb9\x8d\xb0\x05\xb0\xf4\xf15=x\x1b\xa1\x08\xee\xbe\x08`X\x83oW\x1d\x8adT\x1e\x8du7d%%\x0ciCX\xd2\x05i\x89\xd9F\xa0\x18\xb2\xb1\xfdW\x02\xfb\xcb\xfc\x02^\xd3\xb1\xe2\x01\xb6s\xb0\xac\x83\xf9\xb4\\\xf8\x03\x1a]_x\xb5\x14\xe4\xa5/\xdb\xee\x0f\xfa\xda-\xf0\xa6\xc8j\xb3f\xb7T\xa5\x8e\xd6<\xe3\xb4\x95\x82\x8d'\xd0\xc9\xc1a\x90J\x17@\x1e=\"t8\xcc/\x88t\x01\xadn\xec\xd3\x06\x9a\xef\xbe\xfdP\xca\xfc!\x92\xf8:x\xb8\x80\x1ch\x94,H\xc6\x9b\x11\xb9\xff\xc7\xfd\x04\xe7\xfd\x04\xef\xa3\x1d\xba6\x8a\xcb-\xdb\x87\xe2\xfd\x04\xb7\x91\x9a\x0f\x1e\xb6.\x8d,\xaf\x8f\xc5\x07\x95s\xf1\xd4\x11=\xceZ\xf37\xde\x14\xcc}\xce\x0fP\x13\x12\xd5\xaaE\x9dH#\x19*\xe8\x90R\x971\\\xdb\x0d(\xeb\\O\xc9\x7f>^\xba\x82%o\xd51>\xb9$\xf4\x82\xf8m^]\x88\xa1Is\x1f._\xa5]._\x99_\xdc\xc1\xbb\x0b9\xe8\xe1\x858i\xa9\xf9\xe9\xcdM\xd7\xfb\\\x9aN\xe0j*\xda\x0c\xa4\xcd\xd2b\xbe\xd0\xd3\x11\xe1f\xf1\x15\x97\xca\x01rSYzu\xa2\x03K\xc9\x1d\xf5\xa8\x8b\x19DY\x8c\xaaQ\xac\x8eP\x1eV\x96\xf3CMw\xb4\xc1\xfb\x85\xec\xef\xf2an\"\xeem\xe3\xdc6\x86\x1f\x8d\x88\x1d\x8e\xb0r\xfe\xf4\xb9#\xc0J\xd4?\xff\xb4\x92L\x1b\xe2\xae\x08vgbc<\x9d\xba#wD\xec\x16\xa7\x1as\x9d\xbbs\xb1\xd4\xa3\x89\xcd\xf4\xd4\x9diE\xbd\x1b\xe1{7&\x8a\xcb\xd3\x86`!k\x16\x98\x1c\xcf\xdd9\xfc\xc8\xd6\xf1\xc2\x9d#\xa4\xdc\xc4\x1ay\xda\x10Q\x86\x85\xc9\x8e\xa6\xbe\xad\xe93w\xb64[\x99\x1c\x9f7\xe5Ht\x8egg\xee\x1c\x81\x1f\xd9^?k\x18h{\x95\xc4\xac-\xcc\xdd0\xe0\xc5\x8b'&k\xc3\xb0S\x1d\x1e\xc8dk \xd1\"\xa8 \xe4\xf2\xaca\\Y$|qo2}\xd6%0J\xf6Q\x02\xa3\xe4^\x90\x9c\x81Q\xa8 \x8cB10JE\x11\x0c\xd9\xf7\x18\x81\x99}\xebG7\x8a@\x17\x16i\x1d\xea\xb4n\xe9\xb3\xb7\x81t\x91\xd8\xb7E\xcc\xd5\xbc\xc3\x1c\xc6\xabb\xbe9z\xf9J\x8d\xa1\xafXI\xf1\xf8f\xd63\xf1hU\x89\xb9\x0d\xa6\xdb\x1b\x15\xe3\xed\xf6\xc0H\x0bM\x9c\xd6T\xd0\xde\xd2\xd6 \xcc\x11\xce\xac7\x98\x9f-]\xe6:Y\xc5\xe7\xf5kE*[=\x86C\x9fG\xc6KLa\xd4KQ]j\x88\x02\x8ez\x8d\x8e\xac\xf6\x15u\xafI\x9c:4y([y\xd4\xdb\xb1\x7ff\xa2\xef\xc3\xe5\x97\xb3\x01\xe6W\xe8R\xd1o\xb9MP1l\x03b\x8f \x97$\xbe \xa2Mx\xe2s\x01\"\xcbI\xc1g\x08\x04\xe2\xd2\xa0\xfc\xa0@\x19!\x10\xce3\x86$N\xf1\xdeb={)w>\x17\xefG\xa5\xe90\x1b\xfd\x8e\xfe\xdb\x0fNIy\n\xf2!G\xf7\xf40\x98\x97\xc4o\xd6\nF8x\x91q1s\x02\xc3\xc9\xe7\x11\x8e\xd3t0\xc0}\x84{W\xd6\x18\xe8\x187z\xaa\xf5\x97`\xef\xd4z\xbb\x9dM\x12\x16\xad\xfdh\x8b7\x04S\xee\xcd\xf5H/\x1b\x06\x95\xe0d\xe8R\xa0\xf7P\xe4\xe1;L\xe8\x0f\x9aF\xff\xd8\x802\xcdaO\x1ct\xc7\xeap\xfcF\xa7\xdc\xd9\xaf\xc8\xb1bB\x9dd\xf1:\xc2\xa4\xb7\xbe\xf0v\xc4mw\xed\xd1\x94\x91\xe9\xd9\xcc\xfd\xe1\xf3\xf3\xa6\x0f/\x1a>m\x1a\xad\xa7\x9f65\xdf4(\xd3\xf3\xc6\x91o\x82\xebE\xd38>w\x8c\n)\x98\xd29vbk\xb6\xa1Y \xda\xcb5\xf9S\xeap\x94\xd5H\xec\"\xcb.\x80\x1c\x192\x06T\x89\xd7]7G\x83\xc1\xc5@\xd1&'G\x8e\xf4e\nE\x82\xd4\xb6L\xe8\xbb\xe2UJ\xa3\xad\xf4!\xa3Z\x87\x83Q\xce\x82\xca\xf6\xe2\x1f \xe2w\x1e\x8b\xaa2\xc8\xc9;\xa7\x0d\x17E\xe2v[?=\xbc\xd8\xff\x82\xf1\x81\xd1#\xe1h\x8f\xc8\x89p;\x9a\x85\xd3\xcb\xb3\xd2\xf5TSYyV\x9c\x88ck\x98\x1e\xacA\xbb(9\xa0\xc6\xb0\xf4\x19U^>\x9eS\x12\x7f<>\xac\xb9\xb0~\xd4\x1c\xcd\xfb\x9d\xd4\x189\"\x15\xab\xc9\xedE\xce\x14+\x1e\x92iC\xe8\xd9\xe2\xefC4\x1d\xec\x90\xfe\x9d\xe4[\xe1\x1d\xe5kh\xabE O\xdaw\xbd\xc5\xdf{\xf70\xd7Xzi|\n1SG\x87\x81\xd7\x80\xa7\xf1F\x1c\x02\xbc\x03\xd0N\xa3\x11\x0d\xeb\xc1\x13\xb7C0\x1ch\xdfiv\x17\x0f\x87\xe8\x19\x9a\x93\x96;\xdf\xb1\xa2rq\xe3\xfd\x1b$U\xf1\xc7RF\xd8\xa5\xc5\xb59\xb8\x0e\x9c\xa2\xc0<\x7f\xfe\x02\xfdP\x13\xbd\x19;+\xf4\xaa\xb7X\x9c,z\xbf\xfe\xe4\x9f\x1e=\xee\x0f\x9e\x0cG\x93\xd3\xd9\xc5\xe5\xd5\xcb\xeb\xdf\xcc\x97o\xde\xfe\xf9g\xf9\xfe?\x8f{f\xe3\xd2\x1bt\xbboQ6\xb4Z\x92\xabb$\xa9\xca\xe5\x8b.d\xd5\xd2\xd4\x96\xad\x8a\x92\x9bk\xa4\xf3\xf3\x06\xbf\x8b\x07(\xeep\x18\xe3\xc5\xdf:j\xf9\x8d\x8e1\xf1\xb6\xf0\xf9\xf3\x17\n)\xcc]\xb0(\xbf\x88\xd0\xc4\xc8\x8c\x8fg\x85\x10\xc3+r>r2w\xcd?\xb4\xc3J7\xca\xebM\x15\xf8\xf4\xea\xb6B\xbb\x90\x96N+\x14\xa2\xf2 \xb6\xf9\xc7/\n\xf3k]\x1c\xb6\xb1_5\xbf5\x0fuo\xb1\xe8\x99aV\x1b\xc1\x8f\xb3\xea\x8eE\xe4\xd29F\xb3\xa0\xa0c\x89\x1c\xe3*\xc8\xee \xb3\x11\x01\x0f=\xbc\xb4\xa1\xcc\x0c\xb5\xfa\xfcE\x93+\xa1\x8b\x81*\xe8\"w\xa4,rE\xe8\x12\xc3\xd7\xc1_\xb3\x0b\xb0\x84\xac\xdc\xa7)D \x81\x93\xbf\xe6\x8d,\x85sx\xb8\xceH\x0fAIU=\xd4\x85>>\\\xc0\x19+\xa8\xae\xf2\x00\xb6\xe5\xc5\xd7\x85_4\x84\xed!\xa4\xd9i\x85_\x08\x93?'\x8bh9\x04\x93]\xd2k7Q1\x91|\x9a,S\x0e1\xa6\\\xde\xa5\xb5u\xd2uU\xc4E\xca\x93G\xfd\xfd;Z\x1cJ\xb2\xadu>m\x91\xb1\xcf\x1b\xd6N\xdaN\xf2\xdb\xed\xd7R\xf4^\x06w\x91[\xb257\xfe\xcb9\"\xf3u \xce\x94\xbc$g\x18\\\xa0\xda6\xd8.\xcf\xc0)\x96\xd3\xa7\xb9\x82\xee|0\x02\x03\xca\xab\x83\xd7\xdcL\xaef\x9f\xe7~\xee\xed\x8c*\x9c\xd3|\xab\xb9\x00\xd0\x01\xaeC`\x9ec\xdc0\xb8\x99n\xda\xaa\x81\xcc\x15!\xa8\x05\x0d\xf3\xd1\xa74T\x93\xc7O\xb2\x08\xce\xc9\x98\xa4\xa3FF\xacWt:\"\x1c\x0f\x89\x1c@\x9a%\x97\xe2A~\x8c\x8e\xe4u\x0b\x10>.k\xf4v\xdd\xd8\x19TC\xb6\xf6\xd7\xb6\x80\xceH\x9c\xf7\x161\x0f\xda\x0dY[Xj\x96\n\\\xd2T\xc3\xea@\x11\x9b\x01\xd1\xc4\x82b\xef?\x9a\x8d\x17\xbc\xd8P\xa8\xd7$\x1e\x8f\xc9\xcc:\xc1/|\x84\xe7\x18\x1d6]\x82\xa7\xe7&\xa1%\xfa\xc0\x18J\x04wSxjou\xe6}\xd6\xc1\xd4;\"\xd7zF1\x06\xaa\xd6%T\xe6\xd8\xa2K\xbb\x15\nk6 m3\x8c{\xef\xf6\x98\xd6\xb6\xcb*\xb4\xf8@\xc3\x97\x02\xef\xb0\xdd\xd7\xd6qv02P\xa2\x90Y\x01\xe7A\xad\xfco\x963h\xdf\xfd\xff*\x8c\xa1\xb1\xed\x7f\x13|\xe1\xd9\xd3\x0elAg\xfa[p\x85g\x0d\xee0\xdb\x98\xc2\xc9\x95\xae\xe7\xef\x8e-4\xf5&\xe7\n\xad9\x8e`\n\x1a\x0b\x1f\xce\x13t\x05\xff` \x9dX\x82\x1f\xa5\x7fc\x96\xa0Z\xfc\x07K\xa8\xfcZX\xc2\x8b\x06w\xc3\x7f\x0b\x96\xd0\xd8\xf6\xbf \x96\xa0\xdd\x9e\xb5\xb3\x04\x9d\xe9o\xc1\x12tS\xffNXBSor\x96\xd0\x9a\xe3\x08\x96\xf0b\xfa\x81,AW\xf0\x0f\x96\xd0\x89%\x84\x94\xdf\xfc\x8dy\x024\xf9o\x8c)\xd8\xe46\xd3 \xb3f\x89\x0d\x00\xc50\x00\x14\xa8\xfaT\xea\x8b\xe76\xf5\xf33\x9b\x8a\x9e\xe9X\xd53\xdd\xd1Q\xb9\n\xfeR\xeb\x03\x9b\xa1-}-=mH\x0fZY\x98\xe7Z\xc6\xc2u4\x85\x97\x0c\x1a\xc8\xbb\xc8\xc9;\xeaZ\x03\x18\x89j6\x8a\xa1\x95=\x97\xaaU\x0f:\xdc\x16\x81\xd2`5\x0f\xf7\x9a\xfa\xa8\x10\x1e\xeb\xab\xa7\xcf\xc85\x8c\x02\xf4x\xaa\xf0\xe3i!\x9a\x1f\xb6\xee\x80\x91\x16U\x10H%bt;o\xda\xd1\xd5D\x85\x1c\x91u\xe1\x0c9>G\xa7\xb0\x1e\xc0\xc7\xfb\xda[\xad\xad\x80\xf7\xe3\xdc\x15\xf3\xc9t\xa0\xd0\xbc\xbe|<\x1a\xc1J\x9d\x91\xcc1!4\xc25\xe5t\x07\xbff\x81\x1f\xa63\xe27\x10\x97\x07\xd8Z\xe4RO\xf5\xdap+\xe2l\x9a\x0f\xce\x12\x17Nm\x06uF\xa9C*&\xb0\x01\xc0\xb1O>@\\\xfb\xbb\xdcW>z\x84\xfd\xd3s\xa4\xbax]7\xb7\xb0\x01\x05\x90\xad\xa3C\xea\xd3\xfe\x1b9\x7f\xb3X,\x07\xfd\xc5b\xb1\x18\x00\x83>9\xcc\xf9U\xb6(?K\xd5\xb1\xf8\x80\xcc\x18s\x08\xe3\xdc\xd4\xde\x07}p\xfc\xe1\xc0O\x9du\xe0\x87+2_\x0e\xcc\xee\xac\xfe\xbd\xe0V\xd4E\x0e\xe2\xc3\xe8Xv\x0cR\xa7\xcb\xeb\x87\x84\x8d\xac\xac\x1b\xdc=\xd6\x1c\xa1\xba\x17S\xbd\x93s\x7f\xa9\x06\xaf\xde\x03\xa8p\x96W\x9d&\xb8\x9d\xa9H\xfe\x95%ZXCqm\x07\x90\xd9\x08x\x1fc1\x1d\xbbhJa/\x9b\x17M\xcbU\x1d\xc5\xba\x9e\x92\x97\x07\x8c\\N\x1c\xf8ZM\x83 \xd6\xad\xb54EGo\xb9\x16\xd4\xa60\xc8~9K#k\xa7\x93\xe5v:\xf4\x82\xf0\xe3\xa3\xa3\xf3\xc3\x81\xd7\xa6\x0d\x02}\x87\xa2M\x81\xd5y\xf7\xc0\xeahG\x04\xfd\xd4\xe4\x8e\xab\xe1B\xd7\x8a}\xae\x96cT\x11k2\xe3\x05\x10\x05#-\x12\xe1\x1c5\xc65\x8f\x96\xcd\xe4\xaf\x1bMk\xaf\xfc\x12D9\xad\xaah%|\x0e\x82\x11\xbb \x86\x8e\x98\x1e\xb9\xb4\x08Y$f\xe4\xacN8\xda`\x84\xa8\xcd3\xe2\x82\xb1\x94\xb1\x99~\xcf\xe3\xe5\x04\xdan\xec\x08~\xd6\xd2\xc7\x87R\xf2\xd8\xc1\x80\xb3\xd57\x0f\xa0\xf1\x05\"\xcaK\x04\x94~\xc4\xc0\xe4\x05Y\xe4\xecY\xd5u\x99\xd1\x99|\xe6\xd0\x99\x14\xe2\x8a\x9e\x8d?\x9f\x9c\x80\xf2\xf4\xc9pqzum\x15\xa6\xc3\xdf\xe49\x96\xfd\xebY\xfe6^\xfe|6z1}_\xf8>\xb8\xee_\xcf\x16\x93\xa3J\x0c\x9e\x0c^\x9e\xd6\xf56\x05\xd8&\x8b\xf1\xf2\xe7\xe9\xe8\xfc\xf9\xfb\xc1\xac?\x7fs\xf9rqwv6^\xdc\x9d\x9f-U\xd9\x87\xf3\x91\x92n\xa7U\xc2z\xd1\xa8}\xd0\xd4\xa3_\xa5\x16\x9b\xa2\x13\xaa\x97\xbd\x82(\x04\xaa\x90H\xab\x0f)\xb8\xab?\xe9s\x9b9\xab\xc5\xa1,\x94U\xbb\xa1l~\xb6\xd4\x8dL\xf5\xd5~\x0f\xac\x08\x02\xb5\xe7:\xb1\x02C\xd1/W?(\x8ba\x1dd\xef\xd6\xfd\xc3\xc1]Be\x1d\x1c^\x96\x02|\xe69(\x8e\xd6[\xba\xc2S\xb2\xaa\xe3\xc3\xa3[\xed\xb2\xcb8\xb0\xb2\x87zF\xf2[\x98\x03E\xedN04i\x94\x874\xb5\x13\x986M`/\xa4~ b \x87m\x93\xe9\xfdc2K\xbf\x8f:\x99iu2?\x0e\x91.\xd2\xa6y\xcf\x8b1N\xe7:\xf6\xeb\x8e\xe8(\xa5\xfa\x0fD\xe6\xa4\xab\x18CwR\x0f\x0b\x99?>\x04\xd6\xf48\xfe\x05\xb7u\xf0\x17#\x94\xfa\x18\xffs\x0d>\x1d\xads\xbb\x8d\x80\xb2[\x16\xc3\x1f\xfdo\xb2\xd3\xd1E\x9f\x9ec\x04R\x81\xd9\xd4_(\xee\xd3;\xf8\xa3\x9b\xf6C\xfcW\xbfE\x1b\xa8\xc7O\xf0\x95\xfb\xa9\xf9;Y1f\x13'w\x89W|\xces\x05\xb7\xef\xd4s\xb0\xc6\nq\x19\xc0\x13\xf6-Lyb\xfeB\xa9P\xfc\x84 Y\xa2V\x85z\x8c\xd8-|\x8a6\xf8\xc7\xc7\x7f!\x16i\x14a\x7f\xe2\x84\xfe\x94\xb1 \xf6n`+\xa4\x92\x92\xd8DD\x85b\\\xa4\xf0\x9e2\xbe\xf7=\x86\x8fij\xe2\xa1\x9a\x81I}\xb6\xc7\x8f\xbe~G\xb8\xd2\x10\xffD!&\xc74\xb1C`_ \x0b\xfa\x84\xec p\xca\xa9\xfeD\x188V\xe8\x19\x12;?\x0dY\x9a\x82\x06\x8a\xf4D\xf4\xf4\xfc\xd33x\xc2\x16\x05\xccr\xc6\x01\xae=\x0bC\xe8/\x0e\xc1-\x86t\xbd\xf3\x10j\xf5w\x9c\xa5L#\xca]\x18\xf0\xc4\xb3`\x15^\xb1T\x88\xd3\xf8\xee\xe9\xe7\x93\xe7g<\x7fDd\\\xfbYx'8b\xe8&\xc1?\xf8 \xb1\x82j$\x16\x82z\xbb\x90E\xf8v\xab\xfe]\xb1tG1\xf4\xec\xca\x17^\xeccX\xde8\x80\xb9\xf6h\xa0g\xdd\xdb\xf1\x18\x83\xda\xe2\xd3\x98\xdd \x16\xa566o8f{\x16\x89\x15\xf7\x05\x1bS!X\xb4f\x98\x1d \x0c<\xee\x01\xa8u\x10\xd1q\x12\xd0\xfb\xd4\x8f\xb6\xda\xbf\xa3IR\xb9\xa9\x1f!\xea\xaf\x05T\xbe\xde\xaf\xd4\x1f\xb6>\xbfQ\x7f7\xd4c\xc2GX6\xcc\x84\xf9\x8d\xb6:\x84\xaf\x9f\x02zma*\xb7\xbe\xc0?\xef\xc28\xe1\xb1 \xc0\xbb\x154\x80\xbav\x1e\xae\x04=+~\x82\x7f\xb8^\x13\xde\x0b\xfd\x17\x97\x85@L\xfa\x91BK?\xe2\xdb\x0d\xbbO(\x16\x08h*60\xe0j\xd5\xe0\xa2\xa0[\x8dD\xa1M\xe17:%G\xa5\x10\xeb\n\xd3\xf1\x8e\x05zYE8wa\x16\xea8\xbf\xe1\x1e\xa0\x03\x19[=\xc4\x88; \x0dB\xfc\x9bPN\xdf\xbd\x03\xa4K\x02*L4\xe3\x84\xc7w\x10\x1f8I\xef\x01\xce\x9f2\xc6!\xc1,0\x96\xc6\x19\xc7\x95\xc5\x11iyz\x1fA^.\xf4\xb2a^\x1c\xad\x03\x7f\x83KL\xaf\x88t\x8bk\xf0\xe6>\xc1\xf4\x10\xa6*\x8d\x835\xc5\xc0\xc5I,\xfc\x0d4\x96\xe2\xc4\xa4\x82Q\x00+\xc5\xee\xa8\xd74\x01\xc7)\xb0\xc2\xa2-\xc0\x94\xad\xa1\x81,\xe2\x8c\xc2r\xcc\xc4\xf9\xd9\x19DaVx\xc6}D\xd0\xbd\xcfn\xc79\xf4\xb7l\xe5a\xf6[Aq\xf5\xdd{\xfe\xed= \xc3\xdd\xc6GD\xbf\xe3\xf0\xe9>L\xb7\xbc\xb7|8\xff( \xf9\x9f\x0e&\xbf\x7f\xfd\xea\xdb\xb7\xaf\xbf\xf8\xe7\xb7\xdf\x7f\xf5p\x01\xb8\xa2Eq+\x17+A\xf8I~CE+^\xc8Ic0}\n\xc7\x1aE3\x05\x14\x97\x9f\xea;\x8dN\x97\x0e\x06\x17\xa7\x15\x8d\\\x8a\xe5@u\x04\x98\xac3?\x9d\xbeW\x99\x1f\xce*\x8b\x97v\x1c\x04\xab\xc0\x0f\xeb\xfa\xf8\xa7\x9f\xb9\xb9\xa3w(Z8\xde8\xdd\xb8/\xa9<}\xee\xd6Iy\x9a}\xbai\xa6\xbf1f(9\x93\xf1\x0c'+\x1cI\xa0rA\xf1\xe7\xde\x1dF\xaa \xe6\xd3\xa5b %\xdd\x14\xb9&\xa0\xa1\xf8&\x12}\x95\xc1\xe85\x06#2}\x01\x01\xd6\x8b_Gd\x8aa\xb6\n\x97\x81\xfc~\xa4j\xa1}\xa0\xcc\xb4\xff\xe2\xf9\xf3\xa7OK;\xf2\xa0\xcc\xb6\xea\xc4\x1am6\xc0p\xa8\xb1k)2\xe9X\xf1\x01\x05J\xb5\xa7%\x98\xf8\\eY\xb6\x00\xe1\x14\x95\\\x0e\xec\x1e\xfd\xc2\xfe\xeb\xca\xb3\xac\x05\xb5\x99c\xf2\x95\xe0\xe1\xf6[v\xa7>\xfd1k\x88\xca\x01\x07*iC\xc4\x0e\x1am\xbf\xe3l\xe3\xdf\xcd\xd4\x8e$\xdaft\xcb\xc6.\xed\x8b\x1f\xdd\xf8\x9b\xfb\xc6\xf8*7\xaf)\xdf21sJ\x03\xe2>\x89!\xa8\x08\xe3\xee\n\x809\xa63\xd2\xfb\xeb_\xfe\xcf\xbf\xfe\xe5\xff\xfa\xeb_\xfe\x8f\xbf\xfe\xe5\xbf\xb8\xd4]\xfev\x17`\xfc\x91(\x0b\x1cJ\xa8\xfc\x8clF\xce\xab\xa7\x1c\xa5W/\x0e\x938b\x91p\x8e\xb5\x17s\xe6JW?\x9e\x05\x10\x8a\xa5\x07\x9e\xe4z\xa3<\xea\x8b\xda\x1c\x19+\x19|\x03\xc9E1\"x\xd7\x83\x88{\x1f\xca\x05v\xbb^\x8e\xaeV\xfc\\=\xd8\xa3\x0eA\xfd\xa0\xe7\x08\x83\xe8\x98mto\xd7\x05th\xbe72\xce\xf7\xd4\x06\xd9@`\x1aV\xcf;F\xd7\xc8 {;T2\x890\xb0}\x0f\n\x9fu\x90\xbeB\xd0\xa6\x91\x8e\xa5\xdb\x0dv\x1c\xc7\x83\xc0\x17\x02w\x94b\xa7\xe8\x00)\xc5\x00&y\\\x8e<\x14K5FH!\xc2\x87\x0dHR\x08\xef\x82\xbaP\x07\xfc\xbfr\xbf\xfd\x83,\x14?\xfe\xbb$\x0b-\xcb\xae\x0d\xab\xff\xce0\xc6q\x1d\xbe\x801\x8e\xaf\xff\xc0\x18\xf8=\x04cj\xe9\xe4(F\x82\x0c\xa1\x13\x0d\xfd8\xf4\xffCh~'0?\x94\xd4\x1f\xa2\xf1\xff\n4\x1d\xb6]\xf9\xd2\xe4\xc5}IU\x98w\xaffS\x0b\x83#&jf\x1e\xfez<\x8e\xeeQ?\xbf^s\x86\x07\x04\x943\xcc\xc5\x85\xef\xa1\xde\x97\xa6>N&\xcd\xd6>h=A\xc9\xbaZ\xfb\xf8\x07\x93|\x18\x99\x95\x1d\xda\x12:\xac\xe25\x8c&\xb6\xbc\xca\x84\xd0z{\x1a\xed\xf1D\xcb\xa3\x890\xca|\x16 T\xa6{~\x19\x9b\xbc8\xd0\x7f\xb6<\xce\xf0\xc4+W\xef\xe7\xa7]\x82\x1a\x1cZ\xe39\x18\xf3bNE\x8cZ}d\xe9k\xa6$ d\xf2\x1b\xd4\xf3\xfb\xf8\xdd\xc7\xc32\xcc\x05\xb5\xb0\x80\x99S\x0b\x06\x03\xb6\xf1Y\xb0N\x99\x8e\x11\xb5-\x00\xbf\xf1\xb7\x19\xd72\x01\x96P\xb2\x81>\x1b\xd0\n\xf1\xdd\x14\xfe\x05yl\x87\x87k\xa0X\xde=\x87\x7fA\xe9\xaf\xd6\x83\xf9\xab\x0f\xe2l\x9f\xf3\xf5\xa3\xfe\xc2,\xf8!\x0c\xbf\x1f%x.\x88a\xdbz7+\xa8\x04\xacw\xe0\x81mY\x84IP,\xa4x\xde\x12\x9aC6\x08\xe5\xa6\xfe\xfe\x94\xe1\xf1I\xc8\xa2\xcc\xfc\xf5\x05\xf6>d\xbaC\x11\x9e+F1\xce+\xceN\x9c\x08\x0bil\xc7%\xce\x84\x06\xcd\x9c\xad\xe1\x9fxk0\xef'\xf5\x0f\x9e\xe9q\xc8\xc8\xb3\x15\n\xb6\xf0\x0f\xb5\xe7\x00\xa6\xca\x94\x05\xfa<%\xdd\xd1u\x0c\xc7IiH\x03\x80\"\xd7\xc9\xa7 \xf5\x10\xdc4\xa1XPp\xff\x86\xe9\xa7\x18\x89N*\xee\x11\xdb1\x08]/\xcd\xc2\x90\xe2)\x05\x06\x9d\xd3R\xa7z0\xd8,`$\x05\x0b\x93@\x1f8*\"`V\x90P\x13\x0f\x0f(\xb4\x9a\x195gG\x82\xe3\xbf\x14)\xa0\x80\xbc0\xd6\x19\xf4`\x8f\xc7<{\x7f\x8d\x07\xb3\xb7+\xdes\x04\x8a\x03\xa3\xb0^\xba\x87^\xe0\xd2\x0d\xc46\xb8GQ\xd9<\xafQ.5\xaff&i\xe4\x87T0/\x0epm\xe8\xf706c\xac\x13\x04\xa7Qj\xd0\xd7\x92\x81\xc2\xea\xf5\xb9&\x16^\xe0' \xc5.\xaf\xd9F\x0b\xd1)\x9c\xe5\xb0 \xf0\x93\x14\x17\x87\x1f\xd8E\x81\xcb\x04\xcf\xcb\x0c\xdc\xf0`\x84\xe9\x1b\x86G\x9a\xda\xf6\x1e\xe8\xaf\xfdK\xf9\x96\xd3\xb5\xaf\x97'\x9cnq|J\x11\x97\x99\xa0\x862\x84\x06\xb2\xc2_\xa1+O\xe2\xe0~\x1b\xdbG\xcb5\xe9\xda\xa7A\xb1 n\x90N\xe01q\x8e9\x10\x01\n\x9e\xee\xc3U\xac\x0fq\xef\x84\xf9k\x1a\x05\xabzx\xd0\x1d\x14\x061\xed\\\xef}\x06\xe8\xbc\x87\xae;f=\x82Y\xdf\xb0\xdf\x06z=o\xd8\x97j\x12_Q\xc1\xfd;\x93\xa0\xc5\x88\xd70{z\xb819\xd5\x94U\xbdF\xfb8\xd8\xb3b\xc9\xdf\xf9\x9bM\x96\xb2o\x958\xa3\x99\xb2JL\xed\xde\xf3\x15\xd2\x0bH\x144\x12\x90\x13S\xbe\x0e\xe2XC\xf4u\x16y_\xe4\x8f\xbf\xcd\x1f\xff9\x7f\xfc\x1e\x1f\xff\x99fi\xea\xd3\xe8\xb7A\xa6\xe1|\xc5\xf8\x96\x15\x1e\xff`E\x8aW1Ovq\x10o\xef\xf1\xfd\x8f\x9b\x8d\xa1\xc5\xa87,\x80\xf3C\xc2\xbc,\xa0\xbc\xdc\x97\x1f\x92\xb8\x98\xe9\xb5\xb1\x84`\xaf3\xbe\xca\x02%\xb4\xb8F\x1d\"r\xf4B=\x8f!\x8b\xb4e\x89z\xe6\x1c\x97P\x08\"\x0f\x9a(l8\x05\xc4\x0f-^\xe3\xe9f\x08\x04\x99\xad\x91\x04\x84a\x16\xf8h\xea\x81\xa7\xb0H\x92\xd1\xd8!\xdektN\xe8z\xad\xabMv4\x121\x92b\xae\x89L\xc8\x91\x00\xea\x83\xdc\x04\xa8\x1e&\xfc\x84\xe44\xbc\xb7\x98\x1aj\"\x17j\xd2\xa6\xde\xcd\xa3%s!\x92\xb7\xd0\xa0p\xa8\xa1\xcd\"\xcd\x90\xf0 \x00t\x8cU\x0cc\xf5k\x14\x8b\x1c\xd2\x1a\n$\x9e\xc7\xb4m\x80%\xeb4\xf0\xb7\xfa\x01\xbfd\"V\x12q\xc0\xb4,A\xbd\x1b\xc5`\x10\xefW[K\xbcV1\xd7\x90y,\x08\xd4x\xe9\xf9V\xafj<\xcc\xeb\x8ey78\x94V\xc0\x08(2!/`Hvm\xad^\x8cB\x82\xfa\xab\x97\xa9\x17\xc7|\x8d\x89\x9a:A3\x8a!\x8cW4e\x86g\xd2\xd436>\xe6L\xcf \x84M00\xd3w~\x98!`\xaa\x8a\x8d\x9a \x16y\xf7&A\xd59Nw\xfe\x06\xea[1\xbd\xd2V>\n\x1e(!\x16\x96/ZB\xa9\xbfc\xc3o\xe1E\xed\xffz\x95u\x1d\xf3\xb1Z <\x89\x03j7\x1f\xf5\xe41\n+i\xfe9\xe1\xb11\x9e\xc3\x04\xce\x14)4\xf4\x05f\x07\xbb\x80\x8b\x1d\x12Pf\\#k\xf5\xe2\x08\x18'&\xf1\\\xa8]\x03\x97\xd5Y\xf7~\xaa\xf7,\xc8\x14\xd9z\xcbB\xcd\x06Y\xc0\xf6\x16j#\x04\xf8(\xfc\xaa\xbf\xe3XQ<\\\xf9\xf0nF\xa0 z)V=\xb6#\x82\xaf\xc5bq$\xc6\x1b\x1a\xfaA\xfejP\xdb\xbe\x8c\xe9\xfa\xc7,\x15y\x9a\xe0L\x8bA\xfa]c1\xbc\xed)\xf7i\x94\xe7\xbe\xb5h\xb6A\xd9\x03Z\xda\xc2\x06i\x0b\x1b$`\x9dc\x83?E\xb9\xd0\x08eY\xe4#\xe34 %i\xb5@8u9M\x1a\x950Y\x9e8D-?\x82va\x99\xdf\x00 7\x98\x00;\xb5\x1b\xd8\xa9)\xb1L\x17\xbaa\xf7\x89\x929R\xfd\x92&\x10X]\xbf)n\x00\xcf\x96\xd4\x02%\xcd\xc7,`\x8a\xd6\x8d\x0b\xecI\xd5\xcd\x82\xd0\x8ac\xf8\xae:\x99S\xe1@K3\xf9\xe4\x05\xb16P\x1c\xb3\x84\xef\xbc\x1d\x8d\"\x16\xa0\x00\x84=\xbdw\xa4Asw\xd0\x8f;\xe8\x07\xca\x1f*7\xfc\x03_\xee\xe1\x0b\x18|\xbf\x8b\xe3\x90Fk%09d\x94\xac \xa3\xf4P8\x81U\xaa\x97\xb4\x15{Vl\xcf\x02-k\xdbM\x9a\x17\x07Y\x18\xa56\x13\xbe[r\xad?kQm\xcd\xa28\xb4Y\xd7,\xd1:\x0d+\xcb\xe7l\x1a\x1es>\x07\xbbG\xf5\xc05ykbA\x81\xc2\x1f-q\x17H{\xc4\xc4\xce\xf7n\"\xad\x17\x0b\xecV.\xb0\xfaT\xb5\x05-\xef\x83T\x8a]g\xea\xc50j\xf5\\\xe0\xba!\xbd\xb3_\xfc\xc8>\xc6{\xb55\x81U\x03\x8dFqNL\xa3,\x1f\x07#\xad\xf3\xf8\xd6\xa6\xf1\xf8\xd6\x8e!\n\xcc\x06w\n\xe23\xb7\xbd\xe0\xb6\x17\xb8\xe7\x05\x03\xc5\xfc\xb5\x00\x95\xde\x13\xfb\xef\x98\xde[\xf8Z\x8f\x07\xe8e\xb5\x80 \xb5L\xc2\xbeh\xe2\x03\xa2\x88V\xe2\xe9 \xffV\x96L\xb3\xa4\x9ar\x1f\x86Lp\x1f\xe4\xf1}N}\x0e\x8b\xcex\x83\xe3.\xf0\xa3\x9b\x99\x99\xe3\xbb0\x98i\xebzH\xb7\xe2\xba\xfa`G\x03\xaa\x9cA\x8e\xde\xb2`?I\x8a&\x8f\x81\xd3\n\x89T#7\x9b\xab\x9d\x17$\x1a\x8f/\x06\xa8\xe8\x8c\xb6=ru\x05\xa6\xa6\xf1\x86\x88\xb9\xb9}:\x87[\x98\xeaO\xe5f\xd9\x88\xb0\xb9J^6x\xdf2\xa6\x9b\x95\x83\x0d7\xe4^\xbb-\xae\xebp\x93h\xf5\x16^\xa6\xad\xb7\xaf\xbdc\xfb\x11a\x03\xf2\xc7\xd5\x8f\xcc\x13\x85\xf0\xf2;\x9a\xfe\xf16\xfa\x8e+\xd1A\xdcO<\x1a\xc0\xe0i\xcf\xd1\xba\xd7l\x1e-\x1d\x9eT\x8c\xc9N\xc3\x91\x0d\xd1\x80o\xc0\xbb\xdc\xcf\x8b\x9f\xe7\x8bt\xf1\xc3\xf2\x89\xd4\x7f\x17\xef\x17\xefO\xb7a\xbdG\x89*p\xf9O\x95\xec\xff\xf4\xd2\x99y\x0d\xd6jk*\xe8x\xbe\x18/n'\x8b\xec\xec\xec\xb7\x9f\x8e\x17\xd9\xd7_\x7f\xfd\xf5\xf2\xd4q\xf2\x08%\xd4\x12\xc7\x12\xcb\xe1'\x8e\\{\xc8\xd5\xbf\x9e\xe1\xff\x1b\xb9\x13\x03\x91\xa4\xd7\x12o\xd6H\xc1\x02\x89\xd7-\xa4\xe7\xaf\xe5]\x98$\x83\x99\x9c\xbf\xa1\xe3wK9\xa7\xe3w\xc3\xc9b\xbc\x1c\xf6\xafg\x90\xa6\xdefK\xf9\xc9`P5\xb7#\xda\xb3\x154\xb6\xb8\x1d\xe2\"\x93`\x829se\xde\xaa\xccs\xd5\xcd\xb3\xb3\xb1\xfas~\xa6\xfe\xfd\xe2l\x91M_|\xa6\xfe\xfd\xec\xec\xabEv\x8e\x9f\xcf\xcf\xce?W\xff>\xdf,\xb2\xa7ggg\xcb\xd3m\xbd\xca{rEz\x06 \x8b\xf8\xff\x03hf\x15.\x18%m\xed\xe3D\xc9\x0f\x8a\x86\x90\xeb\x03\x16\xe5\xa4\x803XC\xdd\xa9\xee{2\xeb^\x0b\x03\xc0\xda\xe1f\x13\x10\xd1x\xa6\x18,\x18\xe1\x15\xbe\x81M\xa1\xee\x86]\x13\xe4:\xef\xec\xac\x05\xd2&\xea\xb3r\xc3\xedoH\xff\x0b%\xb5M\xfc\x14\xfe\xf6Y\xa3\x85\xa1%Sj\xd1\x9f\xe1=z]\xc6\x98\xb0_\x10\x01\x11\xe7\x0d \x13\xc3\xe1\x80Ds\x81\xebU,\xeb\xcb\x95\x14\xdc\xf5\xd5{\xd3\xb4\xba\x11\xe4\x0d\x8f\xc3vG\x80\n\xda\xb7m\x07\xae\x85:{J\x00\xd9\xf8\x11[\x17\xe7\xec\xd6\x8f\xd6\xf1-\xb9\x06{\x002\xd3\xef\xe5&\x9d6\x83v\xe4o\x9d\x8d*\xc8\xbe\"W\x84\xf2m\x06\x86`&\x92\xfcK\x8c\x0d_\xf0B`\xb3\xcc\xcf\x96\xe4\xba\xfc:#o\x9b\x02\x9a\xde\x95\x0c`\x9b&\x95\xe4\x10\xdfV\xc7\xd2\xfc\xde\xbb\xbd5\xdcM\xf6\x8c\xa7\xaa\x8bW\xa47\x9d\x9cM\xd4\xae\xfan\xc2Y\x18\xef\xd9Z\xc7\xbd>\xf9\n\x9ck|5Y\xc7\x1e\x80\xad^?\x87~\xe5i\x93(^\xb3\xd7\xf7 \xb3\xb6\x9bw\x13?\xfd!K\x92\x98\x0b\xa8\xead:\"wu0\xd4(\xfe@\x8aU\xb9\xc7\xe2\xcb\x06\xbf~\xeaw\xd3\xf2\xed\x8b\x0eu\xff\x11\xf2\xfcN\xe7\xf9\x9a\xd3ms\xde\xef \xef\xef_\xbf\xfa\xf6\xb5>p\xfc\nO\xa5\xdd\xd9_C\xf6?\xd4,\xad\xcd\xef\x95\xfd\xfe5\xe8\x83\xdc\xb9\xbe\xc1\\4dk\x95\xf5\x15M\xdc\xf9~\xb4\xfc\x1a(\xd27\xe4\xbaRLM\xddW\x93W\xf1;H\xfcB\x08\xae\x12g\xe4\x1bw}\x7f\x80v_\xb3\xbb\x86\xde}\x0f\xdf\xbfD\x8b|w\x96\xdf\xe1\xd8\xfe\xf1\xd5wp[\xda\x9d\xe9[\xc8\xf4?\xbf\xfa\xf6\xf7B$\xdf\xb3\x9f2\x966T\xf7\xa7r\x0f\xbf\x85\x1e\x96\x0b\x92\x19\xf9\xd6]\xf8'h\x86Ej\xff\xf6\xa7\xef\x1b\xfa\xfcu\xb9\x85\x9f\xa0\x05[\x86\xcc\xc8O\xee\xb5\xe4\xe4\x17\xdf5-Z\x85\xf6\xef\x14\xf5\xfd\xff\xd9\xfb\xda\xae\xb8m%\xe0\xef\xf7W\x0c~zR\xfb\xe05\x90\xa4\xb7\xed\x06\xc2!\xb0ii\x03\xe4\x02i\xdaK\xf3p\xcc\xaev\xd7\xc1k\xed\xe3\x17^z\xcb\x7f\x7f\x8eF\x92-\xdb\x92\xec%iz?\\\x7fHXk$K\xa3\x91\xe6E\xa3\x99`\x9c\x92\x8a\x88\xdc\xea\x18\xdb\x10\xc4\xff\x8f@\x98D\xd8\x16S\xfe\x08\xe8mBRI\xc1(c1\xc27\x94\xdb.\xd5\xc8\x87u\xf0\x15\xeb\xa0\x1eK\xbf\xc0\x0e\xbc\n\xa2\xc5\x92\xf7\x1b\x95\x14=\xe4\x8f\x08\xc9G\xc9\xa8\xf0P\xb0u=\xf4{\x84\x9e\x91\\ ${u\x7f\x1e\xce\x18\xb5\xea\xe1\x7fRZ\xef\xb7\x80\x7f\x83\x1d8c=\xa7in^\x97?\xa3T\xdc\x9e\x82\xe6\xae\xf6Kc\xa7\xffE\xf4\x85m\x10\xeat\xf0\xfdr\xaf\xdc\x88\x8e\xe8Ds\xf7\x8d!\xfd\x07\x8c\x8c\xa6\xed\xd4W\xb0\x03\x86\x95\xffo\xd8\x81\x89\xbe\xe8W\xd8\x81\xb9\xbe\xe8_\x18wM[D\x08\xec\x80F\xa4cON0(\xa0\xb6,aez\xcf;@F\x05;\x10\xbb\xffy\xf0\xe1\xe2\x03\xa3\xceq\x98\xbbW\x188\xeb\xca\xcd\xf1\xdf\x04\xffM\xf1_\xeay\x06\xdeH\xed\xdf\x89\xf4\xdf\x89\xb0\xd5\x10\xff-\xf0\xdf\xcc\xf8\x85\xd0\xfe\x85\xc2^\x9c\x11Cb\"\xc0[\x81\x96\xc21\xb1\xb0\xb3\xa9\xadpi+\x9c\xd8\n\xe7\xb6\xc2\x1b[\xe1\xc2V8\xb3\x15\xde\xdb\n\xafl\x18\xba\xb4\x15\xde\x12\x8bB;R\xc8\xa2r\xa0\x91.A\xd2\xa3\xa0\x8a\xf7PZ\x93T\xef\"\xe1\xe4\xc3\xbdD>\x98d7\xed\x97J\xcf\x12\xe1(V\xb9Gq\xa7\x1aSkg\xb5\xd6\xb8a\xb99}uh\xf8\x98R\xc6*\xb1\x97\x85ZI\xfb)\xa5LVB\xfaw\xde\x9d\x8d.\xdf\x9e\x9e\xbc>|3\x92\x9fz\xf2\x04\xa6\x81\xfa\xde\x17\x9b\x14\x0f\x82'\xfa}\xb9wz\xb8\x87\x0d\xfab\x9b\xaa\x17\x1f\xec\x9d\xcbb\xdc\xa8\xe4\xfbw\xc7?\x1f\x9f\xbc?f\x8d\x9f\x9f\xec\x9f\xbc9C\xa5a\xcb\xe7;\xd648\xdb{=\xba|}rz\xf9\xd3\xbf\xde\x8dN\x7f\x93\xa5\xcbF\xe9\xf9\xe8\xe8\xed\x9b\xbd\xf3QY}\xc2\x01\xde\xffx\xf2ftyp\xb2\xff\xeeht|.\x0b\x17\xbc\xf0tt\xfe\xee\xf4\xf8\xf2\xe0\xe4H\x16\xcc\x9a\x05\x97\xafO\xf7~P\xab\xde\xb7 \x0e\x8f\xde\x9e\x9c\x96\xe57\xbc\xfc\xf5\xc9\xe9\xfe\xe8\xf2\xd5\xc9A\xd9\xe3\xab\x1aR\xce\xf6\x8e\x0f\xcf\x0f\xff\xcd\xbav\xe4\x8b\x8dI\x96\xfd<\x1a\xbd\xbd\xdc?9>\x1f\x1d\x9f\xfb\x9ciV\xc4\xf1\xee\xf4\xf0\xf2t\xf4\xc3\xe8\xd7\xb7\xac\xe1\x9c *0\x0c\x11\x91i\xd5f\xfc\x05\xdfa7=\x9cZ\x0c\xecI\xb4\xbc\x0dy%\xa7OT\xdb\xf8Z\xb8%Uh\x80\xd8M\x88\x0f\x8c\xd7\xc6.%>D<\xb3\x97\x84\xcbnf\nX^\x82\x85\xe5_Y\xab\x02\xd7Z2\xa5^\xd2]\x8f\xed\xb3Gj\x97\xd2\x12\xb2P\xebx\xb8\x9a\x0e\xf8\xa2(\x87\xbe\xb3\xc3\xa4\x88\x12\x11c7!\x1e\xd6b-U\xf0UmF\xad\x08Oy\xed\x88\x94\xbf`\xecRQ\x9b\x12\x15\xbe\xaa\xcd&\n\xc9S6\x13\xbbgD[\xe8!\x01\xf0\x8e\x95.Wr\xee\xb8\x85\x94\x1b\x96RB\xfe \xb8*\xab\xb7\xc2\x82\xca\xcb\xdc\xa9\xe7\xf3\xadu\xaa\xdd\xfd\x0c\xdc\xed\x84\xf46\x18\x94J\xbe)&\x82\xfa\x08\xbf\xeb\xa1\xc6Z%\x9f\x07K\xce\xb1<\xbd\xb7\xf4\x04dv\x08\x92\xa0<.:\xb6?\x8f\xe2\x89\xc9\x9c\x01h\xd1\x1b\x87\xf9x\x8ey8\xbaZ\xa7ENR&\x92c\xe8rs\x93\xab \xfb-\xe9\xba\x9e\xac>\xdd8XiF\xd8S\xfa\xf0\x0c!g\x1a\xd3\x9e\xfc\xcd\xb0\xc8$\xea\xce\x16\xa6)]\x0c\x1bv\xf6\xe6\xf3\xd0c\x06\xac\x94\x06\x9f86\xb3p\xa1>\x9f:\x14\xf3\xc4\x89\xae\x97\xd85\x9a\xd8\xf4\x9d<\xef\xbf&\xa5a\x96K2\xf61\xdbNf\xe4\x13M\xc1\xbd\xe1\x1b\x12\xca\x04\xdb|$/\xb77\xc4\x1f\x0e\xac#7\xb8\xee\x9a\xbfn\xeae\x0f\xfb\xc8k\xdb\x92\x85&\xd1\x98\xd1\x0ej\xb4\x03r\x0b\xef\xcc\xc3dO\x1a\xa4$[\xd2$C\x1b$\x1b\xacT\xb4\x1d\x1f\xd2\x80.I\xe2:?\x8c\xce\x1dq/e\xc86\xe7\x0d\xc6\x18_\x8c\xe7a\x9a\x91|\xa7\xc8\xa7\x83\xef|D\x89/\xd2\x9a\x06\x19I&.#@\x8fGE\xa9>\xf3\x08Jb\xd3\xb1\xef\xf5\xc0%\xfb\x92\xcb\x06}\xe0\xf1\x18\x83\xafS\xba8\xc33D\xb6\xcf8e\xdf\x9d\x9ek\xd3\xdc\xa7\xf2v\xfc\x93'\x90\x97\xc6 !\xa8\xe3\x95y\x9e^\x94uIg\xdap\x1d\xc7\xf3\x82+:\xb9\xf7L[x\xa2\x16L\xa34\x93\xcdc1\x13\xc4k\xdb3\xa3\xc7\xf7\xfc\xbc0G\xe9oW\\\xb1\x81\xa1\xb8\xbf\xe4]l\xb6\xefw\x81\xde\xc8]7\xd70 \xd8v\x8c\x00\xca-\xads\xe2~\xbd\x9d\xdd\xcc^n\xcf\x80\xa2\x8f\xf0\x0e\x06~k\x0f\xd3\xf5\x9c\x97\xdb\x1b\xb3\x97\xdb\x1b\x0c\xfck\x03#$\x01\x86\xdb:\x13.\x19.j\x91\x18\x82\xc9\xbd\xe62\x82\xbe\x9e\x9d\\\xdczW\x97/\xb7Qo{\xb9\x1d-f\x90\xa5\xe3\x1dg{\xa3\xf1\xe6\x0eh\x82^\xf2;aL\xd2\xdc\xdd\xf266\x9c\x97_{\x9e\xa6\x83\xc0\xd4T\xae7\xed\xf3N\xea\x11o'\xb6\x07W36\x86\xe7\xa3\xfe{\xa3 \xd4\x1f\xc5Ir\xc3\xde\xf9\xe7\x9fl\xd1\x12\x1f\x8e\x82\xb3\x1fO\xde_\x8e\xde\x8c\xb8\xac/_\xec\x9f\x1c\xd5_\x9c\x8f~=\xf7\xbb\xa9\xa1\xf1\xf9\xa3\xe0\xf5\xe1\x9b\xf3\xd1\xe9\xe5\xde\xfe\xfe\xe8\xed\xb9y\xf5\xd5s.\xd5\x8b\xb4\xaf\x0fWFE\xa9\xfd\xee4\xb4\xdfs\x8d\xf6{\x8e\xb1l D\xe8U6&t\n\xe70\x14\x07\x9d\xa6\x86\x88\xa6!\xc2\xd5h')\x16W$UM\xdd\xa4<\x02\xe2\xc7\xba-\x9f\x07\x0ep\x1c.\x0c)O\xf5\x88\xf9\xd8\x12\xb3\x1a\x973\x9b\xcf\xcf\x17\x04]+\xd8\xff\xc1\x94\xa6\xa3pN<\x95\x0c\x8eQ\xfdT\xdf\x9cb\xe8/\x8d\xcfJ9\x7f\x86 \xce\x03\xc6\x99\xf6\xab\xe3 \xed\x91H\xaer\x07\xcewJi/S\xfb\xf1\xb1\xb3\x89R&\xb3@f\x8a`\\\x05\x969\xe1\xb9\x1al\xf9\x7f\xa5\xf4Q\x91m\xddA\xa7{J\x8a%M\x1a\x13\xc2\xe7\xa3\x83\xfd\xf3\xf3\x8e!\x18\x8eH\xe4\x13\xc61\xbd%\x93\xf3p\x96\x0d!\xb1\xa9f>\xac%\xe4\"\xfd\x80\x01\xff\xd8\x1f]\x8b\x80\x8d\x80\xab\xb2k#\xach\xc2/ \xa2$#i\xbe7\xf9\x18\x8eI\x923&\xdeG\xc4\x01\\i\xed\xba\xae\xb37\xcdI:Bg:\x06\x90p\xc1\xe0\xb3\xc9\x94\xcd\xf97c\xadk\xff]\x9b\x12\x1eT\xb0%\xd3\xf0\xd7\xca1]\xf9C\x0f\xbb\xb6\xb1\xbd1\x0br\x92\xe5.Q\x97\x10\x97\x0eV\xd2\x9d*M=\x18\xc74\xe1\xaa\xa0m\x03\xaba\x99'9\xa9:P\x06\xe8c\x1d\xf4\xc1y\x12\xe7/\x1c\xcf\x93\xa6*\x99\xeaA\xdd\xf7\xb9\xb8X\xfeS\x1fO\xd9\xde\x0f>8\xc0$G\xf9\xe2+\xfe\xc2\xafW\xa8\x82J~\x01,\xa8\xdf\xdd\x81\x84\x0d\x93-\xe2\x90\xd1\xa3}[\xddZ\x85\x0b\x9c\xae\xc8\x05V\xd6\x07\xedpiO8\xda\x13.\xea \x17\xf6\x84+\x1e\xcd\xf2\xca]\xbe>;<\x82j\xc5a\xba\xb6>\x86\xf4v\xcc\x15\xdd\xc3\xda\xe4\x1b\xb5.\xa0\x89\x0e\xfa\x970.z\x82_\x13\xb2d#\xd2\xc7ki>\x82\x15T(\x18\x0253\x04\xd0\xebJ\xea\x83\x8ebl.\xc2\xd2\x11\xac@_\xd6n\xb4\xc8\xec\x92(k\x84\x17\xc5\x07/H\xc2\x05\xf1\x91\xf4\xf2\x00\x0f\x98\x82<\x8d\x16\xae\xe7\xf3\xa0\x85u\xbe\xeaC\x16H\xd4\xf2\x04P\xfc7\"\x8f'\xeb\xc8\x02\x89\x1e\x91J\xb3\xc9m\xf7\x94\x18\x96hJ\xe6_W\x1a\x92\x07d\xb8\x85Q\xe4o\x87G?8\xca\x8e&\x05\x9d0\x88&\x1e\xd29\xfb\x8b\x13\x14w^\xab\xbc]1\xa0]\x10.\x97\xf1=\x1e.\xbf%.?\x8e#\xfcG\xc2\xff\n\xcbL\x12\x91\x07/\xa1\xe0\xbcA\x95PD\xb5\x88\xa3\xc9\"c\xc8\xc7\x90\x12Q\xf7\xa0\x93\xca\xe1\xf1\xdbw\xe7\xbaa\xf2\xbb\x0e\n:\xf0f\x1d\xb7\xb6\x0bs\xf9\x05E b\xad`\x7fy\x1eF\xc5\x8d\x92B\xe3\xc7\xa0{\xd8\xc8\xb0\xb9D3\xec\xc4\x07\xc7Qp\xd5\xd9\xa2\x9d\xcb\x83\x18\xaeB(\x18)\xf8\nY6\xf6d\xad\x1c(\xa7\x03\xfe\x9b\x0d\xcfM!J`\x8f\xfd\x8d\x7f]\x13\xcf\xe8P\xd9|\xd8G\x05#d\x04\x87\xff\xa4\x9dl\xcf\xc3\xa3\xb6'O\xe0\xdf\\\n\xa0^\x8f\x99\x079\xfb8P\xac\xfe\xebc\xaa\xf7\x1b\x18\x88\xc1\xad\x95d\xc0\xa9`E\"\x00\xd1\xcc\x19V\xee_\xa7\x1chN\xf8\x18+\xa4\x12\x82\xb4\xd3w\xcc\xa0\xb6\x86\x97~\x15RPn\x0eT\x04\xc1\x1d{\xaa,0\xdc\x80\xc8m7kw\xe4\xc2\xa4 |\xe8\xa6b\xf5\xc1\xb0\xa2\\\xe6\xfe\xd7g\x18#\xa8\xe3L\xaby\xea\xd5@\xf7\xea\x82N\xd3T\xf3i\xaf\xf8\xd4\xf3\xd5\x93\x01\xba\xb4\xc8h\xea\xb3\x82\xb8\x0f\x9d\x83\xb1\x97\xb6$@\xad\x94alb\xa5\x03\xa5\x03U2\x04b?\xd7\x92wM\xfa\xc8Tl\x13:b\xed\x99\xa9\x07\xf9}[\xa6:\xc3\x80>\x07'G\x0e7\x87\xb0\xc1\xbe\xc0\xef\xa6AB\xeer.X\xbf\xf0Z\x0c\x98W\x14\xa1B\x92R\x18;&n\xc2\xb5\x9a\xa4\xd4\x8f\x14\x8d\xff\x049CU\xe6\xf9p\xcajX:\xde\x9a ]\x97\xf5\xb3`\xbcxr\x17d\xa2\xb1\xbe'|}g\xa3\x8f\xf4\xddG\xf2\xee#u\x87\x1d\x924f#\xe4Qqa\x07\x9c\xdf\xef\x9e\x8d\xd7\x06\x83\xdf\xef\x9e\x11\xc6\x88K\xf3\xceZ\xa5\xeb\xe3\xdetH,\xf7\x0b\xa0\xed\x0b\xab\xd4\x0fr\xcaO1<\xc8\xe7)\xbd\xc5\x83\x1d\xa68\x8e\xd2\x94\xa6\xae#\x8b!\xca \xa19\x84%\xf2M\xce\xb0\xe5\xf7Z\xbd\xc5AU_t\x19\x0b\xd7~t\x12\xa5\xf9}\xf5E\xde\x90\x0f\xe1\x15M1N\x8d\x81x\x8c(]\xab\x1d9t\"J\xb5\xbd\xde\xbb#\xecp\x98GcnHa\xc2\x8a\xce\xec\xd2\x84\xeb\xb6\xe6\xe8\xec\xb1\xa55\xac\xde\x9c\xdb%w\xb2\xf6\x04\x19\x18\x1a\xa8NtV\xdd\x1b\xc1t\xb3M>f\xcc\xcf\x91\x9a\xf7\x08\xba\x916/1\xd4M\xdf\x1e\xf0,\xbb\\HK\xf8\x19J} x\xf5#\x06\xc5a\x98\xed\x04k\x9b\x9eW\xb7w\xbf:9\xf8M\x88\xcb\x95\\\xbd\xcb\xf7J\x18B\xc2\xb4\x03\x92L\xf8\x99Xj:$\xb2\x0bdH_\\\\_\x9b\xe0\x7f\x03\x99-\xb8\x14N\xb6\x1d%\x7f\xb7}\xd5\xac\xc9\x91\xa3\x80+\xea\xf0^\xf3\x9b2\x06W \xfd\x14\xf0\x93\xe6\x13\xb6}\xa3\x95\x8b\x1f\xef\xe9{P\xdeC*8kJ\xbc\x17\xb8\xef\x15u\xae\xc2\x0dL\xb4\x86h\xca]x\xd8T\x1f\x13\x97rnB\x8d\xdc\xe4\x80T\x85\x9c\x9dP\x91\x8c\x98\x1a\xfa\xc60\xb3\xb0\xdae\x18\xc4\xacCG\xc1\x11\xb2-\xf8'~\x9e\x904<\xf0_\x80\x8a\xa6\x17\x1e\x845\x02\xe9\x81C\x90\xf4\x82A\xfb\xcd0b^\xef\xb9V\xc2\x80\x7f\xe3]:\xf3e\xaaK\x1f\xc2\x15&Z4\x88G\xb3\xea\xd9-#\xf2\xd2\x94\xd8\xaa\xf9\xc0\xd6dF\xf2}\x9aL\xa3Y/\x1b\xd8\x1e7\xd2r\xdfdMly\xd6\"\x06\x8aj\xb7ij\xb2rW\x95.\xcf\xfaf\xc3\xc9\xe4GJ\xaf\xfb\xf2\x7f\xfd\xd9\x03\"\x1c\x8f\xa3v\xf8\xa9\xd4\x9f\x7f\xe2^\x84'Sh\xc6\xcc=\xcdU\x8cj\xf3ju\xc1\xf4\xfd\xda\x99\x97^\x90n4\x9b\xad\xd4\xae\x1c\xc5\x85F\xa7Q\x1a\xde\x8b\xe3V\xdb\xc6\xa6\xd1\x0fW\xdbZ\xed\xe5\x832\x16\x9e\xce\xb6\x0c\x8b\x9c\x8a\xa2G\xc5W\x16\xfev\xfcpS\xdeSvs\x1f\x9c\xcbK\x92\x1d\xd1 \x0f\xd3S\xef\xfc\x0d7\xe0\xa9\xa9\x02\x94\xd5)O\x8cb7q\x9f7o\x15PQ\xf0\xb4Y\x10\x89\x82g\xcd\x82P\x14|\xd3,(D\xc1?\x9b\x05\x99(\xd8T%f\xf6b\x8b\xbd(\xdf\x94:F\xdc\x9ey\xf5\x06, *T\xe0\xe9\xb1.\xa8\xaf\x88\xaf\xd6\xf4\x0dlF\xd8\x05\x81\x9f\xb1\x95\xee\xca\x9e\xe5\xb6k\x9e\xee\xa6\x0f4\x10\x1f\xf6\xdc|\x1ee\xdc]\x95\x15\x84\xcd\x027\x0f./\xd1Twy\x89\xccb\xd3\x87T\x01\xf2;\xd3\x88P\xd0%\xbb>\xba\xaf\xab\xe0\xc5\x82\x93\xb4\xb4\x88\x99 \"[/\xaa\x8554]\xc3\xe4`lM\x0dM7<\x01\x0f\x0e3z6\xa7\xb7f\x92[Zmh\xe6\x01,;\x87\x18\xf7Et\x94Li\xba\xe01 ;\x88\xc2\xd2\xa1\xb1\xeds\x0bz\x15\xc5d\x08[OWm\x96\x8aqz\x96\x91N:q1\xed\x84\x98wB\xc4rg\xf8D\x0cXx\x08\xc9\xaes\xba|\x0c\x9a\xc2\x1eh\xfa\xaf\x1e@Q\x0e@\xa7\xb3\xd5\xde<|\xf0|\xe5*\xc2\x83[\xb5Y\nS\n\xa3\xcbe)\xec\xc0\x18\xdf\xfe\xbd\n\x8d\x0fy\xf0SF\x13\x14\x15\xc2Kn\xa1D&\xad\xbc\xbd\xa24&a\xd2|\x8d\xe1\x03\x9b/\xb9\xe9\xb1\xf1\xf65M\x17\x1a.-u\xa8{\xa6*\xb5T\"*KZ:Q$JZzW(\xab\xe8\xb4\xa8{\x9d\xde\x95\x89\x82\xd67bQ\xd0\xd2\xbb\xb8\x94\xd7\x14\x88\xa6\x08>n\xbc]\x8aF\xb6\x9a\x8dp\x01\xed\xdb\xc6\xdb\xb9\x04\xdfj\xf5\xf3F\x16\xb5\x86\xb6\x90%\x9b\xdf\xb4\x061\x13\x89\x8a\xb5\n\xe1\xfd\x97U\x08\x97\xe5\xba`=\x08\xa2\xecT\x84\x85\xf6\x95\xa20\xb9\xf7\x1b\x90\x96bN\xad\x86\xa6x\xa1\x0f7\xe5\x9b8\xcar\x15\x82\x91\xb5\xedw\x98\xdc\xd7i\xf5\xaa\xe5*t\xa3w\xf2\xa1\xc9\xfe\xf9\x86\xb6]\xcd:\xff\x1c:\x7fK\xb5\x97:\x7f\xd6,\xd0\xe9\xfc\xaaF\xfe\xa9:\x7f\xac\xb4U\xe9\xfcuK\x80Q\xe7/\xd3J\x1dD\x93#\x1eG\xb6\x05\xf9\xd7\xa9\xff\x93([\x86\xf9x~\xc8t\x860\xe6\xceP\xc6:\xdc\npc\x07\xe2^\xd2\x92\xc0\xf5\x1a\x17\x1aCS7\xe9\xe4\x9d:\x16\xff\xf7\xd9J\x90\x84\xbb\xd0\xc3\x97Z\x17~:\x90\x18\xd5\x90h\x91\xd8W\xb0\xcb\x14\x08;5\x1c\x0e\xe4AN\x7f\xe2\xd7\xaa9{g?]\xd3a\xbb\xf4\x8b\xb4|.F\x17\xbb\xfc~i\xe9\xfe\x18a\xb8\x9a\xbf\xe0\xa6\x80>*\xa9\x0f\xb4=\xe3\x06\xc6\xd3\x06\xac\x9di6c\x02\xfa\xb88x\xa8\xc5\xc2\xe3\xf9\xaa7_\xc0\x18\xb6\xa1x\x01\xe3\xf5u\x0f\xe2\x8b\xf1\x07\xb5\xe6\xc5X\x13kQ\xc6Y\xc4S\xe5\x1d\x03\xf3\xc3=\xae\x93\x01\x8e\xc38\x16\\\x90\xf8p\xc1\xea\x96\xc1$\xb8\x9e\x96\x96\xdbQ\xaf\xc3\"\xe9\xae\xaez\x8er\x92\x17\xfbh \xa2`\x92\x80G\xec\x0e\x18\xa0\x88\x81X\xbeC\xba4,<\xd1\x9a\xec\x15\xe3\xb2\xf2\x9d\x90\x90\xb4\xc7Sl\x1c\xa3\xa4X\xac0\x16\x81\xe7\xd6\x17\xf5\x1f@\x9bvK\x14a\xf4\xf4%\xe4\x89\xbf\x81/\xf6c?+\x08\x0f]\x8c\x96\xf6b\xb4\x9c\x87J\x99\xb8\x8b\x87N\x08\x8f\xf3d\x8c\\\x07\x82\x85\xa6\x01I\x8a\x85\xd92\xcd:G93\xdd\x15\x7f\xb8\x1e\x0c\xf1\xac\xb7\xe82U#Ou\x1d~\"c\xf3s\xea`;V\xbe\x02u\x8b\x1a\x95\x91Jw\xc1\x89\x12\xcc\x07\x84\xd7\xab;\xee%`\x90\xa8Zm\xda\xa3\x96\xb8\x9b\x80\x82ff\xe5]P\xd1\xaceF@\xb69Z,\xf3{q\xa5b\xcd\xc2\xa2\xa0\xc6\xcb\x90\xc8\xd5\xfd\xc0X\xcft\xbb\xd3\xb8\x86b\xdc\xfch\xba8\x08\xf3Pn\x80\x11\xba\xbb\xaf\xb9\xce\xeb\xb2 JD\x0c\xda\x8e\x83\xa3\xdcu\x0e1\x91\xa4]\x10\xa9\xed\xb7b\x8b5Q\x89\xd5\x82\xc6\xea\x0eEs\x96\x9e}\x12\x1d\xadNC\xad\xa9\xeb\x92\x90e~\xaf!\xc4\xfa dk\xd3\x84\xa0\x85|\xdf\x03Q\xcb0\xcbni:\x91\xb8\xe7R-CFU2\x94\xb9\x07\xffk\xf0\xd9\xbd\xc2\x16Q\xf2\x06[\x1b\xda\xfcK'\xe4\x8a\x16\xc9\x98\x9cG\x0bB\x8b|\x08\xcf\xbe\xb1@+\xa1\xe7\xacb\xe9_0\xdb\xad\xd7\x9fU\x02\x95\x16\xcf^\x02(1\xdc]\xef-dJ\xf3\xe8c\xad\x1e<\xae\x06Bc_\xcc\xd1\xf7\xf5\xc2\xdf\xaa\xf2R\x1ady\x98\x0b!\xc0(\x9c\x1d\xe6D'\x9cY\x1c\xae\xd2 #\xf9\x19k\xba\xba\xdao\x8d\n :hg\x91ri\x88Kj\x19\xc9\xb98f\xacd\xf2\xefW\xb0g\x184w\x98b\x03\xef'\x8fj\xc6k\xbd\x1f\xb0\xcax\xe5\xa5<\x11\xce\xe4/\x19o8\x994\x07\xbb\xcaX\xfb\x04\xc4\x10T\x06;p\xe9J\x8a\xeb\x12\x8a\x04\x06\x048w\xcaslau\x1e\x8d\x80\xd5U\x10\x0d\x1az`\xa1\xdfx\xff\x82\x01\xe2B7^\x9c\x15\x1f\xaefF\xdbH\xed\xe5_\xa3-\x95\xd6\xd7\xf7Q\x1c\x9f\x921\x89n\xf0\xb4,\xeb\xa1@\x19\xe7J\x92\xde\xda\x8e\xd0\xa2\x94]\x8f\x89\x7f\xfc\x9d\x9cN\x9bB\xa0\x92\xa3~*:\xf9\xd9\x17\xb2\xa0\xdau\xc4>\xba$?=\xec\xa7KR\x84\xedV\xed\"\x84\xebR'C\x84\xeaR'\x0b\x842\x99OC\xbc\x11,\xb4\xbeP\xd5\xfa\xec\x06\xd4\"\x88\x92)I\xb9\xf8\xe0FA\x94\x93E\xd6\xedhV?Q\xe9\xe1s\xf6\x8ag\xf7\xef\xf0\x1f\xcbP\xb7\xb5\x88W\xd0\xa6h\xb3&\xbc\xec\xd2v\xe7\xd2\xd3\xed\x13\xb5\xddy\xd7\xc6\xaeH\xd5\xe1\xeaR5T\x92\xb5R;\xecQKf\xdf\xed\xbe\xb7/\xd6\x9c\x85\x96\xa1\xad=\x1b\xa2\xbf\xd7\xa0kz1\xfd\x9b\xf5\xe2\x8ey\x14\x0eW\xdc\xedc\x8dGC\x99\x04\x98]\x91\xfd-\xfet=\xd8\x86\xad\xea^\xca$X\x84KE\x10\xf2\x81v\x11^$\x84\xe6\xb4n\x96\xcf:.\x96\xc9\xd9\xb75\x0f\xe2\x13K\xdc\x10xZ\xd7\x9e\x92\x8b|J \x06\xaf\xf1\xf0[/\xd6J\xb6p\xab\x80'\xeb\x82j\xe5\x9d\x8f\x8b\xe5\xc5\xe6\x07\xbe\xe3\xc1:P\xcb\xdd\xe4\xce{Y\x1dsi\x1f-2\xa2\x0e\xa2T}\xbf>f4\x19\xf0\xed|\xc0\xf4\xeb\x01\xdb.\xad\x0e\x81\xa6\xeeY\xdd\xcd\xa0\xfbd\x05Z\xa7+\x1dF*)]\xf7]\x81\xfd\x04{\xf9\x94$\xa3\xaaO|)\xd8)\xc7\xde\x1dy\x9e\x13Y\x96\xbf\x19\xc7V\xf3\x124\xa6\xf6*O\xe0*O\x06\xd9\x02\xb4\xb3<\xe0\xfaH\xc7\x86K\x93\xfd8\x1a_\xf7\x10^\xd4\xa7\xc4^\xa5\x87\xb9]\x88\xb3\x11\x9d\x03\x03pL\x9e\xa8^\x90S~\xf4\xf3X\xd4\xad\x84\xb6p2\x01\x07\xd6\xab\xcd\xab\xc1\xf8\xb8\x1b\xa1\xf1[%B\x91#\x08\xbdM?06\xee\xbd\xc9\x04\xd8g\xb5\xc3\xef\xb4\xb4\xbc-R\xb2\x8a\xb5\xa5r;\xebeo\xf9\xdf\x81\xdf\xca\x07~\xabj\xa9\xff;(\xd3?\x7f\xd1AY\x97\xceB{\x1d\xa7\xd5\x0f\xca\x0c\xa7\x0bx\xf2%\xf4\x9b\xb4\x9f~\x13\xf69\xcc\xea\x10#\xc2\x9e\x1ba\xba\xbaX/Dz\xa5f\xda\xcfX.\x82\x08$\xb6\xdbFuA\x9d\xbb\xc6MS\xba\xf8\xe9\xccs)jYx\xff\xd3\xc9S\x9e`e\x1a\xc6\x999\xe1\x0b\xe8\xa5\xf9\xb2\x1d\xdb\x81\xd7\xaaB}\xb7I\xe1\xd3L\xe4\xa5\x07\xf1\xa3\xf7\xec\xde{\xb2\\\xa1\x9fl\x1f\xb7X\xc6\xd9\xc2\xc9H\x8esrN\xcf\xc2\xc52\xeee#\xaf\xbc\xbb\\\xf6\xe5\x19\xdb\x1cxm\x8e'\xcf%5w \xfd\xdd`\xa2\xb5\xcb\x1bEF\xd2\xf2\x990\xb4:\x0f\x93ILNVi\xfb\xa6\xccw\xdc\xed\xbb\xa1\x0c^\xe7\x03\xe8\x1b\xbd\x85\xe132\x80\xcf\xe9y\xb9V1\x81\x86\x9dO\x9d\xc3\xf2e\x9bdtw\xb4\xeb8\xf8B\x86\xbc\xffbN\x96\xbb\xce9\xb9\xcb\xf7R\x12>\x92\x9b\xd4\x0c\x0c& \xda\x93\xe50R\x9b+\x06\x04c\x1d\xf6\x08\x9e\xc4\xd8M\x16\xfda\x0d\xcfkF\xbddX\xac\x05d\xc3\x1fi\x94\xb8\x8c}x\xfd8\x97EGm\xb0\x89\xfa\x06\xa0\xad\xf5(w\xbe.\x11\x1f\x81\x1fu\xe3E\x1e\x86\xe2E\x87\x7fz\xc1\x818\x91F\xa7\x89\n,\xad\x17\xf0\x10\x92\xb58\x02\x8f\xef\xc2g\xbdt\xd3\xec\xa6\xe9n\x8c\xf8h\x98e\xd1,a\x8c\xcc.\xa6\xd7\x92>o\xf1\xfc\xceMuE\xe4y\xb6\xef\xf3\x95\xa6bJ\x03]~\n\x03'&=\xf3\xc2c(8\xb4Ta\xac\xe9\x1dH.R]\xa0\x89\xd6\x1b\xc9\x90\xeb$X\xa7x\xda\xc5\x9aK\xd1\x83XO\x9ck\x19\xfe7_@\x02\xdbj\xa2\x7f3\xf6@\x99\xb9\xfc\"1`\x0e\x90P\x99tG\xd2\xf0\n\x05\x8a\xdaO\x91|,e\n\xdb4\x9a\x15\x12hm\xb3L\xda\xc7P\xce\xe3\\\xa6\xc1m\x1a\xe5%D\x99}\xaaI\xa7\x845xM\xee\x19\xfe\xf5\x0b\xbe\xff$\xa8\xd6X>\xa1V\x85\x91\x07\x01u\x15\xd2\xe0\x99\xc3R\xf1\x9eG\x07l{\x157\xb6\x9b\xe6\xc5r\xa6\xd8\x14<\x02F\xbd \x14\x05[\x9b\xdf|\xab\x0f\x86Q|\x91\xbbOn{\x99\xf7\x92\x8a\xb5+{\xad\x9f\xb3\x04\x8f\xf5T\x8b\x80\x95\x9b\xc2\xa1\xed\x87IBs`\xeb\x12B\xce\xfb \xccj\xa1\xd8\xdas\xd2!\x90'}\xbd:\xb0\xa3D\xed\xd9)\x99\x92\x94$\xe32D\xdc<\xca`\x1ef\xc9\xd79\\\x11\x92@\xc4\xaf\xb1D\x19\x99\xc0\x00\xb2bIR\xd7\xabA\xb0\xa1\x90I\x87\xf8\xb0\x86\xc7\x0dJB\xc9Z\x10\x1fm8\xbb\\P\x81\x86F\x0d\xfa\x86X\x843\xc2\x98\x1f'\xfa\x93i\xcb-\xc7\xa2y$\xab9d\x93`I\xd2,\xcarSX\x05\xc9\x14\x92\xee\xd3\xbdd\xa5\xe3kU\x1f\xd0o,=s\xaf\xb0\x1e\xd2~=dO\xe9\x06\xf7\x92U\xe1\x82x\xe9\xcd\x86\xe1\xaa\x12\x9aGS\xbc\xe68,\xb7oxYU|\xf2\xa4\x02J\xf1\x88\xa8G\xbe\x066\xd8!\x08p1\xf8\xaeZP\xe1\xcb\x92\x91\x0e\xf4\xeayUd29\xb7\x89\x12\x13-%?\x93\xfb\x03zk7\xa0\xca\xa7\"\x0f\xa9C\x8a\xda\xfa pFI\xceS\xc20\xf1\xfe\x9a\xdcsdNi:&\xc7\x12\xed\xbe\xc85e0\x10\xb2.\xbe\x8a\x8b\xf4\x91\xfdcUM\xf4\xbbb?\xb8\x86\x80\xf0\x11\xe9\xd7\x1f\x1eQs\x1b6\xbd\x92\x86\xba\x84\x0f\xf9\xc8\x05^\xc4\x06/F\x83V-\x03\xfc\x8a\x84=\xb5\x0f'\xc1\x84\xf2\xf1Z*\xdb\x97^.L)\x8a\xed\xa5\x1b\x0d\xf2I\x82(\x13\xbc\x8e\xdf\xd1a\x02L\xd5)\xab\x9f\x19\xdb\x07\xcd\xcb\\\x87\xddGtg\xd3\xd7\xcf\xbf|\x90\x0e\xa6q\x91\xcd\xfbN#TS\x99\xf3\x9a\xb6\xb4\x13Hf\x8c!\xc7\xab\xb4\xafEk.\x1a\xb2}NOXz\xea\x97\x93\xd4\xa7cI\xc3\xc4$\xce\x18D|Z\xe5r\xad\xfeS\xca\xba\xec5\x9f\x98_\xa0\x86\x03\x1b\xc6J\x0c\xe3^$\x91d&--K\xec8\x81\x04\x0d\xb31\x7f!Wx\x14E\x9e\xa4\xac\x08\x0c\xa2X\xfe\xfeR\x0c\xe8\xf1i3{\x07\xdf\xc1\xa9\xee\xe5\"(\xdd\xe6\x98<\xd6f\x8c\xd8\x8en_\xa9Aj\xcd\x87\x9d\"\xa81r1\xb2\n\xf4=A\x07?\x83\xe8|\xc6\x84O w\xcb\x94d\x19\x93\xda\x17E\x96\x03\x89\xf29I\xe1\x8a\xf0\x06h\xaa\xc8\xd2>\x06\x1dv`\xbd\xfc\x90\x862I\xa5\"U\xba?\xe7N\xae\xc8\xdb\xa8\xe8Pz\xd4\x8ei\x92\xe5i1\xcei\xaaS[\xe4#g\xc0L\xef\x95F\xda\x8e8\xa0>R\xff\xb4\xbbA\xa9\xba\xec\xd0\x94\x8cICK\x92{\xbb\x02\x1bYM\xa2\x86]\xd0\xbe\x17\xf3>DUN\x8a\xe5l:\xeb\xa4\xc3t\xcf\xf2T\xa0a\xbd\xf2\x81\xf630\xbf\x8f\xe2\xf8S-\xcch\x95\xab\x8b!\xaeb`n\xdc\xbf\xe8\xb2\x97X\xac\xc9\x7f\x89K\xac\xdcH;\xb7\xd0D\\\xc6\xab\x8dF\xbf}\xe2\xe8k\x8b\xff\xcf?\xcb\x8c\x85\xb84+g[\xc5\x01\xb7Q\xd2[\x8f1\xddi\xf6!\xa9<}\xb5\x93Q~\xac1}I\xb7\x01\xb5\xe74\xbdK\x16\x9f\x83\xbc\xb8t#{k\x92Xzw\xf1o8\x97\x10\xb9\xbe\xec\xf4\xe5*\x91\x15J\x8a\x04R\xb1k\xbfM\x82\xec\x95\"\x9b\xbc\xbaG\xf5\xc6\xe68\xc3\xa3-TUNP\x1f\xb1\x9c\xef\x8a\x90\x0fB\xab2\x03\x16\x02\xd0\xde\\\x86PQ\xb2,\xf2S25\xc3\xc5}\xcd1\xf2\x916\x9c\xff\xf4I\x1aUZ\x7f\x89\x07y\x19\x96<\xf5\x98\xb8\xb3\xa9XA\xec&aR\x9a\x84\x13n\x12\xc6\xac\x85\xf6\xcfK\x1d\xca\x08\xf4\x80~/\x8e\xa0\x18\xc7\x07G\x12\x85S\x1aQ}pJ\xa2\xc0d\xd1u\xa2\xc0\x83\xfb\x16Q4\xde\xf2y\xe7\xed\x8b\xb9\xe5?\xe4k9G\xd6\xd3\xffqG\x0cKt\xf3\x86]\xcb\xdc\x95_/\x1d\x01\xc4o\xfd\xbe\x06C\x08\xfb\xb6g\x88\x17\x0eC#\x910\xba\x98v\x0c\x89\x95\xd3\x8e.0\x1c\x96\xe3a?\x8c=)z\xb5T\xadB\x99\xba\xb4(r\xaeueb\xe8\xba\"\xf3=\xd8\xd6\xdd\xd7\xad\xcd\x06D{\x93h\x8b\xc2\xad-\xa3\x0d\"w\n\xd9\xc1\n\x97\xf8W\xc7\x99\xa5\xe5\xae\xa0\xdc\xd3\x9d\xd1\xdd\x92\x8cs2QM\xfcmBIa\x07\x8e\xc3\xe3v\x01cz\xce\x85\xf0\xf09\xbb_\\\xd1\xf8\x83\xa6~\x04;\xb0\xf1\x7f\x7f\xcf\xd6\xff\xfc=[\xffjc\xd6\x86\x08\x11\xe2b\xb0\xfea\xf3\xeebs\xf0}8\x98~X\xffjC\xe3\xe6T \xe4\xe6\xd5\xc5\xe6\x96\x01\"\xe3\x10\xf4bs\xf0\xad\x01\x841A\xcc\xad\x7f\xa8\x93\x1d\xd8\xde\xaa\xa4f\xa9\xe9\x81B\xe7:\x11NM;R'\xc3\xd7\xed\xa6\xa6\xfa\xa62\x12OY\x0d\xf5\x7f}\x9b\xac\xa4\xdd,\xdb\x80\xc6x\xf6\xcb\xfey-\xe7\xd9\x91\xd6\xa7y\x949\x9e.\xec\xf2\xa4R\"+\x16,\xd3\xe4\xb4\xc1\xe7\xb0\x03Ga>\x0f\x16\xe1\x9dF\xac+K#\x8d\xf8\xd2\xef\xb6'\xef\xf028`\xdbNBou\xf2\xa7r^\x07\xea\xb9\xd8L\xaf\x7fH\xddC&\xba1\x1e\xa8\xac\xad\xf1\xac\x18\xb5 \xd2d\xddiz\xa7\xea{\xa3\x89\x9e\x08\xd2\xac\xa0\xc9\x97nK\xd3\xc2\xeat\xebX\xa2\xbe\x93\xe1\xba\xab5\xde\xed\x16\xd0hD\xa0BC\xaa\x066\xc0Z}\xf2\x04&B`\xf3@{i\xe5AM\x13\xa4\xb1\xcdc.\x15KF\xa9\x9b2\xa8PmBdF)\xdc\xbdQ\xe5/\xffF'U\x93\x17\x1a\xec\xc0\x8cm\x86\xbb\x90\xc3:\x8f)\xd6u\xc6\x0c\xcd\x0cJk\x9a)\xac\x12\xe6\x13\x18\xc2\xba\xe6\xf3D\xb8\xdc\xf2\x84~\x11\xe6\xf33\x1f\x97\x16\"\x1d\xb4\xe5,\x90\xcdp&\xc1`\x17bW\xe4!u\x9f\xa2\x86\xba\x0bOa\x08\xdf1l\x84\nX\x8a\xfdk\xd0\xb3\xfaK\xf5\x8ci0\x17\xed\xa1>\x1e\xd1\xf9\x10a6\x99\xc2\x87\x0c\x85\x13\xf4w\xd7\x0b\x1cSn\xb2\xd3\x96--e\x13\xb4\xd9\xebIH\x9fpLo\xa8K\xbc\xc6v\x02\xea\"\xbe\xea\xf6w\xb4\\_b|2\xb2Jv\x8ca*\xe9\xdbx\xa0\x17_\xa8x\xdcr\x9e26\xae\xa1Js\xa75\x91;\xe5#;M`\x00\xb1\xb5gJ\xc0\xbd\x98\x11W\xc2T\xb6\x9c\xff\xb5\xcdu\xb7%zB\xc0\x00\xc6\xac\xac\xad\x04\xd8\xfax\xdb\xa9\xf4/l\xe1\xff/k\xf9\xc6\x8c9\xca\x18\xd5f$\x17\x82\x99{\xeb\xf7\xdc\x05K_V\x18\x80\x8b\xb8\xea\xbe\x9c\xba\x84]\xb8q\x13\x1fBYi\xec\xa1\x05\xdf\xb8a\xae6\xab\xa3\xce\x9d?S\x08i\x02\x98\x1dk\x17\xae\xf89\x82\xdb\xa4\xb4b\xb5\xaf\xdf\xf5\x99/\xf3JHx\x1c\x06\xcb\x8cR\xd5\xa5\x8c\xe7\xe4\xe2.\x10L63EJQ\x1bP\x086\xf3\xdaV\xfe.\xb3\x86\xa80\xe6_k\x13N\xee\xf90\xad\xf0\xa9W\x14\x01g\xd6F,\xe2^\xb42c\xed\xcf\\\xb9\xa6\x00\xfb=\x17l\x86b\x8c\xaeq\xcf\xd7\xf4\xdc\xe8\xc5\x95c\xe4\xe8\x1ccbn\xfa0s\x85\x15\x06\xf7\xec\xb54\x88 \xe6f\xe0Y\xb0]\xb6[;\x8b\xf0\xee}\x18\xe5\xdc\xfd\x8cq\x98\xb9{\xef\xa6\x81x-[B\xc3{\xe8\xe3&\xee\xe4i\x18\xc5\xc8K\xd1em\x17\x9b\x96/a\x08\x13L\xe0\xd7\xffhT\xb1\x00#\"0)\x98\xc4B&o_\xf1\xebG\xb1X\x15\xd5\xd2ic\x87}\xbd\xf7\xb9\xafn2v\xa1\x80!\x8c\xdc\x85kH\xf0U{\xa9\xb8\x87IW \x1f\x12\xf7\xd9\x96\xa8\xdc\xa1\xe5I\xe7\xc2z\xf7\x9c`#\x8c\xe3\xe0c\xe6\x0c\xe1\xf9\xf3\xe7~\xab\xb0\xc8\xe7\x1b!6\x9aq\xa8\xa7\xcf\x9e\xea\xa1\xd0\x88\xc7a\x9e}\xffL\x0f\x93\x92I1&i&\xc1\x0c\x1f\xccd\xe2! \xf7\x8d\x01nI\xc6\x83\xdb4\\\x0ej]|\xf6\xfd?[\xf0\xfc\x10)k\x8e\xa5\xdd\x01 8'\xf1\xb2\xec\xe9\xd3g\xed\x01I\xc0\xda\xb8\xbf7\x82\xd5\x87\xfe|\xb3\x8dE \xd9\x18\xfd\xf3\xcd-3(C@mH\xcf\x9b&\x06'\xd8\x98\x10\xb2\x1c\xc4Qr\x1d%\xb3\xfa\xb8\x9eo\xb61[\x83V\x06\xf7|\xb3\x8d\x83\x1al\x1c\xde\xd3\"\x97\xc0m\xcc\xd6\x80\xcb|K\x83<\x9c\xe1\x1c.I\x1a|\xcc\xee\xb0\xf2\xb7}+7+\xb6'~Bo\x93\x98\x86\x93A\x91\xc6r\x96\xbekA\x914\xad\x93\xc6\xd6\xd3v\x1f\x18\x10\xdeG\x18\xe4i\x98dS\x9a.H\x9am\xcc)\xbd\x16-?mO\x95\xa1R\xedGB\xf3\x01\x9d\x0eP\xc9\x16\x0d\xb5\xc9\xa3OC\xcb0\x0d\x17$'\xe9\x80&\x84Nec\xed\x89\xeb\xd3\x18\xd3d\x96\x03\xe9\x0e*\xdbj\xcf+kK]\x04[\xedE\xc0@\x1ak\xffi\x9bN\x19Ts\xe9?m\x13(\x8f\x9dP'\xcd\xf6\x8c\n(\xba\xccxV* \xd9\xee\x1c\xa7\xdb\xc6\xce\xa0YF\x02N\x1d\xea\xd36\xbd \xa8\xe6h\xdb\xd4$\x00[\x03n\x0f%\xa6\x8dm\xe6\xbb6Rh\x98=knn\xed\xceq\xa8\"\x9f\x0f\xc8]N\x92\x8cAo\xe0\x06\xda\xdct44\x83\x95\xcb\xe3\xc5l\x83\xf1\xa0\xabp|\x9d\xc9\xd5\xa7\xc1F\xb3\xce<\xcf\x97\x03\xd6\x01YG\xc3M\x9au\xd4\x89\xd6\x90C\x13\xbc\xda\x1c\xd8vQ\xf6\xad\x8dVs\xc5\x8c\xa7X+\xfb\xd8\x8d\x8b\x94\xfc\xbf\x82d\xf9\xe0\x8aN\xee\x07d\x12\xe5\xb4\xdc\x93\x9e\xb5\xf7\x04[\xed\xb2\xc3m\x8aiV\x13\xdd\xac\xb2\x1d\x95\x9fl\x13\xaf\xa1n\xf9\xb5\xf6\xb2\xc0\x1a5n\xf1\xcc\x80\xfc\xda\x04\x19F\xdb`\x7f\xcf\x0d(m\x92\xe1s\x03y \xe3Sh\xb8E\xbe\xedmJ[OO\xfb\x86\x8f\"\xb0\x82C\\HQN\x16%\xde\x0d\x0b\xa0YQE\x98F\x04\xd1\xd6Q\xa38p\x1b\x93D\x91\x01\xe3\xcd\x06\x16az\xcd\x98\xa1\xfc\xaea2[\xd5\xe8\x84\xc4r\x80\xcf\x0d\x84\xd5\xacD\x938J\xc8\x00\xaf\xb6\x859M\x07W\xe1dF\xe4\x97\x0d\xb4\xd6l\xa4df\xd5B4\xac\x89f\xcd\x1b\x9e\x02r\x90\xe5\xe1bYV\xd6\xec\x00 \xd6\x8aINjs\xb2\xd5\x1ef\x86\xb71\xb3\x8d\xa9\xc0\xdf\xd6\xf7m\"\x910\xb5\xad\xba=\xbd\x8c\x06\x9b\xdcF\xd3\x18\x83R[\xd2\xec\x94\x08\xd3\xe04\x9a\xcd\n\xc1\x1aD\xfeT#U\"\x9cF\x9c~\xde&k\x99\xd5\xeecc\xb4m\xc8\"\x8f\xe2\xba\x8c\xdc\x9e\xc4\x9b\x88\xdc\xd6`\x9e\x1b`RJ\xf3A\x94|$\xe3\xbc\xec\xdcw%\xa46]\x0d5^\xd8I\xdc\xa8fly\xd0\xd4\x8e\xda\xb5\xa5\xad9\xbd \x8d[Z\xfc\x06M\x0e\xeb\xb0U\xbb8S\xbf43\x8d\x92 ,\xf8\x0d\xa1\xaf\x1dX\x07\x02\xeb\xe0|\x1d4\x0d\xbdR\xd7V\xfa'\xff\xa2\xc15\xb9\xb7\xe6O\x16\x95\xc5\x11\x0e\x83v\x95\xcb[\x0f>\xd0 %\x19\x8do\x08St\xeb\x17\x1d)+\x8d\x98\n\xbe\xb5\xf9\x0d\xc7\xee\xc3\x07\xef\x1f\x0f\xde\x8b\x7fll\xfc\x1f\xc8h\x91\x8e\xc9Q\xb8\\F\xc9\xec\xdd\xe9\x9b\x9d*\xc3\xe1\xe0\xaaH&1[\xe7\xc1\"\\\xfe\xff\x00\x00\x00\xff\xffPK\x07\x08-\xe3\xb5\x97=9\x05\x00\xf7\x0c\x1b\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00 \x00swagger-ui-standalone-preset.jsUT\x05\x00\x01\x80Cm8\xec\xbdys\xdc6\x9a0\xfe\xff|\x8aG|w\x152M\xd1\xdd\xad\xc3:,k\x1d\xc7\x9e\xf5\xbb\xf1Q\x963\xf3\x9b\xb7\xa3UQl\xb4\x9a1\x9b\xec\xe1!Y\x13i?\xfb\xaf\xf0\x00 \x01\x10 \xd9\xb2\xb33\xbb5\xacT\xac\x06A\xdcx\xeec\x0b\x16U\x1a\x95q\x96\xba\xa5\x0f\xc4\x83\xdf\xfe\x00\x00\xe0dW\xbf\x92\xa8t\xe0\xf4\x14\xca\xbb5\xc9\x16@\xbe\xac\xb3\xbc,`{\xdb\xf4v\x95\xcd\xab\x84\xc0\x19\xff#\x10\xb5O\x81\xb8\x1e\x1c\x83#\xba\x91?\x9a\x93E\x9c\x12\xda\"\xfb+\x08Ws8\xe3?\xdc\xd9\x05\x0e\xe8\xb8k0g\xe2\xaf\xe0\xfc6\xbc\xbe&\xf9\xcfo\xce\xcb0\x9d\x87I\x96\x92\x0f9)HY\x0f\xa1\xec\xab\xf3\x87\x07\xb7\\\xc6\x85\xdf,\x89X\x8e\x9c\x94U\x9eJK%^\xd0\xe7&\xcc\x81\xc0)\xfc\xf6p\xf2\x87\xbaPT\x85\xd4\xcd\xe5\xca\xf4\x89\x17\xe0\x92Y~\xe1\x89v\xe9\x0f\xb1b'JU\xdavLG7\xcb/h\x17\xcaKl\xeb\x18r\xbfU\x9a\x1c\xc3\xd6\xa4]\xcc\xbb8\x86\xdf\x1e\x94w\x0fj\xa7|T%\x1dU\x14&\x89\x1b\x8b\xc1\xf9\x10\xfb \xfdJ=\xfa3\x81S\xd8\x1aK/\xea\xd6\x9anx\x9bi\xb0\x82S(}H\x83\x88N\x8b\xfe1\x87S\xf5\x10\xfa\xd0Z\xb24\xc8\xf8\xf9\xbc\xbf\x87\xf7x\x1c\x02vL>\xe4\xd9\x9a\xe4\xe5\x1d\xff\xb2\xbdBQ\x96.\xe2\xeb*\x0f\xaf\x12bY\x96\xb4Z\x11\xf1~\xdc~\x7fM\xcac\xc8\xd5\x15\xf3\x9a9\xd29\xa4\xca\x1c\xf4\xd1\x8b\x13R\xd2\xa3^\x06\x97\x97\xa4x+\xeeK\xeb\xac\xc9\x8f\xd8 :\xd7\xb0JJu\x0cp<\xec\xeb\x01{\x9d\x06s\x97\xf8\xe0\x84\x0e]d\x1f\x88:\xbdL\xdf\"\xbd;\xde\x0c\xdf\x99u\x9e\x95\x19\xbd\xa9\xc12,\xde\xdf\xa6b\x8f\xd8i\xc2\xef\xd5\xf6\xd7p\n\xce\x93y\\\x94\x8e\x0f\xa9\x9b\x06\x14pL\xc7\x07\xac\xda\x83;\xd3\xceG*\xf7\xefT\x05\x81\xa2\xcc\xe3\xa8tN\x94[\x99\xc3)\xa4\xee\xfe\xd4S\xf7\x94^\xa8\x99\xf39N\xe7\x8e\x0fNN\x8a,\xb9!\xf4\xcf(K\x8b2\xaf\":\n'N\x8b2L#\xf2~A\x7f\xads2\x8f\xa3\xb0$\xec\x935\x05\x1b)\xd6\xe3[s^\xde%\xf8\xb2\xa0\x7f\xbcH\xe2\xb0 \x85s\xa1\xf6\x9ca\xcfE\x14&a\x8eu\xc9_+\x92F\xf8\xdd*\\\xaf\xe3\xf4\xda\xb9h\xe6PJ`\xb4s\xf9\xe9dS\x1f\xaa\x936\x9c\xa1\xb7\x8c^\x9a\xdf\x1e|\xb1=\x9f\xc9]\xe1\x12/Xd\xf9\xab0Z\xbau\xd3\xadvE+;\x138==\x858\x88\xd39\xf9\xf2~\xe1\x12\xcf\x83r\x99g\xb7\x90\x92[\xc8\xdd\xef~N?\xa7\xd9m\n\xd9\x1a\xa1\x9e\xf3\x1d\x8c\x80\xc0\x08\xbes .`EJ\x88S\x06\xd8c\xac\x90-X\x9d\x92\xd5\xf9\xcb\x8b\xb7?!l\x0f\xbe\xf3\xb4\x8b\xe6\x03\x05\xcaA\x19^3\xc8\x81\xbf\xe8\xe6\xd1\x99\xb1?\xee\xef!\xad\x92\x84\xbf\xe3\x1b\x8a\xaf\xc5\xdf\xf7\xf7\x83\xae\xca\xd6X\xed\x9c\xb7X\x9f\x0bl\xb3\xf9%\xb7\xda\xba\xf4`\xbd\x81\xbc\xd5\xe6\x80a\xb3\xd2Ou>\xf5\xd1\xc3j\xcd/}\xd6\xfcL\xf2y\x8b_j-\xf9\xb0bE\xa5@\xad+\x1fd8\x057\xc5\x0f\x94\xd2\xfa\x83\n\xf1\x9f\x8f\xbf`\xeb\xf4\x14R\n\xea\xe4\xf3\x96\x1a\xce\x9bq\xcd\xd2Yy1\xf0h\xd2\xa7\x9a\x9d\x97y\x9c^\xbb\xc4\xa3\x18\xb2lUzh\x1f\xa8\xca\xf3\x81\x1f\xe9\xac>\xd2\xf5\xb9\xb2\x1dm\xd0F%\x1e:\xba\xc8\x87\x85\x0f\x89\x0fk\x1f\x96\x8c\x06\x81\"x\xdd\xa6r\xe83\xaf+\xfc\xd1\\\xe1\xa6\xaepn\xaepWW\xf8`\xaep]W\xf8\xc1\\\x81\x12\x88\x94\x0b\xc8\xe1\x18n\xe8\xbf3\"N\x17A\x1a\xf8\x81\x12\xf3\xae(\xfe\xed\xc1k\xe8\x0ds\x8b\x97\xbc\xc5\x98\x9eB\xd1Z\\\xb7f\xfe\xe8\nN\xe1\xb2i\x19\xbf\x91\x7f\xe3\xa7'\xadO\xe9\xf5w#Dvx\x98\x10hz\xb8?\x94Lv]\n\xec\xb7\x96\xf4\xdd\x8a\xfe\xef&\x8b\xe70F\x90\xb9\x9aE\x17\x1e\xe5\xa0\xe0\x18Ro\x16]\xf8@\xe9\xa2kZm\x01g\x10\xba R\xc6\xc7p\x87L\x98\xe9\x0e'X\xef5\x7f\x83\xf4\x96\x0f \xfd&\xf1Y\x87\x95\xbb\xf2\xe9\xa1\xa0P\x1e\xb7\xe1g\xcf\x87\xcbYt\x01[\xa7\x90\xe0\xcdu/\xb1\xc6\xda\xf3YOW\xf2[\x17\x7f\x9dB\xa2\x81\xd5f)\xf2 bw9\xf6\xe9I\x83S\x98\xd0?\xfeHI:\xfa\xc79\x9c\xc2\x1e\xfd\xe3\x03\x9c\xc2!\xfd\xe3\x07Z\xe7\x80\xfe\xf5g8\x85]\xac\xf53\x9c\xc2\x01V\xfbH\xdfN\x0f}\xe5\xc6\x17\x9b\xdd\xce]\xe3\xed\xdc\xd3\x8b\xf9\xed\xd4\xef\x1b\xbd\x9dO\x9c'\xd7\xed\xcb\xa9\xf7n`]@b\xe38\xaa\xca\xdc\xd2\xb3\x1c;\xda\xa8\xf3\x8c\x02H\xd2>\\\x1c\xde:N\x83b\xdd\x10F\xa7\xe0\x00\xfd\"\xa5\x18\xe7\x14\x91\x0f\xef(\xf7(%\x90\x84\x11q+\x1f\x9c\xed\xbfVYy\xe2x\x88\x99\xbe\xf3|\x08a\x04\xces\xfamL\xffz\xf6\xc4\xe1d\x9b\xf3\xdc\xb1m\xeffD)\xe7\x8b\xe5\xf2\x94a \xe2\x86\x9e\x0f\xb9\x9b\x07\x1f`\x04y\xf0\x1a\xbe\x87\xd8\xed\xa4\xd2\x04\x1f\xe580+/\\:\x07\xeb\"\x11\\#\x12\x94\xd9O\xd9-\xc9_\x86\x05q\x91{$A\xb1N\xe2\x12\xbf\x0e\x12\x92^\x97Kx\x0e\xbb\xeat=\x1f\x1c\xb6\x86\x94!\xe9C\xdc}\xe8\xc9\xa9R\xc6\xac\xce\xe9\xce\x89\xbbz\x1b\xa7\xf3\xec\x96n\"\xfb+x\x1b\x96Kz\x97\xf1\xdf3\xf1\xfe\xd8\xf2yA\x92\x05\xfd\x98\xfe\xab\x7f\x8a\xef\x8eA\xc0\x01\xd7\x11\x84\xe82.\x1c\xcf\xf5z\xf0\xe05\xc7\x83\xd7\x8f\xc0\x83G\x9d\xa4\xca\xbe\x8e&\xd9\x8d;\xfa\xdfC\xaa\xd8\x89\xb8\x03\x9d\x16\xa0Kb\x90m\xc9\x1b[o0#\xa5\x91d\xe5\x7f\xf27\xed\xe5\xcc\xe9\\b\xfa\xbf\x01\xfb/\xaf^6\xf8p\xbf\xc8\xf3\xf0.\x88\x0b\xfc\xd7\xdcX:\xb8\xb1\xff\xe57E\x9e\xf2\xb0\xb3J9nN\x17\xd0\xbe\x04;\xf2\xe9nM^\xe5y\x96\xbb\xce\xcb0\xfd\xae\x04\x8a\xdd)k\xbd\xcc\xe6\x90\xa5\x00\xec\xac\x9aey\x9bB\xb0\xa6\x15E\xb4e\xb9Vt\xb5\x9a\x1e\x94\xf3\x95\xdfi\x9f\xd0\xf6\xd2\xce\xd3\x89wq\xec\x03\xb9 \x13\xcfuXq\xd3\xfee\xd9\xc7\xbf\xcc\xfb\xf8\x97\x9b>\xfe\xe5\xae\x8f\x7fi\x18\x9c?\xdb\x19\x9c\xe5\xa6\xec\x08\xe5aV}\x8c\xce\x15o\x99\xb2Ns\xc1:\xd9x\xa5.\xdee\xa9\xf1.\x8ckY#3\xa0q-W\xc8\xb5loC\x88\x8c\x05\xbb\xbc\x94\xd5\xa1,\x0b\xf2\n\xc7\x90\"3\xb3b\x8c\xc3Rc^\x9a\xd3\x8f\xb5\xcf\xb0\xb6`rh#Y\xcd\xf7\\\xd7\xdc\xc8\xe9)\xb2:\xdd\x92$\x90H\xc6F\x90d\xa7\xd2\xc5C\xaf'\x05: Dr\xecf\xda?\xa0Oq\x1b#T\n\xf3\xebjE\xd2\xb2\xe0\xb4e\xdfw\xf4\x89\xc2\x82\xc0\xf8\xb8\xb7\x1eH\x02{r\x0be{\x0b\xf5\x07[\x9el\xde\xb2K\x0c\x94\xb5\xfe`\xe3\xd3\xc74\xae\xd0\xd4\xa6\xe7\xa1\xf3m\xab1\xba\xa1\xd6/\xecm\xd5\xea\x95p\xbdN\xee\xb8\xf2\xaf\xde@s\x8b\x0f\xe6u\x11\\\x87\"!\x904!\xb2J\xa5n\xcaE\xce\xfc\xa6\x93\x9b\xcfl\xdc<~\xe6\xba\xab\xe0&\xce\xcb*L\xf0\xe25\xbf\x10\x96x\x9cW\x17\xbc\xfeG\xfa\xcd%\xfd\xdf\x16\xb2\xfc(\x0f`\xdc~\xe2yV\x8e\xfe\x1f\x85\x8b\x9f\xeab3.dk\x953\x1cu\xa8#4\x8a\xa2\x8c\xca\xc3f\xaa$X\xb06\xf7=83W\x96\xd5n\x16\xccE!H\xee\x96\x9e\x8f\xb0'\xa3gtk\x8c\xdc.jL=\x03Y\x04\xcd!\xaa\xeaf\xd5\x0d\x91 \x9f\x87V\x7f\xce5)\x1d\n\xbc\x91\xb8r\n\xf1\xcb@>\xbe\x88\"R\x14Y\xce\x08\x8a\xa2Z\xd3\xfd \xf3-\x0bA\xe1\xdc\x84IEx\xdb\xf4\xd0\x95\x0cY\xa5\x01\xbe\xf0\xfcMI\x0e\xf9\x08l\xa5\xee\xf4\xc8\xb3\xf3\xfd|\x0cO)\x9e0+~\x7f{\xe0\x8a\xcb\xf6\x82\xa2\xe6\xb6S\xa4 w\xd1\xbe\xa0\xea\xfa{A\xd8\xcc\xb3\x9f\xd8o\xe4\x1f\x9a\x1a\xb4\x8f\\\xb4\xebWS\xa3\x06u\xc8\x92K\x82j\xcb%\xda\xdd\xb3\xb0\x85\xa9\xbb7\xf5\x14dk>\xf4\x82\xc5\x0e\x16\xbcF\xecNh5\x99t\xef\xbf:\xb5\xf1\x01;b\x1b\x9f-I\xe67\xb1L\xa8\x9b0\xdf\xa2\x17\xb7}iT\x1a<\x05\xc6k\xd8\xaeL\xdf\xa0\xfb\xf8`uX\xff\x8d\n\x8dne\xba\xb2rCd\x82\x88\x9bc\x1f2\x1f*\x1fB\x1f\n3\xa8\xa4@d\xcbHc!\x03\xd0\xc6\xb9\n\x8fL\xc9T\x88\xe8\x1c\xc9-p\x18\xf76N\x99B\x8e|\x89\x08SJgQT\xe59\x99\x9f\x00\x9dd\xb9$\x90f\xe9\xceJT\x9c\x93\x1b \xe9M\x9cg)\xc5\xffH\x0e\xd3J\x8b*I\x80\xd0VaE\x8a\"\xbc&\x10\xa6s\x08\xe7sTe\x87 ,I\xb2^T \xdc\x86y\x1a\xa7\xd7E\xa0\x9f\n\xfa\x90\xa4 \x1dD*E;3}\xb1.\xcct>}(\x86\x1f\x9bi\x11W]\nR\xcb\x80\x9f\xfck\xf1\xe4\xda`\xdedz\xf8A^\xcc\x92\xd1\xe8\xc2X\xeb\xc1\xf3\xbc \x0dW(\x91}\x93\xde\x84y\x1c\xa6%\xfc)\xce\x92\x10)\x99\xd6WmJ\x8c\xdd\xb2(X\xe4\xe1\x8a\x14\x9f\xb2\x0f\xd9\x9aQ\x1a\xd1\x1f\xcc\x1f\x0e\x82\x01}\x16!OM\x9c\xae\xa4\xac\xeeW\xec\x0b\xb6bvaa\xa3\xd8\xa5\x8eS\xca8\x90`]\x15K7\xed\x10V\xab\xb35_\xacD\x9d\nW\xf2\xca@.\x0b\xe2tI\xf2\x98\x83\xed\xdd}O\xfd\x84\xb1\xe8\x93C\x1d\x03p\x1e}\xf2\xd4\xd8\x16e\xbf*\xe9M=?\xdaK\xec\x86\x0d\x91\xeb\xf9x\x0b\xc7'\x10\xc13\x10\x1c\xd0 D\xa3\x91\xbe\x88\xe2\xc8\x17\xb3H[\xc2\xa4io\xb6`\xcc\xb1Vt\n\xa1R \xa3\xc2f\x94|\xff \xb1\x80\xf9\x16\x8b\x97x\x9e\xccY\xd0\xef\xd4\x91U\x1c\xfb\"\x9b@\x89\xbbP/@\xa9\xec\x16\xb3,(\x83\x9c\x84\xf3\xf0*a@\x98\x1bi\xf0\x92S\xd8\x9a\xb4\xea\xdf\xe6q\xa9\xd6\xafKD}Z\x18&Iv\xfb\xefa\xb2x\xbf&)7\xbdS\x1bRk\xd4\xad\xb5>\xac\x9b\xcc\xd2\x88\xb8\x0eA\x83\xa8u\xf7r\xae[P\xc3\xd0\xf6\xfd=+\xbd\x14\x138/\xc3\x92\x04$\x9d\x13\xb4\xd6\xc9\x83\x94|)?\xc5\xd1gw\xc9\x86\xd0\xdd\xe9\xb2\xbd\x87%m\xcd5\x89\xf2\xccTb\"\xf3b\x8e\x18\xd7\xbf\xc7\xd7\xcb?\x87%\xc9\xdf\x86\xf9\xe7\x16 \xa9\x18\x06j\x86\x83\xfd\xa4\xa5$\xd5\xd4\x17b)w\xab\xde\xfdfB\x9e?h*sR\x94yvG\xe6\xad\xe1\x0f\x1e\xa2$\xcea\xa3\x15\xe7\x14G\xab |\x0c\xf3i\x8e\x98\xfaeP\x8f\x8d\xd60-D]Acu4a\xa12\x113@\xfe\xfd\xa7\xd0X\x9f\xd9&A\xabx\x1d\xdb)m\\p\xc9\xbf\xea\xa3\xfc\xb1C\x86?\xaa$\x11\x17\x16\xcf\xbe/\xdf#\xe2\xcb}\x7f\x13499\xda\xb3\xea\x8a\xec\xbb!\x8e=\xaetN\xd7\xb56\n\xeb\xa3\x8a7\x1c\xdf\xde\xc1\x9e\x01\x8f\xbf\x0d\xcbe\xb0\n\xbfv\xeds7\xde|\x02\xd2\x80\xcc\xe3\xd9\xb73\x88LZ2\x90\xb5\xfb\x87a\x10\xa7\x87\x1b/\xf0\xdf\x85A\x1c64!\xaci+\xc1J8\x93\xee\xa0\xcd\x19\xe3\xdb\x8f\xa8S\xc8\xb5\xb5U\xba\x1d\xf2-\xebg\x9a\x85\xeec\xf7\xdeb\xaeg\x16$\xee\xeb\x06\x96\x8c\x90>:\xf4\\\xa7\xc8#\xdd\xd4\x81\x92\xd3\xb5\xd0\xb6\xcc\x98\x1dI[\xfd\xe5:\x0e\x8c \xf4\xb8=\x8a#j\xca'\x06-\x08\x838-\xd6$*\xcf\xb3*\x8f\xc8\x90C \x08S\xe9f\xf96K \xc1\xa5\x87&\x12=\xb2Y`\xa4\xea\xa9\x8e\x10\x7ffn\xea\x83CYB\x07\xf5@q\xf3\x9b\x1e \x8a\xbc\xe8\xadm\x8c\x97\xa4\xcf\xaa\xe6\x8b\x8a\xd7;\x03\\\xa1\x92i\xb1\x8a\xe0\xd7,N\xdd\xda\xda\xd7\xc3\xf6\x90\xe2\xcd\xe1\xac\x86\x07p\x0c\xa1\xf8\xa9\x94\xc6\xcd\x818\x06wN\x12R\x12|\xefK\xaf\x14K\x8fF\xf2.\xd3[\xf56u0\xd2\xe2.\x1a\xef\x19e;894\xab\x90\xc1\x91\xf8\x08\xb9\xffot\x0d\x7fo\xc0\xb01\xd66_\xbd\x03\x93\xa2\xd9M\xdd\x83\x03\xcf\xc7\xf7\xe3\x86 \xb69\x98\x18\xaf\xe9\xe4@7\xf3\x0b\x8d\xaeT\x9f\xc9\x9d\xd9\xff''\x0b\xf3\x8b\xcb\xcb\x82$\xf6wx]\x8f[ \xcb\xe4%VX\xb7M&[\x83\x9c,\xa4\xcdh7\x13\x0dk\xe63\xb9\xd3\xf6\x14$\x96\xbc\x0d\x1ar!\x962\xc2\x88\xb6\xbc\x92>\xff\xf2/\xec\xf8\x1cC\xd5^\x1c\xfa\xea\x18\xca\xf6\x0b\xdc\x03\x83v\x1b\xb7 m\x97\xaf\xf3l]\x1cChX\xff\xec6%\xf917j\x12\x8f\xd9\xfbI\xb2]\x91\xc4\x1cA\x94\x93\xb0$\xaf\x12\xb2bn\x15}\x94 \x9e\xf1\xda\x17\xa25\xa2\x84\x9e\xc6*I\x0c\xb3\xe0o\xd4\xc1QZ\x83\xdfNY\xdc/\x1e\x14\xc3\xe4\x10\xd3\xc3CP\x03\xef\xae\xb9\xef\xc7\xc2\xf3!\x12\x85 3\x98\x1c\x01\xa1\xfb\xee\xf9 \x8bM\x03v\x84\x05\x1c8\xaeK\xda\xd5\x18\xf2Q+b\x19\x02\xa5\x8c\x810\xe6\xbb\xb7\xbd\x0d[\xa1v5]V\xeeV\xcc\x93\x11\xfd\x1fOZ\xcb\xb7\x84S\xd05\xe8\xb0\x03\xd3\xf6\xca0Y\xc7\xd2\x83*\x88\x96q2\xcfQ\xa4\xa1\xa1%\x94\xb9\xd2\xdaKx\x0e\x13\x13YQ\x0b\xb3\xe6\xc2\xac\xcd]\xd25bb\xac\x1bx\x06\xcb\x13\xb8\x19\x8d<\x98\xcfn.\xe4\xd1\xcdn`\x04S\x83\xfco\xec\xabc\x9a\xab'\xb05\x13\xee\x15\xc8=q\xe8z\xb5\x84\xe4\xc0\x97\x07\x8dO\x94\x9a\x16\xf1#\x9e\x8b;O\xdeD\\xi\x07\xee\xe8\x0et\x0cM\x08\x80\xe9ig\xee\x03c\xfc/\x0eP\x8a\x9e\x96\x14g7\x17\xc7\xaf/\xcc\xeb0*\xb3\xfcn\x90G\xa4v\xc9\x82\xab8\x9d\xbb\xdc\x07\xc9L8\x93@(\xd75/\xc5E\x10%YJ^\xa4\xf3\x8fL\xdc\xfd\x1f\xa4\x97\xb9n\xe6\x18p%\xbd\xcf\xa0,\xfd\x87\xdf\x03\xfa\x07?\xe7e\xc0\xa0\x8a\xcf4\xfb\xebB\x9f?\x1d\xc0f\xf0\xa2\xaa\x0d\x9brTd\x8a\x86\xdb@\x02m\x9b\xe8\x15n\xbfB\xc1\x03\x0e\xbb}j(\x12\xed\x9a\x8b\xb79\xd0\xa9\x14\xa03\x17@\x87\xdd\x9a\xfax\xc80h\xa9\xc3 \xb6\xde\xec\xe0#\x1e\x97\xcft\x0d\xb6\x0c\xef<\x0d\xdaT\x16h\xc3\xca\x15\x15\x11%\xb6T9P\x02g\xb0\xa6\xc5\xa7\x90\xd0\x7f\x8e\xc5/Z\xd7\x00\x9d\xee6\x84Nw\x1e\xac\x87@\xa7\xbb^\xe8t]C'\xbaz+\x06\x9dV\xf0\x0c\xeeN`E\xa1\xd3\xf5l\xa5B\xa7\x95\x05:)\x03\xba\x1et\xff\xf9\xddX\xfa0\x17@\xe0F\x95\x13\xd3\xc3\x1f\x17\x7f\n\x93xn:\xfe\x9bP\xa4\x8a\xbc\x88\x1d\x10AJ00&\xf7\xaa\x10\xc0\x7f\x80~\xe2T\xd2\x0e\x1f\x98Y\xc0\xdd\x83~\xa9@\x87\xb3\x03c%\xcc\xa0+wS\x8f\"P8\xe6\x87\xb0\x99\x8aq\xec\xfa\xc09%\xa6\xab\x8a\x8d\x04ef\x10\xd3\x0b\xc3R\xae!-H\xf9)^\x91\xac*a\x192\xb1\xc5\x15!\xdcK\x97\xcc\x9dn\x91|\xd5\xdfA\x94\x900\xff\x8a.B\xb3\xfc%\xc5s\xd0\x8c\xbe\xd6\xda4Et\xf9\xc6\x06\xc8\xc6\xbf\xcd(\xd3\xb5\x95\"\x880\xb4C\xf7\xb1)\xf6{\xda\xed\x94r\xa4\xec\x0b\xf5\x9a 9\x87\xd1\xa7\xd5\xdc\x1c\xb4l@8\x92l\xb5\x0e\xbd=\xb4\xdb\xe2\n,s[\x16\x10\xf1\xb0eg\x7f\xcdsHm\xb2\x04\xe9 \x9e\xc9?Z\xc4{\xa7\x80(\xad=\x18\xea\xfa\x03\x06\x95\xdb\x06\xa5\x1c\xde3\xf5\xe7\xb1\x04\x85\xa0w`\xb4\x8b\xca\xb6\x8a\xae\xa6\xa2-\x98\nu\xa6i\xfe\xd1\xfeV\xd3@Q\x0c\xb931]\xfe\xb6\x8e\x8e\xf9? J\xe4M\xd5\xeaY:9z\xe0\x83(K\xa3\xb0t#\xb4/\xc4\xb6}\x88D\xa5\xedmX\xba^\x9f\x96\xcet]\xb7\x166j\x96\"\x89\xd0]\x1b\xd4\xe28F\x83uC\x8d\x0f)\x01\x18\xd5\xfaerb;\xe7\xf8\x01\x85\x92\x91X\xd7\x13\x18\x8d\x12x\x86\xdf\xe0\x82\x14\xb3\xe4\"\xc8\xab\xd4\xb5X\xbc\x8a\xa5\x90\xbb\xec\xb9%\xc0%|\xec\x8e\x9a\xf6N\x865\xbc\x92\x0b[Jk\xbd\x1d\xdeP\x85 \x90\xf1d\xc6F\xe9\xa9\x95_\xf8\xc3\xbb\xb1\x830\xf1\xe4n\xd9\x864\xe2\xe9\x87^\xe2\xe9\xef\x08d\xb5\x83\x0c7\xed\xdd\xc3FC\x80V\x07\xc2\x1a\xa0\xbb\x03\xfb\xec\x8do\x1e\xf4\x05{\xe8\xbc\x89s\xbb*qQ\xa5\x92&3\xa44%%x;\x9b\xbbq\x15\x8b\xd3\xb8\xd6:\x0e\xe2\xf1(E\xc0hW\x03\xed<1`\xe9V5J\x1d\xdba\x01\x9d\xcf\xe4\x04Rx\xd6\"\xceO \xa5\xc41\x99\xa5\xb4+\x95@N5\xe28\xe2ZVr+\x96\xcf\xf3a\x82th\x0d\x05\xef\xef\x01\xa3s\x84\xeeR\xa1~\xe7\x92D2\xaf:=\xa6\xc4&p\x9bs)\xde\x06\xee\x85\xd2l\x1c\x94q\x89\xd6\x1f\xceU\x9e\xdd\x16$wh!\xff\xbb\x89\xba\x94\xde\xf0\xf0\x1bq\x10\xe6\xd77\x0c\x7f@\x1cp\xbbAd\xbe\xa4\xdfE]\x1b\xdf\xdd\xe0w\xf3\xf9OqQ\x92\x14\xdb\xbda/Q\xd9\xc0\xfe^,\xc4\x9f9Ye7D\xaf\xccJ_$\x89xQ\x887d\x15\x97\xe2\xefuN\xd6$m\xf5\xc4\x8b\xdf\xa7Q\xab\xddDj\xae\x97\xa1\x98]\xa8\xabw\x15\xa7\xf38\xbd\xeeVR\xe9T\xeb:\xcf\"R\x14\xf5\xc7\xb1f%\xedh[\x14\xdd\xce\x07x\xc89O\x1c\xed\xb3\xe5\x0f\x18\xd9&\\\x88\x91R\xe22y&\xc8\x81\xb3\xe1\xbd\xf9\xd3\xab\xcb7\xef^\xbfy\xf7\xe6\xd3_\xb0\xc6\x04\x9e\xd8V\x9a|)I\xda\x8a\x8bh[\x02\xa6\x9dk\xd3Q6\xf9-.\x0d[:7S-\x9f]\xe2y\x0d\xed\x04\xcf o\xd6\xae\x9c\xc5\x94\xc5\x9e\xa5\x17LD\x1a_|\xfb+$J%9\x9d\xd9]\xa5\x15\xd4\x8fYj\x8c=\xd35\xac:5v\x063n1\x95 N\xa3\xa4\x9a\x93\xa1\xa1\xcb(\xa7_\xf7\xa5\xbc~\xe0\xc6\x0fC[2D@3\x8c_<\x84\x85\xc7C\xe5.\xfdk{[\x84\xc6ce\xf8\xe7\xf66\xe4\xc2\x12\xbd\xd5\n\x1d_\xca\xde\xea\x9c\x06\xbeY\xc4IIr\xb7\xf3-IN(\x11\x17\xa2\x17\n\xfb\x06\xc11z\x0d, \xd4\xe3\xa740d\x0b\x08\xa1\x88\x96d\x15\x06\xf0F\xbcb\xf1\x0d)>\xc8\x16PT\xd1\x12[(Z\xc4a\xe0\x18\x8e\xe3\x12C\x1b\xae\xd6qB\xe6o\x9a\x95\xab8\x0b\xeb\x88\x018>\xcc.\xf4\x0f^}i\x7f \xd6\xd3\xf8\x01E\xcco\xc3u\x17E\nB0\xc4n\x90\xd1\xae\x80>l\xb1\x8e\x8dZv|\xcf\xc3j\xdak\xf0`\x9b\xf6\n\x8b0I\xae\xc2\xe8s+V.}d\x89{\xfdA\x07\xce\x17O:cW\xf1b\x86\xd7\x94\xf9P\x8a\x9e\x9a2C\x0c\xc3vw\x14\x90\x97\x0c\x90\x13\x83Z\xea\x04J\x86\xf9J\x0e\xbd\x1b\xc6W\n\xaf\xa8k\xff@\x12\x0d\xab\xe7\xc55\x9e\x16\xcb\x99\x90/\xb7\xf8+\x0c~|\xf5\xfa\xc5\xcf?}\xaa\xe5b\xa1`\x19:N\x848\x0d\xea07\xf1\xb5\xef\xf2\x80G\x01\xa4\x18\x97\xb6\x8e\xb3\xb1AyF\x9f\xab\x9c\x84\x9f\xdb\xaf\xba\x9c\xe1K\xada\xbd\xab\xc9f]q}\xa8\xa5/\x19\xc8\xfc9\xcf\xd2k`\x9e\x81\x08AD\x97x~\xce\x194\xe1\xbbP\xb3v]F\x01\xcc^\x81\x02vN\x0c\xd6N\xceM \xf3\xe5\x0b\xc8\x0d\xc9\xefz\x80\xa7\xc0\xb3\xb2\x1bN\xa8\x01*\x0dn\x9e\xd7\x916\x05XDn\x88\x83\xc6\x02\xdc,\xa7\x802N\xaf\x13\xc2g\xc8Mq=\xca\xa0\x95a\x9c\n\x98\xab\xbcm\xf9\xec!wA\x1e=\x8dl\xd3i\xd4\x81B\xb59P\xb8i\x9b\x81\xf4\xae5~q\x8f\xc9-\x84\xae\x01o1\xf4id\x89\x05\x1c?\xd6\x1d\xd3\x14\x11\x83\xcc\xa4\xb1M\x1bj\xab\xf8\xdb \xcaP2Ho\x05\xc6\xe4\x81Om\x16\xe9\x83}\xf9j\xcdl\xe9C\xac\x83\xad^},s\xee\x16\x06\xa1\x9b\xb2\xaf\x9a\x0e\xce\x0b\x8a$\x8e\x88{\xe8\xc3\xce\xa4o(\xdd\x0e\xf5{\xbb\xff+\x1d\xea\x87-\xeb?\x80\xd5\xf9\xb7:\xf7\xfb&?U\xe6\xdf\x12\xa7\x8f\xa3\xec\xb3\x9eC:@/+\xb7=\\7+\xf5\xf1\xa3&F\x1d4z\xfaQ\xcf\xd8\x91\x86\xda\xb8a\xfcJj\x19\xc3\xc1\xc8\xb21\xac`\xeaO8\xdc\x0e\xeeR\x81\x9e]G\xe6C\x1e\xaf\xe22\xbe\x19\xbcL*\xa1i\x04\x1d\xf8\xc2p\xbdX\xfc\xc5\xf6\x05a\xe5\xed#\xaeS\xb2FPW-\x16x\xe9\xcb\xfaG]\xed\xc1\xab\xddaR\xf7\xe0\xd0\x0b\xd8{\xb3@es\x0b\x06\x03\xe9\x8e\x1b(9-s=\x80\x08\x06\xf6\x97\x17o\x7fz%\xc2\xae9u\x82\xaa\xb0\xc8d\xdb\xc3U\x98\x7f\xe6\xa6?\xf8\x93\xc7V;mb%\xd1\xfat\xcd\xdc\x8a\xa7`be\x1ef\xb0p\x9bF\xcex\x02\x8c\xba\xa4\xc6b,\xf7\xa4\xe3\xf9\xf5\x90\xd7e\x95\x93\xf32\x8c>\x7f\xcaCth\xb4\xbc\x11\x86\x9cK9\x01X\x86q\x88\xb1\xac\xa05\xd1EYXhy\xbc\x8c\x0eY\xb2\xf6\xaa\xff\xca;,\x9c\xd8 \xe4HZ\xb9\xd5\xf2&W_\x8a\xb9\x0e\xa3U\xea}\x1a\x81s\x0c\x8e\x91f!h%\xd1\xb7 >l1\x07\x9dz\x1f(\x85C\x9a|$\xa6\xed\xd0s\x0b\xca\x94\xd6\xa0\x84\n\xbd\xf6\x026\xf7\x1d\x96\xcdK]\x95Z\x08>K\xdd\xe9x\xeaiV\xf7B\x01\x8a\xef\xf7w'\xe8\x88\xbe\xbf\xdb\xaa\xd7\xc8\xcb\xb1\xde.\xaf\xb7\xc7\xff\xdd\xe7\xff\x1ex\x92\xc5\xcbc\xc5\x9dv/\xc66(S\xcc\xda\xdc lCip,\xd4\xcc\xd6\xdc\xa9\xa5\x9ed\x00\xe7\xeeY\xeap3;Mm\xa0\xdd\x85!ru\xcd\xc4.\x17\x82\xcf\xb8\xa3Q\n#\xc8\xbd\xe6\x00\xef\x1e<>\xae\xce\xe3\x03\xfapV\xea\x11a\x89$%\x8a\x1e\xc4\x84\x87\xf7oE\x1f\xcax\xb9\xce\xb0n\x10=\x99\x05\x8c\xfdg\xf4\xe4\xea\x9bDO6\xdd\x8f\xbfOPa\xd3H\xf0ZF$N,7v\x91dY\xde7:\xcb\xd0\xe2\xe2]\xf8\x0e\x15\xce#\x14#\x8c\xe1\x18\\\xa1\xc1\xc81OZ\xbfD\xc1.\xaa\xe9\x0f\x10\xdcw@\xd5\x10\xb4|\xd4\x9a @X+\x18\xad\xb7\xba\xcc\x13xs\xf5h\xac\xe6_R\xe5\xb2!\x05\xdb\xf27\xfa\x18D\xd7]\xa6\x0b\xad1\xf4\xe4Nh\x0f\xc3\x1a\x9b\xdf6\x92\xdd\xe1#Ah\xb0\xe1`\x14E\xaf\xfc\x0c\x90N\xd6\x9dw0\x0e\"\x9b\x00\xb1\xa6\x12\xd8\x04\x1f\x0e\xbb.qoB\x99\xded2\x8f\x0dTf\x8f\xaefQ\xdaO\xc6\xbd\xb7\xce\x02\x0d\x1e\x15\xd6\xae\x8f^l\x85\xfc\xe2\xf2Z}\xf0\x0c+\xb62\x06VbNm\x19m\xea>\x16\xbe\xdc\xf0\xa8:\xa1k\xa4\xd7\xb0\xed\xca\x87\xc2\xe7\x99\xf0\x0c\x95(\x1e\x8efcC\x00\xe9\x04\xdf\xe8&G\xd9\xb0\xcc{\x1d\x9a/2+.\xba4\x9fZu\x83q\x80\xcf\x8c\x12xv\xbf\x96\xc5(\"\xcf\x98\x07\x00S\x1c\x17|X y\xc0\xe41\xf2\xab\xc2\x87)\x93\xb5\x9eu\xe3BhF\x96\xd4\xf8\x90q\x80\xfa@\xa0/\x16\xa9\xb1\x1d}6}\xc7Xn\x98\x91U\xbf=\x18\x15\xd0\x8f\xbf\x04\xc3.\x9f\xa2\xeb5y\xf01\xedo\x13p\xfd# \xa3\x92\x07L\xff?\x0e\xcf\x84\xec\x9c\xc0M\\\xc4%,\xcbr}\xfc\xe4\xc9\"\x8c\xc8U\x96}\x0e\xae\xe3rY]\x05q\xf6$\xa7\xdf=\x99gQ\xf1\x04?\xde\x99\x93(\x9b\x93>\x81\x9c\x999\xe6\xa3\x91\xc7,\xd5\x9d\xed0\xbf.f\x17X\x8f\xa4\xb4\x89\x9f?\xbey\x99\xad\xd6YJRY\xaf\x96\xc3\x08&\xba\xf2\x8c\xb5\xa1\x06\x7f\x17\xa2\x89,\x1f\x1e9\xbe\x89\x1a_\xf4\x87\x8b?i]\xff\x18\xe4\x10\xee\xba\xaa\x8e\xc1\xf4\xb83\xfa\xba\x0fq;\xacz\xdcs\xea\x06\x9d\x1b\x89\x82\xb2q4\x8f`\xe5\xebb\xf1I\x87\xf7\xcc <\xac^\xb8?\xb4\xff\x12\xeb,\xb7&\xc1\xb78(\x97a\xf9\x11[+\x98\xd8E)z\x1d&\x05Z>\xba\x18H[y\xf7)\xaf\xf8\xab\xb1\xfe\x8a+\x17r\x11\xcfW\xfdn\x19w\x9a\x8f\x88\xb9)\xf9\xf6\xb46^\xf0\x03>\x04\xa5\x9a\xfdO\xe0\x94\x1f\x94\x8d6P\x94v(\xa5\x9e|\xbf\xa5n\xd7\xf7\xf0iI\xe0\x8a 7W\xd9\xbcJ\x08,\xf2l\x05i6'\xc1\xaf\x85__D\xee\xf4\x1ah\xdf\xeb\xcd\xfd[X\x95\xcb,\x07\x80\xd7$\xcf\x8a\x02^\\e\xd5\xe7e8\x8f\x7f%Kx\xb6\xc0\xc2\x7fc\xff\x04Y~\xfd\x1c\x9e \x88\xd4\x94\xb5\x1a\x15\xf6H\x8aA\x12{\xf9\xa4uu\xb9\x1c\xaa\xc5?CC\\\xb4\xb2\xe4A\x93X\x0f\xef\x94\xf2\xb2\xbe\x10\xed\x98+\xd0le\x11|\xfa\xcb\x87W?^\xbe\xf8\xf8\xf1\xc5_.\xcf\x7f\xfe\xf0\xe1\xfd\xc7Op\x06\xd3\xc9\xde\xd3\xbd\xc3\xdd\x83\xbd\xa7p\x0c\x93\xf1\xd3\xdd\xa7{\x93\xc3\xa9\x96\xef\xd6\xd2ah\xc5\x95\x94\xe2\xa4\xc3yF_7\x86\x17\x1f\xc3\xf4Z\xf0\xc9\x14(%\xf1\x1cI\xd190Os\x865:\xcc+l\xb3p\x85\xbd\xd3\xcfqZ\x1e\nCc/\xb8\xbcDl\x7fy\x89!,\x1a\xf9\xea\xb1b*\x82l7o\x00}\x9c\xe8a\xe7\x18\x8c\xe5\xb8\xd3\xa1\x85y=\n\x1b\xc5\x06\xc2\x88\xcb5O\x80\x07\xc4\x97\x95 \x85\x9an\xa0i\xba\xbd6H\xde\x1b\x14\x0d6\x12\x0b\xeb\xb7\x15\x10\xcaN\x89MZ0\x1c\xc9=\x9d\x8b\xda,\xb9\\\x12\xe6\x86\xb2\x88\xf3\xa2\xac\x11?\xac\xaa\x02\xedgB(Z\xd1j\xe5G\x10A\xf6x\x08\x0f\xb63\x105\x01i\x0cr\x1c\xcb\xd6Db\xfd,\x0c\xaae\x0d\x89\xd9l\xe8;!\xb5Q\xe7\xcdm\x87BnR\xdf\x91~\xda\x9c\x89\x16\xcf-W\xe5lo\x03\x91\xcf\x83\xfc\xae\x1dK\xbb\x83\xedFW\xbf\xe0\xea\xae$?\xe1\x89\xf6\xd1\x0co\x0c\x98\xeb\xba)\x86g\x8d4K\xbf\xaa\xdfe\x8bEA\xca\xef\xe8\x11\xc8*4G\xbf\xca\xaat^\xd8vW\xef\x936\x0e#p1\xf7\xf0\xd8\xb3\xf6\xc3\xee\xdc\xf0~0\x00A#cI\xa5\x00n\xa7<\xf0o\x0b(\xd4F.\xd6*x\x81\x8fM\xc5t\x99\xcd#\xe9\x04L\xa4\x0b\x10\xd1\nk\x06H;\xaf\x8a\xc1\xd0O\xd9\xfdc\x93R\xb1\xc5\xd8tx \x1a>\xc7\x05\xad\xf3\xc9\xdf\xdf3\xe7P\xa7*\x17\x87][\xbfU\x04q\xf1\x8a\xc3\x0d7\xb58`\x7f\xe7\x08\xd0\xe2H`\x83!\x056\x94\x1a\xf6\x98n\x12H\xf8t\x0c\xf70g\x1bg\xf6\xd7\x02\x8e\\]\x16T\xa8d\x86\x8e\xb7y\\\x12\xd7\x02U\xd9'u\x96\x02\x97\xf9\x042#\xfc\xb1\x0f\xb1\xf7\xe8\xed\xf2\xfaL\x1f\xc5C\xd7\xb2\xa8\x15\xba\x141uH\xb3j\xd5\x08\xdc\xc3\xd2%\xc2\xe7\xc9\x166c\x08\x906\x9a]Iu\x82\xb8\xf8SLX\xda\xfdv\xb1\xc9\"L\xaa%\x8f\xb4!0\xdb\xa3\xad\xa9\x99-\xd5R\x0e\x11\x1dK\x1caX\xe2\x9b:\xd9f\xd7*pj\xb3\x1eIW(\xc2\x1c\xc3\xfb\x9d\x9cx\xb5\xa2\xcf\x8a Q\xbd\xe5\x84E\x14\xc7\x8eY\xc9\xc5j$a\x19\xa7\x93\xce*Wq\x1a\xe6w\x96* )w\xcd\xe8\x845\x82d^W/U\xb9\xd8\xe9\xac\xc1\x08\xed\xdeQ\xfc\xec\x96\x9eu\xc1\xa1\xe9.*\xa6\xdd\xe3\x89\x8a\x9d\x9e\x1a\xe5br\x90\x90\xbe:;\x1d\x95\xa0\x19\xf7\x14\xbe\xef^\xc1%\xf9\xd2\xdfJ\n\xcf\x9f?\x07\x83?\x114\xdb\x19\x16\xe4`\xaf\xbf\xa9\x1f\xfa\x16\xb2\xd37\x1c\xa0v\x0c\x19\xba1\xc0\x990\x96\xac\x86Ph\xf6SvK\xf2\x97aA0\x03\x19F\xa1k}\xaa\xebR\xcd\xe0\xeb\xa6\x8bc\x11w\xab\x9c\x11\x03\xec\xe7F\x14\x14\xfd\xf9\x02 \xe6\x83:\xbd\x93\x98*\x8b\xfe\xb8\x01\x01eM1\xf2\x05\xdb1l\xa3E\xdc\x92R\xee\x10\x85\x81\xdc?\x0eyNx.K\xe4\xce\xf0\x8d\"\xa2\xa3\xd8}\xa7.9D\x90F+Ie\x1ekp\x94\xfa\xdcB\x82\x852\xc6j1G\xce\xa5\x1ccQ\x88\x04D\xa5\xfa\xe5\x08i\xfd\x94\"\xc0\xb2#\x88\x82\x98e\xdc\xb9\x0e\xc0C\xe0\xc8]\xb7OF\x13\xf6h\\\x99\xc2J\x91\x86}\xda\x99\xc01\\k'\xcarB\x8c\xc2'\xde0\x81m\xa4u|\x8b\x9c\xc1\x86t\x1b\xf1\x85d\x10\xcac\xee\xc0\x19\x1e\x86\xae*\x8d\xe5\x0f\xe7Z\x8d\x95\x93\xb0(\xdfX>\xc0\xb9c\x12%\xfb\xec\x8d\xbc\xcbM\x98\xd4\x84\xbd`WD\xa0\x8a\x9c\x93W\xadP\x14\xe6\x1b\xad\xaf\xbf\x05\x98d,5\x8b%\xbc_(\x1d\\s\x8dB\xa2\x82\xcd[,\xa5\x16`\"\x05\x86\xd1\x18\xffM!\x01'\x04s\x0d\x8c\"=\xc4\x91\x1b\x17Za\x01\xc7ej\xd1\x8eTf\x95\x17\xc4,*\x91\xa0\xd8\xa7L\x18\xd8\xfc\xee\xbdWt\xa5\xa6>\x84\xf0\x04\xff-\xf8\xbf)\xfek\xb8o\xad\"M0k\x1b(\x1f\x06\x0b\x17U\x89\x8c]\xc7<{\xee\xcfo\xd2rr\xf0\xc3+\x97\xc0\xf7r\xb6\x11\xf1\x98\xef\xb9\xd5&H85\xda&\x8d4\x1d\xaaaN \x83g\x10\x9e@6\x1a\x99\x992\xe0\x9d\xe1\xf42\x0f\xc7\x1fQ\xf0\xc1C_-8\x1c\xce`\x07\x16\x9dr\x1d\xd1R\xfd\xa1\x88\xd2\x9dy>\xfb\x1cF|\x81\x8az\xdf\x16tA\xacMr \xbb\xc3\xc2\xd7\xb2\x163\xd89\xe5\xa3\xf1\xf9*X\x80\xb3}mR\x18A\x01\xcf!\xac1I\x08;P\xe08\xf9\xaa=Gf.\xdb\xd9\xe9\x9arM<'<\x88\xed\x9a\xf1\x80kx\x06\xc5 \xac\xbb\x16\x1d\x94\x85\x87\x11\xac=\x16\xa4\x97.\xfe\xbaw\xa5\x81\x9b\xc0\x98\xfc\xbb\xf5\x07\xe3\xeft\xd62\xcbq\x80\x0f1\xa9\xb7+3\xd6\xb3j@vt7k3\xe0[\xf5h\x07\xe8\x061o1J!\xdc\xdf\x9b\xf8\x18\xa1\x04\x97\x90\xb6\x81\xe2\xcd\x05-\xc3\x9b\xa3\x90\xe79\xc4x\x0chqLq\x01\xfea\xee!\xeb\x85\x9d\x19\xfc+L)/7\xb68r\x0bu\xe2\x92|\xe9P=\xe5\xf0\x1c2x\x02\xd3zh\xf8\xabK\xfeP\xb1\xb3W\xb1h\x87\xa3Q\xd5\x05>(\x9aX\x87yA\xde\xa4\xa5K\x82\xa2\xba*\xca\xdc\xa5|B\xe5\xc3\xd4\xf3ar\xd0!7g\xd4\x9a$(\xac\xccu\xcb\x19\xbdi\x98\x8a&\x1c\x00\xf4Dc\x83\x0e\xcde\xcf\xa1\xe1\x8d\xfd\xd5\xfd\x19s\nK\xc7\xc2C\x95\\\xdb\xa0\xd3\xd6\xd3\xd5\xd0\x9e\xec\x06\x03u\x9b\xb2\x11\xd2\xecB 8Q\xb3\xf2L\"\xc6\xb3\xed3\xc1Q\x19D<\xe4\xc4\x8b\xd2M{$\xfam\xc0\xf7\xc0dy\x9bL\xfav\xd8\xa4\x95\xb5\x19\xd4\xf0\x97a\x0d\xff\xd5\xfda\xf3A\x9f\x0fm{\x90VC\x0e\xec\xc0\x83\x93\xf2]\x93\xaeZ}\xb0\xb6\xb7a\xcbu \xc5NS\x0f9\x02~ \x19+!\xed_\xc5\xf9M\xcaO\xc3!\xcb\x84\x93R\xb0\xb1\x7f\xe0C\xc6\xb6=\xf6\xea?m\x9a<+H~\xf8\xda\x03\xff\xaa\x8b\x9fUY\x08\xf4\xe9TXL\xf4\xd5\xa7<\xc8\x0fw%\x91<\xa2[\x85\\E\x85\xfd\x0c\x1b\xd7\x8b\xaeq\xa5RL\xa1\x9af\x1c \xb2\xc5\x10\xf3\x18\x83\x1ab\x14\xddv\x81\xcd\x8c\x85\xf8\xf0E~\x93r\x16\x1bLS\xc5\x83N$\xc6L\x89\xe2A#V\xcaJ\xef\x1e\xc1\x19\xec\xc11\xfb5\xdd\x853\xd8\xe5\xbf&G\x138\x83)\x1c\xdbD/\x08\x91a\x04 \xad\x87[|\x83\xe1Z\x8c\xf8\xc5#\x8f\x8f\x81\x05\xf6kz\xe1kS\xc9p\xf4jY%\xcdh\xb2_\xcfh2\x85{p\xc5\x9c\xe4)Vt\x8a\xd3\xf1\xdeS\xfe\xdd3\xd8\xdf\x9f\x1e\x1dP\x92\x88\x92\xb3\xfbOw\xf7v\xbdo:\xff\xbd\xc7\xcf?\xac\x7f\xedn\xb0\x1ajYhY\xa1Cm\x85\xa4%\xab\xd4%\x0b\xe9\x92\x1d\xec\xef\xef\xee\x03\x06\xf4x\x06\x93\xc9do2\x99J\xcbd\x9c\xa2\x99$\xae\x8d\xb1(_\x84\x9f\xd3\xb6w}\xbc\xc9\x18tl!\xf7\xe7.(>\xa0?\x0f|\x11\xb5x\xc1\xc4\xa8c\xd8\x86\xc9x\xba\x0b\xf7l\x1397\xb3\x7f\xb0;\x1d\xc3={\xb5\xcd\x0c\xc2\xf9w\x1e\x05T\xa3SH\xda\x10\xdf\x06\xa5\xfb)\x12A\x8c\xd8\x15 \x14\xe3\x14\xbc\xbc\xafI>C8,\xee1\xc2\x13\x85\x1b\xf5\x16 \xe9.\x1c\xc7\x0e\x18s\xb32\x10\x04\xf4\x16\x06\xd3\xdcXz\xc0`8\xba\xc9}\xa6\x9a{\xdfCD\xa5\xedEv[\xe8S\xfeE\x82\xda\xb7\xbd\xf0\x81\x04\xe7Iv[\x97t\xef\xc3\xa8l\"\xab`,\xdc.\xbbBT\xdd\xb9#S\xa0\x837\xef\xce?\xbcz\xf9\xe9\xf2\xed\x8b\xff\xef\xf2\x87\xbf|zuN\xcf\xd3\xd8&\x8b;U\x93)\x9b\xcd\x82\xcc\xe5=\xb1\x13\xed\xf9\x8cn\xa4\x88o\x92\xc9\x92\x9e=G<\xb5\x02M\xb6J\xb2\xe3\xb4\xba\x96Y\x00\xd8\x81\xa8\xb3l@8H\xf1\xf0Q\xed\xb5\xe5G\xe21\xc3\x8e\x07\x1f\xf6\xa6\x9cVZd\x99\xebY\xc5\xa1%e\xc8\x98\xa5\xe9\xf6\xb6p\xeb\xad\xcb\xdc\x89\x0f\x13OR*\xb6\x8fjg\x0c4h\xe6\xb0e\x90\x9d\xa8\xe7\xca\xf5\xe8\xc9\xfa\xfc6\xfc\xc2-\xe4P\xc5L\xcf\xd4:\xcb\x92\xf3\xf8o\x14x\x1cN\x8e\xa6\xb4\xe82\xac\xae{M\xb6\xc1\xb6\xb1\x85\xe2\x0c\xa3\x1fo&\xd8\x1e\xe0u$\xb5\x1f5\xe9\x05\x0d\x16\x98\x1dBjW\x1a\x8b2F\xe3\xb9\xa237\xd6\xf1-\xf6\x93<\x9c\xcc\xf66\xff+@{U\xc2\xf3\xb8\xa9e\x17LbF_\x99\xc3\x9c\x16\xbe\xd6\x8a)\xe0)wh7S\xa3\x9d _\x1e\x98\x1a\x01\xc1\xcef\xab\xbf\x81\xed\xa7\xf8\x02Y>D4ca\xd6$\x1bB2\xf3\xbe3\x93\x05`\xde\xd4\x0f\x161\x0b\xea\x86\xc6\x86j\xa1Tb\x00\xf0}\xa7\x05\x17\xe1\xe7\xb4\x08\x17\x83\xe3\xafX2\xb5\xe9\xcdQl\xf1-\x9a\x94\"\xac\x0cjk\xcbmb\xa1\xdd\xdf\xc3V\x19\\\x8a&\x0c\xadG\xd9j\x1d\xe6\xa4\xcf!\x1bd\xf3\xca\xdar\x03\xdb\xd7\xf4QF \xd9\x8b:\xba\xb7P\xac\xb0/\x8c\xb6&\xcc\xf0Eu\\\xee2s\x90\x15{\x8c\x0d'\xf5\xaf\x98\xc5\xa1\xcfdN\x92\x99\xd2\"k\x98Q\x86\xde\xe2t\x8b\xc3\x98\xc5\x17xD\xc9,\xbe\xe8B\"\xa9\xe0\x1cY\xff\xad\x0c$\xf2c\x97\xddZ\x89>\xccw\"\x94zh\x8e\x04g0Q\xe2\xe1Bs^\x84\xf9k\xef\x89\x11l%W\xfe\x94-\xe5\x8fy\xc2}\x06\x06\xdf\xca\x84\xe3\xbf\xc1\x1ee\x80\x8d\xc3?\xa8\x01\x88) )\x0c1\xb3\x18L'\xf8u\xe6\xd5\xc1\xd0!\xb3\xa6\xbc\xfa\xceI\xe2\xa24\x99N\xf2\xe0{\x90-\x04P\xb0YQZ\x0c\x1f\x04\x01m\xa2\xb1\x11>\x98[S\x02$\x18W\x0b!\x0ca\x10\xa4C\xaa\x8b!\x89f\xe9\x85\x95\xdd\x12r)\x05=P\xbch\x86;f>IO\x1d\xa5\x8d\xc2N\x9cW\xdc\x18\xc5\xce\x06\xca \xbc\xfa\x9d\xf6\x8f>\x153\xe6FM8g|E\xf4\xd6\x9e\xb3\x08\xcd\xb9mEg+dg\x8fS\x98\xfb\xa0Pz\x12\xfa\xdc\x1a\xab\xef\x8a\xdbp=9\xe8\xf3\x0c\x17\x0c\x0e\xc6\x8c\xea\xd2\x13\x95F=\x91l\xae\xc9GRP\x12\xbb1\x1d^UI\x19\xaf\x13BWpr\xb0s\x15\x97F\xb4\xa8(\x1a\xc6'h\xbe[\x9e\xb0\xe37\xf5\xe0\x86\xbb&\x11Jm\x8dZ\xd9KA\"\xd1e\x17M\x10\x8b\xa8.\xcb\xee\xf4\x9b.\xcb\xdeW.\xcb\xee\xf4Q\xcb\xb2\xd7Z\x96]\xcfo\x8a\xe82\xb1\x7fLZ\xb8\x0dV\xeb`\xef\x9b\xae\xd6\xe1W\xae\xd6\xc1\xde\xa3V\xeb\xb0\xb5ZO\xcd\xabu\xa0\x15O\xd9?\xfbZ\xf1.\xfbg\xef\xf1kk\x8a\x1f\xd7\xb5\xbah\x9e\xdc\xb5\xc2\x8a\xa6\xa3\x8e\xaa\xc5~\xb6\x02\x08\x9c\xc1\x0b>\x9b1\xa5\xcc\x07\x84\x87\x92\xc7\x93wh\xf2\xe9F+\xf8\x07\x8d`\x98\xcd\x99\xb0\xfa\x1a#\xdb\xf4\\\x9eO\xe3Q\xe2\x0ck\x17\xfd\xa6R\xbd\x91\xda\xd4N*D3<\x8a7\xcda\xb69Y\xc1\x10j\x15\x06Q\xac\xe2\xe1\x9d\xbf\xd8\xa4\xf3.:W<\xbc\xdd_7i\xb7\x93:\x86a\x14\xb2xx\xff\x9f7\xe9\xbf\xd7v\x18\x9a\x86_m\xd2p\x075\x0e\x83(r\x18H\x95\xc3&\x9494\xb3y;l6\xbd\xc4:4v\xd1F\xc6\xfag\x1e\xf9Rx+\x1e\x83\xcd\xbd@~J\xe6\x8e8\x02\xc7\x19j6\x0dF\x9a\xec\x81\x8b\xe4\xd9dmA\xa5T\xa0N\xfeZ\x85Iw`\x170J\x1bzd\x0b\x122\x146\x9a\x9d\x88\x87\xe3\x80\xfb{\x0e,kY\x88\xd9/\\\x9bE\x9c\x16k-xr\x17f\xb2)F\x98\xffRK\xca\xdf9p\x81\x9f\x9es\xb3\xe9\x9a\xae\xa8\xddy\x10Fr\x7f\xc9`\x15\x96\xd1\xd2}\x12\xfc6}xr-2l\x80#\"\xe3\xd6\x8d\xf1\x10\x80,\xc8L\x10\x04\xe0x\x9e\x0f\xce3No\xd4\xe1r\x9e;]\xebb\x91'\xf5\x1a\xb5\x7f\xfb\xad\xd6y<\x05\xb3\xea\x9e\xdb\x0c!\xa2v\x84/\xc8\xb1^/\xaf\xed\xb6\xb4\x17\xcc\xd6,naT\"|\xdd\x11\x03\x8bv\xef\xefQ\x80\x83/b\x1d5\x9b)>\xee\x8f\x9e\xd3\"@\xfbh\xdb|sx\xce\xc7C\xe8_\x9dnBM\xfd^\x17\x02\xad1{-\xa4\x03|H\xeb\xbf\xf2\xfa\xaf\xb8\xfe\xab\xb9|\x83\xc4{\x19\xba\x0e\xec\xd0\xd3\x83!\xcd`\x87\x1e\xa7P\x96\xe8e>T\x1e7\xdf\xc0\x00\xc8B/\x18s\x15\xacb\x99\xc24\xbb\xe3\x13H\x98!\xedh\x94\xd8%\x80\xd1,a\x12\xc0\xc5,\xe9\x94\x00f\x18\xbc,\xe1:sZ\xdb\x0e\x83\x1f!\x01\xcc\xe0\x19\x1a!\xa3\x04\xb0\x82g\x90\xd9%\x802\x94\xc2(\xc2C\"\xbbI}q\xe3\\\\J\x91%\xd7.Ao[\xf7o\xd4\xd9\x9d\x1aR\x03\x03\xaavu\"\x99\xfc\x7fmG\x93\xce\x8e\xd0C\xdf\x0c\xc7l@L\x8b\xb9Y\x93\xb8L|$\xddt\x9f\xf3_\xadVj\x0f\x14\x1d@\x99\x83\xa6\xe4,J\xf9F\xad\x9b\x8f0\xc2\xe0\xb8x\x1d\xa7\x18\x97\xc03\x04d\xe1\xae\x92,r\x81p\x8c\x10\x84\x87\x0f,P\xc7\xcc\xe7\x91t.<\x16\xc9\x11\x92,\xbd\xa6\xfc\xaa\x88Fk\x0f\xa8q\xcf\x00\x85\x18D\xea\xc1\x19\x05\xcc\xac\xd8\x08\x899\x07Ay3\xd9\x9f\x89\xd5\x1db\x94_\xdb\x18K\xa8pGO\xea\n]\xacU,98\xc9\xc1{\x9e\xd7NM\"\xe2 \xe3\xef\xf0\xafA`_r\xeeeg1\xab\xca\"\x9e\xd7A\xa9\xec\xf1I\xf2:\xae\x805^\x86\x02^U'Q\xabJo\x08\xff\xc5/\xdbJ\x0b\x94c\xde\xf2^\xd6k\x18\xdb\xc5\xfb\xbc\xdc\xa0\xcf>\x8e\x8b7y\xb5A\x93_\xab\x8a\x80\xa6\xdb\xdb\x0d\xba\xed\xe5\xb1x\x9b_6h\xf3\x1fN\xd9q>h\xf0\xbd\xdc\x14Z\xf3o\xc4I\xd9,u\x01\x98A\x13s>\xd5\xbd\xa6\x98\xc2\xb1\xdf\xf9T\x97v\xfd\xdf\xf3\xf7\xef\xfa8\n\xbe\"\xe6\x1bJ\xdb9\x06\x11\x0c\xc4\xccr\xcc\xc32<\x06\xdd\x93\x0e\xe9\xa3&oFp\x19\xe6\xb9\x88\x0d\xe6\xf7\xc3R-\xf8*\x05,\xef\xe1\x14\xf6\xc6G\x07\xb6\x90q\xbfv\xe1l!A3I\x92\x1ec\x16\xac\x98\x03\xa3\xce\x97\xd9\x8c\x992@\xa2\xc1)js\xed\x0c\xe40\x87\xde\xcf\xff\xa8S\xfc\x16\x93{3drv\x1bDw\xcb&\xf5t\xb78r\x95\xd8\xa7\xbc\xc1\xb2\xa6+\xa9,\x82\xe3\xb0\xfbG\x98\xab\x1c.F\xe61}\xd3k\xb7\x9ce\x1dS\x8f\x07M\xfdm\xd7\xd4\x15St\x8d\xf1\x90\x877f\xc3\xcbk=^\xc659\xb1m\xd7\xf2Yv\x01#\x98\xee\x1f\xc0\xf7\x90\xcf2S\x90X\xd8t.\x9f\xba\xe6\"4\x12\x13\xd4H\xb0\xd8\x18\xf6H6\x0e#\x01E\x04\xef*NK\xbb}\xc7\x08\xc9 k\xdc\xb7O\xf9]\x9c^c`\x13Lj\x00W\xe4.K\xe7\x82\xf6ak6\xd0\x0b\xf7\xa5*\x82@\xa7\xc8\xc7K!\xbes\xd8\x18\x8ca\x80\xb8\xb0D\xc4\x0f\xb1i\xb2 \xba\xa8\xf1\xe3\x9fY\x03\x03\xe9\x91\xfe\xf4\xd8t\xb6\xe615\x88$t\xb0\xc7\xc1\x9c\x93/ \x8b\x17\x06\xae\xe8\x87\x1ef\x88\xd4>\xfd\x84\xdbS\xef\xe3\x86\x9b\xf5\x92\xca\xed\xd5\xadud\xaf\x17\x1f\xa6\xaa\xe1\x0ewG\x8b/\x00\xf5\x10\xdb\x18\x94\xe7\xd938\x84\xef)\xfd{\x061\x1c\xc3\x04v \xf6<\xb4\xd16\xbc\x184\xe1\x8f\x1bMxoz\xb4wt\xf0tz\xf4\x8df\xbdg\x9f5iOk\x17\xa7\xc5\x16c\xd0\xe4\xde\x0d\xbe\x1f_s\xb0lG\xb5\x03\x9e<\xfa|\xfe\xa4\xcc\xc88\x9dZ\xaer\x7f\xcf\x16`\xec\xb3\xa5\xf6!\xe6<\xae\xdc\xc6t\x97\xbd\xa3+\xb07h\x0c?>z\x0c\x87\x961\xecO\xd9;:\x86Cm\x0c\xf2\xafB\xa7\xeb\x86\xd8\xef\x08\xaf\xb8aJ\xeaS\xf8\xaf\xff*}=\x08&\xe1\xb9O\xfe\xeb\xbf\x88\xcf0\x05\x0bC9\xa2X\xbb\xbe!\xa5\x888RR\xc4^\x17\xe5^\x13\x92\x8c\xe5\xea\x92\xbe!\xe2\x1bR\x7fC\xa4o\xca\xba\x04\x93\x1d\x1b\x03\x985:\xcf\xda\xea\x1a\xd7\xc2\x1a s#\xf9IM\x81\xc1\x8e\x9eeE3\x86\x11\xec\xec\x101\xef\x13<\xda\xe3\x9e\xe9\xd2\x0f\xbe~\xc2\x87C\x00\x02o\x90\xd4s\x9c\xf8\x9a\x82\x83o\xdc\x90\x1e'\x07\xedc5\xa8\xd3\xa9\xa5Sn\xe9\x81\x8b2\xb9@\x9c?l\x1c\xed\xcd\xfe\xbaq \xb5\xa1\x0cf\xc88v\xa7\x8f\\\x8f=}\x1c\xae}A\xe4\xa2)\x16\xb18\x7f\x93\x83\xa7O\x9fN'\x94\x8b\xa8\xdf\xef\x0e\x1c\xf6#\x97\xaf5\xec\xd6\x18.D\xe2Li\x06\x93\x83\xf6\x14\x94Y\xed^t\x8a\xf0\xe9\xb0\xff\xd7A4x~\xca?\x9fL\x0f=.\n\xdf\xe1\xb4\xe3:\xbbu)\x95\x00\xdf\x03\x06\xf3\xec\x05\x07\x7f\x0f\xf0G\x94\x85\x91`[~q\x82\xe4e\x1b\nf\x1a\x14\xcc\xbb\x17)3,Rf]\xa4l\xc0\"}#\x90\x89\xbe\xd7\xf5\x89Gu\xde\xf7\x80\x11!v\xa4{0\x11\xa9\\\x07@\xd7\x0d\x80\xab\x15\x9a\xb5\xd7\xf1F\xf8UX\x81\x8bu\xedw\xa7O\x0f\xe8$S8c\x8c\xd0x\xf2\xf4`\x0c\xf7\x90\xc2q?\x05\xb2\x01\x8c~\xf4t\xd8$\xee\x15\x10\xfe\xfbM\xe7\xdb\x81\xfa\xcd \xbd\n'i\xd9to\xd0p\x87\xad\xfe\xf0\xe1b\xcf\xedA\x0f\x00\xee}\xc3}\x9dd\xa1\x01\xba?n\xb816\xd9(\x1a\xb6\xc6\x82\xeb\x1b4\x8co\xb5j\xadaL\x86\x0e\xe3\xc7\xac\xbaJ\xc8#\x97\xe3\xb0w\x1cc\xc1\x80\x0e\x1b\xc7#\xd7\xa3\x7f\x1c\x93!\xe3@\xe6\xd9\xca\xcdX\x848<\x9d\xa7\x82\xe0\x98\x15\x0b\xaam_\xea\x06\x04:2I=\x96t\xcc\xe6\x88\x12\xdbc\xfce\x1dN\x1fx!H\x13r\xba\x14\x94D\xdaB\x93\xac*#\"N\xa1\x84'\x1039\x90\x15\xbc\xd1\xca\x9dP\xac^I#\x99\xf0w\\\xc9\x14\xabXW\xd3`\xa4$\xad\xa6\x10\x9f\xd5+\xba\xb3\x13c\x808N*\x18\x964\x16K\x9a}\xb3%m\x11\x15\xdd\x16,\x86E\xd5\xd7\x92\x02\x8b\xfd}\x1f\xf5(\xd6|?\xb8;M\x06\\\xb7\xf4\x04\xb4\x96O\x197\xf9\x1f4\x11\x13\x05\xf2\xd5s\x99\xfaLr\xdc5\x9b3\xc3\xf5\xf0\x9b=\x9b\xb0=C\x11)\xa5\xa9>(\x1dl1\x1b\xfb\x91\x166\xd2>\xc9\xc1\x94\xf2\xef8I>\x1b}\x92|\xee\x86IN6\x9a\xa4\x89Z\xf9\xeaI\xee\xf9\x92H|\xd0L\x19\xcd\"f;\xdd\x93\xa6;m\xca'\x07\x96\xbd6\x1cg\xba2\x1f\xcd\xdb\xdfI\x16I+\xf3;l\xff\xe6+cY\x95\x89eU\xa6\xe63\xb3\xdb\xbd2\x93\xc1+\xb3!\x8a\x15\xd2cyY\xb6\xac\x06G\x02\xd4\xb7\xd0\x03\x86\x8e6\xcbN[\xb8%f\xa8d\xc7\xe0\xe6m\xb6\x07C\\lF,=Qz\x1f\x89\xc1+\x19\xdd\x08\x917wJb\x7f\nsL\x86\xdb\xe9\x84.\xf0\xcb\x10C\x14\xf9\x1a\xdew)\x96\xaa\xe0\xf9s\x18S<\x1a~\x13|\xb5!\x05\xf0?e\xa3;\xa8\x88\xaf\xdal\xb1\x17\x12\x81\x915\x04\xc6\xc6;>\xfa\xfb\xec\xf8\xefB\xa0L\xa6O}\xd8\x99L\x0f7\xa7Q\x14\x1d\x12]Z\xe6\x930\xf9\x1a\xfa\xe5w$_v\xa7O\x0f\xe8\\Q\x860\x0c\xb4\xff\x8e4\xcc\xefH\xc2\x04_K{0`\xca\xdd{;\x80\xc4QH\xa2\xaf\"h~Gz\xc6\xbeD\xea\xf5U\x8c$\xc4-\x1e\xb0\x8a\xff@\xc4\x8fE\xfe\xd4\xbd\x8a?i{\xd6\xe7U\xd1\xf4\xb4\xe9~i=M\x06\xf5d\x93\"uw\xf5\xe3c&e\x13\x14m\xd4U\xef\xac\xa2l}\xb7\x19\xdd\xd2\xa4\x9b\x1c\xa3Cd\xed\"\xd8\xd8\xd5\x97\x9a\xa7\x97\x94\xa5\xa41E\x90+\xd0\x0fI\xdd\"Wq\xe45 \x88\xce\x0b\xcc\xfb\xb2/\xbdS\xdc\x8a\x84\xd2\x0cP\x1eVO\x13\xa4\xcb\xf0\xa6\x0c\xf3kR\x9e\x97a^\xf6gC\xad\xcdx\x80\x19kj\xc30\xf7PdU\x1e\x91\x0dz\xc8\xbb\xc6\xcbZ{\x95\xce\xfb\xdb\xcaU\xe7\x8bz\xf5\xd5\x1d\x95\xec\xaf\x08\xc6^\xda\x916Jy92Z\xe5\"A\xcb\xf4[\xb99n=\x12\xc8\x8d\x1b*\x06]\xe6\xcaA\xec\xb1#$M\x0c,]\xc2\xe4\x04b\x9e\xd5`g\x07\xcd\xc2b\x18\x01\x03\x92\x14\xd6\xd1_\xa6\xb8/\xb5\x93\x11eA&d\x17X\x18\xaf\xcd\xb2\xfe\xb105\x9aY\xda\x06\xfd\x1b\xf3\xb9\x14\xa4\xac\xf3\xb8\x94\x8a\xa9N\xca\xcc\x9e2\xcf\x9c\x0bS\xe8\xfd\xba\x00\xc1\"\xc6\xf4\xf6\x1b\x00\x02\x83\xd3\xd5\xc6\x99\xadEz\x02\x0c\xa9\xc1\xd1\xa6vC\x8c\xe9s%\xb8\xd0\xfe\xc4\xe7Y7\xfa2#\x81\xec\xe2$\x07,\xb7Y\x1e\xd1\x87n\xe9t\xff\xa0F\xd4\x96\xf8h\xf6|\xabz\xb2\x19C><\x9b?{\x9d\xf1{h2o\xcb\xb2c\xbfj.\xe0\xdc\xe6Ul\xf3\xfch\xf5\xc7s\x97\x98\xf2\x9d\xf3\xc5b\xa9\x92\xacF\xbf\x1cF\xca\xe0\xe7\x19\xc3\x0dj\x91\xd5*\xfa\xfd`O`\x0c\xe7\xd1\xc4\xcf\xa3\xed\x9b\xa1Tf\x1bl\xe3\xcc\xab%\xba>SF{\xcc\x93\xc8\x8d}h\"{P,gL\x0bo\x87'\x06\x8b}\x04\"L\x93a\x01\"viB\x85\xb6|r\xacB\x96Q\xf8g7\x15)\xeds)\x01\xa6\xd7\x91\xbc\x99\xb2\xdc\"N\x95\xf9\x10\xd6\x13\xe0\xb6z\xe8\xa3\xacLB\xc0\xc5j\x96\xc1\xbfB\xb8\x81\xcd^\xd9\x8a\x91\xa3\x8e\x81N\xf6op\nOf\xff9\xfa\xe5\xc9x\xe7\xe8\xc5\xce\xff\x0bw\xfe\xb6sy\xf1\xe4\xda\xe6z\xf3\xba;\x84+\xa0r\xf6\x0c\x9c1:\xfd\xabiB\x8f\xb5\x02ul\x96\x0e\x7f\xb6*\x00o\xcc\x01\xda\x08\xf0\xa88\x13x\xd2\x9b\xe3\xb2q\x90\x89Ex~S^\x87\xee\x14*1\x0bl\xd3J\xec\xe0\xc1s\x8c\xe6\xbd/P\xf4\xfe\xd3\xdd\xbd\xbd.\x80\x1b\xf3\xfcp\xf6\x1aP_\xd2\xe7\xb0\x7f\xb0;9\xea\xabL\x1f\x96\x88b\x97\x8eggB\x07\xc3\x93ILw\x8f|\x98\x1cM|\x98\x1c\x1eu\x80u\xf1DYZ\xc6ie\xce\xa5$\x1e{\xf6 \xe0c\xaf@\xa4~\xb2J\xf5\xe4\xe7\x1fi\xf4\x98\x10\xaa\xb3Jo/\xdd\xd9\x95\xf0\x98\x1c\xecN\xad)\x04\xc53lU\xfc\xdfy\xc8)\xf7\xd18\x80\x11\xa5\xebvx\n\x82g\xcf`\xc2\x0c]v\xf8l\x8c-\x88\xb4\x89\x9c\xef\x190\x1f;&o\xeeo\xca\x12U\xf4\xdd3\xd6\xe1\x84eg\xe9K\x7f\xc0\x07\x93v\xcf\x83\xef\xdft\xbc7\xb0\xf7\xe9f\xbd\xc3\xf3\xe7\x98\xcb\x00\x03lcB\x83\x94\xfe\x9a\x1e\x0e\x1a\x16\xee\xd3\xb0q\xedn>.L\xba0\x9d\xee\xb1\x10\x1ep\x00\xdbt\x848\xba\x0d\xc6\xda\x03\x1aq\x1e(\x14!\x92\xb4&V\xd2\xdar\xf6\x99p\x86\x19X(i+\x93\xab\xfbu\xd6\x7fy\x8cw\xa6\xe3t'\x13>\xb5\x07\xbfS\xb8&h\xa8\xd4}\xea\x05,\xe8|\xd3q\x19\x90/\xeb,/\x8b:\x85\xf1\xe0\xd6\xf6\x0e5\x8a:f\xc5GZ1\xa5\xd3\x9cY\x86a\xf0y\xd0\xfb\x0b\xc7<\x02\xfb\x89\x15'\xa7\xc0\xefU\xc6\x8c\xae6\xfdb{\x1b\x90\x0d8=\x95\xee\xdd\xc3f\x93\xda\xdd\xf5\\\x16\xb1\xdf\x07'\xcaIX*~m_\xb1\\\xbbOw\x8d\xeb\xb5\xfbt\xcf\xb0`\xb4|_+\xafx\xf9\x81V\x1e\xf2\xf2\xa7\x9e\xc4\x0d\xd4\x07\xbbh/\xe6\x0d\x8f\x0e\xbac\xd0}\xa6\x1c?\x03\x0f\x9f)\xa7sV\xcfk\xad\n\x0d\xa2\x84\x84\xb9\x8b\x87\x9cX\xb3q\xddt\xa7\xd4FQ\x10)\xdd|6\xbe\xf0!\x9fMt\xbb\xff?\xb4\xffRd\xc0t\x0ctWT\x89\xd0\x9c$\x04c\xfc\xc4j\xf95\xa1\x102S\x0b\x97!\xdd\xd7J-,\xb0f\xe8+{_l\xb6\xf7O\xf7,gH\xf9\\_5c\xf8\xfb\x13HwvN\xda\xf0\x17\x05\xa8n9K/p\x01\xa5\xbc\xd1\x1aU\xc9K\xa5,\x9f\xe6+\"\x8ff\xf0\x90\x1b5\x92\x88y\xdad\xc9!\xf4/\xf2\xe8\x8b\xf9\xf4\xe81k\xd8,\xdf\xe5\xe5<,\xc3\xcbK\xe3j\xe4.\xf1\xe0\x0c\xd2\x99E\xbeW\x17\x1f\x83\xb3\x0c\x8b\xa5s\x01\xc7\x90\x06\xabp\xfd\xd8\xf9\xec\x8d-\xe0s\xa2_{\x06\x0e\xf0v\x8b\xa2\x8d`f\xc6D#9\xcb\xe8G!\xe5c\xc7<\xb1\x80\xb0\xc9d\xf7\xb1\x83CP#NH\xec6\xd2N\x8aY\xf3\xaf\x18\xeb\xd3\xb1a\xa8\x9a\xa8a\xd8Hmbbz\xbaY\x0c\x01q\xea\xdbb\x1bT\x12a\x14N\xe3\xb1s\xc6\xd8\"\xaa\x04\xe8\xd8\xe8\xbd\x81\x9d\x98\x1e\xb8\x9d1=l\x1b^\x17\xa7*XB\xf3\xa8\x94:lh\xc6\xd6\xf5\xd8\"\xc1\x0d\xc9\x0b\x8a'j\x0dS]TG\x86sn\xc6\x81\xe3u\xd7\x98\xd0\x1a\xb5]\x8b\xb9\xc6!\xads\xa6,{\x1bO\xa4\xe4K\xf9)\x8e>\xab\xb1\x98;bK\x82\xd8#Q_\x96B\x97\xb6\x08\x0f\x94\x8e\xba\n\xa3\xcf\xc6\x18\x0f\xa2%[\x98\xfb\x9b&\xab$\xb4\xc3J\x9b\xbf\x11\xb1\xb7\xc2.b\x1c\xa3&\x8d{\x02\xd5\xf6$\x80\x14\x16@\x81XI\xb7+X,\xb6\xd8\x93\xdf\xb1\xddb\xbd5}\xe2\x0f\xc0k\x86D+\xe7\xfa\xcd\xac\x83x\x1e\xfa\x86\xda\x93\xdb\xf1\x9b\x0e\xb5\x95{U\x7fzG\xdb\x93\x89\xf1[\x8f\xd6\xb7ir\xc4\xd35\xe0\xde\xd8Z \xcb\xc1\xe9}b\x1ci\x88\x16|\x8a\x1c6\x137\xc1\x83lV\x8dF\x17\xf2-\x99U\x1dq3\xe1[\xac\n\x8bX\xcc\xa5\xc4}\x0bb|\xdd\xc7\xe2? U\xdc\x801 N\xcb,\xda\xee\xde\xa6,\xda\x81\x89*\xc8y\x96B\x13y\x9f\xf5\x91\x8eqJ\x81 \x99q\xae3m\x14\x13\x0f\x86\xe6*\x9by\x86\xe0L\xeb\xf7R3\xe2\xaf\x98e{\xa3\x98\x9c\xa7\x1ek\xfe\xe4 \xb8\xf4\x02L\xa1\xa5\xa2\x84\x1c\x8e\xc1\xcd\xdc\x9cN\xcb\x9734V\x9e\x0f\x99\x1b\xb3H\xb0\xd5\xd0\xccr\x88\x1aL\x8a\xaa!\x01\x88\xd3\x8cc\x04\xde\x80gD\xe3\xa6E\xa1#\x1c\x9a~M\x19b/\xee2\xc5H6\x0fO\x1c\xab\xb8\x85\x01\xf8\xc0%5.1ghKYf\xe8\x98\x9fh\x9e\x13\x1a\x7fJ\x7f\x8f\x15?\xe4f\xee\x03\xb2\xae\xfd^so\xb6\xc6\xb4)\x03\xf3\xb7\xfd\xce\x83\xcb\xa5|\xa3\x1b\x93\xbafZO\xbeH\xa9\xbbwp\xe4\xb9\xce\"\xcb_\x85\x91\x08\xa5\xf5\xa8f%\x1e\xe0H\x17?p\x1e\xe0H\xe7\x0d2\xce\x1b\xe8\x10\x8d\x891\xf6\x9e\x1eJ\x8b\xe2n\xc6\xd0\xf9\x94\xfa\xe2 \xbd\x8d+\xdb\xca\xf4\xf1\x0c\xa6\x94~5\xd8)\x94p\xc6r\x15s\xf3\x8d\xd2g\xc9N\xab$\xa1'\xbcPP\xd7\xf4\xc2W\xa4#\xa8N\x0cy\xe2!\x16g\x15#\xd5\xa6\xa8P\x16v.N\xe4\xf0\x80\x91R\x19\xa1e\xa1Zv\x8b\x01\xd9##]\xcc\x93A\x1a\x12\xa2\xaa\x99 \xd3v\x05\x92V+\xc2_g\xed\xd7\xb7y\\\xb2\x97\xa1\xf2\xee\xc1\x87\x02\x19\xc7\xd8-\xe8\xb0\xe8\xcc\xa2\xe6\x90z\xc1\xf5\x90\xa8\xd3t\xc3\xf8V\xf9\xb00\xb3A\x96]\x89\x1a\xd3\x18\xf3\xe6D\xca\xe6\xecJ\x9bC\xc1\x99\x14\xba\xe8\x182\xce\xe1\xf3\xf7\x14\xae\xa5\xea\xfb\x149\x1c\xb9S\x1e\xc1\x87nh\xd4\x8cAz\xa3\x1d\x06q\x10\x8a\xe6 \x84\x86\x83P\xb4\x0e\x02\x8fa\xde\xde\xf4kR\x1a\xb7\xbc\xa0\xe5\x86\x9dV\x8fB\xd8}\x14Z\x89y\"\xbe\xdb\x11\x1d\x0ff\xc3\xf9\x16 I\x92\xe1\x1c\xdaD\xa9\xc1\x8f\xaf^\xbf\xf8\xf9\xa7O\x9c\xb0\xcc]\x0d\x0e\xb3 \xe7\xc70K\xdd\xfd]O\xcb\xdeO\xbe\xac\x938\x8aK\xfe\xfa)\xdd\x16w\x7f\xf7\x90\xff{\xe4I$\xcf \x18hgP\x05\x8d\x0c\xa9;m p./I\xf16\x9bWZ>\xd6AKG\xdb\x93\x05\\\x8a\xf5C\xea\xd6\x1abwz\xc0AI\xea\xee\x1eq\xaa;u\x0f<\xd7\x11&\x1b\x9f\xc2k\x01Z\x9c\x97\xe7\xe7\x1f\xab\x84\xfc\x14\x17\xa5\xff\xf2\xfc\xfc\xbc\xbcK\xc8\x8f$J\xc2<\xa4#\xa1e\x7f\xa2p\x85UHb\x92\x96\x1fIT\xe2\xcf\x1f\xdf\xbf\x95\xfff\x8d\x8b_\x9f\xb2\xcf$e?\xc22\xfc\x94\x87i\xb1 \xf9\x9b\x92\xac\xb0\xf0u\xcc;\xfd\xf7Oo\x7fz\x91$/\xb3$!8y,\xd1~\xbe\xce\xf2\xd5\xab\x84\xd0[\x8c\xbf\xcf }+J\xde\x92y\x1cbco\xe3\x15\xa1\xe8\x96\xa5\xe9}\x17\xae\xc8\xfc]6'o\xc3\xb5O\xff\xc5:\x1f\xc2\x98\xce\xe1\xaf\x15)\xd8\xd0?$\xd5u\x9c\xf2\x7f\xd8\x97\xe7\x7f\xfa#K&\x87\x15\xce\xff\xf4\xc7w\x88\xa5\xc5\xaf\x0fa\xb9<'\xd7\xf5\xcf,NK\xf1CZ\x85\xf3?\xfd\x91\xcd;\xcb\xd9\xa4\xcf\xd1D\x95\xa1sV@\x97\xfb|I\x08\xfb\xfc\x13eg\xf20\xfa\xfc\x92/x]\xc0~eU\x84#r\x82b\x9d\xc4\xa5\xeb\xf8\x02Z\x8cO0 ~X\xcb\x80\x8b\xd1\xc8\x04g\x11\x1e\xce\x8a\x8b\xf6\xbd\xa7\xe0%\x9fE\x867h0I\xe9\xf2E#\xf4V\xa14\xe6<\xdeJf\xd5\x05\x13\xd2%(\xf9\xa0@\"\x9bE\x94\xab\xc8\x02\\\xd7\x9e\x13\xaf3<\x14\x8e\xfe\xf6P[\x1am*\x96\x13\x02D\x0eH=\x1e\x86\xf5\xd0\x87\x9dI\x1f)e\xbb\xec\xdd\x94`m\"\xd7\x10\x80\x12\xf1\xf72L\xbf+\x81\x0e\x06V\xa4\\fs\xc8R0\xe6\xeaii+7\x1b$\x07-\x83Y\xca\xa9\x0d\xeav\xd2Y\xa8\xc7\xef\x13o\xa6\xbe\x1e\xa1\x87\x19\x16ZR\xa4s\xe3+\xb1\xe3B\xc8\x8b\x80Mlc\xd3\x9f\xa1\xe5\x8eF\x91\xbe\xff\xf4\xde1h\x1aeY\xcc\x83\xfa\xba\xd0^\xb7`\x0d\x1dl\xc9\xa9(w2=\xf4\\'^\xe4\xe1\x8a\xe8\x1d\x89'G\xe8b\x13\xab\"\x92$AA\xc1l0\x8f\x8bu\x12\xdeQ\xac\x97f)q|\x9c\xfb\xa1\x17\x84\xeb5I\xe7/\x97q2g\x99\xca\x83\"\xa7\x80\xd2\xf95\xbc \x8b(\x8f\xd7\xe5\xb1\xe33\xabV\x12DYZ\x92\xb4\xfcs\x9c\xce\xb3\xdb`\x9eEH\\zA\xb6&\xa9\x8bn\x03,j\xa7\xf3\x8c}\xfa\\T ^\x9f2\xc5\xf1\xb3_\x9e\xf0W\x98\x81)\x88\x92\x8cE\x8c/\xf08\xbd>\x81|g\xe7\xc4\x03\xae\x9a\x94t\x8d\xb3l\x96_\xd8\xad\x02\nWS\x89\x9a\xaf5O8\xcf\x94\xd7\x94\xa4\xed\xe7\xa7\x8c\xf0\x89\xabf\x04m\xdb\x0c\x93\xa2\x12\xb7\xf4\xfc:\xdce\xe8\x83\xfa\x9aK$)\xc68e\x0eX\xb4j\xe1\xaaY\x95\x08\xd2\xe0\xc7\x10\xbb\xa9/'\xe8\xed\x07\x87\x02}\xa0\xf7hDb-=~\xae8\x96\xf6\x01?\x9b\xa4\xabx\x17\xbe\xe3\x0e\xce\x1eW\x84\xbb%\xfa\xf5\xb0\x10\xa8\xa9\xb71\xcf.\x11t\xbb\x9e\xeb|&w\x85~\xf2\xd9\xa5U,\xcc7\x1av\x8e\xe1\xa3\xee\xc1\xc5?\x98\xec\xe7\xf1\xa34 #g\xce\xe5e\x94\xe5d\xe7\xd7\xe2\xb2X\x869\x99_^:\xa2O\xf3;\x8a\xe8\x1f;\xa1XL(f\x13\xfa\xed\xa1o:6\xc4\xe9DYZ\x94y\x15\x95Y\xee/\xc3\xe2\xfdm\xfa!\xcf\xd6$/\xef\xfc\xb8\xf8 \xce\xef\xfb\x85\xbf\xe6\xc5o\x8aW5\xbf\xe4\x97\xd9OY\x14&\x84a\x03_\xa0\x05\x9fc\x1e\x99j\xdbl\x95'{^\xb00\xcaTtQKf&\xf6\xfbV\xd6\xcc\x98\xa3\xcau+\xc6#\x9er\xdb\xf9\xb2\xb9\xc6\x18\xd0\x98\x99\xd4\xa0\xb8\xa5\x0d\xcdUfs\xcb\x10PA\xc8,\x94\x17\xbd\xfb\xb7!W9\x9d\x1cy\xee\x96\xec\xeeBq\xcb\xbe\xc7s\xde\xfb\xe0\xb0?\x1c\xbf\xe3\xb0\xa1\xfd\xc9%]\x8a:S>\xf7O\xbaD\x83\xaff\xc8\xbe\x1d\xc5I\xe8\x8d\xb7g\xb6\xaf\xe1\xed\x9a\xa1\xaebHvf\x17\x041@\xda\xee`\x9e\xa5*\xffI\x9f\x07\x06\xbc(\xe0\xc6\xe5m\xe66\x92\x8d\xeb\xad\x9d\x19&\xc2\xfb\x99X\xf7v\xc3[\xb071\xcb\x15[\x9cm\xebF\xd4r\xd7\x02\x89\xb7\xbc[]\xa4K\x08\xd5\xf1\xbb^\xefm2\xed:A\xfd[\xd5%d\xaf\xf3\x11\xff\x9c\xce\xc9\"N\xc9\xdc\xa1H\x84\xc9\x8f\xf8\xabwU\x928Fg1\xa4E;\x119\x0e8\xbf3\x94Jc)g\xc4\xe0\x98\x02QX\xa7\xe6\xd5\xf4\\\xe8\xd1\xca(\n\xbc\x12\xb1\xe7q\xac\x9d\xa1\xb0\x08\xb5\x00\x0e\xab\x80\xc3u+v\xca<\xcfFV\x03KBCP\xe3 m\xdd1T=\x80\xc1D\x02\x8c-\xa8?\x0f\xd3y\xb6r7\xdeM!\x92d\x86\x8a\xaeC \xc2(,]}\x17\xe9xK\x1f\x1c\xef\x92\xd2\x8e\xa3Q*\x92\x04q\xf8\xb1{\xf0x\xb4\xbbk\xbe\n\xfb^M\x8f\xb6/A\xee\xc6\x1c\\\xc7\x9c\xf4\xe3\xf2\x93\xc7\xae\x00\xdd_\xad)fA\xf4\x9bn\x8a7x^\x93\xddn\xaa\xe7\xa8\x9fS\xfd\xef\xa0z\xf6\x9fZ\xf0\xf1\xbe.\xf1\xcb\xcc \xaao\x12\xff\xbb\xf1\xf1\xc1\xc4\xb4\x00\xc1b\xc8>Rn\xc2^ $h\xdb\xe6\x92\x10\xa3\xad\xf3l\x15\x17\x843&\xa5+O\xc4\xea\xc5\xa4y\xb4\"\xd3$\xfdN\x0d\xd2\x9e\x1f\xc29|\xe0}Id\xa5=\xf3!\xea.\xd2\xdalX~\x1e\x04:\xceI\x91%7\x84\x03\xd0\xba\xf0W\x96\x858\xd7\xddZ\x1e\xbe\x82\xff\x98\xec\x99\xa5\x05\x93\xf1#O/\xb3?m\xb2JJk\xc5n\xc6\xffq\xd0L~\x04\x0e\xcc3R\xa4\xdf\x95\x98\xf7g]BN\xae\xc9\x97-\x8b\x8e\x94\x83\xd3\xaf\xba\xd0\xf4\x82b\x8e\xe4\xfe\xabiD\xeep\nO\x82'\x9a|\xc7\x88j\x9d'\xc1\x13\x07f\xe5\x85K\xb4\xbd\x128\xb6\xb5p0\x04o\x93Y~\x81J%\x1f\xb6\xac}@\x0f.7-\xef\xa6z\n\xf3\xe5'A\xa3\xfb@ e\x1b.Tn\xeaN\x0f\x0ft/\xdc\xb8~u\xa8\xbfB\xd2\xceD?\xc4\x01W\xc3 \x85\xd1\xf6\x08\xc8\xeb\xf7g=\xc0DPE\\\xe7\xa8\xed\xd8\xf1\xc0\xaf\xad\x84\x8e2\xd02\x90\xe0\x04\xcb*\xad\xbcFPS\x17I\xe2\x94\xb3f\x8e\xc7\x96\xa1\x9a\x0c\x83*+\x90\xe5\xc3\x91\xb6\x8c!\x9b\xf6\x0ckuWi9I\x0f\xd2\x11\x10\x93\xd9p\xd7N!s\xeb\x1d\xf3:\xb7\xccBPW2A\x9d)@\xb1s\x0f\xff\x1e\xfb\xb7\xc1\xd8\x87\\G\x82h5u\x0f6d\xb6L\x82\x9d\xd4\x9d\x1a\xc9\x9bC\xb3\x01\xc7dl\xf6CAi\xc6c\xc1l\xcc\x1d\x94\x98\xc0G\xfc8Eb\xf4\xb7\x0748j*\xfc\xa6[3:\x97l\xf7\xd0\xbd\x1bC`0\x0f\x84\x98\x87\x9f\x0e)\xf3[v\xb0\xb9U\xb0p\xb5\x08\x06\xbd\xd4Q{;\xb8\x00\xf6\x9a\x94\x92\x84\x89\x0d{C\xbf\x91\xdd\x03}K\x84\xcf\x90\x99\x12\xdd=\xd4\xad\xde\xb9\xcf\xd0\xa1\xceQp\x9f\xa1\xc3\xe9?}\x86\xfeA}\x86(\xaf\x94\xbaO=\x1f\x9c\xb7\xe1\xfa[9\xa1\x1d\xea\xde%\xdc\xebdj\xf6:\xd9\xdb\xd5\x0f ;P\xfa\xf1\x0by\xedG\xfb\x81\x18\xe1o\xc9\x11\x93|\xb628\x06'k\xe4\x0dR\xd5\x8a9\xba\xc4n\x89\xe7\xa1\xa4\xe7\x81\x82\x0c\xc6\xb6\x86\xfd\xc0U_3z\xae\x8f\xc6\xe3\xa7\x93\xa3\xa3\xe9\xfe\xde\xd3\xbd\xf1\xd1\xd1\xa4-nx\xf2\x9f\xee\xd9\xf1\xf8~6\xd99\xba\xf8e\xfe\xbd\xf7/O\xfa\xd6\xc0\xa2\x86\xc1\x10>|:FZxk\xcb%\xd2U\x13\xfa\x13\xc2\xb2\x9f\xc8F\xae13v\xe3hg\xeb\x94\xf9\xee\xe7AI\x8a\x12u\xba\x88\xb1\x84\x0b?\xcb\xffy\xcaC\x97\x96\xf0\xac\xd7\xefd\xc8J\xf5\xad\x82\xed$Xb\xeft\x0c\xf7T\nu:\x08m6\x17\xc2\xec\x84\xd5r\x1e\xa2\xb7\xe1\xc9/\xc1\xfd/3\xf7\xecx\xf6\x9f\xb3_..\xbe\xbfwg\xcew\x17\x9e{v\xec\x9em\xfd2\xf1f\xff\xf9\xcb/\x17\xf7\xbf\xfc\x12x\xdf\x9f\xfd2\xf1~\xb9x\xd2\xbe9O\xfe\xf3\x97\xdb\xef\x1fu@\xb8\x7f_\xa3o\xde\xd2\xc2\xdf\x8bm\xe8>A\x8a9k\xaa\x90bu\xc1U\x96%$L\x9b\x12\xc5Ik\x0bY1z\xbe*q\x9c0\xbaX&\xff\x12_\x10\xb6Cq*d\x88\x1b\xa9\xf9j|\xd4\x96\xe42\xf15\xb9!).\x9d\xf2\x13I\x03!\xe1^\x85_~\x8a\x8b\x92\xa4$o**\x855\xb3/\x8d\xac=\x84|C\xd0\xd5\xd9Xlo\xcc\x04\xda\x9a-8\xedi8\x1bD4k[\x00\xda9L}H\x83Wt-_\xad\xe2\xb2D\xdb{,k\x10\\\xb3\xf2\\\x0d\xa1\xbe\xd5\x16\xbd\xa9\xc3\xa9\xe3\xb7\xea\xfb\x89\xf6}A\xf4\x1av\xa8a3\xd1\x06\x91\xc9\x18\xdd\xc3\x99.\xd7$\x9cH%c\xeduV0K\x8cN\xabm\xf3\xb9\xf2\xd50N\x0f\xea\x8c\xc8*\xee\x8e\xc8 )\x11,\x96\xcd1\x8f&(\x1fsW\xbb\x06\xbf=Pr\x81\xd0\x999M\xd4AwK\xae\x16\xe0k\xee4\xdf*gF.\xedr\xe1\x97i\xa2\xd2x|\x0e\xd9\x14\x97b^\x91!9[\xb0\xb0\x1fb\xf1\x0dY7\xe9\xec\x17\\f\xc7\x1d\xf4~N\xa3\xb0\xba^\x96>Ti\xb1&Q\xbc\x88\xc9\xbc\x9e\x1b\x0e-\x00\xf7;\x9e}\xd7\xf1L\x927\xd6\xdf\x82\xd9t|)\x99 \xefB\xa9\xf6\xd0Z\xe3\xac\xc9\"\xcaW`V^\xd8\xc1.\x83\xcb\xa9\xe75\x0e~\x9a\xed\xb9i\xc9\xba\xfc\xf8\xd2&G\xbfE\x9ah \x7f\xd2\xe5\xca'5\xea\xab\xfb\xb4y\x17\x16\x17r\x82\xde\xb8\xaa}\x92\xb7,\"\xdcD4\xdb\xf6\x91\xed\x84\x92=\xa0J\x813)\xb9\xadG\xbf\xcd2\xe8!\xdct\x1d\xe9\x8d\x83\x0c|\xee\x92@\x0c\x89\x92\xfc\xcd/$\x87}\xfd\xfa2\xae@\xbb\xd2\"\xcaaS\xc4\xc2\x06\x11\x91\x9aOn\xe0\x14fZ\x91\x0f\xe4\xc2X\x91\xf8\xa6\xcet\xb0J\xbb\xbb\x0d\xf3\x94\xcc\x81\xa5\x0b8\xa5\xc8\xbb\x85ZP\xdbjD\x9b\xc7\x06D\x84\xddT\"\xf6\xb0\xde\x1d\xb7)x\x0e\x15vi\x19\x0dsa\x88\xb2\xb4\xc8\x12\xc2\x80\xbf\xeb\xb8i6'\x1e\xd0*\x18>s\x9d\x15E|\x95\x10P\xc8\x84\x15Ye\xf9\x1d$$\xfc\x0csR\x92\xa8$\xf3\x00\xfeu\x0eI=\xeap>\xa7e?\x17\x04\x08\xfbJ\xc7\xf6\xae\x07e\x06q\x1a\xe5\x84\x02\x9b$^\xc5e\xe0\xb4\xb6\xb4\x89\x93j\xa4\xbf\xc4\xf8\xcb<\x8c\x90\x08U\n\\\x91\x0e\xc9v\x932\x14i\x98\xaf\x96^\xb3?\xf9\xf67\xbaY\x82\xc2\xa7(Hy!\xd1\x95&dS25\xd2*\xbb!b\x0et\x98\xb1\xc7\xe3\xbb#\xc2\xa3\x9bNT\xf0#\xa0Y+\x82\x92\xfcKXi57\x10o\x00\xf6\xc9\x96#\xeeYkud}kyS\xfb\x7fQB\xe9w\x81`\xd8\x8c\x0e\xbf\xf4\xcb\xdb\x11w5^\xb0\xfbl$$j\x0c\x901a\x1a\xddQ\xa1s\xcc\xddT\x02k\x94\xea\x97V\xf5\x14\x83\xbdr\xd9T\x0b\x16)\x90T[Q\x15\x98\xaa/\x19<\xd5\xe3-\xab\xb8\xd0p\xa4jlX\x9d@\xb8\xb3C!\x8e!&\x0d\xf0\xc5Hg\xe1E3K\xfa\xab\x99\x17\x9d\xa5R\xc0'\xda\xeeS\xf5\xdf\xc4\xfe\xab\xf6\"I\x86\xf1Vf]{\xebz\xf4\\\x85\xad\x8e97!\xecYf\x1c\xddm\xf3Lg\xf4Q \xa0\xe3\xdc\xed\xed\xce{\xd1\x1e\x92\xb97\xebA'\xe8D\xaf\xccX\xdf\x1en8 \xb6\xb0\xbd\xd0nGLs\xdb'z'\xda\xf9\xc1\xe5\xd0`+\x18y\x9a\xdc\xc2\xd3X0\x83\x1e\xee\xbe Oi\xa1\x8bO\xea\xbbqbotV\xdf\x99\x1dh\xf1\x1d|%\xba\xb6\xd1v\xa8\x93Ag\xd9D\x96\xb6i$\x16'I\xbf\xc6g-\xe2\xcf@\xf9 \x1a\x1f\x8eav\xd17\xd6\x97Y\x95v\x0b\x04tv\xdf\xa6\x1e!\xed\x8dm\x9f\xb3\xc68\x83/\x83!u&z\xee\xd4\x15\x84\x05j?\xbc\xd1\xb8\x11\xfb\x0c;\xc2\x85\xa9_\xf5\x0b 5q.\xcf\xc5!{\xbeO\x0e\x9fz^p^\xe6$\\q\xd7\xdd\xe0# \xe7\xe1\x15Z(\xe0\xef?s\xbfg\xf6\xc1\xe4)\xfa\x86\xfcX\xad\x13\xf2\x85\xa9C1MLP;\xf9\xb1zGS,\xfd\x10\x16\xc5\xa7e\x9eU\xd7K\xa6\xfb\xd8?\x1c\xa4\x83\xed\x0d\xd1d\x0ett#\x92\x99\xb9\x18\x07MyW\x93\x7f\x06\x95?h\xc7\xc4$$\x89\x0b\x8c\xb4\x02\xc2o\x83!\xa1\xb4\xcc\xef\xd4\xa2E\x9c\xc6\xc5\xb2\xcf\xc7\x87>[\x9dK\xa0?\xb5\x96\x8fujG\xed\xa52*{=\x0e\x93r\xa3NQ~\x84\xd6%\x0fD8({\xa3\x80\xfa\xdd5I\xe7qz\x1d]\xed\xecP6\x8f't\x81\x1cW\xd0\xfam\x9b\xf2\x10\x0f \xa2,\xffL\xe6\xdcc\xb5x\x9d\xa3]\xac\xa9XlRIy\\\xd3g\xa7\x86\x00\xa8\xf4y@\xb5\xb7\xc1V\xa8\xe3r\xcb\xb7i\xd5fCB\xee\xe4N\x82\xab<\xbb-\x18\xf12sn\xc6\xc1d\xec\xf8@\xff8\n\x9c\x8b:\xfaW\x13\x0f\x8cA\xc9\xb1\x0f\xfb\x1e\x8f!\xcd\xbci\xb2:\xda\x8f\xda\xdb\xaa\xbe\xa6\xe7e\x88Z\xd9\xeb\xf6pP\xc8\xe2\xee\xeby\x04\xa3 N\x97$\x8f9L\xd8\xd5\xd36\x08\xb1\xa3\xf9\x90\xcc\xc9:'QX\x92c\xbc\xdeO\x0d\x0b\xd8V\x85'\x1c\xfa\xe8z%\xfa\xac\x99\xc6i\xec\xf1\x906\xed\x1aK4\x81h\xf2\xa6(\xde[\x1e\xfcfH\x0c0\xf7\xe1\x86\xf7i\x07\x0cw\xf8\xb1\xe5\xe5\xb5\x114\x03\x97\xaf\x85H\xb23X\xc8N\x1f\xaaW\xda\xf7D\xdcb\"\x0b~\x0dt:\x82\x12\xa6\xe5x\x9b\xcd\xd1\\l\xab\x94\n|\x16V\xd7m\xd7\xd3K(W\xb6\xc5\xfc\xf1\xe8\xf9x_\xbf1PZ\xb5~5X\xc6\xd7\xcb?\x87%\xc9\xdf\x86\xf9\xe7\xf6\x16\xd0'\xc2\x8a\xa2\xdd\x7f\xef\xff`a\x18\xdd\x19L\x0e\xe0\x18&\x07\xbb\x87{\x96UP\x86\x02\\k\xcbh\xd3\x18\xce \x86c\xbe\x16Q\xf3\"\xa2\xe4H\x04\xc7\xb0\xf0\xcd\x8d\xc8\x19\x15[\xef\xbd\x06\x94\x87\xc9\xcb0I\x98\xc0g\xe2\x0b4@\xe6?\xe6a\x9c\xca\x85\x0c\xe2i%\xeaw\x0c3\xa8esR\x94yv\xc7\x0b\xcd;\x92\xe0;\x9e\xe7fN\xa2l\xce\xbd\xablxJ\xa9C?N\xea\xdePB&R\xc1\x00kP-\xbb\xbf\x07\xa7*\x17\x87B\x98$spX@w\\\x9b*\x03\xb3R\x9d\xe2.\x8d\xb8\xb8\x04\x7f_\xe1U\xfe\x90g\x11)\n\xed\xe3,E_\xd1N:O<[\xdd\x94\x92\xfc\xdc41Moe\xd8h>\x9b\xe2\xc9\x99 \xfa.\x8d\xba\xeb1\xf7f\x1cxteG\x87\x94\\\xec\x9f\x95xJ}mE\x07\x0d\x85Q3\x07\xe2\xee\x91\x84\xa4\xbe\xf4\xb7\xe2\x86\xa5?\x0f\x88\x8a\x89g =\xba#G\x8aggGB\xee>\x1a\xe0\xbb\x0dNrc\x1fr\xcf\x97\xb0\x94\xfb\x8as\xe4~k\x1f\x98\xd0\x94 E\x85<\xb5\xe4\\=\xd3_\xd1\xc60f\xbfO\xc5\x1b\xcf\xf3!\x91T\xc5\x83\xf6\xf4R\x05\x8aL\x8en\xdae\"\x1f{\n>\xa4\xbbQ\x89\x9f\x1c\x9e\xa3\xe6@\xc2\x8b\xe8\xbc$V\x8aBN\"0!K*\xc1\xde\xb8\xac\xf7\xe6\x9d\xdc\xcad\xd0l\xae\xa4\xd9\x98&\x91B_\xf4\x03\xf1\x88\xb8\xc6\x1c\x07moc\xf4QA\x0ca\xda\x9b6q\xc4!\xf2\x9c\x969\x06(\xfc\xe0\x96\"\x86\xa5\xc26\xe6n\x03\xbb\x07\xcd\xf3\xd6:vb\xa4?\x0c\xd9\xb4\x04\xcd@t\xd0a\x16\x04\xd5\xdb\x87\xf2y\xa6\x8a\xa0\x98\xcf\xb6~5\xf1o\x84Lv\x82#\x069\x92ln\x89\x02\x02\\\xeao\xe2z\xcd\x98(k$\x05\xe6\nu|\xad\x90\x81\xcd\x82\xad\x1b\xda!\xc7\xa8\xae`&O\x98^\x0e\x95d\x05\x0b\xea\xc6\xa3^\xe0j\xf8\x10\xc2\xe8\xd4$L\xa3\x0f\xc69e\x88\x00\xcd\x7f\xfd\xfa\xf6\xb1\x1bSg4\xf3\xc1q(i\xc1\x10\x80z^F#\xac\xda\x81R\x18IB\xc9\x15\x8bP \xe3c\xcdd)\x8fg\x17\"0<\xc1\xce\xad\x0d\xcf\xb4\xcfz\x17\x05!d\xc4\x9d\xf2\x98\x9a\x8f\x0f\xa2e\x95Z\x18-\xf1\xa0\xb1P \xd29v\xd7M@\xc4\xeb\xe9\x16\xf0\xd0s_\xef\xd0\x04!\x93\xc2\xcd\xc11D\xf5\xa6E>e\xc0\x12\xed8\x98\x17\x8c\xde\xf9\x1a`z\x1b)\xa8\xe8S\xbb\x88\x0b@d?\x0d}2\x1e\x90@\x86\xf2\xado\x81$\xc3\xe0\xf0\x97n\xff(\xc1Abtx%\xab\xb10ld\x85\xfa\xb8\xd0d\xa2\xe1-\xd9O\xbe\x8c\x83\xc6un\x85\x9b%G\xa7\x0d\x0bc\x95Pj\xc0\x1b7A'\xc6SviU\x1aN\"\xda\xeb7\x8e\x05\xf2\xd3\xe7a\x182xe\x9d\x94\x80\xf1_\xbatM\xec\x10\x0d\xe46\xd59\xdd\xdf\x03Q$\x07\x14,Z\x88\x17N\xad T\xd2\x80\x99&{\x18+\\\xd59\xe7\xaa\x90;\x1a\xb8\xa4]\xa8W \xf6\x86\xe6fw\xc8\xd2j\xd3\xa4/\xd9\x94C\xeb\"5\x92EJ\xf2R0p\xad:\x8a\xd4A\xab;e\xe55\x16*\x85\x00I\xbb\x03,\x98\xc8\xec\xe2\x04\xca\x13\x8fN\xa3*\x96,4 \x12\x82t\xd9\xac;\xadyy\xb7\x81d\xaf\x18\xdf\xee\x96J\x1f\xee\xe6\xc4\xfc\xd7\x84\x9b\x93{-{\xac;l:\x8e\xc9\xe5J~0\xcc\xe9\"\xa8%\xae\x9b\x05|\x97U{\xf5\xd2\xbbv\xde\x10\x18\xc7\xe7hL7\x1b+\xc4E#\xf9\xe5\x96JZ\xc5f{)wC\xc2y\xe0\xf8\xe0\xfc\xf8\xea\xc3x<\xde\xb5\xa4F\x83\xf6\x05\xaf\x8b\xed.\xbb\xf8\xda\xb5\xb1\x08\xdc\x13n{\x9b\xff\x15,\xc3\xe2\x0d\xe7\xb7\xc0\xe6\xd3\xf8\x9a\x97IQ\xc7\xda__\xd0\x8bK\xef\xc6\xb0\xda\xbe\xe5,\xac|\xc3\xc8:\xdc\xef\xfa\xe5I\xb5#\xcc\\66-\x1b~\x93\xde\xf6\x15\xf0T\xcd\xdb-\xc9\x8a\xcc\x8f^\xf7a\xcb\x07\x84B\xf3^\xf1]\xedG*5^\xb6\x94\xf2>\xac$\x10\xb1\x8e\xd7\xa4\x0f:0 \x80\x8ah\x9a\x1c\x8a/\xc34\xcdJ\xa0\x0d\xf9\x18\xa7>\xe7\xeaM\x9d\x15\xd1zn\x8b$\xed\x1a:$\xebY\xe4Y\x03cn&\xbb*\xc6\x1e\x19\xdfa\x80\xe4X\xa6\xab\xea\x84\xfb>\xac\x9b\\\xce9nh./\xe8\xd2\x8e\xd2B$\x0d\xd6J*h\x91\xd9|\xf0\x91Zc>\x01\xdd\xfb\x13\x80\xe7\x10\xb4\\A6\x81T\n\x0eM\xa90\xca\x17\xb0\xf0\xd3\x02\x00Rj\x1b\xd1%sr\xd5$\xd3j\xeb[R\xf0}\xd1\xfa\x9d\xe7C\xcc\xe5\xeeg\xc3p\xb7\xa0\x06\xa4#\xc3\xb6>\\\x94$\x07\x92\xcem\xc1*L\xd4\x8d\x84\xa2\xf1\xb0\x98V \xefb\xca\xc3^\xeb\x9c\xb7\x9dK\x07I=c\nZ\"\x9e\xca\xa2H\x00\x89\xb8iH\xe53\xe6\xa9\xa8\x06\xe8\x7f\x1b\xde\xe1Ua\x0b\x81\xb5\x11\xf4\x14PfP\xa0\xb1\x80cM\xd6\xdf\x04\x05a= 9\xa4\xaa\xa3\\C\x9f\"\xd7i\x9a\xa5;\xac\xd9'\x1c\xd3 \x9f\x83\xc1\xbf\xb9A\xae\xb6\xee\x95\xba\xee9+\x89\x05\x1f\x1a[\xf7 f2S\xe6\xe6\xe7\xc6*\x01V\x19\xee~-\x0d\xb2\xed\x0f\xdaq\xf5*\xf1MM\xf7!\xf0R\xd7\xe8\x19\xd5A`\x8e\xdd\xdf\xdc)~}\xb1\xc7\x1e\xe9\xb4\x91<\x92\x9f\x87\xda\x08\xc3\xdeP\x8e\x06_U}A)\x11\x19K\x17\x9e\x99\x05T\x16\x8co\xbd\x03!J9Z|g\xde\x99Y\xaa\x16[\x8d\xac\x86\x91\xb4\xed\x02$ \xd73 \xaaf\xd0\xfc\x1d3\xdd\xd7d_c\xcb\xba\xa0\x05Q-\x18\xc4\xeb\xc1\x04\x0c}\xe7&b#k\xb3\xb5\x1d\xfa\n\x0b\x17\xdc}\xd8\xf0\xc6\x1d\x83A\xf3.?B\xacp\x0cq\x8f\xaa\x8c\"\x1cc\x1c~\xf9\x11\x92\x07c\xee\x05\xf9\xa17\x9d9;\xdb\x8f&\x0b\xd2\x1f Q\x8ey\x19\x8e\x8dL\xbe\xb1\xaeU\xc83:\x85\x89\xf9\xf02I\x8f,) \x1b\xf8\xd1 \x9e\x8b.\x88\x152\xce\x0f/\xb0/\x85\x82\x836 CO\xd5 \xe2I#\xdc\xd9i\x1c\x8d\xba\xda\xae\xd2!\xad+<\x9b\xda\x8bA\xa7!4a\x0c\xc8\xb3\x1f;;\xbe\xa4\x15\xa5\xe4\xab\xa4/\x93\xa4\x1e\xf8\xcb\xa8=k\x0bL\x98\xf6\x8c\x93\xc4\x9dD`A\xca\x1f[\x1a\xf3nZ)\xb6\xa5A\x14\xa4V\x19\x94\xd9O\xd9-\xc9_\x86\x05\xf3\xb0\xd8rg\xce\x92|\xa1\xdc\x11\xd7\xbb\xd3\x7fw\xf0\x8f\xb0\x88\xe2\x98\xfeq\x15\xa7a~\x87\x7f\x85\x059\xd8\xc3ZQ1\xe5\xff\xeeL\xf9g\x93\x83\x84\x88\x16\xc4\xdfyx+\x19\x19\xb9,\xd3\xa2\xa7\x8d\x03\xad\x8cp0\xb59\xe2\x90\xbbm\x8d[\xc1,\xae\x9bt5\x12{@ \xccM\x98 )\x10\xf7\xf6\xb6\x1c\x98\x8e\xb1\xb8\xb5\x8eZ\xc8\xbcr\x19\xde\xe4\x8d \x8bP\x1e3\x10\x8774\x17\xb2Y\xcan)@g\xc8J\x01\"\xe2\xc6>h\\\x0b7\xfdZX]\xb7y&\xd3\xb2)\xd3\x04fiDj\xa1[\x07\xe9F\x1a\x93\xa3\xb1/\x99f\xb5E\xd4 !\x95\xbc\xc5\xa8\x0c\xbc\x82\xb5\xe9\x92\xf1\xdamt\xad\xe4\xdd2\xa8\xb6k\x0bt\x1d\xa0\xf0\x01\xb4\xe7\xd6\xbe\xe6\x852\x1e+\x9fk\xe9\xde\xed\xec\x9f\x9e\xe1~1\x89z\xd3\x1a%\xf7\x8d\xf8[\xbb\xa6U*\xd7\xa9\x7fi\xb5\x9a:\xbd\xfc.\x93\x94\xa4s\xd7\xf3\x81\xb4\"8\xfd\xa1\x19\xa9\x9a\x9b\x11\xb3\xe8\x1f\x8d=\x8a\x0e\xdf\xacVd\x1e\x87%\xd9$\xb5~\x7f\x0e6\xfb\xbe\xf0\x03\xd2\x1b=\xe2\x9b\x0c#u\xf7\x0e\xf7<\xd7\x833\xee\xbf\x8c\xc9\x13\xd1\xb0\xf5p\xff+\xa6z\xd3\x84o>2\x87R\x99\x9a\xd3\xc2\xed\xea\xc1\xc3*\x83k5G\xec\xedPC\xfc\x1275\xb5h\xee\xca\x07\x850\x8a\x0c\xaf\n\xf5M\xf4Uy\x02n\xea\x90\x0d\x0b\x1f4k\xf4\xb8\x95=\xa5\xb2\xf8V\xaa\xdf\xa1B \xc5\x00\xb6\xcc\x1b\xd8k\xfc\\\x17Z\x84\x05\x86#h)\x0bo\xb1\x10Y\n\x16\xf0\xfc\x14\xb3\x14D\xee\x82\xa7\xfc^\xc6\x8d\x93\xd3\x0eDn\xe1.<\xef\x04X\xe4-\x18\x8d\x0c\xea(\xb4\xf3\x91\xa5\xac<\xccP\xc2Q\xe3\x8c\\\xf8\x90\xbb\x89\x94\x02E\xc3\x8f\xbc\xb47\xd3\xfc\xa0\x93\xa6xH\xb4\xb0\x91\x10Tj\x03\x18F\xd4\x9aDo\x96\x14\x8fHa\n\xc2\xc4\xeeA\n\x12]\xa5\xbcx`R\x82\xeeA5\x07\x8b\xd6\xad\xf3\x8b\xb0P\xcc\x9f\xc8\x97\xf2]6'\xaec\xcb\x99\x92ah\x01\xdbx\xb4\xb0\xb8]\x029\x0b\xfb\xcd\x1d\x858\x82g\xcau\x16#\x9bX\xf1w\xb7u\xa1\x90.\xb1!v0\xfdp\xaai\xe5\xc4c\x96\xa8\xa0\xcb\x9aJNY\xe4\xb8i\xe3\xc3\x08u\xfa?V\x1f1x\xe9Zf\x86\x176\x0e\xe6a\x19b\x98\xc2S\x18\x8d2\xf8W\x982s\x07l-(\x96\xf1\xa2t1\x04\x05\x17\xbf\x08\xafkN\xe1\x95\x06m\xd5\x83\x17dW\x05\xc9o\xd0R\xca\xbcx\xd12\xcc\xc3\xa8$\xf9\x8fa\x19\xb6\x82\xfe\xb3V,\x16\xeb\xbd\xf4\x02}X\x9a\x17\x0cai&X\x99\x94{F|(/P\xec\xc0\x15\x94\xa8\xbde\x04\xb0iq\x86\x88\xc5\x1e|3\x1c\xb6^\xe3v\xe4$$p\xec\xaa\xb0&\xc1\xb4\xe4\xf6f\xf6B\xe9\xe8D\xdcO\xdaM\x9d.\xa8C\x8cj\x1c\xca\xdb\xaa\xc4\x84|\xef\xd9\x8e7~\xb1\xb1\xdbze\xbf\x95\xc6\xa6\xffL\xae\xfe#.;:\xb0Th\x1f%\x1bH1\xdf\xa8\xde\xe0\xbb\x80\x8c_\xee\xea\xa2\n\x00\x16\xb8\xd5\xd8lA\xcaO\xf1\x8ad\x15J;\x0c\xdb!U\x182\x80\xa6\xba\xcb\x0e\xfb\xd8<\x98\x96T\xeeA\xba\xb2\x83\xe8\xcaoBeY3h\x9a\xb2f\xaay1\xa7l\\\xfb\xd3}\xfe\xef\xc1\xc6y1;F'\xd2S\x1e\x9a\x92\x8d\xa1\x86\x8f\xa7'P\xc3\x0e\xe7\xdda\x87\xd5X\xe9\x96|WV\xc8 \x84t\xed\x0e\x92,\xc2\xc3~\xdcJaF\x9fe\\\x94Y~g~\x99\xadI\xaa\xb2\x7f\x86J\x98\xf2\xab\xb7\xd6\xeb8\xd1+\xd9\xe6\x0b\xe2\x86K\xf1\x82\x9b3\x7f\x8b\xc9\xcal\x89\xfa\xccV\x1cta\xd8wmxr\xc3\x1dFm\xda\xb8\xb4C\xc5\x9b\xd7\xf1\xde\x0c\x82P\xab=Im\x08\x13\xf3\xb0Ih\x15$\x82B\xbb3\x87\xae\x95\xe3\x83\xf3C\x92]\xd1\x7f_g\xf9\x8a\"=\xe7\xc2;\x01\x16\x16\x13\x13\xf3U\x08\xc0]\xcf\x0b\xe6YJ\x90\xc4E\x8dE\x07\x92\x13z\x97\x98\xe5\x10\xb4\x93\x1f!\xc4)_3\xc693;QV2\x0b/\x86`5,\x91\x0d>\xec\x0b\x93;\x8c\xee\xe0P`\xe0\xd0k\xcb\x0b]=\xc9@\xaf;\xbb$\x1eW\xcf\\\x9f\xb8@h\xd6\xe7>\xdc\xf8p\xe7\xc3\xb5\xde|\x81y\x0f}\x98\x1b\xdc\x92W>\\\xfap\xe5\xc3m/\xbb\x08\x82\x83Z\x83\x08\xb6\xfa\xa2\xc6\x05/\x8c\xf1 \xe8#\xc2\x15v2\x00\x18\xef\x8fe\xec1\x87\xe0k*1C\x8a\x8ej\xd0\xacf/\xfbi\xf8\x86R8i\xad\xdd\xea\xfc\xca\xe2\xfce,\xdddD\xc3Gb\x00vmt\xf9\x05\xbd\xa5G\xe0\xc0\x1bq\xa0\xdb\x95\xce\xe1\xb4^[\n&n\xdaU^Y\xd0\xf1\x0bT\xca5\x82\xedV\x85\xf7p\n/f fNz1s\xfe\xed\xdf\xea\x8b\x85E\xe8\xfc\xf1bvcH\x1a\xfd+\x05\x86L\xdfxc\xe00?S\"\x00\xce\xe0\x1c\xce\xe0\xd6uHZ\xe61)\x10\xa2\xfd\n\xf6\xd4uoX2\xb7<\xbc\xc3\xa9\"\xa2z\x11\xf0\xafio\xef\xdb\x14\xd1\x1bD\xc5W\xf4\x96\xb8o\x18\x19\x8e\"\x0e\xcf\xf3P\xea\xae\x8b\ni\xf5+\xa6>G\xcfj\xf7\xca\x87/>%\x11(\xba\xa5<\x85\x89\xed\xb8\xe2\xabT\xd1\xea\x89\x0fK\xcf\xf3\xe1\x9c\xb6\xf0\x1e\xe1\x8c\xd8 \xec1H\xc3\x15\x93\xad\xbf\xe2x\xfc\xd7\x81P\xe6\xbd\xd5\x9f\xcb\xe3n\xf1[L\xf7\x8bW}\xeb\x15\xdb 1\xb4\x178\xb4_=\x1f\xc2\x19\xa1\x94\xc9\xaf\xf4\xaf/\xf4\xaf\xa5\x0f7f\x11\xdf\xcaj4\xc1\xe6t\x8c\x9bHw\xed\xd6\x15\xd3\xb4\xc8\x14(\x988\x86\xbb\xa6\xba)\xd3\x97x\xf8\xae\x1e\x83A\xb1\xe8\x9bl3A\x90\x89\x97\x14\xc2\xad<\xc0\x7f_\xd0\xa9gt\xea\x97>\xacf\x97\xa6\xf0\xa2,|\x91\x1b\x07\x1f`\x04q\xf0\x1a\xbe\x07wM\xbf{\xe5!\xfc]\x99c\x11\xad\xea\xc2A8\xf7FJH9\xb5\xd0\x0f]\xdfC\x1d\xa7\xa7\xd4\xd2\xe4\xda\x08{\x01\xc1\x8d\xba\xb9\xae\x08\xb3:\xcc\xeb4\xd2\x12}7,\xae\x05\xe4\xb5\x17\xbe+ mk\x0c\x1d\xd6\x81`\x1c\x06\xfd`\xa3\x91X\xe2\xd6\x9aF\xd2\xe30n\x1c\x8c\xd5\x1f\xb9+\xce\xca\x10\xf4S\xf7\xc64\x08DV\x1fX\x9a\x1etb\xe5\x93\xb9\x95\xba\x93}\x16\xa54u\xa7G\x9e]B\xccG\xf3\x14\xb6N-\xcaT\x91\xda{\x1e\xdf8\x9e\x0fN\xf8\xf5j\xd4\xa7m \xa1\xce\xdc\x0b\xc2f\xf2\x1b\x92\xfbS35|\xf4?3\xdd\xa2\xaa\xf6\x9bn\x9a\x19\xa8\x95s\x98\xab\xf1\xcc\xf9A\xa6\x93}\xcf\xdd\xd2)uc&\xf9\xbeu\xb1\xc7\xfa\x0cyB\xc76\")\xda @\x813\x163\x8d\xec\xe5\x9a\xb58\x85\xd0\x83\x94\x1e\xde\x8a\xed_\x88K\xb1\xbd\x0d\x11\x13^\xeb\xc1\x0d\xb8\xf3\"i\xc2\xe7\x16'\x1e\xff\x8e\x12p\xb3b4b\xf1}\xdd\xff\xca\xdc\x08[\xbb\xbfoZ3#\x97h\xb3M\xed\xdd\x9f}s\xaa\xe8\xcel\xfe\x95A\x93\xda\xc5\xf7\x06\xd7\xa4\x94\xb2d\xabV\"\x96c]\x8a\xbd\xe3y+\x91\xc5\x9de\x176\xf9\xae\x9ae\x8b\xf33\x8dW\x85\xf2\xf6L\xfd-\xd1x\xc7\xeag\x9c!?\x83J\x97\xe4n\xb8\xf8\x87\xe6\xc5o%\xe4no\xc5?s\x14\xd7\x03\xee\xcbu\xf8?;G\xb1\xf5\xec\x98\x12/\xfd\xcf\xcd\xa5\xdf\xb9\xcd\xbc\xb7\xf6.+\x16\x8b\xee\x04\xb6\xc1\x04\xd5\xb5<\xb6\xee\xd4RO\xd8,\xd1:{\x96:\xe6\x8c\xb7\x9b\xeda\x9f4m\xb2{\xd0N@\xbf\xfb\xf4\x9f \xe8\xa5\xe7\x7f@\x02\xfa}sR\xc4\x01\x19q-\xe7\xbf\xae`\xb3\x9f\xa4}\xf3@\xe6\xcd\xbe\xc7\x14.\x99y\xe6\x82g\x016\xbf\xa5TOhu\x14\xe1c*DJ\x9c\x82ns\x84 \xd6x6s\x8e\x03\x8e\xc1\xc5\x08\xdb\x98D\xf1e6'/J\xb7\xf0\xe4\xee\x9d\xe7\xc3\xdd\x1f\xa4\xa2e\xe7t\xa5\xdd\x91?r\xf8\x15\xc0!\xa4\xee\xde\xc4s\x13\x0f-i\xbb\x1aK\x1a\xd7\xcb\n\x83\xf4\xfa0\x91\xcc\xae\x1f(eI\xf7\xe1&H\xb3\xdb\xde\xd6\xb0\x96\xb5\xa19\x86\xce\x16\x06\x99\x94\xa2\x9c{\x01\x05zS\x1fb\xfcc\x12d\xe9\x8a]68\xa5\xd4\x07\xc6\xcap\xb3`\x9d\x15%\xbf\x85\x08h&\x18\x81i\x11\x84\xf39&\x1a\x94Se\x197Cj\x00\xc9\xbcE\x10\xafh\x8f\xe7Q\x1e\xaf\xcb\x82\x8e\xac{j\x0by\x0c\xdc\xa1\xdc\x07\xe7{)\xac\x17\x85\x94\xad\x11\xb9\x0e\x9f\x90\x83\xe4\xd4\x16\x1b9\xed\xcb\xc9\xd2\x9c\x84\xf3\xbb\xa2\x0cK\x12-\xc3\xf4\x9a [\x1d\xb9N\x81\xa3r\xbcNK\xf5\"\x08\xd7k\x92\xce_.\xe3d\xeeJ_yA\xbb\xe5\xbe3,\x123\xb1\xc6J\x16MY\xdcS\xab2\xb9\xd3\x94Q\xb2\xa0oN\x84bG\x8f\x99>%\xc4\xd7\xfa\xfe\x18\xd6\x1af\xa0\xb0\xfa\x18\x9a\xecC\x9b\xd1)\xf6\xc1\x9a\x95\x0fVy5},\xce\xf5\xf4\xb996{\xee\xa8\xeb\xd8i\xd7\xda\xdb\xb5\xc5\x04\x9bv\xdd\xd7q\xcf\xeamJ\xe9\xb4\x0c29\xa53\x1ed\xed\xa2O\xbe1u\x89]\xe6YH\x14\xe5\x1e\xea\x9bl\x9e\x857<\xb6U\x16,ZQ\xc4\x05!\x8c9\xc5sRd\xc9\x0d\xf10\x9c-F\xb1[\xc5\x05y\xec\xc2\xb4V\x80-\xcc\x9e\x9d\x04\\\xd1\xad\xef'\x00M\xd4\x9f\xd9\x99\xb2\x0en&9\x963O+N\xdemmQ\x02\xcf\xf9H\xae_}Y#h\x8c\x15\x0f\x9bAS\xb6\xdf\xd6\xda5#u\xa7\x87:A\xd7\xb8v(\xf2\xffA]\xca\x12V\xe3*\xeb\x9dq\x03\x84\xa3\xde\xc5\xb5Q\xd7\x88\xa1\x02\xae\x1b\xc6\xa46\x1eW\x8f\xb12J\x16\xb5\xaeX\x85\x84\x9d\xba5\x15\xcf\xfb\xcb\xb2A\xb9yp\x0e#\xc8\x91Y\xce\xba\xf5\xbc\xf4\x90(\x85\x98\xbf\x9dk*}9|\xd4\xa054\xcb\xae\x89\xecr#\xc2\xb5\xf3}\xec[(\x14\x8e\xba\x8a2\x9d\xd8B\xa9\xf0\x80\x84\x14\x97@\x08Q\x12\x16\x05\x84\x85\xe2%\xfb\xbbLG\x93\xd2\x0bO\xa4\xc9\xbe\xe9\xc4|{W$\xe3Z\xb6\xc8\n\xfe\x02J\xab^\xbc&oS\x96\x1a<\xc5\x18]\\\x9d\x03\xe9h\xd4E\xe8\xe7h\x89\x92Z\x08\xfd\"\xd2\x84\xac\xa0s\x01\x0f\xad\xaeB\xf6\x89\xe4\x95\xbd\x95\x07\x0b\xce\x97\xb1\x80J\xe5\x8c\\l\xb8_\x8f\x03%8WJY\x1d\xea\x1a\xdf\x98\xbf\xda\x1dO\xf5W\x19\x7fE\xe1\x8f\x9c\x86\xb0F|\x86\xdc\xa4\xb5\x89 \x0b\xd4,\x83\xa5\xb2\x1b,iA5\xfe\xd0\xfek#\xf8d\xb9\xea\";\xc1\x163\xc27\x12=\xe7\x14:\x01\xf9\xb2\xceIQ`\xd6\xa4\xaa(\x81\xc4\xe5\x92\xe4p\xc5c\xccf\xb9D\x05\xb1`\xcd\x0e\x8c6\x86J\x1a\xb8\x935s\xccc6\x96\xaa3\x8eJ\xc2\x8d\xed\xe5\x94\xd8-\xd3jC\xa7\xf5\x0d\x0c\x08@\x07\xaa\x91\x96\x85\x95\xd5\xcc\xbd\x0c1,\xd4\xdd\xc6\xfb\xc8\xa8\x11\xb1\xc7g8\xfd\\\xa1CD\xb2\xa1K\\\x83\xcbKJ!}\x93\xfb\xa3\x1aX\xef\x8e\xbfM\xfc\xa4\x03\x93}`\xea\xee\x99\xedz'-\xc5\x12zMS\xe09f\xe1\x07\x0e&\x9eb\x906e\xe5\xbb\xe3\x03\xe3\xf5\x0cMc\x06a\x97\xb6\xce\xb3u\xd1\x845\xa4\x98\xaa\xe4\x01HyIN\x16\x05K\x0d\xc5B\xcc\xad\xe7a\x89\xf9\x0f0Nr&\xad{\xbb\xef\xe2\xef\xd8w\xa4\xba\xdd\x87r\xf4\xa9\xe2# \xa3\xf2e\xb6Zg)\xc1\xbc7\xbf=\xf8J\x95\x82\x94\"EY'\x90\x91\x88\x11%n\xa69\xf4\x90\x04x\xd8\x8f\xdcu\x0e\xf7\xeb\xec\xef|~\x01I\xffZ\x91\x8a\x9c\xf31\xd4V\x15\xbe\x94\x87^\xab\xfb\x92\x87\xa2\x15\x11\x9d|p\xc4\x14T\x01\xa7<\xc9E\x96G\xe4gl\xa8[\xb6f\xe8\xf0u\xf3\xad\x906\x96\x03\x07W\xfa\xe0H]\xab\xe3\x8b\x14\xd8\x17\xcap\xaeP^Qp\x1d)\x85\xaa\x94 \n\x1fb\xb7\x90\x1b\x90Z\xf3\xd4/\xe3\xe2C\x95\x93\xd6\xa9\xe0 D,\x8cB]\xf3\x18B\xf5\xca\xd2\xc6\xa4\xb7\xc5\xb7\x00N\xa9{ ;\xaf\x0b\xf8\xa2\xe1\xbc\xe2mV\xa5%\x99\xf7\xc5\x0d\x14\x14\xb5fc\xa9NC\xdb\xbe6ae\xae/\x1d\x0dm\x18\xe6\xfa\x1f\xc9: #\x16\xa0ph\x1f\xe2n\x18\xea7\x8bm\x86\xec\xf9\xe3\xf7@,\xba\x1c\xac\xfe\x1b7\xfd\xdb\xb7\x1f\xb5\xfd\x04GU\x9e\xe3 \xdd\xdcu\xa2{\x16\xc3\xb2\x9a,\x98#H\xf3\xcburz\x05\x03\xc2\xd4\xf8\x0e\xfa\xdb\x1c\x8c'\xe3\xdd\xdfuQ\x9c\xf3W/?\xbe\xfat\xf9\xe3\xfb\xcbw\xef?]~xq~~\xf9\xe9\xdf\xdf\x9c_\xbe\xffx\xf9\x97\xf7?_\xfe\xf9\xcdO?]\xfe\xf0\xea\xf2\xf5\x9b\x8f\xaf~t\x86\xf4\xa9Q\x12\xd3\x897L*\xd1\x17!\xafu\x97\xcd~z\x14\xfc7T\xb7\xd1I\x8f\xd3\x7f\xba17\xa6\xbb\xba&\x14\n\xae\xb2\xf4\xd5\x97\x92\xa4\x94\xf8-0\xca\xf85)\xb5\x12RD\xe1\x9a\xfcH\xc8\xfa\xa78\xfd\xfc!\xc4\xa4\xcb\x84;\xbb\xb5\x8a\x8be\x98$\xd9\xed\xab\xbfVa\xf2\x1f\xe4\xae\xe0i\x05\xe3d.\x82\xbe\xb0jY^\xb2\xccz$\xb8*3^H\xf28L\xe2\xbf\x91s\x12\xe6\x11ko\x1d\xe6\x85\xfc\xfb\x9a\x94\xe7\xe1j\x9d\x90\xf3hIV\xec;L\xd1\x10\x96\xe4C\x98\x87+\xad\xa4,I\x9e*eo\xe3\xf4'\x91;Z*\x0d\xbf\x18J\xffX\xc5s\xa5\xe0\xc7\xb0$\x9f\xe2\x15Q\n\x99%\x8cR\xf4C\x96%$T;~\x1d'\xeawo\xd2\x92\\#\xad\xd3\x94\xbd\xabVWZ\xd1\xdb8\x8dW\xd5J\x1fn]Fi\xac\x97K\x12}\xe6\xdf\xad\xc8*\x8b\xff\xc6\xba\x8a\x8b7\xabU%\x84~\xa6\xd0>\xe2:_Q\xd6p\xfa\xd4d\xbd\x1e\xd7\xaf\x8fL\xaf3\xfe\xfap\xcf\xf4\xb6\x12\x1f\xef\xee\x9a^\x87\xf5kc\xd7\x05\x7f\xcd9S\xf9\x15\x9d\xdc\xff=\x7f\xff\x8e\xeb\x00\xfa\xec\x19\xec\x9eK\xc2*\x816\xc6\xce\x9b1\xb9-p~\x93\x85\xa4kb\x97\x0d\x11P\x15*+X+\xc6Z\x9d\xf4\xa4\x93\xb2\xa1\xf4:\xedD\xbc\xb8\xeb] \xde\xc8+\x17C\xd6|qy\xe4\x9a2\xfb\xbf\xe7.\xb2]\xaa\xdfj\xdd\xc3\xff\xcf\xde\x9fw\xb7\x8d#\x0f\xa3\xf0\xff\xcf\xa7(\xeb\xc9/C\xb6i\xc5r\x96N\x9c(\x9et\xe2\xa4\xdd\xd9z\xb2\xf42\x8a\xc6\x87\x96 \x8b\x1d\x89TH\xd0\xb62\xf2\xfb\xd9\xdf\x83\x02@\x82$\x00\x82\x8e\xbbg~\xf7^\x9e\xd3\x1d\x8b\x0b\x96B\xa1P{\x85i\x1a\xae;t@E\xb3\xe8\xd8\xaa\xfe\x8d\xbd\xbc\xf70@v4nv4K\x93\xe5O\xef\xdf\xa6S\x92\x125\xef7PO\xab|g\xabr\xe1\x11c*S(VN\xb1\x84,\xe5\x92\xf4\xd9\xbe\xb4}Z\xc0\x8b\x94\x19x\xa3\x8c\xcf\x04oM\x8a\xa6\xde\x93/\x1e\xf1\xfb\xcbp\xe5Q\xccd\x1fe\x14g[\xbe\"\xa6\xf5:\\\x95oB#\xc6 +;D\xf1\xf4C\xe2$\xa2\x80b\x16\xab\x1b\xb8\xa0jV\x0d\x159\xdb\xef\xcf\xa2\x05%J<\xa3\xb1 \x91hA\xefD\xa3\x8d\xf9\xf3\xd9i\x7f\x18N\xe6e\xeb\xc6\x1c\x01\xd2*0J\xc7h\x0dM\xc78{O\xe4^\xd7X#\x9a%\xfe\x18\xc8\xe2$]\xe2 \xc2qn\x08\xef\x03\xa4\x13\xcfcW\xa4m\xc9\xe8\\\xf4\x14e\x05\xdd9\x14}\xe4X\xfd\xf8\x9a{\x91\x13qj\xb6\x8a\x9bu\x97\x10A%^\x87+\x17t2\xa2LJ\xa6\xf9D)\xf2g\xcb\xfdP]W\xe2\xb1\x95\xe5\xa6\x9df&\xd8\xcb\xa0\x12\xd1\x08\xca\x90\xdfa\x97\x7f\xd9\xa8\xcfD=\xabr\xbc\x06\xcb\x9cP\xf7Z\x0f\x84\xa8\xed@\x88D\xa5\xa7\xdd\x00\xf2\xf2n\x1c@\xd4 L\xd9:\xa3d\xf9a\x9e\xc7\x9f_G\xd3\xe9\x82\x9c\x87\xa9]\xe4\x07\x9d\xe5\xce\x04\x13\xd2\x9fJ\xf7I\xc1\x85\xe9K*@\x97Fu/7\xf4H\x86\x0f\x8cyKc\x8fz\xe8\xbfE\x9c$\x8b\xe9\xc3\x1e/_\x8f\xff\xa9\xaf\xe2\xbd\xf1h\x05\x07\xb8v\xb7\xe1\x00\xf6`\x1f!|\x0f\x0e\xe0\x8e\xf8\x9b\xdd\xbf\x0d\xfb\xb0}\xeb_^\xe8\x9dd4\x0d't\xb3\x88\xc2l\x13O7\xd2y{\xc3\xf6\xec&\xf3\x96\x9b\x8c\xa4\xd4?\xd8\xe44\xf17'^\x98\x91\x0d9\x8d\xe2M\x92,<\x12\xc6\xfe\xc1&%\xe1\xe7\xcd\x9a\x12\x7f3\xc1\xc7\xec\xc0\xd9\xcc\xc3t\x83\xf2\xedt\xb3\x08\xb3l\xb3Hb\xb2I\x96\xab\xc5&\x893\xbaIb\x1a\xc59\xf17S\xe2\x9d\xe4\xa7\xa7$\xddL\xa2e\xb8\xd8L\x16aJ63\x8f\xed\xf1\x0dI\xfd\x83M\x14Gt\xb3\xf0\xc8iH\xc9\x86P\xe2\x1f\xf8\x9bi\xb2\x99&\xf9\xc9\x82l\x887\x99'\x9bEv\x10\xcd6\x8b\x8cx\xd1\xcc?`\xf3\x88\xb3<%\x9b8_n\xceHL7\x17\xde\x84\xac\xe8\x86L6+\x0fS4o\x92\x94\xfa\x1bJ\xbcx\x9amPs\xb2Ic\xdf\xf7Y\xd7\x8b\x05\x9d\xa7I~:\xdf\x84\x8b\x8cl\xb0l\xf9b\xcd\x86r\xc1\xa6\x93\x84\xeck\x8f\x84\x939\x9b}D\x18\xd8\x92\xe5&\x8f'\x1e\xdb\xbdl\x80\xa7\x8b\xe4$\\lN\x13\x9alN\xf30\x9dn\"o\xb6Y\xae<\x8e\x03\xd9F\x19D\xecEt3Y\xe4S\xe2\x1d'\xf1\x84\xf8\x07\x9bE\xc4\xa0\x95\xd3\x8d\x14}6\xd4#\xe9,\x9c\x90\x0dI\xe3p\xe1\x1f\xf8\x07\x9b\xcc\xdf,\xbcpy2\x0d7\x84n\x92\xc9\xe7M\x12\x9f\xfa\x9b\xa5\x17M\xd2\x04I\xe0\x06\xf5L\x1b\xaeK\xf07o\xc27\x9b\xd8\x0b\x97$[\xb1\x96B\x1a\x9d\x91\x0d\xb9\xa0\x1br\xbe\x89\x16\x9b\x84n\xf2\xc5\xc2\xdf$\x1e\xb2E\x9b\x15\x8f\xaf\xdc\xa4\x9b\x9cn\xceH\x9aFS\xe2oV^8\xf9\x1c\x9e\x92M\x98\x86\xcbl\x93Fgl]\xd2\x84\x92 %\x0c\x104\x99$\x8bM~\xb2\x88&\xfe&\xf5\xc2\x88a\x8c\x17N\x93x\xb1f\x0b7\xdb\x9cF\x19%\xe9fEB\xba\xf9\x92Gi9\xefl\x92\x93\x0d\xd7\xb3mh\xba\xde0\xaa\xe8\xfb\x9b\xcc;Y\xb3\xc5\x0f\x17d\xba!\x8b\xd9f\x9e\xa4t\x13\x9d\xc6d\xba\x89\xbe\"xB\x1aM6\xa8\xd3\xd9\xa0\xa9a\x93\x9fp\x97\x84M\xbe\"\xe9f\x1dO\xe6i\x12G_\xc9t\x83\xb1\xc4>\x83\xe8r\xb5`\x83\x9f\x93x3\x8f\xb2\xcd\xf7|L\xd1\xce\x06\x87\x11^\xf3z\x8a\xf6\xcc)E\xfb\x14\xab\xfc\xa2AB\xefGR\xbc\xdc\xf4\x86\x99\x06Pw\x06\xae_X\x8b\x8c1\xa6\xd6\xb7N\xf1\xadA\xcb[K\xc6\xd3z\xa7\x01\xc4\"\x83\xc9\x00K\xede\x84za\x00k[\x81\xe2&*H\xa1c\xc9\x84\x8e\\: .1\x19\n\x0fq[\xea\xb9A\x0d\xb1hMU\xdb(\x9a([0\x11\xa7\xc2\x9b\x8d{\x87\x95\x84\xbe$U\xa3\x81\x86\xb8H%\\\xa3\x08J\x80\xf6\xb5l\x12.\x9e\x86\x19\x1b\xd6\x93\xea\x9d\xe7b\x90\xad\xa0\x91\xeaG\x8f\xf6Sn\xe8\xf7n}\xea\x8f\xfe\xd5\xbf5\xfe\xee\xc6-&J4K\x7f\x92~\x16\xc6\x11\x8d\xbe\x92\x8f\xe9\xa2\xb5\x87H\xad_\xabz\xdb0a\xadW\x8b7\xd2\xc9\xd6\x8abp\xa6\xf6\xeck\x8f\xe0SB\x9fL\x18\x97\xcf\xb0%M\x16\x8b(>}G\xb2U\x12g\xed\xd0\xa8\x9dd\xa5\xc2\xbf\x1fe\x8a\xf6_Q\x87\xb0\xa51i\x0c\xaa\xc7\x9e\xfe\xcdR\xbf4\x8b\xe2\xa9\xd7\xaa\xac\x91Wq\xc2e4Li\xf6kD\xe7^o\xafW\xe8#U\x15*\x83\x89\xd7\x9b\xf0\xdd\xc3\xad\xf6\xff\xbe\xf4K,lz\xfe\x01\x98+X\x15\xaa\x1d\xaf'\xba\xe8\x89\xc4\x9b\x1a;\x89\xa1\x8d\x14\x9d\xe64\xe3\xd27\xe2\x17\xca7a\xea*\xb3\xa4\xc5\"O\xa2Y+\xc7\x9aM\x9bx2%d\xb5X\xbf\xa7i\xb4zI\xd65~\xcd\x927\xecZX\xaab\x99[\x94\x81:\xa7L=\xb6ut\xbb\xafZ51\x99N]K\xb7\xd9\xa8\xe4\x8f\xf1q\xb1\xcd\xd4&5\xef5e\xf8\xbf\x19\xb05d\xb1\x86\xa3\x91\xc6\xe4dVh\xe3\x98b\xee\xa1\x17a=D\xd4*\x8a\xc8mv\x87 5<\xa1\x0c\x15o\xe8\xd3V_\x9aU\x90\x91\x86\xec!\x15s\xb1\xa3F\x86\xa2\xdd\xa6\x94\xe2\x80^)\x0c\xb9A-\xeb\xcdp\xddp\xa6\x18\xad\x16\xb4m\xc1)\xb7Z\x94\xd5\x8dMn\xf5P%\xbeU7_n\xdf\xd3T\x94+\x98\x9d6\x83d\x91o\xb1\xd9\x84iM\x18L\xc4g\x1a\xd2\x1f\xa3\x03\xc6\x87\xa4p\xeapX#\xfe\x8da\x8d\x94\xde\x8chR3\xfdU\xdfc\x9bb\"\xfd \xee5\xfc\xfa\xa1\xc8\xbaq\xfbN=<\x05D\xee\x0d\xf4\xb0\xb83\xd0}\xba\x92-\x7f\xbf\xab{\xaa\x0f\x89\xaf\x16_e\x0f\xcf*\x07\x89\n-\xa3\x05\x19\xb3\x16\xf4\xa3\x18\xf5\xe3\x99\x17\x97\x0c\xb8N\xb7\x02\xaa'\x809:\xd7m\xa3\xc1\x01(\"A\x84A\x13\x11\x16Z5\xf2\\.hm\x8d\x95t\xf1<\xc0C\x9c\xe2\xa7Q\x93\x18p\xfe\xad\x9f%K\xd5s\xa2\x8d\xddd\xbd\xac\x95a\x8eb\xc6[\x8db\x8d\xdd\xeb\xb2\xbe%\x9a'\xdf[\x83\xdfc\xeb\xfe\x80\"\x10\xf01\x94\x02T\xef\x97p\x91\x13\x1e\xe8uB`A\xb2\x0c\xe8<\x8cA\xb4\xdck\x8e\xb1\xb9;\xfe0\xf8gv\x18\xd3#\xf3\x98NQ\xe5\x9e\x8aa\xf1\xc6\x9d\x86\xf5Y\xefI\xda~Z\xa0\xa4y\xeb_;\x07\x9f\xa6\xdb\xde\xa7>\xfb\xc7?\x90\xb6\x01EN\xad\x0d4\x04\xc1\xf8\xb8\x0c\xee\xc8\xe0\xfa\xdamt\x0e\x83\x8a!\xe2\x8d;\x0d\xeb\xb5\xceE\xd7mLx*\xd5\xf2+\xd4\xbc\n\xcd\x90\x9bE\x0b\xe24\xc0\x0f\x06\xbfb\xb71\xf6h\x9a\x13N\x1aD\xccR\xb8\xc8\xd4\x1b[\xbb\xca\xdf\x03\xc9\xca\x9bF}\xc2\xbbw\x1a\xf8S\xbd\x8f\xb4\xdb\xb8\xf9`5\n\x1f\xf3\xd8\xc4\xcb.C\xfb\xd9\xe4\xd3\xed68^\xb1\x9f}V\xb8\x0b[VZ6\xef4\xb2w:\xf7s\xb7QIqO\n\x1b}\x9a\xbcJ\xceI\xfa4\xcc\x88\xe7\x07\xb0u\xeb_\xa3\x7f{\xe3\x83\xd1\xee\xce\x83pg6\xfe\xf7\xfd\xcb\x9d\xe2\xef;\x0e\x7f\x0f\xf6.G\xfe\xe5\xd8\x890\xb0\x91;M\xf8\x8d\xd1\x0b\xdf\x9d\x98\x96\xbc\x89\x1b\x9d\xe7]8\x0d\xef\x951t\xa0\xfb\xf0:\x90\xfc\x0e#|f\x08xp\x1e\xdf\x16O\xebpzx\x81\x1e\xc9\xb6\xa5\x9d%\x8bEr\x0e+\xd1I\x0f\xb6u.\xec\xd53\xbc\x19\x9e\xd1:\xb2\xabr\xb67oV~\x9b\xb9Z\x13\xc7\x8b\xac\x1eR\x9e\x93d\xba\x16je\xae`\x8c\xe2\x1ew\x93\xc7_h\xc8:\xbeX.z\xc7\xd0\xf9LyS\xb0\x1e\x867\x17\xe5\x9b<\xc9\x85\xfe\xb5U\xf9\xda,I\x97!5\xbd8\xaf\x8cQ\xec\x00\xc3\xbb\xd3\xca(\xed\xef\x9e\x95\xef\n\xc4\xad\xa7\x1e\x01\x01G\xeet\x950\xa67\xb2f\xe6\\3\x91\xbdT\xcc\x0d\x01\xbf\x8c\xf4\xfd\x83Pe\xf4B\x99\xe0[\xbc_\x15\x9ay\x82\x97H\x16\xd306u\xackJot\x94MN\x92<\xa6&-:\xbbN0\x9c\x8fq$\xcal\xccl\x8d\xb9!\xd4eH&\xa1l\xcb\x8bx\xa6\".\x96X\x06r\xc1\xbe/\xb5i\x95\xcfw[\xbf\xc6\x94\xf1\x92\xf9\xeb\xfe\xf9\xa1\xc1\xc8\x0e\xd2\x00\xd7\xd0B,\xcc\x9e|V\xed\xaa\x9bdvhp\x08\x90\x17O\xef\xad\xd7\x11G6u\xac\xbc\x94\x80\xa7\xc8\x0fD\x7f\xc6/\xda\xed\xcf\xf2\x92\xb4\x88\x1b\xb8{H\xf7 ;\xde\xf88y\\bq\xf6\xe1\xf1\x80c\xe9\xf9\x81\xa1\xfc8h\xf5\xb9 \xb6\xe3\x13F\xd2\xd7\x01\x9c\x16\xb5#0\xb5\xfd\xfb\x00\x0e\xc75\xe1\xd5:\xf6R\xdf\xa4}E\xa7\xe6\x07\xb1\xd4 \xf2\xcfe\xf9 9\xf7w\x82\xd6\xc3,\"\x8b)D\x19\xe6\x0fY\xa5\xc9Y4\xc5\x13@G\xb1e\xa3g\xb6\xc1\xb2\x89\x7f\x85!<\xf3\xa2\x00\xce,N _\xd1\xc4\xc1\xc7\xf3\xd5\xd5\xd9\x00\xc4\x10\xe6\xe5\xd6\x99\xb7\x8d\xe69\x0c\xe1\x0d\x1b\xcd\xdc2\x9a\xe7\xcah\x9ew\x1d\xcd\xb4m\x08\x1fa\x08\xaf\xd8\x10\xea\xa5E\xd4\xeb\xa32\x84\x8f]\x87\x10\x96\x00 \xdbF\xf3\x03\x0c\xe1-\x1bMh\x19\xcd\x0f\xcah~\xe8:\x9aY9\x9aY\xdbh\xbe\xc0\x10\xfe`\xa3\x99YF\xf3E\x19\xcd\x97\xae\xa3\xa9\x1e\x89m\xe3\xf9\xdd\xe2\xb7$/\xe4n\xbc\xdfQC\x1eR\xb2C\x99\x1c\x85\xcd\xaf\xe0\x00~\xf6P\x85\xd6\xcb\x99\xb0Q\xdc}\xc7\xef>\xe5D\xd4\xcc\x17\xc9K\xcc\xf6w\x93\x1bKIf\xab\x07[\xdb\xfc~\x85!|\xf0\"\x0b\xb0qv\xbfv\x18\xe3\xaf\xedc\xac\x1c\x9emC\xfc\x05\x86\xf0\xb9}\x88\xbft\x18\xe2/\xedC\xac\x9e\xd0mc| C8j\x1f\xe3\xcb\x0ec|\xd9>F\x95\xc1j\x1b\xe1\x8b\x96\xa1\x1d#\xf3S\xb0a.\x03}!y\xd6\xa3\xd8\x1b\xf5\"J\x96Y/\x00\xceg\x8f\xfd\x00\xa2\xa6\xa1\xbb\xcd\xd7\x03\x14\xc1\xaam\xdb\xb1\xab\x82I/\xd0I\x82!\x0b\x06\xabV\x97P><\x12\x0fU*\xf0\x02\x190\xf6\xf4)\x13*\x03ap\xe7\xeb`\x1f,\xbb\xa2xJ.\xf6\xa1\xc5g\x90]$M\x93t_\x13/\xa7^\x97\x96x\xb0v\x9cP\x18\xe46\x94\xb8\x01Cx\xdd\x8e\xb47\\pA\x00\xeb\x86+56\xda\xbd5\xfe+\xcdl\nvNI:\x1a}\xbb\xbb\xb1\xc6\xd2 \xc2/\xa8\xab\xd8\xdf0h\xe9\"\xa0\x19\xbco],\x17BwE\x8c\xf2]\xc4\xbd\xae.\x96\x0b\xdc\xb6\xf8\x17\x166\xb2\xad9\xd7\xf3\xb0o\x98\x94/\xbe\xfd\xf7e\xc0\xbe\xbfq#%3\xd5\x1d`\xbdBO\x18\xda\xc7}\xcd\xff\x14%WD\xb9'\xda\x0f\xa7S\xf4M\x0c\x17?\x97O\x0e\xe0o\x8f\x0eX\xe3g$\xcd\xa2$\x1e\xf6\x06\xfd\xdd\x1e\x90x\x92L\xa3\xf8t\xd8\xfb\xf8\xe1\xf9\xce\xfd\xde\xc1\xe3O\xb1pl\x87\xdf^\xbf\x02r\x81K\x0c\x13\x9e\xe2\xf7\x84\xc0)\x89I\x1aR2\x05\x1e\xa4\xf47\xa3\xff\x93\xbc\xa4!LL\xa7\x8f\xa9\xb1\xbd[\x9f\xde\x7f\xf7\xe9\x96\xf7\xe9\xfd\xb6\x7f\xe3\x96\x05\xd9K \xc2\x10\xa2\xd1\xa0\x19\x8c\x08F\xc6B1\x16\x9eJK\xed\xf4)\xea\xcb~{\xfd\xea\x90\xcf\x8d;\x93\xb8\xf8\x80\xb0\x89$\xc2\xc3\xa8l\x8fo\x82\xe7i\xb2\xe4\x1bA\xb4\xd7\x9c\x91T\x8a\x99$\xbb\xa4M\xb2K\xb0\xbcm\xcd\x13&)=a`_\xc9y\x06Pxi\xaaYP\xac\x8e_g\xa2\x0eI=\xa9\x92\xbc\xd8\x12\x94\xe2\xfc\"\x99\x84\xac\xa9~\x86\x8d\x1b\xf4K\xa5\xde\xd2\xb4\xb5z\xa8\xa47\xee\x11y\xf0\x90~\x96\x9fd4\xf5\x06\xbe\xac\x17tS\xa7\x8d\x01\xd5C=\x85(\x86\xd8\x87\xb8^>%\xe5\x8e\x8a\x18g8J\xc7\xb2\xc5!&[\x1bM\xc9$\x99\x92\x8f\xef\x8e\x8a,]^:\xda\x1d\xfbc,\xdd;@u\xa1\xf6\x9d\xc1\x98\xdbU{.\xf8$\xb7us\xcd\x9a\xd9l\xec\xb4\xd5h\x15_\x86+\x07\x7f6\xf19\x12\x83\xea\x8c\x88\x0f\xdb\xd0\x1b\xa2\xb6\xb6\xf9\xb4\x9a\x99T^\x97~\xff\x8f$\x8aqy\x9aS\x13\x19{\xec\x83\x92\xf3\xa9d\xdd\xa0\"n\x17K\xd5yD1W\x04\xd0\xcb\xe9l\xe7~\xcf\xf7\xcb\xbb\xbd\x930#\xf7\xee\xe8\xc6Pf\x10jv\x9d`\xb8Y\x94\xc4\xd9{|\xcb\xe4\xb5\x13.V\xf3\xb0%\x97\xacz\x154\\j\x13\xe7=\x1f\xb7\xd0\x02S\xc1\x85)\xf1\x88\xfa\xccpd\xeb7\xe6\x92\xd0y2\xbd\xf2h\xf8\xe7\xa6\xf1\xc8\xa7\xceLDs\x8c4<\xfd\xb3\xc0Y\x1b\xb2\xf3 5\x98Y\xcb4\xe5\xc6\xce\xe8\x9cT\x94\x8c\xeeQ\x0cF\xbd\x91\xf4\xe6\xa5F\x0f\x11\x85m\xe1\xa5oz\xe5\xdf\xa2\xcc\xd1(\x0e\xd8\x06\x0dt\xfb3\xf5K\x9f\xfa\xff\xd9\xdb\xbdu\x1a@o\xbb\xe7\x8f\xc5\xfe\xd4-\xa9\x91J\x11\xdb\xa6\xd6d\xee\xaa\xac\xa4\xc1\xb1\xa6P\x9a1\xc25- W\xac8\xe5\xb4\xb9\x8ct\xf2\x18\xa9\x8e\xbc\ns\xa9\x143\xa4's\"\xc0:\x8f[d\xcaT:&\xcc\xd9\x98\xd4(\x8d\x96\x9e\xb2H\x9f2\\\xa3c\xb4\xd8\xf4z\xb6\xe1\x1a\x92\xab9\x0d\x93\xc1\xec\xb8\x84\xd9\xd7\xa6{Y\xa0I\xe7\xe6\xd44m\xe6\x9b\xb0\xecd\xf1\xd1\xad\x7f]\xec\x14\xccu\xeb\xb2\x05\xc6\x14t\x7f\xe6\x08\x85\xfdgS\xd8\x976\x85\xf5h#\xecb\x1ba\xf5r\x9f\xca\xff)\x1f\xf0\x94\xdfl\xa7x\xf7\xee\xfb\xfd\x1f\xf2\xd9\x8c\x08\x7fq[\xf5\xa3\xb3\"sSq\xf2\x95x\xa2\xa6\x19\xacX\x8c\xc0%S|o\xc49U\xfe\xe9\x18\x91:nT\x8cr\xca\x06\x89\x94\xae\x1cWjcD\xf59\x0eAaO\xf9T\x94d\xbc\x8bhBL^\x97\xc4\xb8\xbc<\xa4\xaa\x9aL[\xe4K\xe4\x14@-1\xe1c)+S.\xd9zZr\xfdP\xecx\x99\x97\xbe\xaf/\x9b%\xb9\xf4-\xa6\xd6\x16\xc3\xb2\xc5\x17\xae-F\xd6\x16\xb3\xb2\xc5\x1b\xae-&\xed\xb3\xbey\x13\xb6&e\xd3?\xba6\xadI-\xaf4\xbd\xe5mQ.\x87\x8f\x16c\xb7\x06C\xd7\x06\xeb\x898L\x0df\xae\x0d\xce\x1d\x1b\x9c\xb4\xaf\xf8f\x83\xdd:57s\x1d\xdf\xb41>\xf5\x17\xf1R^\x83\x85x\x91\xfc#\xe1\x7f\xc4\x8a3+\xcf\xd5\xcd\xee\xbc$kL\xcf\x17\x8a\x17\xe2)\xb9\xc0\x1b\x19\xbf\xf1$\xcb\x92I\x84\x99!\x00s\xb8\xc4e\x00\x1c`x~\xdc\x97m\xb0\xae\xfbe\x0bl\x00\xfd\xf7\x04k84\xe9\x07\xa6\x19\xf8\xfb\xdf\x8f\x8f\x8f^\xbf\xfe\xf8\xe1\xc9\x0f\xaf\x0e\x8f\x8f>\x1c\xbe\xc3?\x8e\xff\xfew\x8dji\xd5\xfc\xe2\xe5\xe1\xef\x87\xcf\x0c\xaf\xcf5\x1d\xbcyv\xf8\x9b\xf1\x83i\xf3\x83\xb7\xef\x9e\x1d\xbe3~p\x06C\xb8\xdb\xbc\xbd\x86!\x0c\xe0\xd1#]\xb5\xf3S\x18\xc2\x1av@\x93\xaa\x7fi\x90\xf7\x8f\xed5\xae\xf7\xeb\x89$A\xcf\xf9\x9f\\\xa5\x19\x13-?o9\xd8\xb9q\x18\x0b\xbb;\x92\xe4\x0b}\x8bT\x1c\x0dE\x83\xbbn\xdb\xe9=O*\xaf\x7fxh9\x89D\x84\x9bF\xaf^\xa9\x0e%\x0bH{\x98x\\\xa88w\xb0JH*r\x9e\xcb\x94\x05<\xd3\xc6\xeeCLw\x11?\x84h{\xdb\x87t\x14\xf1$\x89\x11\x13\xe8\xcd\xee\xf5\xa9\xd3l\xed\x01\x0d\xaa;:\x06\xa2\n\x98f<\\\x82\xf6\x8f\x8fy\xe9|\xe2\xfd\xc1OW\xf6\xc4\xa9\xe3\xb7\xd6Tb\x85\xf5A)\xe9a\x13\xc1P\xb9\x04\x8f\x1f?6\x995\x84\x92j\x1bb\x11C\xbd\xd9\xc0\x9d\xbd\x07w\x1e\xdc\xfb~\xef\xc1]\x9ca\x19\x99\xf8&|\xa3o\x85MZ\x93\x92\xcf\x04>\"\xcax#\x90\xb7Q\xf1\xe1\x06\x9c?l\xc5\xf2\xeb\xf9\x9c\x0dm|v\x90\xda<\x19jP\x16\x9d\xde\x92Q\x91\x14\x1e\x0da'\xae\x14,\x1cJ\xd0\xd5_&\xf0xXW\xc0\x9a\x06v\xd4\x96\xbd\xf1\x83\x18\xb9\xe3\x86}\xed\xda^\xbd\xaa\x8f\xa1\xbd\x0f\x0e\x80\xab\xc5i\xc4\x986\x97/\xb6\xba\xbf l\x03\x1a\xc5j\xb1\xb4\x8cC\x92\xe5\xe2\x99\xbc`\xac\xde\n\x02\xbf\x9f6\xabT\x83pd\xd6\x9c\x07\xef`\x08{\xcd\xdbo\x9c\xb3\xb6\xf3M\x9d\xa4\xcd6^\xf1\x93N\xbe\xa09\xda\x9e\xc1\x10\xde0\x1cye:\x02\xbe\x1a\x08\xf6<\xca0\xbb\x8833\xfe\\\xae\x94!\x99\xa7\xb4Z\x94\x0b\xc5\xb6\xe0\xa0\xb2l#\xf6\xbd\x85\x8a\xc2\x01\xa4\xc5\x19\x12\x89\xb2\xc0\xd6\xd3\xd0\xe0\x078Mb\xd3\x89\xebH\xab?\xda\xa8\x82uH\x1c\xfd\xac\xe3j\xad\xdcc\x18\xd4\x0fv\xees\xebWW6\xf6\x8b\x9d1\x00S\xd5h\x8a8\xe3\xd4\xc5\xefv5\xe0\xaf\xda\xf4\x1d\x05-\xe7Un\xb5\xc5\x96\xf5\xdd\xfdj\xef\x8e3(o\x90\xd6\x8e\xde`\xedR:ze\xcaM\xa4\x9d\xbb\x92\xb7\xdaiD\xbf8\xc0X\x13\xcc,\xb8\x14\xa7.^Z\xbb(\x92\x01\xa8G\x8e\xdc\x8e \xcf\x95-\x85\xe8>M0]\x83\xb5\x80\xb5\xbc$P\xd1y\xbd\x12\x167\xac\xd5\xe6!\xe7@\xa85\xc3\xfb\x96\xa9^\xd8\xe1\xc5\n3\xd3q\x06\x0d\x92\x14\")\x15 5K2\xe3[.\x0b\xd8\xd3\xcf(\xdd\xf0G\xfb\xe8.o\xeaV\xbb\x8a\xecj\xa6\x083\xc0\xfd\xc5\xb7\xc1\xbdO\x13\x94\xc5$\xc4\xc5\"\x84\xcd\xb5\xa0\x98\x9f\xfd0\xa6\xe9\xbax\x99\xba\x8e\xf2\xc6\xb7\x8dR30\xa2\x0e\x84\x8dSH\x91\xf2V\xe8<\xb6\x1f\xadc\xf3\xbe}pr4h\xe0\"\x14\xef\xd7F\xa6\xfe\xfa\xaa\xa8\xaa\xa8&\x1f\x81e\xb0\xbd\xd1\x918\xa0\xc75\x05t\x00_\xfb/\x0f\x7f\x7f\x0fCx\xca\xfe\xfe\xe5\xc9\xab\x8f\x87\xec\xd7\xcf\xec\xd7\xe1\x9b\x0f\xef\x8e\xf0\xe7\xbb\xa0\xd2\x7f\x14g+\x9e\xed\xbc6\xaa$O\xab\x99\xb9m\xf4\x85\x1d\xf0\xe6\xdc\x0bJ\xcb\xa3g\xe3\x0em\xd6\x1b\"\xdeK\xae\xb7x\xd9Of\x8e\xed\xbc\xf4\n'\x92\xc6\xc0^V\xa7L\xbe8\xb6\xa9\x1b\xdb\xcb\xab/*\x82\xef\xf8\xb84\x8e\xb2\x91\xfc\xbb\x17@\xef\xb2i\xcfQ\xfb\x99\x84\x939yG\xb2\x962\xc7JW[\xbc/\xfc\x10d\xc5\xafB\xd6\xfb\x18\xe3\x83)\x17\x06\x957\x87\xfc\xc5\x12\xeb\xcb\x8a\x0f\xa2\xfc\x99\x14\x1c\xcb\x8f\xc4\xd9\"^\xb0M\xa3\xe8\xdf%\x86HLdB\xcb\x82d\xbc\x02\xa8K\x0f\x89S\x00\xbe\xe8b\xd6\xda\x05\xf1^\x04\xf0\xd2\x0f\xe0Ee\xf1%\xbdu\\\x13=\xa6\xdf\xe0-\xdfp\xc7\xf4\x1b\x16L\xbfQ\x19`II\x1d\x9b\xd6\x0d\xf1\xc65#\xfc\x88!\xfc\xb8\x89\xf07\xae\x19S\xea\xb5\xdd\xf5=|\x13\xa64\xbb \xde\x8f|=\x7ft_\xcf\x1f-\xeb\xf9c\x8dr\xd1o[\xcb\x97\xfd(\xe3-D\x94\xfd\x92\xda[\x86\xdeB]\xcb\xc6\xaf(ro4\xb5\xb7?\x05\xf0\xcf\x00~\x0b\xe0\x1fM\xa5\xe9\xfb\xc3\x7f\xa0\xc2\xd4$9Rj\x11\x1d\x8fCQ+\x83\xd6\x88M\x17\xf6\x95\x18z\x90\xfc\xa50.}&\xebL\xcbC\xf2\x91$\xb26\x88\x1c\xca\xf1gQ\x0b\xab:4\xd2eh\xb1u\xf2Q\xa9\x9f7\xcc\x9f{\x16:+\xe8\xd2\xf6\xee\x84\xe1,\xa8\xdd{*\x0e\x83zm\x1fCG\x91\xa1#y\x16\x95\x06\x8c\x7f8\x1aX\x90\x1b36\xf8\x13k\xcd\xfbI\xe8Z)\xf5F\xe3Ff\x16}\xbby\x0brh\xd2\xe0\x88.\xa8\xdf\xe4\x9a\xbf\x94o\xa4\xfa7~(\xdf\x88\xf5oh\xa5\x9c\x83R\xc8)TOf\xcf\xbe\xabK:\xa3\xcf\x01\x9c\x8dAd\x8a\xed \xf1t\x92Y\xc3\x16\xa0gza\xee\xdb\xa7\xc7\x05\xb9k\x9aEfG\xf2_j\xd8\xa2A\x0f\x0d>\x14\xab\xeb4\x04v\xc29\xa9\xcb\xa8`\xcd\xf4@\x8dL\"xa\xe5H\xd8\x01QZ6\x06\x01\x864\xef>\x84\x1c\x1e\x0d!y\x08\xf9\xf6\xb6\xa9\x11\x10\xe3\x08\xd1S8f\xa2\x15\xec@\xced+\x83\x7f\x15\xc8\xc5\xe6z=\xe2\x85\xa3\xc18@\xc5]8\xda\x1d\xb3/\x03P\x02\xdas\xd8\x86\xa6\x12\x0e\x1a\xe2\x97\xbc\xe4g\x8d\x87\x96\x04s\x0dV\x99g\x83tZ\xa6\xd9\x9f\xbcL\xda\x152B\x96\xaf\x9c\x0d0\x0c\x1b\xbfzV\x96B^\xd2\xf9\xc3}a%\xf0\xb7\xb7\xe11:W\x9b\x1b\x077u\xa7\xbc\x8cjOy]\xc2>\xc7\xcc\xb9P\x1f\xa9i8s\xfbp\xa4E\xbe\xe2w5\x94r}\x8e\xf4z\xa8\xe9\x93j\xbe,\x03\xb8\x05\xbb\x85?\x8b\xf0{\xf1\x03\x89\xce\xf2C\xdb\xc1\xf6\xcfbh\xff\xd4#\xce?\x85\xcd\xa0e\xab\x99\xa0u\xda\x02-\xaa\xaa \xb8\x8a\xc0\xd1WhIm\xceB\xfa\xa5X\xd6\x96BiC\xbf\x1a\xa7\xd4\x13\xaeV\x01\xf4\x9e\xf2(\xde\x8c\x92\x15\x84\xf0.\x8cO \x9c\xaca\x17\x83\x1eAX'w\x83\xea*\xc9\xba#\xb8V~\xa0$\x01\xe0\x9eo\xa2\x1a#.ax\x92\xa1\xeb!\x81G\x82cco\xef\xc4\xd2\x84s\x8c\xc5\"T\xbd\x1f\x89\xa7\x8aj\xf3\x18\x87\x86\x83U\xb1FE\x0f\xfc{B\xa2\x85\xe7\x11\xd8a\x04\xf8\x16\xc4L\xb4\xf2\x99l\xde\x0dw~+`\xf9\x9b\x1ew~\xfb6\xdc9\xd6\xeb\x129\xbe(*\xa5'\xa2\xfaa\xdd2ah\xf6\x84\xda\xdcL\xcf\xadO/\xc4S\xf5\xa1b\xc6\x1a\xfdc,\n\x01\x11\x8f\xd2\x00n\xb0\x95S\xe3\x1eN\x89SIW\xc9\xb5\xb3U`\xe4\x91\xdb\xb4KM\xfb\xe8\xad4g\xf8c]\x05\xf3J\x9f\x9dL2\x15\x7fY\xa5G\xe1![Q-\x95\x1e\xb2CH\xb9\x8b\xac\x11W\x84\x8a\x88z\xf1\x88Q\xae\x14v\xd0\xa3+\x1a\xa3\xf0\xc7:*wf\xc4P\xd1H\xb5\x1bu\x1d\xb4\x93u\xb3\x0e\xe9&\xaa\x9dBc\xf2\xfa\x89\xea56\xdd\xb45\x05\x10\x1e\xa3\xfa\xc3\xc6\x819i\\\xac\xda\x16\xaei\xa1\\\x02/Wf{\x9b\xad\xcd\xf6\xb6C\x14 CuB\x03x\xc1\xe8\xd6\xd5Q\xbd\xee\xe5\xaaC}\xae\x1f\x1eQ-\xcaW\xfa\x9e\x87\xee\xf1lJ\xd3\xf5(wM}\xa2\xeb\xdcX\xbcS\xbe\xb3JSU \xd8ju\xa7%|\xa7%l\xa7E\x0f!1+q\xcfDY\xbc\x14\x173\x82\x1dH`\x1f\x12\x83\x9e\xaf\xb63\xf31V!\xae\xee\xc6D\xab\xb45\n\xa3\xcd\x14\n\xd7\xb5=\x05\xb8\x8c\xfbS\x01\xa1qw\xa6\xad{8\xb9\x8e=\xdcm\x15$\xe4P\xd3\x1a\xfdu{>g{>w\xdb\xe3\xca\"\x8e\xa6\xe5!\x17\x8bC.\xd6\xee\x8b\xc2[\xc5a\xad\x19*\x96\x121\xaeeEhR\x84\x0c\x03\xf7,\xb1\xe5w\xafj\x96\xb5\xd4\xb02\xe8$\xbex\xb1A\x06-vq\xf4\x10\xb6\xbc\x08O\x05\xb5*#(\xb9\xbc\xbdHT]\x84t{[\xec*]\xfdR1\xe5F\x8e -LK}\xf5\xb5\x025I;C\xd5\xa0\xce\xf9\xa2j\x89\xf9v\xf9hh\xd6\xb0\x02\xdd\xb7\x1aQ\xd6\xa1E\xcb\x81\x8b\xc4\x9d\xd1q\x0f\xe0\xd2\x08\x15\x9e\xd3F\xf0R\x81\xf2\xe9\x7f\x01\xcaW\xea\xc8\x17$\xb0\x08!\xe0\xb6\xaa\xa6\x83\x80z\xa0\x14\xc6\xa8\x87\x0e\xcc[4J\xc6\x01#T\x8dC\xc206\xb6KbEK\xc4w\x89\xb1\xf2\xbc\xa4\x9b\xb1M\x9b\x84&\xb6Q2\xe6\xe1\x90\xc5\xd8\xf2\xea\xc0NR\x12~n.\xa8 \xdb\x1a\xc7\x96vy\xffc\xbb\xaf\xb6\xb0F\x82\xa6[l=\x10\xafc\xef\xe1J\xc0\xe3\xf2XmS\x18\xb6oT\x90p\xe3En\x8b\x8dkQ,\xf2\xa0<\xb1\x87\xb5\xafY\xad\xcb\x92\xfdMG\xee\x0c\xefZ\xd0\x805\xbd\xba\x8b]M\xd0\x86\x03\xe8\xbd#+\x12R\x18\x8d{\xb0_\xfe\xe2^\x10\x8aZh\x1bz\xe5=\xfc\x96\xdd\xa1\xd1\x92d\xd0t:^_\x9d)\xd71\xe1|\x08\x1a\x06\xbc\xd2\x8f\xac\xf4\xe3\xca\x85O\xa9\xaa\xf8jFe\xd5\x9a\xc7\x94\x05.\x13\xa9\xec\x1f\x06*#\xca+1{|\xaa\"U\xd2\xba6\xb2\xd7\xa2\xba\xe4\x0e\x0f\xa6\xab3\n\xf5\x91\xa6\xe4\x8c\xa4Y\x177\xed\x16\xb8N\xc9\xc5\xdb\xd9\xd5\xc1\n\x07\xa81\xdc\x19X\xbbY\x84\x19=\xba\x86\xaeJ\x0cm\xed\xf2\xea\xc2\xd4\xeeC\x88\xe1\x91\xb2\xc4\x10;i\"*\xc3\x8d\xeb'ZlUB\xc4Ns\xe9.\xe5tbU\xbb\x11k\xc9f\xc2#\x88%\xc5)Y\xa0X@\xc27\xd6\xd9\x83\xeb\x12?\x1c(l\x05\x9a\xc2H\xe9\x88\x87\xb4\xaaz\x87\x83&f*S=k\xda\xfb\x19}_\n\xfa\xbe\xbcf\xfa\x8e*cI\xde\xf9\x0f\x85\xbas\xed\xee6\xf4\xfa\xfd~y\x97\xc4S\xd8\x06O\x08\x15\xf3B\xcd{\x00=8YW>'+\xcc{\x84I\xe74'\xc1\xf2zO\x029\xdcR\x17 \xdfU\x87\xd28#\x96W:#$\xe7\xe0Q\xd8Q\xfb\xf6\xe1\x96\xd2\x9fq\x7f`\x80\xf4.7\xc8+d\x82\xdf`k\x84:\xf1\xd9\"\xd1\xd8\x1ejCv>wj\x87J\xd1\xa9r\xb8\xa0K\x01\x9e!\xe5\xd3\x80\xdb\n\xf0\x8c)\xef\xfa\xf0hX\xf8\x96.\xa9\xb7\x1b\xc0\xae/\x8e\xa7\xa5@\xeeSB=\xd5* M\x06\xec>\xd1\xdcG\x905\xcf\xae\xe5U\x0e\x9b\xb3\"\xaa\xb2\xb2B\x0d\x85/\x18\x031.\xc3\x1c\xd4r\x07V\x87\x03\xe1Z\x89N\x96\xece\xeeSa\x19((x\xba\x0b\x1b\x93s\x14\x1e\xa1qY\x8d\xd3\x8b\xe1_C5G\xd1w@\xfd\x87\x0c1\x94\x9b\x0f}\xc0\xd7(\xdcR\xdf\xb5\x12\xdcC\xea9\xa5J\x8f\xea%]\x145b\x99\x9a\xffg\xaax\x99\xeb1\x0d\x94UxEG\xd4\x9e(\xb7\xea\xb1\xf2\x96ao\x00o8\xac\xdf\x89\x9c\x19\x14\xd3\xe1\xc0+\x9e\xe8\x1c\x9f3*\x8e\x8d\xb3\x83\xef*Y\x16`\x9fw\xd6 \xc7\xe7a6\x7f\x9aLU\xc8\xc8[:\xe5bT\xaf\nV~\xe8\x08B3\xe3\xf9\x9a\xd6\\M\x11~G\xdccM\xadPji\xa3\xfe5\x1d=\xa5c\xa7/\xb7>\x1b\xc7\x0d\xa6\xc6\xfb\xa2\xea\xc1\xfa(;\x8c\xf3\xa5\x08\xc0Bw8\xdd\x13\xa7\xb1\x98:k\x07\xaf\xfa\xb5p\x98\x8c\x93)\xf9\xb0^\x11@\xd2\x9e\x9dG\xbc\xfeYq\xbf\xad)vM\xc2\x8c\xc0`\xbf\xf5=Ph\x7f?\x8f\xa3/99zf\x9e\xa3\xbc\xb0\xf9\x07\x1d\x9b\x9f&\x13\x0c\x18>\\\x10\xf6\x0f\x9fl\xedf1\x06k\xd3z\xa56\x88-\xa5\xac\x96\xf6=\xfd\xd7l\xb9\xb6\xb7?\xd0@=\xfan\xc2\x07\xbe\xf7?\xe0\xde\xb7\x84\x88\xbc\xa6>\xc3\xfa\x8c\x18=\x1c\xc1\xc1\xd1\xb5\x8aB\x7f\xc8\xfa\xc8C\xfc\x81.\xcfu\x8f\xc1\xde\x9b$\xde!<\x95q\x19H\x98A\x98\x12,\xfa\x86\xd9\xb5\xc9\x14\xc2\x0c>\x93u\xd67\xd5=\x90\xdd\xb3\x0d%\xa2\x8dy9\x89\xd2#$\x80\xa7\xd4\x14W\"/R\xec\x9b}\xd8\xb2\x04x\xb1k\x92\xc4\xb3\xe84w|\xfb<\x8d\xa8\xdb\x9b\x82O\xd7/>\x80\xb9\xa4\x1e\xa8\xe5\x0d+N\xf5\xddH\x86`\x93\x95H\x12\x85\x83\xd7}\xe0\x1b\x1b\xb2\xab\xdb\xd4K\x95\xb5\xdd{\xee\x87\xab\xd5b-\xd8xCD\xbfz]\x06\x162\xc9\xce\xc0\x16\xc8\xb6\x13\xc1\x8aSzI\xf2\x1ax\xff1F\x08\xd1\x042B!\x84\x98\xed\x83\x12rr\x8c\x90\xc4bOXQ\x9f]T\xce\xc1<\xfb\x0e\xf4\xc4z\xeaw:\xed\xa5\xf2\xb5 k\x8caP2\xdah\xf3\x01\xd4\xa0\xc5\xcb)\xb3&y\xfddT\x93\x96\xa5y\x18\xf7@\xa6}G/\xd2\xb7\x06\xde\xbeP\xc7\x10\xce(\xa9\x16\niiG\x03\x05\xbep{\x00\xdf\xf1T\x85\xfd\xc9\x829\xf3Ld\x15\x16\xd6\x97)\xdc\xbdu\x9d\x11\xfcW6_r\x85\xa7\x92\x01\xeau\xb82\xa6<\xfb\xfa\x8d\x96\xc5\xe34IJ\xcd,\xfb\x81\xa2s\x11K\xc3\xf36\xf9:\x93b\xa5\xeb\xacS\xd7\xffP\x93B\xd9\xe7\x94\x11z\x14wh\x1a'\x92\xaf\xa6!%G\xf8\xf22h?c\xcd\xdc\x92}p)Y&g\xed\x92\xb6f\xd6K{\xc3S\xb2 l\x02\xaeM7f\xed:\xe5e\xd7)\xf3N\xea\x0bbO\x1c\xcdE\xc8F\x89\xcb\x03\xe1\n\xe2K\xe3L1\x81\x11\x1d\x8bF\x1d\xc6\xd2D\x0f\xc3h0\xd8\x15\x9d\"E,&Gq\x8b\x8flA\xa2]\x12I\x9c\x898P.\x80-\xcd:\xd1\xbc\xd5\x17\x8f\x91\xbb\\\xf8\xe1\x99\x89\xe2\x99H\x19\x93`\xf0Hk\xc5\xd8\x0c\x86\x10y\xb6\xb2\xdcb\xb92\xbe\\\xc2Y\xb7\x19C\x06F\xa9\xe3\x94z \x03\xb2\xc8\x1b\x9c\x11\x1a@/\x8ay\xb5\xfb\xcfd\xfd3V\x883Cf\x82%\x80-\x1e\xa8\xec\xa5\x99\x98\xf2\x92M\x19\xa9\xd5\x84\xed'\xf3\x07X\xa0\xd4\x9b\x95\x0bhU\x94r\xd6e&f\xcf\x7f-\xd9/\xb1\xdb\xbd \xc3W/)y\x19\xe2\xe3\xd91 `\xa1\xe1\x01\xc4\x9e\x8fc\xd4\xe9\x1a\"\x1eE\xdfi\xd1\x9b\xe0\x9a\xea\x96\xd9\xfa\x0e\x98,Hh-J\xa44\xdet\x8b\xa1\xdc\x1fB\x1c8\xc9yL\xd2\xa3gp BaE\x0c\xe3n\xa0\x9e\x14CQ\xb4S|\x83\xc1\xfb\xc3\xf2\xac\xe0w\xc3\x05\x15\xf5N\xb6\xc4M_pw\xd6\xc9,Iz\xda\xaat\x90\x90\"\x02\xae\xb2ks>\xc0f\x1f\xbfF\xd5\x92c\xb6\xf3\xa4\xe8\x08\xfd\x97\xea|\xd2\xa0\xe9\xc8\xd1\xec\xaeJ\xa0\xec\x86pM\x0fFl\xa9\xd2L\x12 \x84\x03\x07\xad\xaf\xf8\xde \xf0\xf3e8\x90\x7fI\x1d\x0d\x12\xd5}\x88Gj4^\xb3\xa8m\xcb\xf1\x81M>#\x18,\xdbi\x9d#\xd2m\x8dY\x1fN\xeb|%\xd0\x17\xc3J\x88\x87b\x85\xe3\x88\xfe7\xa2\x02\xae\xd6\x81\xfa\xebzQ\"KR\xea\xca\xe7\x1c\x11\xef\x17R\x98\xfd\xdb\xdb\xfda\xdd\x81uT\x1b'\xed\xedWd\xa0\xd6 \x14\xb2\x16[\xa90{\xcdu\x11:\x06@.)\"\x16\xe9\x9f\x87\xd9\x13NO=\x1f\x8f\xa1\xe3c\x12gyJ\xde2z\xedU\x89\xb7d\xa5\xac\x03/zw\xdc\x83\x8d\xf3\xa1zn\xa8\xa3a\xa2\xd8{;\xd8\xc2\xecHjb\xba\xf5\xaf\xf6\xd3\xb22\x05\xc8\xba\xf5 \xce-k\xdb\xdd\x1c\x9c\xa4F\x84\x9c\xc3\x0dw\x99\xa7\x93\x17\xda\xb7:1+\x87{\xe1m\x83r`3\xb3H\x0b\x11\xe1\xc1v\x1e\xc1\x043\x043\xca\xe8l\xee\x01/\xfb\xd4\x02\x01e\xb5[\xf7\x96\x9cI\xc9\xe0\xe8\xb0\x15\x0e\xe0\x9f\xb4dmT\xb6&(\xf3: K\x83\x1c^\xad!%\xf7\x83\xca\xe0\x0c\x04\x83\xa3\x99N\x941\xc9}\x08\xcf5\x9eC\x1fi\x00?\xd0f2\xe0\xd7O~6TO\xfb\xc2\xdeV\x81dR\x0f\xfenN\xfc\x81\xc3oNH$*j\x18\x1f\x8c5>\xac @\x0c\x9d\x9cDt\x89\xe0\x90\x90\x8f\x13\xee\x82\x1c;\xf5\xf9\xcbU\xfa\x9c$yL\xaf\xdc\xe5\xcb\xabt\xf9\x99\xac\x7f\xe4L1i@\xd7\xad\xdb\x17\xd7\xd7\xed\xda\xb9\xd3\x1b\xed\x9d\x1eS^j\xb4\xdc9E\x84M\\\xfa6\x87\x93\xcf\xc8\xbc\x14\x14\xe5'\xea\x89_n\xda\xd0\x1f[S<\xf2\nH\xa6}\xac\x0b\x025!\x0f\xad\xa9,$fGAA}\x10u\xa9FM\xd1\xd4Q\xf8X\xe4\x0c9\x84\x08w\x9bN_a\xc0G\x11%^\xe8\x97\xf8\x82\x06\x10Zy\x15&Qq\x89\xcd\xd3~\xba\xcf\x10Q\xac'e\xfc\xc8\x85\x17\xfa\x01\\x\x0cU\x18\xc4_\xc8\x1c\xae#\xf6\x99k:wB\xec;\xbeVy6\xf74\x9eEF\xf2\x92K\xa0En@\x8e\xac@.v=zm\x95j\x95\x9b7\x01\xb3\xb0V\xd4+<'c\x91\xd8\x97o\x7f7\xce<\xb1\xef\xeeR\x9433\x15\x002\\\x0cu\xf8Ue\x1a\x8e\xb7\x92\x8c\xba\xf2\x9c\xab\x84\xcc\x9ax<\xb9\x8a\xce\xadjx\x9e\x8d2\xf2\x85\x1e>jY9\x13@r\x97e\xe1\xdb\x1c-Cq\x7f\x16\xb1\x93\xc1\x01\xfd\x8a\x8f\xcb\xc4\xb9\xcdA\xfa\xbeb\xedb\x07\xb2\x9af\x17\xe9jy\x8am\x18\xa9\xc0\x94\x87\xca7W7\xb5\xa7\"\x1a\xaa\xf8\xc4\xb6\xe2\x80&pq\x1e\xa5U\xabi\xab\xf7pE\xfe^\x8a\x1a\xa3\x08x\xec\xd2\xf8\xad\xc6e\x02o\xabA0\xa6\xa5\x93\x17\x95n\x19\x86\xf4\xb1\x97\xd5z\xd2\x05A\xc3\xb2\xd2\xf1(\x1a\x17\x0e!\x9a\x81bf\xf2\xca\xd1\xe7\xc5\xa3]G\x89#l9iA\x84\x86x\xf7\xef\xde\x7f\xf0\xe0\xf6\x9d\xbb\x0fx,\xcf\xce\x10\x03ax\x1c\xcc\x9d\xdb\x83{w\xef~\x7f\xef\xae\xef3f\x0f\x1f\xec\xc1M(\xbeQ\xee\xdfa'\xd3\xde\xdd\xbd{w\xee\x0en\xdf\x0d\x80\xc2\xb6h\xea~\x00\x83\xbd\xefy\xf3\xf2\xde\xe0\x9e\xdb42\xe2(\x85\xa4\x02\xc5\x0fm\x15E\xa3\x11\x19\x0b\x01\xa3\xd6\xbb\xfa\xeb\x0b\xba\xba\x08\xde\xec\x0b\x15\xe6p\x18\xb2\xbf\xb9\x15.(\xffD\x9dz\xf1\xd2Q\x1c\xc0\xef-N\x11\xe6\xb9T\x0eCUz\x17\xc7\"g.\xa2\xf2X\x84G\x90\xf3\xd3\xd1HH\xa7\x88\x9e\xd1(\x193\xd4)s-\xb2\x1b\x03\xe7R\xe6\xb5Y\x19\xcd\xf0*\x1fi\x9d!\x16\x1b\xe1;6\xc0\xd3\xb9:\xdd \x9f\xee\x0c\xcfc9\xdd <\x02\x8cm\xda\x9abB\xe0l4\xc1I=\x84\xc9\xf6\xb6\x81![\xc0\x90\x7f\xa7\x17\xc8\x16p\xc0\x9b\x19\x8cq0\x11\xec3\xeeWQN\xea\xbf\xe3|\xb0\x17\xa2g\xd4\x02]\xc9.\xbc\x84IQaIH\xb3\x96\xec8\x18\xc4\x81\x0e~[!\xfb\x7f\xe1\x9a\xf0x\x08\x13]\x98\x8a\x15y\xe4\xc5\xa5Z\xe9\xb1\xf8\xdebp\xaf\xa0\x9b\xe0\xfah\x00\xe8\x88\x1a\xc0\x88u4\xf6+\x1c\x19q\xe1\xc8\xe4%\x9d\x0d\xc8\xc8\x94\x00O^\x11b\xb5 \xff\xb4\"\xa2\xe6\xa8h\xc9\x8d\xd5?@\xcbE\xc9K\"\xbb\x9e6\xb3\xae2\xabQ\x9eMa\x05\":LQ\xf0J9\xd3\xd81\x93\xf7V\x0c\xb7\x90\"em6\xff\x03\xe4\xaf'\xc2\xf6\xbf\x03\x038\x80y\x7f\x95\xf0J\x10\xf3\xd1\x84Q\xa3\xc6\x8d\x11\x1b9\xe3\xc7\xe7\x9c\xc1\xe4\xbf\xfd\x00{\xf6j\xda\xbfyi\n\x97\x02s\x00\xf36\x96\xf42\x80_\xafL\xce\xb4\xd1e\x88]\x86\xcd\x8aB=\x13W<\xafZ?\x9cG~R\x94}\x0c\x9a\x91D\xd2\x10\xae\xe95\x126\xd60\x93snr\xee\xae\x08\xcdF\xe5\xec($\xfc\x11fF\x1e\xf38..#\x11\x1d;Q\x07\xcf\x95\xe9b%3\xb4L\x00\xfd\x84z\xa9 T\x8a\x80H\x04\xcb\x13#\x90\x88E\xaa\xcc$|C\xfd\xf3I\x15\x86\xfa\x97f\x18S\xb95\x04o\x027A\x87\xdaH\xd7\x90PGue\x8e\x96\xa0J:\x1d\x12\xde$\x02_\xdf\xf9J\x8e\x10\x97K\xff\x0e\x1a\xdd\xe1\x00V\xa3\xc5\x18Z\n\xb1sE\xd9\x9c\x9b\xc5\xf8BW\xd7J?;\x1e%>w8(8\x1c0\x94|\xa5\x90\xf7\x99\x95\xbc[\xdc\xbc*\x15\xbf\x04C\xc0\xf63\xaf7\xb3\xf6\x03\xc4\x8c\xdd\x87\x82\xd5\x8f\x1fB\x88i~\x18n\x0ca\xe0C>\n\xc7\x88\x067Q\xb3@F\xc9\xf6\xf6\xd8R\xb3\x0e\x14\xa1t\x94\x8e\xb9\x8a\x8b\xf5\xc8M\"\x98\xe3A\x1f\xcc\xcf\x1e\xaf\x02\x98\x04\x10\x0605@R\x9c\xe7\xec\xffj\xb9z\xb5H\x7f\x93*\x11\xb4x\xb2\x04\xb6\"\x12\x0df\x81c\\\xeaWxS^q\x0eRQp.W\x88?{k\xe03V4\x1fc\x9ck\x0e\xdb\xc6\xd4\xb8\xd0~xs\xa8iA\xd6\xc2!\x15\x1c\xb6\x84\x9a1M \x14\nu\x84\xda\xb6@\xaa\xa8\x84\\!P\xb8\x80.\xa9\x80\x8e\xab\xd6\x10tb\xcf\x86\xf0\x08\"\xdc\xb1>\xbb%h\xbb\x97\xf0-\x1b\xf3\xd7w\x06\xa8\x9d\xe5\xf7\xe8(\x84m\x97rn\x86\xc2\x1f*\xee\x19\x8f\xcc\xe3\x82\x9d(\xac\xa8'5\x93\xe6y\x95\xbb\xe0&\xda\x93\x00\xce\x1b\xe7\xe5/\x7f-;aa$Z\xf8\x08\xce\x10Df\x11)\x81\x03Ht,\x82\xceo\xf2\x97\xffel\x82\x94\xcd\xb4/L\x1cNa\xc6&LF\xa1\x81Lg<\xf8\xc6\x911\xa0\xc4\x9bu=\xa2\x85#\xadC\x0f\x05O\x81\xf6z\xc3\xb1\xd2.\xc3\xed\xec\xac\xe0\x11,\xae,\xb7U\x08\xecn\xa0?\xe0cy\xc0s\xa1y\xc0%\xe5R,c\x14d\"\xce\xfc\x0c\x1e=\xc2#\xbf]L\x9b\xa1\x98\xa6[\xac\xca\x9beT0\x1e\xb3!\xfe\x89\xb4\xd1\x8b`3d\xc2T\xce\xf9 \x06yc[\xad\xf2ZIB\"-k\x01\x92\xbd\x98 \x87\x11\x1a\xcd\x8c\xab\xedm\xfd\x9a\xcf\xbb\x9e\xf2\x8cS\xcc\x88\xc7\x99\x99\x05\x93\x9c\x8cta^\x90K\xe9\x00\xb2\xaaQ\xcbi\x95ZrNj\xc5\x98\xa4:\xd9xyej\xf9\xdf\xacKz\xf9\x9f#\x86\x82\xae\xe9wy\\\xe6Z\x14\x86\xbab\x8e\xa1\x92\xc0\x8f+\x7f\xb8\xbe'&\x8a_\x1d\x0eZH\xe1\x9a1\x14K\xf2\xff }WXr\xee\xb3\x8a\xd5\xf4E\x99\x97P\xc0\x92M\x80\xb1\xee\x13\x93\xf1\xb4\xb3\xa6\xa5]\xcb\xf2\x1f\xd4\xb0\xbc\xd4\x00`\xde\xd8\xe0/\xae\xbc\xc1\xa5\x18\xc3\xa3B\x0b\x9f+\x86 2\xa2\x8e\xdf\x18\x8cu\x0c\xc9\x8b\xeb\xd9\x835U\xaev\x99\x90\xe4!\x06W\x87i\\./\xc3\xea\x19\x05\x12(\xf3\x08\xfd\xc6F\x0ce\xc0\n\xc3H\xd8\x87\x0c-\x01Z4\xaa\xac\x1a\xb68,\xca\x10\x89e\xd3\xe1\xadXv\xde\xa5f\xd7#\xd1)w~c\x91+\xba\xf3\xd2\xb9\xf6\xa5\xfeve\x0d\xac\xa4=n\xd0\x91\x94\xd3\x91\xa8V\xb6\xe8!\xa4\xa2\x84L\xea\x94\"9.\xea\x97\xa0\xe7\xc1X\xadwY\x9f\xdc\xaf\xfaY\xfcrm\x93\xe3L\xa6\xdb\xd4\x0c\xbcN!|\xd5\xe6\xa5\xe7w\x18(\x12(\xb3\xcf$\xfdJ9\x06\x13,@\xa7=}qE0H\x8a\xac\xa0k\x03\xad\x88w\x83\x06\xf0\xd5\x0f\xe0\x86\xdaKL.ZS;\x14P\xa6\x12\xca\xe8_\x19\x94A\x02\xdc\x99\xf2!\xd8\x8b6\x88\xfa\x13\x04\x17\xc9\xac\x0e\xc7\xd4\x98<\x0b\xaa\x8e#\x03)f\x8b\x89Z8\xd6\xa8\xa8\xadZ\n\xe1\xdcg3\xd5AI^\x97en\x9bT\xee\x96\xb6n\xb0\xbe\x99\xa8b!>Q\xf0\xce\xd7v\x1f\x91l\xc4\xc1'\xddS\x0f\xb0\xcc\x1e\xafy\xd6:6\xb5KD\xfbj\x87v\x95FR~f\x19\x83]\xd1\x91\xb4I\x0b\xf8\x92\\\xa6\n\x00\xe4]\xbb\x0cQ\xc3/\x18\xc2O\xd4K\x8c\xf6s\xb0\x8a\x0b\x93$\xa6Q\xdc\xa9\xf8C\xb3\x7f\xe5W\x9f\xfb\xcc\xb6\xecj(\xb7\xa7ic\xb4\xe6J5\xe6I\xad\x11\x90*0\xd9*c\x1e\xea5\xdc\x82;\xcd\x96g\xf2\xd9^\xf3\xd9\xa2\xf8\xce\xe4\xb9\xbf2x\x0c\x9c\x89\xd8\xa1\x0bc~=\x87<\x96\x9a\x88Z\xf6\xe5\x9cxJ\xcaI\x8d\xf0-O\x82\xc8\xa3\x96\x0c\xa3\xb1\xbd\xc6\x03\x1fL*t@\xde3~\\\xa7\xf0\x98g\x8dN\xe1\x11\xac\xe1\x00\xce\x89\xb7\x8b\x0c\xcfY \xe2L\xb1\x10\x04\xf1\xe2>M\xb8\xfc\xedcYZ\xd2\xd9-\x06\xfdD\xdeG_ \xf6\xacI\x03\xd2\xa6\xe9-4\xb5-\xfe&:/\x127O\x8b\xb9\xddaD\xc9\x032%-y@\xd8ArN\x19\x9bL\x1c\xf2\x80(\xc2\x87g\x8e\xb1\xe49\xbc\xc4\x11\xf7\xad9-^E\x19\x85Q/\x80\xde\xb8\x99\xd4\xa2\xd2\x93cR\x8bH\xd6\x8a/\x93\xe2\xfbEVrZ\xcdJn9M\x99\x00[\xb0\x96\xe8+\x83#O\xd2\xe842y\xb6I\x99\x8b\xf5\x14\xf7y\x99P\n7\xe1T\x13\ni\x02P#\xbbF\x05\x06\xdd\xb2k\xb8\xda/\x10d\x84\x83\x8c\xb3U\x95\xaa\xf9&\xbfo\xf4\x0d|\xac:\xb1\x11x\xa4d\x83\xed\xee\xb2\x06x,<\x82]8\x80\xb7\x82\xc7\xc3m\xb6+\"L\xdfJ\xa7\x04\xb4\x00\xf0gD\x1b]\x06`N\xb0Gp=\xe5b\xea\xdf)\xed9\xc74\x8c\x16v\x86J\xba\xf7\x1b_J\xac\x81\x02\x08\xc5\xcf\x18%0 W\xe1$\xa2kn\x10\x1f\xc2{t\xc2\xabG\x0dpy\x10E\xac\x88\xbf\x14\xd5^\xa2\xfd\xe3\x059#\x8b\xf2]\xf3\"n%\x8e\xe1\x06Q\xfa\xd0Z\xee\x00\xf8\xd8\xd6\xba\xd0\x13\x8e\xc6\xec$\xd3w\x13 \xbf\x0b\xae\x8a\xd4\xf7\"\xaa^\x98)y\x0e\xea(F6\x03\x16\x16\xa9\xcf\x19\xdd\xca+`F\xd8\xc2\x0e\xea8}\x1fG\x83o%\x15P5\xa9\xb2v\xc0\xdcJ\x169@9\x84!\x1c\x96\xb9\xb3\xf4\xf3\xdfJ\xf4*\x95\x8a\xe3\xc4\xeeC\xc8\xb8\x8bi\x86~\x92\x02\x16\xd9\xb8\x10\xbf\x8c\x049B7\x91\xb0\x80\x1e\xa3\xf1~\x00a\x9d\x82ip\xf4\xc9\x8c\x92\xc6\xf1\xde\x8a\xa2^\x15G1\xc8\xf8\x1b0UX?Q\xa8oA\xd8\xc8\x8e\xb0\xfaN\x9cp0\xa9\xe2\xa0\xc9\xa2\x848\x98b\xb2L\x86]*\x185(\x88/Ez\xc8\xa0\xf1\xab#r\xca\xcdbE9\xd1d.z\x13\xca\x8a\x08\x95|\x81\xf0k\xcb\x8bi2&\xca\x0f \xaf\"K\xf3x;%\x01,I\xc0\x98\x06[\x1a\xf5\x13\xf3iU\xf2\xea\xf2\x10\xd7BX(\n\x8b\x93]\xbf\x0c\x80J\xbe\xd4\x165\xc3\x0f}3|*\x89D\x04\xe3\xb0\xeb\xd7&\x06\x95\xb8g6\xb70\x00\xa3\x8d\xb5\xa2\xc7 +\xe5\xac\x0c\x9e&\xf2\x92\xc4$\x17\xfeK\x07\x12\xc1\xf8\xf1\xbe/\xa3\xdc\xf1\xa7\x99G\x05\xe1\x97\x92\x8b\xca\x87\xbb\xe8\x19\xbb\x03\xb9\xfd\x93 F\x9a\xee@n\xe0\x1b\xf1\x95\xc7\xb0F\xdca/\xdb\xec\xa1\x02\x08\xad<\xbc\xbc\"t\x9ce\xd3\x9e\x14\xfb\xe1\xd8Rt\x04\x14\xb5\x04V{\xdc\x99\xc0>\xa3\x9a\xf6OD\xcb\xe8\xd9\x15\x8e\xa8>W\nh\xb7\x1d\x80\x0c\xab\xab\xbb\xe5G\xa89nYV\x11 \xea\xbc\x80\x13$/\xd5\x05L\xe0\xf1c\x88\xec\xdf\xcd0\x00f\x9b\x1d\xeb\xf2\x03\xcb2\xcd\x8a\x05\x9d]\xf3\x82\xe2\xb9\xf6\xd0\xe8`\xa1^l\xed\xb5\x19]tW\xa1\x8b2 }\xf5+\x12E\xf6\x98\xa8\xd3\xa6\x90\xaf_\xa1P\x85\xb6\xbel\xb6\xe3\xcb\x8b\x0dcR\xf3%lCpP\x08&G\xf2\x19\xec\xc3\xa4\x0d\xc9A\x8c<\xe7\xae\xe8\x19f\xde\x8f\xf8\xa1\x940\xd4\x88\xd9\xa9\x1d\xf9f\xb7\x04\xb0N\xc9\xb27\x90.6\x1e\xbb%\x948\xd7&\xfb1\x1d\"a#;\xd7\x99E\xa3\x10J59;\x9b\xd98UU9\xfeTT\xe5\x04oH=y\x8c\xbf\xca\xacGa\xa1$\x8f\xf0\x87\"5&\xfc\x86\xd0\x97\xe7\xfcW5\xb9W\xe8\x04\x8a\x0bb\xd3\xa8\x9d\xa2i\xd0C\xc5\"\xb7\xeb3\xf1\xcd\xd1\x14\xfe\xbe e\x13\x88s\xee\x8f/\x92\xf3\xd8c*(w\x9a\x7f$\x89\x9bT\xcc6>@^\x18\xf1R\xf1\xa5\x88l\x1b\x93\xb3\x9c-\x9c\xdb\xa4F\\G\xa1%c\xce\x8c\x9b\xf8&\x1c\x0e|cHXX5I3~B\xc9\xbcQ\x9ed\xc3\xd0\xc6[t\xccXi}\xd8\xa0iE\xb3\xea\xc8\x8b\xe3\x9f\x96n\x99jWA\x05v\x1c\xf2(\xec4xK8(nJ\x13Y\xae\x8e\xb3\x19\x83`\xc2\x9bC3OW\xa8\xd9\xd0\x1f\xa0\x88\xc1\xa3\x8ag*\x15\x1e\xa8k\xe2\xf1\xfc\\\x82-E\xae\x94\x8d\x8a\x89\x97\x8d\x02P\xfa\x91<1\x8f\xa4\xb0\xa0\xd7l\xbf\xaaeU\xcf\x0f\xf2/\x1fq\x81F\xb2\x82\xb0\x0dg&\xa4\xab\xfarJ&R\xf0\xad\xf8\xf5C\xee\xb7\x80\xae8XXuX\xf80\xf0P\xad\x14=\x19\xd8G;C8\xb3\"^[\x99wcE/k\x92\x1e%\xe8EF\x9d\xf1r\xc7\xea\x13\x19\x7f`(o\xac\x98\xf5\xd5t;\x98\x9f\xc1\xcc\xb6\xb7\xb0\xff\x89\x0b\xfb\x8f1\x1e\xb0m*\xce\x10\x1623bc\x8c\xdc\xf4>\x9a\x8dv\xf1\xefm\x0c\x19c-h<\x16\x18>\xe4\xf5\xfd\x95\xb4\x91\xa9\x9c\xe1\x9e\x12s\xc0\x0d\xbf:N\xa5\x1a/Q\x88\x1e\x13\x15\x99f2\xe8t\x1bfl\xd4\x0f}|.\xf6\xd1\x84\x8dkR\xdd\xf1\x070\x92\xc6\xa3\xc9X\xec*&\xd8\xcd`[f\x1f\xc8\xd8\x9fg\xba\x11q\x99\x90=\x9e\x05\xbc\x8c\xfa\x8c\x1d\x00\xfc\xdf\x04\xff\xb5Md\xc1\xa5\xb1\x04#\x08\xf0\xcf\xd0\x7f\x08+\x06\x11\xec9c\xbb\xc9i\n\x95\xa1\xf3\xf1\xea\xf1n\xde\xe6N2\xc5 \x8aG\x18#\xc1\xc9F\xc8%\xee}60\xbc\xad\xa8\xb70\xba\xd1pda\x905\xff\xe6\xe6M\x8c\x03F\xd1l^SA\xb4\xd0\x8a5F\xb0 !\x9f\xf0\xe9-a\x08\xd9CX\xc2c8c\xff0J\xd0&K\x1c\xc3\x10\x16HA\x96z%\x89\xbcXwkAr\x8e\xc7\xbc\xdf\xf2\xb71\x81\x94\x9e\xbf\x93\x1f\xf2\x9e\xcf\x90v\xc1\x10\xe6-\x94 $\x83/A\xe6\xb1E\xc1(\xf6iEq\x92\"\x1b\x13\xfax\xd6=\x1e\xc2\xca\x87\x9c\x81c\x85\x8b\x86\xfff\xdcmaR8(4\x9a\x12z@\xde\x96.|\xb2pGf\xc2q\xc4(\x15\xe2\x87u\xe5\xc4>\x9cX\x85\x19\xb60'\\\xe8~\xfc\x98\x1d\xe8\xb6\x85a\x038A\xea\xba*_\xf7\xe1$%\xe1g\xf3W'BP\xdb\x1e\x82\xc7\xb7\x94\x0f\xdf\xc1 n\x92\x9d\x022b?\x8dN\xf4\xc2\xad~q'\x1c\xab\x1f\x0b5\"o\xa7\x0e\xd2\x8c\xad\xcc\x0e\xcc\xd8\x12M\xf8~x\xc4\xf7C\xe5\x83b93F \xc4\xfb\x92\xba\xec\x08\xaa\xb2\xa3\x8d\xa2\xec\x9c\x924D\xb5Fy\x9cp\xb6\x9bV\xd8\xf9\xb0\xd4\xed\x00\xc6q\x96\xeeU\x13\xd5\xbdj\xea\xea^\xc5\xc8\xc49\xf1r.\xee`\xa4f=\xba\xd1p\x1c\xff\xe1\x96/2U\xf3EV\"\xe8\xcb,k\xa1=\"\x04\x93b[\x99\xe0 Z\x01M\xe9{&\x1c\xc2\x8f\xc5\x9eMp}E\xa5\xbf\xdc\xcbxJI\xbe\xea\xd7\x9dR2\xe5\xf1h\x93\x0e\xe8\x91\xc0c\xe94y\xf3&O\x10Uz%'HR$\xe4\xebYn\x0c+\xf5\xb9-\xc5\x1cw\xab\xdeE\xa5\x9c\xd4Y\x9f\xb1My\xe6\xd4\xfe\x91\xbd}k\xa1\xc7\xa7\x9ce~M\xca\xfa\x8e\xecVg\xbf\x9b\xb3\xff\xf5\xf5\x1d_\xdb\xa1X\x94\xc2\x9c\xd5\x11\xce\xd4\xe0\x07\xd7\x94|U\xd5\xc3\x91bT1+!\xca\x14\xe1(\x02\xe1\x8f}\xb4\xdb\xf7\x8fy\xea \x9e;|\xc1\xed\xcb\x0e\xb9\xc3\x9d\xe6\xf4\xd4\xaaLXre\xc2\x92\x8d\xeb\x03\xf1xu\x9b\x0b\xe25B\xfd\x0c\xad\xffl\x970\x84i'\x90,\xbd1\xf5R.\xf8\xe0(3x\xfdb=6LIA\x0c\n\xff\xac\xe4\xf8\xd9\xd1\x1a\x9aT C\x9e\xb7I\x8f\xb7\\?\xd1\xa6(\xcc\x05y\x1cr\xedi\xf9s\x0f\xbe\x83D:n\xa2\x8d\x88\x1b+\x9b\xc9O\x0d\"\xac\xbcD\xff\xca|\x84\x8a\x05\xa55\xc3>\xf2\xfb4yI\xd6d\xfa\x9e|\xf1\xfc\xee\x94\x99\x8ev\x0d\\\x83\xdf\x9f-\xa2\x95\xc7:x\x1d\xf2|:\nn2\xa2\x9bVp\xb5\x8a\xb9\xaa\x933:\\\xa0\xf1L\x96}c\xd4%\xc2\xc3\x9c+1\x14\xe7\xde\\Q[0\"\x12J\xd1T\xa3\xbcTb\xcd\x8c\xb6\x99\x12\x01rD\xa5\xd0\x1f\x0d\xc6m\x8b\x9dr\xd5\x1e_G1\n\x9ej\xdd8\x08>?\xe1L\x9fK\x12Z\xb6\x90\x8bB)\xa2\x19#\xc90\xf1=\xa9,\xb4\")\x07\xf7\x0d\x17\x94#\xd2s2\x0c\x8c\x1f\x90\x93s\xcc\xbc\xfc\xae\xc5\xeb\x04\xdd\x95\x14\xaf\x93\xe3<#/\xc9:SJYH\x8a\xd7L\xe2k\xea\xf4\x8d\x81\xa6k{\xec\xde\xfc\xab?\xb7\xf9g\x7fn\xf3_[\xe2\xd8\xfeAl)b\x89:\x02R\xed\x9e\xdd`[\xbc\xcd\xabSi\x8e6\xb1?\xc0b\x8e\xb2xIkCgE\x99d\xf1\x91\xac\x7f\x86\xdeg\xb6\xbe\xdd\x07\x0b\xean\x12\xddx\x06F$\xd0U\x14as\x9a\x87Y\xab\x1b*\xa8\x1dE\xf1d\x91OIV\xafj_\xb4(_\xe8\xd6\xec<4\xb78 's\xf2\x8ed\xf9\x02\xf9\xdf8\x00\xc5\xa3\xf0c\x8c\x8f+e\xbbl\x11L\x85ZO\xebL\x01U\n\xd5\xa8g\xe5\xc8\x18\n\xafC\xf4\xb5\xa7fu\x84\xb1\xd8\x95\xe2\x9d\xdau~\\\xdf\xcb\x0e\x82wmR\xbd\xd4n\xca\xaex\xbbf1]\xb2\xf0nN\xac\xf2\x92v\xcd\xd4Z\xbeV^\xc8\xa5\xd0\xd6:\xb6\xf2*\xf7\x19\xba\xb9\x8ev[\xb2!\x01\x86u\xcaw\x95\x0f\x07\xe3@\xf9\xbb\xe1^X\xbf\xecfQ#\x19\x91\x97)\x8b\xb9\x1b>\xb2\x95\xc2\x15\xfe\x99\xc9L\xb0\x0f?\x1b\x11\xa9r\xd3D{\x9f\xb7s\xba\xad\x148\xad\x13\xdd\xb4;i1\xd3\x80\xb4\x1e\xd2\xe9RT\x99\x97%O\xcd\x85~\x0b\x19{(r\xd0G\x18&\x8c\xbe\xf6\xbc\xc4N\xaa\x15\xedp@V\x02\xe44\xbc\xab\x12\xa0\xa8\xc5\xd9\xa6J\x83R\xaf\x9c\x91\xfcXX\x04MD)j\x99\xb2\x9e(9\xcdY\xc5\xe1w\xe6\x14\xce\xdd)\x8d\x14_\x93V*\x83\x8ev\x82\xc0H\xf9\xd5\xfc\xf6\x99\xf0I\x8b8m\xb0\xbb\xa8\xa0o\x82\x95\x06I\xf9\x9dA+\x0c\x14d\xcb\x91\x02\x85\x0c\xdf\xb4\x0b\x00\x06uB\xa3*\xa2a\x8f\x7fl\xf7\\\xb3o\xf0Xe\xb1\xe2\xfan\x8f\xbb0G6.\x8br\xf6\x07-s\xce\x9c\x90<\x05\xbe\xeag\x00*w\xd5a\x9c\xa0\xeeE.%\x9a\xb6\x8c\xae\x8c\x07\x83J\x8dl\xd9\xd2 \x16=\xa1&@\xe4}\xdc\x19\xc0\x8e&\x855\x08\xee\xa1Nc\x8d\\A\x95\xc6V\x1a7\xb4|56\xae\x85;\x8c5\xbc\\\xac\x8f\x0e\xf9\x8f\xf3p-\xc5H.\x03\xd82\xc1N\x1f[d\x9b\x91\xf6\x8c7\xf7\xe0\xb4\xe5\x7fpU\xf9\xb5\x9c\xec\xb8\x19\xa3:\xaa\x19\xf1\xf8\xacH\xd4\xebv\xfcFxL-Y/[[%A\x8c,\xa7o\xf4\xe7\xb2\x03\xc5x\x9a\xbc\x80\xb0\xb5kJ\x0b\xf9\\\x87ia\nl\xde\x94gJ\x9c\x80\xf9\x8c \xf5Uy\xa1\x1d\xe1\x13\x8b[/H\xa9A\xe5\x13\xf0\x832\x91\xe2\xf6v\x00\x91\x87~ \x1c\x02hn6\xe7\xf9dS\xad\xfb\x84\x81\\<;\x1f\xe1\x04\xa6\x1a\x1f\x91X*/\xb6\x03\xad\x03\x9b\xe1\xe8\xfc)q.o\xe5F@\x06eT9\x92\xc4\xfe\x854\x84%.\\ \x08\x9bX6\xda\xb5X\xcd\xe4\x85\xd9,\xb5\x89A\xd5\xab\x8a/34\x15*9\x81\x9ecED\x91[\x1d\x91gfd8\xc1(\xf8\xe8\xf9\x1d7\xdb\xc0\x17W\xe2G\x0d\x11\xa7l\x86\x9d\xdc\x88\x98\x101\x80[\xe8\x83\x83\x81\x88\xe8\x93#\xde\xff,*\x98E\xady\x93\x18\xda\x1c\xf1:ff{\xc2k\xa4\x90\x86\x80\x1cF\xc0 \x81\xcd\x06r\xf6W^\xf4\xc8`\xd2\xa7 W\xa1+\x07\xb1\xe7\x97\x90\xd2\x0fJ8y\xe7\xb0\xa3\xc3\xcc\x0c\x86C\xee\xe9\xe7\xb1\xcd\x96 G\xa4]\xd8\xd7V\x9a8\x13^\x8d\xf6cg\"Y\xcc2\xdc \xc4\xcaZ\xd2\x18\x1a\x96\x06\xc4\x00\xb6\xf0\x94\x8a\xa4Y,,\xd2\xf8x\x93\xfaY\xe1p\x0c\xcb\x0c7\"\xdc\xb4L\nDDQE\xc9\xa4m3:\x89\xe9f4~l~\x00\x93o\xd3SEV\x1e'*\xb2\xea\x95\x8eY\x06B\x87\xd6\x81J8Nu\xfd\x95S\xc3\xa2\x03\x92\xd4\xd7\x12E\x9cqW\x02\xe3\xf3I+1\xbe\x12\xcb&|o7\x1b\xd8\xc2r\x90\xf9\xf66<\x82\xa4\xdcl\x13F\x83\n\xad\x9c8\xc7b,\xf8\x80\xe7X\x84h3\xe1\xe65\x031\n`\xa2\xa3G\x93oT\xd6 \x9b\x1e\xeb\xdfi\x89\xecz:\x896J\xabM\x15\x9fy}\x1c\x96\xf7\x9a\xcfR\xb9V\x0f}\x88ZOK\x06\xaf\xed\xed\x0c\x1e+(\xdfv\x12;E\xbfC[\x04<\xbb.\xedj\x024P\xb5N\xa1\xe0\xaa1 \x96\xd4\xe2Q\x0c\xb0'\x01\xaf\xa3\x13\x88'Oe\x92\\\xf4\xc6P5\x95]\x14\x04U\xac5\x1d\x98\xbf\xbb\x1e\x98v\xb2}M<\xb0\x99\x8c%.{\x84x\x16\x97\xf73\x11da\xa3S\xed\x88n\xe1\xb4'\xad\xa4\x8a\xa7\xe4\xc6\xd3\xb2\xceuO\xfc\x92je\x0d\xb6;\xb3\xb3\xdd~\x00\x9a@\xcbk\xe2\xb9\xbf}Y\x92\xd4e]\xba0\xf7\xdf~\xdet X\xb8\xc9q\x914\x89\xda\xe55MZ(R$\xb3\x0e\x86\x82V\xf8U\xd6\x1f)CT\xa3\x0cQ\xc0\x8f\xb0\xa8\x8d.\xb4\xcb\x0d\x8b\xd2\xeaa\x7f\x99q\xa2\x0b\xac\xe47\xc3\xbfX\x07\x9c\xcb\xcb*x;\x13\xf1L\x16\xf6\x1e\xce\xe7\xd1\x82\x80\xd1)\x0fTu\x00\xda\xae\xd4\x99'\xd8G'\x9a\xe7&$\xfcz-\x86\x8fo\xb6\x04X\xf0\x17\xe9\x94\xa1\xce\x91\x18@1\x1b\xeae-\xb4\xe7LT\x0d1oeve:\xca\x16\xb5(\x10@\xe1\x9e\xb7\xd0\xf3j\x02\x8f\xb0`\xcdM\xc8=\xac\xda\x87e\xf2'\x18\xa8\x0d\xfb2M7R\x84X\x94\x03HPR\xf4\x0bIbk\x17\x8bs\x9a\xf1\xca\xac*g\x0b\xcb\xben\x96P\xfa3L\x19\xa9Y\\\x03\xb1\x8a\xa3\x96B\xe7\xd7F\xa5\x04[\x958))\xa8\x93\xc9\x04\xe4\xb9%R\xcdw2\xcfN\\\xe9\x0d\x88^RA\x01\n\xf7\xeb\xd1`\xcc$T\xd4\x10z\xa1\x8c\xa7@\xecb\xc7h\xeeM\xca#3.\x08G\x1a\xf0\xf3s\xd2N\x16\xd9\x15r\xe7\xdcD\x94F\x9b4\x96\xd7\xda\x82\xf0\x8eJ\x90\xac\xa3g\x97\x19i\xdb(`\xdb\xaa]#C\xdb\x81\xa2\xba\x99\x99~\xb1RT\xee\x91\x89\xd1\xaa:\xf9E\x12\xdc\xd0\x986:2SK\xbe'\xa5v\xa3\xe2 HZ\x8a8 \xb8\x8fR\x1cy\xc4K/\x1e\x00\xffP\xb8\x97\x11\xa3\xfb`\x91e\xdaxD$\xfd,I\xa9\x9b4+>!\x1e\x1d\xdd\x1e\x07\x10\x8fn\x8f\x11\xcb\xe9ho\x0c;\x10\x8f\xf64\x19\x82\xfd\xb2 y-+\x83q\x97\x96;i\x08{\xcd6\xeb\x15\xfal\x0d1\xd0\x8f\x06\xba\x81q\xce\xf5\x85\xa8\xf1\xc1\xdd\xbao\xf0_?z5\x85\xa0 \xa7^Zq\x8a\xfb\xbb(x\xe5b7\xfa6\xed\x82,u\xe0\xdcRG\xe0\xcaK\x02\x99\xad\x0f;\x99\xe0w\x0fC\xd8K\x9fK\x86\xef\x96\x03\xff\xea\xfa6\x07\xf6\xbf\x03g\x88\xab\xd9*\x80\xa1n\x02\x973\xb9\"\xa0\x04\x16\xd8\x00\xc2\x13\x90\xf4\xb3dI\xae\xd2\x01C/K\xf3\xa2\xbe\xd4_\xc8H\xc9\xfc\x989\xe6\xc7\x14\xce\xbe\xa2\x1c\xc5U\xa1\x88\x03\xb4\xcd\xf2\xfa\x05\xe2\x1f[s!p\x13\x0b\xaf\xc9A\xfb\x93$\xceh\x9aOP\xb3\xecF\xdf\x7f28zGE6\x1b\x1e\x81\x84%F\xe8(6j\x0d\x810\x01\xc9\xcd\x818mI\x9c\xcc9\x88\x82\x04Zs\x8aq\x0bv\x14g4\x8c'$\x99)\x15\xcf-N\x11\x089D\x8f\xea\xa7\x95d\x9f\xa9gR=\x17MX9tv\xc5\xa8\x96j\xd7\xb2\xe6e(\xe5g\xb2\xce\x8c~\x89\xf2\xdar\xe3\xca\xd4\x8b\xa6k\x87\xb7\xd8E\xb4\x11\xaeN\x9d\xc8K\xcceJfQL~N\x93\x15I\xe9Zp\xbe\xee\xad\xb0\xeb\x94PE\xb4\xec2\x06y\xa9$\x88\x87Mvj\xe2\xb2\xdd F\xbd\xb2\xcax[\x8fo\xdduJk\x89\x98\x03\xe8=\x0d\xe38\xa1\xacuHb\x08c\x88\x8a\xf4\xbc)\x99$\xe9\xb4\xdf+H&\x8f\xb6\xb3\xb0\x98\xba\xab=s\x9b\xbc\x0c\xd1\x08\xf5\xeb\xb2\x7f\x12\xc5S\xaf\x8c\xbak\xff\xec\x12&!\x9d\xcc\x01\xc1f\x1f\xd0\xa5']\xd3\xe5\x11\x91\x0b\xfd\x04r\xfdq\x88\x81\xbcK\x93\xe5aL\xd35\xd7\x95*\xca\x9fv\\\xe9V(\x81\x0b\x7f\xc3F\x95\x04\x87\xfc\xda\xa4B\x14*\xdd\x1a\xcd\x08%!\x11KT\xfd\xc8\xbc\xacp\x00\x1f\x88p\xe5\xecPmA\x1e-D\xdd\xd9<\xef\x85F\xa2AHF\x99BH\x87\xf0\x9aT\xe1;\x9a\xca\xea\x06\x15\xa8\x17u\x0e4\xfb6\x00\xe2\xbd#\x01\xbc\xf0\x03xw\x05\n\xdc\x14\xfc\x90\x02\xeb0\xa1\xd2|-n\xa0\xb5\\\x1ao\x9b\x17M\xb36\x8c\xfa\x91\xf7\xe4K'\x9a\x81\x8d\xcb/\x9bt\xe1]\x15nN\xa1BgJEf=\xbe\xb1&>Jr\xb8\xa5K6X\x19\xa3L6\x80F\x0d\xe7i\xaa\xcd\x88yJ+\x8798\xfc\xd2o\x04\x89\xd6\x80\xc01\xb7\x15;T\xb2\xa8\x07\x02\xa3\x02\xcf+\x87M\x070\xa4W\x01C\\\x03\xc32\\i\xf0\x15\x04\x18\x1a\x85_\xde}\xdb\x19\x11XB\x94\x9a(Y\x1e\x13\xd5\xc9+\xe6<\x07\xc7e\xea\x11S\xcc\xd2%#P2\xdf\xf2?y7>\xcf\xd2S\xf4`T\x9d\x17\xcdG\x81\xc8\xd7\x1c\xc3>/\x06\xa4\xeb\xcao%\n\xdd\x8e&<\x1eT\xb0\xf8\x16\x08\xca\xe3I\x7f\\\xc4U\xddS\xc3\xa0aD\xdd:\xd8\x8c\x8b\xea\xa8\x90\x97\x96\xa1\xd8\xea}Q\x88 hP\xe1JCT4\xf3U\xc0\x82\xf8\xe8\x17V\x98Wt\xcba[\x8a\xf2$!\xde\x1b\x12\xc0\x0d?\x807\xeaR\xe9\x02\x01\x1d\x89x\x11\x0d\xd8\xa4\xe4o\xbems\xb5R\x1a\xf3\xfah7\x9d3o\x86;\x0cA\xee\xca\x92ig\xea\x86\xf7\xdf\x84\xb0\xd7\x82\xa1\xc4\x15C\x89\xc4P\"14\xe5\xa6\x10\x81\x97N5\xc3\x88\xf7\x8a\x04\xf0\xa3\x1f\xc0\xabo\xe7 ,\xc8\xf7\xeaZ\x90\xef\xcf\xc40\xe2\x8e_\xda\xc9\\\x1b~\xfd\x87\x91\xa8\xc4\x9f\x8e\x88\xf4Lp\xba\xcfT\xe8\x10!\xcc\xb4\xf1\x10\xcdu\x14,D\xbd\x9fg\xff\x95\x88\x84.1\xa6\x87\xec\xfa\x89x\xc6\"z\x8a\x93En}\xab@W,\xd1\x8f\xc2\x00:vr\xb1\xb5\xbc\xb9\xcbo\x1a\xa4Xv5\xf5rZD\xd7\x02\xfb\xbf\x06\xd1\x1d\"C\xdd\xf6\x02\x14\xe1\x95\x15\xb7p\x8b\xf3\xa4\\/\xd2\xe6e\x89\xde\x95\xb6\x11\x02G\x0e]\x18\xa0zI\xde%o}S\x0c\x1e\xf7r\x04\x07<\x91\x0bG\x89\x14Q\xa2\xbc9\xe07\x07\xcd|\xf9\xeaepYt\xa0 \x95s\xb8\x9a\x86\xe0\x9d\xf9\xd1+\xf3\xa3g\xe6G\x98\xa3\xcaK\xe3\x00N(\x13-b\xe5\xcdoT\xb0\x86\xb1\xe0A\xb7\xa1g\xd4\xb0V:\xec||V4\xea\xec\xf3\xb7\xe7qi\xf2\xb1w\xe6\xa8L\xe0i\x9e\xe6Eut\x1b\x9aW7oep#\xaa\x89S\xae\xcc\x85\x89\xaf\x07\xe5\xdfRg\xa1\x89\xd9\xac\xcf\xc4I\xf9[J&Z\x95\x15\xef\xff\xe6Me\x00\x15}\xae~\xb2R\x99\xa0\xda\x06\xcc\xd3\xec\x1f\x93\xe5\x8a\xaeQL.~\x0c!\x8f\x85\xa8\xfd\x1bm\xa6<\xadM\xd5Qc\xdc\\\xb4\xd2J\xcd-\xd4\x7fS\xacZy\xfc9N\xcec\xf8L\xd6\xd0\xfb\x1bl\x03\x85m\xf8[\x0f\x92\x18\xd8/\x89\xc7\x06#y\x05z[%\xf8D1\xfd\xb2\x16\x87\x16)\x1c\xf4\x86\x15cBu\x892\xa9\xd7j\xc1\xadJY\x08e4%\xce\xc1~\xb9\x0e\xcd:\xcc\x955pT\xae\x1b7\x8ey\xa6\xc48\xfb({\x8f\x9a\xf8I\xdcT\x01\xcd\xe2\x00\x16\x0c\xc7z\x7f\xff\xfb\xf1\xf1\xd1\xeb\xd7\x1f?<\xf9\xe1\xd5\xe1\xf1\xfb\xc3\x0f\xc7\xc7\x7f\xff{\xaf\xe9\x08\xb2bog\x0eJ\xa3y;\"\x18\xaa5\x91z\xb5& \x05Y([j\x88\x91\xcd\xe5\x87\xa6\xf4\x8eg\xa0^\xae\xe8\x9a\x87O\x17`tSDL\xdb\xf7bU\xc9\xb5\xb2\x04a\x94\xd9\xeck\xe5\xebb9-\xca\xb3z\x97kJ\\\x93p\x9fY\xe9\xd2\x0c\xf3\x0ex36\xdei\xec\xe9L5\x86v\xd7\xdf\xa0\xd2:\xe7*\xad\xd3\xb8\xd4d\x9d\xff\xbfM\x93uj\x87_\xa1\xee\xd3\x14XT\x7f\xad\xe2\xd1\"\x96\x0et+E\xa9\xb5*\x95Z\xab\xaa\x82I\xfe\xac>\x10\xac\xc1*VuV+\x17\x85\xcf\xca\xa6\xf0Y\xb5)|V\xb1\xdc\x870\x84\xb3X\xdc`[\x11Q2\x00\xe2\xadcF\x9c\xfc\x00\xd6\xd7\xa7\x11Z\xff)\x1a\xa1\xf5uj\x84\x84\xff\xbdM1\xb4\x8eK?}N\xb9O5\x94{\x19\x07p\xcc\xf6\xc9\xda\x81\x16\x9ft%l\xc7\xff!\xc2vn\x85\xe6\x92\x13\xb6%\x1b\xefI\xec=u/\xbby\xf1\x0d\x84\xed3'l\xef\x15\xc2\xc6n\xf5\xf38\x9bG3\xfad\xb1p\x8d\xe6\x7f\xef\xac\xe8~bWt\x1f\xc7\xa5\x83\xed\xb1\xba\xd7\xcecqC\xec\xb5\x13\xdck\x17q\x00\xe7\xd4\x0f\xe0\xe2\xfa\xf6\xda\xc5u\xee\x8a\xf74\x9c|\x86\x11\xdb\x10\xe3\xe6\x86\xb8\xb8\x82+H\xd5\x18?'\xe1\xb4\x89\xcf\xa8\xb7\xa2JRn\xea?\xe4\x89\xd7\xe9\xce\xceC\x1f\xbf\xe7^U\xe6\xbd\x00\x07 \x92\xd0\xe8\xe2\xfe*#_\x11\xf2\xb9\x13\x80\xd8\xa8K\xc3!\xfb\xa5\xc9\xde\xd1\xe8%\xcf\xe6m\xbd(9\xbe\xe5\xfa\xbai\x1d\nM_\xe1L\x82\xbb\x7f\xbb\xd1N\xa00\xc0l\xe0\x01\x02\xb3\xfe\x16\xec\xc0\x80A\xfc1W\x1b\xee\xec\xf8\xf8\x99\x89/\xc0\xcc*E\x1b\xa3\xd8\x90\xfb\x90-X}-\xd8\xa5I\xb4\\\xc5GC0e\xc1i\xe3z(\xf1V\x8d\x8a\xa1\xfcn\xad\xfc\xb9p\xed\xff#\xd6\x8b'\x8d\xc5{\xc2H\x91\x83`\"\xd4\xc9\x98\x1f\xda\xa3\xbe\xcf9\"\xfb\xfa\x959HZ\xa4\x16d\xc0\xf5\xd0m\xd9T\x05o_\x84\x07u\xe0\xd0\x08\xcf\x92gB\x01(\xd1\xc0P\xf5\x18\x8a\xf5o\xa6\xce\x87\x06\x19\xc5;E`\xaci\xfdIm\xfd\xe3\xab\xae\x7f\xd3\xfd\xba\xb1\xfeIke*\x15e\xb3E4!\xde\xc0\xde\xa68\xa6\xba\xb4\xcb\xd0\xd0Q\x1d\xa5\xeb\xca\x05\x83\xeb\xdd\xe9N\xd1Z\xeb\xdd\xa7\x91\xac\xae2\x8b.V\xa6o\x8d\xcf\x16(U\xc3\xa0.x\xc5X\x11;\xd8\x18\x92\xb8\x1c\x99\x8c\xa8|\x16\x8e\x1e\xc5`]\\\xc1b,.\xa2V\xe95h\xb8_{\x95\xa6\xab\x16\xaa\xa2\xa3sZ\x1f}\x99\xa6\xc7\x18\xe3W\x9cLi\xe5d\xc22gQ\x95d\xb1\x83\xe6\xa1\x8fw#\xfb\xe9n_\xc4\xb4\xb6\x88\xd1\x95\xd6\xef\x8fXWa\xba\xb6\x86\xdd\xd4V\x85.\xa9\xa9\xb9R\x10\x14\x0e\xf0L*\xa8\xbd2\x99\x8ea\xc8\xea\xcc\x06\x06=\xd4\xc5\x95\xb5\xa0\"\xee@]\x92\xf2hQ<\xbflH\x11\xf3=\x97\xd6\x10!\xad$\x13Le0H\xac$\x13\xc4o\xd2\x16&\xd0i\xb2n:R\xa7\xd9&z\x1db9S\xed\xd9\x97\xba\x9d\xdc\x8e\x91 \xad^\xff\x92\x9fH\xdb\xe2\x07D\xbf%\xa0\x03\xee\xd9\x8f\xcb`\xb2\xfa\xeag\xc8[je\x1e\xda\xb2\xf3Y3\xf3\xb9D\x05\\\xa0\xd6\x15\x85\x9a!\xbc\xd7H\xef\x87q\x00Otz\xd7\x0fO\x9e\xbe4h^\xdf\xb2\xf7/\x1c\xa4\xfd?\nw\xbd\x96\xfc\xa15\x8f=kF\x99\x92\x19\x8eTN8\xaa;\xeaE%\xfdK\xf9\xaf*upK\x19\xf8\xd9z\xea\x1er=\xc0!\x03\xc8\x1f\xb1\xd7pO14z\xd4..\x16ho4K*\x87\xd3\x08ut\xec\x9f&J\x18!\xa9\xa6\xef\"%o\x1c\xfb\x01\x94.\x93Jh\xc4\xfb\xf5\xf2$Y`\x85\x04\xdb\xf3z[\xb4\x06\x11\xf5\xd7\xdbx\xf4\xa4P/\xbeu\xd1\x06\xbe\xb5i\x03\xdf\xb6i\x03Y\x17\xaam\xed\x8b\x9aE%\x80\xb8\x7fT\x12\xc8\xaf\x01[\xa6X\x97\xfeK\xa4\xc4vH\xf3\xf5\x8cz6V\x04\xc4\x82S\x91\x1b\x97g\xda.\x8f\xf6\xcdFk\xa3\x87\x1acP\xe6{0\x98\xde\xac\xa6m*\xb0GOc\x1a+\x88w\x9b4\x81&G\xf1\x94\\\x90\xe9{\xf2\xc5\x010\n\x89\x7f#\xa2\xce\xddz\xf9\xe9\xbd{\xeb\x08\x1cm*l\x17\xcd\"W\x87pa\x84p\xefn\x1d{!\xa7,\xd2\x94]\xd2I!\x17;\xf6\xde\xa9\xdb\xec:\xbb\xed\xbcI^u\"\xa6\x9d\x9a\xcf\xaa\xb3R >\xce,\xac?/WY\xaa!\xe4\x9c\\ \x052\xae\xee#\xbc\xb86\xd0\xbf\x8a\xb2\x0eK\xbe\"\xd7\xd5/7C\xb8\xf7\xdc\x1b!\xc7r\xb2 \xe3\x9eK\x0f\xa5\xa9\xc3\xb1\xfc\x85Y\xbb\x04\xdb&\xc6\xf2\xba\x9f\xbe\xf2\x12\xc3\xcc\xb91\x8f\x97\xd9e\x94?\xc5\xb0\xc7}\xce\x14\xc2\x01\xe4\x98\x92|\x1fB\xea!\x7f\xd8\x8f2\xc1'J#\xe0\x88\x8e\xb5\x94[\xbd.}wOo\xf5*\x10\xc0\xe2\xf5\xad^\xa6\x8a\x1dP1\x16D\x0d+\x8f\xfd\xabA\xed+\xfb\xb8\xcfD%\x84h\xb4\xebP\xe79)\xed\xad\xb8\x08\xa1\x97\xa0\xc7\xae\x0c\xc4\xcd<\xa5\xd0j\xb3\xde\x96\xbc\xcc\xd9W\xcfD\x95(Q\xfdBW\xd7X^\x92\x92ci\xe9!L\xeaT\x14\xc7\xc4$N\xf9T\xd2S?\x90\xf7f\x8b\x90R\x12{[\xbb\xc2\x12\x83\xdaEM\xd1\x13\xebV\x00\x01\x1c%\xcd\xa8\x13\xba\xc8-\xc4\xfd\xa0\xec\xc0\x87f\x1fJ\x85X\xd86XN\xe4e\x06\xf8%\xaf\x8d\xd6,g\x8b\x0f\xa5\xfaV\xe3\x0e\xed\xc6\x8eH\x8f^\x97\xb4\xc9*\xbbV\xf5 v\x897\x98\xda\x12#k\x0b!4n\x91\x98\xa6Qe\xac.CU\xf4{\xef\xdc\xba9#\xe9\xda\xf1Lq\xe4\x82cK*\xf2\x16.8\x0d\xc0V\xf2\x13\x8a@s\x8e\x03\xbc\xd6\x11~\xa1\x14Z\xe3Z\xa2\xad\x81\x01\xf8uG\x12\xd0\x03\x86\x13]G\xc8\xd4O\xae\x1f\xd4|\x82\x9a\xf0'0\xf5\x19Ok=\xbaT\x8db\xc0d\x9fbNT\xcf`\xde\x00UOz\x80 M\xf4\xe5\xc15\xc3\xe2Z\xa1n\xb0\xa8 KP_q\xeei\x89y\xbb\x89\xaf/S\xa3\x19\x08\xe3@\\6o\xbd\xef\xc2\x92\xc2\xe9!\x1c@\x0f\x19\x1f\xd8\x87^\xd03c2#\xc1=\x8d\x1eU^\xdf\x82\xe96\x1c\x8fE\xa9\xfe\xad\x01\xba\xacn\xa3\xd2\x14\xffE7\xa3-YBJ\x99\x14\xaei\xe1E\x83gN\xaf\xc9Y\x82\xd8\x01N|\xdbg\xb2\xfe\x06\xf2\xf3\xd4iE\x97\x159\xd4\x01\xad\x8a-VM\xd9\xe9\xd4\x19?K;n\xb0\x00\"\xeb\x02\xd7p\xad\xe1\xa0\xf2\x08\xf60?\"\xc3\x14\xd8\xe7\xf9\x90\x1a\xdbAU\x03`\xcdZ\x1b\x01\x84\x03\xf0\"A\xe5\xb09_\xb4K\x8b\xd2\xb7\xbcb`b-\xc8\x9c\xba\x83\xec]t:\xa7\x1d\xe1& \x93\xca\x08\x95\x86(;}\x12\\\x8f0\xbd\xa7F\xbb;\x98\x06\x8d\xbd\xb8\xe3n\x81Tj2\\\xa7\xae\xd0\xb8|E\x0c\xfer\xb5C\x82q#\xddz\xe4yYx\xac\xdc\xbb\x18K\x85\xe9\xb2`\xe8\xbaJ\x9djL\xd4gf\x0c\xc8\x01}?(u\x7f\x03\xad\xf9\xd9\xa9\x97\x93\x9c\xbe\n\xbb\xa8\x07\xf8\xbeF\x0f\x99\xdd\x00v\x06N\xbdD\xd9\xe1rE]l\x0c\xa2\x17\xf5dR\xe4\xf4\xba\xe4\xbe/\x96\xb1\xca\x8c:\xf0\xa2&#\xa4\xd3l&I\x1e\xd7w~\xcb|\x9ex\xb4T%\xf1m/\x04X\xfeq\x07\xbd\n\xf6\xfe\x83+{*\xfaw\xa5R\xa0P\xaa\xaf\xd4\xf3K\x83\x94-\x03\x9eD\x0d\x1d\xf1nc]\xf1{\x917\xc1+\xeb\x94\xf3J\xe2lW\xaa9\x8f\x9d\xa46E\xe6\xd2\xb3\xbb\xf2\xb2\x94R\xc1\xb3@5\xb7\x19*\xe4]\xaa\xe7\xad\xcb\xea\x91/y\xb8\xe8\"l\x9d\xd1\x82l8\xb5/\xb2f:l5\xd5\xe1T\xbf\xb6\x18\xa8\xd5?\xc6ty\x95\xe2L\x94\x96\xf7\xed\x9cb\xb5z\xeb\xcf\xb1_S\xb5Z\xcf$\x0e\xc6A\x0b\x1d3\xc3@\xa2\xa0\x1b\x05\x8e\xaa\x94\xb7\xd5\xfc\xa4P\xb0\x00\x12OG\"\xe5e\x18\x7fgQc\x1ev\x913\x90\x0e\x89\x84\xcbK\x1eC\xb0t\xec\xe5\xa8\x0b\x0d\x97\xfdp\xaf\xd1.=E\xd9\xfb\xfc\xc4\xb1\xc0g!\x03\x0eM>aE\xa5\x14nu\xe6<\xba\xa2\x13r[\xda\xe2<.\x12\xe3t\xc8\xa7\xa5\x9f\xe2\x8a\xf1B]&\xe9\xd9f)`\xa6\xcc\xd2/n\xba\x9fj\x9f\xc9\xfa\xed\xac\xc3\x90\x8aC\x8d1s\x9d y\x0dFB\x1eq\xee~\xc4W\xb42lW?mH\xa9.\xdd.\xba\xab\xd1\x1a%\xbf\xfa\xc8\xcf\xba\xf7\xf7\xf2*\xebb\xe0\xbdq\x8d\xb5\xb9\xac\x9a}/\xc3\x8b\x0e\xbd\xbe$\x9dT\x18\xcb\xf0\xa2\xeb\x99\xfa\xb2\x92\x8f\xc8\xa9\x137\xa3Yc\x06p\x00ob\xee\xc2\xf2\xd5MPZF\xf1\xd5\xa7\xc3\xbb#\xbc;\xd7\xb9\xa5\xa43&jC\x1eA\xdf|\xf69Zu\x80\x9d\xd2\xfe\xeb\x90\xce\xfb\xcb\xf0\xc23T$6tV\x17\xbe]\xa5\x04\xc3\x1ecMzT\xb9\xe3<\x90_\xe7\xd1\xa2\xa3\x99\xa1\x18\xcc\xefW4l|\x8eV\x1fc\x1a-\xbau\xcb\x81.\x87\xdcM\x05\xc5\x13\x82u\xeb\xafi\xe5\xd0d\x06\x03}\x7f4\xfcL:,/\xad\x18 \xae\x80R\xac\xbfkF)\xd6dw\x94b_}\x0bJ]E\x92\xf8\x87\x13w\xab\x940\xfa\x18\xa3\x9a\xb7\x92\xbc\x0d#+[\x18^\xc9NS\xa3vY^L\xa4\x8b\xaa\xb1yJ\x81\x96J\x18\x08vlo\xedL\xd4\xf3o)\xfb_0n\x1a\xc1\x87\xa2J$l\x9b\xa1\xd2L)\xfd\x14\xdf\xde\xbc \xdb\xdb9\n\xa9\xa2AC\xa1ry]\xfa\x01\xe4\xc67.\x03P\xcb \xfd\x17\xadJ\x92vY\x16Z\xf1\xc6b\xdf\xd9\xe5Zv\x85\x16\x8f\x12y\x89q:FY\xaa\x17\xfaN\x85\xc5L\xdb?\x00\xf7\x88G\xf5\xb2F?\xaa\x97!VB\xbd\xa4\xe9&o-N%/\xae\xc3\xaf\x14\xa9\xb2x\xa9\xcaKF4R\x11\xc3\xdb\xfa\x01\xbb2\xe1\xac\xea\xf6\xf6\x04\xdf\x1e\xb4\xb8\xb6\x82n\xafM\x02\xc8P\xe3y\xc0H\xdbp\x08\xef\x84\x98\xf3\x9cad\x86/\xf04\x7f\xa1\xf0\x0c\xf9/X\xdc6\"`\xa5\x00\xda\x87\xdd5\xaf\xec\xe0\xb9*SQ\x1cZ\xdd\x98\n\x19C\xd0\x91/\xed.\x86\xcd\xc3l\xfe4\x99vpt\xa1\xf32\xbb\x00\xd6e\x9a\xab\xd9\x06\xday\x04(\xb6\x17wP\x1e\x0ea\x00\xb7`\xb7\xd8h\x16\xd2%\xcd\xa4\xb3V\x05\x9f\x9b+\x7f*\x8a\xdf\x0e\xf4Uo\x8b\xd7\xf8\xc0\x9c\x16\xbf\xf6\x0d\x1b\xed{\x14\xd2o\xdf\xb9\xbd\xf7`p\xff\xf6\xdd\xdb~P\xdc\x86G\x8f`p\x176@\xe0\xf1\xe3\xc7\xb03\xb8\x1b\xc0\x9d{\x83\xfbw\xee>\xd8\xfd\xbe\xfe\xdem\xe5\xbd\xdb\x01\xdc-\x9fc:w\x8f\xc06\xdc\xbe\x7f\xef\xce\xde\x83\xbd\xc1\x83{\xb0a0\xfd\x17\xdb\xd2\xff\x12\x9f\x0d\xee\x05\xb0\xb7w\xe7\xde\xfd\xbd\xbd\xbbE\xf3\x87\xe2s\xec\xa6x\xf3v\x00\xb7\xf7\xee\xdd\xbbs\xff\xc1\x83\xdd\x07\xbe\xda\x84e\xcby*\x7f\x10c\xad\xcb\x83\x8eP\x83!\xdc\x1e\xc0w\x90\xc26<\x8f\xbd'\x147\xcd\x13\xea\x11\xdfg32w\x0e\x8e\xbbS^\\+~\x85^\xaa\x93r\xe9\xa6\x98\x11v\xd4\xdaA\xb7\xc6\x1d\xdb\xf5\xb5\xe5\xac\xa1 \x88:RX\xb9SW\x06\xb3\xbd\xf8\x9a''Sr\x01\xa8o\xbc\x8eG\x0b\x19\xe0\xfd:\x1e=c\x7f\xbf\x16&\x8b\x8c\xdd\x12\xa1\xa3\xfc\xb6\x08\xac.\xee\xab\x81C0\x84W1>\x89\xe2l\xc5s\xe3\xe3'\xef\x93<\xad\xe6\x95\xd1\x81\xac\xa6D\x12\xee\xad\xd5\xd9a\xeb\x93y\x18\xc5\xbcma\xcb\xe4\xb7\x93\x98\x86\x11F\xa5\xe3\x10\xb8\xee\x12c\xc4S\xdd)9[D\x1dB#\x0b\x01\xe5+1\xae\x84N\xed\xb3:l\xb8\xf7\xbbZ\xff\xcdT15\xcb\x02V\xe1\xae\x93a\xb5\x90&\xa4\x93\xc4( \x1a\x9b\x8bO\x03p\xa3\xaab\x93t\x14\x1a\x97\xe1\xeae\xd5\x07\xd9\x15FW\x00\x02[\xf7:,\xda\xc4\x8c\x06,x4\x82\x05\x08\xd8\xc9Uv\xeb\x87\x18\x93\x9b\xb4f\xeexj\x06\x92<\xd5\xaa}\x19\xda\xf9\xb9\xb5\x9d\x11 \x80\x8e\x9d\x1a{g \x87\xf5\xb3\xb9e\xb3mQ\x97d\\\xd0\x84\xa7aXo\xaegX;\xd7<\xacW\xf6a\xf52\xa4\x81\x15\xe3\x07\x1c\xc0O\xef\xdf\xbe\xe9\xf3G\xd1l\xcd\xd5\xb6\x82Z:\xe6\x16}f%\xc0\x87\xc6L\x9e\x86\xe6\xbe\xb6b\x10\x85G\x05\x07G\xe11\xfe\xbd\x83\xec\x9cS\x07\xcf\x1d:`\xac\xcf6\xec\xdd\xbb{\xe7\xce\xed\xbb\xdf\xdf{\x00\xdb\xe0Q\xc6\x90\xdd\xf3\xf9\x9f\x8f\x1f\xc3^\xf3\xf4\xad.\x94h\xedCT\xaf\xc2h`\x95\xcb\xe5\x95|\xb3\xad\xaeu@J\x1b\xdeV\x82\xa5\x00\xf8\xba\xf2\xd0R&\xa2G\xbe\xaf$-\xc5f\xc5}k\xcb\x97\xac\xf7\xc0\x96GC\x85\xa8\xdel\xe7\x0c\xd2\x80[\xee*1~\xd8\x7f\xeb\xe4\xdd\xed\xa1W\xb0\x9f\x15\x90\x8d\x18ds\xf8\x1f&;\xb0\xad\xc7p \xa9\xb8\x00c\xcc\xef>\x7f\x07\x0e\xe09\x9b{\xce\xd3\x91\xa2\xd5F\xfe\x8cd\xca\xd86\xf0[\xad%\x86T\xe5%\x95p\xde\xc6\x0b\x12\x9e\xb9p^\xd2,7b]\x8c5\x87\xb2oY,\xb6/op\x02 \xf5/\x01\xdc\xe8'3t\xa65~\xc6\xf3\x93(\xde\xf9\xd6s\x96\x14\x1b\xdf+\x88\x81\xb8\xc7\xe8\x80\xc8H\x13\x94\x94\xc8\xcd\xc7\xa9\xab\xcb\xdd\x92z\xbbj\xcaj\x97>\xae\xe0_\xc7\x0e|\xc7\x08\xd5\xebv\xefq<\xf9\xbf^I\xafzC\xfe\xf1,\x0el\xc8\xe6<\x86_#:w9\xa7\xa4\xcc\xa3\xf6b\xc77\xc6\xd3\xc9\x00\x81\xe6\xf8M&\xcb\xca\x9dK\x9fQ\x842=\xec\\\xea\x1b\xd4\x9bE\xdd\x96#t\\o\x0e\xbf3\x8f\x85\x18\xc4kA\x0b\xb3\xb2\x93\x9cv\xd5|:\x9a\xaa\xd3p=\x9b\x0d\x9b/s\xb89@;Q\xf2l\xf3\x12\xda\x15+\x81\xfaX\xb1$\xa8\xb7+&\x85\x17\x81\xaa\xa4\xf5\xf1\xde\x8d\xca\xf2\xf1{?V\x9a\xe6\xf7N\xa8\xe6\xe3s\xaa\xf9\xfa\x82\xd6?oBE\xe6\x97\xdb\x87\xb8 W\x04\xea\xcb\xe6\xfd\xa7\xc9bA\x10\xd2\xfbp\xac)\x90\x81\x01b_5\x0f\xd4\xb4\x92G\x1a\xe7 \x9e\x97o\xa5y\"R\x05^hGI\xf7!\xd3\xe5{\xbb\xbb\xd3O\x9f\xf2\xe9\xfd\xdd\xdd\x1d\xf6\xefl6\xfb\xf4)\xdf\xbd\xcd\x7f\xee\xde\xbe\xc7~\xce\xc8\x1e\xfe\x9c\x91\xbd\x19~3\xc5\x9f{\xbb3\xfet\x97\xf0\x7ffc\xd3\xe0\xcc\x14\xad\x100(\xc9\xa8J\xc7.\xbb\xc1i\xb0\xfb\xa0\xc6\xeb0.\xb2wx\xb1\"\x13J\xa6\x10\x16\xed\xf4\x14c\x8f\xbc\x07\x89\x96\xb0G3\xf0\x94\xf8\x88-\xc5D\xb0\xd9\xc8\xecA\x1cE\xb4\xaf\x11\x1f\xe8\x9e\x864<>\x16\xd9F\x9bX\xa9h\xf1\x84\x14[\x83\x0c\xbb&\x9a\x1aTQP\xb9]\x14\x82M\xaa\xf7yQ\xc4\xbcz\x933\xc4a\xf5f\x86ofUB4\xe9\xb6:\xb7\x1f\xe8\x97\xe7\xce\x83\x96\xe3\x18\xa8\xc8\xcb\xc1Co\x1b\x8e\xeb\xca\xe6\x15\xc6\x0eOT\xe6\x04R\x9c\x80\xf2\xd1V\xc4\xb8\xab\x9b7\xd9\x1f\xb1\x8fJay8\xc6\xec\xaf\x98\x1dA\x95\xfe(\xeb\xf2\xca'\xfe\xed\x07\xb7\xb5\xb3\x1e|_G>\x81\x94\x0f\xeei\x90r\xd0\xc4\xc7\xbd6\xd2!k\xb9pG\xe1\x99\x0e\x15\x17\x98\xb5\xf8&\xe4\xcd\x03\x17\x0b\xb2\xca\xb2\x8c\x8d\xa7s\xc4H\x9dY\x8a\x11\xa8\x15\x03\xe4\x1c\x81\xec-\xd8?sx\x0c+;]F\x9d!\x0f\xd0\xf5\x9b-bAK\xfeX\xa9-6\xc5%n\xb6u\x06C\xd8\x194G\xbd\xe62t\xe3\xfe\xa9\x00C\x08\x07|'\x82\xf4\x8e\xae\xb6\x8dy\x01fx\xfc#\xa9\x0f\x80\xff \xbc\x06\xe8\xf6\xf6\x19<\x82\x956\x11\x00\x1b\xd6\x92\x81ttf\xe0n\x8e\xb1(\xcc\x99\xc6Q\x9c\x01 \xf3\xb1\x89\x13\x18\xc2\x02\x0e \xf3\x8e\x03X\x06p\xc6\x03\x91py\xf7!\xf3\x96\x01\x1c\xe3]\xbe\xfa3\x0d?SK\xe2{b\x92\xae\xd9{'>0\x018\x8aM)\x0b\x10\xa2\x03\xfd\xb3\x93\x94\x84\x9f\x1bO\x9a\xe7\n\xeb\xe8\xd46\n\xb6e;\xd8\x0c\xf0\x93\xc4;\xc5\xd7n\xde\x04oY\xe6\x8c\x9e0\x08Q\xb9-f~\x89K\xa7<\x16\xdf\x18\xdel\xeb\xd1\x06\x050B\x02\xb4\xd0\xb8\x04\xb2\xc8\x08Nb\x89\x0bt\x8c\xfbh\"\x96\xb6\x18\xb8a8\xdf\xba \xda\x13y&N\x10t\xba-~0\xfc_\xff\x9f\xea\x876n\xc8H\xa5\xeas\xa9\xd4_\xdb\x11 /%\x11\xa7\x98&o\xbf\xa0Ml\xdb\xc5\xf0\x08\xd2\x87\xcd\x95C\xd3\xb8GG\xf1\x18\x01\xa7r\x86\xbbZ\xfeOI\xef\xd4\x91\xcc\xdf\x19\xd4y\x83\xe2pkRyQ\x91\xa98^\x9b\xf4\x1e%\x19\xa5\\S\x93\xfc\xa3*\x08\x9f\x1de\x87q\xbe\xe4\x8a\x9f&{\x92\xda\xad\x1db\xe2\x85\xb8VE\x06\xcf\xf7\x85 \xde\xae\xec\x13\xad0\xe6\x9bak.X\xcc\x00z\xec\x0fBz\xfc\xc4\x0d\x9b\xf7\xab\xfd\xe9\x8f\xb4\xcce),\x99\xf2\x15\x06Qch\x10\xeb4\x18h\x9e%m*\x97-\xd2\x8f\x93)aB3\xdek6\x81\xab\x89\xa2w\xb3\x1d\xca\x8d\xd4\xac\x1dZiG\xa3sbk\x9es\xe0\x16\x90A\xc1\xe4\x00\xd2\xfe\x0f\xf9lF\xcaS\xab\xf95\x03\xa3\xc7\x8e\xb7\xb0\x1fe\xb5\xb7Q\x8a\x8d\xccJ\"E\xe2\xa9(\x89\xee\x0f\xfc\xc2X\xdc}\xdf\x1b\x988\xda?''\xabp\xf2\xf9\xe7d\xb1\x9eE\x8b\x05\x0fY\xe9O\xc9*%\x93Z\xedG&O0\x96t\x15\xd29k}4\xc6L\xf1\xf3h1MI,\xbe,~\xb2\xe7e\xb9\xb4)\x99E1\x91\xfb\x0bqr\x91\x84S2\xed\xe9\x14\xab\xa4\xd8a\xfbz\x0e\xa2K\xd1\x19\xda_4\x1e7\x95\xd4\xe6qF\x7f\xc9\x18#\x8716Wk\x08\x83J\x02\x9b\xced\xd4 #\x0c\xea\\t\"\xee\xdf\xd1p\xcb\xb8\xdf\x92~\x94\xb1\xfd4\xe5Q\n\x95\x97\xf8f:\x80\xc8\xcbQ\xe5\xa4\xa7;a\xb7\xb1\xdf\xdd\xbd\xaaZ\x91\xf2\x83\x8d\xd1\x81\xb4]\xb9\xd8\xbe\xb74g\xaa<\xc9\xe5;Z\x87\x17\xa9!\x10\xfa\x05\x91E\x90\x8e\x85;_\xcd\xdf\x84p\x8f\x92H\x16'\xf4\xe2\x9a\xa9\xeb\xf2\xaaX0\xb8_\x97\x818\x16|\x7f\xbf\x15\xc2m\xec\xc4.\xf72\xf0\xb8\x1a\x88\x07\xf1\x17\x9cD\xa1X\xe1\xd2\xe0#H\x1e\xfa<\x85\xe8(\xf2\xc8(\xde\xde\x1e\xfbc\xbdv\x8f\x7f!\x082-h\xebU!\xa0\xd7\xd9\x0d\x1a\xd8.v\xc1^\xfd`\xe3\x8a\x8c;\xdf_\x05^bJii\x18\x8c\xc4{\x07\xc0\x90a\x1f\x12/\xaf\xb8 9M\xae\x97g\x042\x9aF\x13\xaa\xa8\xf6*^X\x0d?\x11\xe9j\x13{\xdf?\xa8\xebF\x94\xe9\x1c7E@&\xbas\x98\xdd\xfb\xbe\xf6\xe5q\xff\x1d \xa7\x8cN\xbe\xa7\xfc@YV_`\x80\xbe\xeb\xf7\x0f\xcfHL\x0f\x97\x11\xa5$mv\x10\xb6\x81Q^%\xd1\x8f2Jb\x92b\xd1M\x8er\x8d\x0ft\x96{\xb1%\xea(\x01\"\xb88\xf6\xee\xef\xfa\x82\x03h\xbe1CA\xfdc\x14\xd3\xfbH\x07\xd9\x9e\xad\x9c\x9f\xcd\x99-85\x1b\xd4\xc0\xb6\xe8G\xf1\x9c\xa4\x11\x15J\xaf\xbb\x1a\xf3\xc0\x8a\xa3\xdd\xdd:\xb1\x06\xa12\xd0 \xd5\xec\xfe\x8am\x9fU\x7fJN\xf2\xd3Er\n\x07\xca\x0f\xaf\x97\xd1\x94\x84\xcb\x9e\x0f\xfbmC\x9f\x06(\xfb\xb3!\xd4w\n\x08\xe1\x88\x81\xb2\x8eK\xe5\xd4\x98X]7\xf9\xb3\x86O\x19\xf7\xd0#i\x9a\xa4=\xc6\xbd.\x92\x8c\xb0?\xa6$\xa3i\xb2f\x7f\xae\xc2\x9c\xdfKI\x96/Iol\x8a\xd6Y\x1a\xd1%\x01\xa1i\x8e\xbd\xbd\x81\xa8a\x81b\xab\xae\xbe\xa0$\x16\x04\xa28\xa3a\x94w\x86\xe5S\xdf\x0f \x13j\x85F\xb6?\x13 OJ\xe5\xb8)\xdaS\xe1!h\x0d\"M\xb0 \xdd\x147i{ym\x8f9q \xa8\xaa\xe2{X\xae\x93^\x89\xc7_\x14xfSJ\x9e\x15\xc5\xdd\xc4\xcb\xacu[*\x15\xce\xc3J\xaa\xc4\xa0N\x04\xdd\xe2\xaa\xd1\xd8\x0f\n\x9d?l\xb3\x86\xab\xd4\x17\xf6\x8b\xaf\x0dJT\xed]RR\xae\xdd\x00\x0e\xb5\x86I\x06\xba\x1c\xeb,zH\xb3\x11\xdf\x9d\xe0\x8aP\xd0\xcf9\xe5Uy&\x85F\xc4KQ\x15\x92\xaa\xdbf\x86\x94\xa6\x19}I\x94\xb8\x83a!\x0c\xd5NK\xcc\x12\\u\xaa\xe8\x1d\xc5g\xe1\"\x9aB\x9c\xc4;\xbc\xd9[\xe2p\x98\xcc\xf3\xf8s\xcf\xb7\xc5\xd3\x18&\"\xb6\xb5\x06n9: \x06\\*A\x02\xee\x15\\L\xc2\xe0\x99\xd7\x86,\x1c\x89\xc4*?\xc6\xc8\x1f\xcf4\xff\xfa\xc7e\xa5\xf9\x9f\xa5j\xf3\xed\xcc#<]\xb1bND\xd8\x10\xa7\xe4#bn\x13\x0c%\xd7\xe3\x06N0e\xa7\xb4z\xe45\xe7\xcb\x16B,\x02\xe7(\xfby\x9c\xcd\xa3\x19\xf5|\x08g\x94\xa4@\xe2)\x10\xc6\xf5\xf7\x10\xd7\xce\x11\xedd:;\x04\x16GU\x97\xb6q\xcb\xc8\x86\x0f\xdf>\xe7M6\x88C^\x1c\x19L\xfa\x8f\x19\xb4 &>\x92\x9b\xf6<\x8d\x84\xae\xbd\x0em!\x85\xcb\xb5:\xa8\x8cw\xc0z{[\xee\x9b\xea3\x9fW\x8fb\xcbP\x1d\x90\x0e\xfb\xea\xaa\x83\xb6\xb5\xda\xa2\x02LH\xb8\xab\xdc\x04n\x92\xa2HV\x8d9,\x99.j\xa4#\x97^\xeeF\xe3\xcf\x15\x1a\xaf\x1b0)\xb8\xa8\x9b7\xe5\x1eVh\xdf\x16\xe1l\xd1\x01\x9b\x02_\xebiHC\xb6\xd4\xa8\xf7b@\xf3v\xf9\x9a:\x12E\x8e\xa4\x05M\x95\xc8\x17\xb36t\x94\xb6\x02\xb8\xff?{\xff\xbe\xdc6\x924\n\xe2\xff\x7fO\x91\xc2o\xc6\x03|\x84h\x92\xba\xd8\xa6M\xeb\x93e\xb9\xc7\xd3\xed\xcbH\xb6\xbb{\xd8\xfa\xa9!\xb2H\xa2\x05\x02l\\(\xab\xc7:\xd1gw\xcf^#\xf6\x01\xf6\x9f=o\xb0O\xb0\xb1\x11\xe7MN\xef\x03\xec+lTV\x15P(T\x01\xa0,\xf7\xec9\xdf\x87\x88nS\xa8B]\xb2\xb2\xb22\xb3\xf2r\xef\x1e\x92F\xc7e\x8bJL\x9a\x16\xfa\xe85\x87\xe7\xd2}C.\xb8\x18\xd4\x9d\x1b\xa9\nU\x17$\x85\x7f\xb8wO\xf7\xba\xe0\xfc\xaaK\xac\x91\x81\xdb\x05\x0c6to\xd7\xf6OO\xf86F\xc3\xe7%\x83\n\xc1\x88\\\x8b\xdf\xe5\n\xe7Y(\xd7\xc9\xffRj\x15u\x1a\x0f3&\x0d vdA@\x11D\xe3\x06.7N\xeb\xb6ix]\x8es\xdf\xc8\xec\x08\xf5P\x19\xd1C\x91\xebN\x1b\xa9\x80.\x02\xd25f\xf1\xa6r\xf3,Hv\\f\xb8\xa9\xc0#\xc8>\xbbl'\x98\x99\xd1qyg\x8eK\x19\xb9\x92SB\xc5\x9fC\x81 \xdfs\x8d'\x0f\x9f\xa3\xd4<\x93 (\x87\xa2z\xc4+]\xf8\xc9[/K\xca.P5]l\xf5\x8b\x94_\n\x86r\xfaT\xd7YBd)\xa9\xd5\x9c\xda\xc91\x95\xcd\xa2\x885\x86z\xb2p\xc3j\x94G_U\xac|\x84\x11<\xdcy\xf8p\xbf\xf7\xd0\xa4/95\xa2n\xae>\x7f2b\xfe\x8dU:N\xf2#\xbb\x87d\xb6B\x9dS\xa6\xf0=(\x1f\x08\xd2\xa9\x9a\x93\xe6\x05\xf1\xa6]z\x08\x88\xb2aQm\x88a%\x80(\x07\x1ac\xa2U\x8dA3!\xcb'\xf6t\x04\x1fQ K\xff\xa5\x9dloSY\xeb\x13\x1d2F\xf7*\xfd5(\xfd\xb5[\xfa\xeba\xf9\xbb}\x17\xd2NG\x9bk\xe0\x86\x9d3\x08U \x0e\xe8!\x92CS\x9e9\xa9h\x0cz\x98\x9f\xb9\xd59}\xac\x87Bn(\xd7H\x8f\xaa\xbd\xf7\xe9\xe9\xa9*+(\xd6/l\x8b\xbe\x16\xef,\xb7XtG\xf7\x0d\x9bI\xce \xb0|\x1f\xef\xfc\xc9\xa5}\xc8#/\x1eV\xdceM\xf3<\xd4\xcf\x93\x0f \xc4$-\xe4.\x18\xc3!\xbf{\xd56\xa0\xcb\x1b\xe3n!%}\x08\xb2\xe0\xaa\x86\x04\x9d\x8e\xf2I\xfe\xa4u`2u\xfc\x93\xb1\xe3\xd2\x05Ln5FY,\xc1z2\x86K\xda\x7f[\xa4\xe0!I\xc10\xea\xf6\xd7\xc2\xb6\x96\xde\xf5\x05\xa1\xab\x86\xf3@\xf5B\xcf\x92\xd94\x17m\xfb\x8a\xce\x9d\xc7Ny0\x0d\xc0\x1a\xa9\x89\xbfL@\xb84\xaer\xae/\xa1\xe0M\xfd\xc9\xa5n\x9c\xad\xfax\xd9\xbc\xc2\x02\xdb\x99\xe6M\xd7\x13\xe2\xbb^1G\xaa\xca\xb4\x1c!Q\xb3\xcd\xd1\xd1\x05u\xc9\xa4\xe5\xdclJ\xaf>\x97\x08 \x8a-l\x8b\x8e\xa7\xb4\xad\x1f\x97\x07\x99\xa7R\xe6\xe3s\x1e+\x02\x8fi\x84\xef\x9a\x0e!\xe5\xe89`]!u\xac0J\xf9\x91\"\xc4\xcf!l\xa5\xec6\xf5i\xa9\x0d\xbb\xa4\xc0\x91\x0f\xa3\x9f\"?\xb4-\xbc\x13\xe9\xf3\x9eyI\xcd\xc1%\x0b\x1a\xdc\x9f\x92\x14>\xb1EQ@\xbc\xd8F\xd9&\xd4X\x94\xd6\xa9Z\x0c\x1a\x8a\x94\xed]\xf5\x00=\x00Lu$\x97H\x91B\\\xb9@[-u\xf2,\xc8\x1c\x06\x9a.\x88\x04\xe5p\x93\xf0\x96\x05\xc5\xa2\xad\xea/\"\xc4\x13Wmt\xd5\x07\xef1qlf\x15\\\n\xdb#\xf0\x8dDI<\x88\xed\x8f\x81\xc5r\xa4\xf4\xa46\xf7\x14\x08uf>\x80\xfa\x81\x82\xb8\x91\x81\xa7\x10\x15p\x8c\x8a\x13\xbf!\xb2\xb2?\x03;c\xd6I\xc5\xe7>\x95\x8e#\x18\xf2\x1f\xe5\x85f\x9b\xc7\xc6\xe9g\xb5\xa6\x96\xe2\xa9\xb4ow:\xb1\xcb\xc1\x81\xab\xbe`Zf\xfefX\xbc!\xdd\xd4\xf3\x03\xae\xe7\xe7\x02\xbc\xa8\xecr\x08A1\xc4\xcc\xa4\x91\x93\x1f\xb3\x85\xa7xn:\x1d}xc0jFA\xb2m\x17\x13\xddFw\xa0\xaam\x0e\x085)q6\x89\xab*p|\xd2\xf5\x82 \x9a\xbc\x0f\x13oF\xdaE\xe1m\xb1+(\xca\xd7\x98\xc5\xc6l\xa7N\xa2\xd55\xaa\xde\x04\xe7c\x97\x83\xe4\x8b\xe0\xbc\x1eSaS\x9c\xf7k\xc2]\xb8M\xc1\x974\xb9\xee\xf0+~\xde\xb9\xc5 K\x19E\xc3ev\xb9{\x13\x9bp\xf4\xb9\x8c\x0c\xbb\xde\xe1\x13\x7f\n=\xd95\x93)\x98\xffd\x910\x17Ql\xc7\x024\xa5\x9dB\x14\xe2\x9d\x02Y\xae\xd2k`J\xe8?i\xe6Bd%9\x13\x02\xe4\xfb\x17\x89\xfd\x7f\xabMrb\x8c\x1dj\xd6\\)=rU\xa1\x98$\xb3\xd2,_V\xf7\\\xce\xcbVD:\x9b\xce\xdej9\xa6\x93v\"I\x8fk\xbfr\xc9\x84\xd9\x93C\xd8\xe9\xe8/\xb20\x1a\xfa8\xe4vq\xc5\xbd\xaaQY\xb6\xadJ\x0f\xf2_\xb2B'f{\xb2^C\xc0\xa5 \x8b\x9d\x9d)\x8c`\xe5\xc5 y\x19\xa2[J_\x17\"e]\xf2;+\xe1\xa0\x9e\x12b\xa43=z\xf2\xf5\xe3\xca\x0d\x9dQ@N\xdd\x98\xffyE\x93-a\xf8\xa8\"\xd3}\xfa$\xd4\x0c\xc5\x8d5\x9f\xf1\x10*\xe2;k\xc7\xcd?qku@G\xec\x92\x18\x86pl\xf3\xcblJ\x10M\xf3\xe4\x04z$TP\x8e\xd4\x9ac`\xfc\xef\xdd\x13\xbd\x98\xdaF>\x99\xa5\x13-\x83\xc6\x88>\x0b\xdb\xa2\xf5\n%\x01\xe6\x15\x11#$\xd2N\"\xd2IS\x95\x97q\xfc\x0b\xdb\xe2u\x02\x92$\x90.\xbc\x10\xaeh\x8d\xa5\x17_Zl\\\xa8\\\x15`\xc3f\x85hw \xd6\x82\xfe\x11\xe1\x95\x19\xde!\xf8l\xe1\x91\xbf\xe3R\xf94\xc2\x01[\x8e+}_R\xa9pMQ\x05\x80:\x8dRI\xe3\xa8*\xd5\x1c\xb9\xc9\xbe\xab\x08\xc2l\x05C\\A\xbe*lic~\xc4\xf7\xe0 \x17\xf0\x86\xfc\x88<0\xe8\xb5\xd0\x0e\xc7\x91u\x7f\xdb\xa8\xec\xd4\xce\"\x07\xa0aFa\xb1\x95$\x85\x07\xc7\x1f1T\xd4\x8d\xe7\xd7(\xa5\xbb\xa8\xb8\x92w\\Q\x10\x9f\xb7\"(R\xc3\x9a\x0bM\x06q\x07\xfc\x04\xc2(\x05\x7f\xb9\n\xc8\x92\x84)\xa9\xd2a\xe5\x06\xc2_\x91\xd67\x10\xb5\x01\xd5\xa2\xb6\x97\x13\xc9\x95\x8f\xae\xc6\x91d8eb\xad&^B\xa07\xd4\x96\x01:\xe0\x0b{\xac\x1af\x0f\x99 }1\xb6\xdfo\xd3\xfe\x98\xfft!\xad\xc9\x13S\xd3\x15\xbfOi\xec\x8b] 5^wI_0\xd3\xb3\x0e\x95n\xe9\xce\xc7%\xc5 \xa0\xa3?N!Z\xa5\xc9\xe8\x8f?Yn\xa9\xb6\x9e\x1f\xa3\x8b\x8c^([\xcc\x90\xb0\xcf\x15r$\x9c\"YJ\xf9\x1dP\x92N\xa3,U\xde\x908\xa6\x92;\x0c\xe1\\\xb9%\x80\xb2\xc3\xb5\xce\x88X<\x0b\xdb\x8a\xc2,\xa4\x03\xb5\xd8m\x92\x08\x88\xca.\xdf\x99\x1e%\xee.\xbc\xe4=\xd6b7\xd8\xa5\x17\x8c\x06,lk\x12\x10/\xccVB\xa7\xb6\x8c\xd6\xdc\xf6\x8d\xc4vn\x1e:\xd7\x96\xce\xfc\xd0O\x16\x96\x0bKm\xf14\xf6\xfc\xd0r!\xd0\x96\x8a\xfdy\xad-\xe5\xb3saB\x89G\xf5\xe3\x90\x92\xeaYM\xd9\xb9\xb6\x8cS\x9b\xb5\xe3\xa2\x85/\xde\x82E\xb2\x96\x10\xaf\xf5\xcf\xafb?-]\xbcn\xa9/\x91\x08\xe6\x9f\x04\xfa\xa8\xf8\xe6\xf5\x9d\x19\xaf\xa2qm\x913d\x86{\xd3\xc68P\x808^2\x18\x91x_\xe4\x11\xc2n\x14N\x88\x00\x0dZ\xbeu\xa3\xb0\x04e=\x9e\x07\x8d\x14\x174v\x15Mrz;\x01B<|\xb3\xbe \x9fs|\x92\xd5\xba\x8e\xa2\xe5\xc5\xf3\xa7\xf8{{\xbb8\xcf\xca\xb58\xfc\x8c+\x8cQ1m\x886~(h\xc1\x7fc\xeb\x84-\x06\xe3b\x17\xe8A\x8cx\xa8\xd1-\xac\xb9+9-3#\xd2\xda\x9c\xab\x171\x89M\xd0\x05\xa1\x12\xe7\xd4*\xcd\xadq(\xfa\xb2\x83\xdd\xees\xa9\\\"\x97\xe8}\xc4\x89\xbb\xf0<.Ux\n}Z\x89\x87_=\xb1\x0b\xfa\xcf\xe3t\xae\x04\x135\xf3\x82\x84\x00v\x0b1IVQ\x98\x10\x17\x84\xady\xa8^\xc0\x96\x96\xb8\xa6\xb4\xd3\xe1\x93C.\xa4\x8b\xedm\xba\x1b\xaf\x1b\x80(H\x15q\\8\xb7\x1b\xa9\x19C8\x86`\xec=;\x17\x14\xc6D\x17L\xb1f\x90s\xe3\xb6j \xcc\xe7Z\nb\xeehYO\x9bx\xdb\x8d\xc7\xc5\xa6\xdd\x9e\xd7u[\x1cva\x97\xfdnw\xf6\x0by\x96\xed\xc4\x9c\xf8k\xbbi{;\x00P T%\x1b\xfb\xaeb\xb2\"\xe1T\x00\xa5\x08P\xae\x96\xb0h\xcd5*\xf4\xee9\x9a\xf0%\x0cy\xf8\x1fcr\x06\x07\x90\xd9\xf2\x0b\xf4n\x92\xfe.[d\x95>\x1d\xc18tK\xaf\xce\xb0\x8a\x08\x1e\xad'x\x12*\x8b\x03\x9b\x1d(e\xfe\x80\xbdS\xb8\x02\x86\xf4\xfc\x9c 1f\xa1 \xb4\xfcn\x0fY\xb1\xe2F.\xe4\xb7y\xb6S\xb9\xd4\xaf\x18\xc1T\x18\xf3Z\x9d\xd5&*\x03\xf3\xda\x17L\xd4P\xbdL\x15\x8f\xc6\xc9\xa5\x90\xc3I\x89\xa3\x17\xd8\xa1\x0d_O?\xea\xd7|T0\x97\xbc\x9c\x07\xccfV\x1cBb\xe4exT\x96\x1d3H\xc5+\xa3t\n\xf6\xb95\xbcX\xc4\x9c]Hy\xc4YnH\xaf\x1f\xf8Vmp\xd2\xb8\x18\x98Y\x83\xedCy\xe6\xfa\xcd\xb2\xe9\xac\xf4\xad\xe4\x8a4\x16\xe7\x1a\"x\x02\xfec\x88:\x1d\x07\xe2qtf\x82A\xad\xc2\xb6b8\x04Z2\xb5\xe61\xdcNlR\x9c\x9f5:8D\x89LZl\xfeY\x97eg\xb03\x17\x9d\x97K\x80\xd8F\xc9\xa7\x8aM\x9c\xf9\x11 \xe4\xbf\xc6\xbd3i\xf7\x9a\x16\xbensF\x95\x1b\xd7:\x899)}Y\xb8Ap\xc3\x0d=\x861\x8a\xce8\x13'gm\xcc\x06h\xb9\xeaA\x10\x18\x8dRY\x84,)lVD\xfb\xf5\xb8\xdcJ\xa8\x07\xbc+*+\x91c\x8d\xcb\x11\xdd\xb9\xba\xf7\xecB\xa4\xa2\xc9\x89\x0d\x0eM\xb1\xa4\xec\x8a%}\xceq\xae<\x94\x04\x85K\xbe\xa6\x9b\x1c\xabu\xeb\xefM\xf3\x93\x0eF\nf\xb8\x8a\xaa\x18m;Z\xc4cL\xdb\x02:?s\x95\xa3\xa68eR\x85\xddo\xc4T\xe0f)eC\x13a|T1?)\xdf@\xbc4GP.\xa2\x9c\xeb\xec\x0c\x15=\x14\xe5n\x9b\x00U\xa8Z\xe9.b\x1c6\xf0\xc92\x1dG\xcd\x16q\xdc\x96\xfb\x08\x0fnd\xde\x0d\x16\x94\xca9R(\xe6\xf8W-\xa6{\x15{\xab\x8dN\xf7\x9a\x1b\x80\xb6g\x7fl8\"\xf2\xe3\xc1\x07?\xe4\xa2\x1d\xd7B4\x89\xbd\x94\x9c,l\x8b\xcefE\xa6\xc0\x85\xfb\xb0\xec/!t\xf1\xf5\x92s\xca,\x1f\xda\xb9A\xf1\xb3[\xbe>0i\xcd\xc0x\x8dI$S\xed*\xf2\xe6\x9a\x04\xce[\xe7\xb00&\x1e\x94!!\x84\xd3\x12(l\xbf4G&\xa7\xfa\x14]\xb6B\xc5o$W*\xa3\xa6^\xb2\xde\xf7\x99Ho\xab\x1f`=a\x95\"\xc4~\x9c\x9f\xef0\xa2+t\xe3\xb9 \xa9\xdb\xb2\x0e\xdaLJ>S\x14\xbb\xc6\xfe\x19\x94\xe3\xd2JR\x01/\xb4EE \xa9\x9b\xdc\xed\x1b\xd1K\xaa\x9bR\xe6\x9f\x87\x81\xadM\xe5\x07\x065\x86\xaf\xbb.\xd7qF\xf3\xfc\x8a\x11\x19$D\x82\xf98:\x93vz\xf7\xc2\x0f\xa7\x9c\xba\xd1\xa2\x1a\x8f\x9cT\xf6\xa6l\x86\x8c\x84B\xe7\xfc\xfe\x908\xc2\xfb;\x16\x14\xa7\x10#\xaa\x13\xd5\xd3\x9e6\xee&\x82\x84\x94|\xbb\x9b\xa3\xd8hL\xaa6rM\xd1Q\xd8\xd2\xc5Qu\x8e\xe5\xd9\xa1\xdf\xc7\xf9,\x8e\x96\xf4T\x86\x11\xbc\xfb\xa7\xa2\xac\x1c1\xdb\xc50\xd8\xed\x02g\x97bpW\xa3M\xb4iB\x1fNc]\x84\xbaz\xa4\x8dI\xeakO\xea\x1a%\xcb\x8dv\xd0\xe5\xcf\xb9\x1bK\x0b\xbb\xa3[_\xf5@\x93\x1bQMd\x01\xfc\xac\xa2\x9c\xd6\xbc.Z3\xee9t\xb2\xce\x98\x9b\xde\x01\xfa\xe0\x14\xc6\x9b\xed\xfbA8\x97\xb8\xd9\x9c\xe7\xf1\x85\xb8 |,\xd0Z\xc7\x00\x91F\xcf&\xe9\xde\xb420\xbb\x16\x02\xe5\x8f\xf9k;\x8f(\xee\xb6Ppo\xf1$\\\x07\x94-\x97'\x18\xb2\xd9\x85\xbaA\xa9/\xcb\xb0\xc2A\xe1\xed+\x9e\xccZu\x96A\xcc*\xfd\x99;d5\xd0\x92[\xc3\xbd\xafg\xef\xe2j\xf4\x85\x8a\x0b\xcd\xb4\xb6\x05%\xaa\xc3\xe7,o_\xfb\xadf\x04\x95ru\n\xe5\nL\x95U\xdf\x86\xb2\xa8\xaaO\x95B~>?\xf6\x9f\xec\xa4\xc8\xb0\x12#H\x84\xec\xd4\x9a\xca\xe1\xf0\x13\x12\xcch\x15\xfc\xf7\xd3'\xb8\xf2\xc3itU\xa5/\xbe>\xb272\x12&_&}\x00\x7f\xc81\xcd\x9f\x16\xaeS\xdds4\xc4~\x816\xc8\x06\xf0\x00\xf2\x9a I\xdf\xf9K\x12eiK)'$W\x10\xd9>;\xc0\x8a\xaf1\x1cB\xc1\xff\xb8\x80\x03\xe0\x85\x15\xb5\x05\xf6\xfb2LI\xbc\xf6\x82[v,>\xd7\xf7,J5]\xcb#C\xfdK\xe9\x83F\xf1\x873\xf9\xa8\x88\xad&\x96\x8fJ\xda\xd2\x98\xcc\x94\xec/\xec\x8d<_\xe5#l\xb7 $\xa55f\x10\x89\xdd\x1c\x0f4s&a\x1c\x05A\x1b\xfd\x90\x0c\x1d;\xa5\xcd\x05\x84\xff\xf9r\x8a\xd2\x87\xfc\xaa\x8a_\xb4\xb7,\xd4\xf4w'\x9d\xa9\xd6p\xb4\xb7s\x84\xf3\xe1$\xf5\xd7\xe8'\xda\xf5\xc4\xcf\xcf\xe9\\\x7f?\xc8/R\xa5\xaa\x1a\x8dV\x91bQm\x15FPl\x99\xe6\\ri\xf7<\n\xc5\xe4\xd9\x9dD\xfe\xb7\xee\xb2G\xe3q\xe5bD\xab}G\xec\xb9\xe5\x92L}\x16\x9b\xa5\x99\x84\x95\xbfP\xb2e\xb2\x01\xa95(\x0e\xe6\xac\x8b\\\x98\xef\xbc\x0d\x87\xa0|\xa3\x1dD\xb5Ni\x18\xe5\xe2\xe2|\xb8M\xde\x9a&\xde\xd9\x14P\xcdGU\xa2\x9f\xc8Q\x88\xea\xd1S\xd8#\xe1\x8d\x82eA\x07R~\xab\x99F\xdfDW,W\x8em\xb4\xfeF\x13\"kA>Zz\xd3\x1eV\x8eq\x90\x1a*l\xd7\xd7\xf0\x92\x89\xef\xd7\xd6\xb8\xf0C/\xbe\xae\xaf\xe2%d\x7f\xb7~$\x93d\xd0Ta\xbb\xa1F:\xeb\xef\x07\xa4\xa9\xcevc\xa5\xd8\xbb2\x94\x83\xe4\x9fm\xc8+\xd9hq\x95\xfbwWwxys\x1b\xf2\xfc\xe8\x18\x19Ee+\x90\x0b\xf7\x07i\xeb\x07.(`3\xff.\xae\xa3\xf8T\x18\x9e5\\\x03\x91\xc7\x8f\x9db`u\xca\x97F\xdc\x85V\xf8+\x9e\x16\x83\x846h\x08\xadP\x11Z\xa2#\xb4EI\xf1H\xd3\xc0\xdaM3 \xbc\xd4\x0f\xfb\x8d\xbd\xd7\xee^\xf1\x88\xbey\x9bM]\xd7nwhEZ\xa0\x05\x8d\x13\x8fP\xe9\x98\x87\xd5\xb8'A8X\xd4\x87\xd8\x12\x0f\xa5\xd96'\xdaez\xcdbQl\xf5\xb4\x9f\xeb4\x84\xba{I\xbc/\x13\xd12\xb6\xca\xc1\xc5\xed\xd213\x1a\xf1X\x85,\xbdQ\xd5'\xc4z\x1f^\x86\xd1U\x08\x82\n\x0c\x81\x0d\xdb\xa8\xc7`\x07l\x99\x12\x15a\x1d\xf2\xb8t:\x8e\xab\x05\xdac#)\xf9(\x92\xc6\xb06)\xe74a\xa0\xd3Dh\x04\xb3\x89k#\xa9\xc0\x0ef~\x10|\xe3\xa1\x96\xce\xbb}/\xb5X-\xcfkV\x9aW\xc0z\xdc\xd9\xa8\xc7Z\x84\x95U\x98\xcc\xfek\x04+\x96f\xdc\x96:^\x98$g\x10\xe3\x0d\xbc$}MP\xce\x16\x81\x11\xe9\xabwQ\x8a\x82\x92\xfc\xeeh\xe11\x8f:\xd9\x1b\xb0\xa4\x0c\xcc\x7f\xe6gUV\x13\xd6\xfa\xc9\x08\xfa\x83\x07\"c\x03<}\n{0\x1a\xc1>\x1c\xc0@\xbc\xd9\xa5o\xfa\xbbp\x00;\xe2\xd5\x0e}\xb5\xd3\x83\x03\xd8\x15\xaf\xf6\xe9\xab\x01\x1c\xc0v\x1f\x86\xb0=\xa8\x1d\x92g8>\x852\xb0\x98\xfev\x19DU!\x7f\x13\x07h\xb4;\x19<\xa4{\xd9\xee?\x1a\xc0=L\x0f\xebH\xb6L\xe5\xa5\xb0\xfe\x9f\xff\xeb\xff4PY\xf40*\xaas{A\xc91\xac_w\xb4\xea\x06\xd27\x0d\xa4_;\x10\xd0\x0df\xa0\x0c\x06\xffV;\x1c\x98:\x1c\xf0\x0e\xdb\x13O\xae\x0f}\xacC2I\x90\x08\xd1\xbd~\xa8`\xfd\x13\xc9\xd7\x0c\xa3y\xa1Wf \xe5qY\xe5}@?t\x94}\x91\xa7l+\xf3[nuS\xb1\xa8`\xb5\x1d\x89\xcb4y?\xe7#\xde\x96\x02\xa0\xd5\xef\xbdD\xab\x01\xa0\xebe\xa7\x85'\x10q0!\xf9\x08\x1dWjt\xf2\xc5\x0cs\xf2n\xb6\"\xa9\x0f\x03\x80\x97\x91\x93\x85\x17\x1fESr\x98\xda\x92\x07\xac\x1aWZ<\xb4\xd1\x98J\xdd{{\x83G\xfb\x80f\xf9OF\xb0\xb7\xbf\xd3\x7fT2\xf8Rp\xa9B\xd0v\x95\x85\xe3)\x9a\xc7\x12D\x06gj\x9d~\xa5N\xff\xcc\x85\xb0pS\xd7\xe6\xd9\xae\xbc\xd1\x9bxh\x89\xa32\x93\xbef&\x83\xe6\x99\xf41\xe5\x85v\xe1\n4C\xa8\xd7\"R]\xaa:\x90\xef\xc3\x0f\xa4\x03\x89]~X\n\xe5@jQ\xdaH\x0d\xf7@fr\\\xc3\xbdtL\x9bS\x82@\xaf\x1a\x0eL\xb7\x12\xa4\x1623\xed\x16\x13\xe3\xafl\xb3\x1d-\x91\xeaq_\x93\x83\xd2ZqV\x83\xbb\x9d\xd9*F\xec\xc06\xde\x94\xa8X\xb1#\xec\xd1B\xb1\x1a\xb5\xf8Qj\xfa\xb3\xf6\x83\xe3\x1a\x86_\xc2\xb4\xb0\x81f\x05w\x87j\xda\xadtP\x8b\x1d\xf9\xa0{.\x02X\xc1\xd4a\x036\xac\xcc\xcc\x8e\xe1|\xa8\x07\xc6\xa2\x86yj\x82\x85\xd4\xb0\xf8E\xca\xd1\xdcX\xc6\xc7\xa8d\x1b\xe4\xa7\xf5\xc2\x7faq\x9b\x9fA\xb9`\xa8\x80\x1f\x97\xcdU\xdd\x9e[\xed\x7f\xbfHB\x87\x9e\x989k&\x98x&\xe7\x18:\x06\xd9\xba\xf12u\xbd\x84\x02>\x1e}\xae\x9a\xdeJ4\xb2\xbd\x8d\x83\xa1\xab\xb7=`bv\xdd\xc0\x90\xb1\x92F\xe6\xb4\x1e\xc3\xe0\xf7\x1f\x03o\x0bC\xef\x8cD\xca\xbc\xf2\xa8v\xf4\xa3\x12\x9d\x97\xb7\x8f\xd9\xb0\x98\xe9 \xcb[\xbeJ\x15E\xb8~\xf5\xeb\xca\xf9\x16V\xa9\x8c\x1c\x9e\x01\xb6\xc1\x0e+\x94[\xbf1\xb4,x\x8f\xf9M\xeb\x86FKL\x1bFR/\xd4S\xcf\xf2v|\xa2!\xa4\xfaq\xd5\xf3Bw*\xa0(+p\xeb\xe1\x14bLy\xd2\x92\x04\xa3\x9cR\xb7\xba\x99)e?/^\x17\x176\x035y\x1f\xcfq\xae\xcf\xcb\xac\xd1\xae#\n#\x04J\xd9T\xca9\x13\xa2j\xda\xf0\x92\xc9}n\x8b\x91\xc6^\x98\xcc\xa2x\xc9\x8c1tn1\x18\x17\xfc\x9d\xa8\xd7\xc2r\nT\xaeY\xe9E/T\x85\xdd\xbcV\xbd\x1fG!\xb5\xe1y3\xb90\x0bi[qY\x1c3\x06\x0e`\xcc\x06\x85\xd0\x857\xb9\x14qj\x96Y\x90\xfa\xab\x80@\xea/Ib\x8cw/\x06\xb2\xc8\xc2\xcb\xdcG%\x1f]\xf1\x86\xa7\xec*L\xadx\x1aWW\x93O[<\xe2\x80apl\xe1}\xe0+\x86;\xb6_ k.\xecc\xe1 \xf8\x9a\xa8\x1bEW\xb6Z\\\xe9\xf1\xa6\xb0\x01\xd58\xdd\xd1\x8e%\xc4\xd1\xd9H\xcak\xae\xaf\xc1\xc1\xc8\x82]\x98\x8a)\xe8kk\x14\xdafZ\xa9|\\\xe8\xad\x97t\x0154\xd5\xa4P\x1e\xb5\x89E\xf2\x89J\x06O\xc5\xbb\x91\\\xc3\x9cgd\x16d\xc9Bj\x80\xfd=\x12%\xc2\xe4\x1e\x0d\xb6W1\xc9\x1d\xf5\xb2&\xbd\xa8\x8e\x9d\x12\xbe\x18e<\xd3\x8fL\x1a\xcd\x81\xfcW)g\x9a\x96\x19\xf3r\xdaZ^\x14\xcaDz\x9c\\\x15\xfb\xa7~\x1e\x9e\x89\xeb+\xdd\xa4hLH\xabLB)\xb1`Z\xc4\xba\xaf\x84 \x10\xe7e\xe5\x9e\xe3\xc8\x0b\x02\xba\x0d\x8bE\x9eF!\x81\xab\x05 \xe1*\xcf\xa8\xb45\x82\x9e\xa5\xe9?U\x89f\x89:n\xd8]\x92\xfaAP\xdajj\x979d4\xbe\x00\x85\xcc\xe6W\xf2\xaa\xb9\xd2;;b\xdcJ\xb4adw\x99@\xab\x93.Q\x90\xdc\xe9\xa9\xdc~\xc5\x97\xac\x18yy0\xa5\xfd\xd6$(T\x00\\|m\x080c\xec\xb6*\xc9\xea\xbb,{\x9a\xd5\x9d\x99(\x9b\xc8\x07\x0c\x85J\xe9\x10J\xf37\xd2m;qa+V\x10I/\x1e\xb5>r\xecXY#<_\xbe\xd0\x89sc\x04\xb1\xeaYP\x7f\xa9R\x0b\xdb\xdc\xe7\x84\xc8\x10\xc5[\x04\x01p\x16B\xb8\xc4\xae`\x0c&\x95\x81\xe9U\xb8,[n\xd4\x15M\x16\xfc/\xe9\x96\xb9-f@\\\xdd\x06=#$Z\xe6i\x90\xf93\x95Q\xac\xb6\xa6l\xb1z{\x0c\x96{=\xe4D\x969\x90\xab\xc4]!.\xb7b\xb5%\x9eZ\x97\x89\x17sH\xcaBQ\x14\x1f{\x93E\xb9\xa2\x94\xe2|\x12\x93\x12.\xb4K\x8b+\xf0*bDSKU\xb9\x0din3\xda\x04@Lgz\xef\xde\x06\x8c\xb6\x9e\x15DK\x97\x10\xbd\xd9\x1c \x18\x04\x10\xd2qxV\xa9|c\xf3\xb4\xb8\x18\xc9X]+\xb7\xa4h\x84\xdb.\x97\x16\x9e\x0e\xfc\xfd3\x9a\x940`\xc7iZ93\xcd\xf5\xf5\xab\x96\xbc\xf6^\xdb\x98X\x16\x95\x18\x84\xa9/\xf0\xe2\xee\xde=\xae\xad\xd8\xc6\xc4\x0c>\x86\xb6\x1e\xe6\x8e\x95x#\xd4\x9c\x1d\xb9\xd5\x1c\xcb\xfe7\xbb\x0f\x06\x8eM\x87\xc4\x91\xd6K\x12\x7f\x1e\xc2\x10\x8bv>\xd7\xa2\xd0\x05\xdf\xc5Tr.x.\xcf\xe6:P\x13\xa4N\x9aH\x0b\xe8\xee+\xe8#\xe7\xcc\x8f\xaf\x95\xaf\xf4\xaeY\x13\x17x\x08@\xad\x07\xd6$\ng\xfe<\xab\xc9$.\x985\xbdl\xd1\xe4\xc1\xb5\xf6\x82\x8c\x0cA1\x02\x96\xd6\x15&^n>V\x9cN\xec\xcec\"]\xe5\xc6\x15\xc9\xba~\xe8\xe6a\x97\x87\\\x8c\x84\xc55\xd4B\xd1\xdd8\xa12\xa5h J\xa6\xb9*k\xc4s\x06\xa60\xa4\x87>B\x86\xb1\x14\xe8\xa7U\xacR,_\xaa\xe0m\x11\xcfn\xfc\xe8\xa1\xe3b:\xd4\xf1\x19\xcbl\xdd@U]\x9d\x02\x9cr>\xde8=\xcb\x99y\xfaG\xb9\n\x92=\x82\xfd<\x86t{\xfb\xb1#|\\-\xcf\x82\x0e\xd8\x9dN\xe8\x14\x1a\xa8\x9d}U\xae\x97\xf4(\xc2i\xc2\xb6f!K\x98\x8bE\xb9\xc4a\xd3\x06 \x0fq\xef\x82\xe5@\x87\xfe\xef\xef\xa2\x8dY(\xbc5\xf1\xec,\xdc\x06\x1e\xc3\xcd\xe32\xcb\xd8z\x8d4\x14\x1f\xe5\x1b\xc3\x9a\x15b\x8f\xc2\xe7\xe0\xa9E\x9c\x8a\xea\xa1\xba7\xe9\x93\xd9\xe8\nU\xde z\xf4\x07\xdd\xed\xf2\xcd\xe7\x12'&r\xe8\xb2\xad\xeb\x91\xbeTM:\xe7\xe7$}s\x15\x8aj\xcfI2\x89\xfdU\x1a)\xf6\xd3\x99\xe9\x83\xd7\xdeR\x0dh\xe2\x99\xea\x9e^//\xa2 iq2i\xd7\x98\x91`~4\xc76Q\xf1\x14\xe5D\xb9\x06\x86\x18\xc8\xec\xc4\x11\xccN!~kC\x0d\xeaW\x1a\x9b\xb6\x99\x87M\xc4\xc2\x14j\x14?\xf2\xd2k\x9b@\xee\xb2\xfa]\x19\x81L\xaa\x0e\x0f0\x82\xdb\x7fY3\x91\xed{r ]/g\xffS\xb9\x95\xcf\xdc\x15}\x1d\xff\x1b\xda\x0fUUs\xa4w\x03\xa3\xdc\xe9mq\x94\x9ek\x9a,xt\xfb\xe4\xc4n<8\xd3B!Fj\x85\x0b$w\xc4\xd8\x10O\xb7\x1a\xe18>C\x07'\xe1H\x91\xa1<\"\xbe\xa8\xacH\xd8\x00g\xb9\x8fv\xfc>\x1f\xfa\xd6\x16W\xf6\xb1\xf0\x03\xe5\x14r\x9f>\x19\xb4d\xc8\xd5\x9b\xf4\x83\x0b\xd24\xdaVX\xa1\xe7\xa3\x88\x0b\xd6\xf99I^E\xd3\x0c\x0dN\xd4\xa5D>G\x16+Yt!/N\xc8\xf7\xde28BnE\x93\x16\x7f]D\x88\x0e\xed\xbdAO\x83q\xc8\xfc\xb0\x80\x0dq\xb7\x18\x04\x1c@\x0cC\xcd\"\x0bSS5\\p\xd1\xa9n`\xb5\xa8\xaa'\x0f|-#\x91\xe3\xaf\x9bx3\xf2M\xe4M+ \xacjID\xce3\xb1\xd0\xc8q|\x88\x03I\xba!\xb9zG\x89@x\x1c\xc7v\xa1IB*\xad\x1c\x97\x1bz\x916\x11\x84\x9d\x87\x06q\x88\x8e\"\xb6\xcbs\xf0\xc3I\x90M\xc9\x10\xc6\xa1=\xe8\xed8g\x12\x12\xfcC\x07\xd3\x1f\x0c\x9c3\x85\xb0-W\x81?\xf1S,\xdf\x1b<\xc0P\x06{\x83\x87\xfc\xdfG\xec\xdf\x9d\xde\x1dM\xe2N7S\x10y\xcc[\x99t\xdf\xbd\xf9\xea\xabo\x8e\xcf\x8f\xde\xbc~\xf1\xf2\xabS|\xf5\xfe\xed\xf3\xc3w\xf2\xab\xda\x9d6\xe8\xed\xfdN;-[M\xbd\xaa\xf6\xd2@\x165\x07\xf3\xf5\x8a\x0c!\xab\x9e\x10+\xef\x9a\x02d\x08v\xcf-\xb6\xa0c\xff\xfdF\xd5\xe2\x02(\x9a?\xd2M\xa3\xf9<\xa87\x0ej\x18\x91&\xabJ>\xa2\xd4\xd4uy12\xfd\xbaYL\xb2K\xce\x19\xe4\xac*\xaf\xa8Y\xff\xfc#63K^\x81\x1cod\xad\x89n\xaeU\xad\n|\x1eA!2\x12\x8dJ\x0ef%l\xec\xef\xa9\x0c\xc8\x97\xc2F^\xa7\x85b'\xa7\xca~\xc8\xe2:\x94\xd1\x8c}U\x1d\x04\xdf\xbca\x83\xae@\xa3i\xd8H\x17\xa1\x18\xac\xa0\xa9\x16\x8b\xde\x19\xba\x9br\x87\x94\x1a\x10\xf9\x1c\x18\xdeQy\xa1\x8f\xb7\">\xdd\xd1\xd6%\xb9N\x90\x91&\xdc\xa3\xc2\xc2\x1d\\\xbc\xc3\xe47C\x16\x14w\x1c\x9e\x9d\x95t.\xa22\xdeZ\x1e\ny\x05%\x0c\x0e\xe9\xd8f]\xa0\x91\x86T\x1d\xc3\xd0\xa7\xb1O\xff\xd2\xe2O\xa3haT}7~\xb9\xd1\x01\xcc \x9a&\x18\xde4\n))\xda2\x1ew\xb7\x1c\x9d:4\xbf\x1cJyK\x96\x87\x98\x90\xfc\xeezE8o\x0c\x1d\xb0\xc4\xed\xaa\x977\xbae\xba\xafn\x18\xec\x86\x9b\xf8\x91~\x0f\xef\xedj\xb7\xf0#\x95\x05\xcbP\x18.\x1a\x0e\xed\xc1\xbecg\x94\xf2\xec;\xb6\xe5\xa7$\xf6\xd2(\xa6\xe8\xd3t\x94\xa7r\xf0\xb2\x1b\xa7F;\xa8\xbb\xba.h&\x8c \xa6#\xa8\xe2EH>\xa6t\x13i\x12\x91\xd3\xdd\x80m\xe3b\xbc\xcc\x87\xbd\x19\xb0%\xf5\x84\n?N\x1a\x1fh\xc1\xba\xdb3\x93\xc0=\xe9\xea\xa3\xc4\x94\xfb$i\xca%\xe8W\x14\x9dEf-\x17\xd7.B}\x04\xe5\xd02N\x81\x98\x06\xae\xf7\x18\x85\xbd\x07;\xbb;\xbc\x7fV\x1f;\xa2\xc8\x82\xce\xdf\xf4-\xf3\xc2L\\\xecd@\xcb2\xd8\xe6\xcdt\xe88\xb7\xf9\xa0\x9e<\x81~\xcf\x81\x0e\xec\xef\xed\xed\xec\xdf\xcd\xa6\xaf\x1c\xa9\xfc\xe0\x18\xf4\x8dg\xea\xc0\xe9\xceI*\x0e\xf9\xe6[Y\xa4\xf3\xeaIjd\xf1H\x03\x8b\x87<\xd1E@L\x0c^l\x13n{\xe4\xdcz'\xf6w\xf4\xd7#\nOV\xa10(\xa4\xb5\x03\xdb+\x92.\xa2z\x034\xc9\x8dl\x0b\xa3\xcd\x0b\x9a:\xf6\xcf0\xc0\xc5\xd8\xfa\x97\x7f\xc9\x87\x83\xaf\xa21\xa5Ng\x9b\xcd\x9b\xae\xf6\x0eJ\xbb\xfd\x1d&\xf5\x0evv\xf9\xbfLM:\xd8ej\xd2\xc1^\xaf\"\x0e\xf7\x1f9B\x14o\xd3Y#C\xad\xc3G\x99E\xf6\xc7\xa1\xddwlK\xdc\xc6\xbf\xf3\xe6\x96s\x06#\xb0~\xc1L\x8d\x1d\xba\xcf\xb7F`\x8d\xd9E\x0b\xfcrf1\x1d\xc1N\xcf\xe1VK\xa5\xe8\xbd\xa2\xa1\xba\xb0\xdd\x1c\xf2y\x9b\x16t\xe89\x80\x01L;`\x9d\x95\x9c\xe3\xb6\xda\xe9\x07d0n\x85\xf6\xee\x80%G\n\xed\xdd\x1d\xc7\x1cx\x8d\x8f\xe4\x01\x9d\xa2^\xd7\x1c\xda\x8f\x1e9\xb65\xf5\xd7Tl\xb0<\xad\x19\xccF\x81\x86\x1fT\n\xd5\x9b\xcc\xaeW\x00\xa0\xd5\xe4%]\xbf\x89\xd0\xd4\xb3\xe6\xe8\xaa\x81'\xb1\xdeV\x813\xe9~\x95\xea\x10\xd3\x95\x9a]\x8e\x13\xc0\x96#\xe6\xb1\xc7\x05I)|\xd1j\xe9\x99\xda(\xca\xd4of\x9b\xb7\xb9\xf5e\x86\xab\x92X\xeb\xc8\x0b\xff\x94\xc2$\n\xd7$N\x81\xa3y\x1a\xc1*\xf6\x97>\x06+\xc4)l*\xd25m\xf7\x81\xe1\xfc\xe9\xef\xe8%\xe8~O\xe5_\xaa\"t\xff\x01\x17\xa1\xfb\xff\xaaE\xe8\x87\x86\x83]}\xcf\x01\xbb\xab\x03,\x05x\xcf\xb1\xad\x97\xc7\xe7oO\xde\xbc{\xa3\x1ez\x9e\xaa\x9e*\x17\xab\xda\xab\n\x15U\xba/F\x8c>?\xf9\xe1>/b9FxXV&\x1e\xa7\xdd\x17\x8f!F\x8b\xb3) HJ\xe4\xac7\xe3h\x1c\x9fir\xa6\n.W\x8d\xed\xaa\xa7\xa3%c\xe5rP\xc7v\xa6b\xbc\xbb\xdc\xca\x1d\xefF<\x05\xdd\xd1\x80\x1b\xd8\x0d\xad\xe7B\xb9\x98{\xe3\x8c3\xb4'\xc6\xec\x93hzVX\xc0\x8c$}\xac\xcf\xb2\x19\xdf\x16\xf1\xf7\x0c\x14\xc5\x80\xf75\x1c\x1b=\x92\xff5(\x8f\xf6\xf4\xa4b_wEG\x99\xc2\xbeco\xb5\xa3\x16\xb78\xd99\x80<.5T\xe9\x00\x82\xa8\xfaz\xc2\xcc7\xab\x10Gsv\xcfaJ\xa2\x8c\x19Z{\x08\x8b{\xf7`\"\xfc\xb44\x1f>\x96\xa3@\xe1j\xe0w\x94,\xe0Z\xb0d!\xff.\xb2'\xd8\xda\xa7OEk\xfa\x05\x9a\xdcv\x81vM<\x12\xb7\xe3\xb3~\xb1\x1c\xba\xe1\x90\x01|\x99\x1c\xe7\xf7\x8ev\xaf\xc0\xe0\x12\xc2\x9a\x18\\\xce\nS.#f\x96\xec)&\x10Km\xcb\xa2\xfb6\xb7\xfa\xbf\xedT*H\xc5pmWg\x9c@ \xb6I\xb5\xdb8\x95\x92^\xe2\xdf\xf4\x94\xff\x15\xe9)\x0d\xe4j\xb0\xa3\xfa\x1dD-8\x18\xc9j7?\xb1j\xcf\xd19I\xdf\x8a\x8aof\xf5A\x92s\x90pZF\xf7\x94\x0b\x11n\xabqt\x06C\x93i\xdf$\n\x934\xce&i\xc4r\xe3\x83\xe4\xb7_.=(\xff-\x1d\xbb\xc3\xf2g\x9c\x08\x1c@\x06\x8aG\xf3\x86\xe0\xef\xdfzK\xcaV\xc7\x9b\xf5\x9e\x1f\x9d\xc2w\x07\xfdH\xf3\x03\xdc\x15\xda\x97\x9e\xe3\xf2\x93h\x8f\x1f\xad(\x0e\x08\xcf\x94\xdd]\xc7\xc5\xfdLe\x03\x177\xed\xa4,\"\x04\xecUI\xb9\xc0\xf2\x82'\xe2~wQq\xcc8:==\xc9XN\xbe\xaa\x19\xc7\xd1\xe9\xe9)eH\x9f\x93I\xe0\xc5\x1e\x9da\xd5E\xe3\xe8\xf4\xf4\x03\x15\xafx\x13ji\xe0\x930=!\x93T_\xfe\xfc\xcd\xab\xdaB6\x17c\xf1\xbb\xe8\x92\x84\xfa\xc1?\xf7R\x8fy\x11\x92\xf8eJ\x96\xfa6^\xf8\x81a\xe4\x7f~\xf7\xea\x9b\xc3 8\x8a\x82\x80L\xf4S\xa7U\x9a\xca_D\xf1\x92k\xbb\xf5\x15N \xfd\xdeX\xe5\x15\x99\xfa\x9e~\x86\xaf\xfc%\xa1b0.n\xf5\xcb\xd7\xde\x92L_GS\xf2\xca[iJ\xa3\xa9a\xd5\xdfz>]\xb1\x9f3\x92\x18\xd6\xe5m\x90\xcd}\xcd|\xd9{\xc3pN?|\xf5\x0d\x1eC\xfa6O?|\xf5:[^\x90\xd8X\xfc\xd6K\x17\xa7\xc4\x80\x0b\xb4<\xf2C\xc3\x80O?|U\x87H\xa7\x1f\xbe\xca\xfdM\x0d5\xa2,\x9e\x10\x16z\xdeP\x83n\x94\xd3\x05!\xa9\x1e\xaa\xef\xc8\xc7\xf4]\xecM.\x8fL[%\xafa(\x8e\xb2I\x0e\xbb\xbc\xe4\x86\xa5\x0b\xf7m\x0cY\xc98\xf05<\x81\xa9\x904a\xdd\xe9\xe8\xf8\xd4k\x17\xe60\x82\xe9x\xad\x18\x9d\xd2g #X\x8c\xe7\x9a\x92sd\xe7u%\x170\x82sJ\xf1\xcfu\xa7\x11\xf0c\x18\xdd\x89\xed\x0bz\xf6~\xfa\x04\x9e}\xe1\xc2\xcc\x85\x95\xe3\xc2\xc58(\xde\x05,\x07s2\x9e\x9f\xb1\xe8\xbaK\x8d/\x03R\xd6kz\xa2\xc7\x0e\\\x8c\xaf\x99\x1a\x99~~\xedB<\xbe>+\xf4\x99\xd0\x96Z7*}\xb4>9\xf4\xbd\xe1~_\xd5\x05e\x82\x954In\xfd\x9d\x07\xfff\xf9\xf4_\x8e\xe5\x93\x99\xd7pl+\x0b\x93I\xb4\xa2\xd2L\xa22o\x1a\xa7m \xdf\x84f\x01\xfcq|\xc6\xae\x00\xfa\x0f\x1c\xdbG\xef\x8f\xbf\x9b\xf5{\x15I~\x1c\x9f\x8d\xd33\xc5\x89^;\x11\x93~\xbf\x16\xf5\xf8\xa2\xea\xc4\x93\xbb5\xc4j\xbfMe\xb7^\xbe\xa1T\xa6;\x11lV\xe9-c\xae\xf6U\xab\xa8\x19\xbe\xae\xdc\xed\x04\x8ckS\xde\xae\xd8[U\xc3\xb0`M\xab\xaf\xa7\x9ct\xa8\xd6\x91k\xf6~W\x1d\xca5\x17,\xd5^\xe7\xfc\xfd\xae\xd3M\x88\xb2e\x97\xbc\xad=\xc7V\xbe:\xe7,\xb1*\xd5^\xf0\xd6T\xf8\\\xf1\xf7*\x01\xfc\x88\x1cf\xae\x8fW\x8eE\x91\x0c{B\x12\xc5\x91\xf0\x18\x8b\xf8\xfd[\xb9\xe8\x10F`\xf1\x8fp\x87\xcf\xecS\xa5\xd77\xf5\xea\xdb\x9f0\x92\xde\x08\xce\xbb\xb3r\x01\xa5\x84[[\xf5\xaa]\xb3\x7f\x9d\xa0\x8e\xc7\xdd\x98$Q\xb0&\xb6\xba\xa6\xf2CX ZY\xe6\x19\xd1\xdd\xcb\xaf\x01\x93\x15\x99 a9\xab\xdd\xc3\xea\x93\xdao\\xc\x96v5\xd9\xfaA\xb2\x0394zl\xf1\xa58!?1\x86\x163_\x8a\xac8\x0b\x12\xdao\x1cY*\xab\x8a\xe55\x1e\xb27*\xf6\xbdl\x9c\xf3\xba\x9aX\x05\xa4s\xc4\xde\xc2\x98\xaf\xe5\xc9\xe4w\xf1,p)\x0e\xdb\xc1)\xa8\x89\xb4J\x7f\xbej\xa2s \xae\xb4\xd2\xee\xb9Q B\xcb\x14\xc7\x01\xf9Y\xe7\xe1\xbc\xcf'\xfa\x1a\xcb\xe6\xa4U\xa0J\x94i\xf7|\xcd\xe4\xc9>.e\xf7\x1c\x00\xe9F\x97\x18\x94e\xe6\xf9\x9ahc\xea\x93\xe0\xc5\x03\xdf\x1b\xcd\xd5'\xbc:E\xb8\xe6\xda3\xac=\x8d\x96\x9e\xdf\x94 \xc4\xb8\x81\xe5\xc7c\xc1.>}b19)\xec0\xdc\xd8[\xc6E\xd1\xbfF\x18\xa4t\x8b)\xf9=d=Fh\xedoc\x0e\xadY\x97\x84)\x89m~\x81\xe0\xd91\x8a\xe6\x94\xc5\x9du\xc9G?\xb5\xb9P\xbf\xd5sX\x1d\x8c\xb4\xb3\xe2\xe6\xff\x070\xb1?\xda\x16\xdfw\xdb\x93\x85\xe7\x870\xb9\x9e\x04\xc4b\xa1\xea\xe9:\xbe\xb4)\x06\x1f\x087\xd0\xd0\x85\xc4\x85 -N\xb0d\x08\x13;6S\x03P\xf7e#Xp\xfc[\x19\x9f\x1f\x9f\xc4\xc4\x94f[<75\xf4\x08\xc2B\x19\x1d=v \xb3\xc3q\xd4\xe9\xe8\"\xc8\x8a\x87n\x12\x1e\xe1&p\xd4p\xad\x9a\xde\xde6\xf6\xb6)\xfe\xea\xb1QF\xac\x1c\xe8\x7ff\xaba \x9c\"\x1c\xa7\xf2\n|\xb9\xd8)\\\x83Rm\xd0I\xa0\x12\xddS\xad\xb7~\xedJ\x9d4\xc2n-\x05S\xab\xc2\x85t\xcf1S\xb4\x8d?X\x184\x84\x01\xe9\x9e_\xd1\x02\xe2t\xcf\xd7,F\x1d\xe9\x9e',{\x04\xe1+l\x13\x86y\xa4{>\xe1\xc6\x94\xf4\xa0xe\x13\xd4]\xd4\x8e\xfcu\xbb\x91\xbb\x86\xc8g X\x9a\xb0{\xae\x0d\x05\x0f\x18\xec5\x9f\x14\xde\x90\xf39\x19\x8e\xdf\xfac\x17\x03M\xb2\x00\xf6bc\x15\x87\x1fL\xd0\x88\xe7\x82\xeefd\x1e\xa6\xe0\xa7 f\xaa\xa9\xa4\xfc \x9c_\xa2%\xd5A[\xe6 $!\xbd\xf9,<\xbf\xd2zGV\xaaM\x87\xba\x84\x82\xf2c\xe0\xca\xc5\xd3\x8ec\x11\xe6\xa1\xf4<~\x8d\x07L\x1f\xcf\xe6\x13\xfe\xfb.\xd9\x80\x93\"\xf3\xed\xadO~g\x88y\xc39\xfa\x87\x0c\xfd\xfb\x14\xbfC\x17\xb6L\xe3m7N>\xbe\xfa\x89\xb4X\xbf\x86\xb5\xbb1\xce\xbf:o\x85\xc9(V\xfc\x12\xf7\xfaq\xed\x86\x9d\xf2\xa8I\xc7.\x88Ma\xb9`\x9d/,\xc7\xc5t\x14\xae\x1c\xd5\xbaU\x14\xa3\xd4F4a\xed\xe6\x98\"\xfeT\x88K-\xd0O\xca\xf1\xb4\xcb_\xe6\x7f\xdd\xb8\xec\x107O\x92\xa9\xf9r\xce\x0e\xff\x92O^\xf6&\x91U\x97\xe5l\xe5\xebJ\xe5\x85\\\x991\x8a\xc5\x80\x9c\xb2-\x8f=\xd8\xddw\xecc\xd9\x86V\x1d\x1f [\xc4\xfc\x16\xa2\xdcO\xb6\x88uu\xac\x0b\x97-\xac\x8f\xa8\x0c5\xd2\x8a\xa9\xec\xca\x19\xf7\x06\x15\xb0\xca\xb5F\xe5\xd4\x83\x94\x92s\xe9\x07\xd9\x18z\x16\xf3?\x87\nL&R\x08_\x0e\xe3<\xf0\xa8\xa7\x96a*\xdfW|\x1e\x98\xb8>\x14\x12Jy\x9d\xcb\xfb\x08\xd1\xa5\xce.\x03\xca\xd6\x89L\x85\x90\x8f\xd3\x88C\x8e\x12.\xcd\xa4\xa0\xc6x\x1a\x8f\xab\xd8%\xb8\xc2\"];?Q\xf0z\xf45\xc6[\xc8\xb3\xf33&\x05KNx\x89\x8c\xcd\xe7]*s\xfe\xd4\xe6\x828\xc5\x93\xed\x18\x97\x13\x7ff\x94\x83\xe6\xc1\xe9Q\x8d-\x1b\x9e8.\x04v\xd0\xfd\n:\x10t\xbf\xc5\xff\xbf\x80\x7f\x86\xadK\x15!\xdf\n\xa6\xe8\xb8\xf41\xb3&\xb5eZ\xc1\xad\xdd\x1f8\xb6\xfcJD\xa3\xcb\x0d\xddY\xc7\xa7\xa5.%z\xa3\xce\x8d\x82\xa7i\x91\x05\x83\xf4\x93\x8e2\x81\xa4z\xea\xb9\xb9\xb4\xef\xb0\xe8\x9bzD\xab\xc0\xa9\x18\xae\x8dl\xd3\xd6\xa5S;j\\\xef\xa6a\xf3Q]\xd9\xf9\xe6\xc8\xd7\xed\x98'\x93i\xc0S\x05\x92\xf6%\xd3\xd4\x0fv\x1fJV\xf0\x95\xbe\x8f\xbb\xcc\xc0\xb9\x8b;\xc8~#\xa3E\xdd\xb4\xbc h\x9a\x92\xcc\xaa\xeaO=F\xb5L\xf6BxsQ\xaf\xbe\xf1y\x15\xb3\xca&j/\xa9\n::\xd6\xdc'\xcaO\xa4\xb7\x9b\x93\x1f\x8a\xe8\x86\x14\n\xf4YSZN\x8f\x91\xf6zV\xb4\xb0\x82\x11D\x9dN3\x07\x98\xd4\xa4p\x10O\xc8(/#\x81tov:n\xa1-\xa3\x18\x81$\xb2\xfd\x08\x01;\xa6\xacE\"\x98\xf4\xb1w\xc6(\xdf\xf6vFKb;l\xe2\n\x8dB3p4\x97\x9a\xd2\xd6\xbb1o\xf9\xa8\x8bG\x97oG\xddu\xdb\x83%\xf6&\x8d{\xf7\xae\x10\xdd\x8c\xc5\xfe\x06X\xbc9nUW\xbd\xd8vP\xa3\xcd\xd3\x88\xb7P\xbf\x02>[\x81\xd8\xf6\xebV@\"A\xf8\xf3V\x97\x83L\xe9\xa5N\x9dgp)\xdd\x1c\xa0\xda^\n \xc84<S l\xc4\xe5\xb6\xa6m\xef\x97m\xe2\x81\x8d\x9fIN\xb38Z\xdaQ\x83\xad\x0c;7\x07F\x90\xe8ma[[\xd6\x17\x01T\xb6\x8a\xb4\xe3\xaa\x86Y\xe8\xcf\xd5\xf7z~A\x02\x9c\x9e\xd8\xa0g\xbf\x06\xa6\x90\x1f\xb9MP\x85:\x9f\x00\xf10\x0f\x80\xb0\xba\x00\xe2\xd1\x9cj.\x0el\x83\xee3]\x1b\xa9\x1d\xd5\xdczk\xe9\xfa\x9d\xa4\xa9\x90\xc8\xa5\x9e\xcbV=\x00\"-u\xe2\xf4\xa6\xa2.\xe4~\x0e\xbb\xfb\xd2\xba\xc5v\xdc}\x0b\x1d\x88\xbb'5wJ3?\xf4\x82\xe0\xba\xad\xba=\xe3\xb7\xc4~\x1e\xc1\x9aJ\xc2\xe2\x0f\x83\xae=4\xddjk\x98\xdd\xca}q(\xab&\x8d\x96\xd7\xfc3\x8fRGT\x84\x95/R\xea\xf8\xab\xca2\xcb\x8f\xce\x9a\x8c\x8al\x94\xad\xf8\xc2\xe3\xe2 u6\x1a\x96\xf9\xae\xf2\x0b\xa2n\xc5\x7fD\x84?\xd8S\xb0\xf1\xb4\x06\x0f\xd3\xb85\x0e\xd2C0\xd5g\xe0\x86<\xd1\x97\xce\x9eV\xdcB\x87]\x82\x86\xed\xfc\xee\x7fX\\\xc68v\x88\x97$\xcd\xd7\xd2m\xe0\x19\xda\x83\xbd\x01\x8f=\xb7\xc3\xff\xdd-\xc7\xaa\xdb{\xc0\xff\xe5\xb1\xea\xf6x\xac\xba\xfd\x1e\xff\x97\x7f\xbf\xcf\xbf\xdf\xe7\xb1\xed\xf6\xf9\xf7\xfb\xfb\xfc_\xde\xce>og\x9f\xb7\xf3\x80\xb7\xf3\xa0\xcf\xff\xe5\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=\xe0\xed=x\xa4\x8d\x9d\xc7|j\xdb\xc0\xa2\x11\x8b*\xbeNQ\x1ep\x13\x8f\xe3#\x1e\xae\xb2J\x10\xe5J\xd1\x94\xa0\x17\xb0\x82xH\x06\xd1z`\x8b\xd9\xb5\xf71\x9eJ\x1e\x16#\x8f\x1dR!\x8fr\xa3M\x08\x9a3\xb4\xdc\xe4r|\xe6\xe2\x9c\xf3\xccPy\xa4\x9c\x8c\xf9\xe9\xc6\xf0\x142\xb3v\x80g\xb9\xeb\x14\x99\xa52\x8c\xa2\xe3Sj\xd2\xef\xf7w\xfb\xfd\xbe\xc3r\xf7\x8a;\x91\x13/\x9c\xf3K\x11R\x8e-\xbe\xf6\x02\x7f\n\x93hJ`E'c2\xab\xe4w\xd4\x04\x9e\xb0H\x9dp\x80\xb1~0B,\x8b\xe4\xd9\x01\xdb&\xb0=b\xe5\x0e<}\n\xfd\x1e\xca\x14\x7f\x84~o\xb0\x0b\x1d\x16\xffS\x97|\xcc\xb4'C\x9eSP\xcd\x9c\xbb\xe1\x8ek\xc22CT -\xa52`D\xec]\xb5\xc7\x03\x16;\xa3\x1b{W\\\x10\x8d\num\x1dnP\xcc\xf1\x18\x8e\x84\xf0\x14\xbc\xc7\x0edl]x\x08Z2\xf6:\x9d3\x07\xe3D\xdc\x87\x9eF\x8a\xb0\x8e\xa2,L\x0b\xe7\xac\x90\xcc\xbd\xd4_\x13U|\xe0\xc1\xf8\"x\xaa\x1ar\xf1\xc7\x8e\xe0\xe9\xd3\xa7#\xe8;\xdc\x9b\xb53B\xc3#zb2\x07\xd7\x90\xbdz\xac\xac\xd3\xef\xa7\x84\xdb\x948\x17 \xda\x9a6aQ\xb3n\x1b\x16\xb5\x9a6\xa2\x8eD\x97\xfa\xd0\xad\x00\xe2\x88o\xe7\x84r\x93\x1d\xea\xe6\xe1DM\x99/\xe2[\x10\xd6\x18\x97\xad \xac!\x15\x92(\xec\x84E\x0b%\xac\xf1g\x11\x07\x93dBW\xc5\x0b'\x8b(\xdeH2\xa9\xe5\x06\xf9b`\xd4z+\xf4\x96\xc4\xaaK\xec\xf9\xd9\xc3\xbf\xf0\xe7\x1b\x8d\xbd\xcd\xd0Y\x9b\x16\xfe\xf7\x05G\x1e\xf8\xe1\xe5\xdd\x8f\x9d\xb7\xfa\xc5G\x1f\x05\xd3\xbb\x1f\xfc\xef0\xf0\x99\xff\x91\xdc\xfd\xc8\xd3\xf4\xf7\x18z\x14\xa6\x93(\xf8\x12\xbb\x956MG/\x9a\xff\x82;\x96v\x95\xf8\xbf\x90/7 \xde\xfa\x17\x9c\x83\x9fz\x81?I6\x9aB\x9b\x19\xf8\xbf\x03\x16mLvZ\xc1\x1e\xc9\xfd\"&\xb3/\x0b\xf8d\xe9\x05\xc1F\xa3o3x\xd1\xea\x97\x06=}}\xb9\x19\xe2\xb7\x1a\xbeh\xf6\x8b\x8f?\xbb\xb8\xfb\xc1g\xbf\x07\xd5O\xb2\xd5\x17\x18\xf9\xea\x8eF\x1e\xda\xfb;\x8em-\xbdt\xb2\xb0\\\xe8\xd7\xd7\x96\xc62\xce\xebi\x15\x9dz\x88\x88GH\x02i\xddE\xa2/+\x1aP\xcf\x90\xe7_\x0b\xc7\xc4\x9c\xdaB2\x9b\xf7\xe1@\xd8\xd81\xcf\xa8!\x9a\xb7q}n\xe8\x8c\xc9\x99P\xd8\xc7\x95X\x1f\x10n\x9a\xd5\x9f\x03\x93\xeb\x14-\x17\x06\xb7\x00g\xecV\xdd.\xa0\x15D\xa3&\x88f%\x88\xc62D\xe3\x96\x10\x95\x04\x88\x18C\x95\xf9\x08T\xf6\x86\x832rX\xe8\xa5;\x03hB\xbc\xf8\xdf\xd0\xf3\xce\xa0\xb9\n\xfcT\x8b\x9c\x15\xcbI3\x98\xc4EFh\xf7wUc=\x10z\x8f\xeakv\xb9\x867eU\x8d\x885A\xe3\x14\xcb\xbb\xb8\x98X\x92\x89mYt\x8e\x1a\xa4is\x1d\x02\x92%\x9a\xd0\x01\xe8\x03\x01@\xd9\xd7f$\\\x8bx\x12\x9d\xdc\xceMM\x86\"\x7f\xbb\xe5\xcb\xa9\xd3\x8a\xa8x8:\xfdgkf\xc2\x9f\xb80\xc1p\xd3\x01\x0b\x8b_\xe7u\xbe`\xa1;\xfdy\x18\xc5\xe4\xc8\xc3`}\x96o\xc1\x90\x1ey\xd0\xa1e\xcb,H\xfd\xc0\x0f\xb1hY*\xcaB\x1f\xaf\xda\x0f\xc0\xcaJ\x05I\xeaO.\xaf\xe9\xfbk\xfe\xde<\x84i\xbd\xd3\xfb\xba\xbc\x9a\xb4\xb3\xdd\xc1\xa3\xddG\xfb\x0f\x06\x8f\xf6\xd0\x8e\xff\xe9\xd3\xa7u\x0d`4\xd9b\xbf\xa7\xdd\x04\x83\x9c\xbb\xb0\x80\x0eXs\x93\x85\x00\xaa\xfaX\xf0\xaa\xb8\xdc\x02\xbb\xcb\xbc\xe6\xed\xd0F\xfe`\x1fl\xfd\xf0C\xe2X.,t\xd7\xd0\xf9\x83\x0e\xec\xd7\x0c\x17y\xc0\xce-\xdb\x9e`(1\xd4*C\x07\x92q\xef,\xc7\xf0\xa70E\xad\xe1\x8aG3\xe1*\xa4\xa9+>p\x1c\x17\xb6\xd0h\xbf\xa4\xe0\xc2\xc4\x1f\xbd\xb3\xfc\xe2-v\xebY\x9f\xd2\x83S\x0f0\xd0\x00\x04\xf0\xa4\xaa\xe4\xde\x86\xc1c\x08:\x1dG^\x99B\xa3\x16\xa0\x15\xaf\x8d?FZ\xe5w\xe9\xb9q\xdc\xea\xe098\x9e\x141\x15\xf1\xf2\x9f9\x00\xad\xe8\x07\x0c\x12}\x87g\x89\x90\xc0\xc6b\xc5O\\X\xe5\xad\x8e`\xed8\x8f\x1d\xb8\xee\x06^\x92\xbe\xc4\xb6\xf1>\x83\xf7s\xef\x9e\\\xa4\xc6\xf4\x16\x0f\xdf\x8cSv%S\x84\xf5\xde\x9a\xb1\x06(\xc9\xc4,<\x9f>\x01_1\x96\x93G]>:\xe8bp\xb0\x86\x03X\xf1\xb2\x9e\x0bk\xfc\xa42\x02\xc5,\x99\xb9*X=A\x1a\x85\n\xb3\xe7H\x10\xb3[Q\xb6\xf2\x99\xa9\x92+8\x80\xf1\x19\x0c\x05\x0d\xcau\xb1\xaa\x14\xa8\xd7iK,\x82\x81\xe5\xba\x05Su+>@b\xaa\xc2\x82\xa9\x8a+LU\xa8c\xaa\xe2M\xd9\x80z\xe5|f\x87\xf6\xe0a_U3\xfb\xbchg0P\x8b\"^\xb4\xd7\x7fHIL^&\xc6\x80A\xf1\xf5\\\x1a.f\xda=?'\xc9\xabh\x9a\x05\x18G\x1e\x86\x9a\xa5\x98\x92\x99\x97\x05\xe9P\xbd\x9f\xff\xa7\xea/q\xd2\x8e\xfd.\xff\xca\x85\xa8\xf8i\xa46|L\xd5\xbe'\xd1r\x15\x85\x94\x80\xe8F\x06\x98{B\xf8.}\xe3]GYJ\x17\x8fw\xd8\xb4Y\x8a H\xa8\"_Ny\xb7_S}\x8eW\xe2\x82U@\xbcr\x0b\xc2\x03\xc7\xcb\xe1\xea\x9d*\x9aLl\xca\xf9=\xd4\xa1 \x16\xed\xf5th\xc2\x8a*\xc8\x95\xe5E;j\x91\x97\x17\xed\xabEI^\xf4@>\xda\xf0\xd5\xfe\x9e\x1e\x15'\xbf?*\xcej/\x18\xf3\x91\x91:\xc1\x9f\xd2\xde\x1c\x9b\x1dN\xe8\x88\xe3bA\xa6\x16\xd8\xa4{~\x8e\xce\xe7\xe7\xe7\xc8&\xf4\xdc\x02\x1f\x1d\x9b8\x0e?\xadX\xf5\xfcxTE\x0c\x1d\x98h[\x9e\xd4\x96\x0b)\x1fFTz;\xae\xce\xe5\x92\\\x0f\xc1\x8aI8%\xb1\xe6\xa6\x94\xe3]#3\xb0\x96\xf3c\xac\xe2he\x88?\x03\"UFwN\xd2#\xb1\x85\xcduYd\xf0dE&,!P\x14\xd74\x1c\xb3\xd0\x1fq\xdc\xa2.\xdd\x13\xc4\xb6\x8e\xa20\xf5\xfc\x90T\x1cn\xe4'buO\xa2\xab\xbaZ\x99h1\xa8\xab\xe5\xb1Z\x18\xb57\xb10\x9c\xa9\xb9\xf2\x84U~\x17\xad.\xbc\xb8\xa9\xf2\x8cU~\xe6%\x9c\xde5}\x10\xb0\x0f\xa2\x90r\xeb\x1f\xbc\xc0\x9fzi\x14?\xf3\xa6s\xd2\xf4)&t\xe8\x06\x917\xf5\xc3\xf9i\xea\xa5Y\xa2F\xb2\x97\x9f\x05z/S~\x89\xdd\x9f7\xb0\xf7\x94GZP\x04\xb1\xad%I\x12oN\x90+\xb24J\x01(6A\"P\x9d;T\xf2\xdcQ\xb6o\xf2\x94\xa4\xcf$\xf0\x92\xe4\xb5\xb7$C\xb0\x92+o>'\xf1v\xe6[\xda\xfa7.L\xe0\xc0\xd8\xcf\xc4\xc5$l\x0eO\xc6\xe6\x82\xc5\xe1c!_\xb4b|\xaa\xfe[\xcc\xed\xddv\x9c~8\x8b\x8c#\xbc\x93\x1e\xf8\xc0\xb7'\xf9\xee\xf8=\xba3t\xe2`\xf8\xb7\x99\xe7\x07d\xfa\xaf\x12\x94\x8b\xdd\xd6\xbd\xa5~\x1a\x10c\x0f\xd6\x0b\x04\"\xa4\x11\xd0a\xc1\xe1\xdb\x97\x80l\x88Oi{\xd7r\xcc\x83\xf08rKkq\x84\xae\x95_dE\xcc\xe4\x013A\x9b\x18>\xf1,\xbd\x8f\xdf\xfa\xd3t1\x04\xeb\xe1\xc3\xde\xeacM{\xacz<\xf7\xc3o\xc8,\x1d\x82\xe5ei]\xffE\xfd\x13\x7f\xbeh\xf9AJ>\xa6\x87\x81?\x0f\x87`M\xd0\xdf_\xbfDP9\xdf\xf3\xb7\xff\n\xb01&\xcb(%\x85\xc7n#NZ+\xcb\xe5\xa4v\x8a\x88\xb9\xb5B\xe5_\x92MD,\x8c\x06\xcc\x9cq\xac6\xf7\x11\x89\x1eL\x15\xb2\xa6\nA\xbes\xaa:\x0dE\xea8+\x85H\xba\xb1\x8b&sNIb\xa9\x89(m\x1bl\x8a\x8a\x90;\x15\x8f\xa5\x81\xd3\xd5\xe6Am\xd3\xa2d\xdc\xa7\xcf\xff\xd6\xdf\x91\xad\x96\xa9p\xf2\xc8\xb1\xadrGV\xb3\xf4g\xe6\xd4\xa5J\xbe\x92\x86\x14\xe06\x17o\x83\x87{\x1a\xc1J\x02\x93^\x1ely\x01\x12\xabb\x9f\xa8^\x8c\xb3\xcd0\x8ba\xf5U\xeb\xce\xc2\xabk\x8b\na\x94\\\xb3qWvmy$C\\\x1d\xa7;\xdb\x10b2\x10*\xed3\x89\x8c\x02U\xbd\x8d($\xbaas\x0e\xb6\xca\"=b\x0ey\x0f\xf7\xaa\xfew\xbd}\xa7;\x93\xfd\xe8\xdb\xb4\xd8r\x12\xaa\x01\xeb\xe7Mb\xf0\x88\xbb!>\xe2n\x86|V\x83G\x0ft\x9b\xf4\xf4zy\x11\x05m\x9an\xb2\xf34\xd8\xe1\xaa;\x98\xdby\x1a\xbc\xad\x0d\xce\xd6\x03\xb5q>\xfeG}\xa7\xfb\xf5\xf1\xf7\xe5\xb2 /S>\xe1\xa9\xe5\xd4\x1eXj\xb9G\xeaxXn\xb9=\xf55\xcf-\xa7\xbc\x9d\xe6HR~\xbf\xe6\xefU4\xbd\xe6#T=\xe4\xe6\xfc\xbd:F\x9eV\xae\x82\xed\xec\xb5\x1a\xfe\x92\xa5\x94\x1b\xe83\xcaU\xb0\xed#\x9b\xa8\x1a\xfb\xee\x94\x81E\x95\xd6\x8e\xf9\x08\xd5\xea\x87|U\xd5N\xdf\xb0\xf7j\xf5\x9f\xf0u\xc5\x0d\xf5\x12Fp\xa8\xe6\x90{ #x\xa3\xbe|\x85i\xe1\x94\x97\xefP\x1ed\x18].9\xc2\x92\xbf\x9c\xbey]~\xff\x16FpD\x8f\xf2\xa3n\x82\xaaW\x7fv]\xaeqB\x05G\xdb:_\xf8\xd3) U\x11\xfc5+M\xa3\xb7\xb1\xbf\xf4\x99\xadv\xb9\xc67\xe8\x00\xa6\xcd\xb9_\xae\xf8\x9c\x92{\xdbJp\xf4\xdb1\x99\xfbI\x1a_\xab\xcd\xfd\"\xd7\xaa\xa4\xb9|\xc1J\xa3\xd5\xb6\xa1\xc2{M\x12\xf3r\x8dg\xa6\xf8\x01\xef\xca\xf5~F\x88\xfe\x955V.\xfa\x1eF\xb0\xf53F\x0e\xffY\xca\x08\xa0\xfc\xdd\x9d\xf9\xe1\xf4h\xe1\x07\xd3\xf2\xd7\xdf\x02\x8f\xf18\xa9w\x8d\xe3G\xdf\x03\xd8\x1a\xc1\xa9\xfd\xd2\xfe\xfb\x0d7\x0f\xd33\x91\xed\xe2\xb1@\xd1\xf0K\xd9\xe4\xac^0\xe0\xda\xac\x07\xc6J7N\xd7\xd3\x16V\xd9\xf2\x1bG\xad{\xe3\xc8\xd1\x0f\x0c\x8c\x00H\xa4\xf8\xd2~\xaf\xbf\x9dE\xd7\xd5) HJ\xe0\xfd\x98\x9c\xb9t\x92\xbc=\x1e8,\xc5;\x8a\xf7\xf4\xe7Kl\xa6\x12 \xf9\x06\x86\xf0\xb2\xbcd\x1fj\xb5\x9e \xd9\xd0\xff\xc2|\x0dO\xedw\x05\"\x98\x0d\xd8 K\xa5\x9bV\"|\x96\xbb\xff\x1aF\xf0\x8c\x8e\x98o\x8b\x12\xd6v\xc5\x91]\x02b\x0dBi\x1aI+\x00h\xd5R)\n\xf3\xbb\xba\x19|\xd5\x82\xd5+5<\x12\x8b\xf4\x95\xfd\"_\xc0%\x8b\xf2\x0f#\xb8\xe2\x19\x8d\xe8;Z\xe2\xdb\xbf\xe0\x9d\xdb\x01\xc6c\xc8 \x10f\xe4\xa3\xfd\x9d\xb0\xbc\x93\xe3\x93\xb31a\xb7\xa6\xe2\xf7\x88\xe7\xa8\xc0E\x0bM\x1b\xa1hr\x08\x1f\xed\x1e&\xb6\xd0a6\x0c\x8b\x0e?}b\xd8w\xe2\xc2G\xbb\x8fyv)\x7fR\xf4K\x87\xffm\x0e\x0d\xfa\xed\xcb*_\x0bU`\xfe\xa1\xcd]\xe3R\xeb8\x91;\x93\x87\xcca\xfc\x9a'\x82#th>K}\xc2\xa21\x8a|\xdf\x11<\x05\xff\xb1\x03_\xd9)\x83R<\xf61n\x00\x19\x87\xba\x10\x96b\x05\xeb&\xf0\xe7\xd6\xdb\xe9\x9b\xd2](.|\xcaRY\x19{\xde\xc2\xda\x05\x02!j\xb0\xbc\xa3[>E\xa6\x94\x19\x04\xd8[6#\xd9\x85\x0b'\xff\xf3\x17\xf1[\x94p\xecY\xf8 ]\xbc\xf4\x0c\x0b\xd5k\xd9\xf2\x14\xff\xd2f\x8d\xfc\x19s\xdc\xbd\xd0\xe0\xb5\xa0S\xf9\x90\x08\x1f\xd2\x0b\x16bY\x8f\xa7\xc2n\xe6\xd2\xae\xb1_\x11\x80\n\xab\x8dW\xb6\xca\xa7O\xca\x8e\xe2x[\x8d$sS\x07\x8e\xbf5\xae\xb8\x1a\xee\xe2\x95}\xc1\x9c\xa0c\x1e\xc1 \xe2\x11\x0c\xba\xa5\xdc\x8fl\xf4\x94\xd9b) qe(e;\xc9\x7f%,T#\x0bDa\xc6\x9b\xb8n\xfc\xdfm<~N\xc2\xd8\xf8_a\xe0\xa1\x170\x04>\xa9\x88OJ\x84\xee(&\x95=v\xc4\x9a\xe0f\xcb\xc4\xacB\x8e\xc1\xef\xc5jElJ\xbf\x8cI\xcd>\x8c\xca\xb3*\xea=\xc3\xa5\xf5l\xfb]]\x14,\xc4P\xba\x9ddB_\x0d\x99n1\x96\xb4\x88\x0f\"\xe5(\xaeDN\x17W^+\x9d\xcfX\xaf\xe43\xd6\x93\xbc:\xdd\xca\x14\x89\x94\xd3\x01\xc9\x19\xa9\xac4\xca=\x04\x9b\xf4E)K\xc4\xffOr\xd3\x87\x98\xb4\xe8/.\x15Q`\x04_a\xc4\xa1\xbd]\x07\xff:\xc6\xff\xff\x8d\xbe\xdb\xe7\xaf\xfe\x8c\x15z\x0f\xd9_\xdf\xf1\xf4\x97[\xa1\xfd\xf0!\x02\xd5\xa3\xb3\xb7t\xe2\x82\xe5\xd2\x8f\x91\xbcL\xbb\xf5\x17\xcd|\xbc\x1f\xecEIuE\xc7\x9b\xd9\x19&B\xca0\x11R\xc6T:\xcfTh3\x84\x1dJ\\\x8bl\x17\x90o\xe6\xbfRaa\xe1%/9\xfa\xbb~r\x14\x85\x13/=]\xc5\xc4\x9b\xa2\x90#\xf8/\x17\xcd\xce]n\n\xe623_\x97\x87rt\xd1x\xc8\x95\xe4(W\xac\xcb;o\xee\xca\x99\xfd\xb9\x9d\x91\xe5Z\xf4\x18H\x19\x85\xf8k\xb1E\xd2\xf4\xb1\x03\x0b\xfb\xaf\xe34-'\xbd-HP\x8a\xd9J\x16\xdd$\x8dbB\xa95o\x85\xa4E3!mfm\x93t\x1c*\xedP\x08\x9e\x96`\xc7\xf7w5\xa0Q\x14\xb7d\x15}\xfb9=\xd3:#4^<\x80\xe7tO\x0d\xd9?\xa3j\xea]\x85\xfc^\x92\xeb\x17\xcd]\xa19\xe7\xd7h\xceY\x9b\xd3\xc1\x03\xc6\x01W(\x13\x94\xc3\xed\xf8!<\xd7\xdb\xd3\xd1\x9e\x9e#\x177\x92\xe3\xbb\xd72\xf1YBNI\x9a\x92\xb8AJ\xfb^\x17I\xb2\xd2\x92\xbf\\\x05M\xf6\x05\xdf\x97\xb3\xd7\x01\x94\xf5\xba\xaen\xa1\x0d:O\xa6\x9ao\x91\xca\xaej\xe2F\x99\xf0S\x1b\x93\x96\xfd\xc1>e\x9cN\xedb\xab\xfa\xd5\xafj\x8a}\x92\x0c\xe1\x0f\xe5\ns\x92\xbe\xb9\n\xc5\xf7\xcfI2\x89\xfdUJ\xd1\xe7/u\x15_{K\xda\xd8\xdf\xea\xea\xb0m\x90\x0c\xe1\xbb\x12\x1cQ\xc1R\x06\xa6\xbd\x85\x07l\x8d\x88/\x8e\xc1wjxL!\xa6\x8d\xc3,\x08\xce0\xfe\xcd[[p\x9d\xd6\xdfo\xf8\x9b*\xec\xbd\x8a\x11\x8f\xf2 [\\\x85b:.X\x7f9}\xf3Z\xe3@\xce\xf5EM\xfb\xae\xc4\xfap\x86-=\xe3Y\xe4\x1f\xebb7P\x81\x82sd\xc5a\xef\xebSx\xf3<\xaf\x9c\x1d\xea\x9f\xb9`\x9f\xdb\x95\x94?\x9c\xc1\xffZ6\xe6\x9e\xf3j6i\xc3\x8c\x8b\xbe\xb4\xba!\x16\x1a\x08\xf9\xcc\x8au\xa6\xe3\xd2~\x89c \x03\xc0\x91\x84\x8e\x9dN\xc3\x85\xb7\xdc`\xe9\xa8\xaaz(\xa1\x95\xa4B\x18\xbfFV<\xb4\x07\xfb\x8e\xacZp\xe1u\xa9\x1eK\xc2\xf2f\x86\xd9\xe4\xde\x15\x84\x1b\xff~\xe5\xa5\x0b\x17,\xfa\x0f\xb7S\x81\xc0\xe6J\xc3\x1c\x07\xb6z\xad4\xff\xd2\x0d\xd6\x9ec[K\x92z\xba\xd0\xbb\x1a\xe5m\xa4\xd7\x9a\x8b`\xa4\x8e\xaa\xf3\xf4\xaav\xebI\xa1\xe4\xf3\x93\xe3\x8f) \x13\x9f\xca&\x9f>\xd5\x13D!\xf8\xd4R\xd7 \xa5\x9a\xa8]o\xa5\x9eK\xec\\\xddH\xd6$L\xf9p\xa20\xb1\xa9\xc0\xaf\xec\xc7rW\xf5<\x0e\xe0Q\x9c\xa2\xf7\x91I\xdaC\xb5\x9c\xbe\x90>\xfe\x10\xac7\x16t\xa0\xd3\xf1\xaa\xbc\xa4x\xae\x86j\xb0Z\xf1\xe8\xb4wu\xb0\x0b\x94\x1cR\xd5\x91}}\xfc\xbd68\xf9\xeb\xe3\xe3\xe7C\xd8\xeaWKf^\x92~M\xae[\x9c=\xa0u\xe9\xd0\xa9\xbb\xb85$s$e\x86Fr\x99u\x8a\xde\x14o\xd1\xcd\xc2\x90C\x81e\x01\xc0\xe51J\xe3y\xbd\xa44\xa0\x17\x06{\xac\xbcz\xe1\xb9b\x1d\xd7\xd4\x9d\xa9\\\x93x\xf4\x8b)x\xfcq|\xd6\xad\xe6\xce\xd7\x84p\x9b\x93\xf4[\xe2]n\x02\xf9[\x01dK\x1f\xe3\xa5\xa8M\x8c\x11\xab\xe5\xe73\xc0q\xd5\x06\x1cQ\xf8\"&\xe4\x97\xc6d\x82P4>\xa1\xc7F\xd0\xa5\xc8\x8d\xe6\x146?\xa68\x98\xe8\xef\x19rD\xed\x0c\xab[\xd3\xe4\xca\xbd\x93\x08\x19\xa4'\xc6\xfb\xa6\xe4G\xe6\x89\n\x05]\xac\xcd\xd4\x16\xb2\xc0\xba\xe5\xb5\xc2\x83\xbc\xbaB9\xf7\x90\xb9\xfc2\x94\x02\x84\xf6\x1eug,\xa1J\xef1x\x05\xf30y\xec@\x92g.\xa7\xe7\x867\x9e\xa0\x96\x04\xe5{\xe4*2=O%\x19\x89l\x06\xd0\x87\xfb\x06\x08\xb1\x08\xef~\xc2RY\xc9\x07\x90If\xb5\xb0*\x92\x9c\xd8\xbe}\xa6\xab\xca\xed'_\xe2\xbd\xea \x1a\xb1\x1b:!oV\xcf]+b\\\xbfD\x06\xaf\xfcp\x1a]Q\x88\x16\xbf\ns\x17\x95m\x86\x83\x9aB\x9b\xb5@\x05\x80\xb1\xce+\xa0\x9d\xa8\x8f\x81v\xad1\x1b)|\x8bM\x9e\xe1\x88\xf3Di\x8d\x17 \xe6\xbc7\xb9\x94\xaa!!\xcd\xf9\xe3\xc5\x10\xb9kQ\xa3\xbd\x92\xcdS8\x97\xedn\xf4\x08\xe0\xc0\xdf\x1b-\"\xfa\xbd\x07\x8emy\xc9u8y\xb9\x91\xfd\x86\xf8\x94%GA\x1dL\xab\xef\xda\xd9}<\xba[\xbb\x8f\x9d^\xaf\xc6\x08+\xf9\x0c#\xac\xaa1\x90Y\x12.\xf73\xc4q\xf51\xa7U1\x9fV0\x94\xb6\xb2J\x95}\xbd5D\xd4F\x8c\xa1T\xd6G\x12\xba\x15S\xf9\xe7\xde=4\xa3+\x07v.\x14#\x84eCe\x11\xd9\x12\x92\x82\x97@.Ml\xa9\xe1\x18\xf44\xb0\x02\xa0!h\x17\x05e1+w\xe6\xb0\xc0\x0f\xe1\xef7\xd5\xbb_m\xca\x1b\xf3\xde\xb5\xf9\"R\xd1\xe8\x05o I\x82\xcb\x0d6\xba3\xbbb\x12\x00\xd28XF2\x188\x0e\x1d\xc0\xf8\x8c\xdf\xc5(Yf\x91l\xdf\x86:\x10}f\x8a*W\xc2\xc9\x88\x0c\x0d\xa3V[(\x95Y%\x96\x0f5\x95\x1ceF\x10\xc2\x90\xe5\xc0 \xdb\xf0\x17h]\xb0\xd5wL\xfa\xf6\xc9\x82L.\x87\xd2uB\xabM\xdb\x8aN\xecT\"\xe2}.\x9d\xd8\xfdlKD\xc3!\x14s\x1bUVg\xb3\x81\xdd\x8e\xdc\x08\xc5\x1bZ*\x15\x1d\xb6\xa20M\xf6l\xbb\x06\xdb\xd3==\x97\xb8S\xb1\xf2b2\xfbN_\xb5\xf2bl\xdc\x8e\xfa:\xe1\xd5u\xe9\x89\xe9{\xb5\xf9\x19\x7f\xaf\x0e'\xe0\xcd\xab8\xba\xc2Li%+\xe2r\x85\x85T\xe1\x857I\xa3X\xb1\x85\x9a\xb2\nA\x14\xea\x1bXW\xe3@\\7\xca\xf0mn\xc4\xe7Za\x19\x8d\x87b\x12\x9aD\xfc\xa5\xb7\x1aB\xd4]z+\xbdp?\x8b\xe2co\xb2\xa0u\xf8O}\xbdI\x94\x85):\x1e\xd3\x1f\xfa:i\x84\x04\x90\xd6\xe2?\xf5\xf5\xa20\xb8\x1e\x82&\xe7Y\xb5zn\x9c=\x04\xbf[\xe3\xd3\xf66\x8bI\xa9n\xe9E\xb5~ \x03\x86\xa0\x01\x8e\xbc\xc2C\x98V+\xf8 \xfau\xe5U\xbcn\xf9\x8df\x90q\xb4\xa2\xc7j2\x04\x8d\xf7\x1c\x1b\xd2Q\xe0%\xc9\x10f\xa6r\x8e\x93C\xd0\xac\x13\xab\xf1\xca\xff\xe8\x87C\xd0\xc0\xfe\xf9\x9bWC\xc8\xaa\xef\xd7$N\xfc(\x1c\xc2\xa4Zv~\x9e\xe05\xd6\x10\xd6e\xe4\xd4S\xc8V\xa99\xea\x89\x8e\xacQ3\xf4\x12\x7f~/\x94V\xe9y\xaa\nM\xe2\x02\xb0\x81\xb2\xf5T\x0e\x96\xa5\x13M\xaf\xa2C\xae\xb6~\x1bE\x81\x9a\x8e\x14g\xd1\x9dEY\\W\x8bR\xbd\xfb?\xdc\xef\xdc\x9f\xeb\\{gFA\xc8\xb6,\xe8@\xea\x94\x82\xbd\xff\xe1\xde}K>\x8f\xaa\x0d\x06\xdas\x0d/|i\x1df\x85\x86\x7fN\xa20e\xb9\xb9H\xfe&c7\x88\xb5=\xact\x0b\x05\xd2\xb2\xa4\xd8\x93f\xb3a\x19\xefV\x91\xdb\x99l\xe7c\xc3)\x1b\x88\x9c?]7\x8e\x85\x18\x87\x86\x93\xc4\xe9\xc4$a\xde\x1fb\xc6\x97\xe4\xfamLf\xfeGi\xce\x1c(a\x05(\xf1F@\x996\x03\x85\x0d\xa7\n\x96\x0cK\xf3\xb1U+x50Md\x98j\xa8 ;\xe8(l\x13\x05\xb6\xe5\x05(\xe97\xec \x95\xb1\xd7\x14\xe3b\x84o\xd4M\x17^z\x82\x88\x99\x08d\x17\x8e\x9c\xb05b\n0\xdbW\xa8'm\x87\xbe\x9f\xa0\x9a\x08\x89\xf1a8=a\xf8\xfc5\xb9\xa6\x1dd\xd0\x01{kB\xe7\xcf,yP\xb9C\xff\xc2\xe4\xf2\xf8\xeb\x00,\x0b\x860\xb3\xf1O\x87\x8a2\xf7Qg\x1b\xa2\xe1\x10S\x05M\x9cztYK\xe8\xe2V#g\xacy\xd4\x0c\xd5\x89V\xcc\x90\xdd\x0c\xa1hf\x87b\x08U\x83\x17\xbaV\xe8\x9a\x8b\xa4`j\x13\x8c\x8c\x81\x1d\x96+\xa3\xc6\x7f\xea\x82\xe7\xb8\xb0\xe8\xc6$ ^Bl\xaf~\x0e\xd7&,\xe34\x83\x0eVj@\xfc\n\xa4\x8b\xa3)\x11\x06;u\xf6@\xa5\xad\x81\xee[\xca\xee(\xbd\xacl\x10\xba(\xdetJa\xe0\x87\xf3w\x91\x1d\x88\x89\xdej \xf9F\x96z\x95\xf7\xb2\xf4\xfa\x0e\xc7\xbcp!Q\x04\x8c*\xfb\x96\xb3^u\xa7\x98xP3J\xf1\xa9dM\xa0\xb9x\x10D#(c\x92.\xc9:\xe2\xd1\nS\x17@\x90\xe3\x91z\xdfX\xa6\x0c\xc8O~\x91\x01\xeb\"p S\x01\x9b]q\xb1U\x10\xa6\xda\x0d\xc3|\x19\xa6\xd1\xb7~\xba\xf8Z\xac\xf6\xcb0%q\xe8\x05CX+\xc7,\xe3m\x1b\xf5&B\x87G+\\s\xd7\xc3\xbaA\xe4\xfcp=\xf3/\xf4\xe4M\x00 \x02\x00z\x92Z1\x10/\xf0\xf3\x8b\xf1j\xa1\xbd\xaf\xd31\xdb\xa1M%\xaf\x86y\x0b\xc3\xc1\xae\xd0\xa0Pl\xad (\x07\x12\xac\xaa\xdf\xad\xa2\x95)\xf3\xb5\xc0=\xdc\xbd<\x12|\x15^P\xa7p \xc9\x15~_1B\xaa\xd5\xbfi\x95T\xb2\xc2\x08\x0d\x0f?}\x82\xd8\xb6\x06{h\xcb%\xd16\xdbq5\xf3\xe4w\x1cOx8\x90(\nN\xfd_\x880>V`B\x0f\xb7z\xb3\xa9\x0c\x934\x97^yZAS\xa6o-\xf6\nH\x96\xc6\x86\xebQ\x01\xda\xd2\x98\xb9\xd1kXP/\xb4\xeb\xf8\xf4 2\xfa6\x9f/3:\xce\xff\x1c\xb1\x8cp\xa1\xa0b0\xa2g\xa7\xc6\x02\xb9\xca\xe7P\xce\xa2\xc4\x83\x0fU\x80\xd0\xa7\xc2\xcf\xb7\x84\xc1m\x90\x1cd\xd8m\x82\xe8\xa0Cv\x11\xa8P\x07\x0e\xd0\xe2<\xe8\xf0\xbeb\x92\x05zp\xa6\x8b\x98T\x00\xda\xe6\xc0\x80\xcf\x84V|'\xd0\x8a\x19\xb4tG\x8cx\xda\x03\xac\xe2\xa5\x01z\x98U\xe5\xc0*\xc8\x0c:o\xf8L\xa8\xf9w\x025?\x87\x1a\xe3&\xaa\xb6\x03\xb0)\xe0*\x86O\xd5\x16\x0c\xe7\xdag\xc4\x0fk>\xd7\xfa\x05\x1f\x15?f${\x1f^\xd7\n\xb3\xe5\x05\x89\xe57\x05Ty\x17\xa4\xfb\x87?\xf0\x91\xd1wE\xfe\xf4\x99\xcd8V\xcb\xca\x93\x87y\xd0\x81 \x9dp\x0f\xc5`\xc7\x05\x8d\xc5\n\x9dqM8\xd65\x8a\x9bR\x93CLd\x93\xe8\xa1R\x96\xd0\x89\xc6\x1f\x01d+\x8bkfOq\x0dO\xf2$<\x8f\xe1\xba\xd3q`\n\x9d\x11\xa4\xf6\x8a\x9e\xc9\xe3\xeb3\x17\xd68\x97\x95\x0b\xd7\x0e_\xbd\xea\x0808\xa6\x99C\x98\xb3,\xa5\x06rC\x87?o\"bK\x17\xdd\xc0\xe7\x9c\xbb\xab\xa1\\\xd8\x1c\xbb\xe8\xec\x920\x8d}\x92\xe8\x81!\x9e\x1c(\x17\x0c([\xf6\x12Fp\x8e\xa9\xe9m\xc7\xe9N\xa3\x90<.\x01f\xc9\x0c,%\xd8\\t:f\xe8\x88\x87B\xa9y$\xc6\x01\x98\x01$\x1e:\x89\xabb|\xe6\x91\x88\x07\x0d:lifWhZ\xbbF\x03fN.\xae\xc6\xbd3\x87\"\x9e\x98kO\xcc\xb4\x1e\xac\x06[B\x86+\xb8\x91K[\xac \x01>\x1a\x92\x91\xc9\xcfi\x11+\xba\x0eCb\xdb\xda\xe9[naG\xc2n\xdd\xce\xd8HN\xe1@\xec~\xb8\xf2\xd3\x05\\\x92\xeb\x04\xfenAG\xdcg\xd3\x176qx\x9a[\x17P\xd9d\xddX0\x84S\x17>\xb65?3J\"\xd3R\xc1\x0d\xa5\xb8\x96\xa5\xf2\x1a\xadn\x1b\xeb\x8f@\xad\x8d3\xf7\xe1\xbaw\x8f\xff\xca\x1d\x8b\xabg\xa5\xf5/\xff\x92\x07\n\xd1\x9f\xd3f9)\x97\xf2\x80\xc5\xcdEg\xc3\x18\xcd\x9b\xd3\xb1\xafZ\x80\x1b-\xb2\x89\xc6\xdc\xfa\x0e S\x1e+\xdb\x08me|=\x1a[#k\x08\xd6\xa8g\xc0`k\x88\xc5\x83j\xb8\xa7\x1b\xa3\xc6\xc0\xfa\x03\xc5\xc9\xcaE\xc0\xfd\xf1hxv\x7f\xde$\x9aK\x0d\x91qzV\xed\xb7^\xa6\x0c\xef\x06(=\x9c\xb6 (\xa3\x01-\x1en\x02\x14\x06\x0e\xdb\xea\xb2\xcd\x9c\x8e{\xe8\xe8Ma\xc5\xfe\xee\x9f\xa1\x8dD\x92]0.\xc0\x1e\xd0#Z~\xd1w\x1c \x9a\xf6\xa8\xf7i4p\xee\x1e\xa0\x05\xbe\xea\xf7\xce\xdd\xdc\x80\x0d\x9c\xba\x9bn_\xaf\x07\x18R\x12Y\xb1\xe4\xc7\xa2\x8b\x8b\x98\x95^\\h\x83~z\xd3iL\x92\x84\xd5a\xbf\xb5\xd5b\xc2{\x89\x89\xbe\xa38\xf5'\x01\xe1u\xf0\xb7\xb6Z\xe2Oy%\xfaK[%\x9b\xfa\x11\xabB\x7f\xe9\xaa\\`\xf1\x85\xb6\xc8KX\xfb\xf4\x87\xb6\xc2\xd4g\xe5S__\x1c\xf1b}\xcf\xfe\x9c\x15\xfbsmq\x10M.\x7f\xce\xa2\x94\x8f!\xffS[9\x9a^\xb3j\xd1\xb4\x12P\x05+\xb0\xa5\xd3/\xdcE\x96\xa6Q\xc8*\xe0O]\xa5\x89\x17\xae=\xb6\xb8\xec\xa7\xbe\xd2*\xf5yS\xfc\xb7\xb6\x9a\xcfgE\x7fh+D|i\xe9\x0f}\x85\x80\x97kc\xc6N\xa2`\x1eG\xd9J\xd4\xc1?t\x15\xa7^\xca\x90\x91\xfe0U\x08\xfc$\xcd+\xd1?\xb4\x15\xa7\xac\xcaT[H\xd8p\xa7D;\xdc)I=?Hx\x15\xfc\xad\xad6c\x90\x9d\xce\xb4P\x9d\xfa^\x101\x9cb?\xf5\x95\xd6\xbc\xc6Z[\xcc\xc7\xa9\x1f&\x87\x82v\xfed\x89\x85d\xa9/\xbc S^~A\xb4 \x9a\xf9$\x98\xa2\xe9`l[\xe2\x0f}\xc5\xb9\x8cf\xc5\x9f\x86\xcaYLD\xc5,\xd6\"\xd3,\x8a\xd0+\x93V\xc2\x9f\xfaJ\xf1\x92W\x89\xb5s\\\xf4\xb1x\xd1\xd7\x16\x0eX\xe1@[\xb8\xc3\nw\xb4\x85\xbb\xacpW[\xb8\xc7\n\xf7\xb4\x85\xfb\xacp_[\x88V\x1f\xb4\x98x\xda\xf5\xa0\xef9P\xd8Om\xa5b\x97-\x8c{l\xc1[\xd1\xb7\x90.\x19\xca\xd1\x1f\xba\n\x8c\xc4j \xac?\x8b1\\&-\xc7\x9f\xdaJK\xb6%\xfc\xa5v?\xf8\xe1*c8\x87\xbf\xf4U\x12^A\xbb+//\x18 //\xb4p\xbc$\xd7s\xc2P\x95\xfd\xd4U\n\xbc\x0bN!\xf0\x97\xb6\n\x99\x93\x90\xf5\xc4~j+1h\x05Zp\x05~x\xc9\x8b\xc3K]\x85\xa5\xe7\xb3\x81\xd2\x1f\xfa\n+^\xae]\xe8\xa5\x17_\xf2\xf2X\xdf\x01 3V\x81\x84\x99\xa9\x82\x9frR\"\xfe\xd0W\xe4t[\xe7w\xc8+p\xec\xc5_\xba*\xa1\xc7Ha\xe8iIa\x181\xbfaV\x87\xff\xa1\xab\xc8\x04F\xac\xc6\xc5Z]%\xb6\xbc\xfa\xe3*Z\xa5\xc5F\x12\x7f\x18*\n\xba\x17\x19i^\x94\xa5\x02\xa7\xd9O]%\xd6\x97\xb6\x93\x95\x17{l\x05\xf0\x97\xb6\x8a?I\x05]\xe5\xbf\xb5\xd5D\x15Sq4\xcf9F\xf1\x87\xae\xe2\xcfX\xe3g]Q\xcc&\x12kg\x123(\xc4Z\x08\xc4\xd9\x05\xe3\x99\xe8\x0f]\x056.\xed\x80\x12o\xc9\xfa\xa5?\xb4\x15\n\xd41#NB&\xf9r\xf2\xdf\xfaj\x81\xc0/\xf6S[i\xe9\x05\x0c\xc5X\nN]\x15L\xa3\xc4\xea\xe0Om\xa5\x95\xc7\x07\xb4\xf2\xf4\xa3I\xe3(d$\x95\xfd\xd4W\xba\xe6\x0c<\xfe\xd2V\xc9\x18\xeb\x9ddZ\xe6;\xc9\x96K/\xbe\xe6U\xf0\xb7\xbe\x1a_\x07\xfd~IY\x1c\x95\xd8\xb6R\xe6\xdb\xa2\xa9\x92\xf3\xce\xa9\x89yN\x19\xd9M\xb5$7%\x1f\xd3\\\xa4\x11\x7fh+R\xde\x82\xd5\xa2\xbf\xb4U\x16\xac\\\x9br=\xcd\x8f\xec\xd4tf\xa7>?\x0e\xe9\x0f}\x85T\xc0\x03#L\xeb\xaa0\xaa\x99jIf\x1a{\x93K^\xeeM\xb44\x9e\x11x-u\xcf\x18\x82fZ\xec\\{\xac\xe3\xb5\xa7\xedy\xedO \x13\xa7\xf0\x97\xae\xca\x15\x17r\xae\xf4R\xce\xc4\x8f\x85T\xc9~j+\x05\xfe\xea\xad\xc7\xd7A\xfc\xa1\xab8%3\xc1\xaf\xcf\xb4$\x82\x04\x81\xbf\xe2\x02$\xff\xad\xab\xc6v\x92\x9e5Yzs\xce\xdd,1\x93C\xb5J\xe0\x87\xac\x06\xfda\xaa\xe0\xc5_\xc5\xde\xd4G3f^\xb5x\xa5\xfbh\xe9%\xe2\x1cO\xb4k\xbc\x12\x10Z\x19\xa0\xb3\xf2\xd2\x94\xc4\xa1\xa8C\x7fk\xabE\xc1\xf5\x9c\x13@\xfe\xdbT-\x9f\xa9\xf8CW\x91\xce\xc9\x0bJ\xb3-\xbf\xd2~$\x88kl\"\xadi\xc4\x89L\x1a\xe9\x89\xfd\x9a\xd3\xc3\xb5v\x1d)Q\xc8\xa9\x83\xb6BNtSFuK5\x0c:\"v {\x07:\xa2:\xbbvn3\xdd7\xb9\x07\xfb\xc2\x9e\xecs\xc7\xd1\xdf\xdb\xd8\x01Yx\xe4\xd0\xfe\xe4`\x8cw\xa0\x03\xd6\xd8\x83s\x8f<\xf5\xf6\x97[\x8f\xebcYT\xdckx\xa8\xe7}5V\xb0\xf0\x8b1\xf9\x18\xd7\xda\xa2\x08[\x92\xcfQ\xe9\x03\xb7\x08\xd6\xab\xf5E/3Z\xe3\xc9\x13/\x8c\xc2\xebe\x94%O\x9fj\xb4\xb7\x81Q\xe5\xeb1s\xb9\xb5m\xe1/\xddN\x00\xd4eQ^ym\xe7\xf7\xba\x86zt\xbaX/\x9f\xb7\xa1\"\xbb\xe0\xc5\xaa\xfc\xae\xd7PQ0\xf2\xeb:F\x1e\xf2\xc08X\x91\xdf'\x9b*\xf2 ck\x11\xcf\xd8T\xd1\x0b\xaf\x870\xb5c\xd9\xf6\xef5^`\x9bA\xf9f\xd6\xa4\x82\x17\x8f\xb8\\*\xe2\x99\x14\xe6\xce.DM\xf7\x8b\xca\x15\xccVal\xe0\xc8\xf6\x1d\x0b\xdb\x12n\xdf\xf0\xa3\x05\x1d\x88\xa0\x03\xd6\x8f\x10\xcd\x8a\x94s\xac f\x05\x0b/\x01?\\S\xea\x93{\xcf@\x18\xa5\x98\xc0\x82\x8a\xdd\xfe\x94\x88\xa9vM\xe9C\xc5C\x11\x14\x13I\x8dCC\xb2W\xf1`D\x89\xf2\xa5yV\x1b\xb0B<\xb4\x0b4\xad\xacD\x17\xd0=e\xc8\xbc\xe4\xf3\xa4\xd3\xf71\x16\x99\x02\"\x0c \x8d\xef\x12\xf6.\xc9V\xab\xc0gi>$\xa8\xb9@>\xae\xc8$%S\xf0B\x06\x9d\xaeu\x9b\xebX\xf1\xe4w\xe0<\xd0\xc2\x04\x9e@\x96\x1b\x06L:\x9d\xb6\xa0\x99aj\xc9\x0c\x93\xe2r\xcc\xa2#\x1e\xd3\xb1O\xe8\xaf3\xcb\x05\xaf\x05\xe4\xe8\x02\xcddCJ\xf4T.\x8c.>c\xb2:sx\xf5\xb91\xdc\xe2\xea\xb7\"\x11\x1eb\xf9\xde\xfa\x82;qC$O7@l\xef\xcb#\xb6\xd7\x1a\xb1!\xf1\xc3y@\xe0\x84x\x93\x94s&\x9f\x87\xe5\x9f\xb3\xf0\xa6\xack\x02C\x7fWB\xbce\xd3\xc5/\x99\x19\xb7^c\xe6P\x14zK\x16)K?+\xf5\xf1\x1a\x8d\x9eM\x0f\xc3\xc1\xae\x14\n\x16\xe3\x0d\x97\xde\xe0h\x8a\xad\xdd\x8c}\xe2\x11vp\x95\xc6Z\xb5pc\x1b\xa2W\xab\xcf\x97Gv\xb1\x92\xf4s\xac\x91a\x8d\x7f\x1c\xba\x1b\xb8(\xbc\x92\xbb%\x91\xabu\xb0R\x1fD\x9bk;\x1d\x933Ge0\xe4\x05\x88\x8b\x05\xf0\x0d\xc0\x0e\xab\x94\x05I\xca\xebhJ\x1a9\x8a\xcf\x81\xa1\x89d0\xbe\xf2w%\x18\xff0\xceM\xcc\xb5\x11\xd0\xf2\xa9\xd6L\x93\xdaq`%+\xb3\xad\xd1\x08\x92:T\xbaC\x8e\x8c\xf5\xd98g\x89\xeb\xf2C\xc8\xea\xf7:\xf0 e\xdd\x85\x97H\xd1\x95\xecI+\xd2\x0f\xf5\x0cZ\x17\x19\xb4v\xac\x19|.{\x06\xff\x00\xd2\x15\x85\x1b\x1c\xd1\x1a\xe9@\x8aTW\x11\xd0jL\x0d?o\xeb\x16Q\xd1\xc4\xce`\x810\x1f\x83\x07O \xcd\x19tO\xf6\x866=tR+\xba\xf2\xe9\xd8\x93\x89j\xed\x04@\x12y\xfer\xfa\xe6u\x91?H\x9bYB~6\xdcih\xb2*\x1f~-\xb6Z\x14\xe2\x89\x99o\xcf\xba\xf3\xf2\x16\xe8B)\xda\xef\x8e2R\xe8i\x16\xad\xbb\xb4\xd2\xa4Y\x14\x13\xba\xa0T\x9b\xa9_~\x8c'C\x98\x0f<\xb2\xb7\xfa.\xe4\xab'\xe2\xf4\x96\xd6&\x87U\x17\x8eU\xb1\x14\x8f\x8f\x05\x99\\\xe6`L\\\xb8\xc8R\x88\xc9\x84\xf8k2\x85?&\xe0\xa5\xe0\x87S\xf2\x11\xfe\x98t-\x17\xce1\x99\x0bA\xe7m\x05l\xe6\xd5\xfd]\xb6`\xef1d\xa5\xe5\xc8\x9a\x97\x03\xa4\x1d\x94\x8e\xb3\x86%\x01(\xfb\xd5&\xe5\xd1R\x02\xed\xb4\xa2\x8e\xd0\x9a\xc6\xb6\xd9\x9f\x86\xadxw\xfb-Y\xb4\xb0&\x15\xcfg.\xe9\x7f=\xac\xc6\x8f\xac\xc7\x1f7\xe44Z p9\xb30\x9e\xb4\xc4\xd9Y\x9bf\x817\x1d`\xac\x84;\xe1C\x82\x1c\xd4\xf5\xdb\x01\x1a\xb7D\xbb\x0dswL \xf9\xe8M\xd2\xdf\x11\xeb\x93\xd6X?A\xacO6\xc5\xfa\xc9g`\xfd\xe4\xce\xb1^\xa0p\x86q\xed\x18\xff\xd4\xc4\xb5\xe4;%\xa0;\xa5\x15J\xd3\xda+\xdc)A\xcb\x9d\xb2\xb5\xda\x0cN\x97\x84\xcbdA=9\xfe!|\xe6M\xf3+\x0cZ\xa0\xf0l\x0c\x06,\xc6\x80\x05\xdcs\xe5\x87\x10/\xff\xd0\xd1E\xfb\x95\xec\xf7\x92:\xa5\xef[l\xd35\xf7s[\xd9\x89\x0bAu\xb7\x07\xedv;\x85\xdb4\x07\xdb\xf4\x1f\xb4\x8f+oo$\xafM\xa8\x06B\xd2\xe1\x8f\xd0Z\xe5\x891x\xf2\x02\xf8\xf4 \xfap\x1f\x0b\xf0\x07\x81!f\x00c^2\x84\xfeR\x03@\xe8\xfb^\x18\x02\x13,\xfc\xa4\xbb$I\xe2\xcd\x89\x14\xf8(I\xbd\xc9%\xbaW\xb5j|j\xc8\xff \xcaC\x9b\x11\xa5\xc8\x85\xcc\x85\x04)\xbc\xd6\xe5\x93>6=\x883\xa6\x89D\xa23\xc1\xa4V.\xb0X\xa5\x9e\xc3S.`b&dE\x8f\xbc \xf0\xc3y\x11j\x0dp\xe7xi\x14'0\xf5c2I\x83k\x91\xe4\x85n\x94(\xa6D\xe3\xe2\x1a\xd2\x05\x81\x1fWq\xb4\xda\xa6D'\xf9\x11V\xde\xe4\xd2\x9b\x93.\xbcO\x08\xfc\x987\xd8E\x865\xff\xd3v~\xa4\xfbl\xe2\x05\x01mb\xd9\x85\x13\xe2Ma\x19\xc5\x84r\xae\x8b4]\x0d\xef\xdf\x9f]t\x97\xe4~\x96\x90m\xfcz\xbb\xe8\xc7\xb8I$<\xc48\xd0\xe3\xe8\x0c\x0e\xd0\xd93\xf7W\x15\xef\x18\x91x\xb7 \x85\xacS\"\x9a~\x82\x86\x97\x94\xf1N &?g~\x8cZEY\x9eb|\xb7\x9f&\\\xd4\xf2\x13\xf8\x91vD\xe9(\x0c\xbf\\\x1f\xb9\xbf\xae\xe8\x88Nn\x08\xa9]\xc2\x91&Op\x90\xaf\xe6\xbb\x17~8\xb5\x19\x19\xda\xeak\xc0\x9b\x8b]~r\"F\xaa~\xd7\xabF\x981`\xfc\xba6\xa4\xa3\xe9@v!3a\xbd\xb8k1_\xe1\xf0\xb6\xe7\xb6\xe7p\xe2p\xd0\xee\xa8(\x1d\xa9K\xfay\xdbS\x95\xbeM\x05[\xcf\xd7\xa9\xba(\xaa\x17\x93\x1eb\xd7\xb6\x96\xf2%W>\x8b\x92\x9b{\xef\xe9\xe13\xf1\x12\x92;e\x0fk\xaa\xf0\x9b\xf7\xba*\x85\xbb\xb8\xbe\x16\x14\xd06\xa5 `\x0d S\x84\xe6f\x0c\x9e\xb7\xac\x19\xce.\x99[\xd1\xbas\x8b\xb6I\x97\xacI|m_7x@\x97=\xdeS\xb9\x89\xbaD\x0bk5Bc\xa3\xa8\xb0.9r\x86\xcc\x913\xe4\x8e\x9c\x93\xa6\xdb\x95\x8d\x1c;\xd5\xe7\xa6\xd1\x0f|+n\x953\x82\xce\xc1\x17)O[9\x98\xc7\x8a\x83y\x1b%\xc2c\xd8\xb2}LhPv\xec\xae\xfd\x12\x8a\xbb\x10\x9fyuK\x0b\xd97\x83f\x03gs\xdd\x98Zr\xbd\x18Z\xa8\xad\xb39*\xaf1\xf1\xc5\xb5\x9d\x8d\xfbg\xad&\x02mt;&\x8c\x16\xe1\xa5\x1b\xbf\xaf\xf6\x7f\xd3\x8a\xcc\xcd\xeb\xbd^\xc5=\x8b\xf1|R\xf5\x85p\x00\xdc.\n9?I\xbd~B\xe6\xc7\x1fW\x85k\xba\x05-\xa3\x13\xf1\x9e\xa4\xfc7\x9c\xd3\x14I\xa1\x18\x95\x18[\xff\xf2/R*B\x0b7p\x835\x19\x91\x07\xc8^W\xe1\xc8\"q\xd1\x81\x8b\x11T2W\x1a\x80\xbb4\xc7\x14\x93\x12\xcb\xe1\\rjW\\i1\xb7\xe8*\xe4\xc5\xda\xcc\xb5\xfa\xebJ\\\x82\xfa\xa8O2\x00\x9e{\xa9\x94\xb1g\xea\xa5\xc4\x90\xb4\xa7\xf2%[\xdb\xe2\xdb\x98\xcc\xc9\xc7\x95\xc6\xeb\xd9\x84F\xed\xe0y^\x8f\xac\xfaT\xd1\xe2\xc4n8\xaa\x19\xd2\xd6\x1d\xc3\x8d\xc7\x9e\x98\xbd\x17\"gS{\x86\xd6\x1f\xc5\xac\x0e\xae@]\x05\x0e\xe6\x16#\xaa\x1bP[\x1a\xd3\x14\x89\xae\xfc\x17\xffH\x8a\x88 #v\xc5&g/\x08\x14I\x05F\x94\x95\x0e\xba\xf2\x8b\xc0\x055\xe8\xe7\xad\xccb\xebb\x01\xe5W\xfaw\xd4\xbe\xd5\xdf\xeb\xeewy0\x84[\xb5\xb6.\xc2\xec\xef=tLa\xc5\xfdV\xf6\xcf>\x7fu\xf8\xfa{C\xbc\x87$\xf5R\x7f\xd2\xae\xee\xaa\x08\xb4\xde\xa26\x8f\xf2\xba\xc1\x07\x0b?\x98\x1em\xfa\xd5\x9c\xa4\xcf\x199\xa0;P\xf9\xe6\xfc\xd5\xf1\xc9W\xc7\xcf\xcd\x9f\xbe\x0c\xfd\xd4\xf7\x82\xd3\x14S=l\xf4\xe9\x914\xdcM>\x8dI\x88\xfe\xbd\xe2\x8b7\xaf\x8f\x8e\x8d \xe4[\xe8[?\x08^\xb1p\xaa-@\x92\x7f\xf6\xdc\x9f\xde\xe2+\xda\xd9 \xbb)\xd4\x80\xd4\x84G\x8b(\xa3\xe0\xe0m\xbc_MK\x10m;I\xf5\xbb6\xe3}\xeeOo\xf3\x19v\x17.[\xc3\xe7\xfd\xeb\xd3\xc3\x17\xc7\xe7\xb7\\\x13\xdd\xd7\x1b\x03Y\xd7\xc8\x06S\xcf\xb0\xaa\x94\xcf\xc1z\xf3\xe1\xf8\xe4\xe4\xe5\xf3\xe3\xf3g\x87\xa7\xc7\x1a\xe6\xa7\xda\xce\xc4Htp#\xc6\xfe\x9aLq7\xbd\x88\xa3e\xcd\x8el\xd3\xd7\xcc\xd8\xd7\xd4OV\x81\x87I\xceZ\xb2\xe4\x80\x84W\xfa\x0eT\xbd\xaex\x0c\xd7F\x82\xa6\xb6\xee\x8d\xb2\x9c\x9a\xd8\x9e\xf2\x93\xdf{\x84\xec\x9e;,\x85\x86\x0b;\x1d\x87k\xb4\xc7\xe1\xd9Fw\\\x1aR\xdaz\xdci\xb7\xf25f\x1b\xfc\xfb\x8d\xab+\xd3\x060\x85\x9a\xa1\xddzT\x86\x01}\xc6X*g\xc7\x06\xc3Q\xbe\xc5\x00G\xea\xbb\x11L\xed\xca[ly\xa8\xad\xbd\x11BJ\xa7\xf1\x06\xc3^Il\xaa\x00a\xfenS\xf8\xe5\xccC\xeb\x01l\xb5\xaf\n\xed\xf6\x10\x94\xf7\x91\x1f6\xb7*\x1e\xc1\xe85\x1b\xf5\x8b\x07\xc7\xa3\xda\x02\x86\xadm\x01A\xe8\xbd(\xbb\x88W\x9d\xed\xba\xa5Odo\xf9.\xfc \xadhy6\x9b\xef\xa3\x0c<\xbc\x10I\xc9r\x95\xfa\xe1\x1c\xd2\x88gi\x07\x0fb\x92\x90xM\xa6\x88)t\xa4.\xfc\xf8\xc7\xe4G\x17\xd2\x85\x97\xf2\x03;\xfc\xe1O)\\\x10\x88B\xbc\xa9\xb1\xf8\x8aZpI\xae\xbb\xf0\x9c5\xe5cn:/,,\xa6E\x8b\xf8\x86x\xd3\xc7\xb4\xce\x95\x1f\x04\x90\xa4\xf4\xff\x17\x04\xbc\xc9\x84$,94o\\\xb6\x17\xff\x93>t\xbe\xe9\x11z/\x04\x9a!\xee\xb5\xeeA\xf5\xd7&\xab\x03\x12\xcf=\xa9.4\x1c\xc0d\x1c\x9eqE}\xfbq@!^F\xb6\xee8D\xbd\x87\xe7\x82\xd5z}\xe9RR\xc8^GY,\x19\x0b\xe3\x0dY\xba\xf0B\x88\xc2 \xe9\xc2\xbb\x85\x9fP\xc8\xcf\x02\x7f\x92\xc2\xd2\xbb\xa6k3\xcd\x08m\xc9c\x87Z\xd7ba\x99\xd7\x91?\xb5Q\x8f\x8ct\x0bo\xad\xe3\x86\x80\x93\xf2S\x7f\x01,?\xbc\x13}\x1ch\xf5in\xd6\\\xe3\x86Q\x99Mh\x9a\x97\xa5\xd1\x85\x1fN\xcb&\xf7\x1b\xdcA\xeb\xd3\xfd\x80d$\x98\xa8\x88E(b%cbF\xacs\xcd'\xf7\xeeQd*\xb3p,tm \x8f0?\xc3\xcc\x9b\x10\x13BEk\x12\xc7\xfe\x94\xa3\xd4,\x8e\x96\x1c\xa9\xe8\xd7\x90\xac\xc8\xc4\x9f\xf9\x13\xb40\xef\xc2q\x98d\x0c\xc3RVkI\xd2E4\x85\x10\x93\xd1N#\xbc\x01\xa6-\x06\xde\x8a\x85\xf2\xc4\x91\xf0jhjH\x1c\x97\xdd\\\x94\xb7\x82\x08\xbb\xfb\xe9\x93\x96a\xbc\xcd\xcc\xbe\xc8V!\xedn\xe3\x90q3\xa7\xf00\x11\xa5\xc8`\x1cZ%\x0d\x7f\xaaL7K(\xd9/&\xc8\x160\x8a\x8bAQ2\xceg\x02/\x19\xe9v\xe1\xa7,I\xf9\xb71\x99g\x81\x17\x17\xb6\xf4.=w\x08\xda\x86n\xde\xff\xc6\xbd\xe9 \xea:\xcf\xd7T\xa8\xe1\x8c;\xde\xc7\xfb\xa4\xf3\xf3\x98\x0e\xf60K\xa3g~8}\xeb\xf9\xb1&\x863\xc8\xac\x83G\x8f\x96P\xddf\x19\xcb\x14\xdee\xdc?.)\xff\xedh\xa3\xd0\x8b\x07\xd7Xm\x8c\x19Vxx\x8d\xd5x*\xad\xb9ch8\xf6Z\x98\x8e\xadp\xda\x95\xfe\x9a/\x02\x03{\xc5\x12\x01\xcd\xaa_;0\x1b{gt\xd2\x93\x86\x96jbQ\xcb\x0f\x9d\xd3BG\x00\x9bF\nu\x86\xd3h\xbd\x82\x01\xc4W\xe8\xe6\xd6g\xa4\xa2+(y\xbb\x13\x0c-\xf5\x9b\x16E~\xd6<\xa4w2\xf6Zr\x8f\x80\xfb\x1b\x03\x9b\x9b\x99\x80k\x95\x00\xf2\xd7\xea\x0e|\x1f\xe6V\x04\x94D\xc3*\n\xfc\xc95\xfc1A\x94\xbe$\xf8\xf3jAB\xb6\x03\xe7\x14\xbd\x8b\xadI?Ab|\xcdV\xbff8\x07\x10\x8f=\xc6\x13\xd0\x1f\x14\x19`\xa8\x1b!\x8b*\xcc\xea\xae\xf3\xba\xed\xa0\xcfCT\xf3\xaf'\xcd\xf0d\x11\xadY*\x16\x8f\xf6\xe3\xe6\x1f\xd7~[\xc3+T\x8f\xf8V\x84~a<\xef\xcbbIds\x8b\xb2\x9a\xfc\x01\x9a\xf7\xc4\x05kI\xe29\x11\x89\x97^G\xcf\xb3U@\x0fd\xf25\xb9Nlg\x08G^H\x8f]\xac\x06a\x14n\xb3f\x12$\xe0\xc4\x01\x8d\xc8\xc2r\xa7\x95.\xf5\x90\xe1k\xec\xeb]\xcc-ZXo\xe9U\xc4\xe9w\xc2\x8e{\xca\xe9'\xde\x92P\x14\x1c\xe2\xd1\xdb\xead}LA\xb4\xc2\xa8\xb3\xf4L`Vr\xa2\xea\xc4\xcb\x12nNv\x15\xa9j[\xdb\xa1G\x9c\"L\xdb\x8e\xe088\xdfMw@i\x9c\xf4p\\\xd0\xb7\x97\xe4:\x11,0gL\x0d.\xaa\xc2\x86\xb0\x15ZL\x9bL\x11e\xf6\xd2x\xee\xa1OI\xd7[\xad\x82k\xccE\xe2\xe6\xde \x89\xc1\xd1\x91>(\xd4\x1a\xbe2\xdf\x8f\n\x9b\xb8\xc2\x11%n\xae\\\x18{\x84\xe6\xd3\x1bC\x1ek\xe2G\x83t\xebf\xfbl \xf0\x87>\xd9I\xbb\xfd\xb8\xfel\xc0\x1b\x01n\x04\xea-\x87z\xdd(*\x10f=\xa7\xbb%\x16`WzR[\xd1\xe77\x06\xfd5A#h@X\xb4\x9e\x9f\xfb ~\x84F~\x9a$\xeb\xa0'\xa9U\xa4]6\x0f\xb0\xa4\xaa\xbf\xf5\x18\xf5\x06/\xad\xc6xn\x1c#\x8fY\xce/\x90Z+\xb7p|L\x1f\x1fwI\xf8sF2r\"5\xc51lc\xe95\x9fpK8 c\x9c-\x15`\xb7\x87\xd5\x859\xd90HV\xa2\xf6\x85|\xab.\xf3\xf6p\xae!m\x05d\xeb\xc8%Q\xaeT\xe3\x1a{P(\xd0\xa4*,\x88|p\x94\xf9o\xecY<%/\xc2T\xdb\xaekP\xf5Cg\x04\x83\xa6\xf6A\xd1Y6\x8b\x05\xc0%\"2\x0e\xa1\x03\xfd\x16|*&\x84\x181\xca\xe4\xdf6\x10\xc2\x0d\xa2\xaf\xc8\xb3\xb7\xe2\xda\xedj\x96c\x91\xd07&3\x0cj\xe6\x96\xf6\x850R\x0f\x0b\x93\xf9T\xe4\x172ODh\xef\xf0\x13\x85U\x80\x03\xedk\xdbiT\xe8E\xb6\x865\xf3\xd0\xb0\xaelO\x86\xcc\xf4\x1f5]\x0caI%_\x8e\xfe\xb9\xbf:\xe5]h\xd7\x16=\\\xe4\xeb)*\x050~\x9fR\xc1\xc4\x97.\xee,G\x81\x88\xa7\xdf\xad\x0d\x12o\x8c\xca\xf2\x92\xb5KH\xae\xe0\xc2\x95_\x96\x82\x88`\x8ef\xb9P\x87\xe2<\xd5\xa0'\x12\xdf\xdb+\xd9\x02\x9c8\x8e\x0b+\x9b\xb80\x17?R\xf1c\x89'\xacz-\x82\xbe\x08\xdd\xa9rS\xa2V\xb3\x1d\xd4U\xc8\x83c\x17\xed.XR\nx\xbb\xdb\xedR\x86\xb9\xaa\xdab\xcb\xe3/W\xcc\x1c\x05<\xf8\x915\xf0#\xe7$\x91\x99N\x1cy\xfe\xd3E\xa64'\x13\x8fJ\xb4\xfc\x83A\x14\x92\xffJ\xcb~ \xca\xad\x8d`p5\x80e\xd1\n5\xa9\xd3Y\x80BM\xc1\x0c#\x12j\nD\x04BM\x91p\xd8\xd3\x14\x89(\x83\xba\"\x1eWPS\x84\x91\x04u\xefE\xc8@\x8d\xd62\x8fa\xa6\xf9N\x0er\xa5\xf9\x94\x85\x052N\xcc\xf0\x15\x8f\xc8a*a\xc1\x174\xa5\xdcU\\7\x05\xe6N\xab\x98\xc3jy\xbe\xb0j:\x19\xbb\x10\x96L'C9\x9f\xeag\x10\x0e\xee>\xc9n\x00\x8a[\x13\x17\xac\xf3s\x92\xbc\x8a\xa6Y@,WA?4\xaa\x1f\xca\xd2\xcc\x0d\x1eI\xfc\xf0\xa9\xa3\x1e|\x8aUt\xce\x85\x98dh`\xef\xdeE\xab\x0b/\x1eB$\xfa\xa9\xd42Y\xad\xde(\x84\xd2\xcd\x89\xfc\x8e\x86*\xda\x94\x90\xfa\xa8\xf9\x89\xbb\x05\x14\xe0\x00b\xd0\x8dMX\xd9V\x1c\xb6\xe0\x1f\xbe(\xd5\x03be\x87v\x7f\xf7\xa1\x9a\x03\xd4\x17E{=]^QVT\xc9\x1c\x9a\xe5E\x95l\xa4^^\xb4\xaf\x16%\xdcfU=\xa8&\xcc\x0fWy;\xa3+\x82-\xed\xef1\x9e\x88\xae\xdb\xae\xa3\xb6\x1a\xf0\xf3l\xdf\xd1\xa5*]\x19\xcfg\xd4'\xa6\xe5uN\xeb\xd7\xd9D\xcdoJ\xd0^\xd4r\x07\xd2\xb9a\xba\xff\xb2{.\xf8\x02\xd7\x1d.\xe9\xea\x9c\x7fho\x88\xb8=\x172\xf5\x03\x9br\x9f\xc8v\x9d\x9f#\x13\xd6s!.*\x11\xc7a^E\xb9 \x1d\xea\\B\xc5\xa5|7\n\xdf\xc7\xc1\xd1\xc2\x0b\xe7\xa4\x95+V!\xe6\xa5^<'i\x9dCN\xd4MH\xca\xc4\x00\xb3\x80\x97\xc5\x81JE\xc5\xa3\xf1\x8b\xbeq!\xea\x06\x917=]\x91I\xab\x01GL\x0e\xebR\xa6\xf7\x10\xeb\nA\xeb}\x1c\xa0\x87\xb9\xae\xc64\xba\ni7j\xba\xf3|\x0c\x08\xb7S\xcc\x8e\xd0j\x18z\xb8\xa1\xe7\x9ax\xb3\x88\x89\xc1.\xa6\x98\xb2Mp\xc0\x14\xae\xd87\x99\xd2Y\xe0\xcdrw\x15\x935 \x85t`\x1b\x06.f\xf6>\x0eZ\x0d\\\xea;b\x82W7\x8b\x83\x0d:\xc4\xb1z\xf1\xa4~\xff\x88G\xc0\x89\xa2u\xd0]yqB\xd8\xd7\x8e)\x834\x19[Y\x1cPq\xdb_z1\n\x91\xd6Y\x1ew\xd2\xac\x9c\xa5\\\xd8\x95\x1fN\xa3\xabn\x10\xf1k~\xdcW\x93\x08#\x1f\xdc\xbfoA\xa7Rc\x11%\xa9\xe6\xf5\xcaK\x17\xe6\xeeXmJ\x98\xf8w\x0b?I\xa3\xf8\xba\xfa\x06/v\x98\xcc^-\x93un\\\xac\xb4,\x97\xc5\x1c<\xa0\x83e@KH\xec{\x81\xffK\x0e8]\x86\xde\x9b*\x1am\xb4>b\xd3\xccIz\x14\x853\x7f\x9e\xd8\x0eE\x8c\x84\xa2\xf4\xd8\xa0p\xc1I\x11I\xc7\xc4n\x86r\x899\xef^\xe7\x12Pj\x88v\xc5]\xb2\xf0B\xa7\x0d\xa5\x81<\xb5 \x99\xbe\x0c\xa7\xe4\xe3\xd0\x90\xc2\x1e8\x03$\xe1\xae1\xcb\xb1\x89FE\xe1\x0b?HI\xfc\xc5H+\x03\x7f\xe0]GYZ\xa6k\xacc\x9d\xfd [t\xae<\xd1\x0f\x02\xc9q\x8a\xb4\x90\xa1F\x14'\x14\xd8\xa6\xf8\x92\n@\xab\xfap\xdag\xe9\xa5\xd6\xf9\x88b\xae'\x9dbL;B\xdfF\xa5\xb7\xe3\xea\xa8\xf1\xbe\xcd2\x1a\x98kl\xc29g\xd5\xbc\"L\xd9\xd4\x8cYf\xa0\xb5\xc6\x992\x88T^\x10\xf4\xf3D\x9du\x8b \xd6a\\\xcau\x86f\xa5*\x11Z\xc5\xea\x8e7\x7f\xc4.q\x9a\x08\x02\xde\xa8\xd1\x1d\x1cr\xa2P\xb7\xe9\x0b\x15\xb0\x86\xe0\x9bU\x981k\x7fc\x1a\x03Hg0v1F\xc7`|e\x0bl\x10OkZ\x03z\x9ch(j\xbc\xb7o\x81D\xe2\x06\xec\x8ep\xe86g\x02\xe7\xd7\xa53\x816\x94\xf3\x1c\xe9\xb8\xd0\xf8vK\x10=C>\xe4\xf6@`Z\xce;\x9dy\xc3\x1eb\x80\xd1z\x07\xca\x0f\xbb\xfb.\x11\x13s\xe5\xb8h\x18!n\xae\x89\xf7!\xb6\xf5\xcc\x98pU<\x11\xab\xf8\x8d!i\x9fx\xd0\xc9\x8f\xae\x93\x1f\xce\xb9\x95b\x97\xffIwHVK\x1e\xbc\x9a\x9bqk\xe6\xf9\x01\x99\x1a\xda\xc4\xf3\xde\xebN\xa2\x00\x15\xf3V\x8c\xd9=!S\xdf\xff\xff<\xcf\xab\xb3\xac\x0b\xd0\x11\x80\xe1\xa7y\x9c+\x83\x0f\xa2x\x16\xb5\xf72<`\\=I\x9bb\x17f\xfa\x15TIW\xd3-+}\xa6\xccFh\"\x8eO\x9e\x9aYh\xadE:?\xdd\xfeP\x1f\xdc/5\xb6\x87\xe2\xe1\x1b'\xa50\xad'v.\xe7\xcek\xac\xa4(\x03\xb6j\x98\x03\xcb]\xd94\x054\x07e.S<\x9f\xdd6\xff\xb0\xf6\xb3E\xba\x0c^Dq\xfeQ\xd5uK<7.\x18\x87\x88\xf9\x95\xf2(f\\`\xf4\xf0\n\x86\xa2\xad\xf9;\xd6g\xd3\xdc\xfci1\xbe\xfa\xe9L\xfd\xc4\xbb\x08\xc8t\x08Y}\xc5(d<\xeb\x90\x116I\xd0\xad\xff\x8e\xaf~PO\xb0\xeb\x808uLL63{[\x08b+\xc9\xb0\xcdH\xc2\xd2\xac\xd6\x01RF\x10\xd1\xf4v\x16\x07\xdb\xfcS\xe3\x87)\xaa\x8dY\x9a\xad\x1az\xaa\x01({c\xfeFl\xa5\x02\x94Y\x1c\x98\xab\xb7Z\\\x9e#\xd1pi\xea4\xef7\xffV@\xe4\x19\xbek\xe1\x13\xf8\x93\xcbaem\xf5\x03u\xc1:\xfe\xb8\n\xa2\x984\x05;3\xa2\xc4\xd4_\xb7F\x88\x14\xb5\xd4\xfa\xcd_\xb7\xf17\xe9\xe3*\xf6V+\xf2\x85;a\x13\xd9\xbem_\x91 b\xe6\x8d\xb6\x9c\xd7\x0efA\xfc\xf9\"\x1d\x82\xb5\xd3\xab\xc1\x86+\x7f\x9a.\x9a*%\xf1d\x0831\x90\x1a6#\xa0\xfd\x9d^y\xf39\x89\xe1\xfdK\xc3\xack q\x89\x80'\xac)\xcb\xa9\xfb\x04\x13v\xb7]\x96\xd2^\x11\x8bS\xb7YN\xb3\x8b\xa5\x9f\x0eaaZ\xc1Uw\xe9\xad\xda3\x0b\x92\x04\x9et'A\x14\x8a\x898\xf4\xd3\xfa\xe3\x87q\x06f\x9an\x92\x7f\x1d\x1d\xa5W8\xf73\xc7\x95\x9a\xbe\x91\xa8R\xceCK\xdb_\xbe\xacb\x90Qojd\x18\x94\x02\x80`J~\xccxy\x7f\x15\xce\x1f_x \xd9\xdfu\xfd\x0f\xcf\xde\x9c\\\xf5\xbe\xfej\x1e\x1d\x1e\x1e\x1e\xbe>}\xbf8~??<<|\xb6K\xff&G\x87\xaf\xe8\xbf\xaf\x1e\x04\xfb\x7f\xa5?\xbe\x7f\xf1\xec\xd5\x87\xe3\xf7\xb4\xc2\xfb\xd9\xd5\xad\xfe\xeb\x05\xbf<\xbb\x1f\xf6\x9e\xcd\x16\x1f\x9f\xad~\xba>\xea}\xdc\xbd\x7f\xff\xfe\xfd\xce\xcf\xeb\xdd\xa3\xbf\xac\xfa\xcf{\x8f:\x9dY\xbast\xff\x97\xbd\xfb_\xf7\xf7\xef\xbf\xdfy\xf0\xe8\xfd\xec\xea\xf9l\xef\xe1\xfd\x9f\x1f<\xea\xbc\x8f\x07\xcf\x07'G\x97\x8f\xe8x\xfe\xfc\xdd\xc9\xe9\xbb\xe0\xd5\xe1\xf1\xf1\xe1U\xf8\xe8\xfe\xfd_v\x0e\xe7\xeb\xdd\xfb\xeb\xef_>\xbf\xaf>\xef_\x91\x9f\xfc\xfe\xe5\xe1\xe1\xe1\xf3\x87\xa7\xefO\x9e}\xf8\xf3\xfcY\xf0\xb7W/\x0e\xa3\xbf^=?|w\xf2\xf1\xe2\xbbg\x0ff\x9d\xf5\xdb\xaf\xc3\xe0\xbb\xc3\xbf\x85\xfb\x97\x83\xc9l\xe7\xf0\xd1/\xf7\xdf\xce\xde\x1c=|\xf9\xf2\xfb\xd0\xdf{\xb1\\\x1e>{\xf5\xf0\xc5\xab\xc5\xd5\xbb\xfe\x83\xc9\xa3E\xb8\xf0\xff\xf6M\xff\xe8j}\xfcM?]\xbe}\xde\xfb\xf9\xf4\xeb\x9f\xf7\xe7\xdei\xfa\xed\xfd\xcbW\xdfy\xe1\x87\xe5\xe1\x87\x93\xe7\xef\x83?\xf7\xdf\xac\xb3\xec\xdd\xcb\xd7\xd1\xfe\xe5\xa3\xde\xe9\xc7\xd9\xc3\x9f\x937\xe9\x8b\xfd\xf9\xeel\xd6\x8f\x92\xb7;o\xc2W\x93\x0f\x0f\xa6\xbb\xab_\xa6/\xdf\xa7Y?:\xdc\xfd\xd0{\xfe\xb7\xe8\xeb\xe5\xc7ep\xfc\xfd:}\xfe\xfe\xa7\x9fNw\xd2\xe5\xd7\xcb\x9f\x9fuV\xdf_?\\=\xef\x7fx;{\xf0\xd3\xdb\xe3\xde\xcb\xdd\xde\x9f\xff<\xf1\x9e]\x85\x19\xd9\x9f}\xf5\xcb\xfc\xfat/\xfd\xee\xe5\xfbG\xfbo?<\x88/\x9f\x7f\xfb\xe7\xd7\xdf|\xe8=\xffz\xf7\xc5e\xf4\xf5\xf2\xc5\xea\xf5^\xf4>\\\xfb\x0f\xbf\x8e\xc8\xe1\xe0\xfe_\xbeK\x96\xdf\xfd5\x8b.?\xf6\x12\xff\xa4\xff\xd5\xc3\xf4\x9b\xcb\xd7\xfb\xe4\xd9\xa3\xe4\x9b\xab\xbf\xac\xee__/'\xd7\xde\xdb\xfb\xef\xe2\xb7\x9d\x93\xb7\xcb\x8bW\xaf\xfc\x8f\x93\xbf|\x98\xbf;\xe9{\xef\xff\xf6h'\xfa\xea\xbbd\xfe\xdd_\x0f\xbd\xaf\xf6\x8f\xaf\xe8\xb2\x1c\x9e\xbe\xff\xf0\xe6\xe4\xeb\xbd\xa3\xef_\xbe\x1c}F\xd0\x19\xd2\xbd\xb8N\xc97Lj\xae\xd3.\n\xad\xe2\xc4N5\xf2\x18\xaai\xc6=\x8d\x84\xc34-\xaa\xe9\x1c'\x16;\xf0\xcf`\x87\xd0\x81\xd8\x81\xfb\xb0\x0b\xdb\xd2]\xe9\x8d\x0b\xa4\x9bF\xcf\xaeS\x82\xa6a\xf5\xd7f\xb9\xe9 \xb3\x10\xc4Q2\xcb\x17:*\xe6\xfc:\xee\xf3\\\x14!\xb9\x82\xa8\x92\xe4\xa7\xc6N\x03\xc7I\xa0C+\xb1q*f\xc3x{\xe6BF\xe99%\x06=\x97\x05q\x86\xa7\xd0\xc3\x0b\xe2m\xd8\x85!\xad\x120\xfb\xc5\x00\x9e\xc0\x8c\xfe\xd3\x19\xc1\xae\x83\x90\xf5\xc7iw\xb2\xf0\xe2\xa3hJ\x0eS;p\xce\xe0\xc9\x13\xe8?\x84O\x95\"\xe8@\x9f\x17\x0f\xf4\xc5\x03V\xbc\xaf/\xddq($\xc6I\xa7\x83\xe6\xfa\xf0\xf4)\xf4\xf7\xe1\x1e\x0c\xf6\xf6\xd4\xf7\x0f+\xaf\x07{{pO\x0d-5@)\x9bI\xcf\xe6\xc9\x18\x06K\xe7\xf2\xf4)\xecV;Q\x18\xb3~\xab^\xfa\xbdZ\x90\xed\x9a!\xf6\xf4)\x0cZ\x03\xc0\xd1\xa2\xb4WF\xe0Y\x1c-o\x87\xc2B\x97\xc5\x8d\x12\xe0\x8f\xb0\xc3\xc2=\x8e9>\xf782\xc36\xf8,\xc7\x83G\xff\xe9\x8c\xa0\xbf\xbf\xf3p\xc7\x81\x88\xb1\xe13\x8a\xe0\x99\x8b\xd1n\xb1\x04\x9e\x82\x07\x07\xe0\xc1\xb0x\xa7\xb2\xc0\x0c\xd2>\x1c0@\xa7c\xda\x0d\xdd?\xbc\xd1x\x8c\xc0\x19\x9c\xd1\xcd;&\x0c\xae\xf7`\x7f\x87\xbe\xb0F#\xcbq`\xc8\xb1\xc2\xcf\xd7\xcbf\xed\x0cp\x1d\x1e:\xd016\xdc\xef\x89\x96)b\xe4-\xf3\xae\x06RW\x15\xee=\xbf\x93\xfe)\xf2C\xdb\x92\xec\xb4$E\x91d\xc5\xc9 \xea\xf3\x7f)\x84\xa5\xf8\xab\x92\x9f\xdc{?L\x1f\xb2u<\x90\xff\x18\xb2\x90\x88lQ\xac\xc3gG\xcf\x8f_|\xf5\xe7\x97\x7f\xf9\xfa\x9bW\xaf\xdf\xbc\xfd\xeb\xc9\xe9\xbb\xf7\x1f\xbe\xfd\xee\xfb\xbfy\x17\x93)\x99\xcd\x17\xfeO\x97\xc12\x8cV?\xc7I\x9a\xad\xaf\xfe_\xea\xde\xb4\xc9\x91d9\x0c\xb4\xdd/k\xf6\xfe\xc2~q\xa4\x86\xdd\x99\x83\x04\n@\xdd\xa8F\xd7\xeb\xd7\xd3#55\xd3\xfdl\xaa\x1f\x9fH\x00S\xcaJ\x04\n9\x0dd\x82yTW\xcdT\xafQ\xd2R\xa2H]\xdc\x95(R\x07\x0f\x1d\xe4.IQ\xa4\xb4\x07wy\x99\xed\x9b\xf9#\xfa\x03\xfb\x17\xd6\xc2#\"32#\"\x13\xa8\xaay\xd4\xc2\xac\xbb\x00\xcf\xc88=\xdc=\xdc=\xdc\xafo\xbe\xec\xf5\x07\xbb{\xfb\x07\x87G\xc7\xed\x1d\x8b\xa7\xcbat\xa4\xc8g\xe9\xc1\x13HN\xa0\xdd\xf6\x1cqS+\xc3+b\xc18\x93Q\xd9s\xe8#O\xe7\xec\xe0\x9b\xa9z\x9e\x1d\xa4\xf4\x14\xc35\xc0O\xc0\x1e%c\x0e\xa4\x8b8z\x87\xc4\x13\xa3\xba\x15Q}\x99\xc3W\x178\x1bAO\xd0\x0b\x02\x1e\xac\xb2e\x1a\xac\x97\x98\xf0f\xaf\xaaE\xbb\xca\xef\xe7`\"\x95\xd7s\x9b.\xa6v-;\xfcN\"\xb0x\xad#\xbc\x03=\x0eq\xa3\xe4\xf1\xc8\x87\x8c0\xd3\xfeN\x8b%\xd7\xcc\xc3\xdcD\xf1s\xa4\xe0\xa1\x90\x85+.m\x90\xad@H\xff\xb4G\xb0\xeb \xc2\xd8)] Jr(\xf5\xec\x1f\x1c\xf6\xfb\x07G=\x8a\xd7\xf4 \xba\x8c#\xa6St\xdd\x1f\xf0'\x8c|\xb0\xe7\x03*\x9df\x02\xf3\xed\x88y\x18Q\xfc?\x92p>B\xc8\xa0\n9\x90\x00\x07\xbb\xf0\x08\xa2\xea\xad+>}\x99f+\xe4\xdf\x82\xb1\xd5\xb1d\x0c\xea!\x06\x1d\x0c(jY\xe7\xbaG\xbbZyC\x9eM\xd2\x8d\x897\xab\x0b\xbb\xa7\xa0\x02\x0b\xabM\xe7\xfa\x08>\x84\x80\xca\x02\x942\xa8\x12\x05\xdd\x17v\x9f\xce\xab\xe7\xe8K\xf80\x82\x04\xe7L}F\xd9r\xe7P\x85\xa3\x9f\x10\x9cb\xc3}\x18BO-\xb2\xe6E:\xf4\xb9\xa6\xea\x05K`\x04m\xa8\xe6T@\xc4B^\xbff\x14f\x01\x8f\xf8\x18:s6\x08X\xc0\xd3\xa7#\xe8\xcc\xa9\xe4\xd0\xa6;\x18\xe6t\xdb\x9d`\xf9\xc1\xfe\x01|\x88\xe1\xb2E\x03.\x88\xfa\xe6\xd0\x19\xc1\x91\xa3i\x91\"p\xa4\xb6\x14\x95[\x8a\xf3\x96\xb2\xbc\xa5l\xf3\x96(\x91`7 #\x07\xfb\xda\x87N\xf5\x06\xaa\xe1~3}5\xc2W\x8b\xcc3\x19\x9c\xc2+\xef\x15\x9da\xd8\x81\x1e\x15\xbc\x16\xf9\x9ck\xf44\xc8\xf0>\xf5\xd2Ew\x1d\xbd\xb3\x07\xec\xee[D;Z\xbe\xc8\xaa7\x17KU\xe3\xa8?,U\x15Q$\x94\xf6\x0ce\xe8\xef\xe2 \xad^\x93\xa9\xcdiBq\x9b\"6\x0b\x19\xcf\xd1\x9b\xd6\x1c\xe8\x91w\x9e\xa3\xb7o@o\xf4\xb00\xa07\xc5\xd1\xc1n\xce\xbc\xe5\xd1t\x06{\xb4\xc2\x12\xe8\xf0\xd0\xd1\xe3:\xc5\xe5\x98\x93\xd5H\xdf\x8d\x19/B\xa7\xaf\xa3y~\x85\x12\xd4\x13\xe8\xc1\xed-\xbf#\x8b\x8e\x1b,K\xc4\x13\x14\x8cq\xa7i0\x97\xce0v\xd4\xbbH\xd0-)H^y\xafl\x82>\xf2\xcc\x90\xca\xd0\xe3\x14lJ2\xf2\xc7\xbcJF\xbc\xe7tp\xb8\x0b\xb0\xae\xf92\x8ab\x1b\xbf.\xa3KZz\x87=\xf8\xe4\xd5\xc0q\x81P\\K\xa0\x8cM\x9d\xccq\xe0 \xf4\x91\xf3d\x9d\x0ee\xcb\x1f\x8e\x80\x96\xa7\x07\x82\x11\xee\x94%<\xa5\xfd9\x855\xec@\x02CXW\x10\x89n\x89\xa5CQ,\xa1E\x07\xac\xb6v\x9b\xd6\xb6\xc3j\xcb\xeb\x99\x8b1\xc9\x83(\xb5\x82Om\x82\xb5u\x18\xe6\xca\x8d\x05\xac\xb6\x11,q\xf8\xc8\xbd*E\x96\xe6\xf7F\xd0s\x9c\x13\x08hcG'(\x9f\xb5aQ\x88\xbd\x1e\xa5T\xed\x11\xcc(\xad\xdeAzA\x85\xa7:\x12\x94Qd\x0e\xe0\x96\xbe\xeb\xd3w\x83\x13\xf0\x19\xc5Q\xaa\xcf\x8a\xea\xb3\xbcz_W=\x7f\x15:0\x9b\xc2\xed\x08\xfa\x03\xba\xb1\xae*\x1c\xae\xe1P,+p\xca\xdb6\xf7\xea\x0c\xed\xdd\xc1Q\xe5\xc8[x\x85\x96\x1dk7i\xb2\xb8\x921\xd08\xdb\xc6\xdd\x9f<{\xfd\n\x1d2\xf9W\x9d\x87M\x9e\xe6fXI{S&yMW8\xccwS\xf2\n\xf9\x85\xdd@{[w\xa3\xf1\x9a\xf4\x0e\x92g\xed\xa8\x14\x0d]LPd\x87\xf6\xee\xae\xe2w\x1c\xf0GG{\x8e\xd6\xa57\xfa\xf1\xba\xf4n\xe3\xdd\xde\xa8KU\xd3(H\xf9\x185q\xbbh\xf9\x8a\xe3.\xf3\x11\xa7\xef9\x1b7\x0b\x924^g\xa5\x8eq\xa5j\x94\xcaxM\xd8\xfc\x9c\x12\x03\x161\xc1\xe0\xc3\x11\xdf\xd4(\x8a\x8bP3\xeclT\xf5\x83vN\xa0\x85>\xfaH\xf2\x92Rv\x00f\xee\x0fy\xbc\x0b\x9e\x94\xc0\x85\x16z\xce\n\xa7!\x96\x1f\xc19\xe1\xe34\x18\x85\xde\x83\xef\xb1\x84 u\xda\xf0\x88M\x15\xcb\\n\xa8g\x1e\x84\xderY7\xe4\xfa \xa1\x9f\x16\xfa\x13%]\xbe\xd4\xd2w\x83\xd3\x18l\xd84\x08\xf9L\x9c\xfb2su\xfa\xf1i\xa1\xda[\xf7X\x9ca\xa7:\xe7\xc5\xa9\xf3\xcd\xcd\x9aTN\x9e<\x80\x12\x0bV\xc5\xeeYf1\x8b\xe1\x11\xa4$\xf6.\x96E\xc0\x7f\xe5\xc2V\xd14{\xf2 \xbcb\xb7\x1a\xdb\xfa>\xbc\"\xb4\x8f\xf6\x1d\x17B\xfb\xf8\x00=\xa5\x8b\x0e\xd0\x96\x06\x1bu\xbb\xe07\xfd]\x1d\xc7 \xed\x03\xc7\xb6p\xb6\xd2(\xaez\xea\xb0\xeb\x80\xbb\xa6x\xe1\x94\x89u\x83\xe4\xa5\x98\xebM4\xc89\x85\xd2\x9eUyD\x15\xdc\x8a\xe3\x80\xa5t\xf8\xeew\xf3\xee\xe1\x9d[L\xb7U\x8d\xc9\x12\x97|k7\x9a\xde\x0dWt\xefAWtww_Y\xcb\x81\xd3\xe5w{\xbc$ .\xc3Mj\x92\xd7U\x9a\xca\xd8\x8e\xbbg\xd0\x86\xb8\xfb\xb1\x0b\x16\xabU1\"\xb2V\xd8\xe8\x0e\xa4I\xdb\x08\xa1\x9an\x9a\xeeU\xaf\x94\xf2\xa8\xef\xbd\xaa\x14\xc5p\xeb\xa0:\xbd,F\xfd~5v\xbc\xc7j\x19T\x8b'9J\xf1\xc9\xd3cj\x0b\xbd\x07C{p\xec\xd8F>-\\\xf1\xbe\xd2\xc4e \x068e\x9a,\x91\x88\xceQ\x0d}\xc8t\x9a?K\x8b\xfd<\x80\xce!e\xe9\xc9z\x19\xa4\xb6e9\x1a\xc7-\x1d\xeb!\xe3t\xaap\x9b\xf7\x8e\x0b\x87\xd0\x1aA\xc2\x82\xd5:<\xcf\x91\x9c\x1e\x91=\"\x8e\x93\xab\x89\xe8\x0b\x92%\x86\x1e\xabj\x85\x88R \xe6\x0cm/t\xces\x911We\xd3\xf3o\x9f\xd9F\x82\xee\x9cYC\xa2\xee\xfc\x84\x9e\x8b\xc0\xd7\xe4\x15\xcak^\xbbx&\xf5\xec\xbc\xd2\xb1\xdfnO\x1d\x17\xcf\xa1\xf4\xd0\x14\xdb\x0b\xa7\xebG\xa1\xef\xa5\xf6\xdc^\xa0\x02\x9a\xc2\\<\x89\xce\xf2>\xdc0\x0b\xcc\x15<\x85\x9b\x13\x07\x96\xec\x9e\xd3\xc2\xc5\xb3\xf3l|Cke\xe2\xc2xM't1^\x1b\xf4j\xd2MK\x18B\xb2\xc9\xe6\xd9\x90\xe4<\xe4\x81\x83\xd6w\\Cr(\x0elRO\xb1\xc3\x95\xbd\x19\x88\x8d\x7f\"\xb5\xda\xdf;vl\x8b\xd6n\xb9[\x88\xc65f\xb8\xc0\x8e\xa9`[Fp M7\x19E=\xf5\xda\xf9\xdc\xfe\x89A\xefv\x928\x1f\xda_xW^\xe2\xc7\xc1:\xbd\x9dy\xa9\xe7\xec\x04+u\xd4;\xe3\xcf'\xd7\x83^gr}\xf8b\xbasY-\x12\xb1:\xc7\x9f\x0f\xa7mg\xb8s\xb9RI\xdd\xd8\xeaZ.X;\xb2\xef\xb9\x19K\x12/\x0c\xd2\xe0K\xf2\x83x\xd9t\xf3@\xd8\x92\x98R5\x15\xd7~\xe8Y\xce\xd2y\xb4n\xb4\x12 k\x95\x85\xde>\x1d\xf7\xa6\x0e<\x85\x8e&'\x95\xed9\xdc\xd6\x84\x8a{\xaf\xbb\xa2\xd2\xb3\x1d9\x8e\xb0-1\x0bm\xdcMI\x922\x15\x8e\xe5]DY:\xbcXz\xe1[\x0b\x86\xe0a\xc4<\x19hB\x81M0\xa0\xc0\xe3\xdd=\xbd@\xb4\xbb\xbf\xeblc\x1e\xc6`\xf8\xdd4\xfa$zG\xe2\xe7^Bl\x0c\xd1\xda\xa6C\xa6t \x03\x96W\xe3\x9e\x1a$\xaa`\xbb!\xec\xe9\xc3:\xf4\x0f\xef\x1e\x98\x027Yy4[\xcaUE\xf7\x0e\xaa h\xf8\x04\xefU\xb98\x93\x05\xaad\x8f\x89\x02\x87U\x81\xc2\x03\xae\xfeS%\x81\x98N\xb8\x14\x93e\xc8\x05\xcarIf 8\x85\xa4+\xf2\x87\xe5\x05\xebg\x0d\xb3\x12V\xe6\x0d\x03k\xf2\xa4\x8e\xfal\x80\xaa\xc2<\x92\x93\x1b\x06<\xdfX\x1b,K-\x9a\xc9E}8\x05_\xa4\xfb\xa3\x9b\xa2\xf2\x82\xe0\xc1DS\x19\xaf\xc2\xeaa/\xc3B\x15;\x1aA\xc7\xa3\xdb\xae\xd3\xa3\xbb\xad)~\x80\x89\x9dm.!t\xfa\xdc7\x83\x07\xc1K\xb9\xa2\xb9l\xf2f\n\x90\xd89\x81v;\x84'\x10\x9f8\x10\xf0\x00\x83<\xbcv\xa8\xe6\xc6\x16s\xfa\xa0\x18\xcb9\xa5!~.Z\xed*\xc7\x11\x15\x8f\x83\x1c\xd7TdfX+\xe5\xb2\xdb\x10\x1d\xcd\x87\xac\x88\xdf\xde\xc6\xf0\xa4\xa5\x12 \xae\x86(qW\xf5\xda\x86\x94G$5\xe8m\xc4\xccUB\xd8\x95\xb4$\xef\x95.\x06h\xdbf]\xd4/`\xcc\x9d\x06NE\x07B\x18\xc2\x8c,IJ\x10R\x8ap\xd8\x8c\xa8\x02\xf5\xaa+\x99O\xfa\xb6\x13-D@1\x88\xbb\xe2\xdb\xee^\x95\xe8 \n\xaeO\x92\xb5\xbb\xaf\xcb\x92\x85\x8c\xe0\x8eC\xc8\x0bhu\x83\x04%zSx\x01:\xa5\x01c\xda\x11\xa3H:r+>\xcc]\xe5\x149>\xe5\x88hZF\xb3\xb2\xbe|\xc2\xcb\xc7v\xe8B_:\x9e\xd0w\x93e\xe0\x13\xbb&\x91\xb27N\xa76\xa5\xaaI\x193\xef\xbeR&-H\x93\xa8 0^\xefe!0)\xdfd\xdc\xd7\xe1\x14\x02J\x8dQK\xf9\xe8\x11\x84\xf0\x94\xd9\xf4R<\xd7\x88\xa6\xb6\xd8\x03\xdbv9f\xa4Z\x99_\xf3P\x98YOx\xfbt\x08<\xc5\x1eS\xda\x1e@\x1b\xbd6P\n\x0c\xf9\x03\x1c\xa0\x93\xbf\x84a\xfc\x02\x87\x91\x7f\xfar\xc8_\x0e\xa1\x83\xceXO\xa1\xe7\xb2/#\xad\xd9\xf0\x8aG\xbc`\xac#@\xd6\x11\xc3\x13\x08N\x1c\x88Xh\xb1t\x1c\xd3\x9e\xe8\xfd\x11\xa3;\xe3\xc6~u\xb76\xed\xe2A#.\x19\xe5\xb3\x94m\xb7\x94\x1dp\x1bIO3\n\x18ZJ\x0b\x15\xc4\x16M\x08\xb2`\x8d'\x93lv\xd4\xebu\xe8\xdf\xf9|>\xad\xb8\xa3\xc7\xa2Po\x97\x15\xea\xed\x1e\xcc'\x93lN\x06\xf8sN\x06\xf4\xe7\xa07\xc3\x9f\x83\x9eZ\x05\x9dd\x0b\x9b\xd9\xf5\xc7\xac\x99\x0bSs\xe8\xd85\xfe\xbc\xa1S\xe8\xc3e\x9f\x0e\xe5Jg\xe4\x00\x8b\xcf\xe6\xf3\xa9\xf3\xd5\xe0\xbd\xa52\xf0\xf2`/\xe6\xf3)\x02|sC o(\xcfk~\x9b\xe7Fw,\x16\x89A\x95Y\xb1\x999\xe9\x11\xf6g>=\x15i\xefm\xde\xe9A\xaf7\xe3\xb5\x8e\xb9G\xcd\x94\xd3\xcd[\x0bEL\xc7X\x87\xe5|XU\xff\xce\xa5^\x8e#\xd1\xd5S+\x0f\xed\xe6BX\xad\xbf\xd2\xef%\x8cx\xb6X\x1bGg\x9f\x8e\x8a\x91\xe2\xa0\xe7\xd0\x06\xdf\x05\xeb\xd2\xba\xeb\x9eH\xf9\xa9r\xe9\xb0+\xc2w\xdf\xc6\xd5s\x898\x10V\xa3\x01\x8am\xac;\xb1\xf0\xd1Z\xe3\xc7\xff\xe5\xe7~mj\xddkd\xf5\xccY\xc8JvdS.\x9c\x1f\xf13<\xe2;\x18\xb7\xc72\xdb=\x1a\xf7rC\x02U\x13\x9f\xd31\x8d\xa8F\xde\xd7Pr\x14\xff\xa2\xdc\xdf/\x1d\xb7\xdb\xc1\x14\xe9y\x00O :q\xd81\x87\n\x06\xe98\x98\xa2\xeb\x8dA\x92l:\xcf\xd4`\x83A\xcfU=s\xa3\x96g<\xb9\xf6{\x9d\xc9\xf5\xec`r=;\xeaL\xae\xe7\x07\x93\xeb9~\x99O\xb2^\x9f\x92\x82\xac\xd7?\x9cOw.kpf[zx\x1f\xe4\xb2S\x14\xdfR\xc7a\x96q\x81>\x11]\xdb\n2\xdd}\x12\x0f\x9dJ\x90\x03\xebG?g\x0d\xc1zV!\x14\xd6\x8f\xfe\x96\x1e\xfc\xb7\xf5\xe0\xbf\xa3\x07\xff\x8fz\xf0\xcf\xeb\xc1\xbfI\xc1\x9e\x02\xfe-=\xf8\xdf\xe8\xc1\xffV\x0f\xfewz\xf0\xbf\xd7\x83\xff\x1e\x05?W\xc0\xbfC\xc1\xbe\x02\xfe'\x14\\M\x91j\xfd\xe8\x0f)x\xa6\x80\x7f\x81\x82\xab D\xad\x1f\xfd}=\xf8\x17\xf5\xe0_\xd2\x83\xff\x17\n&\n\xf8\x7f\xd5\x83\x7fW\x0f\xfe==\xf8\x1fP\xf0K\x05\xfc\x0f\xf5\xe0\x7f\xa4\x07\xffc=\xf8\xf7)8P\xc0\xffA\x0f\xfe\x03=\xf8?\xea\xc1\xbfL\xc1\xaf\x14\xf0\x1fQp\xf5\n\xab\xf5\xa3\xff\x89\x82_+\xe0\xffY\x0f\xfe\xa7z\xf0?\xd3\x83\x7fE\x0f\xfeU=\xf8?Qp\xa4\x80\xff\xb3\x1e\xfc\xbf\xe9\xc1\xff\xbb\x1e\xfc\x7f\xe8\xc1\x7f\xac\x07\xff\x1a\x05\xff@\x01\xff\x0b=\xf8_\xea\xc1\xffJ\x0f\xfe\xbf(8S\xc0\xff\xb7\x1e\xfc'z\xf0\x9f\xea\xc1\xff\x9a\x82\xab d\xad\x1f\xfd\x19\x05\xdf(\xe0\xbf\xd0\x83\xff.\x05?S\xb7\xc3oS\xb8\xa7\xc2\x7f\x9d\xc2\xdf,\x14\xf8\x9fSx\xaa\xc2\x7f\x83\xc2\x93jH#\xebk=Y\xfeZO\x7f\xbf\xd6\x13\xda\xaf\x91\x88+\xe4\xed\xeb\xbf\xa3\x07\xff\xbc\x1e\x8c3\xa0\x10\xc3\xaf\x7fA\x0f\xfeE=\xf8\x1f\xe8\xc1Hh\x15\x8a\xfa\xf5\xdf\xd7\x83\x7fI\x0f\xfe\x87z0\x92 \x85,\x7f\xad\xa7\xd6_#eR\xa8\xf5\xd7\xbf\xac\x07#\x99P\xe8\xef\xd7\xffT\x0f\xfe\x15=\xf8W\xf5\xe0\x7f\xa1\x07# R\xf0\xed\xeb\x7f\xa6\x07\xffs=\xf8\xd7\xf4\xe0\x7f\xa9\x07\xe3\x9e\xfd\xab\n\xf8\xd7\xf5\xe0\xdf\xd4\x83\xff\x8d\x1e\x8c\x9b\xf3R\x01\xff\x86\x1e\xfc[z\xf0\xbf\xd5\x83\x91\xd9\xff5\x05\xfc\xdbz0\xca\x00\xca\xc6\xfc\xfaw\xf4`d\xb1\n\x07\xfb\xfaw\xf5\xe0\xdf\xd7\x83\xff@\x0f\xfeC=\x18\xd9\xb7\xc2\xd8\xbe\xfe==X\xcf4\xbf\xd6s\xc7\xaf\xffH\x0fFv\xf2\x93\n\x18\xd9\xc9\x17\n\x18\xd9\xc9_W\xc0\xff'\x05\xbfU\xc0\x7f\xac\x07#'\xf8D\x01\xff\x89\x1e\xfcgz\xf0_h\xc1\xdf\xfc-}i\xe42\xd5\x981\xd6\xd7\x7f\xaa\x07\xff\xb9\x16\xfc\xcd\xcf\xe9\xc1\x7f[\x0fF\xd2\xabH#\xdf\xfc\xbc\x1e\xfc\xf7\xf4\xe0_\xd4\x83\x91 (\"\xcd7\x7fW\x0f\xfe\x05=\xf8\x97\xf4`\xa4\xdf\x8a\x90\xf2\xcd?\xd2\x83\xff\x89\x1e\x8c\x84Z\x91/\xbe\xf9\xc7z\xf0/\xeb\xc1Hc?S\xc0\xbf\xa2\x07\xff\xaa\x1e\x8cT\xb3\x1a\x93\xc1\xfa\xe6\x9f\xeb\xc1\xbf\xa6\x07#\xa1>S\xc0\xffJ\x0f\xfeu=\xf87\xf5`\xa4\xc8\x8aT\xf0\xcd\xbf\xd6\x83\x7fC\x0f\xfe-=\x18)\xf2\x1b\x05\xfc\xef\xf4\xe0\xdf\xd6\x83\x91\xf4VC\xe4X\xdf\xfc{=\xf8w\xf4`$\xa6\x8aP\xf8\xcd\xef\xea\xc1\xbf\xaf\x07\xff\x81\x1e\xfc\x87z\xf0\x7f\xd2\x83\x91\xc6*\"\xe47\xbf\xa7\x07\xff\x07=\xf8?\xea\xc1\x7f\xa4\x07\xffg=\x18I\xef\x0f\x150\x92\xdew\n\x18I\xaf\"\xe3~\x83\xa4W\x11f\xbf\xf9c}i$\xbd?\xa3\x80\xffD\x0f\xfe3=\x18\x89\xe9\x97\n\xf8O\xf5\xe0?\xd7\x82\xbf\xc6\xd5y\xa92\x1e\x9c\xab@\xe1<\xdf\xb0\xe3\x9a\"\xb9|\x83\xc2R\xa4\xc2Q\xb0|\xac\x927\xe4\x1bI\xe1\xcab\xf2\x08a\x8ex\xdb\xab\xe9\xee\xa3Q\x945u\xdc(5\x84tL\xa6\xa5\x17\x9aT\x895J!\x83_\xc8\x81>\x1d\x89\xa2q\xcbx\xf1~\xa3\xeaKo\xde\x12zc\xbcK\x92\xf2\xe4\xdd\xdc\xf2\xc6\x9c\x92\xe4\x81\xa3}\x93\xdb]\xb2\xc2\xee\x82\x1aL\xa6x&\x9b)\x9euv\x12\xf4 \xeb\xf5:\x93\xeb\xc1|r\xbd\xebu&\xd7{\xbd\xc9\xf5\xfeEgr}\xd0\x9b\\\x1f\xd2/\x87\xf3i{\xe7\xae6j\xd1\xc9\xf0>\x9d\xf4:_N\xc7\xcf:?3\xbd\xc5\xff\xbf\x1a\xb8\xef\x11v;\xeeu\x8e\xa7\xf4+{\xc8\xbf \xf4v\xfc9\xfb\xd9\xeb\x1c\xc3t\xe7\x8e\xdd\x0f\x99g\xd8Vv\xae\xdc\x085\x99\\{\xfedr}\xd1\x9fL\xaeg\x87\x93\xc9\xf5\x9c\xfe\x87\nV:\xe1l\xc6q\xca\xd9\x9c\xe3\xa4\xb3Y\x9f\\_0\x85k\x8f+\\\x0f\xe60\x99\xa4\xf4\xf5\x8b\xc9\x84\xbe\xeb\xf5P/;\x9fO&\xe1d\x12c\xa1\xc1\x11\xfbs<\x99d\xfd\x83#Z\xa2\x7f\x84\xd6\x16Z\x11\xfb\xd3g\x7f\x06\xec\xcf.\xfb\xb3\xc7\xfe\xec\xb3?\x07\xec\xcf!\xfb\xc3\xea\xec\x1d\xb3?\x1ek\x81un\x9f\xfe\xd9\xed\xf5\xaaq\xae\x98y\xcd\x826\x0b\xecm0\x9d\xcd\xda\x96\xba\xe1P\x0b=8\xe4\xc3>\xbc\xd0[\xc9\xe8R\xd3I\x9d\xd3\x99\x9a\x1fL\x98\xb6{r\xad\xda\xba<\xad\xe9Mt\x0d-A\x95\x06\x8dU?\xeb\xfc\xcc\x84)\xdaQ\xd3\xceT\xed\x93\xeb\x191\xd9\xd7\xb60\xe4\xf9w2\xe4\xa1\x89l\xbcq\xbf\x96\x92E-\xcb\xed~\x9e\xcer\xb6\x96\x8a\xce\xeb\x8b.x\xd1-\xcd\x07\xb7&\xdb\xa9S\xb5>\xce\x8c\xd6\xc7\x85\xc1\xfa\xa8\xb5\xb5\xe2\x1d\xe8\x8d\x0c\x92\x0b\xbdA\xf2\xaad\x90\xd4\xd7G\x9f\xcd\xca\xaf\xdd\x14&\x96\xf1<\x8fs\x8f\xf3\xdf\xa6\xd3\x86\x96:\xfbt8\xbb].oW\xb71\xb9Mn\xd3\xdb+\xe28\xa7\xdc^9\x8e]\x98\xbb`}`\xa9\xf6NX+\x15}t\xfb\xc9'\xb7\x9f\xde~\xf6\xe2\xf6\xec\xf6\xcd\xedO\xbd\xa8T\x04mX\x9a*+\xfa\xb7\xdc\xa4\x7f\xe2\x8d\xa6\xe6-\x17\xf7\xfb\x87\xf6\xe9\xb0\x7f\xf6\xe6v\xf0\xea\xa3\xdb\xdd\xcf>\xba\xb5O[\xe3\xfe`w\xeaL&\xb37\x7f\xcd\xb1OG\x93\xc9\x05\x92\xf1\xf3\xa9#\xbf\x93\xa4\xb7\x83pv\xbb\x1b\xcfJ\xef\xa4\x8b\xfc\x9dg\x9d\x9fa\xef\x04.\\I\x03\xbb\x97\x8dJ0\xaf\x9b\xcd\x98\x97Y\xe48\xa8\xe6\xf4a\"\xc7a\xd5\x05\x98'@\xeb7:\xd0V;\xcc\x82l\x06_\x12vw\x9b\xe7\xc6\x9cy\xa9w\xae\xcf\x7f\xba\xf0\x92\xc5\x10o\xb6\xc5\xae\xf2p\xe5\xad\xf1\x99\x1d\xd1q\x07\x1a\x0f)\x91f\x0b+(=\xbd\xbb\\\xa6\\\xc6\x11rYU^\xe3\xf6o\xc55\x97\x0bf\x8a\xdb\x8b\xc7\xe1\x03\xed\x9d\xdd\xc4\xec\xc8\xa8\xb3%\x87\xdb\xd9\x92Y\xd6\xcc%\xf1b\x1b-\xc8\x04\x03\xb9\xe8\xa4_1\x13T\xd2U\xfd\xcaD\x18\x7f;f\x1e\xeb\xe3\xfe\xb4\xde\xb4N?\x89\x9c\x0b\x92\xf6\x81e\xed\x92\xc1\xdc\xab\x11\x13x\xca\xf0K\x82\xf2i\x19\xb8\xf0(\x12fe`\x82%\xbd\xf2\x1d\x8f-/u\x1c6\xca\xd2Z\x84\x970\xb5\x9d\xf1d\xfa\xd5\xfb\xdb\xe9\xce%\xd2\xf1\x0f\x1eYR\xb1r3\xb7\xf9}\x07\xa7\xfb\xe1)R\xf4\x89\xed\xdc\xe2\x06\xea\xb69`\xea`M\x1f\xf4\xbb\x1f\x9e2~\xf5\xc1\x9d\xe9z\xcbn\xa1\x0b\x1b%n\xc2\x03\x01o\x1e`\x18\x8d!x\x0e\x13\xfb\xb3\xd2\x8d\x9f\xcdQ'\xcf\xe5\xa6$\xbe\xccs\xb9\xed\x8c?\xefN\xdb\x1f\xect\xc95\xf1m\x8cR\x16\xe0m\xa8\xe2[\xf7\xe5\x8b\xf3\xef\x7f\xf6\xfa\xcdk\xbc\x87j\xe1\xa5\x15\x8b\xdf\xf6Kb\xdf9\xefw\x99\x03W\xd9\x15\x7f\xbb\x99hE\xcc\xd9%\x08\xb7M\xfa)\xed^gl\x9d\x9f\xfbQL:_$\xe7\xc9\xc2\x8b\xc9\xec\xfc\xdct\xa7\xe8\xae*\x05\x8dc\xff\xc6\n\x83\xe6C\xdbf\xb3&\x18\x03\xd2\x96\x85\x87\xac\xe3\xd1\xa3\xdc5\\\xa6I\xe3T\xef\xe6Y\x90\xa5\x0e\x0b\x1e\xc6c\xc6\x90;\xcf\xbe\xce\xfb\xd3:?_F3/Y\x9cSF\x7f\x9e\xc7\x94;?\xd7\x1c\xb9\x14\xbf\xf4\xf2\xf6\xdc\x16\xb5J\x93$\xa6\xa3<\x17\xc1\x1cl\xc5\x83\x0b\xa4\xb33Q\xa6\x0fJ\xde\xca<\xc4P\xbe\xdau\x99\xf4\x85\x7f-\xbf\xba\x82\xd7]N\xd9\x8dU\xe12\xfe\xa0s\xff\xe3\x9f\xce\xfc\xda\xc2i\xf9\n;\x8e0\x90\xc6\xfd\xa0\xe3\xac\xc1\xb1\xa61j\xf6\xb2X\xf9\xe6a\x16;\xa8]\xde\x89L\x18\xeb\xbb\x10\xb2\xdb\xc8\xe8\xc7')\xd7\x08\xf7\xfa&L8\xb8/uh\x12I\xc6\xd3\x07\x12B\xb42\x08\x0b\xd5\"\x89a\xebe\xe0\x93\xa6\x89\xdf\x08\xb9\xf4Bo\xccPH\xbb$-;\x14\xc1\xb6l\xba;\x8b\x04i\x1d\x8c\x1aE\xba\xebh\x8d\xa9\xda\x0bl\xc4k\x15.t:\xf9\x1c\xb9\xd0\xbb\x13\xbb\x15\x93\xf4\x974\xf8\x90\xc7\x13+T\xb6\xe3p:\xee7q\x9f\x87\x1cI\xee\x8b[\x1e\n\xa5t\xa5\x9b\xb1\x0f\xdf\x93Mw\xb2:\xad\x18q\xca\xae\xb9E\xc7\xa7\xd5n\xb7%\x0c\xe1at\xc6\xb4\xe1)^\xb3\x0f\xc7\x01\x9dm\x96\xe0~\x83}m\x1e\xed~\xe3hM\x18\x14\x8bT\xa5\x0e?P\x99n\x96\xdd\x95\xfb7\x12#3r\xb3\x1b\xa1\xa9\xb6;\xf2\xd5Q\x8clb\xb1\xac\xdb\x12\x80e\xcd\x96\x00\x17Q\xb4$^\xc8!\xa7\x94\x0d\xf0T\xae\x16\xb2\x9d\x94\xae \x93\xc8F\xf7\x90)\xb7_\x8c\xd2&\xc0\xb5\xb8$\x1b\xa8\xee\xbf\xdd.0\xd6\xf4-v\xa1f\x03\x16\xdd\xd0\xef\xbe\x101QO\xd3P\xd7\x80\x95\xbbe\x86\x1brv6\xcaoW\xf5\xef\xb7\xedv\x8f\xf6\x1c;\xb4\xf7v\x0f\x9c\xad\x8c\x90\xe63{_\x7f\x1f\xeaPw\x18\x0b\xed\xc3\x83\xc696,s^\x80q\xb3\xcc$\xd0zE\xe0!\xdd]F*\x0c\xb7\x02\xbci\xad\xbe/\xeaH\x04\xb5\xdc\xd5\xd4\x00\xfc\xaed\x84\xe1*\xc3\xda\xbe\xcb\x1f>\x8e\xc4\xf6\xc6\xe9\x14/lx\x86l\x17\nT\x85\xd0^\xfa\x94\xe0\xe4\xd3a\x14\xe0}\xe4Jp\n\xde8AQ\xdc\xa7\x82\xaa\xaf\x91\xc7\x01\xee\xa3Q<2\xdc\xa1P\xe2\xf8p\xbd\xeb\xd1\xde\xd6\xa8 \xc8l`\xa2\xf8\xfd\x928\xf4\xe8\x11\xa6*\x18\x0f\xa6\xec\xd6*\xfd\xde\x9b\xba\x0c\xd8\x9fR~\x96\xb7\xa5\x18\x8e\xa1z\x04J)Af<\xd4Ub<\xdcu\xd6\xfa\x87\xd5\xfbF\xe2:\xa1N\xe5\xd5W\xd5]\x83\xa69\x14wx<\xddd&H\x98\xf8]|e\xf8\x18\xba+`i3b=\xe5\xa3\x0d{\x0e\x96\xbc\xc1(M\x0b\x17f.\xac\xd9\xaep\xe1\xca@1\x91\xee\xca]\xbeAO\x8b\x99\x0b\x0b\x17\"\xb8\xe5w\x0c\xaf\xe8\xa6\xbc\xa9\x1fA\xcd\n\x8a\xb7\xee~\xfak\xbc\xad[]\x91\xeaA\x94Yy\xb6:\x8b\xdeC\xdel>L\x91\x8d\x85dZ\x96\xcb\xfd\x0f\xdea\xb91\xd1\xdf\xcd$\xc6\x07j\xeb\x9e\xa2\xa1>|P\xbf\xaf\xf7b\xea\xf7\xaaV4$\xd5\xbd\xc6 \x1f\x9b\x1e\xf04\xc4\x17D\xf4\xcbh\xae\xde\xd7\x04I8\n\x0d\xb5@.\x1dQF\xe7 &\xfa\x042\x16C\x9aO\xabW:\x13\x96\x11\xbd\xdd\x0e9\x06Q\xa8Z\xbd2\x0e\x10)z<\x13?\x85F1YH\xc9\xf7\x13\x8c\xcd\x8cX/\xc8\xee\x1e\xeb=\xd5\xf6zz\x83\xe8^\xbf\x8a\x12\xc8{\x95@H>\x17\x8e\xaa\x885\xe7\xf0*\".U\xb1\x00\xbdI\x84\xad\xeb\x99\x08\xa2WuOY\x94K\xc5\xdeM\xb5\xc4L.\xc18v\xb5\xc8\xd5\xfd5\xb0B>\xb9q\xe1\xd2\x85\x95\x0e\xfd)\x9a$\xdalT\x17\xf8\x84h\x9e\xbc\x83\x11\x9c\xc3),`\x08\x9e\xf6\xddk\x18\xc1E^BW\xc7\x19e\xf4\xb4\xa2wT\xacY\xc3)\xcc`\x08\xef\x1c\xfak\xa6\x16\x7fA\x8b\xd3Z\xaf\xe5\xe2\xd7\xa6\xe2\xcfD\xc5\xd7\xean~F\xf9\xb9\x8f\xd62u#\xe3&\xf5\xe5`Q\xad\xbe\xba\xd7\xcey\\\xe23\x0c\xd5\\\xb3\xbb\xf2\xf6Zgy\x85+T.\xae\x04;s\\8\xa7\x909S\xfc\x06\x9aU\x1bB\xc4\xa1\xefJ\x0f\xd4\xb1\xb5\xec\x10\x1ea\x90|=\x8dz\x0d#8Cer\x1e\xd9\xc8:?g\x89\x0eg\xe7\xe7\xa6\x0c\xd3_\xc0\x08^H\xaf\x91\xeakzj\x87\xf6\xbe/\xea\x0e\x83o)\x8e\xc3)\xa4,\x984*Vk2H\xbe\x84\x11|\x81Z\xd8\xa28\xd1\xcbD\xc6\xc9\xbe\xb4\xdf\xba\xf0R\xcc\xe3J=&n\"\x03\xb5pQm\xb5\xf6L]\xbe;3F\x95\xd3qc\xec\xb1\xfe\xd4\xb7{\xbc\xaf\xf5\x0b\xc9\xbe}\xbf\x90\xaa\x8c&;\x88`\x01o6\xb3\xd31\x99V'\x83~2\x89\xbey\xb3\x19\x06\xb5* \x94#2\xaf\x8eLq\xe0\x88\xca\xbe\x1a\x99v~\xab\x93\x1b\xde\xcf\xe2\xb3\x91D\xc4\x99i\xe8l\xc48\x7f\x9cbXs[f\xf3t\x8aM\x90\xa6&\x8c\x08m\x8acx\xac\x8fi\xac\xb8\x9ad\x06\xa9\x81\xbbE\x1d\xeb\xa5\x80\xbd^\x95\xdf\xfb*_\xa7\"\xc0@\xe5\xfe9\x8b\xfe\x1e\xd3\x15WytI\x1c\xf8\xc8K\x15G\xd5\x92$\x80a\xd7k%\x81O\xbd\xb5N\x0c\xc8\x9f\xbfB\xa5v\xb5\xc8\x8d\\\x849\xb6T\x8b\\\xcaE\xce\x88\"l\xacJ\xcfQ\x97^-r^*\x82\xca\xf4j\x91\x0bE\xee\xf9^6\x9f\xab\x1d~W\x996\xef\xa7\x02\xf2\xaeZ\xe8z\xe3@\x94g(\x17\x9c\xc25c\x0b\xaf\xe7\x1b\x07\xfe\x13\xb4:v\xe1\xda\x85\x17.<\xab\xa2~\xf2.\xc0\x08|Z\x1d\x96\xef%\x04\xde\x0d\x158p\x06\x98\xcayA[\xa3r\x9e\xd0\xdb[`\xcf_\xcf\xe7 I\x8b\xe7\xecw\xad\x00B?)\x06\x10\xbb\xc0 vy\xf4T\xf6K-\x8f\x1d\xbd\xd0w4\xb7|6\xf5\xb6\xf5\xc2\xa6\xc4=\xc0\xab\x1e\xec\x1bqtY\xbf\xb1\xb5\xa5\xda\x1a\xc2\xd7\x06\xf8Um\xef\"\xbb\x9d\xba\xd0\xd6i\x9d\xf1\xedE\xed\xdbi7\xf4V\x84\xe9/\xf1\x1b\x06jY\x91$\xf1.9\x98\xff0T\x7fc\xe8\xf4\xaa\xbeYfYR\x83\x88\xe6\xef\xcf\xf4\xef\x0bQ\xcd3\xbcvi~\xed\x0b\xe6.P\xcd\x1d&>\xb9Xf\xd3\xfa\x13\x0ch\x8d'\xbd\x96\xd0P\xa0\xb4\xfaE#\xf6 \xe9\xed\x19\xd74\x98\x9b{\x9b\xd7\xf5\x16\xe7\xc3 \xaf\xc1\xed\x08\xe6.<+\x0e\xa2\xe6\x86_b8\xc5\xd7\x88\x88\xaf\xd1T m\xe0Zy\xf0Y\xa1\xb1q\xe1\xa5az\xcf\xcd;\xba\x10\xe3\xcfD\xccJ:\xa83\x11M\xb6\xf4\xa2^v\xbc\xbb\x11\xdb\xe9\x16 3\xf5\x94\xed\xae.i\xdb\xca\x87<\xad\x0e\"\x8cA\xf5\xa5\x89\xb7\xaf v\x85\x15\x8e\xdbm2\x85\x11:\xf5\xa7\x95\xcbq\xce\xb7\xa11\xfbv\x86W;65\xa1@\xd3\xb0\x8cx\xb0\xd7\xd3i\xcc\xfa\xaa\x08\xf5@\xda\x03\x9ewO7\x89\xa8Q\x81G\x10\xa8\xf38gv[\xcd\x89\x123\xef\x19S\xa5.1m\x82M\x1c\xc9\xd2\xd4\xf2\x8d\xf4\xa8Hm\x00#X\x9e\xc0\xba\xc6\xe4\x81\xb9\xb9\xc7k\x83]\xa0e\xfb\xa8\xb1\xc0\xdc(C\xc9\xcbn\xe1lh\xe3\xa0m\xcc\xd03YG\x13i\x1b3\x96[\x88>\x96T\x0c3\x0d]\x14\xe6\x82V%Bg\"+\xea\xd8\x0f\x8dCO>+T4\xf4\xe9il\x0dO`i\x9c\x99K\xb4\xa7\x88\xf91\x98UV\xe8\xce\xb80L_\xe6\xe4\xfa$\x1fox\xae\xf0\xfc\xbb@,J\x11\x7f\x86\x90\xd9\xf4H\x8cP\x86^\x89\xc9\x8c,\x9b3\xce\xe1\x94\xf6p4b\xc7y\x8fW\xc2P\x13\xeb=7\x9b\x9cQE\xa3\xe7 \x171\xf1\xde*OT\x83\xf0\x0d2L\x94\xb2\xfd\xc2\xb7\x1d\xfdF\x16u\x14\x1f\x0dI\x88\xbf7\xa6\x89\xbf@!N\xaaU?\xf5\xefP\xba\x93\x8a\xa9\x03\xba\xa0\xfb\xe6\x1dm\xad\xdc\xc9\x80\xa7lS\xa0\x8c\xd3\xdb\x96\xd8\xf0r\xd8\xf5\x0b\xfa\xecBV{#D[\x16\xdb|'\x97}\xc7\xfc\xd0\xd9\xd4o\xc0\x12\x13\x99)\xe7?(\x82o\x99\x88P\xa6\x91\xfa\xeb\x0e{=}\x0c\xca\xbb\xfbN`\x10\xe1\xc8\x85\xe0\xce\xc7\xe2\xbd\x9e\xfe\xbe\xd0Qc\x97\xd4ZE\xcd\x11\x8b\xefnpHc\xaa\xc6\x08o`G.\x84\x1b\xdc\x0ehf\xb2\x1a\xbd\x816^=)\xc5\xa7\xcf5KR|\xfat\x1c@\x1bX\x8c\xfaqh\xf0>\xbf\xfbl\x9b\xf2\xae\xe8\x8c\x11\n\x0b]s\xe6\xf92y\x11f+\x96\xb0K\xd5R\xf0\xd7.I*\xf1[vfNT\xddEV\xca\x0c\xa4#\x15\xc2J#\xa9\xe5\xc6S\x18V\x0c\xfe.\xc46\xcb\x1b\x94\xd7\xa6\x0dO \xd5XD\xb8'\x1aMh5K\x0c\x0c!\xd0\xe3\xa4\xf7-#M}\x92\x83\x9e\xc8\xe9/c\x91\x9e\xe0f,\x0f\xbf\x86\x89a\x8cN\xf4\xe2D\xea\x15\x8d\x83v\x1b\x13\xc4o@\xc1\x9aB^7N\x84\x81\xb8\xdc\xfd\xa6\xe6\x9eAy\xdc?\xd4_B\xd4'\x0dQme<\x81X\xbf*\x82&\x06\x1b\x9a\xee.\xd7\xf6r\xa8\x8e\xc4\x85\"\xec\x84\xb2\x92\xe8D\x83\xa99\x02\xa3\x00\xca\x9e\xb7\xd0\x19$\xd3\x96ZWJ\xb5\x96(\xbci\xcb.P\x0e\xbe\xbd\x859\xfdoI\xff[\xab\xa5f\x98\xb3\xfc\x94\xb2\x8c\x1c}\x99\xae\x8d\xca0\xba\x9c\xa1r\xce-\xa3\x84\x87~)<\xbe}\xcb\xcf74\xbb\xeb\x8b\xf2\xb3m\xb1*\x90m\xdf\xb0.\"8BUS\x01\xb6\xd6^LB\x0e\xc0\xf7\xd7\xac S,I\x05\x0b\xd5P\x05\xf8Z\xaa\xd2a\xe2\xda\x8d\x0bW\x0e~\x9f1\x03\xf7\x8d\x9e/\xcd\xee\xbb\x8b6&'\"-\xac\xa0\x17\xe9\x89\x03\xb1\xc8\x8a\x12\xea{\x17\xdfy+\xeasS\xec\xe96\xa2\xce\xb6\xdc\xb4?\x0c\xb4#\xe0w\xbab\xae\xa3\xf8\xb6h\xd4\xdd\x15\x1a\xa6\xa4\x1d\xfd\xaa\xec\x16\xe9',\xc3d\x82\xc5\xf4d\xe3|\xfa>^F^\xba;\xe0\xb6w$\xe3\x95\x87\x07{\xfa\x87/\x85\x86E\xf7\xa4\x7f`|dj\xacP\xd9\xe8\x1f=_z\xab5\x99\x99K\x98\xda\xa4\xcfJ\x8db\xa6\xdc\xb1\x0e\x83*o\xea\xeb+\xe9\xeb+\xcfr\xf3G\x05^\xe8\xee\xd5\x07D\x01r\xfbGu58\xae(\x0f\xd0\x18R\x81 \x03H\x05,<(*`a\x0b\xa9\x80\xd1\xfeQ\x85q\x9bG\x05\xfcC\xe2\xbd\xcd\xfb\xd1\xea\xbb\xdbm\xc1\x88o\xc1 '\xf8\xf8\xb3\xd5\xca\xc6tW61\xf7\xc6\x1d\xd9\xec\xcf]#L\xa6fu\xe5F\xfb\xb8F\xf3Ul\xf1\xbeb\xf3\x03\xbe\xcf-6\xc3\xa5d_tr\x18\x1b#\xdd0\x9a\x9177k\x06S\xab\xc0tQx&U\xeba)\xca\xb1\x9e\xb4T\x8f\xc6\xb5\x80\xd2\x10vs\xb8\x98\xe0\x11\xaf\x1a-O>I4~\xba^\x1da\x14\x9f\xfa\xc4\xd3W\xb6+\\Q\x95\xfe\xb1\x98S\\\x8b\xb3\xfbG}'?Zn\xce\x15\xfa\x86\x03Z\x7f\xa3\x03\xdav\xb2eu\xe9P\xf7\x14\xcb \xe3U\x7fx\xa1=\x1eO\x0d\"YHE\xb2\"\x85\xbct\xc8\nq\xff\x97U1-\x9eF\x8e\xb9:\x98\xa4\x8fm\xeeU]\x19\xd2tm;\x19b\xa0<\xe5\xbfQ\xfd$\x99\xbbF\xa0W(\x11>\xc2\xdc\x92{{\xdb\x9cv\xa9\x06E\x8eD\x8e~\x0c0\xe0\xf2\xa1nu\xed\xa6\x99\xba\x9a=!\xf22uW\x1bR\x9b\xca\x92\xf7\xa2\xb1\xd2\x90\x07\x86\x84\xd0\x067\xd9\xbdA\xd5W\x92\xfbP\x0e\xaa'4\xeeC9\xa8\n]\x89^F\xe3N\x94\x8as\x06=t\xf9v\\\x81b0\x0e\xbb\x1axg\x8d\xd0\xa8\x02] 4\xab@g\x08\xad\xe6\xdf\xa3\x07#\x89 \xb2L'\x1a\xb1\x84\xee\xae+4[\xc7\xf8\xbf$\xe4\xd8}\x87\x1dJ\x82\xd2\xbb\xc8\xed\x8b\xd7\x02,\x12\x95\x8a|?\x8eVABD1J\xae\x93hyElV_V*\x8c\xc2FQ_\xc6\xceD\xa5\"\xb9\x90Q\x14\xf3\x9cB\x87\xda\xbcA\xf5\x87\xd2P\xe7c*.;\x96\xb6sM\xc69\xc4>8\x05\x9f\xa2\xba\x9a*\x93\xc7?\x10^\x12Z\xfb\x1e\xdaT\xe7\xb5\x96r\xcd\xca\xa9\xdc\xce\xe4V\xa0\xab\x07\xa7\xd3P\x85\xc6\x03AWE\xbe\xca\x86j\xea]\x0e\xca\xebo\xa8\xc2`\xfe\xafV\x91\xe3\x87\x81\x94\x80\x96MT\x92U_mGovw\x1d;\xb4\x0f\x1d\x17,\xb1&\xa6(5[\xdej\x94j\xe6S\xfc\xf0\x15\x9f\x91\xf4\xe1+\xe5\xcb\xf0@\x15\xf7\x8f\x0c\xa1\xd4\xb6\xb7D\xe4\x82\x87\xb8\xbf\xe7\xf2\xdb)B\xb5\x1e\xd6\x18E#\xaeeW\xb7>p\xa6\x91\x8e#\x9d\xba\x94\xa9Kx~\xb4\xd8\xce\x1cSX[\xd8\\\x8a\xa9\xb9B`\xba\x01\xa9\x0f_\xb57\xd0)\x0b(\xbb\xd4\xc5\xaf\xd2\xad\x86PhV\xcb3\xfewXe\x8bs\xd5\x04\xbf\xdc\xf0\n\xa1A\xc6\xc8\xf8\xe1\xd1c\x99A\x13\xdb\xc7\x95%\xcdW+\x85\x9e;\xd0\x05%\x90Z\x90L\xac\xec\xd4\x90\x07\x17\x89\xd8\x9bh \"\xb8\xc0s\xb8\x85\xe5\x03\xc92\xfd\xa3\x8dn\x83\x1bL[\xb8\xf0\xba@I,\x9d\xa7^|\x96\x86\x1a\xc0)\xa6\xc1mJ|k\xe8\xfe\xce\xf8\xf3\xeex2\x9d\xb6o'c\xfbthwN'\xb3\xb6}:\x9ct'\xb3\xb6s\xea\xdc\xdac\xeb\xf1\xd4\xb1\xe9\xb3\xd3\xd6d\xe0\x8c?\x9fL\xa6\xb7\x93I\xd7\xf9\xf0\xd4\x99\x0c\x9c\xc9\xf4\xd6>\x1d\xe1\x1b\xb7\x93\xf1d\xea\x14_o?p\x9cj^3:\xdc\x9d\xc9\xc4\x9eL\x9c\xd3\xea3\x81\xebGN\x83\x1b\x8a\xe9\xc8\x02\xc5\x0c\xed\x1d\xb0\x9b\xb8\x98N\xf6y4#\x98RV:\x98X\x16r\x14\x11\xfa,.O\x17s\xa2\x8cLGa^GLq\xab\x94C\xff\x83>f\xa2E\xe5y\xaa3A\xc9!%\x18D\x8f:\xd16\x8bH \x8a\xce\x89f\xbf\xf9\x1a\x99I\x06C\xec\xab_\x05\x90,y\"\xf8\x00W5\x84\"\xb4\xa2[\xf1\x14\x026 \n\x8c\x11x\xdf\xf3\x17\xfa\xb8\x07w\xa6\xb4{\xbb\xfa\x83\xc6\xdench\xc3\x1ab\x86\x1b\xb6\xc5\x8f\x92\xe2\x8eK\xdct\x00\xbc\xcf\x11\xad\xd4\")\x9d\xc8\xef:5}\xc35\xfc-mj\x8a\xedL\xd8\xd4\xf4,\xe8\xf0\xae~\x00\xb9X\xe0s\xcb\x07\xe5Q6)\x82\x009\xb9\x15j\xc9\xbcd\xa0\xdd\xf6\xe1 \xcck\xafg'6\x19\xfbS\xa3\xdf\xceR\x90g1\xf7\xd8\xbf5=k\xa1\xbf\x8d\xfa^\xca/s\x97\x1eh\xc5\x074\xac\xd1>\xb6F0\x87SX\xc2\x10Z-{\x0ef\x031g\xa1s\xfc\x9b\xd9k\x17\xe6\xdc\xbekKq\x13\xef\x8d\x87\x06$\xbc\xbb\x97\xc2\xae\xde'doW\xef\xbf\xa2\xca5\xd9\xa6\xc8c\xe8z\xc4\x9cD\x98G\x01\x06\xbcj\xde9w\x9e\xa7\xbc@\x9d\xc2Z,1)\x87\xa8\xaaz\x8c\xdeu\xca7\x91J\xee\xd3\xfd\xb8\x12\xb9\x0e\xee\xd3\xd9\xbd\xdd\xaa2T\xa8\x83\xf4\xa9\xb2\xf7vu\xc4\xe8S/]tW\xdeu\xd3\xb0\xcd\xc2\x98W\xb3\xf5TMA\xcb\xcb\xd5\xaa\x9d\x8aO\xde\x95\x88\x98\xc1+\x13I\xcb#\x93B4\xc9\x13\x9e'\xe8\x0d\xeeA\x1b\x12\x0c\xbc\xe62^\x1c\xd0\xf9\xdeu\\H\xee\x8f\xb6\xc2\x15V\xd1o\xe44V\xf6eb\xde(!\xb4\x01\x05\x9e>\x0c\xa1\xd3wN\xf06K\xd4\xe9\xc0\x10\xda\xed\x88%TW\x90\x85N\x13\xb1\xe9\x91\x0b\xbd\xca$Et\xa4\x9d\x86\xbb\xc7D\xdb\xdbm\xce\xc4_#\xec\x98d\x12\xf8 \xe8\xeb%\x12\xb1w\xe9\xd2\x12\xe8\xa0\x10N`\xd8\x18\xc2\xc1<\x82=\x9d\xa8\xd2\x87\x9d\xaa\"\x0b\xe3\xbbt\x0f\x8f\x0f\x0f\x8ew\xfb\xbb{G\x07\x83\xdd\xfe\xfe!\xd9\xed\x1dm;\x01\xb9\xaa\xfb\x94\xf9^1S\x01\x13\xe3\xa8\x04\x8b_;\x01{\xcc\xc2\xbeu\xe8\xfa\xf7\x1d\xf8\x10\x1d\xeeR\xb1SR:r\xfc7\x92!w\x9d\x0b%^3\xd7&\xe8\xb4\xc3\xaf\xbcW*-\xd8\xf9|\x92\xb4o'I\xfb\x83\xea)\x83Ex\x1ew\xda\xd3\xde\xf5\xb8\xd79\xf6:\xf3i\xfb\x83\x9d@\x15Vv>\xef]\x8c{}\xcdS\x9f=\x8d\xc6\xbd\xce\xa1\xe61\xe5\xe0k/N\xc8\xcb0\xddvI\xe8\x8e\x91\xa3\xbd #`\xbeqR\x95\x10\x05\xb6yc\xa1J\xd3p=\\\xe0\xbf\xd6\xc6\x91\xe6\xd7\xcfN\x8b\xef\xecJ\xb3^\xe8\x89\xd9\xc9\x9e\xdd\x10\xa2\x9b\xa1T\xea\xbd:J\x11\xe4\xae\xa5\x19e\x19\x8f\xda\x95&\xd9e\xb1r2j\x95\x00\x87,\xac6K\x14\xa3\xdd\xc4xN\xf3E\x118\x85\xb9\x9dv\x93e\xe0\x13{\x80j\xa7S\x18\xc0\x10\x8e\xe8\xa8=\xa9X\x84}\xba+r\xf7\x15uK\x03\xb7\xdb\xab\x8a\xd8\x99V \xe7\xa6\x8f\xbdf!\xc9\xcc\x01\x19\xf7a\xb2\x12\xe5W\x86iC)4\xaf\x86\xb2-\x8aGL\x8c\xa1VE\xf1\xfcc\xd3\x172.\xdaf\xf0\x04\"\xe6\xe8\xd4\xc7\xb8q\x81\xed\x8d\xb3)\xbbH\xe6\x9c\x98\xf5\xd1\xa6\xd8\xe7\xdb\xae\x84\x9eN\x18\x82\x0d\xa9\xea\x98L\x08T\x1b\xac\xa7\x86)\xe0\nd\xf2\nT\xef\x1f\x89\x83\x93\xf0\x8d\xd0\xd2\xdeV\xab$\xd5x\x18\x1b\x86\xb1\x8e\x08\xf7e\xae\xe0\x18\x96\xa2\xdfz\xb9\xbe+\xe4\xee\x9f\xe1\x98L\xb7\x8f\x99ne \xc1\xec8~*\x99/\xb9\xd3\x05\x0b\x97!\x9clx<\x18\x92|\x1a\xcd\xb2%\xb1\\\x85\xc1,32,E\x8es\\\xbcs\xbd\x8a\x82/\xc9\xec\xcc[\xad\x97\xe4\xe38Z\x9d\xf9\x0b\xb2\xf2`$=|\x1e\x13/%\x7f\xe3\xd3O^\\c1\x16J\x0d\xbf\xfe\x8d\xd5\xb2\xf2R\x10\xceI,\xfdN\xd4\x9a\xb9\xa1\x1bH\xd7Wk^\x9eh\xf0\xa9\xaf\xa4H \x90\xe7\x87\xf6\xde>=n*H\x85\x8f\x0ev\x9dM\xa3\xb1\xc8|\"\xed\x16\x13\xc9e9\x95\x1a\xcc\xc8\xdc\xcb\x96\xe9\xb0z\xab\xf4;\xea7\x81kj%\"\xf3Q\x8e\x04&\xaa\xcc\xbb'\x90L)\xf3^= \xb2\xa2\xe7d\xe5\x05\xcb-Z\xc8\x12\x12\x7f\x97\xb0\xd5\xe8\xfa\xd1j\xa3\xb6x\xbf\xceg^J:i\xb0\"\xd6\xe6-\xa2\xaf\xc5G^J\x9cn\x1a\xbd<{\xcd\xbc@m\x8d\x1dBs\xda\xc5\xcd\xb9y[\xbd\xcd+=\x9f/#/}\xe0\xaa\x830%\x97\x0f\xdea\x1eD{X#T\x88\x8fX\xe5<\xee\xb6t\x8c\xe9r\x94fQ1\xf8\x0f\xb5\xfd2\xba\xab\x07\xd0\xfaN\\\xe5\xfel#\xb0{.\xc4]\xe6`\x11\xcco\x1c\xadB\x03rC\x8b\x9a\x82H|\x02|>\x8f\xe2\x95g\x88\\EI\x827\xc6\xfc\x91\xe7\x16\xb4!\x98\xa2\x0b\x90\xf6\x12\x92\xc0K\xec]\x90|\x9c\x85\xbecGx\x82\xb2\xd1\x1ek\xfd |\x1bF\xefBxs\xb3&C\xa0\xf5\xa5\xd8\xbb\xba\xa9\xf1M\xc40\xa7J\xa9^u)\x0e\x85\x9e\xf0%\x17\x97\xb2\x9fB\x1f\x8a\x9c\x14\x94\xc9\xe7E\xc6\xfd)\x15\xde\xe4\x9f\x98\xc7\xca8{\xcaR\xe8\xe2\xc5\x81\xf0\xf9\xadY\n\xb4yw9\xfd\xd0\x17\xf1\xb0\x08\xbf\xc4\x17\x10\x8dg/\xf0\xf9\n\xba\xdel\x16\xd0\xc9\xf1\x96\xdfo(?\xc7\xf2AJV\x86\x02h\x14\xe9\x06\xa1\xbf\xccf\xe43\xe2\xcd^\x87\xcb\x1b}\xd1\xb5\\\xf4\x87q\x90\x12ZV/\xe8I\xd3\x9f9e\xdc\x99\x11\xb2^\xdePz\xb6\xfe\xeb\xe4\xc6\xc1#\xff\x07\x1f\xc4dnma\xa5\x94\xe5\x8a\x92ou7\x08g\xe4\xfa\xf5\xdc\xb6\xfe\x8aU\xc9\xcc >\xefM\x16\xa2H\xef\x7f\x1c\xb0\xe0\xb7\x91\xe4\x1a\xae\x176kb\xec\x82hc.f\xc3 \xaf\x8a\xdb6^\x1c{7*\x97\x01\xedy\x01U0\x85\xb7\xf9\xc8l\xed\xbe\xe2\xc1\x06\x14\xcc\xae\xba1\xca\x9fY\xe56\x8b\xfc\xc9E\xf5+*\xd8-\x1cX\x8c\xaf\xa6t%\xe8\xdf\xee\x8c\xacc\xe2{)\x99\xe1\x8d/\xf9Q\xccq\x0d\xd8\x05\xb6\xea\xe3w\x02\xbf\xf0\xf9\x1a\xef\xb9\xcfh\x81\x11\xa46-A\x85B\x83\xd0\x8f\x13\xcd\xb4N\xbe\x03\xb3\xcav\xe9\xd7\x8c\x06W\x90\xbe\xee\xebQ\x01\xaa\x11\x0c\x94y\xf4\x1d\x97\xc5,\xb0o\\\x8c\xb2\xb6\x82\x11\xf4O`\x05O`\xef\x04V\xed\xb6\x03\xb3\xb1U\xee\x12\xa5\x95+:\xb4K}\xb78\xd2\xcfTT6\x91i\x8e?\x0c\x19\xe0\x94\xa7\xb2 \x12v\xbdl\xde\xf5\xc2\x9b\xd7s\xd4\x92\xb1\xaf\xdd\x95\xb7.<5\x9a\xee\xe6\xb2\xf8\xf3:\x9f\x08\x18*ME!\x11M\xe1\xd7\x07lj\x9c\xdas\xfa\x94\xd2q\xd2%a\xb6\xc2\x10\x8c\x82c\xcb\xdf\x87|\xa9B\xca\x0e\x97\xc1\x97\x04\xbb\xe7\xd8\xec5g\xdc\xa3uX\xf3`IX\x8a\x8d\x08\x1d\x9b\xd0\xa5I\x17/_U\x12\xdbU\x19\xbf\x9e\x96\x89\xe1u\x13V\xfe\xd1#\xa6\xb6\x17\x00\xf4h)\xb8\x01{\x8e\x1cF\"C\x8aO\xc6{\xd7x\x04\xd9\x88\xa1\xb2K\xcb\xdf\x1aO\x8d\xb6\xe1\xa9x\xff\xa5\x86\xa7z\xf8|\x13\x86\x19m\xc90\xa3&\x86\x19\xd5\xb3\xf25c\xba\x9b\xf0\xd4\x85\\4\xe7\xa9\xfa\xb23l\x99#\xb4\xbe\xc8\x15\xd26\xfd\xb3\x9b\x9ag\x97(\x86]\xaf\x96\xfa\xc7\x94\x86]b|2\xfd\xf3s|\xbe\x8e\xc9<\xb8\xd6\x97\xb8\xc8kH\xd6\x9eo\xa8\xe6\x1d\x9b\xda0[\xe9\x9f_\xe7\x87d\x03\x03\xcfj\x188\x9a\x07\x1c\x96\xda\xfc\xc7\xc1\xc5\xb3&.\x8e\xd1Y1l\x8c\x15F\xa9wI'\xc7b\xfe\xb1\xf69\x9c\xc29\x15\xcb\x87\x16\xba\xb6;\x94A\xb8p\xc1\xf4\xf37c\xfa\xdc\xba^-\xc3\x043e\x9f\xd3B\xf8\x13o\x03^\x18\x04\x1c\x99)\xa0[\xe5\xdcD|i\xe99\xc5\x07J8\xf0\xef\xed-\\\xd2\xff\xbez\xef2\x08\x0f\\'\xff\xa0e\x18\x96\xc0e\x97\xc7\xe0\xcd\x85\xbf+\xee\x95;u+\x1cbIy\xc3R\x8dZe\xe4\x0c\xf43\x17;\x90\xe5\xa4\xa2\x953?>\xe4\x08U\xfd\xbe\xf8h\xf8\xd3\x8c\xb6>\xdb\xbau\xc1V\xb6n]L\x03/9u\x01%\x9c\xa2\ns\xab\xe7^\x9a\xc6C\xb81T\xee\xc2\x95\x1e\x1b)e?3\xb8XB\xc1\x8a4\xabb\xdfsY\xce6\x9a\x15\x17\xce\x0c\xebb\xdfsa\xb6j\x9f\x97R\nm nk\xd3\x12\x01\x9f\xfa\x17zq\xbbA\x9c~F\xc5ii\xcf\xd0\x9d\xb8\x14\x1b\xf0\x85Y:\xa5}{Q\xb9jh?ct\xa3\xf5b\xfcL\x12\xbcooa-?(Dn*\x8c\x1b\xa6\xab\xd4\x0e}\x8b\x11\x89\xfc\xab\xe8!\xff\xdd\xa58\x1b\\di\xed\xb2\x89\xcf\x15\x8f.YF\x05\xac\x0b\xa54\xda\xd9\xfc\x971\x05K\xf5\xf3\x85\xe8_-\xd3\xae~\xde\x8a\xb78F\x99)\xbd\xf8\xdc\x8c\xf3Q\x0br\xf8l\x9a\xb3,\x14\x9b\xbe\xa0#\xf8\x82>\x91\x80\xcb\xf13<\xf7\xe0\xdf\xf2\xa3\xb7\x14\xfe\x96\x0214f\x82sQ\xbf0\xb5\xa9^\xe4O\xb9\xb3#P;\xef\xca\xce\xe9\xf2\x0cV\x84A1\x00\xbbT\x86\xc1Mv\x19\xe9s\xc5\xe3f\xa6lt\xcd/\x94\xd1\xe3%\xa5\x14|\xa7 \x19\xf5\xa3\xd0\xf7R\n\x1fJt\xf5e\xc3\xb4\xd5\x91Fq\x98\xe4\x0d5\x11\xea\xb2\xb49\x04\xebYx\x93.\x82\xf0\x12|/\x84\x0b\x02\x0b\x12\x13\x83T@;\xedo\xca\x11\xaa\x0d%\xa6s+%r\x0f\xc8g6\xa0\x91|\xe6\xae\xcb\xf8\xbf\xe4\xae\xb1\x12h\xc63&\x94\x17\xf5\x1d]\xd4w\xecT\x96\xb0\x80kl\x85o\xe0\x14\xc6\xfa\xbe\x1b\xfb\xfd\xde\x85kZ\xd1u\xb5\xeb\xef\xb5v\x90\xa5\xd9\x17\x81\xca;\xeci\x19K\xd1\x08Z\xd2s\x05\x82n8vX\xb5:\x01\x1aJ\xfc\xa5\x17{\xb4\xc1!\xb44\xd7\x1b\x83pF\xc2t\x08\xd6$\xad\xdc\xae\xab\x9a\xcb\x00o1\xd4X\xa5h\x7f\xa2\xa2?\xcb&\x13W\xa5<\xc7\xa9\x06\xab\\\x0d\x87\x96<\x05\xf6\xabn1PxK\xec\x0f\x9c\xeeY\x1a\x13O#\xfe\xa3N\x8c~\xb1\xa4\x15\x83\x8a\xf5Jo\xf5\x04\x919\x80\xd24\xcd\xc9\x01=\x05\xd0\xa5\x11\xc7\x1e0\xd1!\xbf\x92k\xb3\xf7\x9c\xee\x17Q\x10\xda\xe8KgYU\xdb\x9a\xf8$\x94\x8c\x19\x84oC4\x08\x1b\xbdD\xd3\xb1\x142\xe0-\xb9I\xec\xd4\x19\xf7\xa6SdyI\xf7\x9c,\xc9\xaa0\xdbr\x80\xa0\xdc\x91\x9bC\x02?\xcaB*\xfd\x84\x12\x0c1\x89\x0d\xab\x0c\xa3-{20%q\x9c\xadS\xcc\x00'\xc0\xfa\x19\xf3\x99\xd3\xbe.4\x14\xf0S2\x957\x95\x87\xf9z\xad\xcd:\xde\xf24l-\x02\"y\xab\xf5m\xa8~r3g\x1b\x1e\x8f\xac\xc7\xd0f\x0epmxl=6\xbe\xf8\x1e\xbd\xa6\xc7dj\x14,7 \x93\xe2z2\xc7\x08%\x94\xad\xf8\xe0\xa5\\\x81B\xfa\xbb\xb9Pv\xc6\x18\xd1\xca\x0c\xf7\x1a\xc4'\xe9\"\xcd\xa48\xb6\xb6\xf9\x0f\x0cty\xee\xcf\xbc\x14\x95RK6\x9d\xb6\xf5\xa45~\xfe\xd1\xb37\xcf\xc6\xf4\xc0)J8\xb9\xe3\xde\xced:\x99>\xdd\xb9t\xc1\x9aN\xa7\xd3\xa7y\xf1\xa7xx\xb5\xa6\xd3\xa7\x16V\xcdW\x13Q\xdf\xe7\xa1k\x96\xd2=\xaed\xc3\xf8\xc5\xf2G\xbb\xb7N\xc1\xc2\x01!T\xd9YpJ1\x90\x0f\x19\x86\xa2\x0b9\x15\x816\xf4\xf1r\x81\xbdd\x89\xb5]T%\xb5zyo\xd1\x13\xd3,T\xbc\xc77no\xa5\xc1\xd5\x8865\x0b%L\xea\xc6w\xf3\xfe$\x9a\xee\x189\xb3~F)E\x19B\xa4\xdf\xd49}\x18\xd2U\xd3\x16\xc9\xc5\xfdd\x08s\x83F.\nS\xe4l\x06e\x13#aC\x08M\x9d@\xca5\x04\xaf\xeey\xd5e\x15\x94\xa9xo\xe0#^\x1d\x1f)\x11\xf2\xc2HL$\x97&\x8a\xcf\xba\x08\xf1\x82 \x12\x89\xcc2\x0f|\x0c\x9fK\xa7$\xbf\x9d`\xa6\x9a\x81\xd14\xce\xd3X*\x95\xd5\xed\x1d\xe1$W\xbc\x94,\x82yZ\x0d\xa8#\x7f*\xc6=\xadKX\xb5|d\x07N\xb3\xc2\x8c~p\xf25gp\xf1\xd1K\xe9z([\n;F\xed\xf5)\xce;\xe3yB\xa1f\xf3\x94\x0b\xa7`=\xd9\xa1T\x8d\xffn\x83\xf5\xd4\x92Kq\x06\xfa\xe8\x11\xb4BZz\x12\xf2\xc7\xe8W\x8c\x17\xc9t\x1b\xcf\xbc\x8aQ\xa3\xd9\xa3\xd5\x92\xf1\x04\x9dr\x8b\xdf]o\xbd&\xe1\x8c\x8a\x0d\xae\x8cO]\x06\x0cJ@\x11\x1d\xccn\xf5\x1c\x17Z\xbdMH\x04]4\x8e\xc9\xf9\xac\x95\xe7K\x9a.i\xa2\x8a\xdd/,\x07\xa7`\x01++=CI\xca\x02\xcb)\xde\x8dq\x85D\xf5|\xfaqo\x08\xd8\x8eiM\xc4\x02\x97\x96\xa5\x15W\xb7\xa4xC.\xa8\"#\xae\x0c\xde\xbd3]\x87\x82\x1a\xa7;-\xcd\xd0\xd0\x0bD\x1a\xf4H6\xa8_9\x0d\x0b\xd5\xb52Q\x16\xf41\xc5\x08\x00\xdd\x04eh8e\x99Px\xaax\xb3\xb5\xc3\xb2\xcc\"\x9c\x89\xcc\x0bW\x00>\xa3\xfc|,A\"\xda\xac\xf894\xb6\xb1\xe0q\xe4\xcd[ef\xe6\xfe\x0b\x863\xe4:}\x13\xf8o\x99\x13J\xba\xe5N\xbc\xaa\x95\x0f+\xc4\x0e\xf5\x1e\xf6\x1c\xda#\x96\x8c\x12\xf2\xd8\xab(\xc9 \xb7\xc79\xe7\xd7V{\xa2\xd0\xb2\x89\x08\xe3\xc1\xd2L\x1agv\xa3g\x94\xf8\xf8]\xb2\nR\xdb\xa2\xd2\x99\xa5\xb5\x9c\x8a\x0f\x15P\xd8\xfaoHT\xeb\xe6\xf1\xa6v\x1e=\xfb\x8a'\xa0[\xbb\x98\"\x91\xb2\xbd\x9e\xa3\x0f\xed\\\xd3\xca\xa5q\xf8\xccf\xdf0\xcb\xe9\xb75\xcb)\x95\xf58\x88\x843\x0b\x7f\xc6\xc4\x9by\x17x\x00\xa7\x04H<\xf7\x97QB\x0c\x91\xee@\x7fl\x00\xc3rT!\xc2M\xa0y\x1c\x0b5=$p\x94\x08\xbb\x92j\x02q\x1b\x8f\xee2\xd4\xc5s\xae\xbe\xe6+\x12'\xa8\xd3\xb0\xfa\xdd\x9ea\xd7\x93\xd0\x8ff\xe8\xe1\x19w\xc5wFr)\xbd\xfa^\x8a\xd9\xd4%K\xb2b*\x85\x02\xf6\"\x87\xd5b\x9f\xd8\x87\xfa\xe1\xa2\xc2a\x08\x99\xcd\xb4\x81E\xecD\xbc\xc8\xc5\x82\x15\xe6\xbe\x06&%\x0c=\x0dm\xe2\xf5 \xc2\x9a\xcb\xf2@\xa2L\xe5@\xba\x88\xa3wH\xc61(\xacm\x85Q\n^\x92\x04\x97!\x99A\x1a\x81\x07,\x14uK'?\x88\xcf\x95\x94\xaa\xbb\xde\xdePdG\x96\x143\xe6\x8a=[\xea-'\xaa\xa1[\xaa\x81\xa9\x80\xdaT\xc0\x10\x94V\x0e\xbc\xdfD\xdb\x08\xaf\xdc\xd6\xc9\x8a\xe2c\xa2R\x86#\x1f\xa5y\x9b.\x89\xc4p\xd9\xee\xa1Ccv<\x91\x01\x9a\xca\xb9\xe2 \xed\xe9\xc6$S\x9dW!$\x96\x91=\xffU\x8a\x1a\xba\xbbg\x88\x18*\x0fG\xb0\xf3\xf2\x00\xadG\xd6\x10\xacG\xdej}R!\x8a\x8f\xad\xc7\xf4\xc9\xcffQZ}d=f/\xad\xa3Dy\xf4\x04\x1f-\xd5w\x9e\xe2\x83\xcb\xf4\xa4\xa0\xa3\xd2\xb0\xb7\xbal\xc5\x89\x17\xa7lH\xbcru\x8f=~d=y\xfax\xea\xec\\\xd6LF\xa5\xc2pL\xaaI\xb4`\xb8m(\x8a\xd2%\xba\x93\xd2\xbc\xf3[\x11\xfd}\xa7\xfb\xe2\x8a\x84\xe9\x8bU\x90\xa6$\xd6)\xf9\xd5\x83t\xccc\xa1.\x02\xe5Z>\xfd\x84\xf6\xee\xbec\x07.&\xd3\x0d\xba\x9f\x15\x14\x93\xb6x\x80\xc0\x1f\xc6A\x9a\x03\xf7\xf6\x8f\x11\xf8Q\xb6^\x92k\x06:\xe8!\xe8M\xec\x85\xc9<\x8aW\x1c\xdaG\xe8\xf7\xbd$y\xb3\x88\xa3\xecr\xc1\xe1\x03\x843\x9d8;\xd8\x05r\xc2\x8f\x00\x9d\xc1j'\xffJ\xca#o\xd2\x9c\x07\xfa\xd3h\x8a\x06a\x1c\x0e\xbb0\xc5X\x0dZ\x89\xe9\x1b\x18\x1bh\xede \x91\xbe*\xc7&}\x93\x91\x96\n\x85\x05\x1f\xc2\x1ac\x92d\xab\xd2\xf7\xdaSY\xd8\x8d\xc2\\$\x0b\xd0\x81\x0e\x01\xb1\x17\x84\x96\x0b\x11B\xce\x83\xe4,\x9d\x05\x11\x957\xe4\x81\x11$*\xb7\xb7`\xb3j\xa8\x18\xe7\x82\x87\x02\x11\xfd\xcd\xc46\x17\x92\xaa\x16\xef\x8a\x874k\xf5M\xf3\xebi\x07\x9bac\x19\xe7\xb8)\xa3c\x9b\xcd^\xb2A\x85\x86{\xe03\x92\xa4qt\xc366\xff\xb1i\xb3\xbe\x9en\xa3\xaf\x90\xed\xb8\xdcN\x1cw\x97A\x92\x92\x90\xc4\xcf)\x1f\xc2\xfd\xe4\x82E(3\xb5\x1c\xc1_\xab\xf4V\xdf\xe2\xdc\x88&\xab\xe8\x8a|\xc2\xdb\xa9\xac\xb9\xf2PZ\x7f\xf5Uy\x9d\xab\xcf\x8a5\xd7\xbe\x89#\xa2\xc2\x92\xaeU\xf9\xa9\xa9\xd5ym\xabsm\xbd\xc5\xd3\x9a\x9d \xc8-\xc3\xe4R?\xab\x10\x19\xdb\xe7\n\xb6\xcf\xf3w\xca\x10v\x94\xa1\x04\xc8b^\xceM4\xdca\x8ec5d]\x7f\xab\xaf\xa0\xeaG=\xa7\xcb\xc2\xe3\x96\x19\x9e0\x1e6\x86\xc8\xa9\xa2R\x8ee\xa9\x16\xcbZ\xcd\\\x0d\x84\x00i\xa7 %\x19#\x8e,E\xbe\xb9Y\x13.I>\xf7B*LR6\x03\x1e\xf8K/I\xc0K\xc0\xcb[\xd2\x1c\x0b\xdf\xf3\x0d\x94\xcb>\x0b\xe2\xcd\x80E\xa3\xe1\x90\xd4\x0b\x96e\x08?\x0e\x8c\xaa^\xcb:$I\xd5\x8c\xe6\xf5r\x9a\x10m\xf5\xf3A\xb7\xa21S~H\xaeS\xa6\x8eR\xc7\xa9\x8af\xf2P\x9eb\xc0\x92|\xb8\xa8\xf5\xc1\xdb\xc0\xc3\xd2\xac\x90\xf2\x94\x10\x17\xdam\xa9\x9a\xf2l\xb8\xa5\xb1g!\xea\xbe\xbf\xfd\xe1\xe7\xfd\xddd\x0ex\xec\x0ci&\xd0\x11\\\x1ec\x051\xb6\x19\xb32b\x13}\xe7\xe2xQk\xddy5\x15'\x1a\xda\xa3.\x9d\x91Z\xbf\xc3\xbe2\xc4\xd3\xd2\x80\xaa8^Y\xf2\xa2%:\xbd.t:RU\xda\x98\x85u3\x82\xb1\x0e\x9bf\xa4\xaew\x0d;\xb0\xdc\xda\x17Q\x106\"\x1c\x9b\xffQu\xfe\xc5E\x0f\x8d\x17s)\xean\xdeY\xe6Zl1m<\xae\nO\xcdM\xe7\xed\xc4\x81\x10\xda#4\x81\x13\xc3\x9a \xaeR;\x7f\xe8{u\xcf1\xc5]o\xb9\x8c|\xbbg\xf0cV0\xa6\xd0\xf57\xa0]13xj\x0eXl\x08\xde\xde\x0f\xc2\xc4\x9b\x13;\x85\xa7O\x9f\xa2v2+O\x9fG\x97\xf3\x04\xb2\x13\x07'.\xc36\xd8\xacF\xfc\xe2\x04^\xde\x8e\xd67,\xb0\x01}\xa5-\n\x96\xa2\x18dl\xd2MS\x1c)S\x9c\x03\xdeSI\x0b\x03s\x06\xdd L\xd6\xc4OK?\xba~\x96\xa4\xd1\x8a\x91\x89\\9\x93/\xd0\xb8ZpZ\x87\xecb7\xe7/i\xd4jlXC0\x92\x1c}\xb8\x1e,.\x05z\xcfMo\xec\xe2h1^\xe3\x89{c\x7f$\x1d\xfb.sw\xbd\xddF+\x90\x88\x0fS\x1cu\x13\x92\xbe\\\xad\xc8,\xf0\xcc\x1e\xae\xdc>\xc3|\x8cx\xcab5&\xb3\xfc\xf1k\xaej\x007\xdb\x98L3\xc0M7iw\x16\xf9\xa8(3\x97[\x97\x12B~_ \xc9k\xcc*\xa7}`\xcc\xa7N\xab\xc2\x8clk:'o\x82\x15\x89\xb2\x14NaM\xc9\xb5[D\x8c\xe7yk\xa6\xccq\xfa\xab\xf7\xdd4bW\xdb\xf9\xe9[$\xb6aQ\x8b\x9a\xe8\x88\xf8Hf\xa0Z\xca-\x7ff\xb6&\xaa\xaf\xf8\x98\xf4[0\x94Q\xa7\xae \xb4\xa1v\xd7Q\x92~\xca\xb3\xf9\xb3\xac?\xc1\x8an\xc93?\x0e\xd6\xa9\xd1\xddG|\x04\x11\xd79\x08V?x\xcc\xefF\xe1\x8a5Woh\xcf\x85\xbf\xbc|\x13\xd3\xab~\x88\xde\x84 \x7f\x18o(f\xc0\xb6,\x17\xac\x0f-~\xa8(\x1a\x0e\xab\xa1\x94K\xb5\xe8W\xc2vP!\xc5\xab~\xbe\xf0\xc2\x90,\xe1\x14l\x1b\xa3\xa7\x90wP~\xe4t\xe9\xbc\xf7\xf5\x03\xaeE\xae\x99\x9d\"\x057\xa9<\xb7\xc0\xd3\x08;1(M\x8a\x01\x0bQ5\x86\xc6E+\nc\xe2\xcdn\x92\xd4K\x89\xbf\xf0\xc2K\x82i\x92\x97\xa3\xddvD\xbe\x8b\xe2\x0e.Z\x06\x0d\x97\xbd@r\xfb\xaa\xdf\x85\x94\x1f_x\xfe[\xe3qV|\xbc\xf82\xd1\xf9\xdb\x89\x8f\xe1\xae=\x14l\xc8\x1f'S\xa6\xdf\x8e\xed\xc4q!i\xb7M\x08\xb7fG4y\xed\x16J\xd9:\x1f\x82\x85y\x89Yzw\xf0\xab\x81\x9b\xa1\xa1\xca\x1a\x1f\x15T\x8e::\"\xa1\x9f\x94\x86\xbb;\x02[h\x17\xeb}\xf4\x1a}\x9e\xe7\xdc\xf5\xa6\xaeL}\x9a@\xf1im\xb8{\xe4O~:\xed\n4k\x16p\xc4'\xc6\xf7(\xd6\xd5\xf7^|\xf2\x14P\x0d\xba\x0b\xdd\x07\xfd\xae{f\xdf[\xdd\x87\xd4\xf9O\xea>\x0d^\xda\xd5\x0f\xf6\xa9\xbfm\x9f\xe2qo\x93\xbbU\xf2\xe7.\xfd\x1a\xdc\xa5_.\xc4\xe3\xfe\x8f\xa3w\xbbw\xef\x1d\xfd\x7f\xf0-\xf7\xb1\xd1\xd5[\xf7A{\xfd\x12U\x0e\x1aw\x0f\xddG/Q\x97J\x98\x84\xa3\xbc\x00\xcc\x83\xd0[.7\xa1\x0f\xccp?\xdf\xe0\xbc`|\xba\xa9\xdfoE\xb7g[Y\xc8\x02\x02\xcedY(!\xcby\x11\xa9?\x0fN\xbc\x08\x12\x0c\x83=\xc4\x02\x92\x0d\xb8\x949\x14y\xb1\xd9\x15`\xf3[Q9\xfb0\x90M3\xf1E\xdd\x03\xe9.#\xdf[\x9e\xa5Q\xec]\x12)\xa2\xa3:)r\xfeTm\x855\xef*\x10aQ.\xb7\xaf\xe5GBa\xc8sn\xa07\x99\x95\xc6\x19a\x87\x7f\x1e\xd2.t\xbai\xf4I\xf4\x8e\xc4\xcf=\x8d\x01Y\xfe\xb5q\xf0R\x10wal+\x8c>\xe2A\x88\xd0\xc0b\x8a\xbd\x0d\x92\xb1\xa9\x1a\x15\x13\x8a\xb14\x9eapm\xb4ai\xe5\x12\xa1m\xa1\x85\xa8\xd2\xb5\xaa\xef\x91\xee\x1e\x81\xf8\xd0*b\xcf'\xa5*\xe0\x14\xfc(L\xa2%\xe9\xe2C\x16\xc0F\x80\xdeyq\x88g%\x1c\xa4\x1aD\x0f\x8c;-W\x170R\x93\xa2I\xaap\xc4j\xda\x87\xc6\xad\xb4\xd1\x1e\xd2+\xe2J\x19\x96\n\xb0\xe4\x06r\xac\xcb\xa3\x14\xda\xfb}\xed\xad\xcfH\xdd\x1e\xdc\xb6G\xe9\x82d\xde\x8b\n\x1c\xa2+\x15\xa9\x01\xc9\x0bG\x12MpS\xac\xb8\x1b\x84\x0b\x12\x07\xd8yt,q%\x98\x1d1'\x93H\xd2\xab\x9f\xa7\x92\xcbH\xddd\x01\xa2\x06\xb7DT\xdb\xde\xc2\xb3\x86.\xcf\xe1F\xcbS~k\xd0\xbf\xc3K\xfd\xfe\x81S8\xc5\xdc\xf1}\xc9}f\x93\x1a\x9a\xec\xcd\xfdc}\x16\xc4\xfe\xb1>\xcf\xcd\xdeAs\xac\xf6\xeaBqK\x04\x0bH-\xc7P\xd2\xeb\xcc\xb3\"zU\x8c\x97R\xd1*g\x13)\x8a5\xe6\xd6\xcb\n\xebWau\xe8z\xc9M\xe8\xf3\xe4\xadYw\x1d\x07\xab \x0d\xae\x08\x9c\xe6.0pZn\x02\x87u\xbc\xef`6\x0c\x1e\x03\xca\xd6\x948pl\x82w\xe5*\xcf\xa4zi\xb1C\x07S\x0e\xc8\xc0\xfd^\x9f\x01\xe9\xd7\x01V\x93w\x15\xfd~\xec\xfd\xde.\x82\xd6,!\xa7\x00\xee!p\x16$\xeb(\x07\xf6\xd1f\xd3]y\xd7\xcf.sX_\xc0\x04\x80\xbd\x19\x939\xba\xa7\x90X\xc0\x0f\xe8\x8e\xa3\x88\x92m\xb9k\x9a\x10i\xef@\x17\xb9\x1du>\xdeE\xa2\xa2\x12>\x99/#9\x97\xf5f\xe8\xc4\xd1$H^y\xafl\x8c\xfb\xcf\xd2x \x96\xa40\x82W\x18\xc3\x153H\x0d\xd8\x9e\x92\x07\xc6\xcb\xc9l\xfd\xe4\xe8\x02\xd9]\xb1 v\x89\x0b~y\x81\x03L\x9dBe\x1f\xbb\xc8?_&\xb9\x8eDv\x04\xb9\xd1\xb8\x83\xbf^\xd3\xc6\x13x\x8c\xa5\x1f\x83\x17\xce\xe01/\xfe\x18|\xe6\xe2sA K\xd0]\xfc\x92\xa4\x0b\x12W\xb5\xe5|\x19\xcbazr\xd1\xc8:?\x17\xd1\x19\xce\xcf-\x16\xaf>\xec\xce\xa3\x18\x9dp \x0cYf)\xcf.B\xe3\x93\xfc[X\x0c#\xe24\x9f]\x0c\xcbh\xd5 s\xd7\n\xa8\x8c\xd1(A\x87c\x82q]R\x1e\xa8\xddW\xee\x13\xb1T\xce\xe7\xe7\xeb8\x9a\x07K\x12\x9f\x9f\x03\x8f\x14^@0$\xa6\xdf\xcd\xd63/%/\xc2+\xbcJ\x9d\x87\x9fx\x90\xbd\xd3\x88\x93\xbb\xba\\\xbcBU+\x89Y\x17A8S\xb1TS\x90.\x95\x8a\xb6r\xe2\xff\xd2\xc3\xa4x(y[\xf1u\x7f\x99\xbc\x08\xb3\x15\x89\xbd\x8b%i\xa2\x07\x9b%j\xd0\xde\x84\xa2\x934g7\xd3\n\xbc\x1f\x18\xe27\xacK\xa5vk\x0ew\xc5n\n\xec\x90\xa58\xf3\xf9q\xdf\xb3)\xae\xa1Ux\xdeM\xa28\xb5\xb5\x04v\x8d\xa9W\x11\xf9\xd7\xb8\xdc\xc3\"\xfbL\x83\xc6}>N\xa7\xc8\xcf\x99\xc4\xed\xd2\x01\xca\x93e<\x88\xf1\xde'\xecE\x96R\xf8T\xd4\xe3\xbb\xb0t!\x1c\xa7S\x17R\x91gD{\xa3\xdctX}\x10\\\xde;\xacRR!\x81\xea\xf3E\x1c\xe9\xd3E\xec\x1d\xf5\x9d\xee\x8a\xa4\x8bh\x96\xe8(\xed\x9e\xf2\x1eg\xd6\xc7\xba\x04\xd3\x9a\xbd\x80g\xc2r\xc9\xf9\xa6\xbbfYl\x0cff,?\x96\x1c\x14J\x89\x1d\x94\xf0\x9d\x0b\x94\x81\xa3J\xcc\x80\x19B\xc9*hL\xdd\xa5?H\xa1o\xb7\x0bW.\xdc\xb8p\xe9\xc2\xca\x85s\x17.\\x\xe7\xc2\xb5\x0bg.\xbcp\xe1\x99\x0b\xaf]\xf8\xc2\x85\xb7.\x86\xb1Z\xe2\xe9KO\xf0\xaf\x98T\xdc\xe2\x020%\xe5\x9cw\xe7\xbai\xc6\xabS\x89\x9eK25\xc5\xfb3\xcct*\x831\xb8\xd3\x08\xce\xba\x97$e\xd1\x87\xcf\xba \xfd\xba\xc2\xaf\xcc\xac\xe1b\x94\xce3f>q\xdcB+\xd3\x8dI\x12-\xafH\xcc\x82\xcc\xbe\xe5\x9c%\x87\xd2=\xfd\x05\x8f\xbc\x144\x04a\xe1\xfc\x97\xfbU\xe5\x04D\xa5\x1e\x94\x1fcp3\xb4\xd6\xbf\xb5#\xa7\xe8\xd2\x88\xf1\xe8\x1b\n\xa4Et\\\xf2%]\xad\xfc\x1c\xfe\x82\x16\xcb\xb8W\xf2%I-\xdc\xb4\x11\xf3\xc5s\\x\xa9\x8dhO\xfb\xc0\xd2\xf2a\x94\xe4\xc2\xfbp\x9e\x93\x13v\x86\x8f\xc6\xbd)\xeaQ\xaap\xd1\xe7\x11\xcb}c\xd6\x08iF&D\x8b\xd8\xb6\x9e\x07\xb1\x9f-\xbd\x18\x82\xf0*\xe2\xaa\x1c\x17\xac\xe7/?{\xfe\x83O\x9e}v\xfe\xf2\xd5O\xbd~\xfe\xec\xcd\xcb\xd7\xafLVwZ\xeb\xa5\xad\x89_\xfe\xbe\x08i]3\x8d\x0f\xd4\x13\xbe\x1a/\x99=2p\xe1\x99\xbc.\x89X\x17n\xc1\xa7bH\x99|\xbap\xe5\xe4y\x07\xe9\xfe\xa8\xd5\xb6\xe1\xe1Y\xbf\xaa\x86\xa1\xb2{\x02\xb5h#\xae\x12\xe4\xa8[\xe0\x90\xc1\xa5\x10\x8dm\xba\xa0\xc9\xa7\n\xbe\x14\n3\x18V\x90\xccqMh\x9ew\xfa\x81\x17\x89\xf9\x03\xa0\xbf\xb0f\x99\xf2\xfb\xe3\xb8VD\xcdu.\xa7\xfa\x7fXR \xdf\xefD\x8e\xc7\xf5\xc4\xb8\x0b\x8d\xd3\x14\xd4.kP\xa6\x06\xba\xcc]\xb8M\xefK\x0dj:\xf7\xc0\xcb7\x0e\xe8\x1e\x0b\xb5\x8b\x17\x88u\xa3\xe2\x97\xe2\xae\x9bi-\xffQ\x1c\\\x06\xa1\xb7\xd4Z\xfb\x85\xb0>\x84/\xd4\x87\\\xd2\x7f\x85\x91\x83\x90\xdb\x8b\x9fj\xd9K\x92nr\x0d\x94\x0f\xf2m.\xe7\xbd\xb5S\x07\xb9\xdc)\xdc\xb0@\x0f\x1c)R\xba\x18*\xd5S[^x\xc9\x16-\x1b\xd6Q\xe3\xda\xa3i\x8a\xf1\xdbMZ3\x900`\xfd\xd5\xf7\x00\xe7\x04\xfd{W\xccM\nF\xf0\x12EU\xee\xbe\xc0~\xbc\x96\xd1\x82=\xb1P\x9a%\xba Q\xea PL\xd8 #\x8fP\xac\xbc\xd4\x0f\x03\xcf\x83\xe7\xf4\xc8'\x89Fn\xde1l\xc5\xdatb\xa3R2\x9f\x9aK9B\x9dC7\x7f\xae\x0ey\x81F\x0f\xccI&\x83\x9f\xe5`>K\x85\x1b\x95\xfdZD\xf1X\x94T\xfa\xfa\xb8\x15j\x7f\xe9\x18\x870S\x1f\xe4g\xe1\x0d&8e\x92-\xdf\x9ej\xb3\xd5\xed}\xa1\x8aj\xe6{,n9\x87\x8e\xba\x86l\x0b\x86\xb8\x05\xc3\xb2\x8cFP\x92 \x99\x8c\x96q)\xb3j7\xde\x92\xa7\xe7\x8an^\x1bg~\xe5*\xa1iki\xc8G\xc1T\x18\x17\xc9[\xa8\xa6=w1\n}P\xefF\x8cH\xdf8w\xbc\x1b\xc5\xd09\xcf\x1d\n~'Mk\xcaW\x8dNhA\xddB\xd6Y\xba\xa3U\xbd\xcb\xf5\xb7\xd6\xcf\xac\xbb\xf0\x121\xf7\xda\xee\x16XP\xd3q\x8e\x18\xb4\xaeT\x93pum\x7f\xa1\x0b\x8c*\xeb\xbe\x86\x10a\xd8*#\x89\x8d\xec\x0b\xcdSN\xbb\";\x13\xa7\x1d\xb5\x15\xe4D\x91\xfdN\xf7\x0cyEd_\xab}\xcer\xc8\x83\x9c\xf0\xfb\xc7\xba\xfc}\xf4\xe4\xaf?\xe1\x0ft'|\xd4Kv}o\x9df19K=\xff\xed\x9b\xd8\xf3%\xb6B\xe48\x1d\x8d\xf6\xa8\x90;#2u\xa7.\xf7\x98\x07\xe5\xfc\x1fj\x89\xa4\xa2c\xd2\x9e\x85#;\xe1\xa1\xb6<\xc6\xd4x4R\x91\xb8\x1f\xed1\x89\xc8\x14\xc9n\xe1F\xa2l\xd8\xf5\xa3\x19\x8a\xddxO\x87\"\x1a-CJ\x02\xcf=\xd6hs\xa3\x02\xe3\xc0\\I\xc1\xe2\x84ln[`\xb1l\x88\xad\x8f\x882\x8f\xa2!X\xb1\xf7\xa5U\xa5Qj\xd9\x0b\x8a\xf1\xd6\xec\x9d\xb7A\xd94\xfe\xf2f\x08\x16\xfdS\x0d-\xecb\x80\x9a\x08s\xb7]x1\xcb\xe1\x16\x7fy\x83\xb4\x81ve\xf6\xce\xc3\xf7\x1eXo\xbbgH\x8d\xaaU\xdc\xa2\x11g\xe5]o\xa0\xd41\x18\x08\x8a[8\x91\xe2o\xeb\xc2\xa0\"w\xa3\xa3n*+:Q\x1a-yhk5\x8df\x17\x9et\x1cS\xf9\x9d\x8cc\x8d\xabi\xa3\xbfN\xc8\x02\x15\xd0}\xdd\xe8{\xc1\x04\xfe\xfe d\xf0\x04\x92\x13h\xb73v\x7f\xad\xd8\xa0\xd9\xd4\xc5\x80\xb7yh\xa2jv\x82J\x1c\xb407\x8bh1\xfd\xdb0\x1c\x1e\xee3\xc3\xa1\xa4ag\xa6\xc3\xc3\x83o\xdbt\xa8_D>V9\xae\xac\x95\xdb\xd4-\x8c\xb4X^\x87\xdaE\xd5;`=\xb0>Y\xe1\x1eA\xd9d\xd1\xb4\x9d\xaa\x1d\x17\xe6f\x8c\x84\x9b\xaf\x0d;\x9em\xebzr\xa7\xbek(&oB\x1fR\x9d]A\x1b*Ks\xc7\x81\xe3\xb0\x1f=\x82`,\xec\x12\x98\xbe\xa1\xf5 f\xd6*\xfe\x1f3\xfc\xe7w\xe5J\x17nS/\x08\xf9n8\xea\xddc7\x88\xd9\x96\xc9\xfc\x96{\xa5\x8e\xd7\xc5E_1\xe7\x88\x08\x17\"\xa06r/\x91\x9d\xbb\xfal\x1eE\xd6\xc3\x18\xda\xc50\x95\xa9\xe4wa\xee\x8a\x0d\x95#b\xc9\xb6\\NDy\xdf\xceW\xee\x92\xba\"\x18\xbb\xc6\x04\xb4\xd4[E\xd7\x1b[r\x16\x9bZrf\xf5\x96\x9c+\x83%\xa7\xd2\xdc\xcd\xa6\x06\x9fK\x9dE\xb5\xac4)\xbf\xb0\xd2\x12\x0c?\n\xe7\xc1e\x86\xb6W=\xd1 \xb9mV\x1f\xf5Z\x04I\xaa#+j\x9akJ\xa2\xe2&a\x05\x84\xc0b<\xb3-\xd1\xa5\xe1RF=\xeb\xfc\x9c\x10t\x1b8\x95b\xcb!\x8c\x1e\xe5(h\xd5\xc5\xbc\xe70\x82\x99P\xc8\\U\xdeva\xe5\xb8RA^,\x1c\xa7S8\xd5\xc5[\xe7O\xe8\x1f\x16\xac\x0d=O\x11:\x821\xb3\xa5\x92i\x01\xe2\x91:\xca3V\x11\xf5B\x9f\x0c\x91\xd0o6K\xae\x1c\x0eL|J\x13\x15\x88\x88|\xcan\x0d7\xb9\x9f\xc8\x8d\xd4\x01{\x03\xaf\x91 \x97\x8df\x8fX\x8c\xadCg\xf7u\xe8\xe7\xf1|\xce\xcf7\x9c\x8a\xf9|\x88\xa2\xef\xa63\xc1i\x84^\xcd\xcd&\xa3\xa5G\x9bR,\x05\xfd\xfb-\xbb\x82X\xce8\x9dn\xf0\x9e\x8a6,\xb6(}[\x9d1\x10\x92w\xc4n\xbe\xd1\xc5\x8b\xc7\xd1\x94\x8a\xb0\x91\x03A\x11\x927\xd0\xcd+{J\xe5\xe4\x81\x88K%4\xfa\x1c\x05\xe3q\xc4]\xe40ie\xdcM\xd6x\xeb1r\xa1\xaf\xbb\xb7\x87\x96\xb4\xb8h6\xaem\x96kc\xc3:\xcf\xf8\xa6eg\n\xc4\xac\xf1~\xe2U\x1e\xd1\xa2v\xdd\x0dt\x82r\xe3\xa0\xbc\xa0\xe6\x15\xd1\xafc}\x1cx\\\xc5Pc#c\xb6!9\xd5\n\xbb\xebH\xd8\x89\x85\xc0\x13\x08\xe9r\x13\x07\xa21\xa1\x0f\xcb\x17\x1dI\xcd%8l4\xc0\xe0\x15\xec2+\xaf\xb7w\x82\x847\xa0/\xb3\xaa\xf9.\x8e\x0bC\x8e\xb6RnJ\x15\xb7\xc9\xaac\xa9\x9b\x80Mnl-\n\xe2\xb2\x08\x92\x86{F\x0d\xf7\x8a6\xb9\x89Un\xaf\"\xaf\xdc\xbf\xf5\x86\x9bVu\xad\xbb%\xdd\xd1\xfd\xfa\xb2\xd1\x8d\xaa\xbf\x14\xfc\xa4\x9fue\x16L\x98\xf7\x1d\xfd\xaf\xf7\xba@\xcch$\xb1\xab:O\xc6K\xe7vP\x85S\xc62\xb7#GGx\xe6\xb6\xec\x0b\xcd\xbc\x08o\xec\xaf\xde3]\x9c,\x1d\xd7_\xa1\x16\xaeb\xccU\x02\xad.3\xdbgq\x88\xf3C#\xadTn\x8c\x08\x9f%:\xa3\xdf\x81\xfb\n\xcc\xdc\xd5\xa9\xea\xd3_\xa3W\xd5\x88\xcd^\x9e\x9b\xb0\x12\x99\xb8h\xaf>p\x80D\xf7+i\xb05\xdeG\xd2\x0b\xe8,d\xa7\xe3\x10-\xcf\xf4o\x19%\x1c\x91\xf4\xce+\x19\xa5\xd5\xeb\xfb\xef\xdd\xedN5\xa8\xf6B}\xd7\x86iy\"~(\xce\x14\xcb\x8aC\xa5\xae\x8b ,\xc5]\xb9\xefQ\x88\xadS\xffX\xa3\x1d(%\x94\xbb\xe3\xa1.`\x9a\x8d\x94\x8a\x07\x0f\xd4\xed\x8d\xce\xd1B\xb3\xcc\x04S6\x92y\x1cUrq\xd5\x9d\xb6Y\xe8v\x14\xddq\x0d\xc7\xa8Gv\x99\x8ax\xea\xb8\xf0\xbd(Z\x12/\xb4Q\x94!E\xb8e,\xc0LA\xe8\x15\xfd\x10c\x96\xf4\xbcG\x07N7HI\xec\xa5\x91>\x90\xe3\xb1\xde}|O\xb9\xcd\xc5\xf6\xe8\xa0\xba\xa3=\xfd\xd6M\xf4\xead_\xbf\xff\xe7\xbc\xcdj\xe5\xcb*^mt\xacV\x0f\xcb\x8b\x878\x8cj\x9e\xcb\x87Q\xf5)\x1e\xe64\xf1\x17\xdf\x1bO\xf2\xe5\xa3\xfa\xb6\x9b\xa8\x10K\x8d\x1e\x94\x8d\xa6\xa4\x17\xb5\xa6$\x0c\xb2T(\xe6\x13\xa6\x98\xf7\xed3\xa4A\x9e}\xc6\x83#\x02\x8f\x16\x8eh\x8e\x0bG!\x11\x0b\xf6\xec\xe4q\xf2\xca\x95\x1bb1\xe0 \xe8\xcc$\xee\xa1S!\xde\xa0\xe1\xbb\x93y{\xda\x97P\xc4\xe9\xa7$\x85a\x11\xbf\xb9\xcdo\xeb\xd1\xf3\xb9}S\x928\xfa\x0e&+\x1bA\x8a\x17\xd1o\x0c\xd2\x10;\xd5\xd1V\x1b\xa4\xf0r\xed\xa5N\x95B\x8c\\R\xb1&t\xe0\x86\xf9\xf2\xa5Z\x07J\xf1\xe1#5$\x0cU\xa0*\xe4\x06\xb3\x05~\xc7\\\x08\xe7|\xa9\x98\x91A\xb5M\xd8\xef\xb0\xbb\xf1\xd48\x178\x0f\xe7\xe8\xe5\xfa\x8e_Ge~4\x94`\x8a\xf9\xa1\x07\xe4\x0b\x18\xc19\x06\x16\xb3\x8b\xc9i]tgQHN\x1c\xb4\xbf\x9f\xc1\xa9\x10\xe2\x983\xf0\x05\xd3\x98p7\xf6\xfc\x17\xe5\xdf\xf6\"\xd7\xa6\\\xbb0\xb3opg,\xf0\xae\x15\x9f\xe6\xebj\xa3\xed\xb6!a\x16]9Mv\xa0\xc2\xdbs^\x83\x0d8\x03\xf2\xda\xebF\x8f\xe3uQoW\xc1\x89k\x8e\x10\xbfz7\xa4\x82]#\x05\xbb*\xc7\x92\x1c\xa9\xb6\xc0\xa2\xd8vx0\xdb:\x9bt\xd5\xd8\x0c| f\x8c\x07\xd8\xb3\xa2\xfbn\x8d\xccW\x89\xb0\x1b3\n8\x1b\xa7,\xcb\x1f\xcb\x9e<=q\xa0\xdd\x8e\xb5\xd4\x0b\x8b\x8e\x80\x17\x9d\x8a\x9c\xab\xf6\x9a\xa9]\xac\xef~\x17\x03\xab\xb9\xe0u/\x13.:\xd5\x1fI\x0bo V\x13\xd3\xb5\x10\x17<&.\xe2\x93~\xf5\xb4Zry\x97\x83\xd8F\xb52/J\xa4J\xc4\x08}y\xfa\xf9\xf9\x8c\xb00\x94A\x14\x9e\x9f\x0f\xc1\xc3\xd0\xa2D\xe7\xccw\x1ez+R\x94\xb9\xb2\xab\x0e\xd0\xef\xcb\xea\x91\xb9\x1dT\x9b\x9cG1}\xbd\x1e\xcb\xf8\xa0\x17\xcc\x0e\x86\x7f\x86\xec\xcf\x08\x02;'\xe8\x8aR\xa4\xf4\xfb-\xb9\xf9x\x93\xc6\x0c\x8e\xe3\xb8\xf9\x08\x04!$(\xd3.\xcc:\xfc\xc5\x98L\x99\xa7s\xce\xc1Hm\xd7\x16^\xf2\x92c\x89\x98\xcb\x98YA\xa4'\xcc\x9f\xcf\x92 J\xaa\xf4 y\x8e\xaa\xaa\xb3\xb5H\xf6R\xa9N-\xc0kU\x1f\xa8\x95s6V\xad\x92\x83EE\xfc\xa7\xf2\xfa\x8a\x92\xc3\xca\xbb\x08\xe3/\xe2w\xe5-\x9e\x13\xa9\xf2\x9e\xc8\x9a\xc4\xde\xe4\xbf\x94w\x13\xe2\xc5J\x93\x0c\xc8\xdfd?\xd4\x17\xd7\xc4\x0fHR}\x93A\xc5\xab\xec\x97\xe6\xdde\x90*o.\x834\x7fo\x19\xa4\xca[\x92\x08PyWz\xc2k\x90 \x9azrAA\xa9'\x7f\x92\xd7\x93C\x94z\xb20\xf1\xa35E\x83\xea,HOx=\x12\xa4\xe4E\x82$F\xa2J\xd5\x9d/\x119\xdaFU{.\xba'\xda\xaf\xb5 \xcb\xba_A\x95*;\xae\xd2\xb1\xc0\xdc1\xb9\xe5MZ\x15\xe4\xdb\xc6\xec\xedL\xef\xd1\xad\x90Qh\x83\xe5(\x0e\xa1\xa5\xdfx\xa4x=\xdf\xb4\xd5\xa4\x92M\x0b\xd4Q.\xcb\xa3\x0cddr\x9b\xa6U\\>\xe1\xed\xe8\xb5\xa3\\\xee\xae\xe4\x86\xc7\xe0\x189\xc6\xd9r\xa7\xf4\xbd\xca\x11\x11{\xe5[\xae\x98S\x8b\xbd\x105\xbf\x10\x94\xe2\xf0\x97\x04f}\x15\xe5\x99\xd0UQH\xe5\xf7\x89\xa5%\xe9g\x8f{[G1b!\xcfP\xdf\xa0\x93\x1cR\x8c\xea\x9f\xcb\x0d\xfac\x90\xd8\x1c\xc52\xdc}4\x9b\xf5:?\n\xb1\xab>Z4\xb9\xbd\xa5\xcf\xe54\x05\xac\xecY^\x16#\x98V\xb3\x18\x9e\xf2\x8b{\xb4\x1d~'\x8ecj\x87\x87\xfe\xb0\xa3b\xd1=\\\xf4\x80\xa2=\xf3\x93\xc5X&\xe3\x1e\xf7q\xc7\x07\xf4E\x17\xbcq\x9f\x03\xbf\xc5\xae\xe7}\xefO\xc7\x11\xe2xvr\xaf~;\xae\xa8\x8c-\xe0\x1d\xf0\x97k8\xb5\x99\x16\xd5\xa1n\x17\x1b\x83\x07\x8f\xa9\xc1\xe4\xac\x1e\x93=\xee^^\x8f\xebyn>c)\x1f\xd9\xc1\x06{\x81\x0b[\x19\xc5.\xf3f\xa0\xaf`\x1a\xc0q\xb2 =\x8d$,\xdd\x9c\x9eJ\xd2\x7f\x86\xe8\xe0\x8d#\x89\x9e\xd6\x93R\x9f!J\xc6\xe24\xb1\xbe\xf6\xa7\xe3\x00\x91.\xba\x03a}\x90\x9e\xe5\x17q\xf3\xce\xd0\xf7\x85\xdf~\xe0\"B\xd3g%\xd0 \xb4\xb0\x18\xb7\x7f?z\x04\xbe n\x0e2\\\xbf\xbb\x8e\xd6\xb6\xe3\xb2E\xe1\xbf\x9c\x0dj\xdeb\xbbH\xd7\x016\xd9'\x9b\x86_\xe1r\x8a,\x97\xa8\xd5\x7fG\xff\xeb\x1eRY\xc5\xf0\x7f\xcco'\xb2\x90\xb4]\x0ci\xc7\x83:\xdf\xe7B\xe2VB\x9c\xdc\xf66G9\xb4w\xa7\xf6W\xef\x91P\xa6\xf6+\xef\x15\xbb\x83\x98\x16I\x1e\xe0\xe1fk\x03\xa9\xbf5z\x18=XYt\xbe\xe3\xb4n)\x1bW\x89\xe4C\x88\xc5\x12\xb9 .:\xc2\x19\xbc\xe0\xca\xc2[PHi\xe18\xd8h\xd7\x95\x85\xac\xa6\xe0\xa1,_6K\xac\xe3B\xc8~\xb5\xdb\xa9\xf3\xed\xf0BIc\x85\xf9\xa3\x90\xf1\xb7p\xa0\xec\x0c_&Va\xe9\xb7\x86*<\x0c\xd1\xd1\xc8+\xdf\x02\xbdy\xc8S\xa0^\xc9\xa0G\xf5\xd0(\x8a\x9a\xe48\xcd|hJF\xf7\n\xc7\x15\xcd\xe09\x82\xb8\x10\xa1\x7f\x01ECM\xd8\xe4\x0dh\xe1F\x18\xce\x8e\xb9L\xcag\x83\xa5d\xc9G5\x00\xe1\xc7\xbb;\xe3<;C\xf9x\x86j\x16M\x136#\x9e\xcb\xf3~\xf3S\x1aC\xfel\x0b\xe4\xe7\xbdi\xd5\xf6\xa6\xe1\xc8@\xe4\xe6=U\x90\xf54\"\xb2W\x16\x91\x93\xb2\x88\x9c\xe4\"\xb2W\xfc\xd2\x88\xc8j\xcd\xc6\x9er\x89\x98\xae\xd4\x86\xd3s\x0f\x96e&\xe4p\xc7\xed\xe5\xcaD\\\xed\xeaw\xf4\xbf\x1e\x86\x07j\xef;\x85v\xff\xb8\n\x8f8\xfcH\x7f\xbfM $..\xcfT\xef\xe0$\xa6\x8bo\xe5b\xdb\x05\x0870mL\x15\xc1\x93\x184\\x\xe7J\xd3\xa5\x0bk\x17\xfd+\xe7\xdcAQ\xa5/u\x0f\xaf\xd0\xba!\xc2\xce\xa9\xcfo\xf0\xb9\x08\xc1X\xc6\xe8\xe2=\xf4\x08\xaf\x97\xe5\x84\xa4QD\x17\xd6\xe2V\x8c\x91\xa1DJ\x07\xbcVj\xd4\xd4\xebC\xad\x80\x88\xd7\x1737\xbb$\x17\x9f{.t\xfa\x945\\\xf1\xcb'\xcb<&\xc2\x9a6\xab\xda\x9c6rX\x8eli\x02\xe1\xaa\xc6o\xf9}e\xfa\xa2P\x04\xe9m\x9e\xbb\xda\xdb\xed\xda\xfb\x93\x90\xbb\xbbI\x11\n\xb4s&;\xee\x8d`\xbc\xc0\x88\x15\xa1p\xe2c\xd4=t\x98\x0d\x0e\xa7V#\xbd\x89O\xcc\x18\x12\xdd\x95KF'\xd6LZ^b\x96|\xe1\x92\xdf\xe0D#>(\x7f\x98\xe9\xa8.R\xec\x8c'4@~=c\xc17\x8a\x80\xc8\xb8\xb7X4\xd8\x88\xf1+\x1e\xcb8\xc6T\nQ\x98\x92\xeb\x14\xf30\xc5\x97\x89\x93\xfbo\xc6,yD\xc00%*P\x88\xae\x89)Et#id\x99\xbe\xf9\xdej\x8a\xc2q\xc5\xeeEr\x9fp\xe3\xa6\x08\xe9\xd0\xd3rV-\x1e\xfeCT\x0f\xa9\x19a\x84\xfc\xccD\x8a\xb4\x1b\xcc\xcc\x9a?\x1e \x13jS\xf9\xd3\x82\x9c\xdd\xd1\xdaXO\x16\xe3\xa4\x08\xda\xcb~\x04\x85MF\xe9>\xbf3\x86X\xa1\xf4\x8a\xffX\xe2\x8f\x9cq\xc5\xdb\xf5e\x81\x0eZZ\x94\xc6\x1b 6-\xc0\x88\x8e\xc3\xa9\x0es*^8\x90u\xe9\xcf\x0dD\xa1\xc4\x9esa\x85\x8b\x14Z \xa5qJ\x12{\xad\xe3\x0fj\xefs\x1a\xc2\xa8\xa2\xe8\xaf\xf9x\xa6\xbd`\x9b\xe1M\xfb\x0d6\xc5g$\x8d\x03rE\n\x8a3\x8b\x08#D\xc1j\xbd$T(\x12h(\x90\xf8\xb1\x96*\x89\x0fk\xda\x9e\xbb\xa0\x1bqe|9\xb5\xff\xafq\x9c\xe5\xcdj\x1aoM\xdf\xf8\xfb\x0f\xd6\xbd\xbc?\xdb\xf5P\xac\x08\xe6n\xe0oh\xd1\xb1\x04)\x04\xaf\xaa\x8a\x81\x85\xca3q\x1a\x93\x8a\x01\xf9`\xbb\xad\x0f\xeaW\xe3\xe7D\x19\xc0R\xfb\x12\x88\x03\xfe\xa64I\x7f\x8e\xc7\xc1\xe8\xe9\x8e\xbeM\xcf\x8e\x1c\x93\x8c\x1f\xe1\\cVF\x9ct\x84x\xb3\x03I\x1elH\xf2\x7f\xd5\xefa\xe9\"\x1asj*\xee\x84y\xccO\xb1\xd5\xe9x\xe2\xe4R:\xac\xb4z\x98\x9fP{]L\xc3\xbf.I\xfa\x19G\xd0\x1f\xd38z\xc5 <\x16LV\xb3\xfd\xef\xa7\xd4\x92\xd2\x0f\xe96X\xe8B%DsXD\xecm\xf1\x88\xbd\x04\x86\"\xa5b#s@\xaf\xb2\xee\xf3\xb33\xba\x1c\xf8\xa5K\x12\xdf[\x17\xfaT\x19\xa8N\x95`,\xcd,H\xc4dP2z\x19\xbc\xd8\xfef\xd1\xec\xdf\x84\x98\xfcl\x16\xc4$\x01\xaf\x08}g\xf4X*\xc5\xbb\x96\x82L\xf1\x10La\x9ea\x81\x12\xcfN\x9f\x1d\x83)ya\xa2t)[\xc2 \xb4\xdb\x01<\x81\xf8\xc4\xc1\x19\xe6\xf9{\xe4B\x01\xde{\x8c\xa0Mg\xff\xe9\x08\xfa(\x05S\x01d\xb7\x8ftgp\x08\"\x03!N@\xc0\n<\x1d\xc1\xdeQ^v\xff\x10\xcb\xd6=\x7f\xf4\x08\xf6\xf6i\x81\x8c\x12\xc6\xc9\x04\x83F\x15\x96\x89\xfe\x01Zr\x80\x12K\x1b\xfb\x1a\xb0*[\xfdJ\xd8\x01\x82uup\xc4\x1f\x88\x0e\x1e\x17_\xf5=D\xe8\xc1~\x0e=\xee\xe5\xd0\xe3\xc3\x1c\xda\x1f\x0c\xf02(\xce\x13\xce\x11\xa5\xe0\xac\xcbe \xce\x9b\xf5\xff\xfe\xc5\x9fY\xb5\xfbPuz\xd78Q\xc8\x18\x8b\x1a\x18\xf6\x0dO\xdan \x91Y\x8a\xcfJt\xe5r\xec\xeeX\xd6\x1b\xbew\xf2\xdb:\xa1\xdd\xef\xdf'\xb0\xa76p=\xad\xd8:?'\xc9\xa7\xd1,[\x12\xabJ\xb5y\x9a 9\x8d\x82\xc3T=\x98K\xaf\xceQ\xc5x}9I\xbd\x94|\x7f\x99]\x06a24l\xdadM|\xd33\xfa\xf1\xb0\xcdd\x08\x99Y\xc8O\xc8\x92\xf8i\x14'C0\x04c\xd2\xbf\xcbR/\x19\xbb\x068\xb6Y\xe6\x13Zs\"\xa6\xc2\xdc\x8f\xbc\xaf\xd1F}\xf5\xf4}U\xf1\xf0;\xfa_\xefU\xf9mn\x87\xf6~\xffX\x89\x90\xcd\xed\x0c:\xbb\x84o\xd3'{J\xa0e\xfeh\x7f\xaf_}\xe4\xe5\x8f\x06J\x90i\xd1\x87\xbd]\xc79\xf9N\xfeL\xe0\x0e\xf8z\xc5O\xca\x98C\x81\x9f\x05s8\xa9\xa0)\xe3\x06_U6\xa7|+G\xa3\x10\x93b\xe6\x05!=\xb65\x1c\xac\x0bC\x1d\xa7eEF$\x93\x19\xbc\xd8(i\xd9\x8fC\x9d\x84\xb9\xd1\xbdB\x99\x07\x1e\xb4X'a\xb1\x1c\x97\xd5 \x93\xdfQ\xbf\xd1q/\x95[B\x97$\xfd$\xf2\xbd\xe5s\xdc\x04\x9b\xc5\xfa\xb3{\x18\x8c\xd8\x8b\x13\xf2\xd3\xde\x8a\xbf\xea\xd8\xb1\x18\xfcv^\x0erC2]|\xdc\xe9t&a\x16/\x87`-\xd2t\x9d\x0cwv\xd6$M\xd2(&\xdd\xe4\x9dwyI\xe2n\x10\xed\\\x0dv\xc4\xaf/\x92(\xb4&\xe1,Z\x9d\x07\xb3!X\x7f\x85?\xe8d\x815 \xd11\xddK\xa3\xf8\x07\xa5:\xa3p\x19\x84\xe5\x1aEAk\x12F^\x96.\x06\x9f\x91Y\x10\x13?-\xde\x1c\xee\xec,\xe9\xbc-\xa2$\x1d\xee\x0ez\xbd\x1dV\xb2\x13\xf3\xa2\xddE\xbaZZ\x93\xf0\xb1v\xd0\x1bQp\xc9\xb5c\xd07hR\xe3\x87\xa9^\x7f\xdc\xdb\xdf\xebi\xb7od\xc4\xdcZ\xf4Q\xbcH\x85\xb5\x120\xfe\xa6\x88\x15=#\xeb\x98\xf8^Jf\xe0\x853\xc9\x91&K\xc8\xac\xdb\xe0C\x03\xf2\xfct\xa9\x98\x87#\xe9\xc9IK\xbbg\xfe\x82\xac\x98uu\xf7\xa8\xf4\xe4\xe3g/?9{\xf6\xf1\x8b\xf3\xb3\xe7\x7f\xed\xc5\xa7\xcf\xb8\xc1vP*\xf3\x93g\xaf_\xc9\xcf\x07\xbd\xdd\xd2\xf3\xe7\xaf?{Q~^~\xff\xa3\x17\x1f?\xfb\xc1'o\xce\xab\xed\xec\xefj\x8b}\xfc\x83O>\x91\x8b\x1d\x95\x8b-#o\x86\xa1\x02\xe8\x97\xea\x83g\xf4P\xc1\x9f=c\x17\xce\xc4\xe3\xc4\x9b\x93O\xc4\xbb\xe2\x87\xae\x80\xa8C\xfa-\x17\x9be\xab5\xc6\x0c\xa4_\xaa\xef\x7f$\x1e\x8a\x1fr\x81\x9f~\xf6\xe9'/\xae}\x82!\xe89\x1e\x96\x86\xf6\xe9\xcbW/?}\xf6I\xddZl8\x87\xe6\xe9K|/D\xd5\x81E\xbfY\xa5gH\xe1\xd8C\xfcZ~\xeaG+\xee{\x12\xd9\x16\xffQ.\xe1\xcdf\xcf\xa5\xf0\xe1X\xb0\x0c\xb3\xee!\xdfI\xfe}\xd5\xab\xfcA>\x9b%0\xbfD\xa5h\xa0\xb3|\xeaJ`/\x9f\xaf\x128iVH\x97_\xf0U\x85\xf2\x1cF0(\x83(\x92\xed\x96A\x14u\xf6\xca\xa0\x85Z\xd7L\xad\xebJ\xad\xeb\x86\xb9\xc2]\xf7z\x9d\xc9u\xefhr\xdd\xfb\xde\xe4\xba\xf7|r\xdd{\xd1\x99\\\xf7?\x9e\\\x1f~\xdc\x99\\\x1f\xedM\xae\x8f\x0e:\x93\xeb\xe3\x8f'\xd9\xc7\x1f\x7f\xfc\x02\xff\xffxz;\x9ed\x1f\x1d\xd1\x97\xb3\x8f\xbe\xf7\xf1\xc7S\xfb\xb4E!\xcf\x19\x84\x96pn\xed\xd3\xe1\xf8\xf3r\xb1\xdb\xcf\x9dJ\xb1\x9dr\xb7.y\xb7\x8e\xf6\xcb\x1ez\xe5R+,\xe5N\xc6\x93\xe9\xe4\xab\xc9\xfb\xea\xe3s\xfa\xf8s\xfbt\xd8\xbam\xb5n[c\xaf\xf3\xe5\xa43m\xb7\x9c\x0fv\x82r\xc9\x8b\xa2\xe4\xf8\xf3\xa2>\xc7>\x1d\xfe\xc4\xb8\xd79\xf6:\xf3\xe9W\x83\xf7\xb7\xec\xfb\x97\x93\xce_9\x99\xecLN\x87\xdf}4\x9a\xb4'\x1f\xb8\xe7\x93n\xeb\x7f\x98|\xf8xbO\x1c\xfa\xf6\xd4\xf9\xf0\x83\x9d@\xc7\"\xde\x19YD\x9f_B\xc33\xe3.\xfb.\x11q\xb5\xaakcU\xc7EM\xbb\x83\x0dj:\xdb\xa6&\xec\xdf\xb6}}alao\xaf\xa8\xea\xb8/}\xdf\x95\x9a\x18\x94~\xeco\xd0\xe03\x83yG+\x9e\xee\x1d\xa1\xb9\x02\xa5K~\xd2>\xc5 9{G0\xa4\xc7\xea'\\\xef\xb0;\x80[`\xc9\x9c\xd91\xbb7@}O\x87\x16j\xd3i\x19B\xa7_\xdb\xb1\xd7\xe6\x998\xca\x15]\xd6\xa4g\xb1\x96s\xc8\x7f\x87\x00\xb9\xc8\x05\x85\xf4\xfb\x07\x12(\xc5BU@?_.\n\n\x19H\xae\xe9\nA\xbd\x81\x04\x9a\xb3R{\x12(f\xa5\xfa\x05\xe8\xbf\xa7\x90]\xe95\xd4}\xec\x16/=\xb6\x1e\xc3\x10\xf6\xa4a\xec`\x0f\xe5\x96&\x14r(u\xe7\xff\xf9y,\xb3/A~\x13\xcb\xc8#E\xaa@\xa1G\xbd\n\xf4\x98)\xabk\x17\xe1\x8b\x9a#\xc6\x93\x11\x1c\xec\xef\xef\xee\xc3)W\\a\x96\xe9\xe7\\\xdfd\xa7\x85\x03j\xf9\x01K\xe9\xd9\xa6\xa7\xb5\x0e\xd6p\x00O\x9fB\x9fJX\xfb\x07\xbb\x83^\xf9\xd1#:\xdf\xbb\x8a\x11\x15\xe4\xd3\xd8[\x90\x13\xd3\x0e\xf6\x0f\x1c\x17^j`\x9f\xb2\x84r\x9f\xc2\x13\x18\xec\x1f\x9c\xc0\xa7\xed\xb6\x03o\xc7\x9f\xd23\xd9k\xfbS\x87\xc7\x19\xe8\xb9\xf0\xb2\x00\xea\x88\xd3\x1b\xad\x1e_hb\xc9;\x08P\x01C\xdeQI\xb7;\x0f\x96$\xf4V\x84\xb2\xf6 \\g)\xde\xdb\x8f\x92 \xc5;\x96i\x97\x9e\x1fd\x18t8\xf0,\xf5\xe2\xb2\x9b\xbc\xda\x97\xe7\xda\xbe0Q\x99\xf7\xb3\xf6\xfd\xef\xeb\xdf\xefF\xe1\x0f\xbd8\x0c\xc2Kv\x96\xcc\x7f\xf2\xeb\xea\xe8y\xca\xeb\xd7-\x0e]\x97\xcf\x94\xd3\"\x15\xd9\x86\x8d\x16\x1a\xf1\xbe1d\x0b?\xa2\x8f \xed^\x918\xa1\xc3x\xf4\x88\xcd\x845\xcb\xd6\xcb\xc0\xf7R~3\xf5'h\x93\xc0\x8eT\x98Q\xca\xe5\x91\x0fC)`\x15{\xb3\\\x12<\x9f\x8a\x96 \x90k\xcfO\xf1b*\xc9U\xba\xb4\x9a\\\xe3n\xc7\x8c+R\xa67m;\x93\xae\xf8\xf6\xc1N\x97\\\x13\xdf\x0e\xc7=\x1e\x03\x8d5\x14,\x97\x9dy\x14\xafdw\xffh\x0e\xe9\x82\x80\xda[*\x8b\xa1\xf4\xf82L\xedx\xdc\x9f\xbal\xafDe\xf8@\xc0\xa5\xb8\x8e\xac\xb5,d#\xc1lhX\xbf\x983\xde\xe6,\xf2\xf3A\x15\x13:\x82\x90E-\xef\xfa\x0b\xe2\xbf\xfd$\x08\xc9\xf7b\xe2\xbd\xa5\xe2[Dw\x90h\n\xef\xdc\x0e\x8a\xaf\xdf\xe7\xad&\xd9\x9a\x8a\xb1d\xd6\xd0hiu+*\xb67\xcf\xfe\xeav\xe8\xa2\xe2\xca\xc0\xb0\xdao\x9e\xfd\xd5\x9a\xc5N\xdfE\x85\xfe\xdf\x12\ny\x16\xd1\x0e\xbf\xd1u8\xef\xa6$I\xed\x18\x03@(K\x9bz\x97\xb0\xf0\xc2\xd9\x92\x80=\x0f\xe2$\xcd+t\xc4$\x94\xfa@[\xc9C*\xa4\xde\xe5\xa7\xde\xda\x85\xb8@\x9b\xc7\xe9\x82\xc4\x84\x1ep=X\xc7\xe4*\x88\xb2dy\x033\xe2/\xbd\x98\xcc \xc9\xe6\xf3\xe0\x1a\xa9\xa2\xf5\x18\xda\x10C\x1b\x1e[R7\x1e;.\\\xb0.\x07\xe6.\xafcB\xab\xb1\x13\xe2G\xe1l\x83>\x8b\xce2\xbf\x87r\xe0\xfc\x92\x96Q\xa5=\xaf\xc4\x92\xe2@U)\xa4\xc8\xdf\xaa\xaa\xe9\x08<\xd1\xa3\x02\xbac\xb0\xd8;\x94\xd8\xf2+\x1e\x888\xb4\x19\xa5<\x08V\x120sz$E\xf5f\xf9\x08\"\xfa\xa7=\x82\xbe\xc3e\x06t\x0e\xf0\xaa\xb6\x15&\xfb=\x19AF\xd7,C\xb9\xa7\xdf\xdf\xeb\xf7\xfb\xc5d\x93\xeb5\xbb\x83\xcf\xa2\x1c\xfc\xe4\xd9\xebW@\xab\xf1\xfc\x94(\xb90A\xdc4\xbca\xab\xe6I4\x84.E\x92\xc6\xc4[\xa1\xc3\x81\x17\x84 \x84Q\xd8Y\xc7A\xc8\xb6z^m\xa2\xab7\xed\xc6$\xc9\x96\x98/\xd53\xad\x99f\xc9>)\x96Lqo\xb9\xe2 \x04\xd0-\xac\xe2,\x833\x1cw\x83\x84\xa7\xdb\x0f%\x0c\xe4\x1a\x9a\x15\x89/ \xac\xbc\xf5:\x08/\x93\x13\xc4\xb6u\x1c]\x053\x8a\xddQ\x16\xfb\x84\xe7o\xa6\x9b@&k\x96\x93\x87\xd8\xa4\x87E[\xf2*xKn\x12;t\x9c|A=x\x02>\xfd\xc3\x164\xc3\x80\x8f\xde\xd4\x95\xe2\x9ce\xd87\x9b\xb0\x90\x94!\xfa\xdb\x04\xecG\xabW\xcfM?\x920Z\xce?\xac\x9b*\xdf\x85\xb9\x8a\xd7Aa\x08\x0cd.\xc3S\xf2\x08#\x91\x95z\x97\xc3\x1bo\xb5\xecF\xf1\xa5;\xe8\xf5\x06C\x9c?\xe6q\xabAsZ7\xbb\xeb\x18$L(2E>\xc0\xa5\xe2\xae0\xf4\xa0\x1d\xe5s\xe7\xc3\x13\x98\xd3?l\xee\x04.Dc\x1fS\x90\x1b\xb07/\xa6\x96\xc1\xe7)\xea]\xe9\x94'y\x8cb\x9e\xde\xa9X\x13\x06\xb0\x99\\\x04t\x8f\xdd\xde\xeaD\xa7\x11x\xecI!`\x95\xe5\x022\x13(\x06o\xc9\x0d&\xe0#\xe3`\xcaB$\xe5\x97~\x83\xe6D>\xea\xe2\x7f\xb9\xd1Y\x8a\x1f2p)\x05\x8d\x92(I\xd1s\x87\xdd\xe8\x12?\xdbmz\xac\xd8\xe5\xc8p\n\xb6\xfc\xc8\xcd\x8f\x9a\xb552Y\xaex\x8d\xca\xe8lz<\xc0\x89\xbd\xa0,\x9en/A\xa8\x18\x85\xc7gmt3\x92$S\x1c\x80\xa8\xacvf>6\xf1\xee\\\x86\x97s\x0e\xd5\x0e\xe1\x84;\x10\x04\xda\xb8\xac\xdc+\xeb\xda\x0e\x1c\x1e}TS[\xbb-\xd7\xa7\xdd)\xb8\xdbv\xd9\xd1\xca\xe0!7\x8bj\x0c~\x9b\xb4\xac}\xf9=\xbc[\x04Td\xe8\xf7\nA\xae\xbf[|\xe7`C\xbf[\xef\x90\x15\xe12\xaa%pv\xbeD\x07\x83\xe6\x89v!\xa6x\xc5\xd6\xfbe8\xa3R*\x9e\x9f\xf8A\x96.\x80\xfc\x90\x16\xdez\xd8\xefu\xbb\x8c\x87\xb0\x0d\x8b\xe1\xc6\x0cq\xa5\x9e\xcd\x0c\x99\x06\x8f{\xc16\x08\xe3\xbe?\xc5\x89\xfb\xd2\x85V\x1f\xbd\xe3\\\xd1\x94@\x0e\xa7\xdc\xbfM\x1aw\x0bf\x8f\xb4 g\xf7|HO\xb9\x83\x10\x9f`\x87\xf3\xb1\x0bo&\x13\x01zj\xf1 !?\x9b\x91\xd0'@\xc24\xbe1\x8a\xd9\xcc\xc7\xacDd\x88\x96\x96\n\x12\xd0\xf28\x8e\xd0\x83\x13Kd$p\x07\xc5\x89\xb4\xfb6\x08g0\x02K\xf4\xc0r\x8b\xcd\x841\xc6\x9a\x04\xca\x9f6\xd3\xa8\\\xc4D\x8c\xd6\xef\x80*\xa6\xd3!\xee\xee\x16\x11\xc2\x1b\x04\x90\xdc\x7fBW\x8f\xb4a\xe8\xf8M\x1a\x18\x8f\x1f+\x99i\x87R\xe5\x03.\x01m\xc2-0\x12m\xc41~\xb3\x17\x86\xb0\xcb\xa4\xa4@D\xb1\xc58\\t\x19Z-k\xf3Z\xd8\x1b\x16\x0b6 \x0b\x94\x91N\xf20\x8a\x03\x9b4\xa7\xbc\x98\x8b\x01\x92\x14p00\xb2~\x89r<\xc9\xb3\xf8\xd1\xd1\xc7\xba\x83pi\x97m\xd2\xbdBL\xcc\xc2\xfc\x04K\xc2\x99\xd0 \xf0\x83\xe8\xbb ]\x04!xpE\xe2\x0b/\x0dVt\xe5\xab\n\x1eS\xa8#.\xb9I\xe3m\x9d1)._M\x96D\xe0T\x9c\x80\xbdK\xa1\xf3\xe0\x07H~\x10\x06r\xed/\xbd\x15C\xc0\x95\x17\xbfM\xac<\x0eqe.X\x16\x85\n\xdd\xcd\x15;\xf2\x195\xf4*:\x9dJ\x9bI\xe6/JGn\xe6\xa5I1\xaf\x8c>\x8c\xb4o6\xef\xeaB7\xaf\xe7*WJ\x15\xba\x02\xe3L\xcd\x97\xd1;J.\xe9v\x8d\xe2R\xff\xcb\xab\xa6#\x7f\xc8\xc8Z\x17\xfa\xf60\x99u\xfd\x1c\x0d\xd1m#F]\xe6)\x08\"\x1a\xc3PU\x83\x85\x8eT\"W8\x85STs\x0d\xe9.\xe5\\\xa2(Ea\xe2\xa9\xee\xb1z~\x16\xe5\x99\xb6-\x0bs\xcd\x9a\xb4\xea\xa8Y\x0bQ\xb3\xf6\x18=\xc1k\x89\xf7\x0f\xcd\xc4[C\x96\x8f\x18Y\x0e\xefA\x96\xcd\x82\x8c\x9e4\x87\xc0K\xc8\xe4\xd9\xd0\x81\x12fV\xb1Zl\xdc\x90o\\v\xd4l\xbd\xb0C\x07\x93\xc76\xd7\xa8\xe5\xb0\xd2\xb6\xc9u \xc5~,\x0f!\x8cf\x04VYR\xe0\x9b\x97\xc2\x92xI\x8a\xaa{I\xcbVb\xd3\xf5\xbb\xa9a\x81\x7fJ\xd2\x86i\xf8\xc2U~I\xf2\xc6\x85K\x17V.\x9c\xbbp\xe1\xc2kf\x8c\xd20\xed7\x06f\xfe}\x033\x97\x16{\x19$) I~Vb\xbfl+Zc\xd4\xd9T\xe8j\xa1\x88\x1e\x9d\xcf\x82\x00pyE\xfc\xcc%\x15\x06@\xb5'\x8c\xd0\x19b]\xc8eLA\x85A\xeb\x1f=R\x04Q\xfbM.\xaf\x96\xc578e\x93\x00\xc3\xca!\x93\x9f:\xd0\\W}\xf8\x84+\xc2>E\x97x\x07\x0d\x1e\xf4\x85O\x0d\xde\x9a'L\x82\xba\xbd\xc5\xcdx\xe2\x94\xbbwZ\xf4\xee\x86\xc9c\xdfJ'a\x88\xd5\xeb\xd6\x8f\x07j\x80\x11\xbc\xa1\x9d\x8cr\x0b\xce\xa7\xf4\xc1\x9ao*z\xea\xbb\x80\x11\xf8\xc5\xa4\xcfs\x92F\xf0<\xd6\xa6\x9c\xecu\x99\xd5\x94\xec\x88\xf9L\xc1)\xbf:\x8eg\xaf\xd789\xdb\xd8X\xdcB\xc9\x9b\x98Og\xc0=w\xcc'4\xe0^;_\xd5\x8475=\xcb\x91T\xfb\xf4\xaa\xf6\xe9M\xed\xd3K\xc3\x06\x04\xeeG\xa3\x0b\"|\x87\xf3\xe3\x92\xab\xac7;?z\xc6$D\x18\x84\xa8\xa9\x1e.\xd6D\xd2\xa1-\xab\xc8\xb4\x07\xecP\x80\x07\x9a\xfd#\xfe\xfd\xf6\x96\xd2\xf2\xb8\xf9\n%\xd2\xc1\xd0\xc5[\xaf\xec\x08h\xd4A\xc9\xefI\x07<\xadL-\x7fX\xaa\xdf\xa6\x91:'pm{t\x9f\x1b\x8a6\xc8W\xf2\x87\xf6p\x9f\xf9[x\x0e\x9c\x99\x1a\xafH\xca\xb9\xc4\xe8Q\x11\xfe\xffc\xee[\xbb\xdb\xb6\x95E\xbf\xf7W\x8cx{\x1c2\x92\x15I~$Qlk\xa5i\xd2z7ur\x9a\xa4\xfbt\xcbj\x16-A6\x1b\x89T\xf9\x88\xed\xbd\xdd\xf3\xed\xfe\xb1\xfb\xcb\xee\xc2\x0c\x00\x82$@\xd2N\xd2\xd6k\xb5\xa1@\x10\xcf\xc1`\xde\x93\xb2d\xe3\xcf\xb5\xdbG\x97\xad\x82\xbf\xe4%\x9c\x82\xfe\xc0\xae\xb7\xd1w\x02\x12\xb6\xf1c\xa4\xc6\x149}\xb6\x8a\xe6\x1f\xa4\xd4\x9a__\xc8l\xb9\xa8kX\xf5\xf2\xa88Z\xc4\x9b\x8f\x02K\x8b\xa2\xb5@r\x02\xb8\x91\xf8\xe4\xff.\xd4\xf9\xc5/$\xc2\xaf_\x97\x86\x9c\xcc\xf2\x0f\x01c\xad\xb9g\xd1\xd5\x93\x14\xee\x9d9\x07\x96\xfa\xee\xf8\x9f\xd2\x13aD\xd8\x98\xf9\x0b~\xf1\x07kN\xcd\x04\xa9\x12\xe8o\xfc ~\x02>\xcc\xa3U\x14\xf2\x95^\x07IR \x9bW\xfe3\xbbKC\x1d\xb3\xa2\xff}\xaey\x9a\xe6X\xdcz\x12_\xf0 \xae\xb3U\x1a\xe0\xd9\xf9\xc0\xaea\xed_\x830q\xd6W\x05\xd5\x1b\xf6\xb9\x19\xdf\x88\x19\xef\x13\xcb\xe5\xf3\x0b\xf2\xd3\x80Mp\xed\xe42yN\xedi08\xc8Y\xcb \x9cG\xeb\x0d\xea_\xd8\x95ec\xf9l\x91\xceS{\xfb\x04\xa2\x18\x96\xd1j\x15]\xb2\x05\x9c]\x83\x8fj\xd0\xd4?\xcbV\xa8\xeca\xebMz\x8d\xca\x0d\"\xfcr\x9c\xa8\xbc\xa6c\xf3\xc6P(\x11\x0dEYeP\xae\xa4\x037DZ\x04T\xca\xa7\xab\x1f+A\x06hB\xb1s\xbc\xd9+k{-b\xd9\x1b\x97\xb7(Hk\xc6\x88\x9e\x81\xa8Qr3\xbfVnV\x80;\x9b\x17c\x93\xe8\xac\xf2Q\x15\xf2\xc4\xd1AH\xb3\x01\xda\xba j\xab\x9c\xae\\\xd4&\xf1d\x81~\xc5\x16\n\xfd\xfe\x81\xc4O\x0f\xce\xbc*\x01d\xa3~\xcaZ]\xccY\xb3\xd4\x93\x88u,\xf9\xc6\x17\xf5\x84\xd2\xc7FB\xe9\xda\xe0\xad\x04\x02H\x859\xa8\xbbi\x86\x05\xd2\x89=\xde\xe9 98IbM\xe9\xc9k0\x1f\xefs8\"\x82ac\xe5EUmN>\x8f\xf6D\x8f\x03\xea\xf1?M\xfeip7\xb2*\xf6(\xc3T\xd3=- \xabM-a\xa5\x8e\x1a\xf3z\xad\x96W\xe8\x0b\xab\xec+i\xd2\x08v\x17\x05\xd8\xfd\xa8\xc1.\xc7\xb7\n~al\x13\x1b\xc7\xf6\xcb\xe4\"\xa7?\x08?\xc2>9\xc5\x9f\x04\xe1\xf9\x8a\xc1\xefY\xc4\xab\x8a\xbdGZ\xa2n\x96\x86\x83t\x1b6\xc3\xdc\xe9\xe78):\x83a95\xbb\x04\x1e-\xc4t\x9f\xff\xd4`\xe2m\xf3\xa9i1\x9eZ\xc9\x88\xf0]\xf5\xd5\xa0\x8d\x18m\xe0\x95\x87d\x03|\x14c\x8dd\x9b-\xce\xa2\xa9\xab\xcbv*\x1aO\x87~\xfb9TrM\x9f\xfcE9\xd0\x7f\x98\xfa3\xafp\xc1\x1c\xa3\xef\x88>\xc9\x16-Rp\xd1\x910\x83\xe3\x1c\x8b\xcf\xcf\xd2\x08]\x89\x1f*Vf\x17\xc6\xf0hO\xfd\xe4l\xc3\xc0\x83#\xfe\xbf\x16\xba\xb2\x80\x14\xda\x11\x19m\x07\xfc\xbb'\x10lo{\xd8\xfb\xd3\xb6k\xc5\x99\x14\x0c\x1b\x87~5\x07\x07\xb0\xebA\x172\xc5R\xa9\x13x\xc1\xae\xfc\x05\x9b\x07k\x7fU\xef\xd2\xa4\xff\xe9K\xf9\x9b\x1b\x95\xe0\xc5N\xb7\xd0ZJ,\xf0!\x8c.C\x10\x11\xd3\x94\xcc\xac\xa6\xeb\xea\xc9\xa8\xc7\xa4~\x8eI\xe9\xe8\xdb0i\xb5\xe1/\x84I\x17Qv\xd6\x06\x93\x96\x06\xd3\x82\x96\xb8\x0dj5\x8f\xc2\x88Z51NGC\xb26\x0c+\x0c\\\xcdXu\x97d\x18\xcd\x8a\xef6X\xd5\xd2H+s'2\x81{#\xac\xdf:\xcf\xdd\x98\xa3\xcd6-V\x07s+\x93\xa7U\xe0'\xb7\xb2x2\x18?\xf6\x8a\xa6N\x9aH\xbd\x14\x8eE7\x84\xbc\x97\x85J\x0c\xb0\x10\xe3(\x19\xc5iw\x92.\xa6\x0fge\xddU\x95\\\xe5`rWS\x14\x94\xba.\xa5\xbc\x95\xdf\x94v\xe1\x9c]\xd1\xcd\xc1\xeb\x8d\xbbl\x06,\xbe\"\xcf\xdd%\xb9}\x12\x92F\xa6w\xe7Q\xfe\xbc;\xd2\xcaw\xf2g)\xe8\xc3\x1f\xfbz\xa5\xc7\xda\xb3Vg\xe7\xa1V_+\x7fL\xa1\x1e\x96\xb5P\x8e7\xce\xbe\xd6\xbd\x10\x9b-IF\xff\xa6\xf9\x18 \xee\xec\xe6\x86\xec\xfb8\x98\xb78X\xcd\xe4J\x80\xbe\xe4ErWX\xad\x8b\x03\xb6\xac\xa5B\x84u\xc6\xb2\x89b\xb8\xe3\x14k\x98g-\x8f\xef\xce^\xdbA\xd4\x0f\x00}eZ\xf4\xd9$\x95h\xbcj\xf29.\x9b\xa5\x8f\xbc\xcdK\xac\xd8l\x05\xe1+1\x8bT\xd3h\xc6gsU@\"\x13\xed\xe6DdP\x14\xdc\x1c\xda\xb3t\xe9\x7f\x99\xc6\xbf\xdfYZ%\xfej\xe3\xb6\xcb?\xbb\xc0\x04\x8af\xf8\xc2\xff\x83\x8c\x078~\xd2wB\xe8\xaf\x0b27Kr\x01\xf9w\x179\x8e\xb9\x14\x15`D\xcb\x10\xfe\xec\x0c%-#\xc6\xbb\x0d\xbeWw8\xbd\x1e\\ \xcc\xe7\x16k\x08C3\xcbv4\xb8<\xd8n\xc4\xf2P;\x1d\x85F\xc8%X\xa0\x99\xa2\xc5\xea\xa6*Q!R\xa4'\xad( \xfd\xbd\x16 \x94\x07\xd0\x96\xde,\xca\xd8\xc0\x998(\x9b\xaa\xa9\xab\x95\x08\xcdnn\x07\x96\xdf\xd5\xc9E\x94\xad\x16h\xabs\xe1\x7fd\xe0\x87\xd7\xd2\xf2\x1a\x95\xb0\xd2\xdf\xbb\xb5\xba[\xe9\x15s\xd1\xd9\x8fjVh\xe4)l\xe1h\xf5\x91\xb9\xda\xd4\xeb\xf1\x84\x06\x13\xef\xfbs\x19;OwM\x93\xfb\xfc\x9e4\xccw\xdc\x82\xcf{~\x05\xb2\xcf=!\xae7\x8c\xbaFh\xbf\xb9\x01g\xe9\xafVg\xfe\xfc\x833\xeb\xc9\xed\x99\x80X\xb7\xda\xeaS\xac=+\xccT\xac\xd1\xd6\x16\xbc\xa7O\xa8\x18\x1f\xcd\xa1d\x10\xa2\xf1=\xdf\xfe\xce\x01\xc6\xe0\xc4\x95\xec\xc2\xbd#H\xfds\xd4< \x98?\x13\xbe\x13\xa2uN+\xf6\xf0 `i\x9a\x97\xdeC\xff\x9b\xca.\x93\xc3{\xd3N\xdeq\xebr#4\xa1'\x13\xdd\xa31\xd9\x82!\xbfS\x9a\xa1s\x94+\xe1\xd0\xcbI\xf7\x91\"~\x94W,\x7fdI(\xd5\xc2\x8a\x7f\xbe\x8a\x12&\xcc\xf8K'\x99_\xe8\x95\x89\xdf\xdc\xc0\xeb\xafr\xf8R\x8f\xcaw\xe1\x87v\x9e\x85\x1a\xfa\xaf\x00\xa9\xc9\xc3P\x90~Z\x18!\xe1KP\x0d#\x94\xf6W\xec\xdc\x9f_\xf7\x94K\x8f\xc8l\xa6m\x18\x99=I\xb1U\x0b\x97E\xdc\xf1\"\x9f\xd1\xfcU\x0f:nIs4\x10tw\x07-z\xcc\xd20\x9ck\x06\xed\x9d\x13m|d\xc1\xdf\xadMC5\xbc\xect\xd63\xfa\xba\x15\xd8=\x19\x0f\x05\x0e\xc8\x8d[\xb8\x07\xa9xH\xc8k\"kiR\x1b\xeb\xe6\xcc!PKNCd\x06\xf8L\xd1\x19\xa0\xa8\xa1\xad\xcd\xb1\xd4\xa8\xa3m3\x04;\xd26\xf8hR\xfc\x05\xfbUPC\xdd[gZ\x1b\xd2\x01\xe4\xb2~1\xc0\xe2\x7f\xb1t\xe7\xae\x81\xa8\x16\x04\x9d6&\xd2;\x8b\xeb\xed'\xe1\xe1\xf7\xd34\x9cI\x19\x1b\xc7\xa7\xaf\x85\xc4\x81\xf0\xa9\x12\x82\xe5`Z\x90<|e\xef\xbc\x88\x0f\x06\x1ak$\xce{\xee\x9e_\x8f(\xdaV\xa4x\x0e\xed+\x8f\xbcbD\x17\x11\xe1A\x1f7_\x90\xccpV\x13\x14\xd0\xad\xfd\xb8\x12\xb7\xe5\xe7\x9c\xa6\x17\xd3D;\x8d\x8df\x9cV\\\x98*\x92\xde\xda\x82sr\xf0,\xee}T\xdc{P\xa18\xc2(\xdc~\xfa\xe6\xd9\xf1\xb1\x16O&\x01?f\x10\x84)\x8b71C\xc7\x87\x04\xd9-\x15tNnmR \x1b\xd0\x82\x9f\x9d\xc0\xee~\xf3\"{\x82\x14hXa\xad\x82\xe6I\xbd\xadc\xc9\xaa<4\x8aQ\x16*\xc03\xf7\xe0(\xecG\xede\xfc\x9dk\x8c\xc2XL\n\xc3d\x86(~G\x0e$\xbd\xa0\xe2\xda\xc9\x901\xa5\x05\xc8\xa7\x80K b\xc9\xd4Wrs\xf3\x82\x1e\xec\xef\x8d\x1e\x8aX\xa9\xfaG\x03Y\x93\x97\x8b<\xfa^\x19\xf7Q\xb2\x04\n\xc5\xd9\xa8YK/\x82\x84\xb6\x100\xfd\x01\xfe\x96\xd131!\x92\xfa!H\x1eQ'\x91\xf1\xd8\x99|\xbc\xb9A\x9e\x9b\xbf\xcc\x03Y\x1eb\xda*\xf9\xab\xd8\x04Q\"XE<\xde\xdc\x90\xd5\x02\x7f\x8b\x01\xaa\xf8;\x19\xa9J\xbdQ\xe4\x1a~)\x7f\x14\xdb.01|j\xf9\x981\nx\xb0b\x8bcQG|\"\xe8wK\xe5\xb7\xf4V\x0d\x1d\xf7.\x07\x06Q\xae\xc9\"\x06j\xb4(\x8e\xd0\x7fJ\x89\x84^\xa6\x1b\x02a\xa1:\x9fH_\x14\x11-m\xa7\x81\x08\x0c\xc5^\"$\x0d\x1c\x158(\xac\x1e\xd3P\xbb\x80<\x08\xf5A\x90\x9bFX8\xb7&\x92\xf3\x89^\xe7 \x0f\xf8\xb8\x0d\xc3'\x1e\xfc\xe0Z<\x8c\xc3|n\xb5\x07\xf4k\x9b8Z\x13E\xc3!\x9d\xe3rW\xc8G\xcb\x96\x1c\xcc-B\xf9\x88\xf3\xfc$\x91aFZH\xac<\x04[\x0c\x07\x10\xf0\x7f(\x04\x1bs\xa3i<\xab\xc7-\xdf\x1b\x0f\x9c<\x99\xdf\x99\xf6/XJ\xaa&T\xc9\xaf\xaa\xe7\x95\xd7\x1a\x8a-\x95\xb5\xe4\xb2N\x07\x06\x9f\x82<\x81C\xe0\xe6\x8aC\xa5\xa1W\x184\x085\xec\xda\x83\xb3,\x85e\x94\xf1[.\x8a\xd9\xad\x128\xe4I\x0c\xbe\xeeU\x93\x1e|\xdf\xb3\xe6+h\xd2B\xb4\xd8S\x04\x99\xb8\xcf\xaeR\x16.\xdc\xea\xf2\xd1\xa1\x1eCV\x9c\x0f\xef\xac\xb4\x1d\x12\xf8\xee\xd8\xd8W\xdaOc\x02\x87Z\xcc,f\xf3\xfd]gS\x8d\x0f\xfc\xe9\xe9\nL\xc1D\x03\xb7\x10z\xb1r\x97r<&.\x12\x89e\xcf\xb2\xe5\x92Pw\x15e\x86E\x94\x19\x8b\x9f\xf3h\x95\xad\xc3B\xa0\xd3\x1c\xee\x02-\xa3\xc19K\xdf\x84\xc1f\xc3\xd2\xa6\x05\xae\x98\xabW\xcfbG\x1b\xae\xa7\x0b\x0dL\xbc7\x88\x00\xf0\xbb\x1a\xc5\xf0pOD\xc0\x91\xf1o\xf4\xd9\n\xeb\x00~\x9do\xd3yvN\x07\xa7\xf1i\xf8\xff\xfe\xaf\x9eU\xc0\xe9\x07\xe1\x82]\xbdZ\xba\xdah\x10\x8b?M\xdd\x80\xf4\x17\x96\x90U\x01lS\xf0\xc0\xc2\"oc\xbf\x0c\x1e\xc0\x88(\x0f3\xb3\x86\xe3\x86~\xbf\x0f8\xf8\xee!\xec\x99\xb9\x946\xeef\xb8Dz\x1e\xbd\xd2Jd\x9c\xec\xd3\xa6\x97\x93Ww^\x9a\xcc\xba,n&\xd0\xf8vieZ\xacJ\xa4\xafJ\xc6\xd7\xf7\x13VE@\x94/\xd7CL\x80\xa8\xba\x80\\\x11sSJ@1\x94\xe0\xbc|4\x00\xefR\xc0\xfcn\xb9\x16t\x0d{\xde\xd5\xee\x8b.8\xbf::\x82\xd2\xcf\x90L\x19\xd86\x1b\xb5\xe3\x18\xef\xf8\xfc\xe8s\x82\x15)\x88{A($\x8f\xea\x1dFK\xbe\x87\xaarN\xb1\xf8)q0\x0e\xc6\xa3W\x98\x00\xf9\xba.\x9f\x9b\xc0\x04\xf9{Q@*\x10\xd2M0\xb9\xa096p\x85\x88\x8az\x19\xd3\xaa1\xde\xad\x11M+L\xf3\x89Hs\xa0])z\xe3\xfc2\x8e]C4\x9c$\x8d+\xd9\xfd>\x04\xe1b\x9c\xabs\x0b\xef\x94\xf7\xd7lu\xdb\xc6\xcd#\xaf\xdb\x17\x91\xe7\xf1Mz\xbdbcp\xd4z9\x7f\xf5q?\x8b\xa2?\xf5\xb8\x1bL\xa7Z\x1f\xf7\xc2\xb1N\xe3\x8c\xe9\xc7\xf8m\xf9\xf7O\xef\x9e\xcbc\xcd\x0b\xf6\xf4\x8f\x97\xfe*)\xd4~Q)x\xfa\xf2\xcd\xf3\xbb\xa2\x85\xbas|\x9b\x81\x7fN\xfc\xe1LE&\x81o\xa2h\xc5\xfcpF}T\xf2\xd2I\nT\xa8\xe1k\xe7^\x8bmL8\xc1\x9a\x82\\\xd2\xad0\x91\x0b4\x06\xb1KmN\xb1 E\xb4\xea\x8b\x16{,\xf7\xbbM_&\x8c\xd1\xae/9\xaf\x17\x96y\xfd\x1d\x10\x88%3\xe2m\xb3\x9aV\xf2\xa6\xed\xe5\xe344\x94\xb5o\xe8\xa1\xd6\x90|*c\xba\xc0\x84\xe9\x820\xfd; :\x12\xd7\xe8\xb2k#\xe0\x04v\x87zS\xc3\xca\"\x17\xee\xe4FU\xe8\x1a_\xe7\xbfD3\xeed\\\xbc\xc7\xf3\x1e\xa8\xf2\xe9i\xdf\x9d\x8c\x83pys\xcc\xff;y\xe1\xddPQ\xe8\x877'\xfe\xc9\xcd\xc9\xd3\x13\xcf\xfbZ7\xb9\xc7\x80\xfc\x98\xadW\xeb\x9c=\xb0K \x8d\xbc\xf3r\x15\xf9_\x84{\xd6\x85\xdb\xa4\x15\xe1\x88\xd6\xedD\x82\x80\xf1t\xda'\x9d\xeaf{\xb3\xcfN\xd2\x18#\xc1\xc8\x11\xc2!H2BX\x1eW\xa8\x91~\x1a\xbd\x8c.\xe5\x89\xe6\xa4\x04L\xf8=>\x06\x11\xfcw:\xeb\x81\xd3\xdd\xceu\xe7\x0c\xe9\x95#q\xc1\xb8d\xf2\xa7h\x91\x1e\xf0\x9a\xcb\x9c\xf4\x10\xa6G0\x11wY\xff\xf5\xab7\xc7o\x8f\x7f~\xfe\xfe\xf8\xe4\xc5\xf1\xc9\xf1\xdb_`,_\x9d<\xff\xeei\xf9\x95\xd3\x0f\xfd0o\xee\xc4?\x811\xb0\"\x85!0\x9b\xcb\xeeFf\x04E2\xe3\x05\x07\x9cZBCX\xe7\xc5Dh\x04\xb7\xe8\x8aIB#\xe6\x9f\xdb \x8d\x10\xees\xb2y\x8c\x0f\xda\xa8\xd8\xdf\x89\xd4p\x89\xd6\xe8\x1c\x92\x1b\x86\x81\xd4hKk\x14\xf0\xa4\x0d\xe2C\xb3l(HN\xfc\x13\xde\x17$\x97A:\xbf\x00\xd7*;\x98\xfb \xd3\xe5\x90cc-\xd0\x16\x07\x81\xcf\xcc\x1dQcJ\x8a\xdb\xa6\xb1\x93\xa7'\xb5\x8d)1m\xab\xc6\xfc\x13\x83<6\xf7x\xb6\x1e7!\xf4\xfb\x12\xab\xc5O\xfeg[\xad\xe3\x93\x17\x9fo\xb5\x8e\xc3e\x9b\xd5\xaab\xa0/\xb7Z\xdb\x9fu\xb9\xb6?\xebzm7.\x98\xe9\xb4\xe7\x9f\x0f\xfa\x03\xc3X\xb4{\xa9H\xf6\xf6 S\xc9\xbc&\x10\xaak\xcaa\x0e\xbfP(\x02fX\x87L\xfe,]C\x99\xfc\n*\xe4\x97\xa2\x8e\xb4\xffy\xdb\xae\xed\xc7\xd7N#A\xd7\xd8\xe2\xa4\xf4\x8b\x93no\xd3\xd9\xcd\x14NO\xd3Y\xd7+\xbc\x1c\xeb\xbd\x17~\x10}H%\xf7=\"\x10\xb1\x85\xfb\xee\xbfn\\N\x8by\xe5n\n\xdf{\x13\xcf\x9b\x14(\xb9V\xea\xdc4X\xb3$\xf5\xd7V+\x96\xcfN\xac\xe5\xe1\xca\x83>\xbbbsA\xb3\xa9\xd2H\x96~\x01r\xcd\x10\x07\xc5\xa23\xd9\x08\xb7L\xf3\xb5\xa7\xf47H\x81\xa9yx\x8a(\xcb'\xa1\xe7'\xf74\xf3\xee\xe7q\x1c\xc5\xae\xf3\xad\x9f2\xe5K\xcbx\x99)(S \xf2\x89v\xd9t8#\xda\xa7\xcb\xa6\xa3\x19y+e\xf4sg\xd6\x83\x0e\x9b\xee\xcer\xf3Wv \xbc\x03\x97\xff\xaf\xff\xee\xed3W,\x83\xc9\xff.\x10\xe1)\xba\xbc \x8aN\xd1e\xd3\xbd\x19\xc5\xa5\xe8\xb2\xe9\xfe\xac\x07l\xfapfC\xc2(p\xc5\x80\xb7\xd3\x873A\x94\x0ez\xb0\xe3=\x81U\xeeK\xb9\xf3\xc4\x83\x15\x1a\xf6\x99\x90\x14\x88\xa8\xd1\xddU\x15\xfd\xd9\xc0\x8bM\x1f\xcfp\xe1\xf9\x9e\xed\xb3]\xb8\x0f\xee\xfe\x00\xee\xe3j\x0df\xd0\x85\xae\xcb\xa6\xc3\xe1\x8c\x83\xd9@\x8a\x00qC\xf4/\xb77\x9e\x88\xcb`]6\x0dzV\x1eFS\xdf\xda\x82e?a\xe9\xdb`\xcd\xdce\xff\\\x93?\n\x0d\xda\xa5\x0b\xce\xd3o\x9e}\xfb\xfc\xc5w\xdf\x1f\xff\xe3\x87\x97?\x9e\xbcz\xfd\xdf?\xbdy\xfb\xee\xe7\x7f\xfe\xcf/\xff\xf2\xcf\xe6\x0b\xb6<\xbf\x08~\xfb\xb0Z\x87\xd1\xe6\xf78I\xb3\x8f\x97W\xd7\xff\x1e\x0cG;\xbb{\xfb\x0f\x1f=\xee>8<\x0dOc\xe7\x96\xec; x\xbe\xc4\x86\xddY\xfbm\xc1\xd3A\xa3b\x9cc\xc7\xc8\xa2\x1e\n)\xf2_H\x1eCa\x9d\x8e\xa8\xe3\"b\xcfr3vi\xbcN1\x00a\x7f\xb7Qk\xc4\xe0\x00\x06\xad4?(\x13\xdf7\xbe\xb6\xe2\xc1\x18\xfe\x0b\x1e\xa1\xf0\xb9\x08\xf6\x9f|q\x06E\xe9\xc5\xf44>\x0d\x0fgB\x86a_\xf4\xa0v[|\x8c\xffc|\x95\xd8\xb7{n\xd1\x07)\xff\xee\xc1\x13\xe0\xab\x9c=\x01\xd6\xedz\xc0\xe0\xbf\xd0\n\x8c\xe4%\xa4\xce\x99\x8b\xfc\x10pt\x04\xc3}\xd8\x82\xd1\xde\x9e\xd7\x03\xbd\xf8Q\xb9t\xb4\xb7\x07[\x90p\xa4\x9f`\x12\x90\x83\x03\xd8\x87\x1b\xf0\x158\x04\x12\x1c\x98\xe9r\x15[4\x00\x19\x087\xc3\x81\xdd\x87}T\xd1|\xd2\x90`\x0c\xc3GJ\xd0Slk`lk$J\xf1S\xe1q\xc8\x97F\xaf\xb3\xab\xbe\x8c1\xe9\xc62\x8e\xd6\xea\xc1\x9d#O\x80\xe8\x1e\x1f\xe7u w[\xa9\x08\x06\xf6\xe0,\x0e!\xd0\xf6Z\x93\xb6\x00\x1d\x93s\x8b\x15\xa1X\x80/k\xc45~\x0d\xae\xb1@\xe7N :\xf1\xe4\xfb\xd3\x00\xb7\x8fo\xfa\xfe\x0eR|Z\xe9\xc8T\xba_*\xdc\xdf\x81-@s\x1c>#7\xe0\x10\xfb\xc8\x83.\xa4SfW\xa8\x16\x01t\x87\xf4\x87\x9fyD0\x86Q\x0e\xae\x85v\x06\xa6vv+\x85\x07\x07P\xeeq\x7f\x17\x1b\x1e\xe6\xc0\\h\xb9:\xc0\x83\x83J\xc3\xfb\xbb\xc5\xf6z\x10\x17\x01O\xfd\xfad\x02\xc2\xca\xceVd\x7f\xc58\x93U\x02\xc1*,\xbc%\x89\x16\xd5x2X\x9c9>\xf1\xca\xb7\x19\xf2\x97\x985\x12\x83[o\x03C\x80\xca\xfc\xb8\x91>z\xae\\\x83\xf9\xe1\x0b\x9f\x90 \xd8\xea6\x16\x88|\xa1\xf3)\x9b\xe5I\xc0\x94\xa8\x96\x16|\xe6\x08f\x15E\xb2q\xb3=\x87\x08\x84\x13\x84\x10\xd7\x1b\xf0\x04\xa2Id\xd3j\x08\nY\xdfo\xecZ\xfe\xdd\xc9P\x07i\x9f\xe6>x5a\x81\x90\xa8;1k^\x16\x11\xce\xa2U\xd2\x0e\x058\xc5SyG\xfa\xa6*\x9c\xf8\x93<\x8cZ\x1c\xfa;\x9e\xe1\x8d\x1f\xc4\xc9\xdf\xeb\x10\x0b\x7f\xdd\x9a\x83\x9a\x89\x19=\x8dc\xff\xda\xf5\xa5\xdb\xa3R\xf4\xf0\x13\xec\xdf\xed\x04\xfbx\x82\xcd'7h}r\x03\xf4\xe1G\x93!\x0d\xe1~`\xd7 \xff\xba\xec\xd6ok%\x9b\xb2\x19Ge\xd1t\xc0o\x19\xfcw6\xfb\xd3\xa1\xde\xb2\x8f&\x9a\xfac9\xd4\x99\xf0\x06\xb6\xeccT\xd8\xc7\xcc\xb8\x8f\x99m\x1f\xf9ne\xb8[Ae\x89{\x10\x89\xb5\x0b\xc4\xda\x05\xb8vV\"&\xfa\xeb\x0fp\xf1\xd6\xbe\xe51N\x98Uun\xf6)\xfcrg\xb8\xf6\x82\x0dB\xb0\xc4\xfe\xd2\xee\xb1\xb0'L\x10\x15\xa2\x0d\xa7lV{\\>/\xc4\xdb\xf0\xfc\xdf\xcd\x8f\xf2\xb7\xe4A\x16.\xd82\x08\xd9\xe2\x13%/5\xcbp\xfbE\xf5*\x19\xe6o\xcb\xcf}\x8c\x82\x85\x8c(V\xd7\xbb\x89\x93\xab\x13\xfa\xfd\xcd\xbc\xa1\x7fK\x1e\xc4\xec\x9c]}\x11U\xca-\xe4f\x01F\xa6\xc1zm.'\xe5Mg\xa6\xb19\nxp\xfa\xc0\x9d\x9e\x07\xeb\xd9}\xef\xeb\x07R\xb3a\xae\x1e\x1bb\x0c\x80\x18\x94\xf3@\x8a\xdd\x07V%\x02i:\xa4\x05o8\x1d\"\x1b&\xd5\x07G\x9c%mq]\xf3\x9e\xd0\x9aw\xcar\x03\xa0\xb8`\x0b\x947Si\xe5K\xdf\xc1\x7f\xce\x8a\xcbS\xa2-:\xa9\xdf\xca\xab[0\"\xea\x81e\xc5P\x93\x95kFY\xaf\xcc\xc7|\"\x92PT\x1au\xd0\xd6\x14\xe6\xb6\xf8\xa4vC\xf8Zu!\xed'Q\x16\xcf\x19ty\x81ua\xd3\xfe\xf9*:\xf3WB\xe7\xd7=\x04\xe7\x9cB\xf5\xe5\xa9\xe7\xf3Wkz\x15\x9c\x87Q\xcc\x9e\xf9\x89\xfe.\xe0\xef\xd8\x97BfO\xb4J\xea~\xd1\xa21]\x06\xe1\"\xbaT@A?\xfb,\xd9\xc4\xc1\xda/\x19\x06\x06\x8d\x98\xd1\xa8N\xf8-y \x07\xff\x17\xe3\xc6\xaa\xbaF\xfe)\x18p\x11\x06\xf8\xe6{\x16\x11!\xc8\xf48}4\x0e\xe3g\xa1\x9eM\x8f\xfd\xf0\x9c\x8dkyo[TQq8^\xc7\xd1y\xec\xaf\xe9P\x84\x18\xfb\x8e\xef\x98\x0c-v\x16-\xae\xb58<\xce\xf3+\x0e\xf9I\x10\x85oR?ek\x16\xa6\x8eVu:\x98\xa9&\\\xe7i\x1cG\x97/\xc4\n\xe7_\x96?`\xea\x0d}\x8bN\xcf\xb7\xfd\xca\xc0\xe6\xebZ\xb1\xba5hD\xd4\x9f\x84\x8eEt\x9c\xe6\xcd\x0f\xb4\x8d\x0f\xeb6\xbe~\xd3\xff\xb0`s\x9b\xc3\x0b\xdej\n\n\x88\x81\x95\xdb0\x14\xbfu(\xe0\xbbc\x84\x82\xbc\xaa\x82\x02^\xd7\n\x04\xc5\xfae \xe0\xc0v\xeb\xaf\x0cf\x10/\xfc`\xc5\x16\x90F\xca\x16B!\x0c\xbb6\xc5\xd8\xc1\xc6\x8f\xfdur\x0b\xab\xd0H\x06T\x0d\xfd\xb5 >\xc5\x0di\xec\x0cW\x1c7\xba\x07\xce7\xabh\xfe\xa1t\xde\xec_\xe1\xf2Mp\x0d\xe4\x02\xbaQ\x0fB\x199x\x8a\x96\x0b\xfc>\x9e\x0egt\x01\x0b\x95\x8b^\xdd\x91\x08\x02#F\xe5\x9f\xd2g\xf5&4w\xbe\xa1\xe5\x00\xfe\xd4;Z\xdd\xba\xcat\xed\xcb\xda8X<\x00\xf6F&\x8b1\xf7\xd1N\xa98\xa3\xda\xe5b\xbfN\xdaW\xac\x9a4\xcb\x15J\x08\x0f\x0e\xe1q\xb1h \x870,i\xb3Vp\x08;\xa3\x12(\xf0\xb2\x9db\xd9\x05/\xdb-\x96-x\xd9^\xb1\xec#/{X,\xbb\xe6e\x8f\x8ae\xe7\xbc\xac4\xbe5\x1c\xc2ni,\xefyY\xa9\xdf3^V\xea\xf7\x12\x0ea\xaf\xd4\xc7\x15\x1c\xc2~\xa9\xbd7\xbc\xac4\xb7\xe7\xbc\xac\xd4\xc7S\xbe|%7\xc4W\xbc\xac\xf4\xedo\xbcl\xbfX\xf6\x01\x93\x15\x96*\x1eca\xa9\x97\x1f\xb1\xb04\x95\xb7ph\x80\xf8\xc1\x18\x9c\xd3\xd3\x81\xe1\x1ez\x88o|\xc3\x9bG\xf8\xe6\xcc\xf0\xe61\xbeI\x0do\x86\xd4Qhz5\xc4W\x1fM\xafF\xf8jiz\xb5\x83\xaf\xca\xd4\x1c\xff\x1b\xd1\xd0\xcbBh\xfe\xb7\xb3;\x86{\xa7\xa7\xce=\xc3\xd8\xa9\xaf\xd3Scg\xd4\xdb\x89\xe9\xdd>M\xed\xbdi\xa5F;\xd4\xeaK\xf3Kj\xf5uI\xc6P\xac\xfa\x8c_\xd6\xce\xb5\xd3\x03\xe7\x17\xfe\xbfk\x96\xe0\xb3\xf8\xe7\xf9\x1b\xfe\x0f\xd2\xbc\xce+\xfa\xff \xff?>\xd2S\x84\x8f\xf4\xffWX{\xb9\xc4\x8a\xe2\x9f\x17/\x9c\x99)\x90\xc6\xeb*\x92\xcc\xc5\xb5%\x0d4Y\x9e\x1c\xd6z\x93\xf5(X\xc6ho\xcf#B\xe8\xca\xa1h\xbd\xa3b[\xca\x02\x19\xab\xef\xef\xed\xed\xc8\x0f2\xf1\xc1\xae\xe1\x033\xc9\xde\xa1FvG\x8fw\x1f\xef?\x1c=\xde\xf3\xbcb\xf8\xdby\xb4`\xb0\x89\x82Bz\\\x8av\xb8\xf6\xafe\xda\x85\xf3\x98\xf9)\x8b)\xf3\xc2\xe0\xea\x85\xf83\xd1\x0d8\xd0wb\xa0\x8f\x8a;[\xf8%o\xbc\xd3SG\xc4p\xcc\x836\x0e\xf0\xfbm\xc5'{\xd0\xd5\x987S\xb0\x92\x9f\xaa\x9b\xa5\x85\xac\xc6\x9d\xc9crG2\"\xb6\x0c0\xfd\xa3\x9f^\xf4\xd7\xfe\x95\x8b\xf9\xc1E\xf1\xcd\x0d\x8c<\x19\xda\xfbC\xb09\x0e?\xfa\xab`Ami\xbf\xf58\xdc\xcbUt\xf9\x92}d+\xa4`\x83\xe4$\xe2kz\xee\xa6\xf9\x1bO\xfa\x1fie\xb2\x97\xf4z%\xe2m\x17\xaeU\x1bE]\xcd\xffkH\xdfU\xe0\xdcrw\xfe\xff\xfca\x919\x87\"\xfb \x19iP\xc6\xd5\xb8\xa40`J'C\xce\xff\xd1\x13\x8a\x88:\xa4\x8c\xe4\xf14\x10Z]q\x16\xd84C\x0f\xeeN\x87\xc8\x99,7]\x1d\x91A/\xff\xcc\xc0\xd5r\xd0\xc8\x94\xff\xb6\xd7\x03\x97\x12\xb8\x95B\x90\xf7eV!\xde\x0foOdt\x98\xf7u7\xcb\x1e\xf8\xd4\x99\x8f\nk\xfd\xd5\xd4\xe7\xe3\x0b\xa7\xd9\x0c\x0e\xcb\x91oA\x13p\x17\xe1\xd9\xd5@\x8c\x03\x0e\xb6\x98H\xf3H\x05;Q\x9c\xfe\xc0\xae)\xd5\x8c\xfaQ\x8c\xde\x1e\xb2\x7f\x06\x0b\x19=]\xfd\xba\xb9\x81G2\xf6y\x18\xfd\xc4\x96\xd4\x86x\xd4[\x08\xa3g\xd1z\xe3\xa7?\xf2\xe3Lu\xb4\x02\xbd\xe6<\xe2\xd0\x8d\xeeV\x97b)\xb5\x02\xbd\xe6\x1d\xe2\xc5\xcb\\Du\x9f<\xbf*\x86\x98\xc7\x9cWa\x1e\xa6\xbe\x98I\x9a\x97,2\xfe\x85\x9f2a\xa7@\xa5Y\xc2\x16\xdf\xeao\n\xc1\xfdL8\xe2\xc4x\x98\x10\xe8\xc5i\n\xe0\xb0\x14:\x96y\"w1)\xe6\xb6\x87\x04\xd7|l\x89f\xaa\xf4\x04\"8\x80\xe4\x89\x879\x1a\xd0j]\xa6\xe6\x17n|\x98\xf8?\xf2\xd0\xda\x87\xfcCD\n\x0b\xd1A\x82\xa9\xdd\nox\x97\x14\xc65Bc!z\x0eu!\xc4\xa9\xe0\x03C\x01\xd7\xddC\x08<>\xc4\xeea\xd9\x9dL\x80\xb0_\xbbD/\xebbo\x9bc\xebJty\x1f4\xce\xce\xd4\xf6\xb7U\x14-\x19\x0e\\\xb1\x15\x87>z\x9c\xd76\xf4okC;\xa3b`\xaa\xe1h\x1f\x99\xf7\xfda9\xf2\xd5\xe8\xf1\x1e\xff\xc5)\x94\xdcm\x82\x93$\xe2\xd7\xcd\x0d\xec=\xdc\xd9\xdd-~\xc7/\xe3\x1d\xfe\x8b\x92Q\xa8\xaa\xbc|\xbf\xd4\xf5p\xb8;\x1c\x0ek'\xf2\xc2:\x11\x9cb\xa9\x1fl\x99?\xbe\xcf\x1f\x9f\xe6\x8f\xaf\xf2\xc7\x0f\xf9\xe3\x8f\xf9\xe3e\xfe\xb8\xa8\x1d\xd6;\xeb\xb0\x1e\xfcz\x1a\xde\x07\x19\xc8D\xdfn\xf9\xc4\x0f\xd27\xd5X#\xbfs2\xa7X\xf4\x0b\xe7U\x8aE\xff\xe4\xb4M\xb1\xe8g\xc0\x88\xd2\xd5A\xfeP\x1fg\x9d\x8f#\xd2\xed\x9b:\x86\xe8'sK\xf9\nO:\x85\xfa\xa8\xbe}Kx\xa0R\xce)\xd5\x7f\x8b\xec\xa3\x85\x04%\xa5\x9d\xc4x<\x9do]\xba\x8c|,;\xcb\x1f\xdf\xe4\x8f\x97\xf9\xe3\xfb\xfc\xf1i\xfe\xf8*\x7f\xfc\x90?\xfe\x98?.\xf2\xc7\xeb\xfcq\x9d?n\xf2\xc7\xe3\xfc\xf1*\x7f<\xcf\x1f/\xf2\xc7\x8f\xf9\xe3\xf3\xfc\xf1713{V\x17C\x82\x07\x839\x8a\x97\xbf\xed\x10\x0bb\xf2\x06\x0e[\xff\x13a\x05c\xdd\xef\xd7\x9a\xcdS\xff\xe3m'@\x91\xdd\x9a'\x02\xe2\xe6\x8a\xa7\xa3\x861\x83\xca\xffB\xb3\x9c\xa3\xfa'\xe2'=\x81.\xe7\xf50\x9b=_\x07Q\x01&\xfcqL\xc9\xeb\xa0\x0b\xffp\xe7\xc4L\xa2\xd2\xa2\xb63{\x98K\xc8A1\xb2V\xfa\x83\x83g\xe65A\xfb\xcf\x8d\xd0~\x0f3\x934+\xf7\xe4\x9fb\xa4s\xaa\\p\xcaV\x1aI\xc8LK\x84\xd0\x111h\xfb\x80\x0e;\x9c]\xdb\xdf\x19\"\x11P\x8dO\x1a!WL\xdf\xec\xef\x8c\x06\x90\x07+\xdd\xd9\xdd\xe1\xcc6\n\xa6^\xbb\xc3\xc1\x08\xbd\x96\x19lS\xeb\x949f[|\xd6%\x1e\x8e/\x1b\xa7\xdd\xc6$\xf3z+\xcce\xbb\x87\xd0AJ\xe6\xdf\xfc\xe2\x99@:\x8df0\xa6[\xee\xb5\xd9\x1bM\xff\x93\xba\xd4\xba=\xf3(}\xa8\xb9!\x11\xfc\xc1\xbee\x05\x99n\xb0\xdeDI\x12\x9c\xad\x84\xb7\xfb\x18\x02!\xaa$\x0b\x10\x8a=\xe64\x11v\x7f\xb8\xf5\xfc\xfc\xd7\xf64Rp(\xe95)\x00\xc4\x90k\x06-@\\D&\x85XRF\xf9E\xc8\xcf\x1b%\xd46\x7f7\"|\xa4\xde\xf1Q8]\x07\xb7K\x1e\xcam\xbalNC\xa7v\x86\xdf[\x19a\xdb\x909l\xe4(u{\x88\xb9/\xa9\xf4\x85a,\x8a\xf8\x99\xb2\xf1/E6\xfe{G\x98\xa2_\xd0\xfe1\xf8\xf39\xdb\xa4 \xaa\xde\xf0\x06^QN0\\\x81{M7MqZ\xd3\xd5\x8cff\xbfy\xecW\x8ad\x87cc\x95\xda\x90\xd3\x06\x83,#\x9b\xdf\xa9\x97\x8f\xfeOA\xc6G\x87\xbe\xcc\xb3\x17\xf4\x07r\xc8a\x8f\x8er\xd8\x83\xce\x10C\xdf\xa8\x9f\x03Cj\xe0\x04\x14\x94P\x13\xe5$\xad\n\xf9\xe9,\xed\x01E\x85+r\xb9\xe5\x14\xa6\xbc\xf9y\x0fV=\xb4\xff\xa8\xbaIq\x00Ea\x87z\x85\xbe=\xf2MU\\\x86\x02;W\x93P\n\x8dX\xae$Q\xbbM\"@-al~\x13\x18\xda\xd1\x8a\x1aZ\xd4?.\xa0:\xa5\xee\\g Z\x12\xf8pF\xa9n([y\x9d\x05\"\x14D\xacDB,\n\xfa\xb6\xec \xf1`C\x0fE\xf6\x9c\xd5\x10\x1b\xceW&\xe2@\xedb\x1c$\xa1\xd6\x12\x91%\xc2)'p\x16\xd3h6\xeb \x1cCf\x80>\xe5`\xa7\xff\x08\xee\xf1t\xb58A\x02\xf8\xf1l\xf0\xa7\xdc\x9b\x823\x1e2\xeb\xbb\xac\xb3\x14[\x875\x8b\xc9\xcc'\"r\xd3\x84\x13\xaa\xe2\x11\x1c\xe5\xf1MS-\x1d{?\xf1\x97\xec\xdb\x92\xb5B\x8d\xe5\x1eM1\xee\xb3\xab\x94\x85\x0b\xb7z\x8e\xc8Fs\x0cYq\xb7\xf0\xc6/\x8d\xeeN>?\x02\x90\xc85V\xba\xd6\xf0\x83\xed\xbc\x7f\xcf\x92\x1f\xa3E\xb6\xaa\xc6.\xfd\xe8\xaf\xb2\xa2w\x1f:\x8a\xf5\xcfY\xfa,\n\x97\xc1\xf97\xd7\xefb\x0c\x86\xdb_D\x97\xe1*\xf2\x17T\x0e\x87\"\x1eB>\x80\xdc\xe9h4\x18j;h\xf8\xd4\xae\xf1*\xdb\x16\x18\x15\xbd\xa2\x92;\xe0C]\x86\xfd%K\xe7\x17^\xc5E+\x9f\x93qJmvU\xd51\x92-\xca\x97\xb8\x9fl\xd8\xfc)\xd6L\xccH2\xf7\xe7\x0dJ\xcb\xe1\xa6^?\xbd`\xe8\x07\x17\xe9\xe9F\xe5\x9f:E\x91y\x14\x80\x9aSM\xbe\x8c\xce\x88\xa8.\xed'\xa9\x9ff \x1c\x1d\xc2\xee\x00\xd3[\x04\xfdl\xb3\xf0S\xf62\xf2\x17Ax\xfe\x06\xdf\xbb\xce\x12\x1d\x17i@\x9c\xb3\xb8e\xb5w\xf1\xcaux\xc1<\n\x93h\xc5\xfa\xa8\x14se\xffo\xd9U\xaa\x91'Y\xbc\xe2@\x86\x17\x07R\x89\xcc\xe5[)\xdcQ\x7f\xf1\xd7+\xea\xc1s\xc3~\xca\xae\xca!\xb4\xa1\xaaF\xfb[\x9d\x1f\x1d\xf2\xcfY\xda\x12\xd2R^\xf78t\xcbw\x15L\x80\xc1\x18\xa6l\xf6\xf7\xc2\x12\xa5s\xaf\x08w~\xfa\xf7\x0c^\x84H\x91\xcb\x1b<\xef\x0b&\x10\x83)9\x93\xd4\xc7\x96\x83\x17\x16[F5\x9a;\xdc\x7fT\xea1\x11#\xd9-\xe2!j\x93\x02I\x92\x0b\x06\x07\xbcL\xbe\xf0\xdc\xa0\x07I\xff\xdd\xebo\x9f\xbe}\xfe\xfe\xd9\xab\x93\x17\xc7\xdf\xbd\xe9\xb5\xdc>\x0c\x0e\x8d\x80\xeccp\xd1\x7f\xbc\xf1\\\xd6\xdf\xf8\xd7\xfc\xa8\xeb(\xde3\xf7\xfa\xf6\xd5w\xdf\xbdl\xdb\xab\xbc9U\x07f\xb5/\x02UEt\xa2\x86\x9c\xf0\x97=\xe8\xc4\xc5\xd1\x05\xc2\xf3t\xe6}\xc5\xf7\xf9\xc1\x83\xff\x03\x14J\xe2G\n\xdb\xf4\xee\xa7\x97\x87\xc9\xa5\x7f~\xce\xe2\xed,\xd8\xe6xg\xe1\xaf\xa2\x90m\xa3N$\xed\xff\x96\xf4\xd7\xfe\xe6\xff\x07\x00\x00\xff\xffPK\x07\x08v\xf2\x8aA\x86\xba\x01\x00\xc5\x87\x08\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00 \x00swagger-ui.cssUT\x05\x00\x01\x80Cm8\xec\xfd{s\xdb8\xb27\x8e\xff\xff\xbc\n=\xbb\x95\x9a\x99\x1dS!EQ\x17\xabf\xeb\xc8\xb1\x93q6r\xc6\xcem\x92\xad\xad)\x8a\x84$\xda\xe0\xe5\x90\xd4\xcdz\xf6\xbd\xff\x8aw\\\x1a $;s\xf6\xf7\xad\xb3\xd9dl\xe2\xd3\x8dFw\x03h4\x00\xb2\x9bl\xed\xe5\x12\xc5\xda\xda;\xfc\x9fN\xe7\xe5\xdf\xfeo'\x08c\xdf\xc6\xde#\xea:I\xd2\xd9\x0c\xbbzW\xef\xfc\xbf\xce\xec\xfac\xe7\x9d\xe7\xa0 A\x9d\xff\xd7Yz\xe9j=\xef:\xa1\xff2@N\x88\xed\xe4%M\xf7\xb7\x97\x8b0H\xb5\x85\xed{x\x7f\x9e\xd8A\xa2%(\xf6\x16\x13'\xc4a|\xfeWs\xde7,\xe3\xdfD\xfd\x9dU\xea\xe3\x03\xf6\x02\xa4\xad\x90\xb7\\\xa5\xe7F\xd7\xb0&\x9a\x9fh)\xda\xa5Z\xe2=\"\xcdv\xef\xd7Izn\xe8\xfa\x8b\x89\xb6E\xf3\x07/\x85K)\xce\xf3\xd0\xdd\x1f|;^z\xc1\xb9N\x95\xd8q\xea9\x18\x9dQ\xcf\x12\xcf\xa5\x9f,\xc20E1\xf5h\x85l\x97y\x14\xd8\x1b\xea\xf7\x049\xa9\x17\x06\x07\xd7K\"l\xef\xcf\xe78t\x1e\xe8\x16\x1b\x87\\K\x99\xf0\xe7=\xe4OJ\x19\xbb\x83!\xf2;\xb4\xa4\x0bo\xe9\xd8Q\xc6\xf0\x8cy\xbc\x8eii}\xdb\x93UZPT\xea0\x90\xdf\xe9\xeb\xd1\x8e\x96+>T\xca\x9d\x87\xbbL\xe4\xdd2\x1f:\x16a\xec\xf3\xca\xfbg\xba\x8f\xd0/1JP\xfa\xaf3\xbe Y\xcf}\x8f)\x01*\xcbf\xb5\x92\xa2(\xfdW=\xb6\xdaQ\x84\xec\xd8\x0e\x1ct^\x14\x01\xd5\x974\xe7\xe7\x9a\x1f>j\x8b\xd0Y'\x9a\x17\x04\xcc\xd4C\x8a\xaa\x04-\x85o\xc1\x16\x95\xf3 \xde\xeb&\x91\xed\xba\xd9l\xa0K\xda\xd0\xb0\x89\xbd`)n@+\xae\x92^\x02,E\xa7\x11\x87p\x9df\xbevnD\xbbr\xec\xed\\\xe4\xc0\x8fh\x972\xb3$\xc2n\x82\xd2C\xd5\xb0\xaei!\xbf\xd3\x1d\xe6\xff\x0e\xb8a\x01\xa3%\n\\h\xda\xac\xe7\x14j\xd6$\x9e\x16\x83a5\xacW\xdd>\xb5\xe7\x18M|{\xa7m=7]\x15\x1d\xa5\xd6\xf2d\xbb\xf2R\xa4\xe5\x83\xf4y\x11y1Sl\xb8\x8cQ\x92\x80\x83\x8f\xd2(Xw\xe1\xbaw\xd9\xeb4\x04\xac\xeb\xac\x90\xf30\x0fwP\x1f\x89m\xd7\x0b\xffu\x92Vd\x0e\x15\xac\xfd9\x8a3\xef-\x19\xe7^\xa9%\x91\x17h@\x17\x14\x10\x85\xeb\x94&:\x94C\x90\xa0\xa1 \xb2cg\x05v\xdfLY\xb9\xc7LJ\x0f\xd3\xc2\xc5\"A\xe9\xb9\xd6cB+\x8aU#K\xf1@s2nX\xdc\x06\x11]\x13\\@\xd2q#[C\xbf\xf00\xd2\xd6\x11\x0em\xb7R\x82pt\xcaG\xed\xcaO\xe9X\x00\xa5\xb6\x87\x13:\nE\xc1Z\x12\x85&k\xdf\xb7\xe3}\x8d\xc0^\x92j^\xca\xf4*\xc7\x0e66\xec\xc4\xb4V\x8b \xed_\xcc$\xe4G\xd8N\x115\x93Rd]\x17\xcd\xd7\xcb\xce\xdf\xa8q! \xb1\xe7v\x96!v\x01\xac\x96\xf7;\x90\xe2\xaf\x8b\xc5\x02\xa2\x98c\xdby\x80)\xd8\xf8\xa7\xa4X\xc6\x9eK\x04Ndx\xdbY\xc7\xf8G\xd7N\xeds\xcf\xb7\x97\xe8e\x14,'Y\xf7\x1d\xf4\xcf\xbc\xcf\x17\xef\xef\xb6\xfa?\xde,\xc3\xe9t:\xbd\xf9\xf0iu\xf5i\x99\xfd\x98\xffs\xfdj\xfau:\x9d^^]\x0e\x07\xef\xb2\x07o~\xbf{\xfd\xe5\xd7\xbb\x8f\xf3\xde7\xdd\xed\xbd\xde\x7f\xbb\xbd\xb8\xf8\xf6f\xec}\xfbp\xf1v\xfe\xe5u\xf0\xed\xf3[\xfc\xf5\xcb\x9d\xe58\x18\xff\x96\x11\xecW\xd1\xe7\xd7+\xfd\xcb\x951{\xef\xdfl\xe6\x1f\xacU\x81\xb7\xfa\xf3\xdf\xa7\xc5\xff.\xb7/\xd1\xaf\x17\xab\xaf\xbd\x14\xbb\xaf.\xbco_\xdch~\xaf{\xc3\xe1\xfa\xe5\xb5w\x11}\xbb\xd4\xbd\xcf\x8f\x9fofW\xc6\xf6\xb6\xf79\xb4?\xad\x06\x8e\xff\xf9#z\xb0>}5\xa3\xf8\xeb#~\xb8\xbe\x1f\xfd|}\xb9\xeb\xbf\x0fV\xa9\xf3\xc6\xc0\xee\x9b\xab%zc$\xf3`6@\x97\xba\xf7\xf5\xcb\xdd\xe6\xab\xffi\x90\xfd>\xff\xf2Y\xff\xfaa\xe4]\xff\xba\x1c\xa07\xc6\xd6}\x93\x8c\xaf\x1f^?\xcc{o\xf1\xf5\xeb\xd5\xcd\xa7W\x17\x97s\xf3-\xbe\xbe\xfc\xb4\xbe\xf1\x8c\xfb\xd9\xc7\xab\xdd\xf5\xa5c\xbd\xbb\xbf2\xde_\xce\xf67\x1f\xb6\xcb\xd9\xfdtw\xf3a\xb4}\xffa\xb4\x9b\xbd\xd2\xb7\xb3\x8f\xe1nv\x19\xeeg\xaf\xa6\xcb\xeb\xea\xef}\x7f\xf9\xdb\xafo\x1f\xbe\xddG\x1f\xee\xae\xbe\xd6\xf28\xfe\x9d\xff\xdb\x87\xb7\xa1\xfb\xeb\xdd\xf6\xbd7\xda\xb8\xa6k\xbe\x0b\x9c\xc7w\xfex\xffm?\xda\xbd\xff\xf8`\xbd{\x9c\xee\xdf=^\xef\xdf\xfd\xfe\xf6\xe1\x9bg<\xa2/\x96\xfe\xf5\xf7e:\x0ff\xf7\x04\xdf\xabo\xbf\xdf\xdc;>\xde\xbao\xf0f\xee]\xec\xbf\xbd\xf9:\xf8\xfa\xe5\xed\xc6\xfd\xfdv|\xed]7:xcl?~\xd2\xc7\xd7\xfeJw\x7f\x9d\x0e\xde\xed\xc7kg_\xdb\xe2~\xde\xd37\xe8\xcd\xeb\xed\xbb\xc7\xab\xf5\xec\xd58\x9d\xe7\xfaY\xa5\xf37\xd6\xe3\xfb\xe0F\xff\xe4\x7f\xa6d\x9e\x07\xb3u\xa9\xd3\xf5\xd7\xde8}g\xaeV\xce\xab\xd1\xee\xdd\xfdt\xe3\x18w\x96\xf3\xe6\xd3\xe6\x93\xff\xf9qn~\xde\x7f\xed}\xfe\xf0\xed\xcb\xd7\xfbk\xef\xa2?\xff\xb2[;\x8fQf{EY\n9\x9c+\xe3\xe6\xfd\xc3\xdd\xe6\xab\xf99\xfd\xf6\xc5\xd2?|\xba\x1d_g\xb6~e=\xd8_n\x07\xb3\x8fw\x97\xef?~\xed\xdf\xe8\x9fz7\xfa\xe7\xd7\xb3\x8f\xaf_\xdf\xdc/{\xb3\xc7o\x97\xb7\xf7\x0f\xdb\x9b\x87\xdb\xfe\xec~\xb9\x9d]]\x13\xfc\xf0\xda1\xefVs\xff\x06\x13\xfc\"\x9a\xdf\xad\x1a\xbf\xcb\xe8\xd2\xf1?\xaf\xdc7\xe3\xfd\xe77\xe3\xcd\xfcR\xf7n\x0b\xfd,?\xbdYm\xdc7\xe3G\xfb\xcdx{}usy}y\xbd\x9d}\xfc\xb4\xfc\xc7\x95\xb1\xfa\xda\xc3\xeb\xbc\xec\xd5\x83\xf7\x9b7\x1d\x95v\x1a\xdc\xbd\xf9\xbc\xb7\x7f\xff\x86\xbf]}\xdb\xcf{\xfa\xd21\xef2\x1d\x0e\xec/\xd6\xa3\xfb\xe6\xf5\xfak\xef\xf3\xdb\xbbK\xdd\xcb\xf0\xef|\x1c}\xbb\x0c\xcd\x9b{g\x7f\xfbpk\xde\xdc\x7f5o\x1f?\xedf\x9f>\xf5n\xef\xdf\xbe\xba\xd5?\xedo.\xa7\xfd\xd9\xc7\xe9vv\x7fe\xce>\\\xd7\xfc\xbe\xbd\x19\xdf\xbb_\x0c<\x0f\xee\x08~w4\xbf\xc7V~\x9bL\xf6w&\xe0\x93\x99\xaf\xbe\x1a\xe7~\xf9\xe9\xe1\xeeM\x81+\xfa]\xde\x0f?\xf6\x97\xbf]\x8e\xfb\xce\x9b\xd7\xf7v\xef\xb3~\xfd\xe6\xf3:\xeb\xef\x8ew\xfd\xf2\xb7\xe4\xe2\xc3\xcfof\xd9\x08q\xff\xe1\xd3\xdd\xc5\xe7_\xef\xed\xaf\x9b\xc7\x97/\x1fG\x97\xef\x92\xcb\xfe\xd2y\xf3\xbb\xf7\xf5j\xfa\xe6\xe2\xfa\x1fo.\x02\xf4\xf2\xe5\xe2u\xb4\x9d.\xb7\xd3\x8b\xf1hj\xbf\xeeE\xf7\xf8\xd3mF~\xf1\xf6\xee\x93u\x15?\xbc].\x97\xbf\xfc\xf2S'F\x11\xb2\xd3\x8e\xde\x11\x8e\xa4\x9a1x\xc6\xc1\xf4\"\x1f\xe6n\x8b\xc1t\xba\x18\xbd\x1c\xaf\xfew0\xfd\xdf\xc1\xf4?u0}\x7f\xf9u\x7fw\xbf\xba\xba\xbb\xcc\x06\xd3\xaf\xfb\xd6\xc1\xafe0m\xf8\xdd\xaa\xf1\xfb\x0f\x1aLo?\xb6\x0e~G\x0d\xa6\xb7\xed\x83\xf3\xf7\x19L7\xaf>\xe8\xc6u6\x18\xcd\xea\xc1\xd4\xbf\xeb\xbf\xb4~\xbex\xfd\xdb\xc5b:{\xed\xbf\x9c],w\xa3\xbb\xe9\x9b/\xaf\x02c:\xf5?,\xcd\xfe\xed\xe0\xe1\xe2\xf2\x1f\xb37\xb3\xcbW\xdb\xebWhv\x8d\xfc\xd7/\xad[{{\xe5E\xd3/\xdbO\xab\xed\xd5\xfd\xecr3\x9f~\xc1_\x1e6\x9f/\xb6\xeb\xd1\xe6\xf6zz1\xbd\xda^\xbc\x8aV\xa3O\x03G\xcf\xc7\xa5+\xfc\xfa\xe3\xc3\x87\xf5\xad\xff\xea\x95\xd2\x00<\xd2\xf2x\x97\x1c\x85\xb3`\x99\x1d~\xef#T\x8f\xbf/\xc7\xf7/\xfb\xb7\xd3\xafw\xbf\xaf\xa2o\xcb\xe9\xf4\xc3\xa7\x87\xff.\x03\xd9\xe6\x7f\xbf\xbdL\xa6\x17\xaf\xaf\xdc/71\xba\xcdF\xe6\xdbj\xe0|\xd9\xbf\x9d\xed\xec_\xeft\xe72\xdc\xbc\xebY\x8f\xef\xfcb\x1c{\x97\x8f\xb5\xe3\xfe\xd7\xdf\xa7\x9b\xd9\x87\xfe\xf6\xddv:\xfa\xcd\\m\xbf~\xb9\x89\xbf\xfd~\xbb\xfc\xea\x7f\x0e\xec/\xfd\xf1\xf5\xfa\xe7\xe1f\x7f\xbd\xb4\xbf\xdc\x8e\xaf\xb1c|\xfcxq\xe3\\\xdd`\xfb\x0d\xbeF\xc1[\xfc\xc9\x8c\xde\x7f~s3\xb0{3\xeb\xdb\xab\xeb\x97\xb9\x8f^f\xfd\xf7\"\xfd\xf6\xfb\xdd\xaa\x19#\x96\xe3\xeb\xb2\xee\xf7\xbe\xf5\xf8\xde\xcf\xc7\xe0M\xd6\xe7\xf31\xf9\xd7\xbb\xf8\xb7\x0fo\xab\xb9\xe2\xeb\xc7\xcf\xd3\xe5mo\xbc\xff\xf6aj\xbc\xbb\xff\x9a~}\xbc\xda\xcd>L\xcd\xf7\x1f\xfa\xbb\x9b\x8f\xcb\xc7\xd9\xfd\xa7\xa4\xec'\x9b\xd9\xe5\xc3f\xf6q\x9a\xce.\xaf\x06\xb3\x8f\xd3\xc1\xec\x9e\x18c_]g\xe3~\xed_\x8d<\x99/\xea^\xad\x1b\xd35\xdd\xbde\xce\xf6\xd6\xc6\xf1\x9d\xcd\xec\xe3\x83\xf5\xfe\xc3h;\xf3F\xfb\x99gd\xf4\xa9cf}\xf1u\xff\xdd\x17\xeb\xf1z\xdf\xf0\xbd{\xf3\xf9\xf1\xab\xf96r~\xbd\x8b\xe6\xbd\xfe2\x1b\xbf\xdf\xfb\xaf\xbd\xb9\xf9Y\xff\xed\xc351Nf\xe3\x00Q\xa7\xcc\x1e\xfb\xff\xc0\xb1\xf9\xf7\xe9\xe0\xd6|\x8b\xbf\xfe~\xb7q\xf0\xddf\xde\xdb\x12\xf3\xe2E87\xef6No\xb5q^]\\\xde\xee\xa7\xfb\xd9\xe5\x95q\xfdju\xf3\xf5\xcbM4\x0f\xb2\xb2eT\xf0\xb9\xb8\xf9\xf81z;\x0fn\xf4\xaf_\xac\xfbo\x9f\xf0\xd5o\x1f\xdef\xfc\xd7\xf6\x17\xfc\xf0\xfe\xe1z7\xbb\xbf\xd6\xdf\x7ft\x1eo\xee\xddW\xb3\xc7\xab\xdd\xdd\xc7o\xaff\x0fo/\xef>^\xeb\xb3\xcb\xe5nv9\xdd\xcf>:;\x82\xdf\xd5\xbcwc\xcc\xbf|^\xbbW\x0d\xbfoo(~z+\xbf|\xee\xac\xe7\x13\xec\xf8\xb8\xf7\xed\xcb\xdd\x1b\xc7\x1f\xa7\xd7\xbf\x16\xba|\xef\x8b\xe7\x85\xdb\xfb\xab\xfd\xec\xfe\xd6\xbay\xbc\xea\xdd\xe8\xd7\x8f\xf9\xbc\xf0p\xbd\xbf}\xb8y=\xbb\xbf\xdd\xbe\xbf\xbc\xda\xce.\xafw7\x8fW^\xc3O\xde\xfa7\x97\xa3\xf0\x1f\x97\xe3_\x7f{\xfc\xf4\xb2\x8d\xa6\xfd\xef\xe2\xe5v:\xbd{5\x9d^O\xa7\xcb\xcb\xe9\x87\xeb\xe9tuu1\xdd]]\xbc\x1c\xddN\xbfd\xe3\xe6\xed\x14\xf8\xdf\xd7\x8b\xe9\xed\x15\xf0\xfc\xfa\xeajzu1\x9d\xce.\x98\x82\x8b\xe9\xe5\xd5\xab\xa9~u7\x9d^]^\xf0<\xef\xae?\xbe\xbe\xf8\xf4\xe5\xea\xc3\xf5\xe6\xa5=\x9dn/\xa7\xb7\xd3WW\xb7\xb3\xbb\xe9\xe5h\x1a\xbe\x0f>~6n?^\x0e\xdf\xbeMV\xbf\x99\x9b\x0f3\xf3\xb7\x97/\xbf)\xcd/\xc6@m\x829*\xbe\xcf\xe6\xd7W\xb7\x0f_\x96\xbd\xe9\xff\xc6\xf7\xff\x7f\x1d\xdf\xab\xce\x01t\x1c\x9e\x8d\xad\x8asV\xcfH\xc9y\xab\x8c!U\xe7\xad\xc7\xcf\xbf\xe2\xed\xb7\x0f\xe3\x0f\xdf~\xbf\xd9\xb8\xbf\xbf\xbd\xcf|\xe9\x9b7{\xb6\xf8Y%\xae\xbfy\xfcj\xce\x1e\xde^\x15I\x97\x99!\x1f\xbf\xdb\xd7\x1d\x0d\xbf\xaf\xad\xfc\x9e-\xbeoOn\x1c\x15\xdf\xdf]\xb6\xf2\xfbN\xf1=\x1a\xbc5\x1f\xb2\x11\xe2\x91M\x96\xe8\x9f.\x93\xd9vv\xff\xe1.\xfc\xfa\x9b\xf5\xe6\xbf\xfb\x1f~\xbb\x99\xdf\xdd\x7f\x9e]\xdd\x1a\x8bWw\x97\xcb\x9f\xbd\xe0\xe5\xe0\xe7\xb7\xc6\xf4\xed\xa7]\xb2\x9c^\xbd\x99NM\xe3b\xfav\xf6A\x7f\xf3\xb5\x18\xcf?|\xfa\xfc\xfe\xee\x1f\xd6\xab\xaf\xd7\xd7\x92\x04J\xb3\x15C\x1f\x8e\xa1\x7f\x03\x8e\xcf\xccCwO=\xe0N\"\xb8\xf4A\x04\xd7\xa3\xcf\xcd\xb8\x98\xfe\x95\xdeZ\xae6\xe6\xe8\x87\xfc\x01\x9dE\x18\xfb\xf4F\xacA\xff\xda\xa3\x7f5\xe9_\xfb\xf4\xaf\x16\xfd\xeb\x80\xfe\x95?\x0b\xb4J}\xba\x15\xf9Nu\xb1\x89\x83|\xdb\xc3\xff\x12\x95\x96\xdbT\xa2\xe2\xc8N\x92m\x18\xbbB@\x8a\xc4\xbcS\xb4K\x85\x85\xeb\x98!,\xb64\xe9G\x1e\xbd\xc7c{\xf4.UH7\x9a>'\x101\xe7\x94\xca\xf3Q\xd4\xb3|\xd7\x93~BKPmK\xd2\x0fW\xf4\xaf\xb4-\xd6\xf8\x94\x0dH\xba7\xd8I\x84\x9cT\xcb\xf7\xd8\x0e\xe2\xf3%b\"M3\x06\xbbq\xb5\x9b\\\x9d0\xb2\x06\xdd\x9e\xf5BF5\xde\x19\x03\x96\xca\x18\x0e\xbb\xc3\xa1\x94\xac\xbf3Y\xaa\xa1\xbc\"s\xd7\xe7\xea1\xcd\xaeiJ\xa9\x06<\xd5`\xd0\x1d\xb4\xc8\xc6\xb7\xc8\xd2\xa5$\xa3\x9d\xc5U\xd3\xeb\xca\x1bd\xedF\\5\x03y5C\xbe\x9a\xa1\xd1\xed\xf7Z\xea\x19r\xf5\xf4\xe5\xf5\x18;\x83#a\xcf,2$\xc5\xc9\xb5C\xedq\xf6< \xf1:E\x934\x8c\xce\xf5I\\zd\xc9M\x9f`\xb4\xc8~'\xce\x0eT\xe7k\xb2\x9f\x1f5/p\xd1.\xfb\xe5\xdf\xff\xe5#\xd7\xb3;\x89\x13#\x14t\xec\xc0\xed\xfc\xe8{Ay\xea\xc0\xd4\x91\xff\xd3A,W\x90<\xa17d\xd4'u\x08\x80P\xadO\x00\x84\xed\xdd\x02\xaaM\xa9g\x00\x84*\x9d\x03\xaa\xaf\xbd\x7f@\x95)t\x11\xa8\xb2\xf6^\x02\xe9Q\xa5\xa3@\xb5\xb5\xf7\x15\x88J\xa9\xbb\xe4\x84\xcf\xdfc\x14\xbaL\xf9\xb0>\xbd3h\xe9G\xfeS\xba\x91\x7fb/\xe2\xe8\x14;\x11G\xa7\xd0\x87\xf8\xba\xd4\xba\x10G\xa7\xd4\x83\xf8\xda\x14:\x10_\x95J\xff\xe1\xabR\xe8>\xbc\x06\x95z\x0f_\x97B\xe7\xe1\x89\xd4\xfa\x8e\xff\xe7w\x9d\xb6^\x82\x9f\xd2K\xf0\x89\xbd\x84\xa3S\xec%\x1c\x9dB/\xe1\xebR\xeb%\x1c\x9dR/\xe1kS\xe8%|U*\xbd\x84\xafJ\xa1\x97\xf0\x1aT\xea%|]\n\xbd\x84'R\xeb%\xf8\xbb\xf4\x12\xb2^\xcf_\x1e\xe8c\xa0\xb4XN\xb8A1y\xce>?W\x9d?\xfd\xbf\x9e\x1f\x85qj\x07)K\x12\xa4\xb6\x17\x00D\xf9s\x82\xac}\xa6;\xf0\xc2d\xd3\xee)\xf2\xc0t\xacH\n2)\xcc\xbe\x85\xa0\xfeirBd\xc7\x89)\x94\x08\x9f&\x11D\xc6IDQ\xce\x97\x9a\x83\x82\x94v\x9d\"\x19t\x1e\x84\xe5O\x13\xa2\xac\xf6sn\x90\x98/\xb54\x8c\x8e\xe6\x93\x86\x11\xc7'\xef4Gs\xe2;\xc5\xbc\xea\xc7G\xf3*\xc88nY\xe7=\x9a\xd7\xf1\x8b\xab\xda*L_P\xaaN`\x98SX ms\n3\x89yNa'\xb1\xd0)\xec\xda\x82\x12\xd5\x11\xa51\xdd\xf1N'\xb2\xdc\xf1\x9c\xc4\x86;\x9e\x97\xccn\xc7s\x93\x99\xedxnmV\x93\x1a\x08\x1f]\x9d\xc8@\xc7s\x12\x1b\xe8x^2\x03\x1d\xcfMf\xa0\xe3\xb91QL\xb7<\xfe\xce\x1f\x83\x07a\x1aqL\x1389O\x94\xc2\xe4zMt\xfc\x18\\\xf1\x08\x92\x13\x84\x05\xa9\x14\xe4%\xe9\xda|[uD\xaa\x98\xfb\xa7\xb4\x03 Ri\x86\xaf\xdc\n\x89\xc0\xf8\x14\x81\x01\"\x15\x811)0\xed\xfb6}\xcf-g9)\x1f\x95\xd18s\xbb\xa7;O+\x9alt\x00\xe8\xb2\xc7\"\xda\xfa^]1\x1e\x00\xd4E\x81\x88~N\xdf_\x86\x18\x94%\"\x0e\xb8\xe2\x90wz\x80>\x7f.\xa2\x0e\x80{\x81\x94\xba\x8e\xef\x8bs;\x9f\xd2\x8f7\x03Av\x8a%\x08\xf2S\x8dA\xb08\xdd\x1e\x04\x93\xd3L\xc2\xa9\x0f\xb2\x8a\x82Y\x14\x86\x9b\xb9\x9d\xcd\xe3'\x98\xca\x7f\x92\xa5\xfc'\x1b\xca\x7f\x06;\xf9O4\x93\xffT+\xc1\x06\xc1'\x19\x04?\xc9 \xf8\xc9\x06\xc1\xcf`\x90'\x0ee\xac\xe6@\x83\xd04Zq\xd5\xaf\xa2\x13\xbc\xe3 \xc3\x05\xc8\x8eA\xb0a\x18\x1c\xd8\xb5\xe3\x07m\x19\xdb{\x06k\x9a&\x87\xf5=\x17\x82Z\x96\xc5A\x01\xd8p8\xe4`\x89\x877\xcd\x85\xef\x128\x1e\x8f9 .\x8c\x0d\xc1m\xdb\xe6%\x0d\xc3\x00\x92\xc1q\x1c\x01k\x00\x8c\x10\x82u\x9b\xdf\xd2d\xc0\x8b~\xf6\x87\xc3\x83P\xf6&g\x85\xd3\xc6:\x0d]%\xd8\xfeQ?\xd3_\x9ce\xb1\xf8Yw\xfc\x93\x80p\xd4B8\x12\x11\x0e[\x08\x87\"\xc2A\x0b\xe1@Dh\xb5\x10Z\"\xc2~\x0ba_Dh\xb6\x10\x9a\"\xc2^\x0baODh\xb4\x10\x1a\"B\xdd\x92\x13\xeaB\xed\xe8\xbd6\xd2\x9e\x98\xd6h%6 \xea|\x8c\xe1\x9c6^\xces\xda3\x1dt\xd8\x82\x88uX\x92\x08p\xd6\x82\x88uV\x92\x08p\xd4\x82\x88uT\x92\x08p\xd2\x82\x88uR\x92H\xa8\x08\xd6AI\"\xc09\x0b\"\xd69I\"\xc01\x0b\"\xd61I\"\xc0)\x0b\"\xd6)I\"\xc0!\x0b\"\xd6!I\"\xc8\x19K*\xd6\x9f(2\xb1+\xf1\x8eH\x11\x82N\x98O`1r\xd9\xc1{\xa8\xf7u~\x9c\xe5\x81\x8bE\xdf0\x07\x82Y\x01\x82\x0f{\x16?\x89\x84\xb1\x1d,\xf9\x81~`\x02\xf3\xf32\xc4<\xd7\xf9\x10@\xee\x11\xc6\xe1\x96\xc6\xf2\xaf\x0e\xa8\xa5\x85\xe0\x7f]\xcc\x17\x86\xcdO\xa8\xd1:\x8e0+\xb0\x85z\x8e\xcdO\xe6\x05w\x90\xc2\xee\x0f\xccE\x0f6J\xe4\x05l\x04\xe2Z\xba>\xe2\xad\xb2\nS\x08\x9d\x99f\xce\xcf\xa9 r\xa4\x0b\xa7v\x10o\x9b.\x1f\x8e\x94\xc1\x10B\x01\x837\xcc\xe1\xd0\xe2\x9b B\xc7\xf6x\xc8\x0b]E\x19<\xc1\x18\xa1\xb9\xc3\xeb$\xb07l@\xa2\xeb\xc6\xbc\xcf\xb3\xce\xa5\x9e\xe35k\x1b]\xef\xf7\xc7|\x08\x03 Mk\x88\\\x91W\x01\xf8\xf1\xc0q\x80 &\xc7\xa3\x04$q\\\x04\x91l\xedd\x85\\\x88`1X,\x16\xbc\xf4%\x01\xa4H4Z\xb8\x0b\xde{K\n\xb8s,\x16\x0e\x9a\x8bH\xa0\xde\xef.\\\xbe\x15d:\x91\"\x10f\x88\xe6\x9aV\xbe\xea\x84&\x80\xde\x7f\xd2\x9d\xc7\xf5\xd0\x1d\xdb\xae\xb7N\xce\xd9\xa1\"6\x18@\xd7\xe8Y1b\xd3\xadq\x8f\x85\x81(\x93EA\xa0>\x032\x00\x8cf\xe8\xac\xe4@R9\xd6\"\x0fc\x067\x1e\x8f\xc7\xc0\xea\xaf\xdew+\xc0y\x92<[iUz!\xd7\x90\xc5:P\xa41\xad\xd8U,\xe0UV\x1bbU\x96\xb5q+\xf7\x16[\xe4\x82*\xe2y\x15\xdb\x81\xa2\x96\xc8\x05kO\xb6\x1cX\xe7\"\xd3Q\"\xff\xe21\"\x17\x03\x90\xb0\x97\x01@\xd0\xd1x\x9c\xc8\xd7\x00\xa4\xc8\xddx\xa8\xdc\xe3\x98\x8c\xdfS\x9c\x8eO\xdd=\xd9\xefT\xa4Sw=\x86\xdb1\xde\xa7\xe0~*\xb9\xbeX'\x12oB\x97d!B\x8f\xe4\x80\x02\x87\xe4p\xb0?\xb20\xa1;r@\xa17\xb2\xc8\x16g|\xb6\x01\x90\xcbN>\xdd\x15\xdbe;\xc2\x13\xfd\xef\xe3\x88\x02\x9fc'!\xc0\xe7X\x88\xd0\xe78\xa0\xc0\xe78\x1c\xecs,L\xe8s\x1cP\xe8s\xc7M\xb9,\xbc6oc \xa2\xa0<\x9e\x06\xfb\x1c\x9b\x80}\xba\xcf\xe1\xe7\xf49|\xb2\xcf\xd1\xfc4\xadx d\xc5\xaeH\xf5\x02/\xe5-\x82\xf8,\xe4d\xa0\xf93\x0eZ\xdeF&\x91\xc0&f\xb6\x84\x08\x03D\xe3\xf2w\xd4\xb5\x0f\xd1\x07\xb8!\xdcn\x8f\xb4-\xd8\x92a\xb5\xc8(\x1cDd\x17\x1e\x08\x9b\x86\xc7\x81\xd6\xe1`\xa0\x818\x14l#&\xee\x15\x9a\x89\xdb\xbe\x17Z\x8a\x0f\xf5\x85\xc6b\xf7\xe2\xebm\xc0v\x83\xa9\x0cl[\"\x1a\x15\x1a\xd1W\xb4!\x8b\x13\x98\x90\x85\xc1\x16\xf4U\x0c\xe8+\xd9\xcfW3\x9f\xafj=68\x16\x1b\xcf?\xc1v\x023\xe1V3aE3\xb18\x81\x99X\x18l&\xacb&\xacd&\xacf&\xacj&6\x9e\x14\x9b \xc3f\xa2\x80\xc9\xcav\xc3\xadf\xd0\xd7\xba\xf3\x87\xe7zG\xef\xf4\xa3]\xa7\x17\xed:\xf4\xa6\xcbD \x05\xd6\xd4\x13\xd54R\xaa F\x815\x99PM\xbd\x92\xbe\xbd]r$Xc_Vc&\xb9\xaeP\x1f\x84\x03k\xb3\xa0\xda\xfa\xa5\xc4m\xb5\xc9p\n\x83\xf0\x01t\xa2lT\xff\xd3\xfcHR\xd9\xf3\xbb\x92\xa0\xb2\xef\xebM-\x95\xb6\x99\xf8x\x87\x12T\xf8,>\xa5\xe0T\n3{\xedi\xfe\x9f\xe8h\xc2\xba\xbe\x83\x9f\x81u}g7\x93\xd6\xd9f\xf4\x13\xbc\x0c\xac\xefOp2\x99?\xe1?\xd1\x9f\x84u}\x07\x7f\x02\xeb\xfa\xce\xfe$\xad\xb3\xcd\xbe'\xf8\x13X\xdf\xf3\xf8\x13Ua\x14\xa3\xfa\x0b\x1e\xda.\xff\xb4E\xfdq.m_~\x08\xa8\xf9\\W\xe2\xc4!\xa6?%\xd2\xcdb@=\xff\xe6\x11\x13\xb0\x15Q\x9f~\x80S\x89E\xa4\xa7W\x9fRb\x8a\xf3\xf0N?\x14\xe9I\xbe>#\xaf\x8f\x0fa\x8b*\x8d\xb2J \xc4-j5\xaaZyD^\xb1QT\xcc\x97fu\xf7\xf2\xba\xf9\xc8\xb8\xa8\xbbW\xd6\x0dD\xceE\xdd\xbd\xaan\x1e\x91\xd7\xdd+\xea\xe6K\xb3\xba\xcb\x86k\xa2\x96\xd7M\x07\x10e\xfdM\xe3\x01L.A\xd5|\xa0<\x97\xa1P\x80&\xd2@\xad\x02\x00Q\xc9P+\x01\xc0\x142\x94j\x00\xca\xab{\xd4\x9a\xb6\xf00>HoS+\xcc\xd0\x07\xde\x99\xb3\x98\x01\xf0\xe7\xc2'\xb3B\xc8-Ko\xcf\x8a\xa5\x0e_\xa4 \x9f\xcf\x1d\xbb\xaa[\xe4\x99u\xf5B\xe7o$\x10\xfb?!\x84\xc0\xc9+9D^Z\xcb!\xec\x08\x8d\x1c\xe2\xbe@\xc8!r\xf8J\x10\x89\xcf75\xc9\xdc\x9e\xa8K\xec\xf9u\xb3\x84\xce_\xcb#\xf6\x7fB\x1eI\x17 \xe5\x11\xf6\x82F\x9e\xb6\x8eP;\xad\xb0/(t\x06\x85p\xb5\xe8!\xbe\xa4\x83\xf8\xd2\xfe\xe1\xb7t\x0f_\xda;|y\xe7\xf0\xdb\xfa\x86\xdf\xde5\xfc\xb6\x9e\xe1\xcb;\x86\xdf\xd6/\xfc\xf6n\xe1\xb7\xf6\n\xbf\xb5S\xf8*}\xc2W\xe8\x12~[\x8f\xf0[;\x84\xaf\xd2\x1f|\x85\xee\xe0\xab\xf6\x06\xffI\x9dA\xe8\xf7X\xe2\xf7X\xea\xf7\xb8\xc5\xef\xb1\xd4\xef\xb1\xdc\xefq\x9b\xdf\xe3v\xbf\xc7m~\x8f\xe5~\x8f\xdb\xfc\x1e\xb7\xfb=n\xf5{\xdc\xea\xf7X\xc5\xef\xb1\x82\xdf\xe36\xbf\xc7\xad~\x8fU\xfc\x1e+\xf8=V\xf5\xfb\xb6\x80\x88&v\x16\xe7\xf6\x82}5j\xf6t\x8e\x16a\x8c\x0e\xe5\xc7{\xcf\xff\xd2\xf9\x0b\xfd\xe5A\x98\xcd\xc1\xc1\xc8\x8e\xcf\xe7a\xbab\x01\x87\xbf=\x86\x99o1\xcfqI\x92I\xc7\x14U\xdc\xf2\x960esqMAYt\xd2N\xb9\x93O\xa3b\x91\x9aRP\xaa\xa6\x18\x12\xac)U\xd8 V\x9d\x8e\x9dl\xa8\x93\x08\xecK\xe5\xf5e\xe2\xfa\xea\xd2\xc2\x82\xc9\x8c[\x17\xc2\x82a\x99`\x98\x12\x8c*u\x03\xd9\xe7\xfc<\xe6S\x81L\xf1\\\xf2A\xc2\xae\xeb\xcd\xdb?4\xd8u\xbd\x94E\x01\xfd\xc5m@`\xa9C\x17k\x0eb\x17\xddn\xaa\xc5\xe1\x96\x81\xc5\xe1\x16Bi\xcb8\\G<\xb6x\xceQ8!^\xfb\x01+A\xfeP\x80\x05+ \x8b8:m\xe1\xed\x90{(\x90\xd8\xde\x87\xeb\xf4<\x7fD\xbc\xfeJ\xa1\x7f\x1c\x18\xdbg=Lf~\xb2\x1c\xf6\x00\x12\x01;\x01\xcfC\xe0\x07\x00\x1046\x89\x83\xbd\x81C\x08\x1d\x82GJ}\x02\x84K\xdd\x02\x10\xa5\xdd3DDR\xe7\xc8\xd73R\xffPp\x10\x85\x01\xd4\xcd\x06:\xa9\xd3\xf8m>\xe3\xb7\xb9\x0c\xcbA\xe41\x1c\x0ev\x18\xbf\xcd_|Uwa\x81ro\x01\xd0rg\xe1\xe4P\xf0\x15\x98F\xee*\xfe\x93<\x05v\n,w\n\xdc\xe6\x14\xb8\xcd)X\x0e\"\xa7\xe0p\xb0S\xe06\xa7\xc0\xaaN\xc1\x02\xe5N\x01\xa0\xe5N\xc1\xc9\xa1\xe0\x140\x8d\xdc)p\x9bSPt\x0b\x8cvu%D\xee\xbd\x0e{5?\xd12\x10\xf9,\xfb\x9dfS\x9a\x08\xe4V\x99\x99aJ\x90\x90E\xc4c^R\xcd^\xa7!\xb5E\x90==7&\x95\x94\xe7F\xc7\xe8\xe4\xd9|\xfa\xb7\xc6\xeb\xf5\xfc\xe7\xea\x85\xa9@\x15\xf9\xe1S\xae\n\xbd\xa9\"\x7f\xe7A\xfd\x13\xc0\xa1\x8c$H\x1ea\xece\xeb\x89\xea\x0b\xe3\x13\xb2\xcc\xf5\xe2\xe2\x95\xff\xe5\x17\xcb\xeb\x9a\x88\x92\x82\xe5\x04|\nH\x90\xc5H@\xf5\xab0\xf6\x1e\xc3 =A\x808\xdc\xb2\xb5s\xfd#/\xdf\xc6vt\xa8\x19d\xbf\x9dg\xffL\xe8_A\xbd\x03\xa4\xc5\xc3 \xfb@P\xaf\x16\xa3\x0d\x8a\x13\x04\xd4_\x15M\xe0\xc7B+6,\x8f\xb6fU\xa3\xd0\x9c\xb4L\xa2R\xd8\xbc2\xb9Z\xcd,\x91\x8c`\x0d\xd8\x1b\x96\xc9K\x91\x9fhIj\xc7)%N\xf1\x19\xfd\xfcyS\x15\xf90\xff9\xff\xbcy\x92\x8f)\x05\x0f\x889\n\\\x805\n\\\x96q\xf6\x88c\x8b\x02\x17bZ\xbe\xe8\x93\xe7[\x14\xb0\xac\xcb\xa7$\xf7\xe2\x11\xc4{n'(\x1b\xc8\x00\xeeU\x11\xcb\xbf~N\xd6P=\x845\x1e\xa3\xd4Y\x81:\xcfKx\xad\x17\x8f\xc9\n\xcag4\xff\x04\xe1Ee\xd0\x8aE\x06\x07\xac\x97A\x85\xc6\xcb\xf9\xe4\xb6\x03\xb84\xa6jxp\x96\xca9T\x86\x02\x98PF\xc9\xf9@6\xc9\xb94&\x01\xf80\xca\xcf9\xc1\xba/uS\xaa\x1e\xd4\x0e\xa9\xe5\x9c\x13\xa8\xe4\xfbu\x92z\x8b=\xd0q\"\xdby`\xfb\x0d\xf1\xac\"\xac\xb2T\"\xedW8\xb6\xf3\xe4\xac\xa8\xbeS?\x01YsF\xa9Q|\x07\xca9\xb1\xfd\x87|\xc8\xd6\x00\x99\xab\xc2\xccQ\xbaE(\xe0+(\x01L\x0d\xd5S\xb6\x8a$\xb2\x1dT1\x83k\xb2\xf3\xd74\x1eh~\xae\x97\xa4\xb17_\xa7H\xc0\xb2\xa0\xa29\x96\x08\xb6\xf7\xe4A\x0da\xc3\xc29\xda,X1\xa3\xbaP\xc3\xaa\xe9Ar{Ul\xd8~\xd4p\xa2\xba\x91\xcc4\x15\xab\xda4<\xaf\xca\x0c43\x89\x11*\x9e\xac\x11\x1a\x96\x84% \xaer;0=\x95\xb4\x04\xd9Qk\x96P_-\x0e\xdf\xea\xccl\xebz\x81\x8d\x8bh\x9c\x88A\xb5\x1c|\xaeO\xca\xffB\x9c\x0c \xa7\x1e\xcb\xc9(9\x19\x10\xa7\x9e\x84\x93\xc9r\xea\x95\x9cz\x10'S\xc2\xa9\xcfr2KN&\xc4\xa9/\xe1d\xb1\x9c\xfa%\xa7>\xc4\xc9\x92p\x1a\xb0\x9c\xac\x92\x93\x05q\x1aH8\x0dYN\x83\x92\xd3\x00\xe24\x94p\x1a\xb1\x9c\x86%\xa7!\xc4i$\xe14f9\x8dJN#\x88\x13\xb6\x93T\xe6\x9cz\xf6?\x96\xe38\xfb\xdf\x84\xf8\x19\x085\x97Y\xd4\xa7\xcb\xd6C\xe5\xbbm7\xe8\\\x9f\xd4$\xe0\xca*\xe7e\xc8\x96o\x0d/\x83\xe0e\x00\xbc\x92U\xec\x05\x0f\x99d\x15i\x80\x966)F\x81\x00\x05)\x89\x0d\x80\xd8\xa0\x88\x0d\x85\\\xdb\x81\xe7O\xe4\xfd\x88\xc6\x9e\xbe\xa4\x86\x18>\xf7\xaaZc\x0e\x0c/\xbe\xcb\xc2\x1a\xac\xe5\xf8\xb55\xcbFmA\xf6\x9c\xcbk\x81\x04\xadK\xafgZa\xe7\xd5W<\x8e^d\xf3\xd4\xa7\xad\xb3a)\x9e\xba\xd4>\xcd\xb8\x7f\xcaj\xfbT\xab\x7f\xbf\x057+\xd1\xf3\xae\xb9a\xee\xcf\xb2\xec\x86Y?\xe3\xca\x1b\xae\xe0\xb9\x17\xdf\"\xfd?\xd7\xfa\x9b\xeabOY\x82\x8b\x18\x1d\xbb\n\x17\xf19a!.bu\xdaZ\\\xac\xa9\x13\x96\xe3\xacY\x9f\x7fE\x0e\xd6\xf0|\x8br\x90\xfd3\xaf\xcb\xc1:\xbe\xd3\xd2\x9c\xb2\xee3\xad\xce)\x9eO^\xa0\x0b\xb8\x9d\xb6F\x170;u\x99.`\xf7\xc4\x95\xba\x80\xeb\xd3\x17\xebB\xc3\x1c\xbb^\xe7\xe7\xeb',\xd9\xe5\xcc\x8e\\\xb5\xcb\x99\x1d\xb9p\x973;r\xed.gv\xe4\xf2]\xce\xec\xc8\x15\xbc\x9c\xd9\x91\x8bx9\xb3#\xd7\xf1rf\xc7/\xe5[\xfc\xf6\x89\xaby\x96\xfb\xe2i\x0bz\x90\xddS\xd6\xf4T\xf7?aY\x0f\xd3\xb3+{\x85\xa5\xbd\xc21\x9a\x9c\xa7\xff\xcc\xcb}\x9e\xdf\xb3\xaf\xf6\xfd?c\xb1\x0fTr\xc2Z\xdf?a5\xf8\xacK}P\x80\xd65\xdfs\xad\xf4\xfd\xa7,\xf4Y\xe2\x13\xd7\xf9\x90\x0cO^\xe6\x9fb\xd7?g\x95\x7f\x9a\xc1\xbf\xe3\"\xdf\xff\x9ek|\x88\xf9\xf3,\xf1!\xce\xcf\xb9\xc2\x87\xf8?\xfb\x02\x1f\xd6\xfd\xb3\xad\xef\xfdgZ\xde\xc3|\x8e^\xdd\xc3lNY\xdc\xc3\x9cN\\\xdb\x8b\xb4t\xca\xd2\xde\xff\xde+{\xa0\x82g\\\xd8\x03\xdc\x9f{]\x0fT\xf1\xbd\x96\xf5\xfe\xf3\xaf\xea\xfd\xe7\\\xd4\x83\xccN\\\xd3\x83\xbcN^\xd2\x83\xdc\x9e\xba\xa2\x07\x99>\xc3\x82^`\x93\xa3\xd7\xf3\xec\xcc\xfc\x94\xe5\xbc\x8c\xd7\xb1\xaby\x19\xafc\x17\xf32^\xc7\xae\xe5e\xbc\x8e]\xca\xcbx\x1d\xbb\x92\x97\xf1:v!/\xe3u\xec:^\xc6\xeb\x84e\xbc\xd4]\x9f\xba\x8a\x97\xae\xae\x8e^\xc4K\x17\x84'\xac\xe1\xfd\xa7-\xe1!\xf2\xe3V\xf0\xa2\xc5:~\xe6\xc5:\xcf\xef\xd9\x17\xeb\xf8\xcfX\xac\x03\x95\x9c\xb0X\xc7',\xea\x9eu\xb1\x0e\n\xd0\xbav{\xae\xc5:~\xcab\x9d%>q\xb1\x0e\xc9\xf0\xe4\xc5\xfa)v\xfds\x16\xeb\xa7\x19\xfc;.\xd6\xf1\xf7\\\xacC\xcc\x9fg\xb1\x0eq~\xce\xc5:\xc4\xff\xd9\x17\xeb\xb0\xee\x9fm\xb1\x8e\x9fi\xb1\x0e\xf39z\xb1\x0e\xb39e\xb1\x0es:q\xb1.\xd2\xd2)\x8bu\xfc\xbd\x17\xeb@\x05\xcf\xb8X\x07\xb8?\xf7b\x1d\xa8\xe2{-\xd6\xf1\xf3/\xd6\xf1s.\xd6Af'.\xd6A^'/\xd6AnO]\xac\x83L\x9fa\xb1.\xb0\xc9\xd1\x8buvf~\xcab]\xc6\xeb\xd8\xc5\xba\x8c\xd7\xb1\x8bu\x19\xafc\x17\xeb2^\xc7.\xd6e\xbc\x8e]\xac\xcbx\x1d\xbbX\x97\xf1:v\xb1.\xe3u\xc2b]\xea\xaeO]\xacKWWG/\xd6\xa5\x0b\xc2\x13\x16\xeb\xf8i\x8bu\x88\x9c[\xac3\xf4\x87\x05\x0e\xed4\x7fG\xce\xe4\x0fz-\xcc@\xe3\x12\x9a\xbf1\xa7\x05\x1b\x94\xd8\x93\xde\x82\xb4\xc8\xdf\x82\xa4.W\x83V\x12\xad\x81+\xbcYH\xfd\xfc\x81\xe6\x1f#\xb2\x7f\x94\xc4\xbe\xba\xc0\xb0l\xc7\x98\xb9\x06\xab\xc9\x86)\xd9\xa8\xd2\xc4\x0e\x12-A\xb1\xb78,\xc2 \xd5\x16\xb6\xef\xe1\xfd\xb9fG\x11FZ\xb2OR\xe4\x9f]`/x\x98\xd9\xce\x87\xfc\xd7\xd7a\x90\x9e\xd9\x1b\x14xq'@\xbb\xea\xe7\xb3\x15\xc2\x1b\x94-r\x9b\x9f:\x01Z\xa3\xb3\xf5|\x1d\xa4\xeb\xb38\x9c\x87ix\x16d\xff$h\x19\xa2\xce\xda;\xb3c\xcf\xc6g\x8d\x14\x8ct\x9c`K\x14\xc6K\xcf>\x83\xc0\xb9t\x9a\xa0E\xc2*J*\x9e\x80\xc7:\xa1\x8b\xa8\xf7\xa0e\x0f(\xa2Wa\x90\x84\xd8N\xce\xfc0\xb0\x9d0\xfbO\x98G\x13,\xa3u\xec\xa1\x98!\xcd\x9fun2\x95\x96\x00\x11}\xad`\x8a\x03\xa3\xf6\xc6\x1e\xa2\xb6\x17\x86\xa3x\x00v\x15R\xa7+\x84\xed\x84&/\x9e\x9dI\xccT\x16\xa9Z5\xf5|D\xd7\x91?\x81\xa0\xf3\xd0\x0d\x03\x8f\xc2^\xe4\x8f:\xb3\x8f\x10\xde\xb1\xb1\x97\xa4!m\x85\xe2\x99\x80bi\xc7\xb6\x1f\x06.-|\xf9\x10\x14\xc9N\x1eP\xbc\xf10\xa6\xfd\x84x\x0e\x91\x95\x8d(>\xa1\xe5\xa56\xf6\x98\x0f_/\x12\xad\xc8\xc3\x91\xc0\xe2\x89\xc2`I\x8f=\xf9;\xafT\xebc\xb0e\x95\nu*\x0c\xd0^6\x88\xaa\xca\xe1\x1f-\x06X#V\xaf\x11\xd25\x8d%M\xb2-r\xc8}\xee\x93\xefT1\xf7E\xf8\xc5\xd6\xa0\x00\x06\x0f\xe8Q\x80\x1e\x0f0)\x00\xf7y\xfa\xc5\xb6/\x17q\xb1\xb5(\x80\xc5\x03\x06\x14`\xc0\x03\x86m\xcd\x1cQ\x80\x11\x0f\x18S\x80\xb1~\xfc\x9b\xba\x19\x8f\x15Z\x84E@Fa1\x90]X\x0cd\x1a\x16\x03Y\xa7U\xe2E\xf1\xb9\xb36\x1b\xb1\x18\xc8L\nm\x1f\xb1\x18\xc8X,&\xb3\x97\x82\xc1\x14F\x05\xba\xbf\x8b\x8d\xe8\xb7\xb5\xc3` \xa0 \xfdv\x0b\xfa\xed\x06l\x11v\x91\x7f\xed\xac\xd5|~\xbb\xf5Z\x1b=b \xa0\xed\xfc#M'\xb6R\xdb\xe0\xc7\x00@+\xe1v+\xe1v+\xe1v+\xb5\x08\xbb\xc8?v\xd6j%\xdcn\xa5\xd6F\x8f\x18\x08h%\xcc[\x89\xc2xA\xb4N\xb5\x18%\xa8\xb9\xdfnG\x11\xb2c;p\x8a/qN4?|d\x1f2&Z\xa7i\x18\x14l\xce\xcfs\xfc\"t\xd6\x89\xe6\x05\x01\xfb\x16`\xa2F\x1eZ~\x86\xed\\\x9fD\xb6\xebz\xc1\x92]\x18\xaf\x8cC\xb9\xd1\xca\xbf>y\xd5\xab\xca\xf8\xd7\x19\xaf\xcc\xaa\xac\xcf\x97\xf5\xab\xb2\x11_f\xd5\xf5\x0d\xf8B\xadW\x17\xf7\xac\x17l\xa1\xa5W\x85\x16\xfb\xa9\xe5\x956\xac)\x87<\xa5\xa1\xd7\xa4\xfcg\x9a\xf3\xcd\xe6\x1cBl;\xf3\xb0\x0d-\xddf\xc5\x15\x93\xf2\x01\xc5\xa4\x84@1-#\x0b\xc8D\xdb@R\xb2\xc0U\xf1\xce\xb9\x12\x90\xfd\xcc\x96{\xc1\n\xc5^ZA\xca_\x15\xe6\x89\x03\xe39\xd9t#q\x1e\xa2\x18\xf2\x1f\xa2\x18r!\xa2\x18\xf2\"\xb2n\xd8\x91\xc8\xea!_\"\xcaAw\"\xcaa\x8f\"E\x10;U\x86j\xf7+JX\xd0\xb5(qA\xef\xa2\x04\x86\x1d\x8c\x16Y\xecc\xbc\xd0\xb0\x9b\x11\xfc$\x9eF\xa0*gS\xf06\x85\xa8d\x95E\x132\x0f\xf4\xa5\x0e\xe8K\xfd\xcf\x97\xba\x9f\xdf\xe6}\xbe\xdc\xf9|\xb9\xef\xf9-\xae\xe7\xabx\x9e\xaf\xe2x~\x9b\xdf\xf9mn\xe7\xb7z\x9d\xaf\xe6t\xac\xbc\x02\x9f\xf3U\\\xce?\xce\xe3`\xe7\xc2R\xe7\xc2R\xe7\xc2R\xe7\xc2R\xe7\xc2m\xce\x85\xe5\xce\x85\xe5\xce\x85[\x9c\x0b\xab8\x17Vq.\xdc\xe6\\\xb8\xcd\xb9p\xabsa5\xe7b\xe5\x158\x17Vq.\xcc9\x17\x05Lc\xdby@\xee\x01\xa34E\xb1\x96D\xb6\x93E^]\x83\xfb>E\x01\xd4\xd2\x8c\x19\x0b\xd7\xba\xba%\"\xf0\xd1\xd2\xe6\xd8\xf72x\xfb\xb8z\x009\xe6\xdf/:F\\\x80\xa2Mb\xa8\x92\\h\x05\xa9\x15f\x83\xba\xaac[\xc2\x11\xb46\x84\xafB\xa1\x1d\x12\x91\xf1\xb1\"s\x04\xad\"\xf3U\x14\"S\x14x\xa5%!\xf6\xdcC\xbe\x8f^u\x16\x0e\x93z)F4\xa6\xdb\xb38\x98\x13F{\x06e)\x98\xfa\x00\x8a\x94;O\xbbT\x1cL$\x18\x0f\xb4\x9e\xc9\x0fk\x89}%\x81}EyY\\\x9b\xb82\xc9\xb0\x92dXQ2\x16g\xb1^\xe5\x05\x0f\x87\x14\xedR\xcdEN\x18\xdb\xe5 Vv\xd1\x9b\xc1\xce\xb8'\xe7\xb6\x93z\x1b\x04\x14\xe4\xcb\\\xe0\xf9*\xdc\xb0k\xe4\xfc\xb9\x80\xff\xc6K\xbc\x145o\x1cMc;H\xbc\xea\\g\x18w\xba\x86\x95t\x90\x9d \xcd\x0b&\xd2R\xbe=\x85\x90\x87p\x9df*:7\xa2]\xc7\x0d\xd3\x14\xb9\x1dg\x1d\xc7(H_eLX\xba$=d\xff\x14Yn-\xddGP\x8e\xc0\xdf\x16\xab\xc1\xda\x15\x81\xd9zk\x90\xe5\\,\xe1o{D9\x1f\xc6\xf8[\x93(\xe7\x03\x19\x7f\xdb'\xca\xf9P\xc6\xdfZd\xfd|0\xe3o\x07\x04\xc0\x84$\x18\x92\x12@U\x8c\x08\xc0\x00\x92qL\x00\xc6\x90\x0c\xc5+\xd4\x1b\xd0I\x9b\xf1\x859\xf2\x85\x93\xdc\"\x0c\x042\n\x0d\x01\xedBC@\xd3\xd0\x10\xd0:\x8c,\xa0\x81h\x0cl#F\x1a\xd0L4\x06\xb6\x14\x8d\x11\x1b\x8b\xc6)\xec\xf6\xab\x8e\xdd\xa5\x15\xfdV#\xfa\xad6\xf4[M\xe8\xb7Z\xd0o5\xa0\xdfn?\xbf\xdd|~\xbb\xf5\xfcv\xe3\xf9j\xb6\xf3\x8f3\x9d\xd8J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xd5J\xb8\xddJ\xb8\xddJ\xb8\xddJ\xb8\xddJX\xcdJ\x98\xb3\x12\x05\xdb\x1a\x07\x91Z\xb7\xbd\x83H\x9f[\xf3 R\xe4\xb6\x7f\x10ipk\x1d\x84\xaa\xcb<\xa1*e=`\xab\xf5\xaa\xb2\x1ePVq\xe5\xd6\xd0[\xcd\xac\xe8L\x9e\xce\xac\xda`\x9a|Y\xd5\x08\xb3\xcf\x95\xf5+\x9e}\x9e\xa7U\x95q\x0b\xf6\xad6\xa8\xca\x06|\xd9\xb0*\x1b\x02eU\xfb\xb8U\xfeV\x1bUt#\x9en\\\x95\x8d\xf9\xb2,\xe0\x10\xf5\xb7\xad\x96\xae\xbc\xd8\xad\x95\xd35\xb3\xff\xf1\xa0mX\x00\x93\xaaY\x83\xee`0\x18\x0c9d\x9e\xc7.0\xf9b\xbc}\x80?0.\x9aM\x13b/mJ!GmJ!_mJ!w%\xea\x85=\x96\x00@NKH\x06\xf9-Q\x0c\xb9nS\x0cz/Q\x0c90Q\x0c\xf90\xa1\x16\xc8\x8d\x9bb\xd0\x93\x9bb\xd0\x99\x9bb\xd0\x9f\x89b\xc8\xa5 \x9b@^\xdd\x14\xc3\x8eM\xdaD\xe0\xdb\xa4\xeaZ\xdd\x9bh\xab\xcc\xc3\x1bX\xee\xe4\n^\xae\x10\xc6\xe4\x01\x8a\xc4\xf3}\x99\xe3\xfb2\xbf\xf7en\xef\xb7x\xbd/uz_\xea\xf3\xbe\xd4\xe5}\xa9\xc7\xfbR\x87\xf7\xa5\xfe\xeeK\xdd\xdd\x97z\xbb/uv_\xea\xeb\xbe\xd4\xd5}\xa9\xa7\xfbrG\xf7[\xfd\xdc?\xc2\xcd}%/\xf7\xd5\x9d\x1c\xf6g,\xf3g,\xf3g,\xf3g,\xf3g\xdc\xe2\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xea\xcfX\xee\xcf\xb8\xd5\x9f\xf1\x11\xfe\x8c\x95\xfc\x19S\xfeL!\xc2\x0d\x8a\x178\xdcj\x1b/\xf1\xe6\x18\x1d\xaa\x07\xe7\xe5\x03\x01|\xe5\xb9.\n\x1at\xf1\xbb\x00\x9c8q\x88q\x03.~\x17\x80\xf3H\xaa\x86\xf2;\x1b5p\xc7\xc9\xac\xedZ\xa4\xde\xb1rk;\xb9\xe4;Vvm'\x97~G\xcb\xaf\xedd-\xd8\xf3-\xd8\xb7\xb4`\xcf\xb5`/o\xc1\x9ek\xc1^\xde\x82=\xd3\x82\xfdi\x01-\xebXY\xe8p\x94oQ\x04\n\xeeE\xe1[=\x8cB\xab8\x19I\xa0\xecg\x0c\x91\x92\xab14\n\xde\xc6P\xa88\x1cE\xa2\xeas\x0c\x91\x92\xdb14\n\x9e\xc7P(\xcc\xc1\xaa\x81&\xe7\x92\xfe\x91\x1e\xe9\x1f\xe7\x90\xfe1\xfe\xe8\x1f\xe9\x8e\xfe \xde\xe8\x1f\xef\x8c\xfe\xb1\xbe\xe8\x1f\xed\x8a\xfe \x9e\xe8\x1f\xef\x88\xfe\xb1~\xe8\x1f\xe9\x86*\x1e\x87\x8f\xf48|\x9c\xc7\x1d3\xc7\x92`%\x8f\xc3'x\x1c>\xde\xe3\x8e\x9dki\x02%\x8f\xc3'x\x1c>\xde\xe3\x8e\x9dsi\x02 XKR;\xf5\x9cCq\x055\xcc\xdf\x8d\x91\xb2\xb7Ob\x84\xf3;\xa2\x0d\xaazB\xe3\xecy\x12\xe2uJ\xe0\xaa'4\xae\xf8\xa8~\x0d\xca\x7fU\x18\x8e\x0f\x80\xe0\xd9\xc8\xae$;\x05\x94\x8bOA%-\xa0pE#\x14Z\xa10\xa9\x94M\xf3\x15[\xe6+7\xccWk\x97\x7f\\\xb3\xc4-\xc0\x8a-\xc0\xca-\xc0j-\xc0\\\x0b\xe8N\x92'r\xc3\xc8v\xbct\xcf\xbdu@\x1b7e\xdd1[8\"\n\xd9\xbb\xe9\xda\x90(d/\xc1k\x03\xa2\x90\xbdm\xafYD!{\xad_\xeb\x13\x85\xec\xfb\x034\x93(d_T\xa0\xf5\x88B\xf6\x8d\x08\x9aA\x14rJ\xd0\xad\xa6P\xe7$\xd2{d1{0\"\xd4\x1a\xce\xccy\xfb8L\xed\x14i}\x8b>o\xb0\x08c\xff\xbc(\xfb\xb1o\xb9h\xf9\xd3D\xf0\x1cd7\xd6\xc5\xec\xc6:\xcc\xaex\x0e\xb23L\x89x\x86)\x90\xaf,\x809\x8e$\x12\x1a#\x81\x88e\x01\xc8\xb1\xd7\x93\xc8\xd8\xeb d,\x0b`\x8eC\x89\x8c\xbd\xa1@\xc6\xb2\x00\xe4h\x1a\x12\x19MC cY\xa00\x96\x1e`\xd7\xd2\x88\x0f\x1c<\x8fwI9\x9e\xe6`R\x96\xa7\xfa\x98\x9c\xe9\x89n&ez\xaa\xa7\xc9\x99\x9e\xe8lR\xa6\xad\xfe\xa6\xe0p\n\x93w\xe3\x85\xfes;\xa1\x84\xe1\x89>(\xe1x\xb2\x0b\xcax\x9e\xea\x81\x12\x9e';\xa0\x8c\xe7\xa9\xfe'\xe1\xf9D\xf7\x93z\x1a~nO\x930<\xd1\xd3$\x1cO\xf64\x19\xcfS=M\xc2\xf3dO\x93\xf1<\xd5\xd3$<\xdb=\x8db:\xc7\xb6\xf3\x90EP\xf9y\xce\xf3x9\xb7\x7f\xd4\xcf\xb2?\xdd\xf1O\x10t\x04AG t\x08A\x87 t\x00A\x07 \xd4\x82\xa0\x16\x08\xedC\xd0>\x085!\xa8 B{\x10\xb4\x07B\x0d\x08j\x80P\xdd\x02\xa0:\xdb\xae\xed\xca+\x02\xde\x02\xbbJp\x8e}qf\xe8\xfa\x0b\xded\x05|$\x82\xb3f+\xe0C\x11\x9c5]\x01\x1f\x88\xe0\xac\xf9\n\xb8%\x82\xc3M\xed\x8b\xe0\xac\x19\x0b\xb8)\x82\xb3\xa6,\xe0=\x11\x9c5g\x017Dp\xd0\xa4%\xf6\xaf:{\x93:@v\xacQ\x10\xc3`V`\xae\x1d?h\xcb\xd8\xdeW\x08\xd3dVw\xbe\xe7R\x00\xcbb\x96ad\xe1p\xc8\xacG\x13\x0foP\\\x15s\xefB\xc3\xf95\x0b\x1ad\xdb6#A\x18\x06\x94\x08\x8e\xe3@lH\x08B\x08\xd0E\xae\xdd\n\xb2\xe8g\x7f\x00\xf5\xd7\x80\xc5\x02PV\x8c\xdc\xba\x92\xa1\xde\xd7\x19\x0cQ\xbcX\xf4\x0ds\x00IJ\x81\x86=\x8biN\x18\xdb\xc1\x92\x10c\xc0]\xe9_\x86\x98\xe00\xe7\xae\xd9\xef\x11\xc6\xe1\xb6Dd`H\n\n\xf4\xd7\xc5|a\xd8\x8cy\xa2u\x1c\xe1Z\x10\x0b\xf5\x1c\x9b\xbd\x9c\x90s\xa2qv\x7f`.z\x80\xea\"/\xa8=\xd1\xb5t}\xc4\xe8n\x15\xa6\x14&S\xe0\x9c\xb1\x10]>\xd2aW\xa0Q\xb6\xe9\x0eA\xb7G(\xa8{\x869\x1cZ=\xd6\xb3I\xc0\xd8\x1e\x0f\xfb\xb0\xdf\x11\xb01Bs\x87iW`o\xf6M'5\xe6\xfd> \xcd\x1c\xafQ\x03\xea\xf7\xc7\xec\xcb\n\x88r\xd3\x1a\"\x17\xb4)\x89\x1a\x0f\x1c\x87u\xe1\x1c\x85\x12\x1a\xe8\xb8\x88\x03n\xedd\x85\\\n\xb6\x18,\x16\x0b\x04\xc2(\x15\xa0\xd1\xc2]X \x8eq\xb9\xc5\xc2As\x10H\xf5\x10w\xe1ro'\xc3a\\_\xb1/\x80\xd5-AZkK\xad\x8e<\xe6\xb6\xf3\xb0,\xde\x91ZPH\x83\x90\x8ap\xd4B\xc8\x85$\x15\xe1\xb0\x85\x90\x0bP*\xc2A\x0b!\x17\xaeT\x84V\x0b!\x17\xbcT\x84\xfd\x16B.\x94\xa9\x08\xcd\x16B.\xb0\xa9\x08{-\x84\\\x98S\x11\x1a-\x84\xdc\x0cY\x11\xea\x96\x9c\x90\x0b\x81\xe6K\xad\x8e\x828\xca\xb6\x80\xa8&\x86\xdc\xa7-<\xaa\x89!\x17j\x0b\x96jb\xc8\x8d\xdaB\xa7\x9a\x18r\xa5\xb6@\xaa&\x86\xdc\xa9-\xac\xaa\x89!\x97j\x0b\xb2jb\xc8\xad\xdaB\xae\x9a\x18r\xad\xd6\x00\xact/\x9e\x92\x0f\xc7\xe6K\x8d\x88\xc8x\x02.8\x9b/\xb5&>\xe3\xf1\\\xa86_ju\xb4\xc6\xc3\xb9\xc0m\xbe\x14A\xb90n\xbe\xac\x824\x1e\xcc\x05u\xf3\xa5F\xc5u< \x17\xe2e\x92\xd7Q\x1e\x8f\xe7\x02\xbe\xba\n\x01\x01\x17\xfeU\xba/\x02<\x9e\x00\n\x06+\xc7\x80\xe0\xect9_\x16+\xe4\xc8\x8eQ\x90\xf2\x14D!l\xe3l\xc2\x03\xda\x01D\x98\xf3\xa5\x00\x0c\xc5\x9b\xb5\xa2D$|\xf49_je\x00\n\xe1\xf9X4s\xa3,\x1c\x85\xd0|d:_VA\x00\x87\xe7\xe3\xd4Zz\x11 \x18\xb5\xce\x97U@\nt\x02 \x86\xadk\x11RA\x11me\xb8<\xd4\xe4I\xa0\xf8v\xbe\xd4\xea\x10\x176\x1f\x1b\xedfM\x11\xa1\xf9\xd8\xb7i\x88\x88\x86\x8f\x84\x9b1&\x8b\xe0\x80A \x88\x8b\xf3\x81C\x00\x07\xa2d\xa2\xb3\xc2DP\xcc\x9cu\xd8,l\x86\xc6U>\x82\xaeZ\x91\x87\xab\x10 \x10O/Eh(\xba\xae\xdb \xa0\x81b\xed\x8a\xa6\x0e\xb7\x81\x81\x0d\x88\xbc\xb3a\x87\x08\xbe\x013\x02qxC$R2\x14\x957T\xe2\x0e\x06\xc4\xe8\x0d\x99hT\xe1#\xf6\xf9\xb2\x0e\xd79\x020r\xcf\xef\x97\x17s%t\x07\x9d,\xce\x7fn\xd6N\xec\xbb\xd7rd3\xf3\x8a\xb9\x11\x18\x8a%71\x17\xf0zn\x16sl \x14Cn\xe6.\xd0\xd5\xe4-\xe6W#(v\xdc\xcc^\x80\xe5\xacx6\xdc\xac_\x00\x8bY\\\xcc\xa8,\xa7Xq1A\x01%\xc3\x021C\nE\xb1\xe5\xe2\x86R+U\xe8 Q\\\x0d\xa1\x18r\x81\x05)\x81\x9c#\x81\xa1Xr\xa1\x07\xe1[y8\xd1\xe2\x7f\x05\x86b \x05'\x05E\x0bC\x88\x17;\xdc\x10\x1dI\x1b\xeb-]-C\x90\xecd+h\x92l\xd4\xcax$f\xcc.\x8fH\xb2a+\xe3\xa1\x981\xbbt\"\xc9\x06\xad\x8c\x07b\xc6\xec\xb2\x8a$\xb3Z\x19[b\xc6\xec\x92\x8b$\xeb\xb72\xee\x8b\x19\xb3\xcb1\x92\xcclel\x8a\x19\xb3K5\x92\xac\xd7\xca\xb8'f\xcc.\xe3H2\xa3\x95\xb1!f\xcc.\xf1\x88\xae$\xed 5\x82d\xdc\x96' Ie\x9d\xa4F\xc8\x98\xc3\x1d\xa5J%\xb41\x1f\xca\x99\xc3\x9d\xa5J5\xb41\x1f\xc8\x99\xc3\x1d\xa6JE\xb41\xb7\xe4\xcc\xe1NS\xa5*\xda\x98\xf7\xe5\xcc\xe1\x8eS\xa52\xda\x98\x9br\xe6p\xe7\xa9R\x1dm\xcc{r\xe6p\x07\xaaR!m\xcc\x0d9s\xb8\x13\x95\x81\x9e\x98w\x05 Y\xcb\xa2\xc3e[HW#\n\x8e\xd0\xd2\x00\x0c\x17\xa9\\\x8d\x94=\x174\x02\x8b\"8~$\xd3;\xd2*\xd8(\x12X\xb2\xc0\x01%\x91\x10\x92V\xc0\x84\x95\xc0\xb2\x19\x8e0\xcb\x0c\x92\x94\xb7\x94\xaf \xe4\xac\xd3MR\xceT\x84\x08,\xc9\xe0\x18\x94\xc9NIk\x00\"Q 9\x00\x07\xa5dJK\xae|&4\x05V\x89p\x94J%\xc1\x14\xda!\xadC\x10\xb6Ry\xb3\xf6~@\x06\x9c\xc0\xbaP\x18\xc7V\xa96i\x0d-\xcc\x05\x81-\x95\x98\x93\xf2'q\x82Z\x84i\xbc\x9a\x89B \xbddci\xae\x1a\x85\xb0z\xa9\x12Y/\xd9\xe0ZZ\x93 \xce^\xaa\x84\xdaK6\xda\x96\xd6$\x08\xbc\x97*\xb1\xf7\x92\x0d\xbf\xa55 \"\xf1\xa5J0\xbed\xe3qiM\x82\xd0|\xa9\x12\x9d/\xd9\x00]Z\x93 V_\xaa\x84\xebK6b\x97\xd6$\x08\xde\x97*\xf1\xfb\x92\x0d\xe1\xa55 \xa2\xf9\xa5J@\xbfdcziMpdBl\xf6\xb5\x8fA\x92\x9e\xab\x16\xef\x13\xbb\x83\n\xb5\x89{\xaf\xda\x02\x80\xd8NT\xa8M\xdc\x83\xd5V\x04\xc4\xfe\xa3Bm\xe2^\xac\xb6D 6,\x15j\x13\xf7d\xb55\x03\xb1\xc3\xa9P\x9b\xb87\xab-\"\x88-Q\x85\xda\xc4=ZmUA\xec\xa1*\xd4&\xee\xd5j\xcb\x0cb\xd3U\xa16q\xcfV[wT;l\xe2\xaajDQO\x15\x14\x01\xdbo\x05^\xca\x8c\xe3\x03\xed\xcc\x15\xd0zsN\xcc\xad\x810<\xf9\xad\xbb\x82\xa0\xd8\xbd\x133,\xcb\x19n\xfc\xc6^\x81^\x86X\"\\^\xcap\xe27\xfd\nl\xb1\xc7 \xe6U\x96\x93\xdc\xf8-AR'm\x0c)\x14-$\xb0mX\xd0\x14{\x80b\x9ee9\xc5\x0d\xdaT$%h\xe3I\xa1(\xce\xd0\xc6#\xe1\xb0\x91\xe0\x05\xbd,\x84\xe2 \x9f\xbc\xcb\x08\xaa\xcdI1\xcb\x1a\xc1\xb97\xbbsYjK\xca\x0d\xe2\xc4\xefjR:\x92\xf2#0\x0cW~\xdf\x93PQ\xbec\xd6\xa2\xc6\x02Cq\x85vF\xcbN!g\x08\xf1\x02\xb6M\xc96\xb5p$A\x14_hg\xb5 \xec\x8dd\xcd\x98\x97R\x9c\xa0]WB?s\xbc\x968x\x03ax\xf2\xdb\xb2\x05\x81\x9c\x1d\xcf \xda\xb2%U#\xe7G`h\xed\x01\x9b\xba\x04E\xb5\xaf\xdb\xc2\xb8\x86Q\xbc\xa1\x9d\xdf\x82\x88\xd8\xfc\x15s&A\xb4\xaf\x03\x9b\xc3\x14I\x8b+Q(\x8a3\xb4\x81L\xd1\xb4\x0d\xc74\x8c\x96\x1a\xd8e\xa6\x88\xa43$\x81a\xb8\xf2\xfb\xd0\xa5\x07-\x15b\x02\x12T\xf0\x05\xd2&\xc2\x08\xa18\xa6#\xe5.c,\x0e\x19\xc8#=R\xf6l\xe0\x00U\"\x8a!\xeaC@\xd2\x1a\xa8H\x02b/\n*\xca3CR\xe6Dh\x01\xb1\x16E\x19\xf5\x01#)s\xca 9\xf6\xa2\xb0\x839\x8f\xa4\xa0}y=\x928\xa4>\xc4$\xad\x84\x8a\x19x\xf6\xe2\xc0\x849\xf3\xa4\xd0\x92\x96\xaa\xc4\x91\nyP\xaa\xbd\xb3\x11\xb37_\x898t!\x8eVI\xeb`\x02\x18\xb8\xdf\xc1\xb1Ly\x16Kn\x0f9kQpC\x1d\xdcR\xb1\x85\xbc\x1aQ\xb4C\x9d\xf5j7\x059\x07\xf0\xd5\x88\xc3\x9f\xeax\x98\xbcw\xcb\x99\x0b\xe3!\xfa0\x99\x82\xae\xe4\x15\x89\x03\xa4\xf2\x00\x9a\xb4\x06\"L\xe2Y\x8b#&\xf2\xb4Z\xbb\x19\x889\x1e\xaaD\x18B-\xdb\xf9KY\x8bc*\xea0\x9c\x82 \xa4\xd5\x88\x83,\xf6\xfc\\{ML\xa8\xc5W&\x8e\xba\xe8Sw\xd2\xaa\xf8\xd8\x0b\xe8\x84\xc20\x8c9\xa9\xa7R\x93\xdc\x85\xc5q\x19{\xbcO\xa5\xae\xb6 K\x18\xa8Q\x87\x02Uj\x92\x07&\x92\xc8\xadu\x17\x99\xc0\x08*\x00\xf7\x94#[?\x08\xbe\xdf\x1a\xd9F]\xd4\xedY\xdc{j#\xbb\xd7\x94C\xc5f]\xcc\xbfY7\xb2\xfbu)\xffj\xdd\xc8\xb6\xeaR\xfe\xdd\xba\x91=\xa8K\xf9\x97\xebF\xf6\xb0\xa9\x97\x7f\xbbn\x84\xeb\x06k\x18-R\xae\xd5\xd8\xa0\xcb\xc1\xa6\xe3\x1e\x03\x820&\x8d\x01\x94\x80\xfb4\x04\xd0\x04\xb6h\x08\xa0\x0e<\xa0!\x80N\xf0\x90\x91\x05PL\xdc(&\xce\x06\x16N3\xb1\xc1\x00@\xd5\xc4=\x16\x05\x81L\x06\x04('\xee3\x18@;\xb1\xc5`\x00\xf5\xc4\x03\x06\x03\xe8'\x1e\xb2\xf2\x00\n\x9a7\n\x9a\x87i\x1a\xfa\x9c\x86\xe6\x06\x8b\x00U4\xefq0\x08e\xb2(@I\xf3>\x0b\x02\xb44\xb7X\x10\xa0\xa6\xf9\x80\x05\x01z\x9a\x0f9\x99\x00E\xa5\x8d\xa2\xd20\xe2\xb4\x94\x1aT1\xa8\xa2\xb4Gc \x88IA\x00\xe5\xa4}\n\x01h&\xb5(\x04\xa0\x96t@!\x00\x9d\xa4CZ\x0e@!\x1bF!\x93\x16?\xda@\x1ab\x89@\xbdm\x00\xbdq\x84\x10\x1d\xafL\x96\x0cP\xf0\x86W0K\x05(}\xc3+\x9d\xa5\x02\x0c\xb1\xe1\x0d\xc1R\x01\xc6\xd9\x00\xc6\xe1\x1a\x06Xl\xc5\xce\x125\x11<6\xae\xc0Y\x83!\x02-\xb6\x82\xa6\x12\x96\x10\xa2\x03\xa6\x17\x86\x0c\xb0\xd8\n\x98q\x18*\xc0b+`\x12b\xa8\x00\x8b\xad\x80y\x89\xa1\x02,\xb6\x82\xa6*\xb6a\xc0\xc7\x85l\xfd\xe0\xdb\xf1\xd2\x0bX\xdb\xf8\xb6Q\x95@\x06\xf0\xed^]\x0c\x95\x9aU)\xf0\x95'\xbb_\x15\x02\x9fU\xb2\xad\xaa\x10\xf8Z\x92=\xa8\n\x81\xaf-\xd9\xc3\xbaN\xa0\xa1\xb8j(\x18\xbf\xf8\xd8\xa0\x8a\xc1&\xe3\x1e\x8d\x81 &\x05\x01\x1a\x8f\xfb\x14\x02\xd0\x00\xb6(\x04\xa0\x06<\xa0\x10\x80.\xf0\x90\x96\x03PH\\+\x04\xec\x9b~l\xd0\xe5\xa0J\xe2\x1e\x03\x820&\x8d\x01\x94\x12\xf7i\x08\xa0\x95\xd8\xa2!\x80Z\xe2\x01\x0d\x01\xf4\x12\x0f\x19Y\x00\xc5\xcck\xc5\xc0\xf3\x8c?7\x18\x00\xa8\x9ay\x8fEA \x93\x01\x01\xca\x99\xf7\x19\x0c\xa0\x9d\xb9\xc5`\x00\xf5\xcc\x07\x0c\x06\xd0\xcf|\xc8\xca\x03((\xad\x15\x04\xc4)~j\x90\xa5\xa0j\xd2\x1e\x05\x81\x10&\x89\x00\x94\x92\xf6I\x00\xa0\x91\xd4\"\x01\x80:\xd2\x01 \x00t\x91\x0e)\x19\x00ElhEL\xe4n\xb3\x01\x143Qp\xa4\x0d\xaf-\x96\x0c\xa2\xe248i\xf5\xb4\x0d\xa7\xd4I\xab\xe7m8=OZ=q\xc3\xa9~\xd2\xea\x99\x1b\xde\x1al\x83\x00\x0b\xad\x98Q\xbf\"\x81\x87\xbc\x154 \xd0$\xa0\x85V\xc0\xc4\xc0\x90AT\xfc\\A\x13\x01\x16Z\xf1\xb3\x07M\x03Xh\xc5\xcf'4\x0d`\xa1\x15?\xc3\xd04\x80\x85V\xc0\x9c\xc34(\xb7P\xfb[-\xe9\xd7\nFv\xfer\xce2\x96\x01\xf2-d\xa9 \xe5BA \x84I\"\xc0\xc4\x0b \x00s/$\x00L\xbf\x90\x000\x03C\xc9\x00&a\x08\x84(\x0f\xc3A\x04\xa9\x18\x1e\x07\xc1L\x0e\x06&d8\x14\x98\x93\xe1P`Z\x86C\x81\x99\x19^.09C\xc2D\xf9\x19\x1e#H\xd1\x00@\x08g\xf280Q\xc3\xc3\xc0\\\x0d\x0f\x03\xd35<\x0c\xcc\xd8\x00\xb2\x81I\x1b\x12'\xcc\xdb\x00 A\xea\x06BB@\x13\x00\x82 \x1c\x00\x07\xe6p\x00\x1c\x98\xc6\x01p`&\x07\x92\x0fL\xe6\x90@8\x9f\xc3\"\x04)\x1d\x0e\x06\xa1L\x16\x05&vX\x10\x98\xdbaA`z\x87\x05\x81\x19\x1eN&0\xc9\xc3)\xaa=\xcf\x03kN1\xd5\x03\xeaS-\xdb\x03)Y)\xe1\x03)^)\xe7\x03\x19C)\xed\x03\x19H)\xf3\x03\x1aM-\xf9C\x92*\xe6\x7f8\x92cR@<1D\x0b\x91\xc2\xd3\x9aJ\"\x88#T\xcd\x05q\x84\xaa\xe9 \x8eP5#\xc4\xb7Q9)\xa4\xe5\xdfs\x8f\xe1\xbc\x10Q(H\x0d\x91\x08\x08`\x12\x000AD\x94\x839\"\xa2\x1cL\x13\x11\xe5`\xa6\x88\xac\x1fL\x165\x00Q\xbe\x88E\x08RF\x1c\x0cB\x99,\nL\x1c\xb1 0w\xc4\x82\xc0\xf4\x11\x0b\x023H\x9cL`\x12\x89@\x89\xf2H\x1cD\x90J\xe2q\x10\xcc\xe4``B\x89C\x819%\x0e\x05\xa6\x958\x14\x98Y\xe2\xe5\x02\x93K\x04L\x98_\xe21\x82\x14\x13\x00\x84p&\x8f\x03\x13M<\x0c\xcc5\xf100\xdd\xc4\xc3\xc0\x8c\x13 \x1b\x98t\"pp\xde\x89\x01\x08RO,\n\x02\x99\x0c\x08L@1\x180\x07\xc5`\xc04\x14\x83\x013Q\xac<`2\x8aUPk>\nT\x98ZJ\n\xd2\xa2RV\n\xd0\xacJb\nP\xb6Jn\n\xd0\xbfJz\n0\x89J\x86\n\xb2\x92R\x92\x8a T\xcbS\xb1\x04G\xa4\xaa8R\x80\x12\"\x04\xe7(\x85\x84\x15K\xa6\x98\xb3b\xc9\x14\xd3V,\x99b\xe6\x8ak\x9b(y\xa5\x90\xbdR\xf8&Kd\xeb\x9a_\xc5fPF\xab)\x14%\xb4\x08\x04\x040 \x00\x9c\xcej\xca\xe1lVS\x0e'\xb3\x9ar8\x97E\xd4\x0f\xa7\xb2|f\xad\xc0\"\x0c\x16!Jd\xb10\x08e\xb2(8\x8d\xe5\xf3\xb1=\x0b\xb2X\x10\x9c\xc4\xf2\xf9\x98\x9d\x05\x0d9\x99\xe0\x14V\x83\x12f\xb0X\x88(\x81\xc5\xe1 \x98\xc9\xc1\xe0\xf4\x15\x8b\x82\xb3W,\nN^\xb1(8w\xc5\xc9\x05\xa7\xae\x1a\x988s\xc5aD\x89+\x1e\x08\xe1L\x1e\x07\xa7\xad8\x18\x9c\xb5\xe2`p\xd2\x8a\x83\xc19+^68e\xd5\xe0\x04\x19+\x1a JX1(\x08d2 8]Ec\xe0l\x15\x8d\x81\x93U4\x06\xceU1\xf2\xc0\xa9*FA\n\x99*Hc\xaa\x89*@\x8f\x8ay*^\xb9ji*^\xe1jY*\xde\x08jI*\xde0j9*\xc0X\x8a)\xaa\x86R5C\xc5P\x1c\x95\xa0bi!R\x88\x12\x9c\xae\x94\xd2S\x0c\x9drv\x8a\xa1SNN1t\xca\xb9)\xb6}\xea\xa9)\xbf\x8c\xd4\xa0\xccT]&JL5\x00\xa8\xdcl\xca\xe1\xb4T]\x0cg\xa5\xeab8)U\x17\xc39\xa9\xa6n8%\xe5\xd3k\x04\x16`0\x00QB\xca\xe7\xc3\x7f\x16d2 8\x1d\xe5sq=\x8b\xb1\x18\x0c\x9c\x8c\xf2\xb9\x88\x9d\xc5\x0cYy\xe0TT\x0d\x12f\xa2\x18\x84(\x11\xc5\xc2 \x94\xc9\xa2\xe04\x14\x03\x82\xb3P\x0c\x08NB1 8\x07\xc5\xca\x04\xa7\xa0j\x948\x03\xc5BD (\x0e\x07\xc1L\x0e\x06\xa7\x9fX\x14\x9c}bQp\xf2\x89E\xc1\xb9'N.8\xf5T\xc3\x04\x99'\xaa\\\x94x\xa2A\x10\xc6\xa41p\xda\x89\x82\xc0Y'\n\x02'\x9d(\x08\x9cs\xa2e\x81SN\xb4b\xda3N\x80\xa2\x14\x13N\xbc\xf6\xd4\xf2M\x9cF\x95\xd2M\x9c\x92\x95\xb2M\x9c\xde\x95\x92M\x9c)\x94rM\xbcu\xd4RM5\x9db\xa6\x89\xc6\x1f\x93hb(\x01B\x88\x0e\x9a{T\xd2L4\x95j\x96\x89\xa6RM2\xd1T\xaa9&\xa6]\xa7\xa5\x98\x04\xd9$\\\x85SP6\xa9)\x14e\x93\x08\x04\x040 \x00\x9cMj\xca\xe1lRS\x0eg\x93\x9ar8\x9bD\xd4\x0fg\x930\x13\xd7\xb3\x08\x83E\x88\xb2I,\x0cB\x99,\n\xce&a>\x16gA\x16\x0b\x82\xb3I\x98\x8f\xb2Y\xd0\x90\x93 \xce&5(a6\x89\x85\x88\xb2I\x1c\x0e\x82\x99\x1c\x0c\xce&\xb1(8\x9b\xc4\xa2\xe0l\x12\x8b\x82\xb3I\x9c\\p6\xa9\x81\x89\xb3I\x1cF\x94M\xe2\x81\x10\xce\xe4qp6\x89\x83\xc1\xd9$\x0e\x06g\x938\x18\x9cM\xe2e\x83\xb3I\x0dN\x90M\xa2\x01\xa2l\x12\x83\x82@&\x03\x82\xb3I4\x06\xce&\xd1\x188\x9bDc\xe0l\x12#\x0f\x9cMb\x14\xa4\x90M\x824\xa6\x9aM\x02\xf4\xa8\x98M\xe2\x95\xab\x96M\xe2\x15\xae\x96M\xe2\x8d\xa0\x96M\xe2\x0d\xa3\x96M\x02\x8c\xa5\x98Mj(U\xb3I\x0c\xc5Q\xd9$\x96\x16\"\x85(\xc1\xe9J)\x9b\xc4\xd0)g\x93\x18:\xe5l\x12C\xa7\x9cMb\xdb\xa7\x9eM\xc2eP\x06e\x93\xea2Q6\xa9\x01@\xe5fS\x0eg\x93\xeab8\x9bT\x17\xc3\xd9\xa4\xba\x18\xce&5u\xc3\xd9$L\xaf\x03X\x80\xc1\x00D\xd9$\xcc\x07\xf9,\xc8d@p6 s\xf1;\x8b\xb1\x18\x0c\x9cM\xc2\\l\xceb\x86\xac{U\x1fl?w\x15\x1fV\x00w\x17\x1f\xd4\x00w\x19\x1fR\x01w\x1b\x1f\xd2\x01w\x1d\x1fR\x02w\x1f\x1f\xd2\x02w!\x1fT\x03}\xe7\x1e\xd6\x01}\xe9\x1eT\x00}\xeb\x1ej=}\xed\x1ej:}\xef\x1ej7}\xf1\x1ej4}\xf3\xbelq\xfb\xc1\xcb\x033f\x90\x17UD\xa3\x1d\x05\x01\x07<\x12\x01\x8ey$\x00\x1c\xf6H\x008\xf2\x91\x00p\xf0\xa3d\x00\xc7?\xf6\x00\xabh\x08\xe4q\xe0(\xc8\xc1\xc0\x81\x90C\x81c!\x87\x02\x87C\x0e\x05\x8e\x88\xbc\\\xe0\xa0H\xc0\xe4\xe3\"\x00\x04\x87F\x1e\x07\x8e\x8e<\x0c\x1c y\x188F\xf20p\x98\x04d\x03GJ\x02\xd72XBHp\xbc\x04\x80\xe0\x90 \xe0\xc0Q\x13\xc0\x81\x03'\x80\x03\xc7NH>p\xf8$\x80\xb2\x11\x94\x83\x81\x83(\x8b\x02\xc7Q\x16\x04\x0e\xa5,\x08\x1cMY\x108\xa0r2)l5\xaa\x9ef\x0f\xc8\x83W\xc2\x81\x96@\xc0\xe3l\x03\x80\x87\xd9\xa6\x1c\x1ee\x9brx\x90m\xca\xe11\x96\xa8\x1f\x1eb\xe9\xfd[\xe1\x08\xcb\xc2\xe0\x01\x96A\xc1\xe3+\x03\x82\x87W\x06\x04\x8f\xae\x0c\x08\x1e\\Y\x99\xe0\xb1\xd5gF\x1b\xd1\xd0\xca\xe1\xe0\x91\x95\x85\xc1\x03+\x8b\x82\xc7U\x16\x05\x0f\xab,\n\x1eU9\xb9\xe0A\xd5g\x07\x18\xd1\x98\xca\x03\xe1!\x95\xc3\xc1#*\x07\x83\x07T\x0e\x06\x8f\xa7\x1c\x0c\x1eNy\xd9\xe0\xd1\xd4\xa7\xc6\x1a\xd1`\xca\xa0\xe0\xb1\x94\x06\xc1C)\x8d\x81GR\x1a\x03\x0f\xa44\x06\x1eG\x19y\x14\x86Q\xc1\x88\x89\xeb\xe1F4b\x12\x08x\xc4l\x00\xf0\x88\xd9\x94\xc3#fS\x0e\x8f\x98M9\x96\xdc\xca\x05\xfajr\xc1\xa8\x10\xa6\x95C\xdb7\x12Kf\xae\x1d?\xb4\xf2\x92}I5\xe3\xf3\x80\x0e)\xda\xa5\x9a\x8b\x9c0\xb6S/\x0c\xce\xb1\x17 -]\xc5\xe1z\xb9\xa2 \xd6\x81\x8b\xe2\xac\x98\xa3\xa9K\x18\xc7\x0b51M\x10\x06Ha\xe9s\x00d\xce\xd6Q'\x88\x0d\x91)H\x0e\x91\xe5\xc2+H\xaf\xb0p+\x9b\xe4\x9f\xd4\"\x9eJ\xa5A<\x95B{\xc4\xa2\xe3\x93D\xe7\xa9TD\xe7\xa9\n\xd1)\x8a\xb4D\xd9\xd8[\x06\xe7YT\xc0\x94\xc7dy>Q2\x00\x87\x048(HQ\xac`\xed\x03#E\xed9bA\x18\x08(\x0b\x83)\xc5Q\x90G\xc1\xfbR\\y\x83DF\xbf]D\xffh aaZ-G#`a0$\x0c\x0d\xaa,\x9c\x7f!~\x11\xc6\xfe\xb9cG^jc\xef\x11\xb1P\xccBq\xb8E\xb1c'\x1cr\xcd\"\xd7Q\x04#\x03\x16y\xd2p\x98\x12\xce\xa1\xd4\x12\x00-n\x0c\x00\x16\xb7\x07\x00+\x0c*\xcan\xda\xb8\x98Z;9\xb0\xa4\x99\x1cV\xd2J\x0e\xab\xd0HA{8\xb7\x92\xb5\xe7\x08\x1f\xe4\xb1\x92\xf6pX`8]h\x833\xe6\xc1\n\xd9n>\xab/\xc2 \x8b\xf5\x1e\xd19\x1fR/4\x8b\xa5K\xd6s\x80\x94\x0f\xa1\x17\x06Ql\xf2\xc5=\xa2\xb8\x07\x05\xea\x0b\x93@\x18@\x90\xbe\xe8S\x00\x88\x85E\"\xf8\xe2\x01Q\xdc\x1d\x0d\x01\x06C\x12Q\x00\xda{\xc3\x81\xd5\xbd\x16$\"\xf5g\x9d\xae\xc5\x02\x005a\x04\x9a\x01d\x07\x1a\x01\x99\x82F\x08\xacA\x83`\x83\xb0\x18\xd0&\x0c\x080\x0b\x8d\x10X\x86\x01\x15\x18\x05\xeb(\x8cU\x99\xc9|\xa1\xc5\xfcV\x83q\xb4\xa4\xbd\xfc6s\xf9m\xd6\xf2\x15\x8c\xe5\xb7\xdb\xcaW0\x95\xdff)_\xc1P\xfe\xb1v\x12\x98\x04\x0bM\x82[M\xc2\xd1\x92&\xc1m&\xc1m&\xc1\n&\xc1\xed&\xc1\n&\xc1m&\xc1\n&\xc1\x80I(\x8c\x8f\xecd\x1d\xa3C\xd3O\xb2\xce\x03b\xb2r\n\xd8\x17\x01\x03;\x8e\xc3-\x01\xedq<\xbd\xc0EAZLi\xc5\xcf\xe7Fs\"+m?\xcf\x98\xf86\xc6\x9acG\xe5\xe8\xb0\xb1c\xcf\x0e\xd2\xf3\xe69\x8dO\xe3u\xe0\xd8):\xe4\xc9\x81<5\x82\xce\x83p\x1b\xdb\xd1$\xdc\xa0x\x91\x7f\x9c\xcfs]\x14Lr\xa9\xea\x87\x08c/J\xbcDa\xcc9\xc0\xeaH\x94\xd5\xcb`[4L\xa3EJ\xae\xe3\xbd'\xea\xb9\x1e\x88UU\x9d\x11\x9c\xaem\x05u+\x0c\xf1\x95\xc2|u\x13\xf8\xc7X\xc0W1\x80\xff<\xfa\xf7\x8fT\xbf\xff\xdd\xb4/Q4VW4>F\xd1XE\xd1\xf8y\x14\x8d\x8fT4~\x8a\xa2)\x96U\xb9\xe6\x84Aj{\x01\x8a\x0f\xf5\xa3\xfdy\xe2\xc4!\xc64E\xb1h\xa6\xb7\x12\xecu\x1aN\xc8\x9d\x96\xec\x01\xa3\xddX\xcb\x1e\xf2t\x0c\x0cS\xb0\x86Y{\xe7<\x00bj\xec\xd9\x1buIARPX\x8d9\xf4\x94\x03\x15\x04V\x18M\xcaV\xf8'7\x02\xa0\x84\xdb\xe0\x1f\xdb\x04\xb1\xb4\xf8di\x01JXZ\x0cHK\x8b\x82\xbd\xe8\x10\x85\x89\x97'\x02\x17\xde\x0e\xb9\xff\xd7\xf3\xa30N\xed \x9d\xfcQ\x97\xd8\xf3$\xc4\xeb\x14\x11\x85\x19\xe9y\x8c\x9c\xf4G#\xdau\x88\xbf?\xd1Eg\xc4\xdf\x9f\x14\xcc}\xe0\x04\xcc\x1c\xe7\xcf\x94QAH\x15\x9f\xcc$\xf7\xff\x83\x04\x17\xc9\x88\xff\\\x19)\x01\xb6\x89\x16\x84\xb1o\xb3#u\xf6\x88F\x16\xa370\xa0\xd3\xb0(\xa6#\xc9(>>'X\x0b\xc5\x07J\"\xb9\xe0\x90\x8a\x13\x8d\x85e\xd2)\x88\xa7\xe0m\x8d\xcclt!\x14\x19\nCx\x89\xfd#\x05\x96\xca\xa6jfp\xe6\xe6e\xc3\xbcl\x14f\xa3\xcd\xed\x04\x1d6(N=\xc7\xc6e:;{\xc6\xef\x91l4\xdfsY\xa8\xef\xb9.\xe6\x80i\x18\xb1\xc04\x8c\xb8\xaaS\x9f\xab9\x0fp\x14\x0c~\x00\x9a\x91\xf9\x8ezK\x00\xb4\xb01\x00\x16n\x0f$B\xd1$\x856)8q\xd9P^o\x92vr`q39\xa8\xa0\x95\"\xbb\x1d\xed\xf8e{\xf01\xed\xe1\xc0\xe2\xf6pPA{\xf8\xfa\xcb\xf6PX\xd7\xf3\x0fad;^\xba?7\xb8\xa23\xf6\x01\xf41\xfa\xecq\xf1\xfdym\x8b\xe6\x0f^\x99\x15/f\x90\x92w\xa7kXI\x07ez\xf1\x82IK9'\x86\xbc\xd6J\xfc\xae\xc5\x13\xdaN\xeamP\x03\x19M\x94d\x0c\xd7\xa9\\\xc8p\xcd\xec\x9e-q\xb8=\xe3\x9e@\x82\xe7\xcf\xbf\xa3\xbe\x14\xea\x15\x18|\x95-\x03\xf3S\x11\x9dn\xfe\x9f\x1a\xa8\xab\xa9\xedXQ\x9b\nKC\x95\xf5\x9e\x89Py\xb3\xda@y\x1b\xd9\x16\x18\xdf\xa7\x05\xcd\x06{^+\xa4w\x16R\x98 _\x7f\xb6\xef\xe1/\xe3p{\xd0\xfc\xf0Q\x0b\x93\x9dVd\x0f\xfd0LW^\xb0<_\xc6\xf6>ql\x8c\xea\xb6\xcdm\xe7aa;H\xdbx\x897\xf7p\xd6\xf2r\xc1+)\xa24\x93of\xe5?a;E\xdf~\xd4\x7f\x9a\x88\x9e\x03\x1a\xe5Xu\xba=A\xa7:\x02z:\xe4\xac\xa5\x16^\xdb`\xd7\x89\xe1.\x9b\xeb$\xb7\xc0\x8fFW\xb7HM\x11O\x81:\xcaaI\xc4\xac;\xe6Yu\xc7\x00#\x0d\xdb\xf1\x12\xfd\x7f\xc5A\xbc\xe0\x18\x1f\xe1\xd1OEI\x9d\xa5\x80\x88L \xf2\x9a\xb2\xb4\xcdwz\x90\xeb\xf4\x84\x06o\xf7\x1f\xc0\x17\xb3\x87L0\x1dzAZ\x8fH\xce:N\xc2\xf8\xbc|H#\x93\x95\xed\x86[\x0d\x02N\xea\xc5b\x8c\xb0\x9d\x89\x05\x99\xdd\xc6\xb8\xd3\xb5\x92\x8e\xb3\x9e{\x8e6G\x8f\x1e\x8a\x7f\xec\x1a\x03\xeb\xac;\xea\x9fu\xfb\xfd3\xe3\xa7\xc9\x91x\xb1\x88\xe7\xf6\"\xcd\x04\x0d\x83\x14\x05\xe9\xf9_\xfe\xd2\xf8\x7f\xb8\xd3\n\xe4\xb9\xde\xd1;\xc6 \xdauz\xd1\xaeC\x9e\xf7\xeb\xfd4Q\x86\xe5\x07;c\xdb\xf5\xd6\xc9\xb9\x17\xacP\xec\xa5\x93f\xd2\xe4\xd6\xd1\x93\"\xf3\x99\xe7e\xf4I\x11A\x1a\xba\xfeb\xb2ByN'\xff\xf91\xcf\x98\xee\xce5\xf9\x9cu\x846Ui$\x1a\xcd\xfd\xbb\xd0\xeb\x99\x18Ej_\x10d\xcc\x97\x9a\x1dx\xbe\x9d\xa23\xc1s\xa8/\x11\xa5\xc2\xd0\x89=\xc4IM\xdb\xec(\xd0\n\xa6\xa5~\xd4\xf4Ce\x17\x9d-2\xea\"\x83-\xea\xd5E=\xb6\xc8\xac\x8bL\xb6\xa8_\x17\xf5\xd9\"\xab.\xb2\xd8\xa2\xf1x\\\x17\x8e\xc7c\xa0\x98*\xe7\x00\xbe\xbdk\xa45\xfa\xc3\xfe\xc8\x1c\xf4\x87,\xaa\xf4\xf2\x1aY\xfe\xce\xc3\xbc\xd4\xb3q\x0d\xe3\xb3\x95\x8f\xda:HP\xc3(\xff\x8d\x86\x04(IQf\xa0h\xaf\x15\x11T\xdeM:!\xb3\xaf,\xc2Ej\xb05>\x10\xbf\x9e\x1b\xecB\xa2\xa4k6\xae \xda\x95\x01\xd6\x01c{G`\xcd#\xb0\xfd#\xb0\xd6\x11\xd8\x01\xa3\x17\xe8`\x7fA\x8f\xbd$\xd5b\x94 \xa1q\x08\xc4\x9a{\xf1\x1c\x99\xaf\xd6'94I\xf7\x18i\xe9>B\xc5\xd1*\xa1%\x8b\xed\xa5N\xf4sDm7u\x8f\xdbo\"9&(B\xb1\x9d\x86q\xce\x94\xe0at-A\xfb=\x7f\xd9\xf1\xfc\xe5\x81\x18\xd2\x9b\x9cG\xfe\xab\xeb%\x11\xb6\xf7\xe7s\x1c:\x0f\x02\x1d\x06\x0fI\xc7>\x94\xe7\xe1Mk\x88\\\x17\x9a\x02\xf8\x01k\"-\x95\xd5\x06\x0d\xb6\x0c\xa2\x9c\xf5\x0b\xa9\xc6\x03\xc7Y,\x9e_\xaamlG\x11\x8a\x05\n\xec\x0f\xf4hW\x1a\xf0\\\xef\xe4\x9b&\xa5\x0b\x9d\xeb\x9d^VH\xcd\xf0\xdecVRN\xcf\xf3p7\x01\x9f\xd2\x12\x84Qn\x1a-\xb5\x97Z\x82\x9cL\xeaCe4\x82ymH\xcdO\xb4\x05F;\xf2Y\xf6;%I\x18{\x993V\x99\x18\xaa\xcc\xf5\xe2\xa2\x9a2%:\xa98\x12%N\x88\xd7~0\x01\x9f\n\xc5\x7f\xba\xd8\xe4 \xe0F,\xeai\xfe\x8b\xe6\xa5\xc8O\xaaG\x95E\x0c=\x0b\x97\xb2\x7f\x8c\xea\x9f \x134\x8aB\xc4^\xc2E\x81\xbddR\x9b,\xef\xb9F\xb4\xeb$!\xf6\xdc\"\x1c\xb3\xc6g\x03\xebld\x9cu\xcd\x9f\x84*)\x9d\xb8\x99\xf5\xa9\x1b\x1e:\x1bj\x93\xca$\x8e\x18\xf5I'\xd4;V\xb4\x9b\xe4\xa5\x0b\xdb\xf7\xf0\xfe<\xb1\x83DKP\xec-&U\x1f\x9e\xf7\x0d\xcb\x10\xf2\xee\x06\xa1\xe6\xa2\xc4\xe9$\x91\x1d\x1cH\x03d\xfa>7j\xd5\x9f\x1b\x93\xe2?BV\x9dd\xb3\x84\x82\xa2\\\x85}^\xab\xfdD\xc2\xca\xb71u\xde\xa9_5t[\xcc\x04}]\x9f\xa8HK\xf4\xd1\xdc \x8eWVd\xc7\xb6\x8fR\x14\xff\xf1G6\x15\x90B\xf5\xa2]\xcd\xdf\x8av\x1d\x9db\xef\x87A\x98o\x10P\x82\x0ft]V\xdb\xc6C[\xad\x9a\x06\x1f\x0e\xfc\xca&\x9b\x04\xcch7\xa9\x0e>\x90\xfe`\xa9{\xb9\xc5\xdb\xc3\x82\xedq \xdc\xcd\xc8j(\xba\x02\xd1\x07\xfe\xaa\xeb:\xb3\x10\xe9\xb3\xc3a\xb3\x921\x99E\x8c1\xe6\x16;\x00\x04\x14\xad\xd3M\xedy\x1e8\xa0\xf8\xe9#\xceQ\x0eOV]\xfc\x9c\x8dC\x87\xc6\xdb\xfa\xfc\x90s\x04\xa3\xf3\x85\x17'\xa9\x16.\xf2\xf0\x83a\xdb\xd1;\xfa\x11\xbc\xbaebs\xd5/:9\xe7S\xa7\xf3*\xd7Y\xfc\"\xb3\xbe\xad\x999L\x1eSY\xfa\x8bj\xb5\xd9kV\x9b\x99\x9f\x00kd \x9b\xf3\xfb\x8f\x9a\xa5\xbf\x00\x13=U\x111\xb4.c{\x0f6\xab\xeb%Z\x18\xa1\xa0\x19n\x92\xb5\xef\xdb\xf1\xfe \x1a\xe13\xef\x16h\xa8fQL\x8a\x95'V\xd6\x1a\x95s\xd0\xc4\xf7\x82*\x82\xb5\xb2\xdf A\xd9\x1b\x83\xa3\x9f\xe0~c\x00\xcb\x7f\x83\xe980\xe6(\xd9\xcf\x8e\x01w\xb0=G\xf8\xe9\x1d\xef\xa4\xa9\xfe\xa8f\x95\x922C79,\x0fu\xbd\x1eG\xb9\xc30'\xcc\x1aJ\x02\x95\xfd\x91\x9a\xa1$\x9d[\xc0j\xd5g'J\x95Q\xadi\xeds4\xae\xe8C\x9a\x8f\xd2U\xe8\xca\xe6\xed\\\xcf\xf5\xd6\xe5H'f\xd0A\x16\xa8e\xe3\x05w\x03\x8c\x99\\L\xba\x0b\xe5\xd3ONC\xf5\x04\x9d\xed+\xf2v.\x16\x0b\xc5F\x86\xf9\xd2,3\x80\xe7\xb6\xf5\x97\x92$\xb2\xd3\xd5\x11\xd0?\xfepQ\x14#\xc7N\x11\xa5\xccAD\xf4\xacS{[n~\xbdq\x08\xbdc\x16\xab\x19\xfa\xb7'w\xd0\xc96\x8c]m\x1e#\xfb\xe1<\xffW\xb31\x96\x85c\xaa\xf1R\xb9\x19N\xec\xe8\x0f\x07\xa3h\xc7l\x81\xff\x07\x9a\xaf\x17\xed\xd8\xd3\x9d\xcal\xd8\xcd:,\xbc\xa6\xab\xd4p\xa6\x8b*r\xc8\x16\n\xb1\x17\xe5\xebR\x82\x81\xa9:\xe4<\xdfH\xf3?4\xe9\x90\xd1\xbeZp\xc7\xc8\xad\x18\xe0\xf7\xea\x00\x9f\x98\x95\x9e=\xb2\xe7\xa4\xab\xf6\xad\x19\x19\xcb\xb0m\xc4,5\xe0\xf8\xaab\x19\x85IJ\xbc\x8f\"3p\x7f\xec8c}\xc2\xae\x80\x87\xe6YO\xef\x9f\x19\xfd\xbe0\\\xa1\xb8\n\xa7\x1drN(\xea:\x81\x19(\xb3\n\x1f\xf5p\xf9h9\xd7\xac&\x17\x8em\x98\xbc&{V\xef\xcc\x18\x18g\xfd\x91\x82&\xd7j\x8a,\xaa:\x9e\x17(\xb1\x02\x9b\xd3\xd4\xa8\xc2\xdeE\x18\xa5\x88\x95kl\"\x13\xf1\x9a\xec\x8f\xcf\x06\xbd\xec\xff\xad\x8a,\xd8\xaa\xe92\xaf\xec$v\xa0\xd8j\x9cN\xd4\xa8B\x0dK\xc4:\xe6\xc0\xb0\x17\x0b^\x9d\xe3\xe1\x991\xb4\xcez\x96B\x17_\"5\xc7,\xaa:\x9e\x17(\xb1\x02\x9b\xd3\xd4\xa8\xc2>\xb2Sg\xc5\x88e\xe9\xc8tz\x9c\"G\xfaY\xaf7<3\xc6\n\x8a\xcc\xd9*\xa9\xb2\xa8\xec\x14n\xa0\xd4J\x8cNS\xa7J\x05\x19WF\xae\xb1n\xf4\x00\xb7\xcc\xa6\x1cc\xa4\xe6\x96\x19W%e\x16u\x9d\xc0\x0c\x94Y\x85\xcfi\xaaT\xe1\x1f\xe6\xb1^\xc2H\xa6\xbb\x96m\x0fym\x9agc\xfd\xcc\x18\x0c\xdb\x95Y\xf2U\xd2gQ\xdbi\xfc@\xc1\x15Y\x9d\xa6U\x95*\x88\xb0\xbe>\x15:\x98\xd0\xa2\xa2y\xf6\x07\xce\x14\x8d{\xc0\xab\xa5\xc4\x95(i\xb9\xa8\xefd\x96\x07Hzun\xa7\xe9ZR\x0b!\xa0\xb3B>J\xb8\xa4\x9c\x1aY\xa7[\xfe\xa0\xa5^\x8aQk\xaef\xe1\xe14kD\xb3\xd6*\x9eh^\x90Eq\xd4\xd6b\x1eI\xe7{T:\xb5oU%\xd8{M\n\xd2\x1d\xb9.b\xbc*\xb5\xe7\xa7\xad\x82\xa8\x9a\x8bex\xdd,b\xe3\x1b\xd8\xf3N\xedy\x07{l\x1a\x8d<\x89N\xf1b\x16,\xc7\xaf\xfe\x8a\xfa\xd8\\8\xb7bbv\xf2\x99\xcf\x96\xf5X[C\\\x85\x89\xecb\xdf\xbe`5\xa8WeF\xb4\xa3\xceK\x11)l\xc1\xfe\x1e\xbb\xbdW\x08Q\xfa\xf8\x81\xc9\x90\x81\xbeI\xae\xbe\xb5r\xaf\x1aLJhh\x97\xa28\xb0\xb1\xe6\x86N\"\x87\xe6^\xfdGy\x13\x8a\xb5+\xbd\xcdX\xbb\xa8U\xa5\xb5\x8f7\xa8\xa4)\xdc\x11\x12ik\x84h\xb2ALf\x14h\xd3\xf3\xb6 :\xa6\x01\x020%\x7f\xc4fR\x9f\x9e\xb3\x15\xaa\x939\x0fC\x13\xa3\x1dr\xd6)\xaa\xe0\xf50\x98\xbb\x81\xfc\x9d^\x0ci\xa7;O\x03r\x1c$\xc7\xe5>7.\xcfCw\xaf\xe5;\xb0u,r\xd2\x98\xf7?s \x82\x97\x9ez\x86\\/=P'\x16\xf4V\xfab#\x83T\x9a\"M'A\x189i\xb5\x9bkB\xb3W\x8c\x92(\x0c\x12\x94h^\x100f\x96\"\xb9\xee\xc8\x95[\x82\x9eXN\xa3\xa7u\xc6\xaa\x96,\xec\xf8#I\xedt\x9d\x80{\x0fOeJ<\\\x07n\xe8\xac}\x140\xb9]\xe3\xd8d\xf6X\xcf\xfeH\xaa\xce\xcf>1\x9f\x0f\xcd\xcf\x93UY\xef\xbe\x8e\xfc\xc9\xf36\xb78o\xf5?\xd1Zb<\xfd\xe3\x8f\xc2g\\o\xd3\xf5\xed\xf8\xc1\x0d\xb7\x01\xec]2\xca\x18\x05.\x8a\x91;+9\x80\x9b\x7fE\xa0\x93\xbf\xb9\xcd\xa1\x8f\xc75C-\x10\x9a\x91\xa7\x1c\xa8d\x9e\xd1\xef\xf7\xd1q\x9a\xe1\xf6\x9dT\x1aW\xa9\x85\x9dEThY\xc5t\xa2\x038\xad|g\xc9\xedg\x90\xdc>\x1c%\xf0h<_\xe8\xfd\x89\xe2\xbd'\x15\x89\x9a\xd6\x14\xa9\xf3\xe7h\x13}\xd8qd\xcc\x0d\xddy\x82d\xec\xce\x95\n1'T\xba:N\xd3\x8b\xc5BxbN\xb8\xd3\xaaeSW\xf3\x1b\x0e\xed|\xe4+\x0e\xdd\x93G!\xa9\x0ej6gl\x9b\xfd\xfa\x96\xb7TP\x15F1w\xa6\x0b\xee\xfb\xcc\x95\xef<\xa2)69\xb3\x9f\xca=\xce\xecwx\xe7\x93{\x98C\xab\xe0c\xb5\x8fV(H\n\xf1\xb3\xa0\x83z@\xfd\xa24\x06\xd5/\x89ae;\xd6\x8er\xcd\x15'\x18\x1at\xf3\x96\x86\x16\xban\xb1\xdc\xcf\xba\xddAr.y\xe5-W\xc5{\xc0\x9d\xd0\x05\xd6~2\xf4\xdf\xbb\xbe\xe7\xc4a\xfe\x80|iN\xe9!\xbb\xeaHN_g\xce\xe8\x0c\xd8\x13\xd6Y\x1f\xc8\xdcQ+\xd7y\x89\xf8\xc4S\xee)\xe5\xca\x138tJZj\xe8\x8ezc\x138\xed@n2\xf2\xc6&\x0d\xf8\xd1K=\x8c\xbd\xb5\xdf\xf9\x82\xe6g\xc4\x84/\xe9\x97L\xc4P\xb6\xd9\xd4\xeb\xc5\xed\x90\xdb\xdb+r \xc4+\x88\x88eT\x8f\\\xf3\x9bE6\x83\xdaG \x8ej\x83\xa7\x95\x98s\x1a\x96\xe0P\x13\x07\x93\x8bX'n\x9e\xbe^8i\xa7XQ\xba\xbf+\x1dLzr\x13\xbe\xe7\x92\xa7\x1a-\xb5\xe2\xb8\xb5U,,N\x88D[\x94T/`\xeat\x93a\xd6\xcb\xcf\xe6T\xa0\xe0\x85\xb9\xd5l\xd2\xf8p\xe5\xb3\xe5\x89J\xe2x\x7fq\xd1\"\x9bW\x9a1\xc1x\x8e\xa37\x91\xed\xbc_'\xa9\xb7\xd8W\xe3L\x8d}\xaa7\xfei\xce\xd0\xa2\xf4\xfaQ\xdbH.\xa6,3uD\x8f\xd1\x81\x1e\x03'\xf2,\xfdEs\x18\xb5\xce\xd9\x95\x8c\xa5\xa7O\xf3\x13\xa6g\xc2\x13\xa8T\xb1\xc0\x1fO\xe8\x11\x12-\xcc\xd1\"\x8c\x91 aI\xb5\x93\x8e\x9a\x88Dm5\xdb\x11G\xc8\xb5\xbcG\x01\x07r\xeb \xec<\x0e\xd3\xfc\x87\x8e\x91t\xbc`\xe1\x05^\x8a:\xd94n\xc7g\xc4%\xcf\xc9\xf1\x14\xcd{\x12\xb8\x04x\xb1\xf7i\x9d\x15\xff/\x0e\xbe\xe6\xf3b\x1aF\xe5\x9e\x039;\x0c\xd8{\xb1y\xa6\xa9\xf6\xf3S.\xa0\xff\xfb\xbf*\xf2\x07\xb4_\xc4\xb6\x8f\x92N\xd5\xb0C\x1a\x02\xf7\xa0\xf3R\xf4\xa3\x91\xae\xe3\x80t\x1a\xea\xf9\xbf\xff\xfd_\xcf\xccO\x14\xec\xe7&\xa5N\x93W\xc3\x9c\x02I7\xfb%\x0eq\xa2\xd9\x8e\x83\xa2\xb4\xda\xac)\x87dj\xf3g\x19#\x14<\x85g~\xf5\x83\xe0ED,\xdd!\xf2!K\xcc\xb1\x17<\xa0\xf8`\xe9/\x9a\x17\x86P\xba\x15 H1\xcbc\xb5\x9d\x95y8\xba\xab\xda\xdd \xcc\x93 u\xb8\xe1\x05\xdc\x92\xb2\x06\x9d\x81O\xcf3\xa7\x83\xce\xfaU\xb7\xba\x8b\xea\xeb\xdf$\xc7\xcf6(N\xbc0\xd0\xa2\xd8^\xfa\xf6\x81\xdc\xaa\xa8\x83K\xe4\xb3\xe9?\x9a\xea\x8f?|\x94$\xf6\x12==\x82:u\xde#\xe5&\x06\xfcn\x0f\xf9@\xd8\xcc\\\xa0E>q\xd8\xb4\xcb\xc5\xf4\x82\xc6\xfe\xdd\xf56\xc4\x8bE-\xcbY)\x9dmTb\xde\xc9\x171Mt\\m\x97\xba(\xfbS\x8b\xdb\x8fv\x9d~\x11\xf6\xb2\x8bN\xba\x9ay\x1a\xb4\x9d\xb5&\xaf'\xf5\xc8\x83\x9a\xec\x19A\x93?6h&\xfcH\xbc\x8c\xed\xbd|\x05\x9as\x89\xec\x18\x05\xe9s_e8a\n\x9d\xa7A\xf6WK|\xd1\xc5\xad~\xa9\x19\x8e\xee\x9f\xae\x97\xd8s\x8c\xdc\x7fU\xef\x9b\x08\xc2\xcc\xe5p\xb8En=[uM\x8e\x90y?\x00s\xb9\xc9b\x9aer\xd7\x9fx\x04\xdf&\xc7\x0e\x1c\x84\xd9Sa\x8b\x81> \x97_e\x01i\x12\xb9\n\x0b\x0e|u\xf6:]\x85\xb1\xf7\x88\xe8\xeb\xd8\x13z\xb4\xab\xb8T\x07=\xe5\xa7?y\xe1$\xf5\x16\x89\x86\x05\x0e\xed4\xff\xb6\x0cm>p/\x9e\xa1\xdf,\x0f\x0b\x0fc\xf8\xc8e\x86-w\xaa\x80\xfe\xd9\x1f\x8fu\xd4\x03\x92[T9\xc7Q\xcb\xb8D\xa7\x0d\x9f\xe4\x8aZ\xc0\xb8\xe8\xff\xc7\x0fN4\x83r\x1f\xbcxU\x15\xd7\xb13\xadv\xb8\x03\xe2\x0c\x07l\x0b\x18\xe4\xa4\xf9_F\xdd\x95Y\xec\"\xf3\x98\xb5\x83\xb9\x18P\x0e\x0e\xca\xa2\xd3\\3\x0f\x95s\xce}\x98\xb8\xf7Y\xf6B~w\x8ef\xcc\xa8V\x06-\x0f\x80\x13}E\xcf\xfe\xb4\x89-\xbc\xf5\x0bO*\x05\xeb\xa1\x9e\xfd\xa1X\xcf\xd7i\x1a\x06\xec\xdb}\xc2u\x9a\x0d.\xbc\x02\x0bx\xd7\x0b66\xf6\xdc\x03\xbfVIV\xf6\x03\xeat\xfbI\xc7\x98\xc0O\xdb\x0e\x03\xffu\x81\xb83Fe\xd0{\xc4\xc4\x9b\xa7\x18\xac\xea\x1e:\x7f\xbc\xa7\xcc\xd9\xca\x13\xbb\x8ba\xf6\xa7\xb3\x8e\xf1\x8f\xae\x9d\xda\xe7\x9eo/\xd1\xcbd\xb3\xfcy\xe7\xe3\xc9\xdcN\xd0\xa0\x7f\xf6\xdb\xaf7\xbdo\xfb\x8b\xfe\xfc\xcbn\xed<\xea\x9e\xfd\xeb\x9d\xee\\\x86\x9bw\xa6k\xba{\xcb\x9c\xed\xad\x8d\xe3;\x9b\xd9\xfdt;{5~t}\xc7\xbb\xfe\xf5[\xf4\xedw\xf7\xd5\xdc\\\x8e\xaf\xef\xa7\xcb\xd9\xab\xe9\xbe\xf8{\xfd\xf3\xf5\xab\xe9\xf2\xfar\xb7\xfd\xfa\xfb]x\xfd\xe6v|\xfd\xa0\xeff\xfb\xbe>\xfb\xb8\\\xde\xec\xfb\xfd\x9b\x8f\xf8\xfe\xdd\xfd\xb59\xfb\xa0\xafg\xf7_\xfb\xef\xee\x9d\xed\xfb\xfa\xe7\x07\xf3\xfd\xab\xe9\xf6\xfaU\x7f\x7f\xb3\xef\xefo\xee\x97\xeb\xd9\xbd\xb3\xcf0\xb3\x0f\xf9s\xeb\xe6\x1e'\xef>\xce\xd6\xef?N\xfb\xd7\x97\xb3\xf5\xfb\xcb\x9b\xfbw\x1fj|\x9aa\x9b\x9f\x1f\xcc\xf7\x1f\xa6\xdb\xf9+\xfd\xf1\xdd\xfd\xc3\xf6}\xfe\xdf\xe5\xe3\xd7}V\x9f\x93\xbe\xbb\xbf\xee\xdd\xd4?\x17u\xbc\xfb\x90\xd5\xf1\x90=\xdb\xe5|\xef\x97\xeb\x9b\xc7\xa9U\xfd\xfc\xfe\xa3\xd3\xbf\xbe\xbc\x98\xcd>N\x97\xb3\x8f\xaf\x93\xb2m\xe9l\xdf\xdf\xdd\\\xbe\x1e\\{\xa3\x9f\x7f+\xf4\xf4\xf3O\x9d<\xaf[\x9c\xfc*b\xceN\x10j1\x8a\x90\x9d\x92\xf3ZqS\x9f{#\x84<\xa3\xd9SK|f0\x95(\xa8Y\xb9G\x11\xb2\xe3,Z(F\xa4\xfcEm\xecC\xe6w\xc0\xdd\xff\xe9\xafq\xeaE\x18\xfd\xabJ\xfeZ\xd4\xc15\x0b\xf4V\x80\xd1\x9f\xde]\xe9\xbd\x07.\x89\xd8\xcbg\xd8\xa3\xee\x94 8\x19#\x9d\xbd\xe0\xa5\x94\xdd}\xea\x99\xa4\xfch\xe1?\xb3%\xf5/\xc8\xb7=\xfc\xaf3A\xe9\xc2\xc3HX\x18\xd9I\xb2\x0dcW\x08H\x90\x1d;+aq\xb6\x1e\xa3\x0b\xb3'v\x8clRE:\x91l\xa2\x1dh\xc4\x0c\x8f\xc4\x86\xa1;\xce\xfe\xb4\x0d\x8f\x8b\x85\x9a\x15\xff\xf3\xd5\xd5\xbct&\xdf\x8a\x91\x1b\xbb\xeaO\xd2V\xb4\x81\xea\xd6\xb4\x01\xcbV\xb5\xc1\xf2\xd6\x81\xa0\xaa\x95\x7f\xca0\x00d\x8ar6\x07C\x7fq6\xd6_\x00Y\xb6:\xa5k\xba?jF\xb4\xcbF]0\xe5K\x96\xff\xbb\xa7\xbf8\x1b\xb5\xf2\xeb\xc9\xd9U\xc5\xff6\xf5\x17g\x96\xfe\xe2l\xd8\xcaQ\xeb\xb7HX\x95\xff\xbb\xaf\xbf8\x1b\xb4\xf2kaWs#3k\xff\xab\xd1g\xd1(8\x1403\x07y|\xbc\xd9\x9a\xeaQ\xb7\xe8\xf9\xd5\x137l\x92\x01u\xcb\xbb(\x8e:-\x00\xccMUK\x8aw|\x1d\xf8\xd0\x17\xb8\x1fU\x0f\x11\xce:\xe6\x0f%\x13[r\xe4d\xc2\x9c\xd5\x88QN\"P\xc0\xb3\x9f\xd9rV\xc8y\x98\x87\xbb\x03\x19\xf5\x97+Y`mD\xeez\x08\x1eW*\xd5\xb3?peOx\xfd\x86\x80aD\x1dD\xef\xeb:\xf1\xd1\x8d\xc2\x0e\xe4y\xb9J\xf3,HU\x8bP\xba\xae\x16\x85\x98L\xaag\xff\xaa\x9b\xca/\xa5\xa5t?\xe7\x8a\xfa{\xb7xC\x8f\xf0\x8dJt.K#\xf7\xcb\xf27/Tn7 \xcf\x91\x8f\xca\xedn2\x0ef\xcf|\xd0[Q\x8c\xff\xa1Q\xf6G\xf4\xb2$=_\x02T i!\x97\x08\"\xde\xf1\x90\xf7\x83\xfa\xa7\x13U\xd7\xfe\xca_\x85WFKk;\xcf\x7fB.e0^Y\xf9\x1a\xf8/\xc0\"\xd8Y\xd9q\x82\xd2_\xd6\xe9B\x1b\x9d\xbd0_%\x9be'\xb7\xe0/?\x18\xfa\x0f\x9d\xc2\x82\xbf\xfc0\xfa\xa1\xb3\xf1\xd0\xf6\"\xdc\xfd\xf2\x83\xd9\x19v\x0c\xbd3\xfa\xa1\xb3\xf3q\x90\xfc\xf2\xc3*M\xa3\xf3\x97/\xb7\xdbmwkv\xc3x\xf9\xb2\xa7\xebzV\xc7\x0f/\xcc\xab\x17\xe6\xab\xc8NW\x9d\x85\x87\xf1/?\xbc\xe8\x99}\xa3?\xec_\xfd\x90?\xd0\xe25F\xbf\xfc\x806(\x08]\xf7\x87\x8e\xfb\xcb\x0f\xb3A\xd74\xcd\x8ea\xbd3;\x86\xd1\x1d\x0c\x86\xd8\xc8\x9eh\xd9\xbf\xfdN\xaf\xd3{W<\xce\xc40;\xa3\xac\xec\xf1\x87\x97EMY\xa5/\xcc\xab\xbf\xfc\xd4\xb1\xf4\x17\xcdZ\x93\xd6\xa8\xeb\xd98\\j\xeb\x1d\xf35\x9d \xf9\xa2U\xea\x1e\x8b^\x1dV\xaa^\x03,`\xd8\xe9f\xbaw\xe30\x02\xb8K\x19\x8an\xc1\x8c~\x12V\xe5\x87\xae\x8d\xa9z\xea-m\xae!\xd4\xfe63)\x16\xbf\x9a\xe5\xdcP\x7f\xf3\xc3\xe2\x86\xe2\x937\xf8\xf9\x05JuY\xafm\x81\"\xc8\x07\xe8\xd1\xaeS\x9c\x9c\x92\xbe\x04Z\x8ckUj\xb5\xb1&;\x06g\xf5\xc90\x82O*J\xd8\xd2\x17U\x80{6U\x9e\x9c\x9fk\x95V\xb8\xd2\xba\xe9K>#f\x81=h\x16\xd8O8\x9a\x04\xd5\xff\x94\xd7\xce\xd5\xb1J\xaf8/':*[:\x16\xe96'\x9d\xffQmM\xa7\xeb\xe00AZ\xfe\xf8\x88\x94\xfc\xf3e\x9bd\xc2\xad\xc8\x0f\x83\xf7\xd8c?\x03\xf2\x0d^\x8d\xe8\\\x1eN\xb4Ir\x82[\xf8\xa1+O\xef\x98\xfa\x91g\xea\x85\xb5t\xba\xc4}\xd9$\xb2\x99\x1b\x11<&u\xabc\xb9\xb6\x9e\xfd\x11\x9d\xcc\xe5(\xff\x9e\xba\xcc\x8dK\xf5w\x0f\xe5\xcc\xb44\\.1b\x8fh\xc1\x81\xd7@\x14x\x95\xa6\xccF\xa9N\xd7D\xbe\xc2\xebo\xb8\xe1]\xf8*`u\xe4\xa9\x08\xe8C\x0e$\x03~**\xcf\xf1\x8cu\x17-\x81\xf3=\xe5s\x8eN\x0bc/\xcf\xa6\xe9/\xb2(a\"*\x10\x1b\xaa\xeb\x84\x18\xdbQ\x82\\\xf1\xa9#\x81P\xf9c1\xe7\xf2\xac\x1et\x02\x8d\xdd\xc0\x12\\\xa1=*\xd2k\x0f\xe0\xaa`\xb0\xd7o\x82\xc1\xec\xe7:\x1a\xcc\x83\xea~\xa7\xd7'c\xbd,\x8c3\xf4\xce\xe0\xdd\xa8k\x8d;\xc3n\xdf\xe8\x18f\xd7\x18v\x8c\x1e\xd6\xfa]k\xd4\xe9w\xad\xf1;C\xef\x18#<\xd0\x06m\xf1\x1b\xb7W\x90\x05/\x90\x16\xef\xd7~\xa4\xa5a\xfe60`\xe1\";\x01\xc43\x10\xbfz\x8a:;\xa8u\xfb\\g\x03-\\\xdc\x87\x97\x1f\xe3$\xa0\xd5\xbb\xa5\x8aG+/H\x0f\xc4!\xbb\xfcG\xf6cc\x04T \xab\xd1\x1d!\x7f\xc2\x9f\xe3\xab\x86\xff\xae\x81\xfcN~\x14\x08\xf8\x1eo9<\xaa\x04od\xb85\x84\x1c\x9e\xb8D\x95\xad\xfb\x99\xc3F\xe5\xc9\xb2\x02\x9a\xd4W0ub\xf2\x97\xbdR\x9a\x97M\xc2\xbdz\xc1)1{\xeb\xfc\x0b\x0f`\x9a,\x96b\"7Qh\"\x7f\xef5\xcd\x9e \xd1\x9e\xe5-\x86'\x85Ap\xb2\xe8Y\xdf\x13.\x0f\"\x06:w\xbc\x86S\xd5\x13_\xa3\x0d\xf0;\xe9\xcd\xde\x1c\x9f\xe3\xde_\xce\x92[\xac\x07\x90\xddEo\xdd\xf6\x02\x0e\x0b05\xa8\x0d\x99\xf9\xeaQ\xda\x17*F\xc0e\x97\xfa\x82\xc3Q\x1f\x1c\x02\xde\xc6\xa7>\xd8\xb0\xdf\xeej\x91\xb5\xc5F\xc3\xe3\x98\xd1Q \xf1\xda\x90\xa3\xb8\xe4\xa7\x83\x18&\xad#\x12\xc7\xa6|\x90\x08\x0cLM\x0b\xa3\xfa\nVf\xab\xe6\x15;\x96B\x85\xf3pw\x90\x1e\xdai`T\xc2\x19\x8ca\x95\xcd\xcc\xbe\xcc\xa7\xae\xe4\x08\xb7\xe6Ni\xd5L\xba\xd0\x0b\x87,\xf1\xa4\xce\xf4Ty\xcf\xb4\xf4\xec\x0f\xc4\xac\xa9U\xdb\xdaq\xe0\x05K\x903\xb7|\xab^\xdcR\xddn\x17\x1fV\xe4_Q\x97\x8du\x7f\xcf\xfe)\xa7\xe5\xee<\xb6\x1d\xa4\xe5\xabZjF\x84\xceBEq\x18i\x81\xed\xb3\x87\xb8\xa9\x15I#\x1d@\x9c\xfbx\xa5\x18\xcb\x06\x10(X\xfb\xb2\x0b\x8f9(\x0b\xb1\xed\xf4 \x9e4\xba \x8a7(\x16\\\x1f{\xb6\x0bYd%\xa2\xebW\xf47f@\x06\x9dU\xbf[\x9d%\xaf\xee\x1e\x94\x01E\x8fUcE\x92\xdas\x8c:i\xf55\x16So\x01\xba\"\x9b\xd5\xd2eQ \xf8\x85\xdb u\x1f\x82H\x82i\xc4\x9dNy\xe5\xf0\xeb\xfaKWik\xa3\xdb\xe1^\x0eE\x1c|\x87I\xbbN\xe8G\xeb\xack\xadc\\\x0f\xcd\xfc\x91~\x10_\x1cC\x07\xf5E\x9c\xaa\x9d\x88&l\xce\xf5\x978\x9c\xdbX+\xea\xfa\x8f\xbe%*\x90\xb4\xd6S9\x00\x92g\x9c{\xd50$~=S\xf5\xaa/\xc0\xdd\xcb1C\xe0\xed\xb9\x03@/\xc3\xa12nZ\xb5>?\xaf~\xe0\x99\x94\xc3]\x9a\x9fLJ\xe3\xac?\xd4\xbcX\xafg?\xd6,`\xc0\xf8tu\"\xa5O\xbe\xe2\xab\xd8\x84\x82ZU\xde\xefN2IZ\x12dp\xa7|j\xda\xac\xec\\\x80B\xaa7\xb7)\xe9E\xa2\x91fl\xe9Q{\x0f\x03\xe2\xe6 \xf0V\x9f\x92m\xfe\xea\xc6\x9c\xed\x99\xact\xd5vz\x8cI%\x13\xd7b\xf2c\xf2\x8a\xeb\xb7\x9e\xda\xa9Bf\xae\xaa\xbe\x8c\x93\xb0/\x93\xe0\xce\x02\xc1\x1f\xd52\xf9\x17>Ix\xd2\x97\xcdJ\x86B\xfa?\xfe\xc8grI\xc4\xd1\xd7O\x99\x14\x99\n\xba1\xfa\xef\xb5\x17W\xaf\xc7\x11\x0d\x12\"*\xf86+\x1c\xe0i\x03\xfasCM\xca\xac\xe2\xf6\x97R\xf0\xf2e\xd0V1\n\x0e\xd8o\xae6\xb2\xa0]\x8a\x82\xc4\x0b\x99l2\x81\xf0\x14^\x9csLW\xe5?\xccBT&|m\xfe\x13+\x8d\x91+V\x81\x1f\xa5\xfb?66^\xa3?\xf8\xc4\xb5ID\x03\xe5\xda\x91\x8b\x0e\xb8\x17\x0cJ\xb9\x97\x93=\x15L\x0e\x8f\xe2\xd0\xad\xee%5\xc1<\xffjH\x8c\x80\xab\xee\xfc\xa6^\x1aFs\x9b\xfeb\x0dpE\xa7|s\x0eDZ\xfd\x17~\xcd`\x89\xb1O\xdb%{r\xbe\x07\x14\x98:U\x95\xe7\x06\xd9!U%WB\x8eb\xf9^3\xbbIR\x1c\xb9\x90\xaf_\xd8cD\x95\x84E\xca\x06\xd8\xcc\xe2#\xd1\xca\n\xf5+J\xd61\xae_\xd3\xf7d\xad\xe7m5\x9b\xd6\x9b\x93\xea \x01\xca/r\xa2\xc0e\xaevfO\xd8{\x9dy)\n\\\xf56\xb4\xcc$\xa5\x86\xf8seV\x7f\xb8\x80\xbeJV]h\x12\xdf*\x91\x8b\xd3-f!\xed\xf4\xb3WOw\xeb 8\x99\x0e\xa8\xe3p\xa76\xa9\xbcgG\xcf\x9aJ\x1d\x82\xf6\xd2<\xc0\x92\xbf\x19\xf2\x18\xa1\x8a\xa9\x9f\x93\xa3\xd7\xc8\xd1\x9b\x94\xff!\x94#t\x0b\xea\x04$\xb0\xee(\xcf\x0dR\xbf\x1f#<\xf5\xb4\xbc\xd5$\x89D\xc88\xae_\x1e\xf2\x90\x9c\xe1$\xae\xd5Q\x8b\xa8\xb2qG\x0e:^\xb0\x08\xeb;\x1d\xc0K(\xb3\xf2\xce*\xbf\xee\xd7\xf5m/`\x97urt\x87=\xc4\n\xc0\xb1w\xc6?\x8c\x80g\xc5z\x89\xe0w\xda+\x0f\x0b\x19\x0d\xa0\x02\xf6\xf3\xc8\xc5C\x13z\xd8\x87\x1eZ\xc7\xbf9\xa0\xa0,\xdenU\xad\x8f\x8b\xdbb\xea\xe9C\xdd:\xf2\xa4.\xf4\xee\xf7\\\x0e\x9b\xd5\xeeQ\x1b\x11-\xb6\x80\xae\xc9\x16\xb5\xd2\xef\xbc3\x16\x83\xb1\x03xay7\x9f\xdc\x9f\x02\x98u\xe7v\x824\xe0\xe80\xa9\x0b\x93:\xdbZ\xcf#G)Qh\xcc.\x9bF5\x07O{w/\xc1\x95\xff2\xaad\xc1`\xb5\x1c\xae(\xd6\xef\xe4\xcb\x9d{\xc5\xc0\xc2.\x8d\x93u\xc4\x1dd\xb5\x86\xcc\x01\xb7\xa1;\xea\x8f!\xf3\x92\x92\xe7\xaf\xdbST\x057T\xd9\xebt\xa5\xcd\xd3\xe0i\x01\x0e\xbd6\x7f\x8e\x17U\xc8\xa5,\xeeK\xbba\x80\x0e\xf2\x14rN\xf8\xa4\xa6)M\xd4\xcf\x1a\xbb\x912w\x88\xd7\x040)\xd0&4\xd1\x9a\x97\xe3\x01\x9c\xc0\xe4\xa1\xc1\xdeo(\xd2\x89-\xa7\xe6d\xdc\xe1M)a\x1dl8E3#v\xcd\xcbc\xffV\xb4\x13\x1d\xb7bH\xeb\x8f\x8e\xf3\xc1\xbe\x94\xae\xf5&\x9a\x84\xa0\x08\xa3\xd9\x1b\x90R)Q\x1c\x87q\xc2\x0e\xa8\xd4\x06\x18?Y=y0M\x9c0BIg\xd5{\xfa\x94\x9f\xb3\xd2\\\xb4\x90\x1f\x8b(\x1b\xaa1V\xe9\xc1\x0eXu$\xe2\x92\x9acc\xf4)b^\x80E>\xe5C\xd2\xea\xfaZ\xebd/\xf9&\x15-v\xf9;\xdb\nx\xd3\x0b$e\x8fl\x08\xdf=\x7f\x92]\x05U&\xc4\x8b\x9f\xc0M/\x86\xae\x882\x9f>P\x9e\xb4\x06S\x90\x8c\xd6a\x8f\xba\xac\xa44P+\xb99t\xc7\xb1\xf0\xb7\x03x9\xad\xbc\x971\x02\xeej\x8c~\x9a4\xaf\xc6\x02\xdfAV\x00\x0d\x9e\xd6hH\x0d\xfav\xe0\xff\xb4,\x94\x9d\xee\xf2kaq\xb7\no\x9aTZ\xe5\x1d\xf9J\xef\xff\xbc\xfc\xdb_;I\xb8\x8e\x1d4\xb3\xa3\xc8\x0b\x96\x9f\xee\xde\xfd\xd20\xea:I\xd2\xf5\xed\xe8o/\xff\x7f\x01\x00\x00\xff\xffPK\x07\x08_;\x94/\xe8Y\x00\x00\xa8X\x02\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00 \x00swagger.yamlUT\x05\x00\x01\x80Cm8\xec}\xdbr\xe38\xb2\xe0\xbb\xbf\x02\xe1\xde\xd8\x9a\x8ei\xdb\xb2|w\xec\xec\x86\xaf\xdd\xee\xda\x9av\x97\xdd\xd53\xfd\xa2\x82HHb\x99\x02h\x02\xd4\xc5\x15\x13\xb1\xdf\xb1/\xfb\x8b\xfb '\x00\xf0\x02\x92\x00\x05R\x94Kv\x99\xe7\xc4\xb4KD&\x12\x89\xbc!\x91\x04\xb6\xb6\xb66\xe8\x14\x0e\x87(<\x05\x9b\xdd\xed\xce\xe6\x86\x87\x07\xe4t\x03\x80 \n\xa9G\xf0)\xd8\xdc\xe3?\x03\xc0<\xe6\xa3S\xf03\xf4\xe0\xd6\xff\xf6\x18\x02\x03\x12\x82\x0bB\xc7\x84n\x00\xe0\"\xea\x84^\xc0\x04\xc8\x19\xf8xuw\x0f<\xccP8\x80\x8elJ\x19d\x08\x12#T\x80~&\x13\x14b\x88\x1dT\x86\xcb\xde\x19\x80\xef|HG\xfa.\xe37\x06\xc0K\x8f\xb2\xd0\xebG\xbcq\x19\xf8\x1a!\xe0*-\x0cHn\xce5sys~a\"6\n\x02\x7f\xae!U\xfcn\x00\x8a\xd5D\xf9\xe5\x83\x87Y\x19 \xff\xd5<\xdc\x0f\x1eu\xca0\xbf\x0b\xe9\x82A\x90\xf6B\x9d\x11\x1a\xa3X\x1dF\x8c\x05tcD(;\xe5\xca\x15\x0e!C\xdb\x8eP\xc8m\x8c\xd8\x94\x84\x0f\x1b\x149Q\xe8\xb1\xf9%\x1ax\xd8\x13\x02\xc1\x81\x1f\xc6\xe2?\x00\xb0y\x80NA\x1fR\xcf\xd9\x08 \x1b\x89\x9fw0qQ/1\x04\x00\x0c\x11\x93\x7f\x14Y\x89\x07$\x1c\xc7z\xdb'\x11\x03l\x84\x80C0F\x0eC.\xe0hb8\x1a\x8d\xc70\x9c\x9f\x82\xfb\x11\x02AH\x02\x142\x0fQ@\x06f\x98D\xf1\xe5\xb3\xa5\xd3R\xc0q\xb9\x91\x83r\x0da\x10\xf8\\\x8d<\x82w\xbe\xd0X\x80\x00\x08\x11\x0d\x08\xa6j\xdbn\xa7\x93\xfd\xa30\xba\x7f\x12\x17 \xa3\x15Q\xa5\x89\x98\x01\xa8\x02%L$\xfd/\xc8a\xb9\x17\xd9@\xf3\x00@%\xb1\x97X\xdaB\x93*p\xfe\xf4#\xcfw{y&\xa9\x8f\xa4\x8a+I\xac\x7f\xf9\xc7\xf1=\x84YO\xc8_#x2\x1e{\xac\x11\xe8\x904\x02kL*E\xe1\x04\x85\xcd\x87j\x9c\xa0\x05\xb0\x055R\x9f\xea\xa9\xf5\xdc\xda}\xf1gL\xb0\xf7\x80\xc2F\xb0\x00\xa0\x19\x1c\x07\xdc\xc3\xa7^k\x8bsL\xd36\x08 #\x0e\xf1\xcd\x92\x0b\x16\x0eQ\xb4\xe8\x06\xa6W\x16\xf4\x02\x95\xe6#C\x13\xe1\x9a\xdb\xead\xb7ch\x03\x83\xd6\x06\xa2\xeb\"6\xe6\xcb\xce\xeb\x90Gn]\x9d*\x8f \xc6\xc8ofG|\x8f2\x84{\xd0u\x97\x16\xbc\xdd\x93\xee\xf6\xee\xe1\xf1\xf6\xc1\xe1\xf6\xeei\xf7\xf0\xf0\xe0\xb0\xae2\x9a\xa2\xb6\xccK\x97\x1f{\xfa:\xdb\xbb\x07\xdb\xba \"ldR\xbb\x1cEc\x12\"\xe0)^\x93\xe0\x844ZA\x9b\xc6\xb3$\xcfb%c\xb3\x9e\x87]4kK@\x0d\\\x04 \x0c\x1c!\x05\x88\x1ai\xa9\xdb\x17s\x82\xd3\x9d\x9d\xce\xb6\xf8?!\x11\x99\x9e\x1fT\xb8\xeek\xe8\xf9\xc8\x05\x8c\xc4\x01:\xce\xb9\xf2\x1d:\xc7\x8e\x87\x87\x12\\ n\xd2 \xe5N6\x88\x97,dP;*\xc9G\xc9\x88\x01O\xc69\x82\x10\x8f\x02'\nC\x84\x99?\x07t\x8eyOS\x8f\x8d\xa4\x18\x896\x894\xac:\xbaQ\xc6\xb9\x8a('\xc7h\xf5\x89\xc3NB|\x04\xb1\xd5\x94\xde \x1f.\x97\x94\x18\xfa\x00\x85! \xf9d\xca\xc5\xd7\x8e\x0f\x19\xa2\xcc<\xa5|\x12\xf8\x0c\xc8v\xd2/\xd4\x99\xd1\xd5\xcd\xc4\xbd\x9e*`\x98\x86\xff\x16\xa2\xc1)\xd8\xfca\xc7\xcdB\xfa\x9ds\x0e(\x96\x0b\x9b\xadp\xf3\xeb\x08y\xc3\x11\xfbO5?\xa1$\x18@\xfe\xa7\x83B\x06=\x0c$\xe4\x8aX\x1b\xc0\x10\x8e\x11Ca\xae\xb1\x87O\x01_\xbc(\xa3\x95\xcb\xaa\x1c-\xa0\xc8\x04\xc1\xb4r\x9b\x10=F^\x88\xdcS\xc0\xc2H\x0d\x7f\xa4\xd0\xe2h\xdcG\xa1\xf2\xf3l+s`\xcd%@\xe1$\x0d\x90\xe3\x0d<\xa7L\xdaR\xf2\xb0\xdf\xd97R\xf0\x11=F\xa9\x00\xc6\xfd\x02\x97 \x8a\xdf1\x05\x81y\x087XD\x8dE\x92\x1b\xc9\xa0\x9a5\xa9\xad\xd8)0\x909\x17\xb0\x02)l0\xbd9\xb2\xf84\x17m\x91\xddd7\xb0\xc1\x02{Ob7\x19b\xad?\xce\xa6\xc1\x04\x06\xc3\x10\xceK\xef<\x86\xc6\xda\x08@+\xa9\xd9\\|J\xfa[\xd2\x84\xe5\xc5\xc7\xd6\x92\x15&\xe8\xcd\x9c-g\xceJ\xf2\xae\x98\xb57y7\xc9{\x95\x89>O\x1cDl\x9d1a\x00N\xa0\xe7\xc3\xbe\x8f\x14\x0c\xcfc\xa3\xd9\x8c\xab\x16\xa4\xa3\x85\x8au?\x03\xfd9\xe0MMJT\xcc\xe7\x97|\x13\x0b=4A\x00\xe6\xf6\x0c\"\xca#W\x8fQ\x81{{\xf5\xca\x97\x8d\xa0D\xe2\xfd\xac\xf8z\x81\xd6\x95\x04P\xd1\xba\xf3\x8b\xf3\xabn\xe7\xea\xf8r\xff\xf0\xe8\xe0\xf8\xfc\xe4\xf0\xec\xea\xe0\xf8x\xef\xfc\xe8\xa4{|p\xdc=9<\xbb\xe8\x1c^\x1d\xec\xee\xef\x1d\xec\x9ft\xae\xcf//\xce\xae\xba\x07gG\xdd\xf3\xbd\x8b\x8b\xa3\xc3\xf3\x86J;\x93k\x10&\xf3\xb3\x13\xcfEnqP\xd6\xe1\xc7\xfd\xacF,z\x93\x08W,lW\x8a\x8c\x95\x84\xcbBx\xb2U\x9c\xd8\n*n\x86\x94\xfa\xd74\xe3\x12\x8b&\x083\xda\xaa\\\x89\xc5hI\xb0\xc6\x88R8D\xdb\xb2\xef\xc5\xa2\x92#~SU Ir\xba9\xf5.\x8f\xf9\x1f\x14a\xf7\x1d\x98\x8e \xbeO\xa6\\\xa1\x10v\x03\xe2av\n\xde\xfd|u/&\xe1\x7f\xe9\xf0ls\x03\x84\x00\x1bA\x06\x10tF\xc9\xc6\x86K\x9ch,\xc8\xe0\xaaI\xa6 U\xdb\xc0'\xe4Al\x04\xcef\xbd\xf8\xb7\xb1\x9b\x10\xe0\x90P\n\xac\xcb\x89\x90\x9b\x18[\xd4}\xd8q\x89Cw\xb8\xeb\x00\xae\x17\"\x87\x11U\xacrz\xb3\xc9\xe9\xda\xac\xc5r*\x8c\xf12,\xe7\xf2(\x15G\xe2Z\xc0\xb6\xff\x9e\xef\xf9\x1fr\xa0\xbb\x87\xb39\x1a\x07h\x1c\x04'\xdd\xd9\xc9h\xfe\xf4t2\x0d\x87\x83\x93\xfd\xf0\xf0\xcb\xc9\xe8`\xd09\x0cf\xb3\xc9;\xd3\xc0ka\xb1\xe3P\x00\x87\xc8\xc4\x80[8D\xe5\xb8A\xb2\x8e{\x8a\xe1\xa2x\xa2\xbak\xdf\x1b{\xc6 \xe7\x03\x9cy\xe3h\x1cw\x0f\xc8@\xba_\x10\xa0\xb0Hs\x0d\x82j\xda\xca3\xdf\x07lF\xc1\x182G\xeca\xe6\x8c\xa6\x94m\x05\xd6\xdal\xde\xc2\xa1\x87!C\xae\xb0\x9e\xf73\xaaF\x06\x8b\xfd:\x95\x86\xac\xd0\x7f\x13\xd3\x0b@@h#\x9b{\x9e\xeeAC@\xbd!F.`\xb3\x0dM\xd7\xda\x86\x80\x11\x00\xc1 \xf2}5\xe3\xe6\x10L\xa3\xb1\x9d\xedm\xc3L\xf7\x89[\x96J6K)6q\x93\xc7\xbdl\x06\xc6\x11_\xd3\xa1l\\w\xcc\xbd\x9fm\x8b\xd74\n\x02\x122\xa4n\xd6\x8f\x89\x8b\xb8!v\xfc\xc8E\xe0\xf3\xa6\x08`7?\xff-D,\n1\x80\x03\x86B\x8eWn\xb8\xfd\xf8\x13\xf8\xbcI\xe7\xd8Q[\xa0\x10\\\x8c\x90\xf3p?\xfbQT\x02|\xde\x84\xf9&\xa1\x08\x19\xe1\x14\xce\x7f\xdcV\xc87F)-\xc5\xe2L\x93u\xd6J\xbe`\xd1f\xa1-g\x8c)\x147d\x90S\xcdV3i5\xb5\x9b\x07\xacJ\x01J\xec*\x9b\xe8s*1\xf7\xb3\x0b1y\x1f\x05\xaa\xe5\xc3\xa2\x1dY\xddr\xba\x94\xaa^ \x1c\x85\xa8\x9a\x11a\xcc\xce\xc6\x1e&`\xea\x85\xa2tg\x0c\x99N\x85\xb5\x08\xfe\x16\x0b= y\x80\xf0#\x18\x84d\x0c~\xbd\xfb\xed\x9f\x1cu\x1fRt\xb8\xbf%\xa9w\xe3^(\n=\xe8{O\\)\xe6,M}\xaf\x89\xd6/PvF\xe2J\xa3\xb5\xd7\xaa\xbaZ \xc77\x85\"\x9et\x10\xa5\xdc,\xcf\x81\x8b\xe4\xdcq3\x13\xa2d*\x9fg\x90v\xaa/\xb2\xa9\x1aA\xdb*\n\x9a\x08F\x99\x18g\x8a\xad\xca\xcf*,\x19C_\xea\x852\xf4\xc6\xebh\xc9\xd2\xe5\x94\xf9\x12itQ\xe8\x9e\xb5:kQh\xd5\xd9J\x8d\xb9jp\xbd\x7fi\xea,g\xe3\x1b\xab\xb3\x9d\xa4\xdfM\xce\xbd\x7f\xa1\xfd\xf7\xb7\x8f\xde\x97\x7f\xffE\xde__\xffr\xf5\xf4\xeb\xb1\xd3\xfd\xe5\xf6l0\xe9^]\xff\xe1\xdc\x8cf\x9d\xf9-\x1cN\xafF\xf7\xf3\xce\xe4\xf6\xec\xef?\xff<\xba\xb8\xa2\xfe\xfb\x7f\xc1\xfd\xb3A':\xff\xfbxp7\"\x1f.\x86\x9f\x9e\xdc\x9f\xaf\xc3\xbf>\xde\\~\xb8?\x9b^\x0d\x7f\xff}\xfa+\xf9\x10\xf7\xde\xae\xf5X\xc0\xc4\xc5\xc6\xec\xf9\x15\xb5\x0f\xf1\xc3N\x1f\xfa\x10;\x88\xee|\x8d7\xba\x17d\xbf\xb8\xee\xc5\x95\x9c \x815(wZ\xdd\xd9\x92\xfcksX1\xd5\xa6\xc1\x9f\xc5\xa4\xc6\xcd\xf8\xda\xbc\x8f\x9c\xd1^7o5\xc0r\xf9\xadZ\xab\xd5f\xe2w\xa6\xe79\xa8T\xdarvW\x9b\xd9\xd5\n\xe7\x05\xf1\xb0]XW-`I\xd9o&`;\xc2\x1a\x0f\xd2\x19V\x1d\x84\x92\xe9\xc2.p\x88\x87\xa94\xd0\x04gr\xc7\x97TXT\x16,\x96\xbc\xe76\xd2\xafKH+]O<\x1d\xa6Q\x89\xc5\xa1\xc8 \x89\xc8\x8a\xcd\xd42!\x9b!\xb5\xe4\x8c\xb8k\xef\x85\xe8\xb1\xec\x92\xf4+\x1cH\xd1G\xf4X\\\xb9\xc11\x1f\xab\xc9\xad\xb5\xb1\x8d\xa2*\x9c\xd68t\xcd\xdeA\xf5K\xd2-\xc5\xdf\x1f\xac\xdc1%\x99\x9aPn\xb7\xa7\xcd\x1a\x19\x0c\x18\xb1\x91\xc6`\xd8{\xa4B!\x9aX2;#\xe8%\xf2V4\x14\xe9g\x0b\xeb\xa3\xfd6\x9a\xb1\x1aeo\xe8\x91\n\x19\x80\xcb\x04.\x851\xa8\xbf\x96\x13K\xa9\xbeq\xa7\xdb\xf7\x81\xc2\n\x19\x88\xc1l\x841L\xd1\xa8\xaa\xdfd\xd5\xb2\xab5\x0d\xd0o\xef\x957\xab \x82/\xd3\xd1\xd7\xf3\x86)\x8bJV\xbdI~\xd4\x14\"G\xfd\xb1\xc7\x94\x19J8^/\x83P\x82/\xd1%>p\x82\x94NI\xe8&\x9f7)\xb1x\x88\xc6d\x82\xb2\xd4\xcc\xfb\x0fwV\x13S\xcb\xec\xb7\x13\xc5\xa5\xf3b.\xeb\xd6\xa2\x8b\xf5\xb4\x88.\xad\xaf\xa9\x89.\xad\x931\xe0\xcd\xa6\xc4\x12\xa1j\xa5\xab\xd5q5\xeb\xa1\xb65\xb7\xd9\xdeC#\xcd\x04$T\xf8\x9d\xc4\xb1yU\xd9\xef\xec\x1a\x11\xbfG\xf3L9<\n\xa6!\xb1\xf4P\xc6\xed\x90z\x1ej\xe7\xebD\x15\xa7\xff|\x0f\x1e\xabb49fT\x8e\xe6\xb7\x80\xaf\x90R%\xe4CJ\x81\xdb\x19\xd2\x04\xfa\xdc\x9e-\x1cYw\xba\x8f\xbb\xbe\xc0\xa3\xf3\xc5\xf2\xa3YQS\"?\xb2P\x05\xb6\x8f\xd8\x14!\xac\xfae\xb1\xde\x86\xa5\xc1\xac\xad\x9f^\xad\xeb\xe5\n\x9e\xd5n\xb6\xe1\x8fm\x144\xc2}Y\xf9\xd3{\x0b&\xd3`2e\xcaw\x1eV\xfe\x91\xf0\xa15!_J\x9e\xab\xe3K\x88\xb5\xf3\x96\xcc\xc3[\xb0\xf9\xc2\x83M:\x82\xa1.\xcfa\xb7a\xb7\xb9\xdb\xe9\xbcE\x9e\x8dt\x96;&\x9df\xbd\x94\x18T\xeb\xe2\xde\xa2\xd1\xdch^m4jv\xe7\xaf5 \xd58\xed[\xe8\x85-\x18\x81\x15E\xa7!\xb2\x0e=\xf3e\xcb\x05ElI \x07\xd0\xa7\x95\"k&%s}\xdc\xefW\xd2\xf3 \xfa\n=w\xa1\xf3\xa9B\x89Z!\x89\x91\x1a\x04]R\xb6\x04AU\xb1un\xb6\xc1\xdf\x06\x9e\xcfP\x08\xfa\xf3\xf8\xbc\x001\xf3\xf4\xc7u\xd7\xbc\xe5c\xeb\x8f\n\x1f\xec\xea\x17\x16*R\x85\x0f\xac\xa1c\xaf\xc3\xd7U\xae\x14rB\x98\x08\xd3*\x16\x086u\x05\xdf\xc7Z\x80\x86\xe9\x11%\xf6X\x17- 2\xf4.e5)^\x84\xfb\xbbZn\xacAa\x866\xe2P\xf5T\xbf\xdcX\x95\xc1,~\x92\xfc\xba\xadeu\xfc\x9c\xf1B~t\xa8F\xcc\x1e\x05<\xdc\x14G\xfeX\xc9\xfb\xea\x84\xf8\x19\x9c\xb6\xf6\xc3\xf1\x06\xb2\xfd\x8c\xe2\xfb\xb6\xd0\xcd\x8d\xc6~\xa1[\x08\x88\xdb\x1dM\xbbk\\ee\xf6\xa2\x15t\xa5:\xb7\xc2\x15l\xd1YT\xad\x7f2\x12\x1c\x88]\xfe'\xa2\xdb\xe0|\x0e\\4\x80\x91\xcf\x80\xc7\x80\xfct\x90\x02\x82}\xb9\x9f\x16\xcf`\xd6O\xfaq|\xcd/\xdeK\xc7\x8d\x19\xc2\x99R$\x9b\x91\xcdi\x89\xf1l\x83\x0f\xf1\x17\x97\xc8\x13\x07\xa8\xbd\x93\x84\xbe\xfb \xbc\x93I\x17\xf17 \x93\x7fzx\xf8N\xfd\nR\xd1\x0b\xd9\xdaj\x10U_H\xcb\xb4|\xfa\x95\xf4vi\xa8V_%W\xf7_\xf9\x994'`\xbc\xe0S\xe9\x86T\xad\xad\xde\xae\xc4\xb1\xb6\xa4\x91K\xfb?{\x8f\xf1\xc2R\xa3\xdc\xb0\xa8E\xb1\xf1\xfe&\xf5\xf0\xd0G/< \xda\xd0i\xac\xdc?\x14\xa5q\xa9\x12\xceW(\x99\x15\xe5\x9c/F \x97\xb7\x86M\xb7\xdb\x9f_|\xdb)\x1fy\xc5\x82\\YJ\xf2\x1d\x89\xf4\xd2\xa5$+\x92\xed\x80\x10\xff\xb4r\x16\xd5z\xb6\xf4Tb\xfec\x8c\x02p\x14/c\x02k%\x94}B(\xea1\xf2\x80t_qT\xa4Ae$\xdf\x04\xd2\xc3\x03_\xb0\xa2\xe7C\xcaz\xcc\xd3\xdd\x1a`\x03_\x0b\x8a/\xc1d\x87\xe2\x9c\x17J9\x01!\xa2\xa8\xde!\x86A\x88&\xbdx\xec\xb5\x92\xc7\xcb\xc9o\xc1\xcaZJ\xb1\x14\xdc\x04\x16\x88o\x8fL\xdfG\xbfd!\xce$*\xe4\xb3\xec\x8c \x1e6\x94\xa9\xde\x18\xd6;.@\x81\xf4\xeaI\xe4\x90@?\x16\xa5Zp\x997\xae\xad:c8\xeb\x15\xd3\x18e\xd0\xf22\x15\xc4\n\xdfs\x11&c\xcb.\x9bH\xfc\x0f\xe0\xfe\xb7\xcb\xdfN\xc1\x9f\x08`$O\x98\x8f\x93\x0e\x03o\x06\xd8\xc8\xa3 $\x11C`:B\xf2\xeb\xbe\xcccxT\x9c\xd99 \x11\x16\xe7i@\xd7\xe5\x0b\x1d\x1f\xd2\x91\x9aU\xc9N\xc4\xc3,\x84\x0e\x03\x0cQq\x9c\xd7\x0f\\\xe1\xe2[\x93\xf4\xd1\xd0m\xd4\x7f\x8f\xe6\xff\xd9\xa1\xde\x10s\xfe'W\x8f\xfc\x002\x9d\xfcA\x8e6\xa7\x96\xbc\xbdX\x84q\xa72\xf4&\x08\xe7\x82\x82\x1f4\x0c\xb2\x07SU\xf5\x87\x84\xd9Zm\x8d\xdf&\x9a\xaf4V\xae\x91J\xb0\xe6,\x8e\xd2\xb40\xd5\xe9\x1b}$\x97q]~\xa2\x07\x1e\xd0<\x0fU\x88\x0d%\x8b\xf3MJ\x91\x9e\xf2N\x895\x95_u\xf1\x9eC0\x0d\xa2\xfe\xee\x93\xf3\xc5\x8dP\xf0\xd8\x99D\xdd\xa7\xe1\xc3\xf0a\xff\x04\x0d`\x07?N\x9f\xb0\x0b\xf1\xe3\xc1x\xdf9\n\xe0^\xb4\x0f\x83\xa7\xfda7<\x19\xd2\xe0qx8*\x91Q|n\xd7B\x1b\xa2\xfc\x1c[,\x1ek\xa4{:\x12*\x13\x03%:\xd9\xd0P\xd4\x10\xc7\xfa\x063\xb2\x12\xd04\x12nke\xb1\xacC0\x83\x1e\xa6\"aX\x04(/\xf9\xdf\xc2\x96\xe4Q\xef\xc1\xb9\xe5|\x03\x172\x02,\xb4l\x1a\xe0\xe4{\xf8#p\xb9t\x8e\xe1L\xc9\x9d\xad&ry\xe6\x88%yb\x89[e\xb7b\x9a\xf2\xb3T\xd3\x14\x8b\x03\xbe\x95u\xce\xeb \x9e\n\xa6\xf7k\xf2\xe7\x8d[q\xb0kR\x80_\xb56,\xb6\x01\xfd9\xf0\x12\xfe\xac\xde(\x1a4,\xb6f\xe9 \x95W\x0d\xb3\x97\x9b\xdd\x862\xb5\xd0\xbd\xb7\xec\xb1\xd3\x89\xf0\xecN\xa6o 1;yK\xb4(,G\xdaL\xbbl\x91\\\x95\x91\xb4\x14?\x94$\xeeM\x8e\x9a\xca\xd1m\xcc\xd7\x862ts\xb92\x19\x8a\xfd\x10]$CI;\xb3\x0c%-\xb8\xe9)M\xd5\x9b\xe8X\x88\xce\xf2+\x8cK9\x07\x0d\xc5lISeX8\xc44\x01Y\xab'\xef\x80\xabre\xba4\xa7\xbb\x18\xc7Z-\x12l6\x00ul_\xad\xbc\xda\xec\xdf\x89\xa5G\xb2^\x7f-+\x8f4Wb\x89\xc6\x10\xb3\xaf\xc1\xbd\x07KX\x97\xd5\xed5*\x92,O\x90\x95\xca\xfa-\x8f\xec\xb2\xf0x;_S\xb1X\x18|\xc7-74$\xe4\x1a\xe4}\x9f8\x93\xc3\x94\xa7\xfb\x9e\x8d\x90\x0deq}DU\x9a\xd3\x9c)mHe\x93\xaf\xc0\x9fEM\x97\xf5\xeb\x8aZj8Yu/\xfd\xb5\xa8g\xc5\xa4\xa0\x02\xed\xab\xe5\x840\xb40\n\x15\x89\xf7\x8a\x18T\xbe\xcfm-\xacU4\xfa\x8du\xafmY]>`\xfdD\x18j,\xd5K\xc9\xa2!Z\xe5\x045\x08P'Z\xb0\xb7\x98t\xa1H\x96b\xd2R}\x00\x11/6?\x83\x81\x87|7\xdbT\x9a#*\xb7\x8a0I\xfe\xdb\x9bzl\xd4\x9b F6?'7%\xf7)\x83\x1e6\xd5\x06\xf0y{5a\xae\xb0~\x96(\x0c!\xaedv\x19\x87\xe5N?\x9f\x93\xf8u\xdb\xb6\xe6\xd9\xc2W\xa1\xcak\x1a\xbb\n'\xb9\xf3UL\xf4\xc2\xa0\x95\xb7\xda\xd0t\x9c\xbd59J\x10\xc7\xae\xba}\xee\xef\xd9P\xd9P\x96\xd4\xf5\x1aJ\x04\xf4\xd5\x05\x0d\xa9[\xdbxu)\xb7\x9e(a\xc3@U\x11\xfb\xf6\x15\x90A\xdf\x9f\x9b\x15O|\x91\x9d\x8e\xe5\x1d\x05\xa2=\x90w\xcc\x03\x98/\x85e\xdeX\xab\x9f?#F\xeba\xd9\x067\x03%\x7f\xcf\xb9HA\x80\x92o\xc2\xe3\xbc\xec\xdf\xbcm\x14\x17j\x80w\xf1\x8a\xe2V\x94_\xbc\xfbQ=\x11\x08b\x80\xc6\x01\x9b\xe7\xba\xdd\xfe\xce\xd5\xffY\xd4\xe6\x9e3|I\x17\xd6\x82\xe8\xa7\xd3\xb2\x93\xdb\xa56{\x9aa:\xb3i\"\xa4T\xab\xa2qA\x95`\xdb\xc9)G\xbd|\xf5\x10\x880\x17f\x18r\xef\x050\xc4\x84\"\x87`\x97\xaeBB\xdb\x9e\xf5\x06\xa1\xe1\xd8\xc3\xcf]\xde\x98\xd3\xdc\x02j\xddMgw}t\xc4 \\\xedh\x88,\xff\xac\xa1\x1f\x12\xa0\xae\x82\x94\xa0\xa4[\xc9\x15\x9f\xbeh\x8fbV\xa7\xdc\x18\x1b\x8b\xe4\xba\x19n\x93\x184\x94J\xd7\xe3\x1c\xe8Gb\x1e+\xcf\xb6\x9f\xc2\xd0\x8dy\\\x8e[\xd7\xff`\xdb\xa3\xe9\xc9!s'c\xf8\x04\x1f\xdc\xe9\xc3\xb4\x1b\x1d\x1cu\xbbG\xc8\x8d\"\x1fv\x9d\xf9\xc1Q\xd7\x1f\x18\xb51\xf9\x8a\x8f\x11\x06}\x103\x03\xf4\xa1/\x94L\x9e4\x95?QM\xa7\x9d \x16\x1a\x8d\x93\x8f\xe7\xf9?\x13t\x08\x86\x18\xb9\xa0?\xcf_\xa12\xcf\xce\x0b,^\xc3\xb1\x84b^*\x13\xbf\"\xd5\xac:v\x8d\x84\xf7\x9c\x95\x1f\xe5\xd0\xed\xd4j5'=\x1b\xf2\xe0\x7fzl\xe4\x86p\x9a\xceR\xda\xeb;\x9a\xbf\x9fI\x8c@7\xdd\xcdPXL\xd4j\xd2\xea\xe6/D\xb4\x973\xa4\xa3\x0buG\xc6\xd75\xd6\xcb%\x80\x9fEr[\xc9\xb5\x9ae\xf7\x99\x93\xac5\x0d\xff\xd2'\xbc\xae\x8d#\xa8\x93+\xfc\x9e\x0eSL*\xa8K\x86iC3\xb8\xa4q\xde/e0\xd2k\x15\xdd\x95\x85i\xaba\xaf\xdaV\xfa\xe57s\xf39\x84\xe5\xccA\x13\xa5^\xe8\xca\xec&\xb7\xdc^\xef\xb1j\x1ef\xfc\xe6\xc8^\xb5#+\xdc\x9d\xfe-7\x10m}\xdb4\x9e\xf9\xfc\xadF/\xd1\xa9\xb5\xb3\xbaI\x16\" _\xa0_0K\xda\xd5\x8c\xb2XyW\x81b\x1b\xdc\x8f<\xcagX\xdc\xe2\x1b3\xc3\xc3`:\xf2\x9c\x91\xf81\xa2(\x04SO\\`\xe7 o\x82\x14\xaa\xc0 \xc2ub\xe4\x1a\xf6\xe2Y\x94\xaeTo\xd0H\xc9\x96\xd2\x0b\x83{\xf8\x88\x02\x1f:\xa8\x81\x04\xa8\x90\x96R\x10\x7fX\x83\xd1\x14\x10\x9c\xde\xd1`1\x9fo\xae\xc2P\xf4\xa27b\x0b\xb1\x15\xe4\xf1Yt\xa0e\xc7C\xc2t\xf0k\xb5\x9a\xca>\x9d]z\xd5\xf4\n\xd7\x19\xe9\xad\x11@e\x9a\xe6\xdeF\xcd\x82C\x18\x1a\x03\x94\xc8\xa8-\x11\x8b\xd6\xb0\x1a\xcf\xa2,)\x9f8\xad\xcb\x9c\x8f\xd8\x86\xeb\xb0\x15\xf0\x1d\x121\xca\xa0<\x1f\xb9i\xce\xf8\x15\n\xfd5*\x08\xae\xc2\xa7\xd4[\xbe\\\x01n{\xe9\xbcR\x11}\x13\xcbT,/\xd2\xb3\xf8E\xb9#E\xfe`\xab\x9c\x98\xae\x14L\x83\x95v\xac1\xa7\x08k\x04\x83\xafH\xd4\x9f\xdf\x96/\xca\x12\xe5N\xce}G\xadv8\x8a0\xc5\xf9\xe62\x90\x89D\x11\xa7\xc5\x8c\xbf\x85\xff/6Sd\x96\xdeo\x19\xa4si\x8c\xb0\xc7\xe6\xbd\xea\xdbi.\x92v\xe2\n\x9a\xf2\xbe\xbb\x85\xec\xd6\x10\xc8\xb6g\xb5mk\xb5<\xdf\x8b*g\x15-\xbd0\xae/\xd0yY\xac\x8a\xc28@.\xeb\x7fEiJ\x9f\xe0\x88.\x85!\x13|f}\xd7J\xa3i\x1f{\x98\xd9\x9e\x92\xfcA\xb6\x05c\xe2F>Z<\xdf\xbc\xfd:\xcf3\x1f{\xad\xdbZ\xe4\xf3}\xdd\xa4\x13\x9f\xef\x1c\xa0\xb07GP\xf3\xe1V\xfb\xb2X\xb8\xbcJk\xf0\xe3\xef\nb\x90\x8c/\xf2\x9b\xbc\xb5\x16\xc8\xf6\x19\x061\x8e\xa0\xbf\x15\x84d\xe2\x89\xd0\xcd\x9eq\x12\x14d\xa0\xdf\x15\x03\xbd\xbe\xb3\xe3\xf8\x1e\xc2\x8c\xee|\x95\x7fly\xee\x7fvx \x8b0\x8d\xe8\x96\xb8\xe7\xce\xccN\xb9\x96\xe2\x90\xe2\xf8D\x15\xc8\xc0\xc2\x9b\xf3\x8b\xfa\x1c4\x87\xc0\x85\xafBd\x08\x9c\x8e\xc4\xc4\x90\x0b\xd1@=\xb1\xa9\xe2\xe3\x13\x83qP\x96\xbb^\xdf\x91]z\x96\xd7V\x87d\x82L\xb4\xdd\x86\x84\x0c\xf8\x9aS~\xd2S\"\xa4O\x88\x8f \xd6S\xa2\x9e\xb8\xba\x1a\xb1\xab\xf5YD*\x12=E\x8e\xd4\xc7\x10\xcd\xc5Pw\x1c\xa8\xb8\x95\x10p\xfeXb\x12\xbc\xd4\"\x10u\xafu\xb0\xdcB6\xd2c\x1a!o82~\xf6Q\xbc\x0b\xc7f1\"\x85i\xe9\xcf\x84\x8c\xda-\xff\xb4V\xed\xe4\xba\xcb\xb8\xc5\x9bF\x7f\xcf\x1a-\xb8RO\x9d\x05\xc8\x9b.'\xcdZ\xd5\xe5\x90\x10\xfe\x8b\xa4{\xe1\xc7\xe611\x1c(n\xf0}+\xb3\x96<\xc9K\x13m\x1f a\xe5&\x0b\xa8+\xdd\xe8V\xfb\x82\xb6\xd5\x19\x18\x85\xe05\xb0/\\4-U\x99\xcf\xc4\xf7lP\x00 \x8b\x82\xd8\xd8\xb4\x8c\x10t\x17\x1fQ+[\xc5\xefZ\xb1\x1cmK\x9cv\x8a~\x11d/\x99\x1f\xe4\\\xc2\xc4Eva\x13o\xb9\xca\x05\xd1\xb3\xf0\xcd\x14\x877\xe6_\xa6Vf\xce\xdd\x9c_\xa8fy-\xb9\xb5\x92\x05\xb8\x04\xd6\xeez]\x84\x082\x14k~\xfcr5{M\x15\xec\xae\xb7\x0b\xb5\x99\xa39\xb7\x17\xa5\x1a\xca\x97qdS\x1c\xf4z\xf52\x87\x0b\x17\xbf\xc6\xf1\x80\xca1\xa5\xa0\x9a\xdf+ \xe2\x8f\xc8n\xe9!k\xd8\x80\xb6\x15J\xdbu\xe1\x0e\x80e\xf5+\x176G\xe2\x0e\x89\n\x95\x8b/\x99XS\x95[\xf3\xb0Zo\x11r,}\xe1\x16A\x8d\x97\x16\xe2\xc8\xc7\x1f\xdfBwj\xc5\x95i\xc3V5n\xec\xd1>\x1a\xc1\x89G\xa2\xb0B\xef\xe2;\x16\xd5\xd6q\x937\xed[J\xfb4\x8c}\xe1:\x98\xdc\xdcj\x89\xe5*n\xfe=\xe9!\xc1\x189\x92\x92\xaf\xd9?\xb8>J\x84\x15\x99\xa2\xb4\xf5bE\xb1\xd7\xb6\xba:\xa5\x92l\xd4\xab\xb4Q\xab\xba\x95b}\xd5\x19`S\xcc\x17\x8f\xfdc\xdc]M \xcef\xa4\x15)\xd6x\x13E\xb2\xed%9\xae\x11\xcd\xc5t\xdfD\xac\xd7\xc6U\xbc~Q\x16\xe3\xce\x04\x9a6\x94\xe8\xd5\xd8d\x12 \xbc\xc5i\x95\xa8\xf4k\xffL\x99\xd2\xe6q\x9b\xf5\x89\x88\x0c)\x00\x0d\xe9/<\xe6\xc8f\xafv6\xa0a\x0e!\xe2\xc2\x14\xc0\x90\xcd{m\xa0hN\xbf\x8a&\x08\xd1\xc0\xd3Tn\x192\xe4\xbc\xf1\xb7\x0c\xbb\xdaSV\x16\xcek\xe8*K\x8d\xebKSU\xa6\x1c\xff\xf5\xa6\xa9VP\xafNS\xb5\xf8&(T*\xec\xd4GRT\xf3\x94\xd3\x8aa\xc8\xfd\xb3\xcc;\x96\xc1\xd6;sZ\xb1\xbd\x98f\x86_\xdd\xc8\xeamw\xca'\xcb\x93\xd7\x81~\xb1~\xa4\xb0\x10\x97~\x05:\x0f5\xfc\nt\x1e\xe2&\xeb\xe3W^\xd0\x02\xde\xce\x05B\xe7\xe1\x85\xbb@\xa9\x92i\xc8\xa2>/\xdc\xcc\xbc\x19P\xf5if@\x93'\xf6\xe8&\xa0\xdc\xa0\xbf\x85\xd1\xb5Z\x9f\xb7\x9cqZd\xae\x1d\x82\x07^8\xaea\xb2c\x88\xb8\xd9\x9b\xd9\xce~n\xd9l\xc7\x8c~\x15\xa6;\x8d\n\xd4\xe7;2p\xdf\x89\xb9 H\xc8\xe8\xceW\xfe\x1f\x99\xdc\x1eA\x8c\x91\xcfm\x8f\xfc\xcbj\xc3F6\x8d_~\x8b\xb4vL\xbf\x89\x05\xb7$l5\xa5-\xbf\xc2\xe4\x9d\xda\x10\x97q\xd2D\xdf\x85l\xd1&\x89q\xa7\xdfa\xda]\x0e\xbcY\xb2\x9dOi\\\xde\x1a3\xb0\x15-K\xb5\xca*\xeb\x1ew\xfc\xe2R\xeeE\xba_\xba\x1f$a\xfd4\x9a\xe4A]\xb0:qp\xf2$]\x91P[\x0dT\x05\x99\xa5\xf7F$x\x86tZ>+\xd8\x84\xad\xb9\xecd=\x1e?\x8b\xd1i-Y\x933\x14\x0b2\xfe\xaa\xbe\xbd\xa0t\x7f\x81\xec7+a\x0b\xf6f%j h\xc8c\xdd\x86C-\x04\xafx\xeb`\xdd\x97O\x8d\xad\xae\xd5\"\xc8*Y\xae\xda\xb6\x17\x93)\x7f[<\xd9.\x9e,<\xda\xcbO\xdd\xb7d\x02_c\xee\x7f\xdd-\xe07\\\xe2\xd6\xb0\xa1\x16\x19lU\xa3^T\xfa\xfa\xcd\x96\xb6hK\xdf\xf2\xe9o\xe6\x10\xbcfs\xe8\xf8\x84\"\xdb|`\xd68n\xf1f\n\xbf\x0bS\x98\xcd\xfb\x0b5\x84\xdfB\xf5\x9fEq\xed\x03\x99\\\xfb\xb8\xd1\x9b\xfa~G\xea\xfb\x9aB\x99\xb7\xe4\xd670hk\x1f\xcb`4c[\x94\x8b7v\xd0V\x88\x9c\x89\xec\xad\xe2\xa0\x1a4c \x81Hn4\x8b\x9b\xbe\x15\x11\xa4\xcf\x1aY\xbc\xb6\x05_\xa7\\/@\xd4Y\x081\x1d\xa0\xaa\xb3\x04\xee\xe3&\x80\x91\x07\x94\xc8\xe3\x9b\xc7\x7f\xe1\xf2_\xed\xf1\xf3s\xfe\xc2]=\x1c\x93\x08\x1b\xfda\xcd]?}\xa1N\xee\xe2\x04\xf9\xc4N\xa0\xdeN%%Q\xa8;\x8aA\x82\xe4\xab\x93\xda\xb6`\xeb\xee\xba\xa1\xf3\x80\x18\xdd\x89\xf9Za\xb0>\xc6\x17\x8aJ\x88\xf8\xed\xfa\x18,\xbd\xc6\xe5\x89~\xe1\x1a'\x07a\x89\xe3V4\xd6\x86\xb2\x1a\x0dlOi\xb5\x11\xf4\xba\xc7\xce\x8d\xd4\x87FA\xe0\xcfw\x18a\xb0\xe2\xf6\x9b{\xfe\x1a\xc8\xb6\x80\x0c\x80C<,.\xed\x15w|\x8d\xa0g\x12\xfa;\x01R_y\x9e\x87\x7f\x82\xb8\x16\x19\xb8\xf3U\xdc\xf5\xe1a1\x9e\xfa\xd7|\xaa\xd0\x1bZ2\xb87\xd173h\xbf\xd6\xa1(\xee?\x82\x8c\x8c\xad\xe7=\xbd\xfe\xcd1\xd0\xb1\xae\xf3\xafe\x83\x8d\xc72\x0d\xb4\x89\xb4(\xb2\xc7!/F\xc8y\xb8\x9f\xc9\xbb\xb4$\xaa\x92U.[c\x87\xb8J\x10\xa0\xb3=.d\xb0\xd8\"7\xf2!\xa4\xbd\x88\xaa\xb7\xb4\xe8\xd0\xf0VS\x88\xd9\xa2v\x1e\x1e\x90\xca\xee|2\xac|\x9f\x97\x19\x9d\x11/\x19o\xad:\xbf\xfft\x0b\xbd\xf8\x10\xb8D\xbeU\xa6\x81\x8e\xca \xf1\xbf\n\x85\xfc\x7f\x8a\xfc\xe1s\xdc)\xb3\x03\xecv\xb2\xdf\xc5\xf0\xc5\xffj\x87\xb3\x0567\x8b\xff\xb8D>\x8f\xfe\xde\xa6\xfe\xf9\xa6\xfe`M\xa6\xdep\x93\x9e\xbd\x08p\x9b\xd1c\xcaq\x03\x86\xaf\x03\x14\xd3\x92\x10\xe1J\xb1[\x0c]\x90\xcf\x04~\x04\xe9h\x01\xe4/\x90\xa6\xa7t\x17\xc3\xa5\xa2\x00\xc99\xb3\x1e\xf9\x03\x9aW\x8aR!IZh\xf1\x81\x0e\xd5\x9e\xd2\xdf\xcf\xd4\xcb\xd2KXs6\xbd//uE\x98K\x94\x9b\xbb\xc40\xf5\xa6\xf2V\xd6]\x17\x05\x0f\x07\xfbN\x04\xbf\x0c\x1f\x9e\x10<|\n\x86\x0f\x8f{\x87\x0c\x7f\x99\xbaO\x93}8p\xf6\xdc\xee\xd1\x06\xc8.\xc1^ \x1d\xb5o\x87\xe5\xd1\x85\xf5\x84\x14\xae5\xd3z\xd8\x94 \xca\xe0C\x12\x94\x14\xd7\xdc\xd5\x90\x9b\x07\x1d.Q\xbf\xa4\xc2Wj\x9e6\xbd\xba:\xb8\xde\xdb\xef\xecw\xf6\xf6/\x0e\xba\xfb\x07\x9d\xdd\xc3\xee\xc9\xf9\xc1\xe1U\xe7\xf2\xf2b\xef\xf8\xfa\xec\xf2\xf0`\xf7\xba\xb3\xbf\x01\xc0\xfdL$g\xad\x07\x9b\x97\xfd\x05\x14_v\x8e\x0fv\xf7\x8e/Ov\xf7NN\xf6NvO\xba'\x07\xd7\xd7\xfb\xe7\x9d\xb3\x93\xdd\xce\xd1\xf5\xeeu\xf7\xe2\xf2\xaas\xb9wtv|tq\xd59\xdc\xdf\xbf\xea\xee\x1e]\x9c_\xef\x9d\xef\x9f\x1c\x1e\x1cVkP\xe1\xa6\x83\xb4\xdb\xbd\xc3\xe3\xf8\xc7\x85\n\x9e[8\x84\x8a\x05\x02:n\x00\xe3\xaa0g\xde\x81\x891z\x7fR\xd1\\\xe5e\x97\xdb\xdb\xcef\x01Y\xde\x85\xd9\xa2:\xdc;\xd8W1\xe5\xcd50x P\xeb\x9e\xcc\xcc\x13\xdd\xc2!\x0f\x19\x91+$\xed~F\xad\x85M\xac%z\x8eNKL\x93\x9f\\q\xd1\x08(\x80C\xd4\x93\x8d\x1a\x81*\x8bG{H\xdf\x1b{\xd6\x94\xee%.\x97\xcdZ\x89\x17b\xf5\xe7\xd3$t\xc1zj\xc6\xb4\x14\xd04\xe9\xff\x03\x1d&\x828@%\xafe\xa5{C\xa8\x95\xdd\x92\x06\xe82\x9c\xcb\x8b\xb9\x9a\xd5\x1c\xa3qu\x14H\xbd!\x86,\n\x9b\x0dT\x03m\xe8G>\xa9\xd0|\xb8\xfa\xe3\xe2\xe6\xf7\xcbNw@/oCx\xfc\x81\xf5?\xd2\xf9\xf9\xee\xf4\xa8\xffx\xff\xe1\xe0\xe0\xcfhw\xef\xf8\xe9\xf7\xfe\xb5\xf3\xe7l\xff\xef\x17\xd7\xf3\xb3\x9b!:\xf8\xf3\x9f\xb7\x83\xf77\xd1\xe4\xe9\xfc\xaf\xc3\x93\x0f\xf3\xc7_\xe8\xe3\xe5\xf1\xdd\xee\xcd\xd4\xbb\n\xfe\xee\xfd\xd1?\xfct\xe72?\x18\xfe\xfb\x1fJ\xafA\xd4\xef\xe5\x02\x14`\x1a#\xa8L\xb1 \x90\xc2o\x15C\x059\xfb\xc6\x10vQ8\xf60\xdb\xb9\x8d\xfa\xef\xd1\xfc\x0e9A\xf7\xe0\xf0a\xb7\x98\xc92l([\xf6s6y\xea\xec\x7f\x1a\xb1\xf7\xbf\x8e\x8e\xcf..>=\xf97\xc7\xf0\x9e\xd0\x9f\xe7\x1d\xef\xe1\xfa_\xefo>\xfd\xf2\xfb\xde\x97\xf7\x1fBB\x7fQ{\x86\x8e\xb0N%KS\xd9u\xd6m\xce $\xfb\xa9\xcd\xb0\x9c\xfb\xc4y\xb8\xb9\xb4\xd6\xfa\x9a\x91o\x00CV2SV\xb2^\xb0\xa4\xc0d\x18\x81:\xa6\x8e\xf2s\x9eR\xb0\x88Z\xc1\x88_\x94\x93\xd6-\x98!\xd2}\xb9\x0f\x8e\xaa\xc3!\x19\x8b\x8e\xa2\xfeV7ag\xad\xb8&q\x18\xcc\x1b\x9b\xe3\xfb\x02\xccf\xb7\xb3{\xb4\xb5\xdb\xdd\xda\xeb\xdcw\x0eN\x0f\xf6N;'\xdb\xdd\xe3\xa3\xbfwvO\xb3h\x02G\xe3\x9e\xc6\xa1\x98\x08I\xf8\xecC\xcaz\xe2\xd2\xda\x1c\x17\xf4Ip)iI\x8f\xd2\xb3\xd7\xe8s\xef@\xedT\\\x9d\xcfz5\xc5\x91\xafv\xeb\xc2\xa4\x97\xb5\xd3\xba\x90\x18\xcdX\xaf9\xb8r\xd2N=@\x18\x04uA\x04Oe\xf8[\xbb\xbb\xe4h\xf4\xbapAre7TW|F\xd0x]\x98NK\xf1;\x95\x1a\xb6EHl]{\xb9\xab\x1a\x17\x18\x04u\xe1;\x89\x91\xb16/\xc5{\x1f\xccj\x95\xbf\xf4\xa1~d\xa8\xa1\xbe|\xe0}SL\x8a\xbe6\x9f\xad\xd2g\x9d66F\xe2D\xb2\xefe\xd67\xc6\xf8\xa5\xba\xd0-\xd5\xfd\xb2\x88gOe\xa8\x91a\xf0\xb0\x8b4Gk.\x807F\x0d\xf21\xed\xe3-\x875$\x11\xd6|\x84\xbb\x1cR\xee\xf3(\x83\xe3`)\xc4V\xce\xb0\x80\xd7\xd8\x9f&\x12\x91O\xda_\xb7\xf4R/\xcc\xf2\xb1\x15i\xf9\x18\x16\x03\xf2\xb1f\xc8Qt\x7fq\xb4\xff\xbb\xff\x80\x1f\xff\xfd\xe7\xd5tx\xf4 \x1f~8\xfem|t\x1d\xfd\xd5\xb9\xfam\xbf\xffe\x12}9\x0c\xa7\xbf\xec\x8e\xef\xff\xf85\xfc\x18}\xf8\xf0\xd7\xe4\xec\xec\xf1\xfe\xe4\xd3\x97\x7f\x0eo;\x1f\xcfv\xee/\x83\xc3h\xe7\xa4{\xf6\x18\xfe5\xf8\xd7\xafw\xc1\xf9\xef\xff\xf8G\x1aR\xd5K.I\xf6\x8cQ9woe*t7\xe5\xd8ZM\xb0\x94\xa9)\xb8\x143\xc8\xa6\xdc\xf5@C\xb1\x85\x16\xffE\xc2\x8fh\nC\xd7\x9aO\x15\x96E\xdbu1\xbb\x9a\x90\x1d*\xdd\x02[\x1b_\xb9\x0cNG$6L\xe5\xb0\xa8\xf5\xb8B\xb5\xfdr\x04\x19\x99\x9c\x8b@\xdb\xe8)\x19z\\\xe6a=\xd8Ah\x9f5\xde\x8c\xf3\xe9\xc3\x138\n\x0fg\xa3\x11;\x08\xc7\x8f\x13\x84\x0f\xbb\xc7\xf8\xc1\x9f\xf9\xd1\xd3|r\xfct\xf2\xe5\xf1\x8b3v2\x99\xce\xe5\xcb\xef\xc4\xb28\xc9\x93\x03\x12\x82\xf7h\xde\x87\x14\x89Mw\xc0\x08\x18\"\x8cB\xc8\x10\x80@\xd4\x0c\x9e\xf6\x87\xdd\xf0dH\x83\xc7\xe1\xe1\xf0\xc4\xa1{\x0f'N4\x88;\x99\x10\xe6\xe1a/ \xd3\x1a\xa2\xbe\xabH^\xba\xe4\nB\x8f\x84\x1e\xb3\x1eS\x8a\xe5\x1e\xcd\xd8\xad\xc0\x92\xd8N\x0b\xf6\x071\x80F\xd5\xf3\xbb\xe8\xccc~\xb5*\xaabV\xd5.\xed2\x1f\xc2U\xb5\xa4\x0c\xb2\xa8Z\xa7\x07\x1e\xe6(\xa1\xef\xcf{\xc5\xcd\"}v\x9d7\xcd\xef\x1dSq7Zoa\x0eG&H\\\x14\x10Z^8-\xab\xec\xb1$Q\x06\xc3\x05\xa4\xdc\xc6\"\xd3\xc6dk\xf8^!\xc8\x97\xea\xd0-:\xd6o\xa6.\xcb)\xdb\xe1\xc4\x13E\x16\xad\xd7\x15\xdb\xa2\x08\x87\xf5 \xe7e\xc3ovr\xdb\x9d\xf4I\xfde\x9f2\xe8U\xeb\xce\"\x1c\xd8>\n\xd0\x83\xf7\xb8\x85\xefM\x10k\x8e\xe8\x13I<\x95\x05\xd3&\x84-0\x98\xb6\xb3L\xaa-O}\xcf\xc4\xff\xddB\x1c\x9f\xe5\n\x83\xa8\xbf\x16\xbe\xea\x0b\xf4\xfcr\xd1T>\x98\xd0[\xdc\x82K \x0f\x08W\xcb\xbc\x9b\xc4\xf7=:\x82\xe1\x02\x05\xa9p VK\xcc1\xc1\xde\x83\xe5\x9e\x8d\xe7\"\xccr^\xb6\xa2\xf1\x14\xf5\xa9W\xbc\xb9\xd9\xd0\x96\"'\xe2\xee\xbb\xe7\x10\xcc\xa0\xa3\xdd\xd3,\x01\xb9\x88A\xcf\xa7\x0b\xdb\xf6 vK_G.R\xcfM\x15\xd8\xc3,\x84=6\xeb\xc5'\x0bU\xcf\xb0f_!\xc2\x1c\x0f\xf7PM\xe9\xc80,t\xb4\xb90\xe7\xe4\xa8\xb3\xd5\xd9\xdd\xea\xec\xdew:\xa7\xe2\xff\xff\xcatl<\xf6h\xe3\xa4sX\xba\x96\xdb0O\xc6D\xd8\x18\xcez\xed`qF\x10\x0fQ\x0b\xc8\xe4\xd5\xd6\x05\x1e[\"2\xf1:[\xb8[[\xd1\xcc\x02\x94\xcc\xa8\x86\x90\x8a\xe4\x89\xa6\xb5\x85M\xe9C\x1f\xe6\xd6\x90\x95Q\xc5\x1f\x89hf\x03\xadU\xfe\xb7\xca\xc1\"\xccB\xaf\x9d\xb5e:\xcc+\x8937\xf4+\xb5\x1f\x8b1\x0b\xac\xd0\xef\x958m3\x1b\x9a6N\x88\x04\xe3m\xec\xcb\xd8\xc3\xd5FD3\xa1\xd6\x03[\xe5d>3\xd3\xf2V\xdd\xc4\xb5\xac\xd5G\xe4>\x1f\xbfh\xe8\xd4\x84p)\xb3\x82hQeT\x8el\x168\xc45\xc6>\x8f^k\xaa\x1c\xc2-\xb2h^=c`\x05B%\xcd+\xe7\xb6\xb1Y\x1a\xf4^z\x94\xdd\xa4\x85\xf6\x16lh)\xba\xa6\xc8\x1f\xf4Dd\xd3b~:\xb7\x1c\x17E\x8e\xa6\xf0b\x19\xec\xb7Q\xdf\xf7\x9c\xf7\xc8^tD\x93\xaa\x19\xab./\xbf\xf3\x86\xd8\xc3\xc3Z\xd3$\xd3\x10\x16\xa6Xl\x82\xf6\xc8`@QuC\xb9\xfa\xe8E\x98y\xa5\x14\x7f\xc1\xb8S\x8a\\Y\xc3BM\xf1j\nq\x0bC8\xbe\x10\xc1\x93\xfd\xe0\xa2>\x0d`\x8d\x0c3e\xf0\xc1\xc3iUd\x8d\xd5\xdc\xe6\x078Ke\x98* \xa7:86\xab\xa69\x1d\xa9\xfc\x9a\xcd\x9a \xad\xef\xb5\xdc\x9c_\xd4_l/g\x05\x0ci`\xab\xe0?\xafT\xc04\x0b\xdazD\x9d\n~\xfbD\xf0E\x92q\xb8c\xb0F*\xc6j\xcb\xc7\xc6i\x85\x84,J\xbe~$$\xcd\xba\xe6k\xb1z9\xfbQ-\x05w\xf2\xab\xeb\x8fi\x7f\x16\xa3lfC\xad$\xa9\\\xd6X\xb4Q\xca%\xac\xdf\x96\xd4\x07\xa4\xbf\x12\xb6\xd0\x89\xcaik\xb2\xb3\xb2\xba6\xac\x8ajM\x8a*\xb2@N\x8a\xa0\xf2\x12\xf8zJ\xb1@\x1d\x06!yB\xa5\xa8 K\xa5\x89O\xf4\xad;\x0b\xb2\xd6Z\x08=\x14\x10\xd1\x14\xd5M\xe4jk\xa8\xca\x96S\xf9\xbdl?\xe5S*@\xb7\x80\xc9\x7f0j\x04\xbaP\n\xd9,\xb8\xdd\xac8VW\xb4f%\xdd\x06&\x9b\x18\xbc\xb0@\xcd\xc8\xb1\x05\x85i\x15\x9c6d\x92L\xc5hM0i\x0b\xd0\x9a 2\x16\x9dY!\xabQl\xa6\x93r\xd9\x87\xb6\xc8,\xed#_`f*.\xb3\x119\xf9\x18\x8b\xca\xac\x06\xbc\xcab2\xbe\xae@n\xcd\x02\xfd\xa6\x15\xb4\xc5jUC(\xca\x1bq\x90\x9aT\xad\xd0\xe5\x96\xb9\x94<\xda!\xa8\xcdUA0\x04JF<\xc5`)y\xaa\xa2.kd\xd9\xa5\x9b\xc9\x15o\xd6\x9c\xce\xae\xb4Y8\x97IC\xc5\xfd\xabnR\x0b\x95;\x1bG\x9e*\x19@\xb6\xa8\x06^@\xddB6\xcaC.\nz/\nc\xb1\x18>e\x9az\x9e\x9c\xa49\"ZY\x14\x8f\xab\x17DX3\xf2B\x01J\xd7\x94\xa5\x0b\xfdkx5\xc5\x05\xeb\xfa\xb0\xe6\x8a\xed\x98\xd3\xdb\x90\x16\x162\xe4C\xdc\x1a\xeaj\x19!\xa7\x12c=F\x818'\x8a5\x18m\x1d>\x88\xa3zr\xbfT8\n\x84\x1d}[E\xc4\xc5\xccd\xd3K\x97Px1\xfc%\x05\x0d\xac\xa5\x1d\x90\xa7\xc5\xd5g\x8d\x84[\xa4\xbf\xb2\xd5\xfaZAu\x14\x16\xa3^l\x02\xc5Ei\x1e\xae>\x9d\xa5\x96\x05,\xdb=\xe3\xd5jM\xa5\xd2\xf0\xf5Sf\"%\x9b\x1a\xd9\xc7\xd2Ml:~H\xfcU\xcdn\x95\xd3\xed,z\x15M\xaa\xbal\x1e\x14U}![\xbe\xa6\x9e\xc7\xfc$\xd2\x96T\x94\x1b\xcb\x93(\xc5\xe5u:\x80\x92\x19\x8c\xdb\x97t\xb1\x02\xc4E\x94\xc5\x07n\xd9\xf7\xa3\x02\xd5\xea\xac\xb4\x08.4\xfc\x01\xdc\xffv\xf9\xdb)\xb8\x8c\xe4ae\xe8\x13a\xe8*\xfeVl\x03\xe8\x7fW\x85 \xc5\xa4{\xf9\xad$\xa4\x82\xea\xe4\xd1\xea\xba\x16N\x0d\x80\xcb\xe9N`f\xfe\x04\xfa\xc5\x94.\xa8\x12TQ \xba\x10\xe0\xbf\x02\x00\x00\xff\xffPK\x07\x08+\x96\x8a\xd7X(\x00\x00\xf2\x83\x01\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xd4`4t\xc7\x01\x00\x00\xbd\x01\x00\x00\x11\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00favicon-16x16.pngUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(6B\xc8\xd7\x7f\x04\x00\x00u\x04\x00\x00\x11\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x0f\x02\x00\x00favicon-32x32.pngUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xb9\xb1\xf1mT\x02\x00\x008\x05\x00\x00\n\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd6\x06\x00\x00index.htmlUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(]\x12r 9\x03\x00\x00T \x00\x00\x14\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81k \x00\x00oauth2-redirect.htmlUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(-\xe3\xb5\x97=9\x05\x00\xf7\x0c\x1b\x00\x14\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xef\x0c\x00\x00swagger-ui-bundle.jsUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(v\xf2\x8aA\x86\xba\x01\x00\xc5\x87\x08\x00\x1f\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81wF\x05\x00swagger-ui-standalone-preset.jsUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(_;\x94/\xe8Y\x00\x00\xa8X\x02\x00\x0e\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81S\x01\x07\x00swagger-ui.cssUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(+\x96\x8a\xd7X(\x00\x00\xf2\x83\x01\x00\x0c\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x80[\x07\x00swagger.yamlUT\x05\x00\x01\x80Cm8PK\x05\x06\x00\x00\x00\x00\x08\x00\x08\x00E\x02\x00\x00\x1b\x84\x07\x00\x00\x00" fs.Register(data) } diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 23298942e0d3..1f0230591e2e 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -21,6 +21,8 @@ tags: description: Slashing module APIs - name: Distribution description: Fee distribution module APIs + - name: IBC + description: IBC module APIs - name: Supply description: Supply module APIs - name: version @@ -1876,6 +1878,931 @@ paths: type: string 500: description: Internal Server Error + /ibc/clients/{client-id}/consensus-state: + get: + summary: Query cliet consensus-state + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + type: object + properties: + consensus_state: + $ref: "#/definitions/ConsensusState" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/clients/{client-id}/client-state: + get: + summary: Query client state + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + type: object + properties: + client_state: + $ref: "#/definitions/ClientState" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/clients/{client-id}/roots/{height}: + get: + summary: Query client root + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: path + name: height + description: Root height + required: true + type: number + x-example: 1 + - in: query + name: prove + description: Proof of result + type: boolean + x-example: true + responses: + 200: + description: OK + schema: + type: object + properties: + root: + $ref: "#/definitions/Root" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + 400: + description: Invalid client id or height + 500: + description: Internal Server Error + /ibc/header: + get: + summary: Query header + tags: + - IBC + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/Header" + 500: + description: Internal Server Error + /ibc/node-state: + get: + summary: Query node consensus-state + tags: + - IBC + produces: + - application/json + responses: + 200: + description: OK + schema: + $ref: "#/definitions/ConsensusState" + 500: + description: Internal Server Error + /ibc/path: + get: + summary: Query IBC path + tags: + - IBC + produces: + - application/json + responses: + 200: + description: OK + schema: + type: string + 500: + description: Internal Server Error + /ibc/clients: + post: + summary: Create client + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Create client request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + client_id: + type: string + consensus_state: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/ConsensusState" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/clients/{client-id}/update: + post: + summary: Update client + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: body + name: "Update client request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + header: + $ref: "#/definitions/Header" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/clients/{client-id}/misbehaviour: + post: + summary: Submit misbehaviour + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: body + name: "Submit misbehaviour request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + evidence: + $ref: "#/definitions/Evidence" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/connections/{connection-id}: + get: + summary: Query connection + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: connection-id + description: Connection ID + required: true + type: string + x-example: ibcconnectionid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + $ref: "#/definitions/ConnectionResponse" + 400: + description: Invalid connection id + 500: + description: Internal Server Error + /ibc/clients/{client-id}/connections: + get: + summary: Query connections of a client + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: client-id + description: Client ID + required: true + type: string + x-example: ibcclientid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + $ref: "#/definitions/ClientConnectionsResponse" + 400: + description: Invalid client id + 500: + description: Internal Server Error + /ibc/connections/open-init: + post: + summary: Connection open-init + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Connection open-init request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + connection_id: + type: string + client_id: + type: string + counterparty_client_id: + type: string + counterparty_connection_id: + type: string + counterparty_prefix: + $ref: "#/definitions/Prefix" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/connections/open-try: + post: + summary: Connection open-try + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Connection open-try request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + connection_id: + type: string + client_id: + type: string + counterparty_client_id: + type: string + counterparty_connection_id: + type: string + counterparty_prefix: + $ref: "#/definitions/Prefix" + counterparty_versions: + type: array + items: + type: string + proof_init: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_consensus: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + consensus_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/connections/{connection-id}/open-ack: + post: + summary: Connection open-ack + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: connection-id + description: Connection ID + required: true + type: string + x-example: ibcconnectionid + - in: body + name: "Connection open-ack request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + proof_try: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_consensus: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + consensus_height: + type: integer + version: + type: string + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid connection id + 500: + description: Internal Server Error + /ibc/connections/{connection-id}/open-confirm: + post: + summary: Connection open-confirm + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: connection-id + description: Connection ID + required: true + type: string + x-example: ibcconnectionid + - in: body + name: "Connection open-confirm request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + proof_ack: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid connection id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}: + get: + summary: Query channel + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: query + name: prove + description: Proof of result + type: boolean + x-example: false + responses: + 200: + description: OK + schema: + $ref: "#/definitions/ChannelResponse" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/channels/open-init: + post: + summary: Channel open-init + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Channel open-init request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + port_id: + type: string + channel_id: + type: string + version: + type: string + channel_order: + type: string + connection_hops: + type: array + items: + type: string + counterparty_port_id: + type: string + counterparty_channel_id: + type: string + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/channels/open-try: + post: + summary: Channel open-try + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Channel open-try request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + port_id: + type: string + channel_id: + type: string + version: + type: string + channel_order: + type: string + connection_hops: + type: array + items: + type: string + counterparty_port_id: + type: string + counterparty_channel_id: + type: string + counterparty_version: + type: string + proof_init: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/open-ack: + post: + summary: Channel open-ack + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Channel open-ack request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + counterparty_version: + type: string + proof_try: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/open-confirm: + post: + summary: Channel open-confirm + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Channel open-confirm request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + proof_ack: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/close-init: + post: + summary: Channel close-init + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Channel close-init request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/close-confirm: + post: + summary: Channel close-confirm + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Channel close-confirm request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + proof_init: + type: object + properties: + type: + type: string + value: + $ref: "#/definitions/Proof" + proof_height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/next-sequence-recv: + get: + summary: Query next sequence receive + tags: + - IBC + produces: + - application/json + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + responses: + 200: + description: OK + schema: + type: integer + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/ports/{port-id}/channels/{channel-id}/transfer: + post: + summary: Transfer token + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: path + name: port-id + description: Port ID + required: true + type: string + x-example: ibcmoduleport + - in: path + name: channel-id + description: Channel ID + required: true + type: string + x-example: ibcchannelid + - in: body + name: "Transfer token request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + amount: + type: array + items: + $ref: "#/definitions/Coin" + receiver: + type: string + source: + type: boolean + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 400: + description: Invalid port id or channel id + 500: + description: Internal Server Error + /ibc/packets/receive: + post: + summary: Receive packet + consumes: + - application/json + produces: + - application/json + tags: + - IBC + parameters: + - in: body + name: "Receive packet request body" + required: true + schema: + type: object + properties: + base_req: + $ref: "#/definitions/BaseReq" + packet: + $ref: "#/definitions/Packet" + proofs: + type: array + items: + $ref: "#/definitions/Proof" + height: + type: integer + responses: + 200: + description: OK + schema: + $ref: "#/definitions/StdTx" + 500: + description: Internal Server Error /supply/total: get: summary: Total supply of coins in the chain @@ -1908,7 +2835,7 @@ paths: 200: description: OK schema: - type: string + type: string 400: description: Invalid coin denomination 500: @@ -2530,3 +3457,273 @@ definitions: type: array items: $ref: "#/definitions/Coin" + IBCValidator: + type: object + properties: + address: + $ref: "#/definitions/ValidatorAddress" + pub_key: + type: object + properties: + type: + type: string + value: + type: string + voting_power: + type: string + example: "1000" + proposer_priority: + type: string + example: "1000" + ConsensusState: + type: object + properties: + chain_id: + type: string + height: + type: integer + root: + $ref: "#/definitions/Root" + next_validator_set: + $ref: "#/definitions/ValidatorSet" + Root: + type: object + properties: + type: + type: string + value: + type: object + properties: + hash: + type: string + Prefix: + type: object + properties: + type: + type: string + value: + type: object + properties: + key_prefix: + type: string + ValidatorSet: + type: object + properties: + validators: + type: array + items: + $ref: "#/definitions/IBCValidator" + proposer: + $ref: "#/definitions/IBCValidator" + ClientState: + type: object + properties: + id: + type: string + frozen: + type: boolean + Proof: + type: object + properties: + proof: + type: object + properties: + ops: + type: array + items: + type: object + properties: + type: + type: string + key: + type: string + data: + type: string + Commit: + type: object + properties: + block_id: + $ref: "#/definitions/BlockID" + precommits: + type: array + items: + type: object + properties: + validator_address: + type: string + validator_index: + type: string + example: "0" + height: + type: string + example: "0" + round: + type: string + example: "0" + timestamp: + type: string + example: "2017-12-30T05:53:09.287+01:00" + type: + type: number + example: 2 + block_id: + $ref: "#/definitions/BlockID" + signature: + type: string + example: "7uTC74QlknqYWEwg7Vn6M8Om7FuZ0EO4bjvuj6rwH1mTUJrRuMMZvAAqT9VjNgP0RA/TDp6u/92AqrZfXJSpBQ==" + SignedHeader: + type: object + properties: + header: + $ref: "#/definitions/BlockHeader" + commit: + $ref: "#/definitions/Commit" + Header: + type: object + properties: + type: + type: string + value: + type: object + properties: + SignedHeader: + $ref: "#/definitions/SignedHeader" + validator_set: + $ref: "#/definitions/ValidatorSet" + next_validator_set: + $ref: "#/definitions/ValidatorSet" + ConnectionResponse: + type: object + properties: + connection: + $ref: "#/definitions/Connection" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + Connection: + type: object + properties: + state: + type: string + client_id: + type: string + counterparty: + $ref: "#/definitions/ConnectionCounterparty" + versions: + type: array + items: + type: string + ConnectionCounterparty: + type: object + properties: + client_id: + type: string + connection_id: + type: string + prefix: + type: object + properties: + key_prefix: + type: string + ProofPath: + type: object + properties: + key_path: + type: array + items: + type: object + properties: + name: + type: string + enc: + type: integer + ClientConnectionsResponse: + type: object + properties: + connection_paths: + type: array + items: + type: string + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + ChannelResponse: + type: object + properties: + channel: + $ref: "#/definitions/Channel" + proof: + $ref: "#/definitions/Proof" + proof_path: + $ref: "#/definitions/ProofPath" + proof_height: + type: integer + Channel: + type: object + properties: + state: + type: string + ordering: + type: string + counterparty: + $ref: "#/definitions/Counterparty" + connection_hops: + type: array + items: + type: string + version: + type: string + ChannelCounterparty: + type: object + properties: + port_id: + type: string + channel_id: + type: string + Packet: + type: object + properties: + type: + type: string + value: + type: object + properties: + sequence: + type: integer + timeout: + type: integer + source_port: + type: string + source_channel: + type: string + destination_port: + type: string + destination_channel: + type: string + data: + type: string + # TODO: DuplicateVoteEvidence + DuplicateVoteEvidence: + type: string + Evidence: + type: object + properties: + type: + type: string + value: + type: object + properties: + DuplicateVoteEvidence: + $ref: "#/definitions/DuplicateVoteEvidence" + chain_id: + type: string + val_power: + type: integer + total_power: + type: integer diff --git a/types/rest/rest.go b/types/rest/rest.go index 89770c944650..5414b23abab1 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -375,3 +375,14 @@ func ParseHTTPArgsWithLimit(r *http.Request, defaultLimit int) (tags []string, p func ParseHTTPArgs(r *http.Request) (tags []string, page, limit int, err error) { return ParseHTTPArgsWithLimit(r, DefaultLimit) } + +// ParseQueryProve sets the prove to execute a query if set by the http request. +// It returns false if there was an error parsing the prove. +func ParseQueryProve(r *http.Request) bool { + proveStr := r.FormValue("prove") + prove := false + if ok, err := strconv.ParseBool(proveStr); err == nil { + prove = ok + } + return prove +} diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go new file mode 100644 index 000000000000..d8b77d658c0b --- /dev/null +++ b/x/ibc/02-client/client/rest/query.go @@ -0,0 +1,248 @@ +package rest + +import ( + "fmt" + "net/http" + "strconv" + + "github.com/gorilla/mux" + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc("/ibc/header", queryHeaderHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc("/ibc/node-state", queryNodeConsensusStateHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc("/ibc/path", queryPathHandlerFn(cliCtx)).Methods("GET") +} + +// queryConsensusStateHandlerFn implements a consensus state querying route +// +// @Summary Query cliet consensus-state +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryConsensusState "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/consensus-state [get] +func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyConsensusState(clientID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var cs tendermint.ConsensusState + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + } + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height)) + } +} + +// queryHeaderHandlerFn implements a header querying route +// +// @Summary Query header +// @Tags IBC +// @Produce json +// @Success 200 {object} QueryHeader "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/header [get] +func queryHeaderHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + header, err := utils.GetTendermintHeader(cliCtx) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + rest.PostProcessResponse(w, cliCtx, header) + } +} + +// queryClientStateHandlerFn implements a client state querying route +// +// @Summary Query client state +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryClientState "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/client-state [get] +func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyClientState(clientID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var state types.State + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &state); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + } + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewClientStateResponse(clientID, state, res.Proof, res.Height)) + } +} + +// queryRootHandlerFn implements a root querying route +// +// @Summary Query client root +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param height path number true "Root height" +// @Success 200 {object} QueryRoot "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/roots/{height} [get] +func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + height, err := strconv.ParseUint(vars[RestRootHeight], 10, 64) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyRoot(clientID, height), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var root commitment.Root + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &root); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewRootResponse(clientID, height, root, res.Proof, res.Height)) + } +} + +// queryNodeConsensusStateHandlerFn implements a node consensus state querying route +// +// @Summary Query node consensus-state +// @Tags IBC +// @Produce json +// @Success 200 {object} QueryNodeConsensusState "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/node-state [get] +func queryNodeConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + node, err := cliCtx.GetNode() + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + info, err := node.ABCIInfo() + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + height := info.Response.LastBlockHeight + prevHeight := height - 1 + + commit, err := node.Commit(&height) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + validators, err := node.Validators(&prevHeight) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + state := tendermint.ConsensusState{ + ChainID: commit.ChainID, + Height: uint64(commit.Height), + Root: commitment.NewRoot(commit.AppHash), + NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), + } + + res := cliCtx.Codec.MustMarshalJSON(state) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) + } +} + +// queryPathHandlerFn implements a node consensus path querying route +// +// @Summary Query IBC path +// @Tags IBC +// @Produce json +// @Success 200 {object} QueryPath "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/path [get] +func queryPathHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + path := commitment.NewPrefix([]byte("ibc")) + res := cliCtx.Codec.MustMarshalJSON(path) + rest.PostProcessResponse(w, cliCtx, res) + } +} diff --git a/x/ibc/02-client/client/rest/rest.go b/x/ibc/02-client/client/rest/rest.go new file mode 100644 index 000000000000..fb832f63a69a --- /dev/null +++ b/x/ibc/02-client/client/rest/rest.go @@ -0,0 +1,39 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" +) + +const ( + RestClientID = "client-id" + RestRootHeight = "height" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + registerQueryRoutes(cliCtx, r, queryRoute) + registerTxRoutes(cliCtx, r) +} + +// CreateClientReq defines the properties of a create client request's body. +type CreateClientReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ClientID string `json:"client_id" yaml:"client_id"` + ConsensusState exported.ConsensusState `json:"consensus_state" yaml:"consensus_state"` +} + +// UpdateClientReq defines the properties of a update client request's body. +type UpdateClientReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Header exported.Header `json:"header" yaml:"header"` +} + +// SubmitMisbehaviourReq defines the properties of a submit misbehaviour request's body. +type SubmitMisbehaviourReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Evidence exported.Evidence `json:"evidence" yaml:"evidence"` +} diff --git a/x/ibc/02-client/client/rest/swagger.go b/x/ibc/02-client/client/rest/swagger.go new file mode 100644 index 000000000000..b3f64c566e72 --- /dev/null +++ b/x/ibc/02-client/client/rest/swagger.go @@ -0,0 +1,61 @@ +package rest + +import ( + auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +type ( + QueryConsensusState struct { + Height int64 `json:"height"` + Result types.ConsensusStateResponse `json:"result"` + } + + QueryHeader struct { + Height int64 `json:"height"` + Result tendermint.Header `json:"result"` + } + + QueryClientState struct { + Height int64 `json:"height"` + Result types.StateResponse `json:"result"` + } + + QueryRoot struct { + Height int64 `json:"height"` + Result types.RootResponse `json:"result"` + } + + QueryNodeConsensusState struct { + Height int64 `json:"height"` + Result tendermint.ConsensusState `json:"result"` + } + + QueryPath struct { + Height int64 `json:"height"` + Result commitment.Prefix `json:"result"` + } + + PostCreateClient struct { + Msgs []types.MsgCreateClient `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostUpdateClient struct { + Msgs []types.MsgUpdateClient `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostSubmitMisbehaviour struct { + Msgs []types.MsgSubmitMisbehaviour `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } +) diff --git a/x/ibc/02-client/client/rest/tx.go b/x/ibc/02-client/client/rest/tx.go new file mode 100644 index 000000000000..50f9a38b022f --- /dev/null +++ b/x/ibc/02-client/client/rest/tx.go @@ -0,0 +1,164 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc("/ibc/clients", createClientHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/update", RestClientID), updateClientHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/misbehaviour", RestClientID), submitMisbehaviourHandlerFn(cliCtx)).Methods("POST") +} + +// createClientHandlerFn implements a create client handler +// +// @Summary Create client +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.CreateClientReq true "Create client request body" +// @Success 200 {object} PostCreateClient "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients [post] +func createClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req CreateClientReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgCreateClient( + req.ClientID, + req.ConsensusState.ClientType().String(), + req.ConsensusState, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// updateClientHandlerFn implements a update client handler +// +// @Summary update client +// @Tags IBC +// @Accept json +// @Produce json +// @Param client-id path string true "Client ID" +// @Param body body rest.UpdateClientReq true "Update client request body" +// @Success 200 {object} PostUpdateClient "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/update [post] +func updateClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + var req UpdateClientReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgUpdateClient( + clientID, + req.Header, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// submitMisbehaviourHandlerFn implements a submit misbehaviour handler +// +// @Summary Submit misbehaviour +// @Tags IBC +// @Accept json +// @Produce json +// @Param client-id path string true "Client ID" +// @Param body body rest.SubmitMisbehaviourReq true "Submit misbehaviour request body" +// @Success 200 {object} PostSubmitMisbehaviour "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/misbehaviour [post] +func submitMisbehaviourHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + var req SubmitMisbehaviourReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgSubmitMisbehaviour( + clientID, + req.Evidence, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/02-client/module.go b/x/ibc/02-client/module.go index 3df05cdfbdf2..9e5ddbd7dbd5 100644 --- a/x/ibc/02-client/module.go +++ b/x/ibc/02-client/module.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/rest" ) // Name returns the IBC client name @@ -17,8 +18,8 @@ func Name() string { } // RegisterRESTRoutes registers the REST routes for the IBC client -func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { - // TODO: +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router, queryRoute string) { + rest.RegisterRoutes(ctx, rtr, fmt.Sprintf("%s/%s", queryRoute, SubModuleName)) } // GetTxCmd returns the root tx command for the IBC client diff --git a/x/ibc/03-connection/client/rest/query.go b/x/ibc/03-connection/client/rest/query.go new file mode 100644 index 000000000000..f40bbfd2eba6 --- /dev/null +++ b/x/ibc/03-connection/client/rest/query.go @@ -0,0 +1,102 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + r.HandleFunc(fmt.Sprintf("/ibc/connections/{%s}", RestConnectionID), queryConnectionHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/connections", RestClientID), queryClientConnectionsHandlerFn(cliCtx, queryRoute)).Methods("GET") +} + +// queryConnectionHandlerFn implements a connection querying route +// +// @Summary Query connection +// @Tags IBC +// @Produce json +// @Param connection-id path string true "Client ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryConnection "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid connection id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/{connection-id} [get] +func queryConnectionHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + connectionID := vars[RestConnectionID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyConnection(connectionID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var connection types.ConnectionEnd + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + } + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height)) + } +} + +// queryClientConnectionsHandlerFn implements a client connections querying route +// +// @Summary Query connections of a client +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryClientConnections "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/connections [get] +func queryClientConnectionsHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyClientConnections(clientID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var paths []string + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &paths); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + } + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewClientConnectionsResponse(clientID, paths, res.Proof, res.Height)) + } +} diff --git a/x/ibc/03-connection/client/rest/rest.go b/x/ibc/03-connection/client/rest/rest.go new file mode 100644 index 000000000000..ed8e97b69280 --- /dev/null +++ b/x/ibc/03-connection/client/rest/rest.go @@ -0,0 +1,62 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +const ( + RestConnectionID = "connection-id" + RestClientID = "client-id" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + registerQueryRoutes(cliCtx, r, queryRoute) + registerTxRoutes(cliCtx, r) +} + +// ConnectionOpenInitReq defines the properties of a connection open init request's body. +type ConnectionOpenInitReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ConnectionID string `json:"connection_id" yaml:"connection_id"` + ClientID string `json:"client_id" yaml:"client_id"` + CounterpartyClientID string `json:"counterparty_client_id" yaml:"counterparty_client_id"` + CounterpartyConnectionID string `json:"counterparty_connection_id" yaml:"counterparty_connection_id"` + CounterpartyPrefix commitment.PrefixI `json:"counterparty_prefix" yaml:"counterparty_prefix"` +} + +// ConnectionOpenTryReq defines the properties of a connection open try request's body. +type ConnectionOpenTryReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ConnectionID string `json:"connection_id" yaml:"connection_id"` + ClientID string `json:"client_id" yaml:"client_id"` + CounterpartyClientID string `json:"counterparty_client_id" yaml:"counterparty_client_id"` + CounterpartyConnectionID string `json:"counterparty_connection_id" yaml:"counterparty_connection_id"` + CounterpartyPrefix commitment.PrefixI `json:"counterparty_prefix" yaml:"counterparty_prefix"` + CounterpartyVersions []string `json:"counterparty_versions" yaml:"counterparty_versions"` + ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` + ProofConsensus commitment.ProofI `json:"proof_consensus" yaml:"proof_consensus"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` +} + +// ConnectionOpenAckReq defines the properties of a connection open ack request's body. +type ConnectionOpenAckReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofTry commitment.ProofI `json:"proof_try" yaml:"proof_try"` + ProofConsensus commitment.ProofI `json:"proof_consensus" yaml:"proof_consensus"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` + Version string `json:"version" yaml:"version"` +} + +// ConnectionOpenConfirmReq defines the properties of a connection open confirm request's body. +type ConnectionOpenConfirmReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} diff --git a/x/ibc/03-connection/client/rest/swagger.go b/x/ibc/03-connection/client/rest/swagger.go new file mode 100644 index 000000000000..c8620ba41d6a --- /dev/null +++ b/x/ibc/03-connection/client/rest/swagger.go @@ -0,0 +1,46 @@ +package rest + +import ( + auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +type ( + QueryConnection struct { + Height int64 `json:"height"` + Result types.ConnectionResponse `json:"result"` + } + + QueryClientConnections struct { + Height int64 `json:"height"` + Result types.ClientConnectionsResponse `json:"result"` + } + + PostConnectionOpenInit struct { + Msgs []types.MsgConnectionOpenInit `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostConnectionOpenTry struct { + Msgs []types.MsgConnectionOpenTry `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostConnectionOpenAck struct { + Msgs []types.MsgConnectionOpenAck `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostConnectionOpenConfirm struct { + Msgs []types.MsgConnectionOpenConfirm `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } +) diff --git a/x/ibc/03-connection/client/rest/tx.go b/x/ibc/03-connection/client/rest/tx.go new file mode 100644 index 000000000000..f11abbccb111 --- /dev/null +++ b/x/ibc/03-connection/client/rest/tx.go @@ -0,0 +1,204 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc("/ibc/connections/open-init", connectionOpenInitHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc("/ibc/connections/open-try", connectionOpenTryHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/connections/{%s}/open-ack", RestConnectionID), connectionOpenAckHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/connections/{%s}/open-confirm", RestConnectionID), connectionOpenConfirmHandlerFn(cliCtx)).Methods("POST") +} + +// connectionOpenInitHandlerFn implements a connection open init handler +// +// @Summary Connection open-init +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.ConnectionOpenInitReq true "Connection open-init request body" +// @Success 200 {object} PostConnectionOpenInit "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/open-init [post] +func connectionOpenInitHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req ConnectionOpenInitReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgConnectionOpenInit( + req.ConnectionID, req.ClientID, req.CounterpartyConnectionID, + req.CounterpartyClientID, req.CounterpartyPrefix, fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// connectionOpenTryHandlerFn implements a connection open try handler +// +// @Summary Connection open-try +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.ConnectionOpenTryReq true "Connection open-try request body" +// @Success 200 {object} PostConnectionOpenTry "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/open-try [post] +func connectionOpenTryHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req ConnectionOpenTryReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgConnectionOpenTry( + req.ConnectionID, req.ClientID, req.CounterpartyConnectionID, + req.CounterpartyClientID, req.CounterpartyPrefix, req.CounterpartyVersions, + req.ProofInit, req.ProofConsensus, req.ProofHeight, + req.ConsensusHeight, fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// connectionOpenAckHandlerFn implements a connection open ack handler +// +// @Summary Connection open-ack +// @Tags IBC +// @Accept json +// @Produce json +// @Param connection-id path string true "Connection ID" +// @Param body body rest.ConnectionOpenAckReq true "Connection open-ack request body" +// @Success 200 {object} PostConnectionOpenAck "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid connection id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/{connection-id}/open-ack [post] +func connectionOpenAckHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + connectionID := vars[RestConnectionID] + + var req ConnectionOpenAckReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgConnectionOpenAck( + connectionID, req.ProofTry, req.ProofConsensus, req.ProofHeight, + req.ConsensusHeight, req.Version, fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// connectionOpenConfirmHandlerFn implements a connection open confirm handler +// +// @Summary Connection open-confirm +// @Tags IBC +// @Accept json +// @Produce json +// @Param connection-id path string true "Connection ID" +// @Param body body rest.ConnectionOpenConfirmReq true "Connection open-confirm request body" +// @Success 200 {object} PostConnectionOpenConfirm "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid connection id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/connections/{connection-id}/open-confirm [post] +func connectionOpenConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + connectionID := vars[RestConnectionID] + + var req ConnectionOpenConfirmReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgConnectionOpenConfirm( + connectionID, req.ProofAck, req.ProofHeight, fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/03-connection/module.go b/x/ibc/03-connection/module.go index 713ed04d6c6b..d4d7d931c97b 100644 --- a/x/ibc/03-connection/module.go +++ b/x/ibc/03-connection/module.go @@ -3,10 +3,13 @@ package connection import ( "fmt" + "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/rest" ) // Name returns the IBC connection ICS name @@ -23,3 +26,8 @@ func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { return cli.GetQueryCmd(fmt.Sprintf("%s/%s", queryRoute, SubModuleName), cdc) } + +// RegisterRESTRoutes registers the REST routes for the IBC connections. +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router, queryRoute string) { + rest.RegisterRoutes(ctx, rtr, fmt.Sprintf("%s/%s", queryRoute, SubModuleName)) +} diff --git a/x/ibc/04-channel/client/rest/query.go b/x/ibc/04-channel/client/rest/query.go new file mode 100644 index 000000000000..b1f6a0f93b63 --- /dev/null +++ b/x/ibc/04-channel/client/rest/query.go @@ -0,0 +1,63 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}", RestPortID, RestChannelID), queryChannelHandlerFn(cliCtx, queryRoute)).Methods("GET") +} + +// queryChannelHandlerFn implements a channel querying route +// +// @Summary Query channel +// @Tags IBC +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param prove query boolean false "Proof of result" +// @Success 200 {object} QueryChannel "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id} [get] +func queryChannelHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyChannel(portID, channelID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var channel types.Channel + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height)) + } +} diff --git a/x/ibc/04-channel/client/rest/rest.go b/x/ibc/04-channel/client/rest/rest.go new file mode 100644 index 000000000000..55cf81215f64 --- /dev/null +++ b/x/ibc/04-channel/client/rest/rest.go @@ -0,0 +1,75 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +const ( + RestChannelID = "channel-id" + RestPortID = "port-id" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + registerQueryRoutes(cliCtx, r, queryRoute) + registerTxRoutes(cliCtx, r) +} + +// ChannelOpenInitReq defines the properties of a channel open init request's body. +type ChannelOpenInitReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + PortID string `json:"port_id" yaml:"port_id"` + ChannelID string `json:"channel_id" yaml:"channel_id"` + Version string `json:"version" yaml:"version"` + ChannelOrder types.Order `json:"channel_order" yaml:"channel_order"` + ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` + CounterpartyPortID string `json:"counterparty_port_id" yaml:"counterparty_port_id"` + CounterpartyChannelID string `json:"counterparty_channel_id" yaml:"counterparty_channel_id"` +} + +// ChannelOpenTryReq defines the properties of a channel open try request's body. +type ChannelOpenTryReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + PortID string `json:"port_id" yaml:"port_id"` + ChannelID string `json:"channel_id" yaml:"channel_id"` + Version string `json:"version" yaml:"version"` + ChannelOrder types.Order `json:"channel_order" yaml:"channel_order"` + ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` + CounterpartyPortID string `json:"counterparty_port_id" yaml:"counterparty_port_id"` + CounterpartyChannelID string `json:"counterparty_channel_id" yaml:"counterparty_channel_id"` + CounterpartyVersion string `json:"counterparty_version" yaml:"counterparty_version"` + ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} + +// ChannelOpenAckReq defines the properties of a channel open ack request's body. +type ChannelOpenAckReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + CounterpartyVersion string `json:"counterparty_version" yaml:"counterparty_version"` + ProofTry commitment.ProofI `json:"proof_try" yaml:"proof_try"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} + +// ChannelOpenConfirmReq defines the properties of a channel open confirm request's body. +type ChannelOpenConfirmReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} + +// ConnectionOpenInitReq defines the properties of a channel close init request's body. +type ChannelCloseInitReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` +} + +// ChannelCloseConfirmReq defines the properties of a channel close confirm request's body. +type ChannelCloseConfirmReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` +} diff --git a/x/ibc/04-channel/client/rest/swagger.go b/x/ibc/04-channel/client/rest/swagger.go new file mode 100644 index 000000000000..608196f69921 --- /dev/null +++ b/x/ibc/04-channel/client/rest/swagger.go @@ -0,0 +1,55 @@ +package rest + +import ( + auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +type ( + QueryChannel struct { + Height int64 `json:"height"` + Result types.ChannelResponse `json:"result"` + } + + PostChannelOpenInit struct { + Msgs []types.MsgChannelOpenInit `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelOpenTry struct { + Msgs []types.MsgChannelOpenTry `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelOpenAck struct { + Msgs []types.MsgChannelOpenAck `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelOpenConfirm struct { + Msgs []types.MsgChannelOpenConfirm `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelCloseInit struct { + Msgs []types.MsgChannelCloseInit `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostChannelCloseConfirm struct { + Msgs []types.MsgChannelCloseConfirm `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } +) diff --git a/x/ibc/04-channel/client/rest/tx.go b/x/ibc/04-channel/client/rest/tx.go new file mode 100644 index 000000000000..641a62bf20e2 --- /dev/null +++ b/x/ibc/04-channel/client/rest/tx.go @@ -0,0 +1,336 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc("/ibc/channels/open-init", channelOpenInitHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc("/ibc/channels/open-try", channelOpenTryHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/open-ack", RestPortID, RestChannelID), channelOpenAckHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/open-confirm", RestPortID, RestChannelID), channelOpenConfirmHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/close-init", RestPortID, RestChannelID), channelCloseInitHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/close-confirm", RestPortID, RestChannelID), channelCloseConfirmHandlerFn(cliCtx)).Methods("POST") +} + +// channelOpenInitHandlerFn implements a channel open init handler +// +// @Summary Channel open-init +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.ChannelOpenInitReq true "Channel open-init request body" +// @Success 200 {object} PostChannelOpenInit "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/channels/open-init [post] +func channelOpenInitHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req ChannelOpenInitReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelOpenInit( + req.PortID, + req.ChannelID, + req.Version, + req.ChannelOrder, + req.ConnectionHops, + req.CounterpartyPortID, + req.CounterpartyChannelID, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelOpenTryHandlerFn implements a channel open try handler +// +// @Summary Channel open-try +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.ChannelOpenTryReq true "Channel open-try request body" +// @Success 200 {object} PostChannelOpenTry "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/channels/open-try [post] +func channelOpenTryHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req ChannelOpenTryReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelOpenTry( + req.PortID, + req.ChannelID, + req.Version, + req.ChannelOrder, + req.ConnectionHops, + req.CounterpartyPortID, + req.CounterpartyChannelID, + req.CounterpartyVersion, + req.ProofInit, + req.ProofHeight, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelOpenAckHandlerFn implements a channel open ack handler +// +// @Summary Channel open-ack +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.ChannelOpenAckReq true "Channel open-ack request body" +// @Success 200 {object} PostChannelOpenAck "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/open-ack [post] +func channelOpenAckHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req ChannelOpenAckReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelOpenAck( + portID, + channelID, + req.CounterpartyVersion, + req.ProofTry, + req.ProofHeight, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelOpenConfirmHandlerFn implements a channel open confirm handler +// +// @Summary Channel open-confirm +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.ChannelOpenConfirmReq true "Channel open-confirm request body" +// @Success 200 {object} PostChannelOpenConfirm "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/open-confirm [post] +func channelOpenConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req ChannelOpenConfirmReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelOpenConfirm( + portID, + channelID, + req.ProofAck, + req.ProofHeight, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelCloseInitHandlerFn implements a channel close init handler +// +// @Summary Channel close-init +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.ChannelCloseInitReq true "Channel close-init request body" +// @Success 200 {object} PostChannelCloseInit "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/close-init [post] +func channelCloseInitHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req ChannelCloseInitReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelCloseInit( + portID, + channelID, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// channelCloseConfirmHandlerFn implements a channel close confirm handler +// +// @Summary Channel close-confirm +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.ChannelCloseConfirmReq true "Channel close-confirm request body" +// @Success 200 {object} PostChannelCloseConfirm "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/close-confirm [post] +func channelCloseConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req ChannelCloseConfirmReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgChannelCloseConfirm( + portID, + channelID, + req.ProofInit, + req.ProofHeight, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/04-channel/module.go b/x/ibc/04-channel/module.go index 4f9b17b03144..7fb21535e948 100644 --- a/x/ibc/04-channel/module.go +++ b/x/ibc/04-channel/module.go @@ -3,10 +3,13 @@ package channel import ( "fmt" + "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/rest" ) // Name returns the IBC connection ICS name @@ -14,6 +17,11 @@ func Name() string { return SubModuleName } +// RegisterRESTRoutes registers the REST routes for the IBC channel +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router, queryRoute string) { + rest.RegisterRoutes(ctx, rtr, fmt.Sprintf("%s/%s", queryRoute, SubModuleName)) +} + // GetTxCmd returns the root tx command for the IBC connections. func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { return cli.GetTxCmd(fmt.Sprintf("%s/%s", storeKey, SubModuleName), cdc) diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index 6f69c5d6ea86..16a7a1943999 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -46,10 +46,10 @@ func (msg MsgChannelOpenInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenInit) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } // Signer can be empty @@ -109,10 +109,10 @@ func (msg MsgChannelOpenTry) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenTry) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if strings.TrimSpace(msg.CounterpartyVersion) == "" { @@ -176,10 +176,10 @@ func (msg MsgChannelOpenAck) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenAck) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if strings.TrimSpace(msg.CounterpartyVersion) == "" { @@ -241,10 +241,10 @@ func (msg MsgChannelOpenConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenConfirm) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } if msg.ProofAck == nil { @@ -296,10 +296,10 @@ func (msg MsgChannelCloseInit) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgChannelCloseInit) ValidateBasic() sdk.Error { - if err := host.DefaultConnectionIdentifierValidator(msg.PortID); err != nil { + if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) } - if err := host.DefaultClientIdentifierValidator(msg.ChannelID); err != nil { + if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) } // Signer can be empty diff --git a/x/ibc/20-transfer/client/rest/query.go b/x/ibc/20-transfer/client/rest/query.go new file mode 100644 index 000000000000..8e979152a768 --- /dev/null +++ b/x/ibc/20-transfer/client/rest/query.go @@ -0,0 +1,60 @@ +package rest + +import ( + "encoding/binary" + "fmt" + "net/http" + + "github.com/gorilla/mux" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" +) + +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/next-sequence-recv", RestPortID, RestChannelID), queryNextSequenceRecvHandlerFn(cliCtx)).Methods("GET") +} + +// queryNextSequenceRecvHandlerFn implements a next sequence receive querying route +// +// @Summary Query next sequence receive +// @Tags IBC +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Success 200 {object} QueryNextSequenceRecv "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/next-sequence-recv [get] +func queryNextSequenceRecvHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: channel.KeyNextSequenceRecv(portID, channelID), + Prove: rest.ParseQueryProve(r), + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + sequence := binary.BigEndian.Uint64(res.Value) + + cliCtx = cliCtx.WithHeight(res.Height) + rest.PostProcessResponse(w, cliCtx, sequence) + } +} diff --git a/x/ibc/20-transfer/client/rest/rest.go b/x/ibc/20-transfer/client/rest/rest.go new file mode 100644 index 000000000000..a43112f0cce3 --- /dev/null +++ b/x/ibc/20-transfer/client/rest/rest.go @@ -0,0 +1,38 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +const ( + RestChannelID = "channel-id" + RestPortID = "port-id" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) { + registerQueryRoutes(cliCtx, r) + registerTxRoutes(cliCtx, r) +} + +// TransferTxReq defines the properties of a transfer tx request's body. +type TransferTxReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Amount sdk.Coins `json:"amount" yaml:"amount"` + Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` + Source bool `json:"source" yaml:"source"` +} + +// RecvPacketReq defines the properties of a receive packet request's body. +type RecvPacketReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Packet channelexported.PacketI `json:"packet" yaml:"packet"` + Proofs []commitment.Proof `json:"proofs" yaml:"proofs"` + Height uint64 `json:"height" yaml:"height"` +} diff --git a/x/ibc/20-transfer/client/rest/swagger.go b/x/ibc/20-transfer/client/rest/swagger.go new file mode 100644 index 000000000000..c36f5d9e9822 --- /dev/null +++ b/x/ibc/20-transfer/client/rest/swagger.go @@ -0,0 +1,27 @@ +package rest + +import ( + auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +type ( + QueryNextSequenceRecv struct { + Height int64 `json:"height"` + Result uint64 `json:"result"` + } + + PostTransfer struct { + Msgs []types.MsgTransfer `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostRecvPacket struct { + Msgs []types.MsgRecvPacket `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } +) diff --git a/x/ibc/20-transfer/client/rest/tx.go b/x/ibc/20-transfer/client/rest/tx.go new file mode 100644 index 000000000000..de699c04e969 --- /dev/null +++ b/x/ibc/20-transfer/client/rest/tx.go @@ -0,0 +1,118 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" +) + +func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/transfer", RestPortID, RestChannelID), transferHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/packets/receive"), recvPacketHandlerFn(cliCtx)).Methods("POST") +} + +// transferHandlerFn implements a transfer handler +// +// @Summary Transfer token +// @Tags IBC +// @Accept json +// @Produce json +// @Param port-id path string true "Port ID" +// @Param channel-id path string true "Channel ID" +// @Param body body rest.TransferTxReq true "Transfer token request body" +// @Success 200 {object} PostTransfer "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/ports/{port-id}/channels/{channel-id}/transfer [post] +func transferHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + var req TransferTxReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgTransfer( + portID, + channelID, + req.Amount, + fromAddr, + req.Receiver, + req.Source, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} + +// recvPacketHandlerFn implements a receive packet handler +// +// @Summary Receive packet +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.RecvPacketReq true "Receive packet request body" +// @Success 200 {object} PostRecvPacket "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/packets/receive [post] +func recvPacketHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req RecvPacketReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgRecvPacket( + req.Packet, + req.Proofs, + req.Height, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index a1e12ec35d8f..f29136061cde 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -1,10 +1,13 @@ package transfer import ( + "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/rest" ) // Name returns the IBC transfer ICS name @@ -12,6 +15,11 @@ func Name() string { return SubModuleName } +// RegisterRESTRoutes registers the REST routes for the IBC transfer +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { + rest.RegisterRoutes(ctx, rtr) +} + // GetTxCmd returns the root tx command for the IBC transfer. func GetTxCmd(cdc *codec.Codec) *cobra.Command { return cli.GetTxCmd(cdc) diff --git a/x/ibc/client/rest/rest.go b/x/ibc/client/rest/rest.go new file mode 100644 index 000000000000..f593ba135760 --- /dev/null +++ b/x/ibc/client/rest/rest.go @@ -0,0 +1,19 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + client.RegisterRESTRoutes(cliCtx, r, queryRoute) + connection.RegisterRESTRoutes(cliCtx, r, queryRoute) + channel.RegisterRESTRoutes(cliCtx, r, queryRoute) + transfer.RegisterRESTRoutes(cliCtx, r) +} diff --git a/x/ibc/module.go b/x/ibc/module.go index 2e91d5540df0..42da7343d6d6 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -18,6 +18,7 @@ import ( transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/client/rest" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -27,17 +28,17 @@ var ( _ module.AppModuleBasic = AppModuleBasic{} ) -// AppModuleBasic defines the basic application module used by the staking module. +// AppModuleBasic defines the basic application module used by the ibc module. type AppModuleBasic struct{} var _ module.AppModuleBasic = AppModuleBasic{} -// Name returns the staking module's name. +// Name returns the ibc module's name. func (AppModuleBasic) Name() string { return types.ModuleName } -// RegisterCodec registers the staking module's types for the given codec. +// RegisterCodec registers the ibc module's types for the given codec. func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) @@ -46,33 +47,33 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { commitment.RegisterCodec(cdc) } -// DefaultGenesis returns default genesis state as raw bytes for the staking +// DefaultGenesis returns default genesis state as raw bytes for the ibc // module. func (AppModuleBasic) DefaultGenesis() json.RawMessage { return nil } -// ValidateGenesis performs genesis state validation for the staking module. +// ValidateGenesis performs genesis state validation for the ibc module. func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { return nil } -// RegisterRESTRoutes registers the REST routes for the staking module. +// RegisterRESTRoutes registers the REST routes for the ibc module. func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { - /// TODO: + rest.RegisterRoutes(ctx, rtr, StoreKey) } -// GetTxCmd returns the root tx command for the staking module. +// GetTxCmd returns the root tx command for the ibc module. func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { return cli.GetTxCmd(StoreKey, cdc) } -// GetQueryCmd returns no root query command for the staking module. +// GetQueryCmd returns no root query command for the ibc module. func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { return cli.GetQueryCmd(QuerierRoute, cdc) } -// AppModule implements an application module for the staking module. +// AppModule implements an application module for the ibc module. type AppModule struct { AppModuleBasic keeper Keeper @@ -85,37 +86,37 @@ func NewAppModule(k Keeper) AppModule { } } -// Name returns the staking module's name. +// Name returns the ibc module's name. func (AppModule) Name() string { return ModuleName } -// RegisterInvariants registers the staking module invariants. +// RegisterInvariants registers the ibc module invariants. func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { // TODO: } -// Route returns the message routing key for the staking module. +// Route returns the message routing key for the ibc module. func (AppModule) Route() string { return RouterKey } -// NewHandler returns an sdk.Handler for the staking module. +// NewHandler returns an sdk.Handler for the ibc module. func (am AppModule) NewHandler() sdk.Handler { return NewHandler(am.keeper) } -// QuerierRoute returns the staking module's querier route name. +// QuerierRoute returns the ibc module's querier route name. func (AppModule) QuerierRoute() string { return QuerierRoute } -// NewQuerierHandler returns the staking module sdk.Querier. +// NewQuerierHandler returns the ibc module sdk.Querier. func (am AppModule) NewQuerierHandler() sdk.Querier { return NewQuerier(am.keeper) } -// InitGenesis performs genesis initialization for the staking module. It returns +// InitGenesis performs genesis initialization for the ibc module. It returns // no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { // check if the IBC transfer module account is set @@ -123,17 +124,17 @@ func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.Va return []abci.ValidatorUpdate{} } -// ExportGenesis returns the exported genesis state as raw bytes for the staking +// ExportGenesis returns the exported genesis state as raw bytes for the ibc // module. func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { return nil } -// BeginBlock returns the begin blocker for the staking module. +// BeginBlock returns the begin blocker for the ibc module. func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { } -// EndBlock returns the end blocker for the staking module. It returns no validator +// EndBlock returns the end blocker for the ibc module. It returns no validator // updates. func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} From a35c79ed304dda7d4740f752f8802fe16e1bc57c Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 2 Dec 2019 17:05:25 +0100 Subject: [PATCH 049/176] fix IBC proofs (#5351) * fix ICS02 proofs * fix ICS03 proofs * fix ICS04 proofs * fix ICS20 proofs * make format --- x/ibc/02-client/client/cli/cli.go | 45 ++++++ x/ibc/02-client/client/cli/query.go | 160 +++++----------------- x/ibc/02-client/client/cli/tx.go | 18 --- x/ibc/02-client/client/rest/query.go | 149 ++++++-------------- x/ibc/02-client/client/utils/utils.go | 126 +++++++++++++---- x/ibc/02-client/keeper/client_test.go | 5 +- x/ibc/03-connection/client/cli/cli.go | 41 ++++++ x/ibc/03-connection/client/cli/query.go | 66 ++------- x/ibc/03-connection/client/cli/tx.go | 30 +--- x/ibc/03-connection/client/rest/query.go | 37 ++--- x/ibc/03-connection/client/utils/utils.go | 59 ++++++++ x/ibc/04-channel/client/cli/cli.go | 43 ++++++ x/ibc/04-channel/client/cli/query.go | 30 ++-- x/ibc/04-channel/client/cli/tx.go | 109 +++++---------- x/ibc/04-channel/client/rest/query.go | 22 +-- x/ibc/04-channel/client/utils/utils.go | 32 ++--- x/ibc/04-channel/types/querier.go | 22 +++ x/ibc/05-port/keeper/keeper_test.go | 3 +- x/ibc/20-transfer/client/cli/cli.go | 37 +++++ x/ibc/20-transfer/client/cli/query.go | 36 +---- x/ibc/20-transfer/client/cli/tx.go | 22 +-- x/ibc/20-transfer/client/rest/query.go | 20 +-- x/ibc/20-transfer/client/utils/utils.go | 32 +++++ x/ibc/20-transfer/handler_test.go | 5 +- x/ibc/20-transfer/keeper/keeper_test.go | 7 +- x/ibc/20-transfer/keeper/relay_test.go | 3 +- x/ibc/20-transfer/types/msgs_test.go | 5 +- 27 files changed, 584 insertions(+), 580 deletions(-) create mode 100644 x/ibc/02-client/client/cli/cli.go create mode 100644 x/ibc/03-connection/client/cli/cli.go create mode 100644 x/ibc/03-connection/client/utils/utils.go create mode 100644 x/ibc/04-channel/client/cli/cli.go create mode 100644 x/ibc/20-transfer/client/cli/cli.go create mode 100644 x/ibc/20-transfer/client/utils/utils.go diff --git a/x/ibc/02-client/client/cli/cli.go b/x/ibc/02-client/client/cli/cli.go new file mode 100644 index 000000000000..ac182365a7ae --- /dev/null +++ b/x/ibc/02-client/client/cli/cli.go @@ -0,0 +1,45 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" +) + +// GetQueryCmd returns the query commands for IBC clients +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + ics02ClientQueryCmd := &cobra.Command{ + Use: "client", + Short: "IBC client query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics02ClientQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryClientState(queryRoute, cdc), + GetCmdQueryConsensusState(queryRoute, cdc), + GetCmdQueryRoot(queryRoute, cdc), + GetCmdQueryHeader(cdc), + GetCmdNodeConsensusState(queryRoute, cdc), + GetCmdQueryPath(queryRoute, cdc), + )...) + return ics02ClientQueryCmd +} + +// GetTxCmd returns the transaction commands for IBC clients +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics02ClientTxCmd := &cobra.Command{ + Use: "client", + Short: "Client transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics02ClientTxCmd.AddCommand(client.PostCommands( + GetCmdCreateClient(cdc), + GetCmdUpdateClient(cdc), + )...) + + return ics02ClientTxCmd +} diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index cc5cb3364c89..8bc6a755db4f 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -9,40 +9,14 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - tmtypes "github.com/tendermint/tendermint/types" - - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -// GetQueryCmd returns the query commands for IBC clients -func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { - ics02ClientQueryCmd := &cobra.Command{ - Use: "client", - Short: "IBC client query subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - } - - ics02ClientQueryCmd.AddCommand(client.GetCommands( - GetCmdQueryConsensusState(queryRoute, cdc), - GetCmdQueryHeader(cdc), - GetCmdQueryClientState(queryRoute, cdc), - GetCmdQueryRoot(queryRoute, cdc), - GetCmdNodeConsensusState(queryRoute, cdc), - GetCmdQueryPath(queryRoute, cdc), - )...) - return ics02ClientQueryCmd -} - // GetCmdQueryClientState defines the command to query the state of a client with // a given id as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query func GetCmdQueryClientState(queryRoute string, cdc *codec.Codec) *cobra.Command { @@ -64,28 +38,13 @@ $ %s query ibc client state [client-id] return errors.New("client ID can't be blank") } - bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) - if err != nil { - return err - } + prove := viper.GetBool(flags.FlagProve) - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), - } - - res, err := cliCtx.QueryABCI(req) + clientStateRes, err := utils.QueryClientState(cliCtx, clientID, prove) if err != nil { return err } - var clientState types.State - if err := cdc.UnmarshalJSON(res.Value, &clientState); err != nil { - return err - } - - clientStateRes := types.NewClientStateResponse(clientID, clientState, res.Proof, res.Height) return cliCtx.PrintOutput(clientStateRes) }, } @@ -93,19 +52,15 @@ $ %s query ibc client state [client-id] return cmd } -// GetCmdQueryRoot defines the command to query a verified commitment root -func GetCmdQueryRoot(queryRoute string, cdc *codec.Codec) *cobra.Command { +// GetCmdQueryConsensusState defines the command to query the consensus state of +// the chain as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query +func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "root [client-id] [height]", - Short: "Query a verified commitment root", - Long: strings.TrimSpace( - fmt.Sprintf(`Query an already verified commitment root at a specific height for a particular client - -Example: -$ %s query ibc client root [client-id] [height] -`, version.ClientName), - ), - Args: cobra.ExactArgs(2), + Use: "consensus-state [client-id]", + Short: "Query the latest consensus state of the client", + Long: "Query the consensus state for a particular light client", + Example: fmt.Sprintf("%s query ibc client consensus-state [client-id]", version.ClientName), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) clientID := args[0] @@ -113,54 +68,33 @@ $ %s query ibc client root [client-id] [height] return errors.New("client ID can't be blank") } - height, err := strconv.ParseUint(args[1], 10, 64) - if err != nil { - return fmt.Errorf("expected integer height, got: %v", args[1]) - } - - bz, err := cdc.MarshalJSON(types.NewQueryCommitmentRootParams(clientID, height)) - if err != nil { - return err - } - - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryVerifiedRoot), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), - } + prove := viper.GetBool(flags.FlagProve) - res, err := cliCtx.QueryABCI(req) + csRes, err := utils.QueryConsensusStateProof(cliCtx, clientID, prove) if err != nil { return err } - var root commitment.Root - if err := cdc.UnmarshalJSON(res.Value, &root); err != nil { - return err - } - - rootRes := types.NewRootResponse(clientID, height, root, res.Proof, res.Height) - return cliCtx.PrintOutput(rootRes) + return cliCtx.PrintOutput(csRes) }, } cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") return cmd } -// GetCmdQueryConsensusState defines the command to query the consensus state of -// the chain as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query -func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { +// GetCmdQueryRoot defines the command to query a verified commitment root +func GetCmdQueryRoot(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "consensus-state [client-id]", - Short: "Query the latest consensus state of the client", + Use: "root [client-id] [height]", + Short: "Query a verified commitment root", Long: strings.TrimSpace( - fmt.Sprintf(`Query the consensus state for a particular client + fmt.Sprintf(`Query an already verified commitment root at a specific height for a particular client Example: -$ %s query ibc client consensus-state [client-id] - `, version.ClientName), +$ %s query ibc client root [client-id] [height] +`, version.ClientName), ), - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) clientID := args[0] @@ -168,12 +102,19 @@ $ %s query ibc client consensus-state [client-id] return errors.New("client ID can't be blank") } - csRes, err := utils.QueryConsensusStateProof(cliCtx, cdc, queryRoute, clientID) + height, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return fmt.Errorf("expected integer height, got: %v", args[1]) + } + + prove := viper.GetBool(flags.FlagProve) + + rootRes, err := utils.QueryCommitmentRoot(cliCtx, clientID, height, prove) if err != nil { return err } - return cliCtx.PrintOutput(csRes) + return cliCtx.PrintOutput(rootRes) }, } cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") @@ -183,18 +124,14 @@ $ %s query ibc client consensus-state [client-id] // GetCmdQueryHeader defines the command to query the latest header on the chain func GetCmdQueryHeader(cdc *codec.Codec) *cobra.Command { return &cobra.Command{ - Use: "header", - Short: "Query the latest header of the running chain", - Long: strings.TrimSpace(fmt.Sprintf(`Query the latest Tendermint header - -Example: -$ %s query ibc client header - `, version.ClientName), - ), + Use: "header", + Short: "Query the latest header of the running chain", + Long: "Query the latest Tendermint header of the running chain", + Example: fmt.Sprintf("%s query ibc client header", version.ClientName), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) - header, err := utils.GetTendermintHeader(cliCtx) + header, _, err := utils.QueryTendermintHeader(cliCtx) if err != nil { return err } @@ -221,36 +158,11 @@ $ %s query ibc client node-state RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) - node, err := cliCtx.GetNode() - if err != nil { - return err - } - - info, err := node.ABCIInfo() - if err != nil { - return err - } - - height := info.Response.LastBlockHeight - prevHeight := height - 1 - - commit, err := node.Commit(&height) - if err != nil { - return err - } - - validators, err := node.Validators(&prevHeight) + state, _, err := utils.QueryNodeConsensusState(cliCtx) if err != nil { return err } - state := tendermint.ConsensusState{ - ChainID: commit.ChainID, - Height: uint64(commit.Height), - Root: commitment.NewRoot(commit.AppHash), - NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), - } - return cliCtx.PrintOutput(state) }, } diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 4cbc97b39842..2c8abcff4c95 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -8,7 +8,6 @@ import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" @@ -20,23 +19,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ) -// GetTxCmd returns the transaction commands for IBC Clients -func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { - ics02ClientTxCmd := &cobra.Command{ - Use: "client", - Short: "Client transaction subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - } - - ics02ClientTxCmd.AddCommand(client.PostCommands( - GetCmdCreateClient(cdc), - GetCmdUpdateClient(cdc), - )...) - - return ics02ClientTxCmd -} - // GetCmdCreateClient defines the command to create a new IBC Client as defined // in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create func GetCmdCreateClient(cdc *codec.Codec) *cobra.Command { diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go index d8b77d658c0b..bc135bebc1b8 100644 --- a/x/ibc/02-client/client/rest/query.go +++ b/x/ibc/02-client/client/rest/query.go @@ -6,129 +6,85 @@ import ( "strconv" "github.com/gorilla/mux" - abci "github.com/tendermint/tendermint/abci/types" - tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc("/ibc/header", queryHeaderHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/node-state", queryNodeConsensusStateHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/path", queryPathHandlerFn(cliCtx)).Methods("GET") } -// queryConsensusStateHandlerFn implements a consensus state querying route +// queryClientStateHandlerFn implements a client state querying route // -// @Summary Query cliet consensus-state +// @Summary Query client state // @Tags IBC // @Produce json // @Param client-id path string true "Client ID" // @Param prove query boolean false "Proof of result" -// @Success 200 {object} QueryConsensusState "OK" +// @Success 200 {object} QueryClientState "OK" // @Failure 400 {object} rest.ErrorResponse "Invalid client id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/clients/{client-id}/consensus-state [get] -func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +// @Router /ibc/clients/{client-id}/client-state [get] +func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyConsensusState(clientID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + clientStateRes, err := utils.QueryClientState(cliCtx, clientID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var cs tendermint.ConsensusState - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - } - - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(clientStateRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, clientStateRes) } } -// queryHeaderHandlerFn implements a header querying route -// -// @Summary Query header -// @Tags IBC -// @Produce json -// @Success 200 {object} QueryHeader "OK" -// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/header [get] -func queryHeaderHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - header, err := utils.GetTendermintHeader(cliCtx) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - rest.PostProcessResponse(w, cliCtx, header) - } -} - -// queryClientStateHandlerFn implements a client state querying route +// queryConsensusStateHandlerFn implements a consensus state querying route // -// @Summary Query client state +// @Summary Query cliet consensus-state // @Tags IBC // @Produce json // @Param client-id path string true "Client ID" // @Param prove query boolean false "Proof of result" -// @Success 200 {object} QueryClientState "OK" +// @Success 200 {object} QueryConsensusState "OK" // @Failure 400 {object} rest.ErrorResponse "Invalid client id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/clients/{client-id}/client-state [get] -func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +// @Router /ibc/clients/{client-id}/consensus-state [get] +func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyClientState(clientID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + csRes, err := utils.QueryConsensusStateProof(cliCtx, clientID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var state types.State - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &state); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - } - - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewClientStateResponse(clientID, state, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(csRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, csRes) } } @@ -153,31 +109,43 @@ func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Handl return } + prove := rest.ParseQueryProve(r) + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyRoot(clientID, height), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + rootRes, err := utils.QueryCommitmentRoot(cliCtx, clientID, height, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var root commitment.Root - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &root); err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + cliCtx = cliCtx.WithHeight(int64(rootRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, rootRes) + } +} + +// queryHeaderHandlerFn implements a header querying route +// +// @Summary Query header +// @Tags IBC +// @Produce json +// @Success 200 {object} QueryHeader "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/header [get] +func queryHeaderHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + header, height, err := utils.QueryTendermintHeader(cliCtx) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewRootResponse(clientID, height, root, res.Proof, res.Height)) + res := cliCtx.Codec.MustMarshalJSON(header) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -191,38 +159,9 @@ func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Handl // @Router /ibc/node-state [get] func queryNodeConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - node, err := cliCtx.GetNode() - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - info, err := node.ABCIInfo() - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - height := info.Response.LastBlockHeight - prevHeight := height - 1 - - commit, err := node.Commit(&height) + state, height, err := utils.QueryNodeConsensusState(cliCtx) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - validators, err := node.Validators(&prevHeight) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - state := tendermint.ConsensusState{ - ChainID: commit.ChainID, - Height: uint64(commit.Height), - Root: commitment.NewRoot(commit.AppHash), - NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), } res := cliCtx.Codec.MustMarshalJSON(state) diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 955e06f50e7c..a024e0856594 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -1,38 +1,52 @@ package utils import ( - "fmt" - - "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// QueryClientState queries the store to get the light client state and a merkle +// proof. +func QueryClientState( + cliCtx context.CLIContext, clientID string, prove bool, +) (types.StateResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyClientState(clientID), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.StateResponse{}, err + } + + var clientState types.State + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &clientState); err != nil { + return types.StateResponse{}, err + } + + clientStateRes := types.NewClientStateResponse(clientID, clientState, res.Proof, res.Height) + + return clientStateRes, nil +} + // QueryConsensusStateProof queries the store to get the consensus state and a // merkle proof. func QueryConsensusStateProof( - cliCtx client.CLIContext, cdc *codec.Codec, - queryRoute, clientID string, -) (types.ConsensusStateResponse, error) { + cliCtx client.CLIContext, clientID string, prove bool) (types.ConsensusStateResponse, error) { var conStateRes types.ConsensusStateResponse - bz, err := cdc.MarshalJSON(types.NewQueryClientStateParams(clientID)) - if err != nil { - return conStateRes, err - } - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientState), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), + Path: "store/ibc/key", + Data: types.KeyConsensusState(clientID), + Prove: prove, } res, err := cliCtx.QueryABCI(req) @@ -48,17 +62,43 @@ func QueryConsensusStateProof( return types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height), nil } -// GetTendermintHeader takes a client context and returns the appropriate +// QueryCommitmentRoot queries the store to get the commitment root and a merkle +// proof. +func QueryCommitmentRoot( + cliCtx context.CLIContext, clientID string, height uint64, prove bool, +) (types.RootResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyRoot(clientID, height), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.RootResponse{}, err + } + + var root commitment.Root + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &root); err != nil { + return types.RootResponse{}, err + } + + rootRes := types.NewRootResponse(clientID, height, root, res.Proof, res.Height) + + return rootRes, nil +} + +// QueryTendermintHeader takes a client context and returns the appropriate // tendermint header -func GetTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, error) { +func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, error) { node, err := cliCtx.GetNode() if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } info, err := node.ABCIInfo() if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } height := info.Response.LastBlockHeight @@ -66,17 +106,17 @@ func GetTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, error) { commit, err := node.Commit(&height) if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } validators, err := node.Validators(&prevheight) if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } nextvalidators, err := node.Validators(&height) if err != nil { - return tendermint.Header{}, err + return tendermint.Header{}, 0, err } header := tendermint.Header{ @@ -85,5 +125,41 @@ func GetTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, error) { NextValidatorSet: tmtypes.NewValidatorSet(nextvalidators.Validators), } - return header, nil + return header, height, nil +} + +// QueryNodeConsensusState takes a client context and returns the appropriate +// tendermint consensus state +func QueryNodeConsensusState(cliCtx context.CLIContext) (tendermint.ConsensusState, int64, error) { + node, err := cliCtx.GetNode() + if err != nil { + return tendermint.ConsensusState{}, 0, err + } + + info, err := node.ABCIInfo() + if err != nil { + return tendermint.ConsensusState{}, 0, err + } + + height := info.Response.LastBlockHeight + prevHeight := height - 1 + + commit, err := node.Commit(&height) + if err != nil { + return tendermint.ConsensusState{}, 0, err + } + + validators, err := node.Validators(&prevHeight) + if err != nil { + return tendermint.ConsensusState{}, 0, err + } + + state := tendermint.ConsensusState{ + ChainID: commit.ChainID, + Height: uint64(commit.Height), + Root: commitment.NewRoot(commit.AppHash), + NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), + } + + return state, height, nil } diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index 923a6e710981..cfc69e2f2245 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -3,12 +3,13 @@ package keeper_test import ( "fmt" + "github.com/stretchr/testify/require" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - "github.com/stretchr/testify/require" - tmtypes "github.com/tendermint/tendermint/types" ) const ( diff --git a/x/ibc/03-connection/client/cli/cli.go b/x/ibc/03-connection/client/cli/cli.go new file mode 100644 index 000000000000..820baa02b3b6 --- /dev/null +++ b/x/ibc/03-connection/client/cli/cli.go @@ -0,0 +1,41 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" +) + +// GetQueryCmd returns the query commands for IBC connections +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + ics03ConnectionQueryCmd := &cobra.Command{ + Use: "connection", + Short: "IBC connection query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics03ConnectionQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryConnection(queryRoute, cdc), + )...) + return ics03ConnectionQueryCmd +} + +// GetTxCmd returns the transaction commands for IBC connections +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics03ConnectionTxCmd := &cobra.Command{ + Use: "connection", + Short: "IBC connection transaction subcommands", + } + + ics03ConnectionTxCmd.AddCommand(client.PostCommands( + GetCmdConnectionOpenInit(storeKey, cdc), + GetCmdConnectionOpenTry(storeKey, cdc), + GetCmdConnectionOpenAck(storeKey, cdc), + GetCmdConnectionOpenConfirm(storeKey, cdc), + GetCmdHandshakeState(storeKey, cdc), + )...) + + return ics03ConnectionTxCmd +} diff --git a/x/ibc/03-connection/client/cli/query.go b/x/ibc/03-connection/client/cli/query.go index f4502807f859..4eb3f167b451 100644 --- a/x/ibc/03-connection/client/cli/query.go +++ b/x/ibc/03-connection/client/cli/query.go @@ -7,31 +7,13 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" ) -// GetQueryCmd returns the query commands for IBC connections -func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { - ics03ConnectionQueryCmd := &cobra.Command{ - Use: "connection", - Short: "IBC connection query subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - } - - ics03ConnectionQueryCmd.AddCommand(client.GetCommands( - GetCmdQueryConnection(queryRoute, cdc), - )...) - return ics03ConnectionQueryCmd -} - // GetCmdQueryConnection defines the command to query a connection end func GetCmdQueryConnection(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -43,33 +25,18 @@ Example: $ %s query ibc connection end [connection-id] `, version.ClientName), ), - Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s query ibc connection end [connection-id]", version.ClientName), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) connectionID := args[0] + prove := viper.GetBool(flags.FlagProve) - bz, err := cdc.MarshalJSON(types.NewQueryConnectionParams(connectionID)) - if err != nil { - return err - } - - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryConnection), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), - } - - res, err := cliCtx.QueryABCI(req) + connRes, err := utils.QueryConnection(cliCtx, connectionID, prove) if err != nil { return err } - var connection types.ConnectionEnd - if err := cdc.UnmarshalJSON(res.Value, &connection); err != nil { - return err - } - - connRes := types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height) return cliCtx.PrintOutput(connRes) }, } @@ -89,33 +56,18 @@ Example: $ %s query ibc connection client [client-id] `, version.ClientName), ), - Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s query ibc connection client [client-id]", version.ClientName), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) clientID := args[0] + prove := viper.GetBool(flags.FlagProve) - bz, err := cdc.MarshalJSON(types.NewQueryClientConnectionsParams(clientID)) + connPathsRes, err := utils.QueryClientConnections(cliCtx, clientID, prove) if err != nil { return err } - req := abci.RequestQuery{ - Path: fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryClientConnections), - Data: bz, - Prove: viper.GetBool(flags.FlagProve), - } - - res, err := cliCtx.QueryABCI(req) - if err != nil { - return err - } - - var connectionPaths []string - if err := cdc.UnmarshalJSON(res.Value, &connectionPaths); err != nil { - return err - } - - connPathsRes := types.NewClientConnectionsResponse(clientID, connectionPaths, res.Proof, res.Height) return cliCtx.PrintOutput(connPathsRes) }, } diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index b3115069adbc..c2324322f08f 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -38,24 +38,6 @@ const ( FlagChainID2 = "chain-id2" ) -// GetTxCmd returns the transaction commands for IBC Connections -func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { - ics03ConnectionTxCmd := &cobra.Command{ - Use: "connection", - Short: "IBC connection transaction subcommands", - } - - ics03ConnectionTxCmd.AddCommand(client.PostCommands( - GetCmdConnectionOpenInit(storeKey, cdc), - GetCmdConnectionOpenTry(storeKey, cdc), - GetCmdConnectionOpenAck(storeKey, cdc), - GetCmdConnectionOpenConfirm(storeKey, cdc), - GetCmdHandshakeState(storeKey, cdc), - )...) - - return ics03ConnectionTxCmd -} - // GetCmdConnectionOpenInit defines the command to initialize a connection on // chain A with a given counterparty chain B func GetCmdConnectionOpenInit(storeKey string, cdc *codec.Codec) *cobra.Command { @@ -302,7 +284,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { Args: cobra.ExactArgs(6), RunE: func(cmd *cobra.Command, args []string) error { - viper.Set(flags.FlagProve, true) + prove := true // --chain-id values for each chain cid1 := viper.GetString(flags.FlagChainID) @@ -387,7 +369,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { // remove hardcoding this to 8 seconds. time.Sleep(8 * time.Second) - header, err := clientutils.GetTendermintHeader(ctx1) + header, _, err := clientutils.QueryTendermintHeader(ctx1) if err != nil { return err } @@ -414,7 +396,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), cdc, clienttypes.QuerierRoute, clientID1) + csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1, prove) if err != nil { return err } @@ -442,7 +424,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { // remove hardcoding this to 8 seconds. time.Sleep(8 * time.Second) - header, err = clientutils.GetTendermintHeader(ctx2) + header, _, err = clientutils.QueryTendermintHeader(ctx2) if err != nil { return err } @@ -468,7 +450,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), cdc, clienttypes.QuerierRoute, clientID2) + csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2, prove) if err != nil { return err } @@ -495,7 +477,7 @@ func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { // remove hardcoding this to 8 seconds. time.Sleep(8 * time.Second) - header, err = clientutils.GetTendermintHeader(ctx1) + header, _, err = clientutils.QueryTendermintHeader(ctx1) if err != nil { return err } diff --git a/x/ibc/03-connection/client/rest/query.go b/x/ibc/03-connection/client/rest/query.go index f40bbfd2eba6..8085a8965d0c 100644 --- a/x/ibc/03-connection/client/rest/query.go +++ b/x/ibc/03-connection/client/rest/query.go @@ -5,11 +5,10 @@ import ( "net/http" "github.com/gorilla/mux" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { @@ -32,30 +31,21 @@ func queryConnectionHandlerFn(cliCtx context.CLIContext, queryRoute string) http return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) connectionID := vars[RestConnectionID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyConnection(connectionID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + connRes, err := utils.QueryConnection(cliCtx, connectionID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var connection types.ConnectionEnd - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - } - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(connRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, connRes) } } @@ -74,29 +64,20 @@ func queryClientConnectionsHandlerFn(cliCtx context.CLIContext, queryRoute strin return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyClientConnections(clientID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + connPathsRes, err := utils.QueryClientConnections(cliCtx, clientID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var paths []string - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &paths); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - } - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewClientConnectionsResponse(clientID, paths, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(connPathsRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, connPathsRes) } } diff --git a/x/ibc/03-connection/client/utils/utils.go b/x/ibc/03-connection/client/utils/utils.go new file mode 100644 index 000000000000..5cfd7bf7dab4 --- /dev/null +++ b/x/ibc/03-connection/client/utils/utils.go @@ -0,0 +1,59 @@ +package utils + +import ( + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" +) + +// QueryConnection queries the store to get a connection end and a merkle +// proof. +func QueryConnection( + cliCtx context.CLIContext, connectionID string, prove bool, +) (types.ConnectionResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyConnection(connectionID), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.ConnectionResponse{}, err + } + + var connection types.ConnectionEnd + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { + return types.ConnectionResponse{}, err + } + + connRes := types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height) + + return connRes, nil +} + +// QueryClientConnections queries the store to get the registered connection paths +// registered for a particular client and a merkle proof. +func QueryClientConnections( + cliCtx context.CLIContext, clientID string, prove bool, +) (types.ClientConnectionsResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyClientConnections(clientID), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.ClientConnectionsResponse{}, err + } + + var paths []string + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &paths); err != nil { + return types.ClientConnectionsResponse{}, err + } + + connPathsRes := types.NewClientConnectionsResponse(clientID, paths, res.Proof, res.Height) + return connPathsRes, nil +} diff --git a/x/ibc/04-channel/client/cli/cli.go b/x/ibc/04-channel/client/cli/cli.go new file mode 100644 index 000000000000..2f6e76ca9b13 --- /dev/null +++ b/x/ibc/04-channel/client/cli/cli.go @@ -0,0 +1,43 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" +) + +// GetQueryCmd returns the query commands for IBC channels +func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics04ChannelQueryCmd := &cobra.Command{ + Use: "channel", + Short: "IBC channel query subcommands", + DisableFlagParsing: true, + } + + ics04ChannelQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryChannel(storeKey, cdc), + )...) + + return ics04ChannelQueryCmd +} + +// GetTxCmd returns the transaction commands for IBC channels +func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { + ics04ChannelTxCmd := &cobra.Command{ + Use: "channel", + Short: "IBC channel transaction subcommands", + } + + ics04ChannelTxCmd.AddCommand(client.PostCommands( + GetMsgChannelOpenInitCmd(storeKey, cdc), + GetMsgChannelOpenTryCmd(storeKey, cdc), + GetMsgChannelOpenAckCmd(storeKey, cdc), + GetMsgChannelOpenConfirmCmd(storeKey, cdc), + GetMsgChannelCloseInitCmd(storeKey, cdc), + GetMsgChannelCloseConfirmCmd(storeKey, cdc), + GetCmdHandshake(storeKey, cdc), + )...) + + return ics04ChannelTxCmd +} diff --git a/x/ibc/04-channel/client/cli/query.go b/x/ibc/04-channel/client/cli/query.go index 04bfcfcbbe92..e04e943d33e8 100644 --- a/x/ibc/04-channel/client/cli/query.go +++ b/x/ibc/04-channel/client/cli/query.go @@ -5,29 +5,15 @@ import ( "strings" "github.com/spf13/cobra" + "github.com/spf13/viper" - cli "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" ) -// GetQueryCmd returns the query commands for IBC channels -func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { - ics04ChannelQueryCmd := &cobra.Command{ - Use: "channel", - Short: "IBC channel query subcommands", - DisableFlagParsing: true, - } - - ics04ChannelQueryCmd.AddCommand(cli.GetCommands( - GetCmdQueryChannel(storeKey, cdc), - )...) - - return ics04ChannelQueryCmd -} - // GetCmdQueryChannel defines the command to query a channel end func GetCmdQueryChannel(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -39,17 +25,23 @@ Example: $ %s query ibc channel end [port-id] [channel-id] `, version.ClientName), ), - Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s query ibc channel end [port-id] [channel-id]", version.ClientName), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) + portID := args[0] + channelID := args[1] + prove := viper.GetBool(flags.FlagProve) - ch, err := utils.QueryChannel(cliCtx, args[0], args[1], queryRoute) + channelRes, err := utils.QueryChannel(cliCtx, portID, channelID, prove) if err != nil { return err } - return cliCtx.PrintOutput(ch) + return cliCtx.PrintOutput(channelRes) }, } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd } diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index fea92f900ee9..ff0123a060b6 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -11,9 +11,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/keys" @@ -21,9 +18,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -38,26 +36,6 @@ const ( FlagChainID2 = "chain-id2" ) -// GetTxCmd returns the transaction commands for IBC Connections -func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { - ics04ChannelTxCmd := &cobra.Command{ - Use: "channel", - Short: "IBC channel transaction subcommands", - } - - ics04ChannelTxCmd.AddCommand(client.PostCommands( - GetMsgChannelOpenInitCmd(storeKey, cdc), - GetMsgChannelOpenTryCmd(storeKey, cdc), - GetMsgChannelOpenAckCmd(storeKey, cdc), - GetMsgChannelOpenConfirmCmd(storeKey, cdc), - GetMsgChannelCloseInitCmd(storeKey, cdc), - GetMsgChannelCloseConfirmCmd(storeKey, cdc), - GetCmdHandshake(storeKey, cdc), - )...) - - return ics04ChannelTxCmd -} - // TODO: module needs to pass the capability key (i.e store key) // GetMsgChannelOpenInitCmd returns the command to create a MsgChannelOpenInit transaction @@ -67,7 +45,7 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Short: "Creates and sends a ChannelOpenInit message", Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -86,7 +64,7 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } @@ -103,7 +81,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Creates and sends a ChannelOpenTry message", Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -140,7 +118,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") @@ -156,7 +134,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Creates and sends a ChannelOpenAck message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -187,7 +165,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } cmd.Flags().String(FlagIBCVersion, "1.0.0", "supported IBC version") @@ -201,7 +179,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma Short: "Creates and sends a ChannelOpenConfirm message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -231,7 +209,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } } @@ -243,7 +221,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Short: "Creates and sends a ChannelCloseInit message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -254,7 +232,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } } @@ -266,7 +244,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm Short: "Creates and sends a ChannelCloseConfirm message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] @@ -296,7 +274,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } } @@ -342,10 +320,12 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie connid1 := args[3] connid2 := args[7] + prove := true + // Create txbldr, clictx, querier for cid1 viper.Set(flags.FlagChainID, cid1) txBldr1 := auth.NewTxBuilderFromCLI(). - WithTxEncoder(utils.GetTxEncoder(cdc)) + WithTxEncoder(authutils.GetTxEncoder(cdc)) ctx1 := context.NewCLIContextIBC(from1, cid1, node1). WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) @@ -353,7 +333,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie // Create txbldr, clictx, querier for cid2 viper.Set(flags.FlagChainID, cid2) txBldr2 := auth.NewTxBuilderFromCLI(). - WithTxEncoder(utils.GetTxEncoder(cdc)) + WithTxEncoder(authutils.GetTxEncoder(cdc)) ctx2 := context.NewCLIContextIBC(from2, cid2, node2). WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) @@ -377,7 +357,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) + res, err := authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) if err != nil || !res.IsOK() { return err } @@ -386,7 +366,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie // to retrieve the correct proofs time.Sleep(8 * time.Second) - header, err := clientutils.GetTendermintHeader(ctx1) + header, _, err := clientutils.QueryTendermintHeader(ctx1) if err != nil { return err } @@ -397,23 +377,23 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) if err != nil || !res.IsOK() { return err } viper.Set(flags.FlagChainID, cid1) - proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), portid1, chanid1, storeKey) + channelRes, err := utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) if err != nil { return err } - msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) if err := msgUpdateClient.ValidateBasic(); err != nil { return err } - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) + res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) if err != nil || !res.IsOK() { return err } @@ -422,7 +402,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie // to retrieve the correct proofs time.Sleep(8 * time.Second) - header, err = clientutils.GetTendermintHeader(ctx2) + header, _, err = clientutils.QueryTendermintHeader(ctx2) if err != nil { return err } @@ -433,24 +413,24 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) + res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) if err != nil || !res.IsOK() { return err } viper.Set(flags.FlagChainID, cid2) - proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), portid2, chanid2, storeKey) + channelRes, err = utils.QueryChannel(ctx2.WithHeight(header.Height-1), portid2, chanid2, prove) if err != nil { return err } viper.Set(flags.FlagChainID, cid1) - msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", proofs.Proof, uint64(header.Height), ctx1.GetFromAddress()) + msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx1.GetFromAddress()) if err := msgOpenAck.ValidateBasic(); err != nil { return err } - res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) + res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) if err != nil || !res.IsOK() { return err } @@ -459,7 +439,7 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie // to retrieve the correct proofs time.Sleep(8 * time.Second) - header, err = clientutils.GetTendermintHeader(ctx1) + header, _, err = clientutils.QueryTendermintHeader(ctx1) if err != nil { return err } @@ -470,23 +450,23 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return err } - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) + res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) if err != nil || !res.IsOK() { return err } viper.Set(flags.FlagChainID, cid1) - proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), portid1, chanid1, storeKey) + channelRes, err = utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) if err != nil { return err } - msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) if err := msgOpenConfirm.ValidateBasic(); err != nil { return err } - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) + res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) if err != nil || !res.IsOK() { return err } @@ -508,27 +488,6 @@ $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-clie return cmd } -func queryProofs(ctx client.CLIContext, portID string, channelID string, queryRoute string) (types.ChannelResponse, error) { - var connRes types.ChannelResponse - - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyChannel(portID, channelID), - Prove: true, - } - - res, err := ctx.QueryABCI(req) - if res.Value == nil || err != nil { - return connRes, err - } - - var channel types.Channel - if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { - return connRes, err - } - return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil -} - func channelOrder() types.Order { if viper.GetBool(FlagOrdered) { return types.ORDERED diff --git a/x/ibc/04-channel/client/rest/query.go b/x/ibc/04-channel/client/rest/query.go index b1f6a0f93b63..9fcd714de242 100644 --- a/x/ibc/04-channel/client/rest/query.go +++ b/x/ibc/04-channel/client/rest/query.go @@ -5,11 +5,10 @@ import ( "net/http" "github.com/gorilla/mux" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { @@ -33,31 +32,20 @@ func queryChannelHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Ha vars := mux.Vars(r) portID := vars[RestPortID] channelID := vars[RestChannelID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyChannel(portID, channelID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + channelRes, err := utils.QueryChannel(cliCtx, portID, channelID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var channel types.Channel - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height)) + cliCtx = cliCtx.WithHeight(int64(channelRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, channelRes) } } diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index 580a2bf1fb83..0084f57376a1 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -9,29 +9,26 @@ import ( // QueryPacket returns a packet from the store func QueryPacket( - ctx client.CLIContext, portID, channelID string, - sequence, timeout uint64, queryRoute string, + ctx client.CLIContext, portID, channelID string, sequence, timeout uint64, prove bool, ) (types.PacketResponse, error) { - var packetRes types.PacketResponse - req := abci.RequestQuery{ Path: "store/ibc/key", Data: types.KeyPacketCommitment(portID, channelID, sequence), - Prove: true, + Prove: prove, } res, err := ctx.QueryABCI(req) if err != nil { - return packetRes, err + return types.PacketResponse{}, err } - channel, err := QueryChannel(ctx, portID, channelID, queryRoute) + channelRes, err := QueryChannel(ctx, portID, channelID, prove) if err != nil { - return packetRes, err + return types.PacketResponse{}, err } - destPortID := channel.Channel.Counterparty.PortID - destChannelID := channel.Channel.Counterparty.ChannelID + destPortID := channelRes.Channel.Counterparty.PortID + destChannelID := channelRes.Channel.Counterparty.ChannelID packet := types.NewPacket( sequence, @@ -47,24 +44,25 @@ func QueryPacket( return types.NewPacketResponse(portID, channelID, sequence, packet, res.Proof, res.Height+1), nil } -// QueryChannel returns a channel from the store -func QueryChannel(ctx client.CLIContext, portID string, channelID string, queryRoute string) (types.ChannelResponse, error) { - var connRes types.ChannelResponse - +// QueryChannel queries the store to get a channel and a merkle proof. +func QueryChannel( + ctx client.CLIContext, portID, channelID string, prove bool, +) (types.ChannelResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", Data: types.KeyChannel(portID, channelID), - Prove: true, + Prove: prove, } res, err := ctx.QueryABCI(req) if res.Value == nil || err != nil { - return connRes, err + return types.ChannelResponse{}, err } var channel types.Channel if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { - return connRes, err + return types.ChannelResponse{}, err } + return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil } diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go index 707e9076ca39..9594f56473ef 100644 --- a/x/ibc/04-channel/types/querier.go +++ b/x/ibc/04-channel/types/querier.go @@ -69,3 +69,25 @@ func NewPacketResponse( ProofHeight: uint64(height), } } + +// RecvResponse defines the client query response for the next receive sequence +// number which also includes a proof, its path and the height form which the +// proof was retrieved +type RecvResponse struct { + NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewRecvResponse creates a new RecvResponse instance +func NewRecvResponse( + portID, channelID string, sequenceRecv uint64, proof *merkle.Proof, height int64, +) RecvResponse { + return RecvResponse{ + NextSequenceRecv: sequenceRecv, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(NextSequenceRecvPath(portID, channelID), "/")), + ProofHeight: uint64(height), + } +} diff --git a/x/ibc/05-port/keeper/keeper_test.go b/x/ibc/05-port/keeper/keeper_test.go index 320471d56030..c44c1f052d06 100644 --- a/x/ibc/05-port/keeper/keeper_test.go +++ b/x/ibc/05-port/keeper/keeper_test.go @@ -6,11 +6,12 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/05-port/keeper" - abci "github.com/tendermint/tendermint/abci/types" ) var ( diff --git a/x/ibc/20-transfer/client/cli/cli.go b/x/ibc/20-transfer/client/cli/cli.go new file mode 100644 index 000000000000..ce535761c9a9 --- /dev/null +++ b/x/ibc/20-transfer/client/cli/cli.go @@ -0,0 +1,37 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" +) + +// GetQueryCmd returns the query commands for IBC fungible token transfer +func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { + ics20TransferQueryCmd := &cobra.Command{ + Use: "transfer", + Short: "IBC fungible token transfer query subcommands", + } + + ics20TransferQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryNextSequence(cdc, queryRoute), + )...) + + return ics20TransferQueryCmd +} + +// GetTxCmd returns the transaction commands for IBC fungible token transfer +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + ics20TransferTxCmd := &cobra.Command{ + Use: "transfer", + Short: "IBC fungible token transfer transaction subcommands", + } + + ics20TransferTxCmd.AddCommand(client.PostCommands( + GetTransferTxCmd(cdc), + GetMsgRecvPacketCmd(cdc), + )...) + + return ics20TransferTxCmd +} diff --git a/x/ibc/20-transfer/client/cli/query.go b/x/ibc/20-transfer/client/cli/query.go index 6aad7157e228..6c431ea1ee12 100644 --- a/x/ibc/20-transfer/client/cli/query.go +++ b/x/ibc/20-transfer/client/cli/query.go @@ -1,35 +1,19 @@ package cli import ( - "encoding/binary" "fmt" "strings" "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" + "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/utils" ) -// GetQueryCmd returns the query commands for IBC fungible token transfer -func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { - queryCmd := &cobra.Command{ - Use: "transfer", - Short: "IBC fungible token transfer query subcommands", - } - - queryCmd.AddCommand( - GetCmdQueryNextSequence(cdc, queryRoute), - ) - - return queryCmd -} - // GetCmdQueryNextSequence defines the command to query a next receive sequence func GetCmdQueryNextSequence(cdc *codec.Codec, queryRoute string) *cobra.Command { cmd := &cobra.Command{ @@ -41,26 +25,20 @@ Example: $ %s query ibc channel next-recv [port-id] [channel-id] `, version.ClientName), ), - Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s query ibc channel next-recv [port-id] [channel-id]", version.ClientName), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) portID := args[0] channelID := args[1] + prove := viper.GetBool(flags.FlagProve) - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: channel.KeyNextSequenceRecv(portID, channelID), - Prove: true, - } - - res, err := cliCtx.QueryABCI(req) + sequenceRes, err := utils.QueryNextSequenceRecv(cliCtx, portID, channelID, prove) if err != nil { return err } - sequence := binary.BigEndian.Uint64(res.Value) - - return cliCtx.PrintOutput(sequence) + return cliCtx.PrintOutput(sequenceRes) }, } cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index 13917f47a62d..ef56f1430b1d 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -31,20 +31,6 @@ var ( FlagTimeout = "timeout" ) -// GetTxCmd returns the transaction commands for IBC fungible token transfer -func GetTxCmd(cdc *codec.Codec) *cobra.Command { - txCmd := &cobra.Command{ - Use: "transfer", - Short: "IBC fungible token transfer transaction subcommands", - } - txCmd.AddCommand( - GetTransferTxCmd(cdc), - GetMsgRecvPacketCmd(cdc), - ) - - return txCmd -} - // GetTransferTxCmd returns the command to create a NewMsgTransfer transaction func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -94,6 +80,7 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + prove := viper.GetBool(flags.FlagProve) node2 := viper.GetString(FlagNode2) cid1 := viper.GetString(flags.FlagChainID) cid2 := viper.GetString(FlagChainID2) @@ -101,7 +88,7 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { WithCodec(cdc). WithBroadcastMode(flags.BroadcastBlock) - header, err := clientutils.GetTendermintHeader(cliCtx2) + header, _, err := clientutils.QueryTendermintHeader(cliCtx2) if err != nil { return err } @@ -126,16 +113,18 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { viper.Set(flags.FlagChainID, cid2) sequence := uint64(viper.GetInt(FlagSequence)) - packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), "ibc") + packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), prove) if err != nil { return err } + viper.Set(flags.FlagChainID, cid1) msg := types.NewMsgRecvPacket(packetRes.Packet, []commitment.Proof{packetRes.Proof}, packetRes.ProofHeight, cliCtx.GetFromAddress()) if err := msg.ValidateBasic(); err != nil { return err } + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } @@ -146,5 +135,6 @@ func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") cmd.Flags().String(FlagSequence, "", "sequence for the packet") cmd.Flags().String(FlagTimeout, "", "timeout for the packet") + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") return cmd } diff --git a/x/ibc/20-transfer/client/rest/query.go b/x/ibc/20-transfer/client/rest/query.go index 8e979152a768..1b9b42a877e6 100644 --- a/x/ibc/20-transfer/client/rest/query.go +++ b/x/ibc/20-transfer/client/rest/query.go @@ -1,17 +1,14 @@ package rest import ( - "encoding/binary" "fmt" "net/http" "github.com/gorilla/mux" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/utils" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { @@ -34,27 +31,20 @@ func queryNextSequenceRecvHandlerFn(cliCtx context.CLIContext) http.HandlerFunc vars := mux.Vars(r) portID := vars[RestPortID] channelID := vars[RestChannelID] + prove := rest.ParseQueryProve(r) cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) if !ok { return } - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: channel.KeyNextSequenceRecv(portID, channelID), - Prove: rest.ParseQueryProve(r), - } - - res, err := cliCtx.QueryABCI(req) + sequenceRes, err := utils.QueryNextSequenceRecv(cliCtx, portID, channelID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - sequence := binary.BigEndian.Uint64(res.Value) - - cliCtx = cliCtx.WithHeight(res.Height) - rest.PostProcessResponse(w, cliCtx, sequence) + cliCtx = cliCtx.WithHeight(int64(sequenceRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, sequenceRes) } } diff --git a/x/ibc/20-transfer/client/utils/utils.go b/x/ibc/20-transfer/client/utils/utils.go new file mode 100644 index 000000000000..b89b2116b8d4 --- /dev/null +++ b/x/ibc/20-transfer/client/utils/utils.go @@ -0,0 +1,32 @@ +package utils + +import ( + "encoding/binary" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client/context" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// QueryNextSequenceRecv queries the store to get the next receive sequence and +// a merkle proof. +func QueryNextSequenceRecv( + cliCtx context.CLIContext, portID, channelID string, prove bool, +) (channeltypes.RecvResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: channeltypes.KeyNextSequenceRecv(portID, channelID), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return channeltypes.RecvResponse{}, err + } + + sequence := binary.BigEndian.Uint64(res.Value) + sequenceRes := channeltypes.NewRecvResponse(portID, channelID, sequence, res.Proof, res.Height) + + return sequenceRes, nil +} diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 89fad1195d09..7e0f430ddaa9 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -4,6 +4,9 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" @@ -16,8 +19,6 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/supply" - "github.com/stretchr/testify/suite" - abci "github.com/tendermint/tendermint/abci/types" ) // define constants used for testing diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index e5023a662caf..b7370a34d29f 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -4,6 +4,10 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" @@ -11,9 +15,6 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - "github.com/stretchr/testify/suite" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" ) // define constants used for testing diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 7546fc48a98c..fe20d2b26062 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "fmt" + abci "github.com/tendermint/tendermint/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" @@ -11,7 +13,6 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/supply" - abci "github.com/tendermint/tendermint/abci/types" ) func (suite *KeeperTestSuite) createClient() { diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go index f0b500b10d2f..935f94f0419f 100644 --- a/x/ibc/20-transfer/types/msgs_test.go +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -4,12 +4,13 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/merkle" + sdk "github.com/cosmos/cosmos-sdk/types" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/merkle" ) // define constants used for testing From 48a853bfdaf0cbfecd79dabd4111f7e9f0f24540 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 3 Dec 2019 16:36:04 +0100 Subject: [PATCH 050/176] fix build; comment handshakes --- x/ibc/02-client/client/cli/tx.go | 16 +- x/ibc/03-connection/client/cli/cli.go | 1 - x/ibc/03-connection/client/cli/tx.go | 573 ++++++++++++-------------- x/ibc/04-channel/client/cli/cli.go | 1 - x/ibc/04-channel/client/cli/tx.go | 457 ++++++++++---------- x/ibc/20-transfer/client/cli/cli.go | 2 +- x/ibc/20-transfer/client/cli/tx.go | 150 ++++--- 7 files changed, 589 insertions(+), 611 deletions(-) diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 2c8abcff4c95..197f7271b011 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -1,6 +1,7 @@ package cli import ( + "bufio" "fmt" "io/ioutil" "os" @@ -33,8 +34,9 @@ $ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node ), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) clientID := args[0] @@ -80,8 +82,9 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home ), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) clientID := args[0] @@ -124,8 +127,9 @@ $ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 ), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) clientID := args[0] diff --git a/x/ibc/03-connection/client/cli/cli.go b/x/ibc/03-connection/client/cli/cli.go index 820baa02b3b6..9d3777f1fefa 100644 --- a/x/ibc/03-connection/client/cli/cli.go +++ b/x/ibc/03-connection/client/cli/cli.go @@ -34,7 +34,6 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { GetCmdConnectionOpenTry(storeKey, cdc), GetCmdConnectionOpenAck(storeKey, cdc), GetCmdConnectionOpenConfirm(storeKey, cdc), - GetCmdHandshakeState(storeKey, cdc), )...) return ics03ConnectionTxCmd diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index c2324322f08f..3ad967b785d2 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -1,30 +1,24 @@ package cli import ( + "bufio" "fmt" "io/ioutil" "os" "strings" - "time" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -55,8 +49,9 @@ $ %s tx ibc connection open-init [connection-id] [client-id] [counterparty-conne ), Args: cobra.ExactArgs(6), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] clientID := args[1] @@ -107,8 +102,9 @@ $ %s tx ibc connection open-try connection-id] [client-id] ), Args: cobra.ExactArgs(6), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext(). + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) @@ -177,8 +173,9 @@ $ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [versio ), Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] proofBz, err := ioutil.ReadFile(args[1]) @@ -229,8 +226,9 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] ), Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext(). + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) @@ -277,289 +275,6 @@ func lastHeight(cliCtx context.CLIContext) (uint64, error) { return uint64(info.Response.LastBlockHeight), nil } -func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "handshake [conn-id-chain-1] [client-id-chain-1] [path-chain-1] [conn-id-chain-2] [client-id-chain-2] [path-chain-2] ", - Short: "initiate connection handshake between two chains", - Args: cobra.ExactArgs(6), - RunE: func(cmd *cobra.Command, args []string) error { - - prove := true - - // --chain-id values for each chain - cid1 := viper.GetString(flags.FlagChainID) - cid2 := viper.GetString(FlagChainID2) - - // --from values for each wallet - from1 := viper.GetString(FlagFrom1) - from2 := viper.GetString(FlagFrom2) - - // --node values for each RPC - rpc1 := viper.GetString(FlagNode1) - rpc2 := viper.GetString(FlagNode2) - - // ibc connection-id for each chain - connID1 := args[0] - connID2 := args[3] - - // ibc client-id for each chain - clientID1 := args[1] - clientID2 := args[4] - - // Get default version - version := types.GetCompatibleVersions()[0] - - // Create txbldr, clictx, querier for cid1 - viper.Set(flags.FlagChainID, cid1) - txBldr1 := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - ctx1 := context.NewCLIContextIBC(from1, cid1, rpc1).WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - // Create txbldr, clictx, querier for cid1 - viper.Set(flags.FlagChainID, cid2) - txBldr2 := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - ctx2 := context.NewCLIContextIBC(from2, cid2, rpc2).WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - // read in path for cid1 - path1, err := parsePath(ctx1.Codec, args[2]) - if err != nil { - return err - } - - // read in path for cid2 - path2, err := parsePath(ctx1.Codec, args[5]) - if err != nil { - return err - } - - // get passphrase for key from1 - passphrase1, err := keys.GetPassphrase(from1) - if err != nil { - return err - } - - // get passphrase for key from2 - passphrase2, err := keys.GetPassphrase(from2) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid1) - msgOpenInit := types.NewMsgConnectionOpenInit( - connID1, clientID1, connID2, clientID2, - path2, ctx1.GetFromAddress(), - ) - - if err := msgOpenInit.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid1, msgOpenInit.Type()) - res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - - fmt.Printf(" [OK] txid(%v) client(%v) conn(%v)\n", res.TxHash, clientID1, connID1) - - // Another block has to be passed after msgOpenInit is committed - // to retrieve the correct proofs - // TODO: Modify this to actually check two blocks being processed, and - // remove hardcoding this to 8 seconds. - time.Sleep(8 * time.Second) - - header, _, err := clientutils.QueryTendermintHeader(ctx1) - if err != nil { - return err - } - - // Create and send msgUpdateClient - viper.Set(flags.FlagChainID, cid2) - msgUpdateClient := clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) - - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - - // Fetch proofs from cid1 - viper.Set(flags.FlagChainID, cid1) - proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) - if err != nil { - return err - } - - csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1, prove) - if err != nil { - return err - } - - // Create and send msgOpenTry - viper.Set(flags.FlagChainID, cid2) - msgOpenTry := types.NewMsgConnectionOpenTry(connID2, clientID2, connID1, clientID1, path1, []string{version}, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), ctx2.GetFromAddress()) - - if err := msgOpenTry.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid2, msgOpenTry.Type()) - - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - fmt.Printf(" [OK] txid(%v) client(%v) connection(%v)\n", res.TxHash, clientID2, connID2) - - // Another block has to be passed after msgOpenInit is committed - // to retrieve the correct proofs - // TODO: Modify this to actually check two blocks being processed, and - // remove hardcoding this to 8 seconds. - time.Sleep(8 * time.Second) - - header, _, err = clientutils.QueryTendermintHeader(ctx2) - if err != nil { - return err - } - - // Update the client for cid2 on cid1 - viper.Set(flags.FlagChainID, cid1) - msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID1, header, ctx1.GetFromAddress()) - - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID2) - - // Fetch proofs from cid2 - viper.Set(flags.FlagChainID, cid2) - proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), connID2, storeKey) - if err != nil { - return err - } - - csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2, prove) - if err != nil { - return err - } - - // Create and send msgOpenAck - viper.Set(flags.FlagChainID, cid1) - msgOpenAck := types.NewMsgConnectionOpenAck(connID1, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), version, ctx1.GetFromAddress()) - - if err := msgOpenAck.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid1, msgOpenAck.Type()) - - res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID1) - - // Another block has to be passed after msgOpenInit is committed - // to retrieve the correct proofs - // TODO: Modify this to actually check two blocks being processed, and - // remove hardcoding this to 8 seconds. - time.Sleep(8 * time.Second) - - header, _, err = clientutils.QueryTendermintHeader(ctx1) - if err != nil { - return err - } - - // Update client for cid1 on cid2 - viper.Set(flags.FlagChainID, cid2) - msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) - - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) - - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - - viper.Set(flags.FlagChainID, cid1) - proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) - if err != nil { - return err - } - - // Create and send msgOpenConfirm - viper.Set(flags.FlagChainID, cid2) - msgOpenConfirm := types.NewMsgConnectionOpenConfirm(connID2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) - - if err := msgOpenConfirm.ValidateBasic(); err != nil { - return err - } - - fmt.Printf("%v <- %-14v", cid1, msgOpenConfirm.Type()) - - res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID2) - - return nil - }, - } - - cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") - cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") - cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") - cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") - cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") - - cmd.MarkFlagRequired(FlagNode1) - cmd.MarkFlagRequired(FlagNode2) - cmd.MarkFlagRequired(FlagFrom1) - cmd.MarkFlagRequired(FlagFrom2) - cmd.MarkFlagRequired(FlagChainID2) - - return cmd -} - -func queryProofs(ctx client.CLIContext, connectionID string, queryRoute string) (types.ConnectionResponse, error) { - - var connRes types.ConnectionResponse - - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: []byte(fmt.Sprintf("connections/%s", connectionID)), - Prove: true, - } - res, err := ctx.QueryABCI(req) - if err != nil { - return connRes, err - } - - var connection types.ConnectionEnd - if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &connection); err != nil { - return connRes, err - } - return types.NewConnectionResponse(connectionID, connection, res.Proof, res.Height), nil -} - func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { var path commitment.Prefix if err := cdc.UnmarshalJSON([]byte(arg), &path); err != nil { @@ -574,3 +289,265 @@ func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { } return path, nil } + +// func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { +// cmd := &cobra.Command{ +// Use: "handshake [conn-id-chain-1] [client-id-chain-1] [path-chain-1] [conn-id-chain-2] [client-id-chain-2] [path-chain-2] ", +// Short: "initiate connection handshake between two chains", +// Args: cobra.ExactArgs(6), +// RunE: func(cmd *cobra.Command, args []string) error { +// inBuf := bufio.NewReader(cmd.InOrStdin()) +// prove := true + +// // --chain-id values for each chain +// cid1 := viper.GetString(flags.FlagChainID) +// cid2 := viper.GetString(FlagChainID2) + +// // --from values for each wallet +// from1 := viper.GetString(FlagFrom1) +// from2 := viper.GetString(FlagFrom2) + +// // --node values for each RPC +// rpc1 := viper.GetString(FlagNode1) +// rpc2 := viper.GetString(FlagNode2) + +// // ibc connection-id for each chain +// connID1 := args[0] +// connID2 := args[3] + +// // ibc client-id for each chain +// clientID1 := args[1] +// clientID2 := args[4] + +// // Get default version +// version := types.GetCompatibleVersions()[0] + +// // Create txbldr, clictx, querier for cid1 +// viper.Set(flags.FlagChainID, cid1) +// txBldr1 := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) +// ctx1 := context.NewCLIContextIBC(inBuf, from1, cid1, rpc1).WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// // Create txbldr, clictx, querier for cid1 +// viper.Set(flags.FlagChainID, cid2) +// txBldr2 := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) +// ctx2 := context.NewCLIContextIBC(inBuf, from2, cid2, rpc2).WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// // read in path for cid1 +// path1, err := parsePath(ctx1.Codec, args[2]) +// if err != nil { +// return err +// } + +// // read in path for cid2 +// path2, err := parsePath(ctx1.Codec, args[5]) +// if err != nil { +// return err +// } + +// // get passphrase for key from1 +// passphrase1, err := keys.GetPassphrase(from1) +// if err != nil { +// return err +// } + +// // get passphrase for key from2 +// passphrase2, err := keys.GetPassphrase(from2) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// msgOpenInit := types.NewMsgConnectionOpenInit( +// connID1, clientID1, connID2, clientID2, +// path2, ctx1.GetFromAddress(), +// ) + +// if err := msgOpenInit.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid1, msgOpenInit.Type()) +// res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } + +// fmt.Printf(" [OK] txid(%v) client(%v) conn(%v)\n", res.TxHash, clientID1, connID1) + +// // Another block has to be passed after msgOpenInit is committed +// // to retrieve the correct proofs +// // TODO: Modify this to actually check two blocks being processed, and +// // remove hardcoding this to 8 seconds. +// time.Sleep(8 * time.Second) + +// header, _, err := clientutils.QueryTendermintHeader(ctx1) +// if err != nil { +// return err +// } + +// // Create and send msgUpdateClient +// viper.Set(flags.FlagChainID, cid2) +// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) + +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) +// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) + +// // Fetch proofs from cid1 +// viper.Set(flags.FlagChainID, cid1) +// proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) +// if err != nil { +// return err +// } + +// csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1, prove) +// if err != nil { +// return err +// } + +// // Create and send msgOpenTry +// viper.Set(flags.FlagChainID, cid2) +// msgOpenTry := types.NewMsgConnectionOpenTry(connID2, clientID2, connID1, clientID1, path1, []string{version}, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), ctx2.GetFromAddress()) + +// if err := msgOpenTry.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid2, msgOpenTry.Type()) + +// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// fmt.Printf(" [OK] txid(%v) client(%v) connection(%v)\n", res.TxHash, clientID2, connID2) + +// // Another block has to be passed after msgOpenInit is committed +// // to retrieve the correct proofs +// // TODO: Modify this to actually check two blocks being processed, and +// // remove hardcoding this to 8 seconds. +// time.Sleep(8 * time.Second) + +// header, _, err = clientutils.QueryTendermintHeader(ctx2) +// if err != nil { +// return err +// } + +// // Update the client for cid2 on cid1 +// viper.Set(flags.FlagChainID, cid1) +// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID1, header, ctx1.GetFromAddress()) + +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID2) + +// // Fetch proofs from cid2 +// viper.Set(flags.FlagChainID, cid2) +// proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), connID2, storeKey) +// if err != nil { +// return err +// } + +// csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2, prove) +// if err != nil { +// return err +// } + +// // Create and send msgOpenAck +// viper.Set(flags.FlagChainID, cid1) +// msgOpenAck := types.NewMsgConnectionOpenAck(connID1, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), version, ctx1.GetFromAddress()) + +// if err := msgOpenAck.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid1, msgOpenAck.Type()) + +// res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID1) + +// // Another block has to be passed after msgOpenInit is committed +// // to retrieve the correct proofs +// // TODO: Modify this to actually check two blocks being processed, and +// // remove hardcoding this to 8 seconds. +// time.Sleep(8 * time.Second) + +// header, _, err = clientutils.QueryTendermintHeader(ctx1) +// if err != nil { +// return err +// } + +// // Update client for cid1 on cid2 +// viper.Set(flags.FlagChainID, cid2) +// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) + +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) + +// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) + +// viper.Set(flags.FlagChainID, cid1) +// proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) +// if err != nil { +// return err +// } + +// // Create and send msgOpenConfirm +// viper.Set(flags.FlagChainID, cid2) +// msgOpenConfirm := types.NewMsgConnectionOpenConfirm(connID2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) + +// if err := msgOpenConfirm.ValidateBasic(); err != nil { +// return err +// } + +// fmt.Printf("%v <- %-14v", cid1, msgOpenConfirm.Type()) + +// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } +// fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID2) + +// return nil +// }, +// } + +// cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") +// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") +// cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") +// cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") +// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") + +// cmd.MarkFlagRequired(FlagNode1) +// cmd.MarkFlagRequired(FlagNode2) +// cmd.MarkFlagRequired(FlagFrom1) +// cmd.MarkFlagRequired(FlagFrom2) +// cmd.MarkFlagRequired(FlagChainID2) + +// return cmd +// } diff --git a/x/ibc/04-channel/client/cli/cli.go b/x/ibc/04-channel/client/cli/cli.go index 2f6e76ca9b13..35bd02203a1d 100644 --- a/x/ibc/04-channel/client/cli/cli.go +++ b/x/ibc/04-channel/client/cli/cli.go @@ -36,7 +36,6 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { GetMsgChannelOpenConfirmCmd(storeKey, cdc), GetMsgChannelCloseInitCmd(storeKey, cdc), GetMsgChannelCloseConfirmCmd(storeKey, cdc), - GetCmdHandshake(storeKey, cdc), )...) return ics04ChannelTxCmd diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index ff0123a060b6..a0d5ceade64f 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -1,27 +1,21 @@ package cli import ( + "bufio" "fmt" "io/ioutil" "os" "strconv" "strings" - "time" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -45,8 +39,9 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Short: "Creates and sends a ChannelOpenInit message", Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -81,8 +76,9 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Creates and sends a ChannelOpenTry message", Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -134,8 +130,9 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "Creates and sends a ChannelOpenAck message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -179,8 +176,9 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma Short: "Creates and sends a ChannelOpenConfirm message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -221,8 +219,9 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Short: "Creates and sends a ChannelCloseInit message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -244,8 +243,9 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm Short: "Creates and sends a ChannelCloseConfirm message", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(authutils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] channelID := args[1] @@ -279,218 +279,219 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm } } -func GetCmdHandshake(storeKey string, cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "handshake", - Short: "initiate connection handshake between two chains", - Long: strings.TrimSpace( - fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: - -Example: -$ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-client-id] [cp-port-id] [cp-chain-id] [cp-conn-id] - `, version.ClientName)), - Args: cobra.ExactArgs(8), - // Args: []string{portid1, chanid1, connid1, portid2, chanid2, connid2} - RunE: func(cmd *cobra.Command, args []string) error { - // --chain-id values for each chain - cid1 := viper.GetString(flags.FlagChainID) - cid2 := viper.GetString(FlagChainID2) - - // --from values for each wallet - from1 := viper.GetString(FlagFrom1) - from2 := viper.GetString(FlagFrom2) - - // --node values for each RPC - node1 := viper.GetString(FlagNode1) - node2 := viper.GetString(FlagNode2) - - // client IDs - clientid1 := args[0] - clientid2 := args[4] - - // port IDs - portid1 := args[1] - portid2 := args[5] - - // channel IDs - chanid1 := args[2] - chanid2 := args[6] - - // connection IDs - connid1 := args[3] - connid2 := args[7] - - prove := true - - // Create txbldr, clictx, querier for cid1 - viper.Set(flags.FlagChainID, cid1) - txBldr1 := auth.NewTxBuilderFromCLI(). - WithTxEncoder(authutils.GetTxEncoder(cdc)) - ctx1 := context.NewCLIContextIBC(from1, cid1, node1). - WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - // Create txbldr, clictx, querier for cid2 - viper.Set(flags.FlagChainID, cid2) - txBldr2 := auth.NewTxBuilderFromCLI(). - WithTxEncoder(authutils.GetTxEncoder(cdc)) - ctx2 := context.NewCLIContextIBC(from2, cid2, node2). - WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - // get passphrase for key from1 - passphrase1, err := keys.GetPassphrase(from1) - if err != nil { - return err - } - - // get passphrase for key from2 - passphrase2, err := keys.GetPassphrase(from2) - if err != nil { - return err - } - - // TODO: check state and if not Idle continue existing process - viper.Set(flags.FlagChainID, cid1) - msgOpenInit := types.NewMsgChannelOpenInit(portid1, chanid1, "v1.0.0", channelOrder(), []string{connid1}, portid2, chanid2, ctx1.GetFromAddress()) - if err := msgOpenInit.ValidateBasic(); err != nil { - return err - } - - res, err := authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - - // Another block has to be passed after msginit is committed - // to retrieve the correct proofs - time.Sleep(8 * time.Second) - - header, _, err := clientutils.QueryTendermintHeader(ctx1) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid2) - msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - viper.Set(flags.FlagChainID, cid1) - channelRes, err := utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) - if err != nil { - return err - } - - msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - // Another block has to be passed after msginit is committed - // to retrieve the correct proofs - time.Sleep(8 * time.Second) - - header, _, err = clientutils.QueryTendermintHeader(ctx2) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid1) - msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid1, header, ctx1.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - - viper.Set(flags.FlagChainID, cid2) - channelRes, err = utils.QueryChannel(ctx2.WithHeight(header.Height-1), portid2, chanid2, prove) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid1) - msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx1.GetFromAddress()) - if err := msgOpenAck.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) - if err != nil || !res.IsOK() { - return err - } - - // Another block has to be passed after msginit is committed - // to retrieve the correct proofs - time.Sleep(8 * time.Second) - - header, _, err = clientutils.QueryTendermintHeader(ctx1) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid2) - msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - viper.Set(flags.FlagChainID, cid1) - channelRes, err = utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) - if err != nil { - return err - } - - msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) - if err := msgOpenConfirm.ValidateBasic(); err != nil { - return err - } - - res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) - if err != nil || !res.IsOK() { - return err - } - - return nil - }, - } - - cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") - cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") - cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") - cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") - cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") - cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") - - cmd.MarkFlagRequired(FlagFrom1) - cmd.MarkFlagRequired(FlagFrom2) - - return cmd -} - func channelOrder() types.Order { if viper.GetBool(FlagOrdered) { return types.ORDERED } return types.UNORDERED } + +// func GetCmdHandshake(storeKey string, cdc *codec.Codec) *cobra.Command { +// cmd := &cobra.Command{ +// Use: "handshake", +// Short: "initiate connection handshake between two chains", +// Long: strings.TrimSpace( +// fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: + +// Example: +// $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-client-id] [cp-port-id] [cp-chain-id] [cp-conn-id] +// `, version.ClientName)), +// Args: cobra.ExactArgs(8), +// // Args: []string{portid1, chanid1, connid1, portid2, chanid2, connid2} +// RunE: func(cmd *cobra.Command, args []string) error { +// // --chain-id values for each chain +// cid1 := viper.GetString(flags.FlagChainID) +// cid2 := viper.GetString(FlagChainID2) + +// // --from values for each wallet +// from1 := viper.GetString(FlagFrom1) +// from2 := viper.GetString(FlagFrom2) + +// // --node values for each RPC +// node1 := viper.GetString(FlagNode1) +// node2 := viper.GetString(FlagNode2) + +// // client IDs +// clientid1 := args[0] +// clientid2 := args[4] + +// // port IDs +// portid1 := args[1] +// portid2 := args[5] + +// // channel IDs +// chanid1 := args[2] +// chanid2 := args[6] + +// // connection IDs +// connid1 := args[3] +// connid2 := args[7] + +// inBuf := bufio.NewReader(cmd.InOrStdin()) +// prove := true + +// // Create txbldr, clictx, querier for cid1 +// viper.Set(flags.FlagChainID, cid1) +// txBldr1 := auth.NewTxBuilderFromCLI(inBuf). +// WithTxEncoder(authutils.GetTxEncoder(cdc)) +// ctx1 := context.NewCLIContextIBC(inBuf, from1, cid1, node1). +// WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// // Create txbldr, clictx, querier for cid2 +// viper.Set(flags.FlagChainID, cid2) +// txBldr2 := auth.NewTxBuilderFromCLI(inBuf). +// WithTxEncoder(authutils.GetTxEncoder(cdc)) +// ctx2 := context.NewCLIContextIBC(inBuf, from2, cid2, node2). +// WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// // get passphrase for key from1 +// passphrase1, err := keys.GetPassphrase(from1) +// if err != nil { +// return err +// } + +// // get passphrase for key from2 +// passphrase2, err := keys.GetPassphrase(from2) +// if err != nil { +// return err +// } + +// // TODO: check state and if not Idle continue existing process +// viper.Set(flags.FlagChainID, cid1) +// msgOpenInit := types.NewMsgChannelOpenInit(portid1, chanid1, "v1.0.0", channelOrder(), []string{connid1}, portid2, chanid2, ctx1.GetFromAddress()) +// if err := msgOpenInit.ValidateBasic(); err != nil { +// return err +// } + +// res, err := authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } + +// // Another block has to be passed after msginit is committed +// // to retrieve the correct proofs +// time.Sleep(8 * time.Second) + +// header, _, err := clientutils.QueryTendermintHeader(ctx1) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid2) +// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// channelRes, err := utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) +// if err != nil { +// return err +// } + +// msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// // Another block has to be passed after msginit is committed +// // to retrieve the correct proofs +// time.Sleep(8 * time.Second) + +// header, _, err = clientutils.QueryTendermintHeader(ctx2) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid1, header, ctx1.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } + +// viper.Set(flags.FlagChainID, cid2) +// channelRes, err = utils.QueryChannel(ctx2.WithHeight(header.Height-1), portid2, chanid2, prove) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx1.GetFromAddress()) +// if err := msgOpenAck.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) +// if err != nil || !res.IsOK() { +// return err +// } + +// // Another block has to be passed after msginit is committed +// // to retrieve the correct proofs +// time.Sleep(8 * time.Second) + +// header, _, err = clientutils.QueryTendermintHeader(ctx1) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid2) +// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) +// channelRes, err = utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) +// if err != nil { +// return err +// } + +// msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) +// if err := msgOpenConfirm.ValidateBasic(); err != nil { +// return err +// } + +// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) +// if err != nil || !res.IsOK() { +// return err +// } + +// return nil +// }, +// } + +// cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") +// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") +// cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") +// cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") +// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") +// cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") + +// cmd.MarkFlagRequired(FlagFrom1) +// cmd.MarkFlagRequired(FlagFrom2) + +// return cmd +// } diff --git a/x/ibc/20-transfer/client/cli/cli.go b/x/ibc/20-transfer/client/cli/cli.go index ce535761c9a9..2007ed31908d 100644 --- a/x/ibc/20-transfer/client/cli/cli.go +++ b/x/ibc/20-transfer/client/cli/cli.go @@ -30,7 +30,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { ics20TransferTxCmd.AddCommand(client.PostCommands( GetTransferTxCmd(cdc), - GetMsgRecvPacketCmd(cdc), + // GetMsgRecvPacketCmd(cdc), )...) return ics20TransferTxCmd diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index ef56f1430b1d..dc14a53c5a3b 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -1,22 +1,18 @@ package cli import ( + "bufio" + "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - channelutils "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // IBC transfer flags @@ -38,8 +34,9 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { Short: "Transfer fungible token through IBC", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - ctx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + ctx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) sender := ctx.GetFromAddress() srcPort := args[0] @@ -70,71 +67,72 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { return cmd } -// GetMsgRecvPacketCmd returns the command to create a MsgRecvTransferPacket transaction -func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "recv-packet [sending-port-id] [sending-channel-id] [client-id]", - Short: "Creates and sends a SendPacket message", - Args: cobra.ExactArgs(3), - RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext().WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) - - prove := viper.GetBool(flags.FlagProve) - node2 := viper.GetString(FlagNode2) - cid1 := viper.GetString(flags.FlagChainID) - cid2 := viper.GetString(FlagChainID2) - cliCtx2 := context.NewCLIContextIBC(cliCtx.GetFromAddress().String(), cid2, node2). - WithCodec(cdc). - WithBroadcastMode(flags.BroadcastBlock) - - header, _, err := clientutils.QueryTendermintHeader(cliCtx2) - if err != nil { - return err - } - - sourcePort, sourceChannel, clientid := args[0], args[1], args[2] - - passphrase, err := keys.GetPassphrase(viper.GetString(flags.FlagFrom)) - if err != nil { - return nil - } - - viper.Set(flags.FlagChainID, cid1) - msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid, header, cliCtx.GetFromAddress()) - if err := msgUpdateClient.ValidateBasic(); err != nil { - return err - } - - res, err := utils.CompleteAndBroadcastTx(txBldr, cliCtx, []sdk.Msg{msgUpdateClient}, passphrase) - if err != nil || !res.IsOK() { - return err - } - - viper.Set(flags.FlagChainID, cid2) - sequence := uint64(viper.GetInt(FlagSequence)) - packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), prove) - if err != nil { - return err - } - - viper.Set(flags.FlagChainID, cid1) - - msg := types.NewMsgRecvPacket(packetRes.Packet, []commitment.Proof{packetRes.Proof}, packetRes.ProofHeight, cliCtx.GetFromAddress()) - if err := msg.ValidateBasic(); err != nil { - return err - } - - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) - }, - } - - cmd = client.PostCommands(cmd)[0] - cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") - cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") - cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") - cmd.Flags().String(FlagSequence, "", "sequence for the packet") - cmd.Flags().String(FlagTimeout, "", "timeout for the packet") - cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") - return cmd -} +// // GetMsgRecvPacketCmd returns the command to create a MsgRecvTransferPacket transaction +// func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { +// cmd := &cobra.Command{ +// Use: "recv-packet [sending-port-id] [sending-channel-id] [client-id]", +// Short: "Creates and sends a SendPacket message", +// Args: cobra.ExactArgs(3), +// RunE: func(cmd *cobra.Command, args []string) error { +// inBuf := bufio.NewReader(cmd.InOrStdin()) +// txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) +// cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + +// prove := viper.GetBool(flags.FlagProve) +// node2 := viper.GetString(FlagNode2) +// cid1 := viper.GetString(flags.FlagChainID) +// cid2 := viper.GetString(FlagChainID2) +// cliCtx2 := context.NewCLIContextIBC(cliCtx.GetFromAddress().String(), cid2, node2). +// WithCodec(cdc). +// WithBroadcastMode(flags.BroadcastBlock) + +// header, _, err := clientutils.QueryTendermintHeader(cliCtx2) +// if err != nil { +// return err +// } + +// sourcePort, sourceChannel, clientid := args[0], args[1], args[2] + +// passphrase, err := keys.GetPassphrase(viper.GetString(flags.FlagFrom)) +// if err != nil { +// return nil +// } + +// viper.Set(flags.FlagChainID, cid1) +// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid, header, cliCtx.GetFromAddress()) +// if err := msgUpdateClient.ValidateBasic(); err != nil { +// return err +// } + +// res, err := utils.CompleteAndBroadcastTx(txBldr, cliCtx, []sdk.Msg{msgUpdateClient}, passphrase) +// if err != nil || !res.IsOK() { +// return err +// } + +// viper.Set(flags.FlagChainID, cid2) +// sequence := uint64(viper.GetInt(FlagSequence)) +// packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), prove) +// if err != nil { +// return err +// } + +// viper.Set(flags.FlagChainID, cid1) + +// msg := types.NewMsgRecvPacket(packetRes.Packet, []commitment.Proof{packetRes.Proof}, packetRes.ProofHeight, cliCtx.GetFromAddress()) +// if err := msg.ValidateBasic(); err != nil { +// return err +// } + +// return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) +// }, +// } + +// cmd = client.PostCommands(cmd)[0] +// cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") +// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") +// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") +// cmd.Flags().String(FlagSequence, "", "sequence for the packet") +// cmd.Flags().String(FlagTimeout, "", "timeout for the packet") +// cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") +// return cmd +// } From 4bc70d627db6e62d995bd6d2b8221435a2dbcf63 Mon Sep 17 00:00:00 2001 From: Aditya Date: Thu, 5 Dec 2019 01:07:52 -0800 Subject: [PATCH 051/176] ICS-2 Implement Misbehavior (#5321) * ibc client evidence route * split evidence from misbehaviour * clean up client events * test misbehaviour and evidence * remove comments * remove frozen comments from demo * Update x/ibc/02-client/types/tendermint/evidence_test.go Co-Authored-By: Aditya * change evidence to detect malicious chain * remove unnecessary sort * fix evidence and persist committers to check misbehaviour * minor fixes and remove incorrect tests * add evidence tests * remove debug statements * cleanup evidence test * start misbehaviour tests * fix nondeterministic bug * add same height and next height checks in misbehaviour * fix bugs * apply fede review suggestions * finish code review changes * fix GetCommitter and write keeper-level misbehaviour tests * remove incorrect special case checking * save * final fixes * save * fix conflict * fix conflicts and add back submit misbehaviour msg * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * save * add godocs and fix test * fix test panics in other modules * Update x/ibc/02-client/keeper/client.go Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * add back aliases --- simapp/app.go | 6 +- x/evidence/exported/evidence.go | 12 +- x/ibc/02-client/alias.go | 11 +- x/ibc/02-client/client/cli/tx.go | 3 +- x/ibc/02-client/client/rest/rest.go | 3 +- x/ibc/02-client/exported/exported.go | 42 ++-- x/ibc/02-client/handler.go | 39 ++-- x/ibc/02-client/keeper/client.go | 44 +++- x/ibc/02-client/keeper/client_test.go | 111 +++++++++- x/ibc/02-client/keeper/keeper.go | 74 ++++--- x/ibc/02-client/keeper/keeper_test.go | 51 ++++- x/ibc/02-client/types/codec.go | 3 +- x/ibc/02-client/types/errors/errors.go | 22 +- x/ibc/02-client/types/events.go | 6 +- x/ibc/02-client/types/keys.go | 22 +- x/ibc/02-client/types/msgs.go | 16 +- x/ibc/02-client/types/msgs_test.go | 55 +++-- x/ibc/02-client/types/tendermint/codec.go | 3 + x/ibc/02-client/types/tendermint/committer.go | 26 +++ .../types/tendermint/consensus_state.go | 21 +- .../types/tendermint/consensus_state_test.go | 13 +- x/ibc/02-client/types/tendermint/doc.go | 4 +- x/ibc/02-client/types/tendermint/evidence.go | 106 +++++++++ .../types/tendermint/evidence_test.go | 135 ++++++++++++ x/ibc/02-client/types/tendermint/header.go | 26 +++ .../types/tendermint/misbehaviour.go | 111 ++++------ .../types/tendermint/misbehaviour_test.go | 202 +++++++++++++----- .../types/tendermint/tendermint_test.go | 3 +- .../02-client/types/tendermint/test_utils.go | 37 +--- x/ibc/03-connection/keeper/handshake_test.go | 8 +- x/ibc/03-connection/keeper/keeper_test.go | 13 +- x/ibc/04-channel/keeper/handshake_test.go | 10 +- x/ibc/04-channel/keeper/keeper_test.go | 13 +- x/ibc/20-transfer/handler_test.go | 21 +- x/ibc/20-transfer/keeper/keeper_test.go | 13 +- x/ibc/20-transfer/keeper/relay_test.go | 8 +- x/ibc/handler.go | 3 - 37 files changed, 954 insertions(+), 342 deletions(-) create mode 100644 x/ibc/02-client/types/tendermint/committer.go create mode 100644 x/ibc/02-client/types/tendermint/evidence.go create mode 100644 x/ibc/02-client/types/tendermint/evidence_test.go diff --git a/simapp/app.go b/simapp/app.go index 81d7fd4b6e21..4a46d34e07dd 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -24,6 +24,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/ibc" + ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" ibctransfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/params" @@ -208,8 +209,9 @@ func NewSimApp( evidenceKeeper := evidence.NewKeeper( app.cdc, keys[evidence.StoreKey], app.subspaces[evidence.ModuleName], &app.StakingKeeper, app.SlashingKeeper, ) - evidenceRouter := evidence.NewRouter() - // TODO: Register evidence routes. + evidenceRouter := evidence.NewRouter(). + AddRoute(ibcclient.RouterKey, ibcclient.HandlerClientMisbehaviour(app.IBCKeeper.ClientKeeper)) + evidenceKeeper.SetRouter(evidenceRouter) app.EvidenceKeeper = *evidenceKeeper diff --git a/x/evidence/exported/evidence.go b/x/evidence/exported/evidence.go index 1c6adfdf8c0a..79ce2bec737f 100644 --- a/x/evidence/exported/evidence.go +++ b/x/evidence/exported/evidence.go @@ -15,11 +15,17 @@ type Evidence interface { Hash() cmn.HexBytes ValidateBasic() error - // The consensus address of the malicious validator at time of infraction - GetConsensusAddress() sdk.ConsAddress - // Height at which the infraction occurred GetHeight() int64 +} + +// ValidatorEvidence extends Evidence interface to define contract +// for evidence against malicious validators +type ValidatorEvidence interface { + Evidence + + // The consensus address of the malicious validator at time of infraction + GetConsensusAddress() sdk.ConsAddress // The total power of the malicious validator at time of infraction GetValidatorPower() int64 diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go index 00519d9da512..4713a4e77dee 100644 --- a/x/ibc/02-client/alias.go +++ b/x/ibc/02-client/alias.go @@ -61,17 +61,16 @@ var ( KeyRoot = types.KeyRoot NewMsgCreateClient = types.NewMsgCreateClient NewMsgUpdateClient = types.NewMsgUpdateClient - NewMsgSubmitMisbehaviour = types.NewMsgSubmitMisbehaviour + NewMsgSubmitMibehaviour = types.NewMsgSubmitMisbehaviour NewQueryClientStateParams = types.NewQueryClientStateParams NewQueryCommitmentRootParams = types.NewQueryCommitmentRootParams NewClientState = types.NewClientState // variable aliases - SubModuleCdc = types.SubModuleCdc - EventTypeCreateClient = types.EventTypeCreateClient - EventTypeUpdateClient = types.EventTypeUpdateClient - EventTypeSubmitMisbehaviour = types.EventTypeSubmitMisbehaviour - AttributeValueCategory = types.AttributeValueCategory + SubModuleCdc = types.SubModuleCdc + EventTypeCreateClient = types.EventTypeCreateClient + EventTypeUpdateClient = types.EventTypeUpdateClient + AttributeValueCategory = types.AttributeValueCategory ) type ( diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 197f7271b011..9e666f8f926b 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -16,6 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ) @@ -133,7 +134,7 @@ $ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 clientID := args[0] - var evidence exported.Evidence + var evidence evidenceexported.Evidence if err := cdc.UnmarshalJSON([]byte(args[1]), &evidence); err != nil { fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") diff --git a/x/ibc/02-client/client/rest/rest.go b/x/ibc/02-client/client/rest/rest.go index fb832f63a69a..51f8ce762bcb 100644 --- a/x/ibc/02-client/client/rest/rest.go +++ b/x/ibc/02-client/client/rest/rest.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" ) @@ -35,5 +36,5 @@ type UpdateClientReq struct { // SubmitMisbehaviourReq defines the properties of a submit misbehaviour request's body. type SubmitMisbehaviourReq struct { BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - Evidence exported.Evidence `json:"evidence" yaml:"evidence"` + Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` } diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index e611b94301fa..9a5f2bc2e89f 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -4,10 +4,7 @@ import ( "encoding/json" "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" - - cmn "github.com/tendermint/tendermint/libs/common" - + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -20,41 +17,32 @@ type ConsensusState interface { // which is used for key-value pair verification. GetRoot() commitment.RootI + // GetCommitter returns the committer that committed the consensus state + GetCommitter() Committer + // CheckValidityAndUpdateState returns the updated consensus state // only if the header is a descendent of this consensus state. CheckValidityAndUpdateState(Header) (ConsensusState, error) } -// Evidence from ADR 009: Evidence Module -// TODO: use evidence module interface once merged -type Evidence interface { - Route() string - Type() string - String() string - Hash() cmn.HexBytes - ValidateBasic() sdk.Error - - // The consensus address of the malicious validator at time of infraction - GetConsensusAddress() sdk.ConsAddress - - // Height at which the infraction occurred - GetHeight() int64 - - // The total power of the malicious validator at time of infraction - GetValidatorPower() int64 - - // The total validator set power at time of infraction - GetTotalPower() int64 -} - // Misbehaviour defines a specific consensus kind and an evidence type Misbehaviour interface { ClientType() ClientType - Evidence() Evidence + GetEvidence() evidenceexported.Evidence } // Header is the consensus state update information type Header interface { + ClientType() ClientType + GetCommitter() Committer + GetHeight() uint64 +} + +// Committer defines the type that is responsible for +// updating the consensusState at a given height +// +// In Tendermint, this is the ValidatorSet at the given height +type Committer interface { ClientType() ClientType GetHeight() uint64 } diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index 1b1e1807b54a..595656a86c20 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -1,8 +1,13 @@ package client import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" - exported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/evidence" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" ) // HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient @@ -12,7 +17,6 @@ func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.R return sdk.ResultFromError(ErrInvalidClientType(DefaultCodespace, err.Error())) } - // TODO: should we create an event with the new client state id ? _, err = k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) if err != nil { return sdk.ResultFromError(err) @@ -55,24 +59,17 @@ func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) sdk.R return sdk.Result{Events: ctx.EventManager().Events()} } -// HandleMsgSubmitMisbehaviour defines the sdk.Handler for MsgSubmitMisbehaviour -func HandleMsgSubmitMisbehaviour(ctx sdk.Context, k Keeper, msg MsgSubmitMisbehaviour) sdk.Result { - err := k.CheckMisbehaviourAndUpdateState(ctx, msg.ClientID, msg.Evidence) - if err != nil { - return sdk.ResultFromError(err) - } +// HandlerClientMisbehaviour defines the Evidence module handler for submitting a +// light client misbehaviour. +func HandlerClientMisbehaviour(k Keeper) evidence.Handler { + return func(ctx sdk.Context, evidence evidenceexported.Evidence) error { + switch e := evidence.(type) { + case tendermint.Misbehaviour: + return k.CheckMisbehaviourAndUpdateState(ctx, evidence) - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - EventTypeSubmitMisbehaviour, - sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), - ), - sdk.NewEvent( - sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), - sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), - ), - }) - - return sdk.Result{Events: ctx.EventManager().Events()} + default: + errMsg := fmt.Sprintf("unrecognized IBC client evidence type: %T", e) + return sdk.ErrUnknownRequest(errMsg) + } + } } diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index 3ee7a53143bf..9b72ef4a2c2c 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -5,9 +5,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" ) // CreateClient creates a new client state and populates it with a given consensus @@ -27,6 +29,7 @@ func (k Keeper) CreateClient( } clientState := k.initialize(ctx, clientID, consensusState) + k.SetCommitter(ctx, clientID, consensusState.GetHeight(), consensusState.GetCommitter()) k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) k.SetClientState(ctx, clientState) k.SetClientType(ctx, clientID, clientType) @@ -66,6 +69,7 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H } k.SetConsensusState(ctx, clientID, consensusState) + k.SetCommitter(ctx, clientID, consensusState.GetHeight(), consensusState.GetCommitter()) k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, consensusState.GetHeight())) return nil @@ -73,23 +77,47 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H // CheckMisbehaviourAndUpdateState checks for client misbehaviour and freezes the // client if so. -func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, clientID string, evidence exported.Evidence) error { - clientState, found := k.GetClientState(ctx, clientID) +// +// NOTE: In the first implementation, only Tendermint misbehaviour evidence is +// supported. +func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, evidence evidenceexported.Evidence) error { + misbehaviour, ok := evidence.(tendermint.Misbehaviour) + if !ok { + return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint") + } + + clientState, found := k.GetClientState(ctx, misbehaviour.ClientID) if !found { - sdk.ResultFromError(errors.ErrClientNotFound(k.codespace, clientID)) + return errors.ErrClientNotFound(k.codespace, misbehaviour.ClientID) } - err := k.checkMisbehaviour(ctx, evidence) - if err != nil { - return err + committer, found := k.GetCommitter(ctx, misbehaviour.ClientID, uint64(misbehaviour.GetHeight())) + if !found { + return errors.ErrCommitterNotFound(k.codespace, fmt.Sprintf("committer not found for height %d", misbehaviour.GetHeight())) + } + tmCommitter, ok := committer.(tendermint.Committer) + if !ok { + return errors.ErrInvalidCommitter(k.codespace, "committer type is not Tendermint") + } + + if err := tendermint.CheckMisbehaviour(tmCommitter, misbehaviour); err != nil { + return errors.ErrInvalidEvidence(k.codespace, err.Error()) } - clientState, err = k.freeze(ctx, clientState) + clientState, err := k.freeze(ctx, clientState) if err != nil { return err } k.SetClientState(ctx, clientState) - k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", clientID)) + k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", misbehaviour.ClientID)) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeSubmitMisbehaviour, + sdk.NewAttribute(types.AttributeKeyClientID, misbehaviour.ClientID), + ), + ) + return nil } diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index cfc69e2f2245..c99757d3eacb 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "bytes" "fmt" "github.com/stretchr/testify/require" @@ -19,7 +20,7 @@ const ( func (suite *KeeperTestSuite) TestCreateClient() { // Test Valid CreateClient state, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) - require.Nil(suite.T(), err, "CreateClient failed") + suite.NoError(err, "CreateClient failed") // Test ClientState stored correctly expectedState := types.State{ @@ -36,7 +37,7 @@ func (suite *KeeperTestSuite) TestCreateClient() { // Test that trying to CreateClient on existing client fails _, err = suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) - require.NotNil(suite.T(), err, "CreateClient on existing client: %s passed", testClientID) + suite.Error(err, "CreateClient on existing client: %s passed", testClientID) } func (suite *KeeperTestSuite) TestUpdateClient() { @@ -61,10 +62,10 @@ func (suite *KeeperTestSuite) TestUpdateClient() { suite.keeper.SetClientState(suite.ctx, clientState) }, true}, {"past height", func() { - suite.header = tendermint.MakeHeader(2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = tendermint.MakeHeader("gaia", 2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) }, true}, {"validatorHash incorrect", func() { - suite.header = tendermint.MakeHeader(4, altValSet, suite.valSet, altSigners) + suite.header = tendermint.MakeHeader("gaia", 4, altValSet, suite.valSet, altSigners) }, true}, {"nextHash incorrect", func() { suite.header.NextValidatorSet = altValSet @@ -79,28 +80,30 @@ func (suite *KeeperTestSuite) TestUpdateClient() { } for _, tc := range cases { + tc := tc // pin for scopelint suite.Run(fmt.Sprintf("Case %s", tc.name), func() { // Reset suite on each subtest suite.SetupTest() _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) - require.Nil(suite.T(), err, "CreateClient failed") + suite.NoError(err, "CreateClient failed") tc.malleate() err = suite.keeper.UpdateClient(suite.ctx, testClientID, suite.header) retrievedConsState, _ := suite.keeper.GetConsensusState(suite.ctx, testClientID) tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) + tmConsState.ValidatorSet.TotalVotingPower() tmConsState.NextValidatorSet.TotalVotingPower() retrievedRoot, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()+1) if tc.expErr { - require.NotNil(suite.T(), err, "Invalid UpdateClient passed", tc.name) + suite.Error(err, "Invalid UpdateClient passed", tc.name) // require no state changes occurred require.Equal(suite.T(), suite.consensusState, tmConsState, "Consensus state changed after invalid UpdateClient") require.Nil(suite.T(), retrievedRoot, "Root added for new height after invalid UpdateClient") } else { - require.Nil(suite.T(), err, "Valid UpdateClient failed", tc.name) + suite.NoError(err, "Valid UpdateClient failed", tc.name) // require state changes were performed correctly require.Equal(suite.T(), suite.header.GetHeight(), retrievedConsState.GetHeight(), "height not updated correctly") @@ -112,3 +115,97 @@ func (suite *KeeperTestSuite) TestUpdateClient() { }) } } + +func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} + } + + altSigners := []tmtypes.PrivValidator{altPrivVal} + + _, err := suite.keeper.CreateClient(suite.ctx, "gaiamainnet", exported.Tendermint, suite.consensusState) + suite.NoError(err, "CreateClient failed") + + testCases := []struct { + name string + evidence *tendermint.Evidence + clientID string + expErr bool + }{ + { + "trusting period misbehavior should pass", + &tendermint.Evidence{ + Header1: tendermint.MakeHeader("gaia", 5, bothValSet, suite.valSet, bothSigners), + Header2: tendermint.MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + "gaiamainnet", + false, + }, + { + "first valset has too much change", + &tendermint.Evidence{ + Header1: tendermint.MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + Header2: tendermint.MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "second valset has too much change", + &tendermint.Evidence{ + Header1: tendermint.MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + Header2: tendermint.MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "both valsets have too much change", + &tendermint.Evidence{ + Header1: tendermint.MakeHeader("gaia", 5, altValSet, altValSet, altSigners), + Header2: tendermint.MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + } + + for _, tc := range testCases { + tc := tc // pin for scopelint + suite.Run(tc.name, func() { + misbehaviour := tendermint.Misbehaviour{ + Evidence: tc.evidence, + ClientID: tc.clientID, + } + + err = suite.keeper.CheckMisbehaviourAndUpdateState(suite.ctx, misbehaviour) + + if tc.expErr { + suite.Error(err, "CheckMisbehaviour passed unexpectedly") + } else { + suite.NoError(err, "CheckMisbehaviour failed unexpectedly: %v", err) + } + + // reset Frozen flag to false + clientState, _ := suite.keeper.GetClientState(suite.ctx, tc.clientID) + clientState.Frozen = false + suite.keeper.SetClientState(suite.ctx, clientState) + }) + } +} diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index 3911c1f98f0e..e5c4feb26263 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -12,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -119,6 +118,32 @@ func (k Keeper) SetVerifiedRoot(ctx sdk.Context, clientID string, height uint64, store.Set(types.KeyRoot(clientID, height), bz) } +// GetCommitter will get the Committer of a particular client at the oldest height +// that is less than or equal to the height passed in +func (k Keeper) GetCommitter(ctx sdk.Context, clientID string, height uint64) (exported.Committer, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + + var committer exported.Committer + + // TODO: Replace this for-loop with a ReverseIterator for efficiency + for i := height; i > 0; i-- { + bz := store.Get(types.KeyCommitter(clientID, i)) + if bz != nil { + k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &committer) + return committer, true + } + } + return nil, false +} + +// SetCommitter sets a committer from a particular height to +// a particular client +func (k Keeper) SetCommitter(ctx sdk.Context, clientID string, height uint64, committer exported.Committer) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + bz := k.cdc.MustMarshalBinaryLengthPrefixed(committer) + store.Set(types.KeyCommitter(clientID, height), bz) +} + // State returns a new client state with a given id as defined in // https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#example-implementation func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) types.State { @@ -127,24 +152,6 @@ func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState expo return clientState } -func (k Keeper) checkMisbehaviour(ctx sdk.Context, evidence exported.Evidence) error { - switch evidence.Type() { - case exported.ClientTypeTendermint: - var tmEvidence tendermint.Evidence - _, ok := evidence.(tendermint.Evidence) - if !ok { - return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint") - } - err := tendermint.CheckMisbehaviour(tmEvidence) - if err != nil { - return errors.ErrInvalidEvidence(k.codespace, err.Error()) - } - default: - panic(fmt.Sprintf("unregistered evidence type: %s", evidence.Type())) - } - return nil -} - // freeze updates the state of the client in the event of a misbehaviour func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) { if clientState.Frozen { @@ -164,12 +171,14 @@ func (k Keeper) VerifyMembership( path commitment.PathI, value []byte, ) bool { - // XXX: commented out for demo - /* - if clientState.Frozen { - return false - } - */ + clientState, found := k.GetClientState(ctx, clientID) + if !found { + return false + } + + if clientState.Frozen { + return false + } root, found := k.GetVerifiedRoot(ctx, clientID, height) if !found { @@ -187,12 +196,15 @@ func (k Keeper) VerifyNonMembership( proof commitment.ProofI, path commitment.PathI, ) bool { - // XXX: commented out for demo - /* - if clientState.Frozen { - return false - } - */ + clientState, found := k.GetClientState(ctx, clientID) + if !found { + return false + } + + if clientState.Frozen { + return false + } + root, found := k.GetVerifiedRoot(ctx, clientID, height) if !found { return false diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index da81be0edb12..da79777dae50 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -4,6 +4,7 @@ import ( "testing" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/tmhash" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" @@ -48,12 +49,13 @@ func (suite *KeeperTestSuite) SetupTest() { validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - suite.header = tendermint.MakeHeader(4, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = tendermint.MakeHeader("gaia", 4, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.consensusState = tendermint.ConsensusState{ ChainID: testClientID, Height: 3, Root: commitment.NewRoot([]byte("hash")), + ValidatorSet: suite.valSet, NextValidatorSet: suite.valSet, } } @@ -87,6 +89,7 @@ func (suite *KeeperTestSuite) TestSetConsensusState() { require.True(suite.T(), ok, "GetConsensusState failed") tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) // force recalculation of unexported totalVotingPower so we can compare consensusState + tmConsState.ValidatorSet.TotalVotingPower() tmConsState.NextValidatorSet.TotalVotingPower() require.Equal(suite.T(), suite.consensusState, tmConsState, "ConsensusState not stored correctly") } @@ -100,3 +103,49 @@ func (suite *KeeperTestSuite) TestSetVerifiedRoot() { require.True(suite.T(), ok, "GetVerifiedRoot failed") require.Equal(suite.T(), root, retrievedRoot, "Root stored incorrectly") } + +func (suite KeeperTestSuite) TestSetCommitter() { + committer := tendermint.Committer{ + ValidatorSet: suite.valSet, + Height: 3, + NextValSetHash: suite.valSet.Hash(), + } + nextCommitter := tendermint.Committer{ + ValidatorSet: suite.valSet, + Height: 6, + NextValSetHash: tmhash.Sum([]byte("next_hash")), + } + + suite.keeper.SetCommitter(suite.ctx, "gaia", 3, committer) + suite.keeper.SetCommitter(suite.ctx, "gaia", 6, nextCommitter) + + // fetch the commiter on each respective height + for i := 0; i < 3; i++ { + committer, ok := suite.keeper.GetCommitter(suite.ctx, "gaia", uint64(i)) + require.False(suite.T(), ok, "GetCommitter passed on nonexistent height: %d", i) + require.Nil(suite.T(), committer, "GetCommitter returned committer on nonexistent height: %d", i) + } + + for i := 3; i < 6; i++ { + recv, ok := suite.keeper.GetCommitter(suite.ctx, "gaia", uint64(i)) + tmRecv, _ := recv.(tendermint.Committer) + if tmRecv.ValidatorSet != nil { + // update validator set's power + tmRecv.ValidatorSet.TotalVotingPower() + } + require.True(suite.T(), ok, "GetCommitter failed on existing height: %d", i) + require.Equal(suite.T(), committer, recv, "GetCommitter returned committer on nonexistent height: %d", i) + } + + for i := 6; i < 9; i++ { + recv, ok := suite.keeper.GetCommitter(suite.ctx, "gaia", uint64(i)) + tmRecv, _ := recv.(tendermint.Committer) + if tmRecv.ValidatorSet != nil { + // update validator set's power + tmRecv.ValidatorSet.TotalVotingPower() + } + require.True(suite.T(), ok, "GetCommitter failed on existing height: %d", i) + require.Equal(suite.T(), nextCommitter, recv, "GetCommitter returned committer on nonexistent height: %d", i) + } + +} diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index d595f583baa9..ed923f5cbc89 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -12,7 +12,7 @@ var SubModuleCdc *codec.Codec // RegisterCodec registers the IBC client interfaces and types func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*exported.ConsensusState)(nil), nil) - cdc.RegisterInterface((*exported.Evidence)(nil), nil) + cdc.RegisterInterface((*exported.Committer)(nil), nil) cdc.RegisterInterface((*exported.Header)(nil), nil) cdc.RegisterInterface((*exported.Misbehaviour)(nil), nil) @@ -20,6 +20,7 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) cdc.RegisterConcrete(tendermint.ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) + cdc.RegisterConcrete(tendermint.Committer{}, "ibc/client/tendermint/Committer", nil) cdc.RegisterConcrete(tendermint.Header{}, "ibc/client/tendermint/Header", nil) cdc.RegisterConcrete(tendermint.Evidence{}, "ibc/client/tendermint/Evidence", nil) diff --git a/x/ibc/02-client/types/errors/errors.go b/x/ibc/02-client/types/errors/errors.go index 1e9510df6c44..1a7272ca1fcb 100644 --- a/x/ibc/02-client/types/errors/errors.go +++ b/x/ibc/02-client/types/errors/errors.go @@ -19,8 +19,10 @@ const ( CodeClientTypeNotFound sdk.CodeType = 205 CodeInvalidClientType sdk.CodeType = 206 CodeRootNotFound sdk.CodeType = 207 - CodeInvalidHeader sdk.CodeType = 207 + CodeInvalidHeader sdk.CodeType = 208 CodeInvalidEvidence sdk.CodeType = 209 + CodeCommitterNotFound sdk.CodeType = 210 + CodeInvalidCommitter sdk.CodeType = 211 ) // ErrClientExists implements sdk.Error @@ -112,3 +114,21 @@ func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) error { fmt.Sprintf("invalid evidence: %s", msg), ) } + +// ErrCommitterNotFound implements sdk.Error +func ErrCommitterNotFound(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeCommitterNotFound), + fmt.Sprintf("invalid evidence: %s", msg), + ) +} + +// ErrInvalidEvidence implements sdk.Error +func ErrInvalidCommitter(codespace sdk.CodespaceType, msg string) error { + return sdkerrors.New( + string(codespace), + uint32(CodeInvalidCommitter), + fmt.Sprintf("invalid evidence: %s", msg), + ) +} diff --git a/x/ibc/02-client/types/events.go b/x/ibc/02-client/types/events.go index 7e7f9a508cee..6b02bfa5eaf8 100644 --- a/x/ibc/02-client/types/events.go +++ b/x/ibc/02-client/types/events.go @@ -13,9 +13,9 @@ const ( // IBC client events vars var ( - EventTypeCreateClient = MsgCreateClient{}.Type() - EventTypeUpdateClient = MsgUpdateClient{}.Type() - EventTypeSubmitMisbehaviour = MsgSubmitMisbehaviour{}.Type() + EventTypeCreateClient = TypeMsgCreateClient + EventTypeUpdateClient = TypeMsgUpdateClient + EventTypeSubmitMisbehaviour = TypeClientMisbehaviour AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) ) diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go index acebca3ee09a..6dc55a77baf0 100644 --- a/x/ibc/02-client/types/keys.go +++ b/x/ibc/02-client/types/keys.go @@ -6,16 +6,16 @@ import ( const ( // SubModuleName defines the IBC client name - SubModuleName = "client" + SubModuleName string = "client" // StoreKey is the store key string for IBC client - StoreKey = SubModuleName + StoreKey string = SubModuleName // RouterKey is the message route for IBC client - RouterKey = SubModuleName + RouterKey string = SubModuleName // QuerierRoute is the querier route for IBC client - QuerierRoute = SubModuleName + QuerierRoute string = SubModuleName ) // KVStore key prefixes @@ -44,11 +44,17 @@ func ConsensusStatePath(clientID string) string { } // RootPath takes an Identifier and returns a Path under which to -// store the consensus state of a client. +// store the root for a particular height of a client. func RootPath(clientID string, height uint64) string { return fmt.Sprintf("clients/%s/roots/%d", clientID, height) } +// CommitterPath takes an Identifier and returns a Path under which +// to store the committer of a client at a particular height +func CommitterPath(clientID string, height uint64) string { + return fmt.Sprintf("clients/%s/committer/%d", clientID, height) +} + // KeyClientState returns the store key for a particular client state func KeyClientState(clientID string) []byte { return []byte(ClientStatePath(clientID)) @@ -70,3 +76,9 @@ func KeyConsensusState(clientID string) []byte { func KeyRoot(clientID string, height uint64) []byte { return []byte(RootPath(clientID, height)) } + +// KeyValidatorSet returns the store key for a validator of a particular +// client at a given height. Key => clientID||height +func KeyCommitter(clientID string, height uint64) []byte { + return []byte(CommitterPath(clientID, height)) +} diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index f09e126666ff..6f0aa7959ac7 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -2,12 +2,20 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) +// Message types for the IBC client +const ( + TypeMsgCreateClient string = "create_client" + TypeMsgUpdateClient string = "update_client" + TypeClientMisbehaviour string = "client_misbehaviour" +) + var _ sdk.Msg = MsgCreateClient{} // MsgCreateClient defines a message to create an IBC client @@ -35,7 +43,7 @@ func (msg MsgCreateClient) Route() string { // Type implements sdk.Msg func (msg MsgCreateClient) Type() string { - return "create_client" + return TypeMsgCreateClient } // ValidateBasic implements sdk.Msg @@ -90,7 +98,7 @@ func (msg MsgUpdateClient) Route() string { // Type implements sdk.Msg func (msg MsgUpdateClient) Type() string { - return "update_client" + return TypeMsgUpdateClient } // ValidateBasic implements sdk.Msg @@ -120,12 +128,12 @@ func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress { // MsgSubmitMisbehaviour defines a message to update an IBC client type MsgSubmitMisbehaviour struct { ClientID string `json:"id" yaml:"id"` - Evidence exported.Evidence `json:"evidence" yaml:"evidence"` + Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` Signer sdk.AccAddress `json:"address" yaml:"address"` } // NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance -func NewMsgSubmitMisbehaviour(id string, evidence exported.Evidence, signer sdk.AccAddress) MsgSubmitMisbehaviour { +func NewMsgSubmitMisbehaviour(id string, evidence evidenceexported.Evidence, signer sdk.AccAddress) MsgSubmitMisbehaviour { return MsgSubmitMisbehaviour{ ClientID: id, Evidence: evidence, diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go index f7e022ecc89c..b29633420ed4 100644 --- a/x/ibc/02-client/types/msgs_test.go +++ b/x/ibc/02-client/types/msgs_test.go @@ -9,11 +9,38 @@ import ( cmn "github.com/tendermint/tendermint/libs/common" sdk "github.com/cosmos/cosmos-sdk/types" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" ) +var _ evidenceexported.Evidence = mockEvidence{} +var _ evidenceexported.Evidence = mockBadEvidence{} + +const mockStr = "mock" + +// mock GoodEvidence +type mockEvidence struct{} + +// Implement Evidence interface +func (me mockEvidence) Route() string { return mockStr } +func (me mockEvidence) Type() string { return mockStr } +func (me mockEvidence) String() string { return mockStr } +func (me mockEvidence) Hash() cmn.HexBytes { return cmn.HexBytes([]byte(mockStr)) } +func (me mockEvidence) ValidateBasic() error { return nil } +func (me mockEvidence) GetHeight() int64 { return 3 } + +// mock bad evidence +type mockBadEvidence struct { + mockEvidence +} + +// Override ValidateBasic +func (mbe mockBadEvidence) ValidateBasic() error { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence") +} + func TestMsgCreateClientValidateBasic(t *testing.T) { cs := tendermint.ConsensusState{} privKey := secp256k1.GenPrivKey() @@ -79,34 +106,6 @@ func TestMsgUpdateClient(t *testing.T) { } } -var _ exported.Evidence = mockEvidence{} - -const mockStr = "mock" - -// mock GoodEvidence -type mockEvidence struct{} - -// Implement Evidence interface -func (me mockEvidence) Route() string { return mockStr } -func (me mockEvidence) Type() string { return mockStr } -func (me mockEvidence) String() string { return mockStr } -func (me mockEvidence) Hash() cmn.HexBytes { return cmn.HexBytes([]byte(mockStr)) } -func (me mockEvidence) ValidateBasic() sdk.Error { return nil } -func (me mockEvidence) GetConsensusAddress() sdk.ConsAddress { return sdk.ConsAddress{} } -func (me mockEvidence) GetHeight() int64 { return 3 } -func (me mockEvidence) GetValidatorPower() int64 { return 3 } -func (me mockEvidence) GetTotalPower() int64 { return 5 } - -// mock bad evidence -type mockBadEvidence struct { - mockEvidence -} - -// Override ValidateBasic -func (mbe mockBadEvidence) ValidateBasic() sdk.Error { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence")) -} - func TestMsgSubmitMisbehaviour(t *testing.T) { privKey := secp256k1.GenPrivKey() signer := sdk.AccAddress(privKey.PubKey().Address()) diff --git a/x/ibc/02-client/types/tendermint/codec.go b/x/ibc/02-client/types/tendermint/codec.go index 46814fec2479..a546ed313cef 100644 --- a/x/ibc/02-client/types/tendermint/codec.go +++ b/x/ibc/02-client/types/tendermint/codec.go @@ -8,8 +8,11 @@ var SubModuleCdc = codec.New() // RegisterCodec registers the Tendermint types func RegisterCodec(cdc *codec.Codec) { + codec.RegisterCrypto(cdc) + cdc.RegisterConcrete(Committer{}, "ibc/client/tendermint/Committer", nil) cdc.RegisterConcrete(ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) cdc.RegisterConcrete(Header{}, "ibc/client/tendermint/Header", nil) + cdc.RegisterConcrete(Misbehaviour{}, "ibc/client/tendermint/Misbehaviour", nil) cdc.RegisterConcrete(Evidence{}, "ibc/client/tendermint/Evidence", nil) } diff --git a/x/ibc/02-client/types/tendermint/committer.go b/x/ibc/02-client/types/tendermint/committer.go new file mode 100644 index 000000000000..ccf798feb570 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/committer.go @@ -0,0 +1,26 @@ +package tendermint + +import ( + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" +) + +var _ exported.Committer = Committer{} + +// Committer definites a Tendermint Committer +type Committer struct { + *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` + Height uint64 `json:"height" yaml:"height"` + NextValSetHash []byte `json:"next_valset_hash" yaml:"next_valset_hash"` +} + +// Implement exported.Committer interface +func (c Committer) ClientType() exported.ClientType { + return exported.Tendermint +} + +// Implement exported.Committer interface +func (c Committer) GetHeight() uint64 { + return c.Height +} diff --git a/x/ibc/02-client/types/tendermint/consensus_state.go b/x/ibc/02-client/types/tendermint/consensus_state.go index f57887045a2f..25c2f8d990f8 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state.go +++ b/x/ibc/02-client/types/tendermint/consensus_state.go @@ -20,6 +20,7 @@ type ConsensusState struct { ChainID string `json:"chain_id" yaml:"chain_id"` Height uint64 `json:"height" yaml:"height"` // NOTE: defined as 'sequence' in the spec Root commitment.RootI `json:"root" yaml:"root"` + ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` // contains the PublicKey } @@ -38,6 +39,15 @@ func (cs ConsensusState) GetRoot() commitment.RootI { return cs.Root } +// GetCommitter returns the commmitter that committed the ConsensusState +func (cs ConsensusState) GetCommitter() exported.Committer { + return Committer{ + ValidatorSet: cs.ValidatorSet, + Height: cs.Height, + NextValSetHash: cs.NextValidatorSet.Hash(), + } +} + // CheckValidityAndUpdateState checks if the provided header is valid and updates // the consensus state if appropriate func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (exported.ConsensusState, error) { @@ -64,6 +74,11 @@ func (cs ConsensusState) checkValidity(header Header) error { ) } + // basic consistency check + if err := header.ValidateBasic(cs.ChainID); err != nil { + return err + } + // check if the hash from the consensus set and header // matches nextHash := cs.NextValidatorSet.Hash() @@ -78,11 +93,6 @@ func (cs ConsensusState) checkValidity(header Header) error { return lerr.ErrUnexpectedValidators(header.NextValidatorsHash, nextHash) } - // basic consistency check - if err := header.ValidateBasic(cs.ChainID); err != nil { - return err - } - // abortTransactionUnless(consensusState.publicKey.verify(header.signature)) return header.ValidatorSet.VerifyFutureCommit( cs.NextValidatorSet, cs.ChainID, header.Commit.BlockID, header.Height, header.Commit, @@ -93,6 +103,7 @@ func (cs ConsensusState) checkValidity(header Header) error { func (cs ConsensusState) update(header Header) ConsensusState { cs.Height = header.GetHeight() cs.Root = commitment.NewRoot(header.AppHash) + cs.ValidatorSet = header.ValidatorSet cs.NextValidatorSet = header.NextValidatorSet return cs } diff --git a/x/ibc/02-client/types/tendermint/consensus_state_test.go b/x/ibc/02-client/types/tendermint/consensus_state_test.go index 07c1015a3067..778de45fa3a8 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state_test.go +++ b/x/ibc/02-client/types/tendermint/consensus_state_test.go @@ -9,12 +9,12 @@ import ( func (suite *TendermintTestSuite) TestCheckValidity() { // valid header err := suite.cs.checkValidity(suite.header) - require.Nil(suite.T(), err, "validity failed") + suite.NoError(err, "validity failed") // switch out header ValidatorsHash suite.header.ValidatorsHash = tmhash.Sum([]byte("hello")) err = suite.cs.checkValidity(suite.header) - require.NotNil(suite.T(), err, "validator hash is wrong") + suite.Error(err, "validator hash is wrong") // reset suite and make header.NextValidatorSet different // from NextValidatorSetHash @@ -23,13 +23,13 @@ func (suite *TendermintTestSuite) TestCheckValidity() { val := tmtypes.NewValidator(privVal.GetPubKey(), 5) suite.header.NextValidatorSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) err = suite.cs.checkValidity(suite.header) - require.NotNil(suite.T(), err, "header's next validator set is not consistent with hash") + suite.Error(err, "header's next validator set is not consistent with hash") // reset and make header fail validatebasic suite.SetupTest() suite.header.ChainID = "not_gaia" err = suite.cs.checkValidity(suite.header) - require.NotNil(suite.T(), err, "invalid header should fail ValidateBasic") + suite.Error(err, "invalid header should fail ValidateBasic") } func (suite *TendermintTestSuite) TestCheckUpdate() { @@ -40,13 +40,14 @@ func (suite *TendermintTestSuite) TestCheckUpdate() { require.Equal(suite.T(), suite.header.GetHeight(), cs.GetHeight(), "height not updated") require.Equal(suite.T(), suite.header.AppHash.Bytes(), cs.GetRoot().GetHash(), "root not updated") tmCS, _ := cs.(ConsensusState) - require.Equal(suite.T(), suite.header.NextValidatorSet, tmCS.NextValidatorSet, "validator set did not update") + require.Equal(suite.T(), suite.header.ValidatorSet, tmCS.ValidatorSet, "validator set did not update") + require.Equal(suite.T(), suite.header.NextValidatorSet, tmCS.NextValidatorSet, "next validator set did not update") // make header invalid so update should be unsuccessful suite.SetupTest() suite.header.ChainID = "not_gaia" cs, err = suite.cs.CheckValidityAndUpdateState(suite.header) - require.NotNil(suite.T(), err) + suite.Error(err) require.Nil(suite.T(), cs) } diff --git a/x/ibc/02-client/types/tendermint/doc.go b/x/ibc/02-client/types/tendermint/doc.go index f0e27c7696a7..26aa430a82da 100644 --- a/x/ibc/02-client/types/tendermint/doc.go +++ b/x/ibc/02-client/types/tendermint/doc.go @@ -1,5 +1,5 @@ /* -Package tendermint implements a concrete `ConsensusState`, `Header` and `Equivocation` -for the Tendermint consensus algorithm. +Package tendermint implements a concrete `ConsensusState`, `Header`, +`Misbehaviour` and `Equivocation` types for the Tendermint consensus light client. */ package tendermint diff --git a/x/ibc/02-client/types/tendermint/evidence.go b/x/ibc/02-client/types/tendermint/evidence.go new file mode 100644 index 000000000000..a8d1154a27ae --- /dev/null +++ b/x/ibc/02-client/types/tendermint/evidence.go @@ -0,0 +1,106 @@ +package tendermint + +import ( + "fmt" + + yaml "gopkg.in/yaml.v2" + + "github.com/tendermint/tendermint/crypto/tmhash" + cmn "github.com/tendermint/tendermint/libs/common" + tmtypes "github.com/tendermint/tendermint/types" + + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" +) + +var _ evidenceexported.Evidence = Evidence{} + +// Evidence is a wrapper over tendermint's DuplicateVoteEvidence +// that implements Evidence interface expected by ICS-02 +type Evidence struct { + Header1 Header `json:"header1" yaml:"header1"` + Header2 Header `json:"header2" yaml:"header2"` + ChainID string `json:"chain_id" yaml:"chain_id"` +} + +// Route implements Evidence interface +func (ev Evidence) Route() string { + return "client" +} + +// Type implements Evidence interface +func (ev Evidence) Type() string { + return "client_misbehaviour" +} + +// String implements Evidence interface +func (ev Evidence) String() string { + bz, err := yaml.Marshal(ev) + if err != nil { + panic(err) + } + return string(bz) +} + +// Hash implements Evidence interface +func (ev Evidence) Hash() cmn.HexBytes { + return tmhash.Sum(SubModuleCdc.MustMarshalBinaryBare(ev)) +} + +// GetHeight returns the height at which misbehaviour occurred +func (ev Evidence) GetHeight() int64 { + return ev.Header1.Height +} + +// ValidateBasic implements Evidence interface +func (ev Evidence) ValidateBasic() error { + // ValidateBasic on both validators + if err := ev.Header1.ValidateBasic(ev.ChainID); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Header1 failed ValidateBasic: %v", err)) + } + if err := ev.Header2.ValidateBasic(ev.ChainID); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Header2 failed ValidateBasic: %v", err)) + } + // Ensure that Heights are the same + if ev.Header1.Height != ev.Header2.Height { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "headers in evidence are on different heights") + } + // Ensure that Commit Hashes are different + if ev.Header1.Commit.BlockID.Equals(ev.Header2.Commit.BlockID) { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "Headers commit to same blockID") + } + + if err1 := ValidCommit(ev.ChainID, ev.Header1.Commit, ev.Header1.ValidatorSet); err1 != nil { + return err1 + } + if err2 := ValidCommit(ev.ChainID, ev.Header2.Commit, ev.Header2.ValidatorSet); err2 != nil { + return err2 + } + + return nil +} + +// ValidCommit checks if the given commit is a valid commit from the passed-in validatorset +// +// CommitToVoteSet will panic if the commit cannot be converted to a valid voteset given the validatorset +// This implies that someone tried to submit evidence that wasn't actually committed by the validatorset +// thus we should return an error here and reject the evidence rather than panicing. +func ValidCommit(chainID string, commit *tmtypes.Commit, valSet *tmtypes.ValidatorSet) (err error) { + defer func() { + if r := recover(); r != nil { + err = errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("invalid commit: %v", r)) + } + }() + + // Convert commits to vote-sets given the validator set so we can check if they both have 2/3 power + voteSet := tmtypes.CommitToVoteSet(chainID, commit, valSet) + + blockID, ok := voteSet.TwoThirdsMajority() + + // Check that ValidatorSet did indeed commit to blockID in Commit + if !ok || !blockID.Equals(commit.BlockID) { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "ValidatorSet did not commit to Header1") + } + + return nil +} diff --git a/x/ibc/02-client/types/tendermint/evidence_test.go b/x/ibc/02-client/types/tendermint/evidence_test.go new file mode 100644 index 000000000000..09f40499b458 --- /dev/null +++ b/x/ibc/02-client/types/tendermint/evidence_test.go @@ -0,0 +1,135 @@ +package tendermint + +import ( + "bytes" + + "github.com/tendermint/tendermint/crypto/tmhash" + tmtypes "github.com/tendermint/tendermint/types" +) + +func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + + signers := []tmtypes.PrivValidator{suite.privVal} + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} + } + + altSigners := []tmtypes.PrivValidator{altPrivVal} + + testCases := []struct { + name string + evidence Evidence + malleateEvidence func(ev *Evidence) + expErr bool + }{ + { + "valid evidence", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 4, suite.valSet, bothValSet, signers), + ChainID: "gaia", + }, + func(ev *Evidence) {}, + false, + }, + { + "wrong chainID on header1", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("ethermint", 4, suite.valSet, bothValSet, signers), + ChainID: "ethermint", + }, + func(ev *Evidence) {}, + true, + }, + { + "wrong chainID on header2", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("ethermint", 4, suite.valSet, bothValSet, signers), + ChainID: "gaia", + }, + func(ev *Evidence) {}, + true, + }, + { + "mismatched heights", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 6, suite.valSet, bothValSet, signers), + ChainID: "gaia", + }, + func(ev *Evidence) {}, + true, + }, + { + "same block id", + Evidence{ + Header1: suite.header, + Header2: suite.header, + ChainID: "gaia", + }, + func(ev *Evidence) {}, + true, + }, + { + "header doesn't have 2/3 majority", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 4, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + func(ev *Evidence) { + // voteSet contains only altVal which is less than 2/3 of total power (4/14) + wrongVoteSet := tmtypes.NewVoteSet("gaia", ev.Header2.Height, 1, tmtypes.PrecommitType, altValSet) + var err error + ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round(), wrongVoteSet, altSigners) + if err != nil { + panic(err) + } + }, + true, + }, + { + "validators sign off on wrong commit", + Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 4, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + func(ev *Evidence) { + ev.Header2.Commit.BlockID = makeBlockID(tmhash.Sum([]byte("other_hash")), 3, tmhash.Sum([]byte("other_partset"))) + }, + true, + }, + } + + for _, tc := range testCases { + tc := tc // pin for scopelint + suite.Run(tc.name, func() { + // reset suite for each subtest + suite.SetupTest() + + tc.malleateEvidence(&tc.evidence) + + err := tc.evidence.ValidateBasic() + + if tc.expErr { + suite.Error(err, "ValidateBasic did not throw error for invalid evidence") + } else { + suite.NoError(err, "ValidateBasic returned error on valid evidence: %s", err) + } + }) + } +} diff --git a/x/ibc/02-client/types/tendermint/header.go b/x/ibc/02-client/types/tendermint/header.go index c2d9cfebc9c5..133c1741e56e 100644 --- a/x/ibc/02-client/types/tendermint/header.go +++ b/x/ibc/02-client/types/tendermint/header.go @@ -3,7 +3,9 @@ package tendermint import ( tmtypes "github.com/tendermint/tendermint/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienterrors "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" ) var _ exported.Header = Header{} @@ -20,9 +22,33 @@ func (h Header) ClientType() exported.ClientType { return exported.Tendermint } +// GetCommitter returns the ValidatorSet that committed header +func (h Header) GetCommitter() exported.Committer { + return Committer{ + ValidatorSet: h.ValidatorSet, + Height: uint64(h.Height), + NextValSetHash: h.NextValidatorsHash, + } +} + // GetHeight returns the current height // // NOTE: also referred as `sequence` func (h Header) GetHeight() uint64 { return uint64(h.Height) } + +// ValidateBasic calls the SignedHeader ValidateBasic function +// and checks that validatorsets are not nil +func (h Header) ValidateBasic(chainID string) error { + if err := h.SignedHeader.ValidateBasic(chainID); err != nil { + return err + } + if h.ValidatorSet == nil { + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), "ValidatorSet is nil") + } + if h.NextValidatorSet == nil { + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), "NextValidatorSet is nil") + } + return nil +} diff --git a/x/ibc/02-client/types/tendermint/misbehaviour.go b/x/ibc/02-client/types/tendermint/misbehaviour.go index 1edde8ec1c04..5b04b6e3ec0c 100644 --- a/x/ibc/02-client/types/tendermint/misbehaviour.go +++ b/x/ibc/02-client/types/tendermint/misbehaviour.go @@ -3,94 +3,65 @@ package tendermint import ( "fmt" - yaml "gopkg.in/yaml.v2" - - sdk "github.com/cosmos/cosmos-sdk/types" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" - - "github.com/tendermint/tendermint/crypto/tmhash" - cmn "github.com/tendermint/tendermint/libs/common" - tmtypes "github.com/tendermint/tendermint/types" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) -var _ exported.Evidence = Evidence{} +var _ exported.Misbehaviour = Misbehaviour{} +var _ evidenceexported.Evidence = Misbehaviour{} -// Evidence is a wrapper over tendermint's DuplicateVoteEvidence -// that implements Evidence interface expected by ICS-02 -type Evidence struct { - *tmtypes.DuplicateVoteEvidence - ChainID string `json:"chain_id" yaml:"chain_id"` - ValidatorPower int64 `json:"val_power" yaml:"val_power"` - TotalPower int64 `json:"total_power" yaml:"total_power"` +// Misbehaviour contains evidence that a light client submitted a different header from +// a full node at the same height. +type Misbehaviour struct { + *Evidence + ClientID string `json:"client_id" yaml:"client_id"` } -// Type implements exported.Evidence interface -func (ev Evidence) Route() string { - return exported.ClientTypeTendermint +// ClientType is Tendermint light client +func (m Misbehaviour) ClientType() exported.ClientType { + return exported.Tendermint } -// Type implements exported.Evidence interface -func (ev Evidence) Type() string { - return exported.ClientTypeTendermint +// GetEvidence returns the evidence to handle a light client misbehaviour +func (m Misbehaviour) GetEvidence() evidenceexported.Evidence { + return m.Evidence } -// String implements exported.Evidence interface -func (ev Evidence) String() string { - bz, err := yaml.Marshal(ev) - if err != nil { - panic(err) +// ValidateBasic performs the basic validity checks for the evidence and the +// client ID. +func (m Misbehaviour) ValidateBasic() error { + if m.Evidence == nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, "empty evidence") } - return string(bz) -} - -// Hash implements exported.Evidence interface -func (ev Evidence) Hash() cmn.HexBytes { - return tmhash.Sum(SubModuleCdc.MustMarshalBinaryBare(ev)) -} -// ValidateBasic implements exported.Evidence interface -func (ev Evidence) ValidateBasic() sdk.Error { - if ev.DuplicateVoteEvidence == nil { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "duplicate evidence is nil")) - } - err := ev.DuplicateVoteEvidence.ValidateBasic() - if err != nil { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error())) - } - if ev.ChainID == "" { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "chainID is empty")) - } - if ev.ValidatorPower <= 0 { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Validator Power: %d", ev.ValidatorPower))) - } - if ev.TotalPower < ev.ValidatorPower { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Total Power: %d", ev.TotalPower))) + if err := m.Evidence.ValidateBasic(); err != nil { + return err } - return nil -} -// GetConsensusAddress implements exported.Evidence interface -func (ev Evidence) GetConsensusAddress() sdk.ConsAddress { - return sdk.ConsAddress(ev.DuplicateVoteEvidence.Address()) + return host.DefaultClientIdentifierValidator(m.ClientID) } -// GetHeight implements exported.Evidence interface -func (ev Evidence) GetHeight() int64 { - return ev.DuplicateVoteEvidence.Height() -} +// CheckMisbehaviour checks if the evidence provided is a valid light client misbehaviour +func CheckMisbehaviour(trustedCommitter Committer, m Misbehaviour) error { + if err := m.ValidateBasic(); err != nil { + return err + } -// GetValidatorPower implements exported.Evidence interface -func (ev Evidence) GetValidatorPower() int64 { - return ev.ValidatorPower -} + trustedValSet := trustedCommitter.ValidatorSet -// GetTotalPower implements exported.Evidence interface -func (ev Evidence) GetTotalPower() int64 { - return ev.TotalPower -} + // Evidence is within trusting period. ValidatorSet must have 2/3 similarity with trustedCommitter ValidatorSet + // check that the validator sets on both headers are valid given the last trusted validatorset + // less than or equal to evidence height + if err := trustedValSet.VerifyFutureCommit(m.Evidence.Header1.ValidatorSet, m.Evidence.ChainID, + m.Evidence.Header1.Commit.BlockID, m.Evidence.Header1.Height, m.Evidence.Header1.Commit); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("validator set in Header1 has too much change from last known committer: %v", err)) + } + if err := trustedValSet.VerifyFutureCommit(m.Evidence.Header2.ValidatorSet, m.Evidence.ChainID, + m.Evidence.Header2.Commit.BlockID, m.Evidence.Header2.Height, m.Evidence.Header2.Commit); err != nil { + return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("validator set in Header2 has too much change from last known committer: %v", err)) + } -// CheckMisbehaviour checks if the evidence provided is a misbehaviour -func CheckMisbehaviour(evidence Evidence) error { - return evidence.DuplicateVoteEvidence.Verify(evidence.ChainID, evidence.DuplicateVoteEvidence.PubKey) + return nil } diff --git a/x/ibc/02-client/types/tendermint/misbehaviour_test.go b/x/ibc/02-client/types/tendermint/misbehaviour_test.go index f5e75e12f785..f69a6d12884e 100644 --- a/x/ibc/02-client/types/tendermint/misbehaviour_test.go +++ b/x/ibc/02-client/types/tendermint/misbehaviour_test.go @@ -1,64 +1,170 @@ package tendermint import ( - "testing" + "bytes" - "github.com/stretchr/testify/require" - - yaml "gopkg.in/yaml.v2" + tmtypes "github.com/tendermint/tendermint/types" ) -func TestString(t *testing.T) { - dupEv := randomDuplicatedVoteEvidence() - ev := Evidence{ - DuplicateVoteEvidence: dupEv, - ChainID: "mychain", - ValidatorPower: 10, - TotalPower: 50, +func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + + signers := []tmtypes.PrivValidator{suite.privVal} + testCases := []struct { + name string + evidence *Evidence + clientID string + expErr bool + }{ + { + "valid misbehavior", + &Evidence{ + Header1: suite.header, + Header2: MakeHeader("gaia", 4, suite.valSet, bothValSet, signers), + ChainID: "gaia", + }, + "gaiamainnet", + false, + }, + { + "nil evidence", + nil, + "gaiamainnet", + true, + }, + { + "invalid evidence", + &Evidence{ + Header1: suite.header, + Header2: suite.header, + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "invalid ClientID", + &Evidence{ + Header1: MakeHeader("gaia123??", 5, suite.valSet, suite.valSet, signers), + Header2: MakeHeader("gaia123?", 5, suite.valSet, suite.valSet, signers), + ChainID: "gaia123?", + }, + "gaia123?", + true, + }, } - byteStr, err := yaml.Marshal(ev) - require.Nil(t, err) - require.Equal(t, string(byteStr), ev.String(), "Evidence String method does not work as expected") + for _, tc := range testCases { + tc := tc // pin for scopelint + suite.Run(tc.name, func() { + misbehaviour := Misbehaviour{ + Evidence: tc.evidence, + ClientID: tc.clientID, + } + + err := misbehaviour.ValidateBasic() + if tc.expErr { + suite.Error(err, "Invalid Misbehaviour passed ValidateBasic") + } else { + suite.NoError(err, "Valid Misbehaviour failed ValidateBasic: %v", err) + } + }) + } } -func TestValidateBasic(t *testing.T) { - dupEv := randomDuplicatedVoteEvidence() +func (suite *TendermintTestSuite) TestCheckMisbehaviour() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) - // good evidence - ev := Evidence{ - DuplicateVoteEvidence: dupEv, - ChainID: "mychain", - ValidatorPower: 10, - TotalPower: 50, + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} } - err := ev.ValidateBasic() - require.Nil(t, err, "good evidence failed on ValidateBasic: %v", err) - - // invalid duplicate evidence - ev.DuplicateVoteEvidence.VoteA = nil - err = ev.ValidateBasic() - require.NotNil(t, err, "invalid duplicate evidence passed on ValidateBasic") - - // reset duplicate evidence to be valid, and set empty chainID - dupEv = randomDuplicatedVoteEvidence() - ev.DuplicateVoteEvidence = dupEv - ev.ChainID = "" - err = ev.ValidateBasic() - require.NotNil(t, err, "invalid chain-id passed on ValidateBasic") - - // reset chainID and set 0 validator power - ev.ChainID = "mychain" - ev.ValidatorPower = 0 - err = ev.ValidateBasic() - require.NotNil(t, err, "invalid validator power passed on ValidateBasic") - - // reset validator power and set invalid total power - ev.ValidatorPower = 10 - ev.TotalPower = 9 - err = ev.ValidateBasic() - require.NotNil(t, err, "invalid total power passed on ValidateBasic") + altSigners := []tmtypes.PrivValidator{altPrivVal} + committer := Committer{ + ValidatorSet: suite.valSet, + Height: 3, + NextValSetHash: suite.valSet.Hash(), + } + + testCases := []struct { + name string + evidence *Evidence + clientID string + expErr bool + }{ + { + "trusting period misbehavior should pass", + &Evidence{ + Header1: MakeHeader("gaia", 5, bothValSet, suite.valSet, bothSigners), + Header2: MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + "gaiamainnet", + false, + }, + { + "first valset has too much change", + &Evidence{ + Header1: MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + Header2: MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "second valset has too much change", + &Evidence{ + Header1: MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), + Header2: MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + { + "both valsets have too much change", + &Evidence{ + Header1: MakeHeader("gaia", 5, altValSet, altValSet, altSigners), + Header2: MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), + ChainID: "gaia", + }, + "gaiamainnet", + true, + }, + } + + for _, tc := range testCases { + tc := tc // pin for scopelint + suite.Run(tc.name, func() { + misbehaviour := Misbehaviour{ + Evidence: tc.evidence, + ClientID: tc.clientID, + } + + err := CheckMisbehaviour(committer, misbehaviour) + + if tc.expErr { + suite.Error(err, "CheckMisbehaviour passed unexpectedly") + } else { + suite.NoError(err, "CheckMisbehaviour failed unexpectedly: %v", err) + } + }) + } } diff --git a/x/ibc/02-client/types/tendermint/tendermint_test.go b/x/ibc/02-client/types/tendermint/tendermint_test.go index cb3e572d6289..7f8b8e0e863c 100644 --- a/x/ibc/02-client/types/tendermint/tendermint_test.go +++ b/x/ibc/02-client/types/tendermint/tendermint_test.go @@ -24,13 +24,14 @@ func (suite *TendermintTestSuite) SetupTest() { privVal := tmtypes.NewMockPV() val := tmtypes.NewValidator(privVal.GetPubKey(), 10) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) - suite.header = MakeHeader(3, valSet, valSet, []tmtypes.PrivValidator{privVal}) + suite.header = MakeHeader("gaia", 4, valSet, valSet, []tmtypes.PrivValidator{privVal}) root := commitment.NewRoot(tmhash.Sum([]byte("my root"))) cs := ConsensusState{ ChainID: "gaia", Height: 3, Root: root, + ValidatorSet: valSet, NextValidatorSet: valSet, } diff --git a/x/ibc/02-client/types/tendermint/test_utils.go b/x/ibc/02-client/types/tendermint/test_utils.go index ac25a13fabbf..bc2b998c2e71 100644 --- a/x/ibc/02-client/types/tendermint/test_utils.go +++ b/x/ibc/02-client/types/tendermint/test_utils.go @@ -21,42 +21,13 @@ func makeBlockID(hash []byte, partSetSize int, partSetHash []byte) tmtypes.Block } -func makeVote(val tmtypes.PrivValidator, chainID string, valIndex int, height int64, round, step int, blockID tmtypes.BlockID) *tmtypes.Vote { - addr := val.GetPubKey().Address() - v := &tmtypes.Vote{ - ValidatorAddress: addr, - ValidatorIndex: valIndex, - Height: height, - Round: round, - Type: tmtypes.SignedMsgType(step), - BlockID: blockID, - } - err := val.SignVote(chainID, v) - if err != nil { - panic(err) - } - return v -} - -func randomDuplicatedVoteEvidence() *tmtypes.DuplicateVoteEvidence { - val := tmtypes.NewMockPV() - blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), 1000, tmhash.Sum([]byte("partshash"))) - blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), 1000, tmhash.Sum([]byte("partshash"))) - const chainID = "gaia" - return &tmtypes.DuplicateVoteEvidence{ - PubKey: val.GetPubKey(), - VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID), - VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2), - } -} - -func MakeHeader(height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { +func MakeHeader(chainID string, height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { vsetHash := valSet.Hash() nextHash := nextValSet.Hash() timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) tmHeader := tmtypes.Header{ Version: version.Consensus{Block: 2, App: 2}, - ChainID: "gaia", + ChainID: chainID, Height: height, Time: timestamp, NumTxs: 100, @@ -70,11 +41,11 @@ func MakeHeader(height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes. AppHash: tmhash.Sum([]byte("app_hash")), LastResultsHash: tmhash.Sum([]byte("last_results_hash")), EvidenceHash: tmhash.Sum([]byte("evidence_hash")), - ProposerAddress: signers[0].GetPubKey().Address(), + ProposerAddress: valSet.Proposer.Address, } hhash := tmHeader.Hash() blockID := makeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) - voteSet := tmtypes.NewVoteSet("gaia", height, 1, tmtypes.PrecommitType, valSet) + voteSet := tmtypes.NewVoteSet(chainID, height, 1, tmtypes.PrecommitType, valSet) commit, err := tmtypes.MakeCommit(blockID, height, 1, voteSet, signers) if err != nil { panic(err) diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index fede95f47fe9..4e39fbd8de23 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -267,9 +267,11 @@ func (suite *KeeperTestSuite) createClient(clientID string) { suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) consensusState := tendermint.ConsensusState{ - ChainID: chainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + ChainID: chainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, clientType, consensusState) diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index bf6dfe0d7839..904f02ca16d8 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -29,9 +30,10 @@ const ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet } func (suite *KeeperTestSuite) SetupTest() { @@ -41,6 +43,11 @@ func (suite *KeeperTestSuite) SetupTest() { suite.cdc = app.Codec() suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) suite.app = app + + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) } func TestKeeperTestSuite(t *testing.T) { diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index efd704c28d21..98a39778e467 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -22,11 +22,15 @@ func (suite *KeeperTestSuite) createClient() { suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, } + _ = consensusState.GetCommitter() + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) suite.NoError(err) } diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index 299b0ab9c5e5..fa011b3ae104 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -32,9 +33,10 @@ const ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet } func (suite *KeeperTestSuite) SetupTest() { @@ -45,6 +47,11 @@ func (suite *KeeperTestSuite) SetupTest() { suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) suite.app = app + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + suite.createClient() } diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 7e0f430ddaa9..2b07fbe5151a 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -50,9 +51,10 @@ var ( type HandlerTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet } func (suite *HandlerTestSuite) SetupTest() { @@ -63,6 +65,11 @@ func (suite *HandlerTestSuite) SetupTest() { suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) suite.app = app + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + suite.createClient() suite.createConnection(connection.OPEN) } @@ -75,9 +82,11 @@ func (suite *HandlerTestSuite) createClient() { suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index b7370a34d29f..cc67265bb1f8 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -46,9 +47,10 @@ var ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet } func (suite *KeeperTestSuite) SetupTest() { @@ -59,6 +61,11 @@ func (suite *KeeperTestSuite) SetupTest() { suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) suite.app = app + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + suite.createClient() suite.createConnection(connection.OPEN) } diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index fe20d2b26062..c28b4cc9db00 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -23,9 +23,11 @@ func (suite *KeeperTestSuite) createClient() { suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 07fc9f831be8..1a1e2d0189be 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -23,9 +23,6 @@ func NewHandler(k Keeper) sdk.Handler { case client.MsgUpdateClient: return client.HandleMsgUpdateClient(ctx, k.ClientKeeper, msg) - case client.MsgSubmitMisbehaviour: - return client.HandleMsgSubmitMisbehaviour(ctx, k.ClientKeeper, msg) - // IBC connection msgs case connection.MsgConnectionOpenInit: return connection.HandleMsgConnectionOpenInit(ctx, k.ConnectionKeeper, msg) From 6c2232e7e4ed0670e864ed752dcc9a7aff5a5fe0 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 10 Dec 2019 16:06:06 +0100 Subject: [PATCH 052/176] Misc ibc fixes (#5357) * fix cli ExactArgs * remove full handshakes * rm dup flag * fix error handling --- x/ibc/03-connection/client/cli/tx.go | 282 +----------------------- x/ibc/03-connection/keeper/handshake.go | 2 +- x/ibc/04-channel/client/cli/tx.go | 216 +----------------- x/ibc/20-transfer/client/cli/tx.go | 1 - 4 files changed, 14 insertions(+), 487 deletions(-) diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 3ad967b785d2..9693a62b96ea 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -36,18 +36,18 @@ const ( // chain A with a given counterparty chain B func GetCmdConnectionOpenInit(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: strings.TrimSpace(`open-init [connection-id] [client-id] [counterparty-connection-id] - [counterparty-client-id] [path/to/counterparty_prefix.json]`), + Use: strings.TrimSpace(`open-init [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json]`), Short: "initialize connection on chain A", Long: strings.TrimSpace( fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: Example: -$ %s tx ibc connection open-init [connection-id] [client-id] [counterparty-connection-id] -[counterparty-client-id] [path/to/counterparty_prefix.json] +$ %s tx ibc connection open-init [connection-id] [client-id] \ +[counterparty-connection-id] [counterparty-client-id] \ +[path/to/counterparty_prefix.json] `, version.ClientName), ), - Args: cobra.ExactArgs(6), + Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) @@ -87,7 +87,7 @@ $ %s tx ibc connection open-init [connection-id] [client-id] [counterparty-conne // chain B func GetCmdConnectionOpenTry(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: strings.TrimSpace(`open-try [connection-id] [client-id] + Use: strings.TrimSpace(`open-try [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] [counterparty-versions] [path/to/proof_init.json]`), Short: "initiate connection handshake between two chains", @@ -95,12 +95,12 @@ func GetCmdConnectionOpenTry(storeKey string, cdc *codec.Codec) *cobra.Command { fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: Example: -$ %s tx ibc connection open-try connection-id] [client-id] -[counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] +$ %s tx ibc connection open-try connection-id] [client-id] \ +[counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] \ [counterparty-versions] [path/to/proof_init.json] `, version.ClientName), ), - Args: cobra.ExactArgs(6), + Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) @@ -224,7 +224,7 @@ Example: $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] `, version.ClientName), ), - Args: cobra.ExactArgs(3), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) @@ -289,265 +289,3 @@ func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { } return path, nil } - -// func GetCmdHandshakeState(storeKey string, cdc *codec.Codec) *cobra.Command { -// cmd := &cobra.Command{ -// Use: "handshake [conn-id-chain-1] [client-id-chain-1] [path-chain-1] [conn-id-chain-2] [client-id-chain-2] [path-chain-2] ", -// Short: "initiate connection handshake between two chains", -// Args: cobra.ExactArgs(6), -// RunE: func(cmd *cobra.Command, args []string) error { -// inBuf := bufio.NewReader(cmd.InOrStdin()) -// prove := true - -// // --chain-id values for each chain -// cid1 := viper.GetString(flags.FlagChainID) -// cid2 := viper.GetString(FlagChainID2) - -// // --from values for each wallet -// from1 := viper.GetString(FlagFrom1) -// from2 := viper.GetString(FlagFrom2) - -// // --node values for each RPC -// rpc1 := viper.GetString(FlagNode1) -// rpc2 := viper.GetString(FlagNode2) - -// // ibc connection-id for each chain -// connID1 := args[0] -// connID2 := args[3] - -// // ibc client-id for each chain -// clientID1 := args[1] -// clientID2 := args[4] - -// // Get default version -// version := types.GetCompatibleVersions()[0] - -// // Create txbldr, clictx, querier for cid1 -// viper.Set(flags.FlagChainID, cid1) -// txBldr1 := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) -// ctx1 := context.NewCLIContextIBC(inBuf, from1, cid1, rpc1).WithCodec(cdc). -// WithBroadcastMode(flags.BroadcastBlock) - -// // Create txbldr, clictx, querier for cid1 -// viper.Set(flags.FlagChainID, cid2) -// txBldr2 := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) -// ctx2 := context.NewCLIContextIBC(inBuf, from2, cid2, rpc2).WithCodec(cdc). -// WithBroadcastMode(flags.BroadcastBlock) - -// // read in path for cid1 -// path1, err := parsePath(ctx1.Codec, args[2]) -// if err != nil { -// return err -// } - -// // read in path for cid2 -// path2, err := parsePath(ctx1.Codec, args[5]) -// if err != nil { -// return err -// } - -// // get passphrase for key from1 -// passphrase1, err := keys.GetPassphrase(from1) -// if err != nil { -// return err -// } - -// // get passphrase for key from2 -// passphrase2, err := keys.GetPassphrase(from2) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// msgOpenInit := types.NewMsgConnectionOpenInit( -// connID1, clientID1, connID2, clientID2, -// path2, ctx1.GetFromAddress(), -// ) - -// if err := msgOpenInit.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid1, msgOpenInit.Type()) -// res, err := utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } - -// fmt.Printf(" [OK] txid(%v) client(%v) conn(%v)\n", res.TxHash, clientID1, connID1) - -// // Another block has to be passed after msgOpenInit is committed -// // to retrieve the correct proofs -// // TODO: Modify this to actually check two blocks being processed, and -// // remove hardcoding this to 8 seconds. -// time.Sleep(8 * time.Second) - -// header, _, err := clientutils.QueryTendermintHeader(ctx1) -// if err != nil { -// return err -// } - -// // Create and send msgUpdateClient -// viper.Set(flags.FlagChainID, cid2) -// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) - -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) -// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - -// // Fetch proofs from cid1 -// viper.Set(flags.FlagChainID, cid1) -// proofs, err := queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) -// if err != nil { -// return err -// } - -// csProof, err := clientutils.QueryConsensusStateProof(ctx1.WithHeight(header.Height-1), clientID1, prove) -// if err != nil { -// return err -// } - -// // Create and send msgOpenTry -// viper.Set(flags.FlagChainID, cid2) -// msgOpenTry := types.NewMsgConnectionOpenTry(connID2, clientID2, connID1, clientID1, path1, []string{version}, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), ctx2.GetFromAddress()) - -// if err := msgOpenTry.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid2, msgOpenTry.Type()) - -// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// fmt.Printf(" [OK] txid(%v) client(%v) connection(%v)\n", res.TxHash, clientID2, connID2) - -// // Another block has to be passed after msgOpenInit is committed -// // to retrieve the correct proofs -// // TODO: Modify this to actually check two blocks being processed, and -// // remove hardcoding this to 8 seconds. -// time.Sleep(8 * time.Second) - -// header, _, err = clientutils.QueryTendermintHeader(ctx2) -// if err != nil { -// return err -// } - -// // Update the client for cid2 on cid1 -// viper.Set(flags.FlagChainID, cid1) -// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID1, header, ctx1.GetFromAddress()) - -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID2) - -// // Fetch proofs from cid2 -// viper.Set(flags.FlagChainID, cid2) -// proofs, err = queryProofs(ctx2.WithHeight(header.Height-1), connID2, storeKey) -// if err != nil { -// return err -// } - -// csProof, err = clientutils.QueryConsensusStateProof(ctx2.WithHeight(header.Height-1), clientID2, prove) -// if err != nil { -// return err -// } - -// // Create and send msgOpenAck -// viper.Set(flags.FlagChainID, cid1) -// msgOpenAck := types.NewMsgConnectionOpenAck(connID1, proofs.Proof, csProof.Proof, uint64(header.Height), uint64(header.Height), version, ctx1.GetFromAddress()) - -// if err := msgOpenAck.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid1, msgOpenAck.Type()) - -// res, err = utils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID1) - -// // Another block has to be passed after msgOpenInit is committed -// // to retrieve the correct proofs -// // TODO: Modify this to actually check two blocks being processed, and -// // remove hardcoding this to 8 seconds. -// time.Sleep(8 * time.Second) - -// header, _, err = clientutils.QueryTendermintHeader(ctx1) -// if err != nil { -// return err -// } - -// // Update client for cid1 on cid2 -// viper.Set(flags.FlagChainID, cid2) -// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientID2, header, ctx2.GetFromAddress()) - -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid2, msgUpdateClient.Type()) - -// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) client(%v)\n", res.TxHash, clientID1) - -// viper.Set(flags.FlagChainID, cid1) -// proofs, err = queryProofs(ctx1.WithHeight(header.Height-1), connID1, storeKey) -// if err != nil { -// return err -// } - -// // Create and send msgOpenConfirm -// viper.Set(flags.FlagChainID, cid2) -// msgOpenConfirm := types.NewMsgConnectionOpenConfirm(connID2, proofs.Proof, uint64(header.Height), ctx2.GetFromAddress()) - -// if err := msgOpenConfirm.ValidateBasic(); err != nil { -// return err -// } - -// fmt.Printf("%v <- %-14v", cid1, msgOpenConfirm.Type()) - -// res, err = utils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } -// fmt.Printf(" [OK] txid(%v) connection(%v)\n", res.TxHash, connID2) - -// return nil -// }, -// } - -// cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") -// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") -// cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") -// cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") -// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") - -// cmd.MarkFlagRequired(FlagNode1) -// cmd.MarkFlagRequired(FlagNode2) -// cmd.MarkFlagRequired(FlagFrom1) -// cmd.MarkFlagRequired(FlagFrom2) -// cmd.MarkFlagRequired(FlagChainID2) - -// return cmd -// } diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index f9288f7d9ae2..8e8dcbb96090 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -31,7 +31,7 @@ func (k Keeper) ConnOpenInit( err := k.addConnectionToClient(ctx, clientID, connectionID) if err != nil { - sdkerrors.Wrap(err, "cannot initialize connection") + return sdkerrors.Wrap(err, "cannot initialize connection") } k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: NONE -> INIT", connectionID)) diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index a0d5ceade64f..58bb189e2c4a 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -174,7 +174,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma return &cobra.Command{ Use: "open-confirm [port-id] [channel-id] [/path/to/proof-ack.json] [proof-height]", Short: "Creates and sends a ChannelOpenConfirm message", - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) @@ -217,7 +217,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command return &cobra.Command{ Use: "close-init [port-id] [channel-id]", Short: "Creates and sends a ChannelCloseInit message", - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) @@ -241,7 +241,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm return &cobra.Command{ Use: "close-confirm [port-id] [channel-id] [/path/to/proof-init.json] [proof-height]", Short: "Creates and sends a ChannelCloseConfirm message", - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) @@ -285,213 +285,3 @@ func channelOrder() types.Order { } return types.UNORDERED } - -// func GetCmdHandshake(storeKey string, cdc *codec.Codec) *cobra.Command { -// cmd := &cobra.Command{ -// Use: "handshake", -// Short: "initiate connection handshake between two chains", -// Long: strings.TrimSpace( -// fmt.Sprintf(`initialize a connection on chain A with a given counterparty chain B: - -// Example: -// $ %s tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-client-id] [cp-port-id] [cp-chain-id] [cp-conn-id] -// `, version.ClientName)), -// Args: cobra.ExactArgs(8), -// // Args: []string{portid1, chanid1, connid1, portid2, chanid2, connid2} -// RunE: func(cmd *cobra.Command, args []string) error { -// // --chain-id values for each chain -// cid1 := viper.GetString(flags.FlagChainID) -// cid2 := viper.GetString(FlagChainID2) - -// // --from values for each wallet -// from1 := viper.GetString(FlagFrom1) -// from2 := viper.GetString(FlagFrom2) - -// // --node values for each RPC -// node1 := viper.GetString(FlagNode1) -// node2 := viper.GetString(FlagNode2) - -// // client IDs -// clientid1 := args[0] -// clientid2 := args[4] - -// // port IDs -// portid1 := args[1] -// portid2 := args[5] - -// // channel IDs -// chanid1 := args[2] -// chanid2 := args[6] - -// // connection IDs -// connid1 := args[3] -// connid2 := args[7] - -// inBuf := bufio.NewReader(cmd.InOrStdin()) -// prove := true - -// // Create txbldr, clictx, querier for cid1 -// viper.Set(flags.FlagChainID, cid1) -// txBldr1 := auth.NewTxBuilderFromCLI(inBuf). -// WithTxEncoder(authutils.GetTxEncoder(cdc)) -// ctx1 := context.NewCLIContextIBC(inBuf, from1, cid1, node1). -// WithCodec(cdc). -// WithBroadcastMode(flags.BroadcastBlock) - -// // Create txbldr, clictx, querier for cid2 -// viper.Set(flags.FlagChainID, cid2) -// txBldr2 := auth.NewTxBuilderFromCLI(inBuf). -// WithTxEncoder(authutils.GetTxEncoder(cdc)) -// ctx2 := context.NewCLIContextIBC(inBuf, from2, cid2, node2). -// WithCodec(cdc). -// WithBroadcastMode(flags.BroadcastBlock) - -// // get passphrase for key from1 -// passphrase1, err := keys.GetPassphrase(from1) -// if err != nil { -// return err -// } - -// // get passphrase for key from2 -// passphrase2, err := keys.GetPassphrase(from2) -// if err != nil { -// return err -// } - -// // TODO: check state and if not Idle continue existing process -// viper.Set(flags.FlagChainID, cid1) -// msgOpenInit := types.NewMsgChannelOpenInit(portid1, chanid1, "v1.0.0", channelOrder(), []string{connid1}, portid2, chanid2, ctx1.GetFromAddress()) -// if err := msgOpenInit.ValidateBasic(); err != nil { -// return err -// } - -// res, err := authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenInit}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } - -// // Another block has to be passed after msginit is committed -// // to retrieve the correct proofs -// time.Sleep(8 * time.Second) - -// header, _, err := clientutils.QueryTendermintHeader(ctx1) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid2) -// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// channelRes, err := utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) -// if err != nil { -// return err -// } - -// msgOpenTry := types.NewMsgChannelOpenTry(portid2, chanid2, "v1.0.0", channelOrder(), []string{connid2}, portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenTry}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// // Another block has to be passed after msginit is committed -// // to retrieve the correct proofs -// time.Sleep(8 * time.Second) - -// header, _, err = clientutils.QueryTendermintHeader(ctx2) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid1, header, ctx1.GetFromAddress()) -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgUpdateClient}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } - -// viper.Set(flags.FlagChainID, cid2) -// channelRes, err = utils.QueryChannel(ctx2.WithHeight(header.Height-1), portid2, chanid2, prove) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// msgOpenAck := types.NewMsgChannelOpenAck(portid1, chanid1, "v1.0.0", channelRes.Proof, uint64(header.Height), ctx1.GetFromAddress()) -// if err := msgOpenAck.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr1, ctx1, []sdk.Msg{msgOpenAck}, passphrase1) -// if err != nil || !res.IsOK() { -// return err -// } - -// // Another block has to be passed after msginit is committed -// // to retrieve the correct proofs -// time.Sleep(8 * time.Second) - -// header, _, err = clientutils.QueryTendermintHeader(ctx1) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid2) -// msgUpdateClient = clienttypes.NewMsgUpdateClient(clientid2, header, ctx2.GetFromAddress()) -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgUpdateClient}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) -// channelRes, err = utils.QueryChannel(ctx1.WithHeight(header.Height-1), portid1, chanid1, prove) -// if err != nil { -// return err -// } - -// msgOpenConfirm := types.NewMsgChannelOpenConfirm(portid2, chanid2, channelRes.Proof, uint64(header.Height), ctx2.GetFromAddress()) -// if err := msgOpenConfirm.ValidateBasic(); err != nil { -// return err -// } - -// res, err = authutils.CompleteAndBroadcastTx(txBldr2, ctx2, []sdk.Msg{msgOpenConfirm}, passphrase2) -// if err != nil || !res.IsOK() { -// return err -// } - -// return nil -// }, -// } - -// cmd.Flags().String(FlagNode1, "tcp://localhost:26657", "RPC port for the first chain") -// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") -// cmd.Flags().String(FlagFrom1, "", "key in local keystore for first chain") -// cmd.Flags().String(FlagFrom2, "", "key in local keystore for second chain") -// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") -// cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") - -// cmd.MarkFlagRequired(FlagFrom1) -// cmd.MarkFlagRequired(FlagFrom2) - -// return cmd -// } diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index dc14a53c5a3b..cc68453ddedd 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -63,7 +63,6 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { }, } cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") - cmd.Flags().String(flags.FlagFrom, "", "key in local keystore to send from") return cmd } From 883c23d8918f4e4fd94eb32f77530379a0d88de7 Mon Sep 17 00:00:00 2001 From: Aditya Date: Thu, 12 Dec 2019 18:04:22 -0800 Subject: [PATCH 053/176] Implement Query Committer methods in ICS-02 (#5402) * add query methods for committers in ICS-02 * Update x/ibc/02-client/keeper/keeper.go * add REST docs --- x/ibc/02-client/client/cli/query.go | 40 +++++++++++++++++++++++++++ x/ibc/02-client/client/rest/query.go | 40 +++++++++++++++++++++++++++ x/ibc/02-client/client/utils/utils.go | 25 +++++++++++++++++ x/ibc/02-client/keeper/querier.go | 23 +++++++++++++++ x/ibc/02-client/types/querier.go | 36 ++++++++++++++++++++++++ 5 files changed, 164 insertions(+) diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index 8bc6a755db4f..3f8efd9d9698 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -121,6 +121,46 @@ $ %s query ibc client root [client-id] [height] return cmd } +// GetCmdQueryCommitter defines the command to query the committer of the chain +// at a given height +func GetCmdQueryCommitter(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "committer [client-id] [height]", + Short: "Query a committer", + Long: strings.TrimSpace( + fmt.Sprintf(`Query a committer at a specific height for a particular client + +Example: +$ %s query ibc client committer [client-id] [height] +`, version.ClientName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + clientID := args[0] + if strings.TrimSpace(clientID) == "" { + return errors.New("client ID can't be blank") + } + + height, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return fmt.Errorf("expected integer height, got: %v", args[1]) + } + + prove := viper.GetBool(flags.FlagProve) + + committerRes, err := utils.QueryCommitter(cliCtx, clientID, height, prove) + if err != nil { + return err + } + + return cliCtx.PrintOutput(committerRes) + }, + } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + return cmd +} + // GetCmdQueryHeader defines the command to query the latest header on the chain func GetCmdQueryHeader(cdc *codec.Codec) *cobra.Command { return &cobra.Command{ diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go index bc135bebc1b8..ba9cdc33d690 100644 --- a/x/ibc/02-client/client/rest/query.go +++ b/x/ibc/02-client/client/rest/query.go @@ -17,6 +17,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute st r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx, queryRoute)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/committers/{%s}", RestClientID, RestRootHeight), queryCommitterHandlerFn(cliCtx, queryRoute)).Methods("GET") r.HandleFunc("/ibc/header", queryHeaderHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/node-state", queryNodeConsensusStateHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/path", queryPathHandlerFn(cliCtx)).Methods("GET") @@ -127,6 +128,45 @@ func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Handl } } +// queryCommitterHandlerFn implements a committer querying route +// +// @Summary Query committer +// @Tags IBC +// @Produce json +// @Param client-id path string true "Client ID" +// @Param height path number true "Committer height" +// @Success 200 {object} QueryCommitter "OK" +// @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients/{client-id}/committers/{height} [get] +func queryCommitterHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + clientID := vars[RestClientID] + height, err := strconv.ParseUint(vars[RestRootHeight], 10, 64) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + prove := rest.ParseQueryProve(r) + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + committerRes, err := utils.QueryCommitter(cliCtx, clientID, height, prove) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(int64(committerRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, committerRes) + } +} + // queryHeaderHandlerFn implements a header querying route // // @Summary Query header diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index a024e0856594..04c0fa68888d 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -88,6 +88,31 @@ func QueryCommitmentRoot( return rootRes, nil } +// QueryCommitter queries the store to get the committer and a merkle proof +func QueryCommitter( + cliCtx context.CLIContext, clientID string, height uint64, prove bool, +) (types.CommitterResponse, error) { + req := abci.RequestQuery{ + Path: "store/ibc/key", + Data: types.KeyCommitter(clientID, height), + Prove: prove, + } + + res, err := cliCtx.QueryABCI(req) + if err != nil { + return types.CommitterResponse{}, err + } + + var committer tendermint.Committer + if err := cliCtx.Codec.UnmarshalJSON(res.Value, &committer); err != nil { + return types.CommitterResponse{}, err + } + + committerRes := types.NewCommitterResponse(clientID, height, committer, res.Proof, res.Height) + + return committerRes, nil +} + // QueryTendermintHeader takes a client context and returns the appropriate // tendermint header func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, error) { diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go index 8956a72fab2e..8fedcebfb8f6 100644 --- a/x/ibc/02-client/keeper/querier.go +++ b/x/ibc/02-client/keeper/querier.go @@ -75,3 +75,26 @@ func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]by return bz, nil } + +// QuerierCommitter defines the sdk.Querier to query a committer +func QuerierCommitter(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { + var params types.QueryCommitterParams + + err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + committer, found := k.GetCommitter(ctx, params.ClientID, params.Height) + if !found { + return nil, sdk.ConvertError(errors.ErrCommitterNotFound(k.codespace, + fmt.Sprintf("committer not found on height: %d", params.Height))) + } + + bz, err := types.SubModuleCdc.MarshalJSON(committer) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + + return bz, nil +} diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go index 0bf71ebaa6ae..e7ffe21c2786 100644 --- a/x/ibc/02-client/types/querier.go +++ b/x/ibc/02-client/types/querier.go @@ -45,6 +45,21 @@ func NewQueryCommitmentRootParams(id string, height uint64) QueryCommitmentRootP } } +// QueryCommitterParams defines the params for the following queries: +// - 'custom/ibc/clients//committers/' +type QueryCommitterParams struct { + ClientID string + Height uint64 +} + +// NewQueryCommitmentRootParams creates a new QueryCommitmentRootParams instance +func NewQueryCommitterParams(id string, height uint64) QueryCommitterParams { + return QueryCommitterParams{ + ClientID: id, + Height: height, + } +} + // StateResponse defines the client response for a client state query. // It includes the commitment proof and the height of the proof. type StateResponse struct { @@ -107,3 +122,24 @@ func NewRootResponse( ProofHeight: uint64(proofHeight), } } + +// CommitterResponse defines the client response for a committer query +// It includes the commitment proof and the height of the proof +type CommitterResponse struct { + Committer tmtypes.Committer `json:"committer" yaml:"committer"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` +} + +// NewCommitterResponse creates a new CommitterResponse instance. +func NewCommitterResponse( + clientID string, height uint64, committer tmtypes.Committer, proof *merkle.Proof, proofHeight int64, +) CommitterResponse { + return CommitterResponse{ + Committer: committer, + Proof: commitment.Proof{Proof: proof}, + ProofPath: commitment.NewPath(strings.Split(RootPath(clientID, height), "/")), + ProofHeight: uint64(proofHeight), + } +} From 29b82d90e4bafeb6aa5e0aeaded3a328386f5674 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 13 Dec 2019 13:36:03 -0300 Subject: [PATCH 054/176] fix test --- client/keys/root_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/keys/root_test.go b/client/keys/root_test.go index 2dcf912b98d8..49681b17e95f 100644 --- a/client/keys/root_test.go +++ b/client/keys/root_test.go @@ -15,7 +15,7 @@ func TestCommands(t *testing.T) { assert.NotNil(t, rootCommands) // Commands are registered - assert.Equal(t, 12, len(rootCommands.Commands())) + assert.Equal(t, 11, len(rootCommands.Commands())) } func TestMain(m *testing.M) { From e11aca6438b1b615a83828b807f305d9ef94ea10 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 16 Dec 2019 16:41:02 -0300 Subject: [PATCH 055/176] IBC UX improvements (#5364) * ICS02 iterators * ICS03 iterators * ICS04 iterators * ICS02 client updates * CLI connections * setup queriers * clean up queriers * add tests * IBC top-level querier tests * update ICS02 keys * update ICS03 keys * make format * update ICS04 keys * fix a few tests * fix ICS20 tests * update keys --- client/flags/flags.go | 9 ++- x/ibc/02-client/alias.go | 2 + x/ibc/02-client/client/cli/cli.go | 1 + x/ibc/02-client/client/cli/query.go | 32 ++++++++ x/ibc/02-client/client/rest/query.go | 53 +++++++++--- x/ibc/02-client/client/rest/rest.go | 5 +- x/ibc/02-client/client/rest/swagger.go | 1 + x/ibc/02-client/client/utils/utils.go | 25 ++++++ x/ibc/02-client/keeper/keeper.go | 48 ++++++++--- x/ibc/02-client/keeper/keeper_test.go | 19 ++++- x/ibc/02-client/keeper/querier.go | 84 +++++++++++++------- x/ibc/02-client/types/codec.go | 1 + x/ibc/02-client/types/keys.go | 71 +++++++++++++---- x/ibc/02-client/types/msgs.go | 4 +- x/ibc/02-client/types/querier.go | 22 ++++- x/ibc/03-connection/alias.go | 2 + x/ibc/03-connection/client/cli/cli.go | 1 + x/ibc/03-connection/client/cli/query.go | 33 ++++++++ x/ibc/03-connection/client/utils/utils.go | 25 ++++++ x/ibc/03-connection/keeper/handshake_test.go | 14 ++-- x/ibc/03-connection/keeper/keeper.go | 36 +++++++-- x/ibc/03-connection/keeper/keeper_test.go | 42 +++++++++- x/ibc/03-connection/keeper/querier.go | 52 ++++++++---- x/ibc/03-connection/types/connection.go | 2 - x/ibc/03-connection/types/keys.go | 42 +++++++--- x/ibc/03-connection/types/querier.go | 16 ++++ x/ibc/04-channel/alias.go | 2 + x/ibc/04-channel/keeper/handshake_test.go | 16 ++-- x/ibc/04-channel/keeper/keeper.go | 54 +++++++++---- x/ibc/04-channel/keeper/keeper_test.go | 57 +++++++++++-- x/ibc/04-channel/keeper/querier.go | 43 +++++++--- x/ibc/04-channel/types/codec.go | 3 + x/ibc/04-channel/types/keys.go | 78 ++++++++++++++---- x/ibc/04-channel/types/querier.go | 18 ++++- x/ibc/20-transfer/handler_test.go | 6 +- x/ibc/20-transfer/keeper/relay_test.go | 6 +- x/ibc/keeper/querier.go | 38 ++++++--- x/ibc/keeper/querier_test.go | 29 +++++-- x/ibc/types/keys.go | 40 ++++++++++ x/ibc/types/types.go | 15 ---- 40 files changed, 834 insertions(+), 213 deletions(-) create mode 100644 x/ibc/types/keys.go delete mode 100644 x/ibc/types/types.go diff --git a/client/flags/flags.go b/client/flags/flags.go index 622f582c9956..4ac18edb45f8 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -19,13 +19,17 @@ const ( DefaultGasAdjustment = 1.0 DefaultGasLimit = 200000 GasFlagAuto = "auto" +) - // DefaultKeyringBackend +// Keyring constants +const ( DefaultKeyringBackend = KeyringBackendOS KeyringBackendFile = "file" KeyringBackendOS = "os" KeyringBackendTest = "test" +) +const ( // BroadcastBlock defines a tx broadcasting mode where the client waits for // the tx to be committed in a block. BroadcastBlock = "block" @@ -35,7 +39,10 @@ const ( // BroadcastAsync defines a tx broadcasting mode where the client returns // immediately. BroadcastAsync = "async" +) +// List of CLI flags +const ( FlagHome = tmcli.HomeFlag FlagUseLedger = "ledger" FlagChainID = "chain-id" diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go index 4713a4e77dee..02f3aa623668 100644 --- a/x/ibc/02-client/alias.go +++ b/x/ibc/02-client/alias.go @@ -29,6 +29,7 @@ const ( StoreKey = types.StoreKey RouterKey = types.RouterKey QuerierRoute = types.QuerierRoute + QueryAllClients = types.QueryAllClients QueryClientState = types.QueryClientState QueryConsensusState = types.QueryConsensusState QueryVerifiedRoot = types.QueryVerifiedRoot @@ -37,6 +38,7 @@ const ( var ( // functions aliases NewKeeper = keeper.NewKeeper + QuerierClients = keeper.QuerierClients QuerierClientState = keeper.QuerierClientState QuerierConsensusState = keeper.QuerierConsensusState QuerierVerifiedRoot = keeper.QuerierVerifiedRoot diff --git a/x/ibc/02-client/client/cli/cli.go b/x/ibc/02-client/client/cli/cli.go index ac182365a7ae..d2db4d2be958 100644 --- a/x/ibc/02-client/client/cli/cli.go +++ b/x/ibc/02-client/client/cli/cli.go @@ -17,6 +17,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { } ics02ClientQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryClientStates(queryRoute, cdc), GetCmdQueryClientState(queryRoute, cdc), GetCmdQueryConsensusState(queryRoute, cdc), GetCmdQueryRoot(queryRoute, cdc), diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index 3f8efd9d9698..a64405b62993 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -17,6 +17,38 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// GetCmdQueryClientStates defines the command to query all the light clients +// that this chain mantains. +func GetCmdQueryClientStates(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "states", + Short: "Query all available light clients", + Long: strings.TrimSpace( + fmt.Sprintf(`Query all available light clients + +Example: +$ %s query ibc client states + `, version.ClientName), + ), + Example: fmt.Sprintf("%s query ibc client states", version.ClientName), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + page := viper.GetInt(flags.FlagPage) + limit := viper.GetInt(flags.FlagLimit) + + clientStates, _, err := utils.QueryAllClientStates(cliCtx, page, limit) + if err != nil { + return err + } + + return cliCtx.PrintOutput(clientStates) + }, + } + cmd.Flags().Int(flags.FlagPage, 1, "pagination page of light clients to to query for") + cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of light clients to query for") + return cmd +} + // GetCmdQueryClientState defines the command to query the state of a client with // a given id as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query func GetCmdQueryClientState(queryRoute string, cdc *codec.Codec) *cobra.Command { diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go index ba9cdc33d690..d831aa396719 100644 --- a/x/ibc/02-client/client/rest/query.go +++ b/x/ibc/02-client/client/rest/query.go @@ -13,16 +13,51 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx, queryRoute)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx, queryRoute)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx, queryRoute)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/committers/{%s}", RestClientID, RestRootHeight), queryCommitterHandlerFn(cliCtx, queryRoute)).Methods("GET") +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc("/ibc/clients", queryAllClientStatesFn(cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/committers/{%s}", RestClientID, RestRootHeight), queryCommitterHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/header", queryHeaderHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/node-state", queryNodeConsensusStateHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/path", queryPathHandlerFn(cliCtx)).Methods("GET") } +// queryAllClientStatesFn queries all available light clients +// +// @Summary Query client states +// @Tags IBC +// @Produce json +// @Param page query int false "The page number to query" default(1) +// @Param limit query int false "The number of results per page" default(100) +// @Success 200 {object} QueryClientState "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/clients [get] +func queryAllClientStatesFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + _, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + clients, height, err := utils.QueryAllClientStates(cliCtx, page, limit) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, clients) + } +} + // queryClientStateHandlerFn implements a client state querying route // // @Summary Query client state @@ -34,7 +69,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute st // @Failure 400 {object} rest.ErrorResponse "Invalid client id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/clients/{client-id}/client-state [get] -func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +func queryClientStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] @@ -67,7 +102,7 @@ func queryClientStateHandlerFn(cliCtx context.CLIContext, queryRoute string) htt // @Failure 400 {object} rest.ErrorResponse "Invalid client id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/clients/{client-id}/consensus-state [get] -func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +func queryConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] @@ -100,7 +135,7 @@ func queryConsensusStateHandlerFn(cliCtx context.CLIContext, queryRoute string) // @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/clients/{client-id}/roots/{height} [get] -func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +func queryRootHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] @@ -139,7 +174,7 @@ func queryRootHandlerFn(cliCtx context.CLIContext, queryRoute string) http.Handl // @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/clients/{client-id}/committers/{height} [get] -func queryCommitterHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { +func queryCommitterHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] diff --git a/x/ibc/02-client/client/rest/rest.go b/x/ibc/02-client/client/rest/rest.go index 51f8ce762bcb..34000c329e0d 100644 --- a/x/ibc/02-client/client/rest/rest.go +++ b/x/ibc/02-client/client/rest/rest.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" ) +// REST client flags const ( RestClientID = "client-id" RestRootHeight = "height" @@ -16,7 +17,7 @@ const ( // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { - registerQueryRoutes(cliCtx, r, queryRoute) + registerQueryRoutes(cliCtx, r) registerTxRoutes(cliCtx, r) } @@ -35,6 +36,6 @@ type UpdateClientReq struct { // SubmitMisbehaviourReq defines the properties of a submit misbehaviour request's body. type SubmitMisbehaviourReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` } diff --git a/x/ibc/02-client/client/rest/swagger.go b/x/ibc/02-client/client/rest/swagger.go index b3f64c566e72..2ff01ff34fb8 100644 --- a/x/ibc/02-client/client/rest/swagger.go +++ b/x/ibc/02-client/client/rest/swagger.go @@ -7,6 +7,7 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// nolint type ( QueryConsensusState struct { Height int64 `json:"height"` diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 04c0fa68888d..30f56e57a9db 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -1,6 +1,8 @@ package utils import ( + "fmt" + abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" @@ -11,6 +13,29 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// QueryAllClientStates returns all the light client states. It _does not_ return +// any merkle proof. +func QueryAllClientStates(cliCtx context.CLIContext, page, limit int) ([]types.State, int64, error) { + params := types.NewQueryAllClientsParams(page, limit) + bz, err := cliCtx.Codec.MarshalJSON(params) + if err != nil { + return nil, 0, fmt.Errorf("failed to marshal query params: %w", err) + } + + route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAllClients) + res, height, err := cliCtx.QueryWithData(route, bz) + if err != nil { + return nil, 0, err + } + + var clients []types.State + err = cliCtx.Codec.UnmarshalJSON(res, &clients) + if err != nil { + return nil, 0, fmt.Errorf("failed to unmarshal light clients: %w", err) + } + return clients, height, nil +} + // QueryClientState queries the store to get the light client state and a merkle // proof. func QueryClientState( diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index e5c4feb26263..a8b1876d1e41 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -6,7 +6,6 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" @@ -40,7 +39,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetClientState gets a particular client from the store func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyClientState(clientID)) if bz == nil { return types.State{}, false @@ -53,14 +52,14 @@ func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, b // SetClientState sets a particular Client to the store func (k Keeper) SetClientState(ctx sdk.Context, clientState types.State) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(clientState) store.Set(types.KeyClientState(clientState.ID), bz) } // GetClientType gets the consensus type for a specific client func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.ClientType, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyClientType(clientID)) if bz == nil { return 0, false @@ -71,13 +70,13 @@ func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.Client // SetClientType sets the specific client consensus type to the provable store func (k Keeper) SetClientType(ctx sdk.Context, clientID string, clientType exported.ClientType) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) store.Set(types.KeyClientType(clientID), []byte{byte(clientType)}) } // GetConsensusState creates a new client state and populates it with a given consensus state func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.ConsensusState, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyConsensusState(clientID)) if bz == nil { return nil, false @@ -90,7 +89,7 @@ func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.Co // SetConsensusState sets a ConsensusState to a particular client func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) store.Set(types.KeyConsensusState(clientID), bz) } @@ -98,7 +97,7 @@ func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusSta // GetVerifiedRoot gets a verified commitment Root from a particular height to // a client func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) (commitment.RootI, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyRoot(clientID, height)) if bz == nil { @@ -113,15 +112,42 @@ func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) // SetVerifiedRoot sets a verified commitment Root from a particular height to // a client func (k Keeper) SetVerifiedRoot(ctx sdk.Context, clientID string, height uint64, root commitment.RootI) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(root) store.Set(types.KeyRoot(clientID, height), bz) } +// IterateClients provides an iterator over all stored light client State +// objects. For each State object, cb will be called. If the cb returns true, +// the iterator will close and stop. +func (k Keeper) IterateClients(ctx sdk.Context, cb func(types.State) bool) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.GetClientKeysPrefix(ibctypes.KeyClientPrefix)) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var clientState types.State + k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &clientState) + + if cb(clientState) { + break + } + } +} + +// GetAllClients returns all stored light client State objects. +func (k Keeper) GetAllClients(ctx sdk.Context) (states []types.State) { + k.IterateClients(ctx, func(state types.State) bool { + states = append(states, state) + return false + }) + return states +} + // GetCommitter will get the Committer of a particular client at the oldest height // that is less than or equal to the height passed in func (k Keeper) GetCommitter(ctx sdk.Context, clientID string, height uint64) (exported.Committer, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) var committer exported.Committer @@ -139,7 +165,7 @@ func (k Keeper) GetCommitter(ctx sdk.Context, clientID string, height uint64) (e // SetCommitter sets a committer from a particular height to // a particular client func (k Keeper) SetCommitter(ctx sdk.Context, clientID string, height uint64, committer exported.Committer) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixClient) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(committer) store.Set(types.KeyCommitter(clientID, height), bz) } diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index da79777dae50..2c74a5a22f7c 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -21,7 +21,9 @@ import ( ) const ( - testClientID = "gaia" + testClientID = "gaia" + testClientID2 = "ethbridge" + testClientID3 = "ethermint" ) type KeeperTestSuite struct { @@ -147,5 +149,20 @@ func (suite KeeperTestSuite) TestSetCommitter() { require.True(suite.T(), ok, "GetCommitter failed on existing height: %d", i) require.Equal(suite.T(), nextCommitter, recv, "GetCommitter returned committer on nonexistent height: %d", i) } +} + +func (suite KeeperTestSuite) TestGetAllClients() { + expClients := []types.State{ + types.NewClientState(testClientID2), + types.NewClientState(testClientID3), + types.NewClientState(testClientID), + } + + for i := range expClients { + suite.keeper.SetClientState(suite.ctx, expClients[i]) + } + clients := suite.keeper.GetAllClients(suite.ctx) + suite.Require().Len(clients, len(expClients)) + suite.Require().Equal(expClients, clients) } diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go index 8fedcebfb8f6..104ad554c700 100644 --- a/x/ibc/02-client/keeper/querier.go +++ b/x/ibc/02-client/keeper/querier.go @@ -5,95 +5,121 @@ import ( abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" ) +// QuerierClients defines the sdk.Querier to query all the light client states. +func QuerierClients(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { + var params types.QueryAllClientsParams + + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) + } + + clients := k.GetAllClients(ctx) + + start, end := client.Paginate(len(clients), params.Page, params.Limit, 100) + if start < 0 || end < 0 { + clients = []types.State{} + } else { + clients = clients[start:end] + } + + res, err := codec.MarshalJSONIndent(k.cdc, clients) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} + // QuerierClientState defines the sdk.Querier to query the IBC client state -func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryClientStateParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } clientState, found := k.GetClientState(ctx, params.ClientID) if !found { - return nil, sdk.ConvertError(errors.ErrClientTypeNotFound(k.codespace)) + return nil, errors.ErrClientTypeNotFound(k.codespace) } - bz, err := types.SubModuleCdc.MarshalJSON(clientState) + bz, err := codec.MarshalJSONIndent(k.cdc, clientState) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } // QuerierConsensusState defines the sdk.Querier to query a consensus state -func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryClientStateParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } consensusState, found := k.GetConsensusState(ctx, params.ClientID) if !found { - return nil, sdk.ConvertError(errors.ErrConsensusStateNotFound(k.codespace)) + return nil, errors.ErrConsensusStateNotFound(k.codespace) } - bz, err := types.SubModuleCdc.MarshalJSON(consensusState) + bz, err := codec.MarshalJSONIndent(k.cdc, consensusState) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } // QuerierVerifiedRoot defines the sdk.Querier to query a verified commitment root -func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryCommitmentRootParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } root, found := k.GetVerifiedRoot(ctx, params.ClientID, params.Height) if !found { - return nil, sdk.ConvertError(errors.ErrRootNotFound(k.codespace)) + return nil, errors.ErrRootNotFound(k.codespace) } - bz, err := types.SubModuleCdc.MarshalJSON(root) + bz, err := codec.MarshalJSONIndent(k.cdc, root) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } // QuerierCommitter defines the sdk.Querier to query a committer -func QuerierCommitter(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierCommitter(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryCommitterParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } committer, found := k.GetCommitter(ctx, params.ClientID, params.Height) if !found { - return nil, sdk.ConvertError(errors.ErrCommitterNotFound(k.codespace, - fmt.Sprintf("committer not found on height: %d", params.Height))) + return nil, errors.ErrCommitterNotFound( + k.codespace, + fmt.Sprintf("committer not found on height: %d", params.Height), + ) } - bz, err := types.SubModuleCdc.MarshalJSON(committer) + bz, err := codec.MarshalJSONIndent(k.cdc, committer) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index ed923f5cbc89..6cd376b6e8ea 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -18,6 +18,7 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgCreateClient{}, "ibc/client/MsgCreateClient", nil) cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) + cdc.RegisterConcrete(State{}, "ibc/client/State", nil) cdc.RegisterConcrete(tendermint.ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) cdc.RegisterConcrete(tendermint.Committer{}, "ibc/client/tendermint/Committer", nil) diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go index 6dc55a77baf0..eeb7e8b0d8b9 100644 --- a/x/ibc/02-client/types/keys.go +++ b/x/ibc/02-client/types/keys.go @@ -2,6 +2,8 @@ package types import ( "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) const ( @@ -18,67 +20,102 @@ const ( QuerierRoute string = SubModuleName ) -// KVStore key prefixes -var ( - KeyPrefixClient = []byte{} -) - // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space // ClientStatePath takes an Identifier and returns a Path under which to store a // particular client state func ClientStatePath(clientID string) string { - return fmt.Sprintf("clients/%s/state", clientID) + return string(KeyClientState(clientID)) } // ClientTypePath takes an Identifier and returns Path under which to store the // type of a particular client. func ClientTypePath(clientID string) string { - return fmt.Sprintf("clients/%s/type", clientID) + return string(KeyClientType(clientID)) } // ConsensusStatePath takes an Identifier and returns a Path under which to // store the consensus state of a client. func ConsensusStatePath(clientID string) string { - return fmt.Sprintf("clients/%s/consensusState", clientID) + return string(KeyConsensusState(clientID)) } // RootPath takes an Identifier and returns a Path under which to // store the root for a particular height of a client. func RootPath(clientID string, height uint64) string { - return fmt.Sprintf("clients/%s/roots/%d", clientID, height) + return string(KeyRoot(clientID, height)) } // CommitterPath takes an Identifier and returns a Path under which // to store the committer of a client at a particular height func CommitterPath(clientID string, height uint64) string { - return fmt.Sprintf("clients/%s/committer/%d", clientID, height) + return string(KeyCommitter(clientID, height)) } // KeyClientState returns the store key for a particular client state func KeyClientState(clientID string) []byte { - return []byte(ClientStatePath(clientID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyClientPrefix), + []byte(clientStatePath(clientID))..., + ) } // KeyClientType returns the store key for type of a particular client func KeyClientType(clientID string) []byte { - return []byte(ClientTypePath(clientID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyClientTypePrefix), + []byte(clientTypePath(clientID))..., + ) } // KeyConsensusState returns the store key for the consensus state of a particular // client func KeyConsensusState(clientID string) []byte { - return []byte(ConsensusStatePath(clientID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyConsensusStatePrefix), + []byte(consensusStatePath(clientID))..., + ) } // KeyRoot returns the store key for a commitment root of a particular // client at a given height func KeyRoot(clientID string, height uint64) []byte { - return []byte(RootPath(clientID, height)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyRootPrefix), + []byte(rootPath(clientID, height))..., + ) } -// KeyValidatorSet returns the store key for a validator of a particular -// client at a given height. Key => clientID||height +// KeyCommitter returns the store key for a validator (aka commiter) of a particular +// client at a given height. func KeyCommitter(clientID string, height uint64) []byte { - return []byte(CommitterPath(clientID, height)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyCommiterPrefix), + []byte(committerPath(clientID, height))..., + ) +} + +// GetClientKeysPrefix return the ICS02 prefix bytes +func GetClientKeysPrefix(prefix int) []byte { + return []byte(fmt.Sprintf("%d/clients", prefix)) +} + +func clientStatePath(clientID string) string { + return fmt.Sprintf("clients/%s/state", clientID) +} + +func clientTypePath(clientID string) string { + return fmt.Sprintf("clients/%s/type", clientID) +} + +func consensusStatePath(clientID string) string { + return fmt.Sprintf("clients/%s/consensusState", clientID) +} + +func rootPath(clientID string, height uint64) string { + return fmt.Sprintf("clients/%s/roots/%d", clientID, height) +} + +func committerPath(clientID string, height uint64) string { + return fmt.Sprintf("clients/%s/committer/%d", clientID, height) } diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index 6f0aa7959ac7..039f9d04d879 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -127,9 +127,9 @@ func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress { // MsgSubmitMisbehaviour defines a message to update an IBC client type MsgSubmitMisbehaviour struct { - ClientID string `json:"id" yaml:"id"` + ClientID string `json:"id" yaml:"id"` Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` - Signer sdk.AccAddress `json:"address" yaml:"address"` + Signer sdk.AccAddress `json:"address" yaml:"address"` } // NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go index e7ffe21c2786..d2862307b09b 100644 --- a/x/ibc/02-client/types/querier.go +++ b/x/ibc/02-client/types/querier.go @@ -11,6 +11,7 @@ import ( // query routes supported by the IBC client Querier const ( + QueryAllClients = "client_states" QueryClientState = "client_state" QueryConsensusState = "consensus_state" QueryVerifiedRoot = "roots" @@ -30,6 +31,21 @@ func NewQueryClientStateParams(id string) QueryClientStateParams { } } +// QueryAllClientsParams defines the parameters necessary for querying for all +// light client states. +type QueryAllClientsParams struct { + Page int `json:"page" yaml:"page"` + Limit int `json:"limit" yaml:"limit"` +} + +// NewQueryAllClientsParams creates a new QueryAllClientsParams instance. +func NewQueryAllClientsParams(page, limit int) QueryAllClientsParams { + return QueryAllClientsParams{ + Page: page, + Limit: limit, + } +} + // QueryCommitmentRootParams defines the params for the following queries: // - 'custom/ibc/clients//roots/' type QueryCommitmentRootParams struct { @@ -52,7 +68,7 @@ type QueryCommitterParams struct { Height uint64 } -// NewQueryCommitmentRootParams creates a new QueryCommitmentRootParams instance +// NewQueryCommitterParams creates a new QueryCommitmentRootParams instance func NewQueryCommitterParams(id string, height uint64) QueryCommitterParams { return QueryCommitterParams{ ClientID: id, @@ -76,7 +92,7 @@ func NewClientStateResponse( return StateResponse{ ClientState: clientState, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ConsensusStatePath(clientID), "/")), + ProofPath: commitment.NewPath(strings.Split(ClientStatePath(clientID), "/")), ProofHeight: uint64(height), } } @@ -139,7 +155,7 @@ func NewCommitterResponse( return CommitterResponse{ Committer: committer, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(RootPath(clientID, height), "/")), + ProofPath: commitment.NewPath(strings.Split(CommitterPath(clientID, height), "/")), ProofHeight: uint64(proofHeight), } } diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index b73456d28dc8..67367f45b6cb 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -36,6 +36,7 @@ const ( StoreKey = types.StoreKey RouterKey = types.RouterKey QuerierRoute = types.QuerierRoute + QueryAllConnections = types.QueryAllConnections QueryConnection = types.QueryConnection QueryClientConnections = types.QueryClientConnections ) @@ -43,6 +44,7 @@ const ( var ( // functions aliases NewKeeper = keeper.NewKeeper + QuerierConnections = keeper.QuerierConnections QuerierConnection = keeper.QuerierConnection QuerierClientConnections = keeper.QuerierClientConnections RegisterCodec = types.RegisterCodec diff --git a/x/ibc/03-connection/client/cli/cli.go b/x/ibc/03-connection/client/cli/cli.go index 9d3777f1fefa..e0ea7c89880f 100644 --- a/x/ibc/03-connection/client/cli/cli.go +++ b/x/ibc/03-connection/client/cli/cli.go @@ -17,6 +17,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { } ics03ConnectionQueryCmd.AddCommand(client.GetCommands( + GetCmdQueryConnections(queryRoute, cdc), GetCmdQueryConnection(queryRoute, cdc), )...) return ics03ConnectionQueryCmd diff --git a/x/ibc/03-connection/client/cli/query.go b/x/ibc/03-connection/client/cli/query.go index 4eb3f167b451..b3cc8fa0ea80 100644 --- a/x/ibc/03-connection/client/cli/query.go +++ b/x/ibc/03-connection/client/cli/query.go @@ -14,6 +14,39 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" ) +// GetCmdQueryConnections defines the command to query all the connection ends +// that this chain mantains. +func GetCmdQueryConnections(queryRoute string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "connections", + Short: "Query all available light clients", + Long: strings.TrimSpace( + fmt.Sprintf(`Query all available connections + +Example: +$ %s query ibc connection connections + `, version.ClientName), + ), + Example: fmt.Sprintf("%s query ibc connection connections", version.ClientName), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + page := viper.GetInt(flags.FlagPage) + limit := viper.GetInt(flags.FlagLimit) + + connections, _, err := utils.QueryAllConnections(cliCtx, page, limit) + if err != nil { + return err + } + + return cliCtx.PrintOutput(connections) + }, + } + cmd.Flags().Int(flags.FlagPage, 1, "pagination page of light clients to to query for") + cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of light clients to query for") + return cmd +} + // GetCmdQueryConnection defines the command to query a connection end func GetCmdQueryConnection(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ diff --git a/x/ibc/03-connection/client/utils/utils.go b/x/ibc/03-connection/client/utils/utils.go index 5cfd7bf7dab4..0f54e9e3b5cc 100644 --- a/x/ibc/03-connection/client/utils/utils.go +++ b/x/ibc/03-connection/client/utils/utils.go @@ -1,12 +1,37 @@ package utils import ( + "fmt" + abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) +// QueryAllConnections returns all the connections. It _does not_ return +// any merkle proof. +func QueryAllConnections(cliCtx context.CLIContext, page, limit int) ([]types.ConnectionEnd, int64, error) { + params := types.NewQueryAllConnectionsParams(page, limit) + bz, err := cliCtx.Codec.MarshalJSON(params) + if err != nil { + return nil, 0, fmt.Errorf("failed to marshal query params: %w", err) + } + + route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAllConnections) + res, height, err := cliCtx.QueryWithData(route, bz) + if err != nil { + return nil, 0, err + } + + var connections []types.ConnectionEnd + err = cliCtx.Codec.UnmarshalJSON(res, &connections) + if err != nil { + return nil, 0, fmt.Errorf("failed to unmarshal connections: %w", err) + } + return connections, height, nil +} + // QueryConnection queries the store to get a connection end and a merkle // proof. func QueryConnection( diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index 4e39fbd8de23..ba42ba25ee27 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -52,8 +52,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.createClient(testClientID1) suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) - connectionKey := connection.ConnectionPath(testConnectionID2) - consensusKey := string(client.KeyConsensusState(testClientID2)) + connectionKey := connection.KeyConnection(testConnectionID2) + consensusKey := client.KeyConsensusState(testClientID2) invalidProof := func() error { proofInit, proofHeight := suite.queryProof(connectionKey) @@ -119,8 +119,8 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { suite.createClient(testClientID1) suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) - connectionKey := connection.ConnectionPath(testConnectionID1) - consensusKey := string(client.KeyConsensusState(testClientID1)) + connectionKey := connection.KeyConnection(testConnectionID1) + consensusKey := client.KeyConsensusState(testClientID1) connectionNotFound := func() error { //suite.updateClient(testClientID2) @@ -196,7 +196,7 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { suite.createClient(testClientID1) suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.OPEN) - connKey := connection.ConnectionPath(testConnectionID2) + connKey := connection.KeyConnection(testConnectionID2) proof, h := suite.queryProof(connKey) connectionNotFound := func() error { @@ -244,10 +244,10 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { } } -func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { +func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { res := suite.app.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", storeKey), - Data: []byte(key), + Data: key, Prove: true, }) diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index d86a527d169c..c20720c17788 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -6,7 +6,6 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -45,7 +44,7 @@ func (k Keeper) GetCommitmentPrefix() commitment.PrefixI { // GetConnection returns a connection with a particular identifier func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyConnection(connectionID)) if bz == nil { return types.ConnectionEnd{}, false @@ -58,7 +57,7 @@ func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.Conne // SetConnection sets a connection to the store func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(connection) store.Set(types.KeyConnection(connectionID), bz) } @@ -66,7 +65,7 @@ func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection t // GetClientConnectionPaths returns all the connection paths stored under a // particular client func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyClientConnections(clientID)) if bz == nil { return nil, false @@ -79,11 +78,38 @@ func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]st // SetClientConnectionPaths sets the connections paths for client func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths []string) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixConnection) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(paths) store.Set(types.KeyClientConnections(clientID), bz) } +// IterateConnections provides an iterator over all ConnectionEnd objects. +// For each ConnectionEnd, cb will be called. If the cb returns true, the +// iterator will close and stop. +func (k Keeper) IterateConnections(ctx sdk.Context, cb func(types.ConnectionEnd) bool) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.GetConnectionsKeysPrefix(ibctypes.KeyConnectionPrefix)) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var connection types.ConnectionEnd + k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &connection) + + if cb(connection) { + break + } + } +} + +// GetAllConnections returns all stored ConnectionEnd objects. +func (k Keeper) GetAllConnections(ctx sdk.Context) (connections []types.ConnectionEnd) { + k.IterateConnections(ctx, func(connection types.ConnectionEnd) bool { + connections = append(connections, connection) + return false + }) + return connections +} + // addConnectionToClient is used to add a connection identifier to the set of // connections associated with a client. // diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 904f02ca16d8..a4872d114363 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -25,6 +25,9 @@ const ( testClientID2 = "testclientid2" testConnectionID2 = "connectionid2" + + testClientID3 = "testclientid3" + testConnectionID3 = "connectionid3" ) type KeeperTestSuite struct { @@ -72,7 +75,6 @@ func (suite *KeeperTestSuite) TestSetAndGetConnection() { } func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { - _, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1) suite.False(existed) @@ -81,3 +83,41 @@ func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { suite.True(existed) suite.EqualValues(types.GetCompatibleVersions(), paths) } + +func (suite KeeperTestSuite) TestGetAllConnections() { + // Connection (Counterparty): A(C) -> C(B) -> B(A) + counterparty1 := types.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + counterparty2 := types.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + counterparty3 := types.NewCounterparty(testClientID3, testConnectionID3, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + + conn1 := types.ConnectionEnd{ + State: types.INIT, + ClientID: testClientID1, + Counterparty: counterparty3, + Versions: types.GetCompatibleVersions(), + } + + conn2 := types.ConnectionEnd{ + State: types.INIT, + ClientID: testClientID2, + Counterparty: counterparty1, + Versions: types.GetCompatibleVersions(), + } + + conn3 := types.ConnectionEnd{ + State: types.NONE, + ClientID: testClientID3, + Counterparty: counterparty2, + Versions: types.GetCompatibleVersions(), + } + + expConnections := []types.ConnectionEnd{conn1, conn2, conn3} + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID1, expConnections[0]) + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID2, expConnections[1]) + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID3, expConnections[2]) + + connections := suite.app.IBCKeeper.ConnectionKeeper.GetAllConnections(suite.ctx) + suite.Require().Len(connections, len(expConnections)) + suite.Require().Equal(expConnections, connections) +} diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go index 8802ec7443fe..f5c56834161f 100644 --- a/x/ibc/03-connection/keeper/querier.go +++ b/x/ibc/03-connection/keeper/querier.go @@ -1,29 +1,29 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) // QuerierConnection defines the sdk.Querier to query a connection end -func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryConnectionParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } connection, found := k.GetConnection(ctx, params.ConnectionID) if !found { - return nil, sdk.ConvertError(types.ErrConnectionNotFound(k.codespace, params.ConnectionID)) + return nil, types.ErrConnectionNotFound(k.codespace, params.ConnectionID) } - bz, err := types.SubModuleCdc.MarshalJSON(connection) + bz, err := codec.MarshalJSONIndent(k.cdc, connection) if err != nil { return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } @@ -31,23 +31,47 @@ func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte return bz, nil } +// QuerierConnections defines the sdk.Querier to query all the connections. +func QuerierConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { + var params types.QueryAllConnectionsParams + + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) + } + + connections := k.GetAllConnections(ctx) + + start, end := client.Paginate(len(connections), params.Page, params.Limit, 100) + if start < 0 || end < 0 { + connections = []types.ConnectionEnd{} + } else { + connections = connections[start:end] + } + + res, err := codec.MarshalJSONIndent(k.cdc, connections) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} + // QuerierClientConnections defines the sdk.Querier to query the client connections -func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryClientConnectionsParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } clientConnectionPaths, found := k.GetClientConnectionPaths(ctx, params.ClientID) if !found { - return nil, sdk.ConvertError(types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID)) + return nil, types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID) } bz, err := types.SubModuleCdc.MarshalJSON(clientConnectionPaths) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 23ec6ca5709b..8abbda60a313 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -36,8 +36,6 @@ func NewConnectionEnd(state State, clientID string, counterparty Counterparty, v } } -// TODO: create a custom JSON marshaler - // Counterparty defines the counterparty chain associated with a connection end. type Counterparty struct { ClientID string `json:"client_id" yaml:"client_id"` diff --git a/x/ibc/03-connection/types/keys.go b/x/ibc/03-connection/types/keys.go index dbdbc576c61d..345b6b58d023 100644 --- a/x/ibc/03-connection/types/keys.go +++ b/x/ibc/03-connection/types/keys.go @@ -2,6 +2,8 @@ package types import ( "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) const ( @@ -18,29 +20,43 @@ const ( QuerierRoute = SubModuleName ) -// KVStore key prefixes -var ( - KeyPrefixConnection = []byte{} -) - // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths +// ClientConnectionsPath defines a reverse mapping from clients to a set of connections +func ClientConnectionsPath(clientID string) string { + return string(KeyClientConnections(clientID)) +} + // ConnectionPath defines the path under which connection paths are stored func ConnectionPath(connectionID string) string { - return fmt.Sprintf("connections/%s", connectionID) + return string(KeyConnection(connectionID)) } -// ClientConnectionsPath defines a reverse mapping from clients to a set of connections -func ClientConnectionsPath(clientID string) string { - return fmt.Sprintf("clients/%s/connections", clientID) +// KeyClientConnections returns the store key for the connectios of a given client +func KeyClientConnections(clientID string) []byte { + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyClientConnectionsPrefix), + []byte(clientConnectionsPath(clientID))..., + ) } // KeyConnection returns the store key for a particular connection func KeyConnection(connectionID string) []byte { - return []byte(ConnectionPath(connectionID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyConnectionPrefix), + []byte(connectionPath(connectionID))..., + ) } -// KeyClientConnections returns the store key for the connectios of a given client -func KeyClientConnections(clientID string) []byte { - return []byte(ClientConnectionsPath(clientID)) +// GetConnectionsKeysPrefix return the connection prefixes +func GetConnectionsKeysPrefix(prefix int) []byte { + return []byte(fmt.Sprintf("%d/connections", prefix)) +} + +func clientConnectionsPath(clientID string) string { + return fmt.Sprintf("clients/%s/connections", clientID) +} + +func connectionPath(connectionID string) string { + return fmt.Sprintf("connections/%s", connectionID) } diff --git a/x/ibc/03-connection/types/querier.go b/x/ibc/03-connection/types/querier.go index c254bebd6b4c..02581d42b15e 100644 --- a/x/ibc/03-connection/types/querier.go +++ b/x/ibc/03-connection/types/querier.go @@ -10,6 +10,7 @@ import ( // query routes supported by the IBC connection Querier const ( + QueryAllConnections = "connections" QueryConnection = "connection" QueryClientConnections = "client_connections" ) @@ -48,6 +49,21 @@ func NewQueryConnectionParams(clientID string) QueryConnectionParams { } } +// QueryAllConnectionsParams defines the parameters necessary for querying for all +// connections. +type QueryAllConnectionsParams struct { + Page int `json:"page" yaml:"page"` + Limit int `json:"limit" yaml:"limit"` +} + +// NewQueryAllConnectionsParams creates a new QueryAllConnectionsParams instance. +func NewQueryAllConnectionsParams(page, limit int) QueryAllConnectionsParams { + return QueryAllConnectionsParams{ + Page: page, + Limit: limit, + } +} + // ClientConnectionsResponse defines the client query response for a client // connection paths which also includes a proof and the height from which the // proof was retrieved. diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index 8ce587180679..d5494175505a 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -44,12 +44,14 @@ const ( StoreKey = types.StoreKey RouterKey = types.RouterKey QuerierRoute = types.QuerierRoute + QueryAllChannels = types.QueryAllChannels QueryChannel = types.QueryChannel ) var ( // functions aliases NewKeeper = keeper.NewKeeper + QuerierChannels = keeper.QuerierChannels QuerierChannel = keeper.QuerierChannel NewChannel = types.NewChannel NewCounterparty = types.NewCounterparty diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 98a39778e467..98fa69d5451e 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -5,7 +5,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" @@ -84,7 +83,7 @@ func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID } func (suite *KeeperTestSuite) deleteChannel(portID string, chanID string) { - store := prefix.NewStore(suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)), types.KeyPrefixChannel) + store := suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)) store.Delete(types.KeyChannel(portID, chanID)) } @@ -92,10 +91,10 @@ func (suite *KeeperTestSuite) bindPort(portID string) sdk.CapabilityKey { return suite.app.IBCKeeper.PortKeeper.BindPort(portID) } -func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { +func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { res := suite.app.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: []byte(key), + Data: key, Prove: true, }) @@ -134,7 +133,7 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { func (suite *KeeperTestSuite) TestChanOpenTry() { counterparty := types.NewCounterparty(testPort1, testChannel1) suite.bindPort(testPort2) - channelKey := types.ChannelPath(testPort1, testChannel1) + channelKey := types.KeyChannel(testPort1, testChannel1) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.INIT) @@ -164,7 +163,6 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) - fmt.Println(proofInit) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) suite.NoError(err) // successfully executed @@ -175,7 +173,7 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { func (suite *KeeperTestSuite) TestChanOpenAck() { suite.bindPort(testPort1) - channelKey := types.ChannelPath(testPort2, testChannel2) + channelKey := types.KeyChannel(testPort2, testChannel2) suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) suite.updateClient() @@ -219,7 +217,7 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { func (suite *KeeperTestSuite) TestChanOpenConfirm() { suite.bindPort(testPort2) - channelKey := types.ChannelPath(testPort1, testChannel1) + channelKey := types.KeyChannel(testPort1, testChannel1) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) suite.updateClient() @@ -293,7 +291,7 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { func (suite *KeeperTestSuite) TestChanCloseConfirm() { suite.bindPort(testPort2) - channelKey := types.ChannelPath(testPort1, testChannel1) + channelKey := types.KeyChannel(testPort1, testChannel1) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) suite.updateClient() diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index 0de7cc329288..5d72ab76cc60 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -7,7 +7,6 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -46,7 +45,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetChannel returns a channel with a particular identifier binded to a specific port func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyChannel(portID, channelID)) if bz == nil { return types.Channel{}, false @@ -59,14 +58,14 @@ func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Cha // SetChannel sets a channel to the store func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel types.Channel) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(channel) store.Set(types.KeyChannel(portID, channelID), bz) } // GetChannelCapability gets a channel's capability key from the store func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) (string, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyChannelCapabilityPath(portID, channelID)) if bz == nil { return "", false @@ -77,13 +76,13 @@ func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) // SetChannelCapability sets a channel's capability key to the store func (k Keeper) SetChannelCapability(ctx sdk.Context, portID, channelID string, key string) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) store.Set(types.KeyChannelCapabilityPath(portID, channelID), []byte(key)) } // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyNextSequenceSend(portID, channelID)) if bz == nil { return 0, false @@ -94,14 +93,14 @@ func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) ( // SetNextSequenceSend sets a channel's next send sequence to the store func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := sdk.Uint64ToBigEndian(sequence) store.Set(types.KeyNextSequenceSend(portID, channelID), bz) } // GetNextSequenceRecv gets a channel's next receive sequence from the store func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyNextSequenceRecv(portID, channelID)) if bz == nil { return 0, false @@ -112,41 +111,68 @@ func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) ( // SetNextSequenceRecv sets a channel's next receive sequence to the store func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := sdk.Uint64ToBigEndian(sequence) store.Set(types.KeyNextSequenceRecv(portID, channelID), bz) } // GetPacketCommitment gets the packet commitment hash from the store func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyPacketCommitment(portID, channelID, sequence)) return bz } // SetPacketCommitment sets the packet commitment hash to the store func (k Keeper) SetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64, commitmentHash []byte) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) store.Set(types.KeyPacketCommitment(portID, channelID, sequence), commitmentHash) } func (k Keeper) deletePacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) store.Delete(types.KeyPacketCommitment(portID, channelID, sequence)) } // SetPacketAcknowledgement sets the packet ack hash to the store func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64, ackHash []byte) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) } // GetPacketAcknowledgement gets the packet ack hash from the store func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChannel) + store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyPacketAcknowledgement(portID, channelID, sequence)) if bz == nil { return nil, false } return bz, true } + +// IterateChannels provides an iterator over all Channel objects. For each +// Channel, cb will be called. If the cb returns true, the iterator will close +// and stop. +func (k Keeper) IterateChannels(ctx sdk.Context, cb func(types.Channel) bool) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.GetChannelKeysPrefix(ibctypes.KeyChannelPrefix)) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var channel types.Channel + k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &channel) + + if cb(channel) { + break + } + } +} + +// GetAllChannels returns all stored Channel objects. +func (k Keeper) GetAllChannels(ctx sdk.Context) (channels []types.Channel) { + k.IterateChannels(ctx, func(channel types.Channel) bool { + channels = append(channels, channel) + return false + }) + return channels +} diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index fa011b3ae104..b8159d760bc4 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -21,10 +21,14 @@ const ( testClientType = clientexported.Tendermint testConnection = "testconnection" - testPort1 = "firstport" - testPort2 = "secondport" - testChannel1 = "firstchannel" - testChannel2 = "secondchannel" + + testPort1 = "firstport" + testPort2 = "secondport" + testPort3 = "thirdport" + + testChannel1 = "firstchannel" + testChannel2 = "secondchannel" + testChannel3 = "thirdchannel" testChannelOrder = types.ORDERED testChannelVersion = "1.0" @@ -63,8 +67,8 @@ func (suite *KeeperTestSuite) TestSetChannel() { State: types.OPEN, Ordering: testChannelOrder, Counterparty: types.Counterparty{ - PortID: testPort1, - ChannelID: testChannel1, + PortID: testPort2, + ChannelID: testChannel2, }, ConnectionHops: []string{testConnection}, Version: testChannelVersion, @@ -76,6 +80,47 @@ func (suite *KeeperTestSuite) TestSetChannel() { suite.Equal(channel, storedChannel) } +func (suite KeeperTestSuite) TestGetAllChannels() { + // Channel (Counterparty): A(C) -> C(B) -> B(A) + counterparty1 := types.NewCounterparty(testPort1, testChannel1) + counterparty2 := types.NewCounterparty(testPort2, testChannel2) + counterparty3 := types.NewCounterparty(testPort3, testChannel3) + + channel1 := types.Channel{ + State: types.INIT, + Ordering: testChannelOrder, + Counterparty: counterparty3, + ConnectionHops: []string{testConnection}, + Version: testChannelVersion, + } + + channel2 := types.Channel{ + State: types.INIT, + Ordering: testChannelOrder, + Counterparty: counterparty1, + ConnectionHops: []string{testConnection}, + Version: testChannelVersion, + } + + channel3 := types.Channel{ + State: types.CLOSED, + Ordering: testChannelOrder, + Counterparty: counterparty2, + ConnectionHops: []string{testConnection}, + Version: testChannelVersion, + } + + expChannels := []types.Channel{channel1, channel2, channel3} + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort1, testChannel1, expChannels[0]) + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort2, testChannel2, expChannels[1]) + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort3, testChannel3, expChannels[2]) + + channels := suite.app.IBCKeeper.ChannelKeeper.GetAllChannels(suite.ctx) + suite.Require().Len(channels, len(expChannels)) + suite.Require().Equal(expChannels, channels) +} + func (suite *KeeperTestSuite) TestSetChannelCapability() { _, found := suite.app.IBCKeeper.ChannelKeeper.GetChannelCapability(suite.ctx, testPort1, testChannel1) suite.False(found) diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go index 3bf671d1e0fb..8aef90c879ad 100644 --- a/x/ibc/04-channel/keeper/querier.go +++ b/x/ibc/04-channel/keeper/querier.go @@ -1,32 +1,57 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // QuerierChannel defines the sdk.Querier to query a module's channel -func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) { +func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryChannelParams - err := types.SubModuleCdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) if !found { - return nil, sdk.ConvertError(types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID)) + return nil, types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID) } - bz, err := types.SubModuleCdc.MarshalJSON(channel) + bz, err := codec.MarshalJSONIndent(k.cdc, channel) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } + +// QuerierChannels defines the sdk.Querier to query all the channels. +func QuerierChannels(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { + var params types.QueryAllChannelsParams + + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) + } + + channels := k.GetAllChannels(ctx) + + start, end := client.Paginate(len(channels), params.Page, params.Limit, 100) + if start < 0 || end < 0 { + channels = []types.Channel{} + } else { + channels = channels[start:end] + } + + res, err := codec.MarshalJSONIndent(k.cdc, channels) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index 06c268e3e307..a5d709662fa2 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -12,6 +12,7 @@ var SubModuleCdc *codec.Codec // IBC channel. func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*exported.PacketI)(nil), nil) + cdc.RegisterConcrete(Channel{}, "ibc/channel/Channel", nil) cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil) cdc.RegisterConcrete(OpaquePacket{}, "ibc/channel/OpaquePacket", nil) @@ -21,6 +22,8 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgChannelOpenConfirm{}, "ibc/channel/MsgChannelOpenConfirm", nil) cdc.RegisterConcrete(MsgChannelCloseInit{}, "ibc/channel/MsgChannelCloseInit", nil) cdc.RegisterConcrete(MsgChannelCloseConfirm{}, "ibc/channel/MsgChannelCloseConfirm", nil) + + SetSubModuleCodec(cdc) } func SetSubModuleCodec(cdc *codec.Codec) { diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go index 27c444959ec7..1fcbb4f44806 100644 --- a/x/ibc/04-channel/types/keys.go +++ b/x/ibc/04-channel/types/keys.go @@ -2,6 +2,8 @@ package types import ( "fmt" + + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) const ( @@ -18,73 +20,115 @@ const ( QuerierRoute = SubModuleName ) -// KVStore key prefixes -var ( - KeyPrefixChannel = []byte{} -) - // ChannelPath defines the path under which channels are stored func ChannelPath(portID, channelID string) string { - return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) + return string(KeyChannel(portID, channelID)) } // ChannelCapabilityPath defines the path under which capability keys associated // with a channel are stored func ChannelCapabilityPath(portID, channelID string) string { - return fmt.Sprintf("%s/key", ChannelPath(portID, channelID)) + return string(KeyChannelCapabilityPath(portID, channelID)) } // NextSequenceSendPath defines the next send sequence counter store path func NextSequenceSendPath(portID, channelID string) string { - return fmt.Sprintf("%s/nextSequenceSend", ChannelPath(portID, channelID)) + return string(KeyNextSequenceSend(portID, channelID)) } // NextSequenceRecvPath defines the next receive sequence counter store path func NextSequenceRecvPath(portID, channelID string) string { - return fmt.Sprintf("%s/nextSequenceRecv", ChannelPath(portID, channelID)) + return string(KeyNextSequenceRecv(portID, channelID)) } // PacketCommitmentPath defines the commitments to packet data fields store path func PacketCommitmentPath(portID, channelID string, sequence uint64) string { - return fmt.Sprintf("%s/packets/%d", ChannelPath(portID, channelID), sequence) + return string(KeyPacketCommitment(portID, channelID, sequence)) } // PacketAcknowledgementPath defines the packet acknowledgement store path func PacketAcknowledgementPath(portID, channelID string, sequence uint64) string { - return fmt.Sprintf("%s/acknowledgements/%d", ChannelPath(portID, channelID), sequence) + return string(KeyPacketAcknowledgement(portID, channelID, sequence)) } // KeyChannel returns the store key for a particular channel func KeyChannel(portID, channelID string) []byte { - return []byte(ChannelPath(portID, channelID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyChannelPrefix), + []byte(channelPath(portID, channelID))..., + ) } // KeyChannelCapabilityPath returns the store key for the capability key of a // particular channel binded to a specific port func KeyChannelCapabilityPath(portID, channelID string) []byte { - return []byte(ChannelCapabilityPath(portID, channelID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyChannelCapabilityPrefix), + []byte(channelCapabilityPath(portID, channelID))..., + ) } // KeyNextSequenceSend returns the store key for the send sequence of a particular // channel binded to a specific port func KeyNextSequenceSend(portID, channelID string) []byte { - return []byte(NextSequenceSendPath(portID, channelID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyNextSeqSendPrefix), + []byte(nextSequenceSendPath(portID, channelID))..., + ) } // KeyNextSequenceRecv returns the store key for the receive sequence of a particular // channel binded to a specific port func KeyNextSequenceRecv(portID, channelID string) []byte { - return []byte(NextSequenceRecvPath(portID, channelID)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyNextSeqRecvPrefix), + []byte(nextSequenceRecvPath(portID, channelID))..., + ) } // KeyPacketCommitment returns the store key of under which a packet commitment // is stored func KeyPacketCommitment(portID, channelID string, sequence uint64) []byte { - return []byte(PacketCommitmentPath(portID, channelID, sequence)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyPacketCommitmentPrefix), + []byte(packetCommitmentPath(portID, channelID, sequence))..., + ) } // KeyPacketAcknowledgement returns the store key of under which a packet // acknowledgement is stored func KeyPacketAcknowledgement(portID, channelID string, sequence uint64) []byte { - return []byte(PacketAcknowledgementPath(portID, channelID, sequence)) + return append( + ibctypes.KeyPrefixBytes(ibctypes.KeyPacketAckPrefix), + []byte(packetAcknowledgementPath(portID, channelID, sequence))..., + ) +} + +// GetChannelKeysPrefix returns the prefix bytes for ICS04 iterators +func GetChannelKeysPrefix(prefix int) []byte { + return []byte(fmt.Sprintf("%d/ports/", prefix)) +} + +func channelPath(portID, channelID string) string { + return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) +} + +func channelCapabilityPath(portID, channelID string) string { + return channelPath(portID, channelID) + "/key" +} + +func nextSequenceSendPath(portID, channelID string) string { + return channelPath(portID, channelID) + "/nextSequenceSend" +} + +func nextSequenceRecvPath(portID, channelID string) string { + return channelPath(portID, channelID) + "/nextSequenceRecv" +} + +func packetCommitmentPath(portID, channelID string, sequence uint64) string { + return channelPath(portID, channelID) + fmt.Sprintf("/packets/%d", sequence) +} + +func packetAcknowledgementPath(portID, channelID string, sequence uint64) string { + return channelPath(portID, channelID) + fmt.Sprintf("/acknowledgements/%d", sequence) } diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go index 9594f56473ef..e010c6991d88 100644 --- a/x/ibc/04-channel/types/querier.go +++ b/x/ibc/04-channel/types/querier.go @@ -10,7 +10,8 @@ import ( // query routes supported by the IBC channel Querier const ( - QueryChannel = "channel" + QueryAllChannels = "channels" + QueryChannel = "channel" ) // ChannelResponse defines the client query response for a channel which also @@ -49,6 +50,21 @@ func NewQueryChannelParams(portID, channelID string) QueryChannelParams { } } +// QueryAllChannelsParams defines the parameters necessary for querying for all +// channels. +type QueryAllChannelsParams struct { + Page int `json:"page" yaml:"page"` + Limit int `json:"limit" yaml:"limit"` +} + +// NewQueryAllChannelsParams creates a new QueryAllChannelsParams instance. +func NewQueryAllChannelsParams(page, limit int) QueryAllChannelsParams { + return QueryAllChannelsParams{ + Page: page, + Limit: limit, + } +} + // PacketResponse defines the client query response for a packet which also // includes a proof, its path and the height form which the proof was retrieved type PacketResponse struct { diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 2b07fbe5151a..46ef6f08558b 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -141,10 +141,10 @@ func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connI suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) } -func (suite *HandlerTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { +func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { res := suite.app.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: []byte(key), + Data: key, Prove: true, }) @@ -197,7 +197,7 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { packetDataBz := []byte("invaliddata") packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - packetCommitmentPath := channel.PacketCommitmentPath(testPort2, testChannel2, packetSeq) + packetCommitmentPath := channel.KeyPacketCommitment(testPort2, testChannel2, packetSeq) suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) suite.updateClient() diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index c28b4cc9db00..79b84c13716a 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -82,10 +82,10 @@ func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) } -func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { +func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { res := suite.app.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: []byte(key), + Data: key, Prove: true, }) @@ -197,7 +197,7 @@ func (suite *KeeperTestSuite) TestReceivePacket() { packetDataBz := []byte("invaliddata") packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort2, testChannel1, packetDataBz) - packetCommitmentPath := channel.PacketCommitmentPath(testPort2, testChannel2, packetSeq) + packetCommitmentPath := channel.KeyPacketCommitment(testPort2, testChannel2, packetSeq) suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) suite.updateClient() diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index ee934fabd018..02b468cdb031 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -1,11 +1,10 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -13,37 +12,50 @@ import ( // NewQuerier creates a querier for the IBC module func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + var ( + res []byte + err error + ) + switch path[0] { case client.SubModuleName: switch path[1] { case client.QueryClientState: - return client.QuerierClientState(ctx, req, k.ClientKeeper) + res, err = client.QuerierClientState(ctx, req, k.ClientKeeper) + case client.QueryAllClients: + res, err = client.QuerierClients(ctx, req, k.ClientKeeper) case client.QueryConsensusState: - return client.QuerierConsensusState(ctx, req, k.ClientKeeper) + res, err = client.QuerierConsensusState(ctx, req, k.ClientKeeper) case client.QueryVerifiedRoot: - return client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) + res, err = client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName)) + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", client.SubModuleName) } case connection.SubModuleName: switch path[1] { case connection.QueryConnection: - return connection.QuerierConnection(ctx, req, k.ConnectionKeeper) + res, err = connection.QuerierConnection(ctx, req, k.ConnectionKeeper) + case connection.QueryAllConnections: + res, err = connection.QuerierConnections(ctx, req, k.ConnectionKeeper) case connection.QueryClientConnections: - return connection.QuerierClientConnections(ctx, req, k.ConnectionKeeper) + res, err = connection.QuerierClientConnections(ctx, req, k.ConnectionKeeper) default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName)) + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", connection.SubModuleName) } case channel.SubModuleName: switch path[1] { case channel.QueryChannel: - return channel.QuerierChannel(ctx, req, k.ChannelKeeper) + res, err = channel.QuerierChannel(ctx, req, k.ChannelKeeper) + case channel.QueryAllChannels: + res, err = channel.QuerierChannels(ctx, req, k.ChannelKeeper) default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown IBC %s query endpoint", channel.SubModuleName)) + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", channel.SubModuleName) } default: - return nil, sdk.ErrUnknownRequest("unknown IBC query endpoint") + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC query endpoint") } + + return res, sdk.ConvertError(err) } } diff --git a/x/ibc/keeper/querier_test.go b/x/ibc/keeper/querier_test.go index 81abe9ffadb1..f15920608b6c 100644 --- a/x/ibc/keeper/querier_test.go +++ b/x/ibc/keeper/querier_test.go @@ -27,19 +27,24 @@ func (suite *KeeperTestSuite) TestNewQuerier() { expectsDefaultErr bool errMsg string }{ - {"client - QueryClientState", + {"client - QuerierClientState", []string{client.SubModuleName, client.QueryClientState}, false, "", }, + {"client - QuerierClients", + []string{client.SubModuleName, client.QueryAllClients}, + false, + "", + }, { - "client - QueryConsensusState", + "client - QuerierConsensusState", []string{client.SubModuleName, client.QueryConsensusState}, false, "", }, { - "client - QueryVerifiedRoot", + "client - QuerierVerifiedRoot", []string{client.SubModuleName, client.QueryVerifiedRoot}, false, "", @@ -51,13 +56,19 @@ func (suite *KeeperTestSuite) TestNewQuerier() { fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName), }, { - "connection - QueryConnection", + "connection - QuerierConnection", []string{connection.SubModuleName, connection.QueryConnection}, false, "", }, { - "connection - QueryClientConnections", + "connection - QuerierConnections", + []string{connection.SubModuleName, connection.QueryAllConnections}, + false, + "", + }, + { + "connection - QuerierClientConnections", []string{connection.SubModuleName, connection.QueryClientConnections}, false, "", @@ -69,11 +80,17 @@ func (suite *KeeperTestSuite) TestNewQuerier() { fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName), }, { - "channel - QueryChannel", + "channel - QuerierChannel", []string{channel.SubModuleName, channel.QueryChannel}, false, "", }, + { + "channel - QuerierChannels", + []string{channel.SubModuleName, channel.QueryAllChannels}, + false, + "", + }, { "channel - invalid query", []string{channel.SubModuleName, "foo"}, diff --git a/x/ibc/types/keys.go b/x/ibc/types/keys.go new file mode 100644 index 000000000000..f4f39edcd495 --- /dev/null +++ b/x/ibc/types/keys.go @@ -0,0 +1,40 @@ +package types + +import "fmt" + +const ( + // ModuleName is the name of the IBC module + ModuleName = "ibc" + + // StoreKey is the string store representation + StoreKey string = ModuleName + + // QuerierRoute is the querier route for the IBC module + QuerierRoute string = ModuleName + + // RouterKey is the msg router key for the IBC module + RouterKey string = ModuleName +) + +// KVStore key prefixes for IBC +const ( + KeyClientPrefix int = iota + 1 + KeyClientTypePrefix + KeyConsensusStatePrefix + KeyRootPrefix + KeyCommiterPrefix + KeyClientConnectionsPrefix + KeyConnectionPrefix + KeyChannelPrefix + KeyChannelCapabilityPrefix + KeyNextSeqSendPrefix + KeyNextSeqRecvPrefix + KeyPacketCommitmentPrefix + KeyPacketAckPrefix + KeyPortsPrefix +) + +// KeyPrefixBytes return the key prefix bytes from a URL string format +func KeyPrefixBytes(prefix int) []byte { + return []byte(fmt.Sprintf("%d/", prefix)) +} diff --git a/x/ibc/types/types.go b/x/ibc/types/types.go deleted file mode 100644 index 6722e5f3a426..000000000000 --- a/x/ibc/types/types.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -const ( - // ModuleName is the name of the IBC module - ModuleName = "ibc" - - // StoreKey is the string store representation - StoreKey string = ModuleName - - // QuerierRoute is the querier route for the IBC module - QuerierRoute string = ModuleName - - // RouterKey is the msg router key for the IBC module - RouterKey string = ModuleName -) From 300892a5790a3e55cc311bd5b957fd38da166761 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Wed, 18 Dec 2019 18:04:20 -0300 Subject: [PATCH 056/176] fix ICS02 queries (#5425) --- x/ibc/02-client/client/cli/query.go | 2 +- x/ibc/02-client/client/rest/query.go | 2 +- x/ibc/02-client/client/utils/utils.go | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index a64405b62993..682758783292 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -102,7 +102,7 @@ func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Comma prove := viper.GetBool(flags.FlagProve) - csRes, err := utils.QueryConsensusStateProof(cliCtx, clientID, prove) + csRes, err := utils.QueryConsensusState(cliCtx, clientID, prove) if err != nil { return err } diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go index d831aa396719..3b59aeb49f85 100644 --- a/x/ibc/02-client/client/rest/query.go +++ b/x/ibc/02-client/client/rest/query.go @@ -113,7 +113,7 @@ func queryConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - csRes, err := utils.QueryConsensusStateProof(cliCtx, clientID, prove) + csRes, err := utils.QueryConsensusState(cliCtx, clientID, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 30f56e57a9db..848d489b2308 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -53,7 +53,7 @@ func QueryClientState( } var clientState types.State - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &clientState); err != nil { + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &clientState); err != nil { return types.StateResponse{}, err } @@ -64,7 +64,7 @@ func QueryClientState( // QueryConsensusStateProof queries the store to get the consensus state and a // merkle proof. -func QueryConsensusStateProof( +func QueryConsensusState( cliCtx client.CLIContext, clientID string, prove bool) (types.ConsensusStateResponse, error) { var conStateRes types.ConsensusStateResponse @@ -80,7 +80,7 @@ func QueryConsensusStateProof( } var cs tendermint.ConsensusState - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &cs); err != nil { + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { return conStateRes, err } @@ -104,7 +104,7 @@ func QueryCommitmentRoot( } var root commitment.Root - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &root); err != nil { + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &root); err != nil { return types.RootResponse{}, err } @@ -129,7 +129,7 @@ func QueryCommitter( } var committer tendermint.Committer - if err := cliCtx.Codec.UnmarshalJSON(res.Value, &committer); err != nil { + if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &committer); err != nil { return types.CommitterResponse{}, err } From 3ecb819c66aa8081e230faffaba70ff080fb9cfa Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Thu, 2 Jan 2020 10:18:12 -0300 Subject: [PATCH 057/176] fix CLI JSON param unmarshaling (#5431) --- x/ibc/02-client/client/cli/tx.go | 22 +++--- x/ibc/03-connection/client/cli/tx.go | 75 +++++---------------- x/ibc/03-connection/client/utils/utils.go | 39 +++++++++++ x/ibc/04-channel/client/cli/tx.go | 81 ++++++----------------- 4 files changed, 88 insertions(+), 129 deletions(-) diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 9e666f8f926b..6081ddcdddfe 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -7,6 +7,8 @@ import ( "os" "strings" + "github.com/pkg/errors" + "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client/context" @@ -43,14 +45,13 @@ $ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node var state exported.ConsensusState if err := cdc.UnmarshalJSON([]byte(args[1]), &state); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - + // check for file path if JSON input is not provided contents, err := ioutil.ReadFile(args[1]) if err != nil { - return fmt.Errorf("error opening proof file: %v", err) + return errors.New("neither JSON input nor path to .json file were provided") } if err := cdc.UnmarshalJSON(contents, &state); err != nil { - return fmt.Errorf("error unmarshalling consensus state file: %v", err) + return errors.Wrap(err, "error unmarshalling consensus state file") } } @@ -91,14 +92,13 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home var header exported.Header if err := cdc.UnmarshalJSON([]byte(args[1]), &header); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - + // check for file path if JSON input is not provided contents, err := ioutil.ReadFile(args[1]) if err != nil { - return fmt.Errorf("error opening proof file: %v", err) + return errors.New("neither JSON input nor path to .json file were provided") } if err := cdc.UnmarshalJSON(contents, &header); err != nil { - return fmt.Errorf("error unmarshalling header file: %v", err) + return errors.Wrap(err, "error unmarshalling header file") } } @@ -137,13 +137,13 @@ $ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 var evidence evidenceexported.Evidence if err := cdc.UnmarshalJSON([]byte(args[1]), &evidence); err != nil { fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - + // check for file path if JSON input is not provided contents, err := ioutil.ReadFile(args[1]) if err != nil { - return fmt.Errorf("error opening proof file: %v", err) + return errors.New("neither JSON input nor path to .json file were provided") } if err := cdc.UnmarshalJSON(contents, &evidence); err != nil { - return fmt.Errorf("error unmarshalling evidence file: %v", err) + return errors.Wrap(err, "error unmarshalling evidence file") } } diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 9693a62b96ea..cf54b6e785ff 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -3,12 +3,8 @@ package cli import ( "bufio" "fmt" - "io/ioutil" - "os" "strings" - "github.com/pkg/errors" - "github.com/spf13/cobra" "github.com/spf13/viper" @@ -18,9 +14,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // Connection Handshake flags @@ -50,7 +46,7 @@ $ %s tx ibc connection open-init [connection-id] [client-id] \ Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] @@ -58,16 +54,11 @@ $ %s tx ibc connection open-init [connection-id] [client-id] \ counterpartyConnectionID := args[2] counterpartyClientID := args[3] - bz, err := ioutil.ReadFile(args[4]) + counterpartyPrefix, err := utils.ParsePrefix(cliCtx.Codec, args[4]) if err != nil { return err } - var counterpartyPrefix commitment.Prefix - if err := cdc.UnmarshalJSON(bz, &counterpartyPrefix); err != nil { - return err - } - msg := types.NewMsgConnectionOpenInit( connectionID, clientID, counterpartyConnectionID, counterpartyClientID, counterpartyPrefix, cliCtx.GetFromAddress(), @@ -77,7 +68,7 @@ $ %s tx ibc connection open-init [connection-id] [client-id] \ return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -103,7 +94,7 @@ $ %s tx ibc connection open-try connection-id] [client-id] \ Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) @@ -113,29 +104,19 @@ $ %s tx ibc connection open-try connection-id] [client-id] \ counterpartyConnectionID := args[2] counterpartyClientID := args[3] - prefixBz, err := ioutil.ReadFile(args[4]) + counterpartyPrefix, err := utils.ParsePrefix(cliCtx.Codec, args[4]) if err != nil { return err } - var counterpartyPrefix commitment.Prefix - if err := cdc.UnmarshalJSON(prefixBz, &counterpartyPrefix); err != nil { - return err - } - // TODO: parse strings? counterpartyVersions := args[5] - proofBz, err := ioutil.ReadFile(args[6]) + proofInit, err := utils.ParseProof(cliCtx.Codec, args[1]) if err != nil { return err } - var proofInit commitment.Proof - if err := cdc.UnmarshalJSON(proofBz, &proofInit); err != nil { - return err - } - proofHeight := uint64(cliCtx.Height) consensusHeight, err := lastHeight(cliCtx) if err != nil { @@ -152,7 +133,7 @@ $ %s tx ibc connection open-try connection-id] [client-id] \ return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -174,17 +155,13 @@ $ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [versio Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] - proofBz, err := ioutil.ReadFile(args[1]) - if err != nil { - return err - } - var proofTry commitment.Proof - if err := cdc.UnmarshalJSON(proofBz, &proofTry); err != nil { + proofTry, err := utils.ParseProof(cliCtx.Codec, args[1]) + if err != nil { return err } @@ -205,7 +182,7 @@ $ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [versio return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -227,23 +204,18 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) connectionID := args[0] - proofBz, err := ioutil.ReadFile(args[1]) + proofAck, err := utils.ParseProof(cliCtx.Codec, args[1]) if err != nil { return err } - var proofAck commitment.Proof - if err := cdc.UnmarshalJSON(proofBz, &proofAck); err != nil { - return err - } - proofHeight := uint64(cliCtx.Height) msg := types.NewMsgConnectionOpenConfirm( @@ -254,7 +226,7 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -274,18 +246,3 @@ func lastHeight(cliCtx context.CLIContext) (uint64, error) { return uint64(info.Response.LastBlockHeight), nil } - -func parsePath(cdc *codec.Codec, arg string) (commitment.Prefix, error) { - var path commitment.Prefix - if err := cdc.UnmarshalJSON([]byte(arg), &path); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(arg) - if err != nil { - return path, errors.Wrap(err, "error opening path file") - } - if err := cdc.UnmarshalJSON(contents, &path); err != nil { - return path, errors.Wrap(err, "error unmarshalling path file") - } - } - return path, nil -} diff --git a/x/ibc/03-connection/client/utils/utils.go b/x/ibc/03-connection/client/utils/utils.go index 0f54e9e3b5cc..55dcdcbff49e 100644 --- a/x/ibc/03-connection/client/utils/utils.go +++ b/x/ibc/03-connection/client/utils/utils.go @@ -2,11 +2,16 @@ package utils import ( "fmt" + "io/ioutil" + + "github.com/pkg/errors" abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // QueryAllConnections returns all the connections. It _does not_ return @@ -82,3 +87,37 @@ func QueryClientConnections( connPathsRes := types.NewClientConnectionsResponse(clientID, paths, res.Proof, res.Height) return connPathsRes, nil } + +// ParsePrefix unmarshals an cmd input argument from a JSON string to a commitment +// Prefix. If the input is not a JSON, it looks for a path to the JSON file. +func ParsePrefix(cdc *codec.Codec, arg string) (commitment.Prefix, error) { + var prefix commitment.Prefix + if err := cdc.UnmarshalJSON([]byte(arg), &prefix); err != nil { + // check for file path if JSON input is not provided + contents, err := ioutil.ReadFile(arg) + if err != nil { + return commitment.Prefix{}, errors.New("neither JSON input nor path to .json file were provided") + } + if err := cdc.UnmarshalJSON(contents, &prefix); err != nil { + return commitment.Prefix{}, errors.Wrap(err, "error unmarshalling commitment prefix") + } + } + return prefix, nil +} + +// ParseProof unmarshals an cmd input argument from a JSON string to a commitment +// Proof. If the input is not a JSON, it looks for a path to the JSON file. +func ParseProof(cdc *codec.Codec, arg string) (commitment.Proof, error) { + var proof commitment.Proof + if err := cdc.UnmarshalJSON([]byte(arg), &proof); err != nil { + // check for file path if JSON input is not provided + contents, err := ioutil.ReadFile(arg) + if err != nil { + return commitment.Proof{}, errors.New("neither JSON input nor path to .json file were provided") + } + if err := cdc.UnmarshalJSON(contents, &proof); err != nil { + return commitment.Proof{}, errors.Wrap(err, "error unmarshalling commitment proof") + } + } + return proof, nil +} diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index 58bb189e2c4a..df0c53cddf82 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -2,9 +2,6 @@ package cli import ( "bufio" - "fmt" - "io/ioutil" - "os" "strconv" "strings" @@ -16,22 +13,16 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + connectionutils "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// IBC Channel flags const ( FlagOrdered = "ordered" FlagIBCVersion = "ibc-version" - FlagNode1 = "node1" - FlagNode2 = "node2" - FlagFrom1 = "from1" - FlagFrom2 = "from2" - FlagChainID2 = "chain-id2" ) -// TODO: module needs to pass the capability key (i.e store key) - // GetMsgChannelOpenInitCmd returns the command to create a MsgChannelOpenInit transaction func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -72,7 +63,7 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command // GetMsgChannelOpenTryCmd returns the command to create a MsgChannelOpenTry transaction func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "open-try [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof-init.json] [proof-height]", + Use: "open-try [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof_init.json] [proof-height]", Short: "Creates and sends a ChannelOpenTry message", Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { @@ -88,16 +79,9 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { order := channelOrder() version := viper.GetString(FlagIBCVersion) // TODO: diferenciate between channel and counterparty versions - var proof commitment.ProofI - if err := cdc.UnmarshalJSON([]byte(args[5]), &proof); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(args[5]) - if err != nil { - return fmt.Errorf("error opening proof file: %v", err) - } - if err := cdc.UnmarshalJSON(contents, &proof); err != nil { - return fmt.Errorf("error unmarshalling proof file: %v", err) - } + proofInit, err := connectionutils.ParseProof(cliCtx.Codec, args[5]) + if err != nil { + return err } proofHeight, err := strconv.ParseInt(args[6], 10, 64) @@ -108,7 +92,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { msg := types.NewMsgChannelOpenTry( portID, channelID, version, order, hops, counterpartyPortID, counterpartyChannelID, version, - proof, uint64(proofHeight), cliCtx.GetFromAddress(), + proofInit, uint64(proofHeight), cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err @@ -126,7 +110,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { // GetMsgChannelOpenAckCmd returns the command to create a MsgChannelOpenAck transaction func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "open-ack [port-id] [channel-id] [/path/to/proof-try.json] [proof-height]", + Use: "open-ack [port-id] [channel-id] [/path/to/proof_try.json] [proof-height]", Short: "Creates and sends a ChannelOpenAck message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { @@ -138,16 +122,9 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { channelID := args[1] version := viper.GetString(FlagIBCVersion) // TODO: diferenciate between channel and counterparty versions - var proof commitment.ProofI - if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(args[2]) - if err != nil { - return fmt.Errorf("error opening proof file: %v", err) - } - if err := cdc.UnmarshalJSON(contents, &proof); err != nil { - return fmt.Errorf("error unmarshalling proof file: %v", err) - } + proofTry, err := connectionutils.ParseProof(cliCtx.Codec, args[5]) + if err != nil { + return err } proofHeight, err := strconv.ParseInt(args[3], 10, 64) @@ -156,7 +133,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { } msg := types.NewMsgChannelOpenAck( - portID, channelID, version, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + portID, channelID, version, proofTry, uint64(proofHeight), cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err @@ -172,7 +149,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { // GetMsgChannelOpenConfirmCmd returns the command to create a MsgChannelOpenConfirm transaction func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return &cobra.Command{ - Use: "open-confirm [port-id] [channel-id] [/path/to/proof-ack.json] [proof-height]", + Use: "open-confirm [port-id] [channel-id] [/path/to/proof_ack.json] [proof-height]", Short: "Creates and sends a ChannelOpenConfirm message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { @@ -183,16 +160,9 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma portID := args[0] channelID := args[1] - var proof commitment.ProofI - if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(args[2]) - if err != nil { - return fmt.Errorf("error opening proof file: %v", err) - } - if err := cdc.UnmarshalJSON(contents, &proof); err != nil { - return fmt.Errorf("error unmarshalling proof file: %v", err) - } + proofAck, err := connectionutils.ParseProof(cliCtx.Codec, args[5]) + if err != nil { + return err } proofHeight, err := strconv.ParseInt(args[3], 10, 64) @@ -201,7 +171,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma } msg := types.NewMsgChannelOpenConfirm( - portID, channelID, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + portID, channelID, proofAck, uint64(proofHeight), cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err @@ -239,7 +209,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command // GetMsgChannelCloseConfirmCmd returns the command to create a MsgChannelCloseConfirm transaction func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return &cobra.Command{ - Use: "close-confirm [port-id] [channel-id] [/path/to/proof-init.json] [proof-height]", + Use: "close-confirm [port-id] [channel-id] [/path/to/proof_init.json] [proof-height]", Short: "Creates and sends a ChannelCloseConfirm message", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { @@ -250,16 +220,9 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm portID := args[0] channelID := args[1] - var proof commitment.ProofI - if err := cdc.UnmarshalJSON([]byte(args[2]), &proof); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") - contents, err := ioutil.ReadFile(args[2]) - if err != nil { - return fmt.Errorf("error opening proof file: %v", err) - } - if err := cdc.UnmarshalJSON(contents, &proof); err != nil { - return fmt.Errorf("error unmarshalling proof file: %v", err) - } + proofInit, err := connectionutils.ParseProof(cliCtx.Codec, args[5]) + if err != nil { + return err } proofHeight, err := strconv.ParseInt(args[3], 10, 64) @@ -268,7 +231,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm } msg := types.NewMsgChannelCloseConfirm( - portID, channelID, proof, uint64(proofHeight), cliCtx.GetFromAddress(), + portID, channelID, proofInit, uint64(proofHeight), cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err From 045b021b73edfca6ff63e24dc1982f3c327cc27f Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Thu, 2 Jan 2020 11:36:36 -0300 Subject: [PATCH 058/176] Fix inconsistent string lookup functions (#5437) * fix inconsistent string lookup functions * test client type and ordering * channel and connection state tests * address golangcibot comments * fix test --- x/ibc/02-client/exported/exported.go | 14 +-- x/ibc/02-client/exported/exported_test.go | 49 +++++++++++ x/ibc/02-client/handler.go | 10 ++- x/ibc/02-client/types/msgs.go | 8 +- x/ibc/03-connection/alias.go | 4 +- x/ibc/03-connection/keeper/handshake.go | 2 +- x/ibc/03-connection/keeper/handshake_test.go | 2 +- x/ibc/03-connection/keeper/keeper_test.go | 2 +- x/ibc/03-connection/types/connection.go | 34 +++----- x/ibc/03-connection/types/connection_test.go | 46 ++++++++++ x/ibc/04-channel/alias.go | 9 +- x/ibc/04-channel/keeper/handshake.go | 8 +- x/ibc/04-channel/keeper/handshake_test.go | 22 ++--- x/ibc/04-channel/keeper/packet.go | 2 +- x/ibc/04-channel/types/channel.go | 73 +++++++--------- x/ibc/04-channel/types/channel_test.go | 91 ++++++++++++++++++++ 16 files changed, 276 insertions(+), 100 deletions(-) create mode 100644 x/ibc/02-client/exported/exported_test.go create mode 100644 x/ibc/03-connection/types/connection_test.go create mode 100644 x/ibc/04-channel/types/channel_test.go diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index 9a5f2bc2e89f..50632bf71ca8 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -82,23 +82,23 @@ func (ct *ClientType) UnmarshalJSON(data []byte) error { return err } - bz2, err := ClientTypeFromString(s) - if err != nil { - return err + clientType := ClientTypeFromString(s) + if clientType == 0 { + return fmt.Errorf("invalid client type '%s'", s) } - *ct = bz2 + *ct = clientType return nil } // ClientTypeFromString returns a byte that corresponds to the registered client // type. It returns 0 if the type is not found/registered. -func ClientTypeFromString(clientType string) (ClientType, error) { +func ClientTypeFromString(clientType string) ClientType { switch clientType { case ClientTypeTendermint: - return Tendermint, nil + return Tendermint default: - return 0, fmt.Errorf("'%s' is not a valid client type", clientType) + return 0 } } diff --git a/x/ibc/02-client/exported/exported_test.go b/x/ibc/02-client/exported/exported_test.go new file mode 100644 index 000000000000..f0eb1fc4d182 --- /dev/null +++ b/x/ibc/02-client/exported/exported_test.go @@ -0,0 +1,49 @@ +package exported + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestClientTypeString(t *testing.T) { + cases := []struct { + msg string + name string + clientType ClientType + }{ + {"tendermint client", ClientTypeTendermint, Tendermint}, + {"empty type", "", 0}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.clientType, ClientTypeFromString(tt.name), tt.msg) + require.Equal(t, tt.name, tt.clientType.String(), tt.msg) + } +} + +func TestClientTypeMarshalJSON(t *testing.T) { + cases := []struct { + msg string + name string + clientType ClientType + expectPass bool + }{ + {"tendermint client should have passed", ClientTypeTendermint, Tendermint, true}, + {"empty type should have failed", "", 0, false}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.clientType.MarshalJSON() + require.NoError(t, err) + var ct ClientType + if tt.expectPass { + require.NoError(t, ct.UnmarshalJSON(bz), tt.msg) + require.Equal(t, tt.name, ct.String(), tt.msg) + } else { + require.Error(t, ct.UnmarshalJSON(bz), tt.msg) + } + } +} diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index 595656a86c20..7363053f2319 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -12,12 +12,14 @@ import ( // HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.Result { - clientType, err := exported.ClientTypeFromString(msg.ClientType) - if err != nil { - return sdk.ResultFromError(ErrInvalidClientType(DefaultCodespace, err.Error())) + clientType := exported.ClientTypeFromString(msg.ClientType) + if clientType == 0 { + return sdk.ResultFromError( + ErrInvalidClientType(DefaultCodespace, fmt.Sprintf("invalid client type '%s'", msg.ClientType)), + ) } - _, err = k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) + _, err := k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) if err != nil { return sdk.ResultFromError(err) } diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index 039f9d04d879..d52c0a614a44 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -1,6 +1,8 @@ package types import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" @@ -51,8 +53,10 @@ func (msg MsgCreateClient) ValidateBasic() sdk.Error { if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { return sdk.ConvertError(err) } - if _, err := exported.ClientTypeFromString(msg.ClientType); err != nil { - return sdk.ConvertError(errors.ErrInvalidClientType(errors.DefaultCodespace, err.Error())) + if clientType := exported.ClientTypeFromString(msg.ClientType); clientType == 0 { + return sdk.ConvertError( + errors.ErrInvalidClientType(errors.DefaultCodespace, fmt.Sprintf("invalid client type '%s'", msg.ClientType)), + ) } if msg.ConsensusState == nil { return sdk.ConvertError(errors.ErrInvalidConsensus(errors.DefaultCodespace)) diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index 67367f45b6cb..4d44e18048e8 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -12,11 +12,11 @@ import ( ) const ( - NONE = types.NONE + UNINITIALIZED = types.UNINITIALIZED INIT = types.INIT TRYOPEN = types.TRYOPEN OPEN = types.OPEN - StateNone = types.StateNone + StateUninitialized = types.StateUninitialized StateInit = types.StateInit StateTryOpen = types.StateTryOpen StateOpen = types.StateOpen diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index 8e8dcbb96090..e5a011a84b3a 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -78,7 +78,7 @@ func (k Keeper) ConnOpenTry( version := types.PickVersion(counterpartyVersions, types.GetCompatibleVersions()) // connection defines chain B's ConnectionEnd - connection := types.NewConnectionEnd(types.NONE, clientID, counterparty, []string{version}) + connection := types.NewConnectionEnd(types.UNINITIALIZED, clientID, counterparty, []string{version}) expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) if err != nil { return err diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index ba42ba25ee27..52c53df884d5 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -132,7 +132,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { } invalidConnectionState := func() error { - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.NONE) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.UNINITIALIZED) //suite.updateClient(testClientID2) proofTry, proofHeight := suite.queryProof(connectionKey) diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index a4872d114363..8b3fb7f78cce 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -105,7 +105,7 @@ func (suite KeeperTestSuite) TestGetAllConnections() { } conn3 := types.ConnectionEnd{ - State: types.NONE, + State: types.UNINITIALIZED, ClientID: testClientID3, Counterparty: counterparty2, Versions: types.GetCompatibleVersions(), diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 8abbda60a313..65806e9f5a9a 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -2,7 +2,6 @@ package types import ( "encoding/json" - "fmt" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -72,7 +71,7 @@ type State byte // available connection states const ( - NONE State = iota // default State + UNINITIALIZED State = iota // default State INIT TRYOPEN OPEN @@ -80,17 +79,15 @@ const ( // string representation of the connection states const ( - StateNone string = "NONE" - StateInit string = "INIT" - StateTryOpen string = "TRYOPEN" - StateOpen string = "OPEN" + StateUninitialized string = "UNINITIALIZED" + StateInit string = "INIT" + StateTryOpen string = "TRYOPEN" + StateOpen string = "OPEN" ) // String implements the Stringer interface func (cs State) String() string { switch cs { - case NONE: - return StateNone case INIT: return StateInit case TRYOPEN: @@ -98,23 +95,21 @@ func (cs State) String() string { case OPEN: return StateOpen default: - return "" + return StateUninitialized } } // StateFromString parses a string into a connection state -func StateFromString(state string) (State, error) { +func StateFromString(state string) State { switch state { - case StateNone: - return NONE, nil case StateInit: - return INIT, nil + return INIT case StateTryOpen: - return TRYOPEN, nil + return TRYOPEN case StateOpen: - return OPEN, nil + return OPEN default: - return NONE, fmt.Errorf("'%s' is not a valid connection state", state) + return UNINITIALIZED } } @@ -131,11 +126,6 @@ func (cs *State) UnmarshalJSON(data []byte) error { return err } - bz2, err := StateFromString(s) - if err != nil { - return err - } - - *cs = bz2 + *cs = StateFromString(s) return nil } diff --git a/x/ibc/03-connection/types/connection_test.go b/x/ibc/03-connection/types/connection_test.go new file mode 100644 index 000000000000..7202b6f72a0b --- /dev/null +++ b/x/ibc/03-connection/types/connection_test.go @@ -0,0 +1,46 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestConnectionStateString(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.state, StateFromString(tt.name)) + require.Equal(t, tt.name, tt.state.String()) + } +} + +func TestConnectionlStateMarshalJSON(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.state.MarshalJSON() + require.NoError(t, err) + var state State + require.NoError(t, state.UnmarshalJSON(bz)) + require.Equal(t, tt.name, state.String()) + } +} diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index d5494175505a..f2d6a7f49d24 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -12,7 +12,7 @@ import ( ) const ( - NONE = types.NONE + UNINITIALIZED = types.UNINITIALIZED UNORDERED = types.UNORDERED ORDERED = types.ORDERED OrderNone = types.OrderNone @@ -20,12 +20,13 @@ const ( OrderOrdered = types.OrderOrdered CLOSED = types.CLOSED INIT = types.INIT - OPENTRY = types.OPENTRY + TRYOPEN = types.TRYOPEN OPEN = types.OPEN - StateClosed = types.StateClosed + StateUninitialized = types.StateUninitialized StateInit = types.StateInit - StateOpenTry = types.StateOpenTry + StateTryOpen = types.StateTryOpen StateOpen = types.StateOpen + StateClosed = types.StateClosed DefaultCodespace = types.DefaultCodespace CodeChannelExists = types.CodeChannelExists CodeChannelNotFound = types.CodeChannelNotFound diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index f71115da4792..5deef767e415 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -46,7 +46,7 @@ func (k Keeper) ChanOpenInit( return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) } - if connectionEnd.State == connection.NONE { + if connectionEnd.State == connection.UNINITIALIZED { return connection.ErrInvalidConnectionState( k.codespace, fmt.Sprintf("connection state cannot be NONE"), @@ -112,7 +112,7 @@ func (k Keeper) ChanOpenTry( // NOTE: this step has been switched with the one below to reverse the connection // hops - channel := types.NewChannel(types.OPENTRY, order, counterparty, connectionHops, version) + channel := types.NewChannel(types.TRYOPEN, order, counterparty, connectionHops, version) counterpartyHops, found := k.CounterpartyHops(ctx, channel) if !found { @@ -200,7 +200,7 @@ func (k Keeper) ChanOpenAck( // counterparty of the counterparty channel end (i.e self) counterparty := types.NewCounterparty(portID, channelID) expectedChannel := types.NewChannel( - types.OPENTRY, channel.Ordering, counterparty, + types.TRYOPEN, channel.Ordering, counterparty, counterpartyHops, channel.Version, ) @@ -238,7 +238,7 @@ func (k Keeper) ChanOpenConfirm( return types.ErrChannelNotFound(k.codespace, portID, channelID) } - if channel.State != types.OPENTRY { + if channel.State != types.TRYOPEN { return types.ErrInvalidChannelState( k.codespace, fmt.Sprintf("channel state is not OPENTRY (got %s)", channel.State.String()), diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 98fa69d5451e..4e39b906eb44 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -117,7 +117,7 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) suite.Error(err) // connection does not exist - suite.createConnection(connection.NONE) + suite.createConnection(connection.UNINITIALIZED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) suite.Error(err) // invalid connection state @@ -149,12 +149,12 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) suite.Error(err) // connection does not exist - suite.createConnection(connection.NONE) + suite.createConnection(connection.UNINITIALIZED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.TRYOPEN) suite.updateClient() proofInit, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) @@ -168,14 +168,14 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) suite.True(found) - suite.Equal(types.OPENTRY.String(), channel.State.String(), "invalid channel state") + suite.Equal(types.TRYOPEN.String(), channel.State.String(), "invalid channel state") } func (suite *KeeperTestSuite) TestChanOpenAck() { suite.bindPort(testPort1) channelKey := types.KeyChannel(testPort2, testChannel2) - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.TRYOPEN) suite.updateClient() proofTry, proofHeight := suite.queryProof(channelKey) err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) @@ -193,7 +193,7 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) suite.Error(err) // connection does not exist - suite.createConnection(connection.NONE) + suite.createConnection(connection.UNINITIALIZED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) suite.Error(err) // invalid connection state @@ -204,7 +204,7 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) suite.Error(err) // channel membership verification failed due to invalid counterparty - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.TRYOPEN) suite.updateClient() proofTry, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) @@ -229,20 +229,20 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) suite.Error(err) // invalid channel state - suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.OPENTRY) + suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.TRYOPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort1, testChannel2, proofAck, uint64(proofHeight)) suite.Error(err) // unauthenticated port - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY) + suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.TRYOPEN) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) suite.Error(err) // connection does not exist - suite.createConnection(connection.NONE) + suite.createConnection(connection.UNINITIALIZED) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) suite.Error(err) // invalid connection state suite.createConnection(connection.OPEN) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.TRYOPEN) suite.updateClient() proofAck, proofHeight = suite.queryProof(channelKey) err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 0590f3cfd37c..515b7ecdf107 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -154,7 +154,7 @@ func (k Keeper) SendPacket( return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) } - if connectionEnd.State == connection.NONE { + if connectionEnd.State == connection.UNINITIALIZED { return connection.ErrInvalidConnectionState( k.codespace, fmt.Sprintf("connection is closed (i.e NONE)"), diff --git a/x/ibc/04-channel/types/channel.go b/x/ibc/04-channel/types/channel.go index d14c42ad6e2c..1250d1208808 100644 --- a/x/ibc/04-channel/types/channel.go +++ b/x/ibc/04-channel/types/channel.go @@ -94,7 +94,7 @@ const ( // channel order types const ( - OrderNone string = "NONE" + OrderNone string = "" OrderUnordered string = "UNORDERED" OrderOrdered string = "ORDERED" ) @@ -102,14 +102,12 @@ const ( // String implements the Stringer interface func (o Order) String() string { switch o { - case NONE: - return OrderNone case UNORDERED: return OrderUnordered case ORDERED: return OrderOrdered default: - return "" + return OrderNone } } @@ -126,26 +124,24 @@ func (o *Order) UnmarshalJSON(data []byte) error { return err } - bz2, err := OrderFromString(s) - if err != nil { - return err + order := OrderFromString(s) + if order == 0 { + return fmt.Errorf("invalid channel ordering '%s'", s) } - *o = bz2 + *o = order return nil } // OrderFromString parses a string into a channel order byte -func OrderFromString(order string) (Order, error) { +func OrderFromString(order string) Order { switch order { - case OrderNone: - return NONE, nil case OrderUnordered: - return UNORDERED, nil + return UNORDERED case OrderOrdered: - return ORDERED, nil + return ORDERED default: - return 0, fmt.Errorf("'%s' is not a valid channel ordering", order) + return NONE } } @@ -155,33 +151,35 @@ type State byte // channel state types const ( - CLOSED State = iota + 1 // A channel end has been closed and can no longer be used to send or receive packets. - INIT // A channel end has just started the opening handshake. - OPENTRY // A channel end has acknowledged the handshake step on the counterparty chain. - OPEN // A channel end has completed the handshake and is ready to send and receive packets. + UNINITIALIZED State = iota // Default State + INIT // A channel end has just started the opening handshake. + TRYOPEN // A channel end has acknowledged the handshake step on the counterparty chain. + OPEN // A channel end has completed the handshake and is ready to send and receive packets. + CLOSED // A channel end has been closed and can no longer be used to send or receive packets. ) // string representation of the channel states const ( - StateClosed string = "CLOSED" - StateInit string = "INIT" - StateOpenTry string = "OPENTRY" - StateOpen string = "OPEN" + StateUninitialized string = "UNINITIALIZED" + StateInit string = "INIT" + StateTryOpen string = "TRYOPEN" + StateOpen string = "OPEN" + StateClosed string = "CLOSED" ) // String implements the Stringer interface func (s State) String() string { switch s { - case CLOSED: - return StateClosed case INIT: return StateInit - case OPENTRY: - return StateOpenTry + case TRYOPEN: + return StateTryOpen case OPEN: return StateOpen + case CLOSED: + return StateClosed default: - return "" + return StateUninitialized } } @@ -198,27 +196,22 @@ func (s *State) UnmarshalJSON(data []byte) error { return err } - bz2, err := StateFromString(stateStr) - if err != nil { - return err - } - - *s = bz2 + *s = StateFromString(stateStr) return nil } // StateFromString parses a string into a channel state byte -func StateFromString(state string) (State, error) { +func StateFromString(state string) State { switch state { case StateClosed: - return CLOSED, nil + return CLOSED case StateInit: - return INIT, nil - case StateOpenTry: - return OPENTRY, nil + return INIT + case StateTryOpen: + return TRYOPEN case StateOpen: - return OPEN, nil + return OPEN default: - return CLOSED, fmt.Errorf("'%s' is not a valid channel state", state) + return UNINITIALIZED } } diff --git a/x/ibc/04-channel/types/channel_test.go b/x/ibc/04-channel/types/channel_test.go new file mode 100644 index 000000000000..56b0dfe5eefa --- /dev/null +++ b/x/ibc/04-channel/types/channel_test.go @@ -0,0 +1,91 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestChannelStateString(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + {StateClosed, CLOSED}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.state, StateFromString(tt.name)) + require.Equal(t, tt.name, tt.state.String()) + } +} + +func TestChannelStateMarshalJSON(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + {StateClosed, CLOSED}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.state.MarshalJSON() + require.NoError(t, err) + var state State + require.NoError(t, state.UnmarshalJSON(bz)) + require.Equal(t, tt.name, state.String()) + } +} + +func TestOrderString(t *testing.T) { + cases := []struct { + name string + order Order + }{ + {OrderNone, NONE}, + {OrderUnordered, UNORDERED}, + {OrderOrdered, ORDERED}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.order, OrderFromString(tt.name)) + require.Equal(t, tt.name, tt.order.String()) + } +} + +func TestOrderMarshalJSON(t *testing.T) { + cases := []struct { + msg string + name string + order Order + expectPass bool + }{ + {"none ordering should have failed", OrderNone, NONE, false}, + {"unordered should have passed", OrderUnordered, UNORDERED, true}, + {"ordered should have passed", OrderOrdered, ORDERED, true}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.order.MarshalJSON() + require.NoError(t, err) + var order Order + if tt.expectPass { + require.NoError(t, order.UnmarshalJSON(bz), tt.msg) + require.Equal(t, tt.name, order.String(), tt.msg) + } else { + require.Error(t, order.UnmarshalJSON(bz), tt.msg) + } + } +} From 1e10e1f60a33a736f6c1fd6d3b5451162d1b7275 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Thu, 2 Jan 2020 19:58:58 -0300 Subject: [PATCH 059/176] Update x/ibc error handling (#5462) * Merge PR #5428: Add mod, exponentiation for uint * Modified examples in distribution module (#5441) * Merge PR #5442: Remove of the client/alias.go * Merge PR #5445: Mock rpcclient in tests for votes pagination * Merge PR #5435: Added iterator that allows to read only requested values * Merge PR #5427: Remove code duplication in x/auth/client/cli * Merge PR #5421: Refactor Error Handling * update x/ibc error handling * update ICS24 and ICS02 errors * ICS03, ICS23 and common errors * updates from master and errors from ICS04 * build * fix ics20 tests * fix tests * golangcibot fixes Co-authored-by: Kevin Davis Co-authored-by: kaustubhkapatral <54210167+kaustubhkapatral@users.noreply.github.com> Co-authored-by: Ferenc Fabian Co-authored-by: Dmitry Shulyak Co-authored-by: Alessio Treglia Co-authored-by: Alexander Bezobchuk --- CHANGELOG.md | 6 + simapp/app.go | 2 +- types/result.go | 9 - x/ibc/02-client/alias.go | 29 +-- x/ibc/02-client/client/cli/cli.go | 6 +- x/ibc/02-client/client/utils/utils.go | 7 +- x/ibc/02-client/handler.go | 26 +-- x/ibc/02-client/keeper/client.go | 24 +- x/ibc/02-client/keeper/keeper.go | 14 +- x/ibc/02-client/keeper/querier.go | 13 +- x/ibc/02-client/types/errors/errors.go | 144 ++---------- x/ibc/02-client/types/msgs.go | 42 ++-- x/ibc/02-client/types/msgs_test.go | 2 +- .../types/tendermint/consensus_state.go | 6 +- x/ibc/02-client/types/tendermint/evidence.go | 31 +-- x/ibc/02-client/types/tendermint/header.go | 6 +- .../types/tendermint/misbehaviour.go | 30 +-- x/ibc/03-connection/alias.go | 46 ++-- x/ibc/03-connection/client/cli/cli.go | 6 +- x/ibc/03-connection/handler.go | 32 ++- x/ibc/03-connection/keeper/handshake.go | 32 +-- x/ibc/03-connection/keeper/keeper.go | 9 +- x/ibc/03-connection/keeper/querier.go | 8 +- x/ibc/03-connection/types/connection.go | 16 +- x/ibc/03-connection/types/errors.go | 96 +------- x/ibc/03-connection/types/msgs.go | 75 ++++--- x/ibc/03-connection/types/msgs_test.go | 212 +++++++++++------- x/ibc/04-channel/alias.go | 139 ++++++------ x/ibc/04-channel/client/cli/cli.go | 6 +- x/ibc/04-channel/client/utils/utils.go | 6 +- x/ibc/04-channel/handler.go | 48 ++-- x/ibc/04-channel/keeper/handshake.go | 107 ++++----- x/ibc/04-channel/keeper/keeper.go | 4 +- x/ibc/04-channel/keeper/packet.go | 152 ++++++------- x/ibc/04-channel/keeper/querier.go | 2 +- x/ibc/04-channel/keeper/timeout.go | 61 ++--- x/ibc/04-channel/types/channel.go | 36 +-- x/ibc/04-channel/types/errors.go | 110 ++------- x/ibc/04-channel/types/msgs.go | 72 +++--- x/ibc/04-channel/types/msgs_test.go | 180 +++++++++------ x/ibc/04-channel/types/packet.go | 57 +++-- x/ibc/05-port/alias.go | 11 +- x/ibc/05-port/keeper/keeper.go | 17 +- x/ibc/05-port/types/errors.go | 42 +--- x/ibc/20-transfer/alias.go | 1 - x/ibc/20-transfer/client/cli/cli.go | 6 +- x/ibc/20-transfer/handler.go | 16 +- x/ibc/20-transfer/handler_test.go | 65 +++--- x/ibc/20-transfer/keeper/callbacks.go | 32 +-- x/ibc/20-transfer/keeper/keeper.go | 8 +- x/ibc/20-transfer/keeper/relay.go | 25 ++- x/ibc/20-transfer/types/expected_keepers.go | 10 +- x/ibc/20-transfer/types/keys.go | 3 - x/ibc/20-transfer/types/msgs.go | 33 ++- x/ibc/20-transfer/types/packet.go | 11 +- x/ibc/23-commitment/errors.go | 14 ++ x/ibc/23-commitment/merkle.go | 8 + x/ibc/23-commitment/merkle_test.go | 3 + x/ibc/23-commitment/types.go | 2 + x/ibc/24-host/errors.go | 42 +--- x/ibc/24-host/validate.go | 12 +- x/ibc/alias.go | 9 +- x/ibc/client/cli/cli.go | 5 +- x/ibc/handler.go | 8 +- x/ibc/keeper/keeper.go | 12 +- x/ibc/keeper/querier.go | 4 +- x/ibc/types/errors.go | 30 +-- 67 files changed, 1073 insertions(+), 1265 deletions(-) create mode 100644 x/ibc/23-commitment/errors.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d2142e26abf..2d68c1cee013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -111,6 +111,7 @@ if the provided arguments are invalid. the `client/keys` add command. * `SupportedAlgos` and `SupportedAlgosLedger` functions return a slice of `SigningAlgo`s that are supported by the keybase and the ledger integration respectively. + * The option introduced in this PR is `WithKeygenFunc` which allows a custom bytes to key implementation to be defined when keys are created. * (simapp) [\#5419](https://github.com/cosmos/cosmos-sdk/pull/5419) simapp/helpers.GenTx() now accepts a gas argument. * (baseapp) [\#5455](https://github.com/cosmos/cosmos-sdk/issues/5455) An `sdk.Context` is passed into the `router.Route()` function. @@ -261,8 +262,11 @@ to detail this new feature and how state transitions occur. * (docs/interfaces/) Add documentation on building interfaces for the Cosmos SDK. * Redesigned user interface that features new dynamically generated sidebar, build-time code embedding from GitHub, new homepage as well as many other improvements. * (types) [\#5428](https://github.com/cosmos/cosmos-sdk/pull/5428) Add `Mod` (modulo) method and `RelativePow` (exponentation) function for `Uint`. +<<<<<<< HEAD * (modules) [\#5506](https://github.com/cosmos/cosmos-sdk/pull/5506) Remove redundancy in `x/distribution`s use of parameters. There now exists a single `Params` type with a getter and setter along with a getter for each individual parameter. +======= +>>>>>>> Update x/ibc error handling (#5462) ### Bug Fixes @@ -2866,3 +2870,5 @@ BUG FIXES: [v0.37.1]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.1 [v0.37.0]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.0 [v0.36.0]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.36.0 + + diff --git a/simapp/app.go b/simapp/app.go index 4a46d34e07dd..eac5db297345 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -232,7 +232,7 @@ func NewSimApp( staking.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), ) - app.IBCKeeper = ibc.NewKeeper(app.cdc, keys[ibc.StoreKey], ibc.DefaultCodespace, app.BankKeeper, app.SupplyKeeper) + app.IBCKeeper = ibc.NewKeeper(app.cdc, keys[ibc.StoreKey], app.BankKeeper, app.SupplyKeeper) // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. diff --git a/types/result.go b/types/result.go index 7ef9a1775e3a..9530be01d25c 100644 --- a/types/result.go +++ b/types/result.go @@ -85,15 +85,6 @@ type TxResponse struct { Timestamp string `json:"timestamp,omitempty"` } -func (res TxResponse) IsOK() bool { - for _, lg := range res.Logs { - if !lg.Success { - return false - } - } - return true -} - // NewResponseResultTx returns a TxResponse given a ResultTx from tendermint func NewResponseResultTx(res *ctypes.ResultTx, tx Tx, timestamp string) TxResponse { if res == nil { diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go index 02f3aa623668..d818bbb99572 100644 --- a/x/ibc/02-client/alias.go +++ b/x/ibc/02-client/alias.go @@ -13,26 +13,15 @@ import ( ) const ( - DefaultCodespace = errors.DefaultCodespace - CodeClientExists = errors.CodeClientExists - CodeClientNotFound = errors.CodeClientNotFound - CodeClientFrozen = errors.CodeClientFrozen - CodeConsensusStateNotFound = errors.CodeConsensusStateNotFound - CodeInvalidConsensusState = errors.CodeInvalidConsensusState - CodeClientTypeNotFound = errors.CodeClientTypeNotFound - CodeInvalidClientType = errors.CodeInvalidClientType - CodeRootNotFound = errors.CodeRootNotFound - CodeInvalidHeader = errors.CodeInvalidHeader - CodeInvalidEvidence = errors.CodeInvalidEvidence - AttributeKeyClientID = types.AttributeKeyClientID - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - QueryAllClients = types.QueryAllClients - QueryClientState = types.QueryClientState - QueryConsensusState = types.QueryConsensusState - QueryVerifiedRoot = types.QueryVerifiedRoot + AttributeKeyClientID = types.AttributeKeyClientID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryAllClients = types.QueryAllClients + QueryClientState = types.QueryClientState + QueryConsensusState = types.QueryConsensusState + QueryVerifiedRoot = types.QueryVerifiedRoot ) var ( diff --git a/x/ibc/02-client/client/cli/cli.go b/x/ibc/02-client/client/cli/cli.go index d2db4d2be958..4a36894faf35 100644 --- a/x/ibc/02-client/client/cli/cli.go +++ b/x/ibc/02-client/client/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) @@ -16,7 +16,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { SuggestionsMinimumDistance: 2, } - ics02ClientQueryCmd.AddCommand(client.GetCommands( + ics02ClientQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryClientStates(queryRoute, cdc), GetCmdQueryClientState(queryRoute, cdc), GetCmdQueryConsensusState(queryRoute, cdc), @@ -37,7 +37,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { SuggestionsMinimumDistance: 2, } - ics02ClientTxCmd.AddCommand(client.PostCommands( + ics02ClientTxCmd.AddCommand(flags.PostCommands( GetCmdCreateClient(cdc), GetCmdUpdateClient(cdc), )...) diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 848d489b2308..02f1163b3d32 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -6,7 +6,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" @@ -62,10 +61,10 @@ func QueryClientState( return clientStateRes, nil } -// QueryConsensusStateProof queries the store to get the consensus state and a -// merkle proof. +// QueryConsensusState queries the store to get the consensus state and a merkle +// proof. func QueryConsensusState( - cliCtx client.CLIContext, clientID string, prove bool) (types.ConsensusStateResponse, error) { + cliCtx context.CLIContext, clientID string, prove bool) (types.ConsensusStateResponse, error) { var conStateRes types.ConsensusStateResponse req := abci.RequestQuery{ diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index 7363053f2319..0525e115a014 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -1,9 +1,8 @@ package client import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/evidence" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" @@ -11,17 +10,15 @@ import ( ) // HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient -func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.Result { +func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) (*sdk.Result, error) { clientType := exported.ClientTypeFromString(msg.ClientType) if clientType == 0 { - return sdk.ResultFromError( - ErrInvalidClientType(DefaultCodespace, fmt.Sprintf("invalid client type '%s'", msg.ClientType)), - ) + return nil, sdkerrors.Wrap(ErrInvalidClientType, msg.ClientType) } _, err := k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -36,14 +33,16 @@ func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.R ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgUpdateClient defines the sdk.Handler for MsgUpdateClient -func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) sdk.Result { +func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) (*sdk.Result, error) { err := k.UpdateClient(ctx, msg.ClientID, msg.Header) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -58,7 +57,9 @@ func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) sdk.R ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandlerClientMisbehaviour defines the Evidence module handler for submitting a @@ -70,8 +71,7 @@ func HandlerClientMisbehaviour(k Keeper) evidence.Handler { return k.CheckMisbehaviourAndUpdateState(ctx, evidence) default: - errMsg := fmt.Sprintf("unrecognized IBC client evidence type: %T", e) - return sdk.ErrUnknownRequest(errMsg) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized IBC client evidence type: %T", e) } } } diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index 9b72ef4a2c2c..91cadfe4a016 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -20,7 +20,7 @@ func (k Keeper) CreateClient( ) (types.State, error) { _, found := k.GetClientState(ctx, clientID) if found { - return types.State{}, errors.ErrClientExists(k.codespace, clientID) + return types.State{}, sdkerrors.Wrapf(errors.ErrClientExists, "cannot create client with ID %s", clientID) } _, found = k.GetClientType(ctx, clientID) @@ -41,31 +41,31 @@ func (k Keeper) CreateClient( func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) error { clientType, found := k.GetClientType(ctx, clientID) if !found { - return sdkerrors.Wrap(errors.ErrClientTypeNotFound(k.codespace), "cannot update client") + return sdkerrors.Wrapf(errors.ErrClientTypeNotFound, "cannot update client with ID %s", clientID) } // check that the header consensus matches the client one if header.ClientType() != clientType { - return sdkerrors.Wrap(errors.ErrInvalidConsensus(k.codespace), "cannot update client") + return sdkerrors.Wrapf(errors.ErrInvalidConsensus, "cannot update client with ID %s", clientID) } clientState, found := k.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(errors.ErrClientNotFound(k.codespace, clientID), "cannot update client") + return sdkerrors.Wrapf(errors.ErrClientNotFound, "cannot update client with ID %s", clientID) } if clientState.Frozen { - return sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientID), "cannot update client") + return sdkerrors.Wrapf(errors.ErrClientFrozen, "cannot update client with ID %s", clientID) } consensusState, found := k.GetConsensusState(ctx, clientID) if !found { - return sdkerrors.Wrap(errors.ErrConsensusStateNotFound(k.codespace), "cannot update client") + return sdkerrors.Wrapf(errors.ErrConsensusStateNotFound, "cannot update client with ID %s", clientID) } consensusState, err := consensusState.CheckValidityAndUpdateState(header) if err != nil { - return sdkerrors.Wrap(err, "cannot update client") + return sdkerrors.Wrapf(err, "cannot update client with ID %s", clientID) } k.SetConsensusState(ctx, clientID, consensusState) @@ -83,25 +83,25 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, evidence evidenceexported.Evidence) error { misbehaviour, ok := evidence.(tendermint.Misbehaviour) if !ok { - return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint") + return sdkerrors.Wrap(errors.ErrInvalidClientType, "consensus type is not Tendermint") } clientState, found := k.GetClientState(ctx, misbehaviour.ClientID) if !found { - return errors.ErrClientNotFound(k.codespace, misbehaviour.ClientID) + return sdkerrors.Wrap(errors.ErrClientNotFound, misbehaviour.ClientID) } committer, found := k.GetCommitter(ctx, misbehaviour.ClientID, uint64(misbehaviour.GetHeight())) if !found { - return errors.ErrCommitterNotFound(k.codespace, fmt.Sprintf("committer not found for height %d", misbehaviour.GetHeight())) + return errors.ErrCommitterNotFound } tmCommitter, ok := committer.(tendermint.Committer) if !ok { - return errors.ErrInvalidCommitter(k.codespace, "committer type is not Tendermint") + return sdkerrors.Wrap(errors.ErrInvalidCommitter, "committer type is not Tendermint") } if err := tendermint.CheckMisbehaviour(tmCommitter, misbehaviour); err != nil { - return errors.ErrInvalidEvidence(k.codespace, err.Error()) + return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) } clientState, err := k.freeze(ctx, clientState) diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index a8b1876d1e41..5732913247b3 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -18,17 +18,15 @@ import ( // Keeper represents a type that grants read and write permissions to any client // state information type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType + storeKey sdk.StoreKey + cdc *codec.Codec } // NewKeeper creates a new NewKeeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, errors.DefaultCodespace)), // "ibc/client", + storeKey: key, + cdc: cdc, } } @@ -181,7 +179,7 @@ func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState expo // freeze updates the state of the client in the event of a misbehaviour func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) { if clientState.Frozen { - return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen(k.codespace, clientState.ID), "already frozen") + return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen, clientState.ID) } clientState.Frozen = true diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go index 104ad554c700..87da8c1eea5f 100644 --- a/x/ibc/02-client/keeper/querier.go +++ b/x/ibc/02-client/keeper/querier.go @@ -1,8 +1,6 @@ package keeper import ( - "fmt" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client" @@ -48,7 +46,7 @@ func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt clientState, found := k.GetClientState(ctx, params.ClientID) if !found { - return nil, errors.ErrClientTypeNotFound(k.codespace) + return nil, sdkerrors.Wrap(errors.ErrClientTypeNotFound, params.ClientID) } bz, err := codec.MarshalJSONIndent(k.cdc, clientState) @@ -69,7 +67,7 @@ func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([] consensusState, found := k.GetConsensusState(ctx, params.ClientID) if !found { - return nil, errors.ErrConsensusStateNotFound(k.codespace) + return nil, errors.ErrConsensusStateNotFound } bz, err := codec.MarshalJSONIndent(k.cdc, consensusState) @@ -90,7 +88,7 @@ func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]by root, found := k.GetVerifiedRoot(ctx, params.ClientID, params.Height) if !found { - return nil, errors.ErrRootNotFound(k.codespace) + return nil, errors.ErrRootNotFound } bz, err := codec.MarshalJSONIndent(k.cdc, root) @@ -111,10 +109,7 @@ func QuerierCommitter(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, committer, found := k.GetCommitter(ctx, params.ClientID, params.Height) if !found { - return nil, errors.ErrCommitterNotFound( - k.codespace, - fmt.Sprintf("committer not found on height: %d", params.Height), - ) + return nil, errors.ErrCommitterNotFound } bz, err := codec.MarshalJSONIndent(k.cdc, committer) diff --git a/x/ibc/02-client/types/errors/errors.go b/x/ibc/02-client/types/errors/errors.go index 1a7272ca1fcb..b6786a6113f6 100644 --- a/x/ibc/02-client/types/errors/errors.go +++ b/x/ibc/02-client/types/errors/errors.go @@ -1,134 +1,24 @@ package errors import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// client error codes -const ( - DefaultCodespace sdk.CodespaceType = "client" - - CodeClientExists sdk.CodeType = 200 - CodeClientNotFound sdk.CodeType = 201 - CodeClientFrozen sdk.CodeType = 202 - CodeConsensusStateNotFound sdk.CodeType = 203 - CodeInvalidConsensusState sdk.CodeType = 204 - CodeClientTypeNotFound sdk.CodeType = 205 - CodeInvalidClientType sdk.CodeType = 206 - CodeRootNotFound sdk.CodeType = 207 - CodeInvalidHeader sdk.CodeType = 208 - CodeInvalidEvidence sdk.CodeType = 209 - CodeCommitterNotFound sdk.CodeType = 210 - CodeInvalidCommitter sdk.CodeType = 211 +// SubModuleName is the error codespace +const SubModuleName string = "ibc/client" + +// IBC client sentinel errors +var ( + ErrClientExists = sdkerrors.Register(SubModuleName, 1, "light client already exists") + ErrClientNotFound = sdkerrors.Register(SubModuleName, 2, "light client not found") + ErrClientFrozen = sdkerrors.Register(SubModuleName, 3, "light client is frozen due to misbehaviour") + ErrConsensusStateNotFound = sdkerrors.Register(SubModuleName, 4, "consensus state not found") + ErrInvalidConsensus = sdkerrors.Register(SubModuleName, 5, "invalid consensus state") + ErrClientTypeNotFound = sdkerrors.Register(SubModuleName, 6, "client type not found") + ErrInvalidClientType = sdkerrors.Register(SubModuleName, 7, "invalid client type") + ErrRootNotFound = sdkerrors.Register(SubModuleName, 8, "commitment root not found") + ErrInvalidHeader = sdkerrors.Register(SubModuleName, 9, "invalid block header") + ErrInvalidEvidence = sdkerrors.Register(SubModuleName, 10, "invalid light client misbehaviour evidence") + ErrCommitterNotFound = sdkerrors.Register(SubModuleName, 11, "commiter not found") + ErrInvalidCommitter = sdkerrors.Register(SubModuleName, 12, "invalid commiter") ) - -// ErrClientExists implements sdk.Error -func ErrClientExists(codespace sdk.CodespaceType, clientID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientExists), - fmt.Sprintf("client with ID %s already exists", clientID), - ) -} - -// ErrClientNotFound implements sdk.Error -func ErrClientNotFound(codespace sdk.CodespaceType, clientID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientNotFound), - fmt.Sprintf("client with ID %s not found", clientID), - ) -} - -// ErrClientFrozen implements sdk.Error -func ErrClientFrozen(codespace sdk.CodespaceType, clientID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientFrozen), - fmt.Sprintf("client with ID %s is frozen due to misbehaviour", clientID), - ) -} - -// ErrConsensusStateNotFound implements sdk.Error -func ErrConsensusStateNotFound(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeConsensusStateNotFound), - "consensus state not found", - ) -} - -// ErrInvalidConsensus implements sdk.Error -func ErrInvalidConsensus(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidConsensusState), - "invalid consensus state", - ) -} - -// ErrClientTypeNotFound implements sdk.Error -func ErrClientTypeNotFound(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientTypeNotFound), - "client type not found", - ) -} - -// ErrInvalidClientType implements sdk.Error -func ErrInvalidClientType(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidClientType), - msg, - ) -} - -// ErrRootNotFound implements sdk.Error -func ErrRootNotFound(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeRootNotFound), - "commitment root not found", - ) -} - -// ErrInvalidHeader implements sdk.Error -func ErrInvalidHeader(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidHeader), - "invalid header", - ) -} - -// ErrInvalidEvidence implements sdk.Error -func ErrInvalidEvidence(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidEvidence), - fmt.Sprintf("invalid evidence: %s", msg), - ) -} - -// ErrCommitterNotFound implements sdk.Error -func ErrCommitterNotFound(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeCommitterNotFound), - fmt.Sprintf("invalid evidence: %s", msg), - ) -} - -// ErrInvalidEvidence implements sdk.Error -func ErrInvalidCommitter(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidCommitter), - fmt.Sprintf("invalid evidence: %s", msg), - ) -} diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index d52c0a614a44..128c76e4144b 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -1,9 +1,8 @@ package types import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" @@ -49,22 +48,17 @@ func (msg MsgCreateClient) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgCreateClient) ValidateBasic() sdk.Error { - if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(err) - } +func (msg MsgCreateClient) ValidateBasic() error { if clientType := exported.ClientTypeFromString(msg.ClientType); clientType == 0 { - return sdk.ConvertError( - errors.ErrInvalidClientType(errors.DefaultCodespace, fmt.Sprintf("invalid client type '%s'", msg.ClientType)), - ) + return sdkerrors.Wrap(errors.ErrInvalidClientType, msg.ClientType) } if msg.ConsensusState == nil { - return sdk.ConvertError(errors.ErrInvalidConsensus(errors.DefaultCodespace)) + return errors.ErrInvalidConsensus } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("empty address") + return sdkerrors.ErrInvalidAddress } - return nil + return host.DefaultClientIdentifierValidator(msg.ClientID) } // GetSignBytes implements sdk.Msg @@ -106,17 +100,14 @@ func (msg MsgUpdateClient) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgUpdateClient) ValidateBasic() sdk.Error { - if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(err) - } +func (msg MsgUpdateClient) ValidateBasic() error { if msg.Header == nil { - return sdk.ConvertError(errors.ErrInvalidHeader(errors.DefaultCodespace)) + return errors.ErrInvalidHeader } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("empty address") + return sdkerrors.ErrInvalidAddress } - return nil + return host.DefaultClientIdentifierValidator(msg.ClientID) } // GetSignBytes implements sdk.Msg @@ -156,20 +147,17 @@ func (msg MsgSubmitMisbehaviour) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgSubmitMisbehaviour) ValidateBasic() sdk.Error { - if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(err) - } +func (msg MsgSubmitMisbehaviour) ValidateBasic() error { if msg.Evidence == nil { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, "evidence is nil")) + return sdkerrors.Wrap(errors.ErrInvalidEvidence, "evidence cannot be nil") } if err := msg.Evidence.ValidateBasic(); err != nil { - return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, err.Error())) + return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("empty address") + return sdkerrors.ErrInvalidAddress } - return nil + return host.DefaultClientIdentifierValidator(msg.ClientID) } // GetSignBytes implements sdk.Msg diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go index b29633420ed4..844276b3ae6b 100644 --- a/x/ibc/02-client/types/msgs_test.go +++ b/x/ibc/02-client/types/msgs_test.go @@ -38,7 +38,7 @@ type mockBadEvidence struct { // Override ValidateBasic func (mbe mockBadEvidence) ValidateBasic() error { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "invalid evidence") + return errors.ErrInvalidEvidence } func TestMsgCreateClientValidateBasic(t *testing.T) { diff --git a/x/ibc/02-client/types/tendermint/consensus_state.go b/x/ibc/02-client/types/tendermint/consensus_state.go index 25c2f8d990f8..cb7e2e42e849 100644 --- a/x/ibc/02-client/types/tendermint/consensus_state.go +++ b/x/ibc/02-client/types/tendermint/consensus_state.go @@ -53,7 +53,9 @@ func (cs ConsensusState) GetCommitter() exported.Committer { func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (exported.ConsensusState, error) { tmHeader, ok := header.(Header) if !ok { - return nil, clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace) + return nil, sdkerrors.Wrap( + clienterrors.ErrInvalidHeader, "header is not from Tendermint", + ) } if err := cs.checkValidity(tmHeader); err != nil { @@ -69,7 +71,7 @@ func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (ex func (cs ConsensusState) checkValidity(header Header) error { if header.GetHeight() < cs.Height { return sdkerrors.Wrap( - clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), + clienterrors.ErrInvalidHeader, fmt.Sprintf("header height < consensus height (%d < %d)", header.GetHeight(), cs.Height), ) } diff --git a/x/ibc/02-client/types/tendermint/evidence.go b/x/ibc/02-client/types/tendermint/evidence.go index a8d1154a27ae..bc60b413b4e6 100644 --- a/x/ibc/02-client/types/tendermint/evidence.go +++ b/x/ibc/02-client/types/tendermint/evidence.go @@ -1,14 +1,13 @@ package tendermint import ( - "fmt" - yaml "gopkg.in/yaml.v2" "github.com/tendermint/tendermint/crypto/tmhash" cmn "github.com/tendermint/tendermint/libs/common" tmtypes "github.com/tendermint/tendermint/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" ) @@ -56,27 +55,31 @@ func (ev Evidence) GetHeight() int64 { func (ev Evidence) ValidateBasic() error { // ValidateBasic on both validators if err := ev.Header1.ValidateBasic(ev.ChainID); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Header1 failed ValidateBasic: %v", err)) + return sdkerrors.Wrap( + errors.ErrInvalidEvidence, + sdkerrors.Wrap(err, "header 1 failed validation").Error(), + ) } if err := ev.Header2.ValidateBasic(ev.ChainID); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Header2 failed ValidateBasic: %v", err)) + return sdkerrors.Wrap( + errors.ErrInvalidEvidence, + sdkerrors.Wrap(err, "header 2 failed validation").Error(), + ) } // Ensure that Heights are the same if ev.Header1.Height != ev.Header2.Height { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "headers in evidence are on different heights") + return sdkerrors.Wrapf(errors.ErrInvalidEvidence, "headers in evidence are on different heights (%d ≠ %d)", ev.Header1.Height, ev.Header2.Height) } // Ensure that Commit Hashes are different if ev.Header1.Commit.BlockID.Equals(ev.Header2.Commit.BlockID) { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "Headers commit to same blockID") + return sdkerrors.Wrap(errors.ErrInvalidEvidence, "headers commit to same blockID") } - - if err1 := ValidCommit(ev.ChainID, ev.Header1.Commit, ev.Header1.ValidatorSet); err1 != nil { - return err1 + if err := ValidCommit(ev.ChainID, ev.Header1.Commit, ev.Header1.ValidatorSet); err != nil { + return err } - if err2 := ValidCommit(ev.ChainID, ev.Header2.Commit, ev.Header2.ValidatorSet); err2 != nil { - return err2 + if err := ValidCommit(ev.ChainID, ev.Header2.Commit, ev.Header2.ValidatorSet); err != nil { + return err } - return nil } @@ -88,7 +91,7 @@ func (ev Evidence) ValidateBasic() error { func ValidCommit(chainID string, commit *tmtypes.Commit, valSet *tmtypes.ValidatorSet) (err error) { defer func() { if r := recover(); r != nil { - err = errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("invalid commit: %v", r)) + err = sdkerrors.Wrapf(errors.ErrInvalidEvidence, "invalid commit: %v", r) } }() @@ -99,7 +102,7 @@ func ValidCommit(chainID string, commit *tmtypes.Commit, valSet *tmtypes.Validat // Check that ValidatorSet did indeed commit to blockID in Commit if !ok || !blockID.Equals(commit.BlockID) { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "ValidatorSet did not commit to Header1") + return sdkerrors.Wrap(errors.ErrInvalidEvidence, "validator set did not commit to header 1") } return nil diff --git a/x/ibc/02-client/types/tendermint/header.go b/x/ibc/02-client/types/tendermint/header.go index 133c1741e56e..9509d6370019 100644 --- a/x/ibc/02-client/types/tendermint/header.go +++ b/x/ibc/02-client/types/tendermint/header.go @@ -42,13 +42,13 @@ func (h Header) GetHeight() uint64 { // and checks that validatorsets are not nil func (h Header) ValidateBasic(chainID string) error { if err := h.SignedHeader.ValidateBasic(chainID); err != nil { - return err + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader, err.Error()) } if h.ValidatorSet == nil { - return sdkerrors.Wrap(clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), "ValidatorSet is nil") + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader, "validator set is nil") } if h.NextValidatorSet == nil { - return sdkerrors.Wrap(clienterrors.ErrInvalidHeader(clienterrors.DefaultCodespace), "NextValidatorSet is nil") + return sdkerrors.Wrap(clienterrors.ErrInvalidHeader, "next validator set is nil") } return nil } diff --git a/x/ibc/02-client/types/tendermint/misbehaviour.go b/x/ibc/02-client/types/tendermint/misbehaviour.go index 5b04b6e3ec0c..36c8e14ce8ab 100644 --- a/x/ibc/02-client/types/tendermint/misbehaviour.go +++ b/x/ibc/02-client/types/tendermint/misbehaviour.go @@ -1,8 +1,7 @@ package tendermint import ( - "fmt" - + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" @@ -33,14 +32,15 @@ func (m Misbehaviour) GetEvidence() evidenceexported.Evidence { // client ID. func (m Misbehaviour) ValidateBasic() error { if m.Evidence == nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, "empty evidence") + return sdkerrors.Wrap(errors.ErrInvalidEvidence, "evidence is empty") } - if err := m.Evidence.ValidateBasic(); err != nil { - return err + return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) } - - return host.DefaultClientIdentifierValidator(m.ClientID) + if err := host.DefaultClientIdentifierValidator(m.ClientID); err != nil { + return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) + } + return nil } // CheckMisbehaviour checks if the evidence provided is a valid light client misbehaviour @@ -54,13 +54,17 @@ func CheckMisbehaviour(trustedCommitter Committer, m Misbehaviour) error { // Evidence is within trusting period. ValidatorSet must have 2/3 similarity with trustedCommitter ValidatorSet // check that the validator sets on both headers are valid given the last trusted validatorset // less than or equal to evidence height - if err := trustedValSet.VerifyFutureCommit(m.Evidence.Header1.ValidatorSet, m.Evidence.ChainID, - m.Evidence.Header1.Commit.BlockID, m.Evidence.Header1.Height, m.Evidence.Header1.Commit); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("validator set in Header1 has too much change from last known committer: %v", err)) + if err := trustedValSet.VerifyFutureCommit( + m.Evidence.Header1.ValidatorSet, m.Evidence.ChainID, + m.Evidence.Header1.Commit.BlockID, m.Evidence.Header1.Height, m.Evidence.Header1.Commit, + ); err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidEvidence, "validator set in header 1 has too much change from last known committer: %v", err) } - if err := trustedValSet.VerifyFutureCommit(m.Evidence.Header2.ValidatorSet, m.Evidence.ChainID, - m.Evidence.Header2.Commit.BlockID, m.Evidence.Header2.Height, m.Evidence.Header2.Commit); err != nil { - return errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("validator set in Header2 has too much change from last known committer: %v", err)) + if err := trustedValSet.VerifyFutureCommit( + m.Evidence.Header2.ValidatorSet, m.Evidence.ChainID, + m.Evidence.Header2.Commit.BlockID, m.Evidence.Header2.Height, m.Evidence.Header2.Commit, + ); err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidEvidence, "validator set in header 2 has too much change from last known committer: %v", err) } return nil diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index 4d44e18048e8..2cb4faf887ff 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -12,33 +12,23 @@ import ( ) const ( - UNINITIALIZED = types.UNINITIALIZED - INIT = types.INIT - TRYOPEN = types.TRYOPEN - OPEN = types.OPEN - StateUninitialized = types.StateUninitialized - StateInit = types.StateInit - StateTryOpen = types.StateTryOpen - StateOpen = types.StateOpen - DefaultCodespace = types.DefaultCodespace - CodeConnectionExists = types.CodeConnectionExists - CodeConnectionNotFound = types.CodeConnectionNotFound - CodeClientConnectionPathsNotFound = types.CodeClientConnectionPathsNotFound - CodeConnectionPath = types.CodeConnectionPath - CodeInvalidCounterpartyConnection = types.CodeInvalidCounterpartyConnection - CodeInvalidVersion = types.CodeInvalidVersion - CodeInvalidHeight = types.CodeInvalidHeight - CodeInvalidConnectionState = types.CodeInvalidConnectionState - CodeInvalidCounterparty = types.CodeInvalidCounterparty - AttributeKeyConnectionID = types.AttributeKeyConnectionID - AttributeKeyCounterpartyClientID = types.AttributeKeyCounterpartyClientID - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - QueryAllConnections = types.QueryAllConnections - QueryConnection = types.QueryConnection - QueryClientConnections = types.QueryClientConnections + UNINITIALIZED = types.UNINITIALIZED + INIT = types.INIT + TRYOPEN = types.TRYOPEN + OPEN = types.OPEN + StateUninitialized = types.StateUninitialized + StateInit = types.StateInit + StateTryOpen = types.StateTryOpen + StateOpen = types.StateOpen + AttributeKeyConnectionID = types.AttributeKeyConnectionID + AttributeKeyCounterpartyClientID = types.AttributeKeyCounterpartyClientID + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryAllConnections = types.QueryAllConnections + QueryConnection = types.QueryConnection + QueryClientConnections = types.QueryClientConnections ) var ( @@ -55,8 +45,6 @@ var ( ErrConnectionNotFound = types.ErrConnectionNotFound ErrClientConnectionPathsNotFound = types.ErrClientConnectionPathsNotFound ErrConnectionPath = types.ErrConnectionPath - ErrInvalidCounterpartyConnection = types.ErrInvalidCounterpartyConnection - ErrInvalidHeight = types.ErrInvalidHeight ErrInvalidConnectionState = types.ErrInvalidConnectionState ErrInvalidCounterparty = types.ErrInvalidCounterparty ConnectionPath = types.ConnectionPath diff --git a/x/ibc/03-connection/client/cli/cli.go b/x/ibc/03-connection/client/cli/cli.go index e0ea7c89880f..92c3fa8cc901 100644 --- a/x/ibc/03-connection/client/cli/cli.go +++ b/x/ibc/03-connection/client/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) @@ -16,7 +16,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { SuggestionsMinimumDistance: 2, } - ics03ConnectionQueryCmd.AddCommand(client.GetCommands( + ics03ConnectionQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryConnections(queryRoute, cdc), GetCmdQueryConnection(queryRoute, cdc), )...) @@ -30,7 +30,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "IBC connection transaction subcommands", } - ics03ConnectionTxCmd.AddCommand(client.PostCommands( + ics03ConnectionTxCmd.AddCommand(flags.PostCommands( GetCmdConnectionOpenInit(storeKey, cdc), GetCmdConnectionOpenTry(storeKey, cdc), GetCmdConnectionOpenAck(storeKey, cdc), diff --git a/x/ibc/03-connection/handler.go b/x/ibc/03-connection/handler.go index 854436eadd6a..b7c9eae08d3f 100644 --- a/x/ibc/03-connection/handler.go +++ b/x/ibc/03-connection/handler.go @@ -7,10 +7,10 @@ import ( ) // HandleMsgConnectionOpenInit defines the sdk.Handler for MsgConnectionOpenInit -func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenInit) sdk.Result { +func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenInit) (*sdk.Result, error) { err := k.ConnOpenInit(ctx, msg.ConnectionID, msg.ClientID, msg.Counterparty) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -26,16 +26,18 @@ func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.Msg ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgConnectionOpenTry defines the sdk.Handler for MsgConnectionOpenTry -func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenTry) sdk.Result { +func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenTry) (*sdk.Result, error) { err := k.ConnOpenTry( ctx, msg.ConnectionID, msg.Counterparty, msg.ClientID, msg.CounterpartyVersions, msg.ProofInit, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -51,17 +53,19 @@ func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgC ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgConnectionOpenAck defines the sdk.Handler for MsgConnectionOpenAck -func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenAck) sdk.Result { +func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenAck) (*sdk.Result, error) { err := k.ConnOpenAck( ctx, msg.ConnectionID, msg.Version, msg.ProofTry, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight, ) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -76,14 +80,16 @@ func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgC ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgConnectionOpenConfirm defines the sdk.Handler for MsgConnectionOpenConfirm -func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenConfirm) sdk.Result { +func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenConfirm) (*sdk.Result, error) { err := k.ConnOpenConfirm(ctx, msg.ConnectionID, msg.ProofAck, msg.ProofHeight) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -98,5 +104,7 @@ func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types. ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index e5a011a84b3a..8a40c427de52 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -22,7 +22,7 @@ func (k Keeper) ConnOpenInit( ) error { _, found := k.GetConnection(ctx, connectionID) if found { - return sdkerrors.Wrap(types.ErrConnectionExists(k.codespace, connectionID), "cannot initialize connection") + return sdkerrors.Wrap(types.ErrConnectionExists, "cannot initialize connection") } // connection defines chain A's ConnectionEnd @@ -58,7 +58,7 @@ func (k Keeper) ConnOpenTry( // XXX: blocked by #5078 /* if consensusHeight > uint64(ctx.BlockHeight()) { - return errors.New("invalid consensus height") // TODO: sdk.Error + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") } expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, clientID) @@ -112,7 +112,7 @@ func (k Keeper) ConnOpenTry( _, found := k.GetConnection(ctx, connectionID) if found { - return sdkerrors.Wrap(types.ErrConnectionExists(k.codespace, connectionID), "cannot relay connection attempt") + return sdkerrors.Wrap(types.ErrConnectionExists, "cannot relay connection attempt") } connection.State = types.TRYOPEN @@ -142,25 +142,25 @@ func (k Keeper) ConnOpenAck( // XXX: blocked by #5078 /* if consensusHeight > uint64(ctx.BlockHeight()) { - return errors.New("invalid consensus height") // TODO: sdk.Error + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") } */ connection, found := k.GetConnection(ctx, connectionID) if !found { - return sdkerrors.Wrap(types.ErrConnectionNotFound(k.codespace, connectionID), "cannot relay ACK of open attempt") + return sdkerrors.Wrap(types.ErrConnectionNotFound, "cannot relay ACK of open attempt") } if connection.State != types.INIT { - return types.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not INIT (got %s)", connection.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidConnectionState, + "connection state is not INIT (got %s)", connection.State.String(), ) } if types.LatestVersion(connection.Versions) != version { - return ibctypes.ErrInvalidVersion( - k.codespace, - fmt.Sprintf("connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version), + return sdkerrors.Wrapf( + ibctypes.ErrInvalidVersion, + "connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version, ) } @@ -223,13 +223,13 @@ func (k Keeper) ConnOpenConfirm( ) error { connection, found := k.GetConnection(ctx, connectionID) if !found { - return sdkerrors.Wrap(types.ErrConnectionNotFound(k.codespace, connectionID), "cannot relay ACK of open attempt") + return sdkerrors.Wrap(types.ErrConnectionNotFound, "cannot relay ACK of open attempt") } if connection.State != types.TRYOPEN { - return types.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not TRYOPEN (got %s)", connection.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidConnectionState, + "connection state is not TRYOPEN (got %s)", connection.State.String(), ) } @@ -247,7 +247,7 @@ func (k Keeper) ConnOpenConfirm( types.ConnectionPath(connection.Counterparty.ConnectionID), expConnBz, ) if !ok { - return types.ErrInvalidCounterpartyConnection(k.codespace) + return errors.New("couldn't verify connection membership on counterparty's client") } connection.State = types.OPEN diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index c20720c17788..5edec4cdf32b 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" @@ -17,16 +18,14 @@ import ( type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec - codespace sdk.CodespaceType clientKeeper types.ClientKeeper } // NewKeeper creates a new IBC connection Keeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, ck types.ClientKeeper) Keeper { +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ck types.ClientKeeper) Keeper { return Keeper{ storeKey: key, cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/connection", clientKeeper: ck, } } @@ -133,12 +132,12 @@ func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID st func (k Keeper) removeConnectionFromClient(ctx sdk.Context, clientID, connectionID string) error { conns, found := k.GetClientConnectionPaths(ctx, clientID) if !found { - return types.ErrClientConnectionPathsNotFound(k.codespace, clientID) + return sdkerrors.Wrap(types.ErrClientConnectionPathsNotFound, clientID) } conns, ok := host.RemovePath(conns, connectionID) if !ok { - return types.ErrConnectionPath(k.codespace) + return sdkerrors.Wrap(types.ErrConnectionPath, clientID) } k.SetClientConnectionPaths(ctx, clientID, conns) diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go index f5c56834161f..c888e84e32b2 100644 --- a/x/ibc/03-connection/keeper/querier.go +++ b/x/ibc/03-connection/keeper/querier.go @@ -20,12 +20,12 @@ func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte connection, found := k.GetConnection(ctx, params.ConnectionID) if !found { - return nil, types.ErrConnectionNotFound(k.codespace, params.ConnectionID) + return nil, sdkerrors.Wrap(types.ErrConnectionNotFound, params.ConnectionID) } - bz, err := codec.MarshalJSONIndent(k.cdc, connection) + bz, err := types.SubModuleCdc.MarshalJSON(connection) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil @@ -66,7 +66,7 @@ func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) clientConnectionPaths, found := k.GetClientConnectionPaths(ctx, params.ClientID) if !found { - return nil, types.ErrClientConnectionPathsNotFound(k.codespace, params.ClientID) + return nil, sdkerrors.Wrap(types.ErrClientConnectionPathsNotFound, params.ClientID) } bz, err := types.SubModuleCdc.MarshalJSON(clientConnectionPaths) diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 65806e9f5a9a..5a441c22eb26 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -54,13 +54,23 @@ func NewCounterparty(clientID, connectionID string, prefix commitment.PrefixI) C // ValidateBasic performs a basic validation check of the identifiers and prefix func (c Counterparty) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(c.ConnectionID); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty connection ID") + return sdkerrors.Wrap(err, + sdkerrors.Wrapf( + ErrInvalidCounterparty, + "invalid counterparty connection ID %s", c.ConnectionID, + ).Error(), + ) } if err := host.DefaultClientIdentifierValidator(c.ClientID); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty client ID") + return sdkerrors.Wrap(err, + sdkerrors.Wrapf( + ErrInvalidCounterparty, + "invalid counterparty client ID %s", c.ClientID, + ).Error(), + ) } if c.Prefix == nil || len(c.Prefix.Bytes()) == 0 { - return ErrInvalidCounterparty(DefaultCodespace, "invalid counterparty prefix") + return sdkerrors.Wrap(ErrInvalidCounterparty, "invalid counterparty prefix") } return nil } diff --git a/x/ibc/03-connection/types/errors.go b/x/ibc/03-connection/types/errors.go index d62e14a49218..41199efc4103 100644 --- a/x/ibc/03-connection/types/errors.go +++ b/x/ibc/03-connection/types/errors.go @@ -1,95 +1,15 @@ package types import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// connection error codes -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodeConnectionExists sdk.CodeType = 210 - CodeConnectionNotFound sdk.CodeType = 211 - CodeClientConnectionPathsNotFound sdk.CodeType = 212 - CodeConnectionPath sdk.CodeType = 213 - CodeInvalidCounterpartyConnection sdk.CodeType = 214 - CodeInvalidVersion sdk.CodeType = 215 - CodeInvalidHeight sdk.CodeType = 216 - CodeInvalidConnectionState sdk.CodeType = 217 - CodeInvalidCounterparty sdk.CodeType = 218 +// IBC connection sentinel errors +var ( + ErrConnectionExists = sdkerrors.Register(SubModuleName, 1, "connection already exists") + ErrConnectionNotFound = sdkerrors.Register(SubModuleName, 2, "connection not found") + ErrClientConnectionPathsNotFound = sdkerrors.Register(SubModuleName, 3, "light client connection paths not found") + ErrConnectionPath = sdkerrors.Register(SubModuleName, 4, "connection path is not associated to the given light client") + ErrInvalidConnectionState = sdkerrors.Register(SubModuleName, 5, "invalid connection state") + ErrInvalidCounterparty = sdkerrors.Register(SubModuleName, 6, "invalid counterparty connection") ) - -// ErrConnectionExists implements sdk.Error -func ErrConnectionExists(codespace sdk.CodespaceType, connectionID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeConnectionExists), - fmt.Sprintf("connection with ID %s already exists", connectionID), - ) -} - -// ErrConnectionNotFound implements sdk.Error -func ErrConnectionNotFound(codespace sdk.CodespaceType, connectionID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeConnectionNotFound), - fmt.Sprintf("connection with ID %s not found", connectionID), - ) -} - -// ErrClientConnectionPathsNotFound implements sdk.Error -func ErrClientConnectionPathsNotFound(codespace sdk.CodespaceType, clientID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeClientConnectionPathsNotFound), - fmt.Sprintf("client connection paths not found for ID %s", clientID), - ) -} - -// ErrConnectionPath implements sdk.Error -func ErrConnectionPath(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeConnectionPath), - "connection path is not associated to the client", - ) -} - -// ErrInvalidCounterpartyConnection implements sdk.Error -func ErrInvalidCounterpartyConnection(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidCounterpartyConnection), - "couldn't verify connection membership on counterparty's client", - ) -} - -// ErrInvalidHeight implements sdk.Error -func ErrInvalidHeight(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidHeight), - msg, - ) -} - -// ErrInvalidConnectionState implements sdk.Error -func ErrInvalidConnectionState(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidConnectionState), - msg, - ) -} - -// ErrInvalidCounterparty implements sdk.Error -func ErrInvalidCounterparty(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidCounterparty), - msg, - ) -} diff --git a/x/ibc/03-connection/types/msgs.go b/x/ibc/03-connection/types/msgs.go index e302badac9c4..bf0731c3bb66 100644 --- a/x/ibc/03-connection/types/msgs.go +++ b/x/ibc/03-connection/types/msgs.go @@ -47,17 +47,17 @@ func (msg MsgConnectionOpenInit) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgConnectionOpenInit) ValidateBasic() sdk.Error { +func (msg MsgConnectionOpenInit) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) + return sdkerrors.Wrapf(err, "invalid connection ID: %s", msg.ConnectionID) } if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid client ID")) + return sdkerrors.Wrapf(err, "invalid client ID: %s", msg.ClientID) } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.ErrInvalidAddress } - return sdk.ConvertError(msg.Counterparty.ValidateBasic()) + return msg.Counterparty.ValidateBasic() } // GetSignBytes implements sdk.Msg @@ -118,37 +118,40 @@ func (msg MsgConnectionOpenTry) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgConnectionOpenTry) ValidateBasic() sdk.Error { +func (msg MsgConnectionOpenTry) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) + return sdkerrors.Wrapf(err, "invalid connection ID: %s", msg.ConnectionID) } if err := host.DefaultClientIdentifierValidator(msg.ClientID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid client ID")) + return sdkerrors.Wrapf(err, "invalid client ID: %s", msg.ClientID) } if len(msg.CounterpartyVersions) == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "missing counterparty versions")) + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "missing counterparty versions") } for _, version := range msg.CounterpartyVersions { if strings.TrimSpace(version) == "" { - return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "version can't be blank")) + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version can't be blank") } } - if msg.ProofInit == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof init cannot be nil")) + if msg.ProofInit == nil || msg.ProofConsensus == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") } - if msg.ProofConsensus == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof consensus cannot be nil")) + if err := msg.ProofInit.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof init cannot be nil") + } + if err := msg.ProofConsensus.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof consensus cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } if msg.ConsensusHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "consensus height must be > 0") } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.ErrInvalidAddress } - return sdk.ConvertError(msg.Counterparty.ValidateBasic()) + return msg.Counterparty.ValidateBasic() } // GetSignBytes implements sdk.Msg @@ -203,27 +206,30 @@ func (msg MsgConnectionOpenAck) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgConnectionOpenAck) ValidateBasic() sdk.Error { +func (msg MsgConnectionOpenAck) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) + return sdkerrors.Wrap(err, "invalid connection ID") } if strings.TrimSpace(msg.Version) == "" { - return sdk.ConvertError(ibctypes.ErrInvalidVersion(DefaultCodespace, "version can't be blank")) + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version can't be blank") + } + if msg.ProofTry == nil || msg.ProofConsensus == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") } - if msg.ProofTry == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof try cannot be nil")) + if err := msg.ProofTry.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof try cannot be nil") } - if msg.ProofConsensus == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof consensus cannot be nil")) + if err := msg.ProofConsensus.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof consensus cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } if msg.ConsensusHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "consensus height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "consensus height must be > 0") } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.ErrInvalidAddress } return nil } @@ -272,18 +278,21 @@ func (msg MsgConnectionOpenConfirm) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgConnectionOpenConfirm) ValidateBasic() sdk.Error { +func (msg MsgConnectionOpenConfirm) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(msg.ConnectionID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid connection ID")) + return sdkerrors.Wrap(err, "invalid connection ID") } if msg.ProofAck == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof ack cannot be nil")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofAck.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ErrInvalidHeight(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.ErrInvalidAddress } return nil } diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go index 87fbae8b7276..8bca120769ba 100644 --- a/x/ibc/03-connection/types/msgs_test.go +++ b/x/ibc/03-connection/types/msgs_test.go @@ -4,20 +4,50 @@ import ( "fmt" "testing" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -func TestNewMsgConnectionOpenInit(t *testing.T) { +type MsgTestSuite struct { + suite.Suite - type TestCase = struct { - msg MsgConnectionOpenInit - expected bool - errMsg string - } + proof commitment.Proof +} + +func (suite *MsgTestSuite) SetupTest() { + db := dbm.NewMemDB() + store := rootmulti.NewStore(db) + storeKey := storetypes.NewKVStoreKey("iavlStoreKey") + + store.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) + store.LoadVersion(0) + iavlStore := store.GetCommitStore(storeKey).(*iavl.Store) + + iavlStore.Set([]byte("KEY"), []byte("VALUE")) + _ = store.Commit() + + res := store.Query(abci.RequestQuery{ + Path: fmt.Sprintf("/%s/key", storeKey.Name()), // required path to get key/value+proof + Data: []byte("KEY"), + Prove: true, + }) + + suite.proof = commitment.Proof{Proof: res.Proof} +} + +func TestMsgTestSuite(t *testing.T) { + suite.Run(t, new(MsgTestSuite)) +} +func (suite *MsgTestSuite) TestNewMsgConnectionOpenInit() { prefix := commitment.NewPrefix([]byte("storePrefixKey")) signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") @@ -31,7 +61,11 @@ func TestNewMsgConnectionOpenInit(t *testing.T) { NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, signer), } - var testCases = []TestCase{ + var testCases = []struct { + msg MsgConnectionOpenInit + expPass bool + errMsg string + }{ {testMsgs[0], false, "invalid connection ID"}, {testMsgs[1], false, "invalid client ID"}, {testMsgs[2], false, "invalid counterparty client ID"}, @@ -42,36 +76,41 @@ func TestNewMsgConnectionOpenInit(t *testing.T) { } for i, tc := range testCases { - require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %v", i, err) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } } } -func TestNewMsgConnectionOpenTry(t *testing.T) { - type TestCase = struct { - msg MsgConnectionOpenTry - expected bool - errMsg string - } - +func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { prefix := commitment.NewPrefix([]byte("storePrefixKey")) signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenTry{ - NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "ibc/test", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "test/conn1", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", nil, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, nil, commitment.Proof{}, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, nil, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 0, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 0, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, nil), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{}, commitment.Proof{}, 10, 10, signer), - } - - var testCases = []TestCase{ + NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "ibc/test", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "test/conn1", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", nil, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{}, suite.proof, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, nil, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{Proof: nil}, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, nil, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, commitment.Proof{Proof: nil}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 0, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 0, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, nil), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), + } + + var testCases = []struct { + msg MsgConnectionOpenTry + expPass bool + errMsg string + }{ {testMsgs[0], false, "invalid connection ID"}, {testMsgs[1], false, "invalid client ID"}, {testMsgs[2], false, "invalid counterparty connection ID"}, @@ -79,79 +118,98 @@ func TestNewMsgConnectionOpenTry(t *testing.T) { {testMsgs[4], false, "empty counterparty prefix"}, {testMsgs[5], false, "empty counterpartyVersions"}, {testMsgs[6], false, "empty proofInit"}, - {testMsgs[7], false, "empty proofConsensus"}, - {testMsgs[8], false, "invalid proofHeight"}, - {testMsgs[9], false, "invalid consensusHeight"}, - {testMsgs[10], false, "empty singer"}, - {testMsgs[11], true, "success"}, + {testMsgs[7], false, "empty proofInit"}, + {testMsgs[8], false, "empty proofConsensus"}, + {testMsgs[9], false, "empty proofConsensus"}, + {testMsgs[10], false, "invalid proofHeight"}, + {testMsgs[11], false, "invalid consensusHeight"}, + {testMsgs[12], false, "empty singer"}, + {testMsgs[13], true, "success"}, } for i, tc := range testCases { - require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } } } -func TestNewMsgConnectionOpenAck(t *testing.T) { - type TestCase = struct { - msg MsgConnectionOpenAck - expected bool - errMsg string - } - +func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenAck{ - NewMsgConnectionOpenAck("test/conn1", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", nil, commitment.Proof{}, 10, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, nil, 10, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 0, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 0, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", nil), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{}, commitment.Proof{}, 10, 10, "1.0.0", signer), - } - var testCases = []TestCase{ + NewMsgConnectionOpenAck("test/conn1", suite.proof, suite.proof, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", nil, suite.proof, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{Proof: nil}, suite.proof, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, nil, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, commitment.Proof{Proof: nil}, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 0, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 0, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 10, "", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 10, "1.0.0", nil), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 10, "1.0.0", signer), + } + var testCases = []struct { + msg MsgConnectionOpenAck + expPass bool + errMsg string + }{ {testMsgs[0], false, "invalid connection ID"}, {testMsgs[1], false, "empty proofTry"}, - {testMsgs[2], false, "empty proofConsensus"}, - {testMsgs[3], false, "invalid proofHeight"}, - {testMsgs[4], false, "invalid consensusHeight"}, - {testMsgs[5], false, "invalid version"}, - {testMsgs[6], false, "empty signer"}, - {testMsgs[7], true, "success"}, + {testMsgs[2], false, "empty proofTry"}, + {testMsgs[3], false, "empty proofConsensus"}, + {testMsgs[4], false, "empty proofConsensus"}, + {testMsgs[5], false, "invalid proofHeight"}, + {testMsgs[6], false, "invalid consensusHeight"}, + {testMsgs[7], false, "invalid version"}, + {testMsgs[8], false, "empty signer"}, + {testMsgs[9], true, "success"}, } for i, tc := range testCases { - require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } } } -func TestNewMsgConnectionOpenConfirm(t *testing.T) { - type TestCase = struct { - msg MsgConnectionOpenConfirm - expected bool - errMsg string - } - +func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenConfirm{ - NewMsgConnectionOpenConfirm("test/conn1", commitment.Proof{}, 10, signer), + NewMsgConnectionOpenConfirm("test/conn1", suite.proof, 10, signer), NewMsgConnectionOpenConfirm("ibcconntest", nil, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 0, signer), - NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 10, nil), - NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{}, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{Proof: nil}, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 0, signer), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, nil), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, signer), } - var testCases = []TestCase{ + var testCases = []struct { + msg MsgConnectionOpenConfirm + expPass bool + errMsg string + }{ {testMsgs[0], false, "invalid connection ID"}, {testMsgs[1], false, "empty proofTry"}, - {testMsgs[2], false, "invalid proofHeight"}, - {testMsgs[3], false, "empty signer"}, - {testMsgs[4], true, "success"}, + {testMsgs[2], false, "empty proofTry"}, + {testMsgs[3], false, "invalid proofHeight"}, + {testMsgs[4], false, "empty signer"}, + {testMsgs[5], true, "success"}, } for i, tc := range testCases { - require.Equal(t, tc.expected, tc.msg.ValidateBasic() == nil, fmt.Sprintf("case: %d,msg: %s,", i, tc.errMsg)) + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } } } diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index f2d6a7f49d24..73e18df48d0c 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -12,84 +12,75 @@ import ( ) const ( - UNINITIALIZED = types.UNINITIALIZED - UNORDERED = types.UNORDERED - ORDERED = types.ORDERED - OrderNone = types.OrderNone - OrderUnordered = types.OrderUnordered - OrderOrdered = types.OrderOrdered - CLOSED = types.CLOSED - INIT = types.INIT - TRYOPEN = types.TRYOPEN - OPEN = types.OPEN - StateUninitialized = types.StateUninitialized - StateInit = types.StateInit - StateTryOpen = types.StateTryOpen - StateOpen = types.StateOpen - StateClosed = types.StateClosed - DefaultCodespace = types.DefaultCodespace - CodeChannelExists = types.CodeChannelExists - CodeChannelNotFound = types.CodeChannelNotFound - CodeInvalidCounterpartyChannel = types.CodeInvalidCounterpartyChannel - CodeChannelCapabilityNotFound = types.CodeChannelCapabilityNotFound - CodeInvalidPacket = types.CodeInvalidPacket - CodeSequenceNotFound = types.CodeSequenceNotFound - CodePacketTimeout = types.CodePacketTimeout - CodeInvalidChannel = types.CodeInvalidChannel - CodeInvalidChannelState = types.CodeInvalidChannelState - AttributeKeySenderPort = types.AttributeKeySenderPort - AttributeKeyReceiverPort = types.AttributeKeyReceiverPort - AttributeKeyChannelID = types.AttributeKeyChannelID - AttributeKeySequence = types.AttributeKeySequence - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - QueryAllChannels = types.QueryAllChannels - QueryChannel = types.QueryChannel + UNINITIALIZED = types.UNINITIALIZED + UNORDERED = types.UNORDERED + ORDERED = types.ORDERED + OrderNone = types.OrderNone + OrderUnordered = types.OrderUnordered + OrderOrdered = types.OrderOrdered + CLOSED = types.CLOSED + INIT = types.INIT + TRYOPEN = types.TRYOPEN + OPEN = types.OPEN + StateUninitialized = types.StateUninitialized + StateInit = types.StateInit + StateTryOpen = types.StateTryOpen + StateOpen = types.StateOpen + StateClosed = types.StateClosed + AttributeKeySenderPort = types.AttributeKeySenderPort + AttributeKeyReceiverPort = types.AttributeKeyReceiverPort + AttributeKeyChannelID = types.AttributeKeyChannelID + AttributeKeySequence = types.AttributeKeySequence + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryAllChannels = types.QueryAllChannels + QueryChannel = types.QueryChannel ) var ( // functions aliases - NewKeeper = keeper.NewKeeper - QuerierChannels = keeper.QuerierChannels - QuerierChannel = keeper.QuerierChannel - NewChannel = types.NewChannel - NewCounterparty = types.NewCounterparty - OrderFromString = types.OrderFromString - StateFromString = types.StateFromString - RegisterCodec = types.RegisterCodec - ErrChannelExists = types.ErrChannelExists - ErrChannelNotFound = types.ErrChannelNotFound - ErrInvalidCounterpartyChannel = types.ErrInvalidCounterpartyChannel - ErrChannelCapabilityNotFound = types.ErrChannelCapabilityNotFound - ErrInvalidPacket = types.ErrInvalidPacket - ErrSequenceNotFound = types.ErrSequenceNotFound - ErrPacketTimeout = types.ErrPacketTimeout - ErrInvalidChannel = types.ErrInvalidChannel - ErrInvalidChannelState = types.ErrInvalidChannelState - ChannelPath = types.ChannelPath - ChannelCapabilityPath = types.ChannelCapabilityPath - NextSequenceSendPath = types.NextSequenceSendPath - NextSequenceRecvPath = types.NextSequenceRecvPath - PacketCommitmentPath = types.PacketCommitmentPath - PacketAcknowledgementPath = types.PacketAcknowledgementPath - KeyChannel = types.KeyChannel - KeyChannelCapabilityPath = types.KeyChannelCapabilityPath - KeyNextSequenceSend = types.KeyNextSequenceSend - KeyNextSequenceRecv = types.KeyNextSequenceRecv - KeyPacketCommitment = types.KeyPacketCommitment - KeyPacketAcknowledgement = types.KeyPacketAcknowledgement - NewMsgChannelOpenInit = types.NewMsgChannelOpenInit - NewMsgChannelOpenTry = types.NewMsgChannelOpenTry - NewMsgChannelOpenAck = types.NewMsgChannelOpenAck - NewMsgChannelOpenConfirm = types.NewMsgChannelOpenConfirm - NewMsgChannelCloseInit = types.NewMsgChannelCloseInit - NewMsgChannelCloseConfirm = types.NewMsgChannelCloseConfirm - NewPacket = types.NewPacket - NewOpaquePacket = types.NewOpaquePacket - NewChannelResponse = types.NewChannelResponse - NewQueryChannelParams = types.NewQueryChannelParams + NewKeeper = keeper.NewKeeper + QuerierChannels = keeper.QuerierChannels + QuerierChannel = keeper.QuerierChannel + NewChannel = types.NewChannel + NewCounterparty = types.NewCounterparty + OrderFromString = types.OrderFromString + StateFromString = types.StateFromString + RegisterCodec = types.RegisterCodec + ErrChannelExists = types.ErrChannelExists + ErrChannelNotFound = types.ErrChannelNotFound + ErrInvalidCounterparty = types.ErrInvalidCounterparty + ErrChannelCapabilityNotFound = types.ErrChannelCapabilityNotFound + ErrInvalidPacket = types.ErrInvalidPacket + ErrSequenceSendNotFound = types.ErrSequenceSendNotFound + ErrSequenceReceiveNotFound = types.ErrSequenceReceiveNotFound + ErrPacketTimeout = types.ErrPacketTimeout + ErrInvalidChannel = types.ErrInvalidChannel + ErrInvalidChannelState = types.ErrInvalidChannelState + ChannelPath = types.ChannelPath + ChannelCapabilityPath = types.ChannelCapabilityPath + NextSequenceSendPath = types.NextSequenceSendPath + NextSequenceRecvPath = types.NextSequenceRecvPath + PacketCommitmentPath = types.PacketCommitmentPath + PacketAcknowledgementPath = types.PacketAcknowledgementPath + KeyChannel = types.KeyChannel + KeyChannelCapabilityPath = types.KeyChannelCapabilityPath + KeyNextSequenceSend = types.KeyNextSequenceSend + KeyNextSequenceRecv = types.KeyNextSequenceRecv + KeyPacketCommitment = types.KeyPacketCommitment + KeyPacketAcknowledgement = types.KeyPacketAcknowledgement + NewMsgChannelOpenInit = types.NewMsgChannelOpenInit + NewMsgChannelOpenTry = types.NewMsgChannelOpenTry + NewMsgChannelOpenAck = types.NewMsgChannelOpenAck + NewMsgChannelOpenConfirm = types.NewMsgChannelOpenConfirm + NewMsgChannelCloseInit = types.NewMsgChannelCloseInit + NewMsgChannelCloseConfirm = types.NewMsgChannelCloseConfirm + NewPacket = types.NewPacket + NewOpaquePacket = types.NewOpaquePacket + NewChannelResponse = types.NewChannelResponse + NewQueryChannelParams = types.NewQueryChannelParams // variable aliases SubModuleCdc = types.SubModuleCdc diff --git a/x/ibc/04-channel/client/cli/cli.go b/x/ibc/04-channel/client/cli/cli.go index 35bd02203a1d..7c24dff1e95f 100644 --- a/x/ibc/04-channel/client/cli/cli.go +++ b/x/ibc/04-channel/client/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) @@ -15,7 +15,7 @@ func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { DisableFlagParsing: true, } - ics04ChannelQueryCmd.AddCommand(client.GetCommands( + ics04ChannelQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryChannel(storeKey, cdc), )...) @@ -29,7 +29,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Short: "IBC channel transaction subcommands", } - ics04ChannelTxCmd.AddCommand(client.PostCommands( + ics04ChannelTxCmd.AddCommand(flags.PostCommands( GetMsgChannelOpenInitCmd(storeKey, cdc), GetMsgChannelOpenTryCmd(storeKey, cdc), GetMsgChannelOpenAckCmd(storeKey, cdc), diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index 0084f57376a1..e7e9568e4add 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -3,13 +3,13 @@ package utils import ( abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // QueryPacket returns a packet from the store func QueryPacket( - ctx client.CLIContext, portID, channelID string, sequence, timeout uint64, prove bool, + ctx context.CLIContext, portID, channelID string, sequence, timeout uint64, prove bool, ) (types.PacketResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", @@ -46,7 +46,7 @@ func QueryPacket( // QueryChannel queries the store to get a channel and a merkle proof. func QueryChannel( - ctx client.CLIContext, portID, channelID string, prove bool, + ctx context.CLIContext, portID, channelID string, prove bool, ) (types.ChannelResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", diff --git a/x/ibc/04-channel/handler.go b/x/ibc/04-channel/handler.go index 31c97b668e1a..fb35ef8e5fbe 100644 --- a/x/ibc/04-channel/handler.go +++ b/x/ibc/04-channel/handler.go @@ -7,13 +7,13 @@ import ( ) // HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit -func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenInit) sdk.Result { +func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenInit) (*sdk.Result, error) { err := k.ChanOpenInit( ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, msg.Channel.Counterparty, msg.Channel.Version, ) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -29,16 +29,18 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCha ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry -func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenTry) sdk.Result { +func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenTry) (*sdk.Result, error) { err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, ) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -55,16 +57,18 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck -func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenAck) sdk.Result { +func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenAck) (*sdk.Result, error) { err := k.ChanOpenAck( ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight, ) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -80,14 +84,16 @@ func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelOpenConfirm defines the sdk.Handler for MsgChannelOpenConfirm -func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenConfirm) sdk.Result { +func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenConfirm) (*sdk.Result, error) { err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofAck, msg.ProofHeight) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -103,14 +109,16 @@ func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Msg ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelCloseInit defines the sdk.Handler for MsgChannelCloseInit -func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseInit) sdk.Result { +func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseInit) (*sdk.Result, error) { err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -126,14 +134,16 @@ func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCh ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgChannelCloseConfirm defines the sdk.Handler for MsgChannelCloseConfirm -func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseConfirm) sdk.Result { +func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseConfirm) (*sdk.Result, error) { err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofInit, msg.ProofHeight) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -149,5 +159,7 @@ func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Ms ), }) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index 5deef767e415..c09dac9344f7 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -2,11 +2,12 @@ package keeper import ( "errors" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -38,18 +39,18 @@ func (k Keeper) ChanOpenInit( // TODO: abortTransactionUnless(validateChannelIdentifier(portIdentifier, channelIdentifier)) _, found := k.GetChannel(ctx, portID, channelID) if found { - return types.ErrChannelExists(k.codespace, channelID) + return sdkerrors.Wrap(types.ErrChannelExists, channelID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.State == connection.UNINITIALIZED { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state cannot be NONE"), + return sdkerrors.Wrap( + connection.ErrInvalidConnectionState, + "connection state cannot be UNINITIALIZED", ) } @@ -58,7 +59,7 @@ func (k Keeper) ChanOpenInit( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } */ @@ -88,25 +89,25 @@ func (k Keeper) ChanOpenTry( ) error { _, found := k.GetChannel(ctx, portID, channelID) if found { - return types.ErrChannelExists(k.codespace, channelID) + return sdkerrors.Wrap(types.ErrChannelExists, channelID) } // TODO: Maybe not right key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, connectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -130,7 +131,7 @@ func (k Keeper) ChanOpenTry( bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) if err != nil { - return errors.New("failed to marshal expected channel") + return err } if !k.connectionKeeper.VerifyMembership( @@ -138,7 +139,7 @@ func (k Keeper) ChanOpenTry( types.ChannelPath(counterparty.PortID, counterparty.ChannelID), bz, ) { - return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return sdkerrors.Wrap(types.ErrInvalidCounterparty, "channel membership verification failed") } k.SetChannel(ctx, portID, channelID, channel) @@ -162,13 +163,13 @@ func (k Keeper) ChanOpenAck( ) error { channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return types.ErrChannelNotFound(k.codespace, portID, channelID) + return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } if channel.State != types.INIT { - return types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not INIT (got %s)", channel.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not INIT (got %s)", channel.State.String(), ) } @@ -176,18 +177,18 @@ func (k Keeper) ChanOpenAck( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -206,7 +207,7 @@ func (k Keeper) ChanOpenAck( bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) if err != nil { - return errors.New("failed to marshal expected channel") + return err } if !k.connectionKeeper.VerifyMembership( @@ -214,7 +215,9 @@ func (k Keeper) ChanOpenAck( types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), bz, ) { - return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return sdkerrors.Wrap( + types.ErrInvalidCounterparty, "channel membership verification failed", + ) } channel.State = types.OPEN @@ -235,13 +238,13 @@ func (k Keeper) ChanOpenConfirm( ) error { channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return types.ErrChannelNotFound(k.codespace, portID, channelID) + return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } if channel.State != types.TRYOPEN { - return types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPENTRY (got %s)", channel.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPENTRY (got %s)", channel.State.String(), ) } @@ -249,18 +252,18 @@ func (k Keeper) ChanOpenConfirm( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -278,7 +281,7 @@ func (k Keeper) ChanOpenConfirm( bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) if err != nil { - return errors.New("failed to marshal expected channel") + return err } if !k.connectionKeeper.VerifyMembership( @@ -286,7 +289,7 @@ func (k Keeper) ChanOpenConfirm( types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), bz, ) { - return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return sdkerrors.Wrap(types.ErrInvalidCounterparty, "channel membership verification failed") } channel.State = types.OPEN @@ -311,27 +314,27 @@ func (k Keeper) ChanCloseInit( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return types.ErrChannelNotFound(k.codespace, portID, channelID) + return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } if channel.State == types.CLOSED { - return types.ErrInvalidChannelState(k.codespace, "channel is already CLOSED") + return sdkerrors.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -354,27 +357,27 @@ func (k Keeper) ChanCloseConfirm( key := sdk.NewKVStoreKey(portID) if !k.portKeeper.Authenticate(key, portID) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, portID) } channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return types.ErrChannelNotFound(k.codespace, portID, channelID) + return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } if channel.State == types.CLOSED { - return types.ErrInvalidChannelState(k.codespace, "channel is already CLOSED") + return sdkerrors.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } @@ -400,7 +403,7 @@ func (k Keeper) ChanCloseConfirm( types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), bz, ) { - return types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return sdkerrors.Wrap(types.ErrInvalidCounterparty, "channel membership verification failed") } channel.State = types.CLOSED diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index 5d72ab76cc60..92b1a3bca1f1 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -16,7 +16,6 @@ import ( type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec - codespace sdk.CodespaceType clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper portKeeper types.PortKeeper @@ -24,14 +23,13 @@ type Keeper struct { // NewKeeper creates a new IBC channel Keeper instance func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + cdc *codec.Codec, key sdk.StoreKey, clientKeeper types.ClientKeeper, connectionKeeper types.ConnectionKeeper, portKeeper types.PortKeeper, ) Keeper { return Keeper{ storeKey: key, cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/channel", clientKeeper: clientKeeper, connectionKeeper: connectionKeeper, portKeeper: portKeeper, diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 515b7ecdf107..2703f283a814 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -3,13 +3,14 @@ package keeper import ( "bytes" "errors" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -34,51 +35,50 @@ func (k Keeper) CleanupPacket( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } if channel.State != types.OPEN { - return nil, types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + return nil, sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), ) } _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelCapabilityNotFound(k.codespace) + return nil, types.ErrChannelCapabilityNotFound } if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return nil, errors.New("port is not valid") + return nil, sdkerrors.Wrapf(port.ErrInvalidPort, "invalid source port: %s", packet.GetSourcePort()) } if packet.GetDestChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if packet.GetDestPort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf(types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, ) } if nextSequenceRecv >= packet.GetSequence() { - return nil, types.ErrInvalidPacket(k.codespace, "packet already received") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet already received") } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } var ok bool @@ -96,11 +96,11 @@ func (k Keeper) CleanupPacket( acknowledgement, ) default: - panic(fmt.Sprintf("invalid channel ordering type %v", channel.Ordering)) + panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) } if !ok { - return nil, types.ErrInvalidPacket(k.codespace, "packet verification failed") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet verification failed") } k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) @@ -121,64 +121,64 @@ func (k Keeper) SendPacket( channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } if channel.State == types.CLOSED { - return types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel is CLOSED (got %s)", channel.State.String()), + return sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel is CLOSED (got %s)", channel.State.String(), ) } if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return errors.New("port is not valid") + return sdkerrors.Wrap(port.ErrInvalidPort, packet.GetSourcePort()) } if packet.GetDestPort() != channel.Counterparty.PortID { - return types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + return sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, ) } if packet.GetDestChannel() != channel.Counterparty.ChannelID { - return types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + return sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State == connection.UNINITIALIZED { - return connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection is closed (i.e NONE)"), + return sdkerrors.Wrap( + connection.ErrInvalidConnectionState, + "connection is closed (i.e NONE)", ) } - consensusState, found := k.clientKeeper.GetConsensusState(ctx, connectionEnd.ClientID) + _, found = k.clientKeeper.GetConsensusState(ctx, connectionEnd.ClientID) if !found { - return client.ErrConsensusStateNotFound(k.codespace) + return client.ErrConsensusStateNotFound } - if consensusState.GetHeight() >= packet.GetTimeoutHeight() { - return types.ErrPacketTimeout(k.codespace) + if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { + return types.ErrPacketTimeout } nextSequenceSend, found := k.GetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return types.ErrSequenceNotFound(k.codespace, "send") + return types.ErrSequenceSendNotFound } if packet.GetSequence() != nextSequenceSend { - return types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet sequence ≠ next send sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceSend), + return sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet sequence ≠ next send sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceSend, ) } @@ -202,49 +202,49 @@ func (k Keeper) RecvPacket( channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetDestPort(), packet.GetDestChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetDestChannel()) } if channel.State != types.OPEN { - return nil, types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + return nil, sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), ) } if !k.portKeeper.Authenticate(portCapability, packet.GetDestPort()) { - return nil, errors.New("port is not valid") + return nil, sdkerrors.Wrap(port.ErrInvalidPort, packet.GetDestPort()) } // packet must come from the channel's counterparty if packet.GetSourcePort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID, ) } if packet.GetSourceChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return nil, connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return nil, sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { - return nil, types.ErrPacketTimeout(k.codespace) + return nil, types.ErrPacketTimeout } if !k.connectionKeeper.VerifyMembership( @@ -265,13 +265,13 @@ func (k Keeper) RecvPacket( if channel.Ordering == types.ORDERED { nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { - return nil, types.ErrSequenceNotFound(k.codespace, "receive") + return nil, types.ErrSequenceReceiveNotFound } if packet.GetSequence() != nextSequenceRecv { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv, ) } @@ -298,13 +298,13 @@ func (k Keeper) AcknowledgePacket( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } if channel.State != types.OPEN { - return nil, types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + return nil, sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), ) } @@ -314,34 +314,34 @@ func (k Keeper) AcknowledgePacket( // packet must come from the channel's counterparty if packet.GetSourcePort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID, ) } if packet.GetSourceChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.State != connection.OPEN { - return nil, connection.ErrInvalidConnectionState( - k.codespace, - fmt.Sprintf("connection state is not OPEN (got %s)", connectionEnd.State.String()), + return nil, sdkerrors.Wrapf( + connection.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectionEnd.State.String(), ) } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } if !k.connectionKeeper.VerifyMembership( diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go index 8aef90c879ad..8c8cac783cec 100644 --- a/x/ibc/04-channel/keeper/querier.go +++ b/x/ibc/04-channel/keeper/querier.go @@ -20,7 +20,7 @@ func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) if !found { - return nil, types.ErrChannelNotFound(k.codespace, params.PortID, params.ChannelID) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, params.ChannelID) } bz, err := codec.MarshalJSONIndent(k.cdc, channel) diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index 3ae481373de3..af54040dad2c 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -3,9 +3,9 @@ package keeper import ( "bytes" "errors" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" @@ -27,19 +27,19 @@ func (k Keeper) TimeoutPacket( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } if channel.State != types.OPEN { - return nil, types.ErrInvalidChannelState( - k.codespace, - fmt.Sprintf("channel state is not OPEN (got %s)", channel.State.String()), + return nil, sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), ) } _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelCapabilityNotFound(k.codespace) + return nil, types.ErrChannelCapabilityNotFound } if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { @@ -47,35 +47,35 @@ func (k Keeper) TimeoutPacket( } if packet.GetDestChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if packet.GetDestPort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, ) } if proofHeight < packet.GetTimeoutHeight() { - return nil, types.ErrPacketTimeout(k.codespace) + return nil, types.ErrPacketTimeout } if nextSequenceRecv >= packet.GetSequence() { - return nil, types.ErrInvalidPacket(k.codespace, "packet already received") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet already received") } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } var ok bool @@ -92,11 +92,11 @@ func (k Keeper) TimeoutPacket( types.PacketAcknowledgementPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), ) default: - panic(fmt.Sprintf("invalid channel ordering type %v", channel.Ordering)) + panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) } if !ok { - return nil, types.ErrInvalidPacket(k.codespace, "packet verification failed") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet verification failed") } k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) @@ -122,12 +122,12 @@ func (k Keeper) TimeoutOnClose( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelNotFound(k.codespace, packet.GetSourcePort(), packet.GetSourceChannel()) + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, types.ErrChannelCapabilityNotFound(k.codespace) + return nil, types.ErrChannelCapabilityNotFound } if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { @@ -135,27 +135,27 @@ func (k Keeper) TimeoutOnClose( } if packet.GetDestChannel() != channel.Counterparty.ChannelID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, ) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, connection.ErrConnectionNotFound(k.codespace, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } if packet.GetDestPort() != channel.Counterparty.PortID { - return nil, types.ErrInvalidPacket( - k.codespace, - fmt.Sprintf("packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID), + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, ) } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, types.ErrInvalidPacket(k.codespace, "packet hasn't been sent") + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } counterpartyHops, found := k.CounterpartyHops(ctx, channel) @@ -179,7 +179,10 @@ func (k Keeper) TimeoutOnClose( types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), bz, ) { - return nil, types.ErrInvalidCounterpartyChannel(k.codespace, "channel membership verification failed") + return nil, sdkerrors.Wrap( + types.ErrInvalidCounterparty, + "channel membership verification failed", + ) } if !k.connectionKeeper.VerifyNonMembership( diff --git a/x/ibc/04-channel/types/channel.go b/x/ibc/04-channel/types/channel.go index 1250d1208808..ae38cb2212df 100644 --- a/x/ibc/04-channel/types/channel.go +++ b/x/ibc/04-channel/types/channel.go @@ -2,11 +2,11 @@ package types import ( "encoding/json" - "fmt" "strings" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) type Channel struct { @@ -34,25 +34,25 @@ func NewChannel( // ValidateBasic performs a basic validation of the channel fields func (ch Channel) ValidateBasic() error { if ch.State.String() == "" { - return ErrInvalidChannelState( - DefaultCodespace, - "channel order should be either 'ORDERED' or 'UNORDERED'", - ) + return sdkerrors.Wrap(ErrInvalidChannel, ErrInvalidChannelState.Error()) } if ch.Ordering.String() == "" { - return ErrInvalidChannel( - DefaultCodespace, - "channel order should be either 'ORDERED' or 'UNORDERED'", - ) + return sdkerrors.Wrap(ErrInvalidChannel, ErrInvalidChannelOrdering.Error()) } if len(ch.ConnectionHops) != 1 { - return ErrInvalidChannel(DefaultCodespace, "IBC v1 only supports one connection hop") + return sdkerrors.Wrap(ErrInvalidChannel, "IBC v1 only supports one connection hop") } if err := host.DefaultConnectionIdentifierValidator(ch.ConnectionHops[0]); err != nil { - return sdkerrors.Wrap(err, "invalid connection hop ID") + return sdkerrors.Wrap( + ErrInvalidChannel, + sdkerrors.Wrap(err, "invalid connection hop ID").Error(), + ) } if strings.TrimSpace(ch.Version) == "" { - return ErrInvalidChannel(DefaultCodespace, "channel version can't be blank") + return sdkerrors.Wrap( + ErrInvalidChannel, + sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "channel version can't be blank").Error(), + ) } return ch.Counterparty.ValidateBasic() } @@ -74,10 +74,16 @@ func NewCounterparty(portID, channelID string) Counterparty { // ValidateBasic performs a basic validation check of the identifiers func (c Counterparty) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(c.PortID); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty connection ID") + return sdkerrors.Wrap( + ErrInvalidCounterparty, + sdkerrors.Wrap(err, "invalid counterparty connection ID").Error(), + ) } if err := host.DefaultChannelIdentifierValidator(c.ChannelID); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty client ID") + return sdkerrors.Wrap( + ErrInvalidCounterparty, + sdkerrors.Wrap(err, "invalid counterparty client ID").Error(), + ) } return nil } @@ -126,7 +132,7 @@ func (o *Order) UnmarshalJSON(data []byte) error { order := OrderFromString(s) if order == 0 { - return fmt.Errorf("invalid channel ordering '%s'", s) + return sdkerrors.Wrap(ErrInvalidChannelOrdering, s) } *o = order diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go index 318c78017d34..40e526476eae 100644 --- a/x/ibc/04-channel/types/errors.go +++ b/x/ibc/04-channel/types/errors.go @@ -1,104 +1,20 @@ package types import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// channel error codes -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodeChannelExists sdk.CodeType = 219 - CodeChannelNotFound sdk.CodeType = 220 - CodeInvalidCounterpartyChannel sdk.CodeType = 221 - CodeChannelCapabilityNotFound sdk.CodeType = 222 - CodeInvalidPacket sdk.CodeType = 223 - CodeSequenceNotFound sdk.CodeType = 224 - CodePacketTimeout sdk.CodeType = 225 - CodeInvalidChannel sdk.CodeType = 226 - CodeInvalidChannelState sdk.CodeType = 227 +// IBC channel sentinel errors +var ( + ErrChannelExists = sdkerrors.Register(SubModuleName, 1, "channel already exists") + ErrChannelNotFound = sdkerrors.Register(SubModuleName, 2, "channel not found") + ErrInvalidChannel = sdkerrors.Register(SubModuleName, 3, "invalid channel") + ErrInvalidChannelState = sdkerrors.Register(SubModuleName, 4, "invalid channel state") + ErrInvalidChannelOrdering = sdkerrors.Register(SubModuleName, 5, "invalid channel ordering") + ErrInvalidCounterparty = sdkerrors.Register(SubModuleName, 6, "invalid counterparty channel") + ErrChannelCapabilityNotFound = sdkerrors.Register(SubModuleName, 7, "channel capability not found") + ErrSequenceSendNotFound = sdkerrors.Register(SubModuleName, 8, "sequence send not found") + ErrSequenceReceiveNotFound = sdkerrors.Register(SubModuleName, 9, "sequence receive not found") + ErrInvalidPacket = sdkerrors.Register(SubModuleName, 10, "invalid packet") + ErrPacketTimeout = sdkerrors.Register(SubModuleName, 11, "packet timeout") ) - -// ErrChannelExists implements sdk.Error -func ErrChannelExists(codespace sdk.CodespaceType, channelID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeChannelExists), - fmt.Sprintf("channel with ID %s already exists", channelID), - ) -} - -// ErrChannelNotFound implements sdk.Error -func ErrChannelNotFound(codespace sdk.CodespaceType, portID, channelID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeChannelNotFound), - fmt.Sprintf("channel with ID %s on port %s not found", channelID, portID), - ) -} - -// ErrInvalidCounterpartyChannel implements sdk.Error -func ErrInvalidCounterpartyChannel(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidCounterpartyChannel), - msg, - ) -} - -// ErrChannelCapabilityNotFound implements sdk.Error -func ErrChannelCapabilityNotFound(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodeChannelCapabilityNotFound), - "channel capability key not found", - ) -} - -// ErrInvalidPacket implements sdk.Error -func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidPacket), - msg, - ) -} - -// ErrSequenceNotFound implements sdk.Error -func ErrSequenceNotFound(codespace sdk.CodespaceType, seqType string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeSequenceNotFound), - fmt.Sprintf("next %s sequence counter not found", seqType), - ) -} - -// ErrPacketTimeout implements sdk.Error -func ErrPacketTimeout(codespace sdk.CodespaceType) error { - return sdkerrors.New( - string(codespace), - uint32(CodePacketTimeout), - "packet timeout", - ) -} - -// ErrInvalidChannel implements sdk.Error -func ErrInvalidChannel(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidChannel), - msg, - ) -} - -// ErrInvalidChannelState implements sdk.Error -func ErrInvalidChannelState(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidChannelState), - msg, - ) -} diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index 16a7a1943999..d0a9e71955ba 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -45,15 +45,15 @@ func (msg MsgChannelOpenInit) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelOpenInit) ValidateBasic() sdk.Error { +func (msg MsgChannelOpenInit) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } // Signer can be empty - return sdk.ConvertError(msg.Channel.ValidateBasic()) + return msg.Channel.ValidateBasic() } // GetSignBytes implements sdk.Msg @@ -108,24 +108,27 @@ func (msg MsgChannelOpenTry) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelOpenTry) ValidateBasic() sdk.Error { +func (msg MsgChannelOpenTry) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } if strings.TrimSpace(msg.CounterpartyVersion) == "" { - return sdk.ConvertError(ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank")) + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty version cannot be blank") } if msg.ProofInit == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofInit.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof init cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } // Signer can be empty - return sdk.ConvertError(msg.Channel.ValidateBasic()) + return msg.Channel.ValidateBasic() } // GetSignBytes implements sdk.Msg @@ -175,21 +178,24 @@ func (msg MsgChannelOpenAck) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelOpenAck) ValidateBasic() sdk.Error { +func (msg MsgChannelOpenAck) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } if strings.TrimSpace(msg.CounterpartyVersion) == "" { - return sdk.ConvertError(ErrInvalidCounterpartyChannel(DefaultCodespace, "counterparty version cannot be blank")) + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty version cannot be blank") } if msg.ProofTry == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofTry.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof try cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } // Signer can be empty return nil @@ -240,18 +246,21 @@ func (msg MsgChannelOpenConfirm) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelOpenConfirm) ValidateBasic() sdk.Error { +func (msg MsgChannelOpenConfirm) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } if msg.ProofAck == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofAck.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } // Signer can be empty return nil @@ -295,12 +304,12 @@ func (msg MsgChannelCloseInit) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelCloseInit) ValidateBasic() sdk.Error { +func (msg MsgChannelCloseInit) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } // Signer can be empty return nil @@ -351,18 +360,21 @@ func (msg MsgChannelCloseConfirm) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgChannelCloseConfirm) ValidateBasic() sdk.Error { +func (msg MsgChannelCloseConfirm) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.PortID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid port ID")) + return sdkerrors.Wrap(err, "invalid port ID") } if err := host.DefaultChannelIdentifierValidator(msg.ChannelID); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid channel ID")) + return sdkerrors.Wrap(err, "invalid channel ID") } if msg.ProofInit == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.ProofInit.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof init cannot be nil") } if msg.ProofHeight == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "proof height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } // Signer can be empty return nil diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index 3754ea4efa1a..2165f8c4eb40 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -1,10 +1,17 @@ package types import ( + "fmt" "testing" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -36,8 +43,39 @@ var ( addr = sdk.AccAddress("testaddr") ) +type MsgTestSuite struct { + suite.Suite + + proof commitment.Proof +} + +func (suite *MsgTestSuite) SetupTest() { + db := dbm.NewMemDB() + store := rootmulti.NewStore(db) + storeKey := storetypes.NewKVStoreKey("iavlStoreKey") + + store.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) + store.LoadVersion(0) + iavlStore := store.GetCommitStore(storeKey).(*iavl.Store) + + iavlStore.Set([]byte("KEY"), []byte("VALUE")) + _ = store.Commit() + + res := store.Query(abci.RequestQuery{ + Path: fmt.Sprintf("/%s/key", storeKey.Name()), // required path to get key/value+proof + Data: []byte("KEY"), + Prove: true, + }) + + suite.proof = commitment.Proof{Proof: res.Proof} +} + +func TestMsgTestSuite(t *testing.T) { + suite.Run(t, new(MsgTestSuite)) +} + // TestMsgChannelOpenInit tests ValidateBasic for MsgChannelOpenInit -func TestMsgChannelOpenInit(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelOpenInit() { testMsgs := []MsgChannelOpenInit{ NewMsgChannelOpenInit("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id @@ -81,34 +119,34 @@ func TestMsgChannelOpenInit(t *testing.T) { for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelOpenTry tests ValidateBasic for MsgChannelOpenTry -func TestMsgChannelOpenTry(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelOpenTry() { testMsgs := []MsgChannelOpenTry{ - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // valid msg - NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short port id - NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long port id - NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenTry("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short channel id - NewMsgChannelOpenTry("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long channel id - NewMsgChannelOpenTry("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", proof, 1, addr), // empty counterparty version - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty proof - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 0, addr), // proof height is zero - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // invalid channel order - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection hops more than 1 - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too short connection id - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // too long connection id - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // connection id contains non-alpha - NewMsgChannelOpenTry("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", proof, 1, addr), // empty channel version - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", proof, 1, addr), // invalid counterparty port id - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", proof, 1, addr), // invalid counterparty channel id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // valid msg + NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short port id + NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long port id + NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenTry("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short channel id + NewMsgChannelOpenTry("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long channel id + NewMsgChannelOpenTry("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", suite.proof, 1, addr), // empty counterparty version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty suite.proof + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 0, addr), // suite.proof height is zero + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // invalid channel order + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // connection hops more than 1 + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // connection id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // empty channel version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", suite.proof, 1, addr), // invalid counterparty port id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", suite.proof, 1, addr), // invalid counterparty channel id } testCases := []struct { @@ -139,26 +177,27 @@ func TestMsgChannelOpenTry(t *testing.T) { for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelOpenAck tests ValidateBasic for MsgChannelOpenAck -func TestMsgChannelOpenAck(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelOpenAck() { testMsgs := []MsgChannelOpenAck{ - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", proof, 1, addr), // valid msg - NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", proof, 1, addr), // too short port id - NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", proof, 1, addr), // too long port id - NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenAck("testportid", invalidShortChannel, "1.0", proof, 1, addr), // too short channel id - NewMsgChannelOpenAck("testportid", invalidLongChannel, "1.0", proof, 1, addr), // too long channel id - NewMsgChannelOpenAck("testportid", invalidChannel, "1.0", proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenAck("testportid", "testchannel", "", proof, 1, addr), // empty counterparty version - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", nil, 1, addr), // empty proof - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", proof, 0, addr), // proof height is zero + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", suite.proof, 1, addr), // valid msg + NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", suite.proof, 1, addr), // too short port id + NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", suite.proof, 1, addr), // too long port id + NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenAck("testportid", invalidShortChannel, "1.0", suite.proof, 1, addr), // too short channel id + NewMsgChannelOpenAck("testportid", invalidLongChannel, "1.0", suite.proof, 1, addr), // too long channel id + NewMsgChannelOpenAck("testportid", invalidChannel, "1.0", suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenAck("testportid", "testchannel", "", suite.proof, 1, addr), // empty counterparty version + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", commitment.Proof{Proof: nil}, 1, addr), // empty proof + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", suite.proof, 0, addr), // proof height is zero } testCases := []struct { @@ -175,31 +214,33 @@ func TestMsgChannelOpenAck(t *testing.T) { {testMsgs[6], false, "channel id contains non-alpha"}, {testMsgs[7], false, "empty counterparty version"}, {testMsgs[8], false, "empty proof"}, - {testMsgs[9], false, "proof height is zero"}, + {testMsgs[9], false, "empty proof"}, + {testMsgs[10], false, "proof height is zero"}, } for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelOpenConfirm tests ValidateBasic for MsgChannelOpenConfirm -func TestMsgChannelOpenConfirm(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelOpenConfirm() { testMsgs := []MsgChannelOpenConfirm{ - NewMsgChannelOpenConfirm("testportid", "testchannel", proof, 1, addr), // valid msg - NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id - NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id - NewMsgChannelOpenConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenConfirm("testportid", invalidShortChannel, proof, 1, addr), // too short channel id - NewMsgChannelOpenConfirm("testportid", invalidLongChannel, proof, 1, addr), // too long channel id - NewMsgChannelOpenConfirm("testportid", invalidChannel, proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenConfirm("testportid", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelOpenConfirm("testportid", "testchannel", proof, 0, addr), // proof height is zero + NewMsgChannelOpenConfirm("testportid", "testchannel", suite.proof, 1, addr), // valid msg + NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", suite.proof, 1, addr), // too short port id + NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", suite.proof, 1, addr), // too long port id + NewMsgChannelOpenConfirm(invalidPort, "testchannel", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenConfirm("testportid", invalidShortChannel, suite.proof, 1, addr), // too short channel id + NewMsgChannelOpenConfirm("testportid", invalidLongChannel, suite.proof, 1, addr), // too long channel id + NewMsgChannelOpenConfirm("testportid", invalidChannel, suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testportid", "testchannel", commitment.Proof{Proof: nil}, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testportid", "testchannel", suite.proof, 0, addr), // proof height is zero } testCases := []struct { @@ -215,21 +256,22 @@ func TestMsgChannelOpenConfirm(t *testing.T) { {testMsgs[5], false, "too long channel id"}, {testMsgs[6], false, "channel id contains non-alpha"}, {testMsgs[7], false, "empty proof"}, - {testMsgs[8], false, "proof height is zero"}, + {testMsgs[8], false, "empty proof"}, + {testMsgs[9], false, "proof height is zero"}, } for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelCloseInit tests ValidateBasic for MsgChannelCloseInit -func TestMsgChannelCloseInit(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelCloseInit() { testMsgs := []MsgChannelCloseInit{ NewMsgChannelCloseInit("testportid", "testchannel", addr), // valid msg NewMsgChannelCloseInit(invalidShortPort, "testchannel", addr), // too short port id @@ -257,25 +299,26 @@ func TestMsgChannelCloseInit(t *testing.T) { for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } // TestMsgChannelCloseConfirm tests ValidateBasic for MsgChannelCloseConfirm -func TestMsgChannelCloseConfirm(t *testing.T) { +func (suite *MsgTestSuite) TestMsgChannelCloseConfirm() { testMsgs := []MsgChannelCloseConfirm{ - NewMsgChannelCloseConfirm("testportid", "testchannel", proof, 1, addr), // valid msg - NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", proof, 1, addr), // too short port id - NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", proof, 1, addr), // too long port id - NewMsgChannelCloseConfirm(invalidPort, "testchannel", proof, 1, addr), // port id contains non-alpha - NewMsgChannelCloseConfirm("testportid", invalidShortChannel, proof, 1, addr), // too short channel id - NewMsgChannelCloseConfirm("testportid", invalidLongChannel, proof, 1, addr), // too long channel id - NewMsgChannelCloseConfirm("testportid", invalidChannel, proof, 1, addr), // channel id contains non-alpha - NewMsgChannelCloseConfirm("testportid", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelCloseConfirm("testportid", "testchannel", proof, 0, addr), // proof height is zero + NewMsgChannelCloseConfirm("testportid", "testchannel", suite.proof, 1, addr), // valid msg + NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", suite.proof, 1, addr), // too short port id + NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", suite.proof, 1, addr), // too long port id + NewMsgChannelCloseConfirm(invalidPort, "testchannel", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelCloseConfirm("testportid", invalidShortChannel, suite.proof, 1, addr), // too short channel id + NewMsgChannelCloseConfirm("testportid", invalidLongChannel, suite.proof, 1, addr), // too long channel id + NewMsgChannelCloseConfirm("testportid", invalidChannel, suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelCloseConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testportid", "testchannel", commitment.Proof{Proof: nil}, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testportid", "testchannel", suite.proof, 0, addr), // proof height is zero } testCases := []struct { @@ -291,15 +334,16 @@ func TestMsgChannelCloseConfirm(t *testing.T) { {testMsgs[5], false, "too long channel id"}, {testMsgs[6], false, "channel id contains non-alpha"}, {testMsgs[7], false, "empty proof"}, - {testMsgs[8], false, "proof height is zero"}, + {testMsgs[8], false, "empty proof"}, + {testMsgs[9], false, "proof height is zero"}, } for i, tc := range testCases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go index 8cfadf458487..7d8242d8db30 100644 --- a/x/ibc/04-channel/types/packet.go +++ b/x/ibc/04-channel/types/packet.go @@ -1,8 +1,7 @@ package types import ( - "fmt" - + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -11,13 +10,13 @@ var _ exported.PacketI = Packet{} // Packet defines a type that carries data across different chains through IBC type Packet struct { - Sequence uint64 `json:"sequence"` // number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. - Timeout uint64 `json:"timeout"` // indicates a consensus height on the destination chain after which the Packet will no longer be processed, and will instead count as having timed-out. - SourcePort string `json:"source_port"` // identifies the port on the sending chain. - SourceChannel string `json:"source_channel"` // identifies the channel end on the sending chain. - DestinationPort string `json:"destination_port"` // identifies the port on the receiving chain. - DestinationChannel string `json:"destination_channel"` // identifies the channel end on the receiving chain. - Data []byte `json:"data"` // opaque value which can be defined by the application logic of the associated modules. + Sequence uint64 `json:"sequence" yaml:"sequence"` // number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. + Timeout uint64 `json:"timeout" yaml:"timeout"` // indicates a consensus height on the destination chain after which the Packet will no longer be processed, and will instead count as having timed-out. + SourcePort string `json:"source_port" yaml:"source_port"` // identifies the port on the sending chain. + SourceChannel string `json:"source_channel" yaml:"source_channel"` // identifies the channel end on the sending chain. + DestinationPort string `json:"destination_port" yaml:"destination_port"` // identifies the port on the receiving chain. + DestinationChannel string `json:"destination_channel" yaml:"destination_channel"` // identifies the channel end on the receiving chain. + Data []byte `json:"data" yaml:"data"` // opaque value which can be defined by the application logic of the associated modules. } // NewPacket creates a new Packet instance @@ -26,13 +25,13 @@ func NewPacket( destinationPort, destinationChannel string, data []byte, ) Packet { return Packet{ - sequence, - timeout, - sourcePort, - sourceChannel, - destinationPort, - destinationChannel, - data, + Sequence: sequence, + Timeout: timeout, + SourcePort: sourcePort, + SourceChannel: sourceChannel, + DestinationPort: destinationPort, + DestinationChannel: destinationChannel, + Data: data, } } @@ -60,25 +59,37 @@ func (p Packet) GetData() []byte { return p.Data } // ValidateBasic implements PacketI interface func (p Packet) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(p.SourcePort); err != nil { - return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source port ID: %s", err.Error())) + return sdkerrors.Wrapf( + ErrInvalidPacket, + sdkerrors.Wrapf(err, "invalid source port ID: %s", p.SourcePort).Error(), + ) } if err := host.DefaultPortIdentifierValidator(p.DestinationPort); err != nil { - return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid destination port ID: %s", err.Error())) + return sdkerrors.Wrapf( + ErrInvalidPacket, + sdkerrors.Wrapf(err, "invalid destination port ID: %s", p.DestinationPort).Error(), + ) } if err := host.DefaultChannelIdentifierValidator(p.SourceChannel); err != nil { - return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid source channel ID: %s", err.Error())) + return sdkerrors.Wrapf( + ErrInvalidPacket, + sdkerrors.Wrapf(err, "invalid source channel ID: %s", p.SourceChannel).Error(), + ) } if err := host.DefaultChannelIdentifierValidator(p.DestinationChannel); err != nil { - return ErrInvalidPacket(DefaultCodespace, fmt.Sprintf("invalid destination channel ID: %s", err.Error())) + return sdkerrors.Wrapf( + ErrInvalidPacket, + sdkerrors.Wrapf(err, "invalid destination channel ID: %s", p.DestinationChannel).Error(), + ) } if p.Sequence == 0 { - return ErrInvalidPacket(DefaultCodespace, "packet sequence cannot be 0") + return sdkerrors.Wrap(ErrInvalidPacket, "packet sequence cannot be 0") } if p.Timeout == 0 { - return ErrPacketTimeout(DefaultCodespace) + return sdkerrors.Wrap(ErrInvalidPacket, "packet timeout cannot be 0") } if len(p.Data) == 0 { - return ErrInvalidPacket(DefaultCodespace, "packet data cannot be empty") + return sdkerrors.Wrap(ErrInvalidPacket, "packet data cannot be empty") } return nil } diff --git a/x/ibc/05-port/alias.go b/x/ibc/05-port/alias.go index ef3b6be60633..f53d7a41f9ee 100644 --- a/x/ibc/05-port/alias.go +++ b/x/ibc/05-port/alias.go @@ -12,13 +12,10 @@ import ( ) const ( - DefaultCodespace = types.DefaultCodespace - CodePortExists = types.CodePortExists - CodePortNotFound = types.CodePortNotFound - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute ) var ( diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index 3d17a6881be8..45f0817f7702 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -5,25 +5,22 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) // Keeper defines the IBC connection keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType - ports map[string]bool + storeKey sdk.StoreKey + cdc *codec.Codec + ports map[string]bool } // NewKeeper creates a new IBC connection Keeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Keeper { +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/port", - ports: make(map[string]bool), // map of capability key names to port ids + storeKey: key, + cdc: cdc, + ports: make(map[string]bool), // map of capability key names to port ids } } diff --git a/x/ibc/05-port/types/errors.go b/x/ibc/05-port/types/errors.go index d15b07bf0791..a0778ecd6b01 100644 --- a/x/ibc/05-port/types/errors.go +++ b/x/ibc/05-port/types/errors.go @@ -1,44 +1,12 @@ package types import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// port error codes -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodePortExists sdk.CodeType = 228 - CodePortNotFound sdk.CodeType = 229 - CodeInvalidPort sdk.CodeType = 230 +// IBC port sentinel errors +var ( + ErrPortExists = sdkerrors.Register(SubModuleName, 1, "port is already binded") + ErrPortNotFound = sdkerrors.Register(SubModuleName, 2, "port not found") + ErrInvalidPort = sdkerrors.Register(SubModuleName, 3, "invalid port") ) - -// ErrPortExists implements sdk.Error -func ErrPortExists(codespace sdk.CodespaceType, portID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodePortExists), - fmt.Sprintf("port with ID %s is already binded", portID), - ) -} - -// ErrPortNotFound implements sdk.Error -func ErrPortNotFound(codespace sdk.CodespaceType, portID string) error { - return sdkerrors.New( - string(codespace), - uint32(CodePortNotFound), - fmt.Sprintf("port with ID %s not found", portID), - ) -} - -// ErrInvalidPort implements sdk.Error -func ErrInvalidPort(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodePortNotFound), - msg, - ) -} diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go index ee87c56d8b3e..00333d69f4b2 100644 --- a/x/ibc/20-transfer/alias.go +++ b/x/ibc/20-transfer/alias.go @@ -13,7 +13,6 @@ import ( const ( DefaultPacketTimeout = keeper.DefaultPacketTimeout - DefaultCodespace = types.DefaultCodespace AttributeKeyReceiver = types.AttributeKeyReceiver SubModuleName = types.SubModuleName StoreKey = types.StoreKey diff --git a/x/ibc/20-transfer/client/cli/cli.go b/x/ibc/20-transfer/client/cli/cli.go index 2007ed31908d..45a41239f974 100644 --- a/x/ibc/20-transfer/client/cli/cli.go +++ b/x/ibc/20-transfer/client/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ) @@ -14,7 +14,7 @@ func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { Short: "IBC fungible token transfer query subcommands", } - ics20TransferQueryCmd.AddCommand(client.GetCommands( + ics20TransferQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryNextSequence(cdc, queryRoute), )...) @@ -28,7 +28,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { Short: "IBC fungible token transfer transaction subcommands", } - ics20TransferTxCmd.AddCommand(client.PostCommands( + ics20TransferTxCmd.AddCommand(flags.PostCommands( GetTransferTxCmd(cdc), // GetMsgRecvPacketCmd(cdc), )...) diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 731a6c27e7f5..6dfcf0470e4d 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -6,10 +6,10 @@ import ( ) // HandleMsgTransfer defines the sdk.Handler for MsgTransfer -func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Result) { +func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) { err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvent( @@ -21,14 +21,16 @@ func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (res sdk.Resu ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } // HandleMsgRecvPacket defines the sdk.Handler for MsgRecvPacket -func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (res sdk.Result) { +func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (*sdk.Result, error) { err := k.ReceivePacket(ctx, msg.Packet, msg.Proofs[0], msg.Height) if err != nil { - return sdk.ResultFromError(err) + return nil, err } ctx.EventManager().EmitEvent( @@ -39,5 +41,7 @@ func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (res sdk. ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil } diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 46ef6f08558b..d3db1ed739fc 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -160,35 +160,41 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { source := true msg := transfer.NewMsgTransfer(testPort1, testChannel1, testCoins, testAddr1, testAddr2, source) - res := transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // channel does not exist + res, err := transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // next send sequence not found + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // next send sequence not found nextSeqSend := uint64(1) suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // sender has insufficient coins + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // sender has insufficient coins _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.True(res.Code.IsOK(), "%v", res) // successfully executed + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().NoError(err) + suite.Require().NotNil(res, "%v", res) // successfully executed // test when the source is false source = false msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, source) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // incorrect denom prefix + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // incorrect denom prefix msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, source) suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) - res = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.True(res.Code.IsOK(), "%v", res) // successfully executed + res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().NoError(err) + suite.Require().NotNil(res, "%v", res) // successfully executed } func (suite *HandlerTestSuite) TestHandleRecvPacket() { @@ -205,16 +211,18 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { msg := types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - res := transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // packet membership verification failed due to invalid counterparty packet commitment + res, err := transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // packet membership verification failed due to invalid counterparty packet commitment suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) suite.updateClient() proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // invalid packet data + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // invalid packet data // test when the source is true source := true @@ -228,8 +236,9 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // invalid denom prefix + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // invalid denom prefix packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) @@ -240,8 +249,9 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.True(res.Code.IsOK(), "%v", res) // successfully executed + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().NoError(err) + suite.Require().NotNil(res, "%v", res) // successfully executed // test when the source is false source = false @@ -255,8 +265,9 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // invalid denom prefix + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // invalid denom prefix packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) @@ -267,13 +278,15 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.False(res.Code.IsOK(), "%v", res) // insufficient coins in the corresponding escrow account + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().Error(err) + suite.Require().Nil(res, "%v", res) // insufficient coins in the corresponding escrow account escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - res = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.True(res.Code.IsOK(), "%v", res) // successfully executed + res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + suite.Require().NoError(err) + suite.Require().NotNil(res, "%v", res) // successfully executed } func TestHandlerTestSuite(t *testing.T) { diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go index 57c772e67b2f..b4c0675bed78 100644 --- a/x/ibc/20-transfer/keeper/callbacks.go +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -1,7 +1,6 @@ package keeper import ( - "fmt" "strings" sdk "github.com/cosmos/cosmos-sdk/types" @@ -24,18 +23,19 @@ func (k Keeper) OnChanOpenInit( version string, ) error { if order != channel.UNORDERED { - return channel.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") + return sdkerrors.Wrap(channel.ErrInvalidChannel, "channel must be UNORDERED") } // NOTE: here the capability key name defines the port ID of the counterparty if counterparty.PortID != k.boundedCapability.Name() { - return port.ErrInvalidPort( - k.codespace, - fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name())) + return sdkerrors.Wrapf( + port.ErrInvalidPort, + "counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name(), + ) } if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version must be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -55,22 +55,23 @@ func (k Keeper) OnChanOpenTry( counterpartyVersion string, ) error { if order != channel.UNORDERED { - return channel.ErrInvalidChannel(k.codespace, "channel must be UNORDERED") + return sdkerrors.Wrap(channel.ErrInvalidChannel, "channel must be UNORDERED") } // NOTE: here the capability key name defines the port ID of the counterparty if counterparty.PortID != k.boundedCapability.Name() { - return port.ErrInvalidPort( - k.codespace, - fmt.Sprintf("counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name())) + return sdkerrors.Wrapf( + port.ErrInvalidPort, + "counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name(), + ) } if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version must be blank") } if strings.TrimSpace(counterpartyVersion) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "counterparty version must be blank") + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "counterparty version must be blank") } // NOTE: as the escrow address is generated from both the port and channel IDs @@ -86,7 +87,7 @@ func (k Keeper) OnChanOpenAck( version string, ) error { if strings.TrimSpace(version) != "" { - return ibctypes.ErrInvalidVersion(k.codespace, "version must be blank") + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version must be blank") } return nil @@ -169,7 +170,10 @@ func (k Keeper) OnTimeoutPacket( for i, coin := range data.Amount { coin := coin if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) } diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index c42786f42741..341f75374881 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -19,9 +19,8 @@ const ( // Keeper defines the IBC transfer keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - codespace sdk.CodespaceType + storeKey sdk.StoreKey + cdc *codec.Codec // Capability key and port to which ICS20 is binded. Used for packet relaying. boundedCapability sdk.CapabilityKey @@ -35,7 +34,7 @@ type Keeper struct { // NewKeeper creates a new IBC transfer Keeper instance func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + cdc *codec.Codec, key sdk.StoreKey, capKey sdk.CapabilityKey, clientKeeper types.ClientKeeper, connnectionKeeper types.ConnectionKeeper, channelKeeper types.ChannelKeeper, bankKeeper types.BankKeeper, supplyKeeper types.SupplyKeeper, @@ -49,7 +48,6 @@ func NewKeeper( return Keeper{ storeKey: key, cdc: cdc, - codespace: sdk.CodespaceType(fmt.Sprintf("%s/%s", codespace, types.DefaultCodespace)), // "ibc/transfer", boundedCapability: capKey, clientKeeper: clientKeeper, connectionKeeper: connnectionKeeper, diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index 8c3a6bb2ea5b..f30d59de04fb 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -1,7 +1,6 @@ package keeper import ( - "fmt" "strings" sdk "github.com/cosmos/cosmos-sdk/types" @@ -25,7 +24,7 @@ func (k Keeper) SendTransfer( // get the port and channel of the counterparty sourceChan, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) if !found { - return channel.ErrChannelNotFound(k.codespace, sourcePort, sourceChannel) + return sdkerrors.Wrap(channel.ErrChannelNotFound, sourceChannel) } destinationPort := sourceChan.Counterparty.PortID @@ -34,7 +33,7 @@ func (k Keeper) SendTransfer( // get the next sequence sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel) if !found { - return channel.ErrSequenceNotFound(k.codespace, "send") + return channel.ErrSequenceSendNotFound } coins := make(sdk.Coins, len(amount)) @@ -81,7 +80,10 @@ func (k Keeper) ReceiveTransfer( prefix := types.GetDenomPrefix(destinationPort, destinationChannel) for _, coin := range data.Amount { if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } } @@ -102,7 +104,10 @@ func (k Keeper) ReceiveTransfer( coins := make(sdk.Coins, len(data.Amount)) for i, coin := range data.Amount { if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) } @@ -132,7 +137,10 @@ func (k Keeper) createOutgoingPacket( coins := make(sdk.Coins, len(amount)) for i, coin := range amount { if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) } @@ -147,7 +155,10 @@ func (k Keeper) createOutgoingPacket( prefix := types.GetDenomPrefix(sourcePort, sourceChannel) for _, coin := range amount { if !strings.HasPrefix(coin.Denom, prefix) { - return sdk.ErrInvalidCoins(fmt.Sprintf("%s doesn't contain the prefix '%s'", coin.Denom, prefix)) + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidCoins, + "%s doesn't contain the prefix '%s'", coin.Denom, prefix, + ) } } diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index 252eb8060645..e7c709306228 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -12,7 +12,7 @@ import ( // BankKeeper defines the expected bank keeper type BankKeeper interface { - SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error } // ChannelKeeper defines the expected IBC channel keeper @@ -37,8 +37,8 @@ type ConnectionKeeper interface { type SupplyKeeper interface { GetModuleAddress(name string) sdk.AccAddress GetModuleAccount(ctx sdk.Context, name string) supplyexported.ModuleAccountI - MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error - BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk.Error - SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) sdk.Error - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error + MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error + BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error } diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go index 469456bbd946..1a3a8458ae53 100644 --- a/x/ibc/20-transfer/types/keys.go +++ b/x/ibc/20-transfer/types/keys.go @@ -21,9 +21,6 @@ const ( // QuerierRoute is the querier route for IBC transfer QuerierRoute = SubModuleName - - // DefaultCodespace is the default error codespace for the ibc transfers - DefaultCodespace sdk.CodespaceType = SubModuleName ) // GetEscrowAddress returns the escrow address for the specified channel diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index 2a353de56cff..42a56e0f30a6 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -3,7 +3,6 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" @@ -44,24 +43,24 @@ func (MsgTransfer) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgTransfer) ValidateBasic() sdk.Error { +func (msg MsgTransfer) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(msg.SourcePort); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source port ID")) + return sdkerrors.Wrap(err, "invalid source port ID") } if err := host.DefaultChannelIdentifierValidator(msg.SourceChannel); err != nil { - return sdk.ConvertError(sdkerrors.Wrap(err, "invalid source channel ID")) + return sdkerrors.Wrap(err, "invalid source channel ID") } if !msg.Amount.IsAllPositive() { - return sdk.ErrInsufficientCoins("transfer amount must be positive") + return sdkerrors.ErrInsufficientFunds } if !msg.Amount.IsValid() { - return sdk.ErrInvalidCoins("transfer amount is invalid") + return sdkerrors.ErrInvalidCoins } if msg.Sender.Empty() { - return sdk.ErrInvalidAddress("missing sender address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") } if msg.Receiver.Empty() { - return sdk.ErrInvalidAddress("missing recipient address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing recipient address") } return nil } @@ -104,26 +103,22 @@ func (MsgRecvPacket) Type() string { } // ValidateBasic implements sdk.Msg -func (msg MsgRecvPacket) ValidateBasic() sdk.Error { +func (msg MsgRecvPacket) ValidateBasic() error { if msg.Height == 0 { - return sdk.ConvertError(connectiontypes.ErrInvalidHeight(DefaultCodespace, "height must be > 0")) + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "height must be > 0") } - if msg.Proofs == nil || len(msg.Proofs) == 0 { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "missing proofs")) + return sdkerrors.Wrap(commitment.ErrInvalidProof, "missing proof") } - for _, proof := range msg.Proofs { - if proof.Proof == nil { - return sdk.ConvertError(ibctypes.ErrInvalidProof(DefaultCodespace, "cannot submit an empty proof")) + if err := proof.ValidateBasic(); err != nil { + return err } } - if msg.Signer.Empty() { - return sdk.ErrInvalidAddress("missing signer address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") } - - return sdk.ConvertError(msg.Packet.ValidateBasic()) + return msg.Packet.ValidateBasic() } // GetSignBytes implements sdk.Msg diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go index f7c79b9be07e..19aed7c60343 100644 --- a/x/ibc/20-transfer/types/packet.go +++ b/x/ibc/20-transfer/types/packet.go @@ -4,6 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // PacketData defines a struct for the packet payload @@ -38,18 +39,18 @@ func (pd PacketData) String() string { } // ValidateBasic performs a basic check of the packet fields -func (pd PacketData) ValidateBasic() sdk.Error { +func (pd PacketData) ValidateBasic() error { if !pd.Amount.IsAllPositive() { - return sdk.ErrInsufficientCoins("transfer amount must be positive") + return sdkerrors.ErrInsufficientFunds } if !pd.Amount.IsValid() { - return sdk.ErrInvalidCoins("transfer amount is invalid") + return sdkerrors.ErrInvalidCoins } if pd.Sender.Empty() { - return sdk.ErrInvalidAddress("missing sender address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") } if pd.Receiver.Empty() { - return sdk.ErrInvalidAddress("missing recipient address") + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing receiver address") } return nil } diff --git a/x/ibc/23-commitment/errors.go b/x/ibc/23-commitment/errors.go new file mode 100644 index 000000000000..89b2bf0b0ad7 --- /dev/null +++ b/x/ibc/23-commitment/errors.go @@ -0,0 +1,14 @@ +package commitment + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// SubModuleName is the error codespace +const SubModuleName string = "ibc/commitment" + +// IBC connection sentinel errors +var ( + ErrInvalidProof = sdkerrors.Register(SubModuleName, 1, "invalid proof") + ErrInvalidPrefix = sdkerrors.Register(SubModuleName, 2, "invalid prefix") +) diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/merkle.go index 33d84408f997..39a355fc9ce8 100644 --- a/x/ibc/23-commitment/merkle.go +++ b/x/ibc/23-commitment/merkle.go @@ -151,3 +151,11 @@ func (proof Proof) VerifyNonMembership(root RootI, path PathI) bool { err := runtime.VerifyAbsence(proof.Proof, root.GetHash(), path.String()) return err == nil } + +// ValidateBasic checks if the proof is empty. +func (proof Proof) ValidateBasic() error { + if (proof == Proof{}) || proof.Proof == nil { + return ErrInvalidProof + } + return nil +} diff --git a/x/ibc/23-commitment/merkle_test.go b/x/ibc/23-commitment/merkle_test.go index 01dc9f2edcb4..7dcb5cbfd0fc 100644 --- a/x/ibc/23-commitment/merkle_test.go +++ b/x/ibc/23-commitment/merkle_test.go @@ -25,6 +25,8 @@ func (suite *MerkleTestSuite) TestVerifyMembership() { proof := commitment.Proof{ Proof: res.Proof, } + suite.Require().NoError(proof.ValidateBasic()) + suite.Require().Error(commitment.Proof{}.ValidateBasic()) cases := []struct { name string @@ -73,6 +75,7 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() { proof := commitment.Proof{ Proof: res.Proof, } + suite.Require().NoError(proof.ValidateBasic()) cases := []struct { name string diff --git a/x/ibc/23-commitment/types.go b/x/ibc/23-commitment/types.go index 1b70f4f04d9c..bd2968da88dc 100644 --- a/x/ibc/23-commitment/types.go +++ b/x/ibc/23-commitment/types.go @@ -38,6 +38,8 @@ type ProofI interface { GetCommitmentType() Type VerifyMembership(RootI, PathI, []byte) bool VerifyNonMembership(RootI, PathI) bool + + ValidateBasic() error } // Type defines the type of the commitment diff --git a/x/ibc/24-host/errors.go b/x/ibc/24-host/errors.go index 0ff6ad59d896..26b7919e6cb5 100644 --- a/x/ibc/24-host/errors.go +++ b/x/ibc/24-host/errors.go @@ -1,47 +1,15 @@ package host import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // SubModuleName defines the ICS 24 host const SubModuleName = "host" -// Error codes specific to the ibc host submodule -const ( - DefaultCodespace sdk.CodespaceType = SubModuleName - - CodeInvalidID sdk.CodeType = 231 - CodeInvalidPath sdk.CodeType = 232 - CodeInvalidPacket sdk.CodeType = 233 +// IBC client sentinel errors +var ( + ErrInvalidID = sdkerrors.Register(SubModuleName, 1, "invalid identifier") + ErrInvalidPath = sdkerrors.Register(SubModuleName, 2, "invalid path") + ErrInvalidPacket = sdkerrors.Register(SubModuleName, 3, "invalid packet") ) - -// ErrInvalidID returns a typed ABCI error for an invalid identifier -func ErrInvalidID(codespace sdk.CodespaceType, id string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidID), - fmt.Sprintf("invalid identifier '%s'", id), - ) -} - -// ErrInvalidPath returns a typed ABCI error for an invalid path -func ErrInvalidPath(codespace sdk.CodespaceType, path string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidPath), - fmt.Sprintf("invalid path '%s'", path), - ) -} - -// ErrInvalidPacket returns a typed ABCI error for an invalid identifier -func ErrInvalidPacket(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidPacket), - fmt.Sprintf("invalid packet: '%s'", msg), - ) -} diff --git a/x/ibc/24-host/validate.go b/x/ibc/24-host/validate.go index f6b3d14751e7..c360abf8616f 100644 --- a/x/ibc/24-host/validate.go +++ b/x/ibc/24-host/validate.go @@ -25,15 +25,15 @@ type ValidateFn func(string) error func defaultIdentifierValidator(id string, min, max int) error { // valid id MUST NOT contain "/" separator if strings.Contains(id, "/") { - return sdkerrors.Wrap(ErrInvalidID(DefaultCodespace, id), "identifier cannot contain separator: /") + return sdkerrors.Wrapf(ErrInvalidID, "identifier %s cannot contain separator '/'", id) } // valid id must be between 10 and 20 characters if len(id) < min || len(id) > max { - return sdkerrors.Wrapf(ErrInvalidID(DefaultCodespace, id), "identifier has invalid length: %d, must be between %d-%d characters", len(id), min, max) + return sdkerrors.Wrapf(ErrInvalidID, "identifier %s has invalid length: %d, must be between %d-%d characters", id, len(id), min, max) } // valid id must contain only lower alphabetic characters if !isAlphaLower(id) { - return sdkerrors.Wrap(ErrInvalidID(DefaultCodespace, id), "identifier must contain only lowercase alphabetic characters") + return sdkerrors.Wrapf(ErrInvalidID, "identifier %s must contain only lowercase alphabetic characters", id) } return nil } @@ -76,7 +76,7 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { // Each path element must either be valid identifier or alphanumeric err := idValidator(p) if err != nil && !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "path contains invalid identifier or non-alphanumeric path element: %s", p) + return sdkerrors.Wrapf(ErrInvalidPath, "path %s contains invalid identifier or non-alphanumeric path element: %s", path, p) } } return nil @@ -89,13 +89,13 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { func DefaultPathValidator(path string) error { pathArr := strings.Split(path, "/") if pathArr[0] == path { - return sdkerrors.Wrap(ErrInvalidPath(DefaultCodespace, path), "path doesn't contain any separator '/'") + return sdkerrors.Wrapf(ErrInvalidPath, "path %s doesn't contain any separator '/'", path) } for _, p := range pathArr { // Each path element must be alphanumeric and non-blank if strings.TrimSpace(p) == "" || !isAlphaNumeric(p) { - return sdkerrors.Wrapf(ErrInvalidPath(DefaultCodespace, path), "invalid path element containing non-alphanumeric characters: '%s'", p) + return sdkerrors.Wrapf(ErrInvalidPath, "path %s contains an invalid non-alphanumeric character: '%s'", path, p) } } return nil diff --git a/x/ibc/alias.go b/x/ibc/alias.go index abb2aae3c59a..7c1ad02349e2 100644 --- a/x/ibc/alias.go +++ b/x/ibc/alias.go @@ -12,11 +12,10 @@ import ( ) const ( - ModuleName = types.ModuleName - StoreKey = types.StoreKey - QuerierRoute = types.QuerierRoute - RouterKey = types.RouterKey - DefaultCodespace = types.DefaultCodespace + ModuleName = types.ModuleName + StoreKey = types.StoreKey + QuerierRoute = types.QuerierRoute + RouterKey = types.RouterKey ) var ( diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index 4818d68008d6..cb095b788a52 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -4,6 +4,7 @@ import ( "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" @@ -22,7 +23,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - ibcTxCmd.AddCommand(client.PostCommands( + ibcTxCmd.AddCommand(flags.PostCommands( ibcclient.GetTxCmd(cdc, storeKey), connection.GetTxCmd(cdc, storeKey), channel.GetTxCmd(cdc, storeKey), @@ -42,7 +43,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - ibcQueryCmd.AddCommand(client.GetCommands( + ibcQueryCmd.AddCommand(flags.GetCommands( ibcclient.GetQueryCmd(cdc, queryRoute), connection.GetQueryCmd(cdc, queryRoute), channel.GetQueryCmd(cdc, queryRoute), diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 1a1e2d0189be..d7d7262a165e 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -1,9 +1,8 @@ package ibc import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -12,7 +11,7 @@ import ( // NewHandler defines the IBC handler func NewHandler(k Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -63,8 +62,7 @@ func NewHandler(k Keeper) sdk.Handler { return transfer.HandleMsgRecvPacket(ctx, k.TransferKeeper, msg) default: - errMsg := fmt.Sprintf("unrecognized IBC message type: %T", msg) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized IBC message type: %T", msg) } } } diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 2c28b5c9dd51..694dae13b9ec 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -22,18 +22,18 @@ type Keeper struct { // NewKeeper creates a new ibc Keeper func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, codespace sdk.CodespaceType, + cdc *codec.Codec, key sdk.StoreKey, bk transfer.BankKeeper, sk transfer.SupplyKeeper, ) Keeper { - clientKeeper := client.NewKeeper(cdc, key, codespace) - connectionKeeper := connection.NewKeeper(cdc, key, codespace, clientKeeper) - portKeeper := port.NewKeeper(cdc, key, codespace) - channelKeeper := channel.NewKeeper(cdc, key, codespace, clientKeeper, connectionKeeper, portKeeper) + clientKeeper := client.NewKeeper(cdc, key) + connectionKeeper := connection.NewKeeper(cdc, key, clientKeeper) + portKeeper := port.NewKeeper(cdc, key) + channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper) // TODO: move out of IBC keeper. Blocked on ADR15 capKey := portKeeper.BindPort(bank.ModuleName) transferKeeper := transfer.NewKeeper( - cdc, key, codespace, capKey, + cdc, key, capKey, clientKeeper, connectionKeeper, channelKeeper, bk, sk, ) diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index 02b468cdb031..68447885bbd1 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -12,7 +12,7 @@ import ( // NewQuerier creates a querier for the IBC module func NewQuerier(k Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { var ( res []byte err error @@ -56,6 +56,6 @@ func NewQuerier(k Keeper) sdk.Querier { err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC query endpoint") } - return res, sdk.ConvertError(err) + return res, err } } diff --git a/x/ibc/types/errors.go b/x/ibc/types/errors.go index 086851321b6a..5246b3c5a206 100644 --- a/x/ibc/types/errors.go +++ b/x/ibc/types/errors.go @@ -1,33 +1,11 @@ package types import ( - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// common IBC error codes -const ( - // DefaultCodespace of the IBC module - DefaultCodespace sdk.CodespaceType = ModuleName - - CodeInvalidProof sdk.CodeType = 234 - CodeInvalidVersion sdk.CodeType = 235 +// ibc module common sentinel errors +var ( + ErrInvalidHeight = sdkerrors.Register(ModuleName, 1, "invalid height") + ErrInvalidVersion = sdkerrors.Register(ModuleName, 2, "invalid version") ) - -// ErrInvalidProof implements sdk.Error -func ErrInvalidProof(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidProof), - msg, - ) -} - -// ErrInvalidVersion implements sdk.Error -func ErrInvalidVersion(codespace sdk.CodespaceType, msg string) error { - return sdkerrors.New( - string(codespace), - uint32(CodeInvalidVersion), - msg, - ) -} From 134551e5141fda6a7786e1e019bf3bae09ca1b70 Mon Sep 17 00:00:00 2001 From: Joon Date: Wed, 15 Jan 2020 00:21:20 +0900 Subject: [PATCH 060/176] ADR 015 Implementation (#5401) * implement in progress * rm unneccessary change under simapp, modify baseapp for codetxbreak * fix test in progress * fix test error * fix golangci * address minor comments * mv antehandler to ante/, address comments * fix GetCommitment => GetData, fix syntax * checkout types/ to ibc-alpha * checkout to origin/ibc-alpha * fix branch problem * fix syntax error * recover PacketI interface * mv recvpacket rest from 20 -> 04 * address minor comments * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * rm wrong files * Apply suggestions from code review * PacketDataI field is now named, not embed * add acknowledgement hashing * rename finalization functiosn * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Rename GetCommitment() to GetBytes() * Add recv sequence incr to RecvPacket() * Revert but where is PacketExecuted() called * Call PacketExecuted(), check seq in RecvPacket() * The port is called "bank" * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update simapp/app.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Remove omitempty * Add godoc * Move events * set ProofVerificationDecorator on AnteHandler * Apply suggestions from code review Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * format Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Christopher Goes Co-authored-by: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> --- client/context/verifier_test.go | 3 +- simapp/app.go | 35 ++- x/auth/alias.go | 103 ++++---- x/auth/ante/ante.go | 10 +- x/auth/ante/ante_test.go | 26 +- x/ibc/02-client/keeper/client.go | 24 ++ x/ibc/04-channel/alias.go | 8 +- x/ibc/04-channel/client/rest/rest.go | 8 + x/ibc/04-channel/client/rest/tx.go | 46 ++++ x/ibc/04-channel/client/utils/utils.go | 18 +- x/ibc/04-channel/exported/exported.go | 13 +- x/ibc/04-channel/keeper/packet.go | 79 ++++-- x/ibc/04-channel/keeper/timeout.go | 65 +++-- x/ibc/04-channel/types/codec.go | 12 +- x/ibc/04-channel/types/msgs.go | 167 ++++++++++++ x/ibc/04-channel/types/msgs_test.go | 133 +++++++++- x/ibc/04-channel/types/packet.go | 76 +++--- x/ibc/20-transfer/alias.go | 18 +- x/ibc/20-transfer/client/rest/rest.go | 10 - x/ibc/20-transfer/client/rest/tx.go | 46 ---- x/ibc/20-transfer/handler.go | 62 ++++- x/ibc/20-transfer/handler_test.go | 118 ++------- x/ibc/20-transfer/keeper/callbacks.go | 44 +--- x/ibc/20-transfer/keeper/callbacks_test.go | 123 +-------- x/ibc/20-transfer/keeper/keeper.go | 18 +- x/ibc/20-transfer/keeper/keeper_test.go | 2 +- x/ibc/20-transfer/keeper/relay.go | 65 +++-- x/ibc/20-transfer/keeper/relay_test.go | 117 +-------- x/ibc/20-transfer/module.go | 94 ++++++- x/ibc/20-transfer/types/codec.go | 3 +- x/ibc/20-transfer/types/expected_keepers.go | 3 +- x/ibc/20-transfer/types/msgs_test.go | 81 ------ x/ibc/20-transfer/types/packet.go | 64 ++++- x/ibc/20-transfer/types/packet_test.go | 32 +-- x/ibc/ante.go | 51 ---- x/ibc/ante/ante.go | 47 ++++ x/ibc/ante/ante_test.go | 272 ++++++++++++++++++++ x/ibc/client/cli/cli.go | 3 - x/ibc/client/rest/rest.go | 2 - x/ibc/handler.go | 10 +- x/ibc/keeper/keeper.go | 10 - x/ibc/module.go | 3 - x/mock/app.go | 4 +- 43 files changed, 1291 insertions(+), 837 deletions(-) delete mode 100644 x/ibc/ante.go create mode 100644 x/ibc/ante/ante.go create mode 100644 x/ibc/ante/ante_test.go diff --git a/client/context/verifier_test.go b/client/context/verifier_test.go index 6eacccae5452..bd2539492349 100644 --- a/client/context/verifier_test.go +++ b/client/context/verifier_test.go @@ -4,8 +4,9 @@ import ( "io/ioutil" "testing" - "github.com/cosmos/cosmos-sdk/client/context" "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/client/context" ) func TestCreateVerifier(t *testing.T) { diff --git a/simapp/app.go b/simapp/app.go index eac5db297345..bd0e1ed45dbc 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -25,7 +25,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/ibc" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" - ibctransfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" + transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/params" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" @@ -65,17 +65,18 @@ var ( upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, ibc.AppModuleBasic{}, + transfer.AppModuleBasic{}, ) // module account permissions maccPerms = map[string][]string{ - auth.FeeCollectorName: nil, - distr.ModuleName: nil, - mint.ModuleName: {supply.Minter}, - staking.BondedPoolName: {supply.Burner, supply.Staking}, - staking.NotBondedPoolName: {supply.Burner, supply.Staking}, - gov.ModuleName: {supply.Burner}, - ibctransfer.GetModuleAccountName(): {supply.Minter, supply.Burner}, + auth.FeeCollectorName: nil, + distr.ModuleName: nil, + mint.ModuleName: {supply.Minter}, + staking.BondedPoolName: {supply.Burner, supply.Staking}, + staking.NotBondedPoolName: {supply.Burner, supply.Staking}, + gov.ModuleName: {supply.Burner}, + transfer.GetModuleAccountName(): {supply.Minter, supply.Burner}, } // module accounts that are allowed to receive tokens @@ -127,6 +128,7 @@ type SimApp struct { ParamsKeeper params.Keeper EvidenceKeeper evidence.Keeper IBCKeeper ibc.Keeper + TransferKeeper transfer.Keeper // the module manager mm *module.Manager @@ -150,8 +152,8 @@ func NewSimApp( keys := sdk.NewKVStoreKeys( bam.MainStoreKey, auth.StoreKey, staking.StoreKey, supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey, - gov.StoreKey, params.StoreKey, upgrade.StoreKey, evidence.StoreKey, - ibc.StoreKey, + gov.StoreKey, params.StoreKey, ibc.StoreKey, upgrade.StoreKey, evidence.StoreKey, + transfer.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(params.TStoreKey) @@ -234,6 +236,12 @@ func NewSimApp( app.IBCKeeper = ibc.NewKeeper(app.cdc, keys[ibc.StoreKey], app.BankKeeper, app.SupplyKeeper) + transferCapKey := app.IBCKeeper.PortKeeper.BindPort(bank.ModuleName) + app.TransferKeeper = transfer.NewKeeper( + app.cdc, keys[transfer.StoreKey], transferCapKey, + app.IBCKeeper.ChannelKeeper, app.BankKeeper, app.SupplyKeeper, + ) + // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. app.mm = module.NewManager( @@ -294,7 +302,12 @@ func NewSimApp( // initialize BaseApp app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) - app.SetAnteHandler(ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, auth.DefaultSigVerificationGasConsumer)) + app.SetAnteHandler( + ante.NewAnteHandler( + app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, + ante.DefaultSigVerificationGasConsumer, + ), + ) app.SetEndBlocker(app.EndBlocker) if loadLatest { diff --git a/x/auth/alias.go b/x/auth/alias.go index 01b20a68f3d7..599ab823967b 100644 --- a/x/auth/alias.go +++ b/x/auth/alias.go @@ -1,17 +1,16 @@ -// nolint -// autogenerated code using github.com/rigelrozanski/multitool -// aliases generated for the following subdirectories: -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/ante -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/keeper -// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/types package auth import ( - "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/types" ) +// nolint +// autogenerated code using github.com/rigelrozanski/multitool +// aliases generated for the following subdirectories: +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/keeper +// ALIASGEN: github.com/cosmos/cosmos-sdk/x/auth/types + const ( ModuleName = types.ModuleName StoreKey = types.StoreKey @@ -28,39 +27,34 @@ const ( var ( // functions aliases - NewAnteHandler = ante.NewAnteHandler - GetSignerAcc = ante.GetSignerAcc - DefaultSigVerificationGasConsumer = ante.DefaultSigVerificationGasConsumer - DeductFees = ante.DeductFees - SetGasMeter = ante.SetGasMeter - NewAccountKeeper = keeper.NewAccountKeeper - NewQuerier = keeper.NewQuerier - NewBaseAccount = types.NewBaseAccount - ProtoBaseAccount = types.ProtoBaseAccount - NewBaseAccountWithAddress = types.NewBaseAccountWithAddress - NewAccountRetriever = types.NewAccountRetriever - RegisterCodec = types.RegisterCodec - RegisterAccountTypeCodec = types.RegisterAccountTypeCodec - NewGenesisState = types.NewGenesisState - DefaultGenesisState = types.DefaultGenesisState - ValidateGenesis = types.ValidateGenesis - SanitizeGenesisAccounts = types.SanitizeGenesisAccounts - AddressStoreKey = types.AddressStoreKey - NewParams = types.NewParams - ParamKeyTable = types.ParamKeyTable - DefaultParams = types.DefaultParams - NewQueryAccountParams = types.NewQueryAccountParams - NewStdTx = types.NewStdTx - CountSubKeys = types.CountSubKeys - NewStdFee = types.NewStdFee - StdSignBytes = types.StdSignBytes - DefaultTxDecoder = types.DefaultTxDecoder - DefaultTxEncoder = types.DefaultTxEncoder - NewTxBuilder = types.NewTxBuilder - NewTxBuilderFromCLI = types.NewTxBuilderFromCLI - MakeSignature = types.MakeSignature - ValidateGenAccounts = types.ValidateGenAccounts - GetGenesisStateFromAppState = types.GetGenesisStateFromAppState + NewAccountKeeper = keeper.NewAccountKeeper + NewQuerier = keeper.NewQuerier + NewBaseAccount = types.NewBaseAccount + ProtoBaseAccount = types.ProtoBaseAccount + NewBaseAccountWithAddress = types.NewBaseAccountWithAddress + NewAccountRetriever = types.NewAccountRetriever + RegisterCodec = types.RegisterCodec + RegisterAccountTypeCodec = types.RegisterAccountTypeCodec + NewGenesisState = types.NewGenesisState + DefaultGenesisState = types.DefaultGenesisState + ValidateGenesis = types.ValidateGenesis + SanitizeGenesisAccounts = types.SanitizeGenesisAccounts + AddressStoreKey = types.AddressStoreKey + NewParams = types.NewParams + ParamKeyTable = types.ParamKeyTable + DefaultParams = types.DefaultParams + NewQueryAccountParams = types.NewQueryAccountParams + NewStdTx = types.NewStdTx + CountSubKeys = types.CountSubKeys + NewStdFee = types.NewStdFee + StdSignBytes = types.StdSignBytes + DefaultTxDecoder = types.DefaultTxDecoder + DefaultTxEncoder = types.DefaultTxEncoder + NewTxBuilder = types.NewTxBuilder + NewTxBuilderFromCLI = types.NewTxBuilderFromCLI + MakeSignature = types.MakeSignature + ValidateGenAccounts = types.ValidateGenAccounts + GetGenesisStateFromAppState = types.GetGenesisStateFromAppState // variable aliases ModuleCdc = types.ModuleCdc @@ -74,19 +68,18 @@ var ( ) type ( - SignatureVerificationGasConsumer = ante.SignatureVerificationGasConsumer - AccountKeeper = keeper.AccountKeeper - BaseAccount = types.BaseAccount - NodeQuerier = types.NodeQuerier - AccountRetriever = types.AccountRetriever - GenesisState = types.GenesisState - Params = types.Params - QueryAccountParams = types.QueryAccountParams - StdSignMsg = types.StdSignMsg - StdTx = types.StdTx - StdFee = types.StdFee - StdSignDoc = types.StdSignDoc - StdSignature = types.StdSignature - TxBuilder = types.TxBuilder - GenesisAccountIterator = types.GenesisAccountIterator + AccountKeeper = keeper.AccountKeeper + BaseAccount = types.BaseAccount + NodeQuerier = types.NodeQuerier + AccountRetriever = types.AccountRetriever + GenesisState = types.GenesisState + Params = types.Params + QueryAccountParams = types.QueryAccountParams + StdSignMsg = types.StdSignMsg + StdTx = types.StdTx + StdFee = types.StdFee + StdSignDoc = types.StdSignDoc + StdSignature = types.StdSignature + TxBuilder = types.TxBuilder + GenesisAccountIterator = types.GenesisAccountIterator ) diff --git a/x/auth/ante/ante.go b/x/auth/ante/ante.go index bdf24823f137..54c3b8017eb7 100644 --- a/x/auth/ante/ante.go +++ b/x/auth/ante/ante.go @@ -4,12 +4,17 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/types" + ibcante "github.com/cosmos/cosmos-sdk/x/ibc/ante" + ibckeeper "github.com/cosmos/cosmos-sdk/x/ibc/keeper" ) // NewAnteHandler returns an AnteHandler that checks and increments sequence // numbers, checks signatures & account numbers, and deducts fees from the first // signer. -func NewAnteHandler(ak keeper.AccountKeeper, supplyKeeper types.SupplyKeeper, sigGasConsumer SignatureVerificationGasConsumer) sdk.AnteHandler { +func NewAnteHandler( + ak keeper.AccountKeeper, supplyKeeper types.SupplyKeeper, ibcKeeper ibckeeper.Keeper, + sigGasConsumer SignatureVerificationGasConsumer, +) sdk.AnteHandler { return sdk.ChainAnteDecorators( NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first NewMempoolFeeDecorator(), @@ -21,6 +26,7 @@ func NewAnteHandler(ak keeper.AccountKeeper, supplyKeeper types.SupplyKeeper, si NewDeductFeeDecorator(ak, supplyKeeper), NewSigGasConsumeDecorator(ak, sigGasConsumer), NewSigVerificationDecorator(ak), - NewIncrementSequenceDecorator(ak), // innermost AnteDecorator + NewIncrementSequenceDecorator(ak), + ibcante.NewProofVerificationDecorator(ibcKeeper.ClientKeeper, ibcKeeper.ChannelKeeper), // innermost AnteDecorator ) } diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index 1d55b4d320c3..df2bb4b16eb2 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -38,7 +38,7 @@ func TestSimulateGasCost(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -89,7 +89,7 @@ func TestSimulateGasCost(t *testing.T) { func TestAnteHandlerSigErrors(t *testing.T) { // setup app, ctx := createTestApp(true) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -138,7 +138,7 @@ func TestAnteHandlerAccountNumbers(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -195,7 +195,7 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(0) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -251,7 +251,7 @@ func TestAnteHandlerSequences(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -327,7 +327,7 @@ func TestAnteHandlerSequences(t *testing.T) { func TestAnteHandlerFees(t *testing.T) { // setup app, ctx := createTestApp(true) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -367,7 +367,7 @@ func TestAnteHandlerMemoGas(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -407,7 +407,7 @@ func TestAnteHandlerMultiSigner(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -457,7 +457,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -534,7 +534,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -652,7 +652,7 @@ func TestAnteHandlerSigLimitExceeded(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -692,7 +692,7 @@ func TestCustomSignatureVerificationGasConsumer(t *testing.T) { app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) // setup an ante handler that only accepts PubKeyEd25519 - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, func(meter sdk.GasMeter, sig []byte, pubkey crypto.PubKey, params types.Params) error { + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, func(meter sdk.GasMeter, sig []byte, pubkey crypto.PubKey, params types.Params) error { switch pubkey := pubkey.(type) { case ed25519.PubKeyEd25519: meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519") @@ -749,7 +749,7 @@ func TestAnteHandlerReCheck(t *testing.T) { require.NoError(t, acc1.SetAccountNumber(0)) app.AccountKeeper.SetAccount(ctx, acc1) - antehandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, ante.DefaultSigVerificationGasConsumer) + antehandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // test that operations skipped on recheck do not run diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index 91cadfe4a016..11e805e466e6 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -34,6 +34,18 @@ func (k Keeper) CreateClient( k.SetClientState(ctx, clientState) k.SetClientType(ctx, clientID, clientType) k.Logger(ctx).Info(fmt.Sprintf("client %s created at height %d", clientID, consensusState.GetHeight())) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeCreateClient, + sdk.NewAttribute(types.AttributeKeyClientID, clientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) + return clientState, nil } @@ -72,6 +84,18 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H k.SetCommitter(ctx, clientID, consensusState.GetHeight(), consensusState.GetCommitter()) k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, consensusState.GetHeight())) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeUpdateClient, + sdk.NewAttribute(types.AttributeKeyClientID, clientID), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) + return nil } diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index 73e18df48d0c..ff4895eae42a 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -77,8 +77,10 @@ var ( NewMsgChannelOpenConfirm = types.NewMsgChannelOpenConfirm NewMsgChannelCloseInit = types.NewMsgChannelCloseInit NewMsgChannelCloseConfirm = types.NewMsgChannelCloseConfirm + NewMsgPacket = types.NewMsgPacket + NewMsgTimeout = types.NewMsgTimeout + NewMsgAcknowledgement = types.NewMsgAcknowledgement NewPacket = types.NewPacket - NewOpaquePacket = types.NewOpaquePacket NewChannelResponse = types.NewChannelResponse NewQueryChannelParams = types.NewQueryChannelParams @@ -108,8 +110,10 @@ type ( MsgChannelOpenConfirm = types.MsgChannelOpenConfirm MsgChannelCloseInit = types.MsgChannelCloseInit MsgChannelCloseConfirm = types.MsgChannelCloseConfirm + MsgPacket = types.MsgPacket + MsgAcknowledgement = types.MsgAcknowledgement + MsgTimeout = types.MsgTimeout Packet = types.Packet - OpaquePacket = types.OpaquePacket ChannelResponse = types.ChannelResponse QueryChannelParams = types.QueryChannelParams ) diff --git a/x/ibc/04-channel/client/rest/rest.go b/x/ibc/04-channel/client/rest/rest.go index 55cf81215f64..4c869297d6e7 100644 --- a/x/ibc/04-channel/client/rest/rest.go +++ b/x/ibc/04-channel/client/rest/rest.go @@ -73,3 +73,11 @@ type ChannelCloseConfirmReq struct { ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` } + +// RecvPacketReq defines the properties of a receive packet request's body. +type RecvPacketReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Packet types.Packet `json:"packet" yaml:"packet"` + Proofs commitment.ProofI `json:"proofs" yaml:"proofs"` + Height uint64 `json:"height" yaml:"height"` +} diff --git a/x/ibc/04-channel/client/rest/tx.go b/x/ibc/04-channel/client/rest/tx.go index 641a62bf20e2..ccbfebde13fc 100644 --- a/x/ibc/04-channel/client/rest/tx.go +++ b/x/ibc/04-channel/client/rest/tx.go @@ -21,6 +21,7 @@ func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/open-confirm", RestPortID, RestChannelID), channelOpenConfirmHandlerFn(cliCtx)).Methods("POST") r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/close-init", RestPortID, RestChannelID), channelCloseInitHandlerFn(cliCtx)).Methods("POST") r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/close-confirm", RestPortID, RestChannelID), channelCloseConfirmHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc(fmt.Sprintf("/ibc/packets/receive"), recvPacketHandlerFn(cliCtx)).Methods("POST") } // channelOpenInitHandlerFn implements a channel open init handler @@ -334,3 +335,48 @@ func channelCloseConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } + +// recvPacketHandlerFn implements a receive packet handler +// +// @Summary Receive packet +// @Tags IBC +// @Accept json +// @Produce json +// @Param body body rest.RecvPacketReq true "Receive packet request body" +// @Success 200 {object} PostRecvPacket "OK" +// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" +// @Router /ibc/packets/receive [post] +func recvPacketHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req RecvPacketReq + if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { + return + } + + req.BaseReq = req.BaseReq.Sanitize() + if !req.BaseReq.ValidateBasic(w) { + return + } + + fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + // create the message + msg := types.NewMsgPacket( + req.Packet, + req.Proofs, + req.Height, + fromAddr, + ) + + if err := msg.ValidateBasic(); err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + } +} diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index e7e9568e4add..912c77d463e9 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -4,12 +4,14 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // QueryPacket returns a packet from the store func QueryPacket( - ctx context.CLIContext, portID, channelID string, sequence, timeout uint64, prove bool, + ctx context.CLIContext, portID, channelID string, + sequence, timeout uint64, prove bool, ) (types.PacketResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", @@ -30,14 +32,23 @@ func QueryPacket( destPortID := channelRes.Channel.Counterparty.PortID destChannelID := channelRes.Channel.Counterparty.ChannelID + var data exported.PacketDataI + // TODO: commitment data is stored, not the data + // but we are unmarshalling the commitment in a json format + // because the current ICS 20 implementation uses json commitment form + // need to be changed to use external source of packet(e.g. event logs) + err = ctx.Codec.UnmarshalJSON(res.Value, &data) + if err != nil { + return types.PacketResponse{}, err + } + packet := types.NewPacket( + data, sequence, - timeout, portID, channelID, destPortID, destChannelID, - res.Value, ) // FIXME: res.Height+1 is hack, fix later @@ -63,6 +74,5 @@ func QueryChannel( if err := ctx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &channel); err != nil { return types.ChannelResponse{}, err } - return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil } diff --git a/x/ibc/04-channel/exported/exported.go b/x/ibc/04-channel/exported/exported.go index 6fd31751fef6..75608bd532a7 100644 --- a/x/ibc/04-channel/exported/exported.go +++ b/x/ibc/04-channel/exported/exported.go @@ -8,6 +8,17 @@ type PacketI interface { GetSourceChannel() string GetDestPort() string GetDestChannel() string - GetData() []byte + GetData() PacketDataI ValidateBasic() error } + +// PacketDataI defines the packet data interface for IBC packets +// IBC application modules should define which data they want to +// send and receive over IBC channels. +type PacketDataI interface { + GetBytes() []byte // GetBytes returns the serialised packet data (without timeout) + GetTimeoutHeight() uint64 // GetTimeoutHeight returns the timeout height defined specifically for each packet data type instance + + ValidateBasic() error // ValidateBasic validates basic properties of the packet data, implements sdk.Msg + Type() string // Type returns human readable identifier, implements sdk.Msg +} diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 2703f283a814..a2db8d3f66a2 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -77,7 +77,7 @@ func (k Keeper) CleanupPacket( } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } @@ -184,7 +184,7 @@ func (k Keeper) SendPacket( nextSequenceSend++ k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend) - k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), packet.GetData()) // TODO: hash packet data + k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), types.CommitPacket(packet.GetData())) return nil } @@ -196,8 +196,6 @@ func (k Keeper) RecvPacket( packet exported.PacketI, proof commitment.ProofI, proofHeight uint64, - acknowledgement []byte, - portCapability sdk.CapabilityKey, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) @@ -212,9 +210,8 @@ func (k Keeper) RecvPacket( ) } - if !k.portKeeper.Authenticate(portCapability, packet.GetDestPort()) { - return nil, sdkerrors.Wrap(port.ErrInvalidPort, packet.GetDestPort()) - } + // RecvPacket is called by the antehandler which acts upon the packet.Route(), + // so the capability authentication can be omitted here // packet must come from the channel's counterparty if packet.GetSourcePort() != channel.Counterparty.PortID { @@ -243,6 +240,20 @@ func (k Keeper) RecvPacket( ) } + if channel.Ordering == types.ORDERED { + nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) + if !found { + return nil, types.ErrSequenceReceiveNotFound + } + + if packet.GetSequence() != nextSequenceRecv { + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv, + ) + } + } + if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { return nil, types.ErrPacketTimeout } @@ -250,26 +261,49 @@ func (k Keeper) RecvPacket( if !k.connectionKeeper.VerifyMembership( ctx, connectionEnd, proofHeight, proof, types.PacketCommitmentPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), - packet.GetData(), // TODO: hash data + types.CommitPacket(packet.GetData()), ) { return nil, errors.New("couldn't verify counterparty packet commitment") } - if len(acknowledgement) > 0 || channel.Ordering == types.UNORDERED { + return packet, nil +} + +// PacketExecuted writes the packet execution acknowledgement to the state, +// which will be verified by the counterparty chain using AcknowledgePacket. +// CONTRACT: each packet handler function should call WriteAcknowledgement at the end of the execution +func (k Keeper) PacketExecuted( + ctx sdk.Context, + packet exported.PacketI, + acknowledgement exported.PacketDataI, +) error { + channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) + if !found { + return sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetDestChannel()) + } + + if channel.State != types.OPEN { + return sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), + ) + } + + if acknowledgement != nil || channel.Ordering == types.UNORDERED { k.SetPacketAcknowledgement( ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), - acknowledgement, // TODO: hash ACK + types.CommitAcknowledgement(acknowledgement), ) } if channel.Ordering == types.ORDERED { nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { - return nil, types.ErrSequenceReceiveNotFound + return types.ErrSequenceReceiveNotFound } if packet.GetSequence() != nextSequenceRecv { - return nil, sdkerrors.Wrapf( + return sdkerrors.Wrapf( types.ErrInvalidPacket, "packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv, ) @@ -280,7 +314,7 @@ func (k Keeper) RecvPacket( k.SetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv) } - return packet, nil + return nil } // AcknowledgePacket is called by a module to process the acknowledgement of a @@ -291,10 +325,9 @@ func (k Keeper) RecvPacket( func (k Keeper) AcknowledgePacket( ctx sdk.Context, packet exported.PacketI, - acknowledgement []byte, + acknowledgement exported.PacketDataI, proof commitment.ProofI, proofHeight uint64, - portCapability sdk.CapabilityKey, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { @@ -308,9 +341,8 @@ func (k Keeper) AcknowledgePacket( ) } - if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return nil, errors.New("invalid capability key") - } + // RecvPacket is called by the antehandler which acts upon the packet.Route(), + // so the capability authentication can be omitted here // packet must come from the channel's counterparty if packet.GetSourcePort() != channel.Counterparty.PortID { @@ -340,18 +372,23 @@ func (k Keeper) AcknowledgePacket( } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } if !k.connectionKeeper.VerifyMembership( ctx, connectionEnd, proofHeight, proof, types.PacketAcknowledgementPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), - acknowledgement, // TODO: hash ACK + acknowledgement.GetBytes(), ) { return nil, errors.New("invalid acknowledgement on counterparty chain") } - k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) return packet, nil } + +// AcknowledgementExecuted deletes the commitment send from this chain after it receives the acknowlegement +// CONTRACT: each acknowledgement handler function should call WriteAcknowledgement at the end of the execution +func (k Keeper) AcknowledgementExecuted(ctx sdk.Context, packet exported.PacketI) { + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) +} diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index af54040dad2c..ccbffd25bd83 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -23,11 +23,13 @@ func (k Keeper) TimeoutPacket( proof commitment.ProofI, proofHeight uint64, nextSequenceRecv uint64, - portCapability sdk.CapabilityKey, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) + return nil, sdkerrors.Wrapf( + types.ErrChannelNotFound, + packet.GetSourcePort(), packet.GetSourceChannel(), + ) } if channel.State != types.OPEN { @@ -37,15 +39,14 @@ func (k Keeper) TimeoutPacket( ) } + // TimeoutPacket is called by the antehandler which acts upon the packet.Route(), + // so the capability authentication can be omitted here + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { return nil, types.ErrChannelCapabilityNotFound } - if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return nil, errors.New("port is not valid") - } - if packet.GetDestChannel() != channel.Counterparty.ChannelID { return nil, sdkerrors.Wrapf( types.ErrInvalidPacket, @@ -55,7 +56,10 @@ func (k Keeper) TimeoutPacket( connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) + return nil, sdkerrors.Wrap( + connection.ErrConnectionNotFound, + channel.ConnectionHops[0], + ) } if packet.GetDestPort() != channel.Counterparty.PortID { @@ -70,12 +74,18 @@ func (k Keeper) TimeoutPacket( } if nextSequenceRecv >= packet.GetSequence() { - return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet already received") + return nil, sdkerrors.Wrap( + types.ErrInvalidPacket, + "packet already received", + ) } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data - return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") + if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { + return nil, sdkerrors.Wrap( + types.ErrInvalidPacket, + "packet hasn't been sent", + ) } var ok bool @@ -99,13 +109,6 @@ func (k Keeper) TimeoutPacket( return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet verification failed") } - k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - - if channel.Ordering == types.ORDERED { - channel.State = types.CLOSED - k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) - } - return packet, nil } @@ -114,7 +117,7 @@ func (k Keeper) TimeoutPacket( // never be received (even if the timeoutHeight has not yet been reached). func (k Keeper) TimeoutOnClose( ctx sdk.Context, - packet exported.PacketI, + packet types.Packet, proofNonMembership, proofClosed commitment.ProofI, proofHeight uint64, @@ -122,7 +125,7 @@ func (k Keeper) TimeoutOnClose( ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) + return nil, sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetSourcePort(), packet.GetSourceChannel()) } _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) @@ -154,7 +157,7 @@ func (k Keeper) TimeoutOnClose( } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if !bytes.Equal(commitment, packet.GetData()) { // TODO: hash packet data + if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } @@ -196,3 +199,25 @@ func (k Keeper) TimeoutOnClose( return packet, nil } + +// TimeoutExecuted deletes the commitment send from this chain after it verifies timeout +func (k Keeper) TimeoutExecuted(ctx sdk.Context, packet exported.PacketI) error { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return types.ErrChannelCapabilityNotFound + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + if channel.Ordering == types.ORDERED { + channel.State = types.CLOSED + k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + } + + return nil +} diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index a5d709662fa2..dea16064dbcd 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -2,19 +2,27 @@ package types import ( "github.com/cosmos/cosmos-sdk/codec" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // SubModuleCdc defines the IBC channel codec. var SubModuleCdc *codec.Codec +func init() { + SubModuleCdc = codec.New() + commitment.RegisterCodec(SubModuleCdc) + client.RegisterCodec(SubModuleCdc) + RegisterCodec(SubModuleCdc) +} + // RegisterCodec registers all the necessary types and interfaces for the // IBC channel. func RegisterCodec(cdc *codec.Codec) { - cdc.RegisterInterface((*exported.PacketI)(nil), nil) + cdc.RegisterInterface((*exported.PacketDataI)(nil), nil) cdc.RegisterConcrete(Channel{}, "ibc/channel/Channel", nil) cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil) - cdc.RegisterConcrete(OpaquePacket{}, "ibc/channel/OpaquePacket", nil) cdc.RegisterConcrete(MsgChannelOpenInit{}, "ibc/channel/MsgChannelOpenInit", nil) cdc.RegisterConcrete(MsgChannelOpenTry{}, "ibc/channel/MsgChannelOpenTry", nil) diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index d0a9e71955ba..3f578425dda0 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -389,3 +390,169 @@ func (msg MsgChannelCloseConfirm) GetSignBytes() []byte { func (msg MsgChannelCloseConfirm) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Signer} } + +// MsgPacket receives incoming IBC packet +type MsgPacket struct { + Packet `json:"packet" yaml:"packet"` + Proof commitment.ProofI `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` +} + +var _ sdk.Msg = MsgPacket{} + +// NewMsgPacket constructs new MsgPacket +func NewMsgPacket(packet Packet, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgPacket { + return MsgPacket{ + Packet: packet, + Proof: proof, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgPacket) Route() string { + return msg.DestinationPort +} + +// ValidateBasic implements sdk.Msg +func (msg MsgPacket) ValidateBasic() error { + if msg.Proof == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.Proof.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") + } + if msg.ProofHeight == 0 { + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") + } + if msg.Signer.Empty() { + return sdkerrors.ErrInvalidAddress + } + + return msg.Packet.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgPacket) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgPacket) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgTimeout{} + +// MsgTimeout receives timeouted packet +type MsgTimeout struct { + Packet `json:"packet" yaml:"packet"` + NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"` + Proof commitment.ProofI `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` +} + +// NewMsgTimeout constructs new MsgTimeout +func NewMsgTimeout(packet Packet, nextSequenceRecv uint64, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgTimeout { + return MsgTimeout{ + Packet: packet, + NextSequenceRecv: nextSequenceRecv, + Proof: proof, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgTimeout) Route() string { + return msg.SourcePort +} + +// ValidateBasic implements sdk.Msg +func (msg MsgTimeout) ValidateBasic() error { + if msg.Proof == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.Proof.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") + } + if msg.ProofHeight == 0 { + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") + } + if msg.Signer.Empty() { + return sdkerrors.ErrInvalidAddress + } + + return msg.Packet.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgTimeout) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgTimeout) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} + +var _ sdk.Msg = MsgAcknowledgement{} + +// MsgAcknowledgement receives incoming IBC acknowledgement +type MsgAcknowledgement struct { + Packet `json:"packet" yaml:"packet"` + Acknowledgement exported.PacketDataI `json:"acknowledgement" yaml:"acknowledgement"` + Proof commitment.ProofI `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` +} + +// NewMsgAcknowledgement constructs a new MsgAcknowledgement +func NewMsgAcknowledgement(packet Packet, ack exported.PacketDataI, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement { + return MsgAcknowledgement{ + Packet: packet, + Acknowledgement: ack, + Proof: proof, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgAcknowledgement) Route() string { + return msg.SourcePort +} + +// ValidateBasic implements sdk.Msg +func (msg MsgAcknowledgement) ValidateBasic() error { + if msg.Proof == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + } + if err := msg.Proof.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "proof ack cannot be nil") + } + if msg.ProofHeight == 0 { + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") + } + if err := msg.Acknowledgement.ValidateBasic(); err != nil { + return err + } + if msg.Signer.Empty() { + return sdkerrors.ErrInvalidAddress + } + + return msg.Packet.ValidateBasic() +} + +// GetSignBytes implements sdk.Msg +func (msg MsgAcknowledgement) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgAcknowledgement) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Signer} +} diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index 2165f8c4eb40..a6d324670200 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -1,10 +1,13 @@ package types import ( + "errors" "fmt" "testing" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/tendermint/tendermint/crypto/merkle" abci "github.com/tendermint/tendermint/abci/types" dbm "github.com/tendermint/tm-db" @@ -13,6 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -38,7 +42,7 @@ var ( invalidShortConnHops = []string{invalidShortConnection} invalidLongConnHops = []string{invalidLongConnection} - proof = commitment.Proof{} + proof = commitment.Proof{Proof: &merkle.Proof{}} addr = sdk.AccAddress("testaddr") ) @@ -347,3 +351,130 @@ func (suite *MsgTestSuite) TestMsgChannelCloseConfirm() { } } } + +var _ exported.PacketDataI = validPacketT{} + +type validPacketT struct{} + +func (validPacketT) GetBytes() []byte { + return []byte("testdata") +} + +func (validPacketT) GetTimeoutHeight() uint64 { + return 100 +} + +func (validPacketT) ValidateBasic() error { + return nil +} + +func (validPacketT) Type() string { + return "valid" +} + +var _ exported.PacketDataI = invalidPacketT{} + +type invalidPacketT struct{} + +func (invalidPacketT) GetBytes() []byte { + return []byte("testdata") +} + +func (invalidPacketT) GetTimeoutHeight() uint64 { + return 100 +} + +func (invalidPacketT) ValidateBasic() error { + return errors.New("invalid packet") +} + +func (invalidPacketT) Type() string { + return "invalid" +} + +// define variables used for testing +var ( + packet = NewPacket(validPacketT{}, 1, portid, chanid, cpportid, cpchanid) + invalidPacket = NewPacket(invalidPacketT{}, 0, portid, chanid, cpportid, cpchanid) + + emptyProof = commitment.Proof{Proof: nil} + invalidProofs1 = commitment.ProofI(nil) + invalidProofs2 = emptyProof + + addr1 = sdk.AccAddress("testaddr1") + emptyAddr sdk.AccAddress + + portid = "testportid" + chanid = "testchannel" + cpportid = "testcpport" + cpchanid = "testcpchannel" +) + +// TestMsgPacketRoute tests Route for MsgPacket +func TestMsgPacketRoute(t *testing.T) { + msg := NewMsgPacket(packet, proof, 1, addr1) + + require.Equal(t, cpportid, msg.Route()) +} + +// TestMsgPacketType tests Type for MsgPacket +func TestMsgPacketType(t *testing.T) { + msg := NewMsgPacket(packet, proof, 1, addr1) + + require.Equal(t, "valid", msg.Type()) +} + +// TestMsgPacketValidation tests ValidateBasic for MsgPacket +func TestMsgPacketValidation(t *testing.T) { + testMsgs := []MsgPacket{ + NewMsgPacket(packet, proof, 1, addr1), // valid msg + NewMsgPacket(packet, proof, 0, addr1), // proof height is zero + NewMsgPacket(packet, nil, 1, addr1), // missing proof + NewMsgPacket(packet, invalidProofs1, 1, addr1), // missing proof + NewMsgPacket(packet, invalidProofs2, 1, addr1), // proof contain empty proof + NewMsgPacket(packet, proof, 1, emptyAddr), // missing signer address + NewMsgPacket(invalidPacket, proof, 1, addr1), // invalid packet + } + + testCases := []struct { + msg MsgPacket + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "proof height is zero"}, + {testMsgs[2], false, "missing proof"}, + {testMsgs[3], false, "missing proof"}, + {testMsgs[4], false, "proof contain empty proof"}, + {testMsgs[5], false, "missing signer address"}, + {testMsgs[6], false, "invalid packet"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "Msg %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgPacketGetSignBytes tests GetSignBytes for MsgPacket +func TestMsgPacketGetSignBytes(t *testing.T) { + msg := NewMsgPacket(packet, proof, 1, addr1) + SubModuleCdc.RegisterConcrete(validPacketT{}, "test/validPacketT", nil) + res := msg.GetSignBytes() + + expected := `{"packet":{"data":{"type":"test/validPacketT","value":{}},"destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid"},"proof":{"type":"ibc/commitment/merkle/Proof","value":{"proof":{"ops":[]}}},"proof_height":"1","signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}` + require.Equal(t, expected, string(res)) +} + +// TestMsgPacketGetSigners tests GetSigners for MsgPacket +func TestMsgPacketGetSigners(t *testing.T) { + msg := NewMsgPacket(packet, proof, 1, addr1) + res := msg.GetSigners() + + expected := "[746573746164647231]" + require.Equal(t, expected, fmt.Sprintf("%v", res)) +} diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go index 7d8242d8db30..df9b78dd0cd5 100644 --- a/x/ibc/04-channel/types/packet.go +++ b/x/ibc/04-channel/types/packet.go @@ -1,46 +1,68 @@ package types import ( + "encoding/binary" + + "github.com/tendermint/tendermint/crypto/tmhash" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) +// CommitPacket appends bigendian encoded timeout height and commitment bytes +// and then returns the hash of the result bytes. +// TODO: no specification for packet commitment currently, +// make it spec compatible once we have it +func CommitPacket(data exported.PacketDataI) []byte { + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, data.GetTimeoutHeight()) + buf = append(buf, data.GetBytes()...) + return tmhash.Sum(buf) +} + +// CommitAcknowledgement returns the hash of commitment bytes +func CommitAcknowledgement(data exported.PacketDataI) []byte { + return tmhash.Sum(data.GetBytes()) +} + var _ exported.PacketI = Packet{} // Packet defines a type that carries data across different chains through IBC type Packet struct { + Data exported.PacketDataI `json:"data" yaml:"data"` // opaque value which can be defined by the application logic of the associated modules. + Sequence uint64 `json:"sequence" yaml:"sequence"` // number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. - Timeout uint64 `json:"timeout" yaml:"timeout"` // indicates a consensus height on the destination chain after which the Packet will no longer be processed, and will instead count as having timed-out. SourcePort string `json:"source_port" yaml:"source_port"` // identifies the port on the sending chain. SourceChannel string `json:"source_channel" yaml:"source_channel"` // identifies the channel end on the sending chain. DestinationPort string `json:"destination_port" yaml:"destination_port"` // identifies the port on the receiving chain. DestinationChannel string `json:"destination_channel" yaml:"destination_channel"` // identifies the channel end on the receiving chain. - Data []byte `json:"data" yaml:"data"` // opaque value which can be defined by the application logic of the associated modules. } // NewPacket creates a new Packet instance func NewPacket( - sequence, timeout uint64, sourcePort, sourceChannel, - destinationPort, destinationChannel string, data []byte, + data exported.PacketDataI, + sequence uint64, sourcePort, sourceChannel, + destinationPort, destinationChannel string, ) Packet { return Packet{ + Data: data, Sequence: sequence, - Timeout: timeout, SourcePort: sourcePort, SourceChannel: sourceChannel, DestinationPort: destinationPort, DestinationChannel: destinationChannel, - Data: data, } } +// Type exports Packet.Data.Type +func (p Packet) Type() string { + return p.Data.Type() +} + // GetSequence implements PacketI interface func (p Packet) GetSequence() uint64 { return p.Sequence } -// GetTimeoutHeight implements PacketI interface -func (p Packet) GetTimeoutHeight() uint64 { return p.Timeout } - // GetSourcePort implements PacketI interface func (p Packet) GetSourcePort() string { return p.SourcePort } @@ -54,7 +76,10 @@ func (p Packet) GetDestPort() string { return p.DestinationPort } func (p Packet) GetDestChannel() string { return p.DestinationChannel } // GetData implements PacketI interface -func (p Packet) GetData() []byte { return p.Data } +func (p Packet) GetData() exported.PacketDataI { return p.Data } + +// GetTimeoutHeight implements PacketI interface +func (p Packet) GetTimeoutHeight() uint64 { return p.Data.GetTimeoutHeight() } // ValidateBasic implements PacketI interface func (p Packet) ValidateBasic() error { @@ -85,34 +110,11 @@ func (p Packet) ValidateBasic() error { if p.Sequence == 0 { return sdkerrors.Wrap(ErrInvalidPacket, "packet sequence cannot be 0") } - if p.Timeout == 0 { + if p.Data.GetTimeoutHeight() == 0 { return sdkerrors.Wrap(ErrInvalidPacket, "packet timeout cannot be 0") } - if len(p.Data) == 0 { - return sdkerrors.Wrap(ErrInvalidPacket, "packet data cannot be empty") + if len(p.Data.GetBytes()) == 0 { + return sdkerrors.Wrap(ErrInvalidPacket, "packet data bytes cannot be empty") } - return nil + return p.Data.ValidateBasic() } - -var _ exported.PacketI = OpaquePacket{} - -// OpaquePacket is a Packet, but cloaked in an obscuring data type by the host -// state machine, such that a module cannot act upon it other than to pass it to -// the IBC handler -type OpaquePacket struct { - *Packet -} - -// NewOpaquePacket creates a new OpaquePacket instance -func NewOpaquePacket(sequence, timeout uint64, sourcePort, sourceChannel, - destinationPort, destinationChannel string, data []byte, -) OpaquePacket { - Packet := NewPacket( - sequence, timeout, sourcePort, sourceChannel, destinationPort, - destinationChannel, data, - ) - return OpaquePacket{&Packet} -} - -// GetData implements PacketI interface -func (op OpaquePacket) GetData() []byte { return nil } diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go index 00333d69f4b2..d819b6ed2399 100644 --- a/x/ibc/20-transfer/alias.go +++ b/x/ibc/20-transfer/alias.go @@ -35,13 +35,13 @@ var ( ) type ( - Keeper = keeper.Keeper - BankKeeper = types.BankKeeper - ChannelKeeper = types.ChannelKeeper - ClientKeeper = types.ClientKeeper - ConnectionKeeper = types.ConnectionKeeper - SupplyKeeper = types.SupplyKeeper - MsgTransfer = types.MsgTransfer - MsgRecvPacket = types.MsgRecvPacket - PacketData = types.PacketData + Keeper = keeper.Keeper + BankKeeper = types.BankKeeper + ChannelKeeper = types.ChannelKeeper + ClientKeeper = types.ClientKeeper + ConnectionKeeper = types.ConnectionKeeper + SupplyKeeper = types.SupplyKeeper + MsgTransfer = types.MsgTransfer + MsgRecvPacket = types.MsgRecvPacket + PacketDataTransfer = types.PacketDataTransfer ) diff --git a/x/ibc/20-transfer/client/rest/rest.go b/x/ibc/20-transfer/client/rest/rest.go index a43112f0cce3..61c6dc44daa6 100644 --- a/x/ibc/20-transfer/client/rest/rest.go +++ b/x/ibc/20-transfer/client/rest/rest.go @@ -6,8 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" - channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) const ( @@ -28,11 +26,3 @@ type TransferTxReq struct { Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` Source bool `json:"source" yaml:"source"` } - -// RecvPacketReq defines the properties of a receive packet request's body. -type RecvPacketReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - Packet channelexported.PacketI `json:"packet" yaml:"packet"` - Proofs []commitment.Proof `json:"proofs" yaml:"proofs"` - Height uint64 `json:"height" yaml:"height"` -} diff --git a/x/ibc/20-transfer/client/rest/tx.go b/x/ibc/20-transfer/client/rest/tx.go index de699c04e969..2413e4e8046e 100644 --- a/x/ibc/20-transfer/client/rest/tx.go +++ b/x/ibc/20-transfer/client/rest/tx.go @@ -15,7 +15,6 @@ import ( func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/transfer", RestPortID, RestChannelID), transferHandlerFn(cliCtx)).Methods("POST") - r.HandleFunc(fmt.Sprintf("/ibc/packets/receive"), recvPacketHandlerFn(cliCtx)).Methods("POST") } // transferHandlerFn implements a transfer handler @@ -71,48 +70,3 @@ func transferHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } - -// recvPacketHandlerFn implements a receive packet handler -// -// @Summary Receive packet -// @Tags IBC -// @Accept json -// @Produce json -// @Param body body rest.RecvPacketReq true "Receive packet request body" -// @Success 200 {object} PostRecvPacket "OK" -// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/packets/receive [post] -func recvPacketHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req RecvPacketReq - if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { - return - } - - req.BaseReq = req.BaseReq.Sanitize() - if !req.BaseReq.ValidateBasic(w) { - return - } - - fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - // create the message - msg := types.NewMsgRecvPacket( - req.Packet, - req.Proofs, - req.Height, - fromAddr, - ) - - if err := msg.ValidateBasic(); err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) - } -} diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 6dfcf0470e4d..877d20f01984 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -2,11 +2,39 @@ package transfer import ( sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) -// HandleMsgTransfer defines the sdk.Handler for MsgTransfer -func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) { +// NewHandler returns sdk.Handler for IBC token transfer module messages +func NewHandler(k Keeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + switch msg := msg.(type) { + case MsgTransfer: + return handleMsgTransfer(ctx, k, msg) + case channeltypes.MsgPacket: + switch data := msg.Data.(type) { + case PacketDataTransfer: // i.e fulfills the Data interface + return handlePacketDataTransfer(ctx, k, msg, data) + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 packet data type: %T", msg) + } + case channeltypes.MsgTimeout: + switch data := msg.Data.(type) { + case PacketDataTransfer: + return handleTimeoutDataTransfer(ctx, k, msg, data) + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 packet data type: %T", data) + } + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 message type: %T", msg) + } + } +} + +func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) { err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source) if err != nil { return nil, err @@ -26,11 +54,19 @@ func HandleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, }, nil } -// HandleMsgRecvPacket defines the sdk.Handler for MsgRecvPacket -func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (*sdk.Result, error) { - err := k.ReceivePacket(ctx, msg.Packet, msg.Proofs[0], msg.Height) +func handlePacketDataTransfer(ctx sdk.Context, k Keeper, msg channeltypes.MsgPacket, data types.PacketDataTransfer) (*sdk.Result, error) { + packet := msg.Packet + err := k.ReceiveTransfer(ctx, packet.SourcePort, packet.SourceChannel, packet.DestinationPort, packet.DestinationChannel, data) if err != nil { - return nil, err + panic(err) + // TODO: Source chain sent invalid packet, shutdown channel + } + + acknowledgement := types.AckDataTransfer{} + err = k.PacketExecuted(ctx, packet, acknowledgement) + if err != nil { + panic(err) + // TODO: This should not happen } ctx.EventManager().EmitEvent( @@ -41,6 +77,20 @@ func HandleMsgRecvPacket(ctx sdk.Context, k Keeper, msg MsgRecvPacket) (*sdk.Res ), ) + // packet receiving should not fail + return &sdk.Result{ + Events: ctx.EventManager().Events(), + }, nil +} + +func handleTimeoutDataTransfer(ctx sdk.Context, k Keeper, msg channeltypes.MsgTimeout, data types.PacketDataTransfer) (*sdk.Result, error) { + packet := msg.Packet + err := k.TimeoutTransfer(ctx, packet.SourcePort, packet.SourceChannel, packet.DestinationPort, packet.DestinationChannel, data) + if err != nil { + // This chain sent invalid packet + panic(err) + } + // packet timeout should not fail return &sdk.Result{ Events: ctx.EventManager().Events(), }, nil diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index d3db1ed739fc..9dcf9e9b1060 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -159,134 +159,46 @@ func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitment.Proof, h func (suite *HandlerTestSuite) TestHandleMsgTransfer() { source := true + handler := transfer.NewHandler(suite.app.TransferKeeper) + msg := transfer.NewMsgTransfer(testPort1, testChannel1, testCoins, testAddr1, testAddr2, source) - res, err := transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err := handler(suite.ctx, msg) suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // channel does not exist + suite.Require().Nil(res, "%+v", res) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err = handler(suite.ctx, msg) suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // next send sequence not found + suite.Require().Nil(res, "%+v", res) // next send sequence not found nextSeqSend := uint64(1) suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err = handler(suite.ctx, msg) suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // sender has insufficient coins + suite.Require().Nil(res, "%+v", res) // sender has insufficient coins _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err = handler(suite.ctx, msg) suite.Require().NoError(err) - suite.Require().NotNil(res, "%v", res) // successfully executed + suite.Require().NotNil(res, "%+v", res) // successfully executed // test when the source is false source = false msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, source) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + + res, err = handler(suite.ctx, msg) suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // incorrect denom prefix + suite.Require().Nil(res, "%+v", res) // incorrect denom prefix msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, source) suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) - res, err = transfer.HandleMsgTransfer(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().NoError(err) - suite.Require().NotNil(res, "%v", res) // successfully executed -} - -func (suite *HandlerTestSuite) TestHandleRecvPacket() { - packetSeq := uint64(1) - packetTimeout := uint64(100) - - packetDataBz := []byte("invaliddata") - packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - packetCommitmentPath := channel.KeyPacketCommitment(testPort2, testChannel2, packetSeq) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) - suite.updateClient() - proofPacket, proofHeight := suite.queryProof(packetCommitmentPath) - - msg := types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - res, err := transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // packet membership verification failed due to invalid counterparty packet commitment - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // invalid packet data - - // test when the source is true - source := true - - packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().NoError(err) - suite.Require().NotNil(res, "%v", res) // successfully executed - - // test when the source is false - source = false - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - - msg = types.NewMsgRecvPacket(packet, []commitment.Proof{proofPacket}, uint64(proofHeight), testAddr1) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) - suite.Require().Error(err) - suite.Require().Nil(res, "%v", res) // insufficient coins in the corresponding escrow account - escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - res, err = transfer.HandleMsgRecvPacket(suite.ctx, suite.app.IBCKeeper.TransferKeeper, msg) + res, err = handler(suite.ctx, msg) suite.Require().NoError(err) - suite.Require().NotNil(res, "%v", res) // successfully executed + suite.Require().NotNil(res, "%+v", res) // successfully executed } func TestHandlerTestSuite(t *testing.T) { diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go index b4c0675bed78..3e478a16c6c7 100644 --- a/x/ibc/20-transfer/keeper/callbacks.go +++ b/x/ibc/20-transfer/keeper/callbacks.go @@ -1,12 +1,19 @@ package keeper +// NOTE: +// OnChanOpenInit, OnChanOpenTry, OnChanOpenAck, OnChanOpenConfirm, OnChanCLoseConfirm +// will be implemented according to ADR15 in the future PRs. Code left for reference. +// +// OnRecvPacket, OnAcknowledgementPacket, OnTimeoutPacket has been implemented according +// to ADR15. + +/* import ( "strings" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -123,35 +130,6 @@ func (k Keeper) OnChanCloseConfirm( return nil } -// onRecvPacket is called when an FTTransfer packet is received -// nolint: unused -func (k Keeper) OnRecvPacket( - ctx sdk.Context, - packet channelexported.PacketI, -) error { - var data types.PacketData - - err := k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) - if err != nil { - return sdkerrors.Wrap(err, "invalid packet data") - } - - return k.ReceiveTransfer( - ctx, packet.GetSourcePort(), packet.GetSourceChannel(), - packet.GetDestPort(), packet.GetDestChannel(), data, - ) -} - -// nolint: unused -func (k Keeper) OnAcknowledgePacket( - ctx sdk.Context, - packet channelexported.PacketI, - acknowledgement []byte, -) error { - // no-op - return nil -} - // nolint: unused func (k Keeper) OnTimeoutPacket( ctx sdk.Context, @@ -191,8 +169,4 @@ func (k Keeper) OnTimeoutPacket( return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Sender, data.Amount) } - -// nolint: unused -func (k Keeper) OnTimeoutPacketClose(_ sdk.Context, _ channelexported.PacketI) { - panic("can't happen, only unordered channels allowed") -} +*/ diff --git a/x/ibc/20-transfer/keeper/callbacks_test.go b/x/ibc/20-transfer/keeper/callbacks_test.go index fb505cf190ac..171cb99e7306 100644 --- a/x/ibc/20-transfer/keeper/callbacks_test.go +++ b/x/ibc/20-transfer/keeper/callbacks_test.go @@ -1,11 +1,7 @@ package keeper_test -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" -) - +// TODO: move to 04-channel after CheckOpen implementation in the following PR +/* func (suite *KeeperTestSuite) TestOnChanOpenInit() { invalidOrder := channel.ORDERED @@ -52,117 +48,4 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenAck(suite.ctx, testPort1, testChannel1, "") suite.NoError(err) // successfully executed } - -func (suite *KeeperTestSuite) TestOnRecvPacket() { - packetSeq := uint64(1) - packetTimeout := uint64(100) - - packetDataBz := []byte("invaliddata") - packet := channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - err := suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.Error(err) // invalid packet data - - // when the source is true - source := true - - packetData := types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.NoError(err) // successfully executed - - totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) - suite.Equal(testPrefixedCoins2, totalSupply.GetTotal()) // supply should be inflated - - receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) - suite.Equal(testPrefixedCoins2, receiverCoins) - - // when the source is false - source = false - - packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.Error(err) // insufficient coins in the corresponding escrow account - - escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) - err = suite.app.IBCKeeper.TransferKeeper.OnRecvPacket(suite.ctx, packet) - suite.NoError(err) // successfully executed - - receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) - suite.Equal(testCoins, receiverCoins) -} - -func (suite *KeeperTestSuite) TestOnTimeoutPacket() { - packetSeq := uint64(1) - packetTimeout := uint64(100) - - packetDataBz := []byte("invaliddata") - packet := channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - err := suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.Error(err) // invalid packet data - - // when the source is true - source := true - - packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.Error(err) // insufficient coins in the corresponding escrow account - - escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.NoError(err) // successfully executed - - senderCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Sender) - suite.Equal(testCoins, senderCoins) - - escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) - suite.Equal(sdk.Coins(nil), escrowCoins) - - // when the source is false - source = false - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort1, testChannel1, testPort2, testChannel2, packetDataBz) - - _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Sender, sdk.Coins{}) - err = suite.app.IBCKeeper.TransferKeeper.OnTimeoutPacket(suite.ctx, packet) - suite.NoError(err) // successfully executed - - totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) - suite.Equal(testPrefixedCoins1, totalSupply.GetTotal()) // supply should be inflated - - senderCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Sender) - suite.Equal(testPrefixedCoins1, senderCoins) -} +*/ diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index 341f75374881..05639f581b14 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" @@ -19,10 +20,8 @@ const ( // Keeper defines the IBC transfer keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - - // Capability key and port to which ICS20 is binded. Used for packet relaying. + storeKey sdk.StoreKey + cdc *codec.Codec boundedCapability sdk.CapabilityKey clientKeeper types.ClientKeeper @@ -34,9 +33,8 @@ type Keeper struct { // NewKeeper creates a new IBC transfer Keeper instance func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, - capKey sdk.CapabilityKey, clientKeeper types.ClientKeeper, - connnectionKeeper types.ConnectionKeeper, channelKeeper types.ChannelKeeper, + cdc *codec.Codec, key sdk.StoreKey, capKey sdk.CapabilityKey, + channelKeeper types.ChannelKeeper, bankKeeper types.BankKeeper, supplyKeeper types.SupplyKeeper, ) Keeper { @@ -49,8 +47,6 @@ func NewKeeper( storeKey: key, cdc: cdc, boundedCapability: capKey, - clientKeeper: clientKeeper, - connectionKeeper: connnectionKeeper, channelKeeper: channelKeeper, bankKeeper: bankKeeper, supplyKeeper: supplyKeeper, @@ -66,3 +62,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { func (k Keeper) GetTransferAccount(ctx sdk.Context) supplyexported.ModuleAccountI { return k.supplyKeeper.GetModuleAccount(ctx, types.GetModuleAccountName()) } + +func (k Keeper) PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketDataI) error { + return k.channelKeeper.PacketExecuted(ctx, packet, acknowledgement) +} diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index cc67265bb1f8..b4d4132c7109 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -74,7 +74,7 @@ func (suite *KeeperTestSuite) TestGetTransferAccount() { expectedMaccName := types.GetModuleAccountName() expectedMaccAddr := sdk.AccAddress(crypto.AddressHash([]byte(expectedMaccName))) - macc := suite.app.IBCKeeper.TransferKeeper.GetTransferAccount(suite.ctx) + macc := suite.app.TransferKeeper.GetTransferAccount(suite.ctx) suite.NotNil(macc) suite.Equal(expectedMaccName, macc.GetName()) diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index f30d59de04fb..d58412d26b1d 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -5,10 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // SendTransfer handles transfer sending logic @@ -51,22 +49,6 @@ func (k Keeper) SendTransfer( return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, coins, sender, receiver, isSourceChain) } -// ReceivePacket handles receiving packet -func (k Keeper) ReceivePacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, height uint64) error { - _, err := k.channelKeeper.RecvPacket(ctx, packet, proof, height, []byte{}, k.boundedCapability) - if err != nil { - return err - } - - var data types.PacketData - err = k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) - if err != nil { - return sdkerrors.Wrap(err, "invalid packet data") - } - - return k.ReceiveTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestPort(), packet.GetDestChannel(), data) -} - // ReceiveTransfer handles transfer receiving logic func (k Keeper) ReceiveTransfer( ctx sdk.Context, @@ -74,7 +56,7 @@ func (k Keeper) ReceiveTransfer( sourceChannel, destinationPort, destinationChannel string, - data types.PacketData, + data types.PacketDataTransfer, ) error { if data.Source { prefix := types.GetDenomPrefix(destinationPort, destinationChannel) @@ -117,6 +99,40 @@ func (k Keeper) ReceiveTransfer( } +// TimeoutTransfer handles transfer timeout logic +func (k Keeper) TimeoutTransfer( + ctx sdk.Context, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel string, + data types.PacketDataTransfer, +) error { + // check the denom prefix + prefix := types.GetDenomPrefix(sourcePort, sourceChannel) + coins := make(sdk.Coins, len(data.Amount)) + for i, coin := range data.Amount { + coin := coin + if !strings.HasPrefix(coin.Denom, prefix) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "%s doesn't contain the prefix '%s'", coin.Denom, prefix) + } + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) + } + + if data.Source { + escrowAddress := types.GetEscrowAddress(destinationPort, destinationChannel) + return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Sender, coins) + } + + // mint from supply + err := k.supplyKeeper.MintCoins(ctx, types.GetModuleAccountName(), data.Amount) + if err != nil { + return err + } + + return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Sender, data.Amount) +} + func (k Keeper) createOutgoingPacket( ctx sdk.Context, seq uint64, @@ -175,22 +191,15 @@ func (k Keeper) createOutgoingPacket( } } - packetData := types.NewPacketData(amount, sender, receiver, isSourceChain) - - // TODO: This should be hashed (for the commitment in the store). - packetDataBz, err := k.cdc.MarshalBinaryBare(packetData) - if err != nil { - return sdkerrors.Wrap(err, "invalid packet data") - } + packetData := types.NewPacketDataTransfer(amount, sender, receiver, isSourceChain, uint64(ctx.BlockHeight())+DefaultPacketTimeout) packet := channel.NewPacket( + packetData, seq, - uint64(ctx.BlockHeight())+DefaultPacketTimeout, sourcePort, sourceChannel, destinationPort, destinationChannel, - packetDataBz, ) return k.channelKeeper.SendPacket(ctx, packet, k.boundedCapability) diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 79b84c13716a..b22135c409b3 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -101,20 +101,20 @@ func (suite *KeeperTestSuite) TestSendTransfer() { // test the situation where the source is true isSourceChain := true - err := suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err := suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // next send sequence not found nextSeqSend := uint64(1) suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // sender has insufficient coins _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testCoins) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.NoError(err) // successfully executed senderCoins := suite.app.BankKeeper.GetCoins(suite.ctx, testAddr1) @@ -134,12 +134,12 @@ func (suite *KeeperTestSuite) TestSendTransfer() { isSourceChain = false _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins2) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, isSourceChain) suite.Error(err) // incorrect denom prefix suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) _ = suite.app.BankKeeper.SetCoins(suite.ctx, testAddr1, testPrefixedCoins1) - err = suite.app.IBCKeeper.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, isSourceChain) suite.NoError(err) // successfully executed senderCoins = suite.app.BankKeeper.GetCoins(suite.ctx, testAddr1) @@ -152,13 +152,14 @@ func (suite *KeeperTestSuite) TestSendTransfer() { func (suite *KeeperTestSuite) TestReceiveTransfer() { // test the situation where the source is true source := true + packetTimeout := uint64(100) - packetData := types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - err := suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + packetData := types.NewPacketDataTransfer(testPrefixedCoins1, testAddr1, testAddr2, source, packetTimeout) + err := suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.Error(err) // incorrect denom prefix packetData.Amount = testPrefixedCoins2 - err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.NoError(err) // successfully executed totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) @@ -171,17 +172,17 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { packetData.Source = false packetData.Amount = testPrefixedCoins2 - err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.Error(err) // incorrect denom prefix packetData.Amount = testPrefixedCoins1 - err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.Error(err) // insufficient coins in the corresponding escrow account escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) - err = suite.app.IBCKeeper.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) + err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) suite.NoError(err) // successfully executed escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) @@ -190,95 +191,3 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) suite.Equal(testCoins, receiverCoins) } - -func (suite *KeeperTestSuite) TestReceivePacket() { - packetSeq := uint64(1) - packetTimeout := uint64(100) - - packetDataBz := []byte("invaliddata") - packet := channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort2, testChannel1, packetDataBz) - packetCommitmentPath := channel.KeyPacketCommitment(testPort2, testChannel2, packetSeq) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, []byte("invalidcommitment")) - suite.updateClient() - proofPacket, proofHeight := suite.queryProof(packetCommitmentPath) - - suite.createChannel(testPort2, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - err := suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // invalid port id - - packet.DestinationPort = testPort1 - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // packet membership verification failed due to invalid counterparty packet commitment - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // invalid packet data - - // test the situation where the source is true - source := true - - packetData := types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.NoError(err) // successfully executed - - totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) - suite.Equal(testPrefixedCoins1, totalSupply.GetTotal()) // supply should be inflated - - receiverCoins := suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) - suite.Equal(testPrefixedCoins1, receiverCoins) - - // test the situation where the source is false - source = false - - packetData = types.NewPacketData(testPrefixedCoins1, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // invalid denom prefix - - packetData = types.NewPacketData(testPrefixedCoins2, testAddr1, testAddr2, source) - packetDataBz, _ = suite.cdc.MarshalBinaryBare(packetData) - packet = channel.NewPacket(packetSeq, packetTimeout, testPort2, testChannel2, testPort1, testChannel1, packetDataBz) - - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort2, testChannel2, packetSeq, packetDataBz) - suite.updateClient() - proofPacket, proofHeight = suite.queryProof(packetCommitmentPath) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.Error(err) // insufficient coins in the corresponding escrow account - - escrowAddress := types.GetEscrowAddress(testPort1, testChannel1) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, escrowAddress, testCoins) - _ = suite.app.BankKeeper.SetCoins(suite.ctx, packetData.Receiver, sdk.Coins{}) - err = suite.app.IBCKeeper.TransferKeeper.ReceivePacket(suite.ctx, packet, proofPacket, uint64(proofHeight)) - suite.NoError(err) // successfully executed - - receiverCoins = suite.app.BankKeeper.GetCoins(suite.ctx, packetData.Receiver) - suite.Equal(testCoins, receiverCoins) - - escrowCoins := suite.app.BankKeeper.GetCoins(suite.ctx, escrowAddress) - suite.Equal(sdk.Coins(nil), escrowCoins) -} diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index f29136061cde..914f4d148c71 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -1,31 +1,109 @@ package transfer import ( + "encoding/json" + "github.com/gorilla/mux" "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) +const ( + ModuleName = types.SubModuleName +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +type AppModuleBasic struct{} + // Name returns the IBC transfer ICS name -func Name() string { +func (AppModuleBasic) Name() string { return SubModuleName } -// RegisterRESTRoutes registers the REST routes for the IBC transfer -func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { +func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { + RegisterCodec(cdc) +} + +func (AppModuleBasic) DefaultGenesis() json.RawMessage { + return nil +} + +func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { + return nil +} + +func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { rest.RegisterRoutes(ctx, rtr) } -// GetTxCmd returns the root tx command for the IBC transfer. -func GetTxCmd(cdc *codec.Codec) *cobra.Command { +func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { return cli.GetTxCmd(cdc) } -// GetQueryCmd returns the root tx command for the IBC transfer. -func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { - return cli.GetQueryCmd(cdc, queryRoute) +func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetQueryCmd(cdc, QuerierRoute) +} + +type AppModule struct { + AppModuleBasic + keeper Keeper +} + +func NewAppModule(k Keeper) AppModule { + return AppModule{ + keeper: k, + } +} + +func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { + // TODO +} + +func (AppModule) Route() string { + return RouterKey +} + +func (am AppModule) NewHandler() sdk.Handler { + return NewHandler(am.keeper) +} + +func (AppModule) QuerierRoute() string { + return QuerierRoute +} + +func (am AppModule) NewQuerierHandler() sdk.Querier { + return nil +} + +// InitGenesis performs genesis initialization for the staking module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { + // check if the IBC transfer module account is set + InitGenesis(ctx, am.keeper) + return []abci.ValidatorUpdate{} +} + +func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { + return nil +} + +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { + +} + +func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} } diff --git a/x/ibc/20-transfer/types/codec.go b/x/ibc/20-transfer/types/codec.go index ba018b3fc676..1b9680c8da3d 100644 --- a/x/ibc/20-transfer/types/codec.go +++ b/x/ibc/20-transfer/types/codec.go @@ -8,8 +8,7 @@ import ( func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgTransfer{}, "ibc/transfer/MsgTransfer", nil) - cdc.RegisterConcrete(MsgRecvPacket{}, "ibc/transfer/MsgRecvPacket", nil) - cdc.RegisterConcrete(PacketData{}, "ibc/transfer/PacketData", nil) + cdc.RegisterConcrete(PacketDataTransfer{}, "ibc/transfer/PacketDataTransfer", nil) } var ModuleCdc = codec.New() diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index e7c709306228..a8bd48a215de 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -6,7 +6,6 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" ) @@ -20,7 +19,7 @@ type ChannelKeeper interface { GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channel.Channel, found bool) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) SendPacket(ctx sdk.Context, packet channelexported.PacketI, portCapability sdk.CapabilityKey) error - RecvPacket(ctx sdk.Context, packet channelexported.PacketI, proof commitment.ProofI, proofHeight uint64, acknowledgement []byte, portCapability sdk.CapabilityKey) (channelexported.PacketI, error) + PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketDataI) error } // ClientKeeper defines the expected IBC client keeper diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go index 935f94f0419f..42e55d32677c 100644 --- a/x/ibc/20-transfer/types/msgs_test.go +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -5,11 +5,8 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/merkle" sdk "github.com/cosmos/cosmos-sdk/types" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -24,17 +21,7 @@ const ( invalidLongChannel = "invalidlongchannelinvalidlongchannel" ) -// define variables used for testing var ( - packet = channel.NewPacket(1, 100, "testportid", "testchannel", "testcpport", "testcpchannel", []byte("testdata")) - invalidPacket = channel.NewPacket(0, 100, "testportid", "testchannel", "testcpport", "testcpchannel", []byte{}) - - proof = commitment.Proof{Proof: &merkle.Proof{}} - emptyProof = commitment.Proof{Proof: nil} - proofs = []commitment.Proof{proof} - invalidProofs1 = []commitment.Proof{} - invalidProofs2 = []commitment.Proof{emptyProof} - addr1 = sdk.AccAddress("testaddr1") addr2 = sdk.AccAddress("testaddr2") emptyAddr sdk.AccAddress @@ -120,71 +107,3 @@ func TestMsgTransferGetSigners(t *testing.T) { expected := "[746573746164647231]" require.Equal(t, expected, fmt.Sprintf("%v", res)) } - -// TestMsgRecvPacketRoute tests Route for MsgRecvPacket -func TestMsgRecvPacketRoute(t *testing.T) { - msg := NewMsgRecvPacket(packet, proofs, 1, addr1) - - require.Equal(t, ibctypes.RouterKey, msg.Route()) -} - -// TestMsgRecvPacketType tests Type for MsgRecvPacket -func TestMsgRecvPacketType(t *testing.T) { - msg := NewMsgRecvPacket(packet, proofs, 1, addr1) - - require.Equal(t, "recv_packet", msg.Type()) -} - -// TestMsgRecvPacketValidation tests ValidateBasic for MsgRecvPacket -func TestMsgRecvPacketValidation(t *testing.T) { - testMsgs := []MsgRecvPacket{ - NewMsgRecvPacket(packet, proofs, 1, addr1), // valid msg - NewMsgRecvPacket(packet, proofs, 0, addr1), // proof height is zero - NewMsgRecvPacket(packet, nil, 1, addr1), // missing proofs - NewMsgRecvPacket(packet, invalidProofs1, 1, addr1), // missing proofs - NewMsgRecvPacket(packet, invalidProofs2, 1, addr1), // proofs contain empty proof - NewMsgRecvPacket(packet, proofs, 1, emptyAddr), // missing signer address - NewMsgRecvPacket(invalidPacket, proofs, 1, addr1), // invalid packet - } - - testCases := []struct { - msg MsgRecvPacket - expPass bool - errMsg string - }{ - {testMsgs[0], true, ""}, - {testMsgs[1], false, "proof height is zero"}, - {testMsgs[2], false, "missing proofs"}, - {testMsgs[3], false, "missing proofs"}, - {testMsgs[4], false, "proofs contain empty proof"}, - {testMsgs[5], false, "missing signer address"}, - {testMsgs[6], false, "invalid packet"}, - } - - for i, tc := range testCases { - err := tc.msg.ValidateBasic() - if tc.expPass { - require.NoError(t, err, "Msg %d failed: %v", i, err) - } else { - require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) - } - } -} - -// TestMsgRecvPacketGetSignBytes tests GetSignBytes for MsgRecvPacket -func TestMsgRecvPacketGetSignBytes(t *testing.T) { - msg := NewMsgRecvPacket(packet, proofs, 1, addr1) - res := msg.GetSignBytes() - - expected := `{"type":"ibc/transfer/MsgRecvPacket","value":{"height":"1","packet":{"type":"ibc/channel/Packet","value":{"data":"dGVzdGRhdGE=","destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid","timeout":"100"}},"proofs":[{"proof":{"ops":[]}}],"signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}}` - require.Equal(t, expected, string(res)) -} - -// TestMsgRecvPacketGetSigners tests GetSigners for MsgRecvPacket -func TestMsgRecvPacketGetSigners(t *testing.T) { - msg := NewMsgRecvPacket(packet, proofs, 1, addr1) - res := msg.GetSigners() - - expected := "[746573746164647231]" - require.Equal(t, expected, fmt.Sprintf("%v", res)) -} diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go index 19aed7c60343..189ae9b40c63 100644 --- a/x/ibc/20-transfer/types/packet.go +++ b/x/ibc/20-transfer/types/packet.go @@ -5,28 +5,34 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" ) -// PacketData defines a struct for the packet payload -type PacketData struct { +var _ channelexported.PacketDataI = PacketDataTransfer{} + +// PacketDataTransfer defines a struct for the packet payload +type PacketDataTransfer struct { Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred + Timeout uint64 `json:"timeout" yaml:"timeout"` } -// NewPacketData contructs a new PacketData -func NewPacketData(amount sdk.Coins, sender, receiver sdk.AccAddress, source bool) PacketData { - return PacketData{ +// NewPacketDataTransfer contructs a new PacketDataTransfer +func NewPacketDataTransfer(amount sdk.Coins, sender, receiver sdk.AccAddress, source bool, timeout uint64) PacketDataTransfer { + return PacketDataTransfer{ Amount: amount, Sender: sender, Receiver: receiver, Source: source, + Timeout: timeout, } } -func (pd PacketData) String() string { - return fmt.Sprintf(`PacketData: +func (pd PacketDataTransfer) String() string { + return fmt.Sprintf(`PacketDataTransfer: Amount: %s Sender: %s Receiver: %s @@ -38,8 +44,9 @@ func (pd PacketData) String() string { ) } +// Implements channelexported.PacketDataI // ValidateBasic performs a basic check of the packet fields -func (pd PacketData) ValidateBasic() error { +func (pd PacketDataTransfer) ValidateBasic() error { if !pd.Amount.IsAllPositive() { return sdkerrors.ErrInsufficientFunds } @@ -54,3 +61,44 @@ func (pd PacketData) ValidateBasic() error { } return nil } + +// Implements channelexported.PacketDataI +func (pd PacketDataTransfer) GetBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(pd)) +} + +// Implements channelexported.PacketDataI +func (pd PacketDataTransfer) GetTimeoutHeight() uint64 { + return pd.Timeout +} + +// Implements channelexported.PacketDataI +func (pd PacketDataTransfer) Type() string { + return "ics20/transfer" +} + +var _ channelexported.PacketDataI = AckDataTransfer{} + +type AckDataTransfer struct { +} + +// Implements channelexported.PacketDataI +// ValidateBasic performs a basic check of the packet fields +func (ack AckDataTransfer) ValidateBasic() error { + return nil +} + +// Implements channelexported.PacketDataI +func (ack AckDataTransfer) GetBytes() []byte { + return []byte("ok") +} + +// Implements channelexported.PacketDataI +func (ack AckDataTransfer) GetTimeoutHeight() uint64 { + return 0 +} + +// Implements channelexported.PacketDataI +func (ack AckDataTransfer) Type() string { + return "ics20/transfer/ack" +} diff --git a/x/ibc/20-transfer/types/packet_test.go b/x/ibc/20-transfer/types/packet_test.go index 8471fb0cf2da..1a3c1b46fc16 100644 --- a/x/ibc/20-transfer/types/packet_test.go +++ b/x/ibc/20-transfer/types/packet_test.go @@ -6,34 +6,34 @@ import ( "github.com/stretchr/testify/require" ) -// TestPacketDataValidation tests ValidateBasic for PacketData -func TestPacketDataValidation(t *testing.T) { - testPacketData := []PacketData{ - NewPacketData(coins, addr1, addr2, true), // valid msg - NewPacketData(invalidDenomCoins, addr1, addr2, true), // invalid amount - NewPacketData(negativeCoins, addr1, addr2, false), // amount contains negative coin - NewPacketData(coins, emptyAddr, addr2, false), // missing sender address - NewPacketData(coins, addr1, emptyAddr, false), // missing recipient address +// TestPacketDataTransferValidation tests ValidateBasic for PacketDataTransfer +func TestPacketDataTransferValidation(t *testing.T) { + testPacketDataTransfer := []PacketDataTransfer{ + NewPacketDataTransfer(coins, addr1, addr2, true, 100), // valid msg + NewPacketDataTransfer(invalidDenomCoins, addr1, addr2, true, 100), // invalid amount + NewPacketDataTransfer(negativeCoins, addr1, addr2, false, 100), // amount contains negative coin + NewPacketDataTransfer(coins, emptyAddr, addr2, false, 100), // missing sender address + NewPacketDataTransfer(coins, addr1, emptyAddr, false, 100), // missing recipient address } testCases := []struct { - packetData PacketData + packetData PacketDataTransfer expPass bool errMsg string }{ - {testPacketData[0], true, ""}, - {testPacketData[1], false, "invalid amount"}, - {testPacketData[2], false, "amount contains negative coin"}, - {testPacketData[3], false, "missing sender address"}, - {testPacketData[4], false, "missing recipient address"}, + {testPacketDataTransfer[0], true, ""}, + {testPacketDataTransfer[1], false, "invalid amount"}, + {testPacketDataTransfer[2], false, "amount contains negative coin"}, + {testPacketDataTransfer[3], false, "missing sender address"}, + {testPacketDataTransfer[4], false, "missing recipient address"}, } for i, tc := range testCases { err := tc.packetData.ValidateBasic() if tc.expPass { - require.NoError(t, err, "PacketData %d failed: %v", i, err) + require.NoError(t, err, "PacketDataTransfer %d failed: %v", i, err) } else { - require.Error(t, err, "Invalid PacketData %d passed: %s", i, tc.errMsg) + require.Error(t, err, "Invalid PacketDataTransfer %d passed: %s", i, tc.errMsg) } } } diff --git a/x/ibc/ante.go b/x/ibc/ante.go deleted file mode 100644 index 0e1f7f635d70..000000000000 --- a/x/ibc/ante.go +++ /dev/null @@ -1,51 +0,0 @@ -package ibc - -// // TODO: Should extract timeout msgs too -// func ExtractMsgPackets(msgs []sdk.Msg) (res []MsgPacket, abort bool) { -// res = make([]MsgPacket, 0, len(msgs)) -// for _, msg := range msgs { -// msgp, ok := msg.(MsgPacket) -// if ok { -// res = append(res, msgp) -// } -// } - -// if len(res) >= 2 { -// first := res[0] -// for _, msg := range res[1:] { -// if len(msg.ChannelID) != 0 && msg.ChannelID != first.ChannelID { -// return res, true -// } -// msg.ChannelID = first.ChannelID -// } -// } - -// return -// } - -// func VerifyMsgPackets(ctx sdk.Context, channel channel.Manager, msgs []MsgPacket) error { -// for _, msg := range msgs { -// err := channel.Receive(ctx, msg.Proofs, msg.Height, msg.ReceiverPort(), msg.ChannelID, msg.Packet) -// if err != nil { -// return err -// } -// } - -// return nil -// } - -// func NewAnteDecorator(channel channel.Manager) sdk.AnteDecorator { -// return func(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { -// msgs, abort := ExtractMsgPackets(tx.GetMsgs()) -// if abort { -// return ctx, host.ErrInvalidPacket -// } - -// err := VerifyMsgPackets(ctx, channel, msgs) -// if err != nil { -// return ctx, sdkerrors.Wrap(host.ErrInvalidPacket, err.Error()) -// } - -// return next(ctx, tx, simulate) -// } -// } diff --git a/x/ibc/ante/ante.go b/x/ibc/ante/ante.go new file mode 100644 index 000000000000..1873c2edf612 --- /dev/null +++ b/x/ibc/ante/ante.go @@ -0,0 +1,47 @@ +package ante + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" +) + +// ProofVerificationDecorator handles messages that contains application specific packet types, +// including MsgPacket, MsgAcknowledgement, MsgTimeout. +// MsgUpdateClients are also handled here to perform atomic multimsg transaction +type ProofVerificationDecorator struct { + clientKeeper client.Keeper + channelKeeper channel.Keeper +} + +// NewProofVerificationDecorator constructs new ProofverificationDecorator +func NewProofVerificationDecorator(clientKeeper client.Keeper, channelKeeper channel.Keeper) ProofVerificationDecorator { + return ProofVerificationDecorator{ + clientKeeper: clientKeeper, + channelKeeper: channelKeeper, + } +} + +// AnteHandle executes MsgUpdateClient, MsgPacket, MsgAcknowledgement, MsgTimeout. +// The packet execution messages are then passed to the respective application handlers. +func (pvr ProofVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + for _, msg := range tx.GetMsgs() { + var err error + switch msg := msg.(type) { + case client.MsgUpdateClient: + err = pvr.clientKeeper.UpdateClient(ctx, msg.ClientID, msg.Header) + case channel.MsgPacket: + _, err = pvr.channelKeeper.RecvPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight) + case channel.MsgAcknowledgement: + _, err = pvr.channelKeeper.AcknowledgePacket(ctx, msg.Packet, msg.Acknowledgement, msg.Proof, msg.ProofHeight) + case channel.MsgTimeout: + _, err = pvr.channelKeeper.TimeoutPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight, msg.NextSequenceRecv) + } + + if err != nil { + return ctx, err + } + } + + return next(ctx, tx, simulate) +} diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go new file mode 100644 index 000000000000..b23f9fbeefcf --- /dev/null +++ b/x/ibc/ante/ante_test.go @@ -0,0 +1,272 @@ +package ante_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/cosmos/cosmos-sdk/x/ibc/ante" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// define constants used for testing +const ( + testChainID = "test-chain-id" + testClient = "test-client" + testClientType = clientexported.Tendermint + + testConnection = "testconnection" + + testChannelVersion = "1.0" +) + +// define variables used for testing +type HandlerTestSuite struct { + suite.Suite + + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet +} + +func (suite *HandlerTestSuite) SetupTest() { + isCheckTx := false + app := simapp.Setup(isCheckTx) + + suite.cdc = app.Codec() + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.app = app + + privVal := tmtypes.NewMockPV() + + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + suite.createClient() + suite.createConnection(connection.OPEN) +} + +func (suite *HandlerTestSuite) createClient() { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + NextValidatorSet: suite.valSet, + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + suite.NoError(err) +} + +func (suite *HandlerTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := clienttypestm.ConsensusState{ + ChainID: testChainID, + Height: uint64(commitID.Version), + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) + suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) +} + +func (suite *HandlerTestSuite) createConnection(state connection.State) { + connection := connection.ConnectionEnd{ + State: state, + ClientID: testClient, + Counterparty: connection.Counterparty{ + ClientID: testClient, + ConnectionID: testConnection, + Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + }, + Versions: connection.GetCompatibleVersions(), + } + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) +} + +func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channel.State, order channel.Order) { + ch := channel.Channel{ + State: state, + Ordering: order, + Counterparty: channel.Counterparty{ + PortID: counterpartyPort, + ChannelID: counterpartyChan, + }, + ConnectionHops: []string{connID}, + Version: testChannelVersion, + } + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) +} + +func (suite *HandlerTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: []byte(key), + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + +func (suite *HandlerTestSuite) newTx(msg sdk.Msg) sdk.Tx { + return auth.StdTx{ + Msgs: []sdk.Msg{msg}, + } +} + +func (suite *HandlerTestSuite) TestHandleMsgPacketOrdered() { + handler := sdk.ChainAnteDecorators(ante.NewProofVerificationDecorator( + suite.app.IBCKeeper.ClientKeeper, + suite.app.IBCKeeper.ChannelKeeper, + )) + + packet := channel.NewPacket(newPacket(12345), 1, portid, chanid, cpportid, cpchanid) + + cctx, _ := suite.ctx.CacheContext() + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, packet.SourcePort, packet.SourceChannel, 1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, packet.SourcePort, packet.SourceChannel, packet.Sequence, channeltypes.CommitPacket(packet.Data)) + msg := channel.NewMsgPacket(packet, nil, 0, addr1) + _, err := handler(cctx, suite.newTx(msg), false) + suite.Error(err, "%+v", err) // channel does not exist + + cctx, _ = suite.ctx.CacheContext() + suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channel.OPEN, channel.ORDERED) + packetCommitmentPath := channel.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, packet.Sequence) + proof, proofHeight := suite.queryProof(packetCommitmentPath) + msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) + _, err = handler(cctx, suite.newTx(msg), false) + suite.Error(err, "%+v", err) // invalid proof + + suite.updateClient() + cctx, _ = suite.ctx.CacheContext() + proof, proofHeight = suite.queryProof(packetCommitmentPath) + msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) + _, err = handler(cctx, suite.newTx(msg), false) + suite.Error(err, "%+v", err) // next recvseq not set + + proof, proofHeight = suite.queryProof(packetCommitmentPath) + msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, cpportid, cpchanid, 1) + cctx, write := suite.ctx.CacheContext() + + for i := 0; i < 10; i++ { + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(cctx, cpportid, cpchanid, uint64(i)) + _, err := handler(cctx, suite.newTx(msg), false) + if i == 1 { + suite.NoError(err, "%d", i) // successfully executed + write() + } else { + suite.Error(err, "%d", i) // wrong incoming sequence + } + } +} + +func (suite *HandlerTestSuite) TestHandleMsgPacketUnordered() { + handler := sdk.ChainAnteDecorators(ante.NewProofVerificationDecorator( + suite.app.IBCKeeper.ClientKeeper, + suite.app.IBCKeeper.ChannelKeeper, + )) + + // Not testing nonexist channel, invalid proof, nextseqsend, they are already tested in TestHandleMsgPacketOrdered + + var packet channeltypes.Packet + for i := 0; i < 5; i++ { + packet = channel.NewPacket(newPacket(uint64(i)), uint64(i), portid, chanid, cpportid, cpchanid) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, packet.SourcePort, packet.SourceChannel, uint64(i), channeltypes.CommitPacket(packet.Data)) + } + + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, packet.SourcePort, packet.SourceChannel, uint64(10)) + + suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channel.OPEN, channel.UNORDERED) + + suite.updateClient() + + for i := 10; i >= 0; i-- { + cctx, write := suite.ctx.CacheContext() + packet = channel.NewPacket(newPacket(uint64(i)), uint64(i), portid, chanid, cpportid, cpchanid) + packetCommitmentPath := channel.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, uint64(i)) + proof, proofHeight := suite.queryProof(packetCommitmentPath) + msg := channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) + _, err := handler(cctx, suite.newTx(msg), false) + if i < 5 { + suite.NoError(err, "%d", i) // successfully executed + write() + } else { + suite.Error(err, "%d", i) // wrong incoming sequence + } + } +} +func TestHandlerTestSuite(t *testing.T) { + suite.Run(t, new(HandlerTestSuite)) +} + +var _ channelexported.PacketDataI = packetT{} + +type packetT struct { + Data uint64 +} + +func (packet packetT) GetBytes() []byte { + return []byte(fmt.Sprintf("%d", packet.Data)) +} + +func (packetT) GetTimeoutHeight() uint64 { + return 100 +} + +func (packetT) ValidateBasic() error { + return nil +} + +func (packetT) Type() string { + return "valid" +} + +func newPacket(data uint64) packetT { + return packetT{data} +} + +// define variables used for testing +var ( + addr1 = sdk.AccAddress("testaddr1") + + portid = "testportid" + chanid = "testchannel" + cpportid = "testcpport" + cpchanid = "testcpchannel" +) diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index cb095b788a52..6a98669c858e 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -9,7 +9,6 @@ import ( ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -27,7 +26,6 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ibcclient.GetTxCmd(cdc, storeKey), connection.GetTxCmd(cdc, storeKey), channel.GetTxCmd(cdc, storeKey), - transfer.GetTxCmd(cdc), )...) return ibcTxCmd } @@ -47,7 +45,6 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { ibcclient.GetQueryCmd(cdc, queryRoute), connection.GetQueryCmd(cdc, queryRoute), channel.GetQueryCmd(cdc, queryRoute), - transfer.GetQueryCmd(cdc, queryRoute), )...) return ibcQueryCmd } diff --git a/x/ibc/client/rest/rest.go b/x/ibc/client/rest/rest.go index f593ba135760..2e0d96e0ec6d 100644 --- a/x/ibc/client/rest/rest.go +++ b/x/ibc/client/rest/rest.go @@ -7,7 +7,6 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" ) // RegisterRoutes - Central function to define routes that get registered by the main application @@ -15,5 +14,4 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) client.RegisterRESTRoutes(cliCtx, r, queryRoute) connection.RegisterRESTRoutes(cliCtx, r, queryRoute) channel.RegisterRESTRoutes(cliCtx, r, queryRoute) - transfer.RegisterRESTRoutes(cliCtx, r) } diff --git a/x/ibc/handler.go b/x/ibc/handler.go index d7d7262a165e..eb6705888f81 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -6,7 +6,6 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" ) // NewHandler defines the IBC handler @@ -20,7 +19,7 @@ func NewHandler(k Keeper) sdk.Handler { return client.HandleMsgCreateClient(ctx, k.ClientKeeper, msg) case client.MsgUpdateClient: - return client.HandleMsgUpdateClient(ctx, k.ClientKeeper, msg) + return &sdk.Result{}, nil // IBC connection msgs case connection.MsgConnectionOpenInit: @@ -54,13 +53,6 @@ func NewHandler(k Keeper) sdk.Handler { case channel.MsgChannelCloseConfirm: return channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, msg) - // IBC transfer msgs - case transfer.MsgTransfer: - return transfer.HandleMsgTransfer(ctx, k.TransferKeeper, msg) - - case transfer.MsgRecvPacket: - return transfer.HandleMsgRecvPacket(ctx, k.TransferKeeper, msg) - default: return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized IBC message type: %T", msg) } diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 694dae13b9ec..35104f4f3eb1 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -3,7 +3,6 @@ package keeper import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/bank" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -17,7 +16,6 @@ type Keeper struct { ConnectionKeeper connection.Keeper ChannelKeeper channel.Keeper PortKeeper port.Keeper - TransferKeeper transfer.Keeper } // NewKeeper creates a new ibc Keeper @@ -30,18 +28,10 @@ func NewKeeper( portKeeper := port.NewKeeper(cdc, key) channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper) - // TODO: move out of IBC keeper. Blocked on ADR15 - capKey := portKeeper.BindPort(bank.ModuleName) - transferKeeper := transfer.NewKeeper( - cdc, key, capKey, - clientKeeper, connectionKeeper, channelKeeper, bk, sk, - ) - return Keeper{ ClientKeeper: clientKeeper, ConnectionKeeper: connectionKeeper, ChannelKeeper: channelKeeper, PortKeeper: portKeeper, - TransferKeeper: transferKeeper, } } diff --git a/x/ibc/module.go b/x/ibc/module.go index 42da7343d6d6..0dc1093e447a 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -15,7 +15,6 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/client/rest" @@ -43,7 +42,6 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) channel.RegisterCodec(cdc) - transfer.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } @@ -120,7 +118,6 @@ func (am AppModule) NewQuerierHandler() sdk.Querier { // no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { // check if the IBC transfer module account is set - transfer.InitGenesis(ctx, am.keeper.TransferKeeper) return []abci.ValidatorUpdate{} } diff --git a/x/mock/app.go b/x/mock/app.go index 29448e8a9067..aaffad901f91 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -18,7 +18,9 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/ante" authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" + "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/cosmos/cosmos-sdk/x/params" ) @@ -78,7 +80,7 @@ func NewApp() *App { // Initialize the app. The chainers and blockers can be overwritten before // calling complete setup. app.SetInitChainer(app.InitChainer) - app.SetAnteHandler(auth.NewAnteHandler(app.AccountKeeper, supplyKeeper, auth.DefaultSigVerificationGasConsumer)) + app.SetAnteHandler(ante.NewAnteHandler(app.AccountKeeper, supplyKeeper, ibc.Keeper{}, ante.DefaultSigVerificationGasConsumer)) // Not sealing for custom extension From 15fde5b8cc8fb7650dc9896377fae0615e4234d6 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Wed, 15 Jan 2020 11:19:24 -0800 Subject: [PATCH 061/176] Fix build errors --- client/context/context.go | 47 ---------------------------------- client/flags/flags.go | 1 - client/keys/add_ledger_test.go | 4 +-- client/keys/add_test.go | 2 +- client/keys/migrate_test.go | 2 +- client/keys/root_test.go | 2 +- 6 files changed, 5 insertions(+), 53 deletions(-) diff --git a/client/context/context.go b/client/context/context.go index b51a93da3623..62b964df072c 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -158,53 +158,6 @@ func NewCLIContextWithFrom(from string) CLIContext { return NewCLIContextWithInputAndFrom(os.Stdin, from) } -// NewCLIContextIBC takes additional arguements -func NewCLIContextIBC(from string, chainID string, nodeURI string) CLIContext { - var rpc rpcclient.Client - - genOnly := viper.GetBool(flags.FlagGenerateOnly) - fromAddress, fromName, err := GetFromFields(os.Stdin, from, genOnly) - if err != nil { - fmt.Printf("failed to get from fields: %v", err) - os.Exit(1) - } - - if !genOnly { - if nodeURI != "" { - rpc = rpcclient.NewHTTP(nodeURI, "/websocket") - } - } - - ctx := CLIContext{ - Client: rpc, - ChainID: chainID, - Output: os.Stdout, - NodeURI: nodeURI, - From: from, - OutputFormat: viper.GetString(cli.OutputFlag), - Height: viper.GetInt64(flags.FlagHeight), - HomeDir: viper.GetString(flags.FlagHome), - TrustNode: viper.GetBool(flags.FlagTrustNode), - UseLedger: viper.GetBool(flags.FlagUseLedger), - BroadcastMode: viper.GetString(flags.FlagBroadcastMode), - Simulate: viper.GetBool(flags.FlagDryRun), - GenerateOnly: genOnly, - FromAddress: fromAddress, - FromName: fromName, - Indent: viper.GetBool(flags.FlagIndentResponse), - SkipConfirm: viper.GetBool(flags.FlagSkipConfirmation), - } - - // create a verifier for the specific chain ID and RPC client - verifier, err := CreateVerifier(ctx, DefaultVerifierCacheSize) - if err != nil && viper.IsSet(flags.FlagTrustNode) { - fmt.Printf("failed to create verifier: %s\n", err) - os.Exit(1) - } - - return ctx.WithVerifier(verifier) -} - // NewCLIContext returns a new initialized CLIContext with parameters from the // command line using Viper. func NewCLIContext() CLIContext { return NewCLIContextWithFrom(viper.GetString(flags.FlagFrom)) } diff --git a/client/flags/flags.go b/client/flags/flags.go index d5f5988bb941..d0ac95e45b8d 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -71,7 +71,6 @@ const ( FlagPage = "page" FlagLimit = "limit" FlagKeyringBackend = "keyring-backend" - FlagProve = "prove" ) // LineBreak can be included in a command list to provide a blank line diff --git a/client/keys/add_ledger_test.go b/client/keys/add_ledger_test.go index 2ada0e113581..a03d77795c86 100644 --- a/client/keys/add_ledger_test.go +++ b/client/keys/add_ledger_test.go @@ -33,7 +33,7 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) { config.SetBech32PrefixForValidator(bech32PrefixValAddr, bech32PrefixValPub) config.SetBech32PrefixForConsensusNode(bech32PrefixConsAddr, bech32PrefixConsPub) - cmd := AddKeyCommand() + cmd := addKeyCommand() require.NotNil(t, cmd) // Prepare a keybase @@ -80,7 +80,7 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) { func Test_runAddCmdLedger(t *testing.T) { runningUnattended := isRunningUnattended() - cmd := AddKeyCommand() + cmd := addKeyCommand() require.NotNil(t, cmd) mockIn, _, _ := tests.ApplyMockIO(cmd) diff --git a/client/keys/add_test.go b/client/keys/add_test.go index d1a7dd04b3e0..3f332a393e4a 100644 --- a/client/keys/add_test.go +++ b/client/keys/add_test.go @@ -15,7 +15,7 @@ import ( func Test_runAddCmdBasic(t *testing.T) { runningUnattended := isRunningUnattended() - cmd := AddKeyCommand() + cmd := addKeyCommand() assert.NotNil(t, cmd) mockIn, _, _ := tests.ApplyMockIO(cmd) diff --git a/client/keys/migrate_test.go b/client/keys/migrate_test.go index 0ad9226d309d..ef7b5979e666 100644 --- a/client/keys/migrate_test.go +++ b/client/keys/migrate_test.go @@ -13,7 +13,7 @@ import ( ) func Test_runMigrateCmd(t *testing.T) { - cmd := AddKeyCommand() + cmd := addKeyCommand() assert.NotNil(t, cmd) mockIn, _, _ := tests.ApplyMockIO(cmd) diff --git a/client/keys/root_test.go b/client/keys/root_test.go index 49681b17e95f..2dcf912b98d8 100644 --- a/client/keys/root_test.go +++ b/client/keys/root_test.go @@ -15,7 +15,7 @@ func TestCommands(t *testing.T) { assert.NotNil(t, rootCommands) // Commands are registered - assert.Equal(t, 11, len(rootCommands.Commands())) + assert.Equal(t, 12, len(rootCommands.Commands())) } func TestMain(m *testing.M) { From 939b2a52244296d5932ada4a8189788befff9f1a Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Fri, 17 Jan 2020 10:23:39 -0800 Subject: [PATCH 062/176] remove tmcmn instance --- x/ibc/02-client/types/tendermint/evidence.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/ibc/02-client/types/tendermint/evidence.go b/x/ibc/02-client/types/tendermint/evidence.go index bc60b413b4e6..2ebdcb81aa3b 100644 --- a/x/ibc/02-client/types/tendermint/evidence.go +++ b/x/ibc/02-client/types/tendermint/evidence.go @@ -4,7 +4,7 @@ import ( yaml "gopkg.in/yaml.v2" "github.com/tendermint/tendermint/crypto/tmhash" - cmn "github.com/tendermint/tendermint/libs/common" + tmbytes "github.com/tendermint/tendermint/libs/bytes" tmtypes "github.com/tendermint/tendermint/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -42,7 +42,7 @@ func (ev Evidence) String() string { } // Hash implements Evidence interface -func (ev Evidence) Hash() cmn.HexBytes { +func (ev Evidence) Hash() tmbytes.HexBytes { return tmhash.Sum(SubModuleCdc.MustMarshalBinaryBare(ev)) } From 559db33ea99f9d7fa7af3b976591a53531ad3233 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Fri, 17 Jan 2020 10:25:40 -0800 Subject: [PATCH 063/176] remove tmcmn instance --- x/ibc/02-client/types/msgs_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go index 844276b3ae6b..1c4f56e76e26 100644 --- a/x/ibc/02-client/types/msgs_test.go +++ b/x/ibc/02-client/types/msgs_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/secp256k1" - cmn "github.com/tendermint/tendermint/libs/common" + tmbytes "github.com/tendermint/tendermint/libs/bytes" sdk "github.com/cosmos/cosmos-sdk/types" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" @@ -27,7 +27,7 @@ type mockEvidence struct{} func (me mockEvidence) Route() string { return mockStr } func (me mockEvidence) Type() string { return mockStr } func (me mockEvidence) String() string { return mockStr } -func (me mockEvidence) Hash() cmn.HexBytes { return cmn.HexBytes([]byte(mockStr)) } +func (me mockEvidence) Hash() tmbytes.HexBytes { return tmbytes.HexBytes([]byte(mockStr)) } func (me mockEvidence) ValidateBasic() error { return nil } func (me mockEvidence) GetHeight() int64 { return 3 } From 92f306971c77b03a8ec15cbc55bdf06a7bdd311e Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Fri, 17 Jan 2020 10:47:50 -0800 Subject: [PATCH 064/176] Fix compliation errors --- client/context/context.go | 5 ++++- client/context/query.go | 2 +- client/flags/flags.go | 2 -- x/ibc/02-client/client/utils/utils.go | 6 +++--- x/ibc/02-client/types/tendermint/evidence_test.go | 2 +- x/ibc/02-client/types/tendermint/test_utils.go | 2 -- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/client/context/context.go b/client/context/context.go index 82ae2b14a9f7..a5445f3c0b3c 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -118,7 +118,10 @@ func NewCLIContextIBC(input io.Reader, from string, chainID string, nodeURI stri if !genOnly { if nodeURI != "" { - rpc = rpcclient.NewHTTP(nodeURI, "/websocket") + rpc, err = rpcclient.NewHTTP(nodeURI, "/websocket") + if err != nil { + panic(err) + } } } diff --git a/client/context/query.go b/client/context/query.go index 1b8279a55cd5..a10862af8733 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -178,7 +178,7 @@ func (ctx CLIContext) queryABCI(req abci.RequestQuery) (abci.ResponseQuery, erro // or an error if the query fails. In addition, it will verify the returned // proof if TrustNode is disabled. If proof verification fails or the query // height is invalid, an error will be returned. -func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, height int64, err error) { +func (ctx CLIContext) query(path string, key tmbytes.HexBytes) (res []byte, height int64, err error) { resp, err := ctx.queryABCI(abci.RequestQuery{ Path: path, Data: key, diff --git a/client/flags/flags.go b/client/flags/flags.go index 52eef33b8a32..52c4cbe7ea90 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -68,8 +68,6 @@ const ( FlagOutputDocument = "output-document" // inspired by wget -O FlagSkipConfirmation = "yes" FlagProve = "prove" - FlagPage = "page" - FlagLimit = "limit" FlagKeyringBackend = "keyring-backend" FlagPage = "page" FlagLimit = "limit" diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 02f1163b3d32..e77c3766befd 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -158,12 +158,12 @@ func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, return tendermint.Header{}, 0, err } - validators, err := node.Validators(&prevheight) + validators, err := node.Validators(&prevheight, 0, 10000) if err != nil { return tendermint.Header{}, 0, err } - nextvalidators, err := node.Validators(&height) + nextvalidators, err := node.Validators(&height, 0, 10000) if err != nil { return tendermint.Header{}, 0, err } @@ -198,7 +198,7 @@ func QueryNodeConsensusState(cliCtx context.CLIContext) (tendermint.ConsensusSta return tendermint.ConsensusState{}, 0, err } - validators, err := node.Validators(&prevHeight) + validators, err := node.Validators(&prevHeight, 0, 10000) if err != nil { return tendermint.ConsensusState{}, 0, err } diff --git a/x/ibc/02-client/types/tendermint/evidence_test.go b/x/ibc/02-client/types/tendermint/evidence_test.go index 09f40499b458..bf5e073e3e19 100644 --- a/x/ibc/02-client/types/tendermint/evidence_test.go +++ b/x/ibc/02-client/types/tendermint/evidence_test.go @@ -94,7 +94,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { // voteSet contains only altVal which is less than 2/3 of total power (4/14) wrongVoteSet := tmtypes.NewVoteSet("gaia", ev.Header2.Height, 1, tmtypes.PrecommitType, altValSet) var err error - ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round(), wrongVoteSet, altSigners) + ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round, wrongVoteSet, altSigners) if err != nil { panic(err) } diff --git a/x/ibc/02-client/types/tendermint/test_utils.go b/x/ibc/02-client/types/tendermint/test_utils.go index bc2b998c2e71..94d92e418299 100644 --- a/x/ibc/02-client/types/tendermint/test_utils.go +++ b/x/ibc/02-client/types/tendermint/test_utils.go @@ -30,8 +30,6 @@ func MakeHeader(chainID string, height int64, valSet *tmtypes.ValidatorSet, next ChainID: chainID, Height: height, Time: timestamp, - NumTxs: 100, - TotalTxs: 1000, LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt64, make([]byte, tmhash.Size)), LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), DataHash: tmhash.Sum([]byte("data_hash")), From 2c22e52381695c379d650cc6012bb6f8a2e84343 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Wed, 22 Jan 2020 11:47:08 -0800 Subject: [PATCH 065/176] Fix build errors --- client/flags/flags.go | 2 -- client/keys/add.go | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/client/flags/flags.go b/client/flags/flags.go index 06292e8a71a9..6107ef7e718a 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -9,8 +9,6 @@ import ( "github.com/spf13/viper" tmcli "github.com/tendermint/tendermint/libs/cli" - - "github.com/cosmos/cosmos-sdk/crypto/keys" ) // nolint diff --git a/client/keys/add.go b/client/keys/add.go index 7d6cec3da0c0..b1c412c18c72 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -49,7 +49,7 @@ NOTE: This is insecure and only meant to be used during testing!!!! HERE BE DRAG `, Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - kb, err := NewKeyBaseFromHomeFlag() + kb, err := NewKeyBaseFromDir(viper.GetString(flags.FlagHome)) if err != nil { return err } From ee258f02528cd6a2621d5499e190a2ba789ed631 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Wed, 22 Jan 2020 11:48:44 -0800 Subject: [PATCH 066/176] Fix build errors --- go.sum | 6 ------ 1 file changed, 6 deletions(-) diff --git a/go.sum b/go.sum index 796402b6b6c7..15260c8d0c1e 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,6 @@ github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f h1:8N8XWLZelZNibkhM github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= -github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= 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 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -163,8 +161,6 @@ github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDe github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/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-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= @@ -323,8 +319,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= From 3df016eff9700736eae2923f63c7111ec0a30475 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 27 Jan 2020 18:00:42 +0100 Subject: [PATCH 067/176] ICS07 Tendermint Client implementation (#5485) * implement ICS07 * build * update tests and cleanup * x/ibc/02-client/types: remove misbehaviour in favor of evidence * remove root query, update queriers, implement verification funcs * remove committer; cleanup * move keys to ibc/types * fix paths * update ICS03 connection verification * move order and states to exported pkg * update ICS04 to latest spec * fix build * move ics02 types/errors package to /types * update a few tests * update tests; fix codec registration * minor changes from code review * ibc/client/types: fix tests * ibc/02-client/keeper: fix tests * ibc/03-connection/keeper: begin tests for verify.go * ibc/23-commitment: add IsEmpty() to Prefix, Path and Proof * address comments from review * add tests for evidence * x/ibc/07-tendermint: add tests for consensus state, header and update * ibc/07-tendermint: fix verification panic and add tests * ibc/07-tendermint: add failure test cases * x/ibc/03-connection/keeper: add verification tests for failing cases * remove unused queriers * Update ICS 7 tests (#5556) * Update ICS 7 tests * Fix one problem * Also set consensus state for height 1 * Apply same fixes to ICS 4 tests * Remove unnecessary change * Fix ante tests; remove printfs * Remove printf * Update x/ibc/ante/ante_test.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add TODOs for ADR 03 dynamic store * add tests for msgs and packet (#5559) * Add skeleton for ValidateBasic tests * Move tests; basic one passes * Add more ValidateBasic tests * Add more ValidateBasic testcases * Fix minor typo * Add `ValidateBasic` tests for Packet * Move to packet_test.go * use app.Commit for tests * update verify.go * Fix all ICS 07 Tests (#5565) * ICS 07 Debugging * WIP Debugging * Foo bar baz, baz bar foo, :man_shrugging: * cleanup print statements * cleanup verification test * add return err for proof verification * cleanup; start handshake testing * connection handshake tests * scopelint * WIP Test refactor * fix ICS03 tests * fix ICS04 tests * nolint Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * cleanup comments and add a few tests * typo Co-authored-by: Christopher Goes Co-authored-by: Jack Zampolin --- simapp/app.go | 1 - simapp/test_helpers.go | 3 +- store/iavl/store.go | 2 +- x/ibc/02-client/alias.go | 73 +- x/ibc/02-client/client/cli/cli.go | 2 +- x/ibc/02-client/client/cli/query.go | 90 +-- x/ibc/02-client/client/cli/tx.go | 21 +- x/ibc/02-client/client/rest/query.go | 99 +-- x/ibc/02-client/client/rest/swagger.go | 16 +- x/ibc/02-client/client/rest/tx.go | 14 +- x/ibc/02-client/client/utils/utils.go | 84 +-- x/ibc/02-client/exported/exported.go | 99 ++- x/ibc/02-client/handler.go | 15 +- x/ibc/02-client/keeper/client.go | 91 +-- x/ibc/02-client/keeper/client_test.go | 278 +++---- x/ibc/02-client/keeper/keeper.go | 162 +---- x/ibc/02-client/keeper/keeper_test.go | 107 +-- x/ibc/02-client/keeper/querier.go | 88 +-- x/ibc/02-client/types/codec.go | 9 +- x/ibc/02-client/types/errors.go | 26 + x/ibc/02-client/types/errors/errors.go | 24 - x/ibc/02-client/types/events.go | 3 +- x/ibc/02-client/types/keys.go | 109 --- x/ibc/02-client/types/msgs.go | 61 +- x/ibc/02-client/types/msgs_test.go | 117 +-- x/ibc/02-client/types/querier.go | 114 +-- x/ibc/02-client/types/state.go | 19 - x/ibc/02-client/types/tendermint/committer.go | 26 - .../types/tendermint/consensus_state.go | 111 --- .../types/tendermint/consensus_state_test.go | 53 -- .../types/tendermint/evidence_test.go | 135 ---- x/ibc/02-client/types/tendermint/header.go | 54 -- .../types/tendermint/misbehaviour.go | 71 -- .../types/tendermint/misbehaviour_test.go | 170 ----- .../types/tendermint/tendermint_test.go | 46 -- x/ibc/03-connection/alias.go | 18 - x/ibc/03-connection/client/cli/tx.go | 6 +- x/ibc/03-connection/client/rest/rest.go | 7 +- x/ibc/03-connection/client/rest/tx.go | 2 +- x/ibc/03-connection/client/utils/utils.go | 5 +- x/ibc/03-connection/exported/exported.go | 89 +++ x/ibc/03-connection/exported/exported_test.go | 46 ++ x/ibc/03-connection/handler.go | 40 +- x/ibc/03-connection/keeper/handshake.go | 181 ++--- x/ibc/03-connection/keeper/handshake_test.go | 510 ++++++------- x/ibc/03-connection/keeper/keeper.go | 51 +- x/ibc/03-connection/keeper/keeper_test.go | 234 ++++-- x/ibc/03-connection/keeper/querier.go | 21 - x/ibc/03-connection/keeper/verify.go | 167 +++++ x/ibc/03-connection/keeper/verify_test.go | 354 +++++++++ x/ibc/03-connection/types/codec.go | 7 +- x/ibc/03-connection/types/connection.go | 132 ++-- x/ibc/03-connection/types/connection_test.go | 87 ++- x/ibc/03-connection/types/errors.go | 1 + x/ibc/03-connection/types/expected_keepers.go | 14 +- x/ibc/03-connection/types/keys.go | 47 -- x/ibc/03-connection/types/msgs.go | 24 +- x/ibc/03-connection/types/msgs_test.go | 18 +- x/ibc/03-connection/types/querier.go | 19 +- x/ibc/04-channel/alias.go | 34 - x/ibc/04-channel/client/cli/tx.go | 7 +- x/ibc/04-channel/client/rest/rest.go | 19 +- x/ibc/04-channel/client/utils/utils.go | 5 +- x/ibc/04-channel/exported/exported.go | 157 ++++ x/ibc/04-channel/exported/exported_test.go | 91 +++ x/ibc/04-channel/keeper/handshake.go | 241 +++--- x/ibc/04-channel/keeper/handshake_test.go | 686 ++++++++++-------- x/ibc/04-channel/keeper/keeper.go | 28 +- x/ibc/04-channel/keeper/keeper_test.go | 171 ++++- x/ibc/04-channel/keeper/packet.go | 310 ++++---- x/ibc/04-channel/keeper/querier.go | 21 - x/ibc/04-channel/keeper/timeout.go | 195 ++--- x/ibc/04-channel/types/channel.go | 189 ++--- x/ibc/04-channel/types/channel_test.go | 89 +-- x/ibc/04-channel/types/codec.go | 2 + x/ibc/04-channel/types/errors.go | 1 + x/ibc/04-channel/types/expected_keepers.go | 68 +- x/ibc/04-channel/types/keys.go | 119 --- x/ibc/04-channel/types/msgs.go | 8 +- x/ibc/04-channel/types/msgs_test.go | 138 +++- x/ibc/04-channel/types/packet_test.go | 32 + x/ibc/04-channel/types/querier.go | 22 +- x/ibc/07-tendermint/client_state.go | 290 ++++++++ x/ibc/07-tendermint/client_state_test.go | 560 ++++++++++++++ .../tendermint => 07-tendermint}/codec.go | 14 +- x/ibc/07-tendermint/consensus_state.go | 35 + x/ibc/07-tendermint/consensus_state_test.go | 57 ++ .../types/tendermint => 07-tendermint}/doc.go | 0 .../tendermint => 07-tendermint}/evidence.go | 55 +- x/ibc/07-tendermint/evidence_test.go | 196 +++++ x/ibc/07-tendermint/header.go | 72 ++ x/ibc/07-tendermint/header_test.go | 30 + x/ibc/07-tendermint/misbehaviour.go | 90 +++ x/ibc/07-tendermint/misbehaviour_test.go | 140 ++++ x/ibc/07-tendermint/tendermint_test.go | 43 ++ .../test_utils.go | 15 +- x/ibc/07-tendermint/update.go | 72 ++ x/ibc/07-tendermint/update_test.go | 55 ++ x/ibc/20-transfer/client/utils/utils.go | 3 +- x/ibc/20-transfer/handler_test.go | 39 +- x/ibc/20-transfer/keeper/keeper.go | 2 + x/ibc/20-transfer/keeper/keeper_test.go | 8 +- x/ibc/20-transfer/keeper/relay.go | 2 +- x/ibc/20-transfer/keeper/relay_test.go | 26 +- x/ibc/20-transfer/types/codec.go | 6 +- x/ibc/20-transfer/types/expected_keepers.go | 2 +- x/ibc/23-commitment/merkle.go | 43 +- x/ibc/23-commitment/merkle_test.go | 19 +- x/ibc/23-commitment/types.go | 8 +- x/ibc/23-commitment/verify.go | 20 +- x/ibc/ante/ante_test.go | 49 +- x/ibc/keeper/querier.go | 10 - x/ibc/keeper/querier_test.go | 12 - x/ibc/module.go | 2 + x/ibc/types/keys.go | 169 ++++- 115 files changed, 5333 insertions(+), 3917 deletions(-) create mode 100644 x/ibc/02-client/types/errors.go delete mode 100644 x/ibc/02-client/types/errors/errors.go delete mode 100644 x/ibc/02-client/types/state.go delete mode 100644 x/ibc/02-client/types/tendermint/committer.go delete mode 100644 x/ibc/02-client/types/tendermint/consensus_state.go delete mode 100644 x/ibc/02-client/types/tendermint/consensus_state_test.go delete mode 100644 x/ibc/02-client/types/tendermint/evidence_test.go delete mode 100644 x/ibc/02-client/types/tendermint/header.go delete mode 100644 x/ibc/02-client/types/tendermint/misbehaviour.go delete mode 100644 x/ibc/02-client/types/tendermint/misbehaviour_test.go delete mode 100644 x/ibc/02-client/types/tendermint/tendermint_test.go create mode 100644 x/ibc/03-connection/exported/exported.go create mode 100644 x/ibc/03-connection/exported/exported_test.go create mode 100644 x/ibc/03-connection/keeper/verify.go create mode 100644 x/ibc/03-connection/keeper/verify_test.go create mode 100644 x/ibc/04-channel/exported/exported_test.go create mode 100644 x/ibc/04-channel/types/packet_test.go create mode 100644 x/ibc/07-tendermint/client_state.go create mode 100644 x/ibc/07-tendermint/client_state_test.go rename x/ibc/{02-client/types/tendermint => 07-tendermint}/codec.go (55%) create mode 100644 x/ibc/07-tendermint/consensus_state.go create mode 100644 x/ibc/07-tendermint/consensus_state_test.go rename x/ibc/{02-client/types/tendermint => 07-tendermint}/doc.go (100%) rename x/ibc/{02-client/types/tendermint => 07-tendermint}/evidence.go (59%) create mode 100644 x/ibc/07-tendermint/evidence_test.go create mode 100644 x/ibc/07-tendermint/header.go create mode 100644 x/ibc/07-tendermint/header_test.go create mode 100644 x/ibc/07-tendermint/misbehaviour.go create mode 100644 x/ibc/07-tendermint/misbehaviour_test.go create mode 100644 x/ibc/07-tendermint/tendermint_test.go rename x/ibc/{02-client/types/tendermint => 07-tendermint}/test_utils.go (77%) create mode 100644 x/ibc/07-tendermint/update.go create mode 100644 x/ibc/07-tendermint/update_test.go diff --git a/simapp/app.go b/simapp/app.go index 294691891e4a..cb12d7430d46 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -255,7 +255,6 @@ func NewSimApp( slashing.NewAppModule(app.SlashingKeeper, app.AccountKeeper, app.StakingKeeper), distr.NewAppModule(app.DistrKeeper, app.AccountKeeper, app.SupplyKeeper, app.StakingKeeper), staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper), - ibc.NewAppModule(app.IBCKeeper), upgrade.NewAppModule(app.UpgradeKeeper), evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 5192e59feab0..99a351e49afd 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -14,6 +14,7 @@ import ( bam "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp/helpers" + stypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" @@ -23,7 +24,7 @@ import ( // Setup initializes a new SimApp. A Nop logger is set in SimApp. func Setup(isCheckTx bool) *SimApp { db := dbm.NewMemDB() - app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0) + app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0, bam.SetPruning(stypes.PruneNothing)) if !isCheckTx { // init chain must be called to stop deliverState from being nil genesisState := NewDefaultGenesisState() diff --git a/store/iavl/store.go b/store/iavl/store.go index 4a346a65d7b9..29abd10c401d 100644 --- a/store/iavl/store.go +++ b/store/iavl/store.go @@ -249,8 +249,8 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { switch req.Path { case "/key": // get by key key := req.Data // data holds the key bytes - res.Key = key + if !st.VersionExists(res.Height) { res.Log = iavl.ErrVersionDoesNotExist.Error() break diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go index d818bbb99572..20b946cf4a4f 100644 --- a/x/ibc/02-client/alias.go +++ b/x/ibc/02-client/alias.go @@ -9,53 +9,36 @@ package client import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" ) const ( - AttributeKeyClientID = types.AttributeKeyClientID - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - QueryAllClients = types.QueryAllClients - QueryClientState = types.QueryClientState - QueryConsensusState = types.QueryConsensusState - QueryVerifiedRoot = types.QueryVerifiedRoot + AttributeKeyClientID = types.AttributeKeyClientID + AttrbuteKeyClientType = types.AttributeKeyClientType + SubModuleName = types.SubModuleName + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryAllClients = types.QueryAllClients + QueryClientState = types.QueryClientState + QueryConsensusState = types.QueryConsensusState ) var ( // functions aliases - NewKeeper = keeper.NewKeeper - QuerierClients = keeper.QuerierClients - QuerierClientState = keeper.QuerierClientState - QuerierConsensusState = keeper.QuerierConsensusState - QuerierVerifiedRoot = keeper.QuerierVerifiedRoot - RegisterCodec = types.RegisterCodec - ErrClientExists = errors.ErrClientExists - ErrClientNotFound = errors.ErrClientNotFound - ErrClientFrozen = errors.ErrClientFrozen - ErrConsensusStateNotFound = errors.ErrConsensusStateNotFound - ErrInvalidConsensus = errors.ErrInvalidConsensus - ErrClientTypeNotFound = errors.ErrClientTypeNotFound - ErrInvalidClientType = errors.ErrInvalidClientType - ErrRootNotFound = errors.ErrRootNotFound - ErrInvalidHeader = errors.ErrInvalidHeader - ErrInvalidEvidence = errors.ErrInvalidEvidence - ClientStatePath = types.ClientStatePath - ClientTypePath = types.ClientTypePath - ConsensusStatePath = types.ConsensusStatePath - RootPath = types.RootPath - KeyClientState = types.KeyClientState - KeyClientType = types.KeyClientType - KeyConsensusState = types.KeyConsensusState - KeyRoot = types.KeyRoot - NewMsgCreateClient = types.NewMsgCreateClient - NewMsgUpdateClient = types.NewMsgUpdateClient - NewMsgSubmitMibehaviour = types.NewMsgSubmitMisbehaviour - NewQueryClientStateParams = types.NewQueryClientStateParams - NewQueryCommitmentRootParams = types.NewQueryCommitmentRootParams - NewClientState = types.NewClientState + NewKeeper = keeper.NewKeeper + QuerierClients = keeper.QuerierClients + RegisterCodec = types.RegisterCodec + ErrClientExists = types.ErrClientExists + ErrClientNotFound = types.ErrClientNotFound + ErrClientFrozen = types.ErrClientFrozen + ErrConsensusStateNotFound = types.ErrConsensusStateNotFound + ErrInvalidConsensus = types.ErrInvalidConsensus + ErrClientTypeNotFound = types.ErrClientTypeNotFound + ErrInvalidClientType = types.ErrInvalidClientType + ErrRootNotFound = types.ErrRootNotFound + ErrInvalidHeader = types.ErrInvalidHeader + ErrInvalidEvidence = types.ErrInvalidEvidence + NewMsgCreateClient = types.NewMsgCreateClient + NewMsgUpdateClient = types.NewMsgUpdateClient // variable aliases SubModuleCdc = types.SubModuleCdc @@ -65,11 +48,7 @@ var ( ) type ( - Keeper = keeper.Keeper - MsgCreateClient = types.MsgCreateClient - MsgUpdateClient = types.MsgUpdateClient - MsgSubmitMisbehaviour = types.MsgSubmitMisbehaviour - QueryClientStateParams = types.QueryClientStateParams - QueryCommitmentRootParams = types.QueryCommitmentRootParams - State = types.State + Keeper = keeper.Keeper + MsgCreateClient = types.MsgCreateClient + MsgUpdateClient = types.MsgUpdateClient ) diff --git a/x/ibc/02-client/client/cli/cli.go b/x/ibc/02-client/client/cli/cli.go index 4a36894faf35..757b8894f719 100644 --- a/x/ibc/02-client/client/cli/cli.go +++ b/x/ibc/02-client/client/cli/cli.go @@ -20,7 +20,6 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { GetCmdQueryClientStates(queryRoute, cdc), GetCmdQueryClientState(queryRoute, cdc), GetCmdQueryConsensusState(queryRoute, cdc), - GetCmdQueryRoot(queryRoute, cdc), GetCmdQueryHeader(cdc), GetCmdNodeConsensusState(queryRoute, cdc), GetCmdQueryPath(queryRoute, cdc), @@ -40,6 +39,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ics02ClientTxCmd.AddCommand(flags.PostCommands( GetCmdCreateClient(cdc), GetCmdUpdateClient(cdc), + GetCmdSubmitMisbehaviour(cdc), )...) return ics02ClientTxCmd diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index 682758783292..34c5e58093de 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -88,85 +88,11 @@ $ %s query ibc client state [client-id] // the chain as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#query func GetCmdQueryConsensusState(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "consensus-state [client-id]", - Short: "Query the latest consensus state of the client", - Long: "Query the consensus state for a particular light client", - Example: fmt.Sprintf("%s query ibc client consensus-state [client-id]", version.ClientName), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - cliCtx := context.NewCLIContext().WithCodec(cdc) - clientID := args[0] - if strings.TrimSpace(clientID) == "" { - return errors.New("client ID can't be blank") - } - - prove := viper.GetBool(flags.FlagProve) - - csRes, err := utils.QueryConsensusState(cliCtx, clientID, prove) - if err != nil { - return err - } - - return cliCtx.PrintOutput(csRes) - }, - } - cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") - return cmd -} - -// GetCmdQueryRoot defines the command to query a verified commitment root -func GetCmdQueryRoot(queryRoute string, cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "root [client-id] [height]", - Short: "Query a verified commitment root", - Long: strings.TrimSpace( - fmt.Sprintf(`Query an already verified commitment root at a specific height for a particular client - -Example: -$ %s query ibc client root [client-id] [height] -`, version.ClientName), - ), - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - cliCtx := context.NewCLIContext().WithCodec(cdc) - clientID := args[0] - if strings.TrimSpace(clientID) == "" { - return errors.New("client ID can't be blank") - } - - height, err := strconv.ParseUint(args[1], 10, 64) - if err != nil { - return fmt.Errorf("expected integer height, got: %v", args[1]) - } - - prove := viper.GetBool(flags.FlagProve) - - rootRes, err := utils.QueryCommitmentRoot(cliCtx, clientID, height, prove) - if err != nil { - return err - } - - return cliCtx.PrintOutput(rootRes) - }, - } - cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") - return cmd -} - -// GetCmdQueryCommitter defines the command to query the committer of the chain -// at a given height -func GetCmdQueryCommitter(queryRoute string, cdc *codec.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "committer [client-id] [height]", - Short: "Query a committer", - Long: strings.TrimSpace( - fmt.Sprintf(`Query a committer at a specific height for a particular client - -Example: -$ %s query ibc client committer [client-id] [height] -`, version.ClientName), - ), - Args: cobra.ExactArgs(2), + Use: "consensus-state [client-id] [height]", + Short: "Query the consensus state of a client at a given height", + Long: "Query the consensus state for a particular light client at a given height", + Example: fmt.Sprintf("%s query ibc client consensus-state [client-id] [height]", version.ClientName), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) clientID := args[0] @@ -176,17 +102,17 @@ $ %s query ibc client committer [client-id] [height] height, err := strconv.ParseUint(args[1], 10, 64) if err != nil { - return fmt.Errorf("expected integer height, got: %v", args[1]) + return fmt.Errorf("expected integer height, got: %s", args[1]) } prove := viper.GetBool(flags.FlagProve) - committerRes, err := utils.QueryCommitter(cliCtx, clientID, height, prove) + csRes, err := utils.QueryConsensusState(cliCtx, clientID, height, prove) if err != nil { return err } - return cliCtx.PrintOutput(committerRes) + return cliCtx.PrintOutput(csRes) }, } cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 6081ddcdddfe..5dd8cd1b9c30 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -4,7 +4,6 @@ import ( "bufio" "fmt" "io/ioutil" - "os" "strings" "github.com/pkg/errors" @@ -18,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/evidence" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" @@ -118,36 +118,33 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home // https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#misbehaviour func GetCmdSubmitMisbehaviour(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "misbehaviour [client-it] [path/to/evidence.json]", + Use: "misbehaviour [path/to/evidence.json]", Short: "submit a client misbehaviour", Long: strings.TrimSpace(fmt.Sprintf(`submit a client misbehaviour to invalidate to invalidate previous state roots and prevent future updates: Example: -$ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 --home ../node0/cli --chain-id $CID +$ %s tx ibc client misbehaviour [path/to/evidence.json] --from node0 --home ../node0/cli --chain-id $CID `, version.ClientName), ), - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) - clientID := args[0] - - var evidence evidenceexported.Evidence - if err := cdc.UnmarshalJSON([]byte(args[1]), &evidence); err != nil { - fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...") + var ev evidenceexported.Evidence + if err := cdc.UnmarshalJSON([]byte(args[0]), &ev); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(args[1]) + contents, err := ioutil.ReadFile(args[0]) if err != nil { return errors.New("neither JSON input nor path to .json file were provided") } - if err := cdc.UnmarshalJSON(contents, &evidence); err != nil { + if err := cdc.UnmarshalJSON(contents, &ev); err != nil { return errors.Wrap(err, "error unmarshalling evidence file") } } - msg := types.NewMsgSubmitMisbehaviour(clientID, evidence, cliCtx.GetFromAddress()) + msg := evidence.NewMsgSubmitEvidence(ev, cliCtx.GetFromAddress()) if err := msg.ValidateBasic(); err != nil { return err } diff --git a/x/ibc/02-client/client/rest/query.go b/x/ibc/02-client/client/rest/query.go index 3b59aeb49f85..be09c1bc0757 100644 --- a/x/ibc/02-client/client/rest/query.go +++ b/x/ibc/02-client/client/rest/query.go @@ -10,18 +10,14 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { r.HandleFunc("/ibc/clients", queryAllClientStatesFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/client-state", RestClientID), queryClientStateHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/consensus-state", RestClientID), queryConsensusStateHandlerFn(cliCtx)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/roots/{%s}", RestClientID, RestRootHeight), queryRootHandlerFn(cliCtx)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/committers/{%s}", RestClientID, RestRootHeight), queryCommitterHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/header", queryHeaderHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/ibc/node-state", queryNodeConsensusStateHandlerFn(cliCtx)).Methods("GET") - r.HandleFunc("/ibc/path", queryPathHandlerFn(cliCtx)).Methods("GET") } // queryAllClientStatesFn queries all available light clients @@ -97,84 +93,13 @@ func queryClientStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { // @Tags IBC // @Produce json // @Param client-id path string true "Client ID" +// @Param height path number true "Height" // @Param prove query boolean false "Proof of result" // @Success 200 {object} QueryConsensusState "OK" // @Failure 400 {object} rest.ErrorResponse "Invalid client id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/clients/{client-id}/consensus-state [get] func queryConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - clientID := vars[RestClientID] - prove := rest.ParseQueryProve(r) - - cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) - if !ok { - return - } - - csRes, err := utils.QueryConsensusState(cliCtx, clientID, prove) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - cliCtx = cliCtx.WithHeight(int64(csRes.ProofHeight)) - rest.PostProcessResponse(w, cliCtx, csRes) - } -} - -// queryRootHandlerFn implements a root querying route -// -// @Summary Query client root -// @Tags IBC -// @Produce json -// @Param client-id path string true "Client ID" -// @Param height path number true "Root height" -// @Success 200 {object} QueryRoot "OK" -// @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" -// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/clients/{client-id}/roots/{height} [get] -func queryRootHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - clientID := vars[RestClientID] - height, err := strconv.ParseUint(vars[RestRootHeight], 10, 64) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - prove := rest.ParseQueryProve(r) - - cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) - if !ok { - return - } - - rootRes, err := utils.QueryCommitmentRoot(cliCtx, clientID, height, prove) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - cliCtx = cliCtx.WithHeight(int64(rootRes.ProofHeight)) - rest.PostProcessResponse(w, cliCtx, rootRes) - } -} - -// queryCommitterHandlerFn implements a committer querying route -// -// @Summary Query committer -// @Tags IBC -// @Produce json -// @Param client-id path string true "Client ID" -// @Param height path number true "Committer height" -// @Success 200 {object} QueryCommitter "OK" -// @Failure 400 {object} rest.ErrorResponse "Invalid client id or height" -// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/clients/{client-id}/committers/{height} [get] -func queryCommitterHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) clientID := vars[RestClientID] @@ -191,14 +116,14 @@ func queryCommitterHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - committerRes, err := utils.QueryCommitter(cliCtx, clientID, height, prove) + csRes, err := utils.QueryConsensusState(cliCtx, clientID, height, prove) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - cliCtx = cliCtx.WithHeight(int64(committerRes.ProofHeight)) - rest.PostProcessResponse(w, cliCtx, committerRes) + cliCtx = cliCtx.WithHeight(int64(csRes.ProofHeight)) + rest.PostProcessResponse(w, cliCtx, csRes) } } @@ -244,19 +169,3 @@ func queryNodeConsensusStateHandlerFn(cliCtx context.CLIContext) http.HandlerFun rest.PostProcessResponse(w, cliCtx, res) } } - -// queryPathHandlerFn implements a node consensus path querying route -// -// @Summary Query IBC path -// @Tags IBC -// @Produce json -// @Success 200 {object} QueryPath "OK" -// @Failure 500 {object} rest.ErrorResponse "Internal Server Error" -// @Router /ibc/path [get] -func queryPathHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - path := commitment.NewPrefix([]byte("ibc")) - res := cliCtx.Codec.MustMarshalJSON(path) - rest.PostProcessResponse(w, cliCtx, res) - } -} diff --git a/x/ibc/02-client/client/rest/swagger.go b/x/ibc/02-client/client/rest/swagger.go index 2ff01ff34fb8..42809a112192 100644 --- a/x/ibc/02-client/client/rest/swagger.go +++ b/x/ibc/02-client/client/rest/swagger.go @@ -2,8 +2,9 @@ package rest import ( auth "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/evidence" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -24,11 +25,6 @@ type ( Result types.StateResponse `json:"result"` } - QueryRoot struct { - Height int64 `json:"height"` - Result types.RootResponse `json:"result"` - } - QueryNodeConsensusState struct { Height int64 `json:"height"` Result tendermint.ConsensusState `json:"result"` @@ -54,9 +50,9 @@ type ( } PostSubmitMisbehaviour struct { - Msgs []types.MsgSubmitMisbehaviour `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` + Msgs []evidence.MsgSubmitEvidence `json:"msg" yaml:"msg"` + Fee auth.StdFee `json:"fee" yaml:"fee"` + Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` } ) diff --git a/x/ibc/02-client/client/rest/tx.go b/x/ibc/02-client/client/rest/tx.go index 50f9a38b022f..a0cb4840879d 100644 --- a/x/ibc/02-client/client/rest/tx.go +++ b/x/ibc/02-client/client/rest/tx.go @@ -10,6 +10,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + "github.com/cosmos/cosmos-sdk/x/evidence" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ) @@ -17,7 +18,7 @@ import ( func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { r.HandleFunc("/ibc/clients", createClientHandlerFn(cliCtx)).Methods("POST") r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/update", RestClientID), updateClientHandlerFn(cliCtx)).Methods("POST") - r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/misbehaviour", RestClientID), submitMisbehaviourHandlerFn(cliCtx)).Methods("POST") + r.HandleFunc("/ibc/clients/{%s}/misbehaviour", submitMisbehaviourHandlerFn(cliCtx)).Methods("POST") } // createClientHandlerFn implements a create client handler @@ -120,7 +121,6 @@ func updateClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { // @Tags IBC // @Accept json // @Produce json -// @Param client-id path string true "Client ID" // @Param body body rest.SubmitMisbehaviourReq true "Submit misbehaviour request body" // @Success 200 {object} PostSubmitMisbehaviour "OK" // @Failure 400 {object} rest.ErrorResponse "Invalid client id" @@ -128,9 +128,6 @@ func updateClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { // @Router /ibc/clients/{client-id}/misbehaviour [post] func submitMisbehaviourHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - clientID := vars[RestClientID] - var req SubmitMisbehaviourReq if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { return @@ -148,12 +145,7 @@ func submitMisbehaviourHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } // create the message - msg := types.NewMsgSubmitMisbehaviour( - clientID, - req.Evidence, - fromAddr, - ) - + msg := evidence.NewMsgSubmitEvidence(req.Evidence, fromAddr) if err := msg.ValidateBasic(); err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index e77c3766befd..fbe53fcc1063 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -7,14 +7,16 @@ import ( tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // QueryAllClientStates returns all the light client states. It _does not_ return // any merkle proof. -func QueryAllClientStates(cliCtx context.CLIContext, page, limit int) ([]types.State, int64, error) { +func QueryAllClientStates(cliCtx context.CLIContext, page, limit int) ([]exported.ClientState, int64, error) { params := types.NewQueryAllClientsParams(page, limit) bz, err := cliCtx.Codec.MarshalJSON(params) if err != nil { @@ -27,7 +29,7 @@ func QueryAllClientStates(cliCtx context.CLIContext, page, limit int) ([]types.S return nil, 0, err } - var clients []types.State + var clients []exported.ClientState err = cliCtx.Codec.UnmarshalJSON(res, &clients) if err != nil { return nil, 0, fmt.Errorf("failed to unmarshal light clients: %w", err) @@ -42,7 +44,7 @@ func QueryClientState( ) (types.StateResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", - Data: types.KeyClientState(clientID), + Data: ibctypes.KeyClientState(clientID), Prove: prove, } @@ -51,7 +53,7 @@ func QueryClientState( return types.StateResponse{}, err } - var clientState types.State + var clientState exported.ClientState if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &clientState); err != nil { return types.StateResponse{}, err } @@ -64,12 +66,13 @@ func QueryClientState( // QueryConsensusState queries the store to get the consensus state and a merkle // proof. func QueryConsensusState( - cliCtx context.CLIContext, clientID string, prove bool) (types.ConsensusStateResponse, error) { + cliCtx context.CLIContext, clientID string, height uint64, prove bool, +) (types.ConsensusStateResponse, error) { var conStateRes types.ConsensusStateResponse req := abci.RequestQuery{ Path: "store/ibc/key", - Data: types.KeyConsensusState(clientID), + Data: ibctypes.KeyConsensusState(clientID, height), Prove: prove, } @@ -78,7 +81,7 @@ func QueryConsensusState( return conStateRes, err } - var cs tendermint.ConsensusState + var cs exported.ConsensusState if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &cs); err != nil { return conStateRes, err } @@ -86,57 +89,6 @@ func QueryConsensusState( return types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height), nil } -// QueryCommitmentRoot queries the store to get the commitment root and a merkle -// proof. -func QueryCommitmentRoot( - cliCtx context.CLIContext, clientID string, height uint64, prove bool, -) (types.RootResponse, error) { - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyRoot(clientID, height), - Prove: prove, - } - - res, err := cliCtx.QueryABCI(req) - if err != nil { - return types.RootResponse{}, err - } - - var root commitment.Root - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &root); err != nil { - return types.RootResponse{}, err - } - - rootRes := types.NewRootResponse(clientID, height, root, res.Proof, res.Height) - - return rootRes, nil -} - -// QueryCommitter queries the store to get the committer and a merkle proof -func QueryCommitter( - cliCtx context.CLIContext, clientID string, height uint64, prove bool, -) (types.CommitterResponse, error) { - req := abci.RequestQuery{ - Path: "store/ibc/key", - Data: types.KeyCommitter(clientID, height), - Prove: prove, - } - - res, err := cliCtx.QueryABCI(req) - if err != nil { - return types.CommitterResponse{}, err - } - - var committer tendermint.Committer - if err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res.Value, &committer); err != nil { - return types.CommitterResponse{}, err - } - - committerRes := types.NewCommitterResponse(clientID, height, committer, res.Proof, res.Height) - - return committerRes, nil -} - // QueryTendermintHeader takes a client context and returns the appropriate // tendermint header func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, error) { @@ -163,15 +115,9 @@ func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, return tendermint.Header{}, 0, err } - nextvalidators, err := node.Validators(&height, 0, 10000) - if err != nil { - return tendermint.Header{}, 0, err - } - header := tendermint.Header{ - SignedHeader: commit.SignedHeader, - ValidatorSet: tmtypes.NewValidatorSet(validators.Validators), - NextValidatorSet: tmtypes.NewValidatorSet(nextvalidators.Validators), + SignedHeader: commit.SignedHeader, + ValidatorSet: tmtypes.NewValidatorSet(validators.Validators), } return header, height, nil @@ -204,10 +150,8 @@ func QueryNodeConsensusState(cliCtx context.CLIContext) (tendermint.ConsensusSta } state := tendermint.ConsensusState{ - ChainID: commit.ChainID, - Height: uint64(commit.Height), Root: commitment.NewRoot(commit.AppHash), - NextValidatorSet: tmtypes.NewValidatorSet(validators.Validators), + ValidatorSetHash: tmtypes.NewValidatorSet(validators.Validators).Hash(), } return state, height, nil diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index 50632bf71ca8..bdaa85583bce 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -4,45 +4,108 @@ import ( "encoding/json" "fmt" + "github.com/cosmos/cosmos-sdk/codec" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// ClientState defines the required common functions for light clients. +type ClientState interface { + GetID() string + ClientType() ClientType + GetLatestHeight() uint64 + IsFrozen() bool + + // State verification functions + + VerifyClientConsensusState( + cdc *codec.Codec, + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + consensusState ConsensusState, + ) error + VerifyConnectionState( + cdc *codec.Codec, + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + connectionID string, + connectionEnd connectionexported.ConnectionI, + consensusState ConsensusState, + ) error + VerifyChannelState( + cdc *codec.Codec, + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + channel channelexported.ChannelI, + consensusState ConsensusState, + ) error + VerifyPacketCommitment( + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + commitmentBytes []byte, + consensusState ConsensusState, + ) error + VerifyPacketAcknowledgement( + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + acknowledgement []byte, + consensusState ConsensusState, + ) error + VerifyPacketAcknowledgementAbsence( + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + consensusState ConsensusState, + ) error + VerifyNextSequenceRecv( + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + nextSequenceRecv uint64, + consensusState ConsensusState, + ) error +} + // ConsensusState is the state of the consensus process type ConsensusState interface { ClientType() ClientType // Consensus kind - GetHeight() uint64 // GetRoot returns the commitment root of the consensus state, // which is used for key-value pair verification. GetRoot() commitment.RootI - // GetCommitter returns the committer that committed the consensus state - GetCommitter() Committer - - // CheckValidityAndUpdateState returns the updated consensus state - // only if the header is a descendent of this consensus state. - CheckValidityAndUpdateState(Header) (ConsensusState, error) + ValidateBasic() error } // Misbehaviour defines a specific consensus kind and an evidence type Misbehaviour interface { + evidenceexported.Evidence ClientType() ClientType - GetEvidence() evidenceexported.Evidence + GetClientID() string } // Header is the consensus state update information type Header interface { - ClientType() ClientType - GetCommitter() Committer - GetHeight() uint64 -} - -// Committer defines the type that is responsible for -// updating the consensusState at a given height -// -// In Tendermint, this is the ValidatorSet at the given height -type Committer interface { ClientType() ClientType GetHeight() uint64 } diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index 0525e115a014..c9aa56f75404 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/evidence" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ) // HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient @@ -25,6 +25,7 @@ func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) (*sdk sdk.NewEvent( EventTypeCreateClient, sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), + sdk.NewAttribute(AttrbuteKeyClientType, msg.ClientType), ), sdk.NewEvent( sdk.EventTypeMessage, @@ -49,6 +50,7 @@ func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) (*sdk sdk.NewEvent( EventTypeUpdateClient, sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), + sdk.NewAttribute(AttrbuteKeyClientType, msg.Header.ClientType().String()), ), sdk.NewEvent( sdk.EventTypeMessage, @@ -66,12 +68,11 @@ func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) (*sdk // light client misbehaviour. func HandlerClientMisbehaviour(k Keeper) evidence.Handler { return func(ctx sdk.Context, evidence evidenceexported.Evidence) error { - switch e := evidence.(type) { - case tendermint.Misbehaviour: - return k.CheckMisbehaviourAndUpdateState(ctx, evidence) - - default: - return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized IBC client evidence type: %T", e) + misbehaviour, ok := evidence.(exported.Misbehaviour) + if !ok { + return types.ErrInvalidEvidence } + + return k.CheckMisbehaviourAndUpdateState(ctx, misbehaviour) } } diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index 11e805e466e6..b7c8aa272809 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -5,11 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" ) // CreateClient creates a new client state and populates it with a given consensus @@ -17,23 +15,25 @@ import ( func (k Keeper) CreateClient( ctx sdk.Context, clientID string, clientType exported.ClientType, consensusState exported.ConsensusState, -) (types.State, error) { +) (exported.ClientState, error) { _, found := k.GetClientState(ctx, clientID) if found { - return types.State{}, sdkerrors.Wrapf(errors.ErrClientExists, "cannot create client with ID %s", clientID) + return nil, sdkerrors.Wrapf(types.ErrClientExists, "cannot create client with ID %s", clientID) } _, found = k.GetClientType(ctx, clientID) if found { - panic(fmt.Sprintf("consensus type is already defined for client %s", clientID)) + panic(fmt.Sprintf("client type is already defined for client %s", clientID)) + } + + clientState, err := k.initialize(ctx, clientID, clientType, consensusState) + if err != nil { + return nil, sdkerrors.Wrapf(err, "cannot create client with ID %s", clientID) } - clientState := k.initialize(ctx, clientID, consensusState) - k.SetCommitter(ctx, clientID, consensusState.GetHeight(), consensusState.GetCommitter()) - k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) k.SetClientState(ctx, clientState) k.SetClientType(ctx, clientID, clientType) - k.Logger(ctx).Info(fmt.Sprintf("client %s created at height %d", clientID, consensusState.GetHeight())) + k.Logger(ctx).Info(fmt.Sprintf("client %s created at height %d", clientID, clientState.GetLatestHeight())) ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( @@ -53,37 +53,43 @@ func (k Keeper) CreateClient( func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) error { clientType, found := k.GetClientType(ctx, clientID) if !found { - return sdkerrors.Wrapf(errors.ErrClientTypeNotFound, "cannot update client with ID %s", clientID) + return sdkerrors.Wrapf(types.ErrClientTypeNotFound, "cannot update client with ID %s", clientID) } // check that the header consensus matches the client one if header.ClientType() != clientType { - return sdkerrors.Wrapf(errors.ErrInvalidConsensus, "cannot update client with ID %s", clientID) + return sdkerrors.Wrapf(types.ErrInvalidConsensus, "cannot update client with ID %s", clientID) } clientState, found := k.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrapf(errors.ErrClientNotFound, "cannot update client with ID %s", clientID) + return sdkerrors.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID) } - if clientState.Frozen { - return sdkerrors.Wrapf(errors.ErrClientFrozen, "cannot update client with ID %s", clientID) + // addittion to spec: prevent update if the client is frozen + if clientState.IsFrozen() { + return sdkerrors.Wrapf(types.ErrClientFrozen, "cannot update client with ID %s", clientID) } - consensusState, found := k.GetConsensusState(ctx, clientID) - if !found { - return sdkerrors.Wrapf(errors.ErrConsensusStateNotFound, "cannot update client with ID %s", clientID) + var ( + consensusState exported.ConsensusState + err error + ) + + switch clientType { + case exported.Tendermint: + clientState, consensusState, err = tendermint.CheckValidityAndUpdateState(clientState, header, ctx.ChainID()) + default: + return sdkerrors.Wrapf(types.ErrInvalidClientType, "cannot update client with ID %s", clientID) } - consensusState, err := consensusState.CheckValidityAndUpdateState(header) if err != nil { return sdkerrors.Wrapf(err, "cannot update client with ID %s", clientID) } - k.SetConsensusState(ctx, clientID, consensusState) - k.SetCommitter(ctx, clientID, consensusState.GetHeight(), consensusState.GetCommitter()) - k.SetVerifiedRoot(ctx, clientID, consensusState.GetHeight(), consensusState.GetRoot()) - k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, consensusState.GetHeight())) + k.SetClientState(ctx, clientState) + k.SetConsensusState(ctx, clientID, header.GetHeight(), consensusState) + k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, header.GetHeight())) ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( @@ -101,45 +107,40 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H // CheckMisbehaviourAndUpdateState checks for client misbehaviour and freezes the // client if so. -// -// NOTE: In the first implementation, only Tendermint misbehaviour evidence is -// supported. -func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, evidence evidenceexported.Evidence) error { - misbehaviour, ok := evidence.(tendermint.Misbehaviour) - if !ok { - return sdkerrors.Wrap(errors.ErrInvalidClientType, "consensus type is not Tendermint") - } - - clientState, found := k.GetClientState(ctx, misbehaviour.ClientID) +func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, misbehaviour exported.Misbehaviour) error { + clientState, found := k.GetClientState(ctx, misbehaviour.GetClientID()) if !found { - return sdkerrors.Wrap(errors.ErrClientNotFound, misbehaviour.ClientID) + return sdkerrors.Wrap(types.ErrClientNotFound, misbehaviour.GetClientID()) } - committer, found := k.GetCommitter(ctx, misbehaviour.ClientID, uint64(misbehaviour.GetHeight())) + consensusState, found := k.GetConsensusState(ctx, misbehaviour.GetClientID(), uint64(misbehaviour.GetHeight())) if !found { - return errors.ErrCommitterNotFound - } - tmCommitter, ok := committer.(tendermint.Committer) - if !ok { - return sdkerrors.Wrap(errors.ErrInvalidCommitter, "committer type is not Tendermint") + return sdkerrors.Wrap(types.ErrConsensusStateNotFound, misbehaviour.GetClientID()) } - if err := tendermint.CheckMisbehaviour(tmCommitter, misbehaviour); err != nil { - return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) + var err error + switch e := misbehaviour.(type) { + case tendermint.Evidence: + clientState, err = tendermint.CheckMisbehaviourAndUpdateState( + clientState, consensusState, misbehaviour, uint64(misbehaviour.GetHeight()), + ) + + default: + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized IBC client evidence type: %T", e) } - clientState, err := k.freeze(ctx, clientState) if err != nil { return err } k.SetClientState(ctx, clientState) - k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", misbehaviour.ClientID)) + k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", misbehaviour.GetClientID())) ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeSubmitMisbehaviour, - sdk.NewAttribute(types.AttributeKeyClientID, misbehaviour.ClientID), + sdk.NewAttribute(types.AttributeKeyClientID, misbehaviour.GetClientID()), + sdk.NewAttribute(types.AttributeKeyClientType, misbehaviour.ClientType().String()), ), ) diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index c99757d3eacb..c331889237aa 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -4,114 +4,123 @@ import ( "bytes" "fmt" - "github.com/stretchr/testify/require" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) const ( - testClientType exported.ClientType = iota + 2 + invalidClientType exported.ClientType = 0 ) func (suite *KeeperTestSuite) TestCreateClient() { - // Test Valid CreateClient - state, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) - suite.NoError(err, "CreateClient failed") - - // Test ClientState stored correctly - expectedState := types.State{ - ID: testClientID, - Frozen: false, + type params struct { + clientID string + clientType exported.ClientType } - require.Equal(suite.T(), expectedState, state, "Incorrect ClientState returned") - // Test ClientType and VerifiedRoot stored correctly - clientType, _ := suite.keeper.GetClientType(suite.ctx, testClientID) - require.Equal(suite.T(), exported.Tendermint, clientType, "Incorrect ClientType stored") - root, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()) - require.Equal(suite.T(), suite.consensusState.GetRoot(), root, "Incorrect root stored") + suite.keeper.SetClientType(suite.ctx, testClientID2, exported.Tendermint) - // Test that trying to CreateClient on existing client fails - _, err = suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) - suite.Error(err, "CreateClient on existing client: %s passed", testClientID) + cases := []struct { + msg string + params params + expPass bool + expPanic bool + }{ + {"success", params{testClientID, exported.Tendermint}, true, false}, + {"client ID exists", params{testClientID, exported.Tendermint}, false, false}, + {"client type exists", params{testClientID2, exported.Tendermint}, false, true}, + {"invalid client type", params{testClientID3, invalidClientType}, false, false}, + } + + for i, tc := range cases { + tc := tc + + if tc.expPanic { + suite.Require().Panics(func() { + suite.keeper.CreateClient(suite.ctx, tc.params.clientID, tc.params.clientType, suite.consensusState) + }, "Msg %d didn't panic: %s", i, tc.msg) + } else { + clientState, err := suite.keeper.CreateClient(suite.ctx, tc.params.clientID, tc.params.clientType, suite.consensusState) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.msg) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + suite.Require().Nil(clientState, "invalid test case %d passed: %s", i, tc.msg) + } + } + } } func (suite *KeeperTestSuite) TestUpdateClient() { - privVal := tmtypes.NewMockPV() - validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) - altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - altSigners := []tmtypes.PrivValidator{privVal} - - // Test invalid cases all fail and do not update state cases := []struct { name string - malleate func() - expErr bool + malleate func() error + expPass bool }{ - {"valid update", func() {}, false}, - {"wrong client type", func() { - suite.keeper.SetClientType(suite.ctx, testClientID, testClientType) + {"valid update", func() error { + _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + return err }, true}, - {"frozen client", func() { - clientState, _ := suite.keeper.GetClientState(suite.ctx, testClientID) - clientState.Frozen = true + {"client type not found", func() error { + return nil + }, false}, + {"client type and header type mismatch", func() error { + suite.keeper.SetClientType(suite.ctx, testClientID, invalidClientType) + return nil + }, false}, + {"client state not found", func() error { + suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) + return nil + }, false}, + {"frozen client", func() error { + clientState := tendermint.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} suite.keeper.SetClientState(suite.ctx, clientState) - }, true}, - {"past height", func() { - suite.header = tendermint.MakeHeader("gaia", 2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) - }, true}, - {"validatorHash incorrect", func() { - suite.header = tendermint.MakeHeader("gaia", 4, altValSet, suite.valSet, altSigners) - }, true}, - {"nextHash incorrect", func() { - suite.header.NextValidatorSet = altValSet - }, true}, - {"header fails validateBasic", func() { - suite.header.ChainID = "test" - }, true}, - {"verify future commit fails", func() { - suite.consensusState.NextValidatorSet = altValSet - suite.keeper.SetConsensusState(suite.ctx, testClientID, suite.consensusState) - }, true}, + suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) + return nil + }, false}, + {"invalid header", func() error { + _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + if err != nil { + return err + } + suite.header.Height = suite.ctx.BlockHeight() - 1 + return nil + }, false}, } - for _, tc := range cases { - tc := tc // pin for scopelint + for i, tc := range cases { + tc := tc suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - // Reset suite on each subtest suite.SetupTest() - _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) - suite.NoError(err, "CreateClient failed") + err := tc.malleate() + suite.Require().NoError(err) - tc.malleate() err = suite.keeper.UpdateClient(suite.ctx, testClientID, suite.header) - retrievedConsState, _ := suite.keeper.GetConsensusState(suite.ctx, testClientID) - tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) - tmConsState.ValidatorSet.TotalVotingPower() - tmConsState.NextValidatorSet.TotalVotingPower() - retrievedRoot, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()+1) - if tc.expErr { - suite.Error(err, "Invalid UpdateClient passed", tc.name) - - // require no state changes occurred - require.Equal(suite.T(), suite.consensusState, tmConsState, "Consensus state changed after invalid UpdateClient") - require.Nil(suite.T(), retrievedRoot, "Root added for new height after invalid UpdateClient") - } else { - suite.NoError(err, "Valid UpdateClient failed", tc.name) + if tc.expPass { + expConsensusState := tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.header.ValidatorSet.Hash(), + } - // require state changes were performed correctly - require.Equal(suite.T(), suite.header.GetHeight(), retrievedConsState.GetHeight(), "height not updated correctly") - require.Equal(suite.T(), commitment.NewRoot(suite.header.AppHash), retrievedConsState.GetRoot(), "root not updated correctly") - require.Equal(suite.T(), suite.header.NextValidatorSet, tmConsState.NextValidatorSet, "NextValidatorSet not updated correctly") + clientState, found := suite.keeper.GetClientState(suite.ctx, testClientID) + suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) - } + consensusState, found := suite.keeper.GetConsensusState(suite.ctx, testClientID, suite.header.GetHeight()) + suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + suite.Require().Equal(suite.header.GetHeight(), clientState.GetLatestHeight(), "client state height not updated correctly") + suite.Require().Equal(expConsensusState, consensusState, "consensus state should have been updated") + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + } }) } } @@ -135,77 +144,100 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { altSigners := []tmtypes.PrivValidator{altPrivVal} - _, err := suite.keeper.CreateClient(suite.ctx, "gaiamainnet", exported.Tendermint, suite.consensusState) - suite.NoError(err, "CreateClient failed") - testCases := []struct { name string - evidence *tendermint.Evidence - clientID string - expErr bool + evidence tendermint.Evidence + malleate func() error + expPass bool }{ { "trusting period misbehavior should pass", - &tendermint.Evidence{ - Header1: tendermint.MakeHeader("gaia", 5, bothValSet, suite.valSet, bothSigners), - Header2: tendermint.MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), - ChainID: "gaia", + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, suite.valSet, bothSigners), + Header2: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, bothValSet, bothSigners), + FromValidatorSet: bothValSet, + ChainID: testClientID, + ClientID: testClientID, }, - "gaiamainnet", + func() error { + suite.consensusState.ValidatorSetHash = bothValSet.Hash() + _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + return err + }, + true, + }, + { + "client state not found", + tendermint.Evidence{}, + func() error { return nil }, false, }, { - "first valset has too much change", - &tendermint.Evidence{ - Header1: tendermint.MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), - Header2: tendermint.MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), - ChainID: "gaia", + "consensus state not found", + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, suite.valSet, bothSigners), + Header2: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, bothValSet, bothSigners), + ChainID: testClientID, + ClientID: testClientID, }, - "gaiamainnet", - true, + func() error { + clientState := tendermint.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} + suite.keeper.SetClientState(suite.ctx, clientState) + return nil + }, + false, }, { - "second valset has too much change", - &tendermint.Evidence{ - Header1: tendermint.MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), - Header2: tendermint.MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), - ChainID: "gaia", + "consensus state not found", + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, suite.valSet, bothSigners), + Header2: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, bothValSet, bothSigners), + ChainID: testClientID, + ClientID: testClientID, }, - "gaiamainnet", - true, + func() error { + clientState := tendermint.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} + suite.keeper.SetClientState(suite.ctx, clientState) + return nil + }, + false, }, { - "both valsets have too much change", - &tendermint.Evidence{ - Header1: tendermint.MakeHeader("gaia", 5, altValSet, altValSet, altSigners), - Header2: tendermint.MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), - ChainID: "gaia", + "misbehaviour check failed", + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, bothValSet, bothSigners), + Header2: tendermint.CreateTestHeader(testClientID, testClientHeight, altValSet, bothValSet, altSigners), + FromValidatorSet: bothValSet, + ChainID: testClientID, + ClientID: testClientID, }, - "gaiamainnet", - true, + func() error { + _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + return err + }, + false, }, } - for _, tc := range testCases { - tc := tc // pin for scopelint + for i, tc := range testCases { + tc := tc suite.Run(tc.name, func() { - misbehaviour := tendermint.Misbehaviour{ - Evidence: tc.evidence, - ClientID: tc.clientID, - } + suite.SetupTest() // reset + + err := tc.malleate() + suite.Require().NoError(err) + + err = suite.keeper.CheckMisbehaviourAndUpdateState(suite.ctx, tc.evidence) - err = suite.keeper.CheckMisbehaviourAndUpdateState(suite.ctx, misbehaviour) + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - if tc.expErr { - suite.Error(err, "CheckMisbehaviour passed unexpectedly") + clientState, found := suite.keeper.GetClientState(suite.ctx, testClientID) + suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) + suite.Require().True(clientState.IsFrozen(), "valid test case %d failed: %s", i, tc.name) } else { - suite.NoError(err, "CheckMisbehaviour failed unexpectedly: %v", err) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) } - - // reset Frozen flag to false - clientState, _ := suite.keeper.GetClientState(suite.ctx, tc.clientID) - clientState.Frozen = false - suite.keeper.SetClientState(suite.ctx, clientState) }) } } diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index 5732913247b3..4b31f8f08cb2 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -7,11 +7,9 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -36,29 +34,29 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { } // GetClientState gets a particular client from the store -func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (types.State, bool) { +func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (exported.ClientState, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyClientState(clientID)) + bz := store.Get(ibctypes.KeyClientState(clientID)) if bz == nil { - return types.State{}, false + return nil, false } - var clientState types.State + var clientState exported.ClientState k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &clientState) return clientState, true } // SetClientState sets a particular Client to the store -func (k Keeper) SetClientState(ctx sdk.Context, clientState types.State) { +func (k Keeper) SetClientState(ctx sdk.Context, clientState exported.ClientState) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(clientState) - store.Set(types.KeyClientState(clientState.ID), bz) + store.Set(ibctypes.KeyClientState(clientState.GetID()), bz) } // GetClientType gets the consensus type for a specific client func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.ClientType, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyClientType(clientID)) + bz := store.Get(ibctypes.KeyClientType(clientID)) if bz == nil { return 0, false } @@ -69,13 +67,13 @@ func (k Keeper) GetClientType(ctx sdk.Context, clientID string) (exported.Client // SetClientType sets the specific client consensus type to the provable store func (k Keeper) SetClientType(ctx sdk.Context, clientID string, clientType exported.ClientType) { store := ctx.KVStore(k.storeKey) - store.Set(types.KeyClientType(clientID), []byte{byte(clientType)}) + store.Set(ibctypes.KeyClientType(clientID), []byte{byte(clientType)}) } // GetConsensusState creates a new client state and populates it with a given consensus state -func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.ConsensusState, bool) { +func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string, height uint64) (exported.ConsensusState, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyConsensusState(clientID)) + bz := store.Get(ibctypes.KeyConsensusState(clientID, height)) if bz == nil { return nil, false } @@ -86,45 +84,22 @@ func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string) (exported.Co } // SetConsensusState sets a ConsensusState to a particular client -func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) { +func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, height uint64, consensusState exported.ConsensusState) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) - store.Set(types.KeyConsensusState(clientID), bz) -} - -// GetVerifiedRoot gets a verified commitment Root from a particular height to -// a client -func (k Keeper) GetVerifiedRoot(ctx sdk.Context, clientID string, height uint64) (commitment.RootI, bool) { - store := ctx.KVStore(k.storeKey) - - bz := store.Get(types.KeyRoot(clientID, height)) - if bz == nil { - return nil, false - } - - var root commitment.RootI - k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &root) - return root, true -} - -// SetVerifiedRoot sets a verified commitment Root from a particular height to -// a client -func (k Keeper) SetVerifiedRoot(ctx sdk.Context, clientID string, height uint64, root commitment.RootI) { - store := ctx.KVStore(k.storeKey) - bz := k.cdc.MustMarshalBinaryLengthPrefixed(root) - store.Set(types.KeyRoot(clientID, height), bz) + store.Set(ibctypes.KeyConsensusState(clientID, height), bz) } // IterateClients provides an iterator over all stored light client State // objects. For each State object, cb will be called. If the cb returns true, // the iterator will close and stop. -func (k Keeper) IterateClients(ctx sdk.Context, cb func(types.State) bool) { +func (k Keeper) IterateClients(ctx sdk.Context, cb func(exported.ClientState) bool) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types.GetClientKeysPrefix(ibctypes.KeyClientPrefix)) + iterator := sdk.KVStorePrefixIterator(store, ibctypes.KeyClientPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { - var clientState types.State + var clientState exported.ClientState k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &clientState) if cb(clientState) { @@ -134,105 +109,30 @@ func (k Keeper) IterateClients(ctx sdk.Context, cb func(types.State) bool) { } // GetAllClients returns all stored light client State objects. -func (k Keeper) GetAllClients(ctx sdk.Context) (states []types.State) { - k.IterateClients(ctx, func(state types.State) bool { +func (k Keeper) GetAllClients(ctx sdk.Context) (states []exported.ClientState) { + k.IterateClients(ctx, func(state exported.ClientState) bool { states = append(states, state) return false }) return states } -// GetCommitter will get the Committer of a particular client at the oldest height -// that is less than or equal to the height passed in -func (k Keeper) GetCommitter(ctx sdk.Context, clientID string, height uint64) (exported.Committer, bool) { - store := ctx.KVStore(k.storeKey) - - var committer exported.Committer - - // TODO: Replace this for-loop with a ReverseIterator for efficiency - for i := height; i > 0; i-- { - bz := store.Get(types.KeyCommitter(clientID, i)) - if bz != nil { - k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &committer) - return committer, true - } - } - return nil, false -} - -// SetCommitter sets a committer from a particular height to -// a particular client -func (k Keeper) SetCommitter(ctx sdk.Context, clientID string, height uint64, committer exported.Committer) { - store := ctx.KVStore(k.storeKey) - bz := k.cdc.MustMarshalBinaryLengthPrefixed(committer) - store.Set(types.KeyCommitter(clientID, height), bz) -} - // State returns a new client state with a given id as defined in // https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#example-implementation -func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState exported.ConsensusState) types.State { - clientState := types.NewClientState(clientID) - k.SetConsensusState(ctx, clientID, consensusState) - return clientState -} - -// freeze updates the state of the client in the event of a misbehaviour -func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) { - if clientState.Frozen { - return types.State{}, sdkerrors.Wrap(errors.ErrClientFrozen, clientState.ID) +func (k Keeper) initialize( + ctx sdk.Context, clientID string, clientType exported.ClientType, + consensusState exported.ConsensusState, +) (exported.ClientState, error) { + var clientState exported.ClientState + height := uint64(ctx.BlockHeight()) + + switch clientType { + case exported.Tendermint: + clientState = tendermint.NewClientState(clientID, height) + default: + return nil, types.ErrInvalidClientType } - clientState.Frozen = true + k.SetConsensusState(ctx, clientID, height, consensusState) return clientState, nil } - -// VerifyMembership state membership verification function defined by the client type -func (k Keeper) VerifyMembership( - ctx sdk.Context, - clientID string, - height uint64, // sequence - proof commitment.ProofI, - path commitment.PathI, - value []byte, -) bool { - clientState, found := k.GetClientState(ctx, clientID) - if !found { - return false - } - - if clientState.Frozen { - return false - } - - root, found := k.GetVerifiedRoot(ctx, clientID, height) - if !found { - return false - } - - return proof.VerifyMembership(root, path, value) -} - -// VerifyNonMembership state non-membership function defined by the client type -func (k Keeper) VerifyNonMembership( - ctx sdk.Context, - clientID string, - height uint64, // sequence - proof commitment.ProofI, - path commitment.PathI, -) bool { - clientState, found := k.GetClientState(ctx, clientID) - if !found { - return false - } - - if clientState.Frozen { - return false - } - - root, found := k.GetVerifiedRoot(ctx, clientID, height) - if !found { - return false - } - - return proof.VerifyNonMembership(root, path) -} diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index 2c74a5a22f7c..eb0edc99d3e4 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -3,8 +3,10 @@ package keeper_test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/tmhash" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" @@ -12,18 +14,16 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" ) const ( testClientID = "gaia" testClientID2 = "ethbridge" testClientID3 = "ethermint" + + testClientHeight = 5 ) type KeeperTestSuite struct { @@ -43,7 +43,7 @@ func (suite *KeeperTestSuite) SetupTest() { app := simapp.Setup(isCheckTx) suite.cdc = app.Codec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{Height: testClientHeight, ChainID: testClientID}) suite.keeper = &app.IBCKeeper.ClientKeeper suite.privVal = tmtypes.NewMockPV() @@ -51,14 +51,11 @@ func (suite *KeeperTestSuite) SetupTest() { validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - suite.header = tendermint.MakeHeader("gaia", 4, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = tendermint.CreateTestHeader(testClientID, testClientHeight, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.consensusState = tendermint.ConsensusState{ - ChainID: testClientID, - Height: 3, Root: commitment.NewRoot([]byte("hash")), - ValidatorSet: suite.valSet, - NextValidatorSet: suite.valSet, + ValidatorSetHash: suite.valSet.Hash(), } } @@ -67,95 +64,37 @@ func TestKeeperTestSuite(t *testing.T) { } func (suite *KeeperTestSuite) TestSetClientState() { - clientState := types.NewClientState(testClientID) + clientState := tendermint.NewClientState(testClientID, testClientHeight) suite.keeper.SetClientState(suite.ctx, clientState) - retrievedState, ok := suite.keeper.GetClientState(suite.ctx, testClientID) - require.True(suite.T(), ok, "GetClientState failed") - require.Equal(suite.T(), clientState, retrievedState, "Client states are not equal") + retrievedState, found := suite.keeper.GetClientState(suite.ctx, testClientID) + suite.Require().True(found, "GetClientState failed") + suite.Require().Equal(clientState, retrievedState, "Client states are not equal") } func (suite *KeeperTestSuite) TestSetClientType() { suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) - clientType, ok := suite.keeper.GetClientType(suite.ctx, testClientID) + clientType, found := suite.keeper.GetClientType(suite.ctx, testClientID) - require.True(suite.T(), ok, "GetClientType failed") - require.Equal(suite.T(), exported.Tendermint, clientType, "ClientTypes not stored correctly") + suite.Require().True(found, "GetClientType failed") + suite.Require().Equal(exported.Tendermint, clientType, "ClientTypes not stored correctly") } func (suite *KeeperTestSuite) TestSetConsensusState() { - suite.keeper.SetConsensusState(suite.ctx, testClientID, suite.consensusState) + suite.keeper.SetConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) - retrievedConsState, ok := suite.keeper.GetConsensusState(suite.ctx, testClientID) + retrievedConsState, found := suite.keeper.GetConsensusState(suite.ctx, testClientID, testClientHeight) - require.True(suite.T(), ok, "GetConsensusState failed") + suite.Require().True(found, "GetConsensusState failed") tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) - // force recalculation of unexported totalVotingPower so we can compare consensusState - tmConsState.ValidatorSet.TotalVotingPower() - tmConsState.NextValidatorSet.TotalVotingPower() require.Equal(suite.T(), suite.consensusState, tmConsState, "ConsensusState not stored correctly") } -func (suite *KeeperTestSuite) TestSetVerifiedRoot() { - root := commitment.NewRoot([]byte("hash")) - suite.keeper.SetVerifiedRoot(suite.ctx, testClientID, 3, root) - - retrievedRoot, ok := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, 3) - - require.True(suite.T(), ok, "GetVerifiedRoot failed") - require.Equal(suite.T(), root, retrievedRoot, "Root stored incorrectly") -} - -func (suite KeeperTestSuite) TestSetCommitter() { - committer := tendermint.Committer{ - ValidatorSet: suite.valSet, - Height: 3, - NextValSetHash: suite.valSet.Hash(), - } - nextCommitter := tendermint.Committer{ - ValidatorSet: suite.valSet, - Height: 6, - NextValSetHash: tmhash.Sum([]byte("next_hash")), - } - - suite.keeper.SetCommitter(suite.ctx, "gaia", 3, committer) - suite.keeper.SetCommitter(suite.ctx, "gaia", 6, nextCommitter) - - // fetch the commiter on each respective height - for i := 0; i < 3; i++ { - committer, ok := suite.keeper.GetCommitter(suite.ctx, "gaia", uint64(i)) - require.False(suite.T(), ok, "GetCommitter passed on nonexistent height: %d", i) - require.Nil(suite.T(), committer, "GetCommitter returned committer on nonexistent height: %d", i) - } - - for i := 3; i < 6; i++ { - recv, ok := suite.keeper.GetCommitter(suite.ctx, "gaia", uint64(i)) - tmRecv, _ := recv.(tendermint.Committer) - if tmRecv.ValidatorSet != nil { - // update validator set's power - tmRecv.ValidatorSet.TotalVotingPower() - } - require.True(suite.T(), ok, "GetCommitter failed on existing height: %d", i) - require.Equal(suite.T(), committer, recv, "GetCommitter returned committer on nonexistent height: %d", i) - } - - for i := 6; i < 9; i++ { - recv, ok := suite.keeper.GetCommitter(suite.ctx, "gaia", uint64(i)) - tmRecv, _ := recv.(tendermint.Committer) - if tmRecv.ValidatorSet != nil { - // update validator set's power - tmRecv.ValidatorSet.TotalVotingPower() - } - require.True(suite.T(), ok, "GetCommitter failed on existing height: %d", i) - require.Equal(suite.T(), nextCommitter, recv, "GetCommitter returned committer on nonexistent height: %d", i) - } -} - func (suite KeeperTestSuite) TestGetAllClients() { - expClients := []types.State{ - types.NewClientState(testClientID2), - types.NewClientState(testClientID3), - types.NewClientState(testClientID), + expClients := []exported.ClientState{ + tendermint.NewClientState(testClientID2, testClientHeight), + tendermint.NewClientState(testClientID3, testClientHeight), + tendermint.NewClientState(testClientID, testClientHeight), } for i := range expClients { diff --git a/x/ibc/02-client/keeper/querier.go b/x/ibc/02-client/keeper/querier.go index 87da8c1eea5f..7cadac9fe426 100644 --- a/x/ibc/02-client/keeper/querier.go +++ b/x/ibc/02-client/keeper/querier.go @@ -7,8 +7,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" ) // QuerierClients defines the sdk.Querier to query all the light client states. @@ -23,7 +23,7 @@ func QuerierClients(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e start, end := client.Paginate(len(clients), params.Page, params.Limit, 100) if start < 0 || end < 0 { - clients = []types.State{} + clients = []exported.ClientState{} } else { clients = clients[start:end] } @@ -35,87 +35,3 @@ func QuerierClients(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e return res, nil } - -// QuerierClientState defines the sdk.Querier to query the IBC client state -func QuerierClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { - var params types.QueryClientStateParams - - if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) - } - - clientState, found := k.GetClientState(ctx, params.ClientID) - if !found { - return nil, sdkerrors.Wrap(errors.ErrClientTypeNotFound, params.ClientID) - } - - bz, err := codec.MarshalJSONIndent(k.cdc, clientState) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - - return bz, nil -} - -// QuerierConsensusState defines the sdk.Querier to query a consensus state -func QuerierConsensusState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { - var params types.QueryClientStateParams - - if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) - } - - consensusState, found := k.GetConsensusState(ctx, params.ClientID) - if !found { - return nil, errors.ErrConsensusStateNotFound - } - - bz, err := codec.MarshalJSONIndent(k.cdc, consensusState) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - - return bz, nil -} - -// QuerierVerifiedRoot defines the sdk.Querier to query a verified commitment root -func QuerierVerifiedRoot(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { - var params types.QueryCommitmentRootParams - - if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) - } - - root, found := k.GetVerifiedRoot(ctx, params.ClientID, params.Height) - if !found { - return nil, errors.ErrRootNotFound - } - - bz, err := codec.MarshalJSONIndent(k.cdc, root) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - - return bz, nil -} - -// QuerierCommitter defines the sdk.Querier to query a committer -func QuerierCommitter(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { - var params types.QueryCommitterParams - - if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) - } - - committer, found := k.GetCommitter(ctx, params.ClientID, params.Height) - if !found { - return nil, errors.ErrCommitterNotFound - } - - bz, err := codec.MarshalJSONIndent(k.cdc, committer) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - - return bz, nil -} diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index 6cd376b6e8ea..3226fc02c2cf 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -3,7 +3,6 @@ package types import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" ) // SubModuleCdc defines the IBC client codec. @@ -11,19 +10,13 @@ var SubModuleCdc *codec.Codec // RegisterCodec registers the IBC client interfaces and types func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*exported.ClientState)(nil), nil) cdc.RegisterInterface((*exported.ConsensusState)(nil), nil) - cdc.RegisterInterface((*exported.Committer)(nil), nil) cdc.RegisterInterface((*exported.Header)(nil), nil) cdc.RegisterInterface((*exported.Misbehaviour)(nil), nil) cdc.RegisterConcrete(MsgCreateClient{}, "ibc/client/MsgCreateClient", nil) cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) - cdc.RegisterConcrete(State{}, "ibc/client/State", nil) - - cdc.RegisterConcrete(tendermint.ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) - cdc.RegisterConcrete(tendermint.Committer{}, "ibc/client/tendermint/Committer", nil) - cdc.RegisterConcrete(tendermint.Header{}, "ibc/client/tendermint/Header", nil) - cdc.RegisterConcrete(tendermint.Evidence{}, "ibc/client/tendermint/Evidence", nil) SetSubModuleCodec(cdc) } diff --git a/x/ibc/02-client/types/errors.go b/x/ibc/02-client/types/errors.go new file mode 100644 index 000000000000..ceba41f85988 --- /dev/null +++ b/x/ibc/02-client/types/errors.go @@ -0,0 +1,26 @@ +package types + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// IBC client sentinel errors +var ( + ErrClientExists = sdkerrors.Register(SubModuleName, 1, "light client already exists") + ErrClientNotFound = sdkerrors.Register(SubModuleName, 2, "light client not found") + ErrClientFrozen = sdkerrors.Register(SubModuleName, 3, "light client is frozen due to misbehaviour") + ErrConsensusStateNotFound = sdkerrors.Register(SubModuleName, 4, "consensus state not found") + ErrInvalidConsensus = sdkerrors.Register(SubModuleName, 5, "invalid consensus state") + ErrClientTypeNotFound = sdkerrors.Register(SubModuleName, 6, "client type not found") + ErrInvalidClientType = sdkerrors.Register(SubModuleName, 7, "invalid client type") + ErrRootNotFound = sdkerrors.Register(SubModuleName, 8, "commitment root not found") + ErrInvalidHeader = sdkerrors.Register(SubModuleName, 9, "invalid block header") + ErrInvalidEvidence = sdkerrors.Register(SubModuleName, 10, "invalid light client misbehaviour evidence") + ErrFailedClientConsensusStateVerification = sdkerrors.Register(SubModuleName, 13, "client consensus state verification failed") + ErrFailedConnectionStateVerification = sdkerrors.Register(SubModuleName, 14, "connection state verification failed") + ErrFailedChannelStateVerification = sdkerrors.Register(SubModuleName, 15, "channel state verification failed") + ErrFailedPacketCommitmentVerification = sdkerrors.Register(SubModuleName, 16, "packet commitment verification failed") + ErrFailedPacketAckVerification = sdkerrors.Register(SubModuleName, 17, "packet acknowledgement verification failed") + ErrFailedPacketAckAbsenceVerification = sdkerrors.Register(SubModuleName, 18, "packet acknowledgement absence verification failed") + ErrFailedNextSeqRecvVerification = sdkerrors.Register(SubModuleName, 19, "next sequence receive verification failed") +) diff --git a/x/ibc/02-client/types/errors/errors.go b/x/ibc/02-client/types/errors/errors.go deleted file mode 100644 index b6786a6113f6..000000000000 --- a/x/ibc/02-client/types/errors/errors.go +++ /dev/null @@ -1,24 +0,0 @@ -package errors - -import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// SubModuleName is the error codespace -const SubModuleName string = "ibc/client" - -// IBC client sentinel errors -var ( - ErrClientExists = sdkerrors.Register(SubModuleName, 1, "light client already exists") - ErrClientNotFound = sdkerrors.Register(SubModuleName, 2, "light client not found") - ErrClientFrozen = sdkerrors.Register(SubModuleName, 3, "light client is frozen due to misbehaviour") - ErrConsensusStateNotFound = sdkerrors.Register(SubModuleName, 4, "consensus state not found") - ErrInvalidConsensus = sdkerrors.Register(SubModuleName, 5, "invalid consensus state") - ErrClientTypeNotFound = sdkerrors.Register(SubModuleName, 6, "client type not found") - ErrInvalidClientType = sdkerrors.Register(SubModuleName, 7, "invalid client type") - ErrRootNotFound = sdkerrors.Register(SubModuleName, 8, "commitment root not found") - ErrInvalidHeader = sdkerrors.Register(SubModuleName, 9, "invalid block header") - ErrInvalidEvidence = sdkerrors.Register(SubModuleName, 10, "invalid light client misbehaviour evidence") - ErrCommitterNotFound = sdkerrors.Register(SubModuleName, 11, "commiter not found") - ErrInvalidCommitter = sdkerrors.Register(SubModuleName, 12, "invalid commiter") -) diff --git a/x/ibc/02-client/types/events.go b/x/ibc/02-client/types/events.go index 6b02bfa5eaf8..ea0dcc7d6606 100644 --- a/x/ibc/02-client/types/events.go +++ b/x/ibc/02-client/types/events.go @@ -8,7 +8,8 @@ import ( // IBC client events const ( - AttributeKeyClientID = "client_id" + AttributeKeyClientID = "client_id" + AttributeKeyClientType = "client_type" ) // IBC client events vars diff --git a/x/ibc/02-client/types/keys.go b/x/ibc/02-client/types/keys.go index eeb7e8b0d8b9..f360393335d5 100644 --- a/x/ibc/02-client/types/keys.go +++ b/x/ibc/02-client/types/keys.go @@ -1,121 +1,12 @@ package types -import ( - "fmt" - - ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" -) - const ( // SubModuleName defines the IBC client name SubModuleName string = "client" - // StoreKey is the store key string for IBC client - StoreKey string = SubModuleName - // RouterKey is the message route for IBC client RouterKey string = SubModuleName // QuerierRoute is the querier route for IBC client QuerierRoute string = SubModuleName ) - -// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space - -// ClientStatePath takes an Identifier and returns a Path under which to store a -// particular client state -func ClientStatePath(clientID string) string { - return string(KeyClientState(clientID)) -} - -// ClientTypePath takes an Identifier and returns Path under which to store the -// type of a particular client. -func ClientTypePath(clientID string) string { - return string(KeyClientType(clientID)) -} - -// ConsensusStatePath takes an Identifier and returns a Path under which to -// store the consensus state of a client. -func ConsensusStatePath(clientID string) string { - return string(KeyConsensusState(clientID)) -} - -// RootPath takes an Identifier and returns a Path under which to -// store the root for a particular height of a client. -func RootPath(clientID string, height uint64) string { - return string(KeyRoot(clientID, height)) -} - -// CommitterPath takes an Identifier and returns a Path under which -// to store the committer of a client at a particular height -func CommitterPath(clientID string, height uint64) string { - return string(KeyCommitter(clientID, height)) -} - -// KeyClientState returns the store key for a particular client state -func KeyClientState(clientID string) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyClientPrefix), - []byte(clientStatePath(clientID))..., - ) -} - -// KeyClientType returns the store key for type of a particular client -func KeyClientType(clientID string) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyClientTypePrefix), - []byte(clientTypePath(clientID))..., - ) -} - -// KeyConsensusState returns the store key for the consensus state of a particular -// client -func KeyConsensusState(clientID string) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyConsensusStatePrefix), - []byte(consensusStatePath(clientID))..., - ) -} - -// KeyRoot returns the store key for a commitment root of a particular -// client at a given height -func KeyRoot(clientID string, height uint64) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyRootPrefix), - []byte(rootPath(clientID, height))..., - ) -} - -// KeyCommitter returns the store key for a validator (aka commiter) of a particular -// client at a given height. -func KeyCommitter(clientID string, height uint64) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyCommiterPrefix), - []byte(committerPath(clientID, height))..., - ) -} - -// GetClientKeysPrefix return the ICS02 prefix bytes -func GetClientKeysPrefix(prefix int) []byte { - return []byte(fmt.Sprintf("%d/clients", prefix)) -} - -func clientStatePath(clientID string) string { - return fmt.Sprintf("clients/%s/state", clientID) -} - -func clientTypePath(clientID string) string { - return fmt.Sprintf("clients/%s/type", clientID) -} - -func consensusStatePath(clientID string) string { - return fmt.Sprintf("clients/%s/consensusState", clientID) -} - -func rootPath(clientID string, height uint64) string { - return fmt.Sprintf("clients/%s/roots/%d", clientID, height) -} - -func committerPath(clientID string, height uint64) string { - return fmt.Sprintf("clients/%s/committer/%d", clientID, height) -} diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/02-client/types/msgs.go index 128c76e4144b..2790d8d18884 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/02-client/types/msgs.go @@ -3,9 +3,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -50,10 +48,13 @@ func (msg MsgCreateClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgCreateClient) ValidateBasic() error { if clientType := exported.ClientTypeFromString(msg.ClientType); clientType == 0 { - return sdkerrors.Wrap(errors.ErrInvalidClientType, msg.ClientType) + return sdkerrors.Wrap(ErrInvalidClientType, msg.ClientType) } if msg.ConsensusState == nil { - return errors.ErrInvalidConsensus + return ErrInvalidConsensus + } + if err := msg.ConsensusState.ValidateBasic(); err != nil { + return err } if msg.Signer.Empty() { return sdkerrors.ErrInvalidAddress @@ -102,7 +103,7 @@ func (msg MsgUpdateClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgUpdateClient) ValidateBasic() error { if msg.Header == nil { - return errors.ErrInvalidHeader + return ErrInvalidHeader } if msg.Signer.Empty() { return sdkerrors.ErrInvalidAddress @@ -119,53 +120,3 @@ func (msg MsgUpdateClient) GetSignBytes() []byte { func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Signer} } - -// MsgSubmitMisbehaviour defines a message to update an IBC client -type MsgSubmitMisbehaviour struct { - ClientID string `json:"id" yaml:"id"` - Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` - Signer sdk.AccAddress `json:"address" yaml:"address"` -} - -// NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance -func NewMsgSubmitMisbehaviour(id string, evidence evidenceexported.Evidence, signer sdk.AccAddress) MsgSubmitMisbehaviour { - return MsgSubmitMisbehaviour{ - ClientID: id, - Evidence: evidence, - Signer: signer, - } -} - -// Route implements sdk.Msg -func (msg MsgSubmitMisbehaviour) Route() string { - return ibctypes.RouterKey -} - -// Type implements sdk.Msg -func (msg MsgSubmitMisbehaviour) Type() string { - return "submit_misbehaviour" -} - -// ValidateBasic implements sdk.Msg -func (msg MsgSubmitMisbehaviour) ValidateBasic() error { - if msg.Evidence == nil { - return sdkerrors.Wrap(errors.ErrInvalidEvidence, "evidence cannot be nil") - } - if err := msg.Evidence.ValidateBasic(); err != nil { - return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) - } - if msg.Signer.Empty() { - return sdkerrors.ErrInvalidAddress - } - return host.DefaultClientIdentifierValidator(msg.ClientID) -} - -// GetSignBytes implements sdk.Msg -func (msg MsgSubmitMisbehaviour) GetSignBytes() []byte { - return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) -} - -// GetSigners implements sdk.Msg -func (msg MsgSubmitMisbehaviour) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Signer} -} diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go index 1c4f56e76e26..c1c177a3db0b 100644 --- a/x/ibc/02-client/types/msgs_test.go +++ b/x/ibc/02-client/types/msgs_test.go @@ -1,4 +1,4 @@ -package types +package types_test import ( "testing" @@ -6,135 +6,66 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/secp256k1" - tmbytes "github.com/tendermint/tendermint/libs/bytes" sdk "github.com/cosmos/cosmos-sdk/types" - evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -var _ evidenceexported.Evidence = mockEvidence{} -var _ evidenceexported.Evidence = mockBadEvidence{} - -const mockStr = "mock" - -// mock GoodEvidence -type mockEvidence struct{} - -// Implement Evidence interface -func (me mockEvidence) Route() string { return mockStr } -func (me mockEvidence) Type() string { return mockStr } -func (me mockEvidence) String() string { return mockStr } -func (me mockEvidence) Hash() tmbytes.HexBytes { return tmbytes.HexBytes([]byte(mockStr)) } -func (me mockEvidence) ValidateBasic() error { return nil } -func (me mockEvidence) GetHeight() int64 { return 3 } - -// mock bad evidence -type mockBadEvidence struct { - mockEvidence -} - -// Override ValidateBasic -func (mbe mockBadEvidence) ValidateBasic() error { - return errors.ErrInvalidEvidence -} - func TestMsgCreateClientValidateBasic(t *testing.T) { - cs := tendermint.ConsensusState{} - privKey := secp256k1.GenPrivKey() - signer := sdk.AccAddress(privKey.PubKey().Address()) - testMsgs := []MsgCreateClient{ - NewMsgCreateClient(exported.ClientTypeTendermint, exported.ClientTypeTendermint, cs, signer), // valid msg - NewMsgCreateClient("badClient", exported.ClientTypeTendermint, cs, signer), // invalid client id - NewMsgCreateClient("goodChain", "bad_type", cs, signer), // invalid client type - NewMsgCreateClient("goodChain", exported.ClientTypeTendermint, nil, signer), // nil Consensus State - NewMsgCreateClient("goodChain", exported.ClientTypeTendermint, cs, sdk.AccAddress{}), // empty signer + cs := tendermint.ConsensusState{ + Root: commitment.NewRoot([]byte("root")), + ValidatorSetHash: []byte("hash"), } - - cases := []struct { - msg MsgCreateClient - expPass bool - errMsg string - }{ - {testMsgs[0], true, ""}, - {testMsgs[1], false, "invalid client id passed"}, - {testMsgs[2], false, "unregistered client type passed"}, - {testMsgs[3], false, "Nil Consensus State in msg passed"}, - {testMsgs[4], false, "Empty address passed"}, - } - - for i, tc := range cases { - err := tc.msg.ValidateBasic() - if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) - } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) - } - } -} - -func TestMsgUpdateClient(t *testing.T) { privKey := secp256k1.GenPrivKey() signer := sdk.AccAddress(privKey.PubKey().Address()) - testMsgs := []MsgUpdateClient{ - NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, signer), // valid msg - NewMsgUpdateClient("badClient", tendermint.Header{}, signer), // bad client id - NewMsgUpdateClient(exported.ClientTypeTendermint, nil, signer), // nil Header - NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, sdk.AccAddress{}), // empty address - } cases := []struct { - msg MsgUpdateClient + msg types.MsgCreateClient expPass bool errMsg string }{ - {testMsgs[0], true, ""}, - {testMsgs[1], false, "invalid client id passed"}, - {testMsgs[2], false, "Nil Header passed"}, - {testMsgs[3], false, "Empty address passed"}, + {types.NewMsgCreateClient(exported.ClientTypeTendermint, exported.ClientTypeTendermint, cs, signer), true, "success msg should pass"}, + {types.NewMsgCreateClient("BADCHAIN", exported.ClientTypeTendermint, cs, signer), false, "invalid client id passed"}, + {types.NewMsgCreateClient("goodchain", "invalid_client_type", cs, signer), false, "unregistered client type passed"}, + {types.NewMsgCreateClient("goodchain", exported.ClientTypeTendermint, nil, signer), false, "nil Consensus State in msg passed"}, + {types.NewMsgCreateClient("goodchain", exported.ClientTypeTendermint, tendermint.ConsensusState{}, signer), false, "invalid Consensus State in msg passed"}, + {types.NewMsgCreateClient("goodchain", exported.ClientTypeTendermint, cs, nil), false, "Empty address passed"}, } for i, tc := range cases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + require.NoError(t, err, "Msg %d failed: %v", i, err) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } -func TestMsgSubmitMisbehaviour(t *testing.T) { +func TestMsgUpdateClient(t *testing.T) { privKey := secp256k1.GenPrivKey() signer := sdk.AccAddress(privKey.PubKey().Address()) - testMsgs := []MsgSubmitMisbehaviour{ - NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, mockEvidence{}, signer), // valid msg - NewMsgSubmitMisbehaviour("badClient", mockEvidence{}, signer), // bad client id - NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, nil, signer), // nil evidence - NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, mockBadEvidence{}, signer), // invalid evidence - NewMsgSubmitMisbehaviour(exported.ClientTypeTendermint, mockEvidence{}, sdk.AccAddress{}), // empty signer - } cases := []struct { - msg MsgSubmitMisbehaviour + msg types.MsgUpdateClient expPass bool errMsg string }{ - {testMsgs[0], true, ""}, - {testMsgs[1], false, "invalid client id passed"}, - {testMsgs[2], false, "Nil Evidence passed"}, - {testMsgs[3], false, "Invalid Evidence passed"}, - {testMsgs[4], false, "Empty address passed"}, + {types.NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, signer), true, "success msg should pass"}, + {types.NewMsgUpdateClient("badClient", tendermint.Header{}, signer), false, "invalid client id passed"}, + {types.NewMsgUpdateClient(exported.ClientTypeTendermint, nil, signer), false, "Nil Header passed"}, + {types.NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, nil), false, "Empty address passed"}, } for i, tc := range cases { err := tc.msg.ValidateBasic() if tc.expPass { - require.Nil(t, err, "Msg %d failed: %v", i, err) + require.NoError(t, err, "Msg %d failed: %v", i, err) } else { - require.NotNil(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go index d2862307b09b..31a1b3586006 100644 --- a/x/ibc/02-client/types/querier.go +++ b/x/ibc/02-client/types/querier.go @@ -5,8 +5,9 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" - tmtypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // query routes supported by the IBC client Querier @@ -14,23 +15,8 @@ const ( QueryAllClients = "client_states" QueryClientState = "client_state" QueryConsensusState = "consensus_state" - QueryVerifiedRoot = "roots" ) -// QueryClientStateParams defines the params for the following queries: -// - 'custom/ibc/clients//client_state' -// - 'custom/ibc/clients//consensus_state' -type QueryClientStateParams struct { - ClientID string -} - -// NewQueryClientStateParams creates a new QueryClientStateParams instance -func NewQueryClientStateParams(id string) QueryClientStateParams { - return QueryClientStateParams{ - ClientID: id, - } -} - // QueryAllClientsParams defines the parameters necessary for querying for all // light client states. type QueryAllClientsParams struct { @@ -46,53 +32,23 @@ func NewQueryAllClientsParams(page, limit int) QueryAllClientsParams { } } -// QueryCommitmentRootParams defines the params for the following queries: -// - 'custom/ibc/clients//roots/' -type QueryCommitmentRootParams struct { - ClientID string - Height uint64 -} - -// NewQueryCommitmentRootParams creates a new QueryCommitmentRootParams instance -func NewQueryCommitmentRootParams(id string, height uint64) QueryCommitmentRootParams { - return QueryCommitmentRootParams{ - ClientID: id, - Height: height, - } -} - -// QueryCommitterParams defines the params for the following queries: -// - 'custom/ibc/clients//committers/' -type QueryCommitterParams struct { - ClientID string - Height uint64 -} - -// NewQueryCommitterParams creates a new QueryCommitmentRootParams instance -func NewQueryCommitterParams(id string, height uint64) QueryCommitterParams { - return QueryCommitterParams{ - ClientID: id, - Height: height, - } -} - // StateResponse defines the client response for a client state query. // It includes the commitment proof and the height of the proof. type StateResponse struct { - ClientState State `json:"client_state" yaml:"client_state"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + ClientState exported.ClientState `json:"client_state" yaml:"client_state"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewClientStateResponse creates a new StateResponse instance. func NewClientStateResponse( - clientID string, clientState State, proof *merkle.Proof, height int64, + clientID string, clientState exported.ClientState, proof *merkle.Proof, height int64, ) StateResponse { return StateResponse{ ClientState: clientState, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ClientStatePath(clientID), "/")), + ProofPath: commitment.NewPath(strings.Split(ibctypes.ClientStatePath(clientID), "/")), ProofHeight: uint64(height), } } @@ -100,62 +56,20 @@ func NewClientStateResponse( // ConsensusStateResponse defines the client response for a Consensus state query. // It includes the commitment proof and the height of the proof. type ConsensusStateResponse struct { - ConsensusState tmtypes.ConsensusState `json:"consensus_state" yaml:"consensus_state"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + ConsensusState exported.ConsensusState `json:"consensus_state" yaml:"consensus_state"` + Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewConsensusStateResponse creates a new ConsensusStateResponse instance. func NewConsensusStateResponse( - clientID string, cs tmtypes.ConsensusState, proof *merkle.Proof, height int64, + clientID string, cs exported.ConsensusState, proof *merkle.Proof, height int64, ) ConsensusStateResponse { return ConsensusStateResponse{ ConsensusState: cs, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ConsensusStatePath(clientID), "/")), + ProofPath: commitment.NewPath(strings.Split(ibctypes.ConsensusStatePath(clientID, uint64(height)), "/")), ProofHeight: uint64(height), } } - -// RootResponse defines the client response for a commitment root query. -// It includes the commitment proof and the height of the proof. -type RootResponse struct { - Root commitment.Root `json:"root" yaml:"root"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` -} - -// NewRootResponse creates a new RootResponse instance. -func NewRootResponse( - clientID string, height uint64, root commitment.Root, proof *merkle.Proof, proofHeight int64, -) RootResponse { - return RootResponse{ - Root: root, - Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(RootPath(clientID, height), "/")), - ProofHeight: uint64(proofHeight), - } -} - -// CommitterResponse defines the client response for a committer query -// It includes the commitment proof and the height of the proof -type CommitterResponse struct { - Committer tmtypes.Committer `json:"committer" yaml:"committer"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` -} - -// NewCommitterResponse creates a new CommitterResponse instance. -func NewCommitterResponse( - clientID string, height uint64, committer tmtypes.Committer, proof *merkle.Proof, proofHeight int64, -) CommitterResponse { - return CommitterResponse{ - Committer: committer, - Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(CommitterPath(clientID, height), "/")), - ProofHeight: uint64(proofHeight), - } -} diff --git a/x/ibc/02-client/types/state.go b/x/ibc/02-client/types/state.go deleted file mode 100644 index 6ae3d0552693..000000000000 --- a/x/ibc/02-client/types/state.go +++ /dev/null @@ -1,19 +0,0 @@ -package types - -// State is a type that represents the state of a client. -// Any actor holding the Stage can access on and modify that client information. -type State struct { - // Client ID - ID string `json:"id" yaml:"id"` - // Boolean that states if the client is frozen when a misbehaviour proof is - // submitted in the event of an equivocation. - Frozen bool `json:"frozen" yaml:"frozen"` -} - -// NewClientState creates a new ClientState instance -func NewClientState(id string) State { - return State{ - ID: id, - Frozen: false, - } -} diff --git a/x/ibc/02-client/types/tendermint/committer.go b/x/ibc/02-client/types/tendermint/committer.go deleted file mode 100644 index ccf798feb570..000000000000 --- a/x/ibc/02-client/types/tendermint/committer.go +++ /dev/null @@ -1,26 +0,0 @@ -package tendermint - -import ( - tmtypes "github.com/tendermint/tendermint/types" - - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" -) - -var _ exported.Committer = Committer{} - -// Committer definites a Tendermint Committer -type Committer struct { - *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` - Height uint64 `json:"height" yaml:"height"` - NextValSetHash []byte `json:"next_valset_hash" yaml:"next_valset_hash"` -} - -// Implement exported.Committer interface -func (c Committer) ClientType() exported.ClientType { - return exported.Tendermint -} - -// Implement exported.Committer interface -func (c Committer) GetHeight() uint64 { - return c.Height -} diff --git a/x/ibc/02-client/types/tendermint/consensus_state.go b/x/ibc/02-client/types/tendermint/consensus_state.go deleted file mode 100644 index cb7e2e42e849..000000000000 --- a/x/ibc/02-client/types/tendermint/consensus_state.go +++ /dev/null @@ -1,111 +0,0 @@ -package tendermint - -import ( - "bytes" - "fmt" - - lerr "github.com/tendermint/tendermint/lite/errors" - tmtypes "github.com/tendermint/tendermint/types" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - clienterrors "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" -) - -var _ exported.ConsensusState = ConsensusState{} - -// ConsensusState defines a Tendermint consensus state -type ConsensusState struct { - ChainID string `json:"chain_id" yaml:"chain_id"` - Height uint64 `json:"height" yaml:"height"` // NOTE: defined as 'sequence' in the spec - Root commitment.RootI `json:"root" yaml:"root"` - ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` - NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` // contains the PublicKey -} - -// ClientType returns Tendermint -func (ConsensusState) ClientType() exported.ClientType { - return exported.Tendermint -} - -// GetHeight returns the ConsensusState height -func (cs ConsensusState) GetHeight() uint64 { - return cs.Height -} - -// GetRoot returns the commitment Root for the specific -func (cs ConsensusState) GetRoot() commitment.RootI { - return cs.Root -} - -// GetCommitter returns the commmitter that committed the ConsensusState -func (cs ConsensusState) GetCommitter() exported.Committer { - return Committer{ - ValidatorSet: cs.ValidatorSet, - Height: cs.Height, - NextValSetHash: cs.NextValidatorSet.Hash(), - } -} - -// CheckValidityAndUpdateState checks if the provided header is valid and updates -// the consensus state if appropriate -func (cs ConsensusState) CheckValidityAndUpdateState(header exported.Header) (exported.ConsensusState, error) { - tmHeader, ok := header.(Header) - if !ok { - return nil, sdkerrors.Wrap( - clienterrors.ErrInvalidHeader, "header is not from Tendermint", - ) - } - - if err := cs.checkValidity(tmHeader); err != nil { - return nil, err - } - - return cs.update(tmHeader), nil -} - -// checkValidity checks if the Tendermint header is valid -// -// CONTRACT: assumes header.Height > consensusState.Height -func (cs ConsensusState) checkValidity(header Header) error { - if header.GetHeight() < cs.Height { - return sdkerrors.Wrap( - clienterrors.ErrInvalidHeader, - fmt.Sprintf("header height < consensus height (%d < %d)", header.GetHeight(), cs.Height), - ) - } - - // basic consistency check - if err := header.ValidateBasic(cs.ChainID); err != nil { - return err - } - - // check if the hash from the consensus set and header - // matches - nextHash := cs.NextValidatorSet.Hash() - if cs.Height == uint64(header.Height-1) && - !bytes.Equal(nextHash, header.ValidatorsHash) { - return lerr.ErrUnexpectedValidators(nextHash, header.ValidatorsHash) - } - - // validate the next validator set hash from the header - nextHash = header.NextValidatorSet.Hash() - if !bytes.Equal(header.NextValidatorsHash, nextHash) { - return lerr.ErrUnexpectedValidators(header.NextValidatorsHash, nextHash) - } - - // abortTransactionUnless(consensusState.publicKey.verify(header.signature)) - return header.ValidatorSet.VerifyFutureCommit( - cs.NextValidatorSet, cs.ChainID, header.Commit.BlockID, header.Height, header.Commit, - ) -} - -// update the consensus state from a new header -func (cs ConsensusState) update(header Header) ConsensusState { - cs.Height = header.GetHeight() - cs.Root = commitment.NewRoot(header.AppHash) - cs.ValidatorSet = header.ValidatorSet - cs.NextValidatorSet = header.NextValidatorSet - return cs -} diff --git a/x/ibc/02-client/types/tendermint/consensus_state_test.go b/x/ibc/02-client/types/tendermint/consensus_state_test.go deleted file mode 100644 index 778de45fa3a8..000000000000 --- a/x/ibc/02-client/types/tendermint/consensus_state_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package tendermint - -import ( - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/tmhash" - tmtypes "github.com/tendermint/tendermint/types" -) - -func (suite *TendermintTestSuite) TestCheckValidity() { - // valid header - err := suite.cs.checkValidity(suite.header) - suite.NoError(err, "validity failed") - - // switch out header ValidatorsHash - suite.header.ValidatorsHash = tmhash.Sum([]byte("hello")) - err = suite.cs.checkValidity(suite.header) - suite.Error(err, "validator hash is wrong") - - // reset suite and make header.NextValidatorSet different - // from NextValidatorSetHash - suite.SetupTest() - privVal := tmtypes.NewMockPV() - val := tmtypes.NewValidator(privVal.GetPubKey(), 5) - suite.header.NextValidatorSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) - err = suite.cs.checkValidity(suite.header) - suite.Error(err, "header's next validator set is not consistent with hash") - - // reset and make header fail validatebasic - suite.SetupTest() - suite.header.ChainID = "not_gaia" - err = suite.cs.checkValidity(suite.header) - suite.Error(err, "invalid header should fail ValidateBasic") -} - -func (suite *TendermintTestSuite) TestCheckUpdate() { - // valid header should successfully update consensus state - cs, err := suite.cs.CheckValidityAndUpdateState(suite.header) - - require.Nil(suite.T(), err, "valid update failed") - require.Equal(suite.T(), suite.header.GetHeight(), cs.GetHeight(), "height not updated") - require.Equal(suite.T(), suite.header.AppHash.Bytes(), cs.GetRoot().GetHash(), "root not updated") - tmCS, _ := cs.(ConsensusState) - require.Equal(suite.T(), suite.header.ValidatorSet, tmCS.ValidatorSet, "validator set did not update") - require.Equal(suite.T(), suite.header.NextValidatorSet, tmCS.NextValidatorSet, "next validator set did not update") - - // make header invalid so update should be unsuccessful - suite.SetupTest() - suite.header.ChainID = "not_gaia" - - cs, err = suite.cs.CheckValidityAndUpdateState(suite.header) - suite.Error(err) - require.Nil(suite.T(), cs) -} diff --git a/x/ibc/02-client/types/tendermint/evidence_test.go b/x/ibc/02-client/types/tendermint/evidence_test.go deleted file mode 100644 index bf5e073e3e19..000000000000 --- a/x/ibc/02-client/types/tendermint/evidence_test.go +++ /dev/null @@ -1,135 +0,0 @@ -package tendermint - -import ( - "bytes" - - "github.com/tendermint/tendermint/crypto/tmhash" - tmtypes "github.com/tendermint/tendermint/types" -) - -func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { - altPrivVal := tmtypes.NewMockPV() - altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) - - // Create bothValSet with both suite validator and altVal - bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) - // Create alternative validator set with only altVal - altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) - - signers := []tmtypes.PrivValidator{suite.privVal} - // Create signer array and ensure it is in same order as bothValSet - var bothSigners []tmtypes.PrivValidator - if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { - bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} - } else { - bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} - } - - altSigners := []tmtypes.PrivValidator{altPrivVal} - - testCases := []struct { - name string - evidence Evidence - malleateEvidence func(ev *Evidence) - expErr bool - }{ - { - "valid evidence", - Evidence{ - Header1: suite.header, - Header2: MakeHeader("gaia", 4, suite.valSet, bothValSet, signers), - ChainID: "gaia", - }, - func(ev *Evidence) {}, - false, - }, - { - "wrong chainID on header1", - Evidence{ - Header1: suite.header, - Header2: MakeHeader("ethermint", 4, suite.valSet, bothValSet, signers), - ChainID: "ethermint", - }, - func(ev *Evidence) {}, - true, - }, - { - "wrong chainID on header2", - Evidence{ - Header1: suite.header, - Header2: MakeHeader("ethermint", 4, suite.valSet, bothValSet, signers), - ChainID: "gaia", - }, - func(ev *Evidence) {}, - true, - }, - { - "mismatched heights", - Evidence{ - Header1: suite.header, - Header2: MakeHeader("gaia", 6, suite.valSet, bothValSet, signers), - ChainID: "gaia", - }, - func(ev *Evidence) {}, - true, - }, - { - "same block id", - Evidence{ - Header1: suite.header, - Header2: suite.header, - ChainID: "gaia", - }, - func(ev *Evidence) {}, - true, - }, - { - "header doesn't have 2/3 majority", - Evidence{ - Header1: suite.header, - Header2: MakeHeader("gaia", 4, bothValSet, bothValSet, bothSigners), - ChainID: "gaia", - }, - func(ev *Evidence) { - // voteSet contains only altVal which is less than 2/3 of total power (4/14) - wrongVoteSet := tmtypes.NewVoteSet("gaia", ev.Header2.Height, 1, tmtypes.PrecommitType, altValSet) - var err error - ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round, wrongVoteSet, altSigners) - if err != nil { - panic(err) - } - }, - true, - }, - { - "validators sign off on wrong commit", - Evidence{ - Header1: suite.header, - Header2: MakeHeader("gaia", 4, bothValSet, bothValSet, bothSigners), - ChainID: "gaia", - }, - func(ev *Evidence) { - ev.Header2.Commit.BlockID = makeBlockID(tmhash.Sum([]byte("other_hash")), 3, tmhash.Sum([]byte("other_partset"))) - }, - true, - }, - } - - for _, tc := range testCases { - tc := tc // pin for scopelint - suite.Run(tc.name, func() { - // reset suite for each subtest - suite.SetupTest() - - tc.malleateEvidence(&tc.evidence) - - err := tc.evidence.ValidateBasic() - - if tc.expErr { - suite.Error(err, "ValidateBasic did not throw error for invalid evidence") - } else { - suite.NoError(err, "ValidateBasic returned error on valid evidence: %s", err) - } - }) - } -} diff --git a/x/ibc/02-client/types/tendermint/header.go b/x/ibc/02-client/types/tendermint/header.go deleted file mode 100644 index 9509d6370019..000000000000 --- a/x/ibc/02-client/types/tendermint/header.go +++ /dev/null @@ -1,54 +0,0 @@ -package tendermint - -import ( - tmtypes "github.com/tendermint/tendermint/types" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - clienterrors "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" -) - -var _ exported.Header = Header{} - -// Header defines the Tendermint consensus Header -type Header struct { - tmtypes.SignedHeader - ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` - NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` -} - -// ClientType defines that the Header is a Tendermint consensus algorithm -func (h Header) ClientType() exported.ClientType { - return exported.Tendermint -} - -// GetCommitter returns the ValidatorSet that committed header -func (h Header) GetCommitter() exported.Committer { - return Committer{ - ValidatorSet: h.ValidatorSet, - Height: uint64(h.Height), - NextValSetHash: h.NextValidatorsHash, - } -} - -// GetHeight returns the current height -// -// NOTE: also referred as `sequence` -func (h Header) GetHeight() uint64 { - return uint64(h.Height) -} - -// ValidateBasic calls the SignedHeader ValidateBasic function -// and checks that validatorsets are not nil -func (h Header) ValidateBasic(chainID string) error { - if err := h.SignedHeader.ValidateBasic(chainID); err != nil { - return sdkerrors.Wrap(clienterrors.ErrInvalidHeader, err.Error()) - } - if h.ValidatorSet == nil { - return sdkerrors.Wrap(clienterrors.ErrInvalidHeader, "validator set is nil") - } - if h.NextValidatorSet == nil { - return sdkerrors.Wrap(clienterrors.ErrInvalidHeader, "next validator set is nil") - } - return nil -} diff --git a/x/ibc/02-client/types/tendermint/misbehaviour.go b/x/ibc/02-client/types/tendermint/misbehaviour.go deleted file mode 100644 index 36c8e14ce8ab..000000000000 --- a/x/ibc/02-client/types/tendermint/misbehaviour.go +++ /dev/null @@ -1,71 +0,0 @@ -package tendermint - -import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" - host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" -) - -var _ exported.Misbehaviour = Misbehaviour{} -var _ evidenceexported.Evidence = Misbehaviour{} - -// Misbehaviour contains evidence that a light client submitted a different header from -// a full node at the same height. -type Misbehaviour struct { - *Evidence - ClientID string `json:"client_id" yaml:"client_id"` -} - -// ClientType is Tendermint light client -func (m Misbehaviour) ClientType() exported.ClientType { - return exported.Tendermint -} - -// GetEvidence returns the evidence to handle a light client misbehaviour -func (m Misbehaviour) GetEvidence() evidenceexported.Evidence { - return m.Evidence -} - -// ValidateBasic performs the basic validity checks for the evidence and the -// client ID. -func (m Misbehaviour) ValidateBasic() error { - if m.Evidence == nil { - return sdkerrors.Wrap(errors.ErrInvalidEvidence, "evidence is empty") - } - if err := m.Evidence.ValidateBasic(); err != nil { - return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) - } - if err := host.DefaultClientIdentifierValidator(m.ClientID); err != nil { - return sdkerrors.Wrap(errors.ErrInvalidEvidence, err.Error()) - } - return nil -} - -// CheckMisbehaviour checks if the evidence provided is a valid light client misbehaviour -func CheckMisbehaviour(trustedCommitter Committer, m Misbehaviour) error { - if err := m.ValidateBasic(); err != nil { - return err - } - - trustedValSet := trustedCommitter.ValidatorSet - - // Evidence is within trusting period. ValidatorSet must have 2/3 similarity with trustedCommitter ValidatorSet - // check that the validator sets on both headers are valid given the last trusted validatorset - // less than or equal to evidence height - if err := trustedValSet.VerifyFutureCommit( - m.Evidence.Header1.ValidatorSet, m.Evidence.ChainID, - m.Evidence.Header1.Commit.BlockID, m.Evidence.Header1.Height, m.Evidence.Header1.Commit, - ); err != nil { - return sdkerrors.Wrapf(errors.ErrInvalidEvidence, "validator set in header 1 has too much change from last known committer: %v", err) - } - if err := trustedValSet.VerifyFutureCommit( - m.Evidence.Header2.ValidatorSet, m.Evidence.ChainID, - m.Evidence.Header2.Commit.BlockID, m.Evidence.Header2.Height, m.Evidence.Header2.Commit, - ); err != nil { - return sdkerrors.Wrapf(errors.ErrInvalidEvidence, "validator set in header 2 has too much change from last known committer: %v", err) - } - - return nil -} diff --git a/x/ibc/02-client/types/tendermint/misbehaviour_test.go b/x/ibc/02-client/types/tendermint/misbehaviour_test.go deleted file mode 100644 index f69a6d12884e..000000000000 --- a/x/ibc/02-client/types/tendermint/misbehaviour_test.go +++ /dev/null @@ -1,170 +0,0 @@ -package tendermint - -import ( - "bytes" - - tmtypes "github.com/tendermint/tendermint/types" -) - -func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { - altPrivVal := tmtypes.NewMockPV() - altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) - - // Create bothValSet with both suite validator and altVal - bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) - - signers := []tmtypes.PrivValidator{suite.privVal} - testCases := []struct { - name string - evidence *Evidence - clientID string - expErr bool - }{ - { - "valid misbehavior", - &Evidence{ - Header1: suite.header, - Header2: MakeHeader("gaia", 4, suite.valSet, bothValSet, signers), - ChainID: "gaia", - }, - "gaiamainnet", - false, - }, - { - "nil evidence", - nil, - "gaiamainnet", - true, - }, - { - "invalid evidence", - &Evidence{ - Header1: suite.header, - Header2: suite.header, - ChainID: "gaia", - }, - "gaiamainnet", - true, - }, - { - "invalid ClientID", - &Evidence{ - Header1: MakeHeader("gaia123??", 5, suite.valSet, suite.valSet, signers), - Header2: MakeHeader("gaia123?", 5, suite.valSet, suite.valSet, signers), - ChainID: "gaia123?", - }, - "gaia123?", - true, - }, - } - - for _, tc := range testCases { - tc := tc // pin for scopelint - suite.Run(tc.name, func() { - misbehaviour := Misbehaviour{ - Evidence: tc.evidence, - ClientID: tc.clientID, - } - - err := misbehaviour.ValidateBasic() - - if tc.expErr { - suite.Error(err, "Invalid Misbehaviour passed ValidateBasic") - } else { - suite.NoError(err, "Valid Misbehaviour failed ValidateBasic: %v", err) - } - }) - } -} - -func (suite *TendermintTestSuite) TestCheckMisbehaviour() { - altPrivVal := tmtypes.NewMockPV() - altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) - - // Create bothValSet with both suite validator and altVal - bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) - // Create alternative validator set with only altVal - altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) - - // Create signer array and ensure it is in same order as bothValSet - var bothSigners []tmtypes.PrivValidator - if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { - bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} - } else { - bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} - } - - altSigners := []tmtypes.PrivValidator{altPrivVal} - - committer := Committer{ - ValidatorSet: suite.valSet, - Height: 3, - NextValSetHash: suite.valSet.Hash(), - } - - testCases := []struct { - name string - evidence *Evidence - clientID string - expErr bool - }{ - { - "trusting period misbehavior should pass", - &Evidence{ - Header1: MakeHeader("gaia", 5, bothValSet, suite.valSet, bothSigners), - Header2: MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), - ChainID: "gaia", - }, - "gaiamainnet", - false, - }, - { - "first valset has too much change", - &Evidence{ - Header1: MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), - Header2: MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), - ChainID: "gaia", - }, - "gaiamainnet", - true, - }, - { - "second valset has too much change", - &Evidence{ - Header1: MakeHeader("gaia", 5, bothValSet, bothValSet, bothSigners), - Header2: MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), - ChainID: "gaia", - }, - "gaiamainnet", - true, - }, - { - "both valsets have too much change", - &Evidence{ - Header1: MakeHeader("gaia", 5, altValSet, altValSet, altSigners), - Header2: MakeHeader("gaia", 5, altValSet, bothValSet, altSigners), - ChainID: "gaia", - }, - "gaiamainnet", - true, - }, - } - - for _, tc := range testCases { - tc := tc // pin for scopelint - suite.Run(tc.name, func() { - misbehaviour := Misbehaviour{ - Evidence: tc.evidence, - ClientID: tc.clientID, - } - - err := CheckMisbehaviour(committer, misbehaviour) - - if tc.expErr { - suite.Error(err, "CheckMisbehaviour passed unexpectedly") - } else { - suite.NoError(err, "CheckMisbehaviour failed unexpectedly: %v", err) - } - }) - } -} diff --git a/x/ibc/02-client/types/tendermint/tendermint_test.go b/x/ibc/02-client/types/tendermint/tendermint_test.go deleted file mode 100644 index 7f8b8e0e863c..000000000000 --- a/x/ibc/02-client/types/tendermint/tendermint_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package tendermint - -import ( - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/tendermint/tendermint/crypto/tmhash" - tmtypes "github.com/tendermint/tendermint/types" - - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" -) - -type TendermintTestSuite struct { - suite.Suite - - privVal tmtypes.PrivValidator - valSet *tmtypes.ValidatorSet - header Header - cs ConsensusState -} - -func (suite *TendermintTestSuite) SetupTest() { - privVal := tmtypes.NewMockPV() - val := tmtypes.NewValidator(privVal.GetPubKey(), 10) - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) - suite.header = MakeHeader("gaia", 4, valSet, valSet, []tmtypes.PrivValidator{privVal}) - root := commitment.NewRoot(tmhash.Sum([]byte("my root"))) - - cs := ConsensusState{ - ChainID: "gaia", - Height: 3, - Root: root, - ValidatorSet: valSet, - NextValidatorSet: valSet, - } - - // set fields in suite - suite.privVal = privVal - suite.valSet = valSet - suite.cs = cs -} - -func TestTendermintTestSuite(t *testing.T) { - suite.Run(t, new(TendermintTestSuite)) -} diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index 2cb4faf887ff..fcd7293ea6a6 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -12,14 +12,6 @@ import ( ) const ( - UNINITIALIZED = types.UNINITIALIZED - INIT = types.INIT - TRYOPEN = types.TRYOPEN - OPEN = types.OPEN - StateUninitialized = types.StateUninitialized - StateInit = types.StateInit - StateTryOpen = types.StateTryOpen - StateOpen = types.StateOpen AttributeKeyConnectionID = types.AttributeKeyConnectionID AttributeKeyCounterpartyClientID = types.AttributeKeyCounterpartyClientID SubModuleName = types.SubModuleName @@ -27,7 +19,6 @@ const ( RouterKey = types.RouterKey QuerierRoute = types.QuerierRoute QueryAllConnections = types.QueryAllConnections - QueryConnection = types.QueryConnection QueryClientConnections = types.QueryClientConnections ) @@ -35,28 +26,21 @@ var ( // functions aliases NewKeeper = keeper.NewKeeper QuerierConnections = keeper.QuerierConnections - QuerierConnection = keeper.QuerierConnection QuerierClientConnections = keeper.QuerierClientConnections RegisterCodec = types.RegisterCodec NewConnectionEnd = types.NewConnectionEnd NewCounterparty = types.NewCounterparty - StateFromString = types.StateFromString ErrConnectionExists = types.ErrConnectionExists ErrConnectionNotFound = types.ErrConnectionNotFound ErrClientConnectionPathsNotFound = types.ErrClientConnectionPathsNotFound ErrConnectionPath = types.ErrConnectionPath ErrInvalidConnectionState = types.ErrInvalidConnectionState ErrInvalidCounterparty = types.ErrInvalidCounterparty - ConnectionPath = types.ConnectionPath - ClientConnectionsPath = types.ClientConnectionsPath - KeyConnection = types.KeyConnection - KeyClientConnections = types.KeyClientConnections NewMsgConnectionOpenInit = types.NewMsgConnectionOpenInit NewMsgConnectionOpenTry = types.NewMsgConnectionOpenTry NewMsgConnectionOpenAck = types.NewMsgConnectionOpenAck NewMsgConnectionOpenConfirm = types.NewMsgConnectionOpenConfirm NewConnectionResponse = types.NewConnectionResponse - NewQueryConnectionParams = types.NewQueryConnectionParams NewClientConnectionsResponse = types.NewClientConnectionsResponse NewQueryClientConnectionsParams = types.NewQueryClientConnectionsParams GetCompatibleVersions = types.GetCompatibleVersions @@ -76,14 +60,12 @@ type ( Keeper = keeper.Keeper ConnectionEnd = types.ConnectionEnd Counterparty = types.Counterparty - State = types.State ClientKeeper = types.ClientKeeper MsgConnectionOpenInit = types.MsgConnectionOpenInit MsgConnectionOpenTry = types.MsgConnectionOpenTry MsgConnectionOpenAck = types.MsgConnectionOpenAck MsgConnectionOpenConfirm = types.MsgConnectionOpenConfirm ConnectionResponse = types.ConnectionResponse - QueryConnectionParams = types.QueryConnectionParams ClientConnectionsResponse = types.ClientConnectionsResponse QueryClientConnectionsParams = types.QueryClientConnectionsParams ) diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index cf54b6e785ff..5ce3a6e65baa 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -217,9 +217,13 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] } proofHeight := uint64(cliCtx.Height) + consensusHeight, err := lastHeight(cliCtx) + if err != nil { + return err + } msg := types.NewMsgConnectionOpenConfirm( - connectionID, proofAck, proofHeight, cliCtx.GetFromAddress(), + connectionID, proofAck, proofHeight, consensusHeight, cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { diff --git a/x/ibc/03-connection/client/rest/rest.go b/x/ibc/03-connection/client/rest/rest.go index ed8e97b69280..7e74109b23b6 100644 --- a/x/ibc/03-connection/client/rest/rest.go +++ b/x/ibc/03-connection/client/rest/rest.go @@ -56,7 +56,8 @@ type ConnectionOpenAckReq struct { // ConnectionOpenConfirmReq defines the properties of a connection open confirm request's body. type ConnectionOpenConfirmReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` } diff --git a/x/ibc/03-connection/client/rest/tx.go b/x/ibc/03-connection/client/rest/tx.go index f11abbccb111..095a8e77a260 100644 --- a/x/ibc/03-connection/client/rest/tx.go +++ b/x/ibc/03-connection/client/rest/tx.go @@ -191,7 +191,7 @@ func connectionOpenConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc // create the message msg := types.NewMsgConnectionOpenConfirm( - connectionID, req.ProofAck, req.ProofHeight, fromAddr, + connectionID, req.ProofAck, req.ProofHeight, req.ConsensusHeight, fromAddr, ) if err := msg.ValidateBasic(); err != nil { diff --git a/x/ibc/03-connection/client/utils/utils.go b/x/ibc/03-connection/client/utils/utils.go index 55dcdcbff49e..29c52a33be9a 100644 --- a/x/ibc/03-connection/client/utils/utils.go +++ b/x/ibc/03-connection/client/utils/utils.go @@ -12,6 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // QueryAllConnections returns all the connections. It _does not_ return @@ -44,7 +45,7 @@ func QueryConnection( ) (types.ConnectionResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", - Data: types.KeyConnection(connectionID), + Data: ibctypes.KeyConnection(connectionID), Prove: prove, } @@ -70,7 +71,7 @@ func QueryClientConnections( ) (types.ClientConnectionsResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", - Data: types.KeyClientConnections(clientID), + Data: ibctypes.KeyClientConnections(clientID), Prove: prove, } diff --git a/x/ibc/03-connection/exported/exported.go b/x/ibc/03-connection/exported/exported.go new file mode 100644 index 000000000000..a45570c80130 --- /dev/null +++ b/x/ibc/03-connection/exported/exported.go @@ -0,0 +1,89 @@ +package exported + +import ( + "encoding/json" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// ConnectionI describes the required methods for a connection. +type ConnectionI interface { + GetState() State + GetClientID() string + GetCounterparty() CounterpartyI + GetVersions() []string + ValidateBasic() error +} + +// CounterpartyI describes the required methods for a counterparty connection. +type CounterpartyI interface { + GetClientID() string + GetConnectionID() string + GetPrefix() commitment.PrefixI + ValidateBasic() error +} + +// State defines the state of a connection between two disctinct +// chains +type State byte + +// available connection states +const ( + UNINITIALIZED State = iota // default State + INIT + TRYOPEN + OPEN +) + +// string representation of the connection states +const ( + StateUninitialized string = "UNINITIALIZED" + StateInit string = "INIT" + StateTryOpen string = "TRYOPEN" + StateOpen string = "OPEN" +) + +// String implements the Stringer interface +func (s State) String() string { + switch s { + case INIT: + return StateInit + case TRYOPEN: + return StateTryOpen + case OPEN: + return StateOpen + default: + return StateUninitialized + } +} + +// StateFromString parses a string into a connection state +func StateFromString(state string) State { + switch state { + case StateInit: + return INIT + case StateTryOpen: + return TRYOPEN + case StateOpen: + return OPEN + default: + return UNINITIALIZED + } +} + +// MarshalJSON marshal to JSON using string. +func (s State) MarshalJSON() ([]byte, error) { + return json.Marshal(s.String()) +} + +// UnmarshalJSON decodes from JSON assuming Bech32 encoding. +func (s *State) UnmarshalJSON(data []byte) error { + var str string + err := json.Unmarshal(data, &str) + if err != nil { + return err + } + + *s = StateFromString(str) + return nil +} diff --git a/x/ibc/03-connection/exported/exported_test.go b/x/ibc/03-connection/exported/exported_test.go new file mode 100644 index 000000000000..c45dfe6cca2b --- /dev/null +++ b/x/ibc/03-connection/exported/exported_test.go @@ -0,0 +1,46 @@ +package exported + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestConnectionStateString(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.state, StateFromString(tt.name)) + require.Equal(t, tt.name, tt.state.String()) + } +} + +func TestConnectionlStateMarshalJSON(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.state.MarshalJSON() + require.NoError(t, err) + var state State + require.NoError(t, state.UnmarshalJSON(bz)) + require.Equal(t, tt.name, state.String()) + } +} diff --git a/x/ibc/03-connection/handler.go b/x/ibc/03-connection/handler.go index b7c9eae08d3f..1c1e90ed6e55 100644 --- a/x/ibc/03-connection/handler.go +++ b/x/ibc/03-connection/handler.go @@ -2,12 +2,10 @@ package connection import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/keeper" - "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) // HandleMsgConnectionOpenInit defines the sdk.Handler for MsgConnectionOpenInit -func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenInit) (*sdk.Result, error) { +func HandleMsgConnectionOpenInit(ctx sdk.Context, k Keeper, msg MsgConnectionOpenInit) (*sdk.Result, error) { err := k.ConnOpenInit(ctx, msg.ConnectionID, msg.ClientID, msg.Counterparty) if err != nil { return nil, err @@ -15,13 +13,13 @@ func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.Msg ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( - types.EventTypeConnectionOpenInit, - sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), - sdk.NewAttribute(types.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), + EventTypeConnectionOpenInit, + sdk.NewAttribute(AttributeKeyConnectionID, msg.ConnectionID), + sdk.NewAttribute(AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), ), sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), ), }) @@ -32,7 +30,7 @@ func HandleMsgConnectionOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.Msg } // HandleMsgConnectionOpenTry defines the sdk.Handler for MsgConnectionOpenTry -func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenTry) (*sdk.Result, error) { +func HandleMsgConnectionOpenTry(ctx sdk.Context, k Keeper, msg MsgConnectionOpenTry) (*sdk.Result, error) { err := k.ConnOpenTry( ctx, msg.ConnectionID, msg.Counterparty, msg.ClientID, msg.CounterpartyVersions, msg.ProofInit, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight) @@ -42,13 +40,13 @@ func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgC ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( - types.EventTypeConnectionOpenTry, - sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), - sdk.NewAttribute(types.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), + EventTypeConnectionOpenTry, + sdk.NewAttribute(AttributeKeyConnectionID, msg.ConnectionID), + sdk.NewAttribute(AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), ), sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), ), }) @@ -59,7 +57,7 @@ func HandleMsgConnectionOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgC } // HandleMsgConnectionOpenAck defines the sdk.Handler for MsgConnectionOpenAck -func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenAck) (*sdk.Result, error) { +func HandleMsgConnectionOpenAck(ctx sdk.Context, k Keeper, msg MsgConnectionOpenAck) (*sdk.Result, error) { err := k.ConnOpenAck( ctx, msg.ConnectionID, msg.Version, msg.ProofTry, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight, @@ -70,12 +68,12 @@ func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgC ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( - types.EventTypeConnectionOpenAck, - sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + EventTypeConnectionOpenAck, + sdk.NewAttribute(AttributeKeyConnectionID, msg.ConnectionID), ), sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), ), }) @@ -86,20 +84,20 @@ func HandleMsgConnectionOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgC } // HandleMsgConnectionOpenConfirm defines the sdk.Handler for MsgConnectionOpenConfirm -func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgConnectionOpenConfirm) (*sdk.Result, error) { - err := k.ConnOpenConfirm(ctx, msg.ConnectionID, msg.ProofAck, msg.ProofHeight) +func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k Keeper, msg MsgConnectionOpenConfirm) (*sdk.Result, error) { + err := k.ConnOpenConfirm(ctx, msg.ConnectionID, msg.ProofAck, msg.ProofHeight, msg.ConsensusHeight) if err != nil { return nil, err } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( - types.EventTypeConnectionOpenConfirm, - sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + EventTypeConnectionOpenConfirm, + sdk.NewAttribute(AttributeKeyConnectionID, msg.ConnectionID), ), sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), ), }) diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index 8a40c427de52..f8eaf98db5c3 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -1,11 +1,13 @@ package keeper import ( - "errors" + "bytes" "fmt" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -26,11 +28,10 @@ func (k Keeper) ConnOpenInit( } // connection defines chain A's ConnectionEnd - connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.GetCompatibleVersions()) + connection := types.NewConnectionEnd(exported.INIT, clientID, counterparty, types.GetCompatibleVersions()) k.SetConnection(ctx, connectionID, connection) - err := k.addConnectionToClient(ctx, clientID, connectionID) - if err != nil { + if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { return sdkerrors.Wrap(err, "cannot initialize connection") } @@ -55,69 +56,55 @@ func (k Keeper) ConnOpenTry( proofHeight uint64, consensusHeight uint64, ) error { - // XXX: blocked by #5078 - /* - if consensusHeight > uint64(ctx.BlockHeight()) { - return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") - } + // XXX: blocked by #5475 + // if consensusHeight > uint64(ctx.BlockHeight()) { + // return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") + // } - expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, clientID) - if !found { - return errors.New("client consensus state not found") // TODO: use ICS02 error - } - */ + expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, clientID, consensusHeight) + if !found { + return clienttypes.ErrConsensusStateNotFound + } - // expectedConn defines Chain A's ConnectionEnd + // expectedConnection defines Chain A's ConnectionEnd // NOTE: chain A's counterparty is chain B (i.e where this code is executed) prefix := k.GetCommitmentPrefix() expectedCounterparty := types.NewCounterparty(clientID, connectionID, prefix) - expectedConn := types.NewConnectionEnd(types.INIT, counterparty.ClientID, expectedCounterparty, counterpartyVersions) + expectedConnection := types.NewConnectionEnd(exported.INIT, counterparty.ClientID, expectedCounterparty, counterpartyVersions) // chain B picks a version from Chain A's available versions that is compatible // with the supported IBC versions version := types.PickVersion(counterpartyVersions, types.GetCompatibleVersions()) // connection defines chain B's ConnectionEnd - connection := types.NewConnectionEnd(types.UNINITIALIZED, clientID, counterparty, []string{version}) - expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) - if err != nil { + connection := types.NewConnectionEnd(exported.UNINITIALIZED, clientID, counterparty, []string{version}) + + if err := k.VerifyConnectionState( + ctx, proofHeight, proofInit, counterparty.ConnectionID, + expectedConnection, expectedConsensusState, + ); err != nil { return err } - ok := k.VerifyMembership( - ctx, connection, proofHeight, proofInit, - types.ConnectionPath(counterparty.ConnectionID), expConnBz, - ) - if !ok { - return errors.New("couldn't verify connection membership on counterparty's client") // TODO: sdk.Error + // XXX: blocked by #5475 + // if err := k.VerifyClientConsensusState( + // ctx, proofHeight, proofInit, expectedConsensusState, + // ); err != nil { + // return err + // } + + previousConnection, found := k.GetConnection(ctx, connectionID) + if found && !(previousConnection.State == exported.INIT && + previousConnection.Counterparty.ConnectionID == counterparty.ConnectionID && + bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) && + previousConnection.ClientID == clientID && + previousConnection.Counterparty.ClientID == counterparty.ClientID && + previousConnection.Versions[0] == version) { + return sdkerrors.Wrap(types.ErrInvalidConnection, "cannot relay connection attempt") } - // XXX: blocked by #5078 - /* - expConsStateBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConsensusState) - if err != nil { - return err - } - - ok = k.VerifyMembership( - ctx, connection, proofHeight, proofConsensus, - clienttypes.ConsensusStatePath(counterparty.ClientID), expConsStateBz, - ) - if !ok { - fmt.Sprintf("couldn't verify consensus state membership on counterparty's client\n") - return errors.New("couldn't verify consensus state membership on counterparty's client") // TODO: sdk.Error - } - - */ - - _, found := k.GetConnection(ctx, connectionID) - if found { - return sdkerrors.Wrap(types.ErrConnectionExists, "cannot relay connection attempt") - } - - connection.State = types.TRYOPEN - err = k.addConnectionToClient(ctx, clientID, connectionID) - if err != nil { + connection.State = exported.TRYOPEN + if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { return sdkerrors.Wrap(err, "cannot relay connection attempt") } @@ -139,18 +126,17 @@ func (k Keeper) ConnOpenAck( proofHeight uint64, consensusHeight uint64, ) error { - // XXX: blocked by #5078 - /* - if consensusHeight > uint64(ctx.BlockHeight()) { - return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") - } - */ + // XXX: blocked by #5475 + // if consensusHeight > uint64(ctx.BlockHeight()) { + // return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") + // } + connection, found := k.GetConnection(ctx, connectionID) if !found { return sdkerrors.Wrap(types.ErrConnectionNotFound, "cannot relay ACK of open attempt") } - if connection.State != types.INIT { + if connection.State != exported.INIT { return sdkerrors.Wrapf( types.ErrInvalidConnectionState, "connection state is not INIT (got %s)", connection.State.String(), @@ -164,47 +150,30 @@ func (k Keeper) ConnOpenAck( ) } - // XXX: blocked by #5078 - /* - expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, connection.ClientID) - if !found { - return errors.New("client consensus state not found") // TODO: use ICS02 error - } - */ + expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, connection.ClientID, consensusHeight) + if !found { + return clienttypes.ErrConsensusStateNotFound + } + prefix := k.GetCommitmentPrefix() expectedCounterparty := types.NewCounterparty(connection.ClientID, connectionID, prefix) - expectedConn := types.NewConnectionEnd(types.TRYOPEN, connection.Counterparty.ClientID, expectedCounterparty, []string{version}) + expectedConnection := types.NewConnectionEnd(exported.TRYOPEN, connection.Counterparty.ClientID, expectedCounterparty, []string{version}) - expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) - if err != nil { + if err := k.VerifyConnectionState( + ctx, proofHeight, proofTry, connection.Counterparty.ConnectionID, + expectedConnection, expectedConsensusState, + ); err != nil { return err } - ok := k.VerifyMembership( - ctx, connection, proofHeight, proofTry, - types.ConnectionPath(connection.Counterparty.ConnectionID), expConnBz, - ) - if !ok { - return errors.New("couldn't verify connection membership on counterparty's client") // TODO: sdk.Error - } - - // XXX: blocked by #5078 - /* - expConsStateBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConsensusState) - if err != nil { - return err - } + // XXX: blocked by #5475 + // if err := k.VerifyClientConsensusState( + // ctx, connection, proofHeight, proofInit, expectedConsensusState, + // ); err != nil { + // return err + // } - ok = k.VerifyMembership( - ctx, connection, proofHeight, proofConsensus, - clienttypes.ConsensusStatePath(connection.Counterparty.ClientID), expConsStateBz, - ) - if !ok { - return errors.New("couldn't verify consensus state membership on counterparty's client") // TODO: sdk.Error - } - - */ - connection.State = types.OPEN + connection.State = exported.OPEN connection.Versions = []string{version} k.SetConnection(ctx, connectionID, connection) k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: INIT -> OPEN ", connectionID)) @@ -219,38 +188,38 @@ func (k Keeper) ConnOpenConfirm( ctx sdk.Context, connectionID string, proofAck commitment.ProofI, - proofHeight uint64, + proofHeight, + consensusHeight uint64, ) error { connection, found := k.GetConnection(ctx, connectionID) if !found { return sdkerrors.Wrap(types.ErrConnectionNotFound, "cannot relay ACK of open attempt") } - if connection.State != types.TRYOPEN { + if connection.State != exported.TRYOPEN { return sdkerrors.Wrapf( types.ErrInvalidConnectionState, "connection state is not TRYOPEN (got %s)", connection.State.String(), ) } + expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, connection.ClientID, consensusHeight) + if !found { + return clienttypes.ErrConsensusStateNotFound + } + prefix := k.GetCommitmentPrefix() expectedCounterparty := types.NewCounterparty(connection.ClientID, connectionID, prefix) - expectedConn := types.NewConnectionEnd(types.OPEN, connection.Counterparty.ClientID, expectedCounterparty, connection.Versions) + expectedConnection := types.NewConnectionEnd(exported.OPEN, connection.Counterparty.ClientID, expectedCounterparty, connection.Versions) - expConnBz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedConn) - if err != nil { + if err := k.VerifyConnectionState( + ctx, proofHeight, proofAck, connection.Counterparty.ConnectionID, + expectedConnection, expectedConsensusState, + ); err != nil { return err } - ok := k.VerifyMembership( - ctx, connection, proofHeight, proofAck, - types.ConnectionPath(connection.Counterparty.ConnectionID), expConnBz, - ) - if !ok { - return errors.New("couldn't verify connection membership on counterparty's client") - } - - connection.State = types.OPEN + connection.State = exported.OPEN k.SetConnection(ctx, connectionID, connection) k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: TRYOPEN -> OPEN ", connectionID)) return nil diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index 52c53df884d5..69eb1335235e 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -3,312 +3,252 @@ package keeper_test import ( "fmt" - abci "github.com/tendermint/tendermint/abci/types" - - client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" ) +// TestConnOpenInit - Chain A (ID #1) initializes (INIT state) a connection with +// Chain B (ID #2) which is yet UNINITIALIZED func (suite *KeeperTestSuite) TestConnOpenInit() { - suite.createClient(testClientID1) - counterparty := connection.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - - success := func() error { - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty) - - conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) - suite.True(existed) - - expectConn := connection.ConnectionEnd{ - State: connection.INIT, - ClientID: testClientID1, - Counterparty: counterparty, - Versions: connection.GetCompatibleVersions(), - } - suite.EqualValues(expectConn, conn) - - return err + testCases := []testCase{ + {"success", func() { + suite.createClient(testClientID1) + }, true}, + {"connection already exists", func() { + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + }, false}, + {"couldn't add connection to client", func() {}, false}, } - connectionExists := func() error { - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty) - return err - } + counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - var testCases = []TestCase{ - {success, true, ""}, - {connectionExists, false, "connection already exists"}, - } + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty) - for _, tc := range testCases { - suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) } } +// TestConnOpenTry - Chain B (ID #2) calls ConnOpenTry to verify the state of +// connection on Chain A (ID #1) is INIT func (suite *KeeperTestSuite) TestConnOpenTry() { - suite.createClient(testClientID2) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) - - connectionKey := connection.KeyConnection(testConnectionID2) - consensusKey := client.KeyConsensusState(testClientID2) - - invalidProof := func() error { - proofInit, proofHeight := suite.queryProof(connectionKey) - proofConsensus, consensusHeight := suite.queryProof(consensusKey) - - counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx, - testConnectionID1, counterparty, testClientID1, - connection.GetCompatibleVersions(), - proofInit, proofConsensus, - uint64(proofHeight), uint64(consensusHeight)) - return err - } - - success := func() error { - suite.updateClient(testClientID1) - proofInit, proofHeight := suite.queryProof(connectionKey) - proofConsensus, consensusHeight := suite.queryProof(consensusKey) - - counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx, - testConnectionID1, counterparty, testClientID1, - connection.GetCompatibleVersions(), - proofInit, proofConsensus, - uint64(proofHeight), uint64(consensusHeight)) - suite.NoError(err) - - //check connection state - conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) - suite.True(existed) - suite.Equal(connection.TRYOPEN.String(), conn.State.String(), "invalid connection state") - return err - } - - connectionExists := func() error { - suite.updateClient(testClientID1) - proofInit, proofHeight := suite.queryProof(connectionKey) - proofConsensus, consensusHeight := suite.queryProof(consensusKey) - - counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx, - testConnectionID1, counterparty, testClientID1, - connection.GetCompatibleVersions(), - proofInit, proofConsensus, - uint64(proofHeight), uint64(consensusHeight)) - return err - } - - var testCases = []TestCase{ - {invalidProof, false, "invalid proof"}, - {success, true, ""}, - {connectionExists, false, "connection already exists"}, + counterparty := connection.NewCounterparty( + testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + ) + + consensusHeight := int64(0) + + testCases := []testCase{ + {"success", func() { + suite.createClient(testClientID1) // height = 2 + suite.createClient(testClientID2) + consensusHeight = suite.ctx.BlockHeight() // height = 3 + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.updateClient(testClientID1) + suite.updateClient(testClientID2) + }, true}, + {"consensus state not found", func() {}, false}, + {"connection state verification invalid", func() { + suite.createClient(testClientID1) + suite.createClient(testClientID2) + consensusHeight = suite.ctx.BlockHeight() + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.UNINITIALIZED) + suite.updateClient(testClientID1) + }, false}, + {"invalid previous connection", func() { + suite.createClient(testClientID1) + suite.createClient(testClientID2) + consensusHeight = suite.ctx.BlockHeight() + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) + suite.updateClient(testClientID1) + }, false}, + {"couldn't add connection to client", func() { + suite.createClient(testClientID1) + consensusHeight = suite.ctx.BlockHeight() + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.INIT) + suite.updateClient(testClientID1) + }, false}, + } + + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + + // connectionKey := ibctypes.KeyConnection(testConnectionID1) + // proofInit, proofHeight := suite.queryProof(connectionKey) + + // consensusKey := ibctypes.KeyConsensusState(testClientID1, uint64(proofHeight)) + // proofConsensus, consensusHeight := suite.queryProof(consensusKey) + + proofHeight := consensusHeight - 1 + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry( + suite.ctx, testConnectionID2, counterparty, testClientID2, + connection.GetCompatibleVersions(), validProof{}, validProof{}, + uint64(proofHeight), uint64(consensusHeight), + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry( + suite.ctx, testConnectionID2, counterparty, testClientID2, + connection.GetCompatibleVersions(), invalidProof{}, validProof{}, + uint64(proofHeight), uint64(consensusHeight), + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) } - - for _, tc := range testCases { - suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) - } - } +// TestConnOpenAck - Chain A (ID #1) calls TestConnOpenAck to acknowledge (ACK state) +// the initialization (TRYINIT) of the connection on Chain B (ID #2). func (suite *KeeperTestSuite) TestConnOpenAck() { - suite.createClient(testClientID2) - suite.createClient(testClientID1) - - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) - connectionKey := connection.KeyConnection(testConnectionID1) - consensusKey := client.KeyConsensusState(testClientID1) - - connectionNotFound := func() error { - //suite.updateClient(testClientID2) - - proofTry, proofHeight := suite.queryProof(connectionKey) - proofConsensus, consensusHeight := suite.queryProof(consensusKey) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) - return err - } - - invalidConnectionState := func() error { - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.UNINITIALIZED) - //suite.updateClient(testClientID2) - - proofTry, proofHeight := suite.queryProof(connectionKey) - proofConsensus, consensusHeight := suite.queryProof(consensusKey) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) - return err - } - - invalidVersion := func() error { - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) - //suite.updateClient(testClientID2) - - proofTry, proofHeight := suite.queryProof(connectionKey) - proofConsensus, consensusHeight := suite.queryProof(consensusKey) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, "1.0.1", proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) - return err - } - - invalidProof := func() error { - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) - //suite.updateClient(testClientID2) - - proofTry, proofHeight := suite.queryProof(connectionKey) - proofConsensus, consensusHeight := suite.queryProof(consensusKey) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) - return err - } - - success := func() error { - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT) - suite.updateClient(testClientID2) - - proofTry, proofHeight := suite.queryProof(connectionKey) - proofConsensus, consensusHeight := suite.queryProof(consensusKey) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight)) - - //check connection state - conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID2) - suite.True(existed) - suite.Equal(connection.OPEN.String(), conn.State.String(), "invalid connection state") - return err - - } - - var testCases = []TestCase{ - {connectionNotFound, false, "connection not exists"}, - {invalidConnectionState, false, "invalid connection state"}, - {invalidVersion, false, "invalid version"}, - {invalidProof, false, "invalid proof"}, - {success, true, ""}, - } - - for _, tc := range testCases { - suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) + version := connection.GetCompatibleVersions()[0] + consensusHeight := int64(0) + + testCases := []struct { + msg string + version string + malleate func() + expPass bool + }{ + {"success", version, func() { + suite.createClient(testClientID1) + consensusHeight = suite.ctx.BlockHeight() + suite.createClient(testClientID2) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) + suite.updateClient(testClientID1) + }, true}, + {"connection not found", version, func() {}, false}, + {"connection state is not INIT", version, func() { + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.UNINITIALIZED) + suite.updateClient(testClientID1) + }, false}, + {"incompatible IBC versions", "2.0", func() { + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.updateClient(testClientID1) + }, false}, + {"consensus state not found", version, func() { + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.updateClient(testClientID1) + }, false}, + {"connection state verification failed", version, func() { + suite.createClient(testClientID1) + consensusHeight = suite.ctx.BlockHeight() + suite.createClient(testClientID2) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) + suite.updateClient(testClientID1) + }, false}, + } + + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + + // connectionKey := ibctypes.KeyConnection(testConnectionID2) + // proofTry, proofHeight := suite.queryProof(connectionKey) + + // consensusKey := ibctypes.KeyConsensusState(testClientID2, uint64(proofHeight)) + // proofConsensus, consensusHeight := suite.queryProof(consensusKey) + + proofHeight := consensusHeight - 1 + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck( + suite.ctx, testConnectionID1, tc.version, validProof{}, validProof{}, + uint64(proofHeight), uint64(consensusHeight), + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck( + suite.ctx, testConnectionID1, tc.version, invalidProof{}, validProof{}, + uint64(proofHeight), uint64(consensusHeight), + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) } - } +// TestConnOpenAck - Chain B (ID #2) calls ConnOpenConfirm to confirm that +// Chain A (ID #1) state is now OPEN. func (suite *KeeperTestSuite) TestConnOpenConfirm() { - suite.createClient(testClientID2) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.OPEN) - - connKey := connection.KeyConnection(testConnectionID2) - proof, h := suite.queryProof(connKey) - - connectionNotFound := func() error { - //ErrConnectionNotFound - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) - return err - } - - invalidConnectionState := func() error { - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.INIT) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) - return err - } - - invalidProof := func() error { - //Error proof - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) - return err - } - - success := func() error { - //Success - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN) - suite.updateClient(testClientID1) - proof, h = suite.queryProof(connKey) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h)) - - //check connection state - conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) - suite.True(existed) - suite.Equal(connection.OPEN.String(), conn.State.String(), "invalid connection state") - return err - } - - var testCases = []TestCase{ - {connectionNotFound, false, "connection not exists"}, - {invalidConnectionState, false, "invalid connection state"}, - {invalidProof, false, "invalid proof"}, - {success, true, ""}, - } - - for _, tc := range testCases { - suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg) - } -} - -func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { - res := suite.app.Query(abci.RequestQuery{ - Path: fmt.Sprintf("store/%s/key", storeKey), - Data: key, - Prove: true, - }) - - height = res.Height - proof = commitment.Proof{ - Proof: res.Proof, - } - - return -} - -func (suite *KeeperTestSuite) createClient(clientID string) { - suite.app.Commit() - commitID := suite.app.LastCommitID() - - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - - consensusState := tendermint.ConsensusState{ - ChainID: chainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, - NextValidatorSet: suite.valSet, - } - - _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, clientType, consensusState) - suite.NoError(err) -} - -func (suite *KeeperTestSuite) updateClient(clientID string) { - // always commit when updateClient and begin a new block - suite.app.Commit() - commitID := suite.app.LastCommitID() - - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - - state := tendermint.ConsensusState{ - ChainID: chainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), - } - - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, clientID, state) - suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, clientID, state.GetHeight(), state.GetRoot()) -} - -func (suite *KeeperTestSuite) createConnection(connID, counterpartyConnID string, clientID, counterpartyClientID string, state connection.State) { - counterparty := connection.NewCounterparty(counterpartyClientID, counterpartyConnID, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - connection := connection.ConnectionEnd{ - State: state, - ClientID: clientID, - Counterparty: counterparty, - Versions: connection.GetCompatibleVersions(), + consensusHeight := int64(0) + + testCases := []testCase{ + {"success", func() { + suite.createClient(testClientID1) + suite.createClient(testClientID2) + consensusHeight = suite.ctx.BlockHeight() + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) + suite.updateClient(testClientID1) + }, true}, + {"connection not found", func() {}, false}, + {"chain B's connection state is not TRYOPEN", func() { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) + }, false}, + {"consensus state not found", func() { + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) + suite.updateClient(testClientID2) + }, false}, + {"connection state verification failed", func() { + suite.createClient(testClientID1) + suite.createClient(testClientID2) + consensusHeight = suite.ctx.BlockHeight() + suite.updateClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) + suite.updateClient(testClientID1) + }, false}, + } + + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + + // connectionKey := ibctypes.KeyConnection(testConnectionID2) + // proofAck, proofHeight := suite.queryProof(connectionKey) + proofHeight := consensusHeight - 1 + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( + suite.ctx, testConnectionID2, validProof{}, uint64(proofHeight), + uint64(consensusHeight), + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( + suite.ctx, testConnectionID2, invalidProof{}, uint64(proofHeight), + uint64(consensusHeight), + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) } - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, connID, connection) } -type TestCase = struct { - fun func() error - expected bool - errMsg string +type testCase = struct { + msg string + malleate func() + expPass bool } diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index 5edec4cdf32b..0ef8d8d77b2d 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" @@ -44,7 +45,7 @@ func (k Keeper) GetCommitmentPrefix() commitment.PrefixI { // GetConnection returns a connection with a particular identifier func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyConnection(connectionID)) + bz := store.Get(ibctypes.KeyConnection(connectionID)) if bz == nil { return types.ConnectionEnd{}, false } @@ -58,14 +59,14 @@ func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.Conne func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(connection) - store.Set(types.KeyConnection(connectionID), bz) + store.Set(ibctypes.KeyConnection(connectionID), bz) } // GetClientConnectionPaths returns all the connection paths stored under a // particular client func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyClientConnections(clientID)) + bz := store.Get(ibctypes.KeyClientConnections(clientID)) if bz == nil { return nil, false } @@ -79,7 +80,7 @@ func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]st func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths []string) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(paths) - store.Set(types.KeyClientConnections(clientID), bz) + store.Set(ibctypes.KeyClientConnections(clientID), bz) } // IterateConnections provides an iterator over all ConnectionEnd objects. @@ -87,7 +88,7 @@ func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths // iterator will close and stop. func (k Keeper) IterateConnections(ctx sdk.Context, cb func(types.ConnectionEnd) bool) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types.GetConnectionsKeysPrefix(ibctypes.KeyConnectionPrefix)) + iterator := sdk.KVStorePrefixIterator(store, ibctypes.KeyConnectionPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -111,9 +112,12 @@ func (k Keeper) GetAllConnections(ctx sdk.Context) (connections []types.Connecti // addConnectionToClient is used to add a connection identifier to the set of // connections associated with a client. -// -// CONTRACT: client must already exist func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID string) error { + _, found := k.clientKeeper.GetClientState(ctx, clientID) + if !found { + return clienttypes.ErrClientNotFound + } + conns, found := k.GetClientConnectionPaths(ctx, clientID) if !found { conns = []string{} @@ -143,36 +147,3 @@ func (k Keeper) removeConnectionFromClient(ctx sdk.Context, clientID, connection k.SetClientConnectionPaths(ctx, clientID, conns) return nil } - -// VerifyMembership helper function for state membership verification -func (k Keeper) VerifyMembership( - ctx sdk.Context, - connection types.ConnectionEnd, - height uint64, - proof commitment.ProofI, - pathStr string, - value []byte, -) bool { - path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) - if err != nil { - return false - } - - return k.clientKeeper.VerifyMembership(ctx, connection.ClientID, height, proof, path, value) -} - -// VerifyNonMembership helper function for state non-membership verification -func (k Keeper) VerifyNonMembership( - ctx sdk.Context, - connection types.ConnectionEnd, - height uint64, - proof commitment.ProofI, - pathStr string, -) bool { - path, err := commitment.ApplyPrefix(connection.Counterparty.Prefix, pathStr) - if err != nil { - return false - } - - return k.clientKeeper.VerifyNonMembership(ctx, connection.ClientID, height, proof, path) -} diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 8b3fb7f78cce..b353d3578a4c 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -1,42 +1,53 @@ package keeper_test import ( + "errors" + "fmt" "testing" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) const ( clientType = clientexported.Tendermint storeKey = ibctypes.StoreKey - chainID = "test" + chainID = "gaia" + testHeight = 10 - testClientID1 = "testclientid1" - testConnectionID1 = "connectionid1" + testClientID1 = "testclientidone" + testConnectionID1 = "connectionidone" - testClientID2 = "testclientid2" - testConnectionID2 = "connectionid2" + testClientID2 = "testclientidtwo" + testConnectionID2 = "connectionidtwo" - testClientID3 = "testclientid3" - testConnectionID3 = "connectionid3" + testClientID3 = "testclientidthree" + testConnectionID3 = "connectionidthree" ) type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp - valSet *tmtypes.ValidatorSet + cdc *codec.Codec + ctx sdk.Context + app *simapp.SimApp + valSet *tmtypes.ValidatorSet + consensusState clientexported.ConsensusState + header tendermint.Header } func (suite *KeeperTestSuite) SetupTest() { @@ -44,13 +55,119 @@ func (suite *KeeperTestSuite) SetupTest() { app := simapp.Setup(isCheckTx) suite.cdc = app.Codec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{ChainID: chainID, Height: 1}) suite.app = app privVal := tmtypes.NewMockPV() validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + suite.header = tendermint.CreateTestHeader(chainID, testHeight, suite.valSet, suite.valSet, []tmtypes.PrivValidator{privVal}) + + suite.consensusState = tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.valSet.Hash(), + } +} + +// nolint: unused +func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", storeKey), + Height: suite.app.LastBlockHeight(), + Data: key, + Prove: true, + }) + + proof := commitment.Proof{ + Proof: res.Proof, + } + + return proof, res.Height +} + +func (suite *KeeperTestSuite) createClient(clientID string) { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.ctx.WithBlockHeight(suite.ctx.BlockHeight() + 1) + + consensusState := tendermint.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), + ValidatorSetHash: suite.valSet.Hash(), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, clientType, consensusState) + suite.Require().NoError(err) + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.app.BaseApp, + // suite.ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgCreateClient(clientID, clientexported.ClientTypeTendermint, consState, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) +} + +func (suite *KeeperTestSuite) updateClient(clientID string) { + // always commit when updateClient and begin a new block + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.ctx.WithBlockHeight(suite.ctx.BlockHeight() + 1) + + consensusState := tendermint.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), + ValidatorSetHash: suite.valSet.Hash(), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState( + suite.ctx, clientID, uint64(suite.app.LastBlockHeight()), consensusState, + ) + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.app.BaseApp, + // suite.ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgUpdateClient(clientID, suite.header, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) + // suite.Require().NoError(err) +} + +func (suite *KeeperTestSuite) createConnection( + connID, counterpartyConnID, clientID, counterpartyClientID string, + state exported.State, +) types.ConnectionEnd { + counterparty := types.NewCounterparty(counterpartyClientID, counterpartyConnID, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + connection := types.ConnectionEnd{ + State: state, + ClientID: clientID, + Counterparty: counterparty, + Versions: types.GetCompatibleVersions(), + } + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, connID, connection) + return connection +} + +func (suite *KeeperTestSuite) createChannel( + portID, channelID, counterpartyPortID, counterpartyChannelID string, + state channelexported.State, order channelexported.Order, connectionID string, +) channeltypes.Channel { + counterparty := channeltypes.NewCounterparty(counterpartyPortID, counterpartyChannelID) + channel := channeltypes.NewChannel(state, order, counterparty, + []string{connectionID}, "1.0", + ) + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, channelID, channel) + return channel } func TestKeeperTestSuite(t *testing.T) { @@ -59,19 +176,14 @@ func TestKeeperTestSuite(t *testing.T) { func (suite *KeeperTestSuite) TestSetAndGetConnection() { _, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) - suite.False(existed) + suite.Require().False(existed) counterparty := types.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - expConn := types.ConnectionEnd{ - State: types.INIT, - ClientID: testClientID1, - Counterparty: counterparty, - Versions: types.GetCompatibleVersions(), - } + expConn := types.NewConnectionEnd(exported.INIT, testClientID1, counterparty, types.GetCompatibleVersions()) suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID1, expConn) conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) - suite.True(existed) - suite.EqualValues(expConn, conn) + suite.Require().True(existed) + suite.Require().EqualValues(expConn, conn) } func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { @@ -90,26 +202,9 @@ func (suite KeeperTestSuite) TestGetAllConnections() { counterparty2 := types.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) counterparty3 := types.NewCounterparty(testClientID3, testConnectionID3, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - conn1 := types.ConnectionEnd{ - State: types.INIT, - ClientID: testClientID1, - Counterparty: counterparty3, - Versions: types.GetCompatibleVersions(), - } - - conn2 := types.ConnectionEnd{ - State: types.INIT, - ClientID: testClientID2, - Counterparty: counterparty1, - Versions: types.GetCompatibleVersions(), - } - - conn3 := types.ConnectionEnd{ - State: types.UNINITIALIZED, - ClientID: testClientID3, - Counterparty: counterparty2, - Versions: types.GetCompatibleVersions(), - } + conn1 := types.NewConnectionEnd(exported.INIT, testClientID1, counterparty3, types.GetCompatibleVersions()) + conn2 := types.NewConnectionEnd(exported.INIT, testClientID2, counterparty1, types.GetCompatibleVersions()) + conn3 := types.NewConnectionEnd(exported.UNINITIALIZED, testClientID3, counterparty2, types.GetCompatibleVersions()) expConnections := []types.ConnectionEnd{conn1, conn2, conn3} @@ -119,5 +214,60 @@ func (suite KeeperTestSuite) TestGetAllConnections() { connections := suite.app.IBCKeeper.ConnectionKeeper.GetAllConnections(suite.ctx) suite.Require().Len(connections, len(expConnections)) - suite.Require().Equal(expConnections, connections) + suite.Require().ElementsMatch(expConnections, connections) +} + +// Mocked types +// TODO: fix tests and replace for real proofs + +var ( + _ commitment.ProofI = validProof{} + _ commitment.ProofI = invalidProof{} +) + +type ( + validProof struct{} + invalidProof struct{} +) + +func (validProof) GetCommitmentType() commitment.Type { + return commitment.Merkle +} + +func (validProof) VerifyMembership( + root commitment.RootI, path commitment.PathI, value []byte) error { + return nil +} + +func (validProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { + return nil +} + +func (validProof) ValidateBasic() error { + return nil +} + +func (validProof) IsEmpty() bool { + return false +} + +func (invalidProof) GetCommitmentType() commitment.Type { + return commitment.Merkle +} + +func (invalidProof) VerifyMembership( + root commitment.RootI, path commitment.PathI, value []byte) error { + return errors.New("proof failed") +} + +func (invalidProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { + return errors.New("proof failed") +} + +func (invalidProof) ValidateBasic() error { + return errors.New("invalid proof") +} + +func (invalidProof) IsEmpty() bool { + return true } diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go index c888e84e32b2..8225eccaa858 100644 --- a/x/ibc/03-connection/keeper/querier.go +++ b/x/ibc/03-connection/keeper/querier.go @@ -10,27 +10,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) -// QuerierConnection defines the sdk.Querier to query a connection end -func QuerierConnection(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { - var params types.QueryConnectionParams - - if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) - } - - connection, found := k.GetConnection(ctx, params.ConnectionID) - if !found { - return nil, sdkerrors.Wrap(types.ErrConnectionNotFound, params.ConnectionID) - } - - bz, err := types.SubModuleCdc.MarshalJSON(connection) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - - return bz, nil -} - // QuerierConnections defines the sdk.Querier to query all the connections. func QuerierConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryAllConnectionsParams diff --git a/x/ibc/03-connection/keeper/verify.go b/x/ibc/03-connection/keeper/verify.go new file mode 100644 index 000000000000..bc15b71e8131 --- /dev/null +++ b/x/ibc/03-connection/keeper/verify.go @@ -0,0 +1,167 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// VerifyClientConsensusState verifies a proof of the consensus state of the +// specified client stored on the target machine. +func (k Keeper) VerifyClientConsensusState( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + consensusState clientexported.ConsensusState, +) error { + clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) + if !found { + return clienttypes.ErrClientNotFound + } + + return clientState.VerifyClientConsensusState( + k.cdc, height, connection.Counterparty.Prefix, proof, consensusState, + ) +} + +// VerifyConnectionState verifies a proof of the connection state of the +// specified connection end stored on the target machine. +func (k Keeper) VerifyConnectionState( + ctx sdk.Context, + height uint64, + proof commitment.ProofI, + connectionID string, + connection types.ConnectionEnd, + consensusState clientexported.ConsensusState, +) error { + clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) + if !found { + return clienttypes.ErrClientNotFound + } + + return clientState.VerifyConnectionState( + k.cdc, height, connection.Counterparty.Prefix, proof, connectionID, connection, consensusState, + ) +} + +// VerifyChannelState verifies a proof of the channel state of the specified +// channel end, under the specified port, stored on the target machine. +func (k Keeper) VerifyChannelState( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + channel channelexported.ChannelI, + consensusState clientexported.ConsensusState, +) error { + clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) + if !found { + return clienttypes.ErrClientNotFound + } + + return clientState.VerifyChannelState( + k.cdc, height, connection.GetCounterparty().GetPrefix(), proof, + portID, channelID, channel, consensusState, + ) +} + +// VerifyPacketCommitment verifies a proof of an outgoing packet commitment at +// the specified port, specified channel, and specified sequence. +func (k Keeper) VerifyPacketCommitment( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + commitmentBytes []byte, + consensusState clientexported.ConsensusState, +) error { + clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) + if !found { + return clienttypes.ErrClientNotFound + } + + return clientState.VerifyPacketCommitment( + height, connection.GetCounterparty().GetPrefix(), proof, portID, channelID, + sequence, commitmentBytes, consensusState, + ) +} + +// VerifyPacketAcknowledgement verifies a proof of an incoming packet +// acknowledgement at the specified port, specified channel, and specified sequence. +func (k Keeper) VerifyPacketAcknowledgement( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + acknowledgement []byte, + consensusState clientexported.ConsensusState, +) error { + clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) + if !found { + return clienttypes.ErrClientNotFound + } + + return clientState.VerifyPacketAcknowledgement( + height, connection.GetCounterparty().GetPrefix(), proof, portID, channelID, + sequence, acknowledgement, consensusState, + ) +} + +// VerifyPacketAcknowledgementAbsence verifies a proof of the absence of an +// incoming packet acknowledgement at the specified port, specified channel, and +// specified sequence. +func (k Keeper) VerifyPacketAcknowledgementAbsence( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + consensusState clientexported.ConsensusState, +) error { + clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) + if !found { + return clienttypes.ErrClientNotFound + } + + return clientState.VerifyPacketAcknowledgementAbsence( + height, connection.GetCounterparty().GetPrefix(), proof, portID, channelID, + sequence, consensusState, + ) +} + +// VerifyNextSequenceRecv verifies a proof of the next sequence number to be +// received of the specified channel at the specified port. +func (k Keeper) VerifyNextSequenceRecv( + ctx sdk.Context, + connection types.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + nextSequenceRecv uint64, + consensusState clientexported.ConsensusState, +) error { + clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) + if !found { + return clienttypes.ErrClientNotFound + } + + return clientState.VerifyNextSequenceRecv( + height, connection.GetCounterparty().GetPrefix(), proof, portID, channelID, + nextSequenceRecv, consensusState, + ) +} diff --git a/x/ibc/03-connection/keeper/verify_test.go b/x/ibc/03-connection/keeper/verify_test.go new file mode 100644 index 000000000000..7e20b27b9557 --- /dev/null +++ b/x/ibc/03-connection/keeper/verify_test.go @@ -0,0 +1,354 @@ +package keeper_test + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" +) + +const ( + testPort1 = "firstport" + testPort2 = "secondport" + + testChannel1 = "firstchannel" + testChannel2 = "secondchannel" +) + +func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { + counterparty := types.NewCounterparty( + testClientID2, testConnectionID2, + suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + ) + + connection1 := types.NewConnectionEnd( + exported.UNINITIALIZED, testClientID1, counterparty, + types.GetCompatibleVersions(), + ) + + cases := []struct { + msg string + connection types.ConnectionEnd + malleate func() + expPass bool + }{ + {"verification success", connection1, func() { + suite.createClient(testClientID1) + }, true}, + {"client state not found", connection1, func() {}, false}, + {"verification failed", connection1, func() { + suite.createClient(testClientID2) + }, false}, + } + + for i, tc := range cases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + suite.updateClient(testClientID1) + + proofHeight := suite.ctx.BlockHeight() - 1 + + // TODO: remove mocked types and uncomment + // consensusKey := ibctypes.KeyConsensusState(testClientID1, uint64(suite.app.LastBlockHeight())) + // proof, proofHeight := suite.queryProof(consensusKey) + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyClientConsensusState( + suite.ctx, tc.connection, uint64(proofHeight), validProof{}, suite.consensusState, + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyClientConsensusState( + suite.ctx, tc.connection, uint64(proofHeight), invalidProof{}, suite.consensusState, + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } +} + +func (suite *KeeperTestSuite) TestVerifyConnectionState() { + // connectionKey := ibctypes.KeyConnection(testConnectionID1) + cases := []struct { + msg string + malleate func() + expPass bool + }{ + {"verification success", func() { + suite.createClient(testClientID1) + }, true}, + {"client state not found", func() {}, false}, + {"verification failed", func() { + suite.createClient(testClientID2) + }, false}, + } + + for i, tc := range cases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) + suite.updateClient(testClientID1) + + proofHeight := suite.ctx.BlockHeight() - 1 + // proof, proofHeight := suite.queryProof(connectionKey) + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyConnectionState( + suite.ctx, uint64(proofHeight), validProof{}, testConnectionID1, connection, suite.consensusState, + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyConnectionState( + suite.ctx, uint64(proofHeight), invalidProof{}, testConnectionID1, connection, suite.consensusState, + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } +} + +func (suite *KeeperTestSuite) TestVerifyChannelState() { + // channelKey := ibctypes.KeyChannel(testPort1, testChannel1) + + cases := []struct { + msg string + malleate func() + expPass bool + }{ + {"verification success", func() { + suite.createClient(testClientID1) + }, true}, + {"client state not found", func() {}, false}, + {"verification failed", func() { + suite.createClient(testClientID2) + }, false}, + } + + for i, tc := range cases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) + channel := suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, + channelexported.OPEN, channelexported.ORDERED, testConnectionID1, + ) + suite.updateClient(testClientID1) + + proofHeight := suite.ctx.BlockHeight() - 1 + // proof, proofHeight := suite.queryProof(channelKey) + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyChannelState( + suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, + testChannel1, channel, suite.consensusState, + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyChannelState( + suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, + testChannel1, channel, suite.consensusState, + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } +} + +func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { + // commitmentKey := ibctypes.KeyPacketCommitment(testPort1, testChannel1, 1) + commitmentBz := []byte("commitment") + + cases := []struct { + msg string + malleate func() + expPass bool + }{ + {"verification success", func() { + suite.createClient(testClientID1) + }, true}, + {"client state not found", func() {}, false}, + {"verification failed", func() { + suite.createClient(testClientID2) + }, false}, + } + + for i, tc := range cases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, commitmentBz) + suite.updateClient(testClientID1) + + proofHeight := suite.ctx.BlockHeight() - 1 + // proof, proofHeight := suite.queryProof(commitmentKey) + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketCommitment( + suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, + testChannel1, 1, commitmentBz, suite.consensusState, + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketCommitment( + suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, + testChannel1, 1, commitmentBz, suite.consensusState, + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } +} + +func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { + // packetAckKey := ibctypes.KeyPacketAcknowledgement(testPort1, testChannel1, 1) + ack := []byte("acknowledgement") + + cases := []struct { + msg string + malleate func() + expPass bool + }{ + {"verification success", func() { + suite.createClient(testClientID1) + }, true}, + {"client state not found", func() {}, false}, + {"verification failed", func() { + suite.createClient(testClientID2) + }, false}, + } + + for i, tc := range cases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) + suite.app.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, 1, ack) + suite.updateClient(testClientID1) + + proofHeight := suite.ctx.BlockHeight() - 1 + // proof, proofHeight := suite.queryProof(packetAckKey) + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgement( + suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, + testChannel1, 1, ack, suite.consensusState, + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgement( + suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, + testChannel1, 1, ack, suite.consensusState, + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } +} + +func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { + // packetAckKey := ibctypes.KeyPacketAcknowledgement(testPort1, testChannel1, 1) + + cases := []struct { + msg string + malleate func() + expPass bool + }{ + {"verification success", func() { + suite.createClient(testClientID1) + }, true}, + {"client state not found", func() {}, false}, + {"verification failed", func() { + suite.createClient(testClientID2) + }, false}, + } + + for i, tc := range cases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) + suite.updateClient(testClientID1) + + proofHeight := suite.ctx.BlockHeight() - 1 + // proof, proofHeight := suite.queryProof(packetAckKey) + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgementAbsence( + suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, + testChannel1, 1, suite.consensusState, + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgementAbsence( + suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, + testChannel1, 1, suite.consensusState, + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } +} + +func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { + // nextSeqRcvKey := ibctypes.KeyNextSequenceRecv(testPort1, testChannel1) + + cases := []struct { + msg string + malleate func() + expPass bool + }{ + {"verification success", func() { + suite.createClient(testClientID1) + }, true}, + {"client state not found", func() {}, false}, + {"verification failed", func() { + suite.createClient(testClientID2) + }, false}, + } + + for i, tc := range cases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, 1) + suite.updateClient(testClientID1) + + proofHeight := suite.ctx.BlockHeight() - 1 + // proof, proofHeight := suite.queryProof(nextSeqRcvKey) + + if tc.expPass { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyNextSequenceRecv( + suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, + testChannel1, 1, suite.consensusState, + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyNextSequenceRecv( + suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, + testChannel1, 1, suite.consensusState, + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } +} diff --git a/x/ibc/03-connection/types/codec.go b/x/ibc/03-connection/types/codec.go index 4317d3c6d539..263ec4c3f4ae 100644 --- a/x/ibc/03-connection/types/codec.go +++ b/x/ibc/03-connection/types/codec.go @@ -2,6 +2,7 @@ package types import ( "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" ) // SubModuleCdc defines the IBC connection codec. @@ -9,15 +10,19 @@ var SubModuleCdc *codec.Codec // RegisterCodec registers the IBC connection types func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*exported.ConnectionI)(nil), nil) + cdc.RegisterInterface((*exported.CounterpartyI)(nil), nil) + cdc.RegisterConcrete(ConnectionEnd{}, "ibc/connection/ConnectionEnd", nil) + cdc.RegisterConcrete(MsgConnectionOpenInit{}, "ibc/connection/MsgConnectionOpenInit", nil) cdc.RegisterConcrete(MsgConnectionOpenTry{}, "ibc/connection/MsgConnectionOpenTry", nil) cdc.RegisterConcrete(MsgConnectionOpenAck{}, "ibc/connection/MsgConnectionOpenAck", nil) cdc.RegisterConcrete(MsgConnectionOpenConfirm{}, "ibc/connection/MsgConnectionOpenConfirm", nil) - cdc.RegisterConcrete(ConnectionEnd{}, "ibc/connection/ConnectionEnd", nil) SetSubModuleCodec(cdc) } +// SetSubModuleCodec sets the ibc connection codec func SetSubModuleCodec(cdc *codec.Codec) { SubModuleCdc = cdc } diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 5a441c22eb26..9f0678310dd7 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -1,22 +1,26 @@ package types import ( - "encoding/json" + "strings" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) +var _ exported.ConnectionI = ConnectionEnd{} + // ICS03 - Connection Data Structures as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#data-structures // ConnectionEnd defines a stateful object on a chain connected to another separate // one. -// NOTE: there must only be 2 defined ConnectionEnds to stablish a connection +// NOTE: there must only be 2 defined ConnectionEnds to establish a connection // between two chains. type ConnectionEnd struct { - State State `json:"state" yaml:"state"` - ClientID string `json:"client_id" yaml:"client_id"` + State exported.State `json:"state" yaml:"state"` + ClientID string `json:"client_id" yaml:"client_id"` // Counterparty chain associated with this connection. Counterparty Counterparty `json:"counterparty" yaml:"counterparty"` @@ -26,7 +30,7 @@ type ConnectionEnd struct { } // NewConnectionEnd creates a new ConnectionEnd instance. -func NewConnectionEnd(state State, clientID string, counterparty Counterparty, versions []string) ConnectionEnd { +func NewConnectionEnd(state exported.State, clientID string, counterparty Counterparty, versions []string) ConnectionEnd { return ConnectionEnd{ State: state, ClientID: clientID, @@ -35,6 +39,44 @@ func NewConnectionEnd(state State, clientID string, counterparty Counterparty, v } } +// GetState implements the Connection interface +func (c ConnectionEnd) GetState() exported.State { + return c.State +} + +// GetClientID implements the Connection interface +func (c ConnectionEnd) GetClientID() string { + return c.ClientID +} + +// GetCounterparty implements the Connection interface +func (c ConnectionEnd) GetCounterparty() exported.CounterpartyI { + return c.Counterparty +} + +// GetVersions implements the Connection interface +func (c ConnectionEnd) GetVersions() []string { + return c.Versions +} + +// ValidateBasic implements the Connection interface +func (c ConnectionEnd) ValidateBasic() error { + if err := host.DefaultClientIdentifierValidator(c.ClientID); err != nil { + return sdkerrors.Wrapf(err, "invalid client ID: %s", c.ClientID) + } + if len(c.Versions) == 0 { + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "missing connection versions") + } + for _, version := range c.Versions { + if strings.TrimSpace(version) == "" { + return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version can't be blank") + } + } + return c.Counterparty.ValidateBasic() +} + +var _ exported.CounterpartyI = Counterparty{} + // Counterparty defines the counterparty chain associated with a connection end. type Counterparty struct { ClientID string `json:"client_id" yaml:"client_id"` @@ -51,6 +93,21 @@ func NewCounterparty(clientID, connectionID string, prefix commitment.PrefixI) C } } +// GetClientID implements the CounterpartyI interface +func (c Counterparty) GetClientID() string { + return c.ClientID +} + +// GetConnectionID implements the CounterpartyI interface +func (c Counterparty) GetConnectionID() string { + return c.ConnectionID +} + +// GetPrefix implements the CounterpartyI interface +func (c Counterparty) GetPrefix() commitment.PrefixI { + return c.Prefix +} + // ValidateBasic performs a basic validation check of the identifiers and prefix func (c Counterparty) ValidateBasic() error { if err := host.DefaultConnectionIdentifierValidator(c.ConnectionID); err != nil { @@ -74,68 +131,3 @@ func (c Counterparty) ValidateBasic() error { } return nil } - -// State defines the state of a connection between two disctinct -// chains -type State byte - -// available connection states -const ( - UNINITIALIZED State = iota // default State - INIT - TRYOPEN - OPEN -) - -// string representation of the connection states -const ( - StateUninitialized string = "UNINITIALIZED" - StateInit string = "INIT" - StateTryOpen string = "TRYOPEN" - StateOpen string = "OPEN" -) - -// String implements the Stringer interface -func (cs State) String() string { - switch cs { - case INIT: - return StateInit - case TRYOPEN: - return StateTryOpen - case OPEN: - return StateOpen - default: - return StateUninitialized - } -} - -// StateFromString parses a string into a connection state -func StateFromString(state string) State { - switch state { - case StateInit: - return INIT - case StateTryOpen: - return TRYOPEN - case StateOpen: - return OPEN - default: - return UNINITIALIZED - } -} - -// MarshalJSON marshal to JSON using string. -func (cs State) MarshalJSON() ([]byte, error) { - return json.Marshal(cs.String()) -} - -// UnmarshalJSON decodes from JSON assuming Bech32 encoding. -func (cs *State) UnmarshalJSON(data []byte) error { - var s string - err := json.Unmarshal(data, &s) - if err != nil { - return err - } - - *cs = StateFromString(s) - return nil -} diff --git a/x/ibc/03-connection/types/connection_test.go b/x/ibc/03-connection/types/connection_test.go index 7202b6f72a0b..895eaf45afdb 100644 --- a/x/ibc/03-connection/types/connection_test.go +++ b/x/ibc/03-connection/types/connection_test.go @@ -4,43 +4,76 @@ import ( "testing" "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -func TestConnectionStateString(t *testing.T) { - cases := []struct { - name string - state State +func TestConnectionValidateBasic(t *testing.T) { + testCases := []struct { + name string + connection ConnectionEnd + expPass bool }{ - {StateUninitialized, UNINITIALIZED}, - {StateInit, INIT}, - {StateTryOpen, TRYOPEN}, - {StateOpen, OPEN}, + { + "valid connection", + ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, []string{"1.0.0"}}, + true, + }, + { + "invalid client id", + ConnectionEnd{exported.INIT, "ClientIDTwo", Counterparty{"clientidtwo", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, []string{"1.0.0"}}, + false, + }, + { + "empty versions", + ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, nil}, + false, + }, + { + "invalid version", + ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, []string{""}}, + false, + }, + { + "invalid counterparty", + ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", nil}, []string{"1.0.0"}}, + false, + }, } - for _, tt := range cases { - tt := tt - require.Equal(t, tt.state, StateFromString(tt.name)) - require.Equal(t, tt.name, tt.state.String()) + for i, tc := range testCases { + tc := tc + + err := tc.connection.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "valid test case %d failed: %s", i, tc.name) + } else { + require.Error(t, err, "invalid test case %d passed: %s", i, tc.name) + } } } -func TestConnectionlStateMarshalJSON(t *testing.T) { - cases := []struct { - name string - state State +func TestCounterpartyValidateBasic(t *testing.T) { + testCases := []struct { + name string + counterparty Counterparty + expPass bool }{ - {StateUninitialized, UNINITIALIZED}, - {StateInit, INIT}, - {StateTryOpen, TRYOPEN}, - {StateOpen, OPEN}, + {"valid counterparty", Counterparty{"clientidone", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, true}, + {"invalid client id", Counterparty{"InvalidClient", "channelidone", commitment.NewPrefix([]byte("prefix"))}, false}, + {"invalid connection id", Counterparty{"clientidone", "InvalidConnection", commitment.NewPrefix([]byte("prefix"))}, false}, + {"invalid prefix", Counterparty{"clientidone", "connectionidone", nil}, false}, } - for _, tt := range cases { - tt := tt - bz, err := tt.state.MarshalJSON() - require.NoError(t, err) - var state State - require.NoError(t, state.UnmarshalJSON(bz)) - require.Equal(t, tt.name, state.String()) + for i, tc := range testCases { + tc := tc + + err := tc.counterparty.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "valid test case %d failed: %s", i, tc.name) + } else { + require.Error(t, err, "invalid test case %d passed: %s", i, tc.name) + } } } diff --git a/x/ibc/03-connection/types/errors.go b/x/ibc/03-connection/types/errors.go index 41199efc4103..a738f9956762 100644 --- a/x/ibc/03-connection/types/errors.go +++ b/x/ibc/03-connection/types/errors.go @@ -12,4 +12,5 @@ var ( ErrConnectionPath = sdkerrors.Register(SubModuleName, 4, "connection path is not associated to the given light client") ErrInvalidConnectionState = sdkerrors.Register(SubModuleName, 5, "invalid connection state") ErrInvalidCounterparty = sdkerrors.Register(SubModuleName, 6, "invalid counterparty connection") + ErrInvalidConnection = sdkerrors.Register(SubModuleName, 7, "invalid connection") ) diff --git a/x/ibc/03-connection/types/expected_keepers.go b/x/ibc/03-connection/types/expected_keepers.go index 1a114f6f8374..a5de7514afa8 100644 --- a/x/ibc/03-connection/types/expected_keepers.go +++ b/x/ibc/03-connection/types/expected_keepers.go @@ -2,21 +2,11 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" - client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // ClientKeeper expected account IBC client keeper type ClientKeeper interface { - GetConsensusState(ctx sdk.Context, clientID string) (clientexported.ConsensusState, bool) - GetClientState(ctx sdk.Context, clientID string) (client.State, bool) - VerifyMembership( - ctx sdk.Context, clientID string, height uint64, - proof commitment.ProofI, path commitment.PathI, value []byte, - ) bool - VerifyNonMembership( - ctx sdk.Context, clientID string, height uint64, - proof commitment.ProofI, path commitment.PathI, - ) bool + GetClientState(ctx sdk.Context, clientID string) (clientexported.ClientState, bool) + GetConsensusState(ctx sdk.Context, clientID string, height uint64) (clientexported.ConsensusState, bool) } diff --git a/x/ibc/03-connection/types/keys.go b/x/ibc/03-connection/types/keys.go index 345b6b58d023..23478ec7591a 100644 --- a/x/ibc/03-connection/types/keys.go +++ b/x/ibc/03-connection/types/keys.go @@ -1,11 +1,5 @@ package types -import ( - "fmt" - - ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" -) - const ( // SubModuleName defines the IBC connection name SubModuleName = "connection" @@ -19,44 +13,3 @@ const ( // QuerierRoute is the querier route for IBC connections QuerierRoute = SubModuleName ) - -// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths - -// ClientConnectionsPath defines a reverse mapping from clients to a set of connections -func ClientConnectionsPath(clientID string) string { - return string(KeyClientConnections(clientID)) -} - -// ConnectionPath defines the path under which connection paths are stored -func ConnectionPath(connectionID string) string { - return string(KeyConnection(connectionID)) -} - -// KeyClientConnections returns the store key for the connectios of a given client -func KeyClientConnections(clientID string) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyClientConnectionsPrefix), - []byte(clientConnectionsPath(clientID))..., - ) -} - -// KeyConnection returns the store key for a particular connection -func KeyConnection(connectionID string) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyConnectionPrefix), - []byte(connectionPath(connectionID))..., - ) -} - -// GetConnectionsKeysPrefix return the connection prefixes -func GetConnectionsKeysPrefix(prefix int) []byte { - return []byte(fmt.Sprintf("%d/connections", prefix)) -} - -func clientConnectionsPath(clientID string) string { - return fmt.Sprintf("clients/%s/connections", clientID) -} - -func connectionPath(connectionID string) string { - return fmt.Sprintf("connections/%s", connectionID) -} diff --git a/x/ibc/03-connection/types/msgs.go b/x/ibc/03-connection/types/msgs.go index bf0731c3bb66..cde1eb87722b 100644 --- a/x/ibc/03-connection/types/msgs.go +++ b/x/ibc/03-connection/types/msgs.go @@ -249,21 +249,24 @@ var _ sdk.Msg = MsgConnectionOpenConfirm{} // MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to acknowledge // the change of connection state to OPEN on Chain A. type MsgConnectionOpenConfirm struct { - ConnectionID string `json:"connection_id"` - ProofAck commitment.ProofI `json:"proof_ack"` // proof for the change of the connection state on Chain A: `INIT -> OPEN` - ProofHeight uint64 `json:"proof_height"` - Signer sdk.AccAddress `json:"signer"` + ConnectionID string `json:"connection_id"` + ProofAck commitment.ProofI `json:"proof_ack"` // proof for the change of the connection state on Chain A: `INIT -> OPEN` + ProofHeight uint64 `json:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height"` + Signer sdk.AccAddress `json:"signer"` } // NewMsgConnectionOpenConfirm creates a new MsgConnectionOpenConfirm instance func NewMsgConnectionOpenConfirm( - connectionID string, proofAck commitment.ProofI, proofHeight uint64, signer sdk.AccAddress, + connectionID string, proofAck commitment.ProofI, proofHeight, consensusHeight uint64, + signer sdk.AccAddress, ) MsgConnectionOpenConfirm { return MsgConnectionOpenConfirm{ - ConnectionID: connectionID, - ProofAck: proofAck, - ProofHeight: proofHeight, - Signer: signer, + ConnectionID: connectionID, + ProofAck: proofAck, + ProofHeight: proofHeight, + ConsensusHeight: consensusHeight, + Signer: signer, } } @@ -291,6 +294,9 @@ func (msg MsgConnectionOpenConfirm) ValidateBasic() error { if msg.ProofHeight == 0 { return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } + if msg.ConsensusHeight == 0 { + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "consensus height must be > 0") + } if msg.Signer.Empty() { return sdkerrors.ErrInvalidAddress } diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go index 8bca120769ba..ae6c73e55889 100644 --- a/x/ibc/03-connection/types/msgs_test.go +++ b/x/ibc/03-connection/types/msgs_test.go @@ -183,12 +183,13 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenConfirm{ - NewMsgConnectionOpenConfirm("test/conn1", suite.proof, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", nil, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{Proof: nil}, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 0, signer), - NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, nil), - NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, signer), + NewMsgConnectionOpenConfirm("test/conn1", suite.proof, 10, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", nil, 10, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{Proof: nil}, 10, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 0, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, 0, signer), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, 10, nil), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, 10, signer), } var testCases = []struct { @@ -200,8 +201,9 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { {testMsgs[1], false, "empty proofTry"}, {testMsgs[2], false, "empty proofTry"}, {testMsgs[3], false, "invalid proofHeight"}, - {testMsgs[4], false, "empty signer"}, - {testMsgs[5], true, "success"}, + {testMsgs[4], false, "invalid consensusHeight"}, + {testMsgs[5], false, "empty signer"}, + {testMsgs[6], true, "success"}, } for i, tc := range testCases { diff --git a/x/ibc/03-connection/types/querier.go b/x/ibc/03-connection/types/querier.go index 02581d42b15e..459082a7f0c0 100644 --- a/x/ibc/03-connection/types/querier.go +++ b/x/ibc/03-connection/types/querier.go @@ -6,12 +6,12 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // query routes supported by the IBC connection Querier const ( QueryAllConnections = "connections" - QueryConnection = "connection" QueryClientConnections = "client_connections" ) @@ -31,24 +31,11 @@ func NewConnectionResponse( return ConnectionResponse{ Connection: connection, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ConnectionPath(connectionID), "/")), + ProofPath: commitment.NewPath(strings.Split(ibctypes.ConnectionPath(connectionID), "/")), ProofHeight: uint64(height), } } -// QueryConnectionParams defines the params for the following queries: -// - 'custom/ibc/connections/' -type QueryConnectionParams struct { - ConnectionID string -} - -// NewQueryConnectionParams creates a new QueryConnectionParams instance -func NewQueryConnectionParams(clientID string) QueryConnectionParams { - return QueryConnectionParams{ - ConnectionID: clientID, - } -} - // QueryAllConnectionsParams defines the parameters necessary for querying for all // connections. type QueryAllConnectionsParams struct { @@ -81,7 +68,7 @@ func NewClientConnectionsResponse( return ClientConnectionsResponse{ ConnectionPaths: connectionPaths, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ClientConnectionsPath(clientID), "/")), + ProofPath: commitment.NewPath(strings.Split(ibctypes.ClientConnectionsPath(clientID), "/")), ProofHeight: uint64(height), } } diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index ff4895eae42a..6fb4daa4586b 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -12,21 +12,6 @@ import ( ) const ( - UNINITIALIZED = types.UNINITIALIZED - UNORDERED = types.UNORDERED - ORDERED = types.ORDERED - OrderNone = types.OrderNone - OrderUnordered = types.OrderUnordered - OrderOrdered = types.OrderOrdered - CLOSED = types.CLOSED - INIT = types.INIT - TRYOPEN = types.TRYOPEN - OPEN = types.OPEN - StateUninitialized = types.StateUninitialized - StateInit = types.StateInit - StateTryOpen = types.StateTryOpen - StateOpen = types.StateOpen - StateClosed = types.StateClosed AttributeKeySenderPort = types.AttributeKeySenderPort AttributeKeyReceiverPort = types.AttributeKeyReceiverPort AttributeKeyChannelID = types.AttributeKeyChannelID @@ -43,11 +28,8 @@ var ( // functions aliases NewKeeper = keeper.NewKeeper QuerierChannels = keeper.QuerierChannels - QuerierChannel = keeper.QuerierChannel NewChannel = types.NewChannel NewCounterparty = types.NewCounterparty - OrderFromString = types.OrderFromString - StateFromString = types.StateFromString RegisterCodec = types.RegisterCodec ErrChannelExists = types.ErrChannelExists ErrChannelNotFound = types.ErrChannelNotFound @@ -59,18 +41,6 @@ var ( ErrPacketTimeout = types.ErrPacketTimeout ErrInvalidChannel = types.ErrInvalidChannel ErrInvalidChannelState = types.ErrInvalidChannelState - ChannelPath = types.ChannelPath - ChannelCapabilityPath = types.ChannelCapabilityPath - NextSequenceSendPath = types.NextSequenceSendPath - NextSequenceRecvPath = types.NextSequenceRecvPath - PacketCommitmentPath = types.PacketCommitmentPath - PacketAcknowledgementPath = types.PacketAcknowledgementPath - KeyChannel = types.KeyChannel - KeyChannelCapabilityPath = types.KeyChannelCapabilityPath - KeyNextSequenceSend = types.KeyNextSequenceSend - KeyNextSequenceRecv = types.KeyNextSequenceRecv - KeyPacketCommitment = types.KeyPacketCommitment - KeyPacketAcknowledgement = types.KeyPacketAcknowledgement NewMsgChannelOpenInit = types.NewMsgChannelOpenInit NewMsgChannelOpenTry = types.NewMsgChannelOpenTry NewMsgChannelOpenAck = types.NewMsgChannelOpenAck @@ -82,7 +52,6 @@ var ( NewMsgAcknowledgement = types.NewMsgAcknowledgement NewPacket = types.NewPacket NewChannelResponse = types.NewChannelResponse - NewQueryChannelParams = types.NewQueryChannelParams // variable aliases SubModuleCdc = types.SubModuleCdc @@ -99,8 +68,6 @@ type ( Keeper = keeper.Keeper Channel = types.Channel Counterparty = types.Counterparty - Order = types.Order - State = types.State ClientKeeper = types.ClientKeeper ConnectionKeeper = types.ConnectionKeeper PortKeeper = types.PortKeeper @@ -115,5 +82,4 @@ type ( MsgTimeout = types.MsgTimeout Packet = types.Packet ChannelResponse = types.ChannelResponse - QueryChannelParams = types.QueryChannelParams ) diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index df0c53cddf82..3ed2119b470f 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" connectionutils "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) @@ -242,9 +243,9 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm } } -func channelOrder() types.Order { +func channelOrder() exported.Order { if viper.GetBool(FlagOrdered) { - return types.ORDERED + return exported.ORDERED } - return types.UNORDERED + return exported.UNORDERED } diff --git a/x/ibc/04-channel/client/rest/rest.go b/x/ibc/04-channel/client/rest/rest.go index 4c869297d6e7..7ee17790ea88 100644 --- a/x/ibc/04-channel/client/rest/rest.go +++ b/x/ibc/04-channel/client/rest/rest.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -22,14 +23,14 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) // ChannelOpenInitReq defines the properties of a channel open init request's body. type ChannelOpenInitReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - PortID string `json:"port_id" yaml:"port_id"` - ChannelID string `json:"channel_id" yaml:"channel_id"` - Version string `json:"version" yaml:"version"` - ChannelOrder types.Order `json:"channel_order" yaml:"channel_order"` - ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` - CounterpartyPortID string `json:"counterparty_port_id" yaml:"counterparty_port_id"` - CounterpartyChannelID string `json:"counterparty_channel_id" yaml:"counterparty_channel_id"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + PortID string `json:"port_id" yaml:"port_id"` + ChannelID string `json:"channel_id" yaml:"channel_id"` + Version string `json:"version" yaml:"version"` + ChannelOrder exported.Order `json:"channel_order" yaml:"channel_order"` + ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` + CounterpartyPortID string `json:"counterparty_port_id" yaml:"counterparty_port_id"` + CounterpartyChannelID string `json:"counterparty_channel_id" yaml:"counterparty_channel_id"` } // ChannelOpenTryReq defines the properties of a channel open try request's body. @@ -38,7 +39,7 @@ type ChannelOpenTryReq struct { PortID string `json:"port_id" yaml:"port_id"` ChannelID string `json:"channel_id" yaml:"channel_id"` Version string `json:"version" yaml:"version"` - ChannelOrder types.Order `json:"channel_order" yaml:"channel_order"` + ChannelOrder exported.Order `json:"channel_order" yaml:"channel_order"` ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` CounterpartyPortID string `json:"counterparty_port_id" yaml:"counterparty_port_id"` CounterpartyChannelID string `json:"counterparty_channel_id" yaml:"counterparty_channel_id"` diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index 912c77d463e9..8cdcd3eb8eb1 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // QueryPacket returns a packet from the store @@ -15,7 +16,7 @@ func QueryPacket( ) (types.PacketResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", - Data: types.KeyPacketCommitment(portID, channelID, sequence), + Data: ibctypes.KeyPacketCommitment(portID, channelID, sequence), Prove: prove, } @@ -61,7 +62,7 @@ func QueryChannel( ) (types.ChannelResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", - Data: types.KeyChannel(portID, channelID), + Data: ibctypes.KeyChannel(portID, channelID), Prove: prove, } diff --git a/x/ibc/04-channel/exported/exported.go b/x/ibc/04-channel/exported/exported.go index 75608bd532a7..ad4f75cacfa8 100644 --- a/x/ibc/04-channel/exported/exported.go +++ b/x/ibc/04-channel/exported/exported.go @@ -1,5 +1,28 @@ package exported +import ( + "encoding/json" + "fmt" +) + +// ChannelI defines the standard interface for a channel end. +type ChannelI interface { + GetState() State + GetOrdering() Order + GetCounterparty() CounterpartyI + GetConnectionHops() []string + GetVersion() string + ValidateBasic() error +} + +// CounterpartyI defines the standard interface for a channel end's +// counterparty. +type CounterpartyI interface { + GetPortID() string + GetChannelID() string + ValidateBasic() error +} + // PacketI defines the standard interface for IBC packets type PacketI interface { GetSequence() uint64 @@ -22,3 +45,137 @@ type PacketDataI interface { ValidateBasic() error // ValidateBasic validates basic properties of the packet data, implements sdk.Msg Type() string // Type returns human readable identifier, implements sdk.Msg } + +// Order defines if a channel is ORDERED or UNORDERED +type Order byte + +// string representation of the channel ordering +const ( + NONE Order = iota // zero-value for channel ordering + UNORDERED // packets can be delivered in any order, which may differ from the order in which they were sent. + ORDERED // packets are delivered exactly in the order which they were sent +) + +// channel order types +const ( + OrderNone string = "" + OrderUnordered string = "UNORDERED" + OrderOrdered string = "ORDERED" +) + +// String implements the Stringer interface +func (o Order) String() string { + switch o { + case UNORDERED: + return OrderUnordered + case ORDERED: + return OrderOrdered + default: + return OrderNone + } +} + +// MarshalJSON marshal to JSON using string. +func (o Order) MarshalJSON() ([]byte, error) { + return json.Marshal(o.String()) +} + +// UnmarshalJSON decodes from JSON. +func (o *Order) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + order := OrderFromString(s) + if order == 0 { + return fmt.Errorf("invalid order '%s'", s) + } + + *o = order + return nil +} + +// OrderFromString parses a string into a channel order byte +func OrderFromString(order string) Order { + switch order { + case OrderUnordered: + return UNORDERED + case OrderOrdered: + return ORDERED + default: + return NONE + } +} + +// State defines if a channel is in one of the following states: +// CLOSED, INIT, OPENTRY or OPEN +type State byte + +// channel state types +const ( + UNINITIALIZED State = iota // Default State + INIT // A channel end has just started the opening handshake. + TRYOPEN // A channel end has acknowledged the handshake step on the counterparty chain. + OPEN // A channel end has completed the handshake and is ready to send and receive packets. + CLOSED // A channel end has been closed and can no longer be used to send or receive packets. +) + +// string representation of the channel states +const ( + StateUninitialized string = "UNINITIALIZED" + StateInit string = "INIT" + StateTryOpen string = "TRYOPEN" + StateOpen string = "OPEN" + StateClosed string = "CLOSED" +) + +// String implements the Stringer interface +func (s State) String() string { + switch s { + case INIT: + return StateInit + case TRYOPEN: + return StateTryOpen + case OPEN: + return StateOpen + case CLOSED: + return StateClosed + default: + return StateUninitialized + } +} + +// MarshalJSON marshal to JSON using string. +func (s State) MarshalJSON() ([]byte, error) { + return json.Marshal(s.String()) +} + +// UnmarshalJSON decodes from JSON. +func (s *State) UnmarshalJSON(data []byte) error { + var stateStr string + err := json.Unmarshal(data, &stateStr) + if err != nil { + return err + } + + *s = StateFromString(stateStr) + return nil +} + +// StateFromString parses a string into a channel state byte +func StateFromString(state string) State { + switch state { + case StateClosed: + return CLOSED + case StateInit: + return INIT + case StateTryOpen: + return TRYOPEN + case StateOpen: + return OPEN + default: + return UNINITIALIZED + } +} diff --git a/x/ibc/04-channel/exported/exported_test.go b/x/ibc/04-channel/exported/exported_test.go new file mode 100644 index 000000000000..51d94bfdebb1 --- /dev/null +++ b/x/ibc/04-channel/exported/exported_test.go @@ -0,0 +1,91 @@ +package exported + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestChannelStateString(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + {StateClosed, CLOSED}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.state, StateFromString(tt.name)) + require.Equal(t, tt.name, tt.state.String()) + } +} + +func TestChannelStateMarshalJSON(t *testing.T) { + cases := []struct { + name string + state State + }{ + {StateUninitialized, UNINITIALIZED}, + {StateInit, INIT}, + {StateTryOpen, TRYOPEN}, + {StateOpen, OPEN}, + {StateClosed, CLOSED}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.state.MarshalJSON() + require.NoError(t, err) + var state State + require.NoError(t, state.UnmarshalJSON(bz)) + require.Equal(t, tt.name, state.String()) + } +} + +func TestOrderString(t *testing.T) { + cases := []struct { + name string + order Order + }{ + {OrderNone, NONE}, + {OrderUnordered, UNORDERED}, + {OrderOrdered, ORDERED}, + } + + for _, tt := range cases { + tt := tt + require.Equal(t, tt.order, OrderFromString(tt.name)) + require.Equal(t, tt.name, tt.order.String()) + } +} + +func TestOrderMarshalJSON(t *testing.T) { + cases := []struct { + msg string + name string + order Order + expectPass bool + }{ + {"none ordering should have failed", OrderNone, NONE, false}, + {"unordered should have passed", OrderUnordered, UNORDERED, true}, + {"ordered should have passed", OrderOrdered, ORDERED, true}, + } + + for _, tt := range cases { + tt := tt + bz, err := tt.order.MarshalJSON() + require.NoError(t, err) + var order Order + if tt.expectPass { + require.NoError(t, order.UnmarshalJSON(bz), tt.msg) + require.Equal(t, tt.name, order.String(), tt.msg) + } else { + require.Error(t, order.UnmarshalJSON(bz), tt.msg) + } + } +} diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index c09dac9344f7..1279b6d0ba25 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -1,13 +1,14 @@ package keeper import ( - "errors" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -20,7 +21,7 @@ func (k Keeper) CounterpartyHops(ctx sdk.Context, ch types.Channel) ([]string, b if !found { return []string{}, false } - counterPartyHops[len(counterPartyHops)-1-i] = connection.Counterparty.ConnectionID + counterPartyHops[len(counterPartyHops)-1-i] = connection.GetCounterparty().GetConnectionID() } return counterPartyHops, true } @@ -29,14 +30,15 @@ func (k Keeper) CounterpartyHops(ctx sdk.Context, ch types.Channel) ([]string, b // a module on another chain. func (k Keeper) ChanOpenInit( ctx sdk.Context, - order types.Order, + order exported.Order, connectionHops []string, portID, channelID string, counterparty types.Counterparty, version string, ) error { - // TODO: abortTransactionUnless(validateChannelIdentifier(portIdentifier, channelIdentifier)) + // channel identifier and connection hop length checked on msg.ValidateBasic() + _, found := k.GetChannel(ctx, portID, channelID) if found { return sdkerrors.Wrap(types.ErrChannelExists, channelID) @@ -47,26 +49,19 @@ func (k Keeper) ChanOpenInit( return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } - if connectionEnd.State == connection.UNINITIALIZED { + if connectionEnd.GetState() == connectionexported.UNINITIALIZED { return sdkerrors.Wrap( connection.ErrInvalidConnectionState, "connection state cannot be UNINITIALIZED", ) } - /* - // TODO: Maybe not right - key := sdk.NewKVStoreKey(portID) - - if !k.portKeeper.Authenticate(key, portID) { - return sdkerrors.Wrap(port.ErrInvalidPort, portID) - } - - */ - channel := types.NewChannel(types.INIT, order, counterparty, connectionHops, version) + channel := types.NewChannel(exported.INIT, order, counterparty, connectionHops, version) k.SetChannel(ctx, portID, channelID, channel) - // TODO: generate channel capability key and set it to store + // TODO: blocked by #5542 + // key := "" + // k.SetChannelCapability(ctx, portID, channelID, key) k.SetNextSequenceSend(ctx, portID, channelID, 1) k.SetNextSequenceRecv(ctx, portID, channelID, 1) @@ -77,7 +72,7 @@ func (k Keeper) ChanOpenInit( // handshake initiated by a module on another chain. func (k Keeper) ChanOpenTry( ctx sdk.Context, - order types.Order, + order exported.Order, connectionHops []string, portID, channelID string, @@ -87,37 +82,43 @@ func (k Keeper) ChanOpenTry( proofInit commitment.ProofI, proofHeight uint64, ) error { - _, found := k.GetChannel(ctx, portID, channelID) - if found { - return sdkerrors.Wrap(types.ErrChannelExists, channelID) - } - - // TODO: Maybe not right - key := sdk.NewKVStoreKey(portID) + // channel identifier and connection hop length checked on msg.ValidateBasic() - if !k.portKeeper.Authenticate(key, portID) { - return sdkerrors.Wrap(port.ErrInvalidPort, portID) + previousChannel, found := k.GetChannel(ctx, portID, channelID) + if found && !(previousChannel.State == exported.INIT && + previousChannel.Ordering == order && + previousChannel.Counterparty.PortID == counterparty.PortID && + previousChannel.Counterparty.ChannelID == counterparty.ChannelID && + previousChannel.ConnectionHops[0] == connectionHops[0] && + previousChannel.Version == version) { + sdkerrors.Wrap(types.ErrInvalidChannel, "cannot relay connection attempt") } + // TODO: blocked by #5542 + // key := sdk.NewKVStoreKey(portID) + // if !k.portKeeper.Authenticate(key, portID) { + // return sdkerrors.Wrap(port.ErrInvalidPort, portID) + // } + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } - if connectionEnd.State != connection.OPEN { + if connectionEnd.GetState() != connectionexported.OPEN { return sdkerrors.Wrapf( connection.ErrInvalidConnectionState, - "connection state is not OPEN (got %s)", connectionEnd.State.String(), + "connection state is not OPEN (got %s)", connectionEnd.GetState().String(), ) } // NOTE: this step has been switched with the one below to reverse the connection // hops - channel := types.NewChannel(types.TRYOPEN, order, counterparty, connectionHops, version) + channel := types.NewChannel(exported.TRYOPEN, order, counterparty, connectionHops, version) counterpartyHops, found := k.CounterpartyHops(ctx, channel) if !found { - // Should not reach here, connectionEnd was able to be retrieved above + // should not reach here, connectionEnd was able to be retrieved above panic("cannot find connection") } @@ -125,26 +126,29 @@ func (k Keeper) ChanOpenTry( // (i.e self) expectedCounterparty := types.NewCounterparty(portID, channelID) expectedChannel := types.NewChannel( - types.INIT, channel.Ordering, expectedCounterparty, + exported.INIT, channel.Ordering, expectedCounterparty, counterpartyHops, channel.Version, ) - bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) - if err != nil { - return err + consensusState, found := k.clientKeeper.GetConsensusState( + ctx, connectionEnd.GetClientID(), proofHeight, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound } - if !k.connectionKeeper.VerifyMembership( + if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofInit, - types.ChannelPath(counterparty.PortID, counterparty.ChannelID), - bz, - ) { - return sdkerrors.Wrap(types.ErrInvalidCounterparty, "channel membership verification failed") + counterparty.PortID, counterparty.ChannelID, expectedChannel, consensusState, + ); err != nil { + return err } k.SetChannel(ctx, portID, channelID, channel) - // TODO: generate channel capability key and set it to store + // TODO: blocked by #5542 + // key := "" + // k.SetChannelCapability(ctx, portID, channelID, key) k.SetNextSequenceSend(ctx, portID, channelID, 1) k.SetNextSequenceRecv(ctx, portID, channelID, 1) @@ -166,61 +170,60 @@ func (k Keeper) ChanOpenAck( return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } - if channel.State != types.INIT { + if !(channel.State == exported.INIT || channel.State == exported.TRYOPEN) { return sdkerrors.Wrapf( types.ErrInvalidChannelState, - "channel state is not INIT (got %s)", channel.State.String(), + "channel state should be INIT or TRYOPEN (got %s)", channel.State.String(), ) } - // TODO: Maybe not right - key := sdk.NewKVStoreKey(portID) - - if !k.portKeeper.Authenticate(key, portID) { - return sdkerrors.Wrap(port.ErrInvalidPort, portID) - } + // TODO: blocked by #5542 + // key := sdk.NewKVStoreKey(portID) + // if !k.portKeeper.Authenticate(key, portID) { + // return sdkerrors.Wrap(port.ErrInvalidPort, portID) + // } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } - if connectionEnd.State != connection.OPEN { + if connectionEnd.GetState() != connectionexported.OPEN { return sdkerrors.Wrapf( connection.ErrInvalidConnectionState, - "connection state is not OPEN (got %s)", connectionEnd.State.String(), + "connection state is not OPEN (got %s)", connectionEnd.GetState().String(), ) } counterpartyHops, found := k.CounterpartyHops(ctx, channel) if !found { - // Should not reach here, connectionEnd was able to be retrieved above + // should not reach here, connectionEnd was able to be retrieved above panic("cannot find connection") } // counterparty of the counterparty channel end (i.e self) counterparty := types.NewCounterparty(portID, channelID) expectedChannel := types.NewChannel( - types.TRYOPEN, channel.Ordering, counterparty, + exported.TRYOPEN, channel.Ordering, counterparty, counterpartyHops, channel.Version, ) - bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) - if err != nil { - return err + consensusState, found := k.clientKeeper.GetConsensusState( + ctx, connectionEnd.GetClientID(), proofHeight, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound } - if !k.connectionKeeper.VerifyMembership( + if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofTry, - types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), - bz, - ) { - return sdkerrors.Wrap( - types.ErrInvalidCounterparty, "channel membership verification failed", - ) + channel.Counterparty.PortID, channel.Counterparty.ChannelID, + expectedChannel, consensusState, + ); err != nil { + return err } - channel.State = types.OPEN + channel.State = exported.OPEN channel.Version = counterpartyVersion k.SetChannel(ctx, portID, channelID, channel) @@ -241,29 +244,33 @@ func (k Keeper) ChanOpenConfirm( return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } - if channel.State != types.TRYOPEN { + if channel.State != exported.TRYOPEN { return sdkerrors.Wrapf( types.ErrInvalidChannelState, - "channel state is not OPENTRY (got %s)", channel.State.String(), + "channel state is not TRYOPEN (got %s)", channel.State.String(), ) } - // TODO: Maybe not right - key := sdk.NewKVStoreKey(portID) + // TODO: blocked by #5542 + // capkey, found := k.GetChannelCapability(ctx, portID, channelID) + // if !found { + // return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID) + // } - if !k.portKeeper.Authenticate(key, portID) { - return sdkerrors.Wrap(port.ErrInvalidPort, portID) - } + // key := sdk.NewKVStoreKey(capkey) + // if !k.portKeeper.Authenticate(key, portID) { + // return sdkerrors.Wrap(port.ErrInvalidPort, portID) + // } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } - if connectionEnd.State != connection.OPEN { + if connectionEnd.GetState() != connectionexported.OPEN { return sdkerrors.Wrapf( connection.ErrInvalidConnectionState, - "connection state is not OPEN (got %s)", connectionEnd.State.String(), + "connection state is not OPEN (got %s)", connectionEnd.GetState().String(), ) } @@ -275,24 +282,26 @@ func (k Keeper) ChanOpenConfirm( counterparty := types.NewCounterparty(portID, channelID) expectedChannel := types.NewChannel( - types.OPEN, channel.Ordering, counterparty, + exported.OPEN, channel.Ordering, counterparty, counterpartyHops, channel.Version, ) - bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) - if err != nil { - return err + consensusState, found := k.clientKeeper.GetConsensusState( + ctx, connectionEnd.GetClientID(), proofHeight, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound } - if !k.connectionKeeper.VerifyMembership( + if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofAck, - types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), - bz, - ) { - return sdkerrors.Wrap(types.ErrInvalidCounterparty, "channel membership verification failed") + channel.Counterparty.PortID, channel.Counterparty.ChannelID, + expectedChannel, consensusState, + ); err != nil { + return err } - channel.State = types.OPEN + channel.State = exported.OPEN k.SetChannel(ctx, portID, channelID, channel) return nil @@ -310,19 +319,23 @@ func (k Keeper) ChanCloseInit( portID, channelID string, ) error { - // TODO: Maybe not right - key := sdk.NewKVStoreKey(portID) + // TODO: blocked by #5542 + // capkey, found := k.GetChannelCapability(ctx, portID, channelID) + // if !found { + // return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID) + // } - if !k.portKeeper.Authenticate(key, portID) { - return sdkerrors.Wrap(port.ErrInvalidPort, portID) - } + // key := sdk.NewKVStoreKey(capkey) + // if !k.portKeeper.Authenticate(key, portID) { + // return sdkerrors.Wrap(port.ErrInvalidPort, portID) + // } channel, found := k.GetChannel(ctx, portID, channelID) if !found { return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } - if channel.State == types.CLOSED { + if channel.State == exported.CLOSED { return sdkerrors.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") } @@ -331,14 +344,14 @@ func (k Keeper) ChanCloseInit( return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } - if connectionEnd.State != connection.OPEN { + if connectionEnd.GetState() != connectionexported.OPEN { return sdkerrors.Wrapf( connection.ErrInvalidConnectionState, - "connection state is not OPEN (got %s)", connectionEnd.State.String(), + "connection state is not OPEN (got %s)", connectionEnd.GetState().String(), ) } - channel.State = types.CLOSED + channel.State = exported.CLOSED k.SetChannel(ctx, portID, channelID, channel) return nil @@ -353,19 +366,23 @@ func (k Keeper) ChanCloseConfirm( proofInit commitment.ProofI, proofHeight uint64, ) error { - // TODO: Maybe not right - key := sdk.NewKVStoreKey(portID) + // TODO: blocked by #5542 + // capkey, found := k.GetChannelCapability(ctx, portID, channelID) + // if !found { + // return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID) + // } - if !k.portKeeper.Authenticate(key, portID) { - return sdkerrors.Wrap(port.ErrInvalidPort, portID) - } + // key := sdk.NewKVStoreKey(capkey) + // if !k.portKeeper.Authenticate(key, portID) { + // return sdkerrors.Wrap(port.ErrInvalidPort, portID) + // } channel, found := k.GetChannel(ctx, portID, channelID) if !found { return sdkerrors.Wrap(types.ErrChannelNotFound, channelID) } - if channel.State == types.CLOSED { + if channel.State == exported.CLOSED { return sdkerrors.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") } @@ -374,10 +391,10 @@ func (k Keeper) ChanCloseConfirm( return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } - if connectionEnd.State != connection.OPEN { + if connectionEnd.GetState() != connectionexported.OPEN { return sdkerrors.Wrapf( connection.ErrInvalidConnectionState, - "connection state is not OPEN (got %s)", connectionEnd.State.String(), + "connection state is not OPEN (got %s)", connectionEnd.GetState().String(), ) } @@ -389,24 +406,26 @@ func (k Keeper) ChanCloseConfirm( counterparty := types.NewCounterparty(portID, channelID) expectedChannel := types.NewChannel( - types.CLOSED, channel.Ordering, counterparty, + exported.CLOSED, channel.Ordering, counterparty, counterpartyHops, channel.Version, ) - bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) - if err != nil { - return errors.New("failed to marshal expected channel") + consensusState, found := k.clientKeeper.GetConsensusState( + ctx, connectionEnd.GetClientID(), proofHeight, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound } - if !k.connectionKeeper.VerifyMembership( + if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofInit, - types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), - bz, - ) { - return sdkerrors.Wrap(types.ErrInvalidCounterparty, "channel membership verification failed") + channel.Counterparty.PortID, channel.Counterparty.ChannelID, + expectedChannel, consensusState, + ); err != nil { + return err } - channel.State = types.CLOSED + channel.State = exported.CLOSED k.SetChannel(ctx, portID, channelID, channel) return nil diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 4e39b906eb44..aee68d6cd00c 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -3,331 +3,423 @@ package keeper_test import ( "fmt" - abci "github.com/tendermint/tendermint/abci/types" - - sdk "github.com/cosmos/cosmos-sdk/types" - clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" - connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) -func (suite *KeeperTestSuite) createClient() { - suite.app.Commit() - commitID := suite.app.LastCommitID() - - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - - consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, - NextValidatorSet: suite.valSet, - } - - _ = consensusState.GetCommitter() - - _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) - suite.NoError(err) -} - -func (suite *KeeperTestSuite) updateClient() { - // always commit and begin a new block on updateClient - suite.app.Commit() - commitID := suite.app.LastCommitID() - - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - - state := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), - } - - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) - suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) -} - -func (suite *KeeperTestSuite) createConnection(state connection.State) { - connection := connection.ConnectionEnd{ - State: state, - ClientID: testClient, - Counterparty: connection.Counterparty{ - ClientID: testClient, - ConnectionID: testConnection, - Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), - }, - Versions: connection.GetCompatibleVersions(), - } - - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) -} - -func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state types.State) { - channel := types.Channel{ - State: state, - Ordering: testChannelOrder, - Counterparty: types.Counterparty{ - PortID: counterpartyPort, - ChannelID: counterpartyChan, - }, - ConnectionHops: []string{connID}, - Version: testChannelVersion, - } - - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, channel) -} - -func (suite *KeeperTestSuite) deleteChannel(portID string, chanID string) { - store := suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)) - store.Delete(types.KeyChannel(portID, chanID)) -} - -func (suite *KeeperTestSuite) bindPort(portID string) sdk.CapabilityKey { - return suite.app.IBCKeeper.PortKeeper.BindPort(portID) -} - -func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { - res := suite.app.Query(abci.RequestQuery{ - Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: key, - Prove: true, - }) - - height = res.Height - proof = commitment.Proof{ - Proof: res.Proof, - } - - return -} - func (suite *KeeperTestSuite) TestChanOpenInit() { counterparty := types.NewCounterparty(testPort2, testChannel2) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.Error(err) // channel has already exist - - suite.deleteChannel(testPort1, testChannel1) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.Error(err) // connection does not exist - - suite.createConnection(connection.UNINITIALIZED) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.Error(err) // invalid connection state - - suite.createConnection(connection.OPEN) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.NoError(err) // successfully executed + testCases := []testCase{ + {"success", func() { + suite.createConnection( + testConnectionID1, testConnectionID2, testClientID1, testClientID2, + connectionexported.INIT, + ) + }, true}, + {"channel already exists", func() { + suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.INIT, + exported.ORDERED, testConnectionID1, + ) + }, false}, + {"connection doesn't exist", func() {}, false}, + {"connection is UNINITIALIZED", func() { + suite.createConnection( + testConnectionID1, testConnectionID2, testClientID1, testClientID2, + connectionexported.UNINITIALIZED, + ) + }, false}, + } - channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) - suite.True(found) - suite.Equal(types.INIT.String(), channel.State.String(), "invalid channel state") + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit( + suite.ctx, exported.ORDERED, []string{testConnectionID1}, + testPort1, testChannel1, counterparty, testChannelVersion, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } } func (suite *KeeperTestSuite) TestChanOpenTry() { counterparty := types.NewCounterparty(testPort1, testChannel1) - suite.bindPort(testPort2) - channelKey := types.KeyChannel(testPort1, testChannel1) - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.INIT) - suite.updateClient() - proofInit, proofHeight := suite.queryProof(channelKey) - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.Error(err) // channel has already exist - - suite.deleteChannel(testPort2, testChannel2) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.Error(err) // unauthenticated port - - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.Error(err) // connection does not exist - suite.createConnection(connection.UNINITIALIZED) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.Error(err) // invalid connection state - - suite.createConnection(connection.OPEN) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.TRYOPEN) - suite.updateClient() - proofInit, proofHeight = suite.queryProof(channelKey) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.Error(err) // channel membership verification failed due to invalid counterparty - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) - suite.updateClient() - proofInit, proofHeight = suite.queryProof(channelKey) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight)) - suite.NoError(err) // successfully executed + testCases := []testCase{ + {"success", func() { + suite.createClient(testClientID2) + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.OPEN, + ) + }, true}, + {"previous channel with invalid state", func() { + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.UNINITIALIZED, + exported.ORDERED, testConnectionID2, + ) + }, false}, + {"connection doesn't exist", func() {}, false}, + {"connection is not OPEN", func() { + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.INIT, + ) + }, false}, + {"consensus state not found", func() { + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.OPEN, + ) + }, false}, + {"channel verification failed", func() { + suite.createClient(testClientID2) + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.OPEN, + ) + }, false}, + } - channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) - suite.True(found) - suite.Equal(types.TRYOPEN.String(), channel.State.String(), "invalid channel state") + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + + if tc.expPass { + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry( + suite.ctx, exported.ORDERED, []string{testConnectionID2}, + testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, + validProof{}, uint64(suite.ctx.BlockHeight()), + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry( + suite.ctx, exported.ORDERED, []string{testConnectionID2}, + testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, + invalidProof{}, uint64(suite.ctx.BlockHeight()), + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } } func (suite *KeeperTestSuite) TestChanOpenAck() { - suite.bindPort(testPort1) - channelKey := types.KeyChannel(testPort2, testChannel2) - - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.TRYOPEN) - suite.updateClient() - proofTry, proofHeight := suite.queryProof(channelKey) - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.Error(err) // channel does not exist - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.Error(err) // invalid channel state - - suite.createChannel(testPort2, testChannel1, testConnection, testPort1, testChannel2, types.INIT) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort2, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.Error(err) // unauthenticated port - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.Error(err) // connection does not exist - - suite.createConnection(connection.UNINITIALIZED) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.Error(err) // invalid connection state - - suite.createConnection(connection.OPEN) - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) - suite.updateClient() - proofTry, proofHeight = suite.queryProof(channelKey) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.Error(err) // channel membership verification failed due to invalid counterparty - - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.TRYOPEN) - suite.updateClient() - proofTry, proofHeight = suite.queryProof(channelKey) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight)) - suite.NoError(err) // successfully executed + testCases := []testCase{ + {"success", func() { + suite.createClient(testClientID1) + _ = suite.createConnection( + testConnectionID1, testConnectionID2, testClientID1, testClientID2, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, + exported.ORDERED, testConnectionID1, + ) + }, true}, + {"channel doesn't exist", func() {}, false}, + {"channel state is not INIT or TRYOPEN", func() { + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.UNINITIALIZED, + exported.ORDERED, testConnectionID1, + ) + }, false}, + {"connection not found", func() { + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, + exported.ORDERED, testConnectionID1, + ) + }, false}, + {"connection is not OPEN", func() { + _ = suite.createConnection( + testConnectionID1, testConnectionID2, testClientID1, testClientID2, + connectionexported.TRYOPEN, + ) + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, + exported.ORDERED, testConnectionID1, + ) + }, false}, + {"consensus state not found", func() { + _ = suite.createConnection( + testConnectionID1, testConnectionID2, testClientID1, testClientID2, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, + exported.ORDERED, testConnectionID1, + ) + }, false}, + {"channel verification failed", func() { + suite.createClient(testClientID1) + _ = suite.createConnection( + testConnectionID1, testConnectionID2, testClientID1, testClientID2, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, + exported.ORDERED, testConnectionID1, + ) + }, false}, + } - channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) - suite.True(found) - suite.Equal(types.OPEN.String(), channel.State.String(), "invalid channel state") + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + + if tc.expPass { + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck( + suite.ctx, testPort1, testChannel1, testChannelVersion, + validProof{}, uint64(suite.ctx.BlockHeight()), + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck( + suite.ctx, testPort1, testChannel1, testChannelVersion, + invalidProof{}, uint64(suite.ctx.BlockHeight()), + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } } func (suite *KeeperTestSuite) TestChanOpenConfirm() { - suite.bindPort(testPort2) - channelKey := types.KeyChannel(testPort1, testChannel1) - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) - suite.updateClient() - proofAck, proofHeight := suite.queryProof(channelKey) - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.Error(err) // channel does not exist - - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.Error(err) // invalid channel state - - suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.TRYOPEN) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort1, testChannel2, proofAck, uint64(proofHeight)) - suite.Error(err) // unauthenticated port - - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.TRYOPEN) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.Error(err) // connection does not exist - - suite.createConnection(connection.UNINITIALIZED) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.Error(err) // invalid connection state - - suite.createConnection(connection.OPEN) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.TRYOPEN) - suite.updateClient() - proofAck, proofHeight = suite.queryProof(channelKey) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.Error(err) // channel membership verification failed due to invalid counterparty - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) - suite.updateClient() - proofAck, proofHeight = suite.queryProof(channelKey) - err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight)) - suite.NoError(err) // successfully executed + testCases := []testCase{ + {"success", func() { + suite.createClient(testClientID2) + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, + exported.ORDERED, testConnectionID2, + ) + }, true}, + {"channel doesn't exist", func() {}, false}, + {"channel state is not TRYOPEN", func() { + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.UNINITIALIZED, + exported.ORDERED, testConnectionID2, + ) + }, false}, + {"connection not found", func() { + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, + exported.ORDERED, testConnectionID2, + ) + }, false}, + {"connection is not OPEN", func() { + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.TRYOPEN, + ) + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, + exported.ORDERED, testConnectionID2, + ) + }, false}, + {"consensus state not found", func() { + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, + exported.ORDERED, testConnectionID2, + ) + }, false}, + {"channel verification failed", func() { + suite.createClient(testClientID2) + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, + exported.ORDERED, testConnectionID2, + ) + }, false}, + } - channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) - suite.True(found) - suite.Equal(types.OPEN.String(), channel.State.String(), "invalid channel state") + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + + if tc.expPass { + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm( + suite.ctx, testPort2, testChannel2, + validProof{}, uint64(suite.ctx.BlockHeight()), + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm( + suite.ctx, testPort2, testChannel2, + invalidProof{}, uint64(suite.ctx.BlockHeight()), + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } } func (suite *KeeperTestSuite) TestChanCloseInit() { - suite.bindPort(testPort1) - - err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort2, testChannel1) - suite.Error(err) // authenticated port - - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.Error(err) // channel does not exist - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.Error(err) // channel is already closed - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.Error(err) // connection does not exist - - suite.createConnection(connection.TRYOPEN) - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.Error(err) // invalid connection state - - suite.createConnection(connection.OPEN) - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1) - suite.NoError(err) // successfully executed + testCases := []testCase{ + {"success", func() { + suite.createClient(testClientID1) + _ = suite.createConnection( + testConnectionID1, testConnectionID2, testClientID1, testClientID2, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, + exported.ORDERED, testConnectionID1, + ) + }, true}, + {"channel doesn't exist", func() {}, false}, + {"channel state is CLOSED", func() { + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, + exported.ORDERED, testConnectionID2, + ) + }, false}, + {"connection not found", func() { + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, + exported.ORDERED, testConnectionID1, + ) + }, false}, + {"connection is not OPEN", func() { + _ = suite.createConnection( + testConnectionID1, testConnectionID2, testClientID1, testClientID2, + connectionexported.TRYOPEN, + ) + _ = suite.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.UNINITIALIZED, + exported.ORDERED, testConnectionID1, + ) + }, false}, + } - channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) - suite.True(found) - suite.Equal(types.CLOSED.String(), channel.State.String(), "invalid channel state") + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit( + suite.ctx, testPort1, testChannel1, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } } func (suite *KeeperTestSuite) TestChanCloseConfirm() { - suite.bindPort(testPort2) - channelKey := types.KeyChannel(testPort1, testChannel1) - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) - suite.updateClient() - proofInit, proofHeight := suite.queryProof(channelKey) - err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort1, testChannel2, proofInit, uint64(proofHeight)) - suite.Error(err) // unauthenticated port - - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.Error(err) // channel does not exist - - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.CLOSED) - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.Error(err) // channel is already closed - - suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN) - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.Error(err) // connection does not exist - - suite.createConnection(connection.TRYOPEN) - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.Error(err) // invalid connection state - - suite.createConnection(connection.OPEN) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN) - suite.updateClient() - proofInit, proofHeight = suite.queryProof(channelKey) - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.Error(err) // channel membership verification failed due to invalid counterparty + testCases := []testCase{ + {"success", func() { + suite.createClient(testClientID2) + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, + exported.ORDERED, testConnectionID2, + ) + }, true}, + {"channel doesn't exist", func() {}, false}, + {"channel state is CLOSED", func() { + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.CLOSED, + exported.ORDERED, testConnectionID2, + ) + }, false}, + {"connection not found", func() { + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, + exported.ORDERED, testConnectionID1, + ) + }, false}, + {"connection is not OPEN", func() { + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.TRYOPEN, + ) + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, + exported.ORDERED, testConnectionID2, + ) + }, false}, + {"consensus state not found", func() { + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, + exported.ORDERED, testConnectionID2, + ) + }, false}, + {"channel verification failed", func() { + suite.createClient(testClientID2) + _ = suite.createConnection( + testConnectionID2, testConnectionID1, testClientID2, testClientID1, + connectionexported.OPEN, + ) + _ = suite.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, + exported.ORDERED, testConnectionID2, + ) + }, false}, + } - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED) - suite.updateClient() - proofInit, proofHeight = suite.queryProof(channelKey) - err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight)) - suite.NoError(err) // successfully executed + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + + if tc.expPass { + err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm( + suite.ctx, testPort2, testChannel2, + validProof{}, uint64(suite.ctx.BlockHeight()), + ) + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm( + suite.ctx, testPort2, testChannel2, + invalidProof{}, uint64(suite.ctx.BlockHeight()), + ) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } +} - channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2) - suite.True(found) - suite.Equal(types.CLOSED.String(), channel.State.String(), "invalid channel state") +type testCase = struct { + msg string + malleate func() + expPass bool } diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index 92b1a3bca1f1..ab756c044971 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -44,7 +44,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetChannel returns a channel with a particular identifier binded to a specific port func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyChannel(portID, channelID)) + bz := store.Get(ibctypes.KeyChannel(portID, channelID)) if bz == nil { return types.Channel{}, false } @@ -58,13 +58,13 @@ func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Cha func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel types.Channel) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(channel) - store.Set(types.KeyChannel(portID, channelID), bz) + store.Set(ibctypes.KeyChannel(portID, channelID), bz) } // GetChannelCapability gets a channel's capability key from the store func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) (string, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyChannelCapabilityPath(portID, channelID)) + bz := store.Get(ibctypes.KeyChannelCapabilityPath(portID, channelID)) if bz == nil { return "", false } @@ -75,13 +75,13 @@ func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) // SetChannelCapability sets a channel's capability key to the store func (k Keeper) SetChannelCapability(ctx sdk.Context, portID, channelID string, key string) { store := ctx.KVStore(k.storeKey) - store.Set(types.KeyChannelCapabilityPath(portID, channelID), []byte(key)) + store.Set(ibctypes.KeyChannelCapabilityPath(portID, channelID), []byte(key)) } // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyNextSequenceSend(portID, channelID)) + bz := store.Get(ibctypes.KeyNextSequenceSend(portID, channelID)) if bz == nil { return 0, false } @@ -93,13 +93,13 @@ func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) ( func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, sequence uint64) { store := ctx.KVStore(k.storeKey) bz := sdk.Uint64ToBigEndian(sequence) - store.Set(types.KeyNextSequenceSend(portID, channelID), bz) + store.Set(ibctypes.KeyNextSequenceSend(portID, channelID), bz) } // GetNextSequenceRecv gets a channel's next receive sequence from the store func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyNextSequenceRecv(portID, channelID)) + bz := store.Get(ibctypes.KeyNextSequenceRecv(portID, channelID)) if bz == nil { return 0, false } @@ -111,37 +111,37 @@ func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) ( func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, sequence uint64) { store := ctx.KVStore(k.storeKey) bz := sdk.Uint64ToBigEndian(sequence) - store.Set(types.KeyNextSequenceRecv(portID, channelID), bz) + store.Set(ibctypes.KeyNextSequenceRecv(portID, channelID), bz) } // GetPacketCommitment gets the packet commitment hash from the store func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyPacketCommitment(portID, channelID, sequence)) + bz := store.Get(ibctypes.KeyPacketCommitment(portID, channelID, sequence)) return bz } // SetPacketCommitment sets the packet commitment hash to the store func (k Keeper) SetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64, commitmentHash []byte) { store := ctx.KVStore(k.storeKey) - store.Set(types.KeyPacketCommitment(portID, channelID, sequence), commitmentHash) + store.Set(ibctypes.KeyPacketCommitment(portID, channelID, sequence), commitmentHash) } func (k Keeper) deletePacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) { store := ctx.KVStore(k.storeKey) - store.Delete(types.KeyPacketCommitment(portID, channelID, sequence)) + store.Delete(ibctypes.KeyPacketCommitment(portID, channelID, sequence)) } // SetPacketAcknowledgement sets the packet ack hash to the store func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64, ackHash []byte) { store := ctx.KVStore(k.storeKey) - store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) + store.Set(ibctypes.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash) } // GetPacketAcknowledgement gets the packet ack hash from the store func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.KeyPacketAcknowledgement(portID, channelID, sequence)) + bz := store.Get(ibctypes.KeyPacketAcknowledgement(portID, channelID, sequence)) if bz == nil { return nil, false } @@ -153,7 +153,7 @@ func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID stri // and stop. func (k Keeper) IterateChannels(ctx sdk.Context, cb func(types.Channel) bool) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types.GetChannelKeysPrefix(ibctypes.KeyChannelPrefix)) + iterator := sdk.KVStorePrefixIterator(store, ibctypes.GetChannelPortsKeysPrefix(ibctypes.KeyChannelPrefix)) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index b8159d760bc4..b502bbfe7347 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -1,6 +1,8 @@ package keeper_test import ( + "errors" + "fmt" "testing" "github.com/stretchr/testify/suite" @@ -11,16 +13,24 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // define constants used for testing const ( - testChainID = "test-chain-id" - testClient = "test-client" testClientType = clientexported.Tendermint - testConnection = "testconnection" + testClientID1 = "testclientidone" + testConnectionID1 = "connectionidone" + + testClientID2 = "testclientidtwo" + testConnectionID2 = "connectionidtwo" testPort1 = "firstport" testPort2 = "secondport" @@ -30,7 +40,7 @@ const ( testChannel2 = "secondchannel" testChannel3 = "thirdchannel" - testChannelOrder = types.ORDERED + testChannelOrder = exported.ORDERED testChannelVersion = "1.0" ) @@ -55,8 +65,6 @@ func (suite *KeeperTestSuite) SetupTest() { validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - suite.createClient() } func (suite *KeeperTestSuite) TestSetChannel() { @@ -64,13 +72,13 @@ func (suite *KeeperTestSuite) TestSetChannel() { suite.False(found) channel := types.Channel{ - State: types.OPEN, + State: exported.OPEN, Ordering: testChannelOrder, Counterparty: types.Counterparty{ PortID: testPort2, ChannelID: testChannel2, }, - ConnectionHops: []string{testConnection}, + ConnectionHops: []string{testConnectionID1}, Version: testChannelVersion, } suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort1, testChannel1, channel) @@ -87,26 +95,26 @@ func (suite KeeperTestSuite) TestGetAllChannels() { counterparty3 := types.NewCounterparty(testPort3, testChannel3) channel1 := types.Channel{ - State: types.INIT, + State: exported.INIT, Ordering: testChannelOrder, Counterparty: counterparty3, - ConnectionHops: []string{testConnection}, + ConnectionHops: []string{testConnectionID1}, Version: testChannelVersion, } channel2 := types.Channel{ - State: types.INIT, + State: exported.INIT, Ordering: testChannelOrder, Counterparty: counterparty1, - ConnectionHops: []string{testConnection}, + ConnectionHops: []string{testConnectionID1}, Version: testChannelVersion, } channel3 := types.Channel{ - State: types.CLOSED, + State: exported.CLOSED, Ordering: testChannelOrder, Counterparty: counterparty2, - ConnectionHops: []string{testConnection}, + ConnectionHops: []string{testConnectionID1}, Version: testChannelVersion, } @@ -183,3 +191,138 @@ func (suite *KeeperTestSuite) TestSetPacketAcknowledgement() { func TestKeeperTestSuite(t *testing.T) { suite.Run(t, new(KeeperTestSuite)) } + +func (suite *KeeperTestSuite) createClient(clientID string) { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{Height: suite.app.LastBlockHeight()}) + + consensusState := tendermint.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), + ValidatorSetHash: suite.valSet.Hash(), + } + + _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, testClientType, consensusState) + suite.Require().NoError(err) +} + +// nolint: unused +func (suite *KeeperTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + height := suite.app.LastBlockHeight() + 1 + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: height}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{Height: suite.app.LastBlockHeight()}) + + state := tendermint.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClientID1, uint64(height-1), state) + csi, _ := suite.app.IBCKeeper.ClientKeeper.GetClientState(suite.ctx, testClientID1) + cs, _ := csi.(tendermint.ClientState) + cs.LatestHeight = uint64(height - 1) + suite.app.IBCKeeper.ClientKeeper.SetClientState(suite.ctx, cs) +} + +func (suite *KeeperTestSuite) createConnection( + connID, counterpartyConnID, clientID, counterpartyClientID string, + state connectionexported.State, +) connectiontypes.ConnectionEnd { + counterparty := connectiontypes.NewCounterparty(counterpartyClientID, counterpartyConnID, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + connection := connectiontypes.ConnectionEnd{ + State: state, + ClientID: clientID, + Counterparty: counterparty, + Versions: connectiontypes.GetCompatibleVersions(), + } + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, connID, connection) + return connection +} + +func (suite *KeeperTestSuite) createChannel( + portID, channelID, counterpartyPortID, counterpartyChannelID string, + state exported.State, order exported.Order, connectionID string, +) types.Channel { + counterparty := types.NewCounterparty(counterpartyPortID, counterpartyChannelID) + channel := types.NewChannel(state, order, counterparty, + []string{connectionID}, "1.0", + ) + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, channelID, channel) + return channel +} + +// nolint: unused +func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Height: suite.app.LastBlockHeight(), + Data: key, + Prove: true, + }) + + proof := commitment.Proof{ + Proof: res.Proof, + } + + return proof, res.Height +} + +// Mocked types +// TODO: fix tests and replace for real proofs + +var ( + _ commitment.ProofI = validProof{} + _ commitment.ProofI = invalidProof{} +) + +type ( + validProof struct{} + invalidProof struct{} +) + +func (validProof) GetCommitmentType() commitment.Type { + return commitment.Merkle +} + +func (validProof) VerifyMembership( + root commitment.RootI, path commitment.PathI, value []byte) error { + return nil +} + +func (validProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { + return nil +} + +func (validProof) ValidateBasic() error { + return nil +} + +func (validProof) IsEmpty() bool { + return false +} + +func (invalidProof) GetCommitmentType() commitment.Type { + return commitment.Merkle +} + +func (invalidProof) VerifyMembership( + root commitment.RootI, path commitment.PathI, value []byte) error { + return errors.New("proof failed") +} + +func (invalidProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { + return errors.New("proof failed") +} + +func (invalidProof) ValidateBasic() error { + return errors.New("invalid proof") +} + +func (invalidProof) IsEmpty() bool { + return true +} diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index a2db8d3f66a2..1c6ee2a5711e 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -2,118 +2,25 @@ package keeper import ( "bytes" - "errors" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -// CleanupPacket is called by a module to remove a received packet commitment -// from storage. The receiving end must have already processed the packet -// (whether regularly or past timeout). -// -// In the ORDERED channel case, CleanupPacket cleans-up a packet on an ordered -// channel by proving that the packet has been received on the other end. -// -// In the UNORDERED channel case, CleanupPacket cleans-up a packet on an -// unordered channel by proving that the associated acknowledgement has been -//written. -func (k Keeper) CleanupPacket( - ctx sdk.Context, - packet exported.PacketI, - proof commitment.ProofI, - proofHeight, - nextSequenceRecv uint64, - acknowledgement []byte, - portCapability sdk.CapabilityKey, -) (exported.PacketI, error) { - channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) - if !found { - return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) - } - - if channel.State != types.OPEN { - return nil, sdkerrors.Wrapf( - types.ErrInvalidChannelState, - "channel state is not OPEN (got %s)", channel.State.String(), - ) - } - - _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) - if !found { - return nil, types.ErrChannelCapabilityNotFound - } - - if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return nil, sdkerrors.Wrapf(port.ErrInvalidPort, "invalid source port: %s", packet.GetSourcePort()) - } - - if packet.GetDestChannel() != channel.Counterparty.ChannelID { - return nil, sdkerrors.Wrapf( - types.ErrInvalidPacket, - "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, - ) - } - - connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) - if !found { - return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) - } - - if packet.GetDestPort() != channel.Counterparty.PortID { - return nil, sdkerrors.Wrapf(types.ErrInvalidPacket, - "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, - ) - } - - if nextSequenceRecv >= packet.GetSequence() { - return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet already received") - } - - commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { - return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") - } - - var ok bool - switch channel.Ordering { - case types.ORDERED: - ok = k.connectionKeeper.VerifyMembership( - ctx, connectionEnd, proofHeight, proof, - types.NextSequenceRecvPath(packet.GetDestPort(), packet.GetDestChannel()), - sdk.Uint64ToBigEndian(nextSequenceRecv), - ) - case types.UNORDERED: - ok = k.connectionKeeper.VerifyMembership( - ctx, connectionEnd, proofHeight, proof, - types.PacketAcknowledgementPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), - acknowledgement, - ) - default: - panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) - } - - if !ok { - return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet verification failed") - } - - k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - return packet, nil -} - // SendPacket is called by a module in order to send an IBC packet on a channel // end owned by the calling module to the corresponding module on the counterparty // chain. func (k Keeper) SendPacket( ctx sdk.Context, packet exported.PacketI, - portCapability sdk.CapabilityKey, ) error { if err := packet.ValidateBasic(); err != nil { return err @@ -124,16 +31,24 @@ func (k Keeper) SendPacket( return sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } - if channel.State == types.CLOSED { + if channel.State == exported.CLOSED { return sdkerrors.Wrapf( types.ErrInvalidChannelState, "channel is CLOSED (got %s)", channel.State.String(), ) } - if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return sdkerrors.Wrap(port.ErrInvalidPort, packet.GetSourcePort()) - } + // TODO: blocked by #5542 + // capKey, found := k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + // if !found { + // return types.ErrChannelCapabilityNotFound + // } + + // portCapabilityKey := sdk.NewKVStoreKey(capKey) + + // if !k.portKeeper.Authenticate(portCapabilityKey, packet.GetSourcePort()) { + // return sdkerrors.Wrap(port.ErrInvalidPort, packet.GetSourcePort()) + // } if packet.GetDestPort() != channel.Counterparty.PortID { return sdkerrors.Wrapf( @@ -154,20 +69,22 @@ func (k Keeper) SendPacket( return sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } - if connectionEnd.State == connection.UNINITIALIZED { + // NOTE: assume UNINITIALIZED is a closed connection + if connectionEnd.GetState() == connectionexported.UNINITIALIZED { return sdkerrors.Wrap( connection.ErrInvalidConnectionState, "connection is closed (i.e NONE)", ) } - _, found = k.clientKeeper.GetConsensusState(ctx, connectionEnd.ClientID) + clientState, found := k.clientKeeper.GetClientState(ctx, connectionEnd.GetClientID()) if !found { return client.ErrConsensusStateNotFound } - if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { - return types.ErrPacketTimeout + // check if packet timeouted on the receiving chain + if clientState.GetLatestHeight() >= packet.GetTimeoutHeight() { + return sdkerrors.Wrap(types.ErrPacketTimeout, "timeout already passed ond the receiving chain") } nextSequenceSend, found := k.GetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) @@ -186,6 +103,7 @@ func (k Keeper) SendPacket( k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend) k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), types.CommitPacket(packet.GetData())) + k.Logger(ctx).Info(fmt.Sprintf("packet sent %v", packet)) // TODO: use packet.String() return nil } @@ -197,20 +115,19 @@ func (k Keeper) RecvPacket( proof commitment.ProofI, proofHeight uint64, ) (exported.PacketI, error) { - channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetDestChannel()) } - if channel.State != types.OPEN { + if channel.State != exported.OPEN { return nil, sdkerrors.Wrapf( types.ErrInvalidChannelState, "channel state is not OPEN (got %s)", channel.State.String(), ) } - // RecvPacket is called by the antehandler which acts upon the packet.Route(), + // NOTE: RecvPacket is called by the AnteHandler which acts upon the packet.Route(), // so the capability authentication can be omitted here // packet must come from the channel's counterparty @@ -233,37 +150,31 @@ func (k Keeper) RecvPacket( return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } - if connectionEnd.State != connection.OPEN { + if connectionEnd.GetState() != connectionexported.OPEN { return nil, sdkerrors.Wrapf( connection.ErrInvalidConnectionState, - "connection state is not OPEN (got %s)", connectionEnd.State.String(), + "connection state is not OPEN (got %s)", connectionEnd.GetState().String(), ) } - if channel.Ordering == types.ORDERED { - nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) - if !found { - return nil, types.ErrSequenceReceiveNotFound - } - - if packet.GetSequence() != nextSequenceRecv { - return nil, sdkerrors.Wrapf( - types.ErrInvalidPacket, - "packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv, - ) - } - } - + // check if packet timeouted by comparing it with the latest height of the chain if uint64(ctx.BlockHeight()) >= packet.GetTimeoutHeight() { return nil, types.ErrPacketTimeout } - if !k.connectionKeeper.VerifyMembership( + consensusState, found := k.clientKeeper.GetConsensusState( + ctx, connectionEnd.GetClientID(), proofHeight, + ) + if !found { + return nil, clienttypes.ErrConsensusStateNotFound + } + + if err := k.connectionKeeper.VerifyPacketCommitment( ctx, connectionEnd, proofHeight, proof, - types.PacketCommitmentPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), - types.CommitPacket(packet.GetData()), - ) { - return nil, errors.New("couldn't verify counterparty packet commitment") + packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), + types.CommitPacket(packet.GetData()), consensusState, + ); err != nil { + return nil, sdkerrors.Wrap(err, "couldn't verify counterparty packet commitment") } return packet, nil @@ -282,21 +193,22 @@ func (k Keeper) PacketExecuted( return sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetDestChannel()) } - if channel.State != types.OPEN { + // sanity check + if channel.State != exported.OPEN { return sdkerrors.Wrapf( types.ErrInvalidChannelState, "channel state is not OPEN (got %s)", channel.State.String(), ) } - if acknowledgement != nil || channel.Ordering == types.UNORDERED { + if acknowledgement != nil || channel.Ordering == exported.UNORDERED { k.SetPacketAcknowledgement( ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), types.CommitAcknowledgement(acknowledgement), ) } - if channel.Ordering == types.ORDERED { + if channel.Ordering == exported.ORDERED { nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { return types.ErrSequenceReceiveNotFound @@ -314,6 +226,8 @@ func (k Keeper) PacketExecuted( k.SetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv) } + // log that a packet has been received & acknowledged + k.Logger(ctx).Info(fmt.Sprintf("packet received %v", packet)) // TODO: use packet.String() return nil } @@ -334,14 +248,14 @@ func (k Keeper) AcknowledgePacket( return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) } - if channel.State != types.OPEN { + if channel.State != exported.OPEN { return nil, sdkerrors.Wrapf( types.ErrInvalidChannelState, "channel state is not OPEN (got %s)", channel.State.String(), ) } - // RecvPacket is called by the antehandler which acts upon the packet.Route(), + // NOTE: RecvPacket is called by the AnteHandler which acts upon the packet.Route(), // so the capability authentication can be omitted here // packet must come from the channel's counterparty @@ -364,24 +278,32 @@ func (k Keeper) AcknowledgePacket( return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } - if connectionEnd.State != connection.OPEN { + if connectionEnd.GetState() != connectionexported.OPEN { return nil, sdkerrors.Wrapf( connection.ErrInvalidConnectionState, - "connection state is not OPEN (got %s)", connectionEnd.State.String(), + "connection state is not OPEN (got %s)", connectionEnd.GetState().String(), ) } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + // verify we sent the packet and haven't cleared it out yet if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } - if !k.connectionKeeper.VerifyMembership( - ctx, connectionEnd, proofHeight, proof, - types.PacketAcknowledgementPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), - acknowledgement.GetBytes(), - ) { - return nil, errors.New("invalid acknowledgement on counterparty chain") + consensusState, found := k.clientKeeper.GetConsensusState( + ctx, connectionEnd.GetClientID(), proofHeight, + ) + if !found { + return nil, clienttypes.ErrConsensusStateNotFound + } + + if err := k.connectionKeeper.VerifyPacketAcknowledgement( + ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), + packet.GetSequence(), acknowledgement.GetBytes(), consensusState, + ); err != nil { + return nil, sdkerrors.Wrap(err, "invalid acknowledgement on counterparty chain") } return packet, nil @@ -392,3 +314,109 @@ func (k Keeper) AcknowledgePacket( func (k Keeper) AcknowledgementExecuted(ctx sdk.Context, packet exported.PacketI) { k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) } + +// CleanupPacket is called by a module to remove a received packet commitment +// from storage. The receiving end must have already processed the packet +// (whether regularly or past timeout). +// +// In the ORDERED channel case, CleanupPacket cleans-up a packet on an ordered +// channel by proving that the packet has been received on the other end. +// +// In the UNORDERED channel case, CleanupPacket cleans-up a packet on an +// unordered channel by proving that the associated acknowledgement has been +//written. +func (k Keeper) CleanupPacket( + ctx sdk.Context, + packet exported.PacketI, + proof commitment.ProofI, + proofHeight, + nextSequenceRecv uint64, + acknowledgement []byte, +) (exported.PacketI, error) { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return nil, sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) + } + + if channel.State != exported.OPEN { + return nil, sdkerrors.Wrapf( + types.ErrInvalidChannelState, + "channel state is not OPEN (got %s)", channel.State.String(), + ) + } + + // TODO: blocked by #5542 + // capKey, found := k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + // if !found { + // return nil, types.ErrChannelCapabilityNotFound + // } + + // portCapabilityKey := sdk.NewKVStoreKey(capKey) + + // if !k.portKeeper.Authenticate(portCapabilityKey, packet.GetSourcePort()) { + // return nil, sdkerrors.Wrapf(port.ErrInvalidPort, "invalid source port: %s", packet.GetSourcePort()) + // } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return nil, sdkerrors.Wrapf(types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, + ) + } + + if packet.GetDestChannel() != channel.Counterparty.ChannelID { + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, + ) + } + + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) + } + + // check that packet has been received on the other end + if nextSequenceRecv <= packet.GetSequence() { + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet already received") + } + + commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + // verify we sent the packet and haven't cleared it out yet + if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") + } + + consensusState, found := k.clientKeeper.GetConsensusState( + ctx, connectionEnd.GetClientID(), proofHeight, + ) + if !found { + return nil, clienttypes.ErrConsensusStateNotFound + } + + var err error + switch channel.Ordering { + case exported.ORDERED: + // check that the recv sequence is as claimed + err = k.connectionKeeper.VerifyNextSequenceRecv( + ctx, connectionEnd, proofHeight, proof, + packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv, + consensusState, + ) + case exported.UNORDERED: + err = k.connectionKeeper.VerifyPacketAcknowledgement( + ctx, connectionEnd, proofHeight, proof, + packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), + acknowledgement, consensusState, + ) + default: + panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) + } + + if err != nil { + return nil, sdkerrors.Wrap(err, "packet verification failed") + } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + return packet, nil +} diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go index 8c8cac783cec..0d60cab08c8b 100644 --- a/x/ibc/04-channel/keeper/querier.go +++ b/x/ibc/04-channel/keeper/querier.go @@ -10,27 +10,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) -// QuerierChannel defines the sdk.Querier to query a module's channel -func QuerierChannel(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { - var params types.QueryChannelParams - - if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) - } - - channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) - if !found { - return nil, sdkerrors.Wrap(types.ErrChannelNotFound, params.ChannelID) - } - - bz, err := codec.MarshalJSONIndent(k.cdc, channel) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - - return bz, nil -} - // QuerierChannels defines the sdk.Querier to query all the channels. func QuerierChannels(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryAllChannelsParams diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index ccbffd25bd83..63b522d88b22 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -2,10 +2,10 @@ package keeper import ( "bytes" - "errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" @@ -21,7 +21,7 @@ func (k Keeper) TimeoutPacket( ctx sdk.Context, packet exported.PacketI, proof commitment.ProofI, - proofHeight uint64, + proofHeight, nextSequenceRecv uint64, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) @@ -32,19 +32,21 @@ func (k Keeper) TimeoutPacket( ) } - if channel.State != types.OPEN { + if channel.State != exported.OPEN { return nil, sdkerrors.Wrapf( types.ErrInvalidChannelState, "channel state is not OPEN (got %s)", channel.State.String(), ) } - // TimeoutPacket is called by the antehandler which acts upon the packet.Route(), + // NOTE: TimeoutPacket is called by the AnteHandler which acts upon the packet.Route(), // so the capability authentication can be omitted here - _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) - if !found { - return nil, types.ErrChannelCapabilityNotFound + if packet.GetDestPort() != channel.Counterparty.PortID { + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, + ) } if packet.GetDestChannel() != channel.Counterparty.ChannelID { @@ -62,56 +64,80 @@ func (k Keeper) TimeoutPacket( ) } - if packet.GetDestPort() != channel.Counterparty.PortID { - return nil, sdkerrors.Wrapf( - types.ErrInvalidPacket, - "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, - ) - } - + // check that timeout height has passed on the other end if proofHeight < packet.GetTimeoutHeight() { return nil, types.ErrPacketTimeout } + // check that packet has not been received if nextSequenceRecv >= packet.GetSequence() { - return nil, sdkerrors.Wrap( - types.ErrInvalidPacket, - "packet already received", - ) + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet already received") } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + // verify we sent the packet and haven't cleared it out yet if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { - return nil, sdkerrors.Wrap( - types.ErrInvalidPacket, - "packet hasn't been sent", - ) + return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } - var ok bool + consensusState, found := k.clientKeeper.GetConsensusState( + ctx, connectionEnd.GetClientID(), proofHeight, + ) + if !found { + return nil, clienttypes.ErrConsensusStateNotFound + } + + var err error switch channel.Ordering { - case types.ORDERED: - ok = k.connectionKeeper.VerifyMembership( + case exported.ORDERED: + // check that the recv sequence is as claimed + err = k.connectionKeeper.VerifyNextSequenceRecv( ctx, connectionEnd, proofHeight, proof, - types.NextSequenceRecvPath(packet.GetDestPort(), packet.GetDestChannel()), - sdk.Uint64ToBigEndian(nextSequenceRecv), + packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv, + consensusState, ) - case types.UNORDERED: - ok = k.connectionKeeper.VerifyNonMembership( + case exported.UNORDERED: + err = k.connectionKeeper.VerifyPacketAcknowledgementAbsence( ctx, connectionEnd, proofHeight, proof, - types.PacketAcknowledgementPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), + packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), + consensusState, ) default: panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) } - if !ok { - return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet verification failed") + if err != nil { + return nil, err } + // NOTE: the remaining code is located on the TimeoutExecuted function return packet, nil } +// TimeoutExecuted deletes the commitment send from this chain after it verifies timeout +func (k Keeper) TimeoutExecuted(ctx sdk.Context, packet exported.PacketI) error { + channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if !found { + return sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetSourcePort(), packet.GetSourceChannel()) + } + + // TODO: blocked by #5542 + // _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + // if !found { + // return types.ErrChannelCapabilityNotFound + // } + + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + if channel.Ordering == exported.ORDERED { + channel.State = exported.CLOSED + k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + } + + return nil +} + // TimeoutOnClose is called by a module in order to prove that the channel to // which an unreceived packet was addressed has been closed, so the packet will // never be received (even if the timeoutHeight has not yet been reached). @@ -120,21 +146,31 @@ func (k Keeper) TimeoutOnClose( packet types.Packet, proofNonMembership, proofClosed commitment.ProofI, - proofHeight uint64, - portCapability sdk.CapabilityKey, + proofHeight, + nextSequenceRecv uint64, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { return nil, sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetSourcePort(), packet.GetSourceChannel()) } - _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) - if !found { - return nil, types.ErrChannelCapabilityNotFound - } + // TODO: blocked by #5542 + // capKey, found := k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + // if !found { + // return nil, types.ErrChannelCapabilityNotFound + // } - if !k.portKeeper.Authenticate(portCapability, packet.GetSourcePort()) { - return nil, errors.New("port is not valid") + // portCapabilityKey := sdk.NewKVStoreKey(capKey) + + // if !k.portKeeper.Authenticate(portCapabilityKey, packet.GetSourcePort()) { + // return nil, sdkerrors.Wrap(port.ErrInvalidPort, packet.GetSourcePort()) + // } + + if packet.GetDestPort() != channel.Counterparty.PortID { + return nil, sdkerrors.Wrapf( + types.ErrInvalidPacket, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, + ) } if packet.GetDestChannel() != channel.Counterparty.ChannelID { @@ -149,14 +185,9 @@ func (k Keeper) TimeoutOnClose( return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, channel.ConnectionHops[0]) } - if packet.GetDestPort() != channel.Counterparty.PortID { - return nil, sdkerrors.Wrapf( - types.ErrInvalidPacket, - "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, - ) - } - commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + // verify we sent the packet and haven't cleared it out yet if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } @@ -169,55 +200,49 @@ func (k Keeper) TimeoutOnClose( counterparty := types.NewCounterparty(packet.GetSourcePort(), packet.GetSourceChannel()) expectedChannel := types.NewChannel( - types.CLOSED, channel.Ordering, counterparty, counterpartyHops, channel.Version, + exported.CLOSED, channel.Ordering, counterparty, counterpartyHops, channel.Version, ) - bz, err := k.cdc.MarshalBinaryLengthPrefixed(expectedChannel) - if err != nil { - return nil, errors.New("failed to marshal expected channel") + consensusState, found := k.clientKeeper.GetConsensusState( + ctx, connectionEnd.GetClientID(), proofHeight, + ) + if !found { + return nil, clienttypes.ErrConsensusStateNotFound } - if !k.connectionKeeper.VerifyMembership( + // check that the opposing channel end has closed + if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofClosed, - types.ChannelPath(channel.Counterparty.PortID, channel.Counterparty.ChannelID), - bz, - ) { - return nil, sdkerrors.Wrap( - types.ErrInvalidCounterparty, - "channel membership verification failed", - ) - } - - if !k.connectionKeeper.VerifyNonMembership( - ctx, connectionEnd, proofHeight, proofNonMembership, - types.PacketAcknowledgementPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()), - ) { - return nil, errors.New("cannot verify absence of acknowledgement at packet index") + channel.Counterparty.PortID, channel.Counterparty.ChannelID, + expectedChannel, consensusState, + ); err != nil { + return nil, err } - k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - - return packet, nil -} - -// TimeoutExecuted deletes the commitment send from this chain after it verifies timeout -func (k Keeper) TimeoutExecuted(ctx sdk.Context, packet exported.PacketI) error { - channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) - if !found { - return sdkerrors.Wrapf(types.ErrChannelNotFound, packet.GetSourcePort(), packet.GetSourceChannel()) + var err error + switch channel.Ordering { + case exported.ORDERED: + // check that the recv sequence is as claimed + err = k.connectionKeeper.VerifyNextSequenceRecv( + ctx, connectionEnd, proofHeight, proofClosed, + packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv, + consensusState, + ) + case exported.UNORDERED: + err = k.connectionKeeper.VerifyPacketAcknowledgementAbsence( + ctx, connectionEnd, proofHeight, proofClosed, + packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), + consensusState, + ) + default: + panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) } - _, found = k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) - if !found { - return types.ErrChannelCapabilityNotFound + if err != nil { + return nil, err } k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if channel.Ordering == types.ORDERED { - channel.State = types.CLOSED - k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) - } - - return nil + return packet, nil } diff --git a/x/ibc/04-channel/types/channel.go b/x/ibc/04-channel/types/channel.go index ae38cb2212df..ebb026bc86ef 100644 --- a/x/ibc/04-channel/types/channel.go +++ b/x/ibc/04-channel/types/channel.go @@ -1,25 +1,26 @@ package types import ( - "encoding/json" "strings" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) +// Channel defines... type Channel struct { - State State `json:"state" yaml:"state"` - Ordering Order `json:"ordering" yaml:"ordering"` - Counterparty Counterparty `json:"counterparty" yaml:"counterparty"` - ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` - Version string `json:"version" yaml:"version "` + State exported.State `json:"state" yaml:"state"` + Ordering exported.Order `json:"ordering" yaml:"ordering"` + Counterparty Counterparty `json:"counterparty" yaml:"counterparty"` + ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` + Version string `json:"version" yaml:"version "` } // NewChannel creates a new Channel instance func NewChannel( - state State, ordering Order, counterparty Counterparty, + state exported.State, ordering exported.Order, counterparty Counterparty, hops []string, version string, ) Channel { return Channel{ @@ -31,6 +32,31 @@ func NewChannel( } } +// GetState implements Channel interface. +func (ch Channel) GetState() exported.State { + return ch.State +} + +// GetOrdering implements Channel interface. +func (ch Channel) GetOrdering() exported.Order { + return ch.Ordering +} + +// GetCounterparty implements Channel interface. +func (ch Channel) GetCounterparty() exported.CounterpartyI { + return ch.Counterparty +} + +// GetConnectionHops implements Channel interface. +func (ch Channel) GetConnectionHops() []string { + return ch.ConnectionHops +} + +// GetVersion implements Channel interface. +func (ch Channel) GetVersion() string { + return ch.Version +} + // ValidateBasic performs a basic validation of the channel fields func (ch Channel) ValidateBasic() error { if ch.State.String() == "" { @@ -40,7 +66,10 @@ func (ch Channel) ValidateBasic() error { return sdkerrors.Wrap(ErrInvalidChannel, ErrInvalidChannelOrdering.Error()) } if len(ch.ConnectionHops) != 1 { - return sdkerrors.Wrap(ErrInvalidChannel, "IBC v1 only supports one connection hop") + return sdkerrors.Wrap( + ErrInvalidChannel, + sdkerrors.Wrap(ErrTooManyConnectionHops, "IBC v1.0 only supports one connection hop").Error(), + ) } if err := host.DefaultConnectionIdentifierValidator(ch.ConnectionHops[0]); err != nil { return sdkerrors.Wrap( @@ -71,6 +100,16 @@ func NewCounterparty(portID, channelID string) Counterparty { } } +// GetPortID implements CounterpartyI interface +func (c Counterparty) GetPortID() string { + return c.PortID +} + +// GetChannelID implements CounterpartyI interface +func (c Counterparty) GetChannelID() string { + return c.ChannelID +} + // ValidateBasic performs a basic validation check of the identifiers func (c Counterparty) ValidateBasic() error { if err := host.DefaultPortIdentifierValidator(c.PortID); err != nil { @@ -87,137 +126,3 @@ func (c Counterparty) ValidateBasic() error { } return nil } - -// Order defines if a channel is ORDERED or UNORDERED -type Order byte - -// string representation of the channel ordering -const ( - NONE Order = iota // zero-value for channel ordering - UNORDERED // packets can be delivered in any order, which may differ from the order in which they were sent. - ORDERED // packets are delivered exactly in the order which they were sent -) - -// channel order types -const ( - OrderNone string = "" - OrderUnordered string = "UNORDERED" - OrderOrdered string = "ORDERED" -) - -// String implements the Stringer interface -func (o Order) String() string { - switch o { - case UNORDERED: - return OrderUnordered - case ORDERED: - return OrderOrdered - default: - return OrderNone - } -} - -// MarshalJSON marshal to JSON using string. -func (o Order) MarshalJSON() ([]byte, error) { - return json.Marshal(o.String()) -} - -// UnmarshalJSON decodes from JSON. -func (o *Order) UnmarshalJSON(data []byte) error { - var s string - err := json.Unmarshal(data, &s) - if err != nil { - return err - } - - order := OrderFromString(s) - if order == 0 { - return sdkerrors.Wrap(ErrInvalidChannelOrdering, s) - } - - *o = order - return nil -} - -// OrderFromString parses a string into a channel order byte -func OrderFromString(order string) Order { - switch order { - case OrderUnordered: - return UNORDERED - case OrderOrdered: - return ORDERED - default: - return NONE - } -} - -// State defines if a channel is in one of the following states: -// CLOSED, INIT, OPENTRY or OPEN -type State byte - -// channel state types -const ( - UNINITIALIZED State = iota // Default State - INIT // A channel end has just started the opening handshake. - TRYOPEN // A channel end has acknowledged the handshake step on the counterparty chain. - OPEN // A channel end has completed the handshake and is ready to send and receive packets. - CLOSED // A channel end has been closed and can no longer be used to send or receive packets. -) - -// string representation of the channel states -const ( - StateUninitialized string = "UNINITIALIZED" - StateInit string = "INIT" - StateTryOpen string = "TRYOPEN" - StateOpen string = "OPEN" - StateClosed string = "CLOSED" -) - -// String implements the Stringer interface -func (s State) String() string { - switch s { - case INIT: - return StateInit - case TRYOPEN: - return StateTryOpen - case OPEN: - return StateOpen - case CLOSED: - return StateClosed - default: - return StateUninitialized - } -} - -// MarshalJSON marshal to JSON using string. -func (s State) MarshalJSON() ([]byte, error) { - return json.Marshal(s.String()) -} - -// UnmarshalJSON decodes from JSON. -func (s *State) UnmarshalJSON(data []byte) error { - var stateStr string - err := json.Unmarshal(data, &stateStr) - if err != nil { - return err - } - - *s = StateFromString(stateStr) - return nil -} - -// StateFromString parses a string into a channel state byte -func StateFromString(state string) State { - switch state { - case StateClosed: - return CLOSED - case StateInit: - return INIT - case StateTryOpen: - return TRYOPEN - case StateOpen: - return OPEN - default: - return UNINITIALIZED - } -} diff --git a/x/ibc/04-channel/types/channel_test.go b/x/ibc/04-channel/types/channel_test.go index 56b0dfe5eefa..ba1ccb10bf39 100644 --- a/x/ibc/04-channel/types/channel_test.go +++ b/x/ibc/04-channel/types/channel_test.go @@ -6,86 +6,25 @@ import ( "github.com/stretchr/testify/require" ) -func TestChannelStateString(t *testing.T) { - cases := []struct { - name string - state State +func TestCounterpartyValidateBasic(t *testing.T) { + testCases := []struct { + name string + counterparty Counterparty + expPass bool }{ - {StateUninitialized, UNINITIALIZED}, - {StateInit, INIT}, - {StateTryOpen, TRYOPEN}, - {StateOpen, OPEN}, - {StateClosed, CLOSED}, + {"valid counterparty", Counterparty{"portidone", "channelidone"}, true}, + {"invalid port id", Counterparty{"InvalidPort", "channelidone"}, false}, + {"invalid channel id", Counterparty{"portidone", "InvalidChannel"}, false}, } - for _, tt := range cases { - tt := tt - require.Equal(t, tt.state, StateFromString(tt.name)) - require.Equal(t, tt.name, tt.state.String()) - } -} - -func TestChannelStateMarshalJSON(t *testing.T) { - cases := []struct { - name string - state State - }{ - {StateUninitialized, UNINITIALIZED}, - {StateInit, INIT}, - {StateTryOpen, TRYOPEN}, - {StateOpen, OPEN}, - {StateClosed, CLOSED}, - } - - for _, tt := range cases { - tt := tt - bz, err := tt.state.MarshalJSON() - require.NoError(t, err) - var state State - require.NoError(t, state.UnmarshalJSON(bz)) - require.Equal(t, tt.name, state.String()) - } -} - -func TestOrderString(t *testing.T) { - cases := []struct { - name string - order Order - }{ - {OrderNone, NONE}, - {OrderUnordered, UNORDERED}, - {OrderOrdered, ORDERED}, - } - - for _, tt := range cases { - tt := tt - require.Equal(t, tt.order, OrderFromString(tt.name)) - require.Equal(t, tt.name, tt.order.String()) - } -} - -func TestOrderMarshalJSON(t *testing.T) { - cases := []struct { - msg string - name string - order Order - expectPass bool - }{ - {"none ordering should have failed", OrderNone, NONE, false}, - {"unordered should have passed", OrderUnordered, UNORDERED, true}, - {"ordered should have passed", OrderOrdered, ORDERED, true}, - } + for i, tc := range testCases { + tc := tc - for _, tt := range cases { - tt := tt - bz, err := tt.order.MarshalJSON() - require.NoError(t, err) - var order Order - if tt.expectPass { - require.NoError(t, order.UnmarshalJSON(bz), tt.msg) - require.Equal(t, tt.name, order.String(), tt.msg) + err := tc.counterparty.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "valid test case %d failed: %s", i, tc.name) } else { - require.Error(t, order.UnmarshalJSON(bz), tt.msg) + require.Error(t, err, "invalid test case %d passed: %s", i, tc.name) } } } diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index dea16064dbcd..2bb785418b67 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -20,6 +20,7 @@ func init() { // RegisterCodec registers all the necessary types and interfaces for the // IBC channel. func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*exported.PacketI)(nil), nil) cdc.RegisterInterface((*exported.PacketDataI)(nil), nil) cdc.RegisterConcrete(Channel{}, "ibc/channel/Channel", nil) cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil) @@ -34,6 +35,7 @@ func RegisterCodec(cdc *codec.Codec) { SetSubModuleCodec(cdc) } +// SetSubModuleCodec sets the ibc channel codec func SetSubModuleCodec(cdc *codec.Codec) { SubModuleCdc = cdc } diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go index 40e526476eae..9e6ee6fcf74c 100644 --- a/x/ibc/04-channel/types/errors.go +++ b/x/ibc/04-channel/types/errors.go @@ -17,4 +17,5 @@ var ( ErrSequenceReceiveNotFound = sdkerrors.Register(SubModuleName, 9, "sequence receive not found") ErrInvalidPacket = sdkerrors.Register(SubModuleName, 10, "invalid packet") ErrPacketTimeout = sdkerrors.Register(SubModuleName, 11, "packet timeout") + ErrTooManyConnectionHops = sdkerrors.Register(SubModuleName, 12, "too many connection hops") ) diff --git a/x/ibc/04-channel/types/expected_keepers.go b/x/ibc/04-channel/types/expected_keepers.go index ab88a2284f27..a8b00b4ac014 100644 --- a/x/ibc/04-channel/types/expected_keepers.go +++ b/x/ibc/04-channel/types/expected_keepers.go @@ -3,26 +3,72 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // ClientKeeper expected account IBC client keeper type ClientKeeper interface { - GetConsensusState(ctx sdk.Context, clientID string) (clientexported.ConsensusState, bool) + GetClientState(ctx sdk.Context, clientID string) (clientexported.ClientState, bool) + GetConsensusState(ctx sdk.Context, clientID string, height uint64) (clientexported.ConsensusState, bool) } // ConnectionKeeper expected account IBC connection keeper type ConnectionKeeper interface { - GetConnection(ctx sdk.Context, connectionID string) (connection.ConnectionEnd, bool) - VerifyMembership( - ctx sdk.Context, connection connection.ConnectionEnd, height uint64, - proof commitment.ProofI, path string, value []byte, - ) bool - VerifyNonMembership( - ctx sdk.Context, connection connection.ConnectionEnd, height uint64, - proof commitment.ProofI, path string, - ) bool + GetConnection(ctx sdk.Context, connectionID string) (connectiontypes.ConnectionEnd, bool) + VerifyChannelState( + ctx sdk.Context, + connection connectiontypes.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + channel exported.ChannelI, + consensusState clientexported.ConsensusState, + ) error + VerifyPacketCommitment( + ctx sdk.Context, + connection connectiontypes.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + commitmentBytes []byte, + consensusState clientexported.ConsensusState, + ) error + VerifyPacketAcknowledgement( + ctx sdk.Context, + connection connectiontypes.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + acknowledgement []byte, + consensusState clientexported.ConsensusState, + ) error + VerifyPacketAcknowledgementAbsence( + ctx sdk.Context, + connection connectiontypes.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + consensusState clientexported.ConsensusState, + ) error + VerifyNextSequenceRecv( + ctx sdk.Context, + connection connectiontypes.ConnectionEnd, + height uint64, + proof commitment.ProofI, + portID, + channelID string, + nextSequenceRecv uint64, + consensusState clientexported.ConsensusState, + ) error } // PortKeeper expected account IBC port keeper diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go index 1fcbb4f44806..21372dc48d99 100644 --- a/x/ibc/04-channel/types/keys.go +++ b/x/ibc/04-channel/types/keys.go @@ -1,11 +1,5 @@ package types -import ( - "fmt" - - ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" -) - const ( // SubModuleName defines the IBC channels name SubModuleName = "channels" @@ -19,116 +13,3 @@ const ( // QuerierRoute is the querier route for IBC channels QuerierRoute = SubModuleName ) - -// ChannelPath defines the path under which channels are stored -func ChannelPath(portID, channelID string) string { - return string(KeyChannel(portID, channelID)) -} - -// ChannelCapabilityPath defines the path under which capability keys associated -// with a channel are stored -func ChannelCapabilityPath(portID, channelID string) string { - return string(KeyChannelCapabilityPath(portID, channelID)) -} - -// NextSequenceSendPath defines the next send sequence counter store path -func NextSequenceSendPath(portID, channelID string) string { - return string(KeyNextSequenceSend(portID, channelID)) -} - -// NextSequenceRecvPath defines the next receive sequence counter store path -func NextSequenceRecvPath(portID, channelID string) string { - return string(KeyNextSequenceRecv(portID, channelID)) -} - -// PacketCommitmentPath defines the commitments to packet data fields store path -func PacketCommitmentPath(portID, channelID string, sequence uint64) string { - return string(KeyPacketCommitment(portID, channelID, sequence)) -} - -// PacketAcknowledgementPath defines the packet acknowledgement store path -func PacketAcknowledgementPath(portID, channelID string, sequence uint64) string { - return string(KeyPacketAcknowledgement(portID, channelID, sequence)) -} - -// KeyChannel returns the store key for a particular channel -func KeyChannel(portID, channelID string) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyChannelPrefix), - []byte(channelPath(portID, channelID))..., - ) -} - -// KeyChannelCapabilityPath returns the store key for the capability key of a -// particular channel binded to a specific port -func KeyChannelCapabilityPath(portID, channelID string) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyChannelCapabilityPrefix), - []byte(channelCapabilityPath(portID, channelID))..., - ) -} - -// KeyNextSequenceSend returns the store key for the send sequence of a particular -// channel binded to a specific port -func KeyNextSequenceSend(portID, channelID string) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyNextSeqSendPrefix), - []byte(nextSequenceSendPath(portID, channelID))..., - ) -} - -// KeyNextSequenceRecv returns the store key for the receive sequence of a particular -// channel binded to a specific port -func KeyNextSequenceRecv(portID, channelID string) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyNextSeqRecvPrefix), - []byte(nextSequenceRecvPath(portID, channelID))..., - ) -} - -// KeyPacketCommitment returns the store key of under which a packet commitment -// is stored -func KeyPacketCommitment(portID, channelID string, sequence uint64) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyPacketCommitmentPrefix), - []byte(packetCommitmentPath(portID, channelID, sequence))..., - ) -} - -// KeyPacketAcknowledgement returns the store key of under which a packet -// acknowledgement is stored -func KeyPacketAcknowledgement(portID, channelID string, sequence uint64) []byte { - return append( - ibctypes.KeyPrefixBytes(ibctypes.KeyPacketAckPrefix), - []byte(packetAcknowledgementPath(portID, channelID, sequence))..., - ) -} - -// GetChannelKeysPrefix returns the prefix bytes for ICS04 iterators -func GetChannelKeysPrefix(prefix int) []byte { - return []byte(fmt.Sprintf("%d/ports/", prefix)) -} - -func channelPath(portID, channelID string) string { - return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) -} - -func channelCapabilityPath(portID, channelID string) string { - return channelPath(portID, channelID) + "/key" -} - -func nextSequenceSendPath(portID, channelID string) string { - return channelPath(portID, channelID) + "/nextSequenceSend" -} - -func nextSequenceRecvPath(portID, channelID string) string { - return channelPath(portID, channelID) + "/nextSequenceRecv" -} - -func packetCommitmentPath(portID, channelID string, sequence uint64) string { - return channelPath(portID, channelID) + fmt.Sprintf("/packets/%d", sequence) -} - -func packetAcknowledgementPath(portID, channelID string, sequence uint64) string { - return channelPath(portID, channelID) + fmt.Sprintf("/acknowledgements/%d", sequence) -} diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index 3f578425dda0..c655cfda0f45 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -22,11 +22,11 @@ type MsgChannelOpenInit struct { // NewMsgChannelOpenInit creates a new MsgChannelCloseInit MsgChannelOpenInit func NewMsgChannelOpenInit( - portID, channelID string, version string, channelOrder Order, connectionHops []string, + portID, channelID string, version string, channelOrder exported.Order, connectionHops []string, counterpartyPortID, counterpartyChannelID string, signer sdk.AccAddress, ) MsgChannelOpenInit { counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) - channel := NewChannel(INIT, channelOrder, counterparty, connectionHops, version) + channel := NewChannel(exported.INIT, channelOrder, counterparty, connectionHops, version) return MsgChannelOpenInit{ PortID: portID, ChannelID: channelID, @@ -81,12 +81,12 @@ type MsgChannelOpenTry struct { // NewMsgChannelOpenTry creates a new MsgChannelOpenTry instance func NewMsgChannelOpenTry( - portID, channelID, version string, channelOrder Order, connectionHops []string, + portID, channelID, version string, channelOrder exported.Order, connectionHops []string, counterpartyPortID, counterpartyChannelID, counterpartyVersion string, proofInit commitment.ProofI, proofHeight uint64, signer sdk.AccAddress, ) MsgChannelOpenTry { counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) - channel := NewChannel(INIT, channelOrder, counterparty, connectionHops, version) + channel := NewChannel(exported.INIT, channelOrder, counterparty, connectionHops, version) return MsgChannelOpenTry{ PortID: portID, ChannelID: channelID, diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index a6d324670200..0e43f58d503b 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -7,9 +7,9 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - "github.com/tendermint/tendermint/crypto/merkle" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/merkle" dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/store/iavl" @@ -81,21 +81,21 @@ func TestMsgTestSuite(t *testing.T) { // TestMsgChannelOpenInit tests ValidateBasic for MsgChannelOpenInit func (suite *MsgTestSuite) TestMsgChannelOpenInit() { testMsgs := []MsgChannelOpenInit{ - NewMsgChannelOpenInit("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg - NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id - NewMsgChannelOpenInit(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long port id - NewMsgChannelOpenInit(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // port id contains non-alpha - NewMsgChannelOpenInit("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short channel id - NewMsgChannelOpenInit("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long channel id - NewMsgChannelOpenInit("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", addr), // channel id contains non-alpha - NewMsgChannelOpenInit("testportid", "testchannel", "1.0", Order(3), connHops, "testcpport", "testcpchannel", addr), // invalid channel order - NewMsgChannelOpenInit("testportid", "testchannel", "1.0", ORDERED, invalidConnHops, "testcpport", "testcpchannel", addr), // connection hops more than 1 - NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", addr), // too short connection id - NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", addr), // too long connection id - NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", addr), // connection id contains non-alpha - NewMsgChannelOpenInit("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", addr), // empty channel version - NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", addr), // invalid counterparty port id - NewMsgChannelOpenInit("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, addr), // invalid counterparty channel id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", addr), // valid msg + NewMsgChannelOpenInit(invalidShortPort, "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short port id + NewMsgChannelOpenInit(invalidLongPort, "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long port id + NewMsgChannelOpenInit(invalidPort, "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", addr), // port id contains non-alpha + NewMsgChannelOpenInit("testportid", invalidShortChannel, "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", addr), // too short channel id + NewMsgChannelOpenInit("testportid", invalidLongChannel, "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", addr), // too long channel id + NewMsgChannelOpenInit("testportid", invalidChannel, "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", addr), // channel id contains non-alpha + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", exported.Order(3), connHops, "testcpport", "testcpchannel", addr), // invalid channel order + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", exported.ORDERED, invalidConnHops, "testcpport", "testcpchannel", addr), // connection hops more than 1 + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", exported.UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", addr), // too short connection id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", exported.UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", addr), // too long connection id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", exported.UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", addr), // connection id contains non-alpha + NewMsgChannelOpenInit("testportid", "testchannel", "", exported.UNORDERED, connHops, "testcpport", "testcpchannel", addr), // empty channel version + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", exported.UNORDERED, connHops, invalidPort, "testcpchannel", addr), // invalid counterparty port id + NewMsgChannelOpenInit("testportid", "testchannel", "1.0", exported.UNORDERED, connHops, "testcpport", invalidChannel, addr), // invalid counterparty channel id } testCases := []struct { @@ -133,24 +133,24 @@ func (suite *MsgTestSuite) TestMsgChannelOpenInit() { // TestMsgChannelOpenTry tests ValidateBasic for MsgChannelOpenTry func (suite *MsgTestSuite) TestMsgChannelOpenTry() { testMsgs := []MsgChannelOpenTry{ - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // valid msg - NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short port id - NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long port id - NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenTry("testportid", invalidShortChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short channel id - NewMsgChannelOpenTry("testportid", invalidLongChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long channel id - NewMsgChannelOpenTry("testportid", invalidChannel, "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "", suite.proof, 1, addr), // empty counterparty version - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty suite.proof - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 0, addr), // suite.proof height is zero - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", Order(4), connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // invalid channel order - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // connection hops more than 1 - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short connection id - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long connection id - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // connection id contains non-alpha - NewMsgChannelOpenTry("testportid", "testchannel", "", UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // empty channel version - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", suite.proof, 1, addr), // invalid counterparty port id - NewMsgChannelOpenTry("testportid", "testchannel", "1.0", UNORDERED, connHops, "testcpport", invalidChannel, "1.0", suite.proof, 1, addr), // invalid counterparty channel id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // valid msg + NewMsgChannelOpenTry(invalidShortPort, "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short port id + NewMsgChannelOpenTry(invalidLongPort, "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long port id + NewMsgChannelOpenTry(invalidPort, "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenTry("testportid", invalidShortChannel, "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short channel id + NewMsgChannelOpenTry("testportid", invalidLongChannel, "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long channel id + NewMsgChannelOpenTry("testportid", invalidChannel, "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "", suite.proof, 1, addr), // empty counterparty version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "1.0", nil, 1, addr), // empty suite.proof + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.ORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 0, addr), // suite.proof height is zero + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.Order(4), connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // invalid channel order + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.UNORDERED, invalidConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // connection hops more than 1 + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.UNORDERED, invalidShortConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too short connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.UNORDERED, invalidLongConnHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // too long connection id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.UNORDERED, []string{invalidConnection}, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // connection id contains non-alpha + NewMsgChannelOpenTry("testportid", "testchannel", "", exported.UNORDERED, connHops, "testcpport", "testcpchannel", "1.0", suite.proof, 1, addr), // empty channel version + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.UNORDERED, connHops, invalidPort, "testcpchannel", "1.0", suite.proof, 1, addr), // invalid counterparty port id + NewMsgChannelOpenTry("testportid", "testchannel", "1.0", exported.UNORDERED, connHops, "testcpport", invalidChannel, "1.0", suite.proof, 1, addr), // invalid counterparty channel id } testCases := []struct { @@ -478,3 +478,73 @@ func TestMsgPacketGetSigners(t *testing.T) { expected := "[746573746164647231]" require.Equal(t, expected, fmt.Sprintf("%v", res)) } + +// TestMsgTimeout tests ValidateBasic for MsgTimeout +func (suite *MsgTestSuite) TestMsgTimeout() { + testMsgs := []MsgTimeout{ + NewMsgTimeout(packet, 0, proof, 1, addr), + NewMsgTimeout(packet, 0, proof, 0, addr), + NewMsgTimeout(packet, 0, proof, 1, emptyAddr), + NewMsgTimeout(packet, 0, emptyProof, 1, addr), + NewMsgTimeout(invalidPacket, 0, proof, 1, addr), + NewMsgTimeout(packet, 0, invalidProofs1, 1, addr), + } + + testCases := []struct { + msg MsgTimeout + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "proof height must be > 0"}, + {testMsgs[2], false, "missing signer address"}, + {testMsgs[3], false, "cannot submit an empty proof"}, + {testMsgs[4], false, "invalid packet"}, + {testMsgs[5], false, "cannot submit an invalid proof"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +// TestMsgAcknowledgement tests ValidateBasic for MsgAcknowledgement +func (suite *MsgTestSuite) TestMsgAcknowledgement() { + testMsgs := []MsgAcknowledgement{ + NewMsgAcknowledgement(packet, packet.GetData(), proof, 1, addr), + NewMsgAcknowledgement(packet, packet.GetData(), proof, 0, addr), + NewMsgAcknowledgement(packet, packet.GetData(), proof, 1, emptyAddr), + NewMsgAcknowledgement(packet, packet.GetData(), emptyProof, 1, addr), + NewMsgAcknowledgement(invalidPacket, packet.GetData(), proof, 1, addr), + NewMsgAcknowledgement(packet, invalidPacket.GetData(), proof, 1, addr), + NewMsgAcknowledgement(packet, packet.GetData(), invalidProofs1, 1, addr), + } + + testCases := []struct { + msg MsgAcknowledgement + expPass bool + errMsg string + }{ + {testMsgs[0], true, ""}, + {testMsgs[1], false, "proof height must be > 0"}, + {testMsgs[2], false, "missing signer address"}, + {testMsgs[3], false, "cannot submit an empty proof"}, + {testMsgs[4], false, "invalid packet"}, + {testMsgs[5], false, "invalid acknowledgement"}, + {testMsgs[6], false, "cannot submit an invalid proof"}, + } + + for i, tc := range testCases { + err := tc.msg.ValidateBasic() + if tc.expPass { + suite.Require().NoError(err, "Msg %d failed: %s", i, tc.errMsg) + } else { + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} diff --git a/x/ibc/04-channel/types/packet_test.go b/x/ibc/04-channel/types/packet_test.go new file mode 100644 index 000000000000..9137bd7380e4 --- /dev/null +++ b/x/ibc/04-channel/types/packet_test.go @@ -0,0 +1,32 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPacketValidateBasic(t *testing.T) { + testCases := []struct { + packet Packet + expPass bool + errMsg string + }{ + {NewPacket(validPacketT{}, 1, portid, chanid, cpportid, cpchanid), true, ""}, + {NewPacket(validPacketT{}, 0, portid, chanid, cpportid, cpchanid), false, "invalid sequence"}, + {NewPacket(validPacketT{}, 1, invalidPort, chanid, cpportid, cpchanid), false, "invalid source port"}, + {NewPacket(validPacketT{}, 1, portid, invalidChannel, cpportid, cpchanid), false, "invalid source channel"}, + {NewPacket(validPacketT{}, 1, portid, chanid, invalidPort, cpchanid), false, "invalid destination port"}, + {NewPacket(validPacketT{}, 1, portid, chanid, cpportid, invalidChannel), false, "invalid destination channel"}, + {NewPacket(invalidPacketT{}, 1, portid, chanid, cpportid, cpchanid), false, "invalid packet data"}, + } + + for i, tc := range testCases { + err := tc.packet.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "Msg %d failed: %s", i, tc.errMsg) + } else { + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go index e010c6991d88..37b24559ba20 100644 --- a/x/ibc/04-channel/types/querier.go +++ b/x/ibc/04-channel/types/querier.go @@ -6,6 +6,7 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // query routes supported by the IBC channel Querier @@ -30,26 +31,11 @@ func NewChannelResponse( return ChannelResponse{ Channel: channel, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ChannelPath(portID, channelID), "/")), + ProofPath: commitment.NewPath(strings.Split(ibctypes.ChannelPath(portID, channelID), "/")), ProofHeight: uint64(height), } } -// QueryChannelParams defines the params for the following queries: -// - 'custom/ibc/channel' -type QueryChannelParams struct { - PortID string - ChannelID string -} - -// NewQueryChannelParams creates a new QueryChannelParams instance -func NewQueryChannelParams(portID, channelID string) QueryChannelParams { - return QueryChannelParams{ - PortID: portID, - ChannelID: channelID, - } -} - // QueryAllChannelsParams defines the parameters necessary for querying for all // channels. type QueryAllChannelsParams struct { @@ -81,7 +67,7 @@ func NewPacketResponse( return PacketResponse{ Packet: packet, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(PacketCommitmentPath(portID, channelID, sequence), "/")), + ProofPath: commitment.NewPath(strings.Split(ibctypes.PacketCommitmentPath(portID, channelID, sequence), "/")), ProofHeight: uint64(height), } } @@ -103,7 +89,7 @@ func NewRecvResponse( return RecvResponse{ NextSequenceRecv: sequenceRecv, Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(NextSequenceRecvPath(portID, channelID), "/")), + ProofPath: commitment.NewPath(strings.Split(ibctypes.NextSequenceRecvPath(portID, channelID), "/")), ProofHeight: uint64(height), } } diff --git a/x/ibc/07-tendermint/client_state.go b/x/ibc/07-tendermint/client_state.go new file mode 100644 index 000000000000..ff10c73a514e --- /dev/null +++ b/x/ibc/07-tendermint/client_state.go @@ -0,0 +1,290 @@ +package tendermint + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +var _ clientexported.ClientState = ClientState{} + +// ClientState from Tendermint tracks the current validator set, latest height, +// and a possible frozen height. +type ClientState struct { + // Client ID + ID string `json:"id" yaml:"id"` + // Latest block height + LatestHeight uint64 `json:"latest_height" yaml:"latest_height"` + // Block height when the client was frozen due to a misbehaviour + FrozenHeight uint64 `json:"frozen_height" yaml:"frozen_height"` +} + +// NewClientState creates a new ClientState instance +func NewClientState(id string, latestHeight uint64) ClientState { + return ClientState{ + ID: id, + LatestHeight: latestHeight, + FrozenHeight: 0, + } +} + +// GetID returns the tendermint client state identifier. +func (cs ClientState) GetID() string { + return cs.ID +} + +// ClientType is tendermint. +func (cs ClientState) ClientType() clientexported.ClientType { + return clientexported.Tendermint +} + +// GetLatestHeight returns latest block height. +func (cs ClientState) GetLatestHeight() uint64 { + return cs.LatestHeight +} + +// IsFrozen returns true if the frozen height has been set. +func (cs ClientState) IsFrozen() bool { + return cs.FrozenHeight != 0 +} + +// VerifyClientConsensusState verifies a proof of the consensus state of the +// Tendermint client stored on the target machine. +func (cs ClientState) VerifyClientConsensusState( + cdc *codec.Codec, + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + consensusState clientexported.ConsensusState, +) error { + path, err := commitment.ApplyPrefix(prefix, ibctypes.ConsensusStatePath(cs.GetID(), height)) + if err != nil { + return err + } + + if err := validateVerificationArgs(cs, height, proof, consensusState); err != nil { + return err + } + + bz, err := cdc.MarshalBinaryBare(consensusState) + if err != nil { + return err + } + + if err := proof.VerifyMembership(consensusState.GetRoot(), path, bz); err != nil { + return sdkerrors.Wrap(clienttypes.ErrFailedClientConsensusStateVerification, err.Error()) + } + + return nil +} + +// VerifyConnectionState verifies a proof of the connection state of the +// specified connection end stored on the target machine. +func (cs ClientState) VerifyConnectionState( + cdc *codec.Codec, + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + connectionID string, + connectionEnd connectionexported.ConnectionI, + consensusState clientexported.ConsensusState, +) error { + path, err := commitment.ApplyPrefix(prefix, ibctypes.ConnectionPath(connectionID)) + if err != nil { + return err + } + + if err := validateVerificationArgs(cs, height, proof, consensusState); err != nil { + return err + } + + bz, err := cdc.MarshalBinaryBare(connectionEnd) + if err != nil { + return err + } + + if err := proof.VerifyMembership(consensusState.GetRoot(), path, bz); err != nil { + return sdkerrors.Wrap(clienttypes.ErrFailedConnectionStateVerification, err.Error()) + } + + return nil +} + +// VerifyChannelState verifies a proof of the channel state of the specified +// channel end, under the specified port, stored on the target machine. +func (cs ClientState) VerifyChannelState( + cdc *codec.Codec, + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + channel channelexported.ChannelI, + consensusState clientexported.ConsensusState, +) error { + path, err := commitment.ApplyPrefix(prefix, ibctypes.ChannelPath(portID, channelID)) + if err != nil { + return err + } + + if err := validateVerificationArgs(cs, height, proof, consensusState); err != nil { + return err + } + + bz, err := cdc.MarshalBinaryBare(channel) + if err != nil { + return err + } + + if err := proof.VerifyMembership(consensusState.GetRoot(), path, bz); err != nil { + return sdkerrors.Wrap(clienttypes.ErrFailedChannelStateVerification, err.Error()) + } + + return nil +} + +// VerifyPacketCommitment verifies a proof of an outgoing packet commitment at +// the specified port, specified channel, and specified sequence. +func (cs ClientState) VerifyPacketCommitment( + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + commitmentBytes []byte, + consensusState clientexported.ConsensusState, +) error { + path, err := commitment.ApplyPrefix(prefix, ibctypes.PacketCommitmentPath(portID, channelID, sequence)) + if err != nil { + return err + } + + if err := validateVerificationArgs(cs, height, proof, consensusState); err != nil { + return err + } + + if err := proof.VerifyMembership(consensusState.GetRoot(), path, commitmentBytes); err != nil { + return sdkerrors.Wrap(clienttypes.ErrFailedPacketCommitmentVerification, err.Error()) + } + + return nil +} + +// VerifyPacketAcknowledgement verifies a proof of an incoming packet +// acknowledgement at the specified port, specified channel, and specified sequence. +func (cs ClientState) VerifyPacketAcknowledgement( + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + acknowledgement []byte, + consensusState clientexported.ConsensusState, +) error { + path, err := commitment.ApplyPrefix(prefix, ibctypes.PacketAcknowledgementPath(portID, channelID, sequence)) + if err != nil { + return err + } + + if err := validateVerificationArgs(cs, height, proof, consensusState); err != nil { + return err + } + + if err := proof.VerifyMembership(consensusState.GetRoot(), path, acknowledgement); err != nil { + return sdkerrors.Wrap(clienttypes.ErrFailedPacketAckVerification, err.Error()) + } + + return nil +} + +// VerifyPacketAcknowledgementAbsence verifies a proof of the absence of an +// incoming packet acknowledgement at the specified port, specified channel, and +// specified sequence. +func (cs ClientState) VerifyPacketAcknowledgementAbsence( + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + sequence uint64, + consensusState clientexported.ConsensusState, +) error { + path, err := commitment.ApplyPrefix(prefix, ibctypes.PacketAcknowledgementPath(portID, channelID, sequence)) + if err != nil { + return err + } + + if err := validateVerificationArgs(cs, height, proof, consensusState); err != nil { + return err + } + + if err := proof.VerifyNonMembership(consensusState.GetRoot(), path); err != nil { + return sdkerrors.Wrap(clienttypes.ErrFailedPacketAckAbsenceVerification, err.Error()) + } + + return nil +} + +// VerifyNextSequenceRecv verifies a proof of the next sequence number to be +// received of the specified channel at the specified port. +func (cs ClientState) VerifyNextSequenceRecv( + height uint64, + prefix commitment.PrefixI, + proof commitment.ProofI, + portID, + channelID string, + nextSequenceRecv uint64, + consensusState clientexported.ConsensusState, +) error { + path, err := commitment.ApplyPrefix(prefix, ibctypes.NextSequenceRecvPath(portID, channelID)) + if err != nil { + return err + } + + if err := validateVerificationArgs(cs, height, proof, consensusState); err != nil { + return err + } + + bz := sdk.Uint64ToBigEndian(nextSequenceRecv) + + if err := proof.VerifyMembership(consensusState.GetRoot(), path, bz); err != nil { + return sdkerrors.Wrap(clienttypes.ErrFailedNextSeqRecvVerification, err.Error()) + } + + return nil +} + +// validateVerificationArgs perfoms the basic checks on the arguments that are +// shared between the verification functions. +func validateVerificationArgs( + cs ClientState, + height uint64, + proof commitment.ProofI, + consensusState clientexported.ConsensusState, +) error { + if cs.LatestHeight < height { + return ibctypes.ErrInvalidHeight + } + + if cs.IsFrozen() && cs.FrozenHeight <= height { + return clienttypes.ErrClientFrozen + } + + if proof == nil { + return sdkerrors.Wrap(commitment.ErrInvalidProof, "proof cannot be empty") + } + + if consensusState == nil { + return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "consensus state cannot be empty") + } + + return nil +} diff --git a/x/ibc/07-tendermint/client_state_test.go b/x/ibc/07-tendermint/client_state_test.go new file mode 100644 index 000000000000..c749647bfa9b --- /dev/null +++ b/x/ibc/07-tendermint/client_state_test.go @@ -0,0 +1,560 @@ +package tendermint_test + +import ( + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +const ( + testConnectionID = "connectionid" + testPortID = "testportid" + testChannelID = "testchannelid" + testSequence = 1 +) + +func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { + testCases := []struct { + name string + clientState tendermint.ClientState + consensusState tendermint.ConsensusState + prefix commitment.Prefix + proof commitment.Proof + expPass bool + }{ + // { + // name: "successful verification", + // clientState: tendermint.NewClientState(chainID, height), + // consensusState: tendermint.ConsensusState{ + // Root: commitment.NewRoot(suite.header.AppHash), + // }, + // prefix: commitment.NewPrefix([]byte("ibc")), + // expPass: true, + // }, + { + name: "ApplyPrefix failed", + clientState: tendermint.NewClientState(chainID, height), + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.Prefix{}, + expPass: false, + }, + { + name: "latest client height < height", + clientState: tendermint.NewClientState(chainID, height-1), + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "client is frozen", + clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "proof verification failed", + clientState: tendermint.NewClientState(chainID, height), + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.valSet.Hash(), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + proof: commitment.Proof{}, + expPass: false, + }, + } + + for i, tc := range testCases { + tc := tc + + err := tc.clientState.VerifyClientConsensusState( + suite.cdc, height, tc.prefix, tc.proof, tc.consensusState, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + +func (suite *TendermintTestSuite) TestVerifyConnectionState() { + counterparty := connection.NewCounterparty("clientB", testConnectionID, commitment.NewPrefix([]byte("ibc"))) + conn := connection.NewConnectionEnd(connectionexported.OPEN, "clientA", counterparty, []string{"1.0.0"}) + + testCases := []struct { + name string + clientState tendermint.ClientState + connection connection.ConnectionEnd + consensusState tendermint.ConsensusState + prefix commitment.Prefix + proof commitment.Proof + expPass bool + }{ + // { + // name: "successful verification", + // clientState: tendermint.NewClientState(chainID, height), + // connection: conn, + // consensusState: tendermint.ConsensusState{ + // Root: commitment.NewRoot(suite.header.AppHash), + // }, + // prefix: commitment.NewPrefix([]byte("ibc")), + // expPass: true, + // }, + { + name: "ApplyPrefix failed", + clientState: tendermint.NewClientState(chainID, height), + connection: conn, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.Prefix{}, + expPass: false, + }, + { + name: "latest client height < height", + clientState: tendermint.NewClientState(chainID, height-1), + connection: conn, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "client is frozen", + clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + connection: conn, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "proof verification failed", + clientState: tendermint.NewClientState(chainID, height), + connection: conn, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.valSet.Hash(), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + proof: commitment.Proof{}, + expPass: false, + }, + } + + for i, tc := range testCases { + tc := tc + + err := tc.clientState.VerifyConnectionState( + suite.cdc, height, tc.prefix, tc.proof, testConnectionID, tc.connection, tc.consensusState, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + +func (suite *TendermintTestSuite) TestVerifyChannelState() { + counterparty := channel.NewCounterparty(testPortID, testChannelID) + ch := channel.NewChannel(channelexported.OPEN, channelexported.ORDERED, counterparty, []string{testConnectionID}, "1.0.0") + + testCases := []struct { + name string + clientState tendermint.ClientState + channel channel.Channel + consensusState tendermint.ConsensusState + prefix commitment.Prefix + proof commitment.Proof + expPass bool + }{ + // { + // name: "successful verification", + // clientState: tendermint.NewClientState(chainID, height), + // connection: conn, + // consensusState: tendermint.ConsensusState{ + // Root: commitment.NewRoot(suite.header.AppHash), + // }, + // prefix: commitment.NewPrefix([]byte("ibc")), + // expPass: true, + // }, + { + name: "ApplyPrefix failed", + clientState: tendermint.NewClientState(chainID, height), + channel: ch, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.Prefix{}, + expPass: false, + }, + { + name: "latest client height < height", + clientState: tendermint.NewClientState(chainID, height-1), + channel: ch, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "client is frozen", + clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + channel: ch, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "proof verification failed", + clientState: tendermint.NewClientState(chainID, height), + channel: ch, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.valSet.Hash(), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + proof: commitment.Proof{}, + expPass: false, + }, + } + + for i, tc := range testCases { + tc := tc + + err := tc.clientState.VerifyChannelState( + suite.cdc, height, tc.prefix, tc.proof, testPortID, testChannelID, tc.channel, tc.consensusState, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + +func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { + testCases := []struct { + name string + clientState tendermint.ClientState + commitment []byte + consensusState tendermint.ConsensusState + prefix commitment.Prefix + proof commitment.Proof + expPass bool + }{ + // { + // name: "successful verification", + // clientState: tendermint.NewClientState(chainID, height), + // connection: conn, + // consensusState: tendermint.ConsensusState{ + // Root: commitment.NewRoot(suite.header.AppHash), + // }, + // prefix: commitment.NewPrefix([]byte("ibc")), + // expPass: true, + // }, + { + name: "ApplyPrefix failed", + clientState: tendermint.NewClientState(chainID, height), + commitment: []byte{}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.Prefix{}, + expPass: false, + }, + { + name: "latest client height < height", + clientState: tendermint.NewClientState(chainID, height-1), + commitment: []byte{}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "client is frozen", + clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + commitment: []byte{}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "proof verification failed", + clientState: tendermint.NewClientState(chainID, height), + commitment: []byte{}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.valSet.Hash(), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + proof: commitment.Proof{}, + expPass: false, + }, + } + + for i, tc := range testCases { + tc := tc + + err := tc.clientState.VerifyPacketCommitment( + height, tc.prefix, tc.proof, testPortID, testChannelID, testSequence, tc.commitment, tc.consensusState, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + +func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { + testCases := []struct { + name string + clientState tendermint.ClientState + ack []byte + consensusState tendermint.ConsensusState + prefix commitment.Prefix + proof commitment.Proof + expPass bool + }{ + // { + // name: "successful verification", + // clientState: tendermint.NewClientState(chainID, height), + // connection: conn, + // consensusState: tendermint.ConsensusState{ + // Root: commitment.NewRoot(suite.header.AppHash), + // }, + // prefix: commitment.NewPrefix([]byte("ibc")), + // expPass: true, + // }, + { + name: "ApplyPrefix failed", + clientState: tendermint.NewClientState(chainID, height), + ack: []byte{}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.Prefix{}, + expPass: false, + }, + { + name: "latest client height < height", + clientState: tendermint.NewClientState(chainID, height-1), + ack: []byte{}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "client is frozen", + clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + ack: []byte{}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "proof verification failed", + clientState: tendermint.NewClientState(chainID, height), + ack: []byte{}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.valSet.Hash(), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + proof: commitment.Proof{}, + expPass: false, + }, + } + + for i, tc := range testCases { + tc := tc + + err := tc.clientState.VerifyPacketAcknowledgement( + height, tc.prefix, tc.proof, testPortID, testChannelID, testSequence, tc.ack, tc.consensusState, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + +func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { + testCases := []struct { + name string + clientState tendermint.ClientState + consensusState tendermint.ConsensusState + prefix commitment.Prefix + proof commitment.Proof + expPass bool + }{ + // { + // name: "successful verification", + // clientState: tendermint.NewClientState(chainID, height), + // connection: conn, + // consensusState: tendermint.ConsensusState{ + // Root: commitment.NewRoot(suite.header.AppHash), + // }, + // prefix: commitment.NewPrefix([]byte("ibc")), + // expPass: true, + // }, + { + name: "ApplyPrefix failed", + clientState: tendermint.NewClientState(chainID, height), + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.Prefix{}, + expPass: false, + }, + { + name: "latest client height < height", + clientState: tendermint.NewClientState(chainID, height-1), + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "client is frozen", + clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "proof verification failed", + clientState: tendermint.NewClientState(chainID, height), + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.valSet.Hash(), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + proof: commitment.Proof{}, + expPass: false, + }, + } + + for i, tc := range testCases { + tc := tc + + err := tc.clientState.VerifyPacketAcknowledgementAbsence( + height, tc.prefix, tc.proof, testPortID, testChannelID, testSequence, tc.consensusState, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + +func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { + testCases := []struct { + name string + clientState tendermint.ClientState + consensusState tendermint.ConsensusState + prefix commitment.Prefix + proof commitment.Proof + expPass bool + }{ + // { + // name: "successful verification", + // clientState: tendermint.NewClientState(chainID, height), + // connection: conn, + // consensusState: tendermint.ConsensusState{ + // Root: commitment.NewRoot(suite.header.AppHash), + // }, + // prefix: commitment.NewPrefix([]byte("ibc")), + // expPass: true, + // }, + { + name: "ApplyPrefix failed", + clientState: tendermint.NewClientState(chainID, height), + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.Prefix{}, + expPass: false, + }, + { + name: "latest client height < height", + clientState: tendermint.NewClientState(chainID, height-1), + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "client is frozen", + clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + expPass: false, + }, + { + name: "proof verification failed", + clientState: tendermint.NewClientState(chainID, height), + consensusState: tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.valSet.Hash(), + }, + prefix: commitment.NewPrefix([]byte("ibc")), + proof: commitment.Proof{}, + expPass: false, + }, + } + + for i, tc := range testCases { + tc := tc + + err := tc.clientState.VerifyNextSequenceRecv( + height, tc.prefix, tc.proof, testPortID, testChannelID, testSequence, tc.consensusState, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + } + } +} diff --git a/x/ibc/02-client/types/tendermint/codec.go b/x/ibc/07-tendermint/codec.go similarity index 55% rename from x/ibc/02-client/types/tendermint/codec.go rename to x/ibc/07-tendermint/codec.go index a546ed313cef..22c6d508ed6a 100644 --- a/x/ibc/02-client/types/tendermint/codec.go +++ b/x/ibc/07-tendermint/codec.go @@ -4,18 +4,20 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ) -var SubModuleCdc = codec.New() +// SubModuleCdc defines the IBC tendermint client codec. +var SubModuleCdc *codec.Codec // RegisterCodec registers the Tendermint types func RegisterCodec(cdc *codec.Codec) { - codec.RegisterCrypto(cdc) - cdc.RegisterConcrete(Committer{}, "ibc/client/tendermint/Committer", nil) + cdc.RegisterConcrete(ClientState{}, "ibc/client/tendermint/ClientState", nil) cdc.RegisterConcrete(ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) cdc.RegisterConcrete(Header{}, "ibc/client/tendermint/Header", nil) - cdc.RegisterConcrete(Misbehaviour{}, "ibc/client/tendermint/Misbehaviour", nil) cdc.RegisterConcrete(Evidence{}, "ibc/client/tendermint/Evidence", nil) + + SetSubModuleCodec(cdc) } -func init() { - RegisterCodec(SubModuleCdc) +// SetSubModuleCodec sets the ibc tendermint client codec +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc } diff --git a/x/ibc/07-tendermint/consensus_state.go b/x/ibc/07-tendermint/consensus_state.go new file mode 100644 index 000000000000..a567c0deaa37 --- /dev/null +++ b/x/ibc/07-tendermint/consensus_state.go @@ -0,0 +1,35 @@ +package tendermint + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// ConsensusState defines a Tendermint consensus state +type ConsensusState struct { + Root commitment.RootI `json:"root" yaml:"root"` + ValidatorSetHash []byte `json:"validator_set_hash" yaml:"validator_set_hash"` +} + +// ClientType returns Tendermint +func (ConsensusState) ClientType() clientexported.ClientType { + return clientexported.Tendermint +} + +// GetRoot returns the commitment Root for the specific +func (cs ConsensusState) GetRoot() commitment.RootI { + return cs.Root +} + +// ValidateBasic defines a basic validation for the tendermint consensus state. +func (cs ConsensusState) ValidateBasic() error { + if cs.Root == nil || cs.Root.IsEmpty() { + return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "root cannot be empty") + } + if len(cs.ValidatorSetHash) == 0 { + return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "validator set hash cannot be empty") + } + return nil +} diff --git a/x/ibc/07-tendermint/consensus_state_test.go b/x/ibc/07-tendermint/consensus_state_test.go new file mode 100644 index 000000000000..9288d433a6ac --- /dev/null +++ b/x/ibc/07-tendermint/consensus_state_test.go @@ -0,0 +1,57 @@ +package tendermint_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func TestConsensusStateValidateBasic(t *testing.T) { + testCases := []struct { + msg string + consensusState tendermint.ConsensusState + expectPass bool + }{ + {"success", + tendermint.ConsensusState{ + Root: commitment.NewRoot([]byte("app_hash")), + ValidatorSetHash: []byte("valset_hash"), + }, + true}, + {"root is nil", + tendermint.ConsensusState{ + Root: nil, + ValidatorSetHash: []byte("valset_hash"), + }, + false}, + {"root is empty", + tendermint.ConsensusState{ + Root: commitment.Root{}, + ValidatorSetHash: []byte("valset_hash"), + }, + false}, + {"invalid client type", + tendermint.ConsensusState{ + Root: commitment.NewRoot([]byte("app_hash")), + ValidatorSetHash: []byte{}, + }, + false}, + } + + for i, tc := range testCases { + tc := tc + + require.Equal(t, tc.consensusState.ClientType(), clientexported.Tendermint) + require.Equal(t, tc.consensusState.GetRoot(), tc.consensusState.Root) + + if tc.expectPass { + require.NoError(t, tc.consensusState.ValidateBasic(), "valid test case %d failed: %s", i, tc.msg) + } else { + require.Error(t, tc.consensusState.ValidateBasic(), "invalid test case %d passed: %s", i, tc.msg) + } + } +} diff --git a/x/ibc/02-client/types/tendermint/doc.go b/x/ibc/07-tendermint/doc.go similarity index 100% rename from x/ibc/02-client/types/tendermint/doc.go rename to x/ibc/07-tendermint/doc.go diff --git a/x/ibc/02-client/types/tendermint/evidence.go b/x/ibc/07-tendermint/evidence.go similarity index 59% rename from x/ibc/02-client/types/tendermint/evidence.go rename to x/ibc/07-tendermint/evidence.go index 2ebdcb81aa3b..82b78ea03370 100644 --- a/x/ibc/02-client/types/tendermint/evidence.go +++ b/x/ibc/07-tendermint/evidence.go @@ -1,6 +1,8 @@ package tendermint import ( + "math" + yaml "gopkg.in/yaml.v2" "github.com/tendermint/tendermint/crypto/tmhash" @@ -9,22 +11,39 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) -var _ evidenceexported.Evidence = Evidence{} +var ( + _ evidenceexported.Evidence = Evidence{} + _ clientexported.Misbehaviour = Evidence{} +) // Evidence is a wrapper over tendermint's DuplicateVoteEvidence // that implements Evidence interface expected by ICS-02 type Evidence struct { - Header1 Header `json:"header1" yaml:"header1"` - Header2 Header `json:"header2" yaml:"header2"` - ChainID string `json:"chain_id" yaml:"chain_id"` + ClientID string `json:"client_id" yaml:"client_id"` + FromValidatorSet *tmtypes.ValidatorSet `json:"from_validator_set" yaml:"from_validator_set"` + Header1 Header `json:"header1" yaml:"header1"` + Header2 Header `json:"header2" yaml:"header2"` + ChainID string `json:"chain_id" yaml:"chain_id"` +} + +// ClientType is Tendermint light client +func (ev Evidence) ClientType() clientexported.ClientType { + return clientexported.Tendermint +} + +// GetClientID returns the ID of the client that committed a misbehaviour. +func (ev Evidence) GetClientID() string { + return ev.ClientID } // Route implements Evidence interface func (ev Evidence) Route() string { - return "client" + return clienttypes.SubModuleName } // Type implements Evidence interface @@ -34,6 +53,7 @@ func (ev Evidence) Type() string { // String implements Evidence interface func (ev Evidence) String() string { + // FIXME: implement custom marshaller bz, err := yaml.Marshal(ev) if err != nil { panic(err) @@ -43,36 +63,43 @@ func (ev Evidence) String() string { // Hash implements Evidence interface func (ev Evidence) Hash() tmbytes.HexBytes { - return tmhash.Sum(SubModuleCdc.MustMarshalBinaryBare(ev)) + bz := SubModuleCdc.MustMarshalBinaryBare(ev) + return tmhash.Sum(bz) } // GetHeight returns the height at which misbehaviour occurred +// +// NOTE: assumes that evidence headers have the same height func (ev Evidence) GetHeight() int64 { - return ev.Header1.Height + return int64(math.Min(float64(ev.Header1.Height), float64(ev.Header2.Height))) } // ValidateBasic implements Evidence interface func (ev Evidence) ValidateBasic() error { + if err := host.DefaultClientIdentifierValidator(ev.ClientID); err != nil { + return sdkerrors.Wrap(clienttypes.ErrInvalidEvidence, err.Error()) + } + // ValidateBasic on both validators if err := ev.Header1.ValidateBasic(ev.ChainID); err != nil { return sdkerrors.Wrap( - errors.ErrInvalidEvidence, + clienttypes.ErrInvalidEvidence, sdkerrors.Wrap(err, "header 1 failed validation").Error(), ) } if err := ev.Header2.ValidateBasic(ev.ChainID); err != nil { return sdkerrors.Wrap( - errors.ErrInvalidEvidence, + clienttypes.ErrInvalidEvidence, sdkerrors.Wrap(err, "header 2 failed validation").Error(), ) } // Ensure that Heights are the same if ev.Header1.Height != ev.Header2.Height { - return sdkerrors.Wrapf(errors.ErrInvalidEvidence, "headers in evidence are on different heights (%d ≠ %d)", ev.Header1.Height, ev.Header2.Height) + return sdkerrors.Wrapf(clienttypes.ErrInvalidEvidence, "headers in evidence are on different heights (%d ≠ %d)", ev.Header1.Height, ev.Header2.Height) } // Ensure that Commit Hashes are different if ev.Header1.Commit.BlockID.Equals(ev.Header2.Commit.BlockID) { - return sdkerrors.Wrap(errors.ErrInvalidEvidence, "headers commit to same blockID") + return sdkerrors.Wrap(clienttypes.ErrInvalidEvidence, "headers commit to same blockID") } if err := ValidCommit(ev.ChainID, ev.Header1.Commit, ev.Header1.ValidatorSet); err != nil { return err @@ -91,7 +118,7 @@ func (ev Evidence) ValidateBasic() error { func ValidCommit(chainID string, commit *tmtypes.Commit, valSet *tmtypes.ValidatorSet) (err error) { defer func() { if r := recover(); r != nil { - err = sdkerrors.Wrapf(errors.ErrInvalidEvidence, "invalid commit: %v", r) + err = sdkerrors.Wrapf(clienttypes.ErrInvalidEvidence, "invalid commit: %v", r) } }() @@ -102,7 +129,7 @@ func ValidCommit(chainID string, commit *tmtypes.Commit, valSet *tmtypes.Validat // Check that ValidatorSet did indeed commit to blockID in Commit if !ok || !blockID.Equals(commit.BlockID) { - return sdkerrors.Wrap(errors.ErrInvalidEvidence, "validator set did not commit to header 1") + return sdkerrors.Wrap(clienttypes.ErrInvalidEvidence, "validator set did not commit to header 1") } return nil diff --git a/x/ibc/07-tendermint/evidence_test.go b/x/ibc/07-tendermint/evidence_test.go new file mode 100644 index 000000000000..4fb819469ef2 --- /dev/null +++ b/x/ibc/07-tendermint/evidence_test.go @@ -0,0 +1,196 @@ +package tendermint_test + +import ( + "bytes" + + "github.com/tendermint/tendermint/crypto/tmhash" + tmbytes "github.com/tendermint/tendermint/libs/bytes" + tmtypes "github.com/tendermint/tendermint/types" + + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" +) + +func (suite *TendermintTestSuite) TestEvidence() { + signers := []tmtypes.PrivValidator{suite.privVal} + + ev := tendermint.Evidence{ + Header1: suite.header, + Header2: tendermint.CreateTestHeader(chainID, height, suite.valSet, suite.valSet, signers), + FromValidatorSet: suite.valSet, + ChainID: chainID, + ClientID: "gaiamainnet", + } + + suite.Require().Equal(ev.ClientType(), clientexported.Tendermint) + suite.Require().Equal(ev.GetClientID(), "gaiamainnet") + suite.Require().Equal(ev.Route(), "client") + suite.Require().Equal(ev.Type(), "client_misbehaviour") + suite.Require().Equal(ev.Hash(), tmbytes.HexBytes(tmhash.Sum(tendermint.SubModuleCdc.MustMarshalBinaryBare(ev)))) + suite.Require().Equal(ev.GetHeight(), int64(height)) +} + +func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), height) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + + signers := []tmtypes.PrivValidator{suite.privVal} + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} + } + + altSigners := []tmtypes.PrivValidator{altPrivVal} + + testCases := []struct { + name string + evidence tendermint.Evidence + malleateEvidence func(ev *tendermint.Evidence) error + expPass bool + }{ + { + "valid evidence", + tendermint.Evidence{ + Header1: suite.header, + Header2: tendermint.CreateTestHeader(chainID, height, suite.valSet, bothValSet, signers), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *tendermint.Evidence) error { return nil }, + true, + }, + { + "invalid client ID ", + tendermint.Evidence{ + Header1: suite.header, + Header2: tendermint.CreateTestHeader(chainID, height, suite.valSet, bothValSet, signers), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: "GAIA", + }, + func(ev *tendermint.Evidence) error { return nil }, + false, + }, + { + "wrong chainID on header1", + tendermint.Evidence{ + Header1: suite.header, + Header2: tendermint.CreateTestHeader("ethermint", height, suite.valSet, bothValSet, signers), + FromValidatorSet: bothValSet, + ChainID: "ethermint", + ClientID: "gaiamainnet", + }, + func(ev *tendermint.Evidence) error { return nil }, + false, + }, + { + "wrong chainID on header2", + tendermint.Evidence{ + Header1: suite.header, + Header2: tendermint.CreateTestHeader("ethermint", height, suite.valSet, bothValSet, signers), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *tendermint.Evidence) error { return nil }, + false, + }, + { + "mismatched heights", + tendermint.Evidence{ + Header1: suite.header, + Header2: tendermint.CreateTestHeader(chainID, 6, suite.valSet, bothValSet, signers), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *tendermint.Evidence) error { return nil }, + false, + }, + { + "same block id", + tendermint.Evidence{ + Header1: suite.header, + Header2: suite.header, + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *tendermint.Evidence) error { return nil }, + false, + }, + { + "header 1 doesn't have 2/3 majority", + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), + Header2: suite.header, + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *tendermint.Evidence) error { + // voteSet contains only altVal which is less than 2/3 of total power (height/1height) + wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header1.Height, 1, tmtypes.PrecommitType, altValSet) + var err error + ev.Header1.Commit, err = tmtypes.MakeCommit(ev.Header1.Commit.BlockID, ev.Header2.Height, ev.Header1.Commit.Round, wrongVoteSet, altSigners) + return err + }, + false, + }, + { + "header 2 doesn't have 2/3 majority", + tendermint.Evidence{ + Header1: suite.header, + Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *tendermint.Evidence) error { + // voteSet contains only altVal which is less than 2/3 of total power (height/1height) + wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header2.Height, 1, tmtypes.PrecommitType, altValSet) + var err error + ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round, wrongVoteSet, altSigners) + return err + }, + false, + }, + { + "validators sign off on wrong commit", + tendermint.Evidence{ + Header1: suite.header, + Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *tendermint.Evidence) error { + ev.Header2.Commit.BlockID = tendermint.MakeBlockID(tmhash.Sum([]byte("other_hash")), 3, tmhash.Sum([]byte("other_partset"))) + return nil + }, + false, + }, + } + + for i, tc := range testCases { + tc := tc + + err := tc.malleateEvidence(&tc.evidence) + suite.Require().NoError(err) + + if tc.expPass { + suite.Require().NoError(tc.evidence.ValidateBasic(), "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(tc.evidence.ValidateBasic(), "invalid test case %d passed: %s", i, tc.name) + } + } +} diff --git a/x/ibc/07-tendermint/header.go b/x/ibc/07-tendermint/header.go new file mode 100644 index 000000000000..fb53e36641b8 --- /dev/null +++ b/x/ibc/07-tendermint/header.go @@ -0,0 +1,72 @@ +package tendermint + +import ( + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" +) + +var _ clientexported.Header = Header{} + +// Header defines the Tendermint consensus Header +type Header struct { + tmtypes.SignedHeader // contains the commitment root + ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` +} + +// ClientType defines that the Header is a Tendermint consensus algorithm +func (h Header) ClientType() clientexported.ClientType { + return clientexported.Tendermint +} + +// GetHeight returns the current height +// +// NOTE: also referred as `sequence` +func (h Header) GetHeight() uint64 { + return uint64(h.Height) +} + +// ValidateBasic calls the SignedHeader ValidateBasic function +// and checks that validatorsets are not nil +func (h Header) ValidateBasic(chainID string) error { + if err := h.SignedHeader.ValidateBasic(chainID); err != nil { + return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, err.Error()) + } + if h.ValidatorSet == nil { + return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set is nil") + } + return nil +} + +// ToABCIHeader parses the header to an ABCI header type. +// NOTE: only for testing use. +func (h Header) ToABCIHeader() abci.Header { + return abci.Header{ + Version: abci.Version{ + App: h.Version.App.Uint64(), + Block: h.Version.Block.Uint64(), + }, + ChainID: h.ChainID, + Height: h.Height, + Time: h.Time, + LastBlockId: abci.BlockID{ + Hash: h.LastBlockID.Hash, + PartsHeader: abci.PartSetHeader{ + Total: int32(h.LastBlockID.PartsHeader.Total), + Hash: h.LastBlockID.PartsHeader.Hash, + }, + }, + LastCommitHash: h.LastCommitHash, + DataHash: h.DataHash, + ValidatorsHash: h.ValidatorsHash, + NextValidatorsHash: h.NextValidatorsHash, + ConsensusHash: h.ConsensusHash, + AppHash: h.AppHash, + LastResultsHash: h.LastResultsHash, + EvidenceHash: h.EvidenceHash, + ProposerAddress: h.ProposerAddress, + } +} diff --git a/x/ibc/07-tendermint/header_test.go b/x/ibc/07-tendermint/header_test.go new file mode 100644 index 000000000000..e88362d230d3 --- /dev/null +++ b/x/ibc/07-tendermint/header_test.go @@ -0,0 +1,30 @@ +package tendermint_test + +import ( + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" +) + +func (suite *TendermintTestSuite) TestHeaderValidateBasic() { + testCases := []struct { + name string + header tendermint.Header + chainID string + expPass bool + }{ + {"valid header", suite.header, chainID, true}, + {"signed header basic validation failed", suite.header, "chainID", false}, + {"validator set nil", tendermint.Header{suite.header.SignedHeader, nil}, chainID, false}, + } + + suite.Require().Equal(clientexported.Tendermint, suite.header.ClientType()) + + for i, tc := range testCases { + tc := tc + if tc.expPass { + suite.Require().NoError(tc.header.ValidateBasic(tc.chainID), "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(tc.header.ValidateBasic(tc.chainID), "invalid test case %d passed: %s", i, tc.name) + } + } +} diff --git a/x/ibc/07-tendermint/misbehaviour.go b/x/ibc/07-tendermint/misbehaviour.go new file mode 100644 index 000000000000..15eb2b935c6a --- /dev/null +++ b/x/ibc/07-tendermint/misbehaviour.go @@ -0,0 +1,90 @@ +package tendermint + +import ( + "bytes" + "errors" + "fmt" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +// CheckMisbehaviourAndUpdateState determines whether or not two conflicting +// headers at the same height would have convinced the light client. +// +// NOTE: assumes provided height is the height at which the consensusState is +// stored. +func CheckMisbehaviourAndUpdateState( + clientState clientexported.ClientState, + consensusState clientexported.ConsensusState, + misbehaviour clientexported.Misbehaviour, + height uint64, // height at which the consensus state was loaded +) (clientexported.ClientState, error) { + + // cast the interface to specific types before checking for misbehaviour + tmClientState, ok := clientState.(ClientState) + if !ok { + return nil, sdkerrors.Wrap(clienttypes.ErrInvalidClientType, "client state type is not Tendermint") + } + + tmConsensusState, ok := consensusState.(ConsensusState) + if !ok { + return nil, sdkerrors.Wrap(clienttypes.ErrInvalidClientType, "consensus state is not Tendermint") + } + + tmEvidence, ok := misbehaviour.(Evidence) + if !ok { + return nil, sdkerrors.Wrap(clienttypes.ErrInvalidClientType, "evidence type is not Tendermint") + } + + if err := checkMisbehaviour(tmClientState, tmConsensusState, tmEvidence, height); err != nil { + return nil, sdkerrors.Wrap(clienttypes.ErrInvalidEvidence, err.Error()) + } + + tmClientState.FrozenHeight = uint64(tmEvidence.GetHeight()) + + return tmClientState, nil +} + +// checkMisbehaviour checks if the evidence provided is a valid light client misbehaviour +func checkMisbehaviour( + clientState ClientState, consensusState ConsensusState, evidence Evidence, height uint64, +) error { + // NOTE: header height and commitment root assertions are checked with the + // evidence and msg ValidateBasic functions at the AnteHandler level. + + // check if provided height matches the headers' height + if height != uint64(evidence.GetHeight()) { + return sdkerrors.Wrapf( + ibctypes.ErrInvalidHeight, + "height ≠ evidence header height (%d ≠ %d)", height, evidence.GetHeight(), + ) + } + + if !bytes.Equal(consensusState.ValidatorSetHash, evidence.FromValidatorSet.Hash()) { + return errors.New( + "the consensus state's validator set hash doesn't match the evidence's one", + ) + } + + // Evidence is within the trusting period. ValidatorSet must have 2/3 similarity with trusted FromValidatorSet + // check that the validator sets on both headers are valid given the last trusted validatorset + // less than or equal to evidence height + if err := evidence.FromValidatorSet.VerifyFutureCommit( + evidence.Header1.ValidatorSet, evidence.ChainID, + evidence.Header1.Commit.BlockID, evidence.Header1.Height, evidence.Header1.Commit, + ); err != nil { + return fmt.Errorf("validator set in header 1 has too much change from last known validator set: %v", err) + } + + if err := evidence.FromValidatorSet.VerifyFutureCommit( + evidence.Header2.ValidatorSet, evidence.ChainID, + evidence.Header2.Commit.BlockID, evidence.Header2.Height, evidence.Header2.Commit, + ); err != nil { + return fmt.Errorf("validator set in header 2 has too much change from last known validator set: %v", err) + } + + return nil +} diff --git a/x/ibc/07-tendermint/misbehaviour_test.go b/x/ibc/07-tendermint/misbehaviour_test.go new file mode 100644 index 000000000000..92925d8582a1 --- /dev/null +++ b/x/ibc/07-tendermint/misbehaviour_test.go @@ -0,0 +1,140 @@ +package tendermint_test + +import ( + "bytes" + + "github.com/tendermint/tendermint/crypto/tmhash" + tmtypes "github.com/tendermint/tendermint/types" + + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func (suite *TendermintTestSuite) TestCheckMisbehaviour() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), 4) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} + } + + altSigners := []tmtypes.PrivValidator{altPrivVal} + + testCases := []struct { + name string + clientState tendermint.ClientState + consensusState tendermint.ConsensusState + evidence tendermint.Evidence + height uint64 + expPass bool + }{ + { + "valid misbehavior evidence", + tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, + tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, suite.valSet, bothSigners), + Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: chainID, + }, + height, + true, + }, + { + "height doesn't match provided evidence", + tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, + tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, suite.valSet, bothSigners), + Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: chainID, + }, + 0, + false, + }, + { + "consensus state's valset hash different from evidence", + tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, + tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: suite.valSet.Hash()}, + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, suite.valSet, bothSigners), + Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: chainID, + }, + height, + false, + }, + { + "first valset has too much change", + tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, + tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(chainID, height, altValSet, bothValSet, altSigners), + Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: chainID, + }, + height, + false, + }, + { + "second valset has too much change", + tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, + tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), + Header2: tendermint.CreateTestHeader(chainID, height, altValSet, bothValSet, altSigners), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: chainID, + }, + height, + false, + }, + { + "both valsets have too much change", + tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, + tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, + tendermint.Evidence{ + Header1: tendermint.CreateTestHeader(chainID, height, altValSet, altValSet, altSigners), + Header2: tendermint.CreateTestHeader(chainID, height, altValSet, bothValSet, altSigners), + FromValidatorSet: bothValSet, + ChainID: chainID, + ClientID: chainID, + }, + height, + false, + }, + } + + for i, tc := range testCases { + tc := tc + + clientState, err := tendermint.CheckMisbehaviourAndUpdateState(tc.clientState, tc.consensusState, tc.evidence, tc.height) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.name) + suite.Require().True(clientState.IsFrozen(), "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + suite.Require().Nil(clientState, "invalid test case %d passed: %s", i, tc.name) + } + } +} diff --git a/x/ibc/07-tendermint/tendermint_test.go b/x/ibc/07-tendermint/tendermint_test.go new file mode 100644 index 000000000000..3a41cc74002c --- /dev/null +++ b/x/ibc/07-tendermint/tendermint_test.go @@ -0,0 +1,43 @@ +package tendermint_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/codec" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +const ( + chainID = "gaia" + height = 4 +) + +type TendermintTestSuite struct { + suite.Suite + + cdc *codec.Codec + privVal tmtypes.PrivValidator + valSet *tmtypes.ValidatorSet + header tendermint.Header +} + +func (suite *TendermintTestSuite) SetupTest() { + suite.cdc = codec.New() + codec.RegisterCrypto(suite.cdc) + tendermint.RegisterCodec(suite.cdc) + commitment.RegisterCodec(suite.cdc) + + suite.privVal = tmtypes.NewMockPV() + val := tmtypes.NewValidator(suite.privVal.GetPubKey(), 10) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) + suite.header = tendermint.CreateTestHeader(chainID, height, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) +} + +func TestTendermintTestSuite(t *testing.T) { + suite.Run(t, new(TendermintTestSuite)) +} diff --git a/x/ibc/02-client/types/tendermint/test_utils.go b/x/ibc/07-tendermint/test_utils.go similarity index 77% rename from x/ibc/02-client/types/tendermint/test_utils.go rename to x/ibc/07-tendermint/test_utils.go index 94d92e418299..32373fab3fd6 100644 --- a/x/ibc/02-client/types/tendermint/test_utils.go +++ b/x/ibc/07-tendermint/test_utils.go @@ -10,7 +10,7 @@ import ( ) // Copied unimported test functions from tmtypes to use them here -func makeBlockID(hash []byte, partSetSize int, partSetHash []byte) tmtypes.BlockID { +func MakeBlockID(hash []byte, partSetSize int, partSetHash []byte) tmtypes.BlockID { return tmtypes.BlockID{ Hash: hash, PartsHeader: tmtypes.PartSetHeader{ @@ -18,10 +18,10 @@ func makeBlockID(hash []byte, partSetSize int, partSetHash []byte) tmtypes.Block Hash: partSetHash, }, } - } -func MakeHeader(chainID string, height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { +// CreateTestHeader creates a mock header for testing only. +func CreateTestHeader(chainID string, height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { vsetHash := valSet.Hash() nextHash := nextValSet.Hash() timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) @@ -30,7 +30,7 @@ func MakeHeader(chainID string, height int64, valSet *tmtypes.ValidatorSet, next ChainID: chainID, Height: height, Time: timestamp, - LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt64, make([]byte, tmhash.Size)), + LastBlockID: MakeBlockID(make([]byte, tmhash.Size), math.MaxInt64, make([]byte, tmhash.Size)), LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), DataHash: tmhash.Sum([]byte("data_hash")), ValidatorsHash: vsetHash, @@ -42,7 +42,7 @@ func MakeHeader(chainID string, height int64, valSet *tmtypes.ValidatorSet, next ProposerAddress: valSet.Proposer.Address, } hhash := tmHeader.Hash() - blockID := makeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) + blockID := MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) voteSet := tmtypes.NewVoteSet(chainID, height, 1, tmtypes.PrecommitType, valSet) commit, err := tmtypes.MakeCommit(blockID, height, 1, voteSet, signers) if err != nil { @@ -55,8 +55,7 @@ func MakeHeader(chainID string, height int64, valSet *tmtypes.ValidatorSet, next } return Header{ - SignedHeader: signedHeader, - ValidatorSet: valSet, - NextValidatorSet: nextValSet, + SignedHeader: signedHeader, + ValidatorSet: valSet, } } diff --git a/x/ibc/07-tendermint/update.go b/x/ibc/07-tendermint/update.go new file mode 100644 index 000000000000..262443165637 --- /dev/null +++ b/x/ibc/07-tendermint/update.go @@ -0,0 +1,72 @@ +package tendermint + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// CheckValidityAndUpdateState checks if the provided header is valid and updates +// the consensus state if appropriate. It returns an error if: +// - the client or header provided are not parseable to tendermint types +// - the header is invalid +// - header height is lower than the latest client height +// - header valset commit verification fails +// +// Tendermint client validity checking uses the bisection algorithm described +// in the [Tendermint spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md). +func CheckValidityAndUpdateState( + clientState clientexported.ClientState, header clientexported.Header, chainID string, +) (clientexported.ClientState, clientexported.ConsensusState, error) { + tmClientState, ok := clientState.(ClientState) + if !ok { + return nil, nil, sdkerrors.Wrap( + clienttypes.ErrInvalidClientType, "light client is not from Tendermint", + ) + } + + tmHeader, ok := header.(Header) + if !ok { + return nil, nil, sdkerrors.Wrap( + clienttypes.ErrInvalidHeader, "header is not from Tendermint", + ) + } + + if err := checkValidity(tmClientState, tmHeader, chainID); err != nil { + return nil, nil, err + } + + tmClientState, consensusState := update(tmClientState, tmHeader) + return tmClientState, consensusState, nil +} + +// checkValidity checks if the Tendermint header is valid +// +// CONTRACT: assumes header.Height > consensusState.Height +func checkValidity(clientState ClientState, header Header, chainID string) error { + if header.GetHeight() < clientState.LatestHeight { + return sdkerrors.Wrapf( + clienttypes.ErrInvalidHeader, + "header height < latest client state height (%d < %d)", header.GetHeight(), clientState.LatestHeight, + ) + } + + // basic consistency check + if err := header.ValidateBasic(chainID); err != nil { + return err + } + + return header.ValidatorSet.VerifyCommit(header.ChainID, header.Commit.BlockID, header.Height, header.Commit) +} + +// update the consensus state from a new header +func update(clientState ClientState, header Header) (ClientState, ConsensusState) { + clientState.LatestHeight = header.GetHeight() + consensusState := ConsensusState{ + Root: commitment.NewRoot(header.AppHash), + ValidatorSetHash: header.ValidatorSet.Hash(), + } + + return clientState, consensusState +} diff --git a/x/ibc/07-tendermint/update_test.go b/x/ibc/07-tendermint/update_test.go new file mode 100644 index 000000000000..7e46a97da17a --- /dev/null +++ b/x/ibc/07-tendermint/update_test.go @@ -0,0 +1,55 @@ +package tendermint_test + +import ( + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func (suite *TendermintTestSuite) TestCheckValidity() { + testCases := []struct { + name string + clientState tendermint.ClientState + chainID string + expPass bool + }{ + { + name: "successful update", + clientState: tendermint.NewClientState(chainID, height), + chainID: chainID, + expPass: true, + }, + { + name: "header basic validation failed", + clientState: tendermint.NewClientState(chainID, height), + chainID: "cosmoshub", + expPass: false, + }, + { + name: "header height < latest client height", + clientState: tendermint.NewClientState(chainID, height+1), + chainID: chainID, + expPass: false, + }, + } + + for i, tc := range testCases { + tc := tc + + expectedConsensus := tendermint.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSetHash: suite.header.ValidatorSet.Hash(), + } + + clientState, consensusState, err := tendermint.CheckValidityAndUpdateState(tc.clientState, suite.header, tc.chainID) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + suite.Require().Equal(suite.header.GetHeight(), clientState.GetLatestHeight(), "valid test case %d failed: %s", i, tc.name) + suite.Require().Equal(expectedConsensus, consensusState, "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + suite.Require().Nil(clientState, "invalid test case %d passed: %s", i, tc.name) + suite.Require().Nil(consensusState, "invalid test case %d passed: %s", i, tc.name) + } + } +} diff --git a/x/ibc/20-transfer/client/utils/utils.go b/x/ibc/20-transfer/client/utils/utils.go index b89b2116b8d4..b2fe98034b5a 100644 --- a/x/ibc/20-transfer/client/utils/utils.go +++ b/x/ibc/20-transfer/client/utils/utils.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // QueryNextSequenceRecv queries the store to get the next receive sequence and @@ -16,7 +17,7 @@ func QueryNextSequenceRecv( ) (channeltypes.RecvResponse, error) { req := abci.RequestQuery{ Path: "store/ibc/key", - Data: channeltypes.KeyNextSequenceRecv(portID, channelID), + Data: ibctypes.KeyNextSequenceRecv(portID, channelID), Prove: prove, } diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 9dcf9e9b1060..8a87dae74783 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -12,9 +12,11 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -34,7 +36,7 @@ const ( testChannel1 = "firstchannel" testChannel2 = "secondchannel" - testChannelOrder = channel.UNORDERED + testChannelOrder = channelexported.UNORDERED testChannelVersion = "1.0" ) @@ -71,7 +73,7 @@ func (suite *HandlerTestSuite) SetupTest() { suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) suite.createClient() - suite.createConnection(connection.OPEN) + suite.createConnection(connectionexported.OPEN) } func (suite *HandlerTestSuite) createClient() { @@ -81,12 +83,9 @@ func (suite *HandlerTestSuite) createClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), + consensusState := tendermint.ConsensusState{ Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, - NextValidatorSet: suite.valSet, + ValidatorSetHash: suite.valSet.Hash(), } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) @@ -101,17 +100,14 @@ func (suite *HandlerTestSuite) updateClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - state := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + state := tendermint.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), } - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) - suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, 1, state) } -func (suite *HandlerTestSuite) createConnection(state connection.State) { +func (suite *HandlerTestSuite) createConnection(state connectionexported.State) { connection := connection.ConnectionEnd{ State: state, ClientID: testClient, @@ -126,19 +122,20 @@ func (suite *HandlerTestSuite) createConnection(state connection.State) { suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) } -func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channel.State) { +func (suite *HandlerTestSuite) createChannel( + portID, channnelID, connnnectionID, counterpartyPortID, counterpartyChannelID string, state channelexported.State) { ch := channel.Channel{ State: state, Ordering: testChannelOrder, Counterparty: channel.Counterparty{ - PortID: counterpartyPort, - ChannelID: counterpartyChan, + PortID: counterpartyPortID, + ChannelID: counterpartyChannelID, }, - ConnectionHops: []string{connID}, + ConnectionHops: []string{connnnectionID}, Version: testChannelVersion, } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, channnelID, ch) } func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { @@ -166,7 +163,7 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // channel does not exist - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) res, err = handler(suite.ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // next send sequence not found diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index 05639f581b14..c57ca802fa4c 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -63,6 +63,8 @@ func (k Keeper) GetTransferAccount(ctx sdk.Context) supplyexported.ModuleAccount return k.supplyKeeper.GetModuleAccount(ctx, types.GetModuleAccountName()) } +// PacketExecuted defines a wrapper function for the channel Keeper's function +// in order to expose it to the ICS20 trasfer handler. func (k Keeper) PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketDataI) error { return k.channelKeeper.PacketExecuted(ctx, packet, acknowledgement) } diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index b4d4132c7109..af4ea22a8e64 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -13,8 +13,8 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) @@ -30,7 +30,7 @@ const ( testChannel1 = "firstchannel" testChannel2 = "secondchannel" - testChannelOrder = channel.UNORDERED + testChannelOrder = channelexported.UNORDERED testChannelVersion = "1.0" ) @@ -67,7 +67,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) suite.createClient() - suite.createConnection(connection.OPEN) + suite.createConnection(connectionexported.OPEN) } func (suite *KeeperTestSuite) TestGetTransferAccount() { diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index d58412d26b1d..8bfa6efcfb97 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -202,5 +202,5 @@ func (k Keeper) createOutgoingPacket( destinationChannel, ) - return k.channelKeeper.SendPacket(ctx, packet, k.boundedCapability) + return k.channelKeeper.SendPacket(ctx, packet) } diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index b22135c409b3..74b80429b09e 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -6,9 +6,11 @@ import ( abci "github.com/tendermint/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" - clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -22,12 +24,9 @@ func (suite *KeeperTestSuite) createClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), + consensusState := tendermint.ConsensusState{ Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, - NextValidatorSet: suite.valSet, + ValidatorSetHash: suite.valSet.Hash(), } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) @@ -42,17 +41,14 @@ func (suite *KeeperTestSuite) updateClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - state := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + state := tendermint.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), } - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) - suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, 1, state) } -func (suite *KeeperTestSuite) createConnection(state connection.State) { +func (suite *KeeperTestSuite) createConnection(state connectionexported.State) { connection := connection.ConnectionEnd{ State: state, ClientID: testClient, @@ -67,7 +63,7 @@ func (suite *KeeperTestSuite) createConnection(state connection.State) { suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) } -func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channel.State) { +func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channelexported.State) { ch := channel.Channel{ State: state, Ordering: testChannelOrder, @@ -104,7 +100,7 @@ func (suite *KeeperTestSuite) TestSendTransfer() { err := suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // channel does not exist - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channel.OPEN) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // next send sequence not found diff --git a/x/ibc/20-transfer/types/codec.go b/x/ibc/20-transfer/types/codec.go index 1b9680c8da3d..ff87c7fcfeaf 100644 --- a/x/ibc/20-transfer/types/codec.go +++ b/x/ibc/20-transfer/types/codec.go @@ -6,13 +6,15 @@ import ( commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) +// ModuleCdc defines the IBC transfer codec. +var ModuleCdc = codec.New() + +// RegisterCodec registers the IBC transfer types func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgTransfer{}, "ibc/transfer/MsgTransfer", nil) cdc.RegisterConcrete(PacketDataTransfer{}, "ibc/transfer/PacketDataTransfer", nil) } -var ModuleCdc = codec.New() - func init() { RegisterCodec(ModuleCdc) channel.RegisterCodec(ModuleCdc) diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index a8bd48a215de..b79fbe5313eb 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -18,7 +18,7 @@ type BankKeeper interface { type ChannelKeeper interface { GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channel.Channel, found bool) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) - SendPacket(ctx sdk.Context, packet channelexported.PacketI, portCapability sdk.CapabilityKey) error + SendPacket(ctx sdk.Context, packet channelexported.PacketI) error PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketDataI) error } diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/merkle.go index 39a355fc9ce8..d3649e7313f9 100644 --- a/x/ibc/23-commitment/merkle.go +++ b/x/ibc/23-commitment/merkle.go @@ -41,6 +41,11 @@ func (r Root) GetHash() []byte { return r.Hash } +// IsEmpty returns true if the root is empty +func (r Root) IsEmpty() bool { + return len(r.GetHash()) == 0 +} + var _ PrefixI = Prefix{} // Prefix is merkle path prefixed to the key. @@ -66,6 +71,11 @@ func (p Prefix) Bytes() []byte { return p.KeyPrefix } +// IsEmpty returns true if the prefix is empty +func (p Prefix) IsEmpty() bool { + return len(p.Bytes()) == 0 +} + var _ PathI = Path{} // Path is the path used to verify commitment proofs, which can be an arbitrary @@ -105,6 +115,11 @@ func (p Path) Pretty() string { return path } +// IsEmpty returns true if the path is empty +func (p Path) IsEmpty() bool { + return len(p.KeyPath) == 0 +} + // ApplyPrefix constructs a new commitment path from the arguments. It interprets // the path argument in the context of the prefix argument. // @@ -116,10 +131,9 @@ func ApplyPrefix(prefix PrefixI, path string) (Path, error) { return Path{}, err } - if prefix == nil || len(prefix.Bytes()) == 0 { + if prefix == nil || prefix.IsEmpty() { return Path{}, errors.New("prefix can't be empty") } - return NewPath([]string{string(prefix.Bytes()), path}), nil } @@ -139,22 +153,33 @@ func (Proof) GetCommitmentType() Type { } // VerifyMembership verifies the membership pf a merkle proof against the given root, path, and value. -func (proof Proof) VerifyMembership(root RootI, path PathI, value []byte) bool { +func (proof Proof) VerifyMembership(root RootI, path PathI, value []byte) error { + if proof.IsEmpty() || root == nil || root.IsEmpty() || path == nil || path.IsEmpty() || len(value) == 0 { + return errors.New("empty params or proof") + } + runtime := rootmulti.DefaultProofRuntime() - err := runtime.VerifyValue(proof.Proof, root.GetHash(), path.String(), value) - return err == nil + return runtime.VerifyValue(proof.Proof, root.GetHash(), path.String(), value) } // VerifyNonMembership verifies the absence of a merkle proof against the given root and path. -func (proof Proof) VerifyNonMembership(root RootI, path PathI) bool { +func (proof Proof) VerifyNonMembership(root RootI, path PathI) error { + if proof.IsEmpty() || root == nil || root.IsEmpty() || path == nil || path.IsEmpty() { + return errors.New("empty params or proof") + } + runtime := rootmulti.DefaultProofRuntime() - err := runtime.VerifyAbsence(proof.Proof, root.GetHash(), path.String()) - return err == nil + return runtime.VerifyAbsence(proof.Proof, root.GetHash(), path.String()) +} + +// IsEmpty returns true if the root is empty +func (proof Proof) IsEmpty() bool { + return (proof == Proof{}) || proof.Proof == nil } // ValidateBasic checks if the proof is empty. func (proof Proof) ValidateBasic() error { - if (proof == Proof{}) || proof.Proof == nil { + if proof.IsEmpty() { return ErrInvalidProof } return nil diff --git a/x/ibc/23-commitment/merkle_test.go b/x/ibc/23-commitment/merkle_test.go index 7dcb5cbfd0fc..4ce2c697df4d 100644 --- a/x/ibc/23-commitment/merkle_test.go +++ b/x/ibc/23-commitment/merkle_test.go @@ -48,13 +48,18 @@ func (suite *MerkleTestSuite) TestVerifyMembership() { } for i, tc := range cases { + tc := tc suite.Run(tc.name, func() { root := commitment.NewRoot(tc.root) path := commitment.NewPath(tc.pathArr) - ok := proof.VerifyMembership(root, path, tc.value) + err := proof.VerifyMembership(root, path, tc.value) - require.True(suite.T(), ok == tc.shouldPass, "Test case %d failed", i) + if tc.shouldPass { + suite.Require().NoError(err, "test case %d should have passed", i) + } else { + suite.Require().Error(err, "test case %d should have failed", i) + } }) } @@ -95,13 +100,19 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() { } for i, tc := range cases { + tc := tc + suite.Run(tc.name, func() { root := commitment.NewRoot(tc.root) path := commitment.NewPath(tc.pathArr) - ok := proof.VerifyNonMembership(root, path) + err := proof.VerifyNonMembership(root, path) - require.True(suite.T(), ok == tc.shouldPass, "Test case %d failed", i) + if tc.shouldPass { + suite.Require().NoError(err, "test case %d should have passed", i) + } else { + suite.Require().Error(err, "test case %d should have failed", i) + } }) } diff --git a/x/ibc/23-commitment/types.go b/x/ibc/23-commitment/types.go index bd2968da88dc..aaab6f9d656b 100644 --- a/x/ibc/23-commitment/types.go +++ b/x/ibc/23-commitment/types.go @@ -14,6 +14,7 @@ package commitment type RootI interface { GetCommitmentType() Type GetHash() []byte + IsEmpty() bool } // PrefixI implements spec:CommitmentPrefix. @@ -21,6 +22,7 @@ type RootI interface { type PrefixI interface { GetCommitmentType() Type Bytes() []byte + IsEmpty() bool } // PathI implements spec:CommitmentPath. @@ -28,6 +30,7 @@ type PrefixI interface { type PathI interface { GetCommitmentType() Type String() string + IsEmpty() bool } // ProofI implements spec:CommitmentProof. @@ -36,8 +39,9 @@ type PathI interface { // Proofs includes key but value is provided dynamically at the verification time. type ProofI interface { GetCommitmentType() Type - VerifyMembership(RootI, PathI, []byte) bool - VerifyNonMembership(RootI, PathI) bool + VerifyMembership(RootI, PathI, []byte) error + VerifyNonMembership(RootI, PathI) error + IsEmpty() bool ValidateBasic() error } diff --git a/x/ibc/23-commitment/verify.go b/x/ibc/23-commitment/verify.go index 7c620c2b5a90..8e070595949f 100644 --- a/x/ibc/23-commitment/verify.go +++ b/x/ibc/23-commitment/verify.go @@ -19,21 +19,21 @@ func BatchVerifyMembership( proof ProofI, prefix PrefixI, items map[string][]byte, -) bool { +) error { root := CalculateRoot(ctx) for pathStr, value := range items { path, err := ApplyPrefix(prefix, pathStr) if err != nil { - return false + return err } - if ok := proof.VerifyMembership(root, path, value); !ok { - return false + if err := proof.VerifyMembership(root, path, value); err != nil { + return err } } - return true + return nil } // BatchVerifyNonMembership verifies a proof that many paths have not been set @@ -45,18 +45,18 @@ func BatchVerifyNonMembership( proof ProofI, prefix PrefixI, paths []string, -) bool { +) error { root := CalculateRoot(ctx) for _, pathStr := range paths { path, err := ApplyPrefix(prefix, pathStr) if err != nil { - return false + return err } - if ok := proof.VerifyNonMembership(root, path); !ok { - return false + if err := proof.VerifyNonMembership(root, path); err != nil { + return err } } - return true + return nil } diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go index b23f9fbeefcf..f6c23c3d9627 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/ante/ante_test.go @@ -13,11 +13,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/ante" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -58,7 +59,7 @@ func (suite *HandlerTestSuite) SetupTest() { suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) suite.createClient() - suite.createConnection(connection.OPEN) + suite.createConnection(connectionexported.OPEN) } func (suite *HandlerTestSuite) createClient() { @@ -68,15 +69,13 @@ func (suite *HandlerTestSuite) createClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - consensusState := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), + consensusState := tendermint.ConsensusState{ Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, - NextValidatorSet: suite.valSet, + ValidatorSetHash: suite.valSet.Hash(), } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, uint64(suite.app.LastBlockHeight()), consensusState) suite.NoError(err) } @@ -85,20 +84,22 @@ func (suite *HandlerTestSuite) updateClient() { suite.app.Commit() commitID := suite.app.LastCommitID() - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + height := suite.app.LastBlockHeight() + 1 + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: height}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - state := clienttypestm.ConsensusState{ - ChainID: testChainID, - Height: uint64(commitID.Version), - Root: commitment.NewRoot(commitID.Hash), + state := tendermint.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), } - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, state) - suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, testClient, state.GetHeight(), state.GetRoot()) + suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, uint64(height-1), state) + csi, _ := suite.app.IBCKeeper.ClientKeeper.GetClientState(suite.ctx, testClient) + cs, _ := csi.(tendermint.ClientState) + cs.LatestHeight = uint64(height - 1) + suite.app.IBCKeeper.ClientKeeper.SetClientState(suite.ctx, cs) } -func (suite *HandlerTestSuite) createConnection(state connection.State) { +func (suite *HandlerTestSuite) createConnection(state connectionexported.State) { connection := connection.ConnectionEnd{ State: state, ClientID: testClient, @@ -113,7 +114,7 @@ func (suite *HandlerTestSuite) createConnection(state connection.State) { suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) } -func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channel.State, order channel.Order) { +func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channelexported.State, order channelexported.Order) { ch := channel.Channel{ State: state, Ordering: order, @@ -165,19 +166,14 @@ func (suite *HandlerTestSuite) TestHandleMsgPacketOrdered() { suite.Error(err, "%+v", err) // channel does not exist cctx, _ = suite.ctx.CacheContext() - suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channel.OPEN, channel.ORDERED) - packetCommitmentPath := channel.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, packet.Sequence) + suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channelexported.OPEN, channelexported.ORDERED) + packetCommitmentPath := ibctypes.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, packet.Sequence) proof, proofHeight := suite.queryProof(packetCommitmentPath) msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) _, err = handler(cctx, suite.newTx(msg), false) suite.Error(err, "%+v", err) // invalid proof suite.updateClient() - cctx, _ = suite.ctx.CacheContext() - proof, proofHeight = suite.queryProof(packetCommitmentPath) - msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) - _, err = handler(cctx, suite.newTx(msg), false) - suite.Error(err, "%+v", err) // next recvseq not set proof, proofHeight = suite.queryProof(packetCommitmentPath) msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) @@ -187,6 +183,9 @@ func (suite *HandlerTestSuite) TestHandleMsgPacketOrdered() { for i := 0; i < 10; i++ { suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(cctx, cpportid, cpchanid, uint64(i)) _, err := handler(cctx, suite.newTx(msg), false) + if err == nil { + err = suite.app.IBCKeeper.ChannelKeeper.PacketExecuted(cctx, packet, packet.Data) + } if i == 1 { suite.NoError(err, "%d", i) // successfully executed write() @@ -212,14 +211,14 @@ func (suite *HandlerTestSuite) TestHandleMsgPacketUnordered() { suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, packet.SourcePort, packet.SourceChannel, uint64(10)) - suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channel.OPEN, channel.UNORDERED) + suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channelexported.OPEN, channelexported.UNORDERED) suite.updateClient() for i := 10; i >= 0; i-- { cctx, write := suite.ctx.CacheContext() packet = channel.NewPacket(newPacket(uint64(i)), uint64(i), portid, chanid, cpportid, cpchanid) - packetCommitmentPath := channel.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, uint64(i)) + packetCommitmentPath := ibctypes.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, uint64(i)) proof, proofHeight := suite.queryProof(packetCommitmentPath) msg := channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) _, err := handler(cctx, suite.newTx(msg), false) diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index 68447885bbd1..20bd0e746e82 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -21,21 +21,13 @@ func NewQuerier(k Keeper) sdk.Querier { switch path[0] { case client.SubModuleName: switch path[1] { - case client.QueryClientState: - res, err = client.QuerierClientState(ctx, req, k.ClientKeeper) case client.QueryAllClients: res, err = client.QuerierClients(ctx, req, k.ClientKeeper) - case client.QueryConsensusState: - res, err = client.QuerierConsensusState(ctx, req, k.ClientKeeper) - case client.QueryVerifiedRoot: - res, err = client.QuerierVerifiedRoot(ctx, req, k.ClientKeeper) default: err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", client.SubModuleName) } case connection.SubModuleName: switch path[1] { - case connection.QueryConnection: - res, err = connection.QuerierConnection(ctx, req, k.ConnectionKeeper) case connection.QueryAllConnections: res, err = connection.QuerierConnections(ctx, req, k.ConnectionKeeper) case connection.QueryClientConnections: @@ -45,8 +37,6 @@ func NewQuerier(k Keeper) sdk.Querier { } case channel.SubModuleName: switch path[1] { - case channel.QueryChannel: - res, err = channel.QuerierChannel(ctx, req, k.ChannelKeeper) case channel.QueryAllChannels: res, err = channel.QuerierChannels(ctx, req, k.ChannelKeeper) default: diff --git a/x/ibc/keeper/querier_test.go b/x/ibc/keeper/querier_test.go index f15920608b6c..3c8231c6be06 100644 --- a/x/ibc/keeper/querier_test.go +++ b/x/ibc/keeper/querier_test.go @@ -43,24 +43,12 @@ func (suite *KeeperTestSuite) TestNewQuerier() { false, "", }, - { - "client - QuerierVerifiedRoot", - []string{client.SubModuleName, client.QueryVerifiedRoot}, - false, - "", - }, { "client - invalid query", []string{client.SubModuleName, "foo"}, true, fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName), }, - { - "connection - QuerierConnection", - []string{connection.SubModuleName, connection.QueryConnection}, - false, - "", - }, { "connection - QuerierConnections", []string{connection.SubModuleName, connection.QueryAllConnections}, diff --git a/x/ibc/module.go b/x/ibc/module.go index 0dc1093e447a..65f03954cd1d 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -15,6 +15,7 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/client/rest" @@ -42,6 +43,7 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) channel.RegisterCodec(cdc) + tendermint.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } diff --git a/x/ibc/types/keys.go b/x/ibc/types/keys.go index f4f39edcd495..8789ec33cc82 100644 --- a/x/ibc/types/keys.go +++ b/x/ibc/types/keys.go @@ -16,16 +16,18 @@ const ( RouterKey string = ModuleName ) +// KVStore key prefixes for IBC +var ( + KeyClientPrefix = []byte("clientState") + KeyClientTypePrefix = []byte("clientType") + KeyConsensusStatePrefix = []byte("consensusState") + KeyClientConnectionsPrefix = []byte("clientConnections") + KeyConnectionPrefix = []byte("connection") +) + // KVStore key prefixes for IBC const ( - KeyClientPrefix int = iota + 1 - KeyClientTypePrefix - KeyConsensusStatePrefix - KeyRootPrefix - KeyCommiterPrefix - KeyClientConnectionsPrefix - KeyConnectionPrefix - KeyChannelPrefix + KeyChannelPrefix int = iota + 1 KeyChannelCapabilityPrefix KeyNextSeqSendPrefix KeyNextSeqRecvPrefix @@ -38,3 +40,154 @@ const ( func KeyPrefixBytes(prefix int) []byte { return []byte(fmt.Sprintf("%d/", prefix)) } + +// ICS02 +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#path-space + +// ClientStatePath takes an Identifier and returns a Path under which to store a +// particular client state +func ClientStatePath(clientID string) string { + return fmt.Sprintf("clientState/%s", clientID) +} + +// ClientTypePath takes an Identifier and returns Path under which to store the +// type of a particular client. +func ClientTypePath(clientID string) string { + return fmt.Sprintf("clientType/%s", clientID) +} + +// ConsensusStatePath takes an Identifier and returns a Path under which to +// store the consensus state of a client. +func ConsensusStatePath(clientID string, height uint64) string { + return fmt.Sprintf("consensusState/%s/%d", clientID, height) +} + +// KeyClientState returns the store key for a particular client state +func KeyClientState(clientID string) []byte { + return []byte(ClientStatePath(clientID)) +} + +// KeyClientType returns the store key for type of a particular client +func KeyClientType(clientID string) []byte { + return []byte(ClientTypePath(clientID)) +} + +// KeyConsensusState returns the store key for the consensus state of a particular +// client +func KeyConsensusState(clientID string, height uint64) []byte { + return []byte(ConsensusStatePath(clientID, height)) +} + +// ICS03 +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#store-paths + +// ClientConnectionsPath defines a reverse mapping from clients to a set of connections +func ClientConnectionsPath(clientID string) string { + return fmt.Sprintf("clientConnections/%s/", clientID) +} + +// ConnectionPath defines the path under which connection paths are stored +func ConnectionPath(connectionID string) string { + return fmt.Sprintf("connection/%s", connectionID) +} + +// KeyClientConnections returns the store key for the connectios of a given client +func KeyClientConnections(clientID string) []byte { + return []byte(ClientConnectionsPath(clientID)) +} + +// KeyConnection returns the store key for a particular connection +func KeyConnection(connectionID string) []byte { + return []byte(ConnectionPath(connectionID)) +} + +// ICS04 +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#store-paths + +// GetChannelPortsKeysPrefix returns the prefix bytes for ICS04 and ICS05 iterators +func GetChannelPortsKeysPrefix(prefix int) []byte { + return []byte(fmt.Sprintf("%d/ports/", prefix)) +} + +// ChannelPath defines the path under which channels are stored +func ChannelPath(portID, channelID string) string { + return fmt.Sprintf("%d/", KeyChannelPrefix) + channelPath(portID, channelID) +} + +// ChannelCapabilityPath defines the path under which capability keys associated +// with a channel are stored +func ChannelCapabilityPath(portID, channelID string) string { + return fmt.Sprintf("%d/", KeyChannelCapabilityPrefix) + channelPath(portID, channelID) + "/key" +} + +// NextSequenceSendPath defines the next send sequence counter store path +func NextSequenceSendPath(portID, channelID string) string { + return fmt.Sprintf("%d/", KeyNextSeqSendPrefix) + channelPath(portID, channelID) + "/nextSequenceSend" +} + +// NextSequenceRecvPath defines the next receive sequence counter store path +func NextSequenceRecvPath(portID, channelID string) string { + return fmt.Sprintf("%d/", KeyNextSeqRecvPrefix) + channelPath(portID, channelID) + "/nextSequenceRecv" +} + +// PacketCommitmentPath defines the commitments to packet data fields store path +func PacketCommitmentPath(portID, channelID string, sequence uint64) string { + return fmt.Sprintf("%d/", KeyPacketCommitmentPrefix) + channelPath(portID, channelID) + fmt.Sprintf("/packets/%d", sequence) +} + +// PacketAcknowledgementPath defines the packet acknowledgement store path +func PacketAcknowledgementPath(portID, channelID string, sequence uint64) string { + return fmt.Sprintf("%d/", KeyPacketAckPrefix) + channelPath(portID, channelID) + fmt.Sprintf("/acknowledgements/%d", sequence) +} + +// KeyChannel returns the store key for a particular channel +func KeyChannel(portID, channelID string) []byte { + return []byte(ChannelPath(portID, channelID)) +} + +// KeyChannelCapabilityPath returns the store key for the capability key of a +// particular channel binded to a specific port +func KeyChannelCapabilityPath(portID, channelID string) []byte { + return []byte(ChannelCapabilityPath(portID, channelID)) +} + +// KeyNextSequenceSend returns the store key for the send sequence of a particular +// channel binded to a specific port +func KeyNextSequenceSend(portID, channelID string) []byte { + return []byte(NextSequenceSendPath(portID, channelID)) +} + +// KeyNextSequenceRecv returns the store key for the receive sequence of a particular +// channel binded to a specific port +func KeyNextSequenceRecv(portID, channelID string) []byte { + return []byte(NextSequenceRecvPath(portID, channelID)) +} + +// KeyPacketCommitment returns the store key of under which a packet commitment +// is stored +func KeyPacketCommitment(portID, channelID string, sequence uint64) []byte { + return []byte(PacketCommitmentPath(portID, channelID, sequence)) +} + +// KeyPacketAcknowledgement returns the store key of under which a packet +// acknowledgement is stored +func KeyPacketAcknowledgement(portID, channelID string, sequence uint64) []byte { + return []byte(PacketAcknowledgementPath(portID, channelID, sequence)) +} + +func channelPath(portID, channelID string) string { + return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) +} + +// ICS05 +// The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-005-port-allocation#store-paths + +// PortPath defines the path under which ports paths are stored +func PortPath(portID string) string { + return fmt.Sprintf("%d/ports/%s", KeyPortsPrefix, portID) +} + +// KeyPort returns the store key for a particular port +func KeyPort(portID string) []byte { + return []byte(PortPath(portID)) +} From c2b874bd8a7abb15878e57940afb09b4494df422 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Mon, 27 Jan 2020 18:29:36 +0100 Subject: [PATCH 068/176] fix build --- x/ibc/02-client/client/cli/tx.go | 14 +++++++------- x/ibc/02-client/client/rest/tx.go | 8 ++++---- x/ibc/03-connection/client/cli/tx.go | 18 +++++++++--------- x/ibc/03-connection/client/rest/tx.go | 10 +++++----- x/ibc/04-channel/client/cli/tx.go | 26 +++++++++++++------------- x/ibc/04-channel/client/rest/tx.go | 16 ++++++++-------- x/ibc/20-transfer/client/cli/tx.go | 10 +++++----- x/ibc/20-transfer/client/rest/tx.go | 4 ++-- 8 files changed, 53 insertions(+), 53 deletions(-) diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/02-client/client/cli/tx.go index 5dd8cd1b9c30..d688ac43729f 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/02-client/client/cli/tx.go @@ -16,7 +16,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/evidence" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" @@ -38,7 +38,7 @@ $ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) clientID := args[0] @@ -64,7 +64,7 @@ $ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -85,7 +85,7 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) clientID := args[0] @@ -107,7 +107,7 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -129,7 +129,7 @@ $ %s tx ibc client misbehaviour [path/to/evidence.json] --from node0 --home ../n Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) var ev evidenceexported.Evidence @@ -149,7 +149,7 @@ $ %s tx ibc client misbehaviour [path/to/evidence.json] --from node0 --home ../n return err } - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd diff --git a/x/ibc/02-client/client/rest/tx.go b/x/ibc/02-client/client/rest/tx.go index a0cb4840879d..7cdbe69bdf5f 100644 --- a/x/ibc/02-client/client/rest/tx.go +++ b/x/ibc/02-client/client/rest/tx.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/evidence" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ) @@ -62,7 +62,7 @@ func createClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -111,7 +111,7 @@ func updateClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -151,6 +151,6 @@ func submitMisbehaviourHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 5ce3a6e65baa..1418ed345897 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -14,7 +14,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" - authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) @@ -46,7 +46,7 @@ $ %s tx ibc connection open-init [connection-id] [client-id] \ Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] @@ -68,7 +68,7 @@ $ %s tx ibc connection open-init [connection-id] [client-id] \ return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -94,7 +94,7 @@ $ %s tx ibc connection open-try connection-id] [client-id] \ Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) @@ -133,7 +133,7 @@ $ %s tx ibc connection open-try connection-id] [client-id] \ return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -155,7 +155,7 @@ $ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [versio Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] @@ -182,7 +182,7 @@ $ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [versio return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd @@ -204,7 +204,7 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) @@ -230,7 +230,7 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } return cmd diff --git a/x/ibc/03-connection/client/rest/tx.go b/x/ibc/03-connection/client/rest/tx.go index 095a8e77a260..5f6ca6ac2ae3 100644 --- a/x/ibc/03-connection/client/rest/tx.go +++ b/x/ibc/03-connection/client/rest/tx.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) @@ -59,7 +59,7 @@ func connectionOpenInitHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -104,7 +104,7 @@ func connectionOpenTryHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -152,7 +152,7 @@ func connectionOpenAckHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -199,6 +199,6 @@ func connectionOpenConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index 3ed2119b470f..521e181a68df 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -12,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" - authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" connectionutils "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" @@ -32,7 +32,7 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -51,7 +51,7 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } @@ -69,7 +69,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -99,7 +99,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } cmd.Flags().Bool(FlagOrdered, true, "Pass flag for opening ordered channels") @@ -116,7 +116,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -140,7 +140,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } cmd.Flags().String(FlagIBCVersion, "1.0.0", "supported IBC version") @@ -155,7 +155,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -178,7 +178,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } } @@ -191,7 +191,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -202,7 +202,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } } @@ -215,7 +215,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authutils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -238,7 +238,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm return err } - return authutils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } } diff --git a/x/ibc/04-channel/client/rest/tx.go b/x/ibc/04-channel/client/rest/tx.go index ccbfebde13fc..c48784dca1d7 100644 --- a/x/ibc/04-channel/client/rest/tx.go +++ b/x/ibc/04-channel/client/rest/tx.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) @@ -69,7 +69,7 @@ func channelOpenInitHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -121,7 +121,7 @@ func channelOpenTryHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -175,7 +175,7 @@ func channelOpenAckHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -228,7 +228,7 @@ func channelOpenConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -279,7 +279,7 @@ func channelCloseInitHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -332,7 +332,7 @@ func channelCloseConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } @@ -377,6 +377,6 @@ func recvPacketHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index cc68453ddedd..b1845266b480 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) @@ -35,7 +35,7 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) ctx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) sender := ctx.GetFromAddress() @@ -59,7 +59,7 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { return err } - return utils.GenerateOrBroadcastMsgs(ctx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(ctx, txBldr, []sdk.Msg{msg}) }, } cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") @@ -74,7 +74,7 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { // Args: cobra.ExactArgs(3), // RunE: func(cmd *cobra.Command, args []string) error { // inBuf := bufio.NewReader(cmd.InOrStdin()) -// txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) +// txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) // cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) // prove := viper.GetBool(flags.FlagProve) @@ -122,7 +122,7 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { // return err // } -// return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) +// return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) // }, // } diff --git a/x/ibc/20-transfer/client/rest/tx.go b/x/ibc/20-transfer/client/rest/tx.go index 2413e4e8046e..dce3561c9f8a 100644 --- a/x/ibc/20-transfer/client/rest/tx.go +++ b/x/ibc/20-transfer/client/rest/tx.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/auth/client/utils" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) @@ -67,6 +67,6 @@ func transferHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) + authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } From 4d5c2d1f9e24f20f740d42c642f9fb5378e31f9e Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Wed, 29 Jan 2020 08:11:15 +0100 Subject: [PATCH 069/176] IBC historical info support (#5475) * implement GetConsensusState * introspect past consensus states on ICS03 handshake * implement ToTmValidator staking util function * add test cases * update tests * Fix various compile erros * fix historical info * fix dep cycle * Fix golint issues * Fix proto docs lint fail * move consensus state query downstream to ICS03 * remove unused funcs on expected keeper * update tests and move get consensus state to ICS03 * increase cov for verification funcs * fix tests * interfacer fix * fix expected keeper * remove TODOs Co-authored-by: Jack Zampolin --- simapp/app.go | 5 +- x/ibc/02-client/alias.go | 1 + x/ibc/02-client/client/utils/utils.go | 6 +- x/ibc/02-client/keeper/client.go | 4 +- x/ibc/02-client/keeper/client_test.go | 2 +- x/ibc/02-client/keeper/keeper.go | 40 +++- x/ibc/02-client/keeper/keeper_test.go | 50 ++++- x/ibc/02-client/types/expected_keepers.go | 11 + x/ibc/03-connection/client/cli/tx.go | 3 +- x/ibc/03-connection/client/rest/rest.go | 7 +- x/ibc/03-connection/client/rest/tx.go | 2 +- x/ibc/03-connection/handler.go | 22 +- x/ibc/03-connection/keeper/handshake.go | 61 +++--- x/ibc/03-connection/keeper/handshake_test.go | 139 +++++++----- x/ibc/03-connection/keeper/keeper_test.go | 22 +- x/ibc/03-connection/keeper/verify.go | 79 +++++-- x/ibc/03-connection/keeper/verify_test.go | 200 +++++++++--------- x/ibc/03-connection/types/expected_keepers.go | 3 +- x/ibc/03-connection/types/msgs.go | 23 +- x/ibc/03-connection/types/msgs_test.go | 18 +- x/ibc/04-channel/keeper/handshake.go | 37 +--- x/ibc/04-channel/keeper/keeper_test.go | 2 +- x/ibc/04-channel/keeper/packet.go | 29 +-- x/ibc/04-channel/keeper/timeout.go | 21 +- x/ibc/04-channel/types/expected_keepers.go | 17 +- x/ibc/07-tendermint/client_state.go | 7 +- x/ibc/20-transfer/client/cli/tx.go | 76 +------ x/ibc/20-transfer/handler_test.go | 2 +- x/ibc/20-transfer/keeper/relay_test.go | 2 +- x/ibc/20-transfer/types/expected_keepers.go | 2 +- x/ibc/ante/ante_test.go | 4 +- x/ibc/keeper/keeper.go | 6 +- x/staking/types/historical_info.go | 6 +- x/staking/types/validator.go | 14 ++ x/staking/types/validator_test.go | 16 ++ 35 files changed, 489 insertions(+), 450 deletions(-) create mode 100644 x/ibc/02-client/types/expected_keepers.go diff --git a/simapp/app.go b/simapp/app.go index cb12d7430d46..6edefa21c3b2 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -234,7 +234,9 @@ func NewSimApp( staking.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), ) - app.IBCKeeper = ibc.NewKeeper(app.cdc, keys[ibc.StoreKey], app.BankKeeper, app.SupplyKeeper) + app.IBCKeeper = ibc.NewKeeper( + app.cdc, keys[ibc.StoreKey], app.StakingKeeper, + ) transferCapKey := app.IBCKeeper.PortKeeper.BindPort(bank.ModuleName) app.TransferKeeper = transfer.NewKeeper( @@ -258,6 +260,7 @@ func NewSimApp( upgrade.NewAppModule(app.UpgradeKeeper), evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), + transfer.NewAppModule(app.TransferKeeper), ) // During begin block slashing happens after distr.BeginBlocker so that diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go index 20b946cf4a4f..ac62fc7602c8 100644 --- a/x/ibc/02-client/alias.go +++ b/x/ibc/02-client/alias.go @@ -49,6 +49,7 @@ var ( type ( Keeper = keeper.Keeper + StakingKeeper = types.StakingKeeper MsgCreateClient = types.MsgCreateClient MsgUpdateClient = types.MsgUpdateClient ) diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index fbe53fcc1063..37e99ec12ff7 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -103,14 +103,13 @@ func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, } height := info.Response.LastBlockHeight - prevheight := height - 1 commit, err := node.Commit(&height) if err != nil { return tendermint.Header{}, 0, err } - validators, err := node.Validators(&prevheight, 0, 10000) + validators, err := node.Validators(&height, 0, 10000) if err != nil { return tendermint.Header{}, 0, err } @@ -137,14 +136,13 @@ func QueryNodeConsensusState(cliCtx context.CLIContext) (tendermint.ConsensusSta } height := info.Response.LastBlockHeight - prevHeight := height - 1 commit, err := node.Commit(&height) if err != nil { return tendermint.ConsensusState{}, 0, err } - validators, err := node.Validators(&prevHeight, 0, 10000) + validators, err := node.Validators(&height, 0, 10000) if err != nil { return tendermint.ConsensusState{}, 0, err } diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index b7c8aa272809..e3f65748259d 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -88,7 +88,7 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H } k.SetClientState(ctx, clientState) - k.SetConsensusState(ctx, clientID, header.GetHeight(), consensusState) + k.SetClientConsensusState(ctx, clientID, header.GetHeight(), consensusState) k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, header.GetHeight())) ctx.EventManager().EmitEvents(sdk.Events{ @@ -113,7 +113,7 @@ func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, misbehaviour ex return sdkerrors.Wrap(types.ErrClientNotFound, misbehaviour.GetClientID()) } - consensusState, found := k.GetConsensusState(ctx, misbehaviour.GetClientID(), uint64(misbehaviour.GetHeight())) + consensusState, found := k.GetClientConsensusState(ctx, misbehaviour.GetClientID(), uint64(misbehaviour.GetHeight())) if !found { return sdkerrors.Wrap(types.ErrConsensusStateNotFound, misbehaviour.GetClientID()) } diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index c331889237aa..ab6eec5589a6 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -112,7 +112,7 @@ func (suite *KeeperTestSuite) TestUpdateClient() { clientState, found := suite.keeper.GetClientState(suite.ctx, testClientID) suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) - consensusState, found := suite.keeper.GetConsensusState(suite.ctx, testClientID, suite.header.GetHeight()) + consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, uint64(suite.header.GetHeight())) suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index 4b31f8f08cb2..c90079077de6 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -4,27 +4,31 @@ import ( "fmt" "github.com/tendermint/tendermint/libs/log" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // Keeper represents a type that grants read and write permissions to any client // state information type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec + storeKey sdk.StoreKey + cdc *codec.Codec + stakingKeeper types.StakingKeeper } // NewKeeper creates a new NewKeeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey) Keeper { +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, sk types.StakingKeeper) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, + storeKey: key, + cdc: cdc, + stakingKeeper: sk, } } @@ -70,8 +74,8 @@ func (k Keeper) SetClientType(ctx sdk.Context, clientID string, clientType expor store.Set(ibctypes.KeyClientType(clientID), []byte{byte(clientType)}) } -// GetConsensusState creates a new client state and populates it with a given consensus state -func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string, height uint64) (exported.ConsensusState, bool) { +// GetClientConsensusState gets the stored consensus state from a client at a given height. +func (k Keeper) GetClientConsensusState(ctx sdk.Context, clientID string, height uint64) (exported.ConsensusState, bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(ibctypes.KeyConsensusState(clientID, height)) if bz == nil { @@ -83,13 +87,29 @@ func (k Keeper) GetConsensusState(ctx sdk.Context, clientID string, height uint6 return consensusState, true } -// SetConsensusState sets a ConsensusState to a particular client -func (k Keeper) SetConsensusState(ctx sdk.Context, clientID string, height uint64, consensusState exported.ConsensusState) { +// SetClientConsensusState sets a ConsensusState to a particular client at the given +// height +func (k Keeper) SetClientConsensusState(ctx sdk.Context, clientID string, height uint64, consensusState exported.ConsensusState) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) store.Set(ibctypes.KeyConsensusState(clientID, height), bz) } +// GetSelfConsensusState introspects the (self) past historical info at a given height +// and returns the expected consensus state at that height. +func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported.ConsensusState, bool) { + histInfo, found := k.stakingKeeper.GetHistoricalInfo(ctx, int64(height)) + if !found { + return nil, false + } + + consensusState := tendermint.ConsensusState{ + Root: commitment.NewRoot(histInfo.Header.AppHash), + ValidatorSetHash: tmtypes.NewValidatorSet(histInfo.ValSet.ToTmValidators()).Hash(), + } + return consensusState, true +} + // IterateClients provides an iterator over all stored light client State // objects. For each State object, cb will be called. If the cb returns true, // the iterator will close and stop. @@ -133,6 +153,6 @@ func (k Keeper) initialize( return nil, types.ErrInvalidClientType } - k.SetConsensusState(ctx, clientID, height, consensusState) + k.SetClientConsensusState(ctx, clientID, height, consensusState) return clientState, nil } diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index eb0edc99d3e4..72aef416df0a 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "math/rand" "testing" "github.com/stretchr/testify/require" @@ -16,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/cosmos/cosmos-sdk/x/staking" ) const ( @@ -45,18 +47,26 @@ func (suite *KeeperTestSuite) SetupTest() { suite.cdc = app.Codec() suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{Height: testClientHeight, ChainID: testClientID}) suite.keeper = &app.IBCKeeper.ClientKeeper - suite.privVal = tmtypes.NewMockPV() - validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - suite.header = tendermint.CreateTestHeader(testClientID, testClientHeight, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) - suite.consensusState = tendermint.ConsensusState{ Root: commitment.NewRoot([]byte("hash")), ValidatorSetHash: suite.valSet.Hash(), } + + var validators staking.Validators + for i := 1; i < 11; i++ { + privVal := tmtypes.NewMockPV() + pk := privVal.GetPubKey() + val := staking.NewValidator(sdk.ValAddress(pk.Address()), pk, staking.Description{}) + val.Status = sdk.Bonded + val.Tokens = sdk.NewInt(rand.Int63()) + validators = append(validators, val) + + app.StakingKeeper.SetHistoricalInfo(suite.ctx, int64(i), staking.NewHistoricalInfo(suite.ctx.BlockHeader(), validators)) + } } func TestKeeperTestSuite(t *testing.T) { @@ -80,10 +90,10 @@ func (suite *KeeperTestSuite) TestSetClientType() { suite.Require().Equal(exported.Tendermint, clientType, "ClientTypes not stored correctly") } -func (suite *KeeperTestSuite) TestSetConsensusState() { - suite.keeper.SetConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) +func (suite *KeeperTestSuite) TestSetClientConsensusState() { + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) - retrievedConsState, found := suite.keeper.GetConsensusState(suite.ctx, testClientID, testClientHeight) + retrievedConsState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, testClientHeight) suite.Require().True(found, "GetConsensusState failed") tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) @@ -105,3 +115,29 @@ func (suite KeeperTestSuite) TestGetAllClients() { suite.Require().Len(clients, len(expClients)) suite.Require().Equal(expClients, clients) } + +func (suite KeeperTestSuite) TestGetConsensusState() { + suite.ctx = suite.ctx.WithBlockHeight(10) + cases := []struct { + name string + height uint64 + expPass bool + }{ + {"zero height", 0, false}, + {"height > latest height", uint64(suite.ctx.BlockHeight()) + 1, false}, + {"latest height - 1", uint64(suite.ctx.BlockHeight()) - 1, true}, + {"latest height", uint64(suite.ctx.BlockHeight()), true}, + } + + for i, tc := range cases { + tc := tc + cs, found := suite.keeper.GetSelfConsensusState(suite.ctx, tc.height) + if tc.expPass { + suite.Require().True(found, "Case %d should have passed: %s", i, tc.name) + suite.Require().NotNil(cs, "Case %d should have passed: %s", i, tc.name) + } else { + suite.Require().False(found, "Case %d should have failed: %s", i, tc.name) + suite.Require().Nil(cs, "Case %d should have failed: %s", i, tc.name) + } + } +} diff --git a/x/ibc/02-client/types/expected_keepers.go b/x/ibc/02-client/types/expected_keepers.go new file mode 100644 index 000000000000..c1ca7a4c3e4a --- /dev/null +++ b/x/ibc/02-client/types/expected_keepers.go @@ -0,0 +1,11 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// StakingKeeper expected staking keeper +type StakingKeeper interface { + GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool) +} diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 1418ed345897..5fbfc2d2a6fb 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -217,13 +217,12 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] } proofHeight := uint64(cliCtx.Height) - consensusHeight, err := lastHeight(cliCtx) if err != nil { return err } msg := types.NewMsgConnectionOpenConfirm( - connectionID, proofAck, proofHeight, consensusHeight, cliCtx.GetFromAddress(), + connectionID, proofAck, proofHeight, cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { diff --git a/x/ibc/03-connection/client/rest/rest.go b/x/ibc/03-connection/client/rest/rest.go index 7e74109b23b6..ed8e97b69280 100644 --- a/x/ibc/03-connection/client/rest/rest.go +++ b/x/ibc/03-connection/client/rest/rest.go @@ -56,8 +56,7 @@ type ConnectionOpenAckReq struct { // ConnectionOpenConfirmReq defines the properties of a connection open confirm request's body. type ConnectionOpenConfirmReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` - ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` } diff --git a/x/ibc/03-connection/client/rest/tx.go b/x/ibc/03-connection/client/rest/tx.go index 5f6ca6ac2ae3..d119fde64785 100644 --- a/x/ibc/03-connection/client/rest/tx.go +++ b/x/ibc/03-connection/client/rest/tx.go @@ -191,7 +191,7 @@ func connectionOpenConfirmHandlerFn(cliCtx context.CLIContext) http.HandlerFunc // create the message msg := types.NewMsgConnectionOpenConfirm( - connectionID, req.ProofAck, req.ProofHeight, req.ConsensusHeight, fromAddr, + connectionID, req.ProofAck, req.ProofHeight, fromAddr, ) if err := msg.ValidateBasic(); err != nil { diff --git a/x/ibc/03-connection/handler.go b/x/ibc/03-connection/handler.go index 1c1e90ed6e55..0350fa699f2d 100644 --- a/x/ibc/03-connection/handler.go +++ b/x/ibc/03-connection/handler.go @@ -6,8 +6,9 @@ import ( // HandleMsgConnectionOpenInit defines the sdk.Handler for MsgConnectionOpenInit func HandleMsgConnectionOpenInit(ctx sdk.Context, k Keeper, msg MsgConnectionOpenInit) (*sdk.Result, error) { - err := k.ConnOpenInit(ctx, msg.ConnectionID, msg.ClientID, msg.Counterparty) - if err != nil { + if err := k.ConnOpenInit( + ctx, msg.ConnectionID, msg.ClientID, msg.Counterparty, + ); err != nil { return nil, err } @@ -31,10 +32,11 @@ func HandleMsgConnectionOpenInit(ctx sdk.Context, k Keeper, msg MsgConnectionOpe // HandleMsgConnectionOpenTry defines the sdk.Handler for MsgConnectionOpenTry func HandleMsgConnectionOpenTry(ctx sdk.Context, k Keeper, msg MsgConnectionOpenTry) (*sdk.Result, error) { - err := k.ConnOpenTry( + if err := k.ConnOpenTry( ctx, msg.ConnectionID, msg.Counterparty, msg.ClientID, - msg.CounterpartyVersions, msg.ProofInit, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight) - if err != nil { + msg.CounterpartyVersions, msg.ProofInit, msg.ProofConsensus, + msg.ProofHeight, msg.ConsensusHeight, + ); err != nil { return nil, err } @@ -58,11 +60,10 @@ func HandleMsgConnectionOpenTry(ctx sdk.Context, k Keeper, msg MsgConnectionOpen // HandleMsgConnectionOpenAck defines the sdk.Handler for MsgConnectionOpenAck func HandleMsgConnectionOpenAck(ctx sdk.Context, k Keeper, msg MsgConnectionOpenAck) (*sdk.Result, error) { - err := k.ConnOpenAck( + if err := k.ConnOpenAck( ctx, msg.ConnectionID, msg.Version, msg.ProofTry, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight, - ) - if err != nil { + ); err != nil { return nil, err } @@ -85,8 +86,9 @@ func HandleMsgConnectionOpenAck(ctx sdk.Context, k Keeper, msg MsgConnectionOpen // HandleMsgConnectionOpenConfirm defines the sdk.Handler for MsgConnectionOpenConfirm func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k Keeper, msg MsgConnectionOpenConfirm) (*sdk.Result, error) { - err := k.ConnOpenConfirm(ctx, msg.ConnectionID, msg.ProofAck, msg.ProofHeight, msg.ConsensusHeight) - if err != nil { + if err := k.ConnOpenConfirm( + ctx, msg.ConnectionID, msg.ProofAck, msg.ProofHeight, + ); err != nil { return nil, err } diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index f8eaf98db5c3..9430d8ee2eb4 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -56,12 +56,11 @@ func (k Keeper) ConnOpenTry( proofHeight uint64, consensusHeight uint64, ) error { - // XXX: blocked by #5475 - // if consensusHeight > uint64(ctx.BlockHeight()) { - // return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") - // } + if consensusHeight > uint64(ctx.BlockHeight()) { + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") + } - expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, clientID, consensusHeight) + expectedConsensusState, found := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if !found { return clienttypes.ErrConsensusStateNotFound } @@ -80,18 +79,17 @@ func (k Keeper) ConnOpenTry( connection := types.NewConnectionEnd(exported.UNINITIALIZED, clientID, counterparty, []string{version}) if err := k.VerifyConnectionState( - ctx, proofHeight, proofInit, counterparty.ConnectionID, - expectedConnection, expectedConsensusState, + ctx, connection, proofHeight, proofInit, counterparty.ConnectionID, + expectedConnection, ); err != nil { return err } - // XXX: blocked by #5475 - // if err := k.VerifyClientConsensusState( - // ctx, proofHeight, proofInit, expectedConsensusState, - // ); err != nil { - // return err - // } + if err := k.VerifyClientConsensusState( + ctx, connection, consensusHeight, proofConsensus, expectedConsensusState, + ); err != nil { + return err + } previousConnection, found := k.GetConnection(ctx, connectionID) if found && !(previousConnection.State == exported.INIT && @@ -126,10 +124,9 @@ func (k Keeper) ConnOpenAck( proofHeight uint64, consensusHeight uint64, ) error { - // XXX: blocked by #5475 - // if consensusHeight > uint64(ctx.BlockHeight()) { - // return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") - // } + if consensusHeight > uint64(ctx.BlockHeight()) { + return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") + } connection, found := k.GetConnection(ctx, connectionID) if !found { @@ -149,8 +146,7 @@ func (k Keeper) ConnOpenAck( "connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version, ) } - - expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, connection.ClientID, consensusHeight) + expectedConsensusState, found := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if !found { return clienttypes.ErrConsensusStateNotFound } @@ -160,18 +156,17 @@ func (k Keeper) ConnOpenAck( expectedConnection := types.NewConnectionEnd(exported.TRYOPEN, connection.Counterparty.ClientID, expectedCounterparty, []string{version}) if err := k.VerifyConnectionState( - ctx, proofHeight, proofTry, connection.Counterparty.ConnectionID, - expectedConnection, expectedConsensusState, + ctx, connection, proofHeight, proofTry, connection.Counterparty.ConnectionID, + expectedConnection, ); err != nil { return err } - // XXX: blocked by #5475 - // if err := k.VerifyClientConsensusState( - // ctx, connection, proofHeight, proofInit, expectedConsensusState, - // ); err != nil { - // return err - // } + if err := k.VerifyClientConsensusState( + ctx, connection, consensusHeight, proofConsensus, expectedConsensusState, + ); err != nil { + return err + } connection.State = exported.OPEN connection.Versions = []string{version} @@ -188,8 +183,7 @@ func (k Keeper) ConnOpenConfirm( ctx sdk.Context, connectionID string, proofAck commitment.ProofI, - proofHeight, - consensusHeight uint64, + proofHeight uint64, ) error { connection, found := k.GetConnection(ctx, connectionID) if !found { @@ -203,18 +197,13 @@ func (k Keeper) ConnOpenConfirm( ) } - expectedConsensusState, found := k.clientKeeper.GetConsensusState(ctx, connection.ClientID, consensusHeight) - if !found { - return clienttypes.ErrConsensusStateNotFound - } - prefix := k.GetCommitmentPrefix() expectedCounterparty := types.NewCounterparty(connection.ClientID, connectionID, prefix) expectedConnection := types.NewConnectionEnd(exported.OPEN, connection.Counterparty.ClientID, expectedCounterparty, connection.Versions) if err := k.VerifyConnectionState( - ctx, proofHeight, proofAck, connection.Counterparty.ConnectionID, - expectedConnection, expectedConsensusState, + ctx, connection, proofHeight, proofAck, connection.Counterparty.ConnectionID, + expectedConnection, ); err != nil { return err } diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index 69eb1335235e..3023cb5c4e20 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -5,6 +5,7 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) // TestConnOpenInit - Chain A (ID #1) initializes (INIT state) a connection with @@ -45,42 +46,67 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), ) - consensusHeight := int64(0) - - testCases := []testCase{ - {"success", func() { + var ( + consensusHeight int64 = 0 + proofHeight int64 = 0 + ) + testCases := []struct { + msg string + proofInit commitment.ProofI + proofConsensus commitment.ProofI + malleate func() + expPass bool + }{ + {"success", validProof{}, validProof{}, func() { suite.createClient(testClientID1) // height = 2 + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + proofHeight = suite.ctx.BlockHeight() suite.createClient(testClientID2) consensusHeight = suite.ctx.BlockHeight() // height = 3 - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) suite.updateClient(testClientID1) suite.updateClient(testClientID2) }, true}, - {"consensus state not found", func() {}, false}, - {"connection state verification invalid", func() { + {"consensus height > latest height", validProof{}, validProof{}, func() { + consensusHeight = 100 + }, false}, + {"self consensus state not found", validProof{}, validProof{}, func() { + consensusHeight = 100 + suite.ctx = suite.ctx.WithBlockHeight(100) + }, false}, + {"connection state verification invalid", invalidProof{}, validProof{}, func() { suite.createClient(testClientID1) suite.createClient(testClientID2) consensusHeight = suite.ctx.BlockHeight() suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.UNINITIALIZED) suite.updateClient(testClientID1) }, false}, - {"invalid previous connection", func() { - suite.createClient(testClientID1) + {"consensus state verification invalid", validProof{}, invalidProof{}, func() { + suite.createClient(testClientID1) // height = 2 + suite.createClient(testClientID2) + consensusHeight = suite.ctx.BlockHeight() + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.updateClient(testClientID1) + suite.updateClient(testClientID2) + }, false}, + {"invalid previous connection", validProof{}, validProof{}, func() { + suite.createClient(testClientID1) // height = 2 suite.createClient(testClientID2) consensusHeight = suite.ctx.BlockHeight() suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) suite.updateClient(testClientID1) + suite.updateClient(testClientID2) }, false}, - {"couldn't add connection to client", func() { - suite.createClient(testClientID1) + {"couldn't add connection to client", validProof{}, validProof{}, func() { + suite.createClient(testClientID1) // height = 2 consensusHeight = suite.ctx.BlockHeight() - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.INIT) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) suite.updateClient(testClientID1) + suite.updateClient(testClientID2) }, false}, } for i, tc := range testCases { + tc := tc suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -92,21 +118,15 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // consensusKey := ibctypes.KeyConsensusState(testClientID1, uint64(proofHeight)) // proofConsensus, consensusHeight := suite.queryProof(consensusKey) - proofHeight := consensusHeight - 1 + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry( + suite.ctx, testConnectionID2, counterparty, testClientID2, + connection.GetCompatibleVersions(), tc.proofInit, tc.proofConsensus, + uint64(proofHeight), uint64(consensusHeight), + ) if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry( - suite.ctx, testConnectionID2, counterparty, testClientID2, - connection.GetCompatibleVersions(), validProof{}, validProof{}, - uint64(proofHeight), uint64(consensusHeight), - ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry( - suite.ctx, testConnectionID2, counterparty, testClientID2, - connection.GetCompatibleVersions(), invalidProof{}, validProof{}, - uint64(proofHeight), uint64(consensusHeight), - ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } }) @@ -117,36 +137,62 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // the initialization (TRYINIT) of the connection on Chain B (ID #2). func (suite *KeeperTestSuite) TestConnOpenAck() { version := connection.GetCompatibleVersions()[0] - consensusHeight := int64(0) + + var ( + consensusHeight int64 = 0 + proofHeight int64 = 0 + ) testCases := []struct { - msg string - version string - malleate func() - expPass bool + msg string + version string + proofTry commitment.ProofI + proofConsensus commitment.ProofI + malleate func() + expPass bool }{ - {"success", version, func() { - suite.createClient(testClientID1) - consensusHeight = suite.ctx.BlockHeight() + {"success", version, validProof{}, validProof{}, func() { suite.createClient(testClientID2) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) + proofHeight = suite.ctx.BlockHeight() + consensusHeight = suite.ctx.BlockHeight() + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) suite.updateClient(testClientID1) + suite.updateClient(testClientID2) }, true}, - {"connection not found", version, func() {}, false}, - {"connection state is not INIT", version, func() { + {"consensus height > latest height", version, validProof{}, validProof{}, func() { + consensusHeight = 100 + }, false}, + {"connection not found", version, validProof{}, validProof{}, func() { + consensusHeight = suite.ctx.BlockHeight() + }, false}, + {"connection state is not INIT", version, validProof{}, validProof{}, func() { suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.UNINITIALIZED) suite.updateClient(testClientID1) }, false}, - {"incompatible IBC versions", "2.0", func() { + {"incompatible IBC versions", "2.0", validProof{}, validProof{}, func() { suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) suite.updateClient(testClientID1) }, false}, - {"consensus state not found", version, func() { + {"self consensus state not found", version, validProof{}, validProof{}, func() { + suite.createClient(testClientID1) + suite.createClient(testClientID2) suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) suite.updateClient(testClientID1) + consensusHeight = 100 + suite.ctx = suite.ctx.WithBlockHeight(100) }, false}, - {"connection state verification failed", version, func() { + {"connection state verification failed", version, invalidProof{}, validProof{}, func() { + suite.createClient(testClientID1) + consensusHeight = suite.ctx.BlockHeight() + suite.createClient(testClientID2) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) + suite.updateClient(testClientID1) + }, false}, + {"consensus state verification failed", version, validProof{}, invalidProof{}, func() { suite.createClient(testClientID1) consensusHeight = suite.ctx.BlockHeight() suite.createClient(testClientID2) @@ -157,6 +203,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { } for i, tc := range testCases { + tc := tc suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -168,19 +215,14 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // consensusKey := ibctypes.KeyConsensusState(testClientID2, uint64(proofHeight)) // proofConsensus, consensusHeight := suite.queryProof(consensusKey) - proofHeight := consensusHeight - 1 + err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck( + suite.ctx, testConnectionID1, tc.version, tc.proofTry, tc.proofConsensus, + uint64(proofHeight), uint64(consensusHeight), + ) if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck( - suite.ctx, testConnectionID1, tc.version, validProof{}, validProof{}, - uint64(proofHeight), uint64(consensusHeight), - ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck( - suite.ctx, testConnectionID1, tc.version, invalidProof{}, validProof{}, - uint64(proofHeight), uint64(consensusHeight), - ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } }) @@ -221,6 +263,7 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { } for i, tc := range testCases { + tc := tc suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -233,13 +276,11 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { if tc.expPass { err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( suite.ctx, testConnectionID2, validProof{}, uint64(proofHeight), - uint64(consensusHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( suite.ctx, testConnectionID2, invalidProof{}, uint64(proofHeight), - uint64(consensusHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index b353d3578a4c..97f6b3563716 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "errors" "fmt" + "math/rand" "testing" "github.com/stretchr/testify/suite" @@ -21,6 +22,7 @@ import ( tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/cosmos/cosmos-sdk/x/staking" ) const ( @@ -57,17 +59,26 @@ func (suite *KeeperTestSuite) SetupTest() { suite.cdc = app.Codec() suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{ChainID: chainID, Height: 1}) suite.app = app - privVal := tmtypes.NewMockPV() - validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) suite.header = tendermint.CreateTestHeader(chainID, testHeight, suite.valSet, suite.valSet, []tmtypes.PrivValidator{privVal}) - suite.consensusState = tendermint.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), ValidatorSetHash: suite.valSet.Hash(), } + + var validators staking.Validators + for i := 1; i < 11; i++ { + privVal := tmtypes.NewMockPV() + pk := privVal.GetPubKey() + val := staking.NewValidator(sdk.ValAddress(pk.Address()), pk, staking.Description{}) + val.Status = sdk.Bonded + val.Tokens = sdk.NewInt(rand.Int63()) + validators = append(validators, val) + + app.StakingKeeper.SetHistoricalInfo(suite.ctx, int64(i), staking.NewHistoricalInfo(suite.ctx.BlockHeader(), validators)) + } } // nolint: unused @@ -126,9 +137,12 @@ func (suite *KeeperTestSuite) updateClient(clientID string) { ValidatorSetHash: suite.valSet.Hash(), } - suite.app.IBCKeeper.ClientKeeper.SetConsensusState( + suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState( suite.ctx, clientID, uint64(suite.app.LastBlockHeight()), consensusState, ) + suite.app.IBCKeeper.ClientKeeper.SetClientState( + suite.ctx, tendermint.NewClientState(clientID, uint64(suite.app.LastBlockHeight())), + ) // _, _, err := simapp.SignCheckDeliver( // suite.T(), diff --git a/x/ibc/03-connection/keeper/verify.go b/x/ibc/03-connection/keeper/verify.go index bc15b71e8131..f990d0b5e5bf 100644 --- a/x/ibc/03-connection/keeper/verify.go +++ b/x/ibc/03-connection/keeper/verify.go @@ -4,7 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -13,18 +13,18 @@ import ( // specified client stored on the target machine. func (k Keeper) VerifyClientConsensusState( ctx sdk.Context, - connection types.ConnectionEnd, + connection exported.ConnectionI, height uint64, proof commitment.ProofI, consensusState clientexported.ConsensusState, ) error { - clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) + clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { return clienttypes.ErrClientNotFound } return clientState.VerifyClientConsensusState( - k.cdc, height, connection.Counterparty.Prefix, proof, consensusState, + k.cdc, height, connection.GetCounterparty().GetPrefix(), proof, consensusState, ) } @@ -32,19 +32,27 @@ func (k Keeper) VerifyClientConsensusState( // specified connection end stored on the target machine. func (k Keeper) VerifyConnectionState( ctx sdk.Context, + connection exported.ConnectionI, height uint64, proof commitment.ProofI, connectionID string, - connection types.ConnectionEnd, - consensusState clientexported.ConsensusState, + connectionEnd exported.ConnectionI, // oposite connection ) error { - clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) + clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { return clienttypes.ErrClientNotFound } + // TODO: move to specific clients; blocked by #5502 + consensusState, found := k.clientKeeper.GetClientConsensusState( + ctx, connectionEnd.GetClientID(), height, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound + } + return clientState.VerifyConnectionState( - k.cdc, height, connection.Counterparty.Prefix, proof, connectionID, connection, consensusState, + k.cdc, height, connection.GetCounterparty().GetPrefix(), proof, connectionID, connectionEnd, consensusState, ) } @@ -52,19 +60,26 @@ func (k Keeper) VerifyConnectionState( // channel end, under the specified port, stored on the target machine. func (k Keeper) VerifyChannelState( ctx sdk.Context, - connection types.ConnectionEnd, + connection exported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, channel channelexported.ChannelI, - consensusState clientexported.ConsensusState, ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { return clienttypes.ErrClientNotFound } + // TODO: move to specific clients; blocked by #5502 + consensusState, found := k.clientKeeper.GetClientConsensusState( + ctx, connection.GetClientID(), height, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound + } + return clientState.VerifyChannelState( k.cdc, height, connection.GetCounterparty().GetPrefix(), proof, portID, channelID, channel, consensusState, @@ -75,20 +90,27 @@ func (k Keeper) VerifyChannelState( // the specified port, specified channel, and specified sequence. func (k Keeper) VerifyPacketCommitment( ctx sdk.Context, - connection types.ConnectionEnd, + connection exported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, sequence uint64, commitmentBytes []byte, - consensusState clientexported.ConsensusState, ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { return clienttypes.ErrClientNotFound } + // TODO: move to specific clients; blocked by #5502 + consensusState, found := k.clientKeeper.GetClientConsensusState( + ctx, connection.GetClientID(), height, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound + } + return clientState.VerifyPacketCommitment( height, connection.GetCounterparty().GetPrefix(), proof, portID, channelID, sequence, commitmentBytes, consensusState, @@ -99,20 +121,27 @@ func (k Keeper) VerifyPacketCommitment( // acknowledgement at the specified port, specified channel, and specified sequence. func (k Keeper) VerifyPacketAcknowledgement( ctx sdk.Context, - connection types.ConnectionEnd, + connection exported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, sequence uint64, acknowledgement []byte, - consensusState clientexported.ConsensusState, ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { return clienttypes.ErrClientNotFound } + // TODO: move to specific clients; blocked by #5502 + consensusState, found := k.clientKeeper.GetClientConsensusState( + ctx, connection.GetClientID(), height, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound + } + return clientState.VerifyPacketAcknowledgement( height, connection.GetCounterparty().GetPrefix(), proof, portID, channelID, sequence, acknowledgement, consensusState, @@ -124,19 +153,26 @@ func (k Keeper) VerifyPacketAcknowledgement( // specified sequence. func (k Keeper) VerifyPacketAcknowledgementAbsence( ctx sdk.Context, - connection types.ConnectionEnd, + connection exported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, sequence uint64, - consensusState clientexported.ConsensusState, ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { return clienttypes.ErrClientNotFound } + // TODO: move to specific clients; blocked by #5502 + consensusState, found := k.clientKeeper.GetClientConsensusState( + ctx, connection.GetClientID(), height, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound + } + return clientState.VerifyPacketAcknowledgementAbsence( height, connection.GetCounterparty().GetPrefix(), proof, portID, channelID, sequence, consensusState, @@ -147,19 +183,26 @@ func (k Keeper) VerifyPacketAcknowledgementAbsence( // received of the specified channel at the specified port. func (k Keeper) VerifyNextSequenceRecv( ctx sdk.Context, - connection types.ConnectionEnd, + connection exported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, nextSequenceRecv uint64, - consensusState clientexported.ConsensusState, ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { return clienttypes.ErrClientNotFound } + // TODO: move to specific clients; blocked by #5502 + consensusState, found := k.clientKeeper.GetClientConsensusState( + ctx, connection.GetClientID(), height, + ) + if !found { + return clienttypes.ErrConsensusStateNotFound + } + return clientState.VerifyNextSequenceRecv( height, connection.GetCounterparty().GetPrefix(), proof, portID, channelID, nextSequenceRecv, consensusState, diff --git a/x/ibc/03-connection/keeper/verify_test.go b/x/ibc/03-connection/keeper/verify_test.go index 7e20b27b9557..614929666543 100644 --- a/x/ibc/03-connection/keeper/verify_test.go +++ b/x/ibc/03-connection/keeper/verify_test.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) const ( @@ -30,14 +31,15 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { cases := []struct { msg string connection types.ConnectionEnd + proof commitment.ProofI malleate func() expPass bool }{ - {"verification success", connection1, func() { + {"verification success", connection1, validProof{}, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", connection1, func() {}, false}, - {"verification failed", connection1, func() { + {"client state not found", connection1, validProof{}, func() {}, false}, + {"verification failed", connection1, invalidProof{}, func() { suite.createClient(testClientID2) }, false}, } @@ -48,23 +50,20 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { suite.SetupTest() // reset tc.malleate() - suite.updateClient(testClientID1) - proofHeight := suite.ctx.BlockHeight() - 1 + proofHeight := suite.ctx.BlockHeight() // TODO: remove mocked types and uncomment // consensusKey := ibctypes.KeyConsensusState(testClientID1, uint64(suite.app.LastBlockHeight())) // proof, proofHeight := suite.queryProof(consensusKey) + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyClientConsensusState( + suite.ctx, tc.connection, uint64(proofHeight), tc.proof, suite.consensusState, + ) + if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyClientConsensusState( - suite.ctx, tc.connection, uint64(proofHeight), validProof{}, suite.consensusState, - ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyClientConsensusState( - suite.ctx, tc.connection, uint64(proofHeight), invalidProof{}, suite.consensusState, - ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } }) @@ -75,14 +74,17 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { // connectionKey := ibctypes.KeyConnection(testConnectionID1) cases := []struct { msg string + proof commitment.ProofI malleate func() expPass bool }{ - {"verification success", func() { + {"verification success", validProof{}, func() { suite.createClient(testClientID1) + suite.createClient(testClientID2) }, true}, - {"client state not found", func() {}, false}, - {"verification failed", func() { + {"client state not found", validProof{}, func() {}, false}, + {"verification failed", invalidProof{}, func() { + suite.createClient(testClientID1) suite.createClient(testClientID2) }, false}, } @@ -95,19 +97,19 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { tc.malleate() connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) suite.updateClient(testClientID1) - - proofHeight := suite.ctx.BlockHeight() - 1 + counterparty := types.NewCounterparty(testClientID1, testConnectionID1, commitment.NewPrefix([]byte("ibc"))) + expectedConnection := types.NewConnectionEnd(exported.INIT, testClientID2, counterparty, []string{"1.0.0"}) + suite.updateClient(testClientID1) + proofHeight := uint64(3) // proof, proofHeight := suite.queryProof(connectionKey) + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyConnectionState( + suite.ctx, connection, proofHeight, tc.proof, testConnectionID1, expectedConnection, + ) + if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyConnectionState( - suite.ctx, uint64(proofHeight), validProof{}, testConnectionID1, connection, suite.consensusState, - ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyConnectionState( - suite.ctx, uint64(proofHeight), invalidProof{}, testConnectionID1, connection, suite.consensusState, - ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } }) @@ -116,17 +118,21 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { func (suite *KeeperTestSuite) TestVerifyChannelState() { // channelKey := ibctypes.KeyChannel(testPort1, testChannel1) - cases := []struct { - msg string - malleate func() - expPass bool + msg string + proof commitment.ProofI + proofHeight uint64 + malleate func() + expPass bool }{ - {"verification success", func() { + {"verification success", validProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", func() {}, false}, - {"verification failed", func() { + {"client state not found", validProof{}, 2, func() {}, false}, + {"consensus state not found", validProof{}, 100, func() { + suite.createClient(testClientID1) + }, false}, + {"verification failed", invalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } @@ -144,20 +150,15 @@ func (suite *KeeperTestSuite) TestVerifyChannelState() { ) suite.updateClient(testClientID1) - proofHeight := suite.ctx.BlockHeight() - 1 // proof, proofHeight := suite.queryProof(channelKey) + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyChannelState( + suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + testChannel1, channel, + ) if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyChannelState( - suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, - testChannel1, channel, suite.consensusState, - ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyChannelState( - suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, - testChannel1, channel, suite.consensusState, - ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } }) @@ -169,15 +170,20 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { commitmentBz := []byte("commitment") cases := []struct { - msg string - malleate func() - expPass bool + msg string + proof commitment.ProofI + proofHeight uint64 + malleate func() + expPass bool }{ - {"verification success", func() { + {"verification success", validProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", func() {}, false}, - {"verification failed", func() { + {"client state not found", validProof{}, 2, func() {}, false}, + {"consensus state not found", validProof{}, 100, func() { + suite.createClient(testClientID1) + }, false}, + {"verification failed", invalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } @@ -192,20 +198,15 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, commitmentBz) suite.updateClient(testClientID1) - proofHeight := suite.ctx.BlockHeight() - 1 // proof, proofHeight := suite.queryProof(commitmentKey) + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketCommitment( + suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + testChannel1, 1, commitmentBz, + ) if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketCommitment( - suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, - testChannel1, 1, commitmentBz, suite.consensusState, - ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketCommitment( - suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, - testChannel1, 1, commitmentBz, suite.consensusState, - ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } }) @@ -217,15 +218,20 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { ack := []byte("acknowledgement") cases := []struct { - msg string - malleate func() - expPass bool + msg string + proof commitment.ProofI + proofHeight uint64 + malleate func() + expPass bool }{ - {"verification success", func() { + {"verification success", validProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", func() {}, false}, - {"verification failed", func() { + {"client state not found", validProof{}, 2, func() {}, false}, + {"consensus state not found", validProof{}, 100, func() { + suite.createClient(testClientID1) + }, false}, + {"verification failed", invalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } @@ -239,21 +245,16 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) suite.app.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, 1, ack) suite.updateClient(testClientID1) - - proofHeight := suite.ctx.BlockHeight() - 1 // proof, proofHeight := suite.queryProof(packetAckKey) + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgement( + suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + testChannel1, 1, ack, + ) + if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgement( - suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, - testChannel1, 1, ack, suite.consensusState, - ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgement( - suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, - testChannel1, 1, ack, suite.consensusState, - ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } }) @@ -264,15 +265,20 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { // packetAckKey := ibctypes.KeyPacketAcknowledgement(testPort1, testChannel1, 1) cases := []struct { - msg string - malleate func() - expPass bool + msg string + proof commitment.ProofI + proofHeight uint64 + malleate func() + expPass bool }{ - {"verification success", func() { + {"verification success", validProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", func() {}, false}, - {"verification failed", func() { + {"client state not found", validProof{}, 2, func() {}, false}, + {"consensus state not found", validProof{}, 100, func() { + suite.createClient(testClientID1) + }, false}, + {"verification failed", invalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } @@ -286,20 +292,16 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) suite.updateClient(testClientID1) - proofHeight := suite.ctx.BlockHeight() - 1 // proof, proofHeight := suite.queryProof(packetAckKey) + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgementAbsence( + suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + testChannel1, 1, + ) + if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgementAbsence( - suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, - testChannel1, 1, suite.consensusState, - ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgementAbsence( - suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, - testChannel1, 1, suite.consensusState, - ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } }) @@ -310,15 +312,20 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { // nextSeqRcvKey := ibctypes.KeyNextSequenceRecv(testPort1, testChannel1) cases := []struct { - msg string - malleate func() - expPass bool + msg string + proof commitment.ProofI + proofHeight uint64 + malleate func() + expPass bool }{ - {"verification success", func() { + {"verification success", validProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", func() {}, false}, - {"verification failed", func() { + {"client state not found", validProof{}, 2, func() {}, false}, + {"consensus state not found", validProof{}, 100, func() { + suite.createClient(testClientID1) + }, false}, + {"verification failed", invalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } @@ -333,20 +340,15 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, 1) suite.updateClient(testClientID1) - proofHeight := suite.ctx.BlockHeight() - 1 // proof, proofHeight := suite.queryProof(nextSeqRcvKey) + err := suite.app.IBCKeeper.ConnectionKeeper.VerifyNextSequenceRecv( + suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + testChannel1, 1, + ) if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyNextSequenceRecv( - suite.ctx, connection, uint64(proofHeight), validProof{}, testPort1, - testChannel1, 1, suite.consensusState, - ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyNextSequenceRecv( - suite.ctx, connection, uint64(proofHeight), invalidProof{}, testPort1, - testChannel1, 1, suite.consensusState, - ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } }) diff --git a/x/ibc/03-connection/types/expected_keepers.go b/x/ibc/03-connection/types/expected_keepers.go index a5de7514afa8..c91519e0dfb3 100644 --- a/x/ibc/03-connection/types/expected_keepers.go +++ b/x/ibc/03-connection/types/expected_keepers.go @@ -8,5 +8,6 @@ import ( // ClientKeeper expected account IBC client keeper type ClientKeeper interface { GetClientState(ctx sdk.Context, clientID string) (clientexported.ClientState, bool) - GetConsensusState(ctx sdk.Context, clientID string, height uint64) (clientexported.ConsensusState, bool) + GetClientConsensusState(ctx sdk.Context, clientID string, height uint64) (clientexported.ConsensusState, bool) + GetSelfConsensusState(ctx sdk.Context, height uint64) (clientexported.ConsensusState, bool) } diff --git a/x/ibc/03-connection/types/msgs.go b/x/ibc/03-connection/types/msgs.go index cde1eb87722b..673d42080490 100644 --- a/x/ibc/03-connection/types/msgs.go +++ b/x/ibc/03-connection/types/msgs.go @@ -249,24 +249,22 @@ var _ sdk.Msg = MsgConnectionOpenConfirm{} // MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to acknowledge // the change of connection state to OPEN on Chain A. type MsgConnectionOpenConfirm struct { - ConnectionID string `json:"connection_id"` - ProofAck commitment.ProofI `json:"proof_ack"` // proof for the change of the connection state on Chain A: `INIT -> OPEN` - ProofHeight uint64 `json:"proof_height"` - ConsensusHeight uint64 `json:"consensus_height"` - Signer sdk.AccAddress `json:"signer"` + ConnectionID string `json:"connection_id"` + ProofAck commitment.ProofI `json:"proof_ack"` // proof for the change of the connection state on Chain A: `INIT -> OPEN` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` } // NewMsgConnectionOpenConfirm creates a new MsgConnectionOpenConfirm instance func NewMsgConnectionOpenConfirm( - connectionID string, proofAck commitment.ProofI, proofHeight, consensusHeight uint64, + connectionID string, proofAck commitment.ProofI, proofHeight uint64, signer sdk.AccAddress, ) MsgConnectionOpenConfirm { return MsgConnectionOpenConfirm{ - ConnectionID: connectionID, - ProofAck: proofAck, - ProofHeight: proofHeight, - ConsensusHeight: consensusHeight, - Signer: signer, + ConnectionID: connectionID, + ProofAck: proofAck, + ProofHeight: proofHeight, + Signer: signer, } } @@ -294,9 +292,6 @@ func (msg MsgConnectionOpenConfirm) ValidateBasic() error { if msg.ProofHeight == 0 { return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } - if msg.ConsensusHeight == 0 { - return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "consensus height must be > 0") - } if msg.Signer.Empty() { return sdkerrors.ErrInvalidAddress } diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go index ae6c73e55889..8bca120769ba 100644 --- a/x/ibc/03-connection/types/msgs_test.go +++ b/x/ibc/03-connection/types/msgs_test.go @@ -183,13 +183,12 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenConfirm{ - NewMsgConnectionOpenConfirm("test/conn1", suite.proof, 10, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", nil, 10, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{Proof: nil}, 10, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 0, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, 0, signer), - NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, 10, nil), - NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, 10, signer), + NewMsgConnectionOpenConfirm("test/conn1", suite.proof, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", nil, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{Proof: nil}, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 0, signer), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, nil), + NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, signer), } var testCases = []struct { @@ -201,9 +200,8 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { {testMsgs[1], false, "empty proofTry"}, {testMsgs[2], false, "empty proofTry"}, {testMsgs[3], false, "invalid proofHeight"}, - {testMsgs[4], false, "invalid consensusHeight"}, - {testMsgs[5], false, "empty signer"}, - {testMsgs[6], true, "success"}, + {testMsgs[4], false, "empty signer"}, + {testMsgs[5], true, "success"}, } for i, tc := range testCases { diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index 1279b6d0ba25..9668cafe55ef 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -3,7 +3,6 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" @@ -130,16 +129,9 @@ func (k Keeper) ChanOpenTry( counterpartyHops, channel.Version, ) - consensusState, found := k.clientKeeper.GetConsensusState( - ctx, connectionEnd.GetClientID(), proofHeight, - ) - if !found { - return clienttypes.ErrConsensusStateNotFound - } - if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofInit, - counterparty.PortID, counterparty.ChannelID, expectedChannel, consensusState, + counterparty.PortID, counterparty.ChannelID, expectedChannel, ); err != nil { return err } @@ -208,17 +200,10 @@ func (k Keeper) ChanOpenAck( counterpartyHops, channel.Version, ) - consensusState, found := k.clientKeeper.GetConsensusState( - ctx, connectionEnd.GetClientID(), proofHeight, - ) - if !found { - return clienttypes.ErrConsensusStateNotFound - } - if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofTry, channel.Counterparty.PortID, channel.Counterparty.ChannelID, - expectedChannel, consensusState, + expectedChannel, ); err != nil { return err } @@ -286,17 +271,10 @@ func (k Keeper) ChanOpenConfirm( counterpartyHops, channel.Version, ) - consensusState, found := k.clientKeeper.GetConsensusState( - ctx, connectionEnd.GetClientID(), proofHeight, - ) - if !found { - return clienttypes.ErrConsensusStateNotFound - } - if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofAck, channel.Counterparty.PortID, channel.Counterparty.ChannelID, - expectedChannel, consensusState, + expectedChannel, ); err != nil { return err } @@ -410,17 +388,10 @@ func (k Keeper) ChanCloseConfirm( counterpartyHops, channel.Version, ) - consensusState, found := k.clientKeeper.GetConsensusState( - ctx, connectionEnd.GetClientID(), proofHeight, - ) - if !found { - return clienttypes.ErrConsensusStateNotFound - } - if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofInit, channel.Counterparty.PortID, channel.Counterparty.ChannelID, - expectedChannel, consensusState, + expectedChannel, ); err != nil { return err } diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index b502bbfe7347..68423fefb7a3 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -222,7 +222,7 @@ func (suite *KeeperTestSuite) updateClient() { Root: commitment.NewRoot(commitID.Hash), } - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClientID1, uint64(height-1), state) + suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClientID1, uint64(height-1), state) csi, _ := suite.app.IBCKeeper.ClientKeeper.GetClientState(suite.ctx, testClientID1) cs, _ := csi.(tendermint.ClientState) cs.LatestHeight = uint64(height - 1) diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 1c6ee2a5711e..c56d993215f1 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -7,7 +7,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" @@ -162,17 +161,10 @@ func (k Keeper) RecvPacket( return nil, types.ErrPacketTimeout } - consensusState, found := k.clientKeeper.GetConsensusState( - ctx, connectionEnd.GetClientID(), proofHeight, - ) - if !found { - return nil, clienttypes.ErrConsensusStateNotFound - } - if err := k.connectionKeeper.VerifyPacketCommitment( ctx, connectionEnd, proofHeight, proof, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), - types.CommitPacket(packet.GetData()), consensusState, + types.CommitPacket(packet.GetData()), ); err != nil { return nil, sdkerrors.Wrap(err, "couldn't verify counterparty packet commitment") } @@ -292,16 +284,9 @@ func (k Keeper) AcknowledgePacket( return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } - consensusState, found := k.clientKeeper.GetConsensusState( - ctx, connectionEnd.GetClientID(), proofHeight, - ) - if !found { - return nil, clienttypes.ErrConsensusStateNotFound - } - if err := k.connectionKeeper.VerifyPacketAcknowledgement( ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), - packet.GetSequence(), acknowledgement.GetBytes(), consensusState, + packet.GetSequence(), acknowledgement.GetBytes(), ); err != nil { return nil, sdkerrors.Wrap(err, "invalid acknowledgement on counterparty chain") } @@ -387,13 +372,6 @@ func (k Keeper) CleanupPacket( return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } - consensusState, found := k.clientKeeper.GetConsensusState( - ctx, connectionEnd.GetClientID(), proofHeight, - ) - if !found { - return nil, clienttypes.ErrConsensusStateNotFound - } - var err error switch channel.Ordering { case exported.ORDERED: @@ -401,13 +379,12 @@ func (k Keeper) CleanupPacket( err = k.connectionKeeper.VerifyNextSequenceRecv( ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv, - consensusState, ) case exported.UNORDERED: err = k.connectionKeeper.VerifyPacketAcknowledgement( ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), - acknowledgement, consensusState, + acknowledgement, ) default: panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index 63b522d88b22..72a4afec52dc 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -5,7 +5,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" @@ -81,13 +80,6 @@ func (k Keeper) TimeoutPacket( return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } - consensusState, found := k.clientKeeper.GetConsensusState( - ctx, connectionEnd.GetClientID(), proofHeight, - ) - if !found { - return nil, clienttypes.ErrConsensusStateNotFound - } - var err error switch channel.Ordering { case exported.ORDERED: @@ -95,13 +87,11 @@ func (k Keeper) TimeoutPacket( err = k.connectionKeeper.VerifyNextSequenceRecv( ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv, - consensusState, ) case exported.UNORDERED: err = k.connectionKeeper.VerifyPacketAcknowledgementAbsence( ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), - consensusState, ) default: panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) @@ -203,18 +193,11 @@ func (k Keeper) TimeoutOnClose( exported.CLOSED, channel.Ordering, counterparty, counterpartyHops, channel.Version, ) - consensusState, found := k.clientKeeper.GetConsensusState( - ctx, connectionEnd.GetClientID(), proofHeight, - ) - if !found { - return nil, clienttypes.ErrConsensusStateNotFound - } - // check that the opposing channel end has closed if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofClosed, channel.Counterparty.PortID, channel.Counterparty.ChannelID, - expectedChannel, consensusState, + expectedChannel, ); err != nil { return nil, err } @@ -226,13 +209,11 @@ func (k Keeper) TimeoutOnClose( err = k.connectionKeeper.VerifyNextSequenceRecv( ctx, connectionEnd, proofHeight, proofClosed, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv, - consensusState, ) case exported.UNORDERED: err = k.connectionKeeper.VerifyPacketAcknowledgementAbsence( ctx, connectionEnd, proofHeight, proofClosed, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), - consensusState, ) default: panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) diff --git a/x/ibc/04-channel/types/expected_keepers.go b/x/ibc/04-channel/types/expected_keepers.go index a8b00b4ac014..c63fa9a9fe80 100644 --- a/x/ibc/04-channel/types/expected_keepers.go +++ b/x/ibc/04-channel/types/expected_keepers.go @@ -3,6 +3,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -11,7 +12,6 @@ import ( // ClientKeeper expected account IBC client keeper type ClientKeeper interface { GetClientState(ctx sdk.Context, clientID string) (clientexported.ClientState, bool) - GetConsensusState(ctx sdk.Context, clientID string, height uint64) (clientexported.ConsensusState, bool) } // ConnectionKeeper expected account IBC connection keeper @@ -19,55 +19,50 @@ type ConnectionKeeper interface { GetConnection(ctx sdk.Context, connectionID string) (connectiontypes.ConnectionEnd, bool) VerifyChannelState( ctx sdk.Context, - connection connectiontypes.ConnectionEnd, + connection connectionexported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, channel exported.ChannelI, - consensusState clientexported.ConsensusState, ) error VerifyPacketCommitment( ctx sdk.Context, - connection connectiontypes.ConnectionEnd, + connection connectionexported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, sequence uint64, commitmentBytes []byte, - consensusState clientexported.ConsensusState, ) error VerifyPacketAcknowledgement( ctx sdk.Context, - connection connectiontypes.ConnectionEnd, + connection connectionexported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, sequence uint64, acknowledgement []byte, - consensusState clientexported.ConsensusState, ) error VerifyPacketAcknowledgementAbsence( ctx sdk.Context, - connection connectiontypes.ConnectionEnd, + connection connectionexported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, sequence uint64, - consensusState clientexported.ConsensusState, ) error VerifyNextSequenceRecv( ctx sdk.Context, - connection connectiontypes.ConnectionEnd, + connection connectionexported.ConnectionI, height uint64, proof commitment.ProofI, portID, channelID string, nextSequenceRecv uint64, - consensusState clientexported.ConsensusState, ) error } diff --git a/x/ibc/07-tendermint/client_state.go b/x/ibc/07-tendermint/client_state.go index ff10c73a514e..9ea492e2db72 100644 --- a/x/ibc/07-tendermint/client_state.go +++ b/x/ibc/07-tendermint/client_state.go @@ -1,6 +1,8 @@ package tendermint import ( + "fmt" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -271,7 +273,10 @@ func validateVerificationArgs( consensusState clientexported.ConsensusState, ) error { if cs.LatestHeight < height { - return ibctypes.ErrInvalidHeight + return sdkerrors.Wrap( + ibctypes.ErrInvalidHeight, + fmt.Sprintf("client state (%s) height < proof height (%d < %d)", cs.ID, cs.LatestHeight, height), + ) } if cs.IsFrozen() && cs.FrozenHeight <= height { diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index b1845266b480..7a359de46651 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -36,9 +36,9 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) - ctx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) - sender := ctx.GetFromAddress() + sender := cliCtx.GetFromAddress() srcPort := args[0] srcChannel := args[1] receiver, err := sdk.AccAddressFromBech32(args[2]) @@ -59,79 +59,9 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { return err } - return authclient.GenerateOrBroadcastMsgs(ctx, txBldr, []sdk.Msg{msg}) + return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") return cmd } - -// // GetMsgRecvPacketCmd returns the command to create a MsgRecvTransferPacket transaction -// func GetMsgRecvPacketCmd(cdc *codec.Codec) *cobra.Command { -// cmd := &cobra.Command{ -// Use: "recv-packet [sending-port-id] [sending-channel-id] [client-id]", -// Short: "Creates and sends a SendPacket message", -// Args: cobra.ExactArgs(3), -// RunE: func(cmd *cobra.Command, args []string) error { -// inBuf := bufio.NewReader(cmd.InOrStdin()) -// txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) -// cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) - -// prove := viper.GetBool(flags.FlagProve) -// node2 := viper.GetString(FlagNode2) -// cid1 := viper.GetString(flags.FlagChainID) -// cid2 := viper.GetString(FlagChainID2) -// cliCtx2 := context.NewCLIContextIBC(cliCtx.GetFromAddress().String(), cid2, node2). -// WithCodec(cdc). -// WithBroadcastMode(flags.BroadcastBlock) - -// header, _, err := clientutils.QueryTendermintHeader(cliCtx2) -// if err != nil { -// return err -// } - -// sourcePort, sourceChannel, clientid := args[0], args[1], args[2] - -// passphrase, err := keys.GetPassphrase(viper.GetString(flags.FlagFrom)) -// if err != nil { -// return nil -// } - -// viper.Set(flags.FlagChainID, cid1) -// msgUpdateClient := clienttypes.NewMsgUpdateClient(clientid, header, cliCtx.GetFromAddress()) -// if err := msgUpdateClient.ValidateBasic(); err != nil { -// return err -// } - -// res, err := utils.CompleteAndBroadcastTx(txBldr, cliCtx, []sdk.Msg{msgUpdateClient}, passphrase) -// if err != nil || !res.IsOK() { -// return err -// } - -// viper.Set(flags.FlagChainID, cid2) -// sequence := uint64(viper.GetInt(FlagSequence)) -// packetRes, err := channelutils.QueryPacket(cliCtx2.WithHeight(header.Height-1), sourcePort, sourceChannel, sequence, uint64(viper.GetInt(FlagTimeout)), prove) -// if err != nil { -// return err -// } - -// viper.Set(flags.FlagChainID, cid1) - -// msg := types.NewMsgRecvPacket(packetRes.Packet, []commitment.Proof{packetRes.Proof}, packetRes.ProofHeight, cliCtx.GetFromAddress()) -// if err := msg.ValidateBasic(); err != nil { -// return err -// } - -// return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) -// }, -// } - -// cmd = client.PostCommands(cmd)[0] -// cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") -// cmd.Flags().String(FlagNode2, "tcp://localhost:26657", "RPC port for the second chain") -// cmd.Flags().String(FlagChainID2, "", "chain-id for the second chain") -// cmd.Flags().String(FlagSequence, "", "sequence for the packet") -// cmd.Flags().String(FlagTimeout, "", "timeout for the packet") -// cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") -// return cmd -// } diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 8a87dae74783..ba65c0552408 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -104,7 +104,7 @@ func (suite *HandlerTestSuite) updateClient() { Root: commitment.NewRoot(commitID.Hash), } - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, 1, state) + suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, 1, state) } func (suite *HandlerTestSuite) createConnection(state connectionexported.State) { diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 74b80429b09e..7ce3591bd408 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -45,7 +45,7 @@ func (suite *KeeperTestSuite) updateClient() { Root: commitment.NewRoot(commitID.Hash), } - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, 1, state) + suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, 1, state) } func (suite *KeeperTestSuite) createConnection(state connectionexported.State) { diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index b79fbe5313eb..1b41921815e1 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -24,7 +24,7 @@ type ChannelKeeper interface { // ClientKeeper defines the expected IBC client keeper type ClientKeeper interface { - GetConsensusState(ctx sdk.Context, clientID string) (connection clientexported.ConsensusState, found bool) + GetClientConsensusState(ctx sdk.Context, clientID string) (connection clientexported.ConsensusState, found bool) } // ConnectionKeeper defines the expected IBC connection keeper diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go index f6c23c3d9627..1ce47f8ebf2e 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/ante/ante_test.go @@ -75,7 +75,7 @@ func (suite *HandlerTestSuite) createClient() { } _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, uint64(suite.app.LastBlockHeight()), consensusState) + suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, uint64(suite.app.LastBlockHeight()), consensusState) suite.NoError(err) } @@ -92,7 +92,7 @@ func (suite *HandlerTestSuite) updateClient() { Root: commitment.NewRoot(commitID.Hash), } - suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, testClient, uint64(height-1), state) + suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, uint64(height-1), state) csi, _ := suite.app.IBCKeeper.ClientKeeper.GetClientState(suite.ctx, testClient) cs, _ := csi.(tendermint.ClientState) cs.LatestHeight = uint64(height - 1) diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 35104f4f3eb1..aefe2863b4de 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -7,7 +7,6 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" ) // Keeper defines each ICS keeper for IBC @@ -20,10 +19,9 @@ type Keeper struct { // NewKeeper creates a new ibc Keeper func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, - bk transfer.BankKeeper, sk transfer.SupplyKeeper, + cdc *codec.Codec, key sdk.StoreKey, stakingKeeper client.StakingKeeper, ) Keeper { - clientKeeper := client.NewKeeper(cdc, key) + clientKeeper := client.NewKeeper(cdc, key, stakingKeeper) connectionKeeper := connection.NewKeeper(cdc, key, clientKeeper) portKeeper := port.NewKeeper(cdc, key) channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper) diff --git a/x/staking/types/historical_info.go b/x/staking/types/historical_info.go index 78db1e7dd4a9..1c08caebcde6 100644 --- a/x/staking/types/historical_info.go +++ b/x/staking/types/historical_info.go @@ -12,13 +12,13 @@ import ( // HistoricalInfo contains the historical information that gets stored at each height type HistoricalInfo struct { Header abci.Header `json:"header" yaml:"header"` - ValSet []Validator `json:"valset" yaml:"valset"` + ValSet Validators `json:"valset" yaml:"valset"` } // NewHistoricalInfo will create a historical information struct from header and valset // it will first sort valset before inclusion into historical info -func NewHistoricalInfo(header abci.Header, valSet []Validator) HistoricalInfo { - sort.Sort(Validators(valSet)) +func NewHistoricalInfo(header abci.Header, valSet Validators) HistoricalInfo { + sort.Sort(valSet) return HistoricalInfo{ Header: header, ValSet: valSet, diff --git a/x/staking/types/validator.go b/x/staking/types/validator.go index d64e0ce3e751..855ed988d290 100644 --- a/x/staking/types/validator.go +++ b/x/staking/types/validator.go @@ -104,6 +104,15 @@ func (v Validators) ToSDKValidators() (validators []exported.ValidatorI) { return validators } +// ToTmValidators casts all validators to the corresponding tendermint type. +func (v Validators) ToTmValidators() []*tmtypes.Validator { + validators := make([]*tmtypes.Validator, len(v)) + for i, val := range v { + validators[i] = val.ToTmValidator() + } + return validators +} + // Sort Validators sorts validator array in ascending operator address order func (v Validators) Sort() { sort.Sort(v) @@ -370,6 +379,11 @@ func (v Validator) ABCIValidatorUpdateZero() abci.ValidatorUpdate { } } +// ToTmValidator casts an SDK validator to a tendermint type Validator. +func (v Validator) ToTmValidator() *tmtypes.Validator { + return tmtypes.NewValidator(v.ConsPubKey, v.ConsensusPower()) +} + // SetInitialCommission attempts to set a validator's initial commission. An // error is returned if the commission is invalid. func (v Validator) SetInitialCommission(commission Commission) (Validator, error) { diff --git a/x/staking/types/validator_test.go b/x/staking/types/validator_test.go index e6a7ccbe961a..b8a572444e0c 100644 --- a/x/staking/types/validator_test.go +++ b/x/staking/types/validator_test.go @@ -335,3 +335,19 @@ func TestValidatorsSortDeterminism(t *testing.T) { require.True(t, reflect.DeepEqual(sortedVals, vals), "Validator sort returned different slices") } } + +func TestValidatorToTm(t *testing.T) { + vals := make(Validators, 10) + expected := make([]*tmtypes.Validator, 10) + + for i := range vals { + pk := ed25519.GenPrivKey().PubKey() + val := NewValidator(sdk.ValAddress(pk.Address()), pk, Description{}) + val.Status = sdk.Bonded + val.Tokens = sdk.NewInt(rand.Int63()) + vals[i] = val + expected[i] = tmtypes.NewValidator(pk, val.ConsensusPower()) + } + + require.Equal(t, expected, vals.ToTmValidators()) +} From bf906aaaa956b2ab49c1b3a43a879e7d3cdc83f8 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Wed, 29 Jan 2020 10:49:21 +0100 Subject: [PATCH 070/176] cleanup ibc-alpha diff with master --- CHANGELOG.md | 2 -- client/context/context.go | 50 ------------------------------- client/context/query.go | 55 ++-------------------------------- client/flags/flags.go | 10 +++---- client/keys/add.go | 38 ++--------------------- client/keys/add_ledger_test.go | 4 +-- client/keys/add_test.go | 2 +- client/keys/migrate_test.go | 2 +- client/keys/root.go | 3 +- client/keys/root_test.go | 2 +- store/iavl/store.go | 2 +- x/auth/client/tx.go | 39 ------------------------ 12 files changed, 15 insertions(+), 194 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f2b4b43d482..5b1a9c20bcf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2879,5 +2879,3 @@ BUG FIXES: [v0.37.1]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.1 [v0.37.0]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.0 [v0.36.0]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.36.0 - - diff --git a/client/context/context.go b/client/context/context.go index 5b158844670a..28bfe8e830b0 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -104,56 +104,6 @@ func NewCLIContextWithInputAndFrom(input io.Reader, from string) CLIContext { return ctx.WithVerifier(verifier) } -// NewCLIContextIBC takes additional arguments -func NewCLIContextIBC(input io.Reader, from string, chainID string, nodeURI string) CLIContext { - var rpc rpcclient.Client - - genOnly := viper.GetBool(flags.FlagGenerateOnly) - fromAddress, fromName, err := GetFromFields(input, from, genOnly) - if err != nil { - fmt.Printf("failed to get from fields: %v", err) - os.Exit(1) - } - - if !genOnly { - if nodeURI != "" { - rpc, err = rpcclient.NewHTTP(nodeURI, "/websocket") - if err != nil { - panic(err) - } - } - } - - ctx := CLIContext{ - Client: rpc, - ChainID: chainID, - Output: os.Stdout, - NodeURI: nodeURI, - From: from, - OutputFormat: viper.GetString(cli.OutputFlag), - Height: viper.GetInt64(flags.FlagHeight), - HomeDir: viper.GetString(flags.FlagHome), - TrustNode: viper.GetBool(flags.FlagTrustNode), - UseLedger: viper.GetBool(flags.FlagUseLedger), - BroadcastMode: viper.GetString(flags.FlagBroadcastMode), - Simulate: viper.GetBool(flags.FlagDryRun), - GenerateOnly: genOnly, - FromAddress: fromAddress, - FromName: fromName, - Indent: viper.GetBool(flags.FlagIndentResponse), - SkipConfirm: viper.GetBool(flags.FlagSkipConfirmation), - } - - // create a verifier for the specific chain ID and RPC client - verifier, err := CreateVerifier(ctx, DefaultVerifierCacheSize) - if err != nil && viper.IsSet(flags.FlagTrustNode) { - fmt.Printf("failed to create verifier: %s\n", err) - os.Exit(1) - } - - return ctx.WithVerifier(verifier) -} - // NewCLIContextWithFrom returns a new initialized CLIContext with parameters from the // command line using Viper. It takes a key name or address and populates the FromName and // FromAddress field accordingly. It will also create Tendermint verifier using diff --git a/client/context/query.go b/client/context/query.go index a10862af8733..0e5f416b3658 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -3,7 +3,6 @@ package context import ( "fmt" "strings" - "time" "github.com/pkg/errors" @@ -13,7 +12,6 @@ import ( tmliteErr "github.com/tendermint/tendermint/lite/errors" tmliteProxy "github.com/tendermint/tendermint/lite/proxy" rpcclient "github.com/tendermint/tendermint/rpc/client" - ctypes "github.com/tendermint/tendermint/rpc/core/types" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/store/rootmulti" @@ -30,55 +28,6 @@ func (ctx CLIContext) GetNode() (rpcclient.Client, error) { return ctx.Client, nil } -// WaitForNBlocks blocks until the node defined on the context has advanced N blocks -func (ctx CLIContext) WaitForNBlocks(n int64) { - node, err := ctx.GetNode() - if err != nil { - panic(err) - } - - resBlock, err := node.Block(nil) - var height int64 - if err != nil || resBlock.Block == nil { - // wait for the first block to exist - ctx.waitForHeight(1) - height = 1 + n - } else { - height = resBlock.Block.Height + n - } - ctx.waitForHeight(height) -} - -func (ctx CLIContext) waitForHeight(height int64) { - node, err := ctx.GetNode() - if err != nil { - panic(err) - } - - for { - // get url, try a few times - var resBlock *ctypes.ResultBlock - var err error - INNER: - for i := 0; i < 5; i++ { - resBlock, err = node.Block(nil) - if err == nil { - break INNER - } - time.Sleep(time.Millisecond * 200) - } - if err != nil { - panic(err) - } - - if resBlock.Block != nil && resBlock.Block.Height >= height { - return - } - - time.Sleep(time.Millisecond * 100) - } -} - // Query performs a query to a Tendermint node with the provided path. // It returns the result and height of the query upon success or an error if // the query fails. @@ -178,13 +127,13 @@ func (ctx CLIContext) queryABCI(req abci.RequestQuery) (abci.ResponseQuery, erro // or an error if the query fails. In addition, it will verify the returned // proof if TrustNode is disabled. If proof verification fails or the query // height is invalid, an error will be returned. -func (ctx CLIContext) query(path string, key tmbytes.HexBytes) (res []byte, height int64, err error) { +func (ctx CLIContext) query(path string, key tmbytes.HexBytes) ([]byte, int64, error) { resp, err := ctx.queryABCI(abci.RequestQuery{ Path: path, Data: key, }) if err != nil { - return + return nil, 0, err } return resp.Value, resp.Height, nil diff --git a/client/flags/flags.go b/client/flags/flags.go index 6107ef7e718a..64dc2f25a34f 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -9,6 +9,8 @@ import ( "github.com/spf13/viper" tmcli "github.com/tendermint/tendermint/libs/cli" + + "github.com/cosmos/cosmos-sdk/crypto/keys" ) // nolint @@ -19,13 +21,9 @@ const ( DefaultGasAdjustment = 1.0 DefaultGasLimit = 200000 GasFlagAuto = "auto" -) -const ( - DefaultKeyringBackend = KeyringBackendOS - KeyringBackendFile = "file" - KeyringBackendOS = "os" - KeyringBackendTest = "test" + // DefaultKeyringBackend + DefaultKeyringBackend = keys.BackendOS ) const ( diff --git a/client/keys/add.go b/client/keys/add.go index 4c0353b48f27..4f5fda67d731 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -39,42 +39,8 @@ const ( DefaultKeyPass = "12345678" ) -func addKeyScriptingCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "test [name] [mnemonic] [password]", - Short: "Add a recovered mnemonic to the keystore encrypt it, and save to disk, for testing", - Long: `Derive a new private key from an existing mnemonic file and encrypt to disk. - -NOTE: This is insecure and only meant to be used during testing!!!! HERE BE DRAGONS! -`, - Args: cobra.ExactArgs(3), - RunE: func(cmd *cobra.Command, args []string) error { - kb, err := NewKeyBaseFromDir(viper.GetString(flags.FlagHome)) - if err != nil { - return err - } - - _, err = kb.Get(args[0]) - if err == nil { - return errors.New("key already exists, exiting") - } - - if !bip39.IsMnemonicValid(args[1]) { - return errors.New("invalid mnemonic") - } - - info, err := kb.CreateAccount(args[0], args[1], "", args[2], keys.CreateHDPath(0, 0).String(), keys.Secp256k1) - if err != nil { - return err - } - - return printCreate(cmd, info, false, "") - }, - } - return cmd -} - -func addKeyCommand() *cobra.Command { +// AddKeyCommand defines a keys command to add a generated or recovered private key to keybase. +func AddKeyCommand() *cobra.Command { cmd := &cobra.Command{ Use: "add ", Short: "Add an encrypted private key (either newly generated or recovered), encrypt it, and save to disk", diff --git a/client/keys/add_ledger_test.go b/client/keys/add_ledger_test.go index 4bfe61fe482d..0b8efe8e66de 100644 --- a/client/keys/add_ledger_test.go +++ b/client/keys/add_ledger_test.go @@ -33,7 +33,7 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) { config.SetBech32PrefixForValidator(bech32PrefixValAddr, bech32PrefixValPub) config.SetBech32PrefixForConsensusNode(bech32PrefixConsAddr, bech32PrefixConsPub) - cmd := addKeyCommand() + cmd := AddKeyCommand() require.NotNil(t, cmd) // Prepare a keybase @@ -80,7 +80,7 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) { func Test_runAddCmdLedger(t *testing.T) { runningUnattended := isRunningUnattended() - cmd := addKeyCommand() + cmd := AddKeyCommand() require.NotNil(t, cmd) mockIn, _, _ := tests.ApplyMockIO(cmd) diff --git a/client/keys/add_test.go b/client/keys/add_test.go index fb10c1b24cf5..b1ebee331684 100644 --- a/client/keys/add_test.go +++ b/client/keys/add_test.go @@ -17,7 +17,7 @@ import ( func Test_runAddCmdBasic(t *testing.T) { runningUnattended := isRunningUnattended() - cmd := addKeyCommand() + cmd := AddKeyCommand() assert.NotNil(t, cmd) mockIn, _, _ := tests.ApplyMockIO(cmd) diff --git a/client/keys/migrate_test.go b/client/keys/migrate_test.go index ef7b5979e666..0ad9226d309d 100644 --- a/client/keys/migrate_test.go +++ b/client/keys/migrate_test.go @@ -13,7 +13,7 @@ import ( ) func Test_runMigrateCmd(t *testing.T) { - cmd := addKeyCommand() + cmd := AddKeyCommand() assert.NotNil(t, cmd) mockIn, _, _ := tests.ApplyMockIO(cmd) diff --git a/client/keys/root.go b/client/keys/root.go index 7786070e9109..b7f70059c015 100644 --- a/client/keys/root.go +++ b/client/keys/root.go @@ -21,7 +21,7 @@ func Commands() *cobra.Command { } cmd.AddCommand( MnemonicKeyCommand(), - addKeyCommand(), + AddKeyCommand(), ExportKeyCommand(), ImportKeyCommand(), ListKeysCmd(), @@ -31,7 +31,6 @@ func Commands() *cobra.Command { UpdateKeyCommand(), ParseKeyStringCommand(), MigrateCommand(), - addKeyScriptingCommand(), ) cmd.PersistentFlags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") viper.BindPFlag(flags.FlagKeyringBackend, cmd.Flags().Lookup(flags.FlagKeyringBackend)) diff --git a/client/keys/root_test.go b/client/keys/root_test.go index 0d627350bfda..50bb3a5975c1 100644 --- a/client/keys/root_test.go +++ b/client/keys/root_test.go @@ -16,7 +16,7 @@ func TestCommands(t *testing.T) { assert.NotNil(t, rootCommands) // Commands are registered - assert.Equal(t, 12, len(rootCommands.Commands())) + assert.Equal(t, 11, len(rootCommands.Commands())) } func TestMain(m *testing.M) { diff --git a/store/iavl/store.go b/store/iavl/store.go index 153af5cd5a58..66c5e5262209 100644 --- a/store/iavl/store.go +++ b/store/iavl/store.go @@ -219,8 +219,8 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { switch req.Path { case "/key": // get by key key := req.Data // data holds the key bytes - res.Key = key + res.Key = key if !st.VersionExists(res.Height) { res.Log = iavl.ErrVersionDoesNotExist.Error() break diff --git a/x/auth/client/tx.go b/x/auth/client/tx.go index 6e1e5c4a5465..12d50a65ab03 100644 --- a/x/auth/client/tx.go +++ b/x/auth/client/tx.go @@ -108,45 +108,6 @@ func CompleteAndBroadcastTxCLI(txBldr authtypes.TxBuilder, cliCtx context.CLICon return cliCtx.PrintOutput(res) } -// CompleteAndBroadcastTx implements a utility function that facilitates -// sending a series of messages in a signed transaction given a TxBuilder and a -// QueryContext. It ensures that the account exists, has a proper number and -// sequence set. In addition, it builds and signs a transaction non-interactively -// with the supplied messages. Finally, it broadcasts the signed transaction to a node. -func CompleteAndBroadcastTx(txBldr authtypes.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg, passphrase string) (sdk.TxResponse, error) { - var res sdk.TxResponse - txBldr, err := PrepareTxBuilder(txBldr, cliCtx) - if err != nil { - return res, err - } - - fromName := cliCtx.GetFromName() - - if txBldr.SimulateAndExecute() || cliCtx.Simulate { - txBldr, err = EnrichWithGas(txBldr, cliCtx, msgs) - if err != nil { - return res, err - } - - gasEst := GasEstimateResponse{GasEstimate: txBldr.Gas()} - _, _ = fmt.Fprintf(os.Stderr, "%s\n", gasEst.String()) - } - - // build and sign the transaction - txBytes, err := txBldr.BuildAndSign(fromName, passphrase, msgs) - if err != nil { - return res, err - } - - // broadcast to a Tendermint node - res, err = cliCtx.BroadcastTx(txBytes) - if err != nil { - return res, err - } - - return res, err -} - // EnrichWithGas calculates the gas estimate that would be consumed by the // transaction and set the transaction's respective value accordingly. func EnrichWithGas(txBldr authtypes.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg) (authtypes.TxBuilder, error) { From 5e7a39b941dbfaff593cac07d5a8302d517df8dc Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Fri, 31 Jan 2020 14:12:40 -0800 Subject: [PATCH 071/176] Add bank alias for gaia --- x/bank/alias.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/bank/alias.go b/x/bank/alias.go index 2fdfa6602b82..3e1038cb6bf8 100644 --- a/x/bank/alias.go +++ b/x/bank/alias.go @@ -51,6 +51,7 @@ var ( ParamStoreKeySendEnabled = types.ParamStoreKeySendEnabled BalancesPrefix = types.BalancesPrefix AddressFromBalancesStore = types.AddressFromBalancesStore + GetGenesisStateFromAppState = types.GetGenesisStateFromAppState ) type ( From b52c07aa52cec85a5ca94859c9d564d80a2ad068 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Fri, 31 Jan 2020 14:18:19 -0800 Subject: [PATCH 072/176] Moar bank alias gaia --- x/bank/alias.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/bank/alias.go b/x/bank/alias.go index 3e1038cb6bf8..a0f05ec69a49 100644 --- a/x/bank/alias.go +++ b/x/bank/alias.go @@ -52,6 +52,7 @@ var ( BalancesPrefix = types.BalancesPrefix AddressFromBalancesStore = types.AddressFromBalancesStore GetGenesisStateFromAppState = types.GetGenesisStateFromAppState + GenesisBalancesIterator = types.GenesisBalancesIterator ) type ( From 81e14973890c7e93bce88dea45cdbf9df93e6685 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Fri, 31 Jan 2020 14:19:42 -0800 Subject: [PATCH 073/176] Moar bank alias gaia --- x/bank/alias.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/x/bank/alias.go b/x/bank/alias.go index a0f05ec69a49..4ddeda71f50e 100644 --- a/x/bank/alias.go +++ b/x/bank/alias.go @@ -52,22 +52,22 @@ var ( BalancesPrefix = types.BalancesPrefix AddressFromBalancesStore = types.AddressFromBalancesStore GetGenesisStateFromAppState = types.GetGenesisStateFromAppState - GenesisBalancesIterator = types.GenesisBalancesIterator ) type ( - Keeper = keeper.Keeper - BaseKeeper = keeper.BaseKeeper - SendKeeper = keeper.SendKeeper - BaseSendKeeper = keeper.BaseSendKeeper - ViewKeeper = keeper.ViewKeeper - BaseViewKeeper = keeper.BaseViewKeeper - GenesisState = types.GenesisState - Balance = types.Balance - MsgSend = types.MsgSend - MsgMultiSend = types.MsgMultiSend - Input = types.Input - Output = types.Output - QueryBalanceParams = types.QueryBalanceParams - QueryAllBalancesParams = types.QueryAllBalancesParams + Keeper = keeper.Keeper + BaseKeeper = keeper.BaseKeeper + SendKeeper = keeper.SendKeeper + BaseSendKeeper = keeper.BaseSendKeeper + ViewKeeper = keeper.ViewKeeper + BaseViewKeeper = keeper.BaseViewKeeper + GenesisState = types.GenesisState + Balance = types.Balance + MsgSend = types.MsgSend + MsgMultiSend = types.MsgMultiSend + Input = types.Input + Output = types.Output + QueryBalanceParams = types.QueryBalanceParams + QueryAllBalancesParams = types.QueryAllBalancesParams + GenesisBalancesIterator = types.GenesisBalancesIterator ) From 34e6a875e47e9a2cfd8661bcc5100c5f79d50014 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Thu, 6 Feb 2020 10:44:30 -0800 Subject: [PATCH 074/176] Fix query all clients --- x/bank/alias.go | 1 - x/ibc/02-client/client/utils/utils.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/x/bank/alias.go b/x/bank/alias.go index 4df7479c988c..4ddeda71f50e 100644 --- a/x/bank/alias.go +++ b/x/bank/alias.go @@ -39,7 +39,6 @@ var ( DefaultGenesisState = types.DefaultGenesisState ValidateGenesis = types.ValidateGenesis SanitizeGenesisBalances = types.SanitizeGenesisBalances - GetGenesisStateFromAppState = types.GetGenesisStateFromAppState NewMsgSend = types.NewMsgSend NewMsgMultiSend = types.NewMsgMultiSend NewInput = types.NewInput diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 37e99ec12ff7..297c78c47cd6 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -23,7 +23,7 @@ func QueryAllClientStates(cliCtx context.CLIContext, page, limit int) ([]exporte return nil, 0, fmt.Errorf("failed to marshal query params: %w", err) } - route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAllClients) + route := fmt.Sprintf("custom/%s/%s/%s", "ibc", types.QuerierRoute, types.QueryAllClients) res, height, err := cliCtx.QueryWithData(route, bz) if err != nil { return nil, 0, err From cd6176929a7c8d014c7279559ed79647eb0b8cc5 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Fri, 7 Feb 2020 14:56:18 +0100 Subject: [PATCH 075/176] update to current Tendermint master --- go.mod | 2 ++ go.sum | 9 ++++++--- x/auth/client/query.go | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 6ebb9fdde282..8da3b03deb08 100644 --- a/go.mod +++ b/go.mod @@ -35,4 +35,6 @@ replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alp replace github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 +replace github.com/tendermint/tendermint => github.com/tendermint/tendermint v0.33.0-dev2 + go 1.13 diff --git a/go.sum b/go.sum index 097236eff67f..2f914f4dfd4e 100644 --- a/go.sum +++ b/go.sum @@ -95,6 +95,8 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a 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 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -225,7 +227,6 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -251,8 +252,8 @@ github.com/tendermint/go-amino v0.15.1 h1:D2uk35eT4iTsvJd9jWIetzthE5C0/k2QmMFkCN github.com/tendermint/go-amino v0.15.1/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tendermint/iavl v0.13.0 h1:r2sINvNFlJsLlLhGoqlqPlREWYkuK26BvMfkBt+XQnA= github.com/tendermint/iavl v0.13.0/go.mod h1:7nSUPdrsHEZ2nNZa+9gaIrcJciWd1jCQZXtcyARU82k= -github.com/tendermint/tendermint v0.33.0 h1:TW1g9sQs3YSqKM8o1+opL3/VmBy4Ke/VKV9MxYpqNbI= -github.com/tendermint/tendermint v0.33.0/go.mod h1:s5UoymnPIY+GcA3mMte4P9gpMP8vS7UH7HBXikT1pHI= +github.com/tendermint/tendermint v0.33.0-dev2 h1:rSK0bkfE2emKCKCejhlQ+6DpGjGTU8UGIC5HJlbF94o= +github.com/tendermint/tendermint v0.33.0-dev2/go.mod h1:fBOKyrlXOETqQ+heL8x/TZgSdmItON54csyabvktBp0= github.com/tendermint/tm-db v0.4.0 h1:iPbCcLbf4nwDFhS39Zo1lpdS1X/cT9CkTlUx17FHQgA= github.com/tendermint/tm-db v0.4.0/go.mod h1:+Cwhgowrf7NBGXmsqFMbwEtbo80XmyrlY5Jsk95JubQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -339,6 +340,8 @@ google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.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= 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/x/auth/client/query.go b/x/auth/client/query.go index 3a2c4c44f1b9..abaf7c8b8a46 100644 --- a/x/auth/client/query.go +++ b/x/auth/client/query.go @@ -42,7 +42,7 @@ func QueryTxsByEvents(cliCtx context.CLIContext, events []string, page, limit in prove := !cliCtx.TrustNode - resTxs, err := node.TxSearch(query, prove, page, limit) + resTxs, err := node.TxSearch(query, prove, page, limit, "asc") if err != nil { return nil, err } From 8fd8950496fe13748ccd2c89a153c47646f8c202 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Fri, 7 Feb 2020 16:23:52 +0100 Subject: [PATCH 076/176] TxSearchMock: add orderBy field to TxSearch method --- x/gov/client/utils/query_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/gov/client/utils/query_test.go b/x/gov/client/utils/query_test.go index 10d4e77c7e57..eb4d71e0b061 100644 --- a/x/gov/client/utils/query_test.go +++ b/x/gov/client/utils/query_test.go @@ -21,7 +21,7 @@ type TxSearchMock struct { txs []tmtypes.Tx } -func (mock TxSearchMock) TxSearch(query string, prove bool, page, perPage int) (*ctypes.ResultTxSearch, error) { +func (mock TxSearchMock) TxSearch(query string, prove bool, page, perPage int, orderBy string) (*ctypes.ResultTxSearch, error) { start, end := client.Paginate(len(mock.txs), page, perPage, 100) if start < 0 || end < 0 { // nil result with nil error crashes utils.QueryTxsByEvents From b411199f8da933a54b17772f7da3e3bf309c0ce6 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 11 Feb 2020 10:27:41 -0800 Subject: [PATCH 077/176] fix build errors --- simapp/app.go | 10 ---------- x/ibc/02-client/keeper/keeper.go | 5 ++++- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/simapp/app.go b/simapp/app.go index 3097b5c0b5d4..a5542dd65b68 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -84,16 +84,6 @@ var ( } ) -// MakeCodec custom tx codec -func MakeCodec() *codec.Codec { - var cdc = codec.New() - ModuleBasics.RegisterCodec(cdc) - vesting.RegisterCodec(cdc) - sdk.RegisterCodec(cdc) - codec.RegisterCrypto(cdc) - return cdc -} - // Verify app interface at compile time var _ App = (*SimApp)(nil) diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index c90079077de6..3d0e18fad1c4 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -13,6 +13,7 @@ import ( tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) // Keeper represents a type that grants read and write permissions to any client @@ -103,9 +104,11 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported. return nil, false } + valSet := stakingtypes.Validators(histInfo.Valset) + consensusState := tendermint.ConsensusState{ Root: commitment.NewRoot(histInfo.Header.AppHash), - ValidatorSetHash: tmtypes.NewValidatorSet(histInfo.ValSet.ToTmValidators()).Hash(), + ValidatorSetHash: tmtypes.NewValidatorSet(valSet.ToTmValidators()).Hash(), } return consensusState, true } From c3421663b240ec59030500beb801ee081ee60264 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 11 Feb 2020 13:06:40 -0800 Subject: [PATCH 078/176] Small changes for compilation of gaia --- x/auth/client/query.go | 2 +- x/auth/types/querier.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x/auth/client/query.go b/x/auth/client/query.go index abaf7c8b8a46..3a2c4c44f1b9 100644 --- a/x/auth/client/query.go +++ b/x/auth/client/query.go @@ -42,7 +42,7 @@ func QueryTxsByEvents(cliCtx context.CLIContext, events []string, page, limit in prove := !cliCtx.TrustNode - resTxs, err := node.TxSearch(query, prove, page, limit, "asc") + resTxs, err := node.TxSearch(query, prove, page, limit) if err != nil { return nil, err } diff --git a/x/auth/types/querier.go b/x/auth/types/querier.go index 84a80b1411a4..3b415cbc54d4 100644 --- a/x/auth/types/querier.go +++ b/x/auth/types/querier.go @@ -11,7 +11,7 @@ const ( // QueryAccountParams defines the params for querying accounts. type QueryAccountParams struct { - Address sdk.AccAddress + Address sdk.AccAddress `json:"account"` } // NewQueryAccountParams creates a new instance of QueryAccountParams. From 55d1aeaaa428daa89f3681b6b6346aedb1b60775 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 11 Feb 2020 13:07:30 -0800 Subject: [PATCH 079/176] Small changes for compilation of gaia --- x/auth/client/query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/client/query.go b/x/auth/client/query.go index 3a2c4c44f1b9..abaf7c8b8a46 100644 --- a/x/auth/client/query.go +++ b/x/auth/client/query.go @@ -42,7 +42,7 @@ func QueryTxsByEvents(cliCtx context.CLIContext, events []string, page, limit in prove := !cliCtx.TrustNode - resTxs, err := node.TxSearch(query, prove, page, limit) + resTxs, err := node.TxSearch(query, prove, page, limit, "asc") if err != nil { return nil, err } From 38d87b4a1e8769eb69391c8faeda9e655e6e2ffd Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Thu, 13 Feb 2020 22:04:56 -0800 Subject: [PATCH 080/176] Add 07-tm.Header.ConsensusState() to make conversions easy --- x/ibc/07-tendermint/header.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/x/ibc/07-tendermint/header.go b/x/ibc/07-tendermint/header.go index fb53e36641b8..4a8dbccce4b4 100644 --- a/x/ibc/07-tendermint/header.go +++ b/x/ibc/07-tendermint/header.go @@ -7,6 +7,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) var _ clientexported.Header = Header{} @@ -22,6 +23,14 @@ func (h Header) ClientType() clientexported.ClientType { return clientexported.Tendermint } +// ConsensusState returns the consensus state associated with the header +func (h Header) ConsensusState() ConsensusState { + return ConsensusState{ + Root: commitment.NewRoot(h.AppHash), + ValidatorSetHash: h.ValidatorSet.Hash(), + } +} + // GetHeight returns the current height // // NOTE: also referred as `sequence` From e73cabab9fa657e24e80e502be896cea329ba70b Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 18 Feb 2020 11:36:51 +0000 Subject: [PATCH 081/176] Add additional IBC Channel Tests (#5578) * Add stubbed out tests * one working testcase and mocked packet types * Finish TestSendPacket * Move mocked proofs to ibc/types and finish TestRecvPacket * Implement TestPacketExecuted * WIP TestAckPacket * Start on timeout tests, 1 passing * WIP Tests * first cleanup * test send transfer * add packet tests * fixes and more tests * finish tests * Update x/ibc/04-channel/keeper/packet.go * golangcibot fixes Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Christopher Goes --- x/ibc/03-connection/keeper/handshake_test.go | 35 +- x/ibc/03-connection/keeper/keeper_test.go | 56 --- x/ibc/03-connection/keeper/verify.go | 45 ++- x/ibc/03-connection/keeper/verify_test.go | 53 +-- x/ibc/04-channel/keeper/keeper_test.go | 15 +- x/ibc/04-channel/keeper/packet.go | 20 +- x/ibc/04-channel/keeper/packet_test.go | 391 +++++++++++++++++++ x/ibc/04-channel/keeper/timeout.go | 6 +- x/ibc/04-channel/keeper/timeout_test.go | 235 +++++++++++ x/ibc/ante/ante.go | 2 +- x/ibc/types/mock.go | 62 +++ 11 files changed, 786 insertions(+), 134 deletions(-) create mode 100644 x/ibc/04-channel/keeper/packet_test.go create mode 100644 x/ibc/04-channel/keeper/timeout_test.go create mode 100644 x/ibc/types/mock.go diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index 3023cb5c4e20..133349195c4e 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -6,6 +6,7 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // TestConnOpenInit - Chain A (ID #1) initializes (INIT state) a connection with @@ -57,7 +58,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { malleate func() expPass bool }{ - {"success", validProof{}, validProof{}, func() { + {"success", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { suite.createClient(testClientID1) // height = 2 suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) proofHeight = suite.ctx.BlockHeight() @@ -66,21 +67,21 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.updateClient(testClientID1) suite.updateClient(testClientID2) }, true}, - {"consensus height > latest height", validProof{}, validProof{}, func() { + {"consensus height > latest height", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { consensusHeight = 100 }, false}, - {"self consensus state not found", validProof{}, validProof{}, func() { + {"self consensus state not found", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { consensusHeight = 100 suite.ctx = suite.ctx.WithBlockHeight(100) }, false}, - {"connection state verification invalid", invalidProof{}, validProof{}, func() { + {"connection state verification invalid", ibctypes.InvalidProof{}, ibctypes.ValidProof{}, func() { suite.createClient(testClientID1) suite.createClient(testClientID2) consensusHeight = suite.ctx.BlockHeight() suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.UNINITIALIZED) suite.updateClient(testClientID1) }, false}, - {"consensus state verification invalid", validProof{}, invalidProof{}, func() { + {"consensus state verification invalid", ibctypes.ValidProof{}, ibctypes.InvalidProof{}, func() { suite.createClient(testClientID1) // height = 2 suite.createClient(testClientID2) consensusHeight = suite.ctx.BlockHeight() @@ -88,7 +89,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.updateClient(testClientID1) suite.updateClient(testClientID2) }, false}, - {"invalid previous connection", validProof{}, validProof{}, func() { + {"invalid previous connection", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { suite.createClient(testClientID1) // height = 2 suite.createClient(testClientID2) consensusHeight = suite.ctx.BlockHeight() @@ -96,7 +97,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.updateClient(testClientID1) suite.updateClient(testClientID2) }, false}, - {"couldn't add connection to client", validProof{}, validProof{}, func() { + {"couldn't add connection to client", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { suite.createClient(testClientID1) // height = 2 consensusHeight = suite.ctx.BlockHeight() suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) @@ -151,7 +152,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { malleate func() expPass bool }{ - {"success", version, validProof{}, validProof{}, func() { + {"success", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { suite.createClient(testClientID2) suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) proofHeight = suite.ctx.BlockHeight() @@ -161,21 +162,21 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { suite.updateClient(testClientID1) suite.updateClient(testClientID2) }, true}, - {"consensus height > latest height", version, validProof{}, validProof{}, func() { + {"consensus height > latest height", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { consensusHeight = 100 }, false}, - {"connection not found", version, validProof{}, validProof{}, func() { + {"connection not found", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { consensusHeight = suite.ctx.BlockHeight() }, false}, - {"connection state is not INIT", version, validProof{}, validProof{}, func() { + {"connection state is not INIT", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.UNINITIALIZED) suite.updateClient(testClientID1) }, false}, - {"incompatible IBC versions", "2.0", validProof{}, validProof{}, func() { + {"incompatible IBC versions", "2.0", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) suite.updateClient(testClientID1) }, false}, - {"self consensus state not found", version, validProof{}, validProof{}, func() { + {"self consensus state not found", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { suite.createClient(testClientID1) suite.createClient(testClientID2) suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) @@ -184,7 +185,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { consensusHeight = 100 suite.ctx = suite.ctx.WithBlockHeight(100) }, false}, - {"connection state verification failed", version, invalidProof{}, validProof{}, func() { + {"connection state verification failed", version, ibctypes.InvalidProof{}, ibctypes.ValidProof{}, func() { suite.createClient(testClientID1) consensusHeight = suite.ctx.BlockHeight() suite.createClient(testClientID2) @@ -192,7 +193,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) suite.updateClient(testClientID1) }, false}, - {"consensus state verification failed", version, validProof{}, invalidProof{}, func() { + {"consensus state verification failed", version, ibctypes.ValidProof{}, ibctypes.InvalidProof{}, func() { suite.createClient(testClientID1) consensusHeight = suite.ctx.BlockHeight() suite.createClient(testClientID2) @@ -275,12 +276,12 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { if tc.expPass { err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( - suite.ctx, testConnectionID2, validProof{}, uint64(proofHeight), + suite.ctx, testConnectionID2, ibctypes.ValidProof{}, uint64(proofHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( - suite.ctx, testConnectionID2, invalidProof{}, uint64(proofHeight), + suite.ctx, testConnectionID2, ibctypes.InvalidProof{}, uint64(proofHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 97f6b3563716..72ef41d6bb83 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -1,7 +1,6 @@ package keeper_test import ( - "errors" "fmt" "math/rand" "testing" @@ -230,58 +229,3 @@ func (suite KeeperTestSuite) TestGetAllConnections() { suite.Require().Len(connections, len(expConnections)) suite.Require().ElementsMatch(expConnections, connections) } - -// Mocked types -// TODO: fix tests and replace for real proofs - -var ( - _ commitment.ProofI = validProof{} - _ commitment.ProofI = invalidProof{} -) - -type ( - validProof struct{} - invalidProof struct{} -) - -func (validProof) GetCommitmentType() commitment.Type { - return commitment.Merkle -} - -func (validProof) VerifyMembership( - root commitment.RootI, path commitment.PathI, value []byte) error { - return nil -} - -func (validProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { - return nil -} - -func (validProof) ValidateBasic() error { - return nil -} - -func (validProof) IsEmpty() bool { - return false -} - -func (invalidProof) GetCommitmentType() commitment.Type { - return commitment.Merkle -} - -func (invalidProof) VerifyMembership( - root commitment.RootI, path commitment.PathI, value []byte) error { - return errors.New("proof failed") -} - -func (invalidProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { - return errors.New("proof failed") -} - -func (invalidProof) ValidateBasic() error { - return errors.New("invalid proof") -} - -func (invalidProof) IsEmpty() bool { - return true -} diff --git a/x/ibc/03-connection/keeper/verify.go b/x/ibc/03-connection/keeper/verify.go index f990d0b5e5bf..e9264746a1d0 100644 --- a/x/ibc/03-connection/keeper/verify.go +++ b/x/ibc/03-connection/keeper/verify.go @@ -2,6 +2,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" @@ -20,7 +21,7 @@ func (k Keeper) VerifyClientConsensusState( ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { - return clienttypes.ErrClientNotFound + return sdkerrors.Wrap(clienttypes.ErrClientNotFound, connection.GetClientID()) } return clientState.VerifyClientConsensusState( @@ -40,7 +41,7 @@ func (k Keeper) VerifyConnectionState( ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { - return clienttypes.ErrClientNotFound + return sdkerrors.Wrap(clienttypes.ErrClientNotFound, connection.GetClientID()) } // TODO: move to specific clients; blocked by #5502 @@ -48,7 +49,10 @@ func (k Keeper) VerifyConnectionState( ctx, connectionEnd.GetClientID(), height, ) if !found { - return clienttypes.ErrConsensusStateNotFound + return sdkerrors.Wrapf( + clienttypes.ErrConsensusStateNotFound, + "clientID (%s), height (%d)", connectionEnd.GetClientID(), height, + ) } return clientState.VerifyConnectionState( @@ -69,7 +73,7 @@ func (k Keeper) VerifyChannelState( ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { - return clienttypes.ErrClientNotFound + return sdkerrors.Wrap(clienttypes.ErrClientNotFound, connection.GetClientID()) } // TODO: move to specific clients; blocked by #5502 @@ -77,7 +81,10 @@ func (k Keeper) VerifyChannelState( ctx, connection.GetClientID(), height, ) if !found { - return clienttypes.ErrConsensusStateNotFound + return sdkerrors.Wrapf( + clienttypes.ErrConsensusStateNotFound, + "clientID (%s), height (%d)", connection.GetClientID(), height, + ) } return clientState.VerifyChannelState( @@ -100,7 +107,7 @@ func (k Keeper) VerifyPacketCommitment( ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { - return clienttypes.ErrClientNotFound + return sdkerrors.Wrap(clienttypes.ErrClientNotFound, connection.GetClientID()) } // TODO: move to specific clients; blocked by #5502 @@ -108,7 +115,10 @@ func (k Keeper) VerifyPacketCommitment( ctx, connection.GetClientID(), height, ) if !found { - return clienttypes.ErrConsensusStateNotFound + return sdkerrors.Wrapf( + clienttypes.ErrConsensusStateNotFound, + "clientID (%s), height (%d)", connection.GetClientID(), height, + ) } return clientState.VerifyPacketCommitment( @@ -131,7 +141,7 @@ func (k Keeper) VerifyPacketAcknowledgement( ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { - return clienttypes.ErrClientNotFound + return sdkerrors.Wrap(clienttypes.ErrClientNotFound, connection.GetClientID()) } // TODO: move to specific clients; blocked by #5502 @@ -139,7 +149,10 @@ func (k Keeper) VerifyPacketAcknowledgement( ctx, connection.GetClientID(), height, ) if !found { - return clienttypes.ErrConsensusStateNotFound + return sdkerrors.Wrapf( + clienttypes.ErrConsensusStateNotFound, + "clientID (%s), height (%d)", connection.GetClientID(), height, + ) } return clientState.VerifyPacketAcknowledgement( @@ -162,7 +175,7 @@ func (k Keeper) VerifyPacketAcknowledgementAbsence( ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { - return clienttypes.ErrClientNotFound + return sdkerrors.Wrap(clienttypes.ErrClientNotFound, connection.GetClientID()) } // TODO: move to specific clients; blocked by #5502 @@ -170,7 +183,10 @@ func (k Keeper) VerifyPacketAcknowledgementAbsence( ctx, connection.GetClientID(), height, ) if !found { - return clienttypes.ErrConsensusStateNotFound + return sdkerrors.Wrapf( + clienttypes.ErrConsensusStateNotFound, + "clientID (%s), height (%d)", connection.GetClientID(), height, + ) } return clientState.VerifyPacketAcknowledgementAbsence( @@ -192,7 +208,7 @@ func (k Keeper) VerifyNextSequenceRecv( ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { - return clienttypes.ErrClientNotFound + return sdkerrors.Wrap(clienttypes.ErrClientNotFound, connection.GetClientID()) } // TODO: move to specific clients; blocked by #5502 @@ -200,7 +216,10 @@ func (k Keeper) VerifyNextSequenceRecv( ctx, connection.GetClientID(), height, ) if !found { - return clienttypes.ErrConsensusStateNotFound + return sdkerrors.Wrapf( + clienttypes.ErrConsensusStateNotFound, + "clientID (%s), height (%d)", connection.GetClientID(), height, + ) } return clientState.VerifyNextSequenceRecv( diff --git a/x/ibc/03-connection/keeper/verify_test.go b/x/ibc/03-connection/keeper/verify_test.go index 614929666543..536f3f6ea050 100644 --- a/x/ibc/03-connection/keeper/verify_test.go +++ b/x/ibc/03-connection/keeper/verify_test.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) const ( @@ -35,11 +36,11 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { malleate func() expPass bool }{ - {"verification success", connection1, validProof{}, func() { + {"verification success", connection1, ibctypes.ValidProof{}, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", connection1, validProof{}, func() {}, false}, - {"verification failed", connection1, invalidProof{}, func() { + {"client state not found", connection1, ibctypes.ValidProof{}, func() {}, false}, + {"verification failed", connection1, ibctypes.InvalidProof{}, func() { suite.createClient(testClientID2) }, false}, } @@ -78,12 +79,12 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { malleate func() expPass bool }{ - {"verification success", validProof{}, func() { + {"verification success", ibctypes.ValidProof{}, func() { suite.createClient(testClientID1) suite.createClient(testClientID2) }, true}, - {"client state not found", validProof{}, func() {}, false}, - {"verification failed", invalidProof{}, func() { + {"client state not found", ibctypes.ValidProof{}, func() {}, false}, + {"verification failed", ibctypes.InvalidProof{}, func() { suite.createClient(testClientID1) suite.createClient(testClientID2) }, false}, @@ -125,14 +126,14 @@ func (suite *KeeperTestSuite) TestVerifyChannelState() { malleate func() expPass bool }{ - {"verification success", validProof{}, 2, func() { + {"verification success", ibctypes.ValidProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", validProof{}, 2, func() {}, false}, - {"consensus state not found", validProof{}, 100, func() { + {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, + {"consensus state not found", ibctypes.ValidProof{}, 100, func() { suite.createClient(testClientID1) }, false}, - {"verification failed", invalidProof{}, 2, func() { + {"verification failed", ibctypes.InvalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } @@ -176,14 +177,14 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { malleate func() expPass bool }{ - {"verification success", validProof{}, 2, func() { + {"verification success", ibctypes.ValidProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", validProof{}, 2, func() {}, false}, - {"consensus state not found", validProof{}, 100, func() { + {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, + {"consensus state not found", ibctypes.ValidProof{}, 100, func() { suite.createClient(testClientID1) }, false}, - {"verification failed", invalidProof{}, 2, func() { + {"verification failed", ibctypes.InvalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } @@ -224,14 +225,14 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { malleate func() expPass bool }{ - {"verification success", validProof{}, 2, func() { + {"verification success", ibctypes.ValidProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", validProof{}, 2, func() {}, false}, - {"consensus state not found", validProof{}, 100, func() { + {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, + {"consensus state not found", ibctypes.ValidProof{}, 100, func() { suite.createClient(testClientID1) }, false}, - {"verification failed", invalidProof{}, 2, func() { + {"verification failed", ibctypes.InvalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } @@ -271,14 +272,14 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { malleate func() expPass bool }{ - {"verification success", validProof{}, 2, func() { + {"verification success", ibctypes.ValidProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", validProof{}, 2, func() {}, false}, - {"consensus state not found", validProof{}, 100, func() { + {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, + {"consensus state not found", ibctypes.ValidProof{}, 100, func() { suite.createClient(testClientID1) }, false}, - {"verification failed", invalidProof{}, 2, func() { + {"verification failed", ibctypes.InvalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } @@ -318,14 +319,14 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { malleate func() expPass bool }{ - {"verification success", validProof{}, 2, func() { + {"verification success", ibctypes.ValidProof{}, 2, func() { suite.createClient(testClientID1) }, true}, - {"client state not found", validProof{}, 2, func() {}, false}, - {"consensus state not found", validProof{}, 100, func() { + {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, + {"consensus state not found", ibctypes.ValidProof{}, 100, func() { suite.createClient(testClientID1) }, false}, - {"verification failed", invalidProof{}, 2, func() { + {"verification failed", ibctypes.InvalidProof{}, 2, func() { suite.createClient(testClientID2) }, false}, } diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index 68423fefb7a3..5826f272bd9e 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -192,13 +192,18 @@ func TestKeeperTestSuite(t *testing.T) { suite.Run(t, new(KeeperTestSuite)) } -func (suite *KeeperTestSuite) createClient(clientID string) { - suite.app.Commit() - commitID := suite.app.LastCommitID() +func (suite *KeeperTestSuite) commitNBlocks(n int) { + for i := 0; i < n; i++ { + suite.app.Commit() + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{Height: suite.app.LastBlockHeight()}) + } +} - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{Height: suite.app.LastBlockHeight()}) +func (suite *KeeperTestSuite) createClient(clientID string) { + suite.commitNBlocks(1) + commitID := suite.app.LastCommitID() consensusState := tendermint.ConsensusState{ Root: commitment.NewRoot(commitID.Hash), ValidatorSetHash: suite.valSet.Hash(), diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index c56d993215f1..0ba1186ccd4a 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -231,7 +231,7 @@ func (k Keeper) PacketExecuted( func (k Keeper) AcknowledgePacket( ctx sdk.Context, packet exported.PacketI, - acknowledgement exported.PacketDataI, + acknowledgement []byte, proof commitment.ProofI, proofHeight uint64, ) (exported.PacketI, error) { @@ -250,18 +250,18 @@ func (k Keeper) AcknowledgePacket( // NOTE: RecvPacket is called by the AnteHandler which acts upon the packet.Route(), // so the capability authentication can be omitted here - // packet must come from the channel's counterparty - if packet.GetSourcePort() != channel.Counterparty.PortID { + // packet must have been sent to the channel's counterparty + if packet.GetDestPort() != channel.Counterparty.PortID { return nil, sdkerrors.Wrapf( types.ErrInvalidPacket, - "packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortID, + "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortID, ) } - if packet.GetSourceChannel() != channel.Counterparty.ChannelID { + if packet.GetDestChannel() != channel.Counterparty.ChannelID { return nil, sdkerrors.Wrapf( types.ErrInvalidPacket, - "packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelID, + "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelID, ) } @@ -286,7 +286,7 @@ func (k Keeper) AcknowledgePacket( if err := k.connectionKeeper.VerifyPacketAcknowledgement( ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), - packet.GetSequence(), acknowledgement.GetBytes(), + packet.GetSequence(), acknowledgement, ); err != nil { return nil, sdkerrors.Wrap(err, "invalid acknowledgement on counterparty chain") } @@ -294,12 +294,6 @@ func (k Keeper) AcknowledgePacket( return packet, nil } -// AcknowledgementExecuted deletes the commitment send from this chain after it receives the acknowlegement -// CONTRACT: each acknowledgement handler function should call WriteAcknowledgement at the end of the execution -func (k Keeper) AcknowledgementExecuted(ctx sdk.Context, packet exported.PacketI) { - k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) -} - // CleanupPacket is called by a module to remove a received packet commitment // from storage. The receiving end must have already processed the packet // (whether regularly or past timeout). diff --git a/x/ibc/04-channel/keeper/packet_test.go b/x/ibc/04-channel/keeper/packet_test.go new file mode 100644 index 000000000000..e8901ec1c4e4 --- /dev/null +++ b/x/ibc/04-channel/keeper/packet_test.go @@ -0,0 +1,391 @@ +package keeper_test + +import ( + "fmt" + + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +func (suite *KeeperTestSuite) TestSendPacket() { + counterparty := types.NewCounterparty(testPort2, testChannel2) + var packet exported.PacketI + + testCases := []testCase{ + {"success", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + }, true}, + {"packet basic validation failed", func() { + packet = types.NewPacket(mockFailPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + }, false}, + {"channel not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + }, false}, + {"channel closed", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionID1) + }, false}, + {"packet dest port ≠ channel counterparty port", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, testPort3, counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet dest channel ID ≠ channel counterparty channel ID", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), testChannel3) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection is UNINITIALIZED", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.UNINITIALIZED) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"client state not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"timeout height passed", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.commitNBlocks(10) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"next sequence send not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"next sequence wrong", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 5) + }, false}, + } + + for i, tc := range testCases { + tc := tc + suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { + suite.SetupTest() // reset + tc.malleate() + + err := suite.app.IBCKeeper.ChannelKeeper.SendPacket(suite.ctx, packet) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } + +} + +func (suite *KeeperTestSuite) TestRecvPacket() { + counterparty := types.NewCounterparty(testPort2, testChannel2) + var packet exported.PacketI + + testCases := []testCase{ + {"success", func() { + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.updateClient() + }, true}, + {"channel not found", func() {}, false}, + {"channel not open", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.INIT, exported.ORDERED, testConnectionID1) + }, false}, + {"packet source port ≠ channel counterparty port", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort2, testChannel2, testPort3, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet source channel ID ≠ channel counterparty channel ID", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection not OPEN", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.INIT) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"timeout passed", func() { + suite.commitNBlocks(10) + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"validation failed", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + } + + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { + suite.SetupTest() // reset + tc.malleate() + + var err error + if tc.expPass { + packet, err = suite.app.IBCKeeper.ChannelKeeper.RecvPacket(suite.ctx, packet, ibctypes.ValidProof{}, uint64(suite.ctx.BlockHeader().Height)) + suite.Require().NoError(err) + } else { + packet, err = suite.app.IBCKeeper.ChannelKeeper.RecvPacket(suite.ctx, packet, ibctypes.InvalidProof{}, uint64(suite.ctx.BlockHeader().Height)) + suite.Require().Error(err) + } + }) + } + +} + +func (suite *KeeperTestSuite) TestPacketExecuted() { + counterparty := types.NewCounterparty(testPort2, testChannel2) + var packet types.Packet + + testCases := []testCase{ + {"success: UNORDERED", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.UNORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort2, testChannel2, 1) + }, true}, + {"success: ORDERED", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort2, testChannel2, 1) + }, true}, + {"channel not found", func() {}, false}, + {"channel not OPEN", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.CLOSED, exported.ORDERED, testConnectionID1) + }, false}, + {"next sequence receive not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet sequence ≠ next sequence receive", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort2, testChannel2, 5) + }, false}, + } + + for i, tc := range testCases { + tc := tc + suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { + suite.SetupTest() // reset + tc.malleate() + + err := suite.app.IBCKeeper.ChannelKeeper.PacketExecuted(suite.ctx, packet, mockSuccessPacket{}) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestAcknowledgePacket() { + counterparty := types.NewCounterparty(testPort2, testChannel2) + var packet types.Packet + + ack := []byte("ack") + + testCases := []testCase{ + {"success", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + }, true}, + {"channel not found", func() {}, false}, + {"channel not open", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionID1) + }, false}, + {"packet source port ≠ channel counterparty port", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet source channel ID ≠ channel counterparty channel ID", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection not OPEN", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.INIT) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet hasn't been sent", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet ack verification failed", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + }, false}, + } + + for i, tc := range testCases { + tc := tc + suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { + suite.SetupTest() // reset + tc.malleate() + + if tc.expPass { + packetOut, err := suite.app.IBCKeeper.ChannelKeeper.AcknowledgePacket(suite.ctx, packet, ack, ibctypes.ValidProof{}, uint64(suite.ctx.BlockHeader().Height)) + suite.Require().NoError(err) + suite.Require().NotNil(packetOut) + } else { + packetOut, err := suite.app.IBCKeeper.ChannelKeeper.AcknowledgePacket(suite.ctx, packet, ack, ibctypes.InvalidProof{}, uint64(suite.ctx.BlockHeader().Height)) + suite.Require().Error(err) + suite.Require().Nil(packetOut) + } + }) + } +} + +func (suite *KeeperTestSuite) TestCleanupPacket() { + counterparty := types.NewCounterparty(testPort2, testChannel2) + var ( + packet types.Packet + nextSeqRecv uint64 + ) + + ack := []byte("ack") + + testCases := []testCase{ + {"success", func() { + nextSeqRecv = 10 + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + }, true}, + {"channel not found", func() {}, false}, + {"channel not open", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionID1) + }, false}, + {"packet source port ≠ channel counterparty port", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet source channel ID ≠ channel counterparty channel ID", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection not OPEN", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.INIT) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet already received ", func() { + packet = types.NewPacket(mockSuccessPacket{}, 10, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet hasn't been sent", func() { + nextSeqRecv = 10 + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"next seq receive verification failed", func() { + nextSeqRecv = 10 + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + }, false}, + {"packet ack verification failed", func() { + nextSeqRecv = 10 + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + }, false}, + } + + for i, tc := range testCases { + tc := tc + suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { + suite.SetupTest() // reset + tc.malleate() + + if tc.expPass { + packetOut, err := suite.app.IBCKeeper.ChannelKeeper.CleanupPacket(suite.ctx, packet, ibctypes.ValidProof{}, uint64(suite.ctx.BlockHeader().Height), nextSeqRecv, ack) + suite.Require().NoError(err) + suite.Require().NotNil(packetOut) + } else { + packetOut, err := suite.app.IBCKeeper.ChannelKeeper.CleanupPacket(suite.ctx, packet, ibctypes.InvalidProof{}, uint64(suite.ctx.BlockHeader().Height), nextSeqRecv, ack) + suite.Require().Error(err) + suite.Require().Nil(packetOut) + } + }) + } +} + +type mockSuccessPacket struct{} + +// GetBytes returns the serialised packet data (without timeout) +func (mp mockSuccessPacket) GetBytes() []byte { return []byte("THIS IS A SUCCESS PACKET") } + +// GetTimeoutHeight returns the timeout height defined specifically for each packet data type instance +func (mp mockSuccessPacket) GetTimeoutHeight() uint64 { return 10 } + +// ValidateBasic validates basic properties of the packet data, implements sdk.Msg +func (mp mockSuccessPacket) ValidateBasic() error { return nil } + +// Type returns human readable identifier, implements sdk.Msg +func (mp mockSuccessPacket) Type() string { return "mock/packet/success" } + +type mockFailPacket struct{} + +// GetBytes returns the serialised packet data (without timeout) +func (mp mockFailPacket) GetBytes() []byte { return []byte("THIS IS A FAILURE PACKET") } + +// GetTimeoutHeight returns the timeout height defined specifically for each packet data type instance +func (mp mockFailPacket) GetTimeoutHeight() uint64 { return 10000 } + +// ValidateBasic validates basic properties of the packet data, implements sdk.Msg +func (mp mockFailPacket) ValidateBasic() error { return fmt.Errorf("Packet failed validate basic") } + +// Type returns human readable identifier, implements sdk.Msg +func (mp mockFailPacket) Type() string { return "mock/packet/failure" } diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index 72a4afec52dc..1989722130b2 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -134,7 +134,7 @@ func (k Keeper) TimeoutExecuted(ctx sdk.Context, packet exported.PacketI) error func (k Keeper) TimeoutOnClose( ctx sdk.Context, packet types.Packet, - proofNonMembership, + proof, proofClosed commitment.ProofI, proofHeight, nextSequenceRecv uint64, @@ -207,12 +207,12 @@ func (k Keeper) TimeoutOnClose( case exported.ORDERED: // check that the recv sequence is as claimed err = k.connectionKeeper.VerifyNextSequenceRecv( - ctx, connectionEnd, proofHeight, proofClosed, + ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv, ) case exported.UNORDERED: err = k.connectionKeeper.VerifyPacketAcknowledgementAbsence( - ctx, connectionEnd, proofHeight, proofClosed, + ctx, connectionEnd, proofHeight, proof, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), ) default: diff --git a/x/ibc/04-channel/keeper/timeout_test.go b/x/ibc/04-channel/keeper/timeout_test.go new file mode 100644 index 000000000000..be60e39f1e75 --- /dev/null +++ b/x/ibc/04-channel/keeper/timeout_test.go @@ -0,0 +1,235 @@ +package keeper_test + +import ( + "fmt" + + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" +) + +func (suite *KeeperTestSuite) TestTimeoutPacket() { + counterparty := types.NewCounterparty(testPort2, testChannel2) + var ( + packet types.Packet + nextSeqRecv uint64 + proofHeight uint64 = 3 + ) + + testCases := []testCase{ + {"success", func() { + nextSeqRecv = 1 + proofHeight = 1 + packet = types.NewPacket(newMockTimeoutPacket(1), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + }, true}, + {"channel not found", func() {}, false}, + {"channel not open", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionID1) + }, false}, + {"packet source port ≠ channel counterparty port", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet source channel ID ≠ channel counterparty channel ID", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"timeout", func() { + proofHeight = 1 + packet = types.NewPacket(mockSuccessPacket{}, 10, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet already received ", func() { + nextSeqRecv = 2 + proofHeight = 100 + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet hasn't been sent", func() { + nextSeqRecv = 1 + proofHeight = 100 + packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"next seq receive verification failed", func() { + nextSeqRecv = 1 + proofHeight = 100 + packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + }, false}, + {"packet ack verification failed", func() { + nextSeqRecv = 1 + proofHeight = 100 + packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + }, false}, + } + + for i, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { + suite.SetupTest() // reset + tc.malleate() + + if tc.expPass { + packetOut, err := suite.app.IBCKeeper.ChannelKeeper.TimeoutPacket(suite.ctx, packet, ibctypes.ValidProof{}, proofHeight, nextSeqRecv) + suite.Require().NoError(err) + suite.Require().NotNil(packetOut) + } else { + packetOut, err := suite.app.IBCKeeper.ChannelKeeper.TimeoutPacket(suite.ctx, packet, ibctypes.InvalidProof{}, proofHeight, nextSeqRecv) + suite.Require().Error(err) + suite.Require().Nil(packetOut) + } + }) + } +} + +func (suite *KeeperTestSuite) TestTimeoutExecuted() { + var packet types.Packet + + testCases := []testCase{ + {"success ORDERED", func() { + packet = types.NewPacket(newMockTimeoutPacket(3), 1, testPort1, testChannel1, testPort2, testChannel2) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, true}, + {"channel not found", func() {}, false}, + } + + for i, tc := range testCases { + tc := tc + suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { + suite.SetupTest() // reset + tc.malleate() + + err := suite.app.IBCKeeper.ChannelKeeper.TimeoutExecuted(suite.ctx, packet) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestTimeoutOnClose() { + counterparty := types.NewCounterparty(testPort2, testChannel2) + var ( + packet types.Packet + nextSeqRecv uint64 + proofHeight uint64 = 1 + proof commitment.ProofI = ibctypes.InvalidProof{} + proofClosed commitment.ProofI = ibctypes.InvalidProof{} + ) + + testCases := []testCase{ + {"success", func() { + packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + }, true}, + {"channel not found", func() {}, false}, + {"packet dest port ≠ channel counterparty port", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet dest channel ID ≠ channel counterparty channel ID", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"connection not found", func() { + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"packet hasn't been sent", func() { + packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + }, false}, + {"channel verification failed", func() { + packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + }, false}, + {"next seq receive verification failed", func() { + proofClosed = ibctypes.ValidProof{} + packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + }, false}, + {"packet ack verification failed", func() { + proofClosed = ibctypes.ValidProof{} + packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.createClient(testClientID1) + suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) + suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) + suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + }, false}, + } + + for i, tc := range testCases { + tc := tc + suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { + suite.SetupTest() // reset + tc.malleate() + + if tc.expPass { + packetOut, err := suite.app.IBCKeeper.ChannelKeeper.TimeoutOnClose(suite.ctx, packet, ibctypes.ValidProof{}, ibctypes.ValidProof{}, proofHeight, nextSeqRecv) + suite.Require().NoError(err) + suite.Require().NotNil(packetOut) + } else { + packetOut, err := suite.app.IBCKeeper.ChannelKeeper.TimeoutOnClose(suite.ctx, packet, proof, proofClosed, proofHeight, nextSeqRecv) + suite.Require().Error(err) + suite.Require().Nil(packetOut) + } + }) + } + +} + +type mockTimeoutPacket struct { + timeoutHeight uint64 +} + +func newMockTimeoutPacket(timeoutHeight uint64) mockTimeoutPacket { + return mockTimeoutPacket{timeoutHeight} +} + +// GetBytes returns the serialised packet data (without timeout) +func (mp mockTimeoutPacket) GetBytes() []byte { return []byte("THIS IS A TIMEOUT PACKET") } + +// GetTimeoutHeight returns the timeout height defined specifically for each packet data type instance +func (mp mockTimeoutPacket) GetTimeoutHeight() uint64 { return mp.timeoutHeight } + +// ValidateBasic validates basic properties of the packet data, implements sdk.Msg +func (mp mockTimeoutPacket) ValidateBasic() error { return nil } + +// Type returns human readable identifier, implements sdk.Msg +func (mp mockTimeoutPacket) Type() string { return "mock/packet/success" } diff --git a/x/ibc/ante/ante.go b/x/ibc/ante/ante.go index 1873c2edf612..7895c2655279 100644 --- a/x/ibc/ante/ante.go +++ b/x/ibc/ante/ante.go @@ -33,7 +33,7 @@ func (pvr ProofVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim case channel.MsgPacket: _, err = pvr.channelKeeper.RecvPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight) case channel.MsgAcknowledgement: - _, err = pvr.channelKeeper.AcknowledgePacket(ctx, msg.Packet, msg.Acknowledgement, msg.Proof, msg.ProofHeight) + _, err = pvr.channelKeeper.AcknowledgePacket(ctx, msg.Packet, msg.Acknowledgement.GetBytes(), msg.Proof, msg.ProofHeight) case channel.MsgTimeout: _, err = pvr.channelKeeper.TimeoutPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight, msg.NextSequenceRecv) } diff --git a/x/ibc/types/mock.go b/x/ibc/types/mock.go new file mode 100644 index 000000000000..ebc307a3129a --- /dev/null +++ b/x/ibc/types/mock.go @@ -0,0 +1,62 @@ +package types + +import ( + "errors" + + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +// Mocked types +// TODO: fix tests and replace for real proofs + +var ( + _ commitment.ProofI = ValidProof{} + _ commitment.ProofI = InvalidProof{} +) + +type ( + ValidProof struct{} + InvalidProof struct{} +) + +func (ValidProof) GetCommitmentType() commitment.Type { + return commitment.Merkle +} + +func (ValidProof) VerifyMembership( + root commitment.RootI, path commitment.PathI, value []byte) error { + return nil +} + +func (ValidProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { + return nil +} + +func (ValidProof) ValidateBasic() error { + return nil +} + +func (ValidProof) IsEmpty() bool { + return false +} + +func (InvalidProof) GetCommitmentType() commitment.Type { + return commitment.Merkle +} + +func (InvalidProof) VerifyMembership( + root commitment.RootI, path commitment.PathI, value []byte) error { + return errors.New("proof failed") +} + +func (InvalidProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { + return errors.New("proof failed") +} + +func (InvalidProof) ValidateBasic() error { + return errors.New("invalid proof") +} + +func (InvalidProof) IsEmpty() bool { + return true +} From 5875a962daf02d471da8d5bb0447b6ab50051c8b Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 18 Feb 2020 14:46:53 +0100 Subject: [PATCH 082/176] merge master --- x/ibc/02-client/client/rest/swagger.go | 22 +++++++++--------- x/ibc/03-connection/client/cli/tx.go | 10 ++++----- x/ibc/03-connection/client/rest/swagger.go | 18 +++++++-------- x/ibc/04-channel/client/cli/tx.go | 14 ++++++------ x/ibc/04-channel/client/rest/swagger.go | 26 +++++++++++----------- x/ibc/20-transfer/client/cli/tx.go | 4 ++-- x/ibc/20-transfer/client/rest/swagger.go | 10 ++++----- x/ibc/20-transfer/module.go | 13 ++++++----- x/ibc/ante/ante_test.go | 4 ++-- x/ibc/module.go | 8 +++---- 10 files changed, 66 insertions(+), 63 deletions(-) diff --git a/x/ibc/02-client/client/rest/swagger.go b/x/ibc/02-client/client/rest/swagger.go index 42809a112192..0b3fbc53d2f4 100644 --- a/x/ibc/02-client/client/rest/swagger.go +++ b/x/ibc/02-client/client/rest/swagger.go @@ -1,7 +1,7 @@ package rest import ( - auth "github.com/cosmos/cosmos-sdk/x/auth" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/evidence" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" @@ -36,23 +36,23 @@ type ( } PostCreateClient struct { - Msgs []types.MsgCreateClient `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` + Msgs []types.MsgCreateClient `json:"msg" yaml:"msg"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` } PostUpdateClient struct { - Msgs []types.MsgUpdateClient `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` + Msgs []types.MsgUpdateClient `json:"msg" yaml:"msg"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` } PostSubmitMisbehaviour struct { Msgs []evidence.MsgSubmitEvidence `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } ) diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 5fbfc2d2a6fb..9a02faa374a9 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -13,7 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/auth" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" @@ -46,7 +46,7 @@ $ %s tx ibc connection open-init [connection-id] [client-id] \ Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] @@ -94,7 +94,7 @@ $ %s tx ibc connection open-try connection-id] [client-id] \ Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) @@ -155,7 +155,7 @@ $ %s tx ibc connection open-ack [connection-id] [path/to/proof_try.json] [versio Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) connectionID := args[0] @@ -204,7 +204,7 @@ $ %s tx ibc connection open-confirm [connection-id] [path/to/proof_ack.json] Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf). WithCodec(cdc). WithHeight(viper.GetInt64(flags.FlagHeight)) diff --git a/x/ibc/03-connection/client/rest/swagger.go b/x/ibc/03-connection/client/rest/swagger.go index c8620ba41d6a..bc12e73985d3 100644 --- a/x/ibc/03-connection/client/rest/swagger.go +++ b/x/ibc/03-connection/client/rest/swagger.go @@ -1,7 +1,7 @@ package rest import ( - auth "github.com/cosmos/cosmos-sdk/x/auth" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) @@ -18,29 +18,29 @@ type ( PostConnectionOpenInit struct { Msgs []types.MsgConnectionOpenInit `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostConnectionOpenTry struct { Msgs []types.MsgConnectionOpenTry `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostConnectionOpenAck struct { Msgs []types.MsgConnectionOpenAck `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostConnectionOpenConfirm struct { Msgs []types.MsgConnectionOpenConfirm `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } ) diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index 521e181a68df..3241eb780f39 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" connectionutils "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" @@ -32,7 +32,7 @@ func GetMsgChannelOpenInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -69,7 +69,7 @@ func GetMsgChannelOpenTryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -116,7 +116,7 @@ func GetMsgChannelOpenAckCmd(storeKey string, cdc *codec.Codec) *cobra.Command { Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -155,7 +155,7 @@ func GetMsgChannelOpenConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comma Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -191,7 +191,7 @@ func GetMsgChannelCloseInitCmd(storeKey string, cdc *codec.Codec) *cobra.Command Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] @@ -215,7 +215,7 @@ func GetMsgChannelCloseConfirmCmd(storeKey string, cdc *codec.Codec) *cobra.Comm Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) portID := args[0] diff --git a/x/ibc/04-channel/client/rest/swagger.go b/x/ibc/04-channel/client/rest/swagger.go index 608196f69921..5f6dc5821468 100644 --- a/x/ibc/04-channel/client/rest/swagger.go +++ b/x/ibc/04-channel/client/rest/swagger.go @@ -1,7 +1,7 @@ package rest import ( - auth "github.com/cosmos/cosmos-sdk/x/auth" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) @@ -13,43 +13,43 @@ type ( PostChannelOpenInit struct { Msgs []types.MsgChannelOpenInit `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelOpenTry struct { Msgs []types.MsgChannelOpenTry `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelOpenAck struct { Msgs []types.MsgChannelOpenAck `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelOpenConfirm struct { Msgs []types.MsgChannelOpenConfirm `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelCloseInit struct { Msgs []types.MsgChannelCloseInit `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelCloseConfirm struct { Msgs []types.MsgChannelCloseConfirm `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } ) diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index 7a359de46651..16d08f886f97 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) @@ -35,7 +35,7 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) + txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) sender := cliCtx.GetFromAddress() diff --git a/x/ibc/20-transfer/client/rest/swagger.go b/x/ibc/20-transfer/client/rest/swagger.go index c36f5d9e9822..5714d06dcaaf 100644 --- a/x/ibc/20-transfer/client/rest/swagger.go +++ b/x/ibc/20-transfer/client/rest/swagger.go @@ -1,7 +1,7 @@ package rest import ( - auth "github.com/cosmos/cosmos-sdk/x/auth" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) @@ -13,15 +13,15 @@ type ( PostTransfer struct { Msgs []types.MsgTransfer `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostRecvPacket struct { Msgs []types.MsgRecvPacket `json:"msg" yaml:"msg"` - Fee auth.StdFee `json:"fee" yaml:"fee"` - Signatures []auth.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } ) diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index 914f4d148c71..730d7b880b1a 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -37,11 +37,14 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { RegisterCodec(cdc) } -func (AppModuleBasic) DefaultGenesis() json.RawMessage { +// DefaultGenesis returns default genesis state as raw bytes for the ibc +// transfer module. +func (AppModuleBasic) DefaultGenesis(_ codec.JSONMarshaler) json.RawMessage { return nil } -func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { +// ValidateGenesis performs genesis state validation for the ibc transfer module. +func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, _ json.RawMessage) error { return nil } @@ -88,15 +91,15 @@ func (am AppModule) NewQuerierHandler() sdk.Querier { return nil } -// InitGenesis performs genesis initialization for the staking module. It returns +// InitGenesis performs genesis initialization for the ibc transfer module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(ctx sdk.Context, _ codec.JSONMarshaler, _ json.RawMessage) []abci.ValidatorUpdate { // check if the IBC transfer module account is set InitGenesis(ctx, am.keeper) return []abci.ValidatorUpdate{} } -func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { +func (am AppModule) ExportGenesis(ctx sdk.Context, _ codec.JSONMarshaler) json.RawMessage { return nil } diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go index 1ce47f8ebf2e..eaf62c619de8 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/ante/ante_test.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" @@ -145,7 +145,7 @@ func (suite *HandlerTestSuite) queryProof(key string) (proof commitment.Proof, h } func (suite *HandlerTestSuite) newTx(msg sdk.Msg) sdk.Tx { - return auth.StdTx{ + return authtypes.StdTx{ Msgs: []sdk.Msg{msg}, } } diff --git a/x/ibc/module.go b/x/ibc/module.go index 65f03954cd1d..2cab265d4b6e 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -49,12 +49,12 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { // DefaultGenesis returns default genesis state as raw bytes for the ibc // module. -func (AppModuleBasic) DefaultGenesis() json.RawMessage { +func (AppModuleBasic) DefaultGenesis(_ codec.JSONMarshaler) json.RawMessage { return nil } // ValidateGenesis performs genesis state validation for the ibc module. -func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { +func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, _ json.RawMessage) error { return nil } @@ -118,14 +118,14 @@ func (am AppModule) NewQuerierHandler() sdk.Querier { // InitGenesis performs genesis initialization for the ibc module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(_ sdk.Context, _ codec.JSONMarshaler, _ json.RawMessage) []abci.ValidatorUpdate { // check if the IBC transfer module account is set return []abci.ValidatorUpdate{} } // ExportGenesis returns the exported genesis state as raw bytes for the ibc // module. -func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { +func (am AppModule) ExportGenesis(_ sdk.Context, _ codec.JSONMarshaler) json.RawMessage { return nil } From efb28d7e4e69923fb79a494d00b151e4cb344df2 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 18 Feb 2020 14:57:24 +0100 Subject: [PATCH 083/176] ICS07 follow up changes (#5606) * ADR07 follow up changes * add assertion checks * update ICS02 tests * update ICS07 tests * add trusting and ubd period to msg * tests * more test updates * ICS07 follow ups (#5631) * refactor tendermint package to move msgs here * fix rest of package to accomadate 07 refactor * added GetHeight to ConsensusState and moved clientstate struct creation to 07-tendermint * start work on making misbehavior retrieve consensusState LTE misbehavior * allow misbehavior submission at height not equal to persisted consensusState * optimize submitMisbehavior by erroring earlier * cleanup misbehavior and propose lazy fix * fix bug * Update x/ibc/02-client/keeper/client.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * address fede review * add chain-id into clientstate * address necessary fede review Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Aditya --- x/ibc/02-client/alias.go | 8 +- x/ibc/02-client/client/cli/cli.go | 18 -- x/ibc/02-client/client/rest/rest.go | 23 -- x/ibc/02-client/client/rest/swagger.go | 29 +-- x/ibc/02-client/client/utils/utils.go | 31 +-- x/ibc/02-client/exported/exported.go | 22 ++ x/ibc/02-client/handler.go | 58 +++-- x/ibc/02-client/keeper/client.go | 27 ++- x/ibc/02-client/keeper/client_test.go | 135 ++++++++---- x/ibc/02-client/keeper/keeper.go | 58 ++--- x/ibc/02-client/keeper/keeper_test.go | 75 +++++-- x/ibc/02-client/module.go | 5 - x/ibc/02-client/types/codec.go | 5 +- x/ibc/02-client/types/events.go | 6 +- x/ibc/02-client/types/expected_keepers.go | 3 + x/ibc/02-client/types/msgs_test.go | 71 ------- x/ibc/03-connection/keeper/keeper_test.go | 55 +++-- x/ibc/04-channel/keeper/handshake_test.go | 16 +- x/ibc/04-channel/keeper/keeper_test.go | 24 ++- x/ibc/07-tendermint/client/cli/cli.go | 26 +++ .../client/cli/tx.go | 37 ++-- x/ibc/07-tendermint/client/rest/rest.go | 45 ++++ x/ibc/07-tendermint/client/rest/swagger.go | 31 +++ .../client/rest/tx.go | 9 +- x/ibc/07-tendermint/consensus_state_test.go | 57 ----- x/ibc/07-tendermint/evidence_test.go | 196 ----------------- x/ibc/07-tendermint/misbehaviour.go | 45 ++-- x/ibc/07-tendermint/misbehaviour_test.go | 111 +++++----- x/ibc/07-tendermint/module.go | 29 +++ x/ibc/07-tendermint/tendermint_test.go | 27 ++- .../07-tendermint/{ => types}/client_state.go | 61 +++++- .../{ => types}/client_state_test.go | 200 +++++++++--------- x/ibc/07-tendermint/{ => types}/codec.go | 4 +- .../{ => types}/consensus_state.go | 31 ++- .../types/consensus_state_test.go | 79 +++++++ x/ibc/07-tendermint/types/errors.go | 15 ++ x/ibc/07-tendermint/{ => types}/evidence.go | 11 +- x/ibc/07-tendermint/types/evidence_test.go | 186 ++++++++++++++++ x/ibc/07-tendermint/{ => types}/header.go | 7 +- .../07-tendermint/{ => types}/header_test.go | 8 +- .../types/msgs.go | 83 +++++--- x/ibc/07-tendermint/types/msgs_test.go | 80 +++++++ x/ibc/07-tendermint/types/tendermint_test.go | 48 +++++ x/ibc/07-tendermint/{ => types}/test_utils.go | 5 +- x/ibc/07-tendermint/update.go | 57 +++-- x/ibc/07-tendermint/update_test.go | 22 +- x/ibc/20-transfer/handler_test.go | 18 +- x/ibc/20-transfer/keeper/keeper_test.go | 4 + x/ibc/20-transfer/keeper/relay_test.go | 14 +- x/ibc/ante/ante.go | 5 +- x/ibc/ante/ante_test.go | 32 ++- x/ibc/client/cli/cli.go | 3 +- x/ibc/handler.go | 7 +- x/ibc/module.go | 4 +- x/staking/types/types.pb.go | 9 +- 55 files changed, 1398 insertions(+), 877 deletions(-) delete mode 100644 x/ibc/02-client/types/msgs_test.go create mode 100644 x/ibc/07-tendermint/client/cli/cli.go rename x/ibc/{02-client => 07-tendermint}/client/cli/tx.go (84%) create mode 100644 x/ibc/07-tendermint/client/rest/rest.go create mode 100644 x/ibc/07-tendermint/client/rest/swagger.go rename x/ibc/{02-client => 07-tendermint}/client/rest/tx.go (95%) delete mode 100644 x/ibc/07-tendermint/consensus_state_test.go delete mode 100644 x/ibc/07-tendermint/evidence_test.go create mode 100644 x/ibc/07-tendermint/module.go rename x/ibc/07-tendermint/{ => types}/client_state.go (80%) rename x/ibc/07-tendermint/{ => types}/client_state_test.go (66%) rename x/ibc/07-tendermint/{ => types}/codec.go (80%) rename x/ibc/07-tendermint/{ => types}/consensus_state.go (50%) create mode 100644 x/ibc/07-tendermint/types/consensus_state_test.go create mode 100644 x/ibc/07-tendermint/types/errors.go rename x/ibc/07-tendermint/{ => types}/evidence.go (91%) create mode 100644 x/ibc/07-tendermint/types/evidence_test.go rename x/ibc/07-tendermint/{ => types}/header.go (95%) rename x/ibc/07-tendermint/{ => types}/header_test.go (80%) rename x/ibc/{02-client => 07-tendermint}/types/msgs.go (50%) create mode 100644 x/ibc/07-tendermint/types/msgs_test.go create mode 100644 x/ibc/07-tendermint/types/tendermint_test.go rename x/ibc/07-tendermint/{ => types}/test_utils.go (87%) diff --git a/x/ibc/02-client/alias.go b/x/ibc/02-client/alias.go index ac62fc7602c8..762cb695ab26 100644 --- a/x/ibc/02-client/alias.go +++ b/x/ibc/02-client/alias.go @@ -37,8 +37,6 @@ var ( ErrRootNotFound = types.ErrRootNotFound ErrInvalidHeader = types.ErrInvalidHeader ErrInvalidEvidence = types.ErrInvalidEvidence - NewMsgCreateClient = types.NewMsgCreateClient - NewMsgUpdateClient = types.NewMsgUpdateClient // variable aliases SubModuleCdc = types.SubModuleCdc @@ -48,8 +46,6 @@ var ( ) type ( - Keeper = keeper.Keeper - StakingKeeper = types.StakingKeeper - MsgCreateClient = types.MsgCreateClient - MsgUpdateClient = types.MsgUpdateClient + Keeper = keeper.Keeper + StakingKeeper = types.StakingKeeper ) diff --git a/x/ibc/02-client/client/cli/cli.go b/x/ibc/02-client/client/cli/cli.go index 757b8894f719..bd9d8d361be2 100644 --- a/x/ibc/02-client/client/cli/cli.go +++ b/x/ibc/02-client/client/cli/cli.go @@ -26,21 +26,3 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { )...) return ics02ClientQueryCmd } - -// GetTxCmd returns the transaction commands for IBC clients -func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { - ics02ClientTxCmd := &cobra.Command{ - Use: "client", - Short: "Client transaction subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - } - - ics02ClientTxCmd.AddCommand(flags.PostCommands( - GetCmdCreateClient(cdc), - GetCmdUpdateClient(cdc), - GetCmdSubmitMisbehaviour(cdc), - )...) - - return ics02ClientTxCmd -} diff --git a/x/ibc/02-client/client/rest/rest.go b/x/ibc/02-client/client/rest/rest.go index 34000c329e0d..a6b8b215b2c3 100644 --- a/x/ibc/02-client/client/rest/rest.go +++ b/x/ibc/02-client/client/rest/rest.go @@ -4,9 +4,6 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/types/rest" - evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" ) // REST client flags @@ -18,24 +15,4 @@ const ( // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { registerQueryRoutes(cliCtx, r) - registerTxRoutes(cliCtx, r) -} - -// CreateClientReq defines the properties of a create client request's body. -type CreateClientReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ClientID string `json:"client_id" yaml:"client_id"` - ConsensusState exported.ConsensusState `json:"consensus_state" yaml:"consensus_state"` -} - -// UpdateClientReq defines the properties of a update client request's body. -type UpdateClientReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - Header exported.Header `json:"header" yaml:"header"` -} - -// SubmitMisbehaviourReq defines the properties of a submit misbehaviour request's body. -type SubmitMisbehaviourReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` } diff --git a/x/ibc/02-client/client/rest/swagger.go b/x/ibc/02-client/client/rest/swagger.go index 0b3fbc53d2f4..7c78a9f4808b 100644 --- a/x/ibc/02-client/client/rest/swagger.go +++ b/x/ibc/02-client/client/rest/swagger.go @@ -1,10 +1,8 @@ package rest import ( - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/evidence" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -17,7 +15,7 @@ type ( QueryHeader struct { Height int64 `json:"height"` - Result tendermint.Header `json:"result"` + Result ibctmtypes.Header `json:"result"` } QueryClientState struct { @@ -27,32 +25,11 @@ type ( QueryNodeConsensusState struct { Height int64 `json:"height"` - Result tendermint.ConsensusState `json:"result"` + Result ibctmtypes.ConsensusState `json:"result"` } QueryPath struct { Height int64 `json:"height"` Result commitment.Prefix `json:"result"` } - - PostCreateClient struct { - Msgs []types.MsgCreateClient `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostUpdateClient struct { - Msgs []types.MsgUpdateClient `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostSubmitMisbehaviour struct { - Msgs []evidence.MsgSubmitEvidence `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } ) diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index 297c78c47cd6..eb83f1bc9df8 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -91,30 +91,30 @@ func QueryConsensusState( // QueryTendermintHeader takes a client context and returns the appropriate // tendermint header -func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, error) { +func QueryTendermintHeader(cliCtx context.CLIContext) (ibctmtypes.Header, int64, error) { node, err := cliCtx.GetNode() if err != nil { - return tendermint.Header{}, 0, err + return ibctmtypes.Header{}, 0, err } info, err := node.ABCIInfo() if err != nil { - return tendermint.Header{}, 0, err + return ibctmtypes.Header{}, 0, err } height := info.Response.LastBlockHeight commit, err := node.Commit(&height) if err != nil { - return tendermint.Header{}, 0, err + return ibctmtypes.Header{}, 0, err } validators, err := node.Validators(&height, 0, 10000) if err != nil { - return tendermint.Header{}, 0, err + return ibctmtypes.Header{}, 0, err } - header := tendermint.Header{ + header := ibctmtypes.Header{ SignedHeader: commit.SignedHeader, ValidatorSet: tmtypes.NewValidatorSet(validators.Validators), } @@ -124,32 +124,33 @@ func QueryTendermintHeader(cliCtx context.CLIContext) (tendermint.Header, int64, // QueryNodeConsensusState takes a client context and returns the appropriate // tendermint consensus state -func QueryNodeConsensusState(cliCtx context.CLIContext) (tendermint.ConsensusState, int64, error) { +func QueryNodeConsensusState(cliCtx context.CLIContext) (ibctmtypes.ConsensusState, int64, error) { node, err := cliCtx.GetNode() if err != nil { - return tendermint.ConsensusState{}, 0, err + return ibctmtypes.ConsensusState{}, 0, err } info, err := node.ABCIInfo() if err != nil { - return tendermint.ConsensusState{}, 0, err + return ibctmtypes.ConsensusState{}, 0, err } height := info.Response.LastBlockHeight commit, err := node.Commit(&height) if err != nil { - return tendermint.ConsensusState{}, 0, err + return ibctmtypes.ConsensusState{}, 0, err } validators, err := node.Validators(&height, 0, 10000) if err != nil { - return tendermint.ConsensusState{}, 0, err + return ibctmtypes.ConsensusState{}, 0, err } - state := tendermint.ConsensusState{ - Root: commitment.NewRoot(commit.AppHash), - ValidatorSetHash: tmtypes.NewValidatorSet(validators.Validators).Hash(), + state := ibctmtypes.ConsensusState{ + Timestamp: commit.Time, + Root: commitment.NewRoot(commit.AppHash), + ValidatorSet: tmtypes.NewValidatorSet(validators.Validators), } return state, height, nil diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index bdaa85583bce..e5623ed8ddca 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -4,6 +4,8 @@ import ( "encoding/json" "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/codec" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" @@ -90,6 +92,9 @@ type ClientState interface { type ConsensusState interface { ClientType() ClientType // Consensus kind + // GetHeight returns the height of the consensus state + GetHeight() uint64 + // GetRoot returns the commitment root of the consensus state, // which is used for key-value pair verification. GetRoot() commitment.RootI @@ -110,6 +115,23 @@ type Header interface { GetHeight() uint64 } +// MsgCreateClient defines the msg interface that the +// CreateClient Handler expects +type MsgCreateClient interface { + sdk.Msg + GetClientID() string + GetClientType() string + GetConsensusState() ConsensusState +} + +// MsgUpdateClient defines the msg interface that the +// UpdateClient Handler expects +type MsgUpdateClient interface { + sdk.Msg + GetClientID() string + GetHeader() Header +} + // ClientType defines the type of the consensus algorithm type ClientType byte diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index c9aa56f75404..3354fe93b8c4 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -7,30 +7,52 @@ import ( evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) // HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient -func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) (*sdk.Result, error) { - clientType := exported.ClientTypeFromString(msg.ClientType) - if clientType == 0 { - return nil, sdkerrors.Wrap(ErrInvalidClientType, msg.ClientType) +func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg exported.MsgCreateClient) (*sdk.Result, error) { + clientType := exported.ClientTypeFromString(msg.GetClientType()) + var clientState exported.ClientState + switch clientType { + case 0: + return nil, sdkerrors.Wrap(ErrInvalidClientType, msg.GetClientType()) + case exported.Tendermint: + tmMsg, ok := msg.(ibctmtypes.MsgCreateClient) + if !ok { + return nil, sdkerrors.Wrap(ErrInvalidClientType, "Msg is not a Tendermint CreateClient msg") + } + var err error + clientState, err = ibctmtypes.InitializeFromMsg(tmMsg) + if err != nil { + return nil, err + } + default: + return nil, sdkerrors.Wrap(ErrInvalidClientType, msg.GetClientType()) } - _, err := k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState) + _, err := k.CreateClient( + ctx, clientState, msg.GetConsensusState(), + ) if err != nil { return nil, err } + attributes := make([]sdk.Attribute, len(msg.GetSigners())+1) + attributes[0] = sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory) + for i, signer := range msg.GetSigners() { + attributes[i+1] = sdk.NewAttribute(sdk.AttributeKeySender, signer.String()) + } + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( EventTypeCreateClient, - sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), - sdk.NewAttribute(AttrbuteKeyClientType, msg.ClientType), + sdk.NewAttribute(AttributeKeyClientID, msg.GetClientID()), + sdk.NewAttribute(AttrbuteKeyClientType, msg.GetClientType()), ), sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), - sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + attributes..., ), }) @@ -40,22 +62,26 @@ func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) (*sdk } // HandleMsgUpdateClient defines the sdk.Handler for MsgUpdateClient -func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) (*sdk.Result, error) { - err := k.UpdateClient(ctx, msg.ClientID, msg.Header) - if err != nil { +func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg exported.MsgUpdateClient) (*sdk.Result, error) { + if err := k.UpdateClient(ctx, msg.GetClientID(), msg.GetHeader()); err != nil { return nil, err } + attributes := make([]sdk.Attribute, len(msg.GetSigners())+1) + attributes[0] = sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory) + for i, signer := range msg.GetSigners() { + attributes[i+1] = sdk.NewAttribute(sdk.AttributeKeySender, signer.String()) + } + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( EventTypeUpdateClient, - sdk.NewAttribute(AttributeKeyClientID, msg.ClientID), - sdk.NewAttribute(AttrbuteKeyClientType, msg.Header.ClientType().String()), + sdk.NewAttribute(AttributeKeyClientID, msg.GetClientID()), + sdk.NewAttribute(AttrbuteKeyClientType, msg.GetHeader().ClientType().String()), ), sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), - sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), + attributes..., ), }) diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index e3f65748259d..98f2220727ef 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -8,14 +8,17 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) // CreateClient creates a new client state and populates it with a given consensus // state as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create +// +// CONTRACT: ClientState was constructed correctly from given initial consensusState func (k Keeper) CreateClient( - ctx sdk.Context, clientID string, - clientType exported.ClientType, consensusState exported.ConsensusState, + ctx sdk.Context, clientState exported.ClientState, consensusState exported.ConsensusState, ) (exported.ClientState, error) { + clientID := clientState.GetID() _, found := k.GetClientState(ctx, clientID) if found { return nil, sdkerrors.Wrapf(types.ErrClientExists, "cannot create client with ID %s", clientID) @@ -26,13 +29,13 @@ func (k Keeper) CreateClient( panic(fmt.Sprintf("client type is already defined for client %s", clientID)) } - clientState, err := k.initialize(ctx, clientID, clientType, consensusState) - if err != nil { - return nil, sdkerrors.Wrapf(err, "cannot create client with ID %s", clientID) + height := consensusState.GetHeight() + if consensusState != nil { + k.SetClientConsensusState(ctx, clientID, height, consensusState) } k.SetClientState(ctx, clientState) - k.SetClientType(ctx, clientID, clientType) + k.SetClientType(ctx, clientID, clientState.ClientType()) k.Logger(ctx).Info(fmt.Sprintf("client %s created at height %d", clientID, clientState.GetLatestHeight())) ctx.EventManager().EmitEvents(sdk.Events{ @@ -78,9 +81,11 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H switch clientType { case exported.Tendermint: - clientState, consensusState, err = tendermint.CheckValidityAndUpdateState(clientState, header, ctx.ChainID()) + clientState, consensusState, err = tendermint.CheckValidityAndUpdateState( + clientState, header, ctx.BlockTime(), + ) default: - return sdkerrors.Wrapf(types.ErrInvalidClientType, "cannot update client with ID %s", clientID) + err = types.ErrInvalidClientType } if err != nil { @@ -113,16 +118,16 @@ func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, misbehaviour ex return sdkerrors.Wrap(types.ErrClientNotFound, misbehaviour.GetClientID()) } - consensusState, found := k.GetClientConsensusState(ctx, misbehaviour.GetClientID(), uint64(misbehaviour.GetHeight())) + consensusState, found := k.GetClientConsensusStateLTE(ctx, misbehaviour.GetClientID(), uint64(misbehaviour.GetHeight())) if !found { return sdkerrors.Wrap(types.ErrConsensusStateNotFound, misbehaviour.GetClientID()) } var err error switch e := misbehaviour.(type) { - case tendermint.Evidence: + case ibctmtypes.Evidence: clientState, err = tendermint.CheckMisbehaviourAndUpdateState( - clientState, consensusState, misbehaviour, uint64(misbehaviour.GetHeight()), + clientState, consensusState, misbehaviour, consensusState.GetHeight(), ctx.BlockTime(), ) default: diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index ab6eec5589a6..dcd7ef911474 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -7,7 +7,8 @@ import ( tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -25,14 +26,13 @@ func (suite *KeeperTestSuite) TestCreateClient() { cases := []struct { msg string - params params + clientID string expPass bool expPanic bool }{ - {"success", params{testClientID, exported.Tendermint}, true, false}, - {"client ID exists", params{testClientID, exported.Tendermint}, false, false}, - {"client type exists", params{testClientID2, exported.Tendermint}, false, true}, - {"invalid client type", params{testClientID3, invalidClientType}, false, false}, + {"success", testClientID, true, false}, + {"client ID exists", testClientID, false, false}, + {"client type exists", testClientID2, false, true}, } for i, tc := range cases { @@ -40,17 +40,25 @@ func (suite *KeeperTestSuite) TestCreateClient() { if tc.expPanic { suite.Require().Panics(func() { - suite.keeper.CreateClient(suite.ctx, tc.params.clientID, tc.params.clientType, suite.consensusState) + clientState, err := ibctmtypes.Initialize(tc.clientID, tc.clientID, suite.consensusState, trustingPeriod, ubdPeriod) + suite.Require().NoError(err, "err on client state initialization") + suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) }, "Msg %d didn't panic: %s", i, tc.msg) } else { - clientState, err := suite.keeper.CreateClient(suite.ctx, tc.params.clientID, tc.params.clientType, suite.consensusState) + clientState, err := ibctmtypes.Initialize(tc.clientID, tc.clientID, suite.consensusState, trustingPeriod, ubdPeriod) + if tc.expPass { + suite.Require().NoError(err, "errored on initialization") + suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.msg) + } + // If we were able to initialize clientstate successfully, try persisting it to state + if err == nil { + _, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) + } if tc.expPass { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) - suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.msg) } else { suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) - suite.Require().Nil(clientState, "invalid test case %d passed: %s", i, tc.msg) } } } @@ -63,7 +71,11 @@ func (suite *KeeperTestSuite) TestUpdateClient() { expPass bool }{ {"valid update", func() error { - _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + if err != nil { + return err + } + _, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) return err }, true}, {"client type not found", func() error { @@ -78,13 +90,17 @@ func (suite *KeeperTestSuite) TestUpdateClient() { return nil }, false}, {"frozen client", func() error { - clientState := tendermint.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} + clientState := ibctmtypes.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} suite.keeper.SetClientState(suite.ctx, clientState) suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) return nil }, false}, {"invalid header", func() error { - _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + if err != nil { + return err + } + _, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) if err != nil { return err } @@ -104,9 +120,10 @@ func (suite *KeeperTestSuite) TestUpdateClient() { err = suite.keeper.UpdateClient(suite.ctx, testClientID, suite.header) if tc.expPass { - expConsensusState := tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.header.ValidatorSet.Hash(), + expConsensusState := ibctmtypes.ConsensusState{ + Timestamp: suite.header.Time, + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.header.ValidatorSet, } clientState, found := suite.keeper.GetClientState(suite.ctx, testClientID) @@ -114,10 +131,14 @@ func (suite *KeeperTestSuite) TestUpdateClient() { consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, uint64(suite.header.GetHeight())) suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) + tmConsState, ok := consensusState.(ibctmtypes.ConsensusState) + suite.Require().True(ok, "consensus state is not a tendermint consensus state") + // recalculate cached totalVotingPower field for equality check + tmConsState.ValidatorSet.TotalVotingPower() suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().Equal(suite.header.GetHeight(), clientState.GetLatestHeight(), "client state height not updated correctly") - suite.Require().Equal(expConsensusState, consensusState, "consensus state should have been updated") + suite.Require().Equal(suite.header.GetHeight(), clientState.GetLatestHeight(), "client state height not updated correctly on case %s", tc.name) + suite.Require().Equal(expConsensusState, consensusState, "consensus state should have been updated on case %s", tc.name) } else { suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) } @@ -146,42 +167,66 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { testCases := []struct { name string - evidence tendermint.Evidence + evidence ibctmtypes.Evidence malleate func() error expPass bool }{ { "trusting period misbehavior should pass", - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, suite.valSet, bothSigners), - Header2: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, bothValSet, bothSigners), - FromValidatorSet: bothValSet, - ChainID: testClientID, - ClientID: testClientID, + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, suite.valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + ChainID: testClientID, + ClientID: testClientID, }, func() error { - suite.consensusState.ValidatorSetHash = bothValSet.Hash() - _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + suite.consensusState.ValidatorSet = bothValSet + clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + if err != nil { + return err + } + _, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) + + return err + }, + true, + }, + { + "misbehavior at later height should pass", + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.ctx.BlockTime(), bothValSet, suite.valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + ChainID: testClientID, + ClientID: testClientID, + }, + func() error { + suite.consensusState.ValidatorSet = bothValSet + clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + if err != nil { + return err + } + _, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) + return err }, true, }, { "client state not found", - tendermint.Evidence{}, + ibctmtypes.Evidence{}, func() error { return nil }, false, }, { "consensus state not found", - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, suite.valSet, bothSigners), - Header2: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, bothValSet, bothSigners), + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, suite.valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ChainID: testClientID, ClientID: testClientID, }, func() error { - clientState := tendermint.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} + clientState := ibctmtypes.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} suite.keeper.SetClientState(suite.ctx, clientState) return nil }, @@ -189,14 +234,14 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { }, { "consensus state not found", - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, suite.valSet, bothSigners), - Header2: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, bothValSet, bothSigners), + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, suite.valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ChainID: testClientID, ClientID: testClientID, }, func() error { - clientState := tendermint.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} + clientState := ibctmtypes.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} suite.keeper.SetClientState(suite.ctx, clientState) return nil }, @@ -204,15 +249,19 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { }, { "misbehaviour check failed", - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(testClientID, testClientHeight, bothValSet, bothValSet, bothSigners), - Header2: tendermint.CreateTestHeader(testClientID, testClientHeight, altValSet, bothValSet, altSigners), - FromValidatorSet: bothValSet, - ChainID: testClientID, - ClientID: testClientID, + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), altValSet, bothValSet, altSigners), + ChainID: testClientID, + ClientID: testClientID, }, func() error { - _, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) + clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + if err != nil { + return err + } + _, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) + return err }, false, diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index 3d0e18fad1c4..f9b1dbdcfdc9 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -10,7 +10,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -96,6 +96,34 @@ func (k Keeper) SetClientConsensusState(ctx sdk.Context, clientID string, height store.Set(ibctypes.KeyConsensusState(clientID, height), bz) } +// HasClientConsensusState returns if keeper has a ConsensusState for a particular +// client at the given height +func (k Keeper) HasClientConsensusState(ctx sdk.Context, clientID string, height uint64) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(ibctypes.KeyConsensusState(clientID, height)) +} + +// GetLatestClientConsensusState gets the latest ConsensusState stored for a given client +func (k Keeper) GetLatestClientConsensusState(ctx sdk.Context, clientID string) (exported.ConsensusState, bool) { + clientState, ok := k.GetClientState(ctx, clientID) + if !ok { + return nil, false + } + return k.GetClientConsensusState(ctx, clientID, clientState.GetLatestHeight()) +} + +// GetClientConsensusStatelTE will get the latest ConsensusState of a particular client at the latest height +// less than or equal to the given height +func (k Keeper) GetClientConsensusStateLTE(ctx sdk.Context, clientID string, maxHeight uint64) (exported.ConsensusState, bool) { + for i := maxHeight; i > 0; i-- { + found := k.HasClientConsensusState(ctx, clientID, i) + if found { + return k.GetClientConsensusState(ctx, clientID, i) + } + } + return nil, false +} + // GetSelfConsensusState introspects the (self) past historical info at a given height // and returns the expected consensus state at that height. func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported.ConsensusState, bool) { @@ -106,9 +134,11 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported. valSet := stakingtypes.Validators(histInfo.Valset) - consensusState := tendermint.ConsensusState{ - Root: commitment.NewRoot(histInfo.Header.AppHash), - ValidatorSetHash: tmtypes.NewValidatorSet(valSet.ToTmValidators()).Hash(), + consensusState := ibctmtypes.ConsensusState{ + Height: height, + Timestamp: ctx.BlockTime(), + Root: commitment.NewRoot(histInfo.Header.AppHash), + ValidatorSet: tmtypes.NewValidatorSet(valSet.ToTmValidators()), } return consensusState, true } @@ -139,23 +169,3 @@ func (k Keeper) GetAllClients(ctx sdk.Context) (states []exported.ClientState) { }) return states } - -// State returns a new client state with a given id as defined in -// https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#example-implementation -func (k Keeper) initialize( - ctx sdk.Context, clientID string, clientType exported.ClientType, - consensusState exported.ConsensusState, -) (exported.ClientState, error) { - var clientState exported.ClientState - height := uint64(ctx.BlockHeight()) - - switch clientType { - case exported.Tendermint: - clientState = tendermint.NewClientState(clientID, height) - default: - return nil, types.ErrInvalidClientType - } - - k.SetClientConsensusState(ctx, clientID, height, consensusState) - return clientState, nil -} diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index 72aef416df0a..1cdf296ed6b1 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "math/rand" "testing" + "time" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" @@ -15,7 +15,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/staking" ) @@ -26,6 +26,9 @@ const ( testClientID3 = "ethermint" testClientHeight = 5 + + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) type KeeperTestSuite struct { @@ -34,26 +37,31 @@ type KeeperTestSuite struct { cdc *codec.Codec ctx sdk.Context keeper *keeper.Keeper - consensusState tendermint.ConsensusState - header tendermint.Header + consensusState ibctmtypes.ConsensusState + header ibctmtypes.Header valSet *tmtypes.ValidatorSet privVal tmtypes.PrivValidator + now time.Time } func (suite *KeeperTestSuite) SetupTest() { isCheckTx := false + suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + now2 := suite.now.Add(time.Duration(time.Hour * 1)) app := simapp.Setup(isCheckTx) suite.cdc = app.Codec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{Height: testClientHeight, ChainID: testClientID}) + suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{Height: testClientHeight, ChainID: testClientID, Time: now2}) suite.keeper = &app.IBCKeeper.ClientKeeper suite.privVal = tmtypes.NewMockPV() validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - suite.header = tendermint.CreateTestHeader(testClientID, testClientHeight, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) - suite.consensusState = tendermint.ConsensusState{ - Root: commitment.NewRoot([]byte("hash")), - ValidatorSetHash: suite.valSet.Hash(), + suite.header = ibctmtypes.CreateTestHeader(testClientID, testClientHeight+2, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.consensusState = ibctmtypes.ConsensusState{ + Height: testClientHeight, + Timestamp: suite.now, + Root: commitment.NewRoot([]byte("hash")), + ValidatorSet: suite.valSet, } var validators staking.Validators @@ -74,7 +82,7 @@ func TestKeeperTestSuite(t *testing.T) { } func (suite *KeeperTestSuite) TestSetClientState() { - clientState := tendermint.NewClientState(testClientID, testClientHeight) + clientState := ibctmtypes.NewClientState(testClientID, testClientID, trustingPeriod, ubdPeriod, testClientHeight, suite.now) suite.keeper.SetClientState(suite.ctx, clientState) retrievedState, found := suite.keeper.GetClientState(suite.ctx, testClientID) @@ -94,17 +102,20 @@ func (suite *KeeperTestSuite) TestSetClientConsensusState() { suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) retrievedConsState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, testClientHeight) - suite.Require().True(found, "GetConsensusState failed") - tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) - require.Equal(suite.T(), suite.consensusState, tmConsState, "ConsensusState not stored correctly") + + tmConsState, ok := retrievedConsState.(ibctmtypes.ConsensusState) + // recalculate cached totalVotingPower field for equality check + tmConsState.ValidatorSet.TotalVotingPower() + suite.Require().True(ok) + suite.Require().Equal(suite.consensusState, tmConsState, "ConsensusState not stored correctly") } func (suite KeeperTestSuite) TestGetAllClients() { expClients := []exported.ClientState{ - tendermint.NewClientState(testClientID2, testClientHeight), - tendermint.NewClientState(testClientID3, testClientHeight), - tendermint.NewClientState(testClientID, testClientHeight), + ibctmtypes.NewClientState(testClientID2, testClientID, trustingPeriod, ubdPeriod, testClientHeight, suite.now), + ibctmtypes.NewClientState(testClientID3, testClientID, trustingPeriod, ubdPeriod, testClientHeight, suite.now), + ibctmtypes.NewClientState(testClientID, testClientID, trustingPeriod, ubdPeriod, testClientHeight, suite.now), } for i := range expClients { @@ -141,3 +152,35 @@ func (suite KeeperTestSuite) TestGetConsensusState() { } } } + +func (suite KeeperTestSuite) TestConsensusStateHelpers() { + // initial setup + clientState, _ := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + suite.keeper.SetClientState(suite.ctx, clientState) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) + + nextState := ibctmtypes.ConsensusState{ + Height: testClientHeight + 5, + Timestamp: suite.now, + Root: commitment.NewRoot([]byte("next")), + ValidatorSet: suite.valSet, + } + + // mock update functionality + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+5, nextState) + clientState.LatestHeight += 5 + suite.keeper.SetClientState(suite.ctx, clientState) + + latest, ok := suite.keeper.GetLatestClientConsensusState(suite.ctx, testClientID) + // recalculate cached totalVotingPower for equality check + latest.(ibctmtypes.ConsensusState).ValidatorSet.TotalVotingPower() + suite.Require().True(ok) + suite.Require().Equal(nextState, latest, "Latest client not returned correctly") + + // Should return existing consensusState at latestClientHeight + lte, ok := suite.keeper.GetClientConsensusStateLTE(suite.ctx, testClientID, testClientHeight+3) + // recalculate cached totalVotingPower for equality check + lte.(ibctmtypes.ConsensusState).ValidatorSet.TotalVotingPower() + suite.Require().True(ok) + suite.Require().Equal(suite.consensusState, lte, "LTE helper function did not return latest client state below height: %d", testClientHeight+3) +} diff --git a/x/ibc/02-client/module.go b/x/ibc/02-client/module.go index 9e5ddbd7dbd5..fd1fd48c06b2 100644 --- a/x/ibc/02-client/module.go +++ b/x/ibc/02-client/module.go @@ -22,11 +22,6 @@ func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router, queryRoute stri rest.RegisterRoutes(ctx, rtr, fmt.Sprintf("%s/%s", queryRoute, SubModuleName)) } -// GetTxCmd returns the root tx command for the IBC client -func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { - return cli.GetTxCmd(fmt.Sprintf("%s/%s", storeKey, SubModuleName), cdc) -} - // GetQueryCmd returns no root query command for the IBC client func GetQueryCmd(cdc *codec.Codec, queryRoute string) *cobra.Command { return cli.GetQueryCmd(fmt.Sprintf("%s/%s", queryRoute, SubModuleName), cdc) diff --git a/x/ibc/02-client/types/codec.go b/x/ibc/02-client/types/codec.go index 3226fc02c2cf..b8c0eed6ee61 100644 --- a/x/ibc/02-client/types/codec.go +++ b/x/ibc/02-client/types/codec.go @@ -11,13 +11,12 @@ var SubModuleCdc *codec.Codec // RegisterCodec registers the IBC client interfaces and types func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*exported.ClientState)(nil), nil) + cdc.RegisterInterface((*exported.MsgCreateClient)(nil), nil) + cdc.RegisterInterface((*exported.MsgUpdateClient)(nil), nil) cdc.RegisterInterface((*exported.ConsensusState)(nil), nil) cdc.RegisterInterface((*exported.Header)(nil), nil) cdc.RegisterInterface((*exported.Misbehaviour)(nil), nil) - cdc.RegisterConcrete(MsgCreateClient{}, "ibc/client/MsgCreateClient", nil) - cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) - SetSubModuleCodec(cdc) } diff --git a/x/ibc/02-client/types/events.go b/x/ibc/02-client/types/events.go index ea0dcc7d6606..9692cd389232 100644 --- a/x/ibc/02-client/types/events.go +++ b/x/ibc/02-client/types/events.go @@ -14,9 +14,9 @@ const ( // IBC client events vars var ( - EventTypeCreateClient = TypeMsgCreateClient - EventTypeUpdateClient = TypeMsgUpdateClient - EventTypeSubmitMisbehaviour = TypeClientMisbehaviour + EventTypeCreateClient = "create_client" + EventTypeUpdateClient = "update_client" + EventTypeSubmitMisbehaviour = "client_misbehaviour" AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) ) diff --git a/x/ibc/02-client/types/expected_keepers.go b/x/ibc/02-client/types/expected_keepers.go index c1ca7a4c3e4a..defc81506b1d 100644 --- a/x/ibc/02-client/types/expected_keepers.go +++ b/x/ibc/02-client/types/expected_keepers.go @@ -1,6 +1,8 @@ package types import ( + "time" + sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -8,4 +10,5 @@ import ( // StakingKeeper expected staking keeper type StakingKeeper interface { GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool) + UnbondingTime(ctx sdk.Context) time.Duration } diff --git a/x/ibc/02-client/types/msgs_test.go b/x/ibc/02-client/types/msgs_test.go deleted file mode 100644 index c1c177a3db0b..000000000000 --- a/x/ibc/02-client/types/msgs_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package types_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/tendermint/tendermint/crypto/secp256k1" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" -) - -func TestMsgCreateClientValidateBasic(t *testing.T) { - cs := tendermint.ConsensusState{ - Root: commitment.NewRoot([]byte("root")), - ValidatorSetHash: []byte("hash"), - } - privKey := secp256k1.GenPrivKey() - signer := sdk.AccAddress(privKey.PubKey().Address()) - - cases := []struct { - msg types.MsgCreateClient - expPass bool - errMsg string - }{ - {types.NewMsgCreateClient(exported.ClientTypeTendermint, exported.ClientTypeTendermint, cs, signer), true, "success msg should pass"}, - {types.NewMsgCreateClient("BADCHAIN", exported.ClientTypeTendermint, cs, signer), false, "invalid client id passed"}, - {types.NewMsgCreateClient("goodchain", "invalid_client_type", cs, signer), false, "unregistered client type passed"}, - {types.NewMsgCreateClient("goodchain", exported.ClientTypeTendermint, nil, signer), false, "nil Consensus State in msg passed"}, - {types.NewMsgCreateClient("goodchain", exported.ClientTypeTendermint, tendermint.ConsensusState{}, signer), false, "invalid Consensus State in msg passed"}, - {types.NewMsgCreateClient("goodchain", exported.ClientTypeTendermint, cs, nil), false, "Empty address passed"}, - } - - for i, tc := range cases { - err := tc.msg.ValidateBasic() - if tc.expPass { - require.NoError(t, err, "Msg %d failed: %v", i, err) - } else { - require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) - } - } -} - -func TestMsgUpdateClient(t *testing.T) { - privKey := secp256k1.GenPrivKey() - signer := sdk.AccAddress(privKey.PubKey().Address()) - - cases := []struct { - msg types.MsgUpdateClient - expPass bool - errMsg string - }{ - {types.NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, signer), true, "success msg should pass"}, - {types.NewMsgUpdateClient("badClient", tendermint.Header{}, signer), false, "invalid client id passed"}, - {types.NewMsgUpdateClient(exported.ClientTypeTendermint, nil, signer), false, "Nil Header passed"}, - {types.NewMsgUpdateClient(exported.ClientTypeTendermint, tendermint.Header{}, nil), false, "Empty address passed"}, - } - - for i, tc := range cases { - err := tc.msg.ValidateBasic() - if tc.expPass { - require.NoError(t, err, "Msg %d failed: %v", i, err) - } else { - require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) - } - } -} diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 72ef41d6bb83..c4e7f63e03d1 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -4,6 +4,7 @@ import ( "fmt" "math/rand" "testing" + "time" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" @@ -18,7 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/staking" @@ -28,7 +29,6 @@ const ( clientType = clientexported.Tendermint storeKey = ibctypes.StoreKey chainID = "gaia" - testHeight = 10 testClientID1 = "testclientidone" testConnectionID1 = "connectionidone" @@ -38,8 +38,13 @@ const ( testClientID3 = "testclientidthree" testConnectionID3 = "connectionidthree" + + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) +var testHeight uint64 + type KeeperTestSuite struct { suite.Suite @@ -48,12 +53,16 @@ type KeeperTestSuite struct { app *simapp.SimApp valSet *tmtypes.ValidatorSet consensusState clientexported.ConsensusState - header tendermint.Header + header ibctmtypes.Header + now time.Time } func (suite *KeeperTestSuite) SetupTest() { + testHeight = 1 isCheckTx := false app := simapp.Setup(isCheckTx) + suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + now2 := suite.now.Add(time.Duration(time.Hour * 1)) suite.cdc = app.Codec() suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{ChainID: chainID, Height: 1}) @@ -61,10 +70,12 @@ func (suite *KeeperTestSuite) SetupTest() { privVal := tmtypes.NewMockPV() validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - suite.header = tendermint.CreateTestHeader(chainID, testHeight, suite.valSet, suite.valSet, []tmtypes.PrivValidator{privVal}) - suite.consensusState = tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.valSet.Hash(), + suite.header = ibctmtypes.CreateTestHeader(chainID, int64(testHeight), now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{privVal}) + suite.consensusState = ibctmtypes.ConsensusState{ + Height: testHeight, + Timestamp: suite.now, + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.valSet, } var validators staking.Validators @@ -99,16 +110,22 @@ func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { func (suite *KeeperTestSuite) createClient(clientID string) { suite.app.Commit() commitID := suite.app.LastCommitID() + suite.now = suite.now.Add(time.Minute) - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1, Time: suite.now}}) suite.ctx = suite.ctx.WithBlockHeight(suite.ctx.BlockHeight() + 1) + testHeight++ - consensusState := tendermint.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState := ibctmtypes.ConsensusState{ + Height: testHeight, + Timestamp: suite.now, + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, } - _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, clientType, consensusState) + clientState, err := ibctmtypes.Initialize(clientID, clientID, consensusState, trustingPeriod, ubdPeriod) + suite.Require().NoError(err) + _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) suite.Require().NoError(err) // _, _, err := simapp.SignCheckDeliver( @@ -127,20 +144,24 @@ func (suite *KeeperTestSuite) updateClient(clientID string) { // always commit when updateClient and begin a new block suite.app.Commit() commitID := suite.app.LastCommitID() + suite.now = suite.now.Add(time.Minute) - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1, Time: suite.now}}) suite.ctx = suite.ctx.WithBlockHeight(suite.ctx.BlockHeight() + 1) + testHeight++ - consensusState := tendermint.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState := ibctmtypes.ConsensusState{ + Height: testHeight, + Timestamp: suite.now, + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, } suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState( suite.ctx, clientID, uint64(suite.app.LastBlockHeight()), consensusState, ) suite.app.IBCKeeper.ClientKeeper.SetClientState( - suite.ctx, tendermint.NewClientState(clientID, uint64(suite.app.LastBlockHeight())), + suite.ctx, ibctmtypes.NewClientState(clientID, clientID, trustingPeriod, ubdPeriod, uint64(suite.app.LastBlockHeight()), suite.now), ) // _, _, err := simapp.SignCheckDeliver( diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index aee68d6cd00c..59c42ca40d9f 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -101,14 +101,14 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry( suite.ctx, exported.ORDERED, []string{testConnectionID2}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, - validProof{}, uint64(suite.ctx.BlockHeight()), + validProof{}, uint64(testHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry( suite.ctx, exported.ORDERED, []string{testConnectionID2}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, - invalidProof{}, uint64(suite.ctx.BlockHeight()), + invalidProof{}, uint64(testHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -184,13 +184,13 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { if tc.expPass { err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck( suite.ctx, testPort1, testChannel1, testChannelVersion, - validProof{}, uint64(suite.ctx.BlockHeight()), + validProof{}, uint64(testHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck( suite.ctx, testPort1, testChannel1, testChannelVersion, - invalidProof{}, uint64(suite.ctx.BlockHeight()), + invalidProof{}, uint64(testHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -266,13 +266,13 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { if tc.expPass { err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm( suite.ctx, testPort2, testChannel2, - validProof{}, uint64(suite.ctx.BlockHeight()), + validProof{}, uint64(testHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm( suite.ctx, testPort2, testChannel2, - invalidProof{}, uint64(suite.ctx.BlockHeight()), + invalidProof{}, uint64(testHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -404,13 +404,13 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { if tc.expPass { err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm( suite.ctx, testPort2, testChannel2, - validProof{}, uint64(suite.ctx.BlockHeight()), + validProof{}, uint64(testHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm( suite.ctx, testPort2, testChannel2, - invalidProof{}, uint64(suite.ctx.BlockHeight()), + invalidProof{}, uint64(testHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index 5826f272bd9e..c6f6293609b9 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "testing" + "time" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" @@ -17,7 +18,8 @@ import ( connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -42,6 +44,11 @@ const ( testChannelOrder = exported.ORDERED testChannelVersion = "1.0" + + testHeight = 10 + + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) type KeeperTestSuite struct { @@ -204,12 +211,15 @@ func (suite *KeeperTestSuite) createClient(clientID string) { suite.commitNBlocks(1) commitID := suite.app.LastCommitID() - consensusState := tendermint.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState := ibctmtypes.ConsensusState{ + Height: testHeight, + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, } - _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, testClientType, consensusState) + clientState, err := ibctmtypes.Initialize(clientID, clientID, consensusState, trustingPeriod, ubdPeriod) + suite.Require().NoError(err) + _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) suite.Require().NoError(err) } @@ -223,13 +233,13 @@ func (suite *KeeperTestSuite) updateClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: height}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{Height: suite.app.LastBlockHeight()}) - state := tendermint.ConsensusState{ + state := ibctmtypes.ConsensusState{ Root: commitment.NewRoot(commitID.Hash), } suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClientID1, uint64(height-1), state) csi, _ := suite.app.IBCKeeper.ClientKeeper.GetClientState(suite.ctx, testClientID1) - cs, _ := csi.(tendermint.ClientState) + cs, _ := csi.(ibctmtypes.ClientState) cs.LatestHeight = uint64(height - 1) suite.app.IBCKeeper.ClientKeeper.SetClientState(suite.ctx, cs) } diff --git a/x/ibc/07-tendermint/client/cli/cli.go b/x/ibc/07-tendermint/client/cli/cli.go new file mode 100644 index 000000000000..e25dd98536ed --- /dev/null +++ b/x/ibc/07-tendermint/client/cli/cli.go @@ -0,0 +1,26 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" +) + +// GetTxCmd returns the transaction commands for IBC clients +func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + ics07TendermintTxCmd := &cobra.Command{ + Use: "tendermint", + Short: "Tendermint transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + ics07TendermintTxCmd.AddCommand(flags.PostCommands( + GetCmdCreateClient(cdc), + GetCmdUpdateClient(cdc), + GetCmdSubmitMisbehaviour(cdc), + )...) + + return ics07TendermintTxCmd +} diff --git a/x/ibc/02-client/client/cli/tx.go b/x/ibc/07-tendermint/client/cli/tx.go similarity index 84% rename from x/ibc/02-client/client/cli/tx.go rename to x/ibc/07-tendermint/client/cli/tx.go index e983932a05d3..101a266ae125 100644 --- a/x/ibc/02-client/client/cli/tx.go +++ b/x/ibc/07-tendermint/client/cli/tx.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "strings" + "time" "github.com/pkg/errors" @@ -19,34 +20,34 @@ import ( authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/evidence" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) // GetCmdCreateClient defines the command to create a new IBC Client as defined // in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create func GetCmdCreateClient(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "create [client-id] [path/to/consensus_state.json]", + Use: "create [client-id] [chain-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period]", Short: "create new client with a consensus state", Long: strings.TrimSpace(fmt.Sprintf(`create new client with a specified identifier and consensus state: Example: -$ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node0 --home ../node0/cli --chain-id $CID +$ %s tx ibc client create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period] --from node0 --home ../node0/cli --chain-id $CID `, version.ClientName), ), - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) clientID := args[0] + chainID := args[1] - var state exported.ConsensusState - if err := cdc.UnmarshalJSON([]byte(args[1]), &state); err != nil { + var state ibctmtypes.ConsensusState + if err := cdc.UnmarshalJSON([]byte(args[2]), &state); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(args[1]) + contents, err := ioutil.ReadFile(args[2]) if err != nil { return errors.New("neither JSON input nor path to .json file were provided") } @@ -55,9 +56,19 @@ $ %s tx ibc client create [client-id] [path/to/consensus_state.json] --from node } } - msg := types.NewMsgCreateClient( - clientID, state.ClientType().String(), state, - cliCtx.GetFromAddress(), + trustingPeriod, err := time.ParseDuration(args[3]) + if err != nil { + return err + } + + ubdPeriod, err := time.ParseDuration(args[4]) + if err != nil { + return err + } + + msg := ibctmtypes.NewMsgCreateClient( + clientID, chainID, state, + trustingPeriod, ubdPeriod, cliCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { @@ -90,7 +101,7 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home clientID := args[0] - var header exported.Header + var header ibctmtypes.Header if err := cdc.UnmarshalJSON([]byte(args[1]), &header); err != nil { // check for file path if JSON input is not provided contents, err := ioutil.ReadFile(args[1]) @@ -102,7 +113,7 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home } } - msg := types.NewMsgUpdateClient(clientID, header, cliCtx.GetFromAddress()) + msg := ibctmtypes.NewMsgUpdateClient(clientID, header, cliCtx.GetFromAddress()) if err := msg.ValidateBasic(); err != nil { return err } diff --git a/x/ibc/07-tendermint/client/rest/rest.go b/x/ibc/07-tendermint/client/rest/rest.go new file mode 100644 index 000000000000..c483329e14b2 --- /dev/null +++ b/x/ibc/07-tendermint/client/rest/rest.go @@ -0,0 +1,45 @@ +package rest + +import ( + "time" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" +) + +// REST client flags +const ( + RestClientID = "client-id" + RestRootHeight = "height" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) { + registerTxRoutes(cliCtx, r) +} + +// CreateClientReq defines the properties of a create client request's body. +type CreateClientReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ClientID string `json:"client_id" yaml:"client_id"` + ChainID string `json:"chain_id" yaml:"chain_id"` + ConsensusState ibctmtypes.ConsensusState `json:"consensus_state" yaml:"consensus_state"` + TrustingPeriod time.Duration `json:"trusting_period" yaml:"trusting_period"` + UnbondingPeriod time.Duration `json:"unbonding_period" yaml:"unbonding_period"` +} + +// UpdateClientReq defines the properties of a update client request's body. +type UpdateClientReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Header ibctmtypes.Header `json:"header" yaml:"header"` +} + +// SubmitMisbehaviourReq defines the properties of a submit misbehaviour request's body. +type SubmitMisbehaviourReq struct { + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` +} diff --git a/x/ibc/07-tendermint/client/rest/swagger.go b/x/ibc/07-tendermint/client/rest/swagger.go new file mode 100644 index 000000000000..659569346059 --- /dev/null +++ b/x/ibc/07-tendermint/client/rest/swagger.go @@ -0,0 +1,31 @@ +package rest + +import ( + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/evidence" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" +) + +// nolint +type ( + PostCreateClient struct { + Msgs []ibctmtypes.MsgCreateClient `json:"msg" yaml:"msg"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostUpdateClient struct { + Msgs []ibctmtypes.MsgUpdateClient `json:"msg" yaml:"msg"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } + + PostSubmitMisbehaviour struct { + Msgs []evidence.MsgSubmitEvidence `json:"msg" yaml:"msg"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` + } +) diff --git a/x/ibc/02-client/client/rest/tx.go b/x/ibc/07-tendermint/client/rest/tx.go similarity index 95% rename from x/ibc/02-client/client/rest/tx.go rename to x/ibc/07-tendermint/client/rest/tx.go index 7cdbe69bdf5f..378bedcf9636 100644 --- a/x/ibc/02-client/client/rest/tx.go +++ b/x/ibc/07-tendermint/client/rest/tx.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/rest" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/cosmos/cosmos-sdk/x/evidence" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) // RegisterRoutes - Central function to define routes that get registered by the main application @@ -50,10 +50,11 @@ func createClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } // create the message - msg := types.NewMsgCreateClient( + msg := ibctmtypes.NewMsgCreateClient( req.ClientID, - req.ConsensusState.ClientType().String(), + req.ChainID, req.ConsensusState, + req.TrustingPeriod, req.UnbondingPeriod, fromAddr, ) @@ -100,7 +101,7 @@ func updateClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } // create the message - msg := types.NewMsgUpdateClient( + msg := ibctmtypes.NewMsgUpdateClient( clientID, req.Header, fromAddr, diff --git a/x/ibc/07-tendermint/consensus_state_test.go b/x/ibc/07-tendermint/consensus_state_test.go deleted file mode 100644 index 9288d433a6ac..000000000000 --- a/x/ibc/07-tendermint/consensus_state_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package tendermint_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" -) - -func TestConsensusStateValidateBasic(t *testing.T) { - testCases := []struct { - msg string - consensusState tendermint.ConsensusState - expectPass bool - }{ - {"success", - tendermint.ConsensusState{ - Root: commitment.NewRoot([]byte("app_hash")), - ValidatorSetHash: []byte("valset_hash"), - }, - true}, - {"root is nil", - tendermint.ConsensusState{ - Root: nil, - ValidatorSetHash: []byte("valset_hash"), - }, - false}, - {"root is empty", - tendermint.ConsensusState{ - Root: commitment.Root{}, - ValidatorSetHash: []byte("valset_hash"), - }, - false}, - {"invalid client type", - tendermint.ConsensusState{ - Root: commitment.NewRoot([]byte("app_hash")), - ValidatorSetHash: []byte{}, - }, - false}, - } - - for i, tc := range testCases { - tc := tc - - require.Equal(t, tc.consensusState.ClientType(), clientexported.Tendermint) - require.Equal(t, tc.consensusState.GetRoot(), tc.consensusState.Root) - - if tc.expectPass { - require.NoError(t, tc.consensusState.ValidateBasic(), "valid test case %d failed: %s", i, tc.msg) - } else { - require.Error(t, tc.consensusState.ValidateBasic(), "invalid test case %d passed: %s", i, tc.msg) - } - } -} diff --git a/x/ibc/07-tendermint/evidence_test.go b/x/ibc/07-tendermint/evidence_test.go deleted file mode 100644 index 4fb819469ef2..000000000000 --- a/x/ibc/07-tendermint/evidence_test.go +++ /dev/null @@ -1,196 +0,0 @@ -package tendermint_test - -import ( - "bytes" - - "github.com/tendermint/tendermint/crypto/tmhash" - tmbytes "github.com/tendermint/tendermint/libs/bytes" - tmtypes "github.com/tendermint/tendermint/types" - - clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" -) - -func (suite *TendermintTestSuite) TestEvidence() { - signers := []tmtypes.PrivValidator{suite.privVal} - - ev := tendermint.Evidence{ - Header1: suite.header, - Header2: tendermint.CreateTestHeader(chainID, height, suite.valSet, suite.valSet, signers), - FromValidatorSet: suite.valSet, - ChainID: chainID, - ClientID: "gaiamainnet", - } - - suite.Require().Equal(ev.ClientType(), clientexported.Tendermint) - suite.Require().Equal(ev.GetClientID(), "gaiamainnet") - suite.Require().Equal(ev.Route(), "client") - suite.Require().Equal(ev.Type(), "client_misbehaviour") - suite.Require().Equal(ev.Hash(), tmbytes.HexBytes(tmhash.Sum(tendermint.SubModuleCdc.MustMarshalBinaryBare(ev)))) - suite.Require().Equal(ev.GetHeight(), int64(height)) -} - -func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { - altPrivVal := tmtypes.NewMockPV() - altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), height) - - // Create bothValSet with both suite validator and altVal - bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) - // Create alternative validator set with only altVal - altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) - - signers := []tmtypes.PrivValidator{suite.privVal} - // Create signer array and ensure it is in same order as bothValSet - var bothSigners []tmtypes.PrivValidator - if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { - bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} - } else { - bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} - } - - altSigners := []tmtypes.PrivValidator{altPrivVal} - - testCases := []struct { - name string - evidence tendermint.Evidence - malleateEvidence func(ev *tendermint.Evidence) error - expPass bool - }{ - { - "valid evidence", - tendermint.Evidence{ - Header1: suite.header, - Header2: tendermint.CreateTestHeader(chainID, height, suite.valSet, bothValSet, signers), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: "gaiamainnet", - }, - func(ev *tendermint.Evidence) error { return nil }, - true, - }, - { - "invalid client ID ", - tendermint.Evidence{ - Header1: suite.header, - Header2: tendermint.CreateTestHeader(chainID, height, suite.valSet, bothValSet, signers), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: "GAIA", - }, - func(ev *tendermint.Evidence) error { return nil }, - false, - }, - { - "wrong chainID on header1", - tendermint.Evidence{ - Header1: suite.header, - Header2: tendermint.CreateTestHeader("ethermint", height, suite.valSet, bothValSet, signers), - FromValidatorSet: bothValSet, - ChainID: "ethermint", - ClientID: "gaiamainnet", - }, - func(ev *tendermint.Evidence) error { return nil }, - false, - }, - { - "wrong chainID on header2", - tendermint.Evidence{ - Header1: suite.header, - Header2: tendermint.CreateTestHeader("ethermint", height, suite.valSet, bothValSet, signers), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: "gaiamainnet", - }, - func(ev *tendermint.Evidence) error { return nil }, - false, - }, - { - "mismatched heights", - tendermint.Evidence{ - Header1: suite.header, - Header2: tendermint.CreateTestHeader(chainID, 6, suite.valSet, bothValSet, signers), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: "gaiamainnet", - }, - func(ev *tendermint.Evidence) error { return nil }, - false, - }, - { - "same block id", - tendermint.Evidence{ - Header1: suite.header, - Header2: suite.header, - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: "gaiamainnet", - }, - func(ev *tendermint.Evidence) error { return nil }, - false, - }, - { - "header 1 doesn't have 2/3 majority", - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), - Header2: suite.header, - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: "gaiamainnet", - }, - func(ev *tendermint.Evidence) error { - // voteSet contains only altVal which is less than 2/3 of total power (height/1height) - wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header1.Height, 1, tmtypes.PrecommitType, altValSet) - var err error - ev.Header1.Commit, err = tmtypes.MakeCommit(ev.Header1.Commit.BlockID, ev.Header2.Height, ev.Header1.Commit.Round, wrongVoteSet, altSigners) - return err - }, - false, - }, - { - "header 2 doesn't have 2/3 majority", - tendermint.Evidence{ - Header1: suite.header, - Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: "gaiamainnet", - }, - func(ev *tendermint.Evidence) error { - // voteSet contains only altVal which is less than 2/3 of total power (height/1height) - wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header2.Height, 1, tmtypes.PrecommitType, altValSet) - var err error - ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round, wrongVoteSet, altSigners) - return err - }, - false, - }, - { - "validators sign off on wrong commit", - tendermint.Evidence{ - Header1: suite.header, - Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: "gaiamainnet", - }, - func(ev *tendermint.Evidence) error { - ev.Header2.Commit.BlockID = tendermint.MakeBlockID(tmhash.Sum([]byte("other_hash")), 3, tmhash.Sum([]byte("other_partset"))) - return nil - }, - false, - }, - } - - for i, tc := range testCases { - tc := tc - - err := tc.malleateEvidence(&tc.evidence) - suite.Require().NoError(err) - - if tc.expPass { - suite.Require().NoError(tc.evidence.ValidateBasic(), "valid test case %d failed: %s", i, tc.name) - } else { - suite.Require().Error(tc.evidence.ValidateBasic(), "invalid test case %d passed: %s", i, tc.name) - } - } -} diff --git a/x/ibc/07-tendermint/misbehaviour.go b/x/ibc/07-tendermint/misbehaviour.go index 15eb2b935c6a..990412f78c9d 100644 --- a/x/ibc/07-tendermint/misbehaviour.go +++ b/x/ibc/07-tendermint/misbehaviour.go @@ -1,13 +1,14 @@ package tendermint import ( - "bytes" "errors" "fmt" + "time" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -21,65 +22,73 @@ func CheckMisbehaviourAndUpdateState( consensusState clientexported.ConsensusState, misbehaviour clientexported.Misbehaviour, height uint64, // height at which the consensus state was loaded + currentTimestamp time.Time, ) (clientexported.ClientState, error) { // cast the interface to specific types before checking for misbehaviour - tmClientState, ok := clientState.(ClientState) + tmClientState, ok := clientState.(types.ClientState) if !ok { return nil, sdkerrors.Wrap(clienttypes.ErrInvalidClientType, "client state type is not Tendermint") } - tmConsensusState, ok := consensusState.(ConsensusState) + // If client is already frozen at earlier height than evidence, return with error + if tmClientState.IsFrozen() && tmClientState.FrozenHeight <= uint64(misbehaviour.GetHeight()) { + return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidEvidence, + "client is already frozen at earlier height %d than misbehaviour height %d", tmClientState.FrozenHeight, misbehaviour.GetHeight()) + } + + tmConsensusState, ok := consensusState.(types.ConsensusState) if !ok { return nil, sdkerrors.Wrap(clienttypes.ErrInvalidClientType, "consensus state is not Tendermint") } - tmEvidence, ok := misbehaviour.(Evidence) + tmEvidence, ok := misbehaviour.(types.Evidence) if !ok { return nil, sdkerrors.Wrap(clienttypes.ErrInvalidClientType, "evidence type is not Tendermint") } - if err := checkMisbehaviour(tmClientState, tmConsensusState, tmEvidence, height); err != nil { + if err := checkMisbehaviour( + tmClientState, tmConsensusState, tmEvidence, height, currentTimestamp, + ); err != nil { return nil, sdkerrors.Wrap(clienttypes.ErrInvalidEvidence, err.Error()) } tmClientState.FrozenHeight = uint64(tmEvidence.GetHeight()) - return tmClientState, nil } // checkMisbehaviour checks if the evidence provided is a valid light client misbehaviour func checkMisbehaviour( - clientState ClientState, consensusState ConsensusState, evidence Evidence, height uint64, + clientState types.ClientState, consensusState types.ConsensusState, evidence types.Evidence, + height uint64, currentTimestamp time.Time, ) error { - // NOTE: header height and commitment root assertions are checked with the - // evidence and msg ValidateBasic functions at the AnteHandler level. - // check if provided height matches the headers' height - if height != uint64(evidence.GetHeight()) { + if height > uint64(evidence.GetHeight()) { return sdkerrors.Wrapf( ibctypes.ErrInvalidHeight, - "height ≠ evidence header height (%d ≠ %d)", height, evidence.GetHeight(), + "height > evidence header height (%d > %d)", height, evidence.GetHeight(), ) } - if !bytes.Equal(consensusState.ValidatorSetHash, evidence.FromValidatorSet.Hash()) { - return errors.New( - "the consensus state's validator set hash doesn't match the evidence's one", - ) + // NOTE: header height and commitment root assertions are checked with the + // evidence and msg ValidateBasic functions at the AnteHandler level. + + // assert that the timestamp is not from more than an unbonding period ago + if currentTimestamp.Sub(consensusState.Timestamp) >= clientState.UnbondingPeriod { + return errors.New("unbonding period since last consensus state timestamp is over") } // Evidence is within the trusting period. ValidatorSet must have 2/3 similarity with trusted FromValidatorSet // check that the validator sets on both headers are valid given the last trusted validatorset // less than or equal to evidence height - if err := evidence.FromValidatorSet.VerifyFutureCommit( + if err := consensusState.ValidatorSet.VerifyFutureCommit( evidence.Header1.ValidatorSet, evidence.ChainID, evidence.Header1.Commit.BlockID, evidence.Header1.Height, evidence.Header1.Commit, ); err != nil { return fmt.Errorf("validator set in header 1 has too much change from last known validator set: %v", err) } - if err := evidence.FromValidatorSet.VerifyFutureCommit( + if err := consensusState.ValidatorSet.VerifyFutureCommit( evidence.Header2.ValidatorSet, evidence.ChainID, evidence.Header2.Commit.BlockID, evidence.Header2.Height, evidence.Header2.Commit, ); err != nil { diff --git a/x/ibc/07-tendermint/misbehaviour_test.go b/x/ibc/07-tendermint/misbehaviour_test.go index 92925d8582a1..ca72b5cc78d1 100644 --- a/x/ibc/07-tendermint/misbehaviour_test.go +++ b/x/ibc/07-tendermint/misbehaviour_test.go @@ -7,6 +7,7 @@ import ( tmtypes "github.com/tendermint/tendermint/types" tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -31,92 +32,86 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { testCases := []struct { name string - clientState tendermint.ClientState - consensusState tendermint.ConsensusState - evidence tendermint.Evidence + clientState ibctmtypes.ClientState + consensusState ibctmtypes.ConsensusState + evidence ibctmtypes.Evidence height uint64 expPass bool }{ { "valid misbehavior evidence", - tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, - tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, suite.valSet, bothSigners), - Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: chainID, + ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + ChainID: chainID, + ClientID: chainID, }, height, true, }, { - "height doesn't match provided evidence", - tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, - tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, suite.valSet, bothSigners), - Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: chainID, + "valid misbehavior at height greater than last consensusState", + ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + ChainID: chainID, + ClientID: chainID, }, - 0, - false, + height - 1, + true, }, { - "consensus state's valset hash different from evidence", - tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, - tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: suite.valSet.Hash()}, - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, suite.valSet, bothSigners), - Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: chainID, + "consensus state's valset hash different from evidence should still pass", + ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: suite.valSet}, + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + ChainID: chainID, + ClientID: chainID, }, - height, - false, + height - 1, + true, }, { "first valset has too much change", - tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, - tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(chainID, height, altValSet, bothValSet, altSigners), - Header2: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: chainID, + ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + ChainID: chainID, + ClientID: chainID, }, height, false, }, { "second valset has too much change", - tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, - tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(chainID, height, bothValSet, bothValSet, bothSigners), - Header2: tendermint.CreateTestHeader(chainID, height, altValSet, bothValSet, altSigners), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: chainID, + ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), + ChainID: chainID, + ClientID: chainID, }, height, false, }, { "both valsets have too much change", - tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: 0}, - tendermint.ConsensusState{Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSetHash: bothValSet.Hash()}, - tendermint.Evidence{ - Header1: tendermint.CreateTestHeader(chainID, height, altValSet, altValSet, altSigners), - Header2: tendermint.CreateTestHeader(chainID, height, altValSet, bothValSet, altSigners), - FromValidatorSet: bothValSet, - ChainID: chainID, - ClientID: chainID, + ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altValSet, altSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), + ChainID: chainID, + ClientID: chainID, }, height, false, @@ -126,7 +121,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { for i, tc := range testCases { tc := tc - clientState, err := tendermint.CheckMisbehaviourAndUpdateState(tc.clientState, tc.consensusState, tc.evidence, tc.height) + clientState, err := tendermint.CheckMisbehaviourAndUpdateState(tc.clientState, tc.consensusState, tc.evidence, tc.height, suite.now) if tc.expPass { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) diff --git a/x/ibc/07-tendermint/module.go b/x/ibc/07-tendermint/module.go new file mode 100644 index 000000000000..4f5b32cea681 --- /dev/null +++ b/x/ibc/07-tendermint/module.go @@ -0,0 +1,29 @@ +package tendermint + +import ( + "fmt" + + "github.com/gorilla/mux" + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/client/cli" + "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/client/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" +) + +// Name returns the IBC client name +func Name() string { + return types.SubModuleName +} + +// RegisterRESTRoutes registers the REST routes for the IBC client +func RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router, queryRoute string) { + rest.RegisterRoutes(ctx, rtr, fmt.Sprintf("%s/%s", queryRoute, types.SubModuleName)) +} + +// GetTxCmd returns the root tx command for the IBC client +func GetTxCmd(cdc *codec.Codec, storeKey string) *cobra.Command { + return cli.GetTxCmd(cdc, fmt.Sprintf("%s/%s", storeKey, types.SubModuleName)) +} diff --git a/x/ibc/07-tendermint/tendermint_test.go b/x/ibc/07-tendermint/tendermint_test.go index 3a41cc74002c..9c846c50fb3a 100644 --- a/x/ibc/07-tendermint/tendermint_test.go +++ b/x/ibc/07-tendermint/tendermint_test.go @@ -2,40 +2,49 @@ package tendermint_test import ( "testing" + "time" "github.com/stretchr/testify/suite" tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) const ( - chainID = "gaia" - height = 4 + chainID = "gaia" + height = 4 + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) type TendermintTestSuite struct { suite.Suite - cdc *codec.Codec - privVal tmtypes.PrivValidator - valSet *tmtypes.ValidatorSet - header tendermint.Header + cdc *codec.Codec + privVal tmtypes.PrivValidator + valSet *tmtypes.ValidatorSet + header ibctmtypes.Header + now time.Time + clientTime time.Time + headerTime time.Time } func (suite *TendermintTestSuite) SetupTest() { suite.cdc = codec.New() codec.RegisterCrypto(suite.cdc) - tendermint.RegisterCodec(suite.cdc) + ibctmtypes.RegisterCodec(suite.cdc) commitment.RegisterCodec(suite.cdc) + suite.now = time.Date(2020, 1, 3, 0, 0, 0, 0, time.UTC) + suite.clientTime = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) + suite.headerTime = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) suite.privVal = tmtypes.NewMockPV() val := tmtypes.NewValidator(suite.privVal.GetPubKey(), 10) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) - suite.header = tendermint.CreateTestHeader(chainID, height, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } func TestTendermintTestSuite(t *testing.T) { diff --git a/x/ibc/07-tendermint/client_state.go b/x/ibc/07-tendermint/types/client_state.go similarity index 80% rename from x/ibc/07-tendermint/client_state.go rename to x/ibc/07-tendermint/types/client_state.go index 9ea492e2db72..e681d8f7199f 100644 --- a/x/ibc/07-tendermint/client_state.go +++ b/x/ibc/07-tendermint/types/client_state.go @@ -1,7 +1,9 @@ -package tendermint +package types import ( + "errors" "fmt" + "time" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -21,18 +23,62 @@ var _ clientexported.ClientState = ClientState{} type ClientState struct { // Client ID ID string `json:"id" yaml:"id"` + // Chain ID for Tendermint chain, not guaranteed to be unique + ChainID string `json:"chain_id" yaml:"chain_id"` + // Duration of the period since the LastestTimestamp during which the + // submitted headers are valid for upgrade + TrustingPeriod time.Duration `json:"trusting_period" yaml:"trusting_period"` + // Duration of the staking unbonding period + UnbondingPeriod time.Duration `json:"unbonding_period" yaml:"unbonding_period"` // Latest block height LatestHeight uint64 `json:"latest_height" yaml:"latest_height"` + // Latest block time + LatestTimestamp time.Time `json:"latest_time" yaml:"latest_time"` // Block height when the client was frozen due to a misbehaviour FrozenHeight uint64 `json:"frozen_height" yaml:"frozen_height"` } +// InitializeFromMsg creates a tendermint client state from a CreateClientMsg +func InitializeFromMsg( + msg MsgCreateClient, +) (ClientState, error) { + return Initialize(msg.GetClientID(), msg.ChainID, msg.GetConsensusState(), msg.TrustingPeriod, msg.UnbondingPeriod) +} + +// Initialize creates a client state and validates its contents, checking that +// the provided consensus state is from the same client type. +func Initialize( + id string, chainID string, consensusState clientexported.ConsensusState, trustingPeriod, ubdPeriod time.Duration, +) (ClientState, error) { + tmConsState, ok := consensusState.(ConsensusState) + if !ok { + return ClientState{}, errors.New("consensus state is not from Tendermint") + } + latestHeight := tmConsState.GetHeight() + + if trustingPeriod >= ubdPeriod { + return ClientState{}, errors.New("trusting period should be < unbonding period") + } + + clientState := NewClientState( + id, chainID, trustingPeriod, ubdPeriod, latestHeight, tmConsState.Timestamp, + ) + return clientState, nil +} + // NewClientState creates a new ClientState instance -func NewClientState(id string, latestHeight uint64) ClientState { +func NewClientState( + id string, chainID string, trustingPeriod, ubdPeriod time.Duration, + latestHeight uint64, latestTimestamp time.Time, +) ClientState { return ClientState{ - ID: id, - LatestHeight: latestHeight, - FrozenHeight: 0, + ID: id, + ChainID: chainID, + TrustingPeriod: trustingPeriod, + UnbondingPeriod: ubdPeriod, + LatestHeight: latestHeight, + LatestTimestamp: latestTimestamp, + FrozenHeight: 0, } } @@ -51,6 +97,11 @@ func (cs ClientState) GetLatestHeight() uint64 { return cs.LatestHeight } +// GetLatestTimestamp returns latest block time. +func (cs ClientState) GetLatestTimestamp() time.Time { + return cs.LatestTimestamp +} + // IsFrozen returns true if the frozen height has been set. func (cs ClientState) IsFrozen() bool { return cs.FrozenHeight != 0 diff --git a/x/ibc/07-tendermint/client_state_test.go b/x/ibc/07-tendermint/types/client_state_test.go similarity index 66% rename from x/ibc/07-tendermint/client_state_test.go rename to x/ibc/07-tendermint/types/client_state_test.go index c749647bfa9b..cbb4c9c9e301 100644 --- a/x/ibc/07-tendermint/client_state_test.go +++ b/x/ibc/07-tendermint/types/client_state_test.go @@ -1,11 +1,11 @@ -package tendermint_test +package types_test import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -19,16 +19,16 @@ const ( func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { testCases := []struct { name string - clientState tendermint.ClientState - consensusState tendermint.ConsensusState + clientState ibctmtypes.ClientState + consensusState ibctmtypes.ConsensusState prefix commitment.Prefix proof commitment.Proof expPass bool }{ // { // name: "successful verification", - // clientState: tendermint.NewClientState(chainID, height), - // consensusState: tendermint.ConsensusState{ + // clientState: ibctmtypes.NewClientState(chainID, chainID, height), + // consensusState: ibctmtypes.ConsensusState{ // Root: commitment.NewRoot(suite.header.AppHash), // }, // prefix: commitment.NewPrefix([]byte("ibc")), @@ -36,8 +36,8 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { // }, { name: "ApplyPrefix failed", - clientState: tendermint.NewClientState(chainID, height), - consensusState: tendermint.ConsensusState{ + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.Prefix{}, @@ -45,8 +45,8 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "latest client height < height", - clientState: tendermint.NewClientState(chainID, height-1), - consensusState: tendermint.ConsensusState{ + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -54,8 +54,8 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "client is frozen", - clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, - consensusState: tendermint.ConsensusState{ + clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -63,10 +63,10 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "proof verification failed", - clientState: tendermint.NewClientState(chainID, height), - consensusState: tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.valSet.Hash(), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + consensusState: ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.valSet, }, prefix: commitment.NewPrefix([]byte("ibc")), proof: commitment.Proof{}, @@ -95,18 +95,18 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { testCases := []struct { name string - clientState tendermint.ClientState + clientState ibctmtypes.ClientState connection connection.ConnectionEnd - consensusState tendermint.ConsensusState + consensusState ibctmtypes.ConsensusState prefix commitment.Prefix proof commitment.Proof expPass bool }{ // { // name: "successful verification", - // clientState: tendermint.NewClientState(chainID, height), + // clientState: ibctmtypes.NewClientState(chainID, chainID, height), // connection: conn, - // consensusState: tendermint.ConsensusState{ + // consensusState: ibctmtypes.ConsensusState{ // Root: commitment.NewRoot(suite.header.AppHash), // }, // prefix: commitment.NewPrefix([]byte("ibc")), @@ -114,9 +114,9 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { // }, { name: "ApplyPrefix failed", - clientState: tendermint.NewClientState(chainID, height), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), connection: conn, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.Prefix{}, @@ -124,9 +124,9 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { }, { name: "latest client height < height", - clientState: tendermint.NewClientState(chainID, height-1), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), connection: conn, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -134,9 +134,9 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { }, { name: "client is frozen", - clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, connection: conn, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -144,11 +144,11 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { }, { name: "proof verification failed", - clientState: tendermint.NewClientState(chainID, height), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), connection: conn, - consensusState: tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState: ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.valSet, }, prefix: commitment.NewPrefix([]byte("ibc")), proof: commitment.Proof{}, @@ -177,18 +177,18 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { testCases := []struct { name string - clientState tendermint.ClientState + clientState ibctmtypes.ClientState channel channel.Channel - consensusState tendermint.ConsensusState + consensusState ibctmtypes.ConsensusState prefix commitment.Prefix proof commitment.Proof expPass bool }{ // { // name: "successful verification", - // clientState: tendermint.NewClientState(chainID, height), + // clientState: ibctmtypes.NewClientState(chainID, height), // connection: conn, - // consensusState: tendermint.ConsensusState{ + // consensusState: ibctmtypes.ConsensusState{ // Root: commitment.NewRoot(suite.header.AppHash), // }, // prefix: commitment.NewPrefix([]byte("ibc")), @@ -196,9 +196,9 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { // }, { name: "ApplyPrefix failed", - clientState: tendermint.NewClientState(chainID, height), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), channel: ch, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.Prefix{}, @@ -206,9 +206,9 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { }, { name: "latest client height < height", - clientState: tendermint.NewClientState(chainID, height-1), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), channel: ch, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -216,9 +216,9 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { }, { name: "client is frozen", - clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, channel: ch, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -226,11 +226,11 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { }, { name: "proof verification failed", - clientState: tendermint.NewClientState(chainID, height), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), channel: ch, - consensusState: tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState: ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.valSet, }, prefix: commitment.NewPrefix([]byte("ibc")), proof: commitment.Proof{}, @@ -256,18 +256,18 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { testCases := []struct { name string - clientState tendermint.ClientState + clientState ibctmtypes.ClientState commitment []byte - consensusState tendermint.ConsensusState + consensusState ibctmtypes.ConsensusState prefix commitment.Prefix proof commitment.Proof expPass bool }{ // { // name: "successful verification", - // clientState: tendermint.NewClientState(chainID, height), + // clientState: ibctmtypes.NewClientState(chainID, height), // connection: conn, - // consensusState: tendermint.ConsensusState{ + // consensusState: ibctmtypes.ConsensusState{ // Root: commitment.NewRoot(suite.header.AppHash), // }, // prefix: commitment.NewPrefix([]byte("ibc")), @@ -275,9 +275,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { // }, { name: "ApplyPrefix failed", - clientState: tendermint.NewClientState(chainID, height), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), commitment: []byte{}, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.Prefix{}, @@ -285,9 +285,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { }, { name: "latest client height < height", - clientState: tendermint.NewClientState(chainID, height-1), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), commitment: []byte{}, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -295,9 +295,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { }, { name: "client is frozen", - clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, commitment: []byte{}, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -305,11 +305,11 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { }, { name: "proof verification failed", - clientState: tendermint.NewClientState(chainID, height), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), commitment: []byte{}, - consensusState: tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState: ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.valSet, }, prefix: commitment.NewPrefix([]byte("ibc")), proof: commitment.Proof{}, @@ -335,18 +335,18 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { testCases := []struct { name string - clientState tendermint.ClientState + clientState ibctmtypes.ClientState ack []byte - consensusState tendermint.ConsensusState + consensusState ibctmtypes.ConsensusState prefix commitment.Prefix proof commitment.Proof expPass bool }{ // { // name: "successful verification", - // clientState: tendermint.NewClientState(chainID, height), + // clientState: ibctmtypes.NewClientState(chainID, chainID, height), // connection: conn, - // consensusState: tendermint.ConsensusState{ + // consensusState: ibctmtypes.ConsensusState{ // Root: commitment.NewRoot(suite.header.AppHash), // }, // prefix: commitment.NewPrefix([]byte("ibc")), @@ -354,9 +354,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { // }, { name: "ApplyPrefix failed", - clientState: tendermint.NewClientState(chainID, height), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), ack: []byte{}, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.Prefix{}, @@ -364,9 +364,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { }, { name: "latest client height < height", - clientState: tendermint.NewClientState(chainID, height-1), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), ack: []byte{}, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -374,9 +374,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { }, { name: "client is frozen", - clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, ack: []byte{}, - consensusState: tendermint.ConsensusState{ + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -384,11 +384,11 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { }, { name: "proof verification failed", - clientState: tendermint.NewClientState(chainID, height), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), ack: []byte{}, - consensusState: tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState: ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.valSet, }, prefix: commitment.NewPrefix([]byte("ibc")), proof: commitment.Proof{}, @@ -414,17 +414,17 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { testCases := []struct { name string - clientState tendermint.ClientState - consensusState tendermint.ConsensusState + clientState ibctmtypes.ClientState + consensusState ibctmtypes.ConsensusState prefix commitment.Prefix proof commitment.Proof expPass bool }{ // { // name: "successful verification", - // clientState: tendermint.NewClientState(chainID, height), + // clientState: ibctmtypes.NewClientState(chainID, chainID, height), // connection: conn, - // consensusState: tendermint.ConsensusState{ + // consensusState: ibctmtypes.ConsensusState{ // Root: commitment.NewRoot(suite.header.AppHash), // }, // prefix: commitment.NewPrefix([]byte("ibc")), @@ -432,8 +432,8 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { // }, { name: "ApplyPrefix failed", - clientState: tendermint.NewClientState(chainID, height), - consensusState: tendermint.ConsensusState{ + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.Prefix{}, @@ -441,8 +441,8 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { }, { name: "latest client height < height", - clientState: tendermint.NewClientState(chainID, height-1), - consensusState: tendermint.ConsensusState{ + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -450,8 +450,8 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { }, { name: "client is frozen", - clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, - consensusState: tendermint.ConsensusState{ + clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -459,10 +459,10 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { }, { name: "proof verification failed", - clientState: tendermint.NewClientState(chainID, height), - consensusState: tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.valSet.Hash(), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + consensusState: ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.valSet, }, prefix: commitment.NewPrefix([]byte("ibc")), proof: commitment.Proof{}, @@ -488,17 +488,17 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { testCases := []struct { name string - clientState tendermint.ClientState - consensusState tendermint.ConsensusState + clientState ibctmtypes.ClientState + consensusState ibctmtypes.ConsensusState prefix commitment.Prefix proof commitment.Proof expPass bool }{ // { // name: "successful verification", - // clientState: tendermint.NewClientState(chainID, height), + // clientState: ibctmtypes.NewClientState(chainID, chainID, height), // connection: conn, - // consensusState: tendermint.ConsensusState{ + // consensusState: ibctmtypes.ConsensusState{ // Root: commitment.NewRoot(suite.header.AppHash), // }, // prefix: commitment.NewPrefix([]byte("ibc")), @@ -506,8 +506,8 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { // }, { name: "ApplyPrefix failed", - clientState: tendermint.NewClientState(chainID, height), - consensusState: tendermint.ConsensusState{ + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.Prefix{}, @@ -515,8 +515,8 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { }, { name: "latest client height < height", - clientState: tendermint.NewClientState(chainID, height-1), - consensusState: tendermint.ConsensusState{ + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -524,8 +524,8 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { }, { name: "client is frozen", - clientState: tendermint.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, - consensusState: tendermint.ConsensusState{ + clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, prefix: commitment.NewPrefix([]byte("ibc")), @@ -533,10 +533,10 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { }, { name: "proof verification failed", - clientState: tendermint.NewClientState(chainID, height), - consensusState: tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.valSet.Hash(), + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + consensusState: ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.valSet, }, prefix: commitment.NewPrefix([]byte("ibc")), proof: commitment.Proof{}, diff --git a/x/ibc/07-tendermint/codec.go b/x/ibc/07-tendermint/types/codec.go similarity index 80% rename from x/ibc/07-tendermint/codec.go rename to x/ibc/07-tendermint/types/codec.go index 22c6d508ed6a..61e63c31f603 100644 --- a/x/ibc/07-tendermint/codec.go +++ b/x/ibc/07-tendermint/types/codec.go @@ -1,4 +1,4 @@ -package tendermint +package types import ( "github.com/cosmos/cosmos-sdk/codec" @@ -13,6 +13,8 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(ConsensusState{}, "ibc/client/tendermint/ConsensusState", nil) cdc.RegisterConcrete(Header{}, "ibc/client/tendermint/Header", nil) cdc.RegisterConcrete(Evidence{}, "ibc/client/tendermint/Evidence", nil) + cdc.RegisterConcrete(MsgCreateClient{}, "ibc/client/MsgCreateClient", nil) + cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) SetSubModuleCodec(cdc) } diff --git a/x/ibc/07-tendermint/consensus_state.go b/x/ibc/07-tendermint/types/consensus_state.go similarity index 50% rename from x/ibc/07-tendermint/consensus_state.go rename to x/ibc/07-tendermint/types/consensus_state.go index a567c0deaa37..cba067f9a918 100644 --- a/x/ibc/07-tendermint/consensus_state.go +++ b/x/ibc/07-tendermint/types/consensus_state.go @@ -1,16 +1,21 @@ -package tendermint +package types import ( + "time" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + tmtypes "github.com/tendermint/tendermint/types" ) // ConsensusState defines a Tendermint consensus state type ConsensusState struct { - Root commitment.RootI `json:"root" yaml:"root"` - ValidatorSetHash []byte `json:"validator_set_hash" yaml:"validator_set_hash"` + Timestamp time.Time `json:"timestamp" yaml:"timestamp"` + Root commitment.RootI `json:"root" yaml:"root"` + Height uint64 `json:"height" yaml:"height"` + ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` } // ClientType returns Tendermint @@ -23,13 +28,29 @@ func (cs ConsensusState) GetRoot() commitment.RootI { return cs.Root } +// GetHeight returns the height for the specific consensus state +func (cs ConsensusState) GetHeight() uint64 { + return cs.Height +} + +// GetTimestamp returns block time at which the consensus state was stored +func (cs ConsensusState) GetTimestamp() time.Time { + return cs.Timestamp +} + // ValidateBasic defines a basic validation for the tendermint consensus state. func (cs ConsensusState) ValidateBasic() error { if cs.Root == nil || cs.Root.IsEmpty() { return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "root cannot be empty") } - if len(cs.ValidatorSetHash) == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "validator set hash cannot be empty") + if cs.ValidatorSet == nil { + return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "validator set cannot be nil") + } + if cs.Height == 0 { + return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "height cannot be 0") + } + if cs.Timestamp.IsZero() { + return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "timestamp cannot be zero Unix time") } return nil } diff --git a/x/ibc/07-tendermint/types/consensus_state_test.go b/x/ibc/07-tendermint/types/consensus_state_test.go new file mode 100644 index 000000000000..c50be3483e5f --- /dev/null +++ b/x/ibc/07-tendermint/types/consensus_state_test.go @@ -0,0 +1,79 @@ +package types_test + +import ( + "time" + + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { + testCases := []struct { + msg string + consensusState ibctmtypes.ConsensusState + expectPass bool + }{ + {"success", + ibctmtypes.ConsensusState{ + Timestamp: suite.now, + Height: height, + Root: commitment.NewRoot([]byte("app_hash")), + ValidatorSet: suite.valSet, + }, + true}, + {"root is nil", + ibctmtypes.ConsensusState{ + Timestamp: suite.now, + Height: height, + Root: nil, + ValidatorSet: suite.valSet, + }, + false}, + {"root is empty", + ibctmtypes.ConsensusState{ + Timestamp: suite.now, + Height: height, + Root: commitment.Root{}, + ValidatorSet: suite.valSet, + }, + false}, + {"valset is nil", + ibctmtypes.ConsensusState{ + Timestamp: suite.now, + Height: height, + Root: commitment.NewRoot([]byte("app_hash")), + ValidatorSet: nil, + }, + false}, + {"height is 0", + ibctmtypes.ConsensusState{ + Timestamp: suite.now, + Height: 0, + Root: commitment.NewRoot([]byte("app_hash")), + ValidatorSet: suite.valSet, + }, + false}, + {"timestamp is zero", + ibctmtypes.ConsensusState{ + Timestamp: time.Time{}, + Height: height, + Root: commitment.NewRoot([]byte("app_hash")), + ValidatorSet: suite.valSet, + }, + false}, + } + + for i, tc := range testCases { + tc := tc + + suite.Require().Equal(tc.consensusState.ClientType(), clientexported.Tendermint) + suite.Require().Equal(tc.consensusState.GetRoot(), tc.consensusState.Root) + + if tc.expectPass { + suite.Require().NoError(tc.consensusState.ValidateBasic(), "valid test case %d failed: %s", i, tc.msg) + } else { + suite.Require().Error(tc.consensusState.ValidateBasic(), "invalid test case %d passed: %s", i, tc.msg) + } + } +} diff --git a/x/ibc/07-tendermint/types/errors.go b/x/ibc/07-tendermint/types/errors.go new file mode 100644 index 000000000000..1f2bcd48174b --- /dev/null +++ b/x/ibc/07-tendermint/types/errors.go @@ -0,0 +1,15 @@ +package types + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const ( + SubModuleName = "tendermint" +) + +var ( + ErrInvalidTrustingPeriod = sdkerrors.Register(SubModuleName, 1, "invalid trusting period") + ErrInvalidUnbondingPeriod = sdkerrors.Register(SubModuleName, 2, "invalid unbonding period") + ErrInvalidChainID = sdkerrors.Register(SubModuleName, 3, "invalid chain ID") +) diff --git a/x/ibc/07-tendermint/evidence.go b/x/ibc/07-tendermint/types/evidence.go similarity index 91% rename from x/ibc/07-tendermint/evidence.go rename to x/ibc/07-tendermint/types/evidence.go index 82b78ea03370..d161c10ed5dc 100644 --- a/x/ibc/07-tendermint/evidence.go +++ b/x/ibc/07-tendermint/types/evidence.go @@ -1,4 +1,4 @@ -package tendermint +package types import ( "math" @@ -24,11 +24,10 @@ var ( // Evidence is a wrapper over tendermint's DuplicateVoteEvidence // that implements Evidence interface expected by ICS-02 type Evidence struct { - ClientID string `json:"client_id" yaml:"client_id"` - FromValidatorSet *tmtypes.ValidatorSet `json:"from_validator_set" yaml:"from_validator_set"` - Header1 Header `json:"header1" yaml:"header1"` - Header2 Header `json:"header2" yaml:"header2"` - ChainID string `json:"chain_id" yaml:"chain_id"` + ClientID string `json:"client_id" yaml:"client_id"` + Header1 Header `json:"header1" yaml:"header1"` + Header2 Header `json:"header2" yaml:"header2"` + ChainID string `json:"chain_id" yaml:"chain_id"` } // ClientType is Tendermint light client diff --git a/x/ibc/07-tendermint/types/evidence_test.go b/x/ibc/07-tendermint/types/evidence_test.go new file mode 100644 index 000000000000..2a7384224896 --- /dev/null +++ b/x/ibc/07-tendermint/types/evidence_test.go @@ -0,0 +1,186 @@ +package types_test + +import ( + "bytes" + + "github.com/tendermint/tendermint/crypto/tmhash" + tmbytes "github.com/tendermint/tendermint/libs/bytes" + tmtypes "github.com/tendermint/tendermint/types" + + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" +) + +func (suite *TendermintTestSuite) TestEvidence() { + signers := []tmtypes.PrivValidator{suite.privVal} + + ev := ibctmtypes.Evidence{ + Header1: suite.header, + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, suite.valSet, signers), + ChainID: chainID, + ClientID: "gaiamainnet", + } + + suite.Require().Equal(ev.ClientType(), clientexported.Tendermint) + suite.Require().Equal(ev.GetClientID(), "gaiamainnet") + suite.Require().Equal(ev.Route(), "client") + suite.Require().Equal(ev.Type(), "client_misbehaviour") + suite.Require().Equal(ev.Hash(), tmbytes.HexBytes(tmhash.Sum(ibctmtypes.SubModuleCdc.MustMarshalBinaryBare(ev)))) + suite.Require().Equal(ev.GetHeight(), int64(height)) +} + +func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), height) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + + signers := []tmtypes.PrivValidator{suite.privVal} + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} + } + + altSigners := []tmtypes.PrivValidator{altPrivVal} + + testCases := []struct { + name string + evidence ibctmtypes.Evidence + malleateEvidence func(ev *ibctmtypes.Evidence) error + expPass bool + }{ + { + "valid evidence", + ibctmtypes.Evidence{ + Header1: suite.header, + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, bothValSet, signers), + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *ibctmtypes.Evidence) error { return nil }, + true, + }, + { + "invalid client ID ", + ibctmtypes.Evidence{ + Header1: suite.header, + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, bothValSet, signers), + ChainID: chainID, + ClientID: "GAIA", + }, + func(ev *ibctmtypes.Evidence) error { return nil }, + false, + }, + { + "wrong chainID on header1", + ibctmtypes.Evidence{ + Header1: suite.header, + Header2: ibctmtypes.CreateTestHeader("ethermint", height, suite.now, suite.valSet, bothValSet, signers), + ChainID: "ethermint", + ClientID: "gaiamainnet", + }, + func(ev *ibctmtypes.Evidence) error { return nil }, + false, + }, + { + "wrong chainID on header2", + ibctmtypes.Evidence{ + Header1: suite.header, + Header2: ibctmtypes.CreateTestHeader("ethermint", height, suite.now, suite.valSet, bothValSet, signers), + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *ibctmtypes.Evidence) error { return nil }, + false, + }, + { + "mismatched heights", + ibctmtypes.Evidence{ + Header1: suite.header, + Header2: ibctmtypes.CreateTestHeader(chainID, 6, suite.now, suite.valSet, bothValSet, signers), + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *ibctmtypes.Evidence) error { return nil }, + false, + }, + { + "same block id", + ibctmtypes.Evidence{ + Header1: suite.header, + Header2: suite.header, + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *ibctmtypes.Evidence) error { return nil }, + false, + }, + { + "header 1 doesn't have 2/3 majority", + ibctmtypes.Evidence{ + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.header, + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *ibctmtypes.Evidence) error { + // voteSet contains only altVal which is less than 2/3 of total power (height/1height) + wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header1.Height, 1, tmtypes.PrecommitType, altValSet) + var err error + ev.Header1.Commit, err = tmtypes.MakeCommit(ev.Header1.Commit.BlockID, ev.Header2.Height, ev.Header1.Commit.Round, wrongVoteSet, altSigners) + return err + }, + false, + }, + { + "header 2 doesn't have 2/3 majority", + ibctmtypes.Evidence{ + Header1: suite.header, + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *ibctmtypes.Evidence) error { + // voteSet contains only altVal which is less than 2/3 of total power (height/1height) + wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header2.Height, 1, tmtypes.PrecommitType, altValSet) + var err error + ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round, wrongVoteSet, altSigners) + return err + }, + false, + }, + { + "validators sign off on wrong commit", + ibctmtypes.Evidence{ + Header1: suite.header, + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + ChainID: chainID, + ClientID: "gaiamainnet", + }, + func(ev *ibctmtypes.Evidence) error { + ev.Header2.Commit.BlockID = ibctmtypes.MakeBlockID(tmhash.Sum([]byte("other_hash")), 3, tmhash.Sum([]byte("other_partset"))) + return nil + }, + false, + }, + } + + for i, tc := range testCases { + tc := tc + + err := tc.malleateEvidence(&tc.evidence) + suite.Require().NoError(err) + + if tc.expPass { + suite.Require().NoError(tc.evidence.ValidateBasic(), "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(tc.evidence.ValidateBasic(), "invalid test case %d passed: %s", i, tc.name) + } + } +} diff --git a/x/ibc/07-tendermint/header.go b/x/ibc/07-tendermint/types/header.go similarity index 95% rename from x/ibc/07-tendermint/header.go rename to x/ibc/07-tendermint/types/header.go index 4a8dbccce4b4..bc426a24ac5b 100644 --- a/x/ibc/07-tendermint/header.go +++ b/x/ibc/07-tendermint/types/header.go @@ -1,4 +1,4 @@ -package tendermint +package types import ( abci "github.com/tendermint/tendermint/abci/types" @@ -26,8 +26,9 @@ func (h Header) ClientType() clientexported.ClientType { // ConsensusState returns the consensus state associated with the header func (h Header) ConsensusState() ConsensusState { return ConsensusState{ - Root: commitment.NewRoot(h.AppHash), - ValidatorSetHash: h.ValidatorSet.Hash(), + Timestamp: h.Time, + Root: commitment.NewRoot(h.AppHash), + ValidatorSet: h.ValidatorSet, } } diff --git a/x/ibc/07-tendermint/header_test.go b/x/ibc/07-tendermint/types/header_test.go similarity index 80% rename from x/ibc/07-tendermint/header_test.go rename to x/ibc/07-tendermint/types/header_test.go index e88362d230d3..c5c004028a7f 100644 --- a/x/ibc/07-tendermint/header_test.go +++ b/x/ibc/07-tendermint/types/header_test.go @@ -1,20 +1,20 @@ -package tendermint_test +package types_test import ( clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) func (suite *TendermintTestSuite) TestHeaderValidateBasic() { testCases := []struct { name string - header tendermint.Header + header ibctmtypes.Header chainID string expPass bool }{ {"valid header", suite.header, chainID, true}, {"signed header basic validation failed", suite.header, "chainID", false}, - {"validator set nil", tendermint.Header{suite.header.SignedHeader, nil}, chainID, false}, + {"validator set nil", ibctmtypes.Header{suite.header.SignedHeader, nil}, chainID, false}, } suite.Require().Equal(clientexported.Tendermint, suite.header.ClientType()) diff --git a/x/ibc/02-client/types/msgs.go b/x/ibc/07-tendermint/types/msgs.go similarity index 50% rename from x/ibc/02-client/types/msgs.go rename to x/ibc/07-tendermint/types/msgs.go index 2790d8d18884..cc065a6ec308 100644 --- a/x/ibc/02-client/types/msgs.go +++ b/x/ibc/07-tendermint/types/msgs.go @@ -1,9 +1,13 @@ package types import ( + "strings" + "time" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -15,23 +19,31 @@ const ( TypeClientMisbehaviour string = "client_misbehaviour" ) -var _ sdk.Msg = MsgCreateClient{} +var _ clientexported.MsgCreateClient = MsgCreateClient{} +var _ clientexported.MsgUpdateClient = MsgUpdateClient{} // MsgCreateClient defines a message to create an IBC client type MsgCreateClient struct { - ClientID string `json:"client_id" yaml:"client_id"` - ClientType string `json:"client_type" yaml:"client_type"` - ConsensusState exported.ConsensusState `json:"consensus_state" yaml:"consensus_address"` - Signer sdk.AccAddress `json:"address" yaml:"address"` + ClientID string `json:"client_id" yaml:"client_id"` + ChainID string `json:"chain_id" yaml:"chain_id"` + ConsensusState ConsensusState `json:"consensus_state" yaml:"consensus_state"` + TrustingPeriod time.Duration `json:"trusting_period" yaml:"trusting_period"` + UnbondingPeriod time.Duration `json:"unbonding_period" yaml:"unbonding_period"` + Signer sdk.AccAddress `json:"address" yaml:"address"` } // NewMsgCreateClient creates a new MsgCreateClient instance -func NewMsgCreateClient(id, clientType string, consensusState exported.ConsensusState, signer sdk.AccAddress) MsgCreateClient { +func NewMsgCreateClient( + id string, chainID string, consensusState ConsensusState, + trustingPeriod, unbondingPeriod time.Duration, signer sdk.AccAddress, +) MsgCreateClient { return MsgCreateClient{ - ClientID: id, - ClientType: clientType, - ConsensusState: consensusState, - Signer: signer, + ClientID: id, + ChainID: chainID, + ConsensusState: consensusState, + TrustingPeriod: trustingPeriod, + UnbondingPeriod: unbondingPeriod, + Signer: signer, } } @@ -47,15 +59,18 @@ func (msg MsgCreateClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgCreateClient) ValidateBasic() error { - if clientType := exported.ClientTypeFromString(msg.ClientType); clientType == 0 { - return sdkerrors.Wrap(ErrInvalidClientType, msg.ClientType) - } - if msg.ConsensusState == nil { - return ErrInvalidConsensus + if strings.TrimSpace(msg.ChainID) == "" { + return sdkerrors.Wrap(ErrInvalidChainID, "cannot have empty chain-id") } if err := msg.ConsensusState.ValidateBasic(); err != nil { return err } + if msg.TrustingPeriod == 0 { + return sdkerrors.Wrap(ErrInvalidTrustingPeriod, "duration cannot be 0") + } + if msg.UnbondingPeriod == 0 { + return sdkerrors.Wrap(ErrInvalidUnbondingPeriod, "duration cannot be 0") + } if msg.Signer.Empty() { return sdkerrors.ErrInvalidAddress } @@ -72,17 +87,30 @@ func (msg MsgCreateClient) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Signer} } -var _ sdk.Msg = MsgUpdateClient{} +// GetClientID implements clientexported.MsgCreateClient +func (msg MsgCreateClient) GetClientID() string { + return msg.ClientID +} + +// GetClientType implements clientexported.MsgCreateClient +func (msg MsgCreateClient) GetClientType() string { + return clientexported.ClientTypeTendermint +} + +// GetConsensusState implements clientexported.MsgCreateClient +func (msg MsgCreateClient) GetConsensusState() clientexported.ConsensusState { + return msg.ConsensusState +} // MsgUpdateClient defines a message to update an IBC client type MsgUpdateClient struct { - ClientID string `json:"client_id" yaml:"client_id"` - Header exported.Header `json:"header" yaml:"header"` - Signer sdk.AccAddress `json:"address" yaml:"address"` + ClientID string `json:"client_id" yaml:"client_id"` + Header Header `json:"header" yaml:"header"` + Signer sdk.AccAddress `json:"address" yaml:"address"` } // NewMsgUpdateClient creates a new MsgUpdateClient instance -func NewMsgUpdateClient(id string, header exported.Header, signer sdk.AccAddress) MsgUpdateClient { +func NewMsgUpdateClient(id string, header Header, signer sdk.AccAddress) MsgUpdateClient { return MsgUpdateClient{ ClientID: id, Header: header, @@ -102,9 +130,6 @@ func (msg MsgUpdateClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgUpdateClient) ValidateBasic() error { - if msg.Header == nil { - return ErrInvalidHeader - } if msg.Signer.Empty() { return sdkerrors.ErrInvalidAddress } @@ -120,3 +145,13 @@ func (msg MsgUpdateClient) GetSignBytes() []byte { func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Signer} } + +// GetClientID implements clientexported.MsgUpdateClient +func (msg MsgUpdateClient) GetClientID() string { + return msg.ClientID +} + +// GetHeader implements clientexported.MsgUpdateClient +func (msg MsgUpdateClient) GetHeader() clientexported.Header { + return msg.Header +} diff --git a/x/ibc/07-tendermint/types/msgs_test.go b/x/ibc/07-tendermint/types/msgs_test.go new file mode 100644 index 000000000000..6ea7eac33828 --- /dev/null +++ b/x/ibc/07-tendermint/types/msgs_test.go @@ -0,0 +1,80 @@ +package types_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/crypto/secp256k1" + tmtypes "github.com/tendermint/tendermint/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func TestMsgCreateClientValidateBasic(t *testing.T) { + validator := tmtypes.NewValidator(tmtypes.NewMockPV().GetPubKey(), 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + cs := ibctmtypes.ConsensusState{ + Height: height, + Timestamp: now, + Root: commitment.NewRoot([]byte("root")), + ValidatorSet: valSet, + } + privKey := secp256k1.GenPrivKey() + signer := sdk.AccAddress(privKey.PubKey().Address()) + chainID := "gaia" + + cases := []struct { + msg ibctmtypes.MsgCreateClient + expPass bool + errMsg string + }{ + {ibctmtypes.NewMsgCreateClient(exported.ClientTypeTendermint, chainID, cs, trustingPeriod, ubdPeriod, signer), true, "success msg should pass"}, + {ibctmtypes.NewMsgCreateClient("BADCHAIN", chainID, cs, trustingPeriod, ubdPeriod, signer), false, "invalid client id passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", chainID, cs, trustingPeriod, ubdPeriod, signer), false, "unregistered client type passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", chainID, ibctmtypes.ConsensusState{}, trustingPeriod, ubdPeriod, signer), false, "invalid Consensus State in msg passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", chainID, cs, 0, ubdPeriod, signer), false, "zero trusting period passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", chainID, cs, trustingPeriod, 0, signer), false, "zero unbonding period passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", chainID, cs, trustingPeriod, ubdPeriod, nil), false, "Empty address passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", "", cs, trustingPeriod, ubdPeriod, nil), false, "Empty chain ID"}, + } + + for i, tc := range cases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "Msg %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} + +func TestMsgUpdateClient(t *testing.T) { + privKey := secp256k1.GenPrivKey() + signer := sdk.AccAddress(privKey.PubKey().Address()) + + cases := []struct { + msg ibctmtypes.MsgUpdateClient + expPass bool + errMsg string + }{ + {ibctmtypes.NewMsgUpdateClient(exported.ClientTypeTendermint, ibctmtypes.Header{}, signer), true, "success msg should pass"}, + {ibctmtypes.NewMsgUpdateClient("badClient", ibctmtypes.Header{}, signer), false, "invalid client id passed"}, + {ibctmtypes.NewMsgUpdateClient(exported.ClientTypeTendermint, ibctmtypes.Header{}, nil), false, "Empty address passed"}, + } + + for i, tc := range cases { + err := tc.msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "Msg %d failed: %v", i, err) + } else { + require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + } + } +} diff --git a/x/ibc/07-tendermint/types/tendermint_test.go b/x/ibc/07-tendermint/types/tendermint_test.go new file mode 100644 index 000000000000..d4d71cc91ce2 --- /dev/null +++ b/x/ibc/07-tendermint/types/tendermint_test.go @@ -0,0 +1,48 @@ +package types_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/suite" + + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/codec" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +const ( + chainID = "gaia" + height = 4 + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 +) + +type TendermintTestSuite struct { + suite.Suite + + cdc *codec.Codec + privVal tmtypes.PrivValidator + valSet *tmtypes.ValidatorSet + header ibctmtypes.Header + now time.Time +} + +func (suite *TendermintTestSuite) SetupTest() { + suite.cdc = codec.New() + codec.RegisterCrypto(suite.cdc) + ibctmtypes.RegisterCodec(suite.cdc) + commitment.RegisterCodec(suite.cdc) + + suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + suite.privVal = tmtypes.NewMockPV() + val := tmtypes.NewValidator(suite.privVal.GetPubKey(), 10) + suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) + suite.header = ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) +} + +func TestTendermintTestSuite(t *testing.T) { + suite.Run(t, new(TendermintTestSuite)) +} diff --git a/x/ibc/07-tendermint/test_utils.go b/x/ibc/07-tendermint/types/test_utils.go similarity index 87% rename from x/ibc/07-tendermint/test_utils.go rename to x/ibc/07-tendermint/types/test_utils.go index 32373fab3fd6..bd538bc4871b 100644 --- a/x/ibc/07-tendermint/test_utils.go +++ b/x/ibc/07-tendermint/types/test_utils.go @@ -1,4 +1,4 @@ -package tendermint +package types import ( "math" @@ -21,10 +21,9 @@ func MakeBlockID(hash []byte, partSetSize int, partSetHash []byte) tmtypes.Block } // CreateTestHeader creates a mock header for testing only. -func CreateTestHeader(chainID string, height int64, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { +func CreateTestHeader(chainID string, height int64, timestamp time.Time, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { vsetHash := valSet.Hash() nextHash := nextValSet.Hash() - timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) tmHeader := tmtypes.Header{ Version: version.Consensus{Block: 2, App: 2}, ChainID: chainID, diff --git a/x/ibc/07-tendermint/update.go b/x/ibc/07-tendermint/update.go index 262443165637..b9bfebca401c 100644 --- a/x/ibc/07-tendermint/update.go +++ b/x/ibc/07-tendermint/update.go @@ -1,9 +1,13 @@ package tendermint import ( + "errors" + "time" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -17,23 +21,24 @@ import ( // Tendermint client validity checking uses the bisection algorithm described // in the [Tendermint spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md). func CheckValidityAndUpdateState( - clientState clientexported.ClientState, header clientexported.Header, chainID string, + clientState clientexported.ClientState, header clientexported.Header, + currentTimestamp time.Time, ) (clientexported.ClientState, clientexported.ConsensusState, error) { - tmClientState, ok := clientState.(ClientState) + tmClientState, ok := clientState.(types.ClientState) if !ok { return nil, nil, sdkerrors.Wrap( clienttypes.ErrInvalidClientType, "light client is not from Tendermint", ) } - tmHeader, ok := header.(Header) + tmHeader, ok := header.(types.Header) if !ok { return nil, nil, sdkerrors.Wrap( clienttypes.ErrInvalidHeader, "header is not from Tendermint", ) } - if err := checkValidity(tmClientState, tmHeader, chainID); err != nil { + if err := checkValidity(tmClientState, tmHeader, currentTimestamp); err != nil { return nil, nil, err } @@ -41,19 +46,44 @@ func CheckValidityAndUpdateState( return tmClientState, consensusState, nil } -// checkValidity checks if the Tendermint header is valid +// checkValidity checks if the Tendermint header is valid. // // CONTRACT: assumes header.Height > consensusState.Height -func checkValidity(clientState ClientState, header Header, chainID string) error { - if header.GetHeight() < clientState.LatestHeight { +func checkValidity( + clientState types.ClientState, header types.Header, currentTimestamp time.Time, +) error { + // assert trusting period has not yet passed + if currentTimestamp.Sub(clientState.LatestTimestamp) >= clientState.TrustingPeriod { + return errors.New("trusting period since last client timestamp already passed") + } + + // assert header timestamp is not in the future (& transitively that is not past the trusting period) + if header.Time.Unix() > currentTimestamp.Unix() { + return sdkerrors.Wrap( + clienttypes.ErrInvalidHeader, + "header blocktime can't be in the future", + ) + } + + // assert header timestamp is past current timestamp + if header.Time.Unix() <= clientState.LatestTimestamp.Unix() { + return sdkerrors.Wrapf( + clienttypes.ErrInvalidHeader, + "header blocktime ≤ latest client state block time (%s ≤ %s)", + header.Time.String(), clientState.LatestTimestamp.String(), + ) + } + + // assert header height is newer than any we know + if header.GetHeight() <= clientState.LatestHeight { return sdkerrors.Wrapf( clienttypes.ErrInvalidHeader, - "header height < latest client state height (%d < %d)", header.GetHeight(), clientState.LatestHeight, + "header height ≤ latest client state height (%d ≤ %d)", header.GetHeight(), clientState.LatestHeight, ) } // basic consistency check - if err := header.ValidateBasic(chainID); err != nil { + if err := header.ValidateBasic(clientState.ChainID); err != nil { return err } @@ -61,11 +91,12 @@ func checkValidity(clientState ClientState, header Header, chainID string) error } // update the consensus state from a new header -func update(clientState ClientState, header Header) (ClientState, ConsensusState) { +func update(clientState types.ClientState, header types.Header) (types.ClientState, types.ConsensusState) { clientState.LatestHeight = header.GetHeight() - consensusState := ConsensusState{ - Root: commitment.NewRoot(header.AppHash), - ValidatorSetHash: header.ValidatorSet.Hash(), + consensusState := types.ConsensusState{ + Timestamp: header.Time, + Root: commitment.NewRoot(header.AppHash), + ValidatorSet: header.ValidatorSet, } return clientState, consensusState diff --git a/x/ibc/07-tendermint/update_test.go b/x/ibc/07-tendermint/update_test.go index 7e46a97da17a..5c465c398335 100644 --- a/x/ibc/07-tendermint/update_test.go +++ b/x/ibc/07-tendermint/update_test.go @@ -2,32 +2,29 @@ package tendermint_test import ( tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) func (suite *TendermintTestSuite) TestCheckValidity() { testCases := []struct { name string - clientState tendermint.ClientState - chainID string + clientState ibctmtypes.ClientState expPass bool }{ { name: "successful update", - clientState: tendermint.NewClientState(chainID, height), - chainID: chainID, + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.clientTime), expPass: true, }, { name: "header basic validation failed", - clientState: tendermint.NewClientState(chainID, height), - chainID: "cosmoshub", + clientState: ibctmtypes.NewClientState(chainID, "cosmoshub", trustingPeriod, ubdPeriod, height, suite.clientTime), expPass: false, }, { name: "header height < latest client height", - clientState: tendermint.NewClientState(chainID, height+1), - chainID: chainID, + clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height+1, suite.clientTime), expPass: false, }, } @@ -35,12 +32,13 @@ func (suite *TendermintTestSuite) TestCheckValidity() { for i, tc := range testCases { tc := tc - expectedConsensus := tendermint.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSetHash: suite.header.ValidatorSet.Hash(), + expectedConsensus := ibctmtypes.ConsensusState{ + Timestamp: suite.headerTime, + Root: commitment.NewRoot(suite.header.AppHash), + ValidatorSet: suite.header.ValidatorSet, } - clientState, consensusState, err := tendermint.CheckValidityAndUpdateState(tc.clientState, suite.header, tc.chainID) + clientState, consensusState, err := tendermint.CheckValidityAndUpdateState(tc.clientState, suite.header, suite.now) if tc.expPass { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index fc936f1471b8..e792a9eded06 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -3,6 +3,7 @@ package transfer_test import ( "fmt" "testing" + "time" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" @@ -16,7 +17,7 @@ import ( connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" @@ -38,6 +39,9 @@ const ( testChannelOrder = channelexported.UNORDERED testChannelVersion = "1.0" + + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) // define variables used for testing @@ -83,12 +87,14 @@ func (suite *HandlerTestSuite) createClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - consensusState := tendermint.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState := ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, } - _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + clientState, err := ibctmtypes.Initialize(testClient, testClient, consensusState, trustingPeriod, ubdPeriod) + suite.NoError(err) + _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) suite.NoError(err) } @@ -100,7 +106,7 @@ func (suite *HandlerTestSuite) updateClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - state := tendermint.ConsensusState{ + state := ibctmtypes.ConsensusState{ Root: commitment.NewRoot(commitID.Hash), } diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index af4ea22a8e64..4953bb8d2e47 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "fmt" "testing" + "time" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" @@ -32,6 +33,9 @@ const ( testChannelOrder = channelexported.UNORDERED testChannelVersion = "1.0" + + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) // define variables used for testing diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index a9c6ebd0a3f6..31357c6637e3 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -10,7 +10,7 @@ import ( connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -24,12 +24,14 @@ func (suite *KeeperTestSuite) createClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - consensusState := tendermint.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState := ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, } - _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) + clientState, err := ibctmtypes.Initialize(testClient, testClient, consensusState, trustingPeriod, ubdPeriod) + suite.NoError(err) + _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) suite.NoError(err) } @@ -41,7 +43,7 @@ func (suite *KeeperTestSuite) updateClient() { suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - state := tendermint.ConsensusState{ + state := ibctmtypes.ConsensusState{ Root: commitment.NewRoot(commitID.Hash), } diff --git a/x/ibc/ante/ante.go b/x/ibc/ante/ante.go index 7895c2655279..97f9a99a630f 100644 --- a/x/ibc/ante/ante.go +++ b/x/ibc/ante/ante.go @@ -3,6 +3,7 @@ package ante import ( sdk "github.com/cosmos/cosmos-sdk/types" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" ) @@ -28,8 +29,8 @@ func (pvr ProofVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim for _, msg := range tx.GetMsgs() { var err error switch msg := msg.(type) { - case client.MsgUpdateClient: - err = pvr.clientKeeper.UpdateClient(ctx, msg.ClientID, msg.Header) + case clientexported.MsgUpdateClient: + err = pvr.clientKeeper.UpdateClient(ctx, msg.GetClientID(), msg.GetHeader()) case channel.MsgPacket: _, err = pvr.channelKeeper.RecvPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight) case channel.MsgAcknowledgement: diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go index eaf62c619de8..6148a01f8c33 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/ante/ante_test.go @@ -3,6 +3,7 @@ package ante_test import ( "fmt" "testing" + "time" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" @@ -18,7 +19,8 @@ import ( channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/ante" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -33,6 +35,9 @@ const ( testConnection = "testconnection" testChannelVersion = "1.0" + + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) // define variables used for testing @@ -43,11 +48,13 @@ type HandlerTestSuite struct { ctx sdk.Context app *simapp.SimApp valSet *tmtypes.ValidatorSet + now time.Time } func (suite *HandlerTestSuite) SetupTest() { isCheckTx := false app := simapp.Setup(isCheckTx) + suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) suite.cdc = app.Codec() suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) @@ -65,17 +72,20 @@ func (suite *HandlerTestSuite) SetupTest() { func (suite *HandlerTestSuite) createClient() { suite.app.Commit() commitID := suite.app.LastCommitID() + now2 := suite.now.Add(time.Hour) - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1, Time: now2}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - consensusState := tendermint.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - ValidatorSetHash: suite.valSet.Hash(), + consensusState := ibctmtypes.ConsensusState{ + Timestamp: suite.now, + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, } - _, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, testClient, testClientType, consensusState) - suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, uint64(suite.app.LastBlockHeight()), consensusState) + clientState, err := ibctmtypes.Initialize(testClient, testClient, consensusState, trustingPeriod, ubdPeriod) + suite.NoError(err) + _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) suite.NoError(err) } @@ -85,16 +95,18 @@ func (suite *HandlerTestSuite) updateClient() { commitID := suite.app.LastCommitID() height := suite.app.LastBlockHeight() + 1 - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: height}}) + suite.now = suite.now.Add(time.Minute) + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: height, Time: suite.now}}) suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - state := tendermint.ConsensusState{ + state := ibctmtypes.ConsensusState{ Root: commitment.NewRoot(commitID.Hash), } suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, uint64(height-1), state) csi, _ := suite.app.IBCKeeper.ClientKeeper.GetClientState(suite.ctx, testClient) - cs, _ := csi.(tendermint.ClientState) + cs, _ := csi.(ibctmtypes.ClientState) cs.LatestHeight = uint64(height - 1) suite.app.IBCKeeper.ClientKeeper.SetClientState(suite.ctx, cs) } diff --git a/x/ibc/client/cli/cli.go b/x/ibc/client/cli/cli.go index 6a98669c858e..c42fbc8aa98e 100644 --- a/x/ibc/client/cli/cli.go +++ b/x/ibc/client/cli/cli.go @@ -9,6 +9,7 @@ import ( ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + tmclient "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -23,7 +24,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { } ibcTxCmd.AddCommand(flags.PostCommands( - ibcclient.GetTxCmd(cdc, storeKey), + tmclient.GetTxCmd(cdc, storeKey), connection.GetTxCmd(cdc, storeKey), channel.GetTxCmd(cdc, storeKey), )...) diff --git a/x/ibc/handler.go b/x/ibc/handler.go index eb6705888f81..1a3f5843f01f 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -4,6 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" ) @@ -14,11 +15,11 @@ func NewHandler(k Keeper) sdk.Handler { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { - // IBC client msgs - case client.MsgCreateClient: + // IBC client msg interface types + case clientexported.MsgCreateClient: return client.HandleMsgCreateClient(ctx, k.ClientKeeper, msg) - case client.MsgUpdateClient: + case clientexported.MsgUpdateClient: return &sdk.Result{}, nil // IBC connection msgs diff --git a/x/ibc/module.go b/x/ibc/module.go index 2cab265d4b6e..904820f52c06 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -15,7 +15,7 @@ import ( client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/client/rest" @@ -43,7 +43,7 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { client.RegisterCodec(cdc) connection.RegisterCodec(cdc) channel.RegisterCodec(cdc) - tendermint.RegisterCodec(cdc) + ibctmtypes.RegisterCodec(cdc) commitment.RegisterCodec(cdc) } diff --git a/x/staking/types/types.pb.go b/x/staking/types/types.pb.go index 78da36fae466..4e3b2d75b64f 100644 --- a/x/staking/types/types.pb.go +++ b/x/staking/types/types.pb.go @@ -6,6 +6,11 @@ package types import ( bytes "bytes" fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + time "time" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" _ "github.com/gogo/protobuf/gogoproto" @@ -14,10 +19,6 @@ import ( _ "github.com/golang/protobuf/ptypes/duration" _ "github.com/golang/protobuf/ptypes/timestamp" types1 "github.com/tendermint/tendermint/abci/types" - io "io" - math "math" - math_bits "math/bits" - time "time" ) // Reference imports to suppress errors if they are not otherwise used. From d25f3d31c6980b248885be44b95088d68e1794ac Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 18 Feb 2020 15:31:16 +0100 Subject: [PATCH 084/176] IBC SDK specification (#5426) * IBC SDK specification * update events * add implementation mapping * minor additions to readme * fix conflicts * add missing ADRs, modules and ICS --- docs/spec/ibc/README.md | 3 - x/ibc/03-connection/handler.go | 14 +-- x/ibc/03-connection/types/events.go | 1 + x/ibc/04-channel/handler.go | 19 ++-- x/ibc/04-channel/types/events.go | 9 +- x/ibc/spec/01_concepts.md | 8 ++ x/ibc/spec/02_state.md | 21 ++++ x/ibc/spec/04_messages.md | 80 +++++++++++++++ x/ibc/spec/05_callbacks.md | 5 + x/ibc/spec/06_events.md | 147 ++++++++++++++++++++++++++++ x/ibc/spec/README.md | 106 ++++++++++++++++++++ 11 files changed, 393 insertions(+), 20 deletions(-) delete mode 100644 docs/spec/ibc/README.md create mode 100644 x/ibc/spec/01_concepts.md create mode 100644 x/ibc/spec/02_state.md create mode 100644 x/ibc/spec/04_messages.md create mode 100644 x/ibc/spec/05_callbacks.md create mode 100644 x/ibc/spec/06_events.md create mode 100644 x/ibc/spec/README.md diff --git a/docs/spec/ibc/README.md b/docs/spec/ibc/README.md deleted file mode 100644 index e763c2760caa..000000000000 --- a/docs/spec/ibc/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Cosmos Inter-Blockchain Communication (IBC) Protocol - -__Disclaimer__ This module has been removed from the repository for the time being. If you would like to follow the process of IBC, go to [ICS repo](https://github.com/cosmos/ics), there you will find the standard and updates. \ No newline at end of file diff --git a/x/ibc/03-connection/handler.go b/x/ibc/03-connection/handler.go index 0350fa699f2d..1cc1603ccc6c 100644 --- a/x/ibc/03-connection/handler.go +++ b/x/ibc/03-connection/handler.go @@ -14,9 +14,10 @@ func HandleMsgConnectionOpenInit(ctx sdk.Context, k Keeper, msg MsgConnectionOpe ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( - EventTypeConnectionOpenInit, - sdk.NewAttribute(AttributeKeyConnectionID, msg.ConnectionID), - sdk.NewAttribute(AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), + types.EventTypeConnectionOpenInit, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + sdk.NewAttribute(types.AttributeKeyClientID, msg.ClientID), + sdk.NewAttribute(types.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), ), sdk.NewEvent( sdk.EventTypeMessage, @@ -42,9 +43,10 @@ func HandleMsgConnectionOpenTry(ctx sdk.Context, k Keeper, msg MsgConnectionOpen ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( - EventTypeConnectionOpenTry, - sdk.NewAttribute(AttributeKeyConnectionID, msg.ConnectionID), - sdk.NewAttribute(AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), + types.EventTypeConnectionOpenTry, + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.ConnectionID), + sdk.NewAttribute(types.AttributeKeyClientID, msg.ClientID), + sdk.NewAttribute(types.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientID), ), sdk.NewEvent( sdk.EventTypeMessage, diff --git a/x/ibc/03-connection/types/events.go b/x/ibc/03-connection/types/events.go index 2ede46db907c..92a73afbebd3 100644 --- a/x/ibc/03-connection/types/events.go +++ b/x/ibc/03-connection/types/events.go @@ -9,6 +9,7 @@ import ( // IBC connection events const ( AttributeKeyConnectionID = "connection_id" + AttributeKeyClientID = "client_id" AttributeKeyCounterpartyClientID = "counterparty_client_id" ) diff --git a/x/ibc/04-channel/handler.go b/x/ibc/04-channel/handler.go index fb35ef8e5fbe..6b602e08ec87 100644 --- a/x/ibc/04-channel/handler.go +++ b/x/ibc/04-channel/handler.go @@ -19,8 +19,11 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCha ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenInit, - sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyPortID, msg.PortID), sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), + sdk.NewAttribute(types.AttributeCounterpartyPortID, msg.Channel.Counterparty.PortID), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, msg.Channel.Counterparty.ChannelID), + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.Channel.ConnectionHops[0]), // TODO: iterate ), sdk.NewEvent( sdk.EventTypeMessage, @@ -46,9 +49,11 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenTry, + sdk.NewAttribute(types.AttributeKeyPortID, msg.PortID), sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), - sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), // TODO: double check sender and receiver - sdk.NewAttribute(types.AttributeKeyReceiverPort, msg.Channel.Counterparty.PortID), + sdk.NewAttribute(types.AttributeCounterpartyPortID, msg.Channel.Counterparty.PortID), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, msg.Channel.Counterparty.ChannelID), + sdk.NewAttribute(types.AttributeKeyConnectionID, msg.Channel.ConnectionHops[0]), // TODO: iterate ), sdk.NewEvent( sdk.EventTypeMessage, @@ -74,7 +79,7 @@ func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenAck, - sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyPortID, msg.PortID), sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), ), sdk.NewEvent( @@ -99,7 +104,7 @@ func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Msg ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenConfirm, - sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyPortID, msg.PortID), sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), ), sdk.NewEvent( @@ -124,7 +129,7 @@ func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCh ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelCloseInit, - sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyPortID, msg.PortID), sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), ), sdk.NewEvent( @@ -149,7 +154,7 @@ func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Ms ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelCloseConfirm, - sdk.NewAttribute(types.AttributeKeySenderPort, msg.PortID), + sdk.NewAttribute(types.AttributeKeyPortID, msg.PortID), sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelID), ), sdk.NewEvent( diff --git a/x/ibc/04-channel/types/events.go b/x/ibc/04-channel/types/events.go index b82b3e8700cf..212f8e254d9f 100644 --- a/x/ibc/04-channel/types/events.go +++ b/x/ibc/04-channel/types/events.go @@ -8,10 +8,11 @@ import ( // IBC channel events const ( - AttributeKeySenderPort = "sender_port" - AttributeKeyReceiverPort = "receiver_port" - AttributeKeyChannelID = "channel_id" - AttributeKeySequence = "sequence" + AttributeKeyConnectionID = "connection_id" + AttributeKeyPortID = "port_id" + AttributeKeyChannelID = "channel_id" + AttributeCounterpartyPortID = "counterparty_port_id" + AttributeCounterpartyChannelID = "counterparty_channel_id" ) // IBC channel events vars diff --git a/x/ibc/spec/01_concepts.md b/x/ibc/spec/01_concepts.md new file mode 100644 index 000000000000..907893de27e4 --- /dev/null +++ b/x/ibc/spec/01_concepts.md @@ -0,0 +1,8 @@ + + +# Concepts + +> NOTE: if you are not familiar with the IBC terminology and concepts, please read +this [document](https://github.com/cosmos/ics/blob/master/ibc/1_IBC_TERMINOLOGY.md) as prerequisite reading. diff --git a/x/ibc/spec/02_state.md b/x/ibc/spec/02_state.md new file mode 100644 index 000000000000..b53ece883720 --- /dev/null +++ b/x/ibc/spec/02_state.md @@ -0,0 +1,21 @@ + + +# State + +The paths for the values stored in state can be found [here](https://github.com/cosmos/ics/blob/master/spec/ics-024-host-requirements/README.md#path-space). Additionally, the SDK adds +a prefix to the path to be able to aggregate the values for querying purposes. + +| Prefix | Path | Value type | +|--------|------------------------------------------------------------------------|----------------| +| "0/" | "clients/{identifier}" | ClientState | +| "0/" | "clients/{identifier}/consensusState" | ConsensusState | +| "0/" | "clients/{identifier}/type" | ClientType | +| "0/" | "connections/{identifier}" | ConnectionEnd | +| "0/" | "ports/{identifier}" | CapabilityKey | +| "0/" | "ports/{identifier}/channels/{identifier}" | ChannelEnd | +| "0/" | "ports/{identifier}/channels/{identifier}/key" | CapabilityKey | +| "0/" | "ports/{identifier}/channels/{identifier}/nextSequenceRecv" | uint64 | +| "0/" | "ports/{identifier}/channels/{identifier}/packets/{sequence}" | bytes | +| "0/" | "ports/{identifier}/channels/{identifier}/acknowledgements/{sequence}" | bytes | \ No newline at end of file diff --git a/x/ibc/spec/04_messages.md b/x/ibc/spec/04_messages.md new file mode 100644 index 000000000000..39be055e29fe --- /dev/null +++ b/x/ibc/spec/04_messages.md @@ -0,0 +1,80 @@ + + +# Messages + +In this section we describe the processing of the IBC messages and the corresponding updates to the state. + +## ICS 02 - Client + +### MsgCreateClient + +A light client is created using the `MsgCreateClient`. + +```go +type MsgCreateClient struct { + ClientID string + ClientType string + ConsensusState ConsensusState + Signer AccAddress +} +``` + +This message is expected to fail if: + +- `ClientID` is invalid (not alphanumeric or not within 10-20 characters) +- `ClientType` is not registered +- `ConsensusState` is empty +- `Signer` is empty +- A light client with the provided id and type already exist + +The message creates and stores a light client with the given ID and consensus type, +stores the validator set as the `Commiter` of the given consensus state and stores +both the consensus state and its commitment root (i.e app hash). + +### MsgUpdateClient + +A light client is updated with a new header using the `MsgUpdateClient`. + +```go +type MsgUpdateClient struct { + ClientID string + Header Header + Signer AccAddress +} +``` + +This message is expected to fail if: + +- `ClientID` is invalid (not alphanumeric or not within 10-20 characters) +- `Header` is empty +- `Signer` is empty +- A Client hasn't been created for the given ID +- the header's client type is different from the registered one +- the client is frozen due to misbehaviour and cannot be updated + +The message validates the header and updates the consensus state with the new +height, commitment root and validator sets, which are then stored. + +## ICS 03 - Connection + +## ICS 04 - Channels + +### MsgChannelOpenInit + +A channel handshake is initiated by a chain A using the `MsgChannelOpenInit` +message. + +```go +type MsgChannelOpenInit struct { + PortID string + ChannelID string + Channel Channel + Signer sdk.AccAddress +} +``` + +This message is expected to fail if: + +## ICS 20 - Fungible Token Transfer diff --git a/x/ibc/spec/05_callbacks.md b/x/ibc/spec/05_callbacks.md new file mode 100644 index 000000000000..cf77d8ec3688 --- /dev/null +++ b/x/ibc/spec/05_callbacks.md @@ -0,0 +1,5 @@ + + +# Callbacks diff --git a/x/ibc/spec/06_events.md b/x/ibc/spec/06_events.md new file mode 100644 index 000000000000..e333e8af07d4 --- /dev/null +++ b/x/ibc/spec/06_events.md @@ -0,0 +1,147 @@ + + +# Events + +The IBC module emits the following events: + +## ICS 02 - Client + +### MsgCreateClient + +| Type | Attribute Key | Attribute Value | +|---------------|---------------|-----------------| +| create_client | client_id | {clientID} | +| message | module | ibc_client | +| message | action | create_client | +| message | sender | {signer} | + +### MsgUpdateClient + +| Type | Attribute Key | Attribute Value | +|---------------|---------------|-----------------| +| update_client | client_id | {clientID} | +| message | module | ibc_client | +| message | action | update_client | +| message | sender | {signer} | + +### MsgSubmitMisbehaviour + +| Type | Attribute Key | Attribute Value | +|---------------------|---------------|---------------------| +| client_misbehaviour | client_id | {clientID} | +| message | module | evidence | +| message | action | client_misbehaviour | +| message | sender | {signer} | + +## ICS 03 - Connection + +### MsgConnectionOpenInit + +| Type | Attribute Key | Attribute Value | +|----------------------|------------------------|-------------------------| +| connection_open_init | connection_id | {connectionID} | +| connection_open_init | client_id | {clientID} | +| connection_open_init | counterparty_client_id | {counterparty.clientID} | +| message | module | ibc_connection | +| message | action | connection_open_init | +| message | sender | {signer} | + +### MsgConnectionOpenTry + +| Type | Attribute Key | Attribute Value | +|---------------------|---------------|---------------------| +| connection_open_try | connection_id | {connectionID} | +| connection_open_try | client_id | {clientID} | +| message | module | ibc_connection | +| message | action | connection_open_try | +| message | sender | {signer} | + +### MsgConnectionOpenAck + +| Type | Attribute Key | Attribute Value | +|----------------------|------------------------|-------------------------| +| connection_open_ack | connection_id | {connectionID} | +| connection_open_ack | client_id | {clientID} | +| connection_open_init | counterparty_client_id | {counterparty.clientID} | +| message | module | ibc_connection | +| message | action | connection_open_ack | +| message | sender | {signer} | + +### MsgConnectionOpenConfirm + +| Type | Attribute Key | Attribute Value | +|-------------------------|---------------|-------------------------| +| connection_open_confirm | connection_id | {connectionID} | +| message | module | ibc_connection | +| message | action | connection_open_confirm | +| message | sender | {signer} | + +## ICS 04 - Channel + +### MsgChannelOpenInit + +| Type | Attribute Key | Attribute Value | +|-------------------|-------------------------|----------------------------------| +| channel_open_init | port_id | {portID} | +| channel_open_init | channel_id | {channelID} | +| channel_open_init | counterparty_port_id | {channel.counterparty.portID} | +| channel_open_init | counterparty_channel_id | {channel.counterparty.channelID} | +| channel_open_init | connection_id | {channel.connectionHops} | +| message | module | ibc_channel | +| message | action | channel_open_init | +| message | sender | {signer} | + +### MsgChannelOpenTry + +| Type | Attribute Key | Attribute Value | +|------------------|-------------------------|----------------------------------| +| channel_open_try | port_id | {portID} | +| channel_open_try | channel_id | {channelID} | +| channel_open_try | counterparty_port_id | {channel.counterparty.portID} | +| channel_open_try | counterparty_channel_id | {channel.counterparty.channelID} | +| channel_open_try | connection_id | {channel.connectionHops} | +| message | module | ibc_channel | +| message | action | channel_open_try | +| message | sender | {signer} | + +### MsgChannelOpenAck + +| Type | Attribute Key | Attribute Value | +|------------------|---------------|------------------| +| channel_open_ack | port_id | {portID} | +| channel_open_ack | channel_id | {channelID} | +| message | module | ibc_channel | +| message | action | channel_open_ack | +| message | sender | {signer} | + +### MsgChannelOpenConfirm + +| Type | Attribute Key | Attribute Value | +|----------------------|---------------|----------------------| +| channel_open_confirm | port_id | {portID} | +| channel_open_confirm | channel_id | {channelID} | +| message | module | ibc_channel | +| message | action | channel_open_confirm | +| message | sender | {signer} | + +### MsgChannelCloseInit + +| Type | Attribute Key | Attribute Value | +|--------------------|---------------|--------------------| +| channel_close_init | port_id | {portID} | +| channel_close_init | channel_id | {channelID} | +| message | module | ibc_channel | +| message | action | channel_close_init | +| message | sender | {signer} | + +### MsgChannelCloseConfirm + +| Type | Attribute Key | Attribute Value | +|-----------------------|---------------|-----------------------| +| channel_close_confirm | port_id | {portID} | +| channel_close_confirm | channel_id | {channelID} | +| message | module | ibc_channel | +| message | action | channel_close_confirm | +| message | sender | {signer} | diff --git a/x/ibc/spec/README.md b/x/ibc/spec/README.md new file mode 100644 index 000000000000..9023949b8294 --- /dev/null +++ b/x/ibc/spec/README.md @@ -0,0 +1,106 @@ + + +# `ibc` + +## Abstract + +This paper defines the implementation of the IBC protocol on the Cosmos SDK, the +changes made to the specification and where to find each specific ICS spec within +the module. + +For the general specification please refer to the [Interchain Standards](https://github.com/cosmos/ics). + +## Contents + +1. **[Concepts](01_concepts.md)** +2. **[State](02_state.md)** +3. **[State Transitions](02_state_transitions.md)** +4. **[Messages](03_messages.md)** +5. **[Callbacks](06_callbacks.md)** +6. **[Events](07_events.md)** + +## Implementation Details + +As stated above, the IBC implementation on the Cosmos SDK introduces some changes +to the general specification, in order to avoid code duplication and to take +advantage of the SDK architectural components such as the `AnteHandler` and +transaction routing through `Handlers`. + +### Interchain Standards reference + +The following list is a mapping from each Interchain Standard to their implementation +in the SDK's `x/ibc` module: + +- [ICS 002 - Client Semantics](https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics): Implemented in [`x/ibc/02-client`](https://github.com/cosmos/x/ibc/02-client) +- [ICS 003 - Connection Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-003-connection-semantics): Implemented in [`x/ibc/03-connection`](https://github.com/cosmos/x/ibc/03-connection) +- [ICS 004 - Channel and Packet Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-004-channel-and-packet-semantics): Implemented in [`x/ibc/04-channel`](https://github.com/cosmos/x/ibc/04-channel) +- [ICS 005 - Port Allocation](https://github.com/cosmos/ics/blob/master/spec/ics-005-port-allocation): Implemented in [`x/ibc/05-port`](https://github.com/cosmos/x/ibc/05-port) +- [ICS 006 - Solo Machine Client](https://github.com/cosmos/ics/blob/master/spec/ics-006-solo-machine-client): To be implemented in [`x/ibc/06-solo`](https://github.com/cosmos/x/ibc/06-solo) +- [ICS 007 - Tendermint Client](https://github.com/cosmos/ics/blob/master/spec/ics-007-tendermint-client): Implemented in [`x/ibc/07-tendermint`](https://github.com/cosmos/x/ibc/07-tendermint) +- [ICS 009 - Loopback Client](https://github.com/cosmos/ics/blob/master/spec/ics-009-loopback-client): To be implemented in [`x/ibc/09-loopback`](https://github.com/cosmos/x/ibc/09-loopback) +- [ICS 018- Relayer Algorithms](https://github.com/cosmos/ics/tree/master/spec/ics-018-relayer-algorithms): Implemented in it's own [relayer repository](https://github.com/cosmos/relayer) +- [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer): Implemented in [`x/ibc/20-transfer`](https://github.com/cosmos/x/ibc/20-transfer) +- [ICS 023 - Vector Commitments](https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments): Implemented in [`x/ibc/23-commitment`](https://github.com/cosmos/x/ibc/23-commitment) +- [ICS 024 - Host Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements): Implemented in [`x/ibc/24-host`](https://github.com/cosmos/x/ibc/24-host) +- [ICS 025 - Handler Interface](https://github.com/cosmos/ics/tree/master/spec/ics-025-handler-interface): Handler interfaces are implemented at the top level in `x/ibc/handler.go`, +which call each ICS submodule's handlers (i.e `x/ibc/{XX-ICS}/handler.go`). +- [ICS 026 - Routing Module](https://github.com/cosmos/ics/blob/master/spec/ics-026-routing-module): Replaced by [ADR 15 - IBC Packet Receiver](../../../docs/architecture/adr-015-ibc-packet-receiver.md). + +### Architecture Decision Records (ADR) + +The following ADR provide the design and architecture decision of IBC-related components. + +- [ADR 10 - Modular AnteHandler](../../../docs/architecture/adr-010-modular-antehandler.md): Introduces a decorator pattern for the [`AnteHandler`](../../../docs/basics/gas-fees.md#antehandler), making it modular. +- [ADR 15 - IBC Packet Receiver](../../../docs/architecture/adr-015-ibc-packet-receiver.md): replaces the ICS26 routing module with [`AnteHandler`](../../../docs/basics/gas-fees.md#antehandler) logic within IBC. This is implemented using the `AnteDecorators` defined in [ADR10]((../../../docs/architecture/adr-010-modular-antehandler.md)) +- [ADR 17 - Historical Header Module](../../../docs/architecture/adr-017-historical-header-module.md): Introduces the ability to introspect past +consensus states in order to verify their membership in the counterparty clients. +- [ADR 19 - Protobuf State Encoding](../../../docs/architecture/adr-019-protobuf-state-encoding.md): Migration from Amino to Protobuf for state encoding. + +### SDK Modules + +- [`x/evidence`](https://github.com/cosmos/x/evidence): The evidence module provides the interfaces and client logic to handle light client misbehaviour. Check [ADR 09 - Evidence Module](../../../docs/architecture/adr-009-evidence-module.md) for more details. + +## IBC module architecture + +> **NOTE for auditors**: If you're not familiar with the overall module structure from +the SDK modules, please check this [document](../../../docs/building-modules/structure.md) as +prerequisite reading. + +For ease of auditing, every Interchain Standard has been developed in its own +package. The following tree describes the architecture of the directories within +the IBC module: + +```shell +x/ibc +├── 02-client/ +├── 03-connection/ +├── 04-channel/ +├── 05-port/ +├── 06-solo/ +├── 07-tendermint/ +├── 09-loopback/ +├── 20-transfer/ +├── 23-commitment/ +├── 24-host/ +├── ante +│   └── ante.go +├── client +│   ├── cli +│   │   └── cli.go +│   └── rest +│   └── rest.go +├── keeper +│   ├── keeper.go +│   └── querier.go +├── types +│   ├── errors.go +│   └── keys.go +├── alias.go +├── handler.go +└── module.go +``` From a8b6c677e2aef6e1e9e53a31d57a0f8aa3add919 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 18 Feb 2020 15:42:43 +0100 Subject: [PATCH 085/176] fix build --- x/ibc/03-connection/handler.go | 1 + x/ibc/04-channel/alias.go | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/x/ibc/03-connection/handler.go b/x/ibc/03-connection/handler.go index 1cc1603ccc6c..14c227f7154d 100644 --- a/x/ibc/03-connection/handler.go +++ b/x/ibc/03-connection/handler.go @@ -2,6 +2,7 @@ package connection import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) // HandleMsgConnectionOpenInit defines the sdk.Handler for MsgConnectionOpenInit diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index 6fb4daa4586b..cf71557f2ecc 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -12,10 +12,6 @@ import ( ) const ( - AttributeKeySenderPort = types.AttributeKeySenderPort - AttributeKeyReceiverPort = types.AttributeKeyReceiverPort - AttributeKeyChannelID = types.AttributeKeyChannelID - AttributeKeySequence = types.AttributeKeySequence SubModuleName = types.SubModuleName StoreKey = types.StoreKey RouterKey = types.RouterKey From 1b5bc90a02c831910333998f28829acea0329137 Mon Sep 17 00:00:00 2001 From: Aditya Date: Wed, 19 Feb 2020 00:01:17 +0100 Subject: [PATCH 086/176] Merge PR #5670: Fix Packet Timeout Bug * add destination height to MsgSendTransger * quick fix --- x/ibc/04-channel/keeper/keeper_test.go | 2 +- x/ibc/20-transfer/client/cli/tx.go | 15 ++++++++---- x/ibc/20-transfer/client/rest/rest.go | 9 ++++--- x/ibc/20-transfer/client/rest/tx.go | 1 + x/ibc/20-transfer/handler.go | 2 +- x/ibc/20-transfer/handler_test.go | 6 ++--- x/ibc/20-transfer/keeper/relay.go | 6 +++-- x/ibc/20-transfer/keeper/relay_test.go | 12 ++++----- x/ibc/20-transfer/types/msgs.go | 4 ++- x/ibc/20-transfer/types/msgs_test.go | 34 +++++++++++++------------- 10 files changed, 51 insertions(+), 40 deletions(-) diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index c6f6293609b9..688893e1b5da 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -45,7 +45,7 @@ const ( testChannelOrder = exported.ORDERED testChannelVersion = "1.0" - testHeight = 10 + testHeight = 1 trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index 16d08f886f97..f91c9284ca14 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -2,6 +2,7 @@ package cli import ( "bufio" + "strconv" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -10,8 +11,8 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) @@ -30,7 +31,7 @@ var ( // GetTransferTxCmd returns the command to create a NewMsgTransfer transaction func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "transfer [src-port] [src-channel] [receiver] [amount]", + Use: "transfer [src-port] [src-channel] [dest-height] [receiver] [amount]", Short: "Transfer fungible token through IBC", Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { @@ -41,20 +42,24 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { sender := cliCtx.GetFromAddress() srcPort := args[0] srcChannel := args[1] - receiver, err := sdk.AccAddressFromBech32(args[2]) + destHeight, err := strconv.Atoi(args[2]) + if err != nil { + return err + } + receiver, err := sdk.AccAddressFromBech32(args[3]) if err != nil { return err } // parse coin trying to be sent - coins, err := sdk.ParseCoins(args[3]) + coins, err := sdk.ParseCoins(args[4]) if err != nil { return err } source := viper.GetBool(FlagSource) - msg := types.NewMsgTransfer(srcPort, srcChannel, coins, sender, receiver, source) + msg := types.NewMsgTransfer(srcPort, srcChannel, uint64(destHeight), coins, sender, receiver, source) if err := msg.ValidateBasic(); err != nil { return err } diff --git a/x/ibc/20-transfer/client/rest/rest.go b/x/ibc/20-transfer/client/rest/rest.go index 61c6dc44daa6..625777e9291e 100644 --- a/x/ibc/20-transfer/client/rest/rest.go +++ b/x/ibc/20-transfer/client/rest/rest.go @@ -21,8 +21,9 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) { // TransferTxReq defines the properties of a transfer tx request's body. type TransferTxReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - Amount sdk.Coins `json:"amount" yaml:"amount"` - Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` - Source bool `json:"source" yaml:"source"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + DestHeight uint64 `json:"dest_height" yaml:"dest_height"` + Amount sdk.Coins `json:"amount" yaml:"amount"` + Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` + Source bool `json:"source" yaml:"source"` } diff --git a/x/ibc/20-transfer/client/rest/tx.go b/x/ibc/20-transfer/client/rest/tx.go index dce3561c9f8a..726aa848bbef 100644 --- a/x/ibc/20-transfer/client/rest/tx.go +++ b/x/ibc/20-transfer/client/rest/tx.go @@ -56,6 +56,7 @@ func transferHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { msg := types.NewMsgTransfer( portID, channelID, + req.DestHeight, req.Amount, fromAddr, req.Receiver, diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 877d20f01984..1082b6f7dec4 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -35,7 +35,7 @@ func NewHandler(k Keeper) sdk.Handler { } func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) { - err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source) + err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.DestHeight, msg.Amount, msg.Sender, msg.Receiver, msg.Source) if err != nil { return nil, err } diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index e792a9eded06..64af632ffd03 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -164,7 +164,7 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { handler := transfer.NewHandler(suite.app.TransferKeeper) - msg := transfer.NewMsgTransfer(testPort1, testChannel1, testCoins, testAddr1, testAddr2, source) + msg := transfer.NewMsgTransfer(testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, source) res, err := handler(suite.ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // channel does not exist @@ -188,14 +188,14 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { // test when the source is false source = false - msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, source) + msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2, source) _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testPrefixedCoins2) res, err = handler(suite.ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // incorrect denom prefix - msg = transfer.NewMsgTransfer(testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, source) + msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins1, testAddr1, testAddr2, source) suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testPrefixedCoins1) diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index 8bfa6efcfb97..49ca031ab3f4 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -14,6 +14,7 @@ func (k Keeper) SendTransfer( ctx sdk.Context, sourcePort, sourceChannel string, + destHeight uint64, amount sdk.Coins, sender, receiver sdk.AccAddress, @@ -46,7 +47,7 @@ func (k Keeper) SendTransfer( coins = amount } - return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, coins, sender, receiver, isSourceChain) + return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, destHeight, coins, sender, receiver, isSourceChain) } // ReceiveTransfer handles transfer receiving logic @@ -140,6 +141,7 @@ func (k Keeper) createOutgoingPacket( sourceChannel, destinationPort, destinationChannel string, + destHeight uint64, amount sdk.Coins, sender sdk.AccAddress, receiver sdk.AccAddress, @@ -191,7 +193,7 @@ func (k Keeper) createOutgoingPacket( } } - packetData := types.NewPacketDataTransfer(amount, sender, receiver, isSourceChain, uint64(ctx.BlockHeight())+DefaultPacketTimeout) + packetData := types.NewPacketDataTransfer(amount, sender, receiver, isSourceChain, destHeight+DefaultPacketTimeout) packet := channel.NewPacket( packetData, diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 31357c6637e3..8ad5a7e8b5ab 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -99,20 +99,20 @@ func (suite *KeeperTestSuite) TestSendTransfer() { // test the situation where the source is true isSourceChain := true - err := suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err := suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // channel does not exist suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // next send sequence not found nextSeqSend := uint64(1) suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, isSourceChain) suite.Error(err) // sender has insufficient coins _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testCoins) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testCoins, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, isSourceChain) suite.NoError(err) // successfully executed senderCoins := suite.app.BankKeeper.GetAllBalances(suite.ctx, testAddr1) @@ -132,12 +132,12 @@ func (suite *KeeperTestSuite) TestSendTransfer() { isSourceChain = false _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testPrefixedCoins2) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins2, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2, isSourceChain) suite.Error(err) // incorrect denom prefix suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testPrefixedCoins1) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, testPrefixedCoins1, testAddr1, testAddr2, isSourceChain) + err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testPrefixedCoins1, testAddr1, testAddr2, isSourceChain) suite.NoError(err) // successfully executed senderCoins = suite.app.BankKeeper.GetAllBalances(suite.ctx, testAddr1) diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index 42a56e0f30a6..e350850f9498 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -12,6 +12,7 @@ import ( type MsgTransfer struct { SourcePort string `json:"source_port" yaml:"source_port"` // the port on which the packet will be sent SourceChannel string `json:"source_channel" yaml:"source_channel"` // the channel by which the packet will be sent + DestHeight uint64 `json:"dest_height" yaml:"dest_height"` // the current height of the destination chain Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain @@ -20,11 +21,12 @@ type MsgTransfer struct { // NewMsgTransfer creates a new MsgTransfer instance func NewMsgTransfer( - sourcePort, sourceChannel string, amount sdk.Coins, sender, receiver sdk.AccAddress, source bool, + sourcePort, sourceChannel string, destHeight uint64, amount sdk.Coins, sender, receiver sdk.AccAddress, source bool, ) MsgTransfer { return MsgTransfer{ SourcePort: sourcePort, SourceChannel: sourceChannel, + DestHeight: destHeight, Amount: amount, Sender: sender, Receiver: receiver, diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go index 42e55d32677c..ad0955ee745d 100644 --- a/x/ibc/20-transfer/types/msgs_test.go +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -33,14 +33,14 @@ var ( // TestMsgTransferRoute tests Route for MsgTransfer func TestMsgTransferRoute(t *testing.T) { - msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + msg := NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true) require.Equal(t, ibctypes.RouterKey, msg.Route()) } // TestMsgTransferType tests Type for MsgTransfer func TestMsgTransferType(t *testing.T) { - msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + msg := NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true) require.Equal(t, "transfer", msg.Type()) } @@ -48,18 +48,18 @@ func TestMsgTransferType(t *testing.T) { // TestMsgTransferValidation tests ValidateBasic for MsgTransfer func TestMsgTransferValidation(t *testing.T) { testMsgs := []MsgTransfer{ - NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true), // valid msg - NewMsgTransfer(invalidShortPort, "testchannel", coins, addr1, addr2, true), // too short port id - NewMsgTransfer(invalidLongPort, "testchannel", coins, addr1, addr2, true), // too long port id - NewMsgTransfer(invalidPort, "testchannel", coins, addr1, addr2, true), // port id contains non-alpha - NewMsgTransfer("testportid", invalidShortChannel, coins, addr1, addr2, true), // too short channel id - NewMsgTransfer("testportid", invalidLongChannel, coins, addr1, addr2, false), // too long channel id - NewMsgTransfer("testportid", invalidChannel, coins, addr1, addr2, false), // channel id contains non-alpha - NewMsgTransfer("testportid", "testchannel", invalidDenomCoins, addr1, addr2, false), // invalid amount - NewMsgTransfer("testportid", "testchannel", negativeCoins, addr1, addr2, false), // amount contains negative coin - NewMsgTransfer("testportid", "testchannel", coins, emptyAddr, addr2, false), // missing sender address - NewMsgTransfer("testportid", "testchannel", coins, addr1, emptyAddr, false), // missing recipient address - NewMsgTransfer("testportid", "testchannel", sdk.Coins{}, addr1, addr2, false), // not possitive coin + NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true), // valid msg + NewMsgTransfer(invalidShortPort, "testchannel", 10, coins, addr1, addr2, true), // too short port id + NewMsgTransfer(invalidLongPort, "testchannel", 10, coins, addr1, addr2, true), // too long port id + NewMsgTransfer(invalidPort, "testchannel", 10, coins, addr1, addr2, true), // port id contains non-alpha + NewMsgTransfer("testportid", invalidShortChannel, 10, coins, addr1, addr2, true), // too short channel id + NewMsgTransfer("testportid", invalidLongChannel, 10, coins, addr1, addr2, false), // too long channel id + NewMsgTransfer("testportid", invalidChannel, 10, coins, addr1, addr2, false), // channel id contains non-alpha + NewMsgTransfer("testportid", "testchannel", 10, invalidDenomCoins, addr1, addr2, false), // invalid amount + NewMsgTransfer("testportid", "testchannel", 10, negativeCoins, addr1, addr2, false), // amount contains negative coin + NewMsgTransfer("testportid", "testchannel", 10, coins, emptyAddr, addr2, false), // missing sender address + NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, emptyAddr, false), // missing recipient address + NewMsgTransfer("testportid", "testchannel", 10, sdk.Coins{}, addr1, addr2, false), // not possitive coin } testCases := []struct { @@ -92,16 +92,16 @@ func TestMsgTransferValidation(t *testing.T) { // TestMsgTransferGetSignBytes tests GetSignBytes for MsgTransfer func TestMsgTransferGetSignBytes(t *testing.T) { - msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + msg := NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true) res := msg.GetSignBytes() - expected := `{"type":"ibc/transfer/MsgTransfer","value":{"amount":[{"amount":"100","denom":"atom"}],"receiver":"cosmos1w3jhxarpv3j8yvs7f9y7g","sender":"cosmos1w3jhxarpv3j8yvg4ufs4x","source":true,"source_channel":"testchannel","source_port":"testportid"}}` + expected := `{"type":"ibc/transfer/MsgTransfer","value":{"amount":[{"amount":"100","denom":"atom"}],"dest_height":"10","receiver":"cosmos1w3jhxarpv3j8yvs7f9y7g","sender":"cosmos1w3jhxarpv3j8yvg4ufs4x","source":true,"source_channel":"testchannel","source_port":"testportid"}}` require.Equal(t, expected, string(res)) } // TestMsgTransferGetSigners tests GetSigners for MsgTransfer func TestMsgTransferGetSigners(t *testing.T) { - msg := NewMsgTransfer("testportid", "testchannel", coins, addr1, addr2, true) + msg := NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true) res := msg.GetSigners() expected := "[746573746164647231]" From ff7c881768fbe4f0dc060eee2725556f0471fea4 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Wed, 19 Feb 2020 11:28:51 -0800 Subject: [PATCH 087/176] Add defensive checks before setting param keytables in keeprs --- x/auth/keeper/keeper.go | 7 ++++++- x/bank/internal/keeper/keeper.go | 10 +++++++--- x/crisis/internal/keeper/keeper.go | 7 ++++++- x/mint/internal/keeper/keeper.go | 7 ++++++- x/slashing/internal/keeper/keeper.go | 8 +++++++- x/slashing/internal/types/expected_keepers.go | 1 + x/staking/keeper/keeper.go | 7 ++++++- 7 files changed, 39 insertions(+), 8 deletions(-) diff --git a/x/auth/keeper/keeper.go b/x/auth/keeper/keeper.go index df5228fa7f03..4890af98d413 100644 --- a/x/auth/keeper/keeper.go +++ b/x/auth/keeper/keeper.go @@ -31,11 +31,16 @@ func NewAccountKeeper( cdc types.Codec, key sdk.StoreKey, paramstore paramtypes.Subspace, proto func() exported.Account, ) AccountKeeper { + // set KeyTable if it has not already been set + if !paramstore.HasKeyTable() { + paramstore = paramstore.WithKeyTable(types.ParamKeyTable()) + } + return AccountKeeper{ key: key, proto: proto, cdc: cdc, - paramSubspace: paramstore.WithKeyTable(types.ParamKeyTable()), + paramSubspace: paramstore, } } diff --git a/x/bank/internal/keeper/keeper.go b/x/bank/internal/keeper/keeper.go index 1475a85cfb92..9a1d16305e35 100644 --- a/x/bank/internal/keeper/keeper.go +++ b/x/bank/internal/keeper/keeper.go @@ -38,11 +38,15 @@ func NewBaseKeeper( cdc *codec.Codec, storeKey sdk.StoreKey, ak types.AccountKeeper, paramSpace paramtypes.Subspace, blacklistedAddrs map[string]bool, ) BaseKeeper { - ps := paramSpace.WithKeyTable(types.ParamKeyTable()) + // set KeyTable if it has not already been set + if !paramSpace.HasKeyTable() { + paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + } + return BaseKeeper{ - BaseSendKeeper: NewBaseSendKeeper(cdc, storeKey, ak, ps, blacklistedAddrs), + BaseSendKeeper: NewBaseSendKeeper(cdc, storeKey, ak, paramSpace, blacklistedAddrs), ak: ak, - paramSpace: ps, + paramSpace: paramSpace, } } diff --git a/x/crisis/internal/keeper/keeper.go b/x/crisis/internal/keeper/keeper.go index d57030ed6c1f..04d6bd3a8898 100644 --- a/x/crisis/internal/keeper/keeper.go +++ b/x/crisis/internal/keeper/keeper.go @@ -28,9 +28,14 @@ func NewKeeper( feeCollectorName string, ) Keeper { + // set KeyTable if it has not already been set + if !paramSpace.HasKeyTable() { + paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + } + return Keeper{ routes: make([]types.InvarRoute, 0), - paramSpace: paramSpace.WithKeyTable(types.ParamKeyTable()), + paramSpace: paramSpace, invCheckPeriod: invCheckPeriod, supplyKeeper: supplyKeeper, feeCollectorName: feeCollectorName, diff --git a/x/mint/internal/keeper/keeper.go b/x/mint/internal/keeper/keeper.go index 86721d7bbcc0..a0eef2e9249b 100644 --- a/x/mint/internal/keeper/keeper.go +++ b/x/mint/internal/keeper/keeper.go @@ -32,10 +32,15 @@ func NewKeeper( panic("the mint module account has not been set") } + // set KeyTable if it has not already been set + if !paramSpace.HasKeyTable() { + paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + } + return Keeper{ cdc: cdc, storeKey: key, - paramSpace: paramSpace.WithKeyTable(types.ParamKeyTable()), + paramSpace: paramSpace, sk: sk, supplyKeeper: supplyKeeper, feeCollectorName: feeCollectorName, diff --git a/x/slashing/internal/keeper/keeper.go b/x/slashing/internal/keeper/keeper.go index e725519314d1..6aedd7aee273 100644 --- a/x/slashing/internal/keeper/keeper.go +++ b/x/slashing/internal/keeper/keeper.go @@ -21,11 +21,17 @@ type Keeper struct { // NewKeeper creates a slashing keeper func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, sk types.StakingKeeper, paramspace types.ParamSubspace) Keeper { + + // set KeyTable if it has not already been set + if !paramspace.HasKeyTable() { + paramspace = paramspace.WithKeyTable(types.ParamKeyTable()) + } + return Keeper{ storeKey: key, cdc: cdc, sk: sk, - paramspace: paramspace.WithKeyTable(types.ParamKeyTable()), + paramspace: paramspace, } } diff --git a/x/slashing/internal/types/expected_keepers.go b/x/slashing/internal/types/expected_keepers.go index 4a9dd4f7f2d6..50e71cb614e5 100644 --- a/x/slashing/internal/types/expected_keepers.go +++ b/x/slashing/internal/types/expected_keepers.go @@ -26,6 +26,7 @@ type BankKeeper interface { // ParamSubspace defines the expected Subspace interfacace type ParamSubspace interface { + HasKeyTable() bool WithKeyTable(table paramtypes.KeyTable) paramtypes.Subspace Get(ctx sdk.Context, key []byte, ptr interface{}) GetParamSet(ctx sdk.Context, ps paramtypes.ParamSet) diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index 4e241ded201f..4956a5f2abe3 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -46,12 +46,17 @@ func NewKeeper( panic(fmt.Sprintf("%s module account has not been set", types.NotBondedPoolName)) } + // set KeyTable if it has not already been set + if !ps.HasKeyTable() { + ps = ps.WithKeyTable(ParamKeyTable()) + } + return Keeper{ storeKey: key, cdc: cdc, bankKeeper: bk, supplyKeeper: sk, - paramstore: ps.WithKeyTable(ParamKeyTable()), + paramstore: ps, hooks: nil, validatorCache: make(map[string]cachedValidator, aminoCacheSize), validatorCacheList: list.New(), From 6f42d827140fc02f1271a0aaade3b3d8e67ac965 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Thu, 20 Feb 2020 16:31:49 +0000 Subject: [PATCH 088/176] ICS 20 Cleanup and Tests (#5577) * Add comments, remove unused code and attempt to point to places where the spec is being implemented * close channel when transfer fails * rename packer data transfer to align to spec; refactor table tests * ICS 20 implementation cleanup work (#5602) * Simulation docs (#5033) * simulation docs * update docs with the latest simulation changes * minor imporvments * clean up of simulation.md * expand section on weights * minor reword * minor wording fix Co-authored-by: Marko * Merge PR #5597: Include Amount in Complete Unbonding/Redelegation Events * Add bank alias for gaia * Moar bank alias gaia * Moar bank alias gaia * Call `TimeoutExecuted`, add wrappers * Remove unused `MsgRecvPacket` Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Marko Co-authored-by: Alexander Bezobchuk Co-authored-by: Jack Zampolin * Merge PR #5603: Remove acknowledgement interface in favour of []byte * fixes and cleanup * spec compliance * refactor relay prefixes and tests * Fix test compilation * cleanup; add notes and additional test case * Receive transfer test * Apply suggestions from code review Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * Fix autolinter application * Add testcase with incorrect prefix * golangcibot fixes * delete extra comment Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Christopher Goes Co-authored-by: Marko Co-authored-by: Alexander Bezobchuk Co-authored-by: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> --- types/coin.go | 4 +- x/ibc/04-channel/alias.go | 1 + x/ibc/04-channel/exported/exported.go | 5 + x/ibc/04-channel/keeper/handshake.go | 2 +- x/ibc/04-channel/keeper/packet.go | 6 +- x/ibc/04-channel/keeper/packet_test.go | 3 +- x/ibc/04-channel/types/codec.go | 1 + x/ibc/04-channel/types/errors.go | 1 + x/ibc/04-channel/types/msgs.go | 18 +- x/ibc/04-channel/types/msgs_test.go | 11 +- x/ibc/04-channel/types/packet.go | 2 +- x/ibc/20-transfer/alias.go | 20 +- x/ibc/20-transfer/client/cli/cli.go | 1 - x/ibc/20-transfer/client/rest/swagger.go | 11 +- x/ibc/20-transfer/handler.go | 73 +++-- x/ibc/20-transfer/keeper/callbacks.go | 172 ----------- x/ibc/20-transfer/keeper/callbacks_test.go | 51 ---- x/ibc/20-transfer/keeper/keeper.go | 18 +- x/ibc/20-transfer/keeper/keeper_test.go | 91 +++++- x/ibc/20-transfer/keeper/relay.go | 250 +++++++-------- x/ibc/20-transfer/keeper/relay_test.go | 320 ++++++++++---------- x/ibc/20-transfer/module.go | 23 +- x/ibc/20-transfer/types/codec.go | 2 +- x/ibc/20-transfer/types/errors.go | 10 + x/ibc/20-transfer/types/events.go | 2 +- x/ibc/20-transfer/types/expected_keepers.go | 4 +- x/ibc/20-transfer/types/keys.go | 12 +- x/ibc/20-transfer/types/msgs.go | 60 +--- x/ibc/20-transfer/types/msgs_test.go | 34 ++- x/ibc/20-transfer/types/packet.go | 87 +++--- x/ibc/20-transfer/types/packet_test.go | 20 +- x/ibc/ante/ante.go | 2 +- 32 files changed, 594 insertions(+), 723 deletions(-) delete mode 100644 x/ibc/20-transfer/keeper/callbacks.go delete mode 100644 x/ibc/20-transfer/keeper/callbacks_test.go create mode 100644 x/ibc/20-transfer/types/errors.go diff --git a/types/coin.go b/types/coin.go index 6a759d569387..8f51f640872c 100644 --- a/types/coin.go +++ b/types/coin.go @@ -580,8 +580,8 @@ func (coins Coins) Sort() Coins { // Parsing var ( - // Denominations can be 3 ~ 32 characters long. - reDnmString = `[a-z][a-z0-9/]{2,31}` + // Denominations can be 3 ~ 64 characters long. + reDnmString = `[a-z][a-z0-9/]{2,63}` reAmt = `[[:digit:]]+` reDecAmt = `[[:digit:]]*\.[[:digit:]]+` reSpc = `[[:space:]]*` diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index cf71557f2ecc..c24c077d9c60 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -37,6 +37,7 @@ var ( ErrPacketTimeout = types.ErrPacketTimeout ErrInvalidChannel = types.ErrInvalidChannel ErrInvalidChannelState = types.ErrInvalidChannelState + ErrAcknowledgementTooLong = types.ErrAcknowledgementTooLong NewMsgChannelOpenInit = types.NewMsgChannelOpenInit NewMsgChannelOpenTry = types.NewMsgChannelOpenTry NewMsgChannelOpenAck = types.NewMsgChannelOpenAck diff --git a/x/ibc/04-channel/exported/exported.go b/x/ibc/04-channel/exported/exported.go index ad4f75cacfa8..ba9dc7efdf6b 100644 --- a/x/ibc/04-channel/exported/exported.go +++ b/x/ibc/04-channel/exported/exported.go @@ -46,6 +46,11 @@ type PacketDataI interface { Type() string // Type returns human readable identifier, implements sdk.Msg } +// PacketAcknowledgementI defines the interface for IBC packet acknowledgements. +type PacketAcknowledgementI interface { + GetBytes() []byte +} + // Order defines if a channel is ORDERED or UNORDERED type Order byte diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index 9668cafe55ef..40bfb79e90d1 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -331,7 +331,7 @@ func (k Keeper) ChanCloseInit( channel.State = exported.CLOSED k.SetChannel(ctx, portID, channelID, channel) - + k.Logger(ctx).Info("channel close initialized: portID (%s), channelID (%s)", portID, channelID) return nil } diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 0ba1186ccd4a..614da9d0ebcf 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -178,7 +178,7 @@ func (k Keeper) RecvPacket( func (k Keeper) PacketExecuted( ctx sdk.Context, packet exported.PacketI, - acknowledgement exported.PacketDataI, + acknowledgement exported.PacketAcknowledgementI, ) error { channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { @@ -231,7 +231,7 @@ func (k Keeper) PacketExecuted( func (k Keeper) AcknowledgePacket( ctx sdk.Context, packet exported.PacketI, - acknowledgement []byte, + acknowledgement exported.PacketAcknowledgementI, proof commitment.ProofI, proofHeight uint64, ) (exported.PacketI, error) { @@ -286,7 +286,7 @@ func (k Keeper) AcknowledgePacket( if err := k.connectionKeeper.VerifyPacketAcknowledgement( ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), - packet.GetSequence(), acknowledgement, + packet.GetSequence(), acknowledgement.GetBytes(), ); err != nil { return nil, sdkerrors.Wrap(err, "invalid acknowledgement on counterparty chain") } diff --git a/x/ibc/04-channel/keeper/packet_test.go b/x/ibc/04-channel/keeper/packet_test.go index e8901ec1c4e4..950bf320776b 100644 --- a/x/ibc/04-channel/keeper/packet_test.go +++ b/x/ibc/04-channel/keeper/packet_test.go @@ -6,6 +6,7 @@ import ( connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + transfertypes "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -212,7 +213,7 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { counterparty := types.NewCounterparty(testPort2, testChannel2) var packet types.Packet - ack := []byte("ack") + ack := transfertypes.AckDataTransfer{} testCases := []testCase{ {"success", func() { diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index 2bb785418b67..e8bb91bf33be 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -22,6 +22,7 @@ func init() { func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*exported.PacketI)(nil), nil) cdc.RegisterInterface((*exported.PacketDataI)(nil), nil) + cdc.RegisterInterface((*exported.PacketAcknowledgementI)(nil), nil) cdc.RegisterConcrete(Channel{}, "ibc/channel/Channel", nil) cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil) diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go index 9e6ee6fcf74c..a184314bbd56 100644 --- a/x/ibc/04-channel/types/errors.go +++ b/x/ibc/04-channel/types/errors.go @@ -18,4 +18,5 @@ var ( ErrInvalidPacket = sdkerrors.Register(SubModuleName, 10, "invalid packet") ErrPacketTimeout = sdkerrors.Register(SubModuleName, 11, "packet timeout") ErrTooManyConnectionHops = sdkerrors.Register(SubModuleName, 12, "too many connection hops") + ErrAcknowledgementTooLong = sdkerrors.Register(SubModuleName, 13, "acknowledgement too long") ) diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index c655cfda0f45..3f52db670f97 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -446,7 +446,7 @@ func (msg MsgPacket) GetSigners() []sdk.AccAddress { var _ sdk.Msg = MsgTimeout{} -// MsgTimeout receives timeouted packet +// MsgTimeout receives timed-out packet type MsgTimeout struct { Packet `json:"packet" yaml:"packet"` NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"` @@ -504,14 +504,14 @@ var _ sdk.Msg = MsgAcknowledgement{} // MsgAcknowledgement receives incoming IBC acknowledgement type MsgAcknowledgement struct { Packet `json:"packet" yaml:"packet"` - Acknowledgement exported.PacketDataI `json:"acknowledgement" yaml:"acknowledgement"` - Proof commitment.ProofI `json:"proof" yaml:"proof"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` - Signer sdk.AccAddress `json:"signer" yaml:"signer"` + Acknowledgement exported.PacketAcknowledgementI `json:"acknowledgement" yaml:"acknowledgement"` + Proof commitment.ProofI `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` } // NewMsgAcknowledgement constructs a new MsgAcknowledgement -func NewMsgAcknowledgement(packet Packet, ack exported.PacketDataI, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement { +func NewMsgAcknowledgement(packet Packet, ack exported.PacketAcknowledgementI, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement { return MsgAcknowledgement{ Packet: packet, Acknowledgement: ack, @@ -534,12 +534,12 @@ func (msg MsgAcknowledgement) ValidateBasic() error { if err := msg.Proof.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof ack cannot be nil") } + if len(msg.Acknowledgement.GetBytes()) > 100 { + return sdkerrors.Wrap(ErrAcknowledgementTooLong, "acknowledgement cannot exceed 100 bytes") + } if msg.ProofHeight == 0 { return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0") } - if err := msg.Acknowledgement.ValidateBasic(); err != nil { - return err - } if msg.Signer.Empty() { return sdkerrors.ErrInvalidAddress } diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index 0e43f58d503b..f071b7a17fcb 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -392,10 +392,19 @@ func (invalidPacketT) Type() string { return "invalid" } +var _ exported.PacketAcknowledgementI = invalidAckT{} + +type invalidAckT struct{} + +func (invalidAckT) GetBytes() []byte { + return []byte("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890") +} + // define variables used for testing var ( packet = NewPacket(validPacketT{}, 1, portid, chanid, cpportid, cpchanid) invalidPacket = NewPacket(invalidPacketT{}, 0, portid, chanid, cpportid, cpchanid) + invalidAck = invalidAckT{} emptyProof = commitment.Proof{Proof: nil} invalidProofs1 = commitment.ProofI(nil) @@ -521,7 +530,7 @@ func (suite *MsgTestSuite) TestMsgAcknowledgement() { NewMsgAcknowledgement(packet, packet.GetData(), proof, 1, emptyAddr), NewMsgAcknowledgement(packet, packet.GetData(), emptyProof, 1, addr), NewMsgAcknowledgement(invalidPacket, packet.GetData(), proof, 1, addr), - NewMsgAcknowledgement(packet, invalidPacket.GetData(), proof, 1, addr), + NewMsgAcknowledgement(packet, invalidAck, proof, 1, addr), NewMsgAcknowledgement(packet, packet.GetData(), invalidProofs1, 1, addr), } diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go index df9b78dd0cd5..cd5d1e271c5f 100644 --- a/x/ibc/04-channel/types/packet.go +++ b/x/ibc/04-channel/types/packet.go @@ -22,7 +22,7 @@ func CommitPacket(data exported.PacketDataI) []byte { } // CommitAcknowledgement returns the hash of commitment bytes -func CommitAcknowledgement(data exported.PacketDataI) []byte { +func CommitAcknowledgement(data exported.PacketAcknowledgementI) []byte { return tmhash.Sum(data.GetBytes()) } diff --git a/x/ibc/20-transfer/alias.go b/x/ibc/20-transfer/alias.go index d819b6ed2399..033d9b18611a 100644 --- a/x/ibc/20-transfer/alias.go +++ b/x/ibc/20-transfer/alias.go @@ -14,7 +14,7 @@ import ( const ( DefaultPacketTimeout = keeper.DefaultPacketTimeout AttributeKeyReceiver = types.AttributeKeyReceiver - SubModuleName = types.SubModuleName + ModuleName = types.ModuleName StoreKey = types.StoreKey RouterKey = types.RouterKey QuerierRoute = types.QuerierRoute @@ -35,13 +35,13 @@ var ( ) type ( - Keeper = keeper.Keeper - BankKeeper = types.BankKeeper - ChannelKeeper = types.ChannelKeeper - ClientKeeper = types.ClientKeeper - ConnectionKeeper = types.ConnectionKeeper - SupplyKeeper = types.SupplyKeeper - MsgTransfer = types.MsgTransfer - MsgRecvPacket = types.MsgRecvPacket - PacketDataTransfer = types.PacketDataTransfer + Keeper = keeper.Keeper + BankKeeper = types.BankKeeper + ChannelKeeper = types.ChannelKeeper + ClientKeeper = types.ClientKeeper + ConnectionKeeper = types.ConnectionKeeper + SupplyKeeper = types.SupplyKeeper + FungibleTokenPacketData = types.FungibleTokenPacketData + MsgTransfer = types.MsgTransfer + AckDataTransfer = types.AckDataTransfer ) diff --git a/x/ibc/20-transfer/client/cli/cli.go b/x/ibc/20-transfer/client/cli/cli.go index 45a41239f974..03b26c5cb2b6 100644 --- a/x/ibc/20-transfer/client/cli/cli.go +++ b/x/ibc/20-transfer/client/cli/cli.go @@ -30,7 +30,6 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { ics20TransferTxCmd.AddCommand(flags.PostCommands( GetTransferTxCmd(cdc), - // GetMsgRecvPacketCmd(cdc), )...) return ics20TransferTxCmd diff --git a/x/ibc/20-transfer/client/rest/swagger.go b/x/ibc/20-transfer/client/rest/swagger.go index 5714d06dcaaf..1514502c6b66 100644 --- a/x/ibc/20-transfer/client/rest/swagger.go +++ b/x/ibc/20-transfer/client/rest/swagger.go @@ -12,16 +12,9 @@ type ( } PostTransfer struct { - Msgs []types.MsgTransfer `json:"msg" yaml:"msg"` + Msgs []types.MsgTransfer `json:"msg" yaml:"msg"` Fee authtypes.StdFee `json:"fee" yaml:"fee"` Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostRecvPacket struct { - Msgs []types.MsgRecvPacket `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` + Memo string `json:"memo" yaml:"memo"` } ) diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 1082b6f7dec4..08dd6a5927d0 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -3,7 +3,6 @@ package transfer import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) @@ -16,36 +15,38 @@ func NewHandler(k Keeper) sdk.Handler { return handleMsgTransfer(ctx, k, msg) case channeltypes.MsgPacket: switch data := msg.Data.(type) { - case PacketDataTransfer: // i.e fulfills the Data interface + case FungibleTokenPacketData: return handlePacketDataTransfer(ctx, k, msg, data) default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 packet data type: %T", msg) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer packet data type: %T", data) } case channeltypes.MsgTimeout: switch data := msg.Data.(type) { - case PacketDataTransfer: + case FungibleTokenPacketData: return handleTimeoutDataTransfer(ctx, k, msg, data) default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 packet data type: %T", data) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer packet data type: %T", data) } default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 message type: %T", msg) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer message type: %T", msg) } } } +// See createOutgoingPacket in spec:https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) { - err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.DestHeight, msg.Amount, msg.Sender, msg.Receiver, msg.Source) - if err != nil { + if err := k.SendTransfer( + ctx, msg.SourcePort, msg.SourceChannel, msg.DestHeight, msg.Amount, msg.Sender, msg.Receiver, msg.Source, + ); err != nil { return nil, err } ctx.EventManager().EmitEvent( sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), - sdk.NewAttribute(types.AttributeKeyReceiver, msg.Receiver.String()), + sdk.NewAttribute(AttributeKeyReceiver, msg.Receiver.String()), ), ) @@ -54,43 +55,57 @@ func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, }, nil } -func handlePacketDataTransfer(ctx sdk.Context, k Keeper, msg channeltypes.MsgPacket, data types.PacketDataTransfer) (*sdk.Result, error) { - packet := msg.Packet - err := k.ReceiveTransfer(ctx, packet.SourcePort, packet.SourceChannel, packet.DestinationPort, packet.DestinationChannel, data) - if err != nil { - panic(err) - // TODO: Source chain sent invalid packet, shutdown channel +// See onRecvPacket in spec: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay +func handlePacketDataTransfer( + ctx sdk.Context, k Keeper, msg channeltypes.MsgPacket, data FungibleTokenPacketData, +) (*sdk.Result, error) { + if err := k.ReceiveTransfer(ctx, msg.Packet, data); err != nil { + // NOTE (cwgoes): How do we want to handle this case? Maybe we should be more lenient, + // it's safe to leave the channel open I think. + + // TODO: handle packet receipt that due to an error (specify) + // the receiving chain couldn't process the transfer + + // source chain sent invalid packet, shutdown our channel end + if err := k.ChanCloseInit(ctx, msg.Packet.DestinationPort, msg.Packet.DestinationChannel); err != nil { + return nil, err + } + return nil, err } - acknowledgement := types.AckDataTransfer{} - err = k.PacketExecuted(ctx, packet, acknowledgement) - if err != nil { - panic(err) - // TODO: This should not happen + acknowledgement := AckDataTransfer{} + if err := k.PacketExecuted(ctx, msg.Packet, acknowledgement); err != nil { + return nil, err } ctx.EventManager().EmitEvent( sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), ), ) - // packet receiving should not fail return &sdk.Result{ Events: ctx.EventManager().Events(), }, nil } -func handleTimeoutDataTransfer(ctx sdk.Context, k Keeper, msg channeltypes.MsgTimeout, data types.PacketDataTransfer) (*sdk.Result, error) { - packet := msg.Packet - err := k.TimeoutTransfer(ctx, packet.SourcePort, packet.SourceChannel, packet.DestinationPort, packet.DestinationChannel, data) - if err != nil { - // This chain sent invalid packet +// See onTimeoutPacket in spec: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay +func handleTimeoutDataTransfer( + ctx sdk.Context, k Keeper, msg channeltypes.MsgTimeout, data FungibleTokenPacketData, +) (*sdk.Result, error) { + if err := k.TimeoutTransfer(ctx, msg.Packet, data); err != nil { + // This shouldn't happen, since we've already validated that we've sent the packet. panic(err) } - // packet timeout should not fail + + if err := k.TimeoutExecuted(ctx, msg.Packet); err != nil { + // This shouldn't happen, since we've already validated that we've sent the packet. + // TODO: Figure out what happens if the capability authorisation changes. + panic(err) + } + return &sdk.Result{ Events: ctx.EventManager().Events(), }, nil diff --git a/x/ibc/20-transfer/keeper/callbacks.go b/x/ibc/20-transfer/keeper/callbacks.go deleted file mode 100644 index 3e478a16c6c7..000000000000 --- a/x/ibc/20-transfer/keeper/callbacks.go +++ /dev/null @@ -1,172 +0,0 @@ -package keeper - -// NOTE: -// OnChanOpenInit, OnChanOpenTry, OnChanOpenAck, OnChanOpenConfirm, OnChanCLoseConfirm -// will be implemented according to ADR15 in the future PRs. Code left for reference. -// -// OnRecvPacket, OnAcknowledgementPacket, OnTimeoutPacket has been implemented according -// to ADR15. - -/* -import ( - "strings" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" - "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" -) - -// nolint: unused -func (k Keeper) OnChanOpenInit( - ctx sdk.Context, - order channel.Order, - connectionHops []string, - portID, - channelID string, - counterparty channel.Counterparty, - version string, -) error { - if order != channel.UNORDERED { - return sdkerrors.Wrap(channel.ErrInvalidChannel, "channel must be UNORDERED") - } - - // NOTE: here the capability key name defines the port ID of the counterparty - if counterparty.PortID != k.boundedCapability.Name() { - return sdkerrors.Wrapf( - port.ErrInvalidPort, - "counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name(), - ) - } - - if strings.TrimSpace(version) != "" { - return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version must be blank") - } - - // NOTE: as the escrow address is generated from both the port and channel IDs - // there's no need to store it on a map. - return nil -} - -// nolint: unused -func (k Keeper) OnChanOpenTry( - ctx sdk.Context, - order channel.Order, - connectionHops []string, - portID, - channelID string, - counterparty channel.Counterparty, - version string, - counterpartyVersion string, -) error { - if order != channel.UNORDERED { - return sdkerrors.Wrap(channel.ErrInvalidChannel, "channel must be UNORDERED") - } - - // NOTE: here the capability key name defines the port ID of the counterparty - if counterparty.PortID != k.boundedCapability.Name() { - return sdkerrors.Wrapf( - port.ErrInvalidPort, - "counterparty port ID doesn't match the capability key (%s ≠ %s)", counterparty.PortID, k.boundedCapability.Name(), - ) - } - - if strings.TrimSpace(version) != "" { - return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version must be blank") - } - - if strings.TrimSpace(counterpartyVersion) != "" { - return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "counterparty version must be blank") - } - - // NOTE: as the escrow address is generated from both the port and channel IDs - // there's no need to store it on a map. - return nil -} - -// nolint: unused -func (k Keeper) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - version string, -) error { - if strings.TrimSpace(version) != "" { - return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version must be blank") - } - - return nil -} - -// nolint: unused -func (k Keeper) OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - // no-op - return nil -} - -// nolint: unused -func (k Keeper) OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, -) error { - // no-op - return nil -} - -// nolint: unused -func (k Keeper) OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - // no-op - return nil -} - -// nolint: unused -func (k Keeper) OnTimeoutPacket( - ctx sdk.Context, - packet channelexported.PacketI, -) error { - var data types.PacketData - - err := k.cdc.UnmarshalBinaryBare(packet.GetData(), &data) - if err != nil { - return sdkerrors.Wrap(err, "invalid packet data") - } - - // check the denom prefix - prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) - coins := make(sdk.Coins, len(data.Amount)) - for i, coin := range data.Amount { - coin := coin - if !strings.HasPrefix(coin.Denom, prefix) { - return sdkerrors.Wrapf( - sdkerrors.ErrInvalidCoins, - "%s doesn't contain the prefix '%s'", coin.Denom, prefix, - ) - } - coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) - } - - if data.Source { - escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) - return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Sender, coins) - } - - // mint from supply - err = k.supplyKeeper.MintCoins(ctx, types.GetModuleAccountName(), data.Amount) - if err != nil { - return err - } - - return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Sender, data.Amount) -} -*/ diff --git a/x/ibc/20-transfer/keeper/callbacks_test.go b/x/ibc/20-transfer/keeper/callbacks_test.go deleted file mode 100644 index 171cb99e7306..000000000000 --- a/x/ibc/20-transfer/keeper/callbacks_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package keeper_test - -// TODO: move to 04-channel after CheckOpen implementation in the following PR -/* -func (suite *KeeperTestSuite) TestOnChanOpenInit() { - invalidOrder := channel.ORDERED - - counterparty := channel.NewCounterparty(testPort2, testChannel2) - err := suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, invalidOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "") - suite.Error(err) // invalid channel order - - err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "") - suite.Error(err) // invalid counterparty port ID - - counterparty = channel.NewCounterparty(testPort1, testChannel2) - err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion) - suite.Error(err) // invalid version - - err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "") - suite.NoError(err) // successfully executed -} - -func (suite *KeeperTestSuite) TestOnChanOpenTry() { - invalidOrder := channel.ORDERED - - counterparty := channel.NewCounterparty(testPort2, testChannel2) - err := suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, invalidOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", "") - suite.Error(err) // invalid channel order - - err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", "") - suite.Error(err) // invalid counterparty port ID - - counterparty = channel.NewCounterparty(testPort1, testChannel2) - err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion, "") - suite.Error(err) // invalid version - - err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", testChannelVersion) - suite.Error(err) // invalid counterparty version - - err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, "", "") - suite.NoError(err) // successfully executed -} - -func (suite *KeeperTestSuite) TestOnChanOpenAck() { - err := suite.app.IBCKeeper.TransferKeeper.OnChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion) - suite.Error(err) // invalid version - - err = suite.app.IBCKeeper.TransferKeeper.OnChanOpenAck(suite.ctx, testPort1, testChannel1, "") - suite.NoError(err) // successfully executed -} -*/ diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index c57ca802fa4c..e5225cbe7137 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -55,7 +55,7 @@ func NewKeeper( // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName)) + return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.ModuleName)) } // GetTransferAccount returns the ICS20 - transfers ModuleAccount @@ -64,7 +64,19 @@ func (k Keeper) GetTransferAccount(ctx sdk.Context) supplyexported.ModuleAccount } // PacketExecuted defines a wrapper function for the channel Keeper's function -// in order to expose it to the ICS20 trasfer handler. -func (k Keeper) PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketDataI) error { +// in order to expose it to the ICS20 transfer handler. +func (k Keeper) PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketAcknowledgementI) error { return k.channelKeeper.PacketExecuted(ctx, packet, acknowledgement) } + +// ChanCloseInit defines a wrapper function for the channel Keeper's function +// in order to expose it to the ICS20 trasfer handler. +func (k Keeper) ChanCloseInit(ctx sdk.Context, portID, channelID string) error { + return k.channelKeeper.ChanCloseInit(ctx, portID, channelID) +} + +// TimeoutExecuted defines a wrapper function for the channel Keeper's function +// in order to expose it to the ICS20 transfer handler. +func (k Keeper) TimeoutExecuted(ctx sdk.Context, packet channelexported.PacketI) error { + return k.channelKeeper.TimeoutExecuted(ctx, packet) +} diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index 4953bb8d2e47..082aa2b12f0b 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -14,9 +14,14 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // define constants used for testing @@ -43,9 +48,9 @@ var ( testAddr1 = sdk.AccAddress([]byte("testaddr1")) testAddr2 = sdk.AccAddress([]byte("testaddr2")) - testCoins, _ = sdk.ParseCoins("100atom") - testPrefixedCoins1, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort1, testChannel1))) - testPrefixedCoins2, _ = sdk.ParseCoins(fmt.Sprintf("100%satom", types.GetDenomPrefix(testPort2, testChannel2))) + testCoins, _ = sdk.ParseCoins("100atom") + prefixCoins = sdk.NewCoins(sdk.NewCoin("bank/firstchannel/atom", sdk.NewInt(100))) + prefixCoins2 = sdk.NewCoins(sdk.NewCoin("testportid/secondchannel/atom", sdk.NewInt(100))) ) type KeeperTestSuite struct { @@ -74,6 +79,86 @@ func (suite *KeeperTestSuite) SetupTest() { suite.createConnection(connectionexported.OPEN) } +func (suite *KeeperTestSuite) createClient() { + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + consensusState := ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: suite.valSet, + } + + clientState, err := ibctmtypes.Initialize(testClient, testClient, consensusState, trustingPeriod, ubdPeriod) + suite.NoError(err) + _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) + suite.NoError(err) +} + +// nolint: unused +func (suite *KeeperTestSuite) updateClient() { + // always commit and begin a new block on updateClient + suite.app.Commit() + commitID := suite.app.LastCommitID() + + suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) + suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + + state := ibctmtypes.ConsensusState{ + Root: commitment.NewRoot(commitID.Hash), + } + + suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, 1, state) +} + +func (suite *KeeperTestSuite) createConnection(state connectionexported.State) { + connection := connection.ConnectionEnd{ + State: state, + ClientID: testClient, + Counterparty: connection.Counterparty{ + ClientID: testClient, + ConnectionID: testConnection, + Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + }, + Versions: connection.GetCompatibleVersions(), + } + + suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) +} + +func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channelexported.State) { + ch := channel.Channel{ + State: state, + Ordering: testChannelOrder, + Counterparty: channel.Counterparty{ + PortID: counterpartyPort, + ChannelID: counterpartyChan, + }, + ConnectionHops: []string{connID}, + Version: testChannelVersion, + } + + suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) +} + +// nolint: unused +func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { + res := suite.app.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: key, + Prove: true, + }) + + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } + + return +} + func (suite *KeeperTestSuite) TestGetTransferAccount() { expectedMaccName := types.GetModuleAccountName() expectedMaccAddr := sdk.AccAddress(crypto.AddressHash([]byte(expectedMaccName))) diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index 49ca031ab3f4..bf2553576eb9 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -9,7 +9,16 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) -// SendTransfer handles transfer sending logic +// SendTransfer handles transfer sending logic. There are 2 possible cases: +// +// 1. Sender chain is the source chain of the coins (i.e where they were minted): the coins +// are transferred to an escrow address (i.e locked) on the sender chain and then +// transferred to the destination chain (i.e not the source chain) via a packet +// with the corresponding fungible token data. +// +// 2. Coins are not native from the sender chain (i.e tokens sent where transferred over +// through IBC already): the coins are burned and then a packet is sent to the +// source chain of the tokens. func (k Keeper) SendTransfer( ctx sdk.Context, sourcePort, @@ -18,16 +27,15 @@ func (k Keeper) SendTransfer( amount sdk.Coins, sender, receiver sdk.AccAddress, - isSourceChain bool, + isSourceChain bool, // is the packet sender the source chain of the token? ) error { - // get the port and channel of the counterparty - sourceChan, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) + sourceChannelEnd, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) if !found { return sdkerrors.Wrap(channel.ErrChannelNotFound, sourceChannel) } - destinationPort := sourceChan.Counterparty.PortID - destinationChannel := sourceChan.Counterparty.ChannelID + destinationPort := sourceChannelEnd.Counterparty.PortID + destinationChannel := sourceChannelEnd.Counterparty.ChannelID // get the next sequence sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel) @@ -35,32 +43,109 @@ func (k Keeper) SendTransfer( return channel.ErrSequenceSendNotFound } - coins := make(sdk.Coins, len(amount)) - prefix := types.GetDenomPrefix(destinationPort, destinationChannel) - switch { - case isSourceChain: - // build the receiving denomination prefix + return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, destHeight, amount, sender, receiver, isSourceChain) +} + +// ReceiveTransfer handles transfer receiving logic. +func (k Keeper) ReceiveTransfer(ctx sdk.Context, packet channel.Packet, data types.FungibleTokenPacketData) error { + return k.onRecvPacket(ctx, packet, data) +} + +// TimeoutTransfer handles transfer timeout logic. +func (k Keeper) TimeoutTransfer(ctx sdk.Context, packet channel.Packet, data types.FungibleTokenPacketData) error { + return k.onTimeoutPacket(ctx, packet, data) +} + +// See spec for this function: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay +func (k Keeper) createOutgoingPacket( + ctx sdk.Context, + seq uint64, + sourcePort, sourceChannel, + destinationPort, destinationChannel string, + destHeight uint64, + amount sdk.Coins, + sender, receiver sdk.AccAddress, + isSourceChain bool, +) error { + // NOTE: + // - Coins transferred from the destination chain should have their denomination + // prefixed with source port and channel IDs. + // - Coins transferred from the source chain can have their denomination + // clear from prefixes when transferred to the escrow account (i.e when they are + // locked) BUT MUST have the destination port and channel ID when constructing + // the packet data. + var prefix string + + if isSourceChain { + // clear the denomination from the prefix to send the coins to the escrow account + coins := make(sdk.Coins, len(amount)) + prefix = types.GetDenomPrefix(destinationPort, destinationChannel) for i, coin := range amount { - coins[i] = sdk.NewCoin(prefix+coin.Denom, coin.Amount) + if strings.HasPrefix(coin.Denom, prefix) { + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) + } else { + coins[i] = coin + } + } + + // escrow tokens if the destination chain is the same as the sender's + escrowAddress := types.GetEscrowAddress(sourcePort, sourceChannel) + + // escrow source tokens. It fails if balance insufficient. + if err := k.bankKeeper.SendCoins( + ctx, sender, escrowAddress, coins, + ); err != nil { + return err + } + + } else { + // build the receiving denomination prefix if it's not present + prefix = types.GetDenomPrefix(sourcePort, sourceChannel) + for i, coin := range amount { + if !strings.HasPrefix(coin.Denom, prefix) { + amount[i] = sdk.NewCoin(prefix+coin.Denom, coin.Amount) + } + } + + // transfer the coins to the module account and burn them + if err := k.supplyKeeper.SendCoinsFromAccountToModule( + ctx, sender, types.GetModuleAccountName(), amount, + ); err != nil { + return err + } + + // burn vouchers from the sender's balance if the source is from another chain + if err := k.supplyKeeper.BurnCoins( + ctx, types.GetModuleAccountName(), amount, + ); err != nil { + // NOTE: should not happen as the module account was + // retrieved on the step above and it has enough balace + // to burn. + return err } - default: - coins = amount } - return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, destHeight, coins, sender, receiver, isSourceChain) + packetData := types.NewFungibleTokenPacketData( + amount, sender, receiver, !isSourceChain, destHeight+DefaultPacketTimeout, + ) + + packet := channel.NewPacket( + packetData, + seq, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + ) + + return k.channelKeeper.SendPacket(ctx, packet) } -// ReceiveTransfer handles transfer receiving logic -func (k Keeper) ReceiveTransfer( - ctx sdk.Context, - sourcePort, - sourceChannel, - destinationPort, - destinationChannel string, - data types.PacketDataTransfer, -) error { +func (k Keeper) onRecvPacket(ctx sdk.Context, packet channel.Packet, data types.FungibleTokenPacketData) error { + // NOTE: packet data type already checked in handler.go + if data.Source { - prefix := types.GetDenomPrefix(destinationPort, destinationChannel) + prefix := types.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel()) for _, coin := range data.Amount { if !strings.HasPrefix(coin.Denom, prefix) { return sdkerrors.Wrapf( @@ -71,19 +156,20 @@ func (k Keeper) ReceiveTransfer( } // mint new tokens if the source of the transfer is the same chain - err := k.supplyKeeper.MintCoins(ctx, types.GetModuleAccountName(), data.Amount) - if err != nil { + if err := k.supplyKeeper.MintCoins( + ctx, types.GetModuleAccountName(), data.Amount, + ); err != nil { return err } // send to receiver - return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Receiver, data.Amount) + return k.supplyKeeper.SendCoinsFromModuleToAccount( + ctx, types.GetModuleAccountName(), data.Receiver, data.Amount, + ) } - // unescrow tokens - // check the denom prefix - prefix := types.GetDenomPrefix(sourcePort, sourceChannel) + prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) coins := make(sdk.Coins, len(data.Amount)) for i, coin := range data.Amount { if !strings.HasPrefix(coin.Denom, prefix) { @@ -95,23 +181,18 @@ func (k Keeper) ReceiveTransfer( coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) } - escrowAddress := types.GetEscrowAddress(destinationPort, destinationChannel) + // unescrow tokens + escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Receiver, coins) - } -// TimeoutTransfer handles transfer timeout logic -func (k Keeper) TimeoutTransfer( - ctx sdk.Context, - sourcePort, - sourceChannel, - destinationPort, - destinationChannel string, - data types.PacketDataTransfer, -) error { +func (k Keeper) onTimeoutPacket(ctx sdk.Context, packet channel.Packet, data types.FungibleTokenPacketData) error { + // NOTE: packet data type already checked in handler.go + // check the denom prefix - prefix := types.GetDenomPrefix(sourcePort, sourceChannel) + prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) coins := make(sdk.Coins, len(data.Amount)) + for i, coin := range data.Amount { coin := coin if !strings.HasPrefix(coin.Denom, prefix) { @@ -121,88 +202,17 @@ func (k Keeper) TimeoutTransfer( } if data.Source { - escrowAddress := types.GetEscrowAddress(destinationPort, destinationChannel) + // unescrow tokens back to sender + escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Sender, coins) } - // mint from supply - err := k.supplyKeeper.MintCoins(ctx, types.GetModuleAccountName(), data.Amount) - if err != nil { + // mint vouchers back to sender + if err := k.supplyKeeper.MintCoins( + ctx, types.GetModuleAccountName(), data.Amount, + ); err != nil { return err } return k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.GetModuleAccountName(), data.Sender, data.Amount) } - -func (k Keeper) createOutgoingPacket( - ctx sdk.Context, - seq uint64, - sourcePort, - sourceChannel, - destinationPort, - destinationChannel string, - destHeight uint64, - amount sdk.Coins, - sender sdk.AccAddress, - receiver sdk.AccAddress, - isSourceChain bool, -) error { - if isSourceChain { - // escrow tokens if the destination chain is the same as the sender's - escrowAddress := types.GetEscrowAddress(sourcePort, sourceChannel) - - prefix := types.GetDenomPrefix(destinationPort, destinationChannel) - coins := make(sdk.Coins, len(amount)) - for i, coin := range amount { - if !strings.HasPrefix(coin.Denom, prefix) { - return sdkerrors.Wrapf( - sdkerrors.ErrInvalidCoins, - "%s doesn't contain the prefix '%s'", coin.Denom, prefix, - ) - } - coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) - } - - err := k.bankKeeper.SendCoins(ctx, sender, escrowAddress, coins) - if err != nil { - return err - } - - } else { - // burn vouchers from the sender's balance if the source is from another chain - prefix := types.GetDenomPrefix(sourcePort, sourceChannel) - for _, coin := range amount { - if !strings.HasPrefix(coin.Denom, prefix) { - return sdkerrors.Wrapf( - sdkerrors.ErrInvalidCoins, - "%s doesn't contain the prefix '%s'", coin.Denom, prefix, - ) - } - } - - // transfer the coins to the module account and burn them - err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, sender, types.GetModuleAccountName(), amount) - if err != nil { - return err - } - - // burn from supply - err = k.supplyKeeper.BurnCoins(ctx, types.GetModuleAccountName(), amount) - if err != nil { - return err - } - } - - packetData := types.NewPacketDataTransfer(amount, sender, receiver, isSourceChain, destHeight+DefaultPacketTimeout) - - packet := channel.NewPacket( - packetData, - seq, - sourcePort, - sourceChannel, - destinationPort, - destinationChannel, - ) - - return k.channelKeeper.SendPacket(ctx, packet) -} diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 8ad5a7e8b5ab..38a0cff55d90 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -3,189 +3,191 @@ package keeper_test import ( "fmt" - abci "github.com/tendermint/tendermint/abci/types" - sdk "github.com/cosmos/cosmos-sdk/types" - connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" - connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/supply" ) -func (suite *KeeperTestSuite) createClient() { - suite.app.Commit() - commitID := suite.app.LastCommitID() - - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - - consensusState := ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, +func (suite *KeeperTestSuite) TestSendTransfer() { + testCoins2 := sdk.NewCoins(sdk.NewCoin("testportid/secondchannel/atom", sdk.NewInt(100))) + testCases := []struct { + msg string + amount sdk.Coins + malleate func() + isSourceChain bool + expPass bool + }{ + {"successful transfer from source chain", testCoins, + func() { + suite.app.BankKeeper.AddCoins(suite.ctx, testAddr1, testCoins) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + }, true, true}, + {"successful transfer from source chain with denom prefix", testCoins2, + func() { + _, err := suite.app.BankKeeper.AddCoins(suite.ctx, testAddr1, testCoins) + suite.Require().NoError(err) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + }, true, true}, + {"successful transfer from external chain", testCoins, + func() { + suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(prefixCoins)) + _, err := suite.app.BankKeeper.AddCoins(suite.ctx, testAddr1, prefixCoins) + suite.Require().NoError(err) + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + }, false, true}, + {"source channel not found", testCoins, + func() {}, true, false}, + {"next seq send not found", testCoins, + func() { + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) + }, true, false}, + // createOutgoingPacket tests + // - source chain + {"send coins failed", testCoins, + func() { + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + }, true, false}, + // - receiving chain + {"send from module account failed", testCoins, + func() { + suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) + suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + }, false, false}, } - clientState, err := ibctmtypes.Initialize(testClient, testClient, consensusState, trustingPeriod, ubdPeriod) - suite.NoError(err) - _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) - suite.NoError(err) -} + for i, tc := range testCases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset -func (suite *KeeperTestSuite) updateClient() { - // always commit and begin a new block on updateClient - suite.app.Commit() - commitID := suite.app.LastCommitID() + tc.malleate() - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) + err := suite.app.TransferKeeper.SendTransfer( + suite.ctx, testPort1, testChannel1, 100, tc.amount, testAddr1, testAddr2, tc.isSourceChain, + ) - state := ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) } - - suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, 1, state) } -func (suite *KeeperTestSuite) createConnection(state connectionexported.State) { - connection := connection.ConnectionEnd{ - State: state, - ClientID: testClient, - Counterparty: connection.Counterparty{ - ClientID: testClient, - ConnectionID: testConnection, - Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), - }, - Versions: connection.GetCompatibleVersions(), +func (suite *KeeperTestSuite) TestReceiveTransfer() { + data := types.NewFungibleTokenPacketData(prefixCoins2, testAddr1, testAddr2, true, 100) + + testCases := []struct { + msg string + malleate func() + expPass bool + }{ + {"success receive from source chain", + func() {}, true}, + // onRecvPacket + // - source chain + {"no dest prefix on coin denom", + func() { + data.Amount = testCoins + }, false}, + {"mint failed", + func() { + data.Source = true + data.Amount = prefixCoins2 + data.Amount[0].Amount = sdk.ZeroInt() + }, false}, + // - receiving chain + {"incorrect dest prefix on coin denom", + func() { + data.Source = false + data.Amount = prefixCoins2 + }, false}, + {"success receive from external chain", + func() { + data.Source = false + data.Amount = prefixCoins + escrow := types.GetEscrowAddress(testPort2, testChannel2) + _, err := suite.app.BankKeeper.AddCoins(suite.ctx, escrow, testCoins) + suite.Require().NoError(err) + }, true}, } - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) -} + packet := channeltypes.NewPacket(data, 1, testPort1, testChannel1, testPort2, testChannel2) -func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channelexported.State) { - ch := channel.Channel{ - State: state, - Ordering: testChannelOrder, - Counterparty: channel.Counterparty{ - PortID: counterpartyPort, - ChannelID: counterpartyChan, - }, - ConnectionHops: []string{connID}, - Version: testChannelVersion, - } + for i, tc := range testCases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + tc.malleate() - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) -} + err := suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, packet, data) -func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { - res := suite.app.Query(abci.RequestQuery{ - Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: key, - Prove: true, - }) - - height = res.Height - proof = commitment.Proof{ - Proof: res.Proof, + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) } - - return } -func (suite *KeeperTestSuite) TestSendTransfer() { - // test the situation where the source is true - isSourceChain := true - - err := suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, isSourceChain) - suite.Error(err) // channel does not exist - - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, isSourceChain) - suite.Error(err) // next send sequence not found - - nextSeqSend := uint64(1) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, isSourceChain) - suite.Error(err) // sender has insufficient coins - - _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testCoins) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, isSourceChain) - suite.NoError(err) // successfully executed - - senderCoins := suite.app.BankKeeper.GetAllBalances(suite.ctx, testAddr1) - suite.Equal(sdk.Coins(nil), senderCoins) - - escrowCoins := suite.app.BankKeeper.GetAllBalances(suite.ctx, types.GetEscrowAddress(testPort1, testChannel1)) - suite.Equal(testCoins, escrowCoins) - - newNextSeqSend, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) - suite.True(found) - suite.Equal(nextSeqSend+1, newNextSeqSend) - - packetCommitment := suite.app.IBCKeeper.ChannelKeeper.GetPacketCommitment(suite.ctx, testPort1, testChannel1, nextSeqSend) - suite.NotNil(packetCommitment) - - // test the situation where the source is false - isSourceChain = false - - _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testPrefixedCoins2) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2, isSourceChain) - suite.Error(err) // incorrect denom prefix - - suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) - _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testPrefixedCoins1) - err = suite.app.TransferKeeper.SendTransfer(suite.ctx, testPort1, testChannel1, 10, testPrefixedCoins1, testAddr1, testAddr2, isSourceChain) - suite.NoError(err) // successfully executed - - senderCoins = suite.app.BankKeeper.GetAllBalances(suite.ctx, testAddr1) - suite.Equal(sdk.Coins(nil), senderCoins) - - totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) - suite.Equal(sdk.Coins(nil), totalSupply.GetTotal()) // supply should be deflated -} - -func (suite *KeeperTestSuite) TestReceiveTransfer() { - // test the situation where the source is true - source := true - packetTimeout := uint64(100) - - packetData := types.NewPacketDataTransfer(testPrefixedCoins1, testAddr1, testAddr2, source, packetTimeout) - err := suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) - suite.Error(err) // incorrect denom prefix - - packetData.Amount = testPrefixedCoins2 - err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) - suite.NoError(err) // successfully executed - - totalSupply := suite.app.SupplyKeeper.GetSupply(suite.ctx) - suite.Equal(testPrefixedCoins2, totalSupply.GetTotal()) // supply should be inflated - - receiverCoins := suite.app.BankKeeper.GetAllBalances(suite.ctx, packetData.Receiver) - suite.Equal(testPrefixedCoins2, receiverCoins) - - // test the situation where the source is false - packetData.Source = false - - packetData.Amount = testPrefixedCoins2 - err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) - suite.Error(err) // incorrect denom prefix +func (suite *KeeperTestSuite) TestTimeoutTransfer() { + data := types.NewFungibleTokenPacketData(prefixCoins, testAddr1, testAddr2, true, 100) + + testCases := []struct { + msg string + malleate func() + expPass bool + }{ + {"successful timeout from source chain", + func() { + escrow := types.GetEscrowAddress(testPort2, testChannel2) + _, err := suite.app.BankKeeper.AddCoins(suite.ctx, escrow, sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(100)))) + suite.Require().NoError(err) + }, true}, + {"successful timeout from external chain", + func() { + data.Source = false + }, true}, + {"no source prefix on coin denom", + func() { + data.Source = true + data.Amount = prefixCoins2 + }, false}, + {"unescrow failed", + func() { + data.Source = true + }, false}, + {"mint failed", + func() { + data.Source = false + data.Amount[0].Denom = prefixCoins[0].Denom + data.Amount[0].Amount = sdk.ZeroInt() + }, false}, + } - packetData.Amount = testPrefixedCoins1 - err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) - suite.Error(err) // insufficient coins in the corresponding escrow account + packet := channeltypes.NewPacket(data, 1, testPort1, testChannel1, testPort2, testChannel2) - escrowAddress := types.GetEscrowAddress(testPort2, testChannel2) - _ = suite.app.BankKeeper.SetBalances(suite.ctx, escrowAddress, testCoins) - _ = suite.app.BankKeeper.SetBalances(suite.ctx, packetData.Receiver, sdk.Coins{}) - err = suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, testPort1, testChannel1, testPort2, testChannel2, packetData) - suite.NoError(err) // successfully executed + for i, tc := range testCases { + tc := tc + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + tc.malleate() - escrowCoins := suite.app.BankKeeper.GetAllBalances(suite.ctx, escrowAddress) - suite.Equal(sdk.Coins(nil), escrowCoins) + err := suite.app.TransferKeeper.TimeoutTransfer(suite.ctx, packet, data) - receiverCoins = suite.app.BankKeeper.GetAllBalances(suite.ctx, packetData.Receiver) - suite.Equal(testCoins, receiverCoins) + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + } + }) + } } diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index 730d7b880b1a..805e122f1bb1 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -14,11 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/rest" - "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" -) - -const ( - ModuleName = types.SubModuleName ) var ( @@ -26,13 +21,15 @@ var ( _ module.AppModuleBasic = AppModuleBasic{} ) +// AppModuleBasic is the 20-transfer appmodulebasic type AppModuleBasic struct{} -// Name returns the IBC transfer ICS name +// Name implements AppModuleBasic interface func (AppModuleBasic) Name() string { - return SubModuleName + return ModuleName } +// RegisterCodec implements AppModuleBasic interface func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { RegisterCodec(cdc) } @@ -48,45 +45,55 @@ func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, _ json.RawMessage) return nil } +// RegisterRESTRoutes implements AppModuleBasic interface func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { rest.RegisterRoutes(ctx, rtr) } +// GetTxCmd implements AppModuleBasic interface func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { return cli.GetTxCmd(cdc) } +// GetQueryCmd implements AppModuleBasic interface func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { return cli.GetQueryCmd(cdc, QuerierRoute) } +// AppModule represents the AppModule for this module type AppModule struct { AppModuleBasic keeper Keeper } +// NewAppModule creates a new 20-transfer module func NewAppModule(k Keeper) AppModule { return AppModule{ keeper: k, } } +// RegisterInvariants implements the AppModule interface func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { // TODO } +// Route implements the AppModule interface func (AppModule) Route() string { return RouterKey } +// NewHandler implements the AppModule interface func (am AppModule) NewHandler() sdk.Handler { return NewHandler(am.keeper) } +// QuerierRoute implements the AppModule interface func (AppModule) QuerierRoute() string { return QuerierRoute } +// NewQuerierHandler implements the AppModule interface func (am AppModule) NewQuerierHandler() sdk.Querier { return nil } @@ -103,10 +110,12 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, _ codec.JSONMarshaler) json.R return nil } +// BeginBlock implements the AppModule interface func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { } +// EndBlock implements the AppModule interface func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } diff --git a/x/ibc/20-transfer/types/codec.go b/x/ibc/20-transfer/types/codec.go index ff87c7fcfeaf..489bd6cd9dce 100644 --- a/x/ibc/20-transfer/types/codec.go +++ b/x/ibc/20-transfer/types/codec.go @@ -12,7 +12,7 @@ var ModuleCdc = codec.New() // RegisterCodec registers the IBC transfer types func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgTransfer{}, "ibc/transfer/MsgTransfer", nil) - cdc.RegisterConcrete(PacketDataTransfer{}, "ibc/transfer/PacketDataTransfer", nil) + cdc.RegisterConcrete(FungibleTokenPacketData{}, "ibc/transfer/PacketDataTransfer", nil) } func init() { diff --git a/x/ibc/20-transfer/types/errors.go b/x/ibc/20-transfer/types/errors.go new file mode 100644 index 000000000000..c0f40d1171b9 --- /dev/null +++ b/x/ibc/20-transfer/types/errors.go @@ -0,0 +1,10 @@ +package types + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// IBC channel sentinel errors +var ( + ErrInvalidPacketTimeout = sdkerrors.Register(ModuleName, 1, "invalid packet timeout") +) diff --git a/x/ibc/20-transfer/types/events.go b/x/ibc/20-transfer/types/events.go index 759548ae1827..f233b49377ff 100644 --- a/x/ibc/20-transfer/types/events.go +++ b/x/ibc/20-transfer/types/events.go @@ -13,5 +13,5 @@ const ( // IBC transfer events vars var ( - AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName) + AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, ModuleName) ) diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index 1b41921815e1..a347fb4e476f 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -19,7 +19,9 @@ type ChannelKeeper interface { GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channel.Channel, found bool) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) SendPacket(ctx sdk.Context, packet channelexported.PacketI) error - PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketDataI) error + PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketAcknowledgementI) error + ChanCloseInit(ctx sdk.Context, portID, channelID string) error + TimeoutExecuted(ctx sdk.Context, packet channelexported.PacketI) error } // ClientKeeper defines the expected IBC client keeper diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go index 1a3a8458ae53..322f1500349a 100644 --- a/x/ibc/20-transfer/types/keys.go +++ b/x/ibc/20-transfer/types/keys.go @@ -10,17 +10,17 @@ import ( ) const ( - // SubModuleName defines the IBC transfer name - SubModuleName = "transfer" + // ModuleName defines the IBC transfer name + ModuleName = "transfer" // StoreKey is the store key string for IBC transfer - StoreKey = SubModuleName + StoreKey = ModuleName // RouterKey is the message route for IBC transfer - RouterKey = SubModuleName + RouterKey = ModuleName // QuerierRoute is the querier route for IBC transfer - QuerierRoute = SubModuleName + QuerierRoute = ModuleName ) // GetEscrowAddress returns the escrow address for the specified channel @@ -39,5 +39,5 @@ func GetDenomPrefix(portID, channelID string) string { // GetModuleAccountName returns the IBC transfer module account name for supply func GetModuleAccountName() string { - return fmt.Sprintf("%s/%s", ibctypes.ModuleName, SubModuleName) + return fmt.Sprintf("%s/%s", ibctypes.ModuleName, ModuleName) } diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index e350850f9498..d707fddc182e 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -3,12 +3,12 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) +// MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between ICS20 enabled chains. +// See ICS Spec here: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#data-structures type MsgTransfer struct { SourcePort string `json:"source_port" yaml:"source_port"` // the port on which the packet will be sent SourceChannel string `json:"source_channel" yaml:"source_channel"` // the channel by which the packet will be sent @@ -76,59 +76,3 @@ func (msg MsgTransfer) GetSignBytes() []byte { func (msg MsgTransfer) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Sender} } - -type MsgRecvPacket struct { - Packet channelexported.PacketI `json:"packet" yaml:"packet"` - Proofs []commitment.Proof `json:"proofs" yaml:"proofs"` - Height uint64 `json:"height" yaml:"height"` - Signer sdk.AccAddress `json:"signer" yaml:"signer"` -} - -// NewMsgRecvPacket creates a new MsgRecvPacket instance -func NewMsgRecvPacket(packet channelexported.PacketI, proofs []commitment.Proof, height uint64, signer sdk.AccAddress) MsgRecvPacket { - return MsgRecvPacket{ - Packet: packet, - Proofs: proofs, - Height: height, - Signer: signer, - } -} - -// Route implements sdk.Msg -func (MsgRecvPacket) Route() string { - return ibctypes.RouterKey -} - -// Type implements sdk.Msg -func (MsgRecvPacket) Type() string { - return "recv_packet" -} - -// ValidateBasic implements sdk.Msg -func (msg MsgRecvPacket) ValidateBasic() error { - if msg.Height == 0 { - return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "height must be > 0") - } - if msg.Proofs == nil || len(msg.Proofs) == 0 { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "missing proof") - } - for _, proof := range msg.Proofs { - if err := proof.ValidateBasic(); err != nil { - return err - } - } - if msg.Signer.Empty() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") - } - return msg.Packet.ValidateBasic() -} - -// GetSignBytes implements sdk.Msg -func (msg MsgRecvPacket) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) -} - -// GetSigners implements sdk.Msg -func (msg MsgRecvPacket) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Signer} -} diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go index ad0955ee745d..9efcaf0000e9 100644 --- a/x/ibc/20-transfer/types/msgs_test.go +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -12,10 +12,12 @@ import ( // define constants used for testing const ( + validPort = "testportid" invalidPort = "invalidport1" invalidShortPort = "p" invalidLongPort = "invalidlongportinvalidlongport" + validChannel = "testchannel" invalidChannel = "invalidchannel1" invalidShortChannel = "invalidch" invalidLongChannel = "invalidlongchannelinvalidlongchannel" @@ -33,14 +35,14 @@ var ( // TestMsgTransferRoute tests Route for MsgTransfer func TestMsgTransferRoute(t *testing.T) { - msg := NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true) + msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true) require.Equal(t, ibctypes.RouterKey, msg.Route()) } // TestMsgTransferType tests Type for MsgTransfer func TestMsgTransferType(t *testing.T) { - msg := NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true) + msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true) require.Equal(t, "transfer", msg.Type()) } @@ -48,18 +50,18 @@ func TestMsgTransferType(t *testing.T) { // TestMsgTransferValidation tests ValidateBasic for MsgTransfer func TestMsgTransferValidation(t *testing.T) { testMsgs := []MsgTransfer{ - NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true), // valid msg - NewMsgTransfer(invalidShortPort, "testchannel", 10, coins, addr1, addr2, true), // too short port id - NewMsgTransfer(invalidLongPort, "testchannel", 10, coins, addr1, addr2, true), // too long port id - NewMsgTransfer(invalidPort, "testchannel", 10, coins, addr1, addr2, true), // port id contains non-alpha - NewMsgTransfer("testportid", invalidShortChannel, 10, coins, addr1, addr2, true), // too short channel id - NewMsgTransfer("testportid", invalidLongChannel, 10, coins, addr1, addr2, false), // too long channel id - NewMsgTransfer("testportid", invalidChannel, 10, coins, addr1, addr2, false), // channel id contains non-alpha - NewMsgTransfer("testportid", "testchannel", 10, invalidDenomCoins, addr1, addr2, false), // invalid amount - NewMsgTransfer("testportid", "testchannel", 10, negativeCoins, addr1, addr2, false), // amount contains negative coin - NewMsgTransfer("testportid", "testchannel", 10, coins, emptyAddr, addr2, false), // missing sender address - NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, emptyAddr, false), // missing recipient address - NewMsgTransfer("testportid", "testchannel", 10, sdk.Coins{}, addr1, addr2, false), // not possitive coin + NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true), // valid msg + NewMsgTransfer(invalidShortPort, validChannel, 10, coins, addr1, addr2, true), // too short port id + NewMsgTransfer(invalidLongPort, validChannel, 10, coins, addr1, addr2, true), // too long port id + NewMsgTransfer(invalidPort, validChannel, 10, coins, addr1, addr2, true), // port id contains non-alpha + NewMsgTransfer(validPort, invalidShortChannel, 10, coins, addr1, addr2, true), // too short channel id + NewMsgTransfer(validPort, invalidLongChannel, 10, coins, addr1, addr2, false), // too long channel id + NewMsgTransfer(validPort, invalidChannel, 10, coins, addr1, addr2, false), // channel id contains non-alpha + NewMsgTransfer(validPort, validChannel, 10, invalidDenomCoins, addr1, addr2, false), // invalid amount + NewMsgTransfer(validPort, validChannel, 10, negativeCoins, addr1, addr2, false), // amount contains negative coin + NewMsgTransfer(validPort, validChannel, 10, coins, emptyAddr, addr2, false), // missing sender address + NewMsgTransfer(validPort, validChannel, 10, coins, addr1, emptyAddr, false), // missing recipient address + NewMsgTransfer(validPort, validChannel, 10, sdk.Coins{}, addr1, addr2, false), // not possitive coin } testCases := []struct { @@ -92,7 +94,7 @@ func TestMsgTransferValidation(t *testing.T) { // TestMsgTransferGetSignBytes tests GetSignBytes for MsgTransfer func TestMsgTransferGetSignBytes(t *testing.T) { - msg := NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true) + msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true) res := msg.GetSignBytes() expected := `{"type":"ibc/transfer/MsgTransfer","value":{"amount":[{"amount":"100","denom":"atom"}],"dest_height":"10","receiver":"cosmos1w3jhxarpv3j8yvs7f9y7g","sender":"cosmos1w3jhxarpv3j8yvg4ufs4x","source":true,"source_channel":"testchannel","source_port":"testportid"}}` @@ -101,7 +103,7 @@ func TestMsgTransferGetSignBytes(t *testing.T) { // TestMsgTransferGetSigners tests GetSigners for MsgTransfer func TestMsgTransferGetSigners(t *testing.T) { - msg := NewMsgTransfer("testportid", "testchannel", 10, coins, addr1, addr2, true) + msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true) res := msg.GetSigners() expected := "[746573746164647231]" diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go index 189ae9b40c63..edee9f60ae82 100644 --- a/x/ibc/20-transfer/types/packet.go +++ b/x/ibc/20-transfer/types/packet.go @@ -9,10 +9,11 @@ import ( channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" ) -var _ channelexported.PacketDataI = PacketDataTransfer{} +var _ channelexported.PacketDataI = FungibleTokenPacketData{} -// PacketDataTransfer defines a struct for the packet payload -type PacketDataTransfer struct { +// FungibleTokenPacketData defines a struct for the packet payload +// See FungibleTokenPacketData spec: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#data-structures +type FungibleTokenPacketData struct { Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain @@ -20,9 +21,11 @@ type PacketDataTransfer struct { Timeout uint64 `json:"timeout" yaml:"timeout"` } -// NewPacketDataTransfer contructs a new PacketDataTransfer -func NewPacketDataTransfer(amount sdk.Coins, sender, receiver sdk.AccAddress, source bool, timeout uint64) PacketDataTransfer { - return PacketDataTransfer{ +// NewFungibleTokenPacketData contructs a new FungibleTokenPacketData instance +func NewFungibleTokenPacketData( + amount sdk.Coins, sender, receiver sdk.AccAddress, + source bool, timeout uint64) FungibleTokenPacketData { + return FungibleTokenPacketData{ Amount: amount, Sender: sender, Receiver: receiver, @@ -31,74 +34,62 @@ func NewPacketDataTransfer(amount sdk.Coins, sender, receiver sdk.AccAddress, so } } -func (pd PacketDataTransfer) String() string { - return fmt.Sprintf(`PacketDataTransfer: +// String returns a string representation of FungibleTokenPacketData +func (ftpd FungibleTokenPacketData) String() string { + return fmt.Sprintf(`FungibleTokenPacketData: Amount: %s Sender: %s Receiver: %s Source: %v`, - pd.Amount.String(), - pd.Sender, - pd.Receiver, - pd.Source, + ftpd.Amount.String(), + ftpd.Sender, + ftpd.Receiver, + ftpd.Source, ) } -// Implements channelexported.PacketDataI -// ValidateBasic performs a basic check of the packet fields -func (pd PacketDataTransfer) ValidateBasic() error { - if !pd.Amount.IsAllPositive() { +// ValidateBasic implements channelexported.PacketDataI +func (ftpd FungibleTokenPacketData) ValidateBasic() error { + if !ftpd.Amount.IsAllPositive() { return sdkerrors.ErrInsufficientFunds } - if !pd.Amount.IsValid() { + if !ftpd.Amount.IsValid() { return sdkerrors.ErrInvalidCoins } - if pd.Sender.Empty() { + if ftpd.Sender.Empty() { return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address") } - if pd.Receiver.Empty() { + if ftpd.Receiver.Empty() { return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing receiver address") } + if ftpd.Timeout == 0 { + return sdkerrors.Wrap(ErrInvalidPacketTimeout, "timeout cannot be 0") + } return nil } -// Implements channelexported.PacketDataI -func (pd PacketDataTransfer) GetBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(pd)) +// GetBytes implements channelexported.PacketDataI +func (ftpd FungibleTokenPacketData) GetBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(ftpd)) } -// Implements channelexported.PacketDataI -func (pd PacketDataTransfer) GetTimeoutHeight() uint64 { - return pd.Timeout +// GetTimeoutHeight implements channelexported.PacketDataI +func (ftpd FungibleTokenPacketData) GetTimeoutHeight() uint64 { + return ftpd.Timeout } -// Implements channelexported.PacketDataI -func (pd PacketDataTransfer) Type() string { +// Type implements channelexported.PacketDataI +func (ftpd FungibleTokenPacketData) Type() string { return "ics20/transfer" } -var _ channelexported.PacketDataI = AckDataTransfer{} - -type AckDataTransfer struct { -} +var _ channelexported.PacketAcknowledgementI = AckDataTransfer{} -// Implements channelexported.PacketDataI -// ValidateBasic performs a basic check of the packet fields -func (ack AckDataTransfer) ValidateBasic() error { - return nil -} +// AckDataTransfer is a no-op packet +// See spec for onAcknowledgePacket: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay +type AckDataTransfer struct{} -// Implements channelexported.PacketDataI +// GetBytes implements channelexported.PacketAcknowledgementI func (ack AckDataTransfer) GetBytes() []byte { - return []byte("ok") -} - -// Implements channelexported.PacketDataI -func (ack AckDataTransfer) GetTimeoutHeight() uint64 { - return 0 -} - -// Implements channelexported.PacketDataI -func (ack AckDataTransfer) Type() string { - return "ics20/transfer/ack" + return []byte("fungible token transfer ack") } diff --git a/x/ibc/20-transfer/types/packet_test.go b/x/ibc/20-transfer/types/packet_test.go index 1a3c1b46fc16..fc188708e60f 100644 --- a/x/ibc/20-transfer/types/packet_test.go +++ b/x/ibc/20-transfer/types/packet_test.go @@ -6,18 +6,19 @@ import ( "github.com/stretchr/testify/require" ) -// TestPacketDataTransferValidation tests ValidateBasic for PacketDataTransfer -func TestPacketDataTransferValidation(t *testing.T) { - testPacketDataTransfer := []PacketDataTransfer{ - NewPacketDataTransfer(coins, addr1, addr2, true, 100), // valid msg - NewPacketDataTransfer(invalidDenomCoins, addr1, addr2, true, 100), // invalid amount - NewPacketDataTransfer(negativeCoins, addr1, addr2, false, 100), // amount contains negative coin - NewPacketDataTransfer(coins, emptyAddr, addr2, false, 100), // missing sender address - NewPacketDataTransfer(coins, addr1, emptyAddr, false, 100), // missing recipient address +// TestFungibleTokenPacketDataValidateBasic tests ValidateBasic for FungibleTokenPacketData +func TestFungibleTokenPacketDataValidateBasic(t *testing.T) { + testPacketDataTransfer := []FungibleTokenPacketData{ + NewFungibleTokenPacketData(coins, addr1, addr2, true, 100), // valid msg + NewFungibleTokenPacketData(invalidDenomCoins, addr1, addr2, true, 100), // invalid amount + NewFungibleTokenPacketData(negativeCoins, addr1, addr2, false, 100), // amount contains negative coin + NewFungibleTokenPacketData(coins, emptyAddr, addr2, false, 100), // missing sender address + NewFungibleTokenPacketData(coins, addr1, emptyAddr, false, 100), + NewFungibleTokenPacketData(coins, addr1, emptyAddr, false, 0), // missing recipient address } testCases := []struct { - packetData PacketDataTransfer + packetData FungibleTokenPacketData expPass bool errMsg string }{ @@ -26,6 +27,7 @@ func TestPacketDataTransferValidation(t *testing.T) { {testPacketDataTransfer[2], false, "amount contains negative coin"}, {testPacketDataTransfer[3], false, "missing sender address"}, {testPacketDataTransfer[4], false, "missing recipient address"}, + {testPacketDataTransfer[5], false, "timeout is 0"}, } for i, tc := range testCases { diff --git a/x/ibc/ante/ante.go b/x/ibc/ante/ante.go index 97f9a99a630f..4301e95c5a10 100644 --- a/x/ibc/ante/ante.go +++ b/x/ibc/ante/ante.go @@ -34,7 +34,7 @@ func (pvr ProofVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim case channel.MsgPacket: _, err = pvr.channelKeeper.RecvPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight) case channel.MsgAcknowledgement: - _, err = pvr.channelKeeper.AcknowledgePacket(ctx, msg.Packet, msg.Acknowledgement.GetBytes(), msg.Proof, msg.ProofHeight) + _, err = pvr.channelKeeper.AcknowledgePacket(ctx, msg.Packet, msg.Acknowledgement, msg.Proof, msg.ProofHeight) case channel.MsgTimeout: _, err = pvr.channelKeeper.TimeoutPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight, msg.NextSequenceRecv) } From c3bb6967d9f14fd557d0022055fcc25993eb2f11 Mon Sep 17 00:00:00 2001 From: Aditya Date: Fri, 21 Feb 2020 09:25:50 -0800 Subject: [PATCH 089/176] Merge PR #5666: Use Tendermint lite client verification --- x/ibc/02-client/keeper/client_test.go | 61 +++- x/ibc/02-client/keeper/keeper_test.go | 16 +- x/ibc/03-connection/keeper/handshake.go | 45 ++- x/ibc/03-connection/keeper/handshake_test.go | 207 +++++------ x/ibc/03-connection/keeper/keeper_test.go | 302 +++++++++------- x/ibc/03-connection/keeper/verify.go | 9 +- x/ibc/03-connection/keeper/verify_test.go | 151 ++++---- x/ibc/04-channel/keeper/handshake_test.go | 255 ++++++------- x/ibc/04-channel/keeper/keeper_test.go | 298 ++++++++++----- x/ibc/04-channel/keeper/packet_test.go | 189 +++++----- x/ibc/04-channel/keeper/timeout_test.go | 112 +++--- x/ibc/07-tendermint/client/cli/tx.go | 24 +- x/ibc/07-tendermint/client/rest/rest.go | 12 +- x/ibc/07-tendermint/client/rest/tx.go | 3 +- x/ibc/07-tendermint/misbehaviour.go | 21 +- x/ibc/07-tendermint/misbehaviour_test.go | 12 +- x/ibc/07-tendermint/tendermint_test.go | 7 +- x/ibc/07-tendermint/types/client_state.go | 42 +-- .../07-tendermint/types/client_state_test.go | 56 +-- x/ibc/07-tendermint/types/errors.go | 2 +- x/ibc/07-tendermint/types/header.go | 39 +- x/ibc/07-tendermint/types/header_test.go | 2 +- x/ibc/07-tendermint/types/msgs.go | 29 +- x/ibc/07-tendermint/types/msgs_test.go | 46 +-- x/ibc/07-tendermint/types/test_utils.go | 5 +- x/ibc/07-tendermint/update.go | 24 +- x/ibc/07-tendermint/update_test.go | 148 +++++++- x/ibc/20-transfer/handler_test.go | 307 +++++++++++----- x/ibc/20-transfer/keeper/keeper_test.go | 277 +++++++++----- x/ibc/20-transfer/keeper/relay_test.go | 55 +-- x/ibc/ante/ante_test.go | 342 ++++++++++++------ x/slashing/keeper/keeper.go | 5 + 32 files changed, 1895 insertions(+), 1208 deletions(-) diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index dcd7ef911474..adde9062b7d3 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "bytes" "fmt" + "time" tmtypes "github.com/tendermint/tendermint/types" @@ -40,12 +41,12 @@ func (suite *KeeperTestSuite) TestCreateClient() { if tc.expPanic { suite.Require().Panics(func() { - clientState, err := ibctmtypes.Initialize(tc.clientID, tc.clientID, suite.consensusState, trustingPeriod, ubdPeriod) + clientState, err := ibctmtypes.Initialize(tc.clientID, trustingPeriod, ubdPeriod, suite.header) suite.Require().NoError(err, "err on client state initialization") suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) }, "Msg %d didn't panic: %s", i, tc.msg) } else { - clientState, err := ibctmtypes.Initialize(tc.clientID, tc.clientID, suite.consensusState, trustingPeriod, ubdPeriod) + clientState, err := ibctmtypes.Initialize(tc.clientID, trustingPeriod, ubdPeriod, suite.header) if tc.expPass { suite.Require().NoError(err, "errored on initialization") suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.msg) @@ -65,38 +66,58 @@ func (suite *KeeperTestSuite) TestCreateClient() { } func (suite *KeeperTestSuite) TestUpdateClient() { + // Must create header creation functions since suite.header gets recreated on each test case + createValidUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header { + return ibctmtypes.CreateTestHeader(testClientID, suite.header.Height+1, suite.header.Time.Add(time.Minute), + suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + } + createInvalidUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header { + return ibctmtypes.CreateTestHeader(testClientID, suite.header.Height-3, suite.header.Time.Add(time.Minute), + suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + } + var updateHeader ibctmtypes.Header + cases := []struct { name string malleate func() error expPass bool }{ {"valid update", func() error { - clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + clientState, err := ibctmtypes.Initialize(testClientID, trustingPeriod, ubdPeriod, suite.header) if err != nil { return err } _, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) + updateHeader = createValidUpdateFn(suite) return err }, true}, {"client type not found", func() error { + updateHeader = createValidUpdateFn(suite) + return nil }, false}, {"client type and header type mismatch", func() error { suite.keeper.SetClientType(suite.ctx, testClientID, invalidClientType) + updateHeader = createValidUpdateFn(suite) + return nil }, false}, {"client state not found", func() error { suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) + updateHeader = createValidUpdateFn(suite) + return nil }, false}, {"frozen client", func() error { - clientState := ibctmtypes.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} + clientState := ibctmtypes.ClientState{FrozenHeight: 1, ID: testClientID, LastHeader: suite.header} suite.keeper.SetClientState(suite.ctx, clientState) suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) + updateHeader = createValidUpdateFn(suite) + return nil }, false}, {"invalid header", func() error { - clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + clientState, err := ibctmtypes.Initialize(testClientID, trustingPeriod, ubdPeriod, suite.header) if err != nil { return err } @@ -104,7 +125,8 @@ func (suite *KeeperTestSuite) TestUpdateClient() { if err != nil { return err } - suite.header.Height = suite.ctx.BlockHeight() - 1 + updateHeader = createInvalidUpdateFn(suite) + return nil }, false}, } @@ -117,19 +139,24 @@ func (suite *KeeperTestSuite) TestUpdateClient() { err := tc.malleate() suite.Require().NoError(err) - err = suite.keeper.UpdateClient(suite.ctx, testClientID, suite.header) + suite.ctx = suite.ctx.WithBlockTime(updateHeader.Time.Add(time.Minute)) + + err = suite.keeper.UpdateClient(suite.ctx, testClientID, updateHeader) if tc.expPass { + suite.Require().NoError(err, err) + expConsensusState := ibctmtypes.ConsensusState{ - Timestamp: suite.header.Time, - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSet: suite.header.ValidatorSet, + Height: uint64(updateHeader.Height), + Timestamp: updateHeader.Time, + Root: commitment.NewRoot(updateHeader.AppHash), + ValidatorSet: updateHeader.ValidatorSet, } clientState, found := suite.keeper.GetClientState(suite.ctx, testClientID) suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) - consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, uint64(suite.header.GetHeight())) + consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, uint64(updateHeader.GetHeight())) suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) tmConsState, ok := consensusState.(ibctmtypes.ConsensusState) suite.Require().True(ok, "consensus state is not a tendermint consensus state") @@ -137,7 +164,7 @@ func (suite *KeeperTestSuite) TestUpdateClient() { tmConsState.ValidatorSet.TotalVotingPower() suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().Equal(suite.header.GetHeight(), clientState.GetLatestHeight(), "client state height not updated correctly on case %s", tc.name) + suite.Require().Equal(updateHeader.GetHeight(), clientState.GetLatestHeight(), "client state height not updated correctly on case %s", tc.name) suite.Require().Equal(expConsensusState, consensusState, "consensus state should have been updated on case %s", tc.name) } else { suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) @@ -181,7 +208,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { }, func() error { suite.consensusState.ValidatorSet = bothValSet - clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + clientState, err := ibctmtypes.Initialize(testClientID, trustingPeriod, ubdPeriod, suite.header) if err != nil { return err } @@ -201,7 +228,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { }, func() error { suite.consensusState.ValidatorSet = bothValSet - clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + clientState, err := ibctmtypes.Initialize(testClientID, trustingPeriod, ubdPeriod, suite.header) if err != nil { return err } @@ -226,7 +253,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { ClientID: testClientID, }, func() error { - clientState := ibctmtypes.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} + clientState := ibctmtypes.ClientState{FrozenHeight: 1, ID: testClientID, LastHeader: suite.header} suite.keeper.SetClientState(suite.ctx, clientState) return nil }, @@ -241,7 +268,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { ClientID: testClientID, }, func() error { - clientState := ibctmtypes.ClientState{FrozenHeight: 1, ID: testClientID, LatestHeight: 10} + clientState := ibctmtypes.ClientState{FrozenHeight: 1, ID: testClientID, LastHeader: suite.header} suite.keeper.SetClientState(suite.ctx, clientState) return nil }, @@ -256,7 +283,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { ClientID: testClientID, }, func() error { - clientState, err := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + clientState, err := ibctmtypes.Initialize(testClientID, trustingPeriod, ubdPeriod, suite.header) if err != nil { return err } diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index 1cdf296ed6b1..afeca9bdefa2 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -56,7 +56,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.privVal = tmtypes.NewMockPV() validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - suite.header = ibctmtypes.CreateTestHeader(testClientID, testClientHeight+2, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = ibctmtypes.CreateTestHeader(testClientID, testClientHeight, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.consensusState = ibctmtypes.ConsensusState{ Height: testClientHeight, Timestamp: suite.now, @@ -82,7 +82,7 @@ func TestKeeperTestSuite(t *testing.T) { } func (suite *KeeperTestSuite) TestSetClientState() { - clientState := ibctmtypes.NewClientState(testClientID, testClientID, trustingPeriod, ubdPeriod, testClientHeight, suite.now) + clientState := ibctmtypes.NewClientState(testClientID, trustingPeriod, ubdPeriod, ibctmtypes.Header{}) suite.keeper.SetClientState(suite.ctx, clientState) retrievedState, found := suite.keeper.GetClientState(suite.ctx, testClientID) @@ -113,9 +113,9 @@ func (suite *KeeperTestSuite) TestSetClientConsensusState() { func (suite KeeperTestSuite) TestGetAllClients() { expClients := []exported.ClientState{ - ibctmtypes.NewClientState(testClientID2, testClientID, trustingPeriod, ubdPeriod, testClientHeight, suite.now), - ibctmtypes.NewClientState(testClientID3, testClientID, trustingPeriod, ubdPeriod, testClientHeight, suite.now), - ibctmtypes.NewClientState(testClientID, testClientID, trustingPeriod, ubdPeriod, testClientHeight, suite.now), + ibctmtypes.NewClientState(testClientID2, trustingPeriod, ubdPeriod, ibctmtypes.Header{}), + ibctmtypes.NewClientState(testClientID3, trustingPeriod, ubdPeriod, ibctmtypes.Header{}), + ibctmtypes.NewClientState(testClientID, trustingPeriod, ubdPeriod, ibctmtypes.Header{}), } for i := range expClients { @@ -155,7 +155,7 @@ func (suite KeeperTestSuite) TestGetConsensusState() { func (suite KeeperTestSuite) TestConsensusStateHelpers() { // initial setup - clientState, _ := ibctmtypes.Initialize(testClientID, testClientID, suite.consensusState, trustingPeriod, ubdPeriod) + clientState, _ := ibctmtypes.Initialize(testClientID, trustingPeriod, ubdPeriod, suite.header) suite.keeper.SetClientState(suite.ctx, clientState) suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) @@ -166,9 +166,11 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() { ValidatorSet: suite.valSet, } + header := ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.header.Time.Add(time.Minute), suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + // mock update functionality + clientState.LastHeader = header suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+5, nextState) - clientState.LatestHeight += 5 suite.keeper.SetClientState(suite.ctx, clientState) latest, ok := suite.keeper.GetLatestClientConsensusState(suite.ctx, testClientID) diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index 9430d8ee2eb4..497c52455e56 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -49,12 +49,12 @@ func (k Keeper) ConnOpenTry( ctx sdk.Context, connectionID string, // desiredIdentifier counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier - clientID string, - counterpartyVersions []string, - proofInit commitment.ProofI, - proofConsensus commitment.ProofI, - proofHeight uint64, - consensusHeight uint64, + clientID string, // clientID of chainA + counterpartyVersions []string, // supported versions of chain A + proofInit commitment.ProofI, // proof that chainA stored connectionEnd in state (on ConnOpenInit) + proofConsensus commitment.ProofI, // proof that chainA stored chainB's consensus state at consensus height + proofHeight uint64, // height at which relayer constructs proof of A storing connectionEnd in state + consensusHeight uint64, // latest height of chain B which chain A has stored in its chain B client ) error { if consensusHeight > uint64(ctx.BlockHeight()) { return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") @@ -78,6 +78,7 @@ func (k Keeper) ConnOpenTry( // connection defines chain B's ConnectionEnd connection := types.NewConnectionEnd(exported.UNINITIALIZED, clientID, counterparty, []string{version}) + // Check that ChainA committed expectedConnectionEnd to its state if err := k.VerifyConnectionState( ctx, connection, proofHeight, proofInit, counterparty.ConnectionID, expectedConnection, @@ -85,12 +86,16 @@ func (k Keeper) ConnOpenTry( return err } + // Check that ChainA stored the correct ConsensusState of chainB at the given consensusHeight if err := k.VerifyClientConsensusState( ctx, connection, consensusHeight, proofConsensus, expectedConsensusState, ); err != nil { return err } + // If connection already exists for connectionID, ensure that the existing connection's counterparty + // is chainA and connection is on INIT stage + // Check that existing connection version is on desired version of current handshake previousConnection, found := k.GetConnection(ctx, connectionID) if found && !(previousConnection.State == exported.INIT && previousConnection.Counterparty.ConnectionID == counterparty.ConnectionID && @@ -101,6 +106,7 @@ func (k Keeper) ConnOpenTry( return sdkerrors.Wrap(types.ErrInvalidConnection, "cannot relay connection attempt") } + // Set connection state to TRYOPEN and store in chainB state connection.State = exported.TRYOPEN if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { return sdkerrors.Wrap(err, "cannot relay connection attempt") @@ -118,21 +124,24 @@ func (k Keeper) ConnOpenTry( func (k Keeper) ConnOpenAck( ctx sdk.Context, connectionID string, - version string, - proofTry commitment.ProofI, - proofConsensus commitment.ProofI, - proofHeight uint64, - consensusHeight uint64, + version string, // version that ChainB chose in ConnOpenTry + proofTry commitment.ProofI, // proof that connectionEnd was added to ChainB state in ConnOpenTry + proofConsensus commitment.ProofI, // proof that chainB has stored ConsensusState of chainA on its client + proofHeight uint64, // height that relayer constructed proofTry + consensusHeight uint64, // latest height of chainA that chainB has stored on its chainA client ) error { + // Check that chainB client hasn't stored invalid height if consensusHeight > uint64(ctx.BlockHeight()) { return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "invalid consensus height") } + // Retrieve connection connection, found := k.GetConnection(ctx, connectionID) if !found { return sdkerrors.Wrap(types.ErrConnectionNotFound, "cannot relay ACK of open attempt") } + // Check connection on ChainA is on correct state: INIT if connection.State != exported.INIT { return sdkerrors.Wrapf( types.ErrInvalidConnectionState, @@ -140,12 +149,15 @@ func (k Keeper) ConnOpenAck( ) } + // Check that ChainB's proposed version is one of chainA's accepted versions if types.LatestVersion(connection.Versions) != version { return sdkerrors.Wrapf( ibctypes.ErrInvalidVersion, "connection version does't match provided one (%s ≠ %s)", types.LatestVersion(connection.Versions), version, ) } + + // Retrieve chainA's consensus state at consensusheight expectedConsensusState, found := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if !found { return clienttypes.ErrConsensusStateNotFound @@ -155,6 +167,7 @@ func (k Keeper) ConnOpenAck( expectedCounterparty := types.NewCounterparty(connection.ClientID, connectionID, prefix) expectedConnection := types.NewConnectionEnd(exported.TRYOPEN, connection.Counterparty.ClientID, expectedCounterparty, []string{version}) + // Ensure that ChainB stored expected connectionEnd in its state during ConnOpenTry if err := k.VerifyConnectionState( ctx, connection, proofHeight, proofTry, connection.Counterparty.ConnectionID, expectedConnection, @@ -162,12 +175,14 @@ func (k Keeper) ConnOpenAck( return err } + // Ensure that ChainB has stored the correct ConsensusState for chainA at the consensusHeight if err := k.VerifyClientConsensusState( ctx, connection, consensusHeight, proofConsensus, expectedConsensusState, ); err != nil { return err } + // Update connection state to Open connection.State = exported.OPEN connection.Versions = []string{version} k.SetConnection(ctx, connectionID, connection) @@ -182,14 +197,16 @@ func (k Keeper) ConnOpenAck( func (k Keeper) ConnOpenConfirm( ctx sdk.Context, connectionID string, - proofAck commitment.ProofI, - proofHeight uint64, + proofAck commitment.ProofI, // proof that connection opened on ChainA during ConnOpenAck + proofHeight uint64, // height that relayer constructed proofAck ) error { + // Retrieve connection connection, found := k.GetConnection(ctx, connectionID) if !found { return sdkerrors.Wrap(types.ErrConnectionNotFound, "cannot relay ACK of open attempt") } + // Check that connection state on ChainB is on state: TRYOPEN if connection.State != exported.TRYOPEN { return sdkerrors.Wrapf( types.ErrInvalidConnectionState, @@ -201,6 +218,7 @@ func (k Keeper) ConnOpenConfirm( expectedCounterparty := types.NewCounterparty(connection.ClientID, connectionID, prefix) expectedConnection := types.NewConnectionEnd(exported.OPEN, connection.Counterparty.ClientID, expectedCounterparty, connection.Versions) + // Check that connection on ChainA is open if err := k.VerifyConnectionState( ctx, connection, proofHeight, proofAck, connection.Counterparty.ConnectionID, expectedConnection, @@ -208,6 +226,7 @@ func (k Keeper) ConnOpenConfirm( return err } + // Update ChainB's connection to Open connection.State = exported.OPEN k.SetConnection(ctx, connectionID, connection) k.Logger(ctx).Info(fmt.Sprintf("connection %s state updated: TRYOPEN -> OPEN ", connectionID)) diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index 133349195c4e..e3586b13b5b9 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -12,24 +12,28 @@ import ( // TestConnOpenInit - Chain A (ID #1) initializes (INIT state) a connection with // Chain B (ID #2) which is yet UNINITIALIZED func (suite *KeeperTestSuite) TestConnOpenInit() { - testCases := []testCase{ + testCases := []struct { + msg string + malleate func() + expPass bool + }{ {"success", func() { - suite.createClient(testClientID1) + suite.chainA.CreateClient(suite.chainB) }, true}, {"connection already exists", func() { - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.INIT) }, false}, {"couldn't add connection to client", func() {}, false}, } - counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + counterparty := connection.NewCounterparty(testClientIDA, testConnectionIDB, suite.chainA.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) for i, tc := range testCases { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset tc.malleate() - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty) + err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), testConnectionIDA, testClientIDB, counterparty) if tc.expPass { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) @@ -44,7 +48,7 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { // connection on Chain A (ID #1) is INIT func (suite *KeeperTestSuite) TestConnOpenTry() { counterparty := connection.NewCounterparty( - testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + testClientIDB, testConnectionIDA, suite.chainB.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), ) var ( @@ -59,50 +63,50 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { expPass bool }{ {"success", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - suite.createClient(testClientID1) // height = 2 - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) - proofHeight = suite.ctx.BlockHeight() - suite.createClient(testClientID2) - consensusHeight = suite.ctx.BlockHeight() // height = 3 - suite.updateClient(testClientID1) - suite.updateClient(testClientID2) + suite.chainB.CreateClient(suite.chainA) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) + proofHeight = suite.chainA.Header.Height + suite.chainA.CreateClient(suite.chainB) + consensusHeight = suite.chainB.Header.Height + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) }, true}, {"consensus height > latest height", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { consensusHeight = 100 }, false}, - {"self consensus state not found", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - consensusHeight = 100 - suite.ctx = suite.ctx.WithBlockHeight(100) - }, false}, + // {"self consensus state not found", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { + // consensusHeight = 100 + // suite.ctx = suite.ctx.WithBlockHeight(100) + // }, false}, {"connection state verification invalid", ibctypes.InvalidProof{}, ibctypes.ValidProof{}, func() { - suite.createClient(testClientID1) - suite.createClient(testClientID2) - consensusHeight = suite.ctx.BlockHeight() - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.UNINITIALIZED) - suite.updateClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) + suite.chainA.CreateClient(suite.chainB) + consensusHeight = suite.chainB.Header.Height + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.UNINITIALIZED) + suite.chainB.updateClient(suite.chainA) }, false}, {"consensus state verification invalid", ibctypes.ValidProof{}, ibctypes.InvalidProof{}, func() { - suite.createClient(testClientID1) // height = 2 - suite.createClient(testClientID2) - consensusHeight = suite.ctx.BlockHeight() - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) - suite.updateClient(testClientID1) - suite.updateClient(testClientID2) + suite.chainB.CreateClient(suite.chainA) + suite.chainA.CreateClient(suite.chainB) + consensusHeight = suite.chainB.Header.Height + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) }, false}, {"invalid previous connection", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - suite.createClient(testClientID1) // height = 2 - suite.createClient(testClientID2) - consensusHeight = suite.ctx.BlockHeight() - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) - suite.updateClient(testClientID1) - suite.updateClient(testClientID2) + suite.chainB.CreateClient(suite.chainA) + suite.chainA.CreateClient(suite.chainB) + consensusHeight = suite.chainB.Header.Height + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.UNINITIALIZED) + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) }, false}, {"couldn't add connection to client", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - suite.createClient(testClientID1) // height = 2 - consensusHeight = suite.ctx.BlockHeight() - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) - suite.updateClient(testClientID1) - suite.updateClient(testClientID2) + suite.chainB.CreateClient(suite.chainA) + consensusHeight = suite.chainB.Header.Height + suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, exported.UNINITIALIZED) + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) }, false}, } @@ -113,14 +117,14 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { tc.malleate() - // connectionKey := ibctypes.KeyConnection(testConnectionID1) + // connectionKey := ibctypes.KeyConnection(testConnectionIDA) // proofInit, proofHeight := suite.queryProof(connectionKey) - // consensusKey := ibctypes.KeyConsensusState(testClientID1, uint64(proofHeight)) + // consensusKey := ibctypes.KeyConsensusState(testClientIDA, uint64(proofHeight)) // proofConsensus, consensusHeight := suite.queryProof(consensusKey) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry( - suite.ctx, testConnectionID2, counterparty, testClientID2, + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( + suite.chainB.GetContext(), testConnectionIDB, counterparty, testClientIDA, connection.GetCompatibleVersions(), tc.proofInit, tc.proofConsensus, uint64(proofHeight), uint64(consensusHeight), ) @@ -153,53 +157,52 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { expPass bool }{ {"success", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - suite.createClient(testClientID2) - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) - proofHeight = suite.ctx.BlockHeight() - consensusHeight = suite.ctx.BlockHeight() - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) - suite.updateClient(testClientID1) - suite.updateClient(testClientID2) + suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) + consensusHeight = suite.chainB.Header.Height + proofHeight = suite.chainA.Header.Height + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) }, true}, {"consensus height > latest height", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { consensusHeight = 100 }, false}, {"connection not found", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - consensusHeight = suite.ctx.BlockHeight() + consensusHeight = suite.chainB.Header.Height }, false}, {"connection state is not INIT", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.UNINITIALIZED) - suite.updateClient(testClientID1) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.UNINITIALIZED) + suite.chainB.updateClient(suite.chainA) }, false}, {"incompatible IBC versions", "2.0", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) - suite.updateClient(testClientID1) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.INIT) + suite.chainB.updateClient(suite.chainA) }, false}, {"self consensus state not found", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - suite.createClient(testClientID1) - suite.createClient(testClientID2) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) - suite.updateClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) + suite.chainB.updateClient(suite.chainA) consensusHeight = 100 - suite.ctx = suite.ctx.WithBlockHeight(100) }, false}, {"connection state verification failed", version, ibctypes.InvalidProof{}, ibctypes.ValidProof{}, func() { - suite.createClient(testClientID1) - consensusHeight = suite.ctx.BlockHeight() - suite.createClient(testClientID2) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) - suite.updateClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) + consensusHeight = suite.chainB.Header.Height + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.UNINITIALIZED) + suite.chainB.updateClient(suite.chainA) }, false}, {"consensus state verification failed", version, ibctypes.ValidProof{}, ibctypes.InvalidProof{}, func() { - suite.createClient(testClientID1) - consensusHeight = suite.ctx.BlockHeight() - suite.createClient(testClientID2) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) - suite.updateClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) + consensusHeight = suite.chainB.Header.Height + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.UNINITIALIZED) + suite.chainB.updateClient(suite.chainA) }, false}, } @@ -210,14 +213,14 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { tc.malleate() - // connectionKey := ibctypes.KeyConnection(testConnectionID2) + // connectionKey := ibctypes.KeyConnection(testConnectionIDB) // proofTry, proofHeight := suite.queryProof(connectionKey) - // consensusKey := ibctypes.KeyConsensusState(testClientID2, uint64(proofHeight)) + // consensusKey := ibctypes.KeyConsensusState(testClientIDB, uint64(proofHeight)) // proofConsensus, consensusHeight := suite.queryProof(consensusKey) - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck( - suite.ctx, testConnectionID1, tc.version, tc.proofTry, tc.proofConsensus, + err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenAck( + suite.chainA.GetContext(), testConnectionIDA, tc.version, tc.proofTry, tc.proofConsensus, uint64(proofHeight), uint64(consensusHeight), ) @@ -233,33 +236,36 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // TestConnOpenAck - Chain B (ID #2) calls ConnOpenConfirm to confirm that // Chain A (ID #1) state is now OPEN. func (suite *KeeperTestSuite) TestConnOpenConfirm() { - consensusHeight := int64(0) + // consensusHeight := int64(0) + proofHeight := int64(0) testCases := []testCase{ {"success", func() { - suite.createClient(testClientID1) - suite.createClient(testClientID2) - consensusHeight = suite.ctx.BlockHeight() - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) - suite.updateClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) + suite.chainA.CreateClient(suite.chainB) + proofHeight = suite.chainB.Header.Height + // consensusHeight = suite.chainA.Header.Height + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.OPEN) + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) + suite.chainB.updateClient(suite.chainA) }, true}, {"connection not found", func() {}, false}, {"chain B's connection state is not TRYOPEN", func() { - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.UNINITIALIZED) + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.UNINITIALIZED) }, false}, {"consensus state not found", func() { - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) - suite.updateClient(testClientID2) + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) + suite.chainA.updateClient(suite.chainB) }, false}, {"connection state verification failed", func() { - suite.createClient(testClientID1) - suite.createClient(testClientID2) - consensusHeight = suite.ctx.BlockHeight() - suite.updateClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.INIT) - suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, exported.TRYOPEN) - suite.updateClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) + suite.chainA.CreateClient(suite.chainB) + // consensusHeight = suite.chainA.Header.Height + proofHeight = suite.chainB.Header.Height + suite.chainB.updateClient(suite.chainA) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) + suite.chainA.updateClient(suite.chainA) }, false}, } @@ -270,18 +276,17 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { tc.malleate() - // connectionKey := ibctypes.KeyConnection(testConnectionID2) + // connectionKey := ibctypes.KeyConnection(testConnectionIDB) // proofAck, proofHeight := suite.queryProof(connectionKey) - proofHeight := consensusHeight - 1 if tc.expPass { - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( - suite.ctx, testConnectionID2, ibctypes.ValidProof{}, uint64(proofHeight), + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( + suite.chainB.GetContext(), testConnectionIDB, ibctypes.ValidProof{}, uint64(proofHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( - suite.ctx, testConnectionID2, ibctypes.InvalidProof{}, uint64(proofHeight), + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( + suite.chainB.GetContext(), testConnectionIDB, ibctypes.InvalidProof{}, uint64(proofHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index c4e7f63e03d1..36bb2ea36472 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -2,13 +2,11 @@ package keeper_test import ( "fmt" - "math/rand" "testing" "time" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" - tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" @@ -30,11 +28,11 @@ const ( storeKey = ibctypes.StoreKey chainID = "gaia" - testClientID1 = "testclientidone" - testConnectionID1 = "connectionidone" + testClientIDA = "testclientida" // chainid for chainA also chainB's clientID for A's liteclient + testConnectionIDA = "connectionidatob" - testClientID2 = "testclientidtwo" - testConnectionID2 = "connectionidtwo" + testClientIDB = "testclientidb" // chainid for chainB also chainA's clientID for B's liteclient + testConnectionIDB = "connectionidbtoa" testClientID3 = "testclientidthree" testConnectionID3 = "connectionidthree" @@ -43,59 +41,30 @@ const ( ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) -var testHeight uint64 - type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp - valSet *tmtypes.ValidatorSet - consensusState clientexported.ConsensusState - header ibctmtypes.Header - now time.Time + cdc *codec.Codec + + // ChainA testing fields + chainA *TestChain + + // ChainB testing fields + chainB *TestChain } func (suite *KeeperTestSuite) SetupTest() { - testHeight = 1 - isCheckTx := false - app := simapp.Setup(isCheckTx) - suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) - now2 := suite.now.Add(time.Duration(time.Hour * 1)) - - suite.cdc = app.Codec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{ChainID: chainID, Height: 1}) - suite.app = app - privVal := tmtypes.NewMockPV() - validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) - suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - suite.header = ibctmtypes.CreateTestHeader(chainID, int64(testHeight), now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{privVal}) - suite.consensusState = ibctmtypes.ConsensusState{ - Height: testHeight, - Timestamp: suite.now, - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSet: suite.valSet, - } - - var validators staking.Validators - for i := 1; i < 11; i++ { - privVal := tmtypes.NewMockPV() - pk := privVal.GetPubKey() - val := staking.NewValidator(sdk.ValAddress(pk.Address()), pk, staking.Description{}) - val.Status = sdk.Bonded - val.Tokens = sdk.NewInt(rand.Int63()) - validators = append(validators, val) + suite.chainA = NewTestChain(testClientIDA) + suite.chainB = NewTestChain(testClientIDB) - app.StakingKeeper.SetHistoricalInfo(suite.ctx, int64(i), staking.NewHistoricalInfo(suite.ctx.BlockHeader(), validators)) - } + suite.cdc = suite.chainA.App.Codec() } // nolint: unused func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { - res := suite.app.Query(abci.RequestQuery{ + res := suite.chainA.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", storeKey), - Height: suite.app.LastBlockHeight(), + Height: suite.chainA.App.LastBlockHeight(), Data: key, Prove: true, }) @@ -106,27 +75,121 @@ func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { return proof, res.Height } +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} -func (suite *KeeperTestSuite) createClient(clientID string) { - suite.app.Commit() - commitID := suite.app.LastCommitID() - suite.now = suite.now.Add(time.Minute) +func (suite *KeeperTestSuite) TestSetAndGetConnection() { + _, existed := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), testConnectionIDA) + suite.Require().False(existed) - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1, Time: suite.now}}) - suite.ctx = suite.ctx.WithBlockHeight(suite.ctx.BlockHeight() + 1) - testHeight++ + counterparty := types.NewCounterparty(testClientIDA, testConnectionIDA, suite.chainA.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + expConn := types.NewConnectionEnd(exported.INIT, testClientIDB, counterparty, types.GetCompatibleVersions()) + suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionIDA, expConn) + conn, existed := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), testConnectionIDA) + suite.Require().True(existed) + suite.Require().EqualValues(expConn, conn) +} - consensusState := ibctmtypes.ConsensusState{ - Height: testHeight, - Timestamp: suite.now, - Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, +func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { + _, existed := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.chainA.GetContext(), testClientIDA) + suite.False(existed) + + suite.chainA.App.IBCKeeper.ConnectionKeeper.SetClientConnectionPaths(suite.chainA.GetContext(), testClientIDB, types.GetCompatibleVersions()) + paths, existed := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.chainA.GetContext(), testClientIDB) + suite.True(existed) + suite.EqualValues(types.GetCompatibleVersions(), paths) +} + +func (suite KeeperTestSuite) TestGetAllConnections() { + // Connection (Counterparty): A(C) -> C(B) -> B(A) + counterparty1 := types.NewCounterparty(testClientIDA, testConnectionIDA, suite.chainA.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + counterparty2 := types.NewCounterparty(testClientIDB, testConnectionIDB, suite.chainA.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + counterparty3 := types.NewCounterparty(testClientID3, testConnectionID3, suite.chainA.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + + conn1 := types.NewConnectionEnd(exported.INIT, testClientIDA, counterparty3, types.GetCompatibleVersions()) + conn2 := types.NewConnectionEnd(exported.INIT, testClientIDB, counterparty1, types.GetCompatibleVersions()) + conn3 := types.NewConnectionEnd(exported.UNINITIALIZED, testClientID3, counterparty2, types.GetCompatibleVersions()) + + expConnections := []types.ConnectionEnd{conn1, conn2, conn3} + + suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionIDA, expConnections[0]) + suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionIDB, expConnections[1]) + suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionID3, expConnections[2]) + + connections := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetAllConnections(suite.chainA.GetContext()) + suite.Require().Len(connections, len(expConnections)) + suite.Require().ElementsMatch(expConnections, connections) +} + +type TestChain struct { + ClientID string + App *simapp.SimApp + Header ibctmtypes.Header + Vals *tmtypes.ValidatorSet + Signers []tmtypes.PrivValidator +} + +func NewTestChain(clientID string) *TestChain { + privVal := tmtypes.NewMockPV() + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + signers := []tmtypes.PrivValidator{privVal} + now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + + return &TestChain{ + ClientID: clientID, + App: simapp.Setup(false), + Header: header, + Vals: valSet, + Signers: signers, + } +} + +// Creates simple context for testing purposes +func (chain *TestChain) GetContext() sdk.Context { + return chain.App.BaseApp.NewContext(false, abci.Header{ChainID: chain.Header.ChainID, Height: chain.Header.Height}) +} + +// createClient will create a client for clientChain on targetChain +func (chain *TestChain) CreateClient(client *TestChain) error { + client.Header = nextHeader(client) + // Commit and create a new block on appTarget to get a fresh CommitID + client.App.Commit() + commitID := client.App.LastCommitID() + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) + + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) // get one voting power + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, + }, + Valset: validators, } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) - clientState, err := ibctmtypes.Initialize(clientID, clientID, consensusState, trustingPeriod, ubdPeriod) - suite.Require().NoError(err) - _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) - suite.Require().NoError(err) + // Create target ctx + ctxTarget := chain.GetContext() + + // create client + clientState, err := ibctmtypes.Initialize(client.ClientID, trustingPeriod, ubdPeriod, client.Header) + if err != nil { + return err + } + _, err = chain.App.IBCKeeper.ClientKeeper.CreateClient(ctxTarget, clientState, client.Header.ConsensusState()) + if err != nil { + return err + } + return nil // _, _, err := simapp.SignCheckDeliver( // suite.T(), @@ -140,28 +203,53 @@ func (suite *KeeperTestSuite) createClient(clientID string) { // ) } -func (suite *KeeperTestSuite) updateClient(clientID string) { +func (chain *TestChain) updateClient(client *TestChain) { + // Create chain ctx + ctxTarget := chain.GetContext() + + // if clientState does not already exist, return without updating + _, found := chain.App.IBCKeeper.ClientKeeper.GetClientState( + ctxTarget, client.ClientID, + ) + if !found { + return + } + // always commit when updateClient and begin a new block - suite.app.Commit() - commitID := suite.app.LastCommitID() - suite.now = suite.now.Add(time.Minute) + client.App.Commit() + commitID := client.App.LastCommitID() + + client.Header = nextHeader(client) + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1, Time: suite.now}}) - suite.ctx = suite.ctx.WithBlockHeight(suite.ctx.BlockHeight() + 1) - testHeight++ + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, + }, + Valset: validators, + } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) consensusState := ibctmtypes.ConsensusState{ - Height: testHeight, - Timestamp: suite.now, + Height: uint64(client.Header.Height), + Timestamp: client.Header.Time, Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, + ValidatorSet: client.Vals, } - suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState( - suite.ctx, clientID, uint64(suite.app.LastBlockHeight()), consensusState, + chain.App.IBCKeeper.ClientKeeper.SetClientConsensusState( + ctxTarget, client.ClientID, uint64(client.Header.Height), consensusState, ) - suite.app.IBCKeeper.ClientKeeper.SetClientState( - suite.ctx, ibctmtypes.NewClientState(clientID, clientID, trustingPeriod, ubdPeriod, uint64(suite.app.LastBlockHeight()), suite.now), + chain.App.IBCKeeper.ClientKeeper.SetClientState( + ctxTarget, ibctmtypes.NewClientState(client.ClientID, trustingPeriod, ubdPeriod, client.Header), ) // _, _, err := simapp.SignCheckDeliver( @@ -177,22 +265,23 @@ func (suite *KeeperTestSuite) updateClient(clientID string) { // suite.Require().NoError(err) } -func (suite *KeeperTestSuite) createConnection( +func (chain *TestChain) createConnection( connID, counterpartyConnID, clientID, counterpartyClientID string, state exported.State, ) types.ConnectionEnd { - counterparty := types.NewCounterparty(counterpartyClientID, counterpartyConnID, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + counterparty := types.NewCounterparty(counterpartyClientID, counterpartyConnID, chain.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) connection := types.ConnectionEnd{ State: state, ClientID: clientID, Counterparty: counterparty, Versions: types.GetCompatibleVersions(), } - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, connID, connection) + ctx := chain.GetContext() + chain.App.IBCKeeper.ConnectionKeeper.SetConnection(ctx, connID, connection) return connection } -func (suite *KeeperTestSuite) createChannel( +func (chain *TestChain) createChannel( portID, channelID, counterpartyPortID, counterpartyChannelID string, state channelexported.State, order channelexported.Order, connectionID string, ) channeltypes.Channel { @@ -200,53 +289,12 @@ func (suite *KeeperTestSuite) createChannel( channel := channeltypes.NewChannel(state, order, counterparty, []string{connectionID}, "1.0", ) - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, channelID, channel) + ctx := chain.GetContext() + chain.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, portID, channelID, channel) return channel } -func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(KeeperTestSuite)) -} - -func (suite *KeeperTestSuite) TestSetAndGetConnection() { - _, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) - suite.Require().False(existed) - - counterparty := types.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - expConn := types.NewConnectionEnd(exported.INIT, testClientID1, counterparty, types.GetCompatibleVersions()) - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID1, expConn) - conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1) - suite.Require().True(existed) - suite.Require().EqualValues(expConn, conn) -} - -func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { - _, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1) - suite.False(existed) - - suite.app.IBCKeeper.ConnectionKeeper.SetClientConnectionPaths(suite.ctx, testClientID1, types.GetCompatibleVersions()) - paths, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1) - suite.True(existed) - suite.EqualValues(types.GetCompatibleVersions(), paths) -} - -func (suite KeeperTestSuite) TestGetAllConnections() { - // Connection (Counterparty): A(C) -> C(B) -> B(A) - counterparty1 := types.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - counterparty2 := types.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - counterparty3 := types.NewCounterparty(testClientID3, testConnectionID3, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) - - conn1 := types.NewConnectionEnd(exported.INIT, testClientID1, counterparty3, types.GetCompatibleVersions()) - conn2 := types.NewConnectionEnd(exported.INIT, testClientID2, counterparty1, types.GetCompatibleVersions()) - conn3 := types.NewConnectionEnd(exported.UNINITIALIZED, testClientID3, counterparty2, types.GetCompatibleVersions()) - - expConnections := []types.ConnectionEnd{conn1, conn2, conn3} - - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID1, expConnections[0]) - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID2, expConnections[1]) - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID3, expConnections[2]) - - connections := suite.app.IBCKeeper.ConnectionKeeper.GetAllConnections(suite.ctx) - suite.Require().Len(connections, len(expConnections)) - suite.Require().ElementsMatch(expConnections, connections) +func nextHeader(chain *TestChain) ibctmtypes.Header { + return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, + chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) } diff --git a/x/ibc/03-connection/keeper/verify.go b/x/ibc/03-connection/keeper/verify.go index e9264746a1d0..4741cb359c3a 100644 --- a/x/ibc/03-connection/keeper/verify.go +++ b/x/ibc/03-connection/keeper/verify.go @@ -19,9 +19,10 @@ func (k Keeper) VerifyClientConsensusState( proof commitment.ProofI, consensusState clientexported.ConsensusState, ) error { - clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) + clientID := connection.GetClientID() + clientState, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, connection.GetClientID()) + return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) } return clientState.VerifyClientConsensusState( @@ -37,7 +38,7 @@ func (k Keeper) VerifyConnectionState( height uint64, proof commitment.ProofI, connectionID string, - connectionEnd exported.ConnectionI, // oposite connection + connectionEnd exported.ConnectionI, // opposite connection ) error { clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { @@ -46,7 +47,7 @@ func (k Keeper) VerifyConnectionState( // TODO: move to specific clients; blocked by #5502 consensusState, found := k.clientKeeper.GetClientConsensusState( - ctx, connectionEnd.GetClientID(), height, + ctx, connection.GetClientID(), height, ) if !found { return sdkerrors.Wrapf( diff --git a/x/ibc/03-connection/keeper/verify_test.go b/x/ibc/03-connection/keeper/verify_test.go index 536f3f6ea050..2e5f4f77b6db 100644 --- a/x/ibc/03-connection/keeper/verify_test.go +++ b/x/ibc/03-connection/keeper/verify_test.go @@ -20,12 +20,12 @@ const ( func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { counterparty := types.NewCounterparty( - testClientID2, testConnectionID2, - suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + testClientIDA, testConnectionIDA, + suite.chainA.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), ) connection1 := types.NewConnectionEnd( - exported.UNINITIALIZED, testClientID1, counterparty, + exported.UNINITIALIZED, testClientIDB, counterparty, types.GetCompatibleVersions(), ) @@ -37,29 +37,30 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { expPass bool }{ {"verification success", connection1, ibctypes.ValidProof{}, func() { - suite.createClient(testClientID1) + suite.chainA.CreateClient(suite.chainB) }, true}, {"client state not found", connection1, ibctypes.ValidProof{}, func() {}, false}, {"verification failed", connection1, ibctypes.InvalidProof{}, func() { - suite.createClient(testClientID2) + suite.chainA.CreateClient(suite.chainA) }, false}, } + // Create Client of chain B on Chain App + // Check that we can verify B's consensus state on chain A for i, tc := range cases { tc := tc suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset tc.malleate() - - proofHeight := suite.ctx.BlockHeight() + proofHeight := uint64(suite.chainB.Header.Height) // TODO: remove mocked types and uncomment - // consensusKey := ibctypes.KeyConsensusState(testClientID1, uint64(suite.app.LastBlockHeight())) + // consensusKey := ibctypes.KeyConsensusState(testClientIDA, uint64(suite.app.LastBlockHeight())) // proof, proofHeight := suite.queryProof(consensusKey) - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyClientConsensusState( - suite.ctx, tc.connection, uint64(proofHeight), tc.proof, suite.consensusState, + err := suite.chainA.App.IBCKeeper.ConnectionKeeper.VerifyClientConsensusState( + suite.chainA.GetContext(), tc.connection, proofHeight, tc.proof, suite.chainB.Header.ConsensusState(), ) if tc.expPass { @@ -72,7 +73,7 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { } func (suite *KeeperTestSuite) TestVerifyConnectionState() { - // connectionKey := ibctypes.KeyConnection(testConnectionID1) + // connectionKey := ibctypes.KeyConnection(testConnectionIDA) cases := []struct { msg string proof commitment.ProofI @@ -80,32 +81,43 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { expPass bool }{ {"verification success", ibctypes.ValidProof{}, func() { - suite.createClient(testClientID1) - suite.createClient(testClientID2) + suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) }, true}, {"client state not found", ibctypes.ValidProof{}, func() {}, false}, {"verification failed", ibctypes.InvalidProof{}, func() { - suite.createClient(testClientID1) - suite.createClient(testClientID2) + suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) }, false}, } + // Chains A and B create clients for each other + // A creates connectionEnd for chain B and stores it in state + // Check that B can verify connection is stored after some updates for i, tc := range cases { tc := tc suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset tc.malleate() - connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) - suite.updateClient(testClientID1) - counterparty := types.NewCounterparty(testClientID1, testConnectionID1, commitment.NewPrefix([]byte("ibc"))) - expectedConnection := types.NewConnectionEnd(exported.INIT, testClientID2, counterparty, []string{"1.0.0"}) - suite.updateClient(testClientID1) - proofHeight := uint64(3) + + // create and store connection on chain A + expectedConnection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.OPEN) + + // // create expected connection + // expectedConnection := types.NewConnectionEnd(exported.INIT, testClientIDB, counterparty, []string{"1.0.0"}) + + // perform a couple updates of chain A on chain B + suite.chainB.updateClient(suite.chainA) + suite.chainB.updateClient(suite.chainA) + proofHeight := uint64(suite.chainA.Header.Height) // proof, proofHeight := suite.queryProof(connectionKey) - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyConnectionState( - suite.ctx, connection, proofHeight, tc.proof, testConnectionID1, expectedConnection, + counterparty := types.NewCounterparty(testClientIDB, testConnectionIDA, commitment.NewPrefix([]byte("ibc"))) + connection := types.NewConnectionEnd(exported.UNINITIALIZED, testClientIDA, counterparty, []string{"1.0.0"}) + // Ensure chain B can verify connection exists in chain A + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyConnectionState( + suite.chainB.GetContext(), connection, proofHeight, tc.proof, testConnectionIDA, expectedConnection, ) if tc.expPass { @@ -127,33 +139,39 @@ func (suite *KeeperTestSuite) TestVerifyChannelState() { expPass bool }{ {"verification success", ibctypes.ValidProof{}, 2, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, true}, {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, {"consensus state not found", ibctypes.ValidProof{}, 100, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, false}, {"verification failed", ibctypes.InvalidProof{}, 2, func() { - suite.createClient(testClientID2) + suite.chainB.CreateClient(suite.chainB) }, false}, } + // Chain A creates channel for chain B and stores in its state + // Check that chainB can verify channel is stored in chain A for i, tc := range cases { tc := tc suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset tc.malleate() - connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) - channel := suite.createChannel( + // Create and store channel on chain A + connection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.OPEN) + channel := suite.chainA.createChannel( testPort1, testChannel1, testPort2, testChannel2, - channelexported.OPEN, channelexported.ORDERED, testConnectionID1, + channelexported.OPEN, channelexported.ORDERED, testConnectionIDA, ) - suite.updateClient(testClientID1) + // Update chainA client on chainB + suite.chainB.updateClient(suite.chainA) + + // Check that Chain B can verify channel is stored on chainA // proof, proofHeight := suite.queryProof(channelKey) - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyChannelState( - suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyChannelState( + suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, testChannel1, channel, ) @@ -178,30 +196,37 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { expPass bool }{ {"verification success", ibctypes.ValidProof{}, 2, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, true}, {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, {"consensus state not found", ibctypes.ValidProof{}, 100, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, false}, {"verification failed", ibctypes.InvalidProof{}, 2, func() { - suite.createClient(testClientID2) + suite.chainB.CreateClient(suite.chainA) }, false}, } + // ChainA sets packet commitment on channel with chainB in its state + // Check that ChainB can verify the PacketCommitment for i, tc := range cases { tc := tc suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset tc.malleate() - connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, commitmentBz) - suite.updateClient(testClientID1) + // Set PacketCommitment on chainA + connection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.OPEN) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), testPort1, testChannel1, 1, commitmentBz) + + // Update ChainA client on chainB + suite.chainB.updateClient(suite.chainA) + + // Check that ChainB can verify PacketCommitment stored in chainA // proof, proofHeight := suite.queryProof(commitmentKey) - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketCommitment( - suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyPacketCommitment( + suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, testChannel1, 1, commitmentBz, ) @@ -226,14 +251,14 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { expPass bool }{ {"verification success", ibctypes.ValidProof{}, 2, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, true}, {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, {"consensus state not found", ibctypes.ValidProof{}, 100, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, false}, {"verification failed", ibctypes.InvalidProof{}, 2, func() { - suite.createClient(testClientID2) + suite.chainB.CreateClient(suite.chainB) }, false}, } @@ -243,13 +268,13 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { suite.SetupTest() // reset tc.malleate() - connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) - suite.app.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, 1, ack) - suite.updateClient(testClientID1) + connection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.OPEN) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), testPort1, testChannel1, 1, ack) + suite.chainB.updateClient(suite.chainA) // proof, proofHeight := suite.queryProof(packetAckKey) - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgement( - suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgement( + suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, testChannel1, 1, ack, ) @@ -273,14 +298,14 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { expPass bool }{ {"verification success", ibctypes.ValidProof{}, 2, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, true}, {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, {"consensus state not found", ibctypes.ValidProof{}, 100, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, false}, {"verification failed", ibctypes.InvalidProof{}, 2, func() { - suite.createClient(testClientID2) + suite.chainB.CreateClient(suite.chainB) }, false}, } @@ -290,13 +315,13 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { suite.SetupTest() // reset tc.malleate() - connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) - suite.updateClient(testClientID1) + connection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.OPEN) + suite.chainB.updateClient(suite.chainA) // proof, proofHeight := suite.queryProof(packetAckKey) - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgementAbsence( - suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgementAbsence( + suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, testChannel1, 1, ) @@ -320,14 +345,14 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { expPass bool }{ {"verification success", ibctypes.ValidProof{}, 2, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, true}, {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, {"consensus state not found", ibctypes.ValidProof{}, 100, func() { - suite.createClient(testClientID1) + suite.chainB.CreateClient(suite.chainA) }, false}, {"verification failed", ibctypes.InvalidProof{}, 2, func() { - suite.createClient(testClientID2) + suite.chainB.CreateClient(suite.chainB) }, false}, } @@ -337,13 +362,13 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { suite.SetupTest() // reset tc.malleate() - connection := suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, exported.OPEN) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, 1) - suite.updateClient(testClientID1) + connection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.OPEN) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainA.GetContext(), testPort1, testChannel1, 1) + suite.chainB.updateClient(suite.chainA) // proof, proofHeight := suite.queryProof(nextSeqRcvKey) - err := suite.app.IBCKeeper.ConnectionKeeper.VerifyNextSequenceRecv( - suite.ctx, connection, tc.proofHeight, tc.proof, testPort1, + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyNextSequenceRecv( + suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, testChannel1, 1, ) diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 59c42ca40d9f..2b5257b8e61b 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -13,21 +13,21 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { testCases := []testCase{ {"success", func() { - suite.createConnection( - testConnectionID1, testConnectionID2, testClientID1, testClientID2, + suite.chainA.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, connectionexported.INIT, ) }, true}, {"channel already exists", func() { - suite.createChannel( + suite.chainA.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.INIT, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, false}, {"connection doesn't exist", func() {}, false}, {"connection is UNINITIALIZED", func() { - suite.createConnection( - testConnectionID1, testConnectionID2, testClientID1, testClientID2, + suite.chainA.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, connectionexported.UNINITIALIZED, ) }, false}, @@ -38,8 +38,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { suite.SetupTest() // reset tc.malleate() - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit( - suite.ctx, exported.ORDERED, []string{testConnectionID1}, + err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenInit( + suite.chainA.GetContext(), exported.ORDERED, []string{testConnectionIDA}, testPort1, testChannel1, counterparty, testChannelVersion, ) @@ -57,35 +57,35 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { testCases := []testCase{ {"success", func() { - suite.createClient(testClientID2) - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + suite.chainA.CreateClient(suite.chainB) + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN, ) }, true}, {"previous channel with invalid state", func() { - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.UNINITIALIZED, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, {"connection doesn't exist", func() {}, false}, {"connection is not OPEN", func() { - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.INIT, ) }, false}, {"consensus state not found", func() { - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN, ) }, false}, {"channel verification failed", func() { - suite.createClient(testClientID2) - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + suite.chainA.CreateClient(suite.chainB) + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN, ) }, false}, @@ -97,18 +97,20 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { tc.malleate() + proofHeight := suite.chainB.Header.Height + if tc.expPass { - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry( - suite.ctx, exported.ORDERED, []string{testConnectionID2}, + err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenTry( + suite.chainA.GetContext(), exported.ORDERED, []string{testConnectionIDB}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, - validProof{}, uint64(testHeight), + validProof{}, uint64(proofHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry( - suite.ctx, exported.ORDERED, []string{testConnectionID2}, + err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenTry( + suite.chainA.GetContext(), exported.ORDERED, []string{testConnectionIDB}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, - invalidProof{}, uint64(testHeight), + invalidProof{}, uint64(proofHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -119,58 +121,58 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { func (suite *KeeperTestSuite) TestChanOpenAck() { testCases := []testCase{ {"success", func() { - suite.createClient(testClientID1) - _ = suite.createConnection( - testConnectionID1, testConnectionID2, testClientID1, testClientID2, + suite.chainB.CreateClient(suite.chainA) + _ = suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, true}, {"channel doesn't exist", func() {}, false}, {"channel state is not INIT or TRYOPEN", func() { - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.UNINITIALIZED, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, false}, {"connection not found", func() { - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, false}, {"connection is not OPEN", func() { - _ = suite.createConnection( - testConnectionID1, testConnectionID2, testClientID1, testClientID2, + _ = suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.TRYOPEN, ) - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, false}, {"consensus state not found", func() { - _ = suite.createConnection( - testConnectionID1, testConnectionID2, testClientID1, testClientID2, + _ = suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, false}, {"channel verification failed", func() { - suite.createClient(testClientID1) - _ = suite.createConnection( - testConnectionID1, testConnectionID2, testClientID1, testClientID2, + suite.chainB.CreateClient(suite.chainA) + _ = suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, false}, } @@ -181,16 +183,17 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { tc.malleate() + proofHeight := suite.chainA.Header.Height if tc.expPass { - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck( - suite.ctx, testPort1, testChannel1, testChannelVersion, - validProof{}, uint64(testHeight), + err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenAck( + suite.chainB.GetContext(), testPort1, testChannel1, testChannelVersion, + validProof{}, uint64(proofHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck( - suite.ctx, testPort1, testChannel1, testChannelVersion, - invalidProof{}, uint64(testHeight), + err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenAck( + suite.chainB.GetContext(), testPort1, testChannel1, testChannelVersion, + invalidProof{}, uint64(proofHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -201,58 +204,58 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { func (suite *KeeperTestSuite) TestChanOpenConfirm() { testCases := []testCase{ {"success", func() { - suite.createClient(testClientID2) - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + suite.chainA.CreateClient(suite.chainB) + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, true}, {"channel doesn't exist", func() {}, false}, {"channel state is not TRYOPEN", func() { - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.UNINITIALIZED, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, {"connection not found", func() { - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, {"connection is not OPEN", func() { - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.TRYOPEN, ) - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, {"consensus state not found", func() { - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, {"channel verification failed", func() { - suite.createClient(testClientID2) - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + suite.chainA.CreateClient(suite.chainB) + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, } @@ -263,16 +266,17 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { tc.malleate() + proofHeight := suite.chainB.Header.Height if tc.expPass { - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm( - suite.ctx, testPort2, testChannel2, - validProof{}, uint64(testHeight), + err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenConfirm( + suite.chainA.GetContext(), testPort2, testChannel2, + validProof{}, uint64(proofHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm( - suite.ctx, testPort2, testChannel2, - invalidProof{}, uint64(testHeight), + err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenConfirm( + suite.chainA.GetContext(), testPort2, testChannel2, + invalidProof{}, uint64(proofHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -283,37 +287,37 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { func (suite *KeeperTestSuite) TestChanCloseInit() { testCases := []testCase{ {"success", func() { - suite.createClient(testClientID1) - _ = suite.createConnection( - testConnectionID1, testConnectionID2, testClientID1, testClientID2, + suite.chainB.CreateClient(suite.chainA) + _ = suite.chainA.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, true}, {"channel doesn't exist", func() {}, false}, {"channel state is CLOSED", func() { - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, {"connection not found", func() { - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, false}, {"connection is not OPEN", func() { - _ = suite.createConnection( - testConnectionID1, testConnectionID2, testClientID1, testClientID2, + _ = suite.chainA.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.TRYOPEN, ) - _ = suite.createChannel( + _ = suite.chainA.createChannel( testPort1, testChannel1, testPort2, testChannel2, exported.UNINITIALIZED, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, false}, } @@ -323,8 +327,8 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { suite.SetupTest() // reset tc.malleate() - err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit( - suite.ctx, testPort1, testChannel1, + err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanCloseInit( + suite.chainA.GetContext(), testPort1, testChannel1, ) if tc.expPass { @@ -339,58 +343,58 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { func (suite *KeeperTestSuite) TestChanCloseConfirm() { testCases := []testCase{ {"success", func() { - suite.createClient(testClientID2) - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + suite.chainB.CreateClient(suite.chainA) + _ = suite.chainB.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, true}, {"channel doesn't exist", func() {}, false}, {"channel state is CLOSED", func() { - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.CLOSED, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, {"connection not found", func() { - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, - exported.ORDERED, testConnectionID1, + exported.ORDERED, testConnectionIDA, ) }, false}, {"connection is not OPEN", func() { - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + _ = suite.chainB.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, connectionexported.TRYOPEN, ) - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, {"consensus state not found", func() { - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + _ = suite.chainB.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, {"channel verification failed", func() { - suite.createClient(testClientID2) - _ = suite.createConnection( - testConnectionID2, testConnectionID1, testClientID2, testClientID1, + suite.chainB.CreateClient(suite.chainA) + _ = suite.chainB.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, connectionexported.OPEN, ) - _ = suite.createChannel( + _ = suite.chainB.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, - exported.ORDERED, testConnectionID2, + exported.ORDERED, testConnectionIDB, ) }, false}, } @@ -401,16 +405,17 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { tc.malleate() + proofHeight := suite.chainA.Header.Height if tc.expPass { - err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm( - suite.ctx, testPort2, testChannel2, - validProof{}, uint64(testHeight), + err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanCloseConfirm( + suite.chainB.GetContext(), testPort2, testChannel2, + validProof{}, uint64(proofHeight), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm( - suite.ctx, testPort2, testChannel2, - invalidProof{}, uint64(testHeight), + err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanCloseConfirm( + suite.chainB.GetContext(), testPort2, testChannel2, + invalidProof{}, uint64(proofHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index 688893e1b5da..e3c42527f015 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -19,6 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" + "github.com/cosmos/cosmos-sdk/x/staking" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -28,11 +29,11 @@ import ( const ( testClientType = clientexported.Tendermint - testClientID1 = "testclientidone" - testConnectionID1 = "connectionidone" + testClientIDA = "testclientida" + testConnectionIDA = "connectionidatob" - testClientID2 = "testclientidtwo" - testConnectionID2 = "connectionidtwo" + testClientIDB = "testclientidb" + testConnectionIDB = "connectionidbtoa" testPort1 = "firstport" testPort2 = "secondport" @@ -54,28 +55,22 @@ const ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp - valSet *tmtypes.ValidatorSet + cdc *codec.Codec + + chainA *TestChain + chainB *TestChain } func (suite *KeeperTestSuite) SetupTest() { - isCheckTx := false - app := simapp.Setup(isCheckTx) - - suite.cdc = app.Codec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) - suite.app = app - - privVal := tmtypes.NewMockPV() + suite.chainA = NewTestChain(testClientIDA) + suite.chainB = NewTestChain(testClientIDB) - validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) - suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + suite.cdc = suite.chainA.App.Codec() } func (suite *KeeperTestSuite) TestSetChannel() { - _, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + ctx := suite.chainB.GetContext() + _, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetChannel(ctx, testPort1, testChannel1) suite.False(found) channel := types.Channel{ @@ -85,12 +80,12 @@ func (suite *KeeperTestSuite) TestSetChannel() { PortID: testPort2, ChannelID: testChannel2, }, - ConnectionHops: []string{testConnectionID1}, + ConnectionHops: []string{testConnectionIDA}, Version: testChannelVersion, } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort1, testChannel1, channel) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort1, testChannel1, channel) - storedChannel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1) + storedChannel, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetChannel(ctx, testPort1, testChannel1) suite.True(found) suite.Equal(channel, storedChannel) } @@ -105,7 +100,7 @@ func (suite KeeperTestSuite) TestGetAllChannels() { State: exported.INIT, Ordering: testChannelOrder, Counterparty: counterparty3, - ConnectionHops: []string{testConnectionID1}, + ConnectionHops: []string{testConnectionIDA}, Version: testChannelVersion, } @@ -113,7 +108,7 @@ func (suite KeeperTestSuite) TestGetAllChannels() { State: exported.INIT, Ordering: testChannelOrder, Counterparty: counterparty1, - ConnectionHops: []string{testConnectionID1}, + ConnectionHops: []string{testConnectionIDA}, Version: testChannelVersion, } @@ -121,76 +116,81 @@ func (suite KeeperTestSuite) TestGetAllChannels() { State: exported.CLOSED, Ordering: testChannelOrder, Counterparty: counterparty2, - ConnectionHops: []string{testConnectionID1}, + ConnectionHops: []string{testConnectionIDA}, Version: testChannelVersion, } expChannels := []types.Channel{channel1, channel2, channel3} - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort1, testChannel1, expChannels[0]) - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort2, testChannel2, expChannels[1]) - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, testPort3, testChannel3, expChannels[2]) + ctx := suite.chainB.GetContext() + suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort1, testChannel1, expChannels[0]) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort2, testChannel2, expChannels[1]) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort3, testChannel3, expChannels[2]) - channels := suite.app.IBCKeeper.ChannelKeeper.GetAllChannels(suite.ctx) + channels := suite.chainB.App.IBCKeeper.ChannelKeeper.GetAllChannels(ctx) suite.Require().Len(channels, len(expChannels)) suite.Require().Equal(expChannels, channels) } func (suite *KeeperTestSuite) TestSetChannelCapability() { - _, found := suite.app.IBCKeeper.ChannelKeeper.GetChannelCapability(suite.ctx, testPort1, testChannel1) + ctx := suite.chainB.GetContext() + _, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetChannelCapability(ctx, testPort1, testChannel1) suite.False(found) channelCap := "test-channel-capability" - suite.app.IBCKeeper.ChannelKeeper.SetChannelCapability(suite.ctx, testPort1, testChannel1, channelCap) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannelCapability(ctx, testPort1, testChannel1, channelCap) - storedChannelCap, found := suite.app.IBCKeeper.ChannelKeeper.GetChannelCapability(suite.ctx, testPort1, testChannel1) + storedChannelCap, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetChannelCapability(ctx, testPort1, testChannel1) suite.True(found) suite.Equal(channelCap, storedChannelCap) } func (suite *KeeperTestSuite) TestSetSequence() { - _, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + ctx := suite.chainB.GetContext() + _, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetNextSequenceSend(ctx, testPort1, testChannel1) suite.False(found) - _, found = suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceRecv(suite.ctx, testPort1, testChannel1) + _, found = suite.chainB.App.IBCKeeper.ChannelKeeper.GetNextSequenceRecv(ctx, testPort1, testChannel1) suite.False(found) nextSeqSend, nextSeqRecv := uint64(10), uint64(10) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(ctx, testPort1, testChannel1, nextSeqSend) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(ctx, testPort1, testChannel1, nextSeqRecv) - storedNextSeqSend, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + storedNextSeqSend, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetNextSequenceSend(ctx, testPort1, testChannel1) suite.True(found) suite.Equal(nextSeqSend, storedNextSeqSend) - storedNextSeqRecv, found := suite.app.IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.ctx, testPort1, testChannel1) + storedNextSeqRecv, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetNextSequenceSend(ctx, testPort1, testChannel1) suite.True(found) suite.Equal(nextSeqRecv, storedNextSeqRecv) } func (suite *KeeperTestSuite) TestPackageCommitment() { + ctx := suite.chainB.GetContext() seq := uint64(10) - storedCommitment := suite.app.IBCKeeper.ChannelKeeper.GetPacketCommitment(suite.ctx, testPort1, testChannel1, seq) + storedCommitment := suite.chainB.App.IBCKeeper.ChannelKeeper.GetPacketCommitment(ctx, testPort1, testChannel1, seq) suite.Equal([]byte(nil), storedCommitment) commitment := []byte("commitment") - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, seq, commitment) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(ctx, testPort1, testChannel1, seq, commitment) - storedCommitment = suite.app.IBCKeeper.ChannelKeeper.GetPacketCommitment(suite.ctx, testPort1, testChannel1, seq) + storedCommitment = suite.chainB.App.IBCKeeper.ChannelKeeper.GetPacketCommitment(ctx, testPort1, testChannel1, seq) suite.Equal(commitment, storedCommitment) } func (suite *KeeperTestSuite) TestSetPacketAcknowledgement() { + ctx := suite.chainB.GetContext() seq := uint64(10) - storedAckHash, found := suite.app.IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, seq) + storedAckHash, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(ctx, testPort1, testChannel1, seq) suite.False(found) suite.Nil(storedAckHash) ackHash := []byte("ackhash") - suite.app.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, seq, ackHash) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(ctx, testPort1, testChannel1, seq, ackHash) - storedAckHash, found = suite.app.IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(suite.ctx, testPort1, testChannel1, seq) + storedAckHash, found = suite.chainB.App.IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(ctx, testPort1, testChannel1, seq) suite.True(found) suite.Equal(ackHash, storedAckHash) } @@ -199,67 +199,189 @@ func TestKeeperTestSuite(t *testing.T) { suite.Run(t, new(KeeperTestSuite)) } -func (suite *KeeperTestSuite) commitNBlocks(n int) { +func commitNBlocks(chain *TestChain, n int) { for i := 0; i < n; i++ { - suite.app.Commit() - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{Height: suite.app.LastBlockHeight()}) + chain.App.Commit() + chain.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: chain.App.LastBlockHeight() + 1}}) } } -func (suite *KeeperTestSuite) createClient(clientID string) { - suite.commitNBlocks(1) +// nolint: unused +func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { + res := suite.chainB.App.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Height: suite.chainB.App.LastBlockHeight(), + Data: key, + Prove: true, + }) - commitID := suite.app.LastCommitID() - consensusState := ibctmtypes.ConsensusState{ - Height: testHeight, - Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, + proof := commitment.Proof{ + Proof: res.Proof, } - clientState, err := ibctmtypes.Initialize(clientID, clientID, consensusState, trustingPeriod, ubdPeriod) - suite.Require().NoError(err) - _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) - suite.Require().NoError(err) + return proof, res.Height } -// nolint: unused -func (suite *KeeperTestSuite) updateClient() { - // always commit and begin a new block on updateClient - suite.app.Commit() - commitID := suite.app.LastCommitID() +type TestChain struct { + ClientID string + App *simapp.SimApp + Header ibctmtypes.Header + Vals *tmtypes.ValidatorSet + Signers []tmtypes.PrivValidator +} + +func NewTestChain(clientID string) *TestChain { + privVal := tmtypes.NewMockPV() + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + signers := []tmtypes.PrivValidator{privVal} + now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + + return &TestChain{ + ClientID: clientID, + App: simapp.Setup(false), + Header: header, + Vals: valSet, + Signers: signers, + } +} + +// Creates simple context for testing purposes +func (chain *TestChain) GetContext() sdk.Context { + return chain.App.BaseApp.NewContext(false, abci.Header{ChainID: chain.Header.ChainID, Height: chain.Header.Height}) +} + +// createClient will create a client for clientChain on targetChain +func (chain *TestChain) CreateClient(client *TestChain) error { + client.Header = nextHeader(client) + // Commit and create a new block on appTarget to get a fresh CommitID + client.App.Commit() + commitID := client.App.LastCommitID() + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) + + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) // get one voting power + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, + }, + Valset: validators, + } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) + + // Create target ctx + ctxTarget := chain.GetContext() + + // create client + clientState, err := ibctmtypes.Initialize(client.ClientID, trustingPeriod, ubdPeriod, client.Header) + if err != nil { + return err + } + _, err = chain.App.IBCKeeper.ClientKeeper.CreateClient(ctxTarget, clientState, client.Header.ConsensusState()) + if err != nil { + return err + } + return nil + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.app.BaseApp, + // ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgCreateClient(clientID, clientexported.ClientTypeTendermint, consState, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) +} + +func (chain *TestChain) updateClient(client *TestChain) { + // Create target ctx + ctxTarget := chain.GetContext() + + // if clientState does not already exist, return without updating + _, found := chain.App.IBCKeeper.ClientKeeper.GetClientState( + ctxTarget, client.ClientID, + ) + if !found { + return + } + + // always commit when updateClient and begin a new block + client.App.Commit() + commitID := client.App.LastCommitID() - height := suite.app.LastBlockHeight() + 1 - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: height}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{Height: suite.app.LastBlockHeight()}) + client.Header = nextHeader(client) + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) + + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, + }, + Valset: validators, + } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) - state := ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), + consensusState := ibctmtypes.ConsensusState{ + Height: uint64(client.Header.Height), + Timestamp: client.Header.Time, + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: client.Vals, } - suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClientID1, uint64(height-1), state) - csi, _ := suite.app.IBCKeeper.ClientKeeper.GetClientState(suite.ctx, testClientID1) - cs, _ := csi.(ibctmtypes.ClientState) - cs.LatestHeight = uint64(height - 1) - suite.app.IBCKeeper.ClientKeeper.SetClientState(suite.ctx, cs) + chain.App.IBCKeeper.ClientKeeper.SetClientConsensusState( + ctxTarget, client.ClientID, uint64(client.Header.Height), consensusState, + ) + chain.App.IBCKeeper.ClientKeeper.SetClientState( + ctxTarget, ibctmtypes.NewClientState(client.ClientID, trustingPeriod, ubdPeriod, client.Header), + ) + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.app.BaseApp, + // ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgUpdateClient(clientID, suite.header, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) + // suite.Require().NoError(err) } -func (suite *KeeperTestSuite) createConnection( +func (chain *TestChain) createConnection( connID, counterpartyConnID, clientID, counterpartyClientID string, state connectionexported.State, ) connectiontypes.ConnectionEnd { - counterparty := connectiontypes.NewCounterparty(counterpartyClientID, counterpartyConnID, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + counterparty := connectiontypes.NewCounterparty(counterpartyClientID, counterpartyConnID, chain.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) connection := connectiontypes.ConnectionEnd{ State: state, ClientID: clientID, Counterparty: counterparty, Versions: connectiontypes.GetCompatibleVersions(), } - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, connID, connection) + ctx := chain.GetContext() + chain.App.IBCKeeper.ConnectionKeeper.SetConnection(ctx, connID, connection) return connection } -func (suite *KeeperTestSuite) createChannel( +func (chain *TestChain) createChannel( portID, channelID, counterpartyPortID, counterpartyChannelID string, state exported.State, order exported.Order, connectionID string, ) types.Channel { @@ -267,24 +389,14 @@ func (suite *KeeperTestSuite) createChannel( channel := types.NewChannel(state, order, counterparty, []string{connectionID}, "1.0", ) - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, channelID, channel) + ctx := chain.GetContext() + chain.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, portID, channelID, channel) return channel } -// nolint: unused -func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { - res := suite.app.Query(abci.RequestQuery{ - Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Height: suite.app.LastBlockHeight(), - Data: key, - Prove: true, - }) - - proof := commitment.Proof{ - Proof: res.Proof, - } - - return proof, res.Height +func nextHeader(chain *TestChain) ibctmtypes.Header { + return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, + chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) } // Mocked types diff --git a/x/ibc/04-channel/keeper/packet_test.go b/x/ibc/04-channel/keeper/packet_test.go index 950bf320776b..e65932a09a82 100644 --- a/x/ibc/04-channel/keeper/packet_test.go +++ b/x/ibc/04-channel/keeper/packet_test.go @@ -6,6 +6,7 @@ import ( connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + transfertypes "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -17,10 +18,10 @@ func (suite *KeeperTestSuite) TestSendPacket() { testCases := []testCase{ {"success", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + suite.chainB.CreateClient(suite.chainA) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainB.GetContext(), testPort1, testChannel1, 1) }, true}, {"packet basic validation failed", func() { packet = types.NewPacket(mockFailPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) @@ -30,49 +31,49 @@ func (suite *KeeperTestSuite) TestSendPacket() { }, false}, {"channel closed", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"packet dest port ≠ channel counterparty port", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, testPort3, counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet dest channel ID ≠ channel counterparty channel ID", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), testChannel3) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection is UNINITIALIZED", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.UNINITIALIZED) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.UNINITIALIZED) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"client state not found", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"timeout height passed", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.commitNBlocks(10) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + commitNBlocks(suite.chainB, 10) + suite.chainB.CreateClient(suite.chainA) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"next sequence send not found", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.CreateClient(suite.chainA) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"next sequence wrong", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 5) + suite.chainB.CreateClient(suite.chainA) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainB.GetContext(), testPort1, testChannel1, 5) }, false}, } @@ -82,7 +83,7 @@ func (suite *KeeperTestSuite) TestSendPacket() { suite.SetupTest() // reset tc.malleate() - err := suite.app.IBCKeeper.ChannelKeeper.SendPacket(suite.ctx, packet) + err := suite.chainB.App.IBCKeeper.ChannelKeeper.SendPacket(suite.chainB.GetContext(), packet) if tc.expPass { suite.Require().NoError(err) @@ -100,46 +101,46 @@ func (suite *KeeperTestSuite) TestRecvPacket() { testCases := []testCase{ {"success", func() { - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + suite.chainB.CreateClient(suite.chainA) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainB.GetContext(), testPort1, testChannel1, 1) packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.updateClient() + suite.chainB.updateClient(suite.chainA) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.INIT, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.INIT, exported.ORDERED, testConnectionIDA) }, false}, {"packet source port ≠ channel counterparty port", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort2, testChannel2, testPort3, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort2, testChannel2, testPort3, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet source channel ID ≠ channel counterparty channel ID", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not OPEN", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.INIT) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.INIT) + suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"timeout passed", func() { - suite.commitNBlocks(10) + commitNBlocks(suite.chainB, 10) packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"validation failed", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, } @@ -148,12 +149,14 @@ func (suite *KeeperTestSuite) TestRecvPacket() { suite.SetupTest() // reset tc.malleate() + proofHeight := uint64(suite.chainA.Header.Height) + ctx := suite.chainB.GetContext() var err error if tc.expPass { - packet, err = suite.app.IBCKeeper.ChannelKeeper.RecvPacket(suite.ctx, packet, ibctypes.ValidProof{}, uint64(suite.ctx.BlockHeader().Height)) + packet, err = suite.chainB.App.IBCKeeper.ChannelKeeper.RecvPacket(ctx, packet, ibctypes.ValidProof{}, proofHeight) suite.Require().NoError(err) } else { - packet, err = suite.app.IBCKeeper.ChannelKeeper.RecvPacket(suite.ctx, packet, ibctypes.InvalidProof{}, uint64(suite.ctx.BlockHeader().Height)) + packet, err = suite.chainB.App.IBCKeeper.ChannelKeeper.RecvPacket(ctx, packet, ibctypes.InvalidProof{}, proofHeight) suite.Require().Error(err) } }) @@ -168,27 +171,27 @@ func (suite *KeeperTestSuite) TestPacketExecuted() { testCases := []testCase{ {"success: UNORDERED", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.UNORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort2, testChannel2, 1) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainA.GetContext(), testPort2, testChannel2, 1) }, true}, {"success: ORDERED", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort2, testChannel2, 1) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainA.GetContext(), testPort2, testChannel2, 1) }, true}, {"channel not found", func() {}, false}, {"channel not OPEN", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.CLOSED, exported.ORDERED, testConnectionID1) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"next sequence receive not found", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet sequence ≠ next sequence receive", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort2, testChannel2, 5) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainA.GetContext(), testPort2, testChannel2, 5) }, false}, } @@ -198,7 +201,7 @@ func (suite *KeeperTestSuite) TestPacketExecuted() { suite.SetupTest() // reset tc.malleate() - err := suite.app.IBCKeeper.ChannelKeeper.PacketExecuted(suite.ctx, packet, mockSuccessPacket{}) + err := suite.chainA.App.IBCKeeper.ChannelKeeper.PacketExecuted(suite.chainA.GetContext(), packet, mockSuccessPacket{}) if tc.expPass { suite.Require().NoError(err) @@ -218,43 +221,43 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { testCases := []testCase{ {"success", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainB.CreateClient(suite.chainA) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"packet source port ≠ channel counterparty port", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet source channel ID ≠ channel counterparty channel ID", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not OPEN", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.INIT) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.INIT) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet hasn't been sent", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet ack verification failed", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) }, false}, } @@ -264,12 +267,14 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { suite.SetupTest() // reset tc.malleate() + ctx := suite.chainB.GetContext() + proofHeight := uint64(suite.chainA.Header.Height) if tc.expPass { - packetOut, err := suite.app.IBCKeeper.ChannelKeeper.AcknowledgePacket(suite.ctx, packet, ack, ibctypes.ValidProof{}, uint64(suite.ctx.BlockHeader().Height)) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.AcknowledgePacket(ctx, packet, ack, ibctypes.ValidProof{}, proofHeight) suite.Require().NoError(err) suite.Require().NotNil(packetOut) } else { - packetOut, err := suite.app.IBCKeeper.ChannelKeeper.AcknowledgePacket(suite.ctx, packet, ack, ibctypes.InvalidProof{}, uint64(suite.ctx.BlockHeader().Height)) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.AcknowledgePacket(ctx, packet, ack, ibctypes.InvalidProof{}, proofHeight) suite.Require().Error(err) suite.Require().Nil(packetOut) } @@ -290,57 +295,57 @@ func (suite *KeeperTestSuite) TestCleanupPacket() { {"success", func() { nextSeqRecv = 10 packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainB.CreateClient(suite.chainA) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"packet source port ≠ channel counterparty port", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet source channel ID ≠ channel counterparty channel ID", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not OPEN", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.INIT) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.INIT) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet already received ", func() { packet = types.NewPacket(mockSuccessPacket{}, 10, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet hasn't been sent", func() { nextSeqRecv = 10 packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"next seq receive verification failed", func() { nextSeqRecv = 10 packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) }, false}, {"packet ack verification failed", func() { nextSeqRecv = 10 packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) }, false}, } @@ -350,12 +355,14 @@ func (suite *KeeperTestSuite) TestCleanupPacket() { suite.SetupTest() // reset tc.malleate() + ctx := suite.chainB.GetContext() + proofHeight := uint64(suite.chainA.Header.Height) if tc.expPass { - packetOut, err := suite.app.IBCKeeper.ChannelKeeper.CleanupPacket(suite.ctx, packet, ibctypes.ValidProof{}, uint64(suite.ctx.BlockHeader().Height), nextSeqRecv, ack) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.CleanupPacket(ctx, packet, ibctypes.ValidProof{}, proofHeight, nextSeqRecv, ack) suite.Require().NoError(err) suite.Require().NotNil(packetOut) } else { - packetOut, err := suite.app.IBCKeeper.ChannelKeeper.CleanupPacket(suite.ctx, packet, ibctypes.InvalidProof{}, uint64(suite.ctx.BlockHeader().Height), nextSeqRecv, ack) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.CleanupPacket(ctx, packet, ibctypes.InvalidProof{}, proofHeight, nextSeqRecv, ack) suite.Require().Error(err) suite.Require().Nil(packetOut) } diff --git a/x/ibc/04-channel/keeper/timeout_test.go b/x/ibc/04-channel/keeper/timeout_test.go index be60e39f1e75..8991b7a5952f 100644 --- a/x/ibc/04-channel/keeper/timeout_test.go +++ b/x/ibc/04-channel/keeper/timeout_test.go @@ -21,65 +21,65 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { testCases := []testCase{ {"success", func() { nextSeqRecv = 1 - proofHeight = 1 packet = types.NewPacket(newMockTimeoutPacket(1), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.CreateClient(suite.chainA) + proofHeight = uint64(suite.chainA.Header.Height) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"packet source port ≠ channel counterparty port", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet source channel ID ≠ channel counterparty channel ID", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"timeout", func() { proofHeight = 1 packet = types.NewPacket(mockSuccessPacket{}, 10, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet already received ", func() { nextSeqRecv = 2 proofHeight = 100 packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet hasn't been sent", func() { nextSeqRecv = 1 proofHeight = 100 packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"next seq receive verification failed", func() { nextSeqRecv = 1 - proofHeight = 100 + proofHeight = uint64(suite.chainA.Header.Height) packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) }, false}, {"packet ack verification failed", func() { nextSeqRecv = 1 proofHeight = 100 packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) }, false}, } @@ -88,12 +88,13 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { suite.SetupTest() // reset tc.malleate() + ctx := suite.chainB.GetContext() if tc.expPass { - packetOut, err := suite.app.IBCKeeper.ChannelKeeper.TimeoutPacket(suite.ctx, packet, ibctypes.ValidProof{}, proofHeight, nextSeqRecv) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutPacket(ctx, packet, ibctypes.ValidProof{}, proofHeight, nextSeqRecv) suite.Require().NoError(err) suite.Require().NotNil(packetOut) } else { - packetOut, err := suite.app.IBCKeeper.ChannelKeeper.TimeoutPacket(suite.ctx, packet, ibctypes.InvalidProof{}, proofHeight, nextSeqRecv) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutPacket(ctx, packet, ibctypes.InvalidProof{}, proofHeight, nextSeqRecv) suite.Require().Error(err) suite.Require().Nil(packetOut) } @@ -107,7 +108,7 @@ func (suite *KeeperTestSuite) TestTimeoutExecuted() { testCases := []testCase{ {"success ORDERED", func() { packet = types.NewPacket(newMockTimeoutPacket(3), 1, testPort1, testChannel1, testPort2, testChannel2) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, true}, {"channel not found", func() {}, false}, } @@ -118,7 +119,7 @@ func (suite *KeeperTestSuite) TestTimeoutExecuted() { suite.SetupTest() // reset tc.malleate() - err := suite.app.IBCKeeper.ChannelKeeper.TimeoutExecuted(suite.ctx, packet) + err := suite.chainA.App.IBCKeeper.ChannelKeeper.TimeoutExecuted(suite.chainA.GetContext(), packet) if tc.expPass { suite.Require().NoError(err) @@ -142,55 +143,59 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { testCases := []testCase{ {"success", func() { packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + suite.chainB.CreateClient(suite.chainA) + proofHeight = uint64(suite.chainA.Header.Height) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, true}, {"channel not found", func() {}, false}, {"packet dest port ≠ channel counterparty port", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet dest channel ID ≠ channel counterparty channel ID", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet hasn't been sent", func() { packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"channel verification failed", func() { packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + suite.chainB.CreateClient(suite.chainA) + proofHeight = uint64(suite.chainA.Header.Height) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, false}, {"next seq receive verification failed", func() { proofClosed = ibctypes.ValidProof{} packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + suite.chainB.CreateClient(suite.chainA) + proofHeight = uint64(suite.chainA.Header.Height) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, false}, {"packet ack verification failed", func() { proofClosed = ibctypes.ValidProof{} packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.createClient(testClientID1) - suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connectionexported.OPEN) - suite.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionID1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, testPort1, testChannel1, nextSeqRecv) + suite.chainB.CreateClient(suite.chainA) + proofHeight = uint64(suite.chainA.Header.Height) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, false}, } @@ -200,12 +205,13 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { suite.SetupTest() // reset tc.malleate() + ctx := suite.chainB.GetContext() if tc.expPass { - packetOut, err := suite.app.IBCKeeper.ChannelKeeper.TimeoutOnClose(suite.ctx, packet, ibctypes.ValidProof{}, ibctypes.ValidProof{}, proofHeight, nextSeqRecv) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutOnClose(ctx, packet, ibctypes.ValidProof{}, ibctypes.ValidProof{}, proofHeight, nextSeqRecv) suite.Require().NoError(err) suite.Require().NotNil(packetOut) } else { - packetOut, err := suite.app.IBCKeeper.ChannelKeeper.TimeoutOnClose(suite.ctx, packet, proof, proofClosed, proofHeight, nextSeqRecv) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutOnClose(ctx, packet, proof, proofClosed, proofHeight, nextSeqRecv) suite.Require().Error(err) suite.Require().Nil(packetOut) } diff --git a/x/ibc/07-tendermint/client/cli/tx.go b/x/ibc/07-tendermint/client/cli/tx.go index 101a266ae125..f5da6ad3b8d2 100644 --- a/x/ibc/07-tendermint/client/cli/tx.go +++ b/x/ibc/07-tendermint/client/cli/tx.go @@ -16,8 +16,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/evidence" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" @@ -27,7 +27,7 @@ import ( // in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create func GetCmdCreateClient(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "create [client-id] [chain-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period]", + Use: "create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period]", Short: "create new client with a consensus state", Long: strings.TrimSpace(fmt.Sprintf(`create new client with a specified identifier and consensus state: @@ -42,34 +42,30 @@ $ %s tx ibc client create [client-id] [path/to/consensus_state.json] [trusting_p cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc).WithBroadcastMode(flags.BroadcastBlock) clientID := args[0] - chainID := args[1] - var state ibctmtypes.ConsensusState - if err := cdc.UnmarshalJSON([]byte(args[2]), &state); err != nil { + var header ibctmtypes.Header + if err := cdc.UnmarshalJSON([]byte(args[1]), &header); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(args[2]) + contents, err := ioutil.ReadFile(args[1]) if err != nil { return errors.New("neither JSON input nor path to .json file were provided") } - if err := cdc.UnmarshalJSON(contents, &state); err != nil { - return errors.Wrap(err, "error unmarshalling consensus state file") + if err := cdc.UnmarshalJSON(contents, &header); err != nil { + return errors.Wrap(err, "error unmarshalling consensus header file") } } - trustingPeriod, err := time.ParseDuration(args[3]) + trustingPeriod, err := time.ParseDuration(args[2]) if err != nil { return err } - ubdPeriod, err := time.ParseDuration(args[4]) + ubdPeriod, err := time.ParseDuration(args[3]) if err != nil { return err } - msg := ibctmtypes.NewMsgCreateClient( - clientID, chainID, state, - trustingPeriod, ubdPeriod, cliCtx.GetFromAddress(), - ) + msg := ibctmtypes.NewMsgCreateClient(clientID, header, trustingPeriod, ubdPeriod, cliCtx.GetFromAddress()) if err := msg.ValidateBasic(); err != nil { return err diff --git a/x/ibc/07-tendermint/client/rest/rest.go b/x/ibc/07-tendermint/client/rest/rest.go index c483329e14b2..6a5f50dea877 100644 --- a/x/ibc/07-tendermint/client/rest/rest.go +++ b/x/ibc/07-tendermint/client/rest/rest.go @@ -24,12 +24,12 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) // CreateClientReq defines the properties of a create client request's body. type CreateClientReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ClientID string `json:"client_id" yaml:"client_id"` - ChainID string `json:"chain_id" yaml:"chain_id"` - ConsensusState ibctmtypes.ConsensusState `json:"consensus_state" yaml:"consensus_state"` - TrustingPeriod time.Duration `json:"trusting_period" yaml:"trusting_period"` - UnbondingPeriod time.Duration `json:"unbonding_period" yaml:"unbonding_period"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ClientID string `json:"client_id" yaml:"client_id"` + ChainID string `json:"chain_id" yaml:"chain_id"` + Header ibctmtypes.Header `json:"consensus_state" yaml:"consensus_state"` + TrustingPeriod time.Duration `json:"trusting_period" yaml:"trusting_period"` + UnbondingPeriod time.Duration `json:"unbonding_period" yaml:"unbonding_period"` } // UpdateClientReq defines the properties of a update client request's body. diff --git a/x/ibc/07-tendermint/client/rest/tx.go b/x/ibc/07-tendermint/client/rest/tx.go index 378bedcf9636..d21be2e912bd 100644 --- a/x/ibc/07-tendermint/client/rest/tx.go +++ b/x/ibc/07-tendermint/client/rest/tx.go @@ -52,8 +52,7 @@ func createClientHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { // create the message msg := ibctmtypes.NewMsgCreateClient( req.ClientID, - req.ChainID, - req.ConsensusState, + req.Header, req.TrustingPeriod, req.UnbondingPeriod, fromAddr, ) diff --git a/x/ibc/07-tendermint/misbehaviour.go b/x/ibc/07-tendermint/misbehaviour.go index 990412f78c9d..df6009a14164 100644 --- a/x/ibc/07-tendermint/misbehaviour.go +++ b/x/ibc/07-tendermint/misbehaviour.go @@ -10,6 +10,7 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + lite "github.com/tendermint/tendermint/lite2" ) // CheckMisbehaviourAndUpdateState determines whether or not two conflicting @@ -78,19 +79,21 @@ func checkMisbehaviour( return errors.New("unbonding period since last consensus state timestamp is over") } - // Evidence is within the trusting period. ValidatorSet must have 2/3 similarity with trusted FromValidatorSet - // check that the validator sets on both headers are valid given the last trusted validatorset - // less than or equal to evidence height - if err := consensusState.ValidatorSet.VerifyFutureCommit( - evidence.Header1.ValidatorSet, evidence.ChainID, - evidence.Header1.Commit.BlockID, evidence.Header1.Height, evidence.Header1.Commit, + // TODO: Evidence must be within trusting period + // Blocked on https://github.com/cosmos/ics/issues/379 + + // - ValidatorSet must have 2/3 similarity with trusted FromValidatorSet + // - ValidatorSets on both headers are valid given the last trusted ValidatorSet + if err := consensusState.ValidatorSet.VerifyCommitTrusting( + evidence.ChainID, evidence.Header1.Commit.BlockID, evidence.Header1.Height, + evidence.Header1.Commit, lite.DefaultTrustLevel, ); err != nil { return fmt.Errorf("validator set in header 1 has too much change from last known validator set: %v", err) } - if err := consensusState.ValidatorSet.VerifyFutureCommit( - evidence.Header2.ValidatorSet, evidence.ChainID, - evidence.Header2.Commit.BlockID, evidence.Header2.Height, evidence.Header2.Commit, + if err := consensusState.ValidatorSet.VerifyCommitTrusting( + evidence.ChainID, evidence.Header2.Commit.BlockID, evidence.Header2.Height, + evidence.Header2.Commit, lite.DefaultTrustLevel, ); err != nil { return fmt.Errorf("validator set in header 2 has too much change from last known validator set: %v", err) } diff --git a/x/ibc/07-tendermint/misbehaviour_test.go b/x/ibc/07-tendermint/misbehaviour_test.go index ca72b5cc78d1..4387af1cf7b1 100644 --- a/x/ibc/07-tendermint/misbehaviour_test.go +++ b/x/ibc/07-tendermint/misbehaviour_test.go @@ -40,7 +40,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { }{ { "valid misbehavior evidence", - ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), @@ -53,7 +53,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { }, { "valid misbehavior at height greater than last consensusState", - ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), @@ -66,7 +66,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { }, { "consensus state's valset hash different from evidence should still pass", - ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: suite.valSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), @@ -79,7 +79,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { }, { "first valset has too much change", - ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), @@ -92,7 +92,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { }, { "second valset has too much change", - ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), @@ -105,7 +105,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { }, { "both valsets have too much change", - ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altValSet, altSigners), diff --git a/x/ibc/07-tendermint/tendermint_test.go b/x/ibc/07-tendermint/tendermint_test.go index 9c846c50fb3a..c8c465cdc7f8 100644 --- a/x/ibc/07-tendermint/tendermint_test.go +++ b/x/ibc/07-tendermint/tendermint_test.go @@ -38,13 +38,18 @@ func (suite *TendermintTestSuite) SetupTest() { ibctmtypes.RegisterCodec(suite.cdc) commitment.RegisterCodec(suite.cdc) + // now is the time of the current chain, must be after the updating header + // mocks ctx.BlockTime() suite.now = time.Date(2020, 1, 3, 0, 0, 0, 0, time.UTC) suite.clientTime = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) + // Header time is intended to be time for any new header used for updates suite.headerTime = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) suite.privVal = tmtypes.NewMockPV() val := tmtypes.NewValidator(suite.privVal.GetPubKey(), 10) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) - suite.header = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + // Suite header is intended to be header passed in for initial ClientState + // Thus it should have same height and time as ClientState + suite.header = ibctmtypes.CreateTestHeader(chainID, height, suite.clientTime, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } func TestTendermintTestSuite(t *testing.T) { diff --git a/x/ibc/07-tendermint/types/client_state.go b/x/ibc/07-tendermint/types/client_state.go index e681d8f7199f..1d343608b078 100644 --- a/x/ibc/07-tendermint/types/client_state.go +++ b/x/ibc/07-tendermint/types/client_state.go @@ -23,61 +23,50 @@ var _ clientexported.ClientState = ClientState{} type ClientState struct { // Client ID ID string `json:"id" yaml:"id"` - // Chain ID for Tendermint chain, not guaranteed to be unique - ChainID string `json:"chain_id" yaml:"chain_id"` // Duration of the period since the LastestTimestamp during which the // submitted headers are valid for upgrade TrustingPeriod time.Duration `json:"trusting_period" yaml:"trusting_period"` // Duration of the staking unbonding period UnbondingPeriod time.Duration `json:"unbonding_period" yaml:"unbonding_period"` - // Latest block height - LatestHeight uint64 `json:"latest_height" yaml:"latest_height"` - // Latest block time - LatestTimestamp time.Time `json:"latest_time" yaml:"latest_time"` // Block height when the client was frozen due to a misbehaviour FrozenHeight uint64 `json:"frozen_height" yaml:"frozen_height"` + // Last Header that was stored by client + LastHeader Header } // InitializeFromMsg creates a tendermint client state from a CreateClientMsg func InitializeFromMsg( msg MsgCreateClient, ) (ClientState, error) { - return Initialize(msg.GetClientID(), msg.ChainID, msg.GetConsensusState(), msg.TrustingPeriod, msg.UnbondingPeriod) + return Initialize(msg.GetClientID(), msg.TrustingPeriod, msg.UnbondingPeriod, msg.Header) } // Initialize creates a client state and validates its contents, checking that // the provided consensus state is from the same client type. func Initialize( - id string, chainID string, consensusState clientexported.ConsensusState, trustingPeriod, ubdPeriod time.Duration, + id string, trustingPeriod, ubdPeriod time.Duration, + header Header, ) (ClientState, error) { - tmConsState, ok := consensusState.(ConsensusState) - if !ok { - return ClientState{}, errors.New("consensus state is not from Tendermint") - } - latestHeight := tmConsState.GetHeight() - if trustingPeriod >= ubdPeriod { return ClientState{}, errors.New("trusting period should be < unbonding period") } clientState := NewClientState( - id, chainID, trustingPeriod, ubdPeriod, latestHeight, tmConsState.Timestamp, + id, trustingPeriod, ubdPeriod, header, ) return clientState, nil } // NewClientState creates a new ClientState instance func NewClientState( - id string, chainID string, trustingPeriod, ubdPeriod time.Duration, - latestHeight uint64, latestTimestamp time.Time, + id string, trustingPeriod, ubdPeriod time.Duration, + header Header, ) ClientState { return ClientState{ ID: id, - ChainID: chainID, TrustingPeriod: trustingPeriod, UnbondingPeriod: ubdPeriod, - LatestHeight: latestHeight, - LatestTimestamp: latestTimestamp, + LastHeader: header, FrozenHeight: 0, } } @@ -87,6 +76,11 @@ func (cs ClientState) GetID() string { return cs.ID } +// GetChainID returns the chain-id from the last header +func (cs ClientState) GetChainID() string { + return cs.LastHeader.ChainID +} + // ClientType is tendermint. func (cs ClientState) ClientType() clientexported.ClientType { return clientexported.Tendermint @@ -94,12 +88,12 @@ func (cs ClientState) ClientType() clientexported.ClientType { // GetLatestHeight returns latest block height. func (cs ClientState) GetLatestHeight() uint64 { - return cs.LatestHeight + return uint64(cs.LastHeader.Height) } // GetLatestTimestamp returns latest block time. func (cs ClientState) GetLatestTimestamp() time.Time { - return cs.LatestTimestamp + return cs.LastHeader.Time } // IsFrozen returns true if the frozen height has been set. @@ -323,10 +317,10 @@ func validateVerificationArgs( proof commitment.ProofI, consensusState clientexported.ConsensusState, ) error { - if cs.LatestHeight < height { + if cs.GetLatestHeight() < height { return sdkerrors.Wrap( ibctypes.ErrInvalidHeight, - fmt.Sprintf("client state (%s) height < proof height (%d < %d)", cs.ID, cs.LatestHeight, height), + fmt.Sprintf("client state (%s) height < proof height (%d < %d)", cs.ID, cs.GetLatestHeight(), height), ) } diff --git a/x/ibc/07-tendermint/types/client_state_test.go b/x/ibc/07-tendermint/types/client_state_test.go index cbb4c9c9e301..5f392be235e5 100644 --- a/x/ibc/07-tendermint/types/client_state_test.go +++ b/x/ibc/07-tendermint/types/client_state_test.go @@ -36,7 +36,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { // }, { name: "ApplyPrefix failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, @@ -45,7 +45,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "latest client height < height", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, @@ -54,7 +54,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "client is frozen", - clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, @@ -63,7 +63,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "proof verification failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), ValidatorSet: suite.valSet, @@ -114,7 +114,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { // }, { name: "ApplyPrefix failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), connection: conn, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -124,7 +124,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { }, { name: "latest client height < height", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), connection: conn, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -134,7 +134,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { }, { name: "client is frozen", - clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, connection: conn, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -144,7 +144,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { }, { name: "proof verification failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), connection: conn, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -196,7 +196,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { // }, { name: "ApplyPrefix failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), channel: ch, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -206,7 +206,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { }, { name: "latest client height < height", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), channel: ch, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -216,7 +216,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { }, { name: "client is frozen", - clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, channel: ch, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -226,7 +226,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { }, { name: "proof verification failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), channel: ch, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -275,7 +275,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { // }, { name: "ApplyPrefix failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), commitment: []byte{}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -285,7 +285,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { }, { name: "latest client height < height", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), commitment: []byte{}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -295,7 +295,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { }, { name: "client is frozen", - clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, commitment: []byte{}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -305,7 +305,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { }, { name: "proof verification failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), commitment: []byte{}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -354,7 +354,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { // }, { name: "ApplyPrefix failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ack: []byte{}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -364,7 +364,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { }, { name: "latest client height < height", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ack: []byte{}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -374,7 +374,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { }, { name: "client is frozen", - clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, ack: []byte{}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -384,7 +384,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { }, { name: "proof verification failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ack: []byte{}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), @@ -432,7 +432,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { // }, { name: "ApplyPrefix failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, @@ -441,7 +441,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { }, { name: "latest client height < height", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, @@ -450,7 +450,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { }, { name: "client is frozen", - clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, @@ -459,7 +459,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { }, { name: "proof verification failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), ValidatorSet: suite.valSet, @@ -506,7 +506,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { // }, { name: "ApplyPrefix failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, @@ -515,7 +515,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { }, { name: "latest client height < height", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height-1, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, @@ -524,7 +524,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { }, { name: "client is frozen", - clientState: ibctmtypes.ClientState{ID: chainID, LatestHeight: height, FrozenHeight: height - 1}, + clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), }, @@ -533,7 +533,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { }, { name: "proof verification failed", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.now), + clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ Root: commitment.NewRoot(suite.header.AppHash), ValidatorSet: suite.valSet, diff --git a/x/ibc/07-tendermint/types/errors.go b/x/ibc/07-tendermint/types/errors.go index 1f2bcd48174b..58c97a0ebe4b 100644 --- a/x/ibc/07-tendermint/types/errors.go +++ b/x/ibc/07-tendermint/types/errors.go @@ -11,5 +11,5 @@ const ( var ( ErrInvalidTrustingPeriod = sdkerrors.Register(SubModuleName, 1, "invalid trusting period") ErrInvalidUnbondingPeriod = sdkerrors.Register(SubModuleName, 2, "invalid unbonding period") - ErrInvalidChainID = sdkerrors.Register(SubModuleName, 3, "invalid chain ID") + ErrInvalidHeader = sdkerrors.Register(SubModuleName, 3, "invalid header") ) diff --git a/x/ibc/07-tendermint/types/header.go b/x/ibc/07-tendermint/types/header.go index bc426a24ac5b..ddc5e01f458a 100644 --- a/x/ibc/07-tendermint/types/header.go +++ b/x/ibc/07-tendermint/types/header.go @@ -1,6 +1,8 @@ package types import ( + "bytes" + abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" @@ -16,6 +18,7 @@ var _ clientexported.Header = Header{} type Header struct { tmtypes.SignedHeader // contains the commitment root ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` + NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` } // ClientType defines that the Header is a Tendermint consensus algorithm @@ -26,6 +29,7 @@ func (h Header) ClientType() clientexported.ClientType { // ConsensusState returns the consensus state associated with the header func (h Header) ConsensusState() ConsensusState { return ConsensusState{ + Height: uint64(h.Height), Timestamp: h.Time, Root: commitment.NewRoot(h.AppHash), ValidatorSet: h.ValidatorSet, @@ -48,35 +52,20 @@ func (h Header) ValidateBasic(chainID string) error { if h.ValidatorSet == nil { return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set is nil") } + if h.NextValidatorSet == nil { + return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "next validator set is nil") + } + if !bytes.Equal(h.ValidatorsHash, h.ValidatorSet.Hash()) { + return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set does not match hash") + } + if !bytes.Equal(h.NextValidatorsHash, h.NextValidatorSet.Hash()) { + return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "next validator set does not match hash") + } return nil } // ToABCIHeader parses the header to an ABCI header type. // NOTE: only for testing use. func (h Header) ToABCIHeader() abci.Header { - return abci.Header{ - Version: abci.Version{ - App: h.Version.App.Uint64(), - Block: h.Version.Block.Uint64(), - }, - ChainID: h.ChainID, - Height: h.Height, - Time: h.Time, - LastBlockId: abci.BlockID{ - Hash: h.LastBlockID.Hash, - PartsHeader: abci.PartSetHeader{ - Total: int32(h.LastBlockID.PartsHeader.Total), - Hash: h.LastBlockID.PartsHeader.Hash, - }, - }, - LastCommitHash: h.LastCommitHash, - DataHash: h.DataHash, - ValidatorsHash: h.ValidatorsHash, - NextValidatorsHash: h.NextValidatorsHash, - ConsensusHash: h.ConsensusHash, - AppHash: h.AppHash, - LastResultsHash: h.LastResultsHash, - EvidenceHash: h.EvidenceHash, - ProposerAddress: h.ProposerAddress, - } + return tmtypes.TM2PB.Header(h.SignedHeader.Header) } diff --git a/x/ibc/07-tendermint/types/header_test.go b/x/ibc/07-tendermint/types/header_test.go index c5c004028a7f..7c1fc7748d29 100644 --- a/x/ibc/07-tendermint/types/header_test.go +++ b/x/ibc/07-tendermint/types/header_test.go @@ -14,7 +14,7 @@ func (suite *TendermintTestSuite) TestHeaderValidateBasic() { }{ {"valid header", suite.header, chainID, true}, {"signed header basic validation failed", suite.header, "chainID", false}, - {"validator set nil", ibctmtypes.Header{suite.header.SignedHeader, nil}, chainID, false}, + {"validator set nil", ibctmtypes.Header{suite.header.SignedHeader, nil, nil}, chainID, false}, } suite.Require().Equal(clientexported.Tendermint, suite.header.ClientType()) diff --git a/x/ibc/07-tendermint/types/msgs.go b/x/ibc/07-tendermint/types/msgs.go index cc065a6ec308..82a27f458a3d 100644 --- a/x/ibc/07-tendermint/types/msgs.go +++ b/x/ibc/07-tendermint/types/msgs.go @@ -1,13 +1,13 @@ package types import ( - "strings" "time" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -25,8 +25,7 @@ var _ clientexported.MsgUpdateClient = MsgUpdateClient{} // MsgCreateClient defines a message to create an IBC client type MsgCreateClient struct { ClientID string `json:"client_id" yaml:"client_id"` - ChainID string `json:"chain_id" yaml:"chain_id"` - ConsensusState ConsensusState `json:"consensus_state" yaml:"consensus_state"` + Header Header `json:"header" yaml:"header"` TrustingPeriod time.Duration `json:"trusting_period" yaml:"trusting_period"` UnbondingPeriod time.Duration `json:"unbonding_period" yaml:"unbonding_period"` Signer sdk.AccAddress `json:"address" yaml:"address"` @@ -34,13 +33,12 @@ type MsgCreateClient struct { // NewMsgCreateClient creates a new MsgCreateClient instance func NewMsgCreateClient( - id string, chainID string, consensusState ConsensusState, + id string, header Header, trustingPeriod, unbondingPeriod time.Duration, signer sdk.AccAddress, ) MsgCreateClient { return MsgCreateClient{ ClientID: id, - ChainID: chainID, - ConsensusState: consensusState, + Header: header, TrustingPeriod: trustingPeriod, UnbondingPeriod: unbondingPeriod, Signer: signer, @@ -59,12 +57,6 @@ func (msg MsgCreateClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgCreateClient) ValidateBasic() error { - if strings.TrimSpace(msg.ChainID) == "" { - return sdkerrors.Wrap(ErrInvalidChainID, "cannot have empty chain-id") - } - if err := msg.ConsensusState.ValidateBasic(); err != nil { - return err - } if msg.TrustingPeriod == 0 { return sdkerrors.Wrap(ErrInvalidTrustingPeriod, "duration cannot be 0") } @@ -74,6 +66,10 @@ func (msg MsgCreateClient) ValidateBasic() error { if msg.Signer.Empty() { return sdkerrors.ErrInvalidAddress } + // ValidateBasic of provided header with self-attested chain-id + if msg.Header.ValidateBasic(msg.Header.ChainID) != nil { + return sdkerrors.Wrap(ErrInvalidHeader, "header failed validatebasic with its own chain-id") + } return host.DefaultClientIdentifierValidator(msg.ClientID) } @@ -99,7 +95,14 @@ func (msg MsgCreateClient) GetClientType() string { // GetConsensusState implements clientexported.MsgCreateClient func (msg MsgCreateClient) GetConsensusState() clientexported.ConsensusState { - return msg.ConsensusState + // Construct initial consensus state from provided Header + root := commitment.NewRoot(msg.Header.AppHash) + return ConsensusState{ + Timestamp: msg.Header.Time, + Root: root, + Height: uint64(msg.Header.Height), + ValidatorSet: msg.Header.ValidatorSet, + } } // MsgUpdateClient defines a message to update an IBC client diff --git a/x/ibc/07-tendermint/types/msgs_test.go b/x/ibc/07-tendermint/types/msgs_test.go index 6ea7eac33828..d00561d99d26 100644 --- a/x/ibc/07-tendermint/types/msgs_test.go +++ b/x/ibc/07-tendermint/types/msgs_test.go @@ -1,61 +1,43 @@ package types_test import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/secp256k1" - tmtypes "github.com/tendermint/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) -func TestMsgCreateClientValidateBasic(t *testing.T) { - validator := tmtypes.NewValidator(tmtypes.NewMockPV().GetPubKey(), 1) - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) - cs := ibctmtypes.ConsensusState{ - Height: height, - Timestamp: now, - Root: commitment.NewRoot([]byte("root")), - ValidatorSet: valSet, - } +func (suite *TendermintTestSuite) TestMsgCreateClientValidateBasic() { privKey := secp256k1.GenPrivKey() signer := sdk.AccAddress(privKey.PubKey().Address()) - chainID := "gaia" cases := []struct { msg ibctmtypes.MsgCreateClient expPass bool errMsg string }{ - {ibctmtypes.NewMsgCreateClient(exported.ClientTypeTendermint, chainID, cs, trustingPeriod, ubdPeriod, signer), true, "success msg should pass"}, - {ibctmtypes.NewMsgCreateClient("BADCHAIN", chainID, cs, trustingPeriod, ubdPeriod, signer), false, "invalid client id passed"}, - {ibctmtypes.NewMsgCreateClient("goodchain", chainID, cs, trustingPeriod, ubdPeriod, signer), false, "unregistered client type passed"}, - {ibctmtypes.NewMsgCreateClient("goodchain", chainID, ibctmtypes.ConsensusState{}, trustingPeriod, ubdPeriod, signer), false, "invalid Consensus State in msg passed"}, - {ibctmtypes.NewMsgCreateClient("goodchain", chainID, cs, 0, ubdPeriod, signer), false, "zero trusting period passed"}, - {ibctmtypes.NewMsgCreateClient("goodchain", chainID, cs, trustingPeriod, 0, signer), false, "zero unbonding period passed"}, - {ibctmtypes.NewMsgCreateClient("goodchain", chainID, cs, trustingPeriod, ubdPeriod, nil), false, "Empty address passed"}, - {ibctmtypes.NewMsgCreateClient("goodchain", "", cs, trustingPeriod, ubdPeriod, nil), false, "Empty chain ID"}, + {ibctmtypes.NewMsgCreateClient(exported.ClientTypeTendermint, suite.header, trustingPeriod, ubdPeriod, signer), true, "success msg should pass"}, + {ibctmtypes.NewMsgCreateClient("BADCHAIN", suite.header, trustingPeriod, ubdPeriod, signer), false, "invalid client id passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", suite.header, trustingPeriod, ubdPeriod, signer), false, "unregistered client type passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", suite.header, trustingPeriod, ubdPeriod, signer), false, "invalid Consensus State in msg passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", suite.header, 0, ubdPeriod, signer), false, "zero trusting period passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", suite.header, trustingPeriod, 0, signer), false, "zero unbonding period passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", suite.header, trustingPeriod, ubdPeriod, nil), false, "Empty address passed"}, + {ibctmtypes.NewMsgCreateClient("goodchain", suite.header, trustingPeriod, ubdPeriod, nil), false, "Empty chain ID"}, } for i, tc := range cases { err := tc.msg.ValidateBasic() if tc.expPass { - require.NoError(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %v", i, err) } else { - require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } -func TestMsgUpdateClient(t *testing.T) { +func (suite *TendermintTestSuite) TestMsgUpdateClient() { privKey := secp256k1.GenPrivKey() signer := sdk.AccAddress(privKey.PubKey().Address()) @@ -72,9 +54,9 @@ func TestMsgUpdateClient(t *testing.T) { for i, tc := range cases { err := tc.msg.ValidateBasic() if tc.expPass { - require.NoError(t, err, "Msg %d failed: %v", i, err) + suite.Require().NoError(err, "Msg %d failed: %v", i, err) } else { - require.Error(t, err, "Invalid Msg %d passed: %s", i, tc.errMsg) + suite.Require().Error(err, "Invalid Msg %d passed: %s", i, tc.errMsg) } } } diff --git a/x/ibc/07-tendermint/types/test_utils.go b/x/ibc/07-tendermint/types/test_utils.go index bd538bc4871b..85642d29a466 100644 --- a/x/ibc/07-tendermint/types/test_utils.go +++ b/x/ibc/07-tendermint/types/test_utils.go @@ -54,7 +54,8 @@ func CreateTestHeader(chainID string, height int64, timestamp time.Time, valSet } return Header{ - SignedHeader: signedHeader, - ValidatorSet: valSet, + SignedHeader: signedHeader, + ValidatorSet: valSet, + NextValidatorSet: nextValSet, } } diff --git a/x/ibc/07-tendermint/update.go b/x/ibc/07-tendermint/update.go index b9bfebca401c..9f21eb7d8ce2 100644 --- a/x/ibc/07-tendermint/update.go +++ b/x/ibc/07-tendermint/update.go @@ -9,6 +9,7 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + lite "github.com/tendermint/tendermint/lite2" ) // CheckValidityAndUpdateState checks if the provided header is valid and updates @@ -53,7 +54,7 @@ func checkValidity( clientState types.ClientState, header types.Header, currentTimestamp time.Time, ) error { // assert trusting period has not yet passed - if currentTimestamp.Sub(clientState.LatestTimestamp) >= clientState.TrustingPeriod { + if currentTimestamp.Sub(clientState.GetLatestTimestamp()) >= clientState.TrustingPeriod { return errors.New("trusting period since last client timestamp already passed") } @@ -65,35 +66,32 @@ func checkValidity( ) } - // assert header timestamp is past current timestamp - if header.Time.Unix() <= clientState.LatestTimestamp.Unix() { + // assert header timestamp is past latest clientstate timestamp + if header.Time.Unix() <= clientState.GetLatestTimestamp().Unix() { return sdkerrors.Wrapf( clienttypes.ErrInvalidHeader, "header blocktime ≤ latest client state block time (%s ≤ %s)", - header.Time.String(), clientState.LatestTimestamp.String(), + header.Time.String(), clientState.GetLatestTimestamp().String(), ) } // assert header height is newer than any we know - if header.GetHeight() <= clientState.LatestHeight { + if header.GetHeight() <= clientState.GetLatestHeight() { return sdkerrors.Wrapf( clienttypes.ErrInvalidHeader, - "header height ≤ latest client state height (%d ≤ %d)", header.GetHeight(), clientState.LatestHeight, + "header height ≤ latest client state height (%d ≤ %d)", header.GetHeight(), clientState.GetLatestHeight(), ) } - // basic consistency check - if err := header.ValidateBasic(clientState.ChainID); err != nil { - return err - } - - return header.ValidatorSet.VerifyCommit(header.ChainID, header.Commit.BlockID, header.Height, header.Commit) + return lite.Verify(clientState.GetChainID(), &clientState.LastHeader.SignedHeader, clientState.LastHeader.NextValidatorSet, + &header.SignedHeader, header.ValidatorSet, clientState.TrustingPeriod, currentTimestamp, lite.DefaultTrustLevel) } // update the consensus state from a new header func update(clientState types.ClientState, header types.Header) (types.ClientState, types.ConsensusState) { - clientState.LatestHeight = header.GetHeight() + clientState.LastHeader = header consensusState := types.ConsensusState{ + Height: uint64(header.Height), Timestamp: header.Time, Root: commitment.NewRoot(header.AppHash), ValidatorSet: header.ValidatorSet, diff --git a/x/ibc/07-tendermint/update_test.go b/x/ibc/07-tendermint/update_test.go index 5c465c398335..025c480aa4f0 100644 --- a/x/ibc/07-tendermint/update_test.go +++ b/x/ibc/07-tendermint/update_test.go @@ -1,48 +1,162 @@ package tendermint_test import ( + "bytes" + "time" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + tmtypes "github.com/tendermint/tendermint/types" ) func (suite *TendermintTestSuite) TestCheckValidity() { - testCases := []struct { - name string + var ( clientState ibctmtypes.ClientState - expPass bool + newHeader ibctmtypes.Header + currentTime time.Time + ) + + // Setup different validators and signers for testing different types of updates + altPrivVal := tmtypes.NewMockPV() + altVal := tmtypes.NewValidator(altPrivVal.GetPubKey(), height) + + // Create bothValSet with both suite validator and altVal. Would be valid update + bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) + // Create alternative validator set with only altVal, invalid update (too much change in valSet) + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + + signers := []tmtypes.PrivValidator{suite.privVal} + // Create signer array and ensure it is in same order as bothValSet + var bothSigners []tmtypes.PrivValidator + if bytes.Compare(altPrivVal.GetPubKey().Address(), suite.privVal.GetPubKey().Address()) == -1 { + bothSigners = []tmtypes.PrivValidator{altPrivVal, suite.privVal} + } else { + bothSigners = []tmtypes.PrivValidator{suite.privVal, altPrivVal} + } + + altSigners := []tmtypes.PrivValidator{altPrivVal} + + testCases := []struct { + name string + setup func() + expPass bool }{ { - name: "successful update", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height, suite.clientTime), - expPass: true, + name: "successful update with next height and same validator set", + setup: func() { + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, suite.valSet, signers) + currentTime = suite.now + }, + expPass: true, + }, + { + name: "successful update with next height and different validator set", + setup: func() { + oldHeader := ibctmtypes.CreateTestHeader(chainID, height, suite.clientTime, suite.valSet, bothValSet, signers) + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, oldHeader) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, bothValSet, bothValSet, bothSigners) + currentTime = suite.now + }, + expPass: true, + }, + { + name: "successful update with future height and same validator set", + setup: func() { + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, bothValSet, bothValSet, bothSigners) + currentTime = suite.now + }, + expPass: true, + }, + { + name: "unsuccessful update with next height: update header mismatches nextValSetHash", + setup: func() { + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, bothValSet, bothValSet, bothSigners) + currentTime = suite.now + }, + expPass: false, + }, + { + name: "unsuccessful update with future height: too much change in validator set", + setup: func() { + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, altValSet, altValSet, altSigners) + currentTime = suite.now + }, + expPass: false, + }, + { + name: "unsuccessful update: trusting period has passed since last client timestamp", + setup: func() { + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, suite.valSet, signers) + // make current time pass trusting period from last timestamp on clientstate + currentTime = suite.now.Add(ubdPeriod) + }, + expPass: false, + }, + { + name: "unsuccessful update: header timestamp is past current timestamp", + setup: func() { + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers) + currentTime = suite.now + }, + expPass: false, }, { - name: "header basic validation failed", - clientState: ibctmtypes.NewClientState(chainID, "cosmoshub", trustingPeriod, ubdPeriod, height, suite.clientTime), - expPass: false, + name: "unsuccessful update: header timestamp is not past last client timestamp", + setup: func() { + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.clientTime, suite.valSet, suite.valSet, signers) + currentTime = suite.now + }, + expPass: false, }, { - name: "header height < latest client height", - clientState: ibctmtypes.NewClientState(chainID, chainID, trustingPeriod, ubdPeriod, height+1, suite.clientTime), - expPass: false, + name: "header basic validation failed", + setup: func() { + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, suite.valSet, signers) + // cause new header to fail validatebasic by changing commit height to mismatch header height + newHeader.SignedHeader.Commit.Height = height - 1 + currentTime = suite.now + }, + expPass: false, + }, + { + name: "header height < latest client height", + setup: func() { + clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) + // Make new header at height less than latest client state + newHeader = ibctmtypes.CreateTestHeader(chainID, height-1, suite.headerTime, suite.valSet, suite.valSet, signers) + currentTime = suite.now + }, + + expPass: false, }, } for i, tc := range testCases { tc := tc + // setup test + tc.setup() expectedConsensus := ibctmtypes.ConsensusState{ - Timestamp: suite.headerTime, - Root: commitment.NewRoot(suite.header.AppHash), - ValidatorSet: suite.header.ValidatorSet, + Height: uint64(newHeader.Height), + Timestamp: newHeader.Time, + Root: commitment.NewRoot(newHeader.AppHash), + ValidatorSet: newHeader.ValidatorSet, } - clientState, consensusState, err := tendermint.CheckValidityAndUpdateState(tc.clientState, suite.header, suite.now) + clientState, consensusState, err := tendermint.CheckValidityAndUpdateState(clientState, newHeader, currentTime) if tc.expPass { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().Equal(suite.header.GetHeight(), clientState.GetLatestHeight(), "valid test case %d failed: %s", i, tc.name) + suite.Require().Equal(newHeader.GetHeight(), clientState.GetLatestHeight(), "valid test case %d failed: %s", i, tc.name) suite.Require().Equal(expectedConsensus, consensusState, "valid test case %d failed: %s", i, tc.name) } else { suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 64af632ffd03..98f9c8a1acc8 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -13,22 +13,25 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/supply" ) // define constants used for testing const ( testChainID = "test-chain-id" - testClient = "test-client" + testClientIDA = "testclientida" + testClientIDB = "testclientidb" testClientType = clientexported.Tendermint testConnection = "testconnection" @@ -57,95 +60,21 @@ var ( type HandlerTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp - valSet *tmtypes.ValidatorSet -} - -func (suite *HandlerTestSuite) SetupTest() { - isCheckTx := false - app := simapp.Setup(isCheckTx) - - suite.cdc = app.Codec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) - suite.app = app - - privVal := tmtypes.NewMockPV() - - validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) - suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - suite.createClient() - suite.createConnection(connectionexported.OPEN) -} - -func (suite *HandlerTestSuite) createClient() { - suite.app.Commit() - commitID := suite.app.LastCommitID() - - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - - consensusState := ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, - } - - clientState, err := ibctmtypes.Initialize(testClient, testClient, consensusState, trustingPeriod, ubdPeriod) - suite.NoError(err) - _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) - suite.NoError(err) -} - -func (suite *HandlerTestSuite) updateClient() { - // always commit and begin a new block on updateClient - suite.app.Commit() - commitID := suite.app.LastCommitID() - - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - - state := ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - } + cdc *codec.Codec - suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, 1, state) + chainA *TestChain + chainB *TestChain } -func (suite *HandlerTestSuite) createConnection(state connectionexported.State) { - connection := connection.ConnectionEnd{ - State: state, - ClientID: testClient, - Counterparty: connection.Counterparty{ - ClientID: testClient, - ConnectionID: testConnection, - Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), - }, - Versions: connection.GetCompatibleVersions(), - } - - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) -} - -func (suite *HandlerTestSuite) createChannel( - portID, channnelID, connnnectionID, counterpartyPortID, counterpartyChannelID string, state channelexported.State) { - ch := channel.Channel{ - State: state, - Ordering: testChannelOrder, - Counterparty: channel.Counterparty{ - PortID: counterpartyPortID, - ChannelID: counterpartyChannelID, - }, - ConnectionHops: []string{connnnectionID}, - Version: testChannelVersion, - } +func (suite *HandlerTestSuite) SetupTest() { + suite.chainA = NewTestChain(testClientIDA) + suite.chainB = NewTestChain(testClientIDB) - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, channnelID, ch) + suite.cdc = suite.chainA.App.Codec() } func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { - res := suite.app.Query(abci.RequestQuery{ + res := suite.chainA.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), Data: key, Prove: true, @@ -162,26 +91,31 @@ func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitment.Proof, h func (suite *HandlerTestSuite) TestHandleMsgTransfer() { source := true - handler := transfer.NewHandler(suite.app.TransferKeeper) + handler := transfer.NewHandler(suite.chainA.App.TransferKeeper) + ctx := suite.chainA.GetContext() msg := transfer.NewMsgTransfer(testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, source) - res, err := handler(suite.ctx, msg) + res, err := handler(ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // channel does not exist - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) - res, err = handler(suite.ctx, msg) + // Setup channel from A to B + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) + suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) + + res, err = handler(ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // next send sequence not found nextSeqSend := uint64(1) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, nextSeqSend) - res, err = handler(suite.ctx, msg) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(ctx, testPort1, testChannel1, nextSeqSend) + res, err = handler(ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // sender has insufficient coins - _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testCoins) - res, err = handler(suite.ctx, msg) + _ = suite.chainA.App.BankKeeper.SetBalances(ctx, testAddr1, testCoins) + res, err = handler(ctx, msg) suite.Require().NoError(err) suite.Require().NotNil(res, "%+v", res) // successfully executed @@ -189,17 +123,17 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { source = false msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2, source) - _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testPrefixedCoins2) + _ = suite.chainA.App.BankKeeper.SetBalances(ctx, testAddr1, testPrefixedCoins2) - res, err = handler(suite.ctx, msg) + res, err = handler(ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // incorrect denom prefix msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins1, testAddr1, testAddr2, source) - suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(testPrefixedCoins1)) - _ = suite.app.BankKeeper.SetBalances(suite.ctx, testAddr1, testPrefixedCoins1) + suite.chainA.App.SupplyKeeper.SetSupply(ctx, supply.NewSupply(testPrefixedCoins1)) + _ = suite.chainA.App.BankKeeper.SetBalances(ctx, testAddr1, testPrefixedCoins1) - res, err = handler(suite.ctx, msg) + res, err = handler(ctx, msg) suite.Require().NoError(err) suite.Require().NotNil(res, "%+v", res) // successfully executed } @@ -207,3 +141,180 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { func TestHandlerTestSuite(t *testing.T) { suite.Run(t, new(HandlerTestSuite)) } + +type TestChain struct { + ClientID string + App *simapp.SimApp + Header ibctmtypes.Header + Vals *tmtypes.ValidatorSet + Signers []tmtypes.PrivValidator +} + +func NewTestChain(clientID string) *TestChain { + privVal := tmtypes.NewMockPV() + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + signers := []tmtypes.PrivValidator{privVal} + now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + + return &TestChain{ + ClientID: clientID, + App: simapp.Setup(false), + Header: header, + Vals: valSet, + Signers: signers, + } +} + +// Creates simple context for testing purposes +func (chain *TestChain) GetContext() sdk.Context { + return chain.App.BaseApp.NewContext(false, abci.Header{ChainID: chain.Header.ChainID, Height: chain.Header.Height}) +} + +// createClient will create a client for clientChain on targetChain +func (chain *TestChain) CreateClient(client *TestChain) error { + client.Header = nextHeader(client) + // Commit and create a new block on appTarget to get a fresh CommitID + client.App.Commit() + commitID := client.App.LastCommitID() + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) + + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) // get one voting power + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, + }, + Valset: validators, + } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) + + // Create target ctx + ctxTarget := chain.GetContext() + + // create client + clientState, err := ibctmtypes.Initialize(client.ClientID, trustingPeriod, ubdPeriod, client.Header) + if err != nil { + return err + } + _, err = chain.App.IBCKeeper.ClientKeeper.CreateClient(ctxTarget, clientState, client.Header.ConsensusState()) + if err != nil { + return err + } + return nil + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.app.BaseApp, + // ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgCreateClient(clientID, clientexported.ClientTypeTendermint, consState, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) +} + +func (chain *TestChain) updateClient(client *TestChain) { + // Create target ctx + ctxTarget := chain.GetContext() + + // if clientState does not already exist, return without updating + _, found := chain.App.IBCKeeper.ClientKeeper.GetClientState( + ctxTarget, client.ClientID, + ) + if !found { + return + } + + // always commit when updateClient and begin a new block + client.App.Commit() + commitID := client.App.LastCommitID() + + client.Header = nextHeader(client) + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) + + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, + }, + Valset: validators, + } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) + + consensusState := ibctmtypes.ConsensusState{ + Height: uint64(client.Header.Height), + Timestamp: client.Header.Time, + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: client.Vals, + } + + chain.App.IBCKeeper.ClientKeeper.SetClientConsensusState( + ctxTarget, client.ClientID, uint64(client.Header.Height), consensusState, + ) + chain.App.IBCKeeper.ClientKeeper.SetClientState( + ctxTarget, ibctmtypes.NewClientState(client.ClientID, trustingPeriod, ubdPeriod, client.Header), + ) + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.app.BaseApp, + // ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgUpdateClient(clientID, suite.header, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) + // suite.Require().NoError(err) +} + +func (chain *TestChain) createConnection( + connID, counterpartyConnID, clientID, counterpartyClientID string, + state connectionexported.State, +) connectiontypes.ConnectionEnd { + counterparty := connectiontypes.NewCounterparty(counterpartyClientID, counterpartyConnID, chain.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + connection := connectiontypes.ConnectionEnd{ + State: state, + ClientID: clientID, + Counterparty: counterparty, + Versions: connectiontypes.GetCompatibleVersions(), + } + ctx := chain.GetContext() + chain.App.IBCKeeper.ConnectionKeeper.SetConnection(ctx, connID, connection) + return connection +} + +func (chain *TestChain) createChannel( + portID, channelID, counterpartyPortID, counterpartyChannelID string, + state channelexported.State, order exported.Order, connectionID string, +) channeltypes.Channel { + counterparty := channeltypes.NewCounterparty(counterpartyPortID, counterpartyChannelID) + channel := channeltypes.NewChannel(state, order, counterparty, + []string{connectionID}, "1.0", + ) + ctx := chain.GetContext() + chain.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, portID, channelID, channel) + return channel +} + +func nextHeader(chain *TestChain) ibctmtypes.Header { + return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, + chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) +} diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index 082aa2b12f0b..dfb75aa17438 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -14,23 +14,26 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/cosmos/cosmos-sdk/x/staking" ) // define constants used for testing const ( testChainID = "test-chain-id" - testClient = "test-client" + testClientIDA = "testclientIDA" + testClientIDB = "testClientIDb" testClientType = clientexported.Tendermint - testConnection = "testconnection" + testConnection = "testconnectionatob" testPort1 = "bank" testPort2 = "testportid" testChannel1 = "firstchannel" @@ -56,120 +59,224 @@ var ( type KeeperTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp - valSet *tmtypes.ValidatorSet + cdc *codec.Codec + + chainA *TestChain + chainB *TestChain } func (suite *KeeperTestSuite) SetupTest() { - isCheckTx := false - app := simapp.Setup(isCheckTx) + suite.chainA = NewTestChain(testClientIDA) + suite.chainB = NewTestChain(testClientIDB) - suite.cdc = app.Codec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) - suite.app = app + suite.cdc = suite.chainA.App.Codec() +} - privVal := tmtypes.NewMockPV() +// nolint: unused +func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { + res := suite.chainA.App.Query(abci.RequestQuery{ + Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), + Data: key, + Prove: true, + }) - validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) - suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + height = res.Height + proof = commitment.Proof{ + Proof: res.Proof, + } - suite.createClient() - suite.createConnection(connectionexported.OPEN) + return } -func (suite *KeeperTestSuite) createClient() { - suite.app.Commit() - commitID := suite.app.LastCommitID() - - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) +func (suite *KeeperTestSuite) TestGetTransferAccount() { + expectedMaccName := types.GetModuleAccountName() + expectedMaccAddr := sdk.AccAddress(crypto.AddressHash([]byte(expectedMaccName))) - consensusState := ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, - } + macc := suite.chainA.App.TransferKeeper.GetTransferAccount(suite.chainA.GetContext()) - clientState, err := ibctmtypes.Initialize(testClient, testClient, consensusState, trustingPeriod, ubdPeriod) - suite.NoError(err) - _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) - suite.NoError(err) + suite.NotNil(macc) + suite.Equal(expectedMaccName, macc.GetName()) + suite.Equal(expectedMaccAddr, macc.GetAddress()) } -// nolint: unused -func (suite *KeeperTestSuite) updateClient() { - // always commit and begin a new block on updateClient - suite.app.Commit() - commitID := suite.app.LastCommitID() +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) +type TestChain struct { + ClientID string + App *simapp.SimApp + Header ibctmtypes.Header + Vals *tmtypes.ValidatorSet + Signers []tmtypes.PrivValidator +} - state := ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), +func NewTestChain(clientID string) *TestChain { + privVal := tmtypes.NewMockPV() + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + signers := []tmtypes.PrivValidator{privVal} + now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + + return &TestChain{ + ClientID: clientID, + App: simapp.Setup(false), + Header: header, + Vals: valSet, + Signers: signers, } +} - suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, 1, state) +// Creates simple context for testing purposes +func (chain *TestChain) GetContext() sdk.Context { + return chain.App.BaseApp.NewContext(false, abci.Header{ChainID: chain.Header.ChainID, Height: chain.Header.Height}) } -func (suite *KeeperTestSuite) createConnection(state connectionexported.State) { - connection := connection.ConnectionEnd{ - State: state, - ClientID: testClient, - Counterparty: connection.Counterparty{ - ClientID: testClient, - ConnectionID: testConnection, - Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), +// createClient will create a client for clientChain on targetChain +func (chain *TestChain) CreateClient(client *TestChain) error { + client.Header = nextHeader(client) + // Commit and create a new block on appTarget to get a fresh CommitID + client.App.Commit() + commitID := client.App.LastCommitID() + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) + + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) // get one voting power + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, }, - Versions: connection.GetCompatibleVersions(), + Valset: validators, } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) -} + // Create target ctx + ctxTarget := chain.GetContext() -func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channelexported.State) { - ch := channel.Channel{ - State: state, - Ordering: testChannelOrder, - Counterparty: channel.Counterparty{ - PortID: counterpartyPort, - ChannelID: counterpartyChan, - }, - ConnectionHops: []string{connID}, - Version: testChannelVersion, + // create client + clientState, err := ibctmtypes.Initialize(client.ClientID, trustingPeriod, ubdPeriod, client.Header) + if err != nil { + return err } - - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) + _, err = chain.App.IBCKeeper.ClientKeeper.CreateClient(ctxTarget, clientState, client.Header.ConsensusState()) + if err != nil { + return err + } + return nil + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.app.BaseApp, + // ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgCreateClient(clientID, clientexported.ClientTypeTendermint, consState, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) } // nolint: unused -func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { - res := suite.app.Query(abci.RequestQuery{ - Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: key, - Prove: true, - }) +func (chain *TestChain) updateClient(client *TestChain) { + // Create target ctx + ctxTarget := chain.GetContext() + + // if clientState does not already exist, return without updating + _, found := chain.App.IBCKeeper.ClientKeeper.GetClientState( + ctxTarget, client.ClientID, + ) + if !found { + return + } - height = res.Height - proof = commitment.Proof{ - Proof: res.Proof, + // always commit when updateClient and begin a new block + client.App.Commit() + commitID := client.App.LastCommitID() + + client.Header = nextHeader(client) + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) + + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, + }, + Valset: validators, } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) - return -} + consensusState := ibctmtypes.ConsensusState{ + Height: uint64(client.Header.Height), + Timestamp: client.Header.Time, + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: client.Vals, + } -func (suite *KeeperTestSuite) TestGetTransferAccount() { - expectedMaccName := types.GetModuleAccountName() - expectedMaccAddr := sdk.AccAddress(crypto.AddressHash([]byte(expectedMaccName))) + chain.App.IBCKeeper.ClientKeeper.SetClientConsensusState( + ctxTarget, client.ClientID, uint64(client.Header.Height), consensusState, + ) + chain.App.IBCKeeper.ClientKeeper.SetClientState( + ctxTarget, ibctmtypes.NewClientState(client.ClientID, trustingPeriod, ubdPeriod, client.Header), + ) + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.app.BaseApp, + // ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgUpdateClient(clientID, suite.header, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) + // suite.Require().NoError(err) +} - macc := suite.app.TransferKeeper.GetTransferAccount(suite.ctx) +func (chain *TestChain) createConnection( + connID, counterpartyConnID, clientID, counterpartyClientID string, + state connectionexported.State, +) connectiontypes.ConnectionEnd { + counterparty := connectiontypes.NewCounterparty(counterpartyClientID, counterpartyConnID, chain.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + connection := connectiontypes.ConnectionEnd{ + State: state, + ClientID: clientID, + Counterparty: counterparty, + Versions: connectiontypes.GetCompatibleVersions(), + } + ctx := chain.GetContext() + chain.App.IBCKeeper.ConnectionKeeper.SetConnection(ctx, connID, connection) + return connection +} - suite.NotNil(macc) - suite.Equal(expectedMaccName, macc.GetName()) - suite.Equal(expectedMaccAddr, macc.GetAddress()) +func (chain *TestChain) createChannel( + portID, channelID, counterpartyPortID, counterpartyChannelID string, + state channelexported.State, order exported.Order, connectionID string, +) channeltypes.Channel { + counterparty := channeltypes.NewCounterparty(counterpartyPortID, counterpartyChannelID) + channel := channeltypes.NewChannel(state, order, counterparty, + []string{connectionID}, "1.0", + ) + ctx := chain.GetContext() + chain.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, portID, channelID, channel) + return channel } -func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(KeeperTestSuite)) +func nextHeader(chain *TestChain) ibctmtypes.Header { + return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, + chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) } diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 38a0cff55d90..101ec8698ce9 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -4,6 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" @@ -21,43 +22,55 @@ func (suite *KeeperTestSuite) TestSendTransfer() { }{ {"successful transfer from source chain", testCoins, func() { - suite.app.BankKeeper.AddCoins(suite.ctx, testAddr1, testCoins) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), testAddr1, testCoins) + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) + suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort1, testChannel1, 1) }, true, true}, {"successful transfer from source chain with denom prefix", testCoins2, func() { - _, err := suite.app.BankKeeper.AddCoins(suite.ctx, testAddr1, testCoins) + _, err := suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), testAddr1, testCoins) suite.Require().NoError(err) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) + suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort1, testChannel1, 1) }, true, true}, {"successful transfer from external chain", testCoins, func() { - suite.app.SupplyKeeper.SetSupply(suite.ctx, supply.NewSupply(prefixCoins)) - _, err := suite.app.BankKeeper.AddCoins(suite.ctx, testAddr1, prefixCoins) + suite.chainA.App.SupplyKeeper.SetSupply(suite.chainA.GetContext(), supply.NewSupply(prefixCoins)) + _, err := suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), testAddr1, prefixCoins) suite.Require().NoError(err) - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) + suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort1, testChannel1, 1) }, false, true}, {"source channel not found", testCoins, func() {}, true, false}, {"next seq send not found", testCoins, func() { - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) + suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) }, true, false}, // createOutgoingPacket tests // - source chain {"send coins failed", testCoins, func() { - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) + suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort1, testChannel1, 1) }, true, false}, // - receiving chain {"send from module account failed", testCoins, func() { - suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, channelexported.OPEN) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, testPort1, testChannel1, 1) + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) + suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort1, testChannel1, 1) }, false, false}, } @@ -68,8 +81,8 @@ func (suite *KeeperTestSuite) TestSendTransfer() { tc.malleate() - err := suite.app.TransferKeeper.SendTransfer( - suite.ctx, testPort1, testChannel1, 100, tc.amount, testAddr1, testAddr2, tc.isSourceChain, + err := suite.chainA.App.TransferKeeper.SendTransfer( + suite.chainA.GetContext(), testPort1, testChannel1, 100, tc.amount, testAddr1, testAddr2, tc.isSourceChain, ) if tc.expPass { @@ -114,7 +127,7 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { data.Source = false data.Amount = prefixCoins escrow := types.GetEscrowAddress(testPort2, testChannel2) - _, err := suite.app.BankKeeper.AddCoins(suite.ctx, escrow, testCoins) + _, err := suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), escrow, testCoins) suite.Require().NoError(err) }, true}, } @@ -127,7 +140,7 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { suite.SetupTest() // reset tc.malleate() - err := suite.app.TransferKeeper.ReceiveTransfer(suite.ctx, packet, data) + err := suite.chainA.App.TransferKeeper.ReceiveTransfer(suite.chainA.GetContext(), packet, data) if tc.expPass { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) @@ -149,7 +162,7 @@ func (suite *KeeperTestSuite) TestTimeoutTransfer() { {"successful timeout from source chain", func() { escrow := types.GetEscrowAddress(testPort2, testChannel2) - _, err := suite.app.BankKeeper.AddCoins(suite.ctx, escrow, sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(100)))) + _, err := suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), escrow, sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(100)))) suite.Require().NoError(err) }, true}, {"successful timeout from external chain", @@ -181,7 +194,7 @@ func (suite *KeeperTestSuite) TestTimeoutTransfer() { suite.SetupTest() // reset tc.malleate() - err := suite.app.TransferKeeper.TimeoutTransfer(suite.ctx, packet, data) + err := suite.chainA.App.TransferKeeper.TimeoutTransfer(suite.chainA.GetContext(), packet, data) if tc.expPass { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go index 6148a01f8c33..535157c7ad6c 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/ante/ante_test.go @@ -14,12 +14,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" + connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" + "github.com/cosmos/cosmos-sdk/x/staking" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" "github.com/cosmos/cosmos-sdk/x/ibc/ante" @@ -29,13 +31,16 @@ import ( // define constants used for testing const ( testChainID = "test-chain-id" - testClient = "test-client" + testClientIDA = "testclientida" + testClientIDB = "testclientidb" testClientType = clientexported.Tendermint testConnection = "testconnection" testChannelVersion = "1.0" + height = 10 + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) @@ -44,105 +49,27 @@ const ( type HandlerTestSuite struct { suite.Suite - cdc *codec.Codec - ctx sdk.Context - app *simapp.SimApp - valSet *tmtypes.ValidatorSet - now time.Time -} - -func (suite *HandlerTestSuite) SetupTest() { - isCheckTx := false - app := simapp.Setup(isCheckTx) - suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) - - suite.cdc = app.Codec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) - suite.app = app - - privVal := tmtypes.NewMockPV() - - validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) - suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - suite.createClient() - suite.createConnection(connectionexported.OPEN) -} - -func (suite *HandlerTestSuite) createClient() { - suite.app.Commit() - commitID := suite.app.LastCommitID() - now2 := suite.now.Add(time.Hour) + cdc *codec.Codec - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1, Time: now2}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - - consensusState := ibctmtypes.ConsensusState{ - Timestamp: suite.now, - Root: commitment.NewRoot(commitID.Hash), - ValidatorSet: suite.valSet, - } - - clientState, err := ibctmtypes.Initialize(testClient, testClient, consensusState, trustingPeriod, ubdPeriod) - suite.NoError(err) - _, err = suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientState, consensusState) - suite.NoError(err) + chainA *TestChain + chainB *TestChain } -func (suite *HandlerTestSuite) updateClient() { - // always commit and begin a new block on updateClient - suite.app.Commit() - commitID := suite.app.LastCommitID() - - height := suite.app.LastBlockHeight() + 1 - suite.now = suite.now.Add(time.Minute) - - suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: height, Time: suite.now}}) - suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{}) - - state := ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(commitID.Hash), - } - - suite.app.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.ctx, testClient, uint64(height-1), state) - csi, _ := suite.app.IBCKeeper.ClientKeeper.GetClientState(suite.ctx, testClient) - cs, _ := csi.(ibctmtypes.ClientState) - cs.LatestHeight = uint64(height - 1) - suite.app.IBCKeeper.ClientKeeper.SetClientState(suite.ctx, cs) -} - -func (suite *HandlerTestSuite) createConnection(state connectionexported.State) { - connection := connection.ConnectionEnd{ - State: state, - ClientID: testClient, - Counterparty: connection.Counterparty{ - ClientID: testClient, - ConnectionID: testConnection, - Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), - }, - Versions: connection.GetCompatibleVersions(), - } - - suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection) -} +func (suite *HandlerTestSuite) SetupTest() { + suite.chainA = NewTestChain(testClientIDA) + suite.chainB = NewTestChain(testClientIDB) -func (suite *HandlerTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state channelexported.State, order channelexported.Order) { - ch := channel.Channel{ - State: state, - Ordering: order, - Counterparty: channel.Counterparty{ - PortID: counterpartyPort, - ChannelID: counterpartyChan, - }, - ConnectionHops: []string{connID}, - Version: testChannelVersion, - } + suite.cdc = suite.chainA.App.Codec() - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, ch) + // create client and connection during setups + suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) + suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) + suite.chainB.createConnection(testConnection, testConnection, testClientIDA, testClientIDB, connectionexported.OPEN) } -func (suite *HandlerTestSuite) queryProof(key string) (proof commitment.Proof, height int64) { - res := suite.app.Query(abci.RequestQuery{ +func queryProof(chain *TestChain, key string) (proof commitment.Proof, height int64) { + res := chain.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), Data: []byte(key), Prove: true, @@ -164,39 +91,44 @@ func (suite *HandlerTestSuite) newTx(msg sdk.Msg) sdk.Tx { func (suite *HandlerTestSuite) TestHandleMsgPacketOrdered() { handler := sdk.ChainAnteDecorators(ante.NewProofVerificationDecorator( - suite.app.IBCKeeper.ClientKeeper, - suite.app.IBCKeeper.ChannelKeeper, + suite.chainA.App.IBCKeeper.ClientKeeper, + suite.chainA.App.IBCKeeper.ChannelKeeper, )) packet := channel.NewPacket(newPacket(12345), 1, portid, chanid, cpportid, cpchanid) - cctx, _ := suite.ctx.CacheContext() - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, packet.SourcePort, packet.SourceChannel, 1) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, packet.SourcePort, packet.SourceChannel, packet.Sequence, channeltypes.CommitPacket(packet.Data)) + ctx := suite.chainA.GetContext() + cctx, _ := ctx.CacheContext() + // suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(ctx, packet.SourcePort, packet.SourceChannel, 1) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), packet.SourcePort, packet.SourceChannel, packet.Sequence, channeltypes.CommitPacket(packet.Data)) msg := channel.NewMsgPacket(packet, nil, 0, addr1) _, err := handler(cctx, suite.newTx(msg), false) suite.Error(err, "%+v", err) // channel does not exist - cctx, _ = suite.ctx.CacheContext() - suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channelexported.OPEN, channelexported.ORDERED) + suite.chainA.createChannel(cpportid, cpchanid, portid, chanid, channelexported.OPEN, channelexported.ORDERED, testConnection) + suite.chainB.createChannel(portid, chanid, cpportid, cpchanid, channelexported.OPEN, channelexported.ORDERED, testConnection) + ctx = suite.chainA.GetContext() packetCommitmentPath := ibctypes.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, packet.Sequence) - proof, proofHeight := suite.queryProof(packetCommitmentPath) + proof, proofHeight := queryProof(suite.chainB, packetCommitmentPath) msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) _, err = handler(cctx, suite.newTx(msg), false) suite.Error(err, "%+v", err) // invalid proof - suite.updateClient() + suite.chainA.updateClient(suite.chainB) + // // commit chainA to flush to IAVL so we can get proof + // suite.chainA.App.Commit() + // suite.chainA.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.chainA.App.LastBlockHeight() + 1, Time: suite.chainA.Header.Time}}) + // ctx = suite.chainA.GetContext() - proof, proofHeight = suite.queryProof(packetCommitmentPath) + proof, proofHeight = queryProof(suite.chainB, packetCommitmentPath) msg = channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.ctx, cpportid, cpchanid, 1) - cctx, write := suite.ctx.CacheContext() for i := 0; i < 10; i++ { - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(cctx, cpportid, cpchanid, uint64(i)) + cctx, write := suite.chainA.GetContext().CacheContext() + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(cctx, cpportid, cpchanid, uint64(i)) _, err := handler(cctx, suite.newTx(msg), false) if err == nil { - err = suite.app.IBCKeeper.ChannelKeeper.PacketExecuted(cctx, packet, packet.Data) + err = suite.chainA.App.IBCKeeper.ChannelKeeper.PacketExecuted(cctx, packet, packet.Data) } if i == 1 { suite.NoError(err, "%d", i) // successfully executed @@ -209,8 +141,8 @@ func (suite *HandlerTestSuite) TestHandleMsgPacketOrdered() { func (suite *HandlerTestSuite) TestHandleMsgPacketUnordered() { handler := sdk.ChainAnteDecorators(ante.NewProofVerificationDecorator( - suite.app.IBCKeeper.ClientKeeper, - suite.app.IBCKeeper.ChannelKeeper, + suite.chainA.App.IBCKeeper.ClientKeeper, + suite.chainA.App.IBCKeeper.ChannelKeeper, )) // Not testing nonexist channel, invalid proof, nextseqsend, they are already tested in TestHandleMsgPacketOrdered @@ -218,20 +150,20 @@ func (suite *HandlerTestSuite) TestHandleMsgPacketUnordered() { var packet channeltypes.Packet for i := 0; i < 5; i++ { packet = channel.NewPacket(newPacket(uint64(i)), uint64(i), portid, chanid, cpportid, cpchanid) - suite.app.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.ctx, packet.SourcePort, packet.SourceChannel, uint64(i), channeltypes.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), packet.SourcePort, packet.SourceChannel, uint64(i), channeltypes.CommitPacket(packet.Data)) } - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, packet.SourcePort, packet.SourceChannel, uint64(10)) + // suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), packet.SourcePort, packet.SourceChannel, uint64(10)) - suite.createChannel(cpportid, cpchanid, testConnection, portid, chanid, channelexported.OPEN, channelexported.UNORDERED) + suite.chainA.createChannel(cpportid, cpchanid, portid, chanid, channelexported.OPEN, channelexported.UNORDERED, testConnection) - suite.updateClient() + suite.chainA.updateClient(suite.chainB) for i := 10; i >= 0; i-- { - cctx, write := suite.ctx.CacheContext() + cctx, write := suite.chainA.GetContext().CacheContext() packet = channel.NewPacket(newPacket(uint64(i)), uint64(i), portid, chanid, cpportid, cpchanid) packetCommitmentPath := ibctypes.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, uint64(i)) - proof, proofHeight := suite.queryProof(packetCommitmentPath) + proof, proofHeight := queryProof(suite.chainB, packetCommitmentPath) msg := channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) _, err := handler(cctx, suite.newTx(msg), false) if i < 5 { @@ -242,10 +174,188 @@ func (suite *HandlerTestSuite) TestHandleMsgPacketUnordered() { } } } + func TestHandlerTestSuite(t *testing.T) { suite.Run(t, new(HandlerTestSuite)) } +type TestChain struct { + ClientID string + App *simapp.SimApp + Header ibctmtypes.Header + Vals *tmtypes.ValidatorSet + Signers []tmtypes.PrivValidator +} + +func NewTestChain(clientID string) *TestChain { + privVal := tmtypes.NewMockPV() + validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + signers := []tmtypes.PrivValidator{privVal} + now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + + return &TestChain{ + ClientID: clientID, + App: simapp.Setup(false), + Header: header, + Vals: valSet, + Signers: signers, + } +} + +// Creates simple context for testing purposes +func (chain *TestChain) GetContext() sdk.Context { + return chain.App.BaseApp.NewContext(false, abci.Header{ChainID: chain.Header.ChainID, Height: chain.Header.Height}) +} + +// createClient will create a client for clientChain on targetChain +func (chain *TestChain) CreateClient(client *TestChain) error { + client.Header = nextHeader(client) + // Commit and create a new block on appTarget to get a fresh CommitID + client.App.Commit() + commitID := client.App.LastCommitID() + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) + + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) // get one voting power + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, + }, + Valset: validators, + } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) + + // Create target ctx + ctxTarget := chain.GetContext() + + // create client + clientState, err := ibctmtypes.Initialize(client.ClientID, trustingPeriod, ubdPeriod, client.Header) + if err != nil { + return err + } + _, err = chain.App.IBCKeeper.ClientKeeper.CreateClient(ctxTarget, clientState, client.Header.ConsensusState()) + if err != nil { + return err + } + return nil + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.chainA.App.BaseApp, + // ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgCreateClient(clientID, clientexported.ClientTypeTendermint, consState, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) +} + +func (chain *TestChain) updateClient(client *TestChain) { + // Create target ctx + ctxTarget := chain.GetContext() + + // if clientState does not already exist, return without updating + _, found := chain.App.IBCKeeper.ClientKeeper.GetClientState( + ctxTarget, client.ClientID, + ) + if !found { + return + } + + // always commit when updateClient and begin a new block + client.App.Commit() + commitID := client.App.LastCommitID() + + client.Header = nextHeader(client) + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) + + // Set HistoricalInfo on client chain after Commit + ctxClient := client.GetContext() + validator := staking.NewValidator( + sdk.ValAddress(client.Vals.Validators[0].Address), client.Vals.Validators[0].PubKey, staking.Description{}, + ) + validator.Status = sdk.Bonded + validator.Tokens = sdk.NewInt(1000000) + validators := []staking.Validator{validator} + histInfo := staking.HistoricalInfo{ + Header: abci.Header{ + AppHash: commitID.Hash, + }, + Valset: validators, + } + client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) + + consensusState := ibctmtypes.ConsensusState{ + Height: uint64(client.Header.Height) - 1, + Timestamp: client.Header.Time, + Root: commitment.NewRoot(commitID.Hash), + ValidatorSet: client.Vals, + } + + chain.App.IBCKeeper.ClientKeeper.SetClientConsensusState( + ctxTarget, client.ClientID, uint64(client.Header.Height-1), consensusState, + ) + chain.App.IBCKeeper.ClientKeeper.SetClientState( + ctxTarget, ibctmtypes.NewClientState(client.ClientID, trustingPeriod, ubdPeriod, client.Header), + ) + + // _, _, err := simapp.SignCheckDeliver( + // suite.T(), + // suite.cdc, + // suite.chainA.App.BaseApp, + // ctx.BlockHeader(), + // []sdk.Msg{clienttypes.NewMsgUpdateClient(clientID, suite.header, accountAddress)}, + // []uint64{baseAccount.GetAccountNumber()}, + // []uint64{baseAccount.GetSequence()}, + // true, true, accountPrivKey, + // ) + // suite.Require().NoError(err) +} + +func (chain *TestChain) createConnection( + connID, counterpartyConnID, clientID, counterpartyClientID string, + state connectionexported.State, +) connectiontypes.ConnectionEnd { + counterparty := connectiontypes.NewCounterparty(counterpartyClientID, counterpartyConnID, chain.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) + connection := connectiontypes.ConnectionEnd{ + State: state, + ClientID: clientID, + Counterparty: counterparty, + Versions: connectiontypes.GetCompatibleVersions(), + } + ctx := chain.GetContext() + chain.App.IBCKeeper.ConnectionKeeper.SetConnection(ctx, connID, connection) + return connection +} + +func (chain *TestChain) createChannel( + portID, channelID, counterpartyPortID, counterpartyChannelID string, + state channelexported.State, order exported.Order, connectionID string, +) channeltypes.Channel { + counterparty := channeltypes.NewCounterparty(counterpartyPortID, counterpartyChannelID) + channel := channeltypes.NewChannel(state, order, counterparty, + []string{connectionID}, "1.0", + ) + ctx := chain.GetContext() + chain.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, portID, channelID, channel) + return channel +} + +func nextHeader(chain *TestChain) ibctmtypes.Header { + return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, + chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) +} + var _ channelexported.PacketDataI = packetT{} type packetT struct { diff --git a/x/slashing/keeper/keeper.go b/x/slashing/keeper/keeper.go index 3616a7cd3dab..3d9baac23cf6 100644 --- a/x/slashing/keeper/keeper.go +++ b/x/slashing/keeper/keeper.go @@ -23,6 +23,11 @@ type Keeper struct { // NewKeeper creates a slashing keeper func NewKeeper(cdc codec.Marshaler, key sdk.StoreKey, sk types.StakingKeeper, paramspace types.ParamSubspace) Keeper { + // set KeyTable if it has not already been set + if !paramspace.HasKeyTable() { + paramspace = paramspace.WithKeyTable(types.ParamKeyTable()) + } + return Keeper{ storeKey: key, cdc: cdc, From ace2a984076b37f57545bc51fc1fff47040e7d71 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 21 Feb 2020 23:02:45 +0100 Subject: [PATCH 090/176] Disambiguate error codes --- x/ibc/02-client/types/errors.go | 1 + x/ibc/03-connection/keeper/handshake.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x/ibc/02-client/types/errors.go b/x/ibc/02-client/types/errors.go index ceba41f85988..d1c8d317a4f1 100644 --- a/x/ibc/02-client/types/errors.go +++ b/x/ibc/02-client/types/errors.go @@ -23,4 +23,5 @@ var ( ErrFailedPacketAckVerification = sdkerrors.Register(SubModuleName, 17, "packet acknowledgement verification failed") ErrFailedPacketAckAbsenceVerification = sdkerrors.Register(SubModuleName, 18, "packet acknowledgement absence verification failed") ErrFailedNextSeqRecvVerification = sdkerrors.Register(SubModuleName, 19, "next sequence receive verification failed") + ErrSelfConsensusStateNotFound = sdkerrors.Register(SubModuleName, 20, "self consensus state not found") ) diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index 497c52455e56..e8d0003c6159 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -62,7 +62,7 @@ func (k Keeper) ConnOpenTry( expectedConsensusState, found := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if !found { - return clienttypes.ErrConsensusStateNotFound + return clienttypes.ErrSelfConsensusStateNotFound } // expectedConnection defines Chain A's ConnectionEnd @@ -160,7 +160,7 @@ func (k Keeper) ConnOpenAck( // Retrieve chainA's consensus state at consensusheight expectedConsensusState, found := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if !found { - return clienttypes.ErrConsensusStateNotFound + return clienttypes.ErrSelfConsensusStateNotFound } prefix := k.GetCommitmentPrefix() From bb7e803cb9291ff408a2d8ceab29a6292537012b Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Mon, 24 Feb 2020 11:05:40 -0800 Subject: [PATCH 091/176] Fix binary marshalling for state storage --- x/ibc/07-tendermint/types/client_state.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/ibc/07-tendermint/types/client_state.go b/x/ibc/07-tendermint/types/client_state.go index 1d343608b078..2081a96333e9 100644 --- a/x/ibc/07-tendermint/types/client_state.go +++ b/x/ibc/07-tendermint/types/client_state.go @@ -151,7 +151,7 @@ func (cs ClientState) VerifyConnectionState( return err } - bz, err := cdc.MarshalBinaryBare(connectionEnd) + bz, err := cdc.MarshalBinaryLengthPrefixed(connectionEnd) if err != nil { return err } From ac0e739ff7297fc83816332b5e639d086ec9d207 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Wed, 26 Feb 2020 11:23:52 -0300 Subject: [PATCH 092/176] readd MsgSubmitClientMisbehaviour --- x/ibc/07-tendermint/client/cli/tx.go | 3 +- x/ibc/07-tendermint/client/rest/swagger.go | 3 +- x/ibc/07-tendermint/client/rest/tx.go | 3 +- x/ibc/07-tendermint/types/codec.go | 1 + x/ibc/07-tendermint/types/msgs.go | 65 ++++++++++++++++++++-- 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/x/ibc/07-tendermint/client/cli/tx.go b/x/ibc/07-tendermint/client/cli/tx.go index f5da6ad3b8d2..26bab9996521 100644 --- a/x/ibc/07-tendermint/client/cli/tx.go +++ b/x/ibc/07-tendermint/client/cli/tx.go @@ -18,7 +18,6 @@ import ( "github.com/cosmos/cosmos-sdk/version" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/evidence" evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) @@ -151,7 +150,7 @@ $ %s tx ibc client misbehaviour [path/to/evidence.json] --from node0 --home ../n } } - msg := evidence.NewMsgSubmitEvidence(ev, cliCtx.GetFromAddress()) + msg := ibctmtypes.NewMsgSubmitClientMisbehaviour(ev, cliCtx.GetFromAddress()) if err := msg.ValidateBasic(); err != nil { return err } diff --git a/x/ibc/07-tendermint/client/rest/swagger.go b/x/ibc/07-tendermint/client/rest/swagger.go index 659569346059..32bb8761f3de 100644 --- a/x/ibc/07-tendermint/client/rest/swagger.go +++ b/x/ibc/07-tendermint/client/rest/swagger.go @@ -2,7 +2,6 @@ package rest import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/evidence" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) @@ -23,7 +22,7 @@ type ( } PostSubmitMisbehaviour struct { - Msgs []evidence.MsgSubmitEvidence `json:"msg" yaml:"msg"` + Msgs []ibctmtypes.MsgSubmitClientMisbehaviour `json:"msg" yaml:"msg"` Fee authtypes.StdFee `json:"fee" yaml:"fee"` Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` diff --git a/x/ibc/07-tendermint/client/rest/tx.go b/x/ibc/07-tendermint/client/rest/tx.go index d21be2e912bd..855fce80c674 100644 --- a/x/ibc/07-tendermint/client/rest/tx.go +++ b/x/ibc/07-tendermint/client/rest/tx.go @@ -10,7 +10,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" - "github.com/cosmos/cosmos-sdk/x/evidence" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) @@ -145,7 +144,7 @@ func submitMisbehaviourHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } // create the message - msg := evidence.NewMsgSubmitEvidence(req.Evidence, fromAddr) + msg := ibctmtypes.NewMsgSubmitClientMisbehaviour(req.Evidence, fromAddr) if err := msg.ValidateBasic(); err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return diff --git a/x/ibc/07-tendermint/types/codec.go b/x/ibc/07-tendermint/types/codec.go index 61e63c31f603..4221c58eda4a 100644 --- a/x/ibc/07-tendermint/types/codec.go +++ b/x/ibc/07-tendermint/types/codec.go @@ -15,6 +15,7 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(Evidence{}, "ibc/client/tendermint/Evidence", nil) cdc.RegisterConcrete(MsgCreateClient{}, "ibc/client/MsgCreateClient", nil) cdc.RegisterConcrete(MsgUpdateClient{}, "ibc/client/MsgUpdateClient", nil) + cdc.RegisterConcrete(MsgSubmitClientMisbehaviour{}, "ibc/client/MsgSubmitClientMisbehaviour", nil) SetSubModuleCodec(cdc) } diff --git a/x/ibc/07-tendermint/types/msgs.go b/x/ibc/07-tendermint/types/msgs.go index 82a27f458a3d..aec1d3a0b9a0 100644 --- a/x/ibc/07-tendermint/types/msgs.go +++ b/x/ibc/07-tendermint/types/msgs.go @@ -5,7 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - + evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" @@ -16,11 +17,14 @@ import ( const ( TypeMsgCreateClient string = "create_client" TypeMsgUpdateClient string = "update_client" - TypeClientMisbehaviour string = "client_misbehaviour" + TypeMsgSubmitClientMisbehaviour string = "submit_client_misbehaviour" ) -var _ clientexported.MsgCreateClient = MsgCreateClient{} -var _ clientexported.MsgUpdateClient = MsgUpdateClient{} +var ( + _ clientexported.MsgCreateClient = MsgCreateClient{} + _ clientexported.MsgUpdateClient = MsgUpdateClient{} + _ evidenceexported.MsgSubmitEvidence = MsgSubmitClientMisbehaviour{} +) // MsgCreateClient defines a message to create an IBC client type MsgCreateClient struct { @@ -158,3 +162,56 @@ func (msg MsgUpdateClient) GetClientID() string { func (msg MsgUpdateClient) GetHeader() clientexported.Header { return msg.Header } + +// MsgSubmitClientMisbehaviour defines an sdk.Msg type that supports submitting +// Evidence for client misbehaviour. +type MsgSubmitClientMisbehaviour struct { + Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` + Submitter sdk.AccAddress `json:"submitter" yaml:"submitter"` +} + +// NewMsgSubmitClientMisbehaviour creates a new MsgSubmitClientMisbehaviour +// instance. +func NewMsgSubmitClientMisbehaviour(e evidenceexported.Evidence, s sdk.AccAddress) MsgSubmitClientMisbehaviour { + return MsgSubmitClientMisbehaviour{Evidence: e, Submitter: s} +} + +// Route returns the MsgSubmitClientMisbehaviour's route. +func (msg MsgSubmitClientMisbehaviour) Route() string { return ibctypes.RouterKey } + +// Type returns the MsgSubmitClientMisbehaviour's type. +func (msg MsgSubmitClientMisbehaviour) Type() string { return TypeMsgSubmitClientMisbehaviour } + +// ValidateBasic performs basic (non-state-dependant) validation on a MsgSubmitClientMisbehaviour. +func (msg MsgSubmitClientMisbehaviour) ValidateBasic() error { + if msg.Evidence == nil { + return sdkerrors.Wrap(evidencetypes.ErrInvalidEvidence, "missing evidence") + } + if err := msg.Evidence.ValidateBasic(); err != nil { + return err + } + if msg.Submitter.Empty() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Submitter.String()) + } + + return nil +} + +// GetSignBytes returns the raw bytes a signer is expected to sign when submitting +// a MsgSubmitClientMisbehaviour message. +func (msg MsgSubmitClientMisbehaviour) GetSignBytes() []byte { + return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) +} + +// GetSigners returns the single expected signer for a MsgSubmitClientMisbehaviour. +func (msg MsgSubmitClientMisbehaviour) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Submitter} +} + +func (msg MsgSubmitClientMisbehaviour) GetEvidence() evidenceexported.Evidence { + return msg.Evidence +} + +func (msg MsgSubmitClientMisbehaviour) GetSubmitter() sdk.AccAddress { + return msg.Submitter +} \ No newline at end of file From 68f6700b37e7ef47bac136354d0c127112ae8c89 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Wed, 26 Feb 2020 12:33:49 -0800 Subject: [PATCH 093/176] Fix double flag registration --- x/auth/client/cli/query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/client/cli/query.go b/x/auth/client/cli/query.go index 0ef0a46e91a4..e4946c5e3e02 100644 --- a/x/auth/client/cli/query.go +++ b/x/auth/client/cli/query.go @@ -100,7 +100,7 @@ func GetAccountCmd(cdc *codec.Codec) *cobra.Command { }, } - return flags.GetCommands(cmd)[0] + return cmd } // QueryTxsByEventsCmd returns a command to search through transactions by events. From 69d089cbda0bc8fa478ba10ad9d0d170e8261e2e Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Thu, 27 Feb 2020 17:03:16 -0300 Subject: [PATCH 094/176] ICS23 refactor (#5710) * ICS23 restructure directories * more fixes * format --- x/ibc/02-client/client/cli/query.go | 4 +- x/ibc/02-client/client/rest/swagger.go | 6 +- x/ibc/02-client/client/utils/utils.go | 4 +- x/ibc/02-client/exported/exported.go | 32 +-- x/ibc/02-client/keeper/client_test.go | 4 +- x/ibc/02-client/keeper/keeper.go | 4 +- x/ibc/02-client/keeper/keeper_test.go | 6 +- x/ibc/02-client/types/querier.go | 26 +-- x/ibc/03-connection/client/cli/tx.go | 2 +- x/ibc/03-connection/client/rest/rest.go | 54 ++--- x/ibc/03-connection/client/rest/swagger.go | 16 +- x/ibc/03-connection/client/utils/utils.go | 18 +- x/ibc/03-connection/exported/exported.go | 4 +- x/ibc/03-connection/keeper/handshake.go | 12 +- x/ibc/03-connection/keeper/handshake_test.go | 10 +- x/ibc/03-connection/keeper/keeper.go | 7 +- x/ibc/03-connection/keeper/keeper_test.go | 8 +- x/ibc/03-connection/keeper/verify.go | 16 +- x/ibc/03-connection/keeper/verify_test.go | 19 +- x/ibc/03-connection/types/connection.go | 12 +- x/ibc/03-connection/types/connection_test.go | 16 +- x/ibc/03-connection/types/msgs.go | 59 +++--- x/ibc/03-connection/types/msgs_test.go | 20 +- x/ibc/03-connection/types/querier.go | 26 +-- x/ibc/04-channel/alias.go | 12 +- x/ibc/04-channel/client/cli/tx.go | 2 +- x/ibc/04-channel/client/rest/rest.go | 52 ++--- x/ibc/04-channel/client/rest/swagger.go | 24 +-- x/ibc/04-channel/keeper/handshake.go | 10 +- x/ibc/04-channel/keeper/keeper_test.go | 32 +-- x/ibc/04-channel/keeper/packet.go | 8 +- x/ibc/04-channel/keeper/timeout.go | 6 +- x/ibc/04-channel/keeper/timeout_test.go | 8 +- x/ibc/04-channel/types/codec.go | 4 +- x/ibc/04-channel/types/expected_keepers.go | 12 +- x/ibc/04-channel/types/msgs.go | 93 ++++----- x/ibc/04-channel/types/msgs_test.go | 77 ++++---- x/ibc/04-channel/types/querier.go | 38 ++-- x/ibc/07-tendermint/client/rest/swagger.go | 14 +- x/ibc/07-tendermint/misbehaviour.go | 3 +- x/ibc/07-tendermint/misbehaviour_test.go | 14 +- x/ibc/07-tendermint/tendermint_test.go | 4 +- x/ibc/07-tendermint/types/client_state.go | 49 ++--- .../07-tendermint/types/client_state_test.go | 186 +++++++++--------- x/ibc/07-tendermint/types/consensus_state.go | 15 +- .../types/consensus_state_test.go | 12 +- x/ibc/07-tendermint/types/header.go | 4 +- x/ibc/07-tendermint/types/msgs.go | 88 ++++----- x/ibc/07-tendermint/types/tendermint_test.go | 4 +- x/ibc/07-tendermint/update.go | 7 +- x/ibc/07-tendermint/update_test.go | 7 +- x/ibc/20-transfer/handler_test.go | 8 +- x/ibc/20-transfer/keeper/keeper_test.go | 8 +- x/ibc/20-transfer/types/codec.go | 4 +- x/ibc/23-commitment/codec.go | 26 --- .../{types.go => exported/exported.go} | 22 +-- x/ibc/23-commitment/types/codec.go | 27 +++ .../{ => types}/commitment_test.go | 2 +- x/ibc/23-commitment/{ => types}/errors.go | 4 +- x/ibc/23-commitment/{ => types}/merkle.go | 111 +++++------ .../23-commitment/{ => types}/merkle_test.go | 26 +-- x/ibc/23-commitment/verify.go | 18 +- x/ibc/ante/ante_test.go | 8 +- x/ibc/module.go | 4 +- x/ibc/types/mock.go | 22 +-- 65 files changed, 737 insertions(+), 723 deletions(-) delete mode 100644 x/ibc/23-commitment/codec.go rename x/ibc/23-commitment/{types.go => exported/exported.go} (78%) create mode 100644 x/ibc/23-commitment/types/codec.go rename x/ibc/23-commitment/{ => types}/commitment_test.go (97%) rename x/ibc/23-commitment/{ => types}/errors.go (82%) rename x/ibc/23-commitment/{ => types}/merkle.go (56%) rename x/ibc/23-commitment/{ => types}/merkle_test.go (88%) diff --git a/x/ibc/02-client/client/cli/query.go b/x/ibc/02-client/client/cli/query.go index 34c5e58093de..e77f82f4a0c3 100644 --- a/x/ibc/02-client/client/cli/query.go +++ b/x/ibc/02-client/client/cli/query.go @@ -14,7 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) // GetCmdQueryClientStates defines the command to query all the light clients @@ -173,7 +173,7 @@ func GetCmdQueryPath(storeName string, cdc *codec.Codec) *cobra.Command { Short: "Query the commitment path of the running chain", RunE: func(cmd *cobra.Command, args []string) error { ctx := context.NewCLIContext().WithCodec(cdc) - path := commitment.NewPrefix([]byte("ibc")) + path := commitmenttypes.NewMerklePrefix([]byte("ibc")) return ctx.PrintOutput(path) }, } diff --git a/x/ibc/02-client/client/rest/swagger.go b/x/ibc/02-client/client/rest/swagger.go index 7c78a9f4808b..29b8b164eb03 100644 --- a/x/ibc/02-client/client/rest/swagger.go +++ b/x/ibc/02-client/client/rest/swagger.go @@ -3,7 +3,7 @@ package rest import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // nolint @@ -29,7 +29,7 @@ type ( } QueryPath struct { - Height int64 `json:"height"` - Result commitment.Prefix `json:"result"` + Height int64 `json:"height"` + Result commitmentexported.Prefix `json:"result"` } ) diff --git a/x/ibc/02-client/client/utils/utils.go b/x/ibc/02-client/client/utils/utils.go index eb83f1bc9df8..c267978ddd83 100644 --- a/x/ibc/02-client/client/utils/utils.go +++ b/x/ibc/02-client/client/utils/utils.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -149,7 +149,7 @@ func QueryNodeConsensusState(cliCtx context.CLIContext) (ibctmtypes.ConsensusSta state := ibctmtypes.ConsensusState{ Timestamp: commit.Time, - Root: commitment.NewRoot(commit.AppHash), + Root: commitmenttypes.NewMerkleRoot(commit.AppHash), ValidatorSet: tmtypes.NewValidatorSet(validators.Validators), } diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index e5623ed8ddca..996a5343c797 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -10,7 +10,7 @@ import ( evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // ClientState defines the required common functions for light clients. @@ -25,15 +25,15 @@ type ClientState interface { VerifyClientConsensusState( cdc *codec.Codec, height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, consensusState ConsensusState, ) error VerifyConnectionState( cdc *codec.Codec, height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, connectionID string, connectionEnd connectionexported.ConnectionI, consensusState ConsensusState, @@ -41,8 +41,8 @@ type ClientState interface { VerifyChannelState( cdc *codec.Codec, height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, channel channelexported.ChannelI, @@ -50,8 +50,8 @@ type ClientState interface { ) error VerifyPacketCommitment( height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, @@ -60,8 +60,8 @@ type ClientState interface { ) error VerifyPacketAcknowledgement( height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, @@ -70,8 +70,8 @@ type ClientState interface { ) error VerifyPacketAcknowledgementAbsence( height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, @@ -79,8 +79,8 @@ type ClientState interface { ) error VerifyNextSequenceRecv( height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, nextSequenceRecv uint64, @@ -97,7 +97,7 @@ type ConsensusState interface { // GetRoot returns the commitment root of the consensus state, // which is used for key-value pair verification. - GetRoot() commitment.RootI + GetRoot() commitmentexported.Root ValidateBasic() error } diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index adde9062b7d3..31edfeec0f21 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) const ( @@ -149,7 +149,7 @@ func (suite *KeeperTestSuite) TestUpdateClient() { expConsensusState := ibctmtypes.ConsensusState{ Height: uint64(updateHeader.Height), Timestamp: updateHeader.Time, - Root: commitment.NewRoot(updateHeader.AppHash), + Root: commitmenttypes.NewMerkleRoot(updateHeader.AppHash), ValidatorSet: updateHeader.ValidatorSet, } diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index f9b1dbdcfdc9..ef5ab61bf87f 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -137,7 +137,7 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported. consensusState := ibctmtypes.ConsensusState{ Height: height, Timestamp: ctx.BlockTime(), - Root: commitment.NewRoot(histInfo.Header.AppHash), + Root: commitmenttypes.NewMerkleRoot(histInfo.Header.AppHash), ValidatorSet: tmtypes.NewValidatorSet(valSet.ToTmValidators()), } return consensusState, true diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index afeca9bdefa2..19a8d99f2f6b 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -16,7 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" "github.com/cosmos/cosmos-sdk/x/staking" ) @@ -60,7 +60,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.consensusState = ibctmtypes.ConsensusState{ Height: testClientHeight, Timestamp: suite.now, - Root: commitment.NewRoot([]byte("hash")), + Root: commitmenttypes.NewMerkleRoot([]byte("hash")), ValidatorSet: suite.valSet, } @@ -162,7 +162,7 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() { nextState := ibctmtypes.ConsensusState{ Height: testClientHeight + 5, Timestamp: suite.now, - Root: commitment.NewRoot([]byte("next")), + Root: commitmenttypes.NewMerkleRoot([]byte("next")), ValidatorSet: suite.valSet, } diff --git a/x/ibc/02-client/types/querier.go b/x/ibc/02-client/types/querier.go index 31a1b3586006..892349f7104b 100644 --- a/x/ibc/02-client/types/querier.go +++ b/x/ibc/02-client/types/querier.go @@ -6,7 +6,7 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -35,10 +35,10 @@ func NewQueryAllClientsParams(page, limit int) QueryAllClientsParams { // StateResponse defines the client response for a client state query. // It includes the commitment proof and the height of the proof. type StateResponse struct { - ClientState exported.ClientState `json:"client_state" yaml:"client_state"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + ClientState exported.ClientState `json:"client_state" yaml:"client_state"` + Proof commitmenttypes.MerkleProof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitmenttypes.MerklePath `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewClientStateResponse creates a new StateResponse instance. @@ -47,8 +47,8 @@ func NewClientStateResponse( ) StateResponse { return StateResponse{ ClientState: clientState, - Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ibctypes.ClientStatePath(clientID), "/")), + Proof: commitmenttypes.MerkleProof{Proof: proof}, + ProofPath: commitmenttypes.NewMerklePath(strings.Split(ibctypes.ClientStatePath(clientID), "/")), ProofHeight: uint64(height), } } @@ -56,10 +56,10 @@ func NewClientStateResponse( // ConsensusStateResponse defines the client response for a Consensus state query. // It includes the commitment proof and the height of the proof. type ConsensusStateResponse struct { - ConsensusState exported.ConsensusState `json:"consensus_state" yaml:"consensus_state"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + ConsensusState exported.ConsensusState `json:"consensus_state" yaml:"consensus_state"` + Proof commitmenttypes.MerkleProof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitmenttypes.MerklePath `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewConsensusStateResponse creates a new ConsensusStateResponse instance. @@ -68,8 +68,8 @@ func NewConsensusStateResponse( ) ConsensusStateResponse { return ConsensusStateResponse{ ConsensusState: cs, - Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ibctypes.ConsensusStatePath(clientID, uint64(height)), "/")), + Proof: commitmenttypes.MerkleProof{Proof: proof}, + ProofPath: commitmenttypes.NewMerklePath(strings.Split(ibctypes.ConsensusStatePath(clientID, uint64(height)), "/")), ProofHeight: uint64(height), } } diff --git a/x/ibc/03-connection/client/cli/tx.go b/x/ibc/03-connection/client/cli/tx.go index 9a02faa374a9..44caac4bf106 100644 --- a/x/ibc/03-connection/client/cli/tx.go +++ b/x/ibc/03-connection/client/cli/tx.go @@ -13,8 +13,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" ) diff --git a/x/ibc/03-connection/client/rest/rest.go b/x/ibc/03-connection/client/rest/rest.go index ed8e97b69280..a3d3c5613de1 100644 --- a/x/ibc/03-connection/client/rest/rest.go +++ b/x/ibc/03-connection/client/rest/rest.go @@ -5,7 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/types/rest" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) const ( @@ -21,42 +21,42 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) // ConnectionOpenInitReq defines the properties of a connection open init request's body. type ConnectionOpenInitReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ConnectionID string `json:"connection_id" yaml:"connection_id"` - ClientID string `json:"client_id" yaml:"client_id"` - CounterpartyClientID string `json:"counterparty_client_id" yaml:"counterparty_client_id"` - CounterpartyConnectionID string `json:"counterparty_connection_id" yaml:"counterparty_connection_id"` - CounterpartyPrefix commitment.PrefixI `json:"counterparty_prefix" yaml:"counterparty_prefix"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ConnectionID string `json:"connection_id" yaml:"connection_id"` + ClientID string `json:"client_id" yaml:"client_id"` + CounterpartyClientID string `json:"counterparty_client_id" yaml:"counterparty_client_id"` + CounterpartyConnectionID string `json:"counterparty_connection_id" yaml:"counterparty_connection_id"` + CounterpartyPrefix commitmentexported.Prefix `json:"counterparty_prefix" yaml:"counterparty_prefix"` } // ConnectionOpenTryReq defines the properties of a connection open try request's body. type ConnectionOpenTryReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ConnectionID string `json:"connection_id" yaml:"connection_id"` - ClientID string `json:"client_id" yaml:"client_id"` - CounterpartyClientID string `json:"counterparty_client_id" yaml:"counterparty_client_id"` - CounterpartyConnectionID string `json:"counterparty_connection_id" yaml:"counterparty_connection_id"` - CounterpartyPrefix commitment.PrefixI `json:"counterparty_prefix" yaml:"counterparty_prefix"` - CounterpartyVersions []string `json:"counterparty_versions" yaml:"counterparty_versions"` - ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` - ProofConsensus commitment.ProofI `json:"proof_consensus" yaml:"proof_consensus"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` - ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ConnectionID string `json:"connection_id" yaml:"connection_id"` + ClientID string `json:"client_id" yaml:"client_id"` + CounterpartyClientID string `json:"counterparty_client_id" yaml:"counterparty_client_id"` + CounterpartyConnectionID string `json:"counterparty_connection_id" yaml:"counterparty_connection_id"` + CounterpartyPrefix commitmentexported.Prefix `json:"counterparty_prefix" yaml:"counterparty_prefix"` + CounterpartyVersions []string `json:"counterparty_versions" yaml:"counterparty_versions"` + ProofInit commitmentexported.Proof `json:"proof_init" yaml:"proof_init"` + ProofConsensus commitmentexported.Proof `json:"proof_consensus" yaml:"proof_consensus"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` } // ConnectionOpenAckReq defines the properties of a connection open ack request's body. type ConnectionOpenAckReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ProofTry commitment.ProofI `json:"proof_try" yaml:"proof_try"` - ProofConsensus commitment.ProofI `json:"proof_consensus" yaml:"proof_consensus"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` - ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` - Version string `json:"version" yaml:"version"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofTry commitmentexported.Proof `json:"proof_try" yaml:"proof_try"` + ProofConsensus commitmentexported.Proof `json:"proof_consensus" yaml:"proof_consensus"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height" yaml:"consensus_height"` + Version string `json:"version" yaml:"version"` } // ConnectionOpenConfirmReq defines the properties of a connection open confirm request's body. type ConnectionOpenConfirmReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofAck commitmentexported.Proof `json:"proof_ack" yaml:"proof_ack"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` } diff --git a/x/ibc/03-connection/client/rest/swagger.go b/x/ibc/03-connection/client/rest/swagger.go index bc12e73985d3..fd41f9449716 100644 --- a/x/ibc/03-connection/client/rest/swagger.go +++ b/x/ibc/03-connection/client/rest/swagger.go @@ -18,29 +18,29 @@ type ( PostConnectionOpenInit struct { Msgs []types.MsgConnectionOpenInit `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostConnectionOpenTry struct { Msgs []types.MsgConnectionOpenTry `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostConnectionOpenAck struct { Msgs []types.MsgConnectionOpenAck `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostConnectionOpenConfirm struct { Msgs []types.MsgConnectionOpenConfirm `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } ) diff --git a/x/ibc/03-connection/client/utils/utils.go b/x/ibc/03-connection/client/utils/utils.go index 29c52a33be9a..f2cb94beac96 100644 --- a/x/ibc/03-connection/client/utils/utils.go +++ b/x/ibc/03-connection/client/utils/utils.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -91,16 +91,16 @@ func QueryClientConnections( // ParsePrefix unmarshals an cmd input argument from a JSON string to a commitment // Prefix. If the input is not a JSON, it looks for a path to the JSON file. -func ParsePrefix(cdc *codec.Codec, arg string) (commitment.Prefix, error) { - var prefix commitment.Prefix +func ParsePrefix(cdc *codec.Codec, arg string) (commitmenttypes.MerklePrefix, error) { + var prefix commitmenttypes.MerklePrefix if err := cdc.UnmarshalJSON([]byte(arg), &prefix); err != nil { // check for file path if JSON input is not provided contents, err := ioutil.ReadFile(arg) if err != nil { - return commitment.Prefix{}, errors.New("neither JSON input nor path to .json file were provided") + return commitmenttypes.MerklePrefix{}, errors.New("neither JSON input nor path to .json file were provided") } if err := cdc.UnmarshalJSON(contents, &prefix); err != nil { - return commitment.Prefix{}, errors.Wrap(err, "error unmarshalling commitment prefix") + return commitmenttypes.MerklePrefix{}, errors.Wrap(err, "error unmarshalling commitment prefix") } } return prefix, nil @@ -108,16 +108,16 @@ func ParsePrefix(cdc *codec.Codec, arg string) (commitment.Prefix, error) { // ParseProof unmarshals an cmd input argument from a JSON string to a commitment // Proof. If the input is not a JSON, it looks for a path to the JSON file. -func ParseProof(cdc *codec.Codec, arg string) (commitment.Proof, error) { - var proof commitment.Proof +func ParseProof(cdc *codec.Codec, arg string) (commitmenttypes.MerkleProof, error) { + var proof commitmenttypes.MerkleProof if err := cdc.UnmarshalJSON([]byte(arg), &proof); err != nil { // check for file path if JSON input is not provided contents, err := ioutil.ReadFile(arg) if err != nil { - return commitment.Proof{}, errors.New("neither JSON input nor path to .json file were provided") + return commitmenttypes.MerkleProof{}, errors.New("neither JSON input nor path to .json file were provided") } if err := cdc.UnmarshalJSON(contents, &proof); err != nil { - return commitment.Proof{}, errors.Wrap(err, "error unmarshalling commitment proof") + return commitmenttypes.MerkleProof{}, errors.Wrap(err, "error unmarshalling commitment proof") } } return proof, nil diff --git a/x/ibc/03-connection/exported/exported.go b/x/ibc/03-connection/exported/exported.go index a45570c80130..8f1591f2f6e6 100644 --- a/x/ibc/03-connection/exported/exported.go +++ b/x/ibc/03-connection/exported/exported.go @@ -3,7 +3,7 @@ package exported import ( "encoding/json" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // ConnectionI describes the required methods for a connection. @@ -19,7 +19,7 @@ type ConnectionI interface { type CounterpartyI interface { GetClientID() string GetConnectionID() string - GetPrefix() commitment.PrefixI + GetPrefix() commitmentexported.Prefix ValidateBasic() error } diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index e8d0003c6159..5b8592f83daa 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -9,7 +9,7 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -51,8 +51,8 @@ func (k Keeper) ConnOpenTry( counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier clientID string, // clientID of chainA counterpartyVersions []string, // supported versions of chain A - proofInit commitment.ProofI, // proof that chainA stored connectionEnd in state (on ConnOpenInit) - proofConsensus commitment.ProofI, // proof that chainA stored chainB's consensus state at consensus height + proofInit commitmentexported.Proof, // proof that chainA stored connectionEnd in state (on ConnOpenInit) + proofConsensus commitmentexported.Proof, // proof that chainA stored chainB's consensus state at consensus height proofHeight uint64, // height at which relayer constructs proof of A storing connectionEnd in state consensusHeight uint64, // latest height of chain B which chain A has stored in its chain B client ) error { @@ -125,8 +125,8 @@ func (k Keeper) ConnOpenAck( ctx sdk.Context, connectionID string, version string, // version that ChainB chose in ConnOpenTry - proofTry commitment.ProofI, // proof that connectionEnd was added to ChainB state in ConnOpenTry - proofConsensus commitment.ProofI, // proof that chainB has stored ConsensusState of chainA on its client + proofTry commitmentexported.Proof, // proof that connectionEnd was added to ChainB state in ConnOpenTry + proofConsensus commitmentexported.Proof, // proof that chainB has stored ConsensusState of chainA on its client proofHeight uint64, // height that relayer constructed proofTry consensusHeight uint64, // latest height of chainA that chainB has stored on its chainA client ) error { @@ -197,7 +197,7 @@ func (k Keeper) ConnOpenAck( func (k Keeper) ConnOpenConfirm( ctx sdk.Context, connectionID string, - proofAck commitment.ProofI, // proof that connection opened on ChainA during ConnOpenAck + proofAck commitmentexported.Proof, // proof that connection opened on ChainA during ConnOpenAck proofHeight uint64, // height that relayer constructed proofAck ) error { // Retrieve connection diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index e3586b13b5b9..83a2ae0958ef 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -5,7 +5,7 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -57,8 +57,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { ) testCases := []struct { msg string - proofInit commitment.ProofI - proofConsensus commitment.ProofI + proofInit commitmentexported.Proof + proofConsensus commitmentexported.Proof malleate func() expPass bool }{ @@ -151,8 +151,8 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { testCases := []struct { msg string version string - proofTry commitment.ProofI - proofConsensus commitment.ProofI + proofTry commitmentexported.Proof + proofConsensus commitmentexported.Proof malleate func() expPass bool }{ diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index 0ef8d8d77b2d..165e46e93823 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -10,7 +10,8 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -38,8 +39,8 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetCommitmentPrefix returns the IBC connection store prefix as a commitment // Prefix -func (k Keeper) GetCommitmentPrefix() commitment.PrefixI { - return commitment.NewPrefix([]byte(k.storeKey.Name())) +func (k Keeper) GetCommitmentPrefix() commitmentexported.Prefix { + return commitmenttypes.NewMerklePrefix([]byte(k.storeKey.Name())) } // GetConnection returns a connection with a particular identifier diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 36bb2ea36472..2ed104744b71 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -18,7 +18,7 @@ import ( channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/staking" ) @@ -61,7 +61,7 @@ func (suite *KeeperTestSuite) SetupTest() { } // nolint: unused -func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { +func (suite *KeeperTestSuite) queryProof(key []byte) (commitmenttypes.MerkleProof, int64) { res := suite.chainA.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", storeKey), Height: suite.chainA.App.LastBlockHeight(), @@ -69,7 +69,7 @@ func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { Prove: true, }) - proof := commitment.Proof{ + proof := commitmenttypes.MerkleProof{ Proof: res.Proof, } @@ -241,7 +241,7 @@ func (chain *TestChain) updateClient(client *TestChain) { consensusState := ibctmtypes.ConsensusState{ Height: uint64(client.Header.Height), Timestamp: client.Header.Time, - Root: commitment.NewRoot(commitID.Hash), + Root: commitmenttypes.NewMerkleRoot(commitID.Hash), ValidatorSet: client.Vals, } diff --git a/x/ibc/03-connection/keeper/verify.go b/x/ibc/03-connection/keeper/verify.go index 4741cb359c3a..aea829d922d5 100644 --- a/x/ibc/03-connection/keeper/verify.go +++ b/x/ibc/03-connection/keeper/verify.go @@ -7,7 +7,7 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // VerifyClientConsensusState verifies a proof of the consensus state of the @@ -16,7 +16,7 @@ func (k Keeper) VerifyClientConsensusState( ctx sdk.Context, connection exported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, consensusState clientexported.ConsensusState, ) error { clientID := connection.GetClientID() @@ -36,7 +36,7 @@ func (k Keeper) VerifyConnectionState( ctx sdk.Context, connection exported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, connectionID string, connectionEnd exported.ConnectionI, // opposite connection ) error { @@ -67,7 +67,7 @@ func (k Keeper) VerifyChannelState( ctx sdk.Context, connection exported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, channel channelexported.ChannelI, @@ -100,7 +100,7 @@ func (k Keeper) VerifyPacketCommitment( ctx sdk.Context, connection exported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, @@ -134,7 +134,7 @@ func (k Keeper) VerifyPacketAcknowledgement( ctx sdk.Context, connection exported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, @@ -169,7 +169,7 @@ func (k Keeper) VerifyPacketAcknowledgementAbsence( ctx sdk.Context, connection exported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, @@ -202,7 +202,7 @@ func (k Keeper) VerifyNextSequenceRecv( ctx sdk.Context, connection exported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, nextSequenceRecv uint64, diff --git a/x/ibc/03-connection/keeper/verify_test.go b/x/ibc/03-connection/keeper/verify_test.go index 2e5f4f77b6db..39a817a13d49 100644 --- a/x/ibc/03-connection/keeper/verify_test.go +++ b/x/ibc/03-connection/keeper/verify_test.go @@ -6,7 +6,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -32,7 +33,7 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { cases := []struct { msg string connection types.ConnectionEnd - proof commitment.ProofI + proof commitmentexported.Proof malleate func() expPass bool }{ @@ -76,7 +77,7 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { // connectionKey := ibctypes.KeyConnection(testConnectionIDA) cases := []struct { msg string - proof commitment.ProofI + proof commitmentexported.Proof malleate func() expPass bool }{ @@ -113,7 +114,7 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { proofHeight := uint64(suite.chainA.Header.Height) // proof, proofHeight := suite.queryProof(connectionKey) - counterparty := types.NewCounterparty(testClientIDB, testConnectionIDA, commitment.NewPrefix([]byte("ibc"))) + counterparty := types.NewCounterparty(testClientIDB, testConnectionIDA, commitmenttypes.NewMerklePrefix([]byte("ibc"))) connection := types.NewConnectionEnd(exported.UNINITIALIZED, testClientIDA, counterparty, []string{"1.0.0"}) // Ensure chain B can verify connection exists in chain A err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyConnectionState( @@ -133,7 +134,7 @@ func (suite *KeeperTestSuite) TestVerifyChannelState() { // channelKey := ibctypes.KeyChannel(testPort1, testChannel1) cases := []struct { msg string - proof commitment.ProofI + proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool @@ -190,7 +191,7 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { cases := []struct { msg string - proof commitment.ProofI + proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool @@ -245,7 +246,7 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { cases := []struct { msg string - proof commitment.ProofI + proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool @@ -292,7 +293,7 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { cases := []struct { msg string - proof commitment.ProofI + proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool @@ -339,7 +340,7 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { cases := []struct { msg string - proof commitment.ProofI + proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool diff --git a/x/ibc/03-connection/types/connection.go b/x/ibc/03-connection/types/connection.go index 9f0678310dd7..27b5d0d9021b 100644 --- a/x/ibc/03-connection/types/connection.go +++ b/x/ibc/03-connection/types/connection.go @@ -5,7 +5,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -79,13 +79,13 @@ var _ exported.CounterpartyI = Counterparty{} // Counterparty defines the counterparty chain associated with a connection end. type Counterparty struct { - ClientID string `json:"client_id" yaml:"client_id"` - ConnectionID string `json:"connection_id" yaml:"connection_id"` - Prefix commitment.PrefixI `json:"prefix" yaml:"prefix"` + ClientID string `json:"client_id" yaml:"client_id"` + ConnectionID string `json:"connection_id" yaml:"connection_id"` + Prefix commitmentexported.Prefix `json:"prefix" yaml:"prefix"` } // NewCounterparty creates a new Counterparty instance. -func NewCounterparty(clientID, connectionID string, prefix commitment.PrefixI) Counterparty { +func NewCounterparty(clientID, connectionID string, prefix commitmentexported.Prefix) Counterparty { return Counterparty{ ClientID: clientID, ConnectionID: connectionID, @@ -104,7 +104,7 @@ func (c Counterparty) GetConnectionID() string { } // GetPrefix implements the CounterpartyI interface -func (c Counterparty) GetPrefix() commitment.PrefixI { +func (c Counterparty) GetPrefix() commitmentexported.Prefix { return c.Prefix } diff --git a/x/ibc/03-connection/types/connection_test.go b/x/ibc/03-connection/types/connection_test.go index 895eaf45afdb..92605a7ea61e 100644 --- a/x/ibc/03-connection/types/connection_test.go +++ b/x/ibc/03-connection/types/connection_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) func TestConnectionValidateBasic(t *testing.T) { @@ -17,22 +17,22 @@ func TestConnectionValidateBasic(t *testing.T) { }{ { "valid connection", - ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, []string{"1.0.0"}}, + ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []string{"1.0.0"}}, true, }, { "invalid client id", - ConnectionEnd{exported.INIT, "ClientIDTwo", Counterparty{"clientidtwo", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, []string{"1.0.0"}}, + ConnectionEnd{exported.INIT, "ClientIDTwo", Counterparty{"clientidtwo", "connectionidone", commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []string{"1.0.0"}}, false, }, { "empty versions", - ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, nil}, + ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", commitmenttypes.NewMerklePrefix([]byte("prefix"))}, nil}, false, }, { "invalid version", - ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, []string{""}}, + ConnectionEnd{exported.INIT, "clientidone", Counterparty{"clientidtwo", "connectionidone", commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []string{""}}, false, }, { @@ -60,9 +60,9 @@ func TestCounterpartyValidateBasic(t *testing.T) { counterparty Counterparty expPass bool }{ - {"valid counterparty", Counterparty{"clientidone", "connectionidone", commitment.NewPrefix([]byte("prefix"))}, true}, - {"invalid client id", Counterparty{"InvalidClient", "channelidone", commitment.NewPrefix([]byte("prefix"))}, false}, - {"invalid connection id", Counterparty{"clientidone", "InvalidConnection", commitment.NewPrefix([]byte("prefix"))}, false}, + {"valid counterparty", Counterparty{"clientidone", "connectionidone", commitmenttypes.NewMerklePrefix([]byte("prefix"))}, true}, + {"invalid client id", Counterparty{"InvalidClient", "channelidone", commitmenttypes.NewMerklePrefix([]byte("prefix"))}, false}, + {"invalid connection id", Counterparty{"clientidone", "InvalidConnection", commitmenttypes.NewMerklePrefix([]byte("prefix"))}, false}, {"invalid prefix", Counterparty{"clientidone", "connectionidone", nil}, false}, } diff --git a/x/ibc/03-connection/types/msgs.go b/x/ibc/03-connection/types/msgs.go index 673d42080490..9fb96cc3734e 100644 --- a/x/ibc/03-connection/types/msgs.go +++ b/x/ibc/03-connection/types/msgs.go @@ -5,7 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -24,7 +25,7 @@ type MsgConnectionOpenInit struct { // NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance func NewMsgConnectionOpenInit( connectionID, clientID, counterpartyConnectionID, - counterpartyClientID string, counterpartyPrefix commitment.PrefixI, + counterpartyClientID string, counterpartyPrefix commitmentexported.Prefix, signer sdk.AccAddress, ) MsgConnectionOpenInit { counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) @@ -75,22 +76,22 @@ var _ sdk.Msg = MsgConnectionOpenTry{} // MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a connection // on Chain B. type MsgConnectionOpenTry struct { - ConnectionID string `json:"connection_id"` - ClientID string `json:"client_id"` - Counterparty Counterparty `json:"counterparty"` - CounterpartyVersions []string `json:"counterparty_versions"` - ProofInit commitment.ProofI `json:"proof_init"` // proof of the initialization the connection on Chain A: `none -> INIT` - ProofConsensus commitment.ProofI `json:"proof_consensus"` // proof of client consensus state - ProofHeight uint64 `json:"proof_height"` - ConsensusHeight uint64 `json:"consensus_height"` - Signer sdk.AccAddress `json:"signer"` + ConnectionID string `json:"connection_id"` + ClientID string `json:"client_id"` + Counterparty Counterparty `json:"counterparty"` + CounterpartyVersions []string `json:"counterparty_versions"` + ProofInit commitmentexported.Proof `json:"proof_init"` // proof of the initialization the connection on Chain A: `none -> INIT` + ProofConsensus commitmentexported.Proof `json:"proof_consensus"` // proof of client consensus state + ProofHeight uint64 `json:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height"` + Signer sdk.AccAddress `json:"signer"` } // NewMsgConnectionOpenTry creates a new MsgConnectionOpenTry instance func NewMsgConnectionOpenTry( connectionID, clientID, counterpartyConnectionID, - counterpartyClientID string, counterpartyPrefix commitment.PrefixI, - counterpartyVersions []string, proofInit, proofConsensus commitment.ProofI, + counterpartyClientID string, counterpartyPrefix commitmentexported.Prefix, + counterpartyVersions []string, proofInit, proofConsensus commitmentexported.Proof, proofHeight, consensusHeight uint64, signer sdk.AccAddress, ) MsgConnectionOpenTry { counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) @@ -134,7 +135,7 @@ func (msg MsgConnectionOpenTry) ValidateBasic() error { } } if msg.ProofInit == nil || msg.ProofConsensus == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.ProofInit.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof init cannot be nil") @@ -169,18 +170,18 @@ var _ sdk.Msg = MsgConnectionOpenAck{} // MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to acknowledge // the change of connection state to TRYOPEN on Chain B. type MsgConnectionOpenAck struct { - ConnectionID string `json:"connection_id"` - ProofTry commitment.ProofI `json:"proof_try"` // proof for the change of the connection state on Chain B: `none -> TRYOPEN` - ProofConsensus commitment.ProofI `json:"proof_consensus"` // proof of client consensus state - ProofHeight uint64 `json:"proof_height"` - ConsensusHeight uint64 `json:"consensus_height"` - Version string `json:"version"` - Signer sdk.AccAddress `json:"signer"` + ConnectionID string `json:"connection_id"` + ProofTry commitmentexported.Proof `json:"proof_try"` // proof for the change of the connection state on Chain B: `none -> TRYOPEN` + ProofConsensus commitmentexported.Proof `json:"proof_consensus"` // proof of client consensus state + ProofHeight uint64 `json:"proof_height"` + ConsensusHeight uint64 `json:"consensus_height"` + Version string `json:"version"` + Signer sdk.AccAddress `json:"signer"` } // NewMsgConnectionOpenAck creates a new MsgConnectionOpenAck instance func NewMsgConnectionOpenAck( - connectionID string, proofTry, proofConsensus commitment.ProofI, + connectionID string, proofTry, proofConsensus commitmentexported.Proof, proofHeight, consensusHeight uint64, version string, signer sdk.AccAddress, ) MsgConnectionOpenAck { @@ -214,7 +215,7 @@ func (msg MsgConnectionOpenAck) ValidateBasic() error { return sdkerrors.Wrap(ibctypes.ErrInvalidVersion, "version can't be blank") } if msg.ProofTry == nil || msg.ProofConsensus == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.ProofTry.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof try cannot be nil") @@ -249,15 +250,15 @@ var _ sdk.Msg = MsgConnectionOpenConfirm{} // MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to acknowledge // the change of connection state to OPEN on Chain A. type MsgConnectionOpenConfirm struct { - ConnectionID string `json:"connection_id"` - ProofAck commitment.ProofI `json:"proof_ack"` // proof for the change of the connection state on Chain A: `INIT -> OPEN` - ProofHeight uint64 `json:"proof_height"` - Signer sdk.AccAddress `json:"signer"` + ConnectionID string `json:"connection_id"` + ProofAck commitmentexported.Proof `json:"proof_ack"` // proof for the change of the connection state on Chain A: `INIT -> OPEN` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` } // NewMsgConnectionOpenConfirm creates a new MsgConnectionOpenConfirm instance func NewMsgConnectionOpenConfirm( - connectionID string, proofAck commitment.ProofI, proofHeight uint64, + connectionID string, proofAck commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress, ) MsgConnectionOpenConfirm { return MsgConnectionOpenConfirm{ @@ -284,7 +285,7 @@ func (msg MsgConnectionOpenConfirm) ValidateBasic() error { return sdkerrors.Wrap(err, "invalid connection ID") } if msg.ProofAck == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.ProofAck.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof ack cannot be nil") diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go index 8bca120769ba..26c88868837f 100644 --- a/x/ibc/03-connection/types/msgs_test.go +++ b/x/ibc/03-connection/types/msgs_test.go @@ -13,13 +13,13 @@ import ( "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) type MsgTestSuite struct { suite.Suite - proof commitment.Proof + proof commitmenttypes.MerkleProof } func (suite *MsgTestSuite) SetupTest() { @@ -40,7 +40,7 @@ func (suite *MsgTestSuite) SetupTest() { Prove: true, }) - suite.proof = commitment.Proof{Proof: res.Proof} + suite.proof = commitmenttypes.MerkleProof{Proof: res.Proof} } func TestMsgTestSuite(t *testing.T) { @@ -48,7 +48,7 @@ func TestMsgTestSuite(t *testing.T) { } func (suite *MsgTestSuite) TestNewMsgConnectionOpenInit() { - prefix := commitment.NewPrefix([]byte("storePrefixKey")) + prefix := commitmenttypes.NewMerklePrefix([]byte("storePrefixKey")) signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenInit{ @@ -86,7 +86,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenInit() { } func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { - prefix := commitment.NewPrefix([]byte("storePrefixKey")) + prefix := commitmenttypes.NewMerklePrefix([]byte("storePrefixKey")) signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") testMsgs := []MsgConnectionOpenTry{ @@ -97,9 +97,9 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", nil, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, signer), NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{}, suite.proof, suite.proof, 10, 10, signer), NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, nil, suite.proof, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitment.Proof{Proof: nil}, suite.proof, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, commitmenttypes.MerkleProof{Proof: nil}, suite.proof, 10, 10, signer), NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, nil, 10, 10, signer), - NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, commitment.Proof{Proof: nil}, 10, 10, signer), + NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, commitmenttypes.MerkleProof{Proof: nil}, 10, 10, signer), NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 0, 10, signer), NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 0, signer), NewMsgConnectionOpenTry("ibcconntest", "clienttotesta", "connectiontotest", "clienttotest", prefix, []string{"1.0.0"}, suite.proof, suite.proof, 10, 10, nil), @@ -143,9 +143,9 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { testMsgs := []MsgConnectionOpenAck{ NewMsgConnectionOpenAck("test/conn1", suite.proof, suite.proof, 10, 10, "1.0.0", signer), NewMsgConnectionOpenAck("ibcconntest", nil, suite.proof, 10, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", commitment.Proof{Proof: nil}, suite.proof, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", commitmenttypes.MerkleProof{Proof: nil}, suite.proof, 10, 10, "1.0.0", signer), NewMsgConnectionOpenAck("ibcconntest", suite.proof, nil, 10, 10, "1.0.0", signer), - NewMsgConnectionOpenAck("ibcconntest", suite.proof, commitment.Proof{Proof: nil}, 10, 10, "1.0.0", signer), + NewMsgConnectionOpenAck("ibcconntest", suite.proof, commitmenttypes.MerkleProof{Proof: nil}, 10, 10, "1.0.0", signer), NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 0, 10, "1.0.0", signer), NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 0, "1.0.0", signer), NewMsgConnectionOpenAck("ibcconntest", suite.proof, suite.proof, 10, 10, "", signer), @@ -185,7 +185,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { testMsgs := []MsgConnectionOpenConfirm{ NewMsgConnectionOpenConfirm("test/conn1", suite.proof, 10, signer), NewMsgConnectionOpenConfirm("ibcconntest", nil, 10, signer), - NewMsgConnectionOpenConfirm("ibcconntest", commitment.Proof{Proof: nil}, 10, signer), + NewMsgConnectionOpenConfirm("ibcconntest", commitmenttypes.MerkleProof{Proof: nil}, 10, signer), NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 0, signer), NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, nil), NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, 10, signer), diff --git a/x/ibc/03-connection/types/querier.go b/x/ibc/03-connection/types/querier.go index 459082a7f0c0..48db30da8f95 100644 --- a/x/ibc/03-connection/types/querier.go +++ b/x/ibc/03-connection/types/querier.go @@ -5,7 +5,7 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -18,10 +18,10 @@ const ( // ConnectionResponse defines the client query response for a connection which // also includes a proof and the height from which the proof was retrieved. type ConnectionResponse struct { - Connection ConnectionEnd `json:"connection" yaml:"connection"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + Connection ConnectionEnd `json:"connection" yaml:"connection"` + Proof commitmenttypes.MerkleProof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitmenttypes.MerklePath `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewConnectionResponse creates a new ConnectionResponse instance @@ -30,8 +30,8 @@ func NewConnectionResponse( ) ConnectionResponse { return ConnectionResponse{ Connection: connection, - Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ibctypes.ConnectionPath(connectionID), "/")), + Proof: commitmenttypes.MerkleProof{Proof: proof}, + ProofPath: commitmenttypes.NewMerklePath(strings.Split(ibctypes.ConnectionPath(connectionID), "/")), ProofHeight: uint64(height), } } @@ -55,10 +55,10 @@ func NewQueryAllConnectionsParams(page, limit int) QueryAllConnectionsParams { // connection paths which also includes a proof and the height from which the // proof was retrieved. type ClientConnectionsResponse struct { - ConnectionPaths []string `json:"connection_paths" yaml:"connection_paths"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + ConnectionPaths []string `json:"connection_paths" yaml:"connection_paths"` + Proof commitmenttypes.MerkleProof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitmenttypes.MerklePath `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewClientConnectionsResponse creates a new ConnectionPaths instance @@ -67,8 +67,8 @@ func NewClientConnectionsResponse( ) ClientConnectionsResponse { return ClientConnectionsResponse{ ConnectionPaths: connectionPaths, - Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ibctypes.ClientConnectionsPath(clientID), "/")), + Proof: commitmenttypes.MerkleProof{Proof: proof}, + ProofPath: commitmenttypes.NewMerklePath(strings.Split(ibctypes.ClientConnectionsPath(clientID), "/")), ProofHeight: uint64(height), } } diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index c24c077d9c60..dc4073212266 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -12,12 +12,12 @@ import ( ) const ( - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - QueryAllChannels = types.QueryAllChannels - QueryChannel = types.QueryChannel + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryAllChannels = types.QueryAllChannels + QueryChannel = types.QueryChannel ) var ( diff --git a/x/ibc/04-channel/client/cli/tx.go b/x/ibc/04-channel/client/cli/tx.go index 3241eb780f39..16183ae2ec04 100644 --- a/x/ibc/04-channel/client/cli/tx.go +++ b/x/ibc/04-channel/client/cli/tx.go @@ -11,8 +11,8 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" connectionutils "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/client/utils" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" diff --git a/x/ibc/04-channel/client/rest/rest.go b/x/ibc/04-channel/client/rest/rest.go index 7ee17790ea88..2d65fc2d5817 100644 --- a/x/ibc/04-channel/client/rest/rest.go +++ b/x/ibc/04-channel/client/rest/rest.go @@ -7,7 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) const ( @@ -35,32 +35,32 @@ type ChannelOpenInitReq struct { // ChannelOpenTryReq defines the properties of a channel open try request's body. type ChannelOpenTryReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - PortID string `json:"port_id" yaml:"port_id"` - ChannelID string `json:"channel_id" yaml:"channel_id"` - Version string `json:"version" yaml:"version"` - ChannelOrder exported.Order `json:"channel_order" yaml:"channel_order"` - ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` - CounterpartyPortID string `json:"counterparty_port_id" yaml:"counterparty_port_id"` - CounterpartyChannelID string `json:"counterparty_channel_id" yaml:"counterparty_channel_id"` - CounterpartyVersion string `json:"counterparty_version" yaml:"counterparty_version"` - ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + PortID string `json:"port_id" yaml:"port_id"` + ChannelID string `json:"channel_id" yaml:"channel_id"` + Version string `json:"version" yaml:"version"` + ChannelOrder exported.Order `json:"channel_order" yaml:"channel_order"` + ConnectionHops []string `json:"connection_hops" yaml:"connection_hops"` + CounterpartyPortID string `json:"counterparty_port_id" yaml:"counterparty_port_id"` + CounterpartyChannelID string `json:"counterparty_channel_id" yaml:"counterparty_channel_id"` + CounterpartyVersion string `json:"counterparty_version" yaml:"counterparty_version"` + ProofInit commitmentexported.Proof `json:"proof_init" yaml:"proof_init"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` } // ChannelOpenAckReq defines the properties of a channel open ack request's body. type ChannelOpenAckReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - CounterpartyVersion string `json:"counterparty_version" yaml:"counterparty_version"` - ProofTry commitment.ProofI `json:"proof_try" yaml:"proof_try"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + CounterpartyVersion string `json:"counterparty_version" yaml:"counterparty_version"` + ProofTry commitmentexported.Proof `json:"proof_try" yaml:"proof_try"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` } // ChannelOpenConfirmReq defines the properties of a channel open confirm request's body. type ChannelOpenConfirmReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ProofAck commitment.ProofI `json:"proof_ack" yaml:"proof_ack"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofAck commitmentexported.Proof `json:"proof_ack" yaml:"proof_ack"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` } // ConnectionOpenInitReq defines the properties of a channel close init request's body. @@ -70,15 +70,15 @@ type ChannelCloseInitReq struct { // ChannelCloseConfirmReq defines the properties of a channel close confirm request's body. type ChannelCloseConfirmReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - ProofInit commitment.ProofI `json:"proof_init" yaml:"proof_init"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + ProofInit commitmentexported.Proof `json:"proof_init" yaml:"proof_init"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` } // RecvPacketReq defines the properties of a receive packet request's body. type RecvPacketReq struct { - BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` - Packet types.Packet `json:"packet" yaml:"packet"` - Proofs commitment.ProofI `json:"proofs" yaml:"proofs"` - Height uint64 `json:"height" yaml:"height"` + BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` + Packet types.Packet `json:"packet" yaml:"packet"` + Proofs commitmentexported.Proof `json:"proofs" yaml:"proofs"` + Height uint64 `json:"height" yaml:"height"` } diff --git a/x/ibc/04-channel/client/rest/swagger.go b/x/ibc/04-channel/client/rest/swagger.go index 5f6dc5821468..04d011f2cb63 100644 --- a/x/ibc/04-channel/client/rest/swagger.go +++ b/x/ibc/04-channel/client/rest/swagger.go @@ -13,43 +13,43 @@ type ( PostChannelOpenInit struct { Msgs []types.MsgChannelOpenInit `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelOpenTry struct { Msgs []types.MsgChannelOpenTry `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelOpenAck struct { Msgs []types.MsgChannelOpenAck `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelOpenConfirm struct { Msgs []types.MsgChannelOpenConfirm `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelCloseInit struct { Msgs []types.MsgChannelCloseInit `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostChannelCloseConfirm struct { Msgs []types.MsgChannelCloseConfirm `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } ) diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index 40bfb79e90d1..0b434d2ea650 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -8,7 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // CounterpartyHops returns the connection hops of the counterparty channel. @@ -78,7 +78,7 @@ func (k Keeper) ChanOpenTry( counterparty types.Counterparty, version, counterpartyVersion string, - proofInit commitment.ProofI, + proofInit commitmentexported.Proof, proofHeight uint64, ) error { // channel identifier and connection hop length checked on msg.ValidateBasic() @@ -154,7 +154,7 @@ func (k Keeper) ChanOpenAck( portID, channelID, counterpartyVersion string, - proofTry commitment.ProofI, + proofTry commitmentexported.Proof, proofHeight uint64, ) error { channel, found := k.GetChannel(ctx, portID, channelID) @@ -221,7 +221,7 @@ func (k Keeper) ChanOpenConfirm( ctx sdk.Context, portID, channelID string, - proofAck commitment.ProofI, + proofAck commitmentexported.Proof, proofHeight uint64, ) error { channel, found := k.GetChannel(ctx, portID, channelID) @@ -341,7 +341,7 @@ func (k Keeper) ChanCloseConfirm( ctx sdk.Context, portID, channelID string, - proofInit commitment.ProofI, + proofInit commitmentexported.Proof, proofHeight uint64, ) error { // TODO: blocked by #5542 diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index e3c42527f015..c65d32dab4c4 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -19,10 +19,10 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - "github.com/cosmos/cosmos-sdk/x/staking" - - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" + "github.com/cosmos/cosmos-sdk/x/staking" ) // define constants used for testing @@ -207,7 +207,7 @@ func commitNBlocks(chain *TestChain, n int) { } // nolint: unused -func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { +func (suite *KeeperTestSuite) queryProof(key []byte) (commitmenttypes.MerkleProof, int64) { res := suite.chainB.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), Height: suite.chainB.App.LastBlockHeight(), @@ -215,7 +215,7 @@ func (suite *KeeperTestSuite) queryProof(key []byte) (commitment.Proof, int64) { Prove: true, }) - proof := commitment.Proof{ + proof := commitmenttypes.MerkleProof{ Proof: res.Proof, } @@ -341,7 +341,7 @@ func (chain *TestChain) updateClient(client *TestChain) { consensusState := ibctmtypes.ConsensusState{ Height: uint64(client.Header.Height), Timestamp: client.Header.Time, - Root: commitment.NewRoot(commitID.Hash), + Root: commitmenttypes.NewMerkleRoot(commitID.Hash), ValidatorSet: client.Vals, } @@ -403,8 +403,8 @@ func nextHeader(chain *TestChain) ibctmtypes.Header { // TODO: fix tests and replace for real proofs var ( - _ commitment.ProofI = validProof{} - _ commitment.ProofI = invalidProof{} + _ commitmentexported.Proof = validProof{} + _ commitmentexported.Proof = invalidProof{} ) type ( @@ -412,16 +412,16 @@ type ( invalidProof struct{} ) -func (validProof) GetCommitmentType() commitment.Type { - return commitment.Merkle +func (validProof) GetCommitmentType() commitmentexported.Type { + return commitmentexported.Merkle } func (validProof) VerifyMembership( - root commitment.RootI, path commitment.PathI, value []byte) error { + root commitmentexported.Root, path commitmentexported.Path, value []byte) error { return nil } -func (validProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { +func (validProof) VerifyNonMembership(root commitmentexported.Root, path commitmentexported.Path) error { return nil } @@ -433,16 +433,16 @@ func (validProof) IsEmpty() bool { return false } -func (invalidProof) GetCommitmentType() commitment.Type { - return commitment.Merkle +func (invalidProof) GetCommitmentType() commitmentexported.Type { + return commitmentexported.Merkle } func (invalidProof) VerifyMembership( - root commitment.RootI, path commitment.PathI, value []byte) error { + root commitmentexported.Root, path commitmentexported.Path, value []byte) error { return errors.New("proof failed") } -func (invalidProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { +func (invalidProof) VerifyNonMembership(root commitmentexported.Root, path commitmentexported.Path) error { return errors.New("proof failed") } diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 614da9d0ebcf..9630cedfd09f 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -11,7 +11,7 @@ import ( connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // SendPacket is called by a module in order to send an IBC packet on a channel @@ -111,7 +111,7 @@ func (k Keeper) SendPacket( func (k Keeper) RecvPacket( ctx sdk.Context, packet exported.PacketI, - proof commitment.ProofI, + proof commitmentexported.Proof, proofHeight uint64, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) @@ -232,7 +232,7 @@ func (k Keeper) AcknowledgePacket( ctx sdk.Context, packet exported.PacketI, acknowledgement exported.PacketAcknowledgementI, - proof commitment.ProofI, + proof commitmentexported.Proof, proofHeight uint64, ) (exported.PacketI, error) { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) @@ -307,7 +307,7 @@ func (k Keeper) AcknowledgePacket( func (k Keeper) CleanupPacket( ctx sdk.Context, packet exported.PacketI, - proof commitment.ProofI, + proof commitmentexported.Proof, proofHeight, nextSequenceRecv uint64, acknowledgement []byte, diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index 1989722130b2..ff2111675024 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -8,7 +8,7 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // TimeoutPacket is called by a module which originally attempted to send a @@ -19,7 +19,7 @@ import ( func (k Keeper) TimeoutPacket( ctx sdk.Context, packet exported.PacketI, - proof commitment.ProofI, + proof commitmentexported.Proof, proofHeight, nextSequenceRecv uint64, ) (exported.PacketI, error) { @@ -135,7 +135,7 @@ func (k Keeper) TimeoutOnClose( ctx sdk.Context, packet types.Packet, proof, - proofClosed commitment.ProofI, + proofClosed commitmentexported.Proof, proofHeight, nextSequenceRecv uint64, ) (exported.PacketI, error) { diff --git a/x/ibc/04-channel/keeper/timeout_test.go b/x/ibc/04-channel/keeper/timeout_test.go index 8991b7a5952f..917b80adbb6a 100644 --- a/x/ibc/04-channel/keeper/timeout_test.go +++ b/x/ibc/04-channel/keeper/timeout_test.go @@ -6,7 +6,7 @@ import ( connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -135,9 +135,9 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { var ( packet types.Packet nextSeqRecv uint64 - proofHeight uint64 = 1 - proof commitment.ProofI = ibctypes.InvalidProof{} - proofClosed commitment.ProofI = ibctypes.InvalidProof{} + proofHeight uint64 = 1 + proof commitmentexported.Proof = ibctypes.InvalidProof{} + proofClosed commitmentexported.Proof = ibctypes.InvalidProof{} ) testCases := []testCase{ diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index e8bb91bf33be..ca64d49d2851 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -4,7 +4,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) // SubModuleCdc defines the IBC channel codec. @@ -12,7 +12,7 @@ var SubModuleCdc *codec.Codec func init() { SubModuleCdc = codec.New() - commitment.RegisterCodec(SubModuleCdc) + commitmenttypes.RegisterCodec(SubModuleCdc) client.RegisterCodec(SubModuleCdc) RegisterCodec(SubModuleCdc) } diff --git a/x/ibc/04-channel/types/expected_keepers.go b/x/ibc/04-channel/types/expected_keepers.go index c63fa9a9fe80..26c6ad1547a4 100644 --- a/x/ibc/04-channel/types/expected_keepers.go +++ b/x/ibc/04-channel/types/expected_keepers.go @@ -6,7 +6,7 @@ import ( connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // ClientKeeper expected account IBC client keeper @@ -21,7 +21,7 @@ type ConnectionKeeper interface { ctx sdk.Context, connection connectionexported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, channel exported.ChannelI, @@ -30,7 +30,7 @@ type ConnectionKeeper interface { ctx sdk.Context, connection connectionexported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, @@ -40,7 +40,7 @@ type ConnectionKeeper interface { ctx sdk.Context, connection connectionexported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, @@ -50,7 +50,7 @@ type ConnectionKeeper interface { ctx sdk.Context, connection connectionexported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, @@ -59,7 +59,7 @@ type ConnectionKeeper interface { ctx sdk.Context, connection connectionexported.ConnectionI, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, portID, channelID string, nextSequenceRecv uint64, diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index 3f52db670f97..6797e942f57b 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -6,7 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -70,20 +71,20 @@ func (msg MsgChannelOpenInit) GetSigners() []sdk.AccAddress { var _ sdk.Msg = MsgChannelOpenTry{} type MsgChannelOpenTry struct { - PortID string `json:"port_id"` - ChannelID string `json:"channel_id"` - Channel Channel `json:"channel"` - CounterpartyVersion string `json:"counterparty_version"` - ProofInit commitment.ProofI `json:"proof_init"` - ProofHeight uint64 `json:"proof_height"` - Signer sdk.AccAddress `json:"signer"` + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + Channel Channel `json:"channel"` + CounterpartyVersion string `json:"counterparty_version"` + ProofInit commitmentexported.Proof `json:"proof_init"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` } // NewMsgChannelOpenTry creates a new MsgChannelOpenTry instance func NewMsgChannelOpenTry( portID, channelID, version string, channelOrder exported.Order, connectionHops []string, counterpartyPortID, counterpartyChannelID, counterpartyVersion string, - proofInit commitment.ProofI, proofHeight uint64, signer sdk.AccAddress, + proofInit commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress, ) MsgChannelOpenTry { counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) channel := NewChannel(exported.INIT, channelOrder, counterparty, connectionHops, version) @@ -120,7 +121,7 @@ func (msg MsgChannelOpenTry) ValidateBasic() error { return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty version cannot be blank") } if msg.ProofInit == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.ProofInit.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof init cannot be nil") @@ -145,17 +146,17 @@ func (msg MsgChannelOpenTry) GetSigners() []sdk.AccAddress { var _ sdk.Msg = MsgChannelOpenAck{} type MsgChannelOpenAck struct { - PortID string `json:"port_id"` - ChannelID string `json:"channel_id"` - CounterpartyVersion string `json:"counterparty_version"` - ProofTry commitment.ProofI `json:"proof_try"` - ProofHeight uint64 `json:"proof_height"` - Signer sdk.AccAddress `json:"signer"` + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + CounterpartyVersion string `json:"counterparty_version"` + ProofTry commitmentexported.Proof `json:"proof_try"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` } // NewMsgChannelOpenAck creates a new MsgChannelOpenAck instance func NewMsgChannelOpenAck( - portID, channelID string, cpv string, proofTry commitment.ProofI, proofHeight uint64, + portID, channelID string, cpv string, proofTry commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress, ) MsgChannelOpenAck { return MsgChannelOpenAck{ @@ -190,7 +191,7 @@ func (msg MsgChannelOpenAck) ValidateBasic() error { return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty version cannot be blank") } if msg.ProofTry == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.ProofTry.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof try cannot be nil") @@ -215,16 +216,16 @@ func (msg MsgChannelOpenAck) GetSigners() []sdk.AccAddress { var _ sdk.Msg = MsgChannelOpenConfirm{} type MsgChannelOpenConfirm struct { - PortID string `json:"port_id"` - ChannelID string `json:"channel_id"` - ProofAck commitment.ProofI `json:"proof_ack"` - ProofHeight uint64 `json:"proof_height"` - Signer sdk.AccAddress `json:"signer"` + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + ProofAck commitmentexported.Proof `json:"proof_ack"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` } // NewMsgChannelOpenConfirm creates a new MsgChannelOpenConfirm instance func NewMsgChannelOpenConfirm( - portID, channelID string, proofAck commitment.ProofI, proofHeight uint64, + portID, channelID string, proofAck commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress, ) MsgChannelOpenConfirm { return MsgChannelOpenConfirm{ @@ -255,7 +256,7 @@ func (msg MsgChannelOpenConfirm) ValidateBasic() error { return sdkerrors.Wrap(err, "invalid channel ID") } if msg.ProofAck == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.ProofAck.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof ack cannot be nil") @@ -329,16 +330,16 @@ func (msg MsgChannelCloseInit) GetSigners() []sdk.AccAddress { var _ sdk.Msg = MsgChannelCloseConfirm{} type MsgChannelCloseConfirm struct { - PortID string `json:"port_id"` - ChannelID string `json:"channel_id"` - ProofInit commitment.ProofI `json:"proof_init"` - ProofHeight uint64 `json:"proof_height"` - Signer sdk.AccAddress `json:"signer"` + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` + ProofInit commitmentexported.Proof `json:"proof_init"` + ProofHeight uint64 `json:"proof_height"` + Signer sdk.AccAddress `json:"signer"` } // NewMsgChannelCloseConfirm creates a new MsgChannelCloseConfirm instance func NewMsgChannelCloseConfirm( - portID, channelID string, proofInit commitment.ProofI, proofHeight uint64, + portID, channelID string, proofInit commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress, ) MsgChannelCloseConfirm { return MsgChannelCloseConfirm{ @@ -369,7 +370,7 @@ func (msg MsgChannelCloseConfirm) ValidateBasic() error { return sdkerrors.Wrap(err, "invalid channel ID") } if msg.ProofInit == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.ProofInit.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof init cannot be nil") @@ -394,15 +395,15 @@ func (msg MsgChannelCloseConfirm) GetSigners() []sdk.AccAddress { // MsgPacket receives incoming IBC packet type MsgPacket struct { Packet `json:"packet" yaml:"packet"` - Proof commitment.ProofI `json:"proof" yaml:"proof"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` - Signer sdk.AccAddress `json:"signer" yaml:"signer"` + Proof commitmentexported.Proof `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` } var _ sdk.Msg = MsgPacket{} // NewMsgPacket constructs new MsgPacket -func NewMsgPacket(packet Packet, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgPacket { +func NewMsgPacket(packet Packet, proof commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress) MsgPacket { return MsgPacket{ Packet: packet, Proof: proof, @@ -419,7 +420,7 @@ func (msg MsgPacket) Route() string { // ValidateBasic implements sdk.Msg func (msg MsgPacket) ValidateBasic() error { if msg.Proof == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.Proof.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof ack cannot be nil") @@ -449,14 +450,14 @@ var _ sdk.Msg = MsgTimeout{} // MsgTimeout receives timed-out packet type MsgTimeout struct { Packet `json:"packet" yaml:"packet"` - NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"` - Proof commitment.ProofI `json:"proof" yaml:"proof"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` - Signer sdk.AccAddress `json:"signer" yaml:"signer"` + NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"` + Proof commitmentexported.Proof `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` } // NewMsgTimeout constructs new MsgTimeout -func NewMsgTimeout(packet Packet, nextSequenceRecv uint64, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgTimeout { +func NewMsgTimeout(packet Packet, nextSequenceRecv uint64, proof commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress) MsgTimeout { return MsgTimeout{ Packet: packet, NextSequenceRecv: nextSequenceRecv, @@ -474,7 +475,7 @@ func (msg MsgTimeout) Route() string { // ValidateBasic implements sdk.Msg func (msg MsgTimeout) ValidateBasic() error { if msg.Proof == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.Proof.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof ack cannot be nil") @@ -505,13 +506,13 @@ var _ sdk.Msg = MsgAcknowledgement{} type MsgAcknowledgement struct { Packet `json:"packet" yaml:"packet"` Acknowledgement exported.PacketAcknowledgementI `json:"acknowledgement" yaml:"acknowledgement"` - Proof commitment.ProofI `json:"proof" yaml:"proof"` + Proof commitmentexported.Proof `json:"proof" yaml:"proof"` ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` Signer sdk.AccAddress `json:"signer" yaml:"signer"` } // NewMsgAcknowledgement constructs a new MsgAcknowledgement -func NewMsgAcknowledgement(packet Packet, ack exported.PacketAcknowledgementI, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement { +func NewMsgAcknowledgement(packet Packet, ack exported.PacketAcknowledgementI, proof commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement { return MsgAcknowledgement{ Packet: packet, Acknowledgement: ack, @@ -529,7 +530,7 @@ func (msg MsgAcknowledgement) Route() string { // ValidateBasic implements sdk.Msg func (msg MsgAcknowledgement) ValidateBasic() error { if msg.Proof == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "cannot submit an empty proof") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if err := msg.Proof.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof ack cannot be nil") diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index f071b7a17fcb..197d5231cac3 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -17,7 +17,8 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) // define constants used for testing @@ -42,7 +43,7 @@ var ( invalidShortConnHops = []string{invalidShortConnection} invalidLongConnHops = []string{invalidLongConnection} - proof = commitment.Proof{Proof: &merkle.Proof{}} + proof = commitmenttypes.MerkleProof{Proof: &merkle.Proof{}} addr = sdk.AccAddress("testaddr") ) @@ -50,7 +51,7 @@ var ( type MsgTestSuite struct { suite.Suite - proof commitment.Proof + proof commitmenttypes.MerkleProof } func (suite *MsgTestSuite) SetupTest() { @@ -71,7 +72,7 @@ func (suite *MsgTestSuite) SetupTest() { Prove: true, }) - suite.proof = commitment.Proof{Proof: res.Proof} + suite.proof = commitmenttypes.MerkleProof{Proof: res.Proof} } func TestMsgTestSuite(t *testing.T) { @@ -191,17 +192,17 @@ func (suite *MsgTestSuite) TestMsgChannelOpenTry() { // TestMsgChannelOpenAck tests ValidateBasic for MsgChannelOpenAck func (suite *MsgTestSuite) TestMsgChannelOpenAck() { testMsgs := []MsgChannelOpenAck{ - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", suite.proof, 1, addr), // valid msg - NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", suite.proof, 1, addr), // too short port id - NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", suite.proof, 1, addr), // too long port id - NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", suite.proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenAck("testportid", invalidShortChannel, "1.0", suite.proof, 1, addr), // too short channel id - NewMsgChannelOpenAck("testportid", invalidLongChannel, "1.0", suite.proof, 1, addr), // too long channel id - NewMsgChannelOpenAck("testportid", invalidChannel, "1.0", suite.proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenAck("testportid", "testchannel", "", suite.proof, 1, addr), // empty counterparty version - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", nil, 1, addr), // empty proof - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", commitment.Proof{Proof: nil}, 1, addr), // empty proof - NewMsgChannelOpenAck("testportid", "testchannel", "1.0", suite.proof, 0, addr), // proof height is zero + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", suite.proof, 1, addr), // valid msg + NewMsgChannelOpenAck(invalidShortPort, "testchannel", "1.0", suite.proof, 1, addr), // too short port id + NewMsgChannelOpenAck(invalidLongPort, "testchannel", "1.0", suite.proof, 1, addr), // too long port id + NewMsgChannelOpenAck(invalidPort, "testchannel", "1.0", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenAck("testportid", invalidShortChannel, "1.0", suite.proof, 1, addr), // too short channel id + NewMsgChannelOpenAck("testportid", invalidLongChannel, "1.0", suite.proof, 1, addr), // too long channel id + NewMsgChannelOpenAck("testportid", invalidChannel, "1.0", suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenAck("testportid", "testchannel", "", suite.proof, 1, addr), // empty counterparty version + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", nil, 1, addr), // empty proof + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", commitmenttypes.MerkleProof{Proof: nil}, 1, addr), // empty proof + NewMsgChannelOpenAck("testportid", "testchannel", "1.0", suite.proof, 0, addr), // proof height is zero } testCases := []struct { @@ -235,16 +236,16 @@ func (suite *MsgTestSuite) TestMsgChannelOpenAck() { // TestMsgChannelOpenConfirm tests ValidateBasic for MsgChannelOpenConfirm func (suite *MsgTestSuite) TestMsgChannelOpenConfirm() { testMsgs := []MsgChannelOpenConfirm{ - NewMsgChannelOpenConfirm("testportid", "testchannel", suite.proof, 1, addr), // valid msg - NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", suite.proof, 1, addr), // too short port id - NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", suite.proof, 1, addr), // too long port id - NewMsgChannelOpenConfirm(invalidPort, "testchannel", suite.proof, 1, addr), // port id contains non-alpha - NewMsgChannelOpenConfirm("testportid", invalidShortChannel, suite.proof, 1, addr), // too short channel id - NewMsgChannelOpenConfirm("testportid", invalidLongChannel, suite.proof, 1, addr), // too long channel id - NewMsgChannelOpenConfirm("testportid", invalidChannel, suite.proof, 1, addr), // channel id contains non-alpha - NewMsgChannelOpenConfirm("testportid", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelOpenConfirm("testportid", "testchannel", commitment.Proof{Proof: nil}, 1, addr), // empty proof - NewMsgChannelOpenConfirm("testportid", "testchannel", suite.proof, 0, addr), // proof height is zero + NewMsgChannelOpenConfirm("testportid", "testchannel", suite.proof, 1, addr), // valid msg + NewMsgChannelOpenConfirm(invalidShortPort, "testchannel", suite.proof, 1, addr), // too short port id + NewMsgChannelOpenConfirm(invalidLongPort, "testchannel", suite.proof, 1, addr), // too long port id + NewMsgChannelOpenConfirm(invalidPort, "testchannel", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelOpenConfirm("testportid", invalidShortChannel, suite.proof, 1, addr), // too short channel id + NewMsgChannelOpenConfirm("testportid", invalidLongChannel, suite.proof, 1, addr), // too long channel id + NewMsgChannelOpenConfirm("testportid", invalidChannel, suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelOpenConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testportid", "testchannel", commitmenttypes.MerkleProof{Proof: nil}, 1, addr), // empty proof + NewMsgChannelOpenConfirm("testportid", "testchannel", suite.proof, 0, addr), // proof height is zero } testCases := []struct { @@ -313,16 +314,16 @@ func (suite *MsgTestSuite) TestMsgChannelCloseInit() { // TestMsgChannelCloseConfirm tests ValidateBasic for MsgChannelCloseConfirm func (suite *MsgTestSuite) TestMsgChannelCloseConfirm() { testMsgs := []MsgChannelCloseConfirm{ - NewMsgChannelCloseConfirm("testportid", "testchannel", suite.proof, 1, addr), // valid msg - NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", suite.proof, 1, addr), // too short port id - NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", suite.proof, 1, addr), // too long port id - NewMsgChannelCloseConfirm(invalidPort, "testchannel", suite.proof, 1, addr), // port id contains non-alpha - NewMsgChannelCloseConfirm("testportid", invalidShortChannel, suite.proof, 1, addr), // too short channel id - NewMsgChannelCloseConfirm("testportid", invalidLongChannel, suite.proof, 1, addr), // too long channel id - NewMsgChannelCloseConfirm("testportid", invalidChannel, suite.proof, 1, addr), // channel id contains non-alpha - NewMsgChannelCloseConfirm("testportid", "testchannel", nil, 1, addr), // empty proof - NewMsgChannelCloseConfirm("testportid", "testchannel", commitment.Proof{Proof: nil}, 1, addr), // empty proof - NewMsgChannelCloseConfirm("testportid", "testchannel", suite.proof, 0, addr), // proof height is zero + NewMsgChannelCloseConfirm("testportid", "testchannel", suite.proof, 1, addr), // valid msg + NewMsgChannelCloseConfirm(invalidShortPort, "testchannel", suite.proof, 1, addr), // too short port id + NewMsgChannelCloseConfirm(invalidLongPort, "testchannel", suite.proof, 1, addr), // too long port id + NewMsgChannelCloseConfirm(invalidPort, "testchannel", suite.proof, 1, addr), // port id contains non-alpha + NewMsgChannelCloseConfirm("testportid", invalidShortChannel, suite.proof, 1, addr), // too short channel id + NewMsgChannelCloseConfirm("testportid", invalidLongChannel, suite.proof, 1, addr), // too long channel id + NewMsgChannelCloseConfirm("testportid", invalidChannel, suite.proof, 1, addr), // channel id contains non-alpha + NewMsgChannelCloseConfirm("testportid", "testchannel", nil, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testportid", "testchannel", commitmenttypes.MerkleProof{Proof: nil}, 1, addr), // empty proof + NewMsgChannelCloseConfirm("testportid", "testchannel", suite.proof, 0, addr), // proof height is zero } testCases := []struct { @@ -406,8 +407,8 @@ var ( invalidPacket = NewPacket(invalidPacketT{}, 0, portid, chanid, cpportid, cpchanid) invalidAck = invalidAckT{} - emptyProof = commitment.Proof{Proof: nil} - invalidProofs1 = commitment.ProofI(nil) + emptyProof = commitmenttypes.MerkleProof{Proof: nil} + invalidProofs1 = commitmentexported.Proof(nil) invalidProofs2 = emptyProof addr1 = sdk.AccAddress("testaddr1") @@ -475,7 +476,7 @@ func TestMsgPacketGetSignBytes(t *testing.T) { SubModuleCdc.RegisterConcrete(validPacketT{}, "test/validPacketT", nil) res := msg.GetSignBytes() - expected := `{"packet":{"data":{"type":"test/validPacketT","value":{}},"destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid"},"proof":{"type":"ibc/commitment/merkle/Proof","value":{"proof":{"ops":[]}}},"proof_height":"1","signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}` + expected := `{"packet":{"data":{"type":"test/validPacketT","value":{}},"destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid"},"proof":{"type":"ibc/commitment/MerkleProof","value":{"proof":{"ops":[]}}},"proof_height":"1","signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}` require.Equal(t, expected, string(res)) } diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go index 37b24559ba20..fdedeca408b6 100644 --- a/x/ibc/04-channel/types/querier.go +++ b/x/ibc/04-channel/types/querier.go @@ -5,7 +5,7 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -18,10 +18,10 @@ const ( // ChannelResponse defines the client query response for a channel which also // includes a proof,its path and the height from which the proof was retrieved. type ChannelResponse struct { - Channel Channel `json:"channel" yaml:"channel"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + Channel Channel `json:"channel" yaml:"channel"` + Proof commitmenttypes.MerkleProof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitmenttypes.MerklePath `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewChannelResponse creates a new ChannelResponse instance @@ -30,8 +30,8 @@ func NewChannelResponse( ) ChannelResponse { return ChannelResponse{ Channel: channel, - Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ibctypes.ChannelPath(portID, channelID), "/")), + Proof: commitmenttypes.MerkleProof{Proof: proof}, + ProofPath: commitmenttypes.NewMerklePath(strings.Split(ibctypes.ChannelPath(portID, channelID), "/")), ProofHeight: uint64(height), } } @@ -54,10 +54,10 @@ func NewQueryAllChannelsParams(page, limit int) QueryAllChannelsParams { // PacketResponse defines the client query response for a packet which also // includes a proof, its path and the height form which the proof was retrieved type PacketResponse struct { - Packet Packet `json:"packet" yaml:"packet"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + Packet Packet `json:"packet" yaml:"packet"` + Proof commitmenttypes.MerkleProof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitmenttypes.MerklePath `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewPacketResponse creates a new PacketResponswe instance @@ -66,8 +66,8 @@ func NewPacketResponse( ) PacketResponse { return PacketResponse{ Packet: packet, - Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ibctypes.PacketCommitmentPath(portID, channelID, sequence), "/")), + Proof: commitmenttypes.MerkleProof{Proof: proof}, + ProofPath: commitmenttypes.NewMerklePath(strings.Split(ibctypes.PacketCommitmentPath(portID, channelID, sequence), "/")), ProofHeight: uint64(height), } } @@ -76,10 +76,10 @@ func NewPacketResponse( // number which also includes a proof, its path and the height form which the // proof was retrieved type RecvResponse struct { - NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"` - Proof commitment.Proof `json:"proof,omitempty" yaml:"proof,omitempty"` - ProofPath commitment.Path `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` - ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` + NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"` + Proof commitmenttypes.MerkleProof `json:"proof,omitempty" yaml:"proof,omitempty"` + ProofPath commitmenttypes.MerklePath `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` + ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` } // NewRecvResponse creates a new RecvResponse instance @@ -88,8 +88,8 @@ func NewRecvResponse( ) RecvResponse { return RecvResponse{ NextSequenceRecv: sequenceRecv, - Proof: commitment.Proof{Proof: proof}, - ProofPath: commitment.NewPath(strings.Split(ibctypes.NextSequenceRecvPath(portID, channelID), "/")), + Proof: commitmenttypes.MerkleProof{Proof: proof}, + ProofPath: commitmenttypes.NewMerklePath(strings.Split(ibctypes.NextSequenceRecvPath(portID, channelID), "/")), ProofHeight: uint64(height), } } diff --git a/x/ibc/07-tendermint/client/rest/swagger.go b/x/ibc/07-tendermint/client/rest/swagger.go index 32bb8761f3de..884ab3c2dd56 100644 --- a/x/ibc/07-tendermint/client/rest/swagger.go +++ b/x/ibc/07-tendermint/client/rest/swagger.go @@ -9,22 +9,22 @@ import ( type ( PostCreateClient struct { Msgs []ibctmtypes.MsgCreateClient `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostUpdateClient struct { Msgs []ibctmtypes.MsgUpdateClient `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` Memo string `json:"memo" yaml:"memo"` } PostSubmitMisbehaviour struct { Msgs []ibctmtypes.MsgSubmitClientMisbehaviour `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` + Fee authtypes.StdFee `json:"fee" yaml:"fee"` + Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` + Memo string `json:"memo" yaml:"memo"` } ) diff --git a/x/ibc/07-tendermint/misbehaviour.go b/x/ibc/07-tendermint/misbehaviour.go index df6009a14164..d373e2e5afd1 100644 --- a/x/ibc/07-tendermint/misbehaviour.go +++ b/x/ibc/07-tendermint/misbehaviour.go @@ -5,12 +5,13 @@ import ( "fmt" "time" + lite "github.com/tendermint/tendermint/lite2" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" - lite "github.com/tendermint/tendermint/lite2" ) // CheckMisbehaviourAndUpdateState determines whether or not two conflicting diff --git a/x/ibc/07-tendermint/misbehaviour_test.go b/x/ibc/07-tendermint/misbehaviour_test.go index 4387af1cf7b1..8796b4af755d 100644 --- a/x/ibc/07-tendermint/misbehaviour_test.go +++ b/x/ibc/07-tendermint/misbehaviour_test.go @@ -8,7 +8,7 @@ import ( tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) func (suite *TendermintTestSuite) TestCheckMisbehaviour() { @@ -41,7 +41,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { { "valid misbehavior evidence", ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), - ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), @@ -54,7 +54,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { { "valid misbehavior at height greater than last consensusState", ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), - ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), @@ -67,7 +67,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { { "consensus state's valset hash different from evidence should still pass", ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), - ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: suite.valSet}, + ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: suite.valSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), @@ -80,7 +80,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { { "first valset has too much change", ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), - ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), @@ -93,7 +93,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { { "second valset has too much change", ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), - ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), @@ -106,7 +106,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { { "both valsets have too much change", ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), - ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitment.NewRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, + ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altValSet, altSigners), Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), diff --git a/x/ibc/07-tendermint/tendermint_test.go b/x/ibc/07-tendermint/tendermint_test.go index c8c465cdc7f8..6339812a8b97 100644 --- a/x/ibc/07-tendermint/tendermint_test.go +++ b/x/ibc/07-tendermint/tendermint_test.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) const ( @@ -36,7 +36,7 @@ func (suite *TendermintTestSuite) SetupTest() { suite.cdc = codec.New() codec.RegisterCrypto(suite.cdc) ibctmtypes.RegisterCodec(suite.cdc) - commitment.RegisterCodec(suite.cdc) + commitmenttypes.RegisterCodec(suite.cdc) // now is the time of the current chain, must be after the updating header // mocks ctx.BlockTime() diff --git a/x/ibc/07-tendermint/types/client_state.go b/x/ibc/07-tendermint/types/client_state.go index 2081a96333e9..94cb54250942 100644 --- a/x/ibc/07-tendermint/types/client_state.go +++ b/x/ibc/07-tendermint/types/client_state.go @@ -12,7 +12,8 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -106,11 +107,11 @@ func (cs ClientState) IsFrozen() bool { func (cs ClientState) VerifyClientConsensusState( cdc *codec.Codec, height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, consensusState clientexported.ConsensusState, ) error { - path, err := commitment.ApplyPrefix(prefix, ibctypes.ConsensusStatePath(cs.GetID(), height)) + path, err := commitmenttypes.ApplyPrefix(prefix, ibctypes.ConsensusStatePath(cs.GetID(), height)) if err != nil { return err } @@ -136,13 +137,13 @@ func (cs ClientState) VerifyClientConsensusState( func (cs ClientState) VerifyConnectionState( cdc *codec.Codec, height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, connectionID string, connectionEnd connectionexported.ConnectionI, consensusState clientexported.ConsensusState, ) error { - path, err := commitment.ApplyPrefix(prefix, ibctypes.ConnectionPath(connectionID)) + path, err := commitmenttypes.ApplyPrefix(prefix, ibctypes.ConnectionPath(connectionID)) if err != nil { return err } @@ -168,14 +169,14 @@ func (cs ClientState) VerifyConnectionState( func (cs ClientState) VerifyChannelState( cdc *codec.Codec, height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, channel channelexported.ChannelI, consensusState clientexported.ConsensusState, ) error { - path, err := commitment.ApplyPrefix(prefix, ibctypes.ChannelPath(portID, channelID)) + path, err := commitmenttypes.ApplyPrefix(prefix, ibctypes.ChannelPath(portID, channelID)) if err != nil { return err } @@ -200,15 +201,15 @@ func (cs ClientState) VerifyChannelState( // the specified port, specified channel, and specified sequence. func (cs ClientState) VerifyPacketCommitment( height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, commitmentBytes []byte, consensusState clientexported.ConsensusState, ) error { - path, err := commitment.ApplyPrefix(prefix, ibctypes.PacketCommitmentPath(portID, channelID, sequence)) + path, err := commitmenttypes.ApplyPrefix(prefix, ibctypes.PacketCommitmentPath(portID, channelID, sequence)) if err != nil { return err } @@ -228,15 +229,15 @@ func (cs ClientState) VerifyPacketCommitment( // acknowledgement at the specified port, specified channel, and specified sequence. func (cs ClientState) VerifyPacketAcknowledgement( height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, acknowledgement []byte, consensusState clientexported.ConsensusState, ) error { - path, err := commitment.ApplyPrefix(prefix, ibctypes.PacketAcknowledgementPath(portID, channelID, sequence)) + path, err := commitmenttypes.ApplyPrefix(prefix, ibctypes.PacketAcknowledgementPath(portID, channelID, sequence)) if err != nil { return err } @@ -257,14 +258,14 @@ func (cs ClientState) VerifyPacketAcknowledgement( // specified sequence. func (cs ClientState) VerifyPacketAcknowledgementAbsence( height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, sequence uint64, consensusState clientexported.ConsensusState, ) error { - path, err := commitment.ApplyPrefix(prefix, ibctypes.PacketAcknowledgementPath(portID, channelID, sequence)) + path, err := commitmenttypes.ApplyPrefix(prefix, ibctypes.PacketAcknowledgementPath(portID, channelID, sequence)) if err != nil { return err } @@ -284,14 +285,14 @@ func (cs ClientState) VerifyPacketAcknowledgementAbsence( // received of the specified channel at the specified port. func (cs ClientState) VerifyNextSequenceRecv( height uint64, - prefix commitment.PrefixI, - proof commitment.ProofI, + prefix commitmentexported.Prefix, + proof commitmentexported.Proof, portID, channelID string, nextSequenceRecv uint64, consensusState clientexported.ConsensusState, ) error { - path, err := commitment.ApplyPrefix(prefix, ibctypes.NextSequenceRecvPath(portID, channelID)) + path, err := commitmenttypes.ApplyPrefix(prefix, ibctypes.NextSequenceRecvPath(portID, channelID)) if err != nil { return err } @@ -314,7 +315,7 @@ func (cs ClientState) VerifyNextSequenceRecv( func validateVerificationArgs( cs ClientState, height uint64, - proof commitment.ProofI, + proof commitmentexported.Proof, consensusState clientexported.ConsensusState, ) error { if cs.GetLatestHeight() < height { @@ -329,7 +330,7 @@ func validateVerificationArgs( } if proof == nil { - return sdkerrors.Wrap(commitment.ErrInvalidProof, "proof cannot be empty") + return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "proof cannot be empty") } if consensusState == nil { diff --git a/x/ibc/07-tendermint/types/client_state_test.go b/x/ibc/07-tendermint/types/client_state_test.go index 5f392be235e5..5eb2705b6cb7 100644 --- a/x/ibc/07-tendermint/types/client_state_test.go +++ b/x/ibc/07-tendermint/types/client_state_test.go @@ -6,7 +6,7 @@ import ( channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) const ( @@ -21,55 +21,55 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { name string clientState ibctmtypes.ClientState consensusState ibctmtypes.ConsensusState - prefix commitment.Prefix - proof commitment.Proof + prefix commitmenttypes.MerklePrefix + proof commitmenttypes.MerkleProof expPass bool }{ // { // name: "successful verification", // clientState: ibctmtypes.NewClientState(chainID, chainID, height), // consensusState: ibctmtypes.ConsensusState{ - // Root: commitment.NewRoot(suite.header.AppHash), + // Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), // }, - // prefix: commitment.NewPrefix([]byte("ibc")), + // prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), // expPass: true, // }, { name: "ApplyPrefix failed", clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.Prefix{}, + prefix: commitmenttypes.MerklePrefix{}, expPass: false, }, { name: "latest client height < height", clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { name: "client is frozen", clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { name: "proof verification failed", clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), ValidatorSet: suite.valSet, }, - prefix: commitment.NewPrefix([]byte("ibc")), - proof: commitment.Proof{}, + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), + proof: commitmenttypes.MerkleProof{}, expPass: false, }, } @@ -90,7 +90,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { } func (suite *TendermintTestSuite) TestVerifyConnectionState() { - counterparty := connection.NewCounterparty("clientB", testConnectionID, commitment.NewPrefix([]byte("ibc"))) + counterparty := connection.NewCounterparty("clientB", testConnectionID, commitmenttypes.NewMerklePrefix([]byte("ibc"))) conn := connection.NewConnectionEnd(connectionexported.OPEN, "clientA", counterparty, []string{"1.0.0"}) testCases := []struct { @@ -98,8 +98,8 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { clientState ibctmtypes.ClientState connection connection.ConnectionEnd consensusState ibctmtypes.ConsensusState - prefix commitment.Prefix - proof commitment.Proof + prefix commitmenttypes.MerklePrefix + proof commitmenttypes.MerkleProof expPass bool }{ // { @@ -107,9 +107,9 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { // clientState: ibctmtypes.NewClientState(chainID, chainID, height), // connection: conn, // consensusState: ibctmtypes.ConsensusState{ - // Root: commitment.NewRoot(suite.header.AppHash), + // Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), // }, - // prefix: commitment.NewPrefix([]byte("ibc")), + // prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), // expPass: true, // }, { @@ -117,9 +117,9 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), connection: conn, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.Prefix{}, + prefix: commitmenttypes.MerklePrefix{}, expPass: false, }, { @@ -127,9 +127,9 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), connection: conn, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { @@ -137,9 +137,9 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, connection: conn, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { @@ -147,11 +147,11 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), connection: conn, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), ValidatorSet: suite.valSet, }, - prefix: commitment.NewPrefix([]byte("ibc")), - proof: commitment.Proof{}, + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), + proof: commitmenttypes.MerkleProof{}, expPass: false, }, } @@ -180,8 +180,8 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { clientState ibctmtypes.ClientState channel channel.Channel consensusState ibctmtypes.ConsensusState - prefix commitment.Prefix - proof commitment.Proof + prefix commitmenttypes.MerklePrefix + proof commitmenttypes.MerkleProof expPass bool }{ // { @@ -189,9 +189,9 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { // clientState: ibctmtypes.NewClientState(chainID, height), // connection: conn, // consensusState: ibctmtypes.ConsensusState{ - // Root: commitment.NewRoot(suite.header.AppHash), + // Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), // }, - // prefix: commitment.NewPrefix([]byte("ibc")), + // prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), // expPass: true, // }, { @@ -199,9 +199,9 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), channel: ch, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.Prefix{}, + prefix: commitmenttypes.MerklePrefix{}, expPass: false, }, { @@ -209,9 +209,9 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), channel: ch, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { @@ -219,9 +219,9 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, channel: ch, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { @@ -229,11 +229,11 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), channel: ch, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), ValidatorSet: suite.valSet, }, - prefix: commitment.NewPrefix([]byte("ibc")), - proof: commitment.Proof{}, + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), + proof: commitmenttypes.MerkleProof{}, expPass: false, }, } @@ -259,8 +259,8 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { clientState ibctmtypes.ClientState commitment []byte consensusState ibctmtypes.ConsensusState - prefix commitment.Prefix - proof commitment.Proof + prefix commitmenttypes.MerklePrefix + proof commitmenttypes.MerkleProof expPass bool }{ // { @@ -268,9 +268,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { // clientState: ibctmtypes.NewClientState(chainID, height), // connection: conn, // consensusState: ibctmtypes.ConsensusState{ - // Root: commitment.NewRoot(suite.header.AppHash), + // Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), // }, - // prefix: commitment.NewPrefix([]byte("ibc")), + // prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), // expPass: true, // }, { @@ -278,9 +278,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), commitment: []byte{}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.Prefix{}, + prefix: commitmenttypes.MerklePrefix{}, expPass: false, }, { @@ -288,9 +288,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), commitment: []byte{}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { @@ -298,9 +298,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, commitment: []byte{}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { @@ -308,11 +308,11 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), commitment: []byte{}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), ValidatorSet: suite.valSet, }, - prefix: commitment.NewPrefix([]byte("ibc")), - proof: commitment.Proof{}, + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), + proof: commitmenttypes.MerkleProof{}, expPass: false, }, } @@ -338,8 +338,8 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { clientState ibctmtypes.ClientState ack []byte consensusState ibctmtypes.ConsensusState - prefix commitment.Prefix - proof commitment.Proof + prefix commitmenttypes.MerklePrefix + proof commitmenttypes.MerkleProof expPass bool }{ // { @@ -347,9 +347,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { // clientState: ibctmtypes.NewClientState(chainID, chainID, height), // connection: conn, // consensusState: ibctmtypes.ConsensusState{ - // Root: commitment.NewRoot(suite.header.AppHash), + // Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), // }, - // prefix: commitment.NewPrefix([]byte("ibc")), + // prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), // expPass: true, // }, { @@ -357,9 +357,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ack: []byte{}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.Prefix{}, + prefix: commitmenttypes.MerklePrefix{}, expPass: false, }, { @@ -367,9 +367,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ack: []byte{}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { @@ -377,9 +377,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, ack: []byte{}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { @@ -387,11 +387,11 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ack: []byte{}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), ValidatorSet: suite.valSet, }, - prefix: commitment.NewPrefix([]byte("ibc")), - proof: commitment.Proof{}, + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), + proof: commitmenttypes.MerkleProof{}, expPass: false, }, } @@ -416,8 +416,8 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { name string clientState ibctmtypes.ClientState consensusState ibctmtypes.ConsensusState - prefix commitment.Prefix - proof commitment.Proof + prefix commitmenttypes.MerklePrefix + proof commitmenttypes.MerkleProof expPass bool }{ // { @@ -425,47 +425,47 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { // clientState: ibctmtypes.NewClientState(chainID, chainID, height), // connection: conn, // consensusState: ibctmtypes.ConsensusState{ - // Root: commitment.NewRoot(suite.header.AppHash), + // Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), // }, - // prefix: commitment.NewPrefix([]byte("ibc")), + // prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), // expPass: true, // }, { name: "ApplyPrefix failed", clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.Prefix{}, + prefix: commitmenttypes.MerklePrefix{}, expPass: false, }, { name: "latest client height < height", clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { name: "client is frozen", clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { name: "proof verification failed", clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), ValidatorSet: suite.valSet, }, - prefix: commitment.NewPrefix([]byte("ibc")), - proof: commitment.Proof{}, + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), + proof: commitmenttypes.MerkleProof{}, expPass: false, }, } @@ -490,8 +490,8 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { name string clientState ibctmtypes.ClientState consensusState ibctmtypes.ConsensusState - prefix commitment.Prefix - proof commitment.Proof + prefix commitmenttypes.MerklePrefix + proof commitmenttypes.MerkleProof expPass bool }{ // { @@ -499,47 +499,47 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { // clientState: ibctmtypes.NewClientState(chainID, chainID, height), // connection: conn, // consensusState: ibctmtypes.ConsensusState{ - // Root: commitment.NewRoot(suite.header.AppHash), + // Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), // }, - // prefix: commitment.NewPrefix([]byte("ibc")), + // prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), // expPass: true, // }, { name: "ApplyPrefix failed", clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.Prefix{}, + prefix: commitmenttypes.MerklePrefix{}, expPass: false, }, { name: "latest client height < height", clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { name: "client is frozen", clientState: ibctmtypes.ClientState{ID: chainID, LastHeader: suite.header, FrozenHeight: height - 1}, consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), }, - prefix: commitment.NewPrefix([]byte("ibc")), + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), expPass: false, }, { name: "proof verification failed", clientState: ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), consensusState: ibctmtypes.ConsensusState{ - Root: commitment.NewRoot(suite.header.AppHash), + Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), ValidatorSet: suite.valSet, }, - prefix: commitment.NewPrefix([]byte("ibc")), - proof: commitment.Proof{}, + prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), + proof: commitmenttypes.MerkleProof{}, expPass: false, }, } diff --git a/x/ibc/07-tendermint/types/consensus_state.go b/x/ibc/07-tendermint/types/consensus_state.go index cba067f9a918..801fc768f181 100644 --- a/x/ibc/07-tendermint/types/consensus_state.go +++ b/x/ibc/07-tendermint/types/consensus_state.go @@ -3,19 +3,20 @@ package types import ( "time" + tmtypes "github.com/tendermint/tendermint/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - tmtypes "github.com/tendermint/tendermint/types" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // ConsensusState defines a Tendermint consensus state type ConsensusState struct { - Timestamp time.Time `json:"timestamp" yaml:"timestamp"` - Root commitment.RootI `json:"root" yaml:"root"` - Height uint64 `json:"height" yaml:"height"` - ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` + Timestamp time.Time `json:"timestamp" yaml:"timestamp"` + Root commitmentexported.Root `json:"root" yaml:"root"` + Height uint64 `json:"height" yaml:"height"` + ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` } // ClientType returns Tendermint @@ -24,7 +25,7 @@ func (ConsensusState) ClientType() clientexported.ClientType { } // GetRoot returns the commitment Root for the specific -func (cs ConsensusState) GetRoot() commitment.RootI { +func (cs ConsensusState) GetRoot() commitmentexported.Root { return cs.Root } diff --git a/x/ibc/07-tendermint/types/consensus_state_test.go b/x/ibc/07-tendermint/types/consensus_state_test.go index c50be3483e5f..ac1229b40568 100644 --- a/x/ibc/07-tendermint/types/consensus_state_test.go +++ b/x/ibc/07-tendermint/types/consensus_state_test.go @@ -5,7 +5,7 @@ import ( clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { @@ -18,7 +18,7 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { ibctmtypes.ConsensusState{ Timestamp: suite.now, Height: height, - Root: commitment.NewRoot([]byte("app_hash")), + Root: commitmenttypes.NewMerkleRoot([]byte("app_hash")), ValidatorSet: suite.valSet, }, true}, @@ -34,7 +34,7 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { ibctmtypes.ConsensusState{ Timestamp: suite.now, Height: height, - Root: commitment.Root{}, + Root: commitmenttypes.MerkleRoot{}, ValidatorSet: suite.valSet, }, false}, @@ -42,7 +42,7 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { ibctmtypes.ConsensusState{ Timestamp: suite.now, Height: height, - Root: commitment.NewRoot([]byte("app_hash")), + Root: commitmenttypes.NewMerkleRoot([]byte("app_hash")), ValidatorSet: nil, }, false}, @@ -50,7 +50,7 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { ibctmtypes.ConsensusState{ Timestamp: suite.now, Height: 0, - Root: commitment.NewRoot([]byte("app_hash")), + Root: commitmenttypes.NewMerkleRoot([]byte("app_hash")), ValidatorSet: suite.valSet, }, false}, @@ -58,7 +58,7 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { ibctmtypes.ConsensusState{ Timestamp: time.Time{}, Height: height, - Root: commitment.NewRoot([]byte("app_hash")), + Root: commitmenttypes.NewMerkleRoot([]byte("app_hash")), ValidatorSet: suite.valSet, }, false}, diff --git a/x/ibc/07-tendermint/types/header.go b/x/ibc/07-tendermint/types/header.go index ddc5e01f458a..7b5d6e047979 100644 --- a/x/ibc/07-tendermint/types/header.go +++ b/x/ibc/07-tendermint/types/header.go @@ -9,7 +9,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) var _ clientexported.Header = Header{} @@ -31,7 +31,7 @@ func (h Header) ConsensusState() ConsensusState { return ConsensusState{ Height: uint64(h.Height), Timestamp: h.Time, - Root: commitment.NewRoot(h.AppHash), + Root: commitmenttypes.NewMerkleRoot(h.AppHash), ValidatorSet: h.ValidatorSet, } } diff --git a/x/ibc/07-tendermint/types/msgs.go b/x/ibc/07-tendermint/types/msgs.go index aec1d3a0b9a0..955d1342ab3f 100644 --- a/x/ibc/07-tendermint/types/msgs.go +++ b/x/ibc/07-tendermint/types/msgs.go @@ -8,21 +8,21 @@ import ( evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // Message types for the IBC client const ( - TypeMsgCreateClient string = "create_client" - TypeMsgUpdateClient string = "update_client" + TypeMsgCreateClient string = "create_client" + TypeMsgUpdateClient string = "update_client" TypeMsgSubmitClientMisbehaviour string = "submit_client_misbehaviour" ) var ( - _ clientexported.MsgCreateClient = MsgCreateClient{} - _ clientexported.MsgUpdateClient = MsgUpdateClient{} + _ clientexported.MsgCreateClient = MsgCreateClient{} + _ clientexported.MsgUpdateClient = MsgUpdateClient{} _ evidenceexported.MsgSubmitEvidence = MsgSubmitClientMisbehaviour{} ) @@ -100,7 +100,7 @@ func (msg MsgCreateClient) GetClientType() string { // GetConsensusState implements clientexported.MsgCreateClient func (msg MsgCreateClient) GetConsensusState() clientexported.ConsensusState { // Construct initial consensus state from provided Header - root := commitment.NewRoot(msg.Header.AppHash) + root := commitmenttypes.NewMerkleRoot(msg.Header.AppHash) return ConsensusState{ Timestamp: msg.Header.Time, Root: root, @@ -163,49 +163,49 @@ func (msg MsgUpdateClient) GetHeader() clientexported.Header { return msg.Header } -// MsgSubmitClientMisbehaviour defines an sdk.Msg type that supports submitting -// Evidence for client misbehaviour. -type MsgSubmitClientMisbehaviour struct { - Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` - Submitter sdk.AccAddress `json:"submitter" yaml:"submitter"` +// MsgSubmitClientMisbehaviour defines an sdk.Msg type that supports submitting +// Evidence for client misbehaviour. +type MsgSubmitClientMisbehaviour struct { + Evidence evidenceexported.Evidence `json:"evidence" yaml:"evidence"` + Submitter sdk.AccAddress `json:"submitter" yaml:"submitter"` } // NewMsgSubmitClientMisbehaviour creates a new MsgSubmitClientMisbehaviour // instance. -func NewMsgSubmitClientMisbehaviour(e evidenceexported.Evidence, s sdk.AccAddress) MsgSubmitClientMisbehaviour { - return MsgSubmitClientMisbehaviour{Evidence: e, Submitter: s} -} - -// Route returns the MsgSubmitClientMisbehaviour's route. -func (msg MsgSubmitClientMisbehaviour) Route() string { return ibctypes.RouterKey } - -// Type returns the MsgSubmitClientMisbehaviour's type. -func (msg MsgSubmitClientMisbehaviour) Type() string { return TypeMsgSubmitClientMisbehaviour } - -// ValidateBasic performs basic (non-state-dependant) validation on a MsgSubmitClientMisbehaviour. -func (msg MsgSubmitClientMisbehaviour) ValidateBasic() error { - if msg.Evidence == nil { - return sdkerrors.Wrap(evidencetypes.ErrInvalidEvidence, "missing evidence") - } - if err := msg.Evidence.ValidateBasic(); err != nil { - return err - } - if msg.Submitter.Empty() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Submitter.String()) - } - - return nil -} - -// GetSignBytes returns the raw bytes a signer is expected to sign when submitting -// a MsgSubmitClientMisbehaviour message. -func (msg MsgSubmitClientMisbehaviour) GetSignBytes() []byte { +func NewMsgSubmitClientMisbehaviour(e evidenceexported.Evidence, s sdk.AccAddress) MsgSubmitClientMisbehaviour { + return MsgSubmitClientMisbehaviour{Evidence: e, Submitter: s} +} + +// Route returns the MsgSubmitClientMisbehaviour's route. +func (msg MsgSubmitClientMisbehaviour) Route() string { return ibctypes.RouterKey } + +// Type returns the MsgSubmitClientMisbehaviour's type. +func (msg MsgSubmitClientMisbehaviour) Type() string { return TypeMsgSubmitClientMisbehaviour } + +// ValidateBasic performs basic (non-state-dependant) validation on a MsgSubmitClientMisbehaviour. +func (msg MsgSubmitClientMisbehaviour) ValidateBasic() error { + if msg.Evidence == nil { + return sdkerrors.Wrap(evidencetypes.ErrInvalidEvidence, "missing evidence") + } + if err := msg.Evidence.ValidateBasic(); err != nil { + return err + } + if msg.Submitter.Empty() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Submitter.String()) + } + + return nil +} + +// GetSignBytes returns the raw bytes a signer is expected to sign when submitting +// a MsgSubmitClientMisbehaviour message. +func (msg MsgSubmitClientMisbehaviour) GetSignBytes() []byte { return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) -} +} -// GetSigners returns the single expected signer for a MsgSubmitClientMisbehaviour. -func (msg MsgSubmitClientMisbehaviour) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Submitter} +// GetSigners returns the single expected signer for a MsgSubmitClientMisbehaviour. +func (msg MsgSubmitClientMisbehaviour) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Submitter} } func (msg MsgSubmitClientMisbehaviour) GetEvidence() evidenceexported.Evidence { @@ -214,4 +214,4 @@ func (msg MsgSubmitClientMisbehaviour) GetEvidence() evidenceexported.Evidence { func (msg MsgSubmitClientMisbehaviour) GetSubmitter() sdk.AccAddress { return msg.Submitter -} \ No newline at end of file +} diff --git a/x/ibc/07-tendermint/types/tendermint_test.go b/x/ibc/07-tendermint/types/tendermint_test.go index d4d71cc91ce2..5b4ecb9338ab 100644 --- a/x/ibc/07-tendermint/types/tendermint_test.go +++ b/x/ibc/07-tendermint/types/tendermint_test.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) const ( @@ -34,7 +34,7 @@ func (suite *TendermintTestSuite) SetupTest() { suite.cdc = codec.New() codec.RegisterCrypto(suite.cdc) ibctmtypes.RegisterCodec(suite.cdc) - commitment.RegisterCodec(suite.cdc) + commitmenttypes.RegisterCodec(suite.cdc) suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) suite.privVal = tmtypes.NewMockPV() diff --git a/x/ibc/07-tendermint/update.go b/x/ibc/07-tendermint/update.go index 9f21eb7d8ce2..efc85eb81de8 100644 --- a/x/ibc/07-tendermint/update.go +++ b/x/ibc/07-tendermint/update.go @@ -4,12 +4,13 @@ import ( "errors" "time" + lite "github.com/tendermint/tendermint/lite2" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - lite "github.com/tendermint/tendermint/lite2" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) // CheckValidityAndUpdateState checks if the provided header is valid and updates @@ -93,7 +94,7 @@ func update(clientState types.ClientState, header types.Header) (types.ClientSta consensusState := types.ConsensusState{ Height: uint64(header.Height), Timestamp: header.Time, - Root: commitment.NewRoot(header.AppHash), + Root: commitmenttypes.NewMerkleRoot(header.AppHash), ValidatorSet: header.ValidatorSet, } diff --git a/x/ibc/07-tendermint/update_test.go b/x/ibc/07-tendermint/update_test.go index 025c480aa4f0..3f293e882126 100644 --- a/x/ibc/07-tendermint/update_test.go +++ b/x/ibc/07-tendermint/update_test.go @@ -4,10 +4,11 @@ import ( "bytes" "time" + tmtypes "github.com/tendermint/tendermint/types" + tendermint "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" - tmtypes "github.com/tendermint/tendermint/types" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) func (suite *TendermintTestSuite) TestCheckValidity() { @@ -148,7 +149,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { expectedConsensus := ibctmtypes.ConsensusState{ Height: uint64(newHeader.Height), Timestamp: newHeader.Time, - Root: commitment.NewRoot(newHeader.AppHash), + Root: commitmenttypes.NewMerkleRoot(newHeader.AppHash), ValidatorSet: newHeader.ValidatorSet, } diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 98f9c8a1acc8..d53905bb5c89 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -21,7 +21,7 @@ import ( ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/supply" @@ -73,7 +73,7 @@ func (suite *HandlerTestSuite) SetupTest() { suite.cdc = suite.chainA.App.Codec() } -func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { +func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitmenttypes.MerkleProof, height int64) { res := suite.chainA.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), Data: key, @@ -81,7 +81,7 @@ func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitment.Proof, h }) height = res.Height - proof = commitment.Proof{ + proof = commitmenttypes.MerkleProof{ Proof: res.Proof, } @@ -261,7 +261,7 @@ func (chain *TestChain) updateClient(client *TestChain) { consensusState := ibctmtypes.ConsensusState{ Height: uint64(client.Header.Height), Timestamp: client.Header.Time, - Root: commitment.NewRoot(commitID.Hash), + Root: commitmenttypes.NewMerkleRoot(commitID.Hash), ValidatorSet: client.Vals, } diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index dfb75aa17438..5f509169cbbe 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -21,7 +21,7 @@ import ( channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/staking" ) @@ -73,7 +73,7 @@ func (suite *KeeperTestSuite) SetupTest() { } // nolint: unused -func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, height int64) { +func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitmenttypes.MerkleProof, height int64) { res := suite.chainA.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), Data: key, @@ -81,7 +81,7 @@ func (suite *KeeperTestSuite) queryProof(key []byte) (proof commitment.Proof, he }) height = res.Height - proof = commitment.Proof{ + proof = commitmenttypes.MerkleProof{ Proof: res.Proof, } @@ -223,7 +223,7 @@ func (chain *TestChain) updateClient(client *TestChain) { consensusState := ibctmtypes.ConsensusState{ Height: uint64(client.Header.Height), Timestamp: client.Header.Time, - Root: commitment.NewRoot(commitID.Hash), + Root: commitmenttypes.NewMerkleRoot(commitID.Hash), ValidatorSet: client.Vals, } diff --git a/x/ibc/20-transfer/types/codec.go b/x/ibc/20-transfer/types/codec.go index 489bd6cd9dce..80c1c767b978 100644 --- a/x/ibc/20-transfer/types/codec.go +++ b/x/ibc/20-transfer/types/codec.go @@ -3,7 +3,7 @@ package types import ( "github.com/cosmos/cosmos-sdk/codec" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) // ModuleCdc defines the IBC transfer codec. @@ -18,5 +18,5 @@ func RegisterCodec(cdc *codec.Codec) { func init() { RegisterCodec(ModuleCdc) channel.RegisterCodec(ModuleCdc) - commitment.RegisterCodec(ModuleCdc) + commitmenttypes.RegisterCodec(ModuleCdc) } diff --git a/x/ibc/23-commitment/codec.go b/x/ibc/23-commitment/codec.go deleted file mode 100644 index 1fc535cfc0ca..000000000000 --- a/x/ibc/23-commitment/codec.go +++ /dev/null @@ -1,26 +0,0 @@ -package commitment - -import ( - "github.com/cosmos/cosmos-sdk/codec" -) - -var SubModuleCdc *codec.Codec - -// RegisterCodec registers types declared in this package -func RegisterCodec(cdc *codec.Codec) { - cdc.RegisterInterface((*RootI)(nil), nil) - cdc.RegisterInterface((*PrefixI)(nil), nil) - cdc.RegisterInterface((*PathI)(nil), nil) - cdc.RegisterInterface((*ProofI)(nil), nil) - - cdc.RegisterConcrete(Root{}, "ibc/commitment/merkle/Root", nil) - cdc.RegisterConcrete(Prefix{}, "ibc/commitment/merkle/Prefix", nil) - cdc.RegisterConcrete(Path{}, "ibc/commitment/merkle/Path", nil) - cdc.RegisterConcrete(Proof{}, "ibc/commitment/merkle/Proof", nil) - - SetSubModuleCodec(cdc) -} - -func SetSubModuleCodec(cdc *codec.Codec) { - SubModuleCdc = cdc -} diff --git a/x/ibc/23-commitment/types.go b/x/ibc/23-commitment/exported/exported.go similarity index 78% rename from x/ibc/23-commitment/types.go rename to x/ibc/23-commitment/exported/exported.go index aaab6f9d656b..c6fbbce3ada1 100644 --- a/x/ibc/23-commitment/types.go +++ b/x/ibc/23-commitment/exported/exported.go @@ -1,4 +1,4 @@ -package commitment +package exported // ICS 023 Types Implementation // @@ -7,40 +7,40 @@ package commitment // spec:Path and spec:Value are defined as bytestring -// RootI implements spec:CommitmentRoot. +// Root implements spec:CommitmentRoot. // A root is constructed from a set of key-value pairs, // and the inclusion or non-inclusion of an arbitrary key-value pair // can be proven with the proof. -type RootI interface { +type Root interface { GetCommitmentType() Type GetHash() []byte IsEmpty() bool } -// PrefixI implements spec:CommitmentPrefix. +// Prefix implements spec:CommitmentPrefix. // Prefix represents the common "prefix" that a set of keys shares. -type PrefixI interface { +type Prefix interface { GetCommitmentType() Type Bytes() []byte IsEmpty() bool } -// PathI implements spec:CommitmentPath. +// Path implements spec:CommitmentPath. // A path is the additional information provided to the verification function. -type PathI interface { +type Path interface { GetCommitmentType() Type String() string IsEmpty() bool } -// ProofI implements spec:CommitmentProof. +// Proof implements spec:CommitmentProof. // Proof can prove whether the key-value pair is a part of the Root or not. // Each proof has designated key-value pair it is able to prove. // Proofs includes key but value is provided dynamically at the verification time. -type ProofI interface { +type Proof interface { GetCommitmentType() Type - VerifyMembership(RootI, PathI, []byte) error - VerifyNonMembership(RootI, PathI) error + VerifyMembership(Root, Path, []byte) error + VerifyNonMembership(Root, Path) error IsEmpty() bool ValidateBasic() error diff --git a/x/ibc/23-commitment/types/codec.go b/x/ibc/23-commitment/types/codec.go new file mode 100644 index 000000000000..e7e761867fc8 --- /dev/null +++ b/x/ibc/23-commitment/types/codec.go @@ -0,0 +1,27 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" +) + +var SubModuleCdc *codec.Codec + +// RegisterCodec registers types declared in this package +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*exported.Root)(nil), nil) + cdc.RegisterInterface((*exported.Prefix)(nil), nil) + cdc.RegisterInterface((*exported.Path)(nil), nil) + cdc.RegisterInterface((*exported.Proof)(nil), nil) + + cdc.RegisterConcrete(MerkleRoot{}, "ibc/commitment/MerkleRoot", nil) + cdc.RegisterConcrete(MerklePrefix{}, "ibc/commitment/MerklePrefix", nil) + cdc.RegisterConcrete(MerklePath{}, "ibc/commitment/MerklePath", nil) + cdc.RegisterConcrete(MerkleProof{}, "ibc/commitment/MerkleProof", nil) + + SetSubModuleCodec(cdc) +} + +func SetSubModuleCodec(cdc *codec.Codec) { + SubModuleCdc = cdc +} diff --git a/x/ibc/23-commitment/commitment_test.go b/x/ibc/23-commitment/types/commitment_test.go similarity index 97% rename from x/ibc/23-commitment/commitment_test.go rename to x/ibc/23-commitment/types/commitment_test.go index 2535f5705e29..932599e539cd 100644 --- a/x/ibc/23-commitment/commitment_test.go +++ b/x/ibc/23-commitment/types/commitment_test.go @@ -1,4 +1,4 @@ -package commitment_test +package types_test import ( "testing" diff --git a/x/ibc/23-commitment/errors.go b/x/ibc/23-commitment/types/errors.go similarity index 82% rename from x/ibc/23-commitment/errors.go rename to x/ibc/23-commitment/types/errors.go index 89b2bf0b0ad7..3b32f24643c0 100644 --- a/x/ibc/23-commitment/errors.go +++ b/x/ibc/23-commitment/types/errors.go @@ -1,11 +1,11 @@ -package commitment +package types import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // SubModuleName is the error codespace -const SubModuleName string = "ibc/commitment" +const SubModuleName string = "commitment" // IBC connection sentinel errors var ( diff --git a/x/ibc/23-commitment/merkle.go b/x/ibc/23-commitment/types/merkle.go similarity index 56% rename from x/ibc/23-commitment/merkle.go rename to x/ibc/23-commitment/types/merkle.go index d3649e7313f9..74f6353f339a 100644 --- a/x/ibc/23-commitment/merkle.go +++ b/x/ibc/23-commitment/types/merkle.go @@ -1,4 +1,4 @@ -package commitment +package types import ( "errors" @@ -7,6 +7,7 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" "github.com/cosmos/cosmos-sdk/store/rootmulti" + "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -16,99 +17,99 @@ import ( // Merkle proof implementation of the Proof interface // Applied on SDK-based IBC implementation -var _ RootI = Root{} +var _ exported.Root = MerkleRoot{} -// Root defines a merkle root hash. -// In the Cosmos SDK, the AppHash of a block header becomes the Root. -type Root struct { +// MerkleRoot defines a merkle root hash. +// In the Cosmos SDK, the AppHash of a block header becomes the root. +type MerkleRoot struct { Hash []byte `json:"hash" yaml:"hash"` } -// NewRoot constructs a new Root -func NewRoot(hash []byte) Root { - return Root{ +// NewMerkleRoot constructs a new MerkleRoot +func NewMerkleRoot(hash []byte) MerkleRoot { + return MerkleRoot{ Hash: hash, } } // GetCommitmentType implements RootI interface -func (Root) GetCommitmentType() Type { - return Merkle +func (MerkleRoot) GetCommitmentType() exported.Type { + return exported.Merkle } // GetHash implements RootI interface -func (r Root) GetHash() []byte { - return r.Hash +func (mr MerkleRoot) GetHash() []byte { + return mr.Hash } // IsEmpty returns true if the root is empty -func (r Root) IsEmpty() bool { - return len(r.GetHash()) == 0 +func (mr MerkleRoot) IsEmpty() bool { + return len(mr.GetHash()) == 0 } -var _ PrefixI = Prefix{} +var _ exported.Prefix = MerklePrefix{} -// Prefix is merkle path prefixed to the key. +// MerklePrefix is merkle path prefixed to the key. // The constructed key from the Path and the key will be append(Path.KeyPath, append(Path.KeyPrefix, key...)) -type Prefix struct { +type MerklePrefix struct { KeyPrefix []byte `json:"key_prefix" yaml:"key_prefix"` // byte slice prefixed before the key } -// NewPrefix constructs new Prefix instance -func NewPrefix(keyPrefix []byte) Prefix { - return Prefix{ +// NewMerklePrefix constructs new MerklePrefix instance +func NewMerklePrefix(keyPrefix []byte) MerklePrefix { + return MerklePrefix{ KeyPrefix: keyPrefix, } } -// GetCommitmentType implements PrefixI -func (Prefix) GetCommitmentType() Type { - return Merkle +// GetCommitmentType implements Prefix interface +func (MerklePrefix) GetCommitmentType() exported.Type { + return exported.Merkle } // Bytes returns the key prefix bytes -func (p Prefix) Bytes() []byte { - return p.KeyPrefix +func (mp MerklePrefix) Bytes() []byte { + return mp.KeyPrefix } // IsEmpty returns true if the prefix is empty -func (p Prefix) IsEmpty() bool { - return len(p.Bytes()) == 0 +func (mp MerklePrefix) IsEmpty() bool { + return len(mp.Bytes()) == 0 } -var _ PathI = Path{} +var _ exported.Path = MerklePath{} -// Path is the path used to verify commitment proofs, which can be an arbitrary +// MerklePath is the path used to verify commitment proofs, which can be an arbitrary // structured object (defined by a commitment type). -type Path struct { +type MerklePath struct { KeyPath merkle.KeyPath `json:"key_path" yaml:"key_path"` // byte slice prefixed before the key } -// NewPath creates a new CommitmentPath instance -func NewPath(keyPathStr []string) Path { +// NewMerklePath creates a new MerklePath instance +func NewMerklePath(keyPathStr []string) MerklePath { merkleKeyPath := merkle.KeyPath{} for _, keyStr := range keyPathStr { merkleKeyPath = merkleKeyPath.AppendKey([]byte(keyStr), merkle.KeyEncodingURL) } - return Path{ + return MerklePath{ KeyPath: merkleKeyPath, } } // GetCommitmentType implements PathI -func (Path) GetCommitmentType() Type { - return Merkle +func (MerklePath) GetCommitmentType() exported.Type { + return exported.Merkle } // String implements fmt.Stringer. -func (p Path) String() string { - return p.KeyPath.String() +func (mp MerklePath) String() string { + return mp.KeyPath.String() } // Pretty returns the unescaped path of the URL string. -func (p Path) Pretty() string { - path, err := url.PathUnescape(p.KeyPath.String()) +func (mp MerklePath) Pretty() string { + path, err := url.PathUnescape(mp.KeyPath.String()) if err != nil { panic(err) } @@ -116,8 +117,8 @@ func (p Path) Pretty() string { } // IsEmpty returns true if the path is empty -func (p Path) IsEmpty() bool { - return len(p.KeyPath) == 0 +func (mp MerklePath) IsEmpty() bool { + return len(mp.KeyPath) == 0 } // ApplyPrefix constructs a new commitment path from the arguments. It interprets @@ -125,35 +126,35 @@ func (p Path) IsEmpty() bool { // // CONTRACT: provided path string MUST be a well formated path. See ICS24 for // reference. -func ApplyPrefix(prefix PrefixI, path string) (Path, error) { +func ApplyPrefix(prefix exported.Prefix, path string) (MerklePath, error) { err := host.DefaultPathValidator(path) if err != nil { - return Path{}, err + return MerklePath{}, err } if prefix == nil || prefix.IsEmpty() { - return Path{}, errors.New("prefix can't be empty") + return MerklePath{}, errors.New("prefix can't be empty") } - return NewPath([]string{string(prefix.Bytes()), path}), nil + return NewMerklePath([]string{string(prefix.Bytes()), path}), nil } -var _ ProofI = Proof{} +var _ exported.Proof = MerkleProof{} -// Proof is a wrapper type that contains a merkle proof. +// MerkleProof is a wrapper type that contains a merkle proof. // It demonstrates membership or non-membership for an element or set of elements, // verifiable in conjunction with a known commitment root. Proofs should be // succinct. -type Proof struct { +type MerkleProof struct { Proof *merkle.Proof `json:"proof" yaml:"proof"` } // GetCommitmentType implements ProofI -func (Proof) GetCommitmentType() Type { - return Merkle +func (MerkleProof) GetCommitmentType() exported.Type { + return exported.Merkle } // VerifyMembership verifies the membership pf a merkle proof against the given root, path, and value. -func (proof Proof) VerifyMembership(root RootI, path PathI, value []byte) error { +func (proof MerkleProof) VerifyMembership(root exported.Root, path exported.Path, value []byte) error { if proof.IsEmpty() || root == nil || root.IsEmpty() || path == nil || path.IsEmpty() || len(value) == 0 { return errors.New("empty params or proof") } @@ -163,7 +164,7 @@ func (proof Proof) VerifyMembership(root RootI, path PathI, value []byte) error } // VerifyNonMembership verifies the absence of a merkle proof against the given root and path. -func (proof Proof) VerifyNonMembership(root RootI, path PathI) error { +func (proof MerkleProof) VerifyNonMembership(root exported.Root, path exported.Path) error { if proof.IsEmpty() || root == nil || root.IsEmpty() || path == nil || path.IsEmpty() { return errors.New("empty params or proof") } @@ -173,12 +174,12 @@ func (proof Proof) VerifyNonMembership(root RootI, path PathI) error { } // IsEmpty returns true if the root is empty -func (proof Proof) IsEmpty() bool { - return (proof == Proof{}) || proof.Proof == nil +func (proof MerkleProof) IsEmpty() bool { + return (proof == MerkleProof{}) || proof.Proof == nil } // ValidateBasic checks if the proof is empty. -func (proof Proof) ValidateBasic() error { +func (proof MerkleProof) ValidateBasic() error { if proof.IsEmpty() { return ErrInvalidProof } diff --git a/x/ibc/23-commitment/merkle_test.go b/x/ibc/23-commitment/types/merkle_test.go similarity index 88% rename from x/ibc/23-commitment/merkle_test.go rename to x/ibc/23-commitment/types/merkle_test.go index 4ce2c697df4d..bb287ecde634 100644 --- a/x/ibc/23-commitment/merkle_test.go +++ b/x/ibc/23-commitment/types/merkle_test.go @@ -1,4 +1,4 @@ -package commitment_test +package types_test import ( "fmt" @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" abci "github.com/tendermint/tendermint/abci/types" ) @@ -22,11 +22,11 @@ func (suite *MerkleTestSuite) TestVerifyMembership() { }) require.NotNil(suite.T(), res.Proof) - proof := commitment.Proof{ + proof := types.MerkleProof{ Proof: res.Proof, } suite.Require().NoError(proof.ValidateBasic()) - suite.Require().Error(commitment.Proof{}.ValidateBasic()) + suite.Require().Error(types.MerkleProof{}.ValidateBasic()) cases := []struct { name string @@ -50,8 +50,8 @@ func (suite *MerkleTestSuite) TestVerifyMembership() { for i, tc := range cases { tc := tc suite.Run(tc.name, func() { - root := commitment.NewRoot(tc.root) - path := commitment.NewPath(tc.pathArr) + root := types.NewMerkleRoot(tc.root) + path := types.NewMerklePath(tc.pathArr) err := proof.VerifyMembership(root, path, tc.value) @@ -77,7 +77,7 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() { }) require.NotNil(suite.T(), res.Proof) - proof := commitment.Proof{ + proof := types.MerkleProof{ Proof: res.Proof, } suite.Require().NoError(proof.ValidateBasic()) @@ -103,8 +103,8 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() { tc := tc suite.Run(tc.name, func() { - root := commitment.NewRoot(tc.root) - path := commitment.NewPath(tc.pathArr) + root := types.NewMerkleRoot(tc.root) + path := types.NewMerklePath(tc.pathArr) err := proof.VerifyNonMembership(root, path) @@ -119,11 +119,11 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() { } func TestApplyPrefix(t *testing.T) { - prefix := commitment.NewPrefix([]byte("storePrefixKey")) + prefix := types.NewMerklePrefix([]byte("storePrefixKey")) pathStr := "path1/path2/path3/key" - prefixedPath, err := commitment.ApplyPrefix(prefix, pathStr) + prefixedPath, err := types.ApplyPrefix(prefix, pathStr) require.Nil(t, err, "valid prefix returns error") require.Equal(t, "/storePrefixKey/path1/path2/path3/key", prefixedPath.Pretty(), "Prefixed path incorrect") @@ -131,7 +131,7 @@ func TestApplyPrefix(t *testing.T) { // invalid prefix contains non-alphanumeric character invalidPathStr := "invalid-path/doesitfail?/hopefully" - invalidPath, err := commitment.ApplyPrefix(prefix, invalidPathStr) + invalidPath, err := types.ApplyPrefix(prefix, invalidPathStr) require.NotNil(t, err, "invalid prefix does not returns error") - require.Equal(t, commitment.Path{}, invalidPath, "invalid prefix returns valid Path on ApplyPrefix") + require.Equal(t, types.MerklePath{}, invalidPath, "invalid prefix returns valid Path on ApplyPrefix") } diff --git a/x/ibc/23-commitment/verify.go b/x/ibc/23-commitment/verify.go index 8e070595949f..4690fe9e1567 100644 --- a/x/ibc/23-commitment/verify.go +++ b/x/ibc/23-commitment/verify.go @@ -2,12 +2,14 @@ package commitment import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) // CalculateRoot returns the application Hash at the curretn block height as a commitment // root for proof verification. -func CalculateRoot(ctx sdk.Context) RootI { - return NewRoot(ctx.BlockHeader().AppHash) +func CalculateRoot(ctx sdk.Context) exported.Root { + return types.NewMerkleRoot(ctx.BlockHeader().AppHash) } // BatchVerifyMembership verifies a proof that many paths have been set to @@ -16,14 +18,14 @@ func CalculateRoot(ctx sdk.Context) RootI { // Returns false on the first failed membership verification. func BatchVerifyMembership( ctx sdk.Context, - proof ProofI, - prefix PrefixI, + proof exported.Proof, + prefix exported.Prefix, items map[string][]byte, ) error { root := CalculateRoot(ctx) for pathStr, value := range items { - path, err := ApplyPrefix(prefix, pathStr) + path, err := types.ApplyPrefix(prefix, pathStr) if err != nil { return err } @@ -42,13 +44,13 @@ func BatchVerifyMembership( // Returns false on the first failed non-membership verification. func BatchVerifyNonMembership( ctx sdk.Context, - proof ProofI, - prefix PrefixI, + proof exported.Proof, + prefix exported.Prefix, paths []string, ) error { root := CalculateRoot(ctx) for _, pathStr := range paths { - path, err := ApplyPrefix(prefix, pathStr) + path, err := types.ApplyPrefix(prefix, pathStr) if err != nil { return err } diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go index 535157c7ad6c..57f5b7c2e608 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/ante/ante_test.go @@ -23,7 +23,7 @@ import ( ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/staking" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" "github.com/cosmos/cosmos-sdk/x/ibc/ante" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -68,7 +68,7 @@ func (suite *HandlerTestSuite) SetupTest() { suite.chainB.createConnection(testConnection, testConnection, testClientIDA, testClientIDB, connectionexported.OPEN) } -func queryProof(chain *TestChain, key string) (proof commitment.Proof, height int64) { +func queryProof(chain *TestChain, key string) (proof commitmenttypes.MerkleProof, height int64) { res := chain.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), Data: []byte(key), @@ -76,7 +76,7 @@ func queryProof(chain *TestChain, key string) (proof commitment.Proof, height in }) height = res.Height - proof = commitment.Proof{ + proof = commitmenttypes.MerkleProof{ Proof: res.Proof, } @@ -298,7 +298,7 @@ func (chain *TestChain) updateClient(client *TestChain) { consensusState := ibctmtypes.ConsensusState{ Height: uint64(client.Header.Height) - 1, Timestamp: client.Header.Time, - Root: commitment.NewRoot(commitID.Hash), + Root: commitmenttypes.NewMerkleRoot(commitID.Hash), ValidatorSet: client.Vals, } diff --git a/x/ibc/module.go b/x/ibc/module.go index 904820f52c06..acb96a3bfedf 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -16,7 +16,7 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/client/rest" "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -44,7 +44,7 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { connection.RegisterCodec(cdc) channel.RegisterCodec(cdc) ibctmtypes.RegisterCodec(cdc) - commitment.RegisterCodec(cdc) + commitmenttypes.RegisterCodec(cdc) } // DefaultGenesis returns default genesis state as raw bytes for the ibc diff --git a/x/ibc/types/mock.go b/x/ibc/types/mock.go index ebc307a3129a..43fcd3beadb1 100644 --- a/x/ibc/types/mock.go +++ b/x/ibc/types/mock.go @@ -3,15 +3,15 @@ package types import ( "errors" - commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" + commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ) // Mocked types // TODO: fix tests and replace for real proofs var ( - _ commitment.ProofI = ValidProof{} - _ commitment.ProofI = InvalidProof{} + _ commitmentexported.Proof = ValidProof{} + _ commitmentexported.Proof = InvalidProof{} ) type ( @@ -19,16 +19,16 @@ type ( InvalidProof struct{} ) -func (ValidProof) GetCommitmentType() commitment.Type { - return commitment.Merkle +func (ValidProof) GetCommitmentType() commitmentexported.Type { + return commitmentexported.Merkle } func (ValidProof) VerifyMembership( - root commitment.RootI, path commitment.PathI, value []byte) error { + root commitmentexported.Root, path commitmentexported.Path, value []byte) error { return nil } -func (ValidProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { +func (ValidProof) VerifyNonMembership(root commitmentexported.Root, path commitmentexported.Path) error { return nil } @@ -40,16 +40,16 @@ func (ValidProof) IsEmpty() bool { return false } -func (InvalidProof) GetCommitmentType() commitment.Type { - return commitment.Merkle +func (InvalidProof) GetCommitmentType() commitmentexported.Type { + return commitmentexported.Merkle } func (InvalidProof) VerifyMembership( - root commitment.RootI, path commitment.PathI, value []byte) error { + root commitmentexported.Root, path commitmentexported.Path, value []byte) error { return errors.New("proof failed") } -func (InvalidProof) VerifyNonMembership(root commitment.RootI, path commitment.PathI) error { +func (InvalidProof) VerifyNonMembership(root commitmentexported.Root, path commitmentexported.Path) error { return errors.New("proof failed") } From 1818d984007f51a323e18e0f3ed3f8b4f304fa10 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Sat, 7 Mar 2020 19:13:35 +0100 Subject: [PATCH 095/176] Merge PR #5711: Switch mock proofs to real proofs * Add key, path, value to mock proofs * Also alter mock types (why are there duplicates) * Remove mock proofs from handshake_test.go * Use actual proofs * Try to fix historical info, no luck * Have test-cases produce consensus heights * Fix consensus height / proof height difference in verifyClientConsensusState * Bug fixes contd. * Fix some identifier issues * `TestConnOpenConfirm` now works * further on proof * fix debugger print statement * IT PASSES * revert identifier changes * refactor query proof to generate proofs from either chain * fix ack and confirm * Remove temporary break * fix connection and channel verify tests * fix everything but verify client consensusstate * fix all verify tests * fix ics07 tests * fix handshake tests * fix packet tests * fix timeout tests Co-authored-by: Aditya Sripal Co-authored-by: Federico Kunze --- simapp/app.go | 2 +- x/ibc/02-client/exported/exported.go | 3 + x/ibc/02-client/keeper/keeper.go | 5 +- x/ibc/03-connection/keeper/handshake.go | 4 +- x/ibc/03-connection/keeper/handshake_test.go | 158 +++++++--------- x/ibc/03-connection/keeper/keeper_test.go | 36 +++- x/ibc/03-connection/keeper/verify.go | 8 +- x/ibc/03-connection/keeper/verify_test.go | 177 +++++++++++------- x/ibc/04-channel/keeper/handshake_test.go | 90 ++++++--- x/ibc/04-channel/keeper/keeper_test.go | 29 ++- x/ibc/04-channel/keeper/packet_test.go | 52 +++-- x/ibc/04-channel/keeper/timeout_test.go | 44 ++--- x/ibc/07-tendermint/types/client_state.go | 11 +- .../07-tendermint/types/client_state_test.go | 9 +- x/ibc/types/mock.go | 21 ++- 15 files changed, 401 insertions(+), 248 deletions(-) diff --git a/simapp/app.go b/simapp/app.go index 268564cc6844..0aea5d976589 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -258,7 +258,7 @@ func NewSimApp( // During begin block slashing happens after distr.BeginBlocker so that // there is nothing left over in the validator fee pool, so as to keep the // CanWithdrawInvariant invariant. - app.mm.SetOrderBeginBlockers(upgrade.ModuleName, mint.ModuleName, distr.ModuleName, slashing.ModuleName, evidence.ModuleName) + app.mm.SetOrderBeginBlockers(upgrade.ModuleName, mint.ModuleName, distr.ModuleName, slashing.ModuleName, evidence.ModuleName, staking.ModuleName) app.mm.SetOrderEndBlockers(crisis.ModuleName, gov.ModuleName, staking.ModuleName) // NOTE: The genutils moodule must occur after staking so that pools are diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index 996a5343c797..aeb861db3de8 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -24,7 +24,10 @@ type ClientState interface { VerifyClientConsensusState( cdc *codec.Codec, + root commitmentexported.Root, height uint64, + counterpartyClientIdentifier string, + consensusHeight uint64, prefix commitmentexported.Prefix, proof commitmentexported.Proof, consensusState ConsensusState, diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index ef5ab61bf87f..160bcde630fa 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -135,8 +135,9 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported. valSet := stakingtypes.Validators(histInfo.Valset) consensusState := ibctmtypes.ConsensusState{ - Height: height, - Timestamp: ctx.BlockTime(), + Height: height, + // FIXME: Currently commented out due to time normalisation issues. + //Timestamp: histInfo.Header.Time, Root: commitmenttypes.NewMerkleRoot(histInfo.Header.AppHash), ValidatorSet: tmtypes.NewValidatorSet(valSet.ToTmValidators()), } diff --git a/x/ibc/03-connection/keeper/handshake.go b/x/ibc/03-connection/keeper/handshake.go index 5b8592f83daa..e7cc6b796dfe 100644 --- a/x/ibc/03-connection/keeper/handshake.go +++ b/x/ibc/03-connection/keeper/handshake.go @@ -88,7 +88,7 @@ func (k Keeper) ConnOpenTry( // Check that ChainA stored the correct ConsensusState of chainB at the given consensusHeight if err := k.VerifyClientConsensusState( - ctx, connection, consensusHeight, proofConsensus, expectedConsensusState, + ctx, connection, proofHeight, consensusHeight, proofConsensus, expectedConsensusState, ); err != nil { return err } @@ -177,7 +177,7 @@ func (k Keeper) ConnOpenAck( // Ensure that ChainB has stored the correct ConsensusState for chainA at the consensusHeight if err := k.VerifyClientConsensusState( - ctx, connection, consensusHeight, proofConsensus, expectedConsensusState, + ctx, connection, proofHeight, consensusHeight, proofConsensus, expectedConsensusState, ); err != nil { return err } diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index 83a2ae0958ef..0df27a306ef2 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -5,7 +5,6 @@ import ( connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" - commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -47,66 +46,62 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { // TestConnOpenTry - Chain B (ID #2) calls ConnOpenTry to verify the state of // connection on Chain A (ID #1) is INIT func (suite *KeeperTestSuite) TestConnOpenTry() { + // counterparty for A on B counterparty := connection.NewCounterparty( testClientIDB, testConnectionIDA, suite.chainB.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), ) - var ( - consensusHeight int64 = 0 - proofHeight int64 = 0 - ) testCases := []struct { - msg string - proofInit commitmentexported.Proof - proofConsensus commitmentexported.Proof - malleate func() - expPass bool + msg string + malleate func() uint64 + expPass bool }{ - {"success", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { + {"success", func() uint64 { suite.chainB.CreateClient(suite.chainA) - suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) - proofHeight = suite.chainA.Header.Height suite.chainA.CreateClient(suite.chainB) - consensusHeight = suite.chainB.Header.Height + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) suite.chainB.updateClient(suite.chainA) suite.chainA.updateClient(suite.chainB) + return uint64(suite.chainB.Header.Height - 1) }, true}, - {"consensus height > latest height", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - consensusHeight = 100 + {"consensus height > latest height", func() uint64 { + return 0 + }, false}, + {"self consensus state not found", func() uint64 { + //suite.ctx = suite.ctx.WithBlockHeight(100) + return 100 }, false}, - // {"self consensus state not found", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - // consensusHeight = 100 - // suite.ctx = suite.ctx.WithBlockHeight(100) - // }, false}, - {"connection state verification invalid", ibctypes.InvalidProof{}, ibctypes.ValidProof{}, func() { + {"connection state verification invalid", func() uint64 { suite.chainB.CreateClient(suite.chainA) suite.chainA.CreateClient(suite.chainB) - consensusHeight = suite.chainB.Header.Height suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.UNINITIALIZED) suite.chainB.updateClient(suite.chainA) + return 0 }, false}, - {"consensus state verification invalid", ibctypes.ValidProof{}, ibctypes.InvalidProof{}, func() { + {"consensus state verification invalid", func() uint64 { suite.chainB.CreateClient(suite.chainA) suite.chainA.CreateClient(suite.chainB) - consensusHeight = suite.chainB.Header.Height suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) suite.chainB.updateClient(suite.chainA) suite.chainA.updateClient(suite.chainB) + return uint64(suite.chainB.Header.Height) }, false}, - {"invalid previous connection", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { + {"invalid previous connection", func() uint64 { suite.chainB.CreateClient(suite.chainA) suite.chainA.CreateClient(suite.chainB) - consensusHeight = suite.chainB.Header.Height suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.UNINITIALIZED) suite.chainB.updateClient(suite.chainA) suite.chainA.updateClient(suite.chainB) + return 0 }, false}, - {"couldn't add connection to client", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { + {"couldn't add connection to client", func() uint64 { suite.chainB.CreateClient(suite.chainA) - consensusHeight = suite.chainB.Header.Height suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, exported.UNINITIALIZED) suite.chainB.updateClient(suite.chainA) suite.chainA.updateClient(suite.chainB) + return 0 }, false}, } @@ -115,24 +110,24 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset - tc.malleate() + consensusHeight := tc.malleate() - // connectionKey := ibctypes.KeyConnection(testConnectionIDA) - // proofInit, proofHeight := suite.queryProof(connectionKey) + connectionKey := ibctypes.KeyConnection(testConnectionIDA) + proofInit, proofHeight := queryProof(suite.chainA, connectionKey) - // consensusKey := ibctypes.KeyConsensusState(testClientIDA, uint64(proofHeight)) - // proofConsensus, consensusHeight := suite.queryProof(consensusKey) + consensusKey := ibctypes.KeyConsensusState(testClientIDB, consensusHeight) + proofConsensus, _ := queryProof(suite.chainA, consensusKey) err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( suite.chainB.GetContext(), testConnectionIDB, counterparty, testClientIDA, - connection.GetCompatibleVersions(), tc.proofInit, tc.proofConsensus, - uint64(proofHeight), uint64(consensusHeight), + connection.GetCompatibleVersions(), proofInit, proofConsensus, + uint64(proofHeight+1), consensusHeight, ) if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + suite.Require().NoError(err, "valid test case %d failed with consensus height %d and proof height %d: %s", i, consensusHeight, proofHeight, tc.msg) } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + suite.Require().Error(err, "invalid test case %d passed with consensus height %d and proof height %d: %s", i, consensusHeight, proofHeight, tc.msg) } }) } @@ -143,66 +138,60 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { func (suite *KeeperTestSuite) TestConnOpenAck() { version := connection.GetCompatibleVersions()[0] - var ( - consensusHeight int64 = 0 - proofHeight int64 = 0 - ) - testCases := []struct { - msg string - version string - proofTry commitmentexported.Proof - proofConsensus commitmentexported.Proof - malleate func() - expPass bool + msg string + version string + malleate func() uint64 + expPass bool }{ - {"success", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { + {"success", version, func() uint64 { suite.chainA.CreateClient(suite.chainB) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) - consensusHeight = suite.chainB.Header.Height - proofHeight = suite.chainA.Header.Height suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) suite.chainB.updateClient(suite.chainA) suite.chainA.updateClient(suite.chainB) + return uint64(suite.chainB.Header.Height) }, true}, - {"consensus height > latest height", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - consensusHeight = 100 + {"consensus height > latest height", version, func() uint64 { + return 10 }, false}, - {"connection not found", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { - consensusHeight = suite.chainB.Header.Height + {"connection not found", version, func() uint64 { + return 2 }, false}, - {"connection state is not INIT", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { + {"connection state is not INIT", version, func() uint64 { suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.UNINITIALIZED) suite.chainB.updateClient(suite.chainA) + return uint64(suite.chainB.Header.Height) }, false}, - {"incompatible IBC versions", "2.0", ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { + {"incompatible IBC versions", "2.0", func() uint64 { suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.INIT) suite.chainB.updateClient(suite.chainA) + return uint64(suite.chainB.Header.Height) }, false}, - {"self consensus state not found", version, ibctypes.ValidProof{}, ibctypes.ValidProof{}, func() { + {"self consensus state not found", version, func() uint64 { suite.chainB.CreateClient(suite.chainA) suite.chainA.CreateClient(suite.chainB) suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) suite.chainB.updateClient(suite.chainA) - consensusHeight = 100 + return uint64(suite.chainB.Header.Height) }, false}, - {"connection state verification failed", version, ibctypes.InvalidProof{}, ibctypes.ValidProof{}, func() { + {"connection state verification failed", version, func() uint64 { suite.chainB.CreateClient(suite.chainA) - consensusHeight = suite.chainB.Header.Height suite.chainA.CreateClient(suite.chainB) suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.UNINITIALIZED) suite.chainB.updateClient(suite.chainA) + return uint64(suite.chainB.Header.Height) }, false}, - {"consensus state verification failed", version, ibctypes.ValidProof{}, ibctypes.InvalidProof{}, func() { + {"consensus state verification failed", version, func() uint64 { suite.chainB.CreateClient(suite.chainA) - consensusHeight = suite.chainB.Header.Height suite.chainA.CreateClient(suite.chainB) suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.UNINITIALIZED) suite.chainB.updateClient(suite.chainA) + return uint64(suite.chainB.Header.Height) }, false}, } @@ -211,40 +200,35 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset - tc.malleate() + consensusHeight := tc.malleate() - // connectionKey := ibctypes.KeyConnection(testConnectionIDB) - // proofTry, proofHeight := suite.queryProof(connectionKey) + connectionKey := ibctypes.KeyConnection(testConnectionIDB) + proofTry, proofHeight := queryProof(suite.chainB, connectionKey) - // consensusKey := ibctypes.KeyConsensusState(testClientIDB, uint64(proofHeight)) - // proofConsensus, consensusHeight := suite.queryProof(consensusKey) + consensusKey := ibctypes.KeyConsensusState(testClientIDA, uint64(consensusHeight)) + proofConsensus, _ := queryProof(suite.chainB, consensusKey) err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenAck( - suite.chainA.GetContext(), testConnectionIDA, tc.version, tc.proofTry, tc.proofConsensus, - uint64(proofHeight), uint64(consensusHeight), + suite.chainA.GetContext(), testConnectionIDA, tc.version, proofTry, proofConsensus, + uint64(proofHeight+1), consensusHeight, ) if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + suite.Require().NoError(err, "valid test case %d failed with consensus height %d: %s", i, consensusHeight, tc.msg) } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) + suite.Require().Error(err, "invalid test case %d passed with consensus height %d: %s", i, consensusHeight, tc.msg) } }) } } -// TestConnOpenAck - Chain B (ID #2) calls ConnOpenConfirm to confirm that +// TestConnOpenConfirm - Chain B (ID #2) calls ConnOpenConfirm to confirm that // Chain A (ID #1) state is now OPEN. func (suite *KeeperTestSuite) TestConnOpenConfirm() { - // consensusHeight := int64(0) - proofHeight := int64(0) - testCases := []testCase{ {"success", func() { suite.chainB.CreateClient(suite.chainA) suite.chainA.CreateClient(suite.chainB) - proofHeight = suite.chainB.Header.Height - // consensusHeight = suite.chainA.Header.Height suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.OPEN) suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) suite.chainB.updateClient(suite.chainA) @@ -252,19 +236,15 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { {"connection not found", func() {}, false}, {"chain B's connection state is not TRYOPEN", func() { suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.UNINITIALIZED) - }, false}, - {"consensus state not found", func() { - suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) + suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, exported.OPEN) suite.chainA.updateClient(suite.chainB) }, false}, {"connection state verification failed", func() { suite.chainB.CreateClient(suite.chainA) suite.chainA.CreateClient(suite.chainB) - // consensusHeight = suite.chainA.Header.Height - proofHeight = suite.chainB.Header.Height suite.chainB.updateClient(suite.chainA) - suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.INIT) - suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, exported.TRYOPEN) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.INIT) + suite.chainB.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, exported.TRYOPEN) suite.chainA.updateClient(suite.chainA) }, false}, } @@ -276,17 +256,17 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { tc.malleate() - // connectionKey := ibctypes.KeyConnection(testConnectionIDB) - // proofAck, proofHeight := suite.queryProof(connectionKey) + connectionKey := ibctypes.KeyConnection(testConnectionIDA) + proofAck, proofHeight := queryProof(suite.chainA, connectionKey) if tc.expPass { err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( - suite.chainB.GetContext(), testConnectionIDB, ibctypes.ValidProof{}, uint64(proofHeight), + suite.chainB.GetContext(), testConnectionIDB, proofAck, uint64(proofHeight+1), ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( - suite.chainB.GetContext(), testConnectionIDB, ibctypes.InvalidProof{}, uint64(proofHeight), + suite.chainB.GetContext(), testConnectionIDB, proofAck, uint64(proofHeight+1), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 2ed104744b71..423cd588bd18 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -61,10 +61,10 @@ func (suite *KeeperTestSuite) SetupTest() { } // nolint: unused -func (suite *KeeperTestSuite) queryProof(key []byte) (commitmenttypes.MerkleProof, int64) { - res := suite.chainA.App.Query(abci.RequestQuery{ +func queryProof(chain *TestChain, key []byte) (commitmenttypes.MerkleProof, uint64) { + res := chain.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", storeKey), - Height: suite.chainA.App.LastBlockHeight(), + Height: chain.App.LastBlockHeight(), Data: key, Prove: true, }) @@ -73,7 +73,7 @@ func (suite *KeeperTestSuite) queryProof(key []byte) (commitmenttypes.MerkleProo Proof: res.Proof, } - return proof, res.Height + return proof, uint64(res.Height) } func TestKeeperTestSuite(t *testing.T) { suite.Run(t, new(KeeperTestSuite)) @@ -122,6 +122,9 @@ func (suite KeeperTestSuite) TestGetAllConnections() { suite.Require().ElementsMatch(expConnections, connections) } +// TestChain is a testing struct that wraps a simapp with the latest Header, Vals and Signers +// It also contains a field called ClientID. This is the clientID that *other* chains use +// to refer to this TestChain. For simplicity's sake it is also the chainID on the TestChain Header type TestChain struct { ClientID string App *simapp.SimApp @@ -135,7 +138,7 @@ func NewTestChain(clientID string) *TestChain { validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) signers := []tmtypes.PrivValidator{privVal} - now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) + now := time.Now() header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) @@ -171,12 +174,18 @@ func (chain *TestChain) CreateClient(client *TestChain) error { validators := []staking.Validator{validator} histInfo := staking.HistoricalInfo{ Header: abci.Header{ + Time: client.Header.Time, AppHash: commitID.Hash, }, Valset: validators, } client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) + // also set staking params + stakingParams := staking.DefaultParams() + stakingParams.HistoricalEntries = 10 + client.App.StakingKeeper.SetParams(ctxClient, stakingParams) + // Create target ctx ctxTarget := chain.GetContext() @@ -218,8 +227,15 @@ func (chain *TestChain) updateClient(client *TestChain) { // always commit when updateClient and begin a new block client.App.Commit() commitID := client.App.LastCommitID() - client.Header = nextHeader(client) + + /* + err := chain.App.IBCKeeper.ClientKeeper.UpdateClient(ctxTarget, client.ClientID, client.Header) + if err != nil { + panic(err) + } + */ + client.App.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: client.Header.Height, Time: client.Header.Time}}) // Set HistoricalInfo on client chain after Commit @@ -232,6 +248,7 @@ func (chain *TestChain) updateClient(client *TestChain) { validators := []staking.Validator{validator} histInfo := staking.HistoricalInfo{ Header: abci.Header{ + Time: client.Header.Time, AppHash: commitID.Hash, }, Valset: validators, @@ -239,8 +256,9 @@ func (chain *TestChain) updateClient(client *TestChain) { client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) consensusState := ibctmtypes.ConsensusState{ - Height: uint64(client.Header.Height), - Timestamp: client.Header.Time, + Height: uint64(client.Header.Height), + // FIXME: currently commented out due to time normalisation issues. + //Timestamp: client.Header.Time, Root: commitmenttypes.NewMerkleRoot(commitID.Hash), ValidatorSet: client.Vals, } @@ -296,5 +314,5 @@ func (chain *TestChain) createChannel( func nextHeader(chain *TestChain) ibctmtypes.Header { return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, - chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) + time.Now(), chain.Vals, chain.Vals, chain.Signers) } diff --git a/x/ibc/03-connection/keeper/verify.go b/x/ibc/03-connection/keeper/verify.go index aea829d922d5..4524444fe07b 100644 --- a/x/ibc/03-connection/keeper/verify.go +++ b/x/ibc/03-connection/keeper/verify.go @@ -16,6 +16,7 @@ func (k Keeper) VerifyClientConsensusState( ctx sdk.Context, connection exported.ConnectionI, height uint64, + consensusHeight uint64, proof commitmentexported.Proof, consensusState clientexported.ConsensusState, ) error { @@ -25,8 +26,13 @@ func (k Keeper) VerifyClientConsensusState( return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) } + targetConsState, found := k.clientKeeper.GetClientConsensusState(ctx, clientID, height) + if !found { + return sdkerrors.Wrapf(clienttypes.ErrConsensusStateNotFound, "clientID: %s with height: %d", clientID, height) + } + return clientState.VerifyClientConsensusState( - k.cdc, height, connection.GetCounterparty().GetPrefix(), proof, consensusState, + k.cdc, targetConsState.GetRoot(), height, connection.GetCounterparty().GetClientID(), consensusHeight, connection.GetCounterparty().GetPrefix(), proof, consensusState, ) } diff --git a/x/ibc/03-connection/keeper/verify_test.go b/x/ibc/03-connection/keeper/verify_test.go index 39a817a13d49..bd48000da1c3 100644 --- a/x/ibc/03-connection/keeper/verify_test.go +++ b/x/ibc/03-connection/keeper/verify_test.go @@ -3,10 +3,10 @@ package keeper_test import ( "fmt" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" - commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -20,11 +20,11 @@ const ( ) func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { + // create connection on chainA to chainB counterparty := types.NewCounterparty( testClientIDA, testConnectionIDA, suite.chainA.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), ) - connection1 := types.NewConnectionEnd( exported.UNINITIALIZED, testClientIDB, counterparty, types.GetCompatibleVersions(), @@ -33,16 +33,21 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { cases := []struct { msg string connection types.ConnectionEnd - proof commitmentexported.Proof - malleate func() + malleate func() clientexported.ConsensusState expPass bool }{ - {"verification success", connection1, ibctypes.ValidProof{}, func() { + {"verification success", connection1, func() clientexported.ConsensusState { suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) + consState := suite.chainA.Header.ConsensusState() + return consState }, true}, - {"client state not found", connection1, ibctypes.ValidProof{}, func() {}, false}, - {"verification failed", connection1, ibctypes.InvalidProof{}, func() { + {"client state not found", connection1, func() clientexported.ConsensusState { + return suite.chainB.Header.ConsensusState() + }, false}, + {"verification failed", connection1, func() clientexported.ConsensusState { suite.chainA.CreateClient(suite.chainA) + return suite.chainA.Header.ConsensusState() }, false}, } @@ -53,15 +58,21 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset - tc.malleate() - proofHeight := uint64(suite.chainB.Header.Height) + consState := tc.malleate() + + // perform a couple updates of chain B on chain A + suite.chainA.updateClient(suite.chainB) + suite.chainA.updateClient(suite.chainB) - // TODO: remove mocked types and uncomment - // consensusKey := ibctypes.KeyConsensusState(testClientIDA, uint64(suite.app.LastBlockHeight())) - // proof, proofHeight := suite.queryProof(consensusKey) + // TODO: is this the right consensus height + consensusHeight := uint64(suite.chainA.Header.Height) + consensusKey := ibctypes.KeyConsensusState(testClientIDA, consensusHeight) + + // get proof that chainB stored chainA' consensus state + proof, proofHeight := queryProof(suite.chainB, consensusKey) err := suite.chainA.App.IBCKeeper.ConnectionKeeper.VerifyClientConsensusState( - suite.chainA.GetContext(), tc.connection, proofHeight, tc.proof, suite.chainB.Header.ConsensusState(), + suite.chainA.GetContext(), tc.connection, proofHeight+1, consensusHeight, proof, consState, ) if tc.expPass { @@ -74,21 +85,23 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { } func (suite *KeeperTestSuite) TestVerifyConnectionState() { - // connectionKey := ibctypes.KeyConnection(testConnectionIDA) + connectionKey := ibctypes.KeyConnection(testConnectionIDA) + var invalidProofHeight uint64 cases := []struct { msg string - proof commitmentexported.Proof malleate func() expPass bool }{ - {"verification success", ibctypes.ValidProof{}, func() { + {"verification success", func() { suite.chainA.CreateClient(suite.chainB) suite.chainB.CreateClient(suite.chainA) + invalidProofHeight = 0 // don't use this }, true}, - {"client state not found", ibctypes.ValidProof{}, func() {}, false}, - {"verification failed", ibctypes.InvalidProof{}, func() { + {"client state not found", func() {}, false}, + {"verification failed", func() { suite.chainA.CreateClient(suite.chainB) suite.chainB.CreateClient(suite.chainA) + invalidProofHeight = 10 // make proofHeight incorrect }, false}, } @@ -106,19 +119,24 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { expectedConnection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, exported.OPEN) // // create expected connection + // TODO: why is this commented // expectedConnection := types.NewConnectionEnd(exported.INIT, testClientIDB, counterparty, []string{"1.0.0"}) // perform a couple updates of chain A on chain B suite.chainB.updateClient(suite.chainA) suite.chainB.updateClient(suite.chainA) - proofHeight := uint64(suite.chainA.Header.Height) - // proof, proofHeight := suite.queryProof(connectionKey) + proof, proofHeight := queryProof(suite.chainA, connectionKey) + // if invalidProofHeight has been set, use that value instead + if invalidProofHeight != 0 { + proofHeight = invalidProofHeight + } + // Create B's connection to A counterparty := types.NewCounterparty(testClientIDB, testConnectionIDA, commitmenttypes.NewMerklePrefix([]byte("ibc"))) connection := types.NewConnectionEnd(exported.UNINITIALIZED, testClientIDA, counterparty, []string{"1.0.0"}) // Ensure chain B can verify connection exists in chain A err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyConnectionState( - suite.chainB.GetContext(), connection, proofHeight, tc.proof, testConnectionIDA, expectedConnection, + suite.chainB.GetContext(), connection, proofHeight+1, proof, testConnectionIDA, expectedConnection, ) if tc.expPass { @@ -131,22 +149,33 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { } func (suite *KeeperTestSuite) TestVerifyChannelState() { - // channelKey := ibctypes.KeyChannel(testPort1, testChannel1) + channelKey := ibctypes.KeyChannel(testPort1, testChannel1) + + // create connection of chainB to pass into verify function + counterparty := types.NewCounterparty( + testClientIDB, testConnectionIDB, + suite.chainA.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(), + ) + + connection := types.NewConnectionEnd( + exported.UNINITIALIZED, testClientIDA, counterparty, + types.GetCompatibleVersions(), + ) + cases := []struct { msg string - proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool }{ - {"verification success", ibctypes.ValidProof{}, 2, func() { + {"verification success", 0, func() { suite.chainB.CreateClient(suite.chainA) }, true}, - {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, - {"consensus state not found", ibctypes.ValidProof{}, 100, func() { + {"client state not found", 0, func() {}, false}, + {"consensus state not found", 100, func() { suite.chainB.CreateClient(suite.chainA) }, false}, - {"verification failed", ibctypes.InvalidProof{}, 2, func() { + {"verification failed", 7, func() { suite.chainB.CreateClient(suite.chainB) }, false}, } @@ -160,7 +189,6 @@ func (suite *KeeperTestSuite) TestVerifyChannelState() { tc.malleate() // Create and store channel on chain A - connection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.OPEN) channel := suite.chainA.createChannel( testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnectionIDA, @@ -170,9 +198,14 @@ func (suite *KeeperTestSuite) TestVerifyChannelState() { suite.chainB.updateClient(suite.chainA) // Check that Chain B can verify channel is stored on chainA - // proof, proofHeight := suite.queryProof(channelKey) + proof, proofHeight := queryProof(suite.chainA, channelKey) + // if testcase proofHeight is not 0, replace proofHeight with this value + if tc.proofHeight != 0 { + proofHeight = tc.proofHeight + } + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyChannelState( - suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, + suite.chainB.GetContext(), connection, proofHeight+1, proof, testPort1, testChannel1, channel, ) @@ -186,24 +219,20 @@ func (suite *KeeperTestSuite) TestVerifyChannelState() { } func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { - // commitmentKey := ibctypes.KeyPacketCommitment(testPort1, testChannel1, 1) + commitmentKey := ibctypes.KeyPacketCommitment(testPort1, testChannel1, 1) commitmentBz := []byte("commitment") cases := []struct { msg string - proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool }{ - {"verification success", ibctypes.ValidProof{}, 2, func() { + {"verification success", 0, func() { suite.chainB.CreateClient(suite.chainA) }, true}, - {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, - {"consensus state not found", ibctypes.ValidProof{}, 100, func() { - suite.chainB.CreateClient(suite.chainA) - }, false}, - {"verification failed", ibctypes.InvalidProof{}, 2, func() { + {"client state not found", 0, func() {}, false}, + {"consensus state not found", 100, func() { suite.chainB.CreateClient(suite.chainA) }, false}, } @@ -225,9 +254,14 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { suite.chainB.updateClient(suite.chainA) // Check that ChainB can verify PacketCommitment stored in chainA - // proof, proofHeight := suite.queryProof(commitmentKey) + proof, proofHeight := queryProof(suite.chainA, commitmentKey) + // if testcase proofHeight is not 0, replace proofHeight with this value + if tc.proofHeight != 0 { + proofHeight = tc.proofHeight + } + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyPacketCommitment( - suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, + suite.chainB.GetContext(), connection, proofHeight+1, proof, testPort1, testChannel1, 1, commitmentBz, ) @@ -241,26 +275,22 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { } func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { - // packetAckKey := ibctypes.KeyPacketAcknowledgement(testPort1, testChannel1, 1) + packetAckKey := ibctypes.KeyPacketAcknowledgement(testPort1, testChannel1, 1) ack := []byte("acknowledgement") cases := []struct { msg string - proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool }{ - {"verification success", ibctypes.ValidProof{}, 2, func() { + {"verification success", 0, func() { suite.chainB.CreateClient(suite.chainA) }, true}, - {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, - {"consensus state not found", ibctypes.ValidProof{}, 100, func() { + {"client state not found", 0, func() {}, false}, + {"consensus state not found", 100, func() { suite.chainB.CreateClient(suite.chainA) }, false}, - {"verification failed", ibctypes.InvalidProof{}, 2, func() { - suite.chainB.CreateClient(suite.chainB) - }, false}, } for i, tc := range cases { @@ -272,10 +302,16 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { connection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.OPEN) suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), testPort1, testChannel1, 1, ack) suite.chainB.updateClient(suite.chainA) - // proof, proofHeight := suite.queryProof(packetAckKey) + + // TODO check this proof height + proof, proofHeight := queryProof(suite.chainA, packetAckKey) + // if testcase proofHeight is not 0, replace proofHeight with this value + if tc.proofHeight != 0 { + proofHeight = tc.proofHeight + } err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgement( - suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, + suite.chainB.GetContext(), connection, proofHeight+1, proof, testPort1, testChannel1, 1, ack, ) @@ -289,25 +325,21 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { } func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { - // packetAckKey := ibctypes.KeyPacketAcknowledgement(testPort1, testChannel1, 1) + packetAckKey := ibctypes.KeyPacketAcknowledgement(testPort1, testChannel1, 1) cases := []struct { msg string - proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool }{ - {"verification success", ibctypes.ValidProof{}, 2, func() { + {"verification success", 0, func() { suite.chainB.CreateClient(suite.chainA) }, true}, - {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, - {"consensus state not found", ibctypes.ValidProof{}, 100, func() { + {"client state not found", 0, func() {}, false}, + {"consensus state not found", 100, func() { suite.chainB.CreateClient(suite.chainA) }, false}, - {"verification failed", ibctypes.InvalidProof{}, 2, func() { - suite.chainB.CreateClient(suite.chainB) - }, false}, } for i, tc := range cases { @@ -319,10 +351,14 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { connection := suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, exported.OPEN) suite.chainB.updateClient(suite.chainA) - // proof, proofHeight := suite.queryProof(packetAckKey) + proof, proofHeight := queryProof(suite.chainA, packetAckKey) + // if testcase proofHeight is not 0, replace proofHeight with this value + if tc.proofHeight != 0 { + proofHeight = tc.proofHeight + } err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyPacketAcknowledgementAbsence( - suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, + suite.chainB.GetContext(), connection, proofHeight+1, proof, testPort1, testChannel1, 1, ) @@ -336,25 +372,21 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { } func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { - // nextSeqRcvKey := ibctypes.KeyNextSequenceRecv(testPort1, testChannel1) + nextSeqRcvKey := ibctypes.KeyNextSequenceRecv(testPort1, testChannel1) cases := []struct { msg string - proof commitmentexported.Proof proofHeight uint64 malleate func() expPass bool }{ - {"verification success", ibctypes.ValidProof{}, 2, func() { + {"verification success", uint64(0), func() { suite.chainB.CreateClient(suite.chainA) }, true}, - {"client state not found", ibctypes.ValidProof{}, 2, func() {}, false}, - {"consensus state not found", ibctypes.ValidProof{}, 100, func() { + {"client state not found", uint64(0), func() {}, false}, + {"consensus state not found", uint64(100), func() { suite.chainB.CreateClient(suite.chainA) }, false}, - {"verification failed", ibctypes.InvalidProof{}, 2, func() { - suite.chainB.CreateClient(suite.chainB) - }, false}, } for i, tc := range cases { @@ -367,9 +399,14 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainA.GetContext(), testPort1, testChannel1, 1) suite.chainB.updateClient(suite.chainA) - // proof, proofHeight := suite.queryProof(nextSeqRcvKey) + proof, proofHeight := queryProof(suite.chainA, nextSeqRcvKey) + // if testcase proofHeight is not 0, replace proofHeight with this value + if tc.proofHeight != 0 { + proofHeight = tc.proofHeight + } + err := suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyNextSequenceRecv( - suite.chainB.GetContext(), connection, tc.proofHeight, tc.proof, testPort1, + suite.chainB.GetContext(), connection, proofHeight+1, proof, testPort1, testChannel1, 1, ) diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 2b5257b8e61b..7cc6f9eba755 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -6,6 +6,7 @@ import ( connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) func (suite *KeeperTestSuite) TestChanOpenInit() { @@ -54,14 +55,19 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { func (suite *KeeperTestSuite) TestChanOpenTry() { counterparty := types.NewCounterparty(testPort1, testChannel1) + channelKey := ibctypes.KeyChannel(testPort1, testChannel1) testCases := []testCase{ {"success", func() { suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) _ = suite.chainA.createConnection( testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN, ) + suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.INIT, exported.ORDERED, testConnectionIDA) }, true}, {"previous channel with invalid state", func() { _ = suite.chainA.createChannel( @@ -97,13 +103,15 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { tc.malleate() - proofHeight := suite.chainB.Header.Height + suite.chainA.updateClient(suite.chainB) + suite.chainB.updateClient(suite.chainA) + proof, proofHeight := queryProof(suite.chainB, channelKey) if tc.expPass { err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenTry( suite.chainA.GetContext(), exported.ORDERED, []string{testConnectionIDB}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, - validProof{}, uint64(proofHeight), + proof, proofHeight+1, ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { @@ -119,15 +127,26 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { } func (suite *KeeperTestSuite) TestChanOpenAck() { + channelKey := ibctypes.KeyChannel(testPort2, testChannel2) + testCases := []testCase{ {"success", func() { + suite.chainA.CreateClient(suite.chainB) suite.chainB.CreateClient(suite.chainA) + suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, + connectionexported.OPEN, + ) _ = suite.chainB.createConnection( testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN, ) - _ = suite.chainB.createChannel( - testPort1, testChannel1, testPort2, testChannel2, exported.TRYOPEN, + _ = suite.chainA.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.INIT, + exported.ORDERED, testConnectionIDB, + ) + suite.chainB.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, exported.ORDERED, testConnectionIDA, ) }, true}, @@ -183,17 +202,20 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { tc.malleate() - proofHeight := suite.chainA.Header.Height + suite.chainA.updateClient(suite.chainB) + suite.chainB.updateClient(suite.chainA) + proof, proofHeight := queryProof(suite.chainB, channelKey) + if tc.expPass { - err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenAck( - suite.chainB.GetContext(), testPort1, testChannel1, testChannelVersion, - validProof{}, uint64(proofHeight), + err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenAck( + suite.chainA.GetContext(), testPort1, testChannel1, testChannelVersion, + proof, proofHeight+1, ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenAck( - suite.chainB.GetContext(), testPort1, testChannel1, testChannelVersion, - invalidProof{}, uint64(proofHeight), + err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenAck( + suite.chainA.GetContext(), testPort1, testChannel1, testChannelVersion, + invalidProof{}, proofHeight+1, ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -202,17 +224,26 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { } func (suite *KeeperTestSuite) TestChanOpenConfirm() { + channelKey := ibctypes.KeyChannel(testPort2, testChannel2) + testCases := []testCase{ {"success", func() { suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) _ = suite.chainA.createConnection( testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, + connectionexported.TRYOPEN, + ) + suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN, ) _ = suite.chainA.createChannel( - testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, + testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDB, ) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, + exported.TRYOPEN, exported.ORDERED, testConnectionIDA) }, true}, {"channel doesn't exist", func() {}, false}, {"channel state is not TRYOPEN", func() { @@ -266,17 +297,20 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { tc.malleate() - proofHeight := suite.chainB.Header.Height + suite.chainA.updateClient(suite.chainB) + suite.chainB.updateClient(suite.chainA) + proof, proofHeight := queryProof(suite.chainA, channelKey) + if tc.expPass { - err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenConfirm( - suite.chainA.GetContext(), testPort2, testChannel2, - validProof{}, uint64(proofHeight), + err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenConfirm( + suite.chainB.GetContext(), testPort1, testChannel1, + proof, proofHeight+1, ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { - err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenConfirm( - suite.chainA.GetContext(), testPort2, testChannel2, - invalidProof{}, uint64(proofHeight), + err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenConfirm( + suite.chainB.GetContext(), testPort1, testChannel1, + invalidProof{}, proofHeight+1, ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -341,17 +375,28 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { } func (suite *KeeperTestSuite) TestChanCloseConfirm() { + channelKey := ibctypes.KeyChannel(testPort1, testChannel1) + testCases := []testCase{ {"success", func() { + suite.chainA.CreateClient(suite.chainB) suite.chainB.CreateClient(suite.chainA) _ = suite.chainB.createConnection( testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, connectionexported.OPEN, ) + suite.chainA.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, + connectionexported.OPEN, + ) _ = suite.chainB.createChannel( testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDB, ) + suite.chainA.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, + exported.ORDERED, testConnectionIDA, + ) }, true}, {"channel doesn't exist", func() {}, false}, {"channel state is CLOSED", func() { @@ -405,11 +450,14 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { tc.malleate() - proofHeight := suite.chainA.Header.Height + suite.chainA.updateClient(suite.chainB) + suite.chainB.updateClient(suite.chainA) + proof, proofHeight := queryProof(suite.chainA, channelKey) + if tc.expPass { err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanCloseConfirm( suite.chainB.GetContext(), testPort2, testChannel2, - validProof{}, uint64(proofHeight), + proof, proofHeight+1, ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index c65d32dab4c4..f68fe078e21e 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "bytes" "errors" "fmt" "testing" @@ -207,10 +208,10 @@ func commitNBlocks(chain *TestChain, n int) { } // nolint: unused -func (suite *KeeperTestSuite) queryProof(key []byte) (commitmenttypes.MerkleProof, int64) { - res := suite.chainB.App.Query(abci.RequestQuery{ +func queryProof(chain *TestChain, key []byte) (commitmenttypes.MerkleProof, uint64) { + res := chain.App.Query(abci.RequestQuery{ Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Height: suite.chainB.App.LastBlockHeight(), + Height: chain.App.LastBlockHeight(), Data: key, Prove: true, }) @@ -219,7 +220,7 @@ func (suite *KeeperTestSuite) queryProof(key []byte) (commitmenttypes.MerkleProo Proof: res.Proof, } - return proof, res.Height + return proof, uint64(res.Height) } type TestChain struct { @@ -403,12 +404,16 @@ func nextHeader(chain *TestChain) ibctmtypes.Header { // TODO: fix tests and replace for real proofs var ( - _ commitmentexported.Proof = validProof{} + _ commitmentexported.Proof = validProof{nil, nil, nil} _ commitmentexported.Proof = invalidProof{} ) type ( - validProof struct{} + validProof struct { + root commitmentexported.Root + path commitmentexported.Path + value []byte + } invalidProof struct{} ) @@ -416,9 +421,15 @@ func (validProof) GetCommitmentType() commitmentexported.Type { return commitmentexported.Merkle } -func (validProof) VerifyMembership( - root commitmentexported.Root, path commitmentexported.Path, value []byte) error { - return nil +func (proof validProof) VerifyMembership( + root commitmentexported.Root, path commitmentexported.Path, value []byte, +) error { + if bytes.Equal(root.GetHash(), proof.root.GetHash()) && + path.String() == proof.path.String() && + bytes.Equal(value, proof.value) { + return nil + } + return errors.New("invalid proof") } func (validProof) VerifyNonMembership(root commitmentexported.Root, path commitmentexported.Path) error { diff --git a/x/ibc/04-channel/keeper/packet_test.go b/x/ibc/04-channel/keeper/packet_test.go index e65932a09a82..ca5239ca5a09 100644 --- a/x/ibc/04-channel/keeper/packet_test.go +++ b/x/ibc/04-channel/keeper/packet_test.go @@ -96,18 +96,23 @@ func (suite *KeeperTestSuite) TestSendPacket() { } func (suite *KeeperTestSuite) TestRecvPacket() { - counterparty := types.NewCounterparty(testPort2, testChannel2) + counterparty := types.NewCounterparty(testPort1, testChannel1) + packetKey := ibctypes.KeyPacketCommitment(testPort2, testChannel2, 1) + var packet exported.PacketI testCases := []testCase{ {"success", func() { suite.chainB.CreateClient(suite.chainA) + suite.chainA.CreateClient(suite.chainB) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) - suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainB.GetContext(), testPort1, testChannel1, 1) - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.chainB.updateClient(suite.chainA) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDB) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort2, testChannel2, 1) + packet = types.NewPacket(mockSuccessPacket{}, 1, testPort2, testChannel2, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), testPort2, testChannel2, 1, types.CommitPacket(packet.(types.Packet).Data)) + }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { @@ -149,11 +154,15 @@ func (suite *KeeperTestSuite) TestRecvPacket() { suite.SetupTest() // reset tc.malleate() - proofHeight := uint64(suite.chainA.Header.Height) ctx := suite.chainB.GetContext() + + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) + proof, proofHeight := queryProof(suite.chainA, packetKey) + var err error if tc.expPass { - packet, err = suite.chainB.App.IBCKeeper.ChannelKeeper.RecvPacket(ctx, packet, ibctypes.ValidProof{}, proofHeight) + _, err = suite.chainB.App.IBCKeeper.ChannelKeeper.RecvPacket(ctx, packet, proof, proofHeight+1) suite.Require().NoError(err) } else { packet, err = suite.chainB.App.IBCKeeper.ChannelKeeper.RecvPacket(ctx, packet, ibctypes.InvalidProof{}, proofHeight) @@ -215,6 +224,7 @@ func (suite *KeeperTestSuite) TestPacketExecuted() { func (suite *KeeperTestSuite) TestAcknowledgePacket() { counterparty := types.NewCounterparty(testPort2, testChannel2) var packet types.Packet + packetKey := ibctypes.KeyPacketAcknowledgement(testPort2, testChannel2, 1) ack := transfertypes.AckDataTransfer{} @@ -222,9 +232,13 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { {"success", func() { packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.CreateClient(suite.chainA) + suite.chainA.CreateClient(suite.chainB) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDB) suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), testPort2, testChannel2, 1, ack.GetBytes()) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { @@ -267,14 +281,17 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { suite.SetupTest() // reset tc.malleate() + suite.chainA.updateClient(suite.chainB) + suite.chainB.updateClient(suite.chainA) + proof, proofHeight := queryProof(suite.chainA, packetKey) + ctx := suite.chainB.GetContext() - proofHeight := uint64(suite.chainA.Header.Height) if tc.expPass { - packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.AcknowledgePacket(ctx, packet, ack, ibctypes.ValidProof{}, proofHeight) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.AcknowledgePacket(ctx, packet, ack, proof, proofHeight+1) suite.Require().NoError(err) suite.Require().NotNil(packetOut) } else { - packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.AcknowledgePacket(ctx, packet, ack, ibctypes.InvalidProof{}, proofHeight) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.AcknowledgePacket(ctx, packet, ack, proof, proofHeight+1) suite.Require().Error(err) suite.Require().Nil(packetOut) } @@ -284,6 +301,7 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { func (suite *KeeperTestSuite) TestCleanupPacket() { counterparty := types.NewCounterparty(testPort2, testChannel2) + packetKey := ibctypes.KeyPacketAcknowledgement(testPort2, testChannel2, 1) var ( packet types.Packet nextSeqRecv uint64 @@ -295,10 +313,14 @@ func (suite *KeeperTestSuite) TestCleanupPacket() { {"success", func() { nextSeqRecv = 10 packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + suite.chainA.CreateClient(suite.chainB) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.UNORDERED, testConnectionIDB) suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), testPort2, testChannel2, 1, ack) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { @@ -356,13 +378,17 @@ func (suite *KeeperTestSuite) TestCleanupPacket() { tc.malleate() ctx := suite.chainB.GetContext() - proofHeight := uint64(suite.chainA.Header.Height) + + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) + proof, proofHeight := queryProof(suite.chainA, packetKey) + if tc.expPass { - packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.CleanupPacket(ctx, packet, ibctypes.ValidProof{}, proofHeight, nextSeqRecv, ack) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.CleanupPacket(ctx, packet, proof, proofHeight+1, nextSeqRecv, ack) suite.Require().NoError(err) suite.Require().NotNil(packetOut) } else { - packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.CleanupPacket(ctx, packet, ibctypes.InvalidProof{}, proofHeight, nextSeqRecv, ack) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.CleanupPacket(ctx, packet, ibctypes.InvalidProof{}, proofHeight+1, nextSeqRecv, ack) suite.Require().Error(err) suite.Require().Nil(packetOut) } diff --git a/x/ibc/04-channel/keeper/timeout_test.go b/x/ibc/04-channel/keeper/timeout_test.go index 917b80adbb6a..5b406e2bdb74 100644 --- a/x/ibc/04-channel/keeper/timeout_test.go +++ b/x/ibc/04-channel/keeper/timeout_test.go @@ -6,16 +6,15 @@ import ( connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) func (suite *KeeperTestSuite) TestTimeoutPacket() { counterparty := types.NewCounterparty(testPort2, testChannel2) + packetKey := ibctypes.KeyPacketAcknowledgement(testPort2, testChannel2, 2) var ( packet types.Packet nextSeqRecv uint64 - proofHeight uint64 = 3 ) testCases := []testCase{ @@ -23,9 +22,11 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { nextSeqRecv = 1 packet = types.NewPacket(newMockTimeoutPacket(1), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.CreateClient(suite.chainA) - proofHeight = uint64(suite.chainA.Header.Height) + suite.chainA.CreateClient(suite.chainB) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.UNORDERED, testConnectionIDB) suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) }, true}, {"channel not found", func() {}, false}, @@ -46,28 +47,24 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"timeout", func() { - proofHeight = 1 packet = types.NewPacket(mockSuccessPacket{}, 10, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet already received ", func() { nextSeqRecv = 2 - proofHeight = 100 packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet hasn't been sent", func() { nextSeqRecv = 1 - proofHeight = 100 packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"next seq receive verification failed", func() { nextSeqRecv = 1 - proofHeight = uint64(suite.chainA.Header.Height) packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) @@ -75,7 +72,6 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { }, false}, {"packet ack verification failed", func() { nextSeqRecv = 1 - proofHeight = 100 packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) @@ -89,12 +85,17 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { tc.malleate() ctx := suite.chainB.GetContext() + + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) + proof, proofHeight := queryProof(suite.chainA, packetKey) + if tc.expPass { - packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutPacket(ctx, packet, ibctypes.ValidProof{}, proofHeight, nextSeqRecv) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutPacket(ctx, packet, proof, proofHeight+1, nextSeqRecv) suite.Require().NoError(err) suite.Require().NotNil(packetOut) } else { - packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutPacket(ctx, packet, ibctypes.InvalidProof{}, proofHeight, nextSeqRecv) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutPacket(ctx, packet, ibctypes.InvalidProof{}, proofHeight+1, nextSeqRecv) suite.Require().Error(err) suite.Require().Nil(packetOut) } @@ -131,22 +132,23 @@ func (suite *KeeperTestSuite) TestTimeoutExecuted() { } func (suite *KeeperTestSuite) TestTimeoutOnClose() { + channelKey := ibctypes.KeyChannel(testPort2, testChannel2) + packetKey := ibctypes.KeyPacketAcknowledgement(testPort1, testChannel1, 2) counterparty := types.NewCounterparty(testPort2, testChannel2) var ( packet types.Packet nextSeqRecv uint64 - proofHeight uint64 = 1 - proof commitmentexported.Proof = ibctypes.InvalidProof{} - proofClosed commitmentexported.Proof = ibctypes.InvalidProof{} ) testCases := []testCase{ {"success", func() { packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.CreateClient(suite.chainA) - proofHeight = uint64(suite.chainA.Header.Height) + suite.chainA.CreateClient(suite.chainB) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) + suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.CLOSED, exported.UNORDERED, testConnectionIDB) // channel on chainA is closed suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, true}, @@ -171,27 +173,22 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { {"channel verification failed", func() { packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.CreateClient(suite.chainA) - proofHeight = uint64(suite.chainA.Header.Height) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, false}, {"next seq receive verification failed", func() { - proofClosed = ibctypes.ValidProof{} packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.CreateClient(suite.chainA) - proofHeight = uint64(suite.chainA.Header.Height) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, false}, {"packet ack verification failed", func() { - proofClosed = ibctypes.ValidProof{} packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) suite.chainB.CreateClient(suite.chainA) - proofHeight = uint64(suite.chainA.Header.Height) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) @@ -205,13 +202,18 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { suite.SetupTest() // reset tc.malleate() + suite.chainB.updateClient(suite.chainA) + suite.chainA.updateClient(suite.chainB) + proofClosed, proofHeight := queryProof(suite.chainA, channelKey) + proofAckAbsence, _ := queryProof(suite.chainA, packetKey) + ctx := suite.chainB.GetContext() if tc.expPass { - packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutOnClose(ctx, packet, ibctypes.ValidProof{}, ibctypes.ValidProof{}, proofHeight, nextSeqRecv) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutOnClose(ctx, packet, proofAckAbsence, proofClosed, proofHeight+1, nextSeqRecv) suite.Require().NoError(err) suite.Require().NotNil(packetOut) } else { - packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutOnClose(ctx, packet, proof, proofClosed, proofHeight, nextSeqRecv) + packetOut, err := suite.chainB.App.IBCKeeper.ChannelKeeper.TimeoutOnClose(ctx, packet, invalidProof{}, invalidProof{}, proofHeight+1, nextSeqRecv) suite.Require().Error(err) suite.Require().Nil(packetOut) } diff --git a/x/ibc/07-tendermint/types/client_state.go b/x/ibc/07-tendermint/types/client_state.go index 94cb54250942..ca42a181ea8c 100644 --- a/x/ibc/07-tendermint/types/client_state.go +++ b/x/ibc/07-tendermint/types/client_state.go @@ -106,12 +106,15 @@ func (cs ClientState) IsFrozen() bool { // Tendermint client stored on the target machine. func (cs ClientState) VerifyClientConsensusState( cdc *codec.Codec, + provingRoot commitmentexported.Root, height uint64, + counterpartyClientIdentifier string, + consensusHeight uint64, prefix commitmentexported.Prefix, proof commitmentexported.Proof, consensusState clientexported.ConsensusState, ) error { - path, err := commitmenttypes.ApplyPrefix(prefix, ibctypes.ConsensusStatePath(cs.GetID(), height)) + path, err := commitmenttypes.ApplyPrefix(prefix, ibctypes.ConsensusStatePath(counterpartyClientIdentifier, consensusHeight)) if err != nil { return err } @@ -120,12 +123,12 @@ func (cs ClientState) VerifyClientConsensusState( return err } - bz, err := cdc.MarshalBinaryBare(consensusState) + bz, err := cdc.MarshalBinaryLengthPrefixed(consensusState) if err != nil { return err } - if err := proof.VerifyMembership(consensusState.GetRoot(), path, bz); err != nil { + if err := proof.VerifyMembership(provingRoot, path, bz); err != nil { return sdkerrors.Wrap(clienttypes.ErrFailedClientConsensusStateVerification, err.Error()) } @@ -185,7 +188,7 @@ func (cs ClientState) VerifyChannelState( return err } - bz, err := cdc.MarshalBinaryBare(channel) + bz, err := cdc.MarshalBinaryLengthPrefixed(channel) if err != nil { return err } diff --git a/x/ibc/07-tendermint/types/client_state_test.go b/x/ibc/07-tendermint/types/client_state_test.go index 5eb2705b6cb7..b5d37ca06ad2 100644 --- a/x/ibc/07-tendermint/types/client_state_test.go +++ b/x/ibc/07-tendermint/types/client_state_test.go @@ -25,6 +25,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { proof commitmenttypes.MerkleProof expPass bool }{ + // FIXME: uncomment // { // name: "successful verification", // clientState: ibctmtypes.NewClientState(chainID, chainID, height), @@ -78,7 +79,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { tc := tc err := tc.clientState.VerifyClientConsensusState( - suite.cdc, height, tc.prefix, tc.proof, tc.consensusState, + suite.cdc, tc.consensusState.Root, height, "chainA", tc.consensusState.GetHeight(), tc.prefix, tc.proof, tc.consensusState, ) if tc.expPass { @@ -102,6 +103,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { proof commitmenttypes.MerkleProof expPass bool }{ + // FIXME: uncomment // { // name: "successful verification", // clientState: ibctmtypes.NewClientState(chainID, chainID, height), @@ -184,6 +186,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { proof commitmenttypes.MerkleProof expPass bool }{ + // FIXME: uncomment // { // name: "successful verification", // clientState: ibctmtypes.NewClientState(chainID, height), @@ -263,6 +266,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { proof commitmenttypes.MerkleProof expPass bool }{ + // FIXME: uncomment // { // name: "successful verification", // clientState: ibctmtypes.NewClientState(chainID, height), @@ -342,6 +346,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { proof commitmenttypes.MerkleProof expPass bool }{ + // FIXME: uncomment // { // name: "successful verification", // clientState: ibctmtypes.NewClientState(chainID, chainID, height), @@ -420,6 +425,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { proof commitmenttypes.MerkleProof expPass bool }{ + // FIXME: uncomment // { // name: "successful verification", // clientState: ibctmtypes.NewClientState(chainID, chainID, height), @@ -494,6 +500,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { proof commitmenttypes.MerkleProof expPass bool }{ + // FIXME: uncomment // { // name: "successful verification", // clientState: ibctmtypes.NewClientState(chainID, chainID, height), diff --git a/x/ibc/types/mock.go b/x/ibc/types/mock.go index 43fcd3beadb1..1cbec82adcef 100644 --- a/x/ibc/types/mock.go +++ b/x/ibc/types/mock.go @@ -1,6 +1,7 @@ package types import ( + "bytes" "errors" commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" @@ -10,12 +11,16 @@ import ( // TODO: fix tests and replace for real proofs var ( - _ commitmentexported.Proof = ValidProof{} + _ commitmentexported.Proof = ValidProof{nil, nil, nil} _ commitmentexported.Proof = InvalidProof{} ) type ( - ValidProof struct{} + ValidProof struct { + root commitmentexported.Root + path commitmentexported.Path + value []byte + } InvalidProof struct{} ) @@ -23,9 +28,15 @@ func (ValidProof) GetCommitmentType() commitmentexported.Type { return commitmentexported.Merkle } -func (ValidProof) VerifyMembership( - root commitmentexported.Root, path commitmentexported.Path, value []byte) error { - return nil +func (proof ValidProof) VerifyMembership( + root commitmentexported.Root, path commitmentexported.Path, value []byte, +) error { + if bytes.Equal(root.GetHash(), proof.root.GetHash()) && + path.String() == proof.path.String() && + bytes.Equal(value, proof.value) { + return nil + } + return errors.New("invalid proof") } func (ValidProof) VerifyNonMembership(root commitmentexported.Root, path commitmentexported.Path) error { From c035957865b30fe651017dbdf06e697426654891 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Sat, 7 Mar 2020 10:51:53 -0800 Subject: [PATCH 096/176] Try to fix store decoding issue --- x/staking/simulation/decoder.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x/staking/simulation/decoder.go b/x/staking/simulation/decoder.go index de5d50de9f7d..f56bf511697b 100644 --- a/x/staking/simulation/decoder.go +++ b/x/staking/simulation/decoder.go @@ -51,6 +51,12 @@ func DecodeStore(cdc *codec.Codec, kvA, kvB tmkv.Pair) string { cdc.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &redB) return fmt.Sprintf("%v\n%v", redA, redB) + case bytes.Equal(kvA.Key[:1], types.HistoricalInfoKey): + var histInfoA, histInfoB types.HistoricalInfo + cdc.Seal().MustUnmarshalBinaryLengthPrefixed(kvA.Value, &histInfoA) + cdc.Seal().MustUnmarshalBinaryLengthPrefixed(kvB.Value, &histInfoB) + return fmt.Sprintf("%v\n%v", histInfoA, histInfoB) + default: panic(fmt.Sprintf("invalid staking key prefix %X", kvA.Key[:1])) } From fdd8f7f75d5df629edb53890647e19e0fe9e4194 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Sat, 7 Mar 2020 11:35:34 -0800 Subject: [PATCH 097/176] Sim issue update --- x/staking/simulation/decoder.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/x/staking/simulation/decoder.go b/x/staking/simulation/decoder.go index f56bf511697b..e083df5097a2 100644 --- a/x/staking/simulation/decoder.go +++ b/x/staking/simulation/decoder.go @@ -52,10 +52,9 @@ func DecodeStore(cdc *codec.Codec, kvA, kvB tmkv.Pair) string { return fmt.Sprintf("%v\n%v", redA, redB) case bytes.Equal(kvA.Key[:1], types.HistoricalInfoKey): - var histInfoA, histInfoB types.HistoricalInfo - cdc.Seal().MustUnmarshalBinaryLengthPrefixed(kvA.Value, &histInfoA) - cdc.Seal().MustUnmarshalBinaryLengthPrefixed(kvB.Value, &histInfoB) - return fmt.Sprintf("%v\n%v", histInfoA, histInfoB) + var histInfo types.HistoricalInfo + cdc.Seal().MustUnmarshalBinaryLengthPrefixed(kvA.Value, &histInfo) + return fmt.Sprintf("%v", histInfo) default: panic(fmt.Sprintf("invalid staking key prefix %X", kvA.Key[:1])) From 3818571d25c87c4a4c344cd51975a8ceba1333f2 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Sat, 7 Mar 2020 14:22:55 -0800 Subject: [PATCH 098/176] add error in msg --- x/ibc/07-tendermint/types/msgs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/ibc/07-tendermint/types/msgs.go b/x/ibc/07-tendermint/types/msgs.go index 955d1342ab3f..170c69d2e60a 100644 --- a/x/ibc/07-tendermint/types/msgs.go +++ b/x/ibc/07-tendermint/types/msgs.go @@ -71,8 +71,8 @@ func (msg MsgCreateClient) ValidateBasic() error { return sdkerrors.ErrInvalidAddress } // ValidateBasic of provided header with self-attested chain-id - if msg.Header.ValidateBasic(msg.Header.ChainID) != nil { - return sdkerrors.Wrap(ErrInvalidHeader, "header failed validatebasic with its own chain-id") + if err := msg.Header.ValidateBasic(msg.Header.ChainID); err != nil { + return sdkerrors.Wrapf(ErrInvalidHeader, "header failed validatebasic with its own chain-id: %v", err) } return host.DefaultClientIdentifierValidator(msg.ClientID) } From 18acea155f50489f246a48782844e55125c13597 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Sat, 7 Mar 2020 16:25:07 -0800 Subject: [PATCH 099/176] remove next validator set from ibctmtypes.Header --- x/ibc/02-client/keeper/client_test.go | 24 ++++++++-------- x/ibc/02-client/keeper/keeper_test.go | 4 +-- x/ibc/03-connection/keeper/keeper_test.go | 4 +-- x/ibc/04-channel/keeper/keeper_test.go | 4 +-- x/ibc/07-tendermint/misbehaviour_test.go | 25 ++++++++-------- x/ibc/07-tendermint/tendermint_test.go | 2 +- x/ibc/07-tendermint/types/evidence_test.go | 19 +++++++------ x/ibc/07-tendermint/types/header.go | 7 ----- x/ibc/07-tendermint/types/header_test.go | 2 +- x/ibc/07-tendermint/types/tendermint_test.go | 2 +- x/ibc/07-tendermint/types/test_utils.go | 10 +++---- x/ibc/07-tendermint/update.go | 7 ++++- x/ibc/07-tendermint/update_test.go | 30 +++++++------------- x/ibc/20-transfer/handler_test.go | 4 +-- x/ibc/20-transfer/keeper/keeper_test.go | 4 +-- x/ibc/ante/ante_test.go | 4 +-- 16 files changed, 70 insertions(+), 82 deletions(-) diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index 31edfeec0f21..0221be04f3ab 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -69,11 +69,11 @@ func (suite *KeeperTestSuite) TestUpdateClient() { // Must create header creation functions since suite.header gets recreated on each test case createValidUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header { return ibctmtypes.CreateTestHeader(testClientID, suite.header.Height+1, suite.header.Time.Add(time.Minute), - suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } createInvalidUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header { return ibctmtypes.CreateTestHeader(testClientID, suite.header.Height-3, suite.header.Time.Add(time.Minute), - suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } var updateHeader ibctmtypes.Header @@ -201,8 +201,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusting period misbehavior should pass", ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, suite.valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothSigners), ChainID: testClientID, ClientID: testClientID, }, @@ -221,8 +221,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehavior at later height should pass", ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.ctx.BlockTime(), bothValSet, suite.valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.ctx.BlockTime(), bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.ctx.BlockTime(), bothValSet, bothSigners), ChainID: testClientID, ClientID: testClientID, }, @@ -247,8 +247,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "consensus state not found", ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, suite.valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothSigners), ChainID: testClientID, ClientID: testClientID, }, @@ -262,8 +262,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "consensus state not found", ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, suite.valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothSigners), ChainID: testClientID, ClientID: testClientID, }, @@ -277,8 +277,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehaviour check failed", ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), altValSet, bothValSet, altSigners), + Header1: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testClientID, testClientHeight, suite.ctx.BlockTime(), altValSet, altSigners), ChainID: testClientID, ClientID: testClientID, }, diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index 19a8d99f2f6b..8f02c3d31a82 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -56,7 +56,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.privVal = tmtypes.NewMockPV() validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - suite.header = ibctmtypes.CreateTestHeader(testClientID, testClientHeight, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = ibctmtypes.CreateTestHeader(testClientID, testClientHeight, now2, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.consensusState = ibctmtypes.ConsensusState{ Height: testClientHeight, Timestamp: suite.now, @@ -166,7 +166,7 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() { ValidatorSet: suite.valSet, } - header := ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.header.Time.Add(time.Minute), suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + header := ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.header.Time.Add(time.Minute), suite.valSet, []tmtypes.PrivValidator{suite.privVal}) // mock update functionality clientState.LastHeader = header diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 423cd588bd18..1254e542c2db 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -140,7 +140,7 @@ func NewTestChain(clientID string) *TestChain { signers := []tmtypes.PrivValidator{privVal} now := time.Now() - header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, signers) return &TestChain{ ClientID: clientID, @@ -314,5 +314,5 @@ func (chain *TestChain) createChannel( func nextHeader(chain *TestChain) ibctmtypes.Header { return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, - time.Now(), chain.Vals, chain.Vals, chain.Signers) + time.Now(), chain.Vals, chain.Signers) } diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index f68fe078e21e..2bf08ae2669e 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -238,7 +238,7 @@ func NewTestChain(clientID string) *TestChain { signers := []tmtypes.PrivValidator{privVal} now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) - header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, signers) return &TestChain{ ClientID: clientID, @@ -397,7 +397,7 @@ func (chain *TestChain) createChannel( func nextHeader(chain *TestChain) ibctmtypes.Header { return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, - chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) + chain.Header.Time.Add(time.Minute), chain.Vals, chain.Signers) } // Mocked types diff --git a/x/ibc/07-tendermint/misbehaviour_test.go b/x/ibc/07-tendermint/misbehaviour_test.go index 8796b4af755d..655ce135df48 100644 --- a/x/ibc/07-tendermint/misbehaviour_test.go +++ b/x/ibc/07-tendermint/misbehaviour_test.go @@ -2,6 +2,7 @@ package tendermint_test import ( "bytes" + "time" "github.com/tendermint/tendermint/crypto/tmhash" tmtypes "github.com/tendermint/tendermint/types" @@ -43,8 +44,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now.Add(time.Minute), bothValSet, bothSigners), ChainID: chainID, ClientID: chainID, }, @@ -56,8 +57,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now.Add(time.Minute), bothValSet, bothSigners), ChainID: chainID, ClientID: chainID, }, @@ -69,8 +70,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: suite.valSet}, ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, suite.valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now.Add(time.Minute), bothValSet, bothSigners), ChainID: chainID, ClientID: chainID, }, @@ -82,8 +83,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now.Add(time.Minute), bothValSet, bothSigners), ChainID: chainID, ClientID: chainID, }, @@ -95,8 +96,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now.Add(time.Minute), altValSet, altSigners), ChainID: chainID, ClientID: chainID, }, @@ -108,8 +109,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() { ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header), ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet}, ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altValSet, altSigners), - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, bothValSet, altSigners), + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now.Add(time.Minute), altValSet, altSigners), ChainID: chainID, ClientID: chainID, }, diff --git a/x/ibc/07-tendermint/tendermint_test.go b/x/ibc/07-tendermint/tendermint_test.go index 6339812a8b97..c5f9b6d0d455 100644 --- a/x/ibc/07-tendermint/tendermint_test.go +++ b/x/ibc/07-tendermint/tendermint_test.go @@ -49,7 +49,7 @@ func (suite *TendermintTestSuite) SetupTest() { suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) // Suite header is intended to be header passed in for initial ClientState // Thus it should have same height and time as ClientState - suite.header = ibctmtypes.CreateTestHeader(chainID, height, suite.clientTime, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = ibctmtypes.CreateTestHeader(chainID, height, suite.clientTime, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } func TestTendermintTestSuite(t *testing.T) { diff --git a/x/ibc/07-tendermint/types/evidence_test.go b/x/ibc/07-tendermint/types/evidence_test.go index 2a7384224896..af1ee0e40cd6 100644 --- a/x/ibc/07-tendermint/types/evidence_test.go +++ b/x/ibc/07-tendermint/types/evidence_test.go @@ -2,6 +2,7 @@ package types_test import ( "bytes" + "time" "github.com/tendermint/tendermint/crypto/tmhash" tmbytes "github.com/tendermint/tendermint/libs/bytes" @@ -16,7 +17,7 @@ func (suite *TendermintTestSuite) TestEvidence() { ev := ibctmtypes.Evidence{ Header1: suite.header, - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, suite.valSet, signers), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, signers), ChainID: chainID, ClientID: "gaiamainnet", } @@ -59,7 +60,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { "valid evidence", ibctmtypes.Evidence{ Header1: suite.header, - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, bothValSet, signers), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now.Add(time.Minute), suite.valSet, signers), ChainID: chainID, ClientID: "gaiamainnet", }, @@ -70,7 +71,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { "invalid client ID ", ibctmtypes.Evidence{ Header1: suite.header, - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, bothValSet, signers), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, signers), ChainID: chainID, ClientID: "GAIA", }, @@ -81,7 +82,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { "wrong chainID on header1", ibctmtypes.Evidence{ Header1: suite.header, - Header2: ibctmtypes.CreateTestHeader("ethermint", height, suite.now, suite.valSet, bothValSet, signers), + Header2: ibctmtypes.CreateTestHeader("ethermint", height, suite.now, suite.valSet, signers), ChainID: "ethermint", ClientID: "gaiamainnet", }, @@ -92,7 +93,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { "wrong chainID on header2", ibctmtypes.Evidence{ Header1: suite.header, - Header2: ibctmtypes.CreateTestHeader("ethermint", height, suite.now, suite.valSet, bothValSet, signers), + Header2: ibctmtypes.CreateTestHeader("ethermint", height, suite.now, suite.valSet, signers), ChainID: chainID, ClientID: "gaiamainnet", }, @@ -103,7 +104,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { "mismatched heights", ibctmtypes.Evidence{ Header1: suite.header, - Header2: ibctmtypes.CreateTestHeader(chainID, 6, suite.now, suite.valSet, bothValSet, signers), + Header2: ibctmtypes.CreateTestHeader(chainID, 6, suite.now, suite.valSet, signers), ChainID: chainID, ClientID: "gaiamainnet", }, @@ -124,7 +125,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { { "header 1 doesn't have 2/3 majority", ibctmtypes.Evidence{ - Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners), Header2: suite.header, ChainID: chainID, ClientID: "gaiamainnet", @@ -142,7 +143,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { "header 2 doesn't have 2/3 majority", ibctmtypes.Evidence{ Header1: suite.header, - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners), ChainID: chainID, ClientID: "gaiamainnet", }, @@ -159,7 +160,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { "validators sign off on wrong commit", ibctmtypes.Evidence{ Header1: suite.header, - Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners), ChainID: chainID, ClientID: "gaiamainnet", }, diff --git a/x/ibc/07-tendermint/types/header.go b/x/ibc/07-tendermint/types/header.go index 7b5d6e047979..17e266a3cccf 100644 --- a/x/ibc/07-tendermint/types/header.go +++ b/x/ibc/07-tendermint/types/header.go @@ -18,7 +18,6 @@ var _ clientexported.Header = Header{} type Header struct { tmtypes.SignedHeader // contains the commitment root ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` - NextValidatorSet *tmtypes.ValidatorSet `json:"next_validator_set" yaml:"next_validator_set"` } // ClientType defines that the Header is a Tendermint consensus algorithm @@ -52,15 +51,9 @@ func (h Header) ValidateBasic(chainID string) error { if h.ValidatorSet == nil { return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set is nil") } - if h.NextValidatorSet == nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "next validator set is nil") - } if !bytes.Equal(h.ValidatorsHash, h.ValidatorSet.Hash()) { return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set does not match hash") } - if !bytes.Equal(h.NextValidatorsHash, h.NextValidatorSet.Hash()) { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "next validator set does not match hash") - } return nil } diff --git a/x/ibc/07-tendermint/types/header_test.go b/x/ibc/07-tendermint/types/header_test.go index 7c1fc7748d29..c5c004028a7f 100644 --- a/x/ibc/07-tendermint/types/header_test.go +++ b/x/ibc/07-tendermint/types/header_test.go @@ -14,7 +14,7 @@ func (suite *TendermintTestSuite) TestHeaderValidateBasic() { }{ {"valid header", suite.header, chainID, true}, {"signed header basic validation failed", suite.header, "chainID", false}, - {"validator set nil", ibctmtypes.Header{suite.header.SignedHeader, nil, nil}, chainID, false}, + {"validator set nil", ibctmtypes.Header{suite.header.SignedHeader, nil}, chainID, false}, } suite.Require().Equal(clientexported.Tendermint, suite.header.ClientType()) diff --git a/x/ibc/07-tendermint/types/tendermint_test.go b/x/ibc/07-tendermint/types/tendermint_test.go index 5b4ecb9338ab..d12c3fd1f95b 100644 --- a/x/ibc/07-tendermint/types/tendermint_test.go +++ b/x/ibc/07-tendermint/types/tendermint_test.go @@ -40,7 +40,7 @@ func (suite *TendermintTestSuite) SetupTest() { suite.privVal = tmtypes.NewMockPV() val := tmtypes.NewValidator(suite.privVal.GetPubKey(), 10) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) - suite.header = ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = ibctmtypes.CreateTestHeader(chainID, height, suite.now, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } func TestTendermintTestSuite(t *testing.T) { diff --git a/x/ibc/07-tendermint/types/test_utils.go b/x/ibc/07-tendermint/types/test_utils.go index 85642d29a466..9e1c7431768c 100644 --- a/x/ibc/07-tendermint/types/test_utils.go +++ b/x/ibc/07-tendermint/types/test_utils.go @@ -21,9 +21,8 @@ func MakeBlockID(hash []byte, partSetSize int, partSetHash []byte) tmtypes.Block } // CreateTestHeader creates a mock header for testing only. -func CreateTestHeader(chainID string, height int64, timestamp time.Time, valSet *tmtypes.ValidatorSet, nextValSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { +func CreateTestHeader(chainID string, height int64, timestamp time.Time, valSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { vsetHash := valSet.Hash() - nextHash := nextValSet.Hash() tmHeader := tmtypes.Header{ Version: version.Consensus{Block: 2, App: 2}, ChainID: chainID, @@ -33,7 +32,7 @@ func CreateTestHeader(chainID string, height int64, timestamp time.Time, valSet LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), DataHash: tmhash.Sum([]byte("data_hash")), ValidatorsHash: vsetHash, - NextValidatorsHash: nextHash, + NextValidatorsHash: vsetHash, ConsensusHash: tmhash.Sum([]byte("consensus_hash")), AppHash: tmhash.Sum([]byte("app_hash")), LastResultsHash: tmhash.Sum([]byte("last_results_hash")), @@ -54,8 +53,7 @@ func CreateTestHeader(chainID string, height int64, timestamp time.Time, valSet } return Header{ - SignedHeader: signedHeader, - ValidatorSet: valSet, - NextValidatorSet: nextValSet, + SignedHeader: signedHeader, + ValidatorSet: valSet, } } diff --git a/x/ibc/07-tendermint/update.go b/x/ibc/07-tendermint/update.go index efc85eb81de8..5a7bde3c543d 100644 --- a/x/ibc/07-tendermint/update.go +++ b/x/ibc/07-tendermint/update.go @@ -84,8 +84,13 @@ func checkValidity( ) } - return lite.Verify(clientState.GetChainID(), &clientState.LastHeader.SignedHeader, clientState.LastHeader.NextValidatorSet, + // Verify next header with the last header's validatorset as trusted validatorset + err := lite.Verify(clientState.GetChainID(), &clientState.LastHeader.SignedHeader, clientState.LastHeader.ValidatorSet, &header.SignedHeader, header.ValidatorSet, clientState.TrustingPeriod, currentTimestamp, lite.DefaultTrustLevel) + if err != nil { + return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, err.Error()) + } + return nil } // update the consensus state from a new header diff --git a/x/ibc/07-tendermint/update_test.go b/x/ibc/07-tendermint/update_test.go index 3f293e882126..3cc190ece6f3 100644 --- a/x/ibc/07-tendermint/update_test.go +++ b/x/ibc/07-tendermint/update_test.go @@ -47,26 +47,16 @@ func (suite *TendermintTestSuite) TestCheckValidity() { name: "successful update with next height and same validator set", setup: func() { clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) - newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers) currentTime = suite.now }, expPass: true, }, { - name: "successful update with next height and different validator set", - setup: func() { - oldHeader := ibctmtypes.CreateTestHeader(chainID, height, suite.clientTime, suite.valSet, bothValSet, signers) - clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, oldHeader) - newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, bothValSet, bothValSet, bothSigners) - currentTime = suite.now - }, - expPass: true, - }, - { - name: "successful update with future height and same validator set", + name: "successful update with future height and different validator set", setup: func() { clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) - newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, bothValSet, bothValSet, bothSigners) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, bothValSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -75,7 +65,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { name: "unsuccessful update with next height: update header mismatches nextValSetHash", setup: func() { clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) - newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, bothValSet, bothValSet, bothSigners) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, bothValSet, bothSigners) currentTime = suite.now }, expPass: false, @@ -84,7 +74,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { name: "unsuccessful update with future height: too much change in validator set", setup: func() { clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) - newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, altValSet, altValSet, altSigners) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, altValSet, altSigners) currentTime = suite.now }, expPass: false, @@ -93,7 +83,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { name: "unsuccessful update: trusting period has passed since last client timestamp", setup: func() { clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) - newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers) // make current time pass trusting period from last timestamp on clientstate currentTime = suite.now.Add(ubdPeriod) }, @@ -103,7 +93,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { name: "unsuccessful update: header timestamp is past current timestamp", setup: func() { clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) - newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.now.Add(time.Minute), suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -112,7 +102,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { name: "unsuccessful update: header timestamp is not past last client timestamp", setup: func() { clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) - newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.clientTime, suite.valSet, suite.valSet, signers) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.clientTime, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -121,7 +111,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { name: "header basic validation failed", setup: func() { clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) - newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers) // cause new header to fail validatebasic by changing commit height to mismatch header height newHeader.SignedHeader.Commit.Height = height - 1 currentTime = suite.now @@ -133,7 +123,7 @@ func (suite *TendermintTestSuite) TestCheckValidity() { setup: func() { clientState = ibctmtypes.NewClientState(chainID, trustingPeriod, ubdPeriod, suite.header) // Make new header at height less than latest client state - newHeader = ibctmtypes.CreateTestHeader(chainID, height-1, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = ibctmtypes.CreateTestHeader(chainID, height-1, suite.headerTime, suite.valSet, signers) currentTime = suite.now }, diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index d53905bb5c89..d27430029f7d 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -157,7 +157,7 @@ func NewTestChain(clientID string) *TestChain { signers := []tmtypes.PrivValidator{privVal} now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) - header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, signers) return &TestChain{ ClientID: clientID, @@ -316,5 +316,5 @@ func (chain *TestChain) createChannel( func nextHeader(chain *TestChain) ibctmtypes.Header { return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, - chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) + chain.Header.Time.Add(time.Minute), chain.Vals, chain.Signers) } diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index 5f509169cbbe..e42c4af302b6 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -118,7 +118,7 @@ func NewTestChain(clientID string) *TestChain { signers := []tmtypes.PrivValidator{privVal} now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) - header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, signers) return &TestChain{ ClientID: clientID, @@ -278,5 +278,5 @@ func (chain *TestChain) createChannel( func nextHeader(chain *TestChain) ibctmtypes.Header { return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, - chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) + chain.Header.Time.Add(time.Minute), chain.Vals, chain.Signers) } diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go index 57f5b7c2e608..f690daab8cb8 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/ante/ante_test.go @@ -194,7 +194,7 @@ func NewTestChain(clientID string) *TestChain { signers := []tmtypes.PrivValidator{privVal} now := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) - header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, valSet, signers) + header := ibctmtypes.CreateTestHeader(clientID, 1, now, valSet, signers) return &TestChain{ ClientID: clientID, @@ -353,7 +353,7 @@ func (chain *TestChain) createChannel( func nextHeader(chain *TestChain) ibctmtypes.Header { return ibctmtypes.CreateTestHeader(chain.Header.ChainID, chain.Header.Height+1, - chain.Header.Time.Add(time.Minute), chain.Vals, chain.Vals, chain.Signers) + chain.Header.Time.Add(time.Minute), chain.Vals, chain.Signers) } var _ channelexported.PacketDataI = packetT{} From 5a0143532e39c30decf6916de8bbc5c469040af6 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Sat, 7 Mar 2020 16:25:48 -0800 Subject: [PATCH 100/176] remove warning msg --- go.mod | 2 ++ go.sum | 2 ++ 2 files changed, 4 insertions(+) diff --git a/go.mod b/go.mod index c010e24ab730..e021f5e57fdf 100644 --- a/go.mod +++ b/go.mod @@ -35,4 +35,6 @@ require ( replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.1 +replace github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 + go 1.14 diff --git a/go.sum b/go.sum index ae529cbb3acf..45141da9ac6f 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.1.4 h1:x0g0zQ9bQKgNsLo0XSXAy1H8Q1RG/td+5OXJt+Ci8b8= github.com/99designs/keyring v1.1.4/go.mod h1:657DQuMrBZRtuL/voxVyiyb6zpMehlm5vLB9Qwrv904= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= From 4b683e58eb1815a87d1b8854838a70f56ab38933 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Sat, 7 Mar 2020 16:36:57 -0800 Subject: [PATCH 101/176] Make IBC updating more robust --- x/ibc/07-tendermint/update.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x/ibc/07-tendermint/update.go b/x/ibc/07-tendermint/update.go index 5a7bde3c543d..5f8258689db9 100644 --- a/x/ibc/07-tendermint/update.go +++ b/x/ibc/07-tendermint/update.go @@ -59,11 +59,11 @@ func checkValidity( return errors.New("trusting period since last client timestamp already passed") } - // assert header timestamp is not in the future (& transitively that is not past the trusting period) - if header.Time.Unix() > currentTimestamp.Unix() { + // assert header timestamp is not past the trusting period + if header.Time.Sub(clientState.GetLatestTimestamp()) >= clientState.TrustingPeriod { return sdkerrors.Wrap( clienttypes.ErrInvalidHeader, - "header blocktime can't be in the future", + "header blocktime is outside trusting period from last client timestamp", ) } @@ -85,6 +85,8 @@ func checkValidity( } // Verify next header with the last header's validatorset as trusted validatorset + // TODO: Figure out a better way to add some leeway in currentTimestamp checking either in Tendermint or here + currentTimestamp = currentTimestamp.Add(time.Minute) err := lite.Verify(clientState.GetChainID(), &clientState.LastHeader.SignedHeader, clientState.LastHeader.ValidatorSet, &header.SignedHeader, header.ValidatorSet, clientState.TrustingPeriod, currentTimestamp, lite.DefaultTrustLevel) if err != nil { From 1ee0b7ee020f5db11f09751da106eeeaf7fdb410 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Sat, 7 Mar 2020 17:24:14 -0800 Subject: [PATCH 102/176] blh --- x/ibc/02-client/keeper/client.go | 2 +- x/ibc/02-client/keeper/keeper.go | 1 + x/ibc/03-connection/keeper/verify.go | 3 +++ x/ibc/07-tendermint/update.go | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index 98f2220727ef..a7a7c0abc28c 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -93,7 +93,7 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H } k.SetClientState(ctx, clientState) - k.SetClientConsensusState(ctx, clientID, header.GetHeight(), consensusState) + k.SetClientConsensusState(ctx, clientID, header.GetHeight()-1, consensusState) k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, header.GetHeight())) ctx.EventManager().EmitEvents(sdk.Events{ diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index 160bcde630fa..dd534e0d7fc7 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -94,6 +94,7 @@ func (k Keeper) SetClientConsensusState(ctx sdk.Context, clientID string, height store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) store.Set(ibctypes.KeyConsensusState(clientID, height), bz) + fmt.Printf("Saving consensus state at %s with hash %v\n", ibctypes.KeyConsensusState(clientID, height), consensusState.GetRoot()) } // HasClientConsensusState returns if keeper has a ConsensusState for a particular diff --git a/x/ibc/03-connection/keeper/verify.go b/x/ibc/03-connection/keeper/verify.go index 4524444fe07b..003badde578c 100644 --- a/x/ibc/03-connection/keeper/verify.go +++ b/x/ibc/03-connection/keeper/verify.go @@ -1,6 +1,8 @@ package keeper import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" @@ -56,6 +58,7 @@ func (k Keeper) VerifyConnectionState( ctx, connection.GetClientID(), height, ) if !found { + fmt.Println("Errored Here") return sdkerrors.Wrapf( clienttypes.ErrConsensusStateNotFound, "clientID (%s), height (%d)", connectionEnd.GetClientID(), height, diff --git a/x/ibc/07-tendermint/update.go b/x/ibc/07-tendermint/update.go index 5f8258689db9..44c7900811e2 100644 --- a/x/ibc/07-tendermint/update.go +++ b/x/ibc/07-tendermint/update.go @@ -99,7 +99,7 @@ func checkValidity( func update(clientState types.ClientState, header types.Header) (types.ClientState, types.ConsensusState) { clientState.LastHeader = header consensusState := types.ConsensusState{ - Height: uint64(header.Height), + Height: uint64(header.Height - 1), Timestamp: header.Time, Root: commitmenttypes.NewMerkleRoot(header.AppHash), ValidatorSet: header.ValidatorSet, From 9dae83793c670dc1780420ea9c9baf866091a375 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Mon, 9 Mar 2020 11:13:13 -0700 Subject: [PATCH 103/176] bump tm dependency --- go.mod | 2 +- go.sum | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index e021f5e57fdf..2ce3f1b68ae4 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 github.com/tendermint/go-amino v0.15.1 github.com/tendermint/iavl v0.13.0 - github.com/tendermint/tendermint v0.33.1 + github.com/tendermint/tendermint v0.33.1-dev3 github.com/tendermint/tm-db v0.4.1 gopkg.in/yaml.v2 v2.2.8 ) diff --git a/go.sum b/go.sum index 45141da9ac6f..ee7cc42941af 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,5 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.1.4 h1:x0g0zQ9bQKgNsLo0XSXAy1H8Q1RG/td+5OXJt+Ci8b8= @@ -7,19 +8,36 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ChainSafe/go-schnorrkel v0.0.0-20200102211924-4bcbc698314f h1:4O1om+UVU+Hfcihr1timk8YNXHxzZWgCo7ofnrZRApw= github.com/ChainSafe/go-schnorrkel v0.0.0-20200102211924-4bcbc698314f/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/Workiva/go-datastructures v1.0.51/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d h1:1aAija9gr0Hyv4KfQcRcwlmFIrhkDmIj2dz5bkg/s/8= github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d/go.mod h1:icNx/6QdFblhsEjZehARqbNumymUT/ydwlLojFdv7Sk= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d h1:xG8Pj6Y6J760xwETNmMzmlt38QSwz0BLp1cZ09g27uw= @@ -32,13 +50,21 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -46,7 +72,9 @@ github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6 github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -55,8 +83,14 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a h1:mq+R6XEM6lJX5VlLyZIrUSP8tSuJp82xTK89hvBwJbU= github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM= @@ -67,25 +101,33 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojt github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= @@ -97,45 +139,85 @@ github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f h1:8N8XWLZelZNibkhM1FuF+3Ad3YIbgirjdMiVA0eUkaM= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.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 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -153,69 +235,135 @@ 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-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 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= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.5.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk= github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/cosmos-proto v0.1.1-0.20200213154359-02baa11ea7c2 h1:jQK1YoH972Aptd22YKgtNu5jM2X2xMGkyIENOAc71to= github.com/regen-network/cosmos-proto v0.1.1-0.20200213154359-02baa11ea7c2/go.mod h1:+r7jN10xXCypD4yBgzKOa+vgLz0riqYMHeDcKekxPvA= github.com/regen-network/protobuf v1.3.2-alpha.regen.1 h1:YdeZbBS0lG1D13COb7b57+nM/RGgIs8WF9DwitU6EBM= github.com/regen-network/protobuf v1.3.2-alpha.regen.1/go.mod h1:lye6mqhOn/GCw1zRl3uPD5VP8rC+LPMyTyPAyQV872U= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +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= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 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/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M= @@ -223,11 +371,13 @@ github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs= github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -235,6 +385,9 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= @@ -263,14 +416,21 @@ github.com/tendermint/go-amino v0.15.1/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoM github.com/tendermint/iavl v0.13.0 h1:r2sINvNFlJsLlLhGoqlqPlREWYkuK26BvMfkBt+XQnA= github.com/tendermint/iavl v0.13.0/go.mod h1:7nSUPdrsHEZ2nNZa+9gaIrcJciWd1jCQZXtcyARU82k= github.com/tendermint/tendermint v0.33.0/go.mod h1:s5UoymnPIY+GcA3mMte4P9gpMP8vS7UH7HBXikT1pHI= +github.com/tendermint/tendermint v0.33.1-dev2.0.20200306190520-b6f0aa3a8874 h1:RmrjmyQeYqcG+UlrtoKOJ0dppGkaSJ9APyg+iWxsgGc= +github.com/tendermint/tendermint v0.33.1-dev2.0.20200306190520-b6f0aa3a8874/go.mod h1:CRiNrmGG8HSRJyj8j69k/vKauv97R54Md9zWlEx+gdg= +github.com/tendermint/tendermint v0.33.1-dev3 h1:bxc7zwOZyt4E/7Bte7ii5nL7j+gbBahgDeiAulh2O24= +github.com/tendermint/tendermint v0.33.1-dev3/go.mod h1:CRiNrmGG8HSRJyj8j69k/vKauv97R54Md9zWlEx+gdg= github.com/tendermint/tendermint v0.33.1 h1:8f68LUBz8yhISZvaLFP4siXXrLWsWeoYfelbdNtmvm4= github.com/tendermint/tendermint v0.33.1/go.mod h1:fBOKyrlXOETqQ+heL8x/TZgSdmItON54csyabvktBp0= github.com/tendermint/tm-db v0.4.0 h1:iPbCcLbf4nwDFhS39Zo1lpdS1X/cT9CkTlUx17FHQgA= github.com/tendermint/tm-db v0.4.0/go.mod h1:+Cwhgowrf7NBGXmsqFMbwEtbo80XmyrlY5Jsk95JubQ= github.com/tendermint/tm-db v0.4.1 h1:TvX7JWjJOVZ+N3y+I86wddrGttOdMmmBxXcu0/Y7ZJ0= github.com/tendermint/tm-db v0.4.1/go.mod h1:JsJ6qzYkCGiGwm5GHl/H5GLI9XLb6qZX7PRe425dHAY= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= @@ -278,12 +438,23 @@ github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWp go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= @@ -291,64 +462,105 @@ golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-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/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/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.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/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/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200110213125-a7a6caa82ab2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f h1:2wh8dWY8959cBGQvk1RD+/eQBgRYYDaZ+hT0/zsARoA= google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.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= @@ -356,22 +568,32 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks 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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 69be1cfd16db460402e5bb1eaf439784ae6a0340 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Mon, 9 Mar 2020 11:13:52 -0700 Subject: [PATCH 104/176] remove redundant clockdrift correction --- go.sum | 10 ++++++++++ x/ibc/07-tendermint/update.go | 2 -- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index ee7cc42941af..115d20bafff0 100644 --- a/go.sum +++ b/go.sum @@ -37,6 +37,7 @@ github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d/go.mod h1:icNx/6Q github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= @@ -53,7 +54,9 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -112,6 +115,7 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -315,6 +319,7 @@ github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAy github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.5.0 h1:Ctq0iGpCmr3jeP77kbF2UxgvRwzWWz+4Bh9/vJTyg1A= github.com/prometheus/client_golang v1.5.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -322,6 +327,7 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -329,18 +335,21 @@ github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk= github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/cosmos-proto v0.1.1-0.20200213154359-02baa11ea7c2 h1:jQK1YoH972Aptd22YKgtNu5jM2X2xMGkyIENOAc71to= github.com/regen-network/cosmos-proto v0.1.1-0.20200213154359-02baa11ea7c2/go.mod h1:+r7jN10xXCypD4yBgzKOa+vgLz0riqYMHeDcKekxPvA= @@ -515,6 +524,7 @@ golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/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= diff --git a/x/ibc/07-tendermint/update.go b/x/ibc/07-tendermint/update.go index 44c7900811e2..14faf9752136 100644 --- a/x/ibc/07-tendermint/update.go +++ b/x/ibc/07-tendermint/update.go @@ -85,8 +85,6 @@ func checkValidity( } // Verify next header with the last header's validatorset as trusted validatorset - // TODO: Figure out a better way to add some leeway in currentTimestamp checking either in Tendermint or here - currentTimestamp = currentTimestamp.Add(time.Minute) err := lite.Verify(clientState.GetChainID(), &clientState.LastHeader.SignedHeader, clientState.LastHeader.ValidatorSet, &header.SignedHeader, header.ValidatorSet, clientState.TrustingPeriod, currentTimestamp, lite.DefaultTrustLevel) if err != nil { From 4a3b03a477e203a16c8b18bc56a25ead35ee5c7a Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Mon, 9 Mar 2020 11:46:29 -0700 Subject: [PATCH 105/176] remove blh commit --- x/ibc/02-client/keeper/client.go | 2 +- x/ibc/02-client/keeper/keeper.go | 1 - x/ibc/03-connection/keeper/verify.go | 3 --- x/ibc/07-tendermint/update.go | 2 +- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index a7a7c0abc28c..98f2220727ef 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -93,7 +93,7 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H } k.SetClientState(ctx, clientState) - k.SetClientConsensusState(ctx, clientID, header.GetHeight()-1, consensusState) + k.SetClientConsensusState(ctx, clientID, header.GetHeight(), consensusState) k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, header.GetHeight())) ctx.EventManager().EmitEvents(sdk.Events{ diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index dd534e0d7fc7..160bcde630fa 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -94,7 +94,6 @@ func (k Keeper) SetClientConsensusState(ctx sdk.Context, clientID string, height store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryLengthPrefixed(consensusState) store.Set(ibctypes.KeyConsensusState(clientID, height), bz) - fmt.Printf("Saving consensus state at %s with hash %v\n", ibctypes.KeyConsensusState(clientID, height), consensusState.GetRoot()) } // HasClientConsensusState returns if keeper has a ConsensusState for a particular diff --git a/x/ibc/03-connection/keeper/verify.go b/x/ibc/03-connection/keeper/verify.go index 003badde578c..4524444fe07b 100644 --- a/x/ibc/03-connection/keeper/verify.go +++ b/x/ibc/03-connection/keeper/verify.go @@ -1,8 +1,6 @@ package keeper import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" @@ -58,7 +56,6 @@ func (k Keeper) VerifyConnectionState( ctx, connection.GetClientID(), height, ) if !found { - fmt.Println("Errored Here") return sdkerrors.Wrapf( clienttypes.ErrConsensusStateNotFound, "clientID (%s), height (%d)", connectionEnd.GetClientID(), height, diff --git a/x/ibc/07-tendermint/update.go b/x/ibc/07-tendermint/update.go index 14faf9752136..4233e8934607 100644 --- a/x/ibc/07-tendermint/update.go +++ b/x/ibc/07-tendermint/update.go @@ -97,7 +97,7 @@ func checkValidity( func update(clientState types.ClientState, header types.Header) (types.ClientState, types.ConsensusState) { clientState.LastHeader = header consensusState := types.ConsensusState{ - Height: uint64(header.Height - 1), + Height: uint64(header.Height), Timestamp: header.Time, Root: commitmenttypes.NewMerkleRoot(header.AppHash), ValidatorSet: header.ValidatorSet, From 4692d2d74bea72233772c9209af64ca82ff0c104 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Mon, 9 Mar 2020 12:18:37 -0700 Subject: [PATCH 106/176] fix test build failures --- x/ibc/07-tendermint/types/evidence_test.go | 4 ++-- x/ibc/07-tendermint/types/test_utils.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x/ibc/07-tendermint/types/evidence_test.go b/x/ibc/07-tendermint/types/evidence_test.go index af1ee0e40cd6..0f363827cdfa 100644 --- a/x/ibc/07-tendermint/types/evidence_test.go +++ b/x/ibc/07-tendermint/types/evidence_test.go @@ -134,7 +134,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { // voteSet contains only altVal which is less than 2/3 of total power (height/1height) wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header1.Height, 1, tmtypes.PrecommitType, altValSet) var err error - ev.Header1.Commit, err = tmtypes.MakeCommit(ev.Header1.Commit.BlockID, ev.Header2.Height, ev.Header1.Commit.Round, wrongVoteSet, altSigners) + ev.Header1.Commit, err = tmtypes.MakeCommit(ev.Header1.Commit.BlockID, ev.Header2.Height, ev.Header1.Commit.Round, wrongVoteSet, altSigners, suite.now) return err }, false, @@ -151,7 +151,7 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() { // voteSet contains only altVal which is less than 2/3 of total power (height/1height) wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header2.Height, 1, tmtypes.PrecommitType, altValSet) var err error - ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round, wrongVoteSet, altSigners) + ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round, wrongVoteSet, altSigners, suite.now) return err }, false, diff --git a/x/ibc/07-tendermint/types/test_utils.go b/x/ibc/07-tendermint/types/test_utils.go index 9e1c7431768c..2a2491b14847 100644 --- a/x/ibc/07-tendermint/types/test_utils.go +++ b/x/ibc/07-tendermint/types/test_utils.go @@ -42,7 +42,7 @@ func CreateTestHeader(chainID string, height int64, timestamp time.Time, valSet hhash := tmHeader.Hash() blockID := MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) voteSet := tmtypes.NewVoteSet(chainID, height, 1, tmtypes.PrecommitType, valSet) - commit, err := tmtypes.MakeCommit(blockID, height, 1, voteSet, signers) + commit, err := tmtypes.MakeCommit(blockID, height, 1, voteSet, signers, timestamp) if err != nil { panic(err) } From 2310bee2de0ec1cf1aa6a1abc143d1ec45949a07 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Mon, 9 Mar 2020 12:23:29 -0700 Subject: [PATCH 107/176] Change time from PST to UTC --- types/utils_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/utils_test.go b/types/utils_test.go index 4ffc67c6101c..1c451f185b34 100644 --- a/types/utils_test.go +++ b/types/utils_test.go @@ -87,7 +87,7 @@ func TestUint64ToBigEndian(t *testing.T) { func TestFormatTimeBytes(t *testing.T) { t.Parallel() - tm, err := time.Parse("Jan 2, 2006 at 3:04pm (MST)", "Mar 3, 2020 at 7:54pm (PST)") + tm, err := time.Parse("Jan 2, 2006 at 3:04pm (MST)", "Mar 3, 2020 at 7:54pm (UTC)") require.NoError(t, err) require.Equal(t, "2020-03-03T19:54:00.000000000", string(sdk.FormatTimeBytes(tm))) } From 382e78df2e16ead9c7224c3c4637449cf4021b23 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Mon, 9 Mar 2020 15:47:45 -0700 Subject: [PATCH 108/176] Merge PR #5770: Update error message in connection keeper --- x/ibc/03-connection/keeper/verify.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/ibc/03-connection/keeper/verify.go b/x/ibc/03-connection/keeper/verify.go index 4524444fe07b..699ef5db15d6 100644 --- a/x/ibc/03-connection/keeper/verify.go +++ b/x/ibc/03-connection/keeper/verify.go @@ -58,7 +58,7 @@ func (k Keeper) VerifyConnectionState( if !found { return sdkerrors.Wrapf( clienttypes.ErrConsensusStateNotFound, - "clientID (%s), height (%d)", connectionEnd.GetClientID(), height, + "clientID (%s), height (%d)", connection.GetClientID(), height, ) } From 01ccc21696ed9e8e87469065b6e98a26170b0c1f Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 10 Mar 2020 13:25:12 +0100 Subject: [PATCH 109/176] Merge PR #5774: Debug timestamp issues --- x/ibc/02-client/keeper/keeper.go | 5 ++--- x/ibc/03-connection/keeper/keeper_test.go | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index 160bcde630fa..32a80d8af43a 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -135,9 +135,8 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported. valSet := stakingtypes.Validators(histInfo.Valset) consensusState := ibctmtypes.ConsensusState{ - Height: height, - // FIXME: Currently commented out due to time normalisation issues. - //Timestamp: histInfo.Header.Time, + Height: height, + Timestamp: histInfo.Header.Time, Root: commitmenttypes.NewMerkleRoot(histInfo.Header.AppHash), ValidatorSet: tmtypes.NewValidatorSet(valSet.ToTmValidators()), } diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index 1254e542c2db..b0143c0f5d6e 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -256,9 +256,8 @@ func (chain *TestChain) updateClient(client *TestChain) { client.App.StakingKeeper.SetHistoricalInfo(ctxClient, client.Header.Height, histInfo) consensusState := ibctmtypes.ConsensusState{ - Height: uint64(client.Header.Height), - // FIXME: currently commented out due to time normalisation issues. - //Timestamp: client.Header.Time, + Height: uint64(client.Header.Height), + Timestamp: client.Header.Time, Root: commitmenttypes.NewMerkleRoot(commitID.Hash), ValidatorSet: client.Vals, } From 455c712e595c4f4bb658617d3afea0428efb96a8 Mon Sep 17 00:00:00 2001 From: Aditya Date: Wed, 11 Mar 2020 06:14:27 -0700 Subject: [PATCH 110/176] Merge PR #5786: Fix MsgTransfer routing --- x/ibc/20-transfer/types/msgs.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index d707fddc182e..f017c1a0dfe7 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -4,7 +4,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" - ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between ICS20 enabled chains. @@ -36,7 +35,7 @@ func NewMsgTransfer( // Route implements sdk.Msg func (MsgTransfer) Route() string { - return ibctypes.RouterKey + return RouterKey } // Type implements sdk.Msg From b4127970cae399375ee1b6a2b7e49664d2959b76 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 11 Mar 2020 14:15:45 +0100 Subject: [PATCH 111/176] Fix test-case --- x/ibc/20-transfer/types/msgs_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go index 9efcaf0000e9..febb4f0df29a 100644 --- a/x/ibc/20-transfer/types/msgs_test.go +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // define constants used for testing @@ -37,7 +36,7 @@ var ( func TestMsgTransferRoute(t *testing.T) { msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true) - require.Equal(t, ibctypes.RouterKey, msg.Route()) + require.Equal(t, RouterKey, msg.Route()) } // TestMsgTransferType tests Type for MsgTransfer From 5795324847cee2049a091cb1210db478fa2aec82 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Thu, 12 Mar 2020 09:15:16 -0700 Subject: [PATCH 112/176] register MsgPacket --- x/ibc/04-channel/types/codec.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index ca64d49d2851..cfb57624b7ba 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -33,6 +33,8 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgChannelCloseInit{}, "ibc/channel/MsgChannelCloseInit", nil) cdc.RegisterConcrete(MsgChannelCloseConfirm{}, "ibc/channel/MsgChannelCloseConfirm", nil) + cdc.RegisterConcrete(MsgPacket{}, "ibc/channel/MsgPacket", nil) + SetSubModuleCodec(cdc) } From c06d4cc99ec8be2ccf470f28b730cfaa8eea97a3 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 16 Mar 2020 18:13:09 +0100 Subject: [PATCH 113/176] Flip boolean --- x/ibc/20-transfer/keeper/relay.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index bf2553576eb9..529a30cf28a8 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -126,7 +126,7 @@ func (k Keeper) createOutgoingPacket( } packetData := types.NewFungibleTokenPacketData( - amount, sender, receiver, !isSourceChain, destHeight+DefaultPacketTimeout, + amount, sender, receiver, isSourceChain, destHeight+DefaultPacketTimeout, ) packet := channel.NewPacket( From 8b2db11ce562fc10159eee00fb5bb7178ba496e9 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Tue, 17 Mar 2020 12:18:40 -0700 Subject: [PATCH 114/176] emit packet event on SendPacket --- x/ibc/04-channel/keeper/packet.go | 15 +++++++++++++++ x/ibc/04-channel/types/events.go | 9 +++++++++ 2 files changed, 24 insertions(+) diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 9630cedfd09f..f4057ce3b198 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -102,6 +102,21 @@ func (k Keeper) SendPacket( k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend) k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), types.CommitPacket(packet.GetData())) + // Emit Event with Packet data along with other packet information for relayer to pick up + // and relay to other chain + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeSendPacket, + sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData().GetBytes())), + sdk.NewAttribute(types.AttributeKeyTimeout, string(packet.GetData().GetTimeoutHeight())), + sdk.NewAttribute(types.AttributeKeySequence, string(packet.GetSequence())), + sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()), + sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()), + sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()), + sdk.NewAttribute(types.AttributeKeyDstChannel, packet.GetDestChannel()), + ), + }) + k.Logger(ctx).Info(fmt.Sprintf("packet sent %v", packet)) // TODO: use packet.String() return nil } diff --git a/x/ibc/04-channel/types/events.go b/x/ibc/04-channel/types/events.go index 212f8e254d9f..3c20b4195bfc 100644 --- a/x/ibc/04-channel/types/events.go +++ b/x/ibc/04-channel/types/events.go @@ -13,6 +13,15 @@ const ( AttributeKeyChannelID = "channel_id" AttributeCounterpartyPortID = "counterparty_port_id" AttributeCounterpartyChannelID = "counterparty_channel_id" + + EventTypeSendPacket = "send_packet" + AttributeKeyData = "packet_data" + AttributeKeyTimeout = "packet_timeout" + AttributeKeySequence = "packet_sequence" + AttributeKeySrcPort = "packet_src_port" + AttributeKeySrcChannel = "packet_src_channel" + AttributeKeyDstPort = "packet_dst_port" + AttributeKeyDstChannel = "packet_dst_channel" ) // IBC channel events vars From b8295506615bb0ebd58e82d31c616f1bec21c713 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Wed, 18 Mar 2020 09:06:16 -0700 Subject: [PATCH 115/176] Fix attribute setting --- x/ibc/04-channel/keeper/packet.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index f4057ce3b198..4cca23525f32 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -108,8 +108,8 @@ func (k Keeper) SendPacket( sdk.NewEvent( types.EventTypeSendPacket, sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData().GetBytes())), - sdk.NewAttribute(types.AttributeKeyTimeout, string(packet.GetData().GetTimeoutHeight())), - sdk.NewAttribute(types.AttributeKeySequence, string(packet.GetSequence())), + sdk.NewAttribute(types.AttributeKeyTimeout, fmt.Sprintf("%d", packet.GetData().GetTimeoutHeight())), + sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())), sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()), sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()), sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()), From af10e050d23e2b6f4c50e7a7ffc273192d32a0a2 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 18 Mar 2020 13:40:32 -0400 Subject: [PATCH 116/176] Implement in-memory KVStore --- baseapp/baseapp.go | 8 ++++++++ simapp/app.go | 6 ++++++ store/mem/mem_test.go | 39 +++++++++++++++++++++++++++++++++++++++ store/mem/store.go | 39 +++++++++++++++++++++++++++++++++++++++ store/rootmulti/store.go | 8 ++++++++ store/types/store.go | 20 ++++++++++++++++++++ types/store.go | 15 +++++++++++++++ 7 files changed, 135 insertions(+) create mode 100644 store/mem/mem_test.go create mode 100644 store/mem/store.go diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 3837a34ccc9a..c8aab9a85a89 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -199,6 +199,14 @@ func (app *BaseApp) MountTransientStores(keys map[string]*sdk.TransientStoreKey) } } +// MountMemoryStores mounts all in-memory KVStores with the BaseApp's internal +// commit multi-store. +func (app *BaseApp) MountMemoryStores(keys map[string]*sdk.MemoryStoreKey) { + for _, memKey := range keys { + app.MountStore(memKey, sdk.StoreTypeMemory) + } +} + // MountStoreWithDB mounts a store to the provided key in the BaseApp // multistore, using a specified DB. func (app *BaseApp) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) { diff --git a/simapp/app.go b/simapp/app.go index 4ed3eee2464b..663f23a7415e 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -157,6 +157,9 @@ func NewSimApp( ) tkeys := sdk.NewTransientStoreKeys(params.TStoreKey) + // TODO: + // memKeys := sdk.NewMemoryStoreKeys(...) + app := &SimApp{ BaseApp: bApp, cdc: cdc, @@ -302,6 +305,9 @@ func NewSimApp( app.MountKVStores(keys) app.MountTransientStores(tkeys) + // TODO: + // app.MountMemoryStores(memKeys) + // initialize BaseApp app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) diff --git a/store/mem/mem_test.go b/store/mem/mem_test.go new file mode 100644 index 000000000000..cff4c37da7dc --- /dev/null +++ b/store/mem/mem_test.go @@ -0,0 +1,39 @@ +package mem_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/store/mem" + "github.com/cosmos/cosmos-sdk/store/types" +) + +func TestStore(t *testing.T) { + db := mem.NewStore() + key, value := []byte("key"), []byte("value") + + require.Equal(t, types.StoreTypeMemory, db.GetStoreType()) + + require.Nil(t, db.Get(key)) + db.Set(key, value) + require.Equal(t, value, db.Get(key)) + + newValue := []byte("newValue") + db.Set(key, newValue) + require.Equal(t, newValue, db.Get(key)) + + db.Delete(key) + require.Nil(t, db.Get(key)) +} + +func TestCommit(t *testing.T) { + db := mem.NewStore() + key, value := []byte("key"), []byte("value") + + db.Set(key, value) + id := db.Commit() + require.True(t, id.IsZero()) + require.True(t, db.LastCommitID().IsZero()) + require.Equal(t, value, db.Get(key)) +} diff --git a/store/mem/store.go b/store/mem/store.go new file mode 100644 index 000000000000..b66eb8414817 --- /dev/null +++ b/store/mem/store.go @@ -0,0 +1,39 @@ +package mem + +import ( + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/store/dbadapter" + "github.com/cosmos/cosmos-sdk/store/types" +) + +var ( + _ types.KVStore = (*Store)(nil) + _ types.Committer = (*Store)(nil) +) + +// Store implements an in-memory only KVStore. Entries are peresistent between +// commits and thus between blocks. +type Store struct { + dbadapter.Store +} + +func NewStore() *Store { + return NewStoreWithDB(dbm.NewMemDB()) +} + +func NewStoreWithDB(db *dbm.MemDB) *Store { + return &Store{Store: dbadapter.Store{DB: db}} +} + +// GetStoreType returns the Store's type. +func (ts *Store) GetStoreType() types.StoreType { + return types.StoreTypeMemory +} + +// Commit performs a no-op as entries are persistent between commitments. +func (ts *Store) Commit() (id types.CommitID) { return } + +// nolint +func (ts *Store) SetPruning(pruning types.PruningOptions) {} +func (ts *Store) LastCommitID() (id types.CommitID) { return } diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index 5239ab8a4e15..0edbff7fee8d 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/cachemulti" "github.com/cosmos/cosmos-sdk/store/dbadapter" "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/mem" "github.com/cosmos/cosmos-sdk/store/tracekv" "github.com/cosmos/cosmos-sdk/store/transient" "github.com/cosmos/cosmos-sdk/store/types" @@ -517,6 +518,13 @@ func (rs *Store) loadCommitStoreFromParams(key types.StoreKey, id types.CommitID return transient.NewStore(), nil + case types.StoreTypeMemory: + if _, ok := key.(*types.MemoryStoreKey); !ok { + return nil, fmt.Errorf("unexpected key type for a MemoryStoreKey; got: %s", key.String()) + } + + return mem.NewStore(), nil + default: panic(fmt.Sprintf("unrecognized store type %v", params.typ)) } diff --git a/store/types/store.go b/store/types/store.go index d48585f8fce2..5de396651dd6 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -266,6 +266,7 @@ const ( StoreTypeDB StoreTypeIAVL StoreTypeTransient + StoreTypeMemory ) //---------------------------------------- @@ -326,6 +327,25 @@ func (key *TransientStoreKey) String() string { return fmt.Sprintf("TransientStoreKey{%p, %s}", key, key.name) } +// MemoryStoreKey defines a typed key to be used with an in-memory KVStore. +type MemoryStoreKey struct { + name string +} + +func NewMemoryStoreKey(name string) *MemoryStoreKey { + return &MemoryStoreKey{name: name} +} + +// Name returns the name of the MemoryStoreKey. +func (key *MemoryStoreKey) Name() string { + return key.name +} + +// String returns a stringified representation of the MemoryStoreKey. +func (key *MemoryStoreKey) String() string { + return fmt.Sprintf("MemoryStoreKey{%p, %s}", key, key.name) +} + //---------------------------------------- // key-value result for iterator queries diff --git a/types/store.go b/types/store.go index 6057526c80e9..884556cc6b26 100644 --- a/types/store.go +++ b/types/store.go @@ -76,6 +76,7 @@ const ( StoreTypeDB = types.StoreTypeDB StoreTypeIAVL = types.StoreTypeIAVL StoreTypeTransient = types.StoreTypeTransient + StoreTypeMemory = types.StoreTypeMemory ) // nolint - reexport @@ -84,6 +85,7 @@ type ( CapabilityKey = types.CapabilityKey KVStoreKey = types.KVStoreKey TransientStoreKey = types.TransientStoreKey + MemoryStoreKey = types.MemoryStoreKey ) // NewKVStoreKey returns a new pointer to a KVStoreKey. @@ -99,6 +101,7 @@ func NewKVStoreKeys(names ...string) map[string]*KVStoreKey { for _, name := range names { keys[name] = NewKVStoreKey(name) } + return keys } @@ -115,6 +118,18 @@ func NewTransientStoreKeys(names ...string) map[string]*TransientStoreKey { for _, name := range names { keys[name] = NewTransientStoreKey(name) } + + return keys +} + +// NewMemoryStoreKeys constructs a new map matching store key names to their +// respective MemoryStoreKey references. +func NewMemoryStoreKeys(names ...string) map[string]*MemoryStoreKey { + keys := make(map[string]*MemoryStoreKey) + for _, name := range names { + keys[name] = types.NewMemoryStoreKey(name) + } + return keys } From 29d68cf621042b5f8030bfcbbd7fbad4ebfb9d3a Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 18 Mar 2020 16:15:16 -0400 Subject: [PATCH 117/176] Start keeper and types --- x/capability/alias.go | 18 +++++++++ x/capability/keeper/keeper.go | 73 +++++++++++++++++++++++++++++++++++ x/capability/types/types.go | 32 +++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 x/capability/alias.go create mode 100644 x/capability/keeper/keeper.go create mode 100644 x/capability/types/types.go diff --git a/x/capability/alias.go b/x/capability/alias.go new file mode 100644 index 000000000000..8e4a2faf0715 --- /dev/null +++ b/x/capability/alias.go @@ -0,0 +1,18 @@ +package capability + +import ( + "github.com/cosmos/cosmos-sdk/x/capability/keeper" + "github.com/cosmos/cosmos-sdk/x/capability/types" +) + +// nolint + +var ( + NewCapabilityKey = types.NewCapabilityKey + NewKeeper = keeper.NewKeeper +) + +type ( + Capability = types.Capability + CapabilityKey = types.CapabilityKey +) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go new file mode 100644 index 000000000000..533f5d6e7337 --- /dev/null +++ b/x/capability/keeper/keeper.go @@ -0,0 +1,73 @@ +package keeper + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type ( + // Keeper defines the capability module's keeper. It is responsible for provisioning, + // tracking, and authenticating capabilities at runtime. During application + // initialization, the keeper can be hooked up to modules through unique function + // references so that it can identify the calling module when later invoked. + // + // When the initial state is loaded from disk, the keeper allows the ability to + // create new capability keys for all previously allocated capability identifiers + // (allocated during execution of past transactions and assigned to particular modes), + // and keep them in a memory-only store while the chain is running. + // + // The keeper allows the ability to create scoped sub-keepers which are tied to + // a single specific module. + Keeper struct { + cdc *codec.Codec + storeKey sdk.StoreKey + memKey sdk.MemoryStoreKey + scopedModules map[string]struct{} + sealed bool + } + + // ScopedKeeper defines a scoped sub-keeper which is tied to a single specific + // module provisioned by the capability keeper. Scoped keepers must be created + // at application initialization and passed to modules, which can then use them + // to claim capabilities they receive and retrieve capabilities which they own + // by name, in addition to creating new capabilities & authenticating capabilities + // passed by other modules. + ScopedKeeper struct { + storeKey sdk.StoreKey + memKey sdk.MemoryStoreKey + module string + } +) + +func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey, memKey sdk.MemoryStoreKey) Keeper { + return Keeper{ + cdc: cdc, + storeKey: storeKey, + memKey: memKey, + scopedModules: make(map[string]struct{}), + sealed: false, + } +} + +// ScopeToModule attempts to create and return a ScopedKeeper for a given module +// by name. It will panic if the keeper is already sealed or if the module name +// already has a ScopedKeeper. +func (k Keeper) ScopeToModule(moduleName string) ScopedKeeper { + if k.sealed { + panic("cannot scope to module via a sealed capability keeper") + } + + if _, ok := k.scopedModules[moduleName]; ok { + panic(fmt.Sprintf("cannot create multiple scoped keepers for the same module name: %s", moduleName)) + } + + k.scopedModules[moduleName] = struct{}{} + + return ScopedKeeper{ + storeKey: k.storeKey, + memKey: k.memKey, + module: moduleName, + } +} diff --git a/x/capability/types/types.go b/x/capability/types/types.go new file mode 100644 index 000000000000..51fd0bd6040e --- /dev/null +++ b/x/capability/types/types.go @@ -0,0 +1,32 @@ +package types + +import "fmt" + +var _ Capability = (*CapabilityKey)(nil) + +// Capability defines the interface a capability must implement. The given +// capability must provide a GUID. +type Capability interface { + GetIndex() uint64 + String() string +} + +// CapabilityKey defines an implementation of a Capability. The index provided to +// a CapabilityKey must be globally unique. +type CapabilityKey struct { + Name string + Index uint64 +} + +func NewCapabilityKey(name string, index uint64) Capability { + return &CapabilityKey{Name: name, Index: index} +} + +// GetIndex returns the capability key's index. +func (ck *CapabilityKey) GetIndex() uint64 { + return ck.Index +} + +func (ck *CapabilityKey) String() string { + return fmt.Sprintf("CapabilityKey{%p, %d, %s}", ck, ck.Index, ck.Name) +} From 191df595d2145f33ea3718826e8343f96f043c34 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 19 Mar 2020 15:41:12 -0400 Subject: [PATCH 118/176] Add codec --- x/capability/types/codec.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 x/capability/types/codec.go diff --git a/x/capability/types/codec.go b/x/capability/types/codec.go new file mode 100644 index 000000000000..7b7cea97dcf4 --- /dev/null +++ b/x/capability/types/codec.go @@ -0,0 +1,25 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" +) + +// ModuleCdc defines the capability module's codec. The codec is not sealed as to +// allow other modules to register their concrete Capability types. +var ModuleCdc = codec.New() + +// RegisterCodec registers all the necessary types and interfaces for the +// capability module. +func RegisterCodec(cdc *codec.Codec) { + cdc.RegisterInterface((*Capability)(nil), nil) +} + +// RegisterCapabilityTypeCodec registers an external concrete Capability type +// defined in another module for the internal ModuleCdc. +func RegisterCapabilityTypeCodec(o interface{}, name string) { + ModuleCdc.RegisterConcrete(o, name, nil) +} + +func init() { + RegisterCodec(ModuleCdc) +} From cb6fc182b7bcde4ec147155dace3d6d27c52bdd9 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 19 Mar 2020 15:41:20 -0400 Subject: [PATCH 119/176] Add keys logic --- x/capability/types/keys.go | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 x/capability/types/keys.go diff --git a/x/capability/types/keys.go b/x/capability/types/keys.go new file mode 100644 index 000000000000..6c1a6ddf2fae --- /dev/null +++ b/x/capability/types/keys.go @@ -0,0 +1,52 @@ +package types + +import ( + "encoding/binary" + "fmt" +) + +const ( + // ModuleName defines the module name + ModuleName = "capability" + + // StoreKey defines the primary module store key + StoreKey = ModuleName + + // MemStoreKey defines the in-memory store key + MemStoreKey = "mem_capability" +) + +var ( + // KeyIndex defines the key that stores the current globally unique capability + // index. + KeyIndex = []byte("index") + + // KeyPrefixIndexCapability defines a key prefix that stores index to capability + // name mappings. + KeyPrefixIndexCapability = []byte("capability_index") +) + +// RevCapabilityKey returns a reverse lookup key for a given module and capability +// name. +func RevCapabilityKey(module, name string) []byte { + return []byte(fmt.Sprintf("%s/rev/%s", module, name)) +} + +// FwdCapabilityKey returns a forward lookup key for a given module and capability +// reference. +func FwdCapabilityKey(module string, cap Capability) []byte { + return []byte(fmt.Sprintf("%s/fwd/%s", module, cap)) +} + +// IndexToKey returns bytes to be used as a key for a given capability index. +func IndexToKey(index uint64) []byte { + buf := make([]byte, 8) + binary.LittleEndian.PutUint64(buf, index) + return buf +} + +// IndexFromKey returns an index from a call to IndexToKey for a given capability +// index. +func IndexFromKey(key []byte) uint64 { + return binary.LittleEndian.Uint64(key) +} From 447221b8f8b0df60a303f5475fe25f774e644ed4 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 19 Mar 2020 15:41:48 -0400 Subject: [PATCH 120/176] Update types --- x/capability/types/keys_test.go | 29 ++++++++++++++ x/capability/types/types.go | 66 +++++++++++++++++++++++++++++--- x/capability/types/types_test.go | 34 ++++++++++++++++ 3 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 x/capability/types/keys_test.go create mode 100644 x/capability/types/types_test.go diff --git a/x/capability/types/keys_test.go b/x/capability/types/keys_test.go new file mode 100644 index 000000000000..b4a0168912b2 --- /dev/null +++ b/x/capability/types/keys_test.go @@ -0,0 +1,29 @@ +package types_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/x/capability/types" +) + +func TestRevCapabilityKey(t *testing.T) { + expected := []byte("bank/rev/send") + require.Equal(t, expected, types.RevCapabilityKey("bank", "send")) +} + +func TestFwdCapabilityKey(t *testing.T) { + cap := types.NewCapabilityKey(23) + expected := []byte(fmt.Sprintf("bank/fwd/%s", cap)) + require.Equal(t, expected, types.FwdCapabilityKey("bank", cap)) +} + +func TestIndexToKey(t *testing.T) { + require.Equal(t, []byte{0x5a, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, types.IndexToKey(3162)) +} + +func TestIndexFromKey(t *testing.T) { + require.Equal(t, uint64(3162), types.IndexFromKey([]byte{0x5a, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})) +} diff --git a/x/capability/types/types.go b/x/capability/types/types.go index 51fd0bd6040e..e6da5535d0d9 100644 --- a/x/capability/types/types.go +++ b/x/capability/types/types.go @@ -1,6 +1,12 @@ package types -import "fmt" +import ( + "fmt" + + "gopkg.in/yaml.v2" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) var _ Capability = (*CapabilityKey)(nil) @@ -14,12 +20,13 @@ type Capability interface { // CapabilityKey defines an implementation of a Capability. The index provided to // a CapabilityKey must be globally unique. type CapabilityKey struct { - Name string - Index uint64 + Index uint64 `json:"index" yaml:"index"` } -func NewCapabilityKey(name string, index uint64) Capability { - return &CapabilityKey{Name: name, Index: index} +// NewCapabilityKey returns a reference to a new CapabilityKey to be used as an +// actual capability. +func NewCapabilityKey(index uint64) Capability { + return &CapabilityKey{Index: index} } // GetIndex returns the capability key's index. @@ -27,6 +34,53 @@ func (ck *CapabilityKey) GetIndex() uint64 { return ck.Index } +// String returns the string representation of a CapabilityKey. The string contains +// the CapabilityKey's memory reference as the string is to be used in a composite +// key and to authenticate capabilities. func (ck *CapabilityKey) String() string { - return fmt.Sprintf("CapabilityKey{%p, %d, %s}", ck, ck.Index, ck.Name) + return fmt.Sprintf("CapabilityKey{%p, %d}", ck, ck.Index) +} + +// Owner defines a single capability owner. An owner is defined by the name of +// capability and the module name. +type Owner struct { + Module string `json:"module" yaml:"module"` + Name string `json:"name" yaml:"name"` +} + +func NewOwner(module, name string) Owner { + return Owner{Module: module, Name: name} +} + +// Key returns a composite key for an Owner. +func (o Owner) Key() string { + return fmt.Sprintf("%s/%s", o.Module, o.Name) +} + +func (o Owner) String() string { + bz, _ := yaml.Marshal(o) + return string(bz) +} + +// CapabilityOwners defines a set of owners of a single Capability. The set of +// owners must be unique. +type CapabilityOwners struct { + Owners []Owner `json:"owners" yaml:"owners"` +} + +func NewCapabilityOwners() *CapabilityOwners { + return &CapabilityOwners{Owners: make([]Owner, 0)} +} + +// Set attempts to add a given owner to the CapabilityOwners. If the owner already +// exists, an error will be returned. +func (co *CapabilityOwners) Set(owner Owner) error { + for _, o := range co.Owners { + if o.Key() == owner.Key() { + return sdkerrors.Wrapf(ErrOwnerClaimed, owner.String()) + } + } + + co.Owners = append(co.Owners, owner) + return nil } diff --git a/x/capability/types/types_test.go b/x/capability/types/types_test.go new file mode 100644 index 000000000000..74da351d7ac3 --- /dev/null +++ b/x/capability/types/types_test.go @@ -0,0 +1,34 @@ +package types_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/x/capability/types" +) + +func TestCapabilityKey(t *testing.T) { + idx := uint64(3162) + cap := types.NewCapabilityKey(idx) + require.Equal(t, idx, cap.GetIndex()) + require.Equal(t, fmt.Sprintf("CapabilityKey{%p, %d}", cap, idx), cap.String()) +} + +func TestOwner(t *testing.T) { + o := types.NewOwner("bank", "send") + require.Equal(t, "bank/send", o.Key()) + require.Equal(t, "module: bank\nname: send\n", o.String()) +} + +func TestCapabilityOwners(t *testing.T) { + co := types.NewCapabilityOwners() + o1 := types.NewOwner("bank", "send") + o2 := types.NewOwner("slashing", "slash") + + require.NoError(t, co.Set(o1)) + require.Error(t, co.Set(o1)) + require.NoError(t, co.Set(o2)) + require.Equal(t, []types.Owner{o1, o2}, co.Owners) +} From 970e7864250df06b792af88cd9bb2ce950010ab8 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 19 Mar 2020 15:42:40 -0400 Subject: [PATCH 121/176] Update keeper --- x/capability/alias.go | 27 +++++++++++++--- x/capability/keeper/keeper.go | 61 +++++++++++++++++++++++++++++++++-- x/capability/types/errors.go | 13 ++++++++ 3 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 x/capability/types/errors.go diff --git a/x/capability/alias.go b/x/capability/alias.go index 8e4a2faf0715..4bdd24ca80ac 100644 --- a/x/capability/alias.go +++ b/x/capability/alias.go @@ -6,13 +6,32 @@ import ( ) // nolint +// DONTCOVER + +const ( + ModuleName = types.ModuleName + StoreKey = types.StoreKey + MemStoreKey = types.MemStoreKey +) var ( - NewCapabilityKey = types.NewCapabilityKey - NewKeeper = keeper.NewKeeper + NewKeeper = keeper.NewKeeper + NewCapabilityKey = types.NewCapabilityKey + RevCapabilityKey = types.RevCapabilityKey + FwdCapabilityKey = types.FwdCapabilityKey + KeyIndex = types.KeyIndex + KeyPrefixIndexCapability = types.KeyPrefixIndexCapability + ErrCapabilityTaken = types.ErrCapabilityTaken + ErrOwnerClaimed = types.ErrOwnerClaimed + RegisterCodec = types.RegisterCodec + RegisterCapabilityTypeCodec = types.RegisterCapabilityTypeCodec + ModuleCdc = types.ModuleCdc + NewOwner = types.NewOwner + NewCapabilityOwners = types.NewCapabilityOwners ) type ( - Capability = types.Capability - CapabilityKey = types.CapabilityKey + Capability = types.Capability + CapabilityKey = types.CapabilityKey + CapabilityOwners = types.CapabilityOwners ) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 533f5d6e7337..d0caad92f358 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability/types" ) type ( @@ -23,7 +25,7 @@ type ( Keeper struct { cdc *codec.Codec storeKey sdk.StoreKey - memKey sdk.MemoryStoreKey + memKey sdk.StoreKey scopedModules map[string]struct{} sealed bool } @@ -35,13 +37,14 @@ type ( // by name, in addition to creating new capabilities & authenticating capabilities // passed by other modules. ScopedKeeper struct { + cdc *codec.Codec storeKey sdk.StoreKey - memKey sdk.MemoryStoreKey + memKey sdk.StoreKey module string } ) -func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey, memKey sdk.MemoryStoreKey) Keeper { +func NewKeeper(cdc *codec.Codec, storeKey, memKey sdk.StoreKey) Keeper { return Keeper{ cdc: cdc, storeKey: storeKey, @@ -71,3 +74,55 @@ func (k Keeper) ScopeToModule(moduleName string) ScopedKeeper { module: moduleName, } } + +// AuthenticateCapability attempts to authenticate a given capability and name +// from a caller. It allows for a caller to check that a capability does in fact +// correspond to a particular name. The scoped keeper will lookup the capability +// from the internal in-memory store and check against the provided name. It returns +// true upon success and false upon failure. +// +// Note, the capability's forward mapping is indexed by a string which should +// contain it's unique memory reference. +func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap types.Capability, name string) bool { + memStore := ctx.KVStore(sk.memKey) + + bz := memStore.Get(types.FwdCapabilityKey(sk.module, cap)) + return string(bz) == name +} + +// ClaimCapability attempts to claim a given Capability and name tuple. This tuple +// is considered an Owner. It will attempt to add the owner to the persistent +// set of capability owners for the capability index. If the owner already exists, +// it will return an error. Otherwise, it will also set a forward and reverse index +// for the capability and capability name. +func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, name string) error { + store := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) + memStore := ctx.KVStore(sk.memKey) + indexKey := types.IndexToKey(cap.GetIndex()) + + var capOwners *types.CapabilityOwners + + bz := store.Get(indexKey) + if len(bz) == 0 { + capOwners = types.NewCapabilityOwners() + } else { + sk.cdc.MustUnmarshalBinaryBare(bz, capOwners) + } + + if err := capOwners.Set(types.NewOwner(sk.module, name)); err != nil { + return err + } + + // update capability owner set + store.Set(indexKey, sk.cdc.MustMarshalBinaryBare(capOwners)) + + // Set the forward mapping between the module and capability tuple and the + // capability name in the in-memory store. + memStore.Set(types.FwdCapabilityKey(sk.module, cap), []byte(name)) + + // Set the reverse mapping between the module and capability name and the + // capability in the in-memory store. + memStore.Set(types.RevCapabilityKey(sk.module, name), sk.cdc.MustMarshalBinaryBare(cap)) + + return nil +} diff --git a/x/capability/types/errors.go b/x/capability/types/errors.go new file mode 100644 index 000000000000..fbf718e9fecc --- /dev/null +++ b/x/capability/types/errors.go @@ -0,0 +1,13 @@ +package types + +// DONTCOVER + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// x/capability module sentinel errors +var ( + ErrCapabilityTaken = sdkerrors.Register(ModuleName, 2, "capability name already taken") + ErrOwnerClaimed = sdkerrors.Register(ModuleName, 3, "given owner already claimed capability") +) From 0f950e164ebc2ef7470a1ff0cce9d33cb5ab24c2 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 19 Mar 2020 16:08:43 -0400 Subject: [PATCH 122/176] Implement NewCapability --- x/capability/keeper/keeper.go | 70 +++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index d0caad92f358..2ffd18f6df54 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -75,6 +75,43 @@ func (k Keeper) ScopeToModule(moduleName string) ScopedKeeper { } } +// NewCapability attempts to create a new capability with a given name. If the +// capability already exists in the in-memory store, an error will be returned. +// Otherwise, a new capability is created with the current global index. The +// newly created capability has the module and name tuple set as the initial owner. +// Finally, the global index is incremented along with forward and reverse indexes +// set in the in-memory store. +func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capability, error) { + store := ctx.KVStore(sk.storeKey) + memStore := ctx.KVStore(sk.memKey) + + if memStore.Has(types.RevCapabilityKey(sk.module, name)) { + return nil, sdkerrors.Wrapf(types.ErrCapabilityTaken, fmt.Sprintf("module: %s, name: %s", sk.module, name)) + } + + // create new capability with the current global index + index := types.IndexFromKey(store.Get(types.KeyIndex)) + cap := types.NewCapabilityKey(index) + + // update capability owner set + if err := sk.addOwner(ctx, cap, name); err != nil { + return nil, err + } + + // increment global index + store.Set(types.KeyIndex, types.IndexToKey(index+1)) + + // Set the forward mapping between the module and capability tuple and the + // capability name in the in-memory store. + memStore.Set(types.FwdCapabilityKey(sk.module, cap), []byte(name)) + + // Set the reverse mapping between the module and capability name and the + // capability in the in-memory store. + memStore.Set(types.RevCapabilityKey(sk.module, name), sk.cdc.MustMarshalBinaryBare(cap)) + + return cap, nil +} + // AuthenticateCapability attempts to authenticate a given capability and name // from a caller. It allows for a caller to check that a capability does in fact // correspond to a particular name. The scoped keeper will lookup the capability @@ -96,13 +133,31 @@ func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap types.Capabil // it will return an error. Otherwise, it will also set a forward and reverse index // for the capability and capability name. func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, name string) error { - store := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) + // update capability owner set + if err := sk.addOwner(ctx, cap, name); err != nil { + return err + } + memStore := ctx.KVStore(sk.memKey) + + // Set the forward mapping between the module and capability tuple and the + // capability name in the in-memory store. + memStore.Set(types.FwdCapabilityKey(sk.module, cap), []byte(name)) + + // Set the reverse mapping between the module and capability name and the + // capability in the in-memory store. + memStore.Set(types.RevCapabilityKey(sk.module, name), sk.cdc.MustMarshalBinaryBare(cap)) + + return nil +} + +func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap types.Capability, name string) error { + prefixStore := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) indexKey := types.IndexToKey(cap.GetIndex()) var capOwners *types.CapabilityOwners - bz := store.Get(indexKey) + bz := prefixStore.Get(indexKey) if len(bz) == 0 { capOwners = types.NewCapabilityOwners() } else { @@ -114,15 +169,6 @@ func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, na } // update capability owner set - store.Set(indexKey, sk.cdc.MustMarshalBinaryBare(capOwners)) - - // Set the forward mapping between the module and capability tuple and the - // capability name in the in-memory store. - memStore.Set(types.FwdCapabilityKey(sk.module, cap), []byte(name)) - - // Set the reverse mapping between the module and capability name and the - // capability in the in-memory store. - memStore.Set(types.RevCapabilityKey(sk.module, name), sk.cdc.MustMarshalBinaryBare(cap)) - + prefixStore.Set(indexKey, sk.cdc.MustMarshalBinaryBare(capOwners)) return nil } From 2a3dde91061896f2c6006ef30d7dbbd1dfab30f3 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 10:52:37 -0400 Subject: [PATCH 123/176] Implement InitializeAndSeal --- x/capability/keeper/keeper.go | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 2ffd18f6df54..4d3acd7495fd 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/capability/types" ) @@ -69,12 +70,55 @@ func (k Keeper) ScopeToModule(moduleName string) ScopedKeeper { k.scopedModules[moduleName] = struct{}{} return ScopedKeeper{ + cdc: k.cdc, storeKey: k.storeKey, memKey: k.memKey, module: moduleName, } } +// InitializeAndSeal loads all capabilities from the persistent KVStore into the +// in-memory store and seals the keeper to prevent further modules from creating +// a scoped keeper. InitializeAndSeal must be called once after the application +// state is loaded. +func (k Keeper) InitializeAndSeal(ctx sdk.Context) { + if k.sealed { + panic("cannot initialize and seal an already sealed capability keeper") + } + + memStore := ctx.KVStore(k.memKey) + memStoreType := memStore.GetStoreType() + + if memStoreType != sdk.StoreTypeMemory { + panic(fmt.Sprintf("invalid memory store type; got %d, expected: %d", memStoreType, sdk.StoreTypeMemory)) + } + + prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixIndexCapability) + iterator := sdk.KVStorePrefixIterator(prefixStore, nil) + + // initialize the in-memory store for all persisted capabilities + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + index := types.IndexFromKey(iterator.Key()) + cap := types.NewCapabilityKey(index) + + var capOwners *types.CapabilityOwners + k.cdc.MustUnmarshalBinaryBare(iterator.Value(), capOwners) + + for _, owner := range capOwners.Owners { + // Set the forward mapping between the module and capability tuple and the + // capability name in the in-memory store. + memStore.Set(types.FwdCapabilityKey(owner.Module, cap), []byte(owner.Name)) + + // Set the reverse mapping between the module and capability name and the + // capability in the in-memory store. + memStore.Set(types.RevCapabilityKey(owner.Module, owner.Name), k.cdc.MustMarshalBinaryBare(cap)) + } + } + + k.sealed = true +} + // NewCapability attempts to create a new capability with a given name. If the // capability already exists in the in-memory store, an error will be returned. // Otherwise, a new capability is created with the current global index. The From 4d40d4d55194d5e58726c0a6c6ba3fb6539791ac Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 10:58:07 -0400 Subject: [PATCH 124/176] Update simapp --- simapp/app.go | 43 ++++++++++++++++++++++--------------------- x/capability/alias.go | 2 ++ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/simapp/app.go b/simapp/app.go index 663f23a7415e..69d6d230d459 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -18,6 +18,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/vesting" "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/capability" "github.com/cosmos/cosmos-sdk/x/crisis" distr "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/cosmos/cosmos-sdk/x/evidence" @@ -115,20 +116,21 @@ type SimApp struct { subspaces map[string]params.Subspace // keepers - AccountKeeper auth.AccountKeeper - BankKeeper bank.Keeper - SupplyKeeper supply.Keeper - StakingKeeper staking.Keeper - SlashingKeeper slashing.Keeper - MintKeeper mint.Keeper - DistrKeeper distr.Keeper - GovKeeper gov.Keeper - CrisisKeeper crisis.Keeper - UpgradeKeeper upgrade.Keeper - ParamsKeeper params.Keeper - IBCKeeper ibc.Keeper - EvidenceKeeper evidence.Keeper - TransferKeeper transfer.Keeper + AccountKeeper auth.AccountKeeper + BankKeeper bank.Keeper + CapabilityKeeper capability.Keeper + SupplyKeeper supply.Keeper + StakingKeeper staking.Keeper + SlashingKeeper slashing.Keeper + MintKeeper mint.Keeper + DistrKeeper distr.Keeper + GovKeeper gov.Keeper + CrisisKeeper crisis.Keeper + UpgradeKeeper upgrade.Keeper + ParamsKeeper params.Keeper + IBCKeeper ibc.Keeper + EvidenceKeeper evidence.Keeper + TransferKeeper transfer.Keeper // the module manager mm *module.Manager @@ -153,12 +155,10 @@ func NewSimApp( bam.MainStoreKey, auth.StoreKey, bank.StoreKey, staking.StoreKey, supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey, gov.StoreKey, params.StoreKey, ibc.StoreKey, upgrade.StoreKey, - evidence.StoreKey, transfer.StoreKey, + evidence.StoreKey, transfer.StoreKey, capability.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(params.TStoreKey) - - // TODO: - // memKeys := sdk.NewMemoryStoreKeys(...) + memKeys := sdk.NewMemoryStoreKeys(capability.MemStoreKey) app := &SimApp{ BaseApp: bApp, @@ -188,6 +188,9 @@ func NewSimApp( app.BankKeeper = bank.NewBaseKeeper( app.cdc, keys[bank.StoreKey], app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(), ) + app.CapabilityKeeper = capability.NewKeeper( + app.cdc, keys[capability.StoreKey], memKeys[capability.MemStoreKey], + ) app.SupplyKeeper = supply.NewKeeper( app.cdc, keys[supply.StoreKey], app.AccountKeeper, app.BankKeeper, maccPerms, ) @@ -304,9 +307,7 @@ func NewSimApp( // initialize stores app.MountKVStores(keys) app.MountTransientStores(tkeys) - - // TODO: - // app.MountMemoryStores(memKeys) + app.MountMemoryStores(memKeys) // initialize BaseApp app.SetInitChainer(app.InitChainer) diff --git a/x/capability/alias.go b/x/capability/alias.go index 4bdd24ca80ac..3066ca7068dc 100644 --- a/x/capability/alias.go +++ b/x/capability/alias.go @@ -31,6 +31,8 @@ var ( ) type ( + Keeper = keeper.Keeper + ScopedKeeper = keeper.ScopedKeeper Capability = types.Capability CapabilityKey = types.CapabilityKey CapabilityOwners = types.CapabilityOwners From 4c3e8efbf112759467afbf5c81e0e4b822612c42 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 11:05:13 -0400 Subject: [PATCH 125/176] Implement GetCapability --- x/capability/keeper/keeper.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 4d3acd7495fd..19783188b744 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -195,6 +195,24 @@ func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, na return nil } +// GetCapability allows a module to fetch a capability which it previously claimed +// by name. The module is not allowed to retrieve capabilities which it does not +// own. If another module claims a capability, the previously owning module will +// no longer be able to claim it. +func (sk ScopedKeeper) GetCapability(ctx sdk.Context, name string) (types.Capability, bool) { + memStore := ctx.KVStore(sk.memKey) + + bz := memStore.Get(types.RevCapabilityKey(sk.module, name)) + if len(bz) == 0 { + return nil, false + } + + var cap types.Capability + sk.cdc.MustUnmarshalBinaryBare(bz, &cap) + + return cap, true +} + func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap types.Capability, name string) error { prefixStore := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) indexKey := types.IndexToKey(cap.GetIndex()) From 772d0f69c267011d5b298e01b907bc2f3687dffa Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 11:10:32 -0400 Subject: [PATCH 126/176] Add logging for new and claimed caps --- x/capability/keeper/keeper.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 19783188b744..2459e1117052 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -3,6 +3,8 @@ package keeper import ( "fmt" + "github.com/tendermint/tendermint/libs/log" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -153,6 +155,7 @@ func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capabi // capability in the in-memory store. memStore.Set(types.RevCapabilityKey(sk.module, name), sk.cdc.MustMarshalBinaryBare(cap)) + logger(ctx).Info("created new capability", "module", sk.module, "name", name) return cap, nil } @@ -192,6 +195,7 @@ func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, na // capability in the in-memory store. memStore.Set(types.RevCapabilityKey(sk.module, name), sk.cdc.MustMarshalBinaryBare(cap)) + logger(ctx).Info("claimed capability", "module", sk.module, "name", name, "capability", cap.GetIndex()) return nil } @@ -234,3 +238,7 @@ func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap types.Capability, name stri prefixStore.Set(indexKey, sk.cdc.MustMarshalBinaryBare(capOwners)) return nil } + +func logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} From d8f0ee21c230b8d8e2c81c9c9a827c6e59278067 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 11:16:49 -0400 Subject: [PATCH 127/176] Call InitializeAndSeal in SimApp --- simapp/app.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/simapp/app.go b/simapp/app.go index 69d6d230d459..2e90595de2af 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -327,6 +327,12 @@ func NewSimApp( } } + // Initialize and seal the capability keeper so all persistent capabilities + // are loaded in-memory and prevent any further modules from creating scoped + // sub-keepers. + ctx := app.BaseApp.NewContext(true, abci.Header{}) + app.CapabilityKeeper.InitializeAndSeal(ctx) + return app } From e989574861e7aa0bf11e1b57f8391bf5f66d847d Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 13:08:07 -0400 Subject: [PATCH 128/176] Update keeper semantics + unit tests --- simapp/app.go | 17 ++++- store/mem/store.go | 22 +++++- store/rootmulti/store.go | 4 +- store/types/store.go | 21 ++++++ x/capability/keeper/keeper.go | 14 ++-- x/capability/keeper/keeper_test.go | 60 +++++++++++++++ x/capability/module.go | 117 +++++++++++++++++++++++++++++ x/capability/types/codec.go | 3 + x/capability/types/keys.go | 4 + 9 files changed, 247 insertions(+), 15 deletions(-) create mode 100644 x/capability/keeper/keeper_test.go create mode 100644 x/capability/module.go diff --git a/simapp/app.go b/simapp/app.go index 2e90595de2af..6430378b92a2 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -54,6 +54,7 @@ var ( supply.AppModuleBasic{}, genutil.AppModuleBasic{}, bank.AppModuleBasic{}, + capability.AppModuleBasic{}, staking.AppModuleBasic{}, mint.AppModuleBasic{}, distr.AppModuleBasic{}, @@ -109,8 +110,9 @@ type SimApp struct { invCheckPeriod uint // keys to access the substores - keys map[string]*sdk.KVStoreKey - tkeys map[string]*sdk.TransientStoreKey + keys map[string]*sdk.KVStoreKey + tkeys map[string]*sdk.TransientStoreKey + memKeys map[string]*sdk.MemoryStoreKey // subspaces subspaces map[string]params.Subspace @@ -118,7 +120,7 @@ type SimApp struct { // keepers AccountKeeper auth.AccountKeeper BankKeeper bank.Keeper - CapabilityKeeper capability.Keeper + CapabilityKeeper *capability.Keeper SupplyKeeper supply.Keeper StakingKeeper staking.Keeper SlashingKeeper slashing.Keeper @@ -166,6 +168,7 @@ func NewSimApp( invCheckPeriod: invCheckPeriod, keys: keys, tkeys: tkeys, + memKeys: memKeys, subspaces: make(map[string]params.Subspace), } @@ -256,6 +259,7 @@ func NewSimApp( genutil.NewAppModule(app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx), auth.NewAppModule(app.AccountKeeper), bank.NewAppModule(app.BankKeeper, app.AccountKeeper), + capability.NewAppModule(*app.CapabilityKeeper), crisis.NewAppModule(&app.CrisisKeeper), supply.NewAppModule(app.SupplyKeeper, app.BankKeeper, app.AccountKeeper), gov.NewAppModule(app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.SupplyKeeper), @@ -403,6 +407,13 @@ func (app *SimApp) GetTKey(storeKey string) *sdk.TransientStoreKey { return app.tkeys[storeKey] } +// GetMemKey returns the MemoryStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (app *SimApp) GetMemKey(storeKey string) *sdk.MemoryStoreKey { + return app.memKeys[storeKey] +} + // GetSubspace returns a param subspace for a given module name. // // NOTE: This is solely to be used for testing purposes. diff --git a/store/mem/store.go b/store/mem/store.go index b66eb8414817..2a436ee15424 100644 --- a/store/mem/store.go +++ b/store/mem/store.go @@ -1,9 +1,13 @@ package mem import ( + "io" + dbm "github.com/tendermint/tm-db" + "github.com/cosmos/cosmos-sdk/store/cachekv" "github.com/cosmos/cosmos-sdk/store/dbadapter" + "github.com/cosmos/cosmos-sdk/store/tracekv" "github.com/cosmos/cosmos-sdk/store/types" ) @@ -27,13 +31,23 @@ func NewStoreWithDB(db *dbm.MemDB) *Store { } // GetStoreType returns the Store's type. -func (ts *Store) GetStoreType() types.StoreType { +func (s Store) GetStoreType() types.StoreType { return types.StoreTypeMemory } +// CacheWrap cache wraps the underlying store. +func (s Store) CacheWrap() types.CacheWrap { + return cachekv.NewStore(s) +} + +// CacheWrapWithTrace implements KVStore. +func (s Store) CacheWrapWithTrace(w io.Writer, tc types.TraceContext) types.CacheWrap { + return cachekv.NewStore(tracekv.NewStore(s, w, tc)) +} + // Commit performs a no-op as entries are persistent between commitments. -func (ts *Store) Commit() (id types.CommitID) { return } +func (s *Store) Commit() (id types.CommitID) { return } // nolint -func (ts *Store) SetPruning(pruning types.PruningOptions) {} -func (ts *Store) LastCommitID() (id types.CommitID) { return } +func (s *Store) SetPruning(pruning types.PruningOptions) {} +func (s Store) LastCommitID() (id types.CommitID) { return } diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index 0edbff7fee8d..98a5486aba8a 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -160,17 +160,19 @@ func (rs *Store) loadVersion(ver int64, upgrades *types.StoreUpgrades) error { for _, storeInfo := range cInfo.StoreInfos { infos[storeInfo.Name] = storeInfo } + lastCommitID = cInfo.CommitID() } // load each Store (note this doesn't panic on unmounted keys now) var newStores = make(map[types.StoreKey]types.CommitKVStore) + for key, storeParams := range rs.storesParams { - // Load it store, err := rs.loadCommitStoreFromParams(key, rs.getCommitID(infos, key.Name()), storeParams) if err != nil { return fmt.Errorf("failed to load Store: %v", err) } + newStores[key] = store // If it was deleted, remove all data diff --git a/store/types/store.go b/store/types/store.go index 5de396651dd6..b19fa7a07423 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -269,6 +269,27 @@ const ( StoreTypeMemory ) +func (st StoreType) String() string { + switch st { + case StoreTypeMulti: + return "StoreTypeMulti" + + case StoreTypeDB: + return "StoreTypeDB" + + case StoreTypeIAVL: + return "StoreTypeIAVL" + + case StoreTypeTransient: + return "StoreTypeTransient" + + case StoreTypeMemory: + return "StoreTypeMemory" + } + + return "unknown store type" +} + //---------------------------------------- // Keys for accessing substores diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 2459e1117052..0434d03beafa 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -47,8 +47,8 @@ type ( } ) -func NewKeeper(cdc *codec.Codec, storeKey, memKey sdk.StoreKey) Keeper { - return Keeper{ +func NewKeeper(cdc *codec.Codec, storeKey, memKey sdk.StoreKey) *Keeper { + return &Keeper{ cdc: cdc, storeKey: storeKey, memKey: memKey, @@ -60,7 +60,7 @@ func NewKeeper(cdc *codec.Codec, storeKey, memKey sdk.StoreKey) Keeper { // ScopeToModule attempts to create and return a ScopedKeeper for a given module // by name. It will panic if the keeper is already sealed or if the module name // already has a ScopedKeeper. -func (k Keeper) ScopeToModule(moduleName string) ScopedKeeper { +func (k *Keeper) ScopeToModule(moduleName string) ScopedKeeper { if k.sealed { panic("cannot scope to module via a sealed capability keeper") } @@ -83,7 +83,7 @@ func (k Keeper) ScopeToModule(moduleName string) ScopedKeeper { // in-memory store and seals the keeper to prevent further modules from creating // a scoped keeper. InitializeAndSeal must be called once after the application // state is loaded. -func (k Keeper) InitializeAndSeal(ctx sdk.Context) { +func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { if k.sealed { panic("cannot initialize and seal an already sealed capability keeper") } @@ -92,7 +92,7 @@ func (k Keeper) InitializeAndSeal(ctx sdk.Context) { memStoreType := memStore.GetStoreType() if memStoreType != sdk.StoreTypeMemory { - panic(fmt.Sprintf("invalid memory store type; got %d, expected: %d", memStoreType, sdk.StoreTypeMemory)) + panic(fmt.Sprintf("invalid memory store type; got %s, expected: %s", memStoreType, sdk.StoreTypeMemory)) } prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixIndexCapability) @@ -104,8 +104,8 @@ func (k Keeper) InitializeAndSeal(ctx sdk.Context) { index := types.IndexFromKey(iterator.Key()) cap := types.NewCapabilityKey(index) - var capOwners *types.CapabilityOwners - k.cdc.MustUnmarshalBinaryBare(iterator.Value(), capOwners) + var capOwners types.CapabilityOwners + k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &capOwners) for _, owner := range capOwners.Owners { // Set the forward mapping between the module and capability tuple and the diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go new file mode 100644 index 000000000000..82e94ee2550d --- /dev/null +++ b/x/capability/keeper/keeper_test.go @@ -0,0 +1,60 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/capability" + "github.com/cosmos/cosmos-sdk/x/capability/keeper" +) + +type KeeperTestSuite struct { + suite.Suite + + ctx sdk.Context + keeper *keeper.Keeper + app *simapp.SimApp +} + +func (suite *KeeperTestSuite) SetupTest() { + checkTx := false + app := simapp.Setup(checkTx) + + // create new keeper so we can define custom scoping before init and seal + keeper := keeper.NewKeeper( + app.Codec(), app.GetKey(capability.StoreKey), app.GetMemKey(capability.MemStoreKey), + ) + + suite.ctx = app.BaseApp.NewContext(checkTx, abci.Header{Height: 1}) + suite.keeper = keeper + suite.app = app +} + +func (suite *KeeperTestSuite) TestInitializeAndSeal() { + sk := suite.keeper.ScopeToModule(bank.ModuleName) + + cap, err := sk.NewCapability(suite.ctx, "transfer") + suite.Require().NoError(err) + suite.Require().NotNil(cap) + + suite.Require().NotPanics(func() { + suite.keeper.InitializeAndSeal(suite.ctx) + }) + + got, ok := sk.GetCapability(suite.ctx, "transfer") + suite.Require().True(ok) + suite.Require().Equal(cap, got) + + suite.Require().Panics(func() { + suite.keeper.InitializeAndSeal(suite.ctx) + }) +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/capability/module.go b/x/capability/module.go new file mode 100644 index 000000000000..da94e00b84d3 --- /dev/null +++ b/x/capability/module.go @@ -0,0 +1,117 @@ +package capability + +import ( + "encoding/json" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/gorilla/mux" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + + // TODO: Enable simulation once concrete types are defined. + // _ module.AppModuleSimulation = AppModuleSimulation{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface for the capability module. +type AppModuleBasic struct { +} + +func NewAppModuleBasic() AppModuleBasic { + return AppModuleBasic{} +} + +// Name returns the capability module's name. +func (AppModuleBasic) Name() string { + return ModuleName +} + +// RegisterCodec registers the capability module's types to the provided codec. +func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { + RegisterCodec(cdc) +} + +// DefaultGenesis returns the capability module's default genesis state. +func (AppModuleBasic) DefaultGenesis() json.RawMessage { return []byte("{}") } + +// ValidateGenesis performs genesis state validation for the capability module. +func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { return nil } + +// RegisterRESTRoutes registers the capability module's REST service handlers. +func (a AppModuleBasic) RegisterRESTRoutes(_ context.CLIContext, _ *mux.Router) {} + +// GetTxCmd returns the capability module's root tx command. +func (a AppModuleBasic) GetTxCmd(_ *codec.Codec) *cobra.Command { return nil } + +// GetTxCmd returns the capability module's root query command. +func (AppModuleBasic) GetQueryCmd(_ *codec.Codec) *cobra.Command { return nil } + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface for the capability module. +type AppModule struct { + AppModuleBasic + + keeper Keeper +} + +func NewAppModule(keeper Keeper) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(), + keeper: keeper, + } +} + +// Name returns the capability module's name. +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// Route returns the capability module's message routing key. +func (AppModule) Route() string { return "" } + +// QuerierRoute returns the capability module's query routing key. +func (AppModule) QuerierRoute() string { return "" } + +// NewHandler returns the capability module's message Handler. +func (am AppModule) NewHandler() sdk.Handler { return nil } + +// NewQuerierHandler returns the capability module's Querier. +func (am AppModule) NewQuerierHandler() sdk.Querier { return nil } + +// RegisterInvariants registers the capability module's invariants. +func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} + +// InitGenesis performs the capability module's genesis initialization It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, bz json.RawMessage) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { + return am.DefaultGenesis() +} + +// BeginBlock executes all ABCI BeginBlock logic respective to the capability module. +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {} + +// EndBlock executes all ABCI EndBlock logic respective to the capability module. It +// returns no validator updates. +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} diff --git a/x/capability/types/codec.go b/x/capability/types/codec.go index 7b7cea97dcf4..7b483557f2ae 100644 --- a/x/capability/types/codec.go +++ b/x/capability/types/codec.go @@ -12,6 +12,9 @@ var ModuleCdc = codec.New() // capability module. func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*Capability)(nil), nil) + cdc.RegisterConcrete(&CapabilityKey{}, "cosmos-sdk/CapabilityKey", nil) + cdc.RegisterConcrete(Owner{}, "cosmos-sdk/Owner", nil) + cdc.RegisterConcrete(&CapabilityOwners{}, "cosmos-sdk/CapabilityOwners", nil) } // RegisterCapabilityTypeCodec registers an external concrete Capability type diff --git a/x/capability/types/keys.go b/x/capability/types/keys.go index 6c1a6ddf2fae..99c32b59e919 100644 --- a/x/capability/types/keys.go +++ b/x/capability/types/keys.go @@ -48,5 +48,9 @@ func IndexToKey(index uint64) []byte { // IndexFromKey returns an index from a call to IndexToKey for a given capability // index. func IndexFromKey(key []byte) uint64 { + if len(key) == 0 { + return 0 + } + return binary.LittleEndian.Uint64(key) } From e9298322476d44f54e7ef133c42455d6daaeb2a6 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 13:12:40 -0400 Subject: [PATCH 129/176] Use big endian --- types/utils.go | 10 ++++++++++ x/capability/types/keys.go | 13 ++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/types/utils.go b/types/utils.go index 2a6add6b45b4..ef62f51ae2ed 100644 --- a/types/utils.go +++ b/types/utils.go @@ -49,6 +49,16 @@ func Uint64ToBigEndian(i uint64) []byte { return b } +// BigEndianToUint64 returns an uint64 from big endian encoded bytes. If encoding +// is empty, zero is returned. +func BigEndianToUint64(bz []byte) uint64 { + if len(bz) == 0 { + return 0 + } + + return binary.BigEndian.Uint64(bz) +} + // Slight modification of the RFC3339Nano but it right pads all zeros and drops the time zone info const SortableTimeFormat = "2006-01-02T15:04:05.000000000" diff --git a/x/capability/types/keys.go b/x/capability/types/keys.go index 99c32b59e919..1db474bc635e 100644 --- a/x/capability/types/keys.go +++ b/x/capability/types/keys.go @@ -1,8 +1,9 @@ package types import ( - "encoding/binary" "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( @@ -40,17 +41,11 @@ func FwdCapabilityKey(module string, cap Capability) []byte { // IndexToKey returns bytes to be used as a key for a given capability index. func IndexToKey(index uint64) []byte { - buf := make([]byte, 8) - binary.LittleEndian.PutUint64(buf, index) - return buf + return sdk.Uint64ToBigEndian(index) } // IndexFromKey returns an index from a call to IndexToKey for a given capability // index. func IndexFromKey(key []byte) uint64 { - if len(key) == 0 { - return 0 - } - - return binary.LittleEndian.Uint64(key) + return sdk.BigEndianToUint64(key) } From 3a95ff8c741226e73166c5a16998e4a2c3d04368 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 13:28:49 -0400 Subject: [PATCH 130/176] More unit tests --- x/capability/keeper/keeper_test.go | 62 +++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index 82e94ee2550d..4f837b3caae6 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "fmt" "testing" "github.com/stretchr/testify/suite" @@ -11,6 +12,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/capability" "github.com/cosmos/cosmos-sdk/x/capability/keeper" + "github.com/cosmos/cosmos-sdk/x/capability/types" + "github.com/cosmos/cosmos-sdk/x/staking" ) type KeeperTestSuite struct { @@ -38,23 +41,70 @@ func (suite *KeeperTestSuite) SetupTest() { func (suite *KeeperTestSuite) TestInitializeAndSeal() { sk := suite.keeper.ScopeToModule(bank.ModuleName) - cap, err := sk.NewCapability(suite.ctx, "transfer") - suite.Require().NoError(err) - suite.Require().NotNil(cap) + caps := make([]types.Capability, 5) + + for i := range caps { + cap, err := sk.NewCapability(suite.ctx, fmt.Sprintf("transfer-%d", i)) + suite.Require().NoError(err) + suite.Require().NotNil(cap) + suite.Require().Equal(uint64(i), cap.GetIndex()) + + caps[i] = cap + } suite.Require().NotPanics(func() { suite.keeper.InitializeAndSeal(suite.ctx) }) - got, ok := sk.GetCapability(suite.ctx, "transfer") - suite.Require().True(ok) - suite.Require().Equal(cap, got) + for i, cap := range caps { + got, ok := sk.GetCapability(suite.ctx, fmt.Sprintf("transfer-%d", i)) + suite.Require().True(ok) + suite.Require().Equal(cap, got) + suite.Require().Equal(uint64(i), got.GetIndex()) + } suite.Require().Panics(func() { suite.keeper.InitializeAndSeal(suite.ctx) }) } +func (suite *KeeperTestSuite) TestNewCapability() { + sk := suite.keeper.ScopeToModule(bank.ModuleName) + + cap, err := sk.NewCapability(suite.ctx, "transfer") + suite.Require().NoError(err) + suite.Require().NotNil(cap) + + got, ok := sk.GetCapability(suite.ctx, "transfer") + suite.Require().True(ok) + suite.Require().Equal(cap, got) + + cap, err = sk.NewCapability(suite.ctx, "transfer") + suite.Require().Error(err) + suite.Require().Nil(cap) +} + +func (suite *KeeperTestSuite) TestAuthenticateCapability() { + sk1 := suite.keeper.ScopeToModule(bank.ModuleName) + sk2 := suite.keeper.ScopeToModule(staking.ModuleName) + + cap1, err := sk1.NewCapability(suite.ctx, "transfer") + suite.Require().NoError(err) + suite.Require().NotNil(cap1) + + cap2, err := sk2.NewCapability(suite.ctx, "bond") + suite.Require().NoError(err) + suite.Require().NotNil(cap2) + + suite.Require().True(sk1.AuthenticateCapability(suite.ctx, cap1, "transfer")) + suite.Require().False(sk1.AuthenticateCapability(suite.ctx, cap1, "invalid")) + suite.Require().False(sk1.AuthenticateCapability(suite.ctx, cap2, "transfer")) + + suite.Require().True(sk2.AuthenticateCapability(suite.ctx, cap2, "bond")) + suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap2, "invalid")) + suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap1, "bond")) +} + func TestKeeperTestSuite(t *testing.T) { suite.Run(t, new(KeeperTestSuite)) } From 9e463688d693105c321bf95465d84087417e5e98 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 14:01:13 -0400 Subject: [PATCH 131/176] Increase keeper test coverage --- x/capability/keeper/keeper.go | 6 ++++-- x/capability/keeper/keeper_test.go | 32 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 0434d03beafa..60a8007a5a01 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -104,7 +104,7 @@ func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { index := types.IndexFromKey(iterator.Key()) cap := types.NewCapabilityKey(index) - var capOwners types.CapabilityOwners + var capOwners *types.CapabilityOwners k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &capOwners) for _, owner := range capOwners.Owners { @@ -180,6 +180,8 @@ func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap types.Capabil // it will return an error. Otherwise, it will also set a forward and reverse index // for the capability and capability name. func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, name string) error { + // TODO: Do we need to authenticate the capability against the name first? + // update capability owner set if err := sk.addOwner(ctx, cap, name); err != nil { return err @@ -227,7 +229,7 @@ func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap types.Capability, name stri if len(bz) == 0 { capOwners = types.NewCapabilityOwners() } else { - sk.cdc.MustUnmarshalBinaryBare(bz, capOwners) + sk.cdc.MustUnmarshalBinaryBare(bz, &capOwners) } if err := capOwners.Set(types.NewOwner(sk.module, name)); err != nil { diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index 4f837b3caae6..515d78b1a137 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -66,6 +66,10 @@ func (suite *KeeperTestSuite) TestInitializeAndSeal() { suite.Require().Panics(func() { suite.keeper.InitializeAndSeal(suite.ctx) }) + + suite.Require().Panics(func() { + _ = suite.keeper.ScopeToModule(staking.ModuleName) + }) } func (suite *KeeperTestSuite) TestNewCapability() { @@ -79,6 +83,10 @@ func (suite *KeeperTestSuite) TestNewCapability() { suite.Require().True(ok) suite.Require().Equal(cap, got) + got, ok = sk.GetCapability(suite.ctx, "invalid") + suite.Require().False(ok) + suite.Require().Nil(got) + cap, err = sk.NewCapability(suite.ctx, "transfer") suite.Require().Error(err) suite.Require().Nil(cap) @@ -103,6 +111,30 @@ func (suite *KeeperTestSuite) TestAuthenticateCapability() { suite.Require().True(sk2.AuthenticateCapability(suite.ctx, cap2, "bond")) suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap2, "invalid")) suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap1, "bond")) + + badCap := types.NewCapabilityKey(100) + suite.Require().False(sk1.AuthenticateCapability(suite.ctx, badCap, "transfer")) + suite.Require().False(sk2.AuthenticateCapability(suite.ctx, badCap, "bond")) +} + +func (suite *KeeperTestSuite) TestClaimCapability() { + sk1 := suite.keeper.ScopeToModule(bank.ModuleName) + sk2 := suite.keeper.ScopeToModule(staking.ModuleName) + + cap, err := sk1.NewCapability(suite.ctx, "transfer") + suite.Require().NoError(err) + suite.Require().NotNil(cap) + + suite.Require().Error(sk1.ClaimCapability(suite.ctx, cap, "transfer")) + suite.Require().NoError(sk2.ClaimCapability(suite.ctx, cap, "transfer")) + + got, ok := sk1.GetCapability(suite.ctx, "transfer") + suite.Require().True(ok) + suite.Require().Equal(cap, got) + + got, ok = sk2.GetCapability(suite.ctx, "transfer") + suite.Require().True(ok) + suite.Require().Equal(cap, got) } func TestKeeperTestSuite(t *testing.T) { From abc15d88afd8a1413378c909c7518a1969a4bffb Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 14:02:55 -0400 Subject: [PATCH 132/176] Remove TODO --- x/capability/keeper/keeper.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 60a8007a5a01..00e65599f531 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -180,8 +180,6 @@ func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap types.Capabil // it will return an error. Otherwise, it will also set a forward and reverse index // for the capability and capability name. func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, name string) error { - // TODO: Do we need to authenticate the capability against the name first? - // update capability owner set if err := sk.addOwner(ctx, cap, name); err != nil { return err From 74d09b9aeb2991df7061f1cabf13dd8be22a8956 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 14:37:24 -0400 Subject: [PATCH 133/176] Add module doc --- x/capability/docs/README.md | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 x/capability/docs/README.md diff --git a/x/capability/docs/README.md b/x/capability/docs/README.md new file mode 100644 index 000000000000..9a259e45ac0a --- /dev/null +++ b/x/capability/docs/README.md @@ -0,0 +1,63 @@ +# x/capability + +## Abstract + +`x/capability` is an implementation of a Cosmos SDK module, per [ADR 003](./../../../docs/architecture/adr-003-dynamic-capability-store.md), +that allows for provisioning, tracking, and authenticating multi-owner capabilities +at runtime. + +The keeper maintains two states: persistent and ephemeral in-memory. The persistent +store maintains a globally unique auto-incrementing index and a mapping from +capability index to a set of capability owners that are defined as a module and +capability name tuple. The in-memory ephemeral state keeps track of the actual +capabilities with both forward and reverse indexes. The forward index maps +module name and capability tuples to the capability name. The reverse index maps +between the module and capability name and the capability itself. + +The keeper allows the creation of "scoped" sub-keepers which are tied to a particular +module by name. Scoped keepers must be created at application initialization and +passed to modules, which can then use them to claim capabilities they receive and +retrieve capabilities which they own by name, in addition to creating new capabilities +& authenticating capabilities passed by other modules. + +The keeper provides no other core functionality that can be found in other modules +like queriers, REST and CLI handlers, and genesis state. + +## Initialization + +During application initialization, the keeper must be instantiated with a persistent +store key and an in-memory store key. + +```go +type App struct { + // ... + + capabilityKeeper *capability.Keeper +} + +func NewApp(...) *App { + // ... + + app.capabilityKeeper = capability.NewKeeper(codec, persistentStoreKey, memStoreKey) +} +``` + +After the keeper is created, it can be used to create scoped sub-keepers which +are passed to other modules that can create, authenticate, and claim capabilities. +After all the necessary scoped keepers are created and the state is loaded, the +main capability keeper must be initialized and sealed to populate the in-memory +state and to prevent further scoped keepers from being created. + +```go +func NewApp(...) *App { + // ... + + // Initialize and seal the capability keeper so all persistent capabilities + // are loaded in-memory and prevent any further modules from creating scoped + // sub-keepers. + ctx := app.BaseApp.NewContext(true, abci.Header{}) + app.capabilityKeeper.InitializeAndSeal(ctx) + + return app +} +``` From 083494cb58ebd375fbff4db182616f3e16e26617 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Mar 2020 15:12:02 -0400 Subject: [PATCH 134/176] Update doc --- x/capability/docs/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/x/capability/docs/README.md b/x/capability/docs/README.md index 9a259e45ac0a..63a67a001603 100644 --- a/x/capability/docs/README.md +++ b/x/capability/docs/README.md @@ -61,3 +61,27 @@ func NewApp(...) *App { return app } ``` + +## Capabilities + +Capabilities are multi-owner. A scoped keeper can create a capability via `NewCapability` +which creates a new unique, unforgeable object-capability reference. The newly +created capability is automatically persisted; the calling module need not call +`ClaimCapability`. Calling `NewCapability` will create the capability with the +calling module and name as a tuple to be treated the capabilities first owner. + +Capabilities can be claimed by other modules which add them as owners. `ClaimCapability` +allows a module to claim a capability key which it has received from another +module so that future `GetCapability` calls will succeed. `ClaimCapability` MUST +be called if a module which receives a capability wishes to access it by name in +the future. Again, capabilities are multi-owner, so if multiple modules have a +single Capability reference, they will all own it. + +`AuthenticateCapability` can be called by any module to check that a capability +does in fact correspond to a particular name (the name can be un-trusted user input) +with which the calling module previously associated it. + +`GetCapability` allows a module to fetch a capability which it has previously +claimed by name. The module is not allowed to retrieve capabilities which it does +not own. If another module claims a capability, the previously owning module will +no longer be able to claim it. From d6b5f5b92ea21098f8ed40d0c276b804af4dbb16 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 23 Mar 2020 11:37:17 +0100 Subject: [PATCH 135/176] Apply suggestions from code review Co-Authored-By: Aditya --- store/mem/store.go | 4 ++-- x/capability/docs/README.md | 9 ++++----- x/capability/keeper/keeper.go | 5 ++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/store/mem/store.go b/store/mem/store.go index 2a436ee15424..8987a37adff9 100644 --- a/store/mem/store.go +++ b/store/mem/store.go @@ -16,8 +16,8 @@ var ( _ types.Committer = (*Store)(nil) ) -// Store implements an in-memory only KVStore. Entries are peresistent between -// commits and thus between blocks. +// Store implements an in-memory only KVStore. Entries are persisted between +// commits and thus between blocks. State in Memory store is not committed as part of app state but maintained privately by each node type Store struct { dbadapter.Store } diff --git a/x/capability/docs/README.md b/x/capability/docs/README.md index 63a67a001603..395e5b69c84f 100644 --- a/x/capability/docs/README.md +++ b/x/capability/docs/README.md @@ -10,7 +10,7 @@ The keeper maintains two states: persistent and ephemeral in-memory. The persist store maintains a globally unique auto-incrementing index and a mapping from capability index to a set of capability owners that are defined as a module and capability name tuple. The in-memory ephemeral state keeps track of the actual -capabilities with both forward and reverse indexes. The forward index maps +capabilities, represented as addresses in local memory, with both forward and reverse indexes. The forward index maps module name and capability tuples to the capability name. The reverse index maps between the module and capability name and the capability itself. @@ -18,7 +18,7 @@ The keeper allows the creation of "scoped" sub-keepers which are tied to a parti module by name. Scoped keepers must be created at application initialization and passed to modules, which can then use them to claim capabilities they receive and retrieve capabilities which they own by name, in addition to creating new capabilities -& authenticating capabilities passed by other modules. +& authenticating capabilities passed by other modules. A scoped keeper cannot escape its scope, so a module cannot interfere with or inspect capabilities owned by other modules. The keeper provides no other core functionality that can be found in other modules like queriers, REST and CLI handlers, and genesis state. @@ -75,7 +75,7 @@ allows a module to claim a capability key which it has received from another module so that future `GetCapability` calls will succeed. `ClaimCapability` MUST be called if a module which receives a capability wishes to access it by name in the future. Again, capabilities are multi-owner, so if multiple modules have a -single Capability reference, they will all own it. +single Capability reference, they will all own it. If a module receives a capability from another module but does not call `ClaimCapability`, it may use it in the executing transaction but will not be able to access it afterwards. `AuthenticateCapability` can be called by any module to check that a capability does in fact correspond to a particular name (the name can be un-trusted user input) @@ -83,5 +83,4 @@ with which the calling module previously associated it. `GetCapability` allows a module to fetch a capability which it has previously claimed by name. The module is not allowed to retrieve capabilities which it does -not own. If another module claims a capability, the previously owning module will -no longer be able to claim it. +not own. diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 00e65599f531..3f30be774e2a 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -166,7 +166,7 @@ func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capabi // true upon success and false upon failure. // // Note, the capability's forward mapping is indexed by a string which should -// contain it's unique memory reference. +// contain its unique memory reference. func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap types.Capability, name string) bool { memStore := ctx.KVStore(sk.memKey) @@ -201,8 +201,7 @@ func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, na // GetCapability allows a module to fetch a capability which it previously claimed // by name. The module is not allowed to retrieve capabilities which it does not -// own. If another module claims a capability, the previously owning module will -// no longer be able to claim it. +// own. func (sk ScopedKeeper) GetCapability(ctx sdk.Context, name string) (types.Capability, bool) { memStore := ctx.KVStore(sk.memKey) From c5e9c605e888817fa8b1c78941b3280b6abc85a7 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 23 Mar 2020 10:49:13 -0400 Subject: [PATCH 136/176] Update NewCapability godoc --- x/capability/keeper/keeper.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 3f30be774e2a..3a5be5e7bdf5 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -123,10 +123,13 @@ func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { // NewCapability attempts to create a new capability with a given name. If the // capability already exists in the in-memory store, an error will be returned. -// Otherwise, a new capability is created with the current global index. The -// newly created capability has the module and name tuple set as the initial owner. -// Finally, the global index is incremented along with forward and reverse indexes -// set in the in-memory store. +// Otherwise, a new capability is created with the current global unique index. +// The newly created capability has the module and name tuple set as the initial +// owner. Finally, the global index is incremented along with forward and reverse +// indexes set in the in-memory store. +// +// Note, namespacing is completely local, which is safe since records are prefixed +// with the module name and no two ScopedKeeper can have the same module name. func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capability, error) { store := ctx.KVStore(sk.storeKey) memStore := ctx.KVStore(sk.memKey) From 0fa35229dfe8d651ac96be5bca291f834138c020 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 23 Mar 2020 11:06:43 -0400 Subject: [PATCH 137/176] Clarify owner --- x/capability/keeper/keeper.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 3a5be5e7bdf5..03bd897a3832 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -124,9 +124,9 @@ func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { // NewCapability attempts to create a new capability with a given name. If the // capability already exists in the in-memory store, an error will be returned. // Otherwise, a new capability is created with the current global unique index. -// The newly created capability has the module and name tuple set as the initial -// owner. Finally, the global index is incremented along with forward and reverse -// indexes set in the in-memory store. +// The newly created capability has the scoped module name and capability name +// tuple set as the initial owner. Finally, the global index is incremented along +// with forward and reverse indexes set in the in-memory store. // // Note, namespacing is completely local, which is safe since records are prefixed // with the module name and no two ScopedKeeper can have the same module name. @@ -177,11 +177,11 @@ func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap types.Capabil return string(bz) == name } -// ClaimCapability attempts to claim a given Capability and name tuple. This tuple -// is considered an Owner. It will attempt to add the owner to the persistent -// set of capability owners for the capability index. If the owner already exists, -// it will return an error. Otherwise, it will also set a forward and reverse index -// for the capability and capability name. +// ClaimCapability attempts to claim a given Capability. The provided name and +// the scoped module's name tuple are treated as the owner. It will attempt +// to add the owner to the persistent set of capability owners for the capability +// index. If the owner already exists, it will return an error. Otherwise, it will +// also set a forward and reverse index for the capability and capability name. func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, name string) error { // update capability owner set if err := sk.addOwner(ctx, cap, name); err != nil { From f3a514aa11607b55920e1bf3cdc128e87590fb0a Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 23 Mar 2020 11:13:10 -0400 Subject: [PATCH 138/176] Add forgery test case to TestAuthenticateCapability --- x/capability/keeper/keeper_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index 515d78b1a137..dc52d9b96d5e 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -100,6 +100,9 @@ func (suite *KeeperTestSuite) TestAuthenticateCapability() { suite.Require().NoError(err) suite.Require().NotNil(cap1) + forgedCap := types.NewCapabilityKey(0) // index should be the same index as the first capability + suite.Require().False(sk2.AuthenticateCapability(suite.ctx, forgedCap, "transfer")) + cap2, err := sk2.NewCapability(suite.ctx, "bond") suite.Require().NoError(err) suite.Require().NotNil(cap2) From 1db27ad73706f14831162a6129cfc7ff55e22f81 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 23 Mar 2020 11:17:12 -0400 Subject: [PATCH 139/176] Format doc --- x/capability/docs/README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/x/capability/docs/README.md b/x/capability/docs/README.md index 395e5b69c84f..a280743d7edf 100644 --- a/x/capability/docs/README.md +++ b/x/capability/docs/README.md @@ -10,15 +10,16 @@ The keeper maintains two states: persistent and ephemeral in-memory. The persist store maintains a globally unique auto-incrementing index and a mapping from capability index to a set of capability owners that are defined as a module and capability name tuple. The in-memory ephemeral state keeps track of the actual -capabilities, represented as addresses in local memory, with both forward and reverse indexes. The forward index maps -module name and capability tuples to the capability name. The reverse index maps -between the module and capability name and the capability itself. +capabilities, represented as addresses in local memory, with both forward and reverse indexes. +The forward index maps module name and capability tuples to the capability name. The +reverse index maps between the module and capability name and the capability itself. The keeper allows the creation of "scoped" sub-keepers which are tied to a particular module by name. Scoped keepers must be created at application initialization and passed to modules, which can then use them to claim capabilities they receive and retrieve capabilities which they own by name, in addition to creating new capabilities -& authenticating capabilities passed by other modules. A scoped keeper cannot escape its scope, so a module cannot interfere with or inspect capabilities owned by other modules. +& authenticating capabilities passed by other modules. A scoped keeper cannot escape its scope, +so a module cannot interfere with or inspect capabilities owned by other modules. The keeper provides no other core functionality that can be found in other modules like queriers, REST and CLI handlers, and genesis state. @@ -75,7 +76,9 @@ allows a module to claim a capability key which it has received from another module so that future `GetCapability` calls will succeed. `ClaimCapability` MUST be called if a module which receives a capability wishes to access it by name in the future. Again, capabilities are multi-owner, so if multiple modules have a -single Capability reference, they will all own it. If a module receives a capability from another module but does not call `ClaimCapability`, it may use it in the executing transaction but will not be able to access it afterwards. +single Capability reference, they will all own it. If a module receives a capability +from another module but does not call `ClaimCapability`, it may use it in the executing +transaction but will not be able to access it afterwards. `AuthenticateCapability` can be called by any module to check that a capability does in fact correspond to a particular name (the name can be un-trusted user input) From 6f2a9dd8c74daab28c060b0c8266b826714824f7 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Mon, 23 Mar 2020 09:28:37 -0700 Subject: [PATCH 140/176] Update to tm@v0.33.2 --- go.mod | 2 +- go.sum | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 2ce3f1b68ae4..d2886464809c 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 github.com/tendermint/go-amino v0.15.1 github.com/tendermint/iavl v0.13.0 - github.com/tendermint/tendermint v0.33.1-dev3 + github.com/tendermint/tendermint v0.33.2 github.com/tendermint/tm-db v0.4.1 gopkg.in/yaml.v2 v2.2.8 ) diff --git a/go.sum b/go.sum index 115d20bafff0..7709269a94a4 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,7 @@ github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrd github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/Workiva/go-datastructures v1.0.51/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -431,6 +432,8 @@ github.com/tendermint/tendermint v0.33.1-dev3 h1:bxc7zwOZyt4E/7Bte7ii5nL7j+gbBah github.com/tendermint/tendermint v0.33.1-dev3/go.mod h1:CRiNrmGG8HSRJyj8j69k/vKauv97R54Md9zWlEx+gdg= github.com/tendermint/tendermint v0.33.1 h1:8f68LUBz8yhISZvaLFP4siXXrLWsWeoYfelbdNtmvm4= github.com/tendermint/tendermint v0.33.1/go.mod h1:fBOKyrlXOETqQ+heL8x/TZgSdmItON54csyabvktBp0= +github.com/tendermint/tendermint v0.33.2 h1:NzvRMTuXJxqSsFed2J7uHmMU5N1CVzSpfi3nCc882KY= +github.com/tendermint/tendermint v0.33.2/go.mod h1:25DqB7YvV1tN3tHsjWoc2vFtlwICfrub9XO6UBO+4xk= github.com/tendermint/tm-db v0.4.0 h1:iPbCcLbf4nwDFhS39Zo1lpdS1X/cT9CkTlUx17FHQgA= github.com/tendermint/tm-db v0.4.0/go.mod h1:+Cwhgowrf7NBGXmsqFMbwEtbo80XmyrlY5Jsk95JubQ= github.com/tendermint/tm-db v0.4.1 h1:TvX7JWjJOVZ+N3y+I86wddrGttOdMmmBxXcu0/Y7ZJ0= From 290344c9e03cb5ab21f6606b884faedb20030c39 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 23 Mar 2020 12:38:48 -0400 Subject: [PATCH 141/176] Update ADR --- docs/architecture/adr-003-dynamic-capability-store.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/architecture/adr-003-dynamic-capability-store.md b/docs/architecture/adr-003-dynamic-capability-store.md index 7fd438fd931c..c1dbf4741f5c 100644 --- a/docs/architecture/adr-003-dynamic-capability-store.md +++ b/docs/architecture/adr-003-dynamic-capability-store.md @@ -171,8 +171,7 @@ func (sck ScopedCapabilityKeeper) ClaimCapability(ctx Context, capability Capabi } ``` -`GetCapability` allows a module to fetch a capability which it has previously claimed by name. The module is not allowed to retrieve capabilities which it does not own. If another module -claims a capability, the previously owning module will no longer be able to claim it. +`GetCapability` allows a module to fetch a capability which it has previously claimed by name. The module is not allowed to retrieve capabilities which it does not own. ```golang func (sck ScopedCapabilityKeeper) GetCapability(ctx Context, name string) (Capability, error) { From 76a5c3e5e2715232f7d591b60115dd7649d607a7 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 23 Mar 2020 12:40:33 -0400 Subject: [PATCH 142/176] Explicitly take pointer in FwdCapabilityKey --- x/capability/types/keys.go | 2 +- x/capability/types/keys_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x/capability/types/keys.go b/x/capability/types/keys.go index 1db474bc635e..76726015246b 100644 --- a/x/capability/types/keys.go +++ b/x/capability/types/keys.go @@ -36,7 +36,7 @@ func RevCapabilityKey(module, name string) []byte { // FwdCapabilityKey returns a forward lookup key for a given module and capability // reference. func FwdCapabilityKey(module string, cap Capability) []byte { - return []byte(fmt.Sprintf("%s/fwd/%s", module, cap)) + return []byte(fmt.Sprintf("%s/fwd/%p", module, cap)) } // IndexToKey returns bytes to be used as a key for a given capability index. diff --git a/x/capability/types/keys_test.go b/x/capability/types/keys_test.go index b4a0168912b2..fb380888e90f 100644 --- a/x/capability/types/keys_test.go +++ b/x/capability/types/keys_test.go @@ -16,14 +16,14 @@ func TestRevCapabilityKey(t *testing.T) { func TestFwdCapabilityKey(t *testing.T) { cap := types.NewCapabilityKey(23) - expected := []byte(fmt.Sprintf("bank/fwd/%s", cap)) + expected := []byte(fmt.Sprintf("bank/fwd/%p", cap)) require.Equal(t, expected, types.FwdCapabilityKey("bank", cap)) } func TestIndexToKey(t *testing.T) { - require.Equal(t, []byte{0x5a, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, types.IndexToKey(3162)) + require.Equal(t, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5a}, types.IndexToKey(3162)) } func TestIndexFromKey(t *testing.T) { - require.Equal(t, uint64(3162), types.IndexFromKey([]byte{0x5a, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})) + require.Equal(t, uint64(3162), types.IndexFromKey([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5a})) } From 82afa7da02a820e940d5dd6c2983e9cf33715f47 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 23 Mar 2020 14:25:15 -0400 Subject: [PATCH 143/176] Update set to be logn --- x/capability/types/types.go | 21 ++++++++++++++------- x/capability/types/types_test.go | 27 +++++++++++++++++++++------ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/x/capability/types/types.go b/x/capability/types/types.go index e6da5535d0d9..afa5b79b4e93 100644 --- a/x/capability/types/types.go +++ b/x/capability/types/types.go @@ -2,6 +2,7 @@ package types import ( "fmt" + "sort" "gopkg.in/yaml.v2" @@ -72,15 +73,21 @@ func NewCapabilityOwners() *CapabilityOwners { return &CapabilityOwners{Owners: make([]Owner, 0)} } -// Set attempts to add a given owner to the CapabilityOwners. If the owner already -// exists, an error will be returned. +// Set attempts to add a given owner to the CapabilityOwners. If the owner +// already exists, an error will be returned. Set runs in O(log n) average time +// and O(n) in the worst case. func (co *CapabilityOwners) Set(owner Owner) error { - for _, o := range co.Owners { - if o.Key() == owner.Key() { - return sdkerrors.Wrapf(ErrOwnerClaimed, owner.String()) - } + // find smallest index s.t. co.Owners[i] >= owner in O(log n) time + i := sort.Search(len(co.Owners), func(i int) bool { return co.Owners[i].Key() >= owner.Key() }) + if i < len(co.Owners) && co.Owners[i].Key() == owner.Key() { + // owner already exists at co.Owners[i] + return sdkerrors.Wrapf(ErrOwnerClaimed, owner.String()) } - co.Owners = append(co.Owners, owner) + // owner does not exist in the set of owners, so we insert at position i + co.Owners = append(co.Owners, Owner{}) // expand by 1 in amortized O(1) / O(n) worst case + copy(co.Owners[i+1:], co.Owners[i:]) + co.Owners[i] = owner + return nil } diff --git a/x/capability/types/types_test.go b/x/capability/types/types_test.go index 74da351d7ac3..0c1ba6e3d3bc 100644 --- a/x/capability/types/types_test.go +++ b/x/capability/types/types_test.go @@ -2,6 +2,7 @@ package types_test import ( "fmt" + "sort" "testing" "github.com/stretchr/testify/require" @@ -24,11 +25,25 @@ func TestOwner(t *testing.T) { func TestCapabilityOwners(t *testing.T) { co := types.NewCapabilityOwners() - o1 := types.NewOwner("bank", "send") - o2 := types.NewOwner("slashing", "slash") - require.NoError(t, co.Set(o1)) - require.Error(t, co.Set(o1)) - require.NoError(t, co.Set(o2)) - require.Equal(t, []types.Owner{o1, o2}, co.Owners) + owners := make([]types.Owner, 1024) + for i := range owners { + var owner types.Owner + + if i%2 == 0 { + owner = types.NewOwner("bank", fmt.Sprintf("send-%d", i)) + } else { + owner = types.NewOwner("slashing", fmt.Sprintf("slash-%d", i)) + } + + owners[i] = owner + require.NoError(t, co.Set(owner)) + } + + sort.Slice(owners, func(i, j int) bool { return owners[i].Key() < owners[j].Key() }) + require.Equal(t, owners, co.Owners) + + for _, owner := range owners { + require.Error(t, co.Set(owner)) + } } From a8efe0fd05450ceb452d64ee3bf43c2a12f2d28a Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 23 Mar 2020 14:37:08 -0400 Subject: [PATCH 144/176] Update app module --- x/capability/module.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/x/capability/module.go b/x/capability/module.go index da94e00b84d3..1ee89573c4b4 100644 --- a/x/capability/module.go +++ b/x/capability/module.go @@ -44,10 +44,10 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { } // DefaultGenesis returns the capability module's default genesis state. -func (AppModuleBasic) DefaultGenesis() json.RawMessage { return []byte("{}") } +func (AppModuleBasic) DefaultGenesis(_ codec.JSONMarshaler) json.RawMessage { return []byte("{}") } // ValidateGenesis performs genesis state validation for the capability module. -func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { return nil } +func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, _ json.RawMessage) error { return nil } // RegisterRESTRoutes registers the capability module's REST service handlers. func (a AppModuleBasic) RegisterRESTRoutes(_ context.CLIContext, _ *mux.Router) {} @@ -94,24 +94,24 @@ func (am AppModule) NewHandler() sdk.Handler { return nil } func (am AppModule) NewQuerierHandler() sdk.Querier { return nil } // RegisterInvariants registers the capability module's invariants. -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} // InitGenesis performs the capability module's genesis initialization It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, bz json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(_ sdk.Context, _ codec.JSONMarshaler, _ json.RawMessage) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } // ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. -func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { - return am.DefaultGenesis() +func (am AppModule) ExportGenesis(_ sdk.Context, cdc codec.JSONMarshaler) json.RawMessage { + return am.DefaultGenesis(cdc) } // BeginBlock executes all ABCI BeginBlock logic respective to the capability module. -func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {} +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} // EndBlock executes all ABCI EndBlock logic respective to the capability module. It // returns no validator updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } From 9b4f448c57d5e00bba3511f56f6d263f615445cd Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 23 Mar 2020 14:50:45 -0400 Subject: [PATCH 145/176] Lint --- store/mem/store.go | 2 +- x/capability/alias.go | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/store/mem/store.go b/store/mem/store.go index 8987a37adff9..3a1cdd617a0a 100644 --- a/store/mem/store.go +++ b/store/mem/store.go @@ -26,7 +26,7 @@ func NewStore() *Store { return NewStoreWithDB(dbm.NewMemDB()) } -func NewStoreWithDB(db *dbm.MemDB) *Store { +func NewStoreWithDB(db *dbm.MemDB) *Store { // nolint: interfacer return &Store{Store: dbadapter.Store{DB: db}} } diff --git a/x/capability/alias.go b/x/capability/alias.go index 3066ca7068dc..3aa949677e50 100644 --- a/x/capability/alias.go +++ b/x/capability/alias.go @@ -5,15 +5,16 @@ import ( "github.com/cosmos/cosmos-sdk/x/capability/types" ) -// nolint // DONTCOVER +// nolint const ( ModuleName = types.ModuleName StoreKey = types.StoreKey MemStoreKey = types.MemStoreKey ) +// nolint var ( NewKeeper = keeper.NewKeeper NewCapabilityKey = types.NewCapabilityKey @@ -30,6 +31,7 @@ var ( NewCapabilityOwners = types.NewCapabilityOwners ) +// nolint type ( Keeper = keeper.Keeper ScopedKeeper = keeper.ScopedKeeper From 4a04faa7522b0fff342ca59c328322a9055e43c0 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Wed, 25 Mar 2020 07:38:08 -0700 Subject: [PATCH 146/176] Fix broken test after packet format changed --- x/ibc/04-channel/types/msgs_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index 197d5231cac3..bea0e43995be 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -476,7 +476,7 @@ func TestMsgPacketGetSignBytes(t *testing.T) { SubModuleCdc.RegisterConcrete(validPacketT{}, "test/validPacketT", nil) res := msg.GetSignBytes() - expected := `{"packet":{"data":{"type":"test/validPacketT","value":{}},"destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid"},"proof":{"type":"ibc/commitment/MerkleProof","value":{"proof":{"ops":[]}}},"proof_height":"1","signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}` + expected := `{"type":"ibc/channel/MsgPacket","value":{"packet":{"data":{"type":"test/validPacketT","value":{}},"destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid"},"proof":{"type":"ibc/commitment/MerkleProof","value":{"proof":{"ops":[]}}},"proof_height":"1","signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}}` require.Equal(t, expected, string(res)) } From 087c1024ac41331ad72a17d449473daefb79c102 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 26 Mar 2020 14:55:05 -0400 Subject: [PATCH 147/176] Add stub and unit tests for ReleaseCapability --- x/capability/keeper/keeper.go | 7 +++++++ x/capability/keeper/keeper_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 03bd897a3832..57552e630cee 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -202,6 +202,13 @@ func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, na return nil } +// ReleaseCapability allows a scoped module to release a capability which it had +// previously claimed or created. After releasing the capability, if no more +// owners exist, the capability will be globally removed. +func (sk ScopedKeeper) ReleaseCapability(ctx sdk.Context, cap types.Capability) error { + return nil +} + // GetCapability allows a module to fetch a capability which it previously claimed // by name. The module is not allowed to retrieve capabilities which it does not // own. diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index dc52d9b96d5e..dc9998be11a4 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -140,6 +140,33 @@ func (suite *KeeperTestSuite) TestClaimCapability() { suite.Require().Equal(cap, got) } +func (suite *KeeperTestSuite) TestReleaseCapability() { + sk1 := suite.keeper.ScopeToModule(bank.ModuleName) + sk2 := suite.keeper.ScopeToModule(staking.ModuleName) + + cap1, err := sk1.NewCapability(suite.ctx, "transfer") + suite.Require().NoError(err) + suite.Require().NotNil(cap1) + + suite.Require().NoError(sk2.ClaimCapability(suite.ctx, cap1, "transfer")) + + cap2, err := sk2.NewCapability(suite.ctx, "bond") + suite.Require().NoError(err) + suite.Require().NotNil(cap2) + + suite.Require().Error(sk1.ReleaseCapability(suite.ctx, cap2)) + + suite.Require().NoError(sk2.ReleaseCapability(suite.ctx, cap1)) + got, ok := sk1.GetCapability(suite.ctx, "transfer") + suite.Require().False(ok) + suite.Require().Nil(got) + + suite.Require().NoError(sk1.ReleaseCapability(suite.ctx, cap1)) + got, ok = sk2.GetCapability(suite.ctx, "transfer") + suite.Require().False(ok) + suite.Require().Nil(got) +} + func TestKeeperTestSuite(t *testing.T) { suite.Run(t, new(KeeperTestSuite)) } From 19a8cb1e08a77641a648f7041ff67867a51005f6 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 27 Mar 2020 11:01:44 -0400 Subject: [PATCH 148/176] Finish implementation --- x/capability/alias.go | 1 + x/capability/keeper/keeper.go | 55 +++++++++++++++++++++++++----- x/capability/keeper/keeper_test.go | 4 +-- x/capability/types/errors.go | 5 +-- x/capability/types/types.go | 33 ++++++++++++++++-- x/capability/types/types_test.go | 22 +++++++++++- 6 files changed, 104 insertions(+), 16 deletions(-) diff --git a/x/capability/alias.go b/x/capability/alias.go index 3aa949677e50..7bf21b034e98 100644 --- a/x/capability/alias.go +++ b/x/capability/alias.go @@ -24,6 +24,7 @@ var ( KeyPrefixIndexCapability = types.KeyPrefixIndexCapability ErrCapabilityTaken = types.ErrCapabilityTaken ErrOwnerClaimed = types.ErrOwnerClaimed + ErrCapabilityNotOwned = types.ErrCapabilityNotOwned RegisterCodec = types.RegisterCodec RegisterCapabilityTypeCodec = types.RegisterCapabilityTypeCodec ModuleCdc = types.ModuleCdc diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 57552e630cee..acb33b3912cf 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -206,6 +206,38 @@ func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, na // previously claimed or created. After releasing the capability, if no more // owners exist, the capability will be globally removed. func (sk ScopedKeeper) ReleaseCapability(ctx sdk.Context, cap types.Capability) error { + memStore := ctx.KVStore(sk.memKey) + + bz := memStore.Get(types.FwdCapabilityKey(sk.module, cap)) + if len(bz) == 0 { + return sdkerrors.Wrap(types.ErrCapabilityNotOwned, sk.module) + } + + name := string(bz) + + // Remove the forward mapping between the module and capability tuple and the + // capability name in the in-memory store. + memStore.Delete(types.FwdCapabilityKey(sk.module, cap)) + + // Remove the reverse mapping between the module and capability name and the + // capability in the in-memory store. + memStore.Delete(types.RevCapabilityKey(sk.module, name)) + + // remove owner + capOwners := sk.getOwners(ctx, cap) + capOwners.Remove(types.NewOwner(sk.module, name)) + + prefixStore := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) + indexKey := types.IndexToKey(cap.GetIndex()) + + if len(capOwners.Owners) == 0 { + // remove capability owner set + prefixStore.Delete(indexKey) + } else { + // update capability owner set + prefixStore.Set(indexKey, sk.cdc.MustMarshalBinaryBare(capOwners)) + } + return nil } @@ -230,14 +262,7 @@ func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap types.Capability, name stri prefixStore := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) indexKey := types.IndexToKey(cap.GetIndex()) - var capOwners *types.CapabilityOwners - - bz := prefixStore.Get(indexKey) - if len(bz) == 0 { - capOwners = types.NewCapabilityOwners() - } else { - sk.cdc.MustUnmarshalBinaryBare(bz, &capOwners) - } + capOwners := sk.getOwners(ctx, cap) if err := capOwners.Set(types.NewOwner(sk.module, name)); err != nil { return err @@ -248,6 +273,20 @@ func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap types.Capability, name stri return nil } +func (sk ScopedKeeper) getOwners(ctx sdk.Context, cap types.Capability) (capOwners *types.CapabilityOwners) { + prefixStore := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) + indexKey := types.IndexToKey(cap.GetIndex()) + + bz := prefixStore.Get(indexKey) + if len(bz) == 0 { + capOwners = types.NewCapabilityOwners() + } else { + sk.cdc.MustUnmarshalBinaryBare(bz, &capOwners) + } + + return capOwners +} + func logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index dc9998be11a4..54cec4b2e039 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -157,12 +157,12 @@ func (suite *KeeperTestSuite) TestReleaseCapability() { suite.Require().Error(sk1.ReleaseCapability(suite.ctx, cap2)) suite.Require().NoError(sk2.ReleaseCapability(suite.ctx, cap1)) - got, ok := sk1.GetCapability(suite.ctx, "transfer") + got, ok := sk2.GetCapability(suite.ctx, "transfer") suite.Require().False(ok) suite.Require().Nil(got) suite.Require().NoError(sk1.ReleaseCapability(suite.ctx, cap1)) - got, ok = sk2.GetCapability(suite.ctx, "transfer") + got, ok = sk1.GetCapability(suite.ctx, "transfer") suite.Require().False(ok) suite.Require().Nil(got) } diff --git a/x/capability/types/errors.go b/x/capability/types/errors.go index fbf718e9fecc..bc3354789ca1 100644 --- a/x/capability/types/errors.go +++ b/x/capability/types/errors.go @@ -8,6 +8,7 @@ import ( // x/capability module sentinel errors var ( - ErrCapabilityTaken = sdkerrors.Register(ModuleName, 2, "capability name already taken") - ErrOwnerClaimed = sdkerrors.Register(ModuleName, 3, "given owner already claimed capability") + ErrCapabilityTaken = sdkerrors.Register(ModuleName, 2, "capability name already taken") + ErrOwnerClaimed = sdkerrors.Register(ModuleName, 3, "given owner already claimed capability") + ErrCapabilityNotOwned = sdkerrors.Register(ModuleName, 4, "capability not owned by module") ) diff --git a/x/capability/types/types.go b/x/capability/types/types.go index afa5b79b4e93..484abbff1dd0 100644 --- a/x/capability/types/types.go +++ b/x/capability/types/types.go @@ -77,9 +77,8 @@ func NewCapabilityOwners() *CapabilityOwners { // already exists, an error will be returned. Set runs in O(log n) average time // and O(n) in the worst case. func (co *CapabilityOwners) Set(owner Owner) error { - // find smallest index s.t. co.Owners[i] >= owner in O(log n) time - i := sort.Search(len(co.Owners), func(i int) bool { return co.Owners[i].Key() >= owner.Key() }) - if i < len(co.Owners) && co.Owners[i].Key() == owner.Key() { + i, ok := co.Get(owner) + if ok { // owner already exists at co.Owners[i] return sdkerrors.Wrapf(ErrOwnerClaimed, owner.String()) } @@ -91,3 +90,31 @@ func (co *CapabilityOwners) Set(owner Owner) error { return nil } + +// Remove removes a provided owner from the CapabilityOwners if it exists. If the +// owner does not exist, Remove is considered a no-op. +func (co *CapabilityOwners) Remove(owner Owner) { + if len(co.Owners) == 0 { + return + } + + i, ok := co.Get(owner) + if ok { + // owner exists at co.Owners[i] + co.Owners = append(co.Owners[:i], co.Owners[i+1:]...) + } +} + +// Get returns (i, true) of the provided owner in the CapabilityOwners if the +// owner exists, where i indicates the owner's index in the set. Otherwise +// (i, false) where i indicates where in the set the owner should be added. +func (co *CapabilityOwners) Get(owner Owner) (int, bool) { + // find smallest index s.t. co.Owners[i] >= owner in O(log n) time + i := sort.Search(len(co.Owners), func(i int) bool { return co.Owners[i].Key() >= owner.Key() }) + if i < len(co.Owners) && co.Owners[i].Key() == owner.Key() { + // owner exists at co.Owners[i] + return i, true + } + + return i, false +} diff --git a/x/capability/types/types_test.go b/x/capability/types/types_test.go index 0c1ba6e3d3bc..86a2a28f1618 100644 --- a/x/capability/types/types_test.go +++ b/x/capability/types/types_test.go @@ -23,7 +23,7 @@ func TestOwner(t *testing.T) { require.Equal(t, "module: bank\nname: send\n", o.String()) } -func TestCapabilityOwners(t *testing.T) { +func TestCapabilityOwners_Set(t *testing.T) { co := types.NewCapabilityOwners() owners := make([]types.Owner, 1024) @@ -47,3 +47,23 @@ func TestCapabilityOwners(t *testing.T) { require.Error(t, co.Set(owner)) } } + +func TestCapabilityOwners_Remove(t *testing.T) { + co := types.NewCapabilityOwners() + + co.Remove(types.NewOwner("bank", "send-0")) + require.Len(t, co.Owners, 0) + + for i := 0; i < 5; i++ { + require.NoError(t, co.Set(types.NewOwner("bank", fmt.Sprintf("send-%d", i)))) + } + + require.Len(t, co.Owners, 5) + + for i := 0; i < 5; i++ { + co.Remove(types.NewOwner("bank", fmt.Sprintf("send-%d", i))) + require.Len(t, co.Owners, 5-(i+1)) + } + + require.Len(t, co.Owners, 0) +} From 24bd82e33d7504a3a0474654ffda5bf4007bf983 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 27 Mar 2020 12:16:05 -0400 Subject: [PATCH 149/176] Add test case to TestAuthenticateCapability for releasing a cap --- x/capability/keeper/keeper_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index 54cec4b2e039..7c8df90b51bc 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -115,6 +115,9 @@ func (suite *KeeperTestSuite) TestAuthenticateCapability() { suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap2, "invalid")) suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap1, "bond")) + sk2.ReleaseCapability(suite.ctx, cap2) + suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap2, "bond")) + badCap := types.NewCapabilityKey(100) suite.Require().False(sk1.AuthenticateCapability(suite.ctx, badCap, "transfer")) suite.Require().False(sk2.AuthenticateCapability(suite.ctx, badCap, "bond")) From b6e977daf4f8ef62e056320ec350ffbc6c1dc292 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 31 Mar 2020 12:29:48 -0300 Subject: [PATCH 150/176] remove swagger files from ibc module (#5893) --- x/ibc/02-client/client/rest/swagger.go | 35 -------------- x/ibc/03-connection/client/rest/swagger.go | 46 ------------------ x/ibc/04-channel/client/rest/swagger.go | 55 ---------------------- x/ibc/07-tendermint/client/rest/swagger.go | 30 ------------ x/ibc/20-transfer/client/rest/swagger.go | 20 -------- 5 files changed, 186 deletions(-) delete mode 100644 x/ibc/02-client/client/rest/swagger.go delete mode 100644 x/ibc/03-connection/client/rest/swagger.go delete mode 100644 x/ibc/04-channel/client/rest/swagger.go delete mode 100644 x/ibc/07-tendermint/client/rest/swagger.go delete mode 100644 x/ibc/20-transfer/client/rest/swagger.go diff --git a/x/ibc/02-client/client/rest/swagger.go b/x/ibc/02-client/client/rest/swagger.go deleted file mode 100644 index 29b8b164eb03..000000000000 --- a/x/ibc/02-client/client/rest/swagger.go +++ /dev/null @@ -1,35 +0,0 @@ -package rest - -import ( - "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" - ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" - commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" -) - -// nolint -type ( - QueryConsensusState struct { - Height int64 `json:"height"` - Result types.ConsensusStateResponse `json:"result"` - } - - QueryHeader struct { - Height int64 `json:"height"` - Result ibctmtypes.Header `json:"result"` - } - - QueryClientState struct { - Height int64 `json:"height"` - Result types.StateResponse `json:"result"` - } - - QueryNodeConsensusState struct { - Height int64 `json:"height"` - Result ibctmtypes.ConsensusState `json:"result"` - } - - QueryPath struct { - Height int64 `json:"height"` - Result commitmentexported.Prefix `json:"result"` - } -) diff --git a/x/ibc/03-connection/client/rest/swagger.go b/x/ibc/03-connection/client/rest/swagger.go deleted file mode 100644 index fd41f9449716..000000000000 --- a/x/ibc/03-connection/client/rest/swagger.go +++ /dev/null @@ -1,46 +0,0 @@ -package rest - -import ( - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" -) - -type ( - QueryConnection struct { - Height int64 `json:"height"` - Result types.ConnectionResponse `json:"result"` - } - - QueryClientConnections struct { - Height int64 `json:"height"` - Result types.ClientConnectionsResponse `json:"result"` - } - - PostConnectionOpenInit struct { - Msgs []types.MsgConnectionOpenInit `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostConnectionOpenTry struct { - Msgs []types.MsgConnectionOpenTry `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostConnectionOpenAck struct { - Msgs []types.MsgConnectionOpenAck `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostConnectionOpenConfirm struct { - Msgs []types.MsgConnectionOpenConfirm `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } -) diff --git a/x/ibc/04-channel/client/rest/swagger.go b/x/ibc/04-channel/client/rest/swagger.go deleted file mode 100644 index 04d011f2cb63..000000000000 --- a/x/ibc/04-channel/client/rest/swagger.go +++ /dev/null @@ -1,55 +0,0 @@ -package rest - -import ( - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" -) - -type ( - QueryChannel struct { - Height int64 `json:"height"` - Result types.ChannelResponse `json:"result"` - } - - PostChannelOpenInit struct { - Msgs []types.MsgChannelOpenInit `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostChannelOpenTry struct { - Msgs []types.MsgChannelOpenTry `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostChannelOpenAck struct { - Msgs []types.MsgChannelOpenAck `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostChannelOpenConfirm struct { - Msgs []types.MsgChannelOpenConfirm `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostChannelCloseInit struct { - Msgs []types.MsgChannelCloseInit `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostChannelCloseConfirm struct { - Msgs []types.MsgChannelCloseConfirm `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } -) diff --git a/x/ibc/07-tendermint/client/rest/swagger.go b/x/ibc/07-tendermint/client/rest/swagger.go deleted file mode 100644 index 884ab3c2dd56..000000000000 --- a/x/ibc/07-tendermint/client/rest/swagger.go +++ /dev/null @@ -1,30 +0,0 @@ -package rest - -import ( - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" -) - -// nolint -type ( - PostCreateClient struct { - Msgs []ibctmtypes.MsgCreateClient `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostUpdateClient struct { - Msgs []ibctmtypes.MsgUpdateClient `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } - - PostSubmitMisbehaviour struct { - Msgs []ibctmtypes.MsgSubmitClientMisbehaviour `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } -) diff --git a/x/ibc/20-transfer/client/rest/swagger.go b/x/ibc/20-transfer/client/rest/swagger.go deleted file mode 100644 index 1514502c6b66..000000000000 --- a/x/ibc/20-transfer/client/rest/swagger.go +++ /dev/null @@ -1,20 +0,0 @@ -package rest - -import ( - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" -) - -type ( - QueryNextSequenceRecv struct { - Height int64 `json:"height"` - Result uint64 `json:"result"` - } - - PostTransfer struct { - Msgs []types.MsgTransfer `json:"msg" yaml:"msg"` - Fee authtypes.StdFee `json:"fee" yaml:"fee"` - Signatures []authtypes.StdSignature `json:"signatures" yaml:"signatures"` - Memo string `json:"memo" yaml:"memo"` - } -) From d45627171e5324c74b2f6e35d92e694e8a8a2294 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Wed, 1 Apr 2020 13:26:10 -0600 Subject: [PATCH 151/176] Move IBC packet data interpretation to the application module (#5890) * fix: move IBC packet data interpretation to the application module This also adds a channelexported.NewOpaquePacketData(rawBytes) implementation to assist apps in being able to manipulate the raw packet data using the codec layer. * feat: use an internal-to-module PacketDataI type This one only has a GetBytes() method, which is implemented by OpaquePacketData. * fix: remove OpaquePacketData No need to wrap the []byte packet.GetData(). If the caller wants it, they can use it directly. * docs: update adr-015 * fix: put the TimeoutHeight back into the packet commitment * refactor: simplify unmarshalling of transfer packet * docs: update for new unmarshal steps * fix: clean up usage of sdkerrors.Wrapf * Apply suggestions from code review Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * chore: remove unnecessary "encoding/binary" import Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- .../adr-015-ibc-packet-receiver.md | 33 ++--- x/ibc/04-channel/client/utils/utils.go | 14 +- x/ibc/04-channel/exported/exported.go | 18 +-- x/ibc/04-channel/keeper/packet.go | 18 +-- x/ibc/04-channel/keeper/packet_test.go | 124 ++++++++---------- x/ibc/04-channel/keeper/timeout.go | 4 +- x/ibc/04-channel/keeper/timeout_test.go | 65 ++++----- x/ibc/04-channel/types/codec.go | 2 - x/ibc/04-channel/types/msgs.go | 35 ++++- x/ibc/04-channel/types/msgs_test.go | 74 +++-------- x/ibc/04-channel/types/packet.go | 39 +++--- x/ibc/04-channel/types/packet_test.go | 14 +- x/ibc/20-transfer/handler.go | 21 ++- x/ibc/20-transfer/keeper/keeper.go | 2 +- x/ibc/20-transfer/keeper/relay.go | 5 +- x/ibc/20-transfer/keeper/relay_test.go | 8 +- x/ibc/20-transfer/types/expected_keepers.go | 2 +- x/ibc/20-transfer/types/packet.go | 31 +---- x/ibc/20-transfer/types/packet_test.go | 12 +- x/ibc/ante/ante_test.go | 26 +--- 20 files changed, 209 insertions(+), 338 deletions(-) diff --git a/docs/architecture/adr-015-ibc-packet-receiver.md b/docs/architecture/adr-015-ibc-packet-receiver.md index 2ea26dcb5bae..924ddc7eb648 100644 --- a/docs/architecture/adr-015-ibc-packet-receiver.md +++ b/docs/architecture/adr-015-ibc-packet-receiver.md @@ -192,22 +192,7 @@ func NewAnteHandler( } ``` -The implementation of this ADR will also change the `Data` field of the `Packet` type from `[]byte` (i.e. arbitrary data) to `PacketDataI`. We want to make application modules be able to register custom packet data type which is automatically unmarshaled at `TxDecoder` time and can be simply type switched inside the application handler. Also, by having `GetCommitment()` method instead of manually generate the commitment inside the IBC keeper, the applications can define their own commitment method, including bare bytes, hashing, etc. - -This also removes the `Timeout` field from the `Packet` struct. This is because the `PacketDataI` interface now contains this information. You can see details about this in [ICS04](https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#definitions). - -The `PacketDataI` is the application specific interface that provides information for the execution of the application packet. In the case of ICS20 this would be `denom`, `amount` and `address` - -```go -// PacketDataI defines the standard interface for IBC packet data -type PacketDataI interface { - GetCommitment() []byte // Commitment form that will be stored in the state. - GetTimeoutHeight() uint64 - - ValidateBasic() error - Type() string -} -``` +The implementation of this ADR will also create a `Data` field of the `Packet` of type `[]byte`, which can be deserialised by the receiving module into its own private type. It is up to the application modules to do this according to their own interpretation, not by the IBC keeper. This is crucial for dynamic IBC. Example application-side usage: @@ -234,15 +219,17 @@ func NewHandler(k Keeper) Handler { case MsgTransfer: return handleMsgTransfer(ctx, k, msg) case ibc.MsgPacket: - switch data := msg.Packet.Data.(type) { - case PacketDataTransfer: // i.e fulfills the PacketDataI interface - return handlePacketDataTransfer(ctx, k, msg.Packet, data) + var data PacketDataTransfer + if err := types.ModuleCodec.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + return err } - case ibc.MsgTimeoutPacket: - switch packet := msg.Packet.Data.(type) { - case PacketDataTransfer: // i.e fulfills the PacketDataI interface - return handleTimeoutPacketDataTransfer(ctx, k, msg.Packet) + return handlePacketDataTransfer(ctx, k, msg, data) + case ibc.MsgTimeoutPacket: + var data PacketDataTransfer + if err := types.ModuleCodec.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + return err } + return handleTimeoutPacketDataTransfer(ctx, k, packet) // interface { PortID() string; ChannelID() string; Channel() ibc.Channel } // MsgChanInit, MsgChanTry implements ibc.MsgChannelOpen case ibc.MsgChannelOpen: diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index 8cdcd3eb8eb1..b9fbd9175ba1 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -4,7 +4,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -33,23 +32,14 @@ func QueryPacket( destPortID := channelRes.Channel.Counterparty.PortID destChannelID := channelRes.Channel.Counterparty.ChannelID - var data exported.PacketDataI - // TODO: commitment data is stored, not the data - // but we are unmarshalling the commitment in a json format - // because the current ICS 20 implementation uses json commitment form - // need to be changed to use external source of packet(e.g. event logs) - err = ctx.Codec.UnmarshalJSON(res.Value, &data) - if err != nil { - return types.PacketResponse{}, err - } - packet := types.NewPacket( - data, + res.Value, sequence, portID, channelID, destPortID, destChannelID, + timeout, ) // FIXME: res.Height+1 is hack, fix later diff --git a/x/ibc/04-channel/exported/exported.go b/x/ibc/04-channel/exported/exported.go index ba9dc7efdf6b..850b13d7dc3e 100644 --- a/x/ibc/04-channel/exported/exported.go +++ b/x/ibc/04-channel/exported/exported.go @@ -31,26 +31,10 @@ type PacketI interface { GetSourceChannel() string GetDestPort() string GetDestChannel() string - GetData() PacketDataI + GetData() []byte ValidateBasic() error } -// PacketDataI defines the packet data interface for IBC packets -// IBC application modules should define which data they want to -// send and receive over IBC channels. -type PacketDataI interface { - GetBytes() []byte // GetBytes returns the serialised packet data (without timeout) - GetTimeoutHeight() uint64 // GetTimeoutHeight returns the timeout height defined specifically for each packet data type instance - - ValidateBasic() error // ValidateBasic validates basic properties of the packet data, implements sdk.Msg - Type() string // Type returns human readable identifier, implements sdk.Msg -} - -// PacketAcknowledgementI defines the interface for IBC packet acknowledgements. -type PacketAcknowledgementI interface { - GetBytes() []byte -} - // Order defines if a channel is ORDERED or UNORDERED type Order byte diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 4cca23525f32..b7e1e1c42036 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -100,15 +100,15 @@ func (k Keeper) SendPacket( nextSequenceSend++ k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend) - k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), types.CommitPacket(packet.GetData())) + k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), types.CommitPacket(packet)) // Emit Event with Packet data along with other packet information for relayer to pick up // and relay to other chain ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeSendPacket, - sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData().GetBytes())), - sdk.NewAttribute(types.AttributeKeyTimeout, fmt.Sprintf("%d", packet.GetData().GetTimeoutHeight())), + sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData())), + sdk.NewAttribute(types.AttributeKeyTimeout, fmt.Sprintf("%d", packet.GetTimeoutHeight())), sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())), sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()), sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()), @@ -179,7 +179,7 @@ func (k Keeper) RecvPacket( if err := k.connectionKeeper.VerifyPacketCommitment( ctx, connectionEnd, proofHeight, proof, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), - types.CommitPacket(packet.GetData()), + types.CommitPacket(packet), ); err != nil { return nil, sdkerrors.Wrap(err, "couldn't verify counterparty packet commitment") } @@ -193,7 +193,7 @@ func (k Keeper) RecvPacket( func (k Keeper) PacketExecuted( ctx sdk.Context, packet exported.PacketI, - acknowledgement exported.PacketAcknowledgementI, + acknowledgement []byte, ) error { channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { @@ -246,7 +246,7 @@ func (k Keeper) PacketExecuted( func (k Keeper) AcknowledgePacket( ctx sdk.Context, packet exported.PacketI, - acknowledgement exported.PacketAcknowledgementI, + acknowledgement []byte, proof commitmentexported.Proof, proofHeight uint64, ) (exported.PacketI, error) { @@ -295,13 +295,13 @@ func (k Keeper) AcknowledgePacket( commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) // verify we sent the packet and haven't cleared it out yet - if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { + if !bytes.Equal(commitment, types.CommitPacket(packet)) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } if err := k.connectionKeeper.VerifyPacketAcknowledgement( ctx, connectionEnd, proofHeight, proof, packet.GetDestPort(), packet.GetDestChannel(), - packet.GetSequence(), acknowledgement.GetBytes(), + packet.GetSequence(), acknowledgement, ); err != nil { return nil, sdkerrors.Wrap(err, "invalid acknowledgement on counterparty chain") } @@ -377,7 +377,7 @@ func (k Keeper) CleanupPacket( commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) // verify we sent the packet and haven't cleared it out yet - if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { + if !bytes.Equal(commitment, types.CommitPacket(packet)) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } diff --git a/x/ibc/04-channel/keeper/packet_test.go b/x/ibc/04-channel/keeper/packet_test.go index ca5239ca5a09..2f96212a9e36 100644 --- a/x/ibc/04-channel/keeper/packet_test.go +++ b/x/ibc/04-channel/keeper/packet_test.go @@ -17,59 +17,59 @@ func (suite *KeeperTestSuite) TestSendPacket() { testCases := []testCase{ {"success", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainB.GetContext(), testPort1, testChannel1, 1) }, true}, {"packet basic validation failed", func() { - packet = types.NewPacket(mockFailPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockFailPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) }, false}, {"channel not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) }, false}, {"channel closed", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"packet dest port ≠ channel counterparty port", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, testPort3, counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, testPort3, counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet dest channel ID ≠ channel counterparty channel ID", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), testChannel3) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), testChannel3, 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection is UNINITIALIZED", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.UNINITIALIZED) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"client state not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"timeout height passed", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) commitNBlocks(suite.chainB, 10) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"next sequence send not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"next sequence wrong", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) @@ -110,40 +110,40 @@ func (suite *KeeperTestSuite) TestRecvPacket() { suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDB) suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort2, testChannel2, 1) - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort2, testChannel2, counterparty.GetPortID(), counterparty.GetChannelID()) - suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), testPort2, testChannel2, 1, types.CommitPacket(packet.(types.Packet).Data)) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort2, testChannel2, counterparty.GetPortID(), counterparty.GetChannelID(), 100) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), testPort2, testChannel2, 1, types.CommitPacket(packet)) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.INIT, exported.ORDERED, testConnectionIDA) }, false}, {"packet source port ≠ channel counterparty port", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort2, testChannel2, testPort3, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet source channel ID ≠ channel counterparty channel ID", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not OPEN", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.INIT) suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"timeout passed", func() { commitNBlocks(suite.chainB, 10) - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"validation failed", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, @@ -179,26 +179,26 @@ func (suite *KeeperTestSuite) TestPacketExecuted() { testCases := []testCase{ {"success: UNORDERED", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.UNORDERED, testConnectionIDA) suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainA.GetContext(), testPort2, testChannel2, 1) }, true}, {"success: ORDERED", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainA.GetContext(), testPort2, testChannel2, 1) }, true}, {"channel not found", func() {}, false}, {"channel not OPEN", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"next sequence receive not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet sequence ≠ next sequence receive", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDA) suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainA.GetContext(), testPort2, testChannel2, 5) }, false}, @@ -210,7 +210,7 @@ func (suite *KeeperTestSuite) TestPacketExecuted() { suite.SetupTest() // reset tc.malleate() - err := suite.chainA.App.IBCKeeper.ChannelKeeper.PacketExecuted(suite.chainA.GetContext(), packet, mockSuccessPacket{}) + err := suite.chainA.App.IBCKeeper.ChannelKeeper.PacketExecuted(suite.chainA.GetContext(), packet, mockSuccessPacket{}.GetBytes()) if tc.expPass { suite.Require().NoError(err) @@ -226,52 +226,52 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { var packet types.Packet packetKey := ibctypes.KeyPacketAcknowledgement(testPort2, testChannel2, 1) - ack := transfertypes.AckDataTransfer{} + ack := transfertypes.AckDataTransfer{}.GetBytes() testCases := []testCase{ {"success", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.CreateClient(suite.chainA) suite.chainA.CreateClient(suite.chainB) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.ORDERED, testConnectionIDB) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) - suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), testPort2, testChannel2, 1, ack.GetBytes()) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet)) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), testPort2, testChannel2, 1, ack) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"packet source port ≠ channel counterparty port", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet source channel ID ≠ channel counterparty channel ID", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not OPEN", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.INIT) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet hasn't been sent", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet ack verification failed", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet)) }, false}, } @@ -312,62 +312,62 @@ func (suite *KeeperTestSuite) TestCleanupPacket() { testCases := []testCase{ {"success", func() { nextSeqRecv = 10 - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainA.CreateClient(suite.chainB) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.UNORDERED, testConnectionIDB) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet)) suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), testPort2, testChannel2, 1, ack) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"packet source port ≠ channel counterparty port", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet source channel ID ≠ channel counterparty channel ID", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not OPEN", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.INIT) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet already received ", func() { - packet = types.NewPacket(mockSuccessPacket{}, 10, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 10, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet hasn't been sent", func() { nextSeqRecv = 10 - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"next seq receive verification failed", func() { nextSeqRecv = 10 - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet)) }, false}, {"packet ack verification failed", func() { nextSeqRecv = 10 - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 1, types.CommitPacket(packet)) }, false}, } @@ -398,28 +398,10 @@ func (suite *KeeperTestSuite) TestCleanupPacket() { type mockSuccessPacket struct{} -// GetBytes returns the serialised packet data (without timeout) +// GetBytes returns the serialised packet data func (mp mockSuccessPacket) GetBytes() []byte { return []byte("THIS IS A SUCCESS PACKET") } -// GetTimeoutHeight returns the timeout height defined specifically for each packet data type instance -func (mp mockSuccessPacket) GetTimeoutHeight() uint64 { return 10 } - -// ValidateBasic validates basic properties of the packet data, implements sdk.Msg -func (mp mockSuccessPacket) ValidateBasic() error { return nil } - -// Type returns human readable identifier, implements sdk.Msg -func (mp mockSuccessPacket) Type() string { return "mock/packet/success" } - type mockFailPacket struct{} // GetBytes returns the serialised packet data (without timeout) func (mp mockFailPacket) GetBytes() []byte { return []byte("THIS IS A FAILURE PACKET") } - -// GetTimeoutHeight returns the timeout height defined specifically for each packet data type instance -func (mp mockFailPacket) GetTimeoutHeight() uint64 { return 10000 } - -// ValidateBasic validates basic properties of the packet data, implements sdk.Msg -func (mp mockFailPacket) ValidateBasic() error { return fmt.Errorf("Packet failed validate basic") } - -// Type returns human readable identifier, implements sdk.Msg -func (mp mockFailPacket) Type() string { return "mock/packet/failure" } diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index ff2111675024..204f4c91c1ca 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -76,7 +76,7 @@ func (k Keeper) TimeoutPacket( commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) // verify we sent the packet and haven't cleared it out yet - if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { + if !bytes.Equal(commitment, types.CommitPacket(packet)) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } @@ -178,7 +178,7 @@ func (k Keeper) TimeoutOnClose( commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) // verify we sent the packet and haven't cleared it out yet - if !bytes.Equal(commitment, types.CommitPacket(packet.GetData())) { + if !bytes.Equal(commitment, types.CommitPacket(packet)) { return nil, sdkerrors.Wrap(types.ErrInvalidPacket, "packet hasn't been sent") } diff --git a/x/ibc/04-channel/keeper/timeout_test.go b/x/ibc/04-channel/keeper/timeout_test.go index 5b406e2bdb74..58c51b7fbe33 100644 --- a/x/ibc/04-channel/keeper/timeout_test.go +++ b/x/ibc/04-channel/keeper/timeout_test.go @@ -20,62 +20,62 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { testCases := []testCase{ {"success", func() { nextSeqRecv = 1 - packet = types.NewPacket(newMockTimeoutPacket(1), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(newMockTimeoutPacket().GetBytes(), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 1) suite.chainB.CreateClient(suite.chainA) suite.chainA.CreateClient(suite.chainB) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainA.createConnection(testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, exported.UNORDERED, testConnectionIDB) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet)) }, true}, {"channel not found", func() {}, false}, {"channel not open", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, exported.ORDERED, testConnectionIDA) }, false}, {"packet source port ≠ channel counterparty port", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet source channel ID ≠ channel counterparty channel ID", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"timeout", func() { - packet = types.NewPacket(mockSuccessPacket{}, 10, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 10, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet already received ", func() { nextSeqRecv = 2 - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet hasn't been sent", func() { nextSeqRecv = 1 - packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"next seq receive verification failed", func() { nextSeqRecv = 1 - packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet)) }, false}, {"packet ack verification failed", func() { nextSeqRecv = 1 - packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet)) }, false}, } @@ -108,7 +108,7 @@ func (suite *KeeperTestSuite) TestTimeoutExecuted() { testCases := []testCase{ {"success ORDERED", func() { - packet = types.NewPacket(newMockTimeoutPacket(3), 1, testPort1, testChannel1, testPort2, testChannel2) + packet = types.NewPacket(newMockTimeoutPacket().GetBytes(), 1, testPort1, testChannel1, testPort2, testChannel2, 3) suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, true}, {"channel not found", func() {}, false}, @@ -142,56 +142,56 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { testCases := []testCase{ {"success", func() { - packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.CreateClient(suite.chainA) suite.chainA.CreateClient(suite.chainB) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainA.createConnection(testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) suite.chainA.createChannel(testPort2, testChannel2, testPort1, testChannel1, exported.CLOSED, exported.UNORDERED, testConnectionIDB) // channel on chainA is closed - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet)) suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, true}, {"channel not found", func() {}, false}, {"packet dest port ≠ channel counterparty port", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort3, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet dest channel ID ≠ channel counterparty channel ID", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel3, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"connection not found", func() { - packet = types.NewPacket(mockSuccessPacket{}, 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"packet hasn't been sent", func() { - packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) }, false}, {"channel verification failed", func() { - packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet)) suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, false}, {"next seq receive verification failed", func() { - packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet)) suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, false}, {"packet ack verification failed", func() { - packet = types.NewPacket(mockSuccessPacket{}, 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID()) + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 2, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) suite.chainB.CreateClient(suite.chainA) suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.UNORDERED, testConnectionIDA) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), testPort1, testChannel1, 2, types.CommitPacket(packet)) suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainB.GetContext(), testPort1, testChannel1, nextSeqRecv) }, false}, } @@ -226,18 +226,9 @@ type mockTimeoutPacket struct { timeoutHeight uint64 } -func newMockTimeoutPacket(timeoutHeight uint64) mockTimeoutPacket { - return mockTimeoutPacket{timeoutHeight} +func newMockTimeoutPacket() mockTimeoutPacket { + return mockTimeoutPacket{} } // GetBytes returns the serialised packet data (without timeout) func (mp mockTimeoutPacket) GetBytes() []byte { return []byte("THIS IS A TIMEOUT PACKET") } - -// GetTimeoutHeight returns the timeout height defined specifically for each packet data type instance -func (mp mockTimeoutPacket) GetTimeoutHeight() uint64 { return mp.timeoutHeight } - -// ValidateBasic validates basic properties of the packet data, implements sdk.Msg -func (mp mockTimeoutPacket) ValidateBasic() error { return nil } - -// Type returns human readable identifier, implements sdk.Msg -func (mp mockTimeoutPacket) Type() string { return "mock/packet/success" } diff --git a/x/ibc/04-channel/types/codec.go b/x/ibc/04-channel/types/codec.go index cfb57624b7ba..270852973248 100644 --- a/x/ibc/04-channel/types/codec.go +++ b/x/ibc/04-channel/types/codec.go @@ -21,8 +21,6 @@ func init() { // IBC channel. func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*exported.PacketI)(nil), nil) - cdc.RegisterInterface((*exported.PacketDataI)(nil), nil) - cdc.RegisterInterface((*exported.PacketAcknowledgementI)(nil), nil) cdc.RegisterConcrete(Channel{}, "ibc/channel/Channel", nil) cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil) diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index 6797e942f57b..6501f40f3e5c 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -1,6 +1,7 @@ package types import ( + "encoding/base64" "strings" sdk "github.com/cosmos/cosmos-sdk/types" @@ -440,11 +441,23 @@ func (msg MsgPacket) GetSignBytes() []byte { return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(msg)) } +// GetDataSignBytes returns the base64-encoded bytes used for the +// data field when signing the packet. +func (msg MsgPacket) GetDataSignBytes() []byte { + s := "\"" + base64.StdEncoding.EncodeToString(msg.Data) + "\"" + return []byte(s) +} + // GetSigners implements sdk.Msg func (msg MsgPacket) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Signer} } +// Type implements sdk.Msg +func (msg MsgPacket) Type() string { + return "ics04/opaque" +} + var _ sdk.Msg = MsgTimeout{} // MsgTimeout receives timed-out packet @@ -500,19 +513,24 @@ func (msg MsgTimeout) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Signer} } +// Type implements sdk.Msg +func (msg MsgTimeout) Type() string { + return "ics04/timeout" +} + var _ sdk.Msg = MsgAcknowledgement{} // MsgAcknowledgement receives incoming IBC acknowledgement type MsgAcknowledgement struct { Packet `json:"packet" yaml:"packet"` - Acknowledgement exported.PacketAcknowledgementI `json:"acknowledgement" yaml:"acknowledgement"` - Proof commitmentexported.Proof `json:"proof" yaml:"proof"` - ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` - Signer sdk.AccAddress `json:"signer" yaml:"signer"` + Acknowledgement []byte `json:"acknowledgement" yaml:"acknowledgement"` + Proof commitmentexported.Proof `json:"proof" yaml:"proof"` + ProofHeight uint64 `json:"proof_height" yaml:"proof_height"` + Signer sdk.AccAddress `json:"signer" yaml:"signer"` } // NewMsgAcknowledgement constructs a new MsgAcknowledgement -func NewMsgAcknowledgement(packet Packet, ack exported.PacketAcknowledgementI, proof commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement { +func NewMsgAcknowledgement(packet Packet, ack []byte, proof commitmentexported.Proof, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement { return MsgAcknowledgement{ Packet: packet, Acknowledgement: ack, @@ -535,7 +553,7 @@ func (msg MsgAcknowledgement) ValidateBasic() error { if err := msg.Proof.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "proof ack cannot be nil") } - if len(msg.Acknowledgement.GetBytes()) > 100 { + if len(msg.Acknowledgement) > 100 { return sdkerrors.Wrap(ErrAcknowledgementTooLong, "acknowledgement cannot exceed 100 bytes") } if msg.ProofHeight == 0 { @@ -557,3 +575,8 @@ func (msg MsgAcknowledgement) GetSignBytes() []byte { func (msg MsgAcknowledgement) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Signer} } + +// Type implements sdk.Msg +func (msg MsgAcknowledgement) Type() string { + return "ics04/opaque" +} diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index bea0e43995be..aeb47f4ad640 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -1,7 +1,6 @@ package types import ( - "errors" "fmt" "testing" @@ -353,59 +352,16 @@ func (suite *MsgTestSuite) TestMsgChannelCloseConfirm() { } } -var _ exported.PacketDataI = validPacketT{} - -type validPacketT struct{} - -func (validPacketT) GetBytes() []byte { - return []byte("testdata") -} - -func (validPacketT) GetTimeoutHeight() uint64 { - return 100 -} - -func (validPacketT) ValidateBasic() error { - return nil -} - -func (validPacketT) Type() string { - return "valid" -} - -var _ exported.PacketDataI = invalidPacketT{} - -type invalidPacketT struct{} - -func (invalidPacketT) GetBytes() []byte { - return []byte("testdata") -} - -func (invalidPacketT) GetTimeoutHeight() uint64 { - return 100 -} - -func (invalidPacketT) ValidateBasic() error { - return errors.New("invalid packet") -} - -func (invalidPacketT) Type() string { - return "invalid" -} - -var _ exported.PacketAcknowledgementI = invalidAckT{} - -type invalidAckT struct{} - -func (invalidAckT) GetBytes() []byte { - return []byte("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890") -} - // define variables used for testing var ( - packet = NewPacket(validPacketT{}, 1, portid, chanid, cpportid, cpchanid) - invalidPacket = NewPacket(invalidPacketT{}, 0, portid, chanid, cpportid, cpchanid) - invalidAck = invalidAckT{} + timeout = uint64(100) + validPacketData = []byte("testdata") + unknownPacketData = []byte("unknown") + invalidAckData = []byte("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890") + + packet = NewPacket(validPacketData, 1, portid, chanid, cpportid, cpchanid, 100) + unknownPacket = NewPacket(unknownPacketData, 0, portid, chanid, cpportid, cpchanid, 100) + invalidAck = invalidAckData emptyProof = commitmenttypes.MerkleProof{Proof: nil} invalidProofs1 = commitmentexported.Proof(nil) @@ -431,7 +387,7 @@ func TestMsgPacketRoute(t *testing.T) { func TestMsgPacketType(t *testing.T) { msg := NewMsgPacket(packet, proof, 1, addr1) - require.Equal(t, "valid", msg.Type()) + require.Equal(t, []byte("testdata"), msg.GetData()) } // TestMsgPacketValidation tests ValidateBasic for MsgPacket @@ -443,7 +399,7 @@ func TestMsgPacketValidation(t *testing.T) { NewMsgPacket(packet, invalidProofs1, 1, addr1), // missing proof NewMsgPacket(packet, invalidProofs2, 1, addr1), // proof contain empty proof NewMsgPacket(packet, proof, 1, emptyAddr), // missing signer address - NewMsgPacket(invalidPacket, proof, 1, addr1), // invalid packet + NewMsgPacket(unknownPacket, proof, 1, addr1), // unknown packet } testCases := []struct { @@ -473,10 +429,12 @@ func TestMsgPacketValidation(t *testing.T) { // TestMsgPacketGetSignBytes tests GetSignBytes for MsgPacket func TestMsgPacketGetSignBytes(t *testing.T) { msg := NewMsgPacket(packet, proof, 1, addr1) - SubModuleCdc.RegisterConcrete(validPacketT{}, "test/validPacketT", nil) res := msg.GetSignBytes() - expected := `{"type":"ibc/channel/MsgPacket","value":{"packet":{"data":{"type":"test/validPacketT","value":{}},"destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid"},"proof":{"type":"ibc/commitment/MerkleProof","value":{"proof":{"ops":[]}}},"proof_height":"1","signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}}` + expected := fmt.Sprintf( + `{"type":"ibc/channel/MsgPacket","value":{"packet":{"data":%s,"destination_channel":"testcpchannel","destination_port":"testcpport","sequence":"1","source_channel":"testchannel","source_port":"testportid","timeout_height":"100"},"proof":{"type":"ibc/commitment/MerkleProof","value":{"proof":{"ops":[]}}},"proof_height":"1","signer":"cosmos1w3jhxarpv3j8yvg4ufs4x"}}`, + string(msg.GetDataSignBytes()), + ) require.Equal(t, expected, string(res)) } @@ -496,7 +454,7 @@ func (suite *MsgTestSuite) TestMsgTimeout() { NewMsgTimeout(packet, 0, proof, 0, addr), NewMsgTimeout(packet, 0, proof, 1, emptyAddr), NewMsgTimeout(packet, 0, emptyProof, 1, addr), - NewMsgTimeout(invalidPacket, 0, proof, 1, addr), + NewMsgTimeout(unknownPacket, 0, proof, 1, addr), NewMsgTimeout(packet, 0, invalidProofs1, 1, addr), } @@ -530,7 +488,7 @@ func (suite *MsgTestSuite) TestMsgAcknowledgement() { NewMsgAcknowledgement(packet, packet.GetData(), proof, 0, addr), NewMsgAcknowledgement(packet, packet.GetData(), proof, 1, emptyAddr), NewMsgAcknowledgement(packet, packet.GetData(), emptyProof, 1, addr), - NewMsgAcknowledgement(invalidPacket, packet.GetData(), proof, 1, addr), + NewMsgAcknowledgement(unknownPacket, packet.GetData(), proof, 1, addr), NewMsgAcknowledgement(packet, invalidAck, proof, 1, addr), NewMsgAcknowledgement(packet, packet.GetData(), invalidProofs1, 1, addr), } diff --git a/x/ibc/04-channel/types/packet.go b/x/ibc/04-channel/types/packet.go index cd5d1e271c5f..d302f3414511 100644 --- a/x/ibc/04-channel/types/packet.go +++ b/x/ibc/04-channel/types/packet.go @@ -1,49 +1,48 @@ package types import ( - "encoding/binary" - "github.com/tendermint/tendermint/crypto/tmhash" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) -// CommitPacket appends bigendian encoded timeout height and commitment bytes -// and then returns the hash of the result bytes. +// CommitPacket return the hash of commitment bytes // TODO: no specification for packet commitment currently, // make it spec compatible once we have it -func CommitPacket(data exported.PacketDataI) []byte { - buf := make([]byte, 8) - binary.BigEndian.PutUint64(buf, data.GetTimeoutHeight()) - buf = append(buf, data.GetBytes()...) +func CommitPacket(packet exported.PacketI) []byte { + buf := sdk.Uint64ToBigEndian(packet.GetTimeoutHeight()) + buf = append(buf, packet.GetData()...) return tmhash.Sum(buf) } // CommitAcknowledgement returns the hash of commitment bytes -func CommitAcknowledgement(data exported.PacketAcknowledgementI) []byte { - return tmhash.Sum(data.GetBytes()) +func CommitAcknowledgement(data []byte) []byte { + return tmhash.Sum(data) } var _ exported.PacketI = Packet{} // Packet defines a type that carries data across different chains through IBC type Packet struct { - Data exported.PacketDataI `json:"data" yaml:"data"` // opaque value which can be defined by the application logic of the associated modules. + Data []byte `json:"data" yaml:"data"` // Actual opaque bytes transferred directly to the application module Sequence uint64 `json:"sequence" yaml:"sequence"` // number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. SourcePort string `json:"source_port" yaml:"source_port"` // identifies the port on the sending chain. SourceChannel string `json:"source_channel" yaml:"source_channel"` // identifies the channel end on the sending chain. DestinationPort string `json:"destination_port" yaml:"destination_port"` // identifies the port on the receiving chain. DestinationChannel string `json:"destination_channel" yaml:"destination_channel"` // identifies the channel end on the receiving chain. + TimeoutHeight uint64 `json:"timeout_height" yaml:"timeout_height"` // block height after which the packet times out } // NewPacket creates a new Packet instance func NewPacket( - data exported.PacketDataI, + data []byte, sequence uint64, sourcePort, sourceChannel, destinationPort, destinationChannel string, + timeoutHeight uint64, ) Packet { return Packet{ Data: data, @@ -52,14 +51,10 @@ func NewPacket( SourceChannel: sourceChannel, DestinationPort: destinationPort, DestinationChannel: destinationChannel, + TimeoutHeight: timeoutHeight, } } -// Type exports Packet.Data.Type -func (p Packet) Type() string { - return p.Data.Type() -} - // GetSequence implements PacketI interface func (p Packet) GetSequence() uint64 { return p.Sequence } @@ -76,10 +71,10 @@ func (p Packet) GetDestPort() string { return p.DestinationPort } func (p Packet) GetDestChannel() string { return p.DestinationChannel } // GetData implements PacketI interface -func (p Packet) GetData() exported.PacketDataI { return p.Data } +func (p Packet) GetData() []byte { return p.Data } // GetTimeoutHeight implements PacketI interface -func (p Packet) GetTimeoutHeight() uint64 { return p.Data.GetTimeoutHeight() } +func (p Packet) GetTimeoutHeight() uint64 { return p.TimeoutHeight } // ValidateBasic implements PacketI interface func (p Packet) ValidateBasic() error { @@ -110,11 +105,11 @@ func (p Packet) ValidateBasic() error { if p.Sequence == 0 { return sdkerrors.Wrap(ErrInvalidPacket, "packet sequence cannot be 0") } - if p.Data.GetTimeoutHeight() == 0 { + if p.TimeoutHeight == 0 { return sdkerrors.Wrap(ErrInvalidPacket, "packet timeout cannot be 0") } - if len(p.Data.GetBytes()) == 0 { + if len(p.Data) == 0 { return sdkerrors.Wrap(ErrInvalidPacket, "packet data bytes cannot be empty") } - return p.Data.ValidateBasic() + return nil } diff --git a/x/ibc/04-channel/types/packet_test.go b/x/ibc/04-channel/types/packet_test.go index 9137bd7380e4..3efc7158db87 100644 --- a/x/ibc/04-channel/types/packet_test.go +++ b/x/ibc/04-channel/types/packet_test.go @@ -12,13 +12,13 @@ func TestPacketValidateBasic(t *testing.T) { expPass bool errMsg string }{ - {NewPacket(validPacketT{}, 1, portid, chanid, cpportid, cpchanid), true, ""}, - {NewPacket(validPacketT{}, 0, portid, chanid, cpportid, cpchanid), false, "invalid sequence"}, - {NewPacket(validPacketT{}, 1, invalidPort, chanid, cpportid, cpchanid), false, "invalid source port"}, - {NewPacket(validPacketT{}, 1, portid, invalidChannel, cpportid, cpchanid), false, "invalid source channel"}, - {NewPacket(validPacketT{}, 1, portid, chanid, invalidPort, cpchanid), false, "invalid destination port"}, - {NewPacket(validPacketT{}, 1, portid, chanid, cpportid, invalidChannel), false, "invalid destination channel"}, - {NewPacket(invalidPacketT{}, 1, portid, chanid, cpportid, cpchanid), false, "invalid packet data"}, + {NewPacket(validPacketData, 1, portid, chanid, cpportid, cpchanid, timeout), true, ""}, + {NewPacket(validPacketData, 0, portid, chanid, cpportid, cpchanid, timeout), false, "invalid sequence"}, + {NewPacket(validPacketData, 1, invalidPort, chanid, cpportid, cpchanid, timeout), false, "invalid source port"}, + {NewPacket(validPacketData, 1, portid, invalidChannel, cpportid, cpchanid, timeout), false, "invalid source channel"}, + {NewPacket(validPacketData, 1, portid, chanid, invalidPort, cpchanid, timeout), false, "invalid destination port"}, + {NewPacket(validPacketData, 1, portid, chanid, cpportid, invalidChannel, timeout), false, "invalid destination channel"}, + {NewPacket(unknownPacketData, 1, portid, chanid, cpportid, cpchanid, timeout), true, ""}, } for i, tc := range testCases { diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 08dd6a5927d0..4b96f58dd3f2 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -5,6 +5,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) // NewHandler returns sdk.Handler for IBC token transfer module messages @@ -14,19 +15,17 @@ func NewHandler(k Keeper) sdk.Handler { case MsgTransfer: return handleMsgTransfer(ctx, k, msg) case channeltypes.MsgPacket: - switch data := msg.Data.(type) { - case FungibleTokenPacketData: - return handlePacketDataTransfer(ctx, k, msg, data) - default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer packet data type: %T", data) + var data FungibleTokenPacketData + if err := types.ModuleCdc.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) } + return handlePacketDataTransfer(ctx, k, msg, data) case channeltypes.MsgTimeout: - switch data := msg.Data.(type) { - case FungibleTokenPacketData: - return handleTimeoutDataTransfer(ctx, k, msg, data) - default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer packet data type: %T", data) + var data FungibleTokenPacketData + if err := types.ModuleCdc.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) } + return handleTimeoutDataTransfer(ctx, k, msg, data) default: return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer message type: %T", msg) } @@ -74,7 +73,7 @@ func handlePacketDataTransfer( } acknowledgement := AckDataTransfer{} - if err := k.PacketExecuted(ctx, msg.Packet, acknowledgement); err != nil { + if err := k.PacketExecuted(ctx, msg.Packet, acknowledgement.GetBytes()); err != nil { return nil, err } diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index e5225cbe7137..f629de5e9bf8 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -65,7 +65,7 @@ func (k Keeper) GetTransferAccount(ctx sdk.Context) supplyexported.ModuleAccount // PacketExecuted defines a wrapper function for the channel Keeper's function // in order to expose it to the ICS20 transfer handler. -func (k Keeper) PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketAcknowledgementI) error { +func (k Keeper) PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement []byte) error { return k.channelKeeper.PacketExecuted(ctx, packet, acknowledgement) } diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index 529a30cf28a8..6f13b0d43189 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -126,16 +126,17 @@ func (k Keeper) createOutgoingPacket( } packetData := types.NewFungibleTokenPacketData( - amount, sender, receiver, isSourceChain, destHeight+DefaultPacketTimeout, + amount, sender, receiver, isSourceChain, ) packet := channel.NewPacket( - packetData, + packetData.GetBytes(), seq, sourcePort, sourceChannel, destinationPort, destinationChannel, + destHeight+DefaultPacketTimeout, ) return k.channelKeeper.SendPacket(ctx, packet) diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 101ec8698ce9..7db510decfdf 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -95,7 +95,7 @@ func (suite *KeeperTestSuite) TestSendTransfer() { } func (suite *KeeperTestSuite) TestReceiveTransfer() { - data := types.NewFungibleTokenPacketData(prefixCoins2, testAddr1, testAddr2, true, 100) + data := types.NewFungibleTokenPacketData(prefixCoins2, testAddr1, testAddr2, true) testCases := []struct { msg string @@ -132,7 +132,7 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { }, true}, } - packet := channeltypes.NewPacket(data, 1, testPort1, testChannel1, testPort2, testChannel2) + packet := channeltypes.NewPacket(data.GetBytes(), 1, testPort1, testChannel1, testPort2, testChannel2, 100) for i, tc := range testCases { tc := tc @@ -152,7 +152,7 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { } func (suite *KeeperTestSuite) TestTimeoutTransfer() { - data := types.NewFungibleTokenPacketData(prefixCoins, testAddr1, testAddr2, true, 100) + data := types.NewFungibleTokenPacketData(prefixCoins, testAddr1, testAddr2, true) testCases := []struct { msg string @@ -186,7 +186,7 @@ func (suite *KeeperTestSuite) TestTimeoutTransfer() { }, false}, } - packet := channeltypes.NewPacket(data, 1, testPort1, testChannel1, testPort2, testChannel2) + packet := channeltypes.NewPacket(data.GetBytes(), 1, testPort1, testChannel1, testPort2, testChannel2, 100) for i, tc := range testCases { tc := tc diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index a347fb4e476f..9cf6c4dc8549 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -19,7 +19,7 @@ type ChannelKeeper interface { GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channel.Channel, found bool) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) SendPacket(ctx sdk.Context, packet channelexported.PacketI) error - PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement channelexported.PacketAcknowledgementI) error + PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement []byte) error ChanCloseInit(ctx sdk.Context, portID, channelID string) error TimeoutExecuted(ctx sdk.Context, packet channelexported.PacketI) error } diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go index edee9f60ae82..acb50b4e4a23 100644 --- a/x/ibc/20-transfer/types/packet.go +++ b/x/ibc/20-transfer/types/packet.go @@ -5,12 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" ) -var _ channelexported.PacketDataI = FungibleTokenPacketData{} - // FungibleTokenPacketData defines a struct for the packet payload // See FungibleTokenPacketData spec: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#data-structures type FungibleTokenPacketData struct { @@ -18,19 +14,17 @@ type FungibleTokenPacketData struct { Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred - Timeout uint64 `json:"timeout" yaml:"timeout"` } // NewFungibleTokenPacketData contructs a new FungibleTokenPacketData instance func NewFungibleTokenPacketData( amount sdk.Coins, sender, receiver sdk.AccAddress, - source bool, timeout uint64) FungibleTokenPacketData { + source bool) FungibleTokenPacketData { return FungibleTokenPacketData{ Amount: amount, Sender: sender, Receiver: receiver, Source: source, - Timeout: timeout, } } @@ -48,7 +42,7 @@ func (ftpd FungibleTokenPacketData) String() string { ) } -// ValidateBasic implements channelexported.PacketDataI +// ValidateBasic is used for validating the token transfer func (ftpd FungibleTokenPacketData) ValidateBasic() error { if !ftpd.Amount.IsAllPositive() { return sdkerrors.ErrInsufficientFunds @@ -62,34 +56,19 @@ func (ftpd FungibleTokenPacketData) ValidateBasic() error { if ftpd.Receiver.Empty() { return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing receiver address") } - if ftpd.Timeout == 0 { - return sdkerrors.Wrap(ErrInvalidPacketTimeout, "timeout cannot be 0") - } return nil } -// GetBytes implements channelexported.PacketDataI +// GetBytes is a helper for serialising func (ftpd FungibleTokenPacketData) GetBytes() []byte { return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(ftpd)) } -// GetTimeoutHeight implements channelexported.PacketDataI -func (ftpd FungibleTokenPacketData) GetTimeoutHeight() uint64 { - return ftpd.Timeout -} - -// Type implements channelexported.PacketDataI -func (ftpd FungibleTokenPacketData) Type() string { - return "ics20/transfer" -} - -var _ channelexported.PacketAcknowledgementI = AckDataTransfer{} - // AckDataTransfer is a no-op packet // See spec for onAcknowledgePacket: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay type AckDataTransfer struct{} -// GetBytes implements channelexported.PacketAcknowledgementI -func (ack AckDataTransfer) GetBytes() []byte { +// GetBytes is a helper for serialising +func (AckDataTransfer) GetBytes() []byte { return []byte("fungible token transfer ack") } diff --git a/x/ibc/20-transfer/types/packet_test.go b/x/ibc/20-transfer/types/packet_test.go index fc188708e60f..2f82a33c779b 100644 --- a/x/ibc/20-transfer/types/packet_test.go +++ b/x/ibc/20-transfer/types/packet_test.go @@ -9,12 +9,11 @@ import ( // TestFungibleTokenPacketDataValidateBasic tests ValidateBasic for FungibleTokenPacketData func TestFungibleTokenPacketDataValidateBasic(t *testing.T) { testPacketDataTransfer := []FungibleTokenPacketData{ - NewFungibleTokenPacketData(coins, addr1, addr2, true, 100), // valid msg - NewFungibleTokenPacketData(invalidDenomCoins, addr1, addr2, true, 100), // invalid amount - NewFungibleTokenPacketData(negativeCoins, addr1, addr2, false, 100), // amount contains negative coin - NewFungibleTokenPacketData(coins, emptyAddr, addr2, false, 100), // missing sender address - NewFungibleTokenPacketData(coins, addr1, emptyAddr, false, 100), - NewFungibleTokenPacketData(coins, addr1, emptyAddr, false, 0), // missing recipient address + NewFungibleTokenPacketData(coins, addr1, addr2, true), // valid msg + NewFungibleTokenPacketData(invalidDenomCoins, addr1, addr2, true), // invalid amount + NewFungibleTokenPacketData(negativeCoins, addr1, addr2, false), // amount contains negative coin + NewFungibleTokenPacketData(coins, emptyAddr, addr2, false), // missing sender address + NewFungibleTokenPacketData(coins, addr1, emptyAddr, false), // missing recipient address } testCases := []struct { @@ -27,7 +26,6 @@ func TestFungibleTokenPacketDataValidateBasic(t *testing.T) { {testPacketDataTransfer[2], false, "amount contains negative coin"}, {testPacketDataTransfer[3], false, "missing sender address"}, {testPacketDataTransfer[4], false, "missing recipient address"}, - {testPacketDataTransfer[5], false, "timeout is 0"}, } for i, tc := range testCases { diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go index f690daab8cb8..a2e9bb463ca3 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/ante/ante_test.go @@ -95,12 +95,12 @@ func (suite *HandlerTestSuite) TestHandleMsgPacketOrdered() { suite.chainA.App.IBCKeeper.ChannelKeeper, )) - packet := channel.NewPacket(newPacket(12345), 1, portid, chanid, cpportid, cpchanid) + packet := channel.NewPacket(newPacket(12345).GetData(), 1, portid, chanid, cpportid, cpchanid, 100) ctx := suite.chainA.GetContext() cctx, _ := ctx.CacheContext() // suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(ctx, packet.SourcePort, packet.SourceChannel, 1) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), packet.SourcePort, packet.SourceChannel, packet.Sequence, channeltypes.CommitPacket(packet.Data)) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), packet.SourcePort, packet.SourceChannel, packet.Sequence, channeltypes.CommitPacket(packet)) msg := channel.NewMsgPacket(packet, nil, 0, addr1) _, err := handler(cctx, suite.newTx(msg), false) suite.Error(err, "%+v", err) // channel does not exist @@ -149,8 +149,8 @@ func (suite *HandlerTestSuite) TestHandleMsgPacketUnordered() { var packet channeltypes.Packet for i := 0; i < 5; i++ { - packet = channel.NewPacket(newPacket(uint64(i)), uint64(i), portid, chanid, cpportid, cpchanid) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), packet.SourcePort, packet.SourceChannel, uint64(i), channeltypes.CommitPacket(packet.Data)) + packet = channel.NewPacket(newPacket(uint64(i)).GetData(), uint64(i), portid, chanid, cpportid, cpchanid, 100) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), packet.SourcePort, packet.SourceChannel, uint64(i), channeltypes.CommitPacket(packet)) } // suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), packet.SourcePort, packet.SourceChannel, uint64(10)) @@ -161,7 +161,7 @@ func (suite *HandlerTestSuite) TestHandleMsgPacketUnordered() { for i := 10; i >= 0; i-- { cctx, write := suite.chainA.GetContext().CacheContext() - packet = channel.NewPacket(newPacket(uint64(i)), uint64(i), portid, chanid, cpportid, cpchanid) + packet = channel.NewPacket(newPacket(uint64(i)).GetData(), uint64(i), portid, chanid, cpportid, cpchanid, 100) packetCommitmentPath := ibctypes.PacketCommitmentPath(packet.SourcePort, packet.SourceChannel, uint64(i)) proof, proofHeight := queryProof(suite.chainB, packetCommitmentPath) msg := channel.NewMsgPacket(packet, proof, uint64(proofHeight), addr1) @@ -356,28 +356,14 @@ func nextHeader(chain *TestChain) ibctmtypes.Header { chain.Header.Time.Add(time.Minute), chain.Vals, chain.Signers) } -var _ channelexported.PacketDataI = packetT{} - type packetT struct { Data uint64 } -func (packet packetT) GetBytes() []byte { +func (packet packetT) GetData() []byte { return []byte(fmt.Sprintf("%d", packet.Data)) } -func (packetT) GetTimeoutHeight() uint64 { - return 100 -} - -func (packetT) ValidateBasic() error { - return nil -} - -func (packetT) Type() string { - return "valid" -} - func newPacket(data uint64) packetT { return packetT{data} } From 8d26b7fd1426bca90d2dca1ac9a9c021df2b4733 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Thu, 2 Apr 2020 09:28:26 -0300 Subject: [PATCH 152/176] fix ibc-alpha sims (#5909) * fix some simulations --- x/ibc/02-client/handler.go | 4 ++-- x/ibc/03-connection/handler.go | 8 ++++---- x/ibc/04-channel/handler.go | 12 ++++++------ x/ibc/20-transfer/handler.go | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index 3354fe93b8c4..df6f41e3a72d 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -57,7 +57,7 @@ func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg exported.MsgCreateClie }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -86,7 +86,7 @@ func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg exported.MsgUpdateClie }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } diff --git a/x/ibc/03-connection/handler.go b/x/ibc/03-connection/handler.go index 14c227f7154d..42da0f7de72f 100644 --- a/x/ibc/03-connection/handler.go +++ b/x/ibc/03-connection/handler.go @@ -28,7 +28,7 @@ func HandleMsgConnectionOpenInit(ctx sdk.Context, k Keeper, msg MsgConnectionOpe }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -57,7 +57,7 @@ func HandleMsgConnectionOpenTry(ctx sdk.Context, k Keeper, msg MsgConnectionOpen }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -83,7 +83,7 @@ func HandleMsgConnectionOpenAck(ctx sdk.Context, k Keeper, msg MsgConnectionOpen }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -108,6 +108,6 @@ func HandleMsgConnectionOpenConfirm(ctx sdk.Context, k Keeper, msg MsgConnection }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } diff --git a/x/ibc/04-channel/handler.go b/x/ibc/04-channel/handler.go index 6b602e08ec87..64a36402df1b 100644 --- a/x/ibc/04-channel/handler.go +++ b/x/ibc/04-channel/handler.go @@ -33,7 +33,7 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCha }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -63,7 +63,7 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -90,7 +90,7 @@ func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -115,7 +115,7 @@ func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Msg }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -140,7 +140,7 @@ func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCh }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -165,6 +165,6 @@ func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Ms }) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 4b96f58dd3f2..98916ed856a7 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -50,7 +50,7 @@ func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, ) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -86,7 +86,7 @@ func handlePacketDataTransfer( ) return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } @@ -106,6 +106,6 @@ func handleTimeoutDataTransfer( } return &sdk.Result{ - Events: ctx.EventManager().Events(), + Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } From eb0930ea61af33b287cc1fb07d422534e9cf2402 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Thu, 2 Apr 2020 11:45:43 -0300 Subject: [PATCH 153/176] fix HistoricalInfo sim decoders --- x/staking/simulation/decoder.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x/staking/simulation/decoder.go b/x/staking/simulation/decoder.go index 205c59d1cdf9..fc4ef61605cb 100644 --- a/x/staking/simulation/decoder.go +++ b/x/staking/simulation/decoder.go @@ -52,9 +52,10 @@ func DecodeStore(cdc *codec.Codec, kvA, kvB tmkv.Pair) string { return fmt.Sprintf("%v\n%v", redA, redB) case bytes.Equal(kvA.Key[:1], types.HistoricalInfoKey): - var histInfo types.HistoricalInfo - cdc.Seal().MustUnmarshalBinaryLengthPrefixed(kvA.Value, &histInfo) - return fmt.Sprintf("%v", histInfo) + var histInfoA, histInfoB types.HistoricalInfo + cdc.MustUnmarshalBinaryBare(kvA.Value, histInfoA) + cdc.MustUnmarshalBinaryBare(kvB.Value, histInfoB) + return fmt.Sprintf("%v\n%v", histInfoA, histInfoB) default: panic(fmt.Sprintf("invalid staking key prefix %X", kvA.Key[:1])) From 70a0e3056bcaea8ea2ddd5d961f06235e484faa0 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Thu, 2 Apr 2020 11:49:34 -0300 Subject: [PATCH 154/176] add staking sim decoder test case for HistInfo --- x/staking/simulation/decoder_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x/staking/simulation/decoder_test.go b/x/staking/simulation/decoder_test.go index 40dd39710e84..fbe6482e71da 100644 --- a/x/staking/simulation/decoder_test.go +++ b/x/staking/simulation/decoder_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" tmkv "github.com/tendermint/tendermint/libs/kv" @@ -38,6 +39,7 @@ func TestDecodeStore(t *testing.T) { del := types.NewDelegation(delAddr1, valAddr1, sdk.OneDec()) ubd := types.NewUnbondingDelegation(delAddr1, valAddr1, 15, bondTime, sdk.OneInt()) red := types.NewRedelegation(delAddr1, valAddr1, valAddr1, 12, bondTime, sdk.OneInt(), sdk.OneDec()) + histInfo := types.NewHistoricalInfo(abci.Header{ChainID: "gaia", Height: 10, Time: bondTime}, types.Validators{val}) kvPairs := tmkv.Pairs{ tmkv.Pair{Key: types.LastTotalPowerKey, Value: cdc.MustMarshalBinaryBare(sdk.OneInt())}, @@ -46,6 +48,7 @@ func TestDecodeStore(t *testing.T) { tmkv.Pair{Key: types.GetDelegationKey(delAddr1, valAddr1), Value: cdc.MustMarshalBinaryBare(del)}, tmkv.Pair{Key: types.GetUBDKey(delAddr1, valAddr1), Value: cdc.MustMarshalBinaryBare(ubd)}, tmkv.Pair{Key: types.GetREDKey(delAddr1, valAddr1, valAddr1), Value: cdc.MustMarshalBinaryBare(red)}, + tmkv.Pair{Key: types.GetHistoricalInfoKey(10), Value: cdc.MustMarshalBinaryBare(histInfo)}, tmkv.Pair{Key: []byte{0x99}, Value: []byte{0x99}}, } From fa2ea30c957cff2cc8fdcf92a2f0f1f36c5f1fbb Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 2 Apr 2020 18:09:32 +0200 Subject: [PATCH 155/176] Merge PR #5901: Add & update IBC queriers for relayer use * Add identifier to connection responses (ref #5829) * Update querier as well * Fix test-case * Update for consistency * Add querier for connection channels; fix linter * Fix build (?) * Add JSON & Yaml tags * Add tags * Add identifiers to channels as well --- x/ibc/03-connection/client/utils/utils.go | 4 +-- x/ibc/03-connection/keeper/keeper.go | 9 +++--- x/ibc/03-connection/keeper/keeper_test.go | 12 +++++--- x/ibc/03-connection/keeper/querier.go | 2 +- x/ibc/03-connection/types/querier.go | 10 +++++-- x/ibc/04-channel/alias.go | 14 ++++++---- x/ibc/04-channel/client/utils/utils.go | 4 +-- x/ibc/04-channel/keeper/keeper.go | 9 +++--- x/ibc/04-channel/keeper/keeper_test.go | 12 +++++--- x/ibc/04-channel/keeper/querier.go | 34 ++++++++++++++++++++++- x/ibc/04-channel/types/querier.go | 32 ++++++++++++++++++--- x/ibc/keeper/querier.go | 2 ++ x/ibc/keeper/querier_test.go | 6 ++++ x/ibc/types/keys.go | 16 ++++++++++- 14 files changed, 131 insertions(+), 35 deletions(-) diff --git a/x/ibc/03-connection/client/utils/utils.go b/x/ibc/03-connection/client/utils/utils.go index f2cb94beac96..0334ad0b5393 100644 --- a/x/ibc/03-connection/client/utils/utils.go +++ b/x/ibc/03-connection/client/utils/utils.go @@ -17,7 +17,7 @@ import ( // QueryAllConnections returns all the connections. It _does not_ return // any merkle proof. -func QueryAllConnections(cliCtx context.CLIContext, page, limit int) ([]types.ConnectionEnd, int64, error) { +func QueryAllConnections(cliCtx context.CLIContext, page, limit int) ([]types.IdentifiedConnectionEnd, int64, error) { params := types.NewQueryAllConnectionsParams(page, limit) bz, err := cliCtx.Codec.MarshalJSON(params) if err != nil { @@ -30,7 +30,7 @@ func QueryAllConnections(cliCtx context.CLIContext, page, limit int) ([]types.Co return nil, 0, err } - var connections []types.ConnectionEnd + var connections []types.IdentifiedConnectionEnd err = cliCtx.Codec.UnmarshalJSON(res, &connections) if err != nil { return nil, 0, fmt.Errorf("failed to unmarshal connections: %w", err) diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index 165e46e93823..3ae51c8b44cb 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -87,7 +87,7 @@ func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths // IterateConnections provides an iterator over all ConnectionEnd objects. // For each ConnectionEnd, cb will be called. If the cb returns true, the // iterator will close and stop. -func (k Keeper) IterateConnections(ctx sdk.Context, cb func(types.ConnectionEnd) bool) { +func (k Keeper) IterateConnections(ctx sdk.Context, cb func(types.IdentifiedConnectionEnd) bool) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, ibctypes.KeyConnectionPrefix) @@ -95,16 +95,17 @@ func (k Keeper) IterateConnections(ctx sdk.Context, cb func(types.ConnectionEnd) for ; iterator.Valid(); iterator.Next() { var connection types.ConnectionEnd k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &connection) + identifier := string(iterator.Key()[len(ibctypes.KeyConnectionPrefix)+1:]) - if cb(connection) { + if cb(types.IdentifiedConnectionEnd{connection, identifier}) { break } } } // GetAllConnections returns all stored ConnectionEnd objects. -func (k Keeper) GetAllConnections(ctx sdk.Context) (connections []types.ConnectionEnd) { - k.IterateConnections(ctx, func(connection types.ConnectionEnd) bool { +func (k Keeper) GetAllConnections(ctx sdk.Context) (connections []types.IdentifiedConnectionEnd) { + k.IterateConnections(ctx, func(connection types.IdentifiedConnectionEnd) bool { connections = append(connections, connection) return false }) diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index b0143c0f5d6e..f70b405eed7e 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -111,11 +111,15 @@ func (suite KeeperTestSuite) TestGetAllConnections() { conn2 := types.NewConnectionEnd(exported.INIT, testClientIDB, counterparty1, types.GetCompatibleVersions()) conn3 := types.NewConnectionEnd(exported.UNINITIALIZED, testClientID3, counterparty2, types.GetCompatibleVersions()) - expConnections := []types.ConnectionEnd{conn1, conn2, conn3} + expConnections := []types.IdentifiedConnectionEnd{ + {Connection: conn1, Identifier: testConnectionIDA}, + {Connection: conn2, Identifier: testConnectionIDB}, + {Connection: conn3, Identifier: testConnectionID3}, + } - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionIDA, expConnections[0]) - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionIDB, expConnections[1]) - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionID3, expConnections[2]) + suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionIDA, conn1) + suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionIDB, conn2) + suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), testConnectionID3, conn3) connections := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetAllConnections(suite.chainA.GetContext()) suite.Require().Len(connections, len(expConnections)) diff --git a/x/ibc/03-connection/keeper/querier.go b/x/ibc/03-connection/keeper/querier.go index 8225eccaa858..1eebee214bd5 100644 --- a/x/ibc/03-connection/keeper/querier.go +++ b/x/ibc/03-connection/keeper/querier.go @@ -22,7 +22,7 @@ func QuerierConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt start, end := client.Paginate(len(connections), params.Page, params.Limit, 100) if start < 0 || end < 0 { - connections = []types.ConnectionEnd{} + connections = []types.IdentifiedConnectionEnd{} } else { connections = connections[start:end] } diff --git a/x/ibc/03-connection/types/querier.go b/x/ibc/03-connection/types/querier.go index 48db30da8f95..a283f37641f9 100644 --- a/x/ibc/03-connection/types/querier.go +++ b/x/ibc/03-connection/types/querier.go @@ -15,10 +15,16 @@ const ( QueryClientConnections = "client_connections" ) +// IdentifiedConnectionEnd defines the union of a connection end & an identifier. +type IdentifiedConnectionEnd struct { + Connection ConnectionEnd `json:"connection_end" yaml:"connection_end"` + Identifier string `json:"identifier" yaml:"identifier"` +} + // ConnectionResponse defines the client query response for a connection which // also includes a proof and the height from which the proof was retrieved. type ConnectionResponse struct { - Connection ConnectionEnd `json:"connection" yaml:"connection"` + Connection IdentifiedConnectionEnd `json:"connection" yaml:"connection"` Proof commitmenttypes.MerkleProof `json:"proof,omitempty" yaml:"proof,omitempty"` ProofPath commitmenttypes.MerklePath `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` @@ -29,7 +35,7 @@ func NewConnectionResponse( connectionID string, connection ConnectionEnd, proof *merkle.Proof, height int64, ) ConnectionResponse { return ConnectionResponse{ - Connection: connection, + Connection: IdentifiedConnectionEnd{connection, connectionID}, Proof: commitmenttypes.MerkleProof{Proof: proof}, ProofPath: commitmenttypes.NewMerklePath(strings.Split(ibctypes.ConnectionPath(connectionID), "/")), ProofHeight: uint64(height), diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index dc4073212266..55b3ac78d0b2 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -12,18 +12,20 @@ import ( ) const ( - SubModuleName = types.SubModuleName - StoreKey = types.StoreKey - RouterKey = types.RouterKey - QuerierRoute = types.QuerierRoute - QueryAllChannels = types.QueryAllChannels - QueryChannel = types.QueryChannel + SubModuleName = types.SubModuleName + StoreKey = types.StoreKey + RouterKey = types.RouterKey + QuerierRoute = types.QuerierRoute + QueryAllChannels = types.QueryAllChannels + QueryConnectionChannels = types.QueryConnectionChannels + QueryChannel = types.QueryChannel ) var ( // functions aliases NewKeeper = keeper.NewKeeper QuerierChannels = keeper.QuerierChannels + QuerierConnectionChannels = keeper.QuerierConnectionChannels NewChannel = types.NewChannel NewCounterparty = types.NewCounterparty RegisterCodec = types.RegisterCodec diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index b9fbd9175ba1..729fad9d1d2e 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -29,8 +29,8 @@ func QueryPacket( return types.PacketResponse{}, err } - destPortID := channelRes.Channel.Counterparty.PortID - destChannelID := channelRes.Channel.Counterparty.ChannelID + destPortID := channelRes.Channel.Channel.Counterparty.PortID + destChannelID := channelRes.Channel.Channel.Counterparty.ChannelID packet := types.NewPacket( res.Value, diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index ab756c044971..bccdeb775765 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -151,7 +151,7 @@ func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID stri // IterateChannels provides an iterator over all Channel objects. For each // Channel, cb will be called. If the cb returns true, the iterator will close // and stop. -func (k Keeper) IterateChannels(ctx sdk.Context, cb func(types.Channel) bool) { +func (k Keeper) IterateChannels(ctx sdk.Context, cb func(types.IdentifiedChannel) bool) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, ibctypes.GetChannelPortsKeysPrefix(ibctypes.KeyChannelPrefix)) @@ -159,16 +159,17 @@ func (k Keeper) IterateChannels(ctx sdk.Context, cb func(types.Channel) bool) { for ; iterator.Valid(); iterator.Next() { var channel types.Channel k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &channel) + portID, channelID := ibctypes.MustParseChannelPath(string(iterator.Key())) - if cb(channel) { + if cb(types.IdentifiedChannel{Channel: channel, PortIdentifier: portID, ChannelIdentifier: channelID}) { break } } } // GetAllChannels returns all stored Channel objects. -func (k Keeper) GetAllChannels(ctx sdk.Context) (channels []types.Channel) { - k.IterateChannels(ctx, func(channel types.Channel) bool { +func (k Keeper) GetAllChannels(ctx sdk.Context) (channels []types.IdentifiedChannel) { + k.IterateChannels(ctx, func(channel types.IdentifiedChannel) bool { channels = append(channels, channel) return false }) diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index 2bf08ae2669e..8780b1feba9d 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -121,12 +121,16 @@ func (suite KeeperTestSuite) TestGetAllChannels() { Version: testChannelVersion, } - expChannels := []types.Channel{channel1, channel2, channel3} + expChannels := []types.IdentifiedChannel{ + {Channel: channel1, PortIdentifier: testPort1, ChannelIdentifier: testChannel1}, + {Channel: channel2, PortIdentifier: testPort2, ChannelIdentifier: testChannel2}, + {Channel: channel3, PortIdentifier: testPort3, ChannelIdentifier: testChannel3}, + } ctx := suite.chainB.GetContext() - suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort1, testChannel1, expChannels[0]) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort2, testChannel2, expChannels[1]) - suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort3, testChannel3, expChannels[2]) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort1, testChannel1, channel1) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort2, testChannel2, channel2) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel(ctx, testPort3, testChannel3, channel3) channels := suite.chainB.App.IBCKeeper.ChannelKeeper.GetAllChannels(ctx) suite.Require().Len(channels, len(expChannels)) diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go index 0d60cab08c8b..91dfce5ec5ed 100644 --- a/x/ibc/04-channel/keeper/querier.go +++ b/x/ibc/04-channel/keeper/querier.go @@ -22,7 +22,7 @@ func QuerierChannels(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, start, end := client.Paginate(len(channels), params.Page, params.Limit, 100) if start < 0 || end < 0 { - channels = []types.Channel{} + channels = []types.IdentifiedChannel{} } else { channels = channels[start:end] } @@ -34,3 +34,35 @@ func QuerierChannels(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, return res, nil } + +// QuerierConnectionChannels defines the sdk.Querier to query all the channels for a connection. +func QuerierConnectionChannels(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { + var params types.QueryConnectionChannelsParams + + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) + } + + channels := k.GetAllChannels(ctx) + + connectionChannels := []types.IdentifiedChannel{} + for _, channel := range channels { + if channel.Channel.ConnectionHops[0] == params.Connection { + connectionChannels = append(connectionChannels, channel) + } + } + + start, end := client.Paginate(len(connectionChannels), params.Page, params.Limit, 100) + if start < 0 || end < 0 { + connectionChannels = []types.IdentifiedChannel{} + } else { + connectionChannels = channels[start:end] + } + + res, err := codec.MarshalJSONIndent(k.cdc, connectionChannels) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go index fdedeca408b6..289a5bfc3cc6 100644 --- a/x/ibc/04-channel/types/querier.go +++ b/x/ibc/04-channel/types/querier.go @@ -11,14 +11,21 @@ import ( // query routes supported by the IBC channel Querier const ( - QueryAllChannels = "channels" - QueryChannel = "channel" + QueryAllChannels = "channels" + QueryChannel = "channel" + QueryConnectionChannels = "connection-channels" ) +type IdentifiedChannel struct { + Channel Channel `json:"channel_end" yaml:"channel_end"` + PortIdentifier string `json:"port_identifier" yaml:"port_identifier"` + ChannelIdentifier string `json:"channel_identifier" yaml:"channel_identifier"` +} + // ChannelResponse defines the client query response for a channel which also // includes a proof,its path and the height from which the proof was retrieved. type ChannelResponse struct { - Channel Channel `json:"channel" yaml:"channel"` + Channel IdentifiedChannel `json:"channel" yaml:"channel"` Proof commitmenttypes.MerkleProof `json:"proof,omitempty" yaml:"proof,omitempty"` ProofPath commitmenttypes.MerklePath `json:"proof_path,omitempty" yaml:"proof_path,omitempty"` ProofHeight uint64 `json:"proof_height,omitempty" yaml:"proof_height,omitempty"` @@ -29,7 +36,7 @@ func NewChannelResponse( portID, channelID string, channel Channel, proof *merkle.Proof, height int64, ) ChannelResponse { return ChannelResponse{ - Channel: channel, + Channel: IdentifiedChannel{Channel: channel, PortIdentifier: portID, ChannelIdentifier: channelID}, Proof: commitmenttypes.MerkleProof{Proof: proof}, ProofPath: commitmenttypes.NewMerklePath(strings.Split(ibctypes.ChannelPath(portID, channelID), "/")), ProofHeight: uint64(height), @@ -51,6 +58,23 @@ func NewQueryAllChannelsParams(page, limit int) QueryAllChannelsParams { } } +// QueryConnectionChannelsParams defines the parameters necessary for querying +// for all channels associated with a given connection. +type QueryConnectionChannelsParams struct { + Connection string `json:"connection" yaml:"connection"` + Page int `json:"page" yaml:"page"` + Limit int `json:"limit" yaml:"limit"` +} + +// NewQueryConnectionChannelsParams creates a new QueryConnectionChannelsParams instance. +func NewQueryConnectionChannelsParams(connection string, page, limit int) QueryConnectionChannelsParams { + return QueryConnectionChannelsParams{ + Connection: connection, + Page: page, + Limit: limit, + } +} + // PacketResponse defines the client query response for a packet which also // includes a proof, its path and the height form which the proof was retrieved type PacketResponse struct { diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index 20bd0e746e82..0f9b2f0f5be5 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -39,6 +39,8 @@ func NewQuerier(k Keeper) sdk.Querier { switch path[1] { case channel.QueryAllChannels: res, err = channel.QuerierChannels(ctx, req, k.ChannelKeeper) + case channel.QueryConnectionChannels: + res, err = channel.QuerierConnectionChannels(ctx, req, k.ChannelKeeper) default: err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", channel.SubModuleName) } diff --git a/x/ibc/keeper/querier_test.go b/x/ibc/keeper/querier_test.go index 3c8231c6be06..83987a517cc1 100644 --- a/x/ibc/keeper/querier_test.go +++ b/x/ibc/keeper/querier_test.go @@ -79,6 +79,12 @@ func (suite *KeeperTestSuite) TestNewQuerier() { false, "", }, + { + "channel - QuerierConnectionChannels", + []string{channel.SubModuleName, channel.QueryConnectionChannels}, + false, + "", + }, { "channel - invalid query", []string{channel.SubModuleName, "foo"}, diff --git a/x/ibc/types/keys.go b/x/ibc/types/keys.go index 8789ec33cc82..edb2ed243eb3 100644 --- a/x/ibc/types/keys.go +++ b/x/ibc/types/keys.go @@ -1,6 +1,9 @@ package types -import "fmt" +import ( + "fmt" + "strings" +) const ( // ModuleName is the name of the IBC module @@ -179,6 +182,17 @@ func channelPath(portID, channelID string) string { return fmt.Sprintf("ports/%s/channels/%s", portID, channelID) } +func MustParseChannelPath(path string) (string, string) { + split := strings.Split(path, "/") + if len(split) != 5 { + panic("cannot parse channel path") + } + if split[1] != "ports" || split[3] != "channels" { + panic("cannot parse channel path") + } + return split[2], split[4] +} + // ICS05 // The following paths are the keys to the store as defined in https://github.com/cosmos/ics/tree/master/spec/ics-005-port-allocation#store-paths From cb485e00c10e0924966456787d692571766acf5b Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Thu, 2 Apr 2020 13:41:29 -0300 Subject: [PATCH 156/176] fix test --- sim_state-4.json | 0 x/staking/simulation/decoder.go | 4 ++-- x/staking/simulation/decoder_test.go | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 sim_state-4.json diff --git a/sim_state-4.json b/sim_state-4.json new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/x/staking/simulation/decoder.go b/x/staking/simulation/decoder.go index fc4ef61605cb..efd8cb917e42 100644 --- a/x/staking/simulation/decoder.go +++ b/x/staking/simulation/decoder.go @@ -53,8 +53,8 @@ func DecodeStore(cdc *codec.Codec, kvA, kvB tmkv.Pair) string { case bytes.Equal(kvA.Key[:1], types.HistoricalInfoKey): var histInfoA, histInfoB types.HistoricalInfo - cdc.MustUnmarshalBinaryBare(kvA.Value, histInfoA) - cdc.MustUnmarshalBinaryBare(kvB.Value, histInfoB) + cdc.MustUnmarshalBinaryBare(kvA.Value, &histInfoA) + cdc.MustUnmarshalBinaryBare(kvB.Value, &histInfoB) return fmt.Sprintf("%v\n%v", histInfoA, histInfoB) default: diff --git a/x/staking/simulation/decoder_test.go b/x/staking/simulation/decoder_test.go index fbe6482e71da..813f7fc74a6f 100644 --- a/x/staking/simulation/decoder_test.go +++ b/x/staking/simulation/decoder_test.go @@ -62,6 +62,7 @@ func TestDecodeStore(t *testing.T) { {"Delegation", fmt.Sprintf("%v\n%v", del, del)}, {"UnbondingDelegation", fmt.Sprintf("%v\n%v", ubd, ubd)}, {"Redelegation", fmt.Sprintf("%v\n%v", red, red)}, + {"HistoricalInfo", fmt.Sprintf("%v\n%v", histInfo, histInfo)}, {"other", ""}, } for i, tt := range tests { From 0d39e00ba03fbc0e2596cb015bfa6e7dcc60be8d Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Thu, 2 Apr 2020 15:05:11 -0400 Subject: [PATCH 157/176] Merge PR #5914: x/capability: Fix Object Capability Model --- baseapp/baseapp.go | 8 -- .../adr-003-dynamic-capability-store.md | 130 +++++++++++------- simapp/app.go | 19 +-- store/mem/mem_test.go | 39 ------ store/mem/store.go | 53 ------- store/rootmulti/store.go | 8 -- store/types/store.go | 23 ---- types/store.go | 13 -- x/capability/alias.go | 2 + x/capability/keeper/keeper.go | 61 +++----- x/capability/keeper/keeper_test.go | 5 +- x/capability/types/store.go | 56 ++++++++ 12 files changed, 163 insertions(+), 254 deletions(-) delete mode 100644 store/mem/mem_test.go delete mode 100644 store/mem/store.go create mode 100644 x/capability/types/store.go diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 9a0558c889e0..f52aa0dd11e6 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -195,14 +195,6 @@ func (app *BaseApp) MountTransientStores(keys map[string]*sdk.TransientStoreKey) } } -// MountMemoryStores mounts all in-memory KVStores with the BaseApp's internal -// commit multi-store. -func (app *BaseApp) MountMemoryStores(keys map[string]*sdk.MemoryStoreKey) { - for _, memKey := range keys { - app.MountStore(memKey, sdk.StoreTypeMemory) - } -} - // MountStoreWithDB mounts a store to the provided key in the BaseApp // multistore, using a specified DB. func (app *BaseApp) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) { diff --git a/docs/architecture/adr-003-dynamic-capability-store.md b/docs/architecture/adr-003-dynamic-capability-store.md index c44f1dd1977d..104deb109660 100644 --- a/docs/architecture/adr-003-dynamic-capability-store.md +++ b/docs/architecture/adr-003-dynamic-capability-store.md @@ -3,6 +3,7 @@ ## Changelog - 12 December 2019: Initial version +- 02 April 2020: Memory Store Revisions ## Context @@ -15,20 +16,33 @@ At present, the Cosmos SDK does not have the ability to do this. Object-capabili and passed to Keepers as fixed arguments ([example](https://github.com/cosmos/gaia/blob/dcbddd9f04b3086c0ad07ee65de16e7adedc7da4/app/app.go#L160)). Keepers cannot create or store capability keys during transaction execution — although they could call `NewKVStoreKey` and take the memory address of the returned struct, storing this in the Merklised store would result in a consensus fault, since the memory address will be different on each machine (this is intentional — were this not the case, the keys would be predictable and couldn't serve as object capabilities). -Keepers need a way to keep a private map of store keys which can be altered during transacton execution, along with a suitable mechanism for regenerating the unique memory addresses (capability keys) in this map whenever the application is started or restarted. +Keepers need a way to keep a private map of store keys which can be altered during transaction execution, along with a suitable mechanism for regenerating the unique memory addresses (capability keys) in this map whenever the application is started or restarted. This ADR proposes such an interface & mechanism. ## Decision -The SDK will include a new `CapabilityKeeper` abstraction, which is responsible for provisioning, tracking, and authenticating capabilities at runtime. During application initialisation in `app.go`, the `CapabilityKeeper` will -be hooked up to modules through unique function references (by calling `ScopeToModule`, defined below) so that it can identify the calling module when later invoked. When the initial state is loaded from disk, the `CapabilityKeeper`'s `Initialise` function will create new capability keys -for all previously allocated capability identifiers (allocated during execution of past transactions and assigned to particular modes), and keep them in a memory-only store while the chain is running. The SDK will include a new `MemoryStore` store type, similar -to the existing `TransientStore` but without erasure on `Commit()`, which this `CapabilityKeeper` will use to privately store capability keys. +The SDK will include a new `CapabilityKeeper` abstraction, which is responsible for provisioning, +tracking, and authenticating capabilities at runtime. During application initialisation in `app.go`, +the `CapabilityKeeper` will be hooked up to modules through unique function references +(by calling `ScopeToModule`, defined below) so that it can identify the calling module when later +invoked. -The `CapabilityKeeper` will use two stores: a regular, persistent `KVStore`, which will track what capabilities have been created by each module, and an in-memory `MemoryStore` (described below), which will -store the actual capabilities. The `CapabilityKeeper` will define the following types & functions: +When the initial state is loaded from disk, the `CapabilityKeeper`'s `Initialise` function will create +new capability keys for all previously allocated capability identifiers (allocated during execution of +past transactions and assigned to particular modes), and keep them in a memory-only store while the +chain is running. -The `Capability` interface is similar to `StoreKey`, but has a globally unique `Index()` instead of a name. A `String()` method is provided for debugging. +The `CapabilityKeeper` will include an ephemeral in-memory `CapabilityStore`, which internally maintains +two maps, one for forward mappings that map from module name, capability tuples to capability names and +one for reverse mappings that map from module name, capability name to capabilities. The reverse +mapping contains the actual capability objects by reference. + +In addition to the `CapabilityStore`, the `CapabilityKeeper` will use a persistent `KVStore`, which +will track what capabilities have been created by each module. The `CapabilityKeeper` will define the +following types & functions: + +The `Capability` interface is similar to `StoreKey`, but has a globally unique `Index()` instead of +a name. A `String()` method is provided for debugging. ```golang type Capability interface { @@ -50,25 +64,28 @@ A `CapabilityKeeper` contains a persistent store key, memory store key, and mapp ```golang type CapabilityKeeper struct { persistentKey StoreKey - memoryKey MemoryStoreKey - moduleNames map[string]interface{} - sealed bool + capStore CapabilityStore + moduleNames map[string]interface{} + sealed bool } ``` -The `CapabilityKeeper` provides the ability to create *scoped* sub-keepers which are tied to a particular module name. These `ScopedCapabilityKeeper`s must be created at application -initialisation and passed to modules, which can then use them to claim capabilities they receive and retrieve capabilities which they own by name, in addition -to creating new capabilities & authenticating capabilities passed by other modules. +The `CapabilityKeeper` provides the ability to create *scoped* sub-keepers which are tied to a +particular module name. These `ScopedCapabilityKeeper`s must be created at application initialisation +and passed to modules, which can then use them to claim capabilities they receive and retrieve +capabilities which they own by name, in addition to creating new capabilities & authenticating capabilities +passed by other modules. ```golang type ScopedCapabilityKeeper struct { persistentKey StoreKey - memoryKey MemoryStoreKey - moduleName string + capStore CapabilityStore + moduleName string } ``` -`ScopeToModule` is used to create a scoped sub-keeper with a particular name, which must be unique. It MUST be called before `InitialiseAndSeal`. +`ScopeToModule` is used to create a scoped sub-keeper with a particular name, which must be unique. +It MUST be called before `InitialiseAndSeal`. ```golang func (ck CapabilityKeeper) ScopeToModule(moduleName string) ScopedCapabilityKeeper { @@ -78,35 +95,41 @@ func (ck CapabilityKeeper) ScopeToModule(moduleName string) ScopedCapabilityKeep if _, present := ck.moduleNames[moduleName]; present { panic("cannot create multiple scoped capability keepers for the same module name") } + ck.moduleNames[moduleName] = struct{}{} + return ScopedCapabilityKeeper{ persistentKey: ck.persistentKey, - memoryKey: ck.memoryKey, - moduleName: moduleName + capStore: ck.capStore, + moduleName: moduleName, } } ``` -`InitialiseAndSeal` MUST be called exactly once, after loading the initial state and creating all necessary `ScopedCapabilityKeeper`s, -in order to populate the memory store with newly-created capability keys in accordance with the keys previously claimed by particular modules -and prevent the creation of any new `ScopedCapabilityKeeper`s. +`InitialiseAndSeal` MUST be called exactly once, after loading the initial state and creating all +necessary `ScopedCapabilityKeeper`s, in order to populate the memory store with newly-created +capability keys in accordance with the keys previously claimed by particular modules and prevent the +creation of any new `ScopedCapabilityKeeper`s. ```golang func (ck CapabilityKeeper) InitialiseAndSeal(ctx Context) { if ck.sealed { panic("capability keeper is sealed") } + persistentStore := ctx.KVStore(ck.persistentKey) - memoryStore := ctx.KVStore(ck.memoryKey) + // initialise memory store for all names in persistent store for index, value := range persistentStore.Iter() { capability = &CapabilityKey{index: index} + for moduleAndCapability := range value { moduleName, capabilityName := moduleAndCapability.Split("/") - memoryStore.Set(moduleName + "/fwd/" + capability, capabilityName) - memoryStore.Set(moduleName + "/rev/" + capabilityName, capability) + capStore.Set(moduleName + "/fwd/" + capability, capabilityName) + capStore.Set(moduleName + "/rev/" + capabilityName, capability) } } + ck.sealed = true } ``` @@ -117,24 +140,30 @@ call `ClaimCapability`. ```golang func (sck ScopedCapabilityKeeper) NewCapability(ctx Context, name string) (Capability, error) { - memoryStore := ctx.KVStore(sck.memoryKey) // check name not taken in memory store - if memoryStore.Get("rev/" + name) != nil { + if capStore.Get("rev/" + name) != nil { return nil, errors.New("name already taken") } + // fetch the current index index := persistentStore.Get("index") + // create a new capability capability := &CapabilityKey{index: index} + // set persistent store persistentStore.Set(index, Set.singleton(sck.moduleName + "/" + name)) + // update the index index++ persistentStore.Set("index", index) + // set forward mapping in memory store from capability to name - memoryStore.Set(sck.moduleName + "/fwd/" + capability, name) + capStore.Set(sck.moduleName + "/fwd/" + capability, name) + // set reverse mapping in memory store from name to capability - memoryStore.Set(sck.moduleName + "/rev/" + name, capability) + capStore.Set(sck.moduleName + "/rev/" + name, capability) + // return the newly created capability return capability } @@ -146,24 +175,28 @@ with which the calling module previously associated it. ```golang func (sck ScopedCapabilityKeeper) AuthenticateCapability(name string, capability Capability) bool { - memoryStore := ctx.KVStore(sck.memoryKey) // return whether forward mapping in memory store matches name - return memoryStore.Get(sck.moduleName + "/fwd/" + capability) === name + return capStore.Get(sck.moduleName + "/fwd/" + capability) === name } ``` -`ClaimCapability` allows a module to claim a capability key which it has received from another module so that future `GetCapability` calls will succeed. +`ClaimCapability` allows a module to claim a capability key which it has received from another module +so that future `GetCapability` calls will succeed. -`ClaimCapability` MUST be called if a module which receives a capability wishes to access it by name in the future. Capabilities are multi-owner, so if multiple modules have a single `Capability` reference, they will all own it. +`ClaimCapability` MUST be called if a module which receives a capability wishes to access it by name +in the future. Capabilities are multi-owner, so if multiple modules have a single `Capability` reference, +they will all own it. ```golang func (sck ScopedCapabilityKeeper) ClaimCapability(ctx Context, capability Capability, name string) error { persistentStore := ctx.KVStore(sck.persistentKey) - memoryStore := ctx.KVStore(sck.memoryKey) + // set forward mapping in memory store from capability to name - memoryStore.Set(sck.moduleName + "/fwd/" + capability, name) + capStore.Set(sck.moduleName + "/fwd/" + capability, name) + // set reverse mapping in memory store from name to capability - memoryStore.Set(sck.moduleName + "/rev/" + name, capability) + capStore.Set(sck.moduleName + "/rev/" + name, capability) + // update owner set in persistent store owners := persistentStore.Get(capability.Index()) owners.add(sck.moduleName + "/" + name) @@ -171,32 +204,37 @@ func (sck ScopedCapabilityKeeper) ClaimCapability(ctx Context, capability Capabi } ``` -`GetCapability` allows a module to fetch a capability which it has previously claimed by name. The module is not allowed to retrieve capabilities which it does not own. +`GetCapability` allows a module to fetch a capability which it has previously claimed by name. +The module is not allowed to retrieve capabilities which it does not own. ```golang func (sck ScopedCapabilityKeeper) GetCapability(ctx Context, name string) (Capability, error) { - memoryStore := ctx.KVStore(sck.memoryKey) // fetch capability from memory store - capability := memoryStore.Get(sck.moduleName + "/rev/" + name) + capability := capStore.Get(sck.moduleName + "/rev/" + name) + // return the capability return capability } ``` -`ReleaseCapability` allows a module to release a capability which it had previously claimed. If no more owners exist, the capability will be deleted globally. +`ReleaseCapability` allows a module to release a capability which it had previously claimed. If no +more owners exist, the capability will be deleted globally. ```golang func (sck ScopedCapabilityKeeper) ReleaseCapability(ctx Context, capability Capability) err { persistentStore := ctx.KVStore(sck.persistentKey) - memoryStore := ctx.KVStore(sck.memoryKey) - name := memoryStore.Get(sck.moduleName + "/fwd/" + capability) + + name := capStore.Get(sck.moduleName + "/fwd/" + capability) if name == nil { return error("capability not owned by module") } + // delete forward mapping in memory store memoryStore.Delete(sck.moduleName + "/fwd/" + capability, name) + // delete reverse mapping in memory store memoryStore.Delete(sck.moduleName + "/rev/" + name, capability) + // update owner set in persistent store owners := persistentStore.Get(capability.Index()) owners.remove(sck.moduleName + "/" + name) @@ -210,14 +248,6 @@ func (sck ScopedCapabilityKeeper) ReleaseCapability(ctx Context, capability Capa } ``` -### Memory store - -A new store key type, `MemoryStoreKey`, will be added to the `store` package. The `MemoryStoreKey`s work just like `StoreKey`s. - -The memory store will work just like the current transient store, except that it will not create a new `dbadapter.Store` when `Commit()` is called, but instead retain the current one (so that state will persist across blocks). - -Initially the memory store will only be used by the `CapabilityKeeper`, but it could be used by other modules in the future. - ### Usage patterns #### Initialisation diff --git a/simapp/app.go b/simapp/app.go index 8e73e752217f..1e2427d9d657 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -100,9 +100,8 @@ type SimApp struct { invCheckPeriod uint // keys to access the substores - keys map[string]*sdk.KVStoreKey - tkeys map[string]*sdk.TransientStoreKey - memKeys map[string]*sdk.MemoryStoreKey + keys map[string]*sdk.KVStoreKey + tkeys map[string]*sdk.TransientStoreKey // subspaces subspaces map[string]params.Subspace @@ -152,7 +151,6 @@ func NewSimApp( evidence.StoreKey, transfer.StoreKey, capability.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(params.TStoreKey) - memKeys := sdk.NewMemoryStoreKeys(capability.MemStoreKey) app := &SimApp{ BaseApp: bApp, @@ -160,7 +158,6 @@ func NewSimApp( invCheckPeriod: invCheckPeriod, keys: keys, tkeys: tkeys, - memKeys: memKeys, subspaces: make(map[string]params.Subspace), } @@ -183,9 +180,7 @@ func NewSimApp( app.BankKeeper = bank.NewBaseKeeper( appCodec, keys[bank.StoreKey], app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(), ) - app.CapabilityKeeper = capability.NewKeeper( - app.cdc, keys[capability.StoreKey], memKeys[capability.MemStoreKey], - ) + app.CapabilityKeeper = capability.NewKeeper(app.cdc, keys[capability.StoreKey]) app.SupplyKeeper = supply.NewKeeper( appCodec, keys[supply.StoreKey], app.AccountKeeper, app.BankKeeper, maccPerms, ) @@ -303,7 +298,6 @@ func NewSimApp( // initialize stores app.MountKVStores(keys) app.MountTransientStores(tkeys) - app.MountMemoryStores(memKeys) // initialize BaseApp app.SetInitChainer(app.InitChainer) @@ -399,13 +393,6 @@ func (app *SimApp) GetTKey(storeKey string) *sdk.TransientStoreKey { return app.tkeys[storeKey] } -// GetMemKey returns the MemoryStoreKey for the provided store key. -// -// NOTE: This is solely to be used for testing purposes. -func (app *SimApp) GetMemKey(storeKey string) *sdk.MemoryStoreKey { - return app.memKeys[storeKey] -} - // GetSubspace returns a param subspace for a given module name. // // NOTE: This is solely to be used for testing purposes. diff --git a/store/mem/mem_test.go b/store/mem/mem_test.go deleted file mode 100644 index cff4c37da7dc..000000000000 --- a/store/mem/mem_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package mem_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/store/mem" - "github.com/cosmos/cosmos-sdk/store/types" -) - -func TestStore(t *testing.T) { - db := mem.NewStore() - key, value := []byte("key"), []byte("value") - - require.Equal(t, types.StoreTypeMemory, db.GetStoreType()) - - require.Nil(t, db.Get(key)) - db.Set(key, value) - require.Equal(t, value, db.Get(key)) - - newValue := []byte("newValue") - db.Set(key, newValue) - require.Equal(t, newValue, db.Get(key)) - - db.Delete(key) - require.Nil(t, db.Get(key)) -} - -func TestCommit(t *testing.T) { - db := mem.NewStore() - key, value := []byte("key"), []byte("value") - - db.Set(key, value) - id := db.Commit() - require.True(t, id.IsZero()) - require.True(t, db.LastCommitID().IsZero()) - require.Equal(t, value, db.Get(key)) -} diff --git a/store/mem/store.go b/store/mem/store.go deleted file mode 100644 index 3a1cdd617a0a..000000000000 --- a/store/mem/store.go +++ /dev/null @@ -1,53 +0,0 @@ -package mem - -import ( - "io" - - dbm "github.com/tendermint/tm-db" - - "github.com/cosmos/cosmos-sdk/store/cachekv" - "github.com/cosmos/cosmos-sdk/store/dbadapter" - "github.com/cosmos/cosmos-sdk/store/tracekv" - "github.com/cosmos/cosmos-sdk/store/types" -) - -var ( - _ types.KVStore = (*Store)(nil) - _ types.Committer = (*Store)(nil) -) - -// Store implements an in-memory only KVStore. Entries are persisted between -// commits and thus between blocks. State in Memory store is not committed as part of app state but maintained privately by each node -type Store struct { - dbadapter.Store -} - -func NewStore() *Store { - return NewStoreWithDB(dbm.NewMemDB()) -} - -func NewStoreWithDB(db *dbm.MemDB) *Store { // nolint: interfacer - return &Store{Store: dbadapter.Store{DB: db}} -} - -// GetStoreType returns the Store's type. -func (s Store) GetStoreType() types.StoreType { - return types.StoreTypeMemory -} - -// CacheWrap cache wraps the underlying store. -func (s Store) CacheWrap() types.CacheWrap { - return cachekv.NewStore(s) -} - -// CacheWrapWithTrace implements KVStore. -func (s Store) CacheWrapWithTrace(w io.Writer, tc types.TraceContext) types.CacheWrap { - return cachekv.NewStore(tracekv.NewStore(s, w, tc)) -} - -// Commit performs a no-op as entries are persistent between commitments. -func (s *Store) Commit() (id types.CommitID) { return } - -// nolint -func (s *Store) SetPruning(pruning types.PruningOptions) {} -func (s Store) LastCommitID() (id types.CommitID) { return } diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index 032da04416e2..21d26aacf342 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -16,7 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/store/cachemulti" "github.com/cosmos/cosmos-sdk/store/dbadapter" "github.com/cosmos/cosmos-sdk/store/iavl" - "github.com/cosmos/cosmos-sdk/store/mem" "github.com/cosmos/cosmos-sdk/store/tracekv" "github.com/cosmos/cosmos-sdk/store/transient" "github.com/cosmos/cosmos-sdk/store/types" @@ -529,13 +528,6 @@ func (rs *Store) loadCommitStoreFromParams(key types.StoreKey, id types.CommitID return transient.NewStore(), nil - case types.StoreTypeMemory: - if _, ok := key.(*types.MemoryStoreKey); !ok { - return nil, fmt.Errorf("unexpected key type for a MemoryStoreKey; got: %s", key.String()) - } - - return mem.NewStore(), nil - default: panic(fmt.Sprintf("unrecognized store type %v", params.typ)) } diff --git a/store/types/store.go b/store/types/store.go index cb0d3dd5c2ce..f22742863c97 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -273,7 +273,6 @@ const ( StoreTypeDB StoreTypeIAVL StoreTypeTransient - StoreTypeMemory ) func (st StoreType) String() string { @@ -289,9 +288,6 @@ func (st StoreType) String() string { case StoreTypeTransient: return "StoreTypeTransient" - - case StoreTypeMemory: - return "StoreTypeMemory" } return "unknown store type" @@ -355,25 +351,6 @@ func (key *TransientStoreKey) String() string { return fmt.Sprintf("TransientStoreKey{%p, %s}", key, key.name) } -// MemoryStoreKey defines a typed key to be used with an in-memory KVStore. -type MemoryStoreKey struct { - name string -} - -func NewMemoryStoreKey(name string) *MemoryStoreKey { - return &MemoryStoreKey{name: name} -} - -// Name returns the name of the MemoryStoreKey. -func (key *MemoryStoreKey) Name() string { - return key.name -} - -// String returns a stringified representation of the MemoryStoreKey. -func (key *MemoryStoreKey) String() string { - return fmt.Sprintf("MemoryStoreKey{%p, %s}", key, key.name) -} - //---------------------------------------- // key-value result for iterator queries diff --git a/types/store.go b/types/store.go index 884556cc6b26..ecf4c48dd8e4 100644 --- a/types/store.go +++ b/types/store.go @@ -76,7 +76,6 @@ const ( StoreTypeDB = types.StoreTypeDB StoreTypeIAVL = types.StoreTypeIAVL StoreTypeTransient = types.StoreTypeTransient - StoreTypeMemory = types.StoreTypeMemory ) // nolint - reexport @@ -85,7 +84,6 @@ type ( CapabilityKey = types.CapabilityKey KVStoreKey = types.KVStoreKey TransientStoreKey = types.TransientStoreKey - MemoryStoreKey = types.MemoryStoreKey ) // NewKVStoreKey returns a new pointer to a KVStoreKey. @@ -122,17 +120,6 @@ func NewTransientStoreKeys(names ...string) map[string]*TransientStoreKey { return keys } -// NewMemoryStoreKeys constructs a new map matching store key names to their -// respective MemoryStoreKey references. -func NewMemoryStoreKeys(names ...string) map[string]*MemoryStoreKey { - keys := make(map[string]*MemoryStoreKey) - for _, name := range names { - keys[name] = types.NewMemoryStoreKey(name) - } - - return keys -} - // PrefixEndBytes returns the []byte that would end a // range query for all []byte with a certain prefix // Deals with last byte of prefix being FF without overflowing diff --git a/x/capability/alias.go b/x/capability/alias.go index 7bf21b034e98..c3c8366c61db 100644 --- a/x/capability/alias.go +++ b/x/capability/alias.go @@ -30,6 +30,7 @@ var ( ModuleCdc = types.ModuleCdc NewOwner = types.NewOwner NewCapabilityOwners = types.NewCapabilityOwners + NewCapabilityStore = types.NewCapabilityStore ) // nolint @@ -39,4 +40,5 @@ type ( Capability = types.Capability CapabilityKey = types.CapabilityKey CapabilityOwners = types.CapabilityOwners + CapabilityStore = types.CapabilityStore ) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index acb33b3912cf..50d03e06d5d4 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -28,7 +28,7 @@ type ( Keeper struct { cdc *codec.Codec storeKey sdk.StoreKey - memKey sdk.StoreKey + capStore types.CapabilityStore scopedModules map[string]struct{} sealed bool } @@ -42,16 +42,16 @@ type ( ScopedKeeper struct { cdc *codec.Codec storeKey sdk.StoreKey - memKey sdk.StoreKey + capStore types.CapabilityStore // shared amongst all scoped keepers module string } ) -func NewKeeper(cdc *codec.Codec, storeKey, memKey sdk.StoreKey) *Keeper { +func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey) *Keeper { return &Keeper{ cdc: cdc, storeKey: storeKey, - memKey: memKey, + capStore: types.NewCapabilityStore(), scopedModules: make(map[string]struct{}), sealed: false, } @@ -74,7 +74,7 @@ func (k *Keeper) ScopeToModule(moduleName string) ScopedKeeper { return ScopedKeeper{ cdc: k.cdc, storeKey: k.storeKey, - memKey: k.memKey, + capStore: k.capStore, module: moduleName, } } @@ -88,13 +88,6 @@ func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { panic("cannot initialize and seal an already sealed capability keeper") } - memStore := ctx.KVStore(k.memKey) - memStoreType := memStore.GetStoreType() - - if memStoreType != sdk.StoreTypeMemory { - panic(fmt.Sprintf("invalid memory store type; got %s, expected: %s", memStoreType, sdk.StoreTypeMemory)) - } - prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixIndexCapability) iterator := sdk.KVStorePrefixIterator(prefixStore, nil) @@ -110,11 +103,11 @@ func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { for _, owner := range capOwners.Owners { // Set the forward mapping between the module and capability tuple and the // capability name in the in-memory store. - memStore.Set(types.FwdCapabilityKey(owner.Module, cap), []byte(owner.Name)) + k.capStore.SetCapabilityName(owner.Module, owner.Name, cap) // Set the reverse mapping between the module and capability name and the // capability in the in-memory store. - memStore.Set(types.RevCapabilityKey(owner.Module, owner.Name), k.cdc.MustMarshalBinaryBare(cap)) + k.capStore.SetCapability(owner.Module, owner.Name, cap) } } @@ -132,10 +125,10 @@ func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { // with the module name and no two ScopedKeeper can have the same module name. func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capability, error) { store := ctx.KVStore(sk.storeKey) - memStore := ctx.KVStore(sk.memKey) - if memStore.Has(types.RevCapabilityKey(sk.module, name)) { + if cap := sk.capStore.GetCapability(sk.module, name); cap != nil { return nil, sdkerrors.Wrapf(types.ErrCapabilityTaken, fmt.Sprintf("module: %s, name: %s", sk.module, name)) + } // create new capability with the current global index @@ -152,11 +145,11 @@ func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capabi // Set the forward mapping between the module and capability tuple and the // capability name in the in-memory store. - memStore.Set(types.FwdCapabilityKey(sk.module, cap), []byte(name)) + sk.capStore.SetCapabilityName(sk.module, name, cap) // Set the reverse mapping between the module and capability name and the // capability in the in-memory store. - memStore.Set(types.RevCapabilityKey(sk.module, name), sk.cdc.MustMarshalBinaryBare(cap)) + sk.capStore.SetCapability(sk.module, name, cap) logger(ctx).Info("created new capability", "module", sk.module, "name", name) return cap, nil @@ -171,10 +164,7 @@ func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capabi // Note, the capability's forward mapping is indexed by a string which should // contain its unique memory reference. func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap types.Capability, name string) bool { - memStore := ctx.KVStore(sk.memKey) - - bz := memStore.Get(types.FwdCapabilityKey(sk.module, cap)) - return string(bz) == name + return sk.capStore.GetCapabilityName(sk.module, cap) == name } // ClaimCapability attempts to claim a given Capability. The provided name and @@ -188,15 +178,13 @@ func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, na return err } - memStore := ctx.KVStore(sk.memKey) - // Set the forward mapping between the module and capability tuple and the // capability name in the in-memory store. - memStore.Set(types.FwdCapabilityKey(sk.module, cap), []byte(name)) + sk.capStore.SetCapabilityName(sk.module, name, cap) // Set the reverse mapping between the module and capability name and the // capability in the in-memory store. - memStore.Set(types.RevCapabilityKey(sk.module, name), sk.cdc.MustMarshalBinaryBare(cap)) + sk.capStore.SetCapability(sk.module, name, cap) logger(ctx).Info("claimed capability", "module", sk.module, "name", name, "capability", cap.GetIndex()) return nil @@ -206,22 +194,18 @@ func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, na // previously claimed or created. After releasing the capability, if no more // owners exist, the capability will be globally removed. func (sk ScopedKeeper) ReleaseCapability(ctx sdk.Context, cap types.Capability) error { - memStore := ctx.KVStore(sk.memKey) - - bz := memStore.Get(types.FwdCapabilityKey(sk.module, cap)) - if len(bz) == 0 { + name := sk.capStore.GetCapabilityName(sk.module, cap) + if len(name) == 0 { return sdkerrors.Wrap(types.ErrCapabilityNotOwned, sk.module) } - name := string(bz) - // Remove the forward mapping between the module and capability tuple and the // capability name in the in-memory store. - memStore.Delete(types.FwdCapabilityKey(sk.module, cap)) + sk.capStore.DeleteCapabilityName(sk.module, cap) // Remove the reverse mapping between the module and capability name and the // capability in the in-memory store. - memStore.Delete(types.RevCapabilityKey(sk.module, name)) + sk.capStore.DeleteCapability(sk.module, name) // remove owner capOwners := sk.getOwners(ctx, cap) @@ -245,16 +229,11 @@ func (sk ScopedKeeper) ReleaseCapability(ctx sdk.Context, cap types.Capability) // by name. The module is not allowed to retrieve capabilities which it does not // own. func (sk ScopedKeeper) GetCapability(ctx sdk.Context, name string) (types.Capability, bool) { - memStore := ctx.KVStore(sk.memKey) - - bz := memStore.Get(types.RevCapabilityKey(sk.module, name)) - if len(bz) == 0 { + cap := sk.capStore.GetCapability(sk.module, name) + if cap == nil { return nil, false } - var cap types.Capability - sk.cdc.MustUnmarshalBinaryBare(bz, &cap) - return cap, true } diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index 7c8df90b51bc..02440d3f8f19 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -29,9 +29,7 @@ func (suite *KeeperTestSuite) SetupTest() { app := simapp.Setup(checkTx) // create new keeper so we can define custom scoping before init and seal - keeper := keeper.NewKeeper( - app.Codec(), app.GetKey(capability.StoreKey), app.GetMemKey(capability.MemStoreKey), - ) + keeper := keeper.NewKeeper(app.Codec(), app.GetKey(capability.StoreKey)) suite.ctx = app.BaseApp.NewContext(checkTx, abci.Header{Height: 1}) suite.keeper = keeper @@ -82,6 +80,7 @@ func (suite *KeeperTestSuite) TestNewCapability() { got, ok := sk.GetCapability(suite.ctx, "transfer") suite.Require().True(ok) suite.Require().Equal(cap, got) + suite.Require().True(cap == got, "expected memory addresses to be equal") got, ok = sk.GetCapability(suite.ctx, "invalid") suite.Require().False(ok) diff --git a/x/capability/types/store.go b/x/capability/types/store.go new file mode 100644 index 000000000000..e46bddbdc0d8 --- /dev/null +++ b/x/capability/types/store.go @@ -0,0 +1,56 @@ +package types + +// CapabilityStore defines an ephemeral in-memory object capability store. +type CapabilityStore struct { + revMemStore map[string]Capability + fwdMemStore map[string]string +} + +func NewCapabilityStore() CapabilityStore { + return CapabilityStore{ + revMemStore: make(map[string]Capability), + fwdMemStore: make(map[string]string), + } +} + +// GetCapability returns a Capability by module and name tuple. If no Capability +// exists, nil will be returned. +func (cs CapabilityStore) GetCapability(module, name string) Capability { + key := RevCapabilityKey(module, name) + return cs.revMemStore[string(key)] +} + +// GetCapabilityName returns a Capability name by module and Capability tuple. If +// no Capability name exists for the given tuple, an empty string is returned. +func (cs CapabilityStore) GetCapabilityName(module string, cap Capability) string { + key := FwdCapabilityKey(module, cap) + return cs.fwdMemStore[string(key)] +} + +// SetCapability sets the reverse mapping between the module and capability name +// and the capability in the in-memory store. +func (cs CapabilityStore) SetCapability(module, name string, cap Capability) { + key := RevCapabilityKey(module, name) + cs.revMemStore[string(key)] = cap +} + +// SetCapabilityName sets the forward mapping between the module and capability +// tuple and the capability name in the in-memory store. +func (cs CapabilityStore) SetCapabilityName(module, name string, cap Capability) { + key := FwdCapabilityKey(module, cap) + cs.fwdMemStore[string(key)] = name +} + +// DeleteCapability removes the reverse mapping between the module and capability +// name and the capability in the in-memory store. +func (cs CapabilityStore) DeleteCapability(module, name string) { + key := RevCapabilityKey(module, name) + delete(cs.revMemStore, string(key)) +} + +// DeleteCapabilityName removes the forward mapping between the module and capability +// tuple and the capability name in the in-memory store. +func (cs CapabilityStore) DeleteCapabilityName(module string, cap Capability) { + key := FwdCapabilityKey(module, cap) + delete(cs.fwdMemStore, string(key)) +} From ebdd0a610c2ce72262cd48ec1143eb586b37c0bb Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 3 Apr 2020 09:36:10 +0200 Subject: [PATCH 158/176] Merge PR #5918: Remove source field from ICS 20 packet & message types per latest spec --- x/ibc/20-transfer/client/cli/tx.go | 7 +-- x/ibc/20-transfer/client/rest/rest.go | 1 - x/ibc/20-transfer/client/rest/tx.go | 1 - x/ibc/20-transfer/handler.go | 2 +- x/ibc/20-transfer/handler_test.go | 10 ++--- x/ibc/20-transfer/keeper/relay.go | 60 ++++++++++++++------------ x/ibc/20-transfer/keeper/relay_test.go | 28 +++--------- x/ibc/20-transfer/types/errors.go | 4 +- x/ibc/20-transfer/types/msgs.go | 4 +- x/ibc/20-transfer/types/msgs_test.go | 34 +++++++-------- x/ibc/20-transfer/types/packet.go | 9 +--- x/ibc/20-transfer/types/packet_test.go | 10 ++--- 12 files changed, 72 insertions(+), 98 deletions(-) diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index f91c9284ca14..1cf9553cb59c 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -5,7 +5,6 @@ import ( "strconv" "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/flags" @@ -18,7 +17,6 @@ import ( // IBC transfer flags var ( - FlagSource = "source" FlagNode1 = "node1" FlagNode2 = "node2" FlagFrom1 = "from1" @@ -57,9 +55,7 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { return err } - source := viper.GetBool(FlagSource) - - msg := types.NewMsgTransfer(srcPort, srcChannel, uint64(destHeight), coins, sender, receiver, source) + msg := types.NewMsgTransfer(srcPort, srcChannel, uint64(destHeight), coins, sender, receiver) if err := msg.ValidateBasic(); err != nil { return err } @@ -67,6 +63,5 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { return authclient.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) }, } - cmd.Flags().Bool(FlagSource, false, "Pass flag for sending token from the source chain") return cmd } diff --git a/x/ibc/20-transfer/client/rest/rest.go b/x/ibc/20-transfer/client/rest/rest.go index 625777e9291e..a49761f846d2 100644 --- a/x/ibc/20-transfer/client/rest/rest.go +++ b/x/ibc/20-transfer/client/rest/rest.go @@ -25,5 +25,4 @@ type TransferTxReq struct { DestHeight uint64 `json:"dest_height" yaml:"dest_height"` Amount sdk.Coins `json:"amount" yaml:"amount"` Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` - Source bool `json:"source" yaml:"source"` } diff --git a/x/ibc/20-transfer/client/rest/tx.go b/x/ibc/20-transfer/client/rest/tx.go index 726aa848bbef..554a0ae19b1e 100644 --- a/x/ibc/20-transfer/client/rest/tx.go +++ b/x/ibc/20-transfer/client/rest/tx.go @@ -60,7 +60,6 @@ func transferHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { req.Amount, fromAddr, req.Receiver, - req.Source, ) if err := msg.ValidateBasic(); err != nil { diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 98916ed856a7..5f88ae9fa668 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -35,7 +35,7 @@ func NewHandler(k Keeper) sdk.Handler { // See createOutgoingPacket in spec:https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) { if err := k.SendTransfer( - ctx, msg.SourcePort, msg.SourceChannel, msg.DestHeight, msg.Amount, msg.Sender, msg.Receiver, msg.Source, + ctx, msg.SourcePort, msg.SourceChannel, msg.DestHeight, msg.Amount, msg.Sender, msg.Receiver, ); err != nil { return nil, err } diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index d27430029f7d..15b9f3b847ae 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -89,12 +89,10 @@ func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitmenttypes.Mer } func (suite *HandlerTestSuite) TestHandleMsgTransfer() { - source := true - handler := transfer.NewHandler(suite.chainA.App.TransferKeeper) ctx := suite.chainA.GetContext() - msg := transfer.NewMsgTransfer(testPort1, testChannel1, 10, testCoins, testAddr1, testAddr2, source) + msg := transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2) res, err := handler(ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // channel does not exist @@ -120,16 +118,14 @@ func (suite *HandlerTestSuite) TestHandleMsgTransfer() { suite.Require().NotNil(res, "%+v", res) // successfully executed // test when the source is false - source = false - - msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2, source) + msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2) _ = suite.chainA.App.BankKeeper.SetBalances(ctx, testAddr1, testPrefixedCoins2) res, err = handler(ctx, msg) suite.Require().Error(err) suite.Require().Nil(res, "%+v", res) // incorrect denom prefix - msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins1, testAddr1, testAddr2, source) + msg = transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins1, testAddr1, testAddr2) suite.chainA.App.SupplyKeeper.SetSupply(ctx, supply.NewSupply(testPrefixedCoins1)) _ = suite.chainA.App.BankKeeper.SetBalances(ctx, testAddr1, testPrefixedCoins1) diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index 6f13b0d43189..342bca5563cb 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -27,7 +27,6 @@ func (k Keeper) SendTransfer( amount sdk.Coins, sender, receiver sdk.AccAddress, - isSourceChain bool, // is the packet sender the source chain of the token? ) error { sourceChannelEnd, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) if !found { @@ -43,7 +42,7 @@ func (k Keeper) SendTransfer( return channel.ErrSequenceSendNotFound } - return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, destHeight, amount, sender, receiver, isSourceChain) + return k.createOutgoingPacket(ctx, sequence, sourcePort, sourceChannel, destinationPort, destinationChannel, destHeight, amount, sender, receiver) } // ReceiveTransfer handles transfer receiving logic. @@ -65,7 +64,6 @@ func (k Keeper) createOutgoingPacket( destHeight uint64, amount sdk.Coins, sender, receiver sdk.AccAddress, - isSourceChain bool, ) error { // NOTE: // - Coins transferred from the destination chain should have their denomination @@ -74,12 +72,16 @@ func (k Keeper) createOutgoingPacket( // clear from prefixes when transferred to the escrow account (i.e when they are // locked) BUT MUST have the destination port and channel ID when constructing // the packet data. - var prefix string + if len(amount) != 1 { + return sdkerrors.Wrapf(types.ErrOnlyOneDenomAllowed, "%d denoms included", len(amount)) + } + + prefix := types.GetDenomPrefix(destinationPort, destinationChannel) + source := strings.HasPrefix(amount[0].Denom, prefix) - if isSourceChain { + if source { // clear the denomination from the prefix to send the coins to the escrow account coins := make(sdk.Coins, len(amount)) - prefix = types.GetDenomPrefix(destinationPort, destinationChannel) for i, coin := range amount { if strings.HasPrefix(coin.Denom, prefix) { coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) @@ -101,9 +103,9 @@ func (k Keeper) createOutgoingPacket( } else { // build the receiving denomination prefix if it's not present prefix = types.GetDenomPrefix(sourcePort, sourceChannel) - for i, coin := range amount { + for _, coin := range amount { if !strings.HasPrefix(coin.Denom, prefix) { - amount[i] = sdk.NewCoin(prefix+coin.Denom, coin.Amount) + return sdkerrors.Wrapf(types.ErrInvalidDenomForTransfer, "denom was: %s", coin.Denom) } } @@ -126,7 +128,7 @@ func (k Keeper) createOutgoingPacket( } packetData := types.NewFungibleTokenPacketData( - amount, sender, receiver, isSourceChain, + amount, sender, receiver, ) packet := channel.NewPacket( @@ -145,17 +147,14 @@ func (k Keeper) createOutgoingPacket( func (k Keeper) onRecvPacket(ctx sdk.Context, packet channel.Packet, data types.FungibleTokenPacketData) error { // NOTE: packet data type already checked in handler.go - if data.Source { - prefix := types.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel()) - for _, coin := range data.Amount { - if !strings.HasPrefix(coin.Denom, prefix) { - return sdkerrors.Wrapf( - sdkerrors.ErrInvalidCoins, - "%s doesn't contain the prefix '%s'", coin.Denom, prefix, - ) - } - } + if len(data.Amount) != 1 { + return sdkerrors.Wrapf(types.ErrOnlyOneDenomAllowed, "%d denoms included", len(data.Amount)) + } + prefix := types.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel()) + source := strings.HasPrefix(data.Amount[0].Denom, prefix) + + if source { // mint new tokens if the source of the transfer is the same chain if err := k.supplyKeeper.MintCoins( ctx, types.GetModuleAccountName(), data.Amount, @@ -170,7 +169,7 @@ func (k Keeper) onRecvPacket(ctx sdk.Context, packet channel.Packet, data types. } // check the denom prefix - prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) + prefix = types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) coins := make(sdk.Coins, len(data.Amount)) for i, coin := range data.Amount { if !strings.HasPrefix(coin.Denom, prefix) { @@ -190,19 +189,24 @@ func (k Keeper) onRecvPacket(ctx sdk.Context, packet channel.Packet, data types. func (k Keeper) onTimeoutPacket(ctx sdk.Context, packet channel.Packet, data types.FungibleTokenPacketData) error { // NOTE: packet data type already checked in handler.go + if len(data.Amount) != 1 { + return sdkerrors.Wrapf(types.ErrOnlyOneDenomAllowed, "%d denoms included", len(data.Amount)) + } + // check the denom prefix prefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) - coins := make(sdk.Coins, len(data.Amount)) + source := strings.HasPrefix(data.Amount[0].Denom, prefix) - for i, coin := range data.Amount { - coin := coin - if !strings.HasPrefix(coin.Denom, prefix) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "%s doesn't contain the prefix '%s'", coin.Denom, prefix) + if source { + coins := make(sdk.Coins, len(data.Amount)) + for i, coin := range data.Amount { + coin := coin + if !strings.HasPrefix(coin.Denom, prefix) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "%s doesn't contain the prefix '%s'", coin.Denom, prefix) + } + coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) } - coins[i] = sdk.NewCoin(coin.Denom[len(prefix):], coin.Amount) - } - if data.Source { // unescrow tokens back to sender escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) return k.bankKeeper.SendCoins(ctx, escrowAddress, data.Sender, coins) diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 7db510decfdf..2a4badc7d9cd 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -20,7 +20,7 @@ func (suite *KeeperTestSuite) TestSendTransfer() { isSourceChain bool expPass bool }{ - {"successful transfer from source chain", testCoins, + {"successful transfer from source chain", testCoins2, func() { suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), testAddr1, testCoins) suite.chainA.CreateClient(suite.chainB) @@ -28,16 +28,7 @@ func (suite *KeeperTestSuite) TestSendTransfer() { suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort1, testChannel1, 1) }, true, true}, - {"successful transfer from source chain with denom prefix", testCoins2, - func() { - _, err := suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), testAddr1, testCoins) - suite.Require().NoError(err) - suite.chainA.CreateClient(suite.chainB) - suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) - suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) - suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort1, testChannel1, 1) - }, true, true}, - {"successful transfer from external chain", testCoins, + {"successful transfer from external chain", prefixCoins, func() { suite.chainA.App.SupplyKeeper.SetSupply(suite.chainA.GetContext(), supply.NewSupply(prefixCoins)) _, err := suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), testAddr1, prefixCoins) @@ -82,7 +73,7 @@ func (suite *KeeperTestSuite) TestSendTransfer() { tc.malleate() err := suite.chainA.App.TransferKeeper.SendTransfer( - suite.chainA.GetContext(), testPort1, testChannel1, 100, tc.amount, testAddr1, testAddr2, tc.isSourceChain, + suite.chainA.GetContext(), testPort1, testChannel1, 100, tc.amount, testAddr1, testAddr2, ) if tc.expPass { @@ -95,7 +86,7 @@ func (suite *KeeperTestSuite) TestSendTransfer() { } func (suite *KeeperTestSuite) TestReceiveTransfer() { - data := types.NewFungibleTokenPacketData(prefixCoins2, testAddr1, testAddr2, true) + data := types.NewFungibleTokenPacketData(prefixCoins2, testAddr1, testAddr2) testCases := []struct { msg string @@ -112,19 +103,16 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { }, false}, {"mint failed", func() { - data.Source = true data.Amount = prefixCoins2 data.Amount[0].Amount = sdk.ZeroInt() }, false}, // - receiving chain {"incorrect dest prefix on coin denom", func() { - data.Source = false data.Amount = prefixCoins2 }, false}, {"success receive from external chain", func() { - data.Source = false data.Amount = prefixCoins escrow := types.GetEscrowAddress(testPort2, testChannel2) _, err := suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), escrow, testCoins) @@ -152,7 +140,8 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { } func (suite *KeeperTestSuite) TestTimeoutTransfer() { - data := types.NewFungibleTokenPacketData(prefixCoins, testAddr1, testAddr2, true) + data := types.NewFungibleTokenPacketData(prefixCoins, testAddr1, testAddr2) + testCoins2 := sdk.NewCoins(sdk.NewCoin("testportid/secondchannel/atom", sdk.NewInt(100))) testCases := []struct { msg string @@ -167,20 +156,17 @@ func (suite *KeeperTestSuite) TestTimeoutTransfer() { }, true}, {"successful timeout from external chain", func() { - data.Source = false + data.Amount = testCoins2 }, true}, {"no source prefix on coin denom", func() { - data.Source = true data.Amount = prefixCoins2 }, false}, {"unescrow failed", func() { - data.Source = true }, false}, {"mint failed", func() { - data.Source = false data.Amount[0].Denom = prefixCoins[0].Denom data.Amount[0].Amount = sdk.ZeroInt() }, false}, diff --git a/x/ibc/20-transfer/types/errors.go b/x/ibc/20-transfer/types/errors.go index c0f40d1171b9..e46c023e4cb7 100644 --- a/x/ibc/20-transfer/types/errors.go +++ b/x/ibc/20-transfer/types/errors.go @@ -6,5 +6,7 @@ import ( // IBC channel sentinel errors var ( - ErrInvalidPacketTimeout = sdkerrors.Register(ModuleName, 1, "invalid packet timeout") + ErrInvalidPacketTimeout = sdkerrors.Register(ModuleName, 2, "invalid packet timeout") + ErrOnlyOneDenomAllowed = sdkerrors.Register(ModuleName, 3, "only one denom allowed") + ErrInvalidDenomForTransfer = sdkerrors.Register(ModuleName, 4, "invalid denomination for cross-chain transfer") ) diff --git a/x/ibc/20-transfer/types/msgs.go b/x/ibc/20-transfer/types/msgs.go index f017c1a0dfe7..b7ae7cb7c764 100644 --- a/x/ibc/20-transfer/types/msgs.go +++ b/x/ibc/20-transfer/types/msgs.go @@ -15,12 +15,11 @@ type MsgTransfer struct { Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain - Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred } // NewMsgTransfer creates a new MsgTransfer instance func NewMsgTransfer( - sourcePort, sourceChannel string, destHeight uint64, amount sdk.Coins, sender, receiver sdk.AccAddress, source bool, + sourcePort, sourceChannel string, destHeight uint64, amount sdk.Coins, sender, receiver sdk.AccAddress, ) MsgTransfer { return MsgTransfer{ SourcePort: sourcePort, @@ -29,7 +28,6 @@ func NewMsgTransfer( Amount: amount, Sender: sender, Receiver: receiver, - Source: source, } } diff --git a/x/ibc/20-transfer/types/msgs_test.go b/x/ibc/20-transfer/types/msgs_test.go index febb4f0df29a..1b00732d4045 100644 --- a/x/ibc/20-transfer/types/msgs_test.go +++ b/x/ibc/20-transfer/types/msgs_test.go @@ -34,14 +34,14 @@ var ( // TestMsgTransferRoute tests Route for MsgTransfer func TestMsgTransferRoute(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true) + msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2) require.Equal(t, RouterKey, msg.Route()) } // TestMsgTransferType tests Type for MsgTransfer func TestMsgTransferType(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true) + msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2) require.Equal(t, "transfer", msg.Type()) } @@ -49,18 +49,18 @@ func TestMsgTransferType(t *testing.T) { // TestMsgTransferValidation tests ValidateBasic for MsgTransfer func TestMsgTransferValidation(t *testing.T) { testMsgs := []MsgTransfer{ - NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true), // valid msg - NewMsgTransfer(invalidShortPort, validChannel, 10, coins, addr1, addr2, true), // too short port id - NewMsgTransfer(invalidLongPort, validChannel, 10, coins, addr1, addr2, true), // too long port id - NewMsgTransfer(invalidPort, validChannel, 10, coins, addr1, addr2, true), // port id contains non-alpha - NewMsgTransfer(validPort, invalidShortChannel, 10, coins, addr1, addr2, true), // too short channel id - NewMsgTransfer(validPort, invalidLongChannel, 10, coins, addr1, addr2, false), // too long channel id - NewMsgTransfer(validPort, invalidChannel, 10, coins, addr1, addr2, false), // channel id contains non-alpha - NewMsgTransfer(validPort, validChannel, 10, invalidDenomCoins, addr1, addr2, false), // invalid amount - NewMsgTransfer(validPort, validChannel, 10, negativeCoins, addr1, addr2, false), // amount contains negative coin - NewMsgTransfer(validPort, validChannel, 10, coins, emptyAddr, addr2, false), // missing sender address - NewMsgTransfer(validPort, validChannel, 10, coins, addr1, emptyAddr, false), // missing recipient address - NewMsgTransfer(validPort, validChannel, 10, sdk.Coins{}, addr1, addr2, false), // not possitive coin + NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2), // valid msg + NewMsgTransfer(invalidShortPort, validChannel, 10, coins, addr1, addr2), // too short port id + NewMsgTransfer(invalidLongPort, validChannel, 10, coins, addr1, addr2), // too long port id + NewMsgTransfer(invalidPort, validChannel, 10, coins, addr1, addr2), // port id contains non-alpha + NewMsgTransfer(validPort, invalidShortChannel, 10, coins, addr1, addr2), // too short channel id + NewMsgTransfer(validPort, invalidLongChannel, 10, coins, addr1, addr2), // too long channel id + NewMsgTransfer(validPort, invalidChannel, 10, coins, addr1, addr2), // channel id contains non-alpha + NewMsgTransfer(validPort, validChannel, 10, invalidDenomCoins, addr1, addr2), // invalid amount + NewMsgTransfer(validPort, validChannel, 10, negativeCoins, addr1, addr2), // amount contains negative coin + NewMsgTransfer(validPort, validChannel, 10, coins, emptyAddr, addr2), // missing sender address + NewMsgTransfer(validPort, validChannel, 10, coins, addr1, emptyAddr), // missing recipient address + NewMsgTransfer(validPort, validChannel, 10, sdk.Coins{}, addr1, addr2), // not possitive coin } testCases := []struct { @@ -93,16 +93,16 @@ func TestMsgTransferValidation(t *testing.T) { // TestMsgTransferGetSignBytes tests GetSignBytes for MsgTransfer func TestMsgTransferGetSignBytes(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true) + msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2) res := msg.GetSignBytes() - expected := `{"type":"ibc/transfer/MsgTransfer","value":{"amount":[{"amount":"100","denom":"atom"}],"dest_height":"10","receiver":"cosmos1w3jhxarpv3j8yvs7f9y7g","sender":"cosmos1w3jhxarpv3j8yvg4ufs4x","source":true,"source_channel":"testchannel","source_port":"testportid"}}` + expected := `{"type":"ibc/transfer/MsgTransfer","value":{"amount":[{"amount":"100","denom":"atom"}],"dest_height":"10","receiver":"cosmos1w3jhxarpv3j8yvs7f9y7g","sender":"cosmos1w3jhxarpv3j8yvg4ufs4x","source_channel":"testchannel","source_port":"testportid"}}` require.Equal(t, expected, string(res)) } // TestMsgTransferGetSigners tests GetSigners for MsgTransfer func TestMsgTransferGetSigners(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2, true) + msg := NewMsgTransfer(validPort, validChannel, 10, coins, addr1, addr2) res := msg.GetSigners() expected := "[746573746164647231]" diff --git a/x/ibc/20-transfer/types/packet.go b/x/ibc/20-transfer/types/packet.go index acb50b4e4a23..9cb6d1b8122e 100644 --- a/x/ibc/20-transfer/types/packet.go +++ b/x/ibc/20-transfer/types/packet.go @@ -13,18 +13,15 @@ type FungibleTokenPacketData struct { Amount sdk.Coins `json:"amount" yaml:"amount"` // the tokens to be transferred Sender sdk.AccAddress `json:"sender" yaml:"sender"` // the sender address Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"` // the recipient address on the destination chain - Source bool `json:"source" yaml:"source"` // indicates if the sending chain is the source chain of the tokens to be transferred } // NewFungibleTokenPacketData contructs a new FungibleTokenPacketData instance func NewFungibleTokenPacketData( - amount sdk.Coins, sender, receiver sdk.AccAddress, - source bool) FungibleTokenPacketData { + amount sdk.Coins, sender, receiver sdk.AccAddress) FungibleTokenPacketData { return FungibleTokenPacketData{ Amount: amount, Sender: sender, Receiver: receiver, - Source: source, } } @@ -33,12 +30,10 @@ func (ftpd FungibleTokenPacketData) String() string { return fmt.Sprintf(`FungibleTokenPacketData: Amount: %s Sender: %s - Receiver: %s - Source: %v`, + Receiver: %s`, ftpd.Amount.String(), ftpd.Sender, ftpd.Receiver, - ftpd.Source, ) } diff --git a/x/ibc/20-transfer/types/packet_test.go b/x/ibc/20-transfer/types/packet_test.go index 2f82a33c779b..e2e4f2cc1600 100644 --- a/x/ibc/20-transfer/types/packet_test.go +++ b/x/ibc/20-transfer/types/packet_test.go @@ -9,11 +9,11 @@ import ( // TestFungibleTokenPacketDataValidateBasic tests ValidateBasic for FungibleTokenPacketData func TestFungibleTokenPacketDataValidateBasic(t *testing.T) { testPacketDataTransfer := []FungibleTokenPacketData{ - NewFungibleTokenPacketData(coins, addr1, addr2, true), // valid msg - NewFungibleTokenPacketData(invalidDenomCoins, addr1, addr2, true), // invalid amount - NewFungibleTokenPacketData(negativeCoins, addr1, addr2, false), // amount contains negative coin - NewFungibleTokenPacketData(coins, emptyAddr, addr2, false), // missing sender address - NewFungibleTokenPacketData(coins, addr1, emptyAddr, false), // missing recipient address + NewFungibleTokenPacketData(coins, addr1, addr2), // valid msg + NewFungibleTokenPacketData(invalidDenomCoins, addr1, addr2), // invalid amount + NewFungibleTokenPacketData(negativeCoins, addr1, addr2), // amount contains negative coin + NewFungibleTokenPacketData(coins, emptyAddr, addr2), // missing sender address + NewFungibleTokenPacketData(coins, addr1, emptyAddr), // missing recipient address } testCases := []struct { From 8927822f75d28187ad03f90a848c7f97533c821b Mon Sep 17 00:00:00 2001 From: Segue Date: Fri, 3 Apr 2020 20:36:24 +0800 Subject: [PATCH 159/176] fix ics20 client args (#5924) --- x/ibc/20-transfer/client/cli/tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/ibc/20-transfer/client/cli/tx.go b/x/ibc/20-transfer/client/cli/tx.go index 1cf9553cb59c..d249a881809b 100644 --- a/x/ibc/20-transfer/client/cli/tx.go +++ b/x/ibc/20-transfer/client/cli/tx.go @@ -31,7 +31,7 @@ func GetTransferTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "transfer [src-port] [src-channel] [dest-height] [receiver] [amount]", Short: "Transfer fungible token through IBC", - Args: cobra.ExactArgs(4), + Args: cobra.ExactArgs(5), RunE: func(cmd *cobra.Command, args []string) error { inBuf := bufio.NewReader(cmd.InOrStdin()) txBldr := authtypes.NewTxBuilderFromCLI(inBuf).WithTxEncoder(authclient.GetTxEncoder(cdc)) From 6c289546136ce41d3e4e607b384278c796a78321 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Fri, 3 Apr 2020 09:50:32 -0700 Subject: [PATCH 160/176] Merge PR #5930: Add GetChainID to ClientState interface --- x/ibc/02-client/exported/exported.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index aeb861db3de8..83ca5be502c0 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -16,6 +16,7 @@ import ( // ClientState defines the required common functions for light clients. type ClientState interface { GetID() string + GetChainID() string ClientType() ClientType GetLatestHeight() uint64 IsFrozen() bool From 60bf21f2efd90cb08322eaa091383b009223d3f1 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 6 Apr 2020 11:29:43 +0200 Subject: [PATCH 161/176] Merge PR #5925: Add additional events to x/ibc --- x/ibc/04-channel/keeper/packet.go | 54 ++++++++++++++++++++++++++++-- x/ibc/04-channel/keeper/timeout.go | 31 +++++++++++++++++ x/ibc/04-channel/types/events.go | 7 +++- 3 files changed, 88 insertions(+), 4 deletions(-) diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index b7e1e1c42036..0978bb64b361 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -117,7 +117,7 @@ func (k Keeper) SendPacket( ), }) - k.Logger(ctx).Info(fmt.Sprintf("packet sent %v", packet)) // TODO: use packet.String() + k.Logger(ctx).Info(fmt.Sprintf("packet sent: %v", packet)) return nil } @@ -233,8 +233,23 @@ func (k Keeper) PacketExecuted( k.SetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv) } - // log that a packet has been received & acknowledged - k.Logger(ctx).Info(fmt.Sprintf("packet received %v", packet)) // TODO: use packet.String() + // log that a packet has been received & executed + k.Logger(ctx).Info(fmt.Sprintf("packet received & executed: %v", packet)) + + // emit an event that the relayer can query for + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeRecvPacket, + sdk.NewAttribute(types.AttributeKeyData, string(acknowledgement)), + sdk.NewAttribute(types.AttributeKeyTimeout, fmt.Sprintf("%d", packet.GetTimeoutHeight())), + sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())), + sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()), + sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()), + sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()), + sdk.NewAttribute(types.AttributeKeyDstChannel, packet.GetDestChannel()), + ), + }) + return nil } @@ -306,6 +321,22 @@ func (k Keeper) AcknowledgePacket( return nil, sdkerrors.Wrap(err, "invalid acknowledgement on counterparty chain") } + // log that a packet has been acknowledged + k.Logger(ctx).Info(fmt.Sprintf("packet acknowledged: %v", packet)) + + // emit an event marking that we have processed the acknowledgement + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeAcknowledgePacket, + sdk.NewAttribute(types.AttributeKeyTimeout, fmt.Sprintf("%d", packet.GetTimeoutHeight())), + sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())), + sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()), + sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()), + sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()), + sdk.NewAttribute(types.AttributeKeyDstChannel, packet.GetDestChannel()), + ), + }) + return packet, nil } @@ -404,5 +435,22 @@ func (k Keeper) CleanupPacket( } k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + // log that a packet has been acknowledged + k.Logger(ctx).Info(fmt.Sprintf("packet cleaned-up: %v", packet)) + + // emit an event marking that we have cleaned up the packet + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeCleanupPacket, + sdk.NewAttribute(types.AttributeKeyTimeout, fmt.Sprintf("%d", packet.GetTimeoutHeight())), + sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())), + sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()), + sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()), + sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()), + sdk.NewAttribute(types.AttributeKeyDstChannel, packet.GetDestChannel()), + ), + }) + return packet, nil } diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index 204f4c91c1ca..9917446131e9 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -2,6 +2,7 @@ package keeper import ( "bytes" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -101,6 +102,21 @@ func (k Keeper) TimeoutPacket( return nil, err } + k.Logger(ctx).Info(fmt.Sprintf("packet timed-out: %v", packet)) + + // emit an event marking that we have processed the timeout + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeTimeoutPacket, + sdk.NewAttribute(types.AttributeKeyTimeout, fmt.Sprintf("%d", packet.GetTimeoutHeight())), + sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())), + sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()), + sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()), + sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()), + sdk.NewAttribute(types.AttributeKeyDstChannel, packet.GetDestChannel()), + ), + }) + // NOTE: the remaining code is located on the TimeoutExecuted function return packet, nil } @@ -225,5 +241,20 @@ func (k Keeper) TimeoutOnClose( k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + k.Logger(ctx).Info(fmt.Sprintf("packet timed-out on close: %v", packet)) + + // emit an event marking that we have processed the timeout + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeTimeoutPacket, + sdk.NewAttribute(types.AttributeKeyTimeout, fmt.Sprintf("%d", packet.GetTimeoutHeight())), + sdk.NewAttribute(types.AttributeKeySequence, fmt.Sprintf("%d", packet.GetSequence())), + sdk.NewAttribute(types.AttributeKeySrcPort, packet.GetSourcePort()), + sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()), + sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()), + sdk.NewAttribute(types.AttributeKeyDstChannel, packet.GetDestChannel()), + ), + }) + return packet, nil } diff --git a/x/ibc/04-channel/types/events.go b/x/ibc/04-channel/types/events.go index 3c20b4195bfc..6896b225b142 100644 --- a/x/ibc/04-channel/types/events.go +++ b/x/ibc/04-channel/types/events.go @@ -14,7 +14,12 @@ const ( AttributeCounterpartyPortID = "counterparty_port_id" AttributeCounterpartyChannelID = "counterparty_channel_id" - EventTypeSendPacket = "send_packet" + EventTypeSendPacket = "send_packet" + EventTypeRecvPacket = "recv_packet" + EventTypeAcknowledgePacket = "acknowledge_packet" + EventTypeCleanupPacket = "cleanup_packet" + EventTypeTimeoutPacket = "timeout_packet" + AttributeKeyData = "packet_data" AttributeKeyTimeout = "packet_timeout" AttributeKeySequence = "packet_sequence" From 52206f46ed466c36a7f16507c12780db7851b3a3 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 6 Apr 2020 09:59:11 -0400 Subject: [PATCH 162/176] Migrate x/capability to Protobuf (#5926) * migrate x/capability to protobuf * fixes * format * remove capability from codec std * return pointer for getOwners * remove & * Update x/capability/keeper/keeper.go Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * rename remove Capability interface; rename CapabilityKey -> Capaility; cc @cwgoes * x/capability: remove RegisterCapabilityTypeCodec and seal amino cdc Co-authored-by: Alexander Bezobchuk Co-authored-by: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> --- simapp/app.go | 2 +- x/capability/alias.go | 30 +- x/capability/keeper/keeper.go | 34 +- x/capability/keeper/keeper_test.go | 10 +- x/capability/types/codec.go | 26 +- x/capability/types/keys.go | 2 +- x/capability/types/keys_test.go | 2 +- x/capability/types/store.go | 14 +- x/capability/types/types.go | 47 +- x/capability/types/types.pb.go | 710 +++++++++++++++++++++++++++++ x/capability/types/types.proto | 33 ++ x/capability/types/types_test.go | 4 +- x/staking/types/types.pb.go | 9 +- 13 files changed, 819 insertions(+), 104 deletions(-) create mode 100644 x/capability/types/types.pb.go create mode 100644 x/capability/types/types.proto diff --git a/simapp/app.go b/simapp/app.go index 1e2427d9d657..efcb16e14441 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -180,7 +180,7 @@ func NewSimApp( app.BankKeeper = bank.NewBaseKeeper( appCodec, keys[bank.StoreKey], app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(), ) - app.CapabilityKeeper = capability.NewKeeper(app.cdc, keys[capability.StoreKey]) + app.CapabilityKeeper = capability.NewKeeper(appCodec, keys[capability.StoreKey]) app.SupplyKeeper = supply.NewKeeper( appCodec, keys[supply.StoreKey], app.AccountKeeper, app.BankKeeper, maccPerms, ) diff --git a/x/capability/alias.go b/x/capability/alias.go index c3c8366c61db..3c7b743d9fbb 100644 --- a/x/capability/alias.go +++ b/x/capability/alias.go @@ -16,21 +16,20 @@ const ( // nolint var ( - NewKeeper = keeper.NewKeeper - NewCapabilityKey = types.NewCapabilityKey - RevCapabilityKey = types.RevCapabilityKey - FwdCapabilityKey = types.FwdCapabilityKey - KeyIndex = types.KeyIndex - KeyPrefixIndexCapability = types.KeyPrefixIndexCapability - ErrCapabilityTaken = types.ErrCapabilityTaken - ErrOwnerClaimed = types.ErrOwnerClaimed - ErrCapabilityNotOwned = types.ErrCapabilityNotOwned - RegisterCodec = types.RegisterCodec - RegisterCapabilityTypeCodec = types.RegisterCapabilityTypeCodec - ModuleCdc = types.ModuleCdc - NewOwner = types.NewOwner - NewCapabilityOwners = types.NewCapabilityOwners - NewCapabilityStore = types.NewCapabilityStore + NewKeeper = keeper.NewKeeper + NewCapability = types.NewCapability + RevCapabilityKey = types.RevCapabilityKey + FwdCapabilityKey = types.FwdCapabilityKey + KeyIndex = types.KeyIndex + KeyPrefixIndexCapability = types.KeyPrefixIndexCapability + ErrCapabilityTaken = types.ErrCapabilityTaken + ErrOwnerClaimed = types.ErrOwnerClaimed + ErrCapabilityNotOwned = types.ErrCapabilityNotOwned + RegisterCodec = types.RegisterCodec + ModuleCdc = types.ModuleCdc + NewOwner = types.NewOwner + NewCapabilityOwners = types.NewCapabilityOwners + NewCapabilityStore = types.NewCapabilityStore ) // nolint @@ -38,7 +37,6 @@ type ( Keeper = keeper.Keeper ScopedKeeper = keeper.ScopedKeeper Capability = types.Capability - CapabilityKey = types.CapabilityKey CapabilityOwners = types.CapabilityOwners CapabilityStore = types.CapabilityStore ) diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 50d03e06d5d4..61ddd456939e 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -26,7 +26,7 @@ type ( // The keeper allows the ability to create scoped sub-keepers which are tied to // a single specific module. Keeper struct { - cdc *codec.Codec + cdc codec.Marshaler storeKey sdk.StoreKey capStore types.CapabilityStore scopedModules map[string]struct{} @@ -40,14 +40,14 @@ type ( // by name, in addition to creating new capabilities & authenticating capabilities // passed by other modules. ScopedKeeper struct { - cdc *codec.Codec + cdc codec.Marshaler storeKey sdk.StoreKey capStore types.CapabilityStore // shared amongst all scoped keepers module string } ) -func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey) *Keeper { +func NewKeeper(cdc codec.Marshaler, storeKey sdk.StoreKey) *Keeper { return &Keeper{ cdc: cdc, storeKey: storeKey, @@ -95,9 +95,9 @@ func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { defer iterator.Close() for ; iterator.Valid(); iterator.Next() { index := types.IndexFromKey(iterator.Key()) - cap := types.NewCapabilityKey(index) + cap := types.NewCapability(index) - var capOwners *types.CapabilityOwners + var capOwners types.CapabilityOwners k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &capOwners) for _, owner := range capOwners.Owners { @@ -123,7 +123,7 @@ func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { // // Note, namespacing is completely local, which is safe since records are prefixed // with the module name and no two ScopedKeeper can have the same module name. -func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capability, error) { +func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (*types.Capability, error) { store := ctx.KVStore(sk.storeKey) if cap := sk.capStore.GetCapability(sk.module, name); cap != nil { @@ -133,7 +133,7 @@ func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capabi // create new capability with the current global index index := types.IndexFromKey(store.Get(types.KeyIndex)) - cap := types.NewCapabilityKey(index) + cap := types.NewCapability(index) // update capability owner set if err := sk.addOwner(ctx, cap, name); err != nil { @@ -163,7 +163,7 @@ func (sk ScopedKeeper) NewCapability(ctx sdk.Context, name string) (types.Capabi // // Note, the capability's forward mapping is indexed by a string which should // contain its unique memory reference. -func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap types.Capability, name string) bool { +func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap *types.Capability, name string) bool { return sk.capStore.GetCapabilityName(sk.module, cap) == name } @@ -172,7 +172,7 @@ func (sk ScopedKeeper) AuthenticateCapability(ctx sdk.Context, cap types.Capabil // to add the owner to the persistent set of capability owners for the capability // index. If the owner already exists, it will return an error. Otherwise, it will // also set a forward and reverse index for the capability and capability name. -func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, name string) error { +func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap *types.Capability, name string) error { // update capability owner set if err := sk.addOwner(ctx, cap, name); err != nil { return err @@ -193,7 +193,7 @@ func (sk ScopedKeeper) ClaimCapability(ctx sdk.Context, cap types.Capability, na // ReleaseCapability allows a scoped module to release a capability which it had // previously claimed or created. After releasing the capability, if no more // owners exist, the capability will be globally removed. -func (sk ScopedKeeper) ReleaseCapability(ctx sdk.Context, cap types.Capability) error { +func (sk ScopedKeeper) ReleaseCapability(ctx sdk.Context, cap *types.Capability) error { name := sk.capStore.GetCapabilityName(sk.module, cap) if len(name) == 0 { return sdkerrors.Wrap(types.ErrCapabilityNotOwned, sk.module) @@ -228,7 +228,7 @@ func (sk ScopedKeeper) ReleaseCapability(ctx sdk.Context, cap types.Capability) // GetCapability allows a module to fetch a capability which it previously claimed // by name. The module is not allowed to retrieve capabilities which it does not // own. -func (sk ScopedKeeper) GetCapability(ctx sdk.Context, name string) (types.Capability, bool) { +func (sk ScopedKeeper) GetCapability(ctx sdk.Context, name string) (*types.Capability, bool) { cap := sk.capStore.GetCapability(sk.module, name) if cap == nil { return nil, false @@ -237,7 +237,7 @@ func (sk ScopedKeeper) GetCapability(ctx sdk.Context, name string) (types.Capabi return cap, true } -func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap types.Capability, name string) error { +func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap *types.Capability, name string) error { prefixStore := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) indexKey := types.IndexToKey(cap.GetIndex()) @@ -252,18 +252,22 @@ func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap types.Capability, name stri return nil } -func (sk ScopedKeeper) getOwners(ctx sdk.Context, cap types.Capability) (capOwners *types.CapabilityOwners) { +func (sk ScopedKeeper) getOwners(ctx sdk.Context, cap *types.Capability) *types.CapabilityOwners { prefixStore := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) indexKey := types.IndexToKey(cap.GetIndex()) bz := prefixStore.Get(indexKey) + + var owners *types.CapabilityOwners if len(bz) == 0 { - capOwners = types.NewCapabilityOwners() + owners = types.NewCapabilityOwners() } else { + var capOwners types.CapabilityOwners sk.cdc.MustUnmarshalBinaryBare(bz, &capOwners) + owners = &capOwners } - return capOwners + return owners } func logger(ctx sdk.Context) log.Logger { diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index 02440d3f8f19..b4911438d3db 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank" @@ -27,9 +28,10 @@ type KeeperTestSuite struct { func (suite *KeeperTestSuite) SetupTest() { checkTx := false app := simapp.Setup(checkTx) + cdc := codec.NewHybridCodec(app.Codec()) // create new keeper so we can define custom scoping before init and seal - keeper := keeper.NewKeeper(app.Codec(), app.GetKey(capability.StoreKey)) + keeper := keeper.NewKeeper(cdc, app.GetKey(capability.StoreKey)) suite.ctx = app.BaseApp.NewContext(checkTx, abci.Header{Height: 1}) suite.keeper = keeper @@ -39,7 +41,7 @@ func (suite *KeeperTestSuite) SetupTest() { func (suite *KeeperTestSuite) TestInitializeAndSeal() { sk := suite.keeper.ScopeToModule(bank.ModuleName) - caps := make([]types.Capability, 5) + caps := make([]*types.Capability, 5) for i := range caps { cap, err := sk.NewCapability(suite.ctx, fmt.Sprintf("transfer-%d", i)) @@ -99,7 +101,7 @@ func (suite *KeeperTestSuite) TestAuthenticateCapability() { suite.Require().NoError(err) suite.Require().NotNil(cap1) - forgedCap := types.NewCapabilityKey(0) // index should be the same index as the first capability + forgedCap := types.NewCapability(0) // index should be the same index as the first capability suite.Require().False(sk2.AuthenticateCapability(suite.ctx, forgedCap, "transfer")) cap2, err := sk2.NewCapability(suite.ctx, "bond") @@ -117,7 +119,7 @@ func (suite *KeeperTestSuite) TestAuthenticateCapability() { sk2.ReleaseCapability(suite.ctx, cap2) suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap2, "bond")) - badCap := types.NewCapabilityKey(100) + badCap := types.NewCapability(100) suite.Require().False(sk1.AuthenticateCapability(suite.ctx, badCap, "transfer")) suite.Require().False(sk2.AuthenticateCapability(suite.ctx, badCap, "bond")) } diff --git a/x/capability/types/codec.go b/x/capability/types/codec.go index 7b483557f2ae..c12a54b6fb6a 100644 --- a/x/capability/types/codec.go +++ b/x/capability/types/codec.go @@ -4,25 +4,27 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ) -// ModuleCdc defines the capability module's codec. The codec is not sealed as to -// allow other modules to register their concrete Capability types. -var ModuleCdc = codec.New() - // RegisterCodec registers all the necessary types and interfaces for the // capability module. func RegisterCodec(cdc *codec.Codec) { - cdc.RegisterInterface((*Capability)(nil), nil) - cdc.RegisterConcrete(&CapabilityKey{}, "cosmos-sdk/CapabilityKey", nil) + cdc.RegisterConcrete(&Capability{}, "cosmos-sdk/Capability", nil) cdc.RegisterConcrete(Owner{}, "cosmos-sdk/Owner", nil) cdc.RegisterConcrete(&CapabilityOwners{}, "cosmos-sdk/CapabilityOwners", nil) } -// RegisterCapabilityTypeCodec registers an external concrete Capability type -// defined in another module for the internal ModuleCdc. -func RegisterCapabilityTypeCodec(o interface{}, name string) { - ModuleCdc.RegisterConcrete(o, name, nil) -} +var ( + amino = codec.New() + + // ModuleCdc references the global x/capability module codec. Note, the codec should + // ONLY be used in certain instances of tests and for JSON encoding as Amino is + // still used for that purpose. + // + // The actual codec used for serialization should be provided to x/capability and + // defined at the application level. + ModuleCdc = codec.NewHybridCodec(amino) +) func init() { - RegisterCodec(ModuleCdc) + RegisterCodec(amino) + amino.Seal() } diff --git a/x/capability/types/keys.go b/x/capability/types/keys.go index 76726015246b..5f171e28a7f4 100644 --- a/x/capability/types/keys.go +++ b/x/capability/types/keys.go @@ -35,7 +35,7 @@ func RevCapabilityKey(module, name string) []byte { // FwdCapabilityKey returns a forward lookup key for a given module and capability // reference. -func FwdCapabilityKey(module string, cap Capability) []byte { +func FwdCapabilityKey(module string, cap *Capability) []byte { return []byte(fmt.Sprintf("%s/fwd/%p", module, cap)) } diff --git a/x/capability/types/keys_test.go b/x/capability/types/keys_test.go index fb380888e90f..e767c3d34222 100644 --- a/x/capability/types/keys_test.go +++ b/x/capability/types/keys_test.go @@ -15,7 +15,7 @@ func TestRevCapabilityKey(t *testing.T) { } func TestFwdCapabilityKey(t *testing.T) { - cap := types.NewCapabilityKey(23) + cap := types.NewCapability(23) expected := []byte(fmt.Sprintf("bank/fwd/%p", cap)) require.Equal(t, expected, types.FwdCapabilityKey("bank", cap)) } diff --git a/x/capability/types/store.go b/x/capability/types/store.go index e46bddbdc0d8..0354ca2b0ba4 100644 --- a/x/capability/types/store.go +++ b/x/capability/types/store.go @@ -2,41 +2,41 @@ package types // CapabilityStore defines an ephemeral in-memory object capability store. type CapabilityStore struct { - revMemStore map[string]Capability + revMemStore map[string]*Capability fwdMemStore map[string]string } func NewCapabilityStore() CapabilityStore { return CapabilityStore{ - revMemStore: make(map[string]Capability), + revMemStore: make(map[string]*Capability), fwdMemStore: make(map[string]string), } } // GetCapability returns a Capability by module and name tuple. If no Capability // exists, nil will be returned. -func (cs CapabilityStore) GetCapability(module, name string) Capability { +func (cs CapabilityStore) GetCapability(module, name string) *Capability { key := RevCapabilityKey(module, name) return cs.revMemStore[string(key)] } // GetCapabilityName returns a Capability name by module and Capability tuple. If // no Capability name exists for the given tuple, an empty string is returned. -func (cs CapabilityStore) GetCapabilityName(module string, cap Capability) string { +func (cs CapabilityStore) GetCapabilityName(module string, cap *Capability) string { key := FwdCapabilityKey(module, cap) return cs.fwdMemStore[string(key)] } // SetCapability sets the reverse mapping between the module and capability name // and the capability in the in-memory store. -func (cs CapabilityStore) SetCapability(module, name string, cap Capability) { +func (cs CapabilityStore) SetCapability(module, name string, cap *Capability) { key := RevCapabilityKey(module, name) cs.revMemStore[string(key)] = cap } // SetCapabilityName sets the forward mapping between the module and capability // tuple and the capability name in the in-memory store. -func (cs CapabilityStore) SetCapabilityName(module, name string, cap Capability) { +func (cs CapabilityStore) SetCapabilityName(module, name string, cap *Capability) { key := FwdCapabilityKey(module, cap) cs.fwdMemStore[string(key)] = name } @@ -50,7 +50,7 @@ func (cs CapabilityStore) DeleteCapability(module, name string) { // DeleteCapabilityName removes the forward mapping between the module and capability // tuple and the capability name in the in-memory store. -func (cs CapabilityStore) DeleteCapabilityName(module string, cap Capability) { +func (cs CapabilityStore) DeleteCapabilityName(module string, cap *Capability) { key := FwdCapabilityKey(module, cap) delete(cs.fwdMemStore, string(key)) } diff --git a/x/capability/types/types.go b/x/capability/types/types.go index 484abbff1dd0..e53efa5c4a1c 100644 --- a/x/capability/types/types.go +++ b/x/capability/types/types.go @@ -9,44 +9,17 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -var _ Capability = (*CapabilityKey)(nil) - -// Capability defines the interface a capability must implement. The given -// capability must provide a GUID. -type Capability interface { - GetIndex() uint64 - String() string -} - -// CapabilityKey defines an implementation of a Capability. The index provided to -// a CapabilityKey must be globally unique. -type CapabilityKey struct { - Index uint64 `json:"index" yaml:"index"` -} - -// NewCapabilityKey returns a reference to a new CapabilityKey to be used as an +// NewCapability returns a reference to a new Capability to be used as an // actual capability. -func NewCapabilityKey(index uint64) Capability { - return &CapabilityKey{Index: index} +func NewCapability(index uint64) *Capability { + return &Capability{Index: index} } -// GetIndex returns the capability key's index. -func (ck *CapabilityKey) GetIndex() uint64 { - return ck.Index -} - -// String returns the string representation of a CapabilityKey. The string contains -// the CapabilityKey's memory reference as the string is to be used in a composite +// String returns the string representation of a Capability. The string contains +// the Capability's memory reference as the string is to be used in a composite // key and to authenticate capabilities. -func (ck *CapabilityKey) String() string { - return fmt.Sprintf("CapabilityKey{%p, %d}", ck, ck.Index) -} - -// Owner defines a single capability owner. An owner is defined by the name of -// capability and the module name. -type Owner struct { - Module string `json:"module" yaml:"module"` - Name string `json:"name" yaml:"name"` +func (ck *Capability) String() string { + return fmt.Sprintf("Capability{%p, %d}", ck, ck.Index) } func NewOwner(module, name string) Owner { @@ -63,12 +36,6 @@ func (o Owner) String() string { return string(bz) } -// CapabilityOwners defines a set of owners of a single Capability. The set of -// owners must be unique. -type CapabilityOwners struct { - Owners []Owner `json:"owners" yaml:"owners"` -} - func NewCapabilityOwners() *CapabilityOwners { return &CapabilityOwners{Owners: make([]Owner, 0)} } diff --git a/x/capability/types/types.pb.go b/x/capability/types/types.pb.go new file mode 100644 index 000000000000..30edfedddac9 --- /dev/null +++ b/x/capability/types/types.pb.go @@ -0,0 +1,710 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: x/capability/types/types.proto + +package types + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Capability defines an implementation of an object capability. The index provided to +// a Capability must be globally unique. +type Capability struct { + Index uint64 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty" yaml:"index"` +} + +func (m *Capability) Reset() { *m = Capability{} } +func (*Capability) ProtoMessage() {} +func (*Capability) Descriptor() ([]byte, []int) { + return fileDescriptor_d73d5c48b3550cdd, []int{0} +} +func (m *Capability) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Capability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Capability.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Capability) XXX_Merge(src proto.Message) { + xxx_messageInfo_Capability.Merge(m, src) +} +func (m *Capability) XXX_Size() int { + return m.Size() +} +func (m *Capability) XXX_DiscardUnknown() { + xxx_messageInfo_Capability.DiscardUnknown(m) +} + +var xxx_messageInfo_Capability proto.InternalMessageInfo + +func (m *Capability) GetIndex() uint64 { + if m != nil { + return m.Index + } + return 0 +} + +// Owner defines a single capability owner. An owner is defined by the name of +// capability and the module name. +type Owner struct { + Module string `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty" yaml:"module"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` +} + +func (m *Owner) Reset() { *m = Owner{} } +func (*Owner) ProtoMessage() {} +func (*Owner) Descriptor() ([]byte, []int) { + return fileDescriptor_d73d5c48b3550cdd, []int{1} +} +func (m *Owner) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Owner) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Owner.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Owner) XXX_Merge(src proto.Message) { + xxx_messageInfo_Owner.Merge(m, src) +} +func (m *Owner) XXX_Size() int { + return m.Size() +} +func (m *Owner) XXX_DiscardUnknown() { + xxx_messageInfo_Owner.DiscardUnknown(m) +} + +var xxx_messageInfo_Owner proto.InternalMessageInfo + +// CapabilityOwners defines a set of owners of a single Capability. The set of +// owners must be unique. +type CapabilityOwners struct { + Owners []Owner `protobuf:"bytes,1,rep,name=owners,proto3" json:"owners"` +} + +func (m *CapabilityOwners) Reset() { *m = CapabilityOwners{} } +func (m *CapabilityOwners) String() string { return proto.CompactTextString(m) } +func (*CapabilityOwners) ProtoMessage() {} +func (*CapabilityOwners) Descriptor() ([]byte, []int) { + return fileDescriptor_d73d5c48b3550cdd, []int{2} +} +func (m *CapabilityOwners) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CapabilityOwners) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CapabilityOwners.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CapabilityOwners) XXX_Merge(src proto.Message) { + xxx_messageInfo_CapabilityOwners.Merge(m, src) +} +func (m *CapabilityOwners) XXX_Size() int { + return m.Size() +} +func (m *CapabilityOwners) XXX_DiscardUnknown() { + xxx_messageInfo_CapabilityOwners.DiscardUnknown(m) +} + +var xxx_messageInfo_CapabilityOwners proto.InternalMessageInfo + +func (m *CapabilityOwners) GetOwners() []Owner { + if m != nil { + return m.Owners + } + return nil +} + +func init() { + proto.RegisterType((*Capability)(nil), "cosmos_sdk.x.capability.v1.Capability") + proto.RegisterType((*Owner)(nil), "cosmos_sdk.x.capability.v1.Owner") + proto.RegisterType((*CapabilityOwners)(nil), "cosmos_sdk.x.capability.v1.CapabilityOwners") +} + +func init() { proto.RegisterFile("x/capability/types/types.proto", fileDescriptor_d73d5c48b3550cdd) } + +var fileDescriptor_d73d5c48b3550cdd = []byte{ + // 308 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xab, 0xd0, 0x4f, 0x4e, + 0x2c, 0x48, 0x4c, 0xca, 0xcc, 0xc9, 0x2c, 0xa9, 0xd4, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0x86, 0x90, + 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x52, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0xf1, 0xc5, + 0x29, 0xd9, 0x7a, 0x15, 0x7a, 0x08, 0xa5, 0x7a, 0x65, 0x86, 0x52, 0x6a, 0x25, 0x19, 0x99, 0x45, + 0x29, 0xf1, 0x05, 0x89, 0x45, 0x25, 0x95, 0xfa, 0x60, 0xe5, 0xfa, 0xe9, 0xf9, 0xe9, 0xf9, 0x08, + 0x16, 0xc4, 0x0c, 0x25, 0x2b, 0x2e, 0x2e, 0x67, 0xb8, 0x46, 0x21, 0x35, 0x2e, 0xd6, 0xcc, 0xbc, + 0x94, 0xd4, 0x0a, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x16, 0x27, 0x81, 0x4f, 0xf7, 0xe4, 0x79, 0x2a, + 0x13, 0x73, 0x73, 0xac, 0x94, 0xc0, 0xc2, 0x4a, 0x41, 0x10, 0x69, 0x2b, 0x96, 0x19, 0x0b, 0xe4, + 0x19, 0x94, 0x12, 0xb9, 0x58, 0xfd, 0xcb, 0xf3, 0x52, 0x8b, 0x84, 0x34, 0xb9, 0xd8, 0x72, 0xf3, + 0x53, 0x4a, 0x73, 0x52, 0xc1, 0xfa, 0x38, 0x9d, 0x04, 0x3f, 0xdd, 0x93, 0xe7, 0x85, 0xe8, 0x83, + 0x88, 0x2b, 0x05, 0x41, 0x15, 0x08, 0x29, 0x73, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x81, + 0x15, 0xf2, 0x7f, 0xba, 0x27, 0xcf, 0x0d, 0x51, 0x08, 0x12, 0x55, 0x0a, 0x02, 0x4b, 0x5a, 0x71, + 0x74, 0x2c, 0x90, 0x67, 0x00, 0x5b, 0x11, 0xcc, 0x25, 0x80, 0x70, 0x1e, 0xd8, 0xb2, 0x62, 0x21, + 0x7b, 0x2e, 0xb6, 0x7c, 0x30, 0x4b, 0x82, 0x51, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x51, 0x0f, 0x77, + 0x38, 0xe8, 0x81, 0xf5, 0x38, 0xb1, 0x9c, 0xb8, 0x27, 0xcf, 0x10, 0x04, 0xd5, 0xe6, 0xe4, 0x79, + 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, + 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xfa, 0xe9, 0x99, 0x25, 0x19, 0xa5, + 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x10, 0x43, 0xa1, 0x94, 0x6e, 0x71, 0x4a, 0xb6, 0x3e, 0x66, + 0x74, 0x24, 0xb1, 0x81, 0x43, 0xd1, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x14, 0xb2, 0xaf, + 0xab, 0x01, 0x00, 0x00, +} + +func (m *Capability) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Capability) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Capability) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Index != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Index)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Owner) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Owner) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Owner) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if len(m.Module) > 0 { + i -= len(m.Module) + copy(dAtA[i:], m.Module) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Module))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CapabilityOwners) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CapabilityOwners) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CapabilityOwners) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Owners) > 0 { + for iNdEx := len(m.Owners) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Owners[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { + offset -= sovTypes(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Capability) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Index != 0 { + n += 1 + sovTypes(uint64(m.Index)) + } + return n +} + +func (m *Owner) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Module) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *CapabilityOwners) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Owners) > 0 { + for _, e := range m.Owners { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + +func sovTypes(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTypes(x uint64) (n int) { + return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Capability) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Capability: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Capability: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Owner) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Owner: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Owner: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Module", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Module = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CapabilityOwners) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CapabilityOwners: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CapabilityOwners: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owners", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owners = append(m.Owners, Owner{}) + if err := m.Owners[len(m.Owners)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTypes(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTypes + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTypes + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTypes + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTypes = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTypes = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/capability/types/types.proto b/x/capability/types/types.proto new file mode 100644 index 000000000000..1468d4f5ba5e --- /dev/null +++ b/x/capability/types/types.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; + +package cosmos_sdk.x.capability.v1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; + +import "third_party/proto/gogoproto/gogo.proto"; + +// Capability defines an implementation of an object capability. The index provided to +// a Capability must be globally unique. +message Capability { + option (gogoproto.goproto_stringer) = false; + + uint64 index = 1 [(gogoproto.moretags) = "yaml:\"index\""]; +} + +// Owner defines a single capability owner. An owner is defined by the name of +// capability and the module name. +message Owner { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + + string module = 1 [(gogoproto.moretags) = "yaml:\"module\""]; + string name = 2 [(gogoproto.moretags) = "yaml:\"name\""]; +} + +// CapabilityOwners defines a set of owners of a single Capability. The set of +// owners must be unique. +message CapabilityOwners { + repeated Owner owners = 1 [ + (gogoproto.nullable) = false + ]; +} diff --git a/x/capability/types/types_test.go b/x/capability/types/types_test.go index 86a2a28f1618..8cec569d2faf 100644 --- a/x/capability/types/types_test.go +++ b/x/capability/types/types_test.go @@ -12,9 +12,9 @@ import ( func TestCapabilityKey(t *testing.T) { idx := uint64(3162) - cap := types.NewCapabilityKey(idx) + cap := types.NewCapability(idx) require.Equal(t, idx, cap.GetIndex()) - require.Equal(t, fmt.Sprintf("CapabilityKey{%p, %d}", cap, idx), cap.String()) + require.Equal(t, fmt.Sprintf("Capability{%p, %d}", cap, idx), cap.String()) } func TestOwner(t *testing.T) { diff --git a/x/staking/types/types.pb.go b/x/staking/types/types.pb.go index 7d022f6cdb03..ca9394854763 100644 --- a/x/staking/types/types.pb.go +++ b/x/staking/types/types.pb.go @@ -6,11 +6,6 @@ package types import ( bytes "bytes" fmt "fmt" - io "io" - math "math" - math_bits "math/bits" - time "time" - github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" _ "github.com/gogo/protobuf/gogoproto" @@ -19,6 +14,10 @@ import ( _ "github.com/golang/protobuf/ptypes/duration" _ "github.com/golang/protobuf/ptypes/timestamp" types1 "github.com/tendermint/tendermint/abci/types" + io "io" + math "math" + math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. From df5badaf4c2bffde370d7cdee95ff9c1d15e7577 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 6 Apr 2020 19:06:59 +0200 Subject: [PATCH 163/176] Merge PR #5939: Unmarshal packets as JSON --- x/ibc/20-transfer/handler.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 5f88ae9fa668..8b5ffa5afc46 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -16,13 +16,13 @@ func NewHandler(k Keeper) sdk.Handler { return handleMsgTransfer(ctx, k, msg) case channeltypes.MsgPacket: var data FungibleTokenPacketData - if err := types.ModuleCdc.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + if err := types.ModuleCdc.UnmarshalJSON(msg.GetData(), &data); err != nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) } return handlePacketDataTransfer(ctx, k, msg, data) case channeltypes.MsgTimeout: var data FungibleTokenPacketData - if err := types.ModuleCdc.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + if err := types.ModuleCdc.UnmarshalJSON(msg.GetData(), &data); err != nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) } return handleTimeoutDataTransfer(ctx, k, msg, data) From 9448610d9c59d11f063b587e3dc6737812f79f36 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 7 Apr 2020 16:50:48 +0530 Subject: [PATCH 164/176] Merge PR #5888: Dynamic Capabilities with Routing --- simapp/app.go | 30 +++- x/capability/keeper/keeper.go | 44 ++++++ x/capability/keeper/keeper_test.go | 69 ++++++++ x/ibc/04-channel/handler.go | 37 ++--- x/ibc/04-channel/keeper/handshake.go | 104 ++++++------ x/ibc/04-channel/keeper/handshake_test.go | 167 ++++++++++++++++++-- x/ibc/04-channel/keeper/keeper.go | 32 ++-- x/ibc/04-channel/keeper/keeper_test.go | 13 -- x/ibc/04-channel/keeper/packet.go | 17 +- x/ibc/04-channel/keeper/packet_test.go | 17 +- x/ibc/04-channel/types/errors.go | 15 +- x/ibc/04-channel/types/expected_keepers.go | 3 +- x/ibc/04-channel/types/msgs.go | 6 +- x/ibc/04-channel/types/msgs_test.go | 7 - x/ibc/05-port/alias.go | 6 +- x/ibc/05-port/keeper/keeper.go | 44 +++--- x/ibc/05-port/keeper/keeper_test.go | 18 +-- x/ibc/05-port/types/errors.go | 1 + x/ibc/05-port/types/module.go | 77 +++++++++ x/ibc/05-port/types/router.go | 64 ++++++++ x/ibc/20-transfer/handler.go | 28 +--- x/ibc/20-transfer/handler_test.go | 7 + x/ibc/20-transfer/keeper/keeper.go | 37 +++-- x/ibc/20-transfer/keeper/relay.go | 7 +- x/ibc/20-transfer/keeper/relay_test.go | 22 ++- x/ibc/20-transfer/module.go | 140 ++++++++++++++++ x/ibc/20-transfer/types/expected_keepers.go | 5 +- x/ibc/20-transfer/types/keys.go | 7 + x/ibc/handler.go | 153 +++++++++++++++++- x/ibc/keeper/keeper.go | 14 +- x/ibc/types/utils.go | 15 ++ 31 files changed, 978 insertions(+), 228 deletions(-) create mode 100644 x/ibc/05-port/types/module.go create mode 100644 x/ibc/05-port/types/router.go create mode 100644 x/ibc/types/utils.go diff --git a/simapp/app.go b/simapp/app.go index efcb16e14441..5c80409a1a67 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -26,6 +26,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/ibc" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" transfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/params" @@ -123,6 +124,10 @@ type SimApp struct { EvidenceKeeper evidence.Keeper TransferKeeper transfer.Keeper + // make scoped keepers public for test purposes + ScopedIBCKeeper capability.ScopedKeeper + ScopedTransferKeeper capability.ScopedKeeper + // the module manager mm *module.Manager @@ -173,6 +178,11 @@ func NewSimApp( app.subspaces[crisis.ModuleName] = app.ParamsKeeper.Subspace(crisis.DefaultParamspace) app.subspaces[evidence.ModuleName] = app.ParamsKeeper.Subspace(evidence.DefaultParamspace) + // add capability keeper and ScopeToModule for ibc module + app.CapabilityKeeper = capability.NewKeeper(appCodec, keys[capability.StoreKey]) + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibc.ModuleName) + scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(transfer.ModuleName) + // add keepers app.AccountKeeper = auth.NewAccountKeeper( appCodec, keys[auth.StoreKey], app.subspaces[auth.ModuleName], auth.ProtoBaseAccount, @@ -180,7 +190,6 @@ func NewSimApp( app.BankKeeper = bank.NewBaseKeeper( appCodec, keys[bank.StoreKey], app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(), ) - app.CapabilityKeeper = capability.NewKeeper(appCodec, keys[capability.StoreKey]) app.SupplyKeeper = supply.NewKeeper( appCodec, keys[supply.StoreKey], app.AccountKeeper, app.BankKeeper, maccPerms, ) @@ -230,15 +239,23 @@ func NewSimApp( staking.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), ) + // Create IBC Keeper app.IBCKeeper = ibc.NewKeeper( - app.cdc, keys[ibc.StoreKey], app.StakingKeeper, + app.cdc, keys[ibc.StoreKey], app.StakingKeeper, scopedIBCKeeper, ) - transferCapKey := app.IBCKeeper.PortKeeper.BindPort(bank.ModuleName) + // Create Transfer Keepers app.TransferKeeper = transfer.NewKeeper( - app.cdc, keys[transfer.StoreKey], transferCapKey, + app.cdc, keys[transfer.StoreKey], app.IBCKeeper.ChannelKeeper, app.BankKeeper, app.SupplyKeeper, + scopedTransferKeeper, ) + transferModule := transfer.NewAppModule(app.TransferKeeper) + + // Create static IBC router, add transfer route, then set and seal it + ibcRouter := port.NewRouter() + ibcRouter.AddRoute(transfer.ModuleName, transferModule) + app.IBCKeeper.SetRouter(ibcRouter) // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. @@ -257,7 +274,7 @@ func NewSimApp( upgrade.NewAppModule(app.UpgradeKeeper), evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), - transfer.NewAppModule(app.TransferKeeper), + transferModule, ) // During begin block slashing happens after distr.BeginBlocker so that @@ -323,6 +340,9 @@ func NewSimApp( ctx := app.BaseApp.NewContext(true, abci.Header{}) app.CapabilityKeeper.InitializeAndSeal(ctx) + app.ScopedIBCKeeper = scopedIBCKeeper + app.ScopedTransferKeeper = scopedTransferKeeper + return app } diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 61ddd456939e..8fc4b5e6cb7e 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -237,6 +237,50 @@ func (sk ScopedKeeper) GetCapability(ctx sdk.Context, name string) (*types.Capab return cap, true } +// Get all the Owners that own the capability associated with the name this ScopedKeeper uses +// to refer to the capability +func (sk ScopedKeeper) GetOwners(ctx sdk.Context, name string) (*types.CapabilityOwners, bool) { + cap, ok := sk.GetCapability(ctx, name) + if !ok { + return nil, false + } + + prefixStore := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) + indexKey := types.IndexToKey(cap.GetIndex()) + + var capOwners types.CapabilityOwners + + bz := prefixStore.Get(indexKey) + if len(bz) == 0 { + return nil, false + } + + sk.cdc.MustUnmarshalBinaryBare(bz, &capOwners) + return &capOwners, true + +} + +// LookupModules returns all the module owners for a given capability +// as a string array, the capability is also returned along with a boolean success flag +func (sk ScopedKeeper) LookupModules(ctx sdk.Context, name string) ([]string, *types.Capability, bool) { + cap, ok := sk.GetCapability(ctx, name) + if !ok { + return nil, nil, false + } + + capOwners, ok := sk.GetOwners(ctx, name) + if !ok { + return nil, nil, false + } + + mods := make([]string, len(capOwners.Owners)) + for i, co := range capOwners.Owners { + mods[i] = co.Module + } + return mods, cap, true + +} + func (sk ScopedKeeper) addOwner(ctx sdk.Context, cap *types.Capability, name string) error { prefixStore := prefix.NewStore(ctx.KVStore(sk.storeKey), types.KeyPrefixIndexCapability) indexKey := types.IndexToKey(cap.GetIndex()) diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index b4911438d3db..127116dbebbd 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -108,7 +108,11 @@ func (suite *KeeperTestSuite) TestAuthenticateCapability() { suite.Require().NoError(err) suite.Require().NotNil(cap2) + got, ok := sk1.GetCapability(suite.ctx, "transfer") + suite.Require().True(ok) + suite.Require().True(sk1.AuthenticateCapability(suite.ctx, cap1, "transfer")) + suite.Require().True(sk1.AuthenticateCapability(suite.ctx, got, "transfer")) suite.Require().False(sk1.AuthenticateCapability(suite.ctx, cap1, "invalid")) suite.Require().False(sk1.AuthenticateCapability(suite.ctx, cap2, "transfer")) @@ -144,6 +148,71 @@ func (suite *KeeperTestSuite) TestClaimCapability() { suite.Require().Equal(cap, got) } +func (suite *KeeperTestSuite) TestGetOwners() { + sk1 := suite.keeper.ScopeToModule(bank.ModuleName) + sk2 := suite.keeper.ScopeToModule(staking.ModuleName) + sk3 := suite.keeper.ScopeToModule("foo") + + sks := []keeper.ScopedKeeper{sk1, sk2, sk3} + + cap, err := sk1.NewCapability(suite.ctx, "transfer") + suite.Require().NoError(err) + suite.Require().NotNil(cap) + + suite.Require().NoError(sk2.ClaimCapability(suite.ctx, cap, "transfer")) + suite.Require().NoError(sk3.ClaimCapability(suite.ctx, cap, "transfer")) + + expectedOrder := []string{bank.ModuleName, "foo", staking.ModuleName} + // Ensure all scoped keepers can get owners + for _, sk := range sks { + owners, ok := sk.GetOwners(suite.ctx, "transfer") + mods, cap, mok := sk.LookupModules(suite.ctx, "transfer") + + suite.Require().True(ok, "could not retrieve owners") + suite.Require().NotNil(owners, "owners is nil") + + suite.Require().True(mok, "could not retrieve modules") + suite.Require().NotNil(cap, "capability is nil") + suite.Require().NotNil(mods, "modules is nil") + + suite.Require().Equal(len(expectedOrder), len(owners.Owners), "length of owners is unexpected") + for i, o := range owners.Owners { + // Require owner is in expected position + suite.Require().Equal(expectedOrder[i], o.Module, "module is unexpected") + suite.Require().Equal(expectedOrder[i], mods[i], "module in lookup is unexpected") + } + } + + // foo module releases capability + err = sk3.ReleaseCapability(suite.ctx, cap) + suite.Require().Nil(err, "could not release capability") + + // new expected order and scoped capabilities + expectedOrder = []string{bank.ModuleName, staking.ModuleName} + sks = []keeper.ScopedKeeper{sk1, sk2} + + // Ensure all scoped keepers can get owners + for _, sk := range sks { + owners, ok := sk.GetOwners(suite.ctx, "transfer") + mods, cap, mok := sk.LookupModules(suite.ctx, "transfer") + + suite.Require().True(ok, "could not retrieve owners") + suite.Require().NotNil(owners, "owners is nil") + + suite.Require().True(mok, "could not retrieve modules") + suite.Require().NotNil(cap, "capability is nil") + suite.Require().NotNil(mods, "modules is nil") + + suite.Require().Equal(len(expectedOrder), len(owners.Owners), "length of owners is unexpected") + for i, o := range owners.Owners { + // Require owner is in expected position + suite.Require().Equal(expectedOrder[i], o.Module, "module is unexpected") + suite.Require().Equal(expectedOrder[i], mods[i], "module in lookup is unexpected") + } + } + +} + func (suite *KeeperTestSuite) TestReleaseCapability() { sk1 := suite.keeper.ScopeToModule(bank.ModuleName) sk2 := suite.keeper.ScopeToModule(staking.ModuleName) diff --git a/x/ibc/04-channel/handler.go b/x/ibc/04-channel/handler.go index 64a36402df1b..4b1c27c0e3d7 100644 --- a/x/ibc/04-channel/handler.go +++ b/x/ibc/04-channel/handler.go @@ -2,18 +2,19 @@ package channel import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit -func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenInit) (*sdk.Result, error) { - err := k.ChanOpenInit( +func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capability.Capability, msg types.MsgChannelOpenInit) (*sdk.Result, *capability.Capability, error) { + capKey, err := k.ChanOpenInit( ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, - msg.Channel.Counterparty, msg.Channel.Version, + portCap, msg.Channel.Counterparty, msg.Channel.Version, ) if err != nil { - return nil, err + return nil, nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -34,16 +35,16 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCha return &sdk.Result{ Events: ctx.EventManager().Events().ToABCIEvents(), - }, nil + }, capKey, nil } // HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry -func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenTry) (*sdk.Result, error) { - err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, - msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, +func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capability.Capability, msg types.MsgChannelOpenTry) (*sdk.Result, *capability.Capability, error) { + capKey, err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, + portCap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, ) if err != nil { - return nil, err + return nil, nil, err } ctx.EventManager().EmitEvents(sdk.Events{ @@ -64,13 +65,13 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan return &sdk.Result{ Events: ctx.EventManager().Events().ToABCIEvents(), - }, nil + }, capKey, nil } // HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck -func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenAck) (*sdk.Result, error) { +func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, channelCap *capability.Capability, msg types.MsgChannelOpenAck) (*sdk.Result, error) { err := k.ChanOpenAck( - ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight, + ctx, msg.PortID, msg.ChannelID, channelCap, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight, ) if err != nil { return nil, err @@ -95,8 +96,8 @@ func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan } // HandleMsgChannelOpenConfirm defines the sdk.Handler for MsgChannelOpenConfirm -func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenConfirm) (*sdk.Result, error) { - err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofAck, msg.ProofHeight) +func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, channelCap *capability.Capability, msg types.MsgChannelOpenConfirm) (*sdk.Result, error) { + err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, channelCap, msg.ProofAck, msg.ProofHeight) if err != nil { return nil, err } @@ -120,8 +121,8 @@ func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Msg } // HandleMsgChannelCloseInit defines the sdk.Handler for MsgChannelCloseInit -func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseInit) (*sdk.Result, error) { - err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID) +func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, channelCap *capability.Capability, msg types.MsgChannelCloseInit) (*sdk.Result, error) { + err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID, channelCap) if err != nil { return nil, err } @@ -145,8 +146,8 @@ func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCh } // HandleMsgChannelCloseConfirm defines the sdk.Handler for MsgChannelCloseConfirm -func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseConfirm) (*sdk.Result, error) { - err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofInit, msg.ProofHeight) +func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, channelCap *capability.Capability, msg types.MsgChannelCloseConfirm) (*sdk.Result, error) { + err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, channelCap, msg.ProofInit, msg.ProofHeight) if err != nil { return nil, err } diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index 0b434d2ea650..c836314c1836 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -3,12 +3,15 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/capability" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // CounterpartyHops returns the connection hops of the counterparty channel. @@ -33,38 +36,44 @@ func (k Keeper) ChanOpenInit( connectionHops []string, portID, channelID string, + portCap *capability.Capability, counterparty types.Counterparty, version string, -) error { +) (*capability.Capability, error) { // channel identifier and connection hop length checked on msg.ValidateBasic() _, found := k.GetChannel(ctx, portID, channelID) if found { - return sdkerrors.Wrap(types.ErrChannelExists, channelID) + return nil, sdkerrors.Wrap(types.ErrChannelExists, channelID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.GetState() == connectionexported.UNINITIALIZED { - return sdkerrors.Wrap( + return nil, sdkerrors.Wrap( connection.ErrInvalidConnectionState, "connection state cannot be UNINITIALIZED", ) } + if !k.portKeeper.Authenticate(ctx, portCap, portID) { + return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "caller does not own port capability") + } + channel := types.NewChannel(exported.INIT, order, counterparty, connectionHops, version) k.SetChannel(ctx, portID, channelID, channel) - // TODO: blocked by #5542 - // key := "" - // k.SetChannelCapability(ctx, portID, channelID, key) + capKey, err := k.scopedKeeper.NewCapability(ctx, ibctypes.ChannelCapabilityPath(portID, channelID)) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrInvalidChannelCapability, err.Error()) + } k.SetNextSequenceSend(ctx, portID, channelID, 1) k.SetNextSequenceRecv(ctx, portID, channelID, 1) - return nil + return capKey, nil } // ChanOpenTry is called by a module to accept the first step of a channel opening @@ -75,12 +84,13 @@ func (k Keeper) ChanOpenTry( connectionHops []string, portID, channelID string, + portCap *capability.Capability, counterparty types.Counterparty, version, counterpartyVersion string, proofInit commitmentexported.Proof, proofHeight uint64, -) error { +) (*capability.Capability, error) { // channel identifier and connection hop length checked on msg.ValidateBasic() previousChannel, found := k.GetChannel(ctx, portID, channelID) @@ -93,19 +103,17 @@ func (k Keeper) ChanOpenTry( sdkerrors.Wrap(types.ErrInvalidChannel, "cannot relay connection attempt") } - // TODO: blocked by #5542 - // key := sdk.NewKVStoreKey(portID) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.portKeeper.Authenticate(ctx, portCap, portID) { + return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "caller does not own port capability") + } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) + return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.GetState() != connectionexported.OPEN { - return sdkerrors.Wrapf( + return nil, sdkerrors.Wrapf( connection.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectionEnd.GetState().String(), ) @@ -133,18 +141,19 @@ func (k Keeper) ChanOpenTry( ctx, connectionEnd, proofHeight, proofInit, counterparty.PortID, counterparty.ChannelID, expectedChannel, ); err != nil { - return err + return nil, err } k.SetChannel(ctx, portID, channelID, channel) - // TODO: blocked by #5542 - // key := "" - // k.SetChannelCapability(ctx, portID, channelID, key) + capKey, err := k.scopedKeeper.NewCapability(ctx, ibctypes.ChannelCapabilityPath(portID, channelID)) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrInvalidChannelCapability, err.Error()) + } k.SetNextSequenceSend(ctx, portID, channelID, 1) k.SetNextSequenceRecv(ctx, portID, channelID, 1) - return nil + return capKey, nil } // ChanOpenAck is called by the handshake-originating module to acknowledge the @@ -152,7 +161,8 @@ func (k Keeper) ChanOpenTry( func (k Keeper) ChanOpenAck( ctx sdk.Context, portID, - channelID, + channelID string, + chanCap *capability.Capability, counterpartyVersion string, proofTry commitmentexported.Proof, proofHeight uint64, @@ -169,11 +179,9 @@ func (k Keeper) ChanOpenAck( ) } - // TODO: blocked by #5542 - // key := sdk.NewKVStoreKey(portID) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) { + return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel") + } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { @@ -221,6 +229,7 @@ func (k Keeper) ChanOpenConfirm( ctx sdk.Context, portID, channelID string, + chanCap *capability.Capability, proofAck commitmentexported.Proof, proofHeight uint64, ) error { @@ -236,16 +245,9 @@ func (k Keeper) ChanOpenConfirm( ) } - // TODO: blocked by #5542 - // capkey, found := k.GetChannelCapability(ctx, portID, channelID) - // if !found { - // return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID) - // } - - // key := sdk.NewKVStoreKey(capkey) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) { + return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel") + } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { @@ -296,17 +298,11 @@ func (k Keeper) ChanCloseInit( ctx sdk.Context, portID, channelID string, + chanCap *capability.Capability, ) error { - // TODO: blocked by #5542 - // capkey, found := k.GetChannelCapability(ctx, portID, channelID) - // if !found { - // return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID) - // } - - // key := sdk.NewKVStoreKey(capkey) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) { + return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel") + } channel, found := k.GetChannel(ctx, portID, channelID) if !found { @@ -341,19 +337,13 @@ func (k Keeper) ChanCloseConfirm( ctx sdk.Context, portID, channelID string, + chanCap *capability.Capability, proofInit commitmentexported.Proof, proofHeight uint64, ) error { - // TODO: blocked by #5542 - // capkey, found := k.GetChannelCapability(ctx, portID, channelID) - // if !found { - // return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID) - // } - - // key := sdk.NewKVStoreKey(capkey) - // if !k.portKeeper.Authenticate(key, portID) { - // return sdkerrors.Wrap(port.ErrInvalidPort, portID) - // } + if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) { + return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel") + } channel, found := k.GetChannel(ctx, portID, channelID) if !found { diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 7cc6f9eba755..216051db7580 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -3,15 +3,18 @@ package keeper_test import ( "fmt" + "github.com/cosmos/cosmos-sdk/x/capability" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) func (suite *KeeperTestSuite) TestChanOpenInit() { counterparty := types.NewCounterparty(testPort2, testChannel2) + var portCap *capability.Capability testCases := []testCase{ {"success", func() { suite.chainA.createConnection( @@ -32,20 +35,40 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { connectionexported.UNINITIALIZED, ) }, false}, + {"capability is incorrect", func() { + suite.chainA.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, + connectionexported.INIT, + ) + portCap = capability.NewCapability(3) + }, false}, } for i, tc := range testCases { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset + var err error + portCap, err = suite.chainA.App.ScopedIBCKeeper.NewCapability( + suite.chainA.GetContext(), porttypes.PortPath(testPort1), + ) + suite.Require().NoError(err, "could not create capability") + tc.malleate() - err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenInit( + cap, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenInit( suite.chainA.GetContext(), exported.ORDERED, []string{testConnectionIDA}, - testPort1, testChannel1, counterparty, testChannelVersion, + testPort1, testChannel1, portCap, counterparty, testChannelVersion, ) if tc.expPass { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + suite.Require().NotNil(cap) + chanCap, ok := suite.chainA.App.ScopedIBCKeeper.GetCapability( + suite.chainA.GetContext(), + ibctypes.ChannelCapabilityPath(testPort1, testChannel1), + ) + suite.Require().True(ok, "could not retrieve channel capapbility after successful ChanOpenInit") + suite.Require().Equal(chanCap.String(), cap.String(), "channel capability is not correct") } else { suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -57,6 +80,7 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { counterparty := types.NewCounterparty(testPort1, testChannel1) channelKey := ibctypes.KeyChannel(testPort1, testChannel1) + var portCap *capability.Capability testCases := []testCase{ {"success", func() { suite.chainA.CreateClient(suite.chainB) @@ -95,12 +119,28 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { connectionexported.OPEN, ) }, false}, + {"port capability not found", func() { + suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, + connectionexported.OPEN, + ) + suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.INIT, exported.ORDERED, testConnectionIDA) + portCap = capability.NewCapability(3) + }, false}, } for i, tc := range testCases { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset + var err error + portCap, err = suite.chainA.App.ScopedIBCKeeper.NewCapability(suite.chainA.GetContext(), porttypes.PortPath(testPort2)) + suite.Require().NoError(err, "could not create capability") + tc.malleate() suite.chainA.updateClient(suite.chainB) @@ -108,16 +148,23 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { proof, proofHeight := queryProof(suite.chainB, channelKey) if tc.expPass { - err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenTry( + cap, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenTry( suite.chainA.GetContext(), exported.ORDERED, []string{testConnectionIDB}, - testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, + testPort2, testChannel2, portCap, counterparty, testChannelVersion, testChannelVersion, proof, proofHeight+1, ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) + suite.Require().NotNil(cap) + chanCap, ok := suite.chainA.App.ScopedIBCKeeper.GetCapability( + suite.chainA.GetContext(), + ibctypes.ChannelCapabilityPath(testPort2, testChannel2), + ) + suite.Require().True(ok, "could not retrieve channel capapbility after successful ChanOpenInit") + suite.Require().Equal(chanCap.String(), cap.String(), "channel capability is not correct") } else { - err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenTry( + _, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenTry( suite.chainA.GetContext(), exported.ORDERED, []string{testConnectionIDB}, - testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, + testPort2, testChannel2, portCap, counterparty, testChannelVersion, testChannelVersion, invalidProof{}, uint64(proofHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) @@ -129,6 +176,7 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { func (suite *KeeperTestSuite) TestChanOpenAck() { channelKey := ibctypes.KeyChannel(testPort2, testChannel2) + var channelCap *capability.Capability testCases := []testCase{ {"success", func() { suite.chainA.CreateClient(suite.chainB) @@ -194,12 +242,37 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { exported.ORDERED, testConnectionIDA, ) }, false}, + {"channel capability not found", func() { + suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) + suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, + connectionexported.OPEN, + ) + _ = suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, + connectionexported.OPEN, + ) + _ = suite.chainA.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.INIT, + exported.ORDERED, testConnectionIDB, + ) + suite.chainB.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.TRYOPEN, + exported.ORDERED, testConnectionIDA, + ) + channelCap = capability.NewCapability(3) + }, false}, } for i, tc := range testCases { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset + var err error + channelCap, err = suite.chainA.App.ScopedIBCKeeper.NewCapability(suite.chainA.GetContext(), ibctypes.ChannelCapabilityPath(testPort1, testChannel1)) + suite.Require().NoError(err, "could not create capability") + tc.malleate() suite.chainA.updateClient(suite.chainB) @@ -208,13 +281,13 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { if tc.expPass { err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenAck( - suite.chainA.GetContext(), testPort1, testChannel1, testChannelVersion, + suite.chainA.GetContext(), testPort1, testChannel1, channelCap, testChannelVersion, proof, proofHeight+1, ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenAck( - suite.chainA.GetContext(), testPort1, testChannel1, testChannelVersion, + suite.chainA.GetContext(), testPort1, testChannel1, channelCap, testChannelVersion, invalidProof{}, proofHeight+1, ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) @@ -226,6 +299,7 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { func (suite *KeeperTestSuite) TestChanOpenConfirm() { channelKey := ibctypes.KeyChannel(testPort2, testChannel2) + var channelCap *capability.Capability testCases := []testCase{ {"success", func() { suite.chainA.CreateClient(suite.chainB) @@ -289,12 +363,35 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { exported.ORDERED, testConnectionIDB, ) }, false}, + {"channel capability not found", func() { + suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) + _ = suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, + connectionexported.TRYOPEN, + ) + suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, + connectionexported.OPEN, + ) + _ = suite.chainA.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, + exported.ORDERED, testConnectionIDB, + ) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, + exported.TRYOPEN, exported.ORDERED, testConnectionIDA) + channelCap = capability.NewCapability(3) + }, false}, } for i, tc := range testCases { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset + var err error + channelCap, err = suite.chainB.App.ScopedIBCKeeper.NewCapability(suite.chainB.GetContext(), ibctypes.ChannelCapabilityPath(testPort1, testChannel1)) + suite.Require().NoError(err, "could not create capability") + tc.malleate() suite.chainA.updateClient(suite.chainB) @@ -304,12 +401,12 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { if tc.expPass { err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenConfirm( suite.chainB.GetContext(), testPort1, testChannel1, - proof, proofHeight+1, + channelCap, proof, proofHeight+1, ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenConfirm( - suite.chainB.GetContext(), testPort1, testChannel1, + suite.chainB.GetContext(), testPort1, testChannel1, channelCap, invalidProof{}, proofHeight+1, ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) @@ -319,6 +416,7 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { } func (suite *KeeperTestSuite) TestChanCloseInit() { + var channelCap *capability.Capability testCases := []testCase{ {"success", func() { suite.chainB.CreateClient(suite.chainA) @@ -354,15 +452,31 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { exported.ORDERED, testConnectionIDA, ) }, false}, + {"channel capability not found", func() { + suite.chainB.CreateClient(suite.chainA) + _ = suite.chainA.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, + connectionexported.OPEN, + ) + _ = suite.chainA.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, + exported.ORDERED, testConnectionIDA, + ) + channelCap = capability.NewCapability(3) + }, false}, } for i, tc := range testCases { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset + var err error + channelCap, err = suite.chainA.App.ScopedIBCKeeper.NewCapability(suite.chainA.GetContext(), ibctypes.ChannelCapabilityPath(testPort1, testChannel1)) + suite.Require().NoError(err, "could not create capability") + tc.malleate() - err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanCloseInit( - suite.chainA.GetContext(), testPort1, testChannel1, + err = suite.chainA.App.IBCKeeper.ChannelKeeper.ChanCloseInit( + suite.chainA.GetContext(), testPort1, testChannel1, channelCap, ) if tc.expPass { @@ -377,6 +491,7 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { func (suite *KeeperTestSuite) TestChanCloseConfirm() { channelKey := ibctypes.KeyChannel(testPort1, testChannel1) + var channelCap *capability.Capability testCases := []testCase{ {"success", func() { suite.chainA.CreateClient(suite.chainB) @@ -442,12 +557,36 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { exported.ORDERED, testConnectionIDB, ) }, false}, + {"channel capability not found", func() { + suite.chainA.CreateClient(suite.chainB) + suite.chainB.CreateClient(suite.chainA) + _ = suite.chainB.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDA, testClientIDB, + connectionexported.OPEN, + ) + suite.chainA.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDB, testClientIDA, + connectionexported.OPEN, + ) + _ = suite.chainB.createChannel( + testPort2, testChannel2, testPort1, testChannel1, exported.OPEN, + exported.ORDERED, testConnectionIDB, + ) + suite.chainA.createChannel( + testPort1, testChannel1, testPort2, testChannel2, exported.CLOSED, + exported.ORDERED, testConnectionIDA, + ) + }, false}, } for i, tc := range testCases { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset + var err error + channelCap, err = suite.chainB.App.ScopedIBCKeeper.NewCapability(suite.chainB.GetContext(), ibctypes.ChannelCapabilityPath(testPort2, testChannel2)) + suite.Require().NoError(err, "could not create capability") + tc.malleate() suite.chainA.updateClient(suite.chainB) @@ -456,13 +595,13 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { if tc.expPass { err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanCloseConfirm( - suite.chainB.GetContext(), testPort2, testChannel2, + suite.chainB.GetContext(), testPort2, testChannel2, channelCap, proof, proofHeight+1, ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanCloseConfirm( - suite.chainB.GetContext(), testPort2, testChannel2, + suite.chainB.GetContext(), testPort2, testChannel2, channelCap, invalidProof{}, uint64(proofHeight), ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) diff --git a/x/ibc/04-channel/keeper/keeper.go b/x/ibc/04-channel/keeper/keeper.go index bccdeb775765..1774cbf0c51f 100644 --- a/x/ibc/04-channel/keeper/keeper.go +++ b/x/ibc/04-channel/keeper/keeper.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) @@ -19,13 +20,14 @@ type Keeper struct { clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper portKeeper types.PortKeeper + scopedKeeper capability.ScopedKeeper } // NewKeeper creates a new IBC channel Keeper instance func NewKeeper( cdc *codec.Codec, key sdk.StoreKey, clientKeeper types.ClientKeeper, connectionKeeper types.ConnectionKeeper, - portKeeper types.PortKeeper, + portKeeper types.PortKeeper, scopedKeeper capability.ScopedKeeper, ) Keeper { return Keeper{ storeKey: key, @@ -33,6 +35,7 @@ func NewKeeper( clientKeeper: clientKeeper, connectionKeeper: connectionKeeper, portKeeper: portKeeper, + scopedKeeper: scopedKeeper, } } @@ -61,23 +64,6 @@ func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel ty store.Set(ibctypes.KeyChannel(portID, channelID), bz) } -// GetChannelCapability gets a channel's capability key from the store -func (k Keeper) GetChannelCapability(ctx sdk.Context, portID, channelID string) (string, bool) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(ibctypes.KeyChannelCapabilityPath(portID, channelID)) - if bz == nil { - return "", false - } - - return string(bz), true -} - -// SetChannelCapability sets a channel's capability key to the store -func (k Keeper) SetChannelCapability(ctx sdk.Context, portID, channelID string, key string) { - store := ctx.KVStore(k.storeKey) - store.Set(ibctypes.KeyChannelCapabilityPath(portID, channelID), []byte(key)) -} - // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) @@ -175,3 +161,13 @@ func (k Keeper) GetAllChannels(ctx sdk.Context) (channels []types.IdentifiedChan }) return channels } + +// LookupModuleByChannel will return the IBCModule along with the capability associated with a given channel defined by its portID and channelID +func (k Keeper) LookupModuleByChannel(ctx sdk.Context, portID, channelID string) (string, *capability.Capability, bool) { + modules, cap, ok := k.scopedKeeper.LookupModules(ctx, ibctypes.ChannelCapabilityPath(portID, channelID)) + if !ok { + return "", nil, false + } + + return ibctypes.GetModuleOwner(modules), cap, true +} diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index 8780b1feba9d..92631bf844b2 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -137,19 +137,6 @@ func (suite KeeperTestSuite) TestGetAllChannels() { suite.Require().Equal(expChannels, channels) } -func (suite *KeeperTestSuite) TestSetChannelCapability() { - ctx := suite.chainB.GetContext() - _, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetChannelCapability(ctx, testPort1, testChannel1) - suite.False(found) - - channelCap := "test-channel-capability" - suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannelCapability(ctx, testPort1, testChannel1, channelCap) - - storedChannelCap, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetChannelCapability(ctx, testPort1, testChannel1) - suite.True(found) - suite.Equal(channelCap, storedChannelCap) -} - func (suite *KeeperTestSuite) TestSetSequence() { ctx := suite.chainB.GetContext() _, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetNextSequenceSend(ctx, testPort1, testChannel1) diff --git a/x/ibc/04-channel/keeper/packet.go b/x/ibc/04-channel/keeper/packet.go index 0978bb64b361..1475d68c9a3f 100644 --- a/x/ibc/04-channel/keeper/packet.go +++ b/x/ibc/04-channel/keeper/packet.go @@ -6,12 +6,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/capability" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // SendPacket is called by a module in order to send an IBC packet on a channel @@ -19,6 +21,7 @@ import ( // chain. func (k Keeper) SendPacket( ctx sdk.Context, + channelCap *capability.Capability, packet exported.PacketI, ) error { if err := packet.ValidateBasic(); err != nil { @@ -37,17 +40,9 @@ func (k Keeper) SendPacket( ) } - // TODO: blocked by #5542 - // capKey, found := k.GetChannelCapability(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) - // if !found { - // return types.ErrChannelCapabilityNotFound - // } - - // portCapabilityKey := sdk.NewKVStoreKey(capKey) - - // if !k.portKeeper.Authenticate(portCapabilityKey, packet.GetSourcePort()) { - // return sdkerrors.Wrap(port.ErrInvalidPort, packet.GetSourcePort()) - // } + if !k.scopedKeeper.AuthenticateCapability(ctx, channelCap, ibctypes.ChannelCapabilityPath(packet.GetSourcePort(), packet.GetSourceChannel())) { + return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel") + } if packet.GetDestPort() != channel.Counterparty.PortID { return sdkerrors.Wrapf( diff --git a/x/ibc/04-channel/keeper/packet_test.go b/x/ibc/04-channel/keeper/packet_test.go index 2f96212a9e36..1d8b5a5522c5 100644 --- a/x/ibc/04-channel/keeper/packet_test.go +++ b/x/ibc/04-channel/keeper/packet_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "fmt" + "github.com/cosmos/cosmos-sdk/x/capability" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" @@ -15,6 +16,7 @@ func (suite *KeeperTestSuite) TestSendPacket() { counterparty := types.NewCounterparty(testPort2, testChannel2) var packet exported.PacketI + var channelCap *capability.Capability testCases := []testCase{ {"success", func() { packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) @@ -75,15 +77,28 @@ func (suite *KeeperTestSuite) TestSendPacket() { suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainB.GetContext(), testPort1, testChannel1, 5) }, false}, + {"channel capability not found", func() { + packet = types.NewPacket(mockSuccessPacket{}.GetBytes(), 1, testPort1, testChannel1, counterparty.GetPortID(), counterparty.GetChannelID(), 100) + suite.chainB.CreateClient(suite.chainA) + suite.chainB.createConnection(testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, connectionexported.OPEN) + suite.chainB.createChannel(testPort1, testChannel1, testPort2, testChannel2, exported.OPEN, exported.ORDERED, testConnectionIDA) + suite.chainB.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainB.GetContext(), testPort1, testChannel1, 1) + channelCap = capability.NewCapability(3) + }, false}, } for i, tc := range testCases { tc := tc suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { suite.SetupTest() // reset + + var err error + channelCap, err = suite.chainB.App.ScopedIBCKeeper.NewCapability(suite.chainB.GetContext(), ibctypes.ChannelCapabilityPath(testPort1, testChannel1)) + suite.Require().Nil(err, "could not create capability") + tc.malleate() - err := suite.chainB.App.IBCKeeper.ChannelKeeper.SendPacket(suite.chainB.GetContext(), packet) + err = suite.chainB.App.IBCKeeper.ChannelKeeper.SendPacket(suite.chainB.GetContext(), channelCap, packet) if tc.expPass { suite.Require().NoError(err) diff --git a/x/ibc/04-channel/types/errors.go b/x/ibc/04-channel/types/errors.go index a184314bbd56..1def7a4d004e 100644 --- a/x/ibc/04-channel/types/errors.go +++ b/x/ibc/04-channel/types/errors.go @@ -12,11 +12,12 @@ var ( ErrInvalidChannelState = sdkerrors.Register(SubModuleName, 4, "invalid channel state") ErrInvalidChannelOrdering = sdkerrors.Register(SubModuleName, 5, "invalid channel ordering") ErrInvalidCounterparty = sdkerrors.Register(SubModuleName, 6, "invalid counterparty channel") - ErrChannelCapabilityNotFound = sdkerrors.Register(SubModuleName, 7, "channel capability not found") - ErrSequenceSendNotFound = sdkerrors.Register(SubModuleName, 8, "sequence send not found") - ErrSequenceReceiveNotFound = sdkerrors.Register(SubModuleName, 9, "sequence receive not found") - ErrInvalidPacket = sdkerrors.Register(SubModuleName, 10, "invalid packet") - ErrPacketTimeout = sdkerrors.Register(SubModuleName, 11, "packet timeout") - ErrTooManyConnectionHops = sdkerrors.Register(SubModuleName, 12, "too many connection hops") - ErrAcknowledgementTooLong = sdkerrors.Register(SubModuleName, 13, "acknowledgement too long") + ErrInvalidChannelCapability = sdkerrors.Register(SubModuleName, 7, "invalid channel capability") + ErrChannelCapabilityNotFound = sdkerrors.Register(SubModuleName, 8, "channel capability not found") + ErrSequenceSendNotFound = sdkerrors.Register(SubModuleName, 9, "sequence send not found") + ErrSequenceReceiveNotFound = sdkerrors.Register(SubModuleName, 10, "sequence receive not found") + ErrInvalidPacket = sdkerrors.Register(SubModuleName, 11, "invalid packet") + ErrPacketTimeout = sdkerrors.Register(SubModuleName, 12, "packet timeout") + ErrTooManyConnectionHops = sdkerrors.Register(SubModuleName, 13, "too many connection hops") + ErrAcknowledgementTooLong = sdkerrors.Register(SubModuleName, 14, "acknowledgement too long") ) diff --git a/x/ibc/04-channel/types/expected_keepers.go b/x/ibc/04-channel/types/expected_keepers.go index 26c6ad1547a4..cbc663528198 100644 --- a/x/ibc/04-channel/types/expected_keepers.go +++ b/x/ibc/04-channel/types/expected_keepers.go @@ -2,6 +2,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" @@ -68,5 +69,5 @@ type ConnectionKeeper interface { // PortKeeper expected account IBC port keeper type PortKeeper interface { - Authenticate(key sdk.CapabilityKey, portID string) bool + Authenticate(ctx sdk.Context, key *capability.Capability, portID string) bool } diff --git a/x/ibc/04-channel/types/msgs.go b/x/ibc/04-channel/types/msgs.go index 6501f40f3e5c..f003bdafb627 100644 --- a/x/ibc/04-channel/types/msgs.go +++ b/x/ibc/04-channel/types/msgs.go @@ -415,7 +415,7 @@ func NewMsgPacket(packet Packet, proof commitmentexported.Proof, proofHeight uin // Route implements sdk.Msg func (msg MsgPacket) Route() string { - return msg.DestinationPort + return ibctypes.RouterKey } // ValidateBasic implements sdk.Msg @@ -482,7 +482,7 @@ func NewMsgTimeout(packet Packet, nextSequenceRecv uint64, proof commitmentexpor // Route implements sdk.Msg func (msg MsgTimeout) Route() string { - return msg.SourcePort + return ibctypes.RouterKey } // ValidateBasic implements sdk.Msg @@ -542,7 +542,7 @@ func NewMsgAcknowledgement(packet Packet, ack []byte, proof commitmentexported.P // Route implements sdk.Msg func (msg MsgAcknowledgement) Route() string { - return msg.SourcePort + return ibctypes.RouterKey } // ValidateBasic implements sdk.Msg diff --git a/x/ibc/04-channel/types/msgs_test.go b/x/ibc/04-channel/types/msgs_test.go index aeb47f4ad640..81237978f9ea 100644 --- a/x/ibc/04-channel/types/msgs_test.go +++ b/x/ibc/04-channel/types/msgs_test.go @@ -376,13 +376,6 @@ var ( cpchanid = "testcpchannel" ) -// TestMsgPacketRoute tests Route for MsgPacket -func TestMsgPacketRoute(t *testing.T) { - msg := NewMsgPacket(packet, proof, 1, addr1) - - require.Equal(t, cpportid, msg.Route()) -} - // TestMsgPacketType tests Type for MsgPacket func TestMsgPacketType(t *testing.T) { msg := NewMsgPacket(packet, proof, 1, addr1) diff --git a/x/ibc/05-port/alias.go b/x/ibc/05-port/alias.go index f53d7a41f9ee..31dd696ea206 100644 --- a/x/ibc/05-port/alias.go +++ b/x/ibc/05-port/alias.go @@ -21,13 +21,17 @@ const ( var ( // functions aliases NewKeeper = keeper.NewKeeper + NewRouter = types.NewRouter ErrPortExists = types.ErrPortExists ErrPortNotFound = types.ErrPortNotFound ErrInvalidPort = types.ErrInvalidPort + ErrInvalidRoute = types.ErrInvalidRoute PortPath = types.PortPath KeyPort = types.KeyPort ) type ( - Keeper = keeper.Keeper + Keeper = keeper.Keeper + Router = types.Router + IBCModule = types.IBCModule ) diff --git a/x/ibc/05-port/keeper/keeper.go b/x/ibc/05-port/keeper/keeper.go index 45f0817f7702..cb0749e35c90 100644 --- a/x/ibc/05-port/keeper/keeper.go +++ b/x/ibc/05-port/keeper/keeper.go @@ -3,47 +3,48 @@ package keeper import ( "fmt" - "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" + "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // Keeper defines the IBC connection keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - ports map[string]bool + scopedKeeper capability.ScopedKeeper } // NewKeeper creates a new IBC connection Keeper instance -func NewKeeper(cdc *codec.Codec, key sdk.StoreKey) Keeper { +func NewKeeper(sck capability.ScopedKeeper) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - ports: make(map[string]bool), // map of capability key names to port ids + scopedKeeper: sck, } } // isBounded checks a given port ID is already bounded. -func (k Keeper) isBounded(portID string) bool { - return k.ports[portID] +func (k Keeper) isBound(ctx sdk.Context, portID string) bool { + _, ok := k.scopedKeeper.GetCapability(ctx, types.PortPath(portID)) + return ok } // BindPort binds to a port and returns the associated capability. // Ports must be bound statically when the chain starts in `app.go`. // The capability must then be passed to a module which will need to pass // it as an extra parameter when calling functions on the IBC module. -func (k *Keeper) BindPort(portID string) sdk.CapabilityKey { +func (k *Keeper) BindPort(ctx sdk.Context, portID string) *capability.Capability { if err := host.DefaultPortIdentifierValidator(portID); err != nil { panic(err.Error()) } - if k.isBounded(portID) { + if k.isBound(ctx, portID) { panic(fmt.Sprintf("port %s is already bound", portID)) } - key := sdk.NewKVStoreKey(portID) - k.ports[key.Name()] = true // NOTE: key name and value always match + key, err := k.scopedKeeper.NewCapability(ctx, types.PortPath(portID)) + if err != nil { + panic(err.Error()) + } return key } @@ -52,14 +53,21 @@ func (k *Keeper) BindPort(portID string) sdk.CapabilityKey { // by checking if the memory address of the capability was previously // generated and bound to the port (provided as a parameter) which the capability // is being authenticated against. -func (k Keeper) Authenticate(key sdk.CapabilityKey, portID string) bool { +func (k Keeper) Authenticate(ctx sdk.Context, key *capability.Capability, portID string) bool { if err := host.DefaultPortIdentifierValidator(portID); err != nil { panic(err.Error()) } - if key.Name() != portID { - return false + return k.scopedKeeper.AuthenticateCapability(ctx, key, types.PortPath(portID)) +} + +// LookupModuleByPort will return the IBCModule along with the capability associated with a given portID +func (k Keeper) LookupModuleByPort(ctx sdk.Context, portID string) (string, *capability.Capability, bool) { + modules, cap, ok := k.scopedKeeper.LookupModules(ctx, types.PortPath(portID)) + if !ok { + return "", nil, false } - return k.ports[key.Name()] + return ibctypes.GetModuleOwner(modules), cap, true + } diff --git a/x/ibc/05-port/keeper/keeper_test.go b/x/ibc/05-port/keeper/keeper_test.go index c44c1f052d06..8afa3295c2b7 100644 --- a/x/ibc/05-port/keeper/keeper_test.go +++ b/x/ibc/05-port/keeper/keeper_test.go @@ -42,33 +42,33 @@ func TestKeeperTestSuite(t *testing.T) { func (suite *KeeperTestSuite) TestBind() { // Test that invalid portID causes panic - require.Panics(suite.T(), func() { suite.keeper.BindPort(invalidPort) }, "Did not panic on invalid portID") + require.Panics(suite.T(), func() { suite.keeper.BindPort(suite.ctx, invalidPort) }, "Did not panic on invalid portID") // Test that valid BindPort returns capability key - capKey := suite.keeper.BindPort(validPort) + capKey := suite.keeper.BindPort(suite.ctx, validPort) require.NotNil(suite.T(), capKey, "capabilityKey is nil on valid BindPort") // Test that rebinding the same portid causes panic - require.Panics(suite.T(), func() { suite.keeper.BindPort(validPort) }, "did not panic on re-binding the same port") + require.Panics(suite.T(), func() { suite.keeper.BindPort(suite.ctx, validPort) }, "did not panic on re-binding the same port") } func (suite *KeeperTestSuite) TestAuthenticate() { - capKey := suite.keeper.BindPort(validPort) + capKey := suite.keeper.BindPort(suite.ctx, validPort) // Require that passing in invalid portID causes panic - require.Panics(suite.T(), func() { suite.keeper.Authenticate(capKey, invalidPort) }, "did not panic on invalid portID") + require.Panics(suite.T(), func() { suite.keeper.Authenticate(suite.ctx, capKey, invalidPort) }, "did not panic on invalid portID") // Valid authentication should return true - auth := suite.keeper.Authenticate(capKey, validPort) + auth := suite.keeper.Authenticate(suite.ctx, capKey, validPort) require.True(suite.T(), auth, "valid authentication failed") // Test that authenticating against incorrect portid fails - auth = suite.keeper.Authenticate(capKey, "wrongportid") + auth = suite.keeper.Authenticate(suite.ctx, capKey, "wrongportid") require.False(suite.T(), auth, "invalid authentication failed") // Test that authenticating port against different valid // capability key fails - capKey2 := suite.keeper.BindPort("otherportid") - auth = suite.keeper.Authenticate(capKey2, validPort) + capKey2 := suite.keeper.BindPort(suite.ctx, "otherportid") + auth = suite.keeper.Authenticate(suite.ctx, capKey2, validPort) require.False(suite.T(), auth, "invalid authentication for different capKey failed") } diff --git a/x/ibc/05-port/types/errors.go b/x/ibc/05-port/types/errors.go index a0778ecd6b01..cad4f8551fb1 100644 --- a/x/ibc/05-port/types/errors.go +++ b/x/ibc/05-port/types/errors.go @@ -9,4 +9,5 @@ var ( ErrPortExists = sdkerrors.Register(SubModuleName, 1, "port is already binded") ErrPortNotFound = sdkerrors.Register(SubModuleName, 2, "port not found") ErrInvalidPort = sdkerrors.Register(SubModuleName, 3, "invalid port") + ErrInvalidRoute = sdkerrors.Register(SubModuleName, 4, "route not found") ) diff --git a/x/ibc/05-port/types/module.go b/x/ibc/05-port/types/module.go new file mode 100644 index 000000000000..013fac6a37b3 --- /dev/null +++ b/x/ibc/05-port/types/module.go @@ -0,0 +1,77 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/cosmos-sdk/x/capability" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" +) + +// IBCModule defines an interface that implements all the callbacks +// that modules must define as specified in ICS-26 +type IBCModule interface { + OnChanOpenInit( + ctx sdk.Context, + order channelexported.Order, + connectionHops []string, + portID string, + channelID string, + channelCap *capability.Capability, + counterParty channeltypes.Counterparty, + version string, + ) error + + OnChanOpenTry( + ctx sdk.Context, + order channelexported.Order, + connectionHops []string, + portID, + channelID string, + channelCap *capability.Capability, + counterparty channeltypes.Counterparty, + version, + counterpartyVersion string, + ) error + + OnChanOpenAck( + ctx sdk.Context, + portID, + channelID string, + counterpartyVersion string, + ) error + + OnChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, + ) error + + OnChanCloseInit( + ctx sdk.Context, + portID, + channelID string, + ) error + + OnChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, + ) error + + OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + ) (*sdk.Result, error) + + OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + ) (*sdk.Result, error) + + OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, + ) (*sdk.Result, error) +} diff --git a/x/ibc/05-port/types/router.go b/x/ibc/05-port/types/router.go new file mode 100644 index 000000000000..cb4a5cd79edd --- /dev/null +++ b/x/ibc/05-port/types/router.go @@ -0,0 +1,64 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// The router is a map from module name to the IBCModule +// which contains all the module-defined callbacks required by ICS-26 +type Router struct { + routes map[string]IBCModule + sealed bool +} + +func NewRouter() *Router { + return &Router{ + routes: make(map[string]IBCModule), + } +} + +// Seal prevents the Router from any subsequent route handlers to be registered. +// Seal will panic if called more than once. +func (rtr *Router) Seal() { + if rtr.sealed { + panic("router already sealed") + } + rtr.sealed = true +} + +// Sealed returns a boolean signifying if the Router is sealed or not. +func (rtr Router) Sealed() bool { + return rtr.sealed +} + +// AddRoute adds IBCModule for a given module name. It returns the Router +// so AddRoute calls can be linked. It will panic if the Router is sealed. +func (rtr *Router) AddRoute(module string, cbs IBCModule) *Router { + if rtr.sealed { + panic(fmt.Sprintf("router sealed; cannot register %s route callbacks", module)) + } + if !sdk.IsAlphaNumeric(module) { + panic("route expressions can only contain alphanumeric characters") + } + if rtr.HasRoute(module) { + panic(fmt.Sprintf("route %s has already been registered", module)) + } + + rtr.routes[module] = cbs + return rtr +} + +// HasRoute returns true if the Router has a module registered or false otherwise. +func (rtr *Router) HasRoute(module string) bool { + return rtr.routes[module] != nil +} + +// GetRoute returns a IBCModule for a given module. +func (rtr *Router) GetRoute(module string) (IBCModule, bool) { + if !rtr.HasRoute(module) { + return nil, false + } + return rtr.routes[module], true +} diff --git a/x/ibc/20-transfer/handler.go b/x/ibc/20-transfer/handler.go index 8b5ffa5afc46..09935da0608b 100644 --- a/x/ibc/20-transfer/handler.go +++ b/x/ibc/20-transfer/handler.go @@ -5,7 +5,6 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" - "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) // NewHandler returns sdk.Handler for IBC token transfer module messages @@ -14,18 +13,6 @@ func NewHandler(k Keeper) sdk.Handler { switch msg := msg.(type) { case MsgTransfer: return handleMsgTransfer(ctx, k, msg) - case channeltypes.MsgPacket: - var data FungibleTokenPacketData - if err := types.ModuleCdc.UnmarshalJSON(msg.GetData(), &data); err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) - } - return handlePacketDataTransfer(ctx, k, msg, data) - case channeltypes.MsgTimeout: - var data FungibleTokenPacketData - if err := types.ModuleCdc.UnmarshalJSON(msg.GetData(), &data); err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) - } - return handleTimeoutDataTransfer(ctx, k, msg, data) default: return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer message type: %T", msg) } @@ -56,9 +43,9 @@ func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, // See onRecvPacket in spec: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay func handlePacketDataTransfer( - ctx sdk.Context, k Keeper, msg channeltypes.MsgPacket, data FungibleTokenPacketData, + ctx sdk.Context, k Keeper, packet channeltypes.Packet, data FungibleTokenPacketData, ) (*sdk.Result, error) { - if err := k.ReceiveTransfer(ctx, msg.Packet, data); err != nil { + if err := k.ReceiveTransfer(ctx, packet, data); err != nil { // NOTE (cwgoes): How do we want to handle this case? Maybe we should be more lenient, // it's safe to leave the channel open I think. @@ -66,14 +53,14 @@ func handlePacketDataTransfer( // the receiving chain couldn't process the transfer // source chain sent invalid packet, shutdown our channel end - if err := k.ChanCloseInit(ctx, msg.Packet.DestinationPort, msg.Packet.DestinationChannel); err != nil { + if err := k.ChanCloseInit(ctx, packet.DestinationPort, packet.DestinationChannel); err != nil { return nil, err } return nil, err } acknowledgement := AckDataTransfer{} - if err := k.PacketExecuted(ctx, msg.Packet, acknowledgement.GetBytes()); err != nil { + if err := k.PacketExecuted(ctx, packet, acknowledgement.GetBytes()); err != nil { return nil, err } @@ -81,7 +68,6 @@ func handlePacketDataTransfer( sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory), - sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()), ), ) @@ -92,14 +78,14 @@ func handlePacketDataTransfer( // See onTimeoutPacket in spec: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay func handleTimeoutDataTransfer( - ctx sdk.Context, k Keeper, msg channeltypes.MsgTimeout, data FungibleTokenPacketData, + ctx sdk.Context, k Keeper, packet channeltypes.Packet, data FungibleTokenPacketData, ) (*sdk.Result, error) { - if err := k.TimeoutTransfer(ctx, msg.Packet, data); err != nil { + if err := k.TimeoutTransfer(ctx, packet, data); err != nil { // This shouldn't happen, since we've already validated that we've sent the packet. panic(err) } - if err := k.TimeoutExecuted(ctx, msg.Packet); err != nil { + if err := k.TimeoutExecuted(ctx, packet); err != nil { // This shouldn't happen, since we've already validated that we've sent the packet. // TODO: Figure out what happens if the capability authorisation changes. panic(err) diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 15b9f3b847ae..8e4d3060edef 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -91,6 +91,13 @@ func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitmenttypes.Mer func (suite *HandlerTestSuite) TestHandleMsgTransfer() { handler := transfer.NewHandler(suite.chainA.App.TransferKeeper) + // create channel capability from ibc scoped keeper and claim with transfer scoped keeper + capName := ibctypes.ChannelCapabilityPath(testPort1, testChannel1) + cap, err := suite.chainA.App.ScopedIBCKeeper.NewCapability(suite.chainA.GetContext(), capName) + suite.Require().Nil(err, "could not create capability") + err = suite.chainA.App.ScopedTransferKeeper.ClaimCapability(suite.chainA.GetContext(), cap, capName) + suite.Require().Nil(err, "transfer module could not claim capability") + ctx := suite.chainA.GetContext() msg := transfer.NewMsgTransfer(testPort1, testChannel1, 10, testPrefixedCoins2, testAddr1, testAddr2) res, err := handler(ctx, msg) diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index f629de5e9bf8..62b73d835395 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -7,6 +7,9 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/capability" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" @@ -20,22 +23,23 @@ const ( // Keeper defines the IBC transfer keeper type Keeper struct { - storeKey sdk.StoreKey - cdc *codec.Codec - boundedCapability sdk.CapabilityKey + storeKey sdk.StoreKey + cdc *codec.Codec clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper channelKeeper types.ChannelKeeper bankKeeper types.BankKeeper supplyKeeper types.SupplyKeeper + scopedKeeper capability.ScopedKeeper } // NewKeeper creates a new IBC transfer Keeper instance func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, capKey sdk.CapabilityKey, + cdc *codec.Codec, key sdk.StoreKey, channelKeeper types.ChannelKeeper, bankKeeper types.BankKeeper, supplyKeeper types.SupplyKeeper, + scopedKeeper capability.ScopedKeeper, ) Keeper { // ensure ibc transfer module account is set @@ -44,12 +48,12 @@ func NewKeeper( } return Keeper{ - storeKey: key, - cdc: cdc, - boundedCapability: capKey, - channelKeeper: channelKeeper, - bankKeeper: bankKeeper, - supplyKeeper: supplyKeeper, + storeKey: key, + cdc: cdc, + channelKeeper: channelKeeper, + bankKeeper: bankKeeper, + supplyKeeper: supplyKeeper, + scopedKeeper: scopedKeeper, } } @@ -72,7 +76,12 @@ func (k Keeper) PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, // ChanCloseInit defines a wrapper function for the channel Keeper's function // in order to expose it to the ICS20 trasfer handler. func (k Keeper) ChanCloseInit(ctx sdk.Context, portID, channelID string) error { - return k.channelKeeper.ChanCloseInit(ctx, portID, channelID) + capName := ibctypes.ChannelCapabilityPath(portID, channelID) + chanCap, ok := k.scopedKeeper.GetCapability(ctx, capName) + if !ok { + return sdkerrors.Wrapf(channel.ErrChannelCapabilityNotFound, "could not retrieve channel capability at: %s", capName) + } + return k.channelKeeper.ChanCloseInit(ctx, portID, channelID, chanCap) } // TimeoutExecuted defines a wrapper function for the channel Keeper's function @@ -80,3 +89,9 @@ func (k Keeper) ChanCloseInit(ctx sdk.Context, portID, channelID string) error { func (k Keeper) TimeoutExecuted(ctx sdk.Context, packet channelexported.PacketI) error { return k.channelKeeper.TimeoutExecuted(ctx, packet) } + +// ClaimCapability allows the transfer module that can claim a capability that IBC module +// passes to it +func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capability.Capability, name string) error { + return k.scopedKeeper.ClaimCapability(ctx, cap, name) +} diff --git a/x/ibc/20-transfer/keeper/relay.go b/x/ibc/20-transfer/keeper/relay.go index 342bca5563cb..cf7d8be4daad 100644 --- a/x/ibc/20-transfer/keeper/relay.go +++ b/x/ibc/20-transfer/keeper/relay.go @@ -7,6 +7,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) // SendTransfer handles transfer sending logic. There are 2 possible cases: @@ -65,6 +66,10 @@ func (k Keeper) createOutgoingPacket( amount sdk.Coins, sender, receiver sdk.AccAddress, ) error { + channelCap, ok := k.scopedKeeper.GetCapability(ctx, ibctypes.ChannelCapabilityPath(sourcePort, sourceChannel)) + if !ok { + return sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, "module does not own channel capability") + } // NOTE: // - Coins transferred from the destination chain should have their denomination // prefixed with source port and channel IDs. @@ -141,7 +146,7 @@ func (k Keeper) createOutgoingPacket( destHeight+DefaultPacketTimeout, ) - return k.channelKeeper.SendPacket(ctx, packet) + return k.channelKeeper.SendPacket(ctx, channelCap, packet) } func (k Keeper) onRecvPacket(ctx sdk.Context, packet channel.Packet, data types.FungibleTokenPacketData) error { diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 2a4badc7d9cd..246987dcf4f9 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -8,11 +8,14 @@ import ( channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" "github.com/cosmos/cosmos-sdk/x/supply" ) func (suite *KeeperTestSuite) TestSendTransfer() { testCoins2 := sdk.NewCoins(sdk.NewCoin("testportid/secondchannel/atom", sdk.NewInt(100))) + capName := ibctypes.ChannelCapabilityPath(testPort1, testChannel1) + testCases := []struct { msg string amount sdk.Coins @@ -63,6 +66,17 @@ func (suite *KeeperTestSuite) TestSendTransfer() { suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort1, testChannel1, 1) }, false, false}, + {"channel capability not found", testCoins, + func() { + suite.chainA.App.BankKeeper.AddCoins(suite.chainA.GetContext(), testAddr1, testCoins) + suite.chainA.CreateClient(suite.chainB) + suite.chainA.createConnection(testConnection, testConnection, testClientIDB, testClientIDA, connectionexported.OPEN) + suite.chainA.createChannel(testPort1, testChannel1, testPort2, testChannel2, channelexported.OPEN, channelexported.ORDERED, testConnection) + suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), testPort1, testChannel1, 1) + // Release channel capability + cap, _ := suite.chainA.App.ScopedTransferKeeper.GetCapability(suite.chainA.GetContext(), capName) + suite.chainA.App.ScopedTransferKeeper.ReleaseCapability(suite.chainA.GetContext(), cap) + }, true, false}, } for i, tc := range testCases { @@ -70,9 +84,15 @@ func (suite *KeeperTestSuite) TestSendTransfer() { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset + // create channel capability from ibc scoped keeper and claim with transfer scoped keeper + cap, err := suite.chainA.App.ScopedIBCKeeper.NewCapability(suite.chainA.GetContext(), capName) + suite.Require().Nil(err, "could not create capability") + err = suite.chainA.App.ScopedTransferKeeper.ClaimCapability(suite.chainA.GetContext(), cap, capName) + suite.Require().Nil(err, "transfer module could not claim capability") + tc.malleate() - err := suite.chainA.App.TransferKeeper.SendTransfer( + err = suite.chainA.App.TransferKeeper.SendTransfer( suite.chainA.GetContext(), testPort1, testChannel1, 100, tc.amount, testAddr1, testAddr2, ) diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index 805e122f1bb1..5d09a1da36b4 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -11,13 +11,23 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/capability" + channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" + porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/rest" + "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" + ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" ) var ( _ module.AppModule = AppModule{} + _ port.IBCModule = AppModule{} _ module.AppModuleBasic = AppModuleBasic{} ) @@ -119,3 +129,133 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } + +// Implement IBCModule callbacks +func (am AppModule) OnChanOpenInit( + ctx sdk.Context, + order channelexported.Order, + connectionHops []string, + portID string, + channelID string, + chanCap *capability.Capability, + counterparty channeltypes.Counterparty, + version string, +) error { + // TODO: Enforce ordering, currently relayers use ORDERED channels + + if counterparty.PortID != types.PortID { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "counterparty has invalid portid. expected: %s, got %s", types.PortID, counterparty.PortID) + } + + if version != types.Version { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid version: %s, expected %s", version, "ics20-1") + } + + // Claim channel capability passed back by IBC module + if err := am.keeper.ClaimCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)); err != nil { + return sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, err.Error()) + } + + // TODO: escrow + return nil +} + +func (am AppModule) OnChanOpenTry( + ctx sdk.Context, + order channelexported.Order, + connectionHops []string, + portID, + channelID string, + chanCap *capability.Capability, + counterparty channeltypes.Counterparty, + version, + counterpartyVersion string, +) error { + // TODO: Enforce ordering, currently relayers use ORDERED channels + + if counterparty.PortID != types.PortID { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "counterparty has invalid portid. expected: %s, got %s", types.PortID, counterparty.PortID) + } + + if version != types.Version { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid version: %s, expected %s", version, "ics20-1") + } + + if counterpartyVersion != types.Version { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid counterparty version: %s, expected %s", counterpartyVersion, "ics20-1") + } + + // Claim channel capability passed back by IBC module + if err := am.keeper.ClaimCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)); err != nil { + return sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, err.Error()) + } + + // TODO: escrow + return nil +} + +func (am AppModule) OnChanOpenAck( + ctx sdk.Context, + portID, + channelID string, + counterpartyVersion string, +) error { + if counterpartyVersion != types.Version { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid counterparty version: %s, expected %s", counterpartyVersion, "ics20-1") + } + return nil +} + +func (am AppModule) OnChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + return nil +} + +func (am AppModule) OnChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + return nil +} + +func (am AppModule) OnChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + return nil +} + +func (am AppModule) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, +) (*sdk.Result, error) { + var data FungibleTokenPacketData + if err := types.ModuleCdc.UnmarshalBinaryBare(packet.GetData(), &data); err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) + } + return handlePacketDataTransfer(ctx, am.keeper, packet, data) +} + +func (am AppModule) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledment []byte, +) (*sdk.Result, error) { + return nil, nil +} + +func (am AppModule) OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, +) (*sdk.Result, error) { + var data FungibleTokenPacketData + if err := types.ModuleCdc.UnmarshalBinaryBare(packet.GetData(), &data); err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) + } + return handleTimeoutDataTransfer(ctx, am.keeper, packet, data) +} diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index 9cf6c4dc8549..2abc95b45854 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -2,6 +2,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -18,9 +19,9 @@ type BankKeeper interface { type ChannelKeeper interface { GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channel.Channel, found bool) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) - SendPacket(ctx sdk.Context, packet channelexported.PacketI) error + SendPacket(ctx sdk.Context, channelCap *capability.Capability, packet channelexported.PacketI) error PacketExecuted(ctx sdk.Context, packet channelexported.PacketI, acknowledgement []byte) error - ChanCloseInit(ctx sdk.Context, portID, channelID string) error + ChanCloseInit(ctx sdk.Context, portID, channelID string, chanCap *capability.Capability) error TimeoutExecuted(ctx sdk.Context, packet channelexported.PacketI) error } diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go index 322f1500349a..5dd17e49b717 100644 --- a/x/ibc/20-transfer/types/keys.go +++ b/x/ibc/20-transfer/types/keys.go @@ -13,6 +13,13 @@ const ( // ModuleName defines the IBC transfer name ModuleName = "transfer" + // Version defines the current version the IBC tranfer + // module supports + Version = "ics20-1" + + // PortID that transfer module binds to + PortID = "bank" + // StoreKey is the store key string for IBC transfer StoreKey = ModuleName diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 1a3f5843f01f..d71f73e4585b 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -7,6 +7,7 @@ import ( clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + port "github.com/cosmos/cosmos-sdk/x/ibc/05-port" ) // NewHandler defines the IBC handler @@ -37,22 +38,162 @@ func NewHandler(k Keeper) sdk.Handler { // IBC channel msgs case channel.MsgChannelOpenInit: - return channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, msg) + // Lookup module by port capability + module, portCap, ok := k.PortKeeper.LookupModuleByPort(ctx, msg.PortID) + if !ok { + return nil, sdkerrors.Wrap(port.ErrInvalidPort, "could not retrieve module from portID") + } + res, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg) + if err != nil { + return nil, err + } + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, cap, msg.Channel.Counterparty, msg.Channel.Version) + if err != nil { + return nil, err + } + + return res, nil case channel.MsgChannelOpenTry: - return channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, msg) + // Lookup module by port capability + module, portCap, ok := k.PortKeeper.LookupModuleByPort(ctx, msg.PortID) + if !ok { + return nil, sdkerrors.Wrap(port.ErrInvalidPort, "could not retrieve module from portID") + } + res, cap, err := channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, portCap, msg) + if err != nil { + return nil, err + } + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion) + if err != nil { + return nil, err + } + + return res, nil case channel.MsgChannelOpenAck: - return channel.HandleMsgChannelOpenAck(ctx, k.ChannelKeeper, msg) + // Lookup module by channel capability + module, cap, ok := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortID, msg.ChannelID) + if !ok { + return nil, sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, "could not retrieve module from channel capability") + } + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + err := cbs.OnChanOpenAck(ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion) + if err != nil { + return nil, err + } + return channel.HandleMsgChannelOpenAck(ctx, k.ChannelKeeper, cap, msg) case channel.MsgChannelOpenConfirm: - return channel.HandleMsgChannelOpenConfirm(ctx, k.ChannelKeeper, msg) + // Lookup module by channel capability + module, cap, ok := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortID, msg.ChannelID) + if !ok { + return nil, sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, "could not retrieve module from channel capability") + } + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + + err := cbs.OnChanOpenConfirm(ctx, msg.PortID, msg.ChannelID) + if err != nil { + return nil, err + } + return channel.HandleMsgChannelOpenConfirm(ctx, k.ChannelKeeper, cap, msg) case channel.MsgChannelCloseInit: - return channel.HandleMsgChannelCloseInit(ctx, k.ChannelKeeper, msg) + // Lookup module by channel capability + module, cap, ok := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortID, msg.ChannelID) + if !ok { + return nil, sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, "could not retrieve module from channel capability") + } + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + + err := cbs.OnChanCloseInit(ctx, msg.PortID, msg.ChannelID) + if err != nil { + return nil, err + } + return channel.HandleMsgChannelCloseInit(ctx, k.ChannelKeeper, cap, msg) case channel.MsgChannelCloseConfirm: - return channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, msg) + // Lookup module by channel capability + module, cap, ok := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortID, msg.ChannelID) + if !ok { + return nil, sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, "could not retrieve module from channel capability") + } + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + + err := cbs.OnChanCloseConfirm(ctx, msg.PortID, msg.ChannelID) + if err != nil { + return nil, err + } + return channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, cap, msg) + + // IBC packet msgs get routed to the appropriate module callback + case channel.MsgPacket: + // Lookup module by channel capability + module, _, ok := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.DestinationPort, msg.Packet.DestinationChannel) + if !ok { + return nil, sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, "could not retrieve module from channel capability") + } + + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + return cbs.OnRecvPacket(ctx, msg.Packet) + + case channel.MsgAcknowledgement: + // Lookup module by channel capability + module, _, ok := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.DestinationPort, msg.Packet.DestinationChannel) + if !ok { + return nil, sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, "could not retrieve module from channel capability") + } + + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + return cbs.OnAcknowledgementPacket(ctx, msg.Packet, msg.Acknowledgement) + + case channel.MsgTimeout: + // Lookup module by channel capability + module, _, ok := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.DestinationPort, msg.Packet.DestinationChannel) + if !ok { + return nil, sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, "could not retrieve module from channel capability") + } + + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + return cbs.OnTimeoutPacket(ctx, msg.Packet) default: return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized IBC message type: %T", msg) diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index aefe2863b4de..3052c2e25ad2 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -3,6 +3,7 @@ package keeper import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/capability" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -15,16 +16,17 @@ type Keeper struct { ConnectionKeeper connection.Keeper ChannelKeeper channel.Keeper PortKeeper port.Keeper + Router *port.Router } // NewKeeper creates a new ibc Keeper func NewKeeper( - cdc *codec.Codec, key sdk.StoreKey, stakingKeeper client.StakingKeeper, + cdc *codec.Codec, key sdk.StoreKey, stakingKeeper client.StakingKeeper, scopedKeeper capability.ScopedKeeper, ) Keeper { clientKeeper := client.NewKeeper(cdc, key, stakingKeeper) connectionKeeper := connection.NewKeeper(cdc, key, clientKeeper) - portKeeper := port.NewKeeper(cdc, key) - channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper) + portKeeper := port.NewKeeper(scopedKeeper) + channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper, scopedKeeper) return Keeper{ ClientKeeper: clientKeeper, @@ -33,3 +35,9 @@ func NewKeeper( PortKeeper: portKeeper, } } + +// Set the Router in IBC Keeper and seal it +func (k Keeper) SetRouter(rtr *port.Router) { + k.Router = rtr + k.Router.Seal() +} diff --git a/x/ibc/types/utils.go b/x/ibc/types/utils.go new file mode 100644 index 000000000000..7af4bf0de5ee --- /dev/null +++ b/x/ibc/types/utils.go @@ -0,0 +1,15 @@ +package types + +// For now, we enforce that only IBC and the module bound to port can own the capability +// while future implementations may allow multiple modules to bind to a port, currently we +// only allow one module to be bound to a port at any given time +func GetModuleOwner(modules []string) string { + if len(modules) != 2 { + panic("capability should only be owned by port or channel owner and ibc module, multiple owners currently not supported") + } + + if modules[0] == "ibc" { + return modules[1] + } + return modules[0] +} From d0053c5acebfdb35f487ee17495d5ca85674a955 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 7 Apr 2020 11:50:42 -0400 Subject: [PATCH 165/176] cleanup ibc-alpha (#5945) * cleanup ibc-alpha * remove HasKeyTable() * add preexisting checks * undo remove checks --- go.mod | 2 -- go.sum | 4 ++-- sim_state-4.json | 0 x/auth/client/cli/query.go | 2 +- x/bank/alias.go | 2 +- x/staking/keeper/keeper.go | 6 +----- 6 files changed, 5 insertions(+), 11 deletions(-) delete mode 100644 sim_state-4.json diff --git a/go.mod b/go.mod index 0703c260ff00..94b3d1391dc4 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,4 @@ require ( replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.1 -replace github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 - go 1.14 diff --git a/go.sum b/go.sum index fef49b591eaa..f5755bcfdd78 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= -github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.1.4 h1:x0g0zQ9bQKgNsLo0XSXAy1H8Q1RG/td+5OXJt+Ci8b8= github.com/99designs/keyring v1.1.4/go.mod h1:657DQuMrBZRtuL/voxVyiyb6zpMehlm5vLB9Qwrv904= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= @@ -228,6 +226,8 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM= +github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= 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= diff --git a/sim_state-4.json b/sim_state-4.json deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/x/auth/client/cli/query.go b/x/auth/client/cli/query.go index 11bf50ab389f..1d7e60639aa9 100644 --- a/x/auth/client/cli/query.go +++ b/x/auth/client/cli/query.go @@ -99,7 +99,7 @@ func GetAccountCmd(cdc *codec.Codec) *cobra.Command { }, } - return cmd + return flags.GetCommands(cmd)[0] } // QueryTxsByEventsCmd returns a command to search through transactions by events. diff --git a/x/bank/alias.go b/x/bank/alias.go index d28cf6c1d4cd..9811c9e001ee 100644 --- a/x/bank/alias.go +++ b/x/bank/alias.go @@ -39,6 +39,7 @@ var ( DefaultGenesisState = types.DefaultGenesisState ValidateGenesis = types.ValidateGenesis SanitizeGenesisBalances = types.SanitizeGenesisBalances + GetGenesisStateFromAppState = types.GetGenesisStateFromAppState NewMsgSend = types.NewMsgSend NewMsgMultiSend = types.NewMsgMultiSend NewInput = types.NewInput @@ -51,7 +52,6 @@ var ( ParamStoreKeySendEnabled = types.ParamStoreKeySendEnabled BalancesPrefix = types.BalancesPrefix AddressFromBalancesStore = types.AddressFromBalancesStore - GetGenesisStateFromAppState = types.GetGenesisStateFromAppState ) type ( diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index 8dbf6edd4c91..c4f19286597e 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -37,6 +37,7 @@ func NewKeeper( cdc codec.Marshaler, key sdk.StoreKey, bk types.BankKeeper, sk types.SupplyKeeper, ps paramtypes.Subspace, ) Keeper { + // set KeyTable if it has not already been set if !ps.HasKeyTable() { ps = ps.WithKeyTable(ParamKeyTable()) } @@ -50,11 +51,6 @@ func NewKeeper( panic(fmt.Sprintf("%s module account has not been set", types.NotBondedPoolName)) } - // set KeyTable if it has not already been set - if !ps.HasKeyTable() { - ps = ps.WithKeyTable(ParamKeyTable()) - } - return Keeper{ storeKey: key, cdc: cdc, From 53e135f715bf1a09e61a892a90b8e1d8a6679b5b Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 7 Apr 2020 13:40:18 -0400 Subject: [PATCH 166/176] x/staking: import and export HistoricalInfo --- x/staking/keeper/historical_info.go | 26 +++++++++++++++++++++ x/staking/keeper/historical_info_test.go | 29 ++++++++++++++++++++++++ x/staking/keeper/keeper.go | 1 + x/staking/simulation/decoder.go | 6 +++++ x/staking/simulation/decoder_test.go | 4 ++++ 5 files changed, 66 insertions(+) diff --git a/x/staking/keeper/historical_info.go b/x/staking/keeper/historical_info.go index 2ce0aee7dbcc..01ae38cc4092 100644 --- a/x/staking/keeper/historical_info.go +++ b/x/staking/keeper/historical_info.go @@ -36,6 +36,32 @@ func (k Keeper) DeleteHistoricalInfo(ctx sdk.Context, height int64) { store.Delete(key) } +// IterateHistoricalInfo provides an interator over all stored HistoricalInfo +// objects. For each HistoricalInfo object, cb will be called. If the cb returns +// true, the iterator will close and stop. +func (k Keeper) IterateHistoricalInfo(ctx sdk.Context, cb func(types.HistoricalInfo) bool) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.HistoricalInfoKey) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + histInfo := types.MustUnmarshalHistoricalInfo(k.cdc, iterator.Value()) + if cb(histInfo) { + break + } + } +} + +// GetAllHistoricalInfo returns all stored HistoricalInfo objects. +func (k Keeper) GetAllHistoricalInfo(ctx sdk.Context) []types.HistoricalInfo { + var infos []types.HistoricalInfo + k.IterateHistoricalInfo(ctx, func(histInfo types.HistoricalInfo) bool { + infos = append(infos, histInfo) + return false + }) + return infos +} + // TrackHistoricalInfo saves the latest historical-info and deletes the oldest // heights that are below pruning height func (k Keeper) TrackHistoricalInfo(ctx sdk.Context) { diff --git a/x/staking/keeper/historical_info_test.go b/x/staking/keeper/historical_info_test.go index 3a3f1100592b..37e3b7237f58 100644 --- a/x/staking/keeper/historical_info_test.go +++ b/x/staking/keeper/historical_info_test.go @@ -114,3 +114,32 @@ func TestTrackHistoricalInfo(t *testing.T) { require.False(t, found, "GetHistoricalInfo did not prune first prune height") require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune") } + +func TestGetAllHistoricalInfo(t *testing.T) { + _, app, ctx := createTestInput() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + valSet := []types.Validator{ + types.NewValidator(addrVals[0], PKs[0], types.Description{}), + types.NewValidator(addrVals[1], PKs[1], types.Description{}), + } + + header1 := abci.Header{ChainID: "HelloChain", Height: 10} + header2 := abci.Header{ChainID: "HelloChain", Height: 11} + header3 := abci.Header{ChainID: "HelloChain", Height: 12} + + hist1 := types.HistoricalInfo{Header: header1, Valset: valSet} + hist2 := types.HistoricalInfo{Header: header2, Valset: valSet} + hist3 := types.HistoricalInfo{Header: header3, Valset: valSet} + + expHistInfos := []types.HistoricalInfo{hist1, hist2, hist3} + + for i, hi := range expHistInfos { + app.StakingKeeper.SetHistoricalInfo(ctx, int64(10+i), hi) + } + + infos := app.StakingKeeper.GetAllHistoricalInfo(ctx) + require.Equal(t, expHistInfos, infos) +} diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index feddaf3b96f8..c4f19286597e 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -37,6 +37,7 @@ func NewKeeper( cdc codec.Marshaler, key sdk.StoreKey, bk types.BankKeeper, sk types.SupplyKeeper, ps paramtypes.Subspace, ) Keeper { + // set KeyTable if it has not already been set if !ps.HasKeyTable() { ps = ps.WithKeyTable(ParamKeyTable()) } diff --git a/x/staking/simulation/decoder.go b/x/staking/simulation/decoder.go index 86f1cecc9e00..efd8cb917e42 100644 --- a/x/staking/simulation/decoder.go +++ b/x/staking/simulation/decoder.go @@ -51,6 +51,12 @@ func DecodeStore(cdc *codec.Codec, kvA, kvB tmkv.Pair) string { cdc.MustUnmarshalBinaryBare(kvB.Value, &redB) return fmt.Sprintf("%v\n%v", redA, redB) + case bytes.Equal(kvA.Key[:1], types.HistoricalInfoKey): + var histInfoA, histInfoB types.HistoricalInfo + cdc.MustUnmarshalBinaryBare(kvA.Value, &histInfoA) + cdc.MustUnmarshalBinaryBare(kvB.Value, &histInfoB) + return fmt.Sprintf("%v\n%v", histInfoA, histInfoB) + default: panic(fmt.Sprintf("invalid staking key prefix %X", kvA.Key[:1])) } diff --git a/x/staking/simulation/decoder_test.go b/x/staking/simulation/decoder_test.go index 40dd39710e84..813f7fc74a6f 100644 --- a/x/staking/simulation/decoder_test.go +++ b/x/staking/simulation/decoder_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" tmkv "github.com/tendermint/tendermint/libs/kv" @@ -38,6 +39,7 @@ func TestDecodeStore(t *testing.T) { del := types.NewDelegation(delAddr1, valAddr1, sdk.OneDec()) ubd := types.NewUnbondingDelegation(delAddr1, valAddr1, 15, bondTime, sdk.OneInt()) red := types.NewRedelegation(delAddr1, valAddr1, valAddr1, 12, bondTime, sdk.OneInt(), sdk.OneDec()) + histInfo := types.NewHistoricalInfo(abci.Header{ChainID: "gaia", Height: 10, Time: bondTime}, types.Validators{val}) kvPairs := tmkv.Pairs{ tmkv.Pair{Key: types.LastTotalPowerKey, Value: cdc.MustMarshalBinaryBare(sdk.OneInt())}, @@ -46,6 +48,7 @@ func TestDecodeStore(t *testing.T) { tmkv.Pair{Key: types.GetDelegationKey(delAddr1, valAddr1), Value: cdc.MustMarshalBinaryBare(del)}, tmkv.Pair{Key: types.GetUBDKey(delAddr1, valAddr1), Value: cdc.MustMarshalBinaryBare(ubd)}, tmkv.Pair{Key: types.GetREDKey(delAddr1, valAddr1, valAddr1), Value: cdc.MustMarshalBinaryBare(red)}, + tmkv.Pair{Key: types.GetHistoricalInfoKey(10), Value: cdc.MustMarshalBinaryBare(histInfo)}, tmkv.Pair{Key: []byte{0x99}, Value: []byte{0x99}}, } @@ -59,6 +62,7 @@ func TestDecodeStore(t *testing.T) { {"Delegation", fmt.Sprintf("%v\n%v", del, del)}, {"UnbondingDelegation", fmt.Sprintf("%v\n%v", ubd, ubd)}, {"Redelegation", fmt.Sprintf("%v\n%v", red, red)}, + {"HistoricalInfo", fmt.Sprintf("%v\n%v", histInfo, histInfo)}, {"other", ""}, } for i, tt := range tests { From 5eb287818e36b660bbe1a302a0aed0027cb05391 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 7 Apr 2020 14:16:13 -0400 Subject: [PATCH 167/176] staking/types: add HistoricalInfo to GenesisState --- x/staking/genesis.go | 6 ++++++ x/staking/genesis_test.go | 8 ++++++++ x/staking/types/genesis.go | 1 + 3 files changed, 15 insertions(+) diff --git a/x/staking/genesis.go b/x/staking/genesis.go index 8a2ecce10740..6f02545ab914 100644 --- a/x/staking/genesis.go +++ b/x/staking/genesis.go @@ -121,6 +121,10 @@ func InitGenesis( supplyKeeper.SetModuleAccount(ctx, notBondedPool) } + for _, hi := range data.HistoricalInfos { + keeper.SetHistoricalInfo(ctx, hi.Header.GetHeight(), hi) + } + // don't need to run Tendermint updates if we exported if data.Exported { for _, lv := range data.LastValidatorPowers { @@ -148,6 +152,7 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { lastTotalPower := keeper.GetLastTotalPower(ctx) validators := keeper.GetAllValidators(ctx) delegations := keeper.GetAllDelegations(ctx) + historicalInfos := keeper.GetAllHistoricalInfo(ctx) var unbondingDelegations []types.UnbondingDelegation keeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd types.UnbondingDelegation) (stop bool) { unbondingDelegations = append(unbondingDelegations, ubd) @@ -172,6 +177,7 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { Delegations: delegations, UnbondingDelegations: unbondingDelegations, Redelegations: redelegations, + HistoricalInfos: historicalInfos, Exported: true, } } diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index 3d3419f3ba54..a1d477ac27d7 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -64,7 +64,15 @@ func TestInitGenesis(t *testing.T) { validators[1].Tokens = valTokens validators[1].DelegatorShares = valTokens.ToDec() + header1 := abci.Header{ChainID: "gaia", Height: 10} + header2 := abci.Header{ChainID: "gaia", Height: 11} + header3 := abci.Header{ChainID: "gaia", Height: 12} + hist1 := types.HistoricalInfo{Header: header1, Valset: validators} + hist2 := types.HistoricalInfo{Header: header2, Valset: validators} + hist3 := types.HistoricalInfo{Header: header3, Valset: validators} + genesisState := types.NewGenesisState(params, validators, delegations) + genesisState.HistoricalInfos = []types.HistoricalInfo{hist1, hist2, hist3} vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.SupplyKeeper, genesisState) actualGenesis := staking.ExportGenesis(ctx, app.StakingKeeper) diff --git a/x/staking/types/genesis.go b/x/staking/types/genesis.go index 943ab4fb31f0..553215800fcc 100644 --- a/x/staking/types/genesis.go +++ b/x/staking/types/genesis.go @@ -13,6 +13,7 @@ type GenesisState struct { Delegations Delegations `json:"delegations" yaml:"delegations"` UnbondingDelegations []UnbondingDelegation `json:"unbonding_delegations" yaml:"unbonding_delegations"` Redelegations []Redelegation `json:"redelegations" yaml:"redelegations"` + HistoricalInfos []HistoricalInfo `json:"historical_infos" yaml:"historical_infos"` Exported bool `json:"exported" yaml:"exported"` } From 46d805cd285b9583bdc3c27200baaa69dc6bb889 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 7 Apr 2020 14:17:54 -0400 Subject: [PATCH 168/176] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bcbedca0ae0..5cc0f3d3c20f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,6 +98,7 @@ when method receivers are offline/multisig keys. types (eg. keys) to the `auth` module internal amino codec. * (rest) [\#5906](https://github.com/cosmos/cosmos-sdk/pull/5906) Fix an issue that make some REST calls panic when sending invalid or incomplete requests. +* (x/staking) [\#5949](https://github.com/cosmos/cosmos-sdk/pull/5949) Add `HistoricalInfo` to staking `GenesisState` for import and export. ### State Machine Breaking From 5c3df550695940ae79bb85f4815299c92157afef Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 7 Apr 2020 14:25:20 -0400 Subject: [PATCH 169/176] add staking module to app BeginBlockers --- sim_params-7.json | 1 + sim_state-7.json | 122226 +++++++++++++++++++++++++++++++++++++++++++ simapp/app.go | 2 +- 3 files changed, 122228 insertions(+), 1 deletion(-) create mode 100644 sim_params-7.json create mode 100644 sim_state-7.json diff --git a/sim_params-7.json b/sim_params-7.json new file mode 100644 index 000000000000..9e26dfeeb6e6 --- /dev/null +++ b/sim_params-7.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/sim_state-7.json b/sim_state-7.json new file mode 100644 index 000000000000..b575940740ef --- /dev/null +++ b/sim_state-7.json @@ -0,0 +1,122226 @@ +{ + "bank": { + "send_enabled": true, + "balances": [ + { + "address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", + "coins": [ + { + "denom": "stake", + "amount": "13015743095" + } + ] + }, + { + "address": "cosmos1wdm9ge7hjzrlh2epwtwu3nsunfd2r7alqhc7r2", + "coins": [ + { + "denom": "stake", + "amount": "766070747" + } + ] + }, + { + "address": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq", + "coins": [ + { + "denom": "stake", + "amount": "14891624890" + } + ] + }, + { + "address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", + "coins": [ + { + "denom": "stake", + "amount": "14963416025" + } + ] + }, + { + "address": "cosmos1823pz6pxtqgm8hdcxaysccpyd8fx83hm287sld", + "coins": [ + { + "denom": "stake", + "amount": "10185265919" + } + ] + }, + { + "address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", + "coins": [ + { + "denom": "stake", + "amount": "45637326" + } + ] + }, + { + "address": "cosmos1gw6f5uf38mv5dng9uwfzv4r9whvdd2f60ay2ra", + "coins": [ + { + "denom": "stake", + "amount": "76112747" + } + ] + }, + { + "address": "cosmos12sx0qw8yggnh7scj90gu08k66q7j8wqq88y25h", + "coins": [ + { + "denom": "stake", + "amount": "4993493505" + } + ] + }, + { + "address": "cosmos12marehfknnseqtft88ut8gehf0lvcun3mymcme", + "coins": [ + { + "denom": "stake", + "amount": "14320099451" + } + ] + }, + { + "address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", + "coins": [ + { + "denom": "stake", + "amount": "10270105" + } + ] + }, + { + "address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", + "coins": [ + { + "denom": "stake", + "amount": "1349398915" + } + ] + }, + { + "address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", + "coins": [ + { + "denom": "stake", + "amount": "484757514" + } + ] + }, + { + "address": "cosmos13y2zjpgaj07umx7a3dsg9ffhpkk22g73492l53", + "coins": [ + { + "denom": "stake", + "amount": "6639888504" + } + ] + }, + { + "address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "coins": [ + { + "denom": "stake", + "amount": "2508642240" + } + ] + }, + { + "address": "cosmos1t929u2r8p5vtvuwn390l506achd08udrwx4ah3", + "coins": [ + { + "denom": "stake", + "amount": "15194890118" + } + ] + }, + { + "address": "cosmos13ps0cszg8lqn0mkzndvhxwaew8yd56s8tl9j20", + "coins": [ + { + "denom": "stake", + "amount": "5412847843" + } + ] + }, + { + "address": "cosmos17gpy6jzg7xdsr2xc7kweljagx4uaysxdk2244g", + "coins": [ + { + "denom": "stake", + "amount": "27613138030" + } + ] + }, + { + "address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", + "coins": [ + { + "denom": "stake", + "amount": "4968763267" + } + ] + }, + { + "address": "cosmos1zsspke0nqudcl0lh747ppqcsy396245akc2vtl", + "coins": [ + { + "denom": "stake", + "amount": "2992774767" + } + ] + }, + { + "address": "cosmos14m0pzuhkpjnx2esurz6kcxcjvlkcdzk7e43krz", + "coins": [ + { + "denom": "stake", + "amount": "1129565009" + } + ] + }, + { + "address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "coins": [ + { + "denom": "stake", + "amount": "3127012273" + } + ] + }, + { + "address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "coins": [ + { + "denom": "stake", + "amount": "7211269830" + } + ] + }, + { + "address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", + "coins": [ + { + "denom": "stake", + "amount": "2684018723" + } + ] + }, + { + "address": "cosmos1c4lft2m4yyrzjsxyu7nzsrxuskgtlr2crzzwwd", + "coins": [ + { + "denom": "stake", + "amount": "250959" + } + ] + }, + { + "address": "cosmos1s34kukvsrdgap0pjh0alnql7vvv9m83m2628wd", + "coins": [ + { + "denom": "stake", + "amount": "920556125" + } + ] + }, + { + "address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", + "coins": [ + { + "denom": "stake", + "amount": "2083847937" + } + ] + }, + { + "address": "cosmos1adwsqn58aype530jae9qrwknsxyf3wmwdr523z", + "coins": [ + { + "denom": "stake", + "amount": "7565995779" + } + ] + }, + { + "address": "cosmos1xq58llsgh49tsz22grs28jk0p7tvswlcjcrl32", + "coins": [ + { + "denom": "stake", + "amount": "482965302" + } + ] + }, + { + "address": "cosmos1vx0z58vgegsfc8e56jzmjtvj8cvprywvnm7l9j", + "coins": [ + { + "denom": "stake", + "amount": "5181478931" + } + ] + }, + { + "address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", + "coins": [ + { + "denom": "stake", + "amount": "2715100272" + } + ] + }, + { + "address": "cosmos14rtpks2cfh8luvywtgrry3hhycwacwtkq6hyp5", + "coins": [ + { + "denom": "stake", + "amount": "12768231969" + } + ] + }, + { + "address": "cosmos1cvhkglegj4zamjrdulawtk4rq658wnm9te6tgl", + "coins": [ + { + "denom": "stake", + "amount": "35357688089" + } + ] + }, + { + "address": "cosmos1xwjpulj30k4y0smg9krxwx80hk83r3zhs48jes", + "coins": [ + { + "denom": "stake", + "amount": "29861447258" + } + ] + }, + { + "address": "cosmos1tqk0l38afmllffqs7g3uqaanhwpksytxtgnlj2", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", + "coins": [ + { + "denom": "stake", + "amount": "3081545741" + } + ] + }, + { + "address": "cosmos1t2uupuuf6p4xr0szwsz47gn682kw64m9wmnewf", + "coins": [ + { + "denom": "stake", + "amount": "25122396271" + } + ] + }, + { + "address": "cosmos1cwk6x5smzaqhtrz95z0sf90d8a8d9vfrpaufnl", + "coins": [ + { + "denom": "stake", + "amount": "22838402464" + } + ] + }, + { + "address": "cosmos1fj43j5263mk8whetx8ru0gm4yf48xkg20txll7", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", + "coins": [ + { + "denom": "stake", + "amount": "579605250" + } + ] + }, + { + "address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", + "coins": [ + { + "denom": "stake", + "amount": "703708135" + } + ] + }, + { + "address": "cosmos1c4w30j37que0ncnss65vr40nuy7d5msegmhgs7", + "coins": [ + { + "denom": "stake", + "amount": "53752421033" + } + ] + }, + { + "address": "cosmos1mfa9me7lxg0gja78krqzv2sxqpehlgrystzdvm", + "coins": [ + { + "denom": "stake", + "amount": "11190639862" + } + ] + }, + { + "address": "cosmos1q0cw6hmrm4myx5c3zzmw6deelygsl2hrts2ju4", + "coins": [ + { + "denom": "stake", + "amount": "4998717819" + } + ] + }, + { + "address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", + "coins": [ + { + "denom": "stake", + "amount": "19714222" + } + ] + }, + { + "address": "cosmos1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcy522k3", + "coins": [ + { + "denom": "stake", + "amount": "15582790811" + } + ] + }, + { + "address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", + "coins": [ + { + "denom": "stake", + "amount": "1980570093" + } + ] + }, + { + "address": "cosmos1kkruz0zwzf7ynu5y9y40ef950f2n3jrdp0lkr2", + "coins": [ + { + "denom": "stake", + "amount": "37935548005" + } + ] + }, + { + "address": "cosmos17z26jlgg6x0hlj4qnl7pxtve270fr7teanj8gr", + "coins": [ + { + "denom": "stake", + "amount": "807560349" + } + ] + }, + { + "address": "cosmos18fkw6s4hnj2llxljrkleetgns2y0h0vjg8kmef", + "coins": [ + { + "denom": "stake", + "amount": "6124353306" + } + ] + }, + { + "address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", + "coins": [ + { + "denom": "stake", + "amount": "21429431988" + } + ] + }, + { + "address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", + "coins": [ + { + "denom": "stake", + "amount": "4061217092" + } + ] + }, + { + "address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", + "coins": [ + { + "denom": "stake", + "amount": "9441079910" + } + ] + }, + { + "address": "cosmos1c4qcdf8mqwyf7rwgkvlputdfwdfnk42lul4d5j", + "coins": [ + { + "denom": "stake", + "amount": "41262535778" + } + ] + }, + { + "address": "cosmos1tmddg4wjnj38wrd8t6xq092jyw3x4hcup6n00u", + "coins": [ + { + "denom": "stake", + "amount": "3888452114" + } + ] + }, + { + "address": "cosmos172lmu2psqlkxkthpr46h2ewjffte7lhlmwe6tg", + "coins": [ + { + "denom": "stake", + "amount": "22639210394" + } + ] + }, + { + "address": "cosmos1guuf6ntr5ujawszq99gkq2gqeevz37adzp2fmy", + "coins": [ + { + "denom": "stake", + "amount": "33283887657" + } + ] + }, + { + "address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz", + "coins": [ + { + "denom": "stake", + "amount": "984210880" + } + ] + }, + { + "address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "coins": [ + { + "denom": "stake", + "amount": "2428727543" + } + ] + }, + { + "address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", + "coins": [ + { + "denom": "stake", + "amount": "34176860650" + } + ] + }, + { + "address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv", + "coins": [ + { + "denom": "stake", + "amount": "2250782680" + } + ] + }, + { + "address": "cosmos1mn2w84lgjyemsggq7eyw8fw0wreclx0w6hfmcw", + "coins": [ + { + "denom": "stake", + "amount": "1224535795" + } + ] + }, + { + "address": "cosmos1umn8dwc5l034syha3xehk0kmjaajdfyedajtka", + "coins": [ + { + "denom": "stake", + "amount": "22588333278" + } + ] + }, + { + "address": "cosmos1f58nf9lzm4d5x9grnt3a3vd9c75szj95f6mm5s", + "coins": [ + { + "denom": "stake", + "amount": "5235315452" + } + ] + }, + { + "address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", + "coins": [ + { + "denom": "stake", + "amount": "812334416" + } + ] + }, + { + "address": "cosmos13cydnwjmscxtqtjywk9atr9uwlm6703mwtycnr", + "coins": [ + { + "denom": "stake", + "amount": "4865397260" + } + ] + }, + { + "address": "cosmos13ljukhcdmvlmaa773v3582cufv74vudsyc59x2", + "coins": [ + { + "denom": "stake", + "amount": "31405558301" + } + ] + }, + { + "address": "cosmos1awyus34e6laq3zxqsrv283w6fgn8w62zkwd87d", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", + "coins": [ + { + "denom": "stake", + "amount": "44642304123" + } + ] + }, + { + "address": "cosmos16tgzg562uhpczcma5at24uvw4a3n0u322jurd2", + "coins": [ + { + "denom": "stake", + "amount": "8100245524" + } + ] + }, + { + "address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", + "coins": [ + { + "denom": "stake", + "amount": "33112" + } + ] + }, + { + "address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", + "coins": [ + { + "denom": "stake", + "amount": "40917232533" + } + ] + }, + { + "address": "cosmos1vjm2s6e2mu4v08mluhgry9chyewhtd2cm79j5s", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", + "coins": [ + { + "denom": "stake", + "amount": "2429895018" + } + ] + }, + { + "address": "cosmos1zgsxapl5dwq6c8nf7hjn2qa7aytg0m365jhs39", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1gy49x7p6xpgdfhv8v9dh8kfgsef479cq3u8fzr", + "coins": [ + { + "denom": "stake", + "amount": "14970611115" + } + ] + }, + { + "address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", + "coins": [ + { + "denom": "stake", + "amount": "2596749133" + } + ] + }, + { + "address": "cosmos1l5vty6svhxd023rl280aqu0eqjffv0qct2kywn", + "coins": [ + { + "denom": "stake", + "amount": "19626094043" + } + ] + }, + { + "address": "cosmos10572shcaewknpzsj6nnrruww0049hnmjymva38", + "coins": [ + { + "denom": "stake", + "amount": "2354956860" + } + ] + }, + { + "address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", + "coins": [ + { + "denom": "stake", + "amount": "8309248839" + } + ] + }, + { + "address": "cosmos17m4lyrws32kta4pj2atdcc2d7z2qrwkpqk0exs", + "coins": [ + { + "denom": "stake", + "amount": "28080411530" + } + ] + }, + { + "address": "cosmos1zlu0kkfr24psuwq54mzdtt7uk7068ameyk8hug", + "coins": [ + { + "denom": "stake", + "amount": "4991758536" + } + ] + }, + { + "address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "coins": [ + { + "denom": "stake", + "amount": "61587410" + } + ] + }, + { + "address": "cosmos1dqukz2u9cssszcudyrjxzf47aeydmfardn09hw", + "coins": [ + { + "denom": "stake", + "amount": "185092657" + } + ] + }, + { + "address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", + "coins": [ + { + "denom": "stake", + "amount": "126479871" + } + ] + }, + { + "address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "coins": [ + { + "denom": "stake", + "amount": "465473874" + } + ] + }, + { + "address": "cosmos16035vhhlcxkxysgfkruk204jvw3lmyhpkn0ffv", + "coins": [ + { + "denom": "stake", + "amount": "44814425008" + } + ] + }, + { + "address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", + "coins": [ + { + "denom": "stake", + "amount": "5285120528" + } + ] + }, + { + "address": "cosmos1zu50umwgah6jhx07sw04ry0pv7fnvkpjmn8vl9", + "coins": [ + { + "denom": "stake", + "amount": "14735329246" + } + ] + }, + { + "address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", + "coins": [ + { + "denom": "stake", + "amount": "55052052" + } + ] + }, + { + "address": "cosmos1m75flstcn3hpq9am7dnvkw79e6jckkkjd59p9h", + "coins": [ + { + "denom": "stake", + "amount": "5000564275" + } + ] + }, + { + "address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", + "coins": [ + { + "denom": "stake", + "amount": "470344197" + } + ] + }, + { + "address": "cosmos1c3jzrd6ju4l55yna9pcrc49x0xkcv2hczxjw3u", + "coins": [ + { + "denom": "stake", + "amount": "19412508" + } + ] + }, + { + "address": "cosmos1tl9mmfa626vgrsz3plpr42cmeqcn2zugg523y3", + "coins": [ + { + "denom": "stake", + "amount": "1936478856" + } + ] + }, + { + "address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", + "coins": [ + { + "denom": "stake", + "amount": "151969270" + } + ] + }, + { + "address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", + "coins": [ + { + "denom": "stake", + "amount": "12914036" + } + ] + }, + { + "address": "cosmos1ecfsusjtvmp57t8n22j9vqx75g6yxdra5vk49e", + "coins": [ + { + "denom": "stake", + "amount": "3575361157" + } + ] + }, + { + "address": "cosmos1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfej3rle", + "coins": [ + { + "denom": "stake", + "amount": "222184285" + } + ] + }, + { + "address": "cosmos1f2tr8j23vqevt4hwk3073y6pvu0cgjg4jx4lja", + "coins": [ + { + "denom": "stake", + "amount": "593489894" + } + ] + }, + { + "address": "cosmos1ftwtj8rwrz4n7e9y5gnnx47g2vtxkqkg26megt", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1tczlc2ruuvetu9w9rq9ka0v7va00ye9vsyxf37", + "coins": [ + { + "denom": "stake", + "amount": "21100981667" + } + ] + }, + { + "address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", + "coins": [ + { + "denom": "stake", + "amount": "2078583112" + } + ] + }, + { + "address": "cosmos1r6j2xkpnnjve9c00c854laqp7l7zv8pxeksxrz", + "coins": [ + { + "denom": "stake", + "amount": "1177804369" + } + ] + }, + { + "address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", + "coins": [ + { + "denom": "stake", + "amount": "13173052" + } + ] + }, + { + "address": "cosmos1z7ruhrtfg8v2xv8egfyxldt2xaygspykszntzv", + "coins": [ + { + "denom": "stake", + "amount": "25229483915" + } + ] + }, + { + "address": "cosmos14q9rupnazu0mmkjd9skpn2zdfs8d0hlghzpk0v", + "coins": [ + { + "denom": "stake", + "amount": "7105221830" + } + ] + }, + { + "address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", + "coins": [ + { + "denom": "stake", + "amount": "5043425774" + } + ] + }, + { + "address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", + "coins": [ + { + "denom": "stake", + "amount": "3217088706" + } + ] + }, + { + "address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", + "coins": [ + { + "denom": "stake", + "amount": "577239654" + } + ] + }, + { + "address": "cosmos12rrjnzeppeagkvqw6d26hn03kr0uvwk4sfw6v6", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", + "coins": [ + { + "denom": "stake", + "amount": "265496713" + } + ] + }, + { + "address": "cosmos1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalavv03x7", + "coins": [ + { + "denom": "stake", + "amount": "9473536568" + } + ] + }, + { + "address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", + "coins": [ + { + "denom": "stake", + "amount": "5061824165" + } + ] + }, + { + "address": "cosmos1639hgh9ke9sxqy7kpcdcu6srk983upzjlf8mwx", + "coins": [ + { + "denom": "stake", + "amount": "90710747" + } + ] + }, + { + "address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj", + "coins": [ + { + "denom": "stake", + "amount": "1752023113" + } + ] + }, + { + "address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", + "coins": [ + { + "denom": "stake", + "amount": "6893987330" + } + ] + }, + { + "address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4", + "coins": [ + { + "denom": "stake", + "amount": "33829012498" + } + ] + }, + { + "address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", + "coins": [ + { + "denom": "stake", + "amount": "10575705008" + } + ] + }, + { + "address": "cosmos1rmyk79ktv6c8q48u78udw5p906fp0w058796d0", + "coins": [ + { + "denom": "stake", + "amount": "2574922950" + } + ] + }, + { + "address": "cosmos1gp93nsn0kdl5qhn5xn2wyqfug6uxu26sfmfal8", + "coins": [ + { + "denom": "stake", + "amount": "3590993517" + } + ] + }, + { + "address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "coins": [ + { + "denom": "stake", + "amount": "6382934181" + } + ] + }, + { + "address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "coins": [ + { + "denom": "stake", + "amount": "1514530340" + } + ] + }, + { + "address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", + "coins": [ + { + "denom": "stake", + "amount": "1822682737" + } + ] + }, + { + "address": "cosmos1wpxkfcmhsmv7d5hdzx4tw9w009fd9wwj7hv682", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos16kuse8g39wn4yzx64shrzned2lgnk0kepcuu9t", + "coins": [ + { + "denom": "stake", + "amount": "3698740868" + } + ] + }, + { + "address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", + "coins": [ + { + "denom": "stake", + "amount": "288330252" + } + ] + }, + { + "address": "cosmos1tpxdvj93x9rqz89zhh0tszegcwtq8mgtdknrw5", + "coins": [ + { + "denom": "stake", + "amount": "785132909" + } + ] + }, + { + "address": "cosmos15vf60ssrdq6fh9ln5a9wtd6f3q64sktl6vk2ss", + "coins": [ + { + "denom": "stake", + "amount": "5955548350" + } + ] + }, + { + "address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", + "coins": [ + { + "denom": "stake", + "amount": "10010539387" + } + ] + }, + { + "address": "cosmos1n0qd05zlz0pr3eajdjukezg8l2str3twyjel3y", + "coins": [ + { + "denom": "stake", + "amount": "29658748791" + } + ] + }, + { + "address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "coins": [ + { + "denom": "stake", + "amount": "9188694926" + } + ] + }, + { + "address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", + "coins": [ + { + "denom": "stake", + "amount": "17354051227" + } + ] + }, + { + "address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", + "coins": [ + { + "denom": "stake", + "amount": "11528376" + } + ] + }, + { + "address": "cosmos1xghyawtulyzs449mhe8drctaaxnmdnmkd90yx9", + "coins": [ + { + "denom": "stake", + "amount": "9048346" + } + ] + }, + { + "address": "cosmos1rlzurkn0mywyldswcafhu7r8r0tha4s5prs34u", + "coins": [ + { + "denom": "stake", + "amount": "14813638442" + } + ] + }, + { + "address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", + "coins": [ + { + "denom": "stake", + "amount": "8318226490" + } + ] + }, + { + "address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", + "coins": [ + { + "denom": "stake", + "amount": "5736725729" + } + ] + }, + { + "address": "cosmos1easmlky76c302my07gffjxjw0a2usueaw8j46t", + "coins": [ + { + "denom": "stake", + "amount": "2769785735" + } + ] + }, + { + "address": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", + "coins": [ + { + "denom": "stake", + "amount": "177937920" + } + ] + }, + { + "address": "cosmos1zcjpltwefj47au6pkrysjffvxq46a8wf4w57nm", + "coins": [ + { + "denom": "stake", + "amount": "41938020" + } + ] + }, + { + "address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "coins": [ + { + "denom": "stake", + "amount": "1577007005" + } + ] + }, + { + "address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", + "coins": [ + { + "denom": "stake", + "amount": "73137440" + } + ] + }, + { + "address": "cosmos1kj8uw44q0fh3znllyxdxr8tc05qwnswd6fv304", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1h72kkqt83nth0npqvgmardgelg6jyx7zupnypp", + "coins": [ + { + "denom": "stake", + "amount": "21817451570" + } + ] + }, + { + "address": "cosmos1m8g0mk56ne6uutj5a8drc92um8cjk9frunx8s7", + "coins": [ + { + "denom": "stake", + "amount": "38409707411" + } + ] + }, + { + "address": "cosmos1m7m72dd80k54s8vg0v5z6h334lumvj3ehn0pyp", + "coins": [ + { + "denom": "stake", + "amount": "658401630" + } + ] + }, + { + "address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", + "coins": [ + { + "denom": "stake", + "amount": "1973244" + } + ] + }, + { + "address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", + "coins": [ + { + "denom": "stake", + "amount": "9879" + } + ] + }, + { + "address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je", + "coins": [ + { + "denom": "stake", + "amount": "1001465254" + } + ] + }, + { + "address": "cosmos1yvn8kgpuuepzefm90rydcladzwwqa9agadsyus", + "coins": [ + { + "denom": "stake", + "amount": "12052924734" + } + ] + }, + { + "address": "cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r", + "coins": [ + { + "denom": "stake", + "amount": "1701273789080" + } + ] + }, + { + "address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", + "coins": [ + { + "denom": "stake", + "amount": "343667368" + } + ] + }, + { + "address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", + "coins": [ + { + "denom": "stake", + "amount": "13784753898" + } + ] + }, + { + "address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", + "coins": [ + { + "denom": "stake", + "amount": "700253" + } + ] + }, + { + "address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7", + "coins": [ + { + "denom": "stake", + "amount": "7098434145" + } + ] + }, + { + "address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", + "coins": [ + { + "denom": "stake", + "amount": "6710289974" + } + ] + }, + { + "address": "cosmos1e2jxyxe4ekjsnkzcup35r8404hxxmntmhpwsgr", + "coins": [ + { + "denom": "stake", + "amount": "28418865695" + } + ] + }, + { + "address": "cosmos1ylf26t6vhvugawg87328ng2ug4d8f25syxp64c", + "coins": [ + { + "denom": "stake", + "amount": "820767733" + } + ] + }, + { + "address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", + "coins": [ + { + "denom": "stake", + "amount": "25851543934" + } + ] + }, + { + "address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", + "coins": [ + { + "denom": "stake", + "amount": "52321903" + } + ] + }, + { + "address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933", + "coins": [ + { + "denom": "stake", + "amount": "15890553368" + } + ] + }, + { + "address": "cosmos12r0m6hwrnn0jy02tnhmk328d7p68x2rndzt0j5", + "coins": [ + { + "denom": "stake", + "amount": "4611711404" + } + ] + }, + { + "address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s", + "coins": [ + { + "denom": "stake", + "amount": "7947557169" + } + ] + }, + { + "address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "coins": [ + { + "denom": "stake", + "amount": "138366734" + } + ] + }, + { + "address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", + "coins": [ + { + "denom": "stake", + "amount": "36416170" + } + ] + }, + { + "address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", + "coins": [ + { + "denom": "stake", + "amount": "9326778513" + } + ] + }, + { + "address": "cosmos1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8kl6qt4", + "coins": [ + { + "denom": "stake", + "amount": "4737972511" + } + ] + }, + { + "address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", + "coins": [ + { + "denom": "stake", + "amount": "167692785" + } + ] + }, + { + "address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd", + "coins": [ + { + "denom": "stake", + "amount": "10253771392" + } + ] + }, + { + "address": "cosmos1lh5v2ew6gwrugasrmt9tr8dql6qnj802lqrn63", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1sgj2stu89zswe28gqh46gv8sp6reppxc9addtd", + "coins": [ + { + "denom": "stake", + "amount": "20722807717" + } + ] + }, + { + "address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "coins": [ + { + "denom": "stake", + "amount": "14246428101" + } + ] + }, + { + "address": "cosmos1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqcrj0xk", + "coins": [ + { + "denom": "stake", + "amount": "8412380461" + } + ] + }, + { + "address": "cosmos1w2vujuajxpvqtdsne0gn6j0x0y0xw3kqtj6jtu", + "coins": [ + { + "denom": "stake", + "amount": "8730523" + } + ] + }, + { + "address": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", + "coins": [ + { + "denom": "stake", + "amount": "194865147" + } + ] + }, + { + "address": "cosmos18rzc0m3vlq3cwee4tckg5grjjc02gu3dv9csx2", + "coins": [ + { + "denom": "stake", + "amount": "35656801938" + } + ] + }, + { + "address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", + "coins": [ + { + "denom": "stake", + "amount": "9613056994" + } + ] + }, + { + "address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", + "coins": [ + { + "denom": "stake", + "amount": "17112642282" + } + ] + }, + { + "address": "cosmos1n3lnhxzzm7ntheu78h6v4zag7zmrlp48tjnhf3", + "coins": [ + { + "denom": "stake", + "amount": "31263429012" + } + ] + }, + { + "address": "cosmos17nxn4xkn8mvyjl9xg3erms4y43xeazku7rw5rc", + "coins": [ + { + "denom": "stake", + "amount": "18566429002" + } + ] + }, + { + "address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "coins": [ + { + "denom": "stake", + "amount": "141354494" + } + ] + }, + { + "address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", + "coins": [ + { + "denom": "stake", + "amount": "11023158820" + } + ] + }, + { + "address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "coins": [ + { + "denom": "stake", + "amount": "4400903048" + } + ] + }, + { + "address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "coins": [ + { + "denom": "stake", + "amount": "3214796449" + } + ] + }, + { + "address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "coins": [ + { + "denom": "stake", + "amount": "142890301" + } + ] + }, + { + "address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "coins": [ + { + "denom": "stake", + "amount": "3397839" + } + ] + }, + { + "address": "cosmos1twu2lvgp3erk6gups2a8nae3jdahaj2xmlufsa", + "coins": [ + { + "denom": "stake", + "amount": "19032639271" + } + ] + }, + { + "address": "cosmos17xpfvakm2amg962yls6f84z3kell8c5lserqta", + "coins": [ + { + "denom": "stake", + "amount": "58122072521" + } + ] + }, + { + "address": "cosmos10qj9cj3dxecyu826gaw72ylwum96jkkh9p462q", + "coins": [ + { + "denom": "stake", + "amount": "9842088248" + } + ] + }, + { + "address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", + "coins": [ + { + "denom": "stake", + "amount": "705908591" + } + ] + }, + { + "address": "cosmos16v3h2mggt8tnkxp0vq5tq25fhr3knvf4jw40l5", + "coins": [ + { + "denom": "stake", + "amount": "1185875189" + } + ] + }, + { + "address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", + "coins": [ + { + "denom": "stake", + "amount": "418029002" + } + ] + }, + { + "address": "cosmos1p9wm55eaeux7v9eqf3szfqt77w70djrj7wpeh5", + "coins": [ + { + "denom": "stake", + "amount": "9462936775" + } + ] + }, + { + "address": "cosmos1vf0r0fg74jmm6qxq4dj8amhr64acs32333ua0d", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos10p78pcqm2slk4x0pfxl9ht5spskwquhzptwzt8", + "coins": [ + { + "denom": "stake", + "amount": "4402481942" + } + ] + }, + { + "address": "cosmos17g3wgr4wy0x5nv9ep2eenc2tucpulq5yjy50st", + "coins": [ + { + "denom": "stake", + "amount": "28602033597" + } + ] + }, + { + "address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", + "coins": [ + { + "denom": "stake", + "amount": "2923917158" + } + ] + }, + { + "address": "cosmos1gkdgukkcx52r2w82q2usyncf67s30g7hmqc74n", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1jhvqn320w9nqxcs3ar7250jqg7us9vuszw9cwq", + "coins": [ + { + "denom": "stake", + "amount": "3106989523" + } + ] + }, + { + "address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", + "coins": [ + { + "denom": "stake", + "amount": "1168619126" + } + ] + }, + { + "address": "cosmos1478sx3zdfylsts5sus5rlz4dgvyvacqpuchj6f", + "coins": [ + { + "denom": "stake", + "amount": "2893443077" + } + ] + }, + { + "address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "coins": [ + { + "denom": "stake", + "amount": "5201373" + } + ] + }, + { + "address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", + "coins": [ + { + "denom": "stake", + "amount": "773136739" + } + ] + }, + { + "address": "cosmos1s0r2g8pzwre6tvywfw0h8vy8qg7spd2ytfkx70", + "coins": [ + { + "denom": "stake", + "amount": "11716014580" + } + ] + }, + { + "address": "cosmos1rzuu7jf5f66jyhqjsusre7uuha0hw5e8ff7tar", + "coins": [ + { + "denom": "stake", + "amount": "2591107671" + } + ] + }, + { + "address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", + "coins": [ + { + "denom": "stake", + "amount": "12549842012" + } + ] + }, + { + "address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", + "coins": [ + { + "denom": "stake", + "amount": "3396133880" + } + ] + }, + { + "address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", + "coins": [ + { + "denom": "stake", + "amount": "1549619016" + } + ] + }, + { + "address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", + "coins": [ + { + "denom": "stake", + "amount": "5024279292" + } + ] + }, + { + "address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "coins": [ + { + "denom": "stake", + "amount": "13027420896" + } + ] + }, + { + "address": "cosmos1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpkca4g8", + "coins": [ + { + "denom": "stake", + "amount": "10045955684" + } + ] + }, + { + "address": "cosmos1hx0cc2lvfagl5q5x34qea2fc53hhr7mtgdy75v", + "coins": [ + { + "denom": "stake", + "amount": "943865159" + } + ] + }, + { + "address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", + "coins": [ + { + "denom": "stake", + "amount": "13536" + } + ] + }, + { + "address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", + "coins": [ + { + "denom": "stake", + "amount": "455288844" + } + ] + }, + { + "address": "cosmos15tv54z32xgqechywvr7ymsfdvr2mmx3553j8rd", + "coins": [ + { + "denom": "stake", + "amount": "4130788285" + } + ] + }, + { + "address": "cosmos15wqxlh0da39gzvp3x50mrju8cj7ppfgachrxd5", + "coins": [ + { + "denom": "stake", + "amount": "13821213719" + } + ] + }, + { + "address": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", + "coins": [ + { + "denom": "stake", + "amount": "23203176886" + } + ] + }, + { + "address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "coins": [ + { + "denom": "stake", + "amount": "186545734" + } + ] + }, + { + "address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "coins": [ + { + "denom": "stake", + "amount": "4079295156" + } + ] + }, + { + "address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", + "coins": [ + { + "denom": "stake", + "amount": "8027715337" + } + ] + }, + { + "address": "cosmos1h9wg5q5x4gxkkca0x7krw7953h0ce2xwr2cwl8", + "coins": [ + { + "denom": "stake", + "amount": "904432602" + } + ] + }, + { + "address": "cosmos1vuws77sz0xzvz8y0dg6wjz9fzd7plxpk29ljn7", + "coins": [ + { + "denom": "stake", + "amount": "9760097671" + } + ] + }, + { + "address": "cosmos1jn4dp0s3ewkwarqmra50czqlm6g7cf9plthphn", + "coins": [ + { + "denom": "stake", + "amount": "10580302668" + } + ] + }, + { + "address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", + "coins": [ + { + "denom": "stake", + "amount": "9940602011" + } + ] + }, + { + "address": "cosmos1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptd8zyma", + "coins": [ + { + "denom": "stake", + "amount": "5874941926" + } + ] + }, + { + "address": "cosmos1l6uepmju2xg0h8rzkx8wku0hsncargw5ruhhfz", + "coins": [ + { + "denom": "stake", + "amount": "27190014712" + } + ] + }, + { + "address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", + "coins": [ + { + "denom": "stake", + "amount": "8089075727" + } + ] + }, + { + "address": "cosmos1nky4q5h5wurtumxwsf9w79vmw3l4682879kly4", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", + "coins": [ + { + "denom": "stake", + "amount": "1001089496" + } + ] + }, + { + "address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m", + "coins": [ + { + "denom": "stake", + "amount": "3626749980" + } + ] + }, + { + "address": "cosmos1wve3m263mdhqqpg0yjd8vmveflugrk5dk2cr0z", + "coins": [ + { + "denom": "stake", + "amount": "471391328" + } + ] + }, + { + "address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", + "coins": [ + { + "denom": "stake", + "amount": "2021915876" + } + ] + }, + { + "address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "coins": [ + { + "denom": "stake", + "amount": "211489" + } + ] + }, + { + "address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", + "coins": [ + { + "denom": "stake", + "amount": "1083080420" + } + ] + }, + { + "address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "coins": [ + { + "denom": "stake", + "amount": "5594690557" + } + ] + }, + { + "address": "cosmos188yd2umzwfwen7es68wrlh6auu3p8jhz0qfgej", + "coins": [ + { + "denom": "stake", + "amount": "14023256937" + } + ] + }, + { + "address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "coins": [ + { + "denom": "stake", + "amount": "84451457" + } + ] + }, + { + "address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", + "coins": [ + { + "denom": "stake", + "amount": "60976392" + } + ] + }, + { + "address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", + "coins": [ + { + "denom": "stake", + "amount": "58207245" + } + ] + }, + { + "address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890", + "coins": [ + { + "denom": "stake", + "amount": "12623413968" + } + ] + }, + { + "address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck", + "coins": [ + { + "denom": "stake", + "amount": "11348168659" + } + ] + }, + { + "address": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", + "coins": [] + }, + { + "address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", + "coins": [ + { + "denom": "stake", + "amount": "3527416972" + } + ] + }, + { + "address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", + "coins": [ + { + "denom": "stake", + "amount": "346508892" + } + ] + }, + { + "address": "cosmos1x3u97k0k8xxxjvt2vca8fy9g3qm7wtgp8wtmqs", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos15zqzxj663h8g8naxyz324j2rpd3rnw4rvtxep2", + "coins": [ + { + "denom": "stake", + "amount": "4344890253" + } + ] + }, + { + "address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", + "coins": [ + { + "denom": "stake", + "amount": "3015097503" + } + ] + }, + { + "address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", + "coins": [ + { + "denom": "stake", + "amount": "2003384336" + } + ] + }, + { + "address": "cosmos1nqlclz6g890zaeq4gadtl82e3f9kwzp60sqrqm", + "coins": [ + { + "denom": "stake", + "amount": "43841823459" + } + ] + }, + { + "address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "coins": [ + { + "denom": "stake", + "amount": "10576644032" + } + ] + }, + { + "address": "cosmos1waql7pehyspkf8l9q04gt508c0khx0nt64jsxj", + "coins": [ + { + "denom": "stake", + "amount": "6361766617" + } + ] + }, + { + "address": "cosmos1e5zmgnq6y7zxn5c642ty3jxur3lk0n0ca4wyym", + "coins": [ + { + "denom": "stake", + "amount": "26478717" + } + ] + }, + { + "address": "cosmos1u2uakvrpv8htq6a7n29hlpxxec956caj2akqcu", + "coins": [ + { + "denom": "stake", + "amount": "322429093" + } + ] + }, + { + "address": "cosmos1yqc7yxdxgz9etrp3avxg8t6ppfm73wxnzyf360", + "coins": [ + { + "denom": "stake", + "amount": "4169687934" + } + ] + }, + { + "address": "cosmos1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75pf45v0", + "coins": [ + { + "denom": "stake", + "amount": "1740107116" + } + ] + }, + { + "address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", + "coins": [ + { + "denom": "stake", + "amount": "458431484" + } + ] + }, + { + "address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", + "coins": [ + { + "denom": "stake", + "amount": "19082873860" + } + ] + }, + { + "address": "cosmos1lvzau6mkgwnyewqvd09h307algs2ncrpp2ukjw", + "coins": [ + { + "denom": "stake", + "amount": "7284516897" + } + ] + }, + { + "address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", + "coins": [ + { + "denom": "stake", + "amount": "297213286" + } + ] + }, + { + "address": "cosmos1gtv2yjxfwhgrwrv6uag9pnqw69q0p5z8mzdddn", + "coins": [ + { + "denom": "stake", + "amount": "20436387859" + } + ] + }, + { + "address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", + "coins": [ + { + "denom": "stake", + "amount": "1723397520" + } + ] + }, + { + "address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", + "coins": [ + { + "denom": "stake", + "amount": "3240002098" + } + ] + }, + { + "address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", + "coins": [ + { + "denom": "stake", + "amount": "3027314017" + } + ] + }, + { + "address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "coins": [ + { + "denom": "stake", + "amount": "1084188767" + } + ] + }, + { + "address": "cosmos1yqt74740zamtyag7qu9naqgrauz5wdzl4290wt", + "coins": [ + { + "denom": "stake", + "amount": "17164314765" + } + ] + }, + { + "address": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", + "coins": [ + { + "denom": "stake", + "amount": "502818439" + } + ] + }, + { + "address": "cosmos15hqa5fj9sx7mjvmquhknrcxkxkeudguk9zpqqy", + "coins": [ + { + "denom": "stake", + "amount": "669796614" + } + ] + }, + { + "address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", + "coins": [ + { + "denom": "stake", + "amount": "29856017771" + } + ] + }, + { + "address": "cosmos1zjzkk7l2jalrspy6500my8v0yy6ycz7el534zw", + "coins": [ + { + "denom": "stake", + "amount": "12459892422" + } + ] + }, + { + "address": "cosmos1v9k0h7s32ujfeu777jkc7z69gctz4zwfy7q49l", + "coins": [ + { + "denom": "stake", + "amount": "93077277" + } + ] + }, + { + "address": "cosmos1kw46xpry8rw4xn0fvv84g0af2mfuhxpyd2m273", + "coins": [ + { + "denom": "stake", + "amount": "4380266755" + } + ] + }, + { + "address": "cosmos1ah3yy9ql35jh5ehykl626e848t2rrsyze8w8nz", + "coins": [ + { + "denom": "stake", + "amount": "5483503654" + } + ] + }, + { + "address": "cosmos18k4yz84xrjqvrq9u7sehvje3ax4aspcksauctw", + "coins": [ + { + "denom": "stake", + "amount": "5879019" + } + ] + }, + { + "address": "cosmos1tzgwtuyftq8f686z0d8zvyqh37la70pje3nmxt", + "coins": [ + { + "denom": "stake", + "amount": "14125018615" + } + ] + }, + { + "address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "coins": [ + { + "denom": "stake", + "amount": "17146233" + } + ] + }, + { + "address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", + "coins": [ + { + "denom": "stake", + "amount": "1315117671" + } + ] + }, + { + "address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3", + "coins": [ + { + "denom": "stake", + "amount": "4627069904" + } + ] + }, + { + "address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", + "coins": [ + { + "denom": "stake", + "amount": "1600841844" + } + ] + }, + { + "address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", + "coins": [ + { + "denom": "stake", + "amount": "541561331" + } + ] + }, + { + "address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", + "coins": [ + { + "denom": "stake", + "amount": "34022337440" + } + ] + }, + { + "address": "cosmos1kszz383fcxdtxhn3xr42hvzp8rfkaaqevxmrtf", + "coins": [ + { + "denom": "stake", + "amount": "41854155720" + } + ] + }, + { + "address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", + "coins": [ + { + "denom": "stake", + "amount": "18645308" + } + ] + }, + { + "address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", + "coins": [ + { + "denom": "stake", + "amount": "7123599859" + } + ] + }, + { + "address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", + "coins": [ + { + "denom": "stake", + "amount": "177070760" + } + ] + }, + { + "address": "cosmos1rtw2ev4xm89vaqzwc7k520jlvrvlqnevk5f53y", + "coins": [ + { + "denom": "stake", + "amount": "2608420772" + } + ] + }, + { + "address": "cosmos1f2pvewnws73u0z5wsfmv5uqudwxl6jupfm6nta", + "coins": [ + { + "denom": "stake", + "amount": "10404746182" + } + ] + }, + { + "address": "cosmos12qsn5ukkpvy0ymcsfh85yqp4paw5ew9mcg8z0y", + "coins": [ + { + "denom": "stake", + "amount": "2367482127" + } + ] + }, + { + "address": "cosmos1mcc0dq93nrt3u6hl6ju82hyw3rdfun029jx4v2", + "coins": [ + { + "denom": "stake", + "amount": "12550456573" + } + ] + }, + { + "address": "cosmos1ly9aff4ptcun94q3cs26cfzqnq59j5rw2gl89u", + "coins": [ + { + "denom": "stake", + "amount": "5402544029" + } + ] + }, + { + "address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "coins": [ + { + "denom": "stake", + "amount": "2968564765" + } + ] + }, + { + "address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "coins": [ + { + "denom": "stake", + "amount": "46901825" + } + ] + }, + { + "address": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", + "coins": [ + { + "denom": "stake", + "amount": "6915791999" + } + ] + }, + { + "address": "cosmos1864wj4twqatq54rrxl5jmfey55tmh0hvgmd9yw", + "coins": [ + { + "denom": "stake", + "amount": "12098312849" + } + ] + }, + { + "address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "coins": [ + { + "denom": "stake", + "amount": "137698291" + } + ] + }, + { + "address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", + "coins": [ + { + "denom": "stake", + "amount": "8229032300" + } + ] + }, + { + "address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", + "coins": [ + { + "denom": "stake", + "amount": "1633274510" + } + ] + }, + { + "address": "cosmos1zs6hn5hf6qxjwmvntrzwhjkgvu963d0g8hz2z8", + "coins": [ + { + "denom": "stake", + "amount": "13153702389" + } + ] + }, + { + "address": "cosmos1y2whyxm3k2mtz3j0hvjev7ztq8q0cz0vqrphgt", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1jjav2y88kx0jempjzz5jcc9y4yatkyn7xnnvsv", + "coins": [ + { + "denom": "stake", + "amount": "3403233527" + } + ] + }, + { + "address": "cosmos1w69f6s0dqsqfqq93hczddadwgeq86zr9dfmddq", + "coins": [ + { + "denom": "stake", + "amount": "1465926361" + } + ] + }, + { + "address": "cosmos1j9jq7pea9y4y7fersmc0wlk99sxj3vgdya3hm3", + "coins": [ + { + "denom": "stake", + "amount": "3142382418" + } + ] + }, + { + "address": "cosmos18037phaq40fkqdr4pxk2jajnsq8prfyyl4tzvz", + "coins": [ + { + "denom": "stake", + "amount": "20638774775" + } + ] + }, + { + "address": "cosmos1gh67zgx4f9d64ctqhtascuh87805v8yffrfytl", + "coins": [ + { + "denom": "stake", + "amount": "3970213411" + } + ] + }, + { + "address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", + "coins": [ + { + "denom": "stake", + "amount": "3724106541" + } + ] + }, + { + "address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", + "coins": [ + { + "denom": "stake", + "amount": "3591544060" + } + ] + }, + { + "address": "cosmos199mt855sp3pqqxarqyjffjgm2v6uzru4fhslp6", + "coins": [ + { + "denom": "stake", + "amount": "5450625896" + } + ] + }, + { + "address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", + "coins": [ + { + "denom": "stake", + "amount": "55502038726" + } + ] + }, + { + "address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", + "coins": [ + { + "denom": "stake", + "amount": "374888103" + } + ] + }, + { + "address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "coins": [ + { + "denom": "stake", + "amount": "2346136451" + } + ] + }, + { + "address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", + "coins": [ + { + "denom": "stake", + "amount": "5755146322" + } + ] + }, + { + "address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", + "coins": [ + { + "denom": "stake", + "amount": "70954933" + } + ] + }, + { + "address": "cosmos139yreyw4l9jthf99c896sc4q7yvx9su4a95294", + "coins": [ + { + "denom": "stake", + "amount": "14628025114" + } + ] + }, + { + "address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "coins": [ + { + "denom": "stake", + "amount": "6804551431" + } + ] + }, + { + "address": "cosmos1gwwltgyatg8yfe54447dxnyvs2nt6xxsl6lv2m", + "coins": [ + { + "denom": "stake", + "amount": "2983492148" + } + ] + }, + { + "address": "cosmos1vwgt6t9vd9heg0jwq6gk0x7egw4cmp4w79yuyy", + "coins": [ + { + "denom": "stake", + "amount": "9833589413" + } + ] + }, + { + "address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", + "coins": [ + { + "denom": "stake", + "amount": "1029471879" + } + ] + }, + { + "address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020", + "coins": [ + { + "denom": "stake", + "amount": "39989039845" + } + ] + }, + { + "address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", + "coins": [ + { + "denom": "stake", + "amount": "1416384776" + } + ] + }, + { + "address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", + "coins": [ + { + "denom": "stake", + "amount": "4553916241" + } + ] + }, + { + "address": "cosmos1884glx2vk6nxcurpf2dtjp3qgsl8zh5pm09rs0", + "coins": [ + { + "denom": "stake", + "amount": "6122315665" + } + ] + }, + { + "address": "cosmos1wvzq2f252674u3gvmqhnq8g4n6lmxedmzs0czm", + "coins": [ + { + "denom": "stake", + "amount": "860628336" + } + ] + }, + { + "address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", + "coins": [ + { + "denom": "stake", + "amount": "14328793467" + } + ] + }, + { + "address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", + "coins": [ + { + "denom": "stake", + "amount": "1003165897" + } + ] + }, + { + "address": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn", + "coins": [ + { + "denom": "stake", + "amount": "2122" + } + ] + }, + { + "address": "cosmos1nrugh7am9s584k6qlf5nxlpetarxs2csglt46w", + "coins": [ + { + "denom": "stake", + "amount": "26037870620" + } + ] + }, + { + "address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe", + "coins": [ + { + "denom": "stake", + "amount": "2271641744" + } + ] + }, + { + "address": "cosmos1qy0qwzljplfauvyhgayw6nxte2zxujh4tnq09z", + "coins": [ + { + "denom": "stake", + "amount": "2132747576" + } + ] + }, + { + "address": "cosmos1py3htj8kmztj0ecdrhcgcmet6vupr9hvlhxkwe", + "coins": [ + { + "denom": "stake", + "amount": "4384438372" + } + ] + }, + { + "address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", + "coins": [ + { + "denom": "stake", + "amount": "7709395586" + } + ] + }, + { + "address": "cosmos1vw3dl2j248ypyvvjfu7036hlup5p2gpwgvg7qd", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos10cl6sallgwf882apcyagjqa2lx4j8592cjw0gf", + "coins": [ + { + "denom": "stake", + "amount": "34250944236" + } + ] + }, + { + "address": "cosmos1jn8g39pdp9zaz750v6x7kspqv4wdfcg8dluy5p", + "coins": [ + { + "denom": "stake", + "amount": "16755478373" + } + ] + }, + { + "address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "coins": [ + { + "denom": "stake", + "amount": "22418778354" + } + ] + }, + { + "address": "cosmos1l802gyymr2zukzel8ge4ddnqdevjvhnm3g4kk9", + "coins": [ + { + "denom": "stake", + "amount": "1027195928" + } + ] + }, + { + "address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", + "coins": [ + { + "denom": "stake", + "amount": "7949579" + } + ] + }, + { + "address": "cosmos1xfqsntajat3kv06ptad8zsqacmjrsjc2sa5ajt", + "coins": [ + { + "denom": "stake", + "amount": "78640589" + } + ] + }, + { + "address": "cosmos1598m5w5wpz27dtq3er8uq2czcdvrwpffh7w03h", + "coins": [ + { + "denom": "stake", + "amount": "2414235590" + } + ] + }, + { + "address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", + "coins": [ + { + "denom": "stake", + "amount": "3865120533" + } + ] + }, + { + "address": "cosmos1syn6uv0ma6a0qn6n8gy6qrc7jdp8ghr6vva3jn", + "coins": [ + { + "denom": "stake", + "amount": "1639770002" + } + ] + }, + { + "address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", + "coins": [ + { + "denom": "stake", + "amount": "11606154318" + } + ] + }, + { + "address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", + "coins": [ + { + "denom": "stake", + "amount": "13958189098" + } + ] + }, + { + "address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", + "coins": [ + { + "denom": "stake", + "amount": "2913504903" + } + ] + }, + { + "address": "cosmos1w0050eew8g7zyvg7ap0tjhd6yzvew3ndls3v0f", + "coins": [ + { + "denom": "stake", + "amount": "25072951889" + } + ] + }, + { + "address": "cosmos19xyafr0fc2g0rvemhmruyj8ywas8qamfnps2zx", + "coins": [ + { + "denom": "stake", + "amount": "454383670" + } + ] + }, + { + "address": "cosmos1ftj05w0hmw2xxw5p7gvr258j2824qd8r2xdk9e", + "coins": [ + { + "denom": "stake", + "amount": "3832536051" + } + ] + }, + { + "address": "cosmos1x5tgg6j5hqh0swtw3wqymfdcju0mmy2uff8zee", + "coins": [ + { + "denom": "stake", + "amount": "28752766463" + } + ] + }, + { + "address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", + "coins": [ + { + "denom": "stake", + "amount": "33862899721" + } + ] + }, + { + "address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", + "coins": [ + { + "denom": "stake", + "amount": "716143736" + } + ] + }, + { + "address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", + "coins": [ + { + "denom": "stake", + "amount": "25865358094" + } + ] + }, + { + "address": "cosmos1cv6mc68xznavrjel5fth3vry84wnwjy29mqn33", + "coins": [ + { + "denom": "stake", + "amount": "5240807143" + } + ] + }, + { + "address": "cosmos16a2sxhxlq7qfvkam3afnh9y6ph2lga8fn6fyqa", + "coins": [ + { + "denom": "stake", + "amount": "31603669849" + } + ] + }, + { + "address": "cosmos1pxwj79qtf9y8jugqgf7vxwhvgd85vapq4ndldk", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1z7sj5sg2cnkg4phzrswwjkkq8p2d6434pcyv2p", + "coins": [ + { + "denom": "stake", + "amount": "86484669" + } + ] + }, + { + "address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", + "coins": [ + { + "denom": "stake", + "amount": "26173345986" + } + ] + }, + { + "address": "cosmos12q3w0j5hp023hdjafgc357hy7kkha296f4xrjf", + "coins": [ + { + "denom": "stake", + "amount": "9982960628" + } + ] + }, + { + "address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq", + "coins": [ + { + "denom": "stake", + "amount": "16211339387" + } + ] + }, + { + "address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "coins": [ + { + "denom": "stake", + "amount": "11937894506" + } + ] + }, + { + "address": "cosmos1s7e8ukt3awex0xh6qw27pramwg3hkgeqtm0nfs", + "coins": [ + { + "denom": "stake", + "amount": "240557834" + } + ] + }, + { + "address": "cosmos1tz087eh88lqkesr77yl6ys9dw95qysfqtff52a", + "coins": [ + { + "denom": "stake", + "amount": "41546208" + } + ] + }, + { + "address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", + "coins": [ + { + "denom": "stake", + "amount": "6588105820" + } + ] + }, + { + "address": "cosmos1c6afa9c3repulws30tzpsggt5jfdpc88ct47wz", + "coins": [ + { + "denom": "stake", + "amount": "7712422872" + } + ] + }, + { + "address": "cosmos18kcmwj6z3gwmsscam9f04ty3tm8std0mw0upfc", + "coins": [ + { + "denom": "stake", + "amount": "1955991522" + } + ] + }, + { + "address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", + "coins": [ + { + "denom": "stake", + "amount": "631103978" + } + ] + }, + { + "address": "cosmos13q5vwanrgz5ff2f6y07c9236xj4ergak73hgrt", + "coins": [ + { + "denom": "stake", + "amount": "5695917256" + } + ] + }, + { + "address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", + "coins": [ + { + "denom": "stake", + "amount": "1557317382" + } + ] + }, + { + "address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", + "coins": [ + { + "denom": "stake", + "amount": "875920239" + } + ] + }, + { + "address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", + "coins": [ + { + "denom": "stake", + "amount": "446950366" + } + ] + }, + { + "address": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", + "coins": [ + { + "denom": "stake", + "amount": "13493884" + } + ] + }, + { + "address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", + "coins": [ + { + "denom": "stake", + "amount": "583792995" + } + ] + }, + { + "address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", + "coins": [ + { + "denom": "stake", + "amount": "50780939059" + } + ] + }, + { + "address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "coins": [ + { + "denom": "stake", + "amount": "3566000849" + } + ] + }, + { + "address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", + "coins": [ + { + "denom": "stake", + "amount": "54091459" + } + ] + }, + { + "address": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", + "coins": [ + { + "denom": "stake", + "amount": "2932939850" + } + ] + }, + { + "address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", + "coins": [ + { + "denom": "stake", + "amount": "1772749888" + } + ] + }, + { + "address": "cosmos19deqn6g9q7mnhzg5j0qr25k9gz74pwlph5p50r", + "coins": [ + { + "denom": "stake", + "amount": "4542114326" + } + ] + }, + { + "address": "cosmos1d9m3l8khcrx0zhftehkuw67zzszf9v9le5dvrm", + "coins": [ + { + "denom": "stake", + "amount": "3202182709" + } + ] + }, + { + "address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "coins": [ + { + "denom": "stake", + "amount": "340320137" + } + ] + }, + { + "address": "cosmos16l54emw4lwhremfds2mnnlxcu06eknp8gxhgq7", + "coins": [ + { + "denom": "stake", + "amount": "21033488960" + } + ] + }, + { + "address": "cosmos1u7e0dy2dr65lfs5c2scvn9xzrntteew7lvuw7w", + "coins": [ + { + "denom": "stake", + "amount": "31932453648" + } + ] + }, + { + "address": "cosmos193pvwgxpxnd6tgz0gtyl00dq8r3ygeflnhaxpm", + "coins": [ + { + "denom": "stake", + "amount": "10058590188" + } + ] + }, + { + "address": "cosmos1tsmp448mysp6vr09f26ee7wa02vpcpppk3jgqf", + "coins": [ + { + "denom": "stake", + "amount": "1724802940" + } + ] + }, + { + "address": "cosmos1tzt5ayvd6xpwxfcsxawlleluwylr2dhl46qvw2", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1cud0s54s6cf9sl786mhjlnzhm58v5cp324fxv3", + "coins": [ + { + "denom": "stake", + "amount": "26879442501" + } + ] + }, + { + "address": "cosmos19rlals9yl7q50rfww4n70m26vna9envvsqj886", + "coins": [ + { + "denom": "stake", + "amount": "197728057" + } + ] + }, + { + "address": "cosmos1fc96780mrsxn5kgplhtna40qepjgrm9wsyly02", + "coins": [ + { + "denom": "stake", + "amount": "1913322840" + } + ] + }, + { + "address": "cosmos1jsfel7tdxv09dm4lsqesfuhlpnlhhpeh4fdl27", + "coins": [ + { + "denom": "stake", + "amount": "9320838117" + } + ] + }, + { + "address": "cosmos1tv8x2sctvryfspc68rypwrld99099hvrh8vxz6", + "coins": [ + { + "denom": "stake", + "amount": "14668985305" + } + ] + }, + { + "address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2", + "coins": [ + { + "denom": "stake", + "amount": "14360106349" + } + ] + }, + { + "address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8", + "coins": [ + { + "denom": "stake", + "amount": "11775985141" + } + ] + }, + { + "address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", + "coins": [ + { + "denom": "stake", + "amount": "6644218663" + } + ] + }, + { + "address": "cosmos1npd5ddcq5cm3q938pk02dqa4te3jnfy25c5gnn", + "coins": [ + { + "denom": "stake", + "amount": "29130561664" + } + ] + }, + { + "address": "cosmos1ng5m6spxngyne4qzce35fdg0whl0yqgv9lg9tt", + "coins": [ + { + "denom": "stake", + "amount": "22155740126" + } + ] + }, + { + "address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", + "coins": [ + { + "denom": "stake", + "amount": "331224560" + } + ] + }, + { + "address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", + "coins": [ + { + "denom": "stake", + "amount": "1110800502" + } + ] + }, + { + "address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", + "coins": [ + { + "denom": "stake", + "amount": "142237005" + } + ] + }, + { + "address": "cosmos1qp6s6vzf6l0mzeglw0a9d75h7ch4w99ahux3j2", + "coins": [ + { + "denom": "stake", + "amount": "16901189909" + } + ] + }, + { + "address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "coins": [ + { + "denom": "stake", + "amount": "21826174532" + } + ] + }, + { + "address": "cosmos1j9vhccgf8520gtz7zn5jxj9lk3nqg0wx479kwp", + "coins": [ + { + "denom": "stake", + "amount": "5655074238" + } + ] + }, + { + "address": "cosmos14urapj7e6tj2s8clcsgyat6xmkppj7nm4qtewf", + "coins": [ + { + "denom": "stake", + "amount": "13328417678" + } + ] + }, + { + "address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "coins": [ + { + "denom": "stake", + "amount": "1042766810" + } + ] + }, + { + "address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", + "coins": [ + { + "denom": "stake", + "amount": "127974117" + } + ] + }, + { + "address": "cosmos19tvzgu6dmna8qljv8ex42vpek4r2handdn09d7", + "coins": [ + { + "denom": "stake", + "amount": "11566522644" + } + ] + }, + { + "address": "cosmos1jzhlspgxp578kzg9dtvg8tm2w9k7tnmcpstzry", + "coins": [ + { + "denom": "stake", + "amount": "6243377472" + } + ] + }, + { + "address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", + "coins": [ + { + "denom": "stake", + "amount": "921394483" + } + ] + }, + { + "address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp", + "coins": [ + { + "denom": "stake", + "amount": "2311740231" + } + ] + }, + { + "address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", + "coins": [ + { + "denom": "stake", + "amount": "2357393775" + } + ] + }, + { + "address": "cosmos1a0jdqzvk078d6486vuxdr5d0yp6rglue2nh5dn", + "coins": [ + { + "denom": "stake", + "amount": "24452743711" + } + ] + }, + { + "address": "cosmos1trs75ceuvsg83y9dje9k79em4v684dm5e9ya49", + "coins": [ + { + "denom": "stake", + "amount": "7877000621" + } + ] + }, + { + "address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", + "coins": [ + { + "denom": "stake", + "amount": "13201025581" + } + ] + }, + { + "address": "cosmos17ph7nmvmxdhm687z4k5phsyd08wvsnv44emkj8", + "coins": [ + { + "denom": "stake", + "amount": "15206858159" + } + ] + }, + { + "address": "cosmos1n8ugy8hee9hnzntcr7rkyhrrkcgclg3385vkd7", + "coins": [ + { + "denom": "stake", + "amount": "7982436451" + } + ] + }, + { + "address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "coins": [ + { + "denom": "stake", + "amount": "27019742" + } + ] + }, + { + "address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", + "coins": [ + { + "denom": "stake", + "amount": "47454378" + } + ] + }, + { + "address": "cosmos147pq4rzswl76kdeyx8sc7pagf4nhjpnq2hlrh3", + "coins": [ + { + "denom": "stake", + "amount": "17684418984" + } + ] + }, + { + "address": "cosmos1k3rapsk6gmfzeugjq5w2c4msuj7t4qhat0xn4m", + "coins": [ + { + "denom": "stake", + "amount": "13530049625" + } + ] + }, + { + "address": "cosmos1hfjku50s3uhp66wuqexafzc3kl73z3xzhj5nqv", + "coins": [ + { + "denom": "stake", + "amount": "27215781841" + } + ] + }, + { + "address": "cosmos1s8c3pza7vnx7e62k94z5jgx5jqtfh7ux2wh592", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "coins": [ + { + "denom": "stake", + "amount": "2163641" + } + ] + }, + { + "address": "cosmos1vpc637uayw7rm4a48cuzuynvu9yse45me0jdmr", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos10d3vd6yx9k9ns6v82r4krm3d4ragw04cysm62c", + "coins": [ + { + "denom": "stake", + "amount": "24915840202" + } + ] + }, + { + "address": "cosmos1etrkjjjjvuej87yu2pv4mcmhjsjqsn5hm9n043", + "coins": [ + { + "denom": "stake", + "amount": "1843095100" + } + ] + }, + { + "address": "cosmos1af3ljdelv635n7yh76vvvkcs9adg6pq5z78lqn", + "coins": [ + { + "denom": "stake", + "amount": "12068688059" + } + ] + }, + { + "address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", + "coins": [ + { + "denom": "stake", + "amount": "367071745" + } + ] + }, + { + "address": "cosmos152haw4xa8p89az8fws3x38vr4cr4l5h0c5hsjx", + "coins": [ + { + "denom": "stake", + "amount": "9234762112" + } + ] + }, + { + "address": "cosmos1dgzvesl67z96ttlt5ulga25phe8pnspt663dvr", + "coins": [ + { + "denom": "stake", + "amount": "7085547226" + } + ] + }, + { + "address": "cosmos1n44p6u7280zd652tkgyxy4jg0pp0agcvw3d2wj", + "coins": [ + { + "denom": "stake", + "amount": "13495776560" + } + ] + }, + { + "address": "cosmos1hxdqddf3u8vjm080ytpe959uktn4axdas3uqhl", + "coins": [ + { + "denom": "stake", + "amount": "595606485" + } + ] + }, + { + "address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", + "coins": [ + { + "denom": "stake", + "amount": "5977131994" + } + ] + }, + { + "address": "cosmos12k9kcewq2045n20vsa0u5a9m98k4se0rxtacum", + "coins": [ + { + "denom": "stake", + "amount": "1505380496" + } + ] + }, + { + "address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", + "coins": [ + { + "denom": "stake", + "amount": "114391691" + } + ] + }, + { + "address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "coins": [ + { + "denom": "stake", + "amount": "651893789" + } + ] + }, + { + "address": "cosmos1njvscahg6cus5fy9k5gkq72cxj4kcahlgy00dj", + "coins": [ + { + "denom": "stake", + "amount": "5124489738" + } + ] + }, + { + "address": "cosmos16tr72kn90g5zl7qhyhuqkjflejz00uzlkl65sj", + "coins": [ + { + "denom": "stake", + "amount": "7529832931" + } + ] + }, + { + "address": "cosmos1mzsvp23mjrjkspddkz6nta0x7kte6a23atg6ml", + "coins": [ + { + "denom": "stake", + "amount": "73193347478" + } + ] + }, + { + "address": "cosmos1a2sgqjezvkgzc6vhvmevtsjh8m8rp52zcfu7ga", + "coins": [ + { + "denom": "stake", + "amount": "1792725655" + } + ] + }, + { + "address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", + "coins": [ + { + "denom": "stake", + "amount": "61022104396" + } + ] + }, + { + "address": "cosmos1q74af09jhrvg2ntxvcfu7pdn4zmhxyvlgahaj3", + "coins": [ + { + "denom": "stake", + "amount": "39059088148" + } + ] + }, + { + "address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", + "coins": [ + { + "denom": "stake", + "amount": "16622058656" + } + ] + }, + { + "address": "cosmos1q3mptmfxfd03myzy847p0mrssqw0sh006086eg", + "coins": [ + { + "denom": "stake", + "amount": "360539951" + } + ] + }, + { + "address": "cosmos1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lypeadd", + "coins": [ + { + "denom": "stake", + "amount": "27838378013" + } + ] + }, + { + "address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", + "coins": [ + { + "denom": "stake", + "amount": "23165226101" + } + ] + }, + { + "address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa", + "coins": [ + { + "denom": "stake", + "amount": "12139282628" + } + ] + }, + { + "address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "coins": [ + { + "denom": "stake", + "amount": "500295785" + } + ] + }, + { + "address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", + "coins": [ + { + "denom": "stake", + "amount": "431054955" + } + ] + }, + { + "address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", + "coins": [ + { + "denom": "stake", + "amount": "134472549" + } + ] + }, + { + "address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", + "coins": [ + { + "denom": "stake", + "amount": "28210417562" + } + ] + }, + { + "address": "cosmos1hq6jh5rru27mkd4c9hye0a4wkq9f9w4n4jx9zj", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1l8slnw5jukpc47xr0s76htvfftpuku2g26f0h8", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", + "coins": [ + { + "denom": "stake", + "amount": "9323619893" + } + ] + }, + { + "address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", + "coins": [ + { + "denom": "stake", + "amount": "12419255009" + } + ] + }, + { + "address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", + "coins": [ + { + "denom": "stake", + "amount": "42497870" + } + ] + }, + { + "address": "cosmos1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpdhe28d", + "coins": [ + { + "denom": "stake", + "amount": "7206783062" + } + ] + }, + { + "address": "cosmos1evqmj6ahqf76keas4ymhvf4r992kg7wrar0fru", + "coins": [ + { + "denom": "stake", + "amount": "38245684" + } + ] + }, + { + "address": "cosmos17vfaz9kp0wysnuhu9pmd9smh4x7s99dkeh8vcc", + "coins": [ + { + "denom": "stake", + "amount": "24884454210" + } + ] + }, + { + "address": "cosmos1x8z2epqz2rn6eknljym3ddjyg0z9tgtldaukjd", + "coins": [ + { + "denom": "stake", + "amount": "13021631151" + } + ] + }, + { + "address": "cosmos18gmd4r8ydls55yvgda4d8pfandk0xem5q7eat8", + "coins": [ + { + "denom": "stake", + "amount": "23002288010" + } + ] + }, + { + "address": "cosmos1ewm28x3e9t3huptgm36wnwx0zcx4aa7numjadx", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1uk8d0xdv7kdhlx3wh4pwff6v6rcx8f970fyjgm", + "coins": [ + { + "denom": "stake", + "amount": "1053780729" + } + ] + }, + { + "address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "coins": [ + { + "denom": "stake", + "amount": "2140387348" + } + ] + }, + { + "address": "cosmos17tphcpvwdr8ezywpz5qqglxul6hvx7elsl6h27", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", + "coins": [ + { + "denom": "stake", + "amount": "5337883637" + } + ] + }, + { + "address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "coins": [ + { + "denom": "stake", + "amount": "12627894956" + } + ] + }, + { + "address": "cosmos14hr55k3es7xfc54gwgu3plde0vaxkgerljee6v", + "coins": [ + { + "denom": "stake", + "amount": "694301419" + } + ] + }, + { + "address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "coins": [ + { + "denom": "stake", + "amount": "1528859698" + } + ] + }, + { + "address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "coins": [ + { + "denom": "stake", + "amount": "1758797154" + } + ] + }, + { + "address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", + "coins": [ + { + "denom": "stake", + "amount": "7921867072" + } + ] + }, + { + "address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", + "coins": [ + { + "denom": "stake", + "amount": "8605752281" + } + ] + }, + { + "address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", + "coins": [ + { + "denom": "stake", + "amount": "3065831325" + } + ] + }, + { + "address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", + "coins": [ + { + "denom": "stake", + "amount": "2831951210" + } + ] + }, + { + "address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", + "coins": [ + { + "denom": "stake", + "amount": "7327816530" + } + ] + }, + { + "address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", + "coins": [ + { + "denom": "stake", + "amount": "1434848168" + } + ] + }, + { + "address": "cosmos1kz20p7j939s8cqadmqqws80c6z93qdtyg8xt0v", + "coins": [ + { + "denom": "stake", + "amount": "20028549819" + } + ] + }, + { + "address": "cosmos1kmly2aspt8rk9h4ukdt8h52k24alvc34qukp2n", + "coins": [ + { + "denom": "stake", + "amount": "7833650880" + } + ] + }, + { + "address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", + "coins": [ + { + "denom": "stake", + "amount": "8844973181" + } + ] + }, + { + "address": "cosmos187t4e0t0xwp8ntfjkvec64kcwruph736hqxmkn", + "coins": [ + { + "denom": "stake", + "amount": "36687321731" + } + ] + }, + { + "address": "cosmos147lwcm3tx6uhtjphxwwmk7u32mucukalplv80z", + "coins": [ + { + "denom": "stake", + "amount": "275302883" + } + ] + }, + { + "address": "cosmos17fffsvdgtsagwjrc3gxqh9fkl872q40wpvajv0", + "coins": [ + { + "denom": "stake", + "amount": "421341763" + } + ] + }, + { + "address": "cosmos16adevt9lhqf3q4dwnmhty7ndr8478thakltsdj", + "coins": [ + { + "denom": "stake", + "amount": "21721083513" + } + ] + }, + { + "address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", + "coins": [ + { + "denom": "stake", + "amount": "11876" + } + ] + }, + { + "address": "cosmos1dwha0rccawlvhudcgdpzcf3eq2c0gqyzwctms8", + "coins": [ + { + "denom": "stake", + "amount": "45446416" + } + ] + }, + { + "address": "cosmos1n9dqelmmf5kfysk24m6chqfdcgz6r75u7mpuwh", + "coins": [ + { + "denom": "stake", + "amount": "3887700971" + } + ] + }, + { + "address": "cosmos16jj80c7d94m772cn77zwcuhnqcl6y95kepxvja", + "coins": [ + { + "denom": "stake", + "amount": "10668944722" + } + ] + }, + { + "address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", + "coins": [ + { + "denom": "stake", + "amount": "9832388029" + } + ] + }, + { + "address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", + "coins": [ + { + "denom": "stake", + "amount": "11246435643" + } + ] + }, + { + "address": "cosmos12gup0vvqv32z5nvdy4ycrhp77dnax5hfmcjav0", + "coins": [ + { + "denom": "stake", + "amount": "20076448050" + } + ] + }, + { + "address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", + "coins": [ + { + "denom": "stake", + "amount": "1171863518" + } + ] + }, + { + "address": "cosmos160jtaz9c35nr7dx349ezfzvs3xfdzm3mlxgulk", + "coins": [ + { + "denom": "stake", + "amount": "127938271" + } + ] + }, + { + "address": "cosmos1zc80fmnzrxu2ksxugtpa2vtkh7sstkqh6yn9de", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "coins": [ + { + "denom": "stake", + "amount": "18521342215" + } + ] + }, + { + "address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", + "coins": [ + { + "denom": "stake", + "amount": "2149842952" + } + ] + }, + { + "address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", + "coins": [ + { + "denom": "stake", + "amount": "283411585" + } + ] + }, + { + "address": "cosmos1rs7csfnnwetmd2dcjsv4p59w3t46g77lt0wq5l", + "coins": [ + { + "denom": "stake", + "amount": "48285588780" + } + ] + }, + { + "address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", + "coins": [ + { + "denom": "stake", + "amount": "3119021563" + } + ] + }, + { + "address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", + "coins": [ + { + "denom": "stake", + "amount": "1014639307" + } + ] + }, + { + "address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", + "coins": [ + { + "denom": "stake", + "amount": "61277" + } + ] + }, + { + "address": "cosmos1jf2rfeaukfmdhrd6prqdmqhcdyr8ezak8sm2wd", + "coins": [ + { + "denom": "stake", + "amount": "12131513230" + } + ] + }, + { + "address": "cosmos15cfduq92j3uvam8u942xj4egs42tjzl6p33fu5", + "coins": [ + { + "denom": "stake", + "amount": "1810883153" + } + ] + }, + { + "address": "cosmos1r572vr0k388gpjw5h2u75ppmarvgma20rqj2ws", + "coins": [ + { + "denom": "stake", + "amount": "4954848513" + } + ] + }, + { + "address": "cosmos194x33ngarpaach5g69g60cd2pjq8h0hqkfvk35", + "coins": [ + { + "denom": "stake", + "amount": "100577976" + } + ] + }, + { + "address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", + "coins": [ + { + "denom": "stake", + "amount": "3139178028" + } + ] + }, + { + "address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj", + "coins": [ + { + "denom": "stake", + "amount": "2206491530" + } + ] + }, + { + "address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", + "coins": [ + { + "denom": "stake", + "amount": "23492678" + } + ] + }, + { + "address": "cosmos1kfnt5d5fcma9kh4c5jk85yu75jer72kwdltg4s", + "coins": [ + { + "denom": "stake", + "amount": "545328955" + } + ] + }, + { + "address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", + "coins": [ + { + "denom": "stake", + "amount": "989039426" + } + ] + }, + { + "address": "cosmos1uvm96xdewfpdwymw5ywt8j5efq6jhpyl35pzg8", + "coins": [ + { + "denom": "stake", + "amount": "2028247266" + } + ] + }, + { + "address": "cosmos1ad5vqqf6lruklvkyyqvx3926cpjyn0wuz6ga64", + "coins": [ + { + "denom": "stake", + "amount": "190309901" + } + ] + }, + { + "address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", + "coins": [ + { + "denom": "stake", + "amount": "2759002567" + } + ] + }, + { + "address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", + "coins": [ + { + "denom": "stake", + "amount": "6188141939" + } + ] + }, + { + "address": "cosmos1qlkz3yutzuz0el2ullpyyaflfp78x8rr2cgld7", + "coins": [ + { + "denom": "stake", + "amount": "359577626" + } + ] + }, + { + "address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", + "coins": [ + { + "denom": "stake", + "amount": "4752910207" + } + ] + }, + { + "address": "cosmos1em3y3h4g7n8ue3wjcramnpmz0x8rwakrpjmrgz", + "coins": [ + { + "denom": "stake", + "amount": "73406829" + } + ] + }, + { + "address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", + "coins": [ + { + "denom": "stake", + "amount": "10502290701" + } + ] + }, + { + "address": "cosmos1kwqgs5v74u9wvxjerktm4mkaxqn4w7z3u6w6pq", + "coins": [ + { + "denom": "stake", + "amount": "2424925855" + } + ] + }, + { + "address": "cosmos1h6j4lyvuenmz9m7vq3hler8j7pg5ldpet0xf9a", + "coins": [ + { + "denom": "stake", + "amount": "28535343317" + } + ] + }, + { + "address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", + "coins": [ + { + "denom": "stake", + "amount": "24381789165" + } + ] + }, + { + "address": "cosmos147xrqy22fnlj0ksdjlhsh5u6hz55sjn5hzzvfh", + "coins": [ + { + "denom": "stake", + "amount": "1058842774" + } + ] + }, + { + "address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", + "coins": [ + { + "denom": "stake", + "amount": "551130155" + } + ] + }, + { + "address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", + "coins": [ + { + "denom": "stake", + "amount": "61560613" + } + ] + }, + { + "address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "coins": [ + { + "denom": "stake", + "amount": "4026291" + } + ] + }, + { + "address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", + "coins": [ + { + "denom": "stake", + "amount": "1039738" + } + ] + }, + { + "address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q", + "coins": [ + { + "denom": "stake", + "amount": "12163997562" + } + ] + }, + { + "address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", + "coins": [ + { + "denom": "stake", + "amount": "11128004217" + } + ] + }, + { + "address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", + "coins": [ + { + "denom": "stake", + "amount": "3507712328" + } + ] + }, + { + "address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", + "coins": [ + { + "denom": "stake", + "amount": "27529553561" + } + ] + }, + { + "address": "cosmos1fxdty0drndqphzcpq7v3jz3hhwp0sdhdatraf6", + "coins": [ + { + "denom": "stake", + "amount": "20001818225" + } + ] + }, + { + "address": "cosmos12vzdkp2z75x4paa9nf0dvg638l92n5s8e0jk0w", + "coins": [ + { + "denom": "stake", + "amount": "20801357125" + } + ] + }, + { + "address": "cosmos1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lpz963de", + "coins": [ + { + "denom": "stake", + "amount": "1429773802" + } + ] + }, + { + "address": "cosmos1uuk9ewj0532rzlhlg86tserdxvtnm3kq2k2zww", + "coins": [ + { + "denom": "stake", + "amount": "644193916" + } + ] + }, + { + "address": "cosmos19lvag94alj6tknd5jxjku46qq330x9r5aa7h6s", + "coins": [ + { + "denom": "stake", + "amount": "42342776905" + } + ] + }, + { + "address": "cosmos1f7utq63ae24m6aqw4metxjrc5q76j8h4gcgaxd", + "coins": [ + { + "denom": "stake", + "amount": "1393248722" + } + ] + }, + { + "address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", + "coins": [ + { + "denom": "stake", + "amount": "19721038" + } + ] + }, + { + "address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", + "coins": [ + { + "denom": "stake", + "amount": "9401621322" + } + ] + }, + { + "address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", + "coins": [ + { + "denom": "stake", + "amount": "8576833381" + } + ] + }, + { + "address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", + "coins": [ + { + "denom": "stake", + "amount": "823655" + } + ] + }, + { + "address": "cosmos1sr6u63sxsprpzv7tedc7e88tn6elrxkjnucszy", + "coins": [ + { + "denom": "stake", + "amount": "3225288403" + } + ] + }, + { + "address": "cosmos1sjhhg2yl2cqszte7pjyrp6lx5tg383lrpjyq0m", + "coins": [ + { + "denom": "stake", + "amount": "25389421762" + } + ] + }, + { + "address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "coins": [ + { + "denom": "stake", + "amount": "7865597657" + } + ] + }, + { + "address": "cosmos16e0y65dxvzn3zqlpql9uc3cmc3adtv8f9gf9ue", + "coins": [ + { + "denom": "stake", + "amount": "15075446352" + } + ] + }, + { + "address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", + "coins": [ + { + "denom": "stake", + "amount": "6642484481" + } + ] + }, + { + "address": "cosmos18xzukww2e9ufj2ae0ath48ul8ycfyv9nq7h362", + "coins": [ + { + "denom": "stake", + "amount": "15999936900" + } + ] + }, + { + "address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", + "coins": [ + { + "denom": "stake", + "amount": "4255284411" + } + ] + }, + { + "address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", + "coins": [ + { + "denom": "stake", + "amount": "1953341917" + } + ] + }, + { + "address": "cosmos179c5a9235h4z7h56gz9dhrj6gyaugvxmjt2e63", + "coins": [ + { + "denom": "stake", + "amount": "23777332675" + } + ] + }, + { + "address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", + "coins": [ + { + "denom": "stake", + "amount": "5054450035" + } + ] + }, + { + "address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", + "coins": [ + { + "denom": "stake", + "amount": "30525650362" + } + ] + }, + { + "address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", + "coins": [ + { + "denom": "stake", + "amount": "22351820978" + } + ] + }, + { + "address": "cosmos10ajx4nktldvyukmjdrx876mmwazd5sz860eu6p", + "coins": [ + { + "denom": "stake", + "amount": "3882498718" + } + ] + }, + { + "address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", + "coins": [ + { + "denom": "stake", + "amount": "1922556915" + } + ] + }, + { + "address": "cosmos1z9ns26y62x3qd3d8vs9eyxk8ndssa6gxtv2c06", + "coins": [ + { + "denom": "stake", + "amount": "15043703340" + } + ] + }, + { + "address": "cosmos1xfps7nht3lsfdzp092ast50aev4nhkaxtf7gh7", + "coins": [ + { + "denom": "stake", + "amount": "20251375850" + } + ] + }, + { + "address": "cosmos1zxpp6x3x0p0gcuuazft5ycgrxsa5wwsgl854uk", + "coins": [ + { + "denom": "stake", + "amount": "1631996648" + } + ] + }, + { + "address": "cosmos1hvfg35av2nfcjvx8ks035jk66dzvfvl24twzza", + "coins": [ + { + "denom": "stake", + "amount": "1576780179" + } + ] + }, + { + "address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", + "coins": [ + { + "denom": "stake", + "amount": "1281070152" + } + ] + }, + { + "address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", + "coins": [ + { + "denom": "stake", + "amount": "11266155" + } + ] + }, + { + "address": "cosmos16p0aw2u5chfc470xkpc6vasz5ys9smqcx40qq9", + "coins": [ + { + "denom": "stake", + "amount": "10339121952" + } + ] + }, + { + "address": "cosmos16x5vyv6aej2868kn56wpxpgzhvtvyegpjpwecw", + "coins": [ + { + "denom": "stake", + "amount": "23784644284" + } + ] + }, + { + "address": "cosmos1rrahhju34rdpmlnaww9r5egq0su2u6f44eve27", + "coins": [ + { + "denom": "stake", + "amount": "1551611997" + } + ] + }, + { + "address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2", + "coins": [ + { + "denom": "stake", + "amount": "3221334257" + } + ] + }, + { + "address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", + "coins": [ + { + "denom": "stake", + "amount": "4365311519" + } + ] + }, + { + "address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", + "coins": [ + { + "denom": "stake", + "amount": "9857714467" + } + ] + }, + { + "address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", + "coins": [ + { + "denom": "stake", + "amount": "31368808" + } + ] + }, + { + "address": "cosmos1yrdtzqfkyum94q4v3j3xllrtf09qv0jvympw86", + "coins": [ + { + "denom": "stake", + "amount": "4328892937" + } + ] + }, + { + "address": "cosmos1wc5kgetgqtfmjz9v87d9epwhlne2we0lzd8qn6", + "coins": [ + { + "denom": "stake", + "amount": "35933769064" + } + ] + }, + { + "address": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", + "coins": [ + { + "denom": "stake", + "amount": "15016694434" + } + ] + }, + { + "address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "coins": [ + { + "denom": "stake", + "amount": "410472665" + } + ] + }, + { + "address": "cosmos1528cn79dzm0p5tgyaclsdcuav6qetanhx9dwum", + "coins": [ + { + "denom": "stake", + "amount": "17147154252" + } + ] + }, + { + "address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", + "coins": [ + { + "denom": "stake", + "amount": "781544314" + } + ] + }, + { + "address": "cosmos1y78hvz86672la4agrx7n6lcmgjfgegpkldazmd", + "coins": [ + { + "denom": "stake", + "amount": "339240948" + } + ] + }, + { + "address": "cosmos1vqm5fdsflvnee33gk3d5pz7j6tf6dsp28eemcq", + "coins": [ + { + "denom": "stake", + "amount": "14819060916" + } + ] + }, + { + "address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", + "coins": [ + { + "denom": "stake", + "amount": "1859040" + } + ] + }, + { + "address": "cosmos1kueuhkfx5cvcuakpfd62y9kzxw3unlef07g2u4", + "coins": [ + { + "denom": "stake", + "amount": "3746927" + } + ] + }, + { + "address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", + "coins": [ + { + "denom": "stake", + "amount": "9392382967" + } + ] + }, + { + "address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", + "coins": [ + { + "denom": "stake", + "amount": "1088681889" + } + ] + }, + { + "address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", + "coins": [ + { + "denom": "stake", + "amount": "14613518005" + } + ] + }, + { + "address": "cosmos1y3h72de80x06cz7fs3adwlnp0r8pjazw0r5707", + "coins": [ + { + "denom": "stake", + "amount": "36598136941" + } + ] + }, + { + "address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", + "coins": [ + { + "denom": "stake", + "amount": "10603713098" + } + ] + }, + { + "address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", + "coins": [ + { + "denom": "stake", + "amount": "968687494" + } + ] + }, + { + "address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", + "coins": [ + { + "denom": "stake", + "amount": "19563719776" + } + ] + }, + { + "address": "cosmos1jp8nnep04hdcxckh0hg4knp4fu4zmzkycwwexl", + "coins": [ + { + "denom": "stake", + "amount": "4560932826" + } + ] + }, + { + "address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266", + "coins": [ + { + "denom": "stake", + "amount": "24996066132" + } + ] + }, + { + "address": "cosmos1tftatt0lp0v59qqf449pdqar8w3yj7n7xa7sk6", + "coins": [ + { + "denom": "stake", + "amount": "15102303619" + } + ] + }, + { + "address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "coins": [ + { + "denom": "stake", + "amount": "3457064927" + } + ] + }, + { + "address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", + "coins": [ + { + "denom": "stake", + "amount": "774827725" + } + ] + }, + { + "address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", + "coins": [ + { + "denom": "stake", + "amount": "151529598" + } + ] + }, + { + "address": "cosmos1cwl6ck677m959vqnjhyynnlpx4n3keh5ujzmm7", + "coins": [ + { + "denom": "stake", + "amount": "18040873849" + } + ] + }, + { + "address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", + "coins": [ + { + "denom": "stake", + "amount": "1502777217" + } + ] + }, + { + "address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", + "coins": [ + { + "denom": "stake", + "amount": "1978902837" + } + ] + }, + { + "address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "coins": [ + { + "denom": "stake", + "amount": "1199336" + } + ] + }, + { + "address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7", + "coins": [ + { + "denom": "stake", + "amount": "309209" + } + ] + }, + { + "address": "cosmos1v9frpsrct2tplfv0r2en28wh8le3f9chavr65w", + "coins": [ + { + "denom": "stake", + "amount": "6097231892" + } + ] + }, + { + "address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", + "coins": [ + { + "denom": "stake", + "amount": "37857485623" + } + ] + }, + { + "address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", + "coins": [ + { + "denom": "stake", + "amount": "10730741844" + } + ] + }, + { + "address": "cosmos1qdzgpyxu8cev4wjz9e567nfdlc2cru8ygy9gz7", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", + "coins": [ + { + "denom": "stake", + "amount": "2510139919" + } + ] + }, + { + "address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", + "coins": [ + { + "denom": "stake", + "amount": "6805326386" + } + ] + }, + { + "address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", + "coins": [ + { + "denom": "stake", + "amount": "294034819" + } + ] + }, + { + "address": "cosmos19ehwyhhnu55mw9d96929sus947zw6eee4ue38p", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos10g2yfqkuyaxgyyj7hhyswh8cmhplvpanrc9tya", + "coins": [ + { + "denom": "stake", + "amount": "24614990370" + } + ] + }, + { + "address": "cosmos1n5qqy42c6su9dv0tjpt3867mu7sdfhz6juqdns", + "coins": [ + { + "denom": "stake", + "amount": "24393251830" + } + ] + }, + { + "address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", + "coins": [ + { + "denom": "stake", + "amount": "801274747" + } + ] + }, + { + "address": "cosmos1556dzhyv2gth4huxdlyur65c2sm3np2en3zzhl", + "coins": [ + { + "denom": "stake", + "amount": "33380032930" + } + ] + }, + { + "address": "cosmos1xychruegs8u4cd4s3l7tkcc23ev90zydd4n92v", + "coins": [ + { + "denom": "stake", + "amount": "35623599941" + } + ] + }, + { + "address": "cosmos1vtqnkp3uat764qv4z02qwc7ysnre8q9ph5kklc", + "coins": [ + { + "denom": "stake", + "amount": "164155157" + } + ] + }, + { + "address": "cosmos13yzpngckxvtky2k25j60qxlkekx0jfau4pjhzn", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos130kk7kw4kx7rfrq9sa4k673zqt3nf6s4l3a0lg", + "coins": [ + { + "denom": "stake", + "amount": "6577769472" + } + ] + }, + { + "address": "cosmos1jsd99e3zfrxrr3nh057u0tvmu0847zkr29f28v", + "coins": [ + { + "denom": "stake", + "amount": "4311765981" + } + ] + }, + { + "address": "cosmos1uwx5cecec8v2af2mdrq3p6gv9gtv4gza5006gx", + "coins": [ + { + "denom": "stake", + "amount": "6919258491" + } + ] + }, + { + "address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a", + "coins": [ + { + "denom": "stake", + "amount": "3305932443" + } + ] + }, + { + "address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", + "coins": [ + { + "denom": "stake", + "amount": "1019468067" + } + ] + }, + { + "address": "cosmos1ax56w233q9c43whd6sdy52v2qhuc8lpjs7gks5", + "coins": [ + { + "denom": "stake", + "amount": "26966405541" + } + ] + }, + { + "address": "cosmos19stzlsklhmx4akvnq7s2jvl828hrt6zdm6dhys", + "coins": [ + { + "denom": "stake", + "amount": "27984308200" + } + ] + }, + { + "address": "cosmos1x4u73wvuayr5w5gfs96jak2nrs3k4r96tknr63", + "coins": [ + { + "denom": "stake", + "amount": "135998804" + } + ] + }, + { + "address": "cosmos1pmjfpv056kk3jk3qfljph9fthrvqtufxe3nwml", + "coins": [ + { + "denom": "stake", + "amount": "19107557733" + } + ] + }, + { + "address": "cosmos1280ce9aj6ezeduu5adlery5cjmd4fy7yfe4s35", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", + "coins": [ + { + "denom": "stake", + "amount": "3027665244" + } + ] + }, + { + "address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", + "coins": [ + { + "denom": "stake", + "amount": "24981208248" + } + ] + }, + { + "address": "cosmos1p9lzwaw02vs55dglhdr3dldmkwgm4km9shedwl", + "coins": [ + { + "denom": "stake", + "amount": "2968133111" + } + ] + }, + { + "address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", + "coins": [ + { + "denom": "stake", + "amount": "18603946" + } + ] + }, + { + "address": "cosmos1ndjmq7ee0g2lmxrx5q0npcmv64km6hysk0qnvn", + "coins": [ + { + "denom": "stake", + "amount": "55535446132" + } + ] + }, + { + "address": "cosmos16erf80gpn7xquce9qmk2uzf4lzdgcgc55ra2y3", + "coins": [ + { + "denom": "stake", + "amount": "5611558468" + } + ] + }, + { + "address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", + "coins": [ + { + "denom": "stake", + "amount": "141333776" + } + ] + }, + { + "address": "cosmos1g04020ghngvh7lj8hmhequs5a83ly7xxyh0q8w", + "coins": [ + { + "denom": "stake", + "amount": "921362709" + } + ] + }, + { + "address": "cosmos1gayzja3zz6unep8ftnpunt2wefazs3jhunl5az", + "coins": [ + { + "denom": "stake", + "amount": "48171207067" + } + ] + }, + { + "address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", + "coins": [ + { + "denom": "stake", + "amount": "2502916665" + } + ] + }, + { + "address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", + "coins": [ + { + "denom": "stake", + "amount": "2985774735" + } + ] + }, + { + "address": "cosmos13acm7994qxzmemx0fekg6s3qtagck36erqgsz8", + "coins": [ + { + "denom": "stake", + "amount": "1972532706" + } + ] + }, + { + "address": "cosmos1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0ajhqc7", + "coins": [ + { + "denom": "stake", + "amount": "6151241715" + } + ] + }, + { + "address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", + "coins": [ + { + "denom": "stake", + "amount": "18456403012" + } + ] + }, + { + "address": "cosmos1jakgqseuh502xcapt7ctxtwaz2w4xyh7kdqqw4", + "coins": [ + { + "denom": "stake", + "amount": "23637058873" + } + ] + }, + { + "address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", + "coins": [ + { + "denom": "stake", + "amount": "3841368367" + } + ] + }, + { + "address": "cosmos12eynrdzx2jqz5u92hgmhl9ga6hmghqfv0xvns8", + "coins": [ + { + "denom": "stake", + "amount": "16243090694" + } + ] + }, + { + "address": "cosmos1tzz5l8sw05e0tm5l0gxuvp04qt42stu3kqwf4s", + "coins": [ + { + "denom": "stake", + "amount": "13054348071" + } + ] + }, + { + "address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", + "coins": [ + { + "denom": "stake", + "amount": "5014095229" + } + ] + }, + { + "address": "cosmos1zah0g92ytwdvpchd3sceuanu7knhtu224vnt5k", + "coins": [ + { + "denom": "stake", + "amount": "51545993844" + } + ] + }, + { + "address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", + "coins": [ + { + "denom": "stake", + "amount": "5237961578" + } + ] + }, + { + "address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "coins": [ + { + "denom": "stake", + "amount": "44696513" + } + ] + }, + { + "address": "cosmos1q6eeennfulay5kz3lym38up6gq5ruf6h43cg94", + "coins": [ + { + "denom": "stake", + "amount": "4252349067" + } + ] + }, + { + "address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", + "coins": [ + { + "denom": "stake", + "amount": "7449763865" + } + ] + }, + { + "address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", + "coins": [ + { + "denom": "stake", + "amount": "14140469266" + } + ] + }, + { + "address": "cosmos1e87dgtw7cd28mt4mm3s4uaaxpapanexw9grzmg", + "coins": [ + { + "denom": "stake", + "amount": "18606905180" + } + ] + }, + { + "address": "cosmos1znvq8jqpwxt5hk2lg5654l7eg7kap3rpgjm462", + "coins": [ + { + "denom": "stake", + "amount": "17067668238" + } + ] + }, + { + "address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", + "coins": [ + { + "denom": "stake", + "amount": "1331425207" + } + ] + }, + { + "address": "cosmos14t66r5m6p8n9egwdxs45ljca5p4hra74vyz9j0", + "coins": [ + { + "denom": "stake", + "amount": "685719243" + } + ] + }, + { + "address": "cosmos174ycyhzg358nxm8r6qunzsyx48uk8fc404ckyf", + "coins": [ + { + "denom": "stake", + "amount": "1127546373" + } + ] + }, + { + "address": "cosmos1f09q88gqlava96kfz8xljgtj02rt4tmcpap5ya", + "coins": [ + { + "denom": "stake", + "amount": "25130539762" + } + ] + }, + { + "address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", + "coins": [ + { + "denom": "stake", + "amount": "10915226754" + } + ] + }, + { + "address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr", + "coins": [ + { + "denom": "stake", + "amount": "13311318969" + } + ] + }, + { + "address": "cosmos1kjupa2w6rlhzj9fjxz35m02g2wpz790fd6mf0j", + "coins": [ + { + "denom": "stake", + "amount": "2225633861" + } + ] + }, + { + "address": "cosmos1kum8rm8vqscd4zafpt39uhsdmcsdcxmrg7znxy", + "coins": [ + { + "denom": "stake", + "amount": "31768080506" + } + ] + }, + { + "address": "cosmos1wwp7j40k9xffj757s4uurkcegskfwq25ef268l", + "coins": [ + { + "denom": "stake", + "amount": "28727597" + } + ] + }, + { + "address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", + "coins": [ + { + "denom": "stake", + "amount": "13265228491" + } + ] + }, + { + "address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", + "coins": [ + { + "denom": "stake", + "amount": "1144205311" + } + ] + }, + { + "address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", + "coins": [ + { + "denom": "stake", + "amount": "3096486333" + } + ] + }, + { + "address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", + "coins": [ + { + "denom": "stake", + "amount": "592403678" + } + ] + }, + { + "address": "cosmos12zkyjh3kjyz2ka0z7lskxqxhvtmgg2pzg8gn96", + "coins": [ + { + "denom": "stake", + "amount": "38168134584" + } + ] + }, + { + "address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", + "coins": [ + { + "denom": "stake", + "amount": "8685542905" + } + ] + }, + { + "address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", + "coins": [ + { + "denom": "stake", + "amount": "614858577" + } + ] + }, + { + "address": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", + "coins": [ + { + "denom": "stake", + "amount": "24713958645" + } + ] + }, + { + "address": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh", + "coins": [ + { + "denom": "stake", + "amount": "7451760474987" + } + ] + }, + { + "address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", + "coins": [ + { + "denom": "stake", + "amount": "25075256975" + } + ] + }, + { + "address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", + "coins": [ + { + "denom": "stake", + "amount": "4709844" + } + ] + }, + { + "address": "cosmos1g95xvy8qgzcvcl05fse0mpxzdfv3w88tpexycr", + "coins": [ + { + "denom": "stake", + "amount": "46109502274" + } + ] + }, + { + "address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "coins": [ + { + "denom": "stake", + "amount": "126603894" + } + ] + }, + { + "address": "cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl", + "coins": [ + { + "denom": "stake", + "amount": "10636092320837" + } + ] + }, + { + "address": "cosmos1hwt3fl2gylwdechqwq8uhmhsl04gn6ksw6lxlt", + "coins": [ + { + "denom": "stake", + "amount": "27595896946" + } + ] + }, + { + "address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", + "coins": [ + { + "denom": "stake", + "amount": "434029796" + } + ] + }, + { + "address": "cosmos1r35ejcqcmv94r87zwrx4xngsutjppj3yx280jm", + "coins": [ + { + "denom": "stake", + "amount": "23876053127" + } + ] + }, + { + "address": "cosmos1yj95f65syc75ptwcy0n7kafdq33awc2ve8hthq", + "coins": [ + { + "denom": "stake", + "amount": "197534165" + } + ] + }, + { + "address": "cosmos17eadsw26t8798nfaw2uq6rnmfw6tn3u7np2yfs", + "coins": [ + { + "denom": "stake", + "amount": "649055481" + } + ] + }, + { + "address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", + "coins": [ + { + "denom": "stake", + "amount": "30018322160" + } + ] + }, + { + "address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", + "coins": [ + { + "denom": "stake", + "amount": "85922675" + } + ] + }, + { + "address": "cosmos1h84c3yuxd6k7950wh868tcsj5tmvzetykv8lld", + "coins": [ + { + "denom": "stake", + "amount": "1925488935" + } + ] + }, + { + "address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", + "coins": [ + { + "denom": "stake", + "amount": "25275217992" + } + ] + }, + { + "address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", + "coins": [ + { + "denom": "stake", + "amount": "3938913881" + } + ] + }, + { + "address": "cosmos1af6mnuvcs8ypz2272x4vhdw9dkc25ac87z04l8", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "coins": [ + { + "denom": "stake", + "amount": "3517756820" + } + ] + }, + { + "address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", + "coins": [ + { + "denom": "stake", + "amount": "9081001" + } + ] + }, + { + "address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "coins": [ + { + "denom": "stake", + "amount": "1266537330" + } + ] + }, + { + "address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", + "coins": [ + { + "denom": "stake", + "amount": "54644876" + } + ] + }, + { + "address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "coins": [ + { + "denom": "stake", + "amount": "1470032177" + } + ] + }, + { + "address": "cosmos12362v43p57f8dgc2dx396rpanj24j67pkcvy2h", + "coins": [ + { + "denom": "stake", + "amount": "2349145013" + } + ] + }, + { + "address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", + "coins": [ + { + "denom": "stake", + "amount": "1412129641" + } + ] + }, + { + "address": "cosmos1jsgcz2u9tgrn3j49t2xg4er3hjhnryzr6w9dqs", + "coins": [ + { + "denom": "stake", + "amount": "3557165086" + } + ] + }, + { + "address": "cosmos1rhc7hrsjmzlqfz4n400j53ztytqafe9qqqq38l", + "coins": [ + { + "denom": "stake", + "amount": "2886829405" + } + ] + }, + { + "address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", + "coins": [ + { + "denom": "stake", + "amount": "26635567" + } + ] + }, + { + "address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "coins": [ + { + "denom": "stake", + "amount": "1609436526" + } + ] + }, + { + "address": "cosmos1vwja3gc3e37f8fkddj38gp74cs7sccnf4zs509", + "coins": [ + { + "denom": "stake", + "amount": "17423311338" + } + ] + }, + { + "address": "cosmos1kl0sk9crf0ru82ejpk8a7zexp2kudszsug5u8z", + "coins": [ + { + "denom": "stake", + "amount": "1822019848" + } + ] + }, + { + "address": "cosmos1uptqu7jt4krnqwlx98nlxs5fg2a0fncvpyhptj", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", + "coins": [ + { + "denom": "stake", + "amount": "7245367" + } + ] + }, + { + "address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "coins": [ + { + "denom": "stake", + "amount": "728194424" + } + ] + }, + { + "address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", + "coins": [ + { + "denom": "stake", + "amount": "9493124191" + } + ] + }, + { + "address": "cosmos135e4v2rg4uz2767zhtdksls7n0s5eleunwdxyx", + "coins": [ + { + "denom": "stake", + "amount": "31122584481" + } + ] + }, + { + "address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", + "coins": [ + { + "denom": "stake", + "amount": "591338" + } + ] + }, + { + "address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", + "coins": [ + { + "denom": "stake", + "amount": "5430059367" + } + ] + }, + { + "address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", + "coins": [ + { + "denom": "stake", + "amount": "24315459129" + } + ] + }, + { + "address": "cosmos1f7wpuyc6ehg8p8rxag43j8fyfaur3jy0ujhs2t", + "coins": [ + { + "denom": "stake", + "amount": "17632090654" + } + ] + }, + { + "address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", + "coins": [ + { + "denom": "stake", + "amount": "18518242703" + } + ] + }, + { + "address": "cosmos1ledlljk33qdj6z6lssp3w88cq2q38kg0j4vrvc", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1n0f0kcjjwrjqvva5wq6x5nj0c45vddc2rr29k3", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1haw8fcay84fjlsdl5cyev275ldj30z3r27m0g5", + "coins": [ + { + "denom": "stake", + "amount": "3067646060" + } + ] + }, + { + "address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn", + "coins": [ + { + "denom": "stake", + "amount": "3328430106" + } + ] + }, + { + "address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", + "coins": [ + { + "denom": "stake", + "amount": "85023275" + } + ] + }, + { + "address": "cosmos1tcaxfulvlrwt9ua2f4hrfpx6wvymwxksnurv3m", + "coins": [ + { + "denom": "stake", + "amount": "948265452" + } + ] + }, + { + "address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", + "coins": [ + { + "denom": "stake", + "amount": "45493045207" + } + ] + }, + { + "address": "cosmos1250k2ymtkl6hf0ty6syhkxft33v580fhmr25qc", + "coins": [ + { + "denom": "stake", + "amount": "1303498572" + } + ] + }, + { + "address": "cosmos1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxx7jqef", + "coins": [ + { + "denom": "stake", + "amount": "25308053792" + } + ] + }, + { + "address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", + "coins": [ + { + "denom": "stake", + "amount": "68519453" + } + ] + }, + { + "address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "coins": [ + { + "denom": "stake", + "amount": "155891306" + } + ] + }, + { + "address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", + "coins": [ + { + "denom": "stake", + "amount": "1736204" + } + ] + }, + { + "address": "cosmos1zyz0twnwwk26pwn3w83d2lj7rda7lfr5d0m64v", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1d0dq8hxzyywrcx73v4z44e8p8685znzml58dg2", + "coins": [ + { + "denom": "stake", + "amount": "1979969851" + } + ] + }, + { + "address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "coins": [ + { + "denom": "stake", + "amount": "7975333120" + } + ] + }, + { + "address": "cosmos15uqsf4wke3ylyp0elnka2rvaefhsmhgjhe5mxf", + "coins": [ + { + "denom": "stake", + "amount": "15786431671" + } + ] + }, + { + "address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "coins": [ + { + "denom": "stake", + "amount": "10654006660" + } + ] + }, + { + "address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", + "coins": [ + { + "denom": "stake", + "amount": "1221309903" + } + ] + }, + { + "address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", + "coins": [ + { + "denom": "stake", + "amount": "17104878021" + } + ] + }, + { + "address": "cosmos1zzca9hed282xcq9s7v69ysyyjls42ppxp37ywc", + "coins": [ + { + "denom": "stake", + "amount": "2490547529" + } + ] + }, + { + "address": "cosmos1xenmhldpnwfl0x8ze8qvu2qc4v58zr7qkz73sz", + "coins": [ + { + "denom": "stake", + "amount": "794583091" + } + ] + }, + { + "address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "coins": [ + { + "denom": "stake", + "amount": "16367605958" + } + ] + }, + { + "address": "cosmos1hksxwc7h56mzm9evkpyg9hevlj94g5v003rs9w", + "coins": [ + { + "denom": "stake", + "amount": "6770746100" + } + ] + }, + { + "address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "coins": [ + { + "denom": "stake", + "amount": "92751494" + } + ] + }, + { + "address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", + "coins": [ + { + "denom": "stake", + "amount": "1675071889" + } + ] + }, + { + "address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", + "coins": [ + { + "denom": "stake", + "amount": "3730204294" + } + ] + }, + { + "address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", + "coins": [ + { + "denom": "stake", + "amount": "1773197688" + } + ] + }, + { + "address": "cosmos1m6y73jlmfnl8ywzrjggruy4nfk8hkgnwve5t8x", + "coins": [ + { + "denom": "stake", + "amount": "5538425359" + } + ] + }, + { + "address": "cosmos1nutj5al03vv5r46uawslcg4mq696v2m48allaa", + "coins": [ + { + "denom": "stake", + "amount": "10803626345" + } + ] + }, + { + "address": "cosmos1kjkf4umv6g2pperq6g74mayntlrp4a7xypuvmr", + "coins": [ + { + "denom": "stake", + "amount": "229593456" + } + ] + }, + { + "address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", + "coins": [ + { + "denom": "stake", + "amount": "8095698562" + } + ] + }, + { + "address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", + "coins": [ + { + "denom": "stake", + "amount": "6589141209" + } + ] + }, + { + "address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "coins": [ + { + "denom": "stake", + "amount": "2853577310" + } + ] + }, + { + "address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", + "coins": [ + { + "denom": "stake", + "amount": "2594299625" + } + ] + }, + { + "address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", + "coins": [ + { + "denom": "stake", + "amount": "3403723991" + } + ] + }, + { + "address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", + "coins": [ + { + "denom": "stake", + "amount": "20948480766" + } + ] + }, + { + "address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "coins": [ + { + "denom": "stake", + "amount": "4833291035" + } + ] + }, + { + "address": "cosmos1rz3n04g9vg0ygh3h2x96wh5ceq44pcjmt3lgag", + "coins": [ + { + "denom": "stake", + "amount": "25180408482" + } + ] + }, + { + "address": "cosmos1d4jyeaslp5p85mmkxqsem6g99l67nqa6uym3c4", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", + "coins": [ + { + "denom": "stake", + "amount": "15294504306" + } + ] + }, + { + "address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", + "coins": [ + { + "denom": "stake", + "amount": "394439386" + } + ] + }, + { + "address": "cosmos13nemj0k45u4pflkfeyey88n8u8sv4wgz8cf253", + "coins": [ + { + "denom": "stake", + "amount": "55593808380" + } + ] + }, + { + "address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", + "coins": [ + { + "denom": "stake", + "amount": "79121" + } + ] + }, + { + "address": "cosmos1stvzt8re3hz8dme2gscrjxzyx9hcefvhjtvuzh", + "coins": [ + { + "denom": "stake", + "amount": "7414001605" + } + ] + }, + { + "address": "cosmos1ff2vzyfjcwwgk07cqv7hgkpvj0yazgcpez9jg5", + "coins": [ + { + "denom": "stake", + "amount": "26431515484" + } + ] + }, + { + "address": "cosmos124wz6pnykadgf3xchp6rdn9s2t9z5sgvl7597p", + "coins": [ + { + "denom": "stake", + "amount": "15591641617" + } + ] + }, + { + "address": "cosmos14j4mehgc448s2m7cr0uqm3pmvjxav94wmq80w4", + "coins": [ + { + "denom": "stake", + "amount": "1629559245" + } + ] + }, + { + "address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", + "coins": [ + { + "denom": "stake", + "amount": "12272463788" + } + ] + }, + { + "address": "cosmos12f4fpl936ld8c64dxqgwv65p42na8dcnv9g7ku", + "coins": [ + { + "denom": "stake", + "amount": "28991496953" + } + ] + }, + { + "address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", + "coins": [ + { + "denom": "stake", + "amount": "7271239015" + } + ] + }, + { + "address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c", + "coins": [ + { + "denom": "stake", + "amount": "9869349475" + } + ] + }, + { + "address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", + "coins": [ + { + "denom": "stake", + "amount": "370" + } + ] + }, + { + "address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "coins": [ + { + "denom": "stake", + "amount": "7448503007" + } + ] + }, + { + "address": "cosmos1nkywcdu694al4mm44np7uy08jujqvwjzarzs3n", + "coins": [ + { + "denom": "stake", + "amount": "11536917655" + } + ] + }, + { + "address": "cosmos17tecr2sngjcm2rc29dzmadtpad2tkmrhj69whr", + "coins": [ + { + "denom": "stake", + "amount": "5366299050" + } + ] + }, + { + "address": "cosmos198k0ah8pnjzthydgvnq30s24s8jd3wad6puc3q", + "coins": [ + { + "denom": "stake", + "amount": "5536109065" + } + ] + }, + { + "address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", + "coins": [ + { + "denom": "stake", + "amount": "150090308" + } + ] + }, + { + "address": "cosmos1k22576dxnqasv25wy542wc3sgj30gm4gmdpec2", + "coins": [ + { + "denom": "stake", + "amount": "17915441405" + } + ] + }, + { + "address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", + "coins": [ + { + "denom": "stake", + "amount": "681490802" + } + ] + }, + { + "address": "cosmos1p5h9hzhyeske3uwhsf6k5nq38r5pxrejpjw49v", + "coins": [ + { + "denom": "stake", + "amount": "28113011166" + } + ] + }, + { + "address": "cosmos1ywe4qsw399leu3wza5jpny3mmrs69a3gj3hlt8", + "coins": [ + { + "denom": "stake", + "amount": "16634177555" + } + ] + }, + { + "address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", + "coins": [ + { + "denom": "stake", + "amount": "13191407681" + } + ] + }, + { + "address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", + "coins": [ + { + "denom": "stake", + "amount": "13599933677" + } + ] + }, + { + "address": "cosmos102sgufwszag3yuhtzcftpyvc8jqtqske4xug7d", + "coins": [ + { + "denom": "stake", + "amount": "5298673511" + } + ] + }, + { + "address": "cosmos1a5fndlfnwtvyzzt7ql4kvuqgnjut7ua7hkfts6", + "coins": [ + { + "denom": "stake", + "amount": "12053420060" + } + ] + }, + { + "address": "cosmos1q9ed2n5wvzcrymaqltypazqzd2xv8d5aw58flt", + "coins": [ + { + "denom": "stake", + "amount": "4003120376" + } + ] + }, + { + "address": "cosmos1munf3xa25sdu0sdxwyqxhz88c8l90llmjsslvj", + "coins": [ + { + "denom": "stake", + "amount": "13387440139" + } + ] + }, + { + "address": "cosmos136jetl40d2fmx3w0a0t2jj7zyp72g850c9j4ez", + "coins": [ + { + "denom": "stake", + "amount": "182142116" + } + ] + }, + { + "address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg", + "coins": [ + { + "denom": "stake", + "amount": "10737984139" + } + ] + }, + { + "address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", + "coins": [ + { + "denom": "stake", + "amount": "1232108619" + } + ] + }, + { + "address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", + "coins": [ + { + "denom": "stake", + "amount": "7486384395" + } + ] + }, + { + "address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", + "coins": [ + { + "denom": "stake", + "amount": "88345652" + } + ] + }, + { + "address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", + "coins": [ + { + "denom": "stake", + "amount": "41321494" + } + ] + }, + { + "address": "cosmos1zyu5csqfxaxacgwegnhrysl0val4t48kfhj9ws", + "coins": [ + { + "denom": "stake", + "amount": "971257721" + } + ] + }, + { + "address": "cosmos1r764cqpxtae8ed0zyy0v6sxut9dm4fuqj95xgc", + "coins": [ + { + "denom": "stake", + "amount": "14835822719" + } + ] + }, + { + "address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "coins": [ + { + "denom": "stake", + "amount": "848646209" + } + ] + }, + { + "address": "cosmos1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6x000jc", + "coins": [ + { + "denom": "stake", + "amount": "16170647207" + } + ] + }, + { + "address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", + "coins": [ + { + "denom": "stake", + "amount": "3630360827" + } + ] + }, + { + "address": "cosmos1lmkyqhjshfd4mqsgk5stvaxlsxkmdmfhfwh7p2", + "coins": [ + { + "denom": "stake", + "amount": "12681039476" + } + ] + }, + { + "address": "cosmos1rpmw7y7cw2cu3kwsryy8z8uskn4eymh89hmq5g", + "coins": [ + { + "denom": "stake", + "amount": "4485725908" + } + ] + }, + { + "address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", + "coins": [ + { + "denom": "stake", + "amount": "14062569321" + } + ] + }, + { + "address": "cosmos1y8jqa6t7g9m9g2l5u7m7lvm36pj4ssqyas8vdh", + "coins": [ + { + "denom": "stake", + "amount": "6797423203" + } + ] + }, + { + "address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", + "coins": [ + { + "denom": "stake", + "amount": "8568857891" + } + ] + }, + { + "address": "cosmos1t58fj97xgxsvsyn89lc75hd0naa6v6c0c340cv", + "coins": [ + { + "denom": "stake", + "amount": "3231818184" + } + ] + }, + { + "address": "cosmos13xm9km2se2am890j398ttvyjhuh8zndwr2p68d", + "coins": [ + { + "denom": "stake", + "amount": "8208101815" + } + ] + }, + { + "address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", + "coins": [ + { + "denom": "stake", + "amount": "6595044565" + } + ] + }, + { + "address": "cosmos1qenyuc4ljgvkp7g2jhg274k2uzcgdc4vdzfr7z", + "coins": [ + { + "denom": "stake", + "amount": "5254392390" + } + ] + }, + { + "address": "cosmos1ryp2xkqe74y5kx6zffqtdc3wzgny8xg8eguupq", + "coins": [ + { + "denom": "stake", + "amount": "516333564" + } + ] + }, + { + "address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", + "coins": [ + { + "denom": "stake", + "amount": "20464645098" + } + ] + }, + { + "address": "cosmos10gu52rf3d0z0py8d0x37r058qh9fgdgg5567wd", + "coins": [ + { + "denom": "stake", + "amount": "2833226888" + } + ] + }, + { + "address": "cosmos1hn79l8dj3u5llk78cjhsxcvlaz0jh966x4ez7z", + "coins": [ + { + "denom": "stake", + "amount": "34506948109" + } + ] + }, + { + "address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", + "coins": [ + { + "denom": "stake", + "amount": "1249698679" + } + ] + }, + { + "address": "cosmos1l6u5cg3wcptmcjyhxtfrrfq3nu036acdauf0fy", + "coins": [ + { + "denom": "stake", + "amount": "3254718618" + } + ] + }, + { + "address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "coins": [ + { + "denom": "stake", + "amount": "18672231661" + } + ] + }, + { + "address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", + "coins": [ + { + "denom": "stake", + "amount": "225708825" + } + ] + }, + { + "address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "coins": [ + { + "denom": "stake", + "amount": "8552716438" + } + ] + }, + { + "address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq", + "coins": [ + { + "denom": "stake", + "amount": "33376497661" + } + ] + }, + { + "address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6", + "coins": [ + { + "denom": "stake", + "amount": "9040963504" + } + ] + }, + { + "address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "coins": [ + { + "denom": "stake", + "amount": "29610448" + } + ] + }, + { + "address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "coins": [ + { + "denom": "stake", + "amount": "9631517107" + } + ] + }, + { + "address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", + "coins": [ + { + "denom": "stake", + "amount": "812862827" + } + ] + }, + { + "address": "cosmos17ql89l8ghyguux4u4jghja9hmw9vjkwpkle699", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1pca5ng2s37clfh72ea806j9fwvpng4fjq3ey5s", + "coins": [ + { + "denom": "stake", + "amount": "462060951" + } + ] + }, + { + "address": "cosmos1m5aynwlefn0dn8pk5d6j705zh29qstsp4dh02h", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1rzynfn4000ww456my9ke4jf72q306sp4w8qs3m", + "coins": [ + { + "denom": "stake", + "amount": "25199750140" + } + ] + }, + { + "address": "cosmos1kv74z5g0s02jv72npe59l4qkn45q7r46xwx6nv", + "coins": [ + { + "denom": "stake", + "amount": "9192004145" + } + ] + }, + { + "address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2", + "coins": [ + { + "denom": "stake", + "amount": "7359783957" + } + ] + }, + { + "address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", + "coins": [ + { + "denom": "stake", + "amount": "16644100113" + } + ] + }, + { + "address": "cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q", + "coins": [] + }, + { + "address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", + "coins": [ + { + "denom": "stake", + "amount": "3448640286" + } + ] + }, + { + "address": "cosmos1sc26mz3pwry0wm9yynh6w02ypx6k6ckpsjgjr2", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", + "coins": [ + { + "denom": "stake", + "amount": "8465916096" + } + ] + }, + { + "address": "cosmos1glku8mx4nzp5crkjt7px9lfe4flfge3zf64tud", + "coins": [ + { + "denom": "stake", + "amount": "47692972630" + } + ] + }, + { + "address": "cosmos1tgghhdcxdgxay7hp2p0lv2fs656c4c0xfzlga5", + "coins": [ + { + "denom": "stake", + "amount": "6283589634" + } + ] + }, + { + "address": "cosmos1qqexr0y3fxueg3v366ctzlqctexhj5mplmznm4", + "coins": [ + { + "denom": "stake", + "amount": "33742441586" + } + ] + }, + { + "address": "cosmos19szahkq3g937j62shd224cdtla3dv8rcwvekj9", + "coins": [ + { + "denom": "stake", + "amount": "6271564202" + } + ] + }, + { + "address": "cosmos1vpensuylw0rg7f6pnx7qm0acs3tmqgv485faen", + "coins": [ + { + "denom": "stake", + "amount": "22432301261" + } + ] + }, + { + "address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", + "coins": [ + { + "denom": "stake", + "amount": "4644281" + } + ] + }, + { + "address": "cosmos18h7dxvzs4vn07gfgwxgjsvl7f2nhn4fspaggvf", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos197wzfp3g9xq92szucsjce5qfd2p4nrl5cj8lz8", + "coins": [ + { + "denom": "stake", + "amount": "9063405069" + } + ] + }, + { + "address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", + "coins": [ + { + "denom": "stake", + "amount": "5907237303" + } + ] + }, + { + "address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", + "coins": [ + { + "denom": "stake", + "amount": "96530865" + } + ] + }, + { + "address": "cosmos125334yspnrcgu7es23745xr4wtmrzyh8m8vmj0", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", + "coins": [ + { + "denom": "stake", + "amount": "2105628153" + } + ] + }, + { + "address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", + "coins": [ + { + "denom": "stake", + "amount": "11169892212" + } + ] + }, + { + "address": "cosmos1rlltvm5ks32kh683c0w7epsjvg8aq2hvct27p6", + "coins": [ + { + "denom": "stake", + "amount": "63294296" + } + ] + }, + { + "address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm", + "coins": [ + { + "denom": "stake", + "amount": "8495793279" + } + ] + }, + { + "address": "cosmos1wtn9tf6wjwmwmddrk377cdl8fd96hexajyhfat", + "coins": [ + { + "denom": "stake", + "amount": "10771731" + } + ] + }, + { + "address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc", + "coins": [ + { + "denom": "stake", + "amount": "2931060613" + } + ] + }, + { + "address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", + "coins": [ + { + "denom": "stake", + "amount": "36665555599" + } + ] + }, + { + "address": "cosmos1r7kh63jvjhwqraux9wtm3jat8ggm437w9cxcxc", + "coins": [ + { + "denom": "stake", + "amount": "6815707766" + } + ] + }, + { + "address": "cosmos17lfwqsp85symf9ftal8wdsmvavla0we4h9kkxy", + "coins": [ + { + "denom": "stake", + "amount": "13042973798" + } + ] + }, + { + "address": "cosmos19num42c3egx8a4calkn0pz9qxaay7svyyh8vfz", + "coins": [ + { + "denom": "stake", + "amount": "662725780" + } + ] + }, + { + "address": "cosmos1wgslx9j6ct5pczy3h5rjl98yyn78r3sel0ulth", + "coins": [ + { + "denom": "stake", + "amount": "1237715217" + } + ] + }, + { + "address": "cosmos14fh7r7lj6928pd5tyqhfc62l5xnw7rq2zpnulw", + "coins": [ + { + "denom": "stake", + "amount": "27108948901" + } + ] + }, + { + "address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", + "coins": [ + { + "denom": "stake", + "amount": "17420725888" + } + ] + }, + { + "address": "cosmos1wykcmn3r389hklplushrjl43cz76djt44yuc2d", + "coins": [ + { + "denom": "stake", + "amount": "18636985230" + } + ] + }, + { + "address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", + "coins": [ + { + "denom": "stake", + "amount": "237102290" + } + ] + }, + { + "address": "cosmos1md3expnuxrws0qg9dpqxh5stns8ugvd6uh0jrk", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1e6ffgexkzs2lke6dywcju2ltqcjej2e7y4q8e2", + "coins": [ + { + "denom": "stake", + "amount": "792649886" + } + ] + }, + { + "address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", + "coins": [ + { + "denom": "stake", + "amount": "3322853752" + } + ] + }, + { + "address": "cosmos178pm30fcgrt5654czwr8nlex050m6y609glx2s", + "coins": [ + { + "denom": "stake", + "amount": "213988970" + } + ] + }, + { + "address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "coins": [ + { + "denom": "stake", + "amount": "515025318" + } + ] + }, + { + "address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", + "coins": [ + { + "denom": "stake", + "amount": "561951501" + } + ] + }, + { + "address": "cosmos10x0lg2djw0uq8qp5hgzujsu34zpreavnhmv0sc", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", + "coins": [ + { + "denom": "stake", + "amount": "15375542271" + } + ] + }, + { + "address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", + "coins": [ + { + "denom": "stake", + "amount": "8691964576" + } + ] + }, + { + "address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", + "coins": [ + { + "denom": "stake", + "amount": "192612999" + } + ] + }, + { + "address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", + "coins": [ + { + "denom": "stake", + "amount": "23474857664" + } + ] + }, + { + "address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", + "coins": [ + { + "denom": "stake", + "amount": "28262326641" + } + ] + }, + { + "address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", + "coins": [ + { + "denom": "stake", + "amount": "34906677" + } + ] + }, + { + "address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "coins": [ + { + "denom": "stake", + "amount": "265307837" + } + ] + }, + { + "address": "cosmos1m4xvwvq7qrr0wy0ryeu24eu8482h4n7en2x2mh", + "coins": [ + { + "denom": "stake", + "amount": "4296307974" + } + ] + }, + { + "address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "coins": [ + { + "denom": "stake", + "amount": "228374825" + } + ] + }, + { + "address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", + "coins": [ + { + "denom": "stake", + "amount": "9657246504" + } + ] + }, + { + "address": "cosmos18fp6y4z2ze4tdqn5ghl70erq5wpe444p548y5l", + "coins": [ + { + "denom": "stake", + "amount": "7168948159" + } + ] + }, + { + "address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", + "coins": [ + { + "denom": "stake", + "amount": "25197221" + } + ] + }, + { + "address": "cosmos13y6fzxm4933kag94elyy4jgfyhgf3jhwakccun", + "coins": [ + { + "denom": "stake", + "amount": "324111135" + } + ] + }, + { + "address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", + "coins": [ + { + "denom": "stake", + "amount": "4652492905" + } + ] + }, + { + "address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", + "coins": [ + { + "denom": "stake", + "amount": "19933266292" + } + ] + }, + { + "address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", + "coins": [ + { + "denom": "stake", + "amount": "9882840105" + } + ] + }, + { + "address": "cosmos1590defm6q73eu39x8ndt9vwmv5fhvp9q4vf96f", + "coins": [ + { + "denom": "stake", + "amount": "964692708" + } + ] + }, + { + "address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429", + "coins": [ + { + "denom": "stake", + "amount": "8500099030" + } + ] + }, + { + "address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", + "coins": [ + { + "denom": "stake", + "amount": "4266943360" + } + ] + }, + { + "address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", + "coins": [ + { + "denom": "stake", + "amount": "17851397628" + } + ] + }, + { + "address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", + "coins": [ + { + "denom": "stake", + "amount": "11055928327" + } + ] + }, + { + "address": "cosmos1w0j4ecghl96s9xayk967z4hnrxlsfht7rawmrc", + "coins": [ + { + "denom": "stake", + "amount": "15818247483" + } + ] + }, + { + "address": "cosmos1369zs5htywxarh8cl6rvmzgatfql00pmvmewet", + "coins": [ + { + "denom": "stake", + "amount": "25280930960" + } + ] + }, + { + "address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", + "coins": [ + { + "denom": "stake", + "amount": "34255416497" + } + ] + }, + { + "address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", + "coins": [ + { + "denom": "stake", + "amount": "4052051" + } + ] + }, + { + "address": "cosmos10ed8tmu5n2xfhtcyht4kahkmzqaxk2u7ks7k9u", + "coins": [ + { + "denom": "stake", + "amount": "14232287154" + } + ] + }, + { + "address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", + "coins": [ + { + "denom": "stake", + "amount": "12906327178" + } + ] + }, + { + "address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "coins": [ + { + "denom": "stake", + "amount": "4940558291" + } + ] + }, + { + "address": "cosmos1z2ynmntxdesahja6gh76cunudwfmrhgcx7krhv", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", + "coins": [ + { + "denom": "stake", + "amount": "4424189878" + } + ] + }, + { + "address": "cosmos13jfnddzl23pkks9f7ahgjeqaz4pyfx43mluaa4", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos16p082pp2g44jm5sa7x8egm2089gw908s85szsm", + "coins": [ + { + "denom": "stake", + "amount": "4101717090" + } + ] + }, + { + "address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "coins": [ + { + "denom": "stake", + "amount": "7253227770" + } + ] + }, + { + "address": "cosmos1renmf3hfgfq3p7wzenfa45alrhtc92f9geghu7", + "coins": [ + { + "denom": "stake", + "amount": "7148036106" + } + ] + }, + { + "address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", + "coins": [ + { + "denom": "stake", + "amount": "166991994" + } + ] + }, + { + "address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", + "coins": [ + { + "denom": "stake", + "amount": "2064809084" + } + ] + }, + { + "address": "cosmos1kxl7gsad663he7lgn66wx6gr3egnfj85dt22pv", + "coins": [ + { + "denom": "stake", + "amount": "17645582456" + } + ] + }, + { + "address": "cosmos17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnk5g0lz", + "coins": [ + { + "denom": "stake", + "amount": "153929962" + } + ] + }, + { + "address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", + "coins": [ + { + "denom": "stake", + "amount": "22599640159" + } + ] + }, + { + "address": "cosmos18fxku8d7wa5vjz9ta2xr7asvdfdrqnpdjfqpe5", + "coins": [ + { + "denom": "stake", + "amount": "13627909428" + } + ] + }, + { + "address": "cosmos1vnceu3qp3cw2qjq3jqmvfgwgv50y4yze7fe22y", + "coins": [ + { + "denom": "stake", + "amount": "870242442" + } + ] + }, + { + "address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", + "coins": [ + { + "denom": "stake", + "amount": "382052780" + } + ] + }, + { + "address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", + "coins": [ + { + "denom": "stake", + "amount": "24658850363" + } + ] + }, + { + "address": "cosmos1l577787urj3qccxypxaznnasxvnn9k8wq5lxf8", + "coins": [ + { + "denom": "stake", + "amount": "71769507" + } + ] + }, + { + "address": "cosmos1p7sc667drjvsjlha0nwz5zxxpt38m9dn50u925", + "coins": [ + { + "denom": "stake", + "amount": "34424110416" + } + ] + }, + { + "address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", + "coins": [ + { + "denom": "stake", + "amount": "56072875965" + } + ] + }, + { + "address": "cosmos1ft0e05t5rl8ycw6a0nfa6jswvckycan4lfmv0q", + "coins": [ + { + "denom": "stake", + "amount": "12443470626" + } + ] + }, + { + "address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", + "coins": [ + { + "denom": "stake", + "amount": "1958035374" + } + ] + }, + { + "address": "cosmos1qqxeqqvjkh2ls3a0taukd8rydrqqad690nxkcc", + "coins": [ + { + "denom": "stake", + "amount": "15287559843" + } + ] + }, + { + "address": "cosmos19akemnyuu0rgf2y0rrd6wrxpkyd74q5gzkgm5q", + "coins": [ + { + "denom": "stake", + "amount": "13924416768" + } + ] + }, + { + "address": "cosmos15pl2c2umxszwar75aft99kns0ltmpepnnpt9y0", + "coins": [ + { + "denom": "stake", + "amount": "22979868888" + } + ] + }, + { + "address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", + "coins": [ + { + "denom": "stake", + "amount": "115546197" + } + ] + }, + { + "address": "cosmos1p0sp7r6mzt05772xq9eqg47rvssgxhf4ktctah", + "coins": [ + { + "denom": "stake", + "amount": "28075176573" + } + ] + }, + { + "address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", + "coins": [ + { + "denom": "stake", + "amount": "16683212256" + } + ] + }, + { + "address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", + "coins": [ + { + "denom": "stake", + "amount": "138266" + } + ] + }, + { + "address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", + "coins": [ + { + "denom": "stake", + "amount": "33376038" + } + ] + }, + { + "address": "cosmos1urnp7yp6u27nut8kvsrapgmmvk8sh6u5wd5dez", + "coins": [ + { + "denom": "stake", + "amount": "4340887167" + } + ] + }, + { + "address": "cosmos1d9cqjx7xh2j23utvyrns2kgtz4w8e694vqw6h6", + "coins": [ + { + "denom": "stake", + "amount": "597776153" + } + ] + }, + { + "address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", + "coins": [ + { + "denom": "stake", + "amount": "42986521" + } + ] + }, + { + "address": "cosmos1ffaxjdp4v8w7kzgjsnf6nf4fvvndhrk6s9syf6", + "coins": [ + { + "denom": "stake", + "amount": "14187770842" + } + ] + }, + { + "address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", + "coins": [ + { + "denom": "stake", + "amount": "340556632" + } + ] + }, + { + "address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", + "coins": [ + { + "denom": "stake", + "amount": "10440851460" + } + ] + }, + { + "address": "cosmos1rcru2vteas2kunww3zt4knx28krlestxydpwza", + "coins": [ + { + "denom": "stake", + "amount": "740320221" + } + ] + }, + { + "address": "cosmos1xxurm2uymwd04sjxqedjae5r0zxhalh26skxct", + "coins": [ + { + "denom": "stake", + "amount": "14639003842" + } + ] + }, + { + "address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", + "coins": [ + { + "denom": "stake", + "amount": "23850785852" + } + ] + }, + { + "address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", + "coins": [ + { + "denom": "stake", + "amount": "3063847202" + } + ] + }, + { + "address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6", + "coins": [ + { + "denom": "stake", + "amount": "228712404" + } + ] + }, + { + "address": "cosmos18ku7lzv6a0d3t63d2tsn2x69u04uv3g8sgf8kq", + "coins": [ + { + "denom": "stake", + "amount": "25069342080" + } + ] + }, + { + "address": "cosmos1vlvxlpzzrk5eye9c3z9uedk0085h7fdvehv32n", + "coins": [ + { + "denom": "stake", + "amount": "1514324156" + } + ] + }, + { + "address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", + "coins": [ + { + "denom": "stake", + "amount": "32478838379" + } + ] + }, + { + "address": "cosmos15mxavsffqqj7enxpy7e3ayywd4jn4hz6ncjfft", + "coins": [ + { + "denom": "stake", + "amount": "5472724450" + } + ] + }, + { + "address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "coins": [ + { + "denom": "stake", + "amount": "596954561" + } + ] + }, + { + "address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n", + "coins": [ + { + "denom": "stake", + "amount": "2581136884" + } + ] + }, + { + "address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", + "coins": [ + { + "denom": "stake", + "amount": "10309758615" + } + ] + }, + { + "address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", + "coins": [ + { + "denom": "stake", + "amount": "8869960226" + } + ] + }, + { + "address": "cosmos1d5vv20893q06tx29mlqmefnyf0w3hn0v07w9p9", + "coins": [ + { + "denom": "stake", + "amount": "50733557399" + } + ] + }, + { + "address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", + "coins": [ + { + "denom": "stake", + "amount": "20940341779" + } + ] + }, + { + "address": "cosmos1l5d2lg5hku0m4u8mh866zhjcy2dekpk598m8wr", + "coins": [ + { + "denom": "stake", + "amount": "1178967884" + } + ] + }, + { + "address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", + "coins": [ + { + "denom": "stake", + "amount": "8095681198" + } + ] + }, + { + "address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "coins": [ + { + "denom": "stake", + "amount": "82769207" + } + ] + } + ] + }, + "crisis": { + "constant_fee": { + "denom": "stake", + "amount": "1000" + } + }, + "mint": { + "minter": { + "inflation": "0.200000000000000000", + "annual_provisions": "5810696836997.800000000000000000" + }, + "params": { + "mint_denom": "stake", + "inflation_rate_change": "0.210000000000000000", + "inflation_max": "0.200000000000000000", + "inflation_min": "0.070000000000000000", + "goal_bonded": "0.670000000000000000", + "blocks_per_year": "6311520" + } + }, + "slashing": { + "params": { + "signed_blocks_window": "80", + "min_signed_per_window": "0.500000000000000000", + "downtime_jail_duration": "35518000000000", + "slash_fraction_double_sign": "0.038461538461538462", + "slash_fraction_downtime": "0.012987012987012987" + }, + "signing_infos": { + "cosmosvalcons12dh9h444s238r7hjrrd2kg6wrw4cwfk3999xl6": { + "address": "cosmosvalcons12dh9h444s238r7hjrrd2kg6wrw4cwfk3999xl6", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtp8l6ug4": { + "address": "cosmosvalcons1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtp8l6ug4", + "start_height": "12", + "index_offset": "37", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "36" + }, + "cosmosvalcons1e8fdmnscnm6axht542696jupnqlkm40e0jefjw": { + "address": "cosmosvalcons1e8fdmnscnm6axht542696jupnqlkm40e0jefjw", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1up7x3srs54xhq897rlda86hdsf4sy7ncez37jn": { + "address": "cosmosvalcons1up7x3srs54xhq897rlda86hdsf4sy7ncez37jn", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux0fv6ry": { + "address": "cosmosvalcons1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux0fv6ry", + "start_height": "48", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1r7kh63jvjhwqraux9wtm3jat8ggm437w5lp3x2": { + "address": "cosmosvalcons1r7kh63jvjhwqraux9wtm3jat8ggm437w5lp3x2", + "start_height": "6", + "index_offset": "37", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1x72py7gr6pd72ch7u380ay04t9mhf3fkgur5k8": { + "address": "cosmosvalcons1x72py7gr6pd72ch7u380ay04t9mhf3fkgur5k8", + "index_offset": "15", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1gfta9y4c4j5dd08mju2zf23cmdn7ylauvct35q": { + "address": "cosmosvalcons1gfta9y4c4j5dd08mju2zf23cmdn7ylauvct35q", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons13nemj0k45u4pflkfeyey88n8u8sv4wgzklwr5r": { + "address": "cosmosvalcons13nemj0k45u4pflkfeyey88n8u8sv4wgzklwr5r", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "41" + }, + "cosmosvalcons1nfurwjwfy3zhw0g9eqcclzeejf9nqw62ewmwyr": { + "address": "cosmosvalcons1nfurwjwfy3zhw0g9eqcclzeejf9nqw62ewmwyr", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons14se5hzhf43yk83pkztukhtlfu683s4ktcqzgvs": { + "address": "cosmosvalcons14se5hzhf43yk83pkztukhtlfu683s4ktcqzgvs", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7t0qj3k": { + "address": "cosmosvalcons1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7t0qj3k", + "start_height": "2", + "index_offset": "46", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "46" + }, + "cosmosvalcons1l5d2lg5hku0m4u8mh866zhjcy2dekpk55quww3": { + "address": "cosmosvalcons1l5d2lg5hku0m4u8mh866zhjcy2dekpk55quww3", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "23" + }, + "cosmosvalcons1z6f7gdevn6dfvpls7tlqmqmzr54le7a4avumjr": { + "address": "cosmosvalcons1z6f7gdevn6dfvpls7tlqmqmzr54le7a4avumjr", + "start_height": "7", + "index_offset": "7", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "7" + }, + "cosmosvalcons190kcpcyvl46xva8ya8vs5wmmg4nygvuty9afhq": { + "address": "cosmosvalcons190kcpcyvl46xva8ya8vs5wmmg4nygvuty9afhq", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons12k6u60mgp8wldpz2xs2u3p3skmghtrjy5etjdq": { + "address": "cosmosvalcons12k6u60mgp8wldpz2xs2u3p3skmghtrjy5etjdq", + "start_height": "4", + "index_offset": "4", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1n20sc20x53kyms9vhrxlr8r79hptq3p2efwm48": { + "address": "cosmosvalcons1n20sc20x53kyms9vhrxlr8r79hptq3p2efwm48", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1ellx23lw5uxmdnyjpnn03expxvu89kd6htl8jx": { + "address": "cosmosvalcons1ellx23lw5uxmdnyjpnn03expxvu89kd6htl8jx", + "index_offset": "7", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "7" + }, + "cosmosvalcons17uusex4s7mds872wzvkpaty29g02n8ethl39rz": { + "address": "cosmosvalcons17uusex4s7mds872wzvkpaty29g02n8ethl39rz", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1zzey9t59j5x7j5z9f3urms7faq0gq9dw27hxcc": { + "address": "cosmosvalcons1zzey9t59j5x7j5z9f3urms7faq0gq9dw27hxcc", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwghsz8u0": { + "address": "cosmosvalcons1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwghsz8u0", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons1yezuhyh4htsy74jkhfey9p7urgwhg00jqp7rty": { + "address": "cosmosvalcons1yezuhyh4htsy74jkhfey9p7urgwhg00jqp7rty", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1dle2tkls5kffwdqhan4rs0dgckjxunfsv0l9kn": { + "address": "cosmosvalcons1dle2tkls5kffwdqhan4rs0dgckjxunfsv0l9kn", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "47" + }, + "cosmosvalcons13fyamuv3fexmuuamtgqtwkz48ynl3hd5jgmlh8": { + "address": "cosmosvalcons13fyamuv3fexmuuamtgqtwkz48ynl3hd5jgmlh8", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons15772l3g3u9kk2qk5cmsl8tr6lshgd443cvttwn": { + "address": "cosmosvalcons15772l3g3u9kk2qk5cmsl8tr6lshgd443cvttwn", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "46" + }, + "cosmosvalcons14qy520rhr0qytqxdtsjsu9rgw708n2w6ex2jmj": { + "address": "cosmosvalcons14qy520rhr0qytqxdtsjsu9rgw708n2w6ex2jmj", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons17gpy6jzg7xdsr2xc7kweljagx4uaysxd8ddu46": { + "address": "cosmosvalcons17gpy6jzg7xdsr2xc7kweljagx4uaysxd8ddu46", + "start_height": "1", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons1zjw6x8t95zuaxprcyl0x6l7u0ag6626v0fzay6": { + "address": "cosmosvalcons1zjw6x8t95zuaxprcyl0x6l7u0ag6626v0fzay6", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons19yplr2r5lu70jlymwrumzuc8tqeeu7fg5x9a4u": { + "address": "cosmosvalcons19yplr2r5lu70jlymwrumzuc8tqeeu7fg5x9a4u", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons19e3lp8kdpnzmd778gxz9hqrnaxw8spa36e4k9u": { + "address": "cosmosvalcons19e3lp8kdpnzmd778gxz9hqrnaxw8spa36e4k9u", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons188yd2umzwfwen7es68wrlh6auu3p8jhz78wpeq": { + "address": "cosmosvalcons188yd2umzwfwen7es68wrlh6auu3p8jhz78wpeq", + "index_offset": "44", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "41" + }, + "cosmosvalcons1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpus7r8l": { + "address": "cosmosvalcons1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpus7r8l", + "start_height": "7", + "index_offset": "42", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1n3lnhxzzm7ntheu78h6v4zag7zmrlp486457fr": { + "address": "cosmosvalcons1n3lnhxzzm7ntheu78h6v4zag7zmrlp486457fr", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons14kdxam68sthcd72526kc5ea42hfq5c2ga5v908": { + "address": "cosmosvalcons14kdxam68sthcd72526kc5ea42hfq5c2ga5v908", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1ql2jawqmha8d2xdgda7njakszmhvt75rv4zlx8": { + "address": "cosmosvalcons1ql2jawqmha8d2xdgda7njakszmhvt75rv4zlx8", + "index_offset": "15", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "8" + }, + "cosmosvalcons1zu50umwgah6jhx07sw04ry0pv7fnvkpj25q9lh": { + "address": "cosmosvalcons1zu50umwgah6jhx07sw04ry0pv7fnvkpj25q9lh", + "index_offset": "49", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1wnn8xrn46u6ryq4kqf7tcf650fe2gl57uk0p3z": { + "address": "cosmosvalcons1wnn8xrn46u6ryq4kqf7tcf650fe2gl57uk0p3z", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1nz5hp6p6wn4fvnaxe9x6fq35daamxvhh6ze2pt": { + "address": "cosmosvalcons1nz5hp6p6wn4fvnaxe9x6fq35daamxvhh6ze2pt", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons16xal57nga5gd2qxkz869qv7hm20xn0rkyfusws": { + "address": "cosmosvalcons16xal57nga5gd2qxkz869qv7hm20xn0rkyfusws", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons16sn6wjtd0kw4yvc7780cpayhz0x45d27cdeswx": { + "address": "cosmosvalcons16sn6wjtd0kw4yvc7780cpayhz0x45d27cdeswx", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1uuk9ewj0532rzlhlg86tserdxvtnm3kqm3dtwu": { + "address": "cosmosvalcons1uuk9ewj0532rzlhlg86tserdxvtnm3kqm3dtwu", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1q55pmsr0wnpzlcx25p9vqde6c52ekjnvysqusa": { + "address": "cosmosvalcons1q55pmsr0wnpzlcx25p9vqde6c52ekjnvysqusa", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1gayzja3zz6unep8ftnpunt2wefazs3jhd5caas": { + "address": "cosmosvalcons1gayzja3zz6unep8ftnpunt2wefazs3jhd5caas", + "index_offset": "14", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "7" + }, + "cosmosvalcons1frjkqcr3r5fpwds4kypq5e9n865qss6ujnfqrc": { + "address": "cosmosvalcons1frjkqcr3r5fpwds4kypq5e9n865qss6ujnfqrc", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1trkrhq6mxwktf24u8jepelvumpd9l6lehelksx": { + "address": "cosmosvalcons1trkrhq6mxwktf24u8jepelvumpd9l6lehelksx", + "start_height": "8", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1vfcm9c4psqrkv9zecgjw7zxvw2jnpe737eaneg": { + "address": "cosmosvalcons1vfcm9c4psqrkv9zecgjw7zxvw2jnpe737eaneg", + "start_height": "6", + "index_offset": "43", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons15jcgjq7sc62rj4s0dlm4sapdcgw06jfuysh66q": { + "address": "cosmosvalcons15jcgjq7sc62rj4s0dlm4sapdcgw06jfuysh66q", + "start_height": "12", + "index_offset": "37", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "37" + }, + "cosmosvalcons1hu260773mytzz030tuq0kffmlyxzs7vg5wftk9": { + "address": "cosmosvalcons1hu260773mytzz030tuq0kffmlyxzs7vg5wftk9", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "7" + }, + "cosmosvalcons16tr72kn90g5zl7qhyhuqkjflejz00uzl8caasq": { + "address": "cosmosvalcons16tr72kn90g5zl7qhyhuqkjflejz00uzl8caasq", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnf22uec": { + "address": "cosmosvalcons1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnf22uec", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons12r0m6hwrnn0jy02tnhmk328d7p68x2rnu9vxjx": { + "address": "cosmosvalcons12r0m6hwrnn0jy02tnhmk328d7p68x2rnu9vxjx", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "47" + }, + "cosmosvalcons1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqpw7fvxl": { + "address": "cosmosvalcons1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqpw7fvxl", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1h6j4lyvuenmz9m7vq3hler8j7pg5ldpe6gpq90": { + "address": "cosmosvalcons1h6j4lyvuenmz9m7vq3hler8j7pg5ldpe6gpq90", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1qk5quugdx54zsrteg9hpee0ke3z35meuz4rde2": { + "address": "cosmosvalcons1qk5quugdx54zsrteg9hpee0ke3z35meuz4rde2", + "index_offset": "49", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1rq7tvegh0yqan5fpp90rya7q9lks5nyxw0kdej": { + "address": "cosmosvalcons1rq7tvegh0yqan5fpp90rya7q9lks5nyxw0kdej", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons183sdz4kk0lueuxfu7zzgp8tzcjndf3pflk3e02": { + "address": "cosmosvalcons183sdz4kk0lueuxfu7zzgp8tzcjndf3pflk3e02", + "start_height": "5", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1w2ly5qah2m47qguaukzr6xx34hszqh8um4gr3k": { + "address": "cosmosvalcons1w2ly5qah2m47qguaukzr6xx34hszqh8um4gr3k", + "start_height": "1", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons13tfk4n07c9dz5swkw7vafmlrd9e0d28faef7g0": { + "address": "cosmosvalcons13tfk4n07c9dz5swkw7vafmlrd9e0d28faef7g0", + "index_offset": "49", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "12" + }, + "cosmosvalcons1nmexjngk0j8jhgmywrkd7r98dgd9hzxpvcqtsq": { + "address": "cosmosvalcons1nmexjngk0j8jhgmywrkd7r98dgd9hzxpvcqtsq", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1kjupa2w6rlhzj9fjxz35m02g2wpz790fuauq0q": { + "address": "cosmosvalcons1kjupa2w6rlhzj9fjxz35m02g2wpz790fuauq0q", + "start_height": "14", + "index_offset": "34", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "20" + }, + "cosmosvalcons172lmu2psqlkxkthpr46h2ewjffte7lhl2f7nt6": { + "address": "cosmosvalcons172lmu2psqlkxkthpr46h2ewjffte7lhl2f7nt6", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1qy0qwzljplfauvyhgayw6nxte2zxujh4658x9s": { + "address": "cosmosvalcons1qy0qwzljplfauvyhgayw6nxte2zxujh4658x9s", + "start_height": "48", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1ylf26t6vhvugawg87328ng2ug4d8f25s4pxn42": { + "address": "cosmosvalcons1ylf26t6vhvugawg87328ng2ug4d8f25s4pxn42", + "start_height": "9", + "index_offset": "40", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "40" + }, + "cosmosvalcons1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7l4x75dl": { + "address": "cosmosvalcons1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7l4x75dl", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons153rklv33fjex4w7r82n9wnwxrwfgae6nn0hfc9": { + "address": "cosmosvalcons153rklv33fjex4w7r82n9wnwxrwfgae6nn0hfc9", + "index_offset": "13", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "13" + }, + "cosmosvalcons14e68cy8rvnmva3fzvhmq67m94zffpvnt09v3de": { + "address": "cosmosvalcons14e68cy8rvnmva3fzvhmq67m94zffpvnt09v3de", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1hxdqddf3u8vjm080ytpe959uktn4axdapkmfhd": { + "address": "cosmosvalcons1hxdqddf3u8vjm080ytpe959uktn4axdapkmfhd", + "start_height": "2", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons1qw9wqlz92hj8y6mcj24l6wu68er03njuzuu92s": { + "address": "cosmosvalcons1qw9wqlz92hj8y6mcj24l6wu68er03njuzuu92s", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "47" + }, + "cosmosvalcons10cl6sallgwf882apcyagjqa2lx4j8592f4fxgm": { + "address": "cosmosvalcons10cl6sallgwf882apcyagjqa2lx4j8592f4fxgm", + "index_offset": "10", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1ng7vpl5wh98pshfef327gfnzyrwh6z4e8869pm": { + "address": "cosmosvalcons1ng7vpl5wh98pshfef327gfnzyrwh6z4e8869pm", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons15a8hadw3wttrnr3qx37ewmzre4w7cjmtk3uf03": { + "address": "cosmosvalcons15a8hadw3wttrnr3qx37ewmzre4w7cjmtk3uf03", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1qqxeqqvjkh2ls3a0taukd8rydrqqad6975plc2": { + "address": "cosmosvalcons1qqxeqqvjkh2ls3a0taukd8rydrqqad6975plc2", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1x76xgyet9jkq94uqcckrwm20l85gt2kxx6qect": { + "address": "cosmosvalcons1x76xgyet9jkq94uqcckrwm20l85gt2kxx6qect", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1g7sk4y3cf2473ff36mlcx9ydvted9evryympt2": { + "address": "cosmosvalcons1g7sk4y3cf2473ff36mlcx9ydvted9evryympt2", + "start_height": "1", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons1qs5htj5ayfgg27t0xnng837lzllla5y235nkaw": { + "address": "cosmosvalcons1qs5htj5ayfgg27t0xnng837lzllla5y235nkaw", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1ptu2vxfcsyl2gpeg73ehzte7t3va459lj69slr": { + "address": "cosmosvalcons1ptu2vxfcsyl2gpeg73ehzte7t3va459lj69slr", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn5472pf8v": { + "address": "cosmosvalcons18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn5472pf8v", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons10gu52rf3d0z0py8d0x37r058qh9fgdgg9nahwl": { + "address": "cosmosvalcons10gu52rf3d0z0py8d0x37r058qh9fgdgg9nahwl", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons15pl2c2umxszwar75aft99kns0ltmpepnzxvvya": { + "address": "cosmosvalcons15pl2c2umxszwar75aft99kns0ltmpepnzxvvya", + "index_offset": "9", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "9" + }, + "cosmosvalcons158hwrawjlg586d47zl4xk9kg3em02vyppstqwv": { + "address": "cosmosvalcons158hwrawjlg586d47zl4xk9kg3em02vyppstqwv", + "index_offset": "45", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "6" + }, + "cosmosvalcons1kz20p7j939s8cqadmqqws80c6z93qdtyeqpz07": { + "address": "cosmosvalcons1kz20p7j939s8cqadmqqws80c6z93qdtyeqpz07", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "24" + }, + "cosmosvalcons1yalqz5m4qcjtss37pdnvalz5kaws3yjy3he4fv": { + "address": "cosmosvalcons1yalqz5m4qcjtss37pdnvalz5kaws3yjy3he4fv", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "13" + }, + "cosmosvalcons1d5vv20893q06tx29mlqmefnyf0w3hn0v7efvph": { + "address": "cosmosvalcons1d5vv20893q06tx29mlqmefnyf0w3hn0v7efvph", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1h7nkedpkxm0t752j0q88rhgwjn94p4y29hqdn2": { + "address": "cosmosvalcons1h7nkedpkxm0t752j0q88rhgwjn94p4y29hqdn2", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwc2lxm7": { + "address": "cosmosvalcons1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwc2lxm7", + "start_height": "12", + "index_offset": "35", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "35" + }, + "cosmosvalcons1t6k46y53tkcjvdttujt542pcfrwanw0flqxj2g": { + "address": "cosmosvalcons1t6k46y53tkcjvdttujt542pcfrwanw0flqxj2g", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons13yzpngckxvtky2k25j60qxlkekx0jfauyx47zp": { + "address": "cosmosvalcons13yzpngckxvtky2k25j60qxlkekx0jfauyx47zp", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1eausepxh2ujd0lpjup9vahjekpz9as2fgn2vdk": { + "address": "cosmosvalcons1eausepxh2ujd0lpjup9vahjekpz9as2fgn2vdk", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1r4czpmmu87t7zhlh34zrzna9gkex4ap5eqd50s": { + "address": "cosmosvalcons1r4czpmmu87t7zhlh34zrzna9gkex4ap5eqd50s", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1jf2wka8xprke2q6qxq2vz3khe4mqxv75jvgj02": { + "address": "cosmosvalcons1jf2wka8xprke2q6qxq2vz3khe4mqxv75jvgj02", + "index_offset": "7", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "7" + }, + "cosmosvalcons1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlvmv8ya": { + "address": "cosmosvalcons1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlvmv8ya", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1nrugh7am9s584k6qlf5nxlpetarxs2csecvu6u": { + "address": "cosmosvalcons1nrugh7am9s584k6qlf5nxlpetarxs2csecvu6u", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4g2ureq": { + "address": "cosmosvalcons15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4g2ureq", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7naq267qg": { + "address": "cosmosvalcons1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7naq267qg", + "start_height": "1", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wwhy7vf": { + "address": "cosmosvalcons1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wwhy7vf", + "index_offset": "49", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "47" + }, + "cosmosvalcons1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfccuman": { + "address": "cosmosvalcons1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfccuman", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "46" + }, + "cosmosvalcons1yt9s823gnqayrjasrra5j43pj9c48ae9gp0f5l": { + "address": "cosmosvalcons1yt9s823gnqayrjasrra5j43pj9c48ae9gp0f5l", + "start_height": "6", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons12f4fpl936ld8c64dxqgwv65p42na8dcnaz0hkw": { + "address": "cosmosvalcons12f4fpl936ld8c64dxqgwv65p42na8dcnaz0hkw", + "index_offset": "9", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "9" + }, + "cosmosvalcons10ndcqfr2zwrspryphtuhq883kc49z38fwtx025": { + "address": "cosmosvalcons10ndcqfr2zwrspryphtuhq883kc49z38fwtx025", + "start_height": "2", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons13mztfedkzpz634g7u5fh8henfmvzyrfflw7r8u": { + "address": "cosmosvalcons13mztfedkzpz634g7u5fh8henfmvzyrfflw7r8u", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons147pq4rzswl76kdeyx8sc7pagf4nhjpnqmsc2hr": { + "address": "cosmosvalcons147pq4rzswl76kdeyx8sc7pagf4nhjpnqmsc2hr", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "24" + }, + "cosmosvalcons1k0z97vlulcmdrrajhms2x9k8srvtmxwu9l0mha": { + "address": "cosmosvalcons1k0z97vlulcmdrrajhms2x9k8srvtmxwu9l0mha", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1cdvntn6mwvvv4qxnty6zp2jwvemg20yuqmdsse": { + "address": "cosmosvalcons1cdvntn6mwvvv4qxnty6zp2jwvemg20yuqmdsse", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons1a4nlyf59n25qmh4myas5mdunvu9r4wlsffl40h": { + "address": "cosmosvalcons1a4nlyf59n25qmh4myas5mdunvu9r4wlsffl40h", + "start_height": "2", + "index_offset": "4", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1zscesuffz58dc0lq7yy6n6z3j5fhkr3du7aulk": { + "address": "cosmosvalcons1zscesuffz58dc0lq7yy6n6z3j5fhkr3du7aulk", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1gd779gn33yuxxla5pm5dphglcyx4ulzd86ldf8": { + "address": "cosmosvalcons1gd779gn33yuxxla5pm5dphglcyx4ulzd86ldf8", + "index_offset": "26", + "jailed_until": "9999-12-31T23:59:59Z", + "tombstoned": true, + "missed_blocks_counter": "14" + }, + "cosmosvalcons12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5ymewrp": { + "address": "cosmosvalcons12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5ymewrp", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1wy59rs74dnqqs0xz70sn2q5hyv9yreth64pa96": { + "address": "cosmosvalcons1wy59rs74dnqqs0xz70sn2q5hyv9yreth64pa96", + "start_height": "2", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1qqe0t0j86umq0379kjcmjg00yd6ddrdw9cehas": { + "address": "cosmosvalcons1qqe0t0j86umq0379kjcmjg00yd6ddrdw9cehas", + "start_height": "1", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons18d56e7qz5869wegeca967hrxrmfduxdenqzjcz": { + "address": "cosmosvalcons18d56e7qz5869wegeca967hrxrmfduxdenqzjcz", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons13w024ysyklmnrq9c6udp98qx93jqynhggkk3rp": { + "address": "cosmosvalcons13w024ysyklmnrq9c6udp98qx93jqynhggkk3rp", + "index_offset": "8", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "6" + }, + "cosmosvalcons1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76v6c2hww": { + "address": "cosmosvalcons1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76v6c2hww", + "start_height": "48", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1qpj52qsl708aqhazaqehhjw7cdj4her9zsvuxy": { + "address": "cosmosvalcons1qpj52qsl708aqhazaqehhjw7cdj4her9zsvuxy", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1y30ftjd79f3p68mssyd9zug24q2avh0zkms02f": { + "address": "cosmosvalcons1y30ftjd79f3p68mssyd9zug24q2avh0zkms02f", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1s30d8tgwhwavwtvanggkj92quj8ucecyqlzjzv": { + "address": "cosmosvalcons1s30d8tgwhwavwtvanggkj92quj8ucecyqlzjzv", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1s6sl7pyvn33lptf7edmux0gex06ffzjz8l2hlr": { + "address": "cosmosvalcons1s6sl7pyvn33lptf7edmux0gex06ffzjz8l2hlr", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons10ke8m795c8svtt2h24n6dad2xp9a8mev6pk3dq": { + "address": "cosmosvalcons10ke8m795c8svtt2h24n6dad2xp9a8mev6pk3dq", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1q03kay3adsttv6watm3agqktnpuuxs65vz6tu7": { + "address": "cosmosvalcons1q03kay3adsttv6watm3agqktnpuuxs65vz6tu7", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons19vugh7w9vrp6x3nqzjph59zg0d28c0fkn7432d": { + "address": "cosmosvalcons19vugh7w9vrp6x3nqzjph59zg0d28c0fkn7432d", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1g95xvy8qgzcvcl05fse0mpxzdfv3w88ts7pdc3": { + "address": "cosmosvalcons1g95xvy8qgzcvcl05fse0mpxzdfv3w88ts7pdc3", + "index_offset": "49", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1hsq728kpcxgr77ncj8asxa0383pyx7vqpf87tj": { + "address": "cosmosvalcons1hsq728kpcxgr77ncj8asxa0383pyx7vqpf87tj", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons17qavkakyqgh62k39frjf5v9pj0c78m2daks0a9": { + "address": "cosmosvalcons17qavkakyqgh62k39frjf5v9pj0c78m2daks0a9", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1p0u57pfl53kwefqrrr652pd3sm2hhv9gznzvw7": { + "address": "cosmosvalcons1p0u57pfl53kwefqrrr652pd3sm2hhv9gznzvw7", + "start_height": "7", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1xec6kclrpkc4ws7lwf5j0u8207nyg6dzr6xsy0": { + "address": "cosmosvalcons1xec6kclrpkc4ws7lwf5j0u8207nyg6dzr6xsy0", + "index_offset": "8", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1289vtnyn8vg9rwv7jdcy2ht3h68627ht5jdl32": { + "address": "cosmosvalcons1289vtnyn8vg9rwv7jdcy2ht3h68627ht5jdl32", + "start_height": "7", + "index_offset": "39", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "19" + }, + "cosmosvalcons1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjf35ts7": { + "address": "cosmosvalcons1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjf35ts7", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1jsd99e3zfrxrr3nh057u0tvmu0847zkrmzwr87": { + "address": "cosmosvalcons1jsd99e3zfrxrr3nh057u0tvmu0847zkrmzwr87", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "23" + }, + "cosmosvalcons1ktnuvrm3q8h30y3k70yzvmvwme77e9yycn5aw6": { + "address": "cosmosvalcons1ktnuvrm3q8h30y3k70yzvmvwme77e9yycn5aw6", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1y7m2ga0zpxr6q000a4a924fdaeycw5ed43yckr": { + "address": "cosmosvalcons1y7m2ga0zpxr6q000a4a924fdaeycw5ed43yckr", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1jp0tqhr79uwqt2rh66vcd378rrhslg49uwt39p": { + "address": "cosmosvalcons1jp0tqhr79uwqt2rh66vcd378rrhslg49uwt39p", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "47" + }, + "cosmosvalcons1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7tn52wp": { + "address": "cosmosvalcons1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7tn52wp", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1m8gpgklc8a2yla9ah9y8mlu226n0mu4ym3qdze": { + "address": "cosmosvalcons1m8gpgklc8a2yla9ah9y8mlu226n0mu4ym3qdze", + "start_height": "4", + "index_offset": "45", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "45" + }, + "cosmosvalcons1awyus34e6laq3zxqsrv283w6fgn8w62z8f2w7l": { + "address": "cosmosvalcons1awyus34e6laq3zxqsrv283w6fgn8w62z8f2w7l", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1ryy20he94rlaryj04mkhcj6n4dhuhcytym4g7r": { + "address": "cosmosvalcons1ryy20he94rlaryj04mkhcj6n4dhuhcytym4g7r", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1rkl7umzewantxm5e8mf2l2tcxc3t7hj8djzmrw": { + "address": "cosmosvalcons1rkl7umzewantxm5e8mf2l2tcxc3t7hj8djzmrw", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1v08dcmtc5f444sxqfvqv8mxdclmc2759mh75r7": { + "address": "cosmosvalcons1v08dcmtc5f444sxqfvqv8mxdclmc2759mh75r7", + "start_height": "4", + "index_offset": "9", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "9" + }, + "cosmosvalcons1r5tg7kujl8x77c84dedr2z9agsjyp8tqq8hrc8": { + "address": "cosmosvalcons1r5tg7kujl8x77c84dedr2z9agsjyp8tqq8hrc8", + "start_height": "2", + "index_offset": "4", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons1dnt8cpf6lwldf4r99n03kuv8fqwfqkfc4ndrkr": { + "address": "cosmosvalcons1dnt8cpf6lwldf4r99n03kuv8fqwfqkfc4ndrkr", + "index_offset": "8", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1wzmzdml4fsakuyukmaa6qqee3g6w6qtc3szmzj": { + "address": "cosmosvalcons1wzmzdml4fsakuyukmaa6qqee3g6w6qtc3szmzj", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "21" + }, + "cosmosvalcons15dt0e900x5cv9w870mevztqwy88hhu2st8xhx4": { + "address": "cosmosvalcons15dt0e900x5cv9w870mevztqwy88hhu2st8xhx4", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons154epq0mwqz393frj38lh265h9slwdynmwkyxq9": { + "address": "cosmosvalcons154epq0mwqz393frj38lh265h9slwdynmwkyxq9", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "22" + }, + "cosmosvalcons16rv5x3545upw3qgemu6kz0cjd36lhvz2k2cpar": { + "address": "cosmosvalcons16rv5x3545upw3qgemu6kz0cjd36lhvz2k2cpar", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "20" + }, + "cosmosvalcons1xw7mpsuf4vma4a2thsad2623wjcgcy6u8yy8sa": { + "address": "cosmosvalcons1xw7mpsuf4vma4a2thsad2623wjcgcy6u8yy8sa", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1c07ez82s6kcfyg9szzg0pgghdpl7a2k0uc46p5": { + "address": "cosmosvalcons1c07ez82s6kcfyg9szzg0pgghdpl7a2k0uc46p5", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1eccz4hnumvgsqzpfgmvhc5vwh4ugptm56yyx9f": { + "address": "cosmosvalcons1eccz4hnumvgsqzpfgmvhc5vwh4ugptm56yyx9f", + "index_offset": "49", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1adwsqn58aype530jae9qrwknsxyf3wmwuynr3s": { + "address": "cosmosvalcons1adwsqn58aype530jae9qrwknsxyf3wmwuynr3s", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1qzj5kxv664trtfn4h0aznrsljtt2q95quzyrql": { + "address": "cosmosvalcons1qzj5kxv664trtfn4h0aznrsljtt2q95quzyrql", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1tnh79aat8d4m82pfm7gqa0z5kzzh7zty9nz93n": { + "address": "cosmosvalcons1tnh79aat8d4m82pfm7gqa0z5kzzh7zty9nz93n", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8e7x7qv": { + "address": "cosmosvalcons1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8e7x7qv", + "index_offset": "44", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "41" + }, + "cosmosvalcons1mfldj5ly78eg08sd2k3nygggjx765vvwr3sa2u": { + "address": "cosmosvalcons1mfldj5ly78eg08sd2k3nygggjx765vvwr3sa2u", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkjpwd47": { + "address": "cosmosvalcons1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkjpwd47", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1yva09usdkzdsqekaasgcqvm50v9vv5puyw2v3r": { + "address": "cosmosvalcons1yva09usdkzdsqekaasgcqvm50v9vv5puyw2v3r", + "start_height": "4", + "index_offset": "45", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "45" + }, + "cosmosvalcons1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3crkzxj": { + "address": "cosmosvalcons1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3crkzxj", + "index_offset": "43", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "41" + }, + "cosmosvalcons13fvz5er8rdttgtuwvcuaku00j2nw2v6kglpshq": { + "address": "cosmosvalcons13fvz5er8rdttgtuwvcuaku00j2nw2v6kglpshq", + "start_height": "6", + "index_offset": "43", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "23" + }, + "cosmosvalcons14dp6lpg8dqs4e0aq34vhcwpxt37nltefr2w0fk": { + "address": "cosmosvalcons14dp6lpg8dqs4e0aq34vhcwpxt37nltefr2w0fk", + "start_height": "8", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons14jvurctjcvs69hlppa0dkjplczns7zlqthruvy": { + "address": "cosmosvalcons14jvurctjcvs69hlppa0dkjplczns7zlqthruvy", + "start_height": "4", + "index_offset": "45", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "45" + }, + "cosmosvalcons144n7h95z7sz0r3k9rm3r8umkc89wt5c70h9mrh": { + "address": "cosmosvalcons144n7h95z7sz0r3k9rm3r8umkc89wt5c70h9mrh", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons18056m2nw355q2tjmvdslp9fqadmca5up2fcnvw": { + "address": "cosmosvalcons18056m2nw355q2tjmvdslp9fqadmca5up2fcnvw", + "index_offset": "7", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1sjhhg2yl2cqszte7pjyrp6lx5tg383lrs4rf0f": { + "address": "cosmosvalcons1sjhhg2yl2cqszte7pjyrp6lx5tg383lrs4rf0f", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1s728ea54m9u76dkd4x9ea3l5cvjjjkk5dgk8gv": { + "address": "cosmosvalcons1s728ea54m9u76dkd4x9ea3l5cvjjjkk5dgk8gv", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1ll2f2v79ssg5teg5trglr0wecm877aprwzvqh9": { + "address": "cosmosvalcons1ll2f2v79ssg5teg5trglr0wecm877aprwzvqh9", + "start_height": "1", + "index_offset": "45", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "7" + }, + "cosmosvalcons1qsxjdj8z2urjdxpp7uu37pp2pf3chjjcttwfff": { + "address": "cosmosvalcons1qsxjdj8z2urjdxpp7uu37pp2pf3chjjcttwfff", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1zjzkk7l2jalrspy6500my8v0yy6ycz7ewnkuzu": { + "address": "cosmosvalcons1zjzkk7l2jalrspy6500my8v0yy6ycz7ewnkuzu", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1r2ncmjrd4efnk9cjrftq7sw7347xqyu3va4mm8": { + "address": "cosmosvalcons1r2ncmjrd4efnk9cjrftq7sw7347xqyu3va4mm8", + "start_height": "5", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons19wgl6sjkktp7mysmmtzqnecd5v2xn7gs7022a6": { + "address": "cosmosvalcons19wgl6sjkktp7mysmmtzqnecd5v2xn7gs7022a6", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1dge9en6j6xl3njpkk8gvw9n326pgna44v3fc2z": { + "address": "cosmosvalcons1dge9en6j6xl3njpkk8gvw9n326pgna44v3fc2z", + "start_height": "5", + "index_offset": "7", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0v4sfcv": { + "address": "cosmosvalcons1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0v4sfcv", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons15tf0n2rqlh49324hrn0vzmj33fr7yk9tjs0up2": { + "address": "cosmosvalcons15tf0n2rqlh49324hrn0vzmj33fr7yk9tjs0up2", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons14lwqx5380234f0fshaycluz08yw74chl9wupjl": { + "address": "cosmosvalcons14lwqx5380234f0fshaycluz08yw74chl9wupjl", + "index_offset": "44", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "11" + }, + "cosmosvalcons1k7dl7gc3umxp45u8m8zc6evvus2gvjvcagsclr": { + "address": "cosmosvalcons1k7dl7gc3umxp45u8m8zc6evvus2gvjvcagsclr", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1hyv7jjh3kswlfc6nh0xp545rl5ttty2xe7j8l3": { + "address": "cosmosvalcons1hyv7jjh3kswlfc6nh0xp545rl5ttty2xe7j8l3", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc9jsr7n": { + "address": "cosmosvalcons1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc9jsr7n", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons17k35dydvkrdxup6z8633k3zcc4ecmgnz23jtdd": { + "address": "cosmosvalcons17k35dydvkrdxup6z8633k3zcc4ecmgnz23jtdd", + "start_height": "1", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1zukq6nknswp76ckcj5s9rnvmye974n7c3mmhnd": { + "address": "cosmosvalcons1zukq6nknswp76ckcj5s9rnvmye974n7c3mmhnd", + "index_offset": "8", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1terlqq72gje366346skcmzfgg4lqypf579w83k": { + "address": "cosmosvalcons1terlqq72gje366346skcmzfgg4lqypf579w83k", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1333066cp52k7fgmug2dwylafnymdxcg6zjcsez": { + "address": "cosmosvalcons1333066cp52k7fgmug2dwylafnymdxcg6zjcsez", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "19" + }, + "cosmosvalcons1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8pce0y2": { + "address": "cosmosvalcons1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8pce0y2", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3gvqu70": { + "address": "cosmosvalcons1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3gvqu70", + "index_offset": "13", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons18gmd4r8ydls55yvgda4d8pfandk0xem53e75t4": { + "address": "cosmosvalcons18gmd4r8ydls55yvgda4d8pfandk0xem53e75t4", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons138ueargdn7h3qhwdpvusu9uduacvm393y0rccz": { + "address": "cosmosvalcons138ueargdn7h3qhwdpvusu9uduacvm393y0rccz", + "start_height": "1", + "index_offset": "8", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons1jv7lxeryc30c0w4p7p92nxywgcnswuhshvzk3n": { + "address": "cosmosvalcons1jv7lxeryc30c0w4p7p92nxywgcnswuhshvzk3n", + "index_offset": "8", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1557a6swa3yv3ew9yk8hcfpyqu3ce7te0dualvr": { + "address": "cosmosvalcons1557a6swa3yv3ew9yk8hcfpyqu3ce7te0dualvr", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1h8wfu2kqcjeev96yddv3nj9r4q003essj2vrm3": { + "address": "cosmosvalcons1h8wfu2kqcjeev96yddv3nj9r4q003essj2vrm3", + "start_height": "4", + "index_offset": "43", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "43" + }, + "cosmosvalcons1q9ed2n5wvzcrymaqltypazqzd2xv8d5alnqqle": { + "address": "cosmosvalcons1q9ed2n5wvzcrymaqltypazqzd2xv8d5alnqqle", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "26" + }, + "cosmosvalcons19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyuhga22w": { + "address": "cosmosvalcons19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyuhga22w", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons18nag9zrh49uaxypx83fmlz85umq0t9j79nzvqa": { + "address": "cosmosvalcons18nag9zrh49uaxypx83fmlz85umq0t9j79nzvqa", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1vsuhkup8jznqt89zgv9nw8c3u3a7l3u80lyhm6": { + "address": "cosmosvalcons1vsuhkup8jznqt89zgv9nw8c3u3a7l3u80lyhm6", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "41" + }, + "cosmosvalcons155znzxm9g8j53k8vyp2d5qmrkzdum4d0a2nk2a": { + "address": "cosmosvalcons155znzxm9g8j53k8vyp2d5qmrkzdum4d0a2nk2a", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1hll5qzyzy4vrtdad5rqnf2jvf7srdnsymt6r3e": { + "address": "cosmosvalcons1hll5qzyzy4vrtdad5rqnf2jvf7srdnsymt6r3e", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1a0jdqzvk078d6486vuxdr5d0yp6rgluem5sadp": { + "address": "cosmosvalcons1a0jdqzvk078d6486vuxdr5d0yp6rgluem5sadp", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons17er26f88ee6l369a2qk7xmnt248gqtucyn7vxs": { + "address": "cosmosvalcons17er26f88ee6l369a2qk7xmnt248gqtucyn7vxs", + "start_height": "8", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "40" + }, + "cosmosvalcons17uqc5hqs6x7ccr7pcrafp8tfwsezt07ejfk5yc": { + "address": "cosmosvalcons17uqc5hqs6x7ccr7pcrafp8tfwsezt07ejfk5yc", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1xau5jp7uyewxcwg9tzwsxm895v3mf0fn04azmn": { + "address": "cosmosvalcons1xau5jp7uyewxcwg9tzwsxm895v3mf0fn04azmn", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1taucnwfqfkpq6c6y345j6h8jt5fffgla9rv3qf": { + "address": "cosmosvalcons1taucnwfqfkpq6c6y345j6h8jt5fffgla9rv3qf", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1jqkfaju29z0270cmm4zhygtzwjcuqjzx9d44za": { + "address": "cosmosvalcons1jqkfaju29z0270cmm4zhygtzwjcuqjzx9d44za", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y5mms0qg": { + "address": "cosmosvalcons1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y5mms0qg", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1n8emgp25g5wh4d9204lpd06gsznurtlpu09dtl": { + "address": "cosmosvalcons1n8emgp25g5wh4d9204lpd06gsznurtlpu09dtl", + "index_offset": "37", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons15zqzxj663h8g8naxyz324j2rpd3rnw4ravpspc": { + "address": "cosmosvalcons15zqzxj663h8g8naxyz324j2rpd3rnw4ravpspc", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons17nckqnw09secacg9y6r7pay02nhemww69ksle3": { + "address": "cosmosvalcons17nckqnw09secacg9y6r7pay02nhemww69ksle3", + "start_height": "1", + "index_offset": "46", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "46" + }, + "cosmosvalcons1s28wuj4yrqsmjm2cckx6mu037e92up2m2w36xt": { + "address": "cosmosvalcons1s28wuj4yrqsmjm2cckx6mu037e92up2m2w36xt", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1ndff2ha25wm2nhunxgfrzlnhvc5j06zve6f54r": { + "address": "cosmosvalcons1ndff2ha25wm2nhunxgfrzlnhvc5j06zve6f54r", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons16ll03qy5htuech4u0z432zertwhyxynl9khkh2": { + "address": "cosmosvalcons16ll03qy5htuech4u0z432zertwhyxynl9khkh2", + "index_offset": "6", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "6" + }, + "cosmosvalcons1x9mhtyr2tak88skl0nr4lq6k7jreus6n9s59vu": { + "address": "cosmosvalcons1x9mhtyr2tak88skl0nr4lq6k7jreus6n9s59vu", + "start_height": "1", + "index_offset": "4", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1fdfwthdupznzgrg2d8e96ryxqz8smppe6dxr7w": { + "address": "cosmosvalcons1fdfwthdupznzgrg2d8e96ryxqz8smppe6dxr7w", + "index_offset": "6", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons1f6qxvzgn7lfsvg2f86m30pshf8wuygk7w7wqdy": { + "address": "cosmosvalcons1f6qxvzgn7lfsvg2f86m30pshf8wuygk7w7wqdy", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1vjj3g3vkh56g04yqqsdn0yxcul9pve2rt04f87": { + "address": "cosmosvalcons1vjj3g3vkh56g04yqqsdn0yxcul9pve2rt04f87", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons10d3vd6yx9k9ns6v82r4krm3d4ragw04c4hun22": { + "address": "cosmosvalcons10d3vd6yx9k9ns6v82r4krm3d4ragw04c4hun22", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1evqmj6ahqf76keas4ymhvf4r992kg7wrvygqrw": { + "address": "cosmosvalcons1evqmj6ahqf76keas4ymhvf4r992kg7wrvygqrw", + "start_height": "12", + "index_offset": "37", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "16" + }, + "cosmosvalcons128xc6r596pllf46ev2cpaetcujfgmhay7tzcwd": { + "address": "cosmosvalcons128xc6r596pllf46ev2cpaetcujfgmhay7tzcwd", + "start_height": "47", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1dkwuxswrh5mx3mmmsny2qhwm4xtu33tynte2nf": { + "address": "cosmosvalcons1dkwuxswrh5mx3mmmsny2qhwm4xtu33tynte2nf", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1n08duqdkxwmqmtjaha236esw6r72njd2xy0fmg": { + "address": "cosmosvalcons1n08duqdkxwmqmtjaha236esw6r72njd2xy0fmg", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "6" + }, + "cosmosvalcons1n5n6d47c4ntac509rtq3s620vmcqcf97ygkv7e": { + "address": "cosmosvalcons1n5n6d47c4ntac509rtq3s620vmcqcf97ygkv7e", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a7ha5z7": { + "address": "cosmosvalcons1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a7ha5z7", + "start_height": "14", + "index_offset": "35", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1707yw2jgerkawrdyylsj4vll8k2ww5evjmxc5a": { + "address": "cosmosvalcons1707yw2jgerkawrdyylsj4vll8k2ww5evjmxc5a", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "28" + }, + "cosmosvalcons1z97a2xx0rzwtfftg3k9yt693dwxx9j80749vks": { + "address": "cosmosvalcons1z97a2xx0rzwtfftg3k9yt693dwxx9j80749vks", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalaatgcxv": { + "address": "cosmosvalcons1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalaatgcxv", + "start_height": "1", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7uajcn9": { + "address": "cosmosvalcons1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7uajcn9", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons14q9rupnazu0mmkjd9skpn2zdfs8d0hlgx9xl07": { + "address": "cosmosvalcons14q9rupnazu0mmkjd9skpn2zdfs8d0hlgx9xl07", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons16v3h2mggt8tnkxp0vq5tq25fhr3knvf4rfjxlx": { + "address": "cosmosvalcons16v3h2mggt8tnkxp0vq5tq25fhr3knvf4rfjxlx", + "start_height": "6", + "index_offset": "43", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "19" + }, + "cosmosvalcons179uxhryqvrkxa2wtnw2cnptdt80qc24kksm9ly": { + "address": "cosmosvalcons179uxhryqvrkxa2wtnw2cnptdt80qc24kksm9ly", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1fjct2f29ymrw9h7aqffafx863c4tkxdh5c95y4": { + "address": "cosmosvalcons1fjct2f29ymrw9h7aqffafx863c4tkxdh5c95y4", + "start_height": "4", + "index_offset": "45", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "21" + }, + "cosmosvalcons1fhpyqq3eex5zcctlgsxj3s3dgz64am96pv0u6u": { + "address": "cosmosvalcons1fhpyqq3eex5zcctlgsxj3s3dgz64am96pv0u6u", + "start_height": "48", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons13296rs6uwadjwya2l2uc2jzxgyllcjm2sl0ym0": { + "address": "cosmosvalcons13296rs6uwadjwya2l2uc2jzxgyllcjm2sl0ym0", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons13spl9rpkd0wd9c32mpsd9h6phwwnxu3uzvy8tm": { + "address": "cosmosvalcons13spl9rpkd0wd9c32mpsd9h6phwwnxu3uzvy8tm", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1n5t5rr83k3emp5e446qjprj0svsh06rw33397a": { + "address": "cosmosvalcons1n5t5rr83k3emp5e446qjprj0svsh06rw33397a", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1mcvztyynwvn7lelqx89xuzzuguhx5xm7usl4un": { + "address": "cosmosvalcons1mcvztyynwvn7lelqx89xuzzuguhx5xm7usl4un", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons1znvpcj20duymyac6cl4r8kcf827aqu60amp48q": { + "address": "cosmosvalcons1znvpcj20duymyac6cl4r8kcf827aqu60amp48q", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1zah0g92ytwdvpchd3sceuanu7knhtu22yt5z5y": { + "address": "cosmosvalcons1zah0g92ytwdvpchd3sceuanu7knhtu22yt5z5y", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons19qqvhp8aacjvxjhtgwncctmtrmjelqs62ar4s5": { + "address": "cosmosvalcons19qqvhp8aacjvxjhtgwncctmtrmjelqs62ar4s5", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1t7wt4qjfsa4kncvvya5m99mq0m53n9e8q9m6p5": { + "address": "cosmosvalcons1t7wt4qjfsa4kncvvya5m99mq0m53n9e8q9m6p5", + "start_height": "1", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1ng5m6spxngyne4qzce35fdg0whl0yqgv5c0vte": { + "address": "cosmosvalcons1ng5m6spxngyne4qzce35fdg0whl0yqgv5c0vte", + "start_height": "8", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "40" + }, + "cosmosvalcons14rhly0ayx5ewyldmrp8kn564wnn8aascwe6d59": { + "address": "cosmosvalcons14rhly0ayx5ewyldmrp8kn564wnn8aascwe6d59", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1mdes9dapqu6vr094qc6wyhd9jt7qfwvjm5cyw3": { + "address": "cosmosvalcons1mdes9dapqu6vr094qc6wyhd9jt7qfwvjm5cyw3", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons178gvnxtnq2n4m23492m7agshjv3zgzy3zzg47d": { + "address": "cosmosvalcons178gvnxtnq2n4m23492m7agshjv3zgzy3zzg47d", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1dzuk49ssprfz3ala9tea3x74x8n2nlyz4zj52j": { + "address": "cosmosvalcons1dzuk49ssprfz3ala9tea3x74x8n2nlyz4zj52j", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "22" + }, + "cosmosvalcons10qj9cj3dxecyu826gaw72ylwum96jkkh5xjn2j": { + "address": "cosmosvalcons10qj9cj3dxecyu826gaw72ylwum96jkkh5xjn2j", + "start_height": "12", + "index_offset": "37", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1ekx8n2y3x9qq34c2uy8fdh400hp8msqufqgdhe": { + "address": "cosmosvalcons1ekx8n2y3x9qq34c2uy8fdh400hp8msqufqgdhe", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1urnp7yp6u27nut8kvsrapgmmvk8sh6u5l2nyes": { + "address": "cosmosvalcons1urnp7yp6u27nut8kvsrapgmmvk8sh6u5l2nyes", + "start_height": "5", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1alxfwr8v98tw6tm4jhgdu2hu5gy0umv88caft8": { + "address": "cosmosvalcons1alxfwr8v98tw6tm4jhgdu2hu5gy0umv88caft8", + "start_height": "47", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons17z20092e9s2ttlzkpzv209dsxsxs946jk0ph4e": { + "address": "cosmosvalcons17z20092e9s2ttlzkpzv209dsxsxs946jk0ph4e", + "start_height": "1", + "index_offset": "7", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "7" + }, + "cosmosvalcons1zyp4lvynuuz8vzmzprpy8mxm4rkql6ry6509hk": { + "address": "cosmosvalcons1zyp4lvynuuz8vzmzprpy8mxm4rkql6ry6509hk", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons19ve7rrjrngdgf6pfaj87csf4rwykqdmhgnsd2w": { + "address": "cosmosvalcons19ve7rrjrngdgf6pfaj87csf4rwykqdmhgnsd2w", + "start_height": "2", + "index_offset": "46", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "21" + }, + "cosmosvalcons15ughagcacjqyaa0f7d28xtev88v5vh693t8f8y": { + "address": "cosmosvalcons15ughagcacjqyaa0f7d28xtev88v5vh693t8f8y", + "index_offset": "44", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "42" + }, + "cosmosvalcons14upsvttjem96xlz8rfsw4zqt234jnqy8vxuxkp": { + "address": "cosmosvalcons14upsvttjem96xlz8rfsw4zqt234jnqy8vxuxkp", + "start_height": "1", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "47" + }, + "cosmosvalcons1c2tutqjg5cqcvt6qen2x6enval6t5pyddwna5e": { + "address": "cosmosvalcons1c2tutqjg5cqcvt6qen2x6enval6t5pyddwna5e", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1mzsvp23mjrjkspddkz6nta0x7kte6a23vv0nmd": { + "address": "cosmosvalcons1mzsvp23mjrjkspddkz6nta0x7kte6a23vv0nmd", + "index_offset": "13", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "13" + }, + "cosmosvalcons1znvq8jqpwxt5hk2lg5654l7eg7kap3rpe4uu6c": { + "address": "cosmosvalcons1znvq8jqpwxt5hk2lg5654l7eg7kap3rpe4uu6c", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1fhnwxus6yyk6lman2qf9fzuqtekl7gcwhqc8q8": { + "address": "cosmosvalcons1fhnwxus6yyk6lman2qf9fzuqtekl7gcwhqc8q8", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56man4rq": { + "address": "cosmosvalcons1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56man4rq", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1kfnt5d5fcma9kh4c5jk85yu75jer72kwucvp4z": { + "address": "cosmosvalcons1kfnt5d5fcma9kh4c5jk85yu75jer72kwucvp4z", + "start_height": "48", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1elu2xlg8qw8st5nppxvgszeyzhm4ht8zhsl8cf": { + "address": "cosmosvalcons1elu2xlg8qw8st5nppxvgszeyzhm4ht8zhsl8cf", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1q9tcvremyhu80vylcpenp9str7wn0qf0sxv9ar": { + "address": "cosmosvalcons1q9tcvremyhu80vylcpenp9str7wn0qf0sxv9ar", + "start_height": "1", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1gpk39c5dc4xnevhz4c7m2sjxequw30s32598cq": { + "address": "cosmosvalcons1gpk39c5dc4xnevhz4c7m2sjxequw30s32598cq", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "18" + }, + "cosmosvalcons13y2zjpgaj07umx7a3dsg9ffhpkk22g73yzdk5r": { + "address": "cosmosvalcons13y2zjpgaj07umx7a3dsg9ffhpkk22g73yzdk5r", + "start_height": "14", + "index_offset": "35", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "34" + }, + "cosmosvalcons15cnzrhl4pe7ekkp0djmyupahdsjjmmkv0q80ee": { + "address": "cosmosvalcons15cnzrhl4pe7ekkp0djmyupahdsjjmmkv0q80ee", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons14j4mehgc448s2m7cr0uqm3pmvjxav94w28qxw8": { + "address": "cosmosvalcons14j4mehgc448s2m7cr0uqm3pmvjxav94w28qxw8", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1kses5l7n9382eay7524cmut5p7en64ldylzjw2": { + "address": "cosmosvalcons1kses5l7n9382eay7524cmut5p7en64ldylzjw2", + "start_height": "8", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "16" + }, + "cosmosvalcons1hwea4x7eagt83nvaz93q3q5gpje64nczejpn33": { + "address": "cosmosvalcons1hwea4x7eagt83nvaz93q3q5gpje64nczejpn33", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3x59pmh": { + "address": "cosmosvalcons1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3x59pmh", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons17e6r58yvwdtyrzxudfrp8gp3zk2mdxd58u87ag": { + "address": "cosmosvalcons17e6r58yvwdtyrzxudfrp8gp3zk2mdxd58u87ag", + "start_height": "1", + "index_offset": "44", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "5" + }, + "cosmosvalcons18p7qvgvjcpl85mjwtvepe9reevevnm9fv605n2": { + "address": "cosmosvalcons18p7qvgvjcpl85mjwtvepe9reevevnm9fv605n2", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons18wfnjhyqjzjpa5pgd3r5n987uet7qczjdf0rvj": { + "address": "cosmosvalcons18wfnjhyqjzjpa5pgd3r5n987uet7qczjdf0rvj", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons187wgdejp6c2h502gtkzxcpn6qgrw9q547kejc7": { + "address": "cosmosvalcons187wgdejp6c2h502gtkzxcpn6qgrw9q547kejc7", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "17" + }, + "cosmosvalcons1twyey6dyu57e7p8lahwgr9ql2pyn6774gnvtex": { + "address": "cosmosvalcons1twyey6dyu57e7p8lahwgr9ql2pyn6774gnvtex", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1twu2lvgp3erk6gups2a8nae3jdahaj2x2cmqs0": { + "address": "cosmosvalcons1twu2lvgp3erk6gups2a8nae3jdahaj2x2cmqs0", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1fuge5wmj546lq6ljv9zfzjjgknrfmngv7pt5pq": { + "address": "cosmosvalcons1fuge5wmj546lq6ljv9zfzjjgknrfmngv7pt5pq", + "index_offset": "49", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons12rjah2jl9jpqwddh20vph9yu448d76252t8yzm": { + "address": "cosmosvalcons12rjah2jl9jpqwddh20vph9yu448d76252t8yzm", + "index_offset": "49", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1rpxgsrsrx8jntwa6q9m0a4xxypnphs9znygvp6": { + "address": "cosmosvalcons1rpxgsrsrx8jntwa6q9m0a4xxypnphs9znygvp6", + "index_offset": "44", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "44" + }, + "cosmosvalcons1re5reme6kyayzfanalqm89u2r9an6wu97g0svk": { + "address": "cosmosvalcons1re5reme6kyayzfanalqm89u2r9an6wu97g0svk", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons19fa3uz9n80megf46sfu7kzepfup4mjcctf7cjl": { + "address": "cosmosvalcons19fa3uz9n80megf46sfu7kzepfup4mjcctf7cjl", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzml74vet": { + "address": "cosmosvalcons1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzml74vet", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "25" + }, + "cosmosvalcons1fv35lda8ltd6juk384yqceqalcxyfj4kplptte": { + "address": "cosmosvalcons1fv35lda8ltd6juk384yqceqalcxyfj4kplptte", + "start_height": "48", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1tftatt0lp0v59qqf449pdqar8w3yj7n7h6eekg": { + "address": "cosmosvalcons1tftatt0lp0v59qqf449pdqar8w3yj7n7h6eekg", + "start_height": "47", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons10xwf26gupjlr4xt69pl779346w7yytxha4ymw0": { + "address": "cosmosvalcons10xwf26gupjlr4xt69pl779346w7yytxha4ymw0", + "start_height": "13", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1nraptt0aagws66pcvnc92kjus460k3l09w274n": { + "address": "cosmosvalcons1nraptt0aagws66pcvnc92kjus460k3l09w274n", + "start_height": "8", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "41" + }, + "cosmosvalcons1hpwfm40p8dwmwtmhdnmazywy79uywk8xxx9cg9": { + "address": "cosmosvalcons1hpwfm40p8dwmwtmhdnmazywy79uywk8xxx9cg9", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqzhzl6w": { + "address": "cosmosvalcons1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqzhzl6w", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1fc96780mrsxn5kgplhtna40qepjgrm9wprcd0c": { + "address": "cosmosvalcons1fc96780mrsxn5kgplhtna40qepjgrm9wprcd0c", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons10t3ld5fvsvy7kye7p409he8dk5q23tep9u5whq": { + "address": "cosmosvalcons10t3ld5fvsvy7kye7p409he8dk5q23tep9u5whq", + "start_height": "2", + "index_offset": "12", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "7" + }, + "cosmosvalcons1ty5s8h0gwtc285mnxwq43cyt2s58g25gfu8xm6": { + "address": "cosmosvalcons1ty5s8h0gwtc285mnxwq43cyt2s58g25gfu8xm6", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "47" + }, + "cosmosvalcons1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4f3ekeh": { + "address": "cosmosvalcons1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4f3ekeh", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1sfewn0rgaw0fqw8lks6ygek6ulmcy3nm4mt3g5": { + "address": "cosmosvalcons1sfewn0rgaw0fqw8lks6ygek6ulmcy3nm4mt3g5", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1pv9f0ze6vmq3qvy29fywmj2eh2cpneymxky07j": { + "address": "cosmosvalcons1pv9f0ze6vmq3qvy29fywmj2eh2cpneymxky07j", + "start_height": "48", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1pjwsvz9745jftv0p0c99t36m6kf9e8rxc2k8gj": { + "address": "cosmosvalcons1pjwsvz9745jftv0p0c99t36m6kf9e8rxc2k8gj", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1glku8mx4nzp5crkjt7px9lfe4flfge3zcajzul": { + "address": "cosmosvalcons1glku8mx4nzp5crkjt7px9lfe4flfge3zcajzul", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons12q3w0j5hp023hdjafgc357hy7kkha296cjp2jm": { + "address": "cosmosvalcons12q3w0j5hp023hdjafgc357hy7kkha296cjp2jm", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1tz087eh88lqkesr77yl6ys9dw95qysfq6wwa20": { + "address": "cosmosvalcons1tz087eh88lqkesr77yl6ys9dw95qysfq6wwa20", + "start_height": "7", + "index_offset": "42", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "42" + }, + "cosmosvalcons1nxr7alffy7zt9gg4285a67ts977pcgaarr7lgd": { + "address": "cosmosvalcons1nxr7alffy7zt9gg4285a67ts977pcgaarr7lgd", + "start_height": "48", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar5y5n7y": { + "address": "cosmosvalcons1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar5y5n7y", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1edwe9quhqnxa4yvqu2ks656guv6rjzhtgr7r6g": { + "address": "cosmosvalcons1edwe9quhqnxa4yvqu2ks656guv6rjzhtgr7r6g", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1x4yzfjt777agvsfz6cskjst7v7k42xc69qcru2": { + "address": "cosmosvalcons1x4yzfjt777agvsfz6cskjst7v7k42xc69qcru2", + "index_offset": "6", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "6" + }, + "cosmosvalcons1864wj4twqatq54rrxl5jmfey55tmh0hveu2vyu": { + "address": "cosmosvalcons1864wj4twqatq54rrxl5jmfey55tmh0hveu2vyu", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zzp9hc2": { + "address": "cosmosvalcons1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zzp9hc2", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1sxmqgulmqw6nxw4f9lxt565hzyj246nj9em88q": { + "address": "cosmosvalcons1sxmqgulmqw6nxw4f9lxt565hzyj246nj9em88q", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "25" + }, + "cosmosvalcons1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx5uzsa7": { + "address": "cosmosvalcons1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx5uzsa7", + "start_height": "2", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1zf34ku927tasyr9fswhasvqt0x49janzmpm3cd": { + "address": "cosmosvalcons1zf34ku927tasyr9fswhasvqt0x49janzmpm3cd", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1z7ruhrtfg8v2xv8egfyxldt2xaygspykp95zz7": { + "address": "cosmosvalcons1z7ruhrtfg8v2xv8egfyxldt2xaygspykp95zz7", + "start_height": "2", + "index_offset": "4", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr338lh7": { + "address": "cosmosvalcons1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr338lh7", + "index_offset": "9", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons12nv5therrzkwjmvrmmnng6uqk2d8u6y70wempr": { + "address": "cosmosvalcons12nv5therrzkwjmvrmmnng6uqk2d8u6y70wempr", + "index_offset": "46", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "44" + }, + "cosmosvalcons1wkt8xe20zdph4ak9vqx2supe3v2gq3wyr7dmne": { + "address": "cosmosvalcons1wkt8xe20zdph4ak9vqx2supe3v2gq3wyr7dmne", + "index_offset": "3", + "jailed_until": "9999-12-31T23:59:59Z", + "tombstoned": true + }, + "cosmosvalcons1sp9hxsl3s8pyj3cs84acgwrkxl85yk88wm5cf7": { + "address": "cosmosvalcons1sp9hxsl3s8pyj3cs84acgwrkxl85yk88wm5cf7", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1chjcdfygnalpfjrjc8ku8vknx782xf7em93zkx": { + "address": "cosmosvalcons1chjcdfygnalpfjrjc8ku8vknx782xf7em93zkx", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "47" + }, + "cosmosvalcons1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkaw34gh": { + "address": "cosmosvalcons1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkaw34gh", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1mh9g99ncua6cecyd5meepx9hecyy3e24y7rey9": { + "address": "cosmosvalcons1mh9g99ncua6cecyd5meepx9hecyy3e24y7rey9", + "index_offset": "49", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "47" + }, + "cosmosvalcons17da97e4gq5p2zavzcd0zmsh7ez540j0ctxc8nz": { + "address": "cosmosvalcons17da97e4gq5p2zavzcd0zmsh7ez540j0ctxc8nz", + "start_height": "1", + "index_offset": "1", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1zlyfewtaxumsyj34fkml4t54yvhqcls4g7u5nm": { + "address": "cosmosvalcons1zlyfewtaxumsyj34fkml4t54yvhqcls4g7u5nm", + "index_offset": "6", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "6" + }, + "cosmosvalcons1f2sunjkaqyu2wr9jupyjkl7qhlnesag7egqylw": { + "address": "cosmosvalcons1f2sunjkaqyu2wr9jupyjkl7qhlnesag7egqylw", + "index_offset": "43", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "43" + }, + "cosmosvalcons12ud83clhrm4jemkal6v0489e0cdm8x0l6frftz": { + "address": "cosmosvalcons12ud83clhrm4jemkal6v0489e0cdm8x0l6frftz", + "index_offset": "9", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1twg3k83aluz6nsqt09pa246rg5wg6fhwdlrqd5": { + "address": "cosmosvalcons1twg3k83aluz6nsqt09pa246rg5wg6fhwdlrqd5", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1dn2s4tgdyjcgpcq6pfw5shzry50veuh8vcq4zc": { + "address": "cosmosvalcons1dn2s4tgdyjcgpcq6pfw5shzry50veuh8vcq4zc", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1n9dqelmmf5kfysk24m6chqfdcgz6r75u0ux4w9": { + "address": "cosmosvalcons1n9dqelmmf5kfysk24m6chqfdcgz6r75u0ux4w9", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "7" + }, + "cosmosvalcons1c08mlht3skve88xx8eth4zgtpr2nhjfawyw6qj": { + "address": "cosmosvalcons1c08mlht3skve88xx8eth4zgtpr2nhjfawyw6qj", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1evys94earewfdh658d0u67j28lq2ltezjkm72y": { + "address": "cosmosvalcons1evys94earewfdh658d0u67j28lq2ltezjkm72y", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1lamxh5pswk923tm9mtmvd4t6pqru5cdtjnrxuu": { + "address": "cosmosvalcons1lamxh5pswk923tm9mtmvd4t6pqru5cdtjnrxuu", + "start_height": "1", + "index_offset": "46", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "24" + }, + "cosmosvalcons1f2pvewnws73u0z5wsfmv5uqudwxl6jupcua6t0": { + "address": "cosmosvalcons1f2pvewnws73u0z5wsfmv5uqudwxl6jupcua6t0", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2esn3du": { + "address": "cosmosvalcons1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2esn3du", + "start_height": "1", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2k77jcj": { + "address": "cosmosvalcons1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2k77jcj", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons1hc5k2vf82jswmnlfrrav6u2kf6rn39mppx25wn": { + "address": "cosmosvalcons1hc5k2vf82jswmnlfrrav6u2kf6rn39mppx25wn", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1l2mzrv0nvs75mjj5nzz966jxklfn9wt6l55sw2": { + "address": "cosmosvalcons1l2mzrv0nvs75mjj5nzz966jxklfn9wt6l55sw2", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1q54ra6ur0wgyamdtgkn7fnmawf00tcj6cvttsq": { + "address": "cosmosvalcons1q54ra6ur0wgyamdtgkn7fnmawf00tcj6cvttsq", + "index_offset": "3", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons193pvwgxpxnd6tgz0gtyl00dq8r3ygeflzs60pf": { + "address": "cosmosvalcons193pvwgxpxnd6tgz0gtyl00dq8r3ygeflzs60pf", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1fqmkps3v8evytw9jmpg3g83a6s0fy8m2xw9kpa": { + "address": "cosmosvalcons1fqmkps3v8evytw9jmpg3g83a6s0fy8m2xw9kpa", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1mmjkdjsqluxlggcl082j977kv8fwp4u0p4fshs": { + "address": "cosmosvalcons1mmjkdjsqluxlggcl082j977kv8fwp4u0p4fshs", + "start_height": "12", + "index_offset": "37", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "36" + }, + "cosmosvalcons1744t93tc6ulm87ccsc47mkl30qz65n8pmtgywr": { + "address": "cosmosvalcons1744t93tc6ulm87ccsc47mkl30qz65n8pmtgywr", + "start_height": "7", + "index_offset": "5", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7f3wcwa": { + "address": "cosmosvalcons1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7f3wcwa", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + }, + "cosmosvalcons18fkw6s4hnj2llxljrkleetgns2y0h0vjeq3jem": { + "address": "cosmosvalcons18fkw6s4hnj2llxljrkleetgns2y0h0vjeq3jem", + "start_height": "47", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1j7352v6z3xcf9y5qusgdxectvn8dv962h27ny2": { + "address": "cosmosvalcons1j7352v6z3xcf9y5qusgdxectvn8dv962h27ny2", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta96zmmy": { + "address": "cosmosvalcons1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta96zmmy", + "start_height": "1", + "index_offset": "7", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons178pm30fcgrt5654czwr8nlex050m6y6050c02z": { + "address": "cosmosvalcons178pm30fcgrt5654czwr8nlex050m6y6050c02z", + "start_height": "8", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "4" + }, + "cosmosvalcons1l4dqy53d57ul42xd8wzs5zxk4ywkc7axqkmnn5": { + "address": "cosmosvalcons1l4dqy53d57ul42xd8wzs5zxk4ywkc7axqkmnn5", + "start_height": "2", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1yr5ztk7t7w329lllmylgz6wnfk664qu0xdmvm3": { + "address": "cosmosvalcons1yr5ztk7t7w329lllmylgz6wnfk664qu0xdmvm3", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1xnh4mumajk76tlnsp8d3d95r7hjnt4drueld2m": { + "address": "cosmosvalcons1xnh4mumajk76tlnsp8d3d95r7hjnt4drueld2m", + "start_height": "49", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1f3j0m80ey8ujgfg783838jqnuw63h3v0yvqnpu": { + "address": "cosmosvalcons1f3j0m80ey8ujgfg783838jqnuw63h3v0yvqnpu", + "start_height": "4", + "index_offset": "45", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "45" + }, + "cosmosvalcons13jxw6xalnpvapujvmm6mc6qn3dk4sn6ktfuppf": { + "address": "cosmosvalcons13jxw6xalnpvapujvmm6mc6qn3dk4sn6ktfuppf", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "3" + }, + "cosmosvalcons1nas3l2avd9hymfeqznjmrw7sde8ual5k5f5hvz": { + "address": "cosmosvalcons1nas3l2avd9hymfeqznjmrw7sde8ual5k5f5hvz", + "start_height": "2", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "24" + }, + "cosmosvalcons1g58m70guf3p7y6hhf5trqmhzpzn99rvr8mla5z": { + "address": "cosmosvalcons1g58m70guf3p7y6hhf5trqmhzpzn99rvr8mla5z", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1wr9032gj6t9s9schc5vnwe9kkee7qkgpmawqtu": { + "address": "cosmosvalcons1wr9032gj6t9s9schc5vnwe9kkee7qkgpmawqtu", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons13cydnwjmscxtqtjywk9atr9uwlm6703mlvr3n3": { + "address": "cosmosvalcons13cydnwjmscxtqtjywk9atr9uwlm6703mlvr3n3", + "start_height": "8", + "index_offset": "41", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "16" + }, + "cosmosvalcons15qje22esqaz79y27940s3ng7r7afx3vv8c7j72": { + "address": "cosmosvalcons15qje22esqaz79y27940s3ng7r7afx3vv8c7j72", + "start_height": "1", + "index_offset": "47", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1478sx3zdfylsts5sus5rlz4dgvyvacqpdlsm6m": { + "address": "cosmosvalcons1478sx3zdfylsts5sus5rlz4dgvyvacqpdlsm6m", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "49" + }, + "cosmosvalcons1hyzzthl6vy5vjucaalz9w6fkyqne5p55fe4j85": { + "address": "cosmosvalcons1hyzzthl6vy5vjucaalz9w6fkyqne5p55fe4j85", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "1" + }, + "cosmosvalcons1eumpungfa2vmx20e27wnu6t0rtmrlmv3unjt4s": { + "address": "cosmosvalcons1eumpungfa2vmx20e27wnu6t0rtmrlmv3unjt4s", + "index_offset": "9", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "9" + }, + "cosmosvalcons18r683wlut54pd8sjzz45ujq8nu4wfr65s5sce8": { + "address": "cosmosvalcons18r683wlut54pd8sjzz45ujq8nu4wfr65s5sce8", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "2" + }, + "cosmosvalcons1dtdk5uytf6kv668r6l6d6cf947mdu38f5hwyap": { + "address": "cosmosvalcons1dtdk5uytf6kv668r6l6d6cf947mdu38f5hwyap", + "index_offset": "50", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "50" + }, + "cosmosvalcons1sjg96xpaa2cayeym6w3a2t38n7gm9zcsj94xgy": { + "address": "cosmosvalcons1sjg96xpaa2cayeym6w3a2t38n7gm9zcsj94xgy", + "index_offset": "2", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1n9lefg5g0mz4glppdt994nsxzg6pxscq20ppwj": { + "address": "cosmosvalcons1n9lefg5g0mz4glppdt994nsxzg6pxscq20ppwj", + "index_offset": "40", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "37" + }, + "cosmosvalcons152vx4n8032chkrgh97h05rs3mtdz3nuc2ke0hg": { + "address": "cosmosvalcons152vx4n8032chkrgh97h05rs3mtdz3nuc2ke0hg", + "index_offset": "4", + "jailed_until": "1970-01-01T00:00:00Z" + }, + "cosmosvalcons1luynvvt3qre3hzald2tdjtah6vw00hdcp4l3d3": { + "address": "cosmosvalcons1luynvvt3qre3hzald2tdjtah6vw00hdcp4l3d3", + "start_height": "1", + "index_offset": "48", + "jailed_until": "1970-01-01T00:00:00Z", + "missed_blocks_counter": "48" + } + }, + "missed_blocks": { + "cosmosvalcons1r5tg7kujl8x77c84dedr2z9agsjyp8tqq8hrc8": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + } + ], + "cosmosvalcons1r4czpmmu87t7zhlh34zrzna9gkex4ap5eqd50s": [], + "cosmosvalcons10cl6sallgwf882apcyagjqa2lx4j8592f4fxgm": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y5mms0qg": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1q9tcvremyhu80vylcpenp9str7wn0qf0sxv9ar": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons1zjw6x8t95zuaxprcyl0x6l7u0ag6626v0fzay6": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1ndff2ha25wm2nhunxgfrzlnhvc5j06zve6f54r": [], + "cosmosvalcons14qy520rhr0qytqxdtsjsu9rgw708n2w6ex2jmj": [ + { + "index": "13", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar5y5n7y": [], + "cosmosvalcons1m8gpgklc8a2yla9ah9y8mlu226n0mu4ym3qdze": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + } + ], + "cosmosvalcons172lmu2psqlkxkthpr46h2ewjffte7lhl2f7nt6": [ + { + "index": "14", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "45", + "missed": true + } + ], + "cosmosvalcons1q9ed2n5wvzcrymaqltypazqzd2xv8d5alnqqle": [ + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1jf2wka8xprke2q6qxq2vz3khe4mqxv75jvgj02": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + } + ], + "cosmosvalcons1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a7ha5z7": [ + { + "index": "9", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "25", + "missed": true + } + ], + "cosmosvalcons1c08mlht3skve88xx8eth4zgtpr2nhjfawyw6qj": [ + { + "index": "8", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1nfurwjwfy3zhw0g9eqcclzeejf9nqw62ewmwyr": [ + { + "index": "0", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "36", + "missed": true + } + ], + "cosmosvalcons1hyv7jjh3kswlfc6nh0xp545rl5ttty2xe7j8l3": [], + "cosmosvalcons19wgl6sjkktp7mysmmtzqnecd5v2xn7gs7022a6": [ + { + "index": "6", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "45", + "missed": true + } + ], + "cosmosvalcons1trkrhq6mxwktf24u8jepelvumpd9l6lehelksx": [ + { + "index": "27", + "missed": true + } + ], + "cosmosvalcons1dtdk5uytf6kv668r6l6d6cf947mdu38f5hwyap": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1n8emgp25g5wh4d9204lpd06gsznurtlpu09dtl": [ + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "36", + "missed": true + } + ], + "cosmosvalcons1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux0fv6ry": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtp8l6ug4": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + } + ], + "cosmosvalcons18056m2nw355q2tjmvdslp9fqadmca5up2fcnvw": [], + "cosmosvalcons1sxmqgulmqw6nxw4f9lxt565hzyj246nj9em88q": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons14se5hzhf43yk83pkztukhtlfu683s4ktcqzgvs": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons16xal57nga5gd2qxkz869qv7hm20xn0rkyfusws": [ + { + "index": "5", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons14jvurctjcvs69hlppa0dkjplczns7zlqthruvy": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + } + ], + "cosmosvalcons14lwqx5380234f0fshaycluz08yw74chl9wupjl": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "35", + "missed": true + } + ], + "cosmosvalcons1kses5l7n9382eay7524cmut5p7en64ldylzjw2": [ + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + } + ], + "cosmosvalcons1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76v6c2hww": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons1qw9wqlz92hj8y6mcj24l6wu68er03njuzuu92s": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1zyp4lvynuuz8vzmzprpy8mxm4rkql6ry6509hk": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zzp9hc2": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1vjj3g3vkh56g04yqqsdn0yxcul9pve2rt04f87": [], + "cosmosvalcons1mfldj5ly78eg08sd2k3nygggjx765vvwr3sa2u": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1gd779gn33yuxxla5pm5dphglcyx4ulzd86ldf8": [ + { + "index": "0", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "24", + "missed": true + } + ], + "cosmosvalcons12q3w0j5hp023hdjafgc357hy7kkha296cjp2jm": [ + { + "index": "13", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0v4sfcv": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1sjg96xpaa2cayeym6w3a2t38n7gm9zcsj94xgy": [], + "cosmosvalcons13296rs6uwadjwya2l2uc2jzxgyllcjm2sl0ym0": [ + { + "index": "15", + "missed": true + }, + { + "index": "22", + "missed": true + } + ], + "cosmosvalcons1h6j4lyvuenmz9m7vq3hler8j7pg5ldpe6gpq90": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1mh9g99ncua6cecyd5meepx9hecyy3e24y7rey9": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1qqe0t0j86umq0379kjcmjg00yd6ddrdw9cehas": [], + "cosmosvalcons1q55pmsr0wnpzlcx25p9vqde6c52ekjnvysqusa": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkjpwd47": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons12ud83clhrm4jemkal6v0489e0cdm8x0l6frftz": [], + "cosmosvalcons1707yw2jgerkawrdyylsj4vll8k2ww5evjmxc5a": [ + { + "index": "2", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1qy0qwzljplfauvyhgayw6nxte2zxujh4658x9s": [], + "cosmosvalcons1glku8mx4nzp5crkjt7px9lfe4flfge3zcajzul": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons12f4fpl936ld8c64dxqgwv65p42na8dcnaz0hkw": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + } + ], + "cosmosvalcons1dnt8cpf6lwldf4r99n03kuv8fqwfqkfc4ndrkr": [], + "cosmosvalcons17er26f88ee6l369a2qk7xmnt248gqtucyn7vxs": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + } + ], + "cosmosvalcons1zscesuffz58dc0lq7yy6n6z3j5fhkr3du7aulk": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1zah0g92ytwdvpchd3sceuanu7knhtu22yt5z5y": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons14rhly0ayx5ewyldmrp8kn564wnn8aascwe6d59": [ + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons16rv5x3545upw3qgemu6kz0cjd36lhvz2k2cpar": [ + { + "index": "2", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons138ueargdn7h3qhwdpvusu9uduacvm393y0rccz": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + } + ], + "cosmosvalcons13mztfedkzpz634g7u5fh8henfmvzyrfflw7r8u": [], + "cosmosvalcons15pl2c2umxszwar75aft99kns0ltmpepnzxvvya": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + } + ], + "cosmosvalcons14q9rupnazu0mmkjd9skpn2zdfs8d0hlgx9xl07": [ + { + "index": "1", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1xw7mpsuf4vma4a2thsad2623wjcgcy6u8yy8sa": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1fqmkps3v8evytw9jmpg3g83a6s0fy8m2xw9kpa": [ + { + "index": "10", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "36", + "missed": true + } + ], + "cosmosvalcons1twg3k83aluz6nsqt09pa246rg5wg6fhwdlrqd5": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56man4rq": [], + "cosmosvalcons1h8wfu2kqcjeev96yddv3nj9r4q003essj2vrm3": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + } + ], + "cosmosvalcons17da97e4gq5p2zavzcd0zmsh7ez540j0ctxc8nz": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons1l5d2lg5hku0m4u8mh866zhjcy2dekpk55quww3": [ + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1p0u57pfl53kwefqrrr652pd3sm2hhv9gznzvw7": [], + "cosmosvalcons193pvwgxpxnd6tgz0gtyl00dq8r3ygeflzs60pf": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1n20sc20x53kyms9vhrxlr8r79hptq3p2efwm48": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7tn52wp": [ + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1gfta9y4c4j5dd08mju2zf23cmdn7ylauvct35q": [ + { + "index": "15", + "missed": true + } + ], + "cosmosvalcons1fc96780mrsxn5kgplhtna40qepjgrm9wprcd0c": [], + "cosmosvalcons10qj9cj3dxecyu826gaw72ylwum96jkkh5xjn2j": [ + { + "index": "3", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "18", + "missed": true + } + ], + "cosmosvalcons1478sx3zdfylsts5sus5rlz4dgvyvacqpdlsm6m": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1zukq6nknswp76ckcj5s9rnvmye974n7c3mmhnd": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "3", + "missed": true + } + ], + "cosmosvalcons1yr5ztk7t7w329lllmylgz6wnfk664qu0xdmvm3": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1ylf26t6vhvugawg87328ng2ug4d8f25s4pxn42": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + } + ], + "cosmosvalcons18d56e7qz5869wegeca967hrxrmfduxdenqzjcz": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1ellx23lw5uxmdnyjpnn03expxvu89kd6htl8jx": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + } + ], + "cosmosvalcons1eccz4hnumvgsqzpfgmvhc5vwh4ugptm56yyx9f": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1x4yzfjt777agvsfz6cskjst7v7k42xc69qcru2": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + } + ], + "cosmosvalcons1x72py7gr6pd72ch7u380ay04t9mhf3fkgur5k8": [], + "cosmosvalcons1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7uajcn9": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1k7dl7gc3umxp45u8m8zc6evvus2gvjvcagsclr": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnf22uec": [], + "cosmosvalcons10gu52rf3d0z0py8d0x37r058qh9fgdgg9nahwl": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons15jcgjq7sc62rj4s0dlm4sapdcgw06jfuysh66q": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + } + ], + "cosmosvalcons1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3x59pmh": [ + { + "index": "16", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1pv9f0ze6vmq3qvy29fywmj2eh2cpneymxky07j": [], + "cosmosvalcons1znvpcj20duymyac6cl4r8kcf827aqu60amp48q": [], + "cosmosvalcons1yalqz5m4qcjtss37pdnvalz5kaws3yjy3he4fv": [ + { + "index": "1", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqzhzl6w": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1eumpungfa2vmx20e27wnu6t0rtmrlmv3unjt4s": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + } + ], + "cosmosvalcons1ll2f2v79ssg5teg5trglr0wecm877aprwzvqh9": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "31", + "missed": true + } + ], + "cosmosvalcons1adwsqn58aype530jae9qrwknsxyf3wmwuynr3s": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons10xwf26gupjlr4xt69pl779346w7yytxha4ymw0": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons10t3ld5fvsvy7kye7p409he8dk5q23tep9u5whq": [ + { + "index": "2", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + } + ], + "cosmosvalcons13y2zjpgaj07umx7a3dsg9ffhpkk22g73yzdk5r": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + } + ], + "cosmosvalcons1chjcdfygnalpfjrjc8ku8vknx782xf7em93zkx": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1z7ruhrtfg8v2xv8egfyxldt2xaygspykp95zz7": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + } + ], + "cosmosvalcons18gmd4r8ydls55yvgda4d8pfandk0xem53e75t4": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1289vtnyn8vg9rwv7jdcy2ht3h68627ht5jdl32": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "38", + "missed": true + } + ], + "cosmosvalcons1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpus7r8l": [ + { + "index": "39", + "missed": true + } + ], + "cosmosvalcons13tfk4n07c9dz5swkw7vafmlrd9e0d28faef7g0": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons14e68cy8rvnmva3fzvhmq67m94zffpvnt09v3de": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1ql2jawqmha8d2xdgda7njakszmhvt75rv4zlx8": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + } + ], + "cosmosvalcons1frjkqcr3r5fpwds4kypq5e9n865qss6ujnfqrc": [ + { + "index": "5", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "21", + "missed": true + } + ], + "cosmosvalcons1tz087eh88lqkesr77yl6ys9dw95qysfq6wwa20": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + } + ], + "cosmosvalcons1dkwuxswrh5mx3mmmsny2qhwm4xtu33tynte2nf": [ + { + "index": "2", + "missed": true + }, + { + "index": "41", + "missed": true + } + ], + "cosmosvalcons1tnh79aat8d4m82pfm7gqa0z5kzzh7zty9nz93n": [ + { + "index": "1", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "43", + "missed": true + } + ], + "cosmosvalcons155znzxm9g8j53k8vyp2d5qmrkzdum4d0a2nk2a": [ + { + "index": "23", + "missed": true + } + ], + "cosmosvalcons17nckqnw09secacg9y6r7pay02nhemww69ksle3": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + } + ], + "cosmosvalcons1mcvztyynwvn7lelqx89xuzzuguhx5xm7usl4un": [ + { + "index": "22", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "42", + "missed": true + } + ], + "cosmosvalcons17z20092e9s2ttlzkpzv209dsxsxs946jk0ph4e": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + } + ], + "cosmosvalcons1ryy20he94rlaryj04mkhcj6n4dhuhcytym4g7r": [ + { + "index": "0", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + } + ], + "cosmosvalcons1twyey6dyu57e7p8lahwgr9ql2pyn6774gnvtex": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons1vsuhkup8jznqt89zgv9nw8c3u3a7l3u80lyhm6": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + } + ], + "cosmosvalcons1d5vv20893q06tx29mlqmefnyf0w3hn0v7efvph": [], + "cosmosvalcons1xau5jp7uyewxcwg9tzwsxm895v3mf0fn04azmn": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7l4x75dl": [ + { + "index": "8", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "37", + "missed": true + } + ], + "cosmosvalcons17k35dydvkrdxup6z8633k3zcc4ecmgnz23jtdd": [], + "cosmosvalcons1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7f3wcwa": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons15tf0n2rqlh49324hrn0vzmj33fr7yk9tjs0up2": [ + { + "index": "26", + "missed": true + }, + { + "index": "44", + "missed": true + } + ], + "cosmosvalcons1rpxgsrsrx8jntwa6q9m0a4xxypnphs9znygvp6": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + } + ], + "cosmosvalcons1g58m70guf3p7y6hhf5trqmhzpzn99rvr8mla5z": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1fhnwxus6yyk6lman2qf9fzuqtekl7gcwhqc8q8": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1terlqq72gje366346skcmzfgg4lqypf579w83k": [ + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1znvq8jqpwxt5hk2lg5654l7eg7kap3rpe4uu6c": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1hyzzthl6vy5vjucaalz9w6fkyqne5p55fe4j85": [ + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons17qavkakyqgh62k39frjf5v9pj0c78m2daks0a9": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1kjupa2w6rlhzj9fjxz35m02g2wpz790fuauq0q": [ + { + "index": "0", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + } + ], + "cosmosvalcons1hwea4x7eagt83nvaz93q3q5gpje64nczejpn33": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + } + ], + "cosmosvalcons1eausepxh2ujd0lpjup9vahjekpz9as2fgn2vdk": [], + "cosmosvalcons178gvnxtnq2n4m23492m7agshjv3zgzy3zzg47d": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons14dp6lpg8dqs4e0aq34vhcwpxt37nltefr2w0fk": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + } + ], + "cosmosvalcons16v3h2mggt8tnkxp0vq5tq25fhr3knvf4rfjxlx": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "41", + "missed": true + } + ], + "cosmosvalcons1up7x3srs54xhq897rlda86hdsf4sy7ncez37jn": [ + { + "index": "5", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "32", + "missed": true + } + ], + "cosmosvalcons12k6u60mgp8wldpz2xs2u3p3skmghtrjy5etjdq": [], + "cosmosvalcons1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2k77jcj": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1vfcm9c4psqrkv9zecgjw7zxvw2jnpe737eaneg": [ + { + "index": "16", + "missed": true + }, + { + "index": "26", + "missed": true + } + ], + "cosmosvalcons13jxw6xalnpvapujvmm6mc6qn3dk4sn6ktfuppf": [ + { + "index": "3", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4g2ureq": [], + "cosmosvalcons14kdxam68sthcd72526kc5ea42hfq5c2ga5v908": [ + { + "index": "14", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "43", + "missed": true + } + ], + "cosmosvalcons1hpwfm40p8dwmwtmhdnmazywy79uywk8xxx9cg9": [ + { + "index": "27", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyuhga22w": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons187wgdejp6c2h502gtkzxcpn6qgrw9q547kejc7": [ + { + "index": "1", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1f2sunjkaqyu2wr9jupyjkl7qhlnesag7egqylw": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + } + ], + "cosmosvalcons1nz5hp6p6wn4fvnaxe9x6fq35daamxvhh6ze2pt": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons14upsvttjem96xlz8rfsw4zqt234jnqy8vxuxkp": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1hxdqddf3u8vjm080ytpe959uktn4axdapkmfhd": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + } + ], + "cosmosvalcons1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wwhy7vf": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1uuk9ewj0532rzlhlg86tserdxvtnm3kqm3dtwu": [ + { + "index": "19", + "missed": true + }, + { + "index": "38", + "missed": true + } + ], + "cosmosvalcons1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwc2lxm7": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + } + ], + "cosmosvalcons183sdz4kk0lueuxfu7zzgp8tzcjndf3pflk3e02": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons12rjah2jl9jpqwddh20vph9yu448d76252t8yzm": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1n3lnhxzzm7ntheu78h6v4zag7zmrlp486457fr": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1fhpyqq3eex5zcctlgsxj3s3dgz64am96pv0u6u": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons158hwrawjlg586d47zl4xk9kg3em02vyppstqwv": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "40", + "missed": true + } + ], + "cosmosvalcons1c2tutqjg5cqcvt6qen2x6enval6t5pyddwna5e": [ + { + "index": "16", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "43", + "missed": true + } + ], + "cosmosvalcons1mdes9dapqu6vr094qc6wyhd9jt7qfwvjm5cyw3": [ + { + "index": "23", + "missed": true + } + ], + "cosmosvalcons1awyus34e6laq3zxqsrv283w6fgn8w62z8f2w7l": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1z6f7gdevn6dfvpls7tlqmqmzr54le7a4avumjr": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + } + ], + "cosmosvalcons1s6sl7pyvn33lptf7edmux0gex06ffzjz8l2hlr": [ + { + "index": "10", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1ng7vpl5wh98pshfef327gfnzyrwh6z4e8869pm": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1hsq728kpcxgr77ncj8asxa0383pyx7vqpf87tj": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1a0jdqzvk078d6486vuxdr5d0yp6rgluem5sadp": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1dzuk49ssprfz3ala9tea3x74x8n2nlyz4zj52j": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons13w024ysyklmnrq9c6udp98qx93jqynhggkk3rp": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + } + ], + "cosmosvalcons1evqmj6ahqf76keas4ymhvf4r992kg7wrvygqrw": [ + { + "index": "1", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "36", + "missed": true + } + ], + "cosmosvalcons1mmjkdjsqluxlggcl082j977kv8fwp4u0p4fshs": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + } + ], + "cosmosvalcons1elu2xlg8qw8st5nppxvgszeyzhm4ht8zhsl8cf": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkaw34gh": [], + "cosmosvalcons1q54ra6ur0wgyamdtgkn7fnmawf00tcj6cvttsq": [], + "cosmosvalcons128xc6r596pllf46ev2cpaetcujfgmhay7tzcwd": [], + "cosmosvalcons1ng5m6spxngyne4qzce35fdg0whl0yqgv5c0vte": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + } + ], + "cosmosvalcons1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8pce0y2": [], + "cosmosvalcons15zqzxj663h8g8naxyz324j2rpd3rnw4ravpspc": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta96zmmy": [], + "cosmosvalcons1hc5k2vf82jswmnlfrrav6u2kf6rn39mppx25wn": [], + "cosmosvalcons1rq7tvegh0yqan5fpp90rya7q9lks5nyxw0kdej": [ + { + "index": "33", + "missed": true + }, + { + "index": "43", + "missed": true + } + ], + "cosmosvalcons1864wj4twqatq54rrxl5jmfey55tmh0hveu2vyu": [ + { + "index": "35", + "missed": true + }, + { + "index": "40", + "missed": true + } + ], + "cosmosvalcons1gayzja3zz6unep8ftnpunt2wefazs3jhd5caas": [ + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "13", + "missed": true + } + ], + "cosmosvalcons1wr9032gj6t9s9schc5vnwe9kkee7qkgpmawqtu": [], + "cosmosvalcons13spl9rpkd0wd9c32mpsd9h6phwwnxu3uzvy8tm": [], + "cosmosvalcons1zu50umwgah6jhx07sw04ry0pv7fnvkpj25q9lh": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons18nag9zrh49uaxypx83fmlz85umq0t9j79nzvqa": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons1v08dcmtc5f444sxqfvqv8mxdclmc2759mh75r7": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + } + ], + "cosmosvalcons1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8e7x7qv": [ + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + } + ], + "cosmosvalcons1h7nkedpkxm0t752j0q88rhgwjn94p4y29hqdn2": [], + "cosmosvalcons16ll03qy5htuech4u0z432zertwhyxynl9khkh2": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + } + ], + "cosmosvalcons1tftatt0lp0v59qqf449pdqar8w3yj7n7h6eekg": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1sfewn0rgaw0fqw8lks6ygek6ulmcy3nm4mt3g5": [], + "cosmosvalcons1j7352v6z3xcf9y5qusgdxectvn8dv962h27ny2": [ + { + "index": "17", + "missed": true + }, + { + "index": "28", + "missed": true + } + ], + "cosmosvalcons1kfnt5d5fcma9kh4c5jk85yu75jer72kwucvp4z": [], + "cosmosvalcons1nrugh7am9s584k6qlf5nxlpetarxs2csecvu6u": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1hu260773mytzz030tuq0kffmlyxzs7vg5wftk9": [ + { + "index": "4", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "36", + "missed": true + } + ], + "cosmosvalcons17e6r58yvwdtyrzxudfrp8gp3zk2mdxd58u87ag": [ + { + "index": "0", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "33", + "missed": true + } + ], + "cosmosvalcons1qqxeqqvjkh2ls3a0taukd8rydrqqad6975plc2": [ + { + "index": "20", + "missed": true + }, + { + "index": "42", + "missed": true + } + ], + "cosmosvalcons1re5reme6kyayzfanalqm89u2r9an6wu97g0svk": [ + { + "index": "21", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "37", + "missed": true + } + ], + "cosmosvalcons10d3vd6yx9k9ns6v82r4krm3d4ragw04c4hun22": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons10ke8m795c8svtt2h24n6dad2xp9a8mev6pk3dq": [], + "cosmosvalcons1zzey9t59j5x7j5z9f3urms7faq0gq9dw27hxcc": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons19vugh7w9vrp6x3nqzjph59zg0d28c0fkn7432d": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1t7wt4qjfsa4kncvvya5m99mq0m53n9e8q9m6p5": [], + "cosmosvalcons1jsd99e3zfrxrr3nh057u0tvmu0847zkrmzwr87": [ + { + "index": "1", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "41", + "missed": true + } + ], + "cosmosvalcons1cdvntn6mwvvv4qxnty6zp2jwvemg20yuqmdsse": [ + { + "index": "1", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "12", + "missed": true + } + ], + "cosmosvalcons1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7t0qj3k": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + } + ], + "cosmosvalcons1ptu2vxfcsyl2gpeg73ehzte7t3va459lj69slr": [ + { + "index": "10", + "missed": true + }, + { + "index": "21", + "missed": true + } + ], + "cosmosvalcons1zlyfewtaxumsyj34fkml4t54yvhqcls4g7u5nm": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + } + ], + "cosmosvalcons1wy59rs74dnqqs0xz70sn2q5hyv9yreth64pa96": [], + "cosmosvalcons1nraptt0aagws66pcvnc92kjus460k3l09w274n": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + } + ], + "cosmosvalcons13yzpngckxvtky2k25j60qxlkekx0jfauyx47zp": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons154epq0mwqz393frj38lh265h9slwdynmwkyxq9": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons144n7h95z7sz0r3k9rm3r8umkc89wt5c70h9mrh": [], + "cosmosvalcons1fdfwthdupznzgrg2d8e96ryxqz8smppe6dxr7w": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + } + ], + "cosmosvalcons12nv5therrzkwjmvrmmnng6uqk2d8u6y70wempr": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + } + ], + "cosmosvalcons1twu2lvgp3erk6gups2a8nae3jdahaj2x2cmqs0": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1dle2tkls5kffwdqhan4rs0dgckjxunfsv0l9kn": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1urnp7yp6u27nut8kvsrapgmmvk8sh6u5l2nyes": [], + "cosmosvalcons1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3gvqu70": [], + "cosmosvalcons19fa3uz9n80megf46sfu7kzepfup4mjcctf7cjl": [ + { + "index": "9", + "missed": true + } + ], + "cosmosvalcons1wzmzdml4fsakuyukmaa6qqee3g6w6qtc3szmzj": [ + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3crkzxj": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + } + ], + "cosmosvalcons1n08duqdkxwmqmtjaha236esw6r72njd2xy0fmg": [ + { + "index": "3", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "45", + "missed": true + } + ], + "cosmosvalcons1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjf35ts7": [ + { + "index": "11", + "missed": true + }, + { + "index": "16", + "missed": true + } + ], + "cosmosvalcons179uxhryqvrkxa2wtnw2cnptdt80qc24kksm9ly": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons19ve7rrjrngdgf6pfaj87csf4rwykqdmhgnsd2w": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "43", + "missed": true + } + ], + "cosmosvalcons19e3lp8kdpnzmd778gxz9hqrnaxw8spa36e4k9u": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1x9mhtyr2tak88skl0nr4lq6k7jreus6n9s59vu": [], + "cosmosvalcons1dn2s4tgdyjcgpcq6pfw5shzry50veuh8vcq4zc": [ + { + "index": "4", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "19", + "missed": true + } + ], + "cosmosvalcons1qk5quugdx54zsrteg9hpee0ke3z35meuz4rde2": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons190kcpcyvl46xva8ya8vs5wmmg4nygvuty9afhq": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons152vx4n8032chkrgh97h05rs3mtdz3nuc2ke0hg": [], + "cosmosvalcons153rklv33fjex4w7r82n9wnwxrwfgae6nn0hfc9": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + } + ], + "cosmosvalcons1x76xgyet9jkq94uqcckrwm20l85gt2kxx6qect": [ + { + "index": "11", + "missed": true + }, + { + "index": "15", + "missed": true + } + ], + "cosmosvalcons18r683wlut54pd8sjzz45ujq8nu4wfr65s5sce8": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2esn3du": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons1sjhhg2yl2cqszte7pjyrp6lx5tg383lrs4rf0f": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1qpj52qsl708aqhazaqehhjw7cdj4her9zsvuxy": [ + { + "index": "45", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons1f3j0m80ey8ujgfg783838jqnuw63h3v0yvqnpu": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + } + ], + "cosmosvalcons1jqkfaju29z0270cmm4zhygtzwjcuqjzx9d44za": [ + { + "index": "2", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1r7kh63jvjhwqraux9wtm3jat8ggm437w5lp3x2": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "27", + "missed": true + } + ], + "cosmosvalcons1dge9en6j6xl3njpkk8gvw9n326pgna44v3fc2z": [ + { + "index": "0", + "missed": true + }, + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons1wnn8xrn46u6ryq4kqf7tcf650fe2gl57uk0p3z": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons178pm30fcgrt5654czwr8nlex050m6y6050c02z": [ + { + "index": "4", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + } + ], + "cosmosvalcons1fjct2f29ymrw9h7aqffafx863c4tkxdh5c95y4": [ + { + "index": "1", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "44", + "missed": true + } + ], + "cosmosvalcons12r0m6hwrnn0jy02tnhmk328d7p68x2rnu9vxjx": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1n9lefg5g0mz4glppdt994nsxzg6pxscq20ppwj": [ + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + } + ], + "cosmosvalcons15772l3g3u9kk2qk5cmsl8tr6lshgd443cvttwn": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1qzj5kxv664trtfn4h0aznrsljtt2q95quzyrql": [ + { + "index": "2", + "missed": true + }, + { + "index": "24", + "missed": true + } + ], + "cosmosvalcons1r2ncmjrd4efnk9cjrftq7sw7347xqyu3va4mm8": [], + "cosmosvalcons18wfnjhyqjzjpa5pgd3r5n987uet7qczjdf0rvj": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1g7sk4y3cf2473ff36mlcx9ydvted9evryympt2": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + } + ], + "cosmosvalcons1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlvmv8ya": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1alxfwr8v98tw6tm4jhgdu2hu5gy0umv88caft8": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons1l4dqy53d57ul42xd8wzs5zxk4ywkc7axqkmnn5": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1557a6swa3yv3ew9yk8hcfpyqu3ce7te0dualvr": [ + { + "index": "6", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "41", + "missed": true + } + ], + "cosmosvalcons1hll5qzyzy4vrtdad5rqnf2jvf7srdnsymt6r3e": [], + "cosmosvalcons1c07ez82s6kcfyg9szzg0pgghdpl7a2k0uc46p5": [], + "cosmosvalcons1z97a2xx0rzwtfftg3k9yt693dwxx9j80749vks": [ + { + "index": "1", + "missed": true + }, + { + "index": "7", + "missed": true + } + ], + "cosmosvalcons1yt9s823gnqayrjasrra5j43pj9c48ae9gp0f5l": [ + { + "index": "13", + "missed": true + }, + { + "index": "33", + "missed": true + } + ], + "cosmosvalcons13nemj0k45u4pflkfeyey88n8u8sv4wgzklwr5r": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx5uzsa7": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons15qje22esqaz79y27940s3ng7r7afx3vv8c7j72": [], + "cosmosvalcons1yezuhyh4htsy74jkhfey9p7urgwhg00jqp7rty": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1y7m2ga0zpxr6q000a4a924fdaeycw5ed43yckr": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5ymewrp": [], + "cosmosvalcons1n5t5rr83k3emp5e446qjprj0svsh06rw33397a": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1s30d8tgwhwavwtvanggkj92quj8ucecyqlzjzv": [ + { + "index": "17", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + } + ], + "cosmosvalcons1mzsvp23mjrjkspddkz6nta0x7kte6a23vv0nmd": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + } + ], + "cosmosvalcons1rkl7umzewantxm5e8mf2l2tcxc3t7hj8djzmrw": [ + { + "index": "3", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1gpk39c5dc4xnevhz4c7m2sjxequw30s32598cq": [ + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1taucnwfqfkpq6c6y345j6h8jt5fffgla9rv3qf": [ + { + "index": "24", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4f3ekeh": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons12dh9h444s238r7hjrrd2kg6wrw4cwfk3999xl6": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1n9dqelmmf5kfysk24m6chqfdcgz6r75u0ux4w9": [ + { + "index": "1", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1k0z97vlulcmdrrajhms2x9k8srvtmxwu9l0mha": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons16tr72kn90g5zl7qhyhuqkjflejz00uzl8caasq": [ + { + "index": "21", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "44", + "missed": true + } + ], + "cosmosvalcons1qs5htj5ayfgg27t0xnng837lzllla5y235nkaw": [ + { + "index": "32", + "missed": true + }, + { + "index": "41", + "missed": true + } + ], + "cosmosvalcons1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfccuman": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons19qqvhp8aacjvxjhtgwncctmtrmjelqs62ar4s5": [ + { + "index": "31", + "missed": true + } + ], + "cosmosvalcons1g95xvy8qgzcvcl05fse0mpxzdfv3w88ts7pdc3": [ + { + "index": "28", + "missed": true + }, + { + "index": "30", + "missed": true + } + ], + "cosmosvalcons1jv7lxeryc30c0w4p7p92nxywgcnswuhshvzk3n": [ + { + "index": "3", + "missed": true + } + ], + "cosmosvalcons1744t93tc6ulm87ccsc47mkl30qz65n8pmtgywr": [ + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + } + ], + "cosmosvalcons1yva09usdkzdsqekaasgcqvm50v9vv5puyw2v3r": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + } + ], + "cosmosvalcons1xnh4mumajk76tlnsp8d3d95r7hjnt4drueld2m": [], + "cosmosvalcons1f2pvewnws73u0z5wsfmv5uqudwxl6jupcua6t0": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1sp9hxsl3s8pyj3cs84acgwrkxl85yk88wm5cf7": [ + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwghsz8u0": [ + { + "index": "4", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1t6k46y53tkcjvdttujt542pcfrwanw0flqxj2g": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1l2mzrv0nvs75mjj5nzz966jxklfn9wt6l55sw2": [ + { + "index": "11", + "missed": true + }, + { + "index": "41", + "missed": true + } + ], + "cosmosvalcons1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqpw7fvxl": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons1s728ea54m9u76dkd4x9ea3l5cvjjjkk5dgk8gv": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons15cnzrhl4pe7ekkp0djmyupahdsjjmmkv0q80ee": [ + { + "index": "18", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "41", + "missed": true + } + ], + "cosmosvalcons1kz20p7j939s8cqadmqqws80c6z93qdtyeqpz07": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons18p7qvgvjcpl85mjwtvepe9reevevnm9fv605n2": [ + { + "index": "5", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "45", + "missed": true + } + ], + "cosmosvalcons18fkw6s4hnj2llxljrkleetgns2y0h0vjeq3jem": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1f6qxvzgn7lfsvg2f86m30pshf8wuygk7w7wqdy": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1ty5s8h0gwtc285mnxwq43cyt2s58g25gfu8xm6": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1qsxjdj8z2urjdxpp7uu37pp2pf3chjjcttwfff": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn5472pf8v": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1nas3l2avd9hymfeqznjmrw7sde8ual5k5f5hvz": [ + { + "index": "2", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons15ughagcacjqyaa0f7d28xtev88v5vh693t8f8y": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + } + ], + "cosmosvalcons1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7naq267qg": [], + "cosmosvalcons17uusex4s7mds872wzvkpaty29g02n8ethl39rz": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1y30ftjd79f3p68mssyd9zug24q2avh0zkms02f": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1w2ly5qah2m47qguaukzr6xx34hszqh8um4gr3k": [], + "cosmosvalcons10ndcqfr2zwrspryphtuhq883kc49z38fwtx025": [], + "cosmosvalcons13fvz5er8rdttgtuwvcuaku00j2nw2v6kglpshq": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + } + ], + "cosmosvalcons188yd2umzwfwen7es68wrlh6auu3p8jhz78wpeq": [ + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + } + ], + "cosmosvalcons1nxr7alffy7zt9gg4285a67ts977pcgaarr7lgd": [], + "cosmosvalcons16sn6wjtd0kw4yvc7780cpayhz0x45d27cdeswx": [ + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons1zjzkk7l2jalrspy6500my8v0yy6ycz7ewnkuzu": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons1333066cp52k7fgmug2dwylafnymdxcg6zjcsez": [ + { + "index": "4", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1jp0tqhr79uwqt2rh66vcd378rrhslg49uwt39p": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + } + ], + "cosmosvalcons1evys94earewfdh658d0u67j28lq2ltezjkm72y": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + } + ], + "cosmosvalcons1luynvvt3qre3hzald2tdjtah6vw00hdcp4l3d3": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons1xec6kclrpkc4ws7lwf5j0u8207nyg6dzr6xsy0": [], + "cosmosvalcons1fv35lda8ltd6juk384yqceqalcxyfj4kplptte": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons15dt0e900x5cv9w870mevztqwy88hhu2st8xhx4": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1edwe9quhqnxa4yvqu2ks656guv6rjzhtgr7r6g": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + } + ], + "cosmosvalcons1wkt8xe20zdph4ak9vqx2supe3v2gq3wyr7dmne": [], + "cosmosvalcons1s28wuj4yrqsmjm2cckx6mu037e92up2m2w36xt": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1ktnuvrm3q8h30y3k70yzvmvwme77e9yycn5aw6": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1a4nlyf59n25qmh4myas5mdunvu9r4wlsffl40h": [ + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + } + ], + "cosmosvalcons1zf34ku927tasyr9fswhasvqt0x49janzmpm3cd": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1nmexjngk0j8jhgmywrkd7r98dgd9hzxpvcqtsq": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + } + ], + "cosmosvalcons17uqc5hqs6x7ccr7pcrafp8tfwsezt07ejfk5yc": [ + { + "index": "1", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "44", + "missed": true + } + ], + "cosmosvalcons15a8hadw3wttrnr3qx37ewmzre4w7cjmtk3uf03": [ + { + "index": "5", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "48", + "missed": true + } + ], + "cosmosvalcons19yplr2r5lu70jlymwrumzuc8tqeeu7fg5x9a4u": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzml74vet": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr338lh7": [], + "cosmosvalcons13cydnwjmscxtqtjywk9atr9uwlm6703mlvr3n3": [ + { + "index": "3", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + } + ], + "cosmosvalcons1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc9jsr7n": [ + { + "index": "4", + "missed": true + }, + { + "index": "38", + "missed": true + } + ], + "cosmosvalcons1ekx8n2y3x9qq34c2uy8fdh400hp8msqufqgdhe": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons17gpy6jzg7xdsr2xc7kweljagx4uaysxd8ddu46": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + } + ], + "cosmosvalcons1q03kay3adsttv6watm3agqktnpuuxs65vz6tu7": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + } + ], + "cosmosvalcons1pjwsvz9745jftv0p0c99t36m6kf9e8rxc2k8gj": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1fuge5wmj546lq6ljv9zfzjjgknrfmngv7pt5pq": [ + { + "index": "2", + "missed": true + }, + { + "index": "14", + "missed": true + } + ], + "cosmosvalcons1n5n6d47c4ntac509rtq3s620vmcqcf97ygkv7e": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons1e8fdmnscnm6axht542696jupnqlkm40e0jefjw": [ + { + "index": "10", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "31", + "missed": true + } + ], + "cosmosvalcons1lamxh5pswk923tm9mtmvd4t6pqru5cdtjnrxuu": [ + { + "index": "2", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "45", + "missed": true + } + ], + "cosmosvalcons1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalaatgcxv": [ + { + "index": "0", + "missed": true + } + ], + "cosmosvalcons13fyamuv3fexmuuamtgqtwkz48ynl3hd5jgmlh8": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "11", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons14j4mehgc448s2m7cr0uqm3pmvjxav94w28qxw8": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "3", + "missed": true + }, + { + "index": "4", + "missed": true + }, + { + "index": "5", + "missed": true + }, + { + "index": "6", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "9", + "missed": true + }, + { + "index": "10", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "13", + "missed": true + }, + { + "index": "14", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "17", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "19", + "missed": true + }, + { + "index": "20", + "missed": true + }, + { + "index": "21", + "missed": true + }, + { + "index": "22", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "24", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "27", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "29", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "36", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "38", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "41", + "missed": true + }, + { + "index": "42", + "missed": true + }, + { + "index": "43", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + }, + { + "index": "46", + "missed": true + }, + { + "index": "47", + "missed": true + }, + { + "index": "48", + "missed": true + }, + { + "index": "49", + "missed": true + } + ], + "cosmosvalcons147pq4rzswl76kdeyx8sc7pagf4nhjpnqmsc2hr": [ + { + "index": "0", + "missed": true + }, + { + "index": "1", + "missed": true + }, + { + "index": "2", + "missed": true + }, + { + "index": "7", + "missed": true + }, + { + "index": "8", + "missed": true + }, + { + "index": "12", + "missed": true + }, + { + "index": "15", + "missed": true + }, + { + "index": "16", + "missed": true + }, + { + "index": "18", + "missed": true + }, + { + "index": "23", + "missed": true + }, + { + "index": "25", + "missed": true + }, + { + "index": "26", + "missed": true + }, + { + "index": "28", + "missed": true + }, + { + "index": "30", + "missed": true + }, + { + "index": "31", + "missed": true + }, + { + "index": "32", + "missed": true + }, + { + "index": "33", + "missed": true + }, + { + "index": "34", + "missed": true + }, + { + "index": "35", + "missed": true + }, + { + "index": "37", + "missed": true + }, + { + "index": "39", + "missed": true + }, + { + "index": "40", + "missed": true + }, + { + "index": "44", + "missed": true + }, + { + "index": "45", + "missed": true + } + ] + } + }, + "distribution": { + "params": { + "community_tax": "0.170000000000000000", + "base_proposer_reward": "0.120000000000000000", + "bonus_proposer_reward": "0.260000000000000000", + "withdraw_addr_enabled": true + }, + "fee_pool": { + "community_pool": [ + { + "denom": "stake", + "amount": "3392935814268.044714008424704425" + } + ] + }, + "delegator_withdraw_infos": [ + { + "delegator_address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", + "withdraw_address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr" + }, + { + "delegator_address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", + "withdraw_address": "cosmos102sgufwszag3yuhtzcftpyvc8jqtqske4xug7d" + }, + { + "delegator_address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", + "withdraw_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7" + }, + { + "delegator_address": "cosmos1q3mptmfxfd03myzy847p0mrssqw0sh006086eg", + "withdraw_address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn" + }, + { + "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", + "withdraw_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh" + }, + { + "delegator_address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", + "withdraw_address": "cosmos1wve3m263mdhqqpg0yjd8vmveflugrk5dk2cr0z" + }, + { + "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", + "withdraw_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t" + }, + { + "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", + "withdraw_address": "cosmos136jetl40d2fmx3w0a0t2jj7zyp72g850c9j4ez" + }, + { + "delegator_address": "cosmos1pmjfpv056kk3jk3qfljph9fthrvqtufxe3nwml", + "withdraw_address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj" + }, + { + "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", + "withdraw_address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj" + }, + { + "delegator_address": "cosmos1zyu5csqfxaxacgwegnhrysl0val4t48kfhj9ws", + "withdraw_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9" + }, + { + "delegator_address": "cosmos1z9ns26y62x3qd3d8vs9eyxk8ndssa6gxtv2c06", + "withdraw_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7" + }, + { + "delegator_address": "cosmos1zxpp6x3x0p0gcuuazft5ycgrxsa5wwsgl854uk", + "withdraw_address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr" + }, + { + "delegator_address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", + "withdraw_address": "cosmos1jn4dp0s3ewkwarqmra50czqlm6g7cf9plthphn" + }, + { + "delegator_address": "cosmos1zs6hn5hf6qxjwmvntrzwhjkgvu963d0g8hz2z8", + "withdraw_address": "cosmos16adevt9lhqf3q4dwnmhty7ndr8478thakltsdj" + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "withdraw_address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8" + }, + { + "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "withdraw_address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd" + }, + { + "delegator_address": "cosmos1rpmw7y7cw2cu3kwsryy8z8uskn4eymh89hmq5g", + "withdraw_address": "cosmos1s7e8ukt3awex0xh6qw27pramwg3hkgeqtm0nfs" + }, + { + "delegator_address": "cosmos1rrahhju34rdpmlnaww9r5egq0su2u6f44eve27", + "withdraw_address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy" + }, + { + "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", + "withdraw_address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7" + }, + { + "delegator_address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", + "withdraw_address": "cosmos1guuf6ntr5ujawszq99gkq2gqeevz37adzp2fmy" + }, + { + "delegator_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", + "withdraw_address": "cosmos1t2uupuuf6p4xr0szwsz47gn682kw64m9wmnewf" + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "withdraw_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee" + }, + { + "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", + "withdraw_address": "cosmos1t2uupuuf6p4xr0szwsz47gn682kw64m9wmnewf" + }, + { + "delegator_address": "cosmos1ywe4qsw399leu3wza5jpny3mmrs69a3gj3hlt8", + "withdraw_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh" + }, + { + "delegator_address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", + "withdraw_address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq" + }, + { + "delegator_address": "cosmos1y78hvz86672la4agrx7n6lcmgjfgegpkldazmd", + "withdraw_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70" + }, + { + "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", + "withdraw_address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2" + }, + { + "delegator_address": "cosmos198k0ah8pnjzthydgvnq30s24s8jd3wad6puc3q", + "withdraw_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl" + }, + { + "delegator_address": "cosmos19szahkq3g937j62shd224cdtla3dv8rcwvekj9", + "withdraw_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4" + }, + { + "delegator_address": "cosmos1xfqsntajat3kv06ptad8zsqacmjrsjc2sa5ajt", + "withdraw_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7" + }, + { + "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", + "withdraw_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp" + }, + { + "delegator_address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", + "withdraw_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz" + }, + { + "delegator_address": "cosmos1xenmhldpnwfl0x8ze8qvu2qc4v58zr7qkz73sz", + "withdraw_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv" + }, + { + "delegator_address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", + "withdraw_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus" + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "withdraw_address": "cosmos12362v43p57f8dgc2dx396rpanj24j67pkcvy2h" + }, + { + "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", + "withdraw_address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp" + }, + { + "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", + "withdraw_address": "cosmos13xm9km2se2am890j398ttvyjhuh8zndwr2p68d" + }, + { + "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", + "withdraw_address": "cosmos1p7sc667drjvsjlha0nwz5zxxpt38m9dn50u925" + }, + { + "delegator_address": "cosmos18037phaq40fkqdr4pxk2jajnsq8prfyyl4tzvz", + "withdraw_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq" + }, + { + "delegator_address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", + "withdraw_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav" + }, + { + "delegator_address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", + "withdraw_address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9" + }, + { + "delegator_address": "cosmos1g04020ghngvh7lj8hmhequs5a83ly7xxyh0q8w", + "withdraw_address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj" + }, + { + "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "withdraw_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7" + }, + { + "delegator_address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", + "withdraw_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts" + }, + { + "delegator_address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", + "withdraw_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u" + }, + { + "delegator_address": "cosmos1ft0e05t5rl8ycw6a0nfa6jswvckycan4lfmv0q", + "withdraw_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j" + }, + { + "delegator_address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", + "withdraw_address": "cosmos1rz3n04g9vg0ygh3h2x96wh5ceq44pcjmt3lgag" + }, + { + "delegator_address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", + "withdraw_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah" + }, + { + "delegator_address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", + "withdraw_address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv" + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "withdraw_address": "cosmos1639hgh9ke9sxqy7kpcdcu6srk983upzjlf8mwx" + }, + { + "delegator_address": "cosmos12qsn5ukkpvy0ymcsfh85yqp4paw5ew9mcg8z0y", + "withdraw_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh" + }, + { + "delegator_address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", + "withdraw_address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck" + }, + { + "delegator_address": "cosmos12gup0vvqv32z5nvdy4ycrhp77dnax5hfmcjav0", + "withdraw_address": "cosmos18rzc0m3vlq3cwee4tckg5grjjc02gu3dv9csx2" + }, + { + "delegator_address": "cosmos12vzdkp2z75x4paa9nf0dvg638l92n5s8e0jk0w", + "withdraw_address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe" + }, + { + "delegator_address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", + "withdraw_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf" + }, + { + "delegator_address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", + "withdraw_address": "cosmos1250k2ymtkl6hf0ty6syhkxft33v580fhmr25qc" + }, + { + "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "withdraw_address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw" + }, + { + "delegator_address": "cosmos1trs75ceuvsg83y9dje9k79em4v684dm5e9ya49", + "withdraw_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9" + }, + { + "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", + "withdraw_address": "cosmos1ndjmq7ee0g2lmxrx5q0npcmv64km6hysk0qnvn" + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "withdraw_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726" + }, + { + "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "withdraw_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn" + }, + { + "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", + "withdraw_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj" + }, + { + "delegator_address": "cosmos1t58fj97xgxsvsyn89lc75hd0naa6v6c0c340cv", + "withdraw_address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc" + }, + { + "delegator_address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", + "withdraw_address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm" + }, + { + "delegator_address": "cosmos1tl9mmfa626vgrsz3plpr42cmeqcn2zugg523y3", + "withdraw_address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n" + }, + { + "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", + "withdraw_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u" + }, + { + "delegator_address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", + "withdraw_address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx" + }, + { + "delegator_address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", + "withdraw_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7" + }, + { + "delegator_address": "cosmos1vwgt6t9vd9heg0jwq6gk0x7egw4cmp4w79yuyy", + "withdraw_address": "cosmos1gkdgukkcx52r2w82q2usyncf67s30g7hmqc74n" + }, + { + "delegator_address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", + "withdraw_address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890" + }, + { + "delegator_address": "cosmos1dqukz2u9cssszcudyrjxzf47aeydmfardn09hw", + "withdraw_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09" + }, + { + "delegator_address": "cosmos1d9cqjx7xh2j23utvyrns2kgtz4w8e694vqw6h6", + "withdraw_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj" + }, + { + "delegator_address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", + "withdraw_address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q" + }, + { + "delegator_address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", + "withdraw_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc" + }, + { + "delegator_address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", + "withdraw_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v" + }, + { + "delegator_address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", + "withdraw_address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933" + }, + { + "delegator_address": "cosmos1wgslx9j6ct5pczy3h5rjl98yyn78r3sel0ulth", + "withdraw_address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266" + }, + { + "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", + "withdraw_address": "cosmos1hfjku50s3uhp66wuqexafzc3kl73z3xzhj5nqv" + }, + { + "delegator_address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", + "withdraw_address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp" + }, + { + "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "withdraw_address": "cosmos1c4w30j37que0ncnss65vr40nuy7d5msegmhgs7" + }, + { + "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", + "withdraw_address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck" + }, + { + "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", + "withdraw_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7" + }, + { + "delegator_address": "cosmos10g2yfqkuyaxgyyj7hhyswh8cmhplvpanrc9tya", + "withdraw_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer" + }, + { + "delegator_address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", + "withdraw_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7" + }, + { + "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", + "withdraw_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh" + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "withdraw_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3" + }, + { + "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", + "withdraw_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72" + }, + { + "delegator_address": "cosmos1s0r2g8pzwre6tvywfw0h8vy8qg7spd2ytfkx70", + "withdraw_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf" + }, + { + "delegator_address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", + "withdraw_address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c" + }, + { + "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", + "withdraw_address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429" + }, + { + "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", + "withdraw_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer" + }, + { + "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "withdraw_address": "cosmos1jsfel7tdxv09dm4lsqesfuhlpnlhhpeh4fdl27" + }, + { + "delegator_address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", + "withdraw_address": "cosmos1n5qqy42c6su9dv0tjpt3867mu7sdfhz6juqdns" + }, + { + "delegator_address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", + "withdraw_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82" + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "withdraw_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc" + }, + { + "delegator_address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", + "withdraw_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn" + }, + { + "delegator_address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", + "withdraw_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz" + }, + { + "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "withdraw_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n" + }, + { + "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", + "withdraw_address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je" + }, + { + "delegator_address": "cosmos1jjav2y88kx0jempjzz5jcc9y4yatkyn7xnnvsv", + "withdraw_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz" + }, + { + "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", + "withdraw_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7" + }, + { + "delegator_address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", + "withdraw_address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq" + }, + { + "delegator_address": "cosmos1n5qqy42c6su9dv0tjpt3867mu7sdfhz6juqdns", + "withdraw_address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2" + }, + { + "delegator_address": "cosmos1n44p6u7280zd652tkgyxy4jg0pp0agcvw3d2wj", + "withdraw_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs" + }, + { + "delegator_address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", + "withdraw_address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj" + }, + { + "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", + "withdraw_address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26" + }, + { + "delegator_address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", + "withdraw_address": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq" + }, + { + "delegator_address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", + "withdraw_address": "cosmos19akemnyuu0rgf2y0rrd6wrxpkyd74q5gzkgm5q" + }, + { + "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", + "withdraw_address": "cosmos1jf2rfeaukfmdhrd6prqdmqhcdyr8ezak8sm2wd" + }, + { + "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", + "withdraw_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s" + }, + { + "delegator_address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", + "withdraw_address": "cosmos13acm7994qxzmemx0fekg6s3qtagck36erqgsz8" + }, + { + "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", + "withdraw_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg" + }, + { + "delegator_address": "cosmos14t66r5m6p8n9egwdxs45ljca5p4hra74vyz9j0", + "withdraw_address": "cosmos1g04020ghngvh7lj8hmhequs5a83ly7xxyh0q8w" + }, + { + "delegator_address": "cosmos147xrqy22fnlj0ksdjlhsh5u6hz55sjn5hzzvfh", + "withdraw_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0" + }, + { + "delegator_address": "cosmos1k22576dxnqasv25wy542wc3sgj30gm4gmdpec2", + "withdraw_address": "cosmos1xfps7nht3lsfdzp092ast50aev4nhkaxtf7gh7" + }, + { + "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", + "withdraw_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9" + }, + { + "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", + "withdraw_address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s" + }, + { + "delegator_address": "cosmos1k3rapsk6gmfzeugjq5w2c4msuj7t4qhat0xn4m", + "withdraw_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3" + }, + { + "delegator_address": "cosmos1kjkf4umv6g2pperq6g74mayntlrp4a7xypuvmr", + "withdraw_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4" + }, + { + "delegator_address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", + "withdraw_address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6" + }, + { + "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", + "withdraw_address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq" + }, + { + "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "withdraw_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs" + }, + { + "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", + "withdraw_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc" + }, + { + "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "withdraw_address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q" + }, + { + "delegator_address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", + "withdraw_address": "cosmos10572shcaewknpzsj6nnrruww0049hnmjymva38" + }, + { + "delegator_address": "cosmos1cv6mc68xznavrjel5fth3vry84wnwjy29mqn33", + "withdraw_address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7" + }, + { + "delegator_address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", + "withdraw_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82" + }, + { + "delegator_address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", + "withdraw_address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm" + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "withdraw_address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp" + }, + { + "delegator_address": "cosmos1e87dgtw7cd28mt4mm3s4uaaxpapanexw9grzmg", + "withdraw_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7" + }, + { + "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "withdraw_address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m" + }, + { + "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", + "withdraw_address": "cosmos1qp6s6vzf6l0mzeglw0a9d75h7ch4w99ahux3j2" + }, + { + "delegator_address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", + "withdraw_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3" + }, + { + "delegator_address": "cosmos1ecfsusjtvmp57t8n22j9vqx75g6yxdra5vk49e", + "withdraw_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m" + }, + { + "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", + "withdraw_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn" + }, + { + "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "withdraw_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4" + }, + { + "delegator_address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", + "withdraw_address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6" + }, + { + "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", + "withdraw_address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq" + }, + { + "delegator_address": "cosmos16p082pp2g44jm5sa7x8egm2089gw908s85szsm", + "withdraw_address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4" + }, + { + "delegator_address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", + "withdraw_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy" + }, + { + "delegator_address": "cosmos1639hgh9ke9sxqy7kpcdcu6srk983upzjlf8mwx", + "withdraw_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc" + }, + { + "delegator_address": "cosmos16kuse8g39wn4yzx64shrzned2lgnk0kepcuu9t", + "withdraw_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4" + }, + { + "delegator_address": "cosmos16adevt9lhqf3q4dwnmhty7ndr8478thakltsdj", + "withdraw_address": "cosmos1njvscahg6cus5fy9k5gkq72cxj4kcahlgy00dj" + }, + { + "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", + "withdraw_address": "cosmos1npd5ddcq5cm3q938pk02dqa4te3jnfy25c5gnn" + }, + { + "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", + "withdraw_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc" + }, + { + "delegator_address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", + "withdraw_address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020" + }, + { + "delegator_address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", + "withdraw_address": "cosmos1ad5vqqf6lruklvkyyqvx3926cpjyn0wuz6ga64" + }, + { + "delegator_address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", + "withdraw_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73" + }, + { + "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", + "withdraw_address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg" + }, + { + "delegator_address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", + "withdraw_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s" + }, + { + "delegator_address": "cosmos1munf3xa25sdu0sdxwyqxhz88c8l90llmjsslvj", + "withdraw_address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa" + }, + { + "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "withdraw_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h" + }, + { + "delegator_address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", + "withdraw_address": "cosmos1njvscahg6cus5fy9k5gkq72cxj4kcahlgy00dj" + }, + { + "delegator_address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", + "withdraw_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc" + }, + { + "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "withdraw_address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz" + }, + { + "delegator_address": "cosmos1uwx5cecec8v2af2mdrq3p6gv9gtv4gza5006gx", + "withdraw_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0" + }, + { + "delegator_address": "cosmos1umn8dwc5l034syha3xehk0kmjaajdfyedajtka", + "withdraw_address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a" + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "withdraw_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt" + }, + { + "delegator_address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", + "withdraw_address": "cosmos1rs7csfnnwetmd2dcjsv4p59w3t46g77lt0wq5l" + }, + { + "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", + "withdraw_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3" + }, + { + "delegator_address": "cosmos1a2sgqjezvkgzc6vhvmevtsjh8m8rp52zcfu7ga", + "withdraw_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma" + }, + { + "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", + "withdraw_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f" + }, + { + "delegator_address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", + "withdraw_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2" + }, + { + "delegator_address": "cosmos1ah3yy9ql35jh5ehykl626e848t2rrsyze8w8nz", + "withdraw_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj" + }, + { + "delegator_address": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq", + "withdraw_address": "cosmos1jhvqn320w9nqxcs3ar7250jqg7us9vuszw9cwq" + }, + { + "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", + "withdraw_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7" + }, + { + "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", + "withdraw_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl" + }, + { + "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", + "withdraw_address": "cosmos15hqa5fj9sx7mjvmquhknrcxkxkeudguk9zpqqy" + }, + { + "delegator_address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", + "withdraw_address": "cosmos1hwt3fl2gylwdechqwq8uhmhsl04gn6ksw6lxlt" + }, + { + "delegator_address": "cosmos17m4lyrws32kta4pj2atdcc2d7z2qrwkpqk0exs", + "withdraw_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg" + }, + { + "delegator_address": "cosmos1ly9aff4ptcun94q3cs26cfzqnq59j5rw2gl89u", + "withdraw_address": "cosmos1zyu5csqfxaxacgwegnhrysl0val4t48kfhj9ws" + }, + { + "delegator_address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", + "withdraw_address": "cosmos198k0ah8pnjzthydgvnq30s24s8jd3wad6puc3q" + }, + { + "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", + "withdraw_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs" + }, + { + "delegator_address": "cosmos1l6uepmju2xg0h8rzkx8wku0hsncargw5ruhhfz", + "withdraw_address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2" + }, + { + "delegator_address": "cosmos1lmkyqhjshfd4mqsgk5stvaxlsxkmdmfhfwh7p2", + "withdraw_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3" + }, + { + "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", + "withdraw_address": "cosmos1dwha0rccawlvhudcgdpzcf3eq2c0gqyzwctms8" + } + ], + "previous_proposer": "cosmosvalcons13cydnwjmscxtqtjywk9atr9uwlm6703mlvr3n3", + "outstanding_rewards": [ + { + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "17220875845.478727382116561306" + } + ] + }, + { + "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.000000002607269154" + } + ] + }, + { + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "20714266865.324899566545795216" + } + ] + }, + { + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "22578940941.547707422600891599" + } + ] + }, + { + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "243766366.173501302964350339" + } + ] + }, + { + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3216182769.537267574462827852" + } + ] + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "192181222063.158244001747782376" + } + ] + }, + { + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7484350031.736343087434817696" + } + ] + }, + { + "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "19396808346.440877742090220124" + } + ] + }, + { + "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "8093136712.520029242917363321" + } + ] + }, + { + "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30006563238.944831778831776839" + } + ] + }, + { + "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.000000027417920605" + } + ] + }, + { + "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2070889900.213970128354397621" + } + ] + }, + { + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3803355882.998610894777957064" + } + ] + }, + { + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30722375684.372368116943940104" + } + ] + }, + { + "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "19813833628.175297782230725146" + } + ] + }, + { + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "218513221.305796703900759708" + } + ] + }, + { + "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2967410354.956862776811539245" + } + ] + }, + { + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5517811984.452160001612139171" + } + ] + }, + { + "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4914087260.336803898118162537" + } + ] + }, + { + "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4137170753.155136953459875226" + } + ] + }, + { + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "17785493982.070854785839706278" + } + ] + }, + { + "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "27845774681.205818014287692026" + } + ] + }, + { + "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "21744315327.805663813285476473" + } + ] + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4862500260.686275927048752655" + } + ] + }, + { + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "27388474340.135639921276003896" + } + ] + }, + { + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "9413561734.369977306377145001" + } + ] + }, + { + "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.911746517175444959" + } + ] + }, + { + "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "537317001.751974465713750532" + } + ] + }, + { + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13185327586.352255587186466738" + } + ] + }, + { + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2460537813.473636151156614982" + } + ] + }, + { + "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6307229865.753421284851169886" + } + ] + }, + { + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1186574299.608995587009377706" + } + ] + }, + { + "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15812227852.701576011915535925" + } + ] + }, + { + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "25850025834.376708123333278670" + } + ] + }, + { + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15376356132.250045445514165950" + } + ] + }, + { + "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "9762599204.437143433283314336" + } + ] + }, + { + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.678747383324805073" + } + ] + }, + { + "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4583277790.314069035393787914" + } + ] + }, + { + "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3192252760.906493428159520191" + } + ] + }, + { + "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32598200271.474079073304604735" + } + ] + }, + { + "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11986642474.515239238070803495" + } + ] + }, + { + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1491407428.638499291892791076" + } + ] + }, + { + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.000000008200074810" + } + ] + }, + { + "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "238242541.508576164280002767" + } + ] + }, + { + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "10982911363.740452103089910785" + } + ] + }, + { + "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "539324167.672321904445007925" + } + ] + }, + { + "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4247641670.745455864797680428" + } + ] + }, + { + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "24905022305.733618844640564250" + } + ] + }, + { + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "23519585548.736582291768757137" + } + ] + }, + { + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "14937531590.521755198594272709" + } + ] + }, + { + "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6101570647.326884697498224390" + } + ] + }, + { + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "25188739122.024442400516517496" + } + ] + }, + { + "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "22703272187.957924377781601946" + } + ] + }, + { + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "20182338713.370527973636616745" + } + ] + }, + { + "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1156593054.161319243614799759" + } + ] + }, + { + "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4209150199.030757097018871025" + } + ] + }, + { + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7491437734.061233480820170767" + } + ] + }, + { + "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "20752661383.101767066969341173" + } + ] + }, + { + "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7231174799.427438369218202505" + } + ] + }, + { + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "59882548526.175225517880905747" + } + ] + }, + { + "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3729583258.268360674575978585" + } + ] + }, + { + "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.730872776412786233" + } + ] + }, + { + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3856572318.851771072193592332" + } + ] + }, + { + "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1121641285.729506202530365697" + } + ] + }, + { + "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "10535382082.831774078181249238" + } + ] + }, + { + "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "19932356085.117152026307143841" + } + ] + }, + { + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3907942954.181938645659497539" + } + ] + }, + { + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "14034395855.684151969521105877" + } + ] + }, + { + "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11611929205.479252180831866808" + } + ] + }, + { + "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15348746910.503476123769763625" + } + ] + }, + { + "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4787120898.780160336455176655" + } + ] + }, + { + "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13890620727.232818420429431135" + } + ] + }, + { + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "10668976316.172822602291681862" + } + ] + }, + { + "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2707301610.153975970423577372" + } + ] + }, + { + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "31852893337.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "92092836922.391558440221811534" + } + ] + }, + { + "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2087788435.418200776424526287" + } + ] + }, + { + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11680570592.639823453395374020" + } + ] + }, + { + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "279399752.525173200280623739" + } + ] + }, + { + "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11317573766.805428918540638656" + } + ] + }, + { + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32328180064.423319206611546586" + } + ] + }, + { + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32965737565.706558742981394560" + } + ] + }, + { + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "21813173013.670232468358393424" + } + ] + }, + { + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "8902110459.391289224658790671" + } + ] + }, + { + "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30568637250.047495197959197696" + } + ] + }, + { + "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "27218433078.031384498796332524" + } + ] + }, + { + "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "16765042786.072138978323269972" + } + ] + }, + { + "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7039007900.090250927297198955" + } + ] + }, + { + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "23310859135.681198341523481656" + } + ] + }, + { + "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "8845550897.653089483109124409" + } + ] + }, + { + "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "643415242.379349043140967768" + } + ] + }, + { + "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3505365960.216933272196077020" + } + ] + }, + { + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1780534040.652204329520714743" + } + ] + }, + { + "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15113937804.117549224775962266" + } + ] + }, + { + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "12751852865.861997681255389525" + } + ] + }, + { + "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "26417240831.344054075916525566" + } + ] + }, + { + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "23612779075.902671847624821978" + } + ] + }, + { + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6708301621.805829658960578965" + } + ] + }, + { + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "394071828.192756186748254466" + } + ] + }, + { + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4865893471.054106591976688258" + } + ] + }, + { + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "16565102521.278623444648051043" + } + ] + }, + { + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15429251118.232731211674479244" + } + ] + }, + { + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "366520347.359138367079797625" + } + ] + }, + { + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4861559078.664980744587286383" + } + ] + }, + { + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "14311640813.184468731208440736" + } + ] + }, + { + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "9250487936.081682822935730661" + } + ] + }, + { + "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.000000000180150137" + } + ] + }, + { + "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15832376449.936755220939206457" + } + ] + }, + { + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "12382233626.659743736725915198" + } + ] + }, + { + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4762044772.816158277497327947" + } + ] + }, + { + "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1196327592.983907819145864128" + } + ] + }, + { + "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4398211183.531754817867646398" + } + ] + }, + { + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11081703733.518827137056819282" + } + ] + }, + { + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4564028000.062910407937527085" + } + ] + }, + { + "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "8255565995.050765057157090981" + } + ] + }, + { + "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "10973507304.839048253284956205" + } + ] + }, + { + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5279249134.484605916395962511" + } + ] + }, + { + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "10292660832.313119256516530727" + } + ] + }, + { + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1503377835.608473133261344084" + } + ] + }, + { + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6932970881.758329424629921610" + } + ] + }, + { + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.039077732414779791" + } + ] + }, + { + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "9660720879.270334500819779497" + } + ] + }, + { + "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5750359180.022920048847960986" + } + ] + }, + { + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "21822836091.192950166124071706" + } + ] + }, + { + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "25176225167.315402180113237786" + } + ] + }, + { + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "16233461599.575941024539501811" + } + ] + }, + { + "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "18818121052.379450688928489869" + } + ] + }, + { + "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1769062615.767787531497192503" + } + ] + }, + { + "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "17021494290.192219756246561560" + } + ] + }, + { + "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.017559471995965787" + } + ] + }, + { + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "72531287930.913064328040812166" + } + ] + }, + { + "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "8935792267.047940856716577941" + } + ] + }, + { + "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2964676563.604466477008846137" + } + ] + }, + { + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3709390855.994028695900542566" + } + ] + }, + { + "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7440174971.015286928233568015" + } + ] + }, + { + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "18828926798.875303947031289624" + } + ] + }, + { + "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "16073693605.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2584782353.707826308221423018" + } + ] + }, + { + "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "29261147380.335414938317826794" + } + ] + }, + { + "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7831893054.662367746440629326" + } + ] + }, + { + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "24030665383.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11281582491.485403113376402651" + } + ] + }, + { + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "695995000.008107666926356585" + } + ] + }, + { + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "19602698420.777667438972556283" + } + ] + }, + { + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30705539084.697448434520200610" + } + ] + }, + { + "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "645816621878.367293520193768267" + } + ] + }, + { + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6284507611.503112537620562852" + } + ] + }, + { + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30267197467.046140347920752886" + } + ] + }, + { + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1702858030.764947001017858982" + } + ] + }, + { + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1148857087.499465536264342298" + } + ] + }, + { + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "31474620879.759763727616154161" + } + ] + }, + { + "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3538765004.906407429568515327" + } + ] + }, + { + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4982786207.080446778604572020" + } + ] + }, + { + "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4322550478.365704941931960840" + } + ] + }, + { + "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "393754972.428724197270373324" + } + ] + }, + { + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "183344357697.108357889602117412" + } + ] + }, + { + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4305875918.065848544638106381" + } + ] + }, + { + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.296620344311288183" + } + ] + }, + { + "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.000000010568084388" + } + ] + }, + { + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.984868576423022223" + } + ] + }, + { + "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5569167846.764595424965116430" + } + ] + }, + { + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30982725275.380854595416700090" + } + ] + }, + { + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "22868767431.258674992913631412" + } + ] + }, + { + "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7410527273.417257058436825667" + } + ] + }, + { + "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "28888366039.201896328490406841" + } + ] + }, + { + "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30016881814.304122473196965404" + } + ] + }, + { + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7491437734.061233480820170767" + } + ] + }, + { + "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "24953883546.381812989649329978" + } + ] + }, + { + "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "26737343970.575423601282944026" + } + ] + }, + { + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.915222892178805867" + } + ] + }, + { + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32578629635.903521192680974262" + } + ] + }, + { + "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4629991007.121270348463553792" + } + ] + }, + { + "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7609968611.277766692803958733" + } + ] + }, + { + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30940652220.067909855227237136" + } + ] + }, + { + "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11710699002.776353141316136395" + } + ] + }, + { + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "20248668283.174600277482822688" + } + ] + }, + { + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15654295055.078633550849799115" + } + ] + }, + { + "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5022344609.482247875627027311" + } + ] + }, + { + "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "898972529.061233480820170767" + } + ] + }, + { + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "12032419756.614984965974294923" + } + ] + }, + { + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5950018859.243540634451321165" + } + ] + }, + { + "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6713911540.137499658822150996" + } + ] + }, + { + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "29604159816.840641093068561244" + } + ] + }, + { + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15060994257.083491216061662735" + } + ] + }, + { + "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6435989540.013921762763316814" + } + ] + }, + { + "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6838136152.615037175085021260" + } + ] + }, + { + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667869107.400743161231430314" + } + ] + }, + { + "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6872161971.350612192443370266" + } + ] + }, + { + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "188862186757.921077920332306886" + } + ] + }, + { + "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4293806142.213096900614901861" + } + ] + }, + { + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "24800561238.279612107830423681" + } + ] + }, + { + "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "19362364963.944129581457482037" + } + ] + }, + { + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5501888149.690502133696473450" + } + ] + }, + { + "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "283466194.255517462784953014" + } + ] + }, + { + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7480775628.212271024900595070" + } + ] + }, + { + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4251311697.155654547507772901" + } + ] + }, + { + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "31646149559.106573719710673659" + } + ] + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "25554844377.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7491437734.061233480820170767" + } + ] + }, + { + "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.000000001029867017" + } + ] + }, + { + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11384451264.610657025520160548" + } + ] + }, + { + "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7491437734.061233480820170767" + } + ] + }, + { + "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.000000000010560399" + } + ] + }, + { + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.761229269409268067" + } + ] + }, + { + "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13320499646.109785502376140729" + } + ] + }, + { + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "26357656015.101505639815155942" + } + ] + }, + { + "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2037871496.161745747665012272" + } + ] + }, + { + "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3262957593.027354006335766007" + } + ] + }, + { + "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4539020696.401796772256668999" + } + ] + }, + { + "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667872132.520451034073092474" + } + ] + }, + { + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "708444493539.650392543815057100" + } + ] + }, + { + "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1489060409.697248161077665311" + } + ] + }, + { + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "27068371579.141295070739546993" + } + ] + }, + { + "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11875195975.520832467094406906" + } + ] + }, + { + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11056908955.278882300765073452" + } + ] + }, + { + "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "269670222.536538166916680288" + } + ] + }, + { + "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1376792534.072854791917986161" + } + ] + }, + { + "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "9246389252.244028771069172506" + } + ] + }, + { + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "31074822357.716339650213728160" + } + ] + }, + { + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "18996793586.879476341521732311" + } + ] + }, + { + "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7101105487.302246818146406250" + } + ] + }, + { + "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13527343184.152064556323864449" + } + ] + }, + { + "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "25176225167.315402180113237786" + } + ] + }, + { + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7838352325.051492113155509734" + } + ] + }, + { + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "31349161589.749906626050893269" + } + ] + }, + { + "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.040153173645477048" + } + ] + }, + { + "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4370182132.035514233647262310" + } + ] + }, + { + "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.684637858590065919" + } + ] + }, + { + "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "11427210316.467976693371780878" + } + ] + }, + { + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "444079902709.451143884839356593" + } + ] + }, + { + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1070219221.118326946516520941" + } + ] + }, + { + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "17215494073.170643188366440982" + } + ] + }, + { + "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "19647631041.570149758029658906" + } + ] + }, + { + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "10324623372.361020700738273242" + } + ] + }, + { + "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "12148059999.607054241837367984" + } + ] + }, + { + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "31597870592.546656317595590730" + } + ] + }, + { + "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "112687796118.974424873851325553" + } + ] + }, + { + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "26060800430.972524809096798726" + } + ] + }, + { + "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "302366795.614952655037558288" + } + ] + }, + { + "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "12111594052.053614597405575288" + } + ] + }, + { + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32372956763.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "17428416405.081307914543346587" + } + ] + }, + { + "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6681478428.376685053433111823" + } + ] + }, + { + "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "874792529.420788333180908175" + } + ] + }, + { + "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "8905047515.681371464004856575" + } + ] + }, + { + "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "26292658617.216324430178584299" + } + ] + }, + { + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "29536482449.046985724736130810" + } + ] + }, + { + "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3078617732.320124450503744079" + } + ] + }, + { + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2978849960.813217307700838576" + } + ] + }, + { + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "603949823.513509808458103600" + } + ] + }, + { + "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3756345859.699570120489841049" + } + ] + }, + { + "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "16881657555.309080574393588903" + } + ] + }, + { + "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "10387065284.263616940433769772" + } + ] + }, + { + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1838179062.644552501830638050" + } + ] + }, + { + "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2281984262.643681243036698338" + } + ] + }, + { + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3840576824.607019537152677998" + } + ] + }, + { + "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.175381665253283715" + } + ] + }, + { + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "31554723907.547803731549142541" + } + ] + }, + { + "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1813439871.341169752719751533" + } + ] + }, + { + "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "51226075.901653923096422965" + } + ] + }, + { + "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "9061862191.464570899664132654" + } + ] + }, + { + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13223340588.859308551321932186" + } + ] + }, + { + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "16954337292.693526774287210266" + } + ] + }, + { + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "7456317782.234348837638428175" + } + ] + }, + { + "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "27430732633.275448957388712899" + } + ] + }, + { + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "21697070140.868247877388767954" + } + ] + }, + { + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "12413866768.273774415754551505" + } + ] + }, + { + "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6625313974.061233480820170767" + } + ] + }, + { + "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3357770219.455058317552130694" + } + ] + }, + { + "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1983117245.095216827935684925" + } + ] + }, + { + "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "3268255262.968986129619963183" + } + ] + }, + { + "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "717587589.405391767552367081" + } + ] + }, + { + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "21233037338.638147619739681502" + } + ] + }, + { + "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "251375143.004754310166118846" + } + ] + }, + { + "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6702327695.877761494338804909" + } + ] + }, + { + "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "8173242868.033189487574265747" + } + ] + }, + { + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "29335651963.155214905560211310" + } + ] + }, + { + "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "20363369993.952452598516547507" + } + ] + }, + { + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4736169209.971261210585364787" + } + ] + }, + { + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "19009296126.940356713521996324" + } + ] + }, + { + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "31756630880.469387280300822842" + } + ] + }, + { + "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "22303221402.975681598448633626" + } + ] + }, + { + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13731927933.676934209964919168" + } + ] + }, + { + "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1621854091.705283752565911617" + } + ] + }, + { + "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.033069359629216292" + } + ] + }, + { + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "8277641822.583445123652347644" + } + ] + }, + { + "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2230674364.963597490904894252" + } + ] + }, + { + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "8205243037.410264065628214006" + } + ] + }, + { + "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13160731423.923070831816120432" + } + ] + }, + { + "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "31233581737.171177753871756710" + } + ] + }, + { + "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13513314439.760880504906257515" + } + ] + }, + { + "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "27078647262.167664364465078829" + } + ] + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "25188841652.827759522584567198" + } + ] + }, + { + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30952447291.576202835534526223" + } + ] + }, + { + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5458068372.195440433865205353" + } + ] + }, + { + "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "17319309526.333681206698225758" + } + ] + }, + { + "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1142673799.671698135354310916" + } + ] + }, + { + "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5061808172.056428799118546191" + } + ] + }, + { + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "25397864297.376635636890792986" + } + ] + }, + { + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "239926289.311199175066434186" + } + ] + }, + { + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "35343843286.901039007622033556" + } + ] + }, + { + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "30814059699.008726822838145807" + } + ] + }, + { + "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2285419328.205248508592749249" + } + ] + }, + { + "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1174883542.187258036855289402" + } + ] + }, + { + "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "27425268290.559019102104827871" + } + ] + }, + { + "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "4539020696.101872352488900792" + } + ] + }, + { + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13985129189.416239603623148731" + } + ] + }, + { + "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "6101286095.766558665001546099" + } + ] + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "19781232193.429308096432999493" + } + ] + }, + { + "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1764535445.724555774238918063" + } + ] + }, + { + "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15477564976.067040516653742243" + } + ] + }, + { + "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "0.891276434601468096" + } + ] + }, + { + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "9301644936.109083164415899687" + } + ] + }, + { + "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "19928728215.894931096994023652" + } + ] + }, + { + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "1520119891.692585578315413794" + } + ] + }, + { + "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "903741229.035846718465032526" + } + ] + }, + { + "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "5176046869.541158581012082931" + } + ] + }, + { + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "13176092868.226450911787779563" + } + ] + }, + { + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "17000022605.192483780939329398" + } + ] + }, + { + "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "16793236941.564038785133487977" + } + ] + }, + { + "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2556241579.807715659172888177" + } + ] + }, + { + "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "23712993284.560665311816608707" + } + ] + }, + { + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "16622128786.002585913660284304" + } + ] + }, + { + "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "35804959813.707173107916888416" + } + ] + }, + { + "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "2189945815.579705929191685262" + } + ] + }, + { + "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "outstanding_rewards": null + }, + { + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "21435411415.823358697847816586" + } + ] + }, + { + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "15935907663.757038179216600516" + } + ] + }, + { + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "outstanding_rewards": [ + { + "denom": "stake", + "amount": "186960971306.660879494461058486" + } + ] + } + ], + "validator_accumulated_commissions": [ + { + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "277106793.379085060880995705" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "528375454.616025550116168257" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "17919450112.486265560724885918" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "36650685.147834037940808756" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3216182769.537267566502926347" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5222044149.414501981269513627" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "159316315311.652442148594472958" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5282822025.770496587886248796" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1694266149.887062395217410896" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "13464597455.693002040748753785" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "30853394.114819286253260622" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "313284872.610534770052663153" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "165711175.150441372956096781" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3883635083.203436659373804991" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "17361078.464024285969583267" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "901370143.144290398313263568" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "515514882.617503415413614078" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "9042545988.049461466938378468" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "9471781585.884609225895050273" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "16958650445.640691116317457097" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "210497461.761590200777121063" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.372454378351718659" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "19093949478.694373195093102337" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6624116332.673643326413807120" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.911746513202759863" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1605872845.093602702083618154" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.922897177570817971" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.809307396335532846" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "15365319997.023040093556811809" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4137340406.786635623849613905" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "888158277.004151113304496023" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6108460201.699772609897943219" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.678747381739283891" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "67876750.369495616131823104" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3192252760.906493428110292228" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "18565657669.240845522854706198" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "227698700.081989892739968849" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1035992898.747517808792808633" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "204823836.791435064159948285" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "238242541.508576160828505834" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1264422561.354404528459365908" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "539324167.672321898794949083" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3348557554.713064312123045489" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "14515380364.326013826645941931" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "10492682990.582862030320466277" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6172519399.334255025005190628" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2779416009.757804733364509848" + } + ] + } + }, + { + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "9462987096.671900612087384837" + } + ] + } + }, + { + "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "10884811246.103690595274200072" + } + ] + } + }, + { + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1156593054.161319238552328930" + } + ] + } + }, + { + "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2969549864.319329755616537086" + } + ] + } + }, + { + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2517242327.788021794537444094" + } + ] + } + }, + { + "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "7231174799.427438348911496884" + } + ] + } + }, + { + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "20415535085.300600305810855920" + } + ] + } + }, + { + "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3628564577.854607465835288073" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3729583258.268360663827945377" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.730872776389496847" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "727468511.827163966271868870" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "443539080.656661733341038036" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "9219557961.909941220098253194" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.798287259643562821" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1625071973.266447765265793749" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "14010630862.905397244157940602" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3868742456.315704367750323102" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "24827423805.046243084037002668" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "209007813.369643938866475631" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "998406746.849611457325733689" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5063754107.056468188631919544" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1585840126.609234778611771961" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "542107876.654206720973554582" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "60570249052.471734300808725551" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2087788435.418200776251472615" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "457565698.824739581007959933" + } + ] + } + }, + { + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "19841691.277488998521068155" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "8386253870.889648281808576890" + } + ] + } + }, + { + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2502177121.751570557615439584" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1913321175.799791883631084942" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "7049343047.385457978329422037" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1807955299.137663563689079302" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.269218634861324671" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "18122629914.191909082126002198" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "518128606.033933702242654350" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3505365960.216933256117891441" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1088655888.703907966613105089" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2404997707.312271750188063590" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "309635025.330001234505614360" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "106232729.667038274225108987" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "451525269.955426958969644791" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6173999738.015913858046021712" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2982671318.818370995664668398" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "39615963.898418932839783220" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "26179773012.093935561850734447" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "358446766.028366775666172929" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.657093524289120227" + } + ] + } + }, + { + "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1760641195.292748050476197170" + } + ] + } + }, + { + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "57023401.060764360053846732" + } + ] + } + }, + { + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "11334939306.896751344811755254" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1496460968.638723867568938016" + } + ] + } + }, + { + "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "357304578.872394901928742331" + } + ] + } + }, + { + "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "360334827.638608685732582369" + } + ] + } + }, + { + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "17832102097.977292317894408791" + } + ] + } + }, + { + "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1261803691.560581223400961357" + } + ] + } + }, + { + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "768829360.356016812865041097" + } + ] + } + }, + { + "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4131540820.475909755531346032" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "9876156574.355143427956460584" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "10077284271.794137717201275555" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "27499856.663866007929934443" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5577446004.931472410981104148" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.039077730500896235" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "9442537894.884848936753835812" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "16136593604.194530483623558451" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "196532702.114908151679458943" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "320752867.021370114030790859" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1419291310.580690020515394483" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.017559471970960521" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "55362050362.088025141531607133" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3038169370.796299891283636499" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "282228430.386525731059968002" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "10802986.622549295974770992" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "778106489.196961655600114269" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "17476224281.345819852032876474" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3521009143.712417456447451464" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1231191151.587291787946168993" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1727606374.518317926293038978" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "939827166.559484129572875521" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "10704132004.092693794840610345" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "10594020970.132285574158281732" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "15290104768.206580602398593906" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2672910620.792123982501072042" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "315560994633.302511918962991399" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "985476794.207414671781679984" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "535116362.703326536779839771" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.621378207506539399" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "462280007.860922507872741088" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4198617809.242572022364345639" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.234577020274302682" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1174904848.162636480329260205" + } + ] + } + }, + { + "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "608652605.707619718314676060" + } + ] + } + }, + { + "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5098983059.386334350777590960" + } + ] + } + }, + { + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4110887229.246190830760061834" + } + ] + } + }, + { + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.296620339914081961" + } + ] + } + }, + { + "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.984868571552507855" + } + ] + } + }, + { + "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.211988653890129529" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5259951931.920439082352243876" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "11062783939.169910923776795037" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "7410527273.417257044130695137" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "12190159952.329409305437883885" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2241438562.431520338273961266" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1306385618.387627384812321579" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6161609546.425337306745443339" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.915222891560483330" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "29591963096.276305889542880860" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3865629784.342460029336936745" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6007412231.571257522971938726" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5001959633.138772959264202502" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1745522978.930349461427722119" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "15347741697.154550789418195693" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2185662379.534427859942116073" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "921192140.970561127318067921" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.973885463121750275" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "369950753.003601331810568469" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2023979919.105426696289036868" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5768495526.158971976738371628" + } + ] + } + }, + { + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "14291401563.340512964420267315" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "11013282385.759629967684477729" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6435989540.013921736043842593" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "783952563.559490614963043696" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "7490224923.584290682442487840" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "7074530368.663948455468727759" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2542901035.340483805265596748" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3765816198.063587525429727015" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "94121758411.137432152822844577" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1212063759.878319664084919355" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2735320379.979481236574224689" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2053954888.037617863314217563" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1152466511.540305723579313447" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "67790689.598536175693120545" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "176953987.495747539465705935" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2295708316.464053455654197366" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3606961189.393231581341044994" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "489477000.336997384781152114" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4491633907.185633003915310721" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.761229269369666070" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "11173277153.455341859217453987" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1651470454.075156671601593586" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "245471199.715003406943272969" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "935721568.343878300767683420" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "512638570.034635767527305791" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "19900777457.138359891421764163" + } + ] + } + }, + { + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "616709690844.948107803587300415" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "378594152.012109173270008245" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "26460806950.115074865881542318" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4473364922.833572894187369426" + } + ] + } + }, + { + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "10121947882.842327806506724259" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "269670222.536538150205029939" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1376792534.072854791654045811" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "29261538831.227011759105810953" + } + ] + } + }, + { + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "146717389.653355862617575999" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1966224709.235392349996651004" + } + ] + } + }, + { + "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2050658504.468701971176653170" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2739403174.407277782418076347" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "10780328757.454289760173961687" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.040153148046354807" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1207594328.437750081127040542" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.684637848776696699" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "14697499.508807378361703466" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "86969720715.747948437493982190" + } + ] + } + }, + { + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1070219221.118326946230364909" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "257130422.779123734899878673" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6177149874.949996410882396263" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6261764164.346494876720764963" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "864900622.021283159098531050" + } + ] + } + }, + { + "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "13793708357.049743717879496927" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5257603171.928755698050608172" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "71909733.189283149930764481" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4400714963.719128256609752294" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "990409100.641271807618667851" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "13689622489.457928167491321838" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2320292914.495778069901718157" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "796471897.362008598599711639" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "60853698.658826404390870382" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "11127466281.080108051347849141" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "19794794946.249954893625129841" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "176315962.441735580569233100" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2978849960.813217298231878130" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "603949823.513509802866417669" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "731753250.605430318889646483" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2424310359.838870556909254733" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1838179062.644552491211163807" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2281984262.643681233750540035" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "855655025.424309398169077457" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.175381639508374923" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "14375354137.255862132472321383" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1813439871.341169748396298709" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "51226075.901653895379048583" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4475193742.787493998110052288" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "570137169.870036047170357928" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1711545963.334268905344256546" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "809417200.054834576882805195" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "7121893770.990194672598519169" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3393411354.357925265591606174" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "10574014570.578186967494133049" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.098456613182261526" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "187490038.144352434924870788" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1983117245.095216807857357404" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3268255262.968986100598839718" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "717587589.405391765800672211" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "19573971462.980076954794627597" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "173448848.673280474014622004" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5812812749.878429105784290673" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4395248538.637439933511619262" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "18916702493.014678191568254058" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.083345401561456978" + } + ] + } + }, + { + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "8432831922.331516907366864390" + } + ] + } + }, + { + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "15695352067.262111032193232725" + } + ] + } + }, + { + "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "13379330700.955599788596771240" + } + ] + } + }, + { + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.250812123199997513" + } + ] + } + }, + { + "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.033069334120454660" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "5882013743.695226765096564642" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "819949534.858298884906474039" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4846422450.938115016005024614" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1044999826.546007091635185885" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "28833490261.832725338386535669" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "13513314439.760880492238326426" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "12913374485.192464060418939753" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "9160397275.853551127737273960" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1854731548.307599642899859027" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "205259995.530384264017183904" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3863275378.219985734240347867" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.100076852969543738" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3044272252.609114282057352623" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "3807822889.007643023782268961" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6259371349.974773943559494431" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "13142253.340468711062168703" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "146098041.506476158905860992" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "12158146783.622659891722269130" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "485367585.883823728864863349" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "2479265539.885419718645476263" + } + ] + } + }, + { + "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "534099257.532275963280022723" + } + ] + } + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1959596116.847024728277261200" + } + ] + } + }, + { + "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "23404905.471265667392571730" + } + ] + } + }, + { + "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "974334308.272468905549661327" + } + ] + } + }, + { + "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.891276428003721941" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4329936388.958354911306147891" + } + ] + } + }, + { + "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "13456930009.407042106926190221" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "0.324150582799065373" + } + ] + } + }, + { + "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "903741229.035846717633311708" + } + ] + } + }, + { + "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "774637220.235809638615652701" + } + ] + } + }, + { + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "910689189.448815092401625690" + } + ] + } + }, + { + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1969536958.783601175071832604" + } + ] + } + }, + { + "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "16078517089.206797598126118738" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "745470508.520604684793912701" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "6968030102.393652296666439447" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "955628472.642170031797186371" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "11621579071.984150218282966402" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "1551154981.438740857459611823" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "accumulated": { + "commission": null + } + }, + { + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "4874329143.745667993186175187" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "12737732456.227655682891563183" + } + ] + } + }, + { + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "accumulated": { + "commission": [ + { + "denom": "stake", + "amount": "34055627676.234885115751275440" + } + ] + } + } + ], + "validator_historical_rewards": [ + { + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.508955723517088539" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.542563501925691871" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.512158938598063517" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.512158938598063517" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.292557112466443942" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.539259718515421305" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.846574216613461540" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.846574216613461540" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.000474683841348262" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.005615493022781994" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.005615493022781994" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.005615493022781994" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.094577217938197191" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.173091786803433045" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.173091786803433045" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.371018262678876459" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.000835365294623529" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "5.904029070862951677" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "6.005371152362798468" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.401660922468163286" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "4.036437109989857068" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "4.036437109989857068" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.301151007082075907" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.915125073946877143" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.172882698073437760" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.160390702721685831" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.318073482619147549" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.409425030456137424" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.604869945812224651" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.623745475040626731" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.277479339607626767" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.057424346716572376" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.188771768611656070" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.490461014765792379" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.663229984723985747" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.663229984723985747" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.760772163248534004" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.760772163248534004" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "period": "11", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.760772163248534004" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.002287855604008229" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.595391980425256456" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.595391980425256456" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.512731017518643148" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.030582869814113061" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.451358340598559564" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.891041271280072008" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.891041271280072008" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.028478558970190569" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.028478558970190569" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.138063059540073047" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.166001761341497381" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "period": "7", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.216111629830644085" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.567013343776276287" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.567013343776276287" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.815739843736418377" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.192131665588792378" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.424179399501514198" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.939918180234345356" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.073826613276445783" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.235570586629868232" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.382380590686964473" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.273441018412842326" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.273441018412842326" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.476855016899218749" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.666847169048692497" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.834168727598941314" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.206428864026463054" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "8.843612149614257729" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "8.843612149614257729" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.054369217226992691" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.126818649319585122" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.126818649319585122" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.154119802519027849" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.134299636052073089" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.197523275359229114" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.249169272474734166" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.267396405659842650" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.152298446988649866" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.152298446988649866" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.273427548172545834" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.917065293185403580" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.967919118512034747" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.221940490937602497" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.221940490937602497" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.259400016265779091" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.259400016265779091" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.466447653853459545" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.508455028347171090" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.518238127250812316" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.051290815241098104" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.212880243805964360" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.151733256707771388" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.515340037809467176" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.747897409567936598" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.747897409567936598" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.599220808780721719" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.599220808780721719" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.599220808780721719" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.163954274436273491" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.310783022065728778" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.078441620834608469" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.078441620834608469" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.078441620834608469" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.336825222876443490" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.336825222876443490" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "36.538908882381596359" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.350086981644848764" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.296125988619195519" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.296125988619195519" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.619350435630525552" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.708550721140497084" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.750069990142618522" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.270663939556433745" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.752014609273368997" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.255403392932049217" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.877223393710481831" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.877223393710481831" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.877223393710481831" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.877223393710481831" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.383583718736168712" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.072792680276490502" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.144751344296845662" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.946868424007155163" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.946868424007155163" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.141005036071022583" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.318032511103067061" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.318032511103067061" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.318032511103067061" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.119175178219769035" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.068794153277072224" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.170751641509677360" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.210611869948743637" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.240719178925335759" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.207384000437970359" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.486190297642737493" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.611598254372192098" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.614122872633608225" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.110295957981012900" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.110295957981012900" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.309243186282087537" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.339376068938902310" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.350913583702945613" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.397473163899589313" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.397473163899589313" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.597078596524170485" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.229396561381528283" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.474400210195279884" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.659477915344641803" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.883512421247652384" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.883512421247652384" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.559277541061147180" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.824569427993582067" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.824569427993582067" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.185175927794623096" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.480550630133862309" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.480550630133862309" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.610321057886218898" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.686782211213352937" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.686782211213352937" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.357968318375469932" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.173605006014279649" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.781147064900722304" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.421038197250524001" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.421038197250524001" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.421038197250524001" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "24.988423861775581700" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "24.988423861775581700" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "24.988423861775581700" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.526902796086228049" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.846611257244369419" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.273209707497210333" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.624847947868380059" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.903081800941262823" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.903081800941262823" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.570157717922226862" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.839315869555212482" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "period": "11", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.839315869555212482" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.001541101634230003" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.417350425346321544" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.095747288859477657" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.270808659467670758" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.391785608601979419" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.407901633183955436" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.891449312982646896" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.891449312982646896" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.209578717794916469" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.767068091242484641" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.794115066133505828" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.877887324030848658" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.150964203522089691" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.150964203522089691" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.434840876964488414" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.656454126215802271" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.656454126215802271" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.310884678556496230" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.700189859456185775" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.761497421872785615" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "2.183522127673967339" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "13.569354899133857126" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "13.569354899133857126" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.565789000020855573" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.989795865475541526" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.989795865475541526" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.026251017841887978" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.135302564883484283" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.515002033830662918" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.515002033830662918" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.864631386174660712" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.050646807222448412" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.136552312176860264" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.177946896419520703" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.261681360082728441" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.414289254830467158" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.662613494259503477" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.662613494259503477" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.859773648661399554" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.795788163476169546" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.795788163476169546" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.822201146798542294" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "2.165040796606679122" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.563323721181839992" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.865081502013398577" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.492498420673879908" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.700085550422976946" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.335010193218545655" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.233280613638698077" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.320565115851631010" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.341072388663254009" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.341072388663254009" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.450947240430845210" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.105038387024241749" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.663809594221120553" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.663809594221120553" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.320929441280401346" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.370608946037426438" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "period": "11", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.417934950719199317" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "period": "12", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.469324463792518916" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.700206851908699409" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.379262677998642793" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.414177418109768832" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.414177418109768832" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.530067227150287181" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.608093994127972862" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.149345876234480559" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.459285021970866948" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.169135244025127739" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.396312921934332814" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "32.890614958717885895" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "32.890614958717885895" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "32.890614958717885895" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "32.919475633814259617" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "33.034297994814080039" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.171968911695567069" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.171968911695567069" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.322079633470521028" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.322079633470521028" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.142027394111757355" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "period": "7", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.064911538484032280" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.116980167755658378" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.285012775586208784" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.404346417765050364" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.649795547220870492" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.859877589627982513" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.248937513973307998" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "period": "11", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.248937513973307998" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.078599581646267108" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.078599581646267108" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.424181202517676095" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.424181202517676095" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.120204712097828385" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.187202790083739017" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.312523098782197027" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.231076015729088306" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "2.065298901068817010" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.112612489782853395" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.219230629967503357" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "23.404215035392724140" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "23.404215035392724140" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "23.404215035392724140" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.148953688872066051" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.772423060454248439" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.772423060454248439" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.490199190222128798" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.076141455703225906" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.030937133125724216" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.029303158405101084" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.114875714168666683" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.008628143921719196" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.008628143921719196" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.012533818609960684" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "period": "7", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.076828297662844090" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.042479281713289724" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.190911431953188409" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.190911431953188409" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.190911431953188409" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.579776534326837376" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.579776534326837376" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.434833192557042808" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.434833192557042808" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.434833192557042808" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.567490307628004052" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "period": "11", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.567490307628004052" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.700206851908699408" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.073714006353122275" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.432593195927369366" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.432593195927369366" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.298828653346982190" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.864631386174660711" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.165964355430803461" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.410388415913048804" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.437535036040629257" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.609804279969736582" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.655548873680788553" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.293548981437233758" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.401066343498857766" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.506919131289083168" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.561145622221834061" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.265736377377838682" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.756880274646164803" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "10.994686653318717548" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "10.994686653318717548" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.184193527891644194" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.250260481007298057" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.276006003337242016" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.364666619671323075" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.268086681179230699" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.102183399208957639" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.271996755742583159" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.417119321775713473" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.543611903201309404" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.046069743680559697" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.046069743680559697" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.046073021507499671" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "period": "11", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.090432945661913993" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.282826355813809912" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.095765663829970693" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.107832997733037325" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.588545225098858270" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.228162415811999516" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.287038741530549007" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.886207688757766439" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.098996222839621020" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.513477283857156384" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.731255206582442871" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.731255206582442871" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.196110242276430759" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.398426524855468392" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.447547977222836718" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.635046107289342641" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "28.844044764030850346" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.126422954094864104" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.126422954094864104" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.200139687281353638" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.255134016027277099" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.420722060554982250" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.473954684434682203" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.629641264581146636" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.635895226788104729" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.913377101663268077" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.002173152155111373" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.241380222482488555" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.241380222482488555" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.260421641812595937" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.544766746539198414" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.661631731670176180" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.678955694723845020" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.262070862528108472" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.511828296909926465" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.511828296909926465" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.511828296909926465" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "period": "11", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.511828296909926465" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "period": "12", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.511828296909926465" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.331073341429133859" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.331073341429133859" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "period": "11", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.439328433311137470" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.029009447969056924" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.284327628093379831" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.808712914763694308" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.145222821352800219" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.283654680026977732" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.283654680026977732" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.283654680026977732" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.283654680026977732" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.756939836817478007" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.756939836817478007" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.756939836817478007" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.332016052780443560" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.756348996398941036" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "2.244481277225370187" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "2.466989093298784981" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.230019187243455262" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.353979172798147590" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.353979172798147590" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.199237867802823236" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.370762382762272957" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.457589199420750226" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.503758648547016424" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "7.467609130427488916" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "7.467609130427488916" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.474965934828543354" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.873581241325519122" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.484539683819238278" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.236556624097939312" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.236556624097939312" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.770107177755693811" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.011535332436306032" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.054356314996810688" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "7.150400405663851910" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "7.150400405663851910" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "7.150400405663851910" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.065925318393522025" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.110221058206893324" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.256456323790825639" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.306081722657220204" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.184183692778275370" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.363593829221112941" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.458603246128568339" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.477969199906528332" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.046312256868738422" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.257907757807096905" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.257907757807096905" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.447208138617613350" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.221440160560810951" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.024057291139310145" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.024057291139310145" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.933143355353396544" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.933143355353396544" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.436103498845057384" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.036554075174326429" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.605360338672048326" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.605360338672048326" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.808167653764758611" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.808167653764758611" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.998959856174665812" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.129992520315172351" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.129995597411229376" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.023215176576678970" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.183556028644616263" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.088881592834584131" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.206743884649377797" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.248203112172867948" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.039797021340298366" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.061529843348518555" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.119200586504466392" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.148649641548535740" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.916402494333050929" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.962075160276744298" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.970527967271634562" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.753760682965552344" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.275567372174847246" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.854501200377174934" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.149903774315467627" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.149903774315467627" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.422519071691696181" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "2.450232020577983513" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "2.464182782143535222" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.144448494759326209" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.137721444798981971" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.250371673774951692" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.317593671645006471" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.333335988538244700" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.274449486254448582" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.506369110375782713" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.736610702598603812" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.736610702598603812" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.736610702598603812" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.117254721392916114" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.117254721392916114" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.590467103140862840" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.674050151055652454" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.460129764831110061" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.491665549011150248" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.390958504850043449" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.390958504850043449" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.564166425327200989" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.717267512605129179" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.732196537149002150" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.745937805858183221" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "5.221625441519346423" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "5.221625441519346423" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "4.070296880898123125" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "4.070296880898123125" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.169670321998103923" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.180874774492538778" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.764864680668560110" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "86.648801710052384136" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "86.648801710052384136" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.200632423730348614" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.427404443767361769" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.449907572372872787" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.534058574665531523" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "157.961554460589527700" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "157.961554460589527700" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "157.961554460589527700" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.847263900313882195" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.256704400909965176" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.567225536578985974" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.002027753539710014" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.019789059558728136" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.766979617911744878" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.227419302074647986" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "19.371457586302624669" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "19.409430364233236385" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.944429441511932348" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.971700777122653302" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "4.027208695009346361" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.088761716208659899" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.101696180930628051" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.101696180930628051" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.177214844124636366" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.471062131657995570" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.858966296940444569" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.691886255527295296" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.010940084028270015" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.010940084028270015" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.154256756806974630" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "5.756655809161183966" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "5.756655809161183966" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.581910361718164399" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.934259605792279606" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.056626821488016550" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.056626821488016550" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.063545823013262070" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.526266558664323650" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.363741243977559781" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.533689230160560385" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.636015099045481807" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.547504316209318183" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.574168096299156240" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.625246919115774701" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.801213498670300992" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.845379831916487104" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "period": "11", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.867932867080139153" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "311.798337991010339097" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "312.077404997298917340" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.298828653346982190" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.627382502211158266" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.001930268506313024" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.063771610982219202" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.263615452639460650" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.281448635188006245" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.361491420037509609" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.161832861350326277" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.161832861350326277" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.543360367590610392" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.738313496721540536" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.087075135369242876" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "4.493581420913290268" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.508603290074890441" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.471402462188297682" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.471402462188297682" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "6.059401416740521166" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.387701131555288654" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.387701131555288654" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.387701131555288654" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.387701131555288654" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.387701131555288654" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.441359228546445605" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.155820651154462258" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.519360732254465526" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.701610762954179236" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.218907031877339606" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.467104902338620579" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.103441651434462990" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.142266672736999887" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.146186463515190020" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.535395044881059979" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.734425098643432068" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.395987317975159049" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.340966682397893180" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.663477504484533124" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.040015039089868574" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.199039534873975854" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "period": "7", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.180499654578205964" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.556694244495838963" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.556694244495838963" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.252398441235965157" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.481255014899103572" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.801403486960695697" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.029212228751076174" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.108575989671163098" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.292636862490135412" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.197039744419585537" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.197039744419585537" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.533474557093356374" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.543751057449875837" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.591285799818710396" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.136491509697193693" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.344508750192330231" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.471178261485792552" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.471178261485792552" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.469031563197041037" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.469031563197041037" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.469031563197041037" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.469031563197041037" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.469031563197041037" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.598837530935306853" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.598837530935306853" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.598837530935306853" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.598837530935306853" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.285011419265350886" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.220895528328028253" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.289857378890239655" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.289857378890239655" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.310360049843716433" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.202105773239370600" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.478847331972890432" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.353395247667561575" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.353395247667561575" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.724577348352943670" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.724577348352943670" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.660446556261372365" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.702793484052293362" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.753745357470380309" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.204348319215397700" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.122935146571044695" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.371703352608772489" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.461603673337516151" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.325491261308193869" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.325491261308193869" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.325491261308193869" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.325491261308193869" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.347374092486373052" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.347374092486373052" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.911264890965101800" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.003816424344824336" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.040422970676080202" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.040422970676080202" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.083810881200298487" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.293613302521008568" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.293613302521008568" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.775621563999071135" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.257370615697938158" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.257370615697938158" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.514282283976201934" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.282182429412887710" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.545479138254305424" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.545479138254305424" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.476669259852289803" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "period": "7", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.114037108225667859" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.694901382265562967" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.694901382265562967" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.107414724940683291" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.385412937873562418" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.440965124276557169" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.491075778461947379" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "5.017756007824860076" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.031276655884644091" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.807054301010728759" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "3.807054301010728759" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.142790727918078468" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.454963964573873576" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "period": "8", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "period": "9", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.406022113728034876" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.431268412831162379" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.553781423080636782" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.892548405116256022" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "2.252249400629833990" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.477714728073539320" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.849708251321342013" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.893051358262773306" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.490818675976954795" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.436593002540042404" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.073320885007748875" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.535558383829381441" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.332603033346361600" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.459225817882215127" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.645952564692883135" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.357184476675212901" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.429911552112663222" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.461405650001174819" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.413430933501424942" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.769399218330863983" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.355017527818609928" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.619764841808303999" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "7.667125683221357209" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.184030369224211166" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.112141876661149759" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.112141876661149759" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.149194260691448546" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.178423986670076652" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.182069724381419970" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.043959100604340286" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.676940589428158514" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.189145919230691870" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.189145919230691870" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.190447099910047547" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.288085592128558286" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.698351523942020326" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.021146682583610744" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.021146682583610744" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.021146682583610744" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.021146682583610744" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.030479689497189926" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.038674767433370474" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.040580231688491452" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.203572174672298865" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.203572174672298865" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.435317429638750043" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.436561252806344649" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.563267904309655740" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.312934457284712428" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.442650070304518367" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.607552276882744775" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.607552276882744775" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.716394249059422611" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.756485557017069964" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.033776776601805758" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "1.074389589039980650" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.031819165140208083" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.031819165140208083" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.239366389934611146" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.239366389934611146" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.588113177176492129" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.204352547182237737" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.188789752641750492" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.410727611393759172" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.437168102787542193" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.365397753164372903" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.365397753164372903" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.393581453177263078" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.479672415425195885" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.560965441700099170" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.875942601310433345" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.120595545766831513" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.120595545766831513" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.283082377207714653" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.589090760178416885" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.942703959089804304" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.565802732827678521" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.212773850507660359" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.299936634632612982" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.477268654394609335" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.524661209857995026" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.108089277510599707" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.109083043467755379" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.109083043467755379" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.154779429229998187" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.208668141601046137" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "period": "10", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.309791005660900330" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.482746151601472326" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.672749242240428784" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.296190207076740235" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.524769104516729944" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.715523252545739256" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "period": "7", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.274825957416607507" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.310894903803217812" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.344210764807960415" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.344210764807960415" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.405208712580924657" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.145461953371886485" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.225863412681956186" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "4.959799004029151994" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "4.959799004029151994" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.024951965636852620" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "period": "8", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.061979194321506474" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "period": "9", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.080295993442108039" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "187.413887557735487405" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "187.462581570737087887" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "187.462581570737087887" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.264647651726356133" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.528614955427939816" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.068235035171399741" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.142296765122500266" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.142296765122500266" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.023420272998184008" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "period": "5", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "period": "6", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.200709929817638069" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.279826910541697627" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "period": "7", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.491061198265997197" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.524230507909253594" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", + "period": "2", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.000680142970688233" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "period": "1", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "period": "4", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.465172269995272757" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "period": "3", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.156563688628831681" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.156563688628831681" + } + ], + "reference_count": 2 + } + }, + { + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "period": "2", + "rewards": { + "cumulative_reward_ratio": null, + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "period": "3", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "0.331380449076186771" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "period": "4", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "4.623193121068814234" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "period": "5", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "11.584704835586788983" + } + ], + "reference_count": 1 + } + }, + { + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "period": "6", + "rewards": { + "cumulative_reward_ratio": [ + { + "denom": "stake", + "amount": "11.636314104881138704" + } + ], + "reference_count": 2 + } + } + ], + "validator_current_rewards": [ + { + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10277856493.095527634341114904" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5598272961.593727179547443916" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4644676884.264688729175493902" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "207115681.025667265023541583" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "987842598.110607568180848335" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2319843589.860200357714156727" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "6398870562.632966843733971534" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1363676012.401787208658110575" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1951801273.054658318178936705" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1911059153.592562708651237926" + } + ], + "period": "12" + } + }, + { + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3926305099.530430590559144506" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3028192283.155572883030556622" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "201152142.841772417931176441" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2066040211.812572378498275677" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1971867051.381170304057033217" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3436765880.424118073825795747" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1677701162.661693330653296004" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1647219660.107198791051496038" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2304895437.957699566725260195" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2801478626.896694449069559090" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1643967281.585803107651548006" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "537317001.751974461235704920" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2832628067.598138303987512647" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "601061546.262455691743635782" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3436765880.424118073825795747" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1186574298.799688190673844860" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "446907855.678535896322872727" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7306007670.973161470203794940" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "8187667982.011825080885306354" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1933620990.361499357724348509" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4515401039.944573415450652442" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5325554931.526395362771097545" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10892509809.810023263230358585" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5179332683.873887686640493447" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "603892572.388185001163485678" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7067971370.869856813516222550" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7608889331.309968025237122554" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1574721924.755928436315422829" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3355456835.961132277473220851" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3322154637.569079964133714542" + } + ], + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7807843748.311728421938425430" + } + ], + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2291641173.511292899566090834" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "401395097.450603808916253285" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1239600334.711427321397218259" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "rewards": { + "rewards": null, + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4122561348.298171183872075374" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "36671140963.536449349290218718" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1853519374.369019667718703971" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "678102205.072844469189327661" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1093048506.563894512888872706" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "19932356084.318864766663581020" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "rewards": { + "rewards": null, + "period": "12" + } + }, + { + "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1004659121.032487853959078690" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "6042294040.155696517456949334" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5618789041.564142217938192403" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "rewards": { + "rewards": null, + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "6374004719.768473657017459264" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1251139087.243721814259766527" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1121461483.544741191811805411" + } + ], + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2223487035.599475204311373362" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1354516488.279692958744195339" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5613519681.719975598382050237" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2319843589.860200357714156727" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "14990202826.251880183671027497" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3436765880.424118073825795747" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1393235352.105575314389468340" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "9397139134.575948555432132014" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3723453677.839623241906194567" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2555.213090618434431017" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7039007900.090250919436094208" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4894071601.506831715974346381" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4539020696.101872342219391398" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "125286636.345415321762708849" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "rewards": { + "rewards": null, + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "rewards": { + "rewards": null, + "period": "13" + } + }, + { + "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "15113937804.117549223425100410" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "rewards": { + "rewards": null, + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "8849100013.706146085491057893" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "14688188410.899554447332040073" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3686177074.703639439562514822" + } + ], + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "394071828.192756186748254466" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2483086266.972933686472908307" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7557143757.354046174020121979" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "12446579799.414360216009810846" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "326904383.460719434240014405" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3590650159.424016330204455704" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4503112312.636613968921113454" + } + ], + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "9058497628.480504327647609498" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10991922908.259483610583649145" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2063986939.818770845290145987" + } + ], + "period": "12" + } + }, + { + "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10399507333.683802036350540862" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "14615455234.544764761123279589" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "707078808.342185924438361202" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3265583804.177434409928389931" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "839023014.111512917217121797" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "rewards": { + "rewards": null, + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1937171809.118902989821754916" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "9819900041.958245913396840287" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "231595697.967335131464966680" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2888671022.634193415479724729" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "112299762.792637984426125829" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "227675550.755497053417389152" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "rewards": { + "rewards": null, + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2319843589.860200357714156727" + } + ], + "period": "12" + } + }, + { + "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5718283025.416988549547676845" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7814724437.948367285321324228" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3436765880.424118073825795747" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2209641436.196926422039779733" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "15602202979.611529735731167077" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "92166192.336386139126686690" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5897622896.251640965432941442" + } + ], + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1150356947.981178229830440766" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1680607357.226291265231113981" + } + ], + "period": "12" + } + }, + { + "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "6662068481.818325252347112441" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "113831668.874438727942326348" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2197273882.042086403055666925" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5316897302.422479873915926716" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "6892065888.102883616867753805" + } + ], + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2332731601.904736860142073240" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "687561521.353117516872695214" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4312593652.571086836573962377" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3155565231.002254805343332690" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5250592474.043364431975225923" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2447696196.583747208629166579" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "6204828909.868571885567149301" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2319843589.860200357714156727" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1702858030.143568780376434943" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2021685235.512978206804270778" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "rewards": { + "rewards": null, + "period": "13" + } + }, + { + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2028048202.307410522302391737" + } + ], + "period": "12" + } + }, + { + "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3509692958.346542084006835789" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "393754972.428724197270373324" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "157172457837.054334966340067567" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "173880003.613594947919371866" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "227148443.582882441770606603" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "14302275850.186440696321400753" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1534242123.510360829138729858" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "8181459114.211123346723938410" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5875336278.412130611927525351" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7491437734.061233480820170767" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "11500406842.994660324297925520" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "292475423.967537468726778995" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "218416067.863109613392324888" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "764361222.778810319126617047" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1139304547.183015572580322888" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "9308877664.292234857132027766" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "9822303024.430489822046174088" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2193467946.249668901240701224" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3199549710.994219904011830049" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4101152468.511686716467324195" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2319843589.860200357714156727" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1497119897.823456116878843655" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2421966811.505426338835378498" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "339880755.615222398900084080" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "25176225167.315402156070622219" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3216656900.040751710953152141" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "693815441.355293014733148834" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "rewards": { + "rewards": null, + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "25177644183.816452478788942474" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "8611504919.398159318221121044" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "23216469146.898232635076615207" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3106345773.287024664465366968" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2139796968.727373856040601704" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3081742382.334777204579359675" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10071749470.035747765542455736" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "16604774031.708783525607604938" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4349421638.150196390156994096" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "215675504.656981287091832469" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "161743647.252169855098040454" + } + ], + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1955603380.691601091853575535" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10991922908.259483610583649145" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1558595001.985836620189378607" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "rewards": { + "rewards": null, + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2357916264.070593421465284924" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5718283025.416988549547676845" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "rewards": { + "rewards": null, + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2147222492.654443636033627948" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3160048499.127467157233427135" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1792400296.446742328721345766" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2327236024.683475694635561075" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4026382126.367160983653377973" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7065842396.077887077039311910" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "182850447.150587687655227970" + } + ], + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "440770282.073438067965689778" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1375740631.181223323134103734" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5718283025.416988549547676845" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "241894085.219643171790147572" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2180215181.127225346211699161" + } + ], + "period": "12" + } + }, + { + "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1973396739.534890353988431837" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3436765880.424118073825795747" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "211113641.859744915012615635" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "23065029415.383302245346169903" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "8265647216.078788559023112266" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1684290275.338641260527058094" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1751710576.406325818010401932" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "44705080263.489304355798548551" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "rewards": { + "rewards": null, + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10196114025.215344641096004591" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1144089328.023521390586505704" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1855825238.316881274542133969" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10700903590.799739908109935897" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "94561396079.057568467994560497" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4524122154.670781273294931278" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "230457062.425669505106793807" + } + ], + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1391073393.469104204083586851" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "24185816067.293205777194315649" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1568033134.761683991816708514" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4361185513.880906983531393666" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7009528441.827634161935745041" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1529643770.501179302608631523" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "914146821.551748304988879216" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2902301769.878388869934510979" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "rewards": { + "rewards": null, + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "rewards": { + "rewards": null, + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "8504987265.571841049655408230" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1858169822.665157405963776665" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2241000588.727955980234459650" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1299000034.324490670518315250" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "32667662901.376635636890792986" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "294256991.593177306128024752" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2279356179.944864697955020983" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10625240926.417478383178251817" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2814481474.179620526783305581" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1716684256.496548264708475978" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "rewards": { + "rewards": null, + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2646308819.776185027003928900" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "rewards": { + "rewards": null, + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1658240365.504973610378159106" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "77926294.331473836151496842" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "889514945.999332377946100865" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2319843589.860200357714156727" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1446667500.937774398753834248" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "rewards": { + "rewards": null, + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3069201314.978010458699757549" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1785553468.049878322256441287" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3825422439.162096659422521657" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "856741087.085451869907038352" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1107485537.421188876918645768" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "196663111.831388265460850030" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1290111576.027326572878630839" + } + ], + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7587187076.317934933846109321" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "257518655.871820875389864165" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2148940801.123186164411551775" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4232132616.947595477084691464" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "9692018924.954280961651733113" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1142673799.571621282384767178" + } + ], + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "22830073747.371989590140957747" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "946279965.124689968806293180" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3350081078.147129251489514962" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "226784035.970730464004265483" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "17906334898.088564400394840052" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5803250531.986983532609795422" + } + ], + "period": "9" + } + }, + { + "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2285419328.205248498506895507" + } + ], + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "689515956.303434307990426053" + } + ], + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "6522712666.029723303123055259" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4539020696.101872342219391398" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "rewards": { + "rewards": null, + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "5567186838.234282701721523376" + } + ], + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "3169264575.957925880112131596" + } + ], + "period": "11" + } + }, + { + "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "287284436.730054004650552695" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1345509282.118916207474210902" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", + "rewards": { + "rewards": null, + "period": "4" + } + }, + { + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "4971708547.150728253109751796" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", + "rewards": { + "rewards": null, + "period": "2" + } + }, + { + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "2095302590.555015731083724595" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "rewards": { + "rewards": null, + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1596804303.998904168738439964" + } + ], + "period": "10" + } + }, + { + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "7981599483.029009876099804721" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "12348237265.667906050348522004" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "541193976.848853395308213099" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1458919260.535587204455444789" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "rewards": { + "rewards": null, + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "16744963182.167013015150169260" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1864133135.176273727732462590" + } + ], + "period": "8" + } + }, + { + "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "rewards": { + "rewards": null, + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "10929960502.284962257920895496" + } + ], + "period": "5" + } + }, + { + "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "638790834.140965066703183270" + } + ], + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "rewards": { + "rewards": null, + "period": "3" + } + }, + { + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1571681108.047964868152707101" + } + ], + "period": "7" + } + }, + { + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1785517640.312737824040413180" + } + ], + "period": "6" + } + }, + { + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "rewards": { + "rewards": [ + { + "denom": "stake", + "amount": "1116422514.011874203580116273" + } + ], + "period": "7" + } + } + ], + "delegator_starting_infos": [ + { + "delegator_address": "cosmos1qqxeqqvjkh2ls3a0taukd8rydrqqad690nxkcc", + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "starting_info": { + "previous_period": "7", + "stake": "12420219756.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "starting_info": { + "previous_period": "3", + "stake": "12278061721.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "starting_info": { + "previous_period": "4", + "stake": "3831088.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "starting_info": { + "previous_period": "6", + "stake": "65633207.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", + "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "starting_info": { + "previous_period": "3", + "stake": "4141412671.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", + "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "starting_info": { + "previous_period": "5", + "stake": "1611728813.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "starting_info": { + "previous_period": "7", + "stake": "5978697013.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "starting_info": { + "previous_period": "4", + "stake": "8832434015.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "starting_info": { + "previous_period": "2", + "stake": "21431257869.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "starting_info": { + "previous_period": "6", + "stake": "3906909228.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "starting_info": { + "previous_period": "3", + "stake": "6479198849.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "starting_info": { + "previous_period": "4", + "stake": "24728825327.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "starting_info": { + "previous_period": "5", + "stake": "2665696727.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1qy0qwzljplfauvyhgayw6nxte2zxujh4tnq09z", + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "starting_info": { + "previous_period": "1", + "stake": "17076084961.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6", + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "starting_info": { + "previous_period": "3", + "stake": "27081595327.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "starting_info": { + "previous_period": "2", + "stake": "5366509387.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "starting_info": { + "previous_period": "2", + "stake": "8265210908.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "starting_info": { + "previous_period": "4", + "stake": "1415578984.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "starting_info": { + "previous_period": "3", + "stake": "2399562500.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1q9ed2n5wvzcrymaqltypazqzd2xv8d5aw58flt", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "starting_info": { + "previous_period": "5", + "stake": "393807838.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1rcru2vteas2kunww3zt4knx28krlestxydpwza", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "starting_info": { + "previous_period": "3", + "stake": "20016004053.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "starting_info": { + "previous_period": "4", + "stake": "9390268176.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "starting_info": { + "previous_period": "7", + "stake": "113007060.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "starting_info": { + "previous_period": "2", + "stake": "21462438160.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "starting_info": { + "previous_period": "6", + "stake": "411136992.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", + "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "starting_info": { + "previous_period": "1", + "stake": "8434736549.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", + "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "starting_info": { + "previous_period": "2", + "stake": "1856911069.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "starting_info": { + "previous_period": "6", + "stake": "9657784018.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "starting_info": { + "previous_period": "3", + "stake": "2267056403.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "starting_info": { + "previous_period": "5", + "stake": "1067919041.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "starting_info": { + "previous_period": "4", + "stake": "3023435039.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "starting_info": { + "previous_period": "4", + "stake": "250632594.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "starting_info": { + "previous_period": "5", + "stake": "632967960.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "starting_info": { + "previous_period": "6", + "stake": "5503709183.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "starting_info": { + "previous_period": "3", + "stake": "319721226.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1q0cw6hmrm4myx5c3zzmw6deelygsl2hrts2ju4", + "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", + "starting_info": { + "previous_period": "1", + "stake": "998337488.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "starting_info": { + "previous_period": "4", + "stake": "14607898235.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "starting_info": { + "previous_period": "6", + "stake": "16848374286.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "starting_info": { + "previous_period": "8", + "stake": "1128230444.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", + "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "starting_info": { + "previous_period": "3", + "stake": "15545552914.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", + "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", + "starting_info": { + "previous_period": "2", + "stake": "632273041.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", + "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", + "starting_info": { + "previous_period": "2", + "stake": "847666854.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "starting_info": { + "previous_period": "8", + "stake": "331591913.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "starting_info": { + "previous_period": "5", + "stake": "78323397.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "starting_info": { + "previous_period": "2", + "stake": "19004884526.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "starting_info": { + "previous_period": "9", + "stake": "489746723.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1l6u5cg3wcptmcjyhxtfrrfq3nu036acdauf0fy", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "starting_info": { + "previous_period": "6", + "stake": "15368943494.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", + "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", + "starting_info": { + "previous_period": "4", + "stake": "1750195180.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", + "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "starting_info": { + "previous_period": "4", + "stake": "4432663925.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "starting_info": { + "previous_period": "3", + "stake": "671769813.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "starting_info": { + "previous_period": "1", + "stake": "7134357042.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "starting_info": { + "previous_period": "3", + "stake": "177902750.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "starting_info": { + "previous_period": "4", + "stake": "126313.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1h72kkqt83nth0npqvgmardgelg6jyx7zupnypp", + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "starting_info": { + "previous_period": "2", + "stake": "1604525333.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "starting_info": { + "previous_period": "5", + "stake": "4686886799.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "starting_info": { + "previous_period": "7", + "stake": "2320211243.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "starting_info": { + "previous_period": "9", + "stake": "1406012334.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "starting_info": { + "previous_period": "10", + "stake": "14744952147.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "starting_info": { + "previous_period": "8", + "stake": "879369780.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "starting_info": { + "previous_period": "11", + "stake": "315931330.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1qlkz3yutzuz0el2ullpyyaflfp78x8rr2cgld7", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "starting_info": { + "previous_period": "2", + "stake": "24971252484.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "starting_info": { + "previous_period": "1", + "stake": "17451346039.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "starting_info": { + "previous_period": "5", + "stake": "7302955.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "starting_info": { + "previous_period": "4", + "stake": "2313732788.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "starting_info": { + "previous_period": "6", + "stake": "235709907.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", + "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "starting_info": { + "previous_period": "2", + "stake": "24914473521.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "starting_info": { + "previous_period": "3", + "stake": "58360958.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "starting_info": { + "previous_period": "1", + "stake": "107356796.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "starting_info": { + "previous_period": "4", + "stake": "141624981.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "starting_info": { + "previous_period": "3", + "stake": "3115334630.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "starting_info": { + "previous_period": "5", + "stake": "11943268264.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", + "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", + "starting_info": { + "previous_period": "2", + "stake": "5044911319.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "starting_info": { + "previous_period": "6", + "stake": "22896384744.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "starting_info": { + "previous_period": "4", + "stake": "6892307704.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "starting_info": { + "previous_period": "5", + "stake": "7497643277.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", + "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", + "starting_info": { + "previous_period": "1", + "stake": "203339835.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "starting_info": { + "previous_period": "4", + "stake": "1211564528.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "starting_info": { + "previous_period": "3", + "stake": "4778016243.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "starting_info": { + "previous_period": "5", + "stake": "68637287.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", + "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", + "starting_info": { + "previous_period": "1", + "stake": "7304584820.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", + "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "starting_info": { + "previous_period": "2", + "stake": "25069342080.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", + "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "starting_info": { + "previous_period": "3", + "stake": "1040485229.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "starting_info": { + "previous_period": "5", + "stake": "1195742287.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "starting_info": { + "previous_period": "6", + "stake": "1956086691.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "starting_info": { + "previous_period": "7", + "stake": "3423632102.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "starting_info": { + "previous_period": "7", + "stake": "22844129667.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "starting_info": { + "previous_period": "6", + "stake": "63638410.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "starting_info": { + "previous_period": "8", + "stake": "16096304.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "starting_info": { + "previous_period": "3", + "stake": "2280542883.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", + "starting_info": { + "previous_period": "4", + "stake": "101462019.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "starting_info": { + "previous_period": "3", + "stake": "19076209513.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "starting_info": { + "previous_period": "5", + "stake": "4784005.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "starting_info": { + "previous_period": "6", + "stake": "1316682053.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "starting_info": { + "previous_period": "2", + "stake": "2616582981.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", + "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", + "starting_info": { + "previous_period": "1", + "stake": "5183376555.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "starting_info": { + "previous_period": "3", + "stake": "6189191937.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "starting_info": { + "previous_period": "4", + "stake": "19589707878.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "starting_info": { + "previous_period": "5", + "stake": "23726525801.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "starting_info": { + "previous_period": "6", + "stake": "14430378546.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "starting_info": { + "previous_period": "4", + "stake": "667949570.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "starting_info": { + "previous_period": "2", + "stake": "2151028602.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "starting_info": { + "previous_period": "3", + "stake": "6774702429.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "starting_info": { + "previous_period": "7", + "stake": "1397139502.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "starting_info": { + "previous_period": "5", + "stake": "2401456661.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1zjzkk7l2jalrspy6500my8v0yy6ycz7el534zw", + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "starting_info": { + "previous_period": "3", + "stake": "562972916.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "starting_info": { + "previous_period": "5", + "stake": "2524305482.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "starting_info": { + "previous_period": "6", + "stake": "16993994.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "starting_info": { + "previous_period": "2", + "stake": "20291325837.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "starting_info": { + "previous_period": "5", + "stake": "15744595023.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "starting_info": { + "previous_period": "6", + "stake": "14549776414.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "starting_info": { + "previous_period": "8", + "stake": "4201547532.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "starting_info": { + "previous_period": "7", + "stake": "14577877248.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1znvq8jqpwxt5hk2lg5654l7eg7kap3rpgjm462", + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "starting_info": { + "previous_period": "6", + "stake": "13141132625.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "starting_info": { + "previous_period": "7", + "stake": "2041910728.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "starting_info": { + "previous_period": "3", + "stake": "1427892425.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "starting_info": { + "previous_period": "8", + "stake": "443348912.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", + "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "starting_info": { + "previous_period": "4", + "stake": "1866755172.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", + "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "starting_info": { + "previous_period": "5", + "stake": "2339204126.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", + "starting_info": { + "previous_period": "2", + "stake": "5951502740.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "starting_info": { + "previous_period": "5", + "stake": "4025204231.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1zu50umwgah6jhx07sw04ry0pv7fnvkpjmn8vl9", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "starting_info": { + "previous_period": "8", + "stake": "10178017385.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "starting_info": { + "previous_period": "9", + "stake": "18672701727.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "starting_info": { + "previous_period": "6", + "stake": "61795.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1cwk6x5smzaqhtrz95z0sf90d8a8d9vfrpaufnl", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "starting_info": { + "previous_period": "4", + "stake": "22113286739.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "starting_info": { + "previous_period": "7", + "stake": "90986838.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "starting_info": { + "previous_period": "2", + "stake": "927515526.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1rmyk79ktv6c8q48u78udw5p906fp0w058796d0", + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "starting_info": { + "previous_period": "8", + "stake": "251069497.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "starting_info": { + "previous_period": "4", + "stake": "8706091689.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "starting_info": { + "previous_period": "7", + "stake": "40296136.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1zah0g92ytwdvpchd3sceuanu7knhtu224vnt5k", + "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "starting_info": { + "previous_period": "3", + "stake": "17763934255.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "starting_info": { + "previous_period": "4", + "stake": "4748086.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1z7ruhrtfg8v2xv8egfyxldt2xaygspykszntzv", + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "starting_info": { + "previous_period": "1", + "stake": "984669335.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "starting_info": { + "previous_period": "3", + "stake": "641381462.000000000000000000", + "creation_height": "3" + } + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "starting_info": { + "previous_period": "2", + "stake": "11523735546.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", + "starting_info": { + "previous_period": "2", + "stake": "9436725725.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "starting_info": { + "previous_period": "4", + "stake": "652452.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "starting_info": { + "previous_period": "2", + "stake": "18814602669.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "starting_info": { + "previous_period": "3", + "stake": "1441730941.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "starting_info": { + "previous_period": "5", + "stake": "2341551967.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "starting_info": { + "previous_period": "4", + "stake": "38918270.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg", + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "starting_info": { + "previous_period": "3", + "stake": "10514537848.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "starting_info": { + "previous_period": "6", + "stake": "4946049715.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "starting_info": { + "previous_period": "5", + "stake": "11650293201.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "starting_info": { + "previous_period": "2", + "stake": "5810217010.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "starting_info": { + "previous_period": "3", + "stake": "260728313.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "starting_info": { + "previous_period": "4", + "stake": "5561406384.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "starting_info": { + "previous_period": "3", + "stake": "1721804886.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "starting_info": { + "previous_period": "2", + "stake": "4722611768.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "starting_info": { + "previous_period": "2", + "stake": "798486027.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "starting_info": { + "previous_period": "3", + "stake": "4660142050.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "starting_info": { + "previous_period": "4", + "stake": "2312465.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1rtw2ev4xm89vaqzwc7k520jlvrvlqnevk5f53y", + "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", + "starting_info": { + "previous_period": "1", + "stake": "12268746738.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", + "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "starting_info": { + "previous_period": "2", + "stake": "3185714296.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "starting_info": { + "previous_period": "3", + "stake": "18797742.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", + "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "starting_info": { + "previous_period": "4", + "stake": "1620479191.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", + "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "starting_info": { + "previous_period": "5", + "stake": "47693559541.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", + "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", + "starting_info": { + "previous_period": "5", + "stake": "12584124.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", + "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", + "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "starting_info": { + "previous_period": "2", + "stake": "1116365771.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "starting_info": { + "previous_period": "6", + "stake": "1246069516.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "starting_info": { + "previous_period": "7", + "stake": "686761769.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "starting_info": { + "previous_period": "3", + "stake": "2944397287.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "starting_info": { + "previous_period": "2", + "stake": "2830380125.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "starting_info": { + "previous_period": "5", + "stake": "8178830.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "starting_info": { + "previous_period": "2", + "stake": "11989838708.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", + "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "starting_info": { + "previous_period": "5", + "stake": "21856354084.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1r7kh63jvjhwqraux9wtm3jat8ggm437w9cxcxc", + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "starting_info": { + "previous_period": "1", + "stake": "1576771801.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "starting_info": { + "previous_period": "3", + "stake": "1096219390.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "starting_info": { + "previous_period": "5", + "stake": "9417801394.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "starting_info": { + "previous_period": "3", + "stake": "2560223943.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1rlzurkn0mywyldswcafhu7r8r0tha4s5prs34u", + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "starting_info": { + "previous_period": "1", + "stake": "5545092214.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1556dzhyv2gth4huxdlyur65c2sm3np2en3zzhl", + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "starting_info": { + "previous_period": "4", + "stake": "6217452551.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "starting_info": { + "previous_period": "3", + "stake": "1615518832.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "starting_info": { + "previous_period": "4", + "stake": "2449818489.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "starting_info": { + "previous_period": "6", + "stake": "106422691.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "starting_info": { + "previous_period": "5", + "stake": "508102761.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", + "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", + "starting_info": { + "previous_period": "2", + "stake": "5346735375.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933", + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "starting_info": { + "previous_period": "1", + "stake": "18217843326.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "starting_info": { + "previous_period": "2", + "stake": "187053499.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "starting_info": { + "previous_period": "3", + "stake": "6661497942.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", + "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "starting_info": { + "previous_period": "5", + "stake": "35129356.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", + "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "starting_info": { + "previous_period": "4", + "stake": "286435366.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1y3h72de80x06cz7fs3adwlnp0r8pjazw0r5707", + "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", + "starting_info": { + "previous_period": "1", + "stake": "3323388806.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1yj95f65syc75ptwcy0n7kafdq33awc2ve8hthq", + "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "starting_info": { + "previous_period": "3", + "stake": "313632363.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", + "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "starting_info": { + "previous_period": "4", + "stake": "127648169.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "starting_info": { + "previous_period": "7", + "stake": "1455198371.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "starting_info": { + "previous_period": "6", + "stake": "3978844161.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a", + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "starting_info": { + "previous_period": "4", + "stake": "5078782917.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "starting_info": { + "previous_period": "5", + "stake": "245003068.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "starting_info": { + "previous_period": "1", + "stake": "5608632459.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "starting_info": { + "previous_period": "3", + "stake": "402116649.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "starting_info": { + "previous_period": "2", + "stake": "7094821824.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "starting_info": { + "previous_period": "7", + "stake": "1727917227.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "starting_info": { + "previous_period": "6", + "stake": "4129974295.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "starting_info": { + "previous_period": "5", + "stake": "74047563.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "starting_info": { + "previous_period": "4", + "stake": "19129298483.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "starting_info": { + "previous_period": "5", + "stake": "20515760055.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "starting_info": { + "previous_period": "9", + "stake": "97785114.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "starting_info": { + "previous_period": "8", + "stake": "7055399052.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "starting_info": { + "previous_period": "7", + "stake": "23981371945.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "starting_info": { + "previous_period": "7", + "stake": "3140280772.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "starting_info": { + "previous_period": "4", + "stake": "12299732605.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "starting_info": { + "previous_period": "8", + "stake": "1993086195.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "starting_info": { + "previous_period": "9", + "stake": "1317573671.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1ylf26t6vhvugawg87328ng2ug4d8f25syxp64c", + "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "starting_info": { + "previous_period": "1", + "stake": "24248574347.000000000000000000", + "creation_height": "9" + } + }, + { + "delegator_address": "cosmos1q6eeennfulay5kz3lym38up6gq5ruf6h43cg94", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "starting_info": { + "previous_period": "9", + "stake": "17332637313.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "starting_info": { + "previous_period": "5", + "stake": "7050196605.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1easmlky76c302my07gffjxjw0a2usueaw8j46t", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "starting_info": { + "previous_period": "4", + "stake": "23176847255.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1m4xvwvq7qrr0wy0ryeu24eu8482h4n7en2x2mh", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "starting_info": { + "previous_period": "8", + "stake": "10673600913.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "starting_info": { + "previous_period": "10", + "stake": "24565420625.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", + "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "starting_info": { + "previous_period": "1", + "stake": "86630682.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "starting_info": { + "previous_period": "2", + "stake": "759535878.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "starting_info": { + "previous_period": "4", + "stake": "13382062777.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "starting_info": { + "previous_period": "5", + "stake": "562769066.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "starting_info": { + "previous_period": "3", + "stake": "3961673047.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "starting_info": { + "previous_period": "6", + "stake": "917167136.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "starting_info": { + "previous_period": "2", + "stake": "7332243055.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "starting_info": { + "previous_period": "7", + "stake": "61614117.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "starting_info": { + "previous_period": "5", + "stake": "1936045503.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "starting_info": { + "previous_period": "2", + "stake": "5053223393.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "starting_info": { + "previous_period": "3", + "stake": "23065486708.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "starting_info": { + "previous_period": "6", + "stake": "2186207273.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", + "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "starting_info": { + "previous_period": "3", + "stake": "2510854249.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "starting_info": { + "previous_period": "6", + "stake": "81292948.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", + "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", + "starting_info": { + "previous_period": "3", + "stake": "2439056961.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "starting_info": { + "previous_period": "2", + "stake": "2726229723.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "starting_info": { + "previous_period": "3", + "stake": "87813996.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "starting_info": { + "previous_period": "4", + "stake": "457491.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos19deqn6g9q7mnhzg5j0qr25k9gz74pwlph5p50r", + "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "starting_info": { + "previous_period": "1", + "stake": "2125901000.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", + "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "starting_info": { + "previous_period": "2", + "stake": "165098526.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1vuws77sz0xzvz8y0dg6wjz9fzd7plxpk29ljn7", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "starting_info": { + "previous_period": "8", + "stake": "1285996047.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "starting_info": { + "previous_period": "6", + "stake": "2012957230.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "starting_info": { + "previous_period": "4", + "stake": "3002359447.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos13ps0cszg8lqn0mkzndvhxwaew8yd56s8tl9j20", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "starting_info": { + "previous_period": "7", + "stake": "7351040665.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "starting_info": { + "previous_period": "10", + "stake": "14714606427.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "starting_info": { + "previous_period": "9", + "stake": "2696689996.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", + "starting_info": { + "previous_period": "6", + "stake": "290004202.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "starting_info": { + "previous_period": "2", + "stake": "14337017011.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos193pvwgxpxnd6tgz0gtyl00dq8r3ygeflnhaxpm", + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "starting_info": { + "previous_period": "3", + "stake": "7421590485.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "starting_info": { + "previous_period": "4", + "stake": "22489048481.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", + "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", + "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "starting_info": { + "previous_period": "3", + "stake": "2738776488.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75pf45v0", + "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", + "starting_info": { + "previous_period": "3", + "stake": "5061822.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1xq58llsgh49tsz22grs28jk0p7tvswlcjcrl32", + "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", + "starting_info": { + "previous_period": "1", + "stake": "2859472400.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "starting_info": { + "previous_period": "5", + "stake": "96280874.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "starting_info": { + "previous_period": "4", + "stake": "3736546194.000000000000000000", + "creation_height": "9" + } + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "starting_info": { + "previous_period": "6", + "stake": "155780036.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1xxurm2uymwd04sjxqedjae5r0zxhalh26skxct", + "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "starting_info": { + "previous_period": "1", + "stake": "8374503099.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "starting_info": { + "previous_period": "2", + "stake": "995278414.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalavv03x7", + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "starting_info": { + "previous_period": "4", + "stake": "41888452.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "starting_info": { + "previous_period": "5", + "stake": "909672651.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "starting_info": { + "previous_period": "6", + "stake": "322814192.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "starting_info": { + "previous_period": "2", + "stake": "1444898370.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "starting_info": { + "previous_period": "4", + "stake": "16141764494.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "starting_info": { + "previous_period": "3", + "stake": "163640358.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", + "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "starting_info": { + "previous_period": "2", + "stake": "2583372381.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "starting_info": { + "previous_period": "3", + "stake": "11868568217.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lpz963de", + "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "starting_info": { + "previous_period": "2", + "stake": "6669322099.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "starting_info": { + "previous_period": "5", + "stake": "185779104.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", + "starting_info": { + "previous_period": "3", + "stake": "1751100.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1py3htj8kmztj0ecdrhcgcmet6vupr9hvlhxkwe", + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "starting_info": { + "previous_period": "6", + "stake": "21846969213.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "starting_info": { + "previous_period": "4", + "stake": "15549849.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "starting_info": { + "previous_period": "5", + "stake": "282264887.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", + "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "starting_info": { + "previous_period": "4", + "stake": "7824280124.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", + "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "starting_info": { + "previous_period": "3", + "stake": "633536370.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", + "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", + "starting_info": { + "previous_period": "3", + "stake": "13735096388.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "starting_info": { + "previous_period": "3", + "stake": "1199565347.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je", + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "starting_info": { + "previous_period": "6", + "stake": "19109522.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "starting_info": { + "previous_period": "7", + "stake": "2713168340.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "starting_info": { + "previous_period": "7", + "stake": "88293788.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "starting_info": { + "previous_period": "10", + "stake": "526869097.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "starting_info": { + "previous_period": "11", + "stake": "9460610373.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", + "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "starting_info": { + "previous_period": "5", + "stake": "9032281.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", + "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "starting_info": { + "previous_period": "3", + "stake": "16205811760.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", + "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "starting_info": { + "previous_period": "3", + "stake": "4574405710.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", + "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "starting_info": { + "previous_period": "2", + "stake": "18778025755.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "starting_info": { + "previous_period": "8", + "stake": "3559099530.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "starting_info": { + "previous_period": "4", + "stake": "20147750165.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "starting_info": { + "previous_period": "6", + "stake": "9304209052.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "starting_info": { + "previous_period": "7", + "stake": "1682063162.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", + "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", + "starting_info": { + "previous_period": "1", + "stake": "1577104716.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "starting_info": { + "previous_period": "7", + "stake": "823335564.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "starting_info": { + "previous_period": "9", + "stake": "17266683.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "starting_info": { + "previous_period": "3", + "stake": "5370042726.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", + "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "starting_info": { + "previous_period": "1", + "stake": "81607574.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "starting_info": { + "previous_period": "2", + "stake": "254035.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "starting_info": { + "previous_period": "5", + "stake": "38719909925.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos188yd2umzwfwen7es68wrlh6auu3p8jhz0qfgej", + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "starting_info": { + "previous_period": "7", + "stake": "786295043.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "starting_info": { + "previous_period": "3", + "stake": "3315560612.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "starting_info": { + "previous_period": "6", + "stake": "137048444.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "starting_info": { + "previous_period": "3", + "stake": "183795109.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos18gmd4r8ydls55yvgda4d8pfandk0xem5q7eat8", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "starting_info": { + "previous_period": "6", + "stake": "19225895723.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "starting_info": { + "previous_period": "8", + "stake": "1356197798.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "starting_info": { + "previous_period": "7", + "stake": "967842562.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "starting_info": { + "previous_period": "5", + "stake": "916587.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos18fkw6s4hnj2llxljrkleetgns2y0h0vjg8kmef", + "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "starting_info": { + "previous_period": "1", + "stake": "29256610441.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos194x33ngarpaach5g69g60cd2pjq8h0hqkfvk35", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "starting_info": { + "previous_period": "7", + "stake": "2698972611.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "starting_info": { + "previous_period": "3", + "stake": "12146467079.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "starting_info": { + "previous_period": "6", + "stake": "15899234337.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "starting_info": { + "previous_period": "4", + "stake": "10949797827.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "starting_info": { + "previous_period": "5", + "stake": "23356660678.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "starting_info": { + "previous_period": "5", + "stake": "5080809691.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "starting_info": { + "previous_period": "2", + "stake": "4422731613.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "starting_info": { + "previous_period": "3", + "stake": "9393510961.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", + "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", + "starting_info": { + "previous_period": "4", + "stake": "859335658.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", + "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "starting_info": { + "previous_period": "5", + "stake": "40933654.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", + "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "starting_info": { + "previous_period": "6", + "stake": "179784223.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "starting_info": { + "previous_period": "8", + "stake": "233343713.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1ftj05w0hmw2xxw5p7gvr258j2824qd8r2xdk9e", + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "starting_info": { + "previous_period": "6", + "stake": "12407365569.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "starting_info": { + "previous_period": "4", + "stake": "352271656.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "starting_info": { + "previous_period": "7", + "stake": "39749190.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "starting_info": { + "previous_period": "3", + "stake": "8989585334.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "starting_info": { + "previous_period": "6", + "stake": "1418840382.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "starting_info": { + "previous_period": "4", + "stake": "585232700.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "starting_info": { + "previous_period": "5", + "stake": "312724720.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", + "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "starting_info": { + "previous_period": "3", + "stake": "2303096766.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", + "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "starting_info": { + "previous_period": "4", + "stake": "712016860.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "starting_info": { + "previous_period": "7", + "stake": "21228627.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "starting_info": { + "previous_period": "4", + "stake": "7720105335.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "starting_info": { + "previous_period": "6", + "stake": "2104208415.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "starting_info": { + "previous_period": "3", + "stake": "7682598.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "starting_info": { + "previous_period": "1", + "stake": "8365880246.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1864wj4twqatq54rrxl5jmfey55tmh0hvgmd9yw", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "starting_info": { + "previous_period": "5", + "stake": "423877981.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "starting_info": { + "previous_period": "3", + "stake": "1456184772.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "starting_info": { + "previous_period": "4", + "stake": "32924160.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "starting_info": { + "previous_period": "6", + "stake": "174754983.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv", + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "starting_info": { + "previous_period": "1", + "stake": "12717644032.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "starting_info": { + "previous_period": "2", + "stake": "20234365401.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "starting_info": { + "previous_period": "3", + "stake": "11937090067.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "starting_info": { + "previous_period": "6", + "stake": "139593046.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "starting_info": { + "previous_period": "7", + "stake": "2225212413.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "starting_info": { + "previous_period": "6", + "stake": "14461099488.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "starting_info": { + "previous_period": "8", + "stake": "785421895.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "starting_info": { + "previous_period": "4", + "stake": "17547096641.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "starting_info": { + "previous_period": "6", + "stake": "1294419142.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1g95xvy8qgzcvcl05fse0mpxzdfv3w88tpexycr", + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "starting_info": { + "previous_period": "7", + "stake": "2300967060.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "starting_info": { + "previous_period": "5", + "stake": "1829057.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "starting_info": { + "previous_period": "4", + "stake": "13950070710.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", + "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "starting_info": { + "previous_period": "4", + "stake": "2258309.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "starting_info": { + "previous_period": "4", + "stake": "2714965216.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", + "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", + "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", + "starting_info": { + "previous_period": "1", + "stake": "1252735315.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm", + "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", + "starting_info": { + "previous_period": "2", + "stake": "5701177554.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "starting_info": { + "previous_period": "3", + "stake": "17483443758.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "starting_info": { + "previous_period": "2", + "stake": "18762995915.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", + "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", + "starting_info": { + "previous_period": "2", + "stake": "4474063302.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", + "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", + "starting_info": { + "previous_period": "3", + "stake": "9095777401.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "starting_info": { + "previous_period": "8", + "stake": "12690053528.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "starting_info": { + "previous_period": "5", + "stake": "2399862586.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "starting_info": { + "previous_period": "6", + "stake": "1729736194.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "starting_info": { + "previous_period": "7", + "stake": "14815040085.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", + "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "starting_info": { + "previous_period": "4", + "stake": "8792247810.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", + "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "starting_info": { + "previous_period": "3", + "stake": "2968081872.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1gh67zgx4f9d64ctqhtascuh87805v8yffrfytl", + "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", + "starting_info": { + "previous_period": "3", + "stake": "602352708.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1gayzja3zz6unep8ftnpunt2wefazs3jhunl5az", + "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", + "starting_info": { + "previous_period": "2", + "stake": "4639932033.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", + "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", + "starting_info": { + "previous_period": "1", + "stake": "556310530.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "starting_info": { + "previous_period": "6", + "stake": "526885228.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "starting_info": { + "previous_period": "8", + "stake": "28000486.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "starting_info": { + "previous_period": "10", + "stake": "4300294602.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "starting_info": { + "previous_period": "11", + "stake": "2237914169.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "starting_info": { + "previous_period": "12", + "stake": "7482618743.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "starting_info": { + "previous_period": "9", + "stake": "8362968596.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1glku8mx4nzp5crkjt7px9lfe4flfge3zf64tud", + "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "starting_info": { + "previous_period": "2", + "stake": "16236700229.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "starting_info": { + "previous_period": "2", + "stake": "9950725535.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "starting_info": { + "previous_period": "9", + "stake": "6990856673.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "starting_info": { + "previous_period": "10", + "stake": "9220026.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "starting_info": { + "previous_period": "5", + "stake": "789297947.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "starting_info": { + "previous_period": "8", + "stake": "25069342080.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "starting_info": { + "previous_period": "7", + "stake": "127732919.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", + "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "starting_info": { + "previous_period": "1", + "stake": "1447202506.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos16jj80c7d94m772cn77zwcuhnqcl6y95kepxvja", + "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "starting_info": { + "previous_period": "2", + "stake": "3841134273.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2", + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "starting_info": { + "previous_period": "4", + "stake": "68061939.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "starting_info": { + "previous_period": "3", + "stake": "11773826677.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "starting_info": { + "previous_period": "5", + "stake": "6926527802.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1f2pvewnws73u0z5wsfmv5uqudwxl6jupfm6nta", + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "starting_info": { + "previous_period": "4", + "stake": "25069342080.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "starting_info": { + "previous_period": "3", + "stake": "7367311429.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "starting_info": { + "previous_period": "6", + "stake": "74135685.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "starting_info": { + "previous_period": "8", + "stake": "202358889.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "starting_info": { + "previous_period": "9", + "stake": "5068354349.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "starting_info": { + "previous_period": "10", + "stake": "6422847905.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "starting_info": { + "previous_period": "7", + "stake": "15967116837.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "starting_info": { + "previous_period": "3", + "stake": "852563445.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "starting_info": { + "previous_period": "1", + "stake": "209918859.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1f7utq63ae24m6aqw4metxjrc5q76j8h4gcgaxd", + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "starting_info": { + "previous_period": "4", + "stake": "23676093358.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "starting_info": { + "previous_period": "2", + "stake": "2867035102.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "starting_info": { + "previous_period": "5", + "stake": "200187880.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "starting_info": { + "previous_period": "6", + "stake": "61726947.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "starting_info": { + "previous_period": "4", + "stake": "11238205953.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "starting_info": { + "previous_period": "3", + "stake": "1627510175.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "starting_info": { + "previous_period": "3", + "stake": "335240579.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "starting_info": { + "previous_period": "4", + "stake": "4469703294.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "starting_info": { + "previous_period": "2", + "stake": "19618367974.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "starting_info": { + "previous_period": "3", + "stake": "24818709486.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "starting_info": { + "previous_period": "2", + "stake": "80752627.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "starting_info": { + "previous_period": "1", + "stake": "693338797.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "starting_info": { + "previous_period": "4", + "stake": "670350742.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "starting_info": { + "previous_period": "6", + "stake": "1116213901.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos160jtaz9c35nr7dx349ezfzvs3xfdzm3mlxgulk", + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "starting_info": { + "previous_period": "7", + "stake": "23889133768.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "starting_info": { + "previous_period": "5", + "stake": "23419734247.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "starting_info": { + "previous_period": "2", + "stake": "22035723908.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4", + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "starting_info": { + "previous_period": "3", + "stake": "885018304.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "starting_info": { + "previous_period": "4", + "stake": "4147746231.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", + "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", + "starting_info": { + "previous_period": "1", + "stake": "12112810368.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "starting_info": { + "previous_period": "6", + "stake": "2228638557.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1fc96780mrsxn5kgplhtna40qepjgrm9wsyly02", + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "starting_info": { + "previous_period": "3", + "stake": "15719680142.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "starting_info": { + "previous_period": "4", + "stake": "2711574997.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "starting_info": { + "previous_period": "4", + "stake": "37913276.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "starting_info": { + "previous_period": "2", + "stake": "9737598105.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "starting_info": { + "previous_period": "3", + "stake": "18799915325.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "starting_info": { + "previous_period": "11", + "stake": "2032334424.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "starting_info": { + "previous_period": "8", + "stake": "3326376911.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos12eynrdzx2jqz5u92hgmhl9ga6hmghqfv0xvns8", + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "starting_info": { + "previous_period": "10", + "stake": "2461085809.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "starting_info": { + "previous_period": "9", + "stake": "13348917907.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", + "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "starting_info": { + "previous_period": "2", + "stake": "10554411.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", + "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "starting_info": { + "previous_period": "3", + "stake": "1360036310.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos12q3w0j5hp023hdjafgc357hy7kkha296f4xrjf", + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "starting_info": { + "previous_period": "2", + "stake": "19013093201.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "starting_info": { + "previous_period": "3", + "stake": "1637026536.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "starting_info": { + "previous_period": "4", + "stake": "6724622674.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "starting_info": { + "previous_period": "6", + "stake": "397947789.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "starting_info": { + "previous_period": "7", + "stake": "20540852.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m", + "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", + "starting_info": { + "previous_period": "1", + "stake": "2878820932.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos12r0m6hwrnn0jy02tnhmk328d7p68x2rndzt0j5", + "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "starting_info": { + "previous_period": "1", + "stake": "9649353957.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "starting_info": { + "previous_period": "3", + "stake": "11280504984.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "starting_info": { + "previous_period": "6", + "stake": "1630410562.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "starting_info": { + "previous_period": "5", + "stake": "2714767582.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "starting_info": { + "previous_period": "5", + "stake": "11887809820.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "starting_info": { + "previous_period": "3", + "stake": "782001327.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "starting_info": { + "previous_period": "2", + "stake": "837111535.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "starting_info": { + "previous_period": "4", + "stake": "998573733.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", + "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "starting_info": { + "previous_period": "2", + "stake": "5637854002.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890", + "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "starting_info": { + "previous_period": "3", + "stake": "9648503235.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos12f4fpl936ld8c64dxqgwv65p42na8dcnv9g7ku", + "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "starting_info": { + "previous_period": "7", + "stake": "4840284805.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "starting_info": { + "previous_period": "8", + "stake": "145922218.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "starting_info": { + "previous_period": "5", + "stake": "11322194414.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1wtn9tf6wjwmwmddrk377cdl8fd96hexajyhfat", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "starting_info": { + "previous_period": "3", + "stake": "18471816853.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "starting_info": { + "previous_period": "4", + "stake": "9991492.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "starting_info": { + "previous_period": "2", + "stake": "15288776108.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", + "starting_info": { + "previous_period": "1", + "stake": "6943791722.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "starting_info": { + "previous_period": "5", + "stake": "19543436761.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "starting_info": { + "previous_period": "4", + "stake": "203058104.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "starting_info": { + "previous_period": "3", + "stake": "533098317.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "starting_info": { + "previous_period": "5", + "stake": "5090332.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "starting_info": { + "previous_period": "2", + "stake": "6087225472.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "starting_info": { + "previous_period": "4", + "stake": "111239871.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", + "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "starting_info": { + "previous_period": "4", + "stake": "2521177822.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "starting_info": { + "previous_period": "2", + "stake": "7038279055.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1tpxdvj93x9rqz89zhh0tszegcwtq8mgtdknrw5", + "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", + "starting_info": { + "previous_period": "1", + "stake": "13387012198.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1tzz5l8sw05e0tm5l0gxuvp04qt42stu3kqwf4s", + "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "starting_info": { + "previous_period": "1", + "stake": "7946485541.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "starting_info": { + "previous_period": "2", + "stake": "3084665544.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1tz087eh88lqkesr77yl6ys9dw95qysfqtff52a", + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "starting_info": { + "previous_period": "1", + "stake": "25027795872.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "starting_info": { + "previous_period": "2", + "stake": "2956537033.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1h84c3yuxd6k7950wh868tcsj5tmvzetykv8lld", + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "starting_info": { + "previous_period": "3", + "stake": "3599965031.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "starting_info": { + "previous_period": "7", + "stake": "1887976035.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "starting_info": { + "previous_period": "3", + "stake": "13987549940.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "starting_info": { + "previous_period": "5", + "stake": "277893955.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "starting_info": { + "previous_period": "2", + "stake": "5284614159.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "starting_info": { + "previous_period": "4", + "stake": "1330954959.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "starting_info": { + "previous_period": "8", + "stake": "100158705.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "starting_info": { + "previous_period": "7", + "stake": "9951710774.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "starting_info": { + "previous_period": "6", + "stake": "16439836386.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "starting_info": { + "previous_period": "5", + "stake": "264012997.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "starting_info": { + "previous_period": "4", + "stake": "3391706116.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "starting_info": { + "previous_period": "7", + "stake": "35571003.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1tgghhdcxdgxay7hp2p0lv2fs656c4c0xfzlga5", + "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", + "starting_info": { + "previous_period": "2", + "stake": "243264064.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "starting_info": { + "previous_period": "3", + "stake": "10725445.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "starting_info": { + "previous_period": "2", + "stake": "7078635448.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1tftatt0lp0v59qqf449pdqar8w3yj7n7xa7sk6", + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "starting_info": { + "previous_period": "1", + "stake": "9168014109.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "starting_info": { + "previous_period": "6", + "stake": "9132286197.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "starting_info": { + "previous_period": "9", + "stake": "9495710.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "starting_info": { + "previous_period": "8", + "stake": "459551216.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "starting_info": { + "previous_period": "7", + "stake": "4718627.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "starting_info": { + "previous_period": "5", + "stake": "3078912948.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "starting_info": { + "previous_period": "4", + "stake": "121624664.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "starting_info": { + "previous_period": "11", + "stake": "7210211965.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "starting_info": { + "previous_period": "6", + "stake": "20548231148.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "starting_info": { + "previous_period": "10", + "stake": "254473474.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1twu2lvgp3erk6gups2a8nae3jdahaj2xmlufsa", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "starting_info": { + "previous_period": "5", + "stake": "25069342080.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "starting_info": { + "previous_period": "7", + "stake": "9719656784.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", + "starting_info": { + "previous_period": "3", + "stake": "365167856.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", + "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "starting_info": { + "previous_period": "3", + "stake": "85878287.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", + "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "starting_info": { + "previous_period": "4", + "stake": "22429572439.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos18k4yz84xrjqvrq9u7sehvje3ax4aspcksauctw", + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "starting_info": { + "previous_period": "3", + "stake": "10553965715.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "starting_info": { + "previous_period": "4", + "stake": "18283793775.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "starting_info": { + "previous_period": "5", + "stake": "718921425.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "starting_info": { + "previous_period": "4", + "stake": "49181074.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "starting_info": { + "previous_period": "3", + "stake": "3111978.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "starting_info": { + "previous_period": "2", + "stake": "25069342080.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1z7sj5sg2cnkg4phzrswwjkkq8p2d6434pcyv2p", + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "starting_info": { + "previous_period": "4", + "stake": "404583402.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "starting_info": { + "previous_period": "6", + "stake": "6106439259.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "starting_info": { + "previous_period": "5", + "stake": "188596153.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "starting_info": { + "previous_period": "3", + "stake": "146683.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1tmddg4wjnj38wrd8t6xq092jyw3x4hcup6n00u", + "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", + "starting_info": { + "previous_period": "1", + "stake": "7029801264.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "starting_info": { + "previous_period": "5", + "stake": "138733335.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "starting_info": { + "previous_period": "6", + "stake": "22265567297.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "starting_info": { + "previous_period": "3", + "stake": "3540231870.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos174ycyhzg358nxm8r6qunzsyx48uk8fc404ckyf", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "starting_info": { + "previous_period": "4", + "stake": "8680187636.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", + "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "starting_info": { + "previous_period": "4", + "stake": "2948850137.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "starting_info": { + "previous_period": "5", + "stake": "143748684.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", + "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "starting_info": { + "previous_period": "1", + "stake": "35599530.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", + "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "starting_info": { + "previous_period": "2", + "stake": "9203549637.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1vqm5fdsflvnee33gk3d5pz7j6tf6dsp28eemcq", + "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "starting_info": { + "previous_period": "2", + "stake": "16949426508.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", + "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "starting_info": { + "previous_period": "1", + "stake": "731773122.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "starting_info": { + "previous_period": "2", + "stake": "5311127.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", + "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "starting_info": { + "previous_period": "7", + "stake": "4778613408.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "starting_info": { + "previous_period": "6", + "stake": "405352.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "starting_info": { + "previous_period": "5", + "stake": "11759488693.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "starting_info": { + "previous_period": "3", + "stake": "2555870064.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "starting_info": { + "previous_period": "4", + "stake": "1003510952.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "starting_info": { + "previous_period": "6", + "stake": "1792101072.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "starting_info": { + "previous_period": "8", + "stake": "3213489253.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", + "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "starting_info": { + "previous_period": "1", + "stake": "18158211957.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", + "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", + "starting_info": { + "previous_period": "2", + "stake": "1728294636.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", + "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "starting_info": { + "previous_period": "4", + "stake": "5071075450.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", + "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "starting_info": { + "previous_period": "3", + "stake": "9022206595.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "starting_info": { + "previous_period": "9", + "stake": "13283049905.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "starting_info": { + "previous_period": "5", + "stake": "175132304.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1dgzvesl67z96ttlt5ulga25phe8pnspt663dvr", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "starting_info": { + "previous_period": "11", + "stake": "7195021215.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "starting_info": { + "previous_period": "4", + "stake": "1781975477.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "starting_info": { + "previous_period": "10", + "stake": "870772585.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "starting_info": { + "previous_period": "7", + "stake": "2129694907.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "starting_info": { + "previous_period": "3", + "stake": "5799285.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", + "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "starting_info": { + "previous_period": "2", + "stake": "5221113247.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", + "starting_info": { + "previous_period": "2", + "stake": "10613605390.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "starting_info": { + "previous_period": "4", + "stake": "3423234396.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "starting_info": { + "previous_period": "3", + "stake": "11105705687.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "starting_info": { + "previous_period": "6", + "stake": "2244459128.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", + "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "starting_info": { + "previous_period": "2", + "stake": "17594927523.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "starting_info": { + "previous_period": "3", + "stake": "110749654.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "starting_info": { + "previous_period": "1", + "stake": "2769362709.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "starting_info": { + "previous_period": "3", + "stake": "9488989139.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "starting_info": { + "previous_period": "4", + "stake": "1612739646.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", + "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "starting_info": { + "previous_period": "2", + "stake": "1392479696.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", + "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", + "starting_info": { + "previous_period": "1", + "stake": "49835911.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpdhe28d", + "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "starting_info": { + "previous_period": "1", + "stake": "17862559018.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "starting_info": { + "previous_period": "4", + "stake": "23869776733.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "starting_info": { + "previous_period": "2", + "stake": "16096471780.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "starting_info": { + "previous_period": "3", + "stake": "23728387848.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "starting_info": { + "previous_period": "5", + "stake": "22288761371.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "starting_info": { + "previous_period": "6", + "stake": "1483865601.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcy522k3", + "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", + "starting_info": { + "previous_period": "4", + "stake": "1291312379.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "starting_info": { + "previous_period": "4", + "stake": "1085633282.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "starting_info": { + "previous_period": "5", + "stake": "5379750065.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1d5vv20893q06tx29mlqmefnyf0w3hn0v07w9p9", + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "starting_info": { + "previous_period": "2", + "stake": "186531063.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "starting_info": { + "previous_period": "2", + "stake": "463086222.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "starting_info": { + "previous_period": "3", + "stake": "8006017871.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "starting_info": { + "previous_period": "1", + "stake": "19056636038.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1vlvxlpzzrk5eye9c3z9uedk0085h7fdvehv32n", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "starting_info": { + "previous_period": "5", + "stake": "1749823283.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lypeadd", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "starting_info": { + "previous_period": "3", + "stake": "7137720854.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "starting_info": { + "previous_period": "6", + "stake": "454715151.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1etrkjjjjvuej87yu2pv4mcmhjsjqsn5hm9n043", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "starting_info": { + "previous_period": "4", + "stake": "23226246980.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", + "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "starting_info": { + "previous_period": "3", + "stake": "8566436836.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", + "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "starting_info": { + "previous_period": "2", + "stake": "11267665039.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "starting_info": { + "previous_period": "3", + "stake": "9627765333.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1f58nf9lzm4d5x9grnt3a3vd9c75szj95f6mm5s", + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "starting_info": { + "previous_period": "8", + "stake": "15007199497.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "starting_info": { + "previous_period": "4", + "stake": "61880678.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1j9vhccgf8520gtz7zn5jxj9lk3nqg0wx479kwp", + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "starting_info": { + "previous_period": "5", + "stake": "12478510598.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "starting_info": { + "previous_period": "4", + "stake": "13273588734.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos10p78pcqm2slk4x0pfxl9ht5spskwquhzptwzt8", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "starting_info": { + "previous_period": "8", + "stake": "3812433475.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "starting_info": { + "previous_period": "7", + "stake": "836513743.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "starting_info": { + "previous_period": "6", + "stake": "12642546664.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "starting_info": { + "previous_period": "3", + "stake": "6110815364.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "starting_info": { + "previous_period": "2", + "stake": "11780930912.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "starting_info": { + "previous_period": "4", + "stake": "2561447038.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", + "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", + "starting_info": { + "previous_period": "2", + "stake": "7094282971.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "starting_info": { + "previous_period": "5", + "stake": "5596804179.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q", + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "starting_info": { + "previous_period": "2", + "stake": "2844380010.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "starting_info": { + "previous_period": "4", + "stake": "425532255.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "starting_info": { + "previous_period": "5", + "stake": "4008660259.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "starting_info": { + "previous_period": "7", + "stake": "375360.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "starting_info": { + "previous_period": "2", + "stake": "18386606315.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "starting_info": { + "previous_period": "8", + "stake": "5093480749.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", + "starting_info": { + "previous_period": "1", + "stake": "1553435623.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "starting_info": { + "previous_period": "8", + "stake": "3332218539.999999999999999999", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "starting_info": { + "previous_period": "9", + "stake": "13894078.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "starting_info": { + "previous_period": "11", + "stake": "11237622542.152609809269746886", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "starting_info": { + "previous_period": "12", + "stake": "30520247.002489505486145750", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1sr6u63sxsprpzv7tedc7e88tn6elrxkjnucszy", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "starting_info": { + "previous_period": "10", + "stake": "31893143160.999999999999999999", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "starting_info": { + "previous_period": "3", + "stake": "6995636695.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "starting_info": { + "previous_period": "9", + "stake": "116762054.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "starting_info": { + "previous_period": "10", + "stake": "16324341322.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "starting_info": { + "previous_period": "11", + "stake": "2119723899.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos10qj9cj3dxecyu826gaw72ylwum96jkkh9p462q", + "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "starting_info": { + "previous_period": "2", + "stake": "7039255436.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", + "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "starting_info": { + "previous_period": "4", + "stake": "15044102286.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2", + "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", + "starting_info": { + "previous_period": "1", + "stake": "1606367134.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", + "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", + "starting_info": { + "previous_period": "3", + "stake": "229341851.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", + "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", + "starting_info": { + "previous_period": "2", + "stake": "5555958746.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "starting_info": { + "previous_period": "3", + "stake": "681974899.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos10gu52rf3d0z0py8d0x37r058qh9fgdgg5567wd", + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "starting_info": { + "previous_period": "5", + "stake": "466233357.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "starting_info": { + "previous_period": "2", + "stake": "545803690.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "starting_info": { + "previous_period": "3", + "stake": "152484301.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "starting_info": { + "previous_period": "5", + "stake": "2246266.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "starting_info": { + "previous_period": "9", + "stake": "2105667711.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "starting_info": { + "previous_period": "8", + "stake": "13307344592.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "starting_info": { + "previous_period": "6", + "stake": "10376224736.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "starting_info": { + "previous_period": "6", + "stake": "19236564.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "starting_info": { + "previous_period": "5", + "stake": "138442642.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos10d3vd6yx9k9ns6v82r4krm3d4ragw04cysm62c", + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "starting_info": { + "previous_period": "3", + "stake": "1365098704.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", + "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", + "starting_info": { + "previous_period": "2", + "stake": "48593531.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", + "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", + "starting_info": { + "previous_period": "4", + "stake": "955350854.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "starting_info": { + "previous_period": "3", + "stake": "2514756351.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "starting_info": { + "previous_period": "4", + "stake": "3468306722.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "starting_info": { + "previous_period": "1", + "stake": "3717256219.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", + "starting_info": { + "previous_period": "3", + "stake": "27773889.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", + "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "starting_info": { + "previous_period": "3", + "stake": "1609536341.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", + "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "starting_info": { + "previous_period": "2", + "stake": "23719777.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos124wz6pnykadgf3xchp6rdn9s2t9z5sgvl7597p", + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "starting_info": { + "previous_period": "4", + "stake": "6557300877.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "starting_info": { + "previous_period": "5", + "stake": "3300457502.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos10cl6sallgwf882apcyagjqa2lx4j8592cjw0gf", + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "starting_info": { + "previous_period": "2", + "stake": "1573970763.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "starting_info": { + "previous_period": "2", + "stake": "694971203.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "starting_info": { + "previous_period": "6", + "stake": "24356273620.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "starting_info": { + "previous_period": "5", + "stake": "276574162.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "starting_info": { + "previous_period": "3", + "stake": "18558143415.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "starting_info": { + "previous_period": "6", + "stake": "14241294624.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "starting_info": { + "previous_period": "7", + "stake": "1160822532.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "starting_info": { + "previous_period": "4", + "stake": "21882314874.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "starting_info": { + "previous_period": "5", + "stake": "9107793740.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "starting_info": { + "previous_period": "2", + "stake": "3452658290.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "starting_info": { + "previous_period": "6", + "stake": "952138064.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", + "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "starting_info": { + "previous_period": "4", + "stake": "6732042.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429", + "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "starting_info": { + "previous_period": "2", + "stake": "17931279589.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", + "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "starting_info": { + "previous_period": "5", + "stake": "1302147397.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp", + "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", + "starting_info": { + "previous_period": "1", + "stake": "1392995609.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", + "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "starting_info": { + "previous_period": "4", + "stake": "892316992.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1s34kukvsrdgap0pjh0alnql7vvv9m83m2628wd", + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "starting_info": { + "previous_period": "1", + "stake": "3141510059.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "starting_info": { + "previous_period": "4", + "stake": "189243223.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "starting_info": { + "previous_period": "2", + "stake": "3120662598.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "starting_info": { + "previous_period": "5", + "stake": "610981525.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "starting_info": { + "previous_period": "4", + "stake": "3355273089.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", + "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "starting_info": { + "previous_period": "2", + "stake": "5059370848.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1sjhhg2yl2cqszte7pjyrp6lx5tg383lrpjyq0m", + "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", + "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "starting_info": { + "previous_period": "3", + "stake": "8251101726.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "starting_info": { + "previous_period": "2", + "stake": "1517022388.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", + "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "starting_info": { + "previous_period": "3", + "stake": "1963736286.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj", + "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", + "starting_info": { + "previous_period": "1", + "stake": "6944508564.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "starting_info": { + "previous_period": "5", + "stake": "17756476456.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "starting_info": { + "previous_period": "6", + "stake": "1117197748.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "starting_info": { + "previous_period": "3", + "stake": "13458847467.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "starting_info": { + "previous_period": "4", + "stake": "5113128716.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "starting_info": { + "previous_period": "7", + "stake": "21648809872.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "starting_info": { + "previous_period": "6", + "stake": "40546790.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "starting_info": { + "previous_period": "5", + "stake": "226539767.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "starting_info": { + "previous_period": "4", + "stake": "2413926110.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "starting_info": { + "previous_period": "4", + "stake": "735588360.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "starting_info": { + "previous_period": "7", + "stake": "419006947.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "starting_info": { + "previous_period": "6", + "stake": "109318647.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "starting_info": { + "previous_period": "2", + "stake": "114707626.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "starting_info": { + "previous_period": "4", + "stake": "2534638254.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos13yzpngckxvtky2k25j60qxlkekx0jfau4pjhzn", + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", + "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "starting_info": { + "previous_period": "4", + "stake": "30094589894.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos13y2zjpgaj07umx7a3dsg9ffhpkk22g73492l53", + "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "starting_info": { + "previous_period": "3", + "stake": "3677892381.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", + "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", + "starting_info": { + "previous_period": "3", + "stake": "1975544514.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", + "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", + "starting_info": { + "previous_period": "2", + "stake": "1089374285.000000000000000000", + "creation_height": "9" + } + }, + { + "delegator_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", + "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "starting_info": { + "previous_period": "2", + "stake": "9334974491.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "starting_info": { + "previous_period": "3", + "stake": "15252711477.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "starting_info": { + "previous_period": "5", + "stake": "7622442762.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "starting_info": { + "previous_period": "3", + "stake": "8429625072.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "starting_info": { + "previous_period": "4", + "stake": "17690207109.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "starting_info": { + "previous_period": "6", + "stake": "3420827405.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", + "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "starting_info": { + "previous_period": "3", + "stake": "3084993241.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", + "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "starting_info": { + "previous_period": "5", + "stake": "22863613869.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "starting_info": { + "previous_period": "8", + "stake": "4124499225.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "starting_info": { + "previous_period": "5", + "stake": "3680624756.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "starting_info": { + "previous_period": "4", + "stake": "10621822118.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "starting_info": { + "previous_period": "2", + "stake": "12794497617.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "starting_info": { + "previous_period": "4", + "stake": "3123465186.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "starting_info": { + "previous_period": "5", + "stake": "856982353.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "starting_info": { + "previous_period": "5", + "stake": "2071677267.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", + "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "starting_info": { + "previous_period": "4", + "stake": "9842289918.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "starting_info": { + "previous_period": "2", + "stake": "2061374262.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", + "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "starting_info": { + "previous_period": "5", + "stake": "2914482410.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "starting_info": { + "previous_period": "3", + "stake": "16529399133.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "starting_info": { + "previous_period": "2", + "stake": "12748204456.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "starting_info": { + "previous_period": "4", + "stake": "2878563531.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "starting_info": { + "previous_period": "1", + "stake": "16792228457.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "starting_info": { + "previous_period": "5", + "stake": "15964121.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "starting_info": { + "previous_period": "6", + "stake": "3169550.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "starting_info": { + "previous_period": "6", + "stake": "638979230.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1w69f6s0dqsqfqq93hczddadwgeq86zr9dfmddq", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "starting_info": { + "previous_period": "3", + "stake": "751916830.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "starting_info": { + "previous_period": "2", + "stake": "14446066.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "starting_info": { + "previous_period": "5", + "stake": "8539175078.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos13nemj0k45u4pflkfeyey88n8u8sv4wgz8cf253", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "starting_info": { + "previous_period": "4", + "stake": "9595922807.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", + "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "starting_info": { + "previous_period": "6", + "stake": "7012397.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "starting_info": { + "previous_period": "5", + "stake": "19594820.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "starting_info": { + "previous_period": "2", + "stake": "11687279303.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "starting_info": { + "previous_period": "3", + "stake": "7174712260.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos13cydnwjmscxtqtjywk9atr9uwlm6703mwtycnr", + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "starting_info": { + "previous_period": "1", + "stake": "14396315468.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "starting_info": { + "previous_period": "5", + "stake": "730434945.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "starting_info": { + "previous_period": "2", + "stake": "14322672203.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "starting_info": { + "previous_period": "3", + "stake": "1420797965.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "starting_info": { + "previous_period": "3", + "stake": "1056544107.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "starting_info": { + "previous_period": "2", + "stake": "22343112357.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "starting_info": { + "previous_period": "6", + "stake": "9519082012.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "starting_info": { + "previous_period": "5", + "stake": "3855652978.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1pca5ng2s37clfh72ea806j9fwvpng4fjq3ey5s", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "starting_info": { + "previous_period": "3", + "stake": "15497814344.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "starting_info": { + "previous_period": "5", + "stake": "190512146.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "starting_info": { + "previous_period": "1", + "stake": "345074496.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "starting_info": { + "previous_period": "4", + "stake": "18480450616.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "starting_info": { + "previous_period": "6", + "stake": "1523447464.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", + "starting_info": { + "previous_period": "3", + "stake": "12315828943.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", + "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", + "starting_info": { + "previous_period": "4", + "stake": "3222725.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "starting_info": { + "previous_period": "8", + "stake": "1580119322.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "starting_info": { + "previous_period": "7", + "stake": "117761745.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "starting_info": { + "previous_period": "3", + "stake": "6237005399.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "starting_info": { + "previous_period": "2", + "stake": "7709220756.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1jsd99e3zfrxrr3nh057u0tvmu0847zkr29f28v", + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "starting_info": { + "previous_period": "3", + "stake": "428070399.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1wwp7j40k9xffj757s4uurkcegskfwq25ef268l", + "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "starting_info": { + "previous_period": "2", + "stake": "584304640.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr", + "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "starting_info": { + "previous_period": "1", + "stake": "4524948359.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0ajhqc7", + "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "starting_info": { + "previous_period": "2", + "stake": "22529203230.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", + "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "starting_info": { + "previous_period": "3", + "stake": "5038451854.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", + "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "starting_info": { + "previous_period": "2", + "stake": "1443592024.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa", + "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "starting_info": { + "previous_period": "3", + "stake": "4681170917.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "starting_info": { + "previous_period": "4", + "stake": "2172957336.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "starting_info": { + "previous_period": "2", + "stake": "3427543323.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxx7jqef", + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "starting_info": { + "previous_period": "1", + "stake": "2320422648.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "starting_info": { + "previous_period": "3", + "stake": "543089195.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", + "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck", + "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "starting_info": { + "previous_period": "2", + "stake": "2602618529.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", + "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", + "starting_info": { + "previous_period": "1", + "stake": "1864943427.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", + "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "starting_info": { + "previous_period": "2", + "stake": "25069342080.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "starting_info": { + "previous_period": "6", + "stake": "3502640543.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1wdm9ge7hjzrlh2epwtwu3nsunfd2r7alqhc7r2", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "starting_info": { + "previous_period": "4", + "stake": "24303271333.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1nrugh7am9s584k6qlf5nxlpetarxs2csglt46w", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "starting_info": { + "previous_period": "3", + "stake": "4938829215.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "starting_info": { + "previous_period": "2", + "stake": "13576729605.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1a5fndlfnwtvyzzt7ql4kvuqgnjut7ua7hkfts6", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "starting_info": { + "previous_period": "5", + "stake": "9415626255.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", + "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "starting_info": { + "previous_period": "2", + "stake": "33054734644.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1r6j2xkpnnjve9c00c854laqp7l7zv8pxeksxrz", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "starting_info": { + "previous_period": "4", + "stake": "20554160964.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "starting_info": { + "previous_period": "5", + "stake": "24771629701.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "starting_info": { + "previous_period": "6", + "stake": "324745845.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1n9dqelmmf5kfysk24m6chqfdcgz6r75u7mpuwh", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "starting_info": { + "previous_period": "3", + "stake": "7881585438.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", + "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "starting_info": { + "previous_period": "2", + "stake": "3033965094.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", + "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "starting_info": { + "previous_period": "3", + "stake": "15056247725.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1zsspke0nqudcl0lh747ppqcsy396245akc2vtl", + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "starting_info": { + "previous_period": "7", + "stake": "28973013721.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "starting_info": { + "previous_period": "6", + "stake": "2427273583.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "starting_info": { + "previous_period": "8", + "stake": "2567851891.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "starting_info": { + "previous_period": "5", + "stake": "401941426.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", + "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "starting_info": { + "previous_period": "4", + "stake": "19455408606.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "starting_info": { + "previous_period": "6", + "stake": "12287749425.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "starting_info": { + "previous_period": "10", + "stake": "9559582899.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "starting_info": { + "previous_period": "7", + "stake": "302642185.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "starting_info": { + "previous_period": "9", + "stake": "1576940428.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "starting_info": { + "previous_period": "3", + "stake": "1338628253.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1vwja3gc3e37f8fkddj38gp74cs7sccnf4zs509", + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "starting_info": { + "previous_period": "4", + "stake": "2070243017.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1ng5m6spxngyne4qzce35fdg0whl0yqgv9lg9tt", + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "starting_info": { + "previous_period": "1", + "stake": "13107417049.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "starting_info": { + "previous_period": "6", + "stake": "680611809.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "starting_info": { + "previous_period": "3", + "stake": "3507629422.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "starting_info": { + "previous_period": "2", + "stake": "25069342080.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "starting_info": { + "previous_period": "5", + "stake": "13388065636.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "starting_info": { + "previous_period": "7", + "stake": "2364587435.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "starting_info": { + "previous_period": "5", + "stake": "1439734010.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1d0dq8hxzyywrcx73v4z44e8p8685znzml58dg2", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "starting_info": { + "previous_period": "6", + "stake": "23089372229.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "starting_info": { + "previous_period": "2", + "stake": "1981740603.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "starting_info": { + "previous_period": "7", + "stake": "158733361.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "starting_info": { + "previous_period": "3", + "stake": "441014433.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "starting_info": { + "previous_period": "4", + "stake": "2588611065.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "starting_info": { + "previous_period": "5", + "stake": "254829181.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "starting_info": { + "previous_period": "4", + "stake": "19691201.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "starting_info": { + "previous_period": "3", + "stake": "1340954232.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "starting_info": { + "previous_period": "8", + "stake": "2311637.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "starting_info": { + "previous_period": "10", + "stake": "52419.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "starting_info": { + "previous_period": "3", + "stake": "43687807.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "starting_info": { + "previous_period": "4", + "stake": "213312801.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1n3lnhxzzm7ntheu78h6v4zag7zmrlp48tjnhf3", + "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "starting_info": { + "previous_period": "2", + "stake": "9794461587.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", + "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "starting_info": { + "previous_period": "3", + "stake": "449732008.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", + "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "starting_info": { + "previous_period": "6", + "stake": "10162772165.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "starting_info": { + "previous_period": "5", + "stake": "12613411.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "starting_info": { + "previous_period": "4", + "stake": "3145157664.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "starting_info": { + "previous_period": "5", + "stake": "2905348435.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "starting_info": { + "previous_period": "2", + "stake": "12269775869.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "starting_info": { + "previous_period": "6", + "stake": "5136199330.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "starting_info": { + "previous_period": "3", + "stake": "19279146842.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "starting_info": { + "previous_period": "7", + "stake": "24652299.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "starting_info": { + "previous_period": "8", + "stake": "43994659.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "starting_info": { + "previous_period": "10", + "stake": "18869340.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", + "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", + "starting_info": { + "previous_period": "4", + "stake": "14531672001.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "starting_info": { + "previous_period": "4", + "stake": "3922123176.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "starting_info": { + "previous_period": "1", + "stake": "17245824357.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "starting_info": { + "previous_period": "3", + "stake": "126388593.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos14hr55k3es7xfc54gwgu3plde0vaxkgerljee6v", + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "starting_info": { + "previous_period": "2", + "stake": "20670117972.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", + "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", + "starting_info": { + "previous_period": "2", + "stake": "981657888.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", + "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", + "starting_info": { + "previous_period": "3", + "stake": "15174649749.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", + "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "starting_info": { + "previous_period": "3", + "stake": "52804172.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "starting_info": { + "previous_period": "4", + "stake": "60608473.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos15pl2c2umxszwar75aft99kns0ltmpepnnpt9y0", + "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", + "starting_info": { + "previous_period": "2", + "stake": "11726853019.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", + "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "starting_info": { + "previous_period": "3", + "stake": "3607007415.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos15zqzxj663h8g8naxyz324j2rpd3rnw4rvtxep2", + "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "starting_info": { + "previous_period": "2", + "stake": "25069342080.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "starting_info": { + "previous_period": "8", + "stake": "3139002667.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "starting_info": { + "previous_period": "5", + "stake": "2095412424.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "starting_info": { + "previous_period": "10", + "stake": "5904983738.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "starting_info": { + "previous_period": "3", + "stake": "2615326319.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", + "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", + "starting_info": { + "previous_period": "1", + "stake": "11868660651.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "starting_info": { + "previous_period": "5", + "stake": "12945220697.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "starting_info": { + "previous_period": "7", + "stake": "548629134.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "starting_info": { + "previous_period": "6", + "stake": "700270403.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "starting_info": { + "previous_period": "6", + "stake": "11335873807.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "starting_info": { + "previous_period": "5", + "stake": "10343736976.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "starting_info": { + "previous_period": "4", + "stake": "12895342060.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos15tv54z32xgqechywvr7ymsfdvr2mmx3553j8rd", + "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", + "starting_info": { + "previous_period": "1", + "stake": "10646429954.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", + "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "starting_info": { + "previous_period": "4", + "stake": "4258157.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos15vf60ssrdq6fh9ln5a9wtd6f3q64sktl6vk2ss", + "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "starting_info": { + "previous_period": "3", + "stake": "502656802.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "starting_info": { + "previous_period": "4", + "stake": "927934611.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "starting_info": { + "previous_period": "3", + "stake": "2830795600.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "starting_info": { + "previous_period": "1", + "stake": "974110958.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "starting_info": { + "previous_period": "6", + "stake": "2095470160.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "starting_info": { + "previous_period": "3", + "stake": "842733222.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "starting_info": { + "previous_period": "4", + "stake": "14053872866.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "starting_info": { + "previous_period": "4", + "stake": "240453816.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1wvzq2f252674u3gvmqhnq8g4n6lmxedmzs0czm", + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "starting_info": { + "previous_period": "3", + "stake": "2584616241.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "starting_info": { + "previous_period": "2", + "stake": "2930417970.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", + "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "starting_info": { + "previous_period": "2", + "stake": "5685279942.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", + "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "starting_info": { + "previous_period": "6", + "stake": "1049818729.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", + "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "starting_info": { + "previous_period": "5", + "stake": "1062187041.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1rlltvm5ks32kh683c0w7epsjvg8aq2hvct27p6", + "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "starting_info": { + "previous_period": "5", + "stake": "71917474.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", + "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "starting_info": { + "previous_period": "4", + "stake": "568146686.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", + "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "starting_info": { + "previous_period": "2", + "stake": "10013094355.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", + "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "starting_info": { + "previous_period": "3", + "stake": "16248624224.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "starting_info": { + "previous_period": "2", + "stake": "24554814193.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "starting_info": { + "previous_period": "5", + "stake": "19978115021.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "starting_info": { + "previous_period": "3", + "stake": "986773968.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "starting_info": { + "previous_period": "4", + "stake": "607901853.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "starting_info": { + "previous_period": "5", + "stake": "1561395724.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "starting_info": { + "previous_period": "3", + "stake": "16358237418.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "starting_info": { + "previous_period": "7", + "stake": "1677820405.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "starting_info": { + "previous_period": "6", + "stake": "2652495105.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "starting_info": { + "previous_period": "2", + "stake": "35850249.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos15cfduq92j3uvam8u942xj4egs42tjzl6p33fu5", + "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "starting_info": { + "previous_period": "1", + "stake": "14156647.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "starting_info": { + "previous_period": "11", + "stake": "12679288910.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1d9m3l8khcrx0zhftehkuw67zzszf9v9le5dvrm", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "starting_info": { + "previous_period": "9", + "stake": "20382465534.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "starting_info": { + "previous_period": "10", + "stake": "731129230.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "starting_info": { + "previous_period": "6", + "stake": "2205728211.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "starting_info": { + "previous_period": "8", + "stake": "3421255938.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "starting_info": { + "previous_period": "7", + "stake": "140255592.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos15uqsf4wke3ylyp0elnka2rvaefhsmhgjhe5mxf", + "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", + "starting_info": { + "previous_period": "1", + "stake": "8741308900.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "starting_info": { + "previous_period": "6", + "stake": "241691384.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "starting_info": { + "previous_period": "4", + "stake": "14533440365.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "starting_info": { + "previous_period": "3", + "stake": "24026548.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", + "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "starting_info": { + "previous_period": "2", + "stake": "16363250391.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "starting_info": { + "previous_period": "3", + "stake": "57475597.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "starting_info": { + "previous_period": "7", + "stake": "1886627332.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "starting_info": { + "previous_period": "8", + "stake": "5720739029.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "starting_info": { + "previous_period": "9", + "stake": "3371357709.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "starting_info": { + "previous_period": "4", + "stake": "7165994372.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "starting_info": { + "previous_period": "5", + "stake": "7918208867.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "starting_info": { + "previous_period": "3", + "stake": "9192729008.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "starting_info": { + "previous_period": "5", + "stake": "2272430680.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "starting_info": { + "previous_period": "4", + "stake": "7778508961.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "starting_info": { + "previous_period": "2", + "stake": "95191076.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos14q9rupnazu0mmkjd9skpn2zdfs8d0hlghzpk0v", + "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", + "starting_info": { + "previous_period": "5", + "stake": "492237770.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "starting_info": { + "previous_period": "2", + "stake": "16977263624.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", + "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "starting_info": { + "previous_period": "3", + "stake": "8106199.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", + "starting_info": { + "previous_period": "6", + "stake": "125301.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", + "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "starting_info": { + "previous_period": "1", + "stake": "18994769458.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1haw8fcay84fjlsdl5cyev275ldj30z3r27m0g5", + "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "starting_info": { + "previous_period": "2", + "stake": "6372741624.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "starting_info": { + "previous_period": "4", + "stake": "21529013972.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "starting_info": { + "previous_period": "3", + "stake": "7193234568.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos14j4mehgc448s2m7cr0uqm3pmvjxav94wmq80w4", + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "starting_info": { + "previous_period": "5", + "stake": "1110360222.000000000000000000", + "creation_height": "9" + } + }, + { + "delegator_address": "cosmos1yrdtzqfkyum94q4v3j3xllrtf09qv0jvympw86", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "starting_info": { + "previous_period": "6", + "stake": "3161698569.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "starting_info": { + "previous_period": "7", + "stake": "269676102.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "starting_info": { + "previous_period": "4", + "stake": "1854783297.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "starting_info": { + "previous_period": "5", + "stake": "1682096242.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "starting_info": { + "previous_period": "8", + "stake": "6656587767.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "starting_info": { + "previous_period": "4", + "stake": "13034888858.653846147589407194", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "starting_info": { + "previous_period": "7", + "stake": "52986923.031037243011576594", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "starting_info": { + "previous_period": "3", + "stake": "2286530039.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", + "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", + "starting_info": { + "previous_period": "2", + "stake": "3041120922.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "starting_info": { + "previous_period": "2", + "stake": "23007967818.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "starting_info": { + "previous_period": "4", + "stake": "2921862659.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "starting_info": { + "previous_period": "3", + "stake": "5446202786.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "starting_info": { + "previous_period": "5", + "stake": "1681443586.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "starting_info": { + "previous_period": "2", + "stake": "5993132567.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "starting_info": { + "previous_period": "5", + "stake": "7303977754.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "starting_info": { + "previous_period": "4", + "stake": "821774041.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos14urapj7e6tj2s8clcsgyat6xmkppj7nm4qtewf", + "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", + "starting_info": { + "previous_period": "2", + "stake": "5480500900.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "starting_info": { + "previous_period": "3", + "stake": "9687342330.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz", + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "starting_info": { + "previous_period": "2", + "stake": "16734096385.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "starting_info": { + "previous_period": "4", + "stake": "843834482.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos147pq4rzswl76kdeyx8sc7pagf4nhjpnq2hlrh3", + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "starting_info": { + "previous_period": "1", + "stake": "22417960991.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "starting_info": { + "previous_period": "3", + "stake": "8142048495.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1478sx3zdfylsts5sus5rlz4dgvyvacqpuchj6f", + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "starting_info": { + "previous_period": "4", + "stake": "1078037731.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "starting_info": { + "previous_period": "4", + "stake": "3439625151.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", + "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "starting_info": { + "previous_period": "2", + "stake": "10941491018.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "starting_info": { + "previous_period": "6", + "stake": "26325596.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "starting_info": { + "previous_period": "8", + "stake": "11344768409.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "starting_info": { + "previous_period": "7", + "stake": "5083047390.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1kz20p7j939s8cqadmqqws80c6z93qdtyg8xt0v", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "starting_info": { + "previous_period": "4", + "stake": "9782915598.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos17ph7nmvmxdhm687z4k5phsyd08wvsnv44emkj8", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "starting_info": { + "previous_period": "9", + "stake": "3648941591.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1kxl7gsad663he7lgn66wx6gr3egnfj85dt22pv", + "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", + "starting_info": { + "previous_period": "1", + "stake": "2533410912.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1kfnt5d5fcma9kh4c5jk85yu75jer72kwdltg4s", + "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "starting_info": { + "previous_period": "1", + "stake": "21181468286.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", + "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "starting_info": { + "previous_period": "7", + "stake": "607985470.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", + "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "starting_info": { + "previous_period": "6", + "stake": "13186298825.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "starting_info": { + "previous_period": "8", + "stake": "5071553218.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "starting_info": { + "previous_period": "4", + "stake": "16667182589.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "starting_info": { + "previous_period": "7", + "stake": "17602930321.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "starting_info": { + "previous_period": "3", + "stake": "89280204.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "starting_info": { + "previous_period": "4", + "stake": "3814662227.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "starting_info": { + "previous_period": "3", + "stake": "3444033677.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2", + "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "starting_info": { + "previous_period": "1", + "stake": "9571086511.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", + "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "starting_info": { + "previous_period": "2", + "stake": "69406130.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", + "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "starting_info": { + "previous_period": "6", + "stake": "9033381920.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", + "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "starting_info": { + "previous_period": "5", + "stake": "6780481465.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", + "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "starting_info": { + "previous_period": "4", + "stake": "22548164258.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "starting_info": { + "previous_period": "3", + "stake": "3409616214.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", + "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "starting_info": { + "previous_period": "2", + "stake": "166860.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "starting_info": { + "previous_period": "3", + "stake": "64540087.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1kjupa2w6rlhzj9fjxz35m02g2wpz790fd6mf0j", + "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "starting_info": { + "previous_period": "4", + "stake": "11188036452.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "starting_info": { + "previous_period": "3", + "stake": "986856358.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", + "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "starting_info": { + "previous_period": "5", + "stake": "4660200511.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", + "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "starting_info": { + "previous_period": "2", + "stake": "6269426755.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1kmly2aspt8rk9h4ukdt8h52k24alvc34qukp2n", + "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "starting_info": { + "previous_period": "1", + "stake": "9031700237.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "starting_info": { + "previous_period": "2", + "stake": "20581321.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", + "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "starting_info": { + "previous_period": "2", + "stake": "157509894.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", + "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "starting_info": { + "previous_period": "1", + "stake": "199824149.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "starting_info": { + "previous_period": "7", + "stake": "9843285414.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "starting_info": { + "previous_period": "5", + "stake": "995636217.000000000000000000", + "creation_height": "9" + } + }, + { + "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "starting_info": { + "previous_period": "6", + "stake": "5575140.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "starting_info": { + "previous_period": "3", + "stake": "15608731707.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "starting_info": { + "previous_period": "2", + "stake": "18830990390.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "starting_info": { + "previous_period": "6", + "stake": "20636678155.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "starting_info": { + "previous_period": "7", + "stake": "3535960309.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos130kk7kw4kx7rfrq9sa4k673zqt3nf6s4l3a0lg", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "starting_info": { + "previous_period": "4", + "stake": "5241869268.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "starting_info": { + "previous_period": "3", + "stake": "14982594771.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "starting_info": { + "previous_period": "5", + "stake": "108025410.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1gwwltgyatg8yfe54447dxnyvs2nt6xxsl6lv2m", + "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "starting_info": { + "previous_period": "2", + "stake": "21998779909.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", + "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "starting_info": { + "previous_period": "1", + "stake": "457781724.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "starting_info": { + "previous_period": "3", + "stake": "4659214363.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "starting_info": { + "previous_period": "9", + "stake": "3878595385.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "starting_info": { + "previous_period": "6", + "stake": "2235582679.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "starting_info": { + "previous_period": "5", + "stake": "361851785.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "starting_info": { + "previous_period": "8", + "stake": "466196437.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "starting_info": { + "previous_period": "6", + "stake": "150189421.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "starting_info": { + "previous_period": "5", + "stake": "3484578053.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "starting_info": { + "previous_period": "9", + "stake": "5669282913.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "starting_info": { + "previous_period": "8", + "stake": "2095189904.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", + "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "starting_info": { + "previous_period": "2", + "stake": "2600875484.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe", + "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "starting_info": { + "previous_period": "1", + "stake": "4203532933.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1hxdqddf3u8vjm080ytpe959uktn4axdas3uqhl", + "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "starting_info": { + "previous_period": "1", + "stake": "13179632835.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", + "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "starting_info": { + "previous_period": "2", + "stake": "663734465.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", + "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", + "starting_info": { + "previous_period": "4", + "stake": "23136285.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "starting_info": { + "previous_period": "6", + "stake": "821954529.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "starting_info": { + "previous_period": "2", + "stake": "16404106448.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos14m0pzuhkpjnx2esurz6kcxcjvlkcdzk7e43krz", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "starting_info": { + "previous_period": "8", + "stake": "2468850551.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "starting_info": { + "previous_period": "5", + "stake": "576145955.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "starting_info": { + "previous_period": "7", + "stake": "18772263304.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "starting_info": { + "previous_period": "4", + "stake": "6767814744.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", + "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "starting_info": { + "previous_period": "4", + "stake": "22058794240.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", + "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "starting_info": { + "previous_period": "5", + "stake": "2551565111.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "starting_info": { + "previous_period": "4", + "stake": "2744054731.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc", + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "starting_info": { + "previous_period": "3", + "stake": "2335097089.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "starting_info": { + "previous_period": "2", + "stake": "1408273393.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "starting_info": { + "previous_period": "4", + "stake": "510250360.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", + "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "starting_info": { + "previous_period": "3", + "stake": "1912310410.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", + "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", + "starting_info": { + "previous_period": "1", + "stake": "2108075856.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", + "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "starting_info": { + "previous_period": "5", + "stake": "4681593063.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "starting_info": { + "previous_period": "6", + "stake": "1987459876.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "starting_info": { + "previous_period": "4", + "stake": "6269261784.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq", + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "starting_info": { + "previous_period": "6", + "stake": "25069342080.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1mcc0dq93nrt3u6hl6ju82hyw3rdfun029jx4v2", + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "starting_info": { + "previous_period": "5", + "stake": "3120721396.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", + "starting_info": { + "previous_period": "4", + "stake": "927350399.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "starting_info": { + "previous_period": "6", + "stake": "1933530153.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "starting_info": { + "previous_period": "4", + "stake": "6858058479.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1h6j4lyvuenmz9m7vq3hler8j7pg5ldpet0xf9a", + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "starting_info": { + "previous_period": "2", + "stake": "25069342080.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "starting_info": { + "previous_period": "5", + "stake": "22087360379.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", + "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", + "starting_info": { + "previous_period": "1", + "stake": "4006205.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", + "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "starting_info": { + "previous_period": "2", + "stake": "15675831119.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "starting_info": { + "previous_period": "5", + "stake": "503691456.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "starting_info": { + "previous_period": "4", + "stake": "3295555517.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1jzhlspgxp578kzg9dtvg8tm2w9k7tnmcpstzry", + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "starting_info": { + "previous_period": "7", + "stake": "6425955236.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "starting_info": { + "previous_period": "6", + "stake": "2665221917.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj", + "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "starting_info": { + "previous_period": "3", + "stake": "4050355196.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "starting_info": { + "previous_period": "4", + "stake": "3002111009.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptd8zyma", + "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", + "starting_info": { + "previous_period": "1", + "stake": "8559089572.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "starting_info": { + "previous_period": "6", + "stake": "41624341.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "starting_info": { + "previous_period": "7", + "stake": "14654910305.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "starting_info": { + "previous_period": "5", + "stake": "20731656728.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "starting_info": { + "previous_period": "9", + "stake": "8305994215.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "starting_info": { + "previous_period": "8", + "stake": "1753289412.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "starting_info": { + "previous_period": "2", + "stake": "6709581679.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "starting_info": { + "previous_period": "5", + "stake": "2739638648.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "starting_info": { + "previous_period": "3", + "stake": "14812554077.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "starting_info": { + "previous_period": "3", + "stake": "16356624866.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "starting_info": { + "previous_period": "2", + "stake": "1616674805.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "starting_info": { + "previous_period": "4", + "stake": "13796856153.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "starting_info": { + "previous_period": "3", + "stake": "689756170.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "starting_info": { + "previous_period": "4", + "stake": "324333952.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "starting_info": { + "previous_period": "2", + "stake": "5261551412.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "starting_info": { + "previous_period": "2", + "stake": "2150744506.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", + "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "starting_info": { + "previous_period": "1", + "stake": "7924071421.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "starting_info": { + "previous_period": "4", + "stake": "900956465.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "starting_info": { + "previous_period": "1", + "stake": "36701249402.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq", + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "starting_info": { + "previous_period": "4", + "stake": "592539582.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "starting_info": { + "previous_period": "7", + "stake": "1112547.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "starting_info": { + "previous_period": "2", + "stake": "421593670.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "starting_info": { + "previous_period": "1", + "stake": "4250535918.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "starting_info": { + "previous_period": "3", + "stake": "2295367808.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", + "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", + "starting_info": { + "previous_period": "2", + "stake": "211016457.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6x000jc", + "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", + "starting_info": { + "previous_period": "1", + "stake": "1201306698.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "starting_info": { + "previous_period": "2", + "stake": "2196379282.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "starting_info": { + "previous_period": "3", + "stake": "721476141.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "starting_info": { + "previous_period": "1", + "stake": "249261878.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "starting_info": { + "previous_period": "7", + "stake": "2727283744.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "starting_info": { + "previous_period": "8", + "stake": "11015469214.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "starting_info": { + "previous_period": "2", + "stake": "23543464834.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "starting_info": { + "previous_period": "4", + "stake": "390088156.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "starting_info": { + "previous_period": "8", + "stake": "5780519.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "starting_info": { + "previous_period": "4", + "stake": "144959703.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "starting_info": { + "previous_period": "5", + "stake": "16883391832.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "starting_info": { + "previous_period": "9", + "stake": "9703623543.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "starting_info": { + "previous_period": "3", + "stake": "1320373881.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", + "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "starting_info": { + "previous_period": "4", + "stake": "2115827243.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", + "starting_info": { + "previous_period": "3", + "stake": "199636304.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1evqmj6ahqf76keas4ymhvf4r992kg7wrar0fru", + "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "starting_info": { + "previous_period": "3", + "stake": "3652777037.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos17tecr2sngjcm2rc29dzmadtpad2tkmrhj69whr", + "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "starting_info": { + "previous_period": "2", + "stake": "16752793632.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", + "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "starting_info": { + "previous_period": "4", + "stake": "6536333612.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", + "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "starting_info": { + "previous_period": "3", + "stake": "1119920089.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266", + "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", + "starting_info": { + "previous_period": "4", + "stake": "5987604552.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6", + "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", + "starting_info": { + "previous_period": "3", + "stake": "11089478639.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "starting_info": { + "previous_period": "8", + "stake": "6852395930.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "starting_info": { + "previous_period": "9", + "stake": "2649436634.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "starting_info": { + "previous_period": "6", + "stake": "372091968.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", + "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", + "starting_info": { + "previous_period": "1", + "stake": "247885300.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "starting_info": { + "previous_period": "3", + "stake": "32698264.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", + "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "starting_info": { + "previous_period": "4", + "stake": "25069342080.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", + "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "starting_info": { + "previous_period": "2", + "stake": "4365594275.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", + "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "starting_info": { + "previous_period": "1", + "stake": "13243911263.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", + "starting_info": { + "previous_period": "3", + "stake": "7847492642.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "starting_info": { + "previous_period": "2", + "stake": "178156456.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1em3y3h4g7n8ue3wjcramnpmz0x8rwakrpjmrgz", + "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "starting_info": { + "previous_period": "1", + "stake": "12071046098.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", + "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "starting_info": { + "previous_period": "5", + "stake": "6709144772.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", + "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "starting_info": { + "previous_period": "4", + "stake": "2778547888.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "starting_info": { + "previous_period": "6", + "stake": "924245075.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "starting_info": { + "previous_period": "5", + "stake": "4448687638.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "starting_info": { + "previous_period": "4", + "stake": "10677551922.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", + "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "starting_info": { + "previous_period": "2", + "stake": "19565632897.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "starting_info": { + "previous_period": "9", + "stake": "1958289106.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "starting_info": { + "previous_period": "5", + "stake": "2037145657.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "starting_info": { + "previous_period": "7", + "stake": "5402886314.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "starting_info": { + "previous_period": "6", + "stake": "17415142521.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "starting_info": { + "previous_period": "5", + "stake": "8106078214.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "starting_info": { + "previous_period": "4", + "stake": "19127653549.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "starting_info": { + "previous_period": "2", + "stake": "5174807457.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "starting_info": { + "previous_period": "7", + "stake": "863704883.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "starting_info": { + "previous_period": "5", + "stake": "3069213832.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "starting_info": { + "previous_period": "6", + "stake": "32603015.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", + "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "starting_info": { + "previous_period": "3", + "stake": "11830766683.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos16tr72kn90g5zl7qhyhuqkjflejz00uzlkl65sj", + "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "starting_info": { + "previous_period": "2", + "stake": "25069342080.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1vx0z58vgegsfc8e56jzmjtvj8cvprywvnm7l9j", + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "starting_info": { + "previous_period": "3", + "stake": "1076204485.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "starting_info": { + "previous_period": "2", + "stake": "4020804640.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos16v3h2mggt8tnkxp0vq5tq25fhr3knvf4jw40l5", + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "starting_info": { + "previous_period": "1", + "stake": "23883466891.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", + "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "starting_info": { + "previous_period": "4", + "stake": "8771546667.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "starting_info": { + "previous_period": "3", + "stake": "230136377.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n", + "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", + "starting_info": { + "previous_period": "1", + "stake": "13444158275.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", + "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", + "starting_info": { + "previous_period": "5", + "stake": "3562717063.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "starting_info": { + "previous_period": "5", + "stake": "13749317760.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "starting_info": { + "previous_period": "6", + "stake": "6458950379.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "starting_info": { + "previous_period": "9", + "stake": "3501192050.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "starting_info": { + "previous_period": "8", + "stake": "233651324.000000000000000000", + "creation_height": "10" + } + }, + { + "delegator_address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "starting_info": { + "previous_period": "7", + "stake": "3799625898.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", + "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "starting_info": { + "previous_period": "3", + "stake": "12266067.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1mzsvp23mjrjkspddkz6nta0x7kte6a23atg6ml", + "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "starting_info": { + "previous_period": "2", + "stake": "2228698398.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c", + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "starting_info": { + "previous_period": "5", + "stake": "1670822058.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "starting_info": { + "previous_period": "6", + "stake": "3804293134.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "starting_info": { + "previous_period": "2", + "stake": "11902636114.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", + "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", + "starting_info": { + "previous_period": "2", + "stake": "965626724.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7", + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "starting_info": { + "previous_period": "7", + "stake": "1694198126.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "starting_info": { + "previous_period": "4", + "stake": "22330517668.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "starting_info": { + "previous_period": "6", + "stake": "1407135534.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", + "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", + "starting_info": { + "previous_period": "1", + "stake": "2479274676.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", + "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", + "starting_info": { + "previous_period": "1", + "stake": "4394402323.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "starting_info": { + "previous_period": "10", + "stake": "8361945358.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "starting_info": { + "previous_period": "5", + "stake": "21819398696.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "starting_info": { + "previous_period": "7", + "stake": "614084859.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "starting_info": { + "previous_period": "9", + "stake": "590997851.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "starting_info": { + "previous_period": "6", + "stake": "12274844463.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "starting_info": { + "previous_period": "8", + "stake": "18071051811.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "starting_info": { + "previous_period": "4", + "stake": "12958021951.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", + "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "starting_info": { + "previous_period": "6", + "stake": "4593224997.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", + "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "starting_info": { + "previous_period": "5", + "stake": "1199437642.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfej3rle", + "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", + "starting_info": { + "previous_period": "1", + "stake": "1494931451.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "starting_info": { + "previous_period": "2", + "stake": "6923120900.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "starting_info": { + "previous_period": "4", + "stake": "19205968225.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "starting_info": { + "previous_period": "5", + "stake": "1744984549.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "starting_info": { + "previous_period": "6", + "stake": "251790.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "starting_info": { + "previous_period": "7", + "stake": "12788946759.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "starting_info": { + "previous_period": "4", + "stake": "22141837134.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos147lwcm3tx6uhtjphxwwmk7u32mucukalplv80z", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "starting_info": { + "previous_period": "6", + "stake": "1601474401.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "starting_info": { + "previous_period": "5", + "stake": "8455755268.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "starting_info": { + "previous_period": "3", + "stake": "330891000.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "starting_info": { + "previous_period": "8", + "stake": "22514769356.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "starting_info": { + "previous_period": "9", + "stake": "252433656.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "starting_info": { + "previous_period": "4", + "stake": "385810656.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "starting_info": { + "previous_period": "1", + "stake": "4301090429.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "starting_info": { + "previous_period": "5", + "stake": "24027809.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", + "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "starting_info": { + "previous_period": "1", + "stake": "24395123.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", + "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "starting_info": { + "previous_period": "2", + "stake": "218958522.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "starting_info": { + "previous_period": "6", + "stake": "19002817.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "starting_info": { + "previous_period": "5", + "stake": "357887239.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "starting_info": { + "previous_period": "5", + "stake": "2725727123.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "starting_info": { + "previous_period": "4", + "stake": "31595387940.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "starting_info": { + "previous_period": "6", + "stake": "938622421.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "starting_info": { + "previous_period": "3", + "stake": "482001747.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", + "starting_info": { + "previous_period": "2", + "stake": "781062755.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "starting_info": { + "previous_period": "4", + "stake": "9948638663.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "starting_info": { + "previous_period": "6", + "stake": "8844305443.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "starting_info": { + "previous_period": "5", + "stake": "844335956.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1urnp7yp6u27nut8kvsrapgmmvk8sh6u5wd5dez", + "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", + "starting_info": { + "previous_period": "1", + "stake": "13977340603.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", + "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", + "starting_info": { + "previous_period": "2", + "stake": "120397764.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", + "starting_info": { + "previous_period": "2", + "stake": "251933.000000000000000000", + "creation_height": "49" + } + }, + { + "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", + "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "starting_info": { + "previous_period": "2", + "stake": "2246425767.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1uvm96xdewfpdwymw5ywt8j5efq6jhpyl35pzg8", + "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "starting_info": { + "previous_period": "1", + "stake": "7577447491.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "starting_info": { + "previous_period": "3", + "stake": "23613691655.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "starting_info": { + "previous_period": "2", + "stake": "8173781116.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1uuk9ewj0532rzlhlg86tserdxvtnm3kq2k2zww", + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", + "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", + "starting_info": { + "previous_period": "2", + "stake": "763826873.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "starting_info": { + "previous_period": "3", + "stake": "1386448079.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "starting_info": { + "previous_period": "4", + "stake": "627370738.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "starting_info": { + "previous_period": "2", + "stake": "5887196.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "starting_info": { + "previous_period": "3", + "stake": "671837638.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "starting_info": { + "previous_period": "1", + "stake": "9361230791.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", + "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", + "starting_info": { + "previous_period": "2", + "stake": "82979650.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "starting_info": { + "previous_period": "3", + "stake": "315491807.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "starting_info": { + "previous_period": "2", + "stake": "2274933257.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "starting_info": { + "previous_period": "1", + "stake": "6631273690.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", + "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", + "starting_info": { + "previous_period": "1", + "stake": "5682430.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "starting_info": { + "previous_period": "3", + "stake": "7610845.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "starting_info": { + "previous_period": "2", + "stake": "11045854268.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1adwsqn58aype530jae9qrwknsxyf3wmwdr523z", + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "starting_info": { + "previous_period": "3", + "stake": "951735771.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "starting_info": { + "previous_period": "4", + "stake": "4858570428.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1c4lft2m4yyrzjsxyu7nzsrxuskgtlr2crzzwwd", + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "starting_info": { + "previous_period": "2", + "stake": "4541366.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "starting_info": { + "previous_period": "1", + "stake": "10992310558.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "starting_info": { + "previous_period": "5", + "stake": "548109039.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "starting_info": { + "previous_period": "7", + "stake": "670559324.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "starting_info": { + "previous_period": "4", + "stake": "22252816301.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1awyus34e6laq3zxqsrv283w6fgn8w62zkwd87d", + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "starting_info": { + "previous_period": "6", + "stake": "1878391814.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "starting_info": { + "previous_period": "3", + "stake": "1549115655.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "starting_info": { + "previous_period": "5", + "stake": "16011251757.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "starting_info": { + "previous_period": "8", + "stake": "349164048.000000000000000000", + "creation_height": "13" + } + }, + { + "delegator_address": "cosmos1a0jdqzvk078d6486vuxdr5d0yp6rglue2nh5dn", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "starting_info": { + "previous_period": "7", + "stake": "9613933711.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1r572vr0k388gpjw5h2u75ppmarvgma20rqj2ws", + "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "starting_info": { + "previous_period": "3", + "stake": "16932030948.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "starting_info": { + "previous_period": "2", + "stake": "7764993320.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8kl6qt4", + "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", + "starting_info": { + "previous_period": "1", + "stake": "15012824613.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", + "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", + "starting_info": { + "previous_period": "4", + "stake": "228354642.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "starting_info": { + "previous_period": "4", + "stake": "19101606110.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "starting_info": { + "previous_period": "5", + "stake": "943974869.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "starting_info": { + "previous_period": "3", + "stake": "21448624442.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", + "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", + "starting_info": { + "previous_period": "2", + "stake": "1820280319.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", + "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", + "starting_info": { + "previous_period": "2", + "stake": "2580293599.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "starting_info": { + "previous_period": "7", + "stake": "6251197681.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "starting_info": { + "previous_period": "5", + "stake": "1793233946.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "starting_info": { + "previous_period": "2", + "stake": "6254739411.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "starting_info": { + "previous_period": "6", + "stake": "51693014.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "starting_info": { + "previous_period": "4", + "stake": "25069342080.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos178pm30fcgrt5654czwr8nlex050m6y609glx2s", + "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "starting_info": { + "previous_period": "1", + "stake": "23703504292.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "starting_info": { + "previous_period": "2", + "stake": "18880150143.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "starting_info": { + "previous_period": "9", + "stake": "7684584877.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "starting_info": { + "previous_period": "7", + "stake": "9360757617.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "starting_info": { + "previous_period": "8", + "stake": "10690661250.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "starting_info": { + "previous_period": "10", + "stake": "827898827.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "starting_info": { + "previous_period": "5", + "stake": "18525526004.000000000000000000", + "creation_height": "3" + } + }, + { + "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "starting_info": { + "previous_period": "6", + "stake": "3755696144.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", + "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "starting_info": { + "previous_period": "4", + "stake": "14112770668.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos17gpy6jzg7xdsr2xc7kweljagx4uaysxdk2244g", + "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "starting_info": { + "previous_period": "3", + "stake": "7651697131.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnk5g0lz", + "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", + "starting_info": { + "previous_period": "1", + "stake": "227804730.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "starting_info": { + "previous_period": "7", + "stake": "151161779.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "starting_info": { + "previous_period": "5", + "stake": "9209912.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos172lmu2psqlkxkthpr46h2ewjffte7lhlmwe6tg", + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "starting_info": { + "previous_period": "1", + "stake": "25069342080.000000000000000000", + "creation_height": "0" + } + }, + { + "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", + "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", + "starting_info": { + "previous_period": "3", + "stake": "1397104980.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s", + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "starting_info": { + "previous_period": "5", + "stake": "9953913240.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "starting_info": { + "previous_period": "4", + "stake": "6161948206.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "starting_info": { + "previous_period": "6", + "stake": "117960718.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "starting_info": { + "previous_period": "7", + "stake": "513446339.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", + "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", + "starting_info": { + "previous_period": "1", + "stake": "300592036.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "starting_info": { + "previous_period": "8", + "stake": "20382455281.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "starting_info": { + "previous_period": "4", + "stake": "18580691943.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "starting_info": { + "previous_period": "9", + "stake": "7585898322.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "starting_info": { + "previous_period": "5", + "stake": "2352005810.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "starting_info": { + "previous_period": "6", + "stake": "8013043987.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "starting_info": { + "previous_period": "4", + "stake": "809035601.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "starting_info": { + "previous_period": "2", + "stake": "6295579444.000000000000000000", + "creation_height": "7" + } + }, + { + "delegator_address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "starting_info": { + "previous_period": "3", + "stake": "1221107604.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", + "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "starting_info": { + "previous_period": "5", + "stake": "3671255483.000000000000000000", + "creation_height": "50" + } + }, + { + "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "starting_info": { + "previous_period": "3", + "stake": "825862061.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", + "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", + "starting_info": { + "previous_period": "2", + "stake": "340930766.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "starting_info": { + "previous_period": "5", + "stake": "13874964933.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "starting_info": { + "previous_period": "7", + "stake": "22147479421.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "starting_info": { + "previous_period": "3", + "stake": "5740343356.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "starting_info": { + "previous_period": "9", + "stake": "11614756424.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "starting_info": { + "previous_period": "8", + "stake": "209859957.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "starting_info": { + "previous_period": "6", + "stake": "157324268.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "starting_info": { + "previous_period": "4", + "stake": "20037186316.000000000000000000", + "creation_height": "6" + } + }, + { + "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "starting_info": { + "previous_period": "3", + "stake": "17646792.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "starting_info": { + "previous_period": "5", + "stake": "89358777.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "starting_info": { + "previous_period": "2", + "stake": "5054551129.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "starting_info": { + "previous_period": "3", + "stake": "39160384.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "starting_info": { + "previous_period": "4", + "stake": "18344719406.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "starting_info": { + "previous_period": "2", + "stake": "410769752.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "starting_info": { + "previous_period": "1", + "stake": "159276935.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "starting_info": { + "previous_period": "5", + "stake": "97571824.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "starting_info": { + "previous_period": "6", + "stake": "4090038169.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "starting_info": { + "previous_period": "4", + "stake": "1168681082.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "starting_info": { + "previous_period": "7", + "stake": "18120372537.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", + "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "starting_info": { + "previous_period": "2", + "stake": "4792139392.000000000000000000", + "creation_height": "47" + } + }, + { + "delegator_address": "cosmos1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpkca4g8", + "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "starting_info": { + "previous_period": "1", + "stake": "15023386396.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", + "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "starting_info": { + "previous_period": "6", + "stake": "376238441.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "starting_info": { + "previous_period": "5", + "stake": "281580943.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqcrj0xk", + "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", + "starting_info": { + "previous_period": "2", + "stake": "1028714701.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1ryp2xkqe74y5kx6zffqtdc3wzgny8xg8eguupq", + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "starting_info": { + "previous_period": "6", + "stake": "1639136540.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "starting_info": { + "previous_period": "5", + "stake": "205025816.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "starting_info": { + "previous_period": "2", + "stake": "23612702988.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "starting_info": { + "previous_period": "7", + "stake": "11095524326.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "starting_info": { + "previous_period": "6", + "stake": "131936453.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "starting_info": { + "previous_period": "5", + "stake": "11761380768.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "starting_info": { + "previous_period": "2", + "stake": "21096282678.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", + "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "starting_info": { + "previous_period": "2", + "stake": "12106150602.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", + "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "starting_info": { + "previous_period": "4", + "stake": "179430222.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "starting_info": { + "previous_period": "4", + "stake": "29688637.000000000000000000", + "creation_height": "12" + } + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "starting_info": { + "previous_period": "2", + "stake": "212323217.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1l5d2lg5hku0m4u8mh866zhjcy2dekpk598m8wr", + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "starting_info": { + "previous_period": "3", + "stake": "25069342080.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", + "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", + "starting_info": { + "previous_period": "2", + "stake": "3907335026.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "starting_info": { + "previous_period": "2", + "stake": "7597437829.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn", + "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "starting_info": { + "previous_period": "1", + "stake": "2977168576.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "starting_info": { + "previous_period": "3", + "stake": "12769609475.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "starting_info": { + "previous_period": "6", + "stake": "522473074.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "starting_info": { + "previous_period": "4", + "stake": "19453723967.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "starting_info": { + "previous_period": "5", + "stake": "7100496609.000000000000000000", + "creation_height": "5" + } + }, + { + "delegator_address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "starting_info": { + "previous_period": "4", + "stake": "5734721271.000000000000000000", + "creation_height": "4" + } + }, + { + "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "starting_info": { + "previous_period": "3", + "stake": "40666822.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "starting_info": { + "previous_period": "2", + "stake": "8982227181.000000000000000000", + "creation_height": "2" + } + }, + { + "delegator_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "starting_info": { + "previous_period": "4", + "stake": "3178697313.000000000000000000", + "creation_height": "8" + } + }, + { + "delegator_address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "starting_info": { + "previous_period": "6", + "stake": "11738157290.000000000000000000", + "creation_height": "48" + } + }, + { + "delegator_address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "starting_info": { + "previous_period": "2", + "stake": "315677262.000000000000000000", + "creation_height": "1" + } + }, + { + "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "starting_info": { + "previous_period": "5", + "stake": "2332669614.000000000000000000", + "creation_height": "14" + } + }, + { + "delegator_address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "starting_info": { + "previous_period": "3", + "stake": "11119271370.000000000000000000", + "creation_height": "5" + } + } + ], + "validator_slash_events": [ + { + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "height": "25", + "period": "4", + "validator_slash_event": { + "validator_period": "4", + "fraction": "0.026601021112653654" + } + }, + { + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "height": "2", + "period": "4", + "validator_slash_event": { + "validator_period": "4", + "fraction": "0.023923716300005538" + } + } + ] + }, + "staking": { + "params": { + "unbonding_time": "17344000000000", + "max_validators": 223, + "max_entries": 7, + "historical_entries": 3, + "bond_denom": "stake" + }, + "last_total_power": "7451648", + "last_validator_powers": [ + { + "Address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "Power": "24767" + }, + { + "Address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "Power": "40149" + }, + { + "Address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "Power": "33873" + }, + { + "Address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "Power": "49524" + }, + { + "Address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "Power": "76856" + }, + { + "Address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "Power": "16016" + }, + { + "Address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "Power": "32584" + }, + { + "Address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "Power": "15545" + }, + { + "Address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "Power": "35273" + }, + { + "Address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "Power": "24353" + }, + { + "Address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "Power": "44979" + }, + { + "Address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "Power": "24972" + }, + { + "Address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "Power": "15307" + }, + { + "Address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "Power": "37286" + }, + { + "Address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "Power": "26109" + }, + { + "Address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "Power": "25204" + }, + { + "Address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "Power": "23014" + }, + { + "Address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "Power": "49505" + }, + { + "Address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "Power": "52891" + }, + { + "Address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "Power": "69365" + }, + { + "Address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "Power": "17054" + }, + { + "Address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "Power": "55080" + }, + { + "Address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "Power": "17768" + }, + { + "Address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "Power": "22598" + }, + { + "Address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "Power": "27149" + }, + { + "Address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "Power": "49314" + }, + { + "Address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "Power": "26185" + }, + { + "Address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "Power": "32785" + }, + { + "Address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "Power": "33846" + }, + { + "Address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "Power": "25066" + }, + { + "Address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "Power": "25061" + }, + { + "Address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "Power": "76719" + }, + { + "Address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "Power": "18750" + }, + { + "Address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "Power": "24248" + }, + { + "Address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "Power": "82798" + }, + { + "Address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "Power": "26155" + }, + { + "Address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "Power": "32302" + }, + { + "Address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "Power": "56132" + }, + { + "Address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "Power": "69316" + }, + { + "Address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "Power": "27808" + }, + { + "Address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "Power": "17750" + }, + { + "Address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "Power": "22144" + }, + { + "Address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "Power": "16214" + }, + { + "Address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "Power": "23352" + }, + { + "Address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "Power": "34693" + }, + { + "Address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "Power": "42958" + }, + { + "Address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "Power": "21734" + }, + { + "Address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "Power": "29256" + }, + { + "Address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "Power": "65051" + }, + { + "Address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "Power": "18897" + }, + { + "Address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "Power": "27157" + }, + { + "Address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "Power": "45028" + }, + { + "Address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "Power": "35018" + }, + { + "Address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "Power": "17547" + }, + { + "Address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "Power": "25071" + }, + { + "Address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "Power": "27784" + }, + { + "Address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "Power": "31634" + }, + { + "Address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "Power": "22383" + }, + { + "Address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "Power": "16236" + }, + { + "Address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "Power": "42937" + }, + { + "Address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "Power": "36911" + }, + { + "Address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "Power": "39363" + }, + { + "Address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "Power": "27734" + }, + { + "Address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "Power": "27605" + }, + { + "Address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "Power": "24423" + }, + { + "Address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "Power": "25592" + }, + { + "Address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "Power": "25675" + }, + { + "Address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "Power": "50488" + }, + { + "Address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "Power": "20659" + }, + { + "Address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "Power": "53644" + }, + { + "Address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "Power": "21168" + }, + { + "Address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "Power": "27374" + }, + { + "Address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "Power": "20929" + }, + { + "Address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "Power": "15286" + }, + { + "Address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "Power": "70162" + }, + { + "Address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "Power": "20279" + }, + { + "Address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "Power": "31584" + }, + { + "Address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "Power": "22768" + }, + { + "Address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "Power": "26491" + }, + { + "Address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "Power": "16257" + }, + { + "Address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "Power": "62801" + }, + { + "Address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "Power": "22515" + }, + { + "Address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "Power": "29556" + }, + { + "Address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "Power": "25121" + }, + { + "Address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "Power": "59694" + }, + { + "Address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "Power": "16949" + }, + { + "Address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "Power": "20324" + }, + { + "Address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "Power": "18158" + }, + { + "Address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "Power": "25435" + }, + { + "Address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "Power": "16773" + }, + { + "Address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "Power": "17705" + }, + { + "Address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "Power": "26461" + }, + { + "Address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "Power": "17862" + }, + { + "Address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "Power": "112536" + }, + { + "Address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "Power": "27525" + }, + { + "Address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "Power": "57637" + }, + { + "Address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "Power": "19834" + }, + { + "Address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "Power": "37175" + }, + { + "Address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "Power": "55634" + }, + { + "Address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "Power": "20453" + }, + { + "Address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "Power": "52558" + }, + { + "Address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "Power": "18560" + }, + { + "Address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "Power": "22083" + }, + { + "Address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "Power": "26763" + }, + { + "Address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "Power": "25943" + }, + { + "Address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "Power": "68955" + }, + { + "Address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "Power": "49844" + }, + { + "Address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "Power": "19233" + }, + { + "Address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "Power": "25961" + }, + { + "Address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "Power": "33320" + }, + { + "Address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "Power": "59094" + }, + { + "Address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "Power": "27718" + }, + { + "Address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "Power": "33772" + }, + { + "Address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "Power": "24587" + }, + { + "Address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "Power": "62232" + }, + { + "Address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "Power": "25948" + }, + { + "Address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "Power": "18426" + }, + { + "Address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "Power": "16774" + }, + { + "Address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "Power": "32156" + }, + { + "Address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "Power": "16811" + }, + { + "Address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "Power": "19540" + }, + { + "Address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "Power": "33258" + }, + { + "Address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "Power": "41543" + }, + { + "Address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "Power": "61843" + }, + { + "Address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "Power": "36037" + }, + { + "Address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "Power": "33206" + }, + { + "Address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "Power": "27567" + }, + { + "Address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "Power": "27671" + }, + { + "Address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "Power": "25069" + }, + { + "Address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "Power": "55737" + }, + { + "Address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "Power": "33054" + }, + { + "Address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "Power": "78601" + }, + { + "Address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "Power": "18090" + }, + { + "Address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "Power": "33968" + }, + { + "Address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "Power": "19857" + }, + { + "Address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "Power": "23726" + }, + { + "Address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "Power": "16516" + }, + { + "Address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "Power": "45010" + }, + { + "Address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "Power": "54768" + }, + { + "Address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "Power": "25326" + }, + { + "Address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "Power": "67804" + }, + { + "Address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "Power": "41964" + }, + { + "Address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "Power": "28676" + }, + { + "Address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "Power": "34574" + }, + { + "Address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "Power": "16992" + }, + { + "Address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "Power": "26261" + }, + { + "Address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "Power": "46127" + }, + { + "Address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "Power": "22249" + }, + { + "Address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "Power": "39560" + }, + { + "Address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "Power": "16420" + }, + { + "Address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "Power": "26062" + }, + { + "Address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "Power": "44313" + }, + { + "Address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "Power": "25164" + }, + { + "Address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "Power": "16985" + }, + { + "Address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "Power": "25367" + }, + { + "Address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "Power": "54901" + }, + { + "Address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "Power": "15374" + }, + { + "Address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "Power": "33057" + }, + { + "Address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "Power": "49683" + }, + { + "Address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "Power": "34289" + }, + { + "Address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "Power": "29885" + }, + { + "Address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "Power": "21181" + }, + { + "Address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "Power": "39430" + }, + { + "Address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "Power": "32328" + }, + { + "Address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "Power": "15813" + }, + { + "Address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "Power": "25957" + }, + { + "Address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "Power": "45284" + }, + { + "Address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "Power": "44505" + }, + { + "Address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "Power": "22456" + }, + { + "Address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "Power": "45811" + }, + { + "Address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "Power": "24610" + }, + { + "Address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "Power": "34459" + }, + { + "Address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "Power": "55948" + }, + { + "Address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "Power": "15675" + }, + { + "Address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "Power": "45487" + }, + { + "Address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "Power": "24261" + }, + { + "Address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "Power": "31770" + }, + { + "Address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "Power": "37602" + }, + { + "Address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "Power": "37676" + }, + { + "Address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "Power": "26737" + }, + { + "Address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "Power": "20405" + }, + { + "Address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "Power": "25102" + }, + { + "Address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "Power": "17609" + }, + { + "Address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "Power": "41119" + }, + { + "Address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "Power": "19565" + }, + { + "Address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "Power": "44648" + }, + { + "Address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "Power": "34209" + }, + { + "Address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "Power": "36900" + }, + { + "Address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "Power": "28980" + }, + { + "Address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "Power": "27742" + }, + { + "Address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "Power": "17377" + }, + { + "Address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "Power": "25431" + }, + { + "Address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "Power": "74690" + }, + { + "Address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "Power": "27874" + }, + { + "Address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "Power": "68086" + }, + { + "Address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "Power": "25446" + }, + { + "Address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "Power": "35741" + }, + { + "Address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "Power": "19637" + }, + { + "Address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "Power": "56856" + }, + { + "Address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "Power": "36122" + }, + { + "Address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "Power": "16807" + }, + { + "Address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "Power": "48540" + }, + { + "Address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "Power": "29401" + }, + { + "Address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "Power": "24697" + }, + { + "Address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "Power": "41494" + }, + { + "Address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "Power": "39420" + }, + { + "Address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "Power": "23703" + }, + { + "Address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "Power": "69725" + }, + { + "Address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "Power": "21764" + }, + { + "Address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "Power": "25229" + }, + { + "Address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "Power": "16747" + }, + { + "Address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "Power": "56914" + }, + { + "Address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "Power": "53587" + }, + { + "Address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "Power": "20301" + }, + { + "Address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "Power": "23438" + }, + { + "Address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "Power": "23476" + }, + { + "Address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "Power": "19815" + }, + { + "Address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "Power": "25456" + }, + { + "Address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "Power": "44085" + }, + { + "Address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "Power": "25311" + }, + { + "Address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "Power": "32745" + }, + { + "Address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "Power": "21858" + }, + { + "Address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "Power": "28684" + } + ], + "validators": [ + { + "operator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels7tpscy", + "status": 3, + "tokens": "24767745772", + "delegator_shares": "24767745772.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.064962829627143450", + "max_rate": "0.700000000000000000", + "max_change_rate": "0.524524837966075502" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2clak7n0wuffqrj9ltzxmj7mp8nfd4mupcs2qx8wcntcmqmrhlg5vf35j7", + "status": 1, + "tokens": "5753141484", + "delegator_shares": "5753141484.000000000000000000", + "description": { + "moniker": "wdwulLxyKe", + "identity": "QqZmHtsqUC", + "website": "cuuMWdybju", + "security_contact": "lFYCqceWXh", + "details": "CUtMyvoidK" + }, + "unbonding_height": "6", + "unbonding_time": "9936-01-01T04:22:01Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.650000000000000000", + "max_change_rate": "0.115214438896595768" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xt2s2vh", + "status": 3, + "tokens": "40149298125", + "delegator_shares": "40149298125.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020987080088521851", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.079654399773437862" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk7tt4rl", + "status": 3, + "tokens": "33873720903", + "delegator_shares": "33873720903.000000000000000000", + "description": { + "moniker": "mLoNnmWUiV", + "identity": "RHiUhLQQnZ", + "website": "GdVEOYibSd", + "security_contact": "DcfUpyGSpE", + "details": "kaQgULDDFV" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.793635545567707656", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.546926599085395557" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfkykt89x2wmxt2w74v340hwp8azwyzswzgxzmcv46995zwggpu66ans7kn", + "status": 3, + "tokens": "49524189675", + "delegator_shares": "49524189675.000000000000000000", + "description": { + "moniker": "qorkgLHbbW", + "identity": "vVsXuupmaH", + "website": "GASCHEJsbz", + "security_contact": "KEcXQQooNh", + "details": "UlGvDMHBgm" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150351690116871266", + "max_rate": "0.470000000000000000", + "max_change_rate": "0.232118363435586291" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqve274rfua7xfczhfywq3xmq697sc39wlnvqwlpewefqud77cehe5t682kl", + "status": 1, + "tokens": "12080352392", + "delegator_shares": "12080352392.000000000000000000", + "description": { + "moniker": "FbRIhVHFau", + "identity": "HIdWlohNVg", + "website": "oXDusHPuBW", + "security_contact": "MIuroYiNYk", + "details": "yzSyOcoXIA" + }, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.980000000000000000", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.637017075521110755" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcrkzkl0", + "status": 3, + "tokens": "76856004359", + "delegator_shares": "76856004359.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.159853619317053801", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.178173481628386356" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv2gdzf9hv5kg8cua2vdmh6j4pvu8t6qt3qna7ahzamg3k85zhqks2vrug8", + "status": 1, + "tokens": "10291647618", + "delegator_shares": "10291647618.000000000000000000", + "description": { + "moniker": "DsEkgGrQIW", + "identity": "LhylLHTNSR", + "website": "neVVZYPYun", + "security_contact": "SrqnNfZPyD", + "details": "covJBBgWgi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.024110631876108367", + "max_rate": "0.060000000000000000", + "max_change_rate": "0.059149357084397769" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0yv2h8z80vtfttsewrwe2v83haaceax7q3ey95uaeqj8lstf7l674zn3ut", + "status": 3, + "tokens": "16016194501", + "delegator_shares": "16016194501.000000000000000000", + "description": { + "moniker": "WVhrVMjLnZ", + "identity": "QiIQjemxtv", + "website": "KCKlbRarYk", + "security_contact": "AwimEeOMDq", + "details": "omCiVdOfZS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.636807270475032336", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.762928812525012131" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwstfpc6n2mx2kwfz0p6cqcp2d4am2xavsgtdncu3aqwvuvr8672zq0r78s", + "status": 1, + "tokens": "6707030963", + "delegator_shares": "6707030963.000000000000000000", + "description": {}, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.300951621180132243", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.231974974827222704" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0rfcm50fj3x25lu4dlrvcypfmrelrrtpckw5qn4xhzwweutl3rpuzqaycl", + "status": 1, + "tokens": "998337488", + "delegator_shares": "998337488.000000000000000000", + "description": { + "moniker": "ggHvjQWPsn", + "identity": "TSLKAGCHeV", + "website": "pJCXCTYBcs", + "security_contact": "bBFXWKuUjd", + "details": "mlLcRteZDO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.000000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-04T15:40:16Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghknhrvft", + "status": 3, + "tokens": "32584502965", + "delegator_shares": "32584502965.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.063963134401067102" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgt7tyq6", + "status": 3, + "tokens": "15545552914", + "delegator_shares": "15545552914.000000000000000000", + "description": { + "moniker": "VaOLitHrfh", + "identity": "zYkbJeTdPC", + "website": "RWLWpQBLTs", + "security_contact": "EEFOrnsvml", + "details": "xRXuWfcvoz" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.209346043397093808", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.261491014079542938" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgvt8hk8ugsx3spnywmwca23g5n2mefgl9wqae5apg5c8rfjqejczx7m9pt", + "status": 1, + "tokens": "632273041", + "delegator_shares": "632273041.000000000000000000", + "description": { + "moniker": "RTtEwCbQJP", + "identity": "nwxkifTnqT", + "website": "XmvidEOMQm", + "security_contact": "vwnSfNMnzZ", + "details": "tggKCpEWIf" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.524843579708394583", + "max_rate": "0.720000000000000000", + "max_change_rate": "0.101390585218042270" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdhs8x9jxh3zj8x9khc8mxzmschyuglut7qc08pgnsvsez40ejvagk98fp5", + "status": 1, + "tokens": "847666854", + "delegator_shares": "847666854.000000000000000000", + "description": { + "moniker": "ydPLQsYmIS", + "identity": "mavrVBFYgS", + "website": "WKiuHqSQHZ", + "security_contact": "JdSAwbrUfj", + "details": "mqtJCHeTAG" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.000000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpvkknmf7", + "status": 3, + "tokens": "35273490053", + "delegator_shares": "35273490053.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.412168984856446389", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.601152598273329028" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2yn5flk79h6vhzu7xp0heeklwgkac6whhz9ezkvj2k0920k58qvquulfzs", + "status": 1, + "tokens": "1750195180", + "delegator_shares": "1750195180.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.117442172658848604" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4645lf2dka2qs2renc2n2rts24k9xfmxnx5fkhvj3squp8nv5ugyr2nj8", + "status": 2, + "tokens": "5104433738", + "delegator_shares": "5104433738.000000000000000000", + "description": {}, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.005185006676002722", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.268395235691771325" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdq977shfdy56qqae5djrzznyn6kqv2s55gh8jtr5gsmkttjdsvd72nkejc", + "status": 1, + "tokens": "8916911438", + "delegator_shares": "8916911438.000000000000000000", + "description": { + "moniker": "dxqsTRkaYb", + "identity": "TOJMyzBlre", + "website": "ruYObGvtfU", + "security_contact": "PoeWHpGxhY", + "details": "NfReLbYTyY" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.210000000000000000", + "max_rate": "0.210000000000000000", + "max_change_rate": "0.014827952061898434" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvw0g93n8", + "status": 3, + "tokens": "24353363633", + "delegator_shares": "24353363633.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.140843713075627976", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.124247346623493378" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtxrkpudghuhgsu0he7ntk7q0asqa5ax23y7rnn5mfjr2d68z4emsrwqssp", + "status": 3, + "tokens": "44979344173", + "delegator_shares": "44979344173.000000000000000000", + "description": { + "moniker": "eJECwiPlqs", + "identity": "TywZsaZwgH", + "website": "jtFVQJUofX", + "security_contact": "fstanspUpc", + "details": "RQddrwMsIR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.005369299901591159", + "max_rate": "0.030000000000000000", + "max_change_rate": "0.010979308887356502" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwz2zelc", + "status": 3, + "tokens": "24972834479", + "delegator_shares": "24972834479.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118883162683785924", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.582076368438090700" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2dcqs6jwgqs06hz297xdv606lcyx76wnyf228c98wsnmrarnjg7qdrlhmh", + "status": 3, + "tokens": "15307584671", + "delegator_shares": "15307584671.000000000000000000", + "description": { + "moniker": "MLAiGifuge", + "identity": "YmgtyeQqKn", + "website": "tgmRpbrPqg", + "security_contact": "EoVdOQlqiF", + "details": "MFxkDUZjLF" + }, + "unbonding_height": "49", + "unbonding_time": "9936-01-04T20:29:20Z", + "commission": { + "commission_rates": { + "rate": "0.079450929148714776", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.213073238635972528" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0g2ma6xw58ftmksx3k7vk80w6fc9cume5z0h05yycsafk9v62ywkzlshqc", + "status": 1, + "tokens": "5044911319", + "delegator_shares": "5044911319.000000000000000000", + "description": { + "moniker": "zTrVCpgXUe", + "identity": "unfAiREWWG", + "website": "zPGHaOmdaQ", + "security_contact": "ejYFFBeYoZ", + "details": "yBOLCBGsRi" + }, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.303756486405262817", + "max_rate": "0.510000000000000000", + "max_change_rate": "0.510000000000000000" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q205udc4", + "status": 3, + "tokens": "37286335725", + "delegator_shares": "37286335725.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.137121313165408722" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt032nytxy3x5xdysx4nyqd43jz9ty6she7qzs8ng7tjyy2rnrstywwgu5c", + "status": 1, + "tokens": "203339835", + "delegator_shares": "203339835.000000000000000000", + "description": { + "moniker": "ynEaQzbejL", + "identity": "MUyIiByuFi", + "website": "AGxnGDQIOT", + "security_contact": "KYcvOadcfO", + "details": "swLSGZmGOw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.462568474915615654", + "max_rate": "0.700000000000000000", + "max_change_rate": "0.700000000000000000" + }, + "update_time": "9936-01-01T16:55:11Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvfjj8axcs74r3vxh3lclw7upds6cn5ru6ggy2ptzjsp4e6j8racwzngt4r", + "status": 1, + "tokens": "6058218058", + "delegator_shares": "6058218058.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.020053792824689742" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdk79m7s7fjmw7x7v9wstfge6tx0y9vlke6q0w8xnw6xrvqjxnx7wremcav", + "status": 1, + "tokens": "7304584820", + "delegator_shares": "7304584820.000000000000000000", + "description": { + "moniker": "BdegmqHdlW", + "identity": "KHOTjTMoXW", + "website": "xjpfgHTnPp", + "security_contact": "nxZRJewfeS", + "details": "gPXCjmtPkp" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.425246430057154161" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zycdvvrg7", + "status": 3, + "tokens": "26109827309", + "delegator_shares": "26109827309.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.272379182115041576" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvqzwt52t9y9pwaa3f2swmdm89ly65wv5vtj3w5uvz52u4w2mhuy7n0hqlm", + "status": 1, + "tokens": "6575461080", + "delegator_shares": "6575461080.000000000000000000", + "description": { + "moniker": "tMnHvAwTJR", + "identity": "onTsWeVUKS", + "website": "veLYiFvaVy", + "security_contact": "njDJSVeKyI", + "details": "sWOtMODqPy" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.769634007692600014", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "consensus_pubkey": "cosmosvalconspub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwlhqscf", + "status": 3, + "tokens": "25204407264", + "delegator_shares": "25204407264.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.276804190595109972", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.303611347820460701" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv9qnwg9cn0v623s0xcnfn88vfn3musyh22lk522tnxt4a9g44tlugcyrxd", + "status": 1, + "tokens": "101462019", + "delegator_shares": "101462019.000000000000000000", + "description": { + "moniker": "VSOJycctFN", + "identity": "vFDsxccNPn", + "website": "szHnznvmsJ", + "security_contact": "WfbWJuwCJr", + "details": "hVYDcdjcPF" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.133628283997124854", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.150000000000000000" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2u3gzal", + "status": 3, + "tokens": "23014258552", + "delegator_shares": "23014258552.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289943655120962524", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.271265684659427360" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvpp0e5dwtq4r86wnmrfva492d8qedsntcl7pamjgecqcwz36qltuzda7yc", + "status": 1, + "tokens": "5183376555", + "delegator_shares": "5183376555.000000000000000000", + "description": { + "moniker": "coLWQUtfpH", + "identity": "qqRgVFIBHt", + "website": "tVbQGrFIRK", + "security_contact": "XqOIjvNBNm", + "details": "PNMPALBEye" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.134622338980971365", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.192256407383356671" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgh4tj7q", + "status": 3, + "tokens": "49505425616", + "delegator_shares": "49505425616.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.519126528788995280", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw55ftmtn", + "status": 3, + "tokens": "52891997390", + "delegator_shares": "52891997390.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.006443603339396517", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.110565720532816181" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0x07aykzgfl7xjmd49u0dnc0xc69xv3cftdhly8hgc7y3djgfpqcd7szxu", + "status": 1, + "tokens": "3104272392", + "delegator_shares": "3104272392.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.309206591421572804", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.173213597206352691" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavc40dh4", + "status": 3, + "tokens": "69365122054", + "delegator_shares": "69365122054.000000000000000000", + "description": { + "moniker": "IoqkplxtIQ", + "identity": "SYtEYnqVjz", + "website": "cbrMdhVrVp", + "security_contact": "eWitXxyhJZ", + "details": "FCojJQQFCQ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.745132980800690980", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.321606633967630124" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tugphy2d", + "status": 3, + "tokens": "17054284690", + "delegator_shares": "17054284690.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.602634897210355218", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.136597759514787421" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfhaz3cwkjvqxwcgmpg4h52j5ta6tnanf0ngtkcreptep0al8vqdqx2rvua", + "status": 1, + "tokens": "4205959298", + "delegator_shares": "4205959298.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000203985932473082", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqghfgrvv86d4rtnt8zqrrmnj8vqrm75e4xsl7wr9rww7tewvzj2pygmcvw3", + "status": 1, + "tokens": "5951502740", + "delegator_shares": "5951502740.000000000000000000", + "description": { + "moniker": "sPILgSqlFb", + "identity": "SeswFftEiP", + "website": "guQCrflISz", + "security_contact": "fHotzizZnj", + "details": "gvAfzRuUwL" + }, + "unbonding_height": "14", + "unbonding_time": "9936-01-01T21:44:15Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.074237147649670066" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jztkylp", + "status": 3, + "tokens": "55080258715", + "delegator_shares": "55080258715.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.052047960532670175", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwuthwk4ulyfx4j6f8q9ql4cwhnu923da4m63sg3n4hldpa2rzr2x7m8t9a", + "status": 1, + "tokens": "9924972848", + "delegator_shares": "9924972848.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.818438994582953595", + "max_rate": "0.950000000000000000", + "max_change_rate": "0.619609185068905685" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgrwz3gl", + "status": 3, + "tokens": "17768682341", + "delegator_shares": "17768682341.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.141929485726276362" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd45mshdzdsn0zpnemh0zghvu25ukrxkn9r0nk0mc8qz44k2fpdn6fptqcl", + "status": 1, + "tokens": "13149786343", + "delegator_shares": "13149786343.000000000000000000", + "description": { + "moniker": "svuLpcmsdf", + "identity": "IvJIgPtZYX", + "website": "gLAZCqbEaE", + "security_contact": "CJQnRdPYVV", + "details": "mTuGpBAhce" + }, + "unbonding_height": "6", + "unbonding_time": "9936-01-01T04:22:01Z", + "commission": { + "commission_rates": { + "rate": "0.590000000000000000", + "max_rate": "0.590000000000000000", + "max_change_rate": "0.048300182902893644" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf2ugr68h5nt2x6k4c6ag0f69f4ey80uv5w4u9ludsdpdtrhw07lvlaey06", + "status": 1, + "tokens": "9436725725", + "delegator_shares": "9436725725.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.783302239482289410", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.369136928052532298" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yr97z8g", + "status": 3, + "tokens": "22598538029", + "delegator_shares": "22598538029.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.335354744004515496", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.096800797786563611" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2zq3f3j", + "status": 3, + "tokens": "27149799034", + "delegator_shares": "27149799034.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.158969199652087770", + "max_rate": "0.220000000000000000", + "max_change_rate": "0.220000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0560r7042zjwg7hflfrslec73nzuyejkhpu5v84lhf4xjlgkkl26vdc8q9", + "status": 1, + "tokens": "6070945323", + "delegator_shares": "6070945323.000000000000000000", + "description": { + "moniker": "lRmVgGciBK", + "identity": "PYKZImdODA", + "website": "DBfUAAMaGR", + "security_contact": "JTAVthKvsq", + "details": "pphPkYzfvl" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.038203004183403745", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.076026861273924845" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt8n7x4t7x2kvd3dr00mfuuemuc4spvhdt35g05vatvjpfvw5uww53gykr9", + "status": 1, + "tokens": "12005823038", + "delegator_shares": "12005823038.000000000000000000", + "description": {}, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.347986548032108220", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.408132835345187007" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvelvh903wf0ufp2qn3rpt50zlv3ffp0n767urfar7af9jt0ng57k7r3flw", + "status": 1, + "tokens": "5460940542", + "delegator_shares": "5460940542.000000000000000000", + "description": { + "moniker": "jmxfekypVf", + "identity": "rYJvVTdygL", + "website": "FChuyqxLnp", + "security_contact": "SttJEHjrWs", + "details": "HkliJnLUqo" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.045222817456626466", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.290000000000000000" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0lh7y04tmtczvnzltnthy5qvtmdx4tznmwt9z76vhhmd7mn5l5uqal3edt", + "status": 1, + "tokens": "12268746738", + "delegator_shares": "12268746738.000000000000000000", + "description": { + "moniker": "eIPQOnpFIY", + "identity": "VfzwEnpOhp", + "website": "aVNuZBcWNj", + "security_contact": "ZrewdyIwdo", + "details": "rlcRtyUbUJ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.032483401886133298", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.013949228326725611" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg4mn8jk4naald3ysu3uh6cnmpsx3fkxn7xer3nyxlcxfz7lgn5w5f6m46j", + "status": 1, + "tokens": "3204512038", + "delegator_shares": "3204512038.000000000000000000", + "description": { + "moniker": "NeplKMBYoj", + "identity": "mxdKPDhMHE", + "website": "PAYxMlLNXk", + "security_contact": "LOuMtpIRJY", + "details": "jYIxjiLuTD" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.753643962520784250" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq246sxc5kns0ym6st5wyf6mk0x2cayek9wngczyvgk8phxrat02cqh8w5p2", + "status": 3, + "tokens": "49314038732", + "delegator_shares": "49314038732.000000000000000000", + "description": { + "moniker": "caRBWwzxXd", + "identity": "BJSnkbfQjh", + "website": "ELsVPBoBHb", + "security_contact": "nZkoSMuzKV", + "details": "AuAKjeoitI" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.010525961964940541", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.045814731203367877" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdn6uzyl56y7nttklxx49wtfnz925n96ut22xx3s7t8hphp4mrh5g5qkdqx", + "status": 1, + "tokens": "12584124", + "delegator_shares": "12584124.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.426120175355968674", + "max_rate": "0.550000000000000000", + "max_change_rate": "0.085472487593213038" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jhhj4uv", + "status": 3, + "tokens": "26185707851", + "delegator_shares": "26185707851.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.568319127244896272", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.226261076338173049" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5u4v4q5", + "status": 3, + "tokens": "32785129607", + "delegator_shares": "32785129607.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.009044195385937429", + "max_rate": "0.010000000000000000", + "max_change_rate": "0.002281789765845776" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpqq8zx8p", + "status": 3, + "tokens": "33846192792", + "delegator_shares": "33846192792.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.094250378854551281", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.043420993012939508" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtje4agendhh34cze964xcknahtyj03ung7v6k9f73rdpvv435jkzygu99m", + "status": 1, + "tokens": "12090792585", + "delegator_shares": "12090792585.000000000000000000", + "description": { + "moniker": "FUgPTgzyXM", + "identity": "jIsaTnGuhb", + "website": "iSiGeNeqiz", + "security_contact": "JoihWbqCAJ", + "details": "pTYcSzhlzs" + }, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.046150926656790509", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.356235996609570640" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvev2kew00wk3maqq2kducqd4yxum5as5y0h53mlymphr9nx5zmzwhqd43d", + "status": 1, + "tokens": "14322768708", + "delegator_shares": "14322768708.000000000000000000", + "description": { + "moniker": "TulFJTfJnY", + "identity": "vmMScmnlzF", + "website": "ERFHdlJtJz", + "security_contact": "nfAIndXgYy", + "details": "jMtNQrtcFe" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.091341847484127071", + "max_rate": "0.530000000000000000", + "max_change_rate": "0.525538840686318300" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv2xfr6pcx5axa04hegq38yjvz5wm0lj6nkvexrzlxe7lga96sasz656krg", + "status": 1, + "tokens": "4679862773", + "delegator_shares": "4679862773.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.630000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvhgqx90svcvk6htmhwpfudunnc0ne989y7ymdyltcssu7n3p4kw5080886", + "status": 1, + "tokens": "5346735375", + "delegator_shares": "5346735375.000000000000000000", + "description": { + "moniker": "QQnYKozfkv", + "identity": "qdNNaDaxFO", + "website": "KVkHWKnuQC", + "security_contact": "uGwwusIzkv", + "details": "GXvnKqrROd" + }, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.040000000000000000", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.012026445943425172" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv79a2a0wcq9kr62m5yupvx82mlxwxw6hx7c8dyl4trf8k2w7vh3w5wlhy0", + "status": 3, + "tokens": "25066394767", + "delegator_shares": "25066394767.000000000000000000", + "description": { + "moniker": "liMRThtiLT", + "identity": "QPHsvzHnkx", + "website": "BytvAmppJT", + "security_contact": "iBgKxrOkqF", + "details": "RcELAgZeDN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.115126355797501393", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.289658857878369113" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq06lz2fxdcn3tph2mnllznwszzja7vtlpm36t97zgrsycq2mdsw5qcrkuq4", + "status": 1, + "tokens": "321564722", + "delegator_shares": "321564722.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.071992077731645947", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.126011183390291568" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2pm4xasvuf9xsmw3578ask3ucm768pc006d69sj25t2j7gppvxpjvz6ggd", + "status": 1, + "tokens": "3323388806", + "delegator_shares": "3323388806.000000000000000000", + "description": { + "moniker": "PvopDaVlYF", + "identity": "rYVNrGoygV", + "website": "WWXcddCKNp", + "security_contact": "XGuHJIweYZ", + "details": "bEnfQrWihj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.536408027766659140", + "max_rate": "0.550000000000000000", + "max_change_rate": "0.116280242991191159" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4cheaqlnuzhlah5axl68mh50h59me9d4ha070l7w3zncl77dlakzzuj2y", + "status": 1, + "tokens": "441280532", + "delegator_shares": "441280532.000000000000000000", + "description": { + "moniker": "fdDvOsajDQ", + "identity": "gskfjrfYPb", + "website": "dIuOHzjERJ", + "security_contact": "dbVEGOmtZG", + "details": "ksTzbgAXtj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.185461719875081045", + "max_rate": "0.390000000000000000", + "max_change_rate": "0.257360618903198667" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtuw2axfye4m3vrjyu733k608nkh57vj62zx3ew7uzpf5lejemapj8cr7lf", + "status": 1, + "tokens": "10757828517", + "delegator_shares": "10757828517.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.308670693379303631", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.486932455559867167" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq04m4crs7rhxhslqgnakermccrsunsp5zty5awqaevlxhl6amrnq7hav7f7", + "status": 1, + "tokens": "13105570932", + "delegator_shares": "13105570932.000000000000000000", + "description": { + "moniker": "RpRNZcpBLM", + "identity": "ETxJEOvOLp", + "website": "AVbBGDsScb", + "security_contact": "zhzRLvZxjz", + "details": "ZzEmeIwzAT" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.213775811323318868", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.363003369418640683" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfp9mvx6gjdezn2vfxn9jk7jm2urml0xyvt3yg64s03yzkfphrthsdy925d", + "status": 3, + "tokens": "25061237568", + "delegator_shares": "25061237568.000000000000000000", + "description": { + "moniker": "wmxxGOZTpL", + "identity": "azxfwYYUUt", + "website": "izxOUVhQSX", + "security_contact": "lRgXsoitme", + "details": "eebhMKbHXO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.578049895054733896", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.402405887034980654" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc255eyr9", + "status": 3, + "tokens": "76719658246", + "delegator_shares": "76719658246.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.321194785873117781", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.561602155526895676" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u43hapa", + "status": 3, + "tokens": "18750673243", + "delegator_shares": "18750673243.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.188948913118426394", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.274693773376656673" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvpup8kv2mmqajfs08aks8yu8kcuwd323y4f0wu9e3k5grynt0g6ule9mjg", + "status": 3, + "tokens": "24248574347", + "delegator_shares": "24248574347.000000000000000000", + "description": { + "moniker": "bsrCMyYTRM", + "identity": "cTWbJOIMRX", + "website": "EMzKHBarjX", + "security_contact": "spsTAIOECF", + "details": "fTrZtqJTUr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.455524678875180233", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-01T06:29:20Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d29fg079", + "status": 3, + "tokens": "82798702711", + "delegator_shares": "82798702711.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289674444273548704", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.060992257943659564" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfurnf5y576evchnh468a5nmvtcllaysy8nfp5k5g6c6u7g9wzgmjzsg777", + "status": 1, + "tokens": "846166560", + "delegator_shares": "846166560.000000000000000000", + "description": { + "moniker": "ayfTQoiMIg", + "identity": "LfMHyAxOyf", + "website": "NHCLoOenMv", + "security_contact": "NCTWVyOnFn", + "details": "IHwPUxjoSZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.458203476477220958", + "max_rate": "0.520000000000000000", + "max_change_rate": "0.201242757286743245" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgss8cv9u", + "status": 3, + "tokens": "26155915081", + "delegator_shares": "26155915081.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.333198345990187069", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.410926346802169727" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "consensus_pubkey": "cosmosvalconspub1addwnpepqghlm3r37c95q3p3wvr8fxw8mvvdtj3tvhgduhzgzh4238ynz6f06f0rjfd", + "status": 3, + "tokens": "32302576994", + "delegator_shares": "32302576994.000000000000000000", + "description": { + "moniker": "hjulbVDPpf", + "identity": "pRsBrwBRzq", + "website": "VjiSZKAfKB", + "security_contact": "UHZkwTciXO", + "details": "JTfVgehmsi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.311759176624756474" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg2e2fy2hl6cn40sx780nvd228x9u40cfcpjvdnmn3mqfapyjt3m25w8u82", + "status": 1, + "tokens": "2592147197", + "delegator_shares": "2592147197.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.154388662793344854", + "max_rate": "0.190000000000000000", + "max_change_rate": "0.163850436594025444" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqge9z0fefq3xpf8y4q8j57c89x65luk2vtcx5mln75662ukq00f6sqefz8w", + "status": 2, + "tokens": "2439056961", + "delegator_shares": "2439056961.000000000000000000", + "description": { + "moniker": "pGvmyXHQYo", + "identity": "cCQHGXFLSL", + "website": "BaxemamtmF", + "security_contact": "wpZarCOeDy", + "details": "XYyJPmrQVh" + }, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.209082457058936007", + "max_rate": "0.470000000000000000", + "max_change_rate": "0.166552912196145925" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgmnkn2nw2c6m0s6nrrcyxksg9j50sesj03xzxa867yvgrzw6rhgjc45yeu", + "status": 1, + "tokens": "2814501210", + "delegator_shares": "2814501210.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.336015918058412894", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.176369444038449060" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvqtq2puvhmk7g8aa2fzxkjrjrvq2hfczxjcvfal8gtzjm7tts96kcamd4h", + "status": 1, + "tokens": "2290999526", + "delegator_shares": "2290999526.000000000000000000", + "description": { + "moniker": "rFekQzBUob", + "identity": "TkgdArxYHD", + "website": "jYCJcCQhAu", + "security_contact": "yLZXwubFtr", + "details": "axFdLIokGQ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.015694038805586186", + "max_rate": "0.070000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwus66jdl", + "status": 3, + "tokens": "56132991892", + "delegator_shares": "56132991892.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwvdjhxcmtkq3y39crkc6ue3q2xdgct97gggllt8a4wyuquyf9u26sv45pf", + "status": 1, + "tokens": "290004202", + "delegator_shares": "290004202.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.497656780906410782", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.491445719567726825" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22ep2k8n", + "status": 3, + "tokens": "69316998057", + "delegator_shares": "69316998057.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.624946300778690751", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.204995912261423056" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7ejhy28", + "status": 3, + "tokens": "27808118568", + "delegator_shares": "27808118568.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.067795278161998694", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.011309118617844055" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2qka3fe9l70y756uvhnkwe0c97sezs7zgnycyhzu4p5s3s4pyknyyl8jld", + "status": 1, + "tokens": "5061822", + "delegator_shares": "5061822.000000000000000000", + "description": { + "moniker": "qEQLmGTBiG", + "identity": "wNJiWXVlVi", + "website": "hReLoZUBPy", + "security_contact": "aDUuPIORAJ", + "details": "TeGFgrskCn" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.135094086175297130", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.696694600733795075" + }, + "update_time": "9936-01-01T14:57:22Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv8t92hg5h8d39cmznd7xfwudv744yj782rg7jx6utajy3xyzfypg4uzdww", + "status": 1, + "tokens": "2859472400", + "delegator_shares": "2859472400.000000000000000000", + "description": { + "moniker": "zZjxsrcHrs", + "identity": "BLTqCTkKhq", + "website": "zvZKSjOSUy", + "security_contact": "WikLlTuZzi", + "details": "LrLZfZwnhm" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.544886660428311705", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.378178897656383282" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwpunsvkz6dm8s4ngxsnzrk4hhlgtg92t2a0wprx9hyrxgun9nn9757k8v3", + "status": 1, + "tokens": "3988607104", + "delegator_shares": "3988607104.000000000000000000", + "description": { + "moniker": "POXTKVuPoD", + "identity": "OiWrlmnspg", + "website": "QuNFffPKCw", + "security_contact": "rfNvnRkTVg", + "details": "HLsWBpcSqd" + }, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.343304845161180522", + "max_rate": "0.490000000000000000", + "max_change_rate": "0.116969381604757084" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "consensus_pubkey": "cosmosvalconspub1addwnpepq28hkvfszngpgcpgkl9gtmjymhmfsdwhaw2zkx4sxqfu46kg7vp5xzr9uv0", + "status": 1, + "tokens": "9369781513", + "delegator_shares": "9369781513.000000000000000000", + "description": { + "moniker": "pczevQdeVR", + "identity": "upAiEfAggi", + "website": "ukoOQsgvEg", + "security_contact": "RoswibAKjH", + "details": "TPKPhtpeXJ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.096467243339835350", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.265046884965878837" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd9rxlxauf0f8wdquzctrg47q24aa3n20rel24g7wn8q2xyyy2cmwupr6a4", + "status": 1, + "tokens": "1274375295", + "delegator_shares": "1274375295.000000000000000000", + "description": { + "moniker": "pjGZMgAqSL", + "identity": "YueQESEyAc", + "website": "gwkHHPESDC", + "security_contact": "AoLWQlBJNV", + "details": "MOxSfCDGor" + }, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.075454810910095894", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.271996952866730673" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5kc0mzw", + "status": 3, + "tokens": "17750303222", + "delegator_shares": "17750303222.000000000000000000", + "description": { + "moniker": "uloyQQWkyI", + "identity": "gFyXSGlhKI", + "website": "ewFltsApZk", + "security_contact": "YGvOhkEKJw", + "details": "vIoOsfiLuj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.068730439287548849", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.118090772640391070" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv6fqe8ryspqh89rpj76xxts4ghsfqws3329ryzhr6cygp934r02qdu0n74", + "status": 1, + "tokens": "14451940598", + "delegator_shares": "14451940598.000000000000000000", + "description": { + "moniker": "BGKhZzgXnx", + "identity": "cWftKUzHxI", + "website": "uaBFHXLzdc", + "security_contact": "ojiAxIqYZm", + "details": "lhxhGPjSnO" + }, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.395437548795457889", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.734660769451270652" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgpthjaszzcvylsczd42sr0lhanxdjkx07ec2r0g27mpwcmw55z0vuwt4te", + "status": 1, + "tokens": "6855101203", + "delegator_shares": "6855101203.000000000000000000", + "description": { + "moniker": "igDzTpVrSP", + "identity": "dvrbdNdcAV", + "website": "VaCxEpXRvn", + "security_contact": "JWxZxskHFt", + "details": "PtGTDRDCnm" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.590000000000000000", + "max_rate": "0.590000000000000000", + "max_change_rate": "0.467061941487853246" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0p646z0m699gujd2cavmh4qjmjy64044a50m4a2vhgmkn3g44jd5d95cf6", + "status": 1, + "tokens": "1751100", + "delegator_shares": "1751100.000000000000000000", + "description": { + "moniker": "twWaSNBAIU", + "identity": "XDOGNsvuzS", + "website": "isTBaTsfhg", + "security_contact": "dNcKvjBXgo", + "details": "qRhvNKpZan" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.439573589792496242", + "max_rate": "0.950000000000000000", + "max_change_rate": "0.285729710011181846" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw4vh38c7e44vpvszes4lcvjkz3ah25sja3jyj8a2jyfk44fn033xtu5ld3", + "status": 3, + "tokens": "22144783949", + "delegator_shares": "22144783949.000000000000000000", + "description": { + "moniker": "cJZANkQgEs", + "identity": "BMLCKDJfbU", + "website": "EvRCcPcNDz", + "security_contact": "wYcIjPQECa", + "details": "FTToLCGlSp" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.490000000000000000", + "max_rate": "0.490000000000000000", + "max_change_rate": "0.478812992279810912" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4hew3dkv9ytm47sg7767ktkthyt4jqgednnvcnhnzqx4fznylc2w43mgk", + "status": 1, + "tokens": "8457816494", + "delegator_shares": "8457816494.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.470000000000000000", + "max_rate": "0.470000000000000000", + "max_change_rate": "0.313668195250471906" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfvnelws9nysntl02t3hn42jsvg37krjan0y9ef0ff6qvyyeuflqxmtvcak", + "status": 1, + "tokens": "13735096388", + "delegator_shares": "13735096388.000000000000000000", + "description": {}, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.080430191050080691", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw0gk7g6ldfltzcg4evfrv6g75hp9d9raerpg574606nwrv8zy8fsu5f4kr", + "status": 1, + "tokens": "3931843209", + "delegator_shares": "3931843209.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.111839100753178310", + "max_rate": "0.520000000000000000", + "max_change_rate": "0.203190440691763416" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf5qh85wpx6k2c76xt38sxea46jc7929269hg8x9ddjeexhgrggjsr3mkxf", + "status": 1, + "tokens": "10075773258", + "delegator_shares": "10075773258.000000000000000000", + "description": {}, + "unbonding_height": "14", + "unbonding_time": "9936-01-01T21:44:15Z", + "commission": { + "commission_rates": { + "rate": "0.479310313704029644", + "max_rate": "0.950000000000000000", + "max_change_rate": "0.366540822300243268" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv0pnal4w8hydpq3vydqgjxmmxz7zg2g9lsj5vedvjq3pw6typfdcjfm5tc", + "status": 3, + "tokens": "16214844041", + "delegator_shares": "16214844041.000000000000000000", + "description": { + "moniker": "jKdcmnPYfC", + "identity": "exfUuYgqmd", + "website": "XdNCNZIBOf", + "security_contact": "hmiwPGchGt", + "details": "nUnBufZQah" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.330000000000000000", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.051583680374523519" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057uxwdfy", + "status": 3, + "tokens": "23352431465", + "delegator_shares": "23352431465.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.760000000000000000", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.183753469845780730" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvy095yf8a7eknhlnwzkum0wt53njxxww60vte7qkutwczt534dwhaclpm", + "status": 3, + "tokens": "34693121909", + "delegator_shares": "34693121909.000000000000000000", + "description": { + "moniker": "RuzZVxWXdB", + "identity": "QjsgdqaNzA", + "website": "UtlkBZyIyQ", + "security_contact": "vnsfyiwxFP", + "details": "dOxLDmGKTb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.005447024365505786", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.005395717096845063" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv368hqruqrftx368wx44f2uaslv95nk3dx7mahejcnruuqhfx9j5sf92lu", + "status": 1, + "tokens": "1577104716", + "delegator_shares": "1577104716.000000000000000000", + "description": { + "moniker": "ZcNwYceFVl", + "identity": "JdwwNpKEGe", + "website": "kIuDSvfEZG", + "security_contact": "kRdEoRVCNt", + "details": "ZxpAkBmyNU" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003879511693068742", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.037055319272782376" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd265f66tdc7mtewx4ayd6d4lls7m4ma9eehyac8s8jn93gxkw0k67nnaz4", + "status": 1, + "tokens": "6210644973", + "delegator_shares": "6210644973.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.096355762649540376" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf4ddylkupthgx8vutwclv8y5m3e5yzya2xsl84hl3fhth7y5xdm73esmg0", + "status": 1, + "tokens": "81861609", + "delegator_shares": "81861609.000000000000000000", + "description": { + "moniker": "aVoFaCLctw", + "identity": "UsuBjrjybt", + "website": "maJLZCDTDo", + "security_contact": "FrZMSAYCke", + "details": "HvsjSBlFEH" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.580000000000000000", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.276569602915150076" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef5gg2q6z", + "status": 3, + "tokens": "42958814024", + "delegator_shares": "42958814024.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.077000158168963029", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.197697608060710078" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwv7ukq0", + "status": 3, + "tokens": "21734647779", + "delegator_shares": "21734647779.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.460679550676466675", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.165088210560206816" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwc7h5wds8u3tspx3mwpfh5l3q3rv0t6ff33dt205v2zy2kxev9sykcs9uv", + "status": 3, + "tokens": "29256610441", + "delegator_shares": "29256610441.000000000000000000", + "description": { + "moniker": "iYUgQcrziE", + "identity": "hDYXNaKKIu", + "website": "FYsreoPnoD", + "security_contact": "FGAHzGKfjM", + "details": "gkHwWfssaE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.585764113115952818", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz4r8scm", + "status": 3, + "tokens": "65051132532", + "delegator_shares": "65051132532.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.041535797793389960", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.029250263820409753" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2cxeaw4", + "status": 3, + "tokens": "18897052265", + "delegator_shares": "18897052265.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.416117321788354038", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.139830256647094326" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgr3yz0pw3dl98dsljzz82u99665wlgyya6ymlhm7vgjypm39jwky55t0wz", + "status": 1, + "tokens": "859335658", + "delegator_shares": "859335658.000000000000000000", + "description": { + "moniker": "wCDTSgWkyH", + "identity": "TitohQmURH", + "website": "RyINWHhgOo", + "security_contact": "hEOUeRXHVg", + "details": "SyWWUTsVOf" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.230769629091954646", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2897we7j0jrf6mg2c7z2vekjpvq4m4rrqpdmpxe7ccnac5smad7zn0jfs4", + "status": 1, + "tokens": "220717877", + "delegator_shares": "220717877.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.278689953722191028", + "max_rate": "0.400000000000000000", + "max_change_rate": "0.399029965743980239" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvj4d7pjfcg6fcckuyh02wkr8vtz82zttnsu2f7say2pwsvyxn52ukma7rw", + "status": 1, + "tokens": "13032730128", + "delegator_shares": "13032730128.000000000000000000", + "description": {}, + "unbonding_height": "6", + "unbonding_time": "9936-01-01T04:22:01Z", + "commission": { + "commission_rates": { + "rate": "0.022505950976301605", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.206573380377502263" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "consensus_pubkey": "cosmosvalconspub1addwnpepq055lazk86cjz6r0s6jgcj7454fm7lscn6ylxwq5stu7lxxve6c8z06lkn6", + "status": 1, + "tokens": "11306383136", + "delegator_shares": "11306383136.000000000000000000", + "description": { + "moniker": "HOVoWzOKbt", + "identity": "TRrmFJQkpB", + "website": "vrfqAOrjMr", + "security_contact": "EqTmbIKhye", + "details": "ORcULZRUGZ" + }, + "unbonding_height": "6", + "unbonding_time": "9936-01-01T04:22:01Z", + "commission": { + "commission_rates": { + "rate": "0.056078612663796658", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.153970901287451505" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt6v4va58n8u0husyys4q2qk258zswwu2m8xh8wq3te6jlg45zcjxkzwshv", + "status": 1, + "tokens": "3015113626", + "delegator_shares": "3015113626.000000000000000000", + "description": { + "moniker": "JZQBeDfYam", + "identity": "FOuxhBHERr", + "website": "ZnmsIAxQfc", + "security_contact": "BxbYtUYFOq", + "details": "OPBuXPYqua" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.098869115736485868", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.013331374901399054" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf26xhga7sa872e20kwjg5wglmv508l9ukcq43k7alqqnjsqq0wrshcyrgw", + "status": 1, + "tokens": "9845542377", + "delegator_shares": "9845542377.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.577150493662706545", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.880000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xf32mjfqeg39dq7qczchp67zznleqkvvycu823a5d689tapae7svdnv4s", + "status": 1, + "tokens": "8373562844", + "delegator_shares": "8373562844.000000000000000000", + "description": { + "moniker": "iUBnDMOhbM", + "identity": "iTSmKytwsB", + "website": "PUhHbruKjv", + "security_contact": "fetNYhEAsc", + "details": "uhcPlrOTgR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.048109597870365501", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazfcl7f9", + "status": 3, + "tokens": "27157083976", + "delegator_shares": "27157083976.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.170000000000000000", + "max_change_rate": "0.024288054259102348" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgxqjc3u3", + "status": 3, + "tokens": "45028692546", + "delegator_shares": "45028692546.000000000000000000", + "description": { + "moniker": "UeFBWJANuQ", + "identity": "gypzUiAlRd", + "website": "zZezcKCiKy", + "security_contact": "KSXTvslQOC", + "details": "qqNIBlVIYk" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.075610127679217055", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.290000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xwmrp7sq", + "status": 3, + "tokens": "35018830437", + "delegator_shares": "35018830437.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.405901469124460870" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "consensus_pubkey": "cosmosvalconspub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc92g545rl", + "status": 3, + "tokens": "17547285969", + "delegator_shares": "17547285969.000000000000000000", + "description": {}, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.073548473514397047", + "max_rate": "0.440000000000000000", + "max_change_rate": "0.413655116572301617" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wyr7x83", + "status": 3, + "tokens": "25071600389", + "delegator_shares": "25071600389.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.280000000000000000", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.063599161373317498" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymswdv67m", + "status": 3, + "tokens": "27784307296", + "delegator_shares": "27784307296.000000000000000000", + "description": { + "moniker": "mjkYspzJbE", + "identity": "xWPMeIdPEi", + "website": "xtRPXfTiQB", + "security_contact": "sdKpqtdpNe", + "details": "MnLujfMpnW" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.072530327063185081" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgwr8xnwk6058r9yaatj26xt570h6mzfs56tnn2tkg7y3jyp356qzqaxfg5", + "status": 1, + "tokens": "1252735315", + "delegator_shares": "1252735315.000000000000000000", + "description": { + "moniker": "UfkjaibOXz", + "identity": "vVVQmleZuk", + "website": "FKRiuhRQvX", + "security_contact": "UHCcLIotsR", + "details": "pEGZETWPPx" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.156679971641128810", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.026853734634610978" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfnc9pflwwv469nrpv8nave7hqd2v4w3ycuzeqk2un0sp5rpt468yx200mn", + "status": 1, + "tokens": "5701177554", + "delegator_shares": "5701177554.000000000000000000", + "description": { + "moniker": "dkViUcHton", + "identity": "lVYfRBBpgr", + "website": "rSpBvDfDVx", + "security_contact": "ZorwmBCgci", + "details": "qfbWDZBvMb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.417793530644749589", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.038374060737037578" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xu8de8m8m8r6s3gdlzevgnuyjxqnerdhdt27a89w2euju4urw8yap7cgs", + "jailed": true, + "status": 1, + "tokens": "35282247366", + "delegator_shares": "36246439673.000000000000000000", + "description": {}, + "unbonding_height": "25", + "unbonding_time": "9936-01-02T19:37:57Z", + "commission": { + "commission_rates": { + "rate": "0.004077496600532069", + "max_rate": "0.110000000000000000", + "max_change_rate": "0.018535351790808554" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtagppnl0ywh6x75gstk6jrws2x0zq0vxz89663enl6sjgmwhphacultfnr", + "status": 1, + "tokens": "4474063302", + "delegator_shares": "4474063302.000000000000000000", + "description": { + "moniker": "SiJCcmpLbs", + "identity": "qjRTuyXVcs", + "website": "sijVVYMurZ", + "security_contact": "MOCCXUuDrR", + "details": "YXkSdbNCBu" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.056403203424930785", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.014536927316112510" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdhcupcamks7erjfhcvl7f0ec9032vygtnraq5xg6uehjy0amzwmq9fx4zk", + "status": 1, + "tokens": "9095777401", + "delegator_shares": "9095777401.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.400000000000000000", + "max_change_rate": "0.244970091744442833" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslqg7mlcx", + "status": 3, + "tokens": "31634692393", + "delegator_shares": "31634692393.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.554757466700447989", + "max_rate": "0.820000000000000000", + "max_change_rate": "0.408903182457515462" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "consensus_pubkey": "cosmosvalconspub1addwnpepqta2kryj27uenxysne52plp50tn9tnc5t8nd2geytjcht6c68yppzcdpk3m", + "status": 1, + "tokens": "11760329682", + "delegator_shares": "11760329682.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.180898114093371403" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtcpp77982hl5fhudkwv9mr6aqf3ree6t34697uvuqptnh6kj4ys5ac3qp9", + "status": 1, + "tokens": "602352708", + "delegator_shares": "602352708.000000000000000000", + "description": { + "moniker": "UNASSmlKTo", + "identity": "uhyuVrXWrq", + "website": "XlFrUaNLQq", + "security_contact": "rdHjnqyqLX", + "details": "bveclkOpHZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.044812571984808905" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdn9m93wfkj62hphl0uep7etngtrwe6mtl6gaf8f9e3a7f7g55npyzazlp7", + "status": 1, + "tokens": "4639932033", + "delegator_shares": "4639932033.000000000000000000", + "description": {}, + "unbonding_height": "13", + "unbonding_time": "9936-01-01T19:46:26Z", + "commission": { + "commission_rates": { + "rate": "0.024626991093728218", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.080004865482248970" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdwwmumvva86wmx94fr3hgtnt8gs40wxy3wt2heja430emv5lxxuvhs2a98", + "status": 1, + "tokens": "556310530", + "delegator_shares": "556310530.000000000000000000", + "description": { + "moniker": "dvrxlOManf", + "identity": "HtMpzaSHDR", + "website": "HqMSLZlkMi", + "security_contact": "CgMEsBUltB", + "details": "FBVqqAFKIJ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.068210196325086922", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.053045144913425869" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt6hn4flrkuvequxy2hhhzddud4tdm5xnwh5agjcqsa4gjec5xjy2n0m9wd", + "status": 1, + "tokens": "554885714", + "delegator_shares": "554885714.000000000000000000", + "description": { + "moniker": "TBWFksRoPx", + "identity": "iVVIAmyigu", + "website": "DTkHTlrvWr", + "security_contact": "DEYqAUJlvV", + "details": "nNnVeluJnY" + }, + "unbonding_height": "6", + "unbonding_time": "9936-01-01T04:22:01Z", + "commission": { + "commission_rates": { + "rate": "0.286897474578479181", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.330000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvlfyhyylne6t33wzse5vhjd3xxyrfkjfmdyvk3gq4rrdhe2e0ul2n637uw", + "status": 3, + "tokens": "22383796110", + "delegator_shares": "22383796110.000000000000000000", + "description": { + "moniker": "MCiuCZVGkF", + "identity": "YVlJRRVogl", + "website": "iBpLGvpPpo", + "security_contact": "bvXcaUSxzJ", + "details": "zsHdsXWXhJ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.012334216153398550" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v67hlsk", + "status": 3, + "tokens": "16236700229", + "delegator_shares": "16236700229.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.498536222135788025" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5l4jsmp", + "status": 3, + "tokens": "42937175180", + "delegator_shares": "42937175180.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.190381602916620701", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.303876600993529705" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdvv5qzxgfwadnygspjwln9c0hn663hz5p65uqf3fzscf0plz577ue0gul8", + "status": 1, + "tokens": "5288336779", + "delegator_shares": "5288336779.000000000000000000", + "description": { + "moniker": "wVQZezVdLb", + "identity": "trDgyJlGtA", + "website": "ohCubujIxo", + "security_contact": "tRTgDjAAVX", + "details": "JqjcImFcXx" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.084545351965758511" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g7drc35", + "status": 3, + "tokens": "36911230696", + "delegator_shares": "36911230696.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.194945225911581915", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.300000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcas8xka", + "status": 3, + "tokens": "39363181311", + "delegator_shares": "39363181311.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.028169322828760497", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcvjsxyz", + "status": 3, + "tokens": "27734813665", + "delegator_shares": "27734813665.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.015116864220436494", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd5nsxkua92z9eamd4hccf0pxeh3chye2475vcrwc22dpxj4lmkvuy950w7", + "status": 3, + "tokens": "27605610764", + "delegator_shares": "27605610764.000000000000000000", + "description": { + "moniker": "RLaOPuFvKx", + "identity": "LQfktbUgZN", + "website": "JiRhAUTjQG", + "security_contact": "LTGuZUEvcW", + "details": "QjLWSYAXxH" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwsa0gtfg8nxze044y6vynaz5f5z0kz4ar9tghvyr9cpacl28c76k8cfuys", + "status": 1, + "tokens": "13127630955", + "delegator_shares": "13127630955.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.087006240044684328", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.090651017996866531" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskj3a67t", + "status": 3, + "tokens": "24423311847", + "delegator_shares": "24423311847.000000000000000000", + "description": { + "moniker": "OtyVVqWsup", + "identity": "EqaejuaTwX", + "website": "egvJRLAnYF", + "security_contact": "KTzlQLiomS", + "details": "ETXsigXuTY" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.372711230134865265", + "max_rate": "0.460000000000000000", + "max_change_rate": "0.056760418592473079" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjzxhelr", + "status": 3, + "tokens": "25592800910", + "delegator_shares": "25592800910.000000000000000000", + "description": { + "moniker": "NYvAvaIOdj", + "identity": "lYbVDursvX", + "website": "UXtFzZcHjM", + "security_contact": "PNNMeOJqcl", + "details": "ROVIgdvaJl" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.193312772989594496", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.226297820963910157" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvvur4tyyl553c4jeyvce0w3d0ezrrmsr6a2kcdksca4wpflc3lj7nf6fm9", + "status": 3, + "tokens": "25675698411", + "delegator_shares": "25675698411.000000000000000000", + "description": { + "moniker": "wDAGDTplVL", + "identity": "VUJoHvcuZs", + "website": "JzvbSfINxu", + "security_contact": "cROcYcTImn", + "details": "bdBDwVnOvM" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.108086670177688287", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.123495090782214164" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsuh3jpet", + "status": 3, + "tokens": "50488222690", + "delegator_shares": "50488222690.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.801397182624616334", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.592521503076154232" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00kz7uf8anh6gpaq5gucxz5u5jxfk75w73c0f4hx3mrevz6wxe5xtvq7c7", + "status": 1, + "tokens": "12112810368", + "delegator_shares": "12112810368.000000000000000000", + "description": { + "moniker": "hhrNeMimUt", + "identity": "wKniwVmzBB", + "website": "RWhKssqoAD", + "security_contact": "HhssEHikTn", + "details": "GKXcfnFtEp" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.073730825899332452", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.038867571778125676" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfk090csv4thlsr4kx3fuucwcsk79lqs6gr5zse6m4xmwpq94hy2w3yuqp6", + "status": 3, + "tokens": "20659893696", + "delegator_shares": "20659893696.000000000000000000", + "description": { + "moniker": "gqjwubbLDT", + "identity": "OsKsdzWbsv", + "website": "rhWGeqAAVi", + "security_contact": "FmaEvvcaAr", + "details": "uMULjHPlYr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.168812875456833709" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5t7pxck", + "status": 3, + "tokens": "53644768786", + "delegator_shares": "53644768786.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.180000000000000000", + "max_change_rate": "0.029528662482337368" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2z47zet", + "status": 3, + "tokens": "21168715051", + "delegator_shares": "21168715051.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.026318239077074162", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.076792434560738120" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0xgzvwtkwtmwqv3l4d4jf3je2qvw5u2s8fcduejf33r8lykwlrzyp5q9fz", + "status": 1, + "tokens": "1370590721", + "delegator_shares": "1370590721.000000000000000000", + "description": { + "moniker": "YxkFqQLCVj", + "identity": "svwKmwRNzU", + "website": "HUYRlreMTk", + "security_contact": "yooYsHUCBp", + "details": "gOGDDEidDB" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.545893826392769667", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.592139558969935420" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyw0np92", + "status": 3, + "tokens": "27374742411", + "delegator_shares": "27374742411.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.053895535796610462", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.182737583024108345" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0hcte6yrzm8ppqms3l3vw92tc8cqqdacl8wkavpcjshum9a0rty23cs5d8", + "status": 1, + "tokens": "418488641", + "delegator_shares": "418488641.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.860000000000000000", + "max_change_rate": "0.273402402333309888" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq242jjldxy02w8e4d8mgh6tx6k9rdhy0rgn56wac2ng7gvjsc8yn7zw7qry", + "status": 1, + "tokens": "2878820932", + "delegator_shares": "2878820932.000000000000000000", + "description": { + "moniker": "FajtVQhfyD", + "identity": "LJBphWhRiy", + "website": "KonhZigFqm", + "security_contact": "kMzJQasgzg", + "details": "BksWuXHzKo" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.143184564002944268", + "max_rate": "0.820000000000000000", + "max_change_rate": "0.610269825406512777" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2al69u7pnek9kcrmz83vstrst5szxuz6z03z0d848kuh3ekkjlfgr96q6z", + "status": 3, + "tokens": "20929858941", + "delegator_shares": "20929858941.000000000000000000", + "description": { + "moniker": "ciowxbJZpb", + "identity": "XgDAZmwEir", + "website": "moPXkGzyqT", + "security_contact": "WTLysotltH", + "details": "qoTHCiKGoL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003240694138410597", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.013650990946439583" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtq4rjflca8vgyn08w3vkpqeq57d80dmja25rd0ntqrx5fxm96gtw0umkjg", + "status": 2, + "tokens": "4345178144", + "delegator_shares": "4345178144.000000000000000000", + "description": {}, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.639608494106780282", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.911798500947612916" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "consensus_pubkey": "cosmosvalconspub1addwnpepqttlhe35hucrdjdhcyrnnv3kggwjw8lzmhfv7hz0vc6zvmez729rjwfq94s", + "status": 1, + "tokens": "14505496415", + "delegator_shares": "14505496415.000000000000000000", + "description": { + "moniker": "hwGSrtUOYW", + "identity": "VSuEnzJoTP", + "website": "SKivYdHQYd", + "security_contact": "nQkFUJMUsq", + "details": "BPIGoQzJZW" + }, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.314247563815691088", + "max_rate": "0.430000000000000000", + "max_change_rate": "0.414706550102643413" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwz7uypw37mz5eky5vktatrwu84geyy9r8jp9dccd73kw62x5hkn54qgedr", + "status": 3, + "tokens": "15286357237", + "delegator_shares": "15286357237.000000000000000000", + "description": { + "moniker": "rXurTMjZPL", + "identity": "AwsdgVtWKY", + "website": "MqIvWlvqZq", + "security_contact": "hoJFiVyrtB", + "details": "FWXLLEocRp" + }, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.298667840621478601", + "max_rate": "0.620000000000000000", + "max_change_rate": "0.023377726384901617" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "consensus_pubkey": "cosmosvalconspub1addwnpepqddlzcmsy4vds97qxa5a5xs4mvgeyp9zhmm7fqfdr888nhp0sftrjk0thpa", + "status": 1, + "tokens": "4986207023", + "delegator_shares": "4986207023.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.079386028745799977", + "max_rate": "0.180000000000000000", + "max_change_rate": "0.113889826113494810" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzvca96h", + "status": 3, + "tokens": "70162120947", + "delegator_shares": "70162120947.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.545864029263808659", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.533310660658318421" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2vpcxra7jn5ph969c4cnj2qngyr09hzyssh4m2rvwkneqt2x00t78j79g7", + "status": 1, + "tokens": "6943791722", + "delegator_shares": "6943791722.000000000000000000", + "description": { + "moniker": "iHZLPGVqoj", + "identity": "PTMFoKCCDe", + "website": "cqKrWoBVHG", + "security_contact": "ZdbkzGqONL", + "details": "hyVBYChgSt" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.730000000000000000", + "max_change_rate": "0.113078578358113548" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqlk7nha", + "status": 3, + "tokens": "20279593182", + "delegator_shares": "20279593182.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.069908236020668720", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.009891358364124589" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgm73g3mrpuk5y0aykvt6zmtpassp8qwu5r4hxrlw8umkqdw6wk5knmfc95", + "status": 1, + "tokens": "6203555675", + "delegator_shares": "6203555675.000000000000000000", + "description": { + "moniker": "SRtaYtDodq", + "identity": "EXTHehjjeA", + "website": "XNnGTPSCSg", + "security_contact": "DDCUFBlRis", + "details": "tFjYKNDXoU" + }, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.094086925383675139", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.386267985496281026" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdlvalhvj0k0kqflaruuvyxjndwjaepha9wm0mphnauaf4tpjy0rzt5nu3n", + "status": 1, + "tokens": "9559456877", + "delegator_shares": "9559456877.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.157603606207056866", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.184901704338581434" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2wk8eudh28aeukdvn2w25d0ywdsrzyvp59xs869e9h9vdu4lw9c5zzw53t", + "status": 1, + "tokens": "13387012198", + "delegator_shares": "13387012198.000000000000000000", + "description": { + "moniker": "bhiZzQubAq", + "identity": "sDcgOtqEmT", + "website": "XCWWoDyVlS", + "security_contact": "esVFcCqRSm", + "details": "gOhHAReWMI" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.450000000000000000", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.179817022007454543" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0y2whh2mx9stzswaxevw5ku8aznuvf0dgaznc4z8wz6fc4ahy35cgvq7km", + "status": 1, + "tokens": "11031151085", + "delegator_shares": "11031151085.000000000000000000", + "description": { + "moniker": "OnUJlqhYgs", + "identity": "QxZSMomSDp", + "website": "SSAuEgkyZs", + "security_contact": "yZapBDsgPP", + "details": "lKjpewmQsy" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.421539780269441578", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.298023294439709308" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqva0a8amjektwyshzjv38f6dw5uwat88kscw834kf3026r5ksn77gf0857j", + "status": 3, + "tokens": "31584297936", + "delegator_shares": "31584297936.000000000000000000", + "description": { + "moniker": "BKQyTeKaLC", + "identity": "eCoPebxrNV", + "website": "auQgzJBeZR", + "security_contact": "bLlknxqKWU", + "details": "amiXFmUGDr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.900000000000000000", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.031968764827487641" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4cv2x09p", + "status": 3, + "tokens": "22768989048", + "delegator_shares": "22768989048.000000000000000000", + "description": { + "moniker": "EVTkHBKcpE", + "identity": "hMErYohFOn", + "website": "QaWaMRxOKv", + "security_contact": "qaxyuRDTeX", + "details": "ELwgPpPDKw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.386471695225710439" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfjcp62cfnelz8s5cl5qar8ymfjd5sjjkkr4tayrqrtzpf638hkjqmg9q4z", + "status": 3, + "tokens": "26491705865", + "delegator_shares": "26491705865.000000000000000000", + "description": { + "moniker": "SJeSnSdrXp", + "identity": "OTlQTOJbcV", + "website": "sulWDbaxDh", + "security_contact": "XTGtIDYHdJ", + "details": "KNeohKLilE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.965860683215034339", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.778196912581936923" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfjswqwlt6yc0lrcmyae0pqya6ymquatdrg9uufx94m6p3fwxqz9x86858h", + "status": 1, + "tokens": "3691290116", + "delegator_shares": "3691290116.000000000000000000", + "description": { + "moniker": "iDjKsiEeDb", + "identity": "XDKHVzYbNp", + "website": "tknKYmQsoF", + "security_contact": "LFqBNfJYwo", + "details": "SrLmeyDcge" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.016082191317166724", + "max_rate": "0.400000000000000000", + "max_change_rate": "0.400000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvvxtcls2a9qfjq04usrzv3ekvavu52z7twu9w3fguenpjett5zpwf62rq6", + "status": 1, + "tokens": "243264064", + "delegator_shares": "243264064.000000000000000000", + "description": { + "moniker": "OwEuBzkAXt", + "identity": "sKregrkhvp", + "website": "QFkaaTPgBS", + "security_contact": "LWqWzpgBBK", + "details": "IiZKuDsnyX" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.871101859572202690", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.754875918298597546" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "consensus_pubkey": "cosmosvalconspub1addwnpepq28myc67l0yhmnn6n2vq8hcmpaxesglyyqg825ujgrxdt9afwlsfx4ezupt", + "status": 3, + "tokens": "16257375002", + "delegator_shares": "16257375002.000000000000000000", + "description": { + "moniker": "mtHVFaNGLx", + "identity": "YTyhLHiifY", + "website": "JFeCDRXGYc", + "security_contact": "HndWqVmQvE", + "details": "JFVkeOUSbg" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.018292046092814578", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.057525240491425891" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfjk3l28hkcd6jl265j6aypx77uqhm4hjwq6j75klu4apy6gl6ze74v7crf", + "status": 1, + "tokens": "9606051750", + "delegator_shares": "9606051750.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.792362515287976876", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.568773929640711892" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgzjwcddk2z8kmnvgh2yyftgqknzry0cp2f9g7tlprezsj3p8yupxjptgj3", + "status": 1, + "tokens": "3200537612", + "delegator_shares": "3200537612.000000000000000000", + "description": { + "moniker": "YxQFCVeXka", + "identity": "uyuvPGTQiI", + "website": "fBprqrDUjJ", + "security_contact": "mqBJzLfJmq", + "details": "GiBjnTfluH" + }, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.103237315548430953", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.117703304223005248" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z6ckp5s", + "status": 3, + "tokens": "62801915451", + "delegator_shares": "62801915451.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.323440196337864016" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf2lh963ms2dlnvtq586ccq3spt7deacf46yf9r3h4ze7sdtpqn42uaajd3", + "status": 1, + "tokens": "365167856", + "delegator_shares": "365167856.000000000000000000", + "description": { + "moniker": "YKpfxbRPDU", + "identity": "HVMtZxINmC", + "website": "MPNkKSEpFt", + "security_contact": "PAebSVjNmN", + "details": "vnIHnmwiHU" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.090000000000000000", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.081458810641796929" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng9t438v", + "status": 3, + "tokens": "22515450726", + "delegator_shares": "22515450726.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.752425052602923482" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6mcm2m0", + "status": 3, + "tokens": "29556680915", + "delegator_shares": "29556680915.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289048467390880739", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.476925303769745140" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswzcmkck", + "status": 3, + "tokens": "25121635132", + "delegator_shares": "25121635132.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.541820589241677763" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "consensus_pubkey": "cosmosvalconspub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z2xdtk5", + "status": 2, + "tokens": "6699765497", + "delegator_shares": "6699765497.000000000000000000", + "description": {}, + "unbonding_height": "50", + "unbonding_time": "9936-01-04T22:14:51Z", + "commission": { + "commission_rates": { + "rate": "0.493962290871886167", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.601549819261141285" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt5fpnmky0a402kgyu04yww96a839ydaxaakw75da6xq6n2d8evcuu06j8t", + "status": 1, + "tokens": "7029801264", + "delegator_shares": "7029801264.000000000000000000", + "description": { + "moniker": "dEbLKTkCfp", + "identity": "chpFnPbjeE", + "website": "hIVhzrwvGR", + "security_contact": "tdkZcmEEtp", + "details": "qIYHtPoIsA" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.170000000000000000", + "max_change_rate": "0.165881689721229366" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vype2jq", + "status": 3, + "tokens": "59694062218", + "delegator_shares": "59694062218.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.047504130944412074", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.160000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgh9l47dn4d09k6xlkwun4uyk07x6979ca2rm6jnuzdredu0m83t25sptkv", + "status": 1, + "tokens": "3092598821", + "delegator_shares": "3092598821.000000000000000000", + "description": { + "moniker": "utphwLfvOM", + "identity": "qzMWKFjmzr", + "website": "sEXBMEaMuK", + "security_contact": "lyindsAreq", + "details": "CTVKoYhpCk" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.061272647435103109", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.141473987309465922" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfzsv864d6pzxm7jr4fnjd0u74phhasnmhne8tp9xk2nwu9j0m7rz67sj3x", + "status": 1, + "tokens": "9239149167", + "delegator_shares": "9239149167.000000000000000000", + "description": { + "moniker": "jPkbzNeKzp", + "identity": "erBtVEeJYZ", + "website": "zDKyjhGPYG", + "security_contact": "tjKPWUglNK", + "details": "lZmMacILat" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.707848956225291609", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xzg536q0eksvxd2297ycyctfwp6x7rk0wq6d0murld346cjs756v0jnxn", + "status": 3, + "tokens": "16949426508", + "delegator_shares": "16949426508.000000000000000000", + "description": { + "moniker": "dNCvXIwisF", + "identity": "PInuRSnoAB", + "website": "IFaDEJuVii", + "security_contact": "DiiitKvkqG", + "details": "wJQyZMjCjC" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083382298074645848", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.156261937510636548" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdazuvwg72zd5mg4lf9mf9eyj7flqcmsw4a03283v0wssdljlj607nt5t8a", + "status": 1, + "tokens": "737084249", + "delegator_shares": "737084249.000000000000000000", + "description": { + "moniker": "FqHViPFdlJ", + "identity": "OmtumbAbsr", + "website": "TYIjFsBXuf", + "security_contact": "jHXPvdANan", + "details": "KiSkcCxjCM" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.123777698447001958", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.320000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "consensus_pubkey": "cosmosvalconspub1addwnpepqflsm7achydcfh2ajnk9d3r4p2ckuphgyw9chrquhyy4xhcct8jc7k5crnk", + "status": 1, + "tokens": "4779018760", + "delegator_shares": "4779018760.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.940000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.882744308468810133" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag73jg46g", + "status": 3, + "tokens": "20324460034", + "delegator_shares": "20324460034.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.742458631966852296", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.368222450098111604" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4d6e962zqejqu3jeypzp740n4k62xte2qnj82q03y28v6wkshycxxdg5w", + "status": 3, + "tokens": "18158211957", + "delegator_shares": "18158211957.000000000000000000", + "description": { + "moniker": "cVYtBkXobK", + "identity": "JOBpTikHPq", + "website": "NyobvRjfBj", + "security_contact": "bKDbHWcmSW", + "details": "xGfkOaAoAb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.340000000000000000", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.117974822314921419" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfs8twrdeftqq3tvq55hq9mxn0duh577l043csvdjhxefl97p3aqq5twjky", + "status": 1, + "tokens": "1728294636", + "delegator_shares": "1728294636.000000000000000000", + "description": { + "moniker": "vdeqSRlmdC", + "identity": "RJhuQmpOMf", + "website": "FRiTavUiHV", + "security_contact": "IoSpxQxqyn", + "details": "KZWhrYllDo" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.107589425669711273", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.048738032041521337" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvkllp9u9v05plyvdmyftgwv96a87j477397tyyrkj50cnaanygrs4ywpus", + "status": 1, + "tokens": "14093282045", + "delegator_shares": "14093282045.000000000000000000", + "description": { + "moniker": "CbenRGMsSc", + "identity": "NjagrmFnYy", + "website": "kpWgwmblKq", + "security_contact": "YvdavQCxws", + "details": "QpvAiaCxgW" + }, + "unbonding_height": "14", + "unbonding_time": "9936-01-01T21:44:15Z", + "commission": { + "commission_rates": { + "rate": "0.043836624388488787", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4cv0e5r0", + "status": 3, + "tokens": "25435646393", + "delegator_shares": "25435646393.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.004320117912957935", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.000447271047532656" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfagcadsa5s2venkcepjtj08rdnnk87phdzlwsl4g9avkkulyx6vzfm5q2y", + "status": 1, + "tokens": "5226912532", + "delegator_shares": "5226912532.000000000000000000", + "description": { + "moniker": "YyfYUVdJyQ", + "identity": "hCVxCQqvPu", + "website": "eHCeufoTrA", + "security_contact": "UyKPzWUXUY", + "details": "XBpFWJEbMv" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.440000000000000000", + "max_rate": "0.440000000000000000", + "max_change_rate": "0.440000000000000000" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvz55wnnaw48qrudyvxm2np0px6xma93kxc0zh8va6xf9ekz7k8ns5palg4", + "status": 1, + "tokens": "10613605390", + "delegator_shares": "10613605390.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.053550077457235518", + "max_rate": "0.190000000000000000", + "max_change_rate": "0.066233442015105736" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwfwqlzf", + "status": 3, + "tokens": "16773399211", + "delegator_shares": "16773399211.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.926805735750034881", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.482844926743337660" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qavly08", + "status": 3, + "tokens": "17705677177", + "delegator_shares": "17705677177.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.615745867723667485", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.398263247650399274" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2eqqj9ng5ru9z7ld9qq6kfljzu5v0rph9gh0gf5zyx4jtc0at3cg44et85", + "status": 1, + "tokens": "13871091494", + "delegator_shares": "13871091494.000000000000000000", + "description": { + "moniker": "zwREkFhOtU", + "identity": "urVIzuITjH", + "website": "LGtPidunhZ", + "security_contact": "hjJvkZYcLY", + "details": "ukIYWLVzYw" + }, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.220000000000000000", + "max_rate": "0.220000000000000000", + "max_change_rate": "0.000727370561970112" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwv80xev", + "status": 3, + "tokens": "26461821776", + "delegator_shares": "26461821776.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.157167562506066789", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.091234306987583436" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf558mk5ff9u9tx0nq76pfgenl6lzddnddywjsy9m5dq6hz9peqj6l3a97z", + "status": 1, + "tokens": "49835911", + "delegator_shares": "49835911.000000000000000000", + "description": { + "moniker": "BGFXyvCoEW", + "identity": "VvrkTmUKcV", + "website": "KAoHgkjVOT", + "security_contact": "WtgEPWzdKE", + "details": "dEDbuRxuQN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.078573260130098190", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.056452518463295050" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwudpuh36geydlpx0yjqu0vhauacf294sn2uetg4ush97p382kqag6sxlqg", + "status": 3, + "tokens": "17862559018", + "delegator_shares": "17862559018.000000000000000000", + "description": { + "moniker": "wSgJTwBWiv", + "identity": "AEATmOIHsP", + "website": "WsuxwwJUIx", + "security_contact": "nzWdiJbKcf", + "details": "WXwvQKoIbT" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.027292850423387945" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq4e58fv", + "status": 3, + "tokens": "112536605413", + "delegator_shares": "112536605413.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.592057337572123856", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.208226705977271974" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtc9vugqcyl9agyk5jfajuhq55zgvrxnn3cjw375k6zdn3cw3pf076rlcay", + "status": 1, + "tokens": "1291312379", + "delegator_shares": "1291312379.000000000000000000", + "description": {}, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.488750140640932143", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.750000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtdldypck872t677fwgapgk44dy7hhw2ghufuda3qtfzqcd8a5095swr5e0", + "status": 1, + "tokens": "6651914410", + "delegator_shares": "6651914410.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.228317860347116037" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7kquya74", + "status": 3, + "tokens": "27525740131", + "delegator_shares": "27525740131.000000000000000000", + "description": { + "moniker": "ajDNnhnkbN", + "identity": "nkdfsqWVlx", + "website": "CeqAfYeTdW", + "security_contact": "KMQJbxKkbm", + "details": "cvAUuqNFYs" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.780000000000000000", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.550890306122411684" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj4x3m9h", + "status": 3, + "tokens": "57637848348", + "delegator_shares": "57637848348.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.081821299211443922", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.458576374327765136" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey2vtdvu", + "status": 3, + "tokens": "19834101875", + "delegator_shares": "19834101875.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.491522368582129610", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.085253529277298261" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0aa00frx8hxrq5pegc0vnt69pj54z3dhwzy8uumr3nhgsc772h0zyr473p", + "status": 3, + "tokens": "37175356106", + "delegator_shares": "37175356106.000000000000000000", + "description": { + "moniker": "oedtWfExZY", + "identity": "taFwTdIwwz", + "website": "oGBHKapVuy", + "security_contact": "hnggEiQcYu", + "details": "qOFIRfzDGP" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083784124252551147", + "max_rate": "0.650000000000000000", + "max_change_rate": "0.550897578676987786" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dsktaxw5", + "status": 3, + "tokens": "55634424696", + "delegator_shares": "55634424696.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.016380613584719475", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.310000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "consensus_pubkey": "cosmosvalconspub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz28vhtm", + "status": 3, + "tokens": "20453193314", + "delegator_shares": "20453193314.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.528106308050967540" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwl3dc4f3s37x82us00qtvs4rtp9t9fvlq3dwgg8wm66hn5ad48jgrxfzcm", + "status": 1, + "tokens": "7094282971", + "delegator_shares": "7094282971.000000000000000000", + "description": { + "moniker": "BDMPqkGylI", + "identity": "YZeHOBMOSc", + "website": "ijOJTZOWdR", + "security_contact": "HYUFFZbwZd", + "details": "eLXzaDckFP" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.055222173408204209", + "max_rate": "0.470000000000000000", + "max_change_rate": "0.191599852279914708" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfxc6u7t75qnm04w78j2ngxr4mpnuqy4f3em3l6mv72kg8ezx4hyyyt9zsk", + "status": 1, + "tokens": "8866716444", + "delegator_shares": "8866716444.000000000000000000", + "description": { + "moniker": "OWlnHGHUpY", + "identity": "rmQGrnevgD", + "website": "SGrzgzpoec", + "security_contact": "SJdamcNZZs", + "details": "MePgsBCfzM" + }, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.140284784345641401", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.310000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqehts4m", + "status": 3, + "tokens": "52558464763", + "delegator_shares": "52558464763.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.128525196978986815", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.100900376719373255" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvlz0fenag3kgjcp0c0qrwyjhrxfxg9ers6mfje4lha7c3hk2qdg6390aav", + "status": 1, + "tokens": "1553435623", + "delegator_shares": "1553435623.000000000000000000", + "description": { + "moniker": "HQTgvYtjWl", + "identity": "cYFFbSdarv", + "website": "DbiOnmrlJt", + "security_contact": "cVrVZLMeQg", + "details": "EaHRYqDHRQ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.143789047273143544", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-04T17:25:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg2887df2cynsehyycldy24y3a4sps3m4w8gmrdfuvw4h9hrc7555u0ayx8", + "jailed": true, + "status": 1, + "tokens": "53335673636", + "delegator_shares": "54642935725.614311989673425860", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.352515542688907487", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.467917537027666540" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru72w0xm", + "status": 3, + "tokens": "18560827275", + "delegator_shares": "18560827275.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.100218404029226728", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.881639682871578638" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00qxpqlwy0p6y9tl23yu7fpu55lhznxa3hrhvsuma6h7lu4c3ekks4wvua", + "status": 3, + "tokens": "22083357722", + "delegator_shares": "22083357722.000000000000000000", + "description": { + "moniker": "LvOuePvVwo", + "identity": "vfegdQlOfT", + "website": "mYvkvMZuDp", + "security_contact": "cfrddDLOlu", + "details": "yHfcxdGyEO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.122593865256918850", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.840000000000000000" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0jekleayf4jvluq0msvqk39kr0s56jg7ch9f4wha3ulmytlpdevsjn72ds", + "status": 1, + "tokens": "1606367134", + "delegator_shares": "1606367134.000000000000000000", + "description": { + "moniker": "MeHdGIwstT", + "identity": "vXbyaoskcs", + "website": "OzuExUMBbW", + "security_contact": "tMoyazzZVW", + "details": "LGmmOunpte" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.874403312310992256", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.936087260014625670" + }, + "update_time": "9936-01-04T15:40:16Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf7z3nz93p6vnus3rsrscqzulxfh5mmx9jc58ys3twdy03l6uepgvakxn52", + "status": 1, + "tokens": "229341851", + "delegator_shares": "229341851.000000000000000000", + "description": { + "moniker": "RNKvcMDBzf", + "identity": "lrNSYDoJzB", + "website": "VjPGQRHRQq", + "security_contact": "uzPAtOuNWp", + "details": "gJbKFrdDPQ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.076730552322816319", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0dp72r2p4adzlsmg95kzs69rdhltghkjvuvmfsac3cdpunr9ctvy2zq9yg", + "status": 1, + "tokens": "5555958746", + "delegator_shares": "5555958746.000000000000000000", + "description": { + "moniker": "SqEyicjIAc", + "identity": "aOctrNrGLp", + "website": "bVeEjmPByN", + "security_contact": "jXOLammCjB", + "details": "HaDjtZfUfP" + }, + "unbonding_height": "14", + "unbonding_time": "9936-01-01T21:44:15Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.510000000000000000", + "max_change_rate": "0.360337629143018233" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxkm9kvvp", + "status": 3, + "tokens": "26763354026", + "delegator_shares": "26763354026.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.027810962515737967", + "max_rate": "0.070000000000000000", + "max_change_rate": "0.034717076557320762" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdpwvxyz0d0thr5hw72lswav4tdfuwkgfqjdjkaws99y4dw5fzncg487kz6", + "status": 3, + "tokens": "25943967606", + "delegator_shares": "25943967606.000000000000000000", + "description": { + "moniker": "anqFIENyYy", + "identity": "LYtCTmovif", + "website": "nDcnuLjZla", + "security_contact": "KhBXWuJORy", + "details": "rcnhuNfFoO" + }, + "unbonding_height": "13", + "unbonding_time": "9936-01-01T19:46:26Z", + "commission": { + "commission_rates": { + "rate": "0.489033782311246085", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.501117175906227815" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtndwvyp0hczl37xh8z2kg32d5jfzkagkdh5mhnfrcemedgavsdauaq9f3f", + "status": 1, + "tokens": "1522777910", + "delegator_shares": "1522777910.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.302268801754965153", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.840000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf3e3e79cz6a8a5ej2sup5a6gr8qjke6y4munem0amzs953pdee6qxllsac", + "status": 1, + "tokens": "48593531", + "delegator_shares": "48593531.000000000000000000", + "description": { + "moniker": "oIkfhnnCKQ", + "identity": "hySDCwZlgb", + "website": "kjGmgoCrNu", + "security_contact": "BcNBxMUwqo", + "details": "TFFDhrPOgE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.046915001210206184", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.036123891352914057" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2y3kj4vhmzue7mqncfd7q98j62a3kcey0mz6faen6sqxeew447lgw2qkre", + "status": 1, + "tokens": "955350854", + "delegator_shares": "955350854.000000000000000000", + "description": { + "moniker": "YoMvXMlPFr", + "identity": "fKGDzIPdra", + "website": "WcCOYuDfvu", + "security_contact": "oZtZtVTHGJ", + "details": "dxGGPZKbDq" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.047292284703768560" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw56zut28tr20sgkqnxxfluz86txzvqx8mrdza94waquh4mglfdl7czkz2u", + "status": 1, + "tokens": "9700319292", + "delegator_shares": "9700319292.000000000000000000", + "description": { + "moniker": "yAtLARqWcT", + "identity": "GDPDnMkbff", + "website": "tcZjjwPSNj", + "security_contact": "FbGNeFZGHW", + "details": "KqYHHRfDeX" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.348806113417240140", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.276441300614760272" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf4eys884495jxdra6k9jqdps582ftj6cp8mjyxws7w6nrxxlhpp7fcwqzj", + "status": 1, + "tokens": "27773889", + "delegator_shares": "27773889.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.105457511098684791", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.235913526142460185" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2cxwldfa72uhy5ecsg7fafzcxujufn8x5585eteclkeu25javyukdtnqfz", + "status": 1, + "tokens": "1633256118", + "delegator_shares": "1633256118.000000000000000000", + "description": { + "moniker": "tgJFunajUY", + "identity": "nLyQJKzFZO", + "website": "qyTiXVjbIh", + "security_contact": "twIziknpbV", + "details": "OoBFXHtHzA" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.099379666682843872", + "max_rate": "0.170000000000000000", + "max_change_rate": "0.051317357664035652" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0sra5mkmllmenj9ymu00ky4wcpwtanyldal7xt3chkm6ksnnhvvjjhfyqq", + "status": 1, + "tokens": "11431729142", + "delegator_shares": "11431729142.000000000000000000", + "description": {}, + "unbonding_height": "10", + "unbonding_time": "9936-01-01T12:58:59Z", + "commission": { + "commission_rates": { + "rate": "0.528428582888525350", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.202815943946770447" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvykaseh7", + "status": 3, + "tokens": "68955304480", + "delegator_shares": "68955304480.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.208925360976246176", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.463634503057540350" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peggwy7x5", + "status": 3, + "tokens": "49844884060", + "delegator_shares": "49844884060.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.338644152469426553", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.069153802725768656" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd76980jyxlezsdfpr4nwaahyuge8958rjpwz7lp7f0shjj445vkq4cla9q", + "status": 1, + "tokens": "958870106", + "delegator_shares": "958870106.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.510000000000000000", + "max_rate": "0.510000000000000000", + "max_change_rate": "0.006589567430698109" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxz2ead4", + "status": 3, + "tokens": "19233426986", + "delegator_shares": "19233426986.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.373154376676147691", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", + "consensus_pubkey": "cosmosvalconspub1addwnpepq07n4j54rccdt2k4p5gw5j0a40ud5wzhlgfwt2fmquptar94tqxksvg7fe9", + "status": 1, + "tokens": "1392995609", + "delegator_shares": "1392995609.000000000000000000", + "description": { + "moniker": "qYrASvEVes", + "identity": "PeqxXaMUrE", + "website": "qiYJuCguZn", + "security_contact": "xuvwbBFfdf", + "details": "vdqxCkfWKd" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.121049931542544207", + "max_rate": "0.170000000000000000", + "max_change_rate": "0.098866031971138939" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wjfqd63", + "status": 3, + "tokens": "25961659072", + "delegator_shares": "25961659072.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.068613373696134985", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.073351676068018235" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgt5lvqw32z2z8wtgskc0gs6wl42agj8p8sjl4rnpkrmrqyy9cagcrpvyjp", + "status": 1, + "tokens": "7062397405", + "delegator_shares": "7062397405.000000000000000000", + "description": { + "moniker": "GiBweZaDWF", + "identity": "pAvSRbpgPx", + "website": "XNrEheNOEd", + "security_contact": "UbuEjmdWgS", + "details": "FanbXQxXQm" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.620000000000000000", + "max_change_rate": "0.352646700715971314" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgtqlt7ucs3nxwwc47qmc03sehv59ttyqhsd537upgtc20ylarm3uauexuv", + "status": 1, + "tokens": "8414643937", + "delegator_shares": "8414643937.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.170000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7ul2hc3", + "status": 3, + "tokens": "33320443806", + "delegator_shares": "33320443806.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118849597906926326", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.228258187539755185" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdmawr65c6guf9rqt4gu9h9ae9a5373t05j2729yyadvd6g5gx5vz9l87k3", + "status": 1, + "tokens": "3480758674", + "delegator_shares": "3480758674.000000000000000000", + "description": { + "moniker": "kwNZPonhYK", + "identity": "hcoDZCuApk", + "website": "TuCKHHpAwY", + "security_contact": "jRHuItJhLi", + "details": "GGHzTJNlEy" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.148257634745595705", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.399887740084543680" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf0wrcap4980h90m65rv3pqwfal4gyy0qt8us030hjxhla2t65jlq96qnz9", + "status": 1, + "tokens": "6944508564", + "delegator_shares": "6944508564.000000000000000000", + "description": { + "moniker": "HQDbMGplPN", + "identity": "pWpzVmWzUQ", + "website": "sBzoUhMVHM", + "security_contact": "GydhSLjldN", + "details": "BWUgqqivmG" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.098439244985309212", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.051461905989545502" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7whvstg", + "status": 3, + "tokens": "59094460259", + "delegator_shares": "59094460259.000000000000000000", + "description": { + "moniker": "cVUXvMdRgs", + "identity": "AHkjmtOkYK", + "website": "KLRPQOyDoY", + "security_contact": "VHwCrfhVnI", + "details": "qdFVvUucvR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.182731553781057822", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.045316794895420248" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwfv0ttln5pqqhkd86m4ujg4r5ape67apt7pfy543n5jg4545waejjpjyt2", + "status": 1, + "tokens": "2681012667", + "delegator_shares": "2681012667.000000000000000000", + "description": { + "moniker": "HFKvirJpBS", + "identity": "qSdijBrgVf", + "website": "AGKPlyJSSq", + "security_contact": "eUTFpfQxFv", + "details": "tLNbfLCQNa" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.036479308923198930", + "max_rate": "0.130000000000000000", + "max_change_rate": "0.113367352262987001" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0kzzpw5g9xn2d6zd2tnarw362fwfvt0evc9gq55lru2xfnw5sum2vv9ulp", + "status": 1, + "tokens": "1263913954", + "delegator_shares": "1263913954.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.097225319727828555", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.157186170206747238" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqde6g57cex9ff650ku6dqdqtfulfnzkacecf6k436xl0dd07zglxx5659h9", + "status": 3, + "tokens": "27718687960", + "delegator_shares": "27718687960.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.905848795661145449", + "max_rate": "0.950000000000000000", + "max_change_rate": "0.476775855507110704" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy7220f9ul3", + "status": 3, + "tokens": "33772482275", + "delegator_shares": "33772482275.000000000000000000", + "description": { + "moniker": "znFMdpLOQw", + "identity": "LEMEnpcxqp", + "website": "TjKmeKjDGm", + "security_contact": "ZOXcBhlDyq", + "details": "WpmmnksSqL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.834910862331446014", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd8ua2f60nuxkgxqguncxzce8vmhdkmxgfcvz323jg9dq73w9gkhvuutwre", + "status": 1, + "tokens": "1975544514", + "delegator_shares": "1975544514.000000000000000000", + "description": { + "moniker": "cJpZJmIecS", + "identity": "KXRKIXLrFa", + "website": "SlrEhmneXz", + "security_contact": "ZEnBrimzTo", + "details": "kYRYkqgakC" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.219853214498709174", + "max_rate": "0.400000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfpdjftwx72whdulutuklct6hpx27tvkf9s475j2jhj0ph8aslkuquduar7", + "status": 1, + "tokens": "1089374285", + "delegator_shares": "1089374285.000000000000000000", + "description": { + "moniker": "AzHxevMaNK", + "identity": "gOOENeIGtQ", + "website": "CdLRpNhPkM", + "security_contact": "SmQaWqWjbJ", + "details": "CTEennTitZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.300000000000000000", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.069984531685936838" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cuyxrn7n", + "status": 3, + "tokens": "24587685968", + "delegator_shares": "24587685968.000000000000000000", + "description": { + "moniker": "tlYEYvdvKp", + "identity": "fQFtYLRSZA", + "website": "ecuAofwdaj", + "security_contact": "gwsuBeDyJU", + "details": "gELFJGuwPs" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.499259642246008210", + "max_rate": "0.560000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jet5tg3", + "status": 3, + "tokens": "62232444428", + "delegator_shares": "62232444428.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.153116543667039838", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.230000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yfudg7m", + "status": 3, + "tokens": "25948607110", + "delegator_shares": "25948607110.000000000000000000", + "description": { + "moniker": "IssGiFwTJv", + "identity": "VgTaqmOLtN", + "website": "BpkICmEqwF", + "security_contact": "qmrIWxiWft", + "details": "sLtbcsMFgA" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.136694009459855954", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.056116480834729575" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4c8wkdlg", + "status": 3, + "tokens": "18426946099", + "delegator_shares": "18426946099.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.469814499540087620", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.960000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvquc4jf3", + "status": 3, + "tokens": "16774945156", + "delegator_shares": "16774945156.000000000000000000", + "description": { + "moniker": "hZvyDgtWxX", + "identity": "TPMmELNQYL", + "website": "YxTdbJnobM", + "security_contact": "ZURHxVMZoL", + "details": "zVjWraUVyE" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.258972799025106506", + "max_rate": "0.910000000000000000", + "max_change_rate": "0.304259315697044502" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "consensus_pubkey": "cosmosvalconspub1addwnpepqghsxshh5tdsf3g9q3a0f7mdq36lcmrxcjcsw0zwx7h6mhrkqt7gxqa5ml3", + "status": 1, + "tokens": "11913967185", + "delegator_shares": "11913967185.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.049529819581902112", + "max_rate": "0.130000000000000000", + "max_change_rate": "0.062116609393646476" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwyktyc4e9j89pv0syud54z03g7tg9j5nx66ceq6gqf698l8h7x8gtg29m4", + "status": 1, + "tokens": "4975856672", + "delegator_shares": "4975856672.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.880000000000000000", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.217954344442803519" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprs83zeag", + "status": 3, + "tokens": "32156167120", + "delegator_shares": "32156167120.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.351977697440288211" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvly6j0pyezy88s9lnat6taglylzq03vvsvyw4uy2tv3vcl3200ej0nev4k", + "status": 3, + "tokens": "16811362128", + "delegator_shares": "16811362128.000000000000000000", + "description": { + "moniker": "lasYiVeRDA", + "identity": "TFiGxJBNUs", + "website": "xswbDClAxs", + "security_contact": "HYUurzqzcC", + "details": "EVSfzEFSuo" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.036542719943188247", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.304756516958654494" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66dra0w3", + "status": 3, + "tokens": "19540440011", + "delegator_shares": "19540440011.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.065303820000927065", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.134868108685582589" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqglmtrs7uwjn4rvak6n3xec3xq3k8x8v59pqunpk44dk93nvjk3vscewj56", + "status": 1, + "tokens": "26607217", + "delegator_shares": "26607217.000000000000000000", + "description": { + "moniker": "hAQlIfWGGk", + "identity": "ohuamGtCae", + "website": "ZpegjNqnTB", + "security_contact": "dmfZxJGUcq", + "details": "YcDlNrjVXU" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.508849573815251530", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.690000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afqga9sv8", + "status": 3, + "tokens": "33258307031", + "delegator_shares": "33258307031.000000000000000000", + "description": { + "moniker": "uVtPIVoLeB", + "identity": "UQUjtBkUkU", + "website": "lrfjDXnSyH", + "security_contact": "tPWaAehpKA", + "details": "YCcmQgJRnO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.859185512301348293", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.915098787337318307" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrq06r4ck", + "status": 3, + "tokens": "41543247193", + "delegator_shares": "41543247193.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.119695944592116460" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4vjajc6x", + "status": 3, + "tokens": "61843733534", + "delegator_shares": "61843733534.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.437478542817284441", + "max_rate": "0.530000000000000000", + "max_change_rate": "0.308410375933996023" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvghhzrgz", + "status": 3, + "tokens": "36037299066", + "delegator_shares": "36037299066.000000000000000000", + "description": { + "moniker": "rUZvoFLmub", + "identity": "dQGYIJXPFq", + "website": "ZPoXnJmgzU", + "security_contact": "MdbwPJFNHC", + "details": "NdoQBlpUhN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.670000000000000000", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.629855974067904060" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdnmydex2xjhqnhfeudkqhkhj888kjzw67pqdw859u8g909jcyn4xkavddn", + "status": 1, + "tokens": "12315828943", + "delegator_shares": "12315828943.000000000000000000", + "description": {}, + "unbonding_height": "6", + "unbonding_time": "9936-01-01T04:22:01Z", + "commission": { + "commission_rates": { + "rate": "0.316562332892492640", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.566007736559520541" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", + "consensus_pubkey": "cosmosvalconspub1addwnpepq25a99sz5z4ux5fahn5g6gh7xsyckplenzjnxztza85ww393mdwe7kjzhj7", + "status": 1, + "tokens": "3222725", + "delegator_shares": "3222725.000000000000000000", + "description": { + "moniker": "iSRrbCHORt", + "identity": "CDdghkkmid", + "website": "nNRlagAXoW", + "security_contact": "MkjeVfcrNI", + "details": "gAzfuHvTeE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.115447316690759036", + "max_rate": "0.260000000000000000", + "max_change_rate": "0.061411901441335590" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf5zqt6stst6y23klsfpcjspr7tkpmjdlckv7wx6vrsewknw0m2a2d2eqav", + "status": 1, + "tokens": "7934886466", + "delegator_shares": "7934886466.000000000000000000", + "description": {}, + "unbonding_height": "13", + "unbonding_time": "9936-01-01T19:46:26Z", + "commission": { + "commission_rates": { + "rate": "0.186498958432282804", + "max_rate": "0.190000000000000000", + "max_change_rate": "0.169324253546368609" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz4luxgn", + "status": 3, + "tokens": "33206633235", + "delegator_shares": "33206633235.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.229284159886860129", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.212917450108859841" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqghun4nxekdzlcezu5epylpx2grw5vst3ct3wfcm25ushh49jtjljltwnht", + "status": 1, + "tokens": "5109252999", + "delegator_shares": "5109252999.000000000000000000", + "description": { + "moniker": "vYsZMuAZMj", + "identity": "ruZsSuRcSU", + "website": "zSbGrYvHQi", + "security_contact": "EGvxmVBnmC", + "details": "jxLlrmuSve" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.152694901599204693", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.241038925182996746" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw24c76ax", + "status": 3, + "tokens": "27567655084", + "delegator_shares": "27567655084.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.216560651737526756", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.026445047137608599" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdwls2cwhnhc6eapdv49a8e2l4pfhl4kyna3gasjle7qd3tw0csrgfsu0w2", + "status": 1, + "tokens": "6124762941", + "delegator_shares": "6124762941.000000000000000000", + "description": { + "moniker": "GbZmuFqSrs", + "identity": "zBDMXWuAAT", + "website": "oYTYLCDhOX", + "security_contact": "BmYozodwdp", + "details": "uwfkokyYnm" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.132737946334112303", + "max_rate": "0.380000000000000000", + "max_change_rate": "0.143930818045613974" + }, + "update_time": "9936-01-01T06:29:20Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgcfljwg4f78y3w65v9unsd283tk5a2zxs2mft203tgwgyjqglf6vua5qk4", + "status": 1, + "tokens": "8464012502", + "delegator_shares": "8464012502.000000000000000000", + "description": { + "moniker": "mVsKKRcaEr", + "identity": "eWIUfkJFLO", + "website": "IFRESgfaTp", + "security_contact": "eJpfnmHgUN", + "details": "wnkKbeWEhk" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.000000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qpu7x5c", + "status": 3, + "tokens": "27671960609", + "delegator_shares": "27671960609.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.077841535313299819", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.054979434313866047" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqde324p8zp7xxqwul8xzv9d79f4aqasjlqm6sxhemwhn2e79rz5jurknp0z", + "status": 1, + "tokens": "1864943427", + "delegator_shares": "1864943427.000000000000000000", + "description": { + "moniker": "ZZatQqAwWf", + "identity": "WIFSSfcIMu", + "website": "AFHEWYMAIc", + "security_contact": "pKTQsTtkRK", + "details": "BUOvcfwoSE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.298096915984498576", + "max_rate": "0.630000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2wcjjal", + "status": 3, + "tokens": "25069342080", + "delegator_shares": "25069342080.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.249161816461641720", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.693944288516379645" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akutfqm7", + "status": 3, + "tokens": "55737096951", + "delegator_shares": "55737096951.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.498362112747574396", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.645641814068879323" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693hazjkkehy", + "status": 3, + "tokens": "33054734644", + "delegator_shares": "33054734644.000000000000000000", + "description": { + "moniker": "mUQFKtnPLD", + "identity": "xsxoaAIVkh", + "website": "EBARfZhhON", + "security_contact": "GynbBFtcRq", + "details": "RftDCeMUPi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.123876475355091478", + "max_rate": "0.860000000000000000", + "max_change_rate": "0.141162753552435345" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v30nmws", + "status": 3, + "tokens": "78601464028", + "delegator_shares": "78601464028.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083731202536014652", + "max_rate": "0.860000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9ykjrzn93", + "status": 3, + "tokens": "18090212819", + "delegator_shares": "18090212819.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.081582427988342735", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.086390137368972014" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06my86wxz2", + "status": 3, + "tokens": "33968139195", + "delegator_shares": "33968139195.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.247483015769197525", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.837420192496215212" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtufvzu2k2knnce8l9jcwuntray9m8hnlal8a4jkcjazppr5p7pyus6emm0", + "status": 3, + "tokens": "19857350032", + "delegator_shares": "19857350032.000000000000000000", + "description": { + "moniker": "PfGefIRkUQ", + "identity": "PQNdBVtoxj", + "website": "nyfnvHyjNl", + "security_contact": "ewMiIvfvCh", + "details": "ttKmCVgWXS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.239149115387739677", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.173620767408899960" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv9w0yqrekktvu6gd7ak8u7wkwqj47llgrtl2vp2gtdvfafwatyysclj3nm", + "status": 3, + "tokens": "23726914937", + "delegator_shares": "23726914937.000000000000000000", + "description": {}, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.522454157166611225", + "max_rate": "0.820000000000000000", + "max_change_rate": "0.329662780053528069" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2crvswax", + "status": 3, + "tokens": "16516288319", + "delegator_shares": "16516288319.000000000000000000", + "description": { + "moniker": "kVNZIBYAxD", + "identity": "ChbsAFHanI", + "website": "SvHMthzzzB", + "security_contact": "cMJXUgGCfx", + "details": "PWsrYNKuPZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.540000000000000000", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.491525012965837080" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2kj4krx", + "status": 3, + "tokens": "45010236382", + "delegator_shares": "45010236382.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.095070637134115497" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveesw5rr6m", + "status": 3, + "tokens": "54768547781", + "delegator_shares": "54768547781.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.328146514360581742", + "max_rate": "0.810000000000000000", + "max_change_rate": "0.166428198995593213" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtjadacgcc9v3sptf62zr88pm3xd82gtxx7fl0vllavvx2vu5gckqagc0rx", + "status": 1, + "tokens": "1615474614", + "delegator_shares": "1615474614.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.065338192442219463", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.071905116454941829" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv59z3edalxhrq233upfrlzdpa2y4qqaahn8u4s56jf9utdxpnnnxnpfxtj", + "status": 1, + "tokens": "2364056", + "delegator_shares": "2364056.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.024463804229337023" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68yqxsxnt", + "status": 3, + "tokens": "25326342688", + "delegator_shares": "25326342688.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.785486462764506620", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.356882054361860100" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqflpdacrnmymf2nxz0z27wu4c42cyqfqued97l9pvln873ptnj722jw5nhc", + "status": 1, + "tokens": "10244193595", + "delegator_shares": "10244193595.000000000000000000", + "description": { + "moniker": "WkRSrJhiPR", + "identity": "MisdRpaRnZ", + "website": "KUNuGjAyZr", + "security_contact": "pYdYTuqYRb", + "details": "AzkAkTfsou" + }, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.094275793948488796" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdlqwps7uuk7l2pszryqcmflpr6rdgvfmkgga6fkjvsydts2s6udkqx67s6", + "status": 1, + "tokens": "10175385576", + "delegator_shares": "10175385576.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzlcd6kj", + "status": 3, + "tokens": "67804970220", + "delegator_shares": "67804970220.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.264013069771684883" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfdzh8ar6wwm3h8dd0n9rxk3vfv753568dq62g3xdqepgen0gkcnsl92xax", + "status": 1, + "tokens": "87516298", + "delegator_shares": "87516298.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.008369971691300017", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.003240979663537908" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", + "consensus_pubkey": "cosmosvalconspub1addwnpepq07ahy07m2ymqkwra0tzkgs0588p94nraj84wvmymmueg8dupcqv7534dt5", + "status": 1, + "tokens": "14531672001", + "delegator_shares": "14531672001.000000000000000000", + "description": {}, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.368173971209038079", + "max_rate": "0.620000000000000000", + "max_change_rate": "0.054850804257024119" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4v8fm8e8", + "status": 3, + "tokens": "41964454098", + "delegator_shares": "41964454098.000000000000000000", + "description": { + "moniker": "LDEzyylLGV", + "identity": "NaLpENvFnX", + "website": "ooOcvgIJwr", + "security_contact": "aQaxAlCyFx", + "details": "CxEFcmLmkI" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.099339754970547702", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.111217397607280422" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0rs6tt6rmqemes8jnlxsawqja89rdvyntyjuhwl73ajeelhrhee7vumxyk", + "status": 1, + "tokens": "981657888", + "delegator_shares": "981657888.000000000000000000", + "description": { + "moniker": "szQvkBMbEg", + "identity": "IBxatcFQNO", + "website": "fldsKGMdNR", + "security_contact": "qLDMtHRNsj", + "details": "RpRencldBz" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.118429306081945145", + "max_rate": "0.190000000000000000", + "max_change_rate": "0.105194643308960695" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt5s2m60xv2n7sxjv7lhzlf83u75fh7yc0pjv3thqf5vkdunr32ksh4xsdu", + "status": 2, + "tokens": "15174649749", + "delegator_shares": "15174649749.000000000000000000", + "description": { + "moniker": "VCTScqQSKa", + "identity": "WzaIRwbXgo", + "website": "BAOhQWhmkQ", + "security_contact": "NncLgAxHdH", + "details": "URrsiopqUa" + }, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.047510383078156072", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.032290417291892447" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqddyzyd3lgpt8jrlkmpg9qwhex2z7msn5uaxv9w46eps5vkmc6kwu5ans84", + "status": 1, + "tokens": "113412645", + "delegator_shares": "113412645.000000000000000000", + "description": { + "moniker": "FFikJsTYtD", + "identity": "GKkbjMUETZ", + "website": "MBebdoLbAT", + "security_contact": "rkOsehQNen", + "details": "vZFASbHJGj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.198586301080035955", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.012224704011526027" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgnwhgwtgfqyxwfp86e906zysx5p02kh5rjzsweq2984lm2e5f3qvs8vqd3", + "status": 1, + "tokens": "11726853019", + "delegator_shares": "11726853019.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.112940346400043350", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.078370922162771010" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k907nvf", + "status": 3, + "tokens": "28676349495", + "delegator_shares": "28676349495.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.609184993023386704", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.699887495531371188" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdzvxgkmxur34cmgyyfzr0mkhrysd6xdqpkz6k0qd62y4hl325qd62h02f4", + "status": 2, + "tokens": "13754725148", + "delegator_shares": "13754725148.000000000000000000", + "description": {}, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.870000000000000000", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.063255826123136327" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd7ruklxzqwqz3u2tdlh3kel0t0536g3pxu37r4286uavkrmx72mus5lvv6", + "status": 1, + "tokens": "11868660651", + "delegator_shares": "11868660651.000000000000000000", + "description": { + "moniker": "xIRtBfvrAE", + "identity": "eAHfYfXhkO", + "website": "dUrPZGxJFL", + "security_contact": "YdvDmWdVbe", + "details": "IXbFohDvjo" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.181867057844473236", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.185540283605239869" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw5h9ggnz7amw48v648wer50qeen3hv283fgyxaytq5l0y5ggz40x3zgm4r", + "status": 1, + "tokens": "14194120234", + "delegator_shares": "14194120234.000000000000000000", + "description": {}, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.043495592753648126", + "max_rate": "0.490000000000000000", + "max_change_rate": "0.490000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "consensus_pubkey": "cosmosvalconspub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjtszrqs", + "status": 3, + "tokens": "34574952843", + "delegator_shares": "34574952843.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.810000000000000000", + "max_rate": "0.810000000000000000", + "max_change_rate": "0.810000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtk5r42sr9allp9fsgh0ldj8fgmfmdl84w8dy23sr44u5zy5lxy2xw577kl", + "status": 1, + "tokens": "10646429954", + "delegator_shares": "10646429954.000000000000000000", + "description": { + "moniker": "SHCpfjKNSu", + "identity": "tDOjGFgyjP", + "website": "IHZYFpGyiJ", + "security_contact": "hjdANxnNHq", + "details": "ypZFjrXaym" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.940000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvact8ahszvndajqxra2w3e5le3trytmp9xqgqwcx4qykydgx70y2whdj6h", + "status": 1, + "tokens": "506914959", + "delegator_shares": "506914959.000000000000000000", + "description": { + "moniker": "qUibSizEqd", + "identity": "bYeZJhWRkx", + "website": "UteQGhdNGk", + "security_contact": "VwPIMByrAe", + "details": "lIhtmLCFtZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003530593563713880", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.006047204189099454" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvm3gjyc4syt8pvjrmfus0my28n42ypfj67yv45es25tpctv2vhxcmlw5d8", + "status": 1, + "tokens": "4732841169", + "delegator_shares": "4732841169.000000000000000000", + "description": { + "moniker": "yufdZLmBSv", + "identity": "UQtKAMmdwN", + "website": "lFmhkKHsad", + "security_contact": "gWQFiKkqtl", + "details": "UemBSSExdy" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.096951425148933086", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.057968950263397204" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "consensus_pubkey": "cosmosvalconspub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku73m9m0", + "status": 3, + "tokens": "16992076248", + "delegator_shares": "16992076248.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.406968367525101581", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.487609794856186092" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw0np49ksk7pxwauu8jkfp7gf9dqwahdc8yknp53jvc0zcq6ugplxxvu2k5", + "status": 1, + "tokens": "5755488027", + "delegator_shares": "5755488027.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.356380989095155962", + "max_rate": "0.380000000000000000", + "max_change_rate": "0.155364476986441701" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfcdg0aax", + "status": 2, + "tokens": "5685279942", + "delegator_shares": "5685279942.000000000000000000", + "description": { + "moniker": "YKKhjZGayb", + "identity": "IvgiPDjmYA", + "website": "gScrUtVzvh", + "security_contact": "kGHySpHXgu", + "details": "IyuehlcoPM" + }, + "unbonding_height": "50", + "unbonding_time": "9936-01-04T22:14:51Z", + "commission": { + "commission_rates": { + "rate": "0.093407705950029411", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.187465926844434813" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0e5h85jydylerz95nl4y6hms29agglx4p9mtwxp4e98r6wckmy3qzsvqn2", + "status": 1, + "tokens": "2112005770", + "delegator_shares": "2112005770.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.183782150095569515", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.173922417381016295" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "consensus_pubkey": "cosmosvalconspub1addwnpepq228r4rpxclcs5ufhlytsyx6dxkvwvecxvjhlsvglg26jg6l9kpy65ys4kc", + "status": 1, + "tokens": "640064160", + "delegator_shares": "640064160.000000000000000000", + "description": { + "moniker": "TkmRhasAJG", + "identity": "nrtIpGdFQw", + "website": "FSkoCAGbBU", + "security_contact": "JYwbMItCZN", + "details": "lEwvgQzPgI" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.070569099867139542", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.057349117351674195" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7zgmra8", + "status": 3, + "tokens": "26261718579", + "delegator_shares": "26261718579.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.210000000000000000", + "max_change_rate": "0.067309904771533509" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqnavslf", + "status": 3, + "tokens": "46127605035", + "delegator_shares": "46127605035.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.895728278286976959", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.140752130806369269" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jyyn3gu", + "status": 3, + "tokens": "22249948652", + "delegator_shares": "22249948652.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.008115100503323252", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwmplgyppurr7j6knpfavaza6xrg007n907th4lslha4qx45q82tw8wvjzt", + "status": 1, + "tokens": "50006896", + "delegator_shares": "50006896.000000000000000000", + "description": { + "moniker": "ybIIoTPlxX", + "identity": "XQTftwoSPG", + "website": "qUglDanvKZ", + "security_contact": "kfbUrCfRzd", + "details": "LTPbNBSEJE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.119939677612298020", + "max_rate": "0.130000000000000000", + "max_change_rate": "0.033345572724347445" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yagkfrr", + "status": 3, + "tokens": "39560123415", + "delegator_shares": "39560123415.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.060188716749386269", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.350000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf9usg6za2dqh4lw3xj0h9rrgtfth0f6lctuv3kwv7smhhl8czc3cnfp3g3", + "status": 1, + "tokens": "8741308900", + "delegator_shares": "8741308900.000000000000000000", + "description": { + "moniker": "PGNhLBZWzw", + "identity": "zDvDjFwbHN", + "website": "CdiTImAnEO", + "security_contact": "rJZQgfIJvh", + "details": "xTTyQTjmMr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.307210706399811753", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.399893848936713140" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwckstndv9w0luxt6p3a694qazxat6kerfnpsr3qafypj9adchjaqxfwvdr", + "status": 1, + "tokens": "14799158297", + "delegator_shares": "14799158297.000000000000000000", + "description": {}, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.136186469015251310" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "consensus_pubkey": "cosmosvalconspub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kwmez9k", + "status": 3, + "tokens": "16420725988", + "delegator_shares": "16420725988.000000000000000000", + "description": { + "moniker": "LVfceOUKZE", + "identity": "ZyVUuaCAJZ", + "website": "rliAdTPvEK", + "security_contact": "hVtZPHOsKh", + "details": "QjmMKruCba" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.036920301680485403" + }, + "update_time": "9936-01-01T16:55:11Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq77rpqn", + "status": 3, + "tokens": "26062927309", + "delegator_shares": "26062927309.000000000000000000", + "description": { + "moniker": "BFoqLaJLDn", + "identity": "weLorPCgTe", + "website": "oyhVcpSOLq", + "security_contact": "hdnvhDJTDC", + "details": "SAZISvvmwB" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.160832184115355939", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xw03emk4", + "status": 3, + "tokens": "44313010729", + "delegator_shares": "44313010729.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083856723472306849", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.569378562223247850" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6yp7zp3n", + "status": 3, + "tokens": "25164533156", + "delegator_shares": "25164533156.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.330000000000000000", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.314039829028852779" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdd48dqgku8keethq2dtl8zmgnjprm0gmc2gawzwr6z3hp4m8s802w6859s", + "status": 1, + "tokens": "492237770", + "delegator_shares": "492237770.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.271162649945129428", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.426439315005694848" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvn899z9u9a7h28682292n9y77yr6yuyrg2xvg8eaammccqfuc9e5jp63vn", + "status": 3, + "tokens": "16985369823", + "delegator_shares": "16985369823.000000000000000000", + "description": { + "moniker": "oVMoJSrGgV", + "identity": "ydZuwvoyLe", + "website": "EdyJLNhNGZ", + "security_contact": "QauDavDNuL", + "details": "CVkbnFlumN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.276325858271560152", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.108166159043578444" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgv72p8pxj6dc526aynu6gkcg0cfrvjmjv6tnrhtp3stacy3jgezzlkdmfv", + "status": 1, + "tokens": "125301", + "delegator_shares": "125301.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.358186845519178392", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.739442651834999796" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwshp63n", + "status": 3, + "tokens": "25367511082", + "delegator_shares": "25367511082.000000000000000000", + "description": { + "moniker": "KODmaZYfBO", + "identity": "dQoWoZcHpD", + "website": "QRjjuYKVNR", + "security_contact": "BHWzdORGfc", + "details": "dZGTxQmqIN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003392332242825811", + "max_rate": "0.060000000000000000", + "max_change_rate": "0.027187395396712775" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqv0lje47", + "status": 3, + "tokens": "54901950842", + "delegator_shares": "54901950842.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.193375046872051394", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.161750559623523660" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtcvgnxpkww6h60yke0z0rmvv34tw9ycuwr02pvw67kgaygtvgku2q2mrjt", + "status": 1, + "tokens": "13624841977", + "delegator_shares": "13624841977.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.142858989036560174", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.660255121442971729" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc9m7uvt", + "status": 3, + "tokens": "15374405822", + "delegator_shares": "15374405820.680335249007925874", + "description": { + "moniker": "eomlzRaIRN", + "identity": "PaBTVBXpcj", + "website": "frMwzGwrdS", + "security_contact": "XwCgZGftYO", + "details": "oynChhccDw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.014913519812752309", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.219118316904950121" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2qs6da44rrhj6hj2ea7a2kjnh9yecavt8t00dry6nd56fvjchyhqesfuvt", + "status": 1, + "tokens": "3041120922", + "delegator_shares": "3041120922.000000000000000000", + "description": { + "moniker": "rLSjWyflSi", + "identity": "HSuNyExgbD", + "website": "vdCDCTATFy", + "security_contact": "jWlYErowfX", + "details": "gFCgjjVhur" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.710000000000000000", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.236185027723064295" + }, + "update_time": "9936-01-01T09:58:26Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7dsh8mr", + "status": 3, + "tokens": "33057476849", + "delegator_shares": "33057476849.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.074914975922116628" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtplsxcj5j56ms8j7lerl57al6asnrh53uft4efkzvuhv50gq8azx0l5f9w", + "status": 2, + "tokens": "14118884362", + "delegator_shares": "14118884362.000000000000000000", + "description": { + "moniker": "qQzVEWDfcL", + "identity": "LQVrYguqLe", + "website": "BJddIAyseo", + "security_contact": "trbqxTDxYA", + "details": "TTjZQrCkYO" + }, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.299140431481446428", + "max_rate": "0.510000000000000000", + "max_change_rate": "0.367721024197463519" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvuzm6rcpa5h3kmgenxc04qaww03748hw2plpqnyyk5c0ypql7jnw76ujdz", + "status": 1, + "tokens": "5480500900", + "delegator_shares": "5480500900.000000000000000000", + "description": { + "moniker": "FaJwpwEttu", + "identity": "kZOHQugtED", + "website": "PQZJSclRmf", + "security_contact": "MIFJdxgvtg", + "details": "NReTekfbjK" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.523988597853042947", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.308301841976871261" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axhh8p8f", + "status": 3, + "tokens": "49683234188", + "delegator_shares": "49683234188.000000000000000000", + "description": { + "moniker": "MJAduJwrkS", + "identity": "YpKMJsMpdh", + "website": "rmUXbHIGjh", + "security_contact": "KxyJSeDEJS", + "details": "gQmDpfNyLZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.637063248045666486", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.100218674012239339" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmkm3zs42", + "status": 3, + "tokens": "34289428306", + "delegator_shares": "34289428306.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.026475742223507385", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.008016543161851368" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00s4avel98xmrp04dalj5dv5cm0szqd8fy6hfqlgtzwtxq3y566yccm7xk", + "status": 1, + "tokens": "14381116169", + "delegator_shares": "14381116169.000000000000000000", + "description": {}, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.117328305608042006" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw3fj2ga", + "status": 3, + "tokens": "29885998584", + "delegator_shares": "29885998584.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.208832068199199828", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.835848953294536000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfxgg4wmgzakcpcmp7g68j059k5k5ucmaj9vfgqvseqgkuuqltlf2c5w6uv", + "status": 1, + "tokens": "2533410912", + "delegator_shares": "2533410912.000000000000000000", + "description": { + "moniker": "bYcSaxNPkq", + "identity": "arINXKFuvD", + "website": "fCFrVNkkzm", + "security_contact": "yhhWWoxqFq", + "details": "urmzJwGIym" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.467362323850790159", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.563213072917526451" + }, + "update_time": "9936-01-01T08:09:55Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv7nw49k6j8sg6379dy0lemj7vee2el49mt5rmypwujwk6lua8duyrr8zrn", + "status": 3, + "tokens": "21181468286", + "delegator_shares": "21181468286.000000000000000000", + "description": { + "moniker": "TgLltHAWtO", + "identity": "zpriAAvZuw", + "website": "pWVJnIqFBY", + "security_contact": "TyuWOjmMFF", + "details": "CbbpwkidBS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.237822850366335221", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.134613352727411591" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqth3ytlunezutcfyr4afacswjkwypdm07lm6kxe4h2aewvmm90t5cc8rts3", + "status": 1, + "tokens": "13794284295", + "delegator_shares": "13794284295.000000000000000000", + "description": { + "moniker": "riEFCuKVXf", + "identity": "RZJMRcSWpl", + "website": "JQleNyHRoA", + "security_contact": "vwBjcPwPLl", + "details": "OxnpsiCZYU" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.025570974549293612", + "max_rate": "0.030000000000000000", + "max_change_rate": "0.001283275853790765" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2vncgld", + "status": 3, + "tokens": "39430946332", + "delegator_shares": "39430946332.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.400358972669819604", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.343431675789315867" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrywn9e6w", + "status": 3, + "tokens": "32328037984", + "delegator_shares": "32328037984.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.039339062684741866", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.021256256594527078" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtsn2j9l0052cprtztzuxzcwspekquyfn9q9nzlt2ez2pfzcvu6jkqu2unx", + "status": 1, + "tokens": "9640492641", + "delegator_shares": "9640492641.000000000000000000", + "description": { + "moniker": "OhKGKdYJlz", + "identity": "LSJqmrKKaR", + "website": "SiTLNvLXQj", + "security_contact": "uKbbQAowYR", + "details": "JzsfhKIeFY" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.080341642170762698", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.105285510061933545" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus2udpwh", + "status": 3, + "tokens": "15813863385", + "delegator_shares": "15813863385.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.543747468021249371", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.392045382869085556" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwujx3ap2", + "status": 3, + "tokens": "25957780472", + "delegator_shares": "25957780472.000000000000000000", + "description": { + "moniker": "hoLpIoNUFo", + "identity": "LCpoujNFyW", + "website": "AOTlTXjPul", + "security_contact": "elgNvDzEfH", + "details": "hwOSWkTDMH" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.347272379813626146", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2pnmqvu6uvxhy0t5zyez5wjcvsh5pkqlmta3uyeqy0yzf7tp0n76xdp2vd", + "status": 1, + "tokens": "64706947", + "delegator_shares": "64706947.000000000000000000", + "description": { + "moniker": "yIzgSLCxWK", + "identity": "LhFzfpIqEv", + "website": "nihretOwDr", + "security_contact": "UqNKLIAQhC", + "details": "IWABqYDyKj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.002948295103320281", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.121632522168200969" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtj39qcdlmh7fr77am26s8as06l9v3p426z5gr5dyfvc4fr5gqyevxe8agn", + "status": 2, + "tokens": "12174892810", + "delegator_shares": "12174892810.000000000000000000", + "description": { + "moniker": "hjYgiDHhzz", + "identity": "KrwRKCSMYC", + "website": "VKtCXTAtbA", + "security_contact": "kqWNgIhnNy", + "details": "etaTpRtVAp" + }, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.344371628918599076", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.334517383567629324" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwdhe2nv5ugezx2nkyx7t7z255pj3xle6kgcpfdkmwdng4vp7sa3y40we66", + "status": 1, + "tokens": "10929627266", + "delegator_shares": "10929627266.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.004188013237240263", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.078008827750366986" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwac5an6ey8yprrjfh3640q8l5hg7w4fgrlu54dm8dzacu0msnv472ryvq8", + "status": 1, + "tokens": "9052281558", + "delegator_shares": "9052281558.000000000000000000", + "description": { + "moniker": "gJaIcmLYsZ", + "identity": "jroUNglzSW", + "website": "XrrZfRjuzl", + "security_contact": "DYvQqylZps", + "details": "wIKrOdZvrO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.010000000000000000", + "max_change_rate": "0.004972274320458977" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtwlwcajqxexfgfd38r4f3zhqxzvupczp89m9y39kt4xqufa4n33clzk663", + "status": 1, + "tokens": "357334043", + "delegator_shares": "357334043.000000000000000000", + "description": { + "moniker": "BRVwdOkVBr", + "identity": "aKYCoLKQUh", + "website": "hDcADiBWXa", + "security_contact": "nzShMsVsKj", + "details": "LNBhxIWHEs" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.970000000000000000", + "max_rate": "0.970000000000000000", + "max_change_rate": "0.128896474943338231" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9ugfdlq9", + "status": 3, + "tokens": "45284218868", + "delegator_shares": "45284218868.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.340626334815374555", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkxmnmkq", + "status": 3, + "tokens": "44505127913", + "delegator_shares": "44505127913.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.605944631117636209", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.639343774657574630" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqk8ct27q", + "status": 3, + "tokens": "22456561633", + "delegator_shares": "22456561633.000000000000000000", + "description": { + "moniker": "DPTpRIdXgW", + "identity": "qysDMlMxpi", + "website": "xWbmLVlZvB", + "security_contact": "QtpKTducMv", + "details": "UWYfFdNOxg" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.057271144965717909", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.075138495309274904" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtwvf7g53a6nlvcr6exwkhumshdv59mh0jaa8umfdts70dtupqctxwks642", + "status": 1, + "tokens": "11601440649", + "delegator_shares": "11601440649.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.397633947789396228", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.717967266416289169" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdrvr2ne6f9hgqca4s5fe3uwfxctwdr4ne2lkmmqsgfv5uw226l85das0j8", + "status": 1, + "tokens": "11399240291", + "delegator_shares": "11399240291.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.041564439158976825", + "max_rate": "0.430000000000000000", + "max_change_rate": "0.217285019740322808" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg048v7u9cfmrxvk8kp4rwr3z3cn7lwsag6nyf5m9696lrdquk44ywwlavq", + "status": 1, + "tokens": "6804408417", + "delegator_shares": "6804408417.000000000000000000", + "description": { + "moniker": "FdDcGcaieJ", + "identity": "YMIBMpEMxW", + "website": "FrQHDjmWVB", + "security_contact": "zvaqppfaVE", + "details": "MeORuLmeIz" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.380000000000000000", + "max_rate": "0.380000000000000000", + "max_change_rate": "0.174389181438542137" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdm5qzsy6r8f29za6hghdk4ej8hujywh6dsyteyguvxm5h64an8rx04zrcx", + "status": 1, + "tokens": "13843367300", + "delegator_shares": "13843367300.000000000000000000", + "description": { + "moniker": "vMZOeDUHUM", + "identity": "wfmFxUNRng", + "website": "KNZJMmrTqA", + "security_contact": "feyLBfuyQx", + "details": "LIzoGEUhKk" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.448785636299397402" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvfuwjyepzrr7elzg5d2u9m6z4aujww6l25gnscerc76t68tvnjd5ttjp2v", + "status": 1, + "tokens": "23136285", + "delegator_shares": "23136285.000000000000000000", + "description": { + "moniker": "sUTOjiepmW", + "identity": "tJVRrBwqlG", + "website": "YshLyiZMrT", + "security_contact": "RUDyZwUQmU", + "details": "QzgVtMvYLd" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.071168023059934609", + "max_rate": "0.930000000000000000", + "max_change_rate": "0.501568793423267606" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd7u4d80m4e6sfhyzj84k6y34v30g9cstzx7cmrazvxdtfe40urcvran9t8", + "status": 3, + "tokens": "45811135531", + "delegator_shares": "45811135531.000000000000000000", + "description": { + "moniker": "zcPImZiDZD", + "identity": "zkcTihefFl", + "website": "mIjAaWRNkf", + "security_contact": "gTafXNexkI", + "details": "tJJDPwaiAf" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.079222020883406460", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.311112908017536993" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggxauhp0sadc5npdva6f492f3n4a76fldyt3lca6lk36685s624ucakcrh", + "status": 3, + "tokens": "24610359351", + "delegator_shares": "24610359351.000000000000000000", + "description": { + "moniker": "dLwrEevbbD", + "identity": "ubSqqBoPRs", + "website": "MNuXpKVOXc", + "security_contact": "lNXuEDYSJp", + "details": "CvXURllZqF" + }, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.175531415042829217" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0xhfz0m55nz4txp2v7ttr3zxa9339nx6tjfv24xth38qs7s9qw56ayattm", + "status": 1, + "tokens": "6487425213", + "delegator_shares": "6487425213.000000000000000000", + "description": { + "moniker": "yoQWgAwfrT", + "identity": "VnLdNIgSPv", + "website": "TmrorbnjLv", + "security_contact": "ddGynzpfAR", + "details": "sQAebQXxiK" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.950000000000000000", + "max_change_rate": "0.013910826406076438" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvcgk67dzzthkzn4yjgfq0p7942jhxjpn4e577szvhz6nwclh2ntclfpnr0", + "status": 1, + "tokens": "2422560770", + "delegator_shares": "2422560770.000000000000000000", + "description": { + "moniker": "zrclnpBtHC", + "identity": "SBouqnqXEt", + "website": "radHZCsfFl", + "security_contact": "ezwkUqrunA", + "details": "ccdxOHlWVD" + }, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.136074064855032333", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.154479519358430381" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7vpfm9vgvxg3sqwsn8y6yacfnwvqf3760dck340wqzsnnpntcgy5h0jt4", + "status": 1, + "tokens": "2108075856", + "delegator_shares": "2108075856.000000000000000000", + "description": { + "moniker": "VxaqXomXpv", + "identity": "NwxmDYXCmJ", + "website": "ATfeeNFFvx", + "security_contact": "TiYWqKMRkn", + "details": "FGaauJzXXI" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.940000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.854090879535681556" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvg5y5xv9eu0yd4rfztn6pehqnxcc0hy7wxll35vfthehmg2w59nvqk80pv", + "status": 1, + "tokens": "6669052939", + "delegator_shares": "6669052939.000000000000000000", + "description": {}, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.130000000000000000", + "max_rate": "0.130000000000000000", + "max_change_rate": "0.074054826101930076" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqwclfkt", + "status": 3, + "tokens": "34459325260", + "delegator_shares": "34459325260.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.033986343509044787", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.090000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7ah3flgscnydj0lgv96mv5s6lwsnvj7spwh06kke4exwq5m0aqz862l0e", + "status": 1, + "tokens": "927350399", + "delegator_shares": "927350399.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.694665412425584983", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.750000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7t4673v", + "status": 3, + "tokens": "55948291091", + "delegator_shares": "55948291091.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.440048441195653325", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.180789237411591672" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfj7kzn2s97tteld9ssyqy7jg0clhn0zhp8zuwwmhw8uxhhgc7g4zjzn7xn", + "status": 1, + "tokens": "4006205", + "delegator_shares": "4006205.000000000000000000", + "description": { + "moniker": "fyHblDkCys", + "identity": "WCDOcZEgti", + "website": "bbUYFhGpRR", + "security_contact": "fhfKBLrEvy", + "details": "kRIUubHcwr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.603701710007259889", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.099074121449624859" + }, + "update_time": "9936-01-01T08:09:55Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5r4xrdd", + "status": 3, + "tokens": "15675831119", + "delegator_shares": "15675831119.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvvf87wq27y92aaj8csgp4s4vqu69xtm4td3qdp3pr5etfrdn6v7ws3hsmv", + "status": 1, + "tokens": "12890424126", + "delegator_shares": "12890424126.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.124802770472432716", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.173959658484508482" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt62glh2fvu9vulmgvh6xqupdqk49yzpk497jcjayystchx48f4kx8v59u0", + "status": 1, + "tokens": "7052466205", + "delegator_shares": "7052466205.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.003525430478281768", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.016675882352481766" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqth5wr26d7sltuj00csrl3f3zly9nxuj4lkfyq0hr0xrxcfu6tsz5qhdhsw", + "status": 1, + "tokens": "8559089572", + "delegator_shares": "8559089572.000000000000000000", + "description": { + "moniker": "otFXajfWNI", + "identity": "xXrEsBXwpv", + "website": "XlaJwNhjAq", + "security_contact": "svEFXzNNQS", + "details": "fTnIHUVEnv" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.204542425183727119", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.145658560298436900" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czwem9y4", + "status": 3, + "tokens": "45487475001", + "delegator_shares": "45487475001.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.177753292751501209", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.323174353688819429" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxe7jutz", + "status": 3, + "tokens": "24261774404", + "delegator_shares": "24261774404.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.017452646416466178", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.020000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4svau85d", + "status": 3, + "tokens": "31770155824", + "delegator_shares": "31770155824.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.138735148670316454", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.286634953103815529" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtumyzl7hulm5v6delsx7hdpcye3stda9rxz6jgjf2eykqm2jh20kej9nsj", + "status": 1, + "tokens": "6275641534", + "delegator_shares": "6275641534.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.055704912322332987", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.094301772909367460" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2n3nxrwxc027jequjln9ps5546ahg3p2h3t3lm4u9vmahke8kxw6lm9f7j", + "status": 1, + "tokens": "10074815927", + "delegator_shares": "10074815927.000000000000000000", + "description": { + "moniker": "BqXVhGrdzr", + "identity": "BssMXIyaOa", + "website": "SMUxWlPGrv", + "security_contact": "CLeUdBrDWI", + "details": "YWFtSWANuy" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.004105601830262673", + "max_rate": "0.030000000000000000", + "max_change_rate": "0.028348463914291344" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf0u600sgl3zdn3uh4jd6jmw6fc0jc40r0l2crvz3sla3f8d32flghwtxaq", + "status": 3, + "tokens": "37602205867", + "delegator_shares": "37602205867.000000000000000000", + "description": { + "moniker": "BUZauhlQrt", + "identity": "yuIKzyGzQS", + "website": "fDSmxAmazc", + "security_contact": "jVDWgXPhkM", + "details": "LBFAwsUoyi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.244517333363622892", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.153245122134586562" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "consensus_pubkey": "cosmosvalconspub1addwnpepqduttph6whz8ngwywhy0hu3c9kxww3hqh0f0mrdkjcvg2h8q3u8cvfu0qkl", + "status": 1, + "tokens": "593652129", + "delegator_shares": "593652129.000000000000000000", + "description": { + "moniker": "xjWbnHCfWc", + "identity": "JaWoTPxlVR", + "website": "VWTFFWylBY", + "security_contact": "CgwYhkKzfA", + "details": "BfFlSjcVHR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.192959054535463189", + "max_rate": "0.380000000000000000", + "max_change_rate": "0.167893162151719645" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0zx0lgud48vvwy6lts09r2l9e8yd5smkjfzzmfsfw9ps33400vwgduselz", + "status": 1, + "tokens": "6967497396", + "delegator_shares": "6967497396.000000000000000000", + "description": { + "moniker": "wZjmyfrmLF", + "identity": "SdxpPXgzQU", + "website": "ojcVqTNCTA", + "security_contact": "JNsQWMMEYr", + "details": "ptoagqGEJY" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.051995396939424988", + "max_rate": "0.720000000000000000", + "max_change_rate": "0.097236596735632381" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2prz4vype8mhmwnvw537vf53ftm02nlpgefm002drthw6py353323jw5e6", + "status": 1, + "tokens": "211016457", + "delegator_shares": "211016457.000000000000000000", + "description": { + "moniker": "IERTNdjcys", + "identity": "RMlZikkNjk", + "website": "HiWCYkrvig", + "security_contact": "PKUdCVyvke", + "details": "QntRmnlGZt" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.735573943921984982", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.090597702660368454" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvrk5jlckmpf0spqdh7a204qtectsss5mznvsl7sjtget8msrg20xlugv3v", + "status": 1, + "tokens": "1201306698", + "delegator_shares": "1201306698.000000000000000000", + "description": { + "moniker": "CGInszCvjL", + "identity": "rUJDJazuTG", + "website": "PYbkObcHdn", + "security_contact": "lVynehLrSd", + "details": "eYRpCKYvrx" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.297069068496065785", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.475462668160887599" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvhqzk07yeludsgh0nffk465d2seqmav2prd2rs6alu56l75w3dyyv7fu28", + "status": 1, + "tokens": "3167117301", + "delegator_shares": "3167117301.000000000000000000", + "description": { + "moniker": "ydQcLezwwL", + "identity": "KtTnlmLXCN", + "website": "KUDIKfgAiY", + "security_contact": "ntlISyWbkj", + "details": "fbspSWJDAB" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.222447677870840972", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.194980583372334332" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzue70ade", + "status": 3, + "tokens": "37676305948", + "delegator_shares": "37676305948.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.260000000000000000", + "max_rate": "0.260000000000000000", + "max_change_rate": "0.239035612898447459" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj2sy3f5", + "status": 3, + "tokens": "26737755597", + "delegator_shares": "26737755597.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.420000000000000000", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.295551090875771737" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgxhtkut5ur5pju0zjkw8lhhfyusz3x409c6qet8yrpd0p7czcadg3sg3mx", + "status": 1, + "tokens": "3436201124", + "delegator_shares": "3436201124.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.115615158377471618", + "max_rate": "0.460000000000000000", + "max_change_rate": "0.219100078099573524" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw8vy48pqzssprlmhvtvtc0hh88lv3uuz6etntlzn9nqznp2r8ewsp2p20f", + "status": 1, + "tokens": "199636304", + "delegator_shares": "199636304.000000000000000000", + "description": { + "moniker": "LsyIcWgMDs", + "identity": "waVauWkwVA", + "website": "oEbvwjXcuI", + "security_contact": "EGRmIniXNY", + "details": "dtZZypERzx" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.247966845740203972", + "max_rate": "0.260000000000000000", + "max_change_rate": "0.206307125726817588" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvhet24yk50y4m60mceffquewu9p4enwrgcum0csceuull7a59u6567nn0v", + "status": 3, + "tokens": "20405570669", + "delegator_shares": "20405570669.000000000000000000", + "description": { + "moniker": "ZeprycSOnc", + "identity": "ZcHuivhMFq", + "website": "hCsVpTWmaL", + "security_contact": "AIKsDuUCDR", + "details": "EgpxVbAOaK" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.054000324644638628", + "max_rate": "0.380000000000000000", + "max_change_rate": "0.120973196882786975" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqww4ac9sdmwjurlwyea8de788rvdqu2gwzv5ukdqnsefzyfjdjtgvzlz3gr", + "status": 1, + "tokens": "7656253701", + "delegator_shares": "7656253701.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.136480139358851972", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.124002561027484210" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", + "consensus_pubkey": "cosmosvalconspub1addwnpepq28x4gcrklk8r22c650tktvywp0hfwv8hwtc0heq6d8wr2kagh2j69eaujq", + "status": 1, + "tokens": "5987604552", + "delegator_shares": "5987604552.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.224924640665354113", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.083804383012326481" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwsf5usr95lzjzve9ap7347d4a8ws0fry32d0428e8elme2m4xe4qy335ne", + "status": 1, + "tokens": "11089478639", + "delegator_shares": "11089478639.000000000000000000", + "description": { + "moniker": "lccuIyGWcn", + "identity": "NZWAFQchWA", + "website": "yXQblCIJFQ", + "security_contact": "nnvdMbLnJq", + "details": "ibClAKBstR" + }, + "unbonding_height": "6", + "unbonding_time": "9936-01-01T04:22:01Z", + "commission": { + "commission_rates": { + "rate": "0.111667297951264416", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.054094041387600362" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgh6neaxc5qc82vrng427tmhlw78y4205pselprm387vgy5vkgvhc8vzhp8", + "status": 1, + "tokens": "9873924532", + "delegator_shares": "9873924532.000000000000000000", + "description": { + "moniker": "ZetnggqSeu", + "identity": "DYVdEOVlTH", + "website": "xPuLnecvry", + "security_contact": "LDzeTzsHFF", + "details": "OUlzqRajSn" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.382653580593648245", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.156454412026067119" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0tus4q4stns9dvru8ju7zdsjqqupgjwf3g4zlux4805ku0ccck2fht2a", + "status": 1, + "tokens": "247885300", + "delegator_shares": "247885300.000000000000000000", + "description": { + "moniker": "wnfRnuwTaN", + "identity": "PsxoKqHBAd", + "website": "UxeEfnWIuY", + "security_contact": "YBArDihhbI", + "details": "XzasuCeQcL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.361954185750494828", + "max_rate": "0.400000000000000000", + "max_change_rate": "0.275644004976418184" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6k07476", + "status": 3, + "tokens": "25102040344", + "delegator_shares": "25102040344.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.599184934718890393", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgh9lxfuk4amzsp0w28t8dkdwf2xk8yrxjj7xz0lnmzs2lyahrdz2f2yy35", + "status": 3, + "tokens": "17609505538", + "delegator_shares": "17609505538.000000000000000000", + "description": { + "moniker": "yAwjGcNsZH", + "identity": "STCkyPeJjc", + "website": "yvmEPebWkk", + "security_contact": "ZficJLXKJM", + "details": "qAWHtJiitW" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.690000000000000000", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.509977105992119960" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt0sk5rhcpv85mjvladxx3ygs0auglwcm4xpurjqeex8z99ya86363zl4ug", + "status": 2, + "tokens": "7847492642", + "delegator_shares": "7847492642.000000000000000000", + "description": {}, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.546622488015386807", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.175928838659210799" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdhcc8jww3jnsk9s3syxvwqdur5w8lzgvgujsu0j8n944m68ux2d2km69mk", + "status": 1, + "tokens": "12249202554", + "delegator_shares": "12249202554.000000000000000000", + "description": { + "moniker": "grFECXszmI", + "identity": "NuvdSJPltV", + "website": "HvSdvMKYkc", + "security_contact": "gqBEvgzWty", + "details": "AqGxwBvLuq" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.413759057762081199", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.211740487873750444" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqghn86gscad5np6l2h0zte7qa4gylqvkzdznqwknhrxk6v7al09zvqvzm8s", + "status": 1, + "tokens": "9487692660", + "delegator_shares": "9487692660.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.167663118910141794", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.257899452167596882" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "consensus_pubkey": "cosmosvalconspub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjycl58l", + "status": 3, + "tokens": "41119826715", + "delegator_shares": "41119826715.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.025162698699691548" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75fh3auv", + "status": 3, + "tokens": "19565632897", + "delegator_shares": "19565632897.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.579061375935434182", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0k56l5wh6qrl4fmp9jl0v78qy4jahrkkl6xqjc2zmap6tjg4h23g8j409r", + "status": 1, + "tokens": "9398321077", + "delegator_shares": "9398321077.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.116448312344293007", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwskjpjy", + "status": 3, + "tokens": "44648874284", + "delegator_shares": "44648874284.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.258140043497759741", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.447039357737510640" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg57gy4ef", + "status": 3, + "tokens": "34209671267", + "delegator_shares": "34209671267.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.480455308806333346", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55hrcqtd", + "status": 3, + "tokens": "36900108763", + "delegator_shares": "36900108763.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.409558857679769509", + "max_rate": "0.930000000000000000", + "max_change_rate": "0.610998804526507722" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0sgshv9mf8qy7ff303mqqv5zppu3q4mcwrnheue8d3kq0ytyynkxlak2ae", + "status": 3, + "tokens": "28980476016", + "delegator_shares": "28980476016.000000000000000000", + "description": { + "moniker": "hVYOUraqpo", + "identity": "XRliNUdYgt", + "website": "FYzwRNeFsW", + "security_contact": "AYYtrdbBmx", + "details": "NaWAwUYhir" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2d8k6kg75hjwqyknda4mj9wc65v7rzcqenfv039tnkwjss5tuq723hs8yv", + "status": 1, + "tokens": "9001683044", + "delegator_shares": "9001683044.000000000000000000", + "description": {}, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.453113774608032219", + "max_rate": "0.950000000000000000", + "max_change_rate": "0.571183533543927226" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwux9qwtmnuzxkw7203qndplmsvj6lpw9670wlu6sgaw6y30tzuhjh0pg3h", + "status": 1, + "tokens": "13444158275", + "delegator_shares": "13444158275.000000000000000000", + "description": { + "moniker": "yFGOJKrIlc", + "identity": "bGyYKcRfzP", + "website": "IRcsWPqPJj", + "security_contact": "oboQYAvKUQ", + "details": "imjjiiwgwg" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.179273604024357441", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.033903582588444164" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwa26gwxuwwnhmgz57tcvyqvj23qft9wryeutcms0z4ss9f5tujfc8t240p", + "status": 1, + "tokens": "3562717063", + "delegator_shares": "3562717063.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.075850735550956083", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.068439348734071304" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxd2wcms", + "status": 3, + "tokens": "27742737411", + "delegator_shares": "27742737411.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.870000000000000000", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.402061609548054151" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw2gxruh52umsuh8jd7g78587jx0qd4skze2u2dm0sm8shx64tvcceje270", + "status": 1, + "tokens": "2240964465", + "delegator_shares": "2240964465.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.028869386567010989", + "max_rate": "0.190000000000000000", + "max_change_rate": "0.173195857712675899" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2x30aum6t8lauwqh72szktjx6fmgf5ux7vcs38uukp9a5h287wawhv5mfv", + "status": 3, + "tokens": "17377751306", + "delegator_shares": "17377751306.000000000000000000", + "description": { + "moniker": "SslqJkEqrN", + "identity": "qMdXPqvbCt", + "website": "HDwwjWlugU", + "security_contact": "LzWMObthwF", + "details": "zlyoRqwOQS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.498765541593724538", + "max_rate": "0.530000000000000000", + "max_change_rate": "0.156108348646223859" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtn32axxpw98r75zep2c0y45qf5fdgt0u334humpn08gxv0rxuya5ggzdsq", + "status": 1, + "tokens": "965626724", + "delegator_shares": "965626724.000000000000000000", + "description": { + "moniker": "QLuovrSeqS", + "identity": "YUQNkExwnl", + "website": "XdRdVvbQcS", + "security_contact": "bwGwmqdTzE", + "details": "IeauAPqpMI" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020000000000000000", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.009367009125578098" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3lu0qw8kj", + "status": 3, + "tokens": "25431851328", + "delegator_shares": "25431851328.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.450461328836777178", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.254665389885134513" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwvyafhmcqnhjk3t6jzdah2rzaq2cqpmz9fgll8493g9nrpcxz4sc7um4ft", + "status": 1, + "tokens": "2479274676", + "delegator_shares": "2479274676.000000000000000000", + "description": { + "moniker": "ypOtLDecZT", + "identity": "LIaJHuYasM", + "website": "bYFtipdQBr", + "security_contact": "iMgHhjMBDk", + "details": "cOpQhsluAN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.525025256762086999", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.151736980542240639" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvtj36dsackmy4p87dys4377ysum2zku3v7tjqtf5jhluzgxk5vqqlcyug9", + "status": 1, + "tokens": "4394402323", + "delegator_shares": "4394402323.000000000000000000", + "description": { + "moniker": "UNrltmiFQU", + "identity": "HlRxPRAiWn", + "website": "miHKtnKEFq", + "security_contact": "GGQHyuiUNg", + "details": "SDyPeWiIir" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.423728810514445933", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcf30j9c", + "status": 3, + "tokens": "74690344989", + "delegator_shares": "74690344989.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.882630947578979215", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.960000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv9arcz0k33sqlng4lqppz6wjctjdpru7slvs2hrdhgagads37lr6xmuhma", + "status": 1, + "tokens": "5792662639", + "delegator_shares": "5792662639.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.930000000000000000", + "max_rate": "0.930000000000000000", + "max_change_rate": "0.196867569678551592" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdrcxqxr3pecujyd0zcx7hlhz3sgne5yrsc2d50rca9j87kuq9sdjp0hevd", + "status": 1, + "tokens": "1494931451", + "delegator_shares": "1494931451.000000000000000000", + "description": { + "moniker": "wpQIfxRBEt", + "identity": "RKTQHvPdJv", + "website": "iiJRommKHA", + "security_contact": "tglHlMyemj", + "details": "TKaMInrxao" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.523520119340770936", + "max_rate": "0.550000000000000000", + "max_change_rate": "0.245778725026844861" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr2mqfkju", + "status": 3, + "tokens": "27874325464", + "delegator_shares": "27874325464.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.459241580368376871", + "max_rate": "0.490000000000000000", + "max_change_rate": "0.448990769658695281" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngklt9fqt", + "status": 3, + "tokens": "68086107574", + "delegator_shares": "68086107574.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.280411773058535090", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.009358685901125498" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg32fxsuegycskpe8m8mzkatq2gn0ge2nalp20xfmvjds36g8rytst6p8gf", + "status": 1, + "tokens": "4710928894", + "delegator_shares": "4710928894.000000000000000000", + "description": { + "moniker": "uLphnQcEDA", + "identity": "seBSPjZpUV", + "website": "awrAGlbOAE", + "security_contact": "gpsZdtvwFl", + "details": "POIzbuYNCV" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.436432231066822901", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.169101910040208464" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf399d5j3n6kaexaha66ucrjr4agzvmk6xpyy54lhgqy486mhe7fwwdg6aq", + "status": 1, + "tokens": "243353645", + "delegator_shares": "243353645.000000000000000000", + "description": { + "moniker": "QzTJXyuVaj", + "identity": "QXgGvfesKW", + "website": "sKaGvCtuno", + "security_contact": "NjeTETgEPj", + "details": "FzKZiPFLWh" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.390000000000000000", + "max_rate": "0.390000000000000000", + "max_change_rate": "0.160488857709882419" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdq8fheeu", + "status": 3, + "tokens": "25446232136", + "delegator_shares": "25446232136.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.073669961838812257", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.338443455873010612" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdjuv3ql5rv5njym62quduw7554as4aa8seufp7f4zv6q28tds2e23v4cv5", + "status": 3, + "tokens": "35741739231", + "delegator_shares": "35741739231.000000000000000000", + "description": { + "moniker": "MoJgIrbTvT", + "identity": "rTfyDjhPlV", + "website": "fXpRItnlwS", + "security_contact": "tIlMCZPLDi", + "details": "QoSUrnFXNb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.037606710200997532", + "max_rate": "0.610000000000000000", + "max_change_rate": "0.432717335122536998" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgkr2p0m3r8u4xaeydfcgmy66nr6whqkfc3fjk7ja0uzw7jzyw46xyx2g7a", + "status": 1, + "tokens": "781062755", + "delegator_shares": "781062755.000000000000000000", + "description": { + "moniker": "bPnQNoLOAC", + "identity": "eGrzxmpmZa", + "website": "SlgcHbrMAz", + "security_contact": "BsjVMIwBin", + "details": "zMLZagxpxk" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.087145043936985654", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.080927128094101738" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwvhpfht", + "status": 3, + "tokens": "19637280062", + "delegator_shares": "19637280062.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118259925415637398", + "max_rate": "0.220000000000000000", + "max_change_rate": "0.176572964585642890" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwajn7v8p6zuv8er2l5c5qwa2v3c86xw8sfhrj37a7x8353g2jspw96p9d3", + "status": 1, + "tokens": "13977340603", + "delegator_shares": "13977340603.000000000000000000", + "description": { + "moniker": "ugAGsihPAs", + "identity": "lCGAuZlvpp", + "website": "ivFSJyyaTn", + "security_contact": "DkGOtlUJqP", + "details": "OFODgAEDSm" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.004938453040925394", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.181525749527416405" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd9mxy4p6jva75efmzsjq5avn59j4n829vx6x9stw90wzg9urga0q5mm74w", + "status": 1, + "tokens": "120397764", + "delegator_shares": "120397764.000000000000000000", + "description": { + "moniker": "rKEeOLDkzz", + "identity": "CgBOpqCLEH", + "website": "IfBZCIaRWP", + "security_contact": "XHLGNxVQTC", + "details": "cjdFwSbCaV" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.005104745061935176", + "max_rate": "0.170000000000000000", + "max_change_rate": "0.163097753090489709" + }, + "update_time": "9936-01-01T14:57:22Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2y0j3sd9kxmqftpqxy9enzjuyzn08t26d5nk02anpwc0hezkzg4xq6vwx8", + "status": 1, + "tokens": "251933", + "delegator_shares": "251933.000000000000000000", + "description": { + "moniker": "NGOcYLtISS", + "identity": "akbHHffdaS", + "website": "EZXoBquUYT", + "security_contact": "XxIIhbuOPH", + "details": "BrcWmsrUNr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.025882905606214690", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.274885458100718873" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvvw2e0mvvrp6sp2y07kk2azrnfl3a2yacq05u5w57z90qjp2ngrj63tfw6", + "status": 1, + "tokens": "9823873258", + "delegator_shares": "9823873258.000000000000000000", + "description": { + "moniker": "kRMkymEDSB", + "identity": "qvuRLMGzrH", + "website": "vSlfyjYpQg", + "security_contact": "AOPUJgQrWP", + "details": "ndFZXPlXMr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.276493152947542370", + "max_rate": "0.490000000000000000", + "max_change_rate": "0.212232519907549121" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwaazwez", + "status": 3, + "tokens": "56856814851", + "delegator_shares": "56856814851.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.093189165744722643", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.044880981942823250" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", + "consensus_pubkey": "cosmosvalconspub1addwnpepq06e0dm4ey2l32nxhrycaez68egwtmj69vtq0hp77e7tf6cplnjc5uvjqtz", + "status": 1, + "tokens": "763826873", + "delegator_shares": "763826873.000000000000000000", + "description": { + "moniker": "FazIurAKdA", + "identity": "DpgBYLokOo", + "website": "CQDlLgAfWV", + "security_contact": "zXchJRCdOD", + "details": "iJdiDWPcgF" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.375080598711455047", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.805841917945325981" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtcxreszx2wu4ngd3amegdgh9549fr4yh4mgvs862ea44ugjv0leywawqen", + "status": 2, + "tokens": "2013818817", + "delegator_shares": "2013818817.000000000000000000", + "description": { + "moniker": "kcMqvkQeGm", + "identity": "ZKjzktvrAj", + "website": "EzWzZovCJZ", + "security_contact": "hwPlfWocdU", + "details": "vvHigjWyJK" + }, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.307501014763216711", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.592156519673221532" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtdv8njc56rymptecue8px6hxff297xt83s6w3m6yn0txy0e49ghsfu6hdh", + "status": 1, + "tokens": "10038955625", + "delegator_shares": "10038955625.000000000000000000", + "description": { + "moniker": "YMPYcTfNXV", + "identity": "hwJcjMjrtB", + "website": "mYdBZQGfkx", + "security_contact": "IBEYReGdlN", + "details": "jvbaZBHbFK" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.570000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd53md7mk6edgy52e2svr0j93ugzvz9s29axp9mcktw4d02fjcy660zqv62", + "status": 1, + "tokens": "82979650", + "delegator_shares": "82979650.000000000000000000", + "description": { + "moniker": "rCudEObWgx", + "identity": "RjLfgqvGwZ", + "website": "pNtHQchsLt", + "security_contact": "HmjsKTdqTq", + "details": "pVMyagMPve" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.359117607212693417", + "max_rate": "0.820000000000000000", + "max_change_rate": "0.213068837225456325" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvj6juduaknlhehjt785gk6vkv8qhqykv5d6zupvwafe38t0unzxgsq9mau", + "status": 1, + "tokens": "9221698754", + "delegator_shares": "9221698754.000000000000000000", + "description": { + "moniker": "SPmeYRxezu", + "identity": "JsfdtwKgSS", + "website": "uCONZqLKzt", + "security_contact": "SydRJqnnUx", + "details": "ykuadWmGDn" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.699765412672875774", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.690273764477740955" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfw46rg95l70w7lekt8eh7szxr7ms8mfhqvz0ywnpc7fu25f6hj72g5rq2r", + "status": 1, + "tokens": "5682430", + "delegator_shares": "5682430.000000000000000000", + "description": { + "moniker": "NSWxSbDfbr", + "identity": "KHpPUqXLbX", + "website": "rqTuqhgzjv", + "security_contact": "duYWuBTCiB", + "details": "JvcmUaPwcV" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.098043346521204171", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.077862966399052363" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyvxmu04", + "status": 3, + "tokens": "36122807193", + "delegator_shares": "36122807193.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.414145633705698803", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd2gmrd8aux64z50e58tu00n3yjunvqduf4xv3g3p6j3wpuxddex59mpcfe", + "status": 3, + "tokens": "16807158123", + "delegator_shares": "16807158123.000000000000000000", + "description": { + "moniker": "ZHKMxyLBmy", + "identity": "EwvvJnavFX", + "website": "DHXlVcQLfr", + "security_contact": "cqkJGwinbb", + "details": "CwxLKqsDci" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.054776212220005616", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.012318363733558931" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2p3sa8dkvz36pz6nusjdhm9aqlnrrldrszzuqd5qy7ssqztn99ggqpcdlz", + "status": 3, + "tokens": "48540826744", + "delegator_shares": "48540826744.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003549575739989554", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.001119527935415439" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycjhwrn7", + "status": 3, + "tokens": "29401856985", + "delegator_shares": "29401856985.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.243341366114153903", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.628404054381210058" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdaa2szanfjwhzucqfj0ct7ljhc3kew8am3h8sr8wqzlnh8df06g5th460y", + "status": 3, + "tokens": "24697024268", + "delegator_shares": "24697024268.000000000000000000", + "description": { + "moniker": "XYWZXrqRDE", + "identity": "MFgElwSSlb", + "website": "ZPGkarWAml", + "security_contact": "dFzxEZXTfo", + "details": "HRGbXKBEeq" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.550000000000000000", + "max_change_rate": "0.376530136432859216" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgtrcqtxc62uk24ac873z7ns2gz75znes579xk2m0xzxpjqswh08kh6nrm0", + "status": 2, + "tokens": "15012824613", + "delegator_shares": "15012824613.000000000000000000", + "description": { + "moniker": "TzIitNrGWU", + "identity": "UtpzgJMsxj", + "website": "KMxjEKqFGe", + "security_contact": "GczmfoVPHm", + "details": "fMoGrNqroM" + }, + "unbonding_height": "48", + "unbonding_time": "9936-01-04T18:13:47Z", + "commission": { + "commission_rates": { + "rate": "0.413119742047134521", + "max_rate": "0.590000000000000000", + "max_change_rate": "0.590000000000000000" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdefatxypu4fp0z52tp76zfp6sjx0feg8ffe5res6pxs520evrxdca7fxy2", + "status": 1, + "tokens": "228354642", + "delegator_shares": "228354642.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.313619258562376348", + "max_rate": "0.510000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w4r0vhq", + "status": 3, + "tokens": "41494205421", + "delegator_shares": "41494205421.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.070000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0qr3zl5rz8qxk4863w768w20vr6gx26sh7uxr5fvvv7d68jjr805eaavkr", + "status": 1, + "tokens": "1820280319", + "delegator_shares": "1820280319.000000000000000000", + "description": { + "moniker": "larTIwdGYJ", + "identity": "oQxxPrmfak", + "website": "tPGPkwLtUK", + "security_contact": "mbyBenqFQd", + "details": "wKOwWlCXff" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.213795341271049705", + "max_rate": "0.380000000000000000", + "max_change_rate": "0.007958552197021359" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0p5kfy8kvyj0rl0lguwv5fmqwpsa5cg7gm8mzldlej5smsm6hhmqpjf6fz", + "status": 1, + "tokens": "2580293599", + "delegator_shares": "2580293599.000000000000000000", + "description": {}, + "unbonding_height": "8", + "unbonding_time": "9936-01-01T08:58:43Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgc0dahup", + "status": 3, + "tokens": "39420206132", + "delegator_shares": "39420206132.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.109747630034489371", + "max_rate": "0.970000000000000000", + "max_change_rate": "0.461346401411912639" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkn6paax", + "status": 3, + "tokens": "23703504292", + "delegator_shares": "23703504292.000000000000000000", + "description": { + "moniker": "eXfwGKuzGb", + "identity": "dYpMrjwrPA", + "website": "DzaFOsditE", + "security_contact": "GuNLPoNZsM", + "details": "iALsKeROvR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.087538799057934086", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.859363741701174499" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyt542en", + "status": 3, + "tokens": "69725274862", + "delegator_shares": "69725274862.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.077835183941357357", + "max_rate": "0.630000000000000000", + "max_change_rate": "0.287966636331923139" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwfq28wcw9gn3mynr4pjdpd5hhert9hheg8qus862ymrt5ex6j75jlkuhe3", + "status": 3, + "tokens": "21764467799", + "delegator_shares": "21764467799.000000000000000000", + "description": { + "moniker": "ObWwGUpRaY", + "identity": "BCfhwnVexY", + "website": "SBehiPUtRR", + "security_contact": "jMhyvuyFaP", + "details": "LHYAZFxdaS" + }, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.075332177620667120", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.039077923270826524" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwa4x4g5600flnra6sk3xek8rqvuxsgcl2e6mh500hd5ukvn5hea2vkwtcq", + "status": 1, + "tokens": "227804730", + "delegator_shares": "227804730.000000000000000000", + "description": { + "moniker": "OREyTcVRpI", + "identity": "qZaHHICplm", + "website": "qLLvRrRHco", + "security_contact": "jAyHoSHCWl", + "details": "CIyKCjIsrZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.090000000000000000", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsrp7s99", + "status": 3, + "tokens": "25229713771", + "delegator_shares": "25229713771.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.420000000000000000", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.006473324874363207" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2u42wlmn9vx90thlzxmuckxdqt93w6ekdghk9v3rr8jvpp28tghvaxdzey", + "status": 1, + "tokens": "1397104980", + "delegator_shares": "1397104980.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.155081394052318110", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd5jsj53j7m0umzvh90dwanxhfxmpydhfazmsz978v9yuh05q0kxcyqtdla", + "status": 3, + "tokens": "16747268503", + "delegator_shares": "16747268503.000000000000000000", + "description": { + "moniker": "OuShqctNnC", + "identity": "MfQbnbeXdv", + "website": "OfOpteXCQn", + "security_contact": "qaSLhJmnUG", + "details": "vIuRzAnYuu" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.589668369513377579", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.640000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgd00cmdzck03zpu4vjerhqt8tp0th04ccpqyesxp93lgef9u4vzusmxtma", + "status": 1, + "tokens": "300592036", + "delegator_shares": "300592036.000000000000000000", + "description": { + "moniker": "JLCFllOWaH", + "identity": "xmzLNprDNm", + "website": "TuCltfQyUl", + "security_contact": "FnFBACeLgN", + "details": "QpBCVOFYRe" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.024279357344684238", + "max_rate": "0.210000000000000000", + "max_change_rate": "0.162470067092097594" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge726q0dwq", + "status": 3, + "tokens": "56914095343", + "delegator_shares": "56914095343.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.561558403350280399", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.088588598076790894" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzwg260rcucyql9q6rnkhayydygkjxk7ly526ue3nwsz356fe38jvhpztz", + "status": 1, + "tokens": "8325722649", + "delegator_shares": "8325722649.000000000000000000", + "description": { + "moniker": "DKkqNgpern", + "identity": "UaPNJrTXWa", + "website": "CRmVrQLcHP", + "security_contact": "simjpTROho", + "details": "LenVFOISIL" + }, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.308481491073534819", + "max_rate": "0.790000000000000000", + "max_change_rate": "0.724731225510437678" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwkc23a70ndeeapn057plztghd0udz8jvf06nxym6tzd305p2kgux9nw52y", + "status": 1, + "tokens": "4497117544", + "delegator_shares": "4497117544.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.128390426870278035", + "max_rate": "0.550000000000000000", + "max_change_rate": "0.236783251632041598" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvpvaw73dlelg9r4uclgtvvylvfysht9usz0wgsvrl5ztsca98fwuv8vekl", + "status": 1, + "tokens": "340930766", + "delegator_shares": "340930766.000000000000000000", + "description": { + "moniker": "GtnANTFzsD", + "identity": "mQAnJjWMXZ", + "website": "klPpVMalzv", + "security_contact": "ZlKqUPcaKh", + "details": "BvqBMmsKnj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.460000000000000000", + "max_rate": "0.460000000000000000", + "max_change_rate": "0.177656813330873825" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0us7fav4", + "status": 3, + "tokens": "53587404091", + "delegator_shares": "53587404091.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.148502470554898869", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.005661642347781868" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw32mxlzzzmmpks775cgclcsmypqhhz7765v03wnjf8cn4hsrw67tq2l8n", + "status": 3, + "tokens": "20301516153", + "delegator_shares": "20301516153.000000000000000000", + "description": { + "moniker": "ibdjDFXkFg", + "identity": "BhaqDbDPwH", + "website": "KoHplbnTSd", + "security_contact": "zgJBSepZRt", + "details": "anTLerUmWY" + }, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.092279263137073204", + "max_rate": "0.130000000000000000", + "max_change_rate": "0.062347977318301413" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4umtaftt", + "status": 3, + "tokens": "23438430919", + "delegator_shares": "23438430919.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.065104244001935780", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.087973256413395308" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "consensus_pubkey": "cosmosvalconspub1addwnpepqddlzxsvj50jm6uwsp29nua35j2ntam89f4gt28g2emwgvl5s786j7wgqf0", + "status": 1, + "tokens": "570046687", + "delegator_shares": "570046687.000000000000000000", + "description": { + "moniker": "czRmrRUsJE", + "identity": "UUVYRGhvlH", + "website": "IbvDgUUmEa", + "security_contact": "OGaCohwkPO", + "details": "yzqmTabmKs" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.115576668318745733", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.114266089646617209" + }, + "update_time": "9936-01-01T16:55:11Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wu8lrdvr", + "status": 3, + "tokens": "23476663612", + "delegator_shares": "23476663612.000000000000000000", + "description": { + "moniker": "qNlNvDKQWh", + "identity": "PdEEmVXzOP", + "website": "jyQRsxutdI", + "security_contact": "hTNdvfWkVQ", + "details": "gPNrXPrkeL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.830000000000000000", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.679717803083962746" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7pax9cuqs5vjjvhpmcgvy5dkqrrtrg6336c3xhyrchtegy2m387ccs037", + "status": 3, + "tokens": "19815525788", + "delegator_shares": "19815525788.000000000000000000", + "description": { + "moniker": "sJKzLUYWBq", + "identity": "ZzbWnFqPTq", + "website": "dlevXyAGdk", + "security_contact": "bnQNzwNRYP", + "details": "PaxiDbFCJj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.291627565410574418", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.017987067010819344" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd7yjw34urmgndhr8r8xr2pclxfx0djpjd0vtfgs3swpdwzprcjczjux4qs", + "status": 1, + "tokens": "657819384", + "delegator_shares": "657819384.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.075522174018022400", + "max_rate": "0.210000000000000000", + "max_change_rate": "0.001608427283172174" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd52427v4hwje032xlsv6gfzv6pa2247jeawtjwhnxndvczv8hhxck575j5", + "status": 1, + "tokens": "1028714701", + "delegator_shares": "1028714701.000000000000000000", + "description": { + "moniker": "HqyxoHhEFh", + "identity": "jWSGBNVszf", + "website": "dEzhiLdOIf", + "security_contact": "hyFJYpqAZe", + "details": "seLogPTgsK" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.029467520966307114", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.041496100825162181" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wel7d3l", + "status": 3, + "tokens": "25456865344", + "delegator_shares": "25456865344.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.293848609442759777", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.580000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6u59lzkg", + "status": 3, + "tokens": "44085124225", + "delegator_shares": "44085124225.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.045106108515206331", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.610987430943531252" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw6x8r9cuvkvguqdx24myp74yx7pxgsg2yfl7eqgghyspvqw2tylqrwrrad", + "status": 1, + "tokens": "12285580824", + "delegator_shares": "12285580824.000000000000000000", + "description": { + "moniker": "HzzzbNxxpx", + "identity": "ViiQdXCLBW", + "website": "OCLfzPwTWp", + "security_contact": "DfUgOxcVro", + "details": "RHrQEtzJzW" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.670000000000000000", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.575718185703869257" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xvdql9k", + "status": 3, + "tokens": "25311353934", + "delegator_shares": "25311353934.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.324580145668396309", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.480000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfd79ep9f3sj30yn4uvl5f65q6dzmddudu5a3m0szgpwlv3hjr0a6xrqhrg", + "status": 1, + "tokens": "3907335026", + "delegator_shares": "3907335026.000000000000000000", + "description": { + "moniker": "uXaNxxYTMQ", + "identity": "QJMnxUPYAd", + "website": "hkagAIrRvX", + "security_contact": "XEmGZxAkJW", + "details": "CyRBAsyicI" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.704312781551764893", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.631767833516112273" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdwm9nyqsl6vc99mf2mmsmuj5384f46a8jp797fcp49qgpuzkaqx509kf4a", + "status": 1, + "tokens": "10574606405", + "delegator_shares": "10574606405.000000000000000000", + "description": { + "moniker": "gEfoUrxzet", + "identity": "xjndEwlJFY", + "website": "IKwYkWCXHD", + "security_contact": "CXolURKfuk", + "details": "ToBdMlGWCh" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.226837298095829297", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.124175068502619156" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujgucg2ktdn", + "status": 3, + "tokens": "32745806516", + "delegator_shares": "32745806516.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.322505571100731689", + "max_rate": "0.520000000000000000", + "max_change_rate": "0.183472725952677048" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592jkkxzm", + "status": 3, + "tokens": "21858111883", + "delegator_shares": "21858111883.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.799310131872627643", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.706235617003159879" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxtyq8dz", + "status": 3, + "tokens": "28684472849", + "delegator_shares": "28684472849.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.174404138163737710", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.360000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + } + ], + "delegations": [ + { + "delegator_address": "cosmos1qqxeqqvjkh2ls3a0taukd8rydrqqad690nxkcc", + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "shares": "12420219756.000000000000000000" + }, + { + "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", + "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "shares": "4141412671.000000000000000000" + }, + { + "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "shares": "61614117.000000000000000000" + }, + { + "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "shares": "138733335.000000000000000000" + }, + { + "delegator_address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "shares": "5978697013.000000000000000000" + }, + { + "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "shares": "6479198849.000000000000000000" + }, + { + "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "shares": "331591913.000000000000000000" + }, + { + "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "shares": "2560223943.000000000000000000" + }, + { + "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "shares": "9192729008.000000000000000000" + }, + { + "delegator_address": "cosmos1qy0qwzljplfauvyhgayw6nxte2zxujh4tnq09z", + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "shares": "17076084961.000000000000000000" + }, + { + "delegator_address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "shares": "8265210908.000000000000000000" + }, + { + "delegator_address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "shares": "3423234396.000000000000000000" + }, + { + "delegator_address": "cosmos1q9ed2n5wvzcrymaqltypazqzd2xv8d5aw58flt", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", + "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "shares": "8434736549.000000000000000000" + }, + { + "delegator_address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "shares": "11322194414.000000000000000000" + }, + { + "delegator_address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429", + "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "shares": "17931279589.000000000000000000" + }, + { + "delegator_address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "shares": "9657784018.000000000000000000" + }, + { + "delegator_address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "shares": "9950725535.000000000000000000" + }, + { + "delegator_address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "shares": "250632594.000000000000000000" + }, + { + "delegator_address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "shares": "24818709486.000000000000000000" + }, + { + "delegator_address": "cosmos1q0cw6hmrm4myx5c3zzmw6deelygsl2hrts2ju4", + "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", + "shares": "998337488.000000000000000000" + }, + { + "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "shares": "14607898235.000000000000000000" + }, + { + "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "shares": "1211564528.000000000000000000" + }, + { + "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "shares": "1294419142.000000000000000000" + }, + { + "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "shares": "12945220697.000000000000000000" + }, + { + "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", + "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "shares": "15545552914.000000000000000000" + }, + { + "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "shares": "6110815364.000000000000000000" + }, + { + "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "shares": "26325596.000000000000000000" + }, + { + "delegator_address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", + "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", + "shares": "632273041.000000000000000000" + }, + { + "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "shares": "393807838.000000000000000000" + }, + { + "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", + "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", + "shares": "847666854.000000000000000000" + }, + { + "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "shares": "12287749425.000000000000000000" + }, + { + "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "shares": "924245075.000000000000000000" + }, + { + "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "shares": "809035601.000000000000000000" + }, + { + "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "shares": "78323397.000000000000000000" + }, + { + "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "shares": "38918270.000000000000000000" + }, + { + "delegator_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", + "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", + "shares": "1750195180.000000000000000000" + }, + { + "delegator_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "shares": "4025204231.000000000000000000" + }, + { + "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", + "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "shares": "4432663925.000000000000000000" + }, + { + "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "shares": "20636678155.000000000000000000" + }, + { + "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "shares": "3413891512.012381154639588436" + }, + { + "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "shares": "6251197681.000000000000000000" + }, + { + "delegator_address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "shares": "7134357042.000000000000000000" + }, + { + "delegator_address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "shares": "2196379282.000000000000000000" + }, + { + "delegator_address": "cosmos1q6eeennfulay5kz3lym38up6gq5ruf6h43cg94", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "shares": "17332637313.000000000000000000" + }, + { + "delegator_address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "shares": "4686886799.000000000000000000" + }, + { + "delegator_address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "shares": "20382455281.000000000000000000" + }, + { + "delegator_address": "cosmos1qlkz3yutzuz0el2ullpyyaflfp78x8rr2cgld7", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "shares": "24971252484.000000000000000000" + }, + { + "delegator_address": "cosmos1py3htj8kmztj0ecdrhcgcmet6vupr9hvlhxkwe", + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "shares": "21846969213.000000000000000000" + }, + { + "delegator_address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "shares": "17451346039.000000000000000000" + }, + { + "delegator_address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "shares": "43687807.000000000000000000" + }, + { + "delegator_address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "shares": "18580691943.000000000000000000" + }, + { + "delegator_address": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", + "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "shares": "24914473521.000000000000000000" + }, + { + "delegator_address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "shares": "9687342330.000000000000000000" + }, + { + "delegator_address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "shares": "2725727123.000000000000000000" + }, + { + "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "shares": "107356796.000000000000000000" + }, + { + "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "shares": "652452.000000000000000000" + }, + { + "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", + "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", + "shares": "5044911319.000000000000000000" + }, + { + "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "shares": "11344768409.000000000000000000" + }, + { + "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "shares": "22896384744.000000000000000000" + }, + { + "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "shares": "2172957336.000000000000000000" + }, + { + "delegator_address": "cosmos1pca5ng2s37clfh72ea806j9fwvpng4fjq3ey5s", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "shares": "15497814344.000000000000000000" + }, + { + "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", + "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", + "shares": "203339835.000000000000000000" + }, + { + "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "shares": "23419734247.000000000000000000" + }, + { + "delegator_address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "shares": "4778016243.000000000000000000" + }, + { + "delegator_address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "shares": "20291325837.000000000000000000" + }, + { + "delegator_address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "shares": "1415578984.000000000000000000" + }, + { + "delegator_address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", + "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", + "shares": "7304584820.000000000000000000" + }, + { + "delegator_address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c", + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "shares": "1670822058.000000000000000000" + }, + { + "delegator_address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", + "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", + "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "shares": "30094589894.000000000000000000" + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "shares": "1195742287.000000000000000000" + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "shares": "1246069516.000000000000000000" + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "shares": "1455198371.000000000000000000" + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "shares": "1517022388.000000000000000000" + }, + { + "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "shares": "1056544107.000000000000000000" + }, + { + "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "shares": "22844129667.000000000000000000" + }, + { + "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "shares": "38719909925.000000000000000000" + }, + { + "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "shares": "2225212413.000000000000000000" + }, + { + "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "shares": "12278061721.000000000000000000" + }, + { + "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", + "shares": "101462019.000000000000000000" + }, + { + "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "shares": "49181074.000000000000000000" + }, + { + "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "shares": "5174807457.000000000000000000" + }, + { + "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "shares": "19076209513.000000000000000000" + }, + { + "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "shares": "686761769.000000000000000000" + }, + { + "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "shares": "5993132567.000000000000000000" + }, + { + "delegator_address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", + "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", + "shares": "5183376555.000000000000000000" + }, + { + "delegator_address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "shares": "63638410.000000000000000000" + }, + { + "delegator_address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "shares": "1793233946.000000000000000000" + }, + { + "delegator_address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "shares": "13273588734.000000000000000000" + }, + { + "delegator_address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "shares": "7610845.000000000000000000" + }, + { + "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "shares": "6189191937.000000000000000000" + }, + { + "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "shares": "1085633282.000000000000000000" + }, + { + "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "shares": "735588360.000000000000000000" + }, + { + "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "shares": "18880150143.000000000000000000" + }, + { + "delegator_address": "cosmos1zsspke0nqudcl0lh747ppqcsy396245akc2vtl", + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "shares": "28973013721.000000000000000000" + }, + { + "delegator_address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6", + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "shares": "27081595327.000000000000000000" + }, + { + "delegator_address": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1zjzkk7l2jalrspy6500my8v0yy6ycz7el534zw", + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "shares": "562972916.000000000000000000" + }, + { + "delegator_address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "shares": "15744595023.000000000000000000" + }, + { + "delegator_address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "shares": "7684584877.000000000000000000" + }, + { + "delegator_address": "cosmos1znvq8jqpwxt5hk2lg5654l7eg7kap3rpgjm462", + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "shares": "13141132625.000000000000000000" + }, + { + "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", + "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "shares": "1866755172.000000000000000000" + }, + { + "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "shares": "1630410562.000000000000000000" + }, + { + "delegator_address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "shares": "6990856673.000000000000000000" + }, + { + "delegator_address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", + "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "shares": "4660200511.000000000000000000" + }, + { + "delegator_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "shares": "1580119322.000000000000000000" + }, + { + "delegator_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", + "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "shares": "376238441.000000000000000000" + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "shares": "7302955.000000000000000000" + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", + "shares": "5951502740.000000000000000000" + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "shares": "3978844161.000000000000000000" + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "shares": "2714965216.000000000000000000" + }, + { + "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "shares": "13283049905.000000000000000000" + }, + { + "delegator_address": "cosmos1zu50umwgah6jhx07sw04ry0pv7fnvkpjmn8vl9", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "shares": "10178017385.000000000000000000" + }, + { + "delegator_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "shares": "927515526.000000000000000000" + }, + { + "delegator_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "shares": "7100496609.000000000000000000" + }, + { + "delegator_address": "cosmos1zah0g92ytwdvpchd3sceuanu7knhtu224vnt5k", + "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "shares": "17763934255.000000000000000000" + }, + { + "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", + "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "shares": "1856911069.000000000000000000" + }, + { + "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "shares": "11887809820.000000000000000000" + }, + { + "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "shares": "9843285414.000000000000000000" + }, + { + "delegator_address": "cosmos1z7ruhrtfg8v2xv8egfyxldt2xaygspykszntzv", + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "shares": "984669335.000000000000000000" + }, + { + "delegator_address": "cosmos1z7sj5sg2cnkg4phzrswwjkkq8p2d6434pcyv2p", + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "shares": "404583402.000000000000000000" + }, + { + "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", + "shares": "9436725725.000000000000000000" + }, + { + "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "shares": "3355273089.000000000000000000" + }, + { + "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "shares": "3814662227.000000000000000000" + }, + { + "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "shares": "1933530153.000000000000000000" + }, + { + "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "shares": "141624981.000000000000000000" + }, + { + "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "shares": "18814602669.000000000000000000" + }, + { + "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "shares": "2514756351.000000000000000000" + }, + { + "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "shares": "6254739411.000000000000000000" + }, + { + "delegator_address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg", + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "shares": "10514537848.000000000000000000" + }, + { + "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "shares": "5810217010.000000000000000000" + }, + { + "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "shares": "1887976035.000000000000000000" + }, + { + "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "shares": "10725445.000000000000000000" + }, + { + "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "shares": "952138064.000000000000000000" + }, + { + "delegator_address": "cosmos1ryp2xkqe74y5kx6zffqtdc3wzgny8xg8eguupq", + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "shares": "1639136540.000000000000000000" + }, + { + "delegator_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "shares": "16848374286.000000000000000000" + }, + { + "delegator_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "shares": "5561406384.000000000000000000" + }, + { + "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "shares": "798486027.000000000000000000" + }, + { + "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "shares": "12788946759.000000000000000000" + }, + { + "delegator_address": "cosmos1rtw2ev4xm89vaqzwc7k520jlvrvlqnevk5f53y", + "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", + "shares": "12268746738.000000000000000000" + }, + { + "delegator_address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "shares": "2032334424.000000000000000000" + }, + { + "delegator_address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", + "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "shares": "3185714296.000000000000000000" + }, + { + "delegator_address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "shares": "1936045503.000000000000000000" + }, + { + "delegator_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", + "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "shares": "1620479191.000000000000000000" + }, + { + "delegator_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", + "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "shares": "10162772165.000000000000000000" + }, + { + "delegator_address": "cosmos1r572vr0k388gpjw5h2u75ppmarvgma20rqj2ws", + "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "shares": "16932030948.000000000000000000" + }, + { + "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", + "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", + "shares": "12584124.000000000000000000" + }, + { + "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "shares": "9220026.000000000000000000" + }, + { + "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "shares": "694971203.000000000000000000" + }, + { + "delegator_address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "shares": "19004884526.000000000000000000" + }, + { + "delegator_address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", + "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "shares": "2041910728.000000000000000000" + }, + { + "delegator_address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "shares": "8361945358.000000000000000000" + }, + { + "delegator_address": "cosmos1rcru2vteas2kunww3zt4knx28krlestxydpwza", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "shares": "20016004053.000000000000000000" + }, + { + "delegator_address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1r6j2xkpnnjve9c00c854laqp7l7zv8pxeksxrz", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "shares": "20554160964.000000000000000000" + }, + { + "delegator_address": "cosmos1rmyk79ktv6c8q48u78udw5p906fp0w058796d0", + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "shares": "251069497.000000000000000000" + }, + { + "delegator_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", + "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "shares": "3033965094.000000000000000000" + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "shares": "11989838708.000000000000000000" + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "shares": "2071677267.000000000000000000" + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "shares": "510250360.000000000000000000" + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "shares": "2727283744.000000000000000000" + }, + { + "delegator_address": "cosmos1r7kh63jvjhwqraux9wtm3jat8ggm437w9cxcxc", + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "shares": "1576771801.000000000000000000" + }, + { + "delegator_address": "cosmos1rlzurkn0mywyldswcafhu7r8r0tha4s5prs34u", + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "shares": "5545092214.000000000000000000" + }, + { + "delegator_address": "cosmos1rlltvm5ks32kh683c0w7epsjvg8aq2hvct27p6", + "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "shares": "71917474.000000000000000000" + }, + { + "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "shares": "3140280772.000000000000000000" + }, + { + "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "shares": "14337017011.000000000000000000" + }, + { + "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "shares": "4008660259.000000000000000000" + }, + { + "delegator_address": "cosmos1yrdtzqfkyum94q4v3j3xllrtf09qv0jvympw86", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "shares": "3161698569.000000000000000000" + }, + { + "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "shares": "1615518832.000000000000000000" + }, + { + "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "shares": "16529399133.000000000000000000" + }, + { + "delegator_address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", + "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", + "shares": "5346735375.000000000000000000" + }, + { + "delegator_address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "shares": "9559582899.000000000000000000" + }, + { + "delegator_address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933", + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "shares": "18217843326.000000000000000000" + }, + { + "delegator_address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", + "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "shares": "35129356.000000000000000000" + }, + { + "delegator_address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "shares": "5083047390.000000000000000000" + }, + { + "delegator_address": "cosmos1y3h72de80x06cz7fs3adwlnp0r8pjazw0r5707", + "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", + "shares": "3323388806.000000000000000000" + }, + { + "delegator_address": "cosmos1yj95f65syc75ptwcy0n7kafdq33awc2ve8hthq", + "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "shares": "313632363.000000000000000000" + }, + { + "delegator_address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a", + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "shares": "5078782917.000000000000000000" + }, + { + "delegator_address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "shares": "5608632459.000000000000000000" + }, + { + "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "shares": "2320211243.000000000000000000" + }, + { + "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "shares": "1727917227.000000000000000000" + }, + { + "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "shares": "1444898370.000000000000000000" + }, + { + "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "shares": "1561395724.000000000000000000" + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "shares": "5799285.000000000000000000" + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "shares": "5780519.000000000000000000" + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "shares": "19002817.000000000000000000" + }, + { + "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "shares": "12299732605.000000000000000000" + }, + { + "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "shares": "12769609475.000000000000000000" + }, + { + "delegator_address": "cosmos1ylf26t6vhvugawg87328ng2ug4d8f25syxp64c", + "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "shares": "24248574347.000000000000000000" + }, + { + "delegator_address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "shares": "7050196605.000000000000000000" + }, + { + "delegator_address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", + "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "shares": "4574405710.000000000000000000" + }, + { + "delegator_address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", + "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "shares": "86630682.000000000000000000" + }, + { + "delegator_address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", + "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "shares": "22058794240.000000000000000000" + }, + { + "delegator_address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "shares": "13382062777.000000000000000000" + }, + { + "delegator_address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "shares": "11687279303.000000000000000000" + }, + { + "delegator_address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "shares": "14549776414.000000000000000000" + }, + { + "delegator_address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", + "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "shares": "8566436836.000000000000000000" + }, + { + "delegator_address": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "shares": "5053223393.000000000000000000" + }, + { + "delegator_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "shares": "4129974295.000000000000000000" + }, + { + "delegator_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "shares": "681974899.000000000000000000" + }, + { + "delegator_address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", + "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "shares": "2510854249.000000000000000000" + }, + { + "delegator_address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "shares": "4659214363.000000000000000000" + }, + { + "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", + "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", + "shares": "2439056961.000000000000000000" + }, + { + "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", + "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "shares": "2600875484.000000000000000000" + }, + { + "delegator_address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "shares": "2726229723.000000000000000000" + }, + { + "delegator_address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "shares": "22343112357.000000000000000000" + }, + { + "delegator_address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "shares": "19543436761.000000000000000000" + }, + { + "delegator_address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "shares": "3468306722.000000000000000000" + }, + { + "delegator_address": "cosmos19deqn6g9q7mnhzg5j0qr25k9gz74pwlph5p50r", + "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "shares": "2125901000.000000000000000000" + }, + { + "delegator_address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "shares": "13749317760.000000000000000000" + }, + { + "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "shares": "671769813.000000000000000000" + }, + { + "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", + "shares": "290004202.000000000000000000" + }, + { + "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "shares": "852563445.000000000000000000" + }, + { + "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "shares": "22141837134.000000000000000000" + }, + { + "delegator_address": "cosmos193pvwgxpxnd6tgz0gtyl00dq8r3ygeflnhaxpm", + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos194x33ngarpaach5g69g60cd2pjq8h0hqkfvk35", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "shares": "2698972611.000000000000000000" + }, + { + "delegator_address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", + "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "shares": "3111978.000000000000000000" + }, + { + "delegator_address": "cosmos1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75pf45v0", + "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", + "shares": "5061822.000000000000000000" + }, + { + "delegator_address": "cosmos1xq58llsgh49tsz22grs28jk0p7tvswlcjcrl32", + "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", + "shares": "2859472400.000000000000000000" + }, + { + "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "shares": "96280874.000000000000000000" + }, + { + "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "shares": "3878595385.000000000000000000" + }, + { + "delegator_address": "cosmos1xxurm2uymwd04sjxqedjae5r0zxhalh26skxct", + "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "shares": "8374503099.000000000000000000" + }, + { + "delegator_address": "cosmos1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalavv03x7", + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "shares": "41888452.000000000000000000" + }, + { + "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "shares": "16141764494.000000000000000000" + }, + { + "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "shares": "3922123176.000000000000000000" + }, + { + "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "shares": "562769066.000000000000000000" + }, + { + "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", + "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "shares": "2583372381.000000000000000000" + }, + { + "delegator_address": "cosmos1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lpz963de", + "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "shares": "6669322099.000000000000000000" + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "shares": "23065486708.000000000000000000" + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", + "shares": "1751100.000000000000000000" + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "shares": "7682598.000000000000000000" + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "shares": "40546790.000000000000000000" + }, + { + "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "shares": "15549849.000000000000000000" + }, + { + "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", + "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "shares": "85878287.000000000000000000" + }, + { + "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "shares": "114707626.000000000000000000" + }, + { + "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "shares": "213312801.000000000000000000" + }, + { + "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "shares": "421593670.000000000000000000" + }, + { + "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "shares": "19101606110.000000000000000000" + }, + { + "delegator_address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", + "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "shares": "7824280124.000000000000000000" + }, + { + "delegator_address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", + "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", + "shares": "13735096388.000000000000000000" + }, + { + "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "shares": "1199565347.000000000000000000" + }, + { + "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "shares": "789297947.000000000000000000" + }, + { + "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "shares": "100158705.000000000000000000" + }, + { + "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "shares": "23869776733.000000000000000000" + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "shares": "2944397287.000000000000000000" + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "shares": "88293788.000000000000000000" + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "shares": "183795109.000000000000000000" + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "shares": "19236564.000000000000000000" + }, + { + "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "shares": "21819398696.000000000000000000" + }, + { + "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", + "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "shares": "127648169.000000000000000000" + }, + { + "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", + "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "shares": "9032281.000000000000000000" + }, + { + "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "shares": "1406012334.000000000000000000" + }, + { + "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", + "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "shares": "18778025755.000000000000000000" + }, + { + "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "shares": "3502640543.000000000000000000" + }, + { + "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "shares": "3559099530.000000000000000000" + }, + { + "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "shares": "463086222.000000000000000000" + }, + { + "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", + "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", + "shares": "1577104716.000000000000000000" + }, + { + "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "shares": "12679288910.000000000000000000" + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "shares": "1128230444.000000000000000000" + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "shares": "823335564.000000000000000000" + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "shares": "22035723908.000000000000000000" + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "shares": "138442642.000000000000000000" + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "shares": "730434945.000000000000000000" + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "shares": "240453816.000000000000000000" + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "shares": "943974869.000000000000000000" + }, + { + "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", + "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "shares": "81607574.000000000000000000" + }, + { + "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "shares": "24356273620.000000000000000000" + }, + { + "delegator_address": "cosmos188yd2umzwfwen7es68wrlh6auu3p8jhz0qfgej", + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "shares": "786295043.000000000000000000" + }, + { + "delegator_address": "cosmos18gmd4r8ydls55yvgda4d8pfandk0xem5q7eat8", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "shares": "19225895723.000000000000000000" + }, + { + "delegator_address": "cosmos18fkw6s4hnj2llxljrkleetgns2y0h0vjg8kmef", + "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "shares": "29256610441.000000000000000000" + }, + { + "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "shares": "12146467079.000000000000000000" + }, + { + "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "shares": "7709220756.000000000000000000" + }, + { + "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "shares": "5080809691.000000000000000000" + }, + { + "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "shares": "614084859.000000000000000000" + }, + { + "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", + "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", + "shares": "859335658.000000000000000000" + }, + { + "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "shares": "503691456.000000000000000000" + }, + { + "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "shares": "951735771.000000000000000000" + }, + { + "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "shares": "187053499.000000000000000000" + }, + { + "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "shares": "87813996.000000000000000000" + }, + { + "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", + "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "shares": "40933654.000000000000000000" + }, + { + "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "shares": "233343713.000000000000000000" + }, + { + "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "shares": "8989585334.000000000000000000" + }, + { + "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "shares": "7210211965.000000000000000000" + }, + { + "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "shares": "419006947.000000000000000000" + }, + { + "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "shares": "1418840382.000000000000000000" + }, + { + "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "shares": "9132286197.000000000000000000" + }, + { + "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "shares": "2272430680.000000000000000000" + }, + { + "delegator_address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", + "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "shares": "4778613408.000000000000000000" + }, + { + "delegator_address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "shares": "5734721271.000000000000000000" + }, + { + "delegator_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", + "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "shares": "2303096766.000000000000000000" + }, + { + "delegator_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "shares": "6852395930.000000000000000000" + }, + { + "delegator_address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "shares": "21228627.000000000000000000" + }, + { + "delegator_address": "cosmos18k4yz84xrjqvrq9u7sehvje3ax4aspcksauctw", + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "shares": "10553965715.000000000000000000" + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "shares": "8365880246.000000000000000000" + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "shares": "7622442762.000000000000000000" + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "shares": "3145157664.000000000000000000" + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "shares": "3139002667.000000000000000000" + }, + { + "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "shares": "721476141.000000000000000000" + }, + { + "delegator_address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "shares": "14744952147.000000000000000000" + }, + { + "delegator_address": "cosmos1864wj4twqatq54rrxl5jmfey55tmh0hvgmd9yw", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv", + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "shares": "12717644032.000000000000000000" + }, + { + "delegator_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "shares": "14461099488.000000000000000000" + }, + { + "delegator_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "shares": "6926527802.000000000000000000" + }, + { + "delegator_address": "cosmos1g95xvy8qgzcvcl05fse0mpxzdfv3w88tpexycr", + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "shares": "2300967060.000000000000000000" + }, + { + "delegator_address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", + "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "shares": "80752627.000000000000000000" + }, + { + "delegator_address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", + "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", + "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", + "shares": "1252735315.000000000000000000" + }, + { + "delegator_address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", + "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "shares": "8771546667.000000000000000000" + }, + { + "delegator_address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm", + "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", + "shares": "5701177554.000000000000000000" + }, + { + "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "shares": "17483443758.000000000000000000" + }, + { + "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "shares": "31595387940.000000000000000000" + }, + { + "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "shares": "7585898322.000000000000000000" + }, + { + "delegator_address": "cosmos1gwwltgyatg8yfe54447dxnyvs2nt6xxsl6lv2m", + "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "shares": "21998779909.000000000000000000" + }, + { + "delegator_address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", + "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", + "shares": "4474063302.000000000000000000" + }, + { + "delegator_address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "shares": "1958289106.000000000000000000" + }, + { + "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "shares": "2228638557.000000000000000000" + }, + { + "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "shares": "5090332.000000000000000000" + }, + { + "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "shares": "995636217.000000000000000000" + }, + { + "delegator_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", + "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", + "shares": "286435366.000000000000000000" + }, + { + "delegator_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", + "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", + "shares": "9095777401.000000000000000000" + }, + { + "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "shares": "12690053528.000000000000000000" + }, + { + "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "shares": "13987549940.000000000000000000" + }, + { + "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "shares": "20548231148.000000000000000000" + }, + { + "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "shares": "1886627332.000000000000000000" + }, + { + "delegator_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", + "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "shares": "8792247810.000000000000000000" + }, + { + "delegator_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "shares": "3178697313.000000000000000000" + }, + { + "delegator_address": "cosmos1gh67zgx4f9d64ctqhtascuh87805v8yffrfytl", + "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", + "shares": "602352708.000000000000000000" + }, + { + "delegator_address": "cosmos1gayzja3zz6unep8ftnpunt2wefazs3jhunl5az", + "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", + "shares": "4639932033.000000000000000000" + }, + { + "delegator_address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", + "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", + "shares": "556310530.000000000000000000" + }, + { + "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "shares": "74047563.000000000000000000" + }, + { + "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "shares": "526885228.000000000000000000" + }, + { + "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "shares": "17756476456.000000000000000000" + }, + { + "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "shares": "1439734010.000000000000000000" + }, + { + "delegator_address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "shares": "4300294602.000000000000000000" + }, + { + "delegator_address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "shares": "9627765333.000000000000000000" + }, + { + "delegator_address": "cosmos1glku8mx4nzp5crkjt7px9lfe4flfge3zf64tud", + "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "shares": "16236700229.000000000000000000" + }, + { + "delegator_address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "shares": "7078635448.000000000000000000" + }, + { + "delegator_address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", + "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "shares": "1447202506.000000000000000000" + }, + { + "delegator_address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2", + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1f2pvewnws73u0z5wsfmv5uqudwxl6jupfm6nta", + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "shares": "74135685.000000000000000000" + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "shares": "37913276.000000000000000000" + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "shares": "22265567297.000000000000000000" + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "shares": "150189421.000000000000000000" + }, + { + "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "shares": "1386448079.000000000000000000" + }, + { + "delegator_address": "cosmos1ftj05w0hmw2xxw5p7gvr258j2824qd8r2xdk9e", + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "shares": "12407365569.000000000000000000" + }, + { + "delegator_address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "shares": "209918859.000000000000000000" + }, + { + "delegator_address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "shares": "1956086691.000000000000000000" + }, + { + "delegator_address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "shares": "200187880.000000000000000000" + }, + { + "delegator_address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "shares": "335240579.000000000000000000" + }, + { + "delegator_address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", + "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "shares": "5071075450.000000000000000000" + }, + { + "delegator_address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", + "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "shares": "693338797.000000000000000000" + }, + { + "delegator_address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "shares": "9495710.000000000000000000" + }, + { + "delegator_address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "shares": "2744054731.000000000000000000" + }, + { + "delegator_address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "shares": "11738157290.000000000000000000" + }, + { + "delegator_address": "cosmos1f58nf9lzm4d5x9grnt3a3vd9c75szj95f6mm5s", + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "shares": "15007199497.000000000000000000" + }, + { + "delegator_address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "shares": "670350742.000000000000000000" + }, + { + "delegator_address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "shares": "590997851.000000000000000000" + }, + { + "delegator_address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "shares": "5720739029.000000000000000000" + }, + { + "delegator_address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4", + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "shares": "885018304.000000000000000000" + }, + { + "delegator_address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", + "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", + "shares": "12112810368.000000000000000000" + }, + { + "delegator_address": "cosmos1fc96780mrsxn5kgplhtna40qepjgrm9wsyly02", + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "shares": "15719680142.000000000000000000" + }, + { + "delegator_address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "shares": "3326376911.000000000000000000" + }, + { + "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", + "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "shares": "6536333612.000000000000000000" + }, + { + "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "shares": "13874964933.000000000000000000" + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "shares": "68061939.000000000000000000" + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "shares": "152484301.000000000000000000" + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "shares": "2534638254.000000000000000000" + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "shares": "7174712260.000000000000000000" + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "shares": "9519082012.000000000000000000" + }, + { + "delegator_address": "cosmos1f7utq63ae24m6aqw4metxjrc5q76j8h4gcgaxd", + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "shares": "23676093358.000000000000000000" + }, + { + "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "shares": "61726947.000000000000000000" + }, + { + "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", + "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "shares": "10554411.000000000000000000" + }, + { + "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "shares": "2095470160.000000000000000000" + }, + { + "delegator_address": "cosmos12q3w0j5hp023hdjafgc357hy7kkha296f4xrjf", + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "shares": "19013093201.000000000000000000" + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "shares": "1441730941.000000000000000000" + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "shares": "397947789.000000000000000000" + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "shares": "3804293134.000000000000000000" + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "shares": "1878391814.000000000000000000" + }, + { + "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "shares": "410769752.000000000000000000" + }, + { + "delegator_address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m", + "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", + "shares": "2878820932.000000000000000000" + }, + { + "delegator_address": "cosmos12r0m6hwrnn0jy02tnhmk328d7p68x2rndzt0j5", + "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "shares": "9649353957.000000000000000000" + }, + { + "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "shares": "4660142050.000000000000000000" + }, + { + "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "shares": "2714767582.000000000000000000" + }, + { + "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "shares": "8006017871.000000000000000000" + }, + { + "delegator_address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "shares": "782001327.000000000000000000" + }, + { + "delegator_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "shares": "2830380125.000000000000000000" + }, + { + "delegator_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", + "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "shares": "5637854002.000000000000000000" + }, + { + "delegator_address": "cosmos12f4fpl936ld8c64dxqgwv65p42na8dcnv9g7ku", + "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "shares": "4840284805.000000000000000000" + }, + { + "delegator_address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq", + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "shares": "592539582.000000000000000000" + }, + { + "delegator_address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "shares": "3855652978.000000000000000000" + }, + { + "delegator_address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", + "shares": "6943791722.000000000000000000" + }, + { + "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "shares": "276574162.000000000000000000" + }, + { + "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "shares": "689756170.000000000000000000" + }, + { + "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "shares": "900956465.000000000000000000" + }, + { + "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "shares": "1549115655.000000000000000000" + }, + { + "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "shares": "203058104.000000000000000000" + }, + { + "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "shares": "24771629701.000000000000000000" + }, + { + "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "shares": "16356624866.000000000000000000" + }, + { + "delegator_address": "cosmos124wz6pnykadgf3xchp6rdn9s2t9z5sgvl7597p", + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "shares": "6557300877.000000000000000000" + }, + { + "delegator_address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "shares": "6087225472.000000000000000000" + }, + { + "delegator_address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "shares": "638979230.000000000000000000" + }, + { + "delegator_address": "cosmos12eynrdzx2jqz5u92hgmhl9ga6hmghqfv0xvns8", + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "shares": "2461085809.000000000000000000" + }, + { + "delegator_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", + "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "shares": "2521177822.000000000000000000" + }, + { + "delegator_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", + "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "shares": "22548164258.000000000000000000" + }, + { + "delegator_address": "cosmos1tpxdvj93x9rqz89zhh0tszegcwtq8mgtdknrw5", + "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", + "shares": "13387012198.000000000000000000" + }, + { + "delegator_address": "cosmos1tzz5l8sw05e0tm5l0gxuvp04qt42stu3kqwf4s", + "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "shares": "7946485541.000000000000000000" + }, + { + "delegator_address": "cosmos1tz087eh88lqkesr77yl6ys9dw95qysfqtff52a", + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "shares": "25027795872.000000000000000000" + }, + { + "delegator_address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj", + "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "shares": "4050355196.000000000000000000" + }, + { + "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "shares": "4422731613.000000000000000000" + }, + { + "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "shares": "277893955.000000000000000000" + }, + { + "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "shares": "190512146.000000000000000000" + }, + { + "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "shares": "4469703294.000000000000000000" + }, + { + "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "shares": "9951710774.000000000000000000" + }, + { + "delegator_address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "shares": "2246266.000000000000000000" + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "shares": "9390268176.000000000000000000" + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "shares": "2399862586.000000000000000000" + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "shares": "264012997.000000000000000000" + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "shares": "1338628253.000000000000000000" + }, + { + "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "shares": "548629134.000000000000000000" + }, + { + "delegator_address": "cosmos1tgghhdcxdgxay7hp2p0lv2fs656c4c0xfzlga5", + "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", + "shares": "243264064.000000000000000000" + }, + { + "delegator_address": "cosmos1tftatt0lp0v59qqf449pdqar8w3yj7n7xa7sk6", + "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "shares": "9168014109.000000000000000000" + }, + { + "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "shares": "15899234337.000000000000000000" + }, + { + "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "shares": "459551216.000000000000000000" + }, + { + "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "shares": "3300457502.000000000000000000" + }, + { + "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "shares": "254829181.000000000000000000" + }, + { + "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "shares": "3078912948.000000000000000000" + }, + { + "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "shares": "254473474.000000000000000000" + }, + { + "delegator_address": "cosmos1twu2lvgp3erk6gups2a8nae3jdahaj2xmlufsa", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", + "shares": "365167856.000000000000000000" + }, + { + "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "shares": "3444033677.000000000000000000" + }, + { + "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "shares": "315491807.000000000000000000" + }, + { + "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "shares": "548109039.000000000000000000" + }, + { + "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "shares": "2186207273.000000000000000000" + }, + { + "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", + "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "shares": "22429572439.000000000000000000" + }, + { + "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", + "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "shares": "4365594275.000000000000000000" + }, + { + "delegator_address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", + "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "shares": "47693559541.000000000000000000" + }, + { + "delegator_address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "shares": "18283793775.000000000000000000" + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "shares": "2524305482.000000000000000000" + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "shares": "526869097.000000000000000000" + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "shares": "2905348435.000000000000000000" + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "shares": "2150744506.000000000000000000" + }, + { + "delegator_address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je", + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "shares": "19109522.000000000000000000" + }, + { + "delegator_address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "shares": "6106439259.000000000000000000" + }, + { + "delegator_address": "cosmos1tmddg4wjnj38wrd8t6xq092jyw3x4hcup6n00u", + "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", + "shares": "7029801264.000000000000000000" + }, + { + "delegator_address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s", + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "shares": "9953913240.000000000000000000" + }, + { + "delegator_address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "shares": "3831088.000000000000000000" + }, + { + "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", + "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "shares": "2948850137.000000000000000000" + }, + { + "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "shares": "680611809.000000000000000000" + }, + { + "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", + "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "shares": "35599530.000000000000000000" + }, + { + "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "shares": "14234623.084306457501521645" + }, + { + "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "shares": "97571824.000000000000000000" + }, + { + "delegator_address": "cosmos1vqm5fdsflvnee33gk3d5pz7j6tf6dsp28eemcq", + "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "shares": "16949426508.000000000000000000" + }, + { + "delegator_address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "shares": "1356197798.000000000000000000" + }, + { + "delegator_address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", + "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "shares": "731773122.000000000000000000" + }, + { + "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "shares": "16096304.000000000000000000" + }, + { + "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "shares": "4748086.000000000000000000" + }, + { + "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", + "shares": "405352.000000000000000000" + }, + { + "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "shares": "2311637.000000000000000000" + }, + { + "delegator_address": "cosmos1vx0z58vgegsfc8e56jzmjtvj8cvprywvnm7l9j", + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "shares": "1076204485.000000000000000000" + }, + { + "delegator_address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", + "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", + "shares": "2399562500.000000000000000000" + }, + { + "delegator_address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", + "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "shares": "1049818729.000000000000000000" + }, + { + "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "shares": "5284614159.000000000000000000" + }, + { + "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "shares": "11759488693.000000000000000000" + }, + { + "delegator_address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", + "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "shares": "18158211957.000000000000000000" + }, + { + "delegator_address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", + "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", + "shares": "1728294636.000000000000000000" + }, + { + "delegator_address": "cosmos1vwja3gc3e37f8fkddj38gp74cs7sccnf4zs509", + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "shares": "2070243017.000000000000000000" + }, + { + "delegator_address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "shares": "4946049715.000000000000000000" + }, + { + "delegator_address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", + "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", + "shares": "9022206595.000000000000000000" + }, + { + "delegator_address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "shares": "175132304.000000000000000000" + }, + { + "delegator_address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "shares": "3507629422.000000000000000000" + }, + { + "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", + "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "shares": "5221113247.000000000000000000" + }, + { + "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", + "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "shares": "4681593063.000000000000000000" + }, + { + "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", + "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "shares": "6709144772.000000000000000000" + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "shares": "14430378546.000000000000000000" + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "shares": "202358889.000000000000000000" + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", + "shares": "10613605390.000000000000000000" + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "shares": "3535960309.000000000000000000" + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "shares": "670559324.000000000000000000" + }, + { + "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "shares": "667949570.000000000000000000" + }, + { + "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "shares": "967842562.000000000000000000" + }, + { + "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "shares": "11105705687.000000000000000000" + }, + { + "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "shares": "12269775869.000000000000000000" + }, + { + "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "shares": "2105667711.000000000000000000" + }, + { + "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "shares": "6458950379.000000000000000000" + }, + { + "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "shares": "9360757617.000000000000000000" + }, + { + "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "shares": "3427543323.000000000000000000" + }, + { + "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "shares": "863704883.000000000000000000" + }, + { + "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "shares": "3501192050.000000000000000000" + }, + { + "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "shares": "6923120900.000000000000000000" + }, + { + "delegator_address": "cosmos1vuws77sz0xzvz8y0dg6wjz9fzd7plxpk29ljn7", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "shares": "1285996047.000000000000000000" + }, + { + "delegator_address": "cosmos1vlvxlpzzrk5eye9c3z9uedk0085h7fdvehv32n", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "shares": "1749823283.000000000000000000" + }, + { + "delegator_address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "shares": "20234365401.000000000000000000" + }, + { + "delegator_address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz", + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "shares": "16734096385.000000000000000000" + }, + { + "delegator_address": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", + "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "shares": "17594927523.000000000000000000" + }, + { + "delegator_address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7", + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "shares": "1694198126.000000000000000000" + }, + { + "delegator_address": "cosmos1d9m3l8khcrx0zhftehkuw67zzszf9v9le5dvrm", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "shares": "20382465534.000000000000000000" + }, + { + "delegator_address": "cosmos1dgzvesl67z96ttlt5ulga25phe8pnspt663dvr", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "shares": "7195021215.000000000000000000" + }, + { + "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "shares": "20147750165.000000000000000000" + }, + { + "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "shares": "837111535.000000000000000000" + }, + { + "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "shares": "2769362709.000000000000000000" + }, + { + "delegator_address": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "shares": "5379750065.000000000000000000" + }, + { + "delegator_address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "shares": "9737598105.000000000000000000" + }, + { + "delegator_address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", + "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", + "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", + "shares": "49835911.000000000000000000" + }, + { + "delegator_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "shares": "17266683.000000000000000000" + }, + { + "delegator_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", + "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "shares": "4258157.000000000000000000" + }, + { + "delegator_address": "cosmos1d0dq8hxzyywrcx73v4z44e8p8685znzml58dg2", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "shares": "23089372229.000000000000000000" + }, + { + "delegator_address": "cosmos1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpdhe28d", + "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "shares": "17862559018.000000000000000000" + }, + { + "delegator_address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "shares": "6295579444.000000000000000000" + }, + { + "delegator_address": "cosmos1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcy522k3", + "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", + "shares": "1291312379.000000000000000000" + }, + { + "delegator_address": "cosmos1d5vv20893q06tx29mlqmefnyf0w3hn0v07w9p9", + "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", + "shares": "186531063.000000000000000000" + }, + { + "delegator_address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "shares": "19589707878.000000000000000000" + }, + { + "delegator_address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", + "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", + "shares": "179784223.000000000000000000" + }, + { + "delegator_address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", + "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "shares": "19056636038.000000000000000000" + }, + { + "delegator_address": "cosmos1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lypeadd", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", + "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "shares": "11267665039.000000000000000000" + }, + { + "delegator_address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", + "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "shares": "11650293201.000000000000000000" + }, + { + "delegator_address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "shares": "61880678.000000000000000000" + }, + { + "delegator_address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "shares": "9719656784.000000000000000000" + }, + { + "delegator_address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "shares": "11780930912.000000000000000000" + }, + { + "delegator_address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", + "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", + "shares": "7094282971.000000000000000000" + }, + { + "delegator_address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "shares": "8142048495.000000000000000000" + }, + { + "delegator_address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "shares": "2012957230.000000000000000000" + }, + { + "delegator_address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", + "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "shares": "16439836386.000000000000000000" + }, + { + "delegator_address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "shares": "3961673047.000000000000000000" + }, + { + "delegator_address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", + "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "shares": "3607007415.000000000000000000" + }, + { + "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "shares": "5596804179.000000000000000000" + }, + { + "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "shares": "3295555517.000000000000000000" + }, + { + "delegator_address": "cosmos1wtn9tf6wjwmwmddrk377cdl8fd96hexajyhfat", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "shares": "18471816853.000000000000000000" + }, + { + "delegator_address": "cosmos1wvzq2f252674u3gvmqhnq8g4n6lmxedmzs0czm", + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "shares": "2584616241.000000000000000000" + }, + { + "delegator_address": "cosmos1wdm9ge7hjzrlh2epwtwu3nsunfd2r7alqhc7r2", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "shares": "24303271333.000000000000000000" + }, + { + "delegator_address": "cosmos1wwp7j40k9xffj757s4uurkcegskfwq25ef268l", + "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "shares": "584304640.000000000000000000" + }, + { + "delegator_address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "shares": "423877981.000000000000000000" + }, + { + "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "shares": "1781975477.000000000000000000" + }, + { + "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", + "shares": "1553435623.000000000000000000" + }, + { + "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "shares": "41624341.000000000000000000" + }, + { + "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "shares": "11513057667.000000000000000000" + }, + { + "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "shares": "13034888858.653846147589407194" + }, + { + "delegator_address": "cosmos1w69f6s0dqsqfqq93hczddadwgeq86zr9dfmddq", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "shares": "751916830.000000000000000000" + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "shares": "1427892425.000000000000000000" + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "shares": "585232700.000000000000000000" + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "shares": "116762054.000000000000000000" + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "shares": "324745845.000000000000000000" + }, + { + "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "shares": "16011251757.000000000000000000" + }, + { + "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "shares": "24728825327.000000000000000000" + }, + { + "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "shares": "14446066.000000000000000000" + }, + { + "delegator_address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "shares": "1721804886.000000000000000000" + }, + { + "delegator_address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "shares": "3002359447.000000000000000000" + }, + { + "delegator_address": "cosmos10qj9cj3dxecyu826gaw72ylwum96jkkh9p462q", + "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "shares": "7039255436.000000000000000000" + }, + { + "delegator_address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2", + "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", + "shares": "1606367134.000000000000000000" + }, + { + "delegator_address": "cosmos10p78pcqm2slk4x0pfxl9ht5spskwquhzptwzt8", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "shares": "3812433475.000000000000000000" + }, + { + "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", + "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "shares": "2341551967.000000000000000000" + }, + { + "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", + "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", + "shares": "229341851.000000000000000000" + }, + { + "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", + "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "shares": "2246425767.000000000000000000" + }, + { + "delegator_address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", + "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", + "shares": "5555958746.000000000000000000" + }, + { + "delegator_address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "shares": "8539175078.000000000000000000" + }, + { + "delegator_address": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "shares": "7137720854.000000000000000000" + }, + { + "delegator_address": "cosmos10gu52rf3d0z0py8d0x37r058qh9fgdgg5567wd", + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "shares": "13307344592.000000000000000000" + }, + { + "delegator_address": "cosmos10d3vd6yx9k9ns6v82r4krm3d4ragw04cysm62c", + "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", + "shares": "1365098704.000000000000000000" + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "shares": "1993086195.000000000000000000" + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "shares": "1981740603.000000000000000000" + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "shares": "19691201.000000000000000000" + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "shares": "2235582679.000000000000000000" + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "shares": "151161779.000000000000000000" + }, + { + "delegator_address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", + "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", + "shares": "48593531.000000000000000000" + }, + { + "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "shares": "11937090067.000000000000000000" + }, + { + "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", + "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", + "shares": "955350854.000000000000000000" + }, + { + "delegator_address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "shares": "917167136.000000000000000000" + }, + { + "delegator_address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "shares": "226539767.000000000000000000" + }, + { + "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "shares": "31268300.962477168044592631" + }, + { + "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", + "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", + "shares": "3717256219.000000000000000000" + }, + { + "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "shares": "8832434015.000000000000000000" + }, + { + "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "shares": "121624664.000000000000000000" + }, + { + "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", + "shares": "27773889.000000000000000000" + }, + { + "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "shares": "7778508961.000000000000000000" + }, + { + "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", + "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", + "shares": "1611728813.000000000000000000" + }, + { + "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", + "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "shares": "1609536341.000000000000000000" + }, + { + "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", + "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "shares": "157509894.000000000000000000" + }, + { + "delegator_address": "cosmos10cl6sallgwf882apcyagjqa2lx4j8592cjw0gf", + "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", + "shares": "1573970763.000000000000000000" + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "shares": "4784005.000000000000000000" + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "shares": "8178830.000000000000000000" + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "shares": "402116649.000000000000000000" + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "shares": "2274933257.000000000000000000" + }, + { + "delegator_address": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "shares": "10376224736.000000000000000000" + }, + { + "delegator_address": "cosmos1sr6u63sxsprpzv7tedc7e88tn6elrxkjnucszy", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "shares": "32674846927.555147209487723148" + }, + { + "delegator_address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "shares": "21431257869.000000000000000000" + }, + { + "delegator_address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "shares": "843834482.000000000000000000" + }, + { + "delegator_address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", + "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", + "shares": "2339204126.000000000000000000" + }, + { + "delegator_address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "shares": "14241294624.000000000000000000" + }, + { + "delegator_address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "shares": "1117197748.000000000000000000" + }, + { + "delegator_address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "shares": "2037145657.000000000000000000" + }, + { + "delegator_address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q", + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "shares": "2844380010.000000000000000000" + }, + { + "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", + "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", + "shares": "6732042.000000000000000000" + }, + { + "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "shares": "21529013972.000000000000000000" + }, + { + "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "shares": "3069213832.000000000000000000" + }, + { + "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", + "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "shares": "1302147397.000000000000000000" + }, + { + "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "shares": "14654910305.000000000000000000" + }, + { + "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "shares": "4020804640.000000000000000000" + }, + { + "delegator_address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "shares": "870772585.000000000000000000" + }, + { + "delegator_address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", + "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "shares": "7012397.000000000000000000" + }, + { + "delegator_address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp", + "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", + "shares": "1392995609.000000000000000000" + }, + { + "delegator_address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", + "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "shares": "11045854268.000000000000000000" + }, + { + "delegator_address": "cosmos1s34kukvsrdgap0pjh0alnql7vvv9m83m2628wd", + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "shares": "3141510059.000000000000000000" + }, + { + "delegator_address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", + "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", + "shares": "5059370848.000000000000000000" + }, + { + "delegator_address": "cosmos1sjhhg2yl2cqszte7pjyrp6lx5tg383lrpjyq0m", + "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "shares": "8429625072.000000000000000000" + }, + { + "delegator_address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "shares": "842733222.000000000000000000" + }, + { + "delegator_address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "shares": "2313732788.000000000000000000" + }, + { + "delegator_address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", + "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", + "shares": "1963736286.000000000000000000" + }, + { + "delegator_address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj", + "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", + "shares": "6944508564.000000000000000000" + }, + { + "delegator_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "shares": "13458847467.000000000000000000" + }, + { + "delegator_address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc", + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "shares": "2335097089.000000000000000000" + }, + { + "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", + "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "shares": "7367311429.000000000000000000" + }, + { + "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "shares": "1116213901.000000000000000000" + }, + { + "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "shares": "2413926110.000000000000000000" + }, + { + "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "shares": "836513743.000000000000000000" + }, + { + "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "shares": "16324341322.000000000000000000" + }, + { + "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", + "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", + "shares": "109318647.000000000000000000" + }, + { + "delegator_address": "cosmos13ps0cszg8lqn0mkzndvhxwaew8yd56s8tl9j20", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "shares": "7351040665.000000000000000000" + }, + { + "delegator_address": "cosmos13yzpngckxvtky2k25j60qxlkekx0jfau4pjhzn", + "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos13y2zjpgaj07umx7a3dsg9ffhpkk22g73492l53", + "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "shares": "3677892381.000000000000000000" + }, + { + "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "shares": "5068354349.000000000000000000" + }, + { + "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "shares": "2649436634.000000000000000000" + }, + { + "delegator_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", + "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", + "shares": "1975544514.000000000000000000" + }, + { + "delegator_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "shares": "3371357709.000000000000000000" + }, + { + "delegator_address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "shares": "3736546194.000000000000000000" + }, + { + "delegator_address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", + "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", + "shares": "1089374285.000000000000000000" + }, + { + "delegator_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", + "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "shares": "9334974491.000000000000000000" + }, + { + "delegator_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "shares": "117761745.000000000000000000" + }, + { + "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "shares": "241691384.000000000000000000" + }, + { + "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", + "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "shares": "12106150602.000000000000000000" + }, + { + "delegator_address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", + "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "shares": "2665696727.000000000000000000" + }, + { + "delegator_address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", + "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "shares": "3084993241.000000000000000000" + }, + { + "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "shares": "4124499225.000000000000000000" + }, + { + "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "shares": "3484578053.000000000000000000" + }, + { + "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "shares": "4448687638.000000000000000000" + }, + { + "delegator_address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890", + "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "shares": "9648503235.000000000000000000" + }, + { + "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "shares": "12794497617.000000000000000000" + }, + { + "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "shares": "12274844463.000000000000000000" + }, + { + "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "shares": "1096219390.000000000000000000" + }, + { + "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "shares": "909672651.000000000000000000" + }, + { + "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", + "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", + "shares": "9842289918.000000000000000000" + }, + { + "delegator_address": "cosmos130kk7kw4kx7rfrq9sa4k673zqt3nf6s4l3a0lg", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "shares": "5241869268.000000000000000000" + }, + { + "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "shares": "916587.000000000000000000" + }, + { + "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "shares": "2061374262.000000000000000000" + }, + { + "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "shares": "23007967818.000000000000000000" + }, + { + "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "shares": "144959703.000000000000000000" + }, + { + "delegator_address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "shares": "5071553218.000000000000000000" + }, + { + "delegator_address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "shares": "9488989139.000000000000000000" + }, + { + "delegator_address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "shares": "12748204456.000000000000000000" + }, + { + "delegator_address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "shares": "16792228457.000000000000000000" + }, + { + "delegator_address": "cosmos13nemj0k45u4pflkfeyey88n8u8sv4wgz8cf253", + "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "shares": "9595922807.000000000000000000" + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", + "shares": "16993994.000000000000000000" + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", + "shares": "143748684.000000000000000000" + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", + "shares": "19594820.000000000000000000" + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "shares": "927934611.000000000000000000" + }, + { + "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "shares": "178156456.000000000000000000" + }, + { + "delegator_address": "cosmos13cydnwjmscxtqtjywk9atr9uwlm6703mwtycnr", + "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "shares": "14396315468.000000000000000000" + }, + { + "delegator_address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", + "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", + "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "shares": "3671255483.000000000000000000" + }, + { + "delegator_address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", + "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "shares": "8251101726.000000000000000000" + }, + { + "delegator_address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "shares": "2352005810.000000000000000000" + }, + { + "delegator_address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "shares": "345074496.000000000000000000" + }, + { + "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", + "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", + "shares": "23719777.000000000000000000" + }, + { + "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "shares": "22252816301.000000000000000000" + }, + { + "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "shares": "29688637.000000000000000000" + }, + { + "delegator_address": "cosmos1jzhlspgxp578kzg9dtvg8tm2w9k7tnmcpstzry", + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "shares": "6425955236.000000000000000000" + }, + { + "delegator_address": "cosmos1j9vhccgf8520gtz7zn5jxj9lk3nqg0wx479kwp", + "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "shares": "12478510598.000000000000000000" + }, + { + "delegator_address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", + "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "shares": "19618367974.000000000000000000" + }, + { + "delegator_address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "shares": "4858570428.000000000000000000" + }, + { + "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "shares": "879369780.000000000000000000" + }, + { + "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", + "shares": "11868568217.000000000000000000" + }, + { + "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", + "shares": "12315828943.000000000000000000" + }, + { + "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "shares": "5575140.000000000000000000" + }, + { + "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", + "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", + "shares": "2312465.000000000000000000" + }, + { + "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", + "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", + "shares": "3222725.000000000000000000" + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "shares": "1829057.000000000000000000" + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "shares": "2258309.000000000000000000" + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "shares": "16096471780.000000000000000000" + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", + "shares": "6237005399.000000000000000000" + }, + { + "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "shares": "731129230.000000000000000000" + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "shares": "443348912.000000000000000000" + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", + "shares": "18797742.000000000000000000" + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", + "shares": "28000486.000000000000000000" + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "shares": "188596153.000000000000000000" + }, + { + "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "shares": "17415142521.000000000000000000" + }, + { + "delegator_address": "cosmos1jsd99e3zfrxrr3nh057u0tvmu0847zkr29f28v", + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr", + "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", + "shares": "4524948359.000000000000000000" + }, + { + "delegator_address": "cosmos1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0ajhqc7", + "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "shares": "22529203230.000000000000000000" + }, + { + "delegator_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", + "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", + "shares": "3423632102.000000000000000000" + }, + { + "delegator_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", + "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "shares": "1443592024.000000000000000000" + }, + { + "delegator_address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa", + "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", + "shares": "4681170917.000000000000000000" + }, + { + "delegator_address": "cosmos1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxx7jqef", + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "shares": "2320422648.000000000000000000" + }, + { + "delegator_address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "shares": "454715151.000000000000000000" + }, + { + "delegator_address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", + "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", + "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", + "shares": "1864943427.000000000000000000" + }, + { + "delegator_address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "shares": "14533440365.000000000000000000" + }, + { + "delegator_address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", + "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", + "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "shares": "14112770668.000000000000000000" + }, + { + "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", + "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", + "shares": "457491.000000000000000000" + }, + { + "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "shares": "9948638663.000000000000000000" + }, + { + "delegator_address": "cosmos1nrugh7am9s584k6qlf5nxlpetarxs2csglt46w", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "shares": "4938829215.000000000000000000" + }, + { + "delegator_address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", + "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "shares": "33054734644.000000000000000000" + }, + { + "delegator_address": "cosmos1n9dqelmmf5kfysk24m6chqfdcgz6r75u7mpuwh", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", + "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "shares": "15056247725.000000000000000000" + }, + { + "delegator_address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", + "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "shares": "10013094355.000000000000000000" + }, + { + "delegator_address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", + "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "shares": "315931330.000000000000000000" + }, + { + "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "shares": "189243223.000000000000000000" + }, + { + "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "shares": "13576729605.000000000000000000" + }, + { + "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "shares": "2427273583.000000000000000000" + }, + { + "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "shares": "401941426.000000000000000000" + }, + { + "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "shares": "158733361.000000000000000000" + }, + { + "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "shares": "35850249.000000000000000000" + }, + { + "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "shares": "205025816.000000000000000000" + }, + { + "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", + "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "shares": "2567851891.000000000000000000" + }, + { + "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "shares": "302642185.000000000000000000" + }, + { + "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "shares": "2830795600.000000000000000000" + }, + { + "delegator_address": "cosmos1ng5m6spxngyne4qzce35fdg0whl0yqgv9lg9tt", + "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "shares": "13107417049.000000000000000000" + }, + { + "delegator_address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "shares": "18672701727.000000000000000000" + }, + { + "delegator_address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", + "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "shares": "235709907.000000000000000000" + }, + { + "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "shares": "4090038169.000000000000000000" + }, + { + "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "shares": "2956537033.000000000000000000" + }, + { + "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "shares": "23728387848.000000000000000000" + }, + { + "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", + "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", + "shares": "1340954232.000000000000000000" + }, + { + "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "shares": "7303977754.000000000000000000" + }, + { + "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "shares": "11095524326.000000000000000000" + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "shares": "61795.000000000000000000" + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "shares": "1729736194.000000000000000000" + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "shares": "11773826677.000000000000000000" + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", + "shares": "5311127.000000000000000000" + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", + "shares": "52419.000000000000000000" + }, + { + "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "shares": "95191076.000000000000000000" + }, + { + "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", + "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "shares": "23726525801.000000000000000000" + }, + { + "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", + "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", + "shares": "312724720.000000000000000000" + }, + { + "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", + "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1n3lnhxzzm7ntheu78h6v4zag7zmrlp48tjnhf3", + "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "shares": "9794461587.000000000000000000" + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "shares": "15964121.000000000000000000" + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "shares": "428070399.000000000000000000" + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", + "shares": "12613411.000000000000000000" + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "shares": "24554814193.000000000000000000" + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "shares": "51693014.000000000000000000" + }, + { + "delegator_address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "shares": "10690661250.000000000000000000" + }, + { + "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "shares": "20540852.000000000000000000" + }, + { + "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "shares": "24652299.000000000000000000" + }, + { + "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "shares": "16883391832.000000000000000000" + }, + { + "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "shares": "32698264.000000000000000000" + }, + { + "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "shares": "2237914169.000000000000000000" + }, + { + "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "shares": "5136199330.000000000000000000" + }, + { + "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", + "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", + "shares": "14531672001.000000000000000000" + }, + { + "delegator_address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "shares": "17245824357.000000000000000000" + }, + { + "delegator_address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", + "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "shares": "16205811760.000000000000000000" + }, + { + "delegator_address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", + "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", + "shares": "981657888.000000000000000000" + }, + { + "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "shares": "177902750.000000000000000000" + }, + { + "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "shares": "13348917907.000000000000000000" + }, + { + "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", + "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "shares": "5038451854.000000000000000000" + }, + { + "delegator_address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", + "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", + "shares": "15174649749.000000000000000000" + }, + { + "delegator_address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "shares": "938622421.000000000000000000" + }, + { + "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "shares": "126388593.000000000000000000" + }, + { + "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", + "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "shares": "52804172.000000000000000000" + }, + { + "delegator_address": "cosmos15pl2c2umxszwar75aft99kns0ltmpepnnpt9y0", + "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", + "shares": "11726853019.000000000000000000" + }, + { + "delegator_address": "cosmos15zqzxj663h8g8naxyz324j2rpd3rnw4rvtxep2", + "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "shares": "2151028602.000000000000000000" + }, + { + "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", + "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", + "shares": "2713168340.000000000000000000" + }, + { + "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "shares": "2095412424.000000000000000000" + }, + { + "delegator_address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", + "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", + "shares": "11868660651.000000000000000000" + }, + { + "delegator_address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "shares": "632967960.000000000000000000" + }, + { + "delegator_address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "shares": "16358237418.000000000000000000" + }, + { + "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", + "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "shares": "1116365771.000000000000000000" + }, + { + "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", + "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", + "shares": "6995636695.000000000000000000" + }, + { + "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", + "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", + "shares": "700270403.000000000000000000" + }, + { + "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "shares": "3315560612.000000000000000000" + }, + { + "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "shares": "11335873807.000000000000000000" + }, + { + "delegator_address": "cosmos15tv54z32xgqechywvr7ymsfdvr2mmx3553j8rd", + "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", + "shares": "10646429954.000000000000000000" + }, + { + "delegator_address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "shares": "2244459128.000000000000000000" + }, + { + "delegator_address": "cosmos15vf60ssrdq6fh9ln5a9wtd6f3q64sktl6vk2ss", + "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", + "shares": "502656802.000000000000000000" + }, + { + "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", + "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", + "shares": "974110958.000000000000000000" + }, + { + "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "shares": "9209912.000000000000000000" + }, + { + "delegator_address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "shares": "14053872866.000000000000000000" + }, + { + "delegator_address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "shares": "11015469214.000000000000000000" + }, + { + "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", + "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", + "shares": "7094821824.000000000000000000" + }, + { + "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", + "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "shares": "15044102286.000000000000000000" + }, + { + "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", + "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "shares": "2930417970.000000000000000000" + }, + { + "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", + "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "shares": "5685279942.000000000000000000" + }, + { + "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", + "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "shares": "4593224997.000000000000000000" + }, + { + "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", + "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", + "shares": "1062187041.000000000000000000" + }, + { + "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "shares": "7193234568.000000000000000000" + }, + { + "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "shares": "23543464834.000000000000000000" + }, + { + "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "shares": "1456184772.000000000000000000" + }, + { + "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", + "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", + "shares": "568146686.000000000000000000" + }, + { + "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", + "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "shares": "21856354084.000000000000000000" + }, + { + "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", + "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "shares": "16248624224.000000000000000000" + }, + { + "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "shares": "324333952.000000000000000000" + }, + { + "delegator_address": "cosmos1556dzhyv2gth4huxdlyur65c2sm3np2en3zzhl", + "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", + "shares": "6217452551.000000000000000000" + }, + { + "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", + "shares": "18762995915.000000000000000000" + }, + { + "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "shares": "19978115021.000000000000000000" + }, + { + "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "shares": "269676102.000000000000000000" + }, + { + "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "shares": "821954529.000000000000000000" + }, + { + "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "shares": "10949797827.000000000000000000" + }, + { + "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "shares": "1677820405.000000000000000000" + }, + { + "delegator_address": "cosmos15cfduq92j3uvam8u942xj4egs42tjzl6p33fu5", + "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", + "shares": "14156647.000000000000000000" + }, + { + "delegator_address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", + "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "shares": "22863613869.000000000000000000" + }, + { + "delegator_address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "shares": "2205728211.000000000000000000" + }, + { + "delegator_address": "cosmos15uqsf4wke3ylyp0elnka2rvaefhsmhgjhe5mxf", + "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", + "shares": "8741308900.000000000000000000" + }, + { + "delegator_address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "shares": "7421590485.000000000000000000" + }, + { + "delegator_address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", + "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", + "shares": "24026548.000000000000000000" + }, + { + "delegator_address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "shares": "8706091689.000000000000000000" + }, + { + "delegator_address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", + "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "shares": "16363250391.000000000000000000" + }, + { + "delegator_address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "shares": "7165994372.000000000000000000" + }, + { + "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "shares": "3115334630.000000000000000000" + }, + { + "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", + "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos14q9rupnazu0mmkjd9skpn2zdfs8d0hlghzpk0v", + "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", + "shares": "260728313.000000000000000000" + }, + { + "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", + "shares": "492237770.000000000000000000" + }, + { + "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "shares": "6269261784.000000000000000000" + }, + { + "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "shares": "357887239.000000000000000000" + }, + { + "delegator_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "shares": "20515760055.000000000000000000" + }, + { + "delegator_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "shares": "5887196.000000000000000000" + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "shares": "2267056403.000000000000000000" + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "shares": "2449818489.000000000000000000" + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "shares": "110749654.000000000000000000" + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "shares": "16977263624.000000000000000000" + }, + { + "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "shares": "3439625151.000000000000000000" + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "shares": "126313.000000000000000000" + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "shares": "7332243055.000000000000000000" + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "shares": "127732919.000000000000000000" + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", + "shares": "998573733.000000000000000000" + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "shares": "3169550.000000000000000000" + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", + "shares": "60608473.000000000000000000" + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", + "shares": "125301.000000000000000000" + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "shares": "16667182589.000000000000000000" + }, + { + "delegator_address": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", + "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "shares": "18994769458.000000000000000000" + }, + { + "delegator_address": "cosmos14j4mehgc448s2m7cr0uqm3pmvjxav94wmq80w4", + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "shares": "1854783297.000000000000000000" + }, + { + "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "shares": "16404106448.000000000000000000" + }, + { + "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "shares": "40666822.000000000000000000" + }, + { + "delegator_address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "shares": "52986923.026489101418518680" + }, + { + "delegator_address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "shares": "157324268.000000000000000000" + }, + { + "delegator_address": "cosmos14hr55k3es7xfc54gwgu3plde0vaxkgerljee6v", + "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "shares": "20670117972.000000000000000000" + }, + { + "delegator_address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "shares": "1160822532.000000000000000000" + }, + { + "delegator_address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", + "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", + "shares": "3041120922.000000000000000000" + }, + { + "delegator_address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "shares": "2921862659.000000000000000000" + }, + { + "delegator_address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "shares": "22147479421.000000000000000000" + }, + { + "delegator_address": "cosmos14m0pzuhkpjnx2esurz6kcxcjvlkcdzk7e43krz", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "shares": "2468850551.000000000000000000" + }, + { + "delegator_address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", + "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "shares": "821774041.000000000000000000" + }, + { + "delegator_address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "shares": "20037186316.000000000000000000" + }, + { + "delegator_address": "cosmos14urapj7e6tj2s8clcsgyat6xmkppj7nm4qtewf", + "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", + "shares": "5480500900.000000000000000000" + }, + { + "delegator_address": "cosmos147pq4rzswl76kdeyx8sc7pagf4nhjpnq2hlrh3", + "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "shares": "22417960991.000000000000000000" + }, + { + "delegator_address": "cosmos1478sx3zdfylsts5sus5rlz4dgvyvacqpuchj6f", + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos147lwcm3tx6uhtjphxwwmk7u32mucukalplv80z", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "shares": "1601474401.000000000000000000" + }, + { + "delegator_address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "shares": "352271656.000000000000000000" + }, + { + "delegator_address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", + "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", + "shares": "10941491018.000000000000000000" + }, + { + "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", + "shares": "145922218.000000000000000000" + }, + { + "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "shares": "375360.000000000000000000" + }, + { + "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "shares": "57475597.000000000000000000" + }, + { + "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "shares": "1616674805.000000000000000000" + }, + { + "delegator_address": "cosmos1kz20p7j939s8cqadmqqws80c6z93qdtyg8xt0v", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "shares": "9782915598.000000000000000000" + }, + { + "delegator_address": "cosmos1kxl7gsad663he7lgn66wx6gr3egnfj85dt22pv", + "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", + "shares": "2533410912.000000000000000000" + }, + { + "delegator_address": "cosmos1kfnt5d5fcma9kh4c5jk85yu75jer72kwdltg4s", + "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "shares": "21181468286.000000000000000000" + }, + { + "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", + "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", + "shares": "322814192.000000000000000000" + }, + { + "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", + "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "shares": "607985470.000000000000000000" + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "shares": "14714606427.000000000000000000" + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", + "shares": "7038279055.000000000000000000" + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "shares": "17602930321.000000000000000000" + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "shares": "671837638.000000000000000000" + }, + { + "delegator_address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "shares": "4201547532.000000000000000000" + }, + { + "delegator_address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "shares": "5669282913.000000000000000000" + }, + { + "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "shares": "65633207.000000000000000000" + }, + { + "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "shares": "11280504984.000000000000000000" + }, + { + "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "shares": "3391706116.000000000000000000" + }, + { + "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2", + "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "shares": "9571086511.000000000000000000" + }, + { + "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", + "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "shares": "9033381920.000000000000000000" + }, + { + "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "shares": "6858058479.000000000000000000" + }, + { + "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "shares": "827898827.000000000000000000" + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "shares": "11943268264.000000000000000000" + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "shares": "2696689996.000000000000000000" + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "shares": "7482618743.000000000000000000" + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "shares": "1637026536.000000000000000000" + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "shares": "3409616214.000000000000000000" + }, + { + "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "shares": "22288761371.000000000000000000" + }, + { + "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", + "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "shares": "166860.000000000000000000" + }, + { + "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", + "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "shares": "12266067.000000000000000000" + }, + { + "delegator_address": "cosmos1kjupa2w6rlhzj9fjxz35m02g2wpz790fd6mf0j", + "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "shares": "11188036452.000000000000000000" + }, + { + "delegator_address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", + "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "shares": "18799915325.000000000000000000" + }, + { + "delegator_address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", + "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", + "shares": "6269426755.000000000000000000" + }, + { + "delegator_address": "cosmos1kmly2aspt8rk9h4ukdt8h52k24alvc34qukp2n", + "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "shares": "9031700237.000000000000000000" + }, + { + "delegator_address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", + "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "shares": "11830766683.000000000000000000" + }, + { + "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", + "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", + "shares": "68637287.000000000000000000" + }, + { + "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "shares": "21882314874.000000000000000000" + }, + { + "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", + "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", + "shares": "199824149.000000000000000000" + }, + { + "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "shares": "9460610373.000000000000000000" + }, + { + "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", + "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "shares": "7918208867.000000000000000000" + }, + { + "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "shares": "15608731707.000000000000000000" + }, + { + "delegator_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "shares": "3123465186.000000000000000000" + }, + { + "delegator_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "shares": "14982594771.000000000000000000" + }, + { + "delegator_address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "shares": "9107793740.000000000000000000" + }, + { + "delegator_address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", + "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "shares": "457781724.000000000000000000" + }, + { + "delegator_address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "shares": "5446202786.000000000000000000" + }, + { + "delegator_address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "shares": "361851785.000000000000000000" + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "shares": "6774702429.000000000000000000" + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", + "shares": "185779104.000000000000000000" + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "shares": "137048444.000000000000000000" + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", + "shares": "3084665544.000000000000000000" + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", + "shares": "2095189904.000000000000000000" + }, + { + "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "shares": "6709581679.000000000000000000" + }, + { + "delegator_address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe", + "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", + "shares": "4203532933.000000000000000000" + }, + { + "delegator_address": "cosmos1hxdqddf3u8vjm080ytpe959uktn4axdas3uqhl", + "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "shares": "13179632835.000000000000000000" + }, + { + "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "shares": "106422691.000000000000000000" + }, + { + "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "shares": "441014433.000000000000000000" + }, + { + "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", + "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", + "shares": "23136285.000000000000000000" + }, + { + "delegator_address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "shares": "785421895.000000000000000000" + }, + { + "delegator_address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "shares": "576145955.000000000000000000" + }, + { + "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "shares": "489746723.000000000000000000" + }, + { + "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", + "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "shares": "2551565111.000000000000000000" + }, + { + "delegator_address": "cosmos1h84c3yuxd6k7950wh868tcsj5tmvzetykv8lld", + "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "shares": "3599965031.000000000000000000" + }, + { + "delegator_address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "shares": "6422847905.000000000000000000" + }, + { + "delegator_address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", + "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", + "shares": "1408273393.000000000000000000" + }, + { + "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", + "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "shares": "14815040085.000000000000000000" + }, + { + "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", + "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", + "shares": "1360036310.000000000000000000" + }, + { + "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", + "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "shares": "1912310410.000000000000000000" + }, + { + "delegator_address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", + "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", + "shares": "2108075856.000000000000000000" + }, + { + "delegator_address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "shares": "19205968225.000000000000000000" + }, + { + "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "shares": "7720105335.000000000000000000" + }, + { + "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "shares": "2555870064.000000000000000000" + }, + { + "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", + "shares": "1987459876.000000000000000000" + }, + { + "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "shares": "10677551922.000000000000000000" + }, + { + "delegator_address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq", + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", + "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "shares": "1612739646.000000000000000000" + }, + { + "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "shares": "10343736976.000000000000000000" + }, + { + "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "shares": "1316682053.000000000000000000" + }, + { + "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "shares": "1003510952.000000000000000000" + }, + { + "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", + "shares": "927350399.000000000000000000" + }, + { + "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "shares": "8106078214.000000000000000000" + }, + { + "delegator_address": "cosmos1h6j4lyvuenmz9m7vq3hler8j7pg5ldpet0xf9a", + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "shares": "17690207109.000000000000000000" + }, + { + "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", + "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "shares": "2588611065.000000000000000000" + }, + { + "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", + "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", + "shares": "4006205.000000000000000000" + }, + { + "delegator_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "shares": "9393510961.000000000000000000" + }, + { + "delegator_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", + "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "shares": "15675831119.000000000000000000" + }, + { + "delegator_address": "cosmos1haw8fcay84fjlsdl5cyev275ldj30z3r27m0g5", + "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "shares": "6372741624.000000000000000000" + }, + { + "delegator_address": "cosmos1h72kkqt83nth0npqvgmardgelg6jyx7zupnypp", + "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "shares": "1604525333.000000000000000000" + }, + { + "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", + "shares": "995278414.000000000000000000" + }, + { + "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "shares": "2129694907.000000000000000000" + }, + { + "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "shares": "19279146842.000000000000000000" + }, + { + "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", + "shares": "2665221917.000000000000000000" + }, + { + "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "shares": "9304209052.000000000000000000" + }, + { + "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "shares": "18386606315.000000000000000000" + }, + { + "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "shares": "3680624756.000000000000000000" + }, + { + "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", + "shares": "3002111009.000000000000000000" + }, + { + "delegator_address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "shares": "35571003.000000000000000000" + }, + { + "delegator_address": "cosmos1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptd8zyma", + "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", + "shares": "8559089572.000000000000000000" + }, + { + "delegator_address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", + "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "shares": "1483865601.000000000000000000" + }, + { + "delegator_address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "shares": "20731656728.000000000000000000" + }, + { + "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", + "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "shares": "19455408606.000000000000000000" + }, + { + "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "shares": "2739638648.000000000000000000" + }, + { + "delegator_address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", + "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "shares": "19129298483.000000000000000000" + }, + { + "delegator_address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", + "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "shares": "4147746231.000000000000000000" + }, + { + "delegator_address": "cosmos1cwk6x5smzaqhtrz95z0sf90d8a8d9vfrpaufnl", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "shares": "22113286739.000000000000000000" + }, + { + "delegator_address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "shares": "3421255938.000000000000000000" + }, + { + "delegator_address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", + "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "shares": "13796856153.000000000000000000" + }, + { + "delegator_address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", + "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", + "shares": "5261551412.000000000000000000" + }, + { + "delegator_address": "cosmos1c4lft2m4yyrzjsxyu7nzsrxuskgtlr2crzzwwd", + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "shares": "4541366.000000000000000000" + }, + { + "delegator_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", + "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "shares": "6661497942.000000000000000000" + }, + { + "delegator_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", + "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", + "shares": "7924071421.000000000000000000" + }, + { + "delegator_address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "shares": "36701249402.000000000000000000" + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "shares": "641381462.000000000000000000" + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "shares": "9991492.000000000000000000" + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "shares": "5093480749.000000000000000000" + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", + "shares": "20581321.000000000000000000" + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "shares": "1112547.000000000000000000" + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "shares": "131936453.000000000000000000" + }, + { + "delegator_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "shares": "4250535918.000000000000000000" + }, + { + "delegator_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", + "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "shares": "4792139392.000000000000000000" + }, + { + "delegator_address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", + "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "shares": "282264887.000000000000000000" + }, + { + "delegator_address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", + "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", + "shares": "211016457.000000000000000000" + }, + { + "delegator_address": "cosmos1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6x000jc", + "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", + "shares": "1201306698.000000000000000000" + }, + { + "delegator_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "shares": "986773968.000000000000000000" + }, + { + "delegator_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", + "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", + "shares": "249261878.000000000000000000" + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "shares": "543089195.000000000000000000" + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "shares": "390088156.000000000000000000" + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "shares": "23613691655.000000000000000000" + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "shares": "522473074.000000000000000000" + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "shares": "113007060.000000000000000000" + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "shares": "15252711477.000000000000000000" + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", + "shares": "64540087.000000000000000000" + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "shares": "9703623543.000000000000000000" + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "shares": "6161948206.000000000000000000" + }, + { + "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "shares": "21462438160.000000000000000000" + }, + { + "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "shares": "533098317.000000000000000000" + }, + { + "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "shares": "2286530039.000000000000000000" + }, + { + "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "shares": "1320373881.000000000000000000" + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", + "shares": "759535878.000000000000000000" + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "shares": "139593046.000000000000000000" + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "shares": "856982353.000000000000000000" + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "shares": "14322672203.000000000000000000" + }, + { + "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", + "shares": "199636304.000000000000000000" + }, + { + "delegator_address": "cosmos1etrkjjjjvuej87yu2pv4mcmhjsjqsn5hm9n043", + "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "shares": "23226246980.000000000000000000" + }, + { + "delegator_address": "cosmos1evqmj6ahqf76keas4ymhvf4r992kg7wrar0fru", + "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "shares": "3652777037.000000000000000000" + }, + { + "delegator_address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", + "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "shares": "23356660678.000000000000000000" + }, + { + "delegator_address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", + "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", + "shares": "1119920089.000000000000000000" + }, + { + "delegator_address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266", + "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", + "shares": "5987604552.000000000000000000" + }, + { + "delegator_address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6", + "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", + "shares": "11089478639.000000000000000000" + }, + { + "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "shares": "32924160.000000000000000000" + }, + { + "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "shares": "1792101072.000000000000000000" + }, + { + "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "shares": "466233357.000000000000000000" + }, + { + "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "shares": "18772263304.000000000000000000" + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "shares": "2616582981.000000000000000000" + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", + "shares": "40296136.000000000000000000" + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "shares": "155780036.000000000000000000" + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", + "shares": "39749190.000000000000000000" + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "shares": "372091968.000000000000000000" + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "shares": "5054551129.000000000000000000" + }, + { + "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "shares": "3120662598.000000000000000000" + }, + { + "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", + "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", + "shares": "247885300.000000000000000000" + }, + { + "delegator_address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", + "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", + "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", + "shares": "9203549637.000000000000000000" + }, + { + "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", + "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "shares": "13243911263.000000000000000000" + }, + { + "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "shares": "1392479696.000000000000000000" + }, + { + "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "shares": "892316992.000000000000000000" + }, + { + "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", + "shares": "7847492642.000000000000000000" + }, + { + "delegator_address": "cosmos1em3y3h4g7n8ue3wjcramnpmz0x8rwakrpjmrgz", + "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", + "shares": "12071046098.000000000000000000" + }, + { + "delegator_address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "shares": "1397139502.000000000000000000" + }, + { + "delegator_address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "shares": "18480450616.000000000000000000" + }, + { + "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", + "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "shares": "1682063162.000000000000000000" + }, + { + "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "shares": "2652495105.000000000000000000" + }, + { + "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", + "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", + "shares": "2778547888.000000000000000000" + }, + { + "delegator_address": "cosmos1easmlky76c302my07gffjxjw0a2usueaw8j46t", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "shares": "23176847255.000000000000000000" + }, + { + "delegator_address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", + "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "shares": "5503709183.000000000000000000" + }, + { + "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "shares": "14812554077.000000000000000000" + }, + { + "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", + "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "shares": "19565632897.000000000000000000" + }, + { + "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "shares": "6892307704.000000000000000000" + }, + { + "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", + "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "shares": "545803690.000000000000000000" + }, + { + "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", + "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", + "shares": "5402886314.000000000000000000" + }, + { + "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", + "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "shares": "2401456661.000000000000000000" + }, + { + "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "shares": "3540231870.000000000000000000" + }, + { + "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", + "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "shares": "19127653549.000000000000000000" + }, + { + "delegator_address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "shares": "8305994215.000000000000000000" + }, + { + "delegator_address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos16tr72kn90g5zl7qhyhuqkjflejz00uzlkl65sj", + "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos16v3h2mggt8tnkxp0vq5tq25fhr3knvf4jw40l5", + "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "shares": "23883466891.000000000000000000" + }, + { + "delegator_address": "cosmos160jtaz9c35nr7dx349ezfzvs3xfdzm3mlxgulk", + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "shares": "23889133768.000000000000000000" + }, + { + "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "shares": "12642546664.000000000000000000" + }, + { + "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "shares": "5113128716.000000000000000000" + }, + { + "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", + "shares": "230136377.000000000000000000" + }, + { + "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "shares": "233651324.000000000000000000" + }, + { + "delegator_address": "cosmos16jj80c7d94m772cn77zwcuhnqcl6y95kepxvja", + "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", + "shares": "3841134273.000000000000000000" + }, + { + "delegator_address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n", + "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", + "shares": "13444158275.000000000000000000" + }, + { + "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "shares": "2280542883.000000000000000000" + }, + { + "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", + "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "shares": "90986838.000000000000000000" + }, + { + "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", + "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "shares": "1523447464.000000000000000000" + }, + { + "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", + "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", + "shares": "3562717063.000000000000000000" + }, + { + "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "shares": "11761380768.000000000000000000" + }, + { + "delegator_address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", + "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "shares": "3799625898.000000000000000000" + }, + { + "delegator_address": "cosmos1mzsvp23mjrjkspddkz6nta0x7kte6a23atg6ml", + "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", + "shares": "2228698398.000000000000000000" + }, + { + "delegator_address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", + "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "shares": "7881585438.000000000000000000" + }, + { + "delegator_address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", + "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "shares": "11902636114.000000000000000000" + }, + { + "delegator_address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", + "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", + "shares": "965626724.000000000000000000" + }, + { + "delegator_address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "shares": "22330517668.000000000000000000" + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", + "shares": "245003068.000000000000000000" + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "shares": "2561447038.000000000000000000" + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "shares": "3452658290.000000000000000000" + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "shares": "1753289412.000000000000000000" + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "shares": "1407135534.000000000000000000" + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "shares": "385810656.000000000000000000" + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "shares": "349164048.000000000000000000" + }, + { + "delegator_address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", + "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "shares": "14577877248.000000000000000000" + }, + { + "delegator_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "shares": "466196437.000000000000000000" + }, + { + "delegator_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", + "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", + "shares": "2479274676.000000000000000000" + }, + { + "delegator_address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", + "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", + "shares": "4394402323.000000000000000000" + }, + { + "delegator_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "shares": "43994659.000000000000000000" + }, + { + "delegator_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", + "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "shares": "32603015.000000000000000000" + }, + { + "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", + "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "shares": "1040485229.000000000000000000" + }, + { + "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "shares": "13388065636.000000000000000000" + }, + { + "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "shares": "18071051811.000000000000000000" + }, + { + "delegator_address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", + "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", + "shares": "610981525.000000000000000000" + }, + { + "delegator_address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "shares": "315677262.000000000000000000" + }, + { + "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", + "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", + "shares": "712016860.000000000000000000" + }, + { + "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", + "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "shares": "18830990390.000000000000000000" + }, + { + "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", + "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", + "shares": "1199437642.000000000000000000" + }, + { + "delegator_address": "cosmos1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfej3rle", + "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", + "shares": "1494931451.000000000000000000" + }, + { + "delegator_address": "cosmos1m4xvwvq7qrr0wy0ryeu24eu8482h4n7en2x2mh", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "shares": "10673600913.000000000000000000" + }, + { + "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "shares": "97785114.000000000000000000" + }, + { + "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", + "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "shares": "22087360379.000000000000000000" + }, + { + "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "shares": "1744984549.000000000000000000" + }, + { + "delegator_address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "shares": "8455755268.000000000000000000" + }, + { + "delegator_address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "shares": "8173781116.000000000000000000" + }, + { + "delegator_address": "cosmos1mcc0dq93nrt3u6hl6ju82hyw3rdfun029jx4v2", + "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "shares": "3120721396.000000000000000000" + }, + { + "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", + "shares": "319721226.000000000000000000" + }, + { + "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", + "shares": "2104208415.000000000000000000" + }, + { + "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "shares": "4301090429.000000000000000000" + }, + { + "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "shares": "2332669614.000000000000000000" + }, + { + "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", + "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "shares": "3420827405.000000000000000000" + }, + { + "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", + "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "shares": "24395123.000000000000000000" + }, + { + "delegator_address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "shares": "1067919041.000000000000000000" + }, + { + "delegator_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", + "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "shares": "482001747.000000000000000000" + }, + { + "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "shares": "5366509387.000000000000000000" + }, + { + "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", + "shares": "508102761.000000000000000000" + }, + { + "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "shares": "12895342060.000000000000000000" + }, + { + "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", + "shares": "781062755.000000000000000000" + }, + { + "delegator_address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "shares": "8844305443.000000000000000000" + }, + { + "delegator_address": "cosmos1urnp7yp6u27nut8kvsrapgmmvk8sh6u5wd5dez", + "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", + "shares": "13977340603.000000000000000000" + }, + { + "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", + "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", + "shares": "69406130.000000000000000000" + }, + { + "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", + "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", + "shares": "120397764.000000000000000000" + }, + { + "delegator_address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", + "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "shares": "163640358.000000000000000000" + }, + { + "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", + "shares": "254035.000000000000000000" + }, + { + "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", + "shares": "111239871.000000000000000000" + }, + { + "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", + "shares": "24027809.000000000000000000" + }, + { + "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", + "shares": "251933.000000000000000000" + }, + { + "delegator_address": "cosmos1uvm96xdewfpdwymw5ywt8j5efq6jhpyl35pzg8", + "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", + "shares": "7577447491.000000000000000000" + }, + { + "delegator_address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "shares": "5904983738.000000000000000000" + }, + { + "delegator_address": "cosmos1uuk9ewj0532rzlhlg86tserdxvtnm3kq2k2zww", + "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", + "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", + "shares": "663734465.000000000000000000" + }, + { + "delegator_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", + "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", + "shares": "763826873.000000000000000000" + }, + { + "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", + "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "shares": "1330954959.000000000000000000" + }, + { + "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", + "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", + "shares": "449732008.000000000000000000" + }, + { + "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "shares": "140255592.000000000000000000" + }, + { + "delegator_address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "shares": "627370738.000000000000000000" + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", + "shares": "11523735546.000000000000000000" + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "shares": "1576940428.000000000000000000" + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "shares": "607901853.000000000000000000" + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "shares": "108025410.000000000000000000" + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "shares": "212323217.000000000000000000" + }, + { + "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "shares": "7597437829.000000000000000000" + }, + { + "delegator_address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", + "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "shares": "1420797965.000000000000000000" + }, + { + "delegator_address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", + "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "shares": "9361230791.000000000000000000" + }, + { + "delegator_address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", + "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", + "shares": "82979650.000000000000000000" + }, + { + "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "shares": "11238205953.000000000000000000" + }, + { + "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "shares": "330891000.000000000000000000" + }, + { + "delegator_address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", + "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "shares": "8106199.000000000000000000" + }, + { + "delegator_address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", + "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", + "shares": "6631273690.000000000000000000" + }, + { + "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", + "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "shares": "24565420625.000000000000000000" + }, + { + "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", + "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", + "shares": "5682430.000000000000000000" + }, + { + "delegator_address": "cosmos1adwsqn58aype530jae9qrwknsxyf3wmwdr523z", + "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", + "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "shares": "10992310558.000000000000000000" + }, + { + "delegator_address": "cosmos1awyus34e6laq3zxqsrv283w6fgn8w62zkwd87d", + "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1a0jdqzvk078d6486vuxdr5d0yp6rglue2nh5dn", + "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "shares": "9613933711.000000000000000000" + }, + { + "delegator_address": "cosmos1a5fndlfnwtvyzzt7ql4kvuqgnjut7ua7hkfts6", + "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "shares": "9415626255.000000000000000000" + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "shares": "3906909228.000000000000000000" + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", + "shares": "5370042726.000000000000000000" + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "shares": "1682096242.000000000000000000" + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "shares": "844335956.000000000000000000" + }, + { + "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "shares": "7764993320.000000000000000000" + }, + { + "delegator_address": "cosmos1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8kl6qt4", + "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", + "shares": "15012824613.000000000000000000" + }, + { + "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", + "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "shares": "15288776108.000000000000000000" + }, + { + "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", + "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "shares": "6780481465.000000000000000000" + }, + { + "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", + "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", + "shares": "228354642.000000000000000000" + }, + { + "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "shares": "7055399052.000000000000000000" + }, + { + "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", + "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", + "shares": "13186298825.000000000000000000" + }, + { + "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", + "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "shares": "21448624442.000000000000000000" + }, + { + "delegator_address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", + "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "shares": "17547096641.000000000000000000" + }, + { + "delegator_address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "shares": "2615326319.000000000000000000" + }, + { + "delegator_address": "cosmos17ph7nmvmxdhm687z4k5phsyd08wvsnv44emkj8", + "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "shares": "3648941591.000000000000000000" + }, + { + "delegator_address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", + "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "shares": "2878563531.000000000000000000" + }, + { + "delegator_address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", + "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", + "shares": "1820280319.000000000000000000" + }, + { + "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", + "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "shares": "22489048481.000000000000000000" + }, + { + "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", + "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", + "shares": "2580293599.000000000000000000" + }, + { + "delegator_address": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos178pm30fcgrt5654czwr8nlex050m6y609glx2s", + "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "shares": "23703504292.000000000000000000" + }, + { + "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", + "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", + "shares": "2914482410.000000000000000000" + }, + { + "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", + "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "shares": "1110360222.000000000000000000" + }, + { + "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "shares": "18525526004.000000000000000000" + }, + { + "delegator_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", + "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", + "shares": "4722611768.000000000000000000" + }, + { + "delegator_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", + "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", + "shares": "1627510175.000000000000000000" + }, + { + "delegator_address": "cosmos17gpy6jzg7xdsr2xc7kweljagx4uaysxdk2244g", + "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "shares": "7651697131.000000000000000000" + }, + { + "delegator_address": "cosmos17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnk5g0lz", + "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", + "shares": "227804730.000000000000000000" + }, + { + "delegator_address": "cosmos172lmu2psqlkxkthpr46h2ewjffte7lhlmwe6tg", + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos17tecr2sngjcm2rc29dzmadtpad2tkmrhj69whr", + "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "shares": "16752793632.000000000000000000" + }, + { + "delegator_address": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", + "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "shares": "718921425.000000000000000000" + }, + { + "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", + "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "shares": "2738776488.000000000000000000" + }, + { + "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", + "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", + "shares": "2115827243.000000000000000000" + }, + { + "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", + "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", + "shares": "1397104980.000000000000000000" + }, + { + "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", + "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "shares": "3213489253.000000000000000000" + }, + { + "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", + "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "shares": "21648809872.000000000000000000" + }, + { + "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "shares": "146683.000000000000000000" + }, + { + "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "shares": "89280204.000000000000000000" + }, + { + "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", + "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "shares": "251790.000000000000000000" + }, + { + "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", + "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", + "shares": "633536370.000000000000000000" + }, + { + "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", + "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "shares": "6767814744.000000000000000000" + }, + { + "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "shares": "117960718.000000000000000000" + }, + { + "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", + "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "shares": "23981371945.000000000000000000" + }, + { + "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", + "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", + "shares": "300592036.000000000000000000" + }, + { + "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "shares": "39160384.000000000000000000" + }, + { + "delegator_address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", + "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "shares": "2364587435.000000000000000000" + }, + { + "delegator_address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", + "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "shares": "8013043987.000000000000000000" + }, + { + "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", + "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", + "shares": "18869340.000000000000000000" + }, + { + "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", + "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", + "shares": "218958522.000000000000000000" + }, + { + "delegator_address": "cosmos174ycyhzg358nxm8r6qunzsyx48uk8fc404ckyf", + "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "shares": "8680187636.000000000000000000" + }, + { + "delegator_address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", + "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "shares": "1221107604.000000000000000000" + }, + { + "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "shares": "411136992.000000000000000000" + }, + { + "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "shares": "1317573671.000000000000000000" + }, + { + "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "shares": "22514769356.000000000000000000" + }, + { + "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", + "shares": "825862061.000000000000000000" + }, + { + "delegator_address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck", + "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "shares": "2602618529.000000000000000000" + }, + { + "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", + "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", + "shares": "165098526.000000000000000000" + }, + { + "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", + "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", + "shares": "4718627.000000000000000000" + }, + { + "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", + "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", + "shares": "340930766.000000000000000000" + }, + { + "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", + "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", + "shares": "2968081872.000000000000000000" + }, + { + "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", + "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "shares": "1681443586.000000000000000000" + }, + { + "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "shares": "5740343356.000000000000000000" + }, + { + "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "shares": "3023435039.000000000000000000" + }, + { + "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "shares": "12958021951.000000000000000000" + }, + { + "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "shares": "3755696144.000000000000000000" + }, + { + "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "shares": "17646792.000000000000000000" + }, + { + "delegator_address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", + "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "shares": "6724622674.000000000000000000" + }, + { + "delegator_address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", + "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "shares": "18344719406.000000000000000000" + }, + { + "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "shares": "6656587767.000000000000000000" + }, + { + "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "shares": "986856358.000000000000000000" + }, + { + "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", + "shares": "159276935.000000000000000000" + }, + { + "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "shares": "1168681082.000000000000000000" + }, + { + "delegator_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", + "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "shares": "2711574997.000000000000000000" + }, + { + "delegator_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", + "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "shares": "18120372537.000000000000000000" + }, + { + "delegator_address": "cosmos1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpkca4g8", + "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "shares": "15023386396.000000000000000000" + }, + { + "delegator_address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", + "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "shares": "2867035102.000000000000000000" + }, + { + "delegator_address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", + "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "shares": "10621822118.000000000000000000" + }, + { + "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "shares": "58360958.000000000000000000" + }, + { + "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", + "shares": "81292948.000000000000000000" + }, + { + "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "shares": "89358777.000000000000000000" + }, + { + "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", + "shares": "281580943.000000000000000000" + }, + { + "delegator_address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", + "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "shares": "513446339.000000000000000000" + }, + { + "delegator_address": "cosmos1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqcrj0xk", + "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", + "shares": "1028714701.000000000000000000" + }, + { + "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", + "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "shares": "1078037731.000000000000000000" + }, + { + "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", + "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "shares": "252433656.000000000000000000" + }, + { + "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", + "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "shares": "23612702988.000000000000000000" + }, + { + "delegator_address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "shares": "11614756424.000000000000000000" + }, + { + "delegator_address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", + "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "shares": "21096282678.000000000000000000" + }, + { + "delegator_address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", + "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", + "shares": "9417801394.000000000000000000" + }, + { + "delegator_address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", + "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "shares": "2119723899.000000000000000000" + }, + { + "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", + "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "shares": "174754983.000000000000000000" + }, + { + "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", + "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "shares": "18558143415.000000000000000000" + }, + { + "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", + "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", + "shares": "179430222.000000000000000000" + }, + { + "delegator_address": "cosmos1l5d2lg5hku0m4u8mh866zhjcy2dekpk598m8wr", + "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "shares": "25069342080.000000000000000000" + }, + { + "delegator_address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", + "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "shares": "8362968596.000000000000000000" + }, + { + "delegator_address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", + "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", + "shares": "425532255.000000000000000000" + }, + { + "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", + "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "shares": "15967116837.000000000000000000" + }, + { + "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", + "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", + "shares": "3907335026.000000000000000000" + }, + { + "delegator_address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn", + "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", + "shares": "2977168576.000000000000000000" + }, + { + "delegator_address": "cosmos1l6u5cg3wcptmcjyhxtfrrfq3nu036acdauf0fy", + "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "shares": "15368943494.000000000000000000" + }, + { + "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", + "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", + "shares": "2295367808.000000000000000000" + }, + { + "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", + "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "shares": "209859957.000000000000000000" + }, + { + "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", + "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "shares": "19453723967.000000000000000000" + }, + { + "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "shares": "7497643277.000000000000000000" + }, + { + "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", + "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "shares": "8982227181.000000000000000000" + }, + { + "delegator_address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", + "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "shares": "13950070710.000000000000000000" + }, + { + "delegator_address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", + "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "shares": "11119271370.000000000000000000" + } + ], + "unbonding_delegations": [ + { + "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", + "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "entries": [ + { + "creation_height": "49", + "completion_time": "9936-01-04T20:29:20Z", + "initial_balance": "183076477", + "balance": "183076477" + } + ] + }, + { + "delegator_address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", + "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2005303616", + "balance": "2005303616" + } + ] + }, + { + "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", + "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "entries": [ + { + "creation_height": "50", + "completion_time": "9936-01-04T22:14:51Z", + "initial_balance": "15030300002", + "balance": "15030300002" + } + ] + }, + { + "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", + "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "20593666623", + "balance": "20593666623" + } + ] + }, + { + "delegator_address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", + "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "4199831033", + "balance": "4199831033" + } + ] + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "29439356", + "balance": "29439356" + } + ] + }, + { + "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", + "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "14986173529", + "balance": "14986173529" + } + ] + }, + { + "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", + "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "3732148769", + "balance": "3732148769" + } + ] + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "25509388", + "balance": "25509388" + } + ] + }, + { + "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "1895209", + "balance": "1895209" + } + ] + }, + { + "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", + "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "6983331316", + "balance": "6983331316" + } + ] + }, + { + "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", + "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "19374447530", + "balance": "19374447530" + } + ] + }, + { + "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", + "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "335873680", + "balance": "335873680" + } + ] + }, + { + "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", + "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2656231998", + "balance": "2656231998" + } + ] + }, + { + "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", + "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "1564778153", + "balance": "1564778153" + } + ] + }, + { + "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", + "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2570223192", + "balance": "2570223192" + } + ] + }, + { + "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2395235221", + "balance": "2395235221" + } + ] + }, + { + "delegator_address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", + "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "entries": [ + { + "creation_height": "50", + "completion_time": "9936-01-04T22:14:51Z", + "initial_balance": "18962902821", + "balance": "18962902821" + } + ] + }, + { + "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "10483079", + "balance": "10483079" + } + ] + }, + { + "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "3109466079", + "balance": "3109466079" + } + ] + }, + { + "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "726017962", + "balance": "726017962" + } + ] + }, + { + "delegator_address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", + "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "196636283", + "balance": "196636283" + } + ] + }, + { + "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "240781727", + "balance": "240781727" + } + ] + }, + { + "delegator_address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", + "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "311403029", + "balance": "311403029" + } + ] + }, + { + "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", + "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2590271094", + "balance": "2590271094" + }, + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "3133575935", + "balance": "3133575935" + } + ] + }, + { + "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", + "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "716875401", + "balance": "716875401" + } + ] + }, + { + "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", + "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", + "entries": [ + { + "creation_height": "50", + "completion_time": "9936-01-04T22:14:51Z", + "initial_balance": "3339815870", + "balance": "3339815870" + } + ] + }, + { + "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", + "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "3944810", + "balance": "3944810" + } + ] + }, + { + "delegator_address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", + "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "4956381732", + "balance": "4956381732" + } + ] + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "915982", + "balance": "915982" + } + ] + }, + { + "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "11358632", + "balance": "11358632" + } + ] + }, + { + "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", + "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "13733468273", + "balance": "13733468273" + } + ] + }, + { + "delegator_address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", + "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "32611419", + "balance": "32611419" + } + ] + }, + { + "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", + "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "entries": [ + { + "creation_height": "50", + "completion_time": "9936-01-04T22:14:51Z", + "initial_balance": "11282230082", + "balance": "11282230082" + } + ] + }, + { + "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "5091227059", + "balance": "5091227059" + } + ] + }, + { + "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", + "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "entries": [ + { + "creation_height": "50", + "completion_time": "9936-01-04T22:14:51Z", + "initial_balance": "237207832", + "balance": "237207832" + } + ] + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "156945410", + "balance": "156945410" + } + ] + }, + { + "delegator_address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", + "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2401741158", + "balance": "2401741158" + } + ] + }, + { + "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", + "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2874294826", + "balance": "2874294826" + } + ] + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "3627849543", + "balance": "3627849543" + } + ] + }, + { + "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", + "entries": [ + { + "creation_height": "50", + "completion_time": "9936-01-04T22:14:51Z", + "initial_balance": "84069", + "balance": "84069" + } + ] + }, + { + "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "7503011", + "balance": "7503011" + } + ] + }, + { + "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "16794484703", + "balance": "16794484703" + } + ] + }, + { + "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", + "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "756303091", + "balance": "756303091" + } + ] + }, + { + "delegator_address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", + "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "4217365098", + "balance": "4217365098" + } + ] + }, + { + "delegator_address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", + "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "16832773759", + "balance": "16832773759" + } + ] + }, + { + "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", + "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2771729865", + "balance": "2771729865" + } + ] + }, + { + "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", + "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "8589471622", + "balance": "8589471622" + } + ] + } + ], + "redelegations": [ + { + "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", + "validator_src_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "validator_dst_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "809035601", + "shares_dst": "809035601.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", + "validator_src_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "validator_dst_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "20636678155", + "shares_dst": "20636678155.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", + "validator_src_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "validator_dst_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2172957336", + "shares_dst": "2172957336.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", + "validator_src_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "validator_dst_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "1856911069", + "shares_dst": "1856911069.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "validator_src_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "validator_dst_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "510250360", + "shares_dst": "510250360.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "validator_src_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "validator_dst_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "5799285", + "shares_dst": "5799285.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", + "validator_src_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "validator_dst_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "3922123176", + "shares_dst": "3922123176.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", + "validator_src_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "validator_dst_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "127648169", + "shares_dst": "127648169.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "validator_src_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "validator_dst_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "240453816", + "shares_dst": "240453816.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "validator_src_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "validator_dst_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "7174712260", + "shares_dst": "7174712260.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", + "validator_src_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "validator_dst_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "11095524326", + "shares_dst": "11095524326.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "validator_src_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "validator_dst_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "51693014", + "shares_dst": "51693014.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "validator_src_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "validator_dst_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "126313", + "shares_dst": "126313.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "validator_src_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "validator_dst_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", + "entries": [ + { + "creation_height": "50", + "completion_time": "9936-01-04T22:14:51Z", + "initial_balance": "671837638", + "shares_dst": "671837638.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "validator_src_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "validator_dst_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "entries": [ + { + "creation_height": "50", + "completion_time": "9936-01-04T22:14:51Z", + "initial_balance": "2696689996", + "shares_dst": "2696689996.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", + "validator_src_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "validator_dst_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "489746723", + "shares_dst": "489746723.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", + "validator_src_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "validator_dst_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "1612739646", + "shares_dst": "1612739646.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", + "validator_src_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "validator_dst_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "19455408606", + "shares_dst": "19455408606.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "validator_src_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "validator_dst_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "543089195", + "shares_dst": "543089195.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "validator_src_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "validator_dst_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "entries": [ + { + "creation_height": "50", + "completion_time": "9936-01-04T22:14:51Z", + "initial_balance": "113007060", + "shares_dst": "113007060.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "validator_src_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "validator_dst_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "2561447038", + "shares_dst": "2561447038.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", + "validator_src_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "validator_dst_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "entries": [ + { + "creation_height": "49", + "completion_time": "9936-01-04T20:29:20Z", + "initial_balance": "21648809872", + "shares_dst": "21648809872.000000000000000000" + } + ] + }, + { + "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "validator_src_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "validator_dst_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", + "entries": [ + { + "creation_height": "48", + "completion_time": "9936-01-04T18:13:47Z", + "initial_balance": "6656587767", + "shares_dst": "6656587767.000000000000000000" + } + ] + } + ], + "historical_infos": [ + { + "header": { + "version": {}, + "chain_id": "simulation-app", + "height": "48", + "time": "9936-01-04T13:24:43Z", + "last_block_id": { + "parts_header": {} + }, + "proposer_address": "ejlFDTFrxPCQ7Xmj4b6HBcqUNQg=" + }, + "valset": [ + { + "operator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels7tpscy", + "status": 3, + "tokens": "24767745772", + "delegator_shares": "24767745772.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.064962829627143450", + "max_rate": "0.700000000000000000", + "max_change_rate": "0.524524837966075502" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xt2s2vh", + "status": 3, + "tokens": "40149298125", + "delegator_shares": "40149298125.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020987080088521851", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.079654399773437862" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk7tt4rl", + "status": 3, + "tokens": "33873720903", + "delegator_shares": "33873720903.000000000000000000", + "description": { + "moniker": "mLoNnmWUiV", + "identity": "RHiUhLQQnZ", + "website": "GdVEOYibSd", + "security_contact": "DcfUpyGSpE", + "details": "kaQgULDDFV" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.793635545567707656", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.546926599085395557" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcrkzkl0", + "status": 3, + "tokens": "76742997299", + "delegator_shares": "76742997299.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.159853619317053801", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.178173481628386356" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0yv2h8z80vtfttsewrwe2v83haaceax7q3ey95uaeqj8lstf7l674zn3ut", + "status": 3, + "tokens": "16016194501", + "delegator_shares": "16016194501.000000000000000000", + "description": { + "moniker": "WVhrVMjLnZ", + "identity": "QiIQjemxtv", + "website": "KCKlbRarYk", + "security_contact": "AwimEeOMDq", + "details": "omCiVdOfZS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.636807270475032336", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.762928812525012131" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghknhrvft", + "status": 3, + "tokens": "32824956781", + "delegator_shares": "32824956781.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.063963134401067102" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgt7tyq6", + "status": 3, + "tokens": "15545552914", + "delegator_shares": "15545552914.000000000000000000", + "description": { + "moniker": "VaOLitHrfh", + "identity": "zYkbJeTdPC", + "website": "RWLWpQBLTs", + "security_contact": "EEFOrnsvml", + "details": "xRXuWfcvoz" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.209346043397093808", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.261491014079542938" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpvkknmf7", + "status": 3, + "tokens": "34783743330", + "delegator_shares": "34783743330.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.412168984856446389", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.601152598273329028" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4645lf2dka2qs2renc2n2rts24k9xfmxnx5fkhvj3squp8nv5ugyr2nj8", + "status": 3, + "tokens": "25741111893", + "delegator_shares": "25741111893.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.005185006676002722", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.268395235691771325" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvw0g93n8", + "status": 3, + "tokens": "24037432303", + "delegator_shares": "24037432303.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.140843713075627976", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.124247346623493378" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtxrkpudghuhgsu0he7ntk7q0asqa5ax23y7rnn5mfjr2d68z4emsrwqssp", + "status": 3, + "tokens": "44972041218", + "delegator_shares": "44972041218.000000000000000000", + "description": { + "moniker": "eJECwiPlqs", + "identity": "TywZsaZwgH", + "website": "jtFVQJUofX", + "security_contact": "fstanspUpc", + "details": "RQddrwMsIR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.005369299901591159", + "max_rate": "0.030000000000000000", + "max_change_rate": "0.010979308887356502" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwz2zelc", + "status": 3, + "tokens": "24972834479", + "delegator_shares": "24972834479.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118883162683785924", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.582076368438090700" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q205udc4", + "status": 3, + "tokens": "48048764683", + "delegator_shares": "48048764683.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.137121313165408722" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zycdvvrg7", + "status": 3, + "tokens": "26109827309", + "delegator_shares": "26109827309.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.272379182115041576" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "consensus_pubkey": "cosmosvalconspub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwlhqscf", + "status": 3, + "tokens": "25214890343", + "delegator_shares": "25214890343.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.276804190595109972", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.303611347820460701" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2u3gzal", + "status": 3, + "tokens": "21697576499", + "delegator_shares": "21697576499.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289943655120962524", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.271265684659427360" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgh4tj7q", + "status": 3, + "tokens": "49505425616", + "delegator_shares": "49505425616.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.519126528788995280", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw55ftmtn", + "status": 3, + "tokens": "51494857888", + "delegator_shares": "51494857888.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.006443603339396517", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.110565720532816181" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavc40dh4", + "status": 3, + "tokens": "69365122054", + "delegator_shares": "69365122054.000000000000000000", + "description": { + "moniker": "IoqkplxtIQ", + "identity": "SYtEYnqVjz", + "website": "cbrMdhVrVp", + "security_contact": "eWitXxyhJZ", + "details": "FCojJQQFCQ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.745132980800690980", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.321606633967630124" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tugphy2d", + "status": 3, + "tokens": "17054284690", + "delegator_shares": "17054284690.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.602634897210355218", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.136597759514787421" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jztkylp", + "status": 3, + "tokens": "36407556988", + "delegator_shares": "36407556988.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.052047960532670175", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgrwz3gl", + "status": 3, + "tokens": "17768682341", + "delegator_shares": "17768682341.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.141929485726276362" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yr97z8g", + "status": 3, + "tokens": "22598538029", + "delegator_shares": "22598538029.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.335354744004515496", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.096800797786563611" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2zq3f3j", + "status": 3, + "tokens": "27149799034", + "delegator_shares": "27149799034.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.158969199652087770", + "max_rate": "0.220000000000000000", + "max_change_rate": "0.220000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq246sxc5kns0ym6st5wyf6mk0x2cayek9wngczyvgk8phxrat02cqh8w5p2", + "status": 3, + "tokens": "49314038732", + "delegator_shares": "49314038732.000000000000000000", + "description": { + "moniker": "caRBWwzxXd", + "identity": "BJSnkbfQjh", + "website": "ELsVPBoBHb", + "security_contact": "nZkoSMuzKV", + "details": "AuAKjeoitI" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.010525961964940541", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.045814731203367877" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jhhj4uv", + "status": 3, + "tokens": "26185707851", + "delegator_shares": "26185707851.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.568319127244896272", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.226261076338173049" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5u4v4q5", + "status": 3, + "tokens": "32785129607", + "delegator_shares": "32785129607.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.009044195385937429", + "max_rate": "0.010000000000000000", + "max_change_rate": "0.002281789765845776" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpqq8zx8p", + "status": 3, + "tokens": "33846192792", + "delegator_shares": "33846192792.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.094250378854551281", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.043420993012939508" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv79a2a0wcq9kr62m5yupvx82mlxwxw6hx7c8dyl4trf8k2w7vh3w5wlhy0", + "status": 3, + "tokens": "25066394767", + "delegator_shares": "25066394767.000000000000000000", + "description": { + "moniker": "liMRThtiLT", + "identity": "QPHsvzHnkx", + "website": "BytvAmppJT", + "security_contact": "iBgKxrOkqF", + "details": "RcELAgZeDN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.115126355797501393", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.289658857878369113" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfp9mvx6gjdezn2vfxn9jk7jm2urml0xyvt3yg64s03yzkfphrthsdy925d", + "status": 3, + "tokens": "25061237568", + "delegator_shares": "25061237568.000000000000000000", + "description": { + "moniker": "wmxxGOZTpL", + "identity": "azxfwYYUUt", + "website": "izxOUVhQSX", + "security_contact": "lRgXsoitme", + "details": "eebhMKbHXO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.578049895054733896", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.402405887034980654" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc255eyr9", + "status": 3, + "tokens": "76621873132", + "delegator_shares": "76621873132.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.321194785873117781", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.561602155526895676" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u43hapa", + "status": 3, + "tokens": "18750673243", + "delegator_shares": "18750673243.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.188948913118426394", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.274693773376656673" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvpup8kv2mmqajfs08aks8yu8kcuwd323y4f0wu9e3k5grynt0g6ule9mjg", + "status": 3, + "tokens": "24248574347", + "delegator_shares": "24248574347.000000000000000000", + "description": { + "moniker": "bsrCMyYTRM", + "identity": "cTWbJOIMRX", + "website": "EMzKHBarjX", + "security_contact": "spsTAIOECF", + "details": "fTrZtqJTUr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.455524678875180233", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-01T06:29:20Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d29fg079", + "status": 3, + "tokens": "82798702711", + "delegator_shares": "82798702711.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289674444273548704", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.060992257943659564" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgss8cv9u", + "status": 3, + "tokens": "26155915081", + "delegator_shares": "26155915081.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.333198345990187069", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.410926346802169727" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "consensus_pubkey": "cosmosvalconspub1addwnpepqghlm3r37c95q3p3wvr8fxw8mvvdtj3tvhgduhzgzh4238ynz6f06f0rjfd", + "status": 3, + "tokens": "32485653471", + "delegator_shares": "32485653471.000000000000000000", + "description": { + "moniker": "hjulbVDPpf", + "identity": "pRsBrwBRzq", + "website": "VjiSZKAfKB", + "security_contact": "UHZkwTciXO", + "details": "JTfVgehmsi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.311759176624756474" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqge9z0fefq3xpf8y4q8j57c89x65luk2vtcx5mln75662ukq00f6sqefz8w", + "status": 3, + "tokens": "17425230490", + "delegator_shares": "17425230490.000000000000000000", + "description": { + "moniker": "pGvmyXHQYo", + "identity": "cCQHGXFLSL", + "website": "BaxemamtmF", + "security_contact": "wpZarCOeDy", + "details": "XYyJPmrQVh" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.209082457058936007", + "max_rate": "0.470000000000000000", + "max_change_rate": "0.166552912196145925" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwus66jdl", + "status": 3, + "tokens": "54108139534", + "delegator_shares": "54108139534.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22ep2k8n", + "status": 3, + "tokens": "69316998057", + "delegator_shares": "69316998057.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.624946300778690751", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.204995912261423056" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7ejhy28", + "status": 3, + "tokens": "27808118568", + "delegator_shares": "27808118568.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.067795278161998694", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.011309118617844055" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5kc0mzw", + "status": 3, + "tokens": "21672426398", + "delegator_shares": "21672426398.000000000000000000", + "description": { + "moniker": "uloyQQWkyI", + "identity": "gFyXSGlhKI", + "website": "ewFltsApZk", + "security_contact": "YGvOhkEKJw", + "details": "vIoOsfiLuj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.068730439287548849", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.118090772640391070" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv0pnal4w8hydpq3vydqgjxmmxz7zg2g9lsj5vedvjq3pw6typfdcjfm5tc", + "status": 3, + "tokens": "16342492210", + "delegator_shares": "16342492210.000000000000000000", + "description": { + "moniker": "jKdcmnPYfC", + "identity": "exfUuYgqmd", + "website": "XdNCNZIBOf", + "security_contact": "hmiwPGchGt", + "details": "nUnBufZQah" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.330000000000000000", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.051583680374523519" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057uxwdfy", + "status": 3, + "tokens": "23352431465", + "delegator_shares": "23352431465.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.760000000000000000", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.183753469845780730" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvy095yf8a7eknhlnwzkum0wt53njxxww60vte7qkutwczt534dwhaclpm", + "status": 3, + "tokens": "34693121909", + "delegator_shares": "34693121909.000000000000000000", + "description": { + "moniker": "MeTXVRIPJJ", + "identity": "TUfYXCkdwb", + "website": "hRiHdgBoDj", + "security_contact": "uoLwAibjAn", + "details": "fXXnusiKCw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.012519787105018298", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.005395717096845063" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef5gg2q6z", + "status": 3, + "tokens": "42958814024", + "delegator_shares": "42958814024.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.077000158168963029", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.197697608060710078" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwv7ukq0", + "status": 3, + "tokens": "21104467943", + "delegator_shares": "21104467943.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.460679550676466675", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.165088210560206816" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwc7h5wds8u3tspx3mwpfh5l3q3rv0t6ff33dt205v2zy2kxev9sykcs9uv", + "status": 3, + "tokens": "29256610441", + "delegator_shares": "29256610441.000000000000000000", + "description": { + "moniker": "iYUgQcrziE", + "identity": "hDYXNaKKIu", + "website": "FYsreoPnoD", + "security_contact": "FGAHzGKfjM", + "details": "gkHwWfssaE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.585764113115952818", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz4r8scm", + "status": 3, + "tokens": "62352159921", + "delegator_shares": "62352159921.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.041535797793389960", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.029250263820409753" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2cxeaw4", + "status": 3, + "tokens": "38271499795", + "delegator_shares": "38271499795.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.416117321788354038", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.139830256647094326" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazfcl7f9", + "status": 3, + "tokens": "26982328993", + "delegator_shares": "26982328993.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.170000000000000000", + "max_change_rate": "0.024288054259102348" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgxqjc3u3", + "status": 3, + "tokens": "45028692546", + "delegator_shares": "45028692546.000000000000000000", + "description": { + "moniker": "UeFBWJANuQ", + "identity": "gypzUiAlRd", + "website": "zZezcKCiKy", + "security_contact": "KSXTvslQOC", + "details": "qqNIBlVIYk" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.075610127679217055", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.290000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xwmrp7sq", + "status": 3, + "tokens": "35018830437", + "delegator_shares": "35018830437.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.405901469124460870" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "consensus_pubkey": "cosmosvalconspub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc92g545rl", + "status": 3, + "tokens": "17547285969", + "delegator_shares": "17547285969.000000000000000000", + "description": {}, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.073548473514397047", + "max_rate": "0.440000000000000000", + "max_change_rate": "0.413655116572301617" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wyr7x83", + "status": 3, + "tokens": "25071600389", + "delegator_shares": "25071600389.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.280000000000000000", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.063599161373317498" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymswdv67m", + "status": 3, + "tokens": "27784307296", + "delegator_shares": "27784307296.000000000000000000", + "description": { + "moniker": "mjkYspzJbE", + "identity": "xWPMeIdPEi", + "website": "xtRPXfTiQB", + "security_contact": "sdKpqtdpNe", + "details": "MnLujfMpnW" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.072530327063185081" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslqg7mlcx", + "status": 3, + "tokens": "31634692393", + "delegator_shares": "31634692393.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.554757466700447989", + "max_rate": "0.820000000000000000", + "max_change_rate": "0.408903182457515462" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvlfyhyylne6t33wzse5vhjd3xxyrfkjfmdyvk3gq4rrdhe2e0ul2n637uw", + "status": 3, + "tokens": "22842571937", + "delegator_shares": "22842571937.000000000000000000", + "description": { + "moniker": "MCiuCZVGkF", + "identity": "YVlJRRVogl", + "website": "iBpLGvpPpo", + "security_contact": "bvXcaUSxzJ", + "details": "zsHdsXWXhJ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.012334216153398550" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v67hlsk", + "status": 3, + "tokens": "16236700229", + "delegator_shares": "16236700229.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.498536222135788025" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5l4jsmp", + "status": 3, + "tokens": "42927955154", + "delegator_shares": "42927955154.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.190381602916620701", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.303876600993529705" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g7drc35", + "status": 3, + "tokens": "36911230696", + "delegator_shares": "36911230696.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.194945225911581915", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.300000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcas8xka", + "status": 3, + "tokens": "39363181311", + "delegator_shares": "39363181311.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.028169322828760497", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcvjsxyz", + "status": 3, + "tokens": "27734813665", + "delegator_shares": "27734813665.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.015116864220436494", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskj3a67t", + "status": 3, + "tokens": "24423311847", + "delegator_shares": "24423311847.000000000000000000", + "description": { + "moniker": "OtyVVqWsup", + "identity": "EqaejuaTwX", + "website": "egvJRLAnYF", + "security_contact": "KTzlQLiomS", + "details": "ETXsigXuTY" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.372711230134865265", + "max_rate": "0.460000000000000000", + "max_change_rate": "0.056760418592473079" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjzxhelr", + "status": 3, + "tokens": "25592800910", + "delegator_shares": "25592800910.000000000000000000", + "description": { + "moniker": "NYvAvaIOdj", + "identity": "lYbVDursvX", + "website": "UXtFzZcHjM", + "security_contact": "PNNMeOJqcl", + "details": "ROVIgdvaJl" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.193312772989594496", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.226297820963910157" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsuh3jpet", + "status": 3, + "tokens": "50488222690", + "delegator_shares": "50488222690.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.801397182624616334", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.592521503076154232" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfk090csv4thlsr4kx3fuucwcsk79lqs6gr5zse6m4xmwpq94hy2w3yuqp6", + "status": 3, + "tokens": "20659893696", + "delegator_shares": "20659893696.000000000000000000", + "description": { + "moniker": "gqjwubbLDT", + "identity": "OsKsdzWbsv", + "website": "rhWGeqAAVi", + "security_contact": "FmaEvvcaAr", + "details": "uMULjHPlYr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.168812875456833709" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5t7pxck", + "status": 3, + "tokens": "53644768786", + "delegator_shares": "53644768786.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.180000000000000000", + "max_change_rate": "0.029528662482337368" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2z47zet", + "status": 3, + "tokens": "22907460275", + "delegator_shares": "22907460275.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.026318239077074162", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.076792434560738120" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyw0np92", + "status": 3, + "tokens": "27374742411", + "delegator_shares": "27374742411.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.053895535796610462", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.182737583024108345" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2al69u7pnek9kcrmz83vstrst5szxuz6z03z0d848kuh3ekkjlfgr96q6z", + "status": 3, + "tokens": "20929858941", + "delegator_shares": "20929858941.000000000000000000", + "description": { + "moniker": "ciowxbJZpb", + "identity": "XgDAZmwEir", + "website": "moPXkGzyqT", + "security_contact": "WTLysotltH", + "details": "qoTHCiKGoL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003240694138410597", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.013650990946439583" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtq4rjflca8vgyn08w3vkpqeq57d80dmja25rd0ntqrx5fxm96gtw0umkjg", + "status": 3, + "tokens": "24938844767", + "delegator_shares": "24938844767.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.639608494106780282", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.911798500947612916" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwz7uypw37mz5eky5vktatrwu84geyy9r8jp9dccd73kw62x5hkn54qgedr", + "status": 3, + "tokens": "15286357237", + "delegator_shares": "15286357237.000000000000000000", + "description": { + "moniker": "rXurTMjZPL", + "identity": "AwsdgVtWKY", + "website": "MqIvWlvqZq", + "security_contact": "hoJFiVyrtB", + "details": "FWXLLEocRp" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.298667840621478601", + "max_rate": "0.620000000000000000", + "max_change_rate": "0.023377726384901617" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzvca96h", + "status": 3, + "tokens": "70162120947", + "delegator_shares": "70162120947.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.545864029263808659", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.533310660658318421" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqlk7nha", + "status": 3, + "tokens": "20279593182", + "delegator_shares": "20279593182.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.069908236020668720", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.009891358364124589" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqva0a8amjektwyshzjv38f6dw5uwat88kscw834kf3026r5ksn77gf0857j", + "status": 3, + "tokens": "27984332905", + "delegator_shares": "27984332905.000000000000000000", + "description": { + "moniker": "BKQyTeKaLC", + "identity": "eCoPebxrNV", + "website": "auQgzJBeZR", + "security_contact": "bLlknxqKWU", + "details": "amiXFmUGDr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.900000000000000000", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.031968764827487641" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4cv2x09p", + "status": 3, + "tokens": "22768989048", + "delegator_shares": "22768989048.000000000000000000", + "description": { + "moniker": "EVTkHBKcpE", + "identity": "hMErYohFOn", + "website": "QaWaMRxOKv", + "security_contact": "qaxyuRDTeX", + "details": "ELwgPpPDKw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.386471695225710439" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfjcp62cfnelz8s5cl5qar8ymfjd5sjjkkr4tayrqrtzpf638hkjqmg9q4z", + "status": 3, + "tokens": "26491705865", + "delegator_shares": "26491705865.000000000000000000", + "description": { + "moniker": "SJeSnSdrXp", + "identity": "OTlQTOJbcV", + "website": "sulWDbaxDh", + "security_contact": "XTGtIDYHdJ", + "details": "KNeohKLilE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.965860683215034339", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.778196912581936923" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "consensus_pubkey": "cosmosvalconspub1addwnpepq28myc67l0yhmnn6n2vq8hcmpaxesglyyqg825ujgrxdt9afwlsfx4ezupt", + "status": 3, + "tokens": "16246649557", + "delegator_shares": "16246649557.000000000000000000", + "description": { + "moniker": "mtHVFaNGLx", + "identity": "YTyhLHiifY", + "website": "JFeCDRXGYc", + "security_contact": "HndWqVmQvE", + "details": "JFVkeOUSbg" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.018292046092814578", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.057525240491425891" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z6ckp5s", + "status": 3, + "tokens": "65372138643", + "delegator_shares": "65372138643.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.323440196337864016" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng9t438v", + "status": 3, + "tokens": "22515450726", + "delegator_shares": "22515450726.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.752425052602923482" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6mcm2m0", + "status": 3, + "tokens": "29556680915", + "delegator_shares": "29556680915.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289048467390880739", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.476925303769745140" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswzcmkck", + "status": 3, + "tokens": "25121635132", + "delegator_shares": "25121635132.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.541820589241677763" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "consensus_pubkey": "cosmosvalconspub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z2xdtk5", + "status": 3, + "tokens": "25474072165", + "delegator_shares": "25474072165.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.493962290871886167", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.601549819261141285" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vype2jq", + "status": 3, + "tokens": "59694062218", + "delegator_shares": "59694062218.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.047504130944412074", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.160000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xzg536q0eksvxd2297ycyctfwp6x7rk0wq6d0murld346cjs756v0jnxn", + "status": 3, + "tokens": "16949426508", + "delegator_shares": "16949426508.000000000000000000", + "description": { + "moniker": "dNCvXIwisF", + "identity": "PInuRSnoAB", + "website": "IFaDEJuVii", + "security_contact": "DiiitKvkqG", + "details": "wJQyZMjCjC" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083382298074645848", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.156261937510636548" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag73jg46g", + "status": 3, + "tokens": "41973269906", + "delegator_shares": "41973269906.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.742458631966852296", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.368222450098111604" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4d6e962zqejqu3jeypzp740n4k62xte2qnj82q03y28v6wkshycxxdg5w", + "status": 3, + "tokens": "18158211957", + "delegator_shares": "18158211957.000000000000000000", + "description": { + "moniker": "cVYtBkXobK", + "identity": "JOBpTikHPq", + "website": "NyobvRjfBj", + "security_contact": "bKDbHWcmSW", + "details": "xGfkOaAoAb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.340000000000000000", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.117974822314921419" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4cv0e5r0", + "status": 3, + "tokens": "18240625178", + "delegator_shares": "18240625178.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.004320117912957935", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.000447271047532656" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwfwqlzf", + "status": 3, + "tokens": "16806010630", + "delegator_shares": "16806010630.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.926805735750034881", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.482844926743337660" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qavly08", + "status": 3, + "tokens": "17705677177", + "delegator_shares": "17705677177.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.615745867723667485", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.398263247650399274" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwv80xev", + "status": 3, + "tokens": "26461821776", + "delegator_shares": "26461821776.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.157167562506066789", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.091234306987583436" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwudpuh36geydlpx0yjqu0vhauacf294sn2uetg4ush97p382kqag6sxlqg", + "status": 3, + "tokens": "17862559018", + "delegator_shares": "17862559018.000000000000000000", + "description": { + "moniker": "wSgJTwBWiv", + "identity": "AEATmOIHsP", + "website": "WsuxwwJUIx", + "security_contact": "nzWdiJbKcf", + "details": "WXwvQKoIbT" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.027292850423387945" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq4e58fv", + "status": 3, + "tokens": "112536605413", + "delegator_shares": "112536605413.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.592057337572123856", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.208226705977271974" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7kquya74", + "status": 3, + "tokens": "27525740131", + "delegator_shares": "27525740131.000000000000000000", + "description": { + "moniker": "ajDNnhnkbN", + "identity": "nkdfsqWVlx", + "website": "CeqAfYeTdW", + "security_contact": "KMQJbxKkbm", + "details": "cvAUuqNFYs" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.780000000000000000", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.550890306122411684" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj4x3m9h", + "status": 3, + "tokens": "57637848348", + "delegator_shares": "57637848348.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.081821299211443922", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.458576374327765136" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey2vtdvu", + "status": 3, + "tokens": "19834101875", + "delegator_shares": "19834101875.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.491522368582129610", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.085253529277298261" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0aa00frx8hxrq5pegc0vnt69pj54z3dhwzy8uumr3nhgsc772h0zyr473p", + "status": 3, + "tokens": "37175356106", + "delegator_shares": "37175356106.000000000000000000", + "description": { + "moniker": "oedtWfExZY", + "identity": "taFwTdIwwz", + "website": "oGBHKapVuy", + "security_contact": "hnggEiQcYu", + "details": "qOFIRfzDGP" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083784124252551147", + "max_rate": "0.650000000000000000", + "max_change_rate": "0.550897578676987786" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dsktaxw5", + "status": 3, + "tokens": "55634424696", + "delegator_shares": "55634424696.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.016380613584719475", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.310000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "consensus_pubkey": "cosmosvalconspub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz28vhtm", + "status": 3, + "tokens": "17891746276", + "delegator_shares": "17891746276.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.528106308050967540" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqehts4m", + "status": 3, + "tokens": "56186314306", + "delegator_shares": "56186314306.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.128525196978986815", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.100900376719373255" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru72w0xm", + "status": 3, + "tokens": "18560827275", + "delegator_shares": "18560827275.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.100218404029226728", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.881639682871578638" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00qxpqlwy0p6y9tl23yu7fpu55lhznxa3hrhvsuma6h7lu4c3ekks4wvua", + "status": 3, + "tokens": "22083357722", + "delegator_shares": "22083357722.000000000000000000", + "description": { + "moniker": "LvOuePvVwo", + "identity": "vfegdQlOfT", + "website": "mYvkvMZuDp", + "security_contact": "cfrddDLOlu", + "details": "yHfcxdGyEO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.122593865256918850", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.840000000000000000" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxkm9kvvp", + "status": 3, + "tokens": "26763354026", + "delegator_shares": "26763354026.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.027810962515737967", + "max_rate": "0.070000000000000000", + "max_change_rate": "0.034717076557320762" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvykaseh7", + "status": 3, + "tokens": "68955304480", + "delegator_shares": "68955304480.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.208925360976246176", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.463634503057540350" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peggwy7x5", + "status": 3, + "tokens": "48684061528", + "delegator_shares": "48684061528.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.338644152469426553", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.069153802725768656" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxz2ead4", + "status": 3, + "tokens": "19233426986", + "delegator_shares": "19233426986.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.373154376676147691", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wjfqd63", + "status": 3, + "tokens": "25961659072", + "delegator_shares": "25961659072.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.068613373696134985", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.073351676068018235" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7ul2hc3", + "status": 3, + "tokens": "33320443806", + "delegator_shares": "33320443806.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118849597906926326", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.228258187539755185" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7whvstg", + "status": 3, + "tokens": "36328452639", + "delegator_shares": "36328452639.000000000000000000", + "description": { + "moniker": "cVUXvMdRgs", + "identity": "AHkjmtOkYK", + "website": "KLRPQOyDoY", + "security_contact": "VHwCrfhVnI", + "details": "qdFVvUucvR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.182731553781057822", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.045316794895420248" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqde6g57cex9ff650ku6dqdqtfulfnzkacecf6k436xl0dd07zglxx5659h9", + "status": 3, + "tokens": "34893400220", + "delegator_shares": "34893400220.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.905848795661145449", + "max_rate": "0.950000000000000000", + "max_change_rate": "0.476775855507110704" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy7220f9ul3", + "status": 3, + "tokens": "33772482275", + "delegator_shares": "33772482275.000000000000000000", + "description": { + "moniker": "znFMdpLOQw", + "identity": "LEMEnpcxqp", + "website": "TjKmeKjDGm", + "security_contact": "ZOXcBhlDyq", + "details": "WpmmnksSqL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.834910862331446014", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cuyxrn7n", + "status": 3, + "tokens": "24587685968", + "delegator_shares": "24587685968.000000000000000000", + "description": { + "moniker": "tlYEYvdvKp", + "identity": "fQFtYLRSZA", + "website": "ecuAofwdaj", + "security_contact": "gwsuBeDyJU", + "details": "gELFJGuwPs" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.499259642246008210", + "max_rate": "0.560000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jet5tg3", + "status": 3, + "tokens": "62232444428", + "delegator_shares": "62232444428.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.153116543667039838", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.230000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yfudg7m", + "status": 3, + "tokens": "25948607110", + "delegator_shares": "25948607110.000000000000000000", + "description": { + "moniker": "IssGiFwTJv", + "identity": "VgTaqmOLtN", + "website": "BpkICmEqwF", + "security_contact": "qmrIWxiWft", + "details": "sLtbcsMFgA" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.136694009459855954", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.056116480834729575" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4c8wkdlg", + "status": 3, + "tokens": "18426946099", + "delegator_shares": "18426946099.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.469814499540087620", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.960000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvquc4jf3", + "status": 3, + "tokens": "16774945156", + "delegator_shares": "16774945156.000000000000000000", + "description": { + "moniker": "hZvyDgtWxX", + "identity": "TPMmELNQYL", + "website": "YxTdbJnobM", + "security_contact": "ZURHxVMZoL", + "details": "zVjWraUVyE" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.258972799025106506", + "max_rate": "0.910000000000000000", + "max_change_rate": "0.304259315697044502" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprs83zeag", + "status": 3, + "tokens": "29277603589", + "delegator_shares": "29277603589.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.351977697440288211" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvly6j0pyezy88s9lnat6taglylzq03vvsvyw4uy2tv3vcl3200ej0nev4k", + "status": 3, + "tokens": "16864097437", + "delegator_shares": "16864097437.000000000000000000", + "description": { + "moniker": "lasYiVeRDA", + "identity": "TFiGxJBNUs", + "website": "xswbDClAxs", + "security_contact": "HYUurzqzcC", + "details": "EVSfzEFSuo" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.036542719943188247", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.304756516958654494" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66dra0w3", + "status": 3, + "tokens": "19540440011", + "delegator_shares": "19540440011.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.065303820000927065", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.134868108685582589" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afqga9sv8", + "status": 3, + "tokens": "26083594771", + "delegator_shares": "26083594771.000000000000000000", + "description": { + "moniker": "uVtPIVoLeB", + "identity": "UQUjtBkUkU", + "website": "lrfjDXnSyH", + "security_contact": "tPWaAehpKA", + "details": "YCcmQgJRnO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.859185512301348293", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.915098787337318307" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrq06r4ck", + "status": 3, + "tokens": "41543247193", + "delegator_shares": "41543247193.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.119695944592116460" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4vjajc6x", + "status": 3, + "tokens": "61843733534", + "delegator_shares": "61843733534.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.437478542817284441", + "max_rate": "0.530000000000000000", + "max_change_rate": "0.308410375933996023" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvghhzrgz", + "status": 3, + "tokens": "34513851602", + "delegator_shares": "34513851602.000000000000000000", + "description": { + "moniker": "rUZvoFLmub", + "identity": "dQGYIJXPFq", + "website": "ZPoXnJmgzU", + "security_contact": "MdbwPJFNHC", + "details": "NdoQBlpUhN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.670000000000000000", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.629855974067904060" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz4luxgn", + "status": 3, + "tokens": "33206633235", + "delegator_shares": "33206633235.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.229284159886860129", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.212917450108859841" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw24c76ax", + "status": 3, + "tokens": "27567655084", + "delegator_shares": "27567655084.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.216560651737526756", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.026445047137608599" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qpu7x5c", + "status": 3, + "tokens": "27671960609", + "delegator_shares": "27671960609.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.077841535313299819", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.054979434313866047" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2wcjjal", + "status": 3, + "tokens": "25069342080", + "delegator_shares": "25069342080.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.249161816461641720", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.693944288516379645" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akutfqm7", + "status": 3, + "tokens": "55737096951", + "delegator_shares": "55737096951.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.498362112747574396", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.645641814068879323" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693hazjkkehy", + "status": 3, + "tokens": "38011116376", + "delegator_shares": "38011116376.000000000000000000", + "description": { + "moniker": "mUQFKtnPLD", + "identity": "xsxoaAIVkh", + "website": "EBARfZhhON", + "security_contact": "GynbBFtcRq", + "details": "RftDCeMUPi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.123876475355091478", + "max_rate": "0.860000000000000000", + "max_change_rate": "0.141162753552435345" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v30nmws", + "status": 3, + "tokens": "78601464028", + "delegator_shares": "78601464028.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083731202536014652", + "max_rate": "0.860000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9ykjrzn93", + "status": 3, + "tokens": "18090212819", + "delegator_shares": "18090212819.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.081582427988342735", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.086390137368972014" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06my86wxz2", + "status": 3, + "tokens": "33968139195", + "delegator_shares": "33968139195.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.247483015769197525", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.837420192496215212" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2crvswax", + "status": 3, + "tokens": "16516288319", + "delegator_shares": "16516288319.000000000000000000", + "description": { + "moniker": "kVNZIBYAxD", + "identity": "ChbsAFHanI", + "website": "SvHMthzzzB", + "security_contact": "cMJXUgGCfx", + "details": "PWsrYNKuPZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.540000000000000000", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.491525012965837080" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2kj4krx", + "status": 3, + "tokens": "45010236382", + "delegator_shares": "45010236382.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.095070637134115497" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveesw5rr6m", + "status": 3, + "tokens": "54609814420", + "delegator_shares": "54609814420.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.328146514360581742", + "max_rate": "0.810000000000000000", + "max_change_rate": "0.166428198995593213" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68yqxsxnt", + "status": 3, + "tokens": "25326342688", + "delegator_shares": "25326342688.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.785486462764506620", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.356882054361860100" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzlcd6kj", + "status": 3, + "tokens": "67804970220", + "delegator_shares": "67804970220.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.264013069771684883" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4v8fm8e8", + "status": 3, + "tokens": "38042330922", + "delegator_shares": "38042330922.000000000000000000", + "description": { + "moniker": "LDEzyylLGV", + "identity": "NaLpENvFnX", + "website": "ooOcvgIJwr", + "security_contact": "aQaxAlCyFx", + "details": "CxEFcmLmkI" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.099339754970547702", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.111217397607280422" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt5s2m60xv2n7sxjv7lhzlf83u75fh7yc0pjv3thqf5vkdunr32ksh4xsdu", + "status": 3, + "tokens": "15174649749", + "delegator_shares": "15174649749.000000000000000000", + "description": { + "moniker": "VCTScqQSKa", + "identity": "WzaIRwbXgo", + "website": "BAOhQWhmkQ", + "security_contact": "NncLgAxHdH", + "details": "URrsiopqUa" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.047510383078156072", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.032290417291892447" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k907nvf", + "status": 3, + "tokens": "28676349495", + "delegator_shares": "28676349495.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.609184993023386704", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.699887495531371188" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdzvxgkmxur34cmgyyfzr0mkhrysd6xdqpkz6k0qd62y4hl325qd62h02f4", + "status": 3, + "tokens": "17972090246", + "delegator_shares": "17972090246.000000000000000000", + "description": {}, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.870000000000000000", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.063255826123136327" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "consensus_pubkey": "cosmosvalconspub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjtszrqs", + "status": 3, + "tokens": "49921160762", + "delegator_shares": "49921160762.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.810000000000000000", + "max_rate": "0.810000000000000000", + "max_change_rate": "0.810000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "consensus_pubkey": "cosmosvalconspub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku73m9m0", + "status": 3, + "tokens": "17327949928", + "delegator_shares": "17327949928.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.406968367525101581", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.487609794856186092" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfcdg0aax", + "status": 3, + "tokens": "16967510024", + "delegator_shares": "16967510024.000000000000000000", + "description": { + "moniker": "YKKhjZGayb", + "identity": "IvgiPDjmYA", + "website": "gScrUtVzvh", + "security_contact": "kGHySpHXgu", + "details": "IyuehlcoPM" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.093407705950029411", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.187465926844434813" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7zgmra8", + "status": 3, + "tokens": "26261718579", + "delegator_shares": "26261718579.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.210000000000000000", + "max_change_rate": "0.067309904771533509" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqnavslf", + "status": 3, + "tokens": "51218832094", + "delegator_shares": "51218832094.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.895728278286976959", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.140752130806369269" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jyyn3gu", + "status": 3, + "tokens": "19834661379", + "delegator_shares": "19834661379.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.008115100503323252", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yagkfrr", + "status": 3, + "tokens": "46543454731", + "delegator_shares": "46543454731.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.060188716749386269", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.350000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "consensus_pubkey": "cosmosvalconspub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kwmez9k", + "status": 3, + "tokens": "16420725988", + "delegator_shares": "16420725988.000000000000000000", + "description": { + "moniker": "LVfceOUKZE", + "identity": "ZyVUuaCAJZ", + "website": "rliAdTPvEK", + "security_contact": "hVtZPHOsKh", + "details": "QjmMKruCba" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.036920301680485403" + }, + "update_time": "9936-01-01T16:55:11Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq77rpqn", + "status": 3, + "tokens": "22691569600", + "delegator_shares": "22691569600.000000000000000000", + "description": { + "moniker": "BFoqLaJLDn", + "identity": "weLorPCgTe", + "website": "oyhVcpSOLq", + "security_contact": "hdnvhDJTDC", + "details": "SAZISvvmwB" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.160832184115355939", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xw03emk4", + "status": 3, + "tokens": "44313010729", + "delegator_shares": "44313010729.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083856723472306849", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.569378562223247850" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6yp7zp3n", + "status": 3, + "tokens": "25164533156", + "delegator_shares": "25164533156.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.330000000000000000", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.314039829028852779" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvn899z9u9a7h28682292n9y77yr6yuyrg2xvg8eaammccqfuc9e5jp63vn", + "status": 3, + "tokens": "16985369823", + "delegator_shares": "16985369823.000000000000000000", + "description": { + "moniker": "oVMoJSrGgV", + "identity": "ydZuwvoyLe", + "website": "EdyJLNhNGZ", + "security_contact": "QauDavDNuL", + "details": "CVkbnFlumN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.276325858271560152", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.108166159043578444" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwshp63n", + "status": 3, + "tokens": "18994769458", + "delegator_shares": "18994769458.000000000000000000", + "description": { + "moniker": "KODmaZYfBO", + "identity": "dQoWoZcHpD", + "website": "QRjjuYKVNR", + "security_contact": "BHWzdORGfc", + "details": "dZGTxQmqIN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003392332242825811", + "max_rate": "0.060000000000000000", + "max_change_rate": "0.027187395396712775" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqv0lje47", + "status": 3, + "tokens": "54901950842", + "delegator_shares": "54901950842.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.193375046872051394", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.161750559623523660" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc9m7uvt", + "status": 3, + "tokens": "15374405822", + "delegator_shares": "15374405820.680335249007925874", + "description": { + "moniker": "eomlzRaIRN", + "identity": "PaBTVBXpcj", + "website": "frMwzGwrdS", + "security_contact": "XwCgZGftYO", + "details": "oynChhccDw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.014913519812752309", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.219118316904950121" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7dsh8mr", + "status": 3, + "tokens": "31376033263", + "delegator_shares": "31376033263.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.074914975922116628" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtplsxcj5j56ms8j7lerl57al6asnrh53uft4efkzvuhv50gq8azx0l5f9w", + "status": 3, + "tokens": "25214408688", + "delegator_shares": "25214408688.000000000000000000", + "description": { + "moniker": "qQzVEWDfcL", + "identity": "LQVrYguqLe", + "website": "BJddIAyseo", + "security_contact": "trbqxTDxYA", + "details": "TTjZQrCkYO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.299140431481446428", + "max_rate": "0.510000000000000000", + "max_change_rate": "0.367721024197463519" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axhh8p8f", + "status": 3, + "tokens": "49683234188", + "delegator_shares": "49683234188.000000000000000000", + "description": { + "moniker": "MJAduJwrkS", + "identity": "YpKMJsMpdh", + "website": "rmUXbHIGjh", + "security_contact": "KxyJSeDEJS", + "details": "gQmDpfNyLZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.637063248045666486", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.100218674012239339" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmkm3zs42", + "status": 3, + "tokens": "34289428306", + "delegator_shares": "34289428306.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.026475742223507385", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.008016543161851368" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw3fj2ga", + "status": 3, + "tokens": "29885998584", + "delegator_shares": "29885998584.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.208832068199199828", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.835848953294536000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2vncgld", + "status": 3, + "tokens": "34516338524", + "delegator_shares": "34516338524.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.400358972669819604", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.343431675789315867" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrywn9e6w", + "status": 3, + "tokens": "32328037984", + "delegator_shares": "32328037984.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.039339062684741866", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.021256256594527078" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus2udpwh", + "status": 3, + "tokens": "15813863385", + "delegator_shares": "15813863385.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.543747468021249371", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.392045382869085556" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwujx3ap2", + "status": 3, + "tokens": "25957780472", + "delegator_shares": "25957780472.000000000000000000", + "description": { + "moniker": "hoLpIoNUFo", + "identity": "LCpoujNFyW", + "website": "AOTlTXjPul", + "security_contact": "elgNvDzEfH", + "details": "hwOSWkTDMH" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.347272379813626146", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtj39qcdlmh7fr77am26s8as06l9v3p426z5gr5dyfvc4fr5gqyevxe8agn", + "status": 3, + "tokens": "18831480577", + "delegator_shares": "18831480577.000000000000000000", + "description": { + "moniker": "hjYgiDHhzz", + "identity": "KrwRKCSMYC", + "website": "VKtCXTAtbA", + "security_contact": "kqWNgIhnNy", + "details": "etaTpRtVAp" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.344371628918599076", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.334517383567629324" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9ugfdlq9", + "status": 3, + "tokens": "47141129937", + "delegator_shares": "47141129937.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.340626334815374555", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkxmnmkq", + "status": 3, + "tokens": "26977915837", + "delegator_shares": "26977915837.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.605944631117636209", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.639343774657574630" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqk8ct27q", + "status": 3, + "tokens": "22456561633", + "delegator_shares": "22456561633.000000000000000000", + "description": { + "moniker": "DPTpRIdXgW", + "identity": "qysDMlMxpi", + "website": "xWbmLVlZvB", + "security_contact": "QtpKTducMv", + "details": "UWYfFdNOxg" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.057271144965717909", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.075138495309274904" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd7u4d80m4e6sfhyzj84k6y34v30g9cstzx7cmrazvxdtfe40urcvran9t8", + "status": 3, + "tokens": "45811135531", + "delegator_shares": "45811135531.000000000000000000", + "description": { + "moniker": "zcPImZiDZD", + "identity": "zkcTihefFl", + "website": "mIjAaWRNkf", + "security_contact": "gTafXNexkI", + "details": "tJJDPwaiAf" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.079222020883406460", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.311112908017536993" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggxauhp0sadc5npdva6f492f3n4a76fldyt3lca6lk36685s624ucakcrh", + "status": 3, + "tokens": "25100106074", + "delegator_shares": "25100106074.000000000000000000", + "description": { + "moniker": "dLwrEevbbD", + "identity": "ubSqqBoPRs", + "website": "MNuXpKVOXc", + "security_contact": "lNXuEDYSJp", + "details": "CvXURllZqF" + }, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.175531415042829217" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqwclfkt", + "status": 3, + "tokens": "34459325260", + "delegator_shares": "34459325260.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.033986343509044787", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.090000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7t4673v", + "status": 3, + "tokens": "54014760938", + "delegator_shares": "54014760938.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.440048441195653325", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.180789237411591672" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5r4xrdd", + "status": 3, + "tokens": "15675831119", + "delegator_shares": "15675831119.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czwem9y4", + "status": 3, + "tokens": "25088017519", + "delegator_shares": "25088017519.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.177753292751501209", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.323174353688819429" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxe7jutz", + "status": 3, + "tokens": "46591477836", + "delegator_shares": "46591477836.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.017452646416466178", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.020000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4svau85d", + "status": 3, + "tokens": "31770155824", + "delegator_shares": "31770155824.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.138735148670316454", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.286634953103815529" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf0u600sgl3zdn3uh4jd6jmw6fc0jc40r0l2crvz3sla3f8d32flghwtxaq", + "status": 3, + "tokens": "40258437865", + "delegator_shares": "40258437865.000000000000000000", + "description": { + "moniker": "BUZauhlQrt", + "identity": "yuIKzyGzQS", + "website": "fDSmxAmazc", + "security_contact": "jVDWgXPhkM", + "details": "LBFAwsUoyi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.244517333363622892", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.153245122134586562" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzue70ade", + "status": 3, + "tokens": "38186556308", + "delegator_shares": "38186556308.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.260000000000000000", + "max_rate": "0.260000000000000000", + "max_change_rate": "0.239035612898447459" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj2sy3f5", + "status": 3, + "tokens": "26856561942", + "delegator_shares": "26856561942.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.420000000000000000", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.295551090875771737" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvhet24yk50y4m60mceffquewu9p4enwrgcum0csceuull7a59u6567nn0v", + "status": 3, + "tokens": "20405570669", + "delegator_shares": "20405570669.000000000000000000", + "description": { + "moniker": "ZeprycSOnc", + "identity": "ZcHuivhMFq", + "website": "hCsVpTWmaL", + "security_contact": "AIKsDuUCDR", + "details": "EgpxVbAOaK" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.054000324644638628", + "max_rate": "0.380000000000000000", + "max_change_rate": "0.120973196882786975" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6k07476", + "status": 3, + "tokens": "25102040344", + "delegator_shares": "25102040344.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.599184934718890393", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt0sk5rhcpv85mjvladxx3ygs0auglwcm4xpurjqeex8z99ya86363zl4ug", + "status": 3, + "tokens": "24641977345", + "delegator_shares": "24641977345.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.546622488015386807", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.175928838659210799" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "consensus_pubkey": "cosmosvalconspub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjycl58l", + "status": 3, + "tokens": "41928862316", + "delegator_shares": "41928862316.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.025162698699691548" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75fh3auv", + "status": 3, + "tokens": "19565632897", + "delegator_shares": "19565632897.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.579061375935434182", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwskjpjy", + "status": 3, + "tokens": "44648874284", + "delegator_shares": "44648874284.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.258140043497759741", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.447039357737510640" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg57gy4ef", + "status": 3, + "tokens": "34209671267", + "delegator_shares": "34209671267.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.480455308806333346", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55hrcqtd", + "status": 3, + "tokens": "25069342080", + "delegator_shares": "25069342080.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.409558857679769509", + "max_rate": "0.930000000000000000", + "max_change_rate": "0.610998804526507722" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0sgshv9mf8qy7ff303mqqv5zppu3q4mcwrnheue8d3kq0ytyynkxlak2ae", + "status": 3, + "tokens": "28980476016", + "delegator_shares": "28980476016.000000000000000000", + "description": { + "moniker": "hVYOUraqpo", + "identity": "XRliNUdYgt", + "website": "FYzwRNeFsW", + "security_contact": "AYYtrdbBmx", + "details": "NaWAwUYhir" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxd2wcms", + "status": 3, + "tokens": "27742737411", + "delegator_shares": "27742737411.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.870000000000000000", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.402061609548054151" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2x30aum6t8lauwqh72szktjx6fmgf5ux7vcs38uukp9a5h287wawhv5mfv", + "status": 3, + "tokens": "17377751306", + "delegator_shares": "17377751306.000000000000000000", + "description": { + "moniker": "SslqJkEqrN", + "identity": "qMdXPqvbCt", + "website": "HDwwjWlugU", + "security_contact": "LzWMObthwF", + "details": "zlyoRqwOQS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.498765541593724538", + "max_rate": "0.530000000000000000", + "max_change_rate": "0.156108348646223859" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3lu0qw8kj", + "status": 3, + "tokens": "23737653202", + "delegator_shares": "23737653202.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.450461328836777178", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.254665389885134513" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcf30j9c", + "status": 3, + "tokens": "74690344989", + "delegator_shares": "74690344989.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.882630947578979215", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.960000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr2mqfkju", + "status": 3, + "tokens": "27874325464", + "delegator_shares": "27874325464.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.459241580368376871", + "max_rate": "0.490000000000000000", + "max_change_rate": "0.448990769658695281" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngklt9fqt", + "status": 3, + "tokens": "67833673918", + "delegator_shares": "67833673918.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.280411773058535090", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.009358685901125498" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdq8fheeu", + "status": 3, + "tokens": "25475671492", + "delegator_shares": "25475671492.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.073669961838812257", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.338443455873010612" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdjuv3ql5rv5njym62quduw7554as4aa8seufp7f4zv6q28tds2e23v4cv5", + "status": 3, + "tokens": "35741739231", + "delegator_shares": "35741739231.000000000000000000", + "description": { + "moniker": "MoJgIrbTvT", + "identity": "rTfyDjhPlV", + "website": "fXpRItnlwS", + "security_contact": "tIlMCZPLDi", + "details": "QoSUrnFXNb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.037606710200997532", + "max_rate": "0.610000000000000000", + "max_change_rate": "0.432717335122536998" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwvhpfht", + "status": 3, + "tokens": "19637280062", + "delegator_shares": "19637280062.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118259925415637398", + "max_rate": "0.220000000000000000", + "max_change_rate": "0.176572964585642890" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwaazwez", + "status": 3, + "tokens": "56856814851", + "delegator_shares": "56856814851.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.093189165744722643", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.044880981942823250" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtcxreszx2wu4ngd3amegdgh9549fr4yh4mgvs862ea44ugjv0leywawqen", + "status": 3, + "tokens": "18846592576", + "delegator_shares": "18846592576.000000000000000000", + "description": { + "moniker": "kcMqvkQeGm", + "identity": "ZKjzktvrAj", + "website": "EzWzZovCJZ", + "security_contact": "hwPlfWocdU", + "details": "vvHigjWyJK" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.307501014763216711", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.592156519673221532" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyvxmu04", + "status": 3, + "tokens": "36122807193", + "delegator_shares": "36122807193.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.414145633705698803", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2p3sa8dkvz36pz6nusjdhm9aqlnrrldrszzuqd5qy7ssqztn99ggqpcdlz", + "status": 3, + "tokens": "48540826744", + "delegator_shares": "48540826744.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003549575739989554", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.001119527935415439" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycjhwrn7", + "status": 3, + "tokens": "29401856985", + "delegator_shares": "29401856985.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.243341366114153903", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.628404054381210058" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdaa2szanfjwhzucqfj0ct7ljhc3kew8am3h8sr8wqzlnh8df06g5th460y", + "status": 3, + "tokens": "24697024268", + "delegator_shares": "24697024268.000000000000000000", + "description": { + "moniker": "XYWZXrqRDE", + "identity": "MFgElwSSlb", + "website": "ZPGkarWAml", + "security_contact": "dFzxEZXTfo", + "details": "HRGbXKBEeq" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.550000000000000000", + "max_change_rate": "0.376530136432859216" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgtrcqtxc62uk24ac873z7ns2gz75znes579xk2m0xzxpjqswh08kh6nrm0", + "status": 3, + "tokens": "15012824613", + "delegator_shares": "15012824613.000000000000000000", + "description": { + "moniker": "TzIitNrGWU", + "identity": "UtpzgJMsxj", + "website": "KMxjEKqFGe", + "security_contact": "GczmfoVPHm", + "details": "fMoGrNqroM" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.413119742047134521", + "max_rate": "0.590000000000000000", + "max_change_rate": "0.590000000000000000" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w4r0vhq", + "status": 3, + "tokens": "41494205421", + "delegator_shares": "41494205421.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.070000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgc0dahup", + "status": 3, + "tokens": "54398813120", + "delegator_shares": "54398813120.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.109747630034489371", + "max_rate": "0.970000000000000000", + "max_change_rate": "0.461346401411912639" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkn6paax", + "status": 3, + "tokens": "23703504292", + "delegator_shares": "23703504292.000000000000000000", + "description": { + "moniker": "eXfwGKuzGb", + "identity": "dYpMrjwrPA", + "website": "DzaFOsditE", + "security_contact": "GuNLPoNZsM", + "details": "iALsKeROvR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.087538799057934086", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.859363741701174499" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyt542en", + "status": 3, + "tokens": "69725274862", + "delegator_shares": "69725274862.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.077835183941357357", + "max_rate": "0.630000000000000000", + "max_change_rate": "0.287966636331923139" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsrp7s99", + "status": 3, + "tokens": "25470495498", + "delegator_shares": "25470495498.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.420000000000000000", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.006473324874363207" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd5jsj53j7m0umzvh90dwanxhfxmpydhfazmsz978v9yuh05q0kxcyqtdla", + "status": 3, + "tokens": "16747268503", + "delegator_shares": "16747268503.000000000000000000", + "description": { + "moniker": "OuShqctNnC", + "identity": "MfQbnbeXdv", + "website": "OfOpteXCQn", + "security_contact": "qaSLhJmnUG", + "details": "vIuRzAnYuu" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.589668369513377579", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.640000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge726q0dwq", + "status": 3, + "tokens": "56914095343", + "delegator_shares": "56914095343.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.561558403350280399", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.088588598076790894" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0us7fav4", + "status": 3, + "tokens": "41972647667", + "delegator_shares": "41972647667.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.148502470554898869", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.005661642347781868" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw32mxlzzzmmpks775cgclcsmypqhhz7765v03wnjf8cn4hsrw67tq2l8n", + "status": 3, + "tokens": "20301516153", + "delegator_shares": "20301516153.000000000000000000", + "description": { + "moniker": "ibdjDFXkFg", + "identity": "BhaqDbDPwH", + "website": "KoHplbnTSd", + "security_contact": "zgJBSepZRt", + "details": "anTLerUmWY" + }, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.092279263137073204", + "max_rate": "0.130000000000000000", + "max_change_rate": "0.062347977318301413" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4umtaftt", + "status": 3, + "tokens": "23438430919", + "delegator_shares": "23438430919.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.065104244001935780", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.087973256413395308" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wu8lrdvr", + "status": 3, + "tokens": "23476663612", + "delegator_shares": "23476663612.000000000000000000", + "description": { + "moniker": "qNlNvDKQWh", + "identity": "PdEEmVXzOP", + "website": "jyQRsxutdI", + "security_contact": "hTNdvfWkVQ", + "details": "gPNrXPrkeL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.830000000000000000", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.679717803083962746" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7pax9cuqs5vjjvhpmcgvy5dkqrrtrg6336c3xhyrchtegy2m387ccs037", + "status": 3, + "tokens": "19815525788", + "delegator_shares": "19815525788.000000000000000000", + "description": { + "moniker": "sJKzLUYWBq", + "identity": "ZzbWnFqPTq", + "website": "dlevXyAGdk", + "security_contact": "bnQNzwNRYP", + "details": "PaxiDbFCJj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.291627565410574418", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.017987067010819344" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wel7d3l", + "status": 3, + "tokens": "25456865344", + "delegator_shares": "25456865344.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.293848609442759777", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.580000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6u59lzkg", + "status": 3, + "tokens": "32989599899", + "delegator_shares": "32989599899.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.045106108515206331", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.610987430943531252" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xvdql9k", + "status": 3, + "tokens": "25311353934", + "delegator_shares": "25311353934.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.324580145668396309", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.480000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujgucg2ktdn", + "status": 3, + "tokens": "33288895711", + "delegator_shares": "33288895711.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.322505571100731689", + "max_rate": "0.520000000000000000", + "max_change_rate": "0.183472725952677048" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592jkkxzm", + "status": 3, + "tokens": "21858111883", + "delegator_shares": "21858111883.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.799310131872627643", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.706235617003159879" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxtyq8dz", + "status": 3, + "tokens": "16946315559", + "delegator_shares": "16946315559.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.174404138163737710", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.360000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + } + ] + }, + { + "header": { + "version": {}, + "chain_id": "simulation-app", + "height": "49", + "time": "9936-01-04T15:40:16Z", + "last_block_id": { + "parts_header": {} + }, + "proposer_address": "LmPwns0Mxbb7x0GEW4Bz6Zx4B7E=" + }, + "valset": [ + { + "operator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels7tpscy", + "status": 3, + "tokens": "24767745772", + "delegator_shares": "24767745772.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.064962829627143450", + "max_rate": "0.700000000000000000", + "max_change_rate": "0.524524837966075502" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xt2s2vh", + "status": 3, + "tokens": "40149298125", + "delegator_shares": "40149298125.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020987080088521851", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.079654399773437862" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk7tt4rl", + "status": 3, + "tokens": "33873720903", + "delegator_shares": "33873720903.000000000000000000", + "description": { + "moniker": "mLoNnmWUiV", + "identity": "RHiUhLQQnZ", + "website": "GdVEOYibSd", + "security_contact": "DcfUpyGSpE", + "details": "kaQgULDDFV" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.793635545567707656", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.546926599085395557" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfkykt89x2wmxt2w74v340hwp8azwyzswzgxzmcv46995zwggpu66ans7kn", + "status": 3, + "tokens": "17076084961", + "delegator_shares": "17076084961.000000000000000000", + "description": { + "moniker": "qorkgLHbbW", + "identity": "vVsXuupmaH", + "website": "GASCHEJsbz", + "security_contact": "KEcXQQooNh", + "details": "UlGvDMHBgm" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150351690116871266", + "max_rate": "0.470000000000000000", + "max_change_rate": "0.232118363435586291" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcrkzkl0", + "status": 3, + "tokens": "76742997299", + "delegator_shares": "76742997299.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.159853619317053801", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.178173481628386356" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0yv2h8z80vtfttsewrwe2v83haaceax7q3ey95uaeqj8lstf7l674zn3ut", + "status": 3, + "tokens": "16016194501", + "delegator_shares": "16016194501.000000000000000000", + "description": { + "moniker": "WVhrVMjLnZ", + "identity": "QiIQjemxtv", + "website": "KCKlbRarYk", + "security_contact": "AwimEeOMDq", + "details": "omCiVdOfZS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.636807270475032336", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.762928812525012131" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghknhrvft", + "status": 3, + "tokens": "32584502965", + "delegator_shares": "32584502965.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.063963134401067102" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgt7tyq6", + "status": 3, + "tokens": "15545552914", + "delegator_shares": "15545552914.000000000000000000", + "description": { + "moniker": "VaOLitHrfh", + "identity": "zYkbJeTdPC", + "website": "RWLWpQBLTs", + "security_contact": "EEFOrnsvml", + "details": "xRXuWfcvoz" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.209346043397093808", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.261491014079542938" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpvkknmf7", + "status": 3, + "tokens": "35273490053", + "delegator_shares": "35273490053.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.412168984856446389", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.601152598273329028" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvw0g93n8", + "status": 3, + "tokens": "24353363633", + "delegator_shares": "24353363633.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.140843713075627976", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.124247346623493378" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtxrkpudghuhgsu0he7ntk7q0asqa5ax23y7rnn5mfjr2d68z4emsrwqssp", + "status": 3, + "tokens": "44979344173", + "delegator_shares": "44979344173.000000000000000000", + "description": { + "moniker": "eJECwiPlqs", + "identity": "TywZsaZwgH", + "website": "jtFVQJUofX", + "security_contact": "fstanspUpc", + "details": "RQddrwMsIR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.005369299901591159", + "max_rate": "0.030000000000000000", + "max_change_rate": "0.010979308887356502" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwz2zelc", + "status": 3, + "tokens": "24972834479", + "delegator_shares": "24972834479.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118883162683785924", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.582076368438090700" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2dcqs6jwgqs06hz297xdv606lcyx76wnyf228c98wsnmrarnjg7qdrlhmh", + "status": 3, + "tokens": "15307584671", + "delegator_shares": "15307584671.000000000000000000", + "description": { + "moniker": "MLAiGifuge", + "identity": "YmgtyeQqKn", + "website": "tgmRpbrPqg", + "security_contact": "EoVdOQlqiF", + "details": "MFxkDUZjLF" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.079450929148714776", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.213073238635972528" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q205udc4", + "status": 3, + "tokens": "37286335725", + "delegator_shares": "37286335725.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.137121313165408722" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zycdvvrg7", + "status": 3, + "tokens": "26109827309", + "delegator_shares": "26109827309.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.272379182115041576" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "consensus_pubkey": "cosmosvalconspub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwlhqscf", + "status": 3, + "tokens": "25204407264", + "delegator_shares": "25204407264.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.276804190595109972", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.303611347820460701" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2u3gzal", + "status": 3, + "tokens": "23014258552", + "delegator_shares": "23014258552.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289943655120962524", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.271265684659427360" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgh4tj7q", + "status": 3, + "tokens": "49505425616", + "delegator_shares": "49505425616.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.519126528788995280", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw55ftmtn", + "status": 3, + "tokens": "52891997390", + "delegator_shares": "52891997390.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.006443603339396517", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.110565720532816181" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavc40dh4", + "status": 3, + "tokens": "69365122054", + "delegator_shares": "69365122054.000000000000000000", + "description": { + "moniker": "IoqkplxtIQ", + "identity": "SYtEYnqVjz", + "website": "cbrMdhVrVp", + "security_contact": "eWitXxyhJZ", + "details": "FCojJQQFCQ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.745132980800690980", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.321606633967630124" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tugphy2d", + "status": 3, + "tokens": "17054284690", + "delegator_shares": "17054284690.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.602634897210355218", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.136597759514787421" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jztkylp", + "status": 3, + "tokens": "55080258715", + "delegator_shares": "55080258715.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.052047960532670175", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgrwz3gl", + "status": 3, + "tokens": "17768682341", + "delegator_shares": "17768682341.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.141929485726276362" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yr97z8g", + "status": 3, + "tokens": "22598538029", + "delegator_shares": "22598538029.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.335354744004515496", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.096800797786563611" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2zq3f3j", + "status": 3, + "tokens": "27149799034", + "delegator_shares": "27149799034.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.158969199652087770", + "max_rate": "0.220000000000000000", + "max_change_rate": "0.220000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq246sxc5kns0ym6st5wyf6mk0x2cayek9wngczyvgk8phxrat02cqh8w5p2", + "status": 3, + "tokens": "49314038732", + "delegator_shares": "49314038732.000000000000000000", + "description": { + "moniker": "caRBWwzxXd", + "identity": "BJSnkbfQjh", + "website": "ELsVPBoBHb", + "security_contact": "nZkoSMuzKV", + "details": "AuAKjeoitI" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.010525961964940541", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.045814731203367877" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jhhj4uv", + "status": 3, + "tokens": "26185707851", + "delegator_shares": "26185707851.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.568319127244896272", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.226261076338173049" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5u4v4q5", + "status": 3, + "tokens": "32785129607", + "delegator_shares": "32785129607.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.009044195385937429", + "max_rate": "0.010000000000000000", + "max_change_rate": "0.002281789765845776" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpqq8zx8p", + "status": 3, + "tokens": "33846192792", + "delegator_shares": "33846192792.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.094250378854551281", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.043420993012939508" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv79a2a0wcq9kr62m5yupvx82mlxwxw6hx7c8dyl4trf8k2w7vh3w5wlhy0", + "status": 3, + "tokens": "25066394767", + "delegator_shares": "25066394767.000000000000000000", + "description": { + "moniker": "liMRThtiLT", + "identity": "QPHsvzHnkx", + "website": "BytvAmppJT", + "security_contact": "iBgKxrOkqF", + "details": "RcELAgZeDN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.115126355797501393", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.289658857878369113" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfp9mvx6gjdezn2vfxn9jk7jm2urml0xyvt3yg64s03yzkfphrthsdy925d", + "status": 3, + "tokens": "25061237568", + "delegator_shares": "25061237568.000000000000000000", + "description": { + "moniker": "wmxxGOZTpL", + "identity": "azxfwYYUUt", + "website": "izxOUVhQSX", + "security_contact": "lRgXsoitme", + "details": "eebhMKbHXO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.578049895054733896", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.402405887034980654" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc255eyr9", + "status": 3, + "tokens": "76719658246", + "delegator_shares": "76719658246.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.321194785873117781", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.561602155526895676" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u43hapa", + "status": 3, + "tokens": "18750673243", + "delegator_shares": "18750673243.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.188948913118426394", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.274693773376656673" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvpup8kv2mmqajfs08aks8yu8kcuwd323y4f0wu9e3k5grynt0g6ule9mjg", + "status": 3, + "tokens": "24248574347", + "delegator_shares": "24248574347.000000000000000000", + "description": { + "moniker": "bsrCMyYTRM", + "identity": "cTWbJOIMRX", + "website": "EMzKHBarjX", + "security_contact": "spsTAIOECF", + "details": "fTrZtqJTUr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.455524678875180233", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-01T06:29:20Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d29fg079", + "status": 3, + "tokens": "82798702711", + "delegator_shares": "82798702711.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289674444273548704", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.060992257943659564" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgss8cv9u", + "status": 3, + "tokens": "26155915081", + "delegator_shares": "26155915081.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.333198345990187069", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.410926346802169727" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "consensus_pubkey": "cosmosvalconspub1addwnpepqghlm3r37c95q3p3wvr8fxw8mvvdtj3tvhgduhzgzh4238ynz6f06f0rjfd", + "status": 3, + "tokens": "32485653471", + "delegator_shares": "32485653471.000000000000000000", + "description": { + "moniker": "hjulbVDPpf", + "identity": "pRsBrwBRzq", + "website": "VjiSZKAfKB", + "security_contact": "UHZkwTciXO", + "details": "JTfVgehmsi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.311759176624756474" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwus66jdl", + "status": 3, + "tokens": "54108139534", + "delegator_shares": "54108139534.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22ep2k8n", + "status": 3, + "tokens": "69316998057", + "delegator_shares": "69316998057.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.624946300778690751", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.204995912261423056" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7ejhy28", + "status": 3, + "tokens": "27808118568", + "delegator_shares": "27808118568.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.067795278161998694", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.011309118617844055" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5kc0mzw", + "status": 3, + "tokens": "17750303222", + "delegator_shares": "17750303222.000000000000000000", + "description": { + "moniker": "uloyQQWkyI", + "identity": "gFyXSGlhKI", + "website": "ewFltsApZk", + "security_contact": "YGvOhkEKJw", + "details": "vIoOsfiLuj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.068730439287548849", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.118090772640391070" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv0pnal4w8hydpq3vydqgjxmmxz7zg2g9lsj5vedvjq3pw6typfdcjfm5tc", + "status": 3, + "tokens": "16214844041", + "delegator_shares": "16214844041.000000000000000000", + "description": { + "moniker": "jKdcmnPYfC", + "identity": "exfUuYgqmd", + "website": "XdNCNZIBOf", + "security_contact": "hmiwPGchGt", + "details": "nUnBufZQah" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.330000000000000000", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.051583680374523519" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057uxwdfy", + "status": 3, + "tokens": "23352431465", + "delegator_shares": "23352431465.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.760000000000000000", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.183753469845780730" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvy095yf8a7eknhlnwzkum0wt53njxxww60vte7qkutwczt534dwhaclpm", + "status": 3, + "tokens": "34693121909", + "delegator_shares": "34693121909.000000000000000000", + "description": { + "moniker": "RuzZVxWXdB", + "identity": "QjsgdqaNzA", + "website": "UtlkBZyIyQ", + "security_contact": "vnsfyiwxFP", + "details": "dOxLDmGKTb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.005447024365505786", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.005395717096845063" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef5gg2q6z", + "status": 3, + "tokens": "42958814024", + "delegator_shares": "42958814024.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.077000158168963029", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.197697608060710078" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwv7ukq0", + "status": 3, + "tokens": "21734647779", + "delegator_shares": "21734647779.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.460679550676466675", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.165088210560206816" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwc7h5wds8u3tspx3mwpfh5l3q3rv0t6ff33dt205v2zy2kxev9sykcs9uv", + "status": 3, + "tokens": "29256610441", + "delegator_shares": "29256610441.000000000000000000", + "description": { + "moniker": "iYUgQcrziE", + "identity": "hDYXNaKKIu", + "website": "FYsreoPnoD", + "security_contact": "FGAHzGKfjM", + "details": "gkHwWfssaE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.585764113115952818", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz4r8scm", + "status": 3, + "tokens": "65051132532", + "delegator_shares": "65051132532.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.041535797793389960", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.029250263820409753" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2cxeaw4", + "status": 3, + "tokens": "18897052265", + "delegator_shares": "18897052265.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.416117321788354038", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.139830256647094326" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazfcl7f9", + "status": 3, + "tokens": "27157083976", + "delegator_shares": "27157083976.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.170000000000000000", + "max_change_rate": "0.024288054259102348" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgxqjc3u3", + "status": 3, + "tokens": "45028692546", + "delegator_shares": "45028692546.000000000000000000", + "description": { + "moniker": "UeFBWJANuQ", + "identity": "gypzUiAlRd", + "website": "zZezcKCiKy", + "security_contact": "KSXTvslQOC", + "details": "qqNIBlVIYk" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.075610127679217055", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.290000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xwmrp7sq", + "status": 3, + "tokens": "35018830437", + "delegator_shares": "35018830437.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.405901469124460870" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "consensus_pubkey": "cosmosvalconspub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc92g545rl", + "status": 3, + "tokens": "17547285969", + "delegator_shares": "17547285969.000000000000000000", + "description": {}, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.073548473514397047", + "max_rate": "0.440000000000000000", + "max_change_rate": "0.413655116572301617" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wyr7x83", + "status": 3, + "tokens": "25071600389", + "delegator_shares": "25071600389.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.280000000000000000", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.063599161373317498" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymswdv67m", + "status": 3, + "tokens": "27784307296", + "delegator_shares": "27784307296.000000000000000000", + "description": { + "moniker": "mjkYspzJbE", + "identity": "xWPMeIdPEi", + "website": "xtRPXfTiQB", + "security_contact": "sdKpqtdpNe", + "details": "MnLujfMpnW" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.072530327063185081" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslqg7mlcx", + "status": 3, + "tokens": "31634692393", + "delegator_shares": "31634692393.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.554757466700447989", + "max_rate": "0.820000000000000000", + "max_change_rate": "0.408903182457515462" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvlfyhyylne6t33wzse5vhjd3xxyrfkjfmdyvk3gq4rrdhe2e0ul2n637uw", + "status": 3, + "tokens": "25080486106", + "delegator_shares": "25080486106.000000000000000000", + "description": { + "moniker": "MCiuCZVGkF", + "identity": "YVlJRRVogl", + "website": "iBpLGvpPpo", + "security_contact": "bvXcaUSxzJ", + "details": "zsHdsXWXhJ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.012334216153398550" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v67hlsk", + "status": 3, + "tokens": "16236700229", + "delegator_shares": "16236700229.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.498536222135788025" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5l4jsmp", + "status": 3, + "tokens": "42927955154", + "delegator_shares": "42927955154.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.190381602916620701", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.303876600993529705" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g7drc35", + "status": 3, + "tokens": "36911230696", + "delegator_shares": "36911230696.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.194945225911581915", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.300000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcas8xka", + "status": 3, + "tokens": "39363181311", + "delegator_shares": "39363181311.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.028169322828760497", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcvjsxyz", + "status": 3, + "tokens": "27734813665", + "delegator_shares": "27734813665.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.015116864220436494", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd5nsxkua92z9eamd4hccf0pxeh3chye2475vcrwc22dpxj4lmkvuy950w7", + "status": 3, + "tokens": "27605610764", + "delegator_shares": "27605610764.000000000000000000", + "description": { + "moniker": "RLaOPuFvKx", + "identity": "LQfktbUgZN", + "website": "JiRhAUTjQG", + "security_contact": "LTGuZUEvcW", + "details": "QjLWSYAXxH" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskj3a67t", + "status": 3, + "tokens": "24423311847", + "delegator_shares": "24423311847.000000000000000000", + "description": { + "moniker": "OtyVVqWsup", + "identity": "EqaejuaTwX", + "website": "egvJRLAnYF", + "security_contact": "KTzlQLiomS", + "details": "ETXsigXuTY" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.372711230134865265", + "max_rate": "0.460000000000000000", + "max_change_rate": "0.056760418592473079" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjzxhelr", + "status": 3, + "tokens": "25592800910", + "delegator_shares": "25592800910.000000000000000000", + "description": { + "moniker": "NYvAvaIOdj", + "identity": "lYbVDursvX", + "website": "UXtFzZcHjM", + "security_contact": "PNNMeOJqcl", + "details": "ROVIgdvaJl" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.193312772989594496", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.226297820963910157" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvvur4tyyl553c4jeyvce0w3d0ezrrmsr6a2kcdksca4wpflc3lj7nf6fm9", + "status": 3, + "tokens": "25675698411", + "delegator_shares": "25675698411.000000000000000000", + "description": { + "moniker": "wDAGDTplVL", + "identity": "VUJoHvcuZs", + "website": "JzvbSfINxu", + "security_contact": "cROcYcTImn", + "details": "bdBDwVnOvM" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.108086670177688287", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.123495090782214164" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsuh3jpet", + "status": 3, + "tokens": "50488222690", + "delegator_shares": "50488222690.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.801397182624616334", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.592521503076154232" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfk090csv4thlsr4kx3fuucwcsk79lqs6gr5zse6m4xmwpq94hy2w3yuqp6", + "status": 3, + "tokens": "20659893696", + "delegator_shares": "20659893696.000000000000000000", + "description": { + "moniker": "gqjwubbLDT", + "identity": "OsKsdzWbsv", + "website": "rhWGeqAAVi", + "security_contact": "FmaEvvcaAr", + "details": "uMULjHPlYr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.168812875456833709" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5t7pxck", + "status": 3, + "tokens": "53644768786", + "delegator_shares": "53644768786.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.180000000000000000", + "max_change_rate": "0.029528662482337368" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2z47zet", + "status": 3, + "tokens": "21168715051", + "delegator_shares": "21168715051.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.026318239077074162", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.076792434560738120" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyw0np92", + "status": 3, + "tokens": "27374742411", + "delegator_shares": "27374742411.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.053895535796610462", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.182737583024108345" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2al69u7pnek9kcrmz83vstrst5szxuz6z03z0d848kuh3ekkjlfgr96q6z", + "status": 3, + "tokens": "20929858941", + "delegator_shares": "20929858941.000000000000000000", + "description": { + "moniker": "ciowxbJZpb", + "identity": "XgDAZmwEir", + "website": "moPXkGzyqT", + "security_contact": "WTLysotltH", + "details": "qoTHCiKGoL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003240694138410597", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.013650990946439583" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzvca96h", + "status": 3, + "tokens": "70162120947", + "delegator_shares": "70162120947.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.545864029263808659", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.533310660658318421" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqlk7nha", + "status": 3, + "tokens": "20279593182", + "delegator_shares": "20279593182.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.069908236020668720", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.009891358364124589" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqva0a8amjektwyshzjv38f6dw5uwat88kscw834kf3026r5ksn77gf0857j", + "status": 3, + "tokens": "31584297936", + "delegator_shares": "31584297936.000000000000000000", + "description": { + "moniker": "BKQyTeKaLC", + "identity": "eCoPebxrNV", + "website": "auQgzJBeZR", + "security_contact": "bLlknxqKWU", + "details": "amiXFmUGDr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.900000000000000000", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.031968764827487641" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4cv2x09p", + "status": 3, + "tokens": "22768989048", + "delegator_shares": "22768989048.000000000000000000", + "description": { + "moniker": "EVTkHBKcpE", + "identity": "hMErYohFOn", + "website": "QaWaMRxOKv", + "security_contact": "qaxyuRDTeX", + "details": "ELwgPpPDKw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.386471695225710439" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfjcp62cfnelz8s5cl5qar8ymfjd5sjjkkr4tayrqrtzpf638hkjqmg9q4z", + "status": 3, + "tokens": "26491705865", + "delegator_shares": "26491705865.000000000000000000", + "description": { + "moniker": "SJeSnSdrXp", + "identity": "OTlQTOJbcV", + "website": "sulWDbaxDh", + "security_contact": "XTGtIDYHdJ", + "details": "KNeohKLilE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.965860683215034339", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.778196912581936923" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "consensus_pubkey": "cosmosvalconspub1addwnpepq28myc67l0yhmnn6n2vq8hcmpaxesglyyqg825ujgrxdt9afwlsfx4ezupt", + "status": 3, + "tokens": "16246649557", + "delegator_shares": "16246649557.000000000000000000", + "description": { + "moniker": "mtHVFaNGLx", + "identity": "YTyhLHiifY", + "website": "JFeCDRXGYc", + "security_contact": "HndWqVmQvE", + "details": "JFVkeOUSbg" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.018292046092814578", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.057525240491425891" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z6ckp5s", + "status": 3, + "tokens": "62801915451", + "delegator_shares": "62801915451.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.323440196337864016" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng9t438v", + "status": 3, + "tokens": "22515450726", + "delegator_shares": "22515450726.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.752425052602923482" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6mcm2m0", + "status": 3, + "tokens": "29556680915", + "delegator_shares": "29556680915.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289048467390880739", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.476925303769745140" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswzcmkck", + "status": 3, + "tokens": "25121635132", + "delegator_shares": "25121635132.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.541820589241677763" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "consensus_pubkey": "cosmosvalconspub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z2xdtk5", + "status": 3, + "tokens": "25662668318", + "delegator_shares": "25662668318.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.493962290871886167", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.601549819261141285" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vype2jq", + "status": 3, + "tokens": "59694062218", + "delegator_shares": "59694062218.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.047504130944412074", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.160000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xzg536q0eksvxd2297ycyctfwp6x7rk0wq6d0murld346cjs756v0jnxn", + "status": 3, + "tokens": "16949426508", + "delegator_shares": "16949426508.000000000000000000", + "description": { + "moniker": "dNCvXIwisF", + "identity": "PInuRSnoAB", + "website": "IFaDEJuVii", + "security_contact": "DiiitKvkqG", + "details": "wJQyZMjCjC" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083382298074645848", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.156261937510636548" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag73jg46g", + "status": 3, + "tokens": "41973269906", + "delegator_shares": "41973269906.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.742458631966852296", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.368222450098111604" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4d6e962zqejqu3jeypzp740n4k62xte2qnj82q03y28v6wkshycxxdg5w", + "status": 3, + "tokens": "18158211957", + "delegator_shares": "18158211957.000000000000000000", + "description": { + "moniker": "cVYtBkXobK", + "identity": "JOBpTikHPq", + "website": "NyobvRjfBj", + "security_contact": "bKDbHWcmSW", + "details": "xGfkOaAoAb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.340000000000000000", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.117974822314921419" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4cv0e5r0", + "status": 3, + "tokens": "25435646393", + "delegator_shares": "25435646393.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.004320117912957935", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.000447271047532656" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwfwqlzf", + "status": 3, + "tokens": "16773399211", + "delegator_shares": "16773399211.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.926805735750034881", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.482844926743337660" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qavly08", + "status": 3, + "tokens": "17705677177", + "delegator_shares": "17705677177.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.615745867723667485", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.398263247650399274" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwv80xev", + "status": 3, + "tokens": "26461821776", + "delegator_shares": "26461821776.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.157167562506066789", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.091234306987583436" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwudpuh36geydlpx0yjqu0vhauacf294sn2uetg4ush97p382kqag6sxlqg", + "status": 3, + "tokens": "17862559018", + "delegator_shares": "17862559018.000000000000000000", + "description": { + "moniker": "wSgJTwBWiv", + "identity": "AEATmOIHsP", + "website": "WsuxwwJUIx", + "security_contact": "nzWdiJbKcf", + "details": "WXwvQKoIbT" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.027292850423387945" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq4e58fv", + "status": 3, + "tokens": "112536605413", + "delegator_shares": "112536605413.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.592057337572123856", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.208226705977271974" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7kquya74", + "status": 3, + "tokens": "27525740131", + "delegator_shares": "27525740131.000000000000000000", + "description": { + "moniker": "ajDNnhnkbN", + "identity": "nkdfsqWVlx", + "website": "CeqAfYeTdW", + "security_contact": "KMQJbxKkbm", + "details": "cvAUuqNFYs" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.780000000000000000", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.550890306122411684" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj4x3m9h", + "status": 3, + "tokens": "57637848348", + "delegator_shares": "57637848348.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.081821299211443922", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.458576374327765136" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey2vtdvu", + "status": 3, + "tokens": "19834101875", + "delegator_shares": "19834101875.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.491522368582129610", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.085253529277298261" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0aa00frx8hxrq5pegc0vnt69pj54z3dhwzy8uumr3nhgsc772h0zyr473p", + "status": 3, + "tokens": "37175356106", + "delegator_shares": "37175356106.000000000000000000", + "description": { + "moniker": "oedtWfExZY", + "identity": "taFwTdIwwz", + "website": "oGBHKapVuy", + "security_contact": "hnggEiQcYu", + "details": "qOFIRfzDGP" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083784124252551147", + "max_rate": "0.650000000000000000", + "max_change_rate": "0.550897578676987786" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dsktaxw5", + "status": 3, + "tokens": "55634424696", + "delegator_shares": "55634424696.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.016380613584719475", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.310000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "consensus_pubkey": "cosmosvalconspub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz28vhtm", + "status": 3, + "tokens": "20453193314", + "delegator_shares": "20453193314.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.528106308050967540" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqehts4m", + "status": 3, + "tokens": "52558464763", + "delegator_shares": "52558464763.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.128525196978986815", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.100900376719373255" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru72w0xm", + "status": 3, + "tokens": "18560827275", + "delegator_shares": "18560827275.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.100218404029226728", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.881639682871578638" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00qxpqlwy0p6y9tl23yu7fpu55lhznxa3hrhvsuma6h7lu4c3ekks4wvua", + "status": 3, + "tokens": "22083357722", + "delegator_shares": "22083357722.000000000000000000", + "description": { + "moniker": "LvOuePvVwo", + "identity": "vfegdQlOfT", + "website": "mYvkvMZuDp", + "security_contact": "cfrddDLOlu", + "details": "yHfcxdGyEO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.122593865256918850", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.840000000000000000" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxkm9kvvp", + "status": 3, + "tokens": "26763354026", + "delegator_shares": "26763354026.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.027810962515737967", + "max_rate": "0.070000000000000000", + "max_change_rate": "0.034717076557320762" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdpwvxyz0d0thr5hw72lswav4tdfuwkgfqjdjkaws99y4dw5fzncg487kz6", + "status": 3, + "tokens": "23838299895", + "delegator_shares": "23838299895.000000000000000000", + "description": { + "moniker": "anqFIENyYy", + "identity": "LYtCTmovif", + "website": "nDcnuLjZla", + "security_contact": "KhBXWuJORy", + "details": "rcnhuNfFoO" + }, + "unbonding_height": "13", + "unbonding_time": "9936-01-01T19:46:26Z", + "commission": { + "commission_rates": { + "rate": "0.489033782311246085", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.501117175906227815" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvykaseh7", + "status": 3, + "tokens": "68955304480", + "delegator_shares": "68955304480.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.208925360976246176", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.463634503057540350" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peggwy7x5", + "status": 3, + "tokens": "49844884060", + "delegator_shares": "49844884060.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.338644152469426553", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.069153802725768656" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxz2ead4", + "status": 3, + "tokens": "19233426986", + "delegator_shares": "19233426986.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.373154376676147691", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wjfqd63", + "status": 3, + "tokens": "25961659072", + "delegator_shares": "25961659072.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.068613373696134985", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.073351676068018235" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7ul2hc3", + "status": 3, + "tokens": "33320443806", + "delegator_shares": "33320443806.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118849597906926326", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.228258187539755185" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7whvstg", + "status": 3, + "tokens": "37445650387", + "delegator_shares": "37445650387.000000000000000000", + "description": { + "moniker": "cVUXvMdRgs", + "identity": "AHkjmtOkYK", + "website": "KLRPQOyDoY", + "security_contact": "VHwCrfhVnI", + "details": "qdFVvUucvR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.182731553781057822", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.045316794895420248" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqde6g57cex9ff650ku6dqdqtfulfnzkacecf6k436xl0dd07zglxx5659h9", + "status": 3, + "tokens": "27718687960", + "delegator_shares": "27718687960.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.905848795661145449", + "max_rate": "0.950000000000000000", + "max_change_rate": "0.476775855507110704" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy7220f9ul3", + "status": 3, + "tokens": "33772482275", + "delegator_shares": "33772482275.000000000000000000", + "description": { + "moniker": "znFMdpLOQw", + "identity": "LEMEnpcxqp", + "website": "TjKmeKjDGm", + "security_contact": "ZOXcBhlDyq", + "details": "WpmmnksSqL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.834910862331446014", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cuyxrn7n", + "status": 3, + "tokens": "24587685968", + "delegator_shares": "24587685968.000000000000000000", + "description": { + "moniker": "tlYEYvdvKp", + "identity": "fQFtYLRSZA", + "website": "ecuAofwdaj", + "security_contact": "gwsuBeDyJU", + "details": "gELFJGuwPs" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.499259642246008210", + "max_rate": "0.560000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jet5tg3", + "status": 3, + "tokens": "62232444428", + "delegator_shares": "62232444428.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.153116543667039838", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.230000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yfudg7m", + "status": 3, + "tokens": "25948607110", + "delegator_shares": "25948607110.000000000000000000", + "description": { + "moniker": "IssGiFwTJv", + "identity": "VgTaqmOLtN", + "website": "BpkICmEqwF", + "security_contact": "qmrIWxiWft", + "details": "sLtbcsMFgA" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.136694009459855954", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.056116480834729575" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4c8wkdlg", + "status": 3, + "tokens": "18426946099", + "delegator_shares": "18426946099.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.469814499540087620", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.960000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvquc4jf3", + "status": 3, + "tokens": "16774945156", + "delegator_shares": "16774945156.000000000000000000", + "description": { + "moniker": "hZvyDgtWxX", + "identity": "TPMmELNQYL", + "website": "YxTdbJnobM", + "security_contact": "ZURHxVMZoL", + "details": "zVjWraUVyE" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.258972799025106506", + "max_rate": "0.910000000000000000", + "max_change_rate": "0.304259315697044502" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprs83zeag", + "status": 3, + "tokens": "32156167120", + "delegator_shares": "32156167120.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.351977697440288211" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvly6j0pyezy88s9lnat6taglylzq03vvsvyw4uy2tv3vcl3200ej0nev4k", + "status": 3, + "tokens": "16811362128", + "delegator_shares": "16811362128.000000000000000000", + "description": { + "moniker": "lasYiVeRDA", + "identity": "TFiGxJBNUs", + "website": "xswbDClAxs", + "security_contact": "HYUurzqzcC", + "details": "EVSfzEFSuo" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.036542719943188247", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.304756516958654494" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66dra0w3", + "status": 3, + "tokens": "19540440011", + "delegator_shares": "19540440011.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.065303820000927065", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.134868108685582589" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afqga9sv8", + "status": 3, + "tokens": "33258307031", + "delegator_shares": "33258307031.000000000000000000", + "description": { + "moniker": "uVtPIVoLeB", + "identity": "UQUjtBkUkU", + "website": "lrfjDXnSyH", + "security_contact": "tPWaAehpKA", + "details": "YCcmQgJRnO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.859185512301348293", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.915098787337318307" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrq06r4ck", + "status": 3, + "tokens": "41543247193", + "delegator_shares": "41543247193.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.119695944592116460" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4vjajc6x", + "status": 3, + "tokens": "61843733534", + "delegator_shares": "61843733534.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.437478542817284441", + "max_rate": "0.530000000000000000", + "max_change_rate": "0.308410375933996023" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvghhzrgz", + "status": 3, + "tokens": "36037299066", + "delegator_shares": "36037299066.000000000000000000", + "description": { + "moniker": "rUZvoFLmub", + "identity": "dQGYIJXPFq", + "website": "ZPoXnJmgzU", + "security_contact": "MdbwPJFNHC", + "details": "NdoQBlpUhN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.670000000000000000", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.629855974067904060" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz4luxgn", + "status": 3, + "tokens": "33206633235", + "delegator_shares": "33206633235.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.229284159886860129", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.212917450108859841" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw24c76ax", + "status": 3, + "tokens": "27567655084", + "delegator_shares": "27567655084.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.216560651737526756", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.026445047137608599" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qpu7x5c", + "status": 3, + "tokens": "27671960609", + "delegator_shares": "27671960609.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.077841535313299819", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.054979434313866047" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2wcjjal", + "status": 3, + "tokens": "25069342080", + "delegator_shares": "25069342080.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.249161816461641720", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.693944288516379645" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akutfqm7", + "status": 3, + "tokens": "55737096951", + "delegator_shares": "55737096951.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.498362112747574396", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.645641814068879323" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693hazjkkehy", + "status": 3, + "tokens": "33054734644", + "delegator_shares": "33054734644.000000000000000000", + "description": { + "moniker": "mUQFKtnPLD", + "identity": "xsxoaAIVkh", + "website": "EBARfZhhON", + "security_contact": "GynbBFtcRq", + "details": "RftDCeMUPi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.123876475355091478", + "max_rate": "0.860000000000000000", + "max_change_rate": "0.141162753552435345" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v30nmws", + "status": 3, + "tokens": "78601464028", + "delegator_shares": "78601464028.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083731202536014652", + "max_rate": "0.860000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9ykjrzn93", + "status": 3, + "tokens": "18090212819", + "delegator_shares": "18090212819.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.081582427988342735", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.086390137368972014" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06my86wxz2", + "status": 3, + "tokens": "33968139195", + "delegator_shares": "33968139195.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.247483015769197525", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.837420192496215212" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtufvzu2k2knnce8l9jcwuntray9m8hnlal8a4jkcjazppr5p7pyus6emm0", + "status": 3, + "tokens": "19857350032", + "delegator_shares": "19857350032.000000000000000000", + "description": { + "moniker": "PfGefIRkUQ", + "identity": "PQNdBVtoxj", + "website": "nyfnvHyjNl", + "security_contact": "ewMiIvfvCh", + "details": "ttKmCVgWXS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.239149115387739677", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.173620767408899960" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv9w0yqrekktvu6gd7ak8u7wkwqj47llgrtl2vp2gtdvfafwatyysclj3nm", + "status": 3, + "tokens": "23726914937", + "delegator_shares": "23726914937.000000000000000000", + "description": {}, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.522454157166611225", + "max_rate": "0.820000000000000000", + "max_change_rate": "0.329662780053528069" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2crvswax", + "status": 3, + "tokens": "16516288319", + "delegator_shares": "16516288319.000000000000000000", + "description": { + "moniker": "kVNZIBYAxD", + "identity": "ChbsAFHanI", + "website": "SvHMthzzzB", + "security_contact": "cMJXUgGCfx", + "details": "PWsrYNKuPZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.540000000000000000", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.491525012965837080" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2kj4krx", + "status": 3, + "tokens": "45010236382", + "delegator_shares": "45010236382.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.095070637134115497" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveesw5rr6m", + "status": 3, + "tokens": "54768547781", + "delegator_shares": "54768547781.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.328146514360581742", + "max_rate": "0.810000000000000000", + "max_change_rate": "0.166428198995593213" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68yqxsxnt", + "status": 3, + "tokens": "25326342688", + "delegator_shares": "25326342688.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.785486462764506620", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.356882054361860100" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzlcd6kj", + "status": 3, + "tokens": "67804970220", + "delegator_shares": "67804970220.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.264013069771684883" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4v8fm8e8", + "status": 3, + "tokens": "41964454098", + "delegator_shares": "41964454098.000000000000000000", + "description": { + "moniker": "LDEzyylLGV", + "identity": "NaLpENvFnX", + "website": "ooOcvgIJwr", + "security_contact": "aQaxAlCyFx", + "details": "CxEFcmLmkI" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.099339754970547702", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.111217397607280422" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k907nvf", + "status": 3, + "tokens": "28676349495", + "delegator_shares": "28676349495.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.609184993023386704", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.699887495531371188" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "consensus_pubkey": "cosmosvalconspub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjtszrqs", + "status": 3, + "tokens": "34574952843", + "delegator_shares": "34574952843.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.810000000000000000", + "max_rate": "0.810000000000000000", + "max_change_rate": "0.810000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "consensus_pubkey": "cosmosvalconspub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku73m9m0", + "status": 3, + "tokens": "16992076248", + "delegator_shares": "16992076248.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.406968367525101581", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.487609794856186092" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfcdg0aax", + "status": 3, + "tokens": "16967510024", + "delegator_shares": "16967510024.000000000000000000", + "description": { + "moniker": "YKKhjZGayb", + "identity": "IvgiPDjmYA", + "website": "gScrUtVzvh", + "security_contact": "kGHySpHXgu", + "details": "IyuehlcoPM" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.093407705950029411", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.187465926844434813" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7zgmra8", + "status": 3, + "tokens": "26261718579", + "delegator_shares": "26261718579.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.210000000000000000", + "max_change_rate": "0.067309904771533509" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqnavslf", + "status": 3, + "tokens": "46127605035", + "delegator_shares": "46127605035.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.895728278286976959", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.140752130806369269" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jyyn3gu", + "status": 3, + "tokens": "22487156484", + "delegator_shares": "22487156484.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.008115100503323252", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yagkfrr", + "status": 3, + "tokens": "39560123415", + "delegator_shares": "39560123415.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.060188716749386269", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.350000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "consensus_pubkey": "cosmosvalconspub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kwmez9k", + "status": 3, + "tokens": "16420725988", + "delegator_shares": "16420725988.000000000000000000", + "description": { + "moniker": "LVfceOUKZE", + "identity": "ZyVUuaCAJZ", + "website": "rliAdTPvEK", + "security_contact": "hVtZPHOsKh", + "details": "QjmMKruCba" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.036920301680485403" + }, + "update_time": "9936-01-01T16:55:11Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq77rpqn", + "status": 3, + "tokens": "22691569600", + "delegator_shares": "22691569600.000000000000000000", + "description": { + "moniker": "BFoqLaJLDn", + "identity": "weLorPCgTe", + "website": "oyhVcpSOLq", + "security_contact": "hdnvhDJTDC", + "details": "SAZISvvmwB" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.160832184115355939", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xw03emk4", + "status": 3, + "tokens": "44313010729", + "delegator_shares": "44313010729.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083856723472306849", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.569378562223247850" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6yp7zp3n", + "status": 3, + "tokens": "25164533156", + "delegator_shares": "25164533156.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.330000000000000000", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.314039829028852779" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvn899z9u9a7h28682292n9y77yr6yuyrg2xvg8eaammccqfuc9e5jp63vn", + "status": 3, + "tokens": "16985369823", + "delegator_shares": "16985369823.000000000000000000", + "description": { + "moniker": "oVMoJSrGgV", + "identity": "ydZuwvoyLe", + "website": "EdyJLNhNGZ", + "security_contact": "QauDavDNuL", + "details": "CVkbnFlumN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.276325858271560152", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.108166159043578444" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwshp63n", + "status": 3, + "tokens": "25367511082", + "delegator_shares": "25367511082.000000000000000000", + "description": { + "moniker": "KODmaZYfBO", + "identity": "dQoWoZcHpD", + "website": "QRjjuYKVNR", + "security_contact": "BHWzdORGfc", + "details": "dZGTxQmqIN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003392332242825811", + "max_rate": "0.060000000000000000", + "max_change_rate": "0.027187395396712775" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqv0lje47", + "status": 3, + "tokens": "54901950842", + "delegator_shares": "54901950842.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.193375046872051394", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.161750559623523660" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc9m7uvt", + "status": 3, + "tokens": "15374405822", + "delegator_shares": "15374405820.680335249007925874", + "description": { + "moniker": "eomlzRaIRN", + "identity": "PaBTVBXpcj", + "website": "frMwzGwrdS", + "security_contact": "XwCgZGftYO", + "details": "oynChhccDw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.014913519812752309", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.219118316904950121" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7dsh8mr", + "status": 3, + "tokens": "31376033263", + "delegator_shares": "31376033263.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.074914975922116628" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axhh8p8f", + "status": 3, + "tokens": "49683234188", + "delegator_shares": "49683234188.000000000000000000", + "description": { + "moniker": "MJAduJwrkS", + "identity": "YpKMJsMpdh", + "website": "rmUXbHIGjh", + "security_contact": "KxyJSeDEJS", + "details": "gQmDpfNyLZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.637063248045666486", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.100218674012239339" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmkm3zs42", + "status": 3, + "tokens": "34289428306", + "delegator_shares": "34289428306.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.026475742223507385", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.008016543161851368" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw3fj2ga", + "status": 3, + "tokens": "29885998584", + "delegator_shares": "29885998584.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.208832068199199828", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.835848953294536000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv7nw49k6j8sg6379dy0lemj7vee2el49mt5rmypwujwk6lua8duyrr8zrn", + "status": 3, + "tokens": "21181468286", + "delegator_shares": "21181468286.000000000000000000", + "description": { + "moniker": "TgLltHAWtO", + "identity": "zpriAAvZuw", + "website": "pWVJnIqFBY", + "security_contact": "TyuWOjmMFF", + "details": "CbbpwkidBS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.237822850366335221", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.134613352727411591" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2vncgld", + "status": 3, + "tokens": "39430946332", + "delegator_shares": "39430946332.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.400358972669819604", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.343431675789315867" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrywn9e6w", + "status": 3, + "tokens": "32328037984", + "delegator_shares": "32328037984.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.039339062684741866", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.021256256594527078" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus2udpwh", + "status": 3, + "tokens": "15813863385", + "delegator_shares": "15813863385.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.543747468021249371", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.392045382869085556" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwujx3ap2", + "status": 3, + "tokens": "25957780472", + "delegator_shares": "25957780472.000000000000000000", + "description": { + "moniker": "hoLpIoNUFo", + "identity": "LCpoujNFyW", + "website": "AOTlTXjPul", + "security_contact": "elgNvDzEfH", + "details": "hwOSWkTDMH" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.347272379813626146", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9ugfdlq9", + "status": 3, + "tokens": "45284218868", + "delegator_shares": "45284218868.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.340626334815374555", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkxmnmkq", + "status": 3, + "tokens": "44505127913", + "delegator_shares": "44505127913.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.605944631117636209", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.639343774657574630" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqk8ct27q", + "status": 3, + "tokens": "22456561633", + "delegator_shares": "22456561633.000000000000000000", + "description": { + "moniker": "DPTpRIdXgW", + "identity": "qysDMlMxpi", + "website": "xWbmLVlZvB", + "security_contact": "QtpKTducMv", + "details": "UWYfFdNOxg" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.057271144965717909", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.075138495309274904" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd7u4d80m4e6sfhyzj84k6y34v30g9cstzx7cmrazvxdtfe40urcvran9t8", + "status": 3, + "tokens": "45811135531", + "delegator_shares": "45811135531.000000000000000000", + "description": { + "moniker": "zcPImZiDZD", + "identity": "zkcTihefFl", + "website": "mIjAaWRNkf", + "security_contact": "gTafXNexkI", + "details": "tJJDPwaiAf" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.079222020883406460", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.311112908017536993" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggxauhp0sadc5npdva6f492f3n4a76fldyt3lca6lk36685s624ucakcrh", + "status": 3, + "tokens": "24610359351", + "delegator_shares": "24610359351.000000000000000000", + "description": { + "moniker": "dLwrEevbbD", + "identity": "ubSqqBoPRs", + "website": "MNuXpKVOXc", + "security_contact": "lNXuEDYSJp", + "details": "CvXURllZqF" + }, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.175531415042829217" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqwclfkt", + "status": 3, + "tokens": "34459325260", + "delegator_shares": "34459325260.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.033986343509044787", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.090000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7t4673v", + "status": 3, + "tokens": "55948291091", + "delegator_shares": "55948291091.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.440048441195653325", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.180789237411591672" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5r4xrdd", + "status": 3, + "tokens": "15675831119", + "delegator_shares": "15675831119.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czwem9y4", + "status": 3, + "tokens": "37181480786", + "delegator_shares": "37181480786.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.177753292751501209", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.323174353688819429" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxe7jutz", + "status": 3, + "tokens": "24261774404", + "delegator_shares": "24261774404.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.017452646416466178", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.020000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4svau85d", + "status": 3, + "tokens": "31770155824", + "delegator_shares": "31770155824.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.138735148670316454", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.286634953103815529" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf0u600sgl3zdn3uh4jd6jmw6fc0jc40r0l2crvz3sla3f8d32flghwtxaq", + "status": 3, + "tokens": "37602205867", + "delegator_shares": "37602205867.000000000000000000", + "description": { + "moniker": "BUZauhlQrt", + "identity": "yuIKzyGzQS", + "website": "fDSmxAmazc", + "security_contact": "jVDWgXPhkM", + "details": "LBFAwsUoyi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.244517333363622892", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.153245122134586562" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzue70ade", + "status": 3, + "tokens": "37676305948", + "delegator_shares": "37676305948.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.260000000000000000", + "max_rate": "0.260000000000000000", + "max_change_rate": "0.239035612898447459" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj2sy3f5", + "status": 3, + "tokens": "26850762657", + "delegator_shares": "26850762657.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.420000000000000000", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.295551090875771737" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvhet24yk50y4m60mceffquewu9p4enwrgcum0csceuull7a59u6567nn0v", + "status": 3, + "tokens": "20405570669", + "delegator_shares": "20405570669.000000000000000000", + "description": { + "moniker": "ZeprycSOnc", + "identity": "ZcHuivhMFq", + "website": "hCsVpTWmaL", + "security_contact": "AIKsDuUCDR", + "details": "EgpxVbAOaK" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.054000324644638628", + "max_rate": "0.380000000000000000", + "max_change_rate": "0.120973196882786975" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6k07476", + "status": 3, + "tokens": "25102040344", + "delegator_shares": "25102040344.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.599184934718890393", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgh9lxfuk4amzsp0w28t8dkdwf2xk8yrxjj7xz0lnmzs2lyahrdz2f2yy35", + "status": 3, + "tokens": "17609505538", + "delegator_shares": "17609505538.000000000000000000", + "description": { + "moniker": "yAwjGcNsZH", + "identity": "STCkyPeJjc", + "website": "yvmEPebWkk", + "security_contact": "ZficJLXKJM", + "details": "qAWHtJiitW" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.690000000000000000", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.509977105992119960" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "consensus_pubkey": "cosmosvalconspub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjycl58l", + "status": 3, + "tokens": "41119826715", + "delegator_shares": "41119826715.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.025162698699691548" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75fh3auv", + "status": 3, + "tokens": "19565632897", + "delegator_shares": "19565632897.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.579061375935434182", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwskjpjy", + "status": 3, + "tokens": "44648874284", + "delegator_shares": "44648874284.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.258140043497759741", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.447039357737510640" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg57gy4ef", + "status": 3, + "tokens": "34209671267", + "delegator_shares": "34209671267.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.480455308806333346", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55hrcqtd", + "status": 3, + "tokens": "25069342080", + "delegator_shares": "25069342080.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.409558857679769509", + "max_rate": "0.930000000000000000", + "max_change_rate": "0.610998804526507722" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0sgshv9mf8qy7ff303mqqv5zppu3q4mcwrnheue8d3kq0ytyynkxlak2ae", + "status": 3, + "tokens": "28980476016", + "delegator_shares": "28980476016.000000000000000000", + "description": { + "moniker": "hVYOUraqpo", + "identity": "XRliNUdYgt", + "website": "FYzwRNeFsW", + "security_contact": "AYYtrdbBmx", + "details": "NaWAwUYhir" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxd2wcms", + "status": 3, + "tokens": "27742737411", + "delegator_shares": "27742737411.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.870000000000000000", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.402061609548054151" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2x30aum6t8lauwqh72szktjx6fmgf5ux7vcs38uukp9a5h287wawhv5mfv", + "status": 3, + "tokens": "17377751306", + "delegator_shares": "17377751306.000000000000000000", + "description": { + "moniker": "SslqJkEqrN", + "identity": "qMdXPqvbCt", + "website": "HDwwjWlugU", + "security_contact": "LzWMObthwF", + "details": "zlyoRqwOQS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.498765541593724538", + "max_rate": "0.530000000000000000", + "max_change_rate": "0.156108348646223859" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3lu0qw8kj", + "status": 3, + "tokens": "23737653202", + "delegator_shares": "23737653202.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.450461328836777178", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.254665389885134513" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcf30j9c", + "status": 3, + "tokens": "74690344989", + "delegator_shares": "74690344989.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.882630947578979215", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.960000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr2mqfkju", + "status": 3, + "tokens": "27874325464", + "delegator_shares": "27874325464.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.459241580368376871", + "max_rate": "0.490000000000000000", + "max_change_rate": "0.448990769658695281" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngklt9fqt", + "status": 3, + "tokens": "67833673918", + "delegator_shares": "67833673918.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.280411773058535090", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.009358685901125498" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdq8fheeu", + "status": 3, + "tokens": "25446232136", + "delegator_shares": "25446232136.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.073669961838812257", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.338443455873010612" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdjuv3ql5rv5njym62quduw7554as4aa8seufp7f4zv6q28tds2e23v4cv5", + "status": 3, + "tokens": "35741739231", + "delegator_shares": "35741739231.000000000000000000", + "description": { + "moniker": "MoJgIrbTvT", + "identity": "rTfyDjhPlV", + "website": "fXpRItnlwS", + "security_contact": "tIlMCZPLDi", + "details": "QoSUrnFXNb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.037606710200997532", + "max_rate": "0.610000000000000000", + "max_change_rate": "0.432717335122536998" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwvhpfht", + "status": 3, + "tokens": "19637280062", + "delegator_shares": "19637280062.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118259925415637398", + "max_rate": "0.220000000000000000", + "max_change_rate": "0.176572964585642890" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwaazwez", + "status": 3, + "tokens": "56856814851", + "delegator_shares": "56856814851.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.093189165744722643", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.044880981942823250" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyvxmu04", + "status": 3, + "tokens": "36122807193", + "delegator_shares": "36122807193.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.414145633705698803", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd2gmrd8aux64z50e58tu00n3yjunvqduf4xv3g3p6j3wpuxddex59mpcfe", + "status": 3, + "tokens": "16807158123", + "delegator_shares": "16807158123.000000000000000000", + "description": { + "moniker": "ZHKMxyLBmy", + "identity": "EwvvJnavFX", + "website": "DHXlVcQLfr", + "security_contact": "cqkJGwinbb", + "details": "CwxLKqsDci" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.054776212220005616", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.012318363733558931" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2p3sa8dkvz36pz6nusjdhm9aqlnrrldrszzuqd5qy7ssqztn99ggqpcdlz", + "status": 3, + "tokens": "48540826744", + "delegator_shares": "48540826744.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003549575739989554", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.001119527935415439" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycjhwrn7", + "status": 3, + "tokens": "29401856985", + "delegator_shares": "29401856985.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.243341366114153903", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.628404054381210058" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdaa2szanfjwhzucqfj0ct7ljhc3kew8am3h8sr8wqzlnh8df06g5th460y", + "status": 3, + "tokens": "24697024268", + "delegator_shares": "24697024268.000000000000000000", + "description": { + "moniker": "XYWZXrqRDE", + "identity": "MFgElwSSlb", + "website": "ZPGkarWAml", + "security_contact": "dFzxEZXTfo", + "details": "HRGbXKBEeq" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.550000000000000000", + "max_change_rate": "0.376530136432859216" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w4r0vhq", + "status": 3, + "tokens": "41494205421", + "delegator_shares": "41494205421.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.070000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgc0dahup", + "status": 3, + "tokens": "54450506134", + "delegator_shares": "54450506134.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.109747630034489371", + "max_rate": "0.970000000000000000", + "max_change_rate": "0.461346401411912639" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkn6paax", + "status": 3, + "tokens": "23703504292", + "delegator_shares": "23703504292.000000000000000000", + "description": { + "moniker": "eXfwGKuzGb", + "identity": "dYpMrjwrPA", + "website": "DzaFOsditE", + "security_contact": "GuNLPoNZsM", + "details": "iALsKeROvR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.087538799057934086", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.859363741701174499" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyt542en", + "status": 3, + "tokens": "69725274862", + "delegator_shares": "69725274862.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.077835183941357357", + "max_rate": "0.630000000000000000", + "max_change_rate": "0.287966636331923139" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwfq28wcw9gn3mynr4pjdpd5hhert9hheg8qus862ymrt5ex6j75jlkuhe3", + "status": 3, + "tokens": "21764467799", + "delegator_shares": "21764467799.000000000000000000", + "description": { + "moniker": "ObWwGUpRaY", + "identity": "BCfhwnVexY", + "website": "SBehiPUtRR", + "security_contact": "jMhyvuyFaP", + "details": "LHYAZFxdaS" + }, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.075332177620667120", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.039077923270826524" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsrp7s99", + "status": 3, + "tokens": "25229713771", + "delegator_shares": "25229713771.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.420000000000000000", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.006473324874363207" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd5jsj53j7m0umzvh90dwanxhfxmpydhfazmsz978v9yuh05q0kxcyqtdla", + "status": 3, + "tokens": "16747268503", + "delegator_shares": "16747268503.000000000000000000", + "description": { + "moniker": "OuShqctNnC", + "identity": "MfQbnbeXdv", + "website": "OfOpteXCQn", + "security_contact": "qaSLhJmnUG", + "details": "vIuRzAnYuu" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.589668369513377579", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.640000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge726q0dwq", + "status": 3, + "tokens": "56914095343", + "delegator_shares": "56914095343.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.561558403350280399", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.088588598076790894" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0us7fav4", + "status": 3, + "tokens": "53587404091", + "delegator_shares": "53587404091.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.148502470554898869", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.005661642347781868" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw32mxlzzzmmpks775cgclcsmypqhhz7765v03wnjf8cn4hsrw67tq2l8n", + "status": 3, + "tokens": "20301516153", + "delegator_shares": "20301516153.000000000000000000", + "description": { + "moniker": "ibdjDFXkFg", + "identity": "BhaqDbDPwH", + "website": "KoHplbnTSd", + "security_contact": "zgJBSepZRt", + "details": "anTLerUmWY" + }, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.092279263137073204", + "max_rate": "0.130000000000000000", + "max_change_rate": "0.062347977318301413" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4umtaftt", + "status": 3, + "tokens": "23438430919", + "delegator_shares": "23438430919.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.065104244001935780", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.087973256413395308" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wu8lrdvr", + "status": 3, + "tokens": "23476663612", + "delegator_shares": "23476663612.000000000000000000", + "description": { + "moniker": "qNlNvDKQWh", + "identity": "PdEEmVXzOP", + "website": "jyQRsxutdI", + "security_contact": "hTNdvfWkVQ", + "details": "gPNrXPrkeL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.830000000000000000", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.679717803083962746" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7pax9cuqs5vjjvhpmcgvy5dkqrrtrg6336c3xhyrchtegy2m387ccs037", + "status": 3, + "tokens": "19815525788", + "delegator_shares": "19815525788.000000000000000000", + "description": { + "moniker": "sJKzLUYWBq", + "identity": "ZzbWnFqPTq", + "website": "dlevXyAGdk", + "security_contact": "bnQNzwNRYP", + "details": "PaxiDbFCJj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.291627565410574418", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.017987067010819344" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wel7d3l", + "status": 3, + "tokens": "25456865344", + "delegator_shares": "25456865344.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.293848609442759777", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.580000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6u59lzkg", + "status": 3, + "tokens": "44085124225", + "delegator_shares": "44085124225.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.045106108515206331", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.610987430943531252" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xvdql9k", + "status": 3, + "tokens": "25311353934", + "delegator_shares": "25311353934.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.324580145668396309", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.480000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujgucg2ktdn", + "status": 3, + "tokens": "32745806516", + "delegator_shares": "32745806516.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.322505571100731689", + "max_rate": "0.520000000000000000", + "max_change_rate": "0.183472725952677048" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592jkkxzm", + "status": 3, + "tokens": "21858111883", + "delegator_shares": "21858111883.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.799310131872627643", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.706235617003159879" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxtyq8dz", + "status": 3, + "tokens": "28684472849", + "delegator_shares": "28684472849.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.174404138163737710", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.360000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + } + ] + }, + { + "header": { + "version": {}, + "chain_id": "simulation-app", + "height": "50", + "time": "9936-01-04T17:25:47Z", + "last_block_id": { + "parts_header": {} + }, + "proposer_address": "jgjZuluGDLAuRHWL1Yy8d/evPjs=" + }, + "valset": [ + { + "operator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels7tpscy", + "status": 3, + "tokens": "24767745772", + "delegator_shares": "24767745772.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.064962829627143450", + "max_rate": "0.700000000000000000", + "max_change_rate": "0.524524837966075502" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xt2s2vh", + "status": 3, + "tokens": "40149298125", + "delegator_shares": "40149298125.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.020987080088521851", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.079654399773437862" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk7tt4rl", + "status": 3, + "tokens": "33873720903", + "delegator_shares": "33873720903.000000000000000000", + "description": { + "moniker": "mLoNnmWUiV", + "identity": "RHiUhLQQnZ", + "website": "GdVEOYibSd", + "security_contact": "DcfUpyGSpE", + "details": "kaQgULDDFV" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.793635545567707656", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.546926599085395557" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfkykt89x2wmxt2w74v340hwp8azwyzswzgxzmcv46995zwggpu66ans7kn", + "status": 3, + "tokens": "49524189675", + "delegator_shares": "49524189675.000000000000000000", + "description": { + "moniker": "qorkgLHbbW", + "identity": "vVsXuupmaH", + "website": "GASCHEJsbz", + "security_contact": "KEcXQQooNh", + "details": "UlGvDMHBgm" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150351690116871266", + "max_rate": "0.470000000000000000", + "max_change_rate": "0.232118363435586291" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcrkzkl0", + "status": 3, + "tokens": "76742997299", + "delegator_shares": "76742997299.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.159853619317053801", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.178173481628386356" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0yv2h8z80vtfttsewrwe2v83haaceax7q3ey95uaeqj8lstf7l674zn3ut", + "status": 3, + "tokens": "16016194501", + "delegator_shares": "16016194501.000000000000000000", + "description": { + "moniker": "WVhrVMjLnZ", + "identity": "QiIQjemxtv", + "website": "KCKlbRarYk", + "security_contact": "AwimEeOMDq", + "details": "omCiVdOfZS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.636807270475032336", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.762928812525012131" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghknhrvft", + "status": 3, + "tokens": "32584502965", + "delegator_shares": "32584502965.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.063963134401067102" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgt7tyq6", + "status": 3, + "tokens": "15545552914", + "delegator_shares": "15545552914.000000000000000000", + "description": { + "moniker": "VaOLitHrfh", + "identity": "zYkbJeTdPC", + "website": "RWLWpQBLTs", + "security_contact": "EEFOrnsvml", + "details": "xRXuWfcvoz" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.209346043397093808", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.261491014079542938" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpvkknmf7", + "status": 3, + "tokens": "35273490053", + "delegator_shares": "35273490053.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.412168984856446389", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.601152598273329028" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvw0g93n8", + "status": 3, + "tokens": "24353363633", + "delegator_shares": "24353363633.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.140843713075627976", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.124247346623493378" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtxrkpudghuhgsu0he7ntk7q0asqa5ax23y7rnn5mfjr2d68z4emsrwqssp", + "status": 3, + "tokens": "44979344173", + "delegator_shares": "44979344173.000000000000000000", + "description": { + "moniker": "eJECwiPlqs", + "identity": "TywZsaZwgH", + "website": "jtFVQJUofX", + "security_contact": "fstanspUpc", + "details": "RQddrwMsIR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.005369299901591159", + "max_rate": "0.030000000000000000", + "max_change_rate": "0.010979308887356502" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwz2zelc", + "status": 3, + "tokens": "24972834479", + "delegator_shares": "24972834479.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118883162683785924", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.582076368438090700" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q205udc4", + "status": 3, + "tokens": "37286335725", + "delegator_shares": "37286335725.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.150000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.137121313165408722" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zycdvvrg7", + "status": 3, + "tokens": "26109827309", + "delegator_shares": "26109827309.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.272379182115041576" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", + "consensus_pubkey": "cosmosvalconspub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwlhqscf", + "status": 3, + "tokens": "25204407264", + "delegator_shares": "25204407264.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.276804190595109972", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.303611347820460701" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2u3gzal", + "status": 3, + "tokens": "23014258552", + "delegator_shares": "23014258552.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289943655120962524", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.271265684659427360" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgh4tj7q", + "status": 3, + "tokens": "49505425616", + "delegator_shares": "49505425616.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.519126528788995280", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw55ftmtn", + "status": 3, + "tokens": "52891997390", + "delegator_shares": "52891997390.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.006443603339396517", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.110565720532816181" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavc40dh4", + "status": 3, + "tokens": "69365122054", + "delegator_shares": "69365122054.000000000000000000", + "description": { + "moniker": "IoqkplxtIQ", + "identity": "SYtEYnqVjz", + "website": "cbrMdhVrVp", + "security_contact": "eWitXxyhJZ", + "details": "FCojJQQFCQ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.745132980800690980", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.321606633967630124" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tugphy2d", + "status": 3, + "tokens": "17054284690", + "delegator_shares": "17054284690.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.602634897210355218", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.136597759514787421" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jztkylp", + "status": 3, + "tokens": "55080258715", + "delegator_shares": "55080258715.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.052047960532670175", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgrwz3gl", + "status": 3, + "tokens": "17768682341", + "delegator_shares": "17768682341.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.141929485726276362" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yr97z8g", + "status": 3, + "tokens": "22598538029", + "delegator_shares": "22598538029.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.335354744004515496", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.096800797786563611" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2zq3f3j", + "status": 3, + "tokens": "27149799034", + "delegator_shares": "27149799034.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.158969199652087770", + "max_rate": "0.220000000000000000", + "max_change_rate": "0.220000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", + "consensus_pubkey": "cosmosvalconspub1addwnpepq246sxc5kns0ym6st5wyf6mk0x2cayek9wngczyvgk8phxrat02cqh8w5p2", + "status": 3, + "tokens": "49314038732", + "delegator_shares": "49314038732.000000000000000000", + "description": { + "moniker": "caRBWwzxXd", + "identity": "BJSnkbfQjh", + "website": "ELsVPBoBHb", + "security_contact": "nZkoSMuzKV", + "details": "AuAKjeoitI" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.010525961964940541", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.045814731203367877" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jhhj4uv", + "status": 3, + "tokens": "26185707851", + "delegator_shares": "26185707851.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.568319127244896272", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.226261076338173049" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5u4v4q5", + "status": 3, + "tokens": "32785129607", + "delegator_shares": "32785129607.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.009044195385937429", + "max_rate": "0.010000000000000000", + "max_change_rate": "0.002281789765845776" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpqq8zx8p", + "status": 3, + "tokens": "33846192792", + "delegator_shares": "33846192792.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.094250378854551281", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.043420993012939508" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv79a2a0wcq9kr62m5yupvx82mlxwxw6hx7c8dyl4trf8k2w7vh3w5wlhy0", + "status": 3, + "tokens": "25066394767", + "delegator_shares": "25066394767.000000000000000000", + "description": { + "moniker": "liMRThtiLT", + "identity": "QPHsvzHnkx", + "website": "BytvAmppJT", + "security_contact": "iBgKxrOkqF", + "details": "RcELAgZeDN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.115126355797501393", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.289658857878369113" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfp9mvx6gjdezn2vfxn9jk7jm2urml0xyvt3yg64s03yzkfphrthsdy925d", + "status": 3, + "tokens": "25061237568", + "delegator_shares": "25061237568.000000000000000000", + "description": { + "moniker": "wmxxGOZTpL", + "identity": "azxfwYYUUt", + "website": "izxOUVhQSX", + "security_contact": "lRgXsoitme", + "details": "eebhMKbHXO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.578049895054733896", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.402405887034980654" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc255eyr9", + "status": 3, + "tokens": "76719658246", + "delegator_shares": "76719658246.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.321194785873117781", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.561602155526895676" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u43hapa", + "status": 3, + "tokens": "18750673243", + "delegator_shares": "18750673243.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.188948913118426394", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.274693773376656673" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvpup8kv2mmqajfs08aks8yu8kcuwd323y4f0wu9e3k5grynt0g6ule9mjg", + "status": 3, + "tokens": "24248574347", + "delegator_shares": "24248574347.000000000000000000", + "description": { + "moniker": "bsrCMyYTRM", + "identity": "cTWbJOIMRX", + "website": "EMzKHBarjX", + "security_contact": "spsTAIOECF", + "details": "fTrZtqJTUr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.455524678875180233", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-01T06:29:20Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d29fg079", + "status": 3, + "tokens": "82798702711", + "delegator_shares": "82798702711.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289674444273548704", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.060992257943659564" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgss8cv9u", + "status": 3, + "tokens": "26155915081", + "delegator_shares": "26155915081.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.333198345990187069", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.410926346802169727" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", + "consensus_pubkey": "cosmosvalconspub1addwnpepqghlm3r37c95q3p3wvr8fxw8mvvdtj3tvhgduhzgzh4238ynz6f06f0rjfd", + "status": 3, + "tokens": "32302576994", + "delegator_shares": "32302576994.000000000000000000", + "description": { + "moniker": "hjulbVDPpf", + "identity": "pRsBrwBRzq", + "website": "VjiSZKAfKB", + "security_contact": "UHZkwTciXO", + "details": "JTfVgehmsi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.311759176624756474" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwus66jdl", + "status": 3, + "tokens": "54108139534", + "delegator_shares": "54108139534.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22ep2k8n", + "status": 3, + "tokens": "69316998057", + "delegator_shares": "69316998057.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.624946300778690751", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.204995912261423056" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7ejhy28", + "status": 3, + "tokens": "27808118568", + "delegator_shares": "27808118568.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.067795278161998694", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.011309118617844055" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5kc0mzw", + "status": 3, + "tokens": "17750303222", + "delegator_shares": "17750303222.000000000000000000", + "description": { + "moniker": "uloyQQWkyI", + "identity": "gFyXSGlhKI", + "website": "ewFltsApZk", + "security_contact": "YGvOhkEKJw", + "details": "vIoOsfiLuj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.068730439287548849", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.118090772640391070" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw4vh38c7e44vpvszes4lcvjkz3ah25sja3jyj8a2jyfk44fn033xtu5ld3", + "status": 3, + "tokens": "22144783949", + "delegator_shares": "22144783949.000000000000000000", + "description": { + "moniker": "cJZANkQgEs", + "identity": "BMLCKDJfbU", + "website": "EvRCcPcNDz", + "security_contact": "wYcIjPQECa", + "details": "FTToLCGlSp" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.490000000000000000", + "max_rate": "0.490000000000000000", + "max_change_rate": "0.478812992279810912" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv0pnal4w8hydpq3vydqgjxmmxz7zg2g9lsj5vedvjq3pw6typfdcjfm5tc", + "status": 3, + "tokens": "16214844041", + "delegator_shares": "16214844041.000000000000000000", + "description": { + "moniker": "jKdcmnPYfC", + "identity": "exfUuYgqmd", + "website": "XdNCNZIBOf", + "security_contact": "hmiwPGchGt", + "details": "nUnBufZQah" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.330000000000000000", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.051583680374523519" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057uxwdfy", + "status": 3, + "tokens": "23352431465", + "delegator_shares": "23352431465.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.760000000000000000", + "max_rate": "0.760000000000000000", + "max_change_rate": "0.183753469845780730" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvy095yf8a7eknhlnwzkum0wt53njxxww60vte7qkutwczt534dwhaclpm", + "status": 3, + "tokens": "34693121909", + "delegator_shares": "34693121909.000000000000000000", + "description": { + "moniker": "RuzZVxWXdB", + "identity": "QjsgdqaNzA", + "website": "UtlkBZyIyQ", + "security_contact": "vnsfyiwxFP", + "details": "dOxLDmGKTb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.005447024365505786", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.005395717096845063" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef5gg2q6z", + "status": 3, + "tokens": "42958814024", + "delegator_shares": "42958814024.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.077000158168963029", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.197697608060710078" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwv7ukq0", + "status": 3, + "tokens": "21734647779", + "delegator_shares": "21734647779.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.460679550676466675", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.165088210560206816" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwc7h5wds8u3tspx3mwpfh5l3q3rv0t6ff33dt205v2zy2kxev9sykcs9uv", + "status": 3, + "tokens": "29256610441", + "delegator_shares": "29256610441.000000000000000000", + "description": { + "moniker": "iYUgQcrziE", + "identity": "hDYXNaKKIu", + "website": "FYsreoPnoD", + "security_contact": "FGAHzGKfjM", + "details": "gkHwWfssaE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.585764113115952818", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9936-01-04T11:36:07Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz4r8scm", + "status": 3, + "tokens": "65051132532", + "delegator_shares": "65051132532.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.041535797793389960", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.029250263820409753" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2cxeaw4", + "status": 3, + "tokens": "18897052265", + "delegator_shares": "18897052265.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.416117321788354038", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.139830256647094326" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazfcl7f9", + "status": 3, + "tokens": "27157083976", + "delegator_shares": "27157083976.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.170000000000000000", + "max_change_rate": "0.024288054259102348" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgxqjc3u3", + "status": 3, + "tokens": "45028692546", + "delegator_shares": "45028692546.000000000000000000", + "description": { + "moniker": "UeFBWJANuQ", + "identity": "gypzUiAlRd", + "website": "zZezcKCiKy", + "security_contact": "KSXTvslQOC", + "details": "qqNIBlVIYk" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.075610127679217055", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.290000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xwmrp7sq", + "status": 3, + "tokens": "35018830437", + "delegator_shares": "35018830437.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.740000000000000000", + "max_change_rate": "0.405901469124460870" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", + "consensus_pubkey": "cosmosvalconspub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc92g545rl", + "status": 3, + "tokens": "17547285969", + "delegator_shares": "17547285969.000000000000000000", + "description": {}, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.073548473514397047", + "max_rate": "0.440000000000000000", + "max_change_rate": "0.413655116572301617" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wyr7x83", + "status": 3, + "tokens": "25071600389", + "delegator_shares": "25071600389.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.280000000000000000", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.063599161373317498" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymswdv67m", + "status": 3, + "tokens": "27784307296", + "delegator_shares": "27784307296.000000000000000000", + "description": { + "moniker": "mjkYspzJbE", + "identity": "xWPMeIdPEi", + "website": "xtRPXfTiQB", + "security_contact": "sdKpqtdpNe", + "details": "MnLujfMpnW" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.100000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.072530327063185081" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslqg7mlcx", + "status": 3, + "tokens": "31634692393", + "delegator_shares": "31634692393.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.554757466700447989", + "max_rate": "0.820000000000000000", + "max_change_rate": "0.408903182457515462" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvlfyhyylne6t33wzse5vhjd3xxyrfkjfmdyvk3gq4rrdhe2e0ul2n637uw", + "status": 3, + "tokens": "25080486106", + "delegator_shares": "25080486106.000000000000000000", + "description": { + "moniker": "MCiuCZVGkF", + "identity": "YVlJRRVogl", + "website": "iBpLGvpPpo", + "security_contact": "bvXcaUSxzJ", + "details": "zsHdsXWXhJ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.012334216153398550" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v67hlsk", + "status": 3, + "tokens": "16236700229", + "delegator_shares": "16236700229.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.498536222135788025" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5l4jsmp", + "status": 3, + "tokens": "42927955154", + "delegator_shares": "42927955154.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.190381602916620701", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.303876600993529705" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g7drc35", + "status": 3, + "tokens": "36911230696", + "delegator_shares": "36911230696.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.194945225911581915", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.300000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcas8xka", + "status": 3, + "tokens": "39363181311", + "delegator_shares": "39363181311.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.028169322828760497", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.050000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcvjsxyz", + "status": 3, + "tokens": "27734813665", + "delegator_shares": "27734813665.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.015116864220436494", + "max_rate": "0.050000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd5nsxkua92z9eamd4hccf0pxeh3chye2475vcrwc22dpxj4lmkvuy950w7", + "status": 3, + "tokens": "27605610764", + "delegator_shares": "27605610764.000000000000000000", + "description": { + "moniker": "RLaOPuFvKx", + "identity": "LQfktbUgZN", + "website": "JiRhAUTjQG", + "security_contact": "LTGuZUEvcW", + "details": "QjLWSYAXxH" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskj3a67t", + "status": 3, + "tokens": "24423311847", + "delegator_shares": "24423311847.000000000000000000", + "description": { + "moniker": "OtyVVqWsup", + "identity": "EqaejuaTwX", + "website": "egvJRLAnYF", + "security_contact": "KTzlQLiomS", + "details": "ETXsigXuTY" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.372711230134865265", + "max_rate": "0.460000000000000000", + "max_change_rate": "0.056760418592473079" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjzxhelr", + "status": 3, + "tokens": "25592800910", + "delegator_shares": "25592800910.000000000000000000", + "description": { + "moniker": "NYvAvaIOdj", + "identity": "lYbVDursvX", + "website": "UXtFzZcHjM", + "security_contact": "PNNMeOJqcl", + "details": "ROVIgdvaJl" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.193312772989594496", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.226297820963910157" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvvur4tyyl553c4jeyvce0w3d0ezrrmsr6a2kcdksca4wpflc3lj7nf6fm9", + "status": 3, + "tokens": "25675698411", + "delegator_shares": "25675698411.000000000000000000", + "description": { + "moniker": "wDAGDTplVL", + "identity": "VUJoHvcuZs", + "website": "JzvbSfINxu", + "security_contact": "cROcYcTImn", + "details": "bdBDwVnOvM" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.108086670177688287", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.123495090782214164" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsuh3jpet", + "status": 3, + "tokens": "50488222690", + "delegator_shares": "50488222690.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.801397182624616334", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.592521503076154232" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfk090csv4thlsr4kx3fuucwcsk79lqs6gr5zse6m4xmwpq94hy2w3yuqp6", + "status": 3, + "tokens": "20659893696", + "delegator_shares": "20659893696.000000000000000000", + "description": { + "moniker": "gqjwubbLDT", + "identity": "OsKsdzWbsv", + "website": "rhWGeqAAVi", + "security_contact": "FmaEvvcaAr", + "details": "uMULjHPlYr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.168812875456833709" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5t7pxck", + "status": 3, + "tokens": "53644768786", + "delegator_shares": "53644768786.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.180000000000000000", + "max_change_rate": "0.029528662482337368" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2z47zet", + "status": 3, + "tokens": "21168715051", + "delegator_shares": "21168715051.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.026318239077074162", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.076792434560738120" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyw0np92", + "status": 3, + "tokens": "27374742411", + "delegator_shares": "27374742411.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.053895535796610462", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.182737583024108345" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2al69u7pnek9kcrmz83vstrst5szxuz6z03z0d848kuh3ekkjlfgr96q6z", + "status": 3, + "tokens": "20929858941", + "delegator_shares": "20929858941.000000000000000000", + "description": { + "moniker": "ciowxbJZpb", + "identity": "XgDAZmwEir", + "website": "moPXkGzyqT", + "security_contact": "WTLysotltH", + "details": "qoTHCiKGoL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003240694138410597", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.013650990946439583" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzvca96h", + "status": 3, + "tokens": "70162120947", + "delegator_shares": "70162120947.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.545864029263808659", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.533310660658318421" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqlk7nha", + "status": 3, + "tokens": "20279593182", + "delegator_shares": "20279593182.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.069908236020668720", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.009891358364124589" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqva0a8amjektwyshzjv38f6dw5uwat88kscw834kf3026r5ksn77gf0857j", + "status": 3, + "tokens": "31584297936", + "delegator_shares": "31584297936.000000000000000000", + "description": { + "moniker": "BKQyTeKaLC", + "identity": "eCoPebxrNV", + "website": "auQgzJBeZR", + "security_contact": "bLlknxqKWU", + "details": "amiXFmUGDr" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.900000000000000000", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.031968764827487641" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4cv2x09p", + "status": 3, + "tokens": "22768989048", + "delegator_shares": "22768989048.000000000000000000", + "description": { + "moniker": "EVTkHBKcpE", + "identity": "hMErYohFOn", + "website": "QaWaMRxOKv", + "security_contact": "qaxyuRDTeX", + "details": "ELwgPpPDKw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.386471695225710439" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfjcp62cfnelz8s5cl5qar8ymfjd5sjjkkr4tayrqrtzpf638hkjqmg9q4z", + "status": 3, + "tokens": "26491705865", + "delegator_shares": "26491705865.000000000000000000", + "description": { + "moniker": "SJeSnSdrXp", + "identity": "OTlQTOJbcV", + "website": "sulWDbaxDh", + "security_contact": "XTGtIDYHdJ", + "details": "KNeohKLilE" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.965860683215034339", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.778196912581936923" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", + "consensus_pubkey": "cosmosvalconspub1addwnpepq28myc67l0yhmnn6n2vq8hcmpaxesglyyqg825ujgrxdt9afwlsfx4ezupt", + "status": 3, + "tokens": "16257375002", + "delegator_shares": "16257375002.000000000000000000", + "description": { + "moniker": "mtHVFaNGLx", + "identity": "YTyhLHiifY", + "website": "JFeCDRXGYc", + "security_contact": "HndWqVmQvE", + "details": "JFVkeOUSbg" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.018292046092814578", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.057525240491425891" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z6ckp5s", + "status": 3, + "tokens": "62801915451", + "delegator_shares": "62801915451.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.323440196337864016" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng9t438v", + "status": 3, + "tokens": "22515450726", + "delegator_shares": "22515450726.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.752425052602923482" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6mcm2m0", + "status": 3, + "tokens": "29556680915", + "delegator_shares": "29556680915.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.289048467390880739", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.476925303769745140" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswzcmkck", + "status": 3, + "tokens": "25121635132", + "delegator_shares": "25121635132.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.541820589241677763" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", + "consensus_pubkey": "cosmosvalconspub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z2xdtk5", + "status": 3, + "tokens": "25662668318", + "delegator_shares": "25662668318.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.493962290871886167", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.601549819261141285" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vype2jq", + "status": 3, + "tokens": "59694062218", + "delegator_shares": "59694062218.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.047504130944412074", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.160000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2xzg536q0eksvxd2297ycyctfwp6x7rk0wq6d0murld346cjs756v0jnxn", + "status": 3, + "tokens": "16949426508", + "delegator_shares": "16949426508.000000000000000000", + "description": { + "moniker": "dNCvXIwisF", + "identity": "PInuRSnoAB", + "website": "IFaDEJuVii", + "security_contact": "DiiitKvkqG", + "details": "wJQyZMjCjC" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083382298074645848", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.156261937510636548" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag73jg46g", + "status": 3, + "tokens": "20324460034", + "delegator_shares": "20324460034.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.742458631966852296", + "max_rate": "0.750000000000000000", + "max_change_rate": "0.368222450098111604" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4d6e962zqejqu3jeypzp740n4k62xte2qnj82q03y28v6wkshycxxdg5w", + "status": 3, + "tokens": "18158211957", + "delegator_shares": "18158211957.000000000000000000", + "description": { + "moniker": "cVYtBkXobK", + "identity": "JOBpTikHPq", + "website": "NyobvRjfBj", + "security_contact": "bKDbHWcmSW", + "details": "xGfkOaAoAb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.340000000000000000", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.117974822314921419" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4cv0e5r0", + "status": 3, + "tokens": "25435646393", + "delegator_shares": "25435646393.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.004320117912957935", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.000447271047532656" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwfwqlzf", + "status": 3, + "tokens": "16773399211", + "delegator_shares": "16773399211.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.926805735750034881", + "max_rate": "0.990000000000000000", + "max_change_rate": "0.482844926743337660" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qavly08", + "status": 3, + "tokens": "17705677177", + "delegator_shares": "17705677177.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.615745867723667485", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.398263247650399274" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwv80xev", + "status": 3, + "tokens": "26461821776", + "delegator_shares": "26461821776.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.157167562506066789", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.091234306987583436" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwudpuh36geydlpx0yjqu0vhauacf294sn2uetg4ush97p382kqag6sxlqg", + "status": 3, + "tokens": "17862559018", + "delegator_shares": "17862559018.000000000000000000", + "description": { + "moniker": "wSgJTwBWiv", + "identity": "AEATmOIHsP", + "website": "WsuxwwJUIx", + "security_contact": "nzWdiJbKcf", + "details": "WXwvQKoIbT" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.120000000000000000", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.027292850423387945" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq4e58fv", + "status": 3, + "tokens": "112536605413", + "delegator_shares": "112536605413.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.592057337572123856", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.208226705977271974" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7kquya74", + "status": 3, + "tokens": "27525740131", + "delegator_shares": "27525740131.000000000000000000", + "description": { + "moniker": "ajDNnhnkbN", + "identity": "nkdfsqWVlx", + "website": "CeqAfYeTdW", + "security_contact": "KMQJbxKkbm", + "details": "cvAUuqNFYs" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.780000000000000000", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.550890306122411684" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj4x3m9h", + "status": 3, + "tokens": "57637848348", + "delegator_shares": "57637848348.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.081821299211443922", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.458576374327765136" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey2vtdvu", + "status": 3, + "tokens": "19834101875", + "delegator_shares": "19834101875.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.491522368582129610", + "max_rate": "0.900000000000000000", + "max_change_rate": "0.085253529277298261" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0aa00frx8hxrq5pegc0vnt69pj54z3dhwzy8uumr3nhgsc772h0zyr473p", + "status": 3, + "tokens": "37175356106", + "delegator_shares": "37175356106.000000000000000000", + "description": { + "moniker": "oedtWfExZY", + "identity": "taFwTdIwwz", + "website": "oGBHKapVuy", + "security_contact": "hnggEiQcYu", + "details": "qOFIRfzDGP" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083784124252551147", + "max_rate": "0.650000000000000000", + "max_change_rate": "0.550897578676987786" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dsktaxw5", + "status": 3, + "tokens": "55634424696", + "delegator_shares": "55634424696.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.016380613584719475", + "max_rate": "0.310000000000000000", + "max_change_rate": "0.310000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", + "consensus_pubkey": "cosmosvalconspub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz28vhtm", + "status": 3, + "tokens": "20453193314", + "delegator_shares": "20453193314.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.680000000000000000", + "max_change_rate": "0.528106308050967540" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqehts4m", + "status": 3, + "tokens": "52558464763", + "delegator_shares": "52558464763.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.128525196978986815", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.100900376719373255" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru72w0xm", + "status": 3, + "tokens": "18560827275", + "delegator_shares": "18560827275.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.100218404029226728", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.881639682871578638" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq00qxpqlwy0p6y9tl23yu7fpu55lhznxa3hrhvsuma6h7lu4c3ekks4wvua", + "status": 3, + "tokens": "22083357722", + "delegator_shares": "22083357722.000000000000000000", + "description": { + "moniker": "LvOuePvVwo", + "identity": "vfegdQlOfT", + "website": "mYvkvMZuDp", + "security_contact": "cfrddDLOlu", + "details": "yHfcxdGyEO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.122593865256918850", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.840000000000000000" + }, + "update_time": "9935-12-31T21:25:29Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxkm9kvvp", + "status": 3, + "tokens": "26763354026", + "delegator_shares": "26763354026.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.027810962515737967", + "max_rate": "0.070000000000000000", + "max_change_rate": "0.034717076557320762" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdpwvxyz0d0thr5hw72lswav4tdfuwkgfqjdjkaws99y4dw5fzncg487kz6", + "status": 3, + "tokens": "25943967606", + "delegator_shares": "25943967606.000000000000000000", + "description": { + "moniker": "anqFIENyYy", + "identity": "LYtCTmovif", + "website": "nDcnuLjZla", + "security_contact": "KhBXWuJORy", + "details": "rcnhuNfFoO" + }, + "unbonding_height": "13", + "unbonding_time": "9936-01-01T19:46:26Z", + "commission": { + "commission_rates": { + "rate": "0.489033782311246085", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.501117175906227815" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvykaseh7", + "status": 3, + "tokens": "68955304480", + "delegator_shares": "68955304480.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.208925360976246176", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.463634503057540350" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peggwy7x5", + "status": 3, + "tokens": "49844884060", + "delegator_shares": "49844884060.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.338644152469426553", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.069153802725768656" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxz2ead4", + "status": 3, + "tokens": "19233426986", + "delegator_shares": "19233426986.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.373154376676147691", + "max_rate": "0.980000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wjfqd63", + "status": 3, + "tokens": "25961659072", + "delegator_shares": "25961659072.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.068613373696134985", + "max_rate": "0.080000000000000000", + "max_change_rate": "0.073351676068018235" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7ul2hc3", + "status": 3, + "tokens": "33320443806", + "delegator_shares": "33320443806.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118849597906926326", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.228258187539755185" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7whvstg", + "status": 3, + "tokens": "59094460259", + "delegator_shares": "59094460259.000000000000000000", + "description": { + "moniker": "cVUXvMdRgs", + "identity": "AHkjmtOkYK", + "website": "KLRPQOyDoY", + "security_contact": "VHwCrfhVnI", + "details": "qdFVvUucvR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.182731553781057822", + "max_rate": "0.270000000000000000", + "max_change_rate": "0.045316794895420248" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqde6g57cex9ff650ku6dqdqtfulfnzkacecf6k436xl0dd07zglxx5659h9", + "status": 3, + "tokens": "27718687960", + "delegator_shares": "27718687960.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.905848795661145449", + "max_rate": "0.950000000000000000", + "max_change_rate": "0.476775855507110704" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy7220f9ul3", + "status": 3, + "tokens": "33772482275", + "delegator_shares": "33772482275.000000000000000000", + "description": { + "moniker": "znFMdpLOQw", + "identity": "LEMEnpcxqp", + "website": "TjKmeKjDGm", + "security_contact": "ZOXcBhlDyq", + "details": "WpmmnksSqL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.834910862331446014", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cuyxrn7n", + "status": 3, + "tokens": "24587685968", + "delegator_shares": "24587685968.000000000000000000", + "description": { + "moniker": "tlYEYvdvKp", + "identity": "fQFtYLRSZA", + "website": "ecuAofwdaj", + "security_contact": "gwsuBeDyJU", + "details": "gELFJGuwPs" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.499259642246008210", + "max_rate": "0.560000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jet5tg3", + "status": 3, + "tokens": "62232444428", + "delegator_shares": "62232444428.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.153116543667039838", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.230000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yfudg7m", + "status": 3, + "tokens": "25948607110", + "delegator_shares": "25948607110.000000000000000000", + "description": { + "moniker": "IssGiFwTJv", + "identity": "VgTaqmOLtN", + "website": "BpkICmEqwF", + "security_contact": "qmrIWxiWft", + "details": "sLtbcsMFgA" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.136694009459855954", + "max_rate": "0.140000000000000000", + "max_change_rate": "0.056116480834729575" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4c8wkdlg", + "status": 3, + "tokens": "18426946099", + "delegator_shares": "18426946099.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.469814499540087620", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.960000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvquc4jf3", + "status": 3, + "tokens": "16774945156", + "delegator_shares": "16774945156.000000000000000000", + "description": { + "moniker": "hZvyDgtWxX", + "identity": "TPMmELNQYL", + "website": "YxTdbJnobM", + "security_contact": "ZURHxVMZoL", + "details": "zVjWraUVyE" + }, + "unbonding_height": "7", + "unbonding_time": "9936-01-01T06:43:57Z", + "commission": { + "commission_rates": { + "rate": "0.258972799025106506", + "max_rate": "0.910000000000000000", + "max_change_rate": "0.304259315697044502" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprs83zeag", + "status": 3, + "tokens": "32156167120", + "delegator_shares": "32156167120.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.351977697440288211" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvly6j0pyezy88s9lnat6taglylzq03vvsvyw4uy2tv3vcl3200ej0nev4k", + "status": 3, + "tokens": "16811362128", + "delegator_shares": "16811362128.000000000000000000", + "description": { + "moniker": "lasYiVeRDA", + "identity": "TFiGxJBNUs", + "website": "xswbDClAxs", + "security_contact": "HYUurzqzcC", + "details": "EVSfzEFSuo" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.036542719943188247", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.304756516958654494" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66dra0w3", + "status": 3, + "tokens": "19540440011", + "delegator_shares": "19540440011.000000000000000000", + "description": {}, + "unbonding_height": "12", + "unbonding_time": "9936-01-01T17:01:39Z", + "commission": { + "commission_rates": { + "rate": "0.065303820000927065", + "max_rate": "0.160000000000000000", + "max_change_rate": "0.134868108685582589" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afqga9sv8", + "status": 3, + "tokens": "33258307031", + "delegator_shares": "33258307031.000000000000000000", + "description": { + "moniker": "uVtPIVoLeB", + "identity": "UQUjtBkUkU", + "website": "lrfjDXnSyH", + "security_contact": "tPWaAehpKA", + "details": "YCcmQgJRnO" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.859185512301348293", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.915098787337318307" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrq06r4ck", + "status": 3, + "tokens": "41543247193", + "delegator_shares": "41543247193.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.119695944592116460" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4vjajc6x", + "status": 3, + "tokens": "61843733534", + "delegator_shares": "61843733534.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.437478542817284441", + "max_rate": "0.530000000000000000", + "max_change_rate": "0.308410375933996023" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvghhzrgz", + "status": 3, + "tokens": "36037299066", + "delegator_shares": "36037299066.000000000000000000", + "description": { + "moniker": "rUZvoFLmub", + "identity": "dQGYIJXPFq", + "website": "ZPoXnJmgzU", + "security_contact": "MdbwPJFNHC", + "details": "NdoQBlpUhN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.670000000000000000", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.629855974067904060" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz4luxgn", + "status": 3, + "tokens": "33206633235", + "delegator_shares": "33206633235.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.229284159886860129", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.212917450108859841" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", + "consensus_pubkey": "cosmosvalconspub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw24c76ax", + "status": 3, + "tokens": "27567655084", + "delegator_shares": "27567655084.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.216560651737526756", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.026445047137608599" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qpu7x5c", + "status": 3, + "tokens": "27671960609", + "delegator_shares": "27671960609.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.077841535313299819", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.054979434313866047" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2wcjjal", + "status": 3, + "tokens": "25069342080", + "delegator_shares": "25069342080.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.249161816461641720", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.693944288516379645" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akutfqm7", + "status": 3, + "tokens": "55737096951", + "delegator_shares": "55737096951.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.498362112747574396", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.645641814068879323" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693hazjkkehy", + "status": 3, + "tokens": "33054734644", + "delegator_shares": "33054734644.000000000000000000", + "description": { + "moniker": "mUQFKtnPLD", + "identity": "xsxoaAIVkh", + "website": "EBARfZhhON", + "security_contact": "GynbBFtcRq", + "details": "RftDCeMUPi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.123876475355091478", + "max_rate": "0.860000000000000000", + "max_change_rate": "0.141162753552435345" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v30nmws", + "status": 3, + "tokens": "78601464028", + "delegator_shares": "78601464028.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083731202536014652", + "max_rate": "0.860000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9ykjrzn93", + "status": 3, + "tokens": "18090212819", + "delegator_shares": "18090212819.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.081582427988342735", + "max_rate": "0.120000000000000000", + "max_change_rate": "0.086390137368972014" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06my86wxz2", + "status": 3, + "tokens": "33968139195", + "delegator_shares": "33968139195.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.247483015769197525", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.837420192496215212" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtufvzu2k2knnce8l9jcwuntray9m8hnlal8a4jkcjazppr5p7pyus6emm0", + "status": 3, + "tokens": "19857350032", + "delegator_shares": "19857350032.000000000000000000", + "description": { + "moniker": "PfGefIRkUQ", + "identity": "PQNdBVtoxj", + "website": "nyfnvHyjNl", + "security_contact": "ewMiIvfvCh", + "details": "ttKmCVgWXS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.239149115387739677", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.173620767408899960" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv9w0yqrekktvu6gd7ak8u7wkwqj47llgrtl2vp2gtdvfafwatyysclj3nm", + "status": 3, + "tokens": "23726914937", + "delegator_shares": "23726914937.000000000000000000", + "description": {}, + "unbonding_height": "47", + "unbonding_time": "9936-01-04T16:25:11Z", + "commission": { + "commission_rates": { + "rate": "0.522454157166611225", + "max_rate": "0.820000000000000000", + "max_change_rate": "0.329662780053528069" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2crvswax", + "status": 3, + "tokens": "16516288319", + "delegator_shares": "16516288319.000000000000000000", + "description": { + "moniker": "kVNZIBYAxD", + "identity": "ChbsAFHanI", + "website": "SvHMthzzzB", + "security_contact": "cMJXUgGCfx", + "details": "PWsrYNKuPZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.540000000000000000", + "max_rate": "0.540000000000000000", + "max_change_rate": "0.491525012965837080" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2kj4krx", + "status": 3, + "tokens": "45010236382", + "delegator_shares": "45010236382.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.095070637134115497" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveesw5rr6m", + "status": 3, + "tokens": "54768547781", + "delegator_shares": "54768547781.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.328146514360581742", + "max_rate": "0.810000000000000000", + "max_change_rate": "0.166428198995593213" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68yqxsxnt", + "status": 3, + "tokens": "25326342688", + "delegator_shares": "25326342688.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.785486462764506620", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.356882054361860100" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzlcd6kj", + "status": 3, + "tokens": "67804970220", + "delegator_shares": "67804970220.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.264013069771684883" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4v8fm8e8", + "status": 3, + "tokens": "41964454098", + "delegator_shares": "41964454098.000000000000000000", + "description": { + "moniker": "LDEzyylLGV", + "identity": "NaLpENvFnX", + "website": "ooOcvgIJwr", + "security_contact": "aQaxAlCyFx", + "details": "CxEFcmLmkI" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.099339754970547702", + "max_rate": "0.320000000000000000", + "max_change_rate": "0.111217397607280422" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k907nvf", + "status": 3, + "tokens": "28676349495", + "delegator_shares": "28676349495.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.609184993023386704", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.699887495531371188" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", + "consensus_pubkey": "cosmosvalconspub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjtszrqs", + "status": 3, + "tokens": "34574952843", + "delegator_shares": "34574952843.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.810000000000000000", + "max_rate": "0.810000000000000000", + "max_change_rate": "0.810000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", + "consensus_pubkey": "cosmosvalconspub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku73m9m0", + "status": 3, + "tokens": "16992076248", + "delegator_shares": "16992076248.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.406968367525101581", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.487609794856186092" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfcdg0aax", + "status": 3, + "tokens": "16967510024", + "delegator_shares": "16967510024.000000000000000000", + "description": { + "moniker": "YKKhjZGayb", + "identity": "IvgiPDjmYA", + "website": "gScrUtVzvh", + "security_contact": "kGHySpHXgu", + "details": "IyuehlcoPM" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.093407705950029411", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.187465926844434813" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7zgmra8", + "status": 3, + "tokens": "26261718579", + "delegator_shares": "26261718579.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.210000000000000000", + "max_change_rate": "0.067309904771533509" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqnavslf", + "status": 3, + "tokens": "46127605035", + "delegator_shares": "46127605035.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.895728278286976959", + "max_rate": "0.920000000000000000", + "max_change_rate": "0.140752130806369269" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jyyn3gu", + "status": 3, + "tokens": "22487156484", + "delegator_shares": "22487156484.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.008115100503323252", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yagkfrr", + "status": 3, + "tokens": "39560123415", + "delegator_shares": "39560123415.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.060188716749386269", + "max_rate": "0.350000000000000000", + "max_change_rate": "0.350000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", + "consensus_pubkey": "cosmosvalconspub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kwmez9k", + "status": 3, + "tokens": "16420725988", + "delegator_shares": "16420725988.000000000000000000", + "description": { + "moniker": "LVfceOUKZE", + "identity": "ZyVUuaCAJZ", + "website": "rliAdTPvEK", + "security_contact": "hVtZPHOsKh", + "details": "QjmMKruCba" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.230000000000000000", + "max_change_rate": "0.036920301680485403" + }, + "update_time": "9936-01-01T16:55:11Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq77rpqn", + "status": 3, + "tokens": "26062927309", + "delegator_shares": "26062927309.000000000000000000", + "description": { + "moniker": "BFoqLaJLDn", + "identity": "weLorPCgTe", + "website": "oyhVcpSOLq", + "security_contact": "hdnvhDJTDC", + "details": "SAZISvvmwB" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.160832184115355939", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", + "consensus_pubkey": "cosmosvalconspub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xw03emk4", + "status": 3, + "tokens": "44313010729", + "delegator_shares": "44313010729.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.083856723472306849", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.569378562223247850" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6yp7zp3n", + "status": 3, + "tokens": "25164533156", + "delegator_shares": "25164533156.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.330000000000000000", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.314039829028852779" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvn899z9u9a7h28682292n9y77yr6yuyrg2xvg8eaammccqfuc9e5jp63vn", + "status": 3, + "tokens": "16985369823", + "delegator_shares": "16985369823.000000000000000000", + "description": { + "moniker": "oVMoJSrGgV", + "identity": "ydZuwvoyLe", + "website": "EdyJLNhNGZ", + "security_contact": "QauDavDNuL", + "details": "CVkbnFlumN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.276325858271560152", + "max_rate": "0.600000000000000000", + "max_change_rate": "0.108166159043578444" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwshp63n", + "status": 3, + "tokens": "25367511082", + "delegator_shares": "25367511082.000000000000000000", + "description": { + "moniker": "KODmaZYfBO", + "identity": "dQoWoZcHpD", + "website": "QRjjuYKVNR", + "security_contact": "BHWzdORGfc", + "details": "dZGTxQmqIN" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003392332242825811", + "max_rate": "0.060000000000000000", + "max_change_rate": "0.027187395396712775" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqv0lje47", + "status": 3, + "tokens": "54901950842", + "delegator_shares": "54901950842.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.193375046872051394", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.161750559623523660" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc9m7uvt", + "status": 3, + "tokens": "15374405822", + "delegator_shares": "15374405820.680335249007925874", + "description": { + "moniker": "eomlzRaIRN", + "identity": "PaBTVBXpcj", + "website": "frMwzGwrdS", + "security_contact": "XwCgZGftYO", + "details": "oynChhccDw" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.014913519812752309", + "max_rate": "0.330000000000000000", + "max_change_rate": "0.219118316904950121" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7dsh8mr", + "status": 3, + "tokens": "31376033263", + "delegator_shares": "31376033263.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.074914975922116628" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axhh8p8f", + "status": 3, + "tokens": "49683234188", + "delegator_shares": "49683234188.000000000000000000", + "description": { + "moniker": "MJAduJwrkS", + "identity": "YpKMJsMpdh", + "website": "rmUXbHIGjh", + "security_contact": "KxyJSeDEJS", + "details": "gQmDpfNyLZ" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.637063248045666486", + "max_rate": "0.800000000000000000", + "max_change_rate": "0.100218674012239339" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmkm3zs42", + "status": 3, + "tokens": "34289428306", + "delegator_shares": "34289428306.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.026475742223507385", + "max_rate": "0.040000000000000000", + "max_change_rate": "0.008016543161851368" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw3fj2ga", + "status": 3, + "tokens": "29885998584", + "delegator_shares": "29885998584.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.208832068199199828", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.835848953294536000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", + "consensus_pubkey": "cosmosvalconspub1addwnpepqv7nw49k6j8sg6379dy0lemj7vee2el49mt5rmypwujwk6lua8duyrr8zrn", + "status": 3, + "tokens": "21181468286", + "delegator_shares": "21181468286.000000000000000000", + "description": { + "moniker": "TgLltHAWtO", + "identity": "zpriAAvZuw", + "website": "pWVJnIqFBY", + "security_contact": "TyuWOjmMFF", + "details": "CbbpwkidBS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.237822850366335221", + "max_rate": "0.300000000000000000", + "max_change_rate": "0.134613352727411591" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2vncgld", + "status": 3, + "tokens": "39430946332", + "delegator_shares": "39430946332.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.400358972669819604", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.343431675789315867" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrywn9e6w", + "status": 3, + "tokens": "32328037984", + "delegator_shares": "32328037984.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.039339062684741866", + "max_rate": "0.150000000000000000", + "max_change_rate": "0.021256256594527078" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", + "consensus_pubkey": "cosmosvalconspub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus2udpwh", + "status": 3, + "tokens": "15813863385", + "delegator_shares": "15813863385.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.543747468021249371", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.392045382869085556" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwujx3ap2", + "status": 3, + "tokens": "25957780472", + "delegator_shares": "25957780472.000000000000000000", + "description": { + "moniker": "hoLpIoNUFo", + "identity": "LCpoujNFyW", + "website": "AOTlTXjPul", + "security_contact": "elgNvDzEfH", + "details": "hwOSWkTDMH" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.347272379813626146", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9ugfdlq9", + "status": 3, + "tokens": "45284218868", + "delegator_shares": "45284218868.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.340626334815374555", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkxmnmkq", + "status": 3, + "tokens": "44505127913", + "delegator_shares": "44505127913.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.605944631117636209", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.639343774657574630" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqk8ct27q", + "status": 3, + "tokens": "22456561633", + "delegator_shares": "22456561633.000000000000000000", + "description": { + "moniker": "DPTpRIdXgW", + "identity": "qysDMlMxpi", + "website": "xWbmLVlZvB", + "security_contact": "QtpKTducMv", + "details": "UWYfFdNOxg" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.057271144965717909", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.075138495309274904" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd7u4d80m4e6sfhyzj84k6y34v30g9cstzx7cmrazvxdtfe40urcvran9t8", + "status": 3, + "tokens": "45811135531", + "delegator_shares": "45811135531.000000000000000000", + "description": { + "moniker": "zcPImZiDZD", + "identity": "zkcTihefFl", + "website": "mIjAaWRNkf", + "security_contact": "gTafXNexkI", + "details": "tJJDPwaiAf" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.079222020883406460", + "max_rate": "0.410000000000000000", + "max_change_rate": "0.311112908017536993" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggxauhp0sadc5npdva6f492f3n4a76fldyt3lca6lk36685s624ucakcrh", + "status": 3, + "tokens": "24610359351", + "delegator_shares": "24610359351.000000000000000000", + "description": { + "moniker": "dLwrEevbbD", + "identity": "ubSqqBoPRs", + "website": "MNuXpKVOXc", + "security_contact": "lNXuEDYSJp", + "details": "CvXURllZqF" + }, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.200000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.175531415042829217" + }, + "update_time": "9935-12-31T19:49:14Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqwclfkt", + "status": 3, + "tokens": "34459325260", + "delegator_shares": "34459325260.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.033986343509044787", + "max_rate": "0.090000000000000000", + "max_change_rate": "0.090000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7t4673v", + "status": 3, + "tokens": "55948291091", + "delegator_shares": "55948291091.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.440048441195653325", + "max_rate": "0.450000000000000000", + "max_change_rate": "0.180789237411591672" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5r4xrdd", + "status": 3, + "tokens": "15675831119", + "delegator_shares": "15675831119.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czwem9y4", + "status": 3, + "tokens": "45487475001", + "delegator_shares": "45487475001.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.177753292751501209", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.323174353688819429" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxe7jutz", + "status": 3, + "tokens": "24261774404", + "delegator_shares": "24261774404.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.017452646416466178", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.020000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4svau85d", + "status": 3, + "tokens": "31770155824", + "delegator_shares": "31770155824.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.138735148670316454", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.286634953103815529" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf0u600sgl3zdn3uh4jd6jmw6fc0jc40r0l2crvz3sla3f8d32flghwtxaq", + "status": 3, + "tokens": "37602205867", + "delegator_shares": "37602205867.000000000000000000", + "description": { + "moniker": "BUZauhlQrt", + "identity": "yuIKzyGzQS", + "website": "fDSmxAmazc", + "security_contact": "jVDWgXPhkM", + "details": "LBFAwsUoyi" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.244517333363622892", + "max_rate": "0.290000000000000000", + "max_change_rate": "0.153245122134586562" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzue70ade", + "status": 3, + "tokens": "37676305948", + "delegator_shares": "37676305948.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.260000000000000000", + "max_rate": "0.260000000000000000", + "max_change_rate": "0.239035612898447459" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj2sy3f5", + "status": 3, + "tokens": "26850762657", + "delegator_shares": "26850762657.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.420000000000000000", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.295551090875771737" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvhet24yk50y4m60mceffquewu9p4enwrgcum0csceuull7a59u6567nn0v", + "status": 3, + "tokens": "20405570669", + "delegator_shares": "20405570669.000000000000000000", + "description": { + "moniker": "ZeprycSOnc", + "identity": "ZcHuivhMFq", + "website": "hCsVpTWmaL", + "security_contact": "AIKsDuUCDR", + "details": "EgpxVbAOaK" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.054000324644638628", + "max_rate": "0.380000000000000000", + "max_change_rate": "0.120973196882786975" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", + "consensus_pubkey": "cosmosvalconspub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6k07476", + "status": 3, + "tokens": "25102040344", + "delegator_shares": "25102040344.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.599184934718890393", + "max_rate": "0.770000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgh9lxfuk4amzsp0w28t8dkdwf2xk8yrxjj7xz0lnmzs2lyahrdz2f2yy35", + "status": 3, + "tokens": "17609505538", + "delegator_shares": "17609505538.000000000000000000", + "description": { + "moniker": "yAwjGcNsZH", + "identity": "STCkyPeJjc", + "website": "yvmEPebWkk", + "security_contact": "ZficJLXKJM", + "details": "qAWHtJiitW" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.690000000000000000", + "max_rate": "0.690000000000000000", + "max_change_rate": "0.509977105992119960" + }, + "update_time": "9936-01-01T01:54:53Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", + "consensus_pubkey": "cosmosvalconspub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjycl58l", + "status": 3, + "tokens": "41119826715", + "delegator_shares": "41119826715.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.240000000000000000", + "max_change_rate": "0.025162698699691548" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75fh3auv", + "status": 3, + "tokens": "19565632897", + "delegator_shares": "19565632897.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.579061375935434182", + "max_rate": "0.780000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwskjpjy", + "status": 3, + "tokens": "44648874284", + "delegator_shares": "44648874284.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.258140043497759741", + "max_rate": "0.570000000000000000", + "max_change_rate": "0.447039357737510640" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg57gy4ef", + "status": 3, + "tokens": "34209671267", + "delegator_shares": "34209671267.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.480455308806333346", + "max_rate": "0.710000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55hrcqtd", + "status": 3, + "tokens": "25069342080", + "delegator_shares": "25069342080.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.409558857679769509", + "max_rate": "0.930000000000000000", + "max_change_rate": "0.610998804526507722" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0sgshv9mf8qy7ff303mqqv5zppu3q4mcwrnheue8d3kq0ytyynkxlak2ae", + "status": 3, + "tokens": "28980476016", + "delegator_shares": "28980476016.000000000000000000", + "description": { + "moniker": "hVYOUraqpo", + "identity": "XRliNUdYgt", + "website": "FYzwRNeFsW", + "security_contact": "AYYtrdbBmx", + "details": "NaWAwUYhir" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.940000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "9935-12-31T23:32:57Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", + "consensus_pubkey": "cosmosvalconspub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxd2wcms", + "status": 3, + "tokens": "27742737411", + "delegator_shares": "27742737411.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.870000000000000000", + "max_rate": "0.870000000000000000", + "max_change_rate": "0.402061609548054151" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2x30aum6t8lauwqh72szktjx6fmgf5ux7vcs38uukp9a5h287wawhv5mfv", + "status": 3, + "tokens": "17377751306", + "delegator_shares": "17377751306.000000000000000000", + "description": { + "moniker": "SslqJkEqrN", + "identity": "qMdXPqvbCt", + "website": "HDwwjWlugU", + "security_contact": "LzWMObthwF", + "details": "zlyoRqwOQS" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.498765541593724538", + "max_rate": "0.530000000000000000", + "max_change_rate": "0.156108348646223859" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3lu0qw8kj", + "status": 3, + "tokens": "25431851328", + "delegator_shares": "25431851328.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.450461328836777178", + "max_rate": "0.840000000000000000", + "max_change_rate": "0.254665389885134513" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcf30j9c", + "status": 3, + "tokens": "74690344989", + "delegator_shares": "74690344989.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.882630947578979215", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.960000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr2mqfkju", + "status": 3, + "tokens": "27874325464", + "delegator_shares": "27874325464.000000000000000000", + "description": {}, + "unbonding_height": "1", + "unbonding_time": "9935-12-31T19:10:44Z", + "commission": { + "commission_rates": { + "rate": "0.459241580368376871", + "max_rate": "0.490000000000000000", + "max_change_rate": "0.448990769658695281" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngklt9fqt", + "status": 3, + "tokens": "68086107574", + "delegator_shares": "68086107574.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.280411773058535090", + "max_rate": "0.880000000000000000", + "max_change_rate": "0.009358685901125498" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdq8fheeu", + "status": 3, + "tokens": "25446232136", + "delegator_shares": "25446232136.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.073669961838812257", + "max_rate": "0.340000000000000000", + "max_change_rate": "0.338443455873010612" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdjuv3ql5rv5njym62quduw7554as4aa8seufp7f4zv6q28tds2e23v4cv5", + "status": 3, + "tokens": "35741739231", + "delegator_shares": "35741739231.000000000000000000", + "description": { + "moniker": "MoJgIrbTvT", + "identity": "rTfyDjhPlV", + "website": "fXpRItnlwS", + "security_contact": "tIlMCZPLDi", + "details": "QoSUrnFXNb" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.037606710200997532", + "max_rate": "0.610000000000000000", + "max_change_rate": "0.432717335122536998" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwvhpfht", + "status": 3, + "tokens": "19637280062", + "delegator_shares": "19637280062.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.118259925415637398", + "max_rate": "0.220000000000000000", + "max_change_rate": "0.176572964585642890" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwaazwez", + "status": 3, + "tokens": "56856814851", + "delegator_shares": "56856814851.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.093189165744722643", + "max_rate": "0.250000000000000000", + "max_change_rate": "0.044880981942823250" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyvxmu04", + "status": 3, + "tokens": "36122807193", + "delegator_shares": "36122807193.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.414145633705698803", + "max_rate": "0.500000000000000000", + "max_change_rate": "0.500000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd2gmrd8aux64z50e58tu00n3yjunvqduf4xv3g3p6j3wpuxddex59mpcfe", + "status": 3, + "tokens": "16807158123", + "delegator_shares": "16807158123.000000000000000000", + "description": { + "moniker": "ZHKMxyLBmy", + "identity": "EwvvJnavFX", + "website": "DHXlVcQLfr", + "security_contact": "cqkJGwinbb", + "details": "CwxLKqsDci" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.054776212220005616", + "max_rate": "0.370000000000000000", + "max_change_rate": "0.012318363733558931" + }, + "update_time": "9936-01-04T13:24:43Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", + "consensus_pubkey": "cosmosvalconspub1addwnpepq2p3sa8dkvz36pz6nusjdhm9aqlnrrldrszzuqd5qy7ssqztn99ggqpcdlz", + "status": 3, + "tokens": "48540826744", + "delegator_shares": "48540826744.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.003549575739989554", + "max_rate": "0.020000000000000000", + "max_change_rate": "0.001119527935415439" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycjhwrn7", + "status": 3, + "tokens": "29401856985", + "delegator_shares": "29401856985.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.243341366114153903", + "max_rate": "0.670000000000000000", + "max_change_rate": "0.628404054381210058" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdaa2szanfjwhzucqfj0ct7ljhc3kew8am3h8sr8wqzlnh8df06g5th460y", + "status": 3, + "tokens": "24697024268", + "delegator_shares": "24697024268.000000000000000000", + "description": { + "moniker": "XYWZXrqRDE", + "identity": "MFgElwSSlb", + "website": "ZPGkarWAml", + "security_contact": "dFzxEZXTfo", + "details": "HRGbXKBEeq" + }, + "unbonding_height": "4", + "unbonding_time": "9936-01-01T00:38:18Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.550000000000000000", + "max_change_rate": "0.376530136432859216" + }, + "update_time": "9935-12-31T16:20:47Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", + "consensus_pubkey": "cosmosvalconspub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w4r0vhq", + "status": 3, + "tokens": "41494205421", + "delegator_shares": "41494205421.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.000000000000000000", + "max_rate": "0.070000000000000000", + "max_change_rate": "0.000000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgc0dahup", + "status": 3, + "tokens": "54450506134", + "delegator_shares": "54450506134.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.109747630034489371", + "max_rate": "0.970000000000000000", + "max_change_rate": "0.461346401411912639" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", + "consensus_pubkey": "cosmosvalconspub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkn6paax", + "status": 3, + "tokens": "23703504292", + "delegator_shares": "23703504292.000000000000000000", + "description": { + "moniker": "eXfwGKuzGb", + "identity": "dYpMrjwrPA", + "website": "DzaFOsditE", + "security_contact": "GuNLPoNZsM", + "details": "iALsKeROvR" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.087538799057934086", + "max_rate": "0.960000000000000000", + "max_change_rate": "0.859363741701174499" + }, + "update_time": "9936-01-01T04:09:39Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyt542en", + "status": 3, + "tokens": "69725274862", + "delegator_shares": "69725274862.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.077835183941357357", + "max_rate": "0.630000000000000000", + "max_change_rate": "0.287966636331923139" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwfq28wcw9gn3mynr4pjdpd5hhert9hheg8qus862ymrt5ex6j75jlkuhe3", + "status": 3, + "tokens": "21764467799", + "delegator_shares": "21764467799.000000000000000000", + "description": { + "moniker": "ObWwGUpRaY", + "identity": "BCfhwnVexY", + "website": "SBehiPUtRR", + "security_contact": "jMhyvuyFaP", + "details": "LHYAZFxdaS" + }, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.075332177620667120", + "max_rate": "0.100000000000000000", + "max_change_rate": "0.039077923270826524" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", + "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsrp7s99", + "status": 3, + "tokens": "25229713771", + "delegator_shares": "25229713771.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.420000000000000000", + "max_rate": "0.420000000000000000", + "max_change_rate": "0.006473324874363207" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd5jsj53j7m0umzvh90dwanxhfxmpydhfazmsz978v9yuh05q0kxcyqtdla", + "status": 3, + "tokens": "16747268503", + "delegator_shares": "16747268503.000000000000000000", + "description": { + "moniker": "OuShqctNnC", + "identity": "MfQbnbeXdv", + "website": "OfOpteXCQn", + "security_contact": "qaSLhJmnUG", + "details": "vIuRzAnYuu" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.589668369513377579", + "max_rate": "0.640000000000000000", + "max_change_rate": "0.640000000000000000" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge726q0dwq", + "status": 3, + "tokens": "56914095343", + "delegator_shares": "56914095343.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.561558403350280399", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.088588598076790894" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0us7fav4", + "status": 3, + "tokens": "53587404091", + "delegator_shares": "53587404091.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.148502470554898869", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.005661642347781868" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvw32mxlzzzmmpks775cgclcsmypqhhz7765v03wnjf8cn4hsrw67tq2l8n", + "status": 3, + "tokens": "20301516153", + "delegator_shares": "20301516153.000000000000000000", + "description": { + "moniker": "ibdjDFXkFg", + "identity": "BhaqDbDPwH", + "website": "KoHplbnTSd", + "security_contact": "zgJBSepZRt", + "details": "anTLerUmWY" + }, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.092279263137073204", + "max_rate": "0.130000000000000000", + "max_change_rate": "0.062347977318301413" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", + "consensus_pubkey": "cosmosvalconspub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4umtaftt", + "status": 3, + "tokens": "23438430919", + "delegator_shares": "23438430919.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.065104244001935780", + "max_rate": "0.280000000000000000", + "max_change_rate": "0.087973256413395308" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", + "consensus_pubkey": "cosmosvalconspub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wu8lrdvr", + "status": 3, + "tokens": "23476663612", + "delegator_shares": "23476663612.000000000000000000", + "description": { + "moniker": "qNlNvDKQWh", + "identity": "PdEEmVXzOP", + "website": "jyQRsxutdI", + "security_contact": "hTNdvfWkVQ", + "details": "gPNrXPrkeL" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.830000000000000000", + "max_rate": "0.830000000000000000", + "max_change_rate": "0.679717803083962746" + }, + "update_time": "9935-12-31T14:21:40Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", + "consensus_pubkey": "cosmosvalconspub1addwnpepqt7pax9cuqs5vjjvhpmcgvy5dkqrrtrg6336c3xhyrchtegy2m387ccs037", + "status": 3, + "tokens": "19815525788", + "delegator_shares": "19815525788.000000000000000000", + "description": { + "moniker": "sJKzLUYWBq", + "identity": "ZzbWnFqPTq", + "website": "dlevXyAGdk", + "security_contact": "bnQNzwNRYP", + "details": "PaxiDbFCJj" + }, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.291627565410574418", + "max_rate": "0.660000000000000000", + "max_change_rate": "0.017987067010819344" + }, + "update_time": "9936-01-01T12:12:35Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", + "consensus_pubkey": "cosmosvalconspub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wel7d3l", + "status": 3, + "tokens": "25456865344", + "delegator_shares": "25456865344.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.293848609442759777", + "max_rate": "0.580000000000000000", + "max_change_rate": "0.580000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", + "consensus_pubkey": "cosmosvalconspub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6u59lzkg", + "status": 3, + "tokens": "44085124225", + "delegator_shares": "44085124225.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.045106108515206331", + "max_rate": "0.850000000000000000", + "max_change_rate": "0.610987430943531252" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", + "consensus_pubkey": "cosmosvalconspub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xvdql9k", + "status": 3, + "tokens": "25311353934", + "delegator_shares": "25311353934.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.324580145668396309", + "max_rate": "0.480000000000000000", + "max_change_rate": "0.480000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", + "consensus_pubkey": "cosmosvalconspub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujgucg2ktdn", + "status": 3, + "tokens": "32745806516", + "delegator_shares": "32745806516.000000000000000000", + "description": {}, + "unbonding_time": "1970-01-01T00:00:00Z", + "commission": { + "commission_rates": { + "rate": "0.322505571100731689", + "max_rate": "0.520000000000000000", + "max_change_rate": "0.183472725952677048" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", + "consensus_pubkey": "cosmosvalconspub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592jkkxzm", + "status": 3, + "tokens": "21858111883", + "delegator_shares": "21858111883.000000000000000000", + "description": {}, + "unbonding_height": "2", + "unbonding_time": "9935-12-31T21:09:51Z", + "commission": { + "commission_rates": { + "rate": "0.799310131872627643", + "max_rate": "0.890000000000000000", + "max_change_rate": "0.706235617003159879" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + }, + { + "operator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", + "consensus_pubkey": "cosmosvalconspub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxtyq8dz", + "status": 3, + "tokens": "28684472849", + "delegator_shares": "28684472849.000000000000000000", + "description": {}, + "unbonding_height": "5", + "unbonding_time": "9936-01-01T02:14:33Z", + "commission": { + "commission_rates": { + "rate": "0.174404138163737710", + "max_rate": "0.360000000000000000", + "max_change_rate": "0.360000000000000000" + }, + "update_time": "1970-01-01T00:00:00Z" + }, + "min_self_delegation": "1" + } + ] + } + ], + "exported": true + }, + "upgrade": {}, + "genutil": { + "gentxs": [] + }, + "auth": { + "params": { + "max_memo_characters": "193", + "tx_sig_limit": "5", + "tx_size_cost_per_byte": "12", + "sig_verify_cost_ed25519": "796", + "sig_verify_cost_secp256k1": "548" + }, + "accounts": [ + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qqxeqqvjkh2ls3a0taukd8rydrqqad690nxkcc", + "public_key": "cosmospub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels38sdnz", + "account_number": 109, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1qqexr0y3fxueg3v366ctzlqctexhj5mplmznm4", + "public_key": null, + "account_number": "738", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "11536924691" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383975314" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", + "public_key": "cosmospub1addwnpepq2clak7n0wuffqrj9ltzxmj7mp8nfd4mupcs2qx8wcntcmqmrhlg5r9qfec", + "account_number": 311, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", + "public_key": "cosmospub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xyxph83", + "account_number": 220, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qp6s6vzf6l0mzeglw0a9d75h7ch4w99ahux3j2", + "public_key": "cosmospub1addwnpepqtehxgdl0fyj92rj04phntj46w906r25ju5aewgplujeau7ytvptyzmztr5", + "account_number": 592, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", + "public_key": "cosmospub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk386gge", + "account_number": 367, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1qy0qwzljplfauvyhgayw6nxte2zxujh4tnq09z", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmxLLOUynbMtTvVZGr7uCfonEFBwkGFvDK6KWgnIQHmt" + }, + "account_number": "364", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "15991078449" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384290305", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AzKvVGnnfGTgV0kcCJtg0X0MRK782Ad8OXZSDjfexm+a" + }, + "account_number": "294", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "18560225561" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382597370" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1q9ed2n5wvzcrymaqltypazqzd2xv8d5aw58flt", + "public_key": "cosmospub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcv6nt5f", + "account_number": 235, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxSGiSW7KWQfHOqY3d9SqFnDr0BcQT77txd2iNj0FcFo" + }, + "account_number": "561", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "19779982592" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382580775", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A2guY1n6F6/cJVl04VWd8rZ+VmzEkRpSH2PtvMnUIzmQ" + }, + "account_number": "714", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "19372177963" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383817284" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qdzgpyxu8cev4wjz9e567nfdlc2cru8ygy9gz7", + "public_key": "", + "account_number": 690, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ap1p4gE1BbDNY8TEiiLY2ONiDCxM7xfMMeA2JgZS2fKM" + }, + "account_number": "832", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "13273656975" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383758174" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A8jFXOI72LStcMuG7KmHjfvcZ6bwI5IWnO5BI/4LT7+v" + }, + "account_number": "453", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "16609259804" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382587419", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", + "public_key": "cosmospub1addwnpepqwstfpc6n2mx2kwfz0p6cqcp2d4am2xavsgtdncu3aqwvuvr8672z0rjrvk", + "account_number": 188, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1q0cw6hmrm4myx5c3zzmw6deelygsl2hrts2ju4", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A8acbo9MomVT/Kt+NmCBTsefjGsOLOoCdTXE52eL/EYe" + }, + "account_number": "391", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "8276558209" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382587682" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "public_key": "cosmospub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghkumj3zd", + "account_number": 127, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", + "public_key": "cosmospub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgyj6etu", + "account_number": 338, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", + "public_key": "cosmospub1addwnpepqgvt8hk8ugsx3spnywmwca23g5n2mefgl9wqae5apg5c8rfjqejczfj2c2d", + "account_number": 841, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1q3mptmfxfd03myzy847p0mrssqw0sh006086eg", + "public_key": "cosmospub1addwnpepq2c22ya9l2vg3zdlw4s92cc95t82zela03cjewxma2dylwgwhtf972cc8v5", + "account_number": 605, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", + "public_key": "cosmospub1addwnpepqdhs8x9jxh3zj8x9khc8mxzmschyuglut7qc08pgnsvsez40ejvagefk52j", + "account_number": 668, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ArecICb+Dq/DKH3tx1VLm7Z6RaOSbKSeRQroefKYO5bo" + }, + "account_number": "602", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "23749174959" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383166471" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", + "public_key": "cosmospub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpve6zxzc", + "account_number": 120, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", + "public_key": "cosmospub1addwnpepq2yn5flk79h6vhzu7xp0heeklwgkac6whhz9ezkvj2k0920k58qvqnsw5fk", + "account_number": 78, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", + "public_key": "cosmospub1addwnpepqv4645lf2dka2qs2renc2n2rts24k9xfmxnx5fkhvj3squp8nv5ugt0mwep", + "account_number": 242, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qenyuc4ljgvkp7g2jhg274k2uzcgdc4vdzfr7z", + "public_key": "cosmospub1addwnpepqdfv5gth68zqmx6ma2ukyx2yskt2wy93yc6n68whzvqe0te49r2gzxnj8l6", + "account_number": 599, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "At7U12yVspu1yjfrRx2nSL8pPxEc8ruMzQaUbZmM5YvM" + }, + "account_number": "265", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "12131214825" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382598342" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A0BfehdLSU0AHc0bIYhTJPVgMVClEXPJY6Ihuy1ybBjf" + }, + "account_number": "246", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "12074854154" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382605308", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1q6eeennfulay5kz3lym38up6gq5ruf6h43cg94", + "public_key": "cosmospub1addwnpepqd9jg6thjt2qjfgak9v4z8yk9alj7c022mup6uqf8pstxp6dfhkmk6vc9kn", + "account_number": 911, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1q74af09jhrvg2ntxvcfu7pdn4zmhxyvlgahaj3", + "public_key": "", + "account_number": 322, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", + "public_key": "cosmospub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvwqy5vcp", + "account_number": 54, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1qlkz3yutzuz0el2ullpyyaflfp78x8rr2cgld7", + "public_key": "cosmospub1addwnpepq0z8s7cuw4zf43uw0gnqlnk7wf4tus2vxyfgwe07gcqnldx4taw9jzf09gy", + "account_number": 402, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1py3htj8kmztj0ecdrhcgcmet6vupr9hvlhxkwe", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AlfsKLtw+wMBuslY6UW5lTsyTkyfm0d0r0z5lIVf+303" + }, + "account_number": "656", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "24014084679" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382616874", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Asw7B41F+XRDj759NdvAf2AO06ZUSeHOdNpkNTdHFXO4" + }, + "account_number": "853", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "17454514646" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382594761" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1p9wm55eaeux7v9eqf3szfqt77w70djrj7wpeh5", + "public_key": "cosmospub1addwnpepqgaxl8yk35t2yefh2j0wntqwzynu8ques0zaxj2dqga6yu04zk36vjqlhxw", + "account_number": 715, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1p9lzwaw02vs55dglhdr3dldmkwgm4km9shedwl", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A8Ku8hTgFQVM2eYSVqxwfmyAcpvpCI80ki5ObSRM7qCk" + }, + "account_number": "795", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "3198654462" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382817884", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1pxwj79qtf9y8jugqgf7vxwhvgd85vapq4ndldk", + "public_key": null, + "account_number": "606", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "10355479768" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382589233" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AjrfFU5ZJ8vsoZ3oogSn5uGlQ/RWs9ue9ZxDwBqN58gG" + }, + "account_number": "373", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "19201518243" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382597950", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", + "public_key": "cosmospub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwdxny57", + "account_number": 139, + "sequence": 173 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", + "public_key": "cosmospub1addwnpepqgu3hhq5qxra529uses54z6mnfxgdvykhx3ervqzf5mv43xn5e7py020px9", + "account_number": 527, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", + "public_key": "cosmospub1addwnpepq2dcqs6jwgqs06hz297xdv606lcyx76wnyf228c98wsnmrarnjg7qz0w2s3", + "account_number": 529, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1p0sp7r6mzt05772xq9eqg47rvssgxhf4ktctah", + "public_key": null, + "account_number": "461", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "4151971935" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382613494", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A9Ct90Z1DpXu0DRt5ljvdpOC45vNBPu+hCYh1Nis0ojr" + }, + "account_number": "465", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "20282066246" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384538442", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", + "public_key": "cosmospub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q2qcdsnn", + "account_number": 89, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1p5h9hzhyeske3uwhsf6k5nq38r5pxrejpjw49v", + "public_key": "", + "account_number": 259, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1pca5ng2s37clfh72ea806j9fwvpng4fjq3ey5s", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ApaO8ii3BOaQmTuiTa2myEPn5fSMTEbtzg73c9WYr5+a" + }, + "account_number": "618", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "5641576477" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382594452" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1pmjfpv056kk3jk3qfljph9fthrvqtufxe3nwml", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AuLVZvU7jdYyE/6DTeaOy5K3Efzk9BzNDb8w3ShooyGT" + }, + "account_number": "357", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "323583139" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382606410" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1p7sc667drjvsjlha0nwz5zxxpt38m9dn50u925", + "public_key": null, + "account_number": "301", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "11307273438" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382600123", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", + "public_key": "cosmospub1addwnpepqt032nytxy3x5xdysx4nyqd43jz9ty6she7qzs8ng7tjyy2rnrstypzepl7", + "account_number": 275, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1zzca9hed282xcq9s7v69ysyyjls42ppxp37ywc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AlIiNO5qErfs6liqTWVSyWpn/wXsQGfGSCPaHQlhgvfZ" + }, + "account_number": "462", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "21178724" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384651288", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", + "public_key": "cosmospub1addwnpepqvfjj8axcs74r3vxh3lclw7upds6cn5ru6ggy2ptzjsp4e6j8racwdlek79", + "account_number": 65, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A23i79DyZbd43mFdBaUZ0szyFZ+2dAe45pu0YbASNM3n" + }, + "account_number": "703", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "9719942655" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383631006", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c", + "public_key": "cosmospub1addwnpepqtlevdnat4yy9zcjfyfq6ms07gxsx9gwc9fnnjjps3pxqvpfkassjwlx2sd", + "account_number": 742, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", + "public_key": "cosmospub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zyczqa7rc", + "account_number": 189, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zyz0twnwwk26pwn3w83d2lj7rda7lfr5d0m64v", + "public_key": "", + "account_number": 616, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwAnLopZSFC7vYpVB227OX5NUcyjFyi6nGCorlXK3fhP" + }, + "account_number": "893", + "sequence": "7", + "original_vesting": [ + { + "denom": "stake", + "amount": "2045484002" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383363912", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zyu5csqfxaxacgwegnhrysl0val4t48kfhj9ws", + "public_key": "cosmospub1addwnpepqgr62hm3rqc645prkl55rkd6t55dn30efmml2en9k4nyya7500f9sq6086u", + "account_number": 499, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1z9ns26y62x3qd3d8vs9eyxk8ndssa6gxtv2c06", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A+/Zuh00Dq+H3yoHkFBGXIZf40x1p0H/LVnneja/uyUe" + }, + "account_number": "712", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "15326381025" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384689508", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", + "public_key": "cosmospub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwsm3dn0", + "account_number": 11, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zxpp6x3x0p0gcuuazft5ycgrxsa5wwsgl854uk", + "public_key": "cosmospub1addwnpepq2nrkgu970mta0gwsxdmz6gjvwwn2t27p9esend8p2pmwu3fxf4hynnl276", + "account_number": 638, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zgsxapl5dwq6c8nf7hjn2qa7aytg0m365jhs39", + "public_key": "", + "account_number": 635, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwoJuQXE3s0qMHmxNMznYmcd8gS6lftRSlzMuvSorVf+" + }, + "account_number": "433", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "21133346450" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382601763" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", + "public_key": "cosmospub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2naelke", + "account_number": 213, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1z2ynmntxdesahja6gh76cunudwfmrhgcx7krhv", + "public_key": "", + "account_number": 680, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwIX5o1ywVGfTp7GlnalU04MthNeP+D3ckZwDDhR0D6+" + }, + "account_number": "847", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "16423278953" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384247065" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AylpbFcBoPjJhzjj7WlFMR/XHwnWQnZWbYJYImf7aBYQ" + }, + "account_number": "537", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "16374404528" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382602799", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", + "public_key": "cosmospub1addwnpepqwt7h659ckadre4vsy98aw47wtrrrfyzpqsgqxy46h3j9c9dvp05jrkkg5g", + "account_number": 274, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", + "public_key": "cosmospub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgce604x", + "account_number": 62, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1zsspke0nqudcl0lh747ppqcsy396245akc2vtl", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "An+FohdUKtKMThLp3iKxISxZGHvc/YM6ajPv30KoFw3w" + }, + "account_number": "912", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "3378104205" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382597949", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AjA+BkynDT2bbzPUa3zqTJW3CRGkB8mGwdKMPzgCo3B6" + }, + "account_number": "287", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "10941659131" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383414945", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", + "public_key": "cosmospub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw5m96xq4", + "account_number": 16, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zs6hn5hf6qxjwmvntrzwhjkgvu963d0g8hz2z8", + "public_key": "cosmospub1addwnpepq2dyjl2cke8x058new73pnls3uj9pd2f7ad8nekyq5t8743k6xfqklnacgl", + "account_number": 821, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zjzkk7l2jalrspy6500my8v0yy6ycz7el534zw", + "public_key": "cosmospub1addwnpepq0x07aykzgfl7xjmd49u0dnc0xc69xv3cftdhly8hgc7y3djgfpqczjpld6", + "account_number": 97, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", + "public_key": "cosmospub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavhe7sun", + "account_number": 4, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1znvq8jqpwxt5hk2lg5654l7eg7kap3rpgjm462", + "public_key": "cosmospub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tu8dxept", + "account_number": 22, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", + "public_key": "cosmospub1addwnpepqfhaz3cwkjvqxwcgmpg4h52j5ta6tnanf0ngtkcreptep0al8vqdqfxj3hm", + "account_number": 46, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A4/EkwUQxvneHuIjAUpaqj7uy0VI31jrM9kE2fZ91eGj" + }, + "account_number": "603", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "17008905034" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382619751", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1zc80fmnzrxu2ksxugtpa2vtkh7sstkqh6yn9de", + "public_key": null, + "account_number": "374", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "17694130941" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383478253", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zcjpltwefj47au6pkrysjffvxq46a8wf4w57nm", + "public_key": "cosmospub1addwnpepqwy30hc84s6fc3dpzg84jxghuzt49rmgvjz9c09gcqtdsj0ed3wmq0wy502", + "account_number": 434, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", + "public_key": "cosmospub1addwnpepqgmgstj32dm22qll893mgf9u8d997g0w5g0nlpm3jpa7xec29h9hgyfkjds", + "account_number": 746, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", + "public_key": "cosmospub1addwnpepqghfgrvv86d4rtnt8zqrrmnj8vqrm75e4xsl7wr9rww7tewvzj2py8hf39h", + "account_number": 609, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zu50umwgah6jhx07sw04ry0pv7fnvkpjmn8vl9", + "public_key": "cosmospub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jd88e58", + "account_number": 135, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", + "public_key": "cosmospub1addwnpepqwuthwk4ulyfx4j6f8q9ql4cwhnu923da4m63sg3n4hldpa2rzr2x3hkkwm", + "account_number": 172, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zah0g92ytwdvpchd3sceuanu7knhtu224vnt5k", + "public_key": "cosmospub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgvznvre", + "account_number": 137, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ak5pG+GoZjwcfODrUPRiK+Ud75A6ckFSIS5sXaZ2rtE8" + }, + "account_number": "639", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "9307136339" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382918615", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1z7ruhrtfg8v2xv8egfyxldt2xaygspykszntzv", + "public_key": "cosmospub1addwnpepqd45mshdzdsn0zpnemh0zghvu25ukrxkn9r0nk0mc8qz44k2fpdn6xd6ane", + "account_number": 619, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1z7sj5sg2cnkg4phzrswwjkkq8p2d6434pcyv2p", + "public_key": "cosmospub1addwnpepqgm0kt3s90754tqnknjvrhxpqvgnr8k4jjzzujl8p68erlluacplw79j5qh", + "account_number": 545, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", + "public_key": "cosmospub1addwnpepqf2ugr68h5nt2x6k4c6ag0f69f4ey80uv5w4u9ludsdpdtrhw07lvs3geyu", + "account_number": 199, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1zlu0kkfr24psuwq54mzdtt7uk7068ameyk8hug", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A8JIkX9/GnENJD0u2+xS5SOysMxweSuYf4/KihulMETr" + }, + "account_number": "487", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "11242547373" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382616560" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", + "public_key": "cosmospub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yvf0lvw", + "account_number": 177, + "sequence": 9 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg", + "public_key": "cosmospub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2dvq565", + "account_number": 207, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1rpmw7y7cw2cu3kwsryy8z8uskn4eymh89hmq5g", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A1lbwhW9UvyBB4zfaD+KzN5K/+sA5elDtbykEe2j9Cvn" + }, + "account_number": "861", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "6569291679" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382892388", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rzynfn4000ww456my9ke4jf72q306sp4w8qs3m", + "public_key": "", + "account_number": 611, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1rz3n04g9vg0ygh3h2x96wh5ceq44pcjmt3lgag", + "public_key": null, + "account_number": "874", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "15150073021" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382584957" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rzuu7jf5f66jyhqjsusre7uuha0hw5e8ff7tar", + "public_key": "cosmospub1addwnpepqfptqtt25tnasc5hjvfl64gqm79l8d5kxkxgplxy5x4r74jmthr7q660k0m", + "account_number": 899, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A+mnj8+qhScj10/SOH849GYuEzK1w8ow9f3TU0votb6t" + }, + "account_number": "380", + "sequence": "7", + "original_vesting": [ + { + "denom": "stake", + "amount": "3868847355" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382583987", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rrahhju34rdpmlnaww9r5egq0su2u6f44eve27", + "public_key": "cosmospub1addwnpepqg9x5hm4v6l3wx5ehy3jjpzhusclnzfqqf74qpehunhu4j5d865h5t33lcm", + "account_number": 835, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1ryp2xkqe74y5kx6zffqtdc3wzgny8xg8eguupq", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A9O9zz0BkCnefcEYcijJcfMbKzX942XDGMgtmU2RZ6vG" + }, + "account_number": "271", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "3707562566" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382593045" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", + "public_key": "cosmospub1addwnpepqt8n7x4t7x2kvd3dr00mfuuemuc4spvhdt35g05vatvjpfvw5uww57y4tgr", + "account_number": 205, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", + "public_key": "cosmospub1addwnpepqvelvh903wf0ufp2qn3rpt50zlv3ffp0n767urfar7af9jt0ng57k30q55g", + "account_number": 813, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1rtw2ev4xm89vaqzwc7k520jlvrvlqnevk5f53y", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/9/EfVe14EyYvrmu5KAYvbTVWKe3LKL2mXvtvtzp+nA" + }, + "account_number": "660", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "5762646824" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382602892", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", + "public_key": "cosmospub1addwnpepqgmdqzgfkwp0d39hlj690r9338gpflvzfvcv8vjhtq2ntv8g6yhvyxt2m79", + "account_number": 249, + "sequence": 9 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rs7csfnnwetmd2dcjsv4p59w3t46g77lt0wq5l", + "public_key": "", + "account_number": 384, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1r35ejcqcmv94r87zwrx4xngsutjppj3yx280jm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Aw7zQ8konZtNR5Jt9FQXGf0cxBl4fC9kfkAFNvSfGCB0" + }, + "account_number": "770", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "14105664945" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384805407" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Aiu5nlas+9+2JIcjy+sT2GBopsafjZHGZDfwZIvfROjq" + }, + "account_number": "393", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "12068860638" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384240724" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AquoGxS04PJvUF0cROt2eZWOkzYrpowIjEWOG5h9W9WA" + }, + "account_number": "590", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "10793715881" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382601156" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1r572vr0k388gpjw5h2u75ppmarvgma20rqj2ws", + "public_key": "cosmospub1addwnpepq0dwzc24j2j76srsg3dk705j73p26s985sckn34g8d85m49nz2mxq5fmge3", + "account_number": 566, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", + "public_key": "cosmospub1addwnpepqdn6uzyl56y7nttklxx49wtfnz925n96ut22xx3s7t8hphp4mrh5gmv8stq", + "account_number": 74, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", + "public_key": "cosmospub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jcmrgh2", + "account_number": 108, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1rhc7hrsjmzlqfz4n400j53ztytqafe9qqqq38l", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ai/T3oRkESImnR/wIYPQRrZquUWYnPrZgEN0i1Uispor" + }, + "account_number": "514", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "21397083756" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585616" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", + "public_key": "cosmospub1addwnpepqduhk88juvx02jj3wm9l47qzf7xhfufcucf2z3zhdsvynmqvqpppyxp4nf6", + "account_number": 497, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rcru2vteas2kunww3zt4knx28krlestxydpwza", + "public_key": "cosmospub1addwnpepqv2std6eyvykrswpyvs6k64fe0nxngrh6p3n96j956uhfnehn3trw36cs5q", + "account_number": 463, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1renmf3hfgfq3p7wzenfa45alrhtc92f9geghu7", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "As8H67414cjhDyfCh3YXJkbN7/bRl0xUzOVYXUa0rbEL" + }, + "account_number": "331", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "10087834154" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585271", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", + "public_key": "cosmospub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5neagtj", + "account_number": 136, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1r6j2xkpnnjve9c00c854laqp7l7zv8pxeksxrz", + "public_key": "cosmospub1addwnpepqw29w9fxpsx87s4zlpx8wh80nx4hpm5793kej5lr2xjj4dfen87ms7nfyjw", + "account_number": 522, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1rmyk79ktv6c8q48u78udw5p906fp0w058796d0", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AzUjU+T3olsA63SxGeZGQQO+sTl3Q7pLT54r2V/4T/nc" + }, + "account_number": "399", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "818342307" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251385156802" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AvCiAefdh/pBQp1X34KxqaRRr/kMrwk8nAtMR+JBVvBP" + }, + "account_number": "565", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "19919188059" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382594294", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", + "public_key": "cosmospub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpq0tnmv8", + "account_number": 159, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1r7kh63jvjhwqraux9wtm3jat8ggm437w9cxcxc", + "public_key": "cosmospub1addwnpepqtje4agendhh34cze964xcknahtyj03ung7v6k9f73rdpvv435jkztydcwa", + "account_number": 862, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1r764cqpxtae8ed0zyy0v6sxut9dm4fuqj95xgc", + "public_key": "cosmospub1addwnpepq064pvv2h504yls65tm9s8uchpekrtur8fzrrqls7p20rdn0ga8755g6kf9", + "account_number": 405, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1rlzurkn0mywyldswcafhu7r8r0tha4s5prs34u", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AzLFWy573WjvoAKs3mANqQ3N07ChH3pHfybDcZZmoLYn" + }, + "account_number": "442", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "13544919961" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382592037", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1rlltvm5ks32kh683c0w7epsjvg8aq2hvct27p6", + "public_key": "cosmospub1addwnpepqdzy52g8msawc0kat2egte3fx2z02trjsl77u9dz4xxy9y60zge5wj48gda", + "account_number": 571, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1yqt74740zamtyag7qu9naqgrauz5wdzl4290wt", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "At1L8wk3va5ZQ37ta+pfU0NN7xHUuDkpwNz1gUoviwNv" + }, + "account_number": "450", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "24610806346" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382615405" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1yqc7yxdxgz9etrp3avxg8t6ppfm73wxnzyf360", + "public_key": "cosmospub1addwnpepqw20j4ku4csznlvaxwlkxjd5dm93w9q0cvwpwkqrpm253trhzzevc75yhan", + "account_number": 833, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", + "public_key": "cosmospub1addwnpepqt4nq6de8f6dhcg3wckrz9f58vpagjhq6hp85hzf4e8vgxxm6zx2x22pp5y", + "account_number": 552, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1yrdtzqfkyum94q4v3j3xllrtf09qv0jvympw86", + "public_key": "cosmospub1addwnpepqv53053cnvql8sp5lyptdrrd2dh7ddl5ad9q82tk532ayyjx2lgtz0nuef9", + "account_number": 408, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", + "public_key": "cosmospub1addwnpepqv2xfr6pcx5axa04hegq38yjvz5wm0lj6nkvexrzlxe7lga96sasz4cttgw", + "account_number": 100, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1y8jqa6t7g9m9g2l5u7m7lvm36pj4ssqyas8vdh", + "public_key": "cosmospub1addwnpepqd6w7k27fsjpuxkc5xq7gyytx3nvy7h3037qhhkcuw4t85j84uz2gs33ya0", + "account_number": 670, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1y2whyxm3k2mtz3j0hvjev7ztq8q0cz0vqrphgt", + "public_key": "", + "account_number": 512, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", + "public_key": "cosmospub1addwnpepqvhgqx90svcvk6htmhwpfudunnc0ne989y7ymdyltcssu7n3p4kw5qt76vu", + "account_number": 745, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1yvn8kgpuuepzefm90rydcladzwwqa9agadsyus", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A2rrXFw5WPGvlYPBD3PBQcZ4HilTAK0L7d2GS692F54y" + }, + "account_number": "701", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "12294556362" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382602733", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Azxeq692AFsPSt0JwLDHVv5nGdq5vYO0n6rGk9lO8y8X" + }, + "account_number": "843", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "15405600669" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383534110" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ywe4qsw399leu3wza5jpny3mmrs69a3gj3hlt8", + "public_key": "cosmospub1addwnpepqgn8ffnhd2tj3w4kf7vzykvts2c25hedmy6m8zzhxs3h0v0jnfs25rwvkjp", + "account_number": 563, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", + "public_key": "cosmospub1addwnpepq06lz2fxdcn3tph2mnllznwszzja7vtlpm36t97zgrsycq2mdsw5qh08ptn", + "account_number": 30, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1y3h72de80x06cz7fs3adwlnp0r8pjazw0r5707", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AoO6m7BnElNDbo08fsLR5jftHDh79N0WElUWqXkBCwwZ" + }, + "account_number": "771", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "7070821988" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383121840", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1yj95f65syc75ptwcy0n7kafdq33awc2ve8hthq", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AuuL56D8+Cv/t6dN/R93o+9C7yVtb9f5//OiKeP+83/b" + }, + "account_number": "831", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "15482923369" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382604027" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a", + "public_key": "cosmospub1addwnpepqtuw2axfye4m3vrjyu733k608nkh57vj62zx3ew7uzpf5lejemapjg5jr50", + "account_number": 143, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", + "public_key": "cosmospub1addwnpepq04m4crs7rhxhslqgnakermccrsunsp5zty5awqaevlxhl6amrnq7c3arzc", + "account_number": 509, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkJdsNpEm5FNTEmmWVvS2rg9/eYjFxIjVYPiQVkhuNd4" + }, + "account_number": "558", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "14579822792" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382612048", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", + "public_key": "cosmospub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc2mcgegr", + "account_number": 42, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1y78hvz86672la4agrx7n6lcmgjfgegpkldazmd", + "public_key": "cosmospub1addwnpepqv5kwv0ddfvkzl957cq5mccpjfe0umpt3ypgem267f58k4cmnsnyy0n0xz8", + "account_number": 880, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", + "public_key": "cosmospub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u6axq2m", + "account_number": 112, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1ylf26t6vhvugawg87328ng2ug4d8f25syxp64c", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwPAnsxW9g7JMHn7aBycPbHHNiqJKpe7hcxtRAyTW9Gu" + }, + "account_number": "800", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "22972055437" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384511147", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", + "public_key": "cosmospub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d229ej4r", + "account_number": 240, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ang5poSntZZi8710ftJ7YvH/9JAh5pDS1EaxrnkFcJG5" + }, + "account_number": "244", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "16030340306" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383385496" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos19rlals9yl7q50rfww4n70m26vna9envvsqj886", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AsXFcdEGEsyAbHLnnAjYBOU5p3+Ob4uWDRvowMzfcusF" + }, + "account_number": "344", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "8580085181" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382588197" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", + "public_key": "cosmospub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgsltf3w6", + "account_number": 122, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos199mt855sp3pqqxarqyjffjgm2v6uzru4fhslp6", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AsTA3MV1yYLXp5UsBMM63zmRMjbGRck3mjbf1DeYQ/Mi" + }, + "account_number": "445", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "3063048900" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382592855", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19xyafr0fc2g0rvemhmruyj8ywas8qamfnps2zx", + "public_key": "cosmospub1addwnpepqdtshp8mmye2xpryf4u4xa9r8x2kvkdgpd65ek0gxpzgy870g9j87xtzexx", + "account_number": 361, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos198k0ah8pnjzthydgvnq30s24s8jd3wad6puc3q", + "public_key": "cosmospub1addwnpepqwk536xvr3zt636maqukru49mcw4tpux4gx5eva4suyllphkyhzkvjpzpq7", + "account_number": 538, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", + "public_key": "cosmospub1addwnpepqwcgreqxwc4ws8pjkut4e8jrjtym2sv7fl3am0x6678xtuhl8hsfspm09ev", + "account_number": 477, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ai/9xHH2C0BEMXMGdJnH2xjVyitl0N5cSBXqqJyTFpL9" + }, + "account_number": "272", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "23749732992" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382609053" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmhKqR5/6XEZdPl4icm/FOW3uOgwNF0cQRodxUnooAqb" + }, + "account_number": "631", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "1341493520" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382621064" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos19tvzgu6dmna8qljv8ex42vpek4r2handdn09d7", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/NfHryvPeXxQt+Z6uvgkhAR6RYoZKLVaCD+uzwA/ajt" + }, + "account_number": "804", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "15400521236" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382587861" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", + "public_key": "cosmospub1addwnpepqg2e2fy2hl6cn40sx780nvd228x9u40cfcpjvdnmn3mqfapyjt3m2mzkpvv", + "account_number": 87, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", + "public_key": "cosmospub1addwnpepqge9z0fefq3xpf8y4q8j57c89x65luk2vtcx5mln75662ukq00f6s04clvg", + "account_number": 585, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", + "public_key": "cosmospub1addwnpepqgmnkn2nw2c6m0s6nrrcyxksg9j50sesj03xzxa867yvgrzw6rhgjhe9ej6", + "account_number": 55, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Av0gT1zLvxZABQuhuDt2eG4cedPvp/KlrP/xwGOpDfva" + }, + "account_number": "901", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "24871225862" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382609607" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19deqn6g9q7mnhzg5j0qr25k9gz74pwlph5p50r", + "public_key": "cosmospub1addwnpepqvqtq2puvhmk7g8aa2fzxkjrjrvq2hfczxjcvfal8gtzjm7tts96kh32s73", + "account_number": 443, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", + "public_key": "cosmospub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwulkt0xe", + "account_number": 164, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", + "public_key": "cosmospub1addwnpepqwvdjhxcmtkq3y39crkc6ue3q2xdgct97gggllt8a4wyuquyf9u26lqyf20", + "account_number": 51, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos19szahkq3g937j62shd224cdtla3dv8rcwvekj9", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Atmfr6tk5qZtMMfGYzf6bEb6hAKyXw/FQtQ93s+cLhMv" + }, + "account_number": "914", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "10021547629" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383470555", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos19stzlsklhmx4akvnq7s2jvl828hrt6zdm6dhys", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A1NLLSC9/7tzys8OUTkDGGHBlRbS1zOrThR764azQG9b" + }, + "account_number": "671", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "14889404486" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382599490", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos193pvwgxpxnd6tgz0gtyl00dq8r3ygeflnhaxpm", + "public_key": "cosmospub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22kdmtv4", + "account_number": 174, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19num42c3egx8a4calkn0pz9qxaay7svyyh8vfz", + "public_key": "cosmospub1addwnpepqfq5uqj5at0tnvnpdd6ejla6a348n44j0d89cnxswghgetrp9kwhz44h05z", + "account_number": 845, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos194x33ngarpaach5g69g60cd2pjq8h0hqkfvk35", + "public_key": "cosmospub1addwnpepqteyhg2k2hn9lyv0ydvaae5gy4azvwyhvetpl9ctzu2gflnvp8dyxjfp9td", + "account_number": 755, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", + "public_key": "cosmospub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7k7xepp", + "account_number": 116, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos19ehwyhhnu55mw9d96929sus947zw6eee4ue38p", + "public_key": null, + "account_number": "576", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "10669949438" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382591784", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos19akemnyuu0rgf2y0rrd6wrxpkyd74q5gzkgm5q", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ahl5VXPKdkiUXpoyNQfSVbPlzgTmoYJKQkoeGsixsBJk" + }, + "account_number": "317", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "13798860848" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382599118" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos197wzfp3g9xq92szucsjce5qfd2p4nrl5cj8lz8", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A5SQ1IUvBfNdSpLKiNZDZSqGkFwgmsh5TV1Tc8omy4G/" + }, + "account_number": "677", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "6679282515" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383494332" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos19lvag94alj6tknd5jxjku46qq330x9r5aa7h6s", + "public_key": "", + "account_number": 812, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75pf45v0", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AoFuxTkv/PJ6muMvOzsvwX0Mih4SJkwS4uVDSEYVCS0y" + }, + "account_number": "683", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "11230513351" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382618456" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xq58llsgh49tsz22grs28jk0p7tvswlcjcrl32", + "public_key": "cosmospub1addwnpepqv8t92hg5h8d39cmznd7xfwudv744yj782rg7jx6utajy3xyzfypg6sns9g", + "account_number": 892, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xychruegs8u4cd4s3l7tkcc23ev90zydd4n92v", + "public_key": "", + "account_number": 319, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", + "public_key": "cosmospub1addwnpepqwpunsvkz6dm8s4ngxsnzrk4hhlgtg92t2a0wprx9hyrxgun9nn97mj868h", + "account_number": 763, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1xxurm2uymwd04sjxqedjae5r0zxhalh26skxct", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ao97MTAU0BRgKLfKhe5E3faYNdfrlCsasDATyurI8wND" + }, + "account_number": "346", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "17450447338" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383588030", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1x8z2epqz2rn6eknljym3ddjyg0z9tgtldaukjd", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A66yHvf0pW6YkPuxA1OfjV0WpfGgo2w3zJX7QPNDGkK7" + }, + "account_number": "424", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "11875627180" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384530535", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xghyawtulyzs449mhe8drctaaxnmdnmkd90yx9", + "public_key": "cosmospub1addwnpepqfj9ar8t6crdlv2ytmapdjl5my6j6yt08rgt2hk66gw43tslkflkklqyxhr", + "account_number": 533, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xfqsntajat3kv06ptad8zsqacmjrsjc2sa5ajt", + "public_key": "cosmospub1addwnpepqvn9lh70feerf3cjcmcxe8gxqqewppel2legf2f4t6v05sf6rwm7yuundjf", + "account_number": 570, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1xfps7nht3lsfdzp092ast50aev4nhkaxtf7gh7", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A5C4vigREixYQyMAjg8oxG7BwdSQN8jZ1qFDzqALTOok" + }, + "account_number": "632", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "15162979006" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383339833" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalavv03x7", + "public_key": "cosmospub1addwnpepqd9rxlxauf0f8wdquzctrg47q24aa3n20rel24g7wn8q2xyyy2cmwndj8kn", + "account_number": 307, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xwjpulj30k4y0smg9krxwx80hk83r3zhs48jes", + "public_key": "", + "account_number": 332, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", + "public_key": "cosmospub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5e57xfg", + "account_number": 593, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AzSQZOMkAgucowy9oxlwqi8EgdCMVFGQVx6wRASxqN6g" + }, + "account_number": "780", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "8642534120" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384717213", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1x3u97k0k8xxxjvt2vca8fy9g3qm7wtgp8wtmqs", + "public_key": null, + "account_number": "485", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "23715398268" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382593856", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lpz963de", + "public_key": "cosmospub1addwnpepqgpthjaszzcvylsczd42sr0lhanxdjkx07ec2r0g27mpwcmw55z0vnz6gql", + "account_number": 320, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A8Oq6E/eilRyTVY6zd6gluRNVfWvaP3XqmXRu04orWTa" + }, + "account_number": "260", + "sequence": "7", + "original_vesting": [ + { + "denom": "stake", + "amount": "727021434" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384488508" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", + "public_key": "cosmospub1addwnpepqw4vh38c7e44vpvszes4lcvjkz3ah25sja3jyj8a2jyfk44fn033xys9zxh", + "account_number": 620, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1x5tgg6j5hqh0swtw3wqymfdcju0mmy2uff8zee", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmS/ygIryBg8MznRY5EnBbRBl6ZPuoD7Tct0VSzqrkun" + }, + "account_number": "395", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "17917842626" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382583601", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", + "public_key": "cosmospub1addwnpepq2yt8nure838qnxhq7fygya55rxvx7z0jfga4ed4c0nm6xuc89hxvyy2r3t", + "account_number": 382, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", + "public_key": "cosmospub1addwnpepqt4hew3dkv9ytm47sg7767ktkthyt4jqgednnvcnhnzqx4fznylc2peqxrs", + "account_number": 140, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1x4u73wvuayr5w5gfs96jak2nrs3k4r96tknr63", + "public_key": "cosmospub1addwnpepq2fyhe0cvqmsj022qm5ss4ph3fselmkxpuruhh83vcm9qemuj03jv2mr92p", + "account_number": 741, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xenmhldpnwfl0x8ze8qvu2qc4v58zr7qkz73sz", + "public_key": "cosmospub1addwnpepqwnwchhjxrz9v0xlwrnp6x4ewsyv2gmc3ys8c565zpskc6dq0qy075z6uh4", + "account_number": 856, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", + "public_key": "cosmospub1addwnpepqfvnelws9nysntl02t3hn42jsvg37krjan0y9ef0ff6qvyyeuflqx58a9ks", + "account_number": 49, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", + "public_key": "cosmospub1addwnpepqw0gk7g6ldfltzcg4evfrv6g75hp9d9raerpg574606nwrv8zy8fsnccga9", + "account_number": 13, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", + "public_key": "cosmospub1addwnpepqf5qh85wpx6k2c76xt38sxea46jc7929269hg8x9ddjeexhgrggjsva2td0", + "account_number": 38, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ax4Z9/Vx7kaEEWEaBEjb2YXhIUgv4SozLWSBELtLIFLc" + }, + "account_number": "610", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "8972475158" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382583060" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", + "public_key": "cosmospub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057n2lszz", + "account_number": 33, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AthHloRJ++zad/zcK3NvcukZyMZztPYvPgW4t2BLpGrX" + }, + "account_number": "476", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "16963604024" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383989413" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", + "public_key": "cosmospub1addwnpepqv368hqruqrftx368wx44f2uaslv95nk3dx7mahejcnruuqhfx9j5l95h56", + "account_number": 773, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18rzc0m3vlq3cwee4tckg5grjjc02gu3dv9csx2", + "public_key": "", + "account_number": 482, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", + "public_key": "cosmospub1addwnpepqd265f66tdc7mtewx4ayd6d4lls7m4ma9eehyac8s8jn93gxkw0k63lzqfn", + "account_number": 106, + "sequence": 10 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", + "public_key": "cosmospub1addwnpepqf4ddylkupthgx8vutwclv8y5m3e5yzya2xsl84hl3fhth7y5xdm774pxrf", + "account_number": 747, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18xzukww2e9ufj2ae0ath48ul8ycfyv9nq7h362", + "public_key": "cosmospub1addwnpepqw0az8gndyp5xhrfxn2n9n8m2vjtjp43dcska4rw9pneucsw0ucfud4sd5v", + "account_number": 293, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos188yd2umzwfwen7es68wrlh6auu3p8jhz0qfgej", + "public_key": "cosmospub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef58yma3y", + "account_number": 60, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1884glx2vk6nxcurpf2dtjp3qgsl8zh5pm09rs0", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwD4CBQtiWlXr1PVrAbb8qm6VMAQ4u/l+9WzPS7uNRwV" + }, + "account_number": "581", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "6114761282" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384276183", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18gmd4r8ydls55yvgda4d8pfandk0xem5q7eat8", + "public_key": "cosmospub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwrjdttf", + "account_number": 206, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18fp6y4z2ze4tdqn5ghl70erq5wpe444p548y5l", + "public_key": "cosmospub1addwnpepq273na8xr4a7kykxadftya2lk05vxupfl86ylpjjc2a25flvgwm5qq2xj6y", + "account_number": 535, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18fxku8d7wa5vjz9ta2xr7asvdfdrqnpdjfqpe5", + "public_key": "cosmospub1addwnpepqw7yu9urxgr66vmwhaqry4ae68kx9sn3mr5c6gxqly4w4h5hl556qpp6qfw", + "account_number": 390, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos18fkw6s4hnj2llxljrkleetgns2y0h0vjg8kmef", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A7Hr0c2B+RXAJo7cFN6fiCI2PXpKYxatT6MUIirGywsC" + }, + "account_number": "292", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "9381392771" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382610089", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1823pz6pxtqgm8hdcxaysccpyd8fx83hm287sld", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AowP66Vk7yzkgKfcBR2HLVKDTqG9jkSPKK8dnK5VCwwZ" + }, + "account_number": "469", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "3098439245" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382593966" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", + "public_key": "cosmospub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz60kdna", + "account_number": 26, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", + "public_key": "cosmospub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2h2gq9n", + "account_number": 129, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", + "public_key": "cosmospub1addwnpepqgr3yz0pw3dl98dsljzz82u99665wlgyya6ymlhm7vgjypm39jwkymc6j9y", + "account_number": 902, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", + "public_key": "cosmospub1addwnpepq2897we7j0jrf6mg2c7z2vekjpvq4m4rrqpdmpxe7ccnac5smad7zurr5mn", + "account_number": 121, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos18037phaq40fkqdr4pxk2jajnsq8prfyyl4tzvz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkypAK9nLDhiwl/FmwO9FovOj8pXHtV2yRlUo2Njohw+" + }, + "account_number": "383", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "4550939975" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384358693" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "public_key": "cosmospub1addwnpepqvj4d7pjfcg6fcckuyh02wkr8vtz82zttnsu2f7say2pwsvyxn52uehvrgg", + "account_number": 7, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", + "public_key": "cosmospub1addwnpepq055lazk86cjz6r0s6jgcj7454fm7lscn6ylxwq5stu7lxxve6c8zqkwtcu", + "account_number": 852, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", + "public_key": "cosmospub1addwnpepqt0vwa2zcjnfg22u6clrl463zp5hlt7qm6ucx8642styraaq76s3uv5k5pl", + "account_number": 396, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", + "public_key": "cosmospub1addwnpepqt6v4va58n8u0husyys4q2qk258zswwu2m8xh8wq3te6jlg45zcjxewldu2", + "account_number": 601, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", + "public_key": "cosmospub1addwnpepqf26xhga7sa872e20kwjg5wglmv508l9ukcq43k7alqqnjsqq0wrsc547rg", + "account_number": 167, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18k4yz84xrjqvrq9u7sehvje3ax4aspcksauctw", + "public_key": "cosmospub1addwnpepqg5954elsry83raausa5d90y69mvsfv8mtp455u6ynd3feg207vgjc230r5", + "account_number": 597, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos18kcmwj6z3gwmsscam9f04ty3tm8std0mw0upfc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A+rhDXuxivLvbjxAYnXlM0IxERSw4vjiLHygTQPQg/B+" + }, + "account_number": "652", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "1955991160" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251385136560" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos18ku7lzv6a0d3t63d2tsn2x69u04uv3g8sgf8kq", + "public_key": null, + "account_number": "559", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "23535369237" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383554343" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos18h7dxvzs4vn07gfgwxgjsvl7f2nhn4fspaggvf", + "public_key": null, + "account_number": "534", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "13481456084" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384487464" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AoyYq3JIMoiVoPAwLFw68IU/5BZjCY4dUe0bo5V9D3Po" + }, + "account_number": "762", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "598797234" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384470229", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd", + "public_key": "cosmospub1addwnpepq2d0au20k4prd7jmwck4gnd7swhwylcq952x5mscay8h334aq6w0x5msx59", + "account_number": 409, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1864wj4twqatq54rrxl5jmfey55tmh0hvgmd9yw", + "public_key": "cosmospub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazx5wrzr", + "account_number": 104, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos187t4e0t0xwp8ntfjkvec64kcwruph736hqxmkn", + "public_key": "", + "account_number": 661, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv", + "public_key": "cosmospub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgx07fvhh", + "account_number": 356, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1gp93nsn0kdl5qhn5xn2wyqfug6uxu26sfmfal8", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxDZD8ij8yya7mS7Dsf8dL5gZIFJplKnjmmQvBSMBtpU" + }, + "account_number": "521", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "10779047310" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382596023", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", + "public_key": "cosmospub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xw50srmx", + "account_number": 151, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1gy49x7p6xpgdfhv8v9dh8kfgsef479cq3u8fzr", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AnDZBbT9+05xOsfIkc2BxVfkr57G7PkRMSQUg93jMvlp" + }, + "account_number": "870", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "9691091859" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383224661" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1g95xvy8qgzcvcl05fse0mpxzdfv3w88tpexycr", + "public_key": "cosmospub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc928cyfge", + "account_number": 107, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", + "public_key": "cosmospub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wt00mvh", + "account_number": 34, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", + "public_key": "cosmospub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymsppa84a", + "account_number": 18, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ahwzmm62n0OMpO9XJWjLp599bEmFNLnNS7I8SMiBjTQB" + }, + "account_number": "806", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "22222636130" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383593264", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmeChT9zmV0WYwsPPrM+uBqmVdEmOCyCyuTfANBhXXRy" + }, + "account_number": "910", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "14087179165" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382604431" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1gtv2yjxfwhgrwrv6uag9pnqw69q0p5z8mzdddn", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AnzRKF//UpZVzOZHust4WwdqJOAewFPkmeGR2+JwlLyM" + }, + "account_number": "429", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "17085375123" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382612249" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", + "public_key": "cosmospub1addwnpepq2xu8de8m8m8r6s3gdlzevgnuyjxqnerdhdt27a89w2euju4urw8yjd09rk", + "account_number": 158, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gwwltgyatg8yfe54447dxnyvs2nt6xxsl6lv2m", + "public_key": "cosmospub1addwnpepqf8sv0x7g6haj9p0t0ycp4t4qtrrwkddhnkkhczs5de58u03hkh4k05urfm", + "account_number": 486, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gw6f5uf38mv5dng9uwfzv4r9whvdd2f60ay2ra", + "public_key": "cosmospub1addwnpepqvm58tuxw7rj3dq4udtdgm49vg4q9pnlwlmfnwtydaamektrdh7fvl0a32k", + "account_number": 705, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1g04020ghngvh7lj8hmhequs5a83ly7xxyh0q8w", + "public_key": "cosmospub1addwnpepqw99ssq2lzjy4g26w7qwwuh36eglqyjn4nyahglh6ykwpctxhjlpws2rher", + "account_number": 531, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AvqAhn95HX0b1EQXbUhugozxAewwjl1qOZ/1CSNuuG/c" + }, + "account_number": "386", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "21471315017" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382938892" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ArXEYydH/+Hux9sq6E+lXxRqd/1A+Qaw4XIBGmhxYWrP" + }, + "account_number": "663", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "10747545130" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382601941" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", + "public_key": "cosmospub1addwnpepqdhcupcamks7erjfhcvl7f0ec9032vygtnraq5xg6uehjy0amzwmq29hgfs", + "account_number": 58, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", + "public_key": "cosmospub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslq8j2znq", + "account_number": 142, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", + "public_key": "cosmospub1addwnpepqta2kryj27uenxysne52plp50tn9tnc5t8nd2geytjcht6c68yppzhpst6a", + "account_number": 219, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gkdgukkcx52r2w82q2usyncf67s30g7hmqc74n", + "public_key": "", + "account_number": 340, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gh67zgx4f9d64ctqhtascuh87805v8yffrfytl", + "public_key": "cosmospub1addwnpepqtcpp77982hl5fhudkwv9mr6aqf3ree6t34697uvuqptnh6kj4ys5j5qa2r", + "account_number": 306, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1guuf6ntr5ujawszq99gkq2gqeevz37adzp2fmy", + "public_key": null, + "account_number": "814", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "27974118" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384000179", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1gayzja3zz6unep8ftnpunt2wefazs3jhunl5az", + "public_key": "cosmospub1addwnpepqdn9m93wfkj62hphl0uep7etngtrwe6mtl6gaf8f9e3a7f7g55npyd3nz2c", + "account_number": 101, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", + "public_key": "cosmospub1addwnpepqdwwmumvva86wmx94fr3hgtnt8gs40wxy3wt2heja430emv5lxxuvcumqwp", + "account_number": 495, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AvV51T8duMyDhiKve4mt42q27oabr06iWAQ7VEs4oaRF" + }, + "account_number": "719", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "6905217040" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384889824", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Az6SXIT886XGLhQzRl5NiYxBptJO2kZaKAVGNt8qy/n1" + }, + "account_number": "776", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "5291392908" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382599824" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1glku8mx4nzp5crkjt7px9lfe4flfge3zf64tud", + "public_key": "cosmospub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v4jxzms", + "account_number": 152, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", + "public_key": "cosmospub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5serds8", + "account_number": 24, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A1jKAEZCXdbMiIBk78y4feetRuKgdU4BMUihhLw/FT3u" + }, + "account_number": "882", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "16337977170" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382602700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2", + "public_key": "cosmospub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g3pj96j", + "account_number": 237, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1fxdty0drndqphzcpq7v3jz3hhwp0sdhdatraf6", + "public_key": "cosmospub1addwnpepqfuau0cn7csxsrxxhnpaqgaus98xjypq44dymc9zj5d6kd87f4h35zyua5l", + "account_number": 516, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1ff2vzyfjcwwgk07cqv7hgkpvj0yazgcpez9jg5", + "public_key": null, + "account_number": "867", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "2017285126" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382590889", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1ffaxjdp4v8w7kzgjsnf6nf4fvvndhrk6s9syf6", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A53L2pyVMpUUTgggISMfQEdEoUPkh1npwsApRvFce3J4" + }, + "account_number": "266", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "13796058501" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383768526" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1f2pvewnws73u0z5wsfmv5uqudwxl6jupfm6nta", + "public_key": "cosmospub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcjukmam", + "account_number": 185, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1f2tr8j23vqevt4hwk3073y6pvu0cgjg4jx4lja", + "public_key": "cosmospub1addwnpepqgxczxjtjfl39afnrsy4jxvvt2a037rydw4zvlyp23r2eu4stx0455yhd4q", + "account_number": 586, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", + "public_key": "cosmospub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcr7pm0y", + "account_number": 56, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1ftwtj8rwrz4n7e9y5gnnx47g2vtxkqkg26megt", + "public_key": null, + "account_number": "472", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "2085194196" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382620775", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ft0e05t5rl8ycw6a0nfa6jswvckycan4lfmv0q", + "public_key": "cosmospub1addwnpepqtct64cpw3n5hl3gxe0le6kqsq5ad7s9efelqpkg2g4kgzuxyym9700xs8a", + "account_number": 269, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ftj05w0hmw2xxw5p7gvr258j2824qd8r2xdk9e", + "public_key": "cosmospub1addwnpepqfyj2hu5pg92u3yd4zaugmzvkn9wpjp96lflmfrgr2jekcwljh9lwvvurtq", + "account_number": 797, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", + "public_key": "cosmospub1addwnpepqd5nsxkua92z9eamd4hccf0pxeh3chye2475vcrwc22dpxj4lmkvutf9j9c", + "account_number": 842, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", + "public_key": "cosmospub1addwnpepqwsa0gtfg8nxze044y6vynaz5f5z0kz4ar9tghvyr9cpacl28c76kg5cp0k", + "account_number": 86, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1f09q88gqlava96kfz8xljgtj02rt4tmcpap5ya", + "public_key": "", + "account_number": 694, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", + "public_key": "cosmospub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskaav84d", + "account_number": 673, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1fj43j5263mk8whetx8ru0gm4yf48xkg20txll7", + "public_key": null, + "account_number": "329", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "9926594367" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384970072", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", + "public_key": "cosmospub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjd2xy59", + "account_number": 410, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", + "public_key": "cosmospub1addwnpepq0cqxf0agdn2c6cgr2gkkzahntmu5uhyu2d0cs5smcz90nz04djcx53vskw", + "account_number": 414, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1f58nf9lzm4d5x9grnt3a3vd9c75szj95f6mm5s", + "public_key": "cosmospub1addwnpepq2y3052wcj9aq5ykg2tf8c0cx6c9dwpgyl53urcnygwly065f6hg6p0a7cu", + "account_number": 345, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxnB1WQn6UjisskZjL3Ra/Ihj3AeuqthtoY7VwU/xH8v" + }, + "account_number": "440", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "5561526745" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585751" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Amm0Qt3iJuUeqCsFiwd9XQpf8ezH103hj/YmZjmd99/j" + }, + "account_number": "517", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "20094731489" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384501420", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4", + "public_key": "cosmospub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsucarujd", + "account_number": 197, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A99he4k/Z30gPQURzBhU5SRk29R3o4emtzR2PLBacbND" + }, + "account_number": "608", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "2191920881" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382584848" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1fc96780mrsxn5kgplhtna40qepjgrm9wsyly02", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmzyvxBlV3/AdbGinnMOxC3i/BDSB0FDOt1NtwQFrcin" + }, + "account_number": "305", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "1957116334" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382579769" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", + "public_key": "cosmospub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5yjsmns", + "account_number": 76, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", + "public_key": "cosmospub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2de0ljd", + "account_number": 93, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", + "public_key": "cosmospub1addwnpepqt0thvaytymy6nqsz555n4hw0kfdx08g98yhpjaucmpm49wfuy9gvex2p3g", + "account_number": 667, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1f7wpuyc6ehg8p8rxag43j8fyfaur3jy0ujhs2t", + "public_key": "cosmospub1addwnpepqg5fj7u33myzlk4ltuul7rdw0q42lm7wzd3uj6gppcm4ymxwtet9cte64h0", + "account_number": 436, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1f7utq63ae24m6aqw4metxjrc5q76j8h4gcgaxd", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkkttVIv/LtML0gKlqHYQrBGLvKKzaj7Lk5/CPLb3IhM" + }, + "account_number": "446", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "21385201198" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382955236" + } + }, + { + "type": "cosmos-sdk/ModuleAccount", + "value": { + "address": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh", + "public_key": "", + "account_number": 918, + "sequence": 0, + "name": "bonded_tokens_pool", + "permissions": [ + "burner", + "staking" + ] + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A8yBMcuzl7cBkf1bWSYyyoDHU4qB04bzMkxiM/yWd8Yi" + }, + "account_number": "520", + "sequence": "7", + "original_vesting": [ + { + "denom": "stake", + "amount": "5048948618" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384085261" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos12qsn5ukkpvy0ymcsfh85yqp4paw5ew9mcg8z0y", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ay/WnReCwD0kUCYGyI0H6du67hcHNPwioYdJnQ3/b2/9" + }, + "account_number": "362", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "2298131693" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384430815", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12q3w0j5hp023hdjafgc357hy7kkha296f4xrjf", + "public_key": "cosmospub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyprzuwv", + "account_number": 186, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12zkyjh3kjyz2ka0z7lskxqxhvtmgg2pzg8gn96", + "public_key": "", + "account_number": 878, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", + "public_key": "cosmospub1addwnpepq0hcte6yrzm8ppqms3l3vw92tc8cqqdacl8wkavpcjshum9a0rty275pfxp", + "account_number": 200, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12rrjnzeppeagkvqw6d26hn03kr0uvwk4sfw6v6", + "public_key": "", + "account_number": 526, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m", + "public_key": "cosmospub1addwnpepq242jjldxy02w8e4d8mgh6tx6k9rdhy0rgn56wac2ng7gvjsc8yn7dz0agz", + "account_number": 820, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos12r0m6hwrnn0jy02tnhmk328d7p68x2rndzt0j5", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Arv9F54M82LbA9iPFkFjgukBG4LQnxE9p6nty8c2tL6U" + }, + "account_number": "474", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "7457647665" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382599125", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", + "public_key": "cosmospub1addwnpepqtq4rjflca8vgyn08w3vkpqeq57d80dmja25rd0ntqrx5fxm96gtwqs2tew", + "account_number": 53, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Atf75jS/MDbJt8EHObI2Qh0nH+Ld0s9cT2Y0Jm8i8oo5" + }, + "account_number": "507", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "11330787049" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384116759", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A4XuEC6PtipmxKMsvqxu4eqMkIUZ5BK3GG+jZ2lGpe06" + }, + "account_number": "557", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "320378521" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382582039", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1280ce9aj6ezeduu5adlery5cjmd4fy7yfe4s35", + "public_key": "", + "account_number": 765, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos12gup0vvqv32z5nvdy4ycrhp77dnax5hfmcjav0", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/S5QqwhiQOlFMUiOfazhvy5Z797zKaXJv3KwE6SKOsA" + }, + "account_number": "297", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "20008020745" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382870868" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12f4fpl936ld8c64dxqgwv65p42na8dcnv9g7ku", + "public_key": "cosmospub1addwnpepqddlzcmsy4vds97qxa5a5xs4mvgeyp9zhmm7fqfdr888nhp0sftrjer622m", + "account_number": 193, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A99E4NBvKh+ntmzMGJaIJmqeFOClOv4iBmm8QFiWEZN4" + }, + "account_number": "722", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "22942834889" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585973", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos12vzdkp2z75x4paa9nf0dvg638l92n5s8e0jk0w", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxMEz5zQyJYz/KAOizvEv8u+8oQTRCyOGCcbwwBYYHFf" + }, + "account_number": "281", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "17036639471" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384070698" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", + "public_key": "cosmospub1addwnpepqwu9dzd2h5zv0m8kky3yvwpp6zjy723lw2uptrcz5877vhy4xwywxae0wdf", + "account_number": 354, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", + "public_key": "cosmospub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzr5vc33", + "account_number": 241, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "public_key": "cosmospub1addwnpepq2vpcxra7jn5ph969c4cnj2qngyr09hzyssh4m2rvwkneqt2x00t7g70crc", + "account_number": 766, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos12sx0qw8yggnh7scj90gu08k66q7j8wqq88y25h", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AqTqR7au/LPljZL+sZhC484/6qIVmswVIOHRd9VOsEXW" + }, + "account_number": "468", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "2995278906" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382915835" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AjkbidSdgf+C27tmz0uaFq/a3ppSlbvDhu5ymkGl6YtC" + }, + "account_number": "413", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "14333368778" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382605814" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12362v43p57f8dgc2dx396rpanj24j67pkcvy2h", + "public_key": "cosmospub1addwnpepqf80y65l3dn5hax76t9kkme9cctn0swqxr2327lqll9lkk0thdmcxzhdqk4", + "account_number": 411, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", + "public_key": "cosmospub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqs60wum", + "account_number": 239, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1250k2ymtkl6hf0ty6syhkxft33v580fhmr25qc", + "public_key": "cosmospub1addwnpepqv2m6qycqv50020tp8rke2pm0xwt5nd5z476jlq3k36jw0l5t7kdx34kuyd", + "account_number": 328, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos125334yspnrcgu7es23745xr4wtmrzyh8m8vmj0", + "public_key": "", + "account_number": 314, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos124wz6pnykadgf3xchp6rdn9s2t9z5sgvl7597p", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Azj9nQ8PMNc1EUjCsrqjftz3BsDfek5OpTnrwVyg1eEd" + }, + "account_number": "417", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "9716215648" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383801826", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos12k9kcewq2045n20vsa0u5a9m98k4se0rxtacum", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ap8/jibKZnaT7unNngjC7qEEWQjppSyeapgCiB3ZQHvd" + }, + "account_number": "803", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "15501591516" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382586898", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", + "public_key": "cosmospub1addwnpepqgm73g3mrpuk5y0aykvt6zmtpassp8qwu5r4hxrlw8umkqdw6wk5kuhc9wj", + "account_number": 672, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos12eynrdzx2jqz5u92hgmhl9ga6hmghqfv0xvns8", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A2Mo014lcxun5LW4JFcr143pe9hx6df2oF0BEWvcLNOY" + }, + "account_number": "254", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "24469943486" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585072" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos12marehfknnseqtft88ut8gehf0lvcun3mymcme", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A147Q2xV6l1SrBZXjIZ4cyGbbPXlEZ5AktcTNsppXCid" + }, + "account_number": "740", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "7494827222" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382591926", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", + "public_key": "cosmospub1addwnpepqdlvalhvj0k0kqflaruuvyxjndwjaepha9wm0mphnauaf4tpjy0rzyczp64", + "account_number": 1, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1tqk0l38afmllffqs7g3uqaanhwpksytxtgnlj2", + "public_key": "", + "account_number": 785, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1tpxdvj93x9rqz89zhh0tszegcwtq8mgtdknrw5", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ap1j5426j9zyzWTU5VGvI5sBiIwNCmgfRcluVjeV+4uK" + }, + "account_number": "691", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "14879386908" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382848155" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1tzz5l8sw05e0tm5l0gxuvp04qt42stu3kqwf4s", + "public_key": "cosmospub1addwnpepq0y2whh2mx9stzswaxevw5ku8aznuvf0dgaznc4z8wz6fc4ahy35c8q3raa", + "account_number": 871, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1tzgwtuyftq8f686z0d8zvyqh37la70pje3nmxt", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmKe1SE909I8d4eHBddzniyrRbQk1uPJbqqZBNJ1TqST" + }, + "account_number": "326", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "2581389113" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382593904", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1tzt5ayvd6xpwxfcsxawlleluwylr2dhl46qvw2", + "public_key": null, + "account_number": "437", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "20205645171" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585819", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1tz087eh88lqkesr77yl6ys9dw95qysfqtff52a", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Azr+n7uWbLcSFxSZE6dNdTjurOe0MOPGtkxerQ6WhP3k" + }, + "account_number": "734", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "18343845903" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251385002878", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj", + "public_key": "cosmospub1addwnpepq0t6u9e52u3cm4kjgwrevgnvrehpk7rlrkwr7nt4695992urhzszq5j2j60", + "account_number": 376, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1trs75ceuvsg83y9dje9k79em4v684dm5e9ya49", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmQCn3QqnDymqOAVEp7SCv0KocBIKLDUpwZhAUNd20Ad" + }, + "account_number": "300", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "10185014984" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382918000", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", + "public_key": "cosmospub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4crxhjw8", + "account_number": 336, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ModuleAccount", + "value": { + "address": "cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r", + "public_key": "", + "account_number": 919, + "sequence": 0, + "name": "not_bonded_tokens_pool", + "permissions": [ + "burner", + "staking" + ] + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmWA6VhM8/EeFMfoDozk2mTaQlK1h1X0gwDWIKdRPe0g" + }, + "account_number": "466", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "23893202797" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382588916" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1t929u2r8p5vtvuwn390l506achd08udrwx4ah3", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AjAT5cAoiL9fVbOrnh3CTH3LG1RN3VPToI/SQz6d9Thm" + }, + "account_number": "366", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "13256822165" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382594619" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7", + "public_key": "cosmospub1addwnpepqfmytfwgk0ys49ezxq0e2rm54nkdg4m0eelhzzxrctpp2use3yuzvgz3h66", + "account_number": 825, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmUHAd9eiYf8eNk7l4QE7omwc6to0F5xJi13oMUuMART" + }, + "account_number": "809", + "sequence": "8", + "original_vesting": [ + { + "denom": "stake", + "amount": "20808467107" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382595226" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1tgghhdcxdgxay7hp2p0lv2fs656c4c0xfzlga5", + "public_key": "cosmospub1addwnpepqvvxtcls2a9qfjq04usrzv3ekvavu52z7twu9w3fguenpjett5zpwxkm7tu", + "account_number": 769, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1tftatt0lp0v59qqf449pdqar8w3yj7n7xa7sk6", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ao+yY177yX3OepqYA98bD02YI+QgEHVTkkDM1Zepd+CT" + }, + "account_number": "464", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "17454582252" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383830804", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1t2uupuuf6p4xr0szwsz47gn682kw64m9wmnewf", + "public_key": "", + "account_number": 387, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1tv8x2sctvryfspc68rypwrld99099hvrh8vxz6", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AipxECoVjWqt1VbbShVOcA7o6kMPZ6WlbzGmqPzZFKkN" + }, + "account_number": "637", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "14179685715" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384578094" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", + "public_key": "cosmospub1addwnpepqfjk3l28hkcd6jl265j6aypx77uqhm4hjwq6j75klu4apy6gl6ze76q09g0", + "account_number": 0, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", + "public_key": "cosmospub1addwnpepqgzjwcddk2z8kmnvgh2yyftgqknzry0cp2f9g7tlprezsj3p8yupxad64eh", + "account_number": 23, + "sequence": 10 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1twu2lvgp3erk6gups2a8nae3jdahaj2xmlufsa", + "public_key": "cosmospub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z458ulk", + "account_number": 126, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AlX7l1HcFN/NiwUPrGARgFfm57hNdESUcb1Fn0GrCCdV" + }, + "account_number": "394", + "sequence": "7", + "original_vesting": [ + { + "denom": "stake", + "amount": "13933984019" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382770570", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1tsmp448mysp6vr09f26ee7wa02vpcpppk3jgqf", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A7035NUmOTlfGRb2GGWdKSZUDlFfFK7pdICGJJMCAwk3" + }, + "account_number": "432", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "1773996319" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384218521", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", + "public_key": "cosmospub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng28yvv2", + "account_number": 150, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", + "public_key": "cosmospub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6552hsf", + "account_number": 72, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1t58fj97xgxsvsyn89lc75hd0naa6v6c0c340cv", + "public_key": "cosmospub1addwnpepq25nespfkz7h9g9pefln8qmftkawz4mxedfmwtrjqj2dtlxfclj9qfgznr8", + "account_number": 676, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1tczlc2ruuvetu9w9rq9ka0v7va00ye9vsyxf37", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ArC7nT8HQpvzAZjWYoH2BiYGjflULiIRZyFtaqZrp5uh" + }, + "account_number": "310", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "519941039" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383513574" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1tcaxfulvlrwt9ua2f4hrfpx6wvymwxksnurv3m", + "public_key": "cosmospub1addwnpepqtpk9wdpkuz96ravz5nqvwavwfzfc032clfafxqypm7x3lhc8x532tj5cw7", + "account_number": 781, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", + "public_key": "cosmospub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswd52tns", + "account_number": 15, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je", + "public_key": "cosmospub1addwnpepqdle8tezdjw3eyrzypex6335tna26ekqqaptxr4pjfmjfauuujcs7fytzuw", + "account_number": 854, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", + "public_key": "cosmospub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z92ukaj", + "account_number": 234, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1tmddg4wjnj38wrd8t6xq092jyw3x4hcup6n00u", + "public_key": "cosmospub1addwnpepqt5fpnmky0a402kgyu04yww96a839ydaxaakw75da6xq6n2d8evcunrt0vd", + "account_number": 264, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s", + "public_key": "cosmospub1addwnpepq206cdqqkhuqmwg0nhyh5k8e9wyqgvlwvpcxn2w4x8fzmc5upx3r5ey49xz", + "account_number": 844, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", + "public_key": "cosmospub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vtdghex", + "account_number": 145, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ai5f182dWvLbRv2dydeEs/xtF8XHVD3qU+CaPLeP2eK1" + }, + "account_number": "729", + "sequence": "10", + "original_vesting": [ + { + "denom": "stake", + "amount": "262606423" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382608974" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", + "public_key": "cosmospub1addwnpepqfzsv864d6pzxm7jr4fnjd0u74phhasnmhne8tp9xk2nwu9j0m7rz4jp06q", + "account_number": 569, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1tl9mmfa626vgrsz3plpr42cmeqcn2zugg523y3", + "public_key": "cosmospub1addwnpepqdjd5xt0z7jup7zfplqtzplltrfp0yzydef3sqjwlfnrz3v8hpkzz4f8q4c", + "account_number": 503, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1vqm5fdsflvnee33gk3d5pz7j6tf6dsp28eemcq", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AowkUjoD82gwzVKL4mCYWlwdG8Oz3A01++D+2NdYlD1N" + }, + "account_number": "879", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "19841569559" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384588704", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", + "public_key": "cosmospub1addwnpepqdazuvwg72zd5mg4lf9mf9eyj7flqcmsw4a03283v0wssdljlj607u89kvm", + "account_number": 378, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", + "public_key": "cosmospub1addwnpepqflsm7achydcfh2ajnk9d3r4p2ckuphgyw9chrquhyy4xhcct8jc7ecf7cs", + "account_number": 5, + "sequence": 10 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vpc637uayw7rm4a48cuzuynvu9yse45me0jdmr", + "public_key": "", + "account_number": 441, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vpensuylw0rg7f6pnx7qm0acs3tmqgv485faen", + "public_key": "cosmospub1addwnpepqddgkww76904d4ggeshu7m9t68446zgfnj3tlrxr0eut858j5sd72pk84x0", + "account_number": 488, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1v9frpsrct2tplfv0r2en28wh8le3f9chavr65w", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A44TlZCS+L6J85oBykDfkToRNlPYKqqfUU7PxUKn8CTF" + }, + "account_number": "749", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "21342460274" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382608947", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1v9k0h7s32ujfeu777jkc7z69gctz4zwfy7q49l", + "public_key": "cosmospub1addwnpepqd2me5dmymmpsqz4yyfu0x5rturv3ka5v3ld5xqgf95l07mrpn78kp2dxdn", + "account_number": 439, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vx0z58vgegsfc8e56jzmjtvj8cvprywvnm7l9j", + "public_key": "cosmospub1addwnpepqdhksqqmv2sx6yefnz7p8rxmjr0mxpvn34hquj39zk3hegu3e4adg3umw94", + "account_number": 858, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", + "public_key": "cosmospub1addwnpepqww4cd27af2gje0s58yu3gsj8rdvc692mu7mlvd32afwq3lrldpvzpflj3t", + "account_number": 423, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", + "public_key": "cosmospub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag777eg3w", + "account_number": 160, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vf0r0fg74jmm6qxq4dj8amhr64acs32333ua0d", + "public_key": "", + "account_number": 313, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AurdZLpQgZkDkZZIEQfVfOttKMvKgTkdQHxIo7NOtC5M" + }, + "account_number": "283", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "6911431250" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382591085" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", + "public_key": "cosmospub1addwnpepqfs8twrdeftqq3tvq55hq9mxn0duh577l043csvdjhxefl97p3aqqm8l0az", + "account_number": 519, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vtqnkp3uat764qv4z02qwc7ysnre8q9ph5kklc", + "public_key": "cosmospub1addwnpepqf40773hc9w2fr3lxtxtxf0p94apylv7tr98lwnjfekfw83psmyr2dkcj4s", + "account_number": 270, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vwgt6t9vd9heg0jwq6gk0x7egw4cmp4w79yuyy", + "public_key": "cosmospub1addwnpepqwczxz60gwaq5z3ncfgjnc79uzx2ckz924q06h8gqtl3j0q0drq4z003fse", + "account_number": 654, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vw3dl2j248ypyvvjfu7036hlup5p2gpwgvg7qd", + "public_key": "", + "account_number": 876, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vwja3gc3e37f8fkddj38gp74cs7sccnf4zs509", + "public_key": "cosmospub1addwnpepq200h9jck2lup7rttjujqt7scyy8ekwyjpmv7dery4ple6hmer9auwxgrec", + "account_number": 273, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", + "public_key": "cosmospub1addwnpepqvkllp9u9v05plyvdmyftgwv96a87j477397tyyrkj50cnaanygrs6gluhk", + "account_number": 826, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", + "public_key": "cosmospub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4crrgfgf", + "account_number": 224, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AnqMdbDtIKZmdsZDJcnnG2c7H8G7RfdD9UF6y1ufIbTB" + }, + "account_number": "881", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "11384887844" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251385084522" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", + "public_key": "cosmospub1addwnpepqvz55wnnaw48qrudyvxm2np0px6xma93kxc0zh8va6xf9ekz7k8nsmdvzrn", + "account_number": 92, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1vjm2s6e2mu4v08mluhgry9chyewhtd2cm79j5s", + "public_key": "", + "account_number": 824, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1vnceu3qp3cw2qjq3jqmvfgwgv50y4yze7fe22y", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxTXojEjRNN1xkFYCeh492aag5NfI989QKHZOXgyLg5b" + }, + "account_number": "658", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "7490727045" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382616571", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", + "public_key": "cosmospub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwxz3zf0", + "account_number": 94, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AoIYnmm0/M/CJU71deWNtYv5Ar2usqQY6XdDeT4Kzm4k" + }, + "account_number": "335", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "17590970270" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383129090", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AiYjN/mWbI4vtAgsnFMGG+Fb20NpQD3LHrweaQn6QtzW" + }, + "account_number": "500", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "7346895419" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382984377" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1vuws77sz0xzvz8y0dg6wjz9fzd7plxpk29ljn7", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A1b6pdzyag9jHjYWMWpuP0KtOlGQkF9jnSLM6HsjR1Vl" + }, + "account_number": "760", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "23297021045" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382596851" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1vlvxlpzzrk5eye9c3z9uedk0085h7fdvehv32n", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A9+I461saOCOXdZSaeZQa3xJU1POKl3i9qtgNQojYJwy" + }, + "account_number": "655", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "20596731311" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382611750", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ArmVhXiDis5pLZE1SzVKQpdXCMHkTs/HG6f8NrLlySKB" + }, + "account_number": "421", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "2652386103" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383053641" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AsMvlkLMd92d31yc4RrnuuuSEs2/ngLui8L92I0cVn3z" + }, + "account_number": "315", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "7735735418" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382612123", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dqukz2u9cssszcudyrjxzf47aeydmfardn09hw", + "public_key": "cosmospub1addwnpepqt95d8pk0f3dgfh0zteuqa6adrpskp2m4krf47jzvwlmqez8287zs4lvkdd", + "account_number": 277, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", + "public_key": "cosmospub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qjqweyp", + "account_number": 50, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7", + "public_key": "cosmospub1addwnpepqgdne4suza7cv9aspke30rvuwyqpd07ns2s5jcfnskyfvafygyyhqenkvav", + "account_number": 401, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1d9cqjx7xh2j23utvyrns2kgtz4w8e694vqw6h6", + "public_key": "cosmospub1addwnpepqdv2p7tyn8u7apd8g9nu37t69hrw9zat3uf92v5y9y9ku4kyns4f5xklu5t", + "account_number": 451, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1d9m3l8khcrx0zhftehkuw67zzszf9v9le5dvrm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AvMEuEw6ZuuyqjDAkqK0I6kuF8HTCxdwK24Jn+HwyL+b" + }, + "account_number": "801", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "14002405995" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384896507" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1dgzvesl67z96ttlt5ulga25phe8pnspt663dvr", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwH0Mt7qKQjcKQc10ncPMlj8mV17x6KWs77SfDR7+gg8" + }, + "account_number": "458", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "13826121764" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383829848" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ArIASLNFB8KL32lADVk/kLlGPGG5UXehNBENWS8P6uOE" + }, + "account_number": "908", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "10017074133" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382617614", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AzWlQF+NPXzTcon71qE/CtsiRi0lgdrIuNnrlufNhviT" + }, + "account_number": "877", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "8818079614" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382761706" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", + "public_key": "cosmospub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwrt7mj2", + "account_number": 178, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", + "public_key": "cosmospub1addwnpepqf558mk5ff9u9tx0nq76pfgenl6lzddnddywjsy9m5dq6hz9peqj6savc4y", + "account_number": 511, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dwha0rccawlvhudcgdpzcf3eq2c0gqyzwctms8", + "public_key": "cosmospub1addwnpepqgmhvev79eltw87wpn44627waqanjhx882xl0a37s0f0tz3fjuz825vctth", + "account_number": 543, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", + "public_key": "cosmospub1addwnpepqwfxtmquurmzgwsxl8fjzlglw489hnrulfvcc29xqtmxwf9m9tr4vlvj8ul", + "account_number": 634, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1d0dq8hxzyywrcx73v4z44e8p8685znzml58dg2", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AhdwJ3lW5Xw56g5hBuihqu4nXjhCtCLSHSDD0ewatuU3" + }, + "account_number": "422", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "18610536319" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384232987", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpdhe28d", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A7jQ8vHSMkb8JnkkDj2X7zuEqLWE1cytFeQuXwYnVYHU" + }, + "account_number": "308", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "21923992439" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383331802", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", + "public_key": "cosmospub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq6496z2", + "account_number": 84, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcy522k3", + "public_key": "cosmospub1addwnpepqtc9vugqcyl9agyk5jfajuhq55zgvrxnn3cjw375k6zdn3cw3pf0740w9kz", + "account_number": 184, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1d5vv20893q06tx29mlqmefnyf0w3hn0v07w9p9", + "public_key": "cosmospub1addwnpepqtdldypck872t677fwgapgk44dy7hhw2ghufuda3qtfzqcd8a5095lzjfjf", + "account_number": 105, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1d4jyeaslp5p85mmkxqsem6g99l67nqa6uym3c4", + "public_key": null, + "account_number": "905", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "16761520335" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382581745", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", + "public_key": "cosmospub1addwnpepq29d27xgflxpx9j63q2e9hrfcujjw3w5g89f58g94net69gx8lvcu98n2u4", + "account_number": 381, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", + "public_key": "cosmospub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7k0s4q4n", + "account_number": 600, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lypeadd", + "public_key": "cosmospub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj62qxw3", + "account_number": 6, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", + "public_key": "cosmospub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey9q6s86", + "account_number": 226, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wpxkfcmhsmv7d5hdzx4tw9w009fd9wwj7hv682", + "public_key": "", + "account_number": 256, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/vXvSMx7mGCgcow9k16KGVKii27hEPzmxxndEMe8q7x" + }, + "account_number": "687", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "751349096" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382592060" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", + "public_key": "cosmospub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dse8vm9j", + "account_number": 99, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", + "public_key": "cosmospub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz9ta2qa", + "account_number": 77, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A78W4qmMI+MdXIPeBbIVGsJVlSz4ItchB3b1q86dbU8k" + }, + "account_number": "312", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "13067070201" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382611372" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1wykcmn3r389hklplushrjl43cz76djt44yuc2d", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AgvKBcI07ZFPvLLNJDJQbqoG8R02Nh+x0tt8vIrmIp83" + }, + "account_number": "630", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "18145178781" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382604285" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", + "public_key": "cosmospub1addwnpepqdgylnekrukj2u2dlx3fkexe74qyd0nqymanj0dcs0ymn53p9jrn6u4a5hs", + "account_number": 659, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", + "public_key": "cosmospub1addwnpepqfrehcj7qxnx02dvvqzwym4tfq8dr6ttextvvjznu3xkrtkq9ysfcwc2zlx", + "account_number": 255, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1wgslx9j6ct5pczy3h5rjl98yyn78r3sel0ulth", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ash8k4Ivl9y44xQcYt9AcF/OCLpWeoAOdx+Kc0zQ4I4B" + }, + "account_number": "767", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "15088034388" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382885184" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1w2vujuajxpvqtdsne0gn6j0x0y0xw3kqtj6jtu", + "public_key": "cosmospub1addwnpepqv6qrul7n98dffvgvqyfrz7pc9cy8l22pdp9g5rxn08rlaep06unck9qacd", + "account_number": 846, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", + "public_key": "cosmospub1addwnpepqfxc6u7t75qnm04w78j2ngxr4mpnuqy4f3em3l6mv72kg8ezx4hyyt85lms", + "account_number": 626, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wtn9tf6wjwmwmddrk377cdl8fd96hexajyhfat", + "public_key": "cosmospub1addwnpepqw29rqhlwdtjtv265lp4yhf6mkljp6qwtjnnej4an2m6waky69sg5hg759a", + "account_number": 484, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1wvzq2f252674u3gvmqhnq8g4n6lmxedmzs0czm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ay4CwyPX1ndSFPULXseHDw1cJ1nrC0x4owYLePgoMtnx" + }, + "account_number": "333", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "1828902041" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382617707", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1wve3m263mdhqqpg0yjd8vmveflugrk5dk2cr0z", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A54OIQScAyF3FhxPLgIa3a9WKWLcZYXX7xdo2Rsvufs6" + }, + "account_number": "573", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "15733791808" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382583599", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1wdm9ge7hjzrlh2epwtwu3nsunfd2r7alqhc7r2", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Am+EQXaMi5T77tJgY85EBCia8tD8pG4n+osQNbv+LvPN" + }, + "account_number": "588", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "23969763741" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384645927" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wwp7j40k9xffj757s4uurkcegskfwq25ef268l", + "public_key": "cosmospub1addwnpepqdq5f9adw92h3mgmnaq3u9ykqy6stmq5f5whhlfjgcdlkcujyn3f7l5u8sz", + "account_number": 420, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1w0050eew8g7zyvg7ap0tjhd6yzvew3ndls3v0f", + "public_key": null, + "account_number": "572", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "3345569032" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383342154" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1w0j4ecghl96s9xayk967z4hnrxlsfht7rawmrc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ApvN0yhzxk+rIKuEJFRERLBLPo+VDQ7FMP7v6XoL4ckb" + }, + "account_number": "518", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "12298589295" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383364879" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", + "public_key": "cosmospub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqkm6d7a", + "account_number": 10, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", + "public_key": "cosmospub1addwnpepqvlz0fenag3kgjcp0c0qrwyjhrxfxg9ers6mfje4lha7c3hk2qdg67f7qk2", + "account_number": 735, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", + "public_key": "cosmospub1addwnpepqg2887df2cynsehyycldy24y3a4sps3m4w8gmrdfuvw4h9hrc7555nrvedp", + "account_number": 14, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wc5kgetgqtfmjz9v87d9epwhlne2we0lzd8qn6", + "public_key": "", + "account_number": 496, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1w69f6s0dqsqfqq93hczddadwgeq86zr9dfmddq", + "public_key": "cosmospub1addwnpepqdutk576dwhq7zcc6g2nc3m0ys67pzqzn4rrwkhmxlg03pzn8ynrq7tayw0", + "account_number": 869, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", + "public_key": "cosmospub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru3xljda", + "account_number": 45, + "sequence": 9 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1waql7pehyspkf8l9q04gt508c0khx0nt64jsxj", + "public_key": "cosmospub1addwnpepq08t54wd3776kxjrtqewrlnl3ag6mxhvye4ksq2dr7gtd7g2hd03w6g0u30", + "account_number": 779, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", + "public_key": "cosmospub1addwnpepqtf9tfhe40sv84mfh95z0fxa243e5zlnfvym5nhfz30uc2ll6xmj6zgrjwu", + "account_number": 492, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ApAwJ3zthZs8uszhi/blGaA/UIya+5WtCCBoOqeNT7Xe" + }, + "account_number": "707", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "8589454947" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382617815", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos10qj9cj3dxecyu826gaw72ylwum96jkkh9p462q", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A94DBB9xHh0Qq/qiTnkh5Sn7imbsbjuyHN91f3+VxHNr" + }, + "account_number": "369", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "5251905003" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382599091", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A+Wbfz0iayZ/gH7gwFolsN8Kakj2LlTV1+x5/ZF/C3LI" + }, + "account_number": "733", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "13161760877" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384119950" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10p78pcqm2slk4x0pfxl9ht5spskwquhzptwzt8", + "public_key": "cosmospub1addwnpepqgsfa58j33rwe9qghpdwlvh556pl2pman9k3r39vcwvlc3htu8l5xqau3jj", + "account_number": 578, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AnwozEWIdMnyERwHDABc+ZN6b2YssUOSEVuaR8f65kKG" + }, + "account_number": "650", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "6229875472" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382608878" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", + "public_key": "cosmospub1addwnpepq0dp72r2p4adzlsmg95kzs69rdhltghkjvuvmfsac3cdpunr9ctvy9w3c0w", + "account_number": 622, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10x0lg2djw0uq8qp5hgzujsu34zpreavnhmv0sc", + "public_key": "", + "account_number": 756, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10g2yfqkuyaxgyyj7hhyswh8cmhplvpanrc9tya", + "public_key": "cosmospub1addwnpepqdlqzf0gu7z7kx256zr2njnta6lyxyhvkuvazwzcpxz7nwftd84z5u7m99u", + "account_number": 772, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwvVsh/gVSExiN//lU0zlc2iYH/bCsMe9hTHmC8ZthzH" + }, + "account_number": "782", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "19683051102" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382608142" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10gu52rf3d0z0py8d0x37r058qh9fgdgg5567wd", + "public_key": "cosmospub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxk5f8388", + "account_number": 203, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos102sgufwszag3yuhtzcftpyvc8jqtqske4xug7d", + "public_key": "cosmospub1addwnpepq0xvdglnqk4yfwsh5jz8r5v8j08a6ynzzzp960qnwxx4xnjnzfe2564xnml", + "account_number": 623, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A0LmGIJ7XruOl3eV+DusqtqeOshIJNlbroFKSrXUSKeE" + }, + "account_number": "528", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "15675936208" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382589769", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ModuleAccount", + "value": { + "address": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn", + "public_key": "", + "account_number": 920, + "sequence": 0, + "name": "gov", + "permissions": [ + "burner" + ] + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10d3vd6yx9k9ns6v82r4krm3d4ragw04cysm62c", + "public_key": "cosmospub1addwnpepqtndwvyp0hczl37xh8z2kg32d5jfzkagkdh5mhnfrcemedgavsdaujv5560", + "account_number": 130, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", + "public_key": "cosmospub1addwnpepq22jjjqgknexwz2kx3cv78gjktd2sqecy0qy64a5ytw8zl3648cwuep85s0", + "account_number": 564, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", + "public_key": "cosmospub1addwnpepqf3e3e79cz6a8a5ej2sup5a6gr8qjke6y4munem0amzs953pdee6qfnwdk7", + "account_number": 248, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", + "public_key": "cosmospub1addwnpepq2y3kj4vhmzue7mqncfd7q98j62a3kcey0mz6faen6sqxeew447lgpx3tgl", + "account_number": 836, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", + "public_key": "cosmospub1addwnpepq24753jujgdgdlncfnw6shcvtkk6skjp2wv8guwenwp9uck6083sccsld7f", + "account_number": 863, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10572shcaewknpzsj6nnrruww0049hnmjymva38", + "public_key": "cosmospub1addwnpepqdxnhkarz06ut8ar22x3d5t4g9l02k52mr6ea8eux2c80u6hyhltg4069r4", + "account_number": 778, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A6mhcWo6xqfBFgTMZP+CPpZhMAY+xtF0tXdBy9do+lv/" + }, + "account_number": "883", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "7247997772" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382584887" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", + "public_key": "cosmospub1addwnpepqf4eys884495jxdra6k9jqdps582ftj6cp8mjyxws7w6nrxxlhpp7x5laf5", + "account_number": 141, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ArBnfanvlcuSmcQR5PUiwbkuJmc1KHplecftniqS6wnL" + }, + "account_number": "562", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "21929317327" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382603431" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10cl6sallgwf882apcyagjqa2lx4j8592cjw0gf", + "public_key": "cosmospub1addwnpepq0sra5mkmllmenj9ymu00ky4wcpwtanyldal7xt3chkm6ksnnhvvjamcetx", + "account_number": 3, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos10ed8tmu5n2xfhtcyht4kahkmzqaxk2u7ks7k9u", + "public_key": "cosmospub1addwnpepqgjs6fuam9stnrwxnjtmqravghgs8gxvfnt6z240p3pn2f7elrr0utpc349", + "account_number": 875, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos10ajx4nktldvyukmjdrx876mmwazd5sz860eu6p", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AoxBNp02bKLC8a0eUfaly+uW5t36siQ6GviNj6df8Bm5" + }, + "account_number": "794", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "13653383216" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382587751", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "public_key": "cosmospub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvye3pyuc", + "account_number": 190, + "sequence": 9 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AnXszHhNrHRNZUurODZV8JfS4hqXBqX2aknGM8LMwK/M" + }, + "account_number": "684", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "22584764663" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382597248", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sr6u63sxsprpzv7tedc7e88tn6elrxkjnucszy", + "public_key": "cosmospub1addwnpepq0p07qsysalkdawpfwskzp67z557yf7y0cypg4xm2nk7m6w3ukk4c8vqgh2", + "account_number": 887, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1syn6uv0ma6a0qn6n8gy6qrc7jdp8ghr6vva3jn", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Az2ky9RifL2XOzp+Bzc7VEVYaoAR+ACs24AbypS8g1zs" + }, + "account_number": "555", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "5422012300" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382609871", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", + "public_key": "cosmospub1addwnpepqf22js8fjl3t24zekqtuvly44vzllatz5d5rfzlzh6ppmqf5txff548tlqg", + "account_number": 489, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", + "public_key": "cosmospub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peg8z4rdj", + "account_number": 221, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1s8c3pza7vnx7e62k94z5jgx5jqtfh7ux2wh592", + "public_key": "", + "account_number": 790, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", + "public_key": "cosmospub1addwnpepq2wk8yhzl32d4k0w4ufp77gjpn0anll27ymgsu6f02606xeg3puqwdgw354", + "account_number": 243, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sgj2stu89zswe28gqh46gv8sp6reppxc9addtd", + "public_key": "cosmospub1addwnpepq2knku3h43s5ch3duw9pkm7g3udyhhgr8jjmve944h5z883r0jaly5vqakm", + "account_number": 323, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A9Il9diF3yAkSz8acC0t4w4oNbAazq+M2ux8+E6TcDPF" + }, + "account_number": "491", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "6277382244" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382582455", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", + "public_key": "cosmospub1addwnpepqd76980jyxlezsdfpr4nwaahyuge8958rjpwz7lp7f0shjj445vkq65wqwx", + "account_number": 17, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", + "public_key": "cosmospub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxdxgqxn", + "account_number": 223, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1stvzt8re3hz8dme2gscrjxzyx9hcefvhjtvuzh", + "public_key": "cosmospub1addwnpepqvreza8nm7mppsynlkqqegvltdg0k2duvq4vcl82x0hupet5y5hg28h7ztx", + "account_number": 907, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AhLXZ7/r118poYZPhXdb+jfmgR43S4vQk73bIKDbQu68" + }, + "account_number": "706", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "3069440430" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382606774" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/06ypUeMNWq1Q0Q6kn9q/jaOFf6EuWpOwcCvoy1WA1o" + }, + "account_number": "556", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "13842188728" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382606518", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1s0r2g8pzwre6tvywfw0h8vy8qg7spd2ytfkx70", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AiCdK75l3e6uP6o36ZSYfbK7u/rJJNq3qnN0+WIyVDFt" + }, + "account_number": "731", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "22598592720" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382622064", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", + "public_key": "cosmospub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wa93s3h", + "account_number": 149, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1s34kukvsrdgap0pjh0alnql7vvv9m83m2628wd", + "public_key": "cosmospub1addwnpepqgt5lvqw32z2z8wtgskc0gs6wl42agj8p8sjl4rnpkrmrqyy9cagcvdaee8", + "account_number": 278, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", + "public_key": "cosmospub1addwnpepqgtqlt7ucs3nxwwc47qmc03sehv59ttyqhsd537upgtc20ylarm3ujsgmh2", + "account_number": 232, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sjhhg2yl2cqszte7pjyrp6lx5tg383lrpjyq0m", + "public_key": "cosmospub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7nnm2nh", + "account_number": 128, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", + "public_key": "cosmospub1addwnpepqv9h32mkjsyhnv6tqahp659wm0dc20p32t8yr8lqexcvf6xac8ayqlf5dkj", + "account_number": 403, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sc26mz3pwry0wm9yynh6w02ypx6k6ckpsjgjr2", + "public_key": "", + "account_number": 791, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A3fXD1TGkcSUYF1Rwty9yXtI+it9JK8opCdaxukUQajB" + }, + "account_number": "849", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "19422922015" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382862080" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj", + "public_key": "cosmospub1addwnpepqf0wrcap4980h90m65rv3pqwfal4gyy0qt8us030hjxhla2t65jlq2k3wfr", + "account_number": 736, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3", + "public_key": "cosmospub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7pmadqw", + "account_number": 204, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A+R7Lpnmp7i3qEIYLcrKmMaS4hxvRl347i+v7G6w50S1" + }, + "account_number": "490", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "4430737307" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383235576" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A5LHrX+dAgBezT63XkkVHToc690K/BSSlYzpJFaVo7uZ" + }, + "account_number": "889", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "17299124236" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383197493", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", + "public_key": "cosmospub1addwnpepq0kzzpw5g9xn2d6zd2tnarw362fwfvt0evc9gq55lru2xfnw5sum2rq5p58", + "account_number": 40, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1s7e8ukt3awex0xh6qw27pramwg3hkgeqtm0nfs", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A4HVxlqlm5YkKlwFHk+iGR2OBjL6huaHlsWmIysb46Kg" + }, + "account_number": "664", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "270491061" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382613690", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13q5vwanrgz5ff2f6y07c9236xj4ergak73hgrt", + "public_key": "cosmospub1addwnpepqwg6cat6uz2sy8dvkgwt443qv85dz6wjmsln2j9qqm6zgkwuw5anwf8w3uz", + "account_number": 263, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos13ps0cszg8lqn0mkzndvhxwaew8yd56s8tl9j20", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxnHejxF6FccQUyn0f8LErZkBAR6PYhSxZAjawR2Nvak" + }, + "account_number": "262", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "15962416097" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585067" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13yzpngckxvtky2k25j60qxlkekx0jfau4pjhzn", + "public_key": "", + "account_number": 79, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13y2zjpgaj07umx7a3dsg9ffhpkk22g73492l53", + "public_key": "cosmospub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy722q95p5h", + "account_number": 267, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13y6fzxm4933kag94elyy4jgfyhgf3jhwakccun", + "public_key": "cosmospub1addwnpepqvgjcey760f0um2fa3um38puaavry6ycvdtj55cp34cjtyg7tepnx5d2rua", + "account_number": 460, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos139yreyw4l9jthf99c896sc4q7yvx9su4a95294", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ax1Db+jKCKw59DkURrtd/16bjmIAQDf4L2yKwQC/7APR" + }, + "account_number": "359", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "14441908009" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384645608", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AuyZYDQcyRJ0HfKpphdcPD3qmwaaBoUJORi7VzMhVmfr" + }, + "account_number": "245", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "4009366611" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382580773" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", + "public_key": "cosmospub1addwnpepqd8ua2f60nuxkgxqguncxzce8vmhdkmxgfcvz323jg9dq73w9gkhvns6ngl", + "account_number": 392, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos13xm9km2se2am890j398ttvyjhuh8zndwr2p68d", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/HEUS7Q9hhXFh/QMN7Jkqh+AzLKvFObvoj2NbMYg+4e" + }, + "account_number": "568", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "258737406" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383411850" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkLZJW43lOu3n+L5b+F6uEyvLZZJYV9SSpXk8Nz9h+3A" + }, + "account_number": "839", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "24830896918" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382604634" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", + "public_key": "cosmospub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cut2jw44", + "account_number": 584, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", + "public_key": "cosmospub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jk89krh", + "account_number": 75, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", + "public_key": "cosmospub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yxsu44a", + "account_number": 860, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", + "public_key": "cosmospub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4cgz8s5w", + "account_number": 96, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A2lNfYgUDueEZqzd8YUzS2sbp1LIunBnLtY1flJU9EBG" + }, + "account_number": "349", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "14878144991" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384665169", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", + "public_key": "cosmospub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvqn5y0zh", + "account_number": 83, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", + "public_key": "cosmospub1addwnpepqghsxshh5tdsf3g9q3a0f7mdq36lcmrxcjcsw0zwx7h6mhrkqt7gx039x5h", + "account_number": 187, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos130kk7kw4kx7rfrq9sa4k673zqt3nf6s4l3a0lg", + "public_key": "cosmospub1addwnpepqglvr53h6nz2tpvjjk5zn77ul4kh6v0uhwr8cyv394nv2zskxqydxeh3t94", + "account_number": 840, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", + "public_key": "cosmospub1addwnpepqwyktyc4e9j89pv0syud54z03g7tg9j5nx66ceq6gqf698l8h7x8gyymcsn", + "account_number": 59, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AiMmxKGuR93Cfb0W5iv1EmrmEnUoxPKoXK39fYwNQdLH" + }, + "account_number": "648", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "23757000561" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382588717", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", + "public_key": "cosmospub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprsganykw", + "account_number": 36, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Az5NSeEmREOeBfz6vS+o+T4gPixkGEdXhFLZFmPxU9+Z" + }, + "account_number": "455", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "21003040257" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382598072", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13jfnddzl23pkks9f7ahgjeqaz4pyfx43mluaa4", + "public_key": "", + "account_number": 904, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13nemj0k45u4pflkfeyey88n8u8sv4wgz8cf253", + "public_key": "cosmospub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66z0vj9h", + "account_number": 156, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos135e4v2rg4uz2767zhtdksls7n0s5eleunwdxyx", + "public_key": null, + "account_number": "855", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "1432712798" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382605010", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Aj+1jh7jpTqNnbanE2cRMCNjmOyhQg5MNq1bYsZslaLI" + }, + "account_number": "830", + "sequence": "8", + "original_vesting": [ + { + "denom": "stake", + "amount": "5838654707" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382608071" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13cydnwjmscxtqtjywk9atr9uwlm6703mwtycnr", + "public_key": "cosmospub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afq835d8p", + "account_number": 368, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1369zs5htywxarh8cl6rvmzgatfql00pmvmewet", + "public_key": null, + "account_number": "577", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "2250098945" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384873115" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos136jetl40d2fmx3w0a0t2jj7zyp72g850c9j4ez", + "public_key": "cosmospub1addwnpepq2asecf0tapds4p2jy8edxs4754909q079nm4qcyj3tjz86mymacz5w3exd", + "account_number": 685, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", + "public_key": "cosmospub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrqqkjgns", + "account_number": 69, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos13acm7994qxzmemx0fekg6s3qtagck36erqgsz8", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A5dh2Bb3bPXttHs4f9pncJLXIe3WQR8MwR738J3rfua6" + }, + "account_number": "280", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "13230569708" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382602456", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos13ljukhcdmvlmaa773v3582cufv74vudsyc59x2", + "public_key": null, + "account_number": "641", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "6706625986" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384576238" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", + "public_key": "cosmospub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4va3r93q", + "account_number": 111, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", + "public_key": "cosmospub1addwnpepq2kkwpf7hyzukxnwcrvdq477h5xqcufeyxgldkcashy8cxxhu3qmjc4ypka", + "account_number": 704, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1jp8nnep04hdcxckh0hg4knp4fu4zmzkycwwexl", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A+x2M6EKicIoOyyL+S1JhffcDwexF7taCjxVqlnAky8i" + }, + "account_number": "431", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "4098379796" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383410994", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", + "public_key": "cosmospub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvgcmn7ry", + "account_number": 261, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", + "public_key": "cosmospub1addwnpepqglwtjkhf3v4kynwhtydykpsr3jkhujq3sjg7zg37mfv6qypj0yykl374cn", + "account_number": 859, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jzhlspgxp578kzg9dtvg8tm2w9k7tnmcpstzry", + "public_key": "cosmospub1addwnpepqwus7hq2vx3cfemr5gpc36fphkmusldfanzk3a3jnfrlyjgzfkxvy9uvnxm", + "account_number": 299, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1j9vhccgf8520gtz7zn5jxj9lk3nqg0wx479kwp", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AygV31+NDv74EjR2oNblfvCnjEh50RKelz3eDHCTQl73" + }, + "account_number": "649", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "4039306257" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382937462", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1j9jq7pea9y4y7fersmc0wlk99sxj3vgdya3hm3", + "public_key": "cosmospub1addwnpepqgkedd4mx9tjk96xd4wl3yly7g4mjf8dqpjwlwhka2nw3dw4hn90vah5ayn", + "account_number": 897, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A4Mt+wj9Uf3Z6vvVrwfSq881AM9fw+T4IT6D/2F1suyt" + }, + "account_number": "674", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "21294145609" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384881136", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1jf2rfeaukfmdhrd6prqdmqhcdyr8ezak8sm2wd", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Akx5G5wGacccZrqN8eQzJHFy8/Vw3Zx3p1obeiBhkQEr" + }, + "account_number": "752", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "6831411503" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384268265" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", + "public_key": "cosmospub1addwnpepqdnmydex2xjhqnhfeudkqhkhj888kjzw67pqdw859u8g909jcyn4xe3asx4", + "account_number": 201, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", + "public_key": "cosmospub1addwnpepq25a99sz5z4ux5fahn5g6gh7xsyckplenzjnxztza85ww393mdwe7e7n2ec", + "account_number": 481, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/ModuleAccount", + "value": { + "address": "cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl", + "public_key": "", + "account_number": 917, + "sequence": 0, + "name": "distribution", + "permissions": null + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", + "public_key": "cosmospub1addwnpepqf5zqt6stst6y23klsfpcjspr7tkpmjdlckv7wx6vrsewknw0m2a2zxgak2", + "account_number": 170, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", + "public_key": "cosmospub1addwnpepqgsd0angdq54jvwzg0fd6jkvns3w8ncaul5nf06d04hz5729q6flj9aapm2", + "account_number": 768, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jsgcz2u9tgrn3j49t2xg4er3hjhnryzr6w9dqs", + "public_key": "cosmospub1addwnpepq2lz883x5qpf8k0j79p9tm323s4z3lsex6472hwjymwvxlh4tg8rsglxu08", + "account_number": 324, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jsfel7tdxv09dm4lsqesfuhlpnlhhpeh4fdl27", + "public_key": "cosmospub1addwnpepq0xy2hgnr5wpzjf6rs9nqcznwzqdsp3kugtlpecux22n2lmf46klyqhsw06", + "account_number": 574, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jsd99e3zfrxrr3nh057u0tvmu0847zkr29f28v", + "public_key": "cosmospub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz6ndmr4", + "account_number": 176, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jjav2y88kx0jempjzz5jcc9y4yatkyn7xnnvsv", + "public_key": "cosmospub1addwnpepq0wfqs2yq2h5xvja9hhg6atrr59l2nlck2fduh8dy86k3yftpqzxcar9j47", + "account_number": 247, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jn8g39pdp9zaz750v6x7kspqv4wdfcg8dluy5p", + "public_key": "cosmospub1addwnpepqgxqts3ye6zkc9eglp90ntej2jp7eenhp3zqus9u04g0lfgekqfjspgs4jt", + "account_number": 819, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jn4dp0s3ewkwarqmra50czqlm6g7cf9plthphn", + "public_key": "cosmospub1addwnpepqd6dzzh4tef4q7czn8wumngkz8nyrlwsn8ru8vg0r49t07caedwxv5zc2x9", + "account_number": 617, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ai/J1mbNmi/jIuUyEnwmUgbqMguOFxcnG1U5C96lkuX5" + }, + "account_number": "318", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "9704458018" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383337721" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0ajhqc7", + "public_key": "cosmospub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw26508kq", + "account_number": 133, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jhvqn320w9nqxcs3ar7250jqg7us9vuszw9cwq", + "public_key": "cosmospub1addwnpepqwx7dceg20dahx5zwg5a5elq6am8h0zgvd8d2cxvn3nzahj94mzswhhssnx", + "account_number": 739, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", + "public_key": "cosmospub1addwnpepqdwls2cwhnhc6eapdv49a8e2l4pfhl4kyna3gasjle7qd3tw0csrgxudj9v", + "account_number": 583, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa", + "public_key": "cosmospub1addwnpepqvfl4jhnn58u9xpcrc7wpduc4x3tyhpk7syv0jcdh33xrmgfa6hgjl56909", + "account_number": 629, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxx7jqef", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AjCfyciqfHJF2qMLycGqPFdqdUI0FbStT4rQ5BJAR9Om" + }, + "account_number": "295", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "9268777247" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382990724", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1jakgqseuh502xcapt7ctxtwaz2w4xyh7kdqqw4", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AhavIvRmhRK+vsHhy96A/2KMvAo6+dJrSBwqCZSeYccb" + }, + "account_number": "351", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "20561986979" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382590789" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", + "public_key": "cosmospub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qws0ml7", + "account_number": 88, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1nqlclz6g890zaeq4gadtl82e3f9kwzp60sqrqm", + "public_key": null, + "account_number": "850", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "13908817508" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382615766", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1npd5ddcq5cm3q938pk02dqa4te3jnfy25c5gnn", + "public_key": "cosmospub1addwnpepqg4s2agzlr0rjrzqz3vqzz9dgvzmyz9x8ueu08rkhruc79guf20xsrva0ep", + "account_number": 657, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A3MVVCcQfGMB3PnMJhW+KmvQdhL4N6ga+duvNWfFGKku" + }, + "account_number": "352", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "5400833576" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382698186", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", + "public_key": "cosmospub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2p5r0ke", + "account_number": 182, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", + "public_key": "cosmospub1addwnpepqgdzcxnrymr534cwr904euu0qwdsjmngaqvvj3lnzxh8mrdl8dukypzz53d", + "account_number": 807, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nrugh7am9s584k6qlf5nxlpetarxs2csglt46w", + "public_key": "cosmospub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akn8casc", + "account_number": 31, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", + "public_key": "cosmospub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693haza68yuz", + "account_number": 388, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n9dqelmmf5kfysk24m6chqfdcgz6r75u7mpuwh", + "public_key": "cosmospub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v7rzx9k", + "account_number": 119, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", + "public_key": "cosmospub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9yka0nwwh", + "account_number": 124, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A1LA8eOZZhFEThT61iiQjGtO6cGKveynRNNGO1QTpPeO" + }, + "account_number": "720", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "11467278300" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382622258", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", + "public_key": "cosmospub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06mygklmfv", + "account_number": 225, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AviWC4qyrTnjJ/llh3JrH0hdnvP/fn7WVsS6IIR0D4JO" + }, + "account_number": "642", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "16920159314" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382594923", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", + "public_key": "cosmospub1addwnpepqv9w0yqrekktvu6gd7ak8u7wkwqj47llgrtl2vp2gtdvfafwatyyshnrvca", + "account_number": 154, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1n8ugy8hee9hnzntcr7rkyhrrkcgclg3385vkd7", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A4wQKjQ0/imWtlghCTJmRDtwDMSRaL0RgogIfcT3H/Tp" + }, + "account_number": "828", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "12728206427" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382604229", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ng5m6spxngyne4qzce35fdg0whl0yqgv9lg9tt", + "public_key": "cosmospub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2cvqpnkq", + "account_number": 494, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", + "public_key": "cosmospub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2e7ytgq", + "account_number": 180, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", + "public_key": "cosmospub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveespcj73a", + "account_number": 20, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", + "public_key": "cosmospub1addwnpepqtjadacgcc9v3sptf62zr88pm3xd82gtxx7fl0vllavvx2vu5gckqjyfjgq", + "account_number": 214, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkA/e3022PSBdqMK9d65GXvKbsLfDO8JTJRYBuqcmNH2" + }, + "account_number": "298", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "10951876744" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382616021", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", + "public_key": "cosmospub1addwnpepqv59z3edalxhrq233upfrlzdpa2y4qqaahn8u4s56jf9utdxpnnnxudcmq5", + "account_number": 47, + "sequence": 14 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ndjmq7ee0g2lmxrx5q0npcmv64km6hysk0qnvn", + "public_key": "", + "account_number": 748, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n0qd05zlz0pr3eajdjukezg8l2str3twyjel3y", + "public_key": "", + "account_number": 725, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", + "public_key": "cosmospub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68y02pmcd", + "account_number": 166, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1n0f0kcjjwrjqvva5wq6x5nj0c45vddc2rr29k3", + "public_key": null, + "account_number": "549", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "18276027667" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383108269", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n3lnhxzzm7ntheu78h6v4zag7zmrlp48tjnhf3", + "public_key": "cosmospub1addwnpepqflpdacrnmymf2nxz0z27wu4c42cyqfqued97l9pvln873ptnj722az9wu7", + "account_number": 114, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1njvscahg6cus5fy9k5gkq72cxj4kcahlgy00dj", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ApKohxuMnLAS7QJklWtYf9Mlpu/uHWI2hUsLvhhK75Hh" + }, + "account_number": "358", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "7296698093" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585002", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n5qqy42c6su9dv0tjpt3867mu7sdfhz6juqdns", + "public_key": "cosmospub1addwnpepq06dv2xjatc7d24rfhxu6zl3srqzzse6xv6nkc7h28dt5vrp8ru8xanm33j", + "account_number": 554, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", + "public_key": "cosmospub1addwnpepqdlqwps7uuk7l2pszryqcmflpr6rdgvfmkgga6fkjvsydts2s6udk02trmu", + "account_number": 64, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", + "public_key": "cosmospub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzs5u8a5", + "account_number": 110, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", + "public_key": "cosmospub1addwnpepqfdzh8ar6wwm3h8dd0n9rxk3vfv753568dq62g3xdqepgen0gkcnssfmmkq", + "account_number": 157, + "sequence": 12 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1n44p6u7280zd652tkgyxy4jg0pp0agcvw3d2wj", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A5f4Wdr23d8m8HObEXSCyqxjwDOhucDcOpty1MuREEd1" + }, + "account_number": "334", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "10142093219" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383344721" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nkywcdu694al4mm44np7uy08jujqvwjzarzs3n", + "public_key": "cosmospub1addwnpepqwkwjjd07zlqsej7l5nn7msjch8467sdpcn8gc6vn6lav8tctzgdzuh7hz5", + "account_number": 732, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nky4q5h5wurtumxwsf9w79vmw3l4682879kly4", + "public_key": "", + "account_number": 544, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", + "public_key": "cosmospub1addwnpepq07ahy07m2ymqkwra0tzkgs0588p94nraj84wvmymmueg8dupcqv7maysqj", + "account_number": 236, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nutj5al03vv5r46uawslcg4mq696v2m48allaa", + "public_key": "cosmospub1addwnpepqgpcv88wh7cxe9f0nfttw07dyvc0zsjwlc5dqv944lfsvtdctt26j6d9vf8", + "account_number": 412, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", + "public_key": "cosmospub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4vg926jp", + "account_number": 873, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", + "public_key": "cosmospub1addwnpepq0rs6tt6rmqemes8jnlxsawqja89rdvyntyjuhwl73ajeelhrhee7rs2m0s", + "account_number": 868, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Aw/DRiymogx5GdyAyiKbC4ydEdBPCUT2/0JFqw6h7NLF" + }, + "account_number": "523", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "8258854720" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382620801", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AukFb08zFT9A0me/cX0njz1E38TDwyZFdwJoyzeTHFVo" + }, + "account_number": "700", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "3451208364" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382596301" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A1pBEbH6ArPIf7bCgoHXyZQvbhOnOmYV1dZDCjLbxqzu" + }, + "account_number": "792", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "7146894644" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384895125" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15pl2c2umxszwar75aft99kns0ltmpepnnpt9y0", + "public_key": "cosmospub1addwnpepqgnwhgwtgfqyxwfp86e906zysx5p02kh5rjzsweq2984lm2e5f3qvltaaxh", + "account_number": 57, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15zqzxj663h8g8naxyz324j2rpd3rnw4rvtxep2", + "public_key": "cosmospub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k2r0w80", + "account_number": 44, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1598m5w5wpz27dtq3er8uq2czcdvrwpffh7w03h", + "public_key": "cosmospub1addwnpepqweqdtlvakvxcygk8ezwyf26n9mt7z94qdpa4mjlev24q2zl8e3h6trpd29", + "account_number": 418, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1590defm6q73eu39x8ndt9vwmv5fhvp9q4vf96f", + "public_key": "cosmospub1addwnpepqd9pazpyfrvusrzwt24gap58zk2ygess4u2rvp6j80f0jcwvzhcqjp3dsdg", + "account_number": 539, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", + "public_key": "cosmospub1addwnpepqdzvxgkmxur34cmgyyfzr0mkhrysd6xdqpkz6k0qd62y4hl325qd69m7hzn", + "account_number": 35, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A3w+W+YQHAFHilt/eNs/et9I6REJuR8Oqj651lh7N5W+" + }, + "account_number": "447", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "20291805980" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585265" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A2vmnUQ2Rd4sXqjUKl1Cdc0E2LqY+QOsAx8W2OMKqfpI" + }, + "account_number": "822", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "18086272324" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382601215" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1528cn79dzm0p5tgyaclsdcuav6qetanhx9dwum", + "public_key": "cosmospub1addwnpepqwtn8ugzsxv8v9hapgqve099fu4aeyrlum2mfwph2h9spr2adxshwpdsmzx", + "account_number": 744, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", + "public_key": "cosmospub1addwnpepqw5h9ggnz7amw48v648wer50qeen3hv283fgyxaytq5l0y5ggz40x7wex79", + "account_number": 231, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos152haw4xa8p89az8fws3x38vr4cr4l5h0c5hsjx", + "public_key": "cosmospub1addwnpepq0rqul6xj8hmgnxpn5uetndpuwr038mjpzecdpazxyfwgkqceg2ej0axy2m", + "account_number": 818, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", + "public_key": "cosmospub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjyun7tk", + "account_number": 192, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos15tv54z32xgqechywvr7ymsfdvr2mmx3553j8rd", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Au1B1VAZe/+EqYIu/7ZHSjadt+erjtIqMB1rygiU+Yij" + }, + "account_number": "786", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "24951038861" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382595111" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", + "public_key": "cosmospub1addwnpepqtrma4umy3zc02gue9jzkgw0n6e63a9gh5jsufmx4yhnrl3daczxjnt0m3u", + "account_number": 653, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos15vf60ssrdq6fh9ln5a9wtd6f3q64sktl6vk2ss", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AzuFn7eAmTb2QDD6p0c0/mKxkXsJTAQB2DVASxGoN55F" + }, + "account_number": "708", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "9611753193" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382614115" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AzcUSJisCLOFkh7TyD9kUedVECmWvEZWmYKosOFsUy5s" + }, + "account_number": "834", + "sequence": "7", + "original_vesting": [ + { + "denom": "stake", + "amount": "19374837709" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382597065", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", + "public_key": "cosmospub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku3a2csf", + "account_number": 66, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos15wqxlh0da39gzvp3x50mrju8cj7ppfgachrxd5", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A5AXP2q4gT1zRSAAYaTKEHByIb7NifInpDRpkswJWFBg" + }, + "account_number": "498", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "23710189980" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382620382", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", + "public_key": "cosmospub1addwnpepqw0np49ksk7pxwauu8jkfp7gf9dqwahdc8yknp53jvc0zcq6ugplxfqdhaj", + "account_number": 21, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", + "public_key": "cosmospub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfczy7qkq", + "account_number": 385, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", + "public_key": "cosmospub1addwnpepq0e5h85jydylerz95nl4y6hms29agglx4p9mtwxp4e98r6wckmy3qduaacv", + "account_number": 171, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", + "public_key": "cosmospub1addwnpepq228r4rpxclcs5ufhlytsyx6dxkvwvecxvjhlsvglg26jg6l9kpy6mgpga7", + "account_number": 444, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", + "public_key": "cosmospub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7dy27kp", + "account_number": 29, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1556dzhyv2gth4huxdlyur65c2sm3np2en3zzhl", + "public_key": "cosmospub1addwnpepqfea7dk2x68zc2ah8axxkcvg8lv2wuendx9tm77k7xxwzqx3t45cg9jgydc", + "account_number": 651, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", + "public_key": "cosmospub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqu3ad50", + "account_number": 37, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", + "public_key": "cosmospub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jtgzvr6", + "account_number": 12, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos15hqa5fj9sx7mjvmquhknrcxkxkeudguk9zpqqy", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AzMvySAuGnTZrPw+UXJWaf0LgNNwifD4C3N5jgyS0QU2" + }, + "account_number": "726", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "25049046818" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382586318" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15cfduq92j3uvam8u942xj4egs42tjzl6p33fu5", + "public_key": "cosmospub1addwnpepqwmplgyppurr7j6knpfavaza6xrg007n907th4lslha4qx45q82twgza0fd", + "account_number": 612, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", + "public_key": "cosmospub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yjy85g9", + "account_number": 147, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos15mxavsffqqj7enxpy7e3ayywd4jn4hz6ncjfft", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Au+3+75I2nP3ASHrUplrt0UxZQlFamQgCXSSfsR6ic7/" + }, + "account_number": "811", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "15664943513" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382607003", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos15uqsf4wke3ylyp0elnka2rvaefhsmhgjhe5mxf", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkvII0LqmgvX7omk+5RjQtK7vTr+F8ZGzmehu9/nwLEc" + }, + "account_number": "285", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "13873921582" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384430274", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", + "public_key": "cosmospub1addwnpepqwckstndv9w0luxt6p3a694qazxat6kerfnpsr3qafypj9adchjaqf9l3x9", + "account_number": 41, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", + "public_key": "cosmospub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kphglws", + "account_number": 113, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", + "public_key": "cosmospub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq3jjut4", + "account_number": 398, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", + "public_key": "cosmospub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xwqagxan", + "account_number": 228, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14q9rupnazu0mmkjd9skpn2zdfs8d0hlghzpk0v", + "public_key": "cosmospub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6ywjnu64", + "account_number": 163, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos14rtpks2cfh8luvywtgrry3hhycwacwtkq6hyp5", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AvRAq8j88LzVD/gBJP1aVMeszSo5kIabgtRVXkj6uefu" + }, + "account_number": "891", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "16380650070" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382615962", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", + "public_key": "cosmospub1addwnpepqdd48dqgku8keethq2dtl8zmgnjprm0gmc2gawzwr6z3hp4m8s802pkkfwk", + "account_number": 169, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14fh7r7lj6928pd5tyqhfc62l5xnw7rq2zpnulw", + "public_key": "", + "account_number": 613, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", + "public_key": "cosmospub1addwnpepqtpesndd2za4kavuzc79nqxjzsmgh5fh0mc2h3lx82vucngmq22vg4m6tn5", + "account_number": 407, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14t66r5m6p8n9egwdxs45ljca5p4hra74vyz9j0", + "public_key": "cosmospub1addwnpepqvwfqajv633m2wgq0httfmpmz2h6gezk3eh5s2pe2atwr8jrlp3a2j5cpyy", + "account_number": 425, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AyZylEXhe+uo+jqUVUyk94g9E4QaFGYg+e93vGAJ5gua" + }, + "account_number": "633", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "17434455945" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384339866", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", + "public_key": "cosmospub1addwnpepqgv72p8pxj6dc526aynu6gkcg0cfrvjmjv6tnrhtp3stacy3jgezzs6uxz2", + "account_number": 91, + "sequence": 13 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", + "public_key": "cosmospub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwlms864", + "account_number": 802, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14j4mehgc448s2m7cr0uqm3pmvjxav94wmq80w4", + "public_key": "cosmospub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqvqnry7c", + "account_number": 148, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", + "public_key": "cosmospub1addwnpepqtcvgnxpkww6h60yke0z0rmvv34tw9ycuwr02pvw67kgaygtvgku20x27ed", + "account_number": 63, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", + "public_key": "cosmospub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc2h0p8d", + "account_number": 470, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14hr55k3es7xfc54gwgu3plde0vaxkgerljee6v", + "public_key": "cosmospub1addwnpepqtr5h2qsd2d5hhwhl6mxd45aw5gz0ttgw6tmt72d3p9symgd35udg98p2kv", + "account_number": 587, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AoENN7Wox3lq8lZ77qrSncpM46xZ1ve0ZNTbTSWSxclw" + }, + "account_number": "598", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "11757858776" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382610635" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", + "public_key": "cosmospub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7zux6s9", + "account_number": 146, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos14m0pzuhkpjnx2esurz6kcxcjvlkcdzk7e43krz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A9IG2koFVjvOxq8y6ifDIb07fvypS9QGmtyoFECfAOTt" + }, + "account_number": "915", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "19366487896" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382591284", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", + "public_key": "cosmospub1addwnpepqtplsxcj5j56ms8j7lerl57al6asnrh53uft4efkzvuhv50gq8azxqn95wg", + "account_number": 774, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos14urapj7e6tj2s8clcsgyat6xmkppj7nm4qtewf", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Azgt6HgPaXjbaMzNh9Qdc58fVPdyg/CCZCWph5Ag/6U3" + }, + "account_number": "551", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "4773666419" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384830695", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos147pq4rzswl76kdeyx8sc7pagf4nhjpnq2hlrh3", + "public_key": "cosmospub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axcmkuv0", + "account_number": 375, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos147xrqy22fnlj0ksdjlhsh5u6hz55sjn5hzzvfh", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A2blTJtAzIJ+YnPKO1cRYO2D9rYBQi2sUkcxYGFq3qhB" + }, + "account_number": "808", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "2441259561" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383179702", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1478sx3zdfylsts5sus5rlz4dgvyvacqpuchj6f", + "public_key": "cosmospub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmk5and7v", + "account_number": 68, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos147lwcm3tx6uhtjphxwwmk7u32mucukalplv80z", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A0hOEP1GKLFl0B1YoLsh8xgbrjDqtEhTD3/EML+SYebu" + }, + "account_number": "560", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "1743386664" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384351634" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", + "public_key": "cosmospub1addwnpepq00s4avel98xmrp04dalj5dv5cm0szqd8fy6hfqlgtzwtxq3y566yh52rds", + "account_number": 161, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A9hn81vFP34UNBYnQXhgCE/BYwMrOzXg4kbVA9jNfArG" + }, + "account_number": "784", + "sequence": "8", + "original_vesting": [ + { + "denom": "stake", + "amount": "15293467106" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383184893" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kz20p7j939s8cqadmqqws80c6z93qdtyg8xt0v", + "public_key": "cosmospub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw79rhrm", + "account_number": 39, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1kxl7gsad663he7lgn66wx6gr3egnfj85dt22pv", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkyEVdtAu2wHGw+Ro8n0LalqcxvsisSgDIZAi3OA+v6V" + }, + "account_number": "890", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "5059098630" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382612906", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1kfnt5d5fcma9kh4c5jk85yu75jer72kwdltg4s", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Az03VLbUjwRqPitI/+dy8zOVZ/Uu10HsgXck62v86dvC" + }, + "account_number": "864", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "22892956798" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382603253" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1k22576dxnqasv25wy542wc3sgj30gm4gmdpec2", + "public_key": "cosmospub1addwnpepqfdercwusxjpjk5f48rmarw39e50pvs97e3grajdaavy0q37p789wpw90zv", + "account_number": 515, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Au8SL/yeRcXhJB16nuIOlZxAt2/396sbNbq7lzN7K9dM" + }, + "account_number": "754", + "sequence": "9", + "original_vesting": [ + { + "denom": "stake", + "amount": "348571452" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384789735", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", + "public_key": "cosmospub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2rlf45t", + "account_number": 61, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AyrL/jOSqkVYGxHdVelG8+fRp9lZUQ2iuE9oWpBCw4ML" + }, + "account_number": "872", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "16788523620" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382589970", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1kv74z5g0s02jv72npe59l4qkn45q7r46xwx6nv", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Av7yEbWMkJv5N7S26XCo6AyXb8LVIsWWEEI8zxk1IuaW" + }, + "account_number": "258", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "1132497455" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382607881" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kwqgs5v74u9wvxjerktm4mkaxqn4w7z3u6w6pq", + "public_key": "cosmospub1addwnpepq2zzp0ap65gqsflg4796v6nklfmtsqzh80unaf0jyam4x8ywynfq73nuz49", + "account_number": 448, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kw46xpry8rw4xn0fvv84g0af2mfuhxpyd2m273", + "public_key": "cosmospub1addwnpepqfu4nd4pj9p99l44dyqc4rqf85ueyt7g398zfzg7u79mvgsz4lfvjgzv8yf", + "account_number": 857, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", + "public_key": "cosmospub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrypl5y3g", + "account_number": 131, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AuE1SL976KwEaxLFwwsOgHNgcImZQFmL61ZEoKRYZzUr" + }, + "account_number": "730", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "8589655212" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384910275", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", + "public_key": "cosmospub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus9suu93", + "account_number": 85, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1kszz383fcxdtxhn3xr42hvzp8rfkaaqevxmrtf", + "public_key": null, + "account_number": "438", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "21199999636" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382619441", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", + "public_key": "cosmospub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwua2qq2v", + "account_number": 666, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1k3rapsk6gmfzeugjq5w2c4msuj7t4qhat0xn4m", + "public_key": "cosmospub1addwnpepqvasmgxsvyqzgtzfy8mf76ryxd9m0pz5hdkjvpurvhmfmj2t6vyp7ule3ey", + "account_number": 459, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", + "public_key": "cosmospub1addwnpepq2pnmqvu6uvxhy0t5zyez5wjcvsh5pkqlmta3uyeqy0yzf7tp0n76fpsh8t", + "account_number": 548, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kj8uw44q0fh3znllyxdxr8tc05qwnswd6fv304", + "public_key": "", + "account_number": 896, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kjkf4umv6g2pperq6g74mayntlrp4a7xypuvmr", + "public_key": "cosmospub1addwnpepqd5g67rxh3lwyx38nsp82d077qcj950af5dgsegzntu2x4mqmu876dajt6y", + "account_number": 682, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kjupa2w6rlhzj9fjxz35m02g2wpz790fd6mf0j", + "public_key": "cosmospub1addwnpepqtj39qcdlmh7fr77am26s8as06l9v3p426z5gr5dyfvc4fr5gqyevf4kqr4", + "account_number": 546, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", + "public_key": "cosmospub1addwnpepqwdhe2nv5ugezx2nkyx7t7z255pj3xle6kgcpfdkmwdng4vp7sa3y6rly3u", + "account_number": 222, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kkruz0zwzf7ynu5y9y40ef950f2n3jrdp0lkr2", + "public_key": "", + "account_number": 686, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kmly2aspt8rk9h4ukdt8h52k24alvc34qukp2n", + "public_key": "cosmospub1addwnpepqwac5an6ey8yprrjfh3640q8l5hg7w4fgrlu54dm8dzacu0msnv479043tp", + "account_number": 350, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1kueuhkfx5cvcuakpfd62y9kzxw3unlef07g2u4", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwZFQFC+Nfemfy6nkm9M8q41mAxfplIAeKT7H+k7/fcA" + }, + "account_number": "615", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "10263331477" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585626" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1kum8rm8vqscd4zafpt39uhsdmcsdcxmrg7znxy", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A5VBku5DuEoMyiNcwnJzwhjtTGeHn8SakMkPXbGVdRFc" + }, + "account_number": "757", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "23168113123" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383783348" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AuCG8oHnLjwMqFy354Kdvy+5saGG6z4lEBz10h09wTmF" + }, + "account_number": "483", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "9286705427" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382837408" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", + "public_key": "cosmospub1addwnpepqtwlwcajqxexfgfd38r4f3zhqxzvupczp89m9y39kt4xqufa4n33csw883h", + "account_number": 289, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", + "public_key": "cosmospub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9u89uztr", + "account_number": 227, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1kl0sk9crf0ru82ejpk8a7zexp2kudszsug5u8z", + "public_key": "cosmospub1addwnpepqvqxjjehndk20k8m2eryzf7us2je23gc4x6m3lydtnucmdyv2jaauhgjvth", + "account_number": 644, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1hq6jh5rru27mkd4c9hye0a4wkq9f9w4n4jx9zj", + "public_key": null, + "account_number": "480", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "14635056784" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383954298" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", + "public_key": "cosmospub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkfhzxax", + "account_number": 73, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", + "public_key": "cosmospub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqkg56h4x", + "account_number": 327, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", + "public_key": "cosmospub1addwnpepqtwvf7g53a6nlvcr6exwkhumshdv59mh0jaa8umfdts70dtupqctxp6p87v", + "account_number": 43, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", + "public_key": "cosmospub1addwnpepqdrvr2ne6f9hgqca4s5fe3uwfxctwdr4ne2lkmmqsgfv5uw226l85z3pjep", + "account_number": 155, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1h9wg5q5x4gxkkca0x7krw7953h0ce2xwr2cwl8", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AlwOPlDnD5fwpHOqKL3ULbhS+Y+1tXFggcQ0JJFW3eH1" + }, + "account_number": "286", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "22658384934" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382601738" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe", + "public_key": "cosmospub1addwnpepqg048v7u9cfmrxvk8kp4rwr3z3cn7lwsag6nyf5m9696lrdquk44ypzwq8x", + "account_number": 377, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hxdqddf3u8vjm080ytpe959uktn4axdas3uqhl", + "public_key": "cosmospub1addwnpepqdm5qzsy6r8f29za6hghdk4ej8hujywh6dsyteyguvxm5h64an8rxqen7nq", + "account_number": 625, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hx0cc2lvfagl5q5x34qea2fc53hhr7mtgdy75v", + "public_key": "cosmospub1addwnpepq2tprqyechvwunl6fmukhs8ffz5rfhl6hf9m6zdrnqdqc9ngtgem2jxyj2f", + "account_number": 698, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", + "public_key": "cosmospub1addwnpepqvfuwjyepzrr7elzg5d2u9m6z4aujww6l25gnscerc76t68tvnjd5y8rup2", + "account_number": 435, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A33KtO/dc6gm5BSPW2iRqyL0FxBYjexsfRMM1ac1fweG" + }, + "account_number": "783", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "5881381635" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382610250", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AhBu8uF8OtxSYWs7pNSqTGde+0n7SLj/HdftHWj0hpVe" + }, + "account_number": "810", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "488919738" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383227856", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1h84c3yuxd6k7950wh868tcsj5tmvzetykv8lld", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AvS7EY+ToyDgW0e68mS4OLCoNg58UGqP8QSn+yUiFzIi" + }, + "account_number": "827", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "19906435459" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382582697", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", + "public_key": "cosmospub1addwnpepq0xhfz0m55nz4txp2v7ttr3zxa9339nx6tjfv24xth38qs7s9qw56jgvkqa", + "account_number": 728, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hfjku50s3uhp66wuqexafzc3kl73z3xzhj5nqv", + "public_key": "", + "account_number": 681, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AzCLa80Ql3sKdSSQkDw+LVUrmkGdc096AmXFqbsfuqa8" + }, + "account_number": "796", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "8860992734" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382871829" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hvfg35av2nfcjvx8ks035jk66dzvfvl24twzza", + "public_key": "cosmospub1addwnpepqwey499g8fa68wl6c36dhtg5psjtsc47daxxkh8vvwer5azmfvlvxqlutm9", + "account_number": 702, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1hwt3fl2gylwdechqwq8uhmhsl04gn6ksw6lxlt", + "public_key": null, + "account_number": "838", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "14484645995" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251385143788", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", + "public_key": "cosmospub1addwnpepqt7vpfm9vgvxg3sqwsn8y6yacfnwvqf3760dck340wqzsnnpntcgymm70qn", + "account_number": 906, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", + "public_key": "cosmospub1addwnpepqvg5y5xv9eu0yd4rfztn6pehqnxcc0hy7wxll35vfthehmg2w59nv06kj22", + "account_number": 115, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq", + "public_key": "cosmospub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqp5w5ad", + "account_number": 19, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A6zgOW3xxZawyk94+zY3kpjRD0qy3Aiz6lsO1XdqNTfN" + }, + "account_number": "454", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "14841485341" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383865686" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hn79l8dj3u5llk78cjhsxcvlaz0jh966x4ez7z", + "public_key": "", + "account_number": 837, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hksxwc7h56mzm9evkpyg9hevlj94g5v003rs9w", + "public_key": "cosmospub1addwnpepqdm59h2t75g2sv24f65vl5lg4336wnhwsxdqq2jwertm839sc4p8z7dajtj", + "account_number": 669, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", + "public_key": "cosmospub1addwnpepqt7ah3flgscnydj0lgv96mv5s6lwsnvj7spwh06kke4exwq5m0aqzgkmzyl", + "account_number": 208, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1h6j4lyvuenmz9m7vq3hler8j7pg5ldpet0xf9a", + "public_key": "cosmospub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7yetr62", + "account_number": 90, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmXrCmqBfLXn7SwgQBPSQ/H7zeK4Ti4527uPw17ox5FR" + }, + "account_number": "627", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "9509006434" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382603483", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", + "public_key": "cosmospub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5veh7xt", + "account_number": 95, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1haw8fcay84fjlsdl5cyev275ldj30z3r27m0g5", + "public_key": "cosmospub1addwnpepqt9e2p4a9lmvuvcsxqvmv2qejkvuf0tgad5g7y9guk9j8gqgl0ggq72vltz", + "account_number": 250, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1h72kkqt83nth0npqvgmardgelg6jyx7zupnypp", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AtTYkm3LN+C4/8JUX/BHAGrPQtPwynEvFQ4CC4o9GS0M" + }, + "account_number": "493", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "22467032737" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384258650" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", + "public_key": "cosmospub1addwnpepqvvf87wq27y92aaj8csgp4s4vqu69xtm4td3qdp3pr5etfrdn6v7wlaxds2", + "account_number": 195, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", + "public_key": "cosmospub1addwnpepqt62glh2fvu9vulmgvh6xqupdqk49yzpk497jcjayystchx48f4kxgq9chf", + "account_number": 81, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", + "public_key": "cosmospub1addwnpepqv3wv7f8kkr7rvmkgeqj96y9yz0nkfmh3wq9ah8ky35trmr8upsavtmw578", + "account_number": 888, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptd8zyma", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Au9HDVpvofXyT34gP8UxF8hZm5Kv7JIB9xvMM2E80uAq" + }, + "account_number": "540", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "9605917851" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382619921" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", + "public_key": "cosmospub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czp42c0n", + "account_number": 9, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1cvhkglegj4zamjrdulawtk4rq658wnm9te6tgl", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AggA8N91ceSGaDEwQB2+P7k67ma4cyynE3JL6jpBsYAq" + }, + "account_number": "304", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "21462868930" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382594033" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1cv6mc68xznavrjel5fth3vry84wnwjy29mqn33", + "public_key": "cosmospub1addwnpepqfyw84lqddzlu0ts4fe3jnndrkkzu4c86283dl3mgz69t6uyhkx3qxyaq06", + "account_number": 750, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", + "public_key": "cosmospub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxkjrpqy", + "account_number": 183, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", + "public_key": "cosmospub1addwnpepqw0vltqp3vc6p6cm0rwsxyxw3f20w29z9kex0epxxaxnnmufz8rs29ty2z5", + "account_number": 595, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1cwk6x5smzaqhtrz95z0sf90d8a8d9vfrpaufnl", + "public_key": "cosmospub1addwnpepq2xv4j2entw32gleec66tekjggte54d28w887kknecju9ah2k538cxdes3p", + "account_number": 541, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1cwl6ck677m959vqnjhyynnlpx4n3keh5ujzmm7", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A6PbpIkGvR0roCcqNV7KjxZZD/d6uG3AT/6JM5Hjoz6a" + }, + "account_number": "532", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "18024237910" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383411944" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", + "public_key": "cosmospub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4sr3d6lt", + "account_number": 132, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", + "public_key": "cosmospub1addwnpepqtumyzl7hulm5v6delsx7hdpcye3stda9rxz6jgjf2eykqm2jh20kk75wm5", + "account_number": 233, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1c3jzrd6ju4l55yna9pcrc49x0xkcv2hczxjw3u", + "public_key": "cosmospub1addwnpepqtveqm5g7826cznecdhw55ya8dvfq6zug79fvxy6va5gaqthxdp427py9ua", + "account_number": 416, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1c4qcdf8mqwyf7rwgkvlputdfwdfnk42lul4d5j", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A23RVmFk8n8SW+HpwhOgbfF4N2nLozhP55o11ZdX4Yq8" + }, + "account_number": "268", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "24135596321" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384292647", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1c4w30j37que0ncnss65vr40nuy7d5msegmhgs7", + "public_key": "", + "account_number": 473, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1c4lft2m4yyrzjsxyu7nzsrxuskgtlr2crzzwwd", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkU30UDYVkL4ofv1i6yPRLxq98qR4fplZLZReeZbJ0+G" + }, + "account_number": "699", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "15882518869" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382596750", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", + "public_key": "cosmospub1addwnpepq2n3nxrwxc027jequjln9ps5546ahg3p2h3t3lm4u9vmahke8kxw6sh5545", + "account_number": 430, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Al/NPfBH4ibOPL1k3Utu0nD5Yq8b/qwNgow/2KTtipP0" + }, + "account_number": "743", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "16731364774" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384463202", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", + "public_key": "cosmospub1addwnpepqduttph6whz8ngwywhy0hu3c9kxww3hqh0f0mrdkjcvg2h8q3u8cvxs7aae", + "account_number": 279, + "sequence": 11 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1c6afa9c3repulws30tzpsggt5jfdpc88ct47wz", + "public_key": "cosmospub1addwnpepqdnczv83gvvtr3vvyq8950052656kfmkfh6mgzgusa8xcjjkps22w2mwyjq", + "account_number": 614, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", + "public_key": "cosmospub1addwnpepq0zx0lgud48vvwy6lts09r2l9e8yd5smkjfzzmfsfw9ps33400vwgzspy5y", + "account_number": 764, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", + "public_key": "cosmospub1addwnpepq2prz4vype8mhmwnvw537vf53ftm02nlpgefm002drthw6py3533277lfju", + "account_number": 343, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1cud0s54s6cf9sl786mhjlnzhm58v5cp324fxv3", + "public_key": null, + "account_number": "290", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "15083188523" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382592977" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6x000jc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwdqS/i2wpfAIG391T6gXnC4QhTYpsh/0JLRlZ9wGhTz" + }, + "account_number": "510", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "15756319400" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383886036", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", + "public_key": "cosmospub1addwnpepqvhqzk07yeludsgh0nffk465d2seqmav2prd2rs6alu56l75w3dyyrjcppp", + "account_number": 341, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", + "public_key": "cosmospub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzukj7qxl", + "account_number": 215, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1e87dgtw7cd28mt4mm3s4uaaxpapanexw9grzmg", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A9gUNRKj2CO306ZR1r/NAPdmB6gQbX/A62ybaC/ZThl1" + }, + "account_number": "321", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "19823952642" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383235785", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", + "public_key": "cosmospub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj9u4vzj", + "account_number": 138, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", + "public_key": "cosmospub1addwnpepqgxhtkut5ur5pju0zjkw8lhhfyusz3x409c6qet8yrpd0p7czcadg7uevsq", + "account_number": 181, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A47CVOEAoQCP+7sWxeH3uc/2R5wWsrmv4plmAUwqGfLo" + }, + "account_number": "347", + "sequence": "8", + "original_vesting": [ + { + "denom": "stake", + "amount": "21152707569" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382596691", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1e2jxyxe4ekjsnkzcup35r8404hxxmntmhpwsgr", + "public_key": "cosmospub1addwnpepqwtfyc6jllhvpgtxalykgrt50jt3npwjymnuuat4u0y35flmeeld68nhe97", + "account_number": 679, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1etrkjjjjvuej87yu2pv4mcmhjsjqsn5hm9n043", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AsmrfunCum3cMzqtk5xMw4R9764J+rVwIqh1Lft+9ovR" + }, + "account_number": "452", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "15181358386" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382943578" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1evqmj6ahqf76keas4ymhvf4r992kg7wrar0fru", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ay+VqqS1HkrvT94ylIOZdwoa5m4aMc2/EMZ5z//doXmq" + }, + "account_number": "710", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "8434446711" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382594307" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", + "public_key": "cosmospub1addwnpepqww4ac9sdmwjurlwyea8de788rvdqu2gwzv5ukdqnsefzyfjdjtgvdnnvr9", + "account_number": 179, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266", + "public_key": "cosmospub1addwnpepq28x4gcrklk8r22c650tktvywp0hfwv8hwtc0heq6d8wr2kagh2j624vpex", + "account_number": 123, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A6CacgMtPikJmS9D6NfNr07oPSMkVNfVR8nz/eVbqbNQ" + }, + "account_number": "596", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "6651076569" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383266107", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ewm28x3e9t3huptgm36wnwx0zcx4aa7numjadx", + "public_key": "", + "account_number": 276, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", + "public_key": "cosmospub1addwnpepqg5xpfg42kdy5fyasz6fs6wh4c8g8jmnfehkx77jk9lk5kwhhm2uurgqtt5", + "account_number": 884, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", + "public_key": "cosmospub1addwnpepqgh6neaxc5qc82vrng427tmhlw78y4205pselprm387vgy5vkgvhcgqn22p", + "account_number": 816, + "sequence": 9 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1e5zmgnq6y7zxn5c642ty3jxur3lk0n0ca4wyym", + "public_key": "cosmospub1addwnpepqf3wz7kcmyvwszetwvsrfvehwqyu8znd47489s5udpzq3jekpgm9sxn3gwt", + "account_number": 758, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", + "public_key": "cosmospub1addwnpepq2z0tus4q4stns9dvru8ju7zdsjqqupgjwf3g4zlux4805ku0ccck99xkpm", + "account_number": 303, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", + "public_key": "cosmospub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6er0g4u", + "account_number": 209, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ecfsusjtvmp57t8n22j9vqx75g6yxdra5vk49e", + "public_key": "cosmospub1addwnpepqfvvqyk2hxwxa98ane0z709sa6dffy880dzk8sdl9mwhvgcd4we7zccuugh", + "account_number": 711, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ai5fmTy1e7FAL3KOs7bNclRrHIM0peMJ/57FBXyduNol" + }, + "account_number": "502", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "21735949807" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382591535", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", + "public_key": "cosmospub1addwnpepqt0sk5rhcpv85mjvladxx3ygs0auglwcm4xpurjqeex8z99ya86367wwghw", + "account_number": 71, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1e6ffgexkzs2lke6dywcju2ltqcjej2e7y4q8e2", + "public_key": "cosmospub1addwnpepqvy2kxmycme83ha7v8dcamwvjae53qzxs5k57sf4c35asdjxlcgmvhkmpm6", + "account_number": 525, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1em3y3h4g7n8ue3wjcramnpmz0x8rwakrpjmrgz", + "public_key": "cosmospub1addwnpepqdhcc8jww3jnsk9s3syxvwqdur5w8lzgvgujsu0j8n944m68ux2d2ehtcss", + "account_number": 291, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", + "public_key": "cosmospub1addwnpepqvd9wuh5nnx26hudxvsypaaylga405wrhenxwmrju8ts6s52xra8j6jlusg", + "account_number": 365, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", + "public_key": "cosmospub1addwnpepqghn86gscad5np6l2h0zte7qa4gylqvkzdznqwknhrxk6v7al09zv0qnxvk", + "account_number": 218, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1easmlky76c302my07gffjxjw0a2usueaw8j46t", + "public_key": "cosmospub1addwnpepqgejk6vtn62t483xtjytvg3dq8h3mh8jhhkt0m2quhwzrzlk3apxyvasxan", + "account_number": 342, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", + "public_key": "cosmospub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjt5wfve", + "account_number": 118, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", + "public_key": "cosmospub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75xmqqh2", + "account_number": 25, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", + "public_key": "cosmospub1addwnpepq0k56l5wh6qrl4fmp9jl0v78qy4jahrkkl6xqjc2zmap6tjg4h23gg7yjw9", + "account_number": 67, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos16p082pp2g44jm5sa7x8egm2089gw908s85szsm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkwElCYsDk6ViVa6g5lWW1yhTt1zy2+rkZnsnK76/uOE" + }, + "account_number": "851", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "1857575892" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383285179" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16p0aw2u5chfc470xkpc6vasz5ys9smqcx40qq9", + "public_key": "cosmospub1addwnpepqdkpkujsj0msclz3najretvktts8n9jxzhptqc558fapdglwgkxs7ua0pna", + "account_number": 400, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", + "public_key": "cosmospub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwl6ruez", + "account_number": 8, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8", + "public_key": "cosmospub1addwnpepqdluksf6scu7m7p5ggj4da3flt6jk97kaygv4ut3lsqjepkwtk6qqzd8mvl", + "account_number": 628, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos16x5vyv6aej2868kn56wpxpgzhvtvyegpjpwecw", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ay7QtwrrJjfxC8J9E17vHiF5AzReJqt7Ok45KDNGDeqH" + }, + "account_number": "898", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "23396058414" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384783069", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", + "public_key": "cosmospub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg53y4gj0", + "account_number": 194, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16tr72kn90g5zl7qhyhuqkjflejz00uzlkl65sj", + "public_key": "cosmospub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55c0faqt", + "account_number": 48, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16tgzg562uhpczcma5at24uvw4a3n0u322jurd2", + "public_key": "cosmospub1addwnpepqwpv4t6jfup40cxuzd36t2acyk9re34rxu6ca2wv23gavncz6whaktjhtnu", + "account_number": 282, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos16v3h2mggt8tnkxp0vq5tq25fhr3knvf4jw40l5", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A+CIXYXaTgJ5KYvjsAGUEEPIgrvDhzvnmTtjYDyLISdj" + }, + "account_number": "371", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "24340309841" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382621640", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos16035vhhlcxkxysgfkruk204jvw3lmyhpkn0ffv", + "public_key": null, + "account_number": "885", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "22970686311" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382604971", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos160jtaz9c35nr7dx349ezfzvs3xfdzm3mlxgulk", + "public_key": "cosmospub1addwnpepqf93mjmpp8lvclzkkfvx5k76mqyscz7d9dws74zevaxu5z9tv7kuz23p56a", + "account_number": 787, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", + "public_key": "cosmospub1addwnpepq2d8k6kg75hjwqyknda4mj9wc65v7rzcqenfv039tnkwjss5tuq727mp602", + "account_number": 153, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1639hgh9ke9sxqy7kpcdcu6srk983upzjlf8mwx", + "public_key": "cosmospub1addwnpepqdnd5ugq8svul038v2sszz5kss342wyxg9k0aa3tdt76e9cj5psw72e63u8", + "account_number": 284, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos16jj80c7d94m772cn77zwcuhnqcl6y95kepxvja", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ArMCLEOuM7kIv3fGebyQj6MOOFDJ8co9abVkVRlHwsnr" + }, + "account_number": "428", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "6516026536" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384991661" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16kuse8g39wn4yzx64shrzned2lgnk0kepcuu9t", + "public_key": "cosmospub1addwnpepq0unlz4edy8fx2yfrmx3rwwakfwjlp2m9paey6agfupzrnknzwepj5arm5w", + "account_number": 591, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16erf80gpn7xquce9qmk2uzf4lzdgcgc55ra2y3", + "public_key": "cosmospub1addwnpepq2msqpv5ce7q9hkpgjje7mvfy7fep6jmmxr2hj2jdy0em4ph8fqm7r4adrp", + "account_number": 709, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos16e0y65dxvzn3zqlpql9uc3cmc3adtv8f9gf9ue", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AyMjsNIWTXtTkZ9VJ2kLEfqWCgb1gGAbfMRKLzKynmWC" + }, + "account_number": "823", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "15979511514" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383548464", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16a2sxhxlq7qfvkam3afnh9y6ph2lga8fn6fyqa", + "public_key": "", + "account_number": 302, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos16adevt9lhqf3q4dwnmhty7ndr8478thakltsdj", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A5Chg1TuB8OyuW4Mflfwfj6pxTVjedmFuYhBdm9gxl5l" + }, + "account_number": "449", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "21563268573" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383296500" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n", + "public_key": "cosmospub1addwnpepqwux9qwtmnuzxkw7203qndplmsvj6lpw9670wlu6sgaw6y30tzuhjcrs463", + "account_number": 789, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "An4mdU0NCkdAWr9+8UAJ6CAWP9B7Tf9wBF+5a9U2RDby" + }, + "account_number": "689", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "635421657" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382594263", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos16l54emw4lwhremfds2mnnlxcu06eknp8gxhgq7", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AocYTNJKOxpnL3xHvmz9AL+qtVbxLKr0VmQuSfvcVss/" + }, + "account_number": "257", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "20469989764" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251385065256" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", + "public_key": "cosmospub1addwnpepqwa26gwxuwwnhmgz57tcvyqvj23qft9wryeutcms0z4ss9f5tujfcg8mgy8", + "account_number": 217, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", + "public_key": "cosmospub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxzxl9sk", + "account_number": 27, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mzsvp23mjrjkspddkz6nta0x7kte6a23atg6ml", + "public_key": "cosmospub1addwnpepqw2gxruh52umsuh8jd7g78587jx0qd4skze2u2dm0sm8shx64tvcck7gh4f", + "account_number": 196, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ao0X95vSz/7xwL+VAVlyNpO0Jpw3mYhE/OWCXtLqP53X" + }, + "account_number": "363", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "19675956933" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383287647", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1m8g0mk56ne6uutj5a8drc92um8cjk9frunx8s7", + "public_key": null, + "account_number": "817", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "4113451544" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382622776", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AucVdMYLinH6gshVh5K0AmiWoW/kY1vzYZvOgzHjNwna" + }, + "account_number": "372", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "5833365049" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384611150", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1mfa9me7lxg0gja78krqzv2sxqpehlgrystzdvm", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ArphUB/rBBtZQbRoe8JXv7/D4o7lpcrs3l1bdxBeTXSF" + }, + "account_number": "296", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "7617475832" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384296169", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", + "public_key": "cosmospub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3luqvl6a5", + "account_number": 211, + "sequence": 12 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", + "public_key": "cosmospub1addwnpepqvurn7xmqx4f0jluk6suggumrnxx9zsz00q6fgfggpnzt8yz5gfawdrfxsa", + "account_number": 467, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", + "public_key": "cosmospub1addwnpepqwvyafhmcqnhjk3t6jzdah2rzaq2cqpmz9fgll8493g9nrpcxz4sc3s2gzd", + "account_number": 316, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", + "public_key": "cosmospub1addwnpepqvtj36dsackmy4p87dys4377ysum2zku3v7tjqtf5jhluzgxk5vqqs54prr", + "account_number": 379, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", + "public_key": "cosmospub1addwnpepqva6nvhvu5wjsfmu4qhdxwe6jtwnjmpzxkhs8f4e006anzaaqv5tv9vdhyl", + "account_number": 805, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1md3expnuxrws0qg9dpqxh5stns8ugvd6uh0jrk", + "public_key": null, + "account_number": "713", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "3063833227" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384310671", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", + "public_key": "cosmospub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcxa70w7", + "account_number": 125, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", + "public_key": "cosmospub1addwnpepq2aplsutfgppd2msqrnrmeeejzrx8232yksx5v4lxf902rc3e59hspu4jr6", + "account_number": 799, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ModuleAccount", + "value": { + "address": "cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q", + "public_key": "", + "account_number": 921, + "sequence": 0, + "name": "mint", + "permissions": [ + "minter" + ] + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", + "public_key": "cosmospub1addwnpepqv9arcz0k33sqlng4lqppz6wjctjdpru7slvs2hrdhgagads37lr6fhd2sm", + "account_number": 175, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfej3rle", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A0eDAMOIc45IjXiwb1/3FGCJ5oQcMKbR48dLI/rcAWDZ" + }, + "account_number": "751", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "2111619031" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382926881", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mn2w84lgjyemsggq7eyw8fw0wreclx0w6hfmcw", + "public_key": "cosmospub1addwnpepq00nh3dxxhtu0npunnf7qdj5lqqczklt2msk4km4s598482h4dunzf4pst3", + "account_number": 348, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1m5aynwlefn0dn8pk5d6j705zh29qstsp4dh02h", + "public_key": null, + "account_number": "478", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "8833783710" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384225738", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1m4xvwvq7qrr0wy0ryeu24eu8482h4n7en2x2mh", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AqkasSiFULDtF1Ut9JseVDGXgqB5EawSKMYToyU4aJwS" + }, + "account_number": "471", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "4112522009" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384725177", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", + "public_key": "cosmospub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr25vcte6", + "account_number": 82, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", + "public_key": "cosmospub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngks855td", + "account_number": 2, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mcc0dq93nrt3u6hl6ju82hyw3rdfun029jx4v2", + "public_key": "cosmospub1addwnpepqwgl56x4s43fltc3trfq7lsj32xtrfdnc37tfevage4uv7cr3ukkj4czs9t", + "account_number": 579, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AiKkmhzKCYhYOT7PsVurApE3oyqffhU8ydsk2EdIOMi4" + }, + "account_number": "693", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "16903055958" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382615165", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1m6y73jlmfnl8ywzrjggruy4nfk8hkgnwve5t8x", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A0inxd7Un3TdC9Oxx82HbM5i2I33Mtv6N9hD7i9td+7g" + }, + "account_number": "504", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "15099636055" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382590974", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmJStpKM9W7k3b91rmByHXqBM3bRgkJSv7oASp9bvnyX" + }, + "account_number": "397", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "10725654048" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382604856", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", + "public_key": "cosmospub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdqg9xyj6", + "account_number": 229, + "sequence": 6 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A2XGRB+g2UnIm9KBxvHepSvYV708M8SHyaiZoCjrbBWV" + }, + "account_number": "427", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "1186041662" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382619443" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1munf3xa25sdu0sdxwyqxhz88c8l90llmjsslvj", + "public_key": "cosmospub1addwnpepqgqxdugstqxww8xf38psl7unt6y40jcakwqjcqufu5rw02z4r829wmkthf0", + "account_number": 607, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1m75flstcn3hpq9am7dnvkw79e6jckkkjd59p9h", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Azmo6vEVQ6XMhEnXv12xGnRd8aYYBqRw20Ag6ENHARHT" + }, + "account_number": "415", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "10616187068" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382615331", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1m7m72dd80k54s8vg0v5z6h334lumvj3ehn0pyp", + "public_key": "cosmospub1addwnpepqgncsvs6kpx7ef6flhdg87smgdv9lrnkvtp6zk8kv37esheg6wkcgel7uvw", + "account_number": 645, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", + "public_key": "cosmospub1addwnpepqgkr2p0m3r8u4xaeydfcgmy66nr6whqkfc3fjk7ja0uzw7jzyw46xt2m44m", + "account_number": 727, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1uptqu7jt4krnqwlx98nlxs5fg2a0fncvpyhptj", + "public_key": null, + "account_number": "913", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "10289348273" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384243574", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", + "public_key": "cosmospub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwrms5ud", + "account_number": 210, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1urnp7yp6u27nut8kvsrapgmmvk8sh6u5wd5dez", + "public_key": "cosmospub1addwnpepqwajn7v8p6zuv8er2l5c5qwa2v3c86xw8sfhrj37a7x8353g2jspw2kscxh", + "account_number": 640, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", + "public_key": "cosmospub1addwnpepqd9mxy4p6jva75efmzsjq5avn59j4n829vx6x9stw90wzg9urga0qmh2r7g", + "account_number": 717, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1u2uakvrpv8htq6a7n29hlpxxec956caj2akqcu", + "public_key": "cosmospub1addwnpepqw9qy7tfy32w0vdxwhqta2hmmk7kmfnpjedz6lu4j5pw5p2wjy3mxk83f6t", + "account_number": 580, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Aidi6GS9OuDYI/kJjbAV7dA3Ups2zVFpAVGjhU8HTQjo" + }, + "account_number": "553", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "455358399" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383844784", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", + "public_key": "cosmospub1addwnpepq2y0j3sd9kxmqftpqxy9enzjuyzn08t26d5nk02anpwc0hezkzg4x0kandp", + "account_number": 513, + "sequence": 8 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1uvm96xdewfpdwymw5ywt8j5efq6jhpyl35pzg8", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxjlZftjBh1AKiP9ayuiHNP49UTuAPpyjqeEV4JBVNA5" + }, + "account_number": "426", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "7430382120" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384473140", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1uwx5cecec8v2af2mdrq3p6gv9gtv4gza5006gx", + "public_key": "cosmospub1addwnpepq0eu2nu0k7vvglv36lukp9x5phn9njy50n5px2taz292gd6f5gz05rz5yjk", + "account_number": 325, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1uk8d0xdv7kdhlx3wh4pwff6v6rcx8f970fyjgm", + "public_key": "cosmospub1addwnpepqwt0pya09r22w4ndrfcvrfr4aga6w5pmnc603m5x5kdel2h62h8vwu2xqxm", + "account_number": 505, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", + "public_key": "cosmospub1addwnpepqv3hq6a80j5hvu0na7e5llp5gnfn4kjdc5dyctlvcqrqzvrnkg03j00wwy0", + "account_number": 866, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1umn8dwc5l034syha3xehk0kmjaajdfyedajtka", + "public_key": "cosmospub1addwnpepqgnkw6ntpx4l4p94m62ln8y7hugqdyt6af8maxh6w2hw4z2xq6sg5e5xfkm", + "account_number": 355, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1uuk9ewj0532rzlhlg86tserdxvtnm3kq2k2zww", + "public_key": "cosmospub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwj3nnjy", + "account_number": 191, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/WXt3XJFfiqZrjJjuRaPlDl7lorFgfcPvZ8tOsB/OWK" + }, + "account_number": "647", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "17214281111" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384027658", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", + "public_key": "cosmospub1addwnpepqt5anqq3knyh2wydkq3u8cwjfqnmqw633ca60tlzd0al29dnl0lsypsh6yz", + "account_number": 903, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1u7e0dy2dr65lfs5c2scvn9xzrntteew7lvuw7w", + "public_key": null, + "account_number": "406", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "4718441430" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382602884" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AvBh5gIyncrNDY93lDUXLSpUjqS9doZA+lZ7WvESY/+S" + }, + "account_number": "777", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "4761380400" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384504666" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/d98xvFJ1Pvb9ri8BGi804YgSvnNa+9CfqMxklfhXqh" + }, + "account_number": "646", + "sequence": "7", + "original_vesting": [ + { + "denom": "stake", + "amount": "7928869580" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382592142", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AtrDzlimhk2FeccycJtXMlKi+Ms8YadHeiTesxH5qVF4" + }, + "account_number": "530", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "6621813014" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382604624" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", + "public_key": "cosmospub1addwnpepqd53md7mk6edgy52e2svr0j93ugzvz9s29axp9mcktw4d02fjcy66qw333v", + "account_number": 775, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AksIfPCdaieHnczGZfdiLGzxtc7sfdfwj50iWC935xQH" + }, + "account_number": "604", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "16834614865" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382592451", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1ax56w233q9c43whd6sdy52v2qhuc8lpjs7gks5", + "public_key": null, + "account_number": "624", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "756065317" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383577052" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1af3ljdelv635n7yh76vvvkcs9adg6pq5z78lqn", + "public_key": "cosmospub1addwnpepqwhgf2gz58tewjlj7l5rgy30npr98jnzxvjqx7f6e4sfy83xxup876fgtk7", + "account_number": 753, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1af6mnuvcs8ypz2272x4vhdw9dkc25ac87z04l8", + "public_key": null, + "account_number": "723", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "360329391" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382908810" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1a2sgqjezvkgzc6vhvmevtsjh8m8rp52zcfu7ga", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ApZlmB5TSabB6uw5onnEU2En5HSYF8KqDQRWgEZnhbzn" + }, + "account_number": "339", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "14044295291" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382616349" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", + "public_key": "cosmospub1addwnpepqvj6juduaknlhehjt785gk6vkv8qhqykv5d6zupvwafe38t0unzxglv5xk6", + "account_number": 688, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", + "public_key": "cosmospub1addwnpepqfw46rg95l70w7lekt8eh7szxr7ms8mfhqvz0ywnpc7fu25f6hj728cjap9", + "account_number": 665, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1adwsqn58aype530jae9qrwknsxyf3wmwdr523z", + "public_key": "cosmospub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyr22pyn", + "account_number": 162, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ad5vqqf6lruklvkyyqvx3926cpjyn0wuz6ga64", + "public_key": "cosmospub1addwnpepq2pfevuuxhe2mmy4nxjhtv9s27zmucxjw79q9y6jl4a27fxr2zxlyssfn6k", + "account_number": 894, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A1SNjafvDaqKj80Ovj3ziSXJsA3iamZFEQ6lFweGa3Jq" + }, + "account_number": "501", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "17720129901" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382586222", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1awyus34e6laq3zxqsrv283w6fgn8w62zkwd87d", + "public_key": "", + "account_number": 212, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1a0jdqzvk078d6486vuxdr5d0yp6rglue2nh5dn", + "public_key": "cosmospub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycaml7cc", + "account_number": 173, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1a5fndlfnwtvyzzt7ql4kvuqgnjut7ua7hkfts6", + "public_key": "cosmospub1addwnpepq09td8a5eszp6sn03gnwlzkynt5m9fgp8qja28pxqhrwfvaj5mdzz2rwryg", + "account_number": 508, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A3vVQF2aZOuLmAJk/C/flfEbZcfu43PAZ3AF+dztS/SK" + }, + "account_number": "524", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "21170621637" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384866197" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1ah3yy9ql35jh5ehykl626e848t2rrsyze8w8nz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AoBN3TFLm4Epk9t2AH+R5wNVM+6N/lTQR0Mo/P4uc4iC" + }, + "account_number": "793", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "1907148058" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384552953", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "ApiEXjoSexWw0Jw9qJuKrs+HUFx7nTczjg5dOEME4mTS" + }, + "account_number": "479", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "14888612438" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384548806" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8kl6qt4", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AhY8AWbGlcsqvcH9EXpwUgXqCnmFPFNZW3mEYMgQdd57" + }, + "account_number": "547", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "21150835180" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382609896" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", + "public_key": "cosmospub1addwnpepqdefatxypu4fp0z52tp76zfp6sjx0feg8ffe5res6pxs520evrxdcjjcm0v", + "account_number": 80, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", + "public_key": "cosmospub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w6073ux", + "account_number": 28, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos17ql89l8ghyguux4u4jghja9hmw9vjkwpkle699", + "public_key": null, + "account_number": "759", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "10598075729" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384805464" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Al5V19lfHB1aGsASC3BaKwN3a8h5gyf9gGQWEhCAzfVH" + }, + "account_number": "330", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "20354737444" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383874583" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17ph7nmvmxdhm687z4k5phsyd08wvsnv44emkj8", + "public_key": "cosmospub1addwnpepqvn4quutlzny26a2narrthzju9dsgk05yjf0vk96lum7vl7rqke5jvzaqjw", + "account_number": 589, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", + "public_key": "cosmospub1addwnpepq0qr3zl5rz8qxk4863w768w20vr6gx26sh7uxr5fvvv7d68jjr805k3v3a9", + "account_number": 900, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", + "public_key": "cosmospub1addwnpepq0p5kfy8kvyj0rl0lguwv5fmqwpsa5cg7gm8mzldlej5smsm6hhmqw7c8zy", + "account_number": 198, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos17z26jlgg6x0hlj4qnl7pxtve270fr7teanj8gr", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AwdV+2fSR/sNHVB4tEULyIjIoEzu9oyEbfZjT8sVHHsy" + }, + "account_number": "404", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "19608075505" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585887", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos179c5a9235h4z7h56gz9dhrj6gyaugvxmjt2e63", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A3qDoODCP/vg2CwZHPIGGfbnU0OFhxiKGTkxSX37eIyT" + }, + "account_number": "457", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "23446843723" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382620239", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", + "public_key": "cosmospub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgcqpv2h8", + "account_number": 102, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ModuleAccount", + "value": { + "address": "cosmos17xpfvakm2amg962yls6f84z3kell8c5lserqta", + "public_key": "", + "account_number": 916, + "sequence": 0, + "name": "fee_collector", + "permissions": null + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos178pm30fcgrt5654czwr8nlex050m6y609glx2s", + "public_key": "cosmospub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkuksqkq", + "account_number": 761, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", + "public_key": "cosmospub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyycyhj4", + "account_number": 168, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AqFX72w4+ZiEspun4R4Du1qFIhHs8TpEo4qstPGP4DFP" + }, + "account_number": "895", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "10902416771" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382622281", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos17gpy6jzg7xdsr2xc7kweljagx4uaysxdk2244g", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A5IFHdhxUTjskx1DJoW0vfI1lvfKDg5A+lE2NdMm1L1J" + }, + "account_number": "662", + "sequence": "5", + "original_vesting": [ + { + "denom": "stake", + "amount": "11542147313" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382616337" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17g3wgr4wy0x5nv9ep2eenc2tucpulq5yjy50st", + "public_key": "", + "account_number": 886, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17fffsvdgtsagwjrc3gxqh9fkl872q40wpvajv0", + "public_key": "cosmospub1addwnpepqgknkrr3ydnutmfjh4q7tdlm45kjvjy9wn6xpntzudfc7598uc9f6krm67u", + "account_number": 721, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnk5g0lz", + "public_key": "cosmospub1addwnpepqwa4x4g5600flnra6sk3xek8rqvuxsgcl2e6mh500hd5ukvn5hea2r6lknx", + "account_number": 716, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos172lmu2psqlkxkthpr46h2ewjffte7lhlmwe6tg", + "public_key": "cosmospub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsvd0dwr", + "account_number": 230, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos17tphcpvwdr8ezywpz5qqglxul6hvx7elsl6h27", + "public_key": null, + "account_number": "353", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "23004313935" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384257285" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17tecr2sngjcm2rc29dzmadtpad2tkmrhj69whr", + "public_key": "cosmospub1addwnpepqw69rhp94kqtr8wre7ehst7hkkurh5fr57kl87da063cw7tzhq2syfu8487", + "account_number": 582, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17vfaz9kp0wysnuhu9pmd9smh4x7s99dkeh8vcc", + "public_key": "cosmospub1addwnpepqgt0gmkfsvl7dynef82pvxke5vnmmwq4uk2whzn3u4g7n3cclzqaxudweq8", + "account_number": 337, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", + "public_key": "cosmospub1addwnpepqwuws3zcs8qd3425yvan5takx2vhud4jlvtfk3lrgtdl5xffs0mlzjh5zt9", + "account_number": 675, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", + "public_key": "cosmospub1addwnpepq2u42wlmn9vx90thlzxmuckxdqt93w6ekdghk9v3rr8jvpp28tghvj2uljz", + "account_number": 165, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxTnwDuX6WBiJlTmSiqZneWMEgycb+eNqrbY5J1pzztP" + }, + "account_number": "252", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "1352830596" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382677350" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", + "public_key": "cosmospub1addwnpepqgvjqzk2vmqxm3j5ftywy5hf04xfg8gl90tsqd463jyrvfprhsu0k8g5w8s", + "account_number": 370, + "sequence": 7 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A2koSpGXtv5sTLle13Zmuk2wkbdPRbgIvjsKTl30A+xs" + }, + "account_number": "288", + "sequence": "6", + "original_vesting": [ + { + "denom": "stake", + "amount": "5058301403" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382583606", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ahr3420WLPiIPKslkdwLOsL13fXGAgJmBglj9GUl5Vgu" + }, + "account_number": "456", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "7559720651" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382618848", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos17nxn4xkn8mvyjl9xg3erms4y43xeazku7rw5rc", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AyA6UeH0mf/x7pySjpFTovPMdT1OAYAfqK6TB/dfhIus" + }, + "account_number": "253", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "19280955030" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383380280", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", + "public_key": "cosmospub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge724v7s9x", + "account_number": 98, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", + "public_key": "cosmospub1addwnpepqf40hwnfaxv6w3yvaaaau2r5c9rumdcp06jd36kln2kt8enm6hqzsy97jkg", + "account_number": 536, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos174ycyhzg358nxm8r6qunzsyx48uk8fc404ckyf", + "public_key": "cosmospub1addwnpepqwqphn8fd6fvcv0kr6ljjtf362wgneqrpky2wzap5srcyz6vhf6770vrct7", + "account_number": 550, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", + "public_key": "cosmospub1addwnpepqwzwg260rcucyql9q6rnkhayydygkjxk7ly526ue3nwsz356fe38jrmslqy", + "account_number": 594, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", + "public_key": "cosmospub1addwnpepqwkc23a70ndeeapn057plztghd0udz8jvf06nxym6tzd305p2kgux2llfpz", + "account_number": 52, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck", + "public_key": "cosmospub1addwnpepqgql4k8d6fyftkac7dtfncw40l2z7ytrz5sk60df7vhrf73z5znxcjm7fzc", + "account_number": 737, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", + "public_key": "cosmospub1addwnpepqvpvaw73dlelg9r4uclgtvvylvfysht9usz0wgsvrl5ztsca98fwurtayae", + "account_number": 718, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", + "public_key": "cosmospub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0uljcq8n", + "account_number": 144, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ax0VbN8Qhb2G0PephGP4hsgQXuL3tUY+LpySfE63gN2v" + }, + "account_number": "389", + "sequence": "8", + "original_vesting": [ + { + "denom": "stake", + "amount": "19490996406" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382593038", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos17eadsw26t8798nfaw2uq6rnmfw6tn3u7np2yfs", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A/fpCGELGoFD3vd6ote1xtdzHJ5IUgEqHLESmD6J6Ory" + }, + "account_number": "692", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "19880742654" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382617181" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos17m4lyrws32kta4pj2atdcc2d7z2qrwkpqk0exs", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AmGzAIwI30MLrRYvx80iz/2A6jqzZeYN5JGzrvWuEuem" + }, + "account_number": "567", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "10938256700" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382585876", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", + "public_key": "cosmospub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4u58v5qd", + "account_number": 216, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A1vxGgyVHy3rjoBUWfOxpJU192cqaoWo6FZ25DP0h4+p" + }, + "account_number": "724", + "sequence": "8", + "original_vesting": [ + { + "denom": "stake", + "amount": "2758412087" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382601614" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", + "public_key": "cosmospub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wugnjs89", + "account_number": 865, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos17lfwqsp85symf9ftal8wdsmvavla0we4h9kkxy", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AyT2FjRoquHB89GZ/GpU07QLSUW0fF5PkY1TKjG0yVUd" + }, + "account_number": "848", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "6720783748" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384976604", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpkca4g8", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AvwemLjgIUZKTLh3hDCUbYAxrGjUY6xE1yDxdeUEVuJ/" + }, + "account_number": "678", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "24768164162" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384624439" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ly9aff4ptcun94q3cs26cfzqnq59j5rw2gl89u", + "public_key": "cosmospub1addwnpepqwexd522g9wrnztyvpa8k0x44sased9erd90c2vzdwc6lwetxxdxggacgfe", + "account_number": 788, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", + "public_key": "cosmospub1addwnpepqdrt48pxhqjvt0yjfxe64vdaknu42wr4dmdt6tah95e6vja950fzv8pvncy", + "account_number": 621, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", + "public_key": "cosmospub1addwnpepqd7yjw34urmgndhr8r8xr2pclxfx0djpjd0vtfgs3swpdwzprcjczashgtk", + "account_number": 134, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "Ap1EavCQrvUmMFxZ36MrfIMDPcETo6RaupVpktpDTklg" + }, + "account_number": "696", + "sequence": "3", + "original_vesting": [ + { + "denom": "stake", + "amount": "4910213287" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382618476", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1l802gyymr2zukzel8ge4ddnqdevjvhnm3g4kk9", + "public_key": "cosmospub1addwnpepqv0zmmgdpyvtphzy08gh9r4e4g75352hjm9derqdkhapxxaavyxt2ukmrc8", + "account_number": 542, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1l8slnw5jukpc47xr0s76htvfftpuku2g26f0h8", + "public_key": "", + "account_number": 419, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqcrj0xk", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A2iqq8yt3Sy+KjfgzSEiZoPVKr6WeuXJ15mm1mBMPe5s" + }, + "account_number": "506", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "18456773828" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382604366" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", + "public_key": "cosmospub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wkn0s6e", + "account_number": 202, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", + "public_key": "cosmospub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6umfwlaw", + "account_number": 70, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1lvzau6mkgwnyewqvd09h307algs2ncrpp2ukjw", + "public_key": "cosmospub1addwnpepqttpsp75lqp82wj00fc0da47jkfptr6d9q88j68n500uytnxkzlskxtfx4t", + "account_number": 636, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxiWxqb9ljypNgNJlaikId7Dv4M1Xeu4gTR44kAXVMMO" + }, + "account_number": "815", + "sequence": "4", + "original_vesting": [ + { + "denom": "stake", + "amount": "24365366613" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382583374", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", + "public_key": "cosmospub1addwnpepqw6x8r9cuvkvguqdx24myp74yx7pxgsg2yfl7eqgghyspvqw2tylqvzj7kt", + "account_number": 829, + "sequence": 4 + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1l5vty6svhxd023rl280aqu0eqjffv0qct2kywn", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AkTvMgRhX7m9fwdnWgNHpiRmJAgDhAqbs0t+mr6cuJT2" + }, + "account_number": "309", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "1767787627" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382608246", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1l5d2lg5hku0m4u8mh866zhjcy2dekpk598m8wr", + "public_key": "cosmospub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xrp3zws", + "account_number": 32, + "sequence": 2 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1l577787urj3qccxypxaznnasxvnn9k8wq5lxf8", + "public_key": "cosmospub1addwnpepqvmsdhudqln86snh6fpr7qfjs5n0u0xst27dfvujtdwfadej57tayryyz74", + "account_number": 695, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", + "public_key": "cosmospub1addwnpepq06v5yue3dkzf9qc3tctcdw9pxmyqz7fm8k9tlw5nc9uzlcah08zux3rmtr", + "account_number": 575, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", + "public_key": "cosmospub1addwnpepqfd79ep9f3sj30yn4uvl5f65q6dzmddudu5a3m0szgpwlv3hjr0a6f032gw", + "account_number": 798, + "sequence": 5 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1lh5v2ew6gwrugasrmt9tr8dql6qnj802lqrn63", + "public_key": "", + "account_number": 360, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A12yzICH9MwUu0q3uG+SpE9U1108g+L5OA1KBAeCt0Bq" + }, + "account_number": "643", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "9452886687" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382606921" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1ledlljk33qdj6z6lssp3w88cq2q38kg0j4vrvc", + "public_key": null, + "account_number": "909", + "sequence": "0", + "original_vesting": [ + { + "denom": "stake", + "amount": "11544444180" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382601252" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1l6u5cg3wcptmcjyhxtfrrfq3nu036acdauf0fy", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxSRu4YhKaJMizzQLgycMyGL2+PWNI+4ayBz0DGaMNmq" + }, + "account_number": "475", + "sequence": "2", + "original_vesting": [ + { + "denom": "stake", + "amount": "16220446022" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251382601114", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1l6uepmju2xg0h8rzkx8wku0hsncargw5ruhhfz", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AgVFLrXBadh053j0StrLY4Mn+EeNhclivXUQpGpoNX0t" + }, + "account_number": "251", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "16040652970" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251383553923", + "start_time": "251382579700" + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1lmkyqhjshfd4mqsgk5stvaxlsxkmdmfhfwh7p2", + "public_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AnpiWNopLsBUXqvcM8GMspvRouwdrKEhQ4AXQ8HSKBDd" + }, + "account_number": "697", + "sequence": "1", + "original_vesting": [ + { + "denom": "stake", + "amount": "501013200" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": "251384688518" + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", + "public_key": "cosmospub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujguc8x8kx4", + "account_number": 103, + "sequence": 11 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", + "public_key": "cosmospub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592a68mfa", + "account_number": 117, + "sequence": 3 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", + "public_key": "cosmospub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxyg36xy", + "account_number": 238, + "sequence": 2 + } + } + ] + }, + "supply": { + "supply": [ + { + "denom": "stake", + "amount": "29053485105638" + } + ] + }, + "gov": { + "starting_proposal_id": "76", + "deposits": [ + { + "proposal_id": "58", + "depositor": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", + "amount": [ + { + "denom": "stake", + "amount": "41" + } + ] + }, + { + "proposal_id": "58", + "depositor": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", + "amount": [ + { + "denom": "stake", + "amount": "167" + } + ] + }, + { + "proposal_id": "58", + "depositor": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", + "amount": [ + { + "denom": "stake", + "amount": "33" + } + ] + }, + { + "proposal_id": "67", + "depositor": "cosmos1trs75ceuvsg83y9dje9k79em4v684dm5e9ya49", + "amount": [ + { + "denom": "stake", + "amount": "198" + } + ] + }, + { + "proposal_id": "67", + "depositor": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", + "amount": [ + { + "denom": "stake", + "amount": "148" + } + ] + }, + { + "proposal_id": "67", + "depositor": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", + "amount": [ + { + "denom": "stake", + "amount": "9" + } + ] + }, + { + "proposal_id": "68", + "depositor": "cosmos1c6afa9c3repulws30tzpsggt5jfdpc88ct47wz", + "amount": [ + { + "denom": "stake", + "amount": "190" + } + ] + }, + { + "proposal_id": "69", + "depositor": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", + "amount": [ + { + "denom": "stake", + "amount": "19" + } + ] + }, + { + "proposal_id": "69", + "depositor": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", + "amount": [ + { + "denom": "stake", + "amount": "119" + } + ] + }, + { + "proposal_id": "70", + "depositor": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", + "amount": [ + { + "denom": "stake", + "amount": "204" + } + ] + }, + { + "proposal_id": "70", + "depositor": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", + "amount": [ + { + "denom": "stake", + "amount": "123" + } + ] + }, + { + "proposal_id": "71", + "depositor": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", + "amount": [ + { + "denom": "stake", + "amount": "18" + } + ] + }, + { + "proposal_id": "71", + "depositor": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", + "amount": [ + { + "denom": "stake", + "amount": "142" + } + ] + }, + { + "proposal_id": "71", + "depositor": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", + "amount": [ + { + "denom": "stake", + "amount": "147" + } + ] + }, + { + "proposal_id": "72", + "depositor": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", + "amount": [ + { + "denom": "stake", + "amount": "163" + } + ] + }, + { + "proposal_id": "72", + "depositor": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", + "amount": [ + { + "denom": "stake", + "amount": "108" + } + ] + }, + { + "proposal_id": "73", + "depositor": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", + "amount": [ + { + "denom": "stake", + "amount": "164" + } + ] + }, + { + "proposal_id": "74", + "depositor": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", + "amount": [ + { + "denom": "stake", + "amount": "58" + } + ] + }, + { + "proposal_id": "75", + "depositor": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", + "amount": [ + { + "denom": "stake", + "amount": "71" + } + ] + } + ], + "votes": [ + { + "proposal_id": "58", + "voter": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", + "option": "Abstain" + } + ], + "proposals": [ + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "YkFEBYEiJOemASPgePTuWgWbCtPMFXrPawtBnmZGIahHdwBsSYJVfTrdzMeFNNoAhdQYhVjPxMaDQHiQuSZepgrGkwzyxDpcOJuNijZwZjrWZrrdPJheCFBcsGyoBwpHNGGoVbGFPrRP", + "description": "sNufnasYkHdSVMBSOtsMzQinBPerRwqHdsXYXenFLsAWUdzvwTKfzpyLzYuMMOmHhsJZCQtfgZkjEdgIUFJgIjpHZtvlSRECioEGodiWfoNDhYgKliFetusZMxERcYUPLgolTVCiVWhsBtrJnkBBqorrRotaSJoSVdwkYDdNvxcFXhCCapYzBvBrAGhEmKsCDNcwRZHyodxQFmwCkJJahNROJIgLBQAlrqTcSuEexXGVAUemVxlyyPzBLMJormlaEXxJrseyRThoRyXIUWlTgnXQzUcvmkZfQVOTdeoXpGNPtnJZqPmSLaTMPilAvOgyrSwpXdNRHLSIiMDHnYwqCIhMurIzMhSYyoOFXvtrlVfZlGuqgyRWmnmmbQRJXepnuUUTIexmaYIRcSnGwQznVXbVEbKmrnUrPsWVLbeVDMsPiRqGHpwirsTamPvdbFTFmgTAKKAmxKqwdjqcutpTiqvQkCaMhqVxAruUwRxctUQJUnbMieaUTlqjWGTSsobBaQiMhyMTbZUSwZatUOeIvTTgNpxKEEChAQYjCcbNxcZvbcLjJsukkMUKYfLwpoDkMRtZqsRawXkoEmkRtdlIwYCundwunTZNPVpGUIJJBVPHfTEGelFgdjYVYRAuMUvdSyYGlBwtwgqngHQhWwUSbZmjMiJNnlYYnOqnPSQkgUqSMxbFbiGLmhoNvzHvhqnFFmUuCYFagjGugzbKseTcukqPoHkdOXiNMJXMpQKeiOotzYiWVTbmgDXJjOxubIloUbuwbkeqAYzXrhNewBpeokaMPskfsWIylswjQlHcgTqJSCFXKgJAIwDXRTQYmKevjpaIkMwrQmOKViZUcSeAkjDLDxnQaMOuInExEPynOvQxXdFMeDOsVqDUOqawILrVPqrAKWvEqcPHnqzGnnWGOLCzGYVaqtFjLxHHCBParSWYLRCynDYYakjSGdUwOuzERUNsrEMdcLNgzQuxkdDybuoTTxMvtTebokSelJwHDAESkkiOAHrkYEdLxpMcuehFEZpgRFIqyIOLlGOZoinTyyntboAPYkFWHFweTgPVcEXqknnByEkZhiOaIYshnZfOyHWTfNbXwLIVZwuHzwdghYlbvwtojKmzMNdBhAWWkNEAaYMNYOcYjaVLrtXQpzasahLKDoCrxjUbaKqWbQmhIibXXJwNaaeVNhFgZiQJlhtCpJldmCYNxASQvMXkonuMnXAruUikjtqsiBmLnCTSgtuOWKKxCPkFzlfFkwTfcaUusDrZBQVOpVHAfFyRsuyheFjKwCfvQnvsLDJEBnvPOjlgJbgkilAfhRWpTOtsswBxCwlPQROHjVzvGQspFoNwxXDqYMfbXhQFAttvmgkBIPjIxlGvlvuEvTTBnapoJkndsHWCxfEoPKTBhWdQbIMmKXeLCIoyIoGTYAJsVfqWljflerpzwkZQdmbOONJvzArNAvBTJIwAsyyGONWmQdYCRMQThEOTAyTdHpNJOmKlaGFGrrUyOCRSbnhjkDSsRvDhlrLmFFjasxjhJldOVBohpjrKcvMXYdHeoUbjgIflqpDzmGYXkAGlbWnvPAOFmSOhzytRDesxLkCBLAqCiEtENURvEvuZRWUfsLwVjgOoPvHUnbUMChxjQKvhPNOBYyIKjUiFliPbhbIDZwPqdbofviGwiSXxZXdFYodvNTUsPABXCNTTIFGRFeksHMuURnXpZMfGDsRjhSSUsgiOyGwmahBoUnVvjrOuYiSLWKPwEzmnCCzFwNSxwdyMGFEKpqhdEmZjpWaxPGpSnZxmzhCxJtlbphqhBgLdCwljdqYBhdLRuCNQBVRCacKfDqYlICwbzdcfLYMBdwWHHdJtPPpnVJEyZJMRmSlpiqhNnUHTMdYpPHrNAMcFDYvWmWqcDBwSQWWEhzhhnioAtLeqeAtPRoSItUIcXejVVmEYMpWAFwHvWUYmVHxdWnKjCIxKTMoUrFLzlGmwpFJFyAARqFiyZuHySgyoPZTonpgVCOXbRUSylLjmCRTsPKsTdAOiUNpxjHFnPEElfrecwSMgHGKhlDrOcFUddGgZIOhkarRezLqVvrWjVFpKeRKyeaYKoEUqgsftxbVZHEIwBEkfkXccMHtfkPqaZgngsPtZbZCAkGcJgdSFbZzryuEJEIsRcEUMgEcfsfamsaVhPEVamtUnRLKYuRGbELaqiQItWLGuvlyClVIECXMxSGLySMOjgrFVDehATPXcuUnanirQCKuiJiYVoGwFEJbJFFvNKHTPmWJCubvNpYUyWODwXQXOuFsyBkWKkpUEitwjBUGMdllUKCtWvScsKuKcrPTpCYcQQIgLDvIjSfXXiHFlgIhBIPsJrSpgbrdGWCDjTxJPAFczHuyqexHoaObPPtzjtjtNtVdiiQloxheZNfbqzbyLTjhirJYYgekbXPcLOWcGnjVajHdGZQOewbUASHbSmoRQGvpDgvQUchaErwdcHRznZBAFQlMlIQUSPlSLFhBMFKfnMJZqSnzOnwtcuSidSnLfhGkZgKmHNiempoNsfPvQifvsegjIbKtEzqnHluglmoKtxRhRvpfHDbDMsVfvDqddjuXFehRJAYsjpyiRoyTwCjTZafPohJsKRwfEblmNuZssqQmPgLCEOsRWOHnoRdfpDzoLRelpqVGctdzKbHGpLcPADBXDNWaSUlLasNmXTSUQJmAvQiaQWkmapvyxDQLITNKiSLgYcxYSHyyciQYLgbhnitaOamndjsoHpcUQfKXtwactIgHoMQDRwUXTnhCFpugOnFAuMMOlcaXyjijloLoycIJYMSWQCEXyWzcqOoxIsySxcpYGaBHOWHVbgkZPfxlgZjRxAtmQEvgdmLtolSnWVmcMuLTlyDDBvCyiWSBKKoYkAOKKakXbTBftJuROktyDiEBoYwaCziGFfyGRBYlZnNSuzIeyylqJAYTQbOtQFqySPPyOOSeOaukCEqBenUjPNgNmwKlRsidHaGAkXsxllwArXxhbRLlKAlPIRJhNhnbEgvcahygegUAjQPPjrdRDipXMOVNaNpDFRYSObCGvPzXGHYmktKYScOlfBPfqOgQWsJogiuITTopufeujZuFvByNoanpTBNcgEOLYbyFatcYwLwiNNSptuOBgtnbTuYBajEWpxridWilCWuiERdaxbtRggooCArGVjfjocgDHJCvtEMzRkcTJNwCsgqaUvnLskFsXeGLuUTcDfZBciVsvLenCBLjPBLMttbGSPmbiCmgfacFsZWzKRVtWOMFvNjWkpyrSTpFVzAduLLPApLEGGcyrBYMxoumAtbxOMdDhueaCuwaygckbzjMMSjdrZUjwYthAxDXnGFjNeiATjwuCHwszzEjsCdmkTNtTmdwrCOqMPEAdmzTRoLXOvKflQvgvLwhjwTSZydAWbyANLedCQkzIpeszyaFlLwECaHKHRCNcmMNCLteyJURoCahLxilxcmqBJPLMjLkTlSQxdYkvxSbzyWPGzysufObAFreEAbzQshHXDNcNaKhVQSvqaWBwpsDATweRDaXOeGlgKwalgBqKueDvwNYCmarjUnlDXmaClkfwmbBkzNRaZXBxlrABnbZgBSkOVbKxwXqgluHirdKlyruenBuUpSMVCpWPbGNbNoIwOoFAJbWpktspIUVzOPkWxLkSCqtLytGGWrDuXewJhDRpuZqtDHbOfdmZNiLDCZetdAdwooegQxrXNKwMnvLgwCAvRUfUbEiOqgNASYdTONUhyldLCyMvGfocKuMkFmXVzZMrlGDzuHqVyhRlUDQByhSmLXMkAkYUPSCmHWzLPFgzAXSZbDWGAXrywdPMTPacCZMtYGYVWMpRhAhtXXdKxkIjzqZsDgWyxYhithPdOtxZxlTyeJdnovavrrPIdnlybiiHnpGIWpOffhgLMiuhBdctDUsxTNBxitYCkIMajKLaVpkCrTGezqIjoUBdvtHBethJngmHcgWYGlSRUcduLTFjoFrnNCKMjiqBHYjiddeXaGPBOVnuFXfefJiSGvTPCmpAdChXGfQkFLNugvYTvEYtPKyKVjOmcySGCMZemzRKzjSxCnXILIpCaGlMYJlwxGUHEMJXVIHuFHXGlRjuwEeZJArYRXlIYJLsZUNHPfHqwaMRKBTolUEIQewAWdFJexnjkVgVovzDvIiZHlcuCUTiFpveVRhFIAaHtpgbinvrHYCcXHxANRoMsmosmCxiTvmodEAjaIDhUaQEBvNRvTyPHqsRvUJnZQTMbqhgjEMNOqgOIMFMSmSHEdcRoxXSoiHbBqHkqCCOlkmpJAsoHVMWIYyeRCqhAkvHqvZTLqyqFwYQuqbEhnJdRBOecRBhrrFqFekfbMdvnoEYfbprwEehDPEUfReKJfhtxVfYUYxVwiEZDyTVkkYDDOrMOKSQxiaDUhjsflNJWqyNwxpVLXGbhnUShiGSiuCNPKtWQhTgeXsKCmlunEzJtoxmabdFycsGiBXHiadppalNIvKYgQAMZcmCjLxRugqxCkitPXVPYpyWBLdaquOXenBXJleAGIIWNWfbWXGZPgwpmetHBXRAYATdwHoRiEeKXdJzFpCgTEXpAWsMtnTFeLMsaPDphwRcDkBBZDbtBihZpkclTdAapoxzCkQUPzgLrztpsZNEKxeWrZUYmCPHkGfCAWEjpvkEYSXAXJAAoFTOcjNurgzZmHFImwHAlcvxtxaMdJsWTKpdKHIEnakaVeuvocmJDnkLBTOATEbztGPgEBUWXyjHQlPuRBPBsTjiSZBbmBoyTWrFQxyrehVAfIXYhwtTVxEeYCZNRBaGzNOrHpEarCHWIQwdJMpMKHOAGTLqNpPfEWQFseWKrWfgDqpkGBqkSqyqsHgqblHMUyHqPZfkecAQjzvuCWbYqkCIdzuCxNoeOGnBRrGbFLzZJXFEViTrMdeaEZqjRKwmSHNEQWZzwTwRjpzlpnPKsmbxRVCVFbvnZXxPjGKiYNPBfvkuedovlgQQmHxOvIkxKasMSPBM", + "changes": [ + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"11\"" + } + ] + } + }, + "ProposalBase": { + "id": "14", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24914473521" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "379" + } + ], + "voting_start_time": "9935-12-31T14:21:40Z", + "voting_end_time": "9936-01-03T17:40:38Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "bWJHwQHLNnEvNLfLsccikFqiNdLdPngIRNWSNbkPXJkniBPnjCsFrTKMhqqwghDtPqILYkLPVeCGctBLsfnXfrOYGgjnnTkuesgGvrFEDHaAHoXHHwRHzCNGtVtZnckDLaqHZfayjbyz", + "description": "dxqSCpFwFdKuQIwabArPeVFfiCtaMhSUOhErUNiOcHWeHtmLFvaNKIUReoIMHSHiVzxniOvEggVdxOitTWDuEfPVqSWcNLVCQlXYOmWxANhPNBtsfoIfkrqItYsmwCcjDovjXPetnWkrJlwbEUQJuMAVylAzURzQPlAJXkUxfzLJtLRdSKwpmzwsWyHCQSffHHBUpIbGkzTJvOdzfYycGgmfHSbsVuSIghzDySUlVRiTMBfxEFPgmBxwMsajgqeoFyGFpTkUGUSUNAYqBIpmysiiWUFJclYwCNDMhZXXCicSgcfECrzVcGGuaHZfVVzIXGybpEKoFQXTNoxbktLMxNvRNzICjZVIxtCLmoSzPprWdXZclkJcvMPJtMqwkFGnjVlFbSVpNPhzuZdAfXATsCFZKGtDeYNXHKfngdTiUVcGHpoTLgHiiaXOoqubTRbKhelUOOKQxnVgwXuxKvEqhSogvApHbOQhTWFJaSmphVhnEjOWtDCzgIzraUlosZyqXyLuQKVBIHEfnFrQacRxLZKrglVjCdHjQpRENgmnRXCAChqutERhKmxvwSysWzwToKrYIUUnsGpOkNWTQdJhDHFrcOllWeVPgtdDZNcJIWgcxKiRksGVskQmkcmrEouGPWiDPFkHcvSbIFtDfzKsWpacOhuqpNoDHpOQSYRJamuuvshvrdbMAdciyvyauFHLxajzYhCuCJhkQVSnynJUYLbqohKIvAbmodEFWgTxbTNvpBQmFnMcmHRpooMOZKQAqblAzMYtQnUdQXBPJBrvUnsKmdxzzEqwISykFtTrQgnZxxSExwTjuVDUYzGvMEDDPTPVjyupaJmblxoGVyDfJQITVvLXrzTbHEkuGdlFzxgpAhyqKyJVpTnlmBOqsCclYyyEOQWqcEMbFaymxDwXFAmECPiOqfPddcOgUZvAqVqPEMtUEpFkqfbXNQKPSnNeoawixOEPhTazfsegmpSkQvBhuWKSJrpmrCQNUZdoHstArsTRYWoYylNuSqhsNiykMARmzVdhNGeJkaCAmIPhonhREaOiOGumCwanYlIXjmyjkyLAEqyzcivhLMhAtbiIQFDJAMiXkKrTlzcfOjydwqiqGiDzDCUgbYxBHdbkhmrXvzQpgjpjDIzozDlOMecpghkYCdgQqUMktEwIkgDWvEdLqZeCViInHKkUibUIqaOUNXIqGoIkQAkHpMfVBhfJoPXJEiSSQgxmJoxISpEWRnXTXwvkzHiIBBNJBClKpLdqKqtIlkvokmtUoINMhobeXlrDvmsFjIkJMkFSKLZbRLCxXadhRGYjAPTqHQNtOVQegCpHvEWbxfceOmxuZOkknmtaBmwSjXQaWhJkWuKkidsCjYWHehEcjkOJyaYExZcAErrROBUjYXnSiilPHAirJFhOBbjoAsNvitRtlDPLtwZfrwblsSXgtjLavmxTnOKNfWQKUcuhXiSaWJnNpxnsPHUHFbbfjidDBSegzBnBmcFkRxAFnmOynEmIADbGLjcGEQUWOitGXvnyHcHyxBDfDfRpZNCcbKxjMQiHaobUuBjxRhgiOAPbLHuhJIdHURDYlRUXTcUVMIbOBXPUNiBBvEjSPXlggkOitFVRsWQnEwcTqhxNCjnhrlDPcaedCFwsyYKozEzVkRvwXejOldittCuepOZLLZQUKmdZwLERpFHSAdIpnJcgwWXjcLEfdOcKgTuLWdZDRCWcDnGkIBJgDaxqBffCwDUPxKvOyjISmPdPbnJGsAVnLOGowFHyqxAhRDqDtDLPhbOjqKnUMSDhLnilaLXvxgAJIfXncdFaYxuTkZqpZkdIeoxhwSZMkGEeItLVLCLrWjWVEUvzQNRtPEPdjtPMWQdzDMVDApOSWhBGgduPatuWIAtNAxlEaEMaaihHFOrnQnKqJhihvjHLTDRLZFfHlLBxfFDVdLEkkGVSiInZrdQewoAeXQLzNbCXCeCIucVwPCoCfZfJxCpdxnJkHyWrFMKDUUcobbZBWztTAhBWhUlYDqAzTOBEeKkOAfwJQOKtWEOBUrrIoCHmismmZyWqAVcwTltGfNDrhupGvALTNEDSuqFLofJEmjnufQzdpbazyvvJMWNQHRrNubmusdgMluEfCoQQmgKfRLaiQPLqjMlsDcmkKJWhkjHIrsygURdXbOFUYxtPGorjFnszyEKcCZjFdqFXuIJgPZmtUFWvMKgBXOiAXHZlxbHvPqRkCXKPAeysBJpzjbLHsMKMvVGfGAXeFODAjMcyHTiBhHbMEUBxPVZJhQRzyZbsuFfLEiYcwcyeedlhUcTiWedIoZirbPLBsrdqGCwjTrNxfriZXBXFjxAOkrTsfJIIWwcWegPsagnBSNwUgHlIIVVlWHiwHJTOKmEpFSbwKcnffCVPhtrztNJSlsoKmxHXbRbAyQbNouWcdWGQvzbHrXRqIIGvKzGYPQDhEIPKpdRMUMiVnJFnZzSpkjRMyhGtoBmHOjBZYciGrjcHFisHsdoeehTOzaletWYJBVfxZDEQqJqezVehfFmzJrQoPCVjoBsOENSgFIYRuxudDbFijBkBmMrtHSyokCfZBALlnXnZYklHCgqltrfQuBHGadnOAGCUCTkAxQxXPGapjxHZnRDdsoHXifEQtRRtyXSWSVKFPMzfBrphAopxBVOMJKkUNmdxUiNuTUQdxbUpNJaDCNPdSsHUtFwFkMAGGaliSdsAlIcIPvFYVyDFFMAjiMRZZMCIDAwkNbzIwmgtbGkvLrcWNZkvyWHyklJEgafGCLVblrPDBcwZuwDqOJzDXeAZzPCgcNFmQHjgNuCggwUBImCisuDZlGHEaDDCMFUQxZfZbYjvsJWpLVYlzqTKtfRySwkzVCmLcqrUuytsrlFjKCEauwLMEpaAPJFlciEXWZnBkBHxBUUcdonsrsdMtTlGJbXloJWfMAXtdBSBqFkrNOxDaZVqTRExLVZusiEKaUCTKTOLmwEjtyspIHgOMrgPxPKnLepZiWPVxrjUOOHiPuDygEIWtVIJNrdTARHTSGBmRseYgoMOlhxRsqvpBsKIaSrTdgBOhzQHkPcjyTAaRZYkgcRlNadajmBEcDMAiaFhSMEyrBxblkOuNUsIxvyqlTOESwrHPzsBmqryQfTzSnTRPreYXduyGsiGKgmYTcRcIGCFhjObqRPaQGbEqLbFkIAiRdDXMMPICGopEMoryHINWFOkldaDUsMkPEVBaJImHFMhxgFyiRLHqybDfiWdwIYsdFjTIuHRhpaASVIdmFDLmPwseoWjBuRkNaEMKmpfwLbLMiOAfyxqEWBwsYpSjgykerItDAyHpDCIOksIdeIFKtcTIRIrjXrvGpBMgWYzGSsUdAPxohhthNKIqidewxjenorHutNPNGSUMINMPCrPvSvXnlnCXVpxDevTjvfRYKHlxvzXQfLGYHyRQryaJAcJOLXLSpNjFEcdCcxDQnmAqQsEyliutHwqwmZNEsNibcMycejQJPafHLszTvCmuKRsrYVrrTTlHSRPAegiWvnavuEpFDbAweNquMPEEvOdWoFKlzkzLrngPeLPKdILtKjISgCSXWXaPhuNBHvFQOSdoNFtVlLLiEvMuQoeESLoXGsoYHpSUmIbfHcGepGRiXFhuEPMnronalIjRhfpHmxIDdyUlwHWUKNrkooBCuRrQfDOQphnphgrjZCsXvgOsgcLVZzVZOSiksnbpWmSKlWltvlBNxrjYsJRQADjqvrdrfThqOsKSCprNtuRycqHsaHqcbIKMfkpiOyDqYpWJxJpAXlxRZOcVOOpjBHIicboLmnsZKIDGbAYZKcYgLCykvvvYuuBqTsZRefTQNtqNqClylADaSzLpkiXMpXBxJEzDyaNPwyfrlCkeIzeLmlOcmjWQSfbXDpzRUCrNTuXcgyhmvDlSlghxzJzNLNWaIEKYmRKFSMuifEqEsjLerwifqoQavxjJSXyfvVzYzBVQtLGYDEnMsrHWsbMJptOVOizOoEfxmXRbkrekhIgxxlkSYJdgFcfMJROlvVhbCNzNJIfrgyvceiWpffMQzYiqQJyboDbIiAbleeYXlfNJnwPIBHGuQZvviVNOnLoXdTsIAdRGeSuIpeMSPBnOzJUbgDYbCotZSLdeoIRAXimPASepFKnlKmnqMfRIdWFGcGWdsIcBQYHTtmVHzYNHQZLJCopozIJGxWgJPWsxSAnXejDwHetzRJdawrXvRUeQRCzRXVcyVKcrrTmzfQxiVGwRNOcOxgWQXtvzrBLxRQkqWifsXCpadrVFZKjWAaoDejLCsahzdFZulZBGrZkefRupAplBWxOfiEVihKECOUyUYZpVxRnzFRahVCXprHSVNnsyGsZRdlzegwpKLPJyTrCXDuMkpQJZbqmJykGKAWmFCzMziNEsTNcLumujUpexqywWFguHSCmdFfuidNfoUHUupvIlqTKSehYMCQVqsLZXGpJaidgqZkUvgTwXiuyGVgldgHBmxJhdGoknRJWsJwVKTwomZwQLprSDJzAAjbfGfeRMBuRCfhBLNaslRrAZiQqZoQuSLPSpQVMiXpJtJNnccCLWwALUzQUlVFEqyZkuKjzrEqXTlbUYIwIaFNnIHZtEojiYigmJeSotHzjaiTueIakOmAEKeQgohPXVXXNcdguIdZjUiOOTIqrpUBQFHDqofRYLVZRLyFRlCTQyaWTfCwhAKNQCDrWZfchhFUibKEkTfoZTIlAXqylIXEhvICsDTOUMznjwUqoJxINpUVoHjfNMCtVkhXSkfedhvtBiAtPBjjmsjPxNeIskwnXqqsbnoFmwzRjAQKeBrtGfrXuNWMjBqzjYxpCDdRFOjZdBKMEleJBPAETRBskwrycyCFmlEYwuVZBlwUCUDhsgImEFObdooPfncaNcEzBHaXPwguaxbbeFxHySSOxsaZUYohBcQTAHdxywhaufHjTemrqwmsCmmuwBYzOUEVlliRWyErTNQFzthNuOHAjzDJbUIyJfAUbESDq", + "changes": [ + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"469\"" + }, + { + "subspace": "distribution", + "key": "communitytax", + "value": "\"0.270000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.000000000000000000\"" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"8\"" + }, + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.150000000000000000\"" + }, + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"65875000000000\"}" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"140338000000000\"" + }, + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.140000000000000000\"" + }, + { + "subspace": "slashing", + "key": "SlashFractionDowntime", + "value": "\"0.006896551724137931\"" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"140\"" + }, + { + "subspace": "mint", + "key": "GoalBonded", + "value": "\"0.670000000000000000\"" + }, + { + "subspace": "gov", + "key": "tallyparams", + "value": "{\"threshold\":\"0.528000000000000000\",\"veto\":\"0.268000000000000000\"}" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"8\"" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.180000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + } + ] + } + }, + "ProposalBase": { + "id": "15", + "status": "Rejected", + "final_tally_result": { + "yes": "24914473521", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "279" + } + ], + "voting_start_time": "9935-12-31T14:21:40Z", + "voting_end_time": "9936-01-03T17:40:38Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "GnyeCBHlVGTTJOygZEldArmWduzARmgGqgmaJHWUzBaswudWraMspToviTFqlUrDpkUoWvlvzftyZMZbOvIySZUUxxsFnvvnsUYtfJuhgqbuhiyHcyMWrIIwBDJaVagQhCWATBYgmAwn", + "description": "BapgczncJLcGwJHgFYEBebKdPrzNeYFVJcLOrdGGBVrRWXjcppVlHYHKwZWGoDRCKWOFFvsaYbvpdpiDvhOQVCKXYiKCNdcAeVfjBZFuJytPQPvyyCKgWEpDUHCdcLBjyKxYGjGWDpoYkIvpOJTNYIlaUKvPclZkCOfUTURCtdMUqaTrvAYZrRGhYzBLBIZWQrviedFegGlTMtTkCpCPVGTYCFChuLoqkYpIIrYQYGRSsXnyBmEglGleKbeLHKDsOmYcmMKIPSTEBZFmtHJAIkMnvSCfgHWazoOnWlkRcLXJXORKDcQbMrqHRFcaBZkVhUNYLtKdfnQZRwzDCcvuAcaAyjFKIfhubhUhFcSJaUTiUhHpjnyBSOTsEiMuElAwHxfEEyMBiLjIPImZOVdzpjNksbcYqQqInfYoBKNfRvKphzkPpjxHeRgcSVttnDKgmmsEkLVfXIcIPpnAPhroRUCrEBQaQdErLkffxcpEqQJjpgthBNltQyiMifhILAztKZmNYyOFURFFYQYuGgiaGykPgXxLzzqNvsOqQsWzlNFufuhjqLMkcELTHnvmwZAGFWTBBspkJmbcIiGWfwCSOGqnJWsYzFjSifzwSOBzisTMdVrALbRjuWHKpMWQQWFcSYXUuwtxtWgmKWQkPerPnKzrjkzNZBbrSWrlNHfbApERmBRQNRVtllPQZEsMWkpcASugiHnpaoKtstAWkTahFFYFetJrdzdnrqTPEpjYdoYbdBcDwvZelwETOtNZpEVFwhdoqIOhJJttXUvmqbAPTiRnbDvohKADvFqEJgugUFafEyABnGnDUecGCyqxqYogsxZavrxQarmIirckHNQcYLKJTazjgciyUJCbSfqIePoNqTYfQYVgpMKzJtIfrzqUDwvHfvkBGRMYlCWZidhtkkaBAyPerGClafdpcSBHHTmUnHGOTHqYjreNYNoKYHVvrFIJoOiBsHVzWJwskMrkBJcuedDpoSPQdxKIfKyduKmPHbaokBNgtcHfJeTrpmhLlndYeDttTQiawTYPUOHSUCsheFGVvjtQJSZbGouiegADLsWtxcCHUpkMSfJfnaeheSWyLsuhnUKpircsOkscKYPRXhlQLkcUFOmnTyOUpxXuAmSRWiRpsCcWhkaCTTALUEEdnnMMneWoKXzGibjJEVLPRYIboERkZbipYhWDAPlCGHnklRxeXVgKLsofrHOlSeVJbZKrMDsuiOiepkPlreMNMZYZiPkvarYKLShJlWXcYQLlJlKKyJyBvCVJYCvWlJSCtsoUbJKBHHNbxDOThtUryjroRhIcwSeEoNsmrrgmoaOsNQCSwQxvFNwPwBTZUMODcIFMXtIGrebvWPKitjagReLfbViJlkvjQuuPpQwHdESFYEXEwgXdPAXNmrmsOdWJRODBObLfKdhPMkftweUVoPTDLbKiqIgATaDnBEEWpPdgQcneRWtlHnkEOWdBAukqYfKFOiYYmwgSPBJjlxYmfPCNNLHcIAfNPIlQlBeqFUtbdwoWmluNoMvfSIEEiJxxjupAbggRxeeywAfOiqYOgvpeqNGvuZQjGoijUUusmvJZiQpvquxsfCXhvGioxzHrFLObyBYOSQmEnIDqMOtTYxCcJuoOhEUVadgclXTtdpoPPvyCLTUGlLRmZjtQhsjPnvKRqWItLOoGcLQQPhuHKKclovBDwtpDIMJjdOvQObgAprUQZAvBhdEXLkGCJXlTtyDixWTHlQkdSfBfeIpDvhubvwIRRlJYTLCuFKwrBNQQsjEpXOCALTbCWBNTCkspryNRstHwgPnppNMWoNuWWWveFODYRkAqTOVMcHIQfxsQCDkUJsCEIcUOFkEKtiupIBZDMoIebqHVlzZfBIVmWRdDjuXSDLAbIaoLOepehwBAOjLLaphNJzAnDZjmsmVoHffBFjtPGxESpausHsmkRjUsCZwLRaCSTzdopQHfMQhGVbBfKjuAbGcoUOnkxCZqTvazzqtNdAHTKqrlcNbelsNQIjsGDgrTnuozOpZOQudwYBSYxURwiEbRuHykZIZHllGpfkqEecMRnHwEgoyHYOVaUBqXuJjbRbnzdCoapmyIBTncQTkgjVUVBIPLlYIjvtjhPGEsuwMQNxOlVIpUGMfObgnsjsoYwzPadkKXkmicMuQHycpRsFvTUnxGtNHzXEKniWfOzlvPoiizgIxYcgSfPpXWshbXXwZTgxVRKMokDwsOtbFVoIbKCVxaViAffugXURyxIExUPUOMtgRMCTlCdcvxzDZYwbmHKcfqJzFqtoyEeEFgjSbVkXXTVGKWmYuHZmaSHtuaZdrAGfSJHlSeEkgxKRndNtdKKRQuDTyfeXPgiMGZKnLCoRfkflJVRDQjTcVFhypbGALSrbAXOUJIQnjGmlUhchIYYIJVRQnHvcHgtpaiidAVzxlXnwuvPPDLrWBsYkPbkRdWdkAUchyNCPZMCZJKmlcZvHFdgsqTIVSNqXgUmPbwsYXeciANfoHpvUFjisXcTCVbQWbksqNYpgABWZVTdXzwjixLzADkpSjcKkTXtVEfJvmtVLHZTquTJDlDGWlFmBkqwQdFNojpGyUirvQdftDKnlbZKKThOSYEpJUfAonuGKoqGPBTeupWYkmNTJjnDnIKrQONFzeASWvlRMnhVhZXKWITRDTUofBQwFxZxGfMvpNeJoQNJpcRdhhgfywgxpHiJwljKMfQYNBpmOppGfZbzaQDQBQKndNKdwjMGufABFKNmCUbDvCtcKUhbIkiRonlxDQhQDMlPqlycgsSlehMYxvHdrHlnpcJBLALBIMcQVWLVvXzuFFPAgRCHHCNdiiEgBUzdDCSzUWmBCXLmJGTWgFGlkpYiLjaVrXntjsVBMjEKaREKUXXfxKqaGjotzholsTsJfJQmjXzVSTiSYXeIDVOqvvmrChZCdwVbXIlfkdYNRizUyWFJMBjRjEZHayyFoPkbiedkualskGUymMpruiLmGyimgPnhfbreovLMxlUObLFJJuTJBpCKSKcxKbCAoICCgAxvIKYnMixBZiIYUSgpOVRhuEngjcbRHPaVetrJhrndNzmpJrwUFCjOWoqObZQhZRUnehNHglKQWLWrZeOBvZjsZkGfoekxbFAPTjwKoeFTHjMTqrGMwvtvkDaomnpIUwePYbAnpkDYfzPCYISnsGNDxzmhDAkBkSomjnpoMBYIMeDIQNQFnLJnoKGoNmaYAtakOMOhdkdQFNDUzMUVezHzhtzwIJIWwppJHMpIBZUlQZgXCODjbTgksMIoixgtGPevzzOdVauAGDgywXLlsUlrGJvkMfxXmbkIEWjNMhOcUxvpikTaIZrdOsIlzocSMANEiShwPjaFujZGsiDuZWtLpHPHbfVAtfSDANndqgdJLkMLzAOIyvTGUDuZRtzSgakbMGwFfSTeCSEhfBzgIKdNxAXbXwRYcAaYOLngiOGprsFiEGrnpifmKNwPXRcuDzGigILwOCCkaoKBVYyEGVWefIRsRxkuLdpesmLRflPbqYnblxhbPhEPUwjLfmaJvytVSpTOTLiUCyAmFaknecbozuwXuQldoEXglRwDMUprIUkzbktrqkwbQBbjKlBMYAdFofCVmRJPgpJBNSeEotiifnWRFdIGVRZgVWDLBtnVNbhFQDbLLELlTBxWfTwktocidCGyallXzUXmzHrWHIbfqhQesKdGIAypIaXmAavcFNZpkIZQURixGEUuvcMgAbVvbpyFVroIjjdjTdFEyqjVfZWdmHwcxpTeiRzsXwBNwCrPwMdDtzEGZXxJeUkfhQCMAYZWNHlYwggvMfNoinVxYpvPLFTjLXmyDwnBxJFgCaPbCNtqSszSHQiLwjtrtbqzmNKRpWOvyVFVbeeCVlskeTrdhsrrKDRPUMIaWQZjyjATLxOcIRwTWqNBJTpddrekPXihWBJxPWJTBGtBeRMJLUFcVzNspDVaPZpvmXfpcWTDUbquCsNJVndomnJfPuqSGyQeErzJRkvAHElNyFMehBKVsSxNBjLYHZFrVuGXEPURpXToqgEgQuZuDJdhxbBQfJjrfYAaNHoIionbnJLzyAUXZQRNfWkZXSRTmugcUSMnIIeAYekNrkuRtZIjxmSqDfDAzoseEBjwemVjkSOJBEyKfMpVxNHumWbvHkqzqPTwEksQoNAxGEeHvlmPoozXAOeROjYkIANrpRkdtuhunJSkCykvTwABwCopMPESbOHcxQOLesYnXWioEHRLzlHJgZOwAiPJTHOUnDkUJHfTicReoFiOOuGwyyLCxoqkNgAtMrsanqsNEUDbKeGjtQXKkXHxdVeEzZOFQoDcYMDcwkljRxmIluwpvzXBEaabYtGvADjwAPFWNicosZEtZjiEBPohHyBXNHGKPXTGaGBuPgRHdZDDELkunznfXZHUpuhoKEajIGSDhWhntJxSdoCVcnzYUwuwhPFkKDeKavNfFaOROHiJotRKOmYvtupiBSUlAhmMWaERLBOZSyOqPZoQRzavEsHcJKjPHzwiwpkaIkWYtqIPWMbzpLlYYQvZfjuLSpnwNOdbqPyTLzZvBuelwZRwNycDTUTRLMRVShsfYTWdjFpQYtWLlOoWikyxrMzjPMbsMJBOrnUJUcxylGTRVkIypivQXAKlPNfdHNtEZwwaquZJledQIuJPkFUEGXDOHBDaQlXAdEijNvZKexOioatXFmnmhRWwczBdQsBLVTndgxWNPihnHYDpwJFvlNRqClICCwnRKVbKotXEsnNRGDbkdbXSGxKQFLTnldPJqfMzLAdtrDNKGeSEesvEXvKmatyOzaiFnOoQwmVZWFfJCCRUBvxPcKsxwcuzuUakGKiOzVKMZtbSCtJcdhqTtVmhnCNcSxdLBrocXGwPbKSZTeEgzuQhFvmKWSTAajXDvCTUnyMjhpIDlXiOxJKdqIhlnqQQJkLmOvqChHUIrfmFSoLzfOeehgiAiWwBcKEuPKWcULWnSqBRYhAXqZVhUJx" + } + }, + "ProposalBase": { + "id": "16", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "232" + } + ], + "voting_start_time": "9935-12-31T14:21:40Z", + "voting_end_time": "9936-01-03T17:40:38Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "wLrSnpntRR", + "description": "MhceRGXcPEMkpWdqmfznNlzyIWGlBCqORsFdlwOcBeWyEfRIpeRKlypBbiLdsuRUqIFAtgAcdeWkOrzkggPujLaIEjqokLJAjPbn", + "recipient": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", + "amount": [ + { + "denom": "stake", + "amount": "126215517818" + } + ] + } + }, + "ProposalBase": { + "id": "17", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "24914473521", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "240" + } + ], + "voting_start_time": "9935-12-31T14:21:40Z", + "voting_end_time": "9936-01-03T17:40:38Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "AEgQMtqCqU", + "description": "sDiuIDTlFvDiMzvTvrcQVyssKNDZXzBqThtQJZJMFaUzNKkqkALkcDBsuXXQtbRNWgOyojgfkiRCUTXarAMMNpilSurPDyLrfAPK", + "recipient": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", + "amount": [ + { + "denom": "stake", + "amount": "83790607203" + } + ] + } + }, + "ProposalBase": { + "id": "18", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "222" + } + ], + "voting_start_time": "9935-12-31T14:21:40Z", + "voting_end_time": "9936-01-03T17:40:38Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "VZMIpFAucKozazhmWhhCpEcgImqejNAhjmcsSrYBClfHDCPJVXKpMLPzVFgSuygbrPNjliNiBxJeRjUkEovHaTsBPGVkSVhCunQpDIWZeLqoxWGtlpSRNPIzABmhoqUuEgjXIdjRKPaY", + "description": "kiDBLECXiyfqlXJZPGsXGJKCFstZEOuDYCWyAazvbkhWqCGUVpJgiBGeSetMxPRoHmDEwYYEsZNTXywLZUyULWJCFBihGMMkJrNQouXfHUXLhOVVLQZwxlPXYJZnfilBBGBBIEgvFXZQwwiKFjfzVMNLspvwwDsqneXvoAFKXXIhkAOoiUbPnPawOriRhxYbkzzyIvYmmbZpgInfhWfSsfoNOULcTrXkjuweLKQrmaICdmrdmrhYJGAEmPLtWvzCzsXfVThZGdauqXNAVFNRiGpWkvMspHKvJucHEVCGZirqMIylMHtRKnrxAYOmVbDIFiZBBUqoZIGHqczIotLoCcpFVozoVytHzUowmCXqUKUYkBNJKZdyGxAXKLKBjIDvgfZteVWTqcqeavUljINMudaFrorRAAplOUMbpnIkMeuXgGqjZgFBNxTHTBOVJUjrBXqqQIOhAGkcgUuboUFdiyOsVjBmVziWraLlabMsYHqgPEWvRCSgEVsIScmaZHWCTnfxWxShgTGailgXfnOWhescBpRuCpiAfMKaySlJZxvrjPGSYFVjIApHjndalfQUnWWQruCwJydHdyCvyOMdeKIWtfkYprEUqXlDcZDrhRWVHrjULQxmtoiafOjflhTLjnyBLQMngvjJKSztLpsRDnIdcEHkTEDWstaPgqsNNWFVkxjSOeHVfhyHOTLZpCyXVjswzxRyzvaitQVnbkFyxwgRKOHqUDsRSVldHnaRQKTtnRXhsiNIVMcubeQiDmzEQxzjqmAQvnFYdENFkemAVEdeaTewvqCOIedNyZdtgbDpbIkBOnkQFJYjUNdXLUPWABEcqDMPRbUkmUCekwDNdRfLwhjplnzavrYvVldiXFoTBUktUUPVpujJVRuLDrUgjgKbGKirMsskscdticsQoCCpBoPAIoOhJRpBydTxVQeXCSlWlvOpkFsVXFKPTQVBewqUEhKXvreNSmOQhlNGFvbUZSuPtJdNUzHNtXGZAQYUyBhvknvyiVWwOmQXaKzldmfBWMIYFatRxWzhRxebDRRaUcrCJVmCzdphUPDdpssmfOwpIhrovnLIDEcYQRyyhncPtzxdzLyMDvyAzXlYYNcgNvClZPoqXNsbKFWvhRBpPyTcOtkcKSMPVYKfRBWJXPnKOcNPgctvBoKiWHgIJgipJBbeEvThUeUGLPcLoTsOIBPgDWUZEDoPPuiiAlxSmsEDPipjMTbeoDWLEmiyyIFRHQXGVWarGVohmWotXncyJzjipwuXJEkHziaMBRepehuAOucQHERzdCNsyWqAbjtlyyZpSpnBGDxGhGKvVfSgJZMySrSgwZwWUvsLyjekUckmGjBpKefQOHcuJIfypSJJfumGrnBepWDigqCQiHbpdcNzmIFJQOgFBFydlZoEoUzgVPwHwTJFOHvunatOVwxViPPDtayxTJsRJAhqLUfiFWKguWFyxZSuQgcuSrdMtxFBiegoudLIdYcIvKTvDjBzarvOCYaHxqwTcfmzQBnufLyeWgSzBWZLQiOIMUEUcnkNWrPVocOmtIaWQchCRWGWjPMKpHJTyLSppSiDWaCgaXLxgyvShiLcegDQEMdZKjVycOGANEgHknCueIekmmuOkFCucKsaOUnYWPTSBFUkCwRFobkTAvgwJGQFVplGMJezOosuUIMETvsbkpNldPlQkovmerxDYGmjiDRpzWitHJarafYEiDlwByABQsWcvZNjfHComMAcAdieFxftwitBJCFxbAnHqzuNfmvsuzJDmDvGBzjHAFOcAydwAzEzImxftWUnQWsATsQYhEpYkGtQleLByixjSGWWlPGPgWeIKyDTDSatoGxVBVHoILanXrKuLkmbOdXjaHobyOHqqjhZWOVxlHGGIecxpeIprzYNixewBafZdAoXrSyGttFXfqEbOrhyTpLOQzOEMvjrmASbEOwQtUUXPFwQLXmWqMVccWlmEoowNYuVANmomGQzUYSSaLUBiFUVjXvgppTmJcusphwmUueMHKSBHUAEhnovPGbEoyAQnZAuIZuOdsxBUUKpuFOwsRmJBIdtzvTvHniCOQmXiQUlsESZZqfquBxHewBCQaLWWhCVaVmoBVzuXVqbyUcjBowIhuYHHpkpJiYpafpNPfpXXRLcilumhOZTdHXNiptQquwlWvKFJsvoRfDzxwAXuvtnTQWUXZohokjvUGivlxXOTgNSjRMgAAtQNmhTOvLUqxZBbCGSBicaDhtBLPCqnlLLxUpJwnPZEQUBbAgHnsxOxCXugDGvYYtqHiXDFMoTqtCycZLqeWJUgUXBdWbVqrUCUheVKgVfwkOjbNSxDZguXBAZditFNphHVPETqZSnWeJZjIVDDcBtGGeFkTAtGHfqWLPAbhrxZAiNFSZYQiwspnuehzrBEiOIjOEcPcUeJBYxPamtpvQoZseYSdFhnQRzKqlFLkPeGxrNraIQUEXUTBrxDpTvmCgONhBqDMAeavaySobXKPhAjUNGSEADbzpVGSFbMRcbVGwGcixalsScCcGMTSrGivIlQUqclLZEWQQgSEtfrLBNIhtGJPFQeRYMRhjmEEMOHujwWwzmGyPWemnumyiTXXGsArXOMhOMNboXgXYHnvhsmspTuZojwciLXUtUNKBzWoiAAZYFDBphViiiJslwWUZCZTFEsXVNXYENLegpuoLXFeEVJldDukCyAjPQWlboSPPJlvuNIeuUFpFCQIKxJthxvIVYgiYOrhxOtkFHCScGOVrXFrZirEnbzmVMTIbmMiFyJazhQWlOIHbsKLQfhAtvfcfysjMWPQicwBTJqhkwNPAEDHmthPVKYpEdeMjIKpCIBSMXQsbJxMMvwselSNigiFunaPLWOtNJFjjubgmvZiTlByGlGvUtWLLkIijRzWSGKxSnnZOfuCiWXtWMiEgYtCYICntakCJPCXvAdqtuHdLJeIGBbDymwEiolKAOMkIKMTTQEIdJkvKMnizOfdiyoBjiaYKNXlanivtkvaOAaAgxRDCskOgPRAVTiTZkxtzBZjVcRwletGllGlnjpYPZxiLHUTvdkdOZdaudCZYjSIgpjZutYSKEMCUQNyUCnjrjavKkLwauVzBrumlTcAJXaGbLsvgsabPMUzaKYfbqTwSxFaEpHylZQNzSOigdMqmHcvIwHFywVOoCwHWFMiWjMwtyJeeSBPWdpAghsxvvlyGaVguNfsLmFPKAVMuCpIdPOpllstUNwxjMWDkakWSudljxEeOTBQsjPUEndhWnkpkXcNxhnzSvUlkgVWqrEwZgcFUawlGgJkeuyawKQWWdjJOEBxdwrEzWJKxrDkiSJTnrFKWATReUwWNJYRaLqqyMIeFGYwOiCuWwdNTYvUutfsAhgSPGVphZlFUnXlxNyOOlAHIhIkUnUuHkpOooTViSFHfXrWHTRuoFCBUlbexwNJuShLYNkjCwvxCEKFyjoplhrtkZChbGIXpvHsqOGEmquKvDCzSioNpOkYFeCjZIUrcuhmPzPsdBAaXzsruspjDQQDdQGrBgYHpaOzGVyGUuKibgpVSzpFIBXYzNXobrgfqYOmRzmWVVOYCQmUvAQiGAJFQnUnnbTLifMjpMjiUJdQSzmroJSCnfcnZXPsEyMZaINAVpKWpinziQhjHnDZUhtIeOmwAJnDPbzDtpzagkfyRpNyXRTaDAGNSkZHrlmANNGYeHyVHcGMHcRIXdBfDzevOLdZVPONOBzMtpVfZipFVcoQxRMaFFDUAmiUxXuDBfGdKPYBHBetvUfumeVTRnjNseyCZssDsbbilzSyNNXLTXVdKkvQqSPrUhizRmChgEmhDRNYjnGvGBZGkCIRlNqYLjWmRQTBbtARkMZtMUKAbYsiMxGiUINbwIyWPagouREbedEqZsORirMzcJyaCLnGpalDnVZBJZmEKmCWhKZhSVutsimKLMaMIDWdVIHNsYzpMGsWAAdUztZRgRhdcnwXzNjtLrCtHyFGAwwnHEpmWNAVyNrfcEvuGIIVeMIPFDtZXLghXXpLXImQowvhreVJBqdCLqmeuDYtSIcxwzPccIAhhEmGJJrxvIrtJGacPHQebkPAAGwozDmNNVwSJncjenPQjGuPvKHRxhcLtItTMjlbYHCzoZTwVAIllMfCkXlzNWjUdgdSWxVacpIFjeYMbTIhYEKLyRIwEiJmXSQtdoWURyYQLvGewvrhsUXWnfScabbUpqnyoHBTzfLhBWnlMFsggVAkNdgHPywpiEJDmlAZlkzNKhYJhNZjjBWpnnvTBXssxXKDCnOgxjJXpmJpkMrUgJJNdcIkSpqqKYLRaHwrjYNpYztquytHFNaRGMTluBdJWuFGTXUghJMtxmelEaRwnSrYFdLjSjaCJgrGuVBmrhJjMFUtApTSPJYOQUKzaMYvbVRxhTqkOloaVLdBdpjBMYsTzGvSbsUsQUdiUYjYafZvlZnUFqToeJuWzabzgmHhttJDtlJCxDqFMQoSavUaQQXadwNSGvoRmXjhDNXFemmXqpupaCBNnjDHkGsSBCAVhBNGpXEWtVZlIQasbpNzCEFBCMiKTgrwtrGBOxWcKFrhQqvGUBJmQmcGvLwVJlNsYdfcGRFxgaSqZEKDbBmMetNduVvaILgZyRaJKyxMoXQMDHLjZdwlTyhuedmKdFNoeadiwAUKYZAymrmIgCMSHcbJkrdWJfarwJnTnOSJUlLYMDjwbZTyQWCXpSBvfllKgJikeeOZBdanlcNxAHhEgsvTkJxbPIvToLOmlPtEmlaxvnPGnNujwNLulYzsVzzCTehokFcMSEqrbpvPVzShlvsUhTteiZQxHbsjqXdnkZEbdzzrbyzEowlVSYuZLFJkNrSRIQXSLPteudlHMdXJYvxjoHkykKozVmGqEfcXsntcipuovjMxUSjApBLKeJoKwteNLvSoPtviMotJIwkhXGXnMhPQmbWaJKRBKPVwIyKabLeAnKbVoZfZKSlNblKNwjTLUGoxZdXUQZkxqL" + } + }, + "ProposalBase": { + "id": "19", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24914473521" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "223" + } + ], + "voting_start_time": "9935-12-31T14:21:40Z", + "voting_end_time": "9936-01-03T17:40:38Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "UVqZEdeaVzZMEMEnpyVkitoboYREaHmQbsMLduwSKCGTVbbjGSPxdqGaRtMfKYfZApqdlNODloHpMStFBCNQLirOHZkkFFIpXCuYhZVbcFINUuSNjRFvfntkQIKkqSsiKneRicwRTFmJ", + "description": "UzmjfKXzvhGxdDqtBZCcqcDBMClOkjbGCCpBugiQmBLEBaOcPfJhYKCsmeZVpBDozGdYuImjhWLcENLQxsLxGfwtdLjExzWBHQhjkPJIlWTAIsKNnHwHQIAIcxkdzRQgJSwUcnaiDCOFwpdHgApHRunQbIHIzxsVjsADRnDqXFLUuSJdPLgbacFmjiTmBcknAoikMDBLtyhNFQXcXUgQHDCARCZBmgvvufzFGXTfBTyUECHZZSHNUwIMTFKDUWuPSOYqDGTqJPuwEhEcFSLPXbnWfePhkkuWLPBoaFtJiwaXkKupLDdEbsdncrFMXDfmcLJBjXmntIzmZxAUDznNVfEAEWQKZsUXgYLInRUZbCdBldQoxbFFfGlNmrmyYgAZQtrItflRsACmcuUAYQlsXnFPIXeYxfIzdWDOTfcXSVwvpxjLOfHoSeqAnyMujVQnTeDxGyBGODXrzYkMxevTaAhxFfWDEdqjKlCBjlUiPNgDFJIAVKBwOFCHrBLuLDIGVZpURlcFIyeIsfsXYUMgNUxejZzvznWlWDVMJmDumvYXgXVuAXGMhbltWIdqEUuMHaYkLTipPNiAykFGFBujucjHQjQuHrOMoRhODTmthVGbVKgVrRdyxXuJFdGTxWkSpwnxpFgUYBOuUKNcPGUineTmIuwKECklmQhPZSgfViTbeAMqWxxZkTLPNEwkaVbbIvdPLUEmrSRmJQERjwjvFxzbfHPfNjKzCIHUcOkJrEnUyjVeSpoRougIwQuGUzqbQYLefXCgcuyUqQxnKHJWPtYOsexxOqimFScWRuXEXXlCedQYgxwmmPEzzkdsktjsceXTLoHLfLLYaouRHFlPyesPjofLXHeCPFUwpDOGUsCHTgJfcOIAVScKFhMctNypsruocjUFGFwHuCSFqmcZOLYYMISFhZWiyNFjvBPTbXyBJljZQClNZJEDIVAuFvENlTYgEkRBQffYjhlqsuaudFgLtDuzlPdwYGtBhIAcHdWOaGSIwNsKQuAXxgvRUpHpfIAFHEplIVSAKLhwFyYdLasAizaEPzzoNQvCCriFpSEoGzNKdDZvIVvWyMgleAOICGBVbjNsfcMrMdrrLYFnDkzPricEJbEsZZwoTBYfuqPUtqONSCUUATAqwgjuTDGDkRGfFmAxNVcZFMPHlAztSsVGfrYESlUbOtAxjWlhcBnzehJTPcqaPSXeZxwyBIJlZbXSvUUUPvaPBdbtTDTMPYNrStlgnIyqBlDgifDzEdXTKdVxxhpxpTWAeWCGvddzzTfujzVcNsiwvZkQXZyFUFSQvMwRHRsBLKQlYnYanWLURqHzAJHspkopBoCMVLtQERHVdPQakKxlrSyLqMxaFqAqGWPEGCvvsDZpDclQfHKxXuRGyfkDxPqiolwsvTvJKsHLjWaIKQpwiaFptRCqdxOEZAqaEkCcGIhavdsgsIBYnVFWJNITYGHTrbLDsAfrPfFivDPcWqgBoqzzWNmOlaQqXPhlvuKreWqwJcrckPbcoJUhHPndxqRgdjUeXbCIetPLrOxRRdsCsvirmNqvXbSRNYkdoBZXlaOHjrLpjXdDJPEqRyMhphlNMPBNGVQnKYBSuamTBkuFCjUiosmItvCYSWvCjfKDbiJYEHnymcHGJwaTuJgRrNXEYJzzGThGfsDoqlFPbBgdprGyFennJdWYCecOXOPyYPZSbwgzIqCAhNUKupYTnqROblMfIqRxDBCERiexkwmqMueEwvnEDONlbEqxZJZGomUOCUMDIjTNWWVKHWuAMSdPNRBBnqJyiEVQxwDSfBuyfVmJxaUOwyjPrNrvIGOdRggiNcNdBEkYvapBupXItFPjupTpHHRPrmStJMvLslwwYwuNNEtIrBEPaZvvALpBDCNFEQfKBBjvsPjtlkNHnAYixyGEZDvmIctATINBwtnfthVvXWvYDRlegXgvmVNcClRHLqcMMkzdFQhTqOJYUhMtvmrrqqcCmwrZCjltbKbPmJwtxRqrihLODOnKYaQWhtglPltKqSoieNDgqCitvroHimiTcIXovyDkTWkwIKeDlQfZEYXqRBshYTYcHnjYazlOrZopzusBaiEtQDSjEstmExSuIXfocsDvRzHqHvJdavBJkfDkNuQIJwmkNlbouzJgtyqKDjevjjJFkkpIgZOVTcFpxyjmFSzESZZLBkWceGBuWlidULaVBOkxcMaXfIXrrNXJmAdNbetixNuGEDSyZlgmTVFAmECfyvULzNyjtHfDTwtRhryENlDhqvmcRORaVJWqFVclWwdofSWQBMvkaUyKiVNVhWcIxaJnMOkfCBQVPnUsHqBgJYXHjmQXskFhiNgoybKTefQdUMYWgEjmpSoArbBcKbRfCqZiEXHIKiteEGJvJrRguAvzAXEQPYJAYmiUPjUzZtJlqfbgmmbPbLvCFZraWpWTyrauamdPEqonSrmvbzgjOMDwxEETyKrdfScNbNgVRhiGyCUgpoiYpLkUzMAwDzjAZiYoEXOVmYbHWdZlQtbxdTvYFflmJosKOUsGutXaRAsZQlwBXeOiKsMKgOBpDBFpWkvXlGQRwsGMaYVUQBxGOfuASIIxXAQEoWHvExVueSUruVNsDzkkFVwpCszJDhQNlEhTJEwxXLDbJXShtlaOKByEEHKlyKtOMtOaUwyJNYsZYhdXPWLVimBcCNIbiMYAQrvpRHfpKIhqTYhngulkxyVJvhtURQiqXbJXYQspzuOEwMDnJMsevtdJmmTWDhERXONUanHvAWXlIIunnKEpUiCTHATwDaPejxRtLLIyTfncJgUdZcMTmRxiFaFDHZamKPaOICuGmUNCDhBaxJWpOyabHHtYjcsTrqBzzjDiDGELkGgwcylCMjNJqTiarfLqVSppJSsEkuRJKuwFpPgtKzGxplDdLoaGCRrXKnukhaKLjTBkdVEjKJxbAgmmncQtQTkVfdWxHYMSujxngaJpyvZXppBQzoBYXspnxdOfYQSAEXQiLBfBRFUOvASfOrWjtsrGngLwzTGPiHhXGKkTjKrazzEmClPFbSiBhhahlAgeYKrHfiZOEhOFXsHuuUwfLdqtbVzMNcBMUEnuZwguNTUQJjfkNmkMcpnfPZVzFiJCeWvpGLPkovMiphPXhMWwSzzqGxFYYCXvFIcYmaTKYrZugskktZJZOWKEXIiQjvmYkxNXFvrLEgtvJGypdcwVBzPaaeLxLpKdAGLNptThveGHMTmgxcAWNAtsabEGpwihjTHzScxHGdSmhbaYHtMOmhpWNxdVlNCqWWQiRwQVKSyQTpQCPqTnnPCDPjXQvNypFTNgouxdeCkJaQemveccAhOqtHeGvqkbrSsTfoQUfmwuqEYEdGuWuGozKvvFiLeOxYxXQrpCYsduqtTnUWEcvSqxIqUzPQqxowGkhNYYEQCkTczKEgNwhHlWRYAGmzJdzpzovLVXAhsqsGlAOKtCNhWyFcePUFXxOTAdoJtPqGNYOQOCZwiydAUKwWNEOndZwqSTpiiIPwfnemFrWfJNzkfZyPCCAspgpoeBsSlwKhiITYhEHrchXYqaTgzCtboXxCjXUNMFiEIxYfJppZIQYuqeAtfZhctFGfzZprDnukqduGxaxJHmzbGlhSvxuaxcDHRYNKhxQjbfAsYhOCNdaKhKECstdARKvPBqyCoXtjdIRvANahJbebqquEbxawSoWxIEfIudZuQzrBDnQGdHSVrcnuORRAyvkUIKhCNxlYyoPCGiWHlsPlpcQGBfXUdtUThbFMtEDDGbGGIQhkeObqFIsbZKmrYDKyVqeKDOMZBpGEOezJmyDNLNvyrEekMxNugpJrufeokRPuRtkhLsnhtXfQcehOJGjdPQeQrwNrcyUsRrNRvNMEtgJbxeIDhYHfralOaWmTPzrZUiOxxQWSFmrpmpGhZIHcWZuLtHwShOAekRYlpxYyxqsKzqlqXnuavTxDYDvDbRHYKPQEhwdLKGetwdnNMmckpkPPxDWoeBfHgeeZroZvZmaGkEUTuNSCrMxOCiFofjUTXzPpRIJBQmNqTjGmgvhHHWyfFWCBwEDjvAjZmgohtGfrheiUiJCyKeeJGLNeXhzfhJTOtrfABocgPYxWJDVJWtvLwdIvGENglLMlIxaBTUSLvzuNARsUVnBvYcoBbjDNKQCBHsZmaphDAibYjxSmDskqXCPYTHhHNUDjgQYnnOQJBrKkETDaBOvolVsLejyvYNcANRbKUxiRSdlePcuhPcSLtatCROTGJdnSTDfMtAPKwFOZDhRBNdpRKUjgoWqFscIdReJpZPPiMmfeXVHAIooMmBPtWIKttcqnJTcKJPuJTZlTXKcqepazecXQWarzRzcdJAZErFYBbAdRhBaHauRpjGqVbrpGbFQFzdDyyQdgeQCltUrwfJaXUxWDKoiSLCqGwuSFeGSaJUdLNwnYhhfUJGYYQSEBTINMIjTXcDELKTWBOPglkAEzJiicSbsprASUKqMUpHYDcEJuNZkHHDrrJNxfDPKKJHbMbuxKazEJZGGEHHmusHGEddBEDQLpoUjYfDuRrvWjbLJOXVpGObXAzolOLyuYLRbDIjVVIfUpemgkejkUmrqrPlGdKBlxflmkGutzUARFFjXpSMwiDrDiuPddFGNWcsgVWfwAmwZmisXhDzlcFsrPEPmCKsJTqoayZyjwfXZmAwEJHBXBuADikNjAVTxEwyMkVZtOXRnWAFKGRIgtzjaulFpnOonBXoGSjwzthPPppjmgXoOzhGwElpbUPJLhgDbblSrUkAgEPRrHlAnRvRstyVjiufElDnQKrDVohkcwIkMVAlVKpQgJxwewcDgeqROBoBEHDQCpUDXazJNNOzGnxiuDEeIUAipCnEfpvldpiWCsRLZQuXQqJKZEguTQSVvPsbsrmSGNBpaZXMKNoRHruykvxnspZMWLwHeXdmscyfjoEUxCbdXKfoubNHehQjdPYZdsCKWhxscaQZWXZtRGeDpDCvRfXmyxabyFam", + "changes": [ + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"11\"" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"165419000000000\"" + }, + { + "subspace": "gov", + "key": "tallyparams", + "value": "{\"quorum\":\"0.449000000000000000\"}" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"6\"" + }, + { + "subspace": "slashing", + "key": "SlashFractionDowntime", + "value": "\"0.011363636363636364\"" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"148400000000000\"}" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"187\"" + }, + { + "subspace": "distribution", + "key": "communitytax", + "value": "\"0.210000000000000000\"" + }, + { + "subspace": "mint", + "key": "GoalBonded", + "value": "\"0.670000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.800000000000000000\"" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.250000000000000000\"" + }, + { + "subspace": "gov", + "key": "depositparams", + "value": "{\"max_deposit_period\": \"277630000000000\"}" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.800000000000000000\"" + }, + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.160000000000000000\"" + } + ] + } + }, + "ProposalBase": { + "id": "20", + "status": "Rejected", + "final_tally_result": { + "yes": "24914473521", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "299" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "XabNyZfMSllVYCVxILlGRMfNKLHVGjUaoBkAkpXQxEVOcSUTwMHrOuseyvPnpmcGfAeQgxTjnatiSivfFyGKxsikkkKFxYyJrlfOJcPyKmduaCNrkRbIXTIksaPwdCgDzxUoydRuqsRU", + "description": "DGoIjnYbygAtiZIjzTLZrscqeQNJkmujNRleHpHQROuyeOafJnozibJrezrTMubVpyacobphDRlThnAcpCuKOvgmKlmTSbzOeScMLSKRvkZdWborIIOZpkosOcbusabSQsJEhofwSzZnsrSfXwijAQBDqELBVJWmkhyNKAsjfhAuerWzjpxjZLevNApUYOZjRnfymTLAvHnUjAwrMOeQjcTqkXsWhBlKdfaCzjrxBoNtdgXnUoKFqElqSgXBvsqPwrAFIExsrMfNPGsmzJkiuqQBaBroJvAuEsCCWfgPeAsLxrBmgMqEwEXBVfvhlpiZNGifbHLbsfVQfTePbRiNTWfrhcJKXSXrJJXwZayzHgXnDIgpFFqwOJWwIHyfsfudUyizYHBFZRFXwLCLOkhjEkQaNgcUeRRWLkezlhEbZaXrrzkRRpSYhxBHKzYiNgZzJckrYlAbONlaboNLbZJJiVJtiAyxxXSxlAKvqoLAxAiuaJpQRMCAKmujvyrFkFpUlyQZnrxiWfvoCBvEUVEmVRbeTBrzLcHJLeejcHfwmEbwiQqnVkgAPKALBIUqlvinfJiSnSmtLjIDNDSaciyhbhNoseiwJBBIiZwaNmvBsVECFmIVwuVCbjnYrlsrlrqXeFiAHnPEqIdhIWzFRoxwPsyIMDHqzgUQFLSqQXuvIxVBljaDqKnZDWwZDrThoJjmvLSUvSkzuMifHvPSkGmqpqgOuVHPQIsBAJaISZObdIvqQCBWYxemQdpweAPSKiKgwQfNhBlBNqZDlBjNEhXGjFMGUQcBMRnYYjRqeNVcxBTCViBZKXdgvzHknKwTztwgzamKDQFJgJfOwkWEnbZAvoLObxRfFGrpQXRFZneZpFZqZJNhqKyAuVbYpVMQELtxhoVqBWQFBkGrAzQXgpBtsamlbRTzCRbmaoWHpDLQdXYzJHrUtcwGbNctktxIxUjRGVxZreGSuIYqmebSqTZHJlUgRJzAqDRnVfxSfiewTfhGtwZEjRsQBmtAoNXpuDeSxjKryrqxwiLkzvQcMnmwCgUBoiGmRjXxaVIIGGwxNEFTLEbxexFtOmoJhNsFLPKQfLvAkACuhTXItpOeYyCqKbhVvlDQNIQIKfumJdCXjrmPZESzGgNMLCMLUBaqTaZfpBVfqSgYhHQTafAWOULkEzUtXCunHcaIhoaoyyVnjmvhbrbahDrNpkQGnCDQmQntFwJFywAcRXcCygBIGBxJQeFiakiQKegqjAAujLgmuWDCUFbFWqrZuutaeEtqyTAbOrbwyphsLqFwRrxCxPyYCCqphZuPTtBomHcEnvomPkSMmzkJIchrJkelCBzVxAHWCdyxmvTIljotyhVdVjVhBWiqkoUwOsPqkhqHMSmgRWdYxwYlCSyeEWBcJNJYaPHziOYUZRyrQDNSIwSwaLgTUfXeSZMPqfYrAHwTAVVORIrVSpdSvlDWxmWzMIpvLWCKVPkYZPsNRurzGGnrfiJxDaxwFXtaDUArSEUyVKfbvSdFKGczQODUUtOqUIfJFuiTICBsyJHwAsavAyXwSIMWeSBLrXujlFWXMMJFrhyTtFnLZiqCNUdpnrzNXVtBKEaPjqUOcgeWSWKRBZhEmjtbUqSwWLyXlPOPJzyChkydTziEbjtxQXYoUGaHoccqwPoEfhochHIKioZbxxfFIZxkNbeQyESojXQSqigMaxKwjEzSNNMjLriLbcNLuwrFWlQJnWHFWoVkFcmMppIcHjqZHCUuRzBAPTWqJnYHGkUvTXfwCnxQdWOXjjmrMzrlXBflfPRnzfjBelWebihuPkqbzWHGypPaGBoqEBHWKdfqoaNOpFNTneJZXyiDMINkLshXdlJgDzYmnOmjysuhoSjpURXtbRTwwdyYmEwlJqLaUeDcrZFgzbeBqnFYkIXSdxULapbWLFfwhzluHULzmsLWIhRsuRHJpwnIqblStqmnSYuvzCMUccEcqzSFTBNyCBYeBhNrlmOekRCnzhswhWmBCZLozyTOMfLRZBHkfmWvycdgIpRiHbGpcwUPwmeFAGVJcCmTOJVGeJcqFivQRIaKaHSiiaceEBnpuisEqjxYTHXuvBnUXLhoPTLEWCzEQdhjSrsBvidBwXYcTNRxiCJaCzXGGCecxOniRMeVUWTyfDugwuBsZXQwWCZqExoFIHiREuAvjLCOcMDCZzkvppHAmHgSgfFPtKseLjdIJxFtlxXnKoKkSqcuQqYxsGVTaFvWpoFlmwuQpzPPyzlBqtliFzhSJMljMnWHQOoGdAKPntVvibdOvMLrcNtVQVhtYnnzdxqJCvVMidpzZcMvCfHdHqgAjWTFBqfMewyPVXVgzmAAlsMldzNeMcFBjenSnSzyddqbnRPvWJHVPiZzNFgMoPgddlMMahJnWEfjJnUCaWDxjhJuXRJOHtMivyCEuHCscSIrXYcKtfSLiaAjaBTNapIvznPLVrzKddXHfFgVoYZQKdkKrNtiMdOZWJqezHdnUJvYMbvQWNdoWCevCQQHYcnkXFYePiaLbAwIaXDSCCABUyrlAvlCtfCHDXSDbLFMiwppdjWFnfdQjjGjvOUgQZwoFWOuipsRyDPEavOqHbnXYoszBtRoFKAJeCJuYytHytIonFRpNQcQvhKpXaLMkDQuyopgqHShZiGfIcGluGpbEOLvVHUzTzBbFPJwXXEYoKoViwQWNRiQRNDrPYUitnvmlphRmvskQBEdhzlaraEflAHEpgbTKtWdSyLAydmgVMaeEUWuzxYELQMEvGTzAtKfzsYbTcdXMdKhayeAScukqsnygfZKgXYrrlWNBwPDQHYaSzofhxwSzOOfYQLMtGecMNGTLuqmnyhdIyZBPDCUPymKSSrYSyUPLjFllRMMXLFJQKsvwAznlTWuTOtgqnWckzqVRSTKvTlZztHRghNoXOVKodBXrCBqAOBGkPQSsuDQVXwDgyhSrNqdHxDagSEneGIIZqpIPkdAZQJsipkbMWJOlHtVQMoYfuXSmEVvxUopqxZjLCpEDwbGcJpdHiRCvyhueWKbxqXcbVlLMkGdjijRquzuQGMHByUNisRXyzFwRHWhBeIcuNQdoWgobXkYkTKriuYSncNiAQqzewIziTZTGMvsNmMUHwhAFTqFLUmqKJzuzTXSZJofOOsDRfEdYbhJseWEIBdjHLwGPYCEjKwYqYynNOhryxYgkQnBzLxcCRRmHKcMDnDRxHBuUeZoLVzJCfmMTymtiIYnPWQxbneeDLXmZTbrqKbVcUGYpFEDRyOjeCSnEIWTFQMeuWwlOiUCbWdBEBQeQKbPjRFSNFUMcbOcutvzLIBnkhVSFqYwFGTOwBqOAOOSIitGlwROnsoxyflsHsWkHFAiCmoKYQsXbpcZdFhYjdzkOYoeCIaHTqaVRfjwlErlEBBvSaiWTrwQXTqzuRlSNEcEqrMNHcYSLfgEZecRZrNBkivLaCcyfUGsQkNCrXiWGOWjAPnTdGJZIUPaFgngNZgCQwfeEacWlarrBtYbxhwpTWxfFpiSAEUgOBsPnHmBwRWwkVgxIViXcnmDuAEwtMFLeTQcFaKyhZXdYdTBVGpoMpQUFxjAfHAzrRKaWppxJGppijuXPxmwlRZNVOPNZkbBLXpYzPNVJhmNLXwSbJZAswZmhZTeIwGwEbMbZHJWOAFcCUgcZtkuZVbArVSSQUcMVLJmGHNYGZcnVFouYUevAUaZtLSjhZAScsrjBgRyNxZKomoAiGGBiVgHoDwERsrRnRuUygdVOsOnUEcXZrEvtHoSywgitVyJGbuzKUgwXnSneYbAEskgKcFEYIWflXQJEovdWklVDHKdChSLUcVOvcmYRWNHsVlvJJWXVwWCrkLXLlMeQSeZRTpUyUXCuClaZydfklzilJACNPnDQOTxybYlPDznqHkJTThXIMpFDvNjiAZBqDBLscsTyXXaWWdgiZdqoKHFeOaTJecTymnAYVudclixdzfqfLbDJNOnTEuaDfZzhVSVpISxMJpFkaISJQJXYTrChIuorxoRpqhMWMSsXxtdcXpDWOhksdRoeONnXoODDhXndxwDrXfjQMewPoaJdCbCYnrAjSNTmvZeiXPvNysKjbhYdAacZgihGRozulXfUhqdoBcrVqwfQGnXtTgmMscbliwXhLMYhvVYiSdHHvNQcxJQqOecWqEVHRJBTiNZmeGxVszAcVvJNJwwTcsfznUcxIcaCyMZSYXWRKrjxhTWlBeMjWbTYPuEzBNcUOVDEWKGGIMIgWswTGsICgaTXZmcNreXwUIkgqpCAlpvptMAOKXPLarwaEeiGFHJzHCQpLLKuJLfIFJaTRzmMyPWuqDKrurmqArXifnbXplZgcgxcTuTqohkjcqjWFDwphoILXZuqUGbPhjaMUrxqNRhtlhYmqFVPpFzesihctXqhpNVlSFuZtjypNFQsDKoFBLeQBxuJlxqerQMzHYImVXdpjYehArnAAmmUzYbRKSAmjFjWOHOsotWRFwWVvJHHHAOOFSlAyYLFNfFZfWHCdqxrOAYmGHUxigrTvhvGysfckfSaahbbtkwXnkfJWDimFLYleYLtaJuErbCbnyKlIOAetfNhxSJIIDenmQbzffhoPiZWDHgeiWqqnsnFHDIqNOoTkyKCyxTouioaUqXmMTAXPrJkuNsOxMXWImVEoRsASPdunXVdQsLTAwuldSdoDAJvqvwgVGYBSxqQhLpAsjHPcXwvjwzPbJISJFXKXWHMRqHFUgDStPKhInljZQaEvjWOwrZxhxrhgFWohOKFYhTCRIswjLqbwUkKjgscAHQFmHQDvjAWLIvLAZzMbRbDOPPazxumdirdqYrEWvZTvRmRGGRxrXbFLoPhHlGQNPeNrOMzReyNqOKeRioWScOxkiFPwQTXAwhUqxbbQojJVcicsDzAjVghdvxpDeISKuRmbObNOOHpkFkwEKbUfywFyRYSVJmPsIaLvKhzWZhBOvBzDDLTVFihXvvGIVsrVJLbRGKsdXE" + } + }, + "ProposalBase": { + "id": "21", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "274" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "VgemKLXqyUGykWDXTQUfQnKNNQvMAXIQGzJbTLhfuFoaCYznfiVdovuzSPkTbQBsjDHlUBuazcelrnBZkYuINsmsHRpMeMChQveuGGXDmqWOzpGONfXNPHIvzWmPznPAYVHGizxuELlN", + "description": "yBofHJibWSMqRspXpNvfcSpIcrsrrsLFZjfdoCqqxttLozzVoEfGHhtykzXYesHgofxaDHtMLJfAIMSpGCTiPtudFBpFaOTMSxliuvUEFjdDraiuIsmYEhhcgFkZVMSnLgzJvvuGaVaSLxFjRDFHrfHqgSKkFwEbkfSZIwZaouScCVNLZQaomxaajwmaaikwlJGWUrLkRzEAxyZHHwDqqndudBEclsnGyxduNnZjWpHFMCjjvPpUDiihIDAGNeARtjKAjjEckFXDRcSGNPacalukPinsifnybBrggjVRqCkOSlSVPSUwgwwXNXjMctUwUVyTmrrrPKeLvQvzfQpTuPkWhIPWaNvXmwQYrYjCDVFNctXBxukmUpmPWIWHFnXtkbYIezzvspshtUHtdlauvKTySEGGTOLmPxelJzHgMozGiDiBLmcqxsvvDsdkAtmllqCKCVnuwNoFiZzSOAFVztckCVtqbwDnPbycXVGlPnqWOIfzPqZQEODeOsxScfwWTiijWdCATIZeazGKyMhmCVfEAbKdvoJElBdSyeDUAbmmGAUJKmIlxCiOGmClQkcPXFTCMPSwxJdxZnCsBKaLIuAcUudUEGzSPasoLxJGKMEqrIVVpvHqkoYSsXMdqnMYXxxlntJxfNqyVqYNtpgONmkRvSjEYymQFDKlLryBrgUNWFWsrmmDfbsuNAKqGPcKTcqrbeJDdjuymgvqxCleSdRvYYpkhteIPEqIYqlQKZvsfuYVTAuLMjLkohERMPlekIeXtHBdGLEqOspwTtNZIyrGwAITxyBtEISMAlZdqbLjULAQPdEBxNHTHHPzuJdmOJPOSKSEDEMDbrxxHSOiJIHADgnmrqImJKrTcXwvaqXoXemHLAQdQFcuAuJyZTFabQUpndEsOLfmbllaMYxGhmlIvoPmkNJZnuaEkVesCRhPxrCLpteiiphwygGofZmvdXNYEwyefoHnHTfFnvrCOLaPIDaGueAqdFGrCzZOyrEQESvIxlHtqQQILJKwoXNZjswNeNsMPrgLnFYwReGXNniPSUTxccxBZEINmQqLRFciMatmxCtoaqySlqvjjVILwqEVjkwaYIDnldBUXphPUKqIZlUeKfnBYURJDOngPHkDkQXMmveiRKNxXZUmtnxwqnNvgOYiqfbTAAkTJfMCnllKWAjvoGwTVvpxlXWVyZqzFspGQqfRjYAuVPoDTumHIvXNBBmwDkDtLJObgimVfUmonoMmWzBpmobOhixYcfVgNbTzUYTyBVqNZKLXcQAymzhcaXIrEbLVGvjXBfzTXlYZFIiXMVCQwMANQocEyFhBbpLHXnWDEQyoYBQUMFidzFCsCGPvnArIDMdNhcnuLoyvQsbRphPjybOhGVnFXvYVBrCZEyZbBoNMqBChclqDbqjqIZnhxofoZPFHGlVGZGWmXIIEwjKilYvGWWzjNPiyqElPkhqJwHwNMAfidCQsQGiHdENCUVrYNLfNGIAeteDlmGwPmaofSGjrdrhlauUtCyAXPDJBvdwmeWVSdyyHixJwxphpyIpITKpOGhaWxqShJuYSDbdUudwPWEPRAjVHoMgZMTRbGlgdvqwmGLRcyQBAvTQLUdbfBEPAvqqJNKvAJfyoMtwqPtwpcWvyVrQrYlTsIhiNwrbgMthPvLsYTgZOGqkZrwpBrFEsLvovmBoMQKyZtdFWuEahyfkRQcEQBhnHCgUZwuMrAQdEDaLfuvkNPredykXofZsHzYBNfXCdRazEkKbfizXqVyqqzKppQCdUtntqSUgoDtJUuaTkNlFjVQNiyJuxxzpyzbjUUrOLNbpBOycVTZHUInZvGIWdMAuzDVYnRnWJuWhOvLpzOnYSjyEpTbrAkgpFLeSXeBTrARNzJREIreYiWbEUJpJPNRrOCVgxTNckETTbwsQwmbCXOgQAczybzRnXuXBCRzLMlBpdLmXhGBnAvlLfpdSNTycfwpupulWsBAENHTDUwHfTXuqiQrMWxQGRYGUFApyagTqaPxQBrSENeqCemjYllHsYqjNLIvKubgVDBSfWVyradGSrpdmPGexIwAIPcDKKSdkGVHTNhYZIhGgKxKCqRoufiGUagNwORvrpBjDbAaYbNosNonPWdNGkVQFOweeaDlQSnBgLyUKBEmXboXhnnIOtGeuiyMGTgezRboFFgboudNnkdsGUCGJPyLwTXMrHAkZbhAwAHHRdpLGSLONJSWoqvPmNrkbSvRKPygARwOztpWriVIMPUnHpFkxStDYXeWYQJvSNtToyJBlwOUkvJSriooveGMDgJhiPzUpKEaAlOjteUDylKTLsElBZGQuqBLWqJLAjMfuVeDhUDLKjOxjOQOGMNTDzhadRZRUefTPnxWnEFLJGVDEtiexMqHCpqSASUoiWWXmLHwnYcBoOSZpBRZBkIIHtzWnfDuXiVPajipeefInrxKSaaPwFELIaQXlqOeeldHkdHeWXetIINNlLhMoSHAtAiKBrMsmouXjQDOcHQvxNyBKtsVjgWzKIehAssKzdhwmHwpHWNGxpfUCwYVuuTTDKhicxCipAOQmEOJOXfMJsBRLxlwIFAjmKbPMydyUVepUibpSKfIBGQiwMeUmWOzqTQgGpvGFKeYxPrCJRdULRhKPZHRzTopoMoSqxaljzHhxcMrTnHokzMUZmLNurQPPEIVMlcuQaBUIegqIXPofAKGlMIoMcfUUbGjcEWUUQixwmNvUQrfPXJcblyXFMhTmsHyltQPUUlKIOxOCJJpgqncFJWaFtlzcWVEWRKkcvMTORjuZxhdSafIZhNcWyJJJooIGQbmkeOAWkoqnUsEMrQTPrrMnACWBQxvZFTuSfPOMdGQvieJksYdtNetKitxpZKnWKmnXaaLrnzDbrpPJVWCEahMyqwIwvMtjrEaozKPhvoYPtaMBLqiiCUWhCIDvSeYTfZXMBytDFyeyCnioWKYKQYuORccfmqTGiEeNDiHkiiToNYbmtOqampZXoDzOHEbTyJlGldcdboLqvwhmWMceUdgWAjyzRQlcLQgDaYNLYDoRTnjWPEXxNuYcmjqRfAuUTHUuzPurdHFuzPLWfuLixKMHUDFzdHFiNCNTzbznYPuKMtEnvDoUeifZfEQShZkaXVmPxatBuPQVXonQuVopAIogsoHkkFVtTeqnKEelWSycOfaCKPhhLUelpdWXqHNJbBeCRfnQEAKxKmXqnLHobhYmHWtYvWwkpHCryfrBGxtBDJnTIEQCNfCXRhJswpcsCkBCvSgPGljQgVOhSGjPFxVBfmisnFUaGQQjTiUzIKSkRJYnTHtghvyHzXKTzqypqIDMSqwULcQepDIIUrFJyGwZxFOJUnfMPEkZgFSQCxKlfPsJKwlxxFxspKlSOGXtIpktDJiyIWoNGnKxAzxTWggCIzDmHBUlOziqmgJvHKtfuwvwuBFKMtXSGGLCUeDpSIOQvGizwELeCdDeXmgamabanVCitOHmlFFlFqDtRwCmKLhgbuOoDhCLVzbskGhOSlARiTZEsKoRIFRoGRvuzvvThBnhErCRJgVhTarFRGhGTembzvAijrTBFjLvAuyBwLEdKEXteoOTyThrBtQhMPtHqwUOARSgNkTojTNubTtEOFChHcuqEhXcpvepJJkJJezETLkFbPVauXNIwKbAiqcZoDyiDcZmdEURZPxPZwAQIQTmfzIbosEdtDDAsvtpprDzQmxJHnKNwXXJcrobSYijgNhIQagbRnlbIDVoIozgkhWhyfnQpmropJljREoeWJrEfvutoMKnuBXeeaOjKMgddvUjBLDKXfXObOucHxBcYyDVyHUTWqczcjXKPxtBbgAjOWEUaEDThzjvgoWuPOywlCUWlPWfejmndthWRPfyAEGpgHPPdeMoulwHZGTKVyJnGAcZmsTOihkcZzZWlknBToKmZNhFBJclfmLqnvxObXAKdxChCbBRTNyUPWHKPPKricILYvBtWfiOXvtBAKMqEtMgHgRBlKYDvqPVNaOtcejRQYpuOeViazItLchvkbNTwHRAJJrEBaVZRgtrAlQVMHJeeWXfBwbjBnfifGXagZMmABLGtTuufHuOwhtTOBjTZiQSESCIbCuiUbQRzcTKTMZptIguckDBvyTVHEAUnPDHqmSGajbRBmNCRxLeTjJEOmefedUnJKOdzCmsQXoGacwmUzWxxJGmwRCqojRawMFaGXqefCevJEKaHaFmDYpxpHcdCAZQElEomeofpxPqiCkotmDzDfComAsJdPRzxzVXAxPSZPKnVCPYHYwISufXTKHSmGRaOwEVCvliWLVrBDkyAFWglVEeYJqQRpqZGFoPfEiQKpYNInZAjVSlEhIVvYtNTDmaneCLMngGAKFXuiWrjiiQtrFgdNBckksekmcYrhFdkPNxVCAWfjOQTprwVeVlHDmGbffqTKxmKRTiaWEuBXNrSQjeHiGEmyDHoceEnHyQZAxFkdeyZArBmkeaCdVxtCGmpbBHfXAFDyoKHXdkUrjwrMhNdQKvdPfKfpqHspcjRXDZhGouwLIUITUcVZQMauSolOxYWtgMZUyyDhuzJdsvpCSMfZwQNZFKTJVLLmFNmBEjdPGZpWlVTzWuhFsqyjzOfKmzfgGCTKfhKvplGsShrRKGWhrhLAJuhwtBtlzijGEVbeeMfzwdNZxSJCrKiOKXUUjzOXKMKlBVqfsYwHFjehbwdQXuKGSqFTaCOXblanwVOFvFtwYhqkMPfZrOQpAhZsKQQAYpSYejzjtqNIxouHIFjBjSavYpYIbtbFNcuiWZZZRDMTUNQsRzMPWqJxdkMxDLvqrCFPEDzvLvUUgfGBfqQLKUPXRxvXWRhAodhMdwDebXjNjtYMdBHhgZoNqEBXmUvpFbdgQiUNhLKdgXYIPbEbGtvugbSSintTAInSrYNCYsbiulPVmurDFmXyyDBdcVsLjhmcGJbbKfSxutuwWqLRpwAkAOdBMyrMBBebibabTYKkIdUpQMmaSwyZoBV", + "changes": [ + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"9\"" + }, + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.390000000000000000\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"549\"" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.240000000000000000\"" + }, + { + "subspace": "gov", + "key": "tallyparams", + "value": "{\"quorum\":\"0.446000000000000000\"}" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"7\"" + }, + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"198445000000000\"}" + }, + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.280000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.500000000000000000\"" + }, + { + "subspace": "slashing", + "key": "SlashFractionDowntime", + "value": "\"0.019230769230769231\"" + }, + { + "subspace": "gov", + "key": "depositparams", + "value": "{\"max_deposit_period\": \"215818000000000\"}" + } + ] + } + }, + "ProposalBase": { + "id": "22", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "24914473521", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "430" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "krwJEAfSwt", + "description": "mmYIsRjXDxOfkhnapaKJpUmYaIziGDYyphzBcylXFrzVeWPmREXHoiSCESkdRxYjdlibfdAljHKbCGKtnMZGKgkqIcVltqOtVamo", + "recipient": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", + "amount": [ + { + "denom": "stake", + "amount": "73837738778" + } + ] + } + }, + "ProposalBase": { + "id": "23", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T14:21:40Z", + "deposit_end_time": "9936-01-01T02:39:58Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "221" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "xYOFuaGOIn", + "description": "lpBXdraAWYLGEnkiPaQhAkwwuCOHIDlkNInRMOdPxBspeXiiPKmQccGafphGIJiyycRuFVaPSAtZXpPwoGsHejrHgawguZPSvlLw", + "recipient": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", + "amount": [ + { + "denom": "stake", + "amount": "588279322451" + } + ] + } + }, + "ProposalBase": { + "id": "24", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "386" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "noreiUazat", + "description": "RMFkdUuwIioyJnTEWMUNomWHyyoFxNbMrVFtcABdgGfPQtJRAmrXKFEFWOCytGLaYRWQzoQENUnYoxHIPNayTnWqHvCpmqJewntg", + "recipient": "cosmos1jp8nnep04hdcxckh0hg4knp4fu4zmzkycwwexl", + "amount": [ + { + "denom": "stake", + "amount": "44229105385" + } + ] + } + }, + "ProposalBase": { + "id": "25", + "status": "Rejected", + "final_tally_result": { + "yes": "24914473521", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "278" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "fGyQdeoZAIgvFkETFIcLLvMxwuHQkRVxsNoIgAKursNKvneVliTVftRIKxIiNlWesQqpXusYKddxPajdppTZDaRjFKCEDLlCodqVGCRzTYXMUsqSfFskvXTYJXYaeWjsSZSgUtRlcrWV", + "description": "RESndybjBKXlapLazUOtuRGmIxZPqFMIiATHeQqGWSILADfBiypwtLiOIqVDPFKgXVmFvUzBLStaVUMjxXQEIIbhFuGDHsYtXTViXpOrKzHABdneyLvRodnBGkNVioqgHkqiaPsoCCkGjmJBqmtHUfXlstwTDMlbBfkRMxmkugYtJnBNpkZiZBQcwzyyWOyAMNZAfJxtZfRyvFflvGDNlYvRIGadqjCLlQYyBsmKhlQREPwfHKuOnFUyGfxRhVdrnamHSfSWKLrElPhsulwNxVzovMyurHUpFRwiFpMOxbbjVmYrsaGeLrHJUuQiSiFwnsGZokZmiuWNetruuCgUqnfhsMiowqzpVdKhZiGbyeKYxBFtUuqBAOzmIRzUalIIAhIJbkzHqVuSNZCBfikaKtHtKmjmoIkaxrsGNvxaYKwRQiPEbWpBjjFCnWNaOljuDlCAhWqCbUQOcexHQJqTsZuPnEGJRUguMcRefaNOgbflarVVLvUCOdsvzlDSGaqUyKrBeybLjoJjrRitbewOrAHUmGsaTWwEyTpxAxDtobZZOtqMQIlkysGqtqjdAqsTEcpEmSvNPmIPWSavOJWJWlDghObxboZHHMZjKFkQubPUSmTXZNusbOBDfaZpiMEoUsnPlrfbzhCChcgDnglsulwvMhiIAXWnYyyrERZthKCpEnyHWhzkrNauQSLdCIbumGFNBmRwWfVxngCNiwvQYzXpEXQfTyLQDloONxpRiUiVMnvnshmCPkJjejxYGEeYTRHqzWZftJIvPLuRymfLPyYSHhTMnSSvuDqXSAMGSXCilxbFgjNvwHtNYWmCTLpBgccsuSklkBStbwXdUKgVrNyJDntGZIMCxsgJDprLbxszmkKOgzDeCLqNldOdopsUxDIHovhnyJZnoanfXPkuUkJrQLtSrKmVBCwEiUpIYTcjVUsgWUohpAuIIbmDdKRuytoQLJIyCokcBvrxCYuSROduFWNiehtmMiAYBhYoZPtwbpsmRmvdYNIClOyiiGjMegnpgdaIflThLvxWwuqrGQPHvLiMdtfENuBjQsWvHQuBytwppmlTRonNDNVuLXguvetxxeicNOyiHrDvmkERBWAypwmTxNKdJzrpGYfKRwdpBqXOGwoHdsHJsskfkzkJqyySlncTyIUlAtdLUiUrVMGQJWlEUqlYTouaCrXdSRBDeSBLZFIWbljzpaoDnWkYSNVvjTaYfDyKyOftlUgzpqGgNqIjeShPLamcqayzInXMnjokbOtDpIFpYRfVUpLDEJnVapZDDgbEiMtXcyrKyILxpGwkqsAPnHwnBKxdSXSsIkQFVcapNHZVcMFxqVkHnSDvomfZEsocFJTIiBVJmiQhSMjetTPjOEZbtQOLQVKKMLYbhiGfFGziRdEsgMrioCKBAtFvDRwkBfSlJERcSmWnSwYftUxmsgyxwWQcrcYcLEnpdFdnLQhDjqQCnUlcOrDDWrTvTmLeajvYLHsnQifpSMxWrfRwtmOnfWykWXhwWKOuSEMLDEcNuvxVhjaWPTAMxZCBJPVnZtMzFKilWwXxVeDWemslHcMfrOAiWVENwmPkEbdgJJvHSmZpHeAPlitfqfyumzlJtdyASkhGIjXNEURVHIpLsTfverqPawpaLltrjSxGfUikcoXhaTMsOWdFfoCIjOJiDFcfzIHlpxsKHrQAWQhyRACqlEpagYiOcDmAVltQKDmLVSttXRvMZiSACBVBNzLXZWLDNjOFMyVmLtvARzOleMoeJaUkpIDmCGCEavoehAhGrmamxAzJPLndoZUydTFiABpwdCQUCSAYuJyULSYVPsoUVGiwNDtRhzlWFDIuvhEqpSqtIKoQLHNWBzKceBJoIjokSibNlqRcyGKlMQIMbqMcQXTBgxzZqaDSMlDagAJWERbWRaxImJLgqsQGHPKjtiBmgffgaZmnwusWpKyHZpiDMnKMtkjwHErQJYLJAEDOPsGWapSBBGyWVytmKsbSjNwsyFVjIArQbbviLWqdCzBJEzfwwYlvzfqUXaEGKZTnEyFJXqxXMMmmYGquuZBiNEBVMciSsPyNcmDAPUsbHjHwdoPESaIDzTwYFTMTNwkaHIvDzdQLcLHhpNZAoSwgbfaGjjcDRGjVkVCOqPfhCvVwEPmMHALnQAmiDgYrQCPgDFDmoDXHFFJFVwQUVHfkJKwfehHtZdkAJILFxjLYsKVreQNBXZOIbZUQSVFFmMqmxfSdbroZjiUDcelRTZQldxCFbnQFYgcPhjhmcTVJnILvsGgUEIOViYNfvaODetWwNpDNxWbpDxxfCUYuEgwFcOMEqaOZGcibcDZmikVoWokXMPwCKvvVOFwPbzyFrgXzRGroKAeSPHIPHarxMUyetysmUKBSCOAasafWfCvMvrRotfTqYHNJsiSTChcfQMCEmSNCsJKzSevliZunVSUcNBJPmJexQkplTZkbGQRTmESRIwBcwjrGQaRcSMtjwssSEuAeRmXHKKLTeldJuEIZIVypnCbovzNomeYnUIXwKGEuyrGinqAPowblmXhNTqcMwwPBqXAJrEvCCmECGlsplnkeIsxgSdCfqsvODpRKeznXiZpLYKrWTUUjGYzCgBidoMWbjThzUqejocPEykjfLQcvCKBByHrGiqdEtZtxCbHLTNLDjkVWauwLjBgYWgtiACVYmVujiYLpJnOfuGThpQNLWuVDeZPITyRruaNPrQOkkOCrDMeTRZQWhJDAAcohpBYyaiWpYAelOLhEiDoSWlSSHfevQaLnNqXRkLRtyYrhNwGTHWiqgXEHmkuwkzBlTupXrxrqueeVJTSEyGyctAvJQsAMRrgqpZrxkfNiLrJvycpOZQtVnwHmwzmasIMsfwUybJWaaJIUaKbuYGmYhFnNkHifTrZMFyOvfUkNMbqqcoFTjGtniqIzPHcIUkJbFWgPvRXxKuKjjxkYbXNblfUdpoXRGyiWQMIMvtlKPgEYycIIBmyMhRbprtvcQbUjnfdXeKSOEScozxAqvCoPALMFKFDkVUfGMkZCvlvEBghpBAtgWPzKvhskznqrQooZwRQbzeqOuSUXCEqiAjrrFNyQMmIEoTgxwuBPJsFmritNfgfiHStJUJJqEEHwvjFHblEiuhjQPgGgXnWNhxHYSsiaHYhfXnqhwFOcyXCWiuPkIqyjVbqwHnguNUCENCmpvcUXUcBTWgIajHlSgqDTJVaLsBTuyUnfgSAKeIaMtIOiecXFQCgfBQYREFFfhiLSQwkOlEeiuujmVJVJWLLHVpbcrqciNxchjbIhVDSocQhtqCjtkBBreqYLGkUPIsxZUCLDgnfECQwuTRQoKpGmHVhHGVeYWJBsqllHYJISzQTOUDaWjAfdxcCHUElYEULoZCdGmapzdTBHVwpMLMSVjMfJbHxAXNmAkHngAXpVebvLpeWTHPpfvKMwFMqzTjHlFCpsVPwdINRvJsKzEGvCRfvTptjdLOwYxXIjGsOtdjliOWvQsnrTrocTVRcRnwvxbMRwghfcCAcATRvfuyhCFWUJDyUkzEthJwfXrsJDSDjuspqNwLPFLBSyiSVCMoiDuYPcGZnVDaOLwaAfnIoxVOfWyDyfFSWIqEkUgRXKDrozwudsbcnnSVkkcZmNGeWJOUQxyqCqpojbKLsxvuKmlXMdIKODbXtySNfPndUCUeFjEvbBbzzVIHrfhFrukeYkHVUJMEsOgjfpINpHRcKDPtKGDneYsMCxfsbEqnUfpnaHMQOThlRLQTdmesuzpYjkrkdtwHNDzlZoswTgyHrxnTgWVqjBpWYFpZHbMSmnMUHqTuqPAlEInrAzfPCikvhSuxGuXqIPFUBWgFQXWAJVRMikGWuwzbnxfQkwlLOfuoeFtzgqXAwgnGiYKVxvbYUHPFpxprKCbqCQOvQNULBcaxrSPcLZuXESsFfvIsEmjpsuCSmeJywjMtIttIgTkluOhCKVjkCTVysUspEMsiYEbppbxIeZbYZbyLlpYKmQRUKspqGHzdqFbWszvxzQEbCCuyKVRyBcoaffcaHTkQRxpuMUjOZOaqMIQKMLuyiJLHjdomPXkxbkgFdnCFibfqEtZJoCmfnQXAnTGGxhiZKyHLsiItVAQeKccqhcDpXNjUqgjHKSMCzOgSnEHMTgpXcMbbERYHXQwONNNVXRXGrFZzThqWWhTDkgftSzrGoKVLERTBYGLCoWHDoMKZxIorArZVIOioIWyjukLHwjqJnfOCjfbSBLuEwEyOCzpqctnSkbaZnlWwKJlzbBvpTSEOHcweEeYzcwGamtzDWdCkgXBqTwzolSmmOQQHFaOxVEVxiagUzlooBpWwuSLWAxwWNDxgfUvomRoCYETKznPycytKKIbZDghHcJoeuvFoSvsxickpyUBuwIYNvXFDhfkFoewBISOZjKTxSLqCiQZuBulfAPsQzJaHrUpMcainpbFHWqEPwJSITejHfmvFmhgsfFDwHGeVVgbIiuNgAGrVtZOFIrPpOyPgnrRVPEVOhdJTqBnMvQXjWuvwPvBfcjBCEDQSkDIuIYrCJJIqwBcmucCumyhCSpzjRPlVdOJHVvNOsHtDksjKssvjLrIfzkkfvsuSVsOcFLHPBVkaVFGThzoxMoCqtpDvVUSppVlqsdYeNuYupNaglgdWxVuokJKKEaVWJXcefiztIieJonmeEiwCzfqFzBcaYoCTsjslvDbMUUrjQcRRUZXNDSsYvrgRYAaUJESfJwfuzocoDurERieAhyHZzoLwhRCCFyclGNoLvVOKGPnDkVkasNdtYCyhOAMiGxEjZIVdtKrFqApANBZgWHomQiNoDKBMTrejEBgNQrIdNDTKyCGipEtjMVYRXNMvjzePpdszXWeVDLgnNccJsZUlPmeDXLpRTlUORvyYbsooANoZxjKRrMDToXNiubEPeCCCBOtYLEHMHKGAjgLoYwwSQfRGqoZbSfZjDxgPDSnCCYumJDxPVUipdCJCTaZzjpOpHhfCQYnRJN", + "changes": [ + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"112\"" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"196907000000000\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"822\"" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.500000000000000000\"" + } + ] + } + }, + "ProposalBase": { + "id": "26", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "368" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "ixiJpFrxkmdeswTRGYwiYGRQWXsQCycyRULezGRSaMUjvniHRdYyCLLahMsarpdAVxAQWwYvFXIbZrSSKmftGwlpvZYTLJGgQnaiGpKDPrSNCSeveEeNzyYxqddBIVpLexhpGthMRogE", + "description": "shDmfZkgwhLDsWdTOnBvsZsgLUEGcUaFbvoWxsaaWSQWlQfvscBIpPHHlTZdSgjqAnslLCMVhJOqQPfMwFpIeMPmkEDdbxEscDNPlChhTSoYIbqMcyxHndXEpZBRFdQcpcpRRSJiNNJEwigaCCGFVQdqTAgZvSrahKkvDsgFFqKsrAKGHaUSUoDAqwpMxEggHqYekYWYptMOqdntHLOyETGYlngCJzTygWHcoNdnCwtGzXLIQSvAhXUAvntsWPqDcZqMXIGKhKCAuUjDAYxlBDnCPKkrLPFPQZUkaZiovaCFiNVQsdOIPsCEKIIOpRrxzffSKjmcrSnSxkCEePmXoCpJVyXnNPdrosuYqHaUuiJckxAgldXVipAutCmbjiVaWAIiioPCuVFrREAhkdbqwXBglngafumzFyOMJuCWCvlLYFQTaawXQaBLRVyxSrFrSNssNMmipAkdfwZYiGJRCmbsfGAEfevBAdsSZYrSryVktwFSoeIHKXeGIbWdRWIjhfsJPyQvEmEFbnZDPIcrGkNkMcCrsVFUShyNiYttDsxUbrLnNNyQwOXzCbXLQTTrXVhGpvUFMkmiwpifkRaFGyxQdgPWKTdCcvzAunZLFnDZTXWbtHxecNQbjLjLCbpzdcXJxmnGihvPfIbYTvMtkLLZJpMBIjfHnFEmcwdMuwYNfKUQTjrdeFUNoLgtgZhkHGyKElbwiBLaoFAKLFrVpzNaGrGJstdJlnbNUwZDKwJcUggYiqclwWrrVJOjxIAQJrHdxxCRoIPXLybIadCzBvAzcKKPZMTOXYsfJkJsCFEpHuFPFcViJTOVASuMsDXjqkkArfEHBoQQKpkGJZJsCakzblwCiGcrOqnRoajAXMpGaZuknysjYmSJVFdSwlVooifYJvEiknLwNQgvJQYJtwbrEPbXbEtMmHtpyEEexdFgjHZBmqLfsWbXvYSJVSHjWgLUDZNponzXxeHRgusQirCxzXmTemCyJlLrsLrdLIaRaJqZItDdDVPKhOtuJUiMgKWAFYcuizwdLxsUqngoTLmdCAAItqKYVlrwXpaOXeUZIDujuwOCGKBiEGpUnmWwTBQXtgUleLotTktTBtfjhsqsQXcugQULkGFUsSwafaQyIaoQZchAjpGvJdKVvBvAXtrmssOXKYNdGCLwsTQOSBMnBiQDgGoZqGvnGCYrAHufgfcBGLmTmoZAhUqVltGNskGhToEDpWMIRVomGOEFenbbBAnBQQDtzROpfYQxyZDXKYZKjYwskEqcsSxgFcpWFBFSFGhkgFrcHTQtIqeSIspzfmAmSwEFsZHDLyrnANNqrjZOSBwZAyvQABsNJWgMCcNZlTNMDcpfJmkxKXrJuKuFHhcvpsRugmwOfTbobntkejbnvRylZAyfFMIcFnvXsPBzyMLCWMszpUoaVeDWirQnjAwXeIIwmcOPNMHAmSBXQJOTONEXHUwfjGpGXpPXFnCHjDwEYgbVibWNitqkSKXYwBjgxCefmjEbBzjhRMOYPFMkEWIDfiRmbfyjfenvIFakRTSnkKuqrANNSVJtdIrFdaiWRhRAdvlJeUyDhBhWrZjDrLDcRJUVZFHjDqfGmAGYvpfaKUQTBqbSvorxPWnPJVFtZIanMreTkvbWcXeQHmrjvRPqlJbqpDbvacrzkBNxmMfmvuhozgPcisyKzpFYfuIVOmVCmThLiCzMTuTPoKPzWxFNBWdxKmyyRlkifCqZvBEuzRyviefshMikoPulHfmxmIPGlrNMZsXijMeHeAsDWncQCuUAtrKJkhbgklhwxdPJnfRLNSRqVIpoFkrHBtsugrJUFktuQBhnwwOhbPUDvDxnSgeCxcZXfAViCuckmjnLDeHnsSzXESnMkEsAjmhJAvpWJixEznsOWQreDgdkzrHaSwKOpWJtLHpIUeSTCWNFZsVFmOzxwqWJjxqogKgMpcRCqWpojivlRAPMyixsvqWwQhGhTPxmFPTwwUnEWMooUTPpDfpcsJukpttVFvyOPllJbrSQViMkjbFgeaUgNorvOxNbuuVFKAduVzMEvzhGRJuDsMztvdvHNwgrEeVumBzxilHjQHAlvZKYAaPjqqAVdeJkUwloAQVedRHiDZLIuASrrBbrPxyaLAEPwxPbRcyrUFaezlsHbVSxzUSbyuOsCuYNCGDBLHmDQiEEfUGELwnsNNifuZdhEWqjfnlbHMyBblrzkmJpUdQpuoYClBGEdvvKcDzxrBdOyBrHdiMezTjPYlDJLPzzjIMJqwZxqYDaNdphfZdsKzoFEHSwQBlNnQpEqwJyVYZkBNcEBZKIRJujjzVXrunxJQZMVOjQgdPyimWcxjRpmhKkfBEAhMikznCxOaHflEguOseTYxFJPhgnOdOEGlCzRdpjupqFDGzMMvuRtabTPmyLOkkdkYOaaKkxMcwFmCWXSRtllenPaVBBbNmlbNVMbAVQdMtiorhvkXgDMecTwmCgxmgbjOiDilVSnEDTlwbScRZoUoLlcExjTEuIwpObOeLfcghCDjrCqUMEXUQRYCutAxKxKIYKaHDstzKKFFJAaBAupGVPvmFXwzeqOzYuMxshHXwmgmPPZkTrZjmCENnYNXJtBkjNIvyNmcwekYMRbFmTEfHYznhrYHZCmRfSbQMaijsJEsHAjbIUtzIULSiCppadRcFlkXwPYVLSHoLXBzsRplXDqpnjsuTdwLtyRBeZfXzSDzRkbZPkElVLuBCfCIUYbzFBRFjDmBLBEQfXIZEdGawGxACcjPKECfrIIFQKIaSBBbzQOoQxOivObqzrgiIRJszSKqUgqOESEngDoFFpjgsThrbhOLaxGCIjzkgzWSakZRswFHYIXMkDAqNFzSYpWPDMFsYbQgwDnWiJEMDWYZyPZAyEBiFcuBprytgXAsaSfkYaDQTGjcKQlhkdvgbfdEAGUmbrifaRgIgSXSUGEvhTvmPokHfUXrSXmhGiBjPHxwelTcgIplWJTAaBqbFFcmZVjqvVjNvzJWTLMWhICztGJudhLazrcyzYEvxiYDvMdGDxBEVdbvkyQkGVyKTvuyfYuPpdRhXrtaTuvTOTVdEswlheLUTxXPaafmGmEUbmsYgxmSnGYfEvNmRNDSJouugZfDiPPFAUgytmHfYEbyyseXoGgjYcUUEsbTxnGEWuUaZmIZsBIUIIKTlOFOzTALbHhYgZIJNcaaHEMfEmFtkcFDWqAcrgmTzgryIanOdYhfVsGJqdWoGGpfwfNmxHAkioSwLCFzCGsUdEWzKZsPjlRGRpBIQPLDMRtRTYPGNqDofVlclVPEvSWQpvjGsGEIjoSoIHQYOaWkHrbsMdMPiSeGRKCsYFaIBkbAqOEkEGvLdKtPWSssTgozEnDBOFhiZklcZbrHWEMNtgxSCNCuAjzfoSPZEhhUaBZjNOOljiNNJAOAIbZAoFsoEbCPYbXRBJGrgHSMfigjxyFutXPrnrskdqJOYdndAfkEocQlBIeAqOXWNNRurtsZkNoOmVspUOPICpeucTGdXpmBkxQTHpCZsBTdyDYrCPniuZCfSVBNYcYPXYGPObJpfVvNLwXxoGqJUObuyAhrLFNDSOBuUISmEuhiatiAZVuOhEmTdfiJJDtYuYnVQxCANABaOSsgAaatqLTEBhEDiKovwwTjDqzyytRPxBtSULPeaCEMaSXpJyVkXtwKKlCwHSOIAoNOUFmRljsTVEUbPzKfeSxHAgJDwnMzmfrPUrqQvkLIkhyaGeKyYebOXFebVfxZZDrZsUDmrywmYUqTvHogxduVgrcBhciSfbrehOvmteotwTXXuyjWXkhGCzouqqrqxeRvoNwpeahPgSTMixvVikgLbBwbUgXLmVKpKhBXaynrABPVYrbbgDiquxpOBugGShrsvPnXTChkOQPndiieWSzjUUTdWSKjJkIBfFUjaPWRlyQiIIugkJmPwXdLWGByZPZfXASHAtwNOzhFChzAJqdoyRCSmmRianYFYiIzOFolpxyhAWCluayukuApckfWHhGMSPOddGtnsDBPuoEryeeKeokBTDqOPTxPVAnlLHgiHhlJyubuftCGmXHYUnDhcSmSSEjjGHNmgDbTeCkTDTXWaCKYpWUrSQBQzfYoyQtKRMwFopiwqFJbrLayakXDtIEutpXISUISfUHggRjTtHjjEaRPvtKTrdDVCLDBnrisgNxmhLuzaazNNISAFWjmwzOWULCRIVozolZETesUrrEyvftXBPQXPaTMybEIxWUhFOhVWsCTCRDeMhdDBkgcBAcXlofBwJQjnJvdfuJOVFRGVvpXStVagOJbGLPHVnftqyNdAlXFLMdGNQzjukqoHcCBmtWguxaUAzkhhAXZfFmmTPzFcvdfuDZPGxASTrkAvwiyziKERoUgOeevMaViTrUWZGwJgzKGFfvXiWTeHKiRYuNkWwJIvudFmkpMSgMGFIwnLqTqmqovcssFnUVuPOwZUeQgANSXySiKKxDRGUKWrUhhLhJKJJaRXBoiopLmiBgHYsCjqPjcCahrIzlfcQsaNMHeoRujXnzFoLrJMTZleRajojIzLmWFGfLTfhoiacsBqYZhZEuUxjQFKvAjACaPrSUWfWqIUoPRdNmyAaWngwompHWPvfShbjlgENrjnTzCkcayJCfOXWYoDUGEOIazohoGJxxgsPEHXmyaYYCziGSTWuvOGzkHnFlJlTovSwVruEnjciFLhSjbWwchIywmhMbHlqjYlGhtrbDpwWhLNGsOCemFcSIcgYzGkkSGBrICYJZSRccKEbLccDtPinbjVfVSxawfojNVrsgrXvSACwCqRQhIBDtAdnztUDBErdOMKqpCjYVvGBDvKjXrAYnzqUroozMiZlnMlkGJPLVIUJCklkEnGywvVmeBjbGXwDKWXrfTDLpRpYvsoBlSTESYDROXzjyLrNUtbkvKfEpeAIKXrivTsbQLYBLirrrfLctqjaoRbQJsIEhpiwZBoETzfkEGytnRFQLDYTxziKcMkf" + } + }, + "ProposalBase": { + "id": "27", + "status": "Rejected", + "final_tally_result": { + "yes": "24914473521", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "277" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "VxMHsCQejd", + "description": "PegFUgrFHgUoDYiJnuOGjBblNPMqrOJyavhOGrpyAUItRPoovYesWSGSQboBCfTiCypwdzusrkhNkTMdlsvjyRMJTPtXlTKCPMZI", + "recipient": "cosmos1n0f0kcjjwrjqvva5wq6x5nj0c45vddc2rr29k3", + "amount": [ + { + "denom": "stake", + "amount": "390762837487" + } + ] + } + }, + "ProposalBase": { + "id": "28", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24914473521" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "418" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "GDSFXfaPaOKOZBvhBPhfFkEbHdnmwQfbBcjHuNOuKEdlQzPHbPwnkhhgYcJjWwYPDVydeUGGSgsUGZWLtREUBrLJNVhFVDBWANcUwcUpbbGiaHSihjzZQihaNPtqrJDqDgIRQaMwTUvJ", + "description": "lYOhEgbxMFHthcmHlxEabufYhHErQYHkkxtrRpTzIWWrHwixGgeBMIdFkesjzteOEdcMfkKAsOYyUyOLjUuwUdzOLNBeFKGSCsRpvvZslSRqFVhybYasqZFGHDbIqmSpEnDgNAhoKbBzpBaWPYeOhbGQIsRYKDLtXLuKrcGhvGqguiRXWlqMDLsiFYHddHIcxMoOVUyiOBgPhJAUPeBTTgUkVYfqLJnEhlvLnrUsnfYuyhWHHMGinYsHRlbYoLFJmfsdujmsamOiCBGhXAqtvuIUTxZWcEWJRVVEzRtvJQrOltlYOhJPClojNEadwLohDSVCyFTWjMGskvLVyNwalDqiBUcgFvXOyLhIXgfAHPSOGzuYMetEvcKyDbAjQQNQsHcLFWOlMKLoInFoaAYxYFsRBGDKVYkcxsIeDURCcnmazlgJskXkrBjKpbrIvAqLRTVddGMPkXrzUIGuWUQZPooyjkaSFszMyxGvMgwPmRhPTcGUyetCHQnQutxmLFBNBhtJUWNSkUpUefjNHRvlymIjgkXrSxYtbyRnGYOqXDUfhRUyTLhQiDmzvyHPEwwSpuqVLDmSTmtELDPcYlyyxJRYiXEXiyzYTNKCFsuokDeidfnVuGAMSfPPYtpwISSwjYUABIqvzTrLZMqfOaDsVClisMEpEpsJbSORgGVRXmhTJFCeltQKWDuKfagaTtLHRNVOgDARawOvNkFuNnebxDPKfxsLHboeScmlSihaftxgrZGVIDFOloKlGlDtLPhfbxKRrnxUvfzRFotqyDowKEVDvcoZsiQOpzSgECVwfyCYEuEHxnKJehKLEwtcWWCLoHEhfXldTNTdlxcgfglbpkIDnQyrcizDLIwWfDzVSEwxjSeJnKCQZuLdsIovwlMJpCqKOsizBHAIItFGEBpEYLevSUfylAlpOjZIqfnbKujeyTXdfQMYoOQgUqsxouAGpAzbOWblSrBdtqAiNJUMEmBDbfxJAOKMPwbNfzWupNnpsTBqIojSRjxQBaIwUXxEKqWGCCnQahPcwoAAYFCHnzqcBaiHYVBwIelTwvslSojjCanIBlscCyXVUBSRxBoNAWNcjAGZsDTqyVhpXfvsKoKpmyARRyUOPsQKPWxVSeqWtvIsVWdGZdVcoCIRgftYSlVGviZMTzepIWCZSgyZfzvczoMPAQoGmfYyEYeiqVTHTgyeTNvIOwIayVUqoOxkHLWEFQpAKcbcoCuQiquleqNrTKPJmVaOdiRNRHqNVicPtaJtUFUtdhsxxVHMsaenVhsZTnDcAPaSmurXzjqtHeoWJeAhRFgGmjQAQORaWKFYnFngJmUHZqZtluQOpPkEEBtfjIcdpFvzqPGwRiCPhBcbiENFDJhNUegfWKvqDROGdRjRPeudGYXdoobqjMXsbqZbfOiBuuzmVtZydYDSxBsROUYBCoLwuQcayovPpoFvNPEeCbDMXIuaSxkiFlNTLhoNLupCnzmzEgujvKughywiqRkptPyuNyYVvCbQGoWbErBwBBODEwdQdsDZHkvZqzeONgoaGRxMbXGcnXOuBeoyXzXYcfxCsNKGlZhoxsScBzPmgAfsQYSAYisStRQXOgTUjtNdPmdpCrIrmUAJALQvEUZMDRcZthzLJcXaTjzfgDiDlaLYXjTRxhNoOwLgKAApKaOfzzVHsWGTahrqscFYhREfbFubBzQVFBqNVqGMZRdCrHbwCDElifaShJPvsKmCiAesEwiwMzKSFMnFojkdAsRzwqzdfoLlJukfaHMyWSUimjWLGOFEtGXMOUsTPimZAHQpiZjDzGABGvpvVSaXttaBgfpZtWxFSfjHvokjTygHrsZsJQDdrUVsipXjXIQXjkfDVKypIEeedqJgNkufvHBnMxFxrDyBfNzvxsZDamwJzlZVlDnUuEfHyYMiycRZVryLxlSIWIyizGIWcfbsIvTcaipFFlZysZtwFIsXDAnpZriZwbVaqbHpmxArqIYWpYqbtpFAgfPswqnCwZlyVvPybCesHUhkEiFDPuUeohkCayUGtaLhkpBnHEPuQujlpGWAXbOiRYQGmrSrVWcSXeEfTytFgczEFajiiQntYuPUcxCsGOennmYWhZCJIOmScaqcQenUmYfGvPftiStidLaXUEedIbAzmlwBCzoIgalQglnzrqWAtDgCxjKeRirXLZrJZqjRyJoVhRIPzJZOsOzMMjwvkAvJELEgHKkNAKodREcsRWslaHscIGfNRgtWZbHXpvUQhwQLaRzFwUGBtIiYCiisldaAaLivCZjXWPsbfLCAjVGJKVHpwfSyWeHWqRZkqBJgAguSDQQJwTlIACqUCuMSgnlcbPmAEvpCEPTIBDEdenypgIIUExKJBWBOvGqeslTtWWFdrankNBEirhETNCfmxVWPkoqpReLeGJeKDhdOoiTfEWqJJjbFvbJKtnOlLjJWMlBitTbVrqkHJFoBKWstolnZiFUCgCOYxLvrRokbsLGqYfCEAYEDygqIzmhedFxmIVTbhzrhWwfKxkJZCneKVIFgqOhuHPOvnMOdxrrJGwfihTJYgXigZwOeJJgTmkCpCFwDUecBiSehTxjmTQMFbUInogNNIKYWXvmypznMubSUAQnSjdyxxkGxMoTfILuZKBBBZhSWRZwXXDVNuewurgXBnLrvDahNrYyctQiRPHWlbKiTVHvqoRuEJbnFcoQYwqBLKYKrEBiTOWfjhdQjwDYuIcYNjRShRyGWiClYJqoNteWhrsoPHIbMJQrFzNFXrfBnZebNMjcZrVvTloLaGRrjQyBNwcUtJZJYntseKKYWARqXRaShQoruieTgWKqDhtXjdzfayNTJvRyQGUDWFwGWHOdLtlYeMRWvXrwlplByTWNoWUsNOsnWMFUnAgMDTXXHcjfnfRYCcixFRUGUbvTfSBdnSpCjLLMfzvnxidGFmjdbhpqfWeDkRGclHdTptmVCeCQZcVOagKwIsyZjZPjgGIAefqCLeRweADnURXUPlmunIGUQqpCVTVdJKkjMqMRNlaeLyTQsvqwrwltlxSvkdOMcLWPEINbpXUyIwveUuXrXlwKpRkhIcvSzeVqiUGfvMTCJgpObfgHzMKZvhwIwklZxCTsQuHsvCqUkyLXjOIDbNZpOQUwlEPsvWMzeObhLBUzHVpCuSbBnanERzNjEwYnAmwSyBleHyITZeyvpbCEZYMGJBKiMipjGMHbIhnUATgaYIfcwkaaSQeajKYHXAPtTjHokbqiWWeelhtNdqQpFewomTukDHegfWHywpbJBgEhOrWjVhpylRehjsxZRjALmTHKYeTjPCXgMsmIqRnjjjdcPWmbBTQoFsEGfjvrJIPabncOaQctzawCgsgnwdBPMEkIthQDwLhKzFzFFHGvgwjbzNYEIkZOgOEZzxpcpYOCfDtqbZJjIkHCSFRqfodvMNrwHdSejnafhmjuhKVgmlfelHXQdPRaJLLpEPrQqACyCvPTQzMOvoHHZlyUcYseuwBLIhEiWOblWKPQeQuheVBGkHJXOutQQivgcMTxpFiyNdndVLflzBnLbOpUguwMVwjjYahQCPQioDBcykBefJJHTMhsFeldxMKpwGbmkFRDkacGWTWhAIZJpMSNqsfGAmucclykOUWZdpBRALvykxJsnXxkMLOexxIJdoLpUQLMsHHRgBZNcAedtsXQNTaFihijjzOyPjsCHPyRpHZHJwPCsEAExHJcGiDPjBhyetsiXmuBaTYSmtNJcQyKTkqVxwNXoXVmOyhzBeiZUduJTgJpScphxNHvTKASIimQRMDNBJclPXlGyODZxgIXsViYAhKVKhpZkfjnSBEEvWHAsbAzZdznNVyeIYGXAtQJSYyfInzPWXloQULRNyusCRVBifdHBMMAqvShySpkvjthjgnkavtFUyPsGdDAPcqmuPzNctbccffotPwEKMdLYDCeGNvLVBacNLvMOcsJkxySjoRHNxoCzTycPZWAWiDWCogMVvpyamAlWDOPmsHcQWhzBCoSuknZMNfhSWYcoOGyYCOlEGCXeoXdVkRaKqkRwDGJcDJPMPKAuTDAlcpKFQcIxuGgcqabjiUsSykGdxwzsBgKpHdxSpXwDDHtwFeIlDvgJCcjMwKXoeKDwnIIoAeBectJcmAqACwKBwyXIMejElbXqoEitcCPhuxnvYktIugizYNiMmZkEHPZexShBTbRMyQpWVMeWEmhZHCKOYTnunkUIYZJdIHuRJtiVKEJHHSCnEWTGskbGKOgBHzTsEqmeYluqVgcSXqiLnzeUKcRlYAqrcSSrmWojskkRBMawMMgLsZaCRsvyPgDcetiuuBLpttLVclasHmrFeAFzQfVPTnkFuIJrsmYmMLpckErSqFhNhoGzWAdXCRzImdgeiyoHWAaSfZvUAdxlGatBhZbAHhXkbtGFeMITVzmbLXyZeZKMqRGpnOFcHZDOfmdZoPKBkrnTKsMpzvBuTlHKULpppCaCCjkJtxoVdZqNJoztrDRiwclmOLZaSZYAZAOaTAYqBgSIOzXHIqqjRLiviSuxZbhjshAnBxITrYlKIddhygoPCTigfzWHVsHhCQRCuCLlKpRQEjAaylcSdlpHQwGaghvDaxaziyQQTzHBQGukSPZOZpfJdcyEBYJkXrzNtCMyEAkbzxUVtqAtmTxDxaSSOeaRFUAJaqQliLGDLaGUEKZVpdekJvQBmMtkbPEHYumbZsNoEUnZojzKdIFGShrMGRpqCUgjerwnefvqlJvUrGmWjsVNTzPoMugLWtAOTTokzbuoQQtLSevHSOKyfrYKiXwrjRuyglQFxEIVOXfqpylGqSQvHFpPWSdckrKqqIaZspRclaBTIFzZMKaJYxRjnXjrpAHoEUMgRrEdxhECiUGuufhcAPgQPVmJbhdbtBkQuuNvbdlVmQmsmFkvqSQKxdFrbjmfrgDRPYCsbKEIQVnwHBsNNAGbAkgkGkMQjACuEqeXEEaLZVQyIuPpzRnZPgpGgmIdcnwM", + "changes": [ + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"9\"" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"11\"" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "staking", + "key": "MaxValidators", + "value": "220" + }, + { + "subspace": "gov", + "key": "tallyparams", + "value": "{\"quorum\":\"0.419000000000000000\",\"veto\":\"0.332000000000000000\"}" + }, + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"221801000000000\"}" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "gov", + "key": "depositparams", + "value": "{\"max_deposit_period\": \"338637000000000\"}" + }, + { + "subspace": "mint", + "key": "GoalBonded", + "value": "\"0.670000000000000000\"" + }, + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.280000000000000000\"" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"175\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"754\"" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.030000000000000000\"" + } + ] + } + }, + "ProposalBase": { + "id": "29", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24914473521" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "334" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "LwwgzugSIVSkUXGrQrFlHbbqBnjBYIbMKvrJyNgBSxOlVCrpbwndyPHQGtiAOxZQNJoZVWzwfRYzBJqxjypeaBeIWGFBYGbEHXlmNWilcyerkTHYRHEaYOrZcODDmzISnAWjvqnaiEZe", + "description": "sMOVlkjyyPJNTVIJiLCWHWRtnXfuyQWPMumEATuMdkxNiHTzcAwNSIUMzpPzTQiNqgUWfXpkSXOWelIYvqtDUAzEovtchYZFvWnmwGdLOfKMalhawzkRYYTKjZTpZZQyqJXTqclqHDWItkjxPBizJpESUgvjsEaWslUGeSgBiVRBaitXhWgJEqNCphWkBYQTeghikpiGgBhyOyvKtHfBNvMSlIpXwmgvJrRGfiySVBdXqXXKYWgjUobedbVSscZMnNwvOeXSiqkBLGZCefegIjetkvmYQEhXyCTDWZdDlcXBCfewBexSfCHbQSyCZBDJrnPHdgUgmrQiWOkySkeTzKbZjRkKDyUdAZYuxLWOoyqJfDdGAiWAXygtQyQYHlfwGHvvgQWgGkufruYCtnkgoVDqPKBOpgiNdLpCywuMRcwYvuRwPlvPtbjFlTZFoRdPwtQnvZGXhPcQwGRsWKRfzkGkHShdEiofScRlRtQFaPxHTZPIMMiKuLgFGmQYvcMNlkowKbPFfZtSgTTjkwgraoPyBoxqTKPSlswisVyptbunKYBSVxJbveWYpAyzMvUsPtudTBRohKzsjmOBJetafdwQtERfWFthbOwwSaZSPwgwnttzRveqxiMThhZGxHXPdtsyjwRQoGoOLAMhTaihFMpjabtESPVjexTRyDtIIKMLsLxPGefiDmbkFgsREUPCuZdXfjqYyyiVMIEUlVLPobYWWvoVQFlJaXMMKZpWJJFbJWjUCMpPzLyRmVgPSFnJGqZUSMgsriRhrlokOhOpsbzcaKWDEaTIyMKqnWUkHmNWOvAYnNNLVfvAmHxKAtSjMTrtBVobEottZLPyekVQEajUkByllItXAcdLcEIleTGLLjCRxQBBATlzMnuJrslHvsfbmnmoGqvlnvUNPaSagduaAhTnxNNjanLeIcaPFGCMtyWBJMQZTtcySESEpctxNRlUIceRwPLsdtdfpPpNogaVLynPrDYjKbRfWzrXSJxvVsylmpZPNgoBafEJrpLajBdseYcSRWUnWTxhBPCVgNzTPRfFAfUXAAWopgwDWjwnekHKTwjSZcHCYUIvUMeFZQmSEPKGcFyrUdKdqMXYVATMfBYVVLDSQcySoxLGvuMMLMXTTLSlAXiiqDYANAEbBJQRmMHcLCrXocXKWsAzlayLKwNrfSWFfVtqwxfHQEbLHtNXFWoEhsPdouJhrZygBnfFNjWwuTIlIFlGQwDGnnyWxaUEnHUMieTpjJEMYRHMyjeIJsuZjANmiMJjvxsarGsenPzhTWThqCbPLGCfDfjUsnWgVCQBYYYMvzdiIsqIYzFbUQcXQiarKANutpZUBVMzSlHHlqTqCZyELBtqRHZfUyreejRgmsteLKVeRenzUCJISLhHaFUrIBhhgsQMXyCWnnrfNFbzQXZkZmQZGxQkHPVfxqTXzCQYxsWIVTfVurFmLORADbrAGCwpHFodCRAulGeHWrlMUEWFbeiIXmxBBaLOenOpltggIyGbFUKZMADlXVmbhXRAFctvRMawnMkjlizTGgnwkcxwcdDOqLFRSTtgTZzoLXzQblyjtwSEopZUWxBCZiHnCImJGXzmnmWxioTgLeJikmNeyNdoGoAwvwEaUvvJdPFfkXWwqzSHgqWSSSRlKojsAhZpGkswrncOGKMFrqCDjAKlEsrWqbOQYOHamADNYDgHWSBzFszFTpZidCxmtWjAaFMSmKEQbJCZolQkGywbbPLUBdUaFsTtBiXcskNOEqaWDFjLglYePVgyYrVcXLSSfFnGxjDQEhwTTyFtTdITMrqhwaRrxhYqBItPXilFYHHCRFgcYmznXwKxFzcwSaUQgbKRhSdiUXkdAJGrJQlytTrAnljtehDJjhiMVuuizdFdmjabbVnzbjdKPrZonsJJFoZlxffAzetBoSmMgAZuUSbWmrscVbWDHZfklmRLevrfiKFuWZlsqqvQxpJflWJkoQaFHaMlxOnCRZmpgOZyjrlrCRlxVQvagmtXSgslvFGaMayMknMtCVraIZeVfGJNtbphZFWamlZDmAfigmQWXExteONoCfAqKXttUHPylLKYeakJmnaYezdjJRqipKtaXLPQCIlGaaRevnEFiVmSlYvnxxcHxzKXKrMgEHgqKPuxSgZDvbNKOdgqfqawgyupXWEqNTaotFxQpgCLmlnpnWbvFsGdAeWWfLLGjUEpIqDQbiHdJemtqfTfMcRyUXnuJscznVeNwCozeywOhaLOEBdJAXqOfJHdqvBRvFsMqvJfuifZSnLkVUvElRhLpJevQxiyxPoEGlQChQNoHFeAtEtKmQdPFKeRqQkkiqXQUASPFgzuYJjawmvYMTPPTrJGphFWWgHDgMCvSEkYjPGvLpndbakQGPedjbDVzheTXCPoLxjNhsCZExnCtfJHWvVllxpQlwOuijaUAsFHhdnRsXQvPyEyZOqaqGtRYKmobDcaLlQQKCuzLptPvDCLGuDubIucsQKUpEWSljHwGlJCnZWOXwlhGLEdADeAGCmgoCGGJoUwyJEtFzTVKnNcdeiDqfHosnILRXJPPChgqrIPocbWXMfziJhTqNMmrCQBoIarMcCGOaFTiwEUbDEAuYryrmweIjSmVVBKYhKCsDuNujaddeDLcokxKFxxmJNEfMsFXzyAqFGATgdxtfHzgVtFfBzkJvPtqfMzMdvgXfxLmrzzdlylSpRCfkbjghCVlKCDhjKkttyPLvSlGBBKWNGdiDCJjUrECAHfxEfWtzMgTHpxNzJXdJhBYKAXczxYRfqpZQeCCZvuetIQQriEvWLDeiXiSwfPdpgyHKjzRRprdqZCrZdEWucEFiYyPkUGTFEjTFNfXWscijTSfNQLMsvAgKPKwgJNlBprtjbHoXnkKrxhIKtEeypGapHRciSlWqTemvnyemqjhkNiTyQRDTNLVxLxwMasMwwqpnxCZuogVlSTzQiLuIlWxvUmGFNCZtvBvJxGhaSaGujFPxXmfZqjDuSmFGEwMUYgVZLzweACiAWhHoGoNYBKnXvlBmoLATMAVjsjAEBCvntfrVhnZsJseUOlgSvEVCFdjWgaidHabXoEsttNbYEVJanxWxXPrcBPXmOHLQSGOsOjIkGUKQgIfVUqhsUbgQRHfIFgvGSUXrNKDLHMkbbmaUOPcsCiIgzsXHypmCLtFafgUosnvNLXXpRXgDMldPcBpRdLhEhiEZUAxqNuXreaPkaBGWJVdPYwTPFmAViDVbCrvvnYIlQIAOMrEVemWXSGScrRyAqyWMvrSilOgaYBmOcaDcXCiGjqxgHOupzcpeboTwCLrczCojBhBdHHruheukQdRIvTnQOXYipwoFJVfpMrvRYJDHToZbLLdnBwBTVCukrnapaRcihCDDJTOUXrWYpbDShyUTxjAmqYoSCXtDxEcrHCBJdlMGekoOVTUfCJGSpsMnhWGouzERyQNMxDoMqOqTEynhYzdaYfJWZDkjnUfgPUqQxFyovvTTmAxpWkVVumyvjelmwGxLhMBpYaCiOBUNEKjRjXOgoMcbXFJbgwXoJmDZcfFGUulHDZgzrStzgEwAyLGWCmTksZSQrWYiPLQKJiSTNCwgWemhAnxepQicZhChLavNdolZnoSrpCbMqseklMIapWfCkKmfWvNASRWnthYgiWNZSPIerGskiKjYVZKiPjfVnOTuJSiZDUzwspuwZINMXZaUyRjmLpMArYpSiFYaPxBCgGZXnFDQdlhmotShYxAVWXYlazzsgyHdkESjkcDNZyZZyBKAvcvQqfJLYmTnWGOyPNolqDqTTNTbLtJmkMWZrtUubSkHYKorwygoctTXPjdqlSkLKcUvVUQnlGrRUPErFWDwWgjHQMuazShbRbrxVLpMepUzedVKEYWyLBHZloRrzFaIUhfXKmsgRErpGJMjCGkcCArPAdzNVfaQdjfhTXOrYXLjEIANYpQjDEgLaLzxlkFRUXyAqLkMipxSCyUNfEjzXwuXJbdMrCCQUUfQZFWWmAatseObvexRfUDkPVEIekwueTuCHIrepLRNPWRvInVrsKuejFQtCYSmhoxAyamJESKtCYpnfsycAbCNCbJUGMxfBbxptcDoqXfhuvUrCRrJQJzodViEwdyRringowDWRaMNRJfWqBhNdEjgYqMzxCCChDWfkgyBXFljTWzjwvNoxHnESHeMVHDBmQenlIosWIMQilcauZbFZATLSRmjiJiUvNnEiwwLtqnqPyNnRBYXhFXhBNHcAValWJcqCOPtkBVXAfCWkoMrdgHYbLsWfUraiCyWrDNJgLmUVWpHUnmSAvVlEKOqxYqsmspzlGIOpQeEpmrVrMTPcnbqkpJvbAVvygenbGNlmXByenApnZBtCCXswlHjXyvRhHkCgPfwrZhazvygZMLSfupSLaoRXqzpJlGENzvloCFRIlTPlzBwXaeIuhqmVHdbmzyliZIVroGcvONaBSUiNUrAhNuWigbVtJglUPhYLOiNAgwCrbaERyvxgcCtWbgurIswCizYwQIwVbWhtASoTVdbyZKEhYBArYDTskIGAXhdhjpTlODmidIqWIahqWWslJSZAOvklIZCGYwLtAqKYoHjnOAEQMLWZNVFTKyXvBlcJatmHXYnxXbLQCngabpuJPaluhobWqlHsBsahJcqUxgKABEqpmXtsMbUrCdNodVgnqmNNmOoEOOStoFCZExPtFOomjQPpcQIeQjpnrwVFhWpyyneuILvsAjsmtCbtdznctOxospbBDQQhqVvgKIIFEKlSgTjqSmVJnPMgaEERiiiAlyEjlqISPjDxXAchPVEltCbaYRUDjfKBIiOZJaXdbKnAWkPtzQbgvzfGkQVqkjDuDXPESoxTMTvppsurfrnZAFkqZErffvpzkEPiwrIqSWJelydkctzQQPVtjlWadwoKramRUgOhznEABddNSPhCijVCqkiCDTwatBzApqeWKQklBBFJbCmbwOhunUbkQSJqJrnltJliIiRzz" + } + }, + "ProposalBase": { + "id": "30", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "257" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "aVOvuSkuXU", + "description": "sfxVWHdImIQozgplnkSNFtWQTyvVgPkRiKepvhSZfeHcsdoKGfdFqsDThSNvmYMnXbzzHDQrcfVZoHYJVESNCWGXQpugcNYBldfZ", + "recipient": "cosmos1waql7pehyspkf8l9q04gt508c0khx0nt64jsxj", + "amount": [ + { + "denom": "stake", + "amount": "598671584082" + } + ] + } + }, + "ProposalBase": { + "id": "31", + "status": "Rejected", + "final_tally_result": { + "yes": "24914473521", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "244" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "hVaLhkXVmCRkbDgBgSFKaYKqXKJLhiYbMnlOCQddqtStsnkPNjlcyeaTTWXsCFkPObhFvrDniFlDimEkNnqojnYvXiyvOVuuFmQCTcAyLlOsncrKgWGPDIPpfAMaDmFfOzXPcmgpFORe", + "description": "jTjaZCkBxMNfRtcYEVgVUdmgiWMiFBeWXaIKCwRuykYdFmRHNiznNgFTPHMcKpRqlJdupUFdMPrPKqKBfSMqpKYsFkuBChuitfPVRvAcOfndAhjldqCyPIseVvvEDFCOQVqhkIWuETvdvvaQtKhLuaxkcLElONPUuSWGbHltDXuuQMnOOTWnRxAGVjBrPsguNcEBnQDSSJoxRwkJaeZNbxZHYmkPVKsslytEyNqkENoWZJfzeRvzyJykkEQjMXrPkfQLyFnsrbhsiTqytKNUFQrNTXBSnlLgThiPMMAljUfJEHKhqQaaABZjInJsnhZxkHUBYKqioLAcBNRKtnAgBdFDILqBUoIZGxkYnuAfHmDggMjOvZXrmPSOwPcpFltcejgOVYAmBfIfUJeDalCZdfNpuspBdFmZdwPuAZfaOIouZLVRheTnMgZodxzOMsBqsYbgrCmwLNobHTcQcQhNhnGzxBLekjCUGNhGZCTiRSyMNauyzwkQYnbpjyVzoaMjBxVaBuiCoESbvzXlwrrjPnOerGVTburUEdLgtgwkVDlguFvnNRqnstfznqACbLGIiqjwBfrfzpCRovteyllNeWARCsyxcRGGMlVPQeYaJOXYlqIHxAfUXxxmwnTPMmRonEiCzWjVWjQscruXUavoloumzUntPtymEJjFZCiCpVBJiRCVlmNLoCHsYbVdryMrOleLyxnKQeRPihmcCUsFcObFOGBFHqzMdWQYPcLnssQBdChIrAjGPsiQlOaobzkhbPOrCkYEjIfAqTwdxqbYdZkDEWGfLhraaXuXEFqGxhgPuNfTaSxoDWPWXHZjKyfcAFurQvYjMDmPgwBYQtQmTiUlykfsiUaFjXxkZQDPvNiFzljHRFztosDTmqxLyLUURvVBRAfxIDedSeUUFpBnCdlbTFXlSVJhzaTzaPKAaBLDVyTAXPVQphTqTzOKbHKtSkbvhFUhiGKbuPSZrlOCOEZwLgpBRblFUrQsyBTPCmPryvpHiuGZjTEotfwJxqIaPOOPUkAQExYZiALfpcgFMgjNJyDfNVwEBSoaUtWfhLxcTbUYEwzBojoQksNfTRwZRxzbnzFFQMtSBAObSbJvOLHiOelzPBuPVuQfzVYUDYJJQYenivyFgjktfJYlzbUnxFCOgNhnjwofvhLVyhxxvtnWOyXXMlTyHmjXPxYyubduEmunwnqUPDKkKJuzsahMyOmqXNRLHBZoJlVERDiWFRhfvCtmIqEJnmTyKisDxQZZUAsUZyobxJczJFXwUqUCoTbgpRxoLutAUVwEQmVuXObqXnCxpHiExqDEXYHUeDyNqhimUZHuVvpLNeLvKGSVmCaMWSDbZxWHLuHAuPfrvcxvPwwaREugannGCKABFWoQjcLgfgVQSsvIYNhGVILSePKwdYlHOcYCYcGiMowzlEsTElBeYSxSOYjTQwLomqYUHxoYhVQUgtMZbwNAiyHJmOqrLNKYkzPAioWvFXqGKdQFDFusgAvDiVgqmqEdTUBOZEQXySwksCAjQgrOzeQVKGNNJLQDOGSLBfzrEhQKdQXIIRUCYiwOGCzMNCIRogaLFQhOqjfQsKiGDnkQocaOJfTktyxOxdMJmQffjQVWEDIbTFrycgCbfJiOtMPjdbaceGhphNRugKkYaMeYwbHlcBpeYORqzEnGwJHeADagrgsfrXncDpEpmxlqloiFgDMdEMvMWWMwwEhbokXWbrrUuoQPzXkSaHWVWVNDAHfFnMCXlzfrclKqgxHDeNQuISUpymIxxfHKDLuZsmcrnQMPGJRRmdXkTqYluKsGcuCkhfoYOSQwzUHOBNfjTFCUEHjblogpjCThafyQdtMdyrjiCYMMNLXmbxTtrFidvwzLtDaFSasDcWoTlwvlDMEHNiyaktbrgMAHPCQitrMKtdZyAodiEtUsPDHQywPQIqGXXDUHYelWccxCpPecAVEcDMDpvzguLLEUvSDTEQAQgKVvUJKYICxDCKoOdFSeoOSbInOvtlwDNcuoRSdxkWLOkqDCRyJqvnSxBySrYxqNmYVCWlBAXVKaBIvUBAbuYjjYtnybxzUYWRmFEYRSkKMrEGpqxZYvvhqBmRbiZnInqIcJmNXCCYdumKKkCpwiyLEdrSaeMIECXZciAActPAQFkmgREXuEmAmpavREizIssHxlUEdljDRgQXyMvLJUNlNrRiEwPKYsSPNwefNHYJooGVsquTuDksXhOxynfreDLikBVKtbPDosatpTSCLcxLlZkeRkgPIemTvteWiepCMywtYOJJdYfRMvEmQOrTSHVNzsPQwUPtaytJmCwzzGFtnxATtQdjtCEjqAxwHMPYtsUpWXrflChTPuqaERLxfixjBtgeIWGMVehgFrcjJKWJEdwQVRxpGRUaHqoUhcFnnvSEpdvjhcxfRkWIygfNUATgxfdLogCicRBbySmXXcxbzqTISwFiJiVsgKlUAcqBisKzDbVKvbmOkJyuWQLzKpFSJuGhiAtavSSEWJFlzGqOdixZCcFdZXXXGsbatHeetRIaFucfgEdZMZgcWAGSYXqnkodRmjndDaYFrhzAGLdsyYxiQFFOkeGfcGxXLToemYfHaSLgNkXZSecVpCOmXTITXEQDLyPsaSdVrJtZzgFZihCFtkQwFBZKiRDyvKZHXEddBCBbrbNqqdHsfRVDhERIMBGWAKQgGSIKezDbGxGAiGZrfyXTeJEQBJIobkWVsdelEYIDQNWaILymOwziefKaTXExKbMSdbiOqtZvEKwyfhFuCAtAkmHVuCfhdMOawyHlcLSzpoAiBqDtSSKwLdIGJCiNOYwEebRxqSsVQwpdmQBmPUCMqaSCozFoBSuNDPkrBlrLQRTEdFcgaVTeXzHwkfszmLBwzhMVzMXCxtAnlnKoxPIpONEsjzYAiUifxNZqzWGRjAInkMvXLWxXLWJpBAJVBWQZNBnVUyCzwLqPyNbvoCVYTXiEBBiEUBnHTqHXElYGUhxrbmLWksucavrDGCbxpbfDEIoeOXxRSOmjHfglQWwwVYyKbxBevengxzikloGVbIkUeSklSMerLJQzTSoxqxizQpXMjlqEjLFWQRaLogiQCwOFOydYpJpXrneBMRsZYXQVBiAAnFfUynIzumMTfehvgTUXqKkUOCimsCorQWfSxxqjmTAZQylBHpQoUdCOJmbWZxwbVXYiWXYgMAhUKgfitKQhFhPuJMROCvTISsRcudfXPuwvUIHmfHmdOrDYxzQpFnSZKMUnwkgDaqOTYeoMEVQxNzBTZopYtdaXQdgznvEvAmmvWfEPUOuoiHGpkyayKoQxbaHtKoidyCdHXiBJzrFgTNirshXysGUfvKLHDVidQIXkRmriUqDZuntTtFRFpVCbRFVIpBZLNNbYiMuAbTggclVNxWJSDjesHeTuPLucQzRJDLoAgtkAXhUqJaXhSBkuywjbOdLzFFHbSmtdQkFvLioQWtRVTqtHKPONAgEQRxdjRVMUioFhAUHHmaNQfdqMMfNlJclTyKTPIrxIrfyIOZEPhpOFINFycrhcKGfTEtCKphLHzMGFacuPxxVgsqfkhyobfodnZxlyweGJerQGfuFJFAmiWFLJFWsnIOeBLkmWPqHtgwLOKRoUEGLAZYlzZautjTjtkdnesJKcUtcREnXfbNpXyWxQRxZgWsgSydNevGKMpnpSaRvDRFfsPHHiGzBxTOwdjzuzQtfIwWTHMdPuMGuyWfzEnZWKbaJdMVCMyonOowIveYAqJYFVkIhdSzapofFoINhBdHVdRqNfxjHroXeUjjfVHpPpZMOQrqrTrJMhuPvrrTrzPwDCsndDTdjCLSPvLWcEAYwpMEyemaMPMhJoLgluGoBvGmmhNoWGxzNSIvvctfTgCMSmIuwnTSHYyRAcUKTiOUIZUQjwaFpnMmHnBpbOyWLnvGftExTaltsmpcRXlJLhoCKzmNwfgqhsVKJobqRmlECcHANstwVqohsSrgSCeQLgIfCtoFtbPVqANXmwimOhJpzAnEryfLWLAYqcgfeCVGLwzFoxkxRNrquqfLrgAHWkcNMmhbvDhjPOqOtHsAFAHFgLEgyPgqlaauFsEdfJpRcbHFrvWvwMEqBTYheReOwXXuwLKMusmeZxxeecFGJXxZVlHhBqZuRmrlBxnCoYifaOcxDeVqSaQzntoxVUENyoovsglzrJqkOhYxvJmxhGComEfMeUdgLZCXQPiOYtAAbStjoQFAfkFavFgUZBtMdyaJkAcewuSjidmSipItGebSpIkLkmxnWBZjvtJVISTWFfOWByqCFCkEuGzljGhziNXasIvVtrdPtuOyqyTnnZgLypGfdDYDmoasdgWiAyytCalQEAAgcymwWekMziuNzsWkEgWNXEhcuyQxAjpQLLPboCTaTexdLOJijUsXMzzFThTNzbbDMyGhQmqbHUBlFKNBHrrCPLcmkGoJOtpoeFyFaaGDcdElWWdPckOJXtyEKRmjsJMEqOUKePthumJoBwHZJibflaWZdFSFrwUYPlmDuCxtsFSEfYDsRTkLJUxOQTYSdMNarnVePUmGhMIrxPfARsdRXBlXuDiOQIfkfijaLwiCsOhvVrHTXBrAbYjDRHNIdIRDMvqiNRAdkjCsVRoINZAThRhBINfjoSvLrUQLOUCODBxtlZLmZfFuvoczMUHvcsxQfmKTXeVoVtlfXNSWZibDQOcPBJAyYwxHZhnXocddZJGPGkgobcANCaWpVXDPBKuWFOIkrwIXiIPecLcbpPSjmhIDlNPtOiHCzYBFnwUjXAqpZfpwaCsZqlDCUiJAbRgJDBDUBCLWGLEwPAbwJkLcoXjYmJDTMDwIdOJwpDNMNgAJpxkkcYdJqBejcsUWzbTaSPEHEooCCaFRHbUCryWIZTeKUzEhqjloSjFGlxOlWmeuTndOmAqHIvZAUQTliBoNOhqRREKZbEvRjaTLYEzzIqdcHSjkzddjgvuuUNkHITGpQaCdbJJIcebZRJJH" + } + }, + "ProposalBase": { + "id": "32", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "256" + } + ], + "voting_start_time": "9935-12-31T16:20:47Z", + "voting_end_time": "9936-01-03T19:39:45Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "uKIxCIZaezWMpEldIjAXerdEctvoAPYUlNigsOAALJzGEzbYsXIpyumKPrfnJwOyQzkHMcojdUSmOvrXBXZPXJNNUvDxWWVkrcVSPokLsACmHFdtRdjcPBTtzMEJGgdDwgqKqmKVyyXs", + "description": "sStOsEQSjEVkZrlpKWMTHNOQgnlvHWntzBAIVwiyQwKqkvcPPFXWjBtisiobVfhJkfRBvQAORlhJAbjKyWIsThGNFJjVKzPEQivVfhYASSfPaoAfPzVOHsGRPuKQiSLNEWLlDnccOATYiCnfhKpmMHyGshFGqIPWUbyRxGbQbCuJADpgNRyuEeLcRiOZyvEqVGEnkmkwKnNewsfNtfHcuWCfnHeHElIRCNjDlxqpuawlrYmyesAMydytBMNvXDCTfSrqeSOThjjdqpwvWqxfbEwWTSzYRMSObdCeGIdNOfjbOmcHEVzFpKgsFnynSJrMNzbXfPhWtHLFSakamMhLSAkSBskADgskMaKqFqfkHsWXJDBtyaHypuRmYgeEPmBRzlCLojZDvVgjCvHpiUlRLIlGEKEHncINHEApIrngygNbVFnYTFtoCvKufVgPANsWyVPkWHwvgZmEcIjbIlBuRPRiHYVGLvCPWyAcEGGtJIfYEONQDvvsUXxtsgomDNxSpXSAbrfjKDWXXerlBVZVgzovqAVtSmYUuSvfVlDNPBLtVNOhtRRatIHbbuDmnNyrlwFwqczvQmIkjOINfCuebfFRpTqZZDcnsaXCSuwBLKvagmutaybIJLVFZMWlXSpmqzaedLMuaDmqRLcUOxZhaHbXBAYItPGNpjtNnjaGngkLsjndiaDwvLPZAbyWlOtqWBxiNUiSRgQWFtIXKJAMjpqdHhLKfyfAQjQFqzvaFMWsRKHqbjsSrzHanAoZrHmMJDBTsNVXASTERXKAYoRyvVSVzYPQhDHpnJXhQmZQJUbXiGMJohrhsZJcMtljJvowawlexodcFYZiHTetUQWsAlHfQYmfmrKpytiqWFKBXSUKpVQMejmEoVqhuSIwVyotWCuJmCYpIWdgrwiDRmORIqcSRPFYphRmwwklRXBpHxbqgeMeLTcSgLVJTDNepRZIfeHskGJocbnGmSTsSqcYXzTnpukfeHQKHfQvDaKissBoGhAECiWMiNFLDTyUytJOPiFSDtxTrntbpoPiTKveCDNfFRiveExDaJQZstHbncBhGEfPBMIBhBsBmIWzJioZBGSHKmrLiZthZqfoTaxXFNPFIcRSlDoKaHsrQAfdSBdnpaIftCdxqLKDlhpKjNRVSNxVZpbgttfYxGrHnMBVPSvRVTtnukuKRivdjRdIwHMvzLmAHiDeFzPsWPWgWsndIMXaAWUnJDLYxFAbXvvMkWUZRNojrsiFqvmEzphHBRDMPCCBmYLbZGvMYyFHXbpMzZeQSPSqFVfppdLLSycIUKmktWTnAGOiVBuOqRYWqBmTcniXhqPACXmtRmzrcRkzJgbNdSNmLSIsxryJVUpjpAAfqnOxbUYTyJuQACCJTcTHHFbyvvsiLqPevmoBNkKldEHKLXrVlliAncOlbNOLvalekiXbsSvJBxYLbVgbfTivfOmWevzooqPhTZLmGJlIbhokJQMBeWgkeXDDMaxfasCwUdpAwwffcMEwrRiznIHBymeljoNkZZkoxnvOPLhVPZEeqaqoDvsXvDdAQKbZJamRweqnirTVKtFiuCoBcpyegHOTBBVhEMLAbrOrXadhhMNhVMiwGzfalRwySnQFiDxWjcQRJSZduDHvLCOPGYAxiogyxcqZNczfrxLwayyslpONJRxxRHXJYbXigvlUQcPeXknKSbnoPwhuQtaVffhQvvUelEaASMQukkFxFCXvAwLepcpgDDuClAiHPLppSYugTuicoSswDwbJYFROWZYDqbUErphNSmyJXMaYvUZnzYLidCFVgXUIpCxJLGndIvJWAuPJEJcNfpDcFYSjHBMGzQNEjrSxXAEWPyQSUvoaVMIFGvIAOPKlrhyJHVgRwOIAukdSRMrvdFkYXlJeADeTqtQcPAteodEaYTheYnPFCJoXshuncteYUiPIwrRstjIcBiOQKOzlusFSXLkriVvkhEfiizXTyrdvWNBnHMoqwAphGnmwsfASWnhhtuNrwkwoOYcMhlLVhFZBNRNVBFNrPEKPgPVjbkXdaJGYnSbZgJenSUaabOwmPvcUOnVLjjEOCaiyvDmxaemPniOexVZHajtPDxxtpTqWfOQMaKAdMLaXCuujVGEbztfeIoEvatLWKEqosgOSVvItYRzKOSLxxnEvnPQirGDHcrWCXnfGhLKitOHNJFQhMxjSlCxHgIMwCIADtWdUqyFWOCfgRyBBwklZTmlbPMlHOCtxzDySrgIRRKMrrXUQnWXzlxepnXZQyUKxkThKkmmakJBVzJZNONxbFcrptEyyfLxpHLrvidhoVLKnKXReOAMyBJFxlcZEpDEEISajrnobKEngxzuwOEDUgpwiqooQUAdSevWKfWuumrxoynqWDLviCljnVCdlPPRuQhUiHFFcgbqjXIpfYgOBmMcHHKGjLPaqOBfpNzUwLXxQiFcQEggXaUDsMAEkrcxhYOSgiAtgsKiQDgtRuHFAGDVnNTuLswhrgZGUvLCaIKPBZzbQAnPBDRxeCDHfuwXfshyKEdaAbeCJKjiuOVIdHKpNXUOpIuViQAIgGlkzObaMIhlMYiOwPxnsyVGbCaLksZeAYLLqZsVbeSWikgcwWYlgAJRDNjHvRJRkOKbeepfCTtumjjZgeRauuyfCJWylQSSCZtqXvgFVQZolRyzcjbVWpmrTSvxUkgnLaltFinaIdtTficackDOjPhUxftIuXYUDjZIInAiHsVfkYWbxlZydjHxUFNIcraaoTCwhOCUZibgBsewCObmGmbLnEgXfhgUUdGKlubCzSMqrXOrgyVqWrEveGlqwQTfrDdfVnPaGgGTligknjzFDywlEbmLpMWHCgMhDKhcfomVvfMhUETSzrsfSrbHUlGDIPxFUnozCMOoRjiiwEeFSRPyJWHHhiqOESbqUXCoTdeUYshOmsIAmQlbHJXaQFrSkPnkNDnHnUYEoLmlvnrgYvYGKmJjWsBZCYOOVZIlkIiKgCyhSKSPJZcrYKSPWFGrmSNOVmFSRqlnzLNzFyDpilKNJkuXqAfeUyZxWSduWWPXCrEJlyeHnZCMLoUAbHEfchEDwWsXVFKsUhkFUpzDyXSrzpaHrkAtGGSYFRCDPkUGMrnULeTzNeHJchXwOIZYWMWnMlIIKFxACovrZoNLPBHfUNuzCQHqBTGFPYgaGolTTmkCBWBPpQShAUtGwuFXXZscaVgYsKtiAemDuoWePpCnFgmeMJuBeGrbbjoFTwhSLwaXgyOtQQrztvlmfszdnnhuPjbqxaBUPCnojCxldhttNGJIgeFXjDVdNVgzyvzUfkVPwUWZFOKxRTMCgJykkvWneYKFHixfZtITtsHRmOlDQiailMfTdKRlWSLBHAnjxUubKBWshkJPkVTQfKcgJzBeqNHEGqAhNMkRvMaKQYIGfvnhGdXmZUituYAzAOhxDOaUyqpMkGuzbwWnnyXLRBMPMLeohoHsQWxCtvCTGCZPOKEIdcnoCLglBZmOclmgIRjZFJIlpRiewbmBDFTQPYscSJENLcSyWtPkalZgyvXMLsuqiNGTmiLnDdjixOLOktOwNyOEzdfumCtgJHPJCVgeBzVrKFdxMyudQTIOkBbOFGxHzBNoxMiHnStuIoUkpyLhRbSVOevlIkfsuRyLjvacjrDeJCpckSYWJpiqHCOUmqdmuVfuYtjnjEOYmTnWXKkFUPooIAOyoWYCTkKYJcwtRTXuxyUvwhMqIANzEHJSqFyuHedpbptmWgENQEyhYKJDDEcBGVVnFYbnxjgcKDjxRrOXeIcKXImsimSInMKvcjtMMVUzfKvDpHaBKiouvSokHzhVGjUZaijAnLoYvFHkVwXUPWGFfdzBjwtSugLCfmxwPfsJQQNfnvQVDuHwtOEPdvaEMuOhBPdxkSucMKShUGgHBJkCXEIRVoGsyrvUbECnoEFSxWyYGeMkqZtIVqNkcffOBpbcCYCQQolUAdRBFzesbRIvyTVUZCLzJQGEhqZMZBNcAbfXQbKbXwIaYEtKXAcvEuZxIEApCIeaqRHCcrcSsAWkzRiUvSJloOLZLfrYMtqCeykyXNXHlyavcusJyovjxiJLqlRNLRmFzUziQNaHrygRiKyVmigsiNlKNjawXmTFbDahwTNYhIPWQxDznAoVnTbhDdXjQzkyPMhtfnVGUgCPutMbrLClwXtZRNYaOKItNVeVGAfNyiluJzTKgsvvMQyfsZxWStrlSXxjVwRQmBFVzEFxSbeTmyuegMYDeVmQcswRPBcTEUlpcdWOomnuoojYJjGtlQxaSsVxXqJmOWKILrIjxUWDYAvbGmcDKBpnQHCJNEyBIYixYdRJIvZuLKSVTNuTdkwVchKwhvzlXumtMMIpCMBvRQBgGFBcSOFbVQCTXzPPLrIENjNjJKqcJtVifAFIiiEdEwdpSRHdXHznvPnFsJUgnrwPTmmQVMFXsjMIMxOoOsGZEkvSozpwjjyyBjXqKUONBllhtFRrchxIInOyekemBYEgnZZRpwylWxcKVCquqaOneqRJCJMofFrcoDvGJrOczZmqnfLuEedVQDWnedLGxaAVlqVVIqhqyPYyKWRHlFfQbXonpsosWboiCtKYyvOLjTfQNOgODYxuHPEwwqDcJbhrEHVEVTxzkOjjvqnDWJwxrQDOQrfwLxJJBlEfoWtrUDBDwMnZyVjZxjbejxjCLSXBzcDHKUJyFhJhaZfatZaNOCQbNsifLEsnkbvOkaNItVKhgwfjDbfthFalXfsRpjCPxJkwjxVGTIUGsBVasWzDBxxMvjBkYMwybIfFxISxVxGUttNUIqlETmOfjhPPnbBmnFeOBRFuGyLmwdmwmFufFRuYkAHghWVtapXFZXSftbTVQmnTnftDrwHgeNasmIhAzjFeELgmNMPXnyOjvtidrWqjrVkXCudWvVKKQmjDLdPcujHDpRCOOeSzLOqrAwXMBpUzqCSYPfMqNUxkPLIQGNijFvYIAdeIhmklKampfmxTMJqlR" + } + }, + "ProposalBase": { + "id": "33", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T16:20:47Z", + "deposit_end_time": "9936-01-01T04:39:05Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "240" + } + ], + "voting_start_time": "9935-12-31T21:25:29Z", + "voting_end_time": "9936-01-04T00:44:27Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "ePBtUGbretHtAJKGwKyIIYsDsliWnyjRKoyCByxEbEfJUACjRyoriStIcsHCGGxbHRdHcgpRAhWIAQVuOJFXgfusTuWkzAcvxeEdXAlyqGjKIKfqiGGwmumzrOvkblnPdxCKjyzulpJY", + "description": "VLByaWYvLPoFvpoARWSIYeZRrdzUajAWCsUVTuLJKnUxjXXfcdqfldQSSJribsKzxpppYxFDufjzrwTCyaBhMSeLeGaLyUqPgijNmtnGMyyouhJCEyNOQSIblZDzrMfJJfjIpqUsmvoloBuSnbuYJuDzyFVtmMjsqaOzhZvLUfCtlgisvMFVrCPPEqEZXXFemtKVZimbVbdWJsfFqCOUcPVdypaOhqdYhdXVJsEdYyyuBhBOPkTPinkQaQLYUnxPKqrEAKmUSxTLMmrmZzjbVYDRQTotIvGiMmNvwGxjqcTLCNZLWYOtUoNptxxJiFpiqKpMfRocDfBJOSwwLbFAFjjhTCsFwKnhNhOeeLiKEnnZydlYkSDyQaihGkpOiWxtXmqOODouTlhuAfKoyOfsmSMxseUWrgxOwHeaWSSOkSHsaNSQQUIUpDgMokeIhwMYvtMUHahGfbbtCUzewikdPLYRONWqroPGntSRxcOgDduMyzbchjTUausdNRLpShDZoopIkVVJKrYBgqcTuZZxDCXNBNDqThQoVzwGzNvzFpvjibwXYfXiRIWXMJoTgPOUvuOsFJwHdecOJAGOwhMzflHCEkAmjQLnEQvtaQDxFZCyhvGEaFKnJGYjSSASxFyHuPiqOWvEnqEJGisxJLZaKiTrJLsMwWrMwiMMMdrpHcVpMoATixEetlfBtatUZHgAEkjXhVeEPJyUPIDqSdtbvLFJgABtQWKRdxUPIaMcmOTyRvghGryFgfHSjEgrvVCMwsmkLfdrguiejITudfmiglfMuFCywjnWotcNQRujJKiWIOXGzvgeOnBXHPjWPBUFAjiDaltNQDKwERrHTtwaLGJFbbZNvonsibOAcMNqsYJTJAHDqEdtnePAwJAFmcMkBLHISmntNLwcJLkkAGUZJLYEkVsXIhtjjTXiTqFLbhumyFRDxzZIyjgnXMIkwiIsdPHUBJAsAsNJTMPNZFsYJSwHjkkqLSCtLrEHlBGrjJWhKYtvzvaaGJzFOQqTyUXJCQtAMSnLeINpgSslgcJjYvoMRoJozDSyAdLMcNUOFhizpMumLTuqkTnXCXstSEznUSvkQyhHedYXenIyZtcrfpOtbNWDvoUFaAmhwRIfwBsQuSAcXoaSQQjTbKNScCAIUMfWZvJByuXTLndhUocIEleutLHmsaELtaMgEMsxDJVVpBTHYKGXhnSXUvQbgBlsDLjBMSHZlguWLfhCVcriadrbhdHYgVniTubbzCrDRPeSjwiJsYdxBHxrEUDlnYwnPcerDILMDTwkIedOQQkVbexxXocRGoMSDavrghAalujBEBfXgdOogvzzfEsonfGHWMuKWtAvcLOFCtmpoqlIcajpHtpFKHiInkDLlcpnIvnWVITccWDgSySfsmQbFeWDPOroJlnOiSuwwmHEgElozJdBDeOwZKsbVMyMInfXADgAVOwqoKssvHrRQyKuKWDmVIWXFUDDifLzMAQQCMuQyTyTeADmHgVQJyZkmxrddxqqiEwSdknoXLlOIIRjChBIuKzZLnMplFlaOTyOsyvQdCCNAuAAJYgGbsAwDQgAIFwYIaYeUpDRDSlsESfFoEyiWxhKibveIQOTyYGkIVKtywOGTCKxwkobckLIxNUhbPWNIaEqQVnoeCvNHhyRsqSenUYKBvERDHbNSKiBUBLRrAvXErIBNkWEggRRLorCjXNnKkPiiQbzUgeWVAEgaqbavizSLgfCqchFPgVReKogXHoDBzKDmSQvdILNMXUozuCanrexxjZuilZSKDjtEbMUHPwGxzcIsrgoaAZzDkUsCnJuMmMPpmdVwmixswAvhxqzubrHwPfVGYMPqKgzQmvUwanuncUsWTUrsCfLcIohDZHPOPgMdKTSWPEZrXLYQubPskoeXvvkbpYtPUxZIXYxrYKeITIfZuDnFfFsfeSIKFXXiUMdksvmWjDyKvehKZOZcprxUbjsCQEkShYhhZeKbqoIRsvogZvlXRYGhyRBRjqfCBUOTJbmFVnkLxfOuiAKFlpTixvDreGzOlthSApQxYhpgjNsxWiNYECtuXOwoXrlSsymAcQcEbdfHNqdKIkIOFskpuFMTnbUHalFufNQBmswqPLdWQwgvcTdSgMjSDeMesubDpbMMcudeKXkRQbPPkjNBlrwSKvNJpANWxgDzYpeHtideEotpOtlrfbUpshmoaLtaNwNWSvqAoqLXhSqAcxIgAhpCjjQlcuABxnVyaCZNrayQMVjEYEiWReKDXNcORojefCtJjGqahGEexIRdfeRIQbBgCfybHpTnjHMOEaFvNPFkZLfWYmRmlUcySPrizfgpSMrcQRHtrBRYVgXrgVYjSwUSAXepnwSCZPFYSWLRtQaaYBFZHkKJGUAJirzOCUzUZkRROocTXDXlGJMLIUAYjLVOnlucUFWYoWckAdMcIdUtvEWGODdFgLsxKWqbcGWKktUAVkBftKSUbfQRykxTLVxPPTArZisBUOzDucugoKIKFXANOlYprDnUzPNVdpBJcDXbuKcKpDqTKwRdOdOjHmRIondwzUMvtiQbCyOfWApfVCPKSHPuIGOKUAbgjYzCKCIESVVkUGyLphBRauoPsguuavrohsllZzBGtXGKeoVESkxAFQAVgnqaIBpLbKYhIJiqVwufpoFDtzMTTEAyPuWRqVoRQdjsauEBKFFNErseHZFjXrxogJIfSbZsQrfxUaNXGCHvyDGeMIAifNIkGjFDhGcINvFNPENLKcXKCewWVUnqiEqahSqOrVAucrtjJYVrQgTuEGpmuTwHLZzOGWrNmRfHrXJHHafxYakuKKudVieCNxCrHiTzMndzwKdmvjNcRakenHORzTNYCHZxbmeOJvWkiapZawGRgABeMgViIjvalkTvguwQjhWTRYifqxtpBwFqVjcnuwIqgXunzABfBffvMCQwAzLprUEbUMkTsETADuRnRPuxVhWpUpIZaNhayEOfElqbeuTnKIWLanJQKWMKmMAYzarlXnuwWShnKGLFWXYjAuDyDleojyJPhgjWFOGyXExDaYVBLTAazMODnaWvlinWKREPjYhqIBIObhFIufCDQWWCRthrVrYiYVUwodkZsCtcREGcPuwYBeXzGhBTbIXVCXPEpPCFsZaGGTzJNaJvavgeZfGWXqQxyAcGfKNPnrToqCgHlKMgewrAJFVWMKLtxfrZvVJUAkjMDwhJCdKDcEzzdneTStjqxMSpLfdqIxDqMiJJBGolsqlCjnArAPUSJmLBEfcRuLTbHjkDXhGcRWBVYdaxdxMJsEIsXwBuodxqAWnYZnNWbtJJXgZVmyIZAZVQDxTQWDbZeqJNVrqmCtNJIhiZngexvgywXzNhWFJaKMxHrLWqtFfWGMhQSYfsBvTWnuLwYMrYnOSfjLzHipqEWZQjWYfEIRGVIEaQeZBJAJuxHxYszLxonqjOKGWHuyGGYMwrSVCrRiNBqnVlzASWPapuobunoXChUeYApkQnYqiEkUxYKBYAoCTlKBjhqAuXAmKlDneHgSIMvqNiENYoDpVQdRrswPgoKBbQpOqBioMcXFabFnToWQwSAgmdWvJuERPGoYTUFqFTwQTsrnvhxLmgSKAmjtyHmBhPBfthyyplrcPnyzakPoKvdKqVaYPtturBzYlfGxPZbGMcKORVtLRGQRxCyltnSkhuwnVoKnkXUAGAOwvwBJYYRkndbrgvzAsgjqwoGzuNGJMzSCzDjySQdCHbiPbtJKMdbilTjPSiYoMfOkqJibETwMTbZUkWWSEtdLhbLlRIrneszAiewlpVfGUHtTWEYepesRbeNmAhcUFcBIWuPJCNTyWRSndjQasTQgeowbySVDNLSYNCgBmspsIrcbXLXggOxqpkOOBdZrQcFgfTxASCLQVZgHWklWzRsstxsJpSQgUNOKBqWLyEdeFKvhreHPoBDvuZCTsRTGmyWOPvOIniwgivJFyehAljbpJXmalpMGlfSZtrDvEtcSqjkVbdzjQqMUVuyzWhoNoBKFSjlWulzKwBnyqSglwMLWtYQvqaHPUlytdLrOPWdujqXooGUcyIxtcAuUeUyfnESJcNFqgTsixMqsdbBIZrQkWxyNGBbTdyjFFOAJOvsmsGYZaAzFJkxaakXzZyrdjoBohsptqHaGfSSIEqAFXSaLPaFsFHlmylUzncuhdlNUaZekzdopHJbYptztTuIULGYTtJcqzSYmngptDTwuEATbOrFvWJcBNPEUdiskRABAbdVsZnHDGwMpGbQxAFSuRyljroAAeKWXzcnpYawTRfkHdJEndZBkGZNBmTGcOYpNoNktPqfFdHbhYJgXVsyBcbbeeSuCjDmyWznIemoLmlsZDqwKhMIlMJOkRqtPxNfIDuOnfjmDiJHNWNtexXdOGXeYEHueUAgtjWKlUWtsyfdqJIKQqDQKGKelvkMJhOhekaksLnmyIRAZSjbMUDZHyQeYaycoeMeTMmNigGuBNdiQSPwrIPgTJFYVlLuhvHPzuzAlZozHBqTBwYJnDIOfczpvwnPtqIlVhCRPpCmLRxItlCsNVZpbYJAYGmBBUUBfOZNkkzpptlSbkHqSZzcGqKOKCRXcNHBMEAuxSRIncKebghpKfHQEKrtklRrSFmtTSCxFFUVVNLZdysJrbrSDwadayxjkheSovNdaILsRJhhXWgJAPebpNmsueBDdfPmSUxYXWrSlmQIlyXwZAkdScPFaeVwzdXZJlHAVWkryMFxvrtGZRSgKtgYUKCMPIKucGKyklpYQNXrsSGCbDtmrmYargXgHcANTerSNXUWhAEkhcVSsOZjSzTmwnEotawmcuhTIPjbQmPuTMaEiVaYCFaYsibMDZSJBoUQUKePxipTtrHMcdBBFCTzZjpYshOOWWVJgEBpuGzzdrDoXOxchbHNwPHdCfOjRGZnWgepYyJdTFhNusupWydJdsxUwxciAdpqJofrwswPAmHzWBkuxcJtqTYKdQZWOXeIbfyhZcwHSN", + "changes": [ + { + "subspace": "staking", + "key": "MaxValidators", + "value": "206" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"11\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"18\"" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"167\"" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.700000000000000000\"" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"8\"" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "distribution", + "key": "communitytax", + "value": "\"0.030000000000000000\"" + }, + { + "subspace": "mint", + "key": "GoalBonded", + "value": "\"0.670000000000000000\"" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"441969000000000\"" + } + ] + } + }, + "ProposalBase": { + "id": "34", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24914473521" + }, + "submit_time": "9935-12-31T19:49:14Z", + "deposit_end_time": "9936-01-01T08:07:32Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "346" + } + ], + "voting_start_time": "9935-12-31T21:25:29Z", + "voting_end_time": "9936-01-04T00:44:27Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "XQXTYSCRDtfMZkwkDXoogrsCLMVXYioEWGhAVtdwDjBIedXunPCYzFDGEZjVojUrdsLrdEfxAKaHHxGEZHiLRbrJyqtsIcuBkVWkXBBTCRnxfxQXvGJCzOkXxsjVxdPcRcvMzRnPaxgN", + "description": "sDQTatnsqifTpuokqGiPbEGCzVJGbdpswSfbWlHEobbpQkQpLGoLpqczKXaVbEEsqmymspwjYanOIEabuLkUuHNnAQqyxmdwigbJTUbtoXoKapZHGJdIVDoZkhsVyiZYzPIYtlFdHraBprWQnAjsmFqVvkEytXfZVcWfONiMvVeWIZmBRPDNsAZvMCEqBRBLTUXeiUZFwUzuZdTNjzZvNYfAEuydpEZdJdSvABSMaCoYSuAFbVLJIaTLsHpjMjSXzZlOYYZegIAZicqlpWkNJYEkvWwtuKggxUluzsbVqKPLmMvfEUXkAmuEXZkESFQjrQtRyEckpmqNlqzWnLYmpScEOkbhwJDTiTZkIhlTWZaibxdWagXIAkUXzuPSrqqDnEUVCKBxPoIOHSwwBYwmkWjbBxGNhSgRgdPQBWQtuXLMpzRVOrAsLaqhCiwPTrQgtyfSIcICWmWKhiONVGZwvzePSpcOzopZENesryUtuiYiyBqdTcLvhUxiqWDcBnNesZcOPOnnnRCfFyBiOqoSdBOSJhvTbELOGsXBZOTUniXzNZHTrChWjWchYXdcZGjTJdeyyzXXPZyVXLjDUvqMvWwTCbLKDiRZJFCIXTgcnsKpEvelInwebntobjDItkJjKvSwZiDqZkeEexowyKEUESmkAFRkJDFbrbHZnkrSYaRPNMEkjGLQSaEZEseJLFVbQjIIaMTpBuGZXjJIwyMiDsltAuQgLAiwjWDrjdJIxHdrhJBWIxbTymWvTIegELKCsUxDqPVFbSkfHjoAHOGcgRdSbztTMlbRKfZQjopfqhfmDBasyFCXbRpxuhcpYbAykmNMzLsUAGZwiYGvruAXxfhgesZafPkHeONQXlcHOBMzIAslyHZwQTFXVnnwNADoNyjeWAnjEWJMbufaElbhUFjpqgsumBCXaAoRZisKHxNGXzUOPZsqMoBmtvGjSNwWbqsbjwvzeQAqpRIrDVBCKoxHFNUuBFLMxVWuHBcIdpeoeSpKyjTZALqDBHRcBzIPqVENiwZOaHIOJNzNykwPYHNfkIQZAyPxidBgZGohUMWlJYLJxdVKqshCdwFQVaHBPQdRLprIKUaZHYcHPKWGvZCYMixnzpqrlCQKoIzkflgVavwtCQfXHpIlyoTsOlClTEDgtfWXATnoLRgCFuizybKHgguECYFLclfIbDwFXVuLcXFfVRzLTFNYBVeXswcZddeAAXLTErNCBRWCSmFrjBHMvERwWBnDdIUADiaUSFcPLiwZVeozSgvUvWnvnwdpzGxiIFHiYtrBBHIahPBNQiEDnsjUyhxtofCjWTssJiWCGJguxZPBMAFREGSThzxNdbYzRnQQPpDKChxYmknoHWRhUUtqKzBpiFtNRmAwuAnxLJMSluMJsyWqVKPmDiBKczjTfwoCIfdAahlFIoIlkGQXuiZqxDrkqAqwFBSOfOzkjBOSZwzBHYdFIMpRjIgFdnGYEwMjljMTfqyDiSFTJpEsbPIaLsaUVxyBaxfdzKxAvFGUizirWjeMfqLdpIPmRcuFJzqzRPwFAaIKAdiKfDcLnWcUeKfoQelaTnqzdWCHaBSTUVeJctFxaOnfbvIBSSqRAeiARUFjFnSMVDsLdoliRBOsdUKqCBynsZzUxjhTdGFYDajuZQmwRTmhZrdDQALRlQDiSlGwyPYGQYJyzaexMahRhPROCKvyJJPxxJGuvAbfDkuEhIrjHqBRmRPqqjvLCzaWXOUpoIQwOVZLktOVNNndWjIAQutVvPFtfeEAbtMObIUmEfiXoQqEDuzfePRZYUoibTfqrILTQkQnbadGYHMymstpUQBlgGuVsUZNLktBavoXaQdwEiRcNksmDcMLWtKJUyWhpnlLyCRbnqQUgXETmFXeQPYDVkVXSqWJuWFcAsIAWhtXMqdiciPIKHWXEeJFNAWGAnbGtPTkHfooXAhGnQeHnbWWrrCFKDCHCdRMHBLTcSbmEmEgduXePuwfUEhpLOoGKnszJpWtkSRKJjmnYMxmWjCntYPyYGmDFetGytNWPFiBarLFMpdlRcKusfMxogojarZdypgsoNVRECqGogAVcMbgEBFXrWJciaRBtvKgtoSRMkdCjzgiJVESELjPQneAdWNscSFKewJiOBWLHvXwUEWKMpFEhgPwyWAeEhuRNdnzUtmzeIZbSkgOjslqCeOYjlyBBkPSXwNThaMqFUzoMpYYBTyZXBMKCtHSpoyeVpZHZJFKpFsxNQFZWPMWcwaeldhqLuwZxOxHavISepvAEnTExRRVtBHwXcTRNUDZNeSGcxcIQdLfRPnOvsZvznjyLfyNqvhPOAPVPrSULFEBigZtVzbYcYvnZzKhPHVvlEFiORZPbYkYtsCIZUsHVoLyCRuIKALMvFoaoKLGmsMwWRQgrnafKxpzDhEfkUHuYSlYLhHUvsMAsLGPVrhZueQwKFvqjPjgUnZpuiAvshzdpUOdTsrqwEDAmlejqREnFVEDMrFvxFXcQSKsGeNDecMUocZbdetXnDGqDGfdfdpbdqmWXySNMdhxqSslAnjjAfACEflIteIzsaDogTaAOJuUiiJTcHKEmHSvdMHAHufOQsSccTpnXnNcqsXDflbNwVRFXrtyXNKTrkkrHsjBQZnTxSAiQVPsaTuJxPlegYdMTefKQFSwKJRSKPwRvsPMGSadTamPXsRsJzuDkvjxydimMZniWLiwTJdNMSfNhAPTgYLHkLBgRQYZwkjgWzQAxGuijsvrPBQBdoXhedUnxnFkZgubzMjWbQBiTUYqMTCjcGeZprFIxetRzuogIozzZqgntXmrYRFNrZhkvFIVQHduvDAzgnRNUrBPIDTOxRrUaWEHeDxoSpxHiRvhsxRIfBzyMsetHPkrAIIbgOMJDIOrZvJhpzKjINuNJSkhFmZuFLdeJUDoYcuPKeHAZjpZmDCZUbsZROcYsqLgORUhkJtZFJnkBsrNyYGiabOaqFFgaUKBQVEClzDZNWXHFKSLFUCxyPWKnbSGXzNnOJuDHDohvzIBkVwuWkVyLGDCidbrkjtkKMpJSmcrjWPYnfTkBtnhjaOrZvjevUrqYsMqqdJmsbPAnEJwHTEbDvdPPAknYaqEYmxHEjRKdEOWuWtiRNLjyGwtHnimIRwcKIIOBzzwdWJLJvcqZXxFBTzjDjqRZDviIciNJTrHEjolDNGtnLjGpAgBDGoLxuEtDGYCeNWcCBPFlxqznMrLIlWviaPGCWvelMgeATWVUfwYPiBUaTKkketQcyVfOUZiRmDqynhWttLEBmLYtDRhdUaNbitMsJsTKEOuEqqyJgVvLgoUOmXIacuEXbHIrjCGJyUmByUVzykTgiypZiXFalWUjcMGlnrwUaKQWVGEQHnjTiOiPEyRkalwOVkxCHCBSmvSAAjSPkZoBIsdtUkNryZbRWrjGaaeomPXeXNIJTKmNxRkGoewOZhIrdUVFKqKGYtcUPmBcrJkqeqARIQAiwAGILShggvffQWdIGlTZqwYyJRBJssAPyNhjeYQHrinNeKmFZdHMxTFpZbOgpcoPZSMGucTSIaKkmYzTUEcQlsEIpDppyFhDzwZPvQzfZAgpqHfajicwoIwkGKZjtDechxycOYsYgVsoQMPtsmXoPQAwgclOWKVcdVmihQdvinYRwhJpwUYblxXzVBijBUJYusZvNmtDODMdhaELqgsDZBArEkDubRClwXimsEWoqbaahSJffvciSuUQtTfkuIcZxRbVkIEPfteNFGTYZHxJpYWGrpdnvUeAItgkRtZHuDjgtgMvWXSuIsruNBvyBfkzHUYjBwDgAOdeLabmwdOUTuizCDZDfsQxwAWhedUpTNOZwUpgquOLwEwbGVmhgkJuqyfkLANBTTzloeoWNyFGYyOcMqLEuIWWVxWrNPdEJNKIHYLMSOnXgiaWsbbDBTdVQLOAlOpsoDpJyWAvdszgcyjeHvDPKndpkZZSVOkDewOqSgjwedyfpiqZqMfBCSUlpbNKkkKzhoNkReXXntYdkuXutVJlSWRmExHlMqFINpjlhpyRNzeCwYPpBQhaxHXARXbCTVDnMsDBvbtudBrlhnqtmPSEJICHyPLhNNEFvCPvSUSruVEZUCepnxvDoPVXxLwzPmbwJLSQLUnhKHFaAaELzeoXiJjDqzRbzEYTnlBFIuuwEKzdemTVblpLufMFdclWqbctRpOupZssZhXAoGBpNoZqVKuzdtqQjkyyuuPsZdufhZrhQAycEAIxwnOOVFFVBpVkmhTrnRNknEbSydBNJpdTWeJBZGtYXiLbVcfqpHQBmAoRwLyhCCBrPlTcFEYkfFbcTRfqWckTECgfIskhOxzkJBucUbCbVbzEzaKSertnNyFhrEAXHHsMGeaCQayDGpssHcIbQaBKusUTPTvPBZZuLgbIBTBUUVVrbwzFNtooViWdsJrvtsliFxkjuweHRcxEibYVfVlWwjbmCJotIOPBYnPZfVbiTGXXqevkpnBJZycERCioxoyERjJeYMNkvhwzuwPdPGxWgwsoifpKWyfzXNeAtRDmRznpKGoJVWazcNlRXvUZDuUNRIisBrNnRFthvfAugZWsiDNMDPiFXpDDLCHsjwIcbVRXblBNzcuUTyKKkUfvFoIGZKpVuQngnXceipFLdBfsdRZSvJHlTeLvBfikEXJotNerILJSeWObduoCBQAwVCinlUNxtFszyqDkjdpYauFoNzKxMocSYZvBseRxfSFLJEWpHmIKFyfwstVXISOshvWGTOMoBloqEFswifpabBWqaIEoeOLsOokYUKAzJNlotivDWtxByrfpMXmzqBSUJYtiUYHTZdYWWiouYMTgeRTrFzjHiTmbMJfITrPiqRLddLYGQwGejFWaMeobDBOLIdRQpaCFBFeoePaWUOABEJRaGitqHrjFvIEWxbCRNkZVtMqRJoWXpfhoaSJKgjQZOyFDMGyXVsWuPQfKeaJizLLvhtuZNjtIZzXCJxvTVSBdJpnviTMroVo" + } + }, + "ProposalBase": { + "id": "35", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24914473521" + }, + "submit_time": "9935-12-31T19:49:14Z", + "deposit_end_time": "9936-01-01T08:07:32Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "437" + } + ], + "voting_start_time": "9935-12-31T21:25:29Z", + "voting_end_time": "9936-01-04T00:44:27Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "ZDsjpqnxNKCrfqAymXjETfBAGoDYhOOQDhCFssWcZyKLIcYEeVKstiLbVaSOGepRWVmDagAUkLTVjMtdrnOuYlKDzhSWvxAicrSrggeBeseROMShKcqxRLqgzfwBJjaMZwttFVSNocCE", + "description": "eLbFYrHqyOrXjWlUNantJSKBvKOYOvLlZmLsQeRYjZReCfffWWGVUhMyNuNRyhHYzaTVhxcYiVVGSeMoYiMhgkxnVjXRfTMnBtPCLYhfaxDYNfIUytiHdOVPZxESTjmhpJZyhBmghotbxabkYhPuXzAWNykukgLFewoBopBOUwPOjGWtUxaJGSpUNfmcSPNMhZVWrLfHpPwpxJiwBweSBNWivqYlxiYYwXipZZHZmDdDKwUojVMRWlSRvMelDsxPcQEeQTlEauWXCtNxijUBGHBjDacJZcHLOCShESnytSBQXeEDNzJusLauBPneGnCZggjXzAGIqZXizEGkixDucMaiBmHhiequjweayHuBKNmnXlWDDUSNSldmdXwBRFBcOLxFQrYOJEwRHlGYvZYJwoIfgdRiUQbgxRQuAoCZYLwiAffuVXcPxNjznAwFbTIylzNFUCQWOBnPLIkblsbgXKilZRfnzDWbIkKkNHGbqGnlnhNxzNoiKCEgNgJqxTqkOmIjwnxFCGnDqPPYfTrmfCTzkdPwjAQEdrhpjSwQGqkLjbkjjRyjcCTWmnCvJkuxMcDDgHxhztRzaqkqqabvJJLbDrtPuyMWpwjhocInYKEgnsXFFOexJfDFoOissejUHBjWbdEWBSEKiaoKShRJKiKMmYfkgxasGmvgFwUevUKZHLhtAupmExbrIwLtjFrFIAMPnsCqSYvYOLBaUcMssRygDExEwPNONHqSTtwZILmvDGBOEwDpfFWbKeseHDoNFFDvmtgAVTJaJZGfvuUKxHIJwzsuBRdIRKVQsvvfxaAjrDNSwevJNnDCVIEJdDGrkuoQTiDGODVBZqTFeLKQCYjGxQdZlAxiagOwggRGOWACeoYEkDgoFkJhqJinDSDBrxGcnkzqPCLHUcFZffRaAngaadkjNROHqcGsuqGVAOxJmOFsQQDNfenMEAFJiUKIfBSEliBWzifSLyAJfqJStTXPtNyTGCGojokqLWtmKBaYlKjWiwjJMywcHZWKqcQeNFUivftMVSELNpSoQhlFuWBEMwXNNskiwCBSTVYQNNtlbsuWGQHOidlDOzUDIGaqOUqNxhBsrBbNjZzABeFhCMvAnbZARNkbqwlqDXhjuJUWGLqiNRIpMJJdKUFgnksyGFUiYqcSCzYkYLISOiCqqLNufOCTQsSunWsjQGSpdUZPfcpgrpUlrYtfEnkSaBsMqmOGirYmoJljEtTdiMmYvbFLUFbeNTGaFNZzMUmthfFEqAIDQpouuIisuCuSIbKgsjhEfQWmbKcaYWneymoXXWNOVoVDqBofryoWMoIRximhmUcsatbxuniSZCIFQvLbOCZPOtbMkTBfNVKbGFvwuVvDPYyPpgApTaNZnqTFcmwBMCaxThSsRencqrMhqfSLxvmfKFWGIlXgpQmBzzlWlYdZHfBwiUFJNphutLiugpyQDLMxZVXPPKUebXcjpFAjPEMoJwcUaMjwAQjulytWdQEzmYdTmMjDnkZWodxIAetMxdLGTeFzPSJCERsOgyKBEqrmzSuIjXhGRDOYUdRDrEAHetytVGCElIrEOcOFGdPOKbGbaEKPxqsjQRcqHILkjUMxLXKLVCJkTbPRREpwcCKLadqXEyBtPmDTIhUYXAEoQPCfBiuhWcgiujEvUAcULHFJcHAcOsJNrVEXOmXHXoufAKJcOjyzuKFlWcCueUOqVnsywJgnULdGhxmqMaCFhDDsGwnqOmIdBMxfGdVEGkIFISlhlyVdDgjhZMMfLCTIbtzIcrlxInUwGUaazyqFTdbdQJSNdkfLxFcVJlPmeWfxHTZiesGgLNSTBYtkHcLvUceuZraHLmGueIvqAMSnPWAvGJZkXsDnZNPYnFCVMUwwYfYmBGBHbQZVbstXevnJjVSYaGFjUvDuFVczWPsNfjffsBYclieZiHIxrFIANSEWVxxBRzqBUtnrqeaKtBbGcCchFgLttiJFxzSxQMexzSEoSQmwCjArERkkRaIxKLaavqKwxCiIAZoEdyxipnCnJCjhDmxpecluEIZnuSGsRFYiolUHIclRcBUCFGcczLUeCVhdlDvjBKPllUNEAmKJVQMZJxRQxEbwrbMaUiBMaqvGzSQoiFQulGASZWTsOoOjKvRcmXcGSmmnkLvXNHTsYjxumuKLdHVfIweZMTBFrpLLIZFIKvsXEJstCFmOgDazirKtNvyubMBTDlJgTzBkdWYGZdcZrYuCiTlarimcbVWKZWoQgDBFEMNMbYqaQbqjhnPGnNfsJOKIwjsBVCFHNZotYeLeyulOtvVyvaEzcIOvrJzycjjALVabYMgfKnpyFAiMppOTRSQWeZkyYuHoCVdiUDWNooiiQaeutBvCUYKmdncFJcseUXqZqVnakZgqfuBcKwwlfkKArtXEvWJctWFQnDjHCAurzZIfTBETyAgCLiDayadQrZClFpntyQIVVsqWiAsHAcBYjywtQRcYVAWZRQYFyVWhQDJEvAkKlKhSFZCArlfyWuqUzKmHrmlyddnSavEbAOoqQznSbeyCtHEwWHbfORTVDaoyDnuXnUsFsvqTEDmRDOBcEXEiLBtVKWtsQdvnoLvwNElhZfspKvdVIKzIVkkwzoutaAbhNUtKtKBomjCoMWkRmKplIzsYIPEbKeqGttLuntHyfxnOlQLWJEGiDCZdbOMmibZxSApeiizGMBMvICFoWWhSNNjGqtYXvOmtdqhArZRYOOgPwrbLhTqoFlOmAjpEhCdJxlyLoPuCWchgHGyfzJCCgFXTQKvWvYsygjOJhARTWrEZtPEhxBpRrhLYpurIcAdJnrIVwENmcDwRkOQbivMmplBbhFzdqCkTHubbtpxzYwKEfFaLvtyRXvtGXxsIJbeFqUDOWeVDLntBhkrUDpnyAascvlOzAYFIlTtfsHCrOMfHbPVqJYxJRqHECLtoqtikBsnEwQfDedNOwQkoMnJYtBHWldtOdJnyigvQWaDjoDINVGpHzRrwPgozmvBOvxZgjmSswReTcHcglmQuYutnuOwwYdKQWmyVPmlEFIMWkrimdDTCLnUmbohdeyxihgiOzYponzdgqyKNVeXLjxiLPpYhWrJUogWRNDTeElXqgZAsOhgrLUMurezkqxlTZTUvFFZzxcEAKaxGrgyxfpGokqNGcwAjmMutlQCAsrVCNZqpmKyoPikSrUsFVSWBCbIsaSMMVpIKFYsUrpqSIrsoeJdVUPCDFQCGGrbWRCjwhnrrenQGbzdfLVXtJCSaeYmdrwWcuNEdlybdaIYQFybSRDcyVFTwseWHIWFfjRmPlGHIgkqTOcKnantiIWjgnmAfDADSxRbkJHMMPtYuYsnBJhLYotIBanHCoNdxXuyFgTyOQAniduQMQIAhNPhZyWtDvSmNwVkBECigfbpWuGDNMGYmwnvovimhDjAsArhRoNaAplQEPXgHtYpTfjzWVJZszKopQIlcXsZAsvQwVCLubJmJxYHFnPqwLoqdNBkhUFLqHXKtcJArWsgzKkuUuaUpVmBAGixYyslwOWlWOizrFdHOajhxFIOvYgLUosOiakXXEXsEYhgOzJmyaTwaHuJgULNVgYaeCKJfQMmeDVxXGLmAyfgudLSHzNTzoTWxwkqrJoLwMqmNESeKbIrKsivSOkzhwBaiIgDGjXuNeTmveSiDojwzltjKwqqFcfidApMMSKByGHBHAQHfLeVdSJZbSlSHpoivHWHPaewbnPVvTvJRUetGYsIkFKlPqicxRVOdoNdAVTvhufKQjZMdtNxAoDySakUcnLKNDDOMwGiFXRdDrtRqTmbtUeeivaTlVREpcDIsrgoAdaRIbrJSgvsXwABqjCCiPjXyLkMrHjRzXGJpDuvBRyexKMgVGgzgWesuvbceBiaAdRBMKlmKfyjezTpijTLAUApFWfQluLqHyMRuQursrgRsnqzxWbnsVYEzrvyPuRigzVryKkWsISxpYpBuymzGPdcPqiRafTvHpIOYqWMCivIxTGMWQqeFKQJKAjiFAyXbqAiuXBHLXnZKjAhlAiiNgEJRltamOYXWWGjdQhHdlYknMxfWZuEvijahOlgidTYJGdBTQaPmLdhNStuMyKFRcmyPJuzbESaKmPwLDiwFMxzmIeQxQAmhgsrIPiwGwbRIsHqKGKnRXCvwjbEsgeidobAccocuiLgvDeTIhFCikoDFXJeuKcBwSAXGBEMiMgYgOPKrHtoNaIoaxgVuNFktRnaoGtFelWXKVToXLKcnPBmyXEofZKPHwHcYLwOcbuavEjNMsXAXmftAvsjxRLcsAwZptJMVfGJeQThYoBtGZHMTorjFGwAMlvHtOIZvJmKjtTwXkMSHnZonzQoxXsdTWplVZCjcCfFIlGZYptDBIKJSoaJnLUGJlpkWfkfXXENvxBTOMvckZyAWpuYzsPHGNsgAJSVZOUGTIOOFoqrODPkGcuszbDhbeHcxeiFHBDOZFNSCmruxqGiwqNTMVDjncRwBfqwBfWPkmEyUTanxyvcTmgsSNQogEiCkvmtKjSJXTHYrqwXjYlLbbqriDupyDhtdsBpuVQFzoJlQpBDKlgNITdrprEQKFkfSXtXCeuwrJWwWuscpHLvonSbsDNRQATqwmJZOQZPYjnMJFntgbgEdTyRrvpcgIrdsNKdgNhgRZDCBfKyzcYfmHGwCwDTOLBpzpiAahASqtSOPwtVQjXxBMwAoaVHaVnqizpzRnatMaHQhVQSJGnMMUJGvkNdZAZgOZqtGMpwGBYzTMPyLkWLMtGvyZsPQUvTuwvUOSOyrNwJIWyXuTAxSJyFcuDAlYgYWgmNnBVbnDvoMnPrRZFwLDEPqThHcTCmLLAttMKgvRuzcRSwPxLKgLapOjaeskkTvaujaajlhypejvTauaRstllxlUoojZyIgzCZCAyuzIaOSCzxVhXstcoUEbPlnfVUGCgzRTGtqdkKmpqLCGCQDEXCIlFmwAoBZMKDcQWXXzqmvswmCvrWbcWInfwAN" + } + }, + "ProposalBase": { + "id": "36", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "24914473521", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T19:49:14Z", + "deposit_end_time": "9936-01-01T08:07:32Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "274" + } + ], + "voting_start_time": "9935-12-31T19:49:14Z", + "voting_end_time": "9936-01-03T23:08:12Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "gXuCzYBOcH", + "description": "ZiYMPxBseFtfXbYQAxwESELolRKhLcbZDSsIkuQhCACbfvLCcvFgvpSaYcmBfmQvltbruqdJEEdHIOmYbxaYyQFXCtuxVxRYwdVT", + "recipient": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", + "amount": [ + { + "denom": "stake", + "amount": "878575312449" + } + ] + } + }, + "ProposalBase": { + "id": "37", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T19:49:14Z", + "deposit_end_time": "9936-01-01T08:07:32Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "278" + } + ], + "voting_start_time": "9936-01-01T04:09:39Z", + "voting_end_time": "9936-01-04T07:28:37Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "qsESAidpcVFxLVUcRtRnSTHnBcjTORKywkTCJkHmkdIaNjqiwIDTeLzDSZuLJyGNxiEiSMIMEVGLtOEgzTMLWBSpaneexJtwIQGgUlrfFGNxMqoyvVemeoxJfVCsVHEXByeAoSzmtVHC", + "description": "SttkhdVbNyXrccSZDlVNdBXUAzkxFKPgVdWZYXGYahhMvGmsubhcfnvBMyoFckRytTxWcITeDbQCxmqPYWBtlhycWXBZFykAQmRqhWphYOYmDrHWfQWYGUhGvDAuGRezGBDNGEHDnPVljDqOjIeKaKZsFDtwHumLttgXXwTkxoLOBGaHpzFRZXUpZrGsJctbYHbvnRxDvbGvilGgIfoMpvvcGFaWwrcYrQcNqpwhlybOuqsioVrCYOWXfjuvryWWjQFbTAgTiWDcdncMNvuzpaWEkxRkhXGLBIXkqPOCENTktLLTtiidfwnWwczgaiZqLvoMQTjQgAqaSeuXigOLqgPMypqdDJoIRlUsayfuMsRUnDZUfCiWiMlckSdHzTfEGhLGdTmsfnZySIAVENvqEihTEeEHYsUwZbyFaTXufrrBzLphnssGEgDjVHWBNUqurjguqjpFRDVTqyVfUDOKpmwfyiyDHDkDoSRbEAlLjikEaaucDCmPrXDqDAGIwjPahzaPRTCEkDSfPsSCXGpSTSifOuwpeTvWiPhblZYXcZAXXSCtAVjpAycPxAcKcbbZcUanVPMSVGvYZBDCsLGurKfdNWNtEFhjpzpUymrYZwXZEvZdehDwKUBHktRvfiSPEpkgeZsrAXpAvqeCSMNeuBPTBMdRgmzXsbSifTRMDslTuYvqPnMozRmnhYTXfAbGntodGLdbNvkFiKBySsiBtqrYNacbRsfsvbwAXubdRQTvTCISZlTbIPsDOfERpJaqxfeuAhODoAwgjakfljCDwOQWdcqZqVWTZGvUsmdydBdZDhLMlPYtSxilaKYHjiLoRlLcNlosYzQdUyzSXdIHlPadOBjGvlWsfbxTgwrMounrkybSmtqjZnXCdHehyZtPjwfneGkAfhQEdRzULmfWLIlwnOJgkjrgFIQgYgJIPXCYLnJfblGoFrRQetAyUZfXyMOFIRggAAEkemrXEhPzbluyByGznrVATGDzoDDxFFnxIvHurIMskftkbJhodadUGHGbrVRNGSFPVgnicaJoPKJCZTFiEfCVDptWldmMxzmJMqMLIgfBPsQUhxhLieBSPFnoDjGutODrvhlVotRRQXnYjtXKkedlcfBZABnAqpAREdXQzTUqlOUpBLGmrsTqNqKSqyxjoJJJJpoaPpYfneegCxVMVETdMVOkgcdShanzElWFdsYKhSFBrzjXygUVwwjXwKYXmSNiZIoIDRNPzJDPShLDTKBecFSoyMxZHHNdUAEmqlybebEtiqnRWwnzikURvasvwvCEubhoypScEgPwSAnfKjLNzNnQzLhVfOtnbkawGiltkIyEfWgOdatzQFXVOYiGSiJkjvmWcbrKFXOXSVNcCUhHRWZDPnHiqzRrGHQFxkvxSborclEufaXPmbTksqHRMvKKaBzxsDBAjbPYAHsGOOwWqerFZKiUzepzIjJNwqYbOpglPVZNItDsOBOxrbpsJuFIwzxDIGVkNoTTMsQcMmMRLpLYbGtyBwEnBFuosbEWpwnHtZXVVNQbfCDOggnUgwLKOIbRzRrDgWYwPKwSeqHqrpKiRxratReKNbQnfMRgcFuHLEVifjnzphjibHTpLTxsgBODVPlvQXzhPJpGyAhpDFRBbxSSmdeeQSfBEdAiGribaqeqIVJVstSqxGttFUMuGqydicSxJkgSlMnjBReVlFhCMhYVFDBCGBFNoCdQXGAVoUIaFdVqzqUvlpICQqSjYYzrBzcFSLNliMcVtwgiexROIESOCNcgWOgSCYtuaudRVoFxabicgxrfJgEbsruwuQmDapcLyEXyxrwxrNnGzlgKDmGooyGwZgOCitGkzeyniIETyBNoVKpEYIsLFqrNsaMJrVTzJdsREDUMYZnBbcErJWeCPioxgBporbTgrqEyNAccvkmsVEtyFYdMYzILULARJnNttfesRNcQjbEDfNeZphYnpmLcyPpzgQYOydCmScABAEILUGGvTkRCwaycHYmAcfCaEUBoKsJluBJcVBJdhOlQWZSxLfXBdxwafgQCJeOYoouBJkFhjsFHFuOSfdzecUbCqfCxwyAYzXNOwcoSGYVgJTWZrlvzTsLHWzpDXzYSRJWEJLBUttnNKmqTRGUWHdEOzkKqFnFeKdookpCBPAiPkTEQIVPXUeLhrVnONMHkCItHizrzqbXaBiVAnNPAwayhmPxnyRjPpbTXFZpxhwYYFAcCmWkqiDCLaXSiZbPIJWpSqTIofANjOCNQlSjdFkojkqPHFrHbUIHkikUdTuEQOZleYCygynWIgTHqJHxNuUcgDuGtEbmJJjSvBzMewpbOLlFEhtJlvILUlslpGDTNQKBJgnEUHmFVLxGpYtMHkxDDZZdGOxoxmmjUXFuFXGZlLJaiNJRSIXfOEaPhVtfARQhCVCaUYBOyCVfLdIGPfHpjkbBjcCOunnlbJJjlvbTHCCEgUTZkaxSXSSbMAgkwLBUPGXEvDxbGjqNEcZqjTaJfFAPKoUSkBbTvQjDpjamDQBiazljbUxdwCTgqMMxsFwOgsPoOiJobLCYccvorIHqntErjEFWpNnJnFTXdzDRhrhgQOUKJbJQmddGMZXcwIArPXihEiRnYpNRawajNcDxfOCYCgoNcZTDcpLrORTEgLVqWOkaSPzSpNLfqQFWenIMSyDToxNxNEdAlSzMfjqXRUPULkcbShhionslyFIZgqGCuPaGxAIRuFNFEpMoqAEwMwWlrMdOFoPKjNsHqovpbLwIOLwfREZkfNyeZbJXUFxPWEbMACuTiGBsPmqyvMIzMonQuXusbFXfGadDjPVPsWbrkqmIPCBYhcDwnUTimAdzJGoecTvuPbRebKnJYquTHbZEoMpcBSgdxiYxJFBtNguMOQjzePkFUremHaJkCrYpozvChfHSipwFzsAdbqXrbLmJSRhWWcABRvgowmPpoWdaPEqQzeGkCfDVAjJBkRQSmgYPMekJqMYlEjBAyADHPlkiRDweaQtgoZXweRHPuFHpYdPUDMeSyYxBeZCGJhlaNqaUFAqKSJrVaLkZzyreVMyuFLMtpPUDcbxrxdAXlgJvLkVBgTRgtspAGUAfiTdDnwPvufwMDfkuCNqfLeGYjvzjGgSuKTBNXyGWvyckscumYKgOCxdhncwQvtVCQYRLUhSDCGwjHJNnrnyMxflSvJZdxDAPXkNvaQraDLbRCtFjwSfdlAWdghrrjoGYOQWFNZOxYecyLGkswNlIQWoLtImZLdjMueOIXNYzFEzYKVmCYqcwWAsvHcdztWTIsDivAJbWJjFsVwahboXDmauVJuFEHZTYDpLDVyRRUSMvTwMXrJkYZneQuraBelgKzXtBcIwNXONkawZVjdqrmuoRcptCtGvOEWMoIiwffPhqJbbuOuyTmEMLwkfgqdRyfxGdEtCepdavbskTkkxeWEfCYXPMOvkigvMDdPZyGkVNbMZCEpgdfkHifSAvZfyYvKalDSRoKNMYbGTClnWYHTiUDrGIOFesiGVCRQRXIyJClcejiANlrYShWoxNMreVyaisLFsIrgiMfxmWWbXZZttnCYengIGjTWGRnfgDGcqMMRxhRXvGBkZPqVlSoMGsbXFQQgVQdsBNdhiAPPyibOroQQeMmzzWrDqsJlkSfIEDdjLBPTLvOsVdLrBznBRQHDlzDgRkNNgzYoTDdlYFCZaSJPydShMaAAkxThPzpeazGAtlZMXinykDYChcvJMcsUHnLfvXbbBWYlXeRmYiuCJQapYnUmxNVLNblkxHcrgNwKyVWvuMBtuEYAFoSVkticFAxriBlZQJrZNbfLrKIgFLPwHFjrNloLYeWEETFGeMfQiIriaxBzBENvXqGrxSKsVmNEFNsAHlTtOOhFSjQuNuhADNQJXAkGSmKxmkMbyQRkVpDKytgftSwVQaTQsRVIQJglJxCVqPxVTwnAwAsLaVEzHyedPJzTqtTLmDxsVSOWqwHfUABFVCengwKQWZwrlLPPvimJwVvkjCePySARDItmIeCqQpnWABkTzpFOOixYQvaKhFJbTimxPVyPGXnScTiQlWRkOTdXpwThNPgobTDmTYMXdxkfNrTnCVtxOzEiLtUZKTMIzvODbBKvAwvSiWdNBRejnqzseCOArkGIuzxbqueUhkhaUscnfFpdDnnlPFcFmkWiQDSsQDvUmKRXBQIRljHbkMjllBUeuzEeoIxRZhwNmnBYHAPftUMZvLzhZtULwJoEvmvhuyddURyXGAQHxWBIQBxSXcBpZSGmIwFcJaLDsSuZgaozapCInufQVoNSeXQKMUoYpuxnBRuYBcrcvVyPSIwxgnNnIFBywpmYNWaQxbjSCCuzXkkKwKiQkxoidzAnuhcoWzmLvnCUuqglfEzTKKTPrysyxBoyjFbFrSpmVabUAMnPpGpqBTrTjrhRfaHxtuwWhekQxKLzwvEhrVwDyCsGBletldXbLJjYFzZedqaNjybRNVUIIHltuuPqVxzSQsxxRtxSIZSLxCHvoWkfuQRdxkOBQKKZMvACxTYkCCmcXftTCJvIsSaNloTdsjPjxcnLZsgPQeYZordJCAFscrlPYTHIJfvIaKJaQUOkVbJQfexdpbTcOMzlHwhqgXqVnuNZHSfwgRPwXPsUkAKWCdAKyEpDYmtsClNyUMxjTxjcTNSslVVMBPHveoGWJfcjlJAJkJzMzdxZxBpPbUqEdGsyAaGJXczvtZRUluJMUVkIrZYllDOqZKgWkVZiVuhvDMxbRvihIbelzicuMKEdgsAcBSHRoklmtvjCLxOdMBXNMmDHslGlPjbxXfmofrDgsycVKdnHEfuwSjFEGbbgCvahKznbcdGPQQaiwMKjerCwdFWkUQSgEOmakSKyxcXtXwduVphTYFLpheurGproYpOczKkYBWhirYKcvSfTjucaEtGYgpwbvYUJSXImnhMGBJuWMpLieFlDhFhIYKckNjkgOHUQkmkuWOfXrcMCBnczZmZnrxacBtrIOKwQBCI" + } + }, + "ProposalBase": { + "id": "38", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T19:49:14Z", + "deposit_end_time": "9936-01-01T08:07:32Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "377" + } + ], + "voting_start_time": "9936-01-01T04:09:39Z", + "voting_end_time": "9936-01-04T07:28:37Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "JFTcBkbkOVtTcBwowhLWODDrtswDmGbVTyDCzcEZqqxYRjSqzgpYSnOZzfAEXlbVfhvgcyJVEyCRGyIIlNQFmWnUcjDESlVhgfcejjVWDETWdWQOOnlaqAliOVTFNaDebuJyxSzOMdkR", + "description": "FBnyEMIITbpMBVKlFPWPOBpnfoDVluqZGGFOFyHWsvwbTtfpBPuKvwakKGjAhZiWUPjmnkoeQvtBqIYYpFdyBlPNybduyOVmceVywXjmUIjTnpCUlgmYDcCrYUKwcvmPumkAMqGWkrZQhukehxcQRUmcHwrAtSIfuilJvtUGJTpdIjRrKTZHkPvoCDzJzyNvrSZzKksVDqBgBuFYXEfYDXVCdaHvnyAFCXDQKbepLCWjOETPFWqVweBwurhGjETrELdAZQxbEiybVFsRPRVIlaJvdtRWApAtogLdyUbgSyOhtZtqSlULYUqGCivSfvIyKBwdOsyIXsGTZBAABmIZUYepHQGgudHfesseRhctqwyqTPcbHByOfoCHQlggzvvFilSOftXbopRiZIYwyDtNywSwzMydwgwWRfAIaLuonrauUOqGgxgzCBkmkTLqXZmndtkVvWXsHTRfgfWmhwnWtRmwnKnkFxwXwMuNIZPkLOnnUEfFdwXummGibNlGyMyPnkBmJRovbrGSCUZnKgzdsgUJTJJcHKRFwCpUFhvufFBBzxhqRlwonSAPkDxlDUrzmgoNbfwmasDpjvogmuxNndHeiHWobygLdBrxzQjhfBHDgHWhCQxYBGoTJjsVBMoZxSYNJWxcDMqJwxbGDyswOpIvbyLTmrljgRASKfgsIolAMGTuEoXXeZreKqtctLBCzehhjBatrLOHHyyiTXJJkhVnJUSHkMMRMrYeVeEHXTWDTqKrJOHDGkDTBeKGZPdtxGDvHnAmtvbsLgLeFEjJfOtrmmOhXHHrqeZaMrWcbKKatsBBVDeYXWNolJkCwnyGDnCpOuMvvFSrfPNyKoEOcKLoJSJeUVYNvBHNMOPPsmYvHPKbhdHnGjDMwyrXbHvOculmpQRxIsRPVNCYAWbiTsOUneYXUXVZiTzAmmFbONmOwXPlDgkpJOUxvNhVuronbZiqQnDebFvHSdVyRjznIjOVlqejhovmVmcJPLFVRXDgqNvyfLmbosGGYyHkJrIsFvRhDuNvQLMfVfGsDdjZqFvjnbpaxMwwYKzHNXvMRHVzZVYbpDiNFeJeLzGfbngqFjADRpmgXROnnbPVuufZHJWcqIchbRCzEKDOwWwulJedCrvdtelABoYmyGpyuyrgtHgjdycWXZZklkARGMPPWbQessQHuCJQNzYUbPsZlLtQYbjLkecPagTIwdkdvwokQWRbdcpAvMTCfTEqfTgtCCHTjSiwKHFMEynjcrrycVWLAeybrobyJohsvOasISRWZYLlQZbAapAVkokxQTrDaQVdnIahYyYHiDPXudRhiYSpAAaqgKEfUUHUHcGuvMYyeEfRVFIUYegHGKZnzsgefXzBfbVTzrPQhnwzvefysuvdlwKaFGnpfpsAWyeEHJbGnQtAYqYHnEKbfIgHGWyZeYWpEWJQGqzyXPMkVYybOEbuKKGSNtsQnJUxPAvXVBviOESvIZwKAYriAyAMSclcfYJevGmPPulVNXretyhMGHtKsKBSAPJePNkvdOVkNAtCeRbvKYXMJUSScZYBHEahCLoCKuxXpPpXGxGMwkQyaJZDMkusLpgPcJOJaaalaykcdujwqAfhPOTuDcWzgQJPHijSCPvOPjRpGRMIsWxvtrNnhbeUTeHXBiAEcqtVNkSkvQbrOfLsvHrCCbEqOUNhhPDXLlSCLabadmzUdTUayKSnlfBIBKAVzbSxNYVWceiLQYkXHoGTUzXWJcRCrBPedLbMgajaUtXpLqRBBGdPPcxkRBcDCCwGDinKNOxjXIQVKJAMCmrfRxljFHSWcgyXmJboxzfZAPRvIXwFRWfHVevwTyNQZtpZibSJPMXqqnHzOmEgPEdSHRpLsvhqCVoYVZxlkGaKsSPSIMSjUABYKPKioQXFQAWGHreyQbMUgsKdnYniNfgExThMpcIvvluyulDJKxbFaDzjFCRYkudYQfZUfeJyQRzfqJIxrcujoLvngFhvCyLHfPSgGJEYpFlWjKqtsfhbHYAxQkLBcyBqsuNmHvVAKDZdfMZVtKTdjjGwmnMDGeUZxZndOlCyeJjauecNAszNhozKqOlDRHgHndzatsuwWtOKFQAuwqJSdiIwzclhKNogSsgcYkceizxwrLXEeKUkebPLUlZwvjxIyFzWVfvDoQiBHwOXZiiKwiRKOmhLjBRFvKnDPlxEffoCYUlYwHftxeKBUCbhiZOYdfLaGJdyJcwpUqIxKxomUJnBrUtezBKpZHzXiJhWDYQMDneosDAkTnoCWuSNkpXFwkaaslxazeGgTpYrjhnYuZlXNKjJGrqzPgRAPkzBCTJuNTUmkhDurQVxifrIeKknjtlaYQvCVMrYnjaHBJptlNRtejVhsrbrDpLaAUggubpDqnFsBAUzxFaWAlhJozRYtSKRZqdJYSuAuATVrcbDUJYttmlBuNJRIaCiIkgcQqDnygecDtYYMIJhuFCUmjIKrtywaJmygvBcudWfcqVzwFWEtTqeEcIKKyYnADAyzkXgEmLNjoqEJfCRULAaXMwkUMcceoxyDOlxwbBTAhMlZxJSrzbSKfVODoAJgbYFmmkguVnnGhewxCctbdQcbayhMGYZdBKesjAtDiHwrWWyWqNKWTxYlNTahCOfuUYLhHBvfFjhAinoUGJRpjdAQgYeVOrRvDDRIWehiMdwRQmyrjMQtPcSMfhyGwEjmRzzWhgiDNBTfmOhnthjrFSOaBMzKYLIbkvWEzRTNudTjRSZCXaJxtIfXMrQjrYGJsBITXCCfZRWWTibIauWMogRrduLtTcjbpPSkWJrmQCAJtMPCGKFXnbitvIBxvaMHxttViNCdMgWodLPKlIUeLwDUHLvIxrylBbLftJkyRZWcCSBZiyGRDwkIodTkITrGcCebauJfNVFQnytNPdNMeXDOkSFfrYecvGKWdPMnrWkmXXDfHWwtSZjlhNkTJikHhNDVUeyaiiaeBEdckjHzlwGHbIarrlKRoKNgnhlnYytnmpXkBtKFdLeAsokcvQveHtuhnvZiWYyAgUPOGxloiJqDAyGFLbYTCfphsKWXFQrFlihbuzXWbSCyPyhfwYZGoVyzcuEFcMOBVVrFZzLxsTTdjZCHwVyXpfNUHnJHZYnKgZkEJmtfGMMjrBlsRbsAXwrtGerEkRkNqYVdjTKYxZspbHyLGFaXEJZoYrnRarSZUrjPXeAdLXZkyqhXsjMeVjnNwHIFZWddNuOOEHHtntyTbEBZmzZkunUcmBAgaeSdznzjgEgpAcupPpvOnGQpQIfjiQschqdzlIByeNbwBcPSPvjybLdPXVrYkkQyPnSUYeuKENdBWVAuqnFOxYRxnyWnilDbQZWsQNRyhCfdKxEGoZLHQymcGTEmnalbsBJGSRciQHOYjkKcmNwokjZdCQbLKOJlkPDhSPLUiOrbbgRBhwQaEjbmEMbRVeHNeXWtvRRhbKZeWeQqyAObPYrvEXomfPudsxtWktBDadrMBUTdCZNTLtwfrmUUygimzFqkeXKeRiwrHnXOFhBUGhcgzMUhGrHGBfbjuqHxBoXUKkznduHYvxeSvWZddlQGWeQnrolwycjaUuMQiydqoWCodIdTjcVugnQttTWkSpDFXEiUPJJCdBPsApVLLWuabzsZdtiloRzZdeEBaArSNFHRGoNWCyvdRgkUiLNEMtavqubfsjcYFPPXTGZkCvdBSFeDcHXLeaAePgCFaPSYlpyTpfzddqMKYnRAvIabctvlIQNHQYeqHLKUObUskCoqyWHxxoWqsJeglGuojdTZiAFzjkxQRyhZlUvTVuBMuZQWeibqUysjtnFTQJIZEmAPpeGMIxNQYnkIqfGxzsrEqIYjJDtFaJbeAZhSrvVRAUHxloCuBvaItUCAmNsIQREqFQNxLWPwfjGalLKxOWEOtWwhzGeQlqNiAIZtuybdSTKfWZGbylVdmzdeSJNiRtOHFHQGrTBiYBPGwbBTjIVecGIxwRNsftRcMShVBbHYanYdCNJzoFVuSVcEwPELtapeUmlqomRcdMewmEaZjJLuymdQIGMuQijONxjLZZXyjAYcnrkegRNizWZWkQETwryFDINQyUeqtByTbjRfCCDBqeYWAgwmxQckKihIdZsQBEdaZxRPbPlwywmveOLfuwOwjInfvynBbBNJSHfEulqMdAbonmxzEWxeRYclSVacgGJgCZsuZiXAbAfOCrGAblegnxnKRaeSiDdpKdkHTnxfQpmqixYmWKJzHbjAOFaXuLpGCyLYoTxgpDsSYqbSUrTfDRqMoBvyhvVqmZGZWUaCjNQuvnppyTHZyEWwzZJElyFzBSzsmkwkmWDpQVVZKQHFveQWOglSjDtTGQlILmjPdDwKAUThFrZOdgsBRIzlshufrWYxZudSXhyKtAyHrwSEEEKNlfZHvzdBCpGoaQjWRvYstIrDKeemMAgnZYgQpBEMQRxDIYmkJqzbPYtLJwDeXLLYDdwLIzvICMnaAyZksCqdHnNZcVCvonhooJxMtDknsuuZNsQCYRStLEkUAklTzfgsXLygpginBPqYMhSTTeSYjrkrRTHhcbUNRFeLuExHVgIwxTFoyhQbLtYjqTaNlgRCOPyedFvrAHeqGWyrzDOmFBSEmyaYAwvcWMNkSJzxXVlNrrlQWnhBPqHMTSjoGCzBflJzltnxKoUAzMBtuIAYvZeiMkkhwPgLpyZhUmOgKmKXJowDDYgEcbbFquYIZoIwhUjTpHhWxovWtQJllUyeXiheglnwHswEMdKoDGCxklkUajaExhuicjfYQZYeHwmsAdaMEQTieKMEPFNDPlgFcRQybGTYYzSVpuzTkVVZlCIIllzRPgHlSlEhZfTveyJJOsWZiiSJjqUPiIgpXENkaywdAPNoHxbARmkizTiefJgpiFUhAgYIqXSljYUWiPCAaNNlnKAdQSnKLxIGtocSsHPHCfcURlnVyXsDRVRADEHdQsNcQZbuOZDYzJZzIiMuxPgCHwmAwcarRcj" + } + }, + "ProposalBase": { + "id": "39", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T19:49:14Z", + "deposit_end_time": "9936-01-01T08:07:32Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "265" + } + ], + "voting_start_time": "9935-12-31T19:49:14Z", + "voting_end_time": "9936-01-03T23:08:12Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "AsaMyVpiymWdEhFeeiBYtcSfWKgHmfCWarvMGodLSyysCgemBrJSHltcRAywuQPPdyWWjWlHCSrJYTOEtjxSWxZKEgYoBWgyZBQdzQYRHZsrwLxZYBeqCIMgRjRAjjLWMNDfTCFSYntV", + "description": "yieEmDLtAUwEfssFIeBKmcvvyezfRmwrimtNKJRBxyTseDtAcyKzllWjWiKjytNanHZKmlLoJZqGtpfmqTSpZPLFhRoNSsLFLLQcoqvStsvzExiTomQRQODfAjzjFEzQgNmtitFxtEjxWQBTTnTYMhDGJSTdTkMNSXplCZEsxDUsmfMcvMbHobqSpDgqgaWqQPGYBgVKEOoxvspQBLikhfPbjmOXCFJrwToiKDpvLrMYexqlbTwluXRIHCNLEqWyGMkJzbXHIdhFtGmqGlMwOPvQUVWLmecUZBFFUTdBCgjxVIzJQLXnSmfYWliRMHydyHDLHaisaQpWDYTKubLJAxjZwCLwVLnyikZjFRDAwROUATaKInskThlkmRyTbuRBLrjPCGVRCeDDXvuYdEbHxRgRMYumeDOjxPFzzIifqdIOMNujPgigYkHUytebnjiPMTRRFxMwgLZLDhOhraBXEBoVQQiOFdrlpJBkImOTjExwgXjKQqCIUfKoIAOolZNioQKqVamOnrWDBgZKbeJVmlYInbyDpRtIMedjlEySbQbETOCVvfvjHVMANxecstdSXMoygVeXkSdVapTDYPiuoBOEXMnqDSetDQjTIfTJXWcHsQjuJyyjBjxaNFjkzRpvkLEByXFSMBkqZULblvzIvONkHYfAqMyPCIShoClDpRSZNNVoWtnoMhWuylPdshKrAMKEWFiyLRSpHItJvNXuyHpQtrRcStkWNIywuwLjGVbYgrxxyiPRaSOWJzGQwxdsXWSvRjirBGdLsqeQEzwiMSJDfUpyuGJBIgDlFueDDVYUUdOQowhnztBaZZwxRKLRDyaxJqeHwokDmgMnmefzZipTppqvfYRGvNUJOpHYauhYJZMZgjmPGyHhQbXtoebwfhmfPzVPBmxzPaVhtXdHPqbRlluCXINgWdGXBOIQDYzNCBSgulpvfrKnwTqgdgIcGIuTTHkSqvFfzqdaEHAnyYuuZXGyGDafSOmyyTTifoEgLcVrJHcddZhVrcxnqVqTkVfKMUIhQxtbKHlXnZvOaWmhlBbZUCRPDrouGTNbjFQUQWIrDjKpUrMsCTasEwFyHVEEtwklrwpuwhXVAYPHGZANXvChXZbleGRsobbFuLkjFhRPEQRvTcZpyvqZQViAYQqlvEUOZVUkgKOuWIQykceqTFqsbZYxDfEUVqOQchSZUIfgzLRlqCmeBydmEwYZarIgZGdJTtnUSslwxnQJmouIwBrtOudVChgzXcSTtNwBSLobgTDrhXHVJurYmmTmSwBHkwUudCQDSfcfKJuwVlYUTUEgZWSJRmooOXOqHCeqcMxDDVNYCGeszERQvFAODsOYJmMyWkazINESNYEyenuytABVGAraCXTsAEpJQoPFyzHWPAjkGHPjTuwWTDLWBambGyTWUMolwXUtTHnpDYmlAUWwkizpxMwXMjtJCITlCLKXDEXHHvghiGbHFxrEAhYZGMvcZuLjIsEwVcxUlNZffxsTeSrrYUoIoehhKeATwpVkFrarVoERZIrSsiRBYUdoXyyaHzMmCMHoicqjwafBZSaWbDviLqtIFNAZWFqGyoAqBteyQghjipVUzblVhxeivdElyCxQBOqWcqrXSbSVhstCyStKEOXPfizdypbCUefMKVJwNCcuZoQMCNKFyzUZmsEpLVneiExEgSjFYRVWMCYXvAmPxzvtJlntWQDTgOnLizYEIXgWeabwIbuugvzuZWbavOkjVApepuHkcKaSzrFJprCMAFWOLJKfMNdxkxvxJUCxtdBxWipYQspTWIcZQkmeSlJyDEicDIfwFOjZVdUezXPgwmgbGVPpuJPzVxGVUNLAGdTdgsZKdvajhZGdyUkfLFTWaNTdEjjWwBshNbtrVixMnZOfrZuFSCLURfTtJZsDKyJDmJQzHfuyzMCNvdhLvYxnCWStvBrQhGZSTjQcgoASRQiseeMuZvbXAkQfyAXTxdISumaLFeZoCbnOHQWyZXHohPOaYGoIApWoYnzyGnFbOizDfBwgNbWOEZXiGYLTHwOlSPiqciKoStcNZTpaaGKumLDsrkQZBTFDUIHcuUOxWjZbHycfoetlqloEDiMKlOznGVOxwQTpAribBStNQQEqXttmVHuwclYLCfgROyXqdHVAYCXWgxMKWvfGJbMgKYLLXCjeByEoxZvXWeoqcZwkcAbkilOAjMkSTAtqpvieCoKclPKcwjUWuSYtcfJIVfkoZoiPoysqhimthqsNLZtsIfdVfRtFuAWHrqKMtNEWczxMWQHqAbulJSZUuYdOstewyjrKKniwsjznoaIlkAoaMgJfyiKzlmUpxDMUpaZvgJjBaiOCHsdLuOIZHTvGYWDVXCSHCcHAdOLwtXDNUkcqIqPebokRThSGKNxqWrAPICgEATFxRaVNaSMYIURNtZUCbQOXdshapgWsQuemIUudhybiywOYihCPlianWLGpCnkhgrsnuvwTUcMWQBHNtBxehgONyxvfZnMEZWlPDcwfYhwxgSvFBEmGyNycgqxXApIeNVNhokKBVUGGkDmfwaAFaRGsrqxaVItdKhqzBRdVxfQWidfibzfDxssnGqMxCJVbSfAZdPPApgSHLTncSkrgVdjFoMAXYTpMZQRSzotGNOLURJBUhPlluSfIoFQQhAzthyoMqKtxDygxJFywvmWtiAeOqELyGsrmYYiBKMXJgSflNbEzPzHszzCdpGDoossyNCXCwvBEiOoqACxIupDhtuLdGgPEQamZSrIyMCuFYnmzOmLDjZxTQLVsXiUduTKTozSxUdexnYZzmvXWiRDjKqDwVCBdQOAWLwVWhJQJvCvHuIwBwreIqnUZfTmKUOzpNTKgFeKFbDBMdXXvKGMcyfEGqqTdmecLboXnpgOQHhlnPCgsUhnEupNTLmwJEuuqenlIqhQCsaMAgSAPWUkFPLkCMblPniWugAKpvfEoZhRmjLAfaahdLROyZkscOMURCqkCFSxmzHdabNnAdupwsIsDiEZTpupUUiQjMxXpNNEEYEFqIbbyuUVpBgdUGcVXQSRPlUjwtPmeWZsAjWdcpTBeZTPwoXnwTOwXXwFxYjBdMAvnhrtBvjAZFlMgPrdfrIUuZVEgIjFggDyCNuQQNVQFhEVxJPLOKSnVWMGLSzmskjKNZJHeuVvidwHheOKIwFhSKieqStaWNJsryVThbDPXRVZFVLWmWJkuSsUQqyfjAmYVHmmXmbTUvWwMGwGCiClovHkkmSvRcTbASHfTktxpiquJpEbnXeHxYtMifWXjohiXdDQZHtavIJIKstKFSJDEkCtjLdqATZBMvIWrRZxfYfowWTpVQLuvrIEYuHfSJcBguAfWgsXlaRIjIDgSsujGCnLBioSeYcrsXDmKJNvBDbmhNPoBATELeXVqxRLTNMKBGEjyaKVOPLoeiQfJvfqhysegiYbSKRRTMjsijgtWVTBibGEYvfDBgsSbCbYbUBWsmJtgNkuxpbksxJpGQdFLQmxjobZFOZstlNBxEViupuTpxDbQVBGirOfUemxcpldZjINHerDDsJFSzXRwqJKDNVfDYKLFQJUoBsmqWvBDfcSvLuGZKVEtIYlmcrhDgFhbCJSFBkXuqCuVUcoTjCrIqSNeWsYSREjUtySaXRvJzYlKIghzxCNCVqbaBoFvNIJRChvmiKIhEuQPTbPjRFkyVivqUperpwfJJgsNqigbxfxmkOFHvVfyoNdRwJdLDkSkhbKPFVJeSrLvzyzFStdSvczuFByqLWpUyvEZZGjgSoiNnqOIfEIygwbUcWvOveeyZmBRCXQAnjQCeaMBftHwuHcTVTinopNyIEubsZpUofGjNtEszwZjAmLduHbCjNAXckQGitpYOWrVNhmhGicvsDyuRQifGDaHRdgtWADdnSOSTwxheFHpFHQPvpAqSKFGLRTBGYDTkWTKOAnCEqVfiGeXlxHxbKfYyjgkmbilTwsFWNPiRLzIEprEPkZBFTVxFZjFRdfwZSPrgsRNjmYHxATamjsjCtJHOARTtyGojAXdUXcmnfbrIWGfAqdfaKGAgqlwUhNsVyKYSNbVQBWQgAyenNoVAHNoIvpVUgCCfcLSafladMxsNyvhImqppyQyvEKKFSTyhjTMkFNtsolUYRaqiKreMrjbhpfiLiSNPpuaqlGbuvpRbpLbTLHdrhOEuhtEoGRTiCJdxLDYRdTvYDUAFzSuIrvSiwuADKjlIRJldZLAbCKpNJnvOfZfvCoWcfAgywzOenPhcJEmdGsiQihiwjHTiDWcdQsWbnXiBpoajxNkmFvnRoDfdVGZJvKkajiHYpSdyNAQnrJjPpjajYyXJrWFGMXZiSiFkIxVWWEdAFNnxABJlHtHApMkmTkbYkapCoReNVfKDKhrBpGpbZIHoJVpwFVeohjtxxSdLoJOOjHCNCOFjzOAfGWRjEoFcyhsQBebCkXLJbJvXzNUxRtoSPCgTtRkULVNCDaBchlHhqKvSSVaeoAqMFimhBFcyBsKKHAUCBJicYuSHiyBlJtwooiUuUrzgzQcqRmrovFCCDQMgFkXHLbUinkFzmTeDqqLVPdecKRBkgldnjqDqRCgYcHhYRVpkxMffbpJPncEUFvfVjfLkbCCYwqguOuOUrTJqVsgarrnrrAUigzeXAZYnGqxDeHCRTkXJAVLzcDbqlRfQthKlAKKdKMYmxgkXRqzNjnvGotUgXmWaXfCccgIHbMcdKgxaeaPnirUkwKkVUnAaKcINelBxGTctVZqOMeRVupsUqZbhnUvwtEuuNZLJIIbhorUuDsjArVqZjTeFoNBYmAjNLbgNsOSRkeEYGxJwqoqDHXHYsfkinvsxqHIjrRfJjmCUACrFqVqlWfcaaFFQBdUfAqaHvXnQszckZUunYKFLbJrfQdiAXSxWnveCLFCTnxowmchiSMyedOlgqalSkXOumcfXjrbwGidjlDzMrLOmRbqPbWnxtNepVnyrfGDfHYwHZvrfFpxYrMkqUuWSVIB", + "changes": [ + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.100000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.080000000000000000\"" + }, + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"234699000000000\"}" + }, + { + "subspace": "gov", + "key": "depositparams", + "value": "{\"max_deposit_period\": \"8250000000000\"}" + }, + { + "subspace": "staking", + "key": "MaxValidators", + "value": "42" + }, + { + "subspace": "mint", + "key": "GoalBonded", + "value": "\"0.670000000000000000\"" + }, + { + "subspace": "distribution", + "key": "communitytax", + "value": "\"0.150000000000000000\"" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"177\"" + }, + { + "subspace": "gov", + "key": "tallyparams", + "value": "{\"threshold\":\"0.529000000000000000\",\"veto\":\"0.317000000000000000\"}" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.100000000000000000\"" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"216667000000000\"" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.010000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"9\"" + }, + { + "subspace": "slashing", + "key": "SlashFractionDowntime", + "value": "\"0.005000000000000000\"" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"5\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"242\"" + } + ] + } + }, + "ProposalBase": { + "id": "40", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24914473521" + }, + "submit_time": "9935-12-31T21:25:29Z", + "deposit_end_time": "9936-01-01T09:43:47Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "338" + } + ], + "voting_start_time": "9935-12-31T21:25:29Z", + "voting_end_time": "9936-01-04T00:44:27Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "SAkQGHUsafluovdPAohenMWpBXBCjgiXEltgbbkxYMxSxnPtFQjVSgeXbEIWzHMxpJGVwIaqtyQBtXIFBaGslergpYKmWEZiSWARDSGNONYnldyruhHzcVcZhuSzXteawJXovDuvKehD", + "description": "UvSEEemWvUUncAXoQSmtzzpSLUUqDFnUKhIRKwvYWogvqdRIBuUCjwNWimDVmDqMppXjYWkBSpxApKfHVOdfjmvqTQXhiVObWkvqNTTAUyzbAmywwZSpWumompPTbjJjTyMdflhtXIykPIamdjGDMDTXCdznQmInyNbXhmtWhpstlPQCVGzqJERqIWHQvgXmRlezqBANnXKzVIhHRYWSlTbpcXJHxgolTHpIMgHcLktSLuaRyeyKHdDCOwLMaeFpMzuoTzIzDOCXyCIxaqgwKImXsrfbSGkKYroQgJfUnZnsojesQOmgXpuWCaMsZeVFjZlifcuaiiNWLYkoZoctMKooAUsJxDGVlNPeRVxaToueIprVArLIknLWrKHIIDdSoanyrGKzIcXuDGwEggFYCEUDGmCQnKlDUcBQWeQYabPdhSvueidXLOWFqWciopfPVmqqslafWdubcloVpxebPpmSVDFZkVbWRKAhyMnidtrCylOVevgNnUGEjjLTWzFEsRjdwdsWtGthexQqILtydJekhcWGLetxfocUyFoUqMJAEmIwvjgWBRwVGHWDBQzJiJxMyPdMBnsdoNgQOJrEMliXtHPUOVtIyXPsyqogpNqStzkNSqbMQrUVnRjlHAYmCLcbQVNRrQjzpqYraEnfubZNrolbuDKwgmRdLnmYtsekHLvewSTBukzuOPVqhnolwCQMVpcjXrXmAWGAhGmtVqnjdZNQESheGAcHtzcLdVHrDZlFBqBmBAhGdhCbuyqplyfpCtxRedzdAEPHyubmLxOXZISaMuUYDqammbRCbFRlddvLMjokKJehNARolieAaTYCLMVKChtVainCiedZUMmbQIrVDeazYDyoGCLOBQaoOsOGbzLvTrfPwqAqavGJeXNjGoPPyyxiUMknGCdUFDoRzsmNrqziumejRhDxAfGOTgDlwiSTbsDXbPsOvJqmcFGOZRJGTdsOzYyuVbDcnXYGUvQBPKJPDzwAENbYkfRNdUXxrALvJRjIOAjYaOczXGrYoZkuFxJwrkdwLvPqwcObwpJzxfscgeVVaKqnYNbgPUfxqrVHMxlyUsLaAoJdwaxGnIdiUowTabXLiwSOUxjhwrdPsLRXwuKjlfvFWcQeLssrECzEBypbIOriJXBfSGZzBmznroyzeqymcNWrfBWqdfdsdOUMmXaOEBJSgmtvhFDMTQTrYHsqAGfdsZueWJAYYoQaZUxtXAFYLckwpBsDYkApiJFoBdWjmkInxKXqrvzpvQJURKPQajOwLekFXoiCXYoHmYDZFlUqpArumEuYfHdaEkeylssvkRrrrRHRephIgdnxKuszRztaDKQUknTyKSMrvPbRYsngShXlVEliiGYKMyXoRVvZZctkVaQXrgfooqJoNguDrtrTvFyRSHAjHnZyLxVHhWVsoLZogvubJBAKseOFZtKHYahKqiWQFxOqyDntzCKECVDiefKQzcKVTlVWMDmdOzcPedfRzupxmlzuacEEdeWRNZvUASJnniXguJhwABsfITvOkUMhtICNxLagULZWqgcDTLQJZTQqONiMsUETwkPNAYKaLwCMNiMbxyBPaSCdLAkMATfcZxuyiRfbwHDYjgIcADUnekaANBljlJoygvkWEdomizotjfqXtlNYcRFOqXmAYTxroJxgFOeVjNvBwTHBwjVLwGAPOGSEqtLSkmEcyYoFIJgOeoZIMECPeOXKCEzUurscYGRkcGlacMEBTaTcXLNdbyNGOvMHeLeHKSCibRAywBQlwiFjRNrPbEkFYkJcUfubjKUIyvKdsdVptKUUVndOZXzmXyUVMPinklCzGlLsEHbgyjVnsLSFpdhPgLKFQseAlUUqmmBVzANWOUltzMkyarWESyILltQFlJlDptvXHlUDvXwriRZsJpvbqgMESmJCNCEQgPcuiQSJSYEEsAXQZyqEHETMJHsBrVmTVXQoFtAPLNvbQXGxyvvfuqbeVjNvjEGuWtqeCAqutocKEHMBDSNLNEprRnsynzOCgudNjuWDKWDfLyVWKAmRmVQMqfnHgYzGiLrYITfFEmGkeDTiEFtQmsyqEUgxuLhsDFgXYlUMPqvsAELSiVvXuxfpbjKwfmyxNKWhqpqDyPMrTtTDibKTXTqPKIjfhPqjHIGQYFLICGgVrKBMDkcnMjdLcWuXVVpNIFlYcctWPlquzwSrYLtMqAZHpgrSdcfZeSZmVMstCEmuAQdQOJSyVpXhHbWcNlNindFpSsIbUOUBXVCSQFdUafuMheGvhQAyKVgHxWtirCQZDJmtUMVlqfkWmBjAyUtStcAjfsousGtQMiPLXRFBLvustLuJWSxelFuDJGohiRhcLFjbhJUBUiqXAflGzeDhtrcbMngiukqInCYEpFROGRjPUzNmVHsVYDOnVFgoMmayrBBwWibPVcdzjZxtXychCuciOdwFUmnmdUkhPLmZqcINGnlcleWRsImxhHcDweJmKltoHXyrhiktcREQSUpIUvUtxEhDGWAeSQQYTCVdpmawwVnYipyipSjklWJuawsJrSkVWwOfwKuzxZbajelodwvSJiCgFBqwIFdZcdubDUnOlOjjTxqOYcIdunJVWeHvnoqbHuKGACNjJCpuznZiNMIFxGarlvpckzOvJELeHGxTLOULnYYpiKaPwmdTdZwHnJQuFIoHbrgmFvfeCoUgrkAAVwSsVPyhwjrXtJjlvpPkSbMkwpFKUVbtcYxeAyPRpwQxlXapTWbRaNZSPfwJFuSzmZkWqpelGfkfjFCnEtjIxajrwHlsQpMfvgkEnPtBTcvVBRcghprbsWRJxgfQWxeTeYtIrLLdZBBaezYhMfgQpwCAcLEFBigzyPOCczhfQEgzYGPqgcURldrPcsZWraeYiVQqaPqVXMOpKiLfCQSzfkUUFPyyiKvuEbnPxRjEfstZKdSKRGWVQCHRVZflRnhDJHfEuHLHBGqTjDUtiskJuMuOqFPgmOpmWYiRsFoRSTzhEKeapEQmNdZGhgWsKNYdFVsJYmbKJZSeQHebJSQItHofusZXESHytEuxfAdqbbWglaUrqafKyGgxtHDnBhxZTpyoEjowDgDfHeeNSUeNfxtmfswemPdlnuIawrBgDlmDuHNNwuZlHQDTeEJSqsFiSnHgsFiVfyBhaZFqiSFupmMgrKeDleRAWctubnkLJAgYCuKsQzWlVxCGTgxwTdSaWRajlJGRiINOkzRdxFXDpxtLDWcocIjdRalPuFTWVoVrmwMMuqexbphFZTXlfgOyDkJDDhrORTZWvUPwghMkvBeIJIeXGCOCJztlDTENKiJVubnSiaMwqGjcUTXMVtkXMoIDyWFgxUrapmoXRldBOFrDTPEQcRUfVUuGWaNyjPKcvZtCFFmYGPVqDkiinShAcKAPRtuOYzsWaeCicSPwBKCXNLTyiHNeUUpfSNISQTnseLSprnSPUpRhydQopVMDPuuNjwIuNUsAzvRaEKvAmwjgnTQLbOGLJYERiCkrcYCHslqDOwEaiRlzTfsQFbmyVMlFIPqyjtqkEKcLKaaZDLEauNKYBprUYAPIcDBdziZtkJbvUTgpDAOuGYgKEUYuZIHuXbgpceNYfHVxgfXAaamlBkyeGwMjJTqKovVNlWGWUozeCQvBoVeJPKzBCNxpzHwBWKTjhJhwpKNTNEzfzTuvnkIukahrLYnCksftTXCWqOZHbncvcwTJNFNlirfAflvNLdOfCJDQEaeUAlWISGivdZaeAQRZJcxqLsslzJrkBzZlQHOxXbiwyAUgUluqRicdlxZDoMTJqAsBWeJxXJvCKAyorQMZaNdVKbLAsDdkjRhqITIVJiZkkrUoNriJifMoMiBaLqLPVPzdXFJvjKIrKvFRktkiFsjWcTtAwZPioJSthbdkzSJWzNAIcJkKqMCrLEHdwvWOcojRqwFvZQXOHOJJugLYyflkyURfZJGyXKORgGJaJDzrRSJnINddwuaeLiIvxeXsrlOYBPWrgGGaWcbQxbQZpWnHbawkmtxnLsPZJOsdpgCGSNbvuxiXVTUWoZIdiqdFZCbrFfXtNJrCXScpOMDIMugpWycdSDpBDGHCFEjXRTkPtfWARXhQCnqsuQrgdHinWLftwAJoUZIywWiYUoANVXVuxKBylPrgZkvAoEogHUteQAaeDZNjyTRYRQZaYScFqyKmsloHZFuyGZrKCsSwLegNGJRBmtuoSApxGQIqYGrMWdBHeLiBGQElViUZZCbNNiCqrzQwlHwOYCgvVCYIUpXibSoijsnTRrszVOpnmoZqmrbGIxZbsGOwooxkDVFlCTEeRKHEcijiJEgsIAAeSNAhsXijlnwYukvXDcrVEVscVcBzVUbjdumFKEDgzvbFZWdexdYdHMUQmxbfGMzBNskHPvYFokfCFTTbjsobWnRzSBUUPbSGEWOxSwpKRXGwPbkFxPqaPYJJjKLEZWFgnvFaEzlDhIOYSnNTFJSbmKVjXiRYtJOvCMqSPsTvTQinrpllHcpNLVGGskWBymSqeXsIJQPsFwKFOzHHtpFIQAzRHjIjqvulZFRVpVCbNRRrfMIKhTfXPxwGPLCKnldUqjdLcHFPnGNgnPxUSVJlrYQiyilvDkZgazenamEFGcxzwyDeQoemJRBoDGJBjkoZCwPnwFTadTBKHXfjFWtXuBSiptmHmQnHATQnmuRoIWdQNdjAwdHalWnCOQSGuatdAgjODyepzuTIMIQwhnmMeZfxKiAaBOjrZbzYcJHLAjDdTnSLBFLuXlUdjaWpGbuVmqRpqxbMflltPmNvGVJvNMKiQZOHoeJEWTYqVhKAYrYqDLokbpCcrsrCnoLpIfuXRdHqSxpseMXOLbHGncVhgzQclEEzZveJFHxnYLiutqrgIGigdCZNZLfnydFJnoqcrolhoxTSsAHlHdmWdbusxypGnxlqhJDRXKTpQgpHGPScRCWFfUBOPIzyyhPJlFYumRhoXtToJOlmImecsQgtzcHiFWQOrowo", + "changes": [ + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"36619000000000\"}" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"500985000000000\"" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.400000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.900000000000000000\"" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"10\"" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.170000000000000000\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"816\"" + }, + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.260000000000000000\"" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"9\"" + }, + { + "subspace": "gov", + "key": "depositparams", + "value": "{\"max_deposit_period\": \"140795000000000\"}" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"181\"" + } + ] + } + }, + "ProposalBase": { + "id": "41", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T21:25:29Z", + "deposit_end_time": "9936-01-01T09:43:47Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "320" + } + ], + "voting_start_time": "9936-01-01T04:09:39Z", + "voting_end_time": "9936-01-04T07:28:37Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "ciOCXYlcnJfKOLbAbmouDwzlXsVaJMcQwHqfcaGzAkTviHrdhCavGBvwJylRwhKnVxmJziEoxyagEBauxCQtRJAkBjbKPtDFeTslMAntDTUchtEMafcZjXRLMbEnedxukoSVXdBdjXAR", + "description": "VUcBmllrPbvvwtjeGyDMfXlbRcXbflWHBmmcphyuiscoQtHZBegKjrWIHynqAavGfREtmozPovxMjSVPSkjgifgFTtpjisGIIZoHzyxJExABEHAJbnbJqgiwoRkltMetUTqepPWIObKKRHIiSKpItUCbRjOdiNPgTSCqZfNvpnWHsoRRoVvZnxhDGiMhTWKrTturuozrNxxcsHdYozilRjUMLlWzQsAMkEBHGoXBPMDHxlSEJFkbNMIJvfkCFffkoVCfdRqXiLlDKdtDGIYeIuEMFvnFgbSHReBYXiLqXjxxyUxvNXmQscryUvfxBEKffCYqFCTQfyHMNAPKXAOyDoJGrWcNhLceYAvLYcLrrnZslLSbTtoXIChAuhmAKFTNiPFqMdGUhFICXTODEJZNhSUocAKZYeiJNpDsqVMCmmWJXNiCHlgvlpcLWswbYdvLrzxJMgXfpJbVOZGmGdacUnMzVFDzFIPCcNDgRddakfhpnrxaqnLoWYQqAkZLoTUrOfDOZEYIKqnQLtoLOLPJlnilZGtyvbjsbuHGRabaMiaolqhCcQnhBZwuGepjxHGgfsEsaiBuwQLXVaqzTetFkhBjlPyxRcHKRdUhAQWXUHhiFDEFlaQXQGRoJksXJyQvNXaZdAZTGgEiqLCodvEDtaeRAYCgIbHWQjZxnymcoxLNPcTcPuzqmkMQWmuPOzCHLTWzogprjvmlBaJmrgwPbgPaAPSCOEgkLjEQzwzQdhrUmAKSwFfQwnetRWvUlgpyykQvYCFCGgsFOqsimhnhzKWNEQxMVMWUVOMtMcJeBVhYtvjCLQQcgCrkwOkIDeSRKSiCAnrVbtOsyWmkiJdvZVQtVYvzljyCRsxxlXhsRjSRDYmmWQFzQoXqKtUwKmWLCgLhtotNxypFVWlsvgDlEUFQTYqPxCscVdYKkevyoaNswFgjASBojZDGdDJdwbBaTwsjMBykMaLomqbQRTeTmKcxiXMGIVXXeDOXFkyzEXijVSrncFNrzXKlYrvhTvSYzpqXFqxPkwIoUSGqwKIbRzpFNSVGCmGiqOfsHvIDtLCRxMuIrcWtYQvVEjLTohyVPobmonNfMSppxmcyiUIhrLNfXKVkwsklrOSOBxGwEkgMuXrvTtmUEdvgAZHqMWmofKZKDEVOfACJhXZtFCriGkKFRClzWCKfoKEnsURoTQXUOKSZgZoMxgbymeLNbWfJnCkssHRdWGfZmcfHCepVatBQcBlSCrcOguBpSjEIykHXPqPTUTRfGDxlxfIFsQomNzumqmyQVedotNGHeJWUVywieUCOyCGokmjtthxDiWANQKBhtpBXtlDPnXadRRzFQWWcOQWXMhmQmsMZZptHdEJjzbBoDefpqqxEKbjbjayjVdsHEDzctMHeQRKkgbdaKxNUTIbhKdDkYZgfxFrErEIFUpXRmmpHLzJdoFAkjmsBjtZxAdwKzYYyzrHHizFJbFDmmDvFjqwcEygJUrOwrnbBDJjsNWoEGbGcHnwpOvofjbJtrklxZiAHDDLqoIxEwZcuvdfSCKCFCSGdSwaMpkCeRTrjPNLzIiqXcpHSWXDpXMqNeCMjrVYESssrBRnxrnzQsVGlDLOSMDwXxVfdtsHuRiIEVNCwqlYicizXDYlhqqlRYtjNhCvTjikqySQDZSAwdnjaBRqewgbBzfhOLBGDbhIybBvpPRRDwcOZhTLOxFuXmLqespeupPDMzLhqBnBKwREKaxMFLiXibnkOtGugEFdOmeatXEjyWCFegZvPryFdYCpeZGLzfCdCuRIokZGQNhYnUTfZbcPXayMMlvWxunaxRhoejeiVurfzhtHowlEuHyfAKpuDutEfAEqfUWHOBGsDbQkItBanRwOwjyaLeedDodcoFWlgiwYbQJSKVOYtCjDbLPRrmysnXwnlBtIITBggcjLGJLwUmiAZHETJrBcMRNytbKospQSeFVkQTOGWqkCzkMaKzVgAUFkzeGigxWpivMnIvIWdzfPKuRPslFLVrOUuVPNTzNvKDvlQrIfIkaWXvtKsgVsVqwRAtyfPUerhqMKxKmAaslLetstNoZwOSxDnkrqDcRfmwWMFXjmoEJXATmZvrMPGwACDLVEoZKnVuIXPbJLAPvCpdbWDkZlyKORNHdeMqaGVALxOiScfaBnjgtrwVJeQRPbVwVmNaxGWWlmPDsQKBHhegdFuJhOJoSJVGPANnhRcjKyknKBklmGoDiXWQIALizjTefvckTDhukLdoPIobvoAlcjjivlniBgGOvGeyEwBXLhxxEWebJPrubzQomvdIyBkbHOBEkCAbODPmBqmmxjrGQgVaGJoLMTeTjayvFABafyfBXCYRbFgwedWJsKtgcSauCecfxvkZFxkailjZPWCrTLDyttEoLkazsEukibulUBkXlFjgEGuvkVeKBcGyHhSRAShmxRVcXGHHPHdneXDhVLzAmZmPSQRRcNWZthxEKvrofXfXGEQiritAEImQXLnHTRcRrBBvDjOciUaDeCnySsvaiBgMFxVHhhKLmRECCYgfEOggnFFoBksHRNYfUYgXDnCGaMliysGZESHwiPZAtJALzMQIqhSFeyfEhFuasmuAXSBcPYffesQiqkWWssiiMFxfqTvYYtEjQMYCsRgqhFGaOVerIRxpZYEKgXJtlcbhwHoafRyOrwgvvmyMncfQPczabeVoCRJixeZNzMOGmuRcwaqqqhALBcOAbUawxdXLqJTUrywxYBjEATBEIaqxXeodQElnSRgeSYEXrtrgrRSmNbtUYQENxQWrTaETOqvqznafIpkBaEhllOTuQfPzEiZffTwFqOYAjfvlBPEsJdMquOMHjilVUkoiDKJMwjfzOHyEUSvGIQAGbiirRzdLbZbjFrGZhmjGRLvraexpMAAZYNAlKHnZXmVkRoHsvyeBYuXDYCdUxgvsoAANCiksHElNlLbzrAUHDsdTiExLbxDLaZBTMEGqxQidJaiFktDzKFqjBrjoMlwRKCJThFophZfiBxidTKTUBjQJidwxppIVZyQitdFSaIZIqwMtePEuIcYfuHdeVzSphLkRtBbRHtoRpgGyEvGrzvOKQFOJdNCMORXusEJmzZykvsQyrRjYThnqPvhDvwHkoYfaEpJveZLlSoFqOHJHnYZrpvLtzAsNTlMWIDBqdJHcEAQfjKZxMyvnUDnYcATZQThzXVjkSkMYvBaXtUGgqaXVSnWdpJXqJjiVcPrAYbjXQiguQaBBSKJBbrBRIfvIOcvcLrmbVWaVLnKFEHgGQgZtOfOYhJIsdWFSlBzoDbHMnoZKHpwlHYMUvjtXZzwOgWnFHAQWSXCOEbSUcFcBzpheRWAhWbHOGeAgboQfuirkkkyGsPzoMkkeGjiQDBHbYbLleEtykBWwggmCSJadzqorlCjDyigWGXUgmvRcpLtQtvEATNtRWpQPYtROpWuneVKvVpDDlMNnJYpCKwhRpmZpHOybYOylxgAZbdPjEDhZLPpNwrGJhrqkUlcqExveVdPTARiskjhlOoENKupyUOjaBfvjexqzKoUqMOEqEjcAfFaAYELGwuPyQUYOoKtZhumgTdgedwWkMTubgRnbvwFaQUkHrVBdzcQHzsWqQYDenyLITdYqbefaXwzImXJZdlTtihbuGcxijSDtbzsTJblUwdzdWUMahxoRDNXxDsJzmdIIjksuurwvLlxQUHsifAmGGXtXsjbuyikcyAouYaimSBEKgNKEUNjGMsLyvuwXIRpoHFBmejoJqkmbrXQUYYTnBipUlXjFVsgpFfBgXjuBHhMvIYwmtIZXCmliCvWJyKSUPDcEzzLmXjgxrhKaPVGLxwAuovfYzEjAxQDcwtFSdIfwSTQynxEzLvCipCWdcDeXRjWusAkVNqjYhngDguwMfcQEzcfyxHphXeaGWxwlQWbcNzjlgTPSNkywyqSkxRjHvIiFcEMbgyapBictzQvMavxckZQufGJFbOJzEntxUgMtPJSwBPflyQCIYBwTlwFNlXLJWQGEcsZeJTpQnCoPmQguioyQpUKQxFqepGBEyArvgXrMWSXJfVaOtZabZvbsMATSLfTrhRdeiPILLNPpzUabILZOWDonSKxezPwVTMdRtbRfSCttKJqWtyuKZmOAMlcWRtpoiwjHzYfQnvQtpvcFQCjgtZkfozETDYRqeOmckENpAYCRGJimyYYCbbEkGXolnotJnhalmxGzEkFeDgBDCFrcWJAgyeqtDYUORXfkwYrJGgGRMwtpIpLHDrqiQDnDajOXTUVEXMURCFfcYUmRYWQOBukLNvqysITusMOkrkOpcTxzINFXmHcfgmloPtAcFWZmxlEDyJXUuDXNPRdnWdcItUKNoIOTvcXsFxtiYcilsiTlpgWkYqIzFylPLBYxqPltksUNtugwJYtPEdNqhtQpxMoBEjcooXYKXPvWMYjJCCYkEQRDKjWNBuYBNuVkZymNVqulZAvnNzxRFhGoQhtKbyRhzSIsQshTBJvdLNSxrzxfDknuszVIMTPEwwGmILpXGCIVKARBfowOHkcQoSjBYQRgrRhenvJPrKsnoWUnZdOyEKJHwYsjZaqgmzbpuvcArTfYOxRtypOatdfcuIauinrwiuLtvblXOtezOjjXdoINXRNGQffYMZBqRZaMFFelAuWAlvzoplwNTujwySbsTmOrcNOkiVRbsODFXSCtxLfEGKiEOKAEFvCttzEJDCPTVMECyqEeUcjYZypVYIQbwKbSLIWmJIkfirVMGynhnYDjNmuqENNQRwlDbtzyOfGwalvjTJUPGGzlLdjQzdtGYhViBmjqOiVBNhjgCdgkivfgSeXGCWbvSxJQwnYtdNrZGAlqvhrYSJdhZPlgJMCYwPkiBSsOeRokwRqVUlInEZQldqPbZzbaTdYaYFRzHhpxCHLHKDxkdxLBKYXdIOfQPZjHhLCCAPFJpRZKaWVaCKHMNWsLYOjhWzpBOawsmZwNTjYIbEIWAeyoPIkiDXdeRUJ" + } + }, + "ProposalBase": { + "id": "42", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24972834479" + }, + "submit_time": "9935-12-31T21:25:29Z", + "deposit_end_time": "9936-01-01T09:43:47Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "363" + } + ], + "voting_start_time": "9936-01-01T08:09:55Z", + "voting_end_time": "9936-01-04T11:28:53Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "RWgNLhgdqfzARFfhQYGcSGNWcnQbcOPmObMiwCCxgIlBFDiSslpXJDyGyyVKMCOZubjCChHfLyprWydGmxiIYgOgbWtdOEuSfJWYUByDZxxmRLdHSIlNlHIEYrqCcBrQgLxSelUMyZpi", + "description": "RgLwfhMdZERbDZmgYTSTULrdnrkAfGQVgriJMHFuMfvZuAJNcuRMGmvqnhxIZSmJeLWQDnVbwJknJGozwpozHmbbljMuAWHDhaKDiymxJljSzGbAjHBGiVvNVgLjdYloePjUrAeYErlDgHzPWWjpyiTYRlkeiRiZbCiWLeDktTCuUZoSFnKjNTVrLCuKVdvzoussLKbqcypZOalQQVCZCMfPIkUMeRPPHeaQIztbQeQtiFXZAGwEsXnXObocoAZjqxFJLCXrvJLtkxeJFTNzzxJKUfRdiAuqfVIYmVdPDPVDgXdXgIbYdRuBVBAWNotiPXKVwGzMYDEwvXaOEKNTEqXIOxyKXnNrIQTcYvGRptIzCeLGacVWStzAYMzFsoTuVsSQQsyXyWQKRvqJiwEyMWQFzghVNOBaDohrMvfEbdvJbNnDWtsFNlydxeRqWqXhPZDaicUvXPWKgAAJcKpdgjKCLZpOioqNaLuMIuiyRSXrEgVVNgpQJNZcemNcETWPZmumgaMeiCDNGNxUGGetwadcfJyDqWHPUiNhqgjcTjXhwNKdazzIvTtUYuOIeUtgCXPfhWbeYZQQIfEPgxmvCmfNmxPKzbJkvbBApxIbdYoQlIWinrQMIRlviTOioIwohPXxCUkyOSqAZFwiXtRQyxdGTBrtVWEfAimvMYZasHIEAmginqvCJfjHnddvmRMdFqPFBiqiWSLGJALhAtCvUhYqgxtMmbuTHfwjcPxzKjALQvTKBFpbuEcUqkuYPapblzmpaCYoJiwNXPzytOTzqkTlMoYVPaJGLxgIgyUVoQlYtkMALMcOfHYEwMnTgIDXgSkHJYZocHnaYGjoyuzKwEtBYBQoevtWoehUHCjQVvrrkvRLglCurWoRLVBBPsfXqtHPWEYiQkfYfwIqoqEdgEEtEdxSicXsawcDwekUWiwnBWpaTtuVpNxMrrsssIjiXiwEafSiBkIcIzQsLfZGQpMFmRAWeyIOheSjkhZvkRgARxVdcBeKJXcomgtIuyFoRxnxwFTLkHDnqzgxltcwTnbFDttEcAvYRWpcLHRrNGUMTTjtKMNJWZuxcPtWOFkvNnUpbkMWBPITNIumwJvRvFqbMhEuesvUHyeoWIThPLTYNprPpKfFDsXeqikaEipvAvEOSiyOWSgnsfDQqycwbSdQCUQeeahikyWFnPFhdGpxIPnqYjJkFSGuJTmQjpkVEsrDGLRwahvyQhEriyuYCNiyuoKsecKDdNAnavaQWOkxnASVBrYwZUGwKsyGlfsinrhsSOcZWFkLqdsfOvXJFPlSRWWjvDlqjQHKiINbVroOszSQjZWUadLHBusGSaNpcRBCXnwfRkwnYHsVQqvhrMvqpLODsmbyUcqsBzxQgovMToyIrUSDhYbsmkasmEdULPwnHOVzEPwBMwAPZoctXQVeFqgfupHQAqacwMwTrOfAfyVuvpozNwbKSjtVlZDySbmRduZQzSZMqjqtFPMDUWTSGYDVPTyjnKxvblNatxxSHnGICcmLkbizHWwTYAUiczSpCIneYyGMlUMWtycqGLtPnwBUOFMVmMYhScswRBOKOoIzcwpYeHUNyRIedmaJrXHfjfRJvGRpSLgbOKFRGUxOQdzBUepDKKLtucVcAOAnFWRodJXGSktSzNyJarpnwaXOuEGrpxmMtBdiIPOymQfMRddqkRAJEGymgEETvwlgRyeozxCYbZwCfpMNbvbyomyVwzMvXHJQTuQSLKRHHAFVinJnJgUczXJqyNDSMxeaEXcXtJuAeLrgJIpRkwnatusNAIWLzxlyiGpVdZBortZhzWLhfKuFjgYotutmXJrFJVcyjcrxplPLXtATYauyguweUDlBlycggtmXEjoNFwpWTbChWpFjWoeLGRaJEFpPvJIogveDSYIctaBHkoxNhxSBFREfFyNmlmLqRPTCoWyJoGibntyUueDsMkkAmdWUXlCoGmKRvFqYkuobOgwDQCpFQfxutKXAFdwfvEIXBVZqdbptIUEwHvCvKOBGVeuVzksppcXBHcNUywIyShmDKyNbtCQelhFQvBHPanAlvhaXmKZycTOwvFrzcnJqTMolokyHQWigDcIOiahSrQLeoXlQlBGkcqByXciEMNhUgHyRmRKMhmrCMjblKmTdlWZjrmNXlNJknvPEXFUUvtAGeVJUijlsBTetQyHItaSRDuMaIXujmFEpuNZNpQOiABuSKyifhevPABUtjdJiEFWGSJkIGACzYverOavjcMVcWmejGKopEiDQSYiYQOzhveWyxdxGoEVKZPbepFnuDLkTjXMTNleQNdbnhaartVOXvvMqCdOihWALlSIiPJNdDBScLfgxbYQnesZwbwPlTWgYWXRvkCociWfojLlnkEnqmUJJYLJASZmLpprdXMNqIYwPVcQmPwXYKUYfmodtQiexjlqAbKspHQdAnoMszaifyflzVWeWCfqUbgFdzaypRgVBsaZEDQLpLrUIlJHJnwwdlTamiIYgfBQkUQvhwBDPZKCkqUNejpAspaqcgwoikybdDQBbxBmRUISgSylGoBKzJhBKcDOzjCYGTcuyTNacCPRTbnMqyCLCmvyEYktTZRUfpQoQZJBEGUGXugedkJNPCVqCzALwIOCTdlUZrkyNUbNrggULncbDXblJHfSBEXblgEvVCFdJGEhDAwwRAFYLFgAMyoXkqaVmTLTwjFLkWAtwzDrysDGeVGzdBzvTCHfEQkQzpMetNcBMHnZCDccoNmxFcDLyrCWaeDboitZhjBlDXQdpcJVPKDKpNOufnlBEQNSJgTTCiIAAxiqEgBkNquHVeMcpnZPiQEwpzQgmFQbKffcPfjHmSsvpDgvtEiGDwcPRjDSEpJZgwfxSpyIkEhGSFkcErmsZmOlLADevPrQelgxQvsgKzpoMxYmKfXLfSQhfBTDhPbdcbMTUxrPgyxoZNZOsYGluaIvdwwiWcgOrtOmtUOPodghLgsIBmpUAkgfDfuzgfydICRKOUfbOnZhOjWuUipgGtjBSSuFRETCoHIjJYFjamLqRyZegOJeSaYhWFKwVCxFTQuwCMJdgwkpBrKFRMlTfKheyZUAYRBQPxMgdWkGZpxfAtUDZriAvizysugrtQhUIiYBBaIIKpnQhbGpqAnjfsIYaVpmGmDpCCwPiDTvFcXDuCncYxEFPhRuSMueFIizDGwUoODQKfiqOXRyTvVYaygOGttbiptNxkphVmqFVYlCuLafrCMYBCSVWtLTVlUewZgVcZiZnpWCDFMDSHeWzsxPsxJvZeGdTGTnEfYjaRMoXFeGSYhVCobWCvusYTwHXYbaaULowtBCZeXhTxkgMPLHYAGiyKGuGtbTUkXXGHIWxobhFjkcJqpNZXHXgdCkYDPPQcYhRNWSrByQBoLHEzotUzcUrmFqJiLGBJHNdSXVPCWjRnSUiYltiTzfXXzQYavbMDJyHzVBcJpJiThBVqRKbxdsjKmBIKirvWiqajEwIMxQcmMvPpmnycSLYjpUOPCIwIbOhMtQsSWKjSxbaaJyIOEnskNhJiXrYCTDzBiNRDdCcTGqaqdKFEyExrIIaWhXMVoWSxkySeKyOSfdmnhlbDWdtdaZVtqXDMSNKpBQFnXZDfmHKDEQNDXvPTYpgZXSxRFAIcZUvwrEEJgLhzXrJSGnkXmgYEVrQAYStcLOBEjGVYSxXomvmaGAADMDmPaPMLIpMAzrxkDzCUKEfMvBfsXHQPDrcFEyBdSIUGjcdaKCmOOoXqetcdEpHlORmLMhRlGeNvPpJoJinglmFTOwPQiAIPQVnTbQnRkJPUjfCpGCDfCprGtqvvhZGEAqlyBGTnoQnqKMSQOXtbRICpREBqKqIJWcnqDcCsARHxsbuwlaQZdDiYSZdLKRmNhqmcVwZLsIgqdEEipJXutkUYHIIERwHoShJwwvVjJRBPHfjILnDiAhCOaThoXuHphSfYyNhtdwznTAZmcnkItowODGFmHOVfIyfElIlxyJpzwXinFEFzEoOIPdKSExNQczCFONAKLHQPlJpxSTBqSwyVZEiazzPbEtVtZscmqmaPjxhFBngYhnurDCDEgRuLZxwXlCYqEPurGAVXNUZtUvbkPdWNiJokVLIMEHkXnrcgJLuHDACdfEigRagWoadSIgAlSJbscxognUChJDdJjpBtZhGsmZrUhKHfymohQkyppPVRUYADVlfqvxEnAvlCBFnHvNgLbVQhJlAqkyWUZSgJDatWSggOynIZBfMYKfCwrlLjAbelMkbABVnHSNtOdkNYJLRWGDUFHesAcZFgxYVfsdCWTdNfVWxeERQYSnVkgkpXuuRUfgQKlhNRRFOSKYFTxURNkJTBWXtSXyapbaFAVmcDIKYPMXYkZFaIogbOYdFxPuEmFqrhpczXwaJHMcjCSMiFaRrpTTuTgJgoDHJNEcsfLBIbqVhMWqKlBFRpHxtGTmYAZcmtQccBQIUtgrUUcrJzmMFmeujwwbyGJnQklLUZrNIxPEpFxgUXNButBkjWhQaTjQAsXaraiRxjgfgrwBzYjGTQoNruMiPUwBtTIUgkxWdEWGZvoqmADFTxGCOIKxLOufVFzgAJnzMACaobAfGsRmPltRWVlBqAFpQYGEiyxfMUxUJGKrJNfyzhrZpeUzZomcmGotRbMRBOjRbIUanahYnkGpWhYyidUslwbxkSzTxrfhbLgoZbwrUgQDZRMHCRAPxldgbHAaeNEtvXUjsJHpKepWTmLzpIQTLTaoCtEhOlsyUqUPVLXMChxZwWvWmenTeDgzzCwXYoNJWxVEVcPwrwDLEJpSfntpiYScuOqGnvZAXzAFSnhuwbpPpccTUQwWidlIUoBJTmsCvOxhxRuGBrASCkBCdnXIdiVcvIxlSQfLRCxUSiiAgEkFMwXsRvxKydtUqerXETdwDyNsCtPcMhehJWrnBNLWXSshdcRXTLLXwCTspmDUsaXvPidAPBbHtpeXvRqrjzrIiTnSswuJPMoildtdR", + "changes": [ + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.850000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"190\"" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.400000000000000000\"" + }, + { + "subspace": "slashing", + "key": "SlashFractionDowntime", + "value": "\"0.015384615384615385\"" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "gov", + "key": "depositparams", + "value": "{\"max_deposit_period\": \"125145000000000\"}" + }, + { + "subspace": "gov", + "key": "tallyparams", + "value": "{\"threshold\":\"0.474000000000000000\",\"veto\":\"0.312000000000000000\"}" + } + ] + } + }, + "ProposalBase": { + "id": "43", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "24914473521", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9935-12-31T23:32:57Z", + "deposit_end_time": "9936-01-01T11:51:15Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "334" + } + ], + "voting_start_time": "9935-12-31T23:32:57Z", + "voting_end_time": "9936-01-04T02:51:55Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "PAlpMWxaWAdEazyrNLgCMQzQTxZKxsGqlXfhDCWNkZarzBykGbxUSeliteOWkorRQZXLQbjgoLRNZtyEtqZVYOLGLDkMNkkUQjySAGabwCFkOaKTknAyJEJrXKgwzWWELUFjvtpaBSBY", + "description": "NyJemyknmQAyICVAiHxtzvXXeFAojqAYZcpPlzQtxliuVAxKnYIDyRbDiSjkbQWUIDpqdNldNQbXQoyyQsDzelXvXriyISvuTKPaJPZvRUNomHAarnLVGHQHmPooSKUiHwOYBFFUhgbyBaNLGpVjXTKXMFGyAWiAXYLagAcSoUAbQsWwPAQceuJMaEGwPLQuHvtAatSfMwTUClqDyCjcIDgQxhWLQYbGxBvgktFmKLNCNxWReSnIPgQJWNSVuJWLBmUxgwEIlpskZxisjeczrprtlOGVkaOsDUFAgTwMoOiITxvaLoLHFXplkOuMUbrarUbAvqXpNNOPFFhfKPBPefTLoETMDTcaxdSCytpjxtjsTVTetzvLbYEGiqLmbhhOKIxrsjPnDFIvZTZlkealDaSYkmcYEfSbgcdCLGzEJvCweISQmdrmawXFqBgQGCrGhHGnmygwkKjogQdVnPohFwsXkivQrVlomsbxCdhekHbZspsNtNvUfGBxdTDLewEQUGeqMFRhTzPtRZgxikBorsPfmUHZmJYmgJdZLzazmctoeiXEYMGPLRrkigEQRbqGgOVWJislSWYWwalgaSwEopaApIhLsWtWQcKBhoCnsjiyLaCKswHLYYGzDIhudEvTqnvpXkfRCdZtIOFkskXZNzIVJYMQvwwxWzuBDdaEcbEZQZRDtUJrDEUqIHanzPjlOZSihDiQDIhEqpSvUCQuWGGONOCsAlZKeayjxSPZtpnOYISmDPNiuZxrqzisoWIXBqLsulWrNkddCoAfhugPOKZOKkxQYWIfnVtQWIrnkxjOhXhrOCCaMxeHOHRLKLXJYBKxaCkKprNfFkfEgYpAptzGkXqbpmWbxZSUPMJQilyaMSZSsHsjgnAFJrybiAPwCIwnvtcMRIpMHbwWHQMTQfcDJweTgzIfbjuadUAWeJLWXjFcoWaxYBQDqlWQpbeCKSnlZnidHsPzqCRGBxTvAfJZWjLIvxydmNrSqxCcibkeEtMtCjwXPGLvooNExziHpHTMEgSsKNDaSiOFpCYAeZPixFOttxncxPzYEjuoWNeRFoUmqLmWalCkUalYtzpqEprljhcxhXFPnNdcMqypvFfjvTLEzkCRQBeFUzjClWanBrGknKSeqRrwrFahohYtIpomXlCDrmGCVDwUQPlThwNvBIhqigpAaXzssBZehsBRTedUWBaNZvdsfZpBOPQxOVZcsUWXXkEIVquMjtcfyUneuDWpPASpkpGskTSrxIoMagAJygHDONhTIxDzryFGFpZBzCOpuJomeBQlRWxwdFQqQMNakSLhGCRPBwZyzeGKmEFQQhYGmEUxFnTCHhijocVkzaJdbHXtzLSfFZZJGIzwYxbCumtTzryZSXzqCFwjrtMqFbaPadWFVXPjpOzYkxcLulNcHkHukqzrlDuINpFdZolxhQJSSdFYPJTQSXWNIgUnqveQIMxzMGtNmROYNpjfLoiSdfXJdRuStClAjeaGCTgfXTIhOzVIKCRcpXZFpKJwyQQULrMDzFwxOrjThBriSjBYHMkQkFyZWbhMxLyBtVVpKyumXgPAsNOLrseqriTdtIAEHLfRllbwuwofiHQuwPTssxKsoOXqMQcwPKPtOOJFhmFGxWdWaUIUZqMLpmfroiwdhxnWbLolkkwxYJCyuIXqNHwrKDxtigcxNAaFPUVMaiOjYgoEwbuiadIHYPtQlQymNMUtBWkFmpJIsuUUcwGINIdKzOsUQpgzPSFwSynuDGKzgtSkuVYizsLGzPLdvCtCLuiiJgkYbAlueLigWBzkRBKcYyquaSCTuaHNgVxJEVqASoTFAtluaNkTQoOSMDFEXQMczuvqhLQydtYFjFWHKKpBTWjRFwKwJPaVqntRwjdEtijqHWNAjiJdxqjIVlWOYsPFQmecNGJzMysfRrlJrKnRdBcrxoCCCLCEUypfpaALrhbOyPlHuuaxGTZUKFGmygsLLelXXXrYxYdDhBGhEWhwjMvWvRamuUKgYezTyDqFAXDNFPHgmXPQwpXGvEnIZFJMYmDkzaTALrlFKzDMNKIaonQNMhmVjrenGOGvikmvaYicawnkemhDxgZuEletHOBrPLxiHwYhsBXHWoKGoqMneOOkOPfasmxMqJcAzNzFhdQNXuXbaQtqvEFlJddizgHrwokTlIxyFFnFqsLiFtibEiaEeOZEhgphFwvrqWaAGdBoZghQePrEgzIIMvqTpaCDQcWPNORVXNpCWEqhhMIuFucmiHOTzHMhftwUwYWxCzIKcKvRAJKvIBqibnGmbOtmJquoEFzVrrVPCtOHnfWrQsfsUxNehEaApGCLrdKjOqUyTGcVxPiEPkUmIvPUxyHlqJjeWVhGkUpSJtzjgpUOSWbkyxTaWRmUnfAPSnNtaWgQbbSmQHydqlSeQTmkpEkLocxvcHkxUhHYAFKPdNybYmvycvxXqZpSCRhGrRNuYebNoVgMgtNbvDSdYpbDhwvmzoHmaEweugHpJkSzXxyTKUVZTCFoqIGolopzqddsXFAXklfrHCqinNcpolMGGMzPAduFQJAEkolPxosaqGdrKKYdSNDeMNYlWuNZnihMmCxWLQTvnmAmyAnWfeIhmqkYjXPCeoYbxoHaEKKzhYHqvroxOKczFxkgLqZIpYAhrPJWxSqPGuDlOHWPgfkbtnjyxtQAihUzPimOEbvtulYqFPOBmhfmmwXOcRlkDVquwaCbJyFzPyzQYXwiGANhDJaiMLZABAQvjuBashYknUdhgtSOvRhSBZUFROKtZIMBBeIkdeyfimVbdqSySmlgFKhCUAVZzgXxoFauteAnxLzOhrkQkKSpYhlbAqeEpUqPqyDZQOIAqoFHGZHdBEBELlceVKmqaZSUyHFuUShAmVEtbDkFXjsAFGLsYbTDwPpToDbvmEfjzrKRfrFdqZxciWrXhctoBnPKusMNYSpkWtrftTPMwKHniYRLOdpOUBYSYjQFsueeCDYrcNYPNxlQbiOZfubwethbkrQWFBuRCXRGIIUrHfdZkpTizvpqXixocwWEAvDPAKPubAJNxHagPjAeUdRtdJlwhMNsIzEXzLMeWIAjeSHKxvIhwefjMGAFfmoEJpjCgVanPmlTXQCcpbjbIjkDYTAgEdZmlLksCIrIhykIxkpFvHVnsKIAHqAzGvxUQmxNjEidXheybzQXiyakeMjtOmObdFzEyvwppcjNzcBdotczuziRzHbrdvWWqmBOCmQqRanwHDGAJyKgScqtuePlqClZdGtFlpdjCfEcwZHnSSTekWyEtdUCMJvPJEmfACAonhveTagHxnDuRpXflAKcPalNVDEAnziiTDfesjjUesVApWTyhDujhbirjZCZvaPEmSfJhRiveDbmyllaVPKQFlnbzkNSzKvrNLQWQRLssAVWDuLshvEmKqJTKEbpUpEZyDfhpZvfRfUUxCVyLEJnXdWdACnWWWaVyVuPABrpBqGjEfXDcvnNVUuSZsIdqBRwFzQJopKchVMYYiKgtHdzhilFlMTyhxgOfNwBRtPbiTOhOZwaJybpcpInVUXEnEOpNhhAsTmTdbUudetwymiwYqAnmfurrerHnjzIbpooezqbyenJdWnBldaxjcYcgpVxLUxykKlkCwLZlRWFbgitUPfdozTmLqsvONNfUsdzcbqAopxohekRhyRNTPRdrHAYHnEjIRYyFORsytMqdlDqikEJYqhUiJAYOpUdVGfRREhMLiHbmzJLnOPkiApTUgvifWmJVGJBXrkhlgsGAtLGZkHmKubVKvNqfrpDwhVeBoMzspwfyFDghOdwqpNLLPEqeeKihNNKtmPgfiPAKKBYVaEsUAWcgbJyXfmaHDHLPyNrXobMLZPivhKFiaLcdEKjUsqxMkDdbAClRYFUrVYRGAlyxCOAwFHTpODCmstEqyzKxDdwDQtaqoZEkCGWfNtpfDywsUVlwcUIpIgJDzscfLdDYKMgUpQzQiRIaaLqEHISNQJOBuLnQHiVnDBleqUaLOxMZyFPLvFDsIdpEbuoWhytBEGKDFPtuIHKJrCRWhKpPbNopGAYccVcnIlePLSrRXjHfLfOWBMvBIXWMzHZOraZsJCYaXCMXjUdeAdMRVEOmimfNmtFCaICVSGzWduofeVYUxlexavtTMEDeKPQVgXWrSGBugLACQImVhvgvFYDRgODRAawnuLPSqyPqPhvaFZKJycobxaWpoONYfhZGvPwAszXhQFZZnXomlVRggZLqdZiKTzcXebJbBQyXSbOdVDVYtYOIsYuOdgrxBjobpzgjpoBYZCBLGwcnSuotOfwOcQaezBgbBMBRWGYjEvUFQUWOhtpEAoFtGVjLlsKnyIfZMzlaGOrFjychfDAbmKlOLDwcjMmlTNJPwVcztnMSymjstgSpvcjZbTJbGxRJQtEsuQPfdNOuIooyrkhGIEgmxOSvhuRETykXhZlIJsMuPfFsWHxGQrOMRCsrOuZIYwPJbDoDcckgYkNqBfdVKjdVQhTVdEgJppnjvwAAzvCFYTXJIaEUgSxzEPZssBqLylsLTmJFDSpipJQnwqyyBZFryeMSuQcsEcTzRvYEzkaLlSTxbvqIHRChdpvlgGwXCCulOScGhBFcKACmajSsmauxjiwrjVHSTTgQAtcmSjcGWIzPADwCIGeARxiTOwmBTIssIdkACKyfVvirpUCHhWzreFzrMjETJyAtqGJjKenltoXmtgeuWLaPoFFZScMXLmSCNnCQMnxenfJcFghrvUptXxoCtYVTckzsDqdHTQRqiBStGegASJNzZrfhZIIGURqhBPhBSWCknDkHVxJdVotGoDrwcYqDrLDFBFRdfICudIHtwUwryBfZaYhiCDkwVNiKrqWsHaClAtIhtkZWFvGWrfijuuXBxYgSWcUKGKIjcgWgtuHjZTFAFhZgCuyvTZoZldHPFHYZdBhnuABEGSXPEjhJiiauqAXkHXEECuuPqIhCwdwhZCdlCZtZtJGkOQXKGHSKXIz", + "changes": [ + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"129\"" + }, + { + "subspace": "gov", + "key": "depositparams", + "value": "{\"max_deposit_period\": \"136625000000000\"}" + }, + { + "subspace": "distribution", + "key": "communitytax", + "value": "\"0.160000000000000000\"" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"487105000000000\"" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"10\"" + }, + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"116272000000000\"}" + }, + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.190000000000000000\"" + } + ] + } + }, + "ProposalBase": { + "id": "45", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "24914473521", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-01T01:54:53Z", + "deposit_end_time": "9936-01-01T14:13:11Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "223" + } + ], + "voting_start_time": "9936-01-01T04:09:39Z", + "voting_end_time": "9936-01-04T07:28:37Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "TmBxUVlJUf", + "description": "okbKXYjboGlKJuMumTFkAfLiJQFINYgNFeLRbZzMIWTspqZInwVVySwLUwyKPhEVqwLXcFnGFYRQHHKADEqUizvnZLPkInmiiwiL", + "recipient": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", + "amount": [ + { + "denom": "stake", + "amount": "1789097633104" + } + ] + } + }, + "ProposalBase": { + "id": "46", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "24914473521", + "no_with_veto": "0" + }, + "submit_time": "9936-01-01T01:54:53Z", + "deposit_end_time": "9936-01-01T14:13:11Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "375" + } + ], + "voting_start_time": "9936-01-01T04:09:39Z", + "voting_end_time": "9936-01-04T07:28:37Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "NhelLubJEyWlLPaFDtKNAfdxUKszgocvKXifOFQRlCyJJrMGdhqZSXJaBRwwCkNZpBAsrVLXeYuUHAlyRnDGgUpqUsiljYvEyUxhcbkxrJyqeAmxQdYXWxbgBmcCIsKGDyNgmiWeXOgB", + "description": "nnQiHILMvvxHBVbQenufzeOQDPEyBzVDqeIQCVdOWlcXVQXKxAjHMguuckObWeawsKHFqCDKbZCTRTsXnnMpnXinukRocUKMuWRMKpeMaEjtjIDVgUCYqpsrhLNARHffROjdLriWoTVZBVSbWuKBMyKHOhGwqwbOFQJLeOdECkJwCoXWlkgMwWCodBTlxlzUPepjzzUCbkkReJoNfMsEbJCotrYkOKtgZMxINVuWmTeDyEhsGUhvBycAgOKfIaYMehVHoXQmfZtmHargmYmIQdDnJkMTcplEyzmZUbMTnxnjfJKynxhraPdUtHVbgRfoKICrdBhDjqPrgDSfqshBVpREWFGdOEIbgVeejQPaJijIqGpwCApooHIVlWqQpnctEcKSMrPZroJPuJNpZNFAFCCFiZVaqLdGdZdkOrhSsLopemsTCUUpHVgGAHNoCOCVTMbfnnRachuPEjapInuOrZHmmxcWZBfmXkRzqalTmxTUFpSeMulvZlDyccRdvSJurrZfiRdUnTiBIAooZMRzwdYGasWvprnVTyTSoTXLBgeqpSNufekYZxKVdlKkKOxihJrAkYByZcsppWjVcmYwZtxOJSjzEbKOWSJHNFwEBarSrRgbFCbMxHTPLDMtcuWCzIICMqRtWtTaMuRuSoqHOYFLXuzSdVnUdjXKnFLVsaCEsknBNWNmtzFdaCOQLrjCjYrsiXCBebCAosMTHzqcPuIBrGECdpfUTOiZexJHKCXgKXrSnQLsQiPaXFYzpPenafsGENmJZFERRrQreDLvgCykapHbXeDGWlteyHyZyUCInEPgnzfUsJOnBUqwqSpdbsGpJWFmUJpFtVtiRoByJwBBEvqveflxxFaAWfRZyehwFCdswGKRKsiEaTvhuTKxhmDrxHSmWeFOQkaluQmCnNItkLQAKFrqimYSzRTeENdBQqpfBoZapvcUjErUaeirWnTuBFuxEwOvHJAXkUsfnMYEzcfLOpEMiUqMsHBXYebOQEGvLXdUVGZrLUNoJQKuljUNrxKnbGZYMYsHXfTdpkPdyPcUfmyDcrXaMkcohUkJgAlqkWNjcQkVPRPysMWngocSXWZSkVUdsKLANaZEFKNczgCvziyqkmMBfMSMAhFYReolzZmTjWQEUhXpAEMtbXBVeOzqJMPVgzVeRCfEfdKKXHZJePbsctVLfwKOJJLVWRMvussiTtHdHLSeUsMgEkoElSFaBOAWGwPtIAiOucjgFuhDeiIPRBVbmLaEbgiwcBScCjpZlVHncLXNthBoaHfIeZUoEWTzHJwtqxtlTJPrEACZidxUIUGMgUPpdOVclpQYNWCbjBgLSzeUlSxhyRLAAUlkKukwPPopgRAQaMMLuPqgdeEVXslgDTvPUPNyGrcOnhBiuukjzAxOmmeCiSCoJTyIgizSQsbksBCjVvEiZNofhFLbVJweatAvhkcFXuzQMiKjYlfJLtmTLOqeoQdAIREGjqEGvHWSrlMAnCRJgnxswBzIjKJlECkSdlvIjjppZBZYfrijDmSFVxQMRtYrJUTiSyedeUHODfETDAIPXQDSQCcnvShImNHCvIHxjAcFlHWLlKRIzZgltOgkVXogKyqJJsBJbjMizSSWnWGxkSfUAOaKJrHWUWwhHGNdNlKjqxTSejMwmbecoTiPMPSQyfcmRgbFYsMuhtxJGrtBmRHZuTtBNTtqcfJTkZOmrvbVNLOgPRGYTRyvPCRsDPdfrQToMErWsNvQQPEXjYkPwVecUFPwVwkPjvbsNhFBqGnltvMPDrchlyhmRljekjnKfXojmLaPmrnsDczAbHEDmAEXnNbRluZRqNevsXkTNFrZlbtrIQXELUpqiZehzxykGvrfAiczOBQuUJpcSEluOvAFFhoIRiRRtbMHxYLUHzmxaEhIWQAcQsZuqKHMocwWRYhYaPQHmkfhsehUZSsUHuhkKZCFcOStxqRjLRjpwYeKNDgdrEZZHbaURKcDFcNRYxqnjZcpXyibdpfUVPVLhlLZgFKQdJzvEqVHxLtMmogecdeUrjmnGCPgwtSGtCeyOpqBwTFYdXyjukqTPoXzlpqgRVtDWJuHaUbrQmqLNqADSOfLHWJzVhHgcxyLhjMYiaKLvrVJXEUqIVhtxaaLZNnJiFtBPwvdhWVaWtqfIKOIDumvYGDsFWfdokpDFFCfAqdhEvaNzItlkQARupxuySKagbjMEjKdHRCXzXtnnDlFRJVXuJRLEofQUbzyQFTVhTuxkWShqFQxmEwcSsjziBoorvbcJHaFXVHYvXREZSyzKQnqlgDxjtFejDGZPPLzDqBFJfTdmTxTVCzYOBkbvLTusONPMLUdDuGpHzSJmqibjwPoZQeEQTEkSSaOBlxzeIAStuorgnvqGSKxbaZNqiRGfomPxiBxEzQOmtoCIKPlZhEXOXOBgwAASwHokjwQsbBcXRZqRMlnhhSijDkPQofQPTkSGsSqyOpVrSUnKCymIdDhdoBUTvQUkzGbxNzDKQmHAMlMtTlwsfMlDFCEQqgBzRVnRcxsczNLcxTKYcicnPOlISyLLevyPuZDgkKoUnogVjGHmebPJtSGvwNTOLalrHlCicWnmavKLcvBhESSabSufdUsBXXNrhmPVhAHuzSPSAmNxTCHDpTtRCEiSAAgBiEhJuleiYjCGhGSRLUPJMdvKrPowXsMYJOtThGtZeEZoWaMawNZwlveWRahDoihegmTBYVHLCqVCCVjrmjrKyIgSxAmFbGOazzHayHkwYCsforfSvXIzfIxfCRVubuUYOLAQmZJChhvOzYNGkyoDxeraWOSPdYJdCqzWTPJKRdCdhLIceYDDbZASgKJRMgJjNUTZGEHdXIBAuSvtNhYfXxBnyvngSgDxXcNAJKVWmZVWlREFvswUQsgImOsoYiKrxFqgSGRUUHIohlsAfJDysYPdtXmEALuKHhJDgMwXmxkLhFMupeGrNZEUxSpvNFNPBNajiltTKLDmMKnGgwbwkCBhSgsLhXHTnsFvBBAjtfDluwdmxnmdiOxSTLwvzwsJliIdBRIcVjsmwjEGcAVxLzJILOWOOfgoNFqoxteflOmxpETpQNBiURVawFYCYjNKDAEcpLLnYIhDMeeXJPSmReCxhbGoTuWVFFCqpgAEdenZBCzlmNHXSHQmrgpTaPKbILOpwFgMCkBrhBvvkzrDqAxylHkeGeKWUzxDARVMooDadsrRhflKsTEtbOkDoXDGZZEjjqcJycyosnUsYfdvsruBUzlMrFnEtAzvdDrTJAJLmDDgErJCJoEfrEADasqdqZbQQRMwLkQctcLewcCxPzVcYFkytCYETpnOKyOVqAVntqSzaZLdjEoBbYmHVucPfaGSKpIUsWlIRLXnPwrSOcAyIDcAicsTaFjlhMdIohFBRMMjkJZVJmqxUukHcFpfLlfQcXNaRrFynvTiKgjjpHAKZSPnoJgudMQVJqBuiSmmSKgkNgHqjXKNilCEzIHKdOmGcmXSmkHQCIWzRdaxIjJGUHxJUAgluPEoseNzXdsfVYImaKPMHCNfifiQOVtdITcKGhaNmUeOFkrsgqGmjLhxxWhwpSlCMvZiRvLhCZBVQVBSduNkbaGzWFLOTiULkHpsJHtwgQahuHVTzNkFYpuwsnNeGLaNFOzSaPypQlkhmZiHSnPIRIRLichCSDguKOCWXFAdmoVXPGEcsyEeqjNBBdeyReizLyusiBbkIAVhAHIvyoDcsbhoRPpRkWpNQUDuQczodcFGIEFzNbjSnmeOPYYoaeDfUJQpMcwWwzvoNodyCmoGixzvHluvDesapITPrKDZxegLEnKRAKOTOzPaNziZhHZUPtLDcHZdSrbfhGVPrGFxRnwFJgTiSdXzXukWIgfpQUioISTjOjrVMQZmziqMnSunNTPDgNIkhFlnmyiYLFFCxxTSlnvAAqBEgkhJOocSjgpFtfJnbGOTCSAVTYyNgxwmhtHLKhvMLYqKkmZtIZolGXKxznaMnXVSfUGUvpRgcXZOVmwfoNoueYLaAOMZhbxJaoRiCWQayYAzNHIqABjZApoVeGauxqPuOHirgqeeEbowQcuiBOBmNGQDHooYKkwsYXCGkLuIaEtTIJGujrxPHpmrQqiqhCqKdwiGcKNSiuITbxolPZpUOGuMckPTfKnMIJawvGAKkXumknorckmkrImupnMtVgkwMEqveQRNEvcwseWUWkogJVHykbOuGPSMJDcarHiYHUMIIGgyoLykLtlWltWltljHKUtYimNlPxVKsuEquVobWotZxLKrDkdVYlUmrrgNjfMFJEWlTDgLJTWWJjLVypjzPGTLJCKUAAXuqHXCUNZmiFXeBIqgiryPkRCoJZTCQRhDVSbJxIYDpmSaxOuoLjLvLCiqXylgeLmuurGFiiGcliiiDycxPZbkuuVkQkMKzfihcKEZLpGWWAskRnIXoMXtQQGtjQoHsJEvqdkeQcKldUgDMsEUbHBoliSOSvvfyvWTffERUCTTXdlSudHgPvfXzRoLlaMqBRWtUXpcbTHPblaTBbTWZoQDowjNVAJBhACHaoIYystezEpVBBWACKDtBvqSMKvnbEfubSNsuyecipKAfZJvBpAEfVzTbCQeBMVhmkoPgXmjDSCFAwnNofvzulkZlPFhtIqeGuEyljewLaYyVFooJYegKiZlJUChXEooiNSdThqvjcDMDISTkZudHSrcYhtYNQGISEVQpftstGiksETztzTCnxJwEIDUkVPWYtCaQsUUXNfMsuiVBSJHMocKqyyrwAGmjXCBoUNFHQDmCDCpcnvSfYCLyBOUNCjtWvSOqNochItHPxiTMlEVtyJLJEyDHXXMHEFIKHpMrGOMeNGCtFobbblbSEBBKzAICEuudJHpmKRUXfECvOeQvnZOsZgoTCloZeZvufajpDDItPOJqqldOTnqhjAJyayrXmavtiVryTpwzwowSqTFbAulVFcYffuBYNxOfVBFYGgvhreBORqlHrxNqHpDlNC" + } + }, + "ProposalBase": { + "id": "47", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24914473521" + }, + "submit_time": "9936-01-01T01:54:53Z", + "deposit_end_time": "9936-01-01T14:13:11Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "321" + } + ], + "voting_start_time": "9936-01-01T04:09:39Z", + "voting_end_time": "9936-01-04T07:28:37Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "DToYQDMGpyahUFEyImhLGAvtpsDWSgFnkZZflACeIPPoCIedCrUOjwFQWDrdAqIWZxAcQfmrowibaMuHQwkJRANqnmJumoWAYNFXpHSZHyiQOCrUWHiRsCcRROijJJXOtTsNhfZiNyBo", + "description": "nTnficHzaRoCdJYEGknqiWTzxZqXVLrUvImOPmhQBdesnBLwDvxqfiNBYtnrzgMCiayMVaMKIOyCtsyfmYLinFkgRUsuqYToIThCNdxKyrAoDxlHTYfQGdvwqakOIVOqGmrQYRpzsLABqJKqgAJzLYWNWWSEizejWezpNRTfOPkmNuIkCnDQPUTuLOLVDoRZbiipqIjzbuwwMXqjUSwYmUGYcliaTNPiTnKybXzIgXZVKraeoEiuXztUPBszHPJdBsvBFkEuOERFZmsPiKHjjCAXKRnQModQpdzPZXyvjgchtIbxuArzCgUordxyyrIjtuySRphvfrFAeiZXGLJtPWKXiSFFAQXxcfwWzBRqmWYELKmgJotOUlFBmZVtDWGBWYLfrxFDEABGgsbXZFSSXzCwZxOnNXkmwWFaWKIhofUvGHtjFLglvmdrteAAKzOISzHrRcIHIpvetvLtLISGQhDZcXqKaLcXbjIYcTPWUvGeIlsihkoCyrzkfyQVfCeonfwvSJBdIartZoOoUOyAncfUtotkStNAQRfhmfgTWZvJuHjlXfzFUzARCswUIQEnyedcthXwyYEEcOPRDhTHwmsgqTTbzlOuyXFUDupIqWQwDrBpEuBumFlCfLojiqxiRYmQYeLWsXDNCFdpqfEsdPLiINxPTXOUlFYeYNoJfDFOcFtJtivjDGUiSJAZbFvbefrcOUWQLMTLASvHQvkmMDywGWhTETrRHFzYoFDUFLEGRHuCLFtEJYjmtshTTRoeptRghPjkAfabFswUGvmcLYBlSGKgXbebmyssyCpfftBTDZeHlZxtnqzvYtmwtEJABwsESWfxeQYLhUnijnKuBOYeCdwnrSiWrSkBPSXvvGRnvMsFARfhpOQdmnWiWaaIvJxsrDdGaHgEZfojTDTymNnfwDFAveBbValRYQnPHyTLumEANVHmncqQapiunlUszTOmrplKKrOuoAPvPxidBNpQpiUHmFnkGBERaRvRBqOiuarUaJxTItxPfptzrcnfRzDIzSrZCpquKjfpKTGzKQzKKllwRtoPGeINWjYBUOhXHIlFoZlhjXFHfVfUyycnHAYFQYaOXNtcNnvIgrJTgrPgBMnpjXocVuQzobFKjQQWMaUZgtTblQhOOQeUOcxhumNDjtoBOrDTisYkHzYHyeWcUfggNsihpRcLbPHdYqtHceJAoYtEHoSJmuInfNQiPAcXfYYPduqrCgdQPtpMDFwFeRDoYlIojAHzPgOYJotjfxEJHnnrVoHzBmZLJWJZBHNPnmwmXDyPxuPaKDwXtLSmrNqOfDdgrgONZuiiVwOOBKlBAgefTNRHZvvpgpJeEKAZuHrLGtfsxeowhIDTjSRFDrLLcGipGVshHpbpdymrTOWGlLrGhcLiDmNoyfvzcRxUiILpKwXGovMKenamTyqSOfPNZFatveFeHjPxoxiFdmFBisnTHVbnUhHTcHRRXOIHVXjDgPnGvVOkwmUhsnlVzhFfWdTdFNEulJSEeerOkZJZQPiTfZXKgaNqmuMoGACyOxxHjEyXrxWCPVTAtmLVfJQvTmgPIgrjJPUYHnRzwJOqguLfxdMZMRFaKFfnGwfxCSTccnPvicjCMQQsNmxKKADGWHZFkGDbPFSlDdGyGPeoSarQZMNewqktIAeltWuVILiyWDDqwsPKFwZuBqSpciepShtcHBsGYQbGcoMoHGmhswmmJRfdotQOGWvgrRzBCMWeQKwpghFNdVBnkGPwdZRoCvwjfLRFmVsQGzqHrJjhvAyhavXfzQYqkHAtYvvsUtswZzNWqdijnfNGlylTZDMdFPqEesrtcolaARJuhZbkiepBSCMKcPqIElJFAxclgFabPVSBLeHFSAVgnrbQKdsMeFdRqgChxtzZCdHLNhOuHxdXjfvSMjMhpeSqljtPZoGWGYcFxrITuigGNaCZfNTMRrQbmazdGqvfcoQaWbEvXSbuCdSTFReAlFWEsBgukQPasiZOZKhJahpiNsJnvRnXEQYxoGzojTdicKaBkLVxHUycjDphuVGBzyPxkANLuEJZMFEGXGjgPwNJGGxTyDJFWUlJswyywFrTCQgvLxyVfOnhauxkMVOapmaAafFEhBeWluralxDviLDObPywnMHyNomZPdRHUZsCuRlaRCHdGhwynxMcLzfdLAEHjOSHoheCsMSgptbmbCTcaLHIsIQbqecfNgbnupXrtpcFRPAHmmDqsFTgQzLvrpWToAcCxuBsoGvIOzSAINAbwgPsiiUvQiGxMrHRzLXehWEXfQWEhuStPFmXXYwRDAKsmOTtwofhIyfMbPiuncgURfkutgynYxYKmQrdnhspgSZwnLPUYceESSEPtCdKFqNRrupuEcmmBFCCFRPfptbEBcBafANALnVlQVQwyUQHQBgjQnhjHGhEpflOGSJmnMwgGQOxzajeOUXleNZUJPlKTiUjgLDnKWsSbwaypsnGAnjESdHVCTQFNUSxPbycLalvKhkrbBQLwqXFtqPJmqAqwAOeQIINCksYFMwxCCwwwOpseoFyFQsZQPZalUxiIPchzTXzvocVoFSDlqbshoWxUFMwQALNqUwtDlGIXCNBhgaLyIBeDrBcFwXeQPMjoazUQnhJRbiuUddaWlKIABlDjfdOTWkaxiuzIPbovrlJSBmIlhkyYovdXKqsKOtzpPYxEvJvZuYkfxKkRbNalNkqtLVYgBQzqVJUrGGNElIakBgQolxHzlVaFmrYKhIneZmgPckudvFQfUEmBbJAxXTYlcaNWPlHWuSNcSKVDeDSBTFdFrzmxvMhPRNCSgHmeagRQDCLSHLkdYWTovMCtzxTDeelgOjklzQVntBHuBIfZkaIhKbDpoutrYRxKVRNQcELmpguNuxHnFtrNnehKpNrbtXZbgIRxXrGZRJOAKBEiYUXtMLAwfSxHxzGWIqZXwaJMYBbFYeoiCggVJrWVnAPnsZqPtBLhJPUmNCwBKUxwXImvVKBUQjdJpkpnPRRqLTDxBbxxhorrKntVOurUtGsgLYdvigApLgwNFGisVRVcCZukKMCrEUpDwSJjCsRtwKAxxbRWDtUwzOTJjCAYvrssdmyvMTSwnKoOpTanVpSYkvjPyUbaIwKELDilNOIeOrcUSjBhbbEyIzbALbzyTZkPsafcsEykhGQMAlkZyjxvfSuHJTgkvsJOqPgPIUaahZFmpbXnyetvzJGTLeTNZsbnkQKiyOjDmAtesUgBOxgFYCqNDOusgKSjJsfTDVcxEZlwcjpiPYQZGyWbISDLfNMCnYcTeGiKNlZUKcvBgqkQgwdTAdfDgMhaIQRUFyPtKKuPKCyWACsbPBUXktzyMYFTRAfPawHwOfYDhmGVwXWCtDFVInDqEugTDZLDIOSLrnmeICqdcmXTIxMdHhuOJjzxkGEALHxwwBbOMVDqTKTcWGMJCeuzwhocbSHKLpFwwSvjAxwPLYMfiLioYfpypLeSODPvgItUQMyAoVbxoWVKqSwRgdhrDYYkEbmqTNxLuJGyFqZHEaNZqUYZtgsUFmqannodZNVuGaOHhKaQkOgzjyMhBKfUDTAOfCXVFiWCRxDVgTkiFNjepivKxKpRqxccKYDwGALoVHlRarJUfcJlFaamWmyrCbyNWzQflEyMMWPaolksNPyORQGcgfwOkPedRIrCMSpNgEfqEABdtZNhFKWJzumuYsMoUudZrxyBHeSVAeZhEtJCZkKxVtQNxAwczYRAqOpvTjMqCUATTBZLBeEPMACjfMDqBuHylWKECMkwWEAOXtxsoulvQsWqOryHUukAMwOggduIiZtgOzVqrPLjpjmhlIylrYCVJzNoLuvKrvlRNnIcyfwgkdHNIOtBPCLmzuvuISkWlzMYPuVIsHZBCTJnqyxoRdBYwgffbNEASdndQvXcxJQJxKEOKRgTBLUswiFTpyyepsKfmlvgpBVZWqJOzUbgUyvUuRgprhPcXoYWVJcDninFrdpwTouaXquvyaoXaBRuHMiYKdbGhocHxSznKCwnxAuwamTCvIUWSHkcAmPMvusKgeJcRNQdHyvVSxapwGyTipKqACWXmIPWowTyRrkhywMuDOiusMArXJwJdJLzRBGyDIjeSAhbCmNSWhhLWQpzsIzbtENheFUMWTcfEbIxbLwqcdNavyEOETRWkLoOtpAcWXgdTaEvyuzyEPhjMYsgkaRTfnWOycfUWEcFvGWKSYkjxcVrUBPTWzMQGCMMgNXxEpiWmKBuzOfQWGAjeZoFdZTjtMzutTmgIuXCseQgnRlPAjZRhtDxzMQEIqhhmcVdLldpBSodPxTMVhScRDzgkifWOrUkYdVwPmGwLjEAwRjXfLzevNRKGOsljgEHXDeptoSAdFsflhdsDSXPRKFMncRuJTGypTkVWWFmhWqjbArBUzKJJayGKyPCocVGoIEMYhMsJPcLzJWLVDJRSMuAwyFvYjBXUHaQbllXjTxocZrdwJSPLEXQVdtuvjzgkFvdgtqXcAtXLOSThHiPcWtXQlyxyBWQHzgpXnXSxmaeKbpcEHaWJFVLtnZzSTDcWSDNJCUYwynevCcNQpJsinZJoYARSBTGXfmOoOYrcWScUcaFeDwzZUzeRuyMxVgJXuysDJTMGwkulEapwpVFquCQnZOnygpVvVCXZZWCNbSiKRXXvJsJfshfPhydFoKzLciyUQjfYmCUVaweJKtyjAJHhpsWxDgYFOqYtcbzqRhyRYoOeHeCgjghnwvCkpxvnxAbYlXdJvjBCoOsYvSisxLLbYfafQpMlOHGoYhYDShEiWeYQpaQMOfeagOyhyIQbDbiVTJUvRelwcVlLaXKMmQMUejhdtXXMLdlJNvvGakIXqPfkJPOYesKYheCIuDFcESQmtKsKnaHGZFIgDSAmmPriwTTEliEvDNAlrLYKsVcOlcywketRWlNaMerzlLhhFgkvlftLWIsblRbNlvUGuYLsXZuBOaQGwXsaejJbqoyZRKjwIbLClkFbunFgzM", + "changes": [ + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.790000000000000000\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"54\"" + }, + { + "subspace": "slashing", + "key": "SlashFractionDowntime", + "value": "\"0.333333333333333333\"" + }, + { + "subspace": "gov", + "key": "depositparams", + "value": "{\"max_deposit_period\": \"172223000000000\"}" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.900000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "staking", + "key": "MaxValidators", + "value": "38" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"6\"" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"339868000000000\"}" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"124\"" + }, + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.140000000000000000\"" + }, + { + "subspace": "mint", + "key": "GoalBonded", + "value": "\"0.670000000000000000\"" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.080000000000000000\"" + } + ] + } + }, + "ProposalBase": { + "id": "49", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24972834479" + }, + "submit_time": "9936-01-01T04:09:39Z", + "deposit_end_time": "9936-01-01T16:27:57Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "391" + } + ], + "voting_start_time": "9936-01-01T08:09:55Z", + "voting_end_time": "9936-01-04T11:28:53Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "KqWOmEIXVnbYarPwshcafKDmWoluAlZjwKeKutGrVXOEZENnarupfnJPRfMguUFXMbExdErUkXClOHicBXbdVkxzLZPbpXavLVBEjyipekjthmyQBYeLUFTfHyxTiNMVGxyrbPgzNdjx", + "description": "lOnsoQypLMgGqYVoZfhsrAsJPznEgJpLaIPQFXZHabiaKHBywZuvfcmuiiUrTzCWSLRkxCFWlONsgxiXabKtXSoqZNjXEEvEoBaPufvMBgnAxwOXwNdzhFpaoBYyrhINwXRdNKGydpdpLkhOHUwIXTBjlrcBDEgJCJYAATwKAymuTfZJRBEdXzsBDiFFjieFFlubvNjBLiALVtcjbKmPIjfmzxaDGtbkjstByzSvTqDREjnoenWzMPSSoWojMWzLLiiIgSHwFrknxxcWPBcSuJDpPjxHZcgYDHGEVJkWxSLqBkQstoTCJTtLLTvuOzZHXnqBwpZAGwyIbwbqaTmWthREoVVnxIUeseUDqGJkGANrsFrQgyMxNvCHqLHwDhnNANGOxXPtJhTilMrMkfpWaruWJlbcTwchrpOogGXTtdZinyICSoiKzdhCnQGabAoFZaBemajOgaRWkYbWNfJFEEObvdvbzctJkBgOOxnQKKgGKPMiPfBbPOyYmqTCOqTcrxMqUnQDOrsxvtPAbOjCjimyLmAPiwwgqqkzLffszMhxtUsjTddMtAPSKhZjMHmXCcjYCwpGZnxHWdVYnvNFleDYzZNsVkgeevWjeMUAeQnVbxEvFBrjNeWsFdFuPrYMmUakeNiqBneSssqwEyxeBJDzjypILzZPiagSkAZpPTMSPpzMQIPhvQTaoHPSZQOBtboJlkhXqzznHBchYXQpIeZFslHNTcvuFtypChiGgMDZsZnvnotajRElzOyJutYDAPCmWBkXxXNgjUomSaFNKsSqtTfiDUqmhrtjXNZOoqhVeSZcKtgcZPoTbSIZSoyIQuFkHtcuwqMDLlLxASIbnegPZJraDFbscjUgZTdncqNqjuAYUeoAHFxMBbGfGVNJgRKPgbveeutAJwjsANmdfkoZKyBMZfNdWCnGfHAISSNVXmajatKfYaxfaJBQlVUxlZjQyVOWIoglxBxvZIBkxZchGgxHeUPtiSzicLbImOhaoZpiApWXzAMzhuprtfOQWTWJxMIPWyCRcEzZkldRctXWAQNGmixBzFaAjtufqmmhSgIVNPQuKjnbBLjRMQgRksRjuEWZUalUWptNocsfloDpdTHSooVdFELzgbXAowAbhsIwzfFgLvMTTVqjGYMNMKFxXDuviTzhQzPkDEvxgPRZytsnhuHFUTZiuuqCWSQCTsVcXUVwLiiEIGvnsoArwTFCJxbqXiEOtyXfhDToCfFJDgVZrobxrtNnrUPzjyNlSocVMJIdgBECSbfBeIfoJzpPbrlNyLPSLFCYnnRIaryKtbwwxhLAjCZkjizvKGgSwQxjnOcabArHicnhfNXuUJNOPlKBvMcKRkXJxSOglIdrStijmzQjsfxaaIFcKGovanlqXkANVNoxmFYjueprvvdaHVgxJZzqlozRqepGLCxJMWWYXkiiqRJZMCIJXHhEuJUNzMmKlywewjJwLGfFyKgKMtpfWWJwMkuoAJGicYicdJvVmlAyqaxvtNZUJEBSBFWYOtDqUAhBophTuOEXhBnNZaTaQGBuDEPhYewJunqZbJYAxsDVksdfSXpLNCxcplftNWckTjrjmiLtGOerzHeJRVqgDWaimBfBiKlzwCsQwmCHUqBYWRreqVWesTOTAcnwedimrSajflynCnqZadBEKoaVhWJeEBCCgmCLPGBIQBFKWHEDvChiJCqSVCwrikvgkTHwxQJSZqaHDhpDEzNUKtViFWoDvDMMDnAPKJTzMARDyqOqASViTwVpfyPtlyuAuNKsHAkghSSgVokSiHmPqDyxogKpsqSlxHpgfpLULQmTwKeTXZPoHzTOqkFzLfEgpOICWbAtjupWtkxxsfzjDIlpJKXcUbgzqPTcDwEOgdTDVjSUWJTjKyXevGZvLdtZqwFEWzvNHZSLTqUIJvydRHcTJImazEkxRRzsCgHOoeUAlkbMhpaVnOsWRCcZMhYNsIDIyQYubLclPxiDSyrAKLakLrZmaKxLXCuIdywSOjlgsSifPKwqYAWgWlDBcjfoEWECMJlCsjbBAyMyebxxZzpAWreeqhowabLljzcdRndhybbpkClXpKrzeDQJKQezezXMLxTTYALpZeanFYkKVSBlVwADsVthOqLFXoXrsKMunYBXxhsYOBlNAqUFYnzUTyrEwcjBVIdEXfbUYhFGKTfdUjlyJmVpUCXtqsTaZSWYwUhEjztRRjxKAlnYGZqqIngYMbhLfFJEKTLBOJxayDSouZWTpbuLduTylNNcxBYgGGZnxOnrmYTmJgElLipdixEWjZATpgvkeIbUTfOnzawCrYrfEMVCDHSZMdEeZLZpAoKLYhJaDNaTPBpEEIQWQiqVuWlYIivkwEccmlXdAvPtddNlrkWNtGiWmbTXAOFceySGrsaNvqYlSVSpilgbDkOgHkzCFUjGRxRAItMlWcWDnIkokRKHOsEvxPATEtmHjHhfHoRXvvXKdlhYwMvRfIaJlyWgUJAYsGhvhfqZhDVtcpQjDPPdLWotMKqSkATjSrlrNjCJQcFTpsGySonBMuThExzjBycCeSBqQufVchCBOlmWbcpETfyFlXtFRBYhInvpHlLvBMGLQlMkthmnTBxuRSXbumeLGdWVTiVVAjIBYbZbwiqqlxbzLBkmRhHjbclxbfsaiLlcBgikcIiAnwYhBAAeBXSRfsTYqmfJBdZiYnsUWqiKsKAfLkhhIOsNGuVlxCGBToxBmhRgWyaJEvaPmhHNSISwnMvahaEFvZtZZVAzODuVFZQcRFaujvQSvxBKUpfTiKdFSZeBMdLBSUHffLzRRivnhgJpBnqjyWZjUUoNzMXkzqvGoSAgylyqOrsTZfMbWZlRppJdnoWcdrEFYAQBzhCnYOismWENFIJWkLrBkbxJakuwMMFECDcGmInWtmtdfIiWbwDWlHAnRrmkFIoOjoGdYvKVlCBDlEHjprwwVeMEqhKcfkFAFLOeeIGTFmoTgzbWznfZnKurIjrbvArQlAklHoLaaQONBQFOXIdYikbPtyKYEtPujTwcEZQmdXXZKABdvTMcCZFZeIBhfehqynNkOjwCxrqfRbUbJQrvIcJWMwBEpJZiSBlGAsnDKwJsKAWxxOGiWtDDXRwGkZAVDYUfXTkvPjASlkKICtqUsbywLmVNTLDFjnIQurePDJNjTKyydbGWlKvehdHkGrLXqDLYNihvfLIAwKgvSqPaHNCsUumEZREsxqczjOzQknrPvQzxfnPsoXZbhhtbEnrzCluboWOZzdIHMYGEIsbEjfeytwgneanAxVlDemlSLDnjVtmteKjcOdHJWiwkOOEuBwvnFNlNKRqerbALkTCgkmGGaKIrQfFEhZjTuPgQGuqnaqNNFmBRamZmLQSwDmIbyNWhkzDXtyjKaohmPBcasyFyqwaFFrMbVgICIvzWIAxuCCveyMTRPzAmcxXsaqCMCflTHbnkjieZhfNmfWtqbRxbIrqibYQKFElsOLBYYXcJMANKpGnTKfOSocXCGAbJpbMAaKNhGiZGuPYNtUSAPzWzhSbewrqMfdaKzgBiyVIuuvULhfBWunHuaQoiLWxPOYFcegejfnuOBxzEmQbXFHlehULDfbrbwjXpenkyBgfsBfrbTUIIGRlPHqMOzGZPiJBHjqUwIreosWCwGnYtajwNLyScCNQnAdrlmgrIrNxCDyPTTxRyCBGQqSqQmcOYJlrPlhxkdMELZGUGqFbkwxwLpwdMVvuTpXePcQOcxsSRfXTeBndpSMrNXMZSZJIbVXnxdvXBOJOSrCZSHEiFEbHnGYffmOQtUQWKDlmFLXeyXRiXiZEiFRtQqZAAoayCdNibsbxSJhZlrEEizbUrcRJiHnIAFnuzGvygGUQbjDsoJvyXCgBLhpgBNFFPWwPtSStJfRRoehDEnOKQDxlNBrrmsfcLRplYQPZZAcsExsdlohXXXUPgfhdDWLIbghvLJUDnRaGeLDfasqtRQPYgvyptYfnaOObFbJUOXWNEsnvjIuRaUqaceBwnxDyVSTMqatJDbmLqQvbjtiPFGPmWImkyWMvPMNtrUMSIanmgerLeriweArlKfowuWaXNNkAffCUwQNAbByCQDICaBQfVeiMxdZOGuFbWoVbwxKUWpITDjOJKsfUMreyoQhEKPbYbJjpqblLtlvLauLOlYSbBpbtQviwTpFUuIpuhRGIHnuZmTqZfjcMxBynJlJsfHNrOsvQlYNmZLaMghXTGXEZtLiXKmLGfYstPdccSRkxmioBmYpbHdnEoLERvstfKXpIXaNIqlkAhxRCMTogSLIrzFXRzbWdzyrgltqzMTRAUbSZTPhEXwyrhAJsgeNxmrkZZhVksXYWbcVjOLvmYwuUuKIiyzjDeIuQntsoPLrdBxHEmaumRxWikRvzCjMfYsXyHxHtCEbgjAAnmfCTLmdCkAfMfPKHEhwRojGLuAsxgSNDodvnjwLvOfmbzadoeilEqCxdJEAhrUeOHNJnLSIjIuExLffOKSHhvXKqwgFwZeMxdhYLjuNzQcOAqvofhWsHkkcBAeDwQeXNMUiUahiELXWMbobSSnaTkFRehJtptbEdtdteWEGBhvRTouuvngZCEircMKtCOEIXHuEiUhBbIrTwRzKCypzzyQZsqquuEgMzJBRfXcqpxNmpfagaxBEpxBZzoKSwpDMLsRgsPgcywUGHnKAIOJDwdFiNjMRnSSquQzdmpatbXMYHJXvkyNyoLlYtshRWLMKujpmagCJSlWBUOFOWPXlipWLHGgMZHmhQzmGZnsQdrRpeoYXINhoOiXJPEsuScNEquEAyFeoBdrTlKgHNcIXcwwSTorXMPwkeaZtPEHUBQsqIvsowZilvpuHxNLAngoMXxKEDiCqUMMdZvKsdhNXDgIDNmBHWHUNZOtaeotwuKjQVsyHDovMeAYlLHXzncqpxsmfUqHKNUYmoGUWZFTZjvKEepilakPCuRtMuHxCoVvbUcHoYSFphbjxaDHkfQSNMTsgme" + } + }, + "ProposalBase": { + "id": "52", + "status": "Rejected", + "final_tally_result": { + "yes": "24914473521", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-01T04:09:39Z", + "deposit_end_time": "9936-01-01T16:27:57Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "229" + } + ], + "voting_start_time": "9936-01-01T04:09:39Z", + "voting_end_time": "9936-01-04T07:28:37Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "fgXBqrbNNT", + "description": "vXAnRhpqBHZjlONvPosWHFScUMDRyJPtzucqkDFSrPGhtPaYQaflFboaaXOcAVVuxKCjjjPHWMjMuwRcpaOiDeGDrYjdWxDvOETP", + "recipient": "cosmos19rlals9yl7q50rfww4n70m26vna9envvsqj886", + "amount": [ + { + "denom": "stake", + "amount": "1061444452021" + } + ] + } + }, + "ProposalBase": { + "id": "55", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "24914473521", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-01T04:09:39Z", + "deposit_end_time": "9936-01-01T16:27:57Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "340" + } + ], + "voting_start_time": "9936-01-01T04:09:39Z", + "voting_end_time": "9936-01-04T07:28:37Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "qdUrTIBHSaGQZZsmAZdIOJRhgDeEUxvWcJrjjWnDbybwkGTuGJVyGdhcjnxVAruCFqOjbspcbloUggaCDGrBelaJXXoXXbezBVRgNhPJUbQUegtuyuqMEJokwALMQbbdZDwycTKjYeSb", + "description": "fMJcyfKjQSyVSuqoRObgZnDBzGahbKHcNqCYoPLBAhJaXiqFyyDMQtsKFCXsHkMQjPQLntENobjaVIAJMzvYZPhtUWklEnPfIJHVEAETiHtkgJBueYSvWDDLwmKqSdHsdiRecFUuvHqvqkGEWeqpyAzNsIHHbFscMTcWstgydLMabSdXkEpZbkjwSDeRfAQRxxMAAGhwHXiQUrHGcSAWwTLRasVQcHCzHCMiEBIXcYRDTYjAEXoOpnxbwUBELSvyLtAPgkocmmcUuzrBXxtnbTSKEQhYDeWLAbdaSdduMBDdgFxGUKpEegoKjkFWITrpImVSdPcCPkocLBZjEpLVGnqcPzMLVdPFUxXBvsrDyOvbFayHKGpYUsNnlzbXNqEDMyEqgQEsnoIqPNdzqSnjjwkqRJGEwtQuGzCABfAJaSAwBgxfalLfSpRDHBBeOMlUBxaeNaLdnPzMdNidHoSXAJOOWnhhgHkYksPhgSMVazojcjBOmanKxPbRAmmjJUrcUxyTixXQGFonjotTtqfIERUVrCeWpaXwTYPcmIqOBbwuTiBfqhGlfwaWvXngHFlLgVxEvmDUUsUJFstXwHepCLmRMmzkGKXYylVNrHsbpGmwVWpgltZNnycqaaLLufhrZjRFeZhBdPEjjCSIvuahVrHuQMCuxBcRnCALLTCfGJEKMGtHOGKCxjcyGdEWfrmCexqyDMOvogZyLyCQhXWGhfLtmxyTSBeeEANfdcANbSwDPXwtjmgPkNPkDYugCmJJQTDKsWyakdvkLnEnnAHfAXpGhatGmsRjKaULwbgrysnsTnKFXHysFbcbIgSiYXVvbWzofkjJAaEzBDMGOSHKMdlXjAuzIKkyXejsgEagafcHpaZlNOyeuinosvVHIgXPSnTZysTAAHfiqRrnLvmvMtzUvyPwXrPRFnszrTqyPeiyjJJOAwDMpZAVeVBxUMGZUQHnRqMllTxWTbrSZvSkZgGXYInTYvPpGEtGkbryJFHgpyHUzSKJUaJDbRWUmqPuizoSvEsTRlSUXtVjzWuDCvOBlyvosCZpbRtVoQjnqFNJZzaYbrqywuUgEuinwfYIIcntoyBLzcavjXEGLpvAfAEPGjSYfCTtnVIKBLoZOvmkfwOtPDzZofVlVMatahiUDsyqqViXphSHicRkhMkLgPdgJRmrAAHRPaSsxgbCfcDFGSJnRCSaQeWidJZFZjBtjAnCjBpjWoztxRUuVXqoHxnJpsRoRtAByOeLwJNbJmSUnvkqzBhSbVapzSQoJcZutpttRsYMyUzhrwizplVJcHYQVsvjyHHBCRZBHtWxZaBQxfRhtwsfAGkmMAPtBTihJcTuXetCKlmseSizIfSFipoFowmaOPsxtaXZBlMoepkNNQqmjCxqZLeXYHLYWowRzLkCfhHdZvMerHUzyofBgsNCAkFsrZkyFqGVPhBWEThfZldaEbLsagPJqziwtrGKQpbnXvVAxmeSXxRLDcYCttiEJtsEACSWfSZTlEHijtBQmbTYKzZEQABmnyFrwueQiYtsWSosMacaEOhlLBADhutvUoHKVdsHNkCkdYtxIJXvlrUPIzwyJFyAcGtrtnNqzVtsarKSjnfEKVxHMEBVrofJhRgdOvYFPNZhCnEhlnkfUdkkuyCdfKeZwsNLZgfhJrDTwdLUjoyLTuIjBswvbByOlTJNKUaJiNoBycKXyRASGzmtWnQpupIBPcBOkJqVCWWEytMKqzvPqapgqCDKcnkKirXzhzpYpRpxqfiYWXgXjJUnfDNwRLqKDtfYLtebuclOhwXupAcpOtWrOPMLTzFerYmXQRxGICoWkLrltNCbMGQenRQDrpOsvfyMUurtSGIBDVfutjQJtMApAFIKfTGtyqlJKYMmjmYgapfySXbjkjRCtZvMVZEubrawwUEOJXYFHSWBtBzWVXGIWQsEGPdlfwTxIdejUBcZICuHFjcNsTsYyYUhpJhXYpaSMeVouwXXGPEnvhALXcUvdvRlsicrfuHhArxmVqjHMpcWdlnFdNyiDPGyZeSODYqJGCreEBgskeYCEJOZfoCBuolCcCrbfdQIuvaYgEEgNQISBXaJTlqsVuJXfKIjPJMcTCkNStInKJaQeoeOHAnfbCpPgDAxiUlxYGvsueuMshEYSceZAPrAwchkyWJxINRoVhqkzrWkPmmNWOdMzUiguQhFTcjkwwGIMrhuGOwCZLjoGSBmcossoWnUtwwyAeRWYyLYJBTrovuLzunXrMBitvNGGZrzhXTOPsvCBBLcRSBdBpOjfVCEUVuhHQDCfIVeNPXXfZdZsueDOAqVqDNoXAvekwqXzsMefKWuLQERrSClnEbNfpkihdLRqZBDZEGlwUqOfcXccJjLMsvSfSfLjlzWNTEpdETfKYUmDEygLaXsonjQnemwRdDsSqIMoQPkDboGfIbiGTLXUFGytVrMLnAoEGaLfvtolpSorIQKgxTEjUZkfthDsxilcJmBgJCuJiZUdcbIkigvIcPNFJXCrMbsTMYneQsTSfoeKnKPRGqOXfWYEdhhgNZYcAZkhMgnQQHBazMXtffnHWDINgeAPSYHBRnTylrGOOTxLYhiWKWLSSPIbTtLxzJdxZVPenQdhUeEDzIoSarmxeUPCNRGftcCTirYahAXNoWSQjDLTMTVmVkYZrYjGwafjLubZSkKYhTpXqFIbohpTIotQcRuBhYWfpKYSGjgzvYvqhfPrbxLKvtJRhSmLbyMRbDonewDWptzsZHDtINulkUEBKIJPLbOLtYGEKTorIpizsTmbxcPpjTNvhVBSSAMdlaXfakeUyPEPjTnNAMfRmcHhrITTMiaVQBdyqbVWXrYhGMJGPFhwpSsQrmXFMUxedVSUHPTJvbuPaPQDMhdBTxeSCTxIBYfJPfAiNnkkFebOGeRVlcSnqWSuZqCeZUvNZWLcFFdEPvbpyRaDUHavZuXFTPRWdPGpyUmgVQVCrFefBwSsZJeQNiPboFlsVnxZmzsCrMkvvcVLmkCToQPRGHQLUzqXCzzHXOWbBRAVlrEFVftIyGDjaErbcznLLOBxdOKyezbVBQPAfFMiBSsTcczZNaVJlLFiXzkWlLEedpLQxxepZIMnqPFtxGFDvCnPzbnkAWSlYdSIwZJDRXkLIAZLRcBDdhjsEUGNZCAngvuiIPvcxVQqFXtKpdQKOGMFRoeXQsYDspZUhDrSlKnEyuAgRFQjydIuDfiJEJJwoZMuaNFKONJLabFGcxLYiuoapKQqUHEPgeCjEClLrEGqpjEvXkcDCdciRTXmNrSGCIzstdrofXDeiVpOfEUoetwWMQHATAtLvFiaaGbmwiYvDlUfbYdrtYoenDXThtVZqNjhgIBGEnZEqFEOiawVXJRaPSnQjmjwAnAdAGLqnqvyHkJsuvDerYuXjGcBWwCLFUQqQbYshFXiwUOVypCtGIyIwbUoCRrgWMcxQhfQDaoALFWlaZgYzZspqFRIbnzQTBMvqhxcjiYdYesxMgZNnxhgdVTjOzWWhCoJmHaneSvwehiHnPXIfTTlqDyRhEbzCNquKLqiGZMcZyEmViDwgvuHIVhhhhhgrpLtWtyTHvQMFHdxNGzygtraKTjhwDSMhMhFLRkNOcSyecSZdBLkaugCGnDgHfAOCkKZMDnBxlboBxCPsTaXwhdBrvBxNOqJHbOzCbAmhVdhluVHVuqUkmqQERAzNCOKDMCIeaUoTBIcMuEWULLSDzuFWxLcnHOQiVTSnFPywdphLtXuVXkKtuAbSRFxEvvArViitSsWJJIDjDomskjLChslwsJNIXvwiILlqmgMkZifwhuNHVFqbYibxolGpkqKpWIuXRQWwqDJMMwsQymMHFJTtCpmdmHsYlZvzBNDxYyIDmGyOaTlsQiYfWGltUrpHwNRyucRDDObdlYFosZGdPZKpDAmQriGMmtbKoMNmXJjvjxKYASvvhlJjdDcrCHzfqXSBmvBYvcrrdIttkrNGaonloMnAsOlilbNrrCDpGVXbtJvpwiloIeSTmkiKCbnIVWRcZKvNMdMMDPeDPpNOziuDMcwhKVSxTLPelIBqcoOrqoKozhjJBiRysHGCADViVGZtgytSMHkyePWjoYtWlHQJkSQSXBzGTyzpoXrAYxGQULESMVvXDoZIdAEhIPMFKiBQHiCviORWiUPJFKjQAUZlDsxPLUzMKimiqaJRgHktHITZkiJywnmwhnXBKwgdlYWpykkmfQAnnfvXEbzoGQFGxMLVfdJuKlQiDeYDDumBRjdLpupXhYiHOZeQqFgyPABdwTPaaTxjsNeMhfQjngqVAXzjwEmNrSqRelbzHkOuFUMmhwDvYcrtmqqFBRGrvXcLOiNKEDAUaamgMwXgPbKKBwPAKmrjPRqribUPFNIKooliFZilzpVYCMYDevqKJKqSAINnCgHPzENwQPSVozcupBEzXmMomMbKILHvQuakIPmrNikaUONurmehCXgAJOhOZkvOkUpRvIuODRMzCvVGJlCiMClRNnmeAJyTjgZukqkyAJzMlUNmgVOoYZeDqkRzCvqgSZPQhPTxCBGXuuVtpNTpOcmXOMUOKPsBsOKRIkYiFRJxAacefyXcXsOfeoyIbaIIdAbKRAbIoxCyuXLRAzymILFoIMXpPbRdalUkKUYdzioldIGltZpFtZybyCLCJyYOpbBNeXAxcQkOIneeXtxHVcRcvaJUrIiBDPYvKvVCrxMYDwfbTMheRpQNAfiIGZLenskEiSJdYToIGqPKjqAOhOZPubULemocYeFlzFWQFJRhILtEAGNypEwKhbMPpWjdpRMiZJPRuPwguavAZKjzEXGcFHJOsclVAcjZigLuErMOylKGWrvkmHHQwkSzQCrKzAnhhfiHEqMsJbTILYVKpBtuYYjUXckwxgGekjccmozphLqQNLLHdsrChuYSbpnbhLlkChVyOJIzbAVKdWcMaOvnhrvkXYGqPpvExMWGiqvuXrTZapxFBZRwyOMYQaJgpC" + } + }, + "ProposalBase": { + "id": "58", + "status": "VotingPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-01T04:09:39Z", + "deposit_end_time": "9936-01-01T16:27:57Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "241" + } + ], + "voting_start_time": "9936-01-01T16:55:11Z", + "voting_end_time": "9936-01-04T20:14:09Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "sskgihpFEtoGfClpvDGmAPzkiOXSNfIJbvGrLCeNgenOvbMxhIzJYshGmsXXiCQCyilfxZdgPRjsDYvDlrqRGTwsxmttNBIPUJcTQSnsrHIdzXxDvYVPEYqJuOeWntblYmCEbjUyitjc", + "description": "cVcvAaxYojEpXPwiqimIloBeClWrHPprJTymCGYangpkQvtjiTVGanIpjEwVZWnUDiplswnXhVJrskUEoluZriofalizZzKuvDbZGIEGvSzQEAwZKudkfruyGsvuekLeIMtPViqLnKNRTDnPGEGDWdUyxQYvTlVODkSFsTGfOfnZSVztVoccaPSAslJwfexURvKjdBHbHkImCsZtlTJWtGHsWaCErWKRdbiHAFTaUkTssCbbAXCdWIpeQUmJdWYJQclsXMxmMhjvLDVEcgSinULzhcsDONZrKwlqpAIjCoFcFbHlInnzPOgylxBJNTswhfEgLjqsXewopesuUKIOSeVBrihzozdDQipdolmSiyYzXwfVvlyjwpSQegsEBXExSfmiGclzJxfsurnOQAeEXQqaWugtMqLGrIAUrwBduSfiZpDFQLOMdANdHDKmrYoisALprQpkulSLOKOejSxQHGhEtKKNlUUqHSnjgvRnyeAxbecyyXFDEkycMFxFTCguBigiciWKvNdHiXiWbHuqOJEfmumIwhkjGScsXWYxcNuWRcCeuudOPcXipOQlLSTXToGlJrpmbiepBbpuIKrmLaLEhswpiCjyeJUAhVNSkNqiMlCusxHWxIIOAIrUlprQfILsvitcIhunuApJCsjPYVDLrkNIBAokDlaekXIafzJAeZhURHZcWroAfMCQMSKQOJapymLhRCqcgHzbRPALJDBsbNhrZtDxcVQIYnUnTisGfkUbmXRkTAmECRrnIUzGNeitBlWGMyirTyNXiNXIxUzsUuONvOygasRooWMmtISvypHXlWtWmpRUBKHfTcQpdYPjUxnaXtOnfIOISfrPyfDanmZuXBBMcohYDeaRWiqEjvJeoRgbGpyWDwqjTkoYZDXhGdFKmTthqIFqztDALPMsHAONxmzIETOVoYCGOxIxsBOtgPWDMxLcbOjoJajYMLakynSYXxHFbiWIHTIZVBhKWjWDuOBCxMUwOURRjzuBhHFyncKBDoybeKAdJwKPfjQJVsQPBgHqcNeHOJUUgSXmUQeTRdPhvcRMuQcNqKXcXnHCRDdJGcSdEKNlleFvSrXxaRUngOCHOwvDxBiFyeSgMPqbGZJpZtaCPgQfHGylvQwNzfHFbjjNGtGGJUDgwwgVpELWXfCqAxlYvAmOiViCeCcAxcjeLjLUxOeKQtEvOtpZgHpAWEesqALRZjAAVOtilZzIdlxqQCZCNgDtbOxHYyeOMAXWoVNtgLHyzbBbQaMTYSLUkdNBsWSkSaSXkvcqYbQPlXLiLuZhhvjxEOGqZirDjiTjUiPNdepbrRBurFVYgKcEnLuItvxjSIzwnOtGgECRaerqwXPZUwSpsVfTBUQarXttlntuuQihDTlMppndVSgKxoSuTnasWmxRJszMjXAIHQloQGwtsnlTWIbkkrCKTSvTOVdddEdNDXCBTOjhDtwMqUxSDeuvoNHUOUWeaQPfYnYQivDrwVbjSaVawJhhUAQvmjNTtixqguSlrIcczoMzlOmQESMxlAiNCpagGIvaeuCSfjtxBWZjjLVWVUVejSeXyChYBZaKZhkRwSBDRTxUABGDwyGBKaCFncIqUoDkAciodntqyVNTgBGtwdhkqAAbemWPzDhRuLgTUoazCkmIeNMNJdrjYguUcsYuZQpMtzcOeQEcZXDDIWbLdsrWzUnDAzlVQJTLAGqnBNrvQTSzwaVQWyIKWdhstvHSbDtlYrtHoNgHyqXaDvLmZjhEVhoNswbNEKpqYAzgVlOJccnExCZgRGKIWXundbADwaESRyDGzxYShssyXDdUuQXjsklRFKiPzSXtsIeGvOKFyjNNtykZSNOAwMaXtvSFynsQKKflHPPPNhvuZvTNTUqlCNmoZDJPaVXDzsUAuZumVPzUOWLKnTlhwenxhhhWXBOdMdvRfPdaBQIcqLhyNkjuawHvguUVKfBqzbECLmGkHMugzhWZhYgRsXvFQFluVBhbmwRgnauSCLzGOnBEPcVsmtpkBaXhYyviFHxltkxjEsFlIfaDUdzHoakPUyQSOpsTqWmQxGWXzdalDwJEUkruurSQeFRMHhJQZbSApbxOnffMFkBwziNZcFxbacqaeapJxVPHrBvuYOiKvTroCaooVLuaddujWomkIvqBmJiPhqhWcvKFAKJzNuhwTizAvPfcRqTgbxShcpaQdFrRXFxdqxtzkZYivQhTQSaiLDpPRxxYsMctsXHwGPofEomPbdkKkucmpYZmQkLteGpkinJiRRaHhCUdynwHtMEWeMmZrrXFTjnSCtDUZrkHtdnAMhqIHYWViFSAIVSycwhnufSropSEnSLySHyvKrSMCZciaIoYzrcJqwowWHMPaATJaAMvQeKJbsYZtnEaNUisDfZozMNifTeoAcAXTJgmPYNAJwbDrjtuFKqHNRyMsAbGAZRvmCnbgqhDLQEQSRYJyAnSVdGeZOfldyAJtXVhFZbLPMVDWxGUbzbtLLjsJtZDujqnZytFjgDbcTQKtVxGflseVGsIlYOwtjmErRrTNyUEbzzdzpjLtgMregLpZMrOkkCCkMwXpaFhFHlGqDGQDYJROCwffqfiJGZtkarutZMHlPLDbOXxIGcFKbyHwfhHxEqMVcYDJaahsLRXlIWlcrnbwqdhVaXsziIHvGGZfldcbbEDJwpITfeQnBHmECrzQEIwQmYAtJIFwZzFIqWjWssiifMDoBNfQNIoKqWqyRvPfsiKCuVxPrYvARGxOaZtMNMnkvIJnVHsdJotmwMjvgyAMxKhBhEicBeOoaDEAYAbBHJmcLIaWxpLZvrlLbrGEvYHYqtiqgDuWEWCpefDLjiGLlQNnBecwzlKzpAqCRscDcMaBgztuHxZbwMPImGCMVzQwPrdWYcKRDjogVCohqPOqcOTxjSkYYzLkaqSikKYqCpSuujojuMcoJgbNZyyeRnFGimavvxHhcvxZCnyvEBTxDGGDhaUdwtvXnmHTJfpkynQABWXJIJhKygIqCdTPrlzAyFLiuQkEwPiIgllhKmkhbLKSpnmoaypqHyNNryTAcAQgHzNtRrgRFWnQAgNkkFUJmFMXPLEVfuBzuoxyrrECfKQlkZHuJOrLKoBpBhEicwJeLawKTcJyTfYsgdZmQtAiqWpvtCpweZXYiATmburfmmvCCpiaBzxqnInrVxtDJFlijFTkHdpLnFXsyKXpjzfmmaVUhoQZeDYkVDRxgknxYtTgdXbFQrVPhaMBxRHABFzyeTRFwVATKPQrpPWuScvxVnVZNljPateFZoZSgcbjvfaTIpjvzQKwQJyqNJNFgbWHBghUSLSEeVnqvpdkxbFpqXAjMyezzVhqHAobECoEofGjgWWJPSQKXZsmWFzMTfuCbbZpsIyrMONwwMwtwqHSHHTXRfHWliPCtQcUMSqdnMsPlHYyHOsVZJVzJQYonPMnZFLZWemKBtosyjpMOZlHpgHTSBSHcZftqEYmSFDsxDPiGkFbaPInoUvquAsoDTqkcmqCDdtWNKjPxgYwaHKqzFXyZbJtDiqllCOxTQCdZlvkGPtsKNZHxuskzFqSnySfBfgpeSclmPzYIZhzjNsvMOWidjMQhcZshqPAXXnlpzEEmrGDCDFdsglkNHzhsZLQYvMGWQNYRYFhAbJGIRQLKMAZNgzlhDBgZsXNwyqNCVvDwGfagIrDvfJukUgPJftlHGJjVNqowUSJNMeIbxlOnUZtJfhMDlJeYeWmtBzpnEYiJXLdcvMWdWhwsaMlfIvCjfLTlGQoBGUBjGTXgdcFNhAMUempKbXyWbnPPAQtnJZFCEibhWfeugMNKtCwsNaUTIeXOUaqPNyMVLMwYgijiROdQrfzsRYOWRkrWWzBlJxkVzBiuPrfyKRTPsdNerpgqYmgVioywIRAFawRiQHoZUwJuKSQanXNuvyXnwHMCdkgEcOrALnDulRfzvqYwdjFXIdUkQxwHqntAOLIrJLmVfzsadukUlUcpBOhrIFqlFrZLwPPTCWMTINMUPeHexZPhhTJjcxEMoGWaShufLobglebKySrlwaFjoTeiIlRuOEiHdddeqxlrgvSKrEyQfdPYhRCLsyzrMBlnXieUSQqQqRBaNwwPrUhPzWppWLwUpJdVtDCgpllvsivOwHXetPBwLCFzmElsYBGfmIMiBEtRjmCuLSOaSBbQrNWKiAdynxpWNCVFAUAbgdZXGSpDEmLiRbPoRqREaOyWTSatIRbDOjEqsGiQmPzfCOtumAXkHPCdVHGvSBzDhwhAgiTiOotiOaePzuLiZDvlLUeYXtYmPVheMjLdcHvjoMINNvjeovJdQcAHrmoAIJtqOyAbYRPXZutuZfzjSxqSaoADLYgIizauMrbeuCaukhiYcCXcPBsJvuXQSPtaraCoMxCqevAhhRdfbqELLdYurHeLrTMpdtbhIbURHjTFdohiPdUPfTqLZmFPtMjMmQceMuckOBdDNmQymTUBAhqIXMKFkJoFYXoDuOZBnlCnMBkrYnxgsYAkCSnErwDIuUXaSosOHcRLHPxvLwFVVdpDWbppbDMuIxuJkTHYCJcQbOsBjncqehNiZwUvYMuvwUmtbsvGyOmVFubhOAOWhOsjDFdcjXnbQkDfisCQhdVIvcltVFRtCidudEYzCiMlQUItUdvpPLPvDoRnGgIOZttRqesjsNJssaGAVcLLodWPgzSVhMxSTsVPpvCPhWkTXrboGlqlOaLBEaBAhsYvVFppIjhYEgKXGfRrbmemWAShOxUMWqmEKNkBbkMzRcwvjbqCuANXwZBqGNmOeYFLdNmvoDoSUdqTYNLplwfhzEONifpsgyzSCHYQdNAYMLyZIXCZiPcEpUCAcUCMYrpyyHbLAQNDerZJxMQYkJMzxdODRNGLqqNWznlkOFvExwtmLTRoCyXTsSoMVheglBNcpwsvxobdTycEtdXRlEEcOKgDmmTMBfzebosgSqyoNZrgneHmJcDSByIAxfLTwMhbXXRmVqizVN" + } + }, + "ProposalBase": { + "id": "62", + "status": "Rejected", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "24972834479" + }, + "submit_time": "9936-01-01T12:12:35Z", + "deposit_end_time": "9936-01-02T00:30:53Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "280" + } + ], + "voting_start_time": "9936-01-01T12:12:35Z", + "voting_end_time": "9936-01-04T15:31:33Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "cWkZWXSygzIaBoZdPtVeTLyWZzoSSnnkxIcqDEeasHpiAiKqIWyxcYTKoErlTdJpNMCvDGxfxJemObIbDcoHfyRIsCwruwUssRQkAAuajobUnhTVddTBCbvlgvVFAglfCzSdnIARoTTj", + "description": "rkxBHDvGyfFVRUdWlbrumbYWVDGAyioZHeYPCzVOuGtFxKzjwgutSyooGYCefgueTTOZwgzRZbPSmYhPgFqowbgvwWOqinVtcESaYfqCOXzDWRFBNQBKuQWsHubGncjmmYavKeBbtYwZzXjkUMlMxDGVXKHScZnAkmrKHbANsvCnILmiDEbQRavSWMpgyIENfUmOMjRGmUFUpjlmrhRojKpZweQdHTCuAvGlRoulntDiRoFFuQUpRXLQKxlWZVnruHzFQFzTQLRasNNzezxLlfWskkgKYpTmvalgcdWGGxlAYxpKDgStUOXaskhjDSYxHOQdorbIbFFuZFLytGzypbguTldIKofWHVFCbJMlBuummuFYWlvydVUWIVzRVBCyhcsbUsSoQfaJVqQAQEAimwHMlrBCPUnOOoycEMIugwFKQCySaXvbKChAlQdtkGHHWHDQeMUaQvDXztmhSwXuQdBDUUxwIpVacpTuRbfXnkJcnTKJcZhSZQstVhZhctZtYJfAKmthPzkWGKUhbmCUQWxzlQIVeyWznBeVwaBKyEibCYsLyGKoWNpzgmXuqtHOGTSLKJKhHkcNNjcbrPPSXyCErFXelhWacxhXYhrXLvmufOTDYKRkAZwPaXVOZvweNGdBBlBaCpMIlqihEuQWuVZsqBftyJWlCqTRLTNLrNKxioyzgAoRYlQrNysulhwpdMxaYbwXMVOdLeoEShNzhjFulxzfHSczhleKKfXfjoutEBYcdXOWIJKIJnhPiBbAAiEcWUPSJphYxRyhYNGZebAWIpuwBJHgaqbnzGnSMyqhYKUCukVCHvijSbniidHRzIKRqaolhvMNgRGgSqKoYZSjqcIJQInbRrJzZyVPClgbPkUlAcVxAWfldQlQUBhXAlvhWDdxQNdArgaNRNxEmrcvghAWKzkgZhlUqnUYEehHgqFlviQryKsZPzVyoGgaLsqrajiusxFHTgkvAYcShfcfTdYOQGUqaJsLkmfyIzaNsFFkatOTdctsaKUDRIAnrPJJPwlpOyeriCWdGNbUGLhWEhnjQLvjYUtaXdIRvfuhnrSRHVfmpZytSwGrQnuJFWxrPRtjIOldXBRTLGmcixilqEmzihsnEyCEMtcnLOMORGmYKfIIgbKEglhdaUYtxNTnWwrTbuHtNIBVjStJAXHVtUxPnXxmigjaWzfegpkahIqmJcPxRCkAMrAddQYIupIStWhEKyARrSPeNUovNGiNVIFlQaBDutUJiMvRkLgLBWakRQiLYuzZBqRJoprTDXaWrwOYzpmqTlWDuxvlPIPEUhDuhKyYLRJGzLeYBrNHGEuygJJRcxsanfghNVzdUAqLwWxdIWMyrgspaWYaijZsCuCaGYxTNnsOWBXWUDDPuMkCfAECbGeqnfEdxpDznrzPGAyvaKEuXtAnrLdpTRRZLxfcsPVXSujgRgxqdSXiQKNcbRTVVtcidqBiuuDfsGIlnLFanrvsNUqWqBUVEdVqtRPMQyuIJwHreFPOdQrEScQKInuKdOBkCPWrWsHMNQIVgVAjOmcfYHkndWhtPTlkuMPxJbqoltliMcTArKqplWaXrMYoePebibQVfGVDhMMtzLtNCKdCERkjQfUlDhwrIBWLzPMFTJAoClsHkDkueRhPqIAcezYDJZawSDhRlSnEuVsxkmdtyCPRtoAYnnHLYJESJHDkjMAdHpMVyxxFHwjYyKzxtvTJPitrmpPqxisZDlUPJNthlVWiXgVTnTFVsKAfLjRekRobQbzyvTHuZpvmGxhJQRghBiUBRvBeenlgvsYDaoahsdXfWSOzlzgFonBCbxRLWAHULxanwRKBpiduPPKrwmefgQucgUWNUwhhTdUvVnqjGMtGbhbippJpagaRKKYiVskSYHSnAnrkpmkkvixDSUzHlRjofDnMsYOiDymlCktxVHALFDdPRNmEdmUiQtILBjjiazUkjTpUIlbjydPiasGLpsyKFKbIaZnUcGMYlYgaoUpORuUwwTWwkPvPwHaDoqXEaVSplODAANukkvFpmwokNnEYxcowBJsZcahQQGQUkQkTTEQtCyxjfjRUUfLyPJolfEZOMYdGrYrVNleRSgGtMBPoFlZZScvATWQqwtZOrLRBYSlgHSwkHzcbPXRdendEqvTexcRJLcZNmgjAkNAseBTsTgkDswKDyZYvfJEuXjntuqPpmvSjVcgEBZxECixLZAriHavzEERoFuxzzIKmIYyAnmbVyApRCezoWWpGUupRHoVyZamULugxcwMbZoiZtEiTuMdzHJOuGzuOBEjERlATWcDSSVgeufFTUezDbSRdmTeBgNsScDVioboMzLUQNhShbTfPEhOTkwsRLSIKXZSnGhjGuiklJDSkFAqVabDCjdwQpLwFcTJnWZeKcytaNaTEewfDdJUbvkbHoyXxkLeFYrxyKCKYMyNptXNNQGaWemAHFupksBLLwRDxQpbLBkkaSzUqGfObnqkuAvkKEJTRPQOysgRsXkEVEKLKXGLcNjBfSAVWthpVjdssyzZwKAklLhhwOkAbpDhVIfcsYtQzLwUcWhGRHgbiUMJiHHjosyAkVqKIfNftdyiawrnCKOFKfEVUkThhaTggPjDkQRulfVVIVOfwUKXpXqKooJEdgJgrbOqSqSzmakCYLRFFMavjkVQhnnFOJqtVxBjFlkLBnwGRBTZcNfjrLknbixDGLcbTFdYQYiUKcyzJiIelmPUJrUOfiDSWjAeWUcSvvqCedyEQcAxAEquGLaSUjtpFnYVqhMCejEcexSsavMiyGVPYXPXReSnRqGyoQVFtNexgqYDPMsKkOBTeGkjQdgFpbdAgnqLZKxodLFJiZYKiADGVjeumKgCeYdZIyVExGTKiCXvvVFCDKzVSAVqnFTCcqNNJzAWFTMVzmPUTOdDbAkIFubLYfUilGiqmnJERuuhRhiANeILLsCPikMJSoQqusXgdSkVjzxHrymopkoUfpINpCQWzkuJahmhVcWufNBPnuKsKUswdnhPBJaUlVeyydbyZBfHvLuwrrwoDiqvaWnhCzIlhXAbjozTPzoENZYWGijNMBzUnlIpxwAfoihxDsQucZDisOLJCdMxixfXeJkVGhtAqXnJbdXzYgseVkivuwUPdtomPnUalAWrGcYEKeWcrvVgvtADXxqowDtXOLWwKlTwanONrtIFXxLqCmHKXdJqoEKhpOWeFfKmzMmAfcxIkEUCGNyshrWURzgTUSLrNHlVgmlGvCIlQjvlSMrRTckmMKFroUYDbixdyXJuHWEctvYzNHCyWocLfCelriRKfXuHHqIZYpjrwwByLAcQbUdLIBXAvLhvQejGwuMtwqdBMwmdCnUrbLSddPGvpWKBhtIrvRYwVOQIvFxRwmJkXXmTAtDBYSeSQQnmMxDTBQcYPtUfIKJXQnVafAyLZGJGsZxUNyDEdQIpTeUhxhPEeSApnfKijSVjEwZhPvdVMcwzlAqdikjkKTmfFolMTVnMnXjjuNUbnqkVuVsdCGPTDngnmzEtJshuGhvXEfjutSVRfIgAMxzyXTDbKpBiDDhZMMauGEkmKwQEJCtNqUDtrLcUbQrKiZpqPuQehwBlXOXbZBSofgZYZWqaFxQULrHybOqbnneNvLtaVBKrRGVXRSxhFXTLzVjtOZFrawuprigJJbOsdYBdpZPxBxzOFwqnhwFKVGtYDrCKtKpserRWxUjfLxCIRRBwvKrRXKCzbhxOWEthgWsKPKLvgBgIskYMnYwGZHcDxDqUznNWIXaakLWOVBfClCQTzcSqLXJzEvhJrzPTdDlBKVvbsyjBpTgfVzXihpVBpSqKQMwiUfvodAMOUTxgplNLHMphTtEtzxlTAavjMUPISCXARhTywgerOdqvqrCdRrOqGtmsCiydUErtTtnSHrytxxDPFXWTeoILrUhuUbtoRwPJqaTELYerOIWIxZwSfCkVKVUnEFAfmZFYKFLgGpwJvTGxXEfPZtzExowsMtAeCfqjBudaQyjYLDQHvvzhMhistyqFEpvVxAJsBXQfYnMnYXzIyWBZBUjBxpfRhtmtcrctEIwwhsswtTqOdXupSXQCTUKbwsstempkzTXgUXGiVJtUJVuDHFGFFRdUpkQhqhoWOwqnquZWDIBpskRgYerdOwQuMpbsnSXCnWxwBgcVRVwcCQtMJBvgvKeSEbjcDQDeqzxWDLbDJgZssuvpEMYrYNIhXcNnExYFBqZTFuqMJrISXCZBrHrAfcPxSxeIQMkZmQRjsPPnDmlolKBUCnTioEOnuQCGdkLiwKoVJcLYTyYNyvBXcfanJYcrSYNIsBailiGJLPUAUjxloxYcKjQPbVddlGpXDUvMVOmrcyTnWcWahaZpFekPfVeoxNdjBNVzYAbaymfTtUlPJQOxfDncmAIOAVLItbAefrQYzdibJatWqBCTTFzuupguBBmHIkFCdXoEswhvkBlUPlNLRYcLavrxmjXIjEQORobOrbEZvoZMLkeEKWHTtjuiVmKvxDJGjAmOQMluiUIbxgpuWbkTrYpDQBNsbfvWrYsVJqpsnxRHMLAPXErtPumMpXOJFNTXMHIBcFtUdpuiRrfpJZJUlymEfezkUKmDYemdDDjQuRcQCRxhiNCClcnjxwfASMEAXnKwbgkGmTYpluJVFiRUwsMzdsFELiUIXisxghMujHCSauPAUsflvrAFPCBJJWeySWdHKLibDzSrwIUMrdluOHXPECblncLFtlunwSkqHyBLUORncvmqODBKaBCTPIhlPUqxFoduFlmmnnbusVtOetWnXTjZqKXnWCNGozqOWGRPTOzYPvMPIkqLAKlWhBELiBNqtFMFDxaoVhrdQigwkvnqyykRMMdnSWDMLwfqDOhyvFelJWuacVEmjWtMIXVCDjLPIXaAPWNTqfsbSgVxpHGPocdcmqgSrYoVSMxwGdFhMYBKEynoAbZIeIKrqSkdmAQdseCITgmELcjmLSeVGXvtVeONrouARsvQKOdHl" + } + }, + "ProposalBase": { + "id": "65", + "status": "Rejected", + "final_tally_result": { + "yes": "24972834479", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-01T12:12:35Z", + "deposit_end_time": "9936-01-02T00:30:53Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "280" + } + ], + "voting_start_time": "9936-01-01T12:12:35Z", + "voting_end_time": "9936-01-04T15:31:33Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "nxLRmtWBXPHZCRovFNDcMriPazWxartBGkXAMsubOYiUcGNtbKpFtlECvbnGUGBpmjMVQjVOmTojfqhSOgESWVChOKwnbycHQppEFcpeHjKlNhaNuOrXOLTtjlnLXjxDfHoCwkJlLFdj", + "description": "aPxDGBZIgrBGpTuqabhDGShdqRLtEVXmTqnklHcIDIPdOvimCzDhMUXDlYLrKleSNsdKxHvgjDmVHqNhwHFjpoiFejQzVLjyhoKBhrapAzJGvHTjFOwzxwlNtZKiKVeVVLTNGtsbgztglouGniyAIMJiuoRTvKamfFStCqppxnfrRQYNshPEguihYJiEyMsYBCCcYVnpQIDqBdisPMZUUyiuGaIBZapmkCHveXPFYEmVHQupEOmYPAPojRFqAiXgMwMLImAdKiTbmUrCPeQLxHYMjZCnIfGCoyUJcvbUAMjjvdJkPOqiOVSHxmzBzDrAlDgLVvVgiiatsWxmMDVSJhqRNtWXfEJgyCGXLSeHyNGOMnAbKABQLzMcOXfbEKgKDOuLuiMFRMsRiLOOsJgzoZqNiSEZuCwAaYrwCAaUdJzbDSEmwmanQMxDNwygsYpvSQNJgpyAixcirfnfpAKtFkXZqxQOhPyTuVayNksSFOKFhzLMVLjwTtTzYzzWAvutslplFOvujfjFzPdelKHfphRGNOLJTiPjsOTPYcxOjzvBCLlovMbXfcjsHjSWfXIOGcOPNkYlbvvwmYFfOPLSxIYfZxUcGqDTiYNqNiVVXYBQORiMIyCCIikQDQrFbueeghgzJTTCMNGJhZuIjHtqzWfolozurhCdcUmiOTpTfswnktvmZuZMPAAoCOBRELungQuScDmAklDJyQxmTZqOMElpPXvwogaqcwLeRMQBDzidqxicDmrsNGQSTkidUFdjmOyonTvggYeBSKGiqwHuTOmLOjwUZPwbGoMdwWaRIPyVtYbqdXWqWdbLqyYpxyfdNghoxHKoiQjWlAziAgdnyOACwsgLXbEVZetfoMMytrVvzAroNHROXObfBQQjwjSxMJMwVYIMvNlUhFGoNbeiTUkmTLgOAqdGbyNKEEasKBwBGRHEWTEGIAGUjWwGefaBUQIfZAqrRvxGsilJsOeGNWnmkmYHyrrMPrAzOzJNIOvbyNPLMvxHJbKgmZIFvrKfUSvewxHVUHaBrnTpYMrRpHrBcFFtSubRQnAKnlKCgcFnRCfowJWHoUYreninIXxNbvQiRgkMklltADNRWWeaKTDTQhsBGnTOPmqSdaptxjYGnVPSUGUWqxODlPHYNtKLnAkAnCPyGdslTGTqGIROzMaLPDQyYhDOvaxmjdxSehLSAGnfETeUvdVbjislUZdXKcsHpoDbzDQOCDKWQxjhHHsZsVzjsfRLnkCTTcqHwikTgfiSpEjfAOPSpotjPkbOWPjZfUPGfrFENUGRoYYhDYZfLgZZAkPBPDXBnDKLTiJFwEqtKwtCHufjMjaZBUcGcyTuSCTXggioHbZOHeogorpepjPnKtuTyRYFcIkxXzfEkfPQKFraeMrVCNbuvkTnikkRuUuxoallJwaIFdMuQfXAlWfavHinGNzhXkjagqRnlYLlQQCYQXrdAdgdrWBLFFkdGMaUGuWFInpswizSpmAcszsWcJtWziDNCbTjthoWyCCPMPbFCpFqXUASEYNTDeDtzizAYVORQnZYdobLueYBygJQkLtfmPwcPXwpAVgtlMPNCUFCHuGcauXIMysjbxdpCOZpSHyEdiAnFRfYUjfybOmJyhJcxNYuTnUaITmWHFxHZCpUNrCNlBcYmqsQXsIsbCVgEUETUEnAwCUiGsvcauANTPOBMoqVSaKyQTMrgKJjvJZnswfCkvtgeFgHYNwCmzyjPPqykafPyHLqRivOMPdTjDWEBCBCQbVaiBGfbnJSvmGgyiuueqlahjzpeuQeDqcouCcYBFiCowgXkyUzRTrZJfYDlZCLLgrsRPlPWYeIRVAWqLHfsyYdUMyogqUttZMXTWpVxtaFWqSrDSANMPxPHgkolwNmBjRemhjRpdJKgoDTwhmoDmIfTDRIbDwrjFZkfhJzKSXGnbuQgwSnLnqeaNDJwZPxckRoZTcCrdkBRVujkGqLKLVFXwHSdFznVCxckLQVHpbtJWBnvHiuEQvsCFGsNWpugwqdeNKjSutARtovERDfGlLQETzJSWQEddaZjvpertReCNqGJgSppkXfLVyzXdCyLezvFCkyQfYcriietzMghzJcgheIDMmtXaKRlsdJqxUsaMrbaZdnjwMSmuBAEcxNmmdhDLzysGtlKAahLRoSxewNVauPHsvsWVdDhIPsyZvDqVnkoDYUazXBVkbFyVKPcIZsmOceoxIvkvJknmEuEANNiYAVtkCIeamzdhoMqgELGvXypfVffgmdoNiDaRQdGhtRwpYKTWHgUgkyIUreHukuPnrnhWHDIduAxDJxGzKpVJoYAzEMPgsIVfSvWJfCSDlfzjlVKeJomvYMEoWNsDYfiVBUPBfdDgoxhKhkkLcKNbWdDQWCgdnjNldAQQLRkiSvWcwDGycOIqKVEOvOGGUBaSPWSXrOXvJBEpVyCzNikwGqzHbGOjUkpqQJGcIaaokRYNcttQmgXOqwtmKwxmlmsuUqufBBkrMeuOlMdCmpmUZLWfAIXrJmpmXhLycUWixgyWcXUmIoSNgjzpoMTVcsEmVJjAIGceCJqHvUmbbFKArfLPlFiBtxlEacCuGzjXcxyIiocRNgnoWBetPXxXtsFyLfZTKNgJpOTiqqbKuJjJonheUXoTpWDXgiWBaACHCtdvTWAfRyxuiZFuYptuFpmWfEtkgfrhADsAYDnhZYfAdUhbdSJITsmnarAnCSmOTFWQotJCJbHtnzTNVJDwoCNloPUudhxyqJoeuDIAadfjHtSaMUcfiAaOEdWSzJhRVVdqtfZtgMFiIkuwsVYathuwdjCAFGOVdOQghVsJJIvEBShoZIXrcqUuwghobaXVwqVhSQYYripMJWNWqZvjVcIGmmHDFQdNdWVgJByYgwXrNuVroxgpxWHHrWROqwgRoscucxhhiQfVkvLekGbKLzNDPxYpGZjjeWGDshquPxlFCalDHTZetWctIrCJQUvYmMhRzYfqFrTnxKqzqehArdrnxLpqTjmzLhoYSNDbsdILiDDSRyNHkQdwRAqrFLOTOTehYtWnQLerEjMYDIASQVEfxZmKwwTHfDkeIEMwxVZuzncWjyhkcvDAampSVmhgqUJSKMJbZlQOiHxgRPrSxoElkEdQwzonGcKVYspShveDAxcVDXcgSyDARORysStvpwoJVEJnafBoOfwDcMKnDQPFiJptbmydpcVSIUSlINAynPvXlFpWNopfnCcVElKziKHYhTAgIGyiczplVVNcrIYqMCTMtHdrkBJVVVgSgnIigeooPFvNZOPZMwqBTitUcrbVcVXJCRiMyxvXIFQRAWnTngwmVhfHWZMbDrFbDNdXVnZowwgGccQOmdaoqJZFCvOajOtPpLJkfhkfGhRnOlNyiOQrfMHXvnzJmmadpsnSMsqRJpIkBBJBMXUcJLFKRureZbIOBmaONljTFeIFtPrbuXLezvqKTVDuJHZFzdoSPyhnotIgyCqgJZQQbuUxntXqdoXdNqqHpBWCOGttAAyyAMSSgLNgnLzrFyyDzZhkYHuzeLHqoTJxwBGLFtaFlUYrMshQdIAuTtdcbSpXoTFOGwHdAFxelJEvXoGtnbIKfEQpijExCCbREhWhcPobNIarrmaObJTQfqsGaItPZcYLNlZwyQwrRlcvxEdVkykuQBCuIlmGXvYxWMDKQoprzulgyzBLmxlWtHWGovpMlpHZdQQJlWdSZHtaNHcULVyDBMLETDTboOzBReoifeGCcFOglTGuTPXHqcoxKqWUIwrEpNTwcFTtzssJUeUZvIrnLUwvLKahuOzCcTUPiBKSpGGIYFrusPOwMnBwNETxNkrogJUopAkymgXfKTzShTpmBzabWFZwgYttAullFSHBjwzRQEstnBjlrqOXRVwSGTJnyKaPKFQlPyIskMHPfuTSGBOFfUPONmqIyXNfAVzOjsxzgPdyFsZgOYfPGHhAWSGFsRMqTqHgHaCTAwfbhjWHltqeqQVjLNPexNzSipnjKvMJbsRRYhTIkapOozCLDzkAxKoJIrXlRESVhWXMpcNXpFNGtMhrkyxRSrzYiZtmuhWSwhsEaTZtRqUCGvQyHazeaimSkLOBzixaFjtNmJlYpYJjXxvtoPjJlEnrjJTaEUEVkvwDUurLHfaiYlZgKehNFmdqOCijHuyNBUGcyyRQFjtOvQFFTBxnpzUColtkVXZMeyoyOLBuHaaNyddVdoxbKVFMFFtRWtyeeTzwmBpDIHagsCyUbjUdVxuEcaDziMVpHfrKipvjSgSannPOiOYrVjlSpPFzMLrLpWlTscvddCkXNFfxPaiawlewgOIVMlRYVlPFsKSFkrGIXtwyzTVGLpgjgVaYmpHLxBzZfErBqFvqzuyPnqOyZJRMmqHhSrEAyzUxGJpkYJCtmNrJqkIzAghrkUVmdcrYEPhWOdEMigYvQEoVLyqOUrtqPsGxpODLyOYCyTilnwLrIvNzgIvdIWnGJFtsreLteSQdpbANVFELGrxjPIHdHDTMtFVMUObPPPlqayEJpVlQrGbdEOKnRwTSBDYMpddrSWHTVfyOEeYXSaEPKEVbBzktLFDiHNgFaerFomaccIITRaTMHLkkVkKpKnPcnkGgZesNpjsaGPWvGJbezlkatKjeNbasBSrnSpgWddpidIaJjxgREKbPLAYetYNCHEbDAkACfAgkcZasqaTBzwFpSJlVzyzUZRUjjYytqOFhxslGCtGsZfJPMZNkUzvABfvwQraaOBafWKpdHLwEKOXuoLQhEuiwklxnKBiGVwLoNlKZZfJhxPTNjIRZIXeddYZHjrhjCSEQhYYNExutgUgWcurmXSAFbVVuPEDNfEDsYUtlOEvmqBPdibZdnSqPxYofICiGErMhruYrAnksBphLNzkzwiScYVwsUUobyWXzjmLJwYJPopkcDpIuOXQHuRxfYdBHjTkYlxBoZSjOiNdJYrkfdAfSwPHjCHASzvtDTuTKnGoGVMutnCFOcmHTIr", + "changes": [ + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.300000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"95\"" + }, + { + "subspace": "gov", + "key": "tallyparams", + "value": "{\"veto\":\"0.271000000000000000\"}" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"10\"" + }, + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.620000000000000000\"" + }, + { + "subspace": "staking", + "key": "MaxValidators", + "value": "52" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.270000000000000000\"" + }, + { + "subspace": "distribution", + "key": "communitytax", + "value": "\"0.220000000000000000\"" + } + ] + } + }, + "ProposalBase": { + "id": "67", + "status": "VotingPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-04T11:36:07Z", + "deposit_end_time": "9936-01-04T23:54:25Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "355" + } + ], + "voting_start_time": "9936-01-04T15:40:16Z", + "voting_end_time": "9936-01-07T18:59:14Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "MsHLpqGHtDzzqzACHaGOqiPDNkrNcvGvUwvdSmuMwQESgQAmDZrbHymDnGBavdMUiTUEWWKkdaUJypPxEuwCtIwCpUUnqkfAXqoHVTBhjCbhncjWgHpcicMJLtRRxPVRrnATbvqXJpyG", + "description": "wUYCUlBzuVxMhHOBauMIOxJnRVQIdYybUYNZbkcrkxZwnAPfQtyWegkIRtrYBOqApJMwqIrDUjVKsjXjmtKWlWGRvthBNWbkdJymLGcakGQNQaQsuAfriAKvxcaxjqsduSurMZPshcbBuNvwGIxWSBHpEmYZWQliSMMavzNOOMSDELGXsLwwkTENjfFPmbwfmcpbEbRZZXdMJmJFkSzjumqRLcUEbNOIJZUJcKBwnNBGcdhvMgxKEnMhFBbwLTjBsZlcgYuXgUBXoRSLYsPacKdsuNxZuvDVdNAhfaxWtNZTwjkCSjcfMHuTzYJuPPigzLIYxFCdqcTplakLQwLsckldDJFgrNYmaSKYvqWDkPTJBMwCXLzehCvRbTxABFrXUDDBPwJYuWDtylEzfKPfpjEIUsiTblQDWalyWkagijArJnIxDZSdknCSASRuZZCFwFiyjORUjaOPgmLswIGWtqpkehExEZMszYqcXyuyeEkRVYSQHoXnjvKiBktHUsBobVtUqAOLOuQzHpMtIArDTMAefWaOsCTwUJGgcVFnraVaLONfEWzBxXftyqVNmlznvErdbWuOwCQVhNStEBdMfucGFzQJiXxRBcDzDUrpbRQrsKOikkmpKoKvZnKELWubiqsoDYcaszlOMrhkyKjlYWxvVbtWBtkLFJKVZCgrKVPnoGKSSJutZMBgQHjupCEvlprHqWvmAhritYrteHnScdLsCJNOKgzjwhcdxIihyYkiAEoeMLfKhNTwiRtyUraguywDgiwGIvBwuOtsVXjBFPUAHGJthYwryanuKFneRHyvYzuwqUMoobqficfifIaqUcDbDZjVjiahZxysMJhnuOJcbQWRsUoahuJCShHPFSveqhvwQaUFofeSfRdxLbrrwTqzJoeiUoKyDECvebuFdzkdKJFRYGPWkmdlNoFceJLlVOtLWQubCSCEEWtncEjqeBoQxSQwGeuvdqzTUJopJaCeagmXdWPSAdMIlsiASDlqXlYwACaKVAClJzDONHOKLmtxGqIPfQqlbWbvJzrakskQGLYuNpkcfEbmjfsJLNhYCjquZqUrLMWYohoblZuTtfdnsCkVtNnYLTeWOMNfrBDLQfDySqpiRKXfpKtJDlhthZoxJLBVicHAfTZgeQxOkHUVXQyhkzhpFAZdPkRHUJOIuWPFhGzTMNCiQtzFxHvGzsMQKyzSRxFOOiTgiDxYTBMBpdqouljAkYAXJgbNIlUSjQieCwXTdtiWpStYFtAmyWdEeiudGZZtUTmQoXwtYqDVERYRUqHawRAMfEJNFtpaKcBEDTIingpqPrVaeqmdJtKVXXPWmFFfxViZyBPDlWXWhkKSzxaIPOJyjQCZyJwbOwiCOEbYcHeEpHOKweiXXPclXmuoFvZfLuiWqIBirDalzFlSRrFZdKxGQZDdOfYvxpLaovNJRlLQmxnYzmHWUrpAzcoJlyeLCzXSvrWlDFoVybczIfFFjrnzwmLtbjlOWphDjxjJYnTAkPWYPdxajGJMRiacwLIOjbcyBcwkKnJNTYQtfclrDlfYarSoaUyWRaXDydFAfMpqMLTaZNtMZwnbrBShaulIlIFMHnLAtzCPRlUntRZhwDPXlYQTYoLElEcKArleoBKFNnjoiFsMrThZdjbVforSaeasazTAxmHdgadXIuURyXlylQJWlzrXgmMweKyEJQtONTRqNzwUwSLSpfOisTewkJVVnaIYFymnDWipnmZKPtHRWlgfbRaqvSXqHLUedninmhHPLToOgnYudtIHTvBrhlVKzNuHqrEczYlUPSCwpWlSFeUTNUtwImRluisqrtVhFeBdbILuZyErBrNtswaFzhdIfFltIgoLOAweACnLXUvbxAJAlAWhuxVXGvWFEgQNgtkLXtTAygXWWihIDpNFnNnMhjKRNMZrGdPvTJbnQCPoNzyZfihTaikpuSCVxccDcmjahIRCPTJeTyxwbHwgUcvilKJAUeWNrJTKXvLjewroCtceJnQCeVQRQEqfCWwSssRuPCqvbDopFSdasrRpDbSCqrKeWoAnptbvcOZAzYzhJAmecbZImTkBplNOeVpFnssKscRqypKoBjwdbYgILyTIPdAUrWIgXZJmQCSvIOoijCwfKTujmVWqTSPeZgmXPdCcfLRDmzqUrLJjOZdGwtgBatJfNbwvDivkBFcnrUcQIbYeZtSKVGguCEViDGoemCEdCmPXamgHIwLCxTNdTEvefOLgZCtmmuOTWOpmWsPVVYGXFZczJVFjzLIJtSrgUqUmXlHiNvisaDYvSLEaBfbMFYIeNrJhBxFYKKQSeiYkdvAxIHjRevvWmTGHVYtMFoJzrXDVWjPkldbTjFniyhaYpsfMeLmBSdBNOouPYsbtDFzHsfVOMQjaEPkvaZSkBvaDzdOewaZUUgGPRGIdjPHCychYJCOkFydJoBGrHhITUxwDefzlsUBwHNYLAIoSAKxnfVjHNPRYanziASmNBFiyNxTrDKXJvPHnMfnsreBkWBgHSvUapaHMKuFDrjnDRRzcFHwrSbCFiPLZnmWbyetZoNYZoyZIVJywWhHFJwTIhwwtaFiKaVFghvJHtJLVzRoYGQwcPglJvFIvXZTZUHwpfRieuvGaxpqbfkREvpkaXdZOiVcEREWfOvhgBuUwmwCiucskSMElqgsnqKekNbmuyGhhLRzOSwYZlEuYyIiGGwrIhzttlOTUyPMzgPJSLAYMLvtpxHqpnIuERWlyibxGfjyApqXAylArBlzayoKILLrFhOLuXnExnEtVNjMaudXChERvNLEpROVjXrgemKqzBSAObFTFrYLWmKEZfIIldQZnbPdaeaUTlmOAoJdjQVAncMPdYqEpWouMbfSWYjOGWoLsVLvRADfBEPoKkKhOqFyIXCksQksHNxBBRsCOgUcPiLXDkFduhOtzpNFNrOCCTFWLdZNzFuHfErQoOaMJylLafGSprPmIXFtAKsORiDnCVOxZGzIeGeqpZSobCdMLyAJcbWVFpnYJmaFgTqadifjZbKDZzonFvoZFHjtqevcCRUGgGhdRWUZyoAecjurmmxahxmWvQtbHBCkvWaRVbmbQAgtNlKbekKVDxEvxUPGhbBgysGGfnEsOaKPXLpdmrjWXsGKefrsgXllnaDoIHCqSqRoBbQofeZmqrSGGXYgixfxoEePyIDBiHMGqCAPtnHwDfcKrhIInVUyvUetKzkEMrRtVMXPWNwgeTTszcTCZiGDXRVanHLuCHuSJRQVixpLUaKdOatAkjbSGHCwEwtZiUZNJAmxxcIQExPkwQhhCyqZipqkVpOZNpdApdVcukQxWSfIeTWnjTyKhBPMITgCHDARhNInJWixpMQmskQwZiiBqVPOpvUFWxGJXjhecHOswlhbXToRKjVEItQLIMgmbpaasugGpAveDHhLfjHrQiOnjtiRmXPZwjONppkMXrZwUXYVROoBaQCrcReAgprhMjPdpIGTHPyvPgSojyyFxsTBSuYBNNBKLuwXtHuDWnhEiemLhVgSKNwrVvXrlgGnFcAiIJuioOQfYEJpsAyQPhKPWgpNdWADrRwqWWEfzZqMcbaDNaexCHwjLgEfxmiREVZsFKsLiJoJmokiNZcwmuvpVsGzVbVporMIFbCNvRfBTJUpwwISNUjLwUUSTKIsawtmjEgfpdQynklbBTRDFxCoHxJbXlbIqGgEdVLzbIZWcBelIpgNdnbORWbzuCkofMLqFtQdfHXnLoXHkvARCpcMbuygZPQyoJHjwKkjNJEiXYigDdsHllWzvTSlmDcDZyluMInvlVVowjwwTYAKAFmYkCCzOtKdquGdmmFJPMbdrDvyhXFNimYmLrQQtuWLraFXRqrCOWWuwVkVHkKKIzBOroTJPhKhcMlfxRoGaYcxqBVkEGHlsmbNNnhVywfphbxutVVMuvseOhxtWayrWcFSftWVlrsIveShmuDxtriNmAnLXOcESnhuoTglzVciAoBcAXKaJqEpGkPngryQFnkQHbSnxbJqHGuITUoQcspviRzjpHxShSBwOnGxLDivvyEuNEvRbyPhylhoofifJdOvsEWPPlCruEnJTZTQSAnYCpBhHZkvTUYhpMoFMeIbxtbdjhBQXJWWugNwgSiGomgBNfycLhEtscOdDbOCqjIeahBMBJPXyYIlhgDfwASvpjeNOgnRyjBrxnnuENsGjNzBLtlaVhQayqrhmUVEiJiqnTOjyvyuWCkkzMgoZGjlEswJMaxPqQnUOIwgGiEOfXsUKqAHXEprSiNYFQYWOWYyhfYbFMGyiejsBsDvvkodzAdXNclscGlLmaTzBhOolEGyzOMlfqlpnnoixPPoLmosYZnjQwOiYDWkVsdAXczvGSgZZXKQvkAUiGoFnWZAKWWmAuiFYazUzfoQlgOSpgdQsWPjAzuZiNXjcwVxguiarzGKDoiBvptBmFhCSvmzLGSfOkdPpvXGjHASiVczzNsmXTPtVdAmYTAqPTNjabftWUeAeuVCJjmIpALGPqfRqAuXEOVlxhUmxjHoDyCpsdvcpZzWFWroJNmceCYRGyVLAIgyouOIOZQgyIrxSecNkKslBwTHifpXqiidEMDCvEhlFGbHIkIhWjYprMzKPvpZaqNmvoTtywAIcpLchRKqHTYknKvHCOWySYuLnYvCBeUehKfSjiHghMadUYOotYOkhODtLYMrdDLRmvpLKUtUWvkOGNHfIqTqhCcvslkKDnwQECJtpsLfGvwYzmCVjOJErNMfgGDzdMcNBhFKuqlqHNzYUaIVNrZiQupUOiATTXiDfLSbCgWTeTxfmddNcQsGNkYxGgTfMKvqkpplUwyhYTUefXYvJvfhzgfLZmOnxcjARSixSHigxAvYswihKKoKTOWQhBahLRuVezJBvVTDJVZdUPOgrAuqAsMDzzVXmCifOJyAndCnDggMSwEdCZeIoHIQVLJfMNFMFTGorMTgYLvNRCenZMQmpFVgHwaagnjtoJUuxOcJB", + "changes": [ + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"330529000000000\"}" + }, + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.300000000000000000\"" + }, + { + "subspace": "gov", + "key": "tallyparams", + "value": "{\"threshold\":\"0.481000000000000000\"}" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.400000000000000000\"" + }, + { + "subspace": "mint", + "key": "GoalBonded", + "value": "\"0.670000000000000000\"" + }, + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.030000000000000000\"" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"9\"" + }, + { + "subspace": "staking", + "key": "MaxValidators", + "value": "148" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"8\"" + }, + { + "subspace": "slashing", + "key": "SlashFractionDowntime", + "value": "\"0.018518518518518519\"" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"167\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"615\"" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"79858000000000\"" + } + ] + } + }, + "ProposalBase": { + "id": "68", + "status": "DepositPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-04T13:24:43Z", + "deposit_end_time": "9936-01-05T01:43:01Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "190" + } + ], + "voting_start_time": "0001-01-01T00:00:00Z", + "voting_end_time": "0001-01-01T00:00:00Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "FIxEAdEyEmgRyGbtmOGeBducacJPpnCVJtknPHwcWbOPfPEsDcyKfrzZJedKxZiihRMAjTDNntCSinDOahbWcKNmLjsEGmpPnzfKrWCrbdJvgJZZNJiYiIAvdzVFKtbMBTlmwbGAqClz", + "description": "uiOjdZvWBbttkZTIQSzcJDXfPLCvGQYaDHlXFQLCjGiwixTcgWFyRqKnDiwchTlJumaADhVsRXZPLQjPnRDqTVNulYqElSRLrqRRazLSwTAdbHebKTmsLUBTHWExfmsQCtAZfDxaHXAdAkVbcTESISbFoJBNFbvbsDWYHIolJwBnZKIAVcOokhcytVvaAHxrgXeMEOkShfRdzfYpFESSMuDNVOVXhcwkzKxlqwJlDPIZfIDoVnnDUPdgGOaUKzVTOUSobFzqdvODdEsgatLnlDolxMarcdQyiMnnjmGbhhuhOWOPiBRUjJcecgqduaeDrIjgZqrudGpkXbTCxdbUJAyrxiplZyXHAVaYSkHRofmQKEcWyYKmROGoQRerzyKVUohSgNoINIKfXTnDnfFXLxYQpqAbTkLdGVwsIrjyqVpMzBZBndPAWtEOFmPSOEubeYWSYNLYhcZHOccvZkQfWrvohFIWIvkOFVEzTHojHoeBVZOZhzbQeTbwRecDbxVNqpktdSzeiyOTXsCLSMSbHJJIgRuJfpTDnwRVGgpybyYEpPxGDHSyMBALepeDooNNoPlHPvCYVFOvzvXZbHKDYPcRNaNRaRRquwzptqRXcdJtYuiAWvnzsBVvTedwMRVOkgUMcyLZMDNzGzUEDbIVpqOcVtcfthCuSXiKrOXjCYVIKaWTXTGCUaQXiVhOTSNCRncoVcmPxtbTERUwGCOzREUyXRaoIwNDOsrvwfEKjJCurnjzwipibHcxlfDDuenmHOcVOzyThZaYnlSkwdRfTBNJEBmCjfoIcHKZbXGIcPMckxXVVRFsGvlthmbsgbYOBDdWSxQKFxJLsszCreVFMzlqYODIoqDTNHezVjzXGTImhpYtnblLfCtKMqWeRwzZxOMsAalktaNhgczKbNjuNKRpUWvPEcepFruVPSFtDQEyPuYiybhtpPlrvyBeFTGmCXjJqYhoATwAyCkbsbjIvkxWtqIMouBpdybyWHflRdFRslScecCgYmTsnZdzJdTwTKnrVRFsLmMYwgRKRFXCwLSXlMiKYdjxlsuyiGCiPKDSJgLwxCDyIptmwjjsBXFkhkTiQfjeqxlPsxvvmdwXlMmqupSErcjgIWxENgWzvJWoZHdJOAjjVKcLxQocOSqfrzaFVihuaYblhHEdnMFUvbBMOZzqDUUUAAVQhANSFerANXjOrUKccxjeiWiMoDFfopsTroyDKFtqTrNtaAkbImfhDgXDJuHsUQMpqiUxCIZFovhyKdSGKCJUlEIgAlhWtupkzUwHYzlaVaTasQKKbIaJlzNsPwLmqpUqGNFLFMsMkQvSSUfVutRctwFnGskbRBPNyMBqfYNjUcDDtWfZHSaVGrlfqccqDqYrbtWQzpiFAwPUiOoBknVTboHVZMZdmuyFJcaDPVTUVjxtIBOxptSVMtwGgbAcHDlDdzqdVnvrwDPMyKzkdgKDtFBTFsbDpScyxCyujpIhOWFVPCxrfkvMshBecDJNTbHvOvysSDicYtgQeAmflshsIQukPXoHIWgOaxCQsJwOUJuFcPlqdwRITbWgVpnhWUGrhBaDNPCMmQMAOpLiOgyBNsrfVjZLMenUgeZRyTtqVKAUughBomTDlrFnImBhPrtpXfmTVlSuBmYiXNIXYXvLYrfzdVnYwEwQwaiyqrmriOgGYcSwxpLQNkFJGntEXZXGLSjdIgfkHkKQlRGiFUDHjpfzxbIVkRzzngHcbtevbxvzULVoxlVSheIJSRKjUjScmZFnqjdTYtTsKOMqTIDLONnmfCIVKbzHWhZGtPfoPMlnnuZKVDshiveNsfwApsknWxCtpxALtCPcVlUPfhzoPpTKytRAnGFhYUakiLLIHGDGFFiDOoLChtZjFFeujofMxtVjNpOPqyiwfzemzCMuWbUtxXmmvwShFuvIZIvSNTvkyAYAodBjsOEtmErWHosPtAhwvDEGiJVBTGyxPGZjnNpAjWQPAyibZEheEAYZAnObVxZNtYzPhtHMWyDXRPsQgLFeAwepbFgBdZrdUoxEqamDVlCxYokPFCyiWguNZuxJcWxIOQBmuSbpFIWSWiyCMSBuBusqPZOhcvdKLIgUswQBoItlVAexCyenpeGmjqHTcsAPlovJHVGAHFnUrKyXbfUOemVJBrwvvaSWOolXIoTxGdwocuiJoUuWVoMVofDwcaMGRXkoDXCFAiyIXxpvokStzSdewOFhNKXqIWHmSvPoNYsRttokCdFaXXfFftrCgpGSwUWBuXDDRjoqVsVSTaXdcthCwupmOsQNpVyAJBHveXExeXKeaWjRKCDbYJIIutbvFBuRDJKnOHyZRZRnQmMHSpVybImrSNZKAiWchcoLwWYJTkUytpDYzdeczhrlNbslWtIReLAJGiAsZflnLAadYIjGKvnRKHuRmjxhrTvwhddXIpnTMMlekBqExtxESYqWwfrLIJGnEVTgRYiyNnWuMyICwJrbIPyXYCwgVkbHtMTUIIwKbASHqvSPcwIsttIVXylsEixvbEUVsjAdgFvtGsttTAvoKPBUKCYoBDcNJSdTcOMUNKmYcCqokIFMYovxZdQXBQeywpDckYrqVJueuywxmJCMjOEVrLgnVsCsXfahmikhQDdMwZkJpKSYcyIgRIaTHMAsFWvDymryBUOmpwUdVYvoWHtwZDWuwOtCcrUVVlbSbCyacMzlEPHmxggybBbZZdAEPrPBeqADzJWNlRvfBQeQqztrWhgFRmXbgNvtEsbqPCmDZWkNohGIFGhDijdOamhXLFcAMiVaDXTroJdSckGoAWXHfgNbKEzpBRbjcOTwcXWIsrYUUFkWBtuFYnpdggSLIFXiDgqbUAJyGFmInNzgCtBvySbJduPAEMKrHZJfgLCZettyGuDyvNnxiIRnDbbapWAkxDfdcPpmMlkADZlpVkPJPpnWpDYSppvXdJcDIAaHydKzTNghnceVTiNwVnQAbQKwyRWLkTJeJbokQcYjApvbwhrDTcvmVCXtKDmkRLUUYpnjaSHJFKjQMIIZkKcwtbXwUqKUidurWBVNrYtWZyPoaHUslMhCkFfeTonnaEEvrzbbLhwPDzsGyJXfUtdDDDpxTRswLLRpCQGTOIboCLgfPMsqfSzHhxNBohOQEEZYzDWGhzifCAVehLfLucdMHULcYanwZsfCseuWmCOUZJefrqcGYweqleOZmdKGmsHelUVWWyHzzauikEstTepJJPpjfHmdedIHyuuwcdIOjTEiCaMdtPtcjRhjceyjPlVhcsMvRYFplGjdCKBLhOdnFcODrGZSZOxSVUMcoDAxEKLxtiyBltMtoSWnNBuTwaxmRAesZTVOKDuzSZpRcycFUYyjzSCRuVTYODmHAaUiqqztqzBdoUEDIBMuRIypKmHhkvMArHihzbqAsVaJQHJJyYAHgALBuphKiMADfgXpywBqiBwcraJLtaEWGokKjRwLlLSYrcTYvjHNWgPyQVRtfOnXVLDnOTTUyByidjJGStGwQXAVycApUWLDlObQpfMkjLYrYtOcjdJnWYhPcGlrnwizEUWzjpxkVvkFeItfEwohKpoCeuBtKuVpTiiirRZNbMLcERCqKtAfuaiPXLqqAEOwzZancofxdClrdDssNpnUUypkYXwqyUhIIpPwwmREWDpgFuasWYiZZMtENkpJOnNrrRdwZifKGoqOaEEfIhduGOSjXMEYrBHpFVpilNIhzbNBKIpPgxkuRqYPohWhOlLsDfQixdVbLBWjUczMaXFEBVyUxasYYhSVCWGLVFNFzPOOSrcbFufjhDGrznRecBzzYGnnFjTHNVOmSfUnlZbMhvwNPbRzCEhsOajuEbVjkwhLAmaldTLamaFdxxzKEnlIzNGUEDZKqoTybFFWnVzclPpQKPFqbhQWZGMSODiNVecDtgVzpekHPYVCcOjbGfOQMCSRfFCfSFEDowVBOBFwZlJCVzcdSpeggfOrFQsRBHobFOxWTxYgfboXTadismgOwskSliZBkXjbUzLTvCQidmYUmItzUFQZVpyWwBcTWfftfssJYxQrbXMHKRyjjjvBzpmJfSKZpCznNNmiYSSmsbOrMEIOSITiwKeFlJRzgpgjIGuyplYnFvyNlEtvSdiqUWSfXKtaqhLHwtyfFZiHNlBIDCqWyKNUIxtipslUybQohbyKUJpMHkmsJYPJNsFqKQztcVYtONScPpXEqafNduPKKldKohAavvOIUABEdxDIXtvTFUKLryCymdPthPjuSICdIKWBFdZjOZPmpkOpcpCKTKEuJDkWXOPIuoUkwkGjmlOpQKKYmDkxGkFhIcHvcmjNVHwdeJfjsIZeFPCtGoidrQOKBZtEyAeutTiSGbzMFUgNtnkAvuhsoysYUJnWpAdJpcqLBsBInZTHdxhQWNzjjUqPaJBTziNKFXtTlIcZlwQjUCoeWrpkwjruYNHRxiCqmhNPJgdAiXcnmpZPcwSuzgFBWQwOortvfxJLlJHsYDpPNmVrSeZtGIgnqLGKPGNQHWOHAMKygULdDQddHNsYeDWNoqSnxQzSkbVMvrgyYDzDKwrFkalcUcmCWkGMeDBYOaCVhgwSUwxluxQrmUybvqKNTASRVFWcHWzuGbHGSfMylmBtmIHwWMuYfPidxizBecodqZyfDbdMuNllCSVBZpJYVNSOUTNYXmQHFmwlwOjtczlWfdOzxeTEAsidhaozXiGeOZfjsStSsWvhShHWMmJCwjczmGlrAZdTvoRRJtWnNJkEAyOcjpjAQWbtzlsvVEHughikBsVdxAIihksOSAFvwAuWPZCnoYtUQabTMHHMSxhbXoBLEbTfyfPqRJQUkDSCcWCepnEgoVOnENQfePpFYJinOHNLGImIzUWSuicNgipJQEaJvCBdhiwWiLAYQsZGHvjbYZnLNaXDfBapMeeDfKwTNCumKTTtJsbYIvIYTTpvLuweGiUOOSZzWSpKZAyCLhGkQLLAUNUJrJxukLqkjDPWCEkENyrD", + "changes": [ + { + "subspace": "distribution", + "key": "bonusproposerreward", + "value": "\"0.260000000000000000\"" + }, + { + "subspace": "slashing", + "key": "MinSignedPerWindow", + "value": "\"0.600000000000000000\"" + }, + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.210000000000000000\"" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"9\"" + }, + { + "subspace": "distribution", + "key": "communitytax", + "value": "\"0.270000000000000000\"" + }, + { + "subspace": "slashing", + "key": "SlashFractionDowntime", + "value": "\"0.006289308176100629\"" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "staking", + "key": "MaxValidators", + "value": "128" + }, + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.640000000000000000\"" + }, + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"230335000000000\"}" + }, + { + "subspace": "mint", + "key": "InflationMin", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "mint", + "key": "GoalBonded", + "value": "\"0.670000000000000000\"" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"155\"" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"421\"" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"204145000000000\"" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"5\"" + } + ] + } + }, + "ProposalBase": { + "id": "69", + "status": "DepositPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-04T13:24:43Z", + "deposit_end_time": "9936-01-05T01:43:01Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "138" + } + ], + "voting_start_time": "0001-01-01T00:00:00Z", + "voting_end_time": "0001-01-01T00:00:00Z" + } + }, + { + "content": { + "type": "cosmos-sdk/TextProposal", + "value": { + "title": "pOEmMucrNnrauabhxZuGhLoDGesHzrGTEKvYRIMBIKyJAWOZfbhbImjUXNUlHSzhnWYPmKGZCFGyNSBKClnmCMWSBDCbSwJJYvqmZuzKWSinuPfKeWuMeIdyJPTDPUrgaUOgmiDwsthv", + "description": "LemUlDSDgWjugDIixCgBmiRYJYfjdDhPwxfwCTvCbuseHBLCojwMyhynuZwPBjYZUMpGNukWEIiMlJxrEKufAiqIZifelGZbxPOeHzxKwdsyBxrUTcPbQjPYEcJULzPVJkENUeOxpumEXZcZRiiADEqCXzeWtTKEAeFARGFKwSOGIuYAJAmZoibbQWvwlEZOPiISaYyuYnIAUcbPNGRnxiWDDcvlvdsGhSanPYjDrfvNEetHFxyQncQUfbLABrDRgWDgTCwdbcfpLtDPfvpdvEuCGkMSZzgVOSzHVNJeYQHvRmnXWnlMymeTdDtFzfhnOeXFzkkHFIEzcXJXHWRUvNcbkRWDHPwLfZmxwydVjiUgUMqivmHPrqntZmBpsqUnlmpeiZvyZzsiaarGPOdYzotUZjvMKkBimtWIeuIAjfRZlHRuXLIzQUXTzlWAVWUsvEjoQmwlMVqXKpydesvGRZFhiLxCLDiShhbVVbuoIEndYCISXfgkbDxrzzAyZqFJHrOqtOWnshQPetjPhksHZEvGcbbPeVaAKuETUseGsrPPAXKLygCtpftJRqVjjzhwhwhPPZzQHTNbyXgtqMYlTkTgVbgKZOchKllyIEgPqnushFMMmTRMsWNpoyitDKYxoGEeTspSuHhZeznHJIqOmuApLmSPEjFztXsjaySqXIYAPLQiFBCcSZDwUNjGDPyMyNuYgorXMCtgOYvNcGifPaPOJtfCzbGHvhhlPdVvSAXBDLfdnJeCzhTTlrhJQhemQcirmuQkPuMcqsBwNoNVCEYGkHJnoTJmdIppTojzQsTNqirNGHpYGqHtiITFNaqpsfHTGCiVjjRsrXVkuywQlJJSybOyJGbGVssjlZKFZuGEUSCwcVafzAqBzMBCbxQYIBTPiSBRoutnqZgyhhuUsBfMKlLdldioxDFlxeaaixGggMqanRVtRyeNZOhoQOSyUmxYXouHSsVMrRYPQMSahOCNoiaBIGVweLOfHLGHcQQpdmvmctsQzNZVCzIpUvikPsaUuPydXTlOrTYDsGPFZmZObKNZuLbxnUAtCgvRuyhUMfxRBJJdxNGfyTVmUTTxcRNkSqqjMhcYOvGQvJqGTfgrWDwyajaMYxHUBIDMdJLIxaVocMwUNjBMyjTRpSIpUPfCoLbzvdpeitZQwvSjbHjrcPtlVaXbTleFeLZqtOCyrLURbOmZlNnVjfLQtorMAfHbohOFbaHoFzmjqBHmxAqIUzZCbUYMERsvXUZiHNGGoreGByLkIRPamGPCWxDlQGsHyPBNuhKPPVPsoVqCxRBJbYifXfGdRDkakQuipjhqnNLOrjuQNaRXdkZeJboJrUeqJjNqTeSDHftluAUeKKyqzagmxtDqbwZLnsdtNQAphZkLaqFvuXYcHamMiDZGWCqYFkUcVYDPwRqaQzNzYJALsJCiyBTfcQmdlylKMYpMgYgCUgtnaaKPlqkSymaTfTEvJVGFCGxEelpdLUDzyLAkiSJpxtuUtFuKUtQrfWMlodLrdqToEzpixEjUawHwQCxCCvFCrZNXjcLopaEIkMErcMMhgNzuxCLvitZtASPjWXBhrtDtfsPfwmUnwGgpFsUVxBRkAKvtlvfbwDRJTiMgunIOpBbbsEfBeuAaxBCluPZyeGLzjoxcoFWGEfDrQBRqaWcUkKuAReIBswXdekPOsStvessqhQnbxeKxgkttEijTFPwFrgEgJAPzspglXBKHKKJikWffbxWiyYrxvihyLyxIgeDsVgDLqYfLuAWexgANwnpBNeMfBEQeXqflVQWonCnrzETonrFYVHJinipltKzyrGDVZsUpxuAWwrUxnbucKJDhQnkKcVWTURlNKpwvzmganrrdhalFWnvhSUHuJmVcPKzKSqNgdNQnYMuywqgMPqXCKmoFPykqsgMGwUILMKRPDyPBpfETgGSJihZGhEIDgvbNdApqABrDnEYmCqGTwDpnnoGkmhQcCKZMvYhSQfZDdBgKmEhBgXBGiVwaBIzmmSJexsYiSAtlgCLBpRVGyNrinToTtdNdYOXGZPvoYaPWOBDFYYyhOdyiZQjiwcIpMspHcYDIlCgiDvtJyZpyLadHXcWjBugtTChiryHQYqlfPaFLSnOebDgGcJiepUGPsgePcdjsNpERtzuCOAJrUaeBCdioApdNMczRVKhKckmyOQQLBWUpmoGZLuKfOmisaeBYEKWsBQOQWEExvKdGLBNpHJRCwYQTQKyCRolVyLTerKvgnhPpXOYFYOCQrMrbBHGIYTkfJFHUCbjRFxyNpmUTRdJXlJXqxyfhYAPbhIRFIXxDwDSolEfyrqnWhfqxadfyPzoRQLzLtCEcbnbQrDaXlEZEtKGBRObpPBeikRjdGcyiSubRGOIXrDGIiATrMkZEfTynnQHfixcKqYwldUDUCcTnyiZtvbFOMfEcFFuWRGVkMcBkdqJDuVHWawioVBdxGJowUEmoKTImUlNnOADKknGuuToFjmjIAYtrgjaOssqmfzNXoLZgKlMKyzlDaacPQQCXZMyXzlCXHJOlrNFwKraHZiOVQxCuALTvWIYneHemmrveGGBzkRrVZfINzADTgEppRZbFhzoWKQsBpaJzVftCmooZgzVOJomkXYZTnnivQGKdhuCWGIWqIXJRbJRRfaRlZPvNHhjCSNPuLRzaRZChimeoXxJQHJMyenprhwKhnBikSvBOtZpASjeeCnKBtiJvJLRqqQorHUXQTkEJURWoPwZSwDwgmpZmONFBvCxZCAUrCPiRjsTRqNlryhVjlmLLbrEnhlOrRAjpNcZsvObWqyvMAZlYSuHZGWQmVBHLRRReCJZQDVRMbeBvqdtfPjyTDCTjQNTgLjYqPYCAJREhZwnOncIMfcmGiHoXKFVSjsFrxdonkBcoBCpaGVXtrxCWYWbdOKiUcURgmuHdfwAWhUqyJJZhsAemSWaxuzTpmcsLscBpWBItZuoyuffQamIHMTrOzuzSGyXbMnqYAwTvWdTXhCnqYzAdiLhoHYZQkzwaZOGeRrJvHiAIiocqZaNjrsZqawQNiJIBSPdPOZjwPeFrpmOBBDbLocwjMvsxJyeLCSbyADOVGhLWPjwJSZLHTuuOUCaJcbnSlsHEmyvOQEflLGvrgRkLBSAEwMeTpfVaVrNLSBTWBCKdNwlrjbUVQfjWjZTBUqLxXKEYVVmjPwIJtmdupnIrWQbPPGSMPyYzSUYZTlfxRPbKGCFjXFAFVAiXpVBCJBWBEJMDjENqdBMQhwtyKYztxcRfdRgTjBeCrUEJKdybAmbnkcNnyZLItKDQrnSIKZefNnrwEcakDIvjGJFUcBtkSBYnrhkMCZOIroitvVwIwkTWOnhECUeOUPklPSWWbUCyjNWeMFOicurxGDPLLNZOCOtaoGHAeEyxABLGFJAgsVckXsIDGRLdikFbvkbXzInYDlTohYMxyDMPIhmMKUyPZpowGzuRXiwPICOpWloGFqmUHQJEtWqkBQDTuvBrRjtXIsklLBRuRCAqkSCsNOWZDkEIocyNLuujpWxsWkmugsiHwMNQZEWRljHGwuDPkGXoZdGfCqgKLnJXVdYBucKCLLkanvIxVWkoTSfuZsxndHYejudMXspScNlwwemwwTicMIquozlHpfUlTQfFRGcKNYbIbMLPZFcfYRhbKKcYerpMdImGdRyoIQJPiFeajQBWlfZtCUYvSTOVqqzMKXOTGQAieVpAUBhMgDzMbxwrkXDZELUKQxPgQSQRNZtFsvrVoXyokhefpFZpuaQVETMXYwBncavfTklmrgbsVYkWnbTTfFILqZIQSEVXNrfNwPGczlccdAywoNyRkKMHNUPjADCcmfWHkGAQBOizaUFseuCptKaagoGOKYVJZnZdsfoFgabpzBuqDMuTOvlFKTlhHxMFTjtTlgXjQFlarrcnnYLRoZcZiRsnfDPdgkJCRNKgQvybxKaOXkPQYxvPZmcgFdfBvxFUESZZSCqJxDIqHLEoWkaLYpRDNcCmQlFFwemMyUxGhEBwEBDGZmHTSCnNiAeWQZhnTKHUsgDTwwiMiSzHOyFiXXVwWZkpupbtIDWQxfZTqJWdMLVpDsMVUaYEHiEEWWPxbdngsoFbSUKwSjLLHLatsizGdZLvoFWBlScMReNyoWMfbQNQNxzFqZGoaHbVKZzrTyXBpCJhDMmVgOqpqRwWDaagCunvYldpPPTpoLzUWCzBlLoNKvzSeemDpnsNEurABqZzqsKcprpXwEFfMnPkGJUumLEIOSWyNMapJnDtyfcLnnNWKywXIXBOigznyNfqAkGamokmbRhFtwMGSBTJYpjcplXAUmInyjvnhZAjEUsyCsPeLppptRqNaudtJINVrxDrBvocmfYIIAfYsdPBIRbWGhgBqgqaqQjGiaPjAUvPBVycOJvpePVHghUTUUYSvxXFWbTCCETLtCROmvDtpTRNXFWIXzKSewmmpzBFLkOxdkrPZCOSnonLToSPisMHytKGtuWVdwMNhuGRQnkCmoTJvQsqteAdCuOKVtuFtYrtebwzCKlYBFoUmRxOlWqCRAxDatKXJvHvRbUQlAlVyZsaEaAgqNGqvIlhGMCwPFmdStGMxdUSfWHszfEEpoXHPNmDXZYRFjbShbkUGmwqmgdHpMPJUDgSEJIDIUzsQZeJahzOuOcOpmyHZtJFZNJdOXmoKlyiEgJBCWvEDAwTOuaZiMPnrlixyGWBqjnlPQEltTLXhmXFZgwCPxAcmKPVnhfwpNNKfddqkEWfwpiRkgKQfLcgkZdsndmSAqEUBBEJayPhKZnWbARRfoyQjQJnjaSFzBQZaypSVZhizwshxNPaNdLbddWbaIjqqbtgYaoUceuXuMLIcGRsvxSiRsYPOOUuHDZBTjMGiiWPMUAVyfTGJhvNvcarkgSPQGBqxQHeuhBUqUaktHGWeVSoVLvpddBkMqHzVNVxnLubPmxGkuUGjHUlQCxSNsOnGiOebzMnoBvoCFTwjufFljTm" + } + }, + "ProposalBase": { + "id": "70", + "status": "VotingPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-04T13:24:43Z", + "deposit_end_time": "9936-01-05T01:43:01Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "327" + } + ], + "voting_start_time": "9936-01-04T13:24:43Z", + "voting_end_time": "9936-01-07T16:43:41Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "hiSuAtSyed", + "description": "hbNHqzPUPujGfTmboMiyqUmEYKOERPYDBrvuJMzNFRHlnSIKoTeodHXPeUZqigdtOWQFMDguuarDJyaTOBJdPBUjcndpxhihdUad", + "recipient": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", + "amount": [ + { + "denom": "stake", + "amount": "3067193834576" + } + ] + } + }, + "ProposalBase": { + "id": "71", + "status": "VotingPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-04T13:24:43Z", + "deposit_end_time": "9936-01-05T01:43:01Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "307" + } + ], + "voting_start_time": "9936-01-04T13:24:43Z", + "voting_end_time": "9936-01-07T16:43:41Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "xfksQfmPlK", + "description": "BqyJiFnBWwwUUyGaIEjNRSwEnRiJZjSuHMNtdAnildHsIsbmdITnBCdWuvavPOnYhIhPDImWvzFLeITZMsyrIiCTexlFihoNGyJv", + "recipient": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq", + "amount": [ + { + "denom": "stake", + "amount": "824554033545" + } + ] + } + }, + "ProposalBase": { + "id": "72", + "status": "VotingPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-04T13:24:43Z", + "deposit_end_time": "9936-01-05T01:43:01Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "271" + } + ], + "voting_start_time": "9936-01-04T13:24:43Z", + "voting_end_time": "9936-01-07T16:43:41Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "rJUhNSQaSV", + "description": "xxWkwtlfKntzMvCYFLdvRBmoeTbdASutCprXGfuYizokpcMOXBgaxEmSlrcOkdMEVBEsyGFYbOiemqlEbibrIaZBcwmrUQufzLcA", + "recipient": "cosmos12k9kcewq2045n20vsa0u5a9m98k4se0rxtacum", + "amount": [ + { + "denom": "stake", + "amount": "2224713311426" + } + ] + } + }, + "ProposalBase": { + "id": "73", + "status": "DepositPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-04T13:24:43Z", + "deposit_end_time": "9936-01-05T01:43:01Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "164" + } + ], + "voting_start_time": "0001-01-01T00:00:00Z", + "voting_end_time": "0001-01-01T00:00:00Z" + } + }, + { + "content": { + "type": "cosmos-sdk/ParameterChangeProposal", + "value": { + "title": "AkrXbHnQRGxwaVMHYLWYkCTDTCHcsfclmvaLYufZTgPYwgSghBAQBynubtzYFByvYoKlJHYTmNmqnQrOUVzLHiTtddPoKTAWfFKPDxxlxtHKUcdeBJbbiCbPApILRQClKaEVMYrPqzbE", + "description": "lRdpqwNqYHvAiwNultBrtVJYKJhIkvwxaNCeWSQBDdRPTNFLAPZRJSyOmdXHZHGprdMJWfLqJOIxlcaJzLIZXtbXncWxWzGUakqMeaSoeLsayFvBqhozBqELgvolNEXjecxzPylFRGBSoNEytnIPiAHuAvOXNXZFTXDIguBALWqTKbAvNEGKKAzHlpxiHKTUBEYOvSjnDkJRjUplApjWVWnuBGFvuZeAISOXhrcEIRqjZyzikwLQgagyCHRwpJlwhbYAyOYMyupLPcIASpnGVLGLwRrxZjCvViGMbncEKfCsUlQbNGRGiwpOhTVnHpqdQsOzSBzxOhAriOKWeHEbgqqAjJXYtxZOwpmEdHVTuXDEdLyUpIccpHrHJjZyVPyFBvaZVIxiDcIXXvZfeerHIcuCOKkEPYuIPTtacXzkEgVdbVFuKvtggOcUsKmHapZiZGePliMOSkcqCBrdvgTmbINNNUdefsFgZbwzFyZAmydGGVIDvMsOsmXXxxNbfiKRQZVhoZwRTXlYuGzHdFIeqiucpairLEsQsCUzSHaTcZkYpdsCBALRTToyheXPJfbaPOKxzMjmFnZlZETPMeUBUeXDqmdOwHBPVPqyWbWNwbNgJIlYpCWvgwufeFKygwYRovxEtFLweRgnbimOFDOrqWBzXEadSRAFdszAMKicraVMwbsrbVaMxOKIMgpXZoKNypLXHnauPjvOjteZivwRVXRFUBnAEXQsizPeFphgtSTpnwimiudcGgZkerlGqhLXluzOuWLPADBrJQWUekBiInybvxKBeafCfMPHOmTdzmeKnoFntPMyEUamBcyIPCnTgCFXfKegxsPhRuQPNcDqLRypCzuxmsUNvDxJrYBTaUlBaVRNaxYVFOoSiCDyHVYSYDxPNiNCMxKRfXCEdQfLkPssBDHsLsTTJOkfkyZmjXdeXXlbqJvJCbVpwQPxvFYuwooKzJgzZjRjdxXsTFsJxQIqYrswsWnkGkFFCIZSDpPKVEbNqrmARRyVnBmWwMMnhDjdQghtmzFTKzXjaajuifeCJmewnnnixIhYhaqLKLeOzwdNMMiUnrxUxsLJUllDWkMKuXdGFOAYTsLkNfhWdBJBlaIIgxkjoyclUeRDgZKBhvvcTsQDfbuSVCnEIPFBVoTfymYIfwlldLVxoBoXzXmuniCvhBnkHQNHXkQmNyURtawuyOpEASKbROTGtwbiDqeTYOafubBSggCbVkqdPLsUIIiLeuVwlSgpECKSHXxSHlWivzzCtAdkVFbupTxhpgrbazhXLAxAWongFQiIrrbOHsuqWAImhTbJtrkeeiZeNCJVjFeWyDXCqkYPRPHILpdvJRezXeBxeDiyLPmRIdXgYLRjnbkWwDDUGcVQcynGcFpURyOAOeKmhwCWpawqICzIdZiMErvGZJPNRMjFPXlAXPiXVbGnDHUJNPcHYmbupvwZHUyhtfsHsPlwfhJmLfjXXrycDGTnUHZMhyJkaPowALCkDByAVSznDkQVPYFbUJxAZUDWiGvdyejuCBYKmsnvnEbMXniYgmmVdPIbqiFlyuxVJcHUiPpNMILwdriZsOcVCcKUYbwvulsAZXzxCgvqqnFbLnTJkOTLKVWGWvpGTgAvNvyfgmXPuKdnlFTiSyVLnRzxgdIqNmHSPJKzpVNzzSOZxWLQBSQBQXbCEDgOjLFYfEdISBFerkslHseNbGRrzODWtCUjRGuLmPuztFDzsJVdBwZyDmaKallSCAaSPlwcZxNOvNFwsTrvVaDdbLwOaOGVnmmmrapCggkjguiNwysZobYbxsMNkHiuXmmXPNQnpAlOTTgRhZUXGcyTLqySmwrRjdsdSNAUvtGJRRXwsgxWTSxmrRIzxeFMviXYNAhWOoJSHyhksQDCePyEJJhDZULwDczslKYIQHAHahuPphXEEzYqFhXNHSJNzVnmiVfrUCaIgfFNQuxsUMbzwmXvvAZgbReXbKBUhquWIQmlhLvIIIeWuyRqjjAQhYNbdIhwqLuyeDbesTSRnecujQZuecLiUsomwjIIGBGLgjseiNcatiDEwMdWLkFGCLUgHpAUKZdNkEhXMnWyRHbqzFZVAvnAjHGHrgobHranExDFMOgqbYKJFuUIMYmmzANkoTRnscWAkBqvnHrSVtBnnsiAyioCeiMmJZSWYTblvVQHeZCNMxyFeebCFGnhdBAGyZFWFmTcXfMFKSJJlueiVYVySvjAdcksyPQiPjbeRLFfDVJqfCPzpddlkvzdrrFcmUOwRYtrXtnnouqUhxZzEKXoreogkiYwAiNomOtoOtwftkaLyWNmldGTCgiaFcJUdfmJmGQuEYZTOqJTWouuXzsXmmiDIHDawdbrJBeBDwVRmurmaBLbKWqEAVMMsZzzqcVPJkHMFqfLphsWovZtsvViVKmWYJWlUkyuOmPDkoLgfnQNlTaOwaZaDgvLrcYbWGoidRQEPMgSFmVuXDDzCZcLUxpepStrfVvPIzhSDdDkLBDbamOXvNRZoTMOtJttRjkvlATCahKJbAKKeqgEwYbjPuBEUPHrAuRiAmsuDNQEKPpTYYHwyspZkwxZopupOlFaUflwtqMzskxFKkeaWBhxcKsFhYnqGtJZivxGCyXkPtVSqwuHIiSkeTonbkraMqxqRjlWReQUnzFgMMMUoWiAxobYTFOchuFOSQsVyUlrFdoudRbShqSOjweHSBUryqIpMIPglGHoSNpHYZvUPFAUloEdxLaWeHOxzaEayhEvwQalIoufOlSlZwZlOTaIYgWwpTOHmKEgpqicUaSeyVGFOsrOOthVUTLWULYtqSieTYLIkQKOKFCFapBEBoqFbIWPAaSAksQJITPByRYiHrpxpJboRHUreTlNDrJGvqjNeIEfxQPXpYYEJDsMiyXubGscQsTsBxhtdVJeFyxGMbFHpyUOgZDgCCQYOHxWbpRJcdObocueTSdUTDzYabhdgtrHLkGVRzccxiGvbFqWdHczKfYnEhJhcuxnJgezRVeOluFEcTcfKprXPWNdtgDYswOjrnPJxapXzaVOoJwfOMLYOAhYmYiFGEiDmzZXoFfyjLqnluLULEtevgkrliqMAgkUYduLHhaTzmTHfjdOebHXNrBCmrhnPvqYtHZXfXrsfGzEQEGdvdQUUlRykeWdzKMoGRthIkDSTYfGvTPAUclZHgXciFaLVJcjNAUqwowWdYXnieCmzAjvYaDpTHUGPUBcQgBhyjDvmxHxbXGBrZCiRvwJjbYLtSsUOyWcDzrjHbCLXZVGBaVSWWMtmSzpvTiUoxOGMNQsxuZtFYardhpRDafWlsUwzaQXgCLzaeNJIdjfwpAakRunwqqzEIuQHfXaqKeFikuXvjqkNugfnTMpLRJWLEDNoXvserNMyAVjMJCLbmXlRNzrUVkLYguXnIqnvLYZCqmsSlnaoQEZGFHIQgOFUKIvgKmeXkINVbhvUbSpDeNQsVSvWxcOjwRFOEbLgKsRQVgBWHLAGZdhwrrlsGWPjSJASWROpLtpXLMXXAZelvSjvRXibJWvgLuZonpVAloVmPRpXzBEfqdSNmNyKBAdHrvyXxsQbyeXocEgRhHcrwOntsNBTCegCKpBWNGTfGtpuUSKvLfAtdWZSPQXwhbpesKiszrdBJXSDQVBWxrLbAbYdJFmmrCquUDMsCKutZWCPHKmVQXvMdwiNYYlHQYXPpFVgtAiOzldyAZtprhyPivfZTbLIPhyiUpvPkdlwmfkXLRtNZKBEYXVtrLufDmLxKFnJuwqvvQhyNPTOUDOCsqxlowDugfZxSlxDXPWLAdRXZfAkZlXKflGnXNNTIWTevyqowtwKHDgNAiFzKTRYKEpCjgvbTsiCZKsLTZPutLNazRJbcoDbhtTCFjHJFhvkOFRgpxPosgjHUrATqHxeFVfdrKeKSLNGcSpFFRyOjsOgruMuIzyfibjDorQJfjDMxodjleFjjlMvZNuVoktFVMYksuNPVaeZDJJjuaHJvOOKWJKEvhJgVtFRrJGdMlhOfpaMfLtWDWgNODZySUtnCSaTsajhcwKsUhuDPhtHqWphvmdkONZPQRUgTdylSdXsOoYGRWgXYVNqdrAGKXKhpFayUgTVwjzwFmEtGpfSUGkAGNFDGiDWGjNRwZGzXeUglzuhAvyfcvVXcaiHsWkCVNXjzYkTLsDsXPTzWfankLNATJuqgEXvcDqiVoEtqsIGZpKzZUZvLLLvdUYcTJsDoXEnZThXvkljFQOSRGUdFlphaLVwjNCOYSzXZOuIjXhOplIrkIjJAXStohBtQkjvTFZPWWXjgNKXjlpLdqdMZylxfKztngQYaYLiUKHIkSJZTAnJRCjgBStepsjddoPCKaTaKFoCMshSyqGVqQFIieXAtqOGjvkrEWblrqsWsGeqoaChiCQzLaNUORQawWQEjaBTGdqmsfargNwKxeTmsVzTZAJLrDarTMyeNgpyXiILCgPcvSVAWxjeBfdywivvBvRtFYctEhhJiihCzcbfsqdCZNjqIJHsJDtxTBOiYGasUYLcgerIJcNXOFUKhxKVgGSjaMuecDBGwtufBMsbUJmdXqFrSWwboFeoYLwVgczOcvHeZRdkCPnvaHyQKlaXQtDcneLsqRzJtKiQZOvWPbyBDQxNNzeIQppCtJgDJgbRLwdWgGhIpJPFJOexBzMySjKARDbJpSMTgGVFHFQDSnJswtPWJxvQLLVkNUjECIEPBVenuxjpJHCCusjustPScPAXtCGcrqtZIINmKwTnsVJorJLOJoyeLGcAITcmWBDgoXSyekHPVVLxeyTQowDbhDQjSdbcfgoWTHOMuGiouxRvewJsubQbWPIcyPNqNApBeVUGNfyLDbekbSSXUGchkiMsTKgSWdixZilWanDRJewhsmSyEOXqMReqiMnazgLmCBWWYixHdWDEXrzAhjmgPnefJqxiSBIGPcHGuliMBWVdEsvxThclOCsOECtKcnYbwRBngghyEvBzhuwEUsZ", + "changes": [ + { + "subspace": "distribution", + "key": "baseproposerreward", + "value": "\"0.230000000000000000\"" + }, + { + "subspace": "slashing", + "key": "SlashFractionDowntime", + "value": "\"0.012987012987012987\"" + }, + { + "subspace": "gov", + "key": "tallyparams", + "value": "{\"veto\":\"0.305000000000000000\"}" + }, + { + "subspace": "mint", + "key": "InflationRateChange", + "value": "\"0.380000000000000000\"" + }, + { + "subspace": "distribution", + "key": "communitytax", + "value": "\"0.070000000000000000\"" + }, + { + "subspace": "staking", + "key": "UnbondingTime", + "value": "\"75959000000000\"" + }, + { + "subspace": "auth", + "key": "TxSigLimit", + "value": "\"5\"" + }, + { + "subspace": "auth", + "key": "MaxMemoCharacters", + "value": "\"177\"" + }, + { + "subspace": "staking", + "key": "MaxValidators", + "value": "127" + }, + { + "subspace": "bank", + "key": "sendenabled", + "value": "true" + }, + { + "subspace": "slashing", + "key": "SignedBlocksWindow", + "value": "\"340\"" + }, + { + "subspace": "mint", + "key": "GoalBonded", + "value": "\"0.670000000000000000\"" + }, + { + "subspace": "mint", + "key": "InflationMax", + "value": "\"0.200000000000000000\"" + }, + { + "subspace": "gov", + "key": "votingparams", + "value": "{\"voting_period\": \"329617000000000\"}" + }, + { + "subspace": "auth", + "key": "TxSizeCostPerByte", + "value": "\"9\"" + } + ] + } + }, + "ProposalBase": { + "id": "74", + "status": "DepositPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-04T15:40:16Z", + "deposit_end_time": "9936-01-05T03:58:34Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "58" + } + ], + "voting_start_time": "0001-01-01T00:00:00Z", + "voting_end_time": "0001-01-01T00:00:00Z" + } + }, + { + "content": { + "type": "cosmos-sdk/CommunityPoolSpendProposal", + "value": { + "title": "nhDqMFkWji", + "description": "cUCDxDCHCRUftEVbrffwtHCvOXhXLBmCxcQCyidVuEekdMavEeLqLwLGEsYuZjREgzWeQlTaKQWDZSJaakavDStzaHDaZmKFEmIH", + "recipient": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", + "amount": [ + { + "denom": "stake", + "amount": "733698530436" + } + ] + } + }, + "ProposalBase": { + "id": "75", + "status": "DepositPeriod", + "final_tally_result": { + "yes": "0", + "abstain": "0", + "no": "0", + "no_with_veto": "0" + }, + "submit_time": "9936-01-04T15:40:16Z", + "deposit_end_time": "9936-01-05T03:58:34Z", + "total_deposit": [ + { + "denom": "stake", + "amount": "71" + } + ], + "voting_start_time": "0001-01-01T00:00:00Z", + "voting_end_time": "0001-01-01T00:00:00Z" + } + } + ], + "deposit_params": { + "min_deposit": [ + { + "denom": "stake", + "amount": "221" + } + ], + "max_deposit_period": "44298000000000" + }, + "voting_params": { + "voting_period": "271138000000000" + }, + "tally_params": { + "quorum": "0.432000000000000000", + "threshold": "0.524000000000000000", + "veto": "0.259000000000000000" + } + }, + "evidence": { + "params": { + "max_evidence_age": "120000000000" + }, + "evidence": null + } +} \ No newline at end of file diff --git a/simapp/app.go b/simapp/app.go index e9c32a713918..90e75741399b 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -236,7 +236,7 @@ func NewSimApp( // During begin block slashing happens after distr.BeginBlocker so that // there is nothing left over in the validator fee pool, so as to keep the // CanWithdrawInvariant invariant. - app.mm.SetOrderBeginBlockers(upgrade.ModuleName, mint.ModuleName, distr.ModuleName, slashing.ModuleName, evidence.ModuleName) + app.mm.SetOrderBeginBlockers(upgrade.ModuleName, mint.ModuleName, distr.ModuleName, slashing.ModuleName, evidence.ModuleName, staking.ModuleName) app.mm.SetOrderEndBlockers(crisis.ModuleName, gov.ModuleName, staking.ModuleName) // NOTE: The genutils moodule must occur after staking so that pools are From 32a3557fcf319044e2a4cc034bc05adfea5fa596 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 7 Apr 2020 14:27:30 -0400 Subject: [PATCH 170/176] remove JSON files --- sim_params-7.json | 1 - sim_state-7.json | 122226 ------------------------------------------- 2 files changed, 122227 deletions(-) delete mode 100644 sim_params-7.json delete mode 100644 sim_state-7.json diff --git a/sim_params-7.json b/sim_params-7.json deleted file mode 100644 index 9e26dfeeb6e6..000000000000 --- a/sim_params-7.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/sim_state-7.json b/sim_state-7.json deleted file mode 100644 index b575940740ef..000000000000 --- a/sim_state-7.json +++ /dev/null @@ -1,122226 +0,0 @@ -{ - "bank": { - "send_enabled": true, - "balances": [ - { - "address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", - "coins": [ - { - "denom": "stake", - "amount": "13015743095" - } - ] - }, - { - "address": "cosmos1wdm9ge7hjzrlh2epwtwu3nsunfd2r7alqhc7r2", - "coins": [ - { - "denom": "stake", - "amount": "766070747" - } - ] - }, - { - "address": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq", - "coins": [ - { - "denom": "stake", - "amount": "14891624890" - } - ] - }, - { - "address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", - "coins": [ - { - "denom": "stake", - "amount": "14963416025" - } - ] - }, - { - "address": "cosmos1823pz6pxtqgm8hdcxaysccpyd8fx83hm287sld", - "coins": [ - { - "denom": "stake", - "amount": "10185265919" - } - ] - }, - { - "address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", - "coins": [ - { - "denom": "stake", - "amount": "45637326" - } - ] - }, - { - "address": "cosmos1gw6f5uf38mv5dng9uwfzv4r9whvdd2f60ay2ra", - "coins": [ - { - "denom": "stake", - "amount": "76112747" - } - ] - }, - { - "address": "cosmos12sx0qw8yggnh7scj90gu08k66q7j8wqq88y25h", - "coins": [ - { - "denom": "stake", - "amount": "4993493505" - } - ] - }, - { - "address": "cosmos12marehfknnseqtft88ut8gehf0lvcun3mymcme", - "coins": [ - { - "denom": "stake", - "amount": "14320099451" - } - ] - }, - { - "address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", - "coins": [ - { - "denom": "stake", - "amount": "10270105" - } - ] - }, - { - "address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", - "coins": [ - { - "denom": "stake", - "amount": "1349398915" - } - ] - }, - { - "address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", - "coins": [ - { - "denom": "stake", - "amount": "484757514" - } - ] - }, - { - "address": "cosmos13y2zjpgaj07umx7a3dsg9ffhpkk22g73492l53", - "coins": [ - { - "denom": "stake", - "amount": "6639888504" - } - ] - }, - { - "address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "coins": [ - { - "denom": "stake", - "amount": "2508642240" - } - ] - }, - { - "address": "cosmos1t929u2r8p5vtvuwn390l506achd08udrwx4ah3", - "coins": [ - { - "denom": "stake", - "amount": "15194890118" - } - ] - }, - { - "address": "cosmos13ps0cszg8lqn0mkzndvhxwaew8yd56s8tl9j20", - "coins": [ - { - "denom": "stake", - "amount": "5412847843" - } - ] - }, - { - "address": "cosmos17gpy6jzg7xdsr2xc7kweljagx4uaysxdk2244g", - "coins": [ - { - "denom": "stake", - "amount": "27613138030" - } - ] - }, - { - "address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", - "coins": [ - { - "denom": "stake", - "amount": "4968763267" - } - ] - }, - { - "address": "cosmos1zsspke0nqudcl0lh747ppqcsy396245akc2vtl", - "coins": [ - { - "denom": "stake", - "amount": "2992774767" - } - ] - }, - { - "address": "cosmos14m0pzuhkpjnx2esurz6kcxcjvlkcdzk7e43krz", - "coins": [ - { - "denom": "stake", - "amount": "1129565009" - } - ] - }, - { - "address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "coins": [ - { - "denom": "stake", - "amount": "3127012273" - } - ] - }, - { - "address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "coins": [ - { - "denom": "stake", - "amount": "7211269830" - } - ] - }, - { - "address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", - "coins": [ - { - "denom": "stake", - "amount": "2684018723" - } - ] - }, - { - "address": "cosmos1c4lft2m4yyrzjsxyu7nzsrxuskgtlr2crzzwwd", - "coins": [ - { - "denom": "stake", - "amount": "250959" - } - ] - }, - { - "address": "cosmos1s34kukvsrdgap0pjh0alnql7vvv9m83m2628wd", - "coins": [ - { - "denom": "stake", - "amount": "920556125" - } - ] - }, - { - "address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", - "coins": [ - { - "denom": "stake", - "amount": "2083847937" - } - ] - }, - { - "address": "cosmos1adwsqn58aype530jae9qrwknsxyf3wmwdr523z", - "coins": [ - { - "denom": "stake", - "amount": "7565995779" - } - ] - }, - { - "address": "cosmos1xq58llsgh49tsz22grs28jk0p7tvswlcjcrl32", - "coins": [ - { - "denom": "stake", - "amount": "482965302" - } - ] - }, - { - "address": "cosmos1vx0z58vgegsfc8e56jzmjtvj8cvprywvnm7l9j", - "coins": [ - { - "denom": "stake", - "amount": "5181478931" - } - ] - }, - { - "address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", - "coins": [ - { - "denom": "stake", - "amount": "2715100272" - } - ] - }, - { - "address": "cosmos14rtpks2cfh8luvywtgrry3hhycwacwtkq6hyp5", - "coins": [ - { - "denom": "stake", - "amount": "12768231969" - } - ] - }, - { - "address": "cosmos1cvhkglegj4zamjrdulawtk4rq658wnm9te6tgl", - "coins": [ - { - "denom": "stake", - "amount": "35357688089" - } - ] - }, - { - "address": "cosmos1xwjpulj30k4y0smg9krxwx80hk83r3zhs48jes", - "coins": [ - { - "denom": "stake", - "amount": "29861447258" - } - ] - }, - { - "address": "cosmos1tqk0l38afmllffqs7g3uqaanhwpksytxtgnlj2", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", - "coins": [ - { - "denom": "stake", - "amount": "3081545741" - } - ] - }, - { - "address": "cosmos1t2uupuuf6p4xr0szwsz47gn682kw64m9wmnewf", - "coins": [ - { - "denom": "stake", - "amount": "25122396271" - } - ] - }, - { - "address": "cosmos1cwk6x5smzaqhtrz95z0sf90d8a8d9vfrpaufnl", - "coins": [ - { - "denom": "stake", - "amount": "22838402464" - } - ] - }, - { - "address": "cosmos1fj43j5263mk8whetx8ru0gm4yf48xkg20txll7", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", - "coins": [ - { - "denom": "stake", - "amount": "579605250" - } - ] - }, - { - "address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", - "coins": [ - { - "denom": "stake", - "amount": "703708135" - } - ] - }, - { - "address": "cosmos1c4w30j37que0ncnss65vr40nuy7d5msegmhgs7", - "coins": [ - { - "denom": "stake", - "amount": "53752421033" - } - ] - }, - { - "address": "cosmos1mfa9me7lxg0gja78krqzv2sxqpehlgrystzdvm", - "coins": [ - { - "denom": "stake", - "amount": "11190639862" - } - ] - }, - { - "address": "cosmos1q0cw6hmrm4myx5c3zzmw6deelygsl2hrts2ju4", - "coins": [ - { - "denom": "stake", - "amount": "4998717819" - } - ] - }, - { - "address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", - "coins": [ - { - "denom": "stake", - "amount": "19714222" - } - ] - }, - { - "address": "cosmos1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcy522k3", - "coins": [ - { - "denom": "stake", - "amount": "15582790811" - } - ] - }, - { - "address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", - "coins": [ - { - "denom": "stake", - "amount": "1980570093" - } - ] - }, - { - "address": "cosmos1kkruz0zwzf7ynu5y9y40ef950f2n3jrdp0lkr2", - "coins": [ - { - "denom": "stake", - "amount": "37935548005" - } - ] - }, - { - "address": "cosmos17z26jlgg6x0hlj4qnl7pxtve270fr7teanj8gr", - "coins": [ - { - "denom": "stake", - "amount": "807560349" - } - ] - }, - { - "address": "cosmos18fkw6s4hnj2llxljrkleetgns2y0h0vjg8kmef", - "coins": [ - { - "denom": "stake", - "amount": "6124353306" - } - ] - }, - { - "address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", - "coins": [ - { - "denom": "stake", - "amount": "21429431988" - } - ] - }, - { - "address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", - "coins": [ - { - "denom": "stake", - "amount": "4061217092" - } - ] - }, - { - "address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", - "coins": [ - { - "denom": "stake", - "amount": "9441079910" - } - ] - }, - { - "address": "cosmos1c4qcdf8mqwyf7rwgkvlputdfwdfnk42lul4d5j", - "coins": [ - { - "denom": "stake", - "amount": "41262535778" - } - ] - }, - { - "address": "cosmos1tmddg4wjnj38wrd8t6xq092jyw3x4hcup6n00u", - "coins": [ - { - "denom": "stake", - "amount": "3888452114" - } - ] - }, - { - "address": "cosmos172lmu2psqlkxkthpr46h2ewjffte7lhlmwe6tg", - "coins": [ - { - "denom": "stake", - "amount": "22639210394" - } - ] - }, - { - "address": "cosmos1guuf6ntr5ujawszq99gkq2gqeevz37adzp2fmy", - "coins": [ - { - "denom": "stake", - "amount": "33283887657" - } - ] - }, - { - "address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz", - "coins": [ - { - "denom": "stake", - "amount": "984210880" - } - ] - }, - { - "address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "coins": [ - { - "denom": "stake", - "amount": "2428727543" - } - ] - }, - { - "address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", - "coins": [ - { - "denom": "stake", - "amount": "34176860650" - } - ] - }, - { - "address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv", - "coins": [ - { - "denom": "stake", - "amount": "2250782680" - } - ] - }, - { - "address": "cosmos1mn2w84lgjyemsggq7eyw8fw0wreclx0w6hfmcw", - "coins": [ - { - "denom": "stake", - "amount": "1224535795" - } - ] - }, - { - "address": "cosmos1umn8dwc5l034syha3xehk0kmjaajdfyedajtka", - "coins": [ - { - "denom": "stake", - "amount": "22588333278" - } - ] - }, - { - "address": "cosmos1f58nf9lzm4d5x9grnt3a3vd9c75szj95f6mm5s", - "coins": [ - { - "denom": "stake", - "amount": "5235315452" - } - ] - }, - { - "address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", - "coins": [ - { - "denom": "stake", - "amount": "812334416" - } - ] - }, - { - "address": "cosmos13cydnwjmscxtqtjywk9atr9uwlm6703mwtycnr", - "coins": [ - { - "denom": "stake", - "amount": "4865397260" - } - ] - }, - { - "address": "cosmos13ljukhcdmvlmaa773v3582cufv74vudsyc59x2", - "coins": [ - { - "denom": "stake", - "amount": "31405558301" - } - ] - }, - { - "address": "cosmos1awyus34e6laq3zxqsrv283w6fgn8w62zkwd87d", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", - "coins": [ - { - "denom": "stake", - "amount": "44642304123" - } - ] - }, - { - "address": "cosmos16tgzg562uhpczcma5at24uvw4a3n0u322jurd2", - "coins": [ - { - "denom": "stake", - "amount": "8100245524" - } - ] - }, - { - "address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", - "coins": [ - { - "denom": "stake", - "amount": "33112" - } - ] - }, - { - "address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", - "coins": [ - { - "denom": "stake", - "amount": "40917232533" - } - ] - }, - { - "address": "cosmos1vjm2s6e2mu4v08mluhgry9chyewhtd2cm79j5s", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", - "coins": [ - { - "denom": "stake", - "amount": "2429895018" - } - ] - }, - { - "address": "cosmos1zgsxapl5dwq6c8nf7hjn2qa7aytg0m365jhs39", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1gy49x7p6xpgdfhv8v9dh8kfgsef479cq3u8fzr", - "coins": [ - { - "denom": "stake", - "amount": "14970611115" - } - ] - }, - { - "address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", - "coins": [ - { - "denom": "stake", - "amount": "2596749133" - } - ] - }, - { - "address": "cosmos1l5vty6svhxd023rl280aqu0eqjffv0qct2kywn", - "coins": [ - { - "denom": "stake", - "amount": "19626094043" - } - ] - }, - { - "address": "cosmos10572shcaewknpzsj6nnrruww0049hnmjymva38", - "coins": [ - { - "denom": "stake", - "amount": "2354956860" - } - ] - }, - { - "address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", - "coins": [ - { - "denom": "stake", - "amount": "8309248839" - } - ] - }, - { - "address": "cosmos17m4lyrws32kta4pj2atdcc2d7z2qrwkpqk0exs", - "coins": [ - { - "denom": "stake", - "amount": "28080411530" - } - ] - }, - { - "address": "cosmos1zlu0kkfr24psuwq54mzdtt7uk7068ameyk8hug", - "coins": [ - { - "denom": "stake", - "amount": "4991758536" - } - ] - }, - { - "address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "coins": [ - { - "denom": "stake", - "amount": "61587410" - } - ] - }, - { - "address": "cosmos1dqukz2u9cssszcudyrjxzf47aeydmfardn09hw", - "coins": [ - { - "denom": "stake", - "amount": "185092657" - } - ] - }, - { - "address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", - "coins": [ - { - "denom": "stake", - "amount": "126479871" - } - ] - }, - { - "address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "coins": [ - { - "denom": "stake", - "amount": "465473874" - } - ] - }, - { - "address": "cosmos16035vhhlcxkxysgfkruk204jvw3lmyhpkn0ffv", - "coins": [ - { - "denom": "stake", - "amount": "44814425008" - } - ] - }, - { - "address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", - "coins": [ - { - "denom": "stake", - "amount": "5285120528" - } - ] - }, - { - "address": "cosmos1zu50umwgah6jhx07sw04ry0pv7fnvkpjmn8vl9", - "coins": [ - { - "denom": "stake", - "amount": "14735329246" - } - ] - }, - { - "address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", - "coins": [ - { - "denom": "stake", - "amount": "55052052" - } - ] - }, - { - "address": "cosmos1m75flstcn3hpq9am7dnvkw79e6jckkkjd59p9h", - "coins": [ - { - "denom": "stake", - "amount": "5000564275" - } - ] - }, - { - "address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", - "coins": [ - { - "denom": "stake", - "amount": "470344197" - } - ] - }, - { - "address": "cosmos1c3jzrd6ju4l55yna9pcrc49x0xkcv2hczxjw3u", - "coins": [ - { - "denom": "stake", - "amount": "19412508" - } - ] - }, - { - "address": "cosmos1tl9mmfa626vgrsz3plpr42cmeqcn2zugg523y3", - "coins": [ - { - "denom": "stake", - "amount": "1936478856" - } - ] - }, - { - "address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", - "coins": [ - { - "denom": "stake", - "amount": "151969270" - } - ] - }, - { - "address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", - "coins": [ - { - "denom": "stake", - "amount": "12914036" - } - ] - }, - { - "address": "cosmos1ecfsusjtvmp57t8n22j9vqx75g6yxdra5vk49e", - "coins": [ - { - "denom": "stake", - "amount": "3575361157" - } - ] - }, - { - "address": "cosmos1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfej3rle", - "coins": [ - { - "denom": "stake", - "amount": "222184285" - } - ] - }, - { - "address": "cosmos1f2tr8j23vqevt4hwk3073y6pvu0cgjg4jx4lja", - "coins": [ - { - "denom": "stake", - "amount": "593489894" - } - ] - }, - { - "address": "cosmos1ftwtj8rwrz4n7e9y5gnnx47g2vtxkqkg26megt", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1tczlc2ruuvetu9w9rq9ka0v7va00ye9vsyxf37", - "coins": [ - { - "denom": "stake", - "amount": "21100981667" - } - ] - }, - { - "address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", - "coins": [ - { - "denom": "stake", - "amount": "2078583112" - } - ] - }, - { - "address": "cosmos1r6j2xkpnnjve9c00c854laqp7l7zv8pxeksxrz", - "coins": [ - { - "denom": "stake", - "amount": "1177804369" - } - ] - }, - { - "address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", - "coins": [ - { - "denom": "stake", - "amount": "13173052" - } - ] - }, - { - "address": "cosmos1z7ruhrtfg8v2xv8egfyxldt2xaygspykszntzv", - "coins": [ - { - "denom": "stake", - "amount": "25229483915" - } - ] - }, - { - "address": "cosmos14q9rupnazu0mmkjd9skpn2zdfs8d0hlghzpk0v", - "coins": [ - { - "denom": "stake", - "amount": "7105221830" - } - ] - }, - { - "address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", - "coins": [ - { - "denom": "stake", - "amount": "5043425774" - } - ] - }, - { - "address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", - "coins": [ - { - "denom": "stake", - "amount": "3217088706" - } - ] - }, - { - "address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", - "coins": [ - { - "denom": "stake", - "amount": "577239654" - } - ] - }, - { - "address": "cosmos12rrjnzeppeagkvqw6d26hn03kr0uvwk4sfw6v6", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", - "coins": [ - { - "denom": "stake", - "amount": "265496713" - } - ] - }, - { - "address": "cosmos1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalavv03x7", - "coins": [ - { - "denom": "stake", - "amount": "9473536568" - } - ] - }, - { - "address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", - "coins": [ - { - "denom": "stake", - "amount": "5061824165" - } - ] - }, - { - "address": "cosmos1639hgh9ke9sxqy7kpcdcu6srk983upzjlf8mwx", - "coins": [ - { - "denom": "stake", - "amount": "90710747" - } - ] - }, - { - "address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj", - "coins": [ - { - "denom": "stake", - "amount": "1752023113" - } - ] - }, - { - "address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", - "coins": [ - { - "denom": "stake", - "amount": "6893987330" - } - ] - }, - { - "address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4", - "coins": [ - { - "denom": "stake", - "amount": "33829012498" - } - ] - }, - { - "address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", - "coins": [ - { - "denom": "stake", - "amount": "10575705008" - } - ] - }, - { - "address": "cosmos1rmyk79ktv6c8q48u78udw5p906fp0w058796d0", - "coins": [ - { - "denom": "stake", - "amount": "2574922950" - } - ] - }, - { - "address": "cosmos1gp93nsn0kdl5qhn5xn2wyqfug6uxu26sfmfal8", - "coins": [ - { - "denom": "stake", - "amount": "3590993517" - } - ] - }, - { - "address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "coins": [ - { - "denom": "stake", - "amount": "6382934181" - } - ] - }, - { - "address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "coins": [ - { - "denom": "stake", - "amount": "1514530340" - } - ] - }, - { - "address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", - "coins": [ - { - "denom": "stake", - "amount": "1822682737" - } - ] - }, - { - "address": "cosmos1wpxkfcmhsmv7d5hdzx4tw9w009fd9wwj7hv682", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos16kuse8g39wn4yzx64shrzned2lgnk0kepcuu9t", - "coins": [ - { - "denom": "stake", - "amount": "3698740868" - } - ] - }, - { - "address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", - "coins": [ - { - "denom": "stake", - "amount": "288330252" - } - ] - }, - { - "address": "cosmos1tpxdvj93x9rqz89zhh0tszegcwtq8mgtdknrw5", - "coins": [ - { - "denom": "stake", - "amount": "785132909" - } - ] - }, - { - "address": "cosmos15vf60ssrdq6fh9ln5a9wtd6f3q64sktl6vk2ss", - "coins": [ - { - "denom": "stake", - "amount": "5955548350" - } - ] - }, - { - "address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", - "coins": [ - { - "denom": "stake", - "amount": "10010539387" - } - ] - }, - { - "address": "cosmos1n0qd05zlz0pr3eajdjukezg8l2str3twyjel3y", - "coins": [ - { - "denom": "stake", - "amount": "29658748791" - } - ] - }, - { - "address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "coins": [ - { - "denom": "stake", - "amount": "9188694926" - } - ] - }, - { - "address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", - "coins": [ - { - "denom": "stake", - "amount": "17354051227" - } - ] - }, - { - "address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", - "coins": [ - { - "denom": "stake", - "amount": "11528376" - } - ] - }, - { - "address": "cosmos1xghyawtulyzs449mhe8drctaaxnmdnmkd90yx9", - "coins": [ - { - "denom": "stake", - "amount": "9048346" - } - ] - }, - { - "address": "cosmos1rlzurkn0mywyldswcafhu7r8r0tha4s5prs34u", - "coins": [ - { - "denom": "stake", - "amount": "14813638442" - } - ] - }, - { - "address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", - "coins": [ - { - "denom": "stake", - "amount": "8318226490" - } - ] - }, - { - "address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", - "coins": [ - { - "denom": "stake", - "amount": "5736725729" - } - ] - }, - { - "address": "cosmos1easmlky76c302my07gffjxjw0a2usueaw8j46t", - "coins": [ - { - "denom": "stake", - "amount": "2769785735" - } - ] - }, - { - "address": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", - "coins": [ - { - "denom": "stake", - "amount": "177937920" - } - ] - }, - { - "address": "cosmos1zcjpltwefj47au6pkrysjffvxq46a8wf4w57nm", - "coins": [ - { - "denom": "stake", - "amount": "41938020" - } - ] - }, - { - "address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "coins": [ - { - "denom": "stake", - "amount": "1577007005" - } - ] - }, - { - "address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", - "coins": [ - { - "denom": "stake", - "amount": "73137440" - } - ] - }, - { - "address": "cosmos1kj8uw44q0fh3znllyxdxr8tc05qwnswd6fv304", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1h72kkqt83nth0npqvgmardgelg6jyx7zupnypp", - "coins": [ - { - "denom": "stake", - "amount": "21817451570" - } - ] - }, - { - "address": "cosmos1m8g0mk56ne6uutj5a8drc92um8cjk9frunx8s7", - "coins": [ - { - "denom": "stake", - "amount": "38409707411" - } - ] - }, - { - "address": "cosmos1m7m72dd80k54s8vg0v5z6h334lumvj3ehn0pyp", - "coins": [ - { - "denom": "stake", - "amount": "658401630" - } - ] - }, - { - "address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", - "coins": [ - { - "denom": "stake", - "amount": "1973244" - } - ] - }, - { - "address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", - "coins": [ - { - "denom": "stake", - "amount": "9879" - } - ] - }, - { - "address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je", - "coins": [ - { - "denom": "stake", - "amount": "1001465254" - } - ] - }, - { - "address": "cosmos1yvn8kgpuuepzefm90rydcladzwwqa9agadsyus", - "coins": [ - { - "denom": "stake", - "amount": "12052924734" - } - ] - }, - { - "address": "cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r", - "coins": [ - { - "denom": "stake", - "amount": "1701273789080" - } - ] - }, - { - "address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", - "coins": [ - { - "denom": "stake", - "amount": "343667368" - } - ] - }, - { - "address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", - "coins": [ - { - "denom": "stake", - "amount": "13784753898" - } - ] - }, - { - "address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", - "coins": [ - { - "denom": "stake", - "amount": "700253" - } - ] - }, - { - "address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7", - "coins": [ - { - "denom": "stake", - "amount": "7098434145" - } - ] - }, - { - "address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", - "coins": [ - { - "denom": "stake", - "amount": "6710289974" - } - ] - }, - { - "address": "cosmos1e2jxyxe4ekjsnkzcup35r8404hxxmntmhpwsgr", - "coins": [ - { - "denom": "stake", - "amount": "28418865695" - } - ] - }, - { - "address": "cosmos1ylf26t6vhvugawg87328ng2ug4d8f25syxp64c", - "coins": [ - { - "denom": "stake", - "amount": "820767733" - } - ] - }, - { - "address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", - "coins": [ - { - "denom": "stake", - "amount": "25851543934" - } - ] - }, - { - "address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", - "coins": [ - { - "denom": "stake", - "amount": "52321903" - } - ] - }, - { - "address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933", - "coins": [ - { - "denom": "stake", - "amount": "15890553368" - } - ] - }, - { - "address": "cosmos12r0m6hwrnn0jy02tnhmk328d7p68x2rndzt0j5", - "coins": [ - { - "denom": "stake", - "amount": "4611711404" - } - ] - }, - { - "address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s", - "coins": [ - { - "denom": "stake", - "amount": "7947557169" - } - ] - }, - { - "address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "coins": [ - { - "denom": "stake", - "amount": "138366734" - } - ] - }, - { - "address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", - "coins": [ - { - "denom": "stake", - "amount": "36416170" - } - ] - }, - { - "address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", - "coins": [ - { - "denom": "stake", - "amount": "9326778513" - } - ] - }, - { - "address": "cosmos1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8kl6qt4", - "coins": [ - { - "denom": "stake", - "amount": "4737972511" - } - ] - }, - { - "address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", - "coins": [ - { - "denom": "stake", - "amount": "167692785" - } - ] - }, - { - "address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd", - "coins": [ - { - "denom": "stake", - "amount": "10253771392" - } - ] - }, - { - "address": "cosmos1lh5v2ew6gwrugasrmt9tr8dql6qnj802lqrn63", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1sgj2stu89zswe28gqh46gv8sp6reppxc9addtd", - "coins": [ - { - "denom": "stake", - "amount": "20722807717" - } - ] - }, - { - "address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "coins": [ - { - "denom": "stake", - "amount": "14246428101" - } - ] - }, - { - "address": "cosmos1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqcrj0xk", - "coins": [ - { - "denom": "stake", - "amount": "8412380461" - } - ] - }, - { - "address": "cosmos1w2vujuajxpvqtdsne0gn6j0x0y0xw3kqtj6jtu", - "coins": [ - { - "denom": "stake", - "amount": "8730523" - } - ] - }, - { - "address": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", - "coins": [ - { - "denom": "stake", - "amount": "194865147" - } - ] - }, - { - "address": "cosmos18rzc0m3vlq3cwee4tckg5grjjc02gu3dv9csx2", - "coins": [ - { - "denom": "stake", - "amount": "35656801938" - } - ] - }, - { - "address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", - "coins": [ - { - "denom": "stake", - "amount": "9613056994" - } - ] - }, - { - "address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", - "coins": [ - { - "denom": "stake", - "amount": "17112642282" - } - ] - }, - { - "address": "cosmos1n3lnhxzzm7ntheu78h6v4zag7zmrlp48tjnhf3", - "coins": [ - { - "denom": "stake", - "amount": "31263429012" - } - ] - }, - { - "address": "cosmos17nxn4xkn8mvyjl9xg3erms4y43xeazku7rw5rc", - "coins": [ - { - "denom": "stake", - "amount": "18566429002" - } - ] - }, - { - "address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "coins": [ - { - "denom": "stake", - "amount": "141354494" - } - ] - }, - { - "address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", - "coins": [ - { - "denom": "stake", - "amount": "11023158820" - } - ] - }, - { - "address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "coins": [ - { - "denom": "stake", - "amount": "4400903048" - } - ] - }, - { - "address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "coins": [ - { - "denom": "stake", - "amount": "3214796449" - } - ] - }, - { - "address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "coins": [ - { - "denom": "stake", - "amount": "142890301" - } - ] - }, - { - "address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "coins": [ - { - "denom": "stake", - "amount": "3397839" - } - ] - }, - { - "address": "cosmos1twu2lvgp3erk6gups2a8nae3jdahaj2xmlufsa", - "coins": [ - { - "denom": "stake", - "amount": "19032639271" - } - ] - }, - { - "address": "cosmos17xpfvakm2amg962yls6f84z3kell8c5lserqta", - "coins": [ - { - "denom": "stake", - "amount": "58122072521" - } - ] - }, - { - "address": "cosmos10qj9cj3dxecyu826gaw72ylwum96jkkh9p462q", - "coins": [ - { - "denom": "stake", - "amount": "9842088248" - } - ] - }, - { - "address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", - "coins": [ - { - "denom": "stake", - "amount": "705908591" - } - ] - }, - { - "address": "cosmos16v3h2mggt8tnkxp0vq5tq25fhr3knvf4jw40l5", - "coins": [ - { - "denom": "stake", - "amount": "1185875189" - } - ] - }, - { - "address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", - "coins": [ - { - "denom": "stake", - "amount": "418029002" - } - ] - }, - { - "address": "cosmos1p9wm55eaeux7v9eqf3szfqt77w70djrj7wpeh5", - "coins": [ - { - "denom": "stake", - "amount": "9462936775" - } - ] - }, - { - "address": "cosmos1vf0r0fg74jmm6qxq4dj8amhr64acs32333ua0d", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos10p78pcqm2slk4x0pfxl9ht5spskwquhzptwzt8", - "coins": [ - { - "denom": "stake", - "amount": "4402481942" - } - ] - }, - { - "address": "cosmos17g3wgr4wy0x5nv9ep2eenc2tucpulq5yjy50st", - "coins": [ - { - "denom": "stake", - "amount": "28602033597" - } - ] - }, - { - "address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", - "coins": [ - { - "denom": "stake", - "amount": "2923917158" - } - ] - }, - { - "address": "cosmos1gkdgukkcx52r2w82q2usyncf67s30g7hmqc74n", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1jhvqn320w9nqxcs3ar7250jqg7us9vuszw9cwq", - "coins": [ - { - "denom": "stake", - "amount": "3106989523" - } - ] - }, - { - "address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", - "coins": [ - { - "denom": "stake", - "amount": "1168619126" - } - ] - }, - { - "address": "cosmos1478sx3zdfylsts5sus5rlz4dgvyvacqpuchj6f", - "coins": [ - { - "denom": "stake", - "amount": "2893443077" - } - ] - }, - { - "address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "coins": [ - { - "denom": "stake", - "amount": "5201373" - } - ] - }, - { - "address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", - "coins": [ - { - "denom": "stake", - "amount": "773136739" - } - ] - }, - { - "address": "cosmos1s0r2g8pzwre6tvywfw0h8vy8qg7spd2ytfkx70", - "coins": [ - { - "denom": "stake", - "amount": "11716014580" - } - ] - }, - { - "address": "cosmos1rzuu7jf5f66jyhqjsusre7uuha0hw5e8ff7tar", - "coins": [ - { - "denom": "stake", - "amount": "2591107671" - } - ] - }, - { - "address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", - "coins": [ - { - "denom": "stake", - "amount": "12549842012" - } - ] - }, - { - "address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", - "coins": [ - { - "denom": "stake", - "amount": "3396133880" - } - ] - }, - { - "address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", - "coins": [ - { - "denom": "stake", - "amount": "1549619016" - } - ] - }, - { - "address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", - "coins": [ - { - "denom": "stake", - "amount": "5024279292" - } - ] - }, - { - "address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "coins": [ - { - "denom": "stake", - "amount": "13027420896" - } - ] - }, - { - "address": "cosmos1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpkca4g8", - "coins": [ - { - "denom": "stake", - "amount": "10045955684" - } - ] - }, - { - "address": "cosmos1hx0cc2lvfagl5q5x34qea2fc53hhr7mtgdy75v", - "coins": [ - { - "denom": "stake", - "amount": "943865159" - } - ] - }, - { - "address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", - "coins": [ - { - "denom": "stake", - "amount": "13536" - } - ] - }, - { - "address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", - "coins": [ - { - "denom": "stake", - "amount": "455288844" - } - ] - }, - { - "address": "cosmos15tv54z32xgqechywvr7ymsfdvr2mmx3553j8rd", - "coins": [ - { - "denom": "stake", - "amount": "4130788285" - } - ] - }, - { - "address": "cosmos15wqxlh0da39gzvp3x50mrju8cj7ppfgachrxd5", - "coins": [ - { - "denom": "stake", - "amount": "13821213719" - } - ] - }, - { - "address": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", - "coins": [ - { - "denom": "stake", - "amount": "23203176886" - } - ] - }, - { - "address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "coins": [ - { - "denom": "stake", - "amount": "186545734" - } - ] - }, - { - "address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "coins": [ - { - "denom": "stake", - "amount": "4079295156" - } - ] - }, - { - "address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", - "coins": [ - { - "denom": "stake", - "amount": "8027715337" - } - ] - }, - { - "address": "cosmos1h9wg5q5x4gxkkca0x7krw7953h0ce2xwr2cwl8", - "coins": [ - { - "denom": "stake", - "amount": "904432602" - } - ] - }, - { - "address": "cosmos1vuws77sz0xzvz8y0dg6wjz9fzd7plxpk29ljn7", - "coins": [ - { - "denom": "stake", - "amount": "9760097671" - } - ] - }, - { - "address": "cosmos1jn4dp0s3ewkwarqmra50czqlm6g7cf9plthphn", - "coins": [ - { - "denom": "stake", - "amount": "10580302668" - } - ] - }, - { - "address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", - "coins": [ - { - "denom": "stake", - "amount": "9940602011" - } - ] - }, - { - "address": "cosmos1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptd8zyma", - "coins": [ - { - "denom": "stake", - "amount": "5874941926" - } - ] - }, - { - "address": "cosmos1l6uepmju2xg0h8rzkx8wku0hsncargw5ruhhfz", - "coins": [ - { - "denom": "stake", - "amount": "27190014712" - } - ] - }, - { - "address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", - "coins": [ - { - "denom": "stake", - "amount": "8089075727" - } - ] - }, - { - "address": "cosmos1nky4q5h5wurtumxwsf9w79vmw3l4682879kly4", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", - "coins": [ - { - "denom": "stake", - "amount": "1001089496" - } - ] - }, - { - "address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m", - "coins": [ - { - "denom": "stake", - "amount": "3626749980" - } - ] - }, - { - "address": "cosmos1wve3m263mdhqqpg0yjd8vmveflugrk5dk2cr0z", - "coins": [ - { - "denom": "stake", - "amount": "471391328" - } - ] - }, - { - "address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", - "coins": [ - { - "denom": "stake", - "amount": "2021915876" - } - ] - }, - { - "address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "coins": [ - { - "denom": "stake", - "amount": "211489" - } - ] - }, - { - "address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", - "coins": [ - { - "denom": "stake", - "amount": "1083080420" - } - ] - }, - { - "address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "coins": [ - { - "denom": "stake", - "amount": "5594690557" - } - ] - }, - { - "address": "cosmos188yd2umzwfwen7es68wrlh6auu3p8jhz0qfgej", - "coins": [ - { - "denom": "stake", - "amount": "14023256937" - } - ] - }, - { - "address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "coins": [ - { - "denom": "stake", - "amount": "84451457" - } - ] - }, - { - "address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", - "coins": [ - { - "denom": "stake", - "amount": "60976392" - } - ] - }, - { - "address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", - "coins": [ - { - "denom": "stake", - "amount": "58207245" - } - ] - }, - { - "address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890", - "coins": [ - { - "denom": "stake", - "amount": "12623413968" - } - ] - }, - { - "address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck", - "coins": [ - { - "denom": "stake", - "amount": "11348168659" - } - ] - }, - { - "address": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", - "coins": [] - }, - { - "address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", - "coins": [ - { - "denom": "stake", - "amount": "3527416972" - } - ] - }, - { - "address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", - "coins": [ - { - "denom": "stake", - "amount": "346508892" - } - ] - }, - { - "address": "cosmos1x3u97k0k8xxxjvt2vca8fy9g3qm7wtgp8wtmqs", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos15zqzxj663h8g8naxyz324j2rpd3rnw4rvtxep2", - "coins": [ - { - "denom": "stake", - "amount": "4344890253" - } - ] - }, - { - "address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", - "coins": [ - { - "denom": "stake", - "amount": "3015097503" - } - ] - }, - { - "address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", - "coins": [ - { - "denom": "stake", - "amount": "2003384336" - } - ] - }, - { - "address": "cosmos1nqlclz6g890zaeq4gadtl82e3f9kwzp60sqrqm", - "coins": [ - { - "denom": "stake", - "amount": "43841823459" - } - ] - }, - { - "address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "coins": [ - { - "denom": "stake", - "amount": "10576644032" - } - ] - }, - { - "address": "cosmos1waql7pehyspkf8l9q04gt508c0khx0nt64jsxj", - "coins": [ - { - "denom": "stake", - "amount": "6361766617" - } - ] - }, - { - "address": "cosmos1e5zmgnq6y7zxn5c642ty3jxur3lk0n0ca4wyym", - "coins": [ - { - "denom": "stake", - "amount": "26478717" - } - ] - }, - { - "address": "cosmos1u2uakvrpv8htq6a7n29hlpxxec956caj2akqcu", - "coins": [ - { - "denom": "stake", - "amount": "322429093" - } - ] - }, - { - "address": "cosmos1yqc7yxdxgz9etrp3avxg8t6ppfm73wxnzyf360", - "coins": [ - { - "denom": "stake", - "amount": "4169687934" - } - ] - }, - { - "address": "cosmos1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75pf45v0", - "coins": [ - { - "denom": "stake", - "amount": "1740107116" - } - ] - }, - { - "address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", - "coins": [ - { - "denom": "stake", - "amount": "458431484" - } - ] - }, - { - "address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", - "coins": [ - { - "denom": "stake", - "amount": "19082873860" - } - ] - }, - { - "address": "cosmos1lvzau6mkgwnyewqvd09h307algs2ncrpp2ukjw", - "coins": [ - { - "denom": "stake", - "amount": "7284516897" - } - ] - }, - { - "address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", - "coins": [ - { - "denom": "stake", - "amount": "297213286" - } - ] - }, - { - "address": "cosmos1gtv2yjxfwhgrwrv6uag9pnqw69q0p5z8mzdddn", - "coins": [ - { - "denom": "stake", - "amount": "20436387859" - } - ] - }, - { - "address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", - "coins": [ - { - "denom": "stake", - "amount": "1723397520" - } - ] - }, - { - "address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", - "coins": [ - { - "denom": "stake", - "amount": "3240002098" - } - ] - }, - { - "address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", - "coins": [ - { - "denom": "stake", - "amount": "3027314017" - } - ] - }, - { - "address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "coins": [ - { - "denom": "stake", - "amount": "1084188767" - } - ] - }, - { - "address": "cosmos1yqt74740zamtyag7qu9naqgrauz5wdzl4290wt", - "coins": [ - { - "denom": "stake", - "amount": "17164314765" - } - ] - }, - { - "address": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", - "coins": [ - { - "denom": "stake", - "amount": "502818439" - } - ] - }, - { - "address": "cosmos15hqa5fj9sx7mjvmquhknrcxkxkeudguk9zpqqy", - "coins": [ - { - "denom": "stake", - "amount": "669796614" - } - ] - }, - { - "address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", - "coins": [ - { - "denom": "stake", - "amount": "29856017771" - } - ] - }, - { - "address": "cosmos1zjzkk7l2jalrspy6500my8v0yy6ycz7el534zw", - "coins": [ - { - "denom": "stake", - "amount": "12459892422" - } - ] - }, - { - "address": "cosmos1v9k0h7s32ujfeu777jkc7z69gctz4zwfy7q49l", - "coins": [ - { - "denom": "stake", - "amount": "93077277" - } - ] - }, - { - "address": "cosmos1kw46xpry8rw4xn0fvv84g0af2mfuhxpyd2m273", - "coins": [ - { - "denom": "stake", - "amount": "4380266755" - } - ] - }, - { - "address": "cosmos1ah3yy9ql35jh5ehykl626e848t2rrsyze8w8nz", - "coins": [ - { - "denom": "stake", - "amount": "5483503654" - } - ] - }, - { - "address": "cosmos18k4yz84xrjqvrq9u7sehvje3ax4aspcksauctw", - "coins": [ - { - "denom": "stake", - "amount": "5879019" - } - ] - }, - { - "address": "cosmos1tzgwtuyftq8f686z0d8zvyqh37la70pje3nmxt", - "coins": [ - { - "denom": "stake", - "amount": "14125018615" - } - ] - }, - { - "address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "coins": [ - { - "denom": "stake", - "amount": "17146233" - } - ] - }, - { - "address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", - "coins": [ - { - "denom": "stake", - "amount": "1315117671" - } - ] - }, - { - "address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3", - "coins": [ - { - "denom": "stake", - "amount": "4627069904" - } - ] - }, - { - "address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", - "coins": [ - { - "denom": "stake", - "amount": "1600841844" - } - ] - }, - { - "address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", - "coins": [ - { - "denom": "stake", - "amount": "541561331" - } - ] - }, - { - "address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", - "coins": [ - { - "denom": "stake", - "amount": "34022337440" - } - ] - }, - { - "address": "cosmos1kszz383fcxdtxhn3xr42hvzp8rfkaaqevxmrtf", - "coins": [ - { - "denom": "stake", - "amount": "41854155720" - } - ] - }, - { - "address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", - "coins": [ - { - "denom": "stake", - "amount": "18645308" - } - ] - }, - { - "address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", - "coins": [ - { - "denom": "stake", - "amount": "7123599859" - } - ] - }, - { - "address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", - "coins": [ - { - "denom": "stake", - "amount": "177070760" - } - ] - }, - { - "address": "cosmos1rtw2ev4xm89vaqzwc7k520jlvrvlqnevk5f53y", - "coins": [ - { - "denom": "stake", - "amount": "2608420772" - } - ] - }, - { - "address": "cosmos1f2pvewnws73u0z5wsfmv5uqudwxl6jupfm6nta", - "coins": [ - { - "denom": "stake", - "amount": "10404746182" - } - ] - }, - { - "address": "cosmos12qsn5ukkpvy0ymcsfh85yqp4paw5ew9mcg8z0y", - "coins": [ - { - "denom": "stake", - "amount": "2367482127" - } - ] - }, - { - "address": "cosmos1mcc0dq93nrt3u6hl6ju82hyw3rdfun029jx4v2", - "coins": [ - { - "denom": "stake", - "amount": "12550456573" - } - ] - }, - { - "address": "cosmos1ly9aff4ptcun94q3cs26cfzqnq59j5rw2gl89u", - "coins": [ - { - "denom": "stake", - "amount": "5402544029" - } - ] - }, - { - "address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "coins": [ - { - "denom": "stake", - "amount": "2968564765" - } - ] - }, - { - "address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "coins": [ - { - "denom": "stake", - "amount": "46901825" - } - ] - }, - { - "address": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", - "coins": [ - { - "denom": "stake", - "amount": "6915791999" - } - ] - }, - { - "address": "cosmos1864wj4twqatq54rrxl5jmfey55tmh0hvgmd9yw", - "coins": [ - { - "denom": "stake", - "amount": "12098312849" - } - ] - }, - { - "address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "coins": [ - { - "denom": "stake", - "amount": "137698291" - } - ] - }, - { - "address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", - "coins": [ - { - "denom": "stake", - "amount": "8229032300" - } - ] - }, - { - "address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", - "coins": [ - { - "denom": "stake", - "amount": "1633274510" - } - ] - }, - { - "address": "cosmos1zs6hn5hf6qxjwmvntrzwhjkgvu963d0g8hz2z8", - "coins": [ - { - "denom": "stake", - "amount": "13153702389" - } - ] - }, - { - "address": "cosmos1y2whyxm3k2mtz3j0hvjev7ztq8q0cz0vqrphgt", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1jjav2y88kx0jempjzz5jcc9y4yatkyn7xnnvsv", - "coins": [ - { - "denom": "stake", - "amount": "3403233527" - } - ] - }, - { - "address": "cosmos1w69f6s0dqsqfqq93hczddadwgeq86zr9dfmddq", - "coins": [ - { - "denom": "stake", - "amount": "1465926361" - } - ] - }, - { - "address": "cosmos1j9jq7pea9y4y7fersmc0wlk99sxj3vgdya3hm3", - "coins": [ - { - "denom": "stake", - "amount": "3142382418" - } - ] - }, - { - "address": "cosmos18037phaq40fkqdr4pxk2jajnsq8prfyyl4tzvz", - "coins": [ - { - "denom": "stake", - "amount": "20638774775" - } - ] - }, - { - "address": "cosmos1gh67zgx4f9d64ctqhtascuh87805v8yffrfytl", - "coins": [ - { - "denom": "stake", - "amount": "3970213411" - } - ] - }, - { - "address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", - "coins": [ - { - "denom": "stake", - "amount": "3724106541" - } - ] - }, - { - "address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", - "coins": [ - { - "denom": "stake", - "amount": "3591544060" - } - ] - }, - { - "address": "cosmos199mt855sp3pqqxarqyjffjgm2v6uzru4fhslp6", - "coins": [ - { - "denom": "stake", - "amount": "5450625896" - } - ] - }, - { - "address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", - "coins": [ - { - "denom": "stake", - "amount": "55502038726" - } - ] - }, - { - "address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", - "coins": [ - { - "denom": "stake", - "amount": "374888103" - } - ] - }, - { - "address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "coins": [ - { - "denom": "stake", - "amount": "2346136451" - } - ] - }, - { - "address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", - "coins": [ - { - "denom": "stake", - "amount": "5755146322" - } - ] - }, - { - "address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", - "coins": [ - { - "denom": "stake", - "amount": "70954933" - } - ] - }, - { - "address": "cosmos139yreyw4l9jthf99c896sc4q7yvx9su4a95294", - "coins": [ - { - "denom": "stake", - "amount": "14628025114" - } - ] - }, - { - "address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "coins": [ - { - "denom": "stake", - "amount": "6804551431" - } - ] - }, - { - "address": "cosmos1gwwltgyatg8yfe54447dxnyvs2nt6xxsl6lv2m", - "coins": [ - { - "denom": "stake", - "amount": "2983492148" - } - ] - }, - { - "address": "cosmos1vwgt6t9vd9heg0jwq6gk0x7egw4cmp4w79yuyy", - "coins": [ - { - "denom": "stake", - "amount": "9833589413" - } - ] - }, - { - "address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", - "coins": [ - { - "denom": "stake", - "amount": "1029471879" - } - ] - }, - { - "address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020", - "coins": [ - { - "denom": "stake", - "amount": "39989039845" - } - ] - }, - { - "address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", - "coins": [ - { - "denom": "stake", - "amount": "1416384776" - } - ] - }, - { - "address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", - "coins": [ - { - "denom": "stake", - "amount": "4553916241" - } - ] - }, - { - "address": "cosmos1884glx2vk6nxcurpf2dtjp3qgsl8zh5pm09rs0", - "coins": [ - { - "denom": "stake", - "amount": "6122315665" - } - ] - }, - { - "address": "cosmos1wvzq2f252674u3gvmqhnq8g4n6lmxedmzs0czm", - "coins": [ - { - "denom": "stake", - "amount": "860628336" - } - ] - }, - { - "address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", - "coins": [ - { - "denom": "stake", - "amount": "14328793467" - } - ] - }, - { - "address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", - "coins": [ - { - "denom": "stake", - "amount": "1003165897" - } - ] - }, - { - "address": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn", - "coins": [ - { - "denom": "stake", - "amount": "2122" - } - ] - }, - { - "address": "cosmos1nrugh7am9s584k6qlf5nxlpetarxs2csglt46w", - "coins": [ - { - "denom": "stake", - "amount": "26037870620" - } - ] - }, - { - "address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe", - "coins": [ - { - "denom": "stake", - "amount": "2271641744" - } - ] - }, - { - "address": "cosmos1qy0qwzljplfauvyhgayw6nxte2zxujh4tnq09z", - "coins": [ - { - "denom": "stake", - "amount": "2132747576" - } - ] - }, - { - "address": "cosmos1py3htj8kmztj0ecdrhcgcmet6vupr9hvlhxkwe", - "coins": [ - { - "denom": "stake", - "amount": "4384438372" - } - ] - }, - { - "address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", - "coins": [ - { - "denom": "stake", - "amount": "7709395586" - } - ] - }, - { - "address": "cosmos1vw3dl2j248ypyvvjfu7036hlup5p2gpwgvg7qd", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos10cl6sallgwf882apcyagjqa2lx4j8592cjw0gf", - "coins": [ - { - "denom": "stake", - "amount": "34250944236" - } - ] - }, - { - "address": "cosmos1jn8g39pdp9zaz750v6x7kspqv4wdfcg8dluy5p", - "coins": [ - { - "denom": "stake", - "amount": "16755478373" - } - ] - }, - { - "address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "coins": [ - { - "denom": "stake", - "amount": "22418778354" - } - ] - }, - { - "address": "cosmos1l802gyymr2zukzel8ge4ddnqdevjvhnm3g4kk9", - "coins": [ - { - "denom": "stake", - "amount": "1027195928" - } - ] - }, - { - "address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", - "coins": [ - { - "denom": "stake", - "amount": "7949579" - } - ] - }, - { - "address": "cosmos1xfqsntajat3kv06ptad8zsqacmjrsjc2sa5ajt", - "coins": [ - { - "denom": "stake", - "amount": "78640589" - } - ] - }, - { - "address": "cosmos1598m5w5wpz27dtq3er8uq2czcdvrwpffh7w03h", - "coins": [ - { - "denom": "stake", - "amount": "2414235590" - } - ] - }, - { - "address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", - "coins": [ - { - "denom": "stake", - "amount": "3865120533" - } - ] - }, - { - "address": "cosmos1syn6uv0ma6a0qn6n8gy6qrc7jdp8ghr6vva3jn", - "coins": [ - { - "denom": "stake", - "amount": "1639770002" - } - ] - }, - { - "address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", - "coins": [ - { - "denom": "stake", - "amount": "11606154318" - } - ] - }, - { - "address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", - "coins": [ - { - "denom": "stake", - "amount": "13958189098" - } - ] - }, - { - "address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", - "coins": [ - { - "denom": "stake", - "amount": "2913504903" - } - ] - }, - { - "address": "cosmos1w0050eew8g7zyvg7ap0tjhd6yzvew3ndls3v0f", - "coins": [ - { - "denom": "stake", - "amount": "25072951889" - } - ] - }, - { - "address": "cosmos19xyafr0fc2g0rvemhmruyj8ywas8qamfnps2zx", - "coins": [ - { - "denom": "stake", - "amount": "454383670" - } - ] - }, - { - "address": "cosmos1ftj05w0hmw2xxw5p7gvr258j2824qd8r2xdk9e", - "coins": [ - { - "denom": "stake", - "amount": "3832536051" - } - ] - }, - { - "address": "cosmos1x5tgg6j5hqh0swtw3wqymfdcju0mmy2uff8zee", - "coins": [ - { - "denom": "stake", - "amount": "28752766463" - } - ] - }, - { - "address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", - "coins": [ - { - "denom": "stake", - "amount": "33862899721" - } - ] - }, - { - "address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", - "coins": [ - { - "denom": "stake", - "amount": "716143736" - } - ] - }, - { - "address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", - "coins": [ - { - "denom": "stake", - "amount": "25865358094" - } - ] - }, - { - "address": "cosmos1cv6mc68xznavrjel5fth3vry84wnwjy29mqn33", - "coins": [ - { - "denom": "stake", - "amount": "5240807143" - } - ] - }, - { - "address": "cosmos16a2sxhxlq7qfvkam3afnh9y6ph2lga8fn6fyqa", - "coins": [ - { - "denom": "stake", - "amount": "31603669849" - } - ] - }, - { - "address": "cosmos1pxwj79qtf9y8jugqgf7vxwhvgd85vapq4ndldk", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1z7sj5sg2cnkg4phzrswwjkkq8p2d6434pcyv2p", - "coins": [ - { - "denom": "stake", - "amount": "86484669" - } - ] - }, - { - "address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", - "coins": [ - { - "denom": "stake", - "amount": "26173345986" - } - ] - }, - { - "address": "cosmos12q3w0j5hp023hdjafgc357hy7kkha296f4xrjf", - "coins": [ - { - "denom": "stake", - "amount": "9982960628" - } - ] - }, - { - "address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq", - "coins": [ - { - "denom": "stake", - "amount": "16211339387" - } - ] - }, - { - "address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "coins": [ - { - "denom": "stake", - "amount": "11937894506" - } - ] - }, - { - "address": "cosmos1s7e8ukt3awex0xh6qw27pramwg3hkgeqtm0nfs", - "coins": [ - { - "denom": "stake", - "amount": "240557834" - } - ] - }, - { - "address": "cosmos1tz087eh88lqkesr77yl6ys9dw95qysfqtff52a", - "coins": [ - { - "denom": "stake", - "amount": "41546208" - } - ] - }, - { - "address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", - "coins": [ - { - "denom": "stake", - "amount": "6588105820" - } - ] - }, - { - "address": "cosmos1c6afa9c3repulws30tzpsggt5jfdpc88ct47wz", - "coins": [ - { - "denom": "stake", - "amount": "7712422872" - } - ] - }, - { - "address": "cosmos18kcmwj6z3gwmsscam9f04ty3tm8std0mw0upfc", - "coins": [ - { - "denom": "stake", - "amount": "1955991522" - } - ] - }, - { - "address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", - "coins": [ - { - "denom": "stake", - "amount": "631103978" - } - ] - }, - { - "address": "cosmos13q5vwanrgz5ff2f6y07c9236xj4ergak73hgrt", - "coins": [ - { - "denom": "stake", - "amount": "5695917256" - } - ] - }, - { - "address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", - "coins": [ - { - "denom": "stake", - "amount": "1557317382" - } - ] - }, - { - "address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", - "coins": [ - { - "denom": "stake", - "amount": "875920239" - } - ] - }, - { - "address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", - "coins": [ - { - "denom": "stake", - "amount": "446950366" - } - ] - }, - { - "address": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", - "coins": [ - { - "denom": "stake", - "amount": "13493884" - } - ] - }, - { - "address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", - "coins": [ - { - "denom": "stake", - "amount": "583792995" - } - ] - }, - { - "address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", - "coins": [ - { - "denom": "stake", - "amount": "50780939059" - } - ] - }, - { - "address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "coins": [ - { - "denom": "stake", - "amount": "3566000849" - } - ] - }, - { - "address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", - "coins": [ - { - "denom": "stake", - "amount": "54091459" - } - ] - }, - { - "address": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", - "coins": [ - { - "denom": "stake", - "amount": "2932939850" - } - ] - }, - { - "address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", - "coins": [ - { - "denom": "stake", - "amount": "1772749888" - } - ] - }, - { - "address": "cosmos19deqn6g9q7mnhzg5j0qr25k9gz74pwlph5p50r", - "coins": [ - { - "denom": "stake", - "amount": "4542114326" - } - ] - }, - { - "address": "cosmos1d9m3l8khcrx0zhftehkuw67zzszf9v9le5dvrm", - "coins": [ - { - "denom": "stake", - "amount": "3202182709" - } - ] - }, - { - "address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "coins": [ - { - "denom": "stake", - "amount": "340320137" - } - ] - }, - { - "address": "cosmos16l54emw4lwhremfds2mnnlxcu06eknp8gxhgq7", - "coins": [ - { - "denom": "stake", - "amount": "21033488960" - } - ] - }, - { - "address": "cosmos1u7e0dy2dr65lfs5c2scvn9xzrntteew7lvuw7w", - "coins": [ - { - "denom": "stake", - "amount": "31932453648" - } - ] - }, - { - "address": "cosmos193pvwgxpxnd6tgz0gtyl00dq8r3ygeflnhaxpm", - "coins": [ - { - "denom": "stake", - "amount": "10058590188" - } - ] - }, - { - "address": "cosmos1tsmp448mysp6vr09f26ee7wa02vpcpppk3jgqf", - "coins": [ - { - "denom": "stake", - "amount": "1724802940" - } - ] - }, - { - "address": "cosmos1tzt5ayvd6xpwxfcsxawlleluwylr2dhl46qvw2", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1cud0s54s6cf9sl786mhjlnzhm58v5cp324fxv3", - "coins": [ - { - "denom": "stake", - "amount": "26879442501" - } - ] - }, - { - "address": "cosmos19rlals9yl7q50rfww4n70m26vna9envvsqj886", - "coins": [ - { - "denom": "stake", - "amount": "197728057" - } - ] - }, - { - "address": "cosmos1fc96780mrsxn5kgplhtna40qepjgrm9wsyly02", - "coins": [ - { - "denom": "stake", - "amount": "1913322840" - } - ] - }, - { - "address": "cosmos1jsfel7tdxv09dm4lsqesfuhlpnlhhpeh4fdl27", - "coins": [ - { - "denom": "stake", - "amount": "9320838117" - } - ] - }, - { - "address": "cosmos1tv8x2sctvryfspc68rypwrld99099hvrh8vxz6", - "coins": [ - { - "denom": "stake", - "amount": "14668985305" - } - ] - }, - { - "address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2", - "coins": [ - { - "denom": "stake", - "amount": "14360106349" - } - ] - }, - { - "address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8", - "coins": [ - { - "denom": "stake", - "amount": "11775985141" - } - ] - }, - { - "address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", - "coins": [ - { - "denom": "stake", - "amount": "6644218663" - } - ] - }, - { - "address": "cosmos1npd5ddcq5cm3q938pk02dqa4te3jnfy25c5gnn", - "coins": [ - { - "denom": "stake", - "amount": "29130561664" - } - ] - }, - { - "address": "cosmos1ng5m6spxngyne4qzce35fdg0whl0yqgv9lg9tt", - "coins": [ - { - "denom": "stake", - "amount": "22155740126" - } - ] - }, - { - "address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", - "coins": [ - { - "denom": "stake", - "amount": "331224560" - } - ] - }, - { - "address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", - "coins": [ - { - "denom": "stake", - "amount": "1110800502" - } - ] - }, - { - "address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", - "coins": [ - { - "denom": "stake", - "amount": "142237005" - } - ] - }, - { - "address": "cosmos1qp6s6vzf6l0mzeglw0a9d75h7ch4w99ahux3j2", - "coins": [ - { - "denom": "stake", - "amount": "16901189909" - } - ] - }, - { - "address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "coins": [ - { - "denom": "stake", - "amount": "21826174532" - } - ] - }, - { - "address": "cosmos1j9vhccgf8520gtz7zn5jxj9lk3nqg0wx479kwp", - "coins": [ - { - "denom": "stake", - "amount": "5655074238" - } - ] - }, - { - "address": "cosmos14urapj7e6tj2s8clcsgyat6xmkppj7nm4qtewf", - "coins": [ - { - "denom": "stake", - "amount": "13328417678" - } - ] - }, - { - "address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "coins": [ - { - "denom": "stake", - "amount": "1042766810" - } - ] - }, - { - "address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", - "coins": [ - { - "denom": "stake", - "amount": "127974117" - } - ] - }, - { - "address": "cosmos19tvzgu6dmna8qljv8ex42vpek4r2handdn09d7", - "coins": [ - { - "denom": "stake", - "amount": "11566522644" - } - ] - }, - { - "address": "cosmos1jzhlspgxp578kzg9dtvg8tm2w9k7tnmcpstzry", - "coins": [ - { - "denom": "stake", - "amount": "6243377472" - } - ] - }, - { - "address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", - "coins": [ - { - "denom": "stake", - "amount": "921394483" - } - ] - }, - { - "address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp", - "coins": [ - { - "denom": "stake", - "amount": "2311740231" - } - ] - }, - { - "address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", - "coins": [ - { - "denom": "stake", - "amount": "2357393775" - } - ] - }, - { - "address": "cosmos1a0jdqzvk078d6486vuxdr5d0yp6rglue2nh5dn", - "coins": [ - { - "denom": "stake", - "amount": "24452743711" - } - ] - }, - { - "address": "cosmos1trs75ceuvsg83y9dje9k79em4v684dm5e9ya49", - "coins": [ - { - "denom": "stake", - "amount": "7877000621" - } - ] - }, - { - "address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", - "coins": [ - { - "denom": "stake", - "amount": "13201025581" - } - ] - }, - { - "address": "cosmos17ph7nmvmxdhm687z4k5phsyd08wvsnv44emkj8", - "coins": [ - { - "denom": "stake", - "amount": "15206858159" - } - ] - }, - { - "address": "cosmos1n8ugy8hee9hnzntcr7rkyhrrkcgclg3385vkd7", - "coins": [ - { - "denom": "stake", - "amount": "7982436451" - } - ] - }, - { - "address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "coins": [ - { - "denom": "stake", - "amount": "27019742" - } - ] - }, - { - "address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", - "coins": [ - { - "denom": "stake", - "amount": "47454378" - } - ] - }, - { - "address": "cosmos147pq4rzswl76kdeyx8sc7pagf4nhjpnq2hlrh3", - "coins": [ - { - "denom": "stake", - "amount": "17684418984" - } - ] - }, - { - "address": "cosmos1k3rapsk6gmfzeugjq5w2c4msuj7t4qhat0xn4m", - "coins": [ - { - "denom": "stake", - "amount": "13530049625" - } - ] - }, - { - "address": "cosmos1hfjku50s3uhp66wuqexafzc3kl73z3xzhj5nqv", - "coins": [ - { - "denom": "stake", - "amount": "27215781841" - } - ] - }, - { - "address": "cosmos1s8c3pza7vnx7e62k94z5jgx5jqtfh7ux2wh592", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "coins": [ - { - "denom": "stake", - "amount": "2163641" - } - ] - }, - { - "address": "cosmos1vpc637uayw7rm4a48cuzuynvu9yse45me0jdmr", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos10d3vd6yx9k9ns6v82r4krm3d4ragw04cysm62c", - "coins": [ - { - "denom": "stake", - "amount": "24915840202" - } - ] - }, - { - "address": "cosmos1etrkjjjjvuej87yu2pv4mcmhjsjqsn5hm9n043", - "coins": [ - { - "denom": "stake", - "amount": "1843095100" - } - ] - }, - { - "address": "cosmos1af3ljdelv635n7yh76vvvkcs9adg6pq5z78lqn", - "coins": [ - { - "denom": "stake", - "amount": "12068688059" - } - ] - }, - { - "address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", - "coins": [ - { - "denom": "stake", - "amount": "367071745" - } - ] - }, - { - "address": "cosmos152haw4xa8p89az8fws3x38vr4cr4l5h0c5hsjx", - "coins": [ - { - "denom": "stake", - "amount": "9234762112" - } - ] - }, - { - "address": "cosmos1dgzvesl67z96ttlt5ulga25phe8pnspt663dvr", - "coins": [ - { - "denom": "stake", - "amount": "7085547226" - } - ] - }, - { - "address": "cosmos1n44p6u7280zd652tkgyxy4jg0pp0agcvw3d2wj", - "coins": [ - { - "denom": "stake", - "amount": "13495776560" - } - ] - }, - { - "address": "cosmos1hxdqddf3u8vjm080ytpe959uktn4axdas3uqhl", - "coins": [ - { - "denom": "stake", - "amount": "595606485" - } - ] - }, - { - "address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", - "coins": [ - { - "denom": "stake", - "amount": "5977131994" - } - ] - }, - { - "address": "cosmos12k9kcewq2045n20vsa0u5a9m98k4se0rxtacum", - "coins": [ - { - "denom": "stake", - "amount": "1505380496" - } - ] - }, - { - "address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", - "coins": [ - { - "denom": "stake", - "amount": "114391691" - } - ] - }, - { - "address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "coins": [ - { - "denom": "stake", - "amount": "651893789" - } - ] - }, - { - "address": "cosmos1njvscahg6cus5fy9k5gkq72cxj4kcahlgy00dj", - "coins": [ - { - "denom": "stake", - "amount": "5124489738" - } - ] - }, - { - "address": "cosmos16tr72kn90g5zl7qhyhuqkjflejz00uzlkl65sj", - "coins": [ - { - "denom": "stake", - "amount": "7529832931" - } - ] - }, - { - "address": "cosmos1mzsvp23mjrjkspddkz6nta0x7kte6a23atg6ml", - "coins": [ - { - "denom": "stake", - "amount": "73193347478" - } - ] - }, - { - "address": "cosmos1a2sgqjezvkgzc6vhvmevtsjh8m8rp52zcfu7ga", - "coins": [ - { - "denom": "stake", - "amount": "1792725655" - } - ] - }, - { - "address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", - "coins": [ - { - "denom": "stake", - "amount": "61022104396" - } - ] - }, - { - "address": "cosmos1q74af09jhrvg2ntxvcfu7pdn4zmhxyvlgahaj3", - "coins": [ - { - "denom": "stake", - "amount": "39059088148" - } - ] - }, - { - "address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", - "coins": [ - { - "denom": "stake", - "amount": "16622058656" - } - ] - }, - { - "address": "cosmos1q3mptmfxfd03myzy847p0mrssqw0sh006086eg", - "coins": [ - { - "denom": "stake", - "amount": "360539951" - } - ] - }, - { - "address": "cosmos1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lypeadd", - "coins": [ - { - "denom": "stake", - "amount": "27838378013" - } - ] - }, - { - "address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", - "coins": [ - { - "denom": "stake", - "amount": "23165226101" - } - ] - }, - { - "address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa", - "coins": [ - { - "denom": "stake", - "amount": "12139282628" - } - ] - }, - { - "address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "coins": [ - { - "denom": "stake", - "amount": "500295785" - } - ] - }, - { - "address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", - "coins": [ - { - "denom": "stake", - "amount": "431054955" - } - ] - }, - { - "address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", - "coins": [ - { - "denom": "stake", - "amount": "134472549" - } - ] - }, - { - "address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", - "coins": [ - { - "denom": "stake", - "amount": "28210417562" - } - ] - }, - { - "address": "cosmos1hq6jh5rru27mkd4c9hye0a4wkq9f9w4n4jx9zj", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1l8slnw5jukpc47xr0s76htvfftpuku2g26f0h8", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", - "coins": [ - { - "denom": "stake", - "amount": "9323619893" - } - ] - }, - { - "address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", - "coins": [ - { - "denom": "stake", - "amount": "12419255009" - } - ] - }, - { - "address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", - "coins": [ - { - "denom": "stake", - "amount": "42497870" - } - ] - }, - { - "address": "cosmos1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpdhe28d", - "coins": [ - { - "denom": "stake", - "amount": "7206783062" - } - ] - }, - { - "address": "cosmos1evqmj6ahqf76keas4ymhvf4r992kg7wrar0fru", - "coins": [ - { - "denom": "stake", - "amount": "38245684" - } - ] - }, - { - "address": "cosmos17vfaz9kp0wysnuhu9pmd9smh4x7s99dkeh8vcc", - "coins": [ - { - "denom": "stake", - "amount": "24884454210" - } - ] - }, - { - "address": "cosmos1x8z2epqz2rn6eknljym3ddjyg0z9tgtldaukjd", - "coins": [ - { - "denom": "stake", - "amount": "13021631151" - } - ] - }, - { - "address": "cosmos18gmd4r8ydls55yvgda4d8pfandk0xem5q7eat8", - "coins": [ - { - "denom": "stake", - "amount": "23002288010" - } - ] - }, - { - "address": "cosmos1ewm28x3e9t3huptgm36wnwx0zcx4aa7numjadx", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1uk8d0xdv7kdhlx3wh4pwff6v6rcx8f970fyjgm", - "coins": [ - { - "denom": "stake", - "amount": "1053780729" - } - ] - }, - { - "address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "coins": [ - { - "denom": "stake", - "amount": "2140387348" - } - ] - }, - { - "address": "cosmos17tphcpvwdr8ezywpz5qqglxul6hvx7elsl6h27", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", - "coins": [ - { - "denom": "stake", - "amount": "5337883637" - } - ] - }, - { - "address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "coins": [ - { - "denom": "stake", - "amount": "12627894956" - } - ] - }, - { - "address": "cosmos14hr55k3es7xfc54gwgu3plde0vaxkgerljee6v", - "coins": [ - { - "denom": "stake", - "amount": "694301419" - } - ] - }, - { - "address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "coins": [ - { - "denom": "stake", - "amount": "1528859698" - } - ] - }, - { - "address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "coins": [ - { - "denom": "stake", - "amount": "1758797154" - } - ] - }, - { - "address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", - "coins": [ - { - "denom": "stake", - "amount": "7921867072" - } - ] - }, - { - "address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", - "coins": [ - { - "denom": "stake", - "amount": "8605752281" - } - ] - }, - { - "address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", - "coins": [ - { - "denom": "stake", - "amount": "3065831325" - } - ] - }, - { - "address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", - "coins": [ - { - "denom": "stake", - "amount": "2831951210" - } - ] - }, - { - "address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", - "coins": [ - { - "denom": "stake", - "amount": "7327816530" - } - ] - }, - { - "address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", - "coins": [ - { - "denom": "stake", - "amount": "1434848168" - } - ] - }, - { - "address": "cosmos1kz20p7j939s8cqadmqqws80c6z93qdtyg8xt0v", - "coins": [ - { - "denom": "stake", - "amount": "20028549819" - } - ] - }, - { - "address": "cosmos1kmly2aspt8rk9h4ukdt8h52k24alvc34qukp2n", - "coins": [ - { - "denom": "stake", - "amount": "7833650880" - } - ] - }, - { - "address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", - "coins": [ - { - "denom": "stake", - "amount": "8844973181" - } - ] - }, - { - "address": "cosmos187t4e0t0xwp8ntfjkvec64kcwruph736hqxmkn", - "coins": [ - { - "denom": "stake", - "amount": "36687321731" - } - ] - }, - { - "address": "cosmos147lwcm3tx6uhtjphxwwmk7u32mucukalplv80z", - "coins": [ - { - "denom": "stake", - "amount": "275302883" - } - ] - }, - { - "address": "cosmos17fffsvdgtsagwjrc3gxqh9fkl872q40wpvajv0", - "coins": [ - { - "denom": "stake", - "amount": "421341763" - } - ] - }, - { - "address": "cosmos16adevt9lhqf3q4dwnmhty7ndr8478thakltsdj", - "coins": [ - { - "denom": "stake", - "amount": "21721083513" - } - ] - }, - { - "address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", - "coins": [ - { - "denom": "stake", - "amount": "11876" - } - ] - }, - { - "address": "cosmos1dwha0rccawlvhudcgdpzcf3eq2c0gqyzwctms8", - "coins": [ - { - "denom": "stake", - "amount": "45446416" - } - ] - }, - { - "address": "cosmos1n9dqelmmf5kfysk24m6chqfdcgz6r75u7mpuwh", - "coins": [ - { - "denom": "stake", - "amount": "3887700971" - } - ] - }, - { - "address": "cosmos16jj80c7d94m772cn77zwcuhnqcl6y95kepxvja", - "coins": [ - { - "denom": "stake", - "amount": "10668944722" - } - ] - }, - { - "address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", - "coins": [ - { - "denom": "stake", - "amount": "9832388029" - } - ] - }, - { - "address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", - "coins": [ - { - "denom": "stake", - "amount": "11246435643" - } - ] - }, - { - "address": "cosmos12gup0vvqv32z5nvdy4ycrhp77dnax5hfmcjav0", - "coins": [ - { - "denom": "stake", - "amount": "20076448050" - } - ] - }, - { - "address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", - "coins": [ - { - "denom": "stake", - "amount": "1171863518" - } - ] - }, - { - "address": "cosmos160jtaz9c35nr7dx349ezfzvs3xfdzm3mlxgulk", - "coins": [ - { - "denom": "stake", - "amount": "127938271" - } - ] - }, - { - "address": "cosmos1zc80fmnzrxu2ksxugtpa2vtkh7sstkqh6yn9de", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "coins": [ - { - "denom": "stake", - "amount": "18521342215" - } - ] - }, - { - "address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", - "coins": [ - { - "denom": "stake", - "amount": "2149842952" - } - ] - }, - { - "address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", - "coins": [ - { - "denom": "stake", - "amount": "283411585" - } - ] - }, - { - "address": "cosmos1rs7csfnnwetmd2dcjsv4p59w3t46g77lt0wq5l", - "coins": [ - { - "denom": "stake", - "amount": "48285588780" - } - ] - }, - { - "address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", - "coins": [ - { - "denom": "stake", - "amount": "3119021563" - } - ] - }, - { - "address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", - "coins": [ - { - "denom": "stake", - "amount": "1014639307" - } - ] - }, - { - "address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", - "coins": [ - { - "denom": "stake", - "amount": "61277" - } - ] - }, - { - "address": "cosmos1jf2rfeaukfmdhrd6prqdmqhcdyr8ezak8sm2wd", - "coins": [ - { - "denom": "stake", - "amount": "12131513230" - } - ] - }, - { - "address": "cosmos15cfduq92j3uvam8u942xj4egs42tjzl6p33fu5", - "coins": [ - { - "denom": "stake", - "amount": "1810883153" - } - ] - }, - { - "address": "cosmos1r572vr0k388gpjw5h2u75ppmarvgma20rqj2ws", - "coins": [ - { - "denom": "stake", - "amount": "4954848513" - } - ] - }, - { - "address": "cosmos194x33ngarpaach5g69g60cd2pjq8h0hqkfvk35", - "coins": [ - { - "denom": "stake", - "amount": "100577976" - } - ] - }, - { - "address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", - "coins": [ - { - "denom": "stake", - "amount": "3139178028" - } - ] - }, - { - "address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj", - "coins": [ - { - "denom": "stake", - "amount": "2206491530" - } - ] - }, - { - "address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", - "coins": [ - { - "denom": "stake", - "amount": "23492678" - } - ] - }, - { - "address": "cosmos1kfnt5d5fcma9kh4c5jk85yu75jer72kwdltg4s", - "coins": [ - { - "denom": "stake", - "amount": "545328955" - } - ] - }, - { - "address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", - "coins": [ - { - "denom": "stake", - "amount": "989039426" - } - ] - }, - { - "address": "cosmos1uvm96xdewfpdwymw5ywt8j5efq6jhpyl35pzg8", - "coins": [ - { - "denom": "stake", - "amount": "2028247266" - } - ] - }, - { - "address": "cosmos1ad5vqqf6lruklvkyyqvx3926cpjyn0wuz6ga64", - "coins": [ - { - "denom": "stake", - "amount": "190309901" - } - ] - }, - { - "address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", - "coins": [ - { - "denom": "stake", - "amount": "2759002567" - } - ] - }, - { - "address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", - "coins": [ - { - "denom": "stake", - "amount": "6188141939" - } - ] - }, - { - "address": "cosmos1qlkz3yutzuz0el2ullpyyaflfp78x8rr2cgld7", - "coins": [ - { - "denom": "stake", - "amount": "359577626" - } - ] - }, - { - "address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", - "coins": [ - { - "denom": "stake", - "amount": "4752910207" - } - ] - }, - { - "address": "cosmos1em3y3h4g7n8ue3wjcramnpmz0x8rwakrpjmrgz", - "coins": [ - { - "denom": "stake", - "amount": "73406829" - } - ] - }, - { - "address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", - "coins": [ - { - "denom": "stake", - "amount": "10502290701" - } - ] - }, - { - "address": "cosmos1kwqgs5v74u9wvxjerktm4mkaxqn4w7z3u6w6pq", - "coins": [ - { - "denom": "stake", - "amount": "2424925855" - } - ] - }, - { - "address": "cosmos1h6j4lyvuenmz9m7vq3hler8j7pg5ldpet0xf9a", - "coins": [ - { - "denom": "stake", - "amount": "28535343317" - } - ] - }, - { - "address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", - "coins": [ - { - "denom": "stake", - "amount": "24381789165" - } - ] - }, - { - "address": "cosmos147xrqy22fnlj0ksdjlhsh5u6hz55sjn5hzzvfh", - "coins": [ - { - "denom": "stake", - "amount": "1058842774" - } - ] - }, - { - "address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", - "coins": [ - { - "denom": "stake", - "amount": "551130155" - } - ] - }, - { - "address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", - "coins": [ - { - "denom": "stake", - "amount": "61560613" - } - ] - }, - { - "address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "coins": [ - { - "denom": "stake", - "amount": "4026291" - } - ] - }, - { - "address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", - "coins": [ - { - "denom": "stake", - "amount": "1039738" - } - ] - }, - { - "address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q", - "coins": [ - { - "denom": "stake", - "amount": "12163997562" - } - ] - }, - { - "address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", - "coins": [ - { - "denom": "stake", - "amount": "11128004217" - } - ] - }, - { - "address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", - "coins": [ - { - "denom": "stake", - "amount": "3507712328" - } - ] - }, - { - "address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", - "coins": [ - { - "denom": "stake", - "amount": "27529553561" - } - ] - }, - { - "address": "cosmos1fxdty0drndqphzcpq7v3jz3hhwp0sdhdatraf6", - "coins": [ - { - "denom": "stake", - "amount": "20001818225" - } - ] - }, - { - "address": "cosmos12vzdkp2z75x4paa9nf0dvg638l92n5s8e0jk0w", - "coins": [ - { - "denom": "stake", - "amount": "20801357125" - } - ] - }, - { - "address": "cosmos1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lpz963de", - "coins": [ - { - "denom": "stake", - "amount": "1429773802" - } - ] - }, - { - "address": "cosmos1uuk9ewj0532rzlhlg86tserdxvtnm3kq2k2zww", - "coins": [ - { - "denom": "stake", - "amount": "644193916" - } - ] - }, - { - "address": "cosmos19lvag94alj6tknd5jxjku46qq330x9r5aa7h6s", - "coins": [ - { - "denom": "stake", - "amount": "42342776905" - } - ] - }, - { - "address": "cosmos1f7utq63ae24m6aqw4metxjrc5q76j8h4gcgaxd", - "coins": [ - { - "denom": "stake", - "amount": "1393248722" - } - ] - }, - { - "address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", - "coins": [ - { - "denom": "stake", - "amount": "19721038" - } - ] - }, - { - "address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", - "coins": [ - { - "denom": "stake", - "amount": "9401621322" - } - ] - }, - { - "address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", - "coins": [ - { - "denom": "stake", - "amount": "8576833381" - } - ] - }, - { - "address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", - "coins": [ - { - "denom": "stake", - "amount": "823655" - } - ] - }, - { - "address": "cosmos1sr6u63sxsprpzv7tedc7e88tn6elrxkjnucszy", - "coins": [ - { - "denom": "stake", - "amount": "3225288403" - } - ] - }, - { - "address": "cosmos1sjhhg2yl2cqszte7pjyrp6lx5tg383lrpjyq0m", - "coins": [ - { - "denom": "stake", - "amount": "25389421762" - } - ] - }, - { - "address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "coins": [ - { - "denom": "stake", - "amount": "7865597657" - } - ] - }, - { - "address": "cosmos16e0y65dxvzn3zqlpql9uc3cmc3adtv8f9gf9ue", - "coins": [ - { - "denom": "stake", - "amount": "15075446352" - } - ] - }, - { - "address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", - "coins": [ - { - "denom": "stake", - "amount": "6642484481" - } - ] - }, - { - "address": "cosmos18xzukww2e9ufj2ae0ath48ul8ycfyv9nq7h362", - "coins": [ - { - "denom": "stake", - "amount": "15999936900" - } - ] - }, - { - "address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", - "coins": [ - { - "denom": "stake", - "amount": "4255284411" - } - ] - }, - { - "address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", - "coins": [ - { - "denom": "stake", - "amount": "1953341917" - } - ] - }, - { - "address": "cosmos179c5a9235h4z7h56gz9dhrj6gyaugvxmjt2e63", - "coins": [ - { - "denom": "stake", - "amount": "23777332675" - } - ] - }, - { - "address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", - "coins": [ - { - "denom": "stake", - "amount": "5054450035" - } - ] - }, - { - "address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", - "coins": [ - { - "denom": "stake", - "amount": "30525650362" - } - ] - }, - { - "address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", - "coins": [ - { - "denom": "stake", - "amount": "22351820978" - } - ] - }, - { - "address": "cosmos10ajx4nktldvyukmjdrx876mmwazd5sz860eu6p", - "coins": [ - { - "denom": "stake", - "amount": "3882498718" - } - ] - }, - { - "address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", - "coins": [ - { - "denom": "stake", - "amount": "1922556915" - } - ] - }, - { - "address": "cosmos1z9ns26y62x3qd3d8vs9eyxk8ndssa6gxtv2c06", - "coins": [ - { - "denom": "stake", - "amount": "15043703340" - } - ] - }, - { - "address": "cosmos1xfps7nht3lsfdzp092ast50aev4nhkaxtf7gh7", - "coins": [ - { - "denom": "stake", - "amount": "20251375850" - } - ] - }, - { - "address": "cosmos1zxpp6x3x0p0gcuuazft5ycgrxsa5wwsgl854uk", - "coins": [ - { - "denom": "stake", - "amount": "1631996648" - } - ] - }, - { - "address": "cosmos1hvfg35av2nfcjvx8ks035jk66dzvfvl24twzza", - "coins": [ - { - "denom": "stake", - "amount": "1576780179" - } - ] - }, - { - "address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", - "coins": [ - { - "denom": "stake", - "amount": "1281070152" - } - ] - }, - { - "address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", - "coins": [ - { - "denom": "stake", - "amount": "11266155" - } - ] - }, - { - "address": "cosmos16p0aw2u5chfc470xkpc6vasz5ys9smqcx40qq9", - "coins": [ - { - "denom": "stake", - "amount": "10339121952" - } - ] - }, - { - "address": "cosmos16x5vyv6aej2868kn56wpxpgzhvtvyegpjpwecw", - "coins": [ - { - "denom": "stake", - "amount": "23784644284" - } - ] - }, - { - "address": "cosmos1rrahhju34rdpmlnaww9r5egq0su2u6f44eve27", - "coins": [ - { - "denom": "stake", - "amount": "1551611997" - } - ] - }, - { - "address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2", - "coins": [ - { - "denom": "stake", - "amount": "3221334257" - } - ] - }, - { - "address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", - "coins": [ - { - "denom": "stake", - "amount": "4365311519" - } - ] - }, - { - "address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", - "coins": [ - { - "denom": "stake", - "amount": "9857714467" - } - ] - }, - { - "address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", - "coins": [ - { - "denom": "stake", - "amount": "31368808" - } - ] - }, - { - "address": "cosmos1yrdtzqfkyum94q4v3j3xllrtf09qv0jvympw86", - "coins": [ - { - "denom": "stake", - "amount": "4328892937" - } - ] - }, - { - "address": "cosmos1wc5kgetgqtfmjz9v87d9epwhlne2we0lzd8qn6", - "coins": [ - { - "denom": "stake", - "amount": "35933769064" - } - ] - }, - { - "address": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", - "coins": [ - { - "denom": "stake", - "amount": "15016694434" - } - ] - }, - { - "address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "coins": [ - { - "denom": "stake", - "amount": "410472665" - } - ] - }, - { - "address": "cosmos1528cn79dzm0p5tgyaclsdcuav6qetanhx9dwum", - "coins": [ - { - "denom": "stake", - "amount": "17147154252" - } - ] - }, - { - "address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", - "coins": [ - { - "denom": "stake", - "amount": "781544314" - } - ] - }, - { - "address": "cosmos1y78hvz86672la4agrx7n6lcmgjfgegpkldazmd", - "coins": [ - { - "denom": "stake", - "amount": "339240948" - } - ] - }, - { - "address": "cosmos1vqm5fdsflvnee33gk3d5pz7j6tf6dsp28eemcq", - "coins": [ - { - "denom": "stake", - "amount": "14819060916" - } - ] - }, - { - "address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", - "coins": [ - { - "denom": "stake", - "amount": "1859040" - } - ] - }, - { - "address": "cosmos1kueuhkfx5cvcuakpfd62y9kzxw3unlef07g2u4", - "coins": [ - { - "denom": "stake", - "amount": "3746927" - } - ] - }, - { - "address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", - "coins": [ - { - "denom": "stake", - "amount": "9392382967" - } - ] - }, - { - "address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", - "coins": [ - { - "denom": "stake", - "amount": "1088681889" - } - ] - }, - { - "address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", - "coins": [ - { - "denom": "stake", - "amount": "14613518005" - } - ] - }, - { - "address": "cosmos1y3h72de80x06cz7fs3adwlnp0r8pjazw0r5707", - "coins": [ - { - "denom": "stake", - "amount": "36598136941" - } - ] - }, - { - "address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", - "coins": [ - { - "denom": "stake", - "amount": "10603713098" - } - ] - }, - { - "address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", - "coins": [ - { - "denom": "stake", - "amount": "968687494" - } - ] - }, - { - "address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", - "coins": [ - { - "denom": "stake", - "amount": "19563719776" - } - ] - }, - { - "address": "cosmos1jp8nnep04hdcxckh0hg4knp4fu4zmzkycwwexl", - "coins": [ - { - "denom": "stake", - "amount": "4560932826" - } - ] - }, - { - "address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266", - "coins": [ - { - "denom": "stake", - "amount": "24996066132" - } - ] - }, - { - "address": "cosmos1tftatt0lp0v59qqf449pdqar8w3yj7n7xa7sk6", - "coins": [ - { - "denom": "stake", - "amount": "15102303619" - } - ] - }, - { - "address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "coins": [ - { - "denom": "stake", - "amount": "3457064927" - } - ] - }, - { - "address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", - "coins": [ - { - "denom": "stake", - "amount": "774827725" - } - ] - }, - { - "address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", - "coins": [ - { - "denom": "stake", - "amount": "151529598" - } - ] - }, - { - "address": "cosmos1cwl6ck677m959vqnjhyynnlpx4n3keh5ujzmm7", - "coins": [ - { - "denom": "stake", - "amount": "18040873849" - } - ] - }, - { - "address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", - "coins": [ - { - "denom": "stake", - "amount": "1502777217" - } - ] - }, - { - "address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", - "coins": [ - { - "denom": "stake", - "amount": "1978902837" - } - ] - }, - { - "address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "coins": [ - { - "denom": "stake", - "amount": "1199336" - } - ] - }, - { - "address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7", - "coins": [ - { - "denom": "stake", - "amount": "309209" - } - ] - }, - { - "address": "cosmos1v9frpsrct2tplfv0r2en28wh8le3f9chavr65w", - "coins": [ - { - "denom": "stake", - "amount": "6097231892" - } - ] - }, - { - "address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", - "coins": [ - { - "denom": "stake", - "amount": "37857485623" - } - ] - }, - { - "address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", - "coins": [ - { - "denom": "stake", - "amount": "10730741844" - } - ] - }, - { - "address": "cosmos1qdzgpyxu8cev4wjz9e567nfdlc2cru8ygy9gz7", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", - "coins": [ - { - "denom": "stake", - "amount": "2510139919" - } - ] - }, - { - "address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", - "coins": [ - { - "denom": "stake", - "amount": "6805326386" - } - ] - }, - { - "address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", - "coins": [ - { - "denom": "stake", - "amount": "294034819" - } - ] - }, - { - "address": "cosmos19ehwyhhnu55mw9d96929sus947zw6eee4ue38p", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos10g2yfqkuyaxgyyj7hhyswh8cmhplvpanrc9tya", - "coins": [ - { - "denom": "stake", - "amount": "24614990370" - } - ] - }, - { - "address": "cosmos1n5qqy42c6su9dv0tjpt3867mu7sdfhz6juqdns", - "coins": [ - { - "denom": "stake", - "amount": "24393251830" - } - ] - }, - { - "address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", - "coins": [ - { - "denom": "stake", - "amount": "801274747" - } - ] - }, - { - "address": "cosmos1556dzhyv2gth4huxdlyur65c2sm3np2en3zzhl", - "coins": [ - { - "denom": "stake", - "amount": "33380032930" - } - ] - }, - { - "address": "cosmos1xychruegs8u4cd4s3l7tkcc23ev90zydd4n92v", - "coins": [ - { - "denom": "stake", - "amount": "35623599941" - } - ] - }, - { - "address": "cosmos1vtqnkp3uat764qv4z02qwc7ysnre8q9ph5kklc", - "coins": [ - { - "denom": "stake", - "amount": "164155157" - } - ] - }, - { - "address": "cosmos13yzpngckxvtky2k25j60qxlkekx0jfau4pjhzn", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos130kk7kw4kx7rfrq9sa4k673zqt3nf6s4l3a0lg", - "coins": [ - { - "denom": "stake", - "amount": "6577769472" - } - ] - }, - { - "address": "cosmos1jsd99e3zfrxrr3nh057u0tvmu0847zkr29f28v", - "coins": [ - { - "denom": "stake", - "amount": "4311765981" - } - ] - }, - { - "address": "cosmos1uwx5cecec8v2af2mdrq3p6gv9gtv4gza5006gx", - "coins": [ - { - "denom": "stake", - "amount": "6919258491" - } - ] - }, - { - "address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a", - "coins": [ - { - "denom": "stake", - "amount": "3305932443" - } - ] - }, - { - "address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", - "coins": [ - { - "denom": "stake", - "amount": "1019468067" - } - ] - }, - { - "address": "cosmos1ax56w233q9c43whd6sdy52v2qhuc8lpjs7gks5", - "coins": [ - { - "denom": "stake", - "amount": "26966405541" - } - ] - }, - { - "address": "cosmos19stzlsklhmx4akvnq7s2jvl828hrt6zdm6dhys", - "coins": [ - { - "denom": "stake", - "amount": "27984308200" - } - ] - }, - { - "address": "cosmos1x4u73wvuayr5w5gfs96jak2nrs3k4r96tknr63", - "coins": [ - { - "denom": "stake", - "amount": "135998804" - } - ] - }, - { - "address": "cosmos1pmjfpv056kk3jk3qfljph9fthrvqtufxe3nwml", - "coins": [ - { - "denom": "stake", - "amount": "19107557733" - } - ] - }, - { - "address": "cosmos1280ce9aj6ezeduu5adlery5cjmd4fy7yfe4s35", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", - "coins": [ - { - "denom": "stake", - "amount": "3027665244" - } - ] - }, - { - "address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", - "coins": [ - { - "denom": "stake", - "amount": "24981208248" - } - ] - }, - { - "address": "cosmos1p9lzwaw02vs55dglhdr3dldmkwgm4km9shedwl", - "coins": [ - { - "denom": "stake", - "amount": "2968133111" - } - ] - }, - { - "address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", - "coins": [ - { - "denom": "stake", - "amount": "18603946" - } - ] - }, - { - "address": "cosmos1ndjmq7ee0g2lmxrx5q0npcmv64km6hysk0qnvn", - "coins": [ - { - "denom": "stake", - "amount": "55535446132" - } - ] - }, - { - "address": "cosmos16erf80gpn7xquce9qmk2uzf4lzdgcgc55ra2y3", - "coins": [ - { - "denom": "stake", - "amount": "5611558468" - } - ] - }, - { - "address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", - "coins": [ - { - "denom": "stake", - "amount": "141333776" - } - ] - }, - { - "address": "cosmos1g04020ghngvh7lj8hmhequs5a83ly7xxyh0q8w", - "coins": [ - { - "denom": "stake", - "amount": "921362709" - } - ] - }, - { - "address": "cosmos1gayzja3zz6unep8ftnpunt2wefazs3jhunl5az", - "coins": [ - { - "denom": "stake", - "amount": "48171207067" - } - ] - }, - { - "address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", - "coins": [ - { - "denom": "stake", - "amount": "2502916665" - } - ] - }, - { - "address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", - "coins": [ - { - "denom": "stake", - "amount": "2985774735" - } - ] - }, - { - "address": "cosmos13acm7994qxzmemx0fekg6s3qtagck36erqgsz8", - "coins": [ - { - "denom": "stake", - "amount": "1972532706" - } - ] - }, - { - "address": "cosmos1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0ajhqc7", - "coins": [ - { - "denom": "stake", - "amount": "6151241715" - } - ] - }, - { - "address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", - "coins": [ - { - "denom": "stake", - "amount": "18456403012" - } - ] - }, - { - "address": "cosmos1jakgqseuh502xcapt7ctxtwaz2w4xyh7kdqqw4", - "coins": [ - { - "denom": "stake", - "amount": "23637058873" - } - ] - }, - { - "address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", - "coins": [ - { - "denom": "stake", - "amount": "3841368367" - } - ] - }, - { - "address": "cosmos12eynrdzx2jqz5u92hgmhl9ga6hmghqfv0xvns8", - "coins": [ - { - "denom": "stake", - "amount": "16243090694" - } - ] - }, - { - "address": "cosmos1tzz5l8sw05e0tm5l0gxuvp04qt42stu3kqwf4s", - "coins": [ - { - "denom": "stake", - "amount": "13054348071" - } - ] - }, - { - "address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", - "coins": [ - { - "denom": "stake", - "amount": "5014095229" - } - ] - }, - { - "address": "cosmos1zah0g92ytwdvpchd3sceuanu7knhtu224vnt5k", - "coins": [ - { - "denom": "stake", - "amount": "51545993844" - } - ] - }, - { - "address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", - "coins": [ - { - "denom": "stake", - "amount": "5237961578" - } - ] - }, - { - "address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "coins": [ - { - "denom": "stake", - "amount": "44696513" - } - ] - }, - { - "address": "cosmos1q6eeennfulay5kz3lym38up6gq5ruf6h43cg94", - "coins": [ - { - "denom": "stake", - "amount": "4252349067" - } - ] - }, - { - "address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", - "coins": [ - { - "denom": "stake", - "amount": "7449763865" - } - ] - }, - { - "address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", - "coins": [ - { - "denom": "stake", - "amount": "14140469266" - } - ] - }, - { - "address": "cosmos1e87dgtw7cd28mt4mm3s4uaaxpapanexw9grzmg", - "coins": [ - { - "denom": "stake", - "amount": "18606905180" - } - ] - }, - { - "address": "cosmos1znvq8jqpwxt5hk2lg5654l7eg7kap3rpgjm462", - "coins": [ - { - "denom": "stake", - "amount": "17067668238" - } - ] - }, - { - "address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", - "coins": [ - { - "denom": "stake", - "amount": "1331425207" - } - ] - }, - { - "address": "cosmos14t66r5m6p8n9egwdxs45ljca5p4hra74vyz9j0", - "coins": [ - { - "denom": "stake", - "amount": "685719243" - } - ] - }, - { - "address": "cosmos174ycyhzg358nxm8r6qunzsyx48uk8fc404ckyf", - "coins": [ - { - "denom": "stake", - "amount": "1127546373" - } - ] - }, - { - "address": "cosmos1f09q88gqlava96kfz8xljgtj02rt4tmcpap5ya", - "coins": [ - { - "denom": "stake", - "amount": "25130539762" - } - ] - }, - { - "address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", - "coins": [ - { - "denom": "stake", - "amount": "10915226754" - } - ] - }, - { - "address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr", - "coins": [ - { - "denom": "stake", - "amount": "13311318969" - } - ] - }, - { - "address": "cosmos1kjupa2w6rlhzj9fjxz35m02g2wpz790fd6mf0j", - "coins": [ - { - "denom": "stake", - "amount": "2225633861" - } - ] - }, - { - "address": "cosmos1kum8rm8vqscd4zafpt39uhsdmcsdcxmrg7znxy", - "coins": [ - { - "denom": "stake", - "amount": "31768080506" - } - ] - }, - { - "address": "cosmos1wwp7j40k9xffj757s4uurkcegskfwq25ef268l", - "coins": [ - { - "denom": "stake", - "amount": "28727597" - } - ] - }, - { - "address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", - "coins": [ - { - "denom": "stake", - "amount": "13265228491" - } - ] - }, - { - "address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", - "coins": [ - { - "denom": "stake", - "amount": "1144205311" - } - ] - }, - { - "address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", - "coins": [ - { - "denom": "stake", - "amount": "3096486333" - } - ] - }, - { - "address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", - "coins": [ - { - "denom": "stake", - "amount": "592403678" - } - ] - }, - { - "address": "cosmos12zkyjh3kjyz2ka0z7lskxqxhvtmgg2pzg8gn96", - "coins": [ - { - "denom": "stake", - "amount": "38168134584" - } - ] - }, - { - "address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", - "coins": [ - { - "denom": "stake", - "amount": "8685542905" - } - ] - }, - { - "address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", - "coins": [ - { - "denom": "stake", - "amount": "614858577" - } - ] - }, - { - "address": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", - "coins": [ - { - "denom": "stake", - "amount": "24713958645" - } - ] - }, - { - "address": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh", - "coins": [ - { - "denom": "stake", - "amount": "7451760474987" - } - ] - }, - { - "address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", - "coins": [ - { - "denom": "stake", - "amount": "25075256975" - } - ] - }, - { - "address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", - "coins": [ - { - "denom": "stake", - "amount": "4709844" - } - ] - }, - { - "address": "cosmos1g95xvy8qgzcvcl05fse0mpxzdfv3w88tpexycr", - "coins": [ - { - "denom": "stake", - "amount": "46109502274" - } - ] - }, - { - "address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "coins": [ - { - "denom": "stake", - "amount": "126603894" - } - ] - }, - { - "address": "cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl", - "coins": [ - { - "denom": "stake", - "amount": "10636092320837" - } - ] - }, - { - "address": "cosmos1hwt3fl2gylwdechqwq8uhmhsl04gn6ksw6lxlt", - "coins": [ - { - "denom": "stake", - "amount": "27595896946" - } - ] - }, - { - "address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", - "coins": [ - { - "denom": "stake", - "amount": "434029796" - } - ] - }, - { - "address": "cosmos1r35ejcqcmv94r87zwrx4xngsutjppj3yx280jm", - "coins": [ - { - "denom": "stake", - "amount": "23876053127" - } - ] - }, - { - "address": "cosmos1yj95f65syc75ptwcy0n7kafdq33awc2ve8hthq", - "coins": [ - { - "denom": "stake", - "amount": "197534165" - } - ] - }, - { - "address": "cosmos17eadsw26t8798nfaw2uq6rnmfw6tn3u7np2yfs", - "coins": [ - { - "denom": "stake", - "amount": "649055481" - } - ] - }, - { - "address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", - "coins": [ - { - "denom": "stake", - "amount": "30018322160" - } - ] - }, - { - "address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", - "coins": [ - { - "denom": "stake", - "amount": "85922675" - } - ] - }, - { - "address": "cosmos1h84c3yuxd6k7950wh868tcsj5tmvzetykv8lld", - "coins": [ - { - "denom": "stake", - "amount": "1925488935" - } - ] - }, - { - "address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", - "coins": [ - { - "denom": "stake", - "amount": "25275217992" - } - ] - }, - { - "address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", - "coins": [ - { - "denom": "stake", - "amount": "3938913881" - } - ] - }, - { - "address": "cosmos1af6mnuvcs8ypz2272x4vhdw9dkc25ac87z04l8", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "coins": [ - { - "denom": "stake", - "amount": "3517756820" - } - ] - }, - { - "address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", - "coins": [ - { - "denom": "stake", - "amount": "9081001" - } - ] - }, - { - "address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "coins": [ - { - "denom": "stake", - "amount": "1266537330" - } - ] - }, - { - "address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", - "coins": [ - { - "denom": "stake", - "amount": "54644876" - } - ] - }, - { - "address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "coins": [ - { - "denom": "stake", - "amount": "1470032177" - } - ] - }, - { - "address": "cosmos12362v43p57f8dgc2dx396rpanj24j67pkcvy2h", - "coins": [ - { - "denom": "stake", - "amount": "2349145013" - } - ] - }, - { - "address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", - "coins": [ - { - "denom": "stake", - "amount": "1412129641" - } - ] - }, - { - "address": "cosmos1jsgcz2u9tgrn3j49t2xg4er3hjhnryzr6w9dqs", - "coins": [ - { - "denom": "stake", - "amount": "3557165086" - } - ] - }, - { - "address": "cosmos1rhc7hrsjmzlqfz4n400j53ztytqafe9qqqq38l", - "coins": [ - { - "denom": "stake", - "amount": "2886829405" - } - ] - }, - { - "address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", - "coins": [ - { - "denom": "stake", - "amount": "26635567" - } - ] - }, - { - "address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "coins": [ - { - "denom": "stake", - "amount": "1609436526" - } - ] - }, - { - "address": "cosmos1vwja3gc3e37f8fkddj38gp74cs7sccnf4zs509", - "coins": [ - { - "denom": "stake", - "amount": "17423311338" - } - ] - }, - { - "address": "cosmos1kl0sk9crf0ru82ejpk8a7zexp2kudszsug5u8z", - "coins": [ - { - "denom": "stake", - "amount": "1822019848" - } - ] - }, - { - "address": "cosmos1uptqu7jt4krnqwlx98nlxs5fg2a0fncvpyhptj", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", - "coins": [ - { - "denom": "stake", - "amount": "7245367" - } - ] - }, - { - "address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "coins": [ - { - "denom": "stake", - "amount": "728194424" - } - ] - }, - { - "address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", - "coins": [ - { - "denom": "stake", - "amount": "9493124191" - } - ] - }, - { - "address": "cosmos135e4v2rg4uz2767zhtdksls7n0s5eleunwdxyx", - "coins": [ - { - "denom": "stake", - "amount": "31122584481" - } - ] - }, - { - "address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", - "coins": [ - { - "denom": "stake", - "amount": "591338" - } - ] - }, - { - "address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", - "coins": [ - { - "denom": "stake", - "amount": "5430059367" - } - ] - }, - { - "address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", - "coins": [ - { - "denom": "stake", - "amount": "24315459129" - } - ] - }, - { - "address": "cosmos1f7wpuyc6ehg8p8rxag43j8fyfaur3jy0ujhs2t", - "coins": [ - { - "denom": "stake", - "amount": "17632090654" - } - ] - }, - { - "address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", - "coins": [ - { - "denom": "stake", - "amount": "18518242703" - } - ] - }, - { - "address": "cosmos1ledlljk33qdj6z6lssp3w88cq2q38kg0j4vrvc", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1n0f0kcjjwrjqvva5wq6x5nj0c45vddc2rr29k3", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1haw8fcay84fjlsdl5cyev275ldj30z3r27m0g5", - "coins": [ - { - "denom": "stake", - "amount": "3067646060" - } - ] - }, - { - "address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn", - "coins": [ - { - "denom": "stake", - "amount": "3328430106" - } - ] - }, - { - "address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", - "coins": [ - { - "denom": "stake", - "amount": "85023275" - } - ] - }, - { - "address": "cosmos1tcaxfulvlrwt9ua2f4hrfpx6wvymwxksnurv3m", - "coins": [ - { - "denom": "stake", - "amount": "948265452" - } - ] - }, - { - "address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", - "coins": [ - { - "denom": "stake", - "amount": "45493045207" - } - ] - }, - { - "address": "cosmos1250k2ymtkl6hf0ty6syhkxft33v580fhmr25qc", - "coins": [ - { - "denom": "stake", - "amount": "1303498572" - } - ] - }, - { - "address": "cosmos1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxx7jqef", - "coins": [ - { - "denom": "stake", - "amount": "25308053792" - } - ] - }, - { - "address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", - "coins": [ - { - "denom": "stake", - "amount": "68519453" - } - ] - }, - { - "address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "coins": [ - { - "denom": "stake", - "amount": "155891306" - } - ] - }, - { - "address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", - "coins": [ - { - "denom": "stake", - "amount": "1736204" - } - ] - }, - { - "address": "cosmos1zyz0twnwwk26pwn3w83d2lj7rda7lfr5d0m64v", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1d0dq8hxzyywrcx73v4z44e8p8685znzml58dg2", - "coins": [ - { - "denom": "stake", - "amount": "1979969851" - } - ] - }, - { - "address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "coins": [ - { - "denom": "stake", - "amount": "7975333120" - } - ] - }, - { - "address": "cosmos15uqsf4wke3ylyp0elnka2rvaefhsmhgjhe5mxf", - "coins": [ - { - "denom": "stake", - "amount": "15786431671" - } - ] - }, - { - "address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "coins": [ - { - "denom": "stake", - "amount": "10654006660" - } - ] - }, - { - "address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", - "coins": [ - { - "denom": "stake", - "amount": "1221309903" - } - ] - }, - { - "address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", - "coins": [ - { - "denom": "stake", - "amount": "17104878021" - } - ] - }, - { - "address": "cosmos1zzca9hed282xcq9s7v69ysyyjls42ppxp37ywc", - "coins": [ - { - "denom": "stake", - "amount": "2490547529" - } - ] - }, - { - "address": "cosmos1xenmhldpnwfl0x8ze8qvu2qc4v58zr7qkz73sz", - "coins": [ - { - "denom": "stake", - "amount": "794583091" - } - ] - }, - { - "address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "coins": [ - { - "denom": "stake", - "amount": "16367605958" - } - ] - }, - { - "address": "cosmos1hksxwc7h56mzm9evkpyg9hevlj94g5v003rs9w", - "coins": [ - { - "denom": "stake", - "amount": "6770746100" - } - ] - }, - { - "address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "coins": [ - { - "denom": "stake", - "amount": "92751494" - } - ] - }, - { - "address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", - "coins": [ - { - "denom": "stake", - "amount": "1675071889" - } - ] - }, - { - "address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", - "coins": [ - { - "denom": "stake", - "amount": "3730204294" - } - ] - }, - { - "address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", - "coins": [ - { - "denom": "stake", - "amount": "1773197688" - } - ] - }, - { - "address": "cosmos1m6y73jlmfnl8ywzrjggruy4nfk8hkgnwve5t8x", - "coins": [ - { - "denom": "stake", - "amount": "5538425359" - } - ] - }, - { - "address": "cosmos1nutj5al03vv5r46uawslcg4mq696v2m48allaa", - "coins": [ - { - "denom": "stake", - "amount": "10803626345" - } - ] - }, - { - "address": "cosmos1kjkf4umv6g2pperq6g74mayntlrp4a7xypuvmr", - "coins": [ - { - "denom": "stake", - "amount": "229593456" - } - ] - }, - { - "address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", - "coins": [ - { - "denom": "stake", - "amount": "8095698562" - } - ] - }, - { - "address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", - "coins": [ - { - "denom": "stake", - "amount": "6589141209" - } - ] - }, - { - "address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "coins": [ - { - "denom": "stake", - "amount": "2853577310" - } - ] - }, - { - "address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", - "coins": [ - { - "denom": "stake", - "amount": "2594299625" - } - ] - }, - { - "address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", - "coins": [ - { - "denom": "stake", - "amount": "3403723991" - } - ] - }, - { - "address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", - "coins": [ - { - "denom": "stake", - "amount": "20948480766" - } - ] - }, - { - "address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "coins": [ - { - "denom": "stake", - "amount": "4833291035" - } - ] - }, - { - "address": "cosmos1rz3n04g9vg0ygh3h2x96wh5ceq44pcjmt3lgag", - "coins": [ - { - "denom": "stake", - "amount": "25180408482" - } - ] - }, - { - "address": "cosmos1d4jyeaslp5p85mmkxqsem6g99l67nqa6uym3c4", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", - "coins": [ - { - "denom": "stake", - "amount": "15294504306" - } - ] - }, - { - "address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", - "coins": [ - { - "denom": "stake", - "amount": "394439386" - } - ] - }, - { - "address": "cosmos13nemj0k45u4pflkfeyey88n8u8sv4wgz8cf253", - "coins": [ - { - "denom": "stake", - "amount": "55593808380" - } - ] - }, - { - "address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", - "coins": [ - { - "denom": "stake", - "amount": "79121" - } - ] - }, - { - "address": "cosmos1stvzt8re3hz8dme2gscrjxzyx9hcefvhjtvuzh", - "coins": [ - { - "denom": "stake", - "amount": "7414001605" - } - ] - }, - { - "address": "cosmos1ff2vzyfjcwwgk07cqv7hgkpvj0yazgcpez9jg5", - "coins": [ - { - "denom": "stake", - "amount": "26431515484" - } - ] - }, - { - "address": "cosmos124wz6pnykadgf3xchp6rdn9s2t9z5sgvl7597p", - "coins": [ - { - "denom": "stake", - "amount": "15591641617" - } - ] - }, - { - "address": "cosmos14j4mehgc448s2m7cr0uqm3pmvjxav94wmq80w4", - "coins": [ - { - "denom": "stake", - "amount": "1629559245" - } - ] - }, - { - "address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", - "coins": [ - { - "denom": "stake", - "amount": "12272463788" - } - ] - }, - { - "address": "cosmos12f4fpl936ld8c64dxqgwv65p42na8dcnv9g7ku", - "coins": [ - { - "denom": "stake", - "amount": "28991496953" - } - ] - }, - { - "address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", - "coins": [ - { - "denom": "stake", - "amount": "7271239015" - } - ] - }, - { - "address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c", - "coins": [ - { - "denom": "stake", - "amount": "9869349475" - } - ] - }, - { - "address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", - "coins": [ - { - "denom": "stake", - "amount": "370" - } - ] - }, - { - "address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "coins": [ - { - "denom": "stake", - "amount": "7448503007" - } - ] - }, - { - "address": "cosmos1nkywcdu694al4mm44np7uy08jujqvwjzarzs3n", - "coins": [ - { - "denom": "stake", - "amount": "11536917655" - } - ] - }, - { - "address": "cosmos17tecr2sngjcm2rc29dzmadtpad2tkmrhj69whr", - "coins": [ - { - "denom": "stake", - "amount": "5366299050" - } - ] - }, - { - "address": "cosmos198k0ah8pnjzthydgvnq30s24s8jd3wad6puc3q", - "coins": [ - { - "denom": "stake", - "amount": "5536109065" - } - ] - }, - { - "address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", - "coins": [ - { - "denom": "stake", - "amount": "150090308" - } - ] - }, - { - "address": "cosmos1k22576dxnqasv25wy542wc3sgj30gm4gmdpec2", - "coins": [ - { - "denom": "stake", - "amount": "17915441405" - } - ] - }, - { - "address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", - "coins": [ - { - "denom": "stake", - "amount": "681490802" - } - ] - }, - { - "address": "cosmos1p5h9hzhyeske3uwhsf6k5nq38r5pxrejpjw49v", - "coins": [ - { - "denom": "stake", - "amount": "28113011166" - } - ] - }, - { - "address": "cosmos1ywe4qsw399leu3wza5jpny3mmrs69a3gj3hlt8", - "coins": [ - { - "denom": "stake", - "amount": "16634177555" - } - ] - }, - { - "address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", - "coins": [ - { - "denom": "stake", - "amount": "13191407681" - } - ] - }, - { - "address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", - "coins": [ - { - "denom": "stake", - "amount": "13599933677" - } - ] - }, - { - "address": "cosmos102sgufwszag3yuhtzcftpyvc8jqtqske4xug7d", - "coins": [ - { - "denom": "stake", - "amount": "5298673511" - } - ] - }, - { - "address": "cosmos1a5fndlfnwtvyzzt7ql4kvuqgnjut7ua7hkfts6", - "coins": [ - { - "denom": "stake", - "amount": "12053420060" - } - ] - }, - { - "address": "cosmos1q9ed2n5wvzcrymaqltypazqzd2xv8d5aw58flt", - "coins": [ - { - "denom": "stake", - "amount": "4003120376" - } - ] - }, - { - "address": "cosmos1munf3xa25sdu0sdxwyqxhz88c8l90llmjsslvj", - "coins": [ - { - "denom": "stake", - "amount": "13387440139" - } - ] - }, - { - "address": "cosmos136jetl40d2fmx3w0a0t2jj7zyp72g850c9j4ez", - "coins": [ - { - "denom": "stake", - "amount": "182142116" - } - ] - }, - { - "address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg", - "coins": [ - { - "denom": "stake", - "amount": "10737984139" - } - ] - }, - { - "address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", - "coins": [ - { - "denom": "stake", - "amount": "1232108619" - } - ] - }, - { - "address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", - "coins": [ - { - "denom": "stake", - "amount": "7486384395" - } - ] - }, - { - "address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", - "coins": [ - { - "denom": "stake", - "amount": "88345652" - } - ] - }, - { - "address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", - "coins": [ - { - "denom": "stake", - "amount": "41321494" - } - ] - }, - { - "address": "cosmos1zyu5csqfxaxacgwegnhrysl0val4t48kfhj9ws", - "coins": [ - { - "denom": "stake", - "amount": "971257721" - } - ] - }, - { - "address": "cosmos1r764cqpxtae8ed0zyy0v6sxut9dm4fuqj95xgc", - "coins": [ - { - "denom": "stake", - "amount": "14835822719" - } - ] - }, - { - "address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "coins": [ - { - "denom": "stake", - "amount": "848646209" - } - ] - }, - { - "address": "cosmos1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6x000jc", - "coins": [ - { - "denom": "stake", - "amount": "16170647207" - } - ] - }, - { - "address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", - "coins": [ - { - "denom": "stake", - "amount": "3630360827" - } - ] - }, - { - "address": "cosmos1lmkyqhjshfd4mqsgk5stvaxlsxkmdmfhfwh7p2", - "coins": [ - { - "denom": "stake", - "amount": "12681039476" - } - ] - }, - { - "address": "cosmos1rpmw7y7cw2cu3kwsryy8z8uskn4eymh89hmq5g", - "coins": [ - { - "denom": "stake", - "amount": "4485725908" - } - ] - }, - { - "address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", - "coins": [ - { - "denom": "stake", - "amount": "14062569321" - } - ] - }, - { - "address": "cosmos1y8jqa6t7g9m9g2l5u7m7lvm36pj4ssqyas8vdh", - "coins": [ - { - "denom": "stake", - "amount": "6797423203" - } - ] - }, - { - "address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", - "coins": [ - { - "denom": "stake", - "amount": "8568857891" - } - ] - }, - { - "address": "cosmos1t58fj97xgxsvsyn89lc75hd0naa6v6c0c340cv", - "coins": [ - { - "denom": "stake", - "amount": "3231818184" - } - ] - }, - { - "address": "cosmos13xm9km2se2am890j398ttvyjhuh8zndwr2p68d", - "coins": [ - { - "denom": "stake", - "amount": "8208101815" - } - ] - }, - { - "address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", - "coins": [ - { - "denom": "stake", - "amount": "6595044565" - } - ] - }, - { - "address": "cosmos1qenyuc4ljgvkp7g2jhg274k2uzcgdc4vdzfr7z", - "coins": [ - { - "denom": "stake", - "amount": "5254392390" - } - ] - }, - { - "address": "cosmos1ryp2xkqe74y5kx6zffqtdc3wzgny8xg8eguupq", - "coins": [ - { - "denom": "stake", - "amount": "516333564" - } - ] - }, - { - "address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", - "coins": [ - { - "denom": "stake", - "amount": "20464645098" - } - ] - }, - { - "address": "cosmos10gu52rf3d0z0py8d0x37r058qh9fgdgg5567wd", - "coins": [ - { - "denom": "stake", - "amount": "2833226888" - } - ] - }, - { - "address": "cosmos1hn79l8dj3u5llk78cjhsxcvlaz0jh966x4ez7z", - "coins": [ - { - "denom": "stake", - "amount": "34506948109" - } - ] - }, - { - "address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", - "coins": [ - { - "denom": "stake", - "amount": "1249698679" - } - ] - }, - { - "address": "cosmos1l6u5cg3wcptmcjyhxtfrrfq3nu036acdauf0fy", - "coins": [ - { - "denom": "stake", - "amount": "3254718618" - } - ] - }, - { - "address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "coins": [ - { - "denom": "stake", - "amount": "18672231661" - } - ] - }, - { - "address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", - "coins": [ - { - "denom": "stake", - "amount": "225708825" - } - ] - }, - { - "address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "coins": [ - { - "denom": "stake", - "amount": "8552716438" - } - ] - }, - { - "address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq", - "coins": [ - { - "denom": "stake", - "amount": "33376497661" - } - ] - }, - { - "address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6", - "coins": [ - { - "denom": "stake", - "amount": "9040963504" - } - ] - }, - { - "address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "coins": [ - { - "denom": "stake", - "amount": "29610448" - } - ] - }, - { - "address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "coins": [ - { - "denom": "stake", - "amount": "9631517107" - } - ] - }, - { - "address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", - "coins": [ - { - "denom": "stake", - "amount": "812862827" - } - ] - }, - { - "address": "cosmos17ql89l8ghyguux4u4jghja9hmw9vjkwpkle699", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1pca5ng2s37clfh72ea806j9fwvpng4fjq3ey5s", - "coins": [ - { - "denom": "stake", - "amount": "462060951" - } - ] - }, - { - "address": "cosmos1m5aynwlefn0dn8pk5d6j705zh29qstsp4dh02h", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1rzynfn4000ww456my9ke4jf72q306sp4w8qs3m", - "coins": [ - { - "denom": "stake", - "amount": "25199750140" - } - ] - }, - { - "address": "cosmos1kv74z5g0s02jv72npe59l4qkn45q7r46xwx6nv", - "coins": [ - { - "denom": "stake", - "amount": "9192004145" - } - ] - }, - { - "address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2", - "coins": [ - { - "denom": "stake", - "amount": "7359783957" - } - ] - }, - { - "address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", - "coins": [ - { - "denom": "stake", - "amount": "16644100113" - } - ] - }, - { - "address": "cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q", - "coins": [] - }, - { - "address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", - "coins": [ - { - "denom": "stake", - "amount": "3448640286" - } - ] - }, - { - "address": "cosmos1sc26mz3pwry0wm9yynh6w02ypx6k6ckpsjgjr2", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", - "coins": [ - { - "denom": "stake", - "amount": "8465916096" - } - ] - }, - { - "address": "cosmos1glku8mx4nzp5crkjt7px9lfe4flfge3zf64tud", - "coins": [ - { - "denom": "stake", - "amount": "47692972630" - } - ] - }, - { - "address": "cosmos1tgghhdcxdgxay7hp2p0lv2fs656c4c0xfzlga5", - "coins": [ - { - "denom": "stake", - "amount": "6283589634" - } - ] - }, - { - "address": "cosmos1qqexr0y3fxueg3v366ctzlqctexhj5mplmznm4", - "coins": [ - { - "denom": "stake", - "amount": "33742441586" - } - ] - }, - { - "address": "cosmos19szahkq3g937j62shd224cdtla3dv8rcwvekj9", - "coins": [ - { - "denom": "stake", - "amount": "6271564202" - } - ] - }, - { - "address": "cosmos1vpensuylw0rg7f6pnx7qm0acs3tmqgv485faen", - "coins": [ - { - "denom": "stake", - "amount": "22432301261" - } - ] - }, - { - "address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", - "coins": [ - { - "denom": "stake", - "amount": "4644281" - } - ] - }, - { - "address": "cosmos18h7dxvzs4vn07gfgwxgjsvl7f2nhn4fspaggvf", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos197wzfp3g9xq92szucsjce5qfd2p4nrl5cj8lz8", - "coins": [ - { - "denom": "stake", - "amount": "9063405069" - } - ] - }, - { - "address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", - "coins": [ - { - "denom": "stake", - "amount": "5907237303" - } - ] - }, - { - "address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", - "coins": [ - { - "denom": "stake", - "amount": "96530865" - } - ] - }, - { - "address": "cosmos125334yspnrcgu7es23745xr4wtmrzyh8m8vmj0", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", - "coins": [ - { - "denom": "stake", - "amount": "2105628153" - } - ] - }, - { - "address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", - "coins": [ - { - "denom": "stake", - "amount": "11169892212" - } - ] - }, - { - "address": "cosmos1rlltvm5ks32kh683c0w7epsjvg8aq2hvct27p6", - "coins": [ - { - "denom": "stake", - "amount": "63294296" - } - ] - }, - { - "address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm", - "coins": [ - { - "denom": "stake", - "amount": "8495793279" - } - ] - }, - { - "address": "cosmos1wtn9tf6wjwmwmddrk377cdl8fd96hexajyhfat", - "coins": [ - { - "denom": "stake", - "amount": "10771731" - } - ] - }, - { - "address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc", - "coins": [ - { - "denom": "stake", - "amount": "2931060613" - } - ] - }, - { - "address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", - "coins": [ - { - "denom": "stake", - "amount": "36665555599" - } - ] - }, - { - "address": "cosmos1r7kh63jvjhwqraux9wtm3jat8ggm437w9cxcxc", - "coins": [ - { - "denom": "stake", - "amount": "6815707766" - } - ] - }, - { - "address": "cosmos17lfwqsp85symf9ftal8wdsmvavla0we4h9kkxy", - "coins": [ - { - "denom": "stake", - "amount": "13042973798" - } - ] - }, - { - "address": "cosmos19num42c3egx8a4calkn0pz9qxaay7svyyh8vfz", - "coins": [ - { - "denom": "stake", - "amount": "662725780" - } - ] - }, - { - "address": "cosmos1wgslx9j6ct5pczy3h5rjl98yyn78r3sel0ulth", - "coins": [ - { - "denom": "stake", - "amount": "1237715217" - } - ] - }, - { - "address": "cosmos14fh7r7lj6928pd5tyqhfc62l5xnw7rq2zpnulw", - "coins": [ - { - "denom": "stake", - "amount": "27108948901" - } - ] - }, - { - "address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", - "coins": [ - { - "denom": "stake", - "amount": "17420725888" - } - ] - }, - { - "address": "cosmos1wykcmn3r389hklplushrjl43cz76djt44yuc2d", - "coins": [ - { - "denom": "stake", - "amount": "18636985230" - } - ] - }, - { - "address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", - "coins": [ - { - "denom": "stake", - "amount": "237102290" - } - ] - }, - { - "address": "cosmos1md3expnuxrws0qg9dpqxh5stns8ugvd6uh0jrk", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1e6ffgexkzs2lke6dywcju2ltqcjej2e7y4q8e2", - "coins": [ - { - "denom": "stake", - "amount": "792649886" - } - ] - }, - { - "address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", - "coins": [ - { - "denom": "stake", - "amount": "3322853752" - } - ] - }, - { - "address": "cosmos178pm30fcgrt5654czwr8nlex050m6y609glx2s", - "coins": [ - { - "denom": "stake", - "amount": "213988970" - } - ] - }, - { - "address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "coins": [ - { - "denom": "stake", - "amount": "515025318" - } - ] - }, - { - "address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", - "coins": [ - { - "denom": "stake", - "amount": "561951501" - } - ] - }, - { - "address": "cosmos10x0lg2djw0uq8qp5hgzujsu34zpreavnhmv0sc", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", - "coins": [ - { - "denom": "stake", - "amount": "15375542271" - } - ] - }, - { - "address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", - "coins": [ - { - "denom": "stake", - "amount": "8691964576" - } - ] - }, - { - "address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", - "coins": [ - { - "denom": "stake", - "amount": "192612999" - } - ] - }, - { - "address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", - "coins": [ - { - "denom": "stake", - "amount": "23474857664" - } - ] - }, - { - "address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", - "coins": [ - { - "denom": "stake", - "amount": "28262326641" - } - ] - }, - { - "address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", - "coins": [ - { - "denom": "stake", - "amount": "34906677" - } - ] - }, - { - "address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "coins": [ - { - "denom": "stake", - "amount": "265307837" - } - ] - }, - { - "address": "cosmos1m4xvwvq7qrr0wy0ryeu24eu8482h4n7en2x2mh", - "coins": [ - { - "denom": "stake", - "amount": "4296307974" - } - ] - }, - { - "address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "coins": [ - { - "denom": "stake", - "amount": "228374825" - } - ] - }, - { - "address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", - "coins": [ - { - "denom": "stake", - "amount": "9657246504" - } - ] - }, - { - "address": "cosmos18fp6y4z2ze4tdqn5ghl70erq5wpe444p548y5l", - "coins": [ - { - "denom": "stake", - "amount": "7168948159" - } - ] - }, - { - "address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", - "coins": [ - { - "denom": "stake", - "amount": "25197221" - } - ] - }, - { - "address": "cosmos13y6fzxm4933kag94elyy4jgfyhgf3jhwakccun", - "coins": [ - { - "denom": "stake", - "amount": "324111135" - } - ] - }, - { - "address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", - "coins": [ - { - "denom": "stake", - "amount": "4652492905" - } - ] - }, - { - "address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", - "coins": [ - { - "denom": "stake", - "amount": "19933266292" - } - ] - }, - { - "address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", - "coins": [ - { - "denom": "stake", - "amount": "9882840105" - } - ] - }, - { - "address": "cosmos1590defm6q73eu39x8ndt9vwmv5fhvp9q4vf96f", - "coins": [ - { - "denom": "stake", - "amount": "964692708" - } - ] - }, - { - "address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429", - "coins": [ - { - "denom": "stake", - "amount": "8500099030" - } - ] - }, - { - "address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", - "coins": [ - { - "denom": "stake", - "amount": "4266943360" - } - ] - }, - { - "address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", - "coins": [ - { - "denom": "stake", - "amount": "17851397628" - } - ] - }, - { - "address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", - "coins": [ - { - "denom": "stake", - "amount": "11055928327" - } - ] - }, - { - "address": "cosmos1w0j4ecghl96s9xayk967z4hnrxlsfht7rawmrc", - "coins": [ - { - "denom": "stake", - "amount": "15818247483" - } - ] - }, - { - "address": "cosmos1369zs5htywxarh8cl6rvmzgatfql00pmvmewet", - "coins": [ - { - "denom": "stake", - "amount": "25280930960" - } - ] - }, - { - "address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", - "coins": [ - { - "denom": "stake", - "amount": "34255416497" - } - ] - }, - { - "address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", - "coins": [ - { - "denom": "stake", - "amount": "4052051" - } - ] - }, - { - "address": "cosmos10ed8tmu5n2xfhtcyht4kahkmzqaxk2u7ks7k9u", - "coins": [ - { - "denom": "stake", - "amount": "14232287154" - } - ] - }, - { - "address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", - "coins": [ - { - "denom": "stake", - "amount": "12906327178" - } - ] - }, - { - "address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "coins": [ - { - "denom": "stake", - "amount": "4940558291" - } - ] - }, - { - "address": "cosmos1z2ynmntxdesahja6gh76cunudwfmrhgcx7krhv", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", - "coins": [ - { - "denom": "stake", - "amount": "4424189878" - } - ] - }, - { - "address": "cosmos13jfnddzl23pkks9f7ahgjeqaz4pyfx43mluaa4", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos16p082pp2g44jm5sa7x8egm2089gw908s85szsm", - "coins": [ - { - "denom": "stake", - "amount": "4101717090" - } - ] - }, - { - "address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "coins": [ - { - "denom": "stake", - "amount": "7253227770" - } - ] - }, - { - "address": "cosmos1renmf3hfgfq3p7wzenfa45alrhtc92f9geghu7", - "coins": [ - { - "denom": "stake", - "amount": "7148036106" - } - ] - }, - { - "address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", - "coins": [ - { - "denom": "stake", - "amount": "166991994" - } - ] - }, - { - "address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", - "coins": [ - { - "denom": "stake", - "amount": "2064809084" - } - ] - }, - { - "address": "cosmos1kxl7gsad663he7lgn66wx6gr3egnfj85dt22pv", - "coins": [ - { - "denom": "stake", - "amount": "17645582456" - } - ] - }, - { - "address": "cosmos17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnk5g0lz", - "coins": [ - { - "denom": "stake", - "amount": "153929962" - } - ] - }, - { - "address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", - "coins": [ - { - "denom": "stake", - "amount": "22599640159" - } - ] - }, - { - "address": "cosmos18fxku8d7wa5vjz9ta2xr7asvdfdrqnpdjfqpe5", - "coins": [ - { - "denom": "stake", - "amount": "13627909428" - } - ] - }, - { - "address": "cosmos1vnceu3qp3cw2qjq3jqmvfgwgv50y4yze7fe22y", - "coins": [ - { - "denom": "stake", - "amount": "870242442" - } - ] - }, - { - "address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", - "coins": [ - { - "denom": "stake", - "amount": "382052780" - } - ] - }, - { - "address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", - "coins": [ - { - "denom": "stake", - "amount": "24658850363" - } - ] - }, - { - "address": "cosmos1l577787urj3qccxypxaznnasxvnn9k8wq5lxf8", - "coins": [ - { - "denom": "stake", - "amount": "71769507" - } - ] - }, - { - "address": "cosmos1p7sc667drjvsjlha0nwz5zxxpt38m9dn50u925", - "coins": [ - { - "denom": "stake", - "amount": "34424110416" - } - ] - }, - { - "address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", - "coins": [ - { - "denom": "stake", - "amount": "56072875965" - } - ] - }, - { - "address": "cosmos1ft0e05t5rl8ycw6a0nfa6jswvckycan4lfmv0q", - "coins": [ - { - "denom": "stake", - "amount": "12443470626" - } - ] - }, - { - "address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", - "coins": [ - { - "denom": "stake", - "amount": "1958035374" - } - ] - }, - { - "address": "cosmos1qqxeqqvjkh2ls3a0taukd8rydrqqad690nxkcc", - "coins": [ - { - "denom": "stake", - "amount": "15287559843" - } - ] - }, - { - "address": "cosmos19akemnyuu0rgf2y0rrd6wrxpkyd74q5gzkgm5q", - "coins": [ - { - "denom": "stake", - "amount": "13924416768" - } - ] - }, - { - "address": "cosmos15pl2c2umxszwar75aft99kns0ltmpepnnpt9y0", - "coins": [ - { - "denom": "stake", - "amount": "22979868888" - } - ] - }, - { - "address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", - "coins": [ - { - "denom": "stake", - "amount": "115546197" - } - ] - }, - { - "address": "cosmos1p0sp7r6mzt05772xq9eqg47rvssgxhf4ktctah", - "coins": [ - { - "denom": "stake", - "amount": "28075176573" - } - ] - }, - { - "address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", - "coins": [ - { - "denom": "stake", - "amount": "16683212256" - } - ] - }, - { - "address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", - "coins": [ - { - "denom": "stake", - "amount": "138266" - } - ] - }, - { - "address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", - "coins": [ - { - "denom": "stake", - "amount": "33376038" - } - ] - }, - { - "address": "cosmos1urnp7yp6u27nut8kvsrapgmmvk8sh6u5wd5dez", - "coins": [ - { - "denom": "stake", - "amount": "4340887167" - } - ] - }, - { - "address": "cosmos1d9cqjx7xh2j23utvyrns2kgtz4w8e694vqw6h6", - "coins": [ - { - "denom": "stake", - "amount": "597776153" - } - ] - }, - { - "address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", - "coins": [ - { - "denom": "stake", - "amount": "42986521" - } - ] - }, - { - "address": "cosmos1ffaxjdp4v8w7kzgjsnf6nf4fvvndhrk6s9syf6", - "coins": [ - { - "denom": "stake", - "amount": "14187770842" - } - ] - }, - { - "address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", - "coins": [ - { - "denom": "stake", - "amount": "340556632" - } - ] - }, - { - "address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", - "coins": [ - { - "denom": "stake", - "amount": "10440851460" - } - ] - }, - { - "address": "cosmos1rcru2vteas2kunww3zt4knx28krlestxydpwza", - "coins": [ - { - "denom": "stake", - "amount": "740320221" - } - ] - }, - { - "address": "cosmos1xxurm2uymwd04sjxqedjae5r0zxhalh26skxct", - "coins": [ - { - "denom": "stake", - "amount": "14639003842" - } - ] - }, - { - "address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", - "coins": [ - { - "denom": "stake", - "amount": "23850785852" - } - ] - }, - { - "address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", - "coins": [ - { - "denom": "stake", - "amount": "3063847202" - } - ] - }, - { - "address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6", - "coins": [ - { - "denom": "stake", - "amount": "228712404" - } - ] - }, - { - "address": "cosmos18ku7lzv6a0d3t63d2tsn2x69u04uv3g8sgf8kq", - "coins": [ - { - "denom": "stake", - "amount": "25069342080" - } - ] - }, - { - "address": "cosmos1vlvxlpzzrk5eye9c3z9uedk0085h7fdvehv32n", - "coins": [ - { - "denom": "stake", - "amount": "1514324156" - } - ] - }, - { - "address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", - "coins": [ - { - "denom": "stake", - "amount": "32478838379" - } - ] - }, - { - "address": "cosmos15mxavsffqqj7enxpy7e3ayywd4jn4hz6ncjfft", - "coins": [ - { - "denom": "stake", - "amount": "5472724450" - } - ] - }, - { - "address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "coins": [ - { - "denom": "stake", - "amount": "596954561" - } - ] - }, - { - "address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n", - "coins": [ - { - "denom": "stake", - "amount": "2581136884" - } - ] - }, - { - "address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", - "coins": [ - { - "denom": "stake", - "amount": "10309758615" - } - ] - }, - { - "address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", - "coins": [ - { - "denom": "stake", - "amount": "8869960226" - } - ] - }, - { - "address": "cosmos1d5vv20893q06tx29mlqmefnyf0w3hn0v07w9p9", - "coins": [ - { - "denom": "stake", - "amount": "50733557399" - } - ] - }, - { - "address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", - "coins": [ - { - "denom": "stake", - "amount": "20940341779" - } - ] - }, - { - "address": "cosmos1l5d2lg5hku0m4u8mh866zhjcy2dekpk598m8wr", - "coins": [ - { - "denom": "stake", - "amount": "1178967884" - } - ] - }, - { - "address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", - "coins": [ - { - "denom": "stake", - "amount": "8095681198" - } - ] - }, - { - "address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "coins": [ - { - "denom": "stake", - "amount": "82769207" - } - ] - } - ] - }, - "crisis": { - "constant_fee": { - "denom": "stake", - "amount": "1000" - } - }, - "mint": { - "minter": { - "inflation": "0.200000000000000000", - "annual_provisions": "5810696836997.800000000000000000" - }, - "params": { - "mint_denom": "stake", - "inflation_rate_change": "0.210000000000000000", - "inflation_max": "0.200000000000000000", - "inflation_min": "0.070000000000000000", - "goal_bonded": "0.670000000000000000", - "blocks_per_year": "6311520" - } - }, - "slashing": { - "params": { - "signed_blocks_window": "80", - "min_signed_per_window": "0.500000000000000000", - "downtime_jail_duration": "35518000000000", - "slash_fraction_double_sign": "0.038461538461538462", - "slash_fraction_downtime": "0.012987012987012987" - }, - "signing_infos": { - "cosmosvalcons12dh9h444s238r7hjrrd2kg6wrw4cwfk3999xl6": { - "address": "cosmosvalcons12dh9h444s238r7hjrrd2kg6wrw4cwfk3999xl6", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtp8l6ug4": { - "address": "cosmosvalcons1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtp8l6ug4", - "start_height": "12", - "index_offset": "37", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "36" - }, - "cosmosvalcons1e8fdmnscnm6axht542696jupnqlkm40e0jefjw": { - "address": "cosmosvalcons1e8fdmnscnm6axht542696jupnqlkm40e0jefjw", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1up7x3srs54xhq897rlda86hdsf4sy7ncez37jn": { - "address": "cosmosvalcons1up7x3srs54xhq897rlda86hdsf4sy7ncez37jn", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux0fv6ry": { - "address": "cosmosvalcons1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux0fv6ry", - "start_height": "48", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1r7kh63jvjhwqraux9wtm3jat8ggm437w5lp3x2": { - "address": "cosmosvalcons1r7kh63jvjhwqraux9wtm3jat8ggm437w5lp3x2", - "start_height": "6", - "index_offset": "37", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1x72py7gr6pd72ch7u380ay04t9mhf3fkgur5k8": { - "address": "cosmosvalcons1x72py7gr6pd72ch7u380ay04t9mhf3fkgur5k8", - "index_offset": "15", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1gfta9y4c4j5dd08mju2zf23cmdn7ylauvct35q": { - "address": "cosmosvalcons1gfta9y4c4j5dd08mju2zf23cmdn7ylauvct35q", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons13nemj0k45u4pflkfeyey88n8u8sv4wgzklwr5r": { - "address": "cosmosvalcons13nemj0k45u4pflkfeyey88n8u8sv4wgzklwr5r", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "41" - }, - "cosmosvalcons1nfurwjwfy3zhw0g9eqcclzeejf9nqw62ewmwyr": { - "address": "cosmosvalcons1nfurwjwfy3zhw0g9eqcclzeejf9nqw62ewmwyr", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons14se5hzhf43yk83pkztukhtlfu683s4ktcqzgvs": { - "address": "cosmosvalcons14se5hzhf43yk83pkztukhtlfu683s4ktcqzgvs", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7t0qj3k": { - "address": "cosmosvalcons1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7t0qj3k", - "start_height": "2", - "index_offset": "46", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "46" - }, - "cosmosvalcons1l5d2lg5hku0m4u8mh866zhjcy2dekpk55quww3": { - "address": "cosmosvalcons1l5d2lg5hku0m4u8mh866zhjcy2dekpk55quww3", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "23" - }, - "cosmosvalcons1z6f7gdevn6dfvpls7tlqmqmzr54le7a4avumjr": { - "address": "cosmosvalcons1z6f7gdevn6dfvpls7tlqmqmzr54le7a4avumjr", - "start_height": "7", - "index_offset": "7", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "7" - }, - "cosmosvalcons190kcpcyvl46xva8ya8vs5wmmg4nygvuty9afhq": { - "address": "cosmosvalcons190kcpcyvl46xva8ya8vs5wmmg4nygvuty9afhq", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons12k6u60mgp8wldpz2xs2u3p3skmghtrjy5etjdq": { - "address": "cosmosvalcons12k6u60mgp8wldpz2xs2u3p3skmghtrjy5etjdq", - "start_height": "4", - "index_offset": "4", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1n20sc20x53kyms9vhrxlr8r79hptq3p2efwm48": { - "address": "cosmosvalcons1n20sc20x53kyms9vhrxlr8r79hptq3p2efwm48", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1ellx23lw5uxmdnyjpnn03expxvu89kd6htl8jx": { - "address": "cosmosvalcons1ellx23lw5uxmdnyjpnn03expxvu89kd6htl8jx", - "index_offset": "7", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "7" - }, - "cosmosvalcons17uusex4s7mds872wzvkpaty29g02n8ethl39rz": { - "address": "cosmosvalcons17uusex4s7mds872wzvkpaty29g02n8ethl39rz", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1zzey9t59j5x7j5z9f3urms7faq0gq9dw27hxcc": { - "address": "cosmosvalcons1zzey9t59j5x7j5z9f3urms7faq0gq9dw27hxcc", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwghsz8u0": { - "address": "cosmosvalcons1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwghsz8u0", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons1yezuhyh4htsy74jkhfey9p7urgwhg00jqp7rty": { - "address": "cosmosvalcons1yezuhyh4htsy74jkhfey9p7urgwhg00jqp7rty", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1dle2tkls5kffwdqhan4rs0dgckjxunfsv0l9kn": { - "address": "cosmosvalcons1dle2tkls5kffwdqhan4rs0dgckjxunfsv0l9kn", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "47" - }, - "cosmosvalcons13fyamuv3fexmuuamtgqtwkz48ynl3hd5jgmlh8": { - "address": "cosmosvalcons13fyamuv3fexmuuamtgqtwkz48ynl3hd5jgmlh8", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons15772l3g3u9kk2qk5cmsl8tr6lshgd443cvttwn": { - "address": "cosmosvalcons15772l3g3u9kk2qk5cmsl8tr6lshgd443cvttwn", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "46" - }, - "cosmosvalcons14qy520rhr0qytqxdtsjsu9rgw708n2w6ex2jmj": { - "address": "cosmosvalcons14qy520rhr0qytqxdtsjsu9rgw708n2w6ex2jmj", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons17gpy6jzg7xdsr2xc7kweljagx4uaysxd8ddu46": { - "address": "cosmosvalcons17gpy6jzg7xdsr2xc7kweljagx4uaysxd8ddu46", - "start_height": "1", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons1zjw6x8t95zuaxprcyl0x6l7u0ag6626v0fzay6": { - "address": "cosmosvalcons1zjw6x8t95zuaxprcyl0x6l7u0ag6626v0fzay6", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons19yplr2r5lu70jlymwrumzuc8tqeeu7fg5x9a4u": { - "address": "cosmosvalcons19yplr2r5lu70jlymwrumzuc8tqeeu7fg5x9a4u", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons19e3lp8kdpnzmd778gxz9hqrnaxw8spa36e4k9u": { - "address": "cosmosvalcons19e3lp8kdpnzmd778gxz9hqrnaxw8spa36e4k9u", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons188yd2umzwfwen7es68wrlh6auu3p8jhz78wpeq": { - "address": "cosmosvalcons188yd2umzwfwen7es68wrlh6auu3p8jhz78wpeq", - "index_offset": "44", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "41" - }, - "cosmosvalcons1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpus7r8l": { - "address": "cosmosvalcons1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpus7r8l", - "start_height": "7", - "index_offset": "42", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1n3lnhxzzm7ntheu78h6v4zag7zmrlp486457fr": { - "address": "cosmosvalcons1n3lnhxzzm7ntheu78h6v4zag7zmrlp486457fr", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons14kdxam68sthcd72526kc5ea42hfq5c2ga5v908": { - "address": "cosmosvalcons14kdxam68sthcd72526kc5ea42hfq5c2ga5v908", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1ql2jawqmha8d2xdgda7njakszmhvt75rv4zlx8": { - "address": "cosmosvalcons1ql2jawqmha8d2xdgda7njakszmhvt75rv4zlx8", - "index_offset": "15", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "8" - }, - "cosmosvalcons1zu50umwgah6jhx07sw04ry0pv7fnvkpj25q9lh": { - "address": "cosmosvalcons1zu50umwgah6jhx07sw04ry0pv7fnvkpj25q9lh", - "index_offset": "49", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1wnn8xrn46u6ryq4kqf7tcf650fe2gl57uk0p3z": { - "address": "cosmosvalcons1wnn8xrn46u6ryq4kqf7tcf650fe2gl57uk0p3z", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1nz5hp6p6wn4fvnaxe9x6fq35daamxvhh6ze2pt": { - "address": "cosmosvalcons1nz5hp6p6wn4fvnaxe9x6fq35daamxvhh6ze2pt", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons16xal57nga5gd2qxkz869qv7hm20xn0rkyfusws": { - "address": "cosmosvalcons16xal57nga5gd2qxkz869qv7hm20xn0rkyfusws", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons16sn6wjtd0kw4yvc7780cpayhz0x45d27cdeswx": { - "address": "cosmosvalcons16sn6wjtd0kw4yvc7780cpayhz0x45d27cdeswx", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1uuk9ewj0532rzlhlg86tserdxvtnm3kqm3dtwu": { - "address": "cosmosvalcons1uuk9ewj0532rzlhlg86tserdxvtnm3kqm3dtwu", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1q55pmsr0wnpzlcx25p9vqde6c52ekjnvysqusa": { - "address": "cosmosvalcons1q55pmsr0wnpzlcx25p9vqde6c52ekjnvysqusa", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1gayzja3zz6unep8ftnpunt2wefazs3jhd5caas": { - "address": "cosmosvalcons1gayzja3zz6unep8ftnpunt2wefazs3jhd5caas", - "index_offset": "14", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "7" - }, - "cosmosvalcons1frjkqcr3r5fpwds4kypq5e9n865qss6ujnfqrc": { - "address": "cosmosvalcons1frjkqcr3r5fpwds4kypq5e9n865qss6ujnfqrc", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1trkrhq6mxwktf24u8jepelvumpd9l6lehelksx": { - "address": "cosmosvalcons1trkrhq6mxwktf24u8jepelvumpd9l6lehelksx", - "start_height": "8", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1vfcm9c4psqrkv9zecgjw7zxvw2jnpe737eaneg": { - "address": "cosmosvalcons1vfcm9c4psqrkv9zecgjw7zxvw2jnpe737eaneg", - "start_height": "6", - "index_offset": "43", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons15jcgjq7sc62rj4s0dlm4sapdcgw06jfuysh66q": { - "address": "cosmosvalcons15jcgjq7sc62rj4s0dlm4sapdcgw06jfuysh66q", - "start_height": "12", - "index_offset": "37", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "37" - }, - "cosmosvalcons1hu260773mytzz030tuq0kffmlyxzs7vg5wftk9": { - "address": "cosmosvalcons1hu260773mytzz030tuq0kffmlyxzs7vg5wftk9", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "7" - }, - "cosmosvalcons16tr72kn90g5zl7qhyhuqkjflejz00uzl8caasq": { - "address": "cosmosvalcons16tr72kn90g5zl7qhyhuqkjflejz00uzl8caasq", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnf22uec": { - "address": "cosmosvalcons1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnf22uec", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons12r0m6hwrnn0jy02tnhmk328d7p68x2rnu9vxjx": { - "address": "cosmosvalcons12r0m6hwrnn0jy02tnhmk328d7p68x2rnu9vxjx", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "47" - }, - "cosmosvalcons1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqpw7fvxl": { - "address": "cosmosvalcons1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqpw7fvxl", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1h6j4lyvuenmz9m7vq3hler8j7pg5ldpe6gpq90": { - "address": "cosmosvalcons1h6j4lyvuenmz9m7vq3hler8j7pg5ldpe6gpq90", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1qk5quugdx54zsrteg9hpee0ke3z35meuz4rde2": { - "address": "cosmosvalcons1qk5quugdx54zsrteg9hpee0ke3z35meuz4rde2", - "index_offset": "49", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1rq7tvegh0yqan5fpp90rya7q9lks5nyxw0kdej": { - "address": "cosmosvalcons1rq7tvegh0yqan5fpp90rya7q9lks5nyxw0kdej", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons183sdz4kk0lueuxfu7zzgp8tzcjndf3pflk3e02": { - "address": "cosmosvalcons183sdz4kk0lueuxfu7zzgp8tzcjndf3pflk3e02", - "start_height": "5", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1w2ly5qah2m47qguaukzr6xx34hszqh8um4gr3k": { - "address": "cosmosvalcons1w2ly5qah2m47qguaukzr6xx34hszqh8um4gr3k", - "start_height": "1", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons13tfk4n07c9dz5swkw7vafmlrd9e0d28faef7g0": { - "address": "cosmosvalcons13tfk4n07c9dz5swkw7vafmlrd9e0d28faef7g0", - "index_offset": "49", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "12" - }, - "cosmosvalcons1nmexjngk0j8jhgmywrkd7r98dgd9hzxpvcqtsq": { - "address": "cosmosvalcons1nmexjngk0j8jhgmywrkd7r98dgd9hzxpvcqtsq", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1kjupa2w6rlhzj9fjxz35m02g2wpz790fuauq0q": { - "address": "cosmosvalcons1kjupa2w6rlhzj9fjxz35m02g2wpz790fuauq0q", - "start_height": "14", - "index_offset": "34", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "20" - }, - "cosmosvalcons172lmu2psqlkxkthpr46h2ewjffte7lhl2f7nt6": { - "address": "cosmosvalcons172lmu2psqlkxkthpr46h2ewjffte7lhl2f7nt6", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1qy0qwzljplfauvyhgayw6nxte2zxujh4658x9s": { - "address": "cosmosvalcons1qy0qwzljplfauvyhgayw6nxte2zxujh4658x9s", - "start_height": "48", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1ylf26t6vhvugawg87328ng2ug4d8f25s4pxn42": { - "address": "cosmosvalcons1ylf26t6vhvugawg87328ng2ug4d8f25s4pxn42", - "start_height": "9", - "index_offset": "40", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "40" - }, - "cosmosvalcons1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7l4x75dl": { - "address": "cosmosvalcons1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7l4x75dl", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons153rklv33fjex4w7r82n9wnwxrwfgae6nn0hfc9": { - "address": "cosmosvalcons153rklv33fjex4w7r82n9wnwxrwfgae6nn0hfc9", - "index_offset": "13", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "13" - }, - "cosmosvalcons14e68cy8rvnmva3fzvhmq67m94zffpvnt09v3de": { - "address": "cosmosvalcons14e68cy8rvnmva3fzvhmq67m94zffpvnt09v3de", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1hxdqddf3u8vjm080ytpe959uktn4axdapkmfhd": { - "address": "cosmosvalcons1hxdqddf3u8vjm080ytpe959uktn4axdapkmfhd", - "start_height": "2", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons1qw9wqlz92hj8y6mcj24l6wu68er03njuzuu92s": { - "address": "cosmosvalcons1qw9wqlz92hj8y6mcj24l6wu68er03njuzuu92s", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "47" - }, - "cosmosvalcons10cl6sallgwf882apcyagjqa2lx4j8592f4fxgm": { - "address": "cosmosvalcons10cl6sallgwf882apcyagjqa2lx4j8592f4fxgm", - "index_offset": "10", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1ng7vpl5wh98pshfef327gfnzyrwh6z4e8869pm": { - "address": "cosmosvalcons1ng7vpl5wh98pshfef327gfnzyrwh6z4e8869pm", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons15a8hadw3wttrnr3qx37ewmzre4w7cjmtk3uf03": { - "address": "cosmosvalcons15a8hadw3wttrnr3qx37ewmzre4w7cjmtk3uf03", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1qqxeqqvjkh2ls3a0taukd8rydrqqad6975plc2": { - "address": "cosmosvalcons1qqxeqqvjkh2ls3a0taukd8rydrqqad6975plc2", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1x76xgyet9jkq94uqcckrwm20l85gt2kxx6qect": { - "address": "cosmosvalcons1x76xgyet9jkq94uqcckrwm20l85gt2kxx6qect", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1g7sk4y3cf2473ff36mlcx9ydvted9evryympt2": { - "address": "cosmosvalcons1g7sk4y3cf2473ff36mlcx9ydvted9evryympt2", - "start_height": "1", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons1qs5htj5ayfgg27t0xnng837lzllla5y235nkaw": { - "address": "cosmosvalcons1qs5htj5ayfgg27t0xnng837lzllla5y235nkaw", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1ptu2vxfcsyl2gpeg73ehzte7t3va459lj69slr": { - "address": "cosmosvalcons1ptu2vxfcsyl2gpeg73ehzte7t3va459lj69slr", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn5472pf8v": { - "address": "cosmosvalcons18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn5472pf8v", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons10gu52rf3d0z0py8d0x37r058qh9fgdgg9nahwl": { - "address": "cosmosvalcons10gu52rf3d0z0py8d0x37r058qh9fgdgg9nahwl", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons15pl2c2umxszwar75aft99kns0ltmpepnzxvvya": { - "address": "cosmosvalcons15pl2c2umxszwar75aft99kns0ltmpepnzxvvya", - "index_offset": "9", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "9" - }, - "cosmosvalcons158hwrawjlg586d47zl4xk9kg3em02vyppstqwv": { - "address": "cosmosvalcons158hwrawjlg586d47zl4xk9kg3em02vyppstqwv", - "index_offset": "45", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "6" - }, - "cosmosvalcons1kz20p7j939s8cqadmqqws80c6z93qdtyeqpz07": { - "address": "cosmosvalcons1kz20p7j939s8cqadmqqws80c6z93qdtyeqpz07", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "24" - }, - "cosmosvalcons1yalqz5m4qcjtss37pdnvalz5kaws3yjy3he4fv": { - "address": "cosmosvalcons1yalqz5m4qcjtss37pdnvalz5kaws3yjy3he4fv", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "13" - }, - "cosmosvalcons1d5vv20893q06tx29mlqmefnyf0w3hn0v7efvph": { - "address": "cosmosvalcons1d5vv20893q06tx29mlqmefnyf0w3hn0v7efvph", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1h7nkedpkxm0t752j0q88rhgwjn94p4y29hqdn2": { - "address": "cosmosvalcons1h7nkedpkxm0t752j0q88rhgwjn94p4y29hqdn2", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwc2lxm7": { - "address": "cosmosvalcons1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwc2lxm7", - "start_height": "12", - "index_offset": "35", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "35" - }, - "cosmosvalcons1t6k46y53tkcjvdttujt542pcfrwanw0flqxj2g": { - "address": "cosmosvalcons1t6k46y53tkcjvdttujt542pcfrwanw0flqxj2g", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons13yzpngckxvtky2k25j60qxlkekx0jfauyx47zp": { - "address": "cosmosvalcons13yzpngckxvtky2k25j60qxlkekx0jfauyx47zp", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1eausepxh2ujd0lpjup9vahjekpz9as2fgn2vdk": { - "address": "cosmosvalcons1eausepxh2ujd0lpjup9vahjekpz9as2fgn2vdk", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1r4czpmmu87t7zhlh34zrzna9gkex4ap5eqd50s": { - "address": "cosmosvalcons1r4czpmmu87t7zhlh34zrzna9gkex4ap5eqd50s", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1jf2wka8xprke2q6qxq2vz3khe4mqxv75jvgj02": { - "address": "cosmosvalcons1jf2wka8xprke2q6qxq2vz3khe4mqxv75jvgj02", - "index_offset": "7", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "7" - }, - "cosmosvalcons1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlvmv8ya": { - "address": "cosmosvalcons1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlvmv8ya", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1nrugh7am9s584k6qlf5nxlpetarxs2csecvu6u": { - "address": "cosmosvalcons1nrugh7am9s584k6qlf5nxlpetarxs2csecvu6u", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4g2ureq": { - "address": "cosmosvalcons15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4g2ureq", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7naq267qg": { - "address": "cosmosvalcons1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7naq267qg", - "start_height": "1", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wwhy7vf": { - "address": "cosmosvalcons1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wwhy7vf", - "index_offset": "49", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "47" - }, - "cosmosvalcons1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfccuman": { - "address": "cosmosvalcons1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfccuman", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "46" - }, - "cosmosvalcons1yt9s823gnqayrjasrra5j43pj9c48ae9gp0f5l": { - "address": "cosmosvalcons1yt9s823gnqayrjasrra5j43pj9c48ae9gp0f5l", - "start_height": "6", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons12f4fpl936ld8c64dxqgwv65p42na8dcnaz0hkw": { - "address": "cosmosvalcons12f4fpl936ld8c64dxqgwv65p42na8dcnaz0hkw", - "index_offset": "9", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "9" - }, - "cosmosvalcons10ndcqfr2zwrspryphtuhq883kc49z38fwtx025": { - "address": "cosmosvalcons10ndcqfr2zwrspryphtuhq883kc49z38fwtx025", - "start_height": "2", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons13mztfedkzpz634g7u5fh8henfmvzyrfflw7r8u": { - "address": "cosmosvalcons13mztfedkzpz634g7u5fh8henfmvzyrfflw7r8u", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons147pq4rzswl76kdeyx8sc7pagf4nhjpnqmsc2hr": { - "address": "cosmosvalcons147pq4rzswl76kdeyx8sc7pagf4nhjpnqmsc2hr", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "24" - }, - "cosmosvalcons1k0z97vlulcmdrrajhms2x9k8srvtmxwu9l0mha": { - "address": "cosmosvalcons1k0z97vlulcmdrrajhms2x9k8srvtmxwu9l0mha", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1cdvntn6mwvvv4qxnty6zp2jwvemg20yuqmdsse": { - "address": "cosmosvalcons1cdvntn6mwvvv4qxnty6zp2jwvemg20yuqmdsse", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons1a4nlyf59n25qmh4myas5mdunvu9r4wlsffl40h": { - "address": "cosmosvalcons1a4nlyf59n25qmh4myas5mdunvu9r4wlsffl40h", - "start_height": "2", - "index_offset": "4", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1zscesuffz58dc0lq7yy6n6z3j5fhkr3du7aulk": { - "address": "cosmosvalcons1zscesuffz58dc0lq7yy6n6z3j5fhkr3du7aulk", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1gd779gn33yuxxla5pm5dphglcyx4ulzd86ldf8": { - "address": "cosmosvalcons1gd779gn33yuxxla5pm5dphglcyx4ulzd86ldf8", - "index_offset": "26", - "jailed_until": "9999-12-31T23:59:59Z", - "tombstoned": true, - "missed_blocks_counter": "14" - }, - "cosmosvalcons12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5ymewrp": { - "address": "cosmosvalcons12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5ymewrp", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1wy59rs74dnqqs0xz70sn2q5hyv9yreth64pa96": { - "address": "cosmosvalcons1wy59rs74dnqqs0xz70sn2q5hyv9yreth64pa96", - "start_height": "2", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1qqe0t0j86umq0379kjcmjg00yd6ddrdw9cehas": { - "address": "cosmosvalcons1qqe0t0j86umq0379kjcmjg00yd6ddrdw9cehas", - "start_height": "1", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons18d56e7qz5869wegeca967hrxrmfduxdenqzjcz": { - "address": "cosmosvalcons18d56e7qz5869wegeca967hrxrmfduxdenqzjcz", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons13w024ysyklmnrq9c6udp98qx93jqynhggkk3rp": { - "address": "cosmosvalcons13w024ysyklmnrq9c6udp98qx93jqynhggkk3rp", - "index_offset": "8", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "6" - }, - "cosmosvalcons1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76v6c2hww": { - "address": "cosmosvalcons1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76v6c2hww", - "start_height": "48", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1qpj52qsl708aqhazaqehhjw7cdj4her9zsvuxy": { - "address": "cosmosvalcons1qpj52qsl708aqhazaqehhjw7cdj4her9zsvuxy", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1y30ftjd79f3p68mssyd9zug24q2avh0zkms02f": { - "address": "cosmosvalcons1y30ftjd79f3p68mssyd9zug24q2avh0zkms02f", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1s30d8tgwhwavwtvanggkj92quj8ucecyqlzjzv": { - "address": "cosmosvalcons1s30d8tgwhwavwtvanggkj92quj8ucecyqlzjzv", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1s6sl7pyvn33lptf7edmux0gex06ffzjz8l2hlr": { - "address": "cosmosvalcons1s6sl7pyvn33lptf7edmux0gex06ffzjz8l2hlr", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons10ke8m795c8svtt2h24n6dad2xp9a8mev6pk3dq": { - "address": "cosmosvalcons10ke8m795c8svtt2h24n6dad2xp9a8mev6pk3dq", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1q03kay3adsttv6watm3agqktnpuuxs65vz6tu7": { - "address": "cosmosvalcons1q03kay3adsttv6watm3agqktnpuuxs65vz6tu7", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons19vugh7w9vrp6x3nqzjph59zg0d28c0fkn7432d": { - "address": "cosmosvalcons19vugh7w9vrp6x3nqzjph59zg0d28c0fkn7432d", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1g95xvy8qgzcvcl05fse0mpxzdfv3w88ts7pdc3": { - "address": "cosmosvalcons1g95xvy8qgzcvcl05fse0mpxzdfv3w88ts7pdc3", - "index_offset": "49", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1hsq728kpcxgr77ncj8asxa0383pyx7vqpf87tj": { - "address": "cosmosvalcons1hsq728kpcxgr77ncj8asxa0383pyx7vqpf87tj", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons17qavkakyqgh62k39frjf5v9pj0c78m2daks0a9": { - "address": "cosmosvalcons17qavkakyqgh62k39frjf5v9pj0c78m2daks0a9", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1p0u57pfl53kwefqrrr652pd3sm2hhv9gznzvw7": { - "address": "cosmosvalcons1p0u57pfl53kwefqrrr652pd3sm2hhv9gznzvw7", - "start_height": "7", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1xec6kclrpkc4ws7lwf5j0u8207nyg6dzr6xsy0": { - "address": "cosmosvalcons1xec6kclrpkc4ws7lwf5j0u8207nyg6dzr6xsy0", - "index_offset": "8", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1289vtnyn8vg9rwv7jdcy2ht3h68627ht5jdl32": { - "address": "cosmosvalcons1289vtnyn8vg9rwv7jdcy2ht3h68627ht5jdl32", - "start_height": "7", - "index_offset": "39", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "19" - }, - "cosmosvalcons1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjf35ts7": { - "address": "cosmosvalcons1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjf35ts7", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1jsd99e3zfrxrr3nh057u0tvmu0847zkrmzwr87": { - "address": "cosmosvalcons1jsd99e3zfrxrr3nh057u0tvmu0847zkrmzwr87", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "23" - }, - "cosmosvalcons1ktnuvrm3q8h30y3k70yzvmvwme77e9yycn5aw6": { - "address": "cosmosvalcons1ktnuvrm3q8h30y3k70yzvmvwme77e9yycn5aw6", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1y7m2ga0zpxr6q000a4a924fdaeycw5ed43yckr": { - "address": "cosmosvalcons1y7m2ga0zpxr6q000a4a924fdaeycw5ed43yckr", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1jp0tqhr79uwqt2rh66vcd378rrhslg49uwt39p": { - "address": "cosmosvalcons1jp0tqhr79uwqt2rh66vcd378rrhslg49uwt39p", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "47" - }, - "cosmosvalcons1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7tn52wp": { - "address": "cosmosvalcons1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7tn52wp", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1m8gpgklc8a2yla9ah9y8mlu226n0mu4ym3qdze": { - "address": "cosmosvalcons1m8gpgklc8a2yla9ah9y8mlu226n0mu4ym3qdze", - "start_height": "4", - "index_offset": "45", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "45" - }, - "cosmosvalcons1awyus34e6laq3zxqsrv283w6fgn8w62z8f2w7l": { - "address": "cosmosvalcons1awyus34e6laq3zxqsrv283w6fgn8w62z8f2w7l", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1ryy20he94rlaryj04mkhcj6n4dhuhcytym4g7r": { - "address": "cosmosvalcons1ryy20he94rlaryj04mkhcj6n4dhuhcytym4g7r", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1rkl7umzewantxm5e8mf2l2tcxc3t7hj8djzmrw": { - "address": "cosmosvalcons1rkl7umzewantxm5e8mf2l2tcxc3t7hj8djzmrw", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1v08dcmtc5f444sxqfvqv8mxdclmc2759mh75r7": { - "address": "cosmosvalcons1v08dcmtc5f444sxqfvqv8mxdclmc2759mh75r7", - "start_height": "4", - "index_offset": "9", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "9" - }, - "cosmosvalcons1r5tg7kujl8x77c84dedr2z9agsjyp8tqq8hrc8": { - "address": "cosmosvalcons1r5tg7kujl8x77c84dedr2z9agsjyp8tqq8hrc8", - "start_height": "2", - "index_offset": "4", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons1dnt8cpf6lwldf4r99n03kuv8fqwfqkfc4ndrkr": { - "address": "cosmosvalcons1dnt8cpf6lwldf4r99n03kuv8fqwfqkfc4ndrkr", - "index_offset": "8", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1wzmzdml4fsakuyukmaa6qqee3g6w6qtc3szmzj": { - "address": "cosmosvalcons1wzmzdml4fsakuyukmaa6qqee3g6w6qtc3szmzj", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "21" - }, - "cosmosvalcons15dt0e900x5cv9w870mevztqwy88hhu2st8xhx4": { - "address": "cosmosvalcons15dt0e900x5cv9w870mevztqwy88hhu2st8xhx4", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons154epq0mwqz393frj38lh265h9slwdynmwkyxq9": { - "address": "cosmosvalcons154epq0mwqz393frj38lh265h9slwdynmwkyxq9", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "22" - }, - "cosmosvalcons16rv5x3545upw3qgemu6kz0cjd36lhvz2k2cpar": { - "address": "cosmosvalcons16rv5x3545upw3qgemu6kz0cjd36lhvz2k2cpar", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "20" - }, - "cosmosvalcons1xw7mpsuf4vma4a2thsad2623wjcgcy6u8yy8sa": { - "address": "cosmosvalcons1xw7mpsuf4vma4a2thsad2623wjcgcy6u8yy8sa", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1c07ez82s6kcfyg9szzg0pgghdpl7a2k0uc46p5": { - "address": "cosmosvalcons1c07ez82s6kcfyg9szzg0pgghdpl7a2k0uc46p5", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1eccz4hnumvgsqzpfgmvhc5vwh4ugptm56yyx9f": { - "address": "cosmosvalcons1eccz4hnumvgsqzpfgmvhc5vwh4ugptm56yyx9f", - "index_offset": "49", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1adwsqn58aype530jae9qrwknsxyf3wmwuynr3s": { - "address": "cosmosvalcons1adwsqn58aype530jae9qrwknsxyf3wmwuynr3s", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1qzj5kxv664trtfn4h0aznrsljtt2q95quzyrql": { - "address": "cosmosvalcons1qzj5kxv664trtfn4h0aznrsljtt2q95quzyrql", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1tnh79aat8d4m82pfm7gqa0z5kzzh7zty9nz93n": { - "address": "cosmosvalcons1tnh79aat8d4m82pfm7gqa0z5kzzh7zty9nz93n", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8e7x7qv": { - "address": "cosmosvalcons1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8e7x7qv", - "index_offset": "44", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "41" - }, - "cosmosvalcons1mfldj5ly78eg08sd2k3nygggjx765vvwr3sa2u": { - "address": "cosmosvalcons1mfldj5ly78eg08sd2k3nygggjx765vvwr3sa2u", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkjpwd47": { - "address": "cosmosvalcons1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkjpwd47", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1yva09usdkzdsqekaasgcqvm50v9vv5puyw2v3r": { - "address": "cosmosvalcons1yva09usdkzdsqekaasgcqvm50v9vv5puyw2v3r", - "start_height": "4", - "index_offset": "45", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "45" - }, - "cosmosvalcons1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3crkzxj": { - "address": "cosmosvalcons1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3crkzxj", - "index_offset": "43", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "41" - }, - "cosmosvalcons13fvz5er8rdttgtuwvcuaku00j2nw2v6kglpshq": { - "address": "cosmosvalcons13fvz5er8rdttgtuwvcuaku00j2nw2v6kglpshq", - "start_height": "6", - "index_offset": "43", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "23" - }, - "cosmosvalcons14dp6lpg8dqs4e0aq34vhcwpxt37nltefr2w0fk": { - "address": "cosmosvalcons14dp6lpg8dqs4e0aq34vhcwpxt37nltefr2w0fk", - "start_height": "8", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons14jvurctjcvs69hlppa0dkjplczns7zlqthruvy": { - "address": "cosmosvalcons14jvurctjcvs69hlppa0dkjplczns7zlqthruvy", - "start_height": "4", - "index_offset": "45", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "45" - }, - "cosmosvalcons144n7h95z7sz0r3k9rm3r8umkc89wt5c70h9mrh": { - "address": "cosmosvalcons144n7h95z7sz0r3k9rm3r8umkc89wt5c70h9mrh", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons18056m2nw355q2tjmvdslp9fqadmca5up2fcnvw": { - "address": "cosmosvalcons18056m2nw355q2tjmvdslp9fqadmca5up2fcnvw", - "index_offset": "7", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1sjhhg2yl2cqszte7pjyrp6lx5tg383lrs4rf0f": { - "address": "cosmosvalcons1sjhhg2yl2cqszte7pjyrp6lx5tg383lrs4rf0f", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1s728ea54m9u76dkd4x9ea3l5cvjjjkk5dgk8gv": { - "address": "cosmosvalcons1s728ea54m9u76dkd4x9ea3l5cvjjjkk5dgk8gv", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1ll2f2v79ssg5teg5trglr0wecm877aprwzvqh9": { - "address": "cosmosvalcons1ll2f2v79ssg5teg5trglr0wecm877aprwzvqh9", - "start_height": "1", - "index_offset": "45", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "7" - }, - "cosmosvalcons1qsxjdj8z2urjdxpp7uu37pp2pf3chjjcttwfff": { - "address": "cosmosvalcons1qsxjdj8z2urjdxpp7uu37pp2pf3chjjcttwfff", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1zjzkk7l2jalrspy6500my8v0yy6ycz7ewnkuzu": { - "address": "cosmosvalcons1zjzkk7l2jalrspy6500my8v0yy6ycz7ewnkuzu", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1r2ncmjrd4efnk9cjrftq7sw7347xqyu3va4mm8": { - "address": "cosmosvalcons1r2ncmjrd4efnk9cjrftq7sw7347xqyu3va4mm8", - "start_height": "5", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons19wgl6sjkktp7mysmmtzqnecd5v2xn7gs7022a6": { - "address": "cosmosvalcons19wgl6sjkktp7mysmmtzqnecd5v2xn7gs7022a6", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1dge9en6j6xl3njpkk8gvw9n326pgna44v3fc2z": { - "address": "cosmosvalcons1dge9en6j6xl3njpkk8gvw9n326pgna44v3fc2z", - "start_height": "5", - "index_offset": "7", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0v4sfcv": { - "address": "cosmosvalcons1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0v4sfcv", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons15tf0n2rqlh49324hrn0vzmj33fr7yk9tjs0up2": { - "address": "cosmosvalcons15tf0n2rqlh49324hrn0vzmj33fr7yk9tjs0up2", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons14lwqx5380234f0fshaycluz08yw74chl9wupjl": { - "address": "cosmosvalcons14lwqx5380234f0fshaycluz08yw74chl9wupjl", - "index_offset": "44", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "11" - }, - "cosmosvalcons1k7dl7gc3umxp45u8m8zc6evvus2gvjvcagsclr": { - "address": "cosmosvalcons1k7dl7gc3umxp45u8m8zc6evvus2gvjvcagsclr", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1hyv7jjh3kswlfc6nh0xp545rl5ttty2xe7j8l3": { - "address": "cosmosvalcons1hyv7jjh3kswlfc6nh0xp545rl5ttty2xe7j8l3", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc9jsr7n": { - "address": "cosmosvalcons1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc9jsr7n", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons17k35dydvkrdxup6z8633k3zcc4ecmgnz23jtdd": { - "address": "cosmosvalcons17k35dydvkrdxup6z8633k3zcc4ecmgnz23jtdd", - "start_height": "1", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1zukq6nknswp76ckcj5s9rnvmye974n7c3mmhnd": { - "address": "cosmosvalcons1zukq6nknswp76ckcj5s9rnvmye974n7c3mmhnd", - "index_offset": "8", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1terlqq72gje366346skcmzfgg4lqypf579w83k": { - "address": "cosmosvalcons1terlqq72gje366346skcmzfgg4lqypf579w83k", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1333066cp52k7fgmug2dwylafnymdxcg6zjcsez": { - "address": "cosmosvalcons1333066cp52k7fgmug2dwylafnymdxcg6zjcsez", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "19" - }, - "cosmosvalcons1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8pce0y2": { - "address": "cosmosvalcons1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8pce0y2", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3gvqu70": { - "address": "cosmosvalcons1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3gvqu70", - "index_offset": "13", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons18gmd4r8ydls55yvgda4d8pfandk0xem53e75t4": { - "address": "cosmosvalcons18gmd4r8ydls55yvgda4d8pfandk0xem53e75t4", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons138ueargdn7h3qhwdpvusu9uduacvm393y0rccz": { - "address": "cosmosvalcons138ueargdn7h3qhwdpvusu9uduacvm393y0rccz", - "start_height": "1", - "index_offset": "8", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons1jv7lxeryc30c0w4p7p92nxywgcnswuhshvzk3n": { - "address": "cosmosvalcons1jv7lxeryc30c0w4p7p92nxywgcnswuhshvzk3n", - "index_offset": "8", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1557a6swa3yv3ew9yk8hcfpyqu3ce7te0dualvr": { - "address": "cosmosvalcons1557a6swa3yv3ew9yk8hcfpyqu3ce7te0dualvr", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1h8wfu2kqcjeev96yddv3nj9r4q003essj2vrm3": { - "address": "cosmosvalcons1h8wfu2kqcjeev96yddv3nj9r4q003essj2vrm3", - "start_height": "4", - "index_offset": "43", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "43" - }, - "cosmosvalcons1q9ed2n5wvzcrymaqltypazqzd2xv8d5alnqqle": { - "address": "cosmosvalcons1q9ed2n5wvzcrymaqltypazqzd2xv8d5alnqqle", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "26" - }, - "cosmosvalcons19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyuhga22w": { - "address": "cosmosvalcons19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyuhga22w", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons18nag9zrh49uaxypx83fmlz85umq0t9j79nzvqa": { - "address": "cosmosvalcons18nag9zrh49uaxypx83fmlz85umq0t9j79nzvqa", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1vsuhkup8jznqt89zgv9nw8c3u3a7l3u80lyhm6": { - "address": "cosmosvalcons1vsuhkup8jznqt89zgv9nw8c3u3a7l3u80lyhm6", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "41" - }, - "cosmosvalcons155znzxm9g8j53k8vyp2d5qmrkzdum4d0a2nk2a": { - "address": "cosmosvalcons155znzxm9g8j53k8vyp2d5qmrkzdum4d0a2nk2a", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1hll5qzyzy4vrtdad5rqnf2jvf7srdnsymt6r3e": { - "address": "cosmosvalcons1hll5qzyzy4vrtdad5rqnf2jvf7srdnsymt6r3e", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1a0jdqzvk078d6486vuxdr5d0yp6rgluem5sadp": { - "address": "cosmosvalcons1a0jdqzvk078d6486vuxdr5d0yp6rgluem5sadp", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons17er26f88ee6l369a2qk7xmnt248gqtucyn7vxs": { - "address": "cosmosvalcons17er26f88ee6l369a2qk7xmnt248gqtucyn7vxs", - "start_height": "8", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "40" - }, - "cosmosvalcons17uqc5hqs6x7ccr7pcrafp8tfwsezt07ejfk5yc": { - "address": "cosmosvalcons17uqc5hqs6x7ccr7pcrafp8tfwsezt07ejfk5yc", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1xau5jp7uyewxcwg9tzwsxm895v3mf0fn04azmn": { - "address": "cosmosvalcons1xau5jp7uyewxcwg9tzwsxm895v3mf0fn04azmn", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1taucnwfqfkpq6c6y345j6h8jt5fffgla9rv3qf": { - "address": "cosmosvalcons1taucnwfqfkpq6c6y345j6h8jt5fffgla9rv3qf", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1jqkfaju29z0270cmm4zhygtzwjcuqjzx9d44za": { - "address": "cosmosvalcons1jqkfaju29z0270cmm4zhygtzwjcuqjzx9d44za", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y5mms0qg": { - "address": "cosmosvalcons1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y5mms0qg", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1n8emgp25g5wh4d9204lpd06gsznurtlpu09dtl": { - "address": "cosmosvalcons1n8emgp25g5wh4d9204lpd06gsznurtlpu09dtl", - "index_offset": "37", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons15zqzxj663h8g8naxyz324j2rpd3rnw4ravpspc": { - "address": "cosmosvalcons15zqzxj663h8g8naxyz324j2rpd3rnw4ravpspc", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons17nckqnw09secacg9y6r7pay02nhemww69ksle3": { - "address": "cosmosvalcons17nckqnw09secacg9y6r7pay02nhemww69ksle3", - "start_height": "1", - "index_offset": "46", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "46" - }, - "cosmosvalcons1s28wuj4yrqsmjm2cckx6mu037e92up2m2w36xt": { - "address": "cosmosvalcons1s28wuj4yrqsmjm2cckx6mu037e92up2m2w36xt", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1ndff2ha25wm2nhunxgfrzlnhvc5j06zve6f54r": { - "address": "cosmosvalcons1ndff2ha25wm2nhunxgfrzlnhvc5j06zve6f54r", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons16ll03qy5htuech4u0z432zertwhyxynl9khkh2": { - "address": "cosmosvalcons16ll03qy5htuech4u0z432zertwhyxynl9khkh2", - "index_offset": "6", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "6" - }, - "cosmosvalcons1x9mhtyr2tak88skl0nr4lq6k7jreus6n9s59vu": { - "address": "cosmosvalcons1x9mhtyr2tak88skl0nr4lq6k7jreus6n9s59vu", - "start_height": "1", - "index_offset": "4", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1fdfwthdupznzgrg2d8e96ryxqz8smppe6dxr7w": { - "address": "cosmosvalcons1fdfwthdupznzgrg2d8e96ryxqz8smppe6dxr7w", - "index_offset": "6", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons1f6qxvzgn7lfsvg2f86m30pshf8wuygk7w7wqdy": { - "address": "cosmosvalcons1f6qxvzgn7lfsvg2f86m30pshf8wuygk7w7wqdy", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1vjj3g3vkh56g04yqqsdn0yxcul9pve2rt04f87": { - "address": "cosmosvalcons1vjj3g3vkh56g04yqqsdn0yxcul9pve2rt04f87", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons10d3vd6yx9k9ns6v82r4krm3d4ragw04c4hun22": { - "address": "cosmosvalcons10d3vd6yx9k9ns6v82r4krm3d4ragw04c4hun22", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1evqmj6ahqf76keas4ymhvf4r992kg7wrvygqrw": { - "address": "cosmosvalcons1evqmj6ahqf76keas4ymhvf4r992kg7wrvygqrw", - "start_height": "12", - "index_offset": "37", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "16" - }, - "cosmosvalcons128xc6r596pllf46ev2cpaetcujfgmhay7tzcwd": { - "address": "cosmosvalcons128xc6r596pllf46ev2cpaetcujfgmhay7tzcwd", - "start_height": "47", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1dkwuxswrh5mx3mmmsny2qhwm4xtu33tynte2nf": { - "address": "cosmosvalcons1dkwuxswrh5mx3mmmsny2qhwm4xtu33tynte2nf", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1n08duqdkxwmqmtjaha236esw6r72njd2xy0fmg": { - "address": "cosmosvalcons1n08duqdkxwmqmtjaha236esw6r72njd2xy0fmg", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "6" - }, - "cosmosvalcons1n5n6d47c4ntac509rtq3s620vmcqcf97ygkv7e": { - "address": "cosmosvalcons1n5n6d47c4ntac509rtq3s620vmcqcf97ygkv7e", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a7ha5z7": { - "address": "cosmosvalcons1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a7ha5z7", - "start_height": "14", - "index_offset": "35", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1707yw2jgerkawrdyylsj4vll8k2ww5evjmxc5a": { - "address": "cosmosvalcons1707yw2jgerkawrdyylsj4vll8k2ww5evjmxc5a", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "28" - }, - "cosmosvalcons1z97a2xx0rzwtfftg3k9yt693dwxx9j80749vks": { - "address": "cosmosvalcons1z97a2xx0rzwtfftg3k9yt693dwxx9j80749vks", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalaatgcxv": { - "address": "cosmosvalcons1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalaatgcxv", - "start_height": "1", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7uajcn9": { - "address": "cosmosvalcons1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7uajcn9", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons14q9rupnazu0mmkjd9skpn2zdfs8d0hlgx9xl07": { - "address": "cosmosvalcons14q9rupnazu0mmkjd9skpn2zdfs8d0hlgx9xl07", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons16v3h2mggt8tnkxp0vq5tq25fhr3knvf4rfjxlx": { - "address": "cosmosvalcons16v3h2mggt8tnkxp0vq5tq25fhr3knvf4rfjxlx", - "start_height": "6", - "index_offset": "43", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "19" - }, - "cosmosvalcons179uxhryqvrkxa2wtnw2cnptdt80qc24kksm9ly": { - "address": "cosmosvalcons179uxhryqvrkxa2wtnw2cnptdt80qc24kksm9ly", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1fjct2f29ymrw9h7aqffafx863c4tkxdh5c95y4": { - "address": "cosmosvalcons1fjct2f29ymrw9h7aqffafx863c4tkxdh5c95y4", - "start_height": "4", - "index_offset": "45", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "21" - }, - "cosmosvalcons1fhpyqq3eex5zcctlgsxj3s3dgz64am96pv0u6u": { - "address": "cosmosvalcons1fhpyqq3eex5zcctlgsxj3s3dgz64am96pv0u6u", - "start_height": "48", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons13296rs6uwadjwya2l2uc2jzxgyllcjm2sl0ym0": { - "address": "cosmosvalcons13296rs6uwadjwya2l2uc2jzxgyllcjm2sl0ym0", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons13spl9rpkd0wd9c32mpsd9h6phwwnxu3uzvy8tm": { - "address": "cosmosvalcons13spl9rpkd0wd9c32mpsd9h6phwwnxu3uzvy8tm", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1n5t5rr83k3emp5e446qjprj0svsh06rw33397a": { - "address": "cosmosvalcons1n5t5rr83k3emp5e446qjprj0svsh06rw33397a", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1mcvztyynwvn7lelqx89xuzzuguhx5xm7usl4un": { - "address": "cosmosvalcons1mcvztyynwvn7lelqx89xuzzuguhx5xm7usl4un", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons1znvpcj20duymyac6cl4r8kcf827aqu60amp48q": { - "address": "cosmosvalcons1znvpcj20duymyac6cl4r8kcf827aqu60amp48q", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1zah0g92ytwdvpchd3sceuanu7knhtu22yt5z5y": { - "address": "cosmosvalcons1zah0g92ytwdvpchd3sceuanu7knhtu22yt5z5y", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons19qqvhp8aacjvxjhtgwncctmtrmjelqs62ar4s5": { - "address": "cosmosvalcons19qqvhp8aacjvxjhtgwncctmtrmjelqs62ar4s5", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1t7wt4qjfsa4kncvvya5m99mq0m53n9e8q9m6p5": { - "address": "cosmosvalcons1t7wt4qjfsa4kncvvya5m99mq0m53n9e8q9m6p5", - "start_height": "1", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1ng5m6spxngyne4qzce35fdg0whl0yqgv5c0vte": { - "address": "cosmosvalcons1ng5m6spxngyne4qzce35fdg0whl0yqgv5c0vte", - "start_height": "8", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "40" - }, - "cosmosvalcons14rhly0ayx5ewyldmrp8kn564wnn8aascwe6d59": { - "address": "cosmosvalcons14rhly0ayx5ewyldmrp8kn564wnn8aascwe6d59", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1mdes9dapqu6vr094qc6wyhd9jt7qfwvjm5cyw3": { - "address": "cosmosvalcons1mdes9dapqu6vr094qc6wyhd9jt7qfwvjm5cyw3", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons178gvnxtnq2n4m23492m7agshjv3zgzy3zzg47d": { - "address": "cosmosvalcons178gvnxtnq2n4m23492m7agshjv3zgzy3zzg47d", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1dzuk49ssprfz3ala9tea3x74x8n2nlyz4zj52j": { - "address": "cosmosvalcons1dzuk49ssprfz3ala9tea3x74x8n2nlyz4zj52j", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "22" - }, - "cosmosvalcons10qj9cj3dxecyu826gaw72ylwum96jkkh5xjn2j": { - "address": "cosmosvalcons10qj9cj3dxecyu826gaw72ylwum96jkkh5xjn2j", - "start_height": "12", - "index_offset": "37", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1ekx8n2y3x9qq34c2uy8fdh400hp8msqufqgdhe": { - "address": "cosmosvalcons1ekx8n2y3x9qq34c2uy8fdh400hp8msqufqgdhe", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1urnp7yp6u27nut8kvsrapgmmvk8sh6u5l2nyes": { - "address": "cosmosvalcons1urnp7yp6u27nut8kvsrapgmmvk8sh6u5l2nyes", - "start_height": "5", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1alxfwr8v98tw6tm4jhgdu2hu5gy0umv88caft8": { - "address": "cosmosvalcons1alxfwr8v98tw6tm4jhgdu2hu5gy0umv88caft8", - "start_height": "47", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons17z20092e9s2ttlzkpzv209dsxsxs946jk0ph4e": { - "address": "cosmosvalcons17z20092e9s2ttlzkpzv209dsxsxs946jk0ph4e", - "start_height": "1", - "index_offset": "7", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "7" - }, - "cosmosvalcons1zyp4lvynuuz8vzmzprpy8mxm4rkql6ry6509hk": { - "address": "cosmosvalcons1zyp4lvynuuz8vzmzprpy8mxm4rkql6ry6509hk", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons19ve7rrjrngdgf6pfaj87csf4rwykqdmhgnsd2w": { - "address": "cosmosvalcons19ve7rrjrngdgf6pfaj87csf4rwykqdmhgnsd2w", - "start_height": "2", - "index_offset": "46", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "21" - }, - "cosmosvalcons15ughagcacjqyaa0f7d28xtev88v5vh693t8f8y": { - "address": "cosmosvalcons15ughagcacjqyaa0f7d28xtev88v5vh693t8f8y", - "index_offset": "44", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "42" - }, - "cosmosvalcons14upsvttjem96xlz8rfsw4zqt234jnqy8vxuxkp": { - "address": "cosmosvalcons14upsvttjem96xlz8rfsw4zqt234jnqy8vxuxkp", - "start_height": "1", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "47" - }, - "cosmosvalcons1c2tutqjg5cqcvt6qen2x6enval6t5pyddwna5e": { - "address": "cosmosvalcons1c2tutqjg5cqcvt6qen2x6enval6t5pyddwna5e", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1mzsvp23mjrjkspddkz6nta0x7kte6a23vv0nmd": { - "address": "cosmosvalcons1mzsvp23mjrjkspddkz6nta0x7kte6a23vv0nmd", - "index_offset": "13", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "13" - }, - "cosmosvalcons1znvq8jqpwxt5hk2lg5654l7eg7kap3rpe4uu6c": { - "address": "cosmosvalcons1znvq8jqpwxt5hk2lg5654l7eg7kap3rpe4uu6c", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1fhnwxus6yyk6lman2qf9fzuqtekl7gcwhqc8q8": { - "address": "cosmosvalcons1fhnwxus6yyk6lman2qf9fzuqtekl7gcwhqc8q8", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56man4rq": { - "address": "cosmosvalcons1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56man4rq", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1kfnt5d5fcma9kh4c5jk85yu75jer72kwucvp4z": { - "address": "cosmosvalcons1kfnt5d5fcma9kh4c5jk85yu75jer72kwucvp4z", - "start_height": "48", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1elu2xlg8qw8st5nppxvgszeyzhm4ht8zhsl8cf": { - "address": "cosmosvalcons1elu2xlg8qw8st5nppxvgszeyzhm4ht8zhsl8cf", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1q9tcvremyhu80vylcpenp9str7wn0qf0sxv9ar": { - "address": "cosmosvalcons1q9tcvremyhu80vylcpenp9str7wn0qf0sxv9ar", - "start_height": "1", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1gpk39c5dc4xnevhz4c7m2sjxequw30s32598cq": { - "address": "cosmosvalcons1gpk39c5dc4xnevhz4c7m2sjxequw30s32598cq", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "18" - }, - "cosmosvalcons13y2zjpgaj07umx7a3dsg9ffhpkk22g73yzdk5r": { - "address": "cosmosvalcons13y2zjpgaj07umx7a3dsg9ffhpkk22g73yzdk5r", - "start_height": "14", - "index_offset": "35", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "34" - }, - "cosmosvalcons15cnzrhl4pe7ekkp0djmyupahdsjjmmkv0q80ee": { - "address": "cosmosvalcons15cnzrhl4pe7ekkp0djmyupahdsjjmmkv0q80ee", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons14j4mehgc448s2m7cr0uqm3pmvjxav94w28qxw8": { - "address": "cosmosvalcons14j4mehgc448s2m7cr0uqm3pmvjxav94w28qxw8", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1kses5l7n9382eay7524cmut5p7en64ldylzjw2": { - "address": "cosmosvalcons1kses5l7n9382eay7524cmut5p7en64ldylzjw2", - "start_height": "8", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "16" - }, - "cosmosvalcons1hwea4x7eagt83nvaz93q3q5gpje64nczejpn33": { - "address": "cosmosvalcons1hwea4x7eagt83nvaz93q3q5gpje64nczejpn33", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3x59pmh": { - "address": "cosmosvalcons1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3x59pmh", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons17e6r58yvwdtyrzxudfrp8gp3zk2mdxd58u87ag": { - "address": "cosmosvalcons17e6r58yvwdtyrzxudfrp8gp3zk2mdxd58u87ag", - "start_height": "1", - "index_offset": "44", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "5" - }, - "cosmosvalcons18p7qvgvjcpl85mjwtvepe9reevevnm9fv605n2": { - "address": "cosmosvalcons18p7qvgvjcpl85mjwtvepe9reevevnm9fv605n2", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons18wfnjhyqjzjpa5pgd3r5n987uet7qczjdf0rvj": { - "address": "cosmosvalcons18wfnjhyqjzjpa5pgd3r5n987uet7qczjdf0rvj", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons187wgdejp6c2h502gtkzxcpn6qgrw9q547kejc7": { - "address": "cosmosvalcons187wgdejp6c2h502gtkzxcpn6qgrw9q547kejc7", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "17" - }, - "cosmosvalcons1twyey6dyu57e7p8lahwgr9ql2pyn6774gnvtex": { - "address": "cosmosvalcons1twyey6dyu57e7p8lahwgr9ql2pyn6774gnvtex", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1twu2lvgp3erk6gups2a8nae3jdahaj2x2cmqs0": { - "address": "cosmosvalcons1twu2lvgp3erk6gups2a8nae3jdahaj2x2cmqs0", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1fuge5wmj546lq6ljv9zfzjjgknrfmngv7pt5pq": { - "address": "cosmosvalcons1fuge5wmj546lq6ljv9zfzjjgknrfmngv7pt5pq", - "index_offset": "49", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons12rjah2jl9jpqwddh20vph9yu448d76252t8yzm": { - "address": "cosmosvalcons12rjah2jl9jpqwddh20vph9yu448d76252t8yzm", - "index_offset": "49", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1rpxgsrsrx8jntwa6q9m0a4xxypnphs9znygvp6": { - "address": "cosmosvalcons1rpxgsrsrx8jntwa6q9m0a4xxypnphs9znygvp6", - "index_offset": "44", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "44" - }, - "cosmosvalcons1re5reme6kyayzfanalqm89u2r9an6wu97g0svk": { - "address": "cosmosvalcons1re5reme6kyayzfanalqm89u2r9an6wu97g0svk", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons19fa3uz9n80megf46sfu7kzepfup4mjcctf7cjl": { - "address": "cosmosvalcons19fa3uz9n80megf46sfu7kzepfup4mjcctf7cjl", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzml74vet": { - "address": "cosmosvalcons1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzml74vet", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "25" - }, - "cosmosvalcons1fv35lda8ltd6juk384yqceqalcxyfj4kplptte": { - "address": "cosmosvalcons1fv35lda8ltd6juk384yqceqalcxyfj4kplptte", - "start_height": "48", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1tftatt0lp0v59qqf449pdqar8w3yj7n7h6eekg": { - "address": "cosmosvalcons1tftatt0lp0v59qqf449pdqar8w3yj7n7h6eekg", - "start_height": "47", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons10xwf26gupjlr4xt69pl779346w7yytxha4ymw0": { - "address": "cosmosvalcons10xwf26gupjlr4xt69pl779346w7yytxha4ymw0", - "start_height": "13", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1nraptt0aagws66pcvnc92kjus460k3l09w274n": { - "address": "cosmosvalcons1nraptt0aagws66pcvnc92kjus460k3l09w274n", - "start_height": "8", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "41" - }, - "cosmosvalcons1hpwfm40p8dwmwtmhdnmazywy79uywk8xxx9cg9": { - "address": "cosmosvalcons1hpwfm40p8dwmwtmhdnmazywy79uywk8xxx9cg9", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqzhzl6w": { - "address": "cosmosvalcons1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqzhzl6w", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1fc96780mrsxn5kgplhtna40qepjgrm9wprcd0c": { - "address": "cosmosvalcons1fc96780mrsxn5kgplhtna40qepjgrm9wprcd0c", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons10t3ld5fvsvy7kye7p409he8dk5q23tep9u5whq": { - "address": "cosmosvalcons10t3ld5fvsvy7kye7p409he8dk5q23tep9u5whq", - "start_height": "2", - "index_offset": "12", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "7" - }, - "cosmosvalcons1ty5s8h0gwtc285mnxwq43cyt2s58g25gfu8xm6": { - "address": "cosmosvalcons1ty5s8h0gwtc285mnxwq43cyt2s58g25gfu8xm6", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "47" - }, - "cosmosvalcons1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4f3ekeh": { - "address": "cosmosvalcons1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4f3ekeh", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1sfewn0rgaw0fqw8lks6ygek6ulmcy3nm4mt3g5": { - "address": "cosmosvalcons1sfewn0rgaw0fqw8lks6ygek6ulmcy3nm4mt3g5", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1pv9f0ze6vmq3qvy29fywmj2eh2cpneymxky07j": { - "address": "cosmosvalcons1pv9f0ze6vmq3qvy29fywmj2eh2cpneymxky07j", - "start_height": "48", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1pjwsvz9745jftv0p0c99t36m6kf9e8rxc2k8gj": { - "address": "cosmosvalcons1pjwsvz9745jftv0p0c99t36m6kf9e8rxc2k8gj", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1glku8mx4nzp5crkjt7px9lfe4flfge3zcajzul": { - "address": "cosmosvalcons1glku8mx4nzp5crkjt7px9lfe4flfge3zcajzul", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons12q3w0j5hp023hdjafgc357hy7kkha296cjp2jm": { - "address": "cosmosvalcons12q3w0j5hp023hdjafgc357hy7kkha296cjp2jm", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1tz087eh88lqkesr77yl6ys9dw95qysfq6wwa20": { - "address": "cosmosvalcons1tz087eh88lqkesr77yl6ys9dw95qysfq6wwa20", - "start_height": "7", - "index_offset": "42", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "42" - }, - "cosmosvalcons1nxr7alffy7zt9gg4285a67ts977pcgaarr7lgd": { - "address": "cosmosvalcons1nxr7alffy7zt9gg4285a67ts977pcgaarr7lgd", - "start_height": "48", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar5y5n7y": { - "address": "cosmosvalcons1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar5y5n7y", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1edwe9quhqnxa4yvqu2ks656guv6rjzhtgr7r6g": { - "address": "cosmosvalcons1edwe9quhqnxa4yvqu2ks656guv6rjzhtgr7r6g", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1x4yzfjt777agvsfz6cskjst7v7k42xc69qcru2": { - "address": "cosmosvalcons1x4yzfjt777agvsfz6cskjst7v7k42xc69qcru2", - "index_offset": "6", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "6" - }, - "cosmosvalcons1864wj4twqatq54rrxl5jmfey55tmh0hveu2vyu": { - "address": "cosmosvalcons1864wj4twqatq54rrxl5jmfey55tmh0hveu2vyu", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zzp9hc2": { - "address": "cosmosvalcons1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zzp9hc2", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1sxmqgulmqw6nxw4f9lxt565hzyj246nj9em88q": { - "address": "cosmosvalcons1sxmqgulmqw6nxw4f9lxt565hzyj246nj9em88q", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "25" - }, - "cosmosvalcons1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx5uzsa7": { - "address": "cosmosvalcons1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx5uzsa7", - "start_height": "2", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1zf34ku927tasyr9fswhasvqt0x49janzmpm3cd": { - "address": "cosmosvalcons1zf34ku927tasyr9fswhasvqt0x49janzmpm3cd", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1z7ruhrtfg8v2xv8egfyxldt2xaygspykp95zz7": { - "address": "cosmosvalcons1z7ruhrtfg8v2xv8egfyxldt2xaygspykp95zz7", - "start_height": "2", - "index_offset": "4", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr338lh7": { - "address": "cosmosvalcons1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr338lh7", - "index_offset": "9", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons12nv5therrzkwjmvrmmnng6uqk2d8u6y70wempr": { - "address": "cosmosvalcons12nv5therrzkwjmvrmmnng6uqk2d8u6y70wempr", - "index_offset": "46", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "44" - }, - "cosmosvalcons1wkt8xe20zdph4ak9vqx2supe3v2gq3wyr7dmne": { - "address": "cosmosvalcons1wkt8xe20zdph4ak9vqx2supe3v2gq3wyr7dmne", - "index_offset": "3", - "jailed_until": "9999-12-31T23:59:59Z", - "tombstoned": true - }, - "cosmosvalcons1sp9hxsl3s8pyj3cs84acgwrkxl85yk88wm5cf7": { - "address": "cosmosvalcons1sp9hxsl3s8pyj3cs84acgwrkxl85yk88wm5cf7", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1chjcdfygnalpfjrjc8ku8vknx782xf7em93zkx": { - "address": "cosmosvalcons1chjcdfygnalpfjrjc8ku8vknx782xf7em93zkx", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "47" - }, - "cosmosvalcons1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkaw34gh": { - "address": "cosmosvalcons1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkaw34gh", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1mh9g99ncua6cecyd5meepx9hecyy3e24y7rey9": { - "address": "cosmosvalcons1mh9g99ncua6cecyd5meepx9hecyy3e24y7rey9", - "index_offset": "49", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "47" - }, - "cosmosvalcons17da97e4gq5p2zavzcd0zmsh7ez540j0ctxc8nz": { - "address": "cosmosvalcons17da97e4gq5p2zavzcd0zmsh7ez540j0ctxc8nz", - "start_height": "1", - "index_offset": "1", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1zlyfewtaxumsyj34fkml4t54yvhqcls4g7u5nm": { - "address": "cosmosvalcons1zlyfewtaxumsyj34fkml4t54yvhqcls4g7u5nm", - "index_offset": "6", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "6" - }, - "cosmosvalcons1f2sunjkaqyu2wr9jupyjkl7qhlnesag7egqylw": { - "address": "cosmosvalcons1f2sunjkaqyu2wr9jupyjkl7qhlnesag7egqylw", - "index_offset": "43", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "43" - }, - "cosmosvalcons12ud83clhrm4jemkal6v0489e0cdm8x0l6frftz": { - "address": "cosmosvalcons12ud83clhrm4jemkal6v0489e0cdm8x0l6frftz", - "index_offset": "9", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1twg3k83aluz6nsqt09pa246rg5wg6fhwdlrqd5": { - "address": "cosmosvalcons1twg3k83aluz6nsqt09pa246rg5wg6fhwdlrqd5", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1dn2s4tgdyjcgpcq6pfw5shzry50veuh8vcq4zc": { - "address": "cosmosvalcons1dn2s4tgdyjcgpcq6pfw5shzry50veuh8vcq4zc", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1n9dqelmmf5kfysk24m6chqfdcgz6r75u0ux4w9": { - "address": "cosmosvalcons1n9dqelmmf5kfysk24m6chqfdcgz6r75u0ux4w9", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "7" - }, - "cosmosvalcons1c08mlht3skve88xx8eth4zgtpr2nhjfawyw6qj": { - "address": "cosmosvalcons1c08mlht3skve88xx8eth4zgtpr2nhjfawyw6qj", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1evys94earewfdh658d0u67j28lq2ltezjkm72y": { - "address": "cosmosvalcons1evys94earewfdh658d0u67j28lq2ltezjkm72y", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1lamxh5pswk923tm9mtmvd4t6pqru5cdtjnrxuu": { - "address": "cosmosvalcons1lamxh5pswk923tm9mtmvd4t6pqru5cdtjnrxuu", - "start_height": "1", - "index_offset": "46", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "24" - }, - "cosmosvalcons1f2pvewnws73u0z5wsfmv5uqudwxl6jupcua6t0": { - "address": "cosmosvalcons1f2pvewnws73u0z5wsfmv5uqudwxl6jupcua6t0", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2esn3du": { - "address": "cosmosvalcons1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2esn3du", - "start_height": "1", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2k77jcj": { - "address": "cosmosvalcons1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2k77jcj", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons1hc5k2vf82jswmnlfrrav6u2kf6rn39mppx25wn": { - "address": "cosmosvalcons1hc5k2vf82jswmnlfrrav6u2kf6rn39mppx25wn", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1l2mzrv0nvs75mjj5nzz966jxklfn9wt6l55sw2": { - "address": "cosmosvalcons1l2mzrv0nvs75mjj5nzz966jxklfn9wt6l55sw2", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1q54ra6ur0wgyamdtgkn7fnmawf00tcj6cvttsq": { - "address": "cosmosvalcons1q54ra6ur0wgyamdtgkn7fnmawf00tcj6cvttsq", - "index_offset": "3", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons193pvwgxpxnd6tgz0gtyl00dq8r3ygeflzs60pf": { - "address": "cosmosvalcons193pvwgxpxnd6tgz0gtyl00dq8r3ygeflzs60pf", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1fqmkps3v8evytw9jmpg3g83a6s0fy8m2xw9kpa": { - "address": "cosmosvalcons1fqmkps3v8evytw9jmpg3g83a6s0fy8m2xw9kpa", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1mmjkdjsqluxlggcl082j977kv8fwp4u0p4fshs": { - "address": "cosmosvalcons1mmjkdjsqluxlggcl082j977kv8fwp4u0p4fshs", - "start_height": "12", - "index_offset": "37", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "36" - }, - "cosmosvalcons1744t93tc6ulm87ccsc47mkl30qz65n8pmtgywr": { - "address": "cosmosvalcons1744t93tc6ulm87ccsc47mkl30qz65n8pmtgywr", - "start_height": "7", - "index_offset": "5", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7f3wcwa": { - "address": "cosmosvalcons1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7f3wcwa", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - }, - "cosmosvalcons18fkw6s4hnj2llxljrkleetgns2y0h0vjeq3jem": { - "address": "cosmosvalcons18fkw6s4hnj2llxljrkleetgns2y0h0vjeq3jem", - "start_height": "47", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1j7352v6z3xcf9y5qusgdxectvn8dv962h27ny2": { - "address": "cosmosvalcons1j7352v6z3xcf9y5qusgdxectvn8dv962h27ny2", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta96zmmy": { - "address": "cosmosvalcons1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta96zmmy", - "start_height": "1", - "index_offset": "7", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons178pm30fcgrt5654czwr8nlex050m6y6050c02z": { - "address": "cosmosvalcons178pm30fcgrt5654czwr8nlex050m6y6050c02z", - "start_height": "8", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "4" - }, - "cosmosvalcons1l4dqy53d57ul42xd8wzs5zxk4ywkc7axqkmnn5": { - "address": "cosmosvalcons1l4dqy53d57ul42xd8wzs5zxk4ywkc7axqkmnn5", - "start_height": "2", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1yr5ztk7t7w329lllmylgz6wnfk664qu0xdmvm3": { - "address": "cosmosvalcons1yr5ztk7t7w329lllmylgz6wnfk664qu0xdmvm3", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1xnh4mumajk76tlnsp8d3d95r7hjnt4drueld2m": { - "address": "cosmosvalcons1xnh4mumajk76tlnsp8d3d95r7hjnt4drueld2m", - "start_height": "49", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1f3j0m80ey8ujgfg783838jqnuw63h3v0yvqnpu": { - "address": "cosmosvalcons1f3j0m80ey8ujgfg783838jqnuw63h3v0yvqnpu", - "start_height": "4", - "index_offset": "45", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "45" - }, - "cosmosvalcons13jxw6xalnpvapujvmm6mc6qn3dk4sn6ktfuppf": { - "address": "cosmosvalcons13jxw6xalnpvapujvmm6mc6qn3dk4sn6ktfuppf", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "3" - }, - "cosmosvalcons1nas3l2avd9hymfeqznjmrw7sde8ual5k5f5hvz": { - "address": "cosmosvalcons1nas3l2avd9hymfeqznjmrw7sde8ual5k5f5hvz", - "start_height": "2", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "24" - }, - "cosmosvalcons1g58m70guf3p7y6hhf5trqmhzpzn99rvr8mla5z": { - "address": "cosmosvalcons1g58m70guf3p7y6hhf5trqmhzpzn99rvr8mla5z", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1wr9032gj6t9s9schc5vnwe9kkee7qkgpmawqtu": { - "address": "cosmosvalcons1wr9032gj6t9s9schc5vnwe9kkee7qkgpmawqtu", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons13cydnwjmscxtqtjywk9atr9uwlm6703mlvr3n3": { - "address": "cosmosvalcons13cydnwjmscxtqtjywk9atr9uwlm6703mlvr3n3", - "start_height": "8", - "index_offset": "41", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "16" - }, - "cosmosvalcons15qje22esqaz79y27940s3ng7r7afx3vv8c7j72": { - "address": "cosmosvalcons15qje22esqaz79y27940s3ng7r7afx3vv8c7j72", - "start_height": "1", - "index_offset": "47", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1478sx3zdfylsts5sus5rlz4dgvyvacqpdlsm6m": { - "address": "cosmosvalcons1478sx3zdfylsts5sus5rlz4dgvyvacqpdlsm6m", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "49" - }, - "cosmosvalcons1hyzzthl6vy5vjucaalz9w6fkyqne5p55fe4j85": { - "address": "cosmosvalcons1hyzzthl6vy5vjucaalz9w6fkyqne5p55fe4j85", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "1" - }, - "cosmosvalcons1eumpungfa2vmx20e27wnu6t0rtmrlmv3unjt4s": { - "address": "cosmosvalcons1eumpungfa2vmx20e27wnu6t0rtmrlmv3unjt4s", - "index_offset": "9", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "9" - }, - "cosmosvalcons18r683wlut54pd8sjzz45ujq8nu4wfr65s5sce8": { - "address": "cosmosvalcons18r683wlut54pd8sjzz45ujq8nu4wfr65s5sce8", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "2" - }, - "cosmosvalcons1dtdk5uytf6kv668r6l6d6cf947mdu38f5hwyap": { - "address": "cosmosvalcons1dtdk5uytf6kv668r6l6d6cf947mdu38f5hwyap", - "index_offset": "50", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "50" - }, - "cosmosvalcons1sjg96xpaa2cayeym6w3a2t38n7gm9zcsj94xgy": { - "address": "cosmosvalcons1sjg96xpaa2cayeym6w3a2t38n7gm9zcsj94xgy", - "index_offset": "2", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1n9lefg5g0mz4glppdt994nsxzg6pxscq20ppwj": { - "address": "cosmosvalcons1n9lefg5g0mz4glppdt994nsxzg6pxscq20ppwj", - "index_offset": "40", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "37" - }, - "cosmosvalcons152vx4n8032chkrgh97h05rs3mtdz3nuc2ke0hg": { - "address": "cosmosvalcons152vx4n8032chkrgh97h05rs3mtdz3nuc2ke0hg", - "index_offset": "4", - "jailed_until": "1970-01-01T00:00:00Z" - }, - "cosmosvalcons1luynvvt3qre3hzald2tdjtah6vw00hdcp4l3d3": { - "address": "cosmosvalcons1luynvvt3qre3hzald2tdjtah6vw00hdcp4l3d3", - "start_height": "1", - "index_offset": "48", - "jailed_until": "1970-01-01T00:00:00Z", - "missed_blocks_counter": "48" - } - }, - "missed_blocks": { - "cosmosvalcons1r5tg7kujl8x77c84dedr2z9agsjyp8tqq8hrc8": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - } - ], - "cosmosvalcons1r4czpmmu87t7zhlh34zrzna9gkex4ap5eqd50s": [], - "cosmosvalcons10cl6sallgwf882apcyagjqa2lx4j8592f4fxgm": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y5mms0qg": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1q9tcvremyhu80vylcpenp9str7wn0qf0sxv9ar": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons1zjw6x8t95zuaxprcyl0x6l7u0ag6626v0fzay6": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1ndff2ha25wm2nhunxgfrzlnhvc5j06zve6f54r": [], - "cosmosvalcons14qy520rhr0qytqxdtsjsu9rgw708n2w6ex2jmj": [ - { - "index": "13", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar5y5n7y": [], - "cosmosvalcons1m8gpgklc8a2yla9ah9y8mlu226n0mu4ym3qdze": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - } - ], - "cosmosvalcons172lmu2psqlkxkthpr46h2ewjffte7lhl2f7nt6": [ - { - "index": "14", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "45", - "missed": true - } - ], - "cosmosvalcons1q9ed2n5wvzcrymaqltypazqzd2xv8d5alnqqle": [ - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1jf2wka8xprke2q6qxq2vz3khe4mqxv75jvgj02": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - } - ], - "cosmosvalcons1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a7ha5z7": [ - { - "index": "9", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "25", - "missed": true - } - ], - "cosmosvalcons1c08mlht3skve88xx8eth4zgtpr2nhjfawyw6qj": [ - { - "index": "8", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1nfurwjwfy3zhw0g9eqcclzeejf9nqw62ewmwyr": [ - { - "index": "0", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "36", - "missed": true - } - ], - "cosmosvalcons1hyv7jjh3kswlfc6nh0xp545rl5ttty2xe7j8l3": [], - "cosmosvalcons19wgl6sjkktp7mysmmtzqnecd5v2xn7gs7022a6": [ - { - "index": "6", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "45", - "missed": true - } - ], - "cosmosvalcons1trkrhq6mxwktf24u8jepelvumpd9l6lehelksx": [ - { - "index": "27", - "missed": true - } - ], - "cosmosvalcons1dtdk5uytf6kv668r6l6d6cf947mdu38f5hwyap": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1n8emgp25g5wh4d9204lpd06gsznurtlpu09dtl": [ - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "36", - "missed": true - } - ], - "cosmosvalcons1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux0fv6ry": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtp8l6ug4": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - } - ], - "cosmosvalcons18056m2nw355q2tjmvdslp9fqadmca5up2fcnvw": [], - "cosmosvalcons1sxmqgulmqw6nxw4f9lxt565hzyj246nj9em88q": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons14se5hzhf43yk83pkztukhtlfu683s4ktcqzgvs": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons16xal57nga5gd2qxkz869qv7hm20xn0rkyfusws": [ - { - "index": "5", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons14jvurctjcvs69hlppa0dkjplczns7zlqthruvy": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - } - ], - "cosmosvalcons14lwqx5380234f0fshaycluz08yw74chl9wupjl": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "35", - "missed": true - } - ], - "cosmosvalcons1kses5l7n9382eay7524cmut5p7en64ldylzjw2": [ - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - } - ], - "cosmosvalcons1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76v6c2hww": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons1qw9wqlz92hj8y6mcj24l6wu68er03njuzuu92s": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1zyp4lvynuuz8vzmzprpy8mxm4rkql6ry6509hk": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zzp9hc2": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1vjj3g3vkh56g04yqqsdn0yxcul9pve2rt04f87": [], - "cosmosvalcons1mfldj5ly78eg08sd2k3nygggjx765vvwr3sa2u": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1gd779gn33yuxxla5pm5dphglcyx4ulzd86ldf8": [ - { - "index": "0", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "24", - "missed": true - } - ], - "cosmosvalcons12q3w0j5hp023hdjafgc357hy7kkha296cjp2jm": [ - { - "index": "13", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0v4sfcv": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1sjg96xpaa2cayeym6w3a2t38n7gm9zcsj94xgy": [], - "cosmosvalcons13296rs6uwadjwya2l2uc2jzxgyllcjm2sl0ym0": [ - { - "index": "15", - "missed": true - }, - { - "index": "22", - "missed": true - } - ], - "cosmosvalcons1h6j4lyvuenmz9m7vq3hler8j7pg5ldpe6gpq90": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1mh9g99ncua6cecyd5meepx9hecyy3e24y7rey9": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1qqe0t0j86umq0379kjcmjg00yd6ddrdw9cehas": [], - "cosmosvalcons1q55pmsr0wnpzlcx25p9vqde6c52ekjnvysqusa": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkjpwd47": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons12ud83clhrm4jemkal6v0489e0cdm8x0l6frftz": [], - "cosmosvalcons1707yw2jgerkawrdyylsj4vll8k2ww5evjmxc5a": [ - { - "index": "2", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1qy0qwzljplfauvyhgayw6nxte2zxujh4658x9s": [], - "cosmosvalcons1glku8mx4nzp5crkjt7px9lfe4flfge3zcajzul": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons12f4fpl936ld8c64dxqgwv65p42na8dcnaz0hkw": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - } - ], - "cosmosvalcons1dnt8cpf6lwldf4r99n03kuv8fqwfqkfc4ndrkr": [], - "cosmosvalcons17er26f88ee6l369a2qk7xmnt248gqtucyn7vxs": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - } - ], - "cosmosvalcons1zscesuffz58dc0lq7yy6n6z3j5fhkr3du7aulk": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1zah0g92ytwdvpchd3sceuanu7knhtu22yt5z5y": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons14rhly0ayx5ewyldmrp8kn564wnn8aascwe6d59": [ - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons16rv5x3545upw3qgemu6kz0cjd36lhvz2k2cpar": [ - { - "index": "2", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons138ueargdn7h3qhwdpvusu9uduacvm393y0rccz": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - } - ], - "cosmosvalcons13mztfedkzpz634g7u5fh8henfmvzyrfflw7r8u": [], - "cosmosvalcons15pl2c2umxszwar75aft99kns0ltmpepnzxvvya": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - } - ], - "cosmosvalcons14q9rupnazu0mmkjd9skpn2zdfs8d0hlgx9xl07": [ - { - "index": "1", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1xw7mpsuf4vma4a2thsad2623wjcgcy6u8yy8sa": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1fqmkps3v8evytw9jmpg3g83a6s0fy8m2xw9kpa": [ - { - "index": "10", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "36", - "missed": true - } - ], - "cosmosvalcons1twg3k83aluz6nsqt09pa246rg5wg6fhwdlrqd5": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56man4rq": [], - "cosmosvalcons1h8wfu2kqcjeev96yddv3nj9r4q003essj2vrm3": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - } - ], - "cosmosvalcons17da97e4gq5p2zavzcd0zmsh7ez540j0ctxc8nz": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons1l5d2lg5hku0m4u8mh866zhjcy2dekpk55quww3": [ - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1p0u57pfl53kwefqrrr652pd3sm2hhv9gznzvw7": [], - "cosmosvalcons193pvwgxpxnd6tgz0gtyl00dq8r3ygeflzs60pf": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1n20sc20x53kyms9vhrxlr8r79hptq3p2efwm48": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7tn52wp": [ - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1gfta9y4c4j5dd08mju2zf23cmdn7ylauvct35q": [ - { - "index": "15", - "missed": true - } - ], - "cosmosvalcons1fc96780mrsxn5kgplhtna40qepjgrm9wprcd0c": [], - "cosmosvalcons10qj9cj3dxecyu826gaw72ylwum96jkkh5xjn2j": [ - { - "index": "3", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "18", - "missed": true - } - ], - "cosmosvalcons1478sx3zdfylsts5sus5rlz4dgvyvacqpdlsm6m": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1zukq6nknswp76ckcj5s9rnvmye974n7c3mmhnd": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "3", - "missed": true - } - ], - "cosmosvalcons1yr5ztk7t7w329lllmylgz6wnfk664qu0xdmvm3": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1ylf26t6vhvugawg87328ng2ug4d8f25s4pxn42": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - } - ], - "cosmosvalcons18d56e7qz5869wegeca967hrxrmfduxdenqzjcz": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1ellx23lw5uxmdnyjpnn03expxvu89kd6htl8jx": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - } - ], - "cosmosvalcons1eccz4hnumvgsqzpfgmvhc5vwh4ugptm56yyx9f": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1x4yzfjt777agvsfz6cskjst7v7k42xc69qcru2": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - } - ], - "cosmosvalcons1x72py7gr6pd72ch7u380ay04t9mhf3fkgur5k8": [], - "cosmosvalcons1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7uajcn9": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1k7dl7gc3umxp45u8m8zc6evvus2gvjvcagsclr": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnf22uec": [], - "cosmosvalcons10gu52rf3d0z0py8d0x37r058qh9fgdgg9nahwl": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons15jcgjq7sc62rj4s0dlm4sapdcgw06jfuysh66q": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - } - ], - "cosmosvalcons1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3x59pmh": [ - { - "index": "16", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1pv9f0ze6vmq3qvy29fywmj2eh2cpneymxky07j": [], - "cosmosvalcons1znvpcj20duymyac6cl4r8kcf827aqu60amp48q": [], - "cosmosvalcons1yalqz5m4qcjtss37pdnvalz5kaws3yjy3he4fv": [ - { - "index": "1", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqzhzl6w": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1eumpungfa2vmx20e27wnu6t0rtmrlmv3unjt4s": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - } - ], - "cosmosvalcons1ll2f2v79ssg5teg5trglr0wecm877aprwzvqh9": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "31", - "missed": true - } - ], - "cosmosvalcons1adwsqn58aype530jae9qrwknsxyf3wmwuynr3s": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons10xwf26gupjlr4xt69pl779346w7yytxha4ymw0": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons10t3ld5fvsvy7kye7p409he8dk5q23tep9u5whq": [ - { - "index": "2", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - } - ], - "cosmosvalcons13y2zjpgaj07umx7a3dsg9ffhpkk22g73yzdk5r": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - } - ], - "cosmosvalcons1chjcdfygnalpfjrjc8ku8vknx782xf7em93zkx": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1z7ruhrtfg8v2xv8egfyxldt2xaygspykp95zz7": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - } - ], - "cosmosvalcons18gmd4r8ydls55yvgda4d8pfandk0xem53e75t4": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1289vtnyn8vg9rwv7jdcy2ht3h68627ht5jdl32": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "38", - "missed": true - } - ], - "cosmosvalcons1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpus7r8l": [ - { - "index": "39", - "missed": true - } - ], - "cosmosvalcons13tfk4n07c9dz5swkw7vafmlrd9e0d28faef7g0": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons14e68cy8rvnmva3fzvhmq67m94zffpvnt09v3de": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1ql2jawqmha8d2xdgda7njakszmhvt75rv4zlx8": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - } - ], - "cosmosvalcons1frjkqcr3r5fpwds4kypq5e9n865qss6ujnfqrc": [ - { - "index": "5", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "21", - "missed": true - } - ], - "cosmosvalcons1tz087eh88lqkesr77yl6ys9dw95qysfq6wwa20": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - } - ], - "cosmosvalcons1dkwuxswrh5mx3mmmsny2qhwm4xtu33tynte2nf": [ - { - "index": "2", - "missed": true - }, - { - "index": "41", - "missed": true - } - ], - "cosmosvalcons1tnh79aat8d4m82pfm7gqa0z5kzzh7zty9nz93n": [ - { - "index": "1", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "43", - "missed": true - } - ], - "cosmosvalcons155znzxm9g8j53k8vyp2d5qmrkzdum4d0a2nk2a": [ - { - "index": "23", - "missed": true - } - ], - "cosmosvalcons17nckqnw09secacg9y6r7pay02nhemww69ksle3": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - } - ], - "cosmosvalcons1mcvztyynwvn7lelqx89xuzzuguhx5xm7usl4un": [ - { - "index": "22", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "42", - "missed": true - } - ], - "cosmosvalcons17z20092e9s2ttlzkpzv209dsxsxs946jk0ph4e": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - } - ], - "cosmosvalcons1ryy20he94rlaryj04mkhcj6n4dhuhcytym4g7r": [ - { - "index": "0", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - } - ], - "cosmosvalcons1twyey6dyu57e7p8lahwgr9ql2pyn6774gnvtex": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons1vsuhkup8jznqt89zgv9nw8c3u3a7l3u80lyhm6": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - } - ], - "cosmosvalcons1d5vv20893q06tx29mlqmefnyf0w3hn0v7efvph": [], - "cosmosvalcons1xau5jp7uyewxcwg9tzwsxm895v3mf0fn04azmn": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7l4x75dl": [ - { - "index": "8", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "37", - "missed": true - } - ], - "cosmosvalcons17k35dydvkrdxup6z8633k3zcc4ecmgnz23jtdd": [], - "cosmosvalcons1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7f3wcwa": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons15tf0n2rqlh49324hrn0vzmj33fr7yk9tjs0up2": [ - { - "index": "26", - "missed": true - }, - { - "index": "44", - "missed": true - } - ], - "cosmosvalcons1rpxgsrsrx8jntwa6q9m0a4xxypnphs9znygvp6": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - } - ], - "cosmosvalcons1g58m70guf3p7y6hhf5trqmhzpzn99rvr8mla5z": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1fhnwxus6yyk6lman2qf9fzuqtekl7gcwhqc8q8": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1terlqq72gje366346skcmzfgg4lqypf579w83k": [ - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1znvq8jqpwxt5hk2lg5654l7eg7kap3rpe4uu6c": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1hyzzthl6vy5vjucaalz9w6fkyqne5p55fe4j85": [ - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons17qavkakyqgh62k39frjf5v9pj0c78m2daks0a9": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1kjupa2w6rlhzj9fjxz35m02g2wpz790fuauq0q": [ - { - "index": "0", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - } - ], - "cosmosvalcons1hwea4x7eagt83nvaz93q3q5gpje64nczejpn33": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - } - ], - "cosmosvalcons1eausepxh2ujd0lpjup9vahjekpz9as2fgn2vdk": [], - "cosmosvalcons178gvnxtnq2n4m23492m7agshjv3zgzy3zzg47d": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons14dp6lpg8dqs4e0aq34vhcwpxt37nltefr2w0fk": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - } - ], - "cosmosvalcons16v3h2mggt8tnkxp0vq5tq25fhr3knvf4rfjxlx": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "41", - "missed": true - } - ], - "cosmosvalcons1up7x3srs54xhq897rlda86hdsf4sy7ncez37jn": [ - { - "index": "5", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "32", - "missed": true - } - ], - "cosmosvalcons12k6u60mgp8wldpz2xs2u3p3skmghtrjy5etjdq": [], - "cosmosvalcons1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2k77jcj": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1vfcm9c4psqrkv9zecgjw7zxvw2jnpe737eaneg": [ - { - "index": "16", - "missed": true - }, - { - "index": "26", - "missed": true - } - ], - "cosmosvalcons13jxw6xalnpvapujvmm6mc6qn3dk4sn6ktfuppf": [ - { - "index": "3", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4g2ureq": [], - "cosmosvalcons14kdxam68sthcd72526kc5ea42hfq5c2ga5v908": [ - { - "index": "14", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "43", - "missed": true - } - ], - "cosmosvalcons1hpwfm40p8dwmwtmhdnmazywy79uywk8xxx9cg9": [ - { - "index": "27", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyuhga22w": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons187wgdejp6c2h502gtkzxcpn6qgrw9q547kejc7": [ - { - "index": "1", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1f2sunjkaqyu2wr9jupyjkl7qhlnesag7egqylw": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - } - ], - "cosmosvalcons1nz5hp6p6wn4fvnaxe9x6fq35daamxvhh6ze2pt": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons14upsvttjem96xlz8rfsw4zqt234jnqy8vxuxkp": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1hxdqddf3u8vjm080ytpe959uktn4axdapkmfhd": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - } - ], - "cosmosvalcons1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wwhy7vf": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1uuk9ewj0532rzlhlg86tserdxvtnm3kqm3dtwu": [ - { - "index": "19", - "missed": true - }, - { - "index": "38", - "missed": true - } - ], - "cosmosvalcons1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwc2lxm7": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - } - ], - "cosmosvalcons183sdz4kk0lueuxfu7zzgp8tzcjndf3pflk3e02": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons12rjah2jl9jpqwddh20vph9yu448d76252t8yzm": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1n3lnhxzzm7ntheu78h6v4zag7zmrlp486457fr": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1fhpyqq3eex5zcctlgsxj3s3dgz64am96pv0u6u": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons158hwrawjlg586d47zl4xk9kg3em02vyppstqwv": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "40", - "missed": true - } - ], - "cosmosvalcons1c2tutqjg5cqcvt6qen2x6enval6t5pyddwna5e": [ - { - "index": "16", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "43", - "missed": true - } - ], - "cosmosvalcons1mdes9dapqu6vr094qc6wyhd9jt7qfwvjm5cyw3": [ - { - "index": "23", - "missed": true - } - ], - "cosmosvalcons1awyus34e6laq3zxqsrv283w6fgn8w62z8f2w7l": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1z6f7gdevn6dfvpls7tlqmqmzr54le7a4avumjr": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - } - ], - "cosmosvalcons1s6sl7pyvn33lptf7edmux0gex06ffzjz8l2hlr": [ - { - "index": "10", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1ng7vpl5wh98pshfef327gfnzyrwh6z4e8869pm": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1hsq728kpcxgr77ncj8asxa0383pyx7vqpf87tj": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1a0jdqzvk078d6486vuxdr5d0yp6rgluem5sadp": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1dzuk49ssprfz3ala9tea3x74x8n2nlyz4zj52j": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons13w024ysyklmnrq9c6udp98qx93jqynhggkk3rp": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - } - ], - "cosmosvalcons1evqmj6ahqf76keas4ymhvf4r992kg7wrvygqrw": [ - { - "index": "1", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "36", - "missed": true - } - ], - "cosmosvalcons1mmjkdjsqluxlggcl082j977kv8fwp4u0p4fshs": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - } - ], - "cosmosvalcons1elu2xlg8qw8st5nppxvgszeyzhm4ht8zhsl8cf": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkaw34gh": [], - "cosmosvalcons1q54ra6ur0wgyamdtgkn7fnmawf00tcj6cvttsq": [], - "cosmosvalcons128xc6r596pllf46ev2cpaetcujfgmhay7tzcwd": [], - "cosmosvalcons1ng5m6spxngyne4qzce35fdg0whl0yqgv5c0vte": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - } - ], - "cosmosvalcons1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8pce0y2": [], - "cosmosvalcons15zqzxj663h8g8naxyz324j2rpd3rnw4ravpspc": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta96zmmy": [], - "cosmosvalcons1hc5k2vf82jswmnlfrrav6u2kf6rn39mppx25wn": [], - "cosmosvalcons1rq7tvegh0yqan5fpp90rya7q9lks5nyxw0kdej": [ - { - "index": "33", - "missed": true - }, - { - "index": "43", - "missed": true - } - ], - "cosmosvalcons1864wj4twqatq54rrxl5jmfey55tmh0hveu2vyu": [ - { - "index": "35", - "missed": true - }, - { - "index": "40", - "missed": true - } - ], - "cosmosvalcons1gayzja3zz6unep8ftnpunt2wefazs3jhd5caas": [ - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "13", - "missed": true - } - ], - "cosmosvalcons1wr9032gj6t9s9schc5vnwe9kkee7qkgpmawqtu": [], - "cosmosvalcons13spl9rpkd0wd9c32mpsd9h6phwwnxu3uzvy8tm": [], - "cosmosvalcons1zu50umwgah6jhx07sw04ry0pv7fnvkpj25q9lh": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons18nag9zrh49uaxypx83fmlz85umq0t9j79nzvqa": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons1v08dcmtc5f444sxqfvqv8mxdclmc2759mh75r7": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - } - ], - "cosmosvalcons1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8e7x7qv": [ - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - } - ], - "cosmosvalcons1h7nkedpkxm0t752j0q88rhgwjn94p4y29hqdn2": [], - "cosmosvalcons16ll03qy5htuech4u0z432zertwhyxynl9khkh2": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - } - ], - "cosmosvalcons1tftatt0lp0v59qqf449pdqar8w3yj7n7h6eekg": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1sfewn0rgaw0fqw8lks6ygek6ulmcy3nm4mt3g5": [], - "cosmosvalcons1j7352v6z3xcf9y5qusgdxectvn8dv962h27ny2": [ - { - "index": "17", - "missed": true - }, - { - "index": "28", - "missed": true - } - ], - "cosmosvalcons1kfnt5d5fcma9kh4c5jk85yu75jer72kwucvp4z": [], - "cosmosvalcons1nrugh7am9s584k6qlf5nxlpetarxs2csecvu6u": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1hu260773mytzz030tuq0kffmlyxzs7vg5wftk9": [ - { - "index": "4", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "36", - "missed": true - } - ], - "cosmosvalcons17e6r58yvwdtyrzxudfrp8gp3zk2mdxd58u87ag": [ - { - "index": "0", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "33", - "missed": true - } - ], - "cosmosvalcons1qqxeqqvjkh2ls3a0taukd8rydrqqad6975plc2": [ - { - "index": "20", - "missed": true - }, - { - "index": "42", - "missed": true - } - ], - "cosmosvalcons1re5reme6kyayzfanalqm89u2r9an6wu97g0svk": [ - { - "index": "21", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "37", - "missed": true - } - ], - "cosmosvalcons10d3vd6yx9k9ns6v82r4krm3d4ragw04c4hun22": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons10ke8m795c8svtt2h24n6dad2xp9a8mev6pk3dq": [], - "cosmosvalcons1zzey9t59j5x7j5z9f3urms7faq0gq9dw27hxcc": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons19vugh7w9vrp6x3nqzjph59zg0d28c0fkn7432d": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1t7wt4qjfsa4kncvvya5m99mq0m53n9e8q9m6p5": [], - "cosmosvalcons1jsd99e3zfrxrr3nh057u0tvmu0847zkrmzwr87": [ - { - "index": "1", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "41", - "missed": true - } - ], - "cosmosvalcons1cdvntn6mwvvv4qxnty6zp2jwvemg20yuqmdsse": [ - { - "index": "1", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "12", - "missed": true - } - ], - "cosmosvalcons1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7t0qj3k": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - } - ], - "cosmosvalcons1ptu2vxfcsyl2gpeg73ehzte7t3va459lj69slr": [ - { - "index": "10", - "missed": true - }, - { - "index": "21", - "missed": true - } - ], - "cosmosvalcons1zlyfewtaxumsyj34fkml4t54yvhqcls4g7u5nm": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - } - ], - "cosmosvalcons1wy59rs74dnqqs0xz70sn2q5hyv9yreth64pa96": [], - "cosmosvalcons1nraptt0aagws66pcvnc92kjus460k3l09w274n": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - } - ], - "cosmosvalcons13yzpngckxvtky2k25j60qxlkekx0jfauyx47zp": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons154epq0mwqz393frj38lh265h9slwdynmwkyxq9": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons144n7h95z7sz0r3k9rm3r8umkc89wt5c70h9mrh": [], - "cosmosvalcons1fdfwthdupznzgrg2d8e96ryxqz8smppe6dxr7w": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - } - ], - "cosmosvalcons12nv5therrzkwjmvrmmnng6uqk2d8u6y70wempr": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - } - ], - "cosmosvalcons1twu2lvgp3erk6gups2a8nae3jdahaj2x2cmqs0": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1dle2tkls5kffwdqhan4rs0dgckjxunfsv0l9kn": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1urnp7yp6u27nut8kvsrapgmmvk8sh6u5l2nyes": [], - "cosmosvalcons1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3gvqu70": [], - "cosmosvalcons19fa3uz9n80megf46sfu7kzepfup4mjcctf7cjl": [ - { - "index": "9", - "missed": true - } - ], - "cosmosvalcons1wzmzdml4fsakuyukmaa6qqee3g6w6qtc3szmzj": [ - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3crkzxj": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - } - ], - "cosmosvalcons1n08duqdkxwmqmtjaha236esw6r72njd2xy0fmg": [ - { - "index": "3", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "45", - "missed": true - } - ], - "cosmosvalcons1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjf35ts7": [ - { - "index": "11", - "missed": true - }, - { - "index": "16", - "missed": true - } - ], - "cosmosvalcons179uxhryqvrkxa2wtnw2cnptdt80qc24kksm9ly": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons19ve7rrjrngdgf6pfaj87csf4rwykqdmhgnsd2w": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "43", - "missed": true - } - ], - "cosmosvalcons19e3lp8kdpnzmd778gxz9hqrnaxw8spa36e4k9u": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1x9mhtyr2tak88skl0nr4lq6k7jreus6n9s59vu": [], - "cosmosvalcons1dn2s4tgdyjcgpcq6pfw5shzry50veuh8vcq4zc": [ - { - "index": "4", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "19", - "missed": true - } - ], - "cosmosvalcons1qk5quugdx54zsrteg9hpee0ke3z35meuz4rde2": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons190kcpcyvl46xva8ya8vs5wmmg4nygvuty9afhq": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons152vx4n8032chkrgh97h05rs3mtdz3nuc2ke0hg": [], - "cosmosvalcons153rklv33fjex4w7r82n9wnwxrwfgae6nn0hfc9": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - } - ], - "cosmosvalcons1x76xgyet9jkq94uqcckrwm20l85gt2kxx6qect": [ - { - "index": "11", - "missed": true - }, - { - "index": "15", - "missed": true - } - ], - "cosmosvalcons18r683wlut54pd8sjzz45ujq8nu4wfr65s5sce8": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2esn3du": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons1sjhhg2yl2cqszte7pjyrp6lx5tg383lrs4rf0f": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1qpj52qsl708aqhazaqehhjw7cdj4her9zsvuxy": [ - { - "index": "45", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons1f3j0m80ey8ujgfg783838jqnuw63h3v0yvqnpu": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - } - ], - "cosmosvalcons1jqkfaju29z0270cmm4zhygtzwjcuqjzx9d44za": [ - { - "index": "2", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1r7kh63jvjhwqraux9wtm3jat8ggm437w5lp3x2": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "27", - "missed": true - } - ], - "cosmosvalcons1dge9en6j6xl3njpkk8gvw9n326pgna44v3fc2z": [ - { - "index": "0", - "missed": true - }, - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons1wnn8xrn46u6ryq4kqf7tcf650fe2gl57uk0p3z": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons178pm30fcgrt5654czwr8nlex050m6y6050c02z": [ - { - "index": "4", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - } - ], - "cosmosvalcons1fjct2f29ymrw9h7aqffafx863c4tkxdh5c95y4": [ - { - "index": "1", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "44", - "missed": true - } - ], - "cosmosvalcons12r0m6hwrnn0jy02tnhmk328d7p68x2rnu9vxjx": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1n9lefg5g0mz4glppdt994nsxzg6pxscq20ppwj": [ - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - } - ], - "cosmosvalcons15772l3g3u9kk2qk5cmsl8tr6lshgd443cvttwn": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1qzj5kxv664trtfn4h0aznrsljtt2q95quzyrql": [ - { - "index": "2", - "missed": true - }, - { - "index": "24", - "missed": true - } - ], - "cosmosvalcons1r2ncmjrd4efnk9cjrftq7sw7347xqyu3va4mm8": [], - "cosmosvalcons18wfnjhyqjzjpa5pgd3r5n987uet7qczjdf0rvj": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1g7sk4y3cf2473ff36mlcx9ydvted9evryympt2": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - } - ], - "cosmosvalcons1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlvmv8ya": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1alxfwr8v98tw6tm4jhgdu2hu5gy0umv88caft8": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons1l4dqy53d57ul42xd8wzs5zxk4ywkc7axqkmnn5": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1557a6swa3yv3ew9yk8hcfpyqu3ce7te0dualvr": [ - { - "index": "6", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "41", - "missed": true - } - ], - "cosmosvalcons1hll5qzyzy4vrtdad5rqnf2jvf7srdnsymt6r3e": [], - "cosmosvalcons1c07ez82s6kcfyg9szzg0pgghdpl7a2k0uc46p5": [], - "cosmosvalcons1z97a2xx0rzwtfftg3k9yt693dwxx9j80749vks": [ - { - "index": "1", - "missed": true - }, - { - "index": "7", - "missed": true - } - ], - "cosmosvalcons1yt9s823gnqayrjasrra5j43pj9c48ae9gp0f5l": [ - { - "index": "13", - "missed": true - }, - { - "index": "33", - "missed": true - } - ], - "cosmosvalcons13nemj0k45u4pflkfeyey88n8u8sv4wgzklwr5r": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx5uzsa7": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons15qje22esqaz79y27940s3ng7r7afx3vv8c7j72": [], - "cosmosvalcons1yezuhyh4htsy74jkhfey9p7urgwhg00jqp7rty": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1y7m2ga0zpxr6q000a4a924fdaeycw5ed43yckr": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5ymewrp": [], - "cosmosvalcons1n5t5rr83k3emp5e446qjprj0svsh06rw33397a": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1s30d8tgwhwavwtvanggkj92quj8ucecyqlzjzv": [ - { - "index": "17", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - } - ], - "cosmosvalcons1mzsvp23mjrjkspddkz6nta0x7kte6a23vv0nmd": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - } - ], - "cosmosvalcons1rkl7umzewantxm5e8mf2l2tcxc3t7hj8djzmrw": [ - { - "index": "3", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1gpk39c5dc4xnevhz4c7m2sjxequw30s32598cq": [ - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1taucnwfqfkpq6c6y345j6h8jt5fffgla9rv3qf": [ - { - "index": "24", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4f3ekeh": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons12dh9h444s238r7hjrrd2kg6wrw4cwfk3999xl6": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1n9dqelmmf5kfysk24m6chqfdcgz6r75u0ux4w9": [ - { - "index": "1", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1k0z97vlulcmdrrajhms2x9k8srvtmxwu9l0mha": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons16tr72kn90g5zl7qhyhuqkjflejz00uzl8caasq": [ - { - "index": "21", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "44", - "missed": true - } - ], - "cosmosvalcons1qs5htj5ayfgg27t0xnng837lzllla5y235nkaw": [ - { - "index": "32", - "missed": true - }, - { - "index": "41", - "missed": true - } - ], - "cosmosvalcons1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfccuman": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons19qqvhp8aacjvxjhtgwncctmtrmjelqs62ar4s5": [ - { - "index": "31", - "missed": true - } - ], - "cosmosvalcons1g95xvy8qgzcvcl05fse0mpxzdfv3w88ts7pdc3": [ - { - "index": "28", - "missed": true - }, - { - "index": "30", - "missed": true - } - ], - "cosmosvalcons1jv7lxeryc30c0w4p7p92nxywgcnswuhshvzk3n": [ - { - "index": "3", - "missed": true - } - ], - "cosmosvalcons1744t93tc6ulm87ccsc47mkl30qz65n8pmtgywr": [ - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - } - ], - "cosmosvalcons1yva09usdkzdsqekaasgcqvm50v9vv5puyw2v3r": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - } - ], - "cosmosvalcons1xnh4mumajk76tlnsp8d3d95r7hjnt4drueld2m": [], - "cosmosvalcons1f2pvewnws73u0z5wsfmv5uqudwxl6jupcua6t0": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1sp9hxsl3s8pyj3cs84acgwrkxl85yk88wm5cf7": [ - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwghsz8u0": [ - { - "index": "4", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1t6k46y53tkcjvdttujt542pcfrwanw0flqxj2g": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1l2mzrv0nvs75mjj5nzz966jxklfn9wt6l55sw2": [ - { - "index": "11", - "missed": true - }, - { - "index": "41", - "missed": true - } - ], - "cosmosvalcons1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqpw7fvxl": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons1s728ea54m9u76dkd4x9ea3l5cvjjjkk5dgk8gv": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons15cnzrhl4pe7ekkp0djmyupahdsjjmmkv0q80ee": [ - { - "index": "18", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "41", - "missed": true - } - ], - "cosmosvalcons1kz20p7j939s8cqadmqqws80c6z93qdtyeqpz07": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons18p7qvgvjcpl85mjwtvepe9reevevnm9fv605n2": [ - { - "index": "5", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "45", - "missed": true - } - ], - "cosmosvalcons18fkw6s4hnj2llxljrkleetgns2y0h0vjeq3jem": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1f6qxvzgn7lfsvg2f86m30pshf8wuygk7w7wqdy": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1ty5s8h0gwtc285mnxwq43cyt2s58g25gfu8xm6": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1qsxjdj8z2urjdxpp7uu37pp2pf3chjjcttwfff": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn5472pf8v": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1nas3l2avd9hymfeqznjmrw7sde8ual5k5f5hvz": [ - { - "index": "2", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons15ughagcacjqyaa0f7d28xtev88v5vh693t8f8y": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - } - ], - "cosmosvalcons1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7naq267qg": [], - "cosmosvalcons17uusex4s7mds872wzvkpaty29g02n8ethl39rz": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1y30ftjd79f3p68mssyd9zug24q2avh0zkms02f": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1w2ly5qah2m47qguaukzr6xx34hszqh8um4gr3k": [], - "cosmosvalcons10ndcqfr2zwrspryphtuhq883kc49z38fwtx025": [], - "cosmosvalcons13fvz5er8rdttgtuwvcuaku00j2nw2v6kglpshq": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - } - ], - "cosmosvalcons188yd2umzwfwen7es68wrlh6auu3p8jhz78wpeq": [ - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - } - ], - "cosmosvalcons1nxr7alffy7zt9gg4285a67ts977pcgaarr7lgd": [], - "cosmosvalcons16sn6wjtd0kw4yvc7780cpayhz0x45d27cdeswx": [ - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons1zjzkk7l2jalrspy6500my8v0yy6ycz7ewnkuzu": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons1333066cp52k7fgmug2dwylafnymdxcg6zjcsez": [ - { - "index": "4", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1jp0tqhr79uwqt2rh66vcd378rrhslg49uwt39p": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - } - ], - "cosmosvalcons1evys94earewfdh658d0u67j28lq2ltezjkm72y": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - } - ], - "cosmosvalcons1luynvvt3qre3hzald2tdjtah6vw00hdcp4l3d3": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons1xec6kclrpkc4ws7lwf5j0u8207nyg6dzr6xsy0": [], - "cosmosvalcons1fv35lda8ltd6juk384yqceqalcxyfj4kplptte": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons15dt0e900x5cv9w870mevztqwy88hhu2st8xhx4": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1edwe9quhqnxa4yvqu2ks656guv6rjzhtgr7r6g": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - } - ], - "cosmosvalcons1wkt8xe20zdph4ak9vqx2supe3v2gq3wyr7dmne": [], - "cosmosvalcons1s28wuj4yrqsmjm2cckx6mu037e92up2m2w36xt": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1ktnuvrm3q8h30y3k70yzvmvwme77e9yycn5aw6": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1a4nlyf59n25qmh4myas5mdunvu9r4wlsffl40h": [ - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - } - ], - "cosmosvalcons1zf34ku927tasyr9fswhasvqt0x49janzmpm3cd": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1nmexjngk0j8jhgmywrkd7r98dgd9hzxpvcqtsq": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - } - ], - "cosmosvalcons17uqc5hqs6x7ccr7pcrafp8tfwsezt07ejfk5yc": [ - { - "index": "1", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "44", - "missed": true - } - ], - "cosmosvalcons15a8hadw3wttrnr3qx37ewmzre4w7cjmtk3uf03": [ - { - "index": "5", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "48", - "missed": true - } - ], - "cosmosvalcons19yplr2r5lu70jlymwrumzuc8tqeeu7fg5x9a4u": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzml74vet": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr338lh7": [], - "cosmosvalcons13cydnwjmscxtqtjywk9atr9uwlm6703mlvr3n3": [ - { - "index": "3", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - } - ], - "cosmosvalcons1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc9jsr7n": [ - { - "index": "4", - "missed": true - }, - { - "index": "38", - "missed": true - } - ], - "cosmosvalcons1ekx8n2y3x9qq34c2uy8fdh400hp8msqufqgdhe": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons17gpy6jzg7xdsr2xc7kweljagx4uaysxd8ddu46": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - } - ], - "cosmosvalcons1q03kay3adsttv6watm3agqktnpuuxs65vz6tu7": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - } - ], - "cosmosvalcons1pjwsvz9745jftv0p0c99t36m6kf9e8rxc2k8gj": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1fuge5wmj546lq6ljv9zfzjjgknrfmngv7pt5pq": [ - { - "index": "2", - "missed": true - }, - { - "index": "14", - "missed": true - } - ], - "cosmosvalcons1n5n6d47c4ntac509rtq3s620vmcqcf97ygkv7e": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons1e8fdmnscnm6axht542696jupnqlkm40e0jefjw": [ - { - "index": "10", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "31", - "missed": true - } - ], - "cosmosvalcons1lamxh5pswk923tm9mtmvd4t6pqru5cdtjnrxuu": [ - { - "index": "2", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "45", - "missed": true - } - ], - "cosmosvalcons1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalaatgcxv": [ - { - "index": "0", - "missed": true - } - ], - "cosmosvalcons13fyamuv3fexmuuamtgqtwkz48ynl3hd5jgmlh8": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "11", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons14j4mehgc448s2m7cr0uqm3pmvjxav94w28qxw8": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "3", - "missed": true - }, - { - "index": "4", - "missed": true - }, - { - "index": "5", - "missed": true - }, - { - "index": "6", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "9", - "missed": true - }, - { - "index": "10", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "13", - "missed": true - }, - { - "index": "14", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "17", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "19", - "missed": true - }, - { - "index": "20", - "missed": true - }, - { - "index": "21", - "missed": true - }, - { - "index": "22", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "24", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "27", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "29", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "36", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "38", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "41", - "missed": true - }, - { - "index": "42", - "missed": true - }, - { - "index": "43", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - }, - { - "index": "46", - "missed": true - }, - { - "index": "47", - "missed": true - }, - { - "index": "48", - "missed": true - }, - { - "index": "49", - "missed": true - } - ], - "cosmosvalcons147pq4rzswl76kdeyx8sc7pagf4nhjpnqmsc2hr": [ - { - "index": "0", - "missed": true - }, - { - "index": "1", - "missed": true - }, - { - "index": "2", - "missed": true - }, - { - "index": "7", - "missed": true - }, - { - "index": "8", - "missed": true - }, - { - "index": "12", - "missed": true - }, - { - "index": "15", - "missed": true - }, - { - "index": "16", - "missed": true - }, - { - "index": "18", - "missed": true - }, - { - "index": "23", - "missed": true - }, - { - "index": "25", - "missed": true - }, - { - "index": "26", - "missed": true - }, - { - "index": "28", - "missed": true - }, - { - "index": "30", - "missed": true - }, - { - "index": "31", - "missed": true - }, - { - "index": "32", - "missed": true - }, - { - "index": "33", - "missed": true - }, - { - "index": "34", - "missed": true - }, - { - "index": "35", - "missed": true - }, - { - "index": "37", - "missed": true - }, - { - "index": "39", - "missed": true - }, - { - "index": "40", - "missed": true - }, - { - "index": "44", - "missed": true - }, - { - "index": "45", - "missed": true - } - ] - } - }, - "distribution": { - "params": { - "community_tax": "0.170000000000000000", - "base_proposer_reward": "0.120000000000000000", - "bonus_proposer_reward": "0.260000000000000000", - "withdraw_addr_enabled": true - }, - "fee_pool": { - "community_pool": [ - { - "denom": "stake", - "amount": "3392935814268.044714008424704425" - } - ] - }, - "delegator_withdraw_infos": [ - { - "delegator_address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", - "withdraw_address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr" - }, - { - "delegator_address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", - "withdraw_address": "cosmos102sgufwszag3yuhtzcftpyvc8jqtqske4xug7d" - }, - { - "delegator_address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", - "withdraw_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7" - }, - { - "delegator_address": "cosmos1q3mptmfxfd03myzy847p0mrssqw0sh006086eg", - "withdraw_address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn" - }, - { - "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", - "withdraw_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh" - }, - { - "delegator_address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", - "withdraw_address": "cosmos1wve3m263mdhqqpg0yjd8vmveflugrk5dk2cr0z" - }, - { - "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", - "withdraw_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t" - }, - { - "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", - "withdraw_address": "cosmos136jetl40d2fmx3w0a0t2jj7zyp72g850c9j4ez" - }, - { - "delegator_address": "cosmos1pmjfpv056kk3jk3qfljph9fthrvqtufxe3nwml", - "withdraw_address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj" - }, - { - "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", - "withdraw_address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj" - }, - { - "delegator_address": "cosmos1zyu5csqfxaxacgwegnhrysl0val4t48kfhj9ws", - "withdraw_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9" - }, - { - "delegator_address": "cosmos1z9ns26y62x3qd3d8vs9eyxk8ndssa6gxtv2c06", - "withdraw_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7" - }, - { - "delegator_address": "cosmos1zxpp6x3x0p0gcuuazft5ycgrxsa5wwsgl854uk", - "withdraw_address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr" - }, - { - "delegator_address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", - "withdraw_address": "cosmos1jn4dp0s3ewkwarqmra50czqlm6g7cf9plthphn" - }, - { - "delegator_address": "cosmos1zs6hn5hf6qxjwmvntrzwhjkgvu963d0g8hz2z8", - "withdraw_address": "cosmos16adevt9lhqf3q4dwnmhty7ndr8478thakltsdj" - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "withdraw_address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8" - }, - { - "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "withdraw_address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd" - }, - { - "delegator_address": "cosmos1rpmw7y7cw2cu3kwsryy8z8uskn4eymh89hmq5g", - "withdraw_address": "cosmos1s7e8ukt3awex0xh6qw27pramwg3hkgeqtm0nfs" - }, - { - "delegator_address": "cosmos1rrahhju34rdpmlnaww9r5egq0su2u6f44eve27", - "withdraw_address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy" - }, - { - "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", - "withdraw_address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7" - }, - { - "delegator_address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", - "withdraw_address": "cosmos1guuf6ntr5ujawszq99gkq2gqeevz37adzp2fmy" - }, - { - "delegator_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", - "withdraw_address": "cosmos1t2uupuuf6p4xr0szwsz47gn682kw64m9wmnewf" - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "withdraw_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee" - }, - { - "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", - "withdraw_address": "cosmos1t2uupuuf6p4xr0szwsz47gn682kw64m9wmnewf" - }, - { - "delegator_address": "cosmos1ywe4qsw399leu3wza5jpny3mmrs69a3gj3hlt8", - "withdraw_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh" - }, - { - "delegator_address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", - "withdraw_address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq" - }, - { - "delegator_address": "cosmos1y78hvz86672la4agrx7n6lcmgjfgegpkldazmd", - "withdraw_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70" - }, - { - "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", - "withdraw_address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2" - }, - { - "delegator_address": "cosmos198k0ah8pnjzthydgvnq30s24s8jd3wad6puc3q", - "withdraw_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl" - }, - { - "delegator_address": "cosmos19szahkq3g937j62shd224cdtla3dv8rcwvekj9", - "withdraw_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4" - }, - { - "delegator_address": "cosmos1xfqsntajat3kv06ptad8zsqacmjrsjc2sa5ajt", - "withdraw_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7" - }, - { - "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", - "withdraw_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp" - }, - { - "delegator_address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", - "withdraw_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz" - }, - { - "delegator_address": "cosmos1xenmhldpnwfl0x8ze8qvu2qc4v58zr7qkz73sz", - "withdraw_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv" - }, - { - "delegator_address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", - "withdraw_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus" - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "withdraw_address": "cosmos12362v43p57f8dgc2dx396rpanj24j67pkcvy2h" - }, - { - "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", - "withdraw_address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp" - }, - { - "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", - "withdraw_address": "cosmos13xm9km2se2am890j398ttvyjhuh8zndwr2p68d" - }, - { - "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", - "withdraw_address": "cosmos1p7sc667drjvsjlha0nwz5zxxpt38m9dn50u925" - }, - { - "delegator_address": "cosmos18037phaq40fkqdr4pxk2jajnsq8prfyyl4tzvz", - "withdraw_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq" - }, - { - "delegator_address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", - "withdraw_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav" - }, - { - "delegator_address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", - "withdraw_address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9" - }, - { - "delegator_address": "cosmos1g04020ghngvh7lj8hmhequs5a83ly7xxyh0q8w", - "withdraw_address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj" - }, - { - "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "withdraw_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7" - }, - { - "delegator_address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", - "withdraw_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts" - }, - { - "delegator_address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", - "withdraw_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u" - }, - { - "delegator_address": "cosmos1ft0e05t5rl8ycw6a0nfa6jswvckycan4lfmv0q", - "withdraw_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j" - }, - { - "delegator_address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", - "withdraw_address": "cosmos1rz3n04g9vg0ygh3h2x96wh5ceq44pcjmt3lgag" - }, - { - "delegator_address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", - "withdraw_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah" - }, - { - "delegator_address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", - "withdraw_address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv" - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "withdraw_address": "cosmos1639hgh9ke9sxqy7kpcdcu6srk983upzjlf8mwx" - }, - { - "delegator_address": "cosmos12qsn5ukkpvy0ymcsfh85yqp4paw5ew9mcg8z0y", - "withdraw_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh" - }, - { - "delegator_address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", - "withdraw_address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck" - }, - { - "delegator_address": "cosmos12gup0vvqv32z5nvdy4ycrhp77dnax5hfmcjav0", - "withdraw_address": "cosmos18rzc0m3vlq3cwee4tckg5grjjc02gu3dv9csx2" - }, - { - "delegator_address": "cosmos12vzdkp2z75x4paa9nf0dvg638l92n5s8e0jk0w", - "withdraw_address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe" - }, - { - "delegator_address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", - "withdraw_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf" - }, - { - "delegator_address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", - "withdraw_address": "cosmos1250k2ymtkl6hf0ty6syhkxft33v580fhmr25qc" - }, - { - "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "withdraw_address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw" - }, - { - "delegator_address": "cosmos1trs75ceuvsg83y9dje9k79em4v684dm5e9ya49", - "withdraw_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9" - }, - { - "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", - "withdraw_address": "cosmos1ndjmq7ee0g2lmxrx5q0npcmv64km6hysk0qnvn" - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "withdraw_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726" - }, - { - "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "withdraw_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn" - }, - { - "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", - "withdraw_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj" - }, - { - "delegator_address": "cosmos1t58fj97xgxsvsyn89lc75hd0naa6v6c0c340cv", - "withdraw_address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc" - }, - { - "delegator_address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", - "withdraw_address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm" - }, - { - "delegator_address": "cosmos1tl9mmfa626vgrsz3plpr42cmeqcn2zugg523y3", - "withdraw_address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n" - }, - { - "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", - "withdraw_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u" - }, - { - "delegator_address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", - "withdraw_address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx" - }, - { - "delegator_address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", - "withdraw_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7" - }, - { - "delegator_address": "cosmos1vwgt6t9vd9heg0jwq6gk0x7egw4cmp4w79yuyy", - "withdraw_address": "cosmos1gkdgukkcx52r2w82q2usyncf67s30g7hmqc74n" - }, - { - "delegator_address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", - "withdraw_address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890" - }, - { - "delegator_address": "cosmos1dqukz2u9cssszcudyrjxzf47aeydmfardn09hw", - "withdraw_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09" - }, - { - "delegator_address": "cosmos1d9cqjx7xh2j23utvyrns2kgtz4w8e694vqw6h6", - "withdraw_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj" - }, - { - "delegator_address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", - "withdraw_address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q" - }, - { - "delegator_address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", - "withdraw_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc" - }, - { - "delegator_address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", - "withdraw_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v" - }, - { - "delegator_address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", - "withdraw_address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933" - }, - { - "delegator_address": "cosmos1wgslx9j6ct5pczy3h5rjl98yyn78r3sel0ulth", - "withdraw_address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266" - }, - { - "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", - "withdraw_address": "cosmos1hfjku50s3uhp66wuqexafzc3kl73z3xzhj5nqv" - }, - { - "delegator_address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", - "withdraw_address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp" - }, - { - "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "withdraw_address": "cosmos1c4w30j37que0ncnss65vr40nuy7d5msegmhgs7" - }, - { - "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", - "withdraw_address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck" - }, - { - "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", - "withdraw_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7" - }, - { - "delegator_address": "cosmos10g2yfqkuyaxgyyj7hhyswh8cmhplvpanrc9tya", - "withdraw_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer" - }, - { - "delegator_address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", - "withdraw_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7" - }, - { - "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", - "withdraw_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh" - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "withdraw_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3" - }, - { - "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", - "withdraw_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72" - }, - { - "delegator_address": "cosmos1s0r2g8pzwre6tvywfw0h8vy8qg7spd2ytfkx70", - "withdraw_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf" - }, - { - "delegator_address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", - "withdraw_address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c" - }, - { - "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", - "withdraw_address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429" - }, - { - "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", - "withdraw_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer" - }, - { - "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "withdraw_address": "cosmos1jsfel7tdxv09dm4lsqesfuhlpnlhhpeh4fdl27" - }, - { - "delegator_address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", - "withdraw_address": "cosmos1n5qqy42c6su9dv0tjpt3867mu7sdfhz6juqdns" - }, - { - "delegator_address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", - "withdraw_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82" - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "withdraw_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc" - }, - { - "delegator_address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", - "withdraw_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn" - }, - { - "delegator_address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", - "withdraw_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz" - }, - { - "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "withdraw_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n" - }, - { - "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", - "withdraw_address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je" - }, - { - "delegator_address": "cosmos1jjav2y88kx0jempjzz5jcc9y4yatkyn7xnnvsv", - "withdraw_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz" - }, - { - "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", - "withdraw_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7" - }, - { - "delegator_address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", - "withdraw_address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq" - }, - { - "delegator_address": "cosmos1n5qqy42c6su9dv0tjpt3867mu7sdfhz6juqdns", - "withdraw_address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2" - }, - { - "delegator_address": "cosmos1n44p6u7280zd652tkgyxy4jg0pp0agcvw3d2wj", - "withdraw_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs" - }, - { - "delegator_address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", - "withdraw_address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj" - }, - { - "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", - "withdraw_address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26" - }, - { - "delegator_address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", - "withdraw_address": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq" - }, - { - "delegator_address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", - "withdraw_address": "cosmos19akemnyuu0rgf2y0rrd6wrxpkyd74q5gzkgm5q" - }, - { - "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", - "withdraw_address": "cosmos1jf2rfeaukfmdhrd6prqdmqhcdyr8ezak8sm2wd" - }, - { - "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", - "withdraw_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s" - }, - { - "delegator_address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", - "withdraw_address": "cosmos13acm7994qxzmemx0fekg6s3qtagck36erqgsz8" - }, - { - "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", - "withdraw_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg" - }, - { - "delegator_address": "cosmos14t66r5m6p8n9egwdxs45ljca5p4hra74vyz9j0", - "withdraw_address": "cosmos1g04020ghngvh7lj8hmhequs5a83ly7xxyh0q8w" - }, - { - "delegator_address": "cosmos147xrqy22fnlj0ksdjlhsh5u6hz55sjn5hzzvfh", - "withdraw_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0" - }, - { - "delegator_address": "cosmos1k22576dxnqasv25wy542wc3sgj30gm4gmdpec2", - "withdraw_address": "cosmos1xfps7nht3lsfdzp092ast50aev4nhkaxtf7gh7" - }, - { - "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", - "withdraw_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9" - }, - { - "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", - "withdraw_address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s" - }, - { - "delegator_address": "cosmos1k3rapsk6gmfzeugjq5w2c4msuj7t4qhat0xn4m", - "withdraw_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3" - }, - { - "delegator_address": "cosmos1kjkf4umv6g2pperq6g74mayntlrp4a7xypuvmr", - "withdraw_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4" - }, - { - "delegator_address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", - "withdraw_address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6" - }, - { - "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", - "withdraw_address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq" - }, - { - "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "withdraw_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs" - }, - { - "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", - "withdraw_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc" - }, - { - "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "withdraw_address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q" - }, - { - "delegator_address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", - "withdraw_address": "cosmos10572shcaewknpzsj6nnrruww0049hnmjymva38" - }, - { - "delegator_address": "cosmos1cv6mc68xznavrjel5fth3vry84wnwjy29mqn33", - "withdraw_address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7" - }, - { - "delegator_address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", - "withdraw_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82" - }, - { - "delegator_address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", - "withdraw_address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm" - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "withdraw_address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp" - }, - { - "delegator_address": "cosmos1e87dgtw7cd28mt4mm3s4uaaxpapanexw9grzmg", - "withdraw_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7" - }, - { - "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "withdraw_address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m" - }, - { - "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", - "withdraw_address": "cosmos1qp6s6vzf6l0mzeglw0a9d75h7ch4w99ahux3j2" - }, - { - "delegator_address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", - "withdraw_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3" - }, - { - "delegator_address": "cosmos1ecfsusjtvmp57t8n22j9vqx75g6yxdra5vk49e", - "withdraw_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m" - }, - { - "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", - "withdraw_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn" - }, - { - "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "withdraw_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4" - }, - { - "delegator_address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", - "withdraw_address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6" - }, - { - "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", - "withdraw_address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq" - }, - { - "delegator_address": "cosmos16p082pp2g44jm5sa7x8egm2089gw908s85szsm", - "withdraw_address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4" - }, - { - "delegator_address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", - "withdraw_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy" - }, - { - "delegator_address": "cosmos1639hgh9ke9sxqy7kpcdcu6srk983upzjlf8mwx", - "withdraw_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc" - }, - { - "delegator_address": "cosmos16kuse8g39wn4yzx64shrzned2lgnk0kepcuu9t", - "withdraw_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4" - }, - { - "delegator_address": "cosmos16adevt9lhqf3q4dwnmhty7ndr8478thakltsdj", - "withdraw_address": "cosmos1njvscahg6cus5fy9k5gkq72cxj4kcahlgy00dj" - }, - { - "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", - "withdraw_address": "cosmos1npd5ddcq5cm3q938pk02dqa4te3jnfy25c5gnn" - }, - { - "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", - "withdraw_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc" - }, - { - "delegator_address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", - "withdraw_address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020" - }, - { - "delegator_address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", - "withdraw_address": "cosmos1ad5vqqf6lruklvkyyqvx3926cpjyn0wuz6ga64" - }, - { - "delegator_address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", - "withdraw_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73" - }, - { - "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", - "withdraw_address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg" - }, - { - "delegator_address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", - "withdraw_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s" - }, - { - "delegator_address": "cosmos1munf3xa25sdu0sdxwyqxhz88c8l90llmjsslvj", - "withdraw_address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa" - }, - { - "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "withdraw_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h" - }, - { - "delegator_address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", - "withdraw_address": "cosmos1njvscahg6cus5fy9k5gkq72cxj4kcahlgy00dj" - }, - { - "delegator_address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", - "withdraw_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc" - }, - { - "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "withdraw_address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz" - }, - { - "delegator_address": "cosmos1uwx5cecec8v2af2mdrq3p6gv9gtv4gza5006gx", - "withdraw_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0" - }, - { - "delegator_address": "cosmos1umn8dwc5l034syha3xehk0kmjaajdfyedajtka", - "withdraw_address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a" - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "withdraw_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt" - }, - { - "delegator_address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", - "withdraw_address": "cosmos1rs7csfnnwetmd2dcjsv4p59w3t46g77lt0wq5l" - }, - { - "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", - "withdraw_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3" - }, - { - "delegator_address": "cosmos1a2sgqjezvkgzc6vhvmevtsjh8m8rp52zcfu7ga", - "withdraw_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma" - }, - { - "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", - "withdraw_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f" - }, - { - "delegator_address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", - "withdraw_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2" - }, - { - "delegator_address": "cosmos1ah3yy9ql35jh5ehykl626e848t2rrsyze8w8nz", - "withdraw_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj" - }, - { - "delegator_address": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq", - "withdraw_address": "cosmos1jhvqn320w9nqxcs3ar7250jqg7us9vuszw9cwq" - }, - { - "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", - "withdraw_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7" - }, - { - "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", - "withdraw_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl" - }, - { - "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", - "withdraw_address": "cosmos15hqa5fj9sx7mjvmquhknrcxkxkeudguk9zpqqy" - }, - { - "delegator_address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", - "withdraw_address": "cosmos1hwt3fl2gylwdechqwq8uhmhsl04gn6ksw6lxlt" - }, - { - "delegator_address": "cosmos17m4lyrws32kta4pj2atdcc2d7z2qrwkpqk0exs", - "withdraw_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg" - }, - { - "delegator_address": "cosmos1ly9aff4ptcun94q3cs26cfzqnq59j5rw2gl89u", - "withdraw_address": "cosmos1zyu5csqfxaxacgwegnhrysl0val4t48kfhj9ws" - }, - { - "delegator_address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", - "withdraw_address": "cosmos198k0ah8pnjzthydgvnq30s24s8jd3wad6puc3q" - }, - { - "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", - "withdraw_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs" - }, - { - "delegator_address": "cosmos1l6uepmju2xg0h8rzkx8wku0hsncargw5ruhhfz", - "withdraw_address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2" - }, - { - "delegator_address": "cosmos1lmkyqhjshfd4mqsgk5stvaxlsxkmdmfhfwh7p2", - "withdraw_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3" - }, - { - "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", - "withdraw_address": "cosmos1dwha0rccawlvhudcgdpzcf3eq2c0gqyzwctms8" - } - ], - "previous_proposer": "cosmosvalcons13cydnwjmscxtqtjywk9atr9uwlm6703mlvr3n3", - "outstanding_rewards": [ - { - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "17220875845.478727382116561306" - } - ] - }, - { - "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.000000002607269154" - } - ] - }, - { - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "20714266865.324899566545795216" - } - ] - }, - { - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "22578940941.547707422600891599" - } - ] - }, - { - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "243766366.173501302964350339" - } - ] - }, - { - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3216182769.537267574462827852" - } - ] - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "192181222063.158244001747782376" - } - ] - }, - { - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7484350031.736343087434817696" - } - ] - }, - { - "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "19396808346.440877742090220124" - } - ] - }, - { - "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "8093136712.520029242917363321" - } - ] - }, - { - "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30006563238.944831778831776839" - } - ] - }, - { - "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.000000027417920605" - } - ] - }, - { - "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2070889900.213970128354397621" - } - ] - }, - { - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3803355882.998610894777957064" - } - ] - }, - { - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30722375684.372368116943940104" - } - ] - }, - { - "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "19813833628.175297782230725146" - } - ] - }, - { - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "218513221.305796703900759708" - } - ] - }, - { - "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2967410354.956862776811539245" - } - ] - }, - { - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5517811984.452160001612139171" - } - ] - }, - { - "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4914087260.336803898118162537" - } - ] - }, - { - "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4137170753.155136953459875226" - } - ] - }, - { - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "17785493982.070854785839706278" - } - ] - }, - { - "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "27845774681.205818014287692026" - } - ] - }, - { - "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "21744315327.805663813285476473" - } - ] - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4862500260.686275927048752655" - } - ] - }, - { - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "27388474340.135639921276003896" - } - ] - }, - { - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "9413561734.369977306377145001" - } - ] - }, - { - "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.911746517175444959" - } - ] - }, - { - "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "537317001.751974465713750532" - } - ] - }, - { - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13185327586.352255587186466738" - } - ] - }, - { - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2460537813.473636151156614982" - } - ] - }, - { - "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6307229865.753421284851169886" - } - ] - }, - { - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1186574299.608995587009377706" - } - ] - }, - { - "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15812227852.701576011915535925" - } - ] - }, - { - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "25850025834.376708123333278670" - } - ] - }, - { - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15376356132.250045445514165950" - } - ] - }, - { - "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "9762599204.437143433283314336" - } - ] - }, - { - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.678747383324805073" - } - ] - }, - { - "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4583277790.314069035393787914" - } - ] - }, - { - "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3192252760.906493428159520191" - } - ] - }, - { - "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32598200271.474079073304604735" - } - ] - }, - { - "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11986642474.515239238070803495" - } - ] - }, - { - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1491407428.638499291892791076" - } - ] - }, - { - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.000000008200074810" - } - ] - }, - { - "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "238242541.508576164280002767" - } - ] - }, - { - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "10982911363.740452103089910785" - } - ] - }, - { - "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "539324167.672321904445007925" - } - ] - }, - { - "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4247641670.745455864797680428" - } - ] - }, - { - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "24905022305.733618844640564250" - } - ] - }, - { - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "23519585548.736582291768757137" - } - ] - }, - { - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "14937531590.521755198594272709" - } - ] - }, - { - "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6101570647.326884697498224390" - } - ] - }, - { - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "25188739122.024442400516517496" - } - ] - }, - { - "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "22703272187.957924377781601946" - } - ] - }, - { - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "20182338713.370527973636616745" - } - ] - }, - { - "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1156593054.161319243614799759" - } - ] - }, - { - "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4209150199.030757097018871025" - } - ] - }, - { - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7491437734.061233480820170767" - } - ] - }, - { - "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "20752661383.101767066969341173" - } - ] - }, - { - "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7231174799.427438369218202505" - } - ] - }, - { - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "59882548526.175225517880905747" - } - ] - }, - { - "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3729583258.268360674575978585" - } - ] - }, - { - "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.730872776412786233" - } - ] - }, - { - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3856572318.851771072193592332" - } - ] - }, - { - "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1121641285.729506202530365697" - } - ] - }, - { - "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "10535382082.831774078181249238" - } - ] - }, - { - "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "19932356085.117152026307143841" - } - ] - }, - { - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3907942954.181938645659497539" - } - ] - }, - { - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "14034395855.684151969521105877" - } - ] - }, - { - "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11611929205.479252180831866808" - } - ] - }, - { - "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15348746910.503476123769763625" - } - ] - }, - { - "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4787120898.780160336455176655" - } - ] - }, - { - "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13890620727.232818420429431135" - } - ] - }, - { - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "10668976316.172822602291681862" - } - ] - }, - { - "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2707301610.153975970423577372" - } - ] - }, - { - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "31852893337.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "92092836922.391558440221811534" - } - ] - }, - { - "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2087788435.418200776424526287" - } - ] - }, - { - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11680570592.639823453395374020" - } - ] - }, - { - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "279399752.525173200280623739" - } - ] - }, - { - "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11317573766.805428918540638656" - } - ] - }, - { - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32328180064.423319206611546586" - } - ] - }, - { - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32965737565.706558742981394560" - } - ] - }, - { - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "21813173013.670232468358393424" - } - ] - }, - { - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "8902110459.391289224658790671" - } - ] - }, - { - "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30568637250.047495197959197696" - } - ] - }, - { - "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "27218433078.031384498796332524" - } - ] - }, - { - "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "16765042786.072138978323269972" - } - ] - }, - { - "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7039007900.090250927297198955" - } - ] - }, - { - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "23310859135.681198341523481656" - } - ] - }, - { - "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "8845550897.653089483109124409" - } - ] - }, - { - "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "643415242.379349043140967768" - } - ] - }, - { - "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3505365960.216933272196077020" - } - ] - }, - { - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1780534040.652204329520714743" - } - ] - }, - { - "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15113937804.117549224775962266" - } - ] - }, - { - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "12751852865.861997681255389525" - } - ] - }, - { - "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "26417240831.344054075916525566" - } - ] - }, - { - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "23612779075.902671847624821978" - } - ] - }, - { - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6708301621.805829658960578965" - } - ] - }, - { - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "394071828.192756186748254466" - } - ] - }, - { - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4865893471.054106591976688258" - } - ] - }, - { - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "16565102521.278623444648051043" - } - ] - }, - { - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15429251118.232731211674479244" - } - ] - }, - { - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "366520347.359138367079797625" - } - ] - }, - { - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4861559078.664980744587286383" - } - ] - }, - { - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "14311640813.184468731208440736" - } - ] - }, - { - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "9250487936.081682822935730661" - } - ] - }, - { - "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.000000000180150137" - } - ] - }, - { - "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15832376449.936755220939206457" - } - ] - }, - { - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "12382233626.659743736725915198" - } - ] - }, - { - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4762044772.816158277497327947" - } - ] - }, - { - "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1196327592.983907819145864128" - } - ] - }, - { - "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4398211183.531754817867646398" - } - ] - }, - { - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11081703733.518827137056819282" - } - ] - }, - { - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4564028000.062910407937527085" - } - ] - }, - { - "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "8255565995.050765057157090981" - } - ] - }, - { - "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "10973507304.839048253284956205" - } - ] - }, - { - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5279249134.484605916395962511" - } - ] - }, - { - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "10292660832.313119256516530727" - } - ] - }, - { - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1503377835.608473133261344084" - } - ] - }, - { - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6932970881.758329424629921610" - } - ] - }, - { - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.039077732414779791" - } - ] - }, - { - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "9660720879.270334500819779497" - } - ] - }, - { - "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5750359180.022920048847960986" - } - ] - }, - { - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "21822836091.192950166124071706" - } - ] - }, - { - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "25176225167.315402180113237786" - } - ] - }, - { - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "16233461599.575941024539501811" - } - ] - }, - { - "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "18818121052.379450688928489869" - } - ] - }, - { - "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1769062615.767787531497192503" - } - ] - }, - { - "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "17021494290.192219756246561560" - } - ] - }, - { - "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.017559471995965787" - } - ] - }, - { - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "72531287930.913064328040812166" - } - ] - }, - { - "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "8935792267.047940856716577941" - } - ] - }, - { - "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2964676563.604466477008846137" - } - ] - }, - { - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3709390855.994028695900542566" - } - ] - }, - { - "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7440174971.015286928233568015" - } - ] - }, - { - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "18828926798.875303947031289624" - } - ] - }, - { - "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "16073693605.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2584782353.707826308221423018" - } - ] - }, - { - "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "29261147380.335414938317826794" - } - ] - }, - { - "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7831893054.662367746440629326" - } - ] - }, - { - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "24030665383.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11281582491.485403113376402651" - } - ] - }, - { - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "695995000.008107666926356585" - } - ] - }, - { - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "19602698420.777667438972556283" - } - ] - }, - { - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30705539084.697448434520200610" - } - ] - }, - { - "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "645816621878.367293520193768267" - } - ] - }, - { - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6284507611.503112537620562852" - } - ] - }, - { - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30267197467.046140347920752886" - } - ] - }, - { - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1702858030.764947001017858982" - } - ] - }, - { - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1148857087.499465536264342298" - } - ] - }, - { - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "31474620879.759763727616154161" - } - ] - }, - { - "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3538765004.906407429568515327" - } - ] - }, - { - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4982786207.080446778604572020" - } - ] - }, - { - "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4322550478.365704941931960840" - } - ] - }, - { - "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "393754972.428724197270373324" - } - ] - }, - { - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "183344357697.108357889602117412" - } - ] - }, - { - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4305875918.065848544638106381" - } - ] - }, - { - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.296620344311288183" - } - ] - }, - { - "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.000000010568084388" - } - ] - }, - { - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.984868576423022223" - } - ] - }, - { - "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5569167846.764595424965116430" - } - ] - }, - { - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30982725275.380854595416700090" - } - ] - }, - { - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "22868767431.258674992913631412" - } - ] - }, - { - "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7410527273.417257058436825667" - } - ] - }, - { - "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "28888366039.201896328490406841" - } - ] - }, - { - "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30016881814.304122473196965404" - } - ] - }, - { - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7491437734.061233480820170767" - } - ] - }, - { - "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "24953883546.381812989649329978" - } - ] - }, - { - "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "26737343970.575423601282944026" - } - ] - }, - { - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.915222892178805867" - } - ] - }, - { - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32578629635.903521192680974262" - } - ] - }, - { - "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4629991007.121270348463553792" - } - ] - }, - { - "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7609968611.277766692803958733" - } - ] - }, - { - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30940652220.067909855227237136" - } - ] - }, - { - "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11710699002.776353141316136395" - } - ] - }, - { - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "20248668283.174600277482822688" - } - ] - }, - { - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15654295055.078633550849799115" - } - ] - }, - { - "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5022344609.482247875627027311" - } - ] - }, - { - "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "898972529.061233480820170767" - } - ] - }, - { - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "12032419756.614984965974294923" - } - ] - }, - { - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5950018859.243540634451321165" - } - ] - }, - { - "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6713911540.137499658822150996" - } - ] - }, - { - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "29604159816.840641093068561244" - } - ] - }, - { - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15060994257.083491216061662735" - } - ] - }, - { - "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6435989540.013921762763316814" - } - ] - }, - { - "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6838136152.615037175085021260" - } - ] - }, - { - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667869107.400743161231430314" - } - ] - }, - { - "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6872161971.350612192443370266" - } - ] - }, - { - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "188862186757.921077920332306886" - } - ] - }, - { - "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4293806142.213096900614901861" - } - ] - }, - { - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "24800561238.279612107830423681" - } - ] - }, - { - "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "19362364963.944129581457482037" - } - ] - }, - { - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5501888149.690502133696473450" - } - ] - }, - { - "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "283466194.255517462784953014" - } - ] - }, - { - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7480775628.212271024900595070" - } - ] - }, - { - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4251311697.155654547507772901" - } - ] - }, - { - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "31646149559.106573719710673659" - } - ] - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "25554844377.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7491437734.061233480820170767" - } - ] - }, - { - "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.000000001029867017" - } - ] - }, - { - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11384451264.610657025520160548" - } - ] - }, - { - "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7491437734.061233480820170767" - } - ] - }, - { - "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.000000000010560399" - } - ] - }, - { - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.761229269409268067" - } - ] - }, - { - "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13320499646.109785502376140729" - } - ] - }, - { - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "26357656015.101505639815155942" - } - ] - }, - { - "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2037871496.161745747665012272" - } - ] - }, - { - "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3262957593.027354006335766007" - } - ] - }, - { - "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4539020696.401796772256668999" - } - ] - }, - { - "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667872132.520451034073092474" - } - ] - }, - { - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "708444493539.650392543815057100" - } - ] - }, - { - "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1489060409.697248161077665311" - } - ] - }, - { - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "27068371579.141295070739546993" - } - ] - }, - { - "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11875195975.520832467094406906" - } - ] - }, - { - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11056908955.278882300765073452" - } - ] - }, - { - "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "269670222.536538166916680288" - } - ] - }, - { - "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1376792534.072854791917986161" - } - ] - }, - { - "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "9246389252.244028771069172506" - } - ] - }, - { - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "31074822357.716339650213728160" - } - ] - }, - { - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "18996793586.879476341521732311" - } - ] - }, - { - "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7101105487.302246818146406250" - } - ] - }, - { - "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13527343184.152064556323864449" - } - ] - }, - { - "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "25176225167.315402180113237786" - } - ] - }, - { - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7838352325.051492113155509734" - } - ] - }, - { - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "31349161589.749906626050893269" - } - ] - }, - { - "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.040153173645477048" - } - ] - }, - { - "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4370182132.035514233647262310" - } - ] - }, - { - "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.684637858590065919" - } - ] - }, - { - "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "11427210316.467976693371780878" - } - ] - }, - { - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "444079902709.451143884839356593" - } - ] - }, - { - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1070219221.118326946516520941" - } - ] - }, - { - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "17215494073.170643188366440982" - } - ] - }, - { - "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "19647631041.570149758029658906" - } - ] - }, - { - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "10324623372.361020700738273242" - } - ] - }, - { - "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "12148059999.607054241837367984" - } - ] - }, - { - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "31597870592.546656317595590730" - } - ] - }, - { - "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "112687796118.974424873851325553" - } - ] - }, - { - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "26060800430.972524809096798726" - } - ] - }, - { - "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "302366795.614952655037558288" - } - ] - }, - { - "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "12111594052.053614597405575288" - } - ] - }, - { - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32372956763.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "17428416405.081307914543346587" - } - ] - }, - { - "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6681478428.376685053433111823" - } - ] - }, - { - "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "874792529.420788333180908175" - } - ] - }, - { - "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "8905047515.681371464004856575" - } - ] - }, - { - "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "26292658617.216324430178584299" - } - ] - }, - { - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "29536482449.046985724736130810" - } - ] - }, - { - "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3078617732.320124450503744079" - } - ] - }, - { - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2978849960.813217307700838576" - } - ] - }, - { - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "603949823.513509808458103600" - } - ] - }, - { - "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3756345859.699570120489841049" - } - ] - }, - { - "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "16881657555.309080574393588903" - } - ] - }, - { - "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "10387065284.263616940433769772" - } - ] - }, - { - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1838179062.644552501830638050" - } - ] - }, - { - "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2281984262.643681243036698338" - } - ] - }, - { - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3840576824.607019537152677998" - } - ] - }, - { - "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.175381665253283715" - } - ] - }, - { - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "31554723907.547803731549142541" - } - ] - }, - { - "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1813439871.341169752719751533" - } - ] - }, - { - "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "51226075.901653923096422965" - } - ] - }, - { - "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "9061862191.464570899664132654" - } - ] - }, - { - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13223340588.859308551321932186" - } - ] - }, - { - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "16954337292.693526774287210266" - } - ] - }, - { - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "7456317782.234348837638428175" - } - ] - }, - { - "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "27430732633.275448957388712899" - } - ] - }, - { - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "21697070140.868247877388767954" - } - ] - }, - { - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "12413866768.273774415754551505" - } - ] - }, - { - "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6625313974.061233480820170767" - } - ] - }, - { - "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3357770219.455058317552130694" - } - ] - }, - { - "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1983117245.095216827935684925" - } - ] - }, - { - "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "3268255262.968986129619963183" - } - ] - }, - { - "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "717587589.405391767552367081" - } - ] - }, - { - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "21233037338.638147619739681502" - } - ] - }, - { - "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "251375143.004754310166118846" - } - ] - }, - { - "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6702327695.877761494338804909" - } - ] - }, - { - "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "8173242868.033189487574265747" - } - ] - }, - { - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "29335651963.155214905560211310" - } - ] - }, - { - "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "20363369993.952452598516547507" - } - ] - }, - { - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4736169209.971261210585364787" - } - ] - }, - { - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "19009296126.940356713521996324" - } - ] - }, - { - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "31756630880.469387280300822842" - } - ] - }, - { - "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "22303221402.975681598448633626" - } - ] - }, - { - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13731927933.676934209964919168" - } - ] - }, - { - "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1621854091.705283752565911617" - } - ] - }, - { - "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.033069359629216292" - } - ] - }, - { - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "8277641822.583445123652347644" - } - ] - }, - { - "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2230674364.963597490904894252" - } - ] - }, - { - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "8205243037.410264065628214006" - } - ] - }, - { - "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13160731423.923070831816120432" - } - ] - }, - { - "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "31233581737.171177753871756710" - } - ] - }, - { - "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13513314439.760880504906257515" - } - ] - }, - { - "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "27078647262.167664364465078829" - } - ] - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "25188841652.827759522584567198" - } - ] - }, - { - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30952447291.576202835534526223" - } - ] - }, - { - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5458068372.195440433865205353" - } - ] - }, - { - "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "17319309526.333681206698225758" - } - ] - }, - { - "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1142673799.671698135354310916" - } - ] - }, - { - "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5061808172.056428799118546191" - } - ] - }, - { - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "25397864297.376635636890792986" - } - ] - }, - { - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "239926289.311199175066434186" - } - ] - }, - { - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "35343843286.901039007622033556" - } - ] - }, - { - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "30814059699.008726822838145807" - } - ] - }, - { - "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2285419328.205248508592749249" - } - ] - }, - { - "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1174883542.187258036855289402" - } - ] - }, - { - "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "27425268290.559019102104827871" - } - ] - }, - { - "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "4539020696.101872352488900792" - } - ] - }, - { - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13985129189.416239603623148731" - } - ] - }, - { - "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "6101286095.766558665001546099" - } - ] - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "19781232193.429308096432999493" - } - ] - }, - { - "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1764535445.724555774238918063" - } - ] - }, - { - "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15477564976.067040516653742243" - } - ] - }, - { - "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "0.891276434601468096" - } - ] - }, - { - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "9301644936.109083164415899687" - } - ] - }, - { - "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "19928728215.894931096994023652" - } - ] - }, - { - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "1520119891.692585578315413794" - } - ] - }, - { - "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "903741229.035846718465032526" - } - ] - }, - { - "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "5176046869.541158581012082931" - } - ] - }, - { - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "13176092868.226450911787779563" - } - ] - }, - { - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "17000022605.192483780939329398" - } - ] - }, - { - "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "16793236941.564038785133487977" - } - ] - }, - { - "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2556241579.807715659172888177" - } - ] - }, - { - "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "23712993284.560665311816608707" - } - ] - }, - { - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "16622128786.002585913660284304" - } - ] - }, - { - "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "35804959813.707173107916888416" - } - ] - }, - { - "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "2189945815.579705929191685262" - } - ] - }, - { - "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "outstanding_rewards": null - }, - { - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "21435411415.823358697847816586" - } - ] - }, - { - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "15935907663.757038179216600516" - } - ] - }, - { - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "outstanding_rewards": [ - { - "denom": "stake", - "amount": "186960971306.660879494461058486" - } - ] - } - ], - "validator_accumulated_commissions": [ - { - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "277106793.379085060880995705" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "528375454.616025550116168257" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "17919450112.486265560724885918" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "36650685.147834037940808756" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3216182769.537267566502926347" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5222044149.414501981269513627" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "159316315311.652442148594472958" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5282822025.770496587886248796" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1694266149.887062395217410896" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "13464597455.693002040748753785" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "30853394.114819286253260622" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "313284872.610534770052663153" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "165711175.150441372956096781" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3883635083.203436659373804991" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "17361078.464024285969583267" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "901370143.144290398313263568" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "515514882.617503415413614078" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "9042545988.049461466938378468" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "9471781585.884609225895050273" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "16958650445.640691116317457097" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "210497461.761590200777121063" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.372454378351718659" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "19093949478.694373195093102337" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6624116332.673643326413807120" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.911746513202759863" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1605872845.093602702083618154" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.922897177570817971" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.809307396335532846" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "15365319997.023040093556811809" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4137340406.786635623849613905" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "888158277.004151113304496023" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6108460201.699772609897943219" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.678747381739283891" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "67876750.369495616131823104" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3192252760.906493428110292228" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "18565657669.240845522854706198" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "227698700.081989892739968849" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1035992898.747517808792808633" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "204823836.791435064159948285" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "238242541.508576160828505834" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1264422561.354404528459365908" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "539324167.672321898794949083" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3348557554.713064312123045489" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "14515380364.326013826645941931" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "10492682990.582862030320466277" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6172519399.334255025005190628" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2779416009.757804733364509848" - } - ] - } - }, - { - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "9462987096.671900612087384837" - } - ] - } - }, - { - "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "10884811246.103690595274200072" - } - ] - } - }, - { - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1156593054.161319238552328930" - } - ] - } - }, - { - "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2969549864.319329755616537086" - } - ] - } - }, - { - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2517242327.788021794537444094" - } - ] - } - }, - { - "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "7231174799.427438348911496884" - } - ] - } - }, - { - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "20415535085.300600305810855920" - } - ] - } - }, - { - "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3628564577.854607465835288073" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3729583258.268360663827945377" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.730872776389496847" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "727468511.827163966271868870" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "443539080.656661733341038036" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "9219557961.909941220098253194" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.798287259643562821" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1625071973.266447765265793749" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "14010630862.905397244157940602" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3868742456.315704367750323102" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "24827423805.046243084037002668" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "209007813.369643938866475631" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "998406746.849611457325733689" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5063754107.056468188631919544" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1585840126.609234778611771961" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "542107876.654206720973554582" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "60570249052.471734300808725551" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2087788435.418200776251472615" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "457565698.824739581007959933" - } - ] - } - }, - { - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "19841691.277488998521068155" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "8386253870.889648281808576890" - } - ] - } - }, - { - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2502177121.751570557615439584" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1913321175.799791883631084942" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "7049343047.385457978329422037" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1807955299.137663563689079302" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.269218634861324671" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "18122629914.191909082126002198" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "518128606.033933702242654350" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3505365960.216933256117891441" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1088655888.703907966613105089" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2404997707.312271750188063590" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "309635025.330001234505614360" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "106232729.667038274225108987" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "451525269.955426958969644791" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6173999738.015913858046021712" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2982671318.818370995664668398" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "39615963.898418932839783220" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "26179773012.093935561850734447" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "358446766.028366775666172929" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.657093524289120227" - } - ] - } - }, - { - "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1760641195.292748050476197170" - } - ] - } - }, - { - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "57023401.060764360053846732" - } - ] - } - }, - { - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "11334939306.896751344811755254" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1496460968.638723867568938016" - } - ] - } - }, - { - "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "357304578.872394901928742331" - } - ] - } - }, - { - "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "360334827.638608685732582369" - } - ] - } - }, - { - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "17832102097.977292317894408791" - } - ] - } - }, - { - "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1261803691.560581223400961357" - } - ] - } - }, - { - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "768829360.356016812865041097" - } - ] - } - }, - { - "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4131540820.475909755531346032" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "9876156574.355143427956460584" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "10077284271.794137717201275555" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "27499856.663866007929934443" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5577446004.931472410981104148" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.039077730500896235" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "9442537894.884848936753835812" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "16136593604.194530483623558451" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "196532702.114908151679458943" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "320752867.021370114030790859" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1419291310.580690020515394483" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.017559471970960521" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "55362050362.088025141531607133" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3038169370.796299891283636499" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "282228430.386525731059968002" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "10802986.622549295974770992" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "778106489.196961655600114269" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "17476224281.345819852032876474" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3521009143.712417456447451464" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1231191151.587291787946168993" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1727606374.518317926293038978" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "939827166.559484129572875521" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "10704132004.092693794840610345" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "10594020970.132285574158281732" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "15290104768.206580602398593906" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2672910620.792123982501072042" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "315560994633.302511918962991399" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "985476794.207414671781679984" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "535116362.703326536779839771" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.621378207506539399" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "462280007.860922507872741088" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4198617809.242572022364345639" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.234577020274302682" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1174904848.162636480329260205" - } - ] - } - }, - { - "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "608652605.707619718314676060" - } - ] - } - }, - { - "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5098983059.386334350777590960" - } - ] - } - }, - { - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4110887229.246190830760061834" - } - ] - } - }, - { - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.296620339914081961" - } - ] - } - }, - { - "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.984868571552507855" - } - ] - } - }, - { - "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.211988653890129529" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5259951931.920439082352243876" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "11062783939.169910923776795037" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "7410527273.417257044130695137" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "12190159952.329409305437883885" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2241438562.431520338273961266" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1306385618.387627384812321579" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6161609546.425337306745443339" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.915222891560483330" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "29591963096.276305889542880860" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3865629784.342460029336936745" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6007412231.571257522971938726" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5001959633.138772959264202502" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1745522978.930349461427722119" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "15347741697.154550789418195693" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2185662379.534427859942116073" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "921192140.970561127318067921" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.973885463121750275" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "369950753.003601331810568469" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2023979919.105426696289036868" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5768495526.158971976738371628" - } - ] - } - }, - { - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "14291401563.340512964420267315" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "11013282385.759629967684477729" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6435989540.013921736043842593" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "783952563.559490614963043696" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "7490224923.584290682442487840" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "7074530368.663948455468727759" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2542901035.340483805265596748" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3765816198.063587525429727015" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "94121758411.137432152822844577" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1212063759.878319664084919355" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2735320379.979481236574224689" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2053954888.037617863314217563" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1152466511.540305723579313447" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "67790689.598536175693120545" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "176953987.495747539465705935" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2295708316.464053455654197366" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3606961189.393231581341044994" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "489477000.336997384781152114" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4491633907.185633003915310721" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.761229269369666070" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "11173277153.455341859217453987" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1651470454.075156671601593586" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "245471199.715003406943272969" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "935721568.343878300767683420" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "512638570.034635767527305791" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "19900777457.138359891421764163" - } - ] - } - }, - { - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "616709690844.948107803587300415" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "378594152.012109173270008245" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "26460806950.115074865881542318" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4473364922.833572894187369426" - } - ] - } - }, - { - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "10121947882.842327806506724259" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "269670222.536538150205029939" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1376792534.072854791654045811" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "29261538831.227011759105810953" - } - ] - } - }, - { - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "146717389.653355862617575999" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1966224709.235392349996651004" - } - ] - } - }, - { - "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2050658504.468701971176653170" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2739403174.407277782418076347" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "10780328757.454289760173961687" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.040153148046354807" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1207594328.437750081127040542" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.684637848776696699" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "14697499.508807378361703466" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "86969720715.747948437493982190" - } - ] - } - }, - { - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1070219221.118326946230364909" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "257130422.779123734899878673" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6177149874.949996410882396263" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6261764164.346494876720764963" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "864900622.021283159098531050" - } - ] - } - }, - { - "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "13793708357.049743717879496927" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5257603171.928755698050608172" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "71909733.189283149930764481" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4400714963.719128256609752294" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "990409100.641271807618667851" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "13689622489.457928167491321838" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2320292914.495778069901718157" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "796471897.362008598599711639" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "60853698.658826404390870382" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "11127466281.080108051347849141" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "19794794946.249954893625129841" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "176315962.441735580569233100" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2978849960.813217298231878130" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "603949823.513509802866417669" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "731753250.605430318889646483" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2424310359.838870556909254733" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1838179062.644552491211163807" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2281984262.643681233750540035" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "855655025.424309398169077457" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.175381639508374923" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "14375354137.255862132472321383" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1813439871.341169748396298709" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "51226075.901653895379048583" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4475193742.787493998110052288" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "570137169.870036047170357928" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1711545963.334268905344256546" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "809417200.054834576882805195" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "7121893770.990194672598519169" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3393411354.357925265591606174" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "10574014570.578186967494133049" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.098456613182261526" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "187490038.144352434924870788" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1983117245.095216807857357404" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3268255262.968986100598839718" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "717587589.405391765800672211" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "19573971462.980076954794627597" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "173448848.673280474014622004" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5812812749.878429105784290673" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4395248538.637439933511619262" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "18916702493.014678191568254058" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.083345401561456978" - } - ] - } - }, - { - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "8432831922.331516907366864390" - } - ] - } - }, - { - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "15695352067.262111032193232725" - } - ] - } - }, - { - "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "13379330700.955599788596771240" - } - ] - } - }, - { - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.250812123199997513" - } - ] - } - }, - { - "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.033069334120454660" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "5882013743.695226765096564642" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "819949534.858298884906474039" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4846422450.938115016005024614" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1044999826.546007091635185885" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "28833490261.832725338386535669" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "13513314439.760880492238326426" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "12913374485.192464060418939753" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "9160397275.853551127737273960" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1854731548.307599642899859027" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "205259995.530384264017183904" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3863275378.219985734240347867" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.100076852969543738" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3044272252.609114282057352623" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "3807822889.007643023782268961" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6259371349.974773943559494431" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "13142253.340468711062168703" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "146098041.506476158905860992" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "12158146783.622659891722269130" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "485367585.883823728864863349" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "2479265539.885419718645476263" - } - ] - } - }, - { - "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "534099257.532275963280022723" - } - ] - } - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1959596116.847024728277261200" - } - ] - } - }, - { - "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "23404905.471265667392571730" - } - ] - } - }, - { - "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "974334308.272468905549661327" - } - ] - } - }, - { - "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.891276428003721941" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4329936388.958354911306147891" - } - ] - } - }, - { - "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "13456930009.407042106926190221" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "0.324150582799065373" - } - ] - } - }, - { - "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "903741229.035846717633311708" - } - ] - } - }, - { - "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "774637220.235809638615652701" - } - ] - } - }, - { - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "910689189.448815092401625690" - } - ] - } - }, - { - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1969536958.783601175071832604" - } - ] - } - }, - { - "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "16078517089.206797598126118738" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "745470508.520604684793912701" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "6968030102.393652296666439447" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "955628472.642170031797186371" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "11621579071.984150218282966402" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "1551154981.438740857459611823" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "accumulated": { - "commission": null - } - }, - { - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "4874329143.745667993186175187" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "12737732456.227655682891563183" - } - ] - } - }, - { - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "accumulated": { - "commission": [ - { - "denom": "stake", - "amount": "34055627676.234885115751275440" - } - ] - } - } - ], - "validator_historical_rewards": [ - { - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.508955723517088539" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.542563501925691871" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.512158938598063517" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.512158938598063517" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.292557112466443942" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.539259718515421305" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.846574216613461540" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.846574216613461540" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.000474683841348262" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.005615493022781994" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.005615493022781994" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.005615493022781994" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.094577217938197191" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.173091786803433045" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.173091786803433045" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.371018262678876459" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.000835365294623529" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "5.904029070862951677" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "6.005371152362798468" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.401660922468163286" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "4.036437109989857068" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "4.036437109989857068" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.301151007082075907" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.915125073946877143" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.172882698073437760" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.160390702721685831" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.318073482619147549" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.409425030456137424" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.604869945812224651" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.623745475040626731" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.277479339607626767" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.057424346716572376" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.188771768611656070" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.490461014765792379" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.663229984723985747" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.663229984723985747" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.760772163248534004" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.760772163248534004" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "period": "11", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.760772163248534004" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.002287855604008229" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.595391980425256456" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.595391980425256456" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.512731017518643148" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.030582869814113061" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.451358340598559564" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.891041271280072008" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.891041271280072008" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.028478558970190569" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.028478558970190569" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.138063059540073047" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.166001761341497381" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "period": "7", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.216111629830644085" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.567013343776276287" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.567013343776276287" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.815739843736418377" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.192131665588792378" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.424179399501514198" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.939918180234345356" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.073826613276445783" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.235570586629868232" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.382380590686964473" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.273441018412842326" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.273441018412842326" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.476855016899218749" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.666847169048692497" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.834168727598941314" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.206428864026463054" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "8.843612149614257729" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "8.843612149614257729" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.054369217226992691" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.126818649319585122" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.126818649319585122" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.154119802519027849" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.134299636052073089" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.197523275359229114" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.249169272474734166" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.267396405659842650" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.152298446988649866" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.152298446988649866" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.273427548172545834" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.917065293185403580" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.967919118512034747" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.221940490937602497" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.221940490937602497" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.259400016265779091" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.259400016265779091" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.466447653853459545" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.508455028347171090" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.518238127250812316" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.051290815241098104" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.212880243805964360" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.151733256707771388" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.515340037809467176" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.747897409567936598" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.747897409567936598" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.599220808780721719" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.599220808780721719" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.599220808780721719" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.163954274436273491" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.310783022065728778" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.078441620834608469" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.078441620834608469" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.078441620834608469" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.336825222876443490" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.336825222876443490" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "36.538908882381596359" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.350086981644848764" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.296125988619195519" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.296125988619195519" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.619350435630525552" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.708550721140497084" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.750069990142618522" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.270663939556433745" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.752014609273368997" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.255403392932049217" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.877223393710481831" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.877223393710481831" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.877223393710481831" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.877223393710481831" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.383583718736168712" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.072792680276490502" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.144751344296845662" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.946868424007155163" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.946868424007155163" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.141005036071022583" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.318032511103067061" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.318032511103067061" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.318032511103067061" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.119175178219769035" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.068794153277072224" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.170751641509677360" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.210611869948743637" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.240719178925335759" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.207384000437970359" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.486190297642737493" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.611598254372192098" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.614122872633608225" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.110295957981012900" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.110295957981012900" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.309243186282087537" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.339376068938902310" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.350913583702945613" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.397473163899589313" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.397473163899589313" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.597078596524170485" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.229396561381528283" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.474400210195279884" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.659477915344641803" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.883512421247652384" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.883512421247652384" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.559277541061147180" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.824569427993582067" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.824569427993582067" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.185175927794623096" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.480550630133862309" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.480550630133862309" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.610321057886218898" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.686782211213352937" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.686782211213352937" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.357968318375469932" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.173605006014279649" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.781147064900722304" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.421038197250524001" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.421038197250524001" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.421038197250524001" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "24.988423861775581700" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "24.988423861775581700" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "24.988423861775581700" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.526902796086228049" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.846611257244369419" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.273209707497210333" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.624847947868380059" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.903081800941262823" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.903081800941262823" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.570157717922226862" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.839315869555212482" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "period": "11", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.839315869555212482" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.001541101634230003" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.417350425346321544" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.095747288859477657" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.270808659467670758" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.391785608601979419" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.407901633183955436" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.891449312982646896" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.891449312982646896" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.209578717794916469" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.767068091242484641" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.794115066133505828" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.877887324030848658" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.150964203522089691" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.150964203522089691" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.434840876964488414" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.656454126215802271" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.656454126215802271" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.310884678556496230" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.700189859456185775" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.761497421872785615" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "2.183522127673967339" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "13.569354899133857126" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "13.569354899133857126" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.565789000020855573" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.989795865475541526" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.989795865475541526" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.026251017841887978" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.135302564883484283" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.515002033830662918" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.515002033830662918" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.864631386174660712" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.050646807222448412" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.136552312176860264" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.177946896419520703" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.261681360082728441" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.414289254830467158" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.662613494259503477" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.662613494259503477" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.859773648661399554" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.795788163476169546" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.795788163476169546" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.822201146798542294" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "2.165040796606679122" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.563323721181839992" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.865081502013398577" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.492498420673879908" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.700085550422976946" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.335010193218545655" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.233280613638698077" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.320565115851631010" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.341072388663254009" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.341072388663254009" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.450947240430845210" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.105038387024241749" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.663809594221120553" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.663809594221120553" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.320929441280401346" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.370608946037426438" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "period": "11", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.417934950719199317" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "period": "12", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.469324463792518916" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.700206851908699409" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.379262677998642793" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.414177418109768832" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.414177418109768832" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.530067227150287181" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.608093994127972862" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.149345876234480559" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.459285021970866948" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.169135244025127739" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.396312921934332814" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "32.890614958717885895" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "32.890614958717885895" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "32.890614958717885895" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "32.919475633814259617" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "33.034297994814080039" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.171968911695567069" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.171968911695567069" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.322079633470521028" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.322079633470521028" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.142027394111757355" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "period": "7", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.064911538484032280" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.116980167755658378" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.285012775586208784" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.404346417765050364" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.649795547220870492" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.859877589627982513" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.248937513973307998" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "period": "11", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.248937513973307998" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.078599581646267108" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.078599581646267108" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.424181202517676095" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.424181202517676095" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.120204712097828385" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.187202790083739017" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.312523098782197027" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.231076015729088306" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "2.065298901068817010" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.112612489782853395" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.219230629967503357" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "23.404215035392724140" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "23.404215035392724140" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "23.404215035392724140" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.148953688872066051" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.772423060454248439" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.772423060454248439" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.490199190222128798" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.076141455703225906" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.030937133125724216" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.029303158405101084" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.114875714168666683" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.008628143921719196" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.008628143921719196" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.012533818609960684" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "period": "7", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.076828297662844090" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.042479281713289724" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.190911431953188409" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.190911431953188409" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.190911431953188409" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.579776534326837376" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.579776534326837376" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.434833192557042808" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.434833192557042808" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.434833192557042808" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.567490307628004052" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "period": "11", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.567490307628004052" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.700206851908699408" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.073714006353122275" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.432593195927369366" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.432593195927369366" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.298828653346982190" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.864631386174660711" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.165964355430803461" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.410388415913048804" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.437535036040629257" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.609804279969736582" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.655548873680788553" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.293548981437233758" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.401066343498857766" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.506919131289083168" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.561145622221834061" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.265736377377838682" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.756880274646164803" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "10.994686653318717548" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "10.994686653318717548" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.184193527891644194" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.250260481007298057" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.276006003337242016" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.364666619671323075" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.268086681179230699" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.102183399208957639" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.271996755742583159" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.417119321775713473" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.543611903201309404" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.046069743680559697" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.046069743680559697" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.046073021507499671" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "period": "11", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.090432945661913993" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.282826355813809912" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.095765663829970693" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.107832997733037325" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.588545225098858270" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.228162415811999516" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.287038741530549007" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.886207688757766439" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.098996222839621020" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.513477283857156384" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.731255206582442871" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.731255206582442871" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.196110242276430759" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.398426524855468392" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.447547977222836718" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.635046107289342641" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "28.844044764030850346" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.126422954094864104" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.126422954094864104" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.200139687281353638" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.255134016027277099" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.420722060554982250" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.473954684434682203" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.629641264581146636" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.635895226788104729" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.913377101663268077" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.002173152155111373" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.241380222482488555" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.241380222482488555" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.260421641812595937" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.544766746539198414" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.661631731670176180" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.678955694723845020" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.262070862528108472" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.511828296909926465" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.511828296909926465" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.511828296909926465" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "period": "11", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.511828296909926465" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "period": "12", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.511828296909926465" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.331073341429133859" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.331073341429133859" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "period": "11", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.439328433311137470" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.029009447969056924" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.284327628093379831" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.808712914763694308" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.145222821352800219" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.283654680026977732" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.283654680026977732" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.283654680026977732" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.283654680026977732" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.756939836817478007" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.756939836817478007" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.756939836817478007" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.332016052780443560" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.756348996398941036" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "2.244481277225370187" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "2.466989093298784981" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.230019187243455262" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.353979172798147590" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.353979172798147590" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.199237867802823236" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.370762382762272957" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.457589199420750226" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.503758648547016424" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "7.467609130427488916" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "7.467609130427488916" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.474965934828543354" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.873581241325519122" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.484539683819238278" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.236556624097939312" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.236556624097939312" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.770107177755693811" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.011535332436306032" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.054356314996810688" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "7.150400405663851910" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "7.150400405663851910" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "7.150400405663851910" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.065925318393522025" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.110221058206893324" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.256456323790825639" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.306081722657220204" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.184183692778275370" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.363593829221112941" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.458603246128568339" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.477969199906528332" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.046312256868738422" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.257907757807096905" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.257907757807096905" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.447208138617613350" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.221440160560810951" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.024057291139310145" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.024057291139310145" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.933143355353396544" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.933143355353396544" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.436103498845057384" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.036554075174326429" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.605360338672048326" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.605360338672048326" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.808167653764758611" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.808167653764758611" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.998959856174665812" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.129992520315172351" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.129995597411229376" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.023215176576678970" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.183556028644616263" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.088881592834584131" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.206743884649377797" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.248203112172867948" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.039797021340298366" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.061529843348518555" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.119200586504466392" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.148649641548535740" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.916402494333050929" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.962075160276744298" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.970527967271634562" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.753760682965552344" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.275567372174847246" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.854501200377174934" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.149903774315467627" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.149903774315467627" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.422519071691696181" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "2.450232020577983513" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "2.464182782143535222" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.144448494759326209" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.137721444798981971" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.250371673774951692" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.317593671645006471" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.333335988538244700" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.274449486254448582" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.506369110375782713" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.736610702598603812" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.736610702598603812" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.736610702598603812" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.117254721392916114" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.117254721392916114" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.590467103140862840" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.674050151055652454" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.460129764831110061" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.491665549011150248" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.390958504850043449" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.390958504850043449" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.564166425327200989" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.717267512605129179" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.732196537149002150" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.745937805858183221" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "5.221625441519346423" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "5.221625441519346423" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "4.070296880898123125" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "4.070296880898123125" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.169670321998103923" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.180874774492538778" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.764864680668560110" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "86.648801710052384136" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "86.648801710052384136" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.200632423730348614" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.427404443767361769" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.449907572372872787" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.534058574665531523" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "157.961554460589527700" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "157.961554460589527700" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "157.961554460589527700" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.847263900313882195" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.256704400909965176" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.567225536578985974" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.002027753539710014" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.019789059558728136" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.766979617911744878" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.227419302074647986" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "19.371457586302624669" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "19.409430364233236385" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.944429441511932348" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.971700777122653302" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "4.027208695009346361" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.088761716208659899" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.101696180930628051" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.101696180930628051" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.177214844124636366" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.471062131657995570" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.858966296940444569" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.691886255527295296" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.010940084028270015" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.010940084028270015" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.154256756806974630" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "5.756655809161183966" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "5.756655809161183966" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.581910361718164399" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.934259605792279606" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.056626821488016550" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.056626821488016550" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.063545823013262070" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.526266558664323650" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.363741243977559781" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.533689230160560385" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.636015099045481807" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.547504316209318183" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.574168096299156240" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.625246919115774701" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.801213498670300992" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.845379831916487104" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "period": "11", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.867932867080139153" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "311.798337991010339097" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "312.077404997298917340" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.298828653346982190" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.627382502211158266" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.001930268506313024" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.063771610982219202" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.263615452639460650" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.281448635188006245" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.361491420037509609" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.161832861350326277" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.161832861350326277" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.543360367590610392" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.738313496721540536" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.087075135369242876" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "4.493581420913290268" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.508603290074890441" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.471402462188297682" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.471402462188297682" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "6.059401416740521166" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.387701131555288654" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.387701131555288654" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.387701131555288654" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.387701131555288654" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.387701131555288654" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.441359228546445605" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.155820651154462258" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.519360732254465526" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.701610762954179236" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.218907031877339606" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.467104902338620579" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.103441651434462990" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.142266672736999887" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.146186463515190020" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.535395044881059979" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.734425098643432068" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.395987317975159049" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.340966682397893180" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.663477504484533124" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.040015039089868574" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.199039534873975854" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "period": "7", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.180499654578205964" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.556694244495838963" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.556694244495838963" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.252398441235965157" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.481255014899103572" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.801403486960695697" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.029212228751076174" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.108575989671163098" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.292636862490135412" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.197039744419585537" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.197039744419585537" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.533474557093356374" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.543751057449875837" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.591285799818710396" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.136491509697193693" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.344508750192330231" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.471178261485792552" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.471178261485792552" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.469031563197041037" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.469031563197041037" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.469031563197041037" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.469031563197041037" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.469031563197041037" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.598837530935306853" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.598837530935306853" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.598837530935306853" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.598837530935306853" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.285011419265350886" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.220895528328028253" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.289857378890239655" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.289857378890239655" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.310360049843716433" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.202105773239370600" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.478847331972890432" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.353395247667561575" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.353395247667561575" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.724577348352943670" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.724577348352943670" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.660446556261372365" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.702793484052293362" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.753745357470380309" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.204348319215397700" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.122935146571044695" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.371703352608772489" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.461603673337516151" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.325491261308193869" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.325491261308193869" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.325491261308193869" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.325491261308193869" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.347374092486373052" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.347374092486373052" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.911264890965101800" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.003816424344824336" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.040422970676080202" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.040422970676080202" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.083810881200298487" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.293613302521008568" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.293613302521008568" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.775621563999071135" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.257370615697938158" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.257370615697938158" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.514282283976201934" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.282182429412887710" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.545479138254305424" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.545479138254305424" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.476669259852289803" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "period": "7", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.114037108225667859" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.694901382265562967" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.694901382265562967" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.107414724940683291" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.385412937873562418" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.440965124276557169" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.491075778461947379" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "5.017756007824860076" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.031276655884644091" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.807054301010728759" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "3.807054301010728759" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.142790727918078468" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.454963964573873576" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "period": "8", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "period": "9", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.406022113728034876" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.431268412831162379" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.553781423080636782" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.892548405116256022" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "2.252249400629833990" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.477714728073539320" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.849708251321342013" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.893051358262773306" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.490818675976954795" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.436593002540042404" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.073320885007748875" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.535558383829381441" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.332603033346361600" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.459225817882215127" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.645952564692883135" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.357184476675212901" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.429911552112663222" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.461405650001174819" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.413430933501424942" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.769399218330863983" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.355017527818609928" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.619764841808303999" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "7.667125683221357209" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.184030369224211166" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.112141876661149759" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.112141876661149759" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.149194260691448546" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.178423986670076652" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.182069724381419970" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.043959100604340286" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.676940589428158514" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.189145919230691870" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.189145919230691870" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.190447099910047547" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.288085592128558286" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.698351523942020326" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.021146682583610744" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.021146682583610744" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.021146682583610744" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.021146682583610744" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.030479689497189926" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.038674767433370474" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.040580231688491452" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.203572174672298865" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.203572174672298865" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.435317429638750043" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.436561252806344649" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.563267904309655740" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.312934457284712428" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.442650070304518367" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.607552276882744775" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.607552276882744775" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.716394249059422611" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.756485557017069964" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.033776776601805758" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "1.074389589039980650" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.031819165140208083" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.031819165140208083" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.239366389934611146" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.239366389934611146" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.588113177176492129" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.204352547182237737" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.188789752641750492" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.410727611393759172" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.437168102787542193" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.365397753164372903" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.365397753164372903" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.393581453177263078" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.479672415425195885" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.560965441700099170" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.875942601310433345" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.120595545766831513" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.120595545766831513" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.283082377207714653" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.589090760178416885" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.942703959089804304" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.565802732827678521" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.212773850507660359" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.299936634632612982" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.477268654394609335" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.524661209857995026" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.108089277510599707" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.109083043467755379" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.109083043467755379" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.154779429229998187" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.208668141601046137" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "period": "10", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.309791005660900330" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.482746151601472326" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.672749242240428784" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.296190207076740235" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.524769104516729944" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.715523252545739256" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "period": "7", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.274825957416607507" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.310894903803217812" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.344210764807960415" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.344210764807960415" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.405208712580924657" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.145461953371886485" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.225863412681956186" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "4.959799004029151994" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "4.959799004029151994" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.024951965636852620" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "period": "8", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.061979194321506474" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "period": "9", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.080295993442108039" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "187.413887557735487405" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "187.462581570737087887" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "187.462581570737087887" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.264647651726356133" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.528614955427939816" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.068235035171399741" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.142296765122500266" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.142296765122500266" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.023420272998184008" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "period": "5", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "period": "6", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.200709929817638069" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.279826910541697627" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "period": "7", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.491061198265997197" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.524230507909253594" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", - "period": "2", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.000680142970688233" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "period": "1", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "period": "4", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.465172269995272757" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "period": "3", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.156563688628831681" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.156563688628831681" - } - ], - "reference_count": 2 - } - }, - { - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "period": "2", - "rewards": { - "cumulative_reward_ratio": null, - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "period": "3", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "0.331380449076186771" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "period": "4", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "4.623193121068814234" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "period": "5", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "11.584704835586788983" - } - ], - "reference_count": 1 - } - }, - { - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "period": "6", - "rewards": { - "cumulative_reward_ratio": [ - { - "denom": "stake", - "amount": "11.636314104881138704" - } - ], - "reference_count": 2 - } - } - ], - "validator_current_rewards": [ - { - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10277856493.095527634341114904" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5598272961.593727179547443916" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4644676884.264688729175493902" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "207115681.025667265023541583" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "987842598.110607568180848335" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2319843589.860200357714156727" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "6398870562.632966843733971534" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1363676012.401787208658110575" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1951801273.054658318178936705" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1911059153.592562708651237926" - } - ], - "period": "12" - } - }, - { - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3926305099.530430590559144506" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3028192283.155572883030556622" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "201152142.841772417931176441" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2066040211.812572378498275677" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1971867051.381170304057033217" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3436765880.424118073825795747" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1677701162.661693330653296004" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1647219660.107198791051496038" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2304895437.957699566725260195" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2801478626.896694449069559090" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1643967281.585803107651548006" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "537317001.751974461235704920" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2832628067.598138303987512647" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "601061546.262455691743635782" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3436765880.424118073825795747" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1186574298.799688190673844860" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "446907855.678535896322872727" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7306007670.973161470203794940" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "8187667982.011825080885306354" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1933620990.361499357724348509" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4515401039.944573415450652442" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5325554931.526395362771097545" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10892509809.810023263230358585" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5179332683.873887686640493447" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "603892572.388185001163485678" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7067971370.869856813516222550" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7608889331.309968025237122554" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1574721924.755928436315422829" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3355456835.961132277473220851" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3322154637.569079964133714542" - } - ], - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7807843748.311728421938425430" - } - ], - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2291641173.511292899566090834" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "401395097.450603808916253285" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1239600334.711427321397218259" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "rewards": { - "rewards": null, - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4122561348.298171183872075374" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "36671140963.536449349290218718" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1853519374.369019667718703971" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "678102205.072844469189327661" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1093048506.563894512888872706" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "19932356084.318864766663581020" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "rewards": { - "rewards": null, - "period": "12" - } - }, - { - "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1004659121.032487853959078690" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "6042294040.155696517456949334" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5618789041.564142217938192403" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "rewards": { - "rewards": null, - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "6374004719.768473657017459264" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1251139087.243721814259766527" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1121461483.544741191811805411" - } - ], - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2223487035.599475204311373362" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1354516488.279692958744195339" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5613519681.719975598382050237" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2319843589.860200357714156727" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "14990202826.251880183671027497" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3436765880.424118073825795747" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1393235352.105575314389468340" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "9397139134.575948555432132014" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3723453677.839623241906194567" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2555.213090618434431017" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7039007900.090250919436094208" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4894071601.506831715974346381" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4539020696.101872342219391398" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "125286636.345415321762708849" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "rewards": { - "rewards": null, - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "rewards": { - "rewards": null, - "period": "13" - } - }, - { - "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "15113937804.117549223425100410" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "rewards": { - "rewards": null, - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "8849100013.706146085491057893" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "14688188410.899554447332040073" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3686177074.703639439562514822" - } - ], - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "394071828.192756186748254466" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2483086266.972933686472908307" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7557143757.354046174020121979" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "12446579799.414360216009810846" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "326904383.460719434240014405" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3590650159.424016330204455704" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4503112312.636613968921113454" - } - ], - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "9058497628.480504327647609498" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10991922908.259483610583649145" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2063986939.818770845290145987" - } - ], - "period": "12" - } - }, - { - "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10399507333.683802036350540862" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "14615455234.544764761123279589" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "707078808.342185924438361202" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3265583804.177434409928389931" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "839023014.111512917217121797" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "rewards": { - "rewards": null, - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1937171809.118902989821754916" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "9819900041.958245913396840287" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "231595697.967335131464966680" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2888671022.634193415479724729" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "112299762.792637984426125829" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "227675550.755497053417389152" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "rewards": { - "rewards": null, - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2319843589.860200357714156727" - } - ], - "period": "12" - } - }, - { - "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5718283025.416988549547676845" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7814724437.948367285321324228" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3436765880.424118073825795747" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2209641436.196926422039779733" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "15602202979.611529735731167077" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "92166192.336386139126686690" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5897622896.251640965432941442" - } - ], - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1150356947.981178229830440766" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1680607357.226291265231113981" - } - ], - "period": "12" - } - }, - { - "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "6662068481.818325252347112441" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "113831668.874438727942326348" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2197273882.042086403055666925" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5316897302.422479873915926716" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "6892065888.102883616867753805" - } - ], - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2332731601.904736860142073240" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "687561521.353117516872695214" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4312593652.571086836573962377" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3155565231.002254805343332690" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5250592474.043364431975225923" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2447696196.583747208629166579" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "6204828909.868571885567149301" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2319843589.860200357714156727" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1702858030.143568780376434943" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2021685235.512978206804270778" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "rewards": { - "rewards": null, - "period": "13" - } - }, - { - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2028048202.307410522302391737" - } - ], - "period": "12" - } - }, - { - "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3509692958.346542084006835789" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "393754972.428724197270373324" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "157172457837.054334966340067567" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "173880003.613594947919371866" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "227148443.582882441770606603" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "14302275850.186440696321400753" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1534242123.510360829138729858" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "8181459114.211123346723938410" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5875336278.412130611927525351" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7491437734.061233480820170767" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "11500406842.994660324297925520" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "292475423.967537468726778995" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "218416067.863109613392324888" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "764361222.778810319126617047" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1139304547.183015572580322888" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "9308877664.292234857132027766" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "9822303024.430489822046174088" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2193467946.249668901240701224" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3199549710.994219904011830049" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4101152468.511686716467324195" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2319843589.860200357714156727" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1497119897.823456116878843655" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2421966811.505426338835378498" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "339880755.615222398900084080" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "25176225167.315402156070622219" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3216656900.040751710953152141" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "693815441.355293014733148834" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "rewards": { - "rewards": null, - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "25177644183.816452478788942474" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "8611504919.398159318221121044" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "23216469146.898232635076615207" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3106345773.287024664465366968" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2139796968.727373856040601704" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3081742382.334777204579359675" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10071749470.035747765542455736" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "16604774031.708783525607604938" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4349421638.150196390156994096" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "215675504.656981287091832469" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "161743647.252169855098040454" - } - ], - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1955603380.691601091853575535" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10991922908.259483610583649145" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1558595001.985836620189378607" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "rewards": { - "rewards": null, - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2357916264.070593421465284924" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5718283025.416988549547676845" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "rewards": { - "rewards": null, - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2147222492.654443636033627948" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3160048499.127467157233427135" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1792400296.446742328721345766" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2327236024.683475694635561075" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4026382126.367160983653377973" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7065842396.077887077039311910" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "182850447.150587687655227970" - } - ], - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "440770282.073438067965689778" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1375740631.181223323134103734" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5718283025.416988549547676845" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "241894085.219643171790147572" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2180215181.127225346211699161" - } - ], - "period": "12" - } - }, - { - "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1973396739.534890353988431837" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3436765880.424118073825795747" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "211113641.859744915012615635" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "23065029415.383302245346169903" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "8265647216.078788559023112266" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1684290275.338641260527058094" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1751710576.406325818010401932" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "44705080263.489304355798548551" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "rewards": { - "rewards": null, - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10196114025.215344641096004591" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1144089328.023521390586505704" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1855825238.316881274542133969" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10700903590.799739908109935897" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "94561396079.057568467994560497" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4524122154.670781273294931278" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "230457062.425669505106793807" - } - ], - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1391073393.469104204083586851" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "24185816067.293205777194315649" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1568033134.761683991816708514" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4361185513.880906983531393666" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7009528441.827634161935745041" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1529643770.501179302608631523" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "914146821.551748304988879216" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2902301769.878388869934510979" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "rewards": { - "rewards": null, - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "rewards": { - "rewards": null, - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "8504987265.571841049655408230" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1858169822.665157405963776665" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2241000588.727955980234459650" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1299000034.324490670518315250" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "32667662901.376635636890792986" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "294256991.593177306128024752" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2279356179.944864697955020983" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10625240926.417478383178251817" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2814481474.179620526783305581" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1716684256.496548264708475978" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "rewards": { - "rewards": null, - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2646308819.776185027003928900" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "rewards": { - "rewards": null, - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1658240365.504973610378159106" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "77926294.331473836151496842" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "889514945.999332377946100865" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2319843589.860200357714156727" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1446667500.937774398753834248" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "rewards": { - "rewards": null, - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3069201314.978010458699757549" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1785553468.049878322256441287" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3825422439.162096659422521657" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "856741087.085451869907038352" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1107485537.421188876918645768" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "196663111.831388265460850030" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1290111576.027326572878630839" - } - ], - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7587187076.317934933846109321" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "257518655.871820875389864165" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2148940801.123186164411551775" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4232132616.947595477084691464" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "9692018924.954280961651733113" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1142673799.571621282384767178" - } - ], - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "22830073747.371989590140957747" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "946279965.124689968806293180" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3350081078.147129251489514962" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "226784035.970730464004265483" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "17906334898.088564400394840052" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5803250531.986983532609795422" - } - ], - "period": "9" - } - }, - { - "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2285419328.205248498506895507" - } - ], - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "689515956.303434307990426053" - } - ], - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "6522712666.029723303123055259" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4539020696.101872342219391398" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "rewards": { - "rewards": null, - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "5567186838.234282701721523376" - } - ], - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "3169264575.957925880112131596" - } - ], - "period": "11" - } - }, - { - "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "287284436.730054004650552695" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1345509282.118916207474210902" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", - "rewards": { - "rewards": null, - "period": "4" - } - }, - { - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "4971708547.150728253109751796" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", - "rewards": { - "rewards": null, - "period": "2" - } - }, - { - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "2095302590.555015731083724595" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "rewards": { - "rewards": null, - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1596804303.998904168738439964" - } - ], - "period": "10" - } - }, - { - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "7981599483.029009876099804721" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "12348237265.667906050348522004" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "541193976.848853395308213099" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1458919260.535587204455444789" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "rewards": { - "rewards": null, - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "16744963182.167013015150169260" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1864133135.176273727732462590" - } - ], - "period": "8" - } - }, - { - "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "rewards": { - "rewards": null, - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "10929960502.284962257920895496" - } - ], - "period": "5" - } - }, - { - "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "638790834.140965066703183270" - } - ], - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "rewards": { - "rewards": null, - "period": "3" - } - }, - { - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1571681108.047964868152707101" - } - ], - "period": "7" - } - }, - { - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1785517640.312737824040413180" - } - ], - "period": "6" - } - }, - { - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "rewards": { - "rewards": [ - { - "denom": "stake", - "amount": "1116422514.011874203580116273" - } - ], - "period": "7" - } - } - ], - "delegator_starting_infos": [ - { - "delegator_address": "cosmos1qqxeqqvjkh2ls3a0taukd8rydrqqad690nxkcc", - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "starting_info": { - "previous_period": "7", - "stake": "12420219756.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "starting_info": { - "previous_period": "3", - "stake": "12278061721.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "starting_info": { - "previous_period": "4", - "stake": "3831088.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "starting_info": { - "previous_period": "6", - "stake": "65633207.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", - "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "starting_info": { - "previous_period": "3", - "stake": "4141412671.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", - "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "starting_info": { - "previous_period": "5", - "stake": "1611728813.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "starting_info": { - "previous_period": "7", - "stake": "5978697013.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "starting_info": { - "previous_period": "4", - "stake": "8832434015.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "starting_info": { - "previous_period": "2", - "stake": "21431257869.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "starting_info": { - "previous_period": "6", - "stake": "3906909228.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "starting_info": { - "previous_period": "3", - "stake": "6479198849.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "starting_info": { - "previous_period": "4", - "stake": "24728825327.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "starting_info": { - "previous_period": "5", - "stake": "2665696727.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1qy0qwzljplfauvyhgayw6nxte2zxujh4tnq09z", - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "starting_info": { - "previous_period": "1", - "stake": "17076084961.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6", - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "starting_info": { - "previous_period": "3", - "stake": "27081595327.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "starting_info": { - "previous_period": "2", - "stake": "5366509387.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "starting_info": { - "previous_period": "2", - "stake": "8265210908.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "starting_info": { - "previous_period": "4", - "stake": "1415578984.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "starting_info": { - "previous_period": "3", - "stake": "2399562500.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1q9ed2n5wvzcrymaqltypazqzd2xv8d5aw58flt", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "starting_info": { - "previous_period": "5", - "stake": "393807838.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1rcru2vteas2kunww3zt4knx28krlestxydpwza", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "starting_info": { - "previous_period": "3", - "stake": "20016004053.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "starting_info": { - "previous_period": "4", - "stake": "9390268176.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "starting_info": { - "previous_period": "7", - "stake": "113007060.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "starting_info": { - "previous_period": "2", - "stake": "21462438160.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "starting_info": { - "previous_period": "6", - "stake": "411136992.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", - "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "starting_info": { - "previous_period": "1", - "stake": "8434736549.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", - "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "starting_info": { - "previous_period": "2", - "stake": "1856911069.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "starting_info": { - "previous_period": "6", - "stake": "9657784018.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "starting_info": { - "previous_period": "3", - "stake": "2267056403.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "starting_info": { - "previous_period": "5", - "stake": "1067919041.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "starting_info": { - "previous_period": "4", - "stake": "3023435039.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "starting_info": { - "previous_period": "4", - "stake": "250632594.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "starting_info": { - "previous_period": "5", - "stake": "632967960.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "starting_info": { - "previous_period": "6", - "stake": "5503709183.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "starting_info": { - "previous_period": "3", - "stake": "319721226.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1q0cw6hmrm4myx5c3zzmw6deelygsl2hrts2ju4", - "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", - "starting_info": { - "previous_period": "1", - "stake": "998337488.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "starting_info": { - "previous_period": "4", - "stake": "14607898235.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "starting_info": { - "previous_period": "6", - "stake": "16848374286.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "starting_info": { - "previous_period": "8", - "stake": "1128230444.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", - "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "starting_info": { - "previous_period": "3", - "stake": "15545552914.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", - "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", - "starting_info": { - "previous_period": "2", - "stake": "632273041.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", - "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", - "starting_info": { - "previous_period": "2", - "stake": "847666854.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "starting_info": { - "previous_period": "8", - "stake": "331591913.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "starting_info": { - "previous_period": "5", - "stake": "78323397.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "starting_info": { - "previous_period": "2", - "stake": "19004884526.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "starting_info": { - "previous_period": "9", - "stake": "489746723.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1l6u5cg3wcptmcjyhxtfrrfq3nu036acdauf0fy", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "starting_info": { - "previous_period": "6", - "stake": "15368943494.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", - "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", - "starting_info": { - "previous_period": "4", - "stake": "1750195180.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", - "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "starting_info": { - "previous_period": "4", - "stake": "4432663925.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "starting_info": { - "previous_period": "3", - "stake": "671769813.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "starting_info": { - "previous_period": "1", - "stake": "7134357042.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "starting_info": { - "previous_period": "3", - "stake": "177902750.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "starting_info": { - "previous_period": "4", - "stake": "126313.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1h72kkqt83nth0npqvgmardgelg6jyx7zupnypp", - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "starting_info": { - "previous_period": "2", - "stake": "1604525333.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "starting_info": { - "previous_period": "5", - "stake": "4686886799.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "starting_info": { - "previous_period": "7", - "stake": "2320211243.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "starting_info": { - "previous_period": "9", - "stake": "1406012334.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "starting_info": { - "previous_period": "10", - "stake": "14744952147.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "starting_info": { - "previous_period": "8", - "stake": "879369780.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "starting_info": { - "previous_period": "11", - "stake": "315931330.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1qlkz3yutzuz0el2ullpyyaflfp78x8rr2cgld7", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "starting_info": { - "previous_period": "2", - "stake": "24971252484.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "starting_info": { - "previous_period": "1", - "stake": "17451346039.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "starting_info": { - "previous_period": "5", - "stake": "7302955.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "starting_info": { - "previous_period": "4", - "stake": "2313732788.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "starting_info": { - "previous_period": "6", - "stake": "235709907.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", - "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "starting_info": { - "previous_period": "2", - "stake": "24914473521.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "starting_info": { - "previous_period": "3", - "stake": "58360958.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "starting_info": { - "previous_period": "1", - "stake": "107356796.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "starting_info": { - "previous_period": "4", - "stake": "141624981.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "starting_info": { - "previous_period": "3", - "stake": "3115334630.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "starting_info": { - "previous_period": "5", - "stake": "11943268264.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", - "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", - "starting_info": { - "previous_period": "2", - "stake": "5044911319.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "starting_info": { - "previous_period": "6", - "stake": "22896384744.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "starting_info": { - "previous_period": "4", - "stake": "6892307704.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "starting_info": { - "previous_period": "5", - "stake": "7497643277.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", - "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", - "starting_info": { - "previous_period": "1", - "stake": "203339835.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "starting_info": { - "previous_period": "4", - "stake": "1211564528.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "starting_info": { - "previous_period": "3", - "stake": "4778016243.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "starting_info": { - "previous_period": "5", - "stake": "68637287.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", - "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", - "starting_info": { - "previous_period": "1", - "stake": "7304584820.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", - "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "starting_info": { - "previous_period": "2", - "stake": "25069342080.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", - "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "starting_info": { - "previous_period": "3", - "stake": "1040485229.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "starting_info": { - "previous_period": "5", - "stake": "1195742287.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "starting_info": { - "previous_period": "6", - "stake": "1956086691.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "starting_info": { - "previous_period": "7", - "stake": "3423632102.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "starting_info": { - "previous_period": "7", - "stake": "22844129667.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "starting_info": { - "previous_period": "6", - "stake": "63638410.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "starting_info": { - "previous_period": "8", - "stake": "16096304.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "starting_info": { - "previous_period": "3", - "stake": "2280542883.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", - "starting_info": { - "previous_period": "4", - "stake": "101462019.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "starting_info": { - "previous_period": "3", - "stake": "19076209513.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "starting_info": { - "previous_period": "5", - "stake": "4784005.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "starting_info": { - "previous_period": "6", - "stake": "1316682053.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "starting_info": { - "previous_period": "2", - "stake": "2616582981.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", - "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", - "starting_info": { - "previous_period": "1", - "stake": "5183376555.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "starting_info": { - "previous_period": "3", - "stake": "6189191937.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "starting_info": { - "previous_period": "4", - "stake": "19589707878.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "starting_info": { - "previous_period": "5", - "stake": "23726525801.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "starting_info": { - "previous_period": "6", - "stake": "14430378546.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "starting_info": { - "previous_period": "4", - "stake": "667949570.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "starting_info": { - "previous_period": "2", - "stake": "2151028602.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "starting_info": { - "previous_period": "3", - "stake": "6774702429.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "starting_info": { - "previous_period": "7", - "stake": "1397139502.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "starting_info": { - "previous_period": "5", - "stake": "2401456661.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1zjzkk7l2jalrspy6500my8v0yy6ycz7el534zw", - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "starting_info": { - "previous_period": "3", - "stake": "562972916.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "starting_info": { - "previous_period": "5", - "stake": "2524305482.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "starting_info": { - "previous_period": "6", - "stake": "16993994.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "starting_info": { - "previous_period": "2", - "stake": "20291325837.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "starting_info": { - "previous_period": "5", - "stake": "15744595023.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "starting_info": { - "previous_period": "6", - "stake": "14549776414.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "starting_info": { - "previous_period": "8", - "stake": "4201547532.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "starting_info": { - "previous_period": "7", - "stake": "14577877248.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1znvq8jqpwxt5hk2lg5654l7eg7kap3rpgjm462", - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "starting_info": { - "previous_period": "6", - "stake": "13141132625.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "starting_info": { - "previous_period": "7", - "stake": "2041910728.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "starting_info": { - "previous_period": "3", - "stake": "1427892425.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "starting_info": { - "previous_period": "8", - "stake": "443348912.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", - "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "starting_info": { - "previous_period": "4", - "stake": "1866755172.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", - "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "starting_info": { - "previous_period": "5", - "stake": "2339204126.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", - "starting_info": { - "previous_period": "2", - "stake": "5951502740.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "starting_info": { - "previous_period": "5", - "stake": "4025204231.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1zu50umwgah6jhx07sw04ry0pv7fnvkpjmn8vl9", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "starting_info": { - "previous_period": "8", - "stake": "10178017385.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "starting_info": { - "previous_period": "9", - "stake": "18672701727.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "starting_info": { - "previous_period": "6", - "stake": "61795.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1cwk6x5smzaqhtrz95z0sf90d8a8d9vfrpaufnl", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "starting_info": { - "previous_period": "4", - "stake": "22113286739.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "starting_info": { - "previous_period": "7", - "stake": "90986838.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "starting_info": { - "previous_period": "2", - "stake": "927515526.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1rmyk79ktv6c8q48u78udw5p906fp0w058796d0", - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "starting_info": { - "previous_period": "8", - "stake": "251069497.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "starting_info": { - "previous_period": "4", - "stake": "8706091689.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "starting_info": { - "previous_period": "7", - "stake": "40296136.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1zah0g92ytwdvpchd3sceuanu7knhtu224vnt5k", - "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "starting_info": { - "previous_period": "3", - "stake": "17763934255.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "starting_info": { - "previous_period": "4", - "stake": "4748086.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1z7ruhrtfg8v2xv8egfyxldt2xaygspykszntzv", - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "starting_info": { - "previous_period": "1", - "stake": "984669335.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "starting_info": { - "previous_period": "3", - "stake": "641381462.000000000000000000", - "creation_height": "3" - } - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "starting_info": { - "previous_period": "2", - "stake": "11523735546.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", - "starting_info": { - "previous_period": "2", - "stake": "9436725725.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "starting_info": { - "previous_period": "4", - "stake": "652452.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "starting_info": { - "previous_period": "2", - "stake": "18814602669.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "starting_info": { - "previous_period": "3", - "stake": "1441730941.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "starting_info": { - "previous_period": "5", - "stake": "2341551967.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "starting_info": { - "previous_period": "4", - "stake": "38918270.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg", - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "starting_info": { - "previous_period": "3", - "stake": "10514537848.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "starting_info": { - "previous_period": "6", - "stake": "4946049715.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "starting_info": { - "previous_period": "5", - "stake": "11650293201.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "starting_info": { - "previous_period": "2", - "stake": "5810217010.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "starting_info": { - "previous_period": "3", - "stake": "260728313.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "starting_info": { - "previous_period": "4", - "stake": "5561406384.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "starting_info": { - "previous_period": "3", - "stake": "1721804886.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "starting_info": { - "previous_period": "2", - "stake": "4722611768.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "starting_info": { - "previous_period": "2", - "stake": "798486027.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "starting_info": { - "previous_period": "3", - "stake": "4660142050.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "starting_info": { - "previous_period": "4", - "stake": "2312465.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1rtw2ev4xm89vaqzwc7k520jlvrvlqnevk5f53y", - "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", - "starting_info": { - "previous_period": "1", - "stake": "12268746738.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", - "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "starting_info": { - "previous_period": "2", - "stake": "3185714296.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "starting_info": { - "previous_period": "3", - "stake": "18797742.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", - "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "starting_info": { - "previous_period": "4", - "stake": "1620479191.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", - "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "starting_info": { - "previous_period": "5", - "stake": "47693559541.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", - "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", - "starting_info": { - "previous_period": "5", - "stake": "12584124.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", - "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", - "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "starting_info": { - "previous_period": "2", - "stake": "1116365771.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "starting_info": { - "previous_period": "6", - "stake": "1246069516.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "starting_info": { - "previous_period": "7", - "stake": "686761769.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "starting_info": { - "previous_period": "3", - "stake": "2944397287.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "starting_info": { - "previous_period": "2", - "stake": "2830380125.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "starting_info": { - "previous_period": "5", - "stake": "8178830.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "starting_info": { - "previous_period": "2", - "stake": "11989838708.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", - "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "starting_info": { - "previous_period": "5", - "stake": "21856354084.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1r7kh63jvjhwqraux9wtm3jat8ggm437w9cxcxc", - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "starting_info": { - "previous_period": "1", - "stake": "1576771801.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "starting_info": { - "previous_period": "3", - "stake": "1096219390.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "starting_info": { - "previous_period": "5", - "stake": "9417801394.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "starting_info": { - "previous_period": "3", - "stake": "2560223943.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1rlzurkn0mywyldswcafhu7r8r0tha4s5prs34u", - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "starting_info": { - "previous_period": "1", - "stake": "5545092214.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1556dzhyv2gth4huxdlyur65c2sm3np2en3zzhl", - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "starting_info": { - "previous_period": "4", - "stake": "6217452551.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "starting_info": { - "previous_period": "3", - "stake": "1615518832.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "starting_info": { - "previous_period": "4", - "stake": "2449818489.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "starting_info": { - "previous_period": "6", - "stake": "106422691.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "starting_info": { - "previous_period": "5", - "stake": "508102761.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", - "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", - "starting_info": { - "previous_period": "2", - "stake": "5346735375.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933", - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "starting_info": { - "previous_period": "1", - "stake": "18217843326.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "starting_info": { - "previous_period": "2", - "stake": "187053499.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "starting_info": { - "previous_period": "3", - "stake": "6661497942.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", - "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "starting_info": { - "previous_period": "5", - "stake": "35129356.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", - "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "starting_info": { - "previous_period": "4", - "stake": "286435366.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1y3h72de80x06cz7fs3adwlnp0r8pjazw0r5707", - "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", - "starting_info": { - "previous_period": "1", - "stake": "3323388806.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1yj95f65syc75ptwcy0n7kafdq33awc2ve8hthq", - "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "starting_info": { - "previous_period": "3", - "stake": "313632363.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", - "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "starting_info": { - "previous_period": "4", - "stake": "127648169.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "starting_info": { - "previous_period": "7", - "stake": "1455198371.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "starting_info": { - "previous_period": "6", - "stake": "3978844161.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a", - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "starting_info": { - "previous_period": "4", - "stake": "5078782917.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "starting_info": { - "previous_period": "5", - "stake": "245003068.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "starting_info": { - "previous_period": "1", - "stake": "5608632459.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "starting_info": { - "previous_period": "3", - "stake": "402116649.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "starting_info": { - "previous_period": "2", - "stake": "7094821824.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "starting_info": { - "previous_period": "7", - "stake": "1727917227.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "starting_info": { - "previous_period": "6", - "stake": "4129974295.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "starting_info": { - "previous_period": "5", - "stake": "74047563.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "starting_info": { - "previous_period": "4", - "stake": "19129298483.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "starting_info": { - "previous_period": "5", - "stake": "20515760055.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "starting_info": { - "previous_period": "9", - "stake": "97785114.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "starting_info": { - "previous_period": "8", - "stake": "7055399052.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "starting_info": { - "previous_period": "7", - "stake": "23981371945.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "starting_info": { - "previous_period": "7", - "stake": "3140280772.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "starting_info": { - "previous_period": "4", - "stake": "12299732605.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "starting_info": { - "previous_period": "8", - "stake": "1993086195.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "starting_info": { - "previous_period": "9", - "stake": "1317573671.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1ylf26t6vhvugawg87328ng2ug4d8f25syxp64c", - "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "starting_info": { - "previous_period": "1", - "stake": "24248574347.000000000000000000", - "creation_height": "9" - } - }, - { - "delegator_address": "cosmos1q6eeennfulay5kz3lym38up6gq5ruf6h43cg94", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "starting_info": { - "previous_period": "9", - "stake": "17332637313.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "starting_info": { - "previous_period": "5", - "stake": "7050196605.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1easmlky76c302my07gffjxjw0a2usueaw8j46t", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "starting_info": { - "previous_period": "4", - "stake": "23176847255.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1m4xvwvq7qrr0wy0ryeu24eu8482h4n7en2x2mh", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "starting_info": { - "previous_period": "8", - "stake": "10673600913.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "starting_info": { - "previous_period": "10", - "stake": "24565420625.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", - "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "starting_info": { - "previous_period": "1", - "stake": "86630682.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "starting_info": { - "previous_period": "2", - "stake": "759535878.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "starting_info": { - "previous_period": "4", - "stake": "13382062777.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "starting_info": { - "previous_period": "5", - "stake": "562769066.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "starting_info": { - "previous_period": "3", - "stake": "3961673047.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "starting_info": { - "previous_period": "6", - "stake": "917167136.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "starting_info": { - "previous_period": "2", - "stake": "7332243055.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "starting_info": { - "previous_period": "7", - "stake": "61614117.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "starting_info": { - "previous_period": "5", - "stake": "1936045503.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "starting_info": { - "previous_period": "2", - "stake": "5053223393.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "starting_info": { - "previous_period": "3", - "stake": "23065486708.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "starting_info": { - "previous_period": "6", - "stake": "2186207273.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", - "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "starting_info": { - "previous_period": "3", - "stake": "2510854249.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "starting_info": { - "previous_period": "6", - "stake": "81292948.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", - "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", - "starting_info": { - "previous_period": "3", - "stake": "2439056961.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "starting_info": { - "previous_period": "2", - "stake": "2726229723.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "starting_info": { - "previous_period": "3", - "stake": "87813996.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "starting_info": { - "previous_period": "4", - "stake": "457491.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos19deqn6g9q7mnhzg5j0qr25k9gz74pwlph5p50r", - "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "starting_info": { - "previous_period": "1", - "stake": "2125901000.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", - "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "starting_info": { - "previous_period": "2", - "stake": "165098526.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1vuws77sz0xzvz8y0dg6wjz9fzd7plxpk29ljn7", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "starting_info": { - "previous_period": "8", - "stake": "1285996047.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "starting_info": { - "previous_period": "6", - "stake": "2012957230.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "starting_info": { - "previous_period": "4", - "stake": "3002359447.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos13ps0cszg8lqn0mkzndvhxwaew8yd56s8tl9j20", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "starting_info": { - "previous_period": "7", - "stake": "7351040665.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "starting_info": { - "previous_period": "10", - "stake": "14714606427.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "starting_info": { - "previous_period": "9", - "stake": "2696689996.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", - "starting_info": { - "previous_period": "6", - "stake": "290004202.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "starting_info": { - "previous_period": "2", - "stake": "14337017011.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos193pvwgxpxnd6tgz0gtyl00dq8r3ygeflnhaxpm", - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "starting_info": { - "previous_period": "3", - "stake": "7421590485.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "starting_info": { - "previous_period": "4", - "stake": "22489048481.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", - "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", - "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "starting_info": { - "previous_period": "3", - "stake": "2738776488.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75pf45v0", - "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", - "starting_info": { - "previous_period": "3", - "stake": "5061822.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1xq58llsgh49tsz22grs28jk0p7tvswlcjcrl32", - "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", - "starting_info": { - "previous_period": "1", - "stake": "2859472400.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "starting_info": { - "previous_period": "5", - "stake": "96280874.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "starting_info": { - "previous_period": "4", - "stake": "3736546194.000000000000000000", - "creation_height": "9" - } - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "starting_info": { - "previous_period": "6", - "stake": "155780036.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1xxurm2uymwd04sjxqedjae5r0zxhalh26skxct", - "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "starting_info": { - "previous_period": "1", - "stake": "8374503099.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "starting_info": { - "previous_period": "2", - "stake": "995278414.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalavv03x7", - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "starting_info": { - "previous_period": "4", - "stake": "41888452.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "starting_info": { - "previous_period": "5", - "stake": "909672651.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "starting_info": { - "previous_period": "6", - "stake": "322814192.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "starting_info": { - "previous_period": "2", - "stake": "1444898370.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "starting_info": { - "previous_period": "4", - "stake": "16141764494.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "starting_info": { - "previous_period": "3", - "stake": "163640358.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", - "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "starting_info": { - "previous_period": "2", - "stake": "2583372381.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "starting_info": { - "previous_period": "3", - "stake": "11868568217.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lpz963de", - "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "starting_info": { - "previous_period": "2", - "stake": "6669322099.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "starting_info": { - "previous_period": "5", - "stake": "185779104.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", - "starting_info": { - "previous_period": "3", - "stake": "1751100.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1py3htj8kmztj0ecdrhcgcmet6vupr9hvlhxkwe", - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "starting_info": { - "previous_period": "6", - "stake": "21846969213.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "starting_info": { - "previous_period": "4", - "stake": "15549849.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "starting_info": { - "previous_period": "5", - "stake": "282264887.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", - "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "starting_info": { - "previous_period": "4", - "stake": "7824280124.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", - "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "starting_info": { - "previous_period": "3", - "stake": "633536370.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", - "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", - "starting_info": { - "previous_period": "3", - "stake": "13735096388.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "starting_info": { - "previous_period": "3", - "stake": "1199565347.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je", - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "starting_info": { - "previous_period": "6", - "stake": "19109522.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "starting_info": { - "previous_period": "7", - "stake": "2713168340.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "starting_info": { - "previous_period": "7", - "stake": "88293788.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "starting_info": { - "previous_period": "10", - "stake": "526869097.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "starting_info": { - "previous_period": "11", - "stake": "9460610373.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", - "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "starting_info": { - "previous_period": "5", - "stake": "9032281.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", - "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "starting_info": { - "previous_period": "3", - "stake": "16205811760.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", - "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "starting_info": { - "previous_period": "3", - "stake": "4574405710.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", - "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "starting_info": { - "previous_period": "2", - "stake": "18778025755.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "starting_info": { - "previous_period": "8", - "stake": "3559099530.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "starting_info": { - "previous_period": "4", - "stake": "20147750165.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "starting_info": { - "previous_period": "6", - "stake": "9304209052.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "starting_info": { - "previous_period": "7", - "stake": "1682063162.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", - "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", - "starting_info": { - "previous_period": "1", - "stake": "1577104716.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "starting_info": { - "previous_period": "7", - "stake": "823335564.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "starting_info": { - "previous_period": "9", - "stake": "17266683.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "starting_info": { - "previous_period": "3", - "stake": "5370042726.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", - "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "starting_info": { - "previous_period": "1", - "stake": "81607574.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "starting_info": { - "previous_period": "2", - "stake": "254035.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "starting_info": { - "previous_period": "5", - "stake": "38719909925.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos188yd2umzwfwen7es68wrlh6auu3p8jhz0qfgej", - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "starting_info": { - "previous_period": "7", - "stake": "786295043.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "starting_info": { - "previous_period": "3", - "stake": "3315560612.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "starting_info": { - "previous_period": "6", - "stake": "137048444.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "starting_info": { - "previous_period": "3", - "stake": "183795109.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos18gmd4r8ydls55yvgda4d8pfandk0xem5q7eat8", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "starting_info": { - "previous_period": "6", - "stake": "19225895723.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "starting_info": { - "previous_period": "8", - "stake": "1356197798.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "starting_info": { - "previous_period": "7", - "stake": "967842562.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "starting_info": { - "previous_period": "5", - "stake": "916587.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos18fkw6s4hnj2llxljrkleetgns2y0h0vjg8kmef", - "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "starting_info": { - "previous_period": "1", - "stake": "29256610441.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos194x33ngarpaach5g69g60cd2pjq8h0hqkfvk35", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "starting_info": { - "previous_period": "7", - "stake": "2698972611.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "starting_info": { - "previous_period": "3", - "stake": "12146467079.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "starting_info": { - "previous_period": "6", - "stake": "15899234337.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "starting_info": { - "previous_period": "4", - "stake": "10949797827.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "starting_info": { - "previous_period": "5", - "stake": "23356660678.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "starting_info": { - "previous_period": "5", - "stake": "5080809691.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "starting_info": { - "previous_period": "2", - "stake": "4422731613.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "starting_info": { - "previous_period": "3", - "stake": "9393510961.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", - "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", - "starting_info": { - "previous_period": "4", - "stake": "859335658.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", - "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "starting_info": { - "previous_period": "5", - "stake": "40933654.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", - "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "starting_info": { - "previous_period": "6", - "stake": "179784223.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "starting_info": { - "previous_period": "8", - "stake": "233343713.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1ftj05w0hmw2xxw5p7gvr258j2824qd8r2xdk9e", - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "starting_info": { - "previous_period": "6", - "stake": "12407365569.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "starting_info": { - "previous_period": "4", - "stake": "352271656.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "starting_info": { - "previous_period": "7", - "stake": "39749190.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "starting_info": { - "previous_period": "3", - "stake": "8989585334.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "starting_info": { - "previous_period": "6", - "stake": "1418840382.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "starting_info": { - "previous_period": "4", - "stake": "585232700.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "starting_info": { - "previous_period": "5", - "stake": "312724720.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", - "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "starting_info": { - "previous_period": "3", - "stake": "2303096766.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", - "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "starting_info": { - "previous_period": "4", - "stake": "712016860.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "starting_info": { - "previous_period": "7", - "stake": "21228627.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "starting_info": { - "previous_period": "4", - "stake": "7720105335.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "starting_info": { - "previous_period": "6", - "stake": "2104208415.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "starting_info": { - "previous_period": "3", - "stake": "7682598.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "starting_info": { - "previous_period": "1", - "stake": "8365880246.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1864wj4twqatq54rrxl5jmfey55tmh0hvgmd9yw", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "starting_info": { - "previous_period": "5", - "stake": "423877981.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "starting_info": { - "previous_period": "3", - "stake": "1456184772.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "starting_info": { - "previous_period": "4", - "stake": "32924160.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "starting_info": { - "previous_period": "6", - "stake": "174754983.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv", - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "starting_info": { - "previous_period": "1", - "stake": "12717644032.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "starting_info": { - "previous_period": "2", - "stake": "20234365401.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "starting_info": { - "previous_period": "3", - "stake": "11937090067.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "starting_info": { - "previous_period": "6", - "stake": "139593046.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "starting_info": { - "previous_period": "7", - "stake": "2225212413.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "starting_info": { - "previous_period": "6", - "stake": "14461099488.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "starting_info": { - "previous_period": "8", - "stake": "785421895.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "starting_info": { - "previous_period": "4", - "stake": "17547096641.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "starting_info": { - "previous_period": "6", - "stake": "1294419142.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1g95xvy8qgzcvcl05fse0mpxzdfv3w88tpexycr", - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "starting_info": { - "previous_period": "7", - "stake": "2300967060.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "starting_info": { - "previous_period": "5", - "stake": "1829057.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "starting_info": { - "previous_period": "4", - "stake": "13950070710.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", - "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "starting_info": { - "previous_period": "4", - "stake": "2258309.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "starting_info": { - "previous_period": "4", - "stake": "2714965216.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", - "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", - "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", - "starting_info": { - "previous_period": "1", - "stake": "1252735315.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm", - "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", - "starting_info": { - "previous_period": "2", - "stake": "5701177554.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "starting_info": { - "previous_period": "3", - "stake": "17483443758.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "starting_info": { - "previous_period": "2", - "stake": "18762995915.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", - "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", - "starting_info": { - "previous_period": "2", - "stake": "4474063302.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", - "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", - "starting_info": { - "previous_period": "3", - "stake": "9095777401.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "starting_info": { - "previous_period": "8", - "stake": "12690053528.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "starting_info": { - "previous_period": "5", - "stake": "2399862586.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "starting_info": { - "previous_period": "6", - "stake": "1729736194.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "starting_info": { - "previous_period": "7", - "stake": "14815040085.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", - "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "starting_info": { - "previous_period": "4", - "stake": "8792247810.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", - "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "starting_info": { - "previous_period": "3", - "stake": "2968081872.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1gh67zgx4f9d64ctqhtascuh87805v8yffrfytl", - "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", - "starting_info": { - "previous_period": "3", - "stake": "602352708.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1gayzja3zz6unep8ftnpunt2wefazs3jhunl5az", - "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", - "starting_info": { - "previous_period": "2", - "stake": "4639932033.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", - "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", - "starting_info": { - "previous_period": "1", - "stake": "556310530.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "starting_info": { - "previous_period": "6", - "stake": "526885228.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "starting_info": { - "previous_period": "8", - "stake": "28000486.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "starting_info": { - "previous_period": "10", - "stake": "4300294602.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "starting_info": { - "previous_period": "11", - "stake": "2237914169.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "starting_info": { - "previous_period": "12", - "stake": "7482618743.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "starting_info": { - "previous_period": "9", - "stake": "8362968596.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1glku8mx4nzp5crkjt7px9lfe4flfge3zf64tud", - "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "starting_info": { - "previous_period": "2", - "stake": "16236700229.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "starting_info": { - "previous_period": "2", - "stake": "9950725535.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "starting_info": { - "previous_period": "9", - "stake": "6990856673.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "starting_info": { - "previous_period": "10", - "stake": "9220026.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "starting_info": { - "previous_period": "5", - "stake": "789297947.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "starting_info": { - "previous_period": "8", - "stake": "25069342080.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "starting_info": { - "previous_period": "7", - "stake": "127732919.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", - "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "starting_info": { - "previous_period": "1", - "stake": "1447202506.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos16jj80c7d94m772cn77zwcuhnqcl6y95kepxvja", - "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "starting_info": { - "previous_period": "2", - "stake": "3841134273.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2", - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "starting_info": { - "previous_period": "4", - "stake": "68061939.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "starting_info": { - "previous_period": "3", - "stake": "11773826677.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "starting_info": { - "previous_period": "5", - "stake": "6926527802.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1f2pvewnws73u0z5wsfmv5uqudwxl6jupfm6nta", - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "starting_info": { - "previous_period": "4", - "stake": "25069342080.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "starting_info": { - "previous_period": "3", - "stake": "7367311429.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "starting_info": { - "previous_period": "6", - "stake": "74135685.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "starting_info": { - "previous_period": "8", - "stake": "202358889.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "starting_info": { - "previous_period": "9", - "stake": "5068354349.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "starting_info": { - "previous_period": "10", - "stake": "6422847905.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "starting_info": { - "previous_period": "7", - "stake": "15967116837.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "starting_info": { - "previous_period": "3", - "stake": "852563445.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "starting_info": { - "previous_period": "1", - "stake": "209918859.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1f7utq63ae24m6aqw4metxjrc5q76j8h4gcgaxd", - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "starting_info": { - "previous_period": "4", - "stake": "23676093358.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "starting_info": { - "previous_period": "2", - "stake": "2867035102.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "starting_info": { - "previous_period": "5", - "stake": "200187880.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "starting_info": { - "previous_period": "6", - "stake": "61726947.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "starting_info": { - "previous_period": "4", - "stake": "11238205953.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "starting_info": { - "previous_period": "3", - "stake": "1627510175.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "starting_info": { - "previous_period": "3", - "stake": "335240579.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "starting_info": { - "previous_period": "4", - "stake": "4469703294.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "starting_info": { - "previous_period": "2", - "stake": "19618367974.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "starting_info": { - "previous_period": "3", - "stake": "24818709486.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "starting_info": { - "previous_period": "2", - "stake": "80752627.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "starting_info": { - "previous_period": "1", - "stake": "693338797.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "starting_info": { - "previous_period": "4", - "stake": "670350742.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "starting_info": { - "previous_period": "6", - "stake": "1116213901.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos160jtaz9c35nr7dx349ezfzvs3xfdzm3mlxgulk", - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "starting_info": { - "previous_period": "7", - "stake": "23889133768.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "starting_info": { - "previous_period": "5", - "stake": "23419734247.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "starting_info": { - "previous_period": "2", - "stake": "22035723908.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4", - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "starting_info": { - "previous_period": "3", - "stake": "885018304.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "starting_info": { - "previous_period": "4", - "stake": "4147746231.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", - "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", - "starting_info": { - "previous_period": "1", - "stake": "12112810368.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "starting_info": { - "previous_period": "6", - "stake": "2228638557.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1fc96780mrsxn5kgplhtna40qepjgrm9wsyly02", - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "starting_info": { - "previous_period": "3", - "stake": "15719680142.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "starting_info": { - "previous_period": "4", - "stake": "2711574997.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "starting_info": { - "previous_period": "4", - "stake": "37913276.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "starting_info": { - "previous_period": "2", - "stake": "9737598105.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "starting_info": { - "previous_period": "3", - "stake": "18799915325.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "starting_info": { - "previous_period": "11", - "stake": "2032334424.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "starting_info": { - "previous_period": "8", - "stake": "3326376911.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos12eynrdzx2jqz5u92hgmhl9ga6hmghqfv0xvns8", - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "starting_info": { - "previous_period": "10", - "stake": "2461085809.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "starting_info": { - "previous_period": "9", - "stake": "13348917907.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", - "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "starting_info": { - "previous_period": "2", - "stake": "10554411.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", - "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "starting_info": { - "previous_period": "3", - "stake": "1360036310.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos12q3w0j5hp023hdjafgc357hy7kkha296f4xrjf", - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "starting_info": { - "previous_period": "2", - "stake": "19013093201.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "starting_info": { - "previous_period": "3", - "stake": "1637026536.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "starting_info": { - "previous_period": "4", - "stake": "6724622674.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "starting_info": { - "previous_period": "6", - "stake": "397947789.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "starting_info": { - "previous_period": "7", - "stake": "20540852.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m", - "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", - "starting_info": { - "previous_period": "1", - "stake": "2878820932.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos12r0m6hwrnn0jy02tnhmk328d7p68x2rndzt0j5", - "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "starting_info": { - "previous_period": "1", - "stake": "9649353957.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "starting_info": { - "previous_period": "3", - "stake": "11280504984.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "starting_info": { - "previous_period": "6", - "stake": "1630410562.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "starting_info": { - "previous_period": "5", - "stake": "2714767582.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "starting_info": { - "previous_period": "5", - "stake": "11887809820.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "starting_info": { - "previous_period": "3", - "stake": "782001327.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "starting_info": { - "previous_period": "2", - "stake": "837111535.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "starting_info": { - "previous_period": "4", - "stake": "998573733.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", - "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "starting_info": { - "previous_period": "2", - "stake": "5637854002.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890", - "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "starting_info": { - "previous_period": "3", - "stake": "9648503235.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos12f4fpl936ld8c64dxqgwv65p42na8dcnv9g7ku", - "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "starting_info": { - "previous_period": "7", - "stake": "4840284805.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "starting_info": { - "previous_period": "8", - "stake": "145922218.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "starting_info": { - "previous_period": "5", - "stake": "11322194414.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1wtn9tf6wjwmwmddrk377cdl8fd96hexajyhfat", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "starting_info": { - "previous_period": "3", - "stake": "18471816853.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "starting_info": { - "previous_period": "4", - "stake": "9991492.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "starting_info": { - "previous_period": "2", - "stake": "15288776108.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", - "starting_info": { - "previous_period": "1", - "stake": "6943791722.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "starting_info": { - "previous_period": "5", - "stake": "19543436761.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "starting_info": { - "previous_period": "4", - "stake": "203058104.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "starting_info": { - "previous_period": "3", - "stake": "533098317.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "starting_info": { - "previous_period": "5", - "stake": "5090332.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "starting_info": { - "previous_period": "2", - "stake": "6087225472.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "starting_info": { - "previous_period": "4", - "stake": "111239871.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", - "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "starting_info": { - "previous_period": "4", - "stake": "2521177822.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "starting_info": { - "previous_period": "2", - "stake": "7038279055.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1tpxdvj93x9rqz89zhh0tszegcwtq8mgtdknrw5", - "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", - "starting_info": { - "previous_period": "1", - "stake": "13387012198.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1tzz5l8sw05e0tm5l0gxuvp04qt42stu3kqwf4s", - "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "starting_info": { - "previous_period": "1", - "stake": "7946485541.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "starting_info": { - "previous_period": "2", - "stake": "3084665544.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1tz087eh88lqkesr77yl6ys9dw95qysfqtff52a", - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "starting_info": { - "previous_period": "1", - "stake": "25027795872.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "starting_info": { - "previous_period": "2", - "stake": "2956537033.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1h84c3yuxd6k7950wh868tcsj5tmvzetykv8lld", - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "starting_info": { - "previous_period": "3", - "stake": "3599965031.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "starting_info": { - "previous_period": "7", - "stake": "1887976035.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "starting_info": { - "previous_period": "3", - "stake": "13987549940.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "starting_info": { - "previous_period": "5", - "stake": "277893955.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "starting_info": { - "previous_period": "2", - "stake": "5284614159.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "starting_info": { - "previous_period": "4", - "stake": "1330954959.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "starting_info": { - "previous_period": "8", - "stake": "100158705.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "starting_info": { - "previous_period": "7", - "stake": "9951710774.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "starting_info": { - "previous_period": "6", - "stake": "16439836386.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "starting_info": { - "previous_period": "5", - "stake": "264012997.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "starting_info": { - "previous_period": "4", - "stake": "3391706116.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "starting_info": { - "previous_period": "7", - "stake": "35571003.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1tgghhdcxdgxay7hp2p0lv2fs656c4c0xfzlga5", - "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", - "starting_info": { - "previous_period": "2", - "stake": "243264064.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "starting_info": { - "previous_period": "3", - "stake": "10725445.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "starting_info": { - "previous_period": "2", - "stake": "7078635448.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1tftatt0lp0v59qqf449pdqar8w3yj7n7xa7sk6", - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "starting_info": { - "previous_period": "1", - "stake": "9168014109.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "starting_info": { - "previous_period": "6", - "stake": "9132286197.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "starting_info": { - "previous_period": "9", - "stake": "9495710.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "starting_info": { - "previous_period": "8", - "stake": "459551216.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "starting_info": { - "previous_period": "7", - "stake": "4718627.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "starting_info": { - "previous_period": "5", - "stake": "3078912948.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "starting_info": { - "previous_period": "4", - "stake": "121624664.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "starting_info": { - "previous_period": "11", - "stake": "7210211965.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "starting_info": { - "previous_period": "6", - "stake": "20548231148.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "starting_info": { - "previous_period": "10", - "stake": "254473474.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1twu2lvgp3erk6gups2a8nae3jdahaj2xmlufsa", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "starting_info": { - "previous_period": "5", - "stake": "25069342080.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "starting_info": { - "previous_period": "7", - "stake": "9719656784.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", - "starting_info": { - "previous_period": "3", - "stake": "365167856.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", - "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "starting_info": { - "previous_period": "3", - "stake": "85878287.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", - "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "starting_info": { - "previous_period": "4", - "stake": "22429572439.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos18k4yz84xrjqvrq9u7sehvje3ax4aspcksauctw", - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "starting_info": { - "previous_period": "3", - "stake": "10553965715.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "starting_info": { - "previous_period": "4", - "stake": "18283793775.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "starting_info": { - "previous_period": "5", - "stake": "718921425.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "starting_info": { - "previous_period": "4", - "stake": "49181074.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "starting_info": { - "previous_period": "3", - "stake": "3111978.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "starting_info": { - "previous_period": "2", - "stake": "25069342080.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1z7sj5sg2cnkg4phzrswwjkkq8p2d6434pcyv2p", - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "starting_info": { - "previous_period": "4", - "stake": "404583402.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "starting_info": { - "previous_period": "6", - "stake": "6106439259.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "starting_info": { - "previous_period": "5", - "stake": "188596153.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "starting_info": { - "previous_period": "3", - "stake": "146683.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1tmddg4wjnj38wrd8t6xq092jyw3x4hcup6n00u", - "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", - "starting_info": { - "previous_period": "1", - "stake": "7029801264.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "starting_info": { - "previous_period": "5", - "stake": "138733335.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "starting_info": { - "previous_period": "6", - "stake": "22265567297.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "starting_info": { - "previous_period": "3", - "stake": "3540231870.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos174ycyhzg358nxm8r6qunzsyx48uk8fc404ckyf", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "starting_info": { - "previous_period": "4", - "stake": "8680187636.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", - "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "starting_info": { - "previous_period": "4", - "stake": "2948850137.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "starting_info": { - "previous_period": "5", - "stake": "143748684.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", - "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "starting_info": { - "previous_period": "1", - "stake": "35599530.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", - "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "starting_info": { - "previous_period": "2", - "stake": "9203549637.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1vqm5fdsflvnee33gk3d5pz7j6tf6dsp28eemcq", - "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "starting_info": { - "previous_period": "2", - "stake": "16949426508.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", - "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "starting_info": { - "previous_period": "1", - "stake": "731773122.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "starting_info": { - "previous_period": "2", - "stake": "5311127.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", - "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "starting_info": { - "previous_period": "7", - "stake": "4778613408.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "starting_info": { - "previous_period": "6", - "stake": "405352.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "starting_info": { - "previous_period": "5", - "stake": "11759488693.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "starting_info": { - "previous_period": "3", - "stake": "2555870064.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "starting_info": { - "previous_period": "4", - "stake": "1003510952.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "starting_info": { - "previous_period": "6", - "stake": "1792101072.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "starting_info": { - "previous_period": "8", - "stake": "3213489253.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", - "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "starting_info": { - "previous_period": "1", - "stake": "18158211957.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", - "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", - "starting_info": { - "previous_period": "2", - "stake": "1728294636.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", - "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "starting_info": { - "previous_period": "4", - "stake": "5071075450.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", - "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "starting_info": { - "previous_period": "3", - "stake": "9022206595.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "starting_info": { - "previous_period": "9", - "stake": "13283049905.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "starting_info": { - "previous_period": "5", - "stake": "175132304.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1dgzvesl67z96ttlt5ulga25phe8pnspt663dvr", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "starting_info": { - "previous_period": "11", - "stake": "7195021215.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "starting_info": { - "previous_period": "4", - "stake": "1781975477.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "starting_info": { - "previous_period": "10", - "stake": "870772585.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "starting_info": { - "previous_period": "7", - "stake": "2129694907.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "starting_info": { - "previous_period": "3", - "stake": "5799285.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", - "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "starting_info": { - "previous_period": "2", - "stake": "5221113247.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", - "starting_info": { - "previous_period": "2", - "stake": "10613605390.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "starting_info": { - "previous_period": "4", - "stake": "3423234396.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "starting_info": { - "previous_period": "3", - "stake": "11105705687.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "starting_info": { - "previous_period": "6", - "stake": "2244459128.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", - "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "starting_info": { - "previous_period": "2", - "stake": "17594927523.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "starting_info": { - "previous_period": "3", - "stake": "110749654.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "starting_info": { - "previous_period": "1", - "stake": "2769362709.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "starting_info": { - "previous_period": "3", - "stake": "9488989139.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "starting_info": { - "previous_period": "4", - "stake": "1612739646.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", - "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "starting_info": { - "previous_period": "2", - "stake": "1392479696.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", - "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", - "starting_info": { - "previous_period": "1", - "stake": "49835911.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpdhe28d", - "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "starting_info": { - "previous_period": "1", - "stake": "17862559018.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "starting_info": { - "previous_period": "4", - "stake": "23869776733.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "starting_info": { - "previous_period": "2", - "stake": "16096471780.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "starting_info": { - "previous_period": "3", - "stake": "23728387848.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "starting_info": { - "previous_period": "5", - "stake": "22288761371.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "starting_info": { - "previous_period": "6", - "stake": "1483865601.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcy522k3", - "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", - "starting_info": { - "previous_period": "4", - "stake": "1291312379.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "starting_info": { - "previous_period": "4", - "stake": "1085633282.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "starting_info": { - "previous_period": "5", - "stake": "5379750065.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1d5vv20893q06tx29mlqmefnyf0w3hn0v07w9p9", - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "starting_info": { - "previous_period": "2", - "stake": "186531063.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "starting_info": { - "previous_period": "2", - "stake": "463086222.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "starting_info": { - "previous_period": "3", - "stake": "8006017871.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "starting_info": { - "previous_period": "1", - "stake": "19056636038.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1vlvxlpzzrk5eye9c3z9uedk0085h7fdvehv32n", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "starting_info": { - "previous_period": "5", - "stake": "1749823283.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lypeadd", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "starting_info": { - "previous_period": "3", - "stake": "7137720854.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "starting_info": { - "previous_period": "6", - "stake": "454715151.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1etrkjjjjvuej87yu2pv4mcmhjsjqsn5hm9n043", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "starting_info": { - "previous_period": "4", - "stake": "23226246980.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", - "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "starting_info": { - "previous_period": "3", - "stake": "8566436836.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", - "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "starting_info": { - "previous_period": "2", - "stake": "11267665039.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "starting_info": { - "previous_period": "3", - "stake": "9627765333.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1f58nf9lzm4d5x9grnt3a3vd9c75szj95f6mm5s", - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "starting_info": { - "previous_period": "8", - "stake": "15007199497.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "starting_info": { - "previous_period": "4", - "stake": "61880678.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1j9vhccgf8520gtz7zn5jxj9lk3nqg0wx479kwp", - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "starting_info": { - "previous_period": "5", - "stake": "12478510598.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "starting_info": { - "previous_period": "4", - "stake": "13273588734.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos10p78pcqm2slk4x0pfxl9ht5spskwquhzptwzt8", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "starting_info": { - "previous_period": "8", - "stake": "3812433475.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "starting_info": { - "previous_period": "7", - "stake": "836513743.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "starting_info": { - "previous_period": "6", - "stake": "12642546664.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "starting_info": { - "previous_period": "3", - "stake": "6110815364.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "starting_info": { - "previous_period": "2", - "stake": "11780930912.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "starting_info": { - "previous_period": "4", - "stake": "2561447038.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", - "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", - "starting_info": { - "previous_period": "2", - "stake": "7094282971.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "starting_info": { - "previous_period": "5", - "stake": "5596804179.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q", - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "starting_info": { - "previous_period": "2", - "stake": "2844380010.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "starting_info": { - "previous_period": "4", - "stake": "425532255.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "starting_info": { - "previous_period": "5", - "stake": "4008660259.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "starting_info": { - "previous_period": "7", - "stake": "375360.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "starting_info": { - "previous_period": "2", - "stake": "18386606315.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "starting_info": { - "previous_period": "8", - "stake": "5093480749.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", - "starting_info": { - "previous_period": "1", - "stake": "1553435623.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "starting_info": { - "previous_period": "8", - "stake": "3332218539.999999999999999999", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "starting_info": { - "previous_period": "9", - "stake": "13894078.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "starting_info": { - "previous_period": "11", - "stake": "11237622542.152609809269746886", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "starting_info": { - "previous_period": "12", - "stake": "30520247.002489505486145750", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1sr6u63sxsprpzv7tedc7e88tn6elrxkjnucszy", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "starting_info": { - "previous_period": "10", - "stake": "31893143160.999999999999999999", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "starting_info": { - "previous_period": "3", - "stake": "6995636695.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "starting_info": { - "previous_period": "9", - "stake": "116762054.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "starting_info": { - "previous_period": "10", - "stake": "16324341322.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "starting_info": { - "previous_period": "11", - "stake": "2119723899.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos10qj9cj3dxecyu826gaw72ylwum96jkkh9p462q", - "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "starting_info": { - "previous_period": "2", - "stake": "7039255436.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", - "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "starting_info": { - "previous_period": "4", - "stake": "15044102286.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2", - "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", - "starting_info": { - "previous_period": "1", - "stake": "1606367134.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", - "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", - "starting_info": { - "previous_period": "3", - "stake": "229341851.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", - "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", - "starting_info": { - "previous_period": "2", - "stake": "5555958746.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "starting_info": { - "previous_period": "3", - "stake": "681974899.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos10gu52rf3d0z0py8d0x37r058qh9fgdgg5567wd", - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "starting_info": { - "previous_period": "5", - "stake": "466233357.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "starting_info": { - "previous_period": "2", - "stake": "545803690.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "starting_info": { - "previous_period": "3", - "stake": "152484301.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "starting_info": { - "previous_period": "5", - "stake": "2246266.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "starting_info": { - "previous_period": "9", - "stake": "2105667711.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "starting_info": { - "previous_period": "8", - "stake": "13307344592.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "starting_info": { - "previous_period": "6", - "stake": "10376224736.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "starting_info": { - "previous_period": "6", - "stake": "19236564.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "starting_info": { - "previous_period": "5", - "stake": "138442642.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos10d3vd6yx9k9ns6v82r4krm3d4ragw04cysm62c", - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "starting_info": { - "previous_period": "3", - "stake": "1365098704.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", - "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", - "starting_info": { - "previous_period": "2", - "stake": "48593531.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", - "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", - "starting_info": { - "previous_period": "4", - "stake": "955350854.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "starting_info": { - "previous_period": "3", - "stake": "2514756351.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "starting_info": { - "previous_period": "4", - "stake": "3468306722.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "starting_info": { - "previous_period": "1", - "stake": "3717256219.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", - "starting_info": { - "previous_period": "3", - "stake": "27773889.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", - "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "starting_info": { - "previous_period": "3", - "stake": "1609536341.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", - "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "starting_info": { - "previous_period": "2", - "stake": "23719777.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos124wz6pnykadgf3xchp6rdn9s2t9z5sgvl7597p", - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "starting_info": { - "previous_period": "4", - "stake": "6557300877.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "starting_info": { - "previous_period": "5", - "stake": "3300457502.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos10cl6sallgwf882apcyagjqa2lx4j8592cjw0gf", - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "starting_info": { - "previous_period": "2", - "stake": "1573970763.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "starting_info": { - "previous_period": "2", - "stake": "694971203.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "starting_info": { - "previous_period": "6", - "stake": "24356273620.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "starting_info": { - "previous_period": "5", - "stake": "276574162.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "starting_info": { - "previous_period": "3", - "stake": "18558143415.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "starting_info": { - "previous_period": "6", - "stake": "14241294624.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "starting_info": { - "previous_period": "7", - "stake": "1160822532.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "starting_info": { - "previous_period": "4", - "stake": "21882314874.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "starting_info": { - "previous_period": "5", - "stake": "9107793740.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "starting_info": { - "previous_period": "2", - "stake": "3452658290.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "starting_info": { - "previous_period": "6", - "stake": "952138064.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", - "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "starting_info": { - "previous_period": "4", - "stake": "6732042.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429", - "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "starting_info": { - "previous_period": "2", - "stake": "17931279589.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", - "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "starting_info": { - "previous_period": "5", - "stake": "1302147397.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp", - "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", - "starting_info": { - "previous_period": "1", - "stake": "1392995609.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", - "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "starting_info": { - "previous_period": "4", - "stake": "892316992.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1s34kukvsrdgap0pjh0alnql7vvv9m83m2628wd", - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "starting_info": { - "previous_period": "1", - "stake": "3141510059.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "starting_info": { - "previous_period": "4", - "stake": "189243223.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "starting_info": { - "previous_period": "2", - "stake": "3120662598.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "starting_info": { - "previous_period": "5", - "stake": "610981525.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "starting_info": { - "previous_period": "4", - "stake": "3355273089.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", - "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "starting_info": { - "previous_period": "2", - "stake": "5059370848.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1sjhhg2yl2cqszte7pjyrp6lx5tg383lrpjyq0m", - "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", - "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "starting_info": { - "previous_period": "3", - "stake": "8251101726.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "starting_info": { - "previous_period": "2", - "stake": "1517022388.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", - "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "starting_info": { - "previous_period": "3", - "stake": "1963736286.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj", - "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", - "starting_info": { - "previous_period": "1", - "stake": "6944508564.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "starting_info": { - "previous_period": "5", - "stake": "17756476456.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "starting_info": { - "previous_period": "6", - "stake": "1117197748.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "starting_info": { - "previous_period": "3", - "stake": "13458847467.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "starting_info": { - "previous_period": "4", - "stake": "5113128716.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "starting_info": { - "previous_period": "7", - "stake": "21648809872.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "starting_info": { - "previous_period": "6", - "stake": "40546790.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "starting_info": { - "previous_period": "5", - "stake": "226539767.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "starting_info": { - "previous_period": "4", - "stake": "2413926110.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "starting_info": { - "previous_period": "4", - "stake": "735588360.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "starting_info": { - "previous_period": "7", - "stake": "419006947.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "starting_info": { - "previous_period": "6", - "stake": "109318647.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "starting_info": { - "previous_period": "2", - "stake": "114707626.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "starting_info": { - "previous_period": "4", - "stake": "2534638254.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos13yzpngckxvtky2k25j60qxlkekx0jfau4pjhzn", - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", - "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "starting_info": { - "previous_period": "4", - "stake": "30094589894.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos13y2zjpgaj07umx7a3dsg9ffhpkk22g73492l53", - "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "starting_info": { - "previous_period": "3", - "stake": "3677892381.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", - "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", - "starting_info": { - "previous_period": "3", - "stake": "1975544514.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", - "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", - "starting_info": { - "previous_period": "2", - "stake": "1089374285.000000000000000000", - "creation_height": "9" - } - }, - { - "delegator_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", - "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "starting_info": { - "previous_period": "2", - "stake": "9334974491.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "starting_info": { - "previous_period": "3", - "stake": "15252711477.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "starting_info": { - "previous_period": "5", - "stake": "7622442762.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "starting_info": { - "previous_period": "3", - "stake": "8429625072.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "starting_info": { - "previous_period": "4", - "stake": "17690207109.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "starting_info": { - "previous_period": "6", - "stake": "3420827405.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", - "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "starting_info": { - "previous_period": "3", - "stake": "3084993241.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", - "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "starting_info": { - "previous_period": "5", - "stake": "22863613869.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "starting_info": { - "previous_period": "8", - "stake": "4124499225.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "starting_info": { - "previous_period": "5", - "stake": "3680624756.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "starting_info": { - "previous_period": "4", - "stake": "10621822118.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "starting_info": { - "previous_period": "2", - "stake": "12794497617.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "starting_info": { - "previous_period": "4", - "stake": "3123465186.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "starting_info": { - "previous_period": "5", - "stake": "856982353.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "starting_info": { - "previous_period": "5", - "stake": "2071677267.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", - "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "starting_info": { - "previous_period": "4", - "stake": "9842289918.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "starting_info": { - "previous_period": "2", - "stake": "2061374262.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", - "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "starting_info": { - "previous_period": "5", - "stake": "2914482410.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "starting_info": { - "previous_period": "3", - "stake": "16529399133.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "starting_info": { - "previous_period": "2", - "stake": "12748204456.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "starting_info": { - "previous_period": "4", - "stake": "2878563531.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "starting_info": { - "previous_period": "1", - "stake": "16792228457.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "starting_info": { - "previous_period": "5", - "stake": "15964121.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "starting_info": { - "previous_period": "6", - "stake": "3169550.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "starting_info": { - "previous_period": "6", - "stake": "638979230.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1w69f6s0dqsqfqq93hczddadwgeq86zr9dfmddq", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "starting_info": { - "previous_period": "3", - "stake": "751916830.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "starting_info": { - "previous_period": "2", - "stake": "14446066.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "starting_info": { - "previous_period": "5", - "stake": "8539175078.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos13nemj0k45u4pflkfeyey88n8u8sv4wgz8cf253", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "starting_info": { - "previous_period": "4", - "stake": "9595922807.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", - "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "starting_info": { - "previous_period": "6", - "stake": "7012397.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "starting_info": { - "previous_period": "5", - "stake": "19594820.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "starting_info": { - "previous_period": "2", - "stake": "11687279303.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "starting_info": { - "previous_period": "3", - "stake": "7174712260.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos13cydnwjmscxtqtjywk9atr9uwlm6703mwtycnr", - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "starting_info": { - "previous_period": "1", - "stake": "14396315468.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "starting_info": { - "previous_period": "5", - "stake": "730434945.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "starting_info": { - "previous_period": "2", - "stake": "14322672203.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "starting_info": { - "previous_period": "3", - "stake": "1420797965.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "starting_info": { - "previous_period": "3", - "stake": "1056544107.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "starting_info": { - "previous_period": "2", - "stake": "22343112357.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "starting_info": { - "previous_period": "6", - "stake": "9519082012.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "starting_info": { - "previous_period": "5", - "stake": "3855652978.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1pca5ng2s37clfh72ea806j9fwvpng4fjq3ey5s", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "starting_info": { - "previous_period": "3", - "stake": "15497814344.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "starting_info": { - "previous_period": "5", - "stake": "190512146.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "starting_info": { - "previous_period": "1", - "stake": "345074496.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "starting_info": { - "previous_period": "4", - "stake": "18480450616.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "starting_info": { - "previous_period": "6", - "stake": "1523447464.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", - "starting_info": { - "previous_period": "3", - "stake": "12315828943.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", - "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", - "starting_info": { - "previous_period": "4", - "stake": "3222725.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "starting_info": { - "previous_period": "8", - "stake": "1580119322.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "starting_info": { - "previous_period": "7", - "stake": "117761745.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "starting_info": { - "previous_period": "3", - "stake": "6237005399.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "starting_info": { - "previous_period": "2", - "stake": "7709220756.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1jsd99e3zfrxrr3nh057u0tvmu0847zkr29f28v", - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "starting_info": { - "previous_period": "3", - "stake": "428070399.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1wwp7j40k9xffj757s4uurkcegskfwq25ef268l", - "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "starting_info": { - "previous_period": "2", - "stake": "584304640.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr", - "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "starting_info": { - "previous_period": "1", - "stake": "4524948359.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0ajhqc7", - "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "starting_info": { - "previous_period": "2", - "stake": "22529203230.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", - "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "starting_info": { - "previous_period": "3", - "stake": "5038451854.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", - "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "starting_info": { - "previous_period": "2", - "stake": "1443592024.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa", - "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "starting_info": { - "previous_period": "3", - "stake": "4681170917.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "starting_info": { - "previous_period": "4", - "stake": "2172957336.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "starting_info": { - "previous_period": "2", - "stake": "3427543323.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxx7jqef", - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "starting_info": { - "previous_period": "1", - "stake": "2320422648.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "starting_info": { - "previous_period": "3", - "stake": "543089195.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", - "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck", - "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "starting_info": { - "previous_period": "2", - "stake": "2602618529.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", - "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", - "starting_info": { - "previous_period": "1", - "stake": "1864943427.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", - "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "starting_info": { - "previous_period": "2", - "stake": "25069342080.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "starting_info": { - "previous_period": "6", - "stake": "3502640543.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1wdm9ge7hjzrlh2epwtwu3nsunfd2r7alqhc7r2", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "starting_info": { - "previous_period": "4", - "stake": "24303271333.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1nrugh7am9s584k6qlf5nxlpetarxs2csglt46w", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "starting_info": { - "previous_period": "3", - "stake": "4938829215.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "starting_info": { - "previous_period": "2", - "stake": "13576729605.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1a5fndlfnwtvyzzt7ql4kvuqgnjut7ua7hkfts6", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "starting_info": { - "previous_period": "5", - "stake": "9415626255.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", - "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "starting_info": { - "previous_period": "2", - "stake": "33054734644.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1r6j2xkpnnjve9c00c854laqp7l7zv8pxeksxrz", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "starting_info": { - "previous_period": "4", - "stake": "20554160964.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "starting_info": { - "previous_period": "5", - "stake": "24771629701.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "starting_info": { - "previous_period": "6", - "stake": "324745845.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1n9dqelmmf5kfysk24m6chqfdcgz6r75u7mpuwh", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "starting_info": { - "previous_period": "3", - "stake": "7881585438.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", - "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "starting_info": { - "previous_period": "2", - "stake": "3033965094.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", - "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "starting_info": { - "previous_period": "3", - "stake": "15056247725.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1zsspke0nqudcl0lh747ppqcsy396245akc2vtl", - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "starting_info": { - "previous_period": "7", - "stake": "28973013721.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "starting_info": { - "previous_period": "6", - "stake": "2427273583.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "starting_info": { - "previous_period": "8", - "stake": "2567851891.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "starting_info": { - "previous_period": "5", - "stake": "401941426.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", - "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "starting_info": { - "previous_period": "4", - "stake": "19455408606.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "starting_info": { - "previous_period": "6", - "stake": "12287749425.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "starting_info": { - "previous_period": "10", - "stake": "9559582899.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "starting_info": { - "previous_period": "7", - "stake": "302642185.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "starting_info": { - "previous_period": "9", - "stake": "1576940428.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "starting_info": { - "previous_period": "3", - "stake": "1338628253.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1vwja3gc3e37f8fkddj38gp74cs7sccnf4zs509", - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "starting_info": { - "previous_period": "4", - "stake": "2070243017.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1ng5m6spxngyne4qzce35fdg0whl0yqgv9lg9tt", - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "starting_info": { - "previous_period": "1", - "stake": "13107417049.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "starting_info": { - "previous_period": "6", - "stake": "680611809.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "starting_info": { - "previous_period": "3", - "stake": "3507629422.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "starting_info": { - "previous_period": "2", - "stake": "25069342080.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "starting_info": { - "previous_period": "5", - "stake": "13388065636.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "starting_info": { - "previous_period": "7", - "stake": "2364587435.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "starting_info": { - "previous_period": "5", - "stake": "1439734010.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1d0dq8hxzyywrcx73v4z44e8p8685znzml58dg2", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "starting_info": { - "previous_period": "6", - "stake": "23089372229.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "starting_info": { - "previous_period": "2", - "stake": "1981740603.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "starting_info": { - "previous_period": "7", - "stake": "158733361.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "starting_info": { - "previous_period": "3", - "stake": "441014433.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "starting_info": { - "previous_period": "4", - "stake": "2588611065.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "starting_info": { - "previous_period": "5", - "stake": "254829181.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "starting_info": { - "previous_period": "4", - "stake": "19691201.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "starting_info": { - "previous_period": "3", - "stake": "1340954232.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "starting_info": { - "previous_period": "8", - "stake": "2311637.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "starting_info": { - "previous_period": "10", - "stake": "52419.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "starting_info": { - "previous_period": "3", - "stake": "43687807.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "starting_info": { - "previous_period": "4", - "stake": "213312801.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1n3lnhxzzm7ntheu78h6v4zag7zmrlp48tjnhf3", - "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "starting_info": { - "previous_period": "2", - "stake": "9794461587.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", - "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "starting_info": { - "previous_period": "3", - "stake": "449732008.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", - "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "starting_info": { - "previous_period": "6", - "stake": "10162772165.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "starting_info": { - "previous_period": "5", - "stake": "12613411.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "starting_info": { - "previous_period": "4", - "stake": "3145157664.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "starting_info": { - "previous_period": "5", - "stake": "2905348435.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "starting_info": { - "previous_period": "2", - "stake": "12269775869.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "starting_info": { - "previous_period": "6", - "stake": "5136199330.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "starting_info": { - "previous_period": "3", - "stake": "19279146842.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "starting_info": { - "previous_period": "7", - "stake": "24652299.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "starting_info": { - "previous_period": "8", - "stake": "43994659.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "starting_info": { - "previous_period": "10", - "stake": "18869340.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", - "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", - "starting_info": { - "previous_period": "4", - "stake": "14531672001.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "starting_info": { - "previous_period": "4", - "stake": "3922123176.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "starting_info": { - "previous_period": "1", - "stake": "17245824357.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "starting_info": { - "previous_period": "3", - "stake": "126388593.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos14hr55k3es7xfc54gwgu3plde0vaxkgerljee6v", - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "starting_info": { - "previous_period": "2", - "stake": "20670117972.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", - "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", - "starting_info": { - "previous_period": "2", - "stake": "981657888.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", - "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", - "starting_info": { - "previous_period": "3", - "stake": "15174649749.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", - "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "starting_info": { - "previous_period": "3", - "stake": "52804172.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "starting_info": { - "previous_period": "4", - "stake": "60608473.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos15pl2c2umxszwar75aft99kns0ltmpepnnpt9y0", - "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", - "starting_info": { - "previous_period": "2", - "stake": "11726853019.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", - "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "starting_info": { - "previous_period": "3", - "stake": "3607007415.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos15zqzxj663h8g8naxyz324j2rpd3rnw4rvtxep2", - "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "starting_info": { - "previous_period": "2", - "stake": "25069342080.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "starting_info": { - "previous_period": "8", - "stake": "3139002667.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "starting_info": { - "previous_period": "5", - "stake": "2095412424.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "starting_info": { - "previous_period": "10", - "stake": "5904983738.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "starting_info": { - "previous_period": "3", - "stake": "2615326319.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", - "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", - "starting_info": { - "previous_period": "1", - "stake": "11868660651.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "starting_info": { - "previous_period": "5", - "stake": "12945220697.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "starting_info": { - "previous_period": "7", - "stake": "548629134.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "starting_info": { - "previous_period": "6", - "stake": "700270403.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "starting_info": { - "previous_period": "6", - "stake": "11335873807.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "starting_info": { - "previous_period": "5", - "stake": "10343736976.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "starting_info": { - "previous_period": "4", - "stake": "12895342060.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos15tv54z32xgqechywvr7ymsfdvr2mmx3553j8rd", - "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", - "starting_info": { - "previous_period": "1", - "stake": "10646429954.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", - "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "starting_info": { - "previous_period": "4", - "stake": "4258157.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos15vf60ssrdq6fh9ln5a9wtd6f3q64sktl6vk2ss", - "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "starting_info": { - "previous_period": "3", - "stake": "502656802.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "starting_info": { - "previous_period": "4", - "stake": "927934611.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "starting_info": { - "previous_period": "3", - "stake": "2830795600.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "starting_info": { - "previous_period": "1", - "stake": "974110958.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "starting_info": { - "previous_period": "6", - "stake": "2095470160.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "starting_info": { - "previous_period": "3", - "stake": "842733222.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "starting_info": { - "previous_period": "4", - "stake": "14053872866.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "starting_info": { - "previous_period": "4", - "stake": "240453816.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1wvzq2f252674u3gvmqhnq8g4n6lmxedmzs0czm", - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "starting_info": { - "previous_period": "3", - "stake": "2584616241.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "starting_info": { - "previous_period": "2", - "stake": "2930417970.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", - "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "starting_info": { - "previous_period": "2", - "stake": "5685279942.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", - "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "starting_info": { - "previous_period": "6", - "stake": "1049818729.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", - "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "starting_info": { - "previous_period": "5", - "stake": "1062187041.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1rlltvm5ks32kh683c0w7epsjvg8aq2hvct27p6", - "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "starting_info": { - "previous_period": "5", - "stake": "71917474.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", - "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "starting_info": { - "previous_period": "4", - "stake": "568146686.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", - "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "starting_info": { - "previous_period": "2", - "stake": "10013094355.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", - "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "starting_info": { - "previous_period": "3", - "stake": "16248624224.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "starting_info": { - "previous_period": "2", - "stake": "24554814193.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "starting_info": { - "previous_period": "5", - "stake": "19978115021.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "starting_info": { - "previous_period": "3", - "stake": "986773968.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "starting_info": { - "previous_period": "4", - "stake": "607901853.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "starting_info": { - "previous_period": "5", - "stake": "1561395724.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "starting_info": { - "previous_period": "3", - "stake": "16358237418.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "starting_info": { - "previous_period": "7", - "stake": "1677820405.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "starting_info": { - "previous_period": "6", - "stake": "2652495105.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "starting_info": { - "previous_period": "2", - "stake": "35850249.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos15cfduq92j3uvam8u942xj4egs42tjzl6p33fu5", - "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "starting_info": { - "previous_period": "1", - "stake": "14156647.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "starting_info": { - "previous_period": "11", - "stake": "12679288910.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1d9m3l8khcrx0zhftehkuw67zzszf9v9le5dvrm", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "starting_info": { - "previous_period": "9", - "stake": "20382465534.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "starting_info": { - "previous_period": "10", - "stake": "731129230.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "starting_info": { - "previous_period": "6", - "stake": "2205728211.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "starting_info": { - "previous_period": "8", - "stake": "3421255938.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "starting_info": { - "previous_period": "7", - "stake": "140255592.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos15uqsf4wke3ylyp0elnka2rvaefhsmhgjhe5mxf", - "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", - "starting_info": { - "previous_period": "1", - "stake": "8741308900.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "starting_info": { - "previous_period": "6", - "stake": "241691384.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "starting_info": { - "previous_period": "4", - "stake": "14533440365.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "starting_info": { - "previous_period": "3", - "stake": "24026548.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", - "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "starting_info": { - "previous_period": "2", - "stake": "16363250391.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "starting_info": { - "previous_period": "3", - "stake": "57475597.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "starting_info": { - "previous_period": "7", - "stake": "1886627332.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "starting_info": { - "previous_period": "8", - "stake": "5720739029.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "starting_info": { - "previous_period": "9", - "stake": "3371357709.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "starting_info": { - "previous_period": "4", - "stake": "7165994372.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "starting_info": { - "previous_period": "5", - "stake": "7918208867.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "starting_info": { - "previous_period": "3", - "stake": "9192729008.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "starting_info": { - "previous_period": "5", - "stake": "2272430680.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "starting_info": { - "previous_period": "4", - "stake": "7778508961.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "starting_info": { - "previous_period": "2", - "stake": "95191076.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos14q9rupnazu0mmkjd9skpn2zdfs8d0hlghzpk0v", - "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", - "starting_info": { - "previous_period": "5", - "stake": "492237770.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "starting_info": { - "previous_period": "2", - "stake": "16977263624.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", - "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "starting_info": { - "previous_period": "3", - "stake": "8106199.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", - "starting_info": { - "previous_period": "6", - "stake": "125301.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", - "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "starting_info": { - "previous_period": "1", - "stake": "18994769458.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1haw8fcay84fjlsdl5cyev275ldj30z3r27m0g5", - "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "starting_info": { - "previous_period": "2", - "stake": "6372741624.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "starting_info": { - "previous_period": "4", - "stake": "21529013972.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "starting_info": { - "previous_period": "3", - "stake": "7193234568.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos14j4mehgc448s2m7cr0uqm3pmvjxav94wmq80w4", - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "starting_info": { - "previous_period": "5", - "stake": "1110360222.000000000000000000", - "creation_height": "9" - } - }, - { - "delegator_address": "cosmos1yrdtzqfkyum94q4v3j3xllrtf09qv0jvympw86", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "starting_info": { - "previous_period": "6", - "stake": "3161698569.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "starting_info": { - "previous_period": "7", - "stake": "269676102.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "starting_info": { - "previous_period": "4", - "stake": "1854783297.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "starting_info": { - "previous_period": "5", - "stake": "1682096242.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "starting_info": { - "previous_period": "8", - "stake": "6656587767.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "starting_info": { - "previous_period": "4", - "stake": "13034888858.653846147589407194", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "starting_info": { - "previous_period": "7", - "stake": "52986923.031037243011576594", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "starting_info": { - "previous_period": "3", - "stake": "2286530039.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", - "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", - "starting_info": { - "previous_period": "2", - "stake": "3041120922.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "starting_info": { - "previous_period": "2", - "stake": "23007967818.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "starting_info": { - "previous_period": "4", - "stake": "2921862659.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "starting_info": { - "previous_period": "3", - "stake": "5446202786.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "starting_info": { - "previous_period": "5", - "stake": "1681443586.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "starting_info": { - "previous_period": "2", - "stake": "5993132567.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "starting_info": { - "previous_period": "5", - "stake": "7303977754.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "starting_info": { - "previous_period": "4", - "stake": "821774041.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos14urapj7e6tj2s8clcsgyat6xmkppj7nm4qtewf", - "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", - "starting_info": { - "previous_period": "2", - "stake": "5480500900.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "starting_info": { - "previous_period": "3", - "stake": "9687342330.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz", - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "starting_info": { - "previous_period": "2", - "stake": "16734096385.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "starting_info": { - "previous_period": "4", - "stake": "843834482.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos147pq4rzswl76kdeyx8sc7pagf4nhjpnq2hlrh3", - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "starting_info": { - "previous_period": "1", - "stake": "22417960991.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "starting_info": { - "previous_period": "3", - "stake": "8142048495.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1478sx3zdfylsts5sus5rlz4dgvyvacqpuchj6f", - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "starting_info": { - "previous_period": "4", - "stake": "1078037731.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "starting_info": { - "previous_period": "4", - "stake": "3439625151.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", - "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "starting_info": { - "previous_period": "2", - "stake": "10941491018.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "starting_info": { - "previous_period": "6", - "stake": "26325596.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "starting_info": { - "previous_period": "8", - "stake": "11344768409.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "starting_info": { - "previous_period": "7", - "stake": "5083047390.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1kz20p7j939s8cqadmqqws80c6z93qdtyg8xt0v", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "starting_info": { - "previous_period": "4", - "stake": "9782915598.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos17ph7nmvmxdhm687z4k5phsyd08wvsnv44emkj8", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "starting_info": { - "previous_period": "9", - "stake": "3648941591.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1kxl7gsad663he7lgn66wx6gr3egnfj85dt22pv", - "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", - "starting_info": { - "previous_period": "1", - "stake": "2533410912.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1kfnt5d5fcma9kh4c5jk85yu75jer72kwdltg4s", - "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "starting_info": { - "previous_period": "1", - "stake": "21181468286.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", - "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "starting_info": { - "previous_period": "7", - "stake": "607985470.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", - "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "starting_info": { - "previous_period": "6", - "stake": "13186298825.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "starting_info": { - "previous_period": "8", - "stake": "5071553218.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "starting_info": { - "previous_period": "4", - "stake": "16667182589.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "starting_info": { - "previous_period": "7", - "stake": "17602930321.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "starting_info": { - "previous_period": "3", - "stake": "89280204.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "starting_info": { - "previous_period": "4", - "stake": "3814662227.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "starting_info": { - "previous_period": "3", - "stake": "3444033677.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2", - "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "starting_info": { - "previous_period": "1", - "stake": "9571086511.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", - "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "starting_info": { - "previous_period": "2", - "stake": "69406130.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", - "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "starting_info": { - "previous_period": "6", - "stake": "9033381920.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", - "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "starting_info": { - "previous_period": "5", - "stake": "6780481465.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", - "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "starting_info": { - "previous_period": "4", - "stake": "22548164258.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "starting_info": { - "previous_period": "3", - "stake": "3409616214.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", - "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "starting_info": { - "previous_period": "2", - "stake": "166860.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "starting_info": { - "previous_period": "3", - "stake": "64540087.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1kjupa2w6rlhzj9fjxz35m02g2wpz790fd6mf0j", - "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "starting_info": { - "previous_period": "4", - "stake": "11188036452.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "starting_info": { - "previous_period": "3", - "stake": "986856358.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", - "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "starting_info": { - "previous_period": "5", - "stake": "4660200511.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", - "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "starting_info": { - "previous_period": "2", - "stake": "6269426755.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1kmly2aspt8rk9h4ukdt8h52k24alvc34qukp2n", - "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "starting_info": { - "previous_period": "1", - "stake": "9031700237.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "starting_info": { - "previous_period": "2", - "stake": "20581321.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", - "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "starting_info": { - "previous_period": "2", - "stake": "157509894.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", - "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "starting_info": { - "previous_period": "1", - "stake": "199824149.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "starting_info": { - "previous_period": "7", - "stake": "9843285414.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "starting_info": { - "previous_period": "5", - "stake": "995636217.000000000000000000", - "creation_height": "9" - } - }, - { - "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "starting_info": { - "previous_period": "6", - "stake": "5575140.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "starting_info": { - "previous_period": "3", - "stake": "15608731707.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "starting_info": { - "previous_period": "2", - "stake": "18830990390.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "starting_info": { - "previous_period": "6", - "stake": "20636678155.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "starting_info": { - "previous_period": "7", - "stake": "3535960309.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos130kk7kw4kx7rfrq9sa4k673zqt3nf6s4l3a0lg", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "starting_info": { - "previous_period": "4", - "stake": "5241869268.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "starting_info": { - "previous_period": "3", - "stake": "14982594771.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "starting_info": { - "previous_period": "5", - "stake": "108025410.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1gwwltgyatg8yfe54447dxnyvs2nt6xxsl6lv2m", - "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "starting_info": { - "previous_period": "2", - "stake": "21998779909.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", - "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "starting_info": { - "previous_period": "1", - "stake": "457781724.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "starting_info": { - "previous_period": "3", - "stake": "4659214363.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "starting_info": { - "previous_period": "9", - "stake": "3878595385.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "starting_info": { - "previous_period": "6", - "stake": "2235582679.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "starting_info": { - "previous_period": "5", - "stake": "361851785.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "starting_info": { - "previous_period": "8", - "stake": "466196437.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "starting_info": { - "previous_period": "6", - "stake": "150189421.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "starting_info": { - "previous_period": "5", - "stake": "3484578053.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "starting_info": { - "previous_period": "9", - "stake": "5669282913.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "starting_info": { - "previous_period": "8", - "stake": "2095189904.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", - "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "starting_info": { - "previous_period": "2", - "stake": "2600875484.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe", - "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "starting_info": { - "previous_period": "1", - "stake": "4203532933.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1hxdqddf3u8vjm080ytpe959uktn4axdas3uqhl", - "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "starting_info": { - "previous_period": "1", - "stake": "13179632835.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", - "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "starting_info": { - "previous_period": "2", - "stake": "663734465.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", - "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", - "starting_info": { - "previous_period": "4", - "stake": "23136285.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "starting_info": { - "previous_period": "6", - "stake": "821954529.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "starting_info": { - "previous_period": "2", - "stake": "16404106448.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos14m0pzuhkpjnx2esurz6kcxcjvlkcdzk7e43krz", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "starting_info": { - "previous_period": "8", - "stake": "2468850551.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "starting_info": { - "previous_period": "5", - "stake": "576145955.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "starting_info": { - "previous_period": "7", - "stake": "18772263304.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "starting_info": { - "previous_period": "4", - "stake": "6767814744.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", - "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "starting_info": { - "previous_period": "4", - "stake": "22058794240.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", - "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "starting_info": { - "previous_period": "5", - "stake": "2551565111.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "starting_info": { - "previous_period": "4", - "stake": "2744054731.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc", - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "starting_info": { - "previous_period": "3", - "stake": "2335097089.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "starting_info": { - "previous_period": "2", - "stake": "1408273393.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "starting_info": { - "previous_period": "4", - "stake": "510250360.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", - "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "starting_info": { - "previous_period": "3", - "stake": "1912310410.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", - "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", - "starting_info": { - "previous_period": "1", - "stake": "2108075856.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", - "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "starting_info": { - "previous_period": "5", - "stake": "4681593063.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "starting_info": { - "previous_period": "6", - "stake": "1987459876.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "starting_info": { - "previous_period": "4", - "stake": "6269261784.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq", - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "starting_info": { - "previous_period": "6", - "stake": "25069342080.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1mcc0dq93nrt3u6hl6ju82hyw3rdfun029jx4v2", - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "starting_info": { - "previous_period": "5", - "stake": "3120721396.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", - "starting_info": { - "previous_period": "4", - "stake": "927350399.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "starting_info": { - "previous_period": "6", - "stake": "1933530153.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "starting_info": { - "previous_period": "4", - "stake": "6858058479.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1h6j4lyvuenmz9m7vq3hler8j7pg5ldpet0xf9a", - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "starting_info": { - "previous_period": "2", - "stake": "25069342080.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "starting_info": { - "previous_period": "5", - "stake": "22087360379.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", - "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", - "starting_info": { - "previous_period": "1", - "stake": "4006205.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", - "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "starting_info": { - "previous_period": "2", - "stake": "15675831119.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "starting_info": { - "previous_period": "5", - "stake": "503691456.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "starting_info": { - "previous_period": "4", - "stake": "3295555517.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1jzhlspgxp578kzg9dtvg8tm2w9k7tnmcpstzry", - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "starting_info": { - "previous_period": "7", - "stake": "6425955236.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "starting_info": { - "previous_period": "6", - "stake": "2665221917.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj", - "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "starting_info": { - "previous_period": "3", - "stake": "4050355196.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "starting_info": { - "previous_period": "4", - "stake": "3002111009.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptd8zyma", - "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", - "starting_info": { - "previous_period": "1", - "stake": "8559089572.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "starting_info": { - "previous_period": "6", - "stake": "41624341.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "starting_info": { - "previous_period": "7", - "stake": "14654910305.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "starting_info": { - "previous_period": "5", - "stake": "20731656728.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "starting_info": { - "previous_period": "9", - "stake": "8305994215.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "starting_info": { - "previous_period": "8", - "stake": "1753289412.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "starting_info": { - "previous_period": "2", - "stake": "6709581679.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "starting_info": { - "previous_period": "5", - "stake": "2739638648.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "starting_info": { - "previous_period": "3", - "stake": "14812554077.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "starting_info": { - "previous_period": "3", - "stake": "16356624866.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "starting_info": { - "previous_period": "2", - "stake": "1616674805.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "starting_info": { - "previous_period": "4", - "stake": "13796856153.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "starting_info": { - "previous_period": "3", - "stake": "689756170.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "starting_info": { - "previous_period": "4", - "stake": "324333952.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "starting_info": { - "previous_period": "2", - "stake": "5261551412.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "starting_info": { - "previous_period": "2", - "stake": "2150744506.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", - "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "starting_info": { - "previous_period": "1", - "stake": "7924071421.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "starting_info": { - "previous_period": "4", - "stake": "900956465.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "starting_info": { - "previous_period": "1", - "stake": "36701249402.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq", - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "starting_info": { - "previous_period": "4", - "stake": "592539582.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "starting_info": { - "previous_period": "7", - "stake": "1112547.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "starting_info": { - "previous_period": "2", - "stake": "421593670.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "starting_info": { - "previous_period": "1", - "stake": "4250535918.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "starting_info": { - "previous_period": "3", - "stake": "2295367808.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", - "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", - "starting_info": { - "previous_period": "2", - "stake": "211016457.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6x000jc", - "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", - "starting_info": { - "previous_period": "1", - "stake": "1201306698.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "starting_info": { - "previous_period": "2", - "stake": "2196379282.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "starting_info": { - "previous_period": "3", - "stake": "721476141.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "starting_info": { - "previous_period": "1", - "stake": "249261878.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "starting_info": { - "previous_period": "7", - "stake": "2727283744.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "starting_info": { - "previous_period": "8", - "stake": "11015469214.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "starting_info": { - "previous_period": "2", - "stake": "23543464834.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "starting_info": { - "previous_period": "4", - "stake": "390088156.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "starting_info": { - "previous_period": "8", - "stake": "5780519.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "starting_info": { - "previous_period": "4", - "stake": "144959703.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "starting_info": { - "previous_period": "5", - "stake": "16883391832.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "starting_info": { - "previous_period": "9", - "stake": "9703623543.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "starting_info": { - "previous_period": "3", - "stake": "1320373881.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", - "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "starting_info": { - "previous_period": "4", - "stake": "2115827243.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", - "starting_info": { - "previous_period": "3", - "stake": "199636304.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1evqmj6ahqf76keas4ymhvf4r992kg7wrar0fru", - "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "starting_info": { - "previous_period": "3", - "stake": "3652777037.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos17tecr2sngjcm2rc29dzmadtpad2tkmrhj69whr", - "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "starting_info": { - "previous_period": "2", - "stake": "16752793632.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", - "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "starting_info": { - "previous_period": "4", - "stake": "6536333612.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", - "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "starting_info": { - "previous_period": "3", - "stake": "1119920089.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266", - "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", - "starting_info": { - "previous_period": "4", - "stake": "5987604552.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6", - "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", - "starting_info": { - "previous_period": "3", - "stake": "11089478639.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "starting_info": { - "previous_period": "8", - "stake": "6852395930.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "starting_info": { - "previous_period": "9", - "stake": "2649436634.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "starting_info": { - "previous_period": "6", - "stake": "372091968.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", - "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", - "starting_info": { - "previous_period": "1", - "stake": "247885300.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "starting_info": { - "previous_period": "3", - "stake": "32698264.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", - "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "starting_info": { - "previous_period": "4", - "stake": "25069342080.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", - "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "starting_info": { - "previous_period": "2", - "stake": "4365594275.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", - "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "starting_info": { - "previous_period": "1", - "stake": "13243911263.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", - "starting_info": { - "previous_period": "3", - "stake": "7847492642.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "starting_info": { - "previous_period": "2", - "stake": "178156456.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1em3y3h4g7n8ue3wjcramnpmz0x8rwakrpjmrgz", - "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "starting_info": { - "previous_period": "1", - "stake": "12071046098.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", - "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "starting_info": { - "previous_period": "5", - "stake": "6709144772.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", - "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "starting_info": { - "previous_period": "4", - "stake": "2778547888.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "starting_info": { - "previous_period": "6", - "stake": "924245075.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "starting_info": { - "previous_period": "5", - "stake": "4448687638.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "starting_info": { - "previous_period": "4", - "stake": "10677551922.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", - "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "starting_info": { - "previous_period": "2", - "stake": "19565632897.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "starting_info": { - "previous_period": "9", - "stake": "1958289106.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "starting_info": { - "previous_period": "5", - "stake": "2037145657.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "starting_info": { - "previous_period": "7", - "stake": "5402886314.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "starting_info": { - "previous_period": "6", - "stake": "17415142521.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "starting_info": { - "previous_period": "5", - "stake": "8106078214.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "starting_info": { - "previous_period": "4", - "stake": "19127653549.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "starting_info": { - "previous_period": "2", - "stake": "5174807457.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "starting_info": { - "previous_period": "7", - "stake": "863704883.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "starting_info": { - "previous_period": "5", - "stake": "3069213832.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "starting_info": { - "previous_period": "6", - "stake": "32603015.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", - "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "starting_info": { - "previous_period": "3", - "stake": "11830766683.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos16tr72kn90g5zl7qhyhuqkjflejz00uzlkl65sj", - "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "starting_info": { - "previous_period": "2", - "stake": "25069342080.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1vx0z58vgegsfc8e56jzmjtvj8cvprywvnm7l9j", - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "starting_info": { - "previous_period": "3", - "stake": "1076204485.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "starting_info": { - "previous_period": "2", - "stake": "4020804640.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos16v3h2mggt8tnkxp0vq5tq25fhr3knvf4jw40l5", - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "starting_info": { - "previous_period": "1", - "stake": "23883466891.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", - "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "starting_info": { - "previous_period": "4", - "stake": "8771546667.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "starting_info": { - "previous_period": "3", - "stake": "230136377.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n", - "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", - "starting_info": { - "previous_period": "1", - "stake": "13444158275.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", - "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", - "starting_info": { - "previous_period": "5", - "stake": "3562717063.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "starting_info": { - "previous_period": "5", - "stake": "13749317760.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "starting_info": { - "previous_period": "6", - "stake": "6458950379.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "starting_info": { - "previous_period": "9", - "stake": "3501192050.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "starting_info": { - "previous_period": "8", - "stake": "233651324.000000000000000000", - "creation_height": "10" - } - }, - { - "delegator_address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "starting_info": { - "previous_period": "7", - "stake": "3799625898.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", - "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "starting_info": { - "previous_period": "3", - "stake": "12266067.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1mzsvp23mjrjkspddkz6nta0x7kte6a23atg6ml", - "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "starting_info": { - "previous_period": "2", - "stake": "2228698398.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c", - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "starting_info": { - "previous_period": "5", - "stake": "1670822058.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "starting_info": { - "previous_period": "6", - "stake": "3804293134.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "starting_info": { - "previous_period": "2", - "stake": "11902636114.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", - "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", - "starting_info": { - "previous_period": "2", - "stake": "965626724.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7", - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "starting_info": { - "previous_period": "7", - "stake": "1694198126.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "starting_info": { - "previous_period": "4", - "stake": "22330517668.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "starting_info": { - "previous_period": "6", - "stake": "1407135534.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", - "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", - "starting_info": { - "previous_period": "1", - "stake": "2479274676.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", - "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", - "starting_info": { - "previous_period": "1", - "stake": "4394402323.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "starting_info": { - "previous_period": "10", - "stake": "8361945358.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "starting_info": { - "previous_period": "5", - "stake": "21819398696.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "starting_info": { - "previous_period": "7", - "stake": "614084859.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "starting_info": { - "previous_period": "9", - "stake": "590997851.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "starting_info": { - "previous_period": "6", - "stake": "12274844463.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "starting_info": { - "previous_period": "8", - "stake": "18071051811.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "starting_info": { - "previous_period": "4", - "stake": "12958021951.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", - "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "starting_info": { - "previous_period": "6", - "stake": "4593224997.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", - "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "starting_info": { - "previous_period": "5", - "stake": "1199437642.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfej3rle", - "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", - "starting_info": { - "previous_period": "1", - "stake": "1494931451.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "starting_info": { - "previous_period": "2", - "stake": "6923120900.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "starting_info": { - "previous_period": "4", - "stake": "19205968225.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "starting_info": { - "previous_period": "5", - "stake": "1744984549.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "starting_info": { - "previous_period": "6", - "stake": "251790.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "starting_info": { - "previous_period": "7", - "stake": "12788946759.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "starting_info": { - "previous_period": "4", - "stake": "22141837134.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos147lwcm3tx6uhtjphxwwmk7u32mucukalplv80z", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "starting_info": { - "previous_period": "6", - "stake": "1601474401.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "starting_info": { - "previous_period": "5", - "stake": "8455755268.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "starting_info": { - "previous_period": "3", - "stake": "330891000.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "starting_info": { - "previous_period": "8", - "stake": "22514769356.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "starting_info": { - "previous_period": "9", - "stake": "252433656.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "starting_info": { - "previous_period": "4", - "stake": "385810656.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "starting_info": { - "previous_period": "1", - "stake": "4301090429.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "starting_info": { - "previous_period": "5", - "stake": "24027809.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", - "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "starting_info": { - "previous_period": "1", - "stake": "24395123.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", - "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "starting_info": { - "previous_period": "2", - "stake": "218958522.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "starting_info": { - "previous_period": "6", - "stake": "19002817.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "starting_info": { - "previous_period": "5", - "stake": "357887239.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "starting_info": { - "previous_period": "5", - "stake": "2725727123.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "starting_info": { - "previous_period": "4", - "stake": "31595387940.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "starting_info": { - "previous_period": "6", - "stake": "938622421.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "starting_info": { - "previous_period": "3", - "stake": "482001747.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", - "starting_info": { - "previous_period": "2", - "stake": "781062755.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "starting_info": { - "previous_period": "4", - "stake": "9948638663.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "starting_info": { - "previous_period": "6", - "stake": "8844305443.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "starting_info": { - "previous_period": "5", - "stake": "844335956.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1urnp7yp6u27nut8kvsrapgmmvk8sh6u5wd5dez", - "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", - "starting_info": { - "previous_period": "1", - "stake": "13977340603.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", - "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", - "starting_info": { - "previous_period": "2", - "stake": "120397764.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", - "starting_info": { - "previous_period": "2", - "stake": "251933.000000000000000000", - "creation_height": "49" - } - }, - { - "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", - "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "starting_info": { - "previous_period": "2", - "stake": "2246425767.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1uvm96xdewfpdwymw5ywt8j5efq6jhpyl35pzg8", - "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "starting_info": { - "previous_period": "1", - "stake": "7577447491.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "starting_info": { - "previous_period": "3", - "stake": "23613691655.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "starting_info": { - "previous_period": "2", - "stake": "8173781116.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1uuk9ewj0532rzlhlg86tserdxvtnm3kq2k2zww", - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", - "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", - "starting_info": { - "previous_period": "2", - "stake": "763826873.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "starting_info": { - "previous_period": "3", - "stake": "1386448079.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "starting_info": { - "previous_period": "4", - "stake": "627370738.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "starting_info": { - "previous_period": "2", - "stake": "5887196.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "starting_info": { - "previous_period": "3", - "stake": "671837638.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "starting_info": { - "previous_period": "1", - "stake": "9361230791.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", - "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", - "starting_info": { - "previous_period": "2", - "stake": "82979650.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "starting_info": { - "previous_period": "3", - "stake": "315491807.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "starting_info": { - "previous_period": "2", - "stake": "2274933257.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "starting_info": { - "previous_period": "1", - "stake": "6631273690.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", - "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", - "starting_info": { - "previous_period": "1", - "stake": "5682430.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "starting_info": { - "previous_period": "3", - "stake": "7610845.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "starting_info": { - "previous_period": "2", - "stake": "11045854268.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1adwsqn58aype530jae9qrwknsxyf3wmwdr523z", - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "starting_info": { - "previous_period": "3", - "stake": "951735771.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "starting_info": { - "previous_period": "4", - "stake": "4858570428.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1c4lft2m4yyrzjsxyu7nzsrxuskgtlr2crzzwwd", - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "starting_info": { - "previous_period": "2", - "stake": "4541366.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "starting_info": { - "previous_period": "1", - "stake": "10992310558.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "starting_info": { - "previous_period": "5", - "stake": "548109039.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "starting_info": { - "previous_period": "7", - "stake": "670559324.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "starting_info": { - "previous_period": "4", - "stake": "22252816301.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1awyus34e6laq3zxqsrv283w6fgn8w62zkwd87d", - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "starting_info": { - "previous_period": "6", - "stake": "1878391814.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "starting_info": { - "previous_period": "3", - "stake": "1549115655.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "starting_info": { - "previous_period": "5", - "stake": "16011251757.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "starting_info": { - "previous_period": "8", - "stake": "349164048.000000000000000000", - "creation_height": "13" - } - }, - { - "delegator_address": "cosmos1a0jdqzvk078d6486vuxdr5d0yp6rglue2nh5dn", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "starting_info": { - "previous_period": "7", - "stake": "9613933711.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1r572vr0k388gpjw5h2u75ppmarvgma20rqj2ws", - "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "starting_info": { - "previous_period": "3", - "stake": "16932030948.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "starting_info": { - "previous_period": "2", - "stake": "7764993320.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8kl6qt4", - "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", - "starting_info": { - "previous_period": "1", - "stake": "15012824613.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", - "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", - "starting_info": { - "previous_period": "4", - "stake": "228354642.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "starting_info": { - "previous_period": "4", - "stake": "19101606110.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "starting_info": { - "previous_period": "5", - "stake": "943974869.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "starting_info": { - "previous_period": "3", - "stake": "21448624442.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", - "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", - "starting_info": { - "previous_period": "2", - "stake": "1820280319.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", - "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", - "starting_info": { - "previous_period": "2", - "stake": "2580293599.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "starting_info": { - "previous_period": "7", - "stake": "6251197681.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "starting_info": { - "previous_period": "5", - "stake": "1793233946.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "starting_info": { - "previous_period": "2", - "stake": "6254739411.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "starting_info": { - "previous_period": "6", - "stake": "51693014.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "starting_info": { - "previous_period": "4", - "stake": "25069342080.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos178pm30fcgrt5654czwr8nlex050m6y609glx2s", - "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "starting_info": { - "previous_period": "1", - "stake": "23703504292.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "starting_info": { - "previous_period": "2", - "stake": "18880150143.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "starting_info": { - "previous_period": "9", - "stake": "7684584877.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "starting_info": { - "previous_period": "7", - "stake": "9360757617.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "starting_info": { - "previous_period": "8", - "stake": "10690661250.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "starting_info": { - "previous_period": "10", - "stake": "827898827.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "starting_info": { - "previous_period": "5", - "stake": "18525526004.000000000000000000", - "creation_height": "3" - } - }, - { - "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "starting_info": { - "previous_period": "6", - "stake": "3755696144.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", - "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "starting_info": { - "previous_period": "4", - "stake": "14112770668.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos17gpy6jzg7xdsr2xc7kweljagx4uaysxdk2244g", - "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "starting_info": { - "previous_period": "3", - "stake": "7651697131.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnk5g0lz", - "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", - "starting_info": { - "previous_period": "1", - "stake": "227804730.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "starting_info": { - "previous_period": "7", - "stake": "151161779.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "starting_info": { - "previous_period": "5", - "stake": "9209912.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos172lmu2psqlkxkthpr46h2ewjffte7lhlmwe6tg", - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "starting_info": { - "previous_period": "1", - "stake": "25069342080.000000000000000000", - "creation_height": "0" - } - }, - { - "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", - "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", - "starting_info": { - "previous_period": "3", - "stake": "1397104980.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s", - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "starting_info": { - "previous_period": "5", - "stake": "9953913240.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "starting_info": { - "previous_period": "4", - "stake": "6161948206.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "starting_info": { - "previous_period": "6", - "stake": "117960718.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "starting_info": { - "previous_period": "7", - "stake": "513446339.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", - "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", - "starting_info": { - "previous_period": "1", - "stake": "300592036.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "starting_info": { - "previous_period": "8", - "stake": "20382455281.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "starting_info": { - "previous_period": "4", - "stake": "18580691943.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "starting_info": { - "previous_period": "9", - "stake": "7585898322.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "starting_info": { - "previous_period": "5", - "stake": "2352005810.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "starting_info": { - "previous_period": "6", - "stake": "8013043987.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "starting_info": { - "previous_period": "4", - "stake": "809035601.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "starting_info": { - "previous_period": "2", - "stake": "6295579444.000000000000000000", - "creation_height": "7" - } - }, - { - "delegator_address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "starting_info": { - "previous_period": "3", - "stake": "1221107604.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", - "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "starting_info": { - "previous_period": "5", - "stake": "3671255483.000000000000000000", - "creation_height": "50" - } - }, - { - "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "starting_info": { - "previous_period": "3", - "stake": "825862061.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", - "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", - "starting_info": { - "previous_period": "2", - "stake": "340930766.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "starting_info": { - "previous_period": "5", - "stake": "13874964933.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "starting_info": { - "previous_period": "7", - "stake": "22147479421.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "starting_info": { - "previous_period": "3", - "stake": "5740343356.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "starting_info": { - "previous_period": "9", - "stake": "11614756424.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "starting_info": { - "previous_period": "8", - "stake": "209859957.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "starting_info": { - "previous_period": "6", - "stake": "157324268.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "starting_info": { - "previous_period": "4", - "stake": "20037186316.000000000000000000", - "creation_height": "6" - } - }, - { - "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "starting_info": { - "previous_period": "3", - "stake": "17646792.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "starting_info": { - "previous_period": "5", - "stake": "89358777.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "starting_info": { - "previous_period": "2", - "stake": "5054551129.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "starting_info": { - "previous_period": "3", - "stake": "39160384.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "starting_info": { - "previous_period": "4", - "stake": "18344719406.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "starting_info": { - "previous_period": "2", - "stake": "410769752.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "starting_info": { - "previous_period": "1", - "stake": "159276935.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "starting_info": { - "previous_period": "5", - "stake": "97571824.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "starting_info": { - "previous_period": "6", - "stake": "4090038169.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "starting_info": { - "previous_period": "4", - "stake": "1168681082.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "starting_info": { - "previous_period": "7", - "stake": "18120372537.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", - "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "starting_info": { - "previous_period": "2", - "stake": "4792139392.000000000000000000", - "creation_height": "47" - } - }, - { - "delegator_address": "cosmos1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpkca4g8", - "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "starting_info": { - "previous_period": "1", - "stake": "15023386396.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", - "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "starting_info": { - "previous_period": "6", - "stake": "376238441.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "starting_info": { - "previous_period": "5", - "stake": "281580943.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqcrj0xk", - "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", - "starting_info": { - "previous_period": "2", - "stake": "1028714701.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1ryp2xkqe74y5kx6zffqtdc3wzgny8xg8eguupq", - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "starting_info": { - "previous_period": "6", - "stake": "1639136540.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "starting_info": { - "previous_period": "5", - "stake": "205025816.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "starting_info": { - "previous_period": "2", - "stake": "23612702988.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "starting_info": { - "previous_period": "7", - "stake": "11095524326.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "starting_info": { - "previous_period": "6", - "stake": "131936453.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "starting_info": { - "previous_period": "5", - "stake": "11761380768.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "starting_info": { - "previous_period": "2", - "stake": "21096282678.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", - "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "starting_info": { - "previous_period": "2", - "stake": "12106150602.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", - "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "starting_info": { - "previous_period": "4", - "stake": "179430222.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "starting_info": { - "previous_period": "4", - "stake": "29688637.000000000000000000", - "creation_height": "12" - } - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "starting_info": { - "previous_period": "2", - "stake": "212323217.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1l5d2lg5hku0m4u8mh866zhjcy2dekpk598m8wr", - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "starting_info": { - "previous_period": "3", - "stake": "25069342080.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", - "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", - "starting_info": { - "previous_period": "2", - "stake": "3907335026.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "starting_info": { - "previous_period": "2", - "stake": "7597437829.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn", - "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "starting_info": { - "previous_period": "1", - "stake": "2977168576.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "starting_info": { - "previous_period": "3", - "stake": "12769609475.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "starting_info": { - "previous_period": "6", - "stake": "522473074.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "starting_info": { - "previous_period": "4", - "stake": "19453723967.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "starting_info": { - "previous_period": "5", - "stake": "7100496609.000000000000000000", - "creation_height": "5" - } - }, - { - "delegator_address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "starting_info": { - "previous_period": "4", - "stake": "5734721271.000000000000000000", - "creation_height": "4" - } - }, - { - "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "starting_info": { - "previous_period": "3", - "stake": "40666822.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "starting_info": { - "previous_period": "2", - "stake": "8982227181.000000000000000000", - "creation_height": "2" - } - }, - { - "delegator_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "starting_info": { - "previous_period": "4", - "stake": "3178697313.000000000000000000", - "creation_height": "8" - } - }, - { - "delegator_address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "starting_info": { - "previous_period": "6", - "stake": "11738157290.000000000000000000", - "creation_height": "48" - } - }, - { - "delegator_address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "starting_info": { - "previous_period": "2", - "stake": "315677262.000000000000000000", - "creation_height": "1" - } - }, - { - "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "starting_info": { - "previous_period": "5", - "stake": "2332669614.000000000000000000", - "creation_height": "14" - } - }, - { - "delegator_address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "starting_info": { - "previous_period": "3", - "stake": "11119271370.000000000000000000", - "creation_height": "5" - } - } - ], - "validator_slash_events": [ - { - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "height": "25", - "period": "4", - "validator_slash_event": { - "validator_period": "4", - "fraction": "0.026601021112653654" - } - }, - { - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "height": "2", - "period": "4", - "validator_slash_event": { - "validator_period": "4", - "fraction": "0.023923716300005538" - } - } - ] - }, - "staking": { - "params": { - "unbonding_time": "17344000000000", - "max_validators": 223, - "max_entries": 7, - "historical_entries": 3, - "bond_denom": "stake" - }, - "last_total_power": "7451648", - "last_validator_powers": [ - { - "Address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "Power": "24767" - }, - { - "Address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "Power": "40149" - }, - { - "Address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "Power": "33873" - }, - { - "Address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "Power": "49524" - }, - { - "Address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "Power": "76856" - }, - { - "Address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "Power": "16016" - }, - { - "Address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "Power": "32584" - }, - { - "Address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "Power": "15545" - }, - { - "Address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "Power": "35273" - }, - { - "Address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "Power": "24353" - }, - { - "Address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "Power": "44979" - }, - { - "Address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "Power": "24972" - }, - { - "Address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "Power": "15307" - }, - { - "Address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "Power": "37286" - }, - { - "Address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "Power": "26109" - }, - { - "Address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "Power": "25204" - }, - { - "Address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "Power": "23014" - }, - { - "Address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "Power": "49505" - }, - { - "Address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "Power": "52891" - }, - { - "Address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "Power": "69365" - }, - { - "Address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "Power": "17054" - }, - { - "Address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "Power": "55080" - }, - { - "Address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "Power": "17768" - }, - { - "Address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "Power": "22598" - }, - { - "Address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "Power": "27149" - }, - { - "Address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "Power": "49314" - }, - { - "Address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "Power": "26185" - }, - { - "Address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "Power": "32785" - }, - { - "Address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "Power": "33846" - }, - { - "Address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "Power": "25066" - }, - { - "Address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "Power": "25061" - }, - { - "Address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "Power": "76719" - }, - { - "Address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "Power": "18750" - }, - { - "Address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "Power": "24248" - }, - { - "Address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "Power": "82798" - }, - { - "Address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "Power": "26155" - }, - { - "Address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "Power": "32302" - }, - { - "Address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "Power": "56132" - }, - { - "Address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "Power": "69316" - }, - { - "Address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "Power": "27808" - }, - { - "Address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "Power": "17750" - }, - { - "Address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "Power": "22144" - }, - { - "Address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "Power": "16214" - }, - { - "Address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "Power": "23352" - }, - { - "Address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "Power": "34693" - }, - { - "Address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "Power": "42958" - }, - { - "Address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "Power": "21734" - }, - { - "Address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "Power": "29256" - }, - { - "Address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "Power": "65051" - }, - { - "Address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "Power": "18897" - }, - { - "Address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "Power": "27157" - }, - { - "Address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "Power": "45028" - }, - { - "Address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "Power": "35018" - }, - { - "Address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "Power": "17547" - }, - { - "Address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "Power": "25071" - }, - { - "Address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "Power": "27784" - }, - { - "Address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "Power": "31634" - }, - { - "Address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "Power": "22383" - }, - { - "Address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "Power": "16236" - }, - { - "Address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "Power": "42937" - }, - { - "Address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "Power": "36911" - }, - { - "Address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "Power": "39363" - }, - { - "Address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "Power": "27734" - }, - { - "Address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "Power": "27605" - }, - { - "Address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "Power": "24423" - }, - { - "Address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "Power": "25592" - }, - { - "Address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "Power": "25675" - }, - { - "Address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "Power": "50488" - }, - { - "Address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "Power": "20659" - }, - { - "Address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "Power": "53644" - }, - { - "Address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "Power": "21168" - }, - { - "Address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "Power": "27374" - }, - { - "Address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "Power": "20929" - }, - { - "Address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "Power": "15286" - }, - { - "Address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "Power": "70162" - }, - { - "Address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "Power": "20279" - }, - { - "Address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "Power": "31584" - }, - { - "Address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "Power": "22768" - }, - { - "Address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "Power": "26491" - }, - { - "Address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "Power": "16257" - }, - { - "Address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "Power": "62801" - }, - { - "Address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "Power": "22515" - }, - { - "Address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "Power": "29556" - }, - { - "Address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "Power": "25121" - }, - { - "Address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "Power": "59694" - }, - { - "Address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "Power": "16949" - }, - { - "Address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "Power": "20324" - }, - { - "Address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "Power": "18158" - }, - { - "Address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "Power": "25435" - }, - { - "Address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "Power": "16773" - }, - { - "Address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "Power": "17705" - }, - { - "Address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "Power": "26461" - }, - { - "Address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "Power": "17862" - }, - { - "Address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "Power": "112536" - }, - { - "Address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "Power": "27525" - }, - { - "Address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "Power": "57637" - }, - { - "Address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "Power": "19834" - }, - { - "Address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "Power": "37175" - }, - { - "Address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "Power": "55634" - }, - { - "Address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "Power": "20453" - }, - { - "Address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "Power": "52558" - }, - { - "Address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "Power": "18560" - }, - { - "Address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "Power": "22083" - }, - { - "Address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "Power": "26763" - }, - { - "Address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "Power": "25943" - }, - { - "Address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "Power": "68955" - }, - { - "Address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "Power": "49844" - }, - { - "Address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "Power": "19233" - }, - { - "Address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "Power": "25961" - }, - { - "Address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "Power": "33320" - }, - { - "Address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "Power": "59094" - }, - { - "Address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "Power": "27718" - }, - { - "Address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "Power": "33772" - }, - { - "Address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "Power": "24587" - }, - { - "Address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "Power": "62232" - }, - { - "Address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "Power": "25948" - }, - { - "Address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "Power": "18426" - }, - { - "Address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "Power": "16774" - }, - { - "Address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "Power": "32156" - }, - { - "Address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "Power": "16811" - }, - { - "Address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "Power": "19540" - }, - { - "Address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "Power": "33258" - }, - { - "Address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "Power": "41543" - }, - { - "Address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "Power": "61843" - }, - { - "Address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "Power": "36037" - }, - { - "Address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "Power": "33206" - }, - { - "Address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "Power": "27567" - }, - { - "Address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "Power": "27671" - }, - { - "Address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "Power": "25069" - }, - { - "Address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "Power": "55737" - }, - { - "Address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "Power": "33054" - }, - { - "Address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "Power": "78601" - }, - { - "Address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "Power": "18090" - }, - { - "Address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "Power": "33968" - }, - { - "Address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "Power": "19857" - }, - { - "Address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "Power": "23726" - }, - { - "Address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "Power": "16516" - }, - { - "Address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "Power": "45010" - }, - { - "Address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "Power": "54768" - }, - { - "Address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "Power": "25326" - }, - { - "Address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "Power": "67804" - }, - { - "Address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "Power": "41964" - }, - { - "Address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "Power": "28676" - }, - { - "Address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "Power": "34574" - }, - { - "Address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "Power": "16992" - }, - { - "Address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "Power": "26261" - }, - { - "Address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "Power": "46127" - }, - { - "Address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "Power": "22249" - }, - { - "Address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "Power": "39560" - }, - { - "Address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "Power": "16420" - }, - { - "Address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "Power": "26062" - }, - { - "Address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "Power": "44313" - }, - { - "Address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "Power": "25164" - }, - { - "Address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "Power": "16985" - }, - { - "Address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "Power": "25367" - }, - { - "Address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "Power": "54901" - }, - { - "Address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "Power": "15374" - }, - { - "Address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "Power": "33057" - }, - { - "Address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "Power": "49683" - }, - { - "Address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "Power": "34289" - }, - { - "Address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "Power": "29885" - }, - { - "Address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "Power": "21181" - }, - { - "Address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "Power": "39430" - }, - { - "Address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "Power": "32328" - }, - { - "Address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "Power": "15813" - }, - { - "Address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "Power": "25957" - }, - { - "Address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "Power": "45284" - }, - { - "Address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "Power": "44505" - }, - { - "Address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "Power": "22456" - }, - { - "Address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "Power": "45811" - }, - { - "Address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "Power": "24610" - }, - { - "Address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "Power": "34459" - }, - { - "Address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "Power": "55948" - }, - { - "Address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "Power": "15675" - }, - { - "Address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "Power": "45487" - }, - { - "Address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "Power": "24261" - }, - { - "Address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "Power": "31770" - }, - { - "Address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "Power": "37602" - }, - { - "Address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "Power": "37676" - }, - { - "Address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "Power": "26737" - }, - { - "Address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "Power": "20405" - }, - { - "Address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "Power": "25102" - }, - { - "Address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "Power": "17609" - }, - { - "Address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "Power": "41119" - }, - { - "Address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "Power": "19565" - }, - { - "Address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "Power": "44648" - }, - { - "Address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "Power": "34209" - }, - { - "Address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "Power": "36900" - }, - { - "Address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "Power": "28980" - }, - { - "Address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "Power": "27742" - }, - { - "Address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "Power": "17377" - }, - { - "Address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "Power": "25431" - }, - { - "Address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "Power": "74690" - }, - { - "Address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "Power": "27874" - }, - { - "Address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "Power": "68086" - }, - { - "Address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "Power": "25446" - }, - { - "Address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "Power": "35741" - }, - { - "Address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "Power": "19637" - }, - { - "Address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "Power": "56856" - }, - { - "Address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "Power": "36122" - }, - { - "Address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "Power": "16807" - }, - { - "Address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "Power": "48540" - }, - { - "Address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "Power": "29401" - }, - { - "Address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "Power": "24697" - }, - { - "Address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "Power": "41494" - }, - { - "Address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "Power": "39420" - }, - { - "Address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "Power": "23703" - }, - { - "Address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "Power": "69725" - }, - { - "Address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "Power": "21764" - }, - { - "Address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "Power": "25229" - }, - { - "Address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "Power": "16747" - }, - { - "Address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "Power": "56914" - }, - { - "Address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "Power": "53587" - }, - { - "Address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "Power": "20301" - }, - { - "Address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "Power": "23438" - }, - { - "Address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "Power": "23476" - }, - { - "Address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "Power": "19815" - }, - { - "Address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "Power": "25456" - }, - { - "Address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "Power": "44085" - }, - { - "Address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "Power": "25311" - }, - { - "Address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "Power": "32745" - }, - { - "Address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "Power": "21858" - }, - { - "Address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "Power": "28684" - } - ], - "validators": [ - { - "operator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels7tpscy", - "status": 3, - "tokens": "24767745772", - "delegator_shares": "24767745772.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.064962829627143450", - "max_rate": "0.700000000000000000", - "max_change_rate": "0.524524837966075502" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2clak7n0wuffqrj9ltzxmj7mp8nfd4mupcs2qx8wcntcmqmrhlg5vf35j7", - "status": 1, - "tokens": "5753141484", - "delegator_shares": "5753141484.000000000000000000", - "description": { - "moniker": "wdwulLxyKe", - "identity": "QqZmHtsqUC", - "website": "cuuMWdybju", - "security_contact": "lFYCqceWXh", - "details": "CUtMyvoidK" - }, - "unbonding_height": "6", - "unbonding_time": "9936-01-01T04:22:01Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.650000000000000000", - "max_change_rate": "0.115214438896595768" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xt2s2vh", - "status": 3, - "tokens": "40149298125", - "delegator_shares": "40149298125.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.020987080088521851", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.079654399773437862" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk7tt4rl", - "status": 3, - "tokens": "33873720903", - "delegator_shares": "33873720903.000000000000000000", - "description": { - "moniker": "mLoNnmWUiV", - "identity": "RHiUhLQQnZ", - "website": "GdVEOYibSd", - "security_contact": "DcfUpyGSpE", - "details": "kaQgULDDFV" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.793635545567707656", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.546926599085395557" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfkykt89x2wmxt2w74v340hwp8azwyzswzgxzmcv46995zwggpu66ans7kn", - "status": 3, - "tokens": "49524189675", - "delegator_shares": "49524189675.000000000000000000", - "description": { - "moniker": "qorkgLHbbW", - "identity": "vVsXuupmaH", - "website": "GASCHEJsbz", - "security_contact": "KEcXQQooNh", - "details": "UlGvDMHBgm" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.150351690116871266", - "max_rate": "0.470000000000000000", - "max_change_rate": "0.232118363435586291" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqve274rfua7xfczhfywq3xmq697sc39wlnvqwlpewefqud77cehe5t682kl", - "status": 1, - "tokens": "12080352392", - "delegator_shares": "12080352392.000000000000000000", - "description": { - "moniker": "FbRIhVHFau", - "identity": "HIdWlohNVg", - "website": "oXDusHPuBW", - "security_contact": "MIuroYiNYk", - "details": "yzSyOcoXIA" - }, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.980000000000000000", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.637017075521110755" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcrkzkl0", - "status": 3, - "tokens": "76856004359", - "delegator_shares": "76856004359.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.159853619317053801", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.178173481628386356" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv2gdzf9hv5kg8cua2vdmh6j4pvu8t6qt3qna7ahzamg3k85zhqks2vrug8", - "status": 1, - "tokens": "10291647618", - "delegator_shares": "10291647618.000000000000000000", - "description": { - "moniker": "DsEkgGrQIW", - "identity": "LhylLHTNSR", - "website": "neVVZYPYun", - "security_contact": "SrqnNfZPyD", - "details": "covJBBgWgi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.024110631876108367", - "max_rate": "0.060000000000000000", - "max_change_rate": "0.059149357084397769" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0yv2h8z80vtfttsewrwe2v83haaceax7q3ey95uaeqj8lstf7l674zn3ut", - "status": 3, - "tokens": "16016194501", - "delegator_shares": "16016194501.000000000000000000", - "description": { - "moniker": "WVhrVMjLnZ", - "identity": "QiIQjemxtv", - "website": "KCKlbRarYk", - "security_contact": "AwimEeOMDq", - "details": "omCiVdOfZS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.636807270475032336", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.762928812525012131" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwstfpc6n2mx2kwfz0p6cqcp2d4am2xavsgtdncu3aqwvuvr8672zq0r78s", - "status": 1, - "tokens": "6707030963", - "delegator_shares": "6707030963.000000000000000000", - "description": {}, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.300951621180132243", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.231974974827222704" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0rfcm50fj3x25lu4dlrvcypfmrelrrtpckw5qn4xhzwweutl3rpuzqaycl", - "status": 1, - "tokens": "998337488", - "delegator_shares": "998337488.000000000000000000", - "description": { - "moniker": "ggHvjQWPsn", - "identity": "TSLKAGCHeV", - "website": "pJCXCTYBcs", - "security_contact": "bBFXWKuUjd", - "details": "mlLcRteZDO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.000000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-04T15:40:16Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghknhrvft", - "status": 3, - "tokens": "32584502965", - "delegator_shares": "32584502965.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.063963134401067102" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgt7tyq6", - "status": 3, - "tokens": "15545552914", - "delegator_shares": "15545552914.000000000000000000", - "description": { - "moniker": "VaOLitHrfh", - "identity": "zYkbJeTdPC", - "website": "RWLWpQBLTs", - "security_contact": "EEFOrnsvml", - "details": "xRXuWfcvoz" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.209346043397093808", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.261491014079542938" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgvt8hk8ugsx3spnywmwca23g5n2mefgl9wqae5apg5c8rfjqejczx7m9pt", - "status": 1, - "tokens": "632273041", - "delegator_shares": "632273041.000000000000000000", - "description": { - "moniker": "RTtEwCbQJP", - "identity": "nwxkifTnqT", - "website": "XmvidEOMQm", - "security_contact": "vwnSfNMnzZ", - "details": "tggKCpEWIf" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.524843579708394583", - "max_rate": "0.720000000000000000", - "max_change_rate": "0.101390585218042270" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdhs8x9jxh3zj8x9khc8mxzmschyuglut7qc08pgnsvsez40ejvagk98fp5", - "status": 1, - "tokens": "847666854", - "delegator_shares": "847666854.000000000000000000", - "description": { - "moniker": "ydPLQsYmIS", - "identity": "mavrVBFYgS", - "website": "WKiuHqSQHZ", - "security_contact": "JdSAwbrUfj", - "details": "mqtJCHeTAG" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.000000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpvkknmf7", - "status": 3, - "tokens": "35273490053", - "delegator_shares": "35273490053.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.412168984856446389", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.601152598273329028" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2yn5flk79h6vhzu7xp0heeklwgkac6whhz9ezkvj2k0920k58qvquulfzs", - "status": 1, - "tokens": "1750195180", - "delegator_shares": "1750195180.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.117442172658848604" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4645lf2dka2qs2renc2n2rts24k9xfmxnx5fkhvj3squp8nv5ugyr2nj8", - "status": 2, - "tokens": "5104433738", - "delegator_shares": "5104433738.000000000000000000", - "description": {}, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.005185006676002722", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.268395235691771325" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdq977shfdy56qqae5djrzznyn6kqv2s55gh8jtr5gsmkttjdsvd72nkejc", - "status": 1, - "tokens": "8916911438", - "delegator_shares": "8916911438.000000000000000000", - "description": { - "moniker": "dxqsTRkaYb", - "identity": "TOJMyzBlre", - "website": "ruYObGvtfU", - "security_contact": "PoeWHpGxhY", - "details": "NfReLbYTyY" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.210000000000000000", - "max_rate": "0.210000000000000000", - "max_change_rate": "0.014827952061898434" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvw0g93n8", - "status": 3, - "tokens": "24353363633", - "delegator_shares": "24353363633.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.140843713075627976", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.124247346623493378" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtxrkpudghuhgsu0he7ntk7q0asqa5ax23y7rnn5mfjr2d68z4emsrwqssp", - "status": 3, - "tokens": "44979344173", - "delegator_shares": "44979344173.000000000000000000", - "description": { - "moniker": "eJECwiPlqs", - "identity": "TywZsaZwgH", - "website": "jtFVQJUofX", - "security_contact": "fstanspUpc", - "details": "RQddrwMsIR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.005369299901591159", - "max_rate": "0.030000000000000000", - "max_change_rate": "0.010979308887356502" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwz2zelc", - "status": 3, - "tokens": "24972834479", - "delegator_shares": "24972834479.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118883162683785924", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.582076368438090700" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2dcqs6jwgqs06hz297xdv606lcyx76wnyf228c98wsnmrarnjg7qdrlhmh", - "status": 3, - "tokens": "15307584671", - "delegator_shares": "15307584671.000000000000000000", - "description": { - "moniker": "MLAiGifuge", - "identity": "YmgtyeQqKn", - "website": "tgmRpbrPqg", - "security_contact": "EoVdOQlqiF", - "details": "MFxkDUZjLF" - }, - "unbonding_height": "49", - "unbonding_time": "9936-01-04T20:29:20Z", - "commission": { - "commission_rates": { - "rate": "0.079450929148714776", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.213073238635972528" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0g2ma6xw58ftmksx3k7vk80w6fc9cume5z0h05yycsafk9v62ywkzlshqc", - "status": 1, - "tokens": "5044911319", - "delegator_shares": "5044911319.000000000000000000", - "description": { - "moniker": "zTrVCpgXUe", - "identity": "unfAiREWWG", - "website": "zPGHaOmdaQ", - "security_contact": "ejYFFBeYoZ", - "details": "yBOLCBGsRi" - }, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.303756486405262817", - "max_rate": "0.510000000000000000", - "max_change_rate": "0.510000000000000000" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q205udc4", - "status": 3, - "tokens": "37286335725", - "delegator_shares": "37286335725.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.150000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.137121313165408722" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt032nytxy3x5xdysx4nyqd43jz9ty6she7qzs8ng7tjyy2rnrstywwgu5c", - "status": 1, - "tokens": "203339835", - "delegator_shares": "203339835.000000000000000000", - "description": { - "moniker": "ynEaQzbejL", - "identity": "MUyIiByuFi", - "website": "AGxnGDQIOT", - "security_contact": "KYcvOadcfO", - "details": "swLSGZmGOw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.462568474915615654", - "max_rate": "0.700000000000000000", - "max_change_rate": "0.700000000000000000" - }, - "update_time": "9936-01-01T16:55:11Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvfjj8axcs74r3vxh3lclw7upds6cn5ru6ggy2ptzjsp4e6j8racwzngt4r", - "status": 1, - "tokens": "6058218058", - "delegator_shares": "6058218058.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.020053792824689742" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdk79m7s7fjmw7x7v9wstfge6tx0y9vlke6q0w8xnw6xrvqjxnx7wremcav", - "status": 1, - "tokens": "7304584820", - "delegator_shares": "7304584820.000000000000000000", - "description": { - "moniker": "BdegmqHdlW", - "identity": "KHOTjTMoXW", - "website": "xjpfgHTnPp", - "security_contact": "nxZRJewfeS", - "details": "gPXCjmtPkp" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.425246430057154161" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zycdvvrg7", - "status": 3, - "tokens": "26109827309", - "delegator_shares": "26109827309.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.272379182115041576" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvqzwt52t9y9pwaa3f2swmdm89ly65wv5vtj3w5uvz52u4w2mhuy7n0hqlm", - "status": 1, - "tokens": "6575461080", - "delegator_shares": "6575461080.000000000000000000", - "description": { - "moniker": "tMnHvAwTJR", - "identity": "onTsWeVUKS", - "website": "veLYiFvaVy", - "security_contact": "njDJSVeKyI", - "details": "sWOtMODqPy" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.769634007692600014", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "consensus_pubkey": "cosmosvalconspub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwlhqscf", - "status": 3, - "tokens": "25204407264", - "delegator_shares": "25204407264.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.276804190595109972", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.303611347820460701" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv9qnwg9cn0v623s0xcnfn88vfn3musyh22lk522tnxt4a9g44tlugcyrxd", - "status": 1, - "tokens": "101462019", - "delegator_shares": "101462019.000000000000000000", - "description": { - "moniker": "VSOJycctFN", - "identity": "vFDsxccNPn", - "website": "szHnznvmsJ", - "security_contact": "WfbWJuwCJr", - "details": "hVYDcdjcPF" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.133628283997124854", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.150000000000000000" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2u3gzal", - "status": 3, - "tokens": "23014258552", - "delegator_shares": "23014258552.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289943655120962524", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.271265684659427360" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvpp0e5dwtq4r86wnmrfva492d8qedsntcl7pamjgecqcwz36qltuzda7yc", - "status": 1, - "tokens": "5183376555", - "delegator_shares": "5183376555.000000000000000000", - "description": { - "moniker": "coLWQUtfpH", - "identity": "qqRgVFIBHt", - "website": "tVbQGrFIRK", - "security_contact": "XqOIjvNBNm", - "details": "PNMPALBEye" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.134622338980971365", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.192256407383356671" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgh4tj7q", - "status": 3, - "tokens": "49505425616", - "delegator_shares": "49505425616.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.519126528788995280", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw55ftmtn", - "status": 3, - "tokens": "52891997390", - "delegator_shares": "52891997390.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.006443603339396517", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.110565720532816181" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0x07aykzgfl7xjmd49u0dnc0xc69xv3cftdhly8hgc7y3djgfpqcd7szxu", - "status": 1, - "tokens": "3104272392", - "delegator_shares": "3104272392.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.309206591421572804", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.173213597206352691" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavc40dh4", - "status": 3, - "tokens": "69365122054", - "delegator_shares": "69365122054.000000000000000000", - "description": { - "moniker": "IoqkplxtIQ", - "identity": "SYtEYnqVjz", - "website": "cbrMdhVrVp", - "security_contact": "eWitXxyhJZ", - "details": "FCojJQQFCQ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.745132980800690980", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.321606633967630124" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tugphy2d", - "status": 3, - "tokens": "17054284690", - "delegator_shares": "17054284690.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.602634897210355218", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.136597759514787421" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfhaz3cwkjvqxwcgmpg4h52j5ta6tnanf0ngtkcreptep0al8vqdqx2rvua", - "status": 1, - "tokens": "4205959298", - "delegator_shares": "4205959298.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000203985932473082", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqghfgrvv86d4rtnt8zqrrmnj8vqrm75e4xsl7wr9rww7tewvzj2pygmcvw3", - "status": 1, - "tokens": "5951502740", - "delegator_shares": "5951502740.000000000000000000", - "description": { - "moniker": "sPILgSqlFb", - "identity": "SeswFftEiP", - "website": "guQCrflISz", - "security_contact": "fHotzizZnj", - "details": "gvAfzRuUwL" - }, - "unbonding_height": "14", - "unbonding_time": "9936-01-01T21:44:15Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.074237147649670066" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jztkylp", - "status": 3, - "tokens": "55080258715", - "delegator_shares": "55080258715.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.052047960532670175", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwuthwk4ulyfx4j6f8q9ql4cwhnu923da4m63sg3n4hldpa2rzr2x7m8t9a", - "status": 1, - "tokens": "9924972848", - "delegator_shares": "9924972848.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.818438994582953595", - "max_rate": "0.950000000000000000", - "max_change_rate": "0.619609185068905685" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgrwz3gl", - "status": 3, - "tokens": "17768682341", - "delegator_shares": "17768682341.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.141929485726276362" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd45mshdzdsn0zpnemh0zghvu25ukrxkn9r0nk0mc8qz44k2fpdn6fptqcl", - "status": 1, - "tokens": "13149786343", - "delegator_shares": "13149786343.000000000000000000", - "description": { - "moniker": "svuLpcmsdf", - "identity": "IvJIgPtZYX", - "website": "gLAZCqbEaE", - "security_contact": "CJQnRdPYVV", - "details": "mTuGpBAhce" - }, - "unbonding_height": "6", - "unbonding_time": "9936-01-01T04:22:01Z", - "commission": { - "commission_rates": { - "rate": "0.590000000000000000", - "max_rate": "0.590000000000000000", - "max_change_rate": "0.048300182902893644" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf2ugr68h5nt2x6k4c6ag0f69f4ey80uv5w4u9ludsdpdtrhw07lvlaey06", - "status": 1, - "tokens": "9436725725", - "delegator_shares": "9436725725.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.783302239482289410", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.369136928052532298" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yr97z8g", - "status": 3, - "tokens": "22598538029", - "delegator_shares": "22598538029.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.335354744004515496", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.096800797786563611" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2zq3f3j", - "status": 3, - "tokens": "27149799034", - "delegator_shares": "27149799034.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.158969199652087770", - "max_rate": "0.220000000000000000", - "max_change_rate": "0.220000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0560r7042zjwg7hflfrslec73nzuyejkhpu5v84lhf4xjlgkkl26vdc8q9", - "status": 1, - "tokens": "6070945323", - "delegator_shares": "6070945323.000000000000000000", - "description": { - "moniker": "lRmVgGciBK", - "identity": "PYKZImdODA", - "website": "DBfUAAMaGR", - "security_contact": "JTAVthKvsq", - "details": "pphPkYzfvl" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.038203004183403745", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.076026861273924845" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt8n7x4t7x2kvd3dr00mfuuemuc4spvhdt35g05vatvjpfvw5uww53gykr9", - "status": 1, - "tokens": "12005823038", - "delegator_shares": "12005823038.000000000000000000", - "description": {}, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.347986548032108220", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.408132835345187007" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvelvh903wf0ufp2qn3rpt50zlv3ffp0n767urfar7af9jt0ng57k7r3flw", - "status": 1, - "tokens": "5460940542", - "delegator_shares": "5460940542.000000000000000000", - "description": { - "moniker": "jmxfekypVf", - "identity": "rYJvVTdygL", - "website": "FChuyqxLnp", - "security_contact": "SttJEHjrWs", - "details": "HkliJnLUqo" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.045222817456626466", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.290000000000000000" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0lh7y04tmtczvnzltnthy5qvtmdx4tznmwt9z76vhhmd7mn5l5uqal3edt", - "status": 1, - "tokens": "12268746738", - "delegator_shares": "12268746738.000000000000000000", - "description": { - "moniker": "eIPQOnpFIY", - "identity": "VfzwEnpOhp", - "website": "aVNuZBcWNj", - "security_contact": "ZrewdyIwdo", - "details": "rlcRtyUbUJ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.032483401886133298", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.013949228326725611" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg4mn8jk4naald3ysu3uh6cnmpsx3fkxn7xer3nyxlcxfz7lgn5w5f6m46j", - "status": 1, - "tokens": "3204512038", - "delegator_shares": "3204512038.000000000000000000", - "description": { - "moniker": "NeplKMBYoj", - "identity": "mxdKPDhMHE", - "website": "PAYxMlLNXk", - "security_contact": "LOuMtpIRJY", - "details": "jYIxjiLuTD" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.753643962520784250" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq246sxc5kns0ym6st5wyf6mk0x2cayek9wngczyvgk8phxrat02cqh8w5p2", - "status": 3, - "tokens": "49314038732", - "delegator_shares": "49314038732.000000000000000000", - "description": { - "moniker": "caRBWwzxXd", - "identity": "BJSnkbfQjh", - "website": "ELsVPBoBHb", - "security_contact": "nZkoSMuzKV", - "details": "AuAKjeoitI" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.010525961964940541", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.045814731203367877" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdn6uzyl56y7nttklxx49wtfnz925n96ut22xx3s7t8hphp4mrh5g5qkdqx", - "status": 1, - "tokens": "12584124", - "delegator_shares": "12584124.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.426120175355968674", - "max_rate": "0.550000000000000000", - "max_change_rate": "0.085472487593213038" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jhhj4uv", - "status": 3, - "tokens": "26185707851", - "delegator_shares": "26185707851.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.568319127244896272", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.226261076338173049" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5u4v4q5", - "status": 3, - "tokens": "32785129607", - "delegator_shares": "32785129607.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.009044195385937429", - "max_rate": "0.010000000000000000", - "max_change_rate": "0.002281789765845776" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpqq8zx8p", - "status": 3, - "tokens": "33846192792", - "delegator_shares": "33846192792.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.094250378854551281", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.043420993012939508" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtje4agendhh34cze964xcknahtyj03ung7v6k9f73rdpvv435jkzygu99m", - "status": 1, - "tokens": "12090792585", - "delegator_shares": "12090792585.000000000000000000", - "description": { - "moniker": "FUgPTgzyXM", - "identity": "jIsaTnGuhb", - "website": "iSiGeNeqiz", - "security_contact": "JoihWbqCAJ", - "details": "pTYcSzhlzs" - }, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.046150926656790509", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.356235996609570640" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvev2kew00wk3maqq2kducqd4yxum5as5y0h53mlymphr9nx5zmzwhqd43d", - "status": 1, - "tokens": "14322768708", - "delegator_shares": "14322768708.000000000000000000", - "description": { - "moniker": "TulFJTfJnY", - "identity": "vmMScmnlzF", - "website": "ERFHdlJtJz", - "security_contact": "nfAIndXgYy", - "details": "jMtNQrtcFe" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.091341847484127071", - "max_rate": "0.530000000000000000", - "max_change_rate": "0.525538840686318300" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv2xfr6pcx5axa04hegq38yjvz5wm0lj6nkvexrzlxe7lga96sasz656krg", - "status": 1, - "tokens": "4679862773", - "delegator_shares": "4679862773.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.630000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvhgqx90svcvk6htmhwpfudunnc0ne989y7ymdyltcssu7n3p4kw5080886", - "status": 1, - "tokens": "5346735375", - "delegator_shares": "5346735375.000000000000000000", - "description": { - "moniker": "QQnYKozfkv", - "identity": "qdNNaDaxFO", - "website": "KVkHWKnuQC", - "security_contact": "uGwwusIzkv", - "details": "GXvnKqrROd" - }, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.040000000000000000", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.012026445943425172" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv79a2a0wcq9kr62m5yupvx82mlxwxw6hx7c8dyl4trf8k2w7vh3w5wlhy0", - "status": 3, - "tokens": "25066394767", - "delegator_shares": "25066394767.000000000000000000", - "description": { - "moniker": "liMRThtiLT", - "identity": "QPHsvzHnkx", - "website": "BytvAmppJT", - "security_contact": "iBgKxrOkqF", - "details": "RcELAgZeDN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.115126355797501393", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.289658857878369113" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq06lz2fxdcn3tph2mnllznwszzja7vtlpm36t97zgrsycq2mdsw5qcrkuq4", - "status": 1, - "tokens": "321564722", - "delegator_shares": "321564722.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.071992077731645947", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.126011183390291568" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2pm4xasvuf9xsmw3578ask3ucm768pc006d69sj25t2j7gppvxpjvz6ggd", - "status": 1, - "tokens": "3323388806", - "delegator_shares": "3323388806.000000000000000000", - "description": { - "moniker": "PvopDaVlYF", - "identity": "rYVNrGoygV", - "website": "WWXcddCKNp", - "security_contact": "XGuHJIweYZ", - "details": "bEnfQrWihj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.536408027766659140", - "max_rate": "0.550000000000000000", - "max_change_rate": "0.116280242991191159" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4cheaqlnuzhlah5axl68mh50h59me9d4ha070l7w3zncl77dlakzzuj2y", - "status": 1, - "tokens": "441280532", - "delegator_shares": "441280532.000000000000000000", - "description": { - "moniker": "fdDvOsajDQ", - "identity": "gskfjrfYPb", - "website": "dIuOHzjERJ", - "security_contact": "dbVEGOmtZG", - "details": "ksTzbgAXtj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.185461719875081045", - "max_rate": "0.390000000000000000", - "max_change_rate": "0.257360618903198667" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtuw2axfye4m3vrjyu733k608nkh57vj62zx3ew7uzpf5lejemapj8cr7lf", - "status": 1, - "tokens": "10757828517", - "delegator_shares": "10757828517.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.308670693379303631", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.486932455559867167" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq04m4crs7rhxhslqgnakermccrsunsp5zty5awqaevlxhl6amrnq7hav7f7", - "status": 1, - "tokens": "13105570932", - "delegator_shares": "13105570932.000000000000000000", - "description": { - "moniker": "RpRNZcpBLM", - "identity": "ETxJEOvOLp", - "website": "AVbBGDsScb", - "security_contact": "zhzRLvZxjz", - "details": "ZzEmeIwzAT" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.213775811323318868", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.363003369418640683" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfp9mvx6gjdezn2vfxn9jk7jm2urml0xyvt3yg64s03yzkfphrthsdy925d", - "status": 3, - "tokens": "25061237568", - "delegator_shares": "25061237568.000000000000000000", - "description": { - "moniker": "wmxxGOZTpL", - "identity": "azxfwYYUUt", - "website": "izxOUVhQSX", - "security_contact": "lRgXsoitme", - "details": "eebhMKbHXO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.578049895054733896", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.402405887034980654" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc255eyr9", - "status": 3, - "tokens": "76719658246", - "delegator_shares": "76719658246.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.321194785873117781", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.561602155526895676" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u43hapa", - "status": 3, - "tokens": "18750673243", - "delegator_shares": "18750673243.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.188948913118426394", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.274693773376656673" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvpup8kv2mmqajfs08aks8yu8kcuwd323y4f0wu9e3k5grynt0g6ule9mjg", - "status": 3, - "tokens": "24248574347", - "delegator_shares": "24248574347.000000000000000000", - "description": { - "moniker": "bsrCMyYTRM", - "identity": "cTWbJOIMRX", - "website": "EMzKHBarjX", - "security_contact": "spsTAIOECF", - "details": "fTrZtqJTUr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.455524678875180233", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-01T06:29:20Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d29fg079", - "status": 3, - "tokens": "82798702711", - "delegator_shares": "82798702711.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289674444273548704", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.060992257943659564" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfurnf5y576evchnh468a5nmvtcllaysy8nfp5k5g6c6u7g9wzgmjzsg777", - "status": 1, - "tokens": "846166560", - "delegator_shares": "846166560.000000000000000000", - "description": { - "moniker": "ayfTQoiMIg", - "identity": "LfMHyAxOyf", - "website": "NHCLoOenMv", - "security_contact": "NCTWVyOnFn", - "details": "IHwPUxjoSZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.458203476477220958", - "max_rate": "0.520000000000000000", - "max_change_rate": "0.201242757286743245" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgss8cv9u", - "status": 3, - "tokens": "26155915081", - "delegator_shares": "26155915081.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.333198345990187069", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.410926346802169727" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "consensus_pubkey": "cosmosvalconspub1addwnpepqghlm3r37c95q3p3wvr8fxw8mvvdtj3tvhgduhzgzh4238ynz6f06f0rjfd", - "status": 3, - "tokens": "32302576994", - "delegator_shares": "32302576994.000000000000000000", - "description": { - "moniker": "hjulbVDPpf", - "identity": "pRsBrwBRzq", - "website": "VjiSZKAfKB", - "security_contact": "UHZkwTciXO", - "details": "JTfVgehmsi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.311759176624756474" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg2e2fy2hl6cn40sx780nvd228x9u40cfcpjvdnmn3mqfapyjt3m25w8u82", - "status": 1, - "tokens": "2592147197", - "delegator_shares": "2592147197.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.154388662793344854", - "max_rate": "0.190000000000000000", - "max_change_rate": "0.163850436594025444" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqge9z0fefq3xpf8y4q8j57c89x65luk2vtcx5mln75662ukq00f6sqefz8w", - "status": 2, - "tokens": "2439056961", - "delegator_shares": "2439056961.000000000000000000", - "description": { - "moniker": "pGvmyXHQYo", - "identity": "cCQHGXFLSL", - "website": "BaxemamtmF", - "security_contact": "wpZarCOeDy", - "details": "XYyJPmrQVh" - }, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.209082457058936007", - "max_rate": "0.470000000000000000", - "max_change_rate": "0.166552912196145925" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgmnkn2nw2c6m0s6nrrcyxksg9j50sesj03xzxa867yvgrzw6rhgjc45yeu", - "status": 1, - "tokens": "2814501210", - "delegator_shares": "2814501210.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.336015918058412894", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.176369444038449060" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvqtq2puvhmk7g8aa2fzxkjrjrvq2hfczxjcvfal8gtzjm7tts96kcamd4h", - "status": 1, - "tokens": "2290999526", - "delegator_shares": "2290999526.000000000000000000", - "description": { - "moniker": "rFekQzBUob", - "identity": "TkgdArxYHD", - "website": "jYCJcCQhAu", - "security_contact": "yLZXwubFtr", - "details": "axFdLIokGQ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.015694038805586186", - "max_rate": "0.070000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwus66jdl", - "status": 3, - "tokens": "56132991892", - "delegator_shares": "56132991892.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.500000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwvdjhxcmtkq3y39crkc6ue3q2xdgct97gggllt8a4wyuquyf9u26sv45pf", - "status": 1, - "tokens": "290004202", - "delegator_shares": "290004202.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.497656780906410782", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.491445719567726825" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22ep2k8n", - "status": 3, - "tokens": "69316998057", - "delegator_shares": "69316998057.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.624946300778690751", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.204995912261423056" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7ejhy28", - "status": 3, - "tokens": "27808118568", - "delegator_shares": "27808118568.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.067795278161998694", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.011309118617844055" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2qka3fe9l70y756uvhnkwe0c97sezs7zgnycyhzu4p5s3s4pyknyyl8jld", - "status": 1, - "tokens": "5061822", - "delegator_shares": "5061822.000000000000000000", - "description": { - "moniker": "qEQLmGTBiG", - "identity": "wNJiWXVlVi", - "website": "hReLoZUBPy", - "security_contact": "aDUuPIORAJ", - "details": "TeGFgrskCn" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.135094086175297130", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.696694600733795075" - }, - "update_time": "9936-01-01T14:57:22Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv8t92hg5h8d39cmznd7xfwudv744yj782rg7jx6utajy3xyzfypg4uzdww", - "status": 1, - "tokens": "2859472400", - "delegator_shares": "2859472400.000000000000000000", - "description": { - "moniker": "zZjxsrcHrs", - "identity": "BLTqCTkKhq", - "website": "zvZKSjOSUy", - "security_contact": "WikLlTuZzi", - "details": "LrLZfZwnhm" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.544886660428311705", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.378178897656383282" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwpunsvkz6dm8s4ngxsnzrk4hhlgtg92t2a0wprx9hyrxgun9nn9757k8v3", - "status": 1, - "tokens": "3988607104", - "delegator_shares": "3988607104.000000000000000000", - "description": { - "moniker": "POXTKVuPoD", - "identity": "OiWrlmnspg", - "website": "QuNFffPKCw", - "security_contact": "rfNvnRkTVg", - "details": "HLsWBpcSqd" - }, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.343304845161180522", - "max_rate": "0.490000000000000000", - "max_change_rate": "0.116969381604757084" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "consensus_pubkey": "cosmosvalconspub1addwnpepq28hkvfszngpgcpgkl9gtmjymhmfsdwhaw2zkx4sxqfu46kg7vp5xzr9uv0", - "status": 1, - "tokens": "9369781513", - "delegator_shares": "9369781513.000000000000000000", - "description": { - "moniker": "pczevQdeVR", - "identity": "upAiEfAggi", - "website": "ukoOQsgvEg", - "security_contact": "RoswibAKjH", - "details": "TPKPhtpeXJ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.096467243339835350", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.265046884965878837" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd9rxlxauf0f8wdquzctrg47q24aa3n20rel24g7wn8q2xyyy2cmwupr6a4", - "status": 1, - "tokens": "1274375295", - "delegator_shares": "1274375295.000000000000000000", - "description": { - "moniker": "pjGZMgAqSL", - "identity": "YueQESEyAc", - "website": "gwkHHPESDC", - "security_contact": "AoLWQlBJNV", - "details": "MOxSfCDGor" - }, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.075454810910095894", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.271996952866730673" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5kc0mzw", - "status": 3, - "tokens": "17750303222", - "delegator_shares": "17750303222.000000000000000000", - "description": { - "moniker": "uloyQQWkyI", - "identity": "gFyXSGlhKI", - "website": "ewFltsApZk", - "security_contact": "YGvOhkEKJw", - "details": "vIoOsfiLuj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.068730439287548849", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.118090772640391070" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv6fqe8ryspqh89rpj76xxts4ghsfqws3329ryzhr6cygp934r02qdu0n74", - "status": 1, - "tokens": "14451940598", - "delegator_shares": "14451940598.000000000000000000", - "description": { - "moniker": "BGKhZzgXnx", - "identity": "cWftKUzHxI", - "website": "uaBFHXLzdc", - "security_contact": "ojiAxIqYZm", - "details": "lhxhGPjSnO" - }, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.395437548795457889", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.734660769451270652" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgpthjaszzcvylsczd42sr0lhanxdjkx07ec2r0g27mpwcmw55z0vuwt4te", - "status": 1, - "tokens": "6855101203", - "delegator_shares": "6855101203.000000000000000000", - "description": { - "moniker": "igDzTpVrSP", - "identity": "dvrbdNdcAV", - "website": "VaCxEpXRvn", - "security_contact": "JWxZxskHFt", - "details": "PtGTDRDCnm" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.590000000000000000", - "max_rate": "0.590000000000000000", - "max_change_rate": "0.467061941487853246" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0p646z0m699gujd2cavmh4qjmjy64044a50m4a2vhgmkn3g44jd5d95cf6", - "status": 1, - "tokens": "1751100", - "delegator_shares": "1751100.000000000000000000", - "description": { - "moniker": "twWaSNBAIU", - "identity": "XDOGNsvuzS", - "website": "isTBaTsfhg", - "security_contact": "dNcKvjBXgo", - "details": "qRhvNKpZan" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.439573589792496242", - "max_rate": "0.950000000000000000", - "max_change_rate": "0.285729710011181846" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw4vh38c7e44vpvszes4lcvjkz3ah25sja3jyj8a2jyfk44fn033xtu5ld3", - "status": 3, - "tokens": "22144783949", - "delegator_shares": "22144783949.000000000000000000", - "description": { - "moniker": "cJZANkQgEs", - "identity": "BMLCKDJfbU", - "website": "EvRCcPcNDz", - "security_contact": "wYcIjPQECa", - "details": "FTToLCGlSp" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.490000000000000000", - "max_rate": "0.490000000000000000", - "max_change_rate": "0.478812992279810912" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4hew3dkv9ytm47sg7767ktkthyt4jqgednnvcnhnzqx4fznylc2w43mgk", - "status": 1, - "tokens": "8457816494", - "delegator_shares": "8457816494.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.470000000000000000", - "max_rate": "0.470000000000000000", - "max_change_rate": "0.313668195250471906" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfvnelws9nysntl02t3hn42jsvg37krjan0y9ef0ff6qvyyeuflqxmtvcak", - "status": 1, - "tokens": "13735096388", - "delegator_shares": "13735096388.000000000000000000", - "description": {}, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.080430191050080691", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw0gk7g6ldfltzcg4evfrv6g75hp9d9raerpg574606nwrv8zy8fsu5f4kr", - "status": 1, - "tokens": "3931843209", - "delegator_shares": "3931843209.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.111839100753178310", - "max_rate": "0.520000000000000000", - "max_change_rate": "0.203190440691763416" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf5qh85wpx6k2c76xt38sxea46jc7929269hg8x9ddjeexhgrggjsr3mkxf", - "status": 1, - "tokens": "10075773258", - "delegator_shares": "10075773258.000000000000000000", - "description": {}, - "unbonding_height": "14", - "unbonding_time": "9936-01-01T21:44:15Z", - "commission": { - "commission_rates": { - "rate": "0.479310313704029644", - "max_rate": "0.950000000000000000", - "max_change_rate": "0.366540822300243268" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv0pnal4w8hydpq3vydqgjxmmxz7zg2g9lsj5vedvjq3pw6typfdcjfm5tc", - "status": 3, - "tokens": "16214844041", - "delegator_shares": "16214844041.000000000000000000", - "description": { - "moniker": "jKdcmnPYfC", - "identity": "exfUuYgqmd", - "website": "XdNCNZIBOf", - "security_contact": "hmiwPGchGt", - "details": "nUnBufZQah" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.330000000000000000", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.051583680374523519" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057uxwdfy", - "status": 3, - "tokens": "23352431465", - "delegator_shares": "23352431465.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.760000000000000000", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.183753469845780730" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvy095yf8a7eknhlnwzkum0wt53njxxww60vte7qkutwczt534dwhaclpm", - "status": 3, - "tokens": "34693121909", - "delegator_shares": "34693121909.000000000000000000", - "description": { - "moniker": "RuzZVxWXdB", - "identity": "QjsgdqaNzA", - "website": "UtlkBZyIyQ", - "security_contact": "vnsfyiwxFP", - "details": "dOxLDmGKTb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.005447024365505786", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.005395717096845063" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv368hqruqrftx368wx44f2uaslv95nk3dx7mahejcnruuqhfx9j5sf92lu", - "status": 1, - "tokens": "1577104716", - "delegator_shares": "1577104716.000000000000000000", - "description": { - "moniker": "ZcNwYceFVl", - "identity": "JdwwNpKEGe", - "website": "kIuDSvfEZG", - "security_contact": "kRdEoRVCNt", - "details": "ZxpAkBmyNU" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003879511693068742", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.037055319272782376" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd265f66tdc7mtewx4ayd6d4lls7m4ma9eehyac8s8jn93gxkw0k67nnaz4", - "status": 1, - "tokens": "6210644973", - "delegator_shares": "6210644973.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.096355762649540376" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf4ddylkupthgx8vutwclv8y5m3e5yzya2xsl84hl3fhth7y5xdm73esmg0", - "status": 1, - "tokens": "81861609", - "delegator_shares": "81861609.000000000000000000", - "description": { - "moniker": "aVoFaCLctw", - "identity": "UsuBjrjybt", - "website": "maJLZCDTDo", - "security_contact": "FrZMSAYCke", - "details": "HvsjSBlFEH" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.580000000000000000", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.276569602915150076" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef5gg2q6z", - "status": 3, - "tokens": "42958814024", - "delegator_shares": "42958814024.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.077000158168963029", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.197697608060710078" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwv7ukq0", - "status": 3, - "tokens": "21734647779", - "delegator_shares": "21734647779.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.460679550676466675", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.165088210560206816" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwc7h5wds8u3tspx3mwpfh5l3q3rv0t6ff33dt205v2zy2kxev9sykcs9uv", - "status": 3, - "tokens": "29256610441", - "delegator_shares": "29256610441.000000000000000000", - "description": { - "moniker": "iYUgQcrziE", - "identity": "hDYXNaKKIu", - "website": "FYsreoPnoD", - "security_contact": "FGAHzGKfjM", - "details": "gkHwWfssaE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.585764113115952818", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz4r8scm", - "status": 3, - "tokens": "65051132532", - "delegator_shares": "65051132532.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.041535797793389960", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.029250263820409753" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2cxeaw4", - "status": 3, - "tokens": "18897052265", - "delegator_shares": "18897052265.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.416117321788354038", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.139830256647094326" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgr3yz0pw3dl98dsljzz82u99665wlgyya6ymlhm7vgjypm39jwky55t0wz", - "status": 1, - "tokens": "859335658", - "delegator_shares": "859335658.000000000000000000", - "description": { - "moniker": "wCDTSgWkyH", - "identity": "TitohQmURH", - "website": "RyINWHhgOo", - "security_contact": "hEOUeRXHVg", - "details": "SyWWUTsVOf" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.230769629091954646", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2897we7j0jrf6mg2c7z2vekjpvq4m4rrqpdmpxe7ccnac5smad7zn0jfs4", - "status": 1, - "tokens": "220717877", - "delegator_shares": "220717877.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.278689953722191028", - "max_rate": "0.400000000000000000", - "max_change_rate": "0.399029965743980239" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvj4d7pjfcg6fcckuyh02wkr8vtz82zttnsu2f7say2pwsvyxn52ukma7rw", - "status": 1, - "tokens": "13032730128", - "delegator_shares": "13032730128.000000000000000000", - "description": {}, - "unbonding_height": "6", - "unbonding_time": "9936-01-01T04:22:01Z", - "commission": { - "commission_rates": { - "rate": "0.022505950976301605", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.206573380377502263" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "consensus_pubkey": "cosmosvalconspub1addwnpepq055lazk86cjz6r0s6jgcj7454fm7lscn6ylxwq5stu7lxxve6c8z06lkn6", - "status": 1, - "tokens": "11306383136", - "delegator_shares": "11306383136.000000000000000000", - "description": { - "moniker": "HOVoWzOKbt", - "identity": "TRrmFJQkpB", - "website": "vrfqAOrjMr", - "security_contact": "EqTmbIKhye", - "details": "ORcULZRUGZ" - }, - "unbonding_height": "6", - "unbonding_time": "9936-01-01T04:22:01Z", - "commission": { - "commission_rates": { - "rate": "0.056078612663796658", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.153970901287451505" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt6v4va58n8u0husyys4q2qk258zswwu2m8xh8wq3te6jlg45zcjxkzwshv", - "status": 1, - "tokens": "3015113626", - "delegator_shares": "3015113626.000000000000000000", - "description": { - "moniker": "JZQBeDfYam", - "identity": "FOuxhBHERr", - "website": "ZnmsIAxQfc", - "security_contact": "BxbYtUYFOq", - "details": "OPBuXPYqua" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.098869115736485868", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.013331374901399054" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf26xhga7sa872e20kwjg5wglmv508l9ukcq43k7alqqnjsqq0wrshcyrgw", - "status": 1, - "tokens": "9845542377", - "delegator_shares": "9845542377.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.577150493662706545", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.880000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xf32mjfqeg39dq7qczchp67zznleqkvvycu823a5d689tapae7svdnv4s", - "status": 1, - "tokens": "8373562844", - "delegator_shares": "8373562844.000000000000000000", - "description": { - "moniker": "iUBnDMOhbM", - "identity": "iTSmKytwsB", - "website": "PUhHbruKjv", - "security_contact": "fetNYhEAsc", - "details": "uhcPlrOTgR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.048109597870365501", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazfcl7f9", - "status": 3, - "tokens": "27157083976", - "delegator_shares": "27157083976.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.170000000000000000", - "max_change_rate": "0.024288054259102348" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgxqjc3u3", - "status": 3, - "tokens": "45028692546", - "delegator_shares": "45028692546.000000000000000000", - "description": { - "moniker": "UeFBWJANuQ", - "identity": "gypzUiAlRd", - "website": "zZezcKCiKy", - "security_contact": "KSXTvslQOC", - "details": "qqNIBlVIYk" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.075610127679217055", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.290000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xwmrp7sq", - "status": 3, - "tokens": "35018830437", - "delegator_shares": "35018830437.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.405901469124460870" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "consensus_pubkey": "cosmosvalconspub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc92g545rl", - "status": 3, - "tokens": "17547285969", - "delegator_shares": "17547285969.000000000000000000", - "description": {}, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.073548473514397047", - "max_rate": "0.440000000000000000", - "max_change_rate": "0.413655116572301617" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wyr7x83", - "status": 3, - "tokens": "25071600389", - "delegator_shares": "25071600389.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.280000000000000000", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.063599161373317498" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymswdv67m", - "status": 3, - "tokens": "27784307296", - "delegator_shares": "27784307296.000000000000000000", - "description": { - "moniker": "mjkYspzJbE", - "identity": "xWPMeIdPEi", - "website": "xtRPXfTiQB", - "security_contact": "sdKpqtdpNe", - "details": "MnLujfMpnW" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.100000000000000000", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.072530327063185081" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgwr8xnwk6058r9yaatj26xt570h6mzfs56tnn2tkg7y3jyp356qzqaxfg5", - "status": 1, - "tokens": "1252735315", - "delegator_shares": "1252735315.000000000000000000", - "description": { - "moniker": "UfkjaibOXz", - "identity": "vVVQmleZuk", - "website": "FKRiuhRQvX", - "security_contact": "UHCcLIotsR", - "details": "pEGZETWPPx" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.156679971641128810", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.026853734634610978" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfnc9pflwwv469nrpv8nave7hqd2v4w3ycuzeqk2un0sp5rpt468yx200mn", - "status": 1, - "tokens": "5701177554", - "delegator_shares": "5701177554.000000000000000000", - "description": { - "moniker": "dkViUcHton", - "identity": "lVYfRBBpgr", - "website": "rSpBvDfDVx", - "security_contact": "ZorwmBCgci", - "details": "qfbWDZBvMb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.417793530644749589", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.038374060737037578" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xu8de8m8m8r6s3gdlzevgnuyjxqnerdhdt27a89w2euju4urw8yap7cgs", - "jailed": true, - "status": 1, - "tokens": "35282247366", - "delegator_shares": "36246439673.000000000000000000", - "description": {}, - "unbonding_height": "25", - "unbonding_time": "9936-01-02T19:37:57Z", - "commission": { - "commission_rates": { - "rate": "0.004077496600532069", - "max_rate": "0.110000000000000000", - "max_change_rate": "0.018535351790808554" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtagppnl0ywh6x75gstk6jrws2x0zq0vxz89663enl6sjgmwhphacultfnr", - "status": 1, - "tokens": "4474063302", - "delegator_shares": "4474063302.000000000000000000", - "description": { - "moniker": "SiJCcmpLbs", - "identity": "qjRTuyXVcs", - "website": "sijVVYMurZ", - "security_contact": "MOCCXUuDrR", - "details": "YXkSdbNCBu" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.056403203424930785", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.014536927316112510" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdhcupcamks7erjfhcvl7f0ec9032vygtnraq5xg6uehjy0amzwmq9fx4zk", - "status": 1, - "tokens": "9095777401", - "delegator_shares": "9095777401.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.400000000000000000", - "max_change_rate": "0.244970091744442833" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslqg7mlcx", - "status": 3, - "tokens": "31634692393", - "delegator_shares": "31634692393.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.554757466700447989", - "max_rate": "0.820000000000000000", - "max_change_rate": "0.408903182457515462" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "consensus_pubkey": "cosmosvalconspub1addwnpepqta2kryj27uenxysne52plp50tn9tnc5t8nd2geytjcht6c68yppzcdpk3m", - "status": 1, - "tokens": "11760329682", - "delegator_shares": "11760329682.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.180898114093371403" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtcpp77982hl5fhudkwv9mr6aqf3ree6t34697uvuqptnh6kj4ys5ac3qp9", - "status": 1, - "tokens": "602352708", - "delegator_shares": "602352708.000000000000000000", - "description": { - "moniker": "UNASSmlKTo", - "identity": "uhyuVrXWrq", - "website": "XlFrUaNLQq", - "security_contact": "rdHjnqyqLX", - "details": "bveclkOpHZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.044812571984808905" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdn9m93wfkj62hphl0uep7etngtrwe6mtl6gaf8f9e3a7f7g55npyzazlp7", - "status": 1, - "tokens": "4639932033", - "delegator_shares": "4639932033.000000000000000000", - "description": {}, - "unbonding_height": "13", - "unbonding_time": "9936-01-01T19:46:26Z", - "commission": { - "commission_rates": { - "rate": "0.024626991093728218", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.080004865482248970" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdwwmumvva86wmx94fr3hgtnt8gs40wxy3wt2heja430emv5lxxuvhs2a98", - "status": 1, - "tokens": "556310530", - "delegator_shares": "556310530.000000000000000000", - "description": { - "moniker": "dvrxlOManf", - "identity": "HtMpzaSHDR", - "website": "HqMSLZlkMi", - "security_contact": "CgMEsBUltB", - "details": "FBVqqAFKIJ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.068210196325086922", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.053045144913425869" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt6hn4flrkuvequxy2hhhzddud4tdm5xnwh5agjcqsa4gjec5xjy2n0m9wd", - "status": 1, - "tokens": "554885714", - "delegator_shares": "554885714.000000000000000000", - "description": { - "moniker": "TBWFksRoPx", - "identity": "iVVIAmyigu", - "website": "DTkHTlrvWr", - "security_contact": "DEYqAUJlvV", - "details": "nNnVeluJnY" - }, - "unbonding_height": "6", - "unbonding_time": "9936-01-01T04:22:01Z", - "commission": { - "commission_rates": { - "rate": "0.286897474578479181", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.330000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvlfyhyylne6t33wzse5vhjd3xxyrfkjfmdyvk3gq4rrdhe2e0ul2n637uw", - "status": 3, - "tokens": "22383796110", - "delegator_shares": "22383796110.000000000000000000", - "description": { - "moniker": "MCiuCZVGkF", - "identity": "YVlJRRVogl", - "website": "iBpLGvpPpo", - "security_contact": "bvXcaUSxzJ", - "details": "zsHdsXWXhJ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.012334216153398550" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v67hlsk", - "status": 3, - "tokens": "16236700229", - "delegator_shares": "16236700229.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.498536222135788025" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5l4jsmp", - "status": 3, - "tokens": "42937175180", - "delegator_shares": "42937175180.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.190381602916620701", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.303876600993529705" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdvv5qzxgfwadnygspjwln9c0hn663hz5p65uqf3fzscf0plz577ue0gul8", - "status": 1, - "tokens": "5288336779", - "delegator_shares": "5288336779.000000000000000000", - "description": { - "moniker": "wVQZezVdLb", - "identity": "trDgyJlGtA", - "website": "ohCubujIxo", - "security_contact": "tRTgDjAAVX", - "details": "JqjcImFcXx" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.084545351965758511" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g7drc35", - "status": 3, - "tokens": "36911230696", - "delegator_shares": "36911230696.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.194945225911581915", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.300000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcas8xka", - "status": 3, - "tokens": "39363181311", - "delegator_shares": "39363181311.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.028169322828760497", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.050000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcvjsxyz", - "status": 3, - "tokens": "27734813665", - "delegator_shares": "27734813665.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.015116864220436494", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd5nsxkua92z9eamd4hccf0pxeh3chye2475vcrwc22dpxj4lmkvuy950w7", - "status": 3, - "tokens": "27605610764", - "delegator_shares": "27605610764.000000000000000000", - "description": { - "moniker": "RLaOPuFvKx", - "identity": "LQfktbUgZN", - "website": "JiRhAUTjQG", - "security_contact": "LTGuZUEvcW", - "details": "QjLWSYAXxH" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwsa0gtfg8nxze044y6vynaz5f5z0kz4ar9tghvyr9cpacl28c76k8cfuys", - "status": 1, - "tokens": "13127630955", - "delegator_shares": "13127630955.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.087006240044684328", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.090651017996866531" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskj3a67t", - "status": 3, - "tokens": "24423311847", - "delegator_shares": "24423311847.000000000000000000", - "description": { - "moniker": "OtyVVqWsup", - "identity": "EqaejuaTwX", - "website": "egvJRLAnYF", - "security_contact": "KTzlQLiomS", - "details": "ETXsigXuTY" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.372711230134865265", - "max_rate": "0.460000000000000000", - "max_change_rate": "0.056760418592473079" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjzxhelr", - "status": 3, - "tokens": "25592800910", - "delegator_shares": "25592800910.000000000000000000", - "description": { - "moniker": "NYvAvaIOdj", - "identity": "lYbVDursvX", - "website": "UXtFzZcHjM", - "security_contact": "PNNMeOJqcl", - "details": "ROVIgdvaJl" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.193312772989594496", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.226297820963910157" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvvur4tyyl553c4jeyvce0w3d0ezrrmsr6a2kcdksca4wpflc3lj7nf6fm9", - "status": 3, - "tokens": "25675698411", - "delegator_shares": "25675698411.000000000000000000", - "description": { - "moniker": "wDAGDTplVL", - "identity": "VUJoHvcuZs", - "website": "JzvbSfINxu", - "security_contact": "cROcYcTImn", - "details": "bdBDwVnOvM" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.108086670177688287", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.123495090782214164" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsuh3jpet", - "status": 3, - "tokens": "50488222690", - "delegator_shares": "50488222690.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.801397182624616334", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.592521503076154232" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00kz7uf8anh6gpaq5gucxz5u5jxfk75w73c0f4hx3mrevz6wxe5xtvq7c7", - "status": 1, - "tokens": "12112810368", - "delegator_shares": "12112810368.000000000000000000", - "description": { - "moniker": "hhrNeMimUt", - "identity": "wKniwVmzBB", - "website": "RWhKssqoAD", - "security_contact": "HhssEHikTn", - "details": "GKXcfnFtEp" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.073730825899332452", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.038867571778125676" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfk090csv4thlsr4kx3fuucwcsk79lqs6gr5zse6m4xmwpq94hy2w3yuqp6", - "status": 3, - "tokens": "20659893696", - "delegator_shares": "20659893696.000000000000000000", - "description": { - "moniker": "gqjwubbLDT", - "identity": "OsKsdzWbsv", - "website": "rhWGeqAAVi", - "security_contact": "FmaEvvcaAr", - "details": "uMULjHPlYr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.168812875456833709" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5t7pxck", - "status": 3, - "tokens": "53644768786", - "delegator_shares": "53644768786.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.180000000000000000", - "max_change_rate": "0.029528662482337368" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2z47zet", - "status": 3, - "tokens": "21168715051", - "delegator_shares": "21168715051.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.026318239077074162", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.076792434560738120" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0xgzvwtkwtmwqv3l4d4jf3je2qvw5u2s8fcduejf33r8lykwlrzyp5q9fz", - "status": 1, - "tokens": "1370590721", - "delegator_shares": "1370590721.000000000000000000", - "description": { - "moniker": "YxkFqQLCVj", - "identity": "svwKmwRNzU", - "website": "HUYRlreMTk", - "security_contact": "yooYsHUCBp", - "details": "gOGDDEidDB" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.545893826392769667", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.592139558969935420" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyw0np92", - "status": 3, - "tokens": "27374742411", - "delegator_shares": "27374742411.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.053895535796610462", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.182737583024108345" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0hcte6yrzm8ppqms3l3vw92tc8cqqdacl8wkavpcjshum9a0rty23cs5d8", - "status": 1, - "tokens": "418488641", - "delegator_shares": "418488641.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.860000000000000000", - "max_change_rate": "0.273402402333309888" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq242jjldxy02w8e4d8mgh6tx6k9rdhy0rgn56wac2ng7gvjsc8yn7zw7qry", - "status": 1, - "tokens": "2878820932", - "delegator_shares": "2878820932.000000000000000000", - "description": { - "moniker": "FajtVQhfyD", - "identity": "LJBphWhRiy", - "website": "KonhZigFqm", - "security_contact": "kMzJQasgzg", - "details": "BksWuXHzKo" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.143184564002944268", - "max_rate": "0.820000000000000000", - "max_change_rate": "0.610269825406512777" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2al69u7pnek9kcrmz83vstrst5szxuz6z03z0d848kuh3ekkjlfgr96q6z", - "status": 3, - "tokens": "20929858941", - "delegator_shares": "20929858941.000000000000000000", - "description": { - "moniker": "ciowxbJZpb", - "identity": "XgDAZmwEir", - "website": "moPXkGzyqT", - "security_contact": "WTLysotltH", - "details": "qoTHCiKGoL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003240694138410597", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.013650990946439583" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtq4rjflca8vgyn08w3vkpqeq57d80dmja25rd0ntqrx5fxm96gtw0umkjg", - "status": 2, - "tokens": "4345178144", - "delegator_shares": "4345178144.000000000000000000", - "description": {}, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.639608494106780282", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.911798500947612916" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "consensus_pubkey": "cosmosvalconspub1addwnpepqttlhe35hucrdjdhcyrnnv3kggwjw8lzmhfv7hz0vc6zvmez729rjwfq94s", - "status": 1, - "tokens": "14505496415", - "delegator_shares": "14505496415.000000000000000000", - "description": { - "moniker": "hwGSrtUOYW", - "identity": "VSuEnzJoTP", - "website": "SKivYdHQYd", - "security_contact": "nQkFUJMUsq", - "details": "BPIGoQzJZW" - }, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.314247563815691088", - "max_rate": "0.430000000000000000", - "max_change_rate": "0.414706550102643413" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwz7uypw37mz5eky5vktatrwu84geyy9r8jp9dccd73kw62x5hkn54qgedr", - "status": 3, - "tokens": "15286357237", - "delegator_shares": "15286357237.000000000000000000", - "description": { - "moniker": "rXurTMjZPL", - "identity": "AwsdgVtWKY", - "website": "MqIvWlvqZq", - "security_contact": "hoJFiVyrtB", - "details": "FWXLLEocRp" - }, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.298667840621478601", - "max_rate": "0.620000000000000000", - "max_change_rate": "0.023377726384901617" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "consensus_pubkey": "cosmosvalconspub1addwnpepqddlzcmsy4vds97qxa5a5xs4mvgeyp9zhmm7fqfdr888nhp0sftrjk0thpa", - "status": 1, - "tokens": "4986207023", - "delegator_shares": "4986207023.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.079386028745799977", - "max_rate": "0.180000000000000000", - "max_change_rate": "0.113889826113494810" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzvca96h", - "status": 3, - "tokens": "70162120947", - "delegator_shares": "70162120947.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.545864029263808659", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.533310660658318421" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2vpcxra7jn5ph969c4cnj2qngyr09hzyssh4m2rvwkneqt2x00t78j79g7", - "status": 1, - "tokens": "6943791722", - "delegator_shares": "6943791722.000000000000000000", - "description": { - "moniker": "iHZLPGVqoj", - "identity": "PTMFoKCCDe", - "website": "cqKrWoBVHG", - "security_contact": "ZdbkzGqONL", - "details": "hyVBYChgSt" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.730000000000000000", - "max_change_rate": "0.113078578358113548" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqlk7nha", - "status": 3, - "tokens": "20279593182", - "delegator_shares": "20279593182.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.069908236020668720", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.009891358364124589" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgm73g3mrpuk5y0aykvt6zmtpassp8qwu5r4hxrlw8umkqdw6wk5knmfc95", - "status": 1, - "tokens": "6203555675", - "delegator_shares": "6203555675.000000000000000000", - "description": { - "moniker": "SRtaYtDodq", - "identity": "EXTHehjjeA", - "website": "XNnGTPSCSg", - "security_contact": "DDCUFBlRis", - "details": "tFjYKNDXoU" - }, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.094086925383675139", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.386267985496281026" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdlvalhvj0k0kqflaruuvyxjndwjaepha9wm0mphnauaf4tpjy0rzt5nu3n", - "status": 1, - "tokens": "9559456877", - "delegator_shares": "9559456877.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.157603606207056866", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.184901704338581434" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2wk8eudh28aeukdvn2w25d0ywdsrzyvp59xs869e9h9vdu4lw9c5zzw53t", - "status": 1, - "tokens": "13387012198", - "delegator_shares": "13387012198.000000000000000000", - "description": { - "moniker": "bhiZzQubAq", - "identity": "sDcgOtqEmT", - "website": "XCWWoDyVlS", - "security_contact": "esVFcCqRSm", - "details": "gOhHAReWMI" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.450000000000000000", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.179817022007454543" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0y2whh2mx9stzswaxevw5ku8aznuvf0dgaznc4z8wz6fc4ahy35cgvq7km", - "status": 1, - "tokens": "11031151085", - "delegator_shares": "11031151085.000000000000000000", - "description": { - "moniker": "OnUJlqhYgs", - "identity": "QxZSMomSDp", - "website": "SSAuEgkyZs", - "security_contact": "yZapBDsgPP", - "details": "lKjpewmQsy" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.421539780269441578", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.298023294439709308" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqva0a8amjektwyshzjv38f6dw5uwat88kscw834kf3026r5ksn77gf0857j", - "status": 3, - "tokens": "31584297936", - "delegator_shares": "31584297936.000000000000000000", - "description": { - "moniker": "BKQyTeKaLC", - "identity": "eCoPebxrNV", - "website": "auQgzJBeZR", - "security_contact": "bLlknxqKWU", - "details": "amiXFmUGDr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.900000000000000000", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.031968764827487641" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4cv2x09p", - "status": 3, - "tokens": "22768989048", - "delegator_shares": "22768989048.000000000000000000", - "description": { - "moniker": "EVTkHBKcpE", - "identity": "hMErYohFOn", - "website": "QaWaMRxOKv", - "security_contact": "qaxyuRDTeX", - "details": "ELwgPpPDKw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.386471695225710439" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfjcp62cfnelz8s5cl5qar8ymfjd5sjjkkr4tayrqrtzpf638hkjqmg9q4z", - "status": 3, - "tokens": "26491705865", - "delegator_shares": "26491705865.000000000000000000", - "description": { - "moniker": "SJeSnSdrXp", - "identity": "OTlQTOJbcV", - "website": "sulWDbaxDh", - "security_contact": "XTGtIDYHdJ", - "details": "KNeohKLilE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.965860683215034339", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.778196912581936923" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfjswqwlt6yc0lrcmyae0pqya6ymquatdrg9uufx94m6p3fwxqz9x86858h", - "status": 1, - "tokens": "3691290116", - "delegator_shares": "3691290116.000000000000000000", - "description": { - "moniker": "iDjKsiEeDb", - "identity": "XDKHVzYbNp", - "website": "tknKYmQsoF", - "security_contact": "LFqBNfJYwo", - "details": "SrLmeyDcge" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.016082191317166724", - "max_rate": "0.400000000000000000", - "max_change_rate": "0.400000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvvxtcls2a9qfjq04usrzv3ekvavu52z7twu9w3fguenpjett5zpwf62rq6", - "status": 1, - "tokens": "243264064", - "delegator_shares": "243264064.000000000000000000", - "description": { - "moniker": "OwEuBzkAXt", - "identity": "sKregrkhvp", - "website": "QFkaaTPgBS", - "security_contact": "LWqWzpgBBK", - "details": "IiZKuDsnyX" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.871101859572202690", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.754875918298597546" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "consensus_pubkey": "cosmosvalconspub1addwnpepq28myc67l0yhmnn6n2vq8hcmpaxesglyyqg825ujgrxdt9afwlsfx4ezupt", - "status": 3, - "tokens": "16257375002", - "delegator_shares": "16257375002.000000000000000000", - "description": { - "moniker": "mtHVFaNGLx", - "identity": "YTyhLHiifY", - "website": "JFeCDRXGYc", - "security_contact": "HndWqVmQvE", - "details": "JFVkeOUSbg" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.018292046092814578", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.057525240491425891" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfjk3l28hkcd6jl265j6aypx77uqhm4hjwq6j75klu4apy6gl6ze74v7crf", - "status": 1, - "tokens": "9606051750", - "delegator_shares": "9606051750.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.792362515287976876", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.568773929640711892" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgzjwcddk2z8kmnvgh2yyftgqknzry0cp2f9g7tlprezsj3p8yupxjptgj3", - "status": 1, - "tokens": "3200537612", - "delegator_shares": "3200537612.000000000000000000", - "description": { - "moniker": "YxQFCVeXka", - "identity": "uyuvPGTQiI", - "website": "fBprqrDUjJ", - "security_contact": "mqBJzLfJmq", - "details": "GiBjnTfluH" - }, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.103237315548430953", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.117703304223005248" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z6ckp5s", - "status": 3, - "tokens": "62801915451", - "delegator_shares": "62801915451.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.323440196337864016" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf2lh963ms2dlnvtq586ccq3spt7deacf46yf9r3h4ze7sdtpqn42uaajd3", - "status": 1, - "tokens": "365167856", - "delegator_shares": "365167856.000000000000000000", - "description": { - "moniker": "YKpfxbRPDU", - "identity": "HVMtZxINmC", - "website": "MPNkKSEpFt", - "security_contact": "PAebSVjNmN", - "details": "vnIHnmwiHU" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.090000000000000000", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.081458810641796929" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng9t438v", - "status": 3, - "tokens": "22515450726", - "delegator_shares": "22515450726.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.752425052602923482" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6mcm2m0", - "status": 3, - "tokens": "29556680915", - "delegator_shares": "29556680915.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289048467390880739", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.476925303769745140" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswzcmkck", - "status": 3, - "tokens": "25121635132", - "delegator_shares": "25121635132.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.541820589241677763" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "consensus_pubkey": "cosmosvalconspub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z2xdtk5", - "status": 2, - "tokens": "6699765497", - "delegator_shares": "6699765497.000000000000000000", - "description": {}, - "unbonding_height": "50", - "unbonding_time": "9936-01-04T22:14:51Z", - "commission": { - "commission_rates": { - "rate": "0.493962290871886167", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.601549819261141285" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt5fpnmky0a402kgyu04yww96a839ydaxaakw75da6xq6n2d8evcuu06j8t", - "status": 1, - "tokens": "7029801264", - "delegator_shares": "7029801264.000000000000000000", - "description": { - "moniker": "dEbLKTkCfp", - "identity": "chpFnPbjeE", - "website": "hIVhzrwvGR", - "security_contact": "tdkZcmEEtp", - "details": "qIYHtPoIsA" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.170000000000000000", - "max_change_rate": "0.165881689721229366" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vype2jq", - "status": 3, - "tokens": "59694062218", - "delegator_shares": "59694062218.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.047504130944412074", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.160000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgh9l47dn4d09k6xlkwun4uyk07x6979ca2rm6jnuzdredu0m83t25sptkv", - "status": 1, - "tokens": "3092598821", - "delegator_shares": "3092598821.000000000000000000", - "description": { - "moniker": "utphwLfvOM", - "identity": "qzMWKFjmzr", - "website": "sEXBMEaMuK", - "security_contact": "lyindsAreq", - "details": "CTVKoYhpCk" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.061272647435103109", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.141473987309465922" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfzsv864d6pzxm7jr4fnjd0u74phhasnmhne8tp9xk2nwu9j0m7rz67sj3x", - "status": 1, - "tokens": "9239149167", - "delegator_shares": "9239149167.000000000000000000", - "description": { - "moniker": "jPkbzNeKzp", - "identity": "erBtVEeJYZ", - "website": "zDKyjhGPYG", - "security_contact": "tjKPWUglNK", - "details": "lZmMacILat" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.707848956225291609", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xzg536q0eksvxd2297ycyctfwp6x7rk0wq6d0murld346cjs756v0jnxn", - "status": 3, - "tokens": "16949426508", - "delegator_shares": "16949426508.000000000000000000", - "description": { - "moniker": "dNCvXIwisF", - "identity": "PInuRSnoAB", - "website": "IFaDEJuVii", - "security_contact": "DiiitKvkqG", - "details": "wJQyZMjCjC" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083382298074645848", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.156261937510636548" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdazuvwg72zd5mg4lf9mf9eyj7flqcmsw4a03283v0wssdljlj607nt5t8a", - "status": 1, - "tokens": "737084249", - "delegator_shares": "737084249.000000000000000000", - "description": { - "moniker": "FqHViPFdlJ", - "identity": "OmtumbAbsr", - "website": "TYIjFsBXuf", - "security_contact": "jHXPvdANan", - "details": "KiSkcCxjCM" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.123777698447001958", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.320000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "consensus_pubkey": "cosmosvalconspub1addwnpepqflsm7achydcfh2ajnk9d3r4p2ckuphgyw9chrquhyy4xhcct8jc7k5crnk", - "status": 1, - "tokens": "4779018760", - "delegator_shares": "4779018760.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.940000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.882744308468810133" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag73jg46g", - "status": 3, - "tokens": "20324460034", - "delegator_shares": "20324460034.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.742458631966852296", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.368222450098111604" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4d6e962zqejqu3jeypzp740n4k62xte2qnj82q03y28v6wkshycxxdg5w", - "status": 3, - "tokens": "18158211957", - "delegator_shares": "18158211957.000000000000000000", - "description": { - "moniker": "cVYtBkXobK", - "identity": "JOBpTikHPq", - "website": "NyobvRjfBj", - "security_contact": "bKDbHWcmSW", - "details": "xGfkOaAoAb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.340000000000000000", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.117974822314921419" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfs8twrdeftqq3tvq55hq9mxn0duh577l043csvdjhxefl97p3aqq5twjky", - "status": 1, - "tokens": "1728294636", - "delegator_shares": "1728294636.000000000000000000", - "description": { - "moniker": "vdeqSRlmdC", - "identity": "RJhuQmpOMf", - "website": "FRiTavUiHV", - "security_contact": "IoSpxQxqyn", - "details": "KZWhrYllDo" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.107589425669711273", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.048738032041521337" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvkllp9u9v05plyvdmyftgwv96a87j477397tyyrkj50cnaanygrs4ywpus", - "status": 1, - "tokens": "14093282045", - "delegator_shares": "14093282045.000000000000000000", - "description": { - "moniker": "CbenRGMsSc", - "identity": "NjagrmFnYy", - "website": "kpWgwmblKq", - "security_contact": "YvdavQCxws", - "details": "QpvAiaCxgW" - }, - "unbonding_height": "14", - "unbonding_time": "9936-01-01T21:44:15Z", - "commission": { - "commission_rates": { - "rate": "0.043836624388488787", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4cv0e5r0", - "status": 3, - "tokens": "25435646393", - "delegator_shares": "25435646393.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.004320117912957935", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.000447271047532656" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfagcadsa5s2venkcepjtj08rdnnk87phdzlwsl4g9avkkulyx6vzfm5q2y", - "status": 1, - "tokens": "5226912532", - "delegator_shares": "5226912532.000000000000000000", - "description": { - "moniker": "YyfYUVdJyQ", - "identity": "hCVxCQqvPu", - "website": "eHCeufoTrA", - "security_contact": "UyKPzWUXUY", - "details": "XBpFWJEbMv" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.440000000000000000", - "max_rate": "0.440000000000000000", - "max_change_rate": "0.440000000000000000" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvz55wnnaw48qrudyvxm2np0px6xma93kxc0zh8va6xf9ekz7k8ns5palg4", - "status": 1, - "tokens": "10613605390", - "delegator_shares": "10613605390.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.053550077457235518", - "max_rate": "0.190000000000000000", - "max_change_rate": "0.066233442015105736" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwfwqlzf", - "status": 3, - "tokens": "16773399211", - "delegator_shares": "16773399211.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.926805735750034881", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.482844926743337660" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qavly08", - "status": 3, - "tokens": "17705677177", - "delegator_shares": "17705677177.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.615745867723667485", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.398263247650399274" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2eqqj9ng5ru9z7ld9qq6kfljzu5v0rph9gh0gf5zyx4jtc0at3cg44et85", - "status": 1, - "tokens": "13871091494", - "delegator_shares": "13871091494.000000000000000000", - "description": { - "moniker": "zwREkFhOtU", - "identity": "urVIzuITjH", - "website": "LGtPidunhZ", - "security_contact": "hjJvkZYcLY", - "details": "ukIYWLVzYw" - }, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.220000000000000000", - "max_rate": "0.220000000000000000", - "max_change_rate": "0.000727370561970112" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwv80xev", - "status": 3, - "tokens": "26461821776", - "delegator_shares": "26461821776.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.157167562506066789", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.091234306987583436" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf558mk5ff9u9tx0nq76pfgenl6lzddnddywjsy9m5dq6hz9peqj6l3a97z", - "status": 1, - "tokens": "49835911", - "delegator_shares": "49835911.000000000000000000", - "description": { - "moniker": "BGFXyvCoEW", - "identity": "VvrkTmUKcV", - "website": "KAoHgkjVOT", - "security_contact": "WtgEPWzdKE", - "details": "dEDbuRxuQN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.078573260130098190", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.056452518463295050" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwudpuh36geydlpx0yjqu0vhauacf294sn2uetg4ush97p382kqag6sxlqg", - "status": 3, - "tokens": "17862559018", - "delegator_shares": "17862559018.000000000000000000", - "description": { - "moniker": "wSgJTwBWiv", - "identity": "AEATmOIHsP", - "website": "WsuxwwJUIx", - "security_contact": "nzWdiJbKcf", - "details": "WXwvQKoIbT" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.120000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.027292850423387945" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq4e58fv", - "status": 3, - "tokens": "112536605413", - "delegator_shares": "112536605413.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.592057337572123856", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.208226705977271974" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtc9vugqcyl9agyk5jfajuhq55zgvrxnn3cjw375k6zdn3cw3pf076rlcay", - "status": 1, - "tokens": "1291312379", - "delegator_shares": "1291312379.000000000000000000", - "description": {}, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.488750140640932143", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.750000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtdldypck872t677fwgapgk44dy7hhw2ghufuda3qtfzqcd8a5095swr5e0", - "status": 1, - "tokens": "6651914410", - "delegator_shares": "6651914410.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.228317860347116037" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7kquya74", - "status": 3, - "tokens": "27525740131", - "delegator_shares": "27525740131.000000000000000000", - "description": { - "moniker": "ajDNnhnkbN", - "identity": "nkdfsqWVlx", - "website": "CeqAfYeTdW", - "security_contact": "KMQJbxKkbm", - "details": "cvAUuqNFYs" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.780000000000000000", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.550890306122411684" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj4x3m9h", - "status": 3, - "tokens": "57637848348", - "delegator_shares": "57637848348.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.081821299211443922", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.458576374327765136" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey2vtdvu", - "status": 3, - "tokens": "19834101875", - "delegator_shares": "19834101875.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.491522368582129610", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.085253529277298261" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0aa00frx8hxrq5pegc0vnt69pj54z3dhwzy8uumr3nhgsc772h0zyr473p", - "status": 3, - "tokens": "37175356106", - "delegator_shares": "37175356106.000000000000000000", - "description": { - "moniker": "oedtWfExZY", - "identity": "taFwTdIwwz", - "website": "oGBHKapVuy", - "security_contact": "hnggEiQcYu", - "details": "qOFIRfzDGP" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083784124252551147", - "max_rate": "0.650000000000000000", - "max_change_rate": "0.550897578676987786" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dsktaxw5", - "status": 3, - "tokens": "55634424696", - "delegator_shares": "55634424696.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.016380613584719475", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.310000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "consensus_pubkey": "cosmosvalconspub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz28vhtm", - "status": 3, - "tokens": "20453193314", - "delegator_shares": "20453193314.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.528106308050967540" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwl3dc4f3s37x82us00qtvs4rtp9t9fvlq3dwgg8wm66hn5ad48jgrxfzcm", - "status": 1, - "tokens": "7094282971", - "delegator_shares": "7094282971.000000000000000000", - "description": { - "moniker": "BDMPqkGylI", - "identity": "YZeHOBMOSc", - "website": "ijOJTZOWdR", - "security_contact": "HYUFFZbwZd", - "details": "eLXzaDckFP" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.055222173408204209", - "max_rate": "0.470000000000000000", - "max_change_rate": "0.191599852279914708" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfxc6u7t75qnm04w78j2ngxr4mpnuqy4f3em3l6mv72kg8ezx4hyyyt9zsk", - "status": 1, - "tokens": "8866716444", - "delegator_shares": "8866716444.000000000000000000", - "description": { - "moniker": "OWlnHGHUpY", - "identity": "rmQGrnevgD", - "website": "SGrzgzpoec", - "security_contact": "SJdamcNZZs", - "details": "MePgsBCfzM" - }, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.140284784345641401", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.310000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqehts4m", - "status": 3, - "tokens": "52558464763", - "delegator_shares": "52558464763.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.128525196978986815", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.100900376719373255" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvlz0fenag3kgjcp0c0qrwyjhrxfxg9ers6mfje4lha7c3hk2qdg6390aav", - "status": 1, - "tokens": "1553435623", - "delegator_shares": "1553435623.000000000000000000", - "description": { - "moniker": "HQTgvYtjWl", - "identity": "cYFFbSdarv", - "website": "DbiOnmrlJt", - "security_contact": "cVrVZLMeQg", - "details": "EaHRYqDHRQ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.143789047273143544", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-04T17:25:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg2887df2cynsehyycldy24y3a4sps3m4w8gmrdfuvw4h9hrc7555u0ayx8", - "jailed": true, - "status": 1, - "tokens": "53335673636", - "delegator_shares": "54642935725.614311989673425860", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.352515542688907487", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.467917537027666540" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru72w0xm", - "status": 3, - "tokens": "18560827275", - "delegator_shares": "18560827275.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.100218404029226728", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.881639682871578638" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00qxpqlwy0p6y9tl23yu7fpu55lhznxa3hrhvsuma6h7lu4c3ekks4wvua", - "status": 3, - "tokens": "22083357722", - "delegator_shares": "22083357722.000000000000000000", - "description": { - "moniker": "LvOuePvVwo", - "identity": "vfegdQlOfT", - "website": "mYvkvMZuDp", - "security_contact": "cfrddDLOlu", - "details": "yHfcxdGyEO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.122593865256918850", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.840000000000000000" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0jekleayf4jvluq0msvqk39kr0s56jg7ch9f4wha3ulmytlpdevsjn72ds", - "status": 1, - "tokens": "1606367134", - "delegator_shares": "1606367134.000000000000000000", - "description": { - "moniker": "MeHdGIwstT", - "identity": "vXbyaoskcs", - "website": "OzuExUMBbW", - "security_contact": "tMoyazzZVW", - "details": "LGmmOunpte" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.874403312310992256", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.936087260014625670" - }, - "update_time": "9936-01-04T15:40:16Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf7z3nz93p6vnus3rsrscqzulxfh5mmx9jc58ys3twdy03l6uepgvakxn52", - "status": 1, - "tokens": "229341851", - "delegator_shares": "229341851.000000000000000000", - "description": { - "moniker": "RNKvcMDBzf", - "identity": "lrNSYDoJzB", - "website": "VjPGQRHRQq", - "security_contact": "uzPAtOuNWp", - "details": "gJbKFrdDPQ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.076730552322816319", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0dp72r2p4adzlsmg95kzs69rdhltghkjvuvmfsac3cdpunr9ctvy2zq9yg", - "status": 1, - "tokens": "5555958746", - "delegator_shares": "5555958746.000000000000000000", - "description": { - "moniker": "SqEyicjIAc", - "identity": "aOctrNrGLp", - "website": "bVeEjmPByN", - "security_contact": "jXOLammCjB", - "details": "HaDjtZfUfP" - }, - "unbonding_height": "14", - "unbonding_time": "9936-01-01T21:44:15Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.510000000000000000", - "max_change_rate": "0.360337629143018233" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxkm9kvvp", - "status": 3, - "tokens": "26763354026", - "delegator_shares": "26763354026.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.027810962515737967", - "max_rate": "0.070000000000000000", - "max_change_rate": "0.034717076557320762" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdpwvxyz0d0thr5hw72lswav4tdfuwkgfqjdjkaws99y4dw5fzncg487kz6", - "status": 3, - "tokens": "25943967606", - "delegator_shares": "25943967606.000000000000000000", - "description": { - "moniker": "anqFIENyYy", - "identity": "LYtCTmovif", - "website": "nDcnuLjZla", - "security_contact": "KhBXWuJORy", - "details": "rcnhuNfFoO" - }, - "unbonding_height": "13", - "unbonding_time": "9936-01-01T19:46:26Z", - "commission": { - "commission_rates": { - "rate": "0.489033782311246085", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.501117175906227815" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtndwvyp0hczl37xh8z2kg32d5jfzkagkdh5mhnfrcemedgavsdauaq9f3f", - "status": 1, - "tokens": "1522777910", - "delegator_shares": "1522777910.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.302268801754965153", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.840000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf3e3e79cz6a8a5ej2sup5a6gr8qjke6y4munem0amzs953pdee6qxllsac", - "status": 1, - "tokens": "48593531", - "delegator_shares": "48593531.000000000000000000", - "description": { - "moniker": "oIkfhnnCKQ", - "identity": "hySDCwZlgb", - "website": "kjGmgoCrNu", - "security_contact": "BcNBxMUwqo", - "details": "TFFDhrPOgE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.046915001210206184", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.036123891352914057" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2y3kj4vhmzue7mqncfd7q98j62a3kcey0mz6faen6sqxeew447lgw2qkre", - "status": 1, - "tokens": "955350854", - "delegator_shares": "955350854.000000000000000000", - "description": { - "moniker": "YoMvXMlPFr", - "identity": "fKGDzIPdra", - "website": "WcCOYuDfvu", - "security_contact": "oZtZtVTHGJ", - "details": "dxGGPZKbDq" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.047292284703768560" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw56zut28tr20sgkqnxxfluz86txzvqx8mrdza94waquh4mglfdl7czkz2u", - "status": 1, - "tokens": "9700319292", - "delegator_shares": "9700319292.000000000000000000", - "description": { - "moniker": "yAtLARqWcT", - "identity": "GDPDnMkbff", - "website": "tcZjjwPSNj", - "security_contact": "FbGNeFZGHW", - "details": "KqYHHRfDeX" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.348806113417240140", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.276441300614760272" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf4eys884495jxdra6k9jqdps582ftj6cp8mjyxws7w6nrxxlhpp7fcwqzj", - "status": 1, - "tokens": "27773889", - "delegator_shares": "27773889.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.105457511098684791", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.235913526142460185" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2cxwldfa72uhy5ecsg7fafzcxujufn8x5585eteclkeu25javyukdtnqfz", - "status": 1, - "tokens": "1633256118", - "delegator_shares": "1633256118.000000000000000000", - "description": { - "moniker": "tgJFunajUY", - "identity": "nLyQJKzFZO", - "website": "qyTiXVjbIh", - "security_contact": "twIziknpbV", - "details": "OoBFXHtHzA" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.099379666682843872", - "max_rate": "0.170000000000000000", - "max_change_rate": "0.051317357664035652" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0sra5mkmllmenj9ymu00ky4wcpwtanyldal7xt3chkm6ksnnhvvjjhfyqq", - "status": 1, - "tokens": "11431729142", - "delegator_shares": "11431729142.000000000000000000", - "description": {}, - "unbonding_height": "10", - "unbonding_time": "9936-01-01T12:58:59Z", - "commission": { - "commission_rates": { - "rate": "0.528428582888525350", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.202815943946770447" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvykaseh7", - "status": 3, - "tokens": "68955304480", - "delegator_shares": "68955304480.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.208925360976246176", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.463634503057540350" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peggwy7x5", - "status": 3, - "tokens": "49844884060", - "delegator_shares": "49844884060.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.338644152469426553", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.069153802725768656" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd76980jyxlezsdfpr4nwaahyuge8958rjpwz7lp7f0shjj445vkq4cla9q", - "status": 1, - "tokens": "958870106", - "delegator_shares": "958870106.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.510000000000000000", - "max_rate": "0.510000000000000000", - "max_change_rate": "0.006589567430698109" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxz2ead4", - "status": 3, - "tokens": "19233426986", - "delegator_shares": "19233426986.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.373154376676147691", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", - "consensus_pubkey": "cosmosvalconspub1addwnpepq07n4j54rccdt2k4p5gw5j0a40ud5wzhlgfwt2fmquptar94tqxksvg7fe9", - "status": 1, - "tokens": "1392995609", - "delegator_shares": "1392995609.000000000000000000", - "description": { - "moniker": "qYrASvEVes", - "identity": "PeqxXaMUrE", - "website": "qiYJuCguZn", - "security_contact": "xuvwbBFfdf", - "details": "vdqxCkfWKd" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.121049931542544207", - "max_rate": "0.170000000000000000", - "max_change_rate": "0.098866031971138939" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wjfqd63", - "status": 3, - "tokens": "25961659072", - "delegator_shares": "25961659072.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.068613373696134985", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.073351676068018235" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgt5lvqw32z2z8wtgskc0gs6wl42agj8p8sjl4rnpkrmrqyy9cagcrpvyjp", - "status": 1, - "tokens": "7062397405", - "delegator_shares": "7062397405.000000000000000000", - "description": { - "moniker": "GiBweZaDWF", - "identity": "pAvSRbpgPx", - "website": "XNrEheNOEd", - "security_contact": "UbuEjmdWgS", - "details": "FanbXQxXQm" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.620000000000000000", - "max_change_rate": "0.352646700715971314" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgtqlt7ucs3nxwwc47qmc03sehv59ttyqhsd537upgtc20ylarm3uauexuv", - "status": 1, - "tokens": "8414643937", - "delegator_shares": "8414643937.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.170000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7ul2hc3", - "status": 3, - "tokens": "33320443806", - "delegator_shares": "33320443806.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118849597906926326", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.228258187539755185" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdmawr65c6guf9rqt4gu9h9ae9a5373t05j2729yyadvd6g5gx5vz9l87k3", - "status": 1, - "tokens": "3480758674", - "delegator_shares": "3480758674.000000000000000000", - "description": { - "moniker": "kwNZPonhYK", - "identity": "hcoDZCuApk", - "website": "TuCKHHpAwY", - "security_contact": "jRHuItJhLi", - "details": "GGHzTJNlEy" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.148257634745595705", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.399887740084543680" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf0wrcap4980h90m65rv3pqwfal4gyy0qt8us030hjxhla2t65jlq96qnz9", - "status": 1, - "tokens": "6944508564", - "delegator_shares": "6944508564.000000000000000000", - "description": { - "moniker": "HQDbMGplPN", - "identity": "pWpzVmWzUQ", - "website": "sBzoUhMVHM", - "security_contact": "GydhSLjldN", - "details": "BWUgqqivmG" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.098439244985309212", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.051461905989545502" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7whvstg", - "status": 3, - "tokens": "59094460259", - "delegator_shares": "59094460259.000000000000000000", - "description": { - "moniker": "cVUXvMdRgs", - "identity": "AHkjmtOkYK", - "website": "KLRPQOyDoY", - "security_contact": "VHwCrfhVnI", - "details": "qdFVvUucvR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.182731553781057822", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.045316794895420248" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwfv0ttln5pqqhkd86m4ujg4r5ape67apt7pfy543n5jg4545waejjpjyt2", - "status": 1, - "tokens": "2681012667", - "delegator_shares": "2681012667.000000000000000000", - "description": { - "moniker": "HFKvirJpBS", - "identity": "qSdijBrgVf", - "website": "AGKPlyJSSq", - "security_contact": "eUTFpfQxFv", - "details": "tLNbfLCQNa" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.036479308923198930", - "max_rate": "0.130000000000000000", - "max_change_rate": "0.113367352262987001" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0kzzpw5g9xn2d6zd2tnarw362fwfvt0evc9gq55lru2xfnw5sum2vv9ulp", - "status": 1, - "tokens": "1263913954", - "delegator_shares": "1263913954.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.097225319727828555", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.157186170206747238" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqde6g57cex9ff650ku6dqdqtfulfnzkacecf6k436xl0dd07zglxx5659h9", - "status": 3, - "tokens": "27718687960", - "delegator_shares": "27718687960.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.905848795661145449", - "max_rate": "0.950000000000000000", - "max_change_rate": "0.476775855507110704" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy7220f9ul3", - "status": 3, - "tokens": "33772482275", - "delegator_shares": "33772482275.000000000000000000", - "description": { - "moniker": "znFMdpLOQw", - "identity": "LEMEnpcxqp", - "website": "TjKmeKjDGm", - "security_contact": "ZOXcBhlDyq", - "details": "WpmmnksSqL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.834910862331446014", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd8ua2f60nuxkgxqguncxzce8vmhdkmxgfcvz323jg9dq73w9gkhvuutwre", - "status": 1, - "tokens": "1975544514", - "delegator_shares": "1975544514.000000000000000000", - "description": { - "moniker": "cJpZJmIecS", - "identity": "KXRKIXLrFa", - "website": "SlrEhmneXz", - "security_contact": "ZEnBrimzTo", - "details": "kYRYkqgakC" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.219853214498709174", - "max_rate": "0.400000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfpdjftwx72whdulutuklct6hpx27tvkf9s475j2jhj0ph8aslkuquduar7", - "status": 1, - "tokens": "1089374285", - "delegator_shares": "1089374285.000000000000000000", - "description": { - "moniker": "AzHxevMaNK", - "identity": "gOOENeIGtQ", - "website": "CdLRpNhPkM", - "security_contact": "SmQaWqWjbJ", - "details": "CTEennTitZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.300000000000000000", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.069984531685936838" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cuyxrn7n", - "status": 3, - "tokens": "24587685968", - "delegator_shares": "24587685968.000000000000000000", - "description": { - "moniker": "tlYEYvdvKp", - "identity": "fQFtYLRSZA", - "website": "ecuAofwdaj", - "security_contact": "gwsuBeDyJU", - "details": "gELFJGuwPs" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.499259642246008210", - "max_rate": "0.560000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jet5tg3", - "status": 3, - "tokens": "62232444428", - "delegator_shares": "62232444428.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.153116543667039838", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.230000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yfudg7m", - "status": 3, - "tokens": "25948607110", - "delegator_shares": "25948607110.000000000000000000", - "description": { - "moniker": "IssGiFwTJv", - "identity": "VgTaqmOLtN", - "website": "BpkICmEqwF", - "security_contact": "qmrIWxiWft", - "details": "sLtbcsMFgA" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.136694009459855954", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.056116480834729575" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4c8wkdlg", - "status": 3, - "tokens": "18426946099", - "delegator_shares": "18426946099.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.469814499540087620", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.960000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvquc4jf3", - "status": 3, - "tokens": "16774945156", - "delegator_shares": "16774945156.000000000000000000", - "description": { - "moniker": "hZvyDgtWxX", - "identity": "TPMmELNQYL", - "website": "YxTdbJnobM", - "security_contact": "ZURHxVMZoL", - "details": "zVjWraUVyE" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.258972799025106506", - "max_rate": "0.910000000000000000", - "max_change_rate": "0.304259315697044502" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "consensus_pubkey": "cosmosvalconspub1addwnpepqghsxshh5tdsf3g9q3a0f7mdq36lcmrxcjcsw0zwx7h6mhrkqt7gxqa5ml3", - "status": 1, - "tokens": "11913967185", - "delegator_shares": "11913967185.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.049529819581902112", - "max_rate": "0.130000000000000000", - "max_change_rate": "0.062116609393646476" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwyktyc4e9j89pv0syud54z03g7tg9j5nx66ceq6gqf698l8h7x8gtg29m4", - "status": 1, - "tokens": "4975856672", - "delegator_shares": "4975856672.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.880000000000000000", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.217954344442803519" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprs83zeag", - "status": 3, - "tokens": "32156167120", - "delegator_shares": "32156167120.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.351977697440288211" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvly6j0pyezy88s9lnat6taglylzq03vvsvyw4uy2tv3vcl3200ej0nev4k", - "status": 3, - "tokens": "16811362128", - "delegator_shares": "16811362128.000000000000000000", - "description": { - "moniker": "lasYiVeRDA", - "identity": "TFiGxJBNUs", - "website": "xswbDClAxs", - "security_contact": "HYUurzqzcC", - "details": "EVSfzEFSuo" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.036542719943188247", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.304756516958654494" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66dra0w3", - "status": 3, - "tokens": "19540440011", - "delegator_shares": "19540440011.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.065303820000927065", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.134868108685582589" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqglmtrs7uwjn4rvak6n3xec3xq3k8x8v59pqunpk44dk93nvjk3vscewj56", - "status": 1, - "tokens": "26607217", - "delegator_shares": "26607217.000000000000000000", - "description": { - "moniker": "hAQlIfWGGk", - "identity": "ohuamGtCae", - "website": "ZpegjNqnTB", - "security_contact": "dmfZxJGUcq", - "details": "YcDlNrjVXU" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.508849573815251530", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.690000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afqga9sv8", - "status": 3, - "tokens": "33258307031", - "delegator_shares": "33258307031.000000000000000000", - "description": { - "moniker": "uVtPIVoLeB", - "identity": "UQUjtBkUkU", - "website": "lrfjDXnSyH", - "security_contact": "tPWaAehpKA", - "details": "YCcmQgJRnO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.859185512301348293", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.915098787337318307" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrq06r4ck", - "status": 3, - "tokens": "41543247193", - "delegator_shares": "41543247193.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.119695944592116460" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4vjajc6x", - "status": 3, - "tokens": "61843733534", - "delegator_shares": "61843733534.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.437478542817284441", - "max_rate": "0.530000000000000000", - "max_change_rate": "0.308410375933996023" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvghhzrgz", - "status": 3, - "tokens": "36037299066", - "delegator_shares": "36037299066.000000000000000000", - "description": { - "moniker": "rUZvoFLmub", - "identity": "dQGYIJXPFq", - "website": "ZPoXnJmgzU", - "security_contact": "MdbwPJFNHC", - "details": "NdoQBlpUhN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.670000000000000000", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.629855974067904060" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdnmydex2xjhqnhfeudkqhkhj888kjzw67pqdw859u8g909jcyn4xkavddn", - "status": 1, - "tokens": "12315828943", - "delegator_shares": "12315828943.000000000000000000", - "description": {}, - "unbonding_height": "6", - "unbonding_time": "9936-01-01T04:22:01Z", - "commission": { - "commission_rates": { - "rate": "0.316562332892492640", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.566007736559520541" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", - "consensus_pubkey": "cosmosvalconspub1addwnpepq25a99sz5z4ux5fahn5g6gh7xsyckplenzjnxztza85ww393mdwe7kjzhj7", - "status": 1, - "tokens": "3222725", - "delegator_shares": "3222725.000000000000000000", - "description": { - "moniker": "iSRrbCHORt", - "identity": "CDdghkkmid", - "website": "nNRlagAXoW", - "security_contact": "MkjeVfcrNI", - "details": "gAzfuHvTeE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.115447316690759036", - "max_rate": "0.260000000000000000", - "max_change_rate": "0.061411901441335590" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf5zqt6stst6y23klsfpcjspr7tkpmjdlckv7wx6vrsewknw0m2a2d2eqav", - "status": 1, - "tokens": "7934886466", - "delegator_shares": "7934886466.000000000000000000", - "description": {}, - "unbonding_height": "13", - "unbonding_time": "9936-01-01T19:46:26Z", - "commission": { - "commission_rates": { - "rate": "0.186498958432282804", - "max_rate": "0.190000000000000000", - "max_change_rate": "0.169324253546368609" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz4luxgn", - "status": 3, - "tokens": "33206633235", - "delegator_shares": "33206633235.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.229284159886860129", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.212917450108859841" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqghun4nxekdzlcezu5epylpx2grw5vst3ct3wfcm25ushh49jtjljltwnht", - "status": 1, - "tokens": "5109252999", - "delegator_shares": "5109252999.000000000000000000", - "description": { - "moniker": "vYsZMuAZMj", - "identity": "ruZsSuRcSU", - "website": "zSbGrYvHQi", - "security_contact": "EGvxmVBnmC", - "details": "jxLlrmuSve" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.152694901599204693", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.241038925182996746" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw24c76ax", - "status": 3, - "tokens": "27567655084", - "delegator_shares": "27567655084.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.216560651737526756", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.026445047137608599" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdwls2cwhnhc6eapdv49a8e2l4pfhl4kyna3gasjle7qd3tw0csrgfsu0w2", - "status": 1, - "tokens": "6124762941", - "delegator_shares": "6124762941.000000000000000000", - "description": { - "moniker": "GbZmuFqSrs", - "identity": "zBDMXWuAAT", - "website": "oYTYLCDhOX", - "security_contact": "BmYozodwdp", - "details": "uwfkokyYnm" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.132737946334112303", - "max_rate": "0.380000000000000000", - "max_change_rate": "0.143930818045613974" - }, - "update_time": "9936-01-01T06:29:20Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgcfljwg4f78y3w65v9unsd283tk5a2zxs2mft203tgwgyjqglf6vua5qk4", - "status": 1, - "tokens": "8464012502", - "delegator_shares": "8464012502.000000000000000000", - "description": { - "moniker": "mVsKKRcaEr", - "identity": "eWIUfkJFLO", - "website": "IFRESgfaTp", - "security_contact": "eJpfnmHgUN", - "details": "wnkKbeWEhk" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.000000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qpu7x5c", - "status": 3, - "tokens": "27671960609", - "delegator_shares": "27671960609.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.077841535313299819", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.054979434313866047" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqde324p8zp7xxqwul8xzv9d79f4aqasjlqm6sxhemwhn2e79rz5jurknp0z", - "status": 1, - "tokens": "1864943427", - "delegator_shares": "1864943427.000000000000000000", - "description": { - "moniker": "ZZatQqAwWf", - "identity": "WIFSSfcIMu", - "website": "AFHEWYMAIc", - "security_contact": "pKTQsTtkRK", - "details": "BUOvcfwoSE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.298096915984498576", - "max_rate": "0.630000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2wcjjal", - "status": 3, - "tokens": "25069342080", - "delegator_shares": "25069342080.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.249161816461641720", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.693944288516379645" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akutfqm7", - "status": 3, - "tokens": "55737096951", - "delegator_shares": "55737096951.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.498362112747574396", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.645641814068879323" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693hazjkkehy", - "status": 3, - "tokens": "33054734644", - "delegator_shares": "33054734644.000000000000000000", - "description": { - "moniker": "mUQFKtnPLD", - "identity": "xsxoaAIVkh", - "website": "EBARfZhhON", - "security_contact": "GynbBFtcRq", - "details": "RftDCeMUPi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.123876475355091478", - "max_rate": "0.860000000000000000", - "max_change_rate": "0.141162753552435345" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v30nmws", - "status": 3, - "tokens": "78601464028", - "delegator_shares": "78601464028.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083731202536014652", - "max_rate": "0.860000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9ykjrzn93", - "status": 3, - "tokens": "18090212819", - "delegator_shares": "18090212819.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.081582427988342735", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.086390137368972014" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06my86wxz2", - "status": 3, - "tokens": "33968139195", - "delegator_shares": "33968139195.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.247483015769197525", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.837420192496215212" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtufvzu2k2knnce8l9jcwuntray9m8hnlal8a4jkcjazppr5p7pyus6emm0", - "status": 3, - "tokens": "19857350032", - "delegator_shares": "19857350032.000000000000000000", - "description": { - "moniker": "PfGefIRkUQ", - "identity": "PQNdBVtoxj", - "website": "nyfnvHyjNl", - "security_contact": "ewMiIvfvCh", - "details": "ttKmCVgWXS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.239149115387739677", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.173620767408899960" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv9w0yqrekktvu6gd7ak8u7wkwqj47llgrtl2vp2gtdvfafwatyysclj3nm", - "status": 3, - "tokens": "23726914937", - "delegator_shares": "23726914937.000000000000000000", - "description": {}, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.522454157166611225", - "max_rate": "0.820000000000000000", - "max_change_rate": "0.329662780053528069" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2crvswax", - "status": 3, - "tokens": "16516288319", - "delegator_shares": "16516288319.000000000000000000", - "description": { - "moniker": "kVNZIBYAxD", - "identity": "ChbsAFHanI", - "website": "SvHMthzzzB", - "security_contact": "cMJXUgGCfx", - "details": "PWsrYNKuPZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.540000000000000000", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.491525012965837080" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2kj4krx", - "status": 3, - "tokens": "45010236382", - "delegator_shares": "45010236382.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.095070637134115497" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveesw5rr6m", - "status": 3, - "tokens": "54768547781", - "delegator_shares": "54768547781.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.328146514360581742", - "max_rate": "0.810000000000000000", - "max_change_rate": "0.166428198995593213" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtjadacgcc9v3sptf62zr88pm3xd82gtxx7fl0vllavvx2vu5gckqagc0rx", - "status": 1, - "tokens": "1615474614", - "delegator_shares": "1615474614.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.065338192442219463", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.071905116454941829" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv59z3edalxhrq233upfrlzdpa2y4qqaahn8u4s56jf9utdxpnnnxnpfxtj", - "status": 1, - "tokens": "2364056", - "delegator_shares": "2364056.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.024463804229337023" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68yqxsxnt", - "status": 3, - "tokens": "25326342688", - "delegator_shares": "25326342688.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.785486462764506620", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.356882054361860100" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqflpdacrnmymf2nxz0z27wu4c42cyqfqued97l9pvln873ptnj722jw5nhc", - "status": 1, - "tokens": "10244193595", - "delegator_shares": "10244193595.000000000000000000", - "description": { - "moniker": "WkRSrJhiPR", - "identity": "MisdRpaRnZ", - "website": "KUNuGjAyZr", - "security_contact": "pYdYTuqYRb", - "details": "AzkAkTfsou" - }, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.094275793948488796" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdlqwps7uuk7l2pszryqcmflpr6rdgvfmkgga6fkjvsydts2s6udkqx67s6", - "status": 1, - "tokens": "10175385576", - "delegator_shares": "10175385576.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.050000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzlcd6kj", - "status": 3, - "tokens": "67804970220", - "delegator_shares": "67804970220.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.264013069771684883" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfdzh8ar6wwm3h8dd0n9rxk3vfv753568dq62g3xdqepgen0gkcnsl92xax", - "status": 1, - "tokens": "87516298", - "delegator_shares": "87516298.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.008369971691300017", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.003240979663537908" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", - "consensus_pubkey": "cosmosvalconspub1addwnpepq07ahy07m2ymqkwra0tzkgs0588p94nraj84wvmymmueg8dupcqv7534dt5", - "status": 1, - "tokens": "14531672001", - "delegator_shares": "14531672001.000000000000000000", - "description": {}, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.368173971209038079", - "max_rate": "0.620000000000000000", - "max_change_rate": "0.054850804257024119" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4v8fm8e8", - "status": 3, - "tokens": "41964454098", - "delegator_shares": "41964454098.000000000000000000", - "description": { - "moniker": "LDEzyylLGV", - "identity": "NaLpENvFnX", - "website": "ooOcvgIJwr", - "security_contact": "aQaxAlCyFx", - "details": "CxEFcmLmkI" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.099339754970547702", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.111217397607280422" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0rs6tt6rmqemes8jnlxsawqja89rdvyntyjuhwl73ajeelhrhee7vumxyk", - "status": 1, - "tokens": "981657888", - "delegator_shares": "981657888.000000000000000000", - "description": { - "moniker": "szQvkBMbEg", - "identity": "IBxatcFQNO", - "website": "fldsKGMdNR", - "security_contact": "qLDMtHRNsj", - "details": "RpRencldBz" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.118429306081945145", - "max_rate": "0.190000000000000000", - "max_change_rate": "0.105194643308960695" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt5s2m60xv2n7sxjv7lhzlf83u75fh7yc0pjv3thqf5vkdunr32ksh4xsdu", - "status": 2, - "tokens": "15174649749", - "delegator_shares": "15174649749.000000000000000000", - "description": { - "moniker": "VCTScqQSKa", - "identity": "WzaIRwbXgo", - "website": "BAOhQWhmkQ", - "security_contact": "NncLgAxHdH", - "details": "URrsiopqUa" - }, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.047510383078156072", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.032290417291892447" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqddyzyd3lgpt8jrlkmpg9qwhex2z7msn5uaxv9w46eps5vkmc6kwu5ans84", - "status": 1, - "tokens": "113412645", - "delegator_shares": "113412645.000000000000000000", - "description": { - "moniker": "FFikJsTYtD", - "identity": "GKkbjMUETZ", - "website": "MBebdoLbAT", - "security_contact": "rkOsehQNen", - "details": "vZFASbHJGj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.198586301080035955", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.012224704011526027" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgnwhgwtgfqyxwfp86e906zysx5p02kh5rjzsweq2984lm2e5f3qvs8vqd3", - "status": 1, - "tokens": "11726853019", - "delegator_shares": "11726853019.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.112940346400043350", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.078370922162771010" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k907nvf", - "status": 3, - "tokens": "28676349495", - "delegator_shares": "28676349495.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.609184993023386704", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.699887495531371188" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdzvxgkmxur34cmgyyfzr0mkhrysd6xdqpkz6k0qd62y4hl325qd62h02f4", - "status": 2, - "tokens": "13754725148", - "delegator_shares": "13754725148.000000000000000000", - "description": {}, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.870000000000000000", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.063255826123136327" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd7ruklxzqwqz3u2tdlh3kel0t0536g3pxu37r4286uavkrmx72mus5lvv6", - "status": 1, - "tokens": "11868660651", - "delegator_shares": "11868660651.000000000000000000", - "description": { - "moniker": "xIRtBfvrAE", - "identity": "eAHfYfXhkO", - "website": "dUrPZGxJFL", - "security_contact": "YdvDmWdVbe", - "details": "IXbFohDvjo" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.181867057844473236", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.185540283605239869" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw5h9ggnz7amw48v648wer50qeen3hv283fgyxaytq5l0y5ggz40x3zgm4r", - "status": 1, - "tokens": "14194120234", - "delegator_shares": "14194120234.000000000000000000", - "description": {}, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.043495592753648126", - "max_rate": "0.490000000000000000", - "max_change_rate": "0.490000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "consensus_pubkey": "cosmosvalconspub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjtszrqs", - "status": 3, - "tokens": "34574952843", - "delegator_shares": "34574952843.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.810000000000000000", - "max_rate": "0.810000000000000000", - "max_change_rate": "0.810000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtk5r42sr9allp9fsgh0ldj8fgmfmdl84w8dy23sr44u5zy5lxy2xw577kl", - "status": 1, - "tokens": "10646429954", - "delegator_shares": "10646429954.000000000000000000", - "description": { - "moniker": "SHCpfjKNSu", - "identity": "tDOjGFgyjP", - "website": "IHZYFpGyiJ", - "security_contact": "hjdANxnNHq", - "details": "ypZFjrXaym" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.940000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvact8ahszvndajqxra2w3e5le3trytmp9xqgqwcx4qykydgx70y2whdj6h", - "status": 1, - "tokens": "506914959", - "delegator_shares": "506914959.000000000000000000", - "description": { - "moniker": "qUibSizEqd", - "identity": "bYeZJhWRkx", - "website": "UteQGhdNGk", - "security_contact": "VwPIMByrAe", - "details": "lIhtmLCFtZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003530593563713880", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.006047204189099454" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvm3gjyc4syt8pvjrmfus0my28n42ypfj67yv45es25tpctv2vhxcmlw5d8", - "status": 1, - "tokens": "4732841169", - "delegator_shares": "4732841169.000000000000000000", - "description": { - "moniker": "yufdZLmBSv", - "identity": "UQtKAMmdwN", - "website": "lFmhkKHsad", - "security_contact": "gWQFiKkqtl", - "details": "UemBSSExdy" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.096951425148933086", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.057968950263397204" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "consensus_pubkey": "cosmosvalconspub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku73m9m0", - "status": 3, - "tokens": "16992076248", - "delegator_shares": "16992076248.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.406968367525101581", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.487609794856186092" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw0np49ksk7pxwauu8jkfp7gf9dqwahdc8yknp53jvc0zcq6ugplxxvu2k5", - "status": 1, - "tokens": "5755488027", - "delegator_shares": "5755488027.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.356380989095155962", - "max_rate": "0.380000000000000000", - "max_change_rate": "0.155364476986441701" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfcdg0aax", - "status": 2, - "tokens": "5685279942", - "delegator_shares": "5685279942.000000000000000000", - "description": { - "moniker": "YKKhjZGayb", - "identity": "IvgiPDjmYA", - "website": "gScrUtVzvh", - "security_contact": "kGHySpHXgu", - "details": "IyuehlcoPM" - }, - "unbonding_height": "50", - "unbonding_time": "9936-01-04T22:14:51Z", - "commission": { - "commission_rates": { - "rate": "0.093407705950029411", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.187465926844434813" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0e5h85jydylerz95nl4y6hms29agglx4p9mtwxp4e98r6wckmy3qzsvqn2", - "status": 1, - "tokens": "2112005770", - "delegator_shares": "2112005770.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.183782150095569515", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.173922417381016295" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "consensus_pubkey": "cosmosvalconspub1addwnpepq228r4rpxclcs5ufhlytsyx6dxkvwvecxvjhlsvglg26jg6l9kpy65ys4kc", - "status": 1, - "tokens": "640064160", - "delegator_shares": "640064160.000000000000000000", - "description": { - "moniker": "TkmRhasAJG", - "identity": "nrtIpGdFQw", - "website": "FSkoCAGbBU", - "security_contact": "JYwbMItCZN", - "details": "lEwvgQzPgI" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.070569099867139542", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.057349117351674195" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7zgmra8", - "status": 3, - "tokens": "26261718579", - "delegator_shares": "26261718579.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.210000000000000000", - "max_change_rate": "0.067309904771533509" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqnavslf", - "status": 3, - "tokens": "46127605035", - "delegator_shares": "46127605035.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.895728278286976959", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.140752130806369269" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jyyn3gu", - "status": 3, - "tokens": "22249948652", - "delegator_shares": "22249948652.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.008115100503323252", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwmplgyppurr7j6knpfavaza6xrg007n907th4lslha4qx45q82tw8wvjzt", - "status": 1, - "tokens": "50006896", - "delegator_shares": "50006896.000000000000000000", - "description": { - "moniker": "ybIIoTPlxX", - "identity": "XQTftwoSPG", - "website": "qUglDanvKZ", - "security_contact": "kfbUrCfRzd", - "details": "LTPbNBSEJE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.119939677612298020", - "max_rate": "0.130000000000000000", - "max_change_rate": "0.033345572724347445" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yagkfrr", - "status": 3, - "tokens": "39560123415", - "delegator_shares": "39560123415.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.060188716749386269", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.350000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf9usg6za2dqh4lw3xj0h9rrgtfth0f6lctuv3kwv7smhhl8czc3cnfp3g3", - "status": 1, - "tokens": "8741308900", - "delegator_shares": "8741308900.000000000000000000", - "description": { - "moniker": "PGNhLBZWzw", - "identity": "zDvDjFwbHN", - "website": "CdiTImAnEO", - "security_contact": "rJZQgfIJvh", - "details": "xTTyQTjmMr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.307210706399811753", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.399893848936713140" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwckstndv9w0luxt6p3a694qazxat6kerfnpsr3qafypj9adchjaqxfwvdr", - "status": 1, - "tokens": "14799158297", - "delegator_shares": "14799158297.000000000000000000", - "description": {}, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.136186469015251310" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "consensus_pubkey": "cosmosvalconspub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kwmez9k", - "status": 3, - "tokens": "16420725988", - "delegator_shares": "16420725988.000000000000000000", - "description": { - "moniker": "LVfceOUKZE", - "identity": "ZyVUuaCAJZ", - "website": "rliAdTPvEK", - "security_contact": "hVtZPHOsKh", - "details": "QjmMKruCba" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.036920301680485403" - }, - "update_time": "9936-01-01T16:55:11Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq77rpqn", - "status": 3, - "tokens": "26062927309", - "delegator_shares": "26062927309.000000000000000000", - "description": { - "moniker": "BFoqLaJLDn", - "identity": "weLorPCgTe", - "website": "oyhVcpSOLq", - "security_contact": "hdnvhDJTDC", - "details": "SAZISvvmwB" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.160832184115355939", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xw03emk4", - "status": 3, - "tokens": "44313010729", - "delegator_shares": "44313010729.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083856723472306849", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.569378562223247850" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6yp7zp3n", - "status": 3, - "tokens": "25164533156", - "delegator_shares": "25164533156.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.330000000000000000", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.314039829028852779" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdd48dqgku8keethq2dtl8zmgnjprm0gmc2gawzwr6z3hp4m8s802w6859s", - "status": 1, - "tokens": "492237770", - "delegator_shares": "492237770.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.271162649945129428", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.426439315005694848" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvn899z9u9a7h28682292n9y77yr6yuyrg2xvg8eaammccqfuc9e5jp63vn", - "status": 3, - "tokens": "16985369823", - "delegator_shares": "16985369823.000000000000000000", - "description": { - "moniker": "oVMoJSrGgV", - "identity": "ydZuwvoyLe", - "website": "EdyJLNhNGZ", - "security_contact": "QauDavDNuL", - "details": "CVkbnFlumN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.276325858271560152", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.108166159043578444" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgv72p8pxj6dc526aynu6gkcg0cfrvjmjv6tnrhtp3stacy3jgezzlkdmfv", - "status": 1, - "tokens": "125301", - "delegator_shares": "125301.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.358186845519178392", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.739442651834999796" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwshp63n", - "status": 3, - "tokens": "25367511082", - "delegator_shares": "25367511082.000000000000000000", - "description": { - "moniker": "KODmaZYfBO", - "identity": "dQoWoZcHpD", - "website": "QRjjuYKVNR", - "security_contact": "BHWzdORGfc", - "details": "dZGTxQmqIN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003392332242825811", - "max_rate": "0.060000000000000000", - "max_change_rate": "0.027187395396712775" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqv0lje47", - "status": 3, - "tokens": "54901950842", - "delegator_shares": "54901950842.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.193375046872051394", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.161750559623523660" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtcvgnxpkww6h60yke0z0rmvv34tw9ycuwr02pvw67kgaygtvgku2q2mrjt", - "status": 1, - "tokens": "13624841977", - "delegator_shares": "13624841977.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.142858989036560174", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.660255121442971729" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc9m7uvt", - "status": 3, - "tokens": "15374405822", - "delegator_shares": "15374405820.680335249007925874", - "description": { - "moniker": "eomlzRaIRN", - "identity": "PaBTVBXpcj", - "website": "frMwzGwrdS", - "security_contact": "XwCgZGftYO", - "details": "oynChhccDw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.014913519812752309", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.219118316904950121" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2qs6da44rrhj6hj2ea7a2kjnh9yecavt8t00dry6nd56fvjchyhqesfuvt", - "status": 1, - "tokens": "3041120922", - "delegator_shares": "3041120922.000000000000000000", - "description": { - "moniker": "rLSjWyflSi", - "identity": "HSuNyExgbD", - "website": "vdCDCTATFy", - "security_contact": "jWlYErowfX", - "details": "gFCgjjVhur" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.710000000000000000", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.236185027723064295" - }, - "update_time": "9936-01-01T09:58:26Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7dsh8mr", - "status": 3, - "tokens": "33057476849", - "delegator_shares": "33057476849.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.074914975922116628" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtplsxcj5j56ms8j7lerl57al6asnrh53uft4efkzvuhv50gq8azx0l5f9w", - "status": 2, - "tokens": "14118884362", - "delegator_shares": "14118884362.000000000000000000", - "description": { - "moniker": "qQzVEWDfcL", - "identity": "LQVrYguqLe", - "website": "BJddIAyseo", - "security_contact": "trbqxTDxYA", - "details": "TTjZQrCkYO" - }, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.299140431481446428", - "max_rate": "0.510000000000000000", - "max_change_rate": "0.367721024197463519" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvuzm6rcpa5h3kmgenxc04qaww03748hw2plpqnyyk5c0ypql7jnw76ujdz", - "status": 1, - "tokens": "5480500900", - "delegator_shares": "5480500900.000000000000000000", - "description": { - "moniker": "FaJwpwEttu", - "identity": "kZOHQugtED", - "website": "PQZJSclRmf", - "security_contact": "MIFJdxgvtg", - "details": "NReTekfbjK" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.523988597853042947", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.308301841976871261" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axhh8p8f", - "status": 3, - "tokens": "49683234188", - "delegator_shares": "49683234188.000000000000000000", - "description": { - "moniker": "MJAduJwrkS", - "identity": "YpKMJsMpdh", - "website": "rmUXbHIGjh", - "security_contact": "KxyJSeDEJS", - "details": "gQmDpfNyLZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.637063248045666486", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.100218674012239339" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmkm3zs42", - "status": 3, - "tokens": "34289428306", - "delegator_shares": "34289428306.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.026475742223507385", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.008016543161851368" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00s4avel98xmrp04dalj5dv5cm0szqd8fy6hfqlgtzwtxq3y566yccm7xk", - "status": 1, - "tokens": "14381116169", - "delegator_shares": "14381116169.000000000000000000", - "description": {}, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.120000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.117328305608042006" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw3fj2ga", - "status": 3, - "tokens": "29885998584", - "delegator_shares": "29885998584.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.208832068199199828", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.835848953294536000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfxgg4wmgzakcpcmp7g68j059k5k5ucmaj9vfgqvseqgkuuqltlf2c5w6uv", - "status": 1, - "tokens": "2533410912", - "delegator_shares": "2533410912.000000000000000000", - "description": { - "moniker": "bYcSaxNPkq", - "identity": "arINXKFuvD", - "website": "fCFrVNkkzm", - "security_contact": "yhhWWoxqFq", - "details": "urmzJwGIym" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.467362323850790159", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.563213072917526451" - }, - "update_time": "9936-01-01T08:09:55Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv7nw49k6j8sg6379dy0lemj7vee2el49mt5rmypwujwk6lua8duyrr8zrn", - "status": 3, - "tokens": "21181468286", - "delegator_shares": "21181468286.000000000000000000", - "description": { - "moniker": "TgLltHAWtO", - "identity": "zpriAAvZuw", - "website": "pWVJnIqFBY", - "security_contact": "TyuWOjmMFF", - "details": "CbbpwkidBS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.237822850366335221", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.134613352727411591" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqth3ytlunezutcfyr4afacswjkwypdm07lm6kxe4h2aewvmm90t5cc8rts3", - "status": 1, - "tokens": "13794284295", - "delegator_shares": "13794284295.000000000000000000", - "description": { - "moniker": "riEFCuKVXf", - "identity": "RZJMRcSWpl", - "website": "JQleNyHRoA", - "security_contact": "vwBjcPwPLl", - "details": "OxnpsiCZYU" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.025570974549293612", - "max_rate": "0.030000000000000000", - "max_change_rate": "0.001283275853790765" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2vncgld", - "status": 3, - "tokens": "39430946332", - "delegator_shares": "39430946332.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.400358972669819604", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.343431675789315867" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrywn9e6w", - "status": 3, - "tokens": "32328037984", - "delegator_shares": "32328037984.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.039339062684741866", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.021256256594527078" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtsn2j9l0052cprtztzuxzcwspekquyfn9q9nzlt2ez2pfzcvu6jkqu2unx", - "status": 1, - "tokens": "9640492641", - "delegator_shares": "9640492641.000000000000000000", - "description": { - "moniker": "OhKGKdYJlz", - "identity": "LSJqmrKKaR", - "website": "SiTLNvLXQj", - "security_contact": "uKbbQAowYR", - "details": "JzsfhKIeFY" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.080341642170762698", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.105285510061933545" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus2udpwh", - "status": 3, - "tokens": "15813863385", - "delegator_shares": "15813863385.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.543747468021249371", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.392045382869085556" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwujx3ap2", - "status": 3, - "tokens": "25957780472", - "delegator_shares": "25957780472.000000000000000000", - "description": { - "moniker": "hoLpIoNUFo", - "identity": "LCpoujNFyW", - "website": "AOTlTXjPul", - "security_contact": "elgNvDzEfH", - "details": "hwOSWkTDMH" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.347272379813626146", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2pnmqvu6uvxhy0t5zyez5wjcvsh5pkqlmta3uyeqy0yzf7tp0n76xdp2vd", - "status": 1, - "tokens": "64706947", - "delegator_shares": "64706947.000000000000000000", - "description": { - "moniker": "yIzgSLCxWK", - "identity": "LhFzfpIqEv", - "website": "nihretOwDr", - "security_contact": "UqNKLIAQhC", - "details": "IWABqYDyKj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.002948295103320281", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.121632522168200969" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtj39qcdlmh7fr77am26s8as06l9v3p426z5gr5dyfvc4fr5gqyevxe8agn", - "status": 2, - "tokens": "12174892810", - "delegator_shares": "12174892810.000000000000000000", - "description": { - "moniker": "hjYgiDHhzz", - "identity": "KrwRKCSMYC", - "website": "VKtCXTAtbA", - "security_contact": "kqWNgIhnNy", - "details": "etaTpRtVAp" - }, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.344371628918599076", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.334517383567629324" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwdhe2nv5ugezx2nkyx7t7z255pj3xle6kgcpfdkmwdng4vp7sa3y40we66", - "status": 1, - "tokens": "10929627266", - "delegator_shares": "10929627266.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.004188013237240263", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.078008827750366986" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwac5an6ey8yprrjfh3640q8l5hg7w4fgrlu54dm8dzacu0msnv472ryvq8", - "status": 1, - "tokens": "9052281558", - "delegator_shares": "9052281558.000000000000000000", - "description": { - "moniker": "gJaIcmLYsZ", - "identity": "jroUNglzSW", - "website": "XrrZfRjuzl", - "security_contact": "DYvQqylZps", - "details": "wIKrOdZvrO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.010000000000000000", - "max_change_rate": "0.004972274320458977" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtwlwcajqxexfgfd38r4f3zhqxzvupczp89m9y39kt4xqufa4n33clzk663", - "status": 1, - "tokens": "357334043", - "delegator_shares": "357334043.000000000000000000", - "description": { - "moniker": "BRVwdOkVBr", - "identity": "aKYCoLKQUh", - "website": "hDcADiBWXa", - "security_contact": "nzShMsVsKj", - "details": "LNBhxIWHEs" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.970000000000000000", - "max_rate": "0.970000000000000000", - "max_change_rate": "0.128896474943338231" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9ugfdlq9", - "status": 3, - "tokens": "45284218868", - "delegator_shares": "45284218868.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.340626334815374555", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkxmnmkq", - "status": 3, - "tokens": "44505127913", - "delegator_shares": "44505127913.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.605944631117636209", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.639343774657574630" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqk8ct27q", - "status": 3, - "tokens": "22456561633", - "delegator_shares": "22456561633.000000000000000000", - "description": { - "moniker": "DPTpRIdXgW", - "identity": "qysDMlMxpi", - "website": "xWbmLVlZvB", - "security_contact": "QtpKTducMv", - "details": "UWYfFdNOxg" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.057271144965717909", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.075138495309274904" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtwvf7g53a6nlvcr6exwkhumshdv59mh0jaa8umfdts70dtupqctxwks642", - "status": 1, - "tokens": "11601440649", - "delegator_shares": "11601440649.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.397633947789396228", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.717967266416289169" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdrvr2ne6f9hgqca4s5fe3uwfxctwdr4ne2lkmmqsgfv5uw226l85das0j8", - "status": 1, - "tokens": "11399240291", - "delegator_shares": "11399240291.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.041564439158976825", - "max_rate": "0.430000000000000000", - "max_change_rate": "0.217285019740322808" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg048v7u9cfmrxvk8kp4rwr3z3cn7lwsag6nyf5m9696lrdquk44ywwlavq", - "status": 1, - "tokens": "6804408417", - "delegator_shares": "6804408417.000000000000000000", - "description": { - "moniker": "FdDcGcaieJ", - "identity": "YMIBMpEMxW", - "website": "FrQHDjmWVB", - "security_contact": "zvaqppfaVE", - "details": "MeORuLmeIz" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.380000000000000000", - "max_rate": "0.380000000000000000", - "max_change_rate": "0.174389181438542137" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdm5qzsy6r8f29za6hghdk4ej8hujywh6dsyteyguvxm5h64an8rx04zrcx", - "status": 1, - "tokens": "13843367300", - "delegator_shares": "13843367300.000000000000000000", - "description": { - "moniker": "vMZOeDUHUM", - "identity": "wfmFxUNRng", - "website": "KNZJMmrTqA", - "security_contact": "feyLBfuyQx", - "details": "LIzoGEUhKk" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.448785636299397402" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvfuwjyepzrr7elzg5d2u9m6z4aujww6l25gnscerc76t68tvnjd5ttjp2v", - "status": 1, - "tokens": "23136285", - "delegator_shares": "23136285.000000000000000000", - "description": { - "moniker": "sUTOjiepmW", - "identity": "tJVRrBwqlG", - "website": "YshLyiZMrT", - "security_contact": "RUDyZwUQmU", - "details": "QzgVtMvYLd" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.071168023059934609", - "max_rate": "0.930000000000000000", - "max_change_rate": "0.501568793423267606" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd7u4d80m4e6sfhyzj84k6y34v30g9cstzx7cmrazvxdtfe40urcvran9t8", - "status": 3, - "tokens": "45811135531", - "delegator_shares": "45811135531.000000000000000000", - "description": { - "moniker": "zcPImZiDZD", - "identity": "zkcTihefFl", - "website": "mIjAaWRNkf", - "security_contact": "gTafXNexkI", - "details": "tJJDPwaiAf" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.079222020883406460", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.311112908017536993" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggxauhp0sadc5npdva6f492f3n4a76fldyt3lca6lk36685s624ucakcrh", - "status": 3, - "tokens": "24610359351", - "delegator_shares": "24610359351.000000000000000000", - "description": { - "moniker": "dLwrEevbbD", - "identity": "ubSqqBoPRs", - "website": "MNuXpKVOXc", - "security_contact": "lNXuEDYSJp", - "details": "CvXURllZqF" - }, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.200000000000000000", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.175531415042829217" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0xhfz0m55nz4txp2v7ttr3zxa9339nx6tjfv24xth38qs7s9qw56ayattm", - "status": 1, - "tokens": "6487425213", - "delegator_shares": "6487425213.000000000000000000", - "description": { - "moniker": "yoQWgAwfrT", - "identity": "VnLdNIgSPv", - "website": "TmrorbnjLv", - "security_contact": "ddGynzpfAR", - "details": "sQAebQXxiK" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.950000000000000000", - "max_change_rate": "0.013910826406076438" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvcgk67dzzthkzn4yjgfq0p7942jhxjpn4e577szvhz6nwclh2ntclfpnr0", - "status": 1, - "tokens": "2422560770", - "delegator_shares": "2422560770.000000000000000000", - "description": { - "moniker": "zrclnpBtHC", - "identity": "SBouqnqXEt", - "website": "radHZCsfFl", - "security_contact": "ezwkUqrunA", - "details": "ccdxOHlWVD" - }, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.136074064855032333", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.154479519358430381" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7vpfm9vgvxg3sqwsn8y6yacfnwvqf3760dck340wqzsnnpntcgy5h0jt4", - "status": 1, - "tokens": "2108075856", - "delegator_shares": "2108075856.000000000000000000", - "description": { - "moniker": "VxaqXomXpv", - "identity": "NwxmDYXCmJ", - "website": "ATfeeNFFvx", - "security_contact": "TiYWqKMRkn", - "details": "FGaauJzXXI" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.940000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.854090879535681556" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvg5y5xv9eu0yd4rfztn6pehqnxcc0hy7wxll35vfthehmg2w59nvqk80pv", - "status": 1, - "tokens": "6669052939", - "delegator_shares": "6669052939.000000000000000000", - "description": {}, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.130000000000000000", - "max_rate": "0.130000000000000000", - "max_change_rate": "0.074054826101930076" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqwclfkt", - "status": 3, - "tokens": "34459325260", - "delegator_shares": "34459325260.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.033986343509044787", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.090000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7ah3flgscnydj0lgv96mv5s6lwsnvj7spwh06kke4exwq5m0aqz862l0e", - "status": 1, - "tokens": "927350399", - "delegator_shares": "927350399.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.694665412425584983", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.750000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7t4673v", - "status": 3, - "tokens": "55948291091", - "delegator_shares": "55948291091.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.440048441195653325", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.180789237411591672" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfj7kzn2s97tteld9ssyqy7jg0clhn0zhp8zuwwmhw8uxhhgc7g4zjzn7xn", - "status": 1, - "tokens": "4006205", - "delegator_shares": "4006205.000000000000000000", - "description": { - "moniker": "fyHblDkCys", - "identity": "WCDOcZEgti", - "website": "bbUYFhGpRR", - "security_contact": "fhfKBLrEvy", - "details": "kRIUubHcwr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.603701710007259889", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.099074121449624859" - }, - "update_time": "9936-01-01T08:09:55Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5r4xrdd", - "status": 3, - "tokens": "15675831119", - "delegator_shares": "15675831119.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvvf87wq27y92aaj8csgp4s4vqu69xtm4td3qdp3pr5etfrdn6v7ws3hsmv", - "status": 1, - "tokens": "12890424126", - "delegator_shares": "12890424126.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.124802770472432716", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.173959658484508482" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt62glh2fvu9vulmgvh6xqupdqk49yzpk497jcjayystchx48f4kx8v59u0", - "status": 1, - "tokens": "7052466205", - "delegator_shares": "7052466205.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.003525430478281768", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.016675882352481766" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqth5wr26d7sltuj00csrl3f3zly9nxuj4lkfyq0hr0xrxcfu6tsz5qhdhsw", - "status": 1, - "tokens": "8559089572", - "delegator_shares": "8559089572.000000000000000000", - "description": { - "moniker": "otFXajfWNI", - "identity": "xXrEsBXwpv", - "website": "XlaJwNhjAq", - "security_contact": "svEFXzNNQS", - "details": "fTnIHUVEnv" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.204542425183727119", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.145658560298436900" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czwem9y4", - "status": 3, - "tokens": "45487475001", - "delegator_shares": "45487475001.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.177753292751501209", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.323174353688819429" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxe7jutz", - "status": 3, - "tokens": "24261774404", - "delegator_shares": "24261774404.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.017452646416466178", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.020000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4svau85d", - "status": 3, - "tokens": "31770155824", - "delegator_shares": "31770155824.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.138735148670316454", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.286634953103815529" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtumyzl7hulm5v6delsx7hdpcye3stda9rxz6jgjf2eykqm2jh20kej9nsj", - "status": 1, - "tokens": "6275641534", - "delegator_shares": "6275641534.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.055704912322332987", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.094301772909367460" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2n3nxrwxc027jequjln9ps5546ahg3p2h3t3lm4u9vmahke8kxw6lm9f7j", - "status": 1, - "tokens": "10074815927", - "delegator_shares": "10074815927.000000000000000000", - "description": { - "moniker": "BqXVhGrdzr", - "identity": "BssMXIyaOa", - "website": "SMUxWlPGrv", - "security_contact": "CLeUdBrDWI", - "details": "YWFtSWANuy" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.004105601830262673", - "max_rate": "0.030000000000000000", - "max_change_rate": "0.028348463914291344" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf0u600sgl3zdn3uh4jd6jmw6fc0jc40r0l2crvz3sla3f8d32flghwtxaq", - "status": 3, - "tokens": "37602205867", - "delegator_shares": "37602205867.000000000000000000", - "description": { - "moniker": "BUZauhlQrt", - "identity": "yuIKzyGzQS", - "website": "fDSmxAmazc", - "security_contact": "jVDWgXPhkM", - "details": "LBFAwsUoyi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.244517333363622892", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.153245122134586562" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "consensus_pubkey": "cosmosvalconspub1addwnpepqduttph6whz8ngwywhy0hu3c9kxww3hqh0f0mrdkjcvg2h8q3u8cvfu0qkl", - "status": 1, - "tokens": "593652129", - "delegator_shares": "593652129.000000000000000000", - "description": { - "moniker": "xjWbnHCfWc", - "identity": "JaWoTPxlVR", - "website": "VWTFFWylBY", - "security_contact": "CgwYhkKzfA", - "details": "BfFlSjcVHR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.192959054535463189", - "max_rate": "0.380000000000000000", - "max_change_rate": "0.167893162151719645" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0zx0lgud48vvwy6lts09r2l9e8yd5smkjfzzmfsfw9ps33400vwgduselz", - "status": 1, - "tokens": "6967497396", - "delegator_shares": "6967497396.000000000000000000", - "description": { - "moniker": "wZjmyfrmLF", - "identity": "SdxpPXgzQU", - "website": "ojcVqTNCTA", - "security_contact": "JNsQWMMEYr", - "details": "ptoagqGEJY" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.051995396939424988", - "max_rate": "0.720000000000000000", - "max_change_rate": "0.097236596735632381" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2prz4vype8mhmwnvw537vf53ftm02nlpgefm002drthw6py353323jw5e6", - "status": 1, - "tokens": "211016457", - "delegator_shares": "211016457.000000000000000000", - "description": { - "moniker": "IERTNdjcys", - "identity": "RMlZikkNjk", - "website": "HiWCYkrvig", - "security_contact": "PKUdCVyvke", - "details": "QntRmnlGZt" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.735573943921984982", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.090597702660368454" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvrk5jlckmpf0spqdh7a204qtectsss5mznvsl7sjtget8msrg20xlugv3v", - "status": 1, - "tokens": "1201306698", - "delegator_shares": "1201306698.000000000000000000", - "description": { - "moniker": "CGInszCvjL", - "identity": "rUJDJazuTG", - "website": "PYbkObcHdn", - "security_contact": "lVynehLrSd", - "details": "eYRpCKYvrx" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.297069068496065785", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.475462668160887599" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvhqzk07yeludsgh0nffk465d2seqmav2prd2rs6alu56l75w3dyyv7fu28", - "status": 1, - "tokens": "3167117301", - "delegator_shares": "3167117301.000000000000000000", - "description": { - "moniker": "ydQcLezwwL", - "identity": "KtTnlmLXCN", - "website": "KUDIKfgAiY", - "security_contact": "ntlISyWbkj", - "details": "fbspSWJDAB" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.222447677870840972", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.194980583372334332" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzue70ade", - "status": 3, - "tokens": "37676305948", - "delegator_shares": "37676305948.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.260000000000000000", - "max_rate": "0.260000000000000000", - "max_change_rate": "0.239035612898447459" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj2sy3f5", - "status": 3, - "tokens": "26737755597", - "delegator_shares": "26737755597.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.420000000000000000", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.295551090875771737" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgxhtkut5ur5pju0zjkw8lhhfyusz3x409c6qet8yrpd0p7czcadg3sg3mx", - "status": 1, - "tokens": "3436201124", - "delegator_shares": "3436201124.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.115615158377471618", - "max_rate": "0.460000000000000000", - "max_change_rate": "0.219100078099573524" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw8vy48pqzssprlmhvtvtc0hh88lv3uuz6etntlzn9nqznp2r8ewsp2p20f", - "status": 1, - "tokens": "199636304", - "delegator_shares": "199636304.000000000000000000", - "description": { - "moniker": "LsyIcWgMDs", - "identity": "waVauWkwVA", - "website": "oEbvwjXcuI", - "security_contact": "EGRmIniXNY", - "details": "dtZZypERzx" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.247966845740203972", - "max_rate": "0.260000000000000000", - "max_change_rate": "0.206307125726817588" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvhet24yk50y4m60mceffquewu9p4enwrgcum0csceuull7a59u6567nn0v", - "status": 3, - "tokens": "20405570669", - "delegator_shares": "20405570669.000000000000000000", - "description": { - "moniker": "ZeprycSOnc", - "identity": "ZcHuivhMFq", - "website": "hCsVpTWmaL", - "security_contact": "AIKsDuUCDR", - "details": "EgpxVbAOaK" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.054000324644638628", - "max_rate": "0.380000000000000000", - "max_change_rate": "0.120973196882786975" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqww4ac9sdmwjurlwyea8de788rvdqu2gwzv5ukdqnsefzyfjdjtgvzlz3gr", - "status": 1, - "tokens": "7656253701", - "delegator_shares": "7656253701.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.136480139358851972", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.124002561027484210" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", - "consensus_pubkey": "cosmosvalconspub1addwnpepq28x4gcrklk8r22c650tktvywp0hfwv8hwtc0heq6d8wr2kagh2j69eaujq", - "status": 1, - "tokens": "5987604552", - "delegator_shares": "5987604552.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.224924640665354113", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.083804383012326481" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwsf5usr95lzjzve9ap7347d4a8ws0fry32d0428e8elme2m4xe4qy335ne", - "status": 1, - "tokens": "11089478639", - "delegator_shares": "11089478639.000000000000000000", - "description": { - "moniker": "lccuIyGWcn", - "identity": "NZWAFQchWA", - "website": "yXQblCIJFQ", - "security_contact": "nnvdMbLnJq", - "details": "ibClAKBstR" - }, - "unbonding_height": "6", - "unbonding_time": "9936-01-01T04:22:01Z", - "commission": { - "commission_rates": { - "rate": "0.111667297951264416", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.054094041387600362" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgh6neaxc5qc82vrng427tmhlw78y4205pselprm387vgy5vkgvhc8vzhp8", - "status": 1, - "tokens": "9873924532", - "delegator_shares": "9873924532.000000000000000000", - "description": { - "moniker": "ZetnggqSeu", - "identity": "DYVdEOVlTH", - "website": "xPuLnecvry", - "security_contact": "LDzeTzsHFF", - "details": "OUlzqRajSn" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.382653580593648245", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.156454412026067119" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0tus4q4stns9dvru8ju7zdsjqqupgjwf3g4zlux4805ku0ccck2fht2a", - "status": 1, - "tokens": "247885300", - "delegator_shares": "247885300.000000000000000000", - "description": { - "moniker": "wnfRnuwTaN", - "identity": "PsxoKqHBAd", - "website": "UxeEfnWIuY", - "security_contact": "YBArDihhbI", - "details": "XzasuCeQcL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.361954185750494828", - "max_rate": "0.400000000000000000", - "max_change_rate": "0.275644004976418184" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6k07476", - "status": 3, - "tokens": "25102040344", - "delegator_shares": "25102040344.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.599184934718890393", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgh9lxfuk4amzsp0w28t8dkdwf2xk8yrxjj7xz0lnmzs2lyahrdz2f2yy35", - "status": 3, - "tokens": "17609505538", - "delegator_shares": "17609505538.000000000000000000", - "description": { - "moniker": "yAwjGcNsZH", - "identity": "STCkyPeJjc", - "website": "yvmEPebWkk", - "security_contact": "ZficJLXKJM", - "details": "qAWHtJiitW" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.690000000000000000", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.509977105992119960" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt0sk5rhcpv85mjvladxx3ygs0auglwcm4xpurjqeex8z99ya86363zl4ug", - "status": 2, - "tokens": "7847492642", - "delegator_shares": "7847492642.000000000000000000", - "description": {}, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.546622488015386807", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.175928838659210799" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdhcc8jww3jnsk9s3syxvwqdur5w8lzgvgujsu0j8n944m68ux2d2km69mk", - "status": 1, - "tokens": "12249202554", - "delegator_shares": "12249202554.000000000000000000", - "description": { - "moniker": "grFECXszmI", - "identity": "NuvdSJPltV", - "website": "HvSdvMKYkc", - "security_contact": "gqBEvgzWty", - "details": "AqGxwBvLuq" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.413759057762081199", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.211740487873750444" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqghn86gscad5np6l2h0zte7qa4gylqvkzdznqwknhrxk6v7al09zvqvzm8s", - "status": 1, - "tokens": "9487692660", - "delegator_shares": "9487692660.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.167663118910141794", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.257899452167596882" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "consensus_pubkey": "cosmosvalconspub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjycl58l", - "status": 3, - "tokens": "41119826715", - "delegator_shares": "41119826715.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.025162698699691548" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75fh3auv", - "status": 3, - "tokens": "19565632897", - "delegator_shares": "19565632897.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.579061375935434182", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0k56l5wh6qrl4fmp9jl0v78qy4jahrkkl6xqjc2zmap6tjg4h23g8j409r", - "status": 1, - "tokens": "9398321077", - "delegator_shares": "9398321077.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.116448312344293007", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwskjpjy", - "status": 3, - "tokens": "44648874284", - "delegator_shares": "44648874284.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.258140043497759741", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.447039357737510640" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg57gy4ef", - "status": 3, - "tokens": "34209671267", - "delegator_shares": "34209671267.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.480455308806333346", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55hrcqtd", - "status": 3, - "tokens": "36900108763", - "delegator_shares": "36900108763.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.409558857679769509", - "max_rate": "0.930000000000000000", - "max_change_rate": "0.610998804526507722" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0sgshv9mf8qy7ff303mqqv5zppu3q4mcwrnheue8d3kq0ytyynkxlak2ae", - "status": 3, - "tokens": "28980476016", - "delegator_shares": "28980476016.000000000000000000", - "description": { - "moniker": "hVYOUraqpo", - "identity": "XRliNUdYgt", - "website": "FYzwRNeFsW", - "security_contact": "AYYtrdbBmx", - "details": "NaWAwUYhir" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2d8k6kg75hjwqyknda4mj9wc65v7rzcqenfv039tnkwjss5tuq723hs8yv", - "status": 1, - "tokens": "9001683044", - "delegator_shares": "9001683044.000000000000000000", - "description": {}, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.453113774608032219", - "max_rate": "0.950000000000000000", - "max_change_rate": "0.571183533543927226" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwux9qwtmnuzxkw7203qndplmsvj6lpw9670wlu6sgaw6y30tzuhjh0pg3h", - "status": 1, - "tokens": "13444158275", - "delegator_shares": "13444158275.000000000000000000", - "description": { - "moniker": "yFGOJKrIlc", - "identity": "bGyYKcRfzP", - "website": "IRcsWPqPJj", - "security_contact": "oboQYAvKUQ", - "details": "imjjiiwgwg" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.179273604024357441", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.033903582588444164" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwa26gwxuwwnhmgz57tcvyqvj23qft9wryeutcms0z4ss9f5tujfc8t240p", - "status": 1, - "tokens": "3562717063", - "delegator_shares": "3562717063.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.075850735550956083", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.068439348734071304" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxd2wcms", - "status": 3, - "tokens": "27742737411", - "delegator_shares": "27742737411.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.870000000000000000", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.402061609548054151" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw2gxruh52umsuh8jd7g78587jx0qd4skze2u2dm0sm8shx64tvcceje270", - "status": 1, - "tokens": "2240964465", - "delegator_shares": "2240964465.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.028869386567010989", - "max_rate": "0.190000000000000000", - "max_change_rate": "0.173195857712675899" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2x30aum6t8lauwqh72szktjx6fmgf5ux7vcs38uukp9a5h287wawhv5mfv", - "status": 3, - "tokens": "17377751306", - "delegator_shares": "17377751306.000000000000000000", - "description": { - "moniker": "SslqJkEqrN", - "identity": "qMdXPqvbCt", - "website": "HDwwjWlugU", - "security_contact": "LzWMObthwF", - "details": "zlyoRqwOQS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.498765541593724538", - "max_rate": "0.530000000000000000", - "max_change_rate": "0.156108348646223859" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtn32axxpw98r75zep2c0y45qf5fdgt0u334humpn08gxv0rxuya5ggzdsq", - "status": 1, - "tokens": "965626724", - "delegator_shares": "965626724.000000000000000000", - "description": { - "moniker": "QLuovrSeqS", - "identity": "YUQNkExwnl", - "website": "XdRdVvbQcS", - "security_contact": "bwGwmqdTzE", - "details": "IeauAPqpMI" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.020000000000000000", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.009367009125578098" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3lu0qw8kj", - "status": 3, - "tokens": "25431851328", - "delegator_shares": "25431851328.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.450461328836777178", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.254665389885134513" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwvyafhmcqnhjk3t6jzdah2rzaq2cqpmz9fgll8493g9nrpcxz4sc7um4ft", - "status": 1, - "tokens": "2479274676", - "delegator_shares": "2479274676.000000000000000000", - "description": { - "moniker": "ypOtLDecZT", - "identity": "LIaJHuYasM", - "website": "bYFtipdQBr", - "security_contact": "iMgHhjMBDk", - "details": "cOpQhsluAN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.525025256762086999", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.151736980542240639" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvtj36dsackmy4p87dys4377ysum2zku3v7tjqtf5jhluzgxk5vqqlcyug9", - "status": 1, - "tokens": "4394402323", - "delegator_shares": "4394402323.000000000000000000", - "description": { - "moniker": "UNrltmiFQU", - "identity": "HlRxPRAiWn", - "website": "miHKtnKEFq", - "security_contact": "GGQHyuiUNg", - "details": "SDyPeWiIir" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.423728810514445933", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcf30j9c", - "status": 3, - "tokens": "74690344989", - "delegator_shares": "74690344989.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.882630947578979215", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.960000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv9arcz0k33sqlng4lqppz6wjctjdpru7slvs2hrdhgagads37lr6xmuhma", - "status": 1, - "tokens": "5792662639", - "delegator_shares": "5792662639.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.930000000000000000", - "max_rate": "0.930000000000000000", - "max_change_rate": "0.196867569678551592" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdrcxqxr3pecujyd0zcx7hlhz3sgne5yrsc2d50rca9j87kuq9sdjp0hevd", - "status": 1, - "tokens": "1494931451", - "delegator_shares": "1494931451.000000000000000000", - "description": { - "moniker": "wpQIfxRBEt", - "identity": "RKTQHvPdJv", - "website": "iiJRommKHA", - "security_contact": "tglHlMyemj", - "details": "TKaMInrxao" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.523520119340770936", - "max_rate": "0.550000000000000000", - "max_change_rate": "0.245778725026844861" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr2mqfkju", - "status": 3, - "tokens": "27874325464", - "delegator_shares": "27874325464.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.459241580368376871", - "max_rate": "0.490000000000000000", - "max_change_rate": "0.448990769658695281" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngklt9fqt", - "status": 3, - "tokens": "68086107574", - "delegator_shares": "68086107574.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.280411773058535090", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.009358685901125498" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg32fxsuegycskpe8m8mzkatq2gn0ge2nalp20xfmvjds36g8rytst6p8gf", - "status": 1, - "tokens": "4710928894", - "delegator_shares": "4710928894.000000000000000000", - "description": { - "moniker": "uLphnQcEDA", - "identity": "seBSPjZpUV", - "website": "awrAGlbOAE", - "security_contact": "gpsZdtvwFl", - "details": "POIzbuYNCV" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.436432231066822901", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.169101910040208464" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf399d5j3n6kaexaha66ucrjr4agzvmk6xpyy54lhgqy486mhe7fwwdg6aq", - "status": 1, - "tokens": "243353645", - "delegator_shares": "243353645.000000000000000000", - "description": { - "moniker": "QzTJXyuVaj", - "identity": "QXgGvfesKW", - "website": "sKaGvCtuno", - "security_contact": "NjeTETgEPj", - "details": "FzKZiPFLWh" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.390000000000000000", - "max_rate": "0.390000000000000000", - "max_change_rate": "0.160488857709882419" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdq8fheeu", - "status": 3, - "tokens": "25446232136", - "delegator_shares": "25446232136.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.073669961838812257", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.338443455873010612" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdjuv3ql5rv5njym62quduw7554as4aa8seufp7f4zv6q28tds2e23v4cv5", - "status": 3, - "tokens": "35741739231", - "delegator_shares": "35741739231.000000000000000000", - "description": { - "moniker": "MoJgIrbTvT", - "identity": "rTfyDjhPlV", - "website": "fXpRItnlwS", - "security_contact": "tIlMCZPLDi", - "details": "QoSUrnFXNb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.037606710200997532", - "max_rate": "0.610000000000000000", - "max_change_rate": "0.432717335122536998" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgkr2p0m3r8u4xaeydfcgmy66nr6whqkfc3fjk7ja0uzw7jzyw46xyx2g7a", - "status": 1, - "tokens": "781062755", - "delegator_shares": "781062755.000000000000000000", - "description": { - "moniker": "bPnQNoLOAC", - "identity": "eGrzxmpmZa", - "website": "SlgcHbrMAz", - "security_contact": "BsjVMIwBin", - "details": "zMLZagxpxk" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.087145043936985654", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.080927128094101738" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwvhpfht", - "status": 3, - "tokens": "19637280062", - "delegator_shares": "19637280062.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118259925415637398", - "max_rate": "0.220000000000000000", - "max_change_rate": "0.176572964585642890" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwajn7v8p6zuv8er2l5c5qwa2v3c86xw8sfhrj37a7x8353g2jspw96p9d3", - "status": 1, - "tokens": "13977340603", - "delegator_shares": "13977340603.000000000000000000", - "description": { - "moniker": "ugAGsihPAs", - "identity": "lCGAuZlvpp", - "website": "ivFSJyyaTn", - "security_contact": "DkGOtlUJqP", - "details": "OFODgAEDSm" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.004938453040925394", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.181525749527416405" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd9mxy4p6jva75efmzsjq5avn59j4n829vx6x9stw90wzg9urga0q5mm74w", - "status": 1, - "tokens": "120397764", - "delegator_shares": "120397764.000000000000000000", - "description": { - "moniker": "rKEeOLDkzz", - "identity": "CgBOpqCLEH", - "website": "IfBZCIaRWP", - "security_contact": "XHLGNxVQTC", - "details": "cjdFwSbCaV" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.005104745061935176", - "max_rate": "0.170000000000000000", - "max_change_rate": "0.163097753090489709" - }, - "update_time": "9936-01-01T14:57:22Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2y0j3sd9kxmqftpqxy9enzjuyzn08t26d5nk02anpwc0hezkzg4xq6vwx8", - "status": 1, - "tokens": "251933", - "delegator_shares": "251933.000000000000000000", - "description": { - "moniker": "NGOcYLtISS", - "identity": "akbHHffdaS", - "website": "EZXoBquUYT", - "security_contact": "XxIIhbuOPH", - "details": "BrcWmsrUNr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.025882905606214690", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.274885458100718873" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvvw2e0mvvrp6sp2y07kk2azrnfl3a2yacq05u5w57z90qjp2ngrj63tfw6", - "status": 1, - "tokens": "9823873258", - "delegator_shares": "9823873258.000000000000000000", - "description": { - "moniker": "kRMkymEDSB", - "identity": "qvuRLMGzrH", - "website": "vSlfyjYpQg", - "security_contact": "AOPUJgQrWP", - "details": "ndFZXPlXMr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.276493152947542370", - "max_rate": "0.490000000000000000", - "max_change_rate": "0.212232519907549121" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwaazwez", - "status": 3, - "tokens": "56856814851", - "delegator_shares": "56856814851.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.093189165744722643", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.044880981942823250" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", - "consensus_pubkey": "cosmosvalconspub1addwnpepq06e0dm4ey2l32nxhrycaez68egwtmj69vtq0hp77e7tf6cplnjc5uvjqtz", - "status": 1, - "tokens": "763826873", - "delegator_shares": "763826873.000000000000000000", - "description": { - "moniker": "FazIurAKdA", - "identity": "DpgBYLokOo", - "website": "CQDlLgAfWV", - "security_contact": "zXchJRCdOD", - "details": "iJdiDWPcgF" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.375080598711455047", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.805841917945325981" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtcxreszx2wu4ngd3amegdgh9549fr4yh4mgvs862ea44ugjv0leywawqen", - "status": 2, - "tokens": "2013818817", - "delegator_shares": "2013818817.000000000000000000", - "description": { - "moniker": "kcMqvkQeGm", - "identity": "ZKjzktvrAj", - "website": "EzWzZovCJZ", - "security_contact": "hwPlfWocdU", - "details": "vvHigjWyJK" - }, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.307501014763216711", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.592156519673221532" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtdv8njc56rymptecue8px6hxff297xt83s6w3m6yn0txy0e49ghsfu6hdh", - "status": 1, - "tokens": "10038955625", - "delegator_shares": "10038955625.000000000000000000", - "description": { - "moniker": "YMPYcTfNXV", - "identity": "hwJcjMjrtB", - "website": "mYdBZQGfkx", - "security_contact": "IBEYReGdlN", - "details": "jvbaZBHbFK" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.570000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd53md7mk6edgy52e2svr0j93ugzvz9s29axp9mcktw4d02fjcy660zqv62", - "status": 1, - "tokens": "82979650", - "delegator_shares": "82979650.000000000000000000", - "description": { - "moniker": "rCudEObWgx", - "identity": "RjLfgqvGwZ", - "website": "pNtHQchsLt", - "security_contact": "HmjsKTdqTq", - "details": "pVMyagMPve" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.359117607212693417", - "max_rate": "0.820000000000000000", - "max_change_rate": "0.213068837225456325" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvj6juduaknlhehjt785gk6vkv8qhqykv5d6zupvwafe38t0unzxgsq9mau", - "status": 1, - "tokens": "9221698754", - "delegator_shares": "9221698754.000000000000000000", - "description": { - "moniker": "SPmeYRxezu", - "identity": "JsfdtwKgSS", - "website": "uCONZqLKzt", - "security_contact": "SydRJqnnUx", - "details": "ykuadWmGDn" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.699765412672875774", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.690273764477740955" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfw46rg95l70w7lekt8eh7szxr7ms8mfhqvz0ywnpc7fu25f6hj72g5rq2r", - "status": 1, - "tokens": "5682430", - "delegator_shares": "5682430.000000000000000000", - "description": { - "moniker": "NSWxSbDfbr", - "identity": "KHpPUqXLbX", - "website": "rqTuqhgzjv", - "security_contact": "duYWuBTCiB", - "details": "JvcmUaPwcV" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.098043346521204171", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.077862966399052363" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyvxmu04", - "status": 3, - "tokens": "36122807193", - "delegator_shares": "36122807193.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.414145633705698803", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.500000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd2gmrd8aux64z50e58tu00n3yjunvqduf4xv3g3p6j3wpuxddex59mpcfe", - "status": 3, - "tokens": "16807158123", - "delegator_shares": "16807158123.000000000000000000", - "description": { - "moniker": "ZHKMxyLBmy", - "identity": "EwvvJnavFX", - "website": "DHXlVcQLfr", - "security_contact": "cqkJGwinbb", - "details": "CwxLKqsDci" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.054776212220005616", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.012318363733558931" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2p3sa8dkvz36pz6nusjdhm9aqlnrrldrszzuqd5qy7ssqztn99ggqpcdlz", - "status": 3, - "tokens": "48540826744", - "delegator_shares": "48540826744.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003549575739989554", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.001119527935415439" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycjhwrn7", - "status": 3, - "tokens": "29401856985", - "delegator_shares": "29401856985.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.243341366114153903", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.628404054381210058" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdaa2szanfjwhzucqfj0ct7ljhc3kew8am3h8sr8wqzlnh8df06g5th460y", - "status": 3, - "tokens": "24697024268", - "delegator_shares": "24697024268.000000000000000000", - "description": { - "moniker": "XYWZXrqRDE", - "identity": "MFgElwSSlb", - "website": "ZPGkarWAml", - "security_contact": "dFzxEZXTfo", - "details": "HRGbXKBEeq" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.550000000000000000", - "max_change_rate": "0.376530136432859216" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgtrcqtxc62uk24ac873z7ns2gz75znes579xk2m0xzxpjqswh08kh6nrm0", - "status": 2, - "tokens": "15012824613", - "delegator_shares": "15012824613.000000000000000000", - "description": { - "moniker": "TzIitNrGWU", - "identity": "UtpzgJMsxj", - "website": "KMxjEKqFGe", - "security_contact": "GczmfoVPHm", - "details": "fMoGrNqroM" - }, - "unbonding_height": "48", - "unbonding_time": "9936-01-04T18:13:47Z", - "commission": { - "commission_rates": { - "rate": "0.413119742047134521", - "max_rate": "0.590000000000000000", - "max_change_rate": "0.590000000000000000" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdefatxypu4fp0z52tp76zfp6sjx0feg8ffe5res6pxs520evrxdca7fxy2", - "status": 1, - "tokens": "228354642", - "delegator_shares": "228354642.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.313619258562376348", - "max_rate": "0.510000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w4r0vhq", - "status": 3, - "tokens": "41494205421", - "delegator_shares": "41494205421.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.070000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0qr3zl5rz8qxk4863w768w20vr6gx26sh7uxr5fvvv7d68jjr805eaavkr", - "status": 1, - "tokens": "1820280319", - "delegator_shares": "1820280319.000000000000000000", - "description": { - "moniker": "larTIwdGYJ", - "identity": "oQxxPrmfak", - "website": "tPGPkwLtUK", - "security_contact": "mbyBenqFQd", - "details": "wKOwWlCXff" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.213795341271049705", - "max_rate": "0.380000000000000000", - "max_change_rate": "0.007958552197021359" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0p5kfy8kvyj0rl0lguwv5fmqwpsa5cg7gm8mzldlej5smsm6hhmqpjf6fz", - "status": 1, - "tokens": "2580293599", - "delegator_shares": "2580293599.000000000000000000", - "description": {}, - "unbonding_height": "8", - "unbonding_time": "9936-01-01T08:58:43Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgc0dahup", - "status": 3, - "tokens": "39420206132", - "delegator_shares": "39420206132.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.109747630034489371", - "max_rate": "0.970000000000000000", - "max_change_rate": "0.461346401411912639" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkn6paax", - "status": 3, - "tokens": "23703504292", - "delegator_shares": "23703504292.000000000000000000", - "description": { - "moniker": "eXfwGKuzGb", - "identity": "dYpMrjwrPA", - "website": "DzaFOsditE", - "security_contact": "GuNLPoNZsM", - "details": "iALsKeROvR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.087538799057934086", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.859363741701174499" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyt542en", - "status": 3, - "tokens": "69725274862", - "delegator_shares": "69725274862.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.077835183941357357", - "max_rate": "0.630000000000000000", - "max_change_rate": "0.287966636331923139" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwfq28wcw9gn3mynr4pjdpd5hhert9hheg8qus862ymrt5ex6j75jlkuhe3", - "status": 3, - "tokens": "21764467799", - "delegator_shares": "21764467799.000000000000000000", - "description": { - "moniker": "ObWwGUpRaY", - "identity": "BCfhwnVexY", - "website": "SBehiPUtRR", - "security_contact": "jMhyvuyFaP", - "details": "LHYAZFxdaS" - }, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.075332177620667120", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.039077923270826524" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwa4x4g5600flnra6sk3xek8rqvuxsgcl2e6mh500hd5ukvn5hea2vkwtcq", - "status": 1, - "tokens": "227804730", - "delegator_shares": "227804730.000000000000000000", - "description": { - "moniker": "OREyTcVRpI", - "identity": "qZaHHICplm", - "website": "qLLvRrRHco", - "security_contact": "jAyHoSHCWl", - "details": "CIyKCjIsrZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.090000000000000000", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsrp7s99", - "status": 3, - "tokens": "25229713771", - "delegator_shares": "25229713771.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.420000000000000000", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.006473324874363207" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2u42wlmn9vx90thlzxmuckxdqt93w6ekdghk9v3rr8jvpp28tghvaxdzey", - "status": 1, - "tokens": "1397104980", - "delegator_shares": "1397104980.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.155081394052318110", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd5jsj53j7m0umzvh90dwanxhfxmpydhfazmsz978v9yuh05q0kxcyqtdla", - "status": 3, - "tokens": "16747268503", - "delegator_shares": "16747268503.000000000000000000", - "description": { - "moniker": "OuShqctNnC", - "identity": "MfQbnbeXdv", - "website": "OfOpteXCQn", - "security_contact": "qaSLhJmnUG", - "details": "vIuRzAnYuu" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.589668369513377579", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.640000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgd00cmdzck03zpu4vjerhqt8tp0th04ccpqyesxp93lgef9u4vzusmxtma", - "status": 1, - "tokens": "300592036", - "delegator_shares": "300592036.000000000000000000", - "description": { - "moniker": "JLCFllOWaH", - "identity": "xmzLNprDNm", - "website": "TuCltfQyUl", - "security_contact": "FnFBACeLgN", - "details": "QpBCVOFYRe" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.024279357344684238", - "max_rate": "0.210000000000000000", - "max_change_rate": "0.162470067092097594" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge726q0dwq", - "status": 3, - "tokens": "56914095343", - "delegator_shares": "56914095343.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.561558403350280399", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.088588598076790894" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzwg260rcucyql9q6rnkhayydygkjxk7ly526ue3nwsz356fe38jvhpztz", - "status": 1, - "tokens": "8325722649", - "delegator_shares": "8325722649.000000000000000000", - "description": { - "moniker": "DKkqNgpern", - "identity": "UaPNJrTXWa", - "website": "CRmVrQLcHP", - "security_contact": "simjpTROho", - "details": "LenVFOISIL" - }, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.308481491073534819", - "max_rate": "0.790000000000000000", - "max_change_rate": "0.724731225510437678" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwkc23a70ndeeapn057plztghd0udz8jvf06nxym6tzd305p2kgux9nw52y", - "status": 1, - "tokens": "4497117544", - "delegator_shares": "4497117544.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.128390426870278035", - "max_rate": "0.550000000000000000", - "max_change_rate": "0.236783251632041598" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvpvaw73dlelg9r4uclgtvvylvfysht9usz0wgsvrl5ztsca98fwuv8vekl", - "status": 1, - "tokens": "340930766", - "delegator_shares": "340930766.000000000000000000", - "description": { - "moniker": "GtnANTFzsD", - "identity": "mQAnJjWMXZ", - "website": "klPpVMalzv", - "security_contact": "ZlKqUPcaKh", - "details": "BvqBMmsKnj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.460000000000000000", - "max_rate": "0.460000000000000000", - "max_change_rate": "0.177656813330873825" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0us7fav4", - "status": 3, - "tokens": "53587404091", - "delegator_shares": "53587404091.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.148502470554898869", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.005661642347781868" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw32mxlzzzmmpks775cgclcsmypqhhz7765v03wnjf8cn4hsrw67tq2l8n", - "status": 3, - "tokens": "20301516153", - "delegator_shares": "20301516153.000000000000000000", - "description": { - "moniker": "ibdjDFXkFg", - "identity": "BhaqDbDPwH", - "website": "KoHplbnTSd", - "security_contact": "zgJBSepZRt", - "details": "anTLerUmWY" - }, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.092279263137073204", - "max_rate": "0.130000000000000000", - "max_change_rate": "0.062347977318301413" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4umtaftt", - "status": 3, - "tokens": "23438430919", - "delegator_shares": "23438430919.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.065104244001935780", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.087973256413395308" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "consensus_pubkey": "cosmosvalconspub1addwnpepqddlzxsvj50jm6uwsp29nua35j2ntam89f4gt28g2emwgvl5s786j7wgqf0", - "status": 1, - "tokens": "570046687", - "delegator_shares": "570046687.000000000000000000", - "description": { - "moniker": "czRmrRUsJE", - "identity": "UUVYRGhvlH", - "website": "IbvDgUUmEa", - "security_contact": "OGaCohwkPO", - "details": "yzqmTabmKs" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.115576668318745733", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.114266089646617209" - }, - "update_time": "9936-01-01T16:55:11Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wu8lrdvr", - "status": 3, - "tokens": "23476663612", - "delegator_shares": "23476663612.000000000000000000", - "description": { - "moniker": "qNlNvDKQWh", - "identity": "PdEEmVXzOP", - "website": "jyQRsxutdI", - "security_contact": "hTNdvfWkVQ", - "details": "gPNrXPrkeL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.830000000000000000", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.679717803083962746" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7pax9cuqs5vjjvhpmcgvy5dkqrrtrg6336c3xhyrchtegy2m387ccs037", - "status": 3, - "tokens": "19815525788", - "delegator_shares": "19815525788.000000000000000000", - "description": { - "moniker": "sJKzLUYWBq", - "identity": "ZzbWnFqPTq", - "website": "dlevXyAGdk", - "security_contact": "bnQNzwNRYP", - "details": "PaxiDbFCJj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.291627565410574418", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.017987067010819344" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd7yjw34urmgndhr8r8xr2pclxfx0djpjd0vtfgs3swpdwzprcjczjux4qs", - "status": 1, - "tokens": "657819384", - "delegator_shares": "657819384.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.075522174018022400", - "max_rate": "0.210000000000000000", - "max_change_rate": "0.001608427283172174" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd52427v4hwje032xlsv6gfzv6pa2247jeawtjwhnxndvczv8hhxck575j5", - "status": 1, - "tokens": "1028714701", - "delegator_shares": "1028714701.000000000000000000", - "description": { - "moniker": "HqyxoHhEFh", - "identity": "jWSGBNVszf", - "website": "dEzhiLdOIf", - "security_contact": "hyFJYpqAZe", - "details": "seLogPTgsK" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.029467520966307114", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.041496100825162181" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wel7d3l", - "status": 3, - "tokens": "25456865344", - "delegator_shares": "25456865344.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.293848609442759777", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.580000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6u59lzkg", - "status": 3, - "tokens": "44085124225", - "delegator_shares": "44085124225.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.045106108515206331", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.610987430943531252" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw6x8r9cuvkvguqdx24myp74yx7pxgsg2yfl7eqgghyspvqw2tylqrwrrad", - "status": 1, - "tokens": "12285580824", - "delegator_shares": "12285580824.000000000000000000", - "description": { - "moniker": "HzzzbNxxpx", - "identity": "ViiQdXCLBW", - "website": "OCLfzPwTWp", - "security_contact": "DfUgOxcVro", - "details": "RHrQEtzJzW" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.670000000000000000", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.575718185703869257" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xvdql9k", - "status": 3, - "tokens": "25311353934", - "delegator_shares": "25311353934.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.324580145668396309", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.480000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfd79ep9f3sj30yn4uvl5f65q6dzmddudu5a3m0szgpwlv3hjr0a6xrqhrg", - "status": 1, - "tokens": "3907335026", - "delegator_shares": "3907335026.000000000000000000", - "description": { - "moniker": "uXaNxxYTMQ", - "identity": "QJMnxUPYAd", - "website": "hkagAIrRvX", - "security_contact": "XEmGZxAkJW", - "details": "CyRBAsyicI" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.704312781551764893", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.631767833516112273" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdwm9nyqsl6vc99mf2mmsmuj5384f46a8jp797fcp49qgpuzkaqx509kf4a", - "status": 1, - "tokens": "10574606405", - "delegator_shares": "10574606405.000000000000000000", - "description": { - "moniker": "gEfoUrxzet", - "identity": "xjndEwlJFY", - "website": "IKwYkWCXHD", - "security_contact": "CXolURKfuk", - "details": "ToBdMlGWCh" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.226837298095829297", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.124175068502619156" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujgucg2ktdn", - "status": 3, - "tokens": "32745806516", - "delegator_shares": "32745806516.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.322505571100731689", - "max_rate": "0.520000000000000000", - "max_change_rate": "0.183472725952677048" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592jkkxzm", - "status": 3, - "tokens": "21858111883", - "delegator_shares": "21858111883.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.799310131872627643", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.706235617003159879" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxtyq8dz", - "status": 3, - "tokens": "28684472849", - "delegator_shares": "28684472849.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.174404138163737710", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.360000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - } - ], - "delegations": [ - { - "delegator_address": "cosmos1qqxeqqvjkh2ls3a0taukd8rydrqqad690nxkcc", - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "shares": "12420219756.000000000000000000" - }, - { - "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", - "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "shares": "4141412671.000000000000000000" - }, - { - "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "shares": "61614117.000000000000000000" - }, - { - "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "shares": "138733335.000000000000000000" - }, - { - "delegator_address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "shares": "5978697013.000000000000000000" - }, - { - "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "shares": "6479198849.000000000000000000" - }, - { - "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "shares": "331591913.000000000000000000" - }, - { - "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "shares": "2560223943.000000000000000000" - }, - { - "delegator_address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "shares": "9192729008.000000000000000000" - }, - { - "delegator_address": "cosmos1qy0qwzljplfauvyhgayw6nxte2zxujh4tnq09z", - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "shares": "17076084961.000000000000000000" - }, - { - "delegator_address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "shares": "8265210908.000000000000000000" - }, - { - "delegator_address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "shares": "3423234396.000000000000000000" - }, - { - "delegator_address": "cosmos1q9ed2n5wvzcrymaqltypazqzd2xv8d5aw58flt", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", - "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "shares": "8434736549.000000000000000000" - }, - { - "delegator_address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "shares": "11322194414.000000000000000000" - }, - { - "delegator_address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429", - "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "shares": "17931279589.000000000000000000" - }, - { - "delegator_address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "shares": "9657784018.000000000000000000" - }, - { - "delegator_address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "shares": "9950725535.000000000000000000" - }, - { - "delegator_address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "shares": "250632594.000000000000000000" - }, - { - "delegator_address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "shares": "24818709486.000000000000000000" - }, - { - "delegator_address": "cosmos1q0cw6hmrm4myx5c3zzmw6deelygsl2hrts2ju4", - "validator_address": "cosmosvaloper1q0cw6hmrm4myx5c3zzmw6deelygsl2hrwy78sx", - "shares": "998337488.000000000000000000" - }, - { - "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "shares": "14607898235.000000000000000000" - }, - { - "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "shares": "1211564528.000000000000000000" - }, - { - "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "shares": "1294419142.000000000000000000" - }, - { - "delegator_address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "shares": "12945220697.000000000000000000" - }, - { - "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", - "validator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "shares": "15545552914.000000000000000000" - }, - { - "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "shares": "6110815364.000000000000000000" - }, - { - "delegator_address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "shares": "26325596.000000000000000000" - }, - { - "delegator_address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", - "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", - "shares": "632273041.000000000000000000" - }, - { - "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "shares": "393807838.000000000000000000" - }, - { - "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", - "validator_address": "cosmosvaloper1qj464sdtg245k3leszy29lh27h3texnhfmtj9c", - "shares": "847666854.000000000000000000" - }, - { - "delegator_address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "shares": "12287749425.000000000000000000" - }, - { - "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "shares": "924245075.000000000000000000" - }, - { - "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "shares": "809035601.000000000000000000" - }, - { - "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "shares": "78323397.000000000000000000" - }, - { - "delegator_address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "shares": "38918270.000000000000000000" - }, - { - "delegator_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", - "validator_address": "cosmosvaloper1q54ra6ur0wgyamdtgkn7fnmawf00tcj6vlchup", - "shares": "1750195180.000000000000000000" - }, - { - "delegator_address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "shares": "4025204231.000000000000000000" - }, - { - "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", - "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "shares": "4432663925.000000000000000000" - }, - { - "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "shares": "20636678155.000000000000000000" - }, - { - "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "shares": "3413891512.012381154639588436" - }, - { - "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "shares": "6251197681.000000000000000000" - }, - { - "delegator_address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "shares": "7134357042.000000000000000000" - }, - { - "delegator_address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "shares": "2196379282.000000000000000000" - }, - { - "delegator_address": "cosmos1q6eeennfulay5kz3lym38up6gq5ruf6h43cg94", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "shares": "17332637313.000000000000000000" - }, - { - "delegator_address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "shares": "4686886799.000000000000000000" - }, - { - "delegator_address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "shares": "20382455281.000000000000000000" - }, - { - "delegator_address": "cosmos1qlkz3yutzuz0el2ullpyyaflfp78x8rr2cgld7", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "shares": "24971252484.000000000000000000" - }, - { - "delegator_address": "cosmos1py3htj8kmztj0ecdrhcgcmet6vupr9hvlhxkwe", - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "shares": "21846969213.000000000000000000" - }, - { - "delegator_address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "shares": "17451346039.000000000000000000" - }, - { - "delegator_address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "shares": "43687807.000000000000000000" - }, - { - "delegator_address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "shares": "18580691943.000000000000000000" - }, - { - "delegator_address": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", - "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "shares": "24914473521.000000000000000000" - }, - { - "delegator_address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "shares": "9687342330.000000000000000000" - }, - { - "delegator_address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "shares": "2725727123.000000000000000000" - }, - { - "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "shares": "107356796.000000000000000000" - }, - { - "delegator_address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "shares": "652452.000000000000000000" - }, - { - "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", - "validator_address": "cosmosvaloper1p0u57pfl53kwefqrrr652pd3sm2hhv9gkq3szl", - "shares": "5044911319.000000000000000000" - }, - { - "delegator_address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "shares": "11344768409.000000000000000000" - }, - { - "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "shares": "22896384744.000000000000000000" - }, - { - "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "shares": "2172957336.000000000000000000" - }, - { - "delegator_address": "cosmos1pca5ng2s37clfh72ea806j9fwvpng4fjq3ey5s", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "shares": "15497814344.000000000000000000" - }, - { - "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", - "validator_address": "cosmosvaloper1zpsu55hh9prdl4zw7dmemtmaqhxc9w3l8uncln", - "shares": "203339835.000000000000000000" - }, - { - "delegator_address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "shares": "23419734247.000000000000000000" - }, - { - "delegator_address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "shares": "4778016243.000000000000000000" - }, - { - "delegator_address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "shares": "20291325837.000000000000000000" - }, - { - "delegator_address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "shares": "1415578984.000000000000000000" - }, - { - "delegator_address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", - "validator_address": "cosmosvaloper1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ugqcmee", - "shares": "7304584820.000000000000000000" - }, - { - "delegator_address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c", - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "shares": "1670822058.000000000000000000" - }, - { - "delegator_address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", - "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", - "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "shares": "30094589894.000000000000000000" - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "shares": "1195742287.000000000000000000" - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "shares": "1246069516.000000000000000000" - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "shares": "1455198371.000000000000000000" - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "shares": "1517022388.000000000000000000" - }, - { - "delegator_address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "shares": "1056544107.000000000000000000" - }, - { - "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "shares": "22844129667.000000000000000000" - }, - { - "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "shares": "38719909925.000000000000000000" - }, - { - "delegator_address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "shares": "2225212413.000000000000000000" - }, - { - "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "shares": "12278061721.000000000000000000" - }, - { - "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "validator_address": "cosmosvaloper1zg7fduehxe98ny57l2rtdv8xxas25kyhl00ylj", - "shares": "101462019.000000000000000000" - }, - { - "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "shares": "49181074.000000000000000000" - }, - { - "delegator_address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "shares": "5174807457.000000000000000000" - }, - { - "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "shares": "19076209513.000000000000000000" - }, - { - "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "shares": "686761769.000000000000000000" - }, - { - "delegator_address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "shares": "5993132567.000000000000000000" - }, - { - "delegator_address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", - "validator_address": "cosmosvaloper1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx0sq3dg", - "shares": "5183376555.000000000000000000" - }, - { - "delegator_address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "shares": "63638410.000000000000000000" - }, - { - "delegator_address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "shares": "1793233946.000000000000000000" - }, - { - "delegator_address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "shares": "13273588734.000000000000000000" - }, - { - "delegator_address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "shares": "7610845.000000000000000000" - }, - { - "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "shares": "6189191937.000000000000000000" - }, - { - "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "shares": "1085633282.000000000000000000" - }, - { - "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "shares": "735588360.000000000000000000" - }, - { - "delegator_address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "shares": "18880150143.000000000000000000" - }, - { - "delegator_address": "cosmos1zsspke0nqudcl0lh747ppqcsy396245akc2vtl", - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "shares": "28973013721.000000000000000000" - }, - { - "delegator_address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6", - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "shares": "27081595327.000000000000000000" - }, - { - "delegator_address": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1zjzkk7l2jalrspy6500my8v0yy6ycz7el534zw", - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "shares": "562972916.000000000000000000" - }, - { - "delegator_address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "shares": "15744595023.000000000000000000" - }, - { - "delegator_address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "shares": "7684584877.000000000000000000" - }, - { - "delegator_address": "cosmos1znvq8jqpwxt5hk2lg5654l7eg7kap3rpgjm462", - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "shares": "13141132625.000000000000000000" - }, - { - "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", - "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "shares": "1866755172.000000000000000000" - }, - { - "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "shares": "1630410562.000000000000000000" - }, - { - "delegator_address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "shares": "6990856673.000000000000000000" - }, - { - "delegator_address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", - "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "shares": "4660200511.000000000000000000" - }, - { - "delegator_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "shares": "1580119322.000000000000000000" - }, - { - "delegator_address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", - "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "shares": "376238441.000000000000000000" - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "shares": "7302955.000000000000000000" - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1z6f7gdevn6dfvpls7tlqmqmzr54le7a4fl087z", - "shares": "5951502740.000000000000000000" - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "shares": "3978844161.000000000000000000" - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "shares": "2714965216.000000000000000000" - }, - { - "delegator_address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "shares": "13283049905.000000000000000000" - }, - { - "delegator_address": "cosmos1zu50umwgah6jhx07sw04ry0pv7fnvkpjmn8vl9", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "shares": "10178017385.000000000000000000" - }, - { - "delegator_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "shares": "927515526.000000000000000000" - }, - { - "delegator_address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "shares": "7100496609.000000000000000000" - }, - { - "delegator_address": "cosmos1zah0g92ytwdvpchd3sceuanu7knhtu224vnt5k", - "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "shares": "17763934255.000000000000000000" - }, - { - "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", - "validator_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "shares": "1856911069.000000000000000000" - }, - { - "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "shares": "11887809820.000000000000000000" - }, - { - "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "shares": "9843285414.000000000000000000" - }, - { - "delegator_address": "cosmos1z7ruhrtfg8v2xv8egfyxldt2xaygspykszntzv", - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "shares": "984669335.000000000000000000" - }, - { - "delegator_address": "cosmos1z7sj5sg2cnkg4phzrswwjkkq8p2d6434pcyv2p", - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "shares": "404583402.000000000000000000" - }, - { - "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "validator_address": "cosmosvaloper1zlyfewtaxumsyj34fkml4t54yvhqcls4ud0gl6", - "shares": "9436725725.000000000000000000" - }, - { - "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "shares": "3355273089.000000000000000000" - }, - { - "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "shares": "3814662227.000000000000000000" - }, - { - "delegator_address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "shares": "1933530153.000000000000000000" - }, - { - "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "shares": "141624981.000000000000000000" - }, - { - "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "shares": "18814602669.000000000000000000" - }, - { - "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "shares": "2514756351.000000000000000000" - }, - { - "delegator_address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "shares": "6254739411.000000000000000000" - }, - { - "delegator_address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg", - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "shares": "10514537848.000000000000000000" - }, - { - "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "shares": "5810217010.000000000000000000" - }, - { - "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "shares": "1887976035.000000000000000000" - }, - { - "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "shares": "10725445.000000000000000000" - }, - { - "delegator_address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "shares": "952138064.000000000000000000" - }, - { - "delegator_address": "cosmos1ryp2xkqe74y5kx6zffqtdc3wzgny8xg8eguupq", - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "shares": "1639136540.000000000000000000" - }, - { - "delegator_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "shares": "16848374286.000000000000000000" - }, - { - "delegator_address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "shares": "5561406384.000000000000000000" - }, - { - "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "shares": "798486027.000000000000000000" - }, - { - "delegator_address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "shares": "12788946759.000000000000000000" - }, - { - "delegator_address": "cosmos1rtw2ev4xm89vaqzwc7k520jlvrvlqnevk5f53y", - "validator_address": "cosmosvaloper1rtw2ev4xm89vaqzwc7k520jlvrvlqnevnqapah", - "shares": "12268746738.000000000000000000" - }, - { - "delegator_address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "shares": "2032334424.000000000000000000" - }, - { - "delegator_address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", - "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "shares": "3185714296.000000000000000000" - }, - { - "delegator_address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "shares": "1936045503.000000000000000000" - }, - { - "delegator_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", - "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "shares": "1620479191.000000000000000000" - }, - { - "delegator_address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", - "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "shares": "10162772165.000000000000000000" - }, - { - "delegator_address": "cosmos1r572vr0k388gpjw5h2u75ppmarvgma20rqj2ws", - "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "shares": "16932030948.000000000000000000" - }, - { - "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", - "validator_address": "cosmosvaloper1r4czpmmu87t7zhlh34zrzna9gkex4ap5dn7gr3", - "shares": "12584124.000000000000000000" - }, - { - "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "shares": "9220026.000000000000000000" - }, - { - "delegator_address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "shares": "694971203.000000000000000000" - }, - { - "delegator_address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "shares": "19004884526.000000000000000000" - }, - { - "delegator_address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", - "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "shares": "2041910728.000000000000000000" - }, - { - "delegator_address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "shares": "8361945358.000000000000000000" - }, - { - "delegator_address": "cosmos1rcru2vteas2kunww3zt4knx28krlestxydpwza", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "shares": "20016004053.000000000000000000" - }, - { - "delegator_address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1r6j2xkpnnjve9c00c854laqp7l7zv8pxeksxrz", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "shares": "20554160964.000000000000000000" - }, - { - "delegator_address": "cosmos1rmyk79ktv6c8q48u78udw5p906fp0w058796d0", - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "shares": "251069497.000000000000000000" - }, - { - "delegator_address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", - "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "shares": "3033965094.000000000000000000" - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "shares": "11989838708.000000000000000000" - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "shares": "2071677267.000000000000000000" - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "shares": "510250360.000000000000000000" - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "shares": "2727283744.000000000000000000" - }, - { - "delegator_address": "cosmos1r7kh63jvjhwqraux9wtm3jat8ggm437w9cxcxc", - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "shares": "1576771801.000000000000000000" - }, - { - "delegator_address": "cosmos1rlzurkn0mywyldswcafhu7r8r0tha4s5prs34u", - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "shares": "5545092214.000000000000000000" - }, - { - "delegator_address": "cosmos1rlltvm5ks32kh683c0w7epsjvg8aq2hvct27p6", - "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "shares": "71917474.000000000000000000" - }, - { - "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "shares": "3140280772.000000000000000000" - }, - { - "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "shares": "14337017011.000000000000000000" - }, - { - "delegator_address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "shares": "4008660259.000000000000000000" - }, - { - "delegator_address": "cosmos1yrdtzqfkyum94q4v3j3xllrtf09qv0jvympw86", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "shares": "3161698569.000000000000000000" - }, - { - "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "shares": "1615518832.000000000000000000" - }, - { - "delegator_address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "shares": "16529399133.000000000000000000" - }, - { - "delegator_address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", - "validator_address": "cosmosvaloper1yt9s823gnqayrjasrra5j43pj9c48ae9uju4c7", - "shares": "5346735375.000000000000000000" - }, - { - "delegator_address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "shares": "9559582899.000000000000000000" - }, - { - "delegator_address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933", - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "shares": "18217843326.000000000000000000" - }, - { - "delegator_address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", - "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "shares": "35129356.000000000000000000" - }, - { - "delegator_address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "shares": "5083047390.000000000000000000" - }, - { - "delegator_address": "cosmos1y3h72de80x06cz7fs3adwlnp0r8pjazw0r5707", - "validator_address": "cosmosvaloper1y3h72de80x06cz7fs3adwlnp0r8pjazw2hqtrd", - "shares": "3323388806.000000000000000000" - }, - { - "delegator_address": "cosmos1yj95f65syc75ptwcy0n7kafdq33awc2ve8hthq", - "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "shares": "313632363.000000000000000000" - }, - { - "delegator_address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a", - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "shares": "5078782917.000000000000000000" - }, - { - "delegator_address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "shares": "5608632459.000000000000000000" - }, - { - "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "shares": "2320211243.000000000000000000" - }, - { - "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "shares": "1727917227.000000000000000000" - }, - { - "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "shares": "1444898370.000000000000000000" - }, - { - "delegator_address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "shares": "1561395724.000000000000000000" - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "shares": "5799285.000000000000000000" - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "shares": "5780519.000000000000000000" - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "shares": "19002817.000000000000000000" - }, - { - "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "shares": "12299732605.000000000000000000" - }, - { - "delegator_address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "shares": "12769609475.000000000000000000" - }, - { - "delegator_address": "cosmos1ylf26t6vhvugawg87328ng2ug4d8f25syxp64c", - "validator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "shares": "24248574347.000000000000000000" - }, - { - "delegator_address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "shares": "7050196605.000000000000000000" - }, - { - "delegator_address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", - "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "shares": "4574405710.000000000000000000" - }, - { - "delegator_address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", - "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "shares": "86630682.000000000000000000" - }, - { - "delegator_address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", - "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "shares": "22058794240.000000000000000000" - }, - { - "delegator_address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "shares": "13382062777.000000000000000000" - }, - { - "delegator_address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "shares": "11687279303.000000000000000000" - }, - { - "delegator_address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "shares": "14549776414.000000000000000000" - }, - { - "delegator_address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", - "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "shares": "8566436836.000000000000000000" - }, - { - "delegator_address": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "shares": "5053223393.000000000000000000" - }, - { - "delegator_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "shares": "4129974295.000000000000000000" - }, - { - "delegator_address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "shares": "681974899.000000000000000000" - }, - { - "delegator_address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", - "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "shares": "2510854249.000000000000000000" - }, - { - "delegator_address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "shares": "4659214363.000000000000000000" - }, - { - "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", - "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", - "shares": "2439056961.000000000000000000" - }, - { - "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", - "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "shares": "2600875484.000000000000000000" - }, - { - "delegator_address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "shares": "2726229723.000000000000000000" - }, - { - "delegator_address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "shares": "22343112357.000000000000000000" - }, - { - "delegator_address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "shares": "19543436761.000000000000000000" - }, - { - "delegator_address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "shares": "3468306722.000000000000000000" - }, - { - "delegator_address": "cosmos19deqn6g9q7mnhzg5j0qr25k9gz74pwlph5p50r", - "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "shares": "2125901000.000000000000000000" - }, - { - "delegator_address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "shares": "13749317760.000000000000000000" - }, - { - "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "validator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "shares": "671769813.000000000000000000" - }, - { - "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "validator_address": "cosmosvaloper190kcpcyvl46xva8ya8vs5wmmg4nygvutskw4mp", - "shares": "290004202.000000000000000000" - }, - { - "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "shares": "852563445.000000000000000000" - }, - { - "delegator_address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "shares": "22141837134.000000000000000000" - }, - { - "delegator_address": "cosmos193pvwgxpxnd6tgz0gtyl00dq8r3ygeflnhaxpm", - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos194x33ngarpaach5g69g60cd2pjq8h0hqkfvk35", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "shares": "2698972611.000000000000000000" - }, - { - "delegator_address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", - "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "shares": "3111978.000000000000000000" - }, - { - "delegator_address": "cosmos1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75pf45v0", - "validator_address": "cosmosvaloper1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75yappqu", - "shares": "5061822.000000000000000000" - }, - { - "delegator_address": "cosmos1xq58llsgh49tsz22grs28jk0p7tvswlcjcrl32", - "validator_address": "cosmosvaloper1xq58llsgh49tsz22grs28jk0p7tvswlchvh2ae", - "shares": "2859472400.000000000000000000" - }, - { - "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "shares": "96280874.000000000000000000" - }, - { - "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "shares": "3878595385.000000000000000000" - }, - { - "delegator_address": "cosmos1xxurm2uymwd04sjxqedjae5r0zxhalh26skxct", - "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "shares": "8374503099.000000000000000000" - }, - { - "delegator_address": "cosmos1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalavv03x7", - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "shares": "41888452.000000000000000000" - }, - { - "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "shares": "16141764494.000000000000000000" - }, - { - "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "shares": "3922123176.000000000000000000" - }, - { - "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "shares": "562769066.000000000000000000" - }, - { - "delegator_address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", - "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "shares": "2583372381.000000000000000000" - }, - { - "delegator_address": "cosmos1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lpz963de", - "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "shares": "6669322099.000000000000000000" - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "shares": "23065486708.000000000000000000" - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper1xjf53m679qpvrg95pz4zn8yr63tj4nyyl5gedt", - "shares": "1751100.000000000000000000" - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "shares": "7682598.000000000000000000" - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "shares": "40546790.000000000000000000" - }, - { - "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "shares": "15549849.000000000000000000" - }, - { - "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", - "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "shares": "85878287.000000000000000000" - }, - { - "delegator_address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "shares": "114707626.000000000000000000" - }, - { - "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "shares": "213312801.000000000000000000" - }, - { - "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "shares": "421593670.000000000000000000" - }, - { - "delegator_address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "shares": "19101606110.000000000000000000" - }, - { - "delegator_address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", - "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "shares": "7824280124.000000000000000000" - }, - { - "delegator_address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", - "validator_address": "cosmosvaloper1xec6kclrpkc4ws7lwf5j0u8207nyg6dzhf4vgw", - "shares": "13735096388.000000000000000000" - }, - { - "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "shares": "1199565347.000000000000000000" - }, - { - "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "shares": "789297947.000000000000000000" - }, - { - "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "shares": "100158705.000000000000000000" - }, - { - "delegator_address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "shares": "23869776733.000000000000000000" - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "shares": "2944397287.000000000000000000" - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "shares": "88293788.000000000000000000" - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "shares": "183795109.000000000000000000" - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "shares": "19236564.000000000000000000" - }, - { - "delegator_address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "shares": "21819398696.000000000000000000" - }, - { - "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", - "validator_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "shares": "127648169.000000000000000000" - }, - { - "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", - "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "shares": "9032281.000000000000000000" - }, - { - "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "shares": "1406012334.000000000000000000" - }, - { - "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", - "validator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "shares": "18778025755.000000000000000000" - }, - { - "delegator_address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "shares": "3502640543.000000000000000000" - }, - { - "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "shares": "3559099530.000000000000000000" - }, - { - "delegator_address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "shares": "463086222.000000000000000000" - }, - { - "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", - "validator_address": "cosmosvaloper18z9fxr2nhp9h2ywqdyq6j2ate0aeupudm5u3a6", - "shares": "1577104716.000000000000000000" - }, - { - "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "shares": "12679288910.000000000000000000" - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "shares": "1128230444.000000000000000000" - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "shares": "823335564.000000000000000000" - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "shares": "22035723908.000000000000000000" - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "shares": "138442642.000000000000000000" - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "shares": "730434945.000000000000000000" - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "shares": "240453816.000000000000000000" - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "shares": "943974869.000000000000000000" - }, - { - "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", - "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "shares": "81607574.000000000000000000" - }, - { - "delegator_address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "shares": "24356273620.000000000000000000" - }, - { - "delegator_address": "cosmos188yd2umzwfwen7es68wrlh6auu3p8jhz0qfgej", - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "shares": "786295043.000000000000000000" - }, - { - "delegator_address": "cosmos18gmd4r8ydls55yvgda4d8pfandk0xem5q7eat8", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "shares": "19225895723.000000000000000000" - }, - { - "delegator_address": "cosmos18fkw6s4hnj2llxljrkleetgns2y0h0vjg8kmef", - "validator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "shares": "29256610441.000000000000000000" - }, - { - "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "shares": "12146467079.000000000000000000" - }, - { - "delegator_address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "shares": "7709220756.000000000000000000" - }, - { - "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "shares": "5080809691.000000000000000000" - }, - { - "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "shares": "614084859.000000000000000000" - }, - { - "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", - "validator_address": "cosmosvaloper18dh648kgh2zpwkdkr4cg3x50ruzucv60682dut", - "shares": "859335658.000000000000000000" - }, - { - "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "shares": "503691456.000000000000000000" - }, - { - "delegator_address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "shares": "951735771.000000000000000000" - }, - { - "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "shares": "187053499.000000000000000000" - }, - { - "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "shares": "87813996.000000000000000000" - }, - { - "delegator_address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", - "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "shares": "40933654.000000000000000000" - }, - { - "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "shares": "233343713.000000000000000000" - }, - { - "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "shares": "8989585334.000000000000000000" - }, - { - "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "shares": "7210211965.000000000000000000" - }, - { - "delegator_address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "shares": "419006947.000000000000000000" - }, - { - "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "shares": "1418840382.000000000000000000" - }, - { - "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "shares": "9132286197.000000000000000000" - }, - { - "delegator_address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "shares": "2272430680.000000000000000000" - }, - { - "delegator_address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", - "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "shares": "4778613408.000000000000000000" - }, - { - "delegator_address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "shares": "5734721271.000000000000000000" - }, - { - "delegator_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", - "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "shares": "2303096766.000000000000000000" - }, - { - "delegator_address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "shares": "6852395930.000000000000000000" - }, - { - "delegator_address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "shares": "21228627.000000000000000000" - }, - { - "delegator_address": "cosmos18k4yz84xrjqvrq9u7sehvje3ax4aspcksauctw", - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "shares": "10553965715.000000000000000000" - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "shares": "8365880246.000000000000000000" - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "shares": "7622442762.000000000000000000" - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "shares": "3145157664.000000000000000000" - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "shares": "3139002667.000000000000000000" - }, - { - "delegator_address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "shares": "721476141.000000000000000000" - }, - { - "delegator_address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "shares": "14744952147.000000000000000000" - }, - { - "delegator_address": "cosmos1864wj4twqatq54rrxl5jmfey55tmh0hvgmd9yw", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv", - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "shares": "12717644032.000000000000000000" - }, - { - "delegator_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "shares": "14461099488.000000000000000000" - }, - { - "delegator_address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "shares": "6926527802.000000000000000000" - }, - { - "delegator_address": "cosmos1g95xvy8qgzcvcl05fse0mpxzdfv3w88tpexycr", - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "shares": "2300967060.000000000000000000" - }, - { - "delegator_address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", - "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "shares": "80752627.000000000000000000" - }, - { - "delegator_address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", - "validator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", - "validator_address": "cosmosvaloper1g2x2lp54k9wntyh774ga64hyp5d7f0pacukhl7", - "shares": "1252735315.000000000000000000" - }, - { - "delegator_address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", - "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "shares": "8771546667.000000000000000000" - }, - { - "delegator_address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm", - "validator_address": "cosmosvaloper1g2nzzd4sqk48066wu82atssmn5cs7vrc8x8zlg", - "shares": "5701177554.000000000000000000" - }, - { - "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "shares": "17483443758.000000000000000000" - }, - { - "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "shares": "31595387940.000000000000000000" - }, - { - "delegator_address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "shares": "7585898322.000000000000000000" - }, - { - "delegator_address": "cosmos1gwwltgyatg8yfe54447dxnyvs2nt6xxsl6lv2m", - "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "shares": "21998779909.000000000000000000" - }, - { - "delegator_address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", - "validator_address": "cosmosvaloper1g37aedx6gtmnkp8gpq33lnxwt2f320yt3l6g2g", - "shares": "4474063302.000000000000000000" - }, - { - "delegator_address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "shares": "1958289106.000000000000000000" - }, - { - "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "shares": "2228638557.000000000000000000" - }, - { - "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "shares": "5090332.000000000000000000" - }, - { - "delegator_address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "shares": "995636217.000000000000000000" - }, - { - "delegator_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", - "validator_address": "cosmosvaloper1y30ftjd79f3p68mssyd9zug24q2avh0zzgrnxg", - "shares": "286435366.000000000000000000" - }, - { - "delegator_address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", - "validator_address": "cosmosvaloper1gnpkhqvfq42exjx6cqaa3d7xnw8uexgnaeeq4e", - "shares": "9095777401.000000000000000000" - }, - { - "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "shares": "12690053528.000000000000000000" - }, - { - "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "shares": "13987549940.000000000000000000" - }, - { - "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "shares": "20548231148.000000000000000000" - }, - { - "delegator_address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "shares": "1886627332.000000000000000000" - }, - { - "delegator_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", - "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "shares": "8792247810.000000000000000000" - }, - { - "delegator_address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "shares": "3178697313.000000000000000000" - }, - { - "delegator_address": "cosmos1gh67zgx4f9d64ctqhtascuh87805v8yffrfytl", - "validator_address": "cosmosvaloper1gh67zgx4f9d64ctqhtascuh87805v8yfvha38v", - "shares": "602352708.000000000000000000" - }, - { - "delegator_address": "cosmos1gayzja3zz6unep8ftnpunt2wefazs3jhunl5az", - "validator_address": "cosmosvaloper1gayzja3zz6unep8ftnpunt2wefazs3jhe8tp33", - "shares": "4639932033.000000000000000000" - }, - { - "delegator_address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", - "validator_address": "cosmosvaloper1g7zpua5k7smc8n8lkv099v06trk98rhpruh733", - "shares": "556310530.000000000000000000" - }, - { - "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "shares": "74047563.000000000000000000" - }, - { - "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "shares": "526885228.000000000000000000" - }, - { - "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "shares": "17756476456.000000000000000000" - }, - { - "delegator_address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "shares": "1439734010.000000000000000000" - }, - { - "delegator_address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "shares": "4300294602.000000000000000000" - }, - { - "delegator_address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "shares": "9627765333.000000000000000000" - }, - { - "delegator_address": "cosmos1glku8mx4nzp5crkjt7px9lfe4flfge3zf64tud", - "validator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "shares": "16236700229.000000000000000000" - }, - { - "delegator_address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "shares": "7078635448.000000000000000000" - }, - { - "delegator_address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", - "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "shares": "1447202506.000000000000000000" - }, - { - "delegator_address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2", - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1f2pvewnws73u0z5wsfmv5uqudwxl6jupfm6nta", - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "shares": "74135685.000000000000000000" - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "shares": "37913276.000000000000000000" - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "shares": "22265567297.000000000000000000" - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "shares": "150189421.000000000000000000" - }, - { - "delegator_address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "shares": "1386448079.000000000000000000" - }, - { - "delegator_address": "cosmos1ftj05w0hmw2xxw5p7gvr258j2824qd8r2xdk9e", - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "shares": "12407365569.000000000000000000" - }, - { - "delegator_address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "shares": "209918859.000000000000000000" - }, - { - "delegator_address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "shares": "1956086691.000000000000000000" - }, - { - "delegator_address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "shares": "200187880.000000000000000000" - }, - { - "delegator_address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "shares": "335240579.000000000000000000" - }, - { - "delegator_address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", - "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "shares": "5071075450.000000000000000000" - }, - { - "delegator_address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", - "validator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "shares": "693338797.000000000000000000" - }, - { - "delegator_address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "shares": "9495710.000000000000000000" - }, - { - "delegator_address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "shares": "2744054731.000000000000000000" - }, - { - "delegator_address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "shares": "11738157290.000000000000000000" - }, - { - "delegator_address": "cosmos1f58nf9lzm4d5x9grnt3a3vd9c75szj95f6mm5s", - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "shares": "15007199497.000000000000000000" - }, - { - "delegator_address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "shares": "670350742.000000000000000000" - }, - { - "delegator_address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "shares": "590997851.000000000000000000" - }, - { - "delegator_address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "shares": "5720739029.000000000000000000" - }, - { - "delegator_address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4", - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "shares": "885018304.000000000000000000" - }, - { - "delegator_address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", - "validator_address": "cosmosvaloper1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2drqdpa", - "shares": "12112810368.000000000000000000" - }, - { - "delegator_address": "cosmos1fc96780mrsxn5kgplhtna40qepjgrm9wsyly02", - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "shares": "15719680142.000000000000000000" - }, - { - "delegator_address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "shares": "3326376911.000000000000000000" - }, - { - "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", - "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "shares": "6536333612.000000000000000000" - }, - { - "delegator_address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "shares": "13874964933.000000000000000000" - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "shares": "68061939.000000000000000000" - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "shares": "152484301.000000000000000000" - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "shares": "2534638254.000000000000000000" - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "shares": "7174712260.000000000000000000" - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "shares": "9519082012.000000000000000000" - }, - { - "delegator_address": "cosmos1f7utq63ae24m6aqw4metxjrc5q76j8h4gcgaxd", - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "shares": "23676093358.000000000000000000" - }, - { - "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "shares": "61726947.000000000000000000" - }, - { - "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", - "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "shares": "10554411.000000000000000000" - }, - { - "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "shares": "2095470160.000000000000000000" - }, - { - "delegator_address": "cosmos12q3w0j5hp023hdjafgc357hy7kkha296f4xrjf", - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "shares": "19013093201.000000000000000000" - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "shares": "1441730941.000000000000000000" - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "shares": "397947789.000000000000000000" - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "shares": "3804293134.000000000000000000" - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "shares": "1878391814.000000000000000000" - }, - { - "delegator_address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "shares": "410769752.000000000000000000" - }, - { - "delegator_address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m", - "validator_address": "cosmosvaloper12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpdk62fg", - "shares": "2878820932.000000000000000000" - }, - { - "delegator_address": "cosmos12r0m6hwrnn0jy02tnhmk328d7p68x2rndzt0j5", - "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "shares": "9649353957.000000000000000000" - }, - { - "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "shares": "4660142050.000000000000000000" - }, - { - "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "shares": "2714767582.000000000000000000" - }, - { - "delegator_address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "shares": "8006017871.000000000000000000" - }, - { - "delegator_address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "shares": "782001327.000000000000000000" - }, - { - "delegator_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "shares": "2830380125.000000000000000000" - }, - { - "delegator_address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", - "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "shares": "5637854002.000000000000000000" - }, - { - "delegator_address": "cosmos12f4fpl936ld8c64dxqgwv65p42na8dcnv9g7ku", - "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "shares": "4840284805.000000000000000000" - }, - { - "delegator_address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq", - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "shares": "592539582.000000000000000000" - }, - { - "delegator_address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "shares": "3855652978.000000000000000000" - }, - { - "delegator_address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "validator_address": "cosmosvaloper12wh7xjav34zj2s3ykpllnq58leslqaayyxcrjf", - "shares": "6943791722.000000000000000000" - }, - { - "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "shares": "276574162.000000000000000000" - }, - { - "delegator_address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "shares": "689756170.000000000000000000" - }, - { - "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "shares": "900956465.000000000000000000" - }, - { - "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "shares": "1549115655.000000000000000000" - }, - { - "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "shares": "203058104.000000000000000000" - }, - { - "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "shares": "24771629701.000000000000000000" - }, - { - "delegator_address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "shares": "16356624866.000000000000000000" - }, - { - "delegator_address": "cosmos124wz6pnykadgf3xchp6rdn9s2t9z5sgvl7597p", - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "shares": "6557300877.000000000000000000" - }, - { - "delegator_address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "shares": "6087225472.000000000000000000" - }, - { - "delegator_address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "shares": "638979230.000000000000000000" - }, - { - "delegator_address": "cosmos12eynrdzx2jqz5u92hgmhl9ga6hmghqfv0xvns8", - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "shares": "2461085809.000000000000000000" - }, - { - "delegator_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", - "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "shares": "2521177822.000000000000000000" - }, - { - "delegator_address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", - "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "shares": "22548164258.000000000000000000" - }, - { - "delegator_address": "cosmos1tpxdvj93x9rqz89zhh0tszegcwtq8mgtdknrw5", - "validator_address": "cosmosvaloper1tpxdvj93x9rqz89zhh0tszegcwtq8mgtgz8kz8", - "shares": "13387012198.000000000000000000" - }, - { - "delegator_address": "cosmos1tzz5l8sw05e0tm5l0gxuvp04qt42stu3kqwf4s", - "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "shares": "7946485541.000000000000000000" - }, - { - "delegator_address": "cosmos1tz087eh88lqkesr77yl6ys9dw95qysfqtff52a", - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "shares": "25027795872.000000000000000000" - }, - { - "delegator_address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj", - "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "shares": "4050355196.000000000000000000" - }, - { - "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "shares": "4422731613.000000000000000000" - }, - { - "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "shares": "277893955.000000000000000000" - }, - { - "delegator_address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "shares": "190512146.000000000000000000" - }, - { - "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "shares": "4469703294.000000000000000000" - }, - { - "delegator_address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "shares": "9951710774.000000000000000000" - }, - { - "delegator_address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "shares": "2246266.000000000000000000" - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "shares": "9390268176.000000000000000000" - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "shares": "2399862586.000000000000000000" - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "shares": "264012997.000000000000000000" - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "shares": "1338628253.000000000000000000" - }, - { - "delegator_address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "shares": "548629134.000000000000000000" - }, - { - "delegator_address": "cosmos1tgghhdcxdgxay7hp2p0lv2fs656c4c0xfzlga5", - "validator_address": "cosmosvaloper1tgghhdcxdgxay7hp2p0lv2fs656c4c0xvkta38", - "shares": "243264064.000000000000000000" - }, - { - "delegator_address": "cosmos1tftatt0lp0v59qqf449pdqar8w3yj7n7xa7sk6", - "validator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "shares": "9168014109.000000000000000000" - }, - { - "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "shares": "15899234337.000000000000000000" - }, - { - "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "shares": "459551216.000000000000000000" - }, - { - "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "shares": "3300457502.000000000000000000" - }, - { - "delegator_address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "shares": "254829181.000000000000000000" - }, - { - "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "shares": "3078912948.000000000000000000" - }, - { - "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "shares": "254473474.000000000000000000" - }, - { - "delegator_address": "cosmos1twu2lvgp3erk6gups2a8nae3jdahaj2xmlufsa", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "validator_address": "cosmosvaloper1t0m9uvcqa3w09srgy3z6725mpj2kcxkk5qwrj3", - "shares": "365167856.000000000000000000" - }, - { - "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "shares": "3444033677.000000000000000000" - }, - { - "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "shares": "315491807.000000000000000000" - }, - { - "delegator_address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "shares": "548109039.000000000000000000" - }, - { - "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "shares": "2186207273.000000000000000000" - }, - { - "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", - "validator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "shares": "22429572439.000000000000000000" - }, - { - "delegator_address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", - "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "shares": "4365594275.000000000000000000" - }, - { - "delegator_address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", - "validator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "shares": "47693559541.000000000000000000" - }, - { - "delegator_address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "shares": "18283793775.000000000000000000" - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "shares": "2524305482.000000000000000000" - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "shares": "526869097.000000000000000000" - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "shares": "2905348435.000000000000000000" - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "shares": "2150744506.000000000000000000" - }, - { - "delegator_address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je", - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "shares": "19109522.000000000000000000" - }, - { - "delegator_address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "shares": "6106439259.000000000000000000" - }, - { - "delegator_address": "cosmos1tmddg4wjnj38wrd8t6xq092jyw3x4hcup6n00u", - "validator_address": "cosmosvaloper1tmddg4wjnj38wrd8t6xq092jyw3x4hcuyw86r0", - "shares": "7029801264.000000000000000000" - }, - { - "delegator_address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s", - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "shares": "9953913240.000000000000000000" - }, - { - "delegator_address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "shares": "3831088.000000000000000000" - }, - { - "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", - "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "shares": "2948850137.000000000000000000" - }, - { - "delegator_address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "shares": "680611809.000000000000000000" - }, - { - "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", - "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "shares": "35599530.000000000000000000" - }, - { - "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "shares": "14234623.084306457501521645" - }, - { - "delegator_address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "shares": "97571824.000000000000000000" - }, - { - "delegator_address": "cosmos1vqm5fdsflvnee33gk3d5pz7j6tf6dsp28eemcq", - "validator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "shares": "16949426508.000000000000000000" - }, - { - "delegator_address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "shares": "1356197798.000000000000000000" - }, - { - "delegator_address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", - "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "shares": "731773122.000000000000000000" - }, - { - "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "shares": "16096304.000000000000000000" - }, - { - "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "validator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "shares": "4748086.000000000000000000" - }, - { - "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "validator_address": "cosmosvaloper1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqp6d6s27", - "shares": "405352.000000000000000000" - }, - { - "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "shares": "2311637.000000000000000000" - }, - { - "delegator_address": "cosmos1vx0z58vgegsfc8e56jzmjtvj8cvprywvnm7l9j", - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "shares": "1076204485.000000000000000000" - }, - { - "delegator_address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", - "validator_address": "cosmosvaloper1q9tcvremyhu80vylcpenp9str7wn0qf0y4le3z", - "shares": "2399562500.000000000000000000" - }, - { - "delegator_address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", - "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "shares": "1049818729.000000000000000000" - }, - { - "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "shares": "5284614159.000000000000000000" - }, - { - "delegator_address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "shares": "11759488693.000000000000000000" - }, - { - "delegator_address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", - "validator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "shares": "18158211957.000000000000000000" - }, - { - "delegator_address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", - "validator_address": "cosmosvaloper1vfect9js0f8535fas4ly6waxvavc2s92ks9mtn", - "shares": "1728294636.000000000000000000" - }, - { - "delegator_address": "cosmos1vwja3gc3e37f8fkddj38gp74cs7sccnf4zs509", - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "shares": "2070243017.000000000000000000" - }, - { - "delegator_address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "shares": "4946049715.000000000000000000" - }, - { - "delegator_address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", - "validator_address": "cosmosvaloper1v08dcmtc5f444sxqfvqv8mxdclmc27590ydg0l", - "shares": "9022206595.000000000000000000" - }, - { - "delegator_address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "shares": "175132304.000000000000000000" - }, - { - "delegator_address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "shares": "3507629422.000000000000000000" - }, - { - "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", - "validator_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "shares": "5221113247.000000000000000000" - }, - { - "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", - "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "shares": "4681593063.000000000000000000" - }, - { - "delegator_address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", - "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "shares": "6709144772.000000000000000000" - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "shares": "14430378546.000000000000000000" - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "shares": "202358889.000000000000000000" - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1vjj3g3vkh56g04yqqsdn0yxcul9pve2rlux4tl", - "shares": "10613605390.000000000000000000" - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "shares": "3535960309.000000000000000000" - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "shares": "670559324.000000000000000000" - }, - { - "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "shares": "667949570.000000000000000000" - }, - { - "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "shares": "967842562.000000000000000000" - }, - { - "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "shares": "11105705687.000000000000000000" - }, - { - "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "shares": "12269775869.000000000000000000" - }, - { - "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "shares": "2105667711.000000000000000000" - }, - { - "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "shares": "6458950379.000000000000000000" - }, - { - "delegator_address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "shares": "9360757617.000000000000000000" - }, - { - "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "shares": "3427543323.000000000000000000" - }, - { - "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "shares": "863704883.000000000000000000" - }, - { - "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "shares": "3501192050.000000000000000000" - }, - { - "delegator_address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "shares": "6923120900.000000000000000000" - }, - { - "delegator_address": "cosmos1vuws77sz0xzvz8y0dg6wjz9fzd7plxpk29ljn7", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "shares": "1285996047.000000000000000000" - }, - { - "delegator_address": "cosmos1vlvxlpzzrk5eye9c3z9uedk0085h7fdvehv32n", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "shares": "1749823283.000000000000000000" - }, - { - "delegator_address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "shares": "20234365401.000000000000000000" - }, - { - "delegator_address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz", - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "shares": "16734096385.000000000000000000" - }, - { - "delegator_address": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", - "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "shares": "17594927523.000000000000000000" - }, - { - "delegator_address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7", - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "shares": "1694198126.000000000000000000" - }, - { - "delegator_address": "cosmos1d9m3l8khcrx0zhftehkuw67zzszf9v9le5dvrm", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "shares": "20382465534.000000000000000000" - }, - { - "delegator_address": "cosmos1dgzvesl67z96ttlt5ulga25phe8pnspt663dvr", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "shares": "7195021215.000000000000000000" - }, - { - "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "shares": "20147750165.000000000000000000" - }, - { - "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "shares": "837111535.000000000000000000" - }, - { - "delegator_address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "shares": "2769362709.000000000000000000" - }, - { - "delegator_address": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "shares": "5379750065.000000000000000000" - }, - { - "delegator_address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "shares": "9737598105.000000000000000000" - }, - { - "delegator_address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", - "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", - "validator_address": "cosmosvaloper1dvav9u8d2a4j8f9salk7kk6pz0aa7e07cj4s7l", - "shares": "49835911.000000000000000000" - }, - { - "delegator_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "shares": "17266683.000000000000000000" - }, - { - "delegator_address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", - "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "shares": "4258157.000000000000000000" - }, - { - "delegator_address": "cosmos1d0dq8hxzyywrcx73v4z44e8p8685znzml58dg2", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "shares": "23089372229.000000000000000000" - }, - { - "delegator_address": "cosmos1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpdhe28d", - "validator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "shares": "17862559018.000000000000000000" - }, - { - "delegator_address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "shares": "6295579444.000000000000000000" - }, - { - "delegator_address": "cosmos1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcy522k3", - "validator_address": "cosmosvaloper1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcpq7l6z", - "shares": "1291312379.000000000000000000" - }, - { - "delegator_address": "cosmos1d5vv20893q06tx29mlqmefnyf0w3hn0v07w9p9", - "validator_address": "cosmosvaloper1d5vv20893q06tx29mlqmefnyf0w3hn0v226sdk", - "shares": "186531063.000000000000000000" - }, - { - "delegator_address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "shares": "19589707878.000000000000000000" - }, - { - "delegator_address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", - "validator_address": "cosmosvaloper18wfnjhyqjzjpa5pgd3r5n987uet7qczje6ulqn", - "shares": "179784223.000000000000000000" - }, - { - "delegator_address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", - "validator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "shares": "19056636038.000000000000000000" - }, - { - "delegator_address": "cosmos1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lypeadd", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", - "validator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "shares": "11267665039.000000000000000000" - }, - { - "delegator_address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", - "validator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "shares": "11650293201.000000000000000000" - }, - { - "delegator_address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "shares": "61880678.000000000000000000" - }, - { - "delegator_address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "shares": "9719656784.000000000000000000" - }, - { - "delegator_address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "shares": "11780930912.000000000000000000" - }, - { - "delegator_address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", - "validator_address": "cosmosvaloper1wy59rs74dnqqs0xz70sn2q5hyv9yrethwxjpfm", - "shares": "7094282971.000000000000000000" - }, - { - "delegator_address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "shares": "8142048495.000000000000000000" - }, - { - "delegator_address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "shares": "2012957230.000000000000000000" - }, - { - "delegator_address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", - "validator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "shares": "16439836386.000000000000000000" - }, - { - "delegator_address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "shares": "3961673047.000000000000000000" - }, - { - "delegator_address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", - "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "shares": "3607007415.000000000000000000" - }, - { - "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "shares": "5596804179.000000000000000000" - }, - { - "delegator_address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "shares": "3295555517.000000000000000000" - }, - { - "delegator_address": "cosmos1wtn9tf6wjwmwmddrk377cdl8fd96hexajyhfat", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "shares": "18471816853.000000000000000000" - }, - { - "delegator_address": "cosmos1wvzq2f252674u3gvmqhnq8g4n6lmxedmzs0czm", - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "shares": "2584616241.000000000000000000" - }, - { - "delegator_address": "cosmos1wdm9ge7hjzrlh2epwtwu3nsunfd2r7alqhc7r2", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "shares": "24303271333.000000000000000000" - }, - { - "delegator_address": "cosmos1wwp7j40k9xffj757s4uurkcegskfwq25ef268l", - "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "shares": "584304640.000000000000000000" - }, - { - "delegator_address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "shares": "423877981.000000000000000000" - }, - { - "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "shares": "1781975477.000000000000000000" - }, - { - "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "validator_address": "cosmosvaloper1wnu44nwfn43e66cgm6kqyxurhytzxkp0a2s4xs", - "shares": "1553435623.000000000000000000" - }, - { - "delegator_address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "shares": "41624341.000000000000000000" - }, - { - "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "shares": "11513057667.000000000000000000" - }, - { - "delegator_address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "shares": "13034888858.653846147589407194" - }, - { - "delegator_address": "cosmos1w69f6s0dqsqfqq93hczddadwgeq86zr9dfmddq", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "shares": "751916830.000000000000000000" - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "shares": "1427892425.000000000000000000" - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "shares": "585232700.000000000000000000" - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "shares": "116762054.000000000000000000" - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "shares": "324745845.000000000000000000" - }, - { - "delegator_address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "shares": "16011251757.000000000000000000" - }, - { - "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "shares": "24728825327.000000000000000000" - }, - { - "delegator_address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "shares": "14446066.000000000000000000" - }, - { - "delegator_address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "shares": "1721804886.000000000000000000" - }, - { - "delegator_address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "shares": "3002359447.000000000000000000" - }, - { - "delegator_address": "cosmos10qj9cj3dxecyu826gaw72ylwum96jkkh9p462q", - "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "shares": "7039255436.000000000000000000" - }, - { - "delegator_address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2", - "validator_address": "cosmosvaloper10qernplwz439sjmxwllhpp4sujq6a9r0x5ev4e", - "shares": "1606367134.000000000000000000" - }, - { - "delegator_address": "cosmos10p78pcqm2slk4x0pfxl9ht5spskwquhzptwzt8", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "shares": "3812433475.000000000000000000" - }, - { - "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", - "validator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "shares": "2341551967.000000000000000000" - }, - { - "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", - "validator_address": "cosmosvaloper10rqahajykyr5fjzf393tg34vmph05ygwh7nudh", - "shares": "229341851.000000000000000000" - }, - { - "delegator_address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", - "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "shares": "2246425767.000000000000000000" - }, - { - "delegator_address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", - "validator_address": "cosmosvaloper10xwf26gupjlr4xt69pl779346w7yytxhfxh8zw", - "shares": "5555958746.000000000000000000" - }, - { - "delegator_address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "shares": "8539175078.000000000000000000" - }, - { - "delegator_address": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "shares": "7137720854.000000000000000000" - }, - { - "delegator_address": "cosmos10gu52rf3d0z0py8d0x37r058qh9fgdgg5567wd", - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "shares": "13307344592.000000000000000000" - }, - { - "delegator_address": "cosmos10d3vd6yx9k9ns6v82r4krm3d4ragw04cysm62c", - "validator_address": "cosmosvaloper10d3vd6yx9k9ns6v82r4krm3d4ragw04cpy00xt", - "shares": "1365098704.000000000000000000" - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "shares": "1993086195.000000000000000000" - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "shares": "1981740603.000000000000000000" - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "shares": "19691201.000000000000000000" - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "shares": "2235582679.000000000000000000" - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "shares": "151161779.000000000000000000" - }, - { - "delegator_address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", - "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", - "shares": "48593531.000000000000000000" - }, - { - "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "shares": "11937090067.000000000000000000" - }, - { - "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", - "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", - "shares": "955350854.000000000000000000" - }, - { - "delegator_address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "shares": "917167136.000000000000000000" - }, - { - "delegator_address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "shares": "226539767.000000000000000000" - }, - { - "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "shares": "31268300.962477168044592631" - }, - { - "delegator_address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", - "validator_address": "cosmosvaloper104v634ezzajvzu3x8r9q9uhz4dd9xm6f0u943p", - "shares": "3717256219.000000000000000000" - }, - { - "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "shares": "8832434015.000000000000000000" - }, - { - "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "shares": "121624664.000000000000000000" - }, - { - "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "validator_address": "cosmosvaloper10ke8m795c8svtt2h24n6dad2xp9a8mevwj9dpp", - "shares": "27773889.000000000000000000" - }, - { - "delegator_address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "shares": "7778508961.000000000000000000" - }, - { - "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", - "validator_address": "cosmosvaloper1qqe0t0j86umq0379kjcmjg00yd6ddrdw3t2t33", - "shares": "1611728813.000000000000000000" - }, - { - "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", - "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "shares": "1609536341.000000000000000000" - }, - { - "delegator_address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", - "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "shares": "157509894.000000000000000000" - }, - { - "delegator_address": "cosmos10cl6sallgwf882apcyagjqa2lx4j8592cjw0gf", - "validator_address": "cosmosvaloper10cl6sallgwf882apcyagjqa2lx4j8592ax66y6", - "shares": "1573970763.000000000000000000" - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "shares": "4784005.000000000000000000" - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "shares": "8178830.000000000000000000" - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "shares": "402116649.000000000000000000" - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "shares": "2274933257.000000000000000000" - }, - { - "delegator_address": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "shares": "10376224736.000000000000000000" - }, - { - "delegator_address": "cosmos1sr6u63sxsprpzv7tedc7e88tn6elrxkjnucszy", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "shares": "32674846927.555147209487723148" - }, - { - "delegator_address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "shares": "21431257869.000000000000000000" - }, - { - "delegator_address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "shares": "843834482.000000000000000000" - }, - { - "delegator_address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", - "validator_address": "cosmosvaloper1znvpcj20duymyac6cl4r8kcf827aqu60fgjftp", - "shares": "2339204126.000000000000000000" - }, - { - "delegator_address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "shares": "14241294624.000000000000000000" - }, - { - "delegator_address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "shares": "1117197748.000000000000000000" - }, - { - "delegator_address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "shares": "2037145657.000000000000000000" - }, - { - "delegator_address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q", - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "shares": "2844380010.000000000000000000" - }, - { - "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", - "validator_address": "cosmosvaloper1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmpgcdy4", - "shares": "6732042.000000000000000000" - }, - { - "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "shares": "21529013972.000000000000000000" - }, - { - "delegator_address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "shares": "3069213832.000000000000000000" - }, - { - "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", - "validator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "shares": "1302147397.000000000000000000" - }, - { - "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "shares": "14654910305.000000000000000000" - }, - { - "delegator_address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "shares": "4020804640.000000000000000000" - }, - { - "delegator_address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "shares": "870772585.000000000000000000" - }, - { - "delegator_address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", - "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "shares": "7012397.000000000000000000" - }, - { - "delegator_address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp", - "validator_address": "cosmosvaloper1sd0jepmznzu54wy89g022t34rchk2wd2c4z7zj", - "shares": "1392995609.000000000000000000" - }, - { - "delegator_address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", - "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "shares": "11045854268.000000000000000000" - }, - { - "delegator_address": "cosmos1s34kukvsrdgap0pjh0alnql7vvv9m83m2628wd", - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "shares": "3141510059.000000000000000000" - }, - { - "delegator_address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", - "validator_address": "cosmosvaloper1sjg96xpaa2cayeym6w3a2t38n7gm9zcsxkx6y9", - "shares": "5059370848.000000000000000000" - }, - { - "delegator_address": "cosmos1sjhhg2yl2cqszte7pjyrp6lx5tg383lrpjyq0m", - "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "shares": "8429625072.000000000000000000" - }, - { - "delegator_address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "shares": "842733222.000000000000000000" - }, - { - "delegator_address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "shares": "2313732788.000000000000000000" - }, - { - "delegator_address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", - "validator_address": "cosmosvaloper1seq3r2t3gzvv422nsy9m7fjvjywx57q3kaluk5", - "shares": "1963736286.000000000000000000" - }, - { - "delegator_address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj", - "validator_address": "cosmosvaloper1sed5gwrv6g8x0pwddqmat3nffg66fwkdymtvgp", - "shares": "6944508564.000000000000000000" - }, - { - "delegator_address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "shares": "13458847467.000000000000000000" - }, - { - "delegator_address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc", - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "shares": "2335097089.000000000000000000" - }, - { - "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", - "validator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "shares": "7367311429.000000000000000000" - }, - { - "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "shares": "1116213901.000000000000000000" - }, - { - "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "shares": "2413926110.000000000000000000" - }, - { - "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "shares": "836513743.000000000000000000" - }, - { - "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "shares": "16324341322.000000000000000000" - }, - { - "delegator_address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", - "validator_address": "cosmosvaloper1s728ea54m9u76dkd4x9ea3l5cvjjjkk5em9myd", - "shares": "109318647.000000000000000000" - }, - { - "delegator_address": "cosmos13ps0cszg8lqn0mkzndvhxwaew8yd56s8tl9j20", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "shares": "7351040665.000000000000000000" - }, - { - "delegator_address": "cosmos13yzpngckxvtky2k25j60qxlkekx0jfau4pjhzn", - "validator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos13y2zjpgaj07umx7a3dsg9ffhpkk22g73492l53", - "validator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "shares": "3677892381.000000000000000000" - }, - { - "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "shares": "5068354349.000000000000000000" - }, - { - "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "shares": "2649436634.000000000000000000" - }, - { - "delegator_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", - "validator_address": "cosmosvaloper13x5pze8uxrt4ea9jmskzdl8j3avc03n2jmjmvk", - "shares": "1975544514.000000000000000000" - }, - { - "delegator_address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "shares": "3371357709.000000000000000000" - }, - { - "delegator_address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "shares": "3736546194.000000000000000000" - }, - { - "delegator_address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", - "validator_address": "cosmosvaloper138cypx3g3puv720atyg9x9dvap8k52y0am3wg0", - "shares": "1089374285.000000000000000000" - }, - { - "delegator_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", - "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "shares": "9334974491.000000000000000000" - }, - { - "delegator_address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "shares": "117761745.000000000000000000" - }, - { - "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "shares": "241691384.000000000000000000" - }, - { - "delegator_address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", - "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "shares": "12106150602.000000000000000000" - }, - { - "delegator_address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", - "validator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "shares": "2665696727.000000000000000000" - }, - { - "delegator_address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", - "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "shares": "3084993241.000000000000000000" - }, - { - "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "shares": "4124499225.000000000000000000" - }, - { - "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "shares": "3484578053.000000000000000000" - }, - { - "delegator_address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "shares": "4448687638.000000000000000000" - }, - { - "delegator_address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890", - "validator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "shares": "9648503235.000000000000000000" - }, - { - "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "shares": "12794497617.000000000000000000" - }, - { - "delegator_address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "shares": "12274844463.000000000000000000" - }, - { - "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "shares": "1096219390.000000000000000000" - }, - { - "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "shares": "909672651.000000000000000000" - }, - { - "delegator_address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", - "validator_address": "cosmosvaloper13w024ysyklmnrq9c6udp98qx93jqynhgu99d0q", - "shares": "9842289918.000000000000000000" - }, - { - "delegator_address": "cosmos130kk7kw4kx7rfrq9sa4k673zqt3nf6s4l3a0lg", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "shares": "5241869268.000000000000000000" - }, - { - "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "shares": "916587.000000000000000000" - }, - { - "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "shares": "2061374262.000000000000000000" - }, - { - "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "shares": "23007967818.000000000000000000" - }, - { - "delegator_address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "shares": "144959703.000000000000000000" - }, - { - "delegator_address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "shares": "5071553218.000000000000000000" - }, - { - "delegator_address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "shares": "9488989139.000000000000000000" - }, - { - "delegator_address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "shares": "12748204456.000000000000000000" - }, - { - "delegator_address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "shares": "16792228457.000000000000000000" - }, - { - "delegator_address": "cosmos13nemj0k45u4pflkfeyey88n8u8sv4wgz8cf253", - "validator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "shares": "9595922807.000000000000000000" - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper1zjzkk7l2jalrspy6500my8v0yy6ycz7e6q9qwa", - "shares": "16993994.000000000000000000" - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper1t7wt4qjfsa4kncvvya5m99mq0m53n9e85kgxd4", - "shares": "143748684.000000000000000000" - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper13kv948cw98pdf4g2gjv9qr97rzvqxmvcpafkfh", - "shares": "19594820.000000000000000000" - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "shares": "927934611.000000000000000000" - }, - { - "delegator_address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "shares": "178156456.000000000000000000" - }, - { - "delegator_address": "cosmos13cydnwjmscxtqtjywk9atr9uwlm6703mwtycnr", - "validator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "shares": "14396315468.000000000000000000" - }, - { - "delegator_address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", - "validator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", - "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "shares": "3671255483.000000000000000000" - }, - { - "delegator_address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", - "validator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "shares": "8251101726.000000000000000000" - }, - { - "delegator_address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "shares": "2352005810.000000000000000000" - }, - { - "delegator_address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "shares": "345074496.000000000000000000" - }, - { - "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", - "validator_address": "cosmosvaloper10kmduud4gcmgkl9vuxff6ztp8qcnl8kzntcquw", - "shares": "23719777.000000000000000000" - }, - { - "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "shares": "22252816301.000000000000000000" - }, - { - "delegator_address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "shares": "29688637.000000000000000000" - }, - { - "delegator_address": "cosmos1jzhlspgxp578kzg9dtvg8tm2w9k7tnmcpstzry", - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "shares": "6425955236.000000000000000000" - }, - { - "delegator_address": "cosmos1j9vhccgf8520gtz7zn5jxj9lk3nqg0wx479kwp", - "validator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "shares": "12478510598.000000000000000000" - }, - { - "delegator_address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", - "validator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "shares": "19618367974.000000000000000000" - }, - { - "delegator_address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "shares": "4858570428.000000000000000000" - }, - { - "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "shares": "879369780.000000000000000000" - }, - { - "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "validator_address": "cosmosvaloper1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwvev6hl", - "shares": "11868568217.000000000000000000" - }, - { - "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "validator_address": "cosmosvaloper1jf2wka8xprke2q6qxq2vz3khe4mqxv75xlmwrt", - "shares": "12315828943.000000000000000000" - }, - { - "delegator_address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "shares": "5575140.000000000000000000" - }, - { - "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", - "validator_address": "cosmosvaloper1r2ncmjrd4efnk9cjrftq7sw7347xqyu3cwx8hx", - "shares": "2312465.000000000000000000" - }, - { - "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", - "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", - "shares": "3222725.000000000000000000" - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "shares": "1829057.000000000000000000" - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "shares": "2258309.000000000000000000" - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "shares": "16096471780.000000000000000000" - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper1jv7lxeryc30c0w4p7p92nxywgcnswuhsrl32aj", - "shares": "6237005399.000000000000000000" - }, - { - "delegator_address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "shares": "731129230.000000000000000000" - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "shares": "443348912.000000000000000000" - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper1r3e4elvyszkwjyp85erl5havx6emrk5tmz37wy", - "shares": "18797742.000000000000000000" - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper1g7sk4y3cf2473ff36mlcx9ydvted9evrshga8t", - "shares": "28000486.000000000000000000" - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "shares": "188596153.000000000000000000" - }, - { - "delegator_address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "shares": "17415142521.000000000000000000" - }, - { - "delegator_address": "cosmos1jsd99e3zfrxrr3nh057u0tvmu0847zkr29f28v", - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr", - "validator_address": "cosmosvaloper1j5fx2wm7gvl8sssx0wpd9luxegxs5he8hsgdzs", - "shares": "4524948359.000000000000000000" - }, - { - "delegator_address": "cosmos1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0ajhqc7", - "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "shares": "22529203230.000000000000000000" - }, - { - "delegator_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", - "validator_address": "cosmosvaloper1zygw824f55tk5srwxl00hhmx6lrl4npkdd5mvp", - "shares": "3423632102.000000000000000000" - }, - { - "delegator_address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", - "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "shares": "1443592024.000000000000000000" - }, - { - "delegator_address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa", - "validator_address": "cosmosvaloper1jcr5vg5nfeyynxggdtv9ncd6av42tetddzr5sr", - "shares": "4681170917.000000000000000000" - }, - { - "delegator_address": "cosmos1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxx7jqef", - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "shares": "2320422648.000000000000000000" - }, - { - "delegator_address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "shares": "454715151.000000000000000000" - }, - { - "delegator_address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", - "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", - "validator_address": "cosmosvaloper1npnutw8qwkvz0sleh593kaawfdygp6r23em4gk", - "shares": "1864943427.000000000000000000" - }, - { - "delegator_address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "shares": "14533440365.000000000000000000" - }, - { - "delegator_address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", - "validator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", - "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "shares": "14112770668.000000000000000000" - }, - { - "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", - "validator_address": "cosmosvaloper19vugh7w9vrp6x3nqzjph59zg0d28c0fk8dxdxv", - "shares": "457491.000000000000000000" - }, - { - "delegator_address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "shares": "9948638663.000000000000000000" - }, - { - "delegator_address": "cosmos1nrugh7am9s584k6qlf5nxlpetarxs2csglt46w", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "shares": "4938829215.000000000000000000" - }, - { - "delegator_address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", - "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "shares": "33054734644.000000000000000000" - }, - { - "delegator_address": "cosmos1n9dqelmmf5kfysk24m6chqfdcgz6r75u7mpuwh", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", - "validator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "shares": "15056247725.000000000000000000" - }, - { - "delegator_address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", - "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "shares": "10013094355.000000000000000000" - }, - { - "delegator_address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", - "validator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "shares": "315931330.000000000000000000" - }, - { - "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "shares": "189243223.000000000000000000" - }, - { - "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "shares": "13576729605.000000000000000000" - }, - { - "delegator_address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "shares": "2427273583.000000000000000000" - }, - { - "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "shares": "401941426.000000000000000000" - }, - { - "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "shares": "158733361.000000000000000000" - }, - { - "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "shares": "35850249.000000000000000000" - }, - { - "delegator_address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "shares": "205025816.000000000000000000" - }, - { - "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", - "validator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "shares": "2567851891.000000000000000000" - }, - { - "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "shares": "302642185.000000000000000000" - }, - { - "delegator_address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "shares": "2830795600.000000000000000000" - }, - { - "delegator_address": "cosmos1ng5m6spxngyne4qzce35fdg0whl0yqgv9lg9tt", - "validator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "shares": "13107417049.000000000000000000" - }, - { - "delegator_address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "shares": "18672701727.000000000000000000" - }, - { - "delegator_address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", - "validator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "shares": "235709907.000000000000000000" - }, - { - "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "shares": "4090038169.000000000000000000" - }, - { - "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "shares": "2956537033.000000000000000000" - }, - { - "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "shares": "23728387848.000000000000000000" - }, - { - "delegator_address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", - "validator_address": "cosmosvaloper1n20sc20x53kyms9vhrxlr8r79hptq3p2d6a8ex", - "shares": "1340954232.000000000000000000" - }, - { - "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "shares": "7303977754.000000000000000000" - }, - { - "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "shares": "11095524326.000000000000000000" - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "shares": "61795.000000000000000000" - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "shares": "1729736194.000000000000000000" - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "shares": "11773826677.000000000000000000" - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1vpnmy3wsyx04tan3x80c5js8ws5slhpk7atnvc", - "shares": "5311127.000000000000000000" - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper1ndff2ha25wm2nhunxgfrzlnhvc5j06zvdf6gez", - "shares": "52419.000000000000000000" - }, - { - "delegator_address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "shares": "95191076.000000000000000000" - }, - { - "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", - "validator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "shares": "23726525801.000000000000000000" - }, - { - "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", - "validator_address": "cosmosvaloper183sdz4kk0lueuxfu7zzgp8tzcjndf3pft9z9rt", - "shares": "312724720.000000000000000000" - }, - { - "delegator_address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", - "validator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1n3lnhxzzm7ntheu78h6v4zag7zmrlp48tjnhf3", - "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "shares": "9794461587.000000000000000000" - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "shares": "15964121.000000000000000000" - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "shares": "428070399.000000000000000000" - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper1n5t5rr83k3emp5e446qjprj0svsh06rw9zzeju", - "shares": "12613411.000000000000000000" - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "shares": "24554814193.000000000000000000" - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "shares": "51693014.000000000000000000" - }, - { - "delegator_address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "shares": "10690661250.000000000000000000" - }, - { - "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "shares": "20540852.000000000000000000" - }, - { - "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "shares": "24652299.000000000000000000" - }, - { - "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "shares": "16883391832.000000000000000000" - }, - { - "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "shares": "32698264.000000000000000000" - }, - { - "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "shares": "2237914169.000000000000000000" - }, - { - "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "shares": "5136199330.000000000000000000" - }, - { - "delegator_address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", - "validator_address": "cosmosvaloper1nmexjngk0j8jhgmywrkd7r98dgd9hzxpctnhup", - "shares": "14531672001.000000000000000000" - }, - { - "delegator_address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "shares": "17245824357.000000000000000000" - }, - { - "delegator_address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", - "validator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "shares": "16205811760.000000000000000000" - }, - { - "delegator_address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", - "validator_address": "cosmosvaloper1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cxq03v3l", - "shares": "981657888.000000000000000000" - }, - { - "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "shares": "177902750.000000000000000000" - }, - { - "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "shares": "13348917907.000000000000000000" - }, - { - "delegator_address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", - "validator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "shares": "5038451854.000000000000000000" - }, - { - "delegator_address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", - "validator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", - "shares": "15174649749.000000000000000000" - }, - { - "delegator_address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "shares": "938622421.000000000000000000" - }, - { - "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "shares": "126388593.000000000000000000" - }, - { - "delegator_address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", - "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "shares": "52804172.000000000000000000" - }, - { - "delegator_address": "cosmos15pl2c2umxszwar75aft99kns0ltmpepnnpt9y0", - "validator_address": "cosmosvaloper15pl2c2umxszwar75aft99kns0ltmpepnk4lsgu", - "shares": "11726853019.000000000000000000" - }, - { - "delegator_address": "cosmos15zqzxj663h8g8naxyz324j2rpd3rnw4rvtxep2", - "validator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "shares": "2151028602.000000000000000000" - }, - { - "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", - "validator_address": "cosmosvaloper1xau5jp7uyewxcwg9tzwsxm895v3mf0fnmxw7hj", - "shares": "2713168340.000000000000000000" - }, - { - "delegator_address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "shares": "2095412424.000000000000000000" - }, - { - "delegator_address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", - "validator_address": "cosmosvaloper15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz2zmx7g", - "shares": "11868660651.000000000000000000" - }, - { - "delegator_address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "shares": "632967960.000000000000000000" - }, - { - "delegator_address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "shares": "16358237418.000000000000000000" - }, - { - "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", - "validator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "shares": "1116365771.000000000000000000" - }, - { - "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", - "validator_address": "cosmosvaloper1wkt8xe20zdph4ak9vqx2supe3v2gq3wyhd78lc", - "shares": "6995636695.000000000000000000" - }, - { - "delegator_address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", - "validator_address": "cosmosvaloper152vx4n8032chkrgh97h05rs3mtdz3nuc792nmf", - "shares": "700270403.000000000000000000" - }, - { - "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "shares": "3315560612.000000000000000000" - }, - { - "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "shares": "11335873807.000000000000000000" - }, - { - "delegator_address": "cosmos15tv54z32xgqechywvr7ymsfdvr2mmx3553j8rd", - "validator_address": "cosmosvaloper15tv54z32xgqechywvr7ymsfdvr2mmx3539xj07", - "shares": "10646429954.000000000000000000" - }, - { - "delegator_address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "shares": "2244459128.000000000000000000" - }, - { - "delegator_address": "cosmos15vf60ssrdq6fh9ln5a9wtd6f3q64sktl6vk2ss", - "validator_address": "cosmosvaloper15vf60ssrdq6fh9ln5a9wtd6f3q64sktllczlur", - "shares": "502656802.000000000000000000" - }, - { - "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", - "validator_address": "cosmosvaloper15v4py2nqd8a7amn63g3jgtedtzd8qlajd97w8s", - "shares": "974110958.000000000000000000" - }, - { - "delegator_address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "shares": "9209912.000000000000000000" - }, - { - "delegator_address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "shares": "14053872866.000000000000000000" - }, - { - "delegator_address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "shares": "11015469214.000000000000000000" - }, - { - "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", - "validator_address": "cosmosvaloper1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2v4rrnn", - "shares": "7094821824.000000000000000000" - }, - { - "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", - "validator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "shares": "15044102286.000000000000000000" - }, - { - "delegator_address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", - "validator_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "shares": "2930417970.000000000000000000" - }, - { - "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", - "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "shares": "5685279942.000000000000000000" - }, - { - "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", - "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "shares": "4593224997.000000000000000000" - }, - { - "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", - "validator_address": "cosmosvaloper15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4ue0l4p", - "shares": "1062187041.000000000000000000" - }, - { - "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "shares": "7193234568.000000000000000000" - }, - { - "delegator_address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "shares": "23543464834.000000000000000000" - }, - { - "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "shares": "1456184772.000000000000000000" - }, - { - "delegator_address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", - "validator_address": "cosmosvaloper15njmhwxm9ehmgm63dhg9rze2kfuk35qfm5avtx", - "shares": "568146686.000000000000000000" - }, - { - "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", - "validator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "shares": "21856354084.000000000000000000" - }, - { - "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", - "validator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "shares": "16248624224.000000000000000000" - }, - { - "delegator_address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "shares": "324333952.000000000000000000" - }, - { - "delegator_address": "cosmos1556dzhyv2gth4huxdlyur65c2sm3np2en3zzhl", - "validator_address": "cosmosvaloper1rlzurkn0mywyldswcafhu7r8r0tha4s5yhyye0", - "shares": "6217452551.000000000000000000" - }, - { - "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "validator_address": "cosmosvaloper1gd779gn33yuxxla5pm5dphglcyx4ulzdnfv39x", - "shares": "18762995915.000000000000000000" - }, - { - "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "shares": "19978115021.000000000000000000" - }, - { - "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "shares": "269676102.000000000000000000" - }, - { - "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "shares": "821954529.000000000000000000" - }, - { - "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "shares": "10949797827.000000000000000000" - }, - { - "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "shares": "1677820405.000000000000000000" - }, - { - "delegator_address": "cosmos15cfduq92j3uvam8u942xj4egs42tjzl6p33fu5", - "validator_address": "cosmosvaloper15cfduq92j3uvam8u942xj4egs42tjzl6y99us8", - "shares": "14156647.000000000000000000" - }, - { - "delegator_address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", - "validator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "shares": "22863613869.000000000000000000" - }, - { - "delegator_address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "shares": "2205728211.000000000000000000" - }, - { - "delegator_address": "cosmos15uqsf4wke3ylyp0elnka2rvaefhsmhgjhe5mxf", - "validator_address": "cosmosvaloper15uqsf4wke3ylyp0elnka2rvaefhsmhgjjdqw26", - "shares": "8741308900.000000000000000000" - }, - { - "delegator_address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "shares": "7421590485.000000000000000000" - }, - { - "delegator_address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", - "validator_address": "cosmosvaloper15ughagcacjqyaa0f7d28xtev88v5vh699c54t9", - "shares": "24026548.000000000000000000" - }, - { - "delegator_address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "shares": "8706091689.000000000000000000" - }, - { - "delegator_address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", - "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "shares": "16363250391.000000000000000000" - }, - { - "delegator_address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "shares": "7165994372.000000000000000000" - }, - { - "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "shares": "3115334630.000000000000000000" - }, - { - "delegator_address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", - "validator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos14q9rupnazu0mmkjd9skpn2zdfs8d0hlghzpk0v", - "validator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "validator_address": "cosmosvaloper1rrp0lpmx2yzd8d62y7flvg2eyh2n49l39tpt47", - "shares": "260728313.000000000000000000" - }, - { - "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "validator_address": "cosmosvaloper14rhly0ayx5ewyldmrp8kn564wnn8aasc62f3cy", - "shares": "492237770.000000000000000000" - }, - { - "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "shares": "6269261784.000000000000000000" - }, - { - "delegator_address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "shares": "357887239.000000000000000000" - }, - { - "delegator_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "shares": "20515760055.000000000000000000" - }, - { - "delegator_address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "shares": "5887196.000000000000000000" - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "shares": "2267056403.000000000000000000" - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "shares": "2449818489.000000000000000000" - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "shares": "110749654.000000000000000000" - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "shares": "16977263624.000000000000000000" - }, - { - "delegator_address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "shares": "3439625151.000000000000000000" - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "shares": "126313.000000000000000000" - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "shares": "7332243055.000000000000000000" - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "shares": "127732919.000000000000000000" - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper1289vtnyn8vg9rwv7jdcy2ht3h68627htqp7rat", - "shares": "998573733.000000000000000000" - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "shares": "3169550.000000000000000000" - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper15ppnu758napp54m693ypq4fw7hzj8gd2ukscs7", - "shares": "60608473.000000000000000000" - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper14se5hzhf43yk83pkztukhtlfu683s4ktvn35q3", - "shares": "125301.000000000000000000" - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "shares": "16667182589.000000000000000000" - }, - { - "delegator_address": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", - "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "shares": "18994769458.000000000000000000" - }, - { - "delegator_address": "cosmos14j4mehgc448s2m7cr0uqm3pmvjxav94wmq80w4", - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "shares": "1854783297.000000000000000000" - }, - { - "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "shares": "16404106448.000000000000000000" - }, - { - "delegator_address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "shares": "40666822.000000000000000000" - }, - { - "delegator_address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "shares": "52986923.026489101418518680" - }, - { - "delegator_address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "shares": "157324268.000000000000000000" - }, - { - "delegator_address": "cosmos14hr55k3es7xfc54gwgu3plde0vaxkgerljee6v", - "validator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "shares": "20670117972.000000000000000000" - }, - { - "delegator_address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "shares": "1160822532.000000000000000000" - }, - { - "delegator_address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", - "validator_address": "cosmosvaloper14e4xnla8ulqmvgc825jaerhgw3sh7exctfu6lz", - "shares": "3041120922.000000000000000000" - }, - { - "delegator_address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "shares": "2921862659.000000000000000000" - }, - { - "delegator_address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "shares": "22147479421.000000000000000000" - }, - { - "delegator_address": "cosmos14m0pzuhkpjnx2esurz6kcxcjvlkcdzk7e43krz", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "shares": "2468850551.000000000000000000" - }, - { - "delegator_address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", - "validator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "shares": "821774041.000000000000000000" - }, - { - "delegator_address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "shares": "20037186316.000000000000000000" - }, - { - "delegator_address": "cosmos14urapj7e6tj2s8clcsgyat6xmkppj7nm4qtewf", - "validator_address": "cosmosvaloper14urapj7e6tj2s8clcsgyat6xmkppj7nms5lvz6", - "shares": "5480500900.000000000000000000" - }, - { - "delegator_address": "cosmos147pq4rzswl76kdeyx8sc7pagf4nhjpnq2hlrh3", - "validator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "shares": "22417960991.000000000000000000" - }, - { - "delegator_address": "cosmos1478sx3zdfylsts5sus5rlz4dgvyvacqpuchj6f", - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos147lwcm3tx6uhtjphxwwmk7u32mucukalplv80z", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "shares": "1601474401.000000000000000000" - }, - { - "delegator_address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "shares": "352271656.000000000000000000" - }, - { - "delegator_address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", - "validator_address": "cosmosvaloper14lwqx5380234f0fshaycluz08yw74chl3a0a77", - "shares": "10941491018.000000000000000000" - }, - { - "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "validator_address": "cosmosvaloper12f4fpl936ld8c64dxqgwv65p42na8dcnf3ut60", - "shares": "145922218.000000000000000000" - }, - { - "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "shares": "375360.000000000000000000" - }, - { - "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "validator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "shares": "57475597.000000000000000000" - }, - { - "delegator_address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "shares": "1616674805.000000000000000000" - }, - { - "delegator_address": "cosmos1kz20p7j939s8cqadmqqws80c6z93qdtyg8xt0v", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "shares": "9782915598.000000000000000000" - }, - { - "delegator_address": "cosmos1kxl7gsad663he7lgn66wx6gr3egnfj85dt22pv", - "validator_address": "cosmosvaloper1kxl7gsad663he7lgn66wx6gr3egnfj85gl7ldl", - "shares": "2533410912.000000000000000000" - }, - { - "delegator_address": "cosmos1kfnt5d5fcma9kh4c5jk85yu75jer72kwdltg4s", - "validator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "shares": "21181468286.000000000000000000" - }, - { - "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", - "validator_address": "cosmosvaloper1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalafcmy2d", - "shares": "322814192.000000000000000000" - }, - { - "delegator_address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", - "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "shares": "607985470.000000000000000000" - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "shares": "14714606427.000000000000000000" - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_address": "cosmosvaloper12ud83clhrm4jemkal6v0489e0cdm8x0lw6s48r", - "shares": "7038279055.000000000000000000" - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "shares": "17602930321.000000000000000000" - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "shares": "671837638.000000000000000000" - }, - { - "delegator_address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "shares": "4201547532.000000000000000000" - }, - { - "delegator_address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "shares": "5669282913.000000000000000000" - }, - { - "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "validator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "shares": "65633207.000000000000000000" - }, - { - "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "validator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "shares": "11280504984.000000000000000000" - }, - { - "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "shares": "3391706116.000000000000000000" - }, - { - "delegator_address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "validator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2", - "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "shares": "9571086511.000000000000000000" - }, - { - "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", - "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "shares": "9033381920.000000000000000000" - }, - { - "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "shares": "6858058479.000000000000000000" - }, - { - "delegator_address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "shares": "827898827.000000000000000000" - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "shares": "11943268264.000000000000000000" - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "shares": "2696689996.000000000000000000" - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "shares": "7482618743.000000000000000000" - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "shares": "1637026536.000000000000000000" - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "shares": "3409616214.000000000000000000" - }, - { - "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "shares": "22288761371.000000000000000000" - }, - { - "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", - "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "shares": "166860.000000000000000000" - }, - { - "delegator_address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", - "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "shares": "12266067.000000000000000000" - }, - { - "delegator_address": "cosmos1kjupa2w6rlhzj9fjxz35m02g2wpz790fd6mf0j", - "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "shares": "11188036452.000000000000000000" - }, - { - "delegator_address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", - "validator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "shares": "18799915325.000000000000000000" - }, - { - "delegator_address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", - "validator_address": "cosmosvaloper1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx84t2ngt", - "shares": "6269426755.000000000000000000" - }, - { - "delegator_address": "cosmos1kmly2aspt8rk9h4ukdt8h52k24alvc34qukp2n", - "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "shares": "9031700237.000000000000000000" - }, - { - "delegator_address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", - "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "shares": "11830766683.000000000000000000" - }, - { - "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", - "validator_address": "cosmosvaloper1zzey9t59j5x7j5z9f3urms7faq0gq9dw7dy65e", - "shares": "68637287.000000000000000000" - }, - { - "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "shares": "21882314874.000000000000000000" - }, - { - "delegator_address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", - "validator_address": "cosmosvaloper1kaunlwq2aakrheyvm206dd2dh4sjtfa00d7zxq", - "shares": "199824149.000000000000000000" - }, - { - "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "shares": "9460610373.000000000000000000" - }, - { - "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", - "validator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "shares": "7918208867.000000000000000000" - }, - { - "delegator_address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "shares": "15608731707.000000000000000000" - }, - { - "delegator_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "shares": "3123465186.000000000000000000" - }, - { - "delegator_address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "shares": "14982594771.000000000000000000" - }, - { - "delegator_address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "shares": "9107793740.000000000000000000" - }, - { - "delegator_address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", - "validator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "shares": "457781724.000000000000000000" - }, - { - "delegator_address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "shares": "5446202786.000000000000000000" - }, - { - "delegator_address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "shares": "361851785.000000000000000000" - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "shares": "6774702429.000000000000000000" - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lp83wyp2", - "shares": "185779104.000000000000000000" - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "shares": "137048444.000000000000000000" - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1tzz5l8sw05e0tm5l0gxuvp04qt42stu3n56uer", - "shares": "3084665544.000000000000000000" - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1hyv7jjh3kswlfc6nh0xp545rl5ttty2xddpmns", - "shares": "2095189904.000000000000000000" - }, - { - "delegator_address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "shares": "6709581679.000000000000000000" - }, - { - "delegator_address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe", - "validator_address": "cosmosvaloper1h9sv6zz2jdqj2u674r2j7srnx2ad4kr23r9222", - "shares": "4203532933.000000000000000000" - }, - { - "delegator_address": "cosmos1hxdqddf3u8vjm080ytpe959uktn4axdas3uqhl", - "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "shares": "13179632835.000000000000000000" - }, - { - "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "shares": "106422691.000000000000000000" - }, - { - "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "shares": "441014433.000000000000000000" - }, - { - "delegator_address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", - "validator_address": "cosmosvaloper1hx7pezmj2euq3u088xluep0fywggztge0wmtgl", - "shares": "23136285.000000000000000000" - }, - { - "delegator_address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "shares": "785421895.000000000000000000" - }, - { - "delegator_address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "shares": "576145955.000000000000000000" - }, - { - "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "shares": "489746723.000000000000000000" - }, - { - "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", - "validator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "shares": "2551565111.000000000000000000" - }, - { - "delegator_address": "cosmos1h84c3yuxd6k7950wh868tcsj5tmvzetykv8lld", - "validator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "shares": "3599965031.000000000000000000" - }, - { - "delegator_address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "shares": "6422847905.000000000000000000" - }, - { - "delegator_address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", - "validator_address": "cosmosvaloper1hfshektc9gmedj5aly922qvvtwh9fj2pg4p8vz", - "shares": "1408273393.000000000000000000" - }, - { - "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", - "validator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "shares": "14815040085.000000000000000000" - }, - { - "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", - "validator_address": "cosmosvaloper12qzdh6cxrgn3t4v0e90m8005mrqakqaupsrp03", - "shares": "1360036310.000000000000000000" - }, - { - "delegator_address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", - "validator_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "shares": "1912310410.000000000000000000" - }, - { - "delegator_address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", - "validator_address": "cosmosvaloper1hwvpltdvjus4euanyzcp97l96gfsg86ecsm75w", - "shares": "2108075856.000000000000000000" - }, - { - "delegator_address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "shares": "19205968225.000000000000000000" - }, - { - "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "shares": "7720105335.000000000000000000" - }, - { - "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "shares": "2555870064.000000000000000000" - }, - { - "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "validator_address": "cosmosvaloper1hwea4x7eagt83nvaz93q3q5gpje64nczdpj0as", - "shares": "1987459876.000000000000000000" - }, - { - "delegator_address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "shares": "10677551922.000000000000000000" - }, - { - "delegator_address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq", - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", - "validator_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "shares": "1612739646.000000000000000000" - }, - { - "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "shares": "10343736976.000000000000000000" - }, - { - "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "shares": "1316682053.000000000000000000" - }, - { - "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "shares": "1003510952.000000000000000000" - }, - { - "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "validator_address": "cosmosvaloper1hc5k2vf82jswmnlfrrav6u2kf6rn39mp44egzj", - "shares": "927350399.000000000000000000" - }, - { - "delegator_address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "shares": "8106078214.000000000000000000" - }, - { - "delegator_address": "cosmos1h6j4lyvuenmz9m7vq3hler8j7pg5ldpet0xf9a", - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "shares": "17690207109.000000000000000000" - }, - { - "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", - "validator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "shares": "2588611065.000000000000000000" - }, - { - "delegator_address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", - "validator_address": "cosmosvaloper1h65n2jz4ka75akxt8wm2fjk7guvx6qfmkzfujj", - "shares": "4006205.000000000000000000" - }, - { - "delegator_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "shares": "9393510961.000000000000000000" - }, - { - "delegator_address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", - "validator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "shares": "15675831119.000000000000000000" - }, - { - "delegator_address": "cosmos1haw8fcay84fjlsdl5cyev275ldj30z3r27m0g5", - "validator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "shares": "6372741624.000000000000000000" - }, - { - "delegator_address": "cosmos1h72kkqt83nth0npqvgmardgelg6jyx7zupnypp", - "validator_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "shares": "1604525333.000000000000000000" - }, - { - "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "validator_address": "cosmosvaloper1xxurm2uymwd04sjxqedjae5r0zxhalh2lyzn5c", - "shares": "995278414.000000000000000000" - }, - { - "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "validator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "shares": "2129694907.000000000000000000" - }, - { - "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "validator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "shares": "19279146842.000000000000000000" - }, - { - "delegator_address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "validator_address": "cosmosvaloper1h7nkedpkxm0t752j0q88rhgwjn94p4y23yn3lt", - "shares": "2665221917.000000000000000000" - }, - { - "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "shares": "9304209052.000000000000000000" - }, - { - "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "shares": "18386606315.000000000000000000" - }, - { - "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "shares": "3680624756.000000000000000000" - }, - { - "delegator_address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "validator_address": "cosmosvaloper1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy0cflac", - "shares": "3002111009.000000000000000000" - }, - { - "delegator_address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "shares": "35571003.000000000000000000" - }, - { - "delegator_address": "cosmos1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptd8zyma", - "validator_address": "cosmosvaloper1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptgnk3hw", - "shares": "8559089572.000000000000000000" - }, - { - "delegator_address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", - "validator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "shares": "1483865601.000000000000000000" - }, - { - "delegator_address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "shares": "20731656728.000000000000000000" - }, - { - "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", - "validator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "shares": "19455408606.000000000000000000" - }, - { - "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "shares": "2739638648.000000000000000000" - }, - { - "delegator_address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", - "validator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "shares": "19129298483.000000000000000000" - }, - { - "delegator_address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", - "validator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "shares": "4147746231.000000000000000000" - }, - { - "delegator_address": "cosmos1cwk6x5smzaqhtrz95z0sf90d8a8d9vfrpaufnl", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "shares": "22113286739.000000000000000000" - }, - { - "delegator_address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "shares": "3421255938.000000000000000000" - }, - { - "delegator_address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", - "validator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "shares": "13796856153.000000000000000000" - }, - { - "delegator_address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", - "validator_address": "cosmosvaloper1c07ez82s6kcfyg9szzg0pgghdpl7a2k0gtxxd4", - "shares": "5261551412.000000000000000000" - }, - { - "delegator_address": "cosmos1c4lft2m4yyrzjsxyu7nzsrxuskgtlr2crzzwwd", - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "shares": "4541366.000000000000000000" - }, - { - "delegator_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", - "validator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "shares": "6661497942.000000000000000000" - }, - { - "delegator_address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", - "validator_address": "cosmosvaloper1ckrj43y28ta0rxfvdudtmtvvkrvev4340jku3y", - "shares": "7924071421.000000000000000000" - }, - { - "delegator_address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "shares": "36701249402.000000000000000000" - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "shares": "641381462.000000000000000000" - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "shares": "9991492.000000000000000000" - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "shares": "5093480749.000000000000000000" - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1kmly2aspt8rk9h4ukdt8h52k24alvc349gz5xq", - "shares": "20581321.000000000000000000" - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "shares": "1112547.000000000000000000" - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "shares": "131936453.000000000000000000" - }, - { - "delegator_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "shares": "4250535918.000000000000000000" - }, - { - "delegator_address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", - "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "shares": "4792139392.000000000000000000" - }, - { - "delegator_address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", - "validator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "shares": "282264887.000000000000000000" - }, - { - "delegator_address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", - "validator_address": "cosmosvaloper1cupqtankeqe6wsmdgph5p289es2j5wd5yu4pxs", - "shares": "211016457.000000000000000000" - }, - { - "delegator_address": "cosmos1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6x000jc", - "validator_address": "cosmosvaloper1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6rmm67t", - "shares": "1201306698.000000000000000000" - }, - { - "delegator_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "shares": "986773968.000000000000000000" - }, - { - "delegator_address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", - "validator_address": "cosmosvaloper1er8j0tqpn9jftqscdkr7cnlgvedcxwnmvee3e0", - "shares": "249261878.000000000000000000" - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "validator_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "shares": "543089195.000000000000000000" - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "validator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "shares": "390088156.000000000000000000" - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "shares": "23613691655.000000000000000000" - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "shares": "522473074.000000000000000000" - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "shares": "113007060.000000000000000000" - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "shares": "15252711477.000000000000000000" - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper1k34mg8jd05mfuw3pmcll4sz4fyhxqvghn4q9ee", - "shares": "64540087.000000000000000000" - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "shares": "9703623543.000000000000000000" - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "shares": "6161948206.000000000000000000" - }, - { - "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "shares": "21462438160.000000000000000000" - }, - { - "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "validator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "shares": "533098317.000000000000000000" - }, - { - "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "validator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "shares": "2286530039.000000000000000000" - }, - { - "delegator_address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "shares": "1320373881.000000000000000000" - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper19rn7ykwqdrc2ftrwefkqqgq9te3q78nk8jz2fy", - "shares": "759535878.000000000000000000" - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "shares": "139593046.000000000000000000" - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "shares": "856982353.000000000000000000" - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "shares": "14322672203.000000000000000000" - }, - { - "delegator_address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "validator_address": "cosmosvaloper1e2vx7q54npgmck0sf4kwseav50c5tewxfuxeud", - "shares": "199636304.000000000000000000" - }, - { - "delegator_address": "cosmos1etrkjjjjvuej87yu2pv4mcmhjsjqsn5hm9n043", - "validator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "shares": "23226246980.000000000000000000" - }, - { - "delegator_address": "cosmos1evqmj6ahqf76keas4ymhvf4r992kg7wrar0fru", - "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "shares": "3652777037.000000000000000000" - }, - { - "delegator_address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", - "validator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "shares": "23356660678.000000000000000000" - }, - { - "delegator_address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", - "validator_address": "cosmosvaloper1evys94earewfdh658d0u67j28lq2ltezx9gzx9", - "shares": "1119920089.000000000000000000" - }, - { - "delegator_address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266", - "validator_address": "cosmosvaloper1edwe9quhqnxa4yvqu2ks656guv6rjzhtusdlkf", - "shares": "5987604552.000000000000000000" - }, - { - "delegator_address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6", - "validator_address": "cosmosvaloper1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na5efzvf", - "shares": "11089478639.000000000000000000" - }, - { - "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "shares": "32924160.000000000000000000" - }, - { - "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "shares": "1792101072.000000000000000000" - }, - { - "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "shares": "466233357.000000000000000000" - }, - { - "delegator_address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "shares": "18772263304.000000000000000000" - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "shares": "2616582981.000000000000000000" - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper1zukq6nknswp76ckcj5s9rnvmye974n7c9ggtlv", - "shares": "40296136.000000000000000000" - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "shares": "155780036.000000000000000000" - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper18056m2nw355q2tjmvdslp9fqadmca5up76t0q0", - "shares": "39749190.000000000000000000" - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "shares": "372091968.000000000000000000" - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "shares": "5054551129.000000000000000000" - }, - { - "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "shares": "3120662598.000000000000000000" - }, - { - "delegator_address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", - "validator_address": "cosmosvaloper1e4zygycdhs6kpgem9cpddmvk5zyh8wr8rr8w6f", - "shares": "247885300.000000000000000000" - }, - { - "delegator_address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", - "validator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", - "validator_address": "cosmosvaloper1t7m8vs498jhd3jnsxxg33lk37uacc2n52x9c5g", - "shares": "9203549637.000000000000000000" - }, - { - "delegator_address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", - "validator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "shares": "13243911263.000000000000000000" - }, - { - "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "validator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "shares": "1392479696.000000000000000000" - }, - { - "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "validator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "shares": "892316992.000000000000000000" - }, - { - "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", - "shares": "7847492642.000000000000000000" - }, - { - "delegator_address": "cosmos1em3y3h4g7n8ue3wjcramnpmz0x8rwakrpjmrgz", - "validator_address": "cosmosvaloper1em3y3h4g7n8ue3wjcramnpmz0x8rwakryx0ky3", - "shares": "12071046098.000000000000000000" - }, - { - "delegator_address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "shares": "1397139502.000000000000000000" - }, - { - "delegator_address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "shares": "18480450616.000000000000000000" - }, - { - "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", - "validator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "shares": "1682063162.000000000000000000" - }, - { - "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "shares": "2652495105.000000000000000000" - }, - { - "delegator_address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", - "validator_address": "cosmosvaloper1eumpungfa2vmx20e27wnu6t0rtmrlmv3gqphe3", - "shares": "2778547888.000000000000000000" - }, - { - "delegator_address": "cosmos1easmlky76c302my07gffjxjw0a2usueaw8j46t", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "shares": "23176847255.000000000000000000" - }, - { - "delegator_address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", - "validator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "shares": "5503709183.000000000000000000" - }, - { - "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "shares": "14812554077.000000000000000000" - }, - { - "delegator_address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", - "validator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "shares": "19565632897.000000000000000000" - }, - { - "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "shares": "6892307704.000000000000000000" - }, - { - "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", - "validator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "shares": "545803690.000000000000000000" - }, - { - "delegator_address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", - "validator_address": "cosmosvaloper1ellx23lw5uxmdnyjpnn03expxvu89kd6rcvm78", - "shares": "5402886314.000000000000000000" - }, - { - "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", - "validator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "shares": "2401456661.000000000000000000" - }, - { - "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "shares": "3540231870.000000000000000000" - }, - { - "delegator_address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", - "validator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "shares": "19127653549.000000000000000000" - }, - { - "delegator_address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "shares": "8305994215.000000000000000000" - }, - { - "delegator_address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos16tr72kn90g5zl7qhyhuqkjflejz00uzlkl65sj", - "validator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos16v3h2mggt8tnkxp0vq5tq25fhr3knvf4jw40l5", - "validator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "shares": "23883466891.000000000000000000" - }, - { - "delegator_address": "cosmos160jtaz9c35nr7dx349ezfzvs3xfdzm3mlxgulk", - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "shares": "23889133768.000000000000000000" - }, - { - "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "validator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "shares": "12642546664.000000000000000000" - }, - { - "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "shares": "5113128716.000000000000000000" - }, - { - "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "validator_address": "cosmosvaloper16sn6wjtd0kw4yvc7780cpayhz0x45d27v72vz8", - "shares": "230136377.000000000000000000" - }, - { - "delegator_address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "shares": "233651324.000000000000000000" - }, - { - "delegator_address": "cosmos16jj80c7d94m772cn77zwcuhnqcl6y95kepxvja", - "validator_address": "cosmosvaloper1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphvx2qlc", - "shares": "3841134273.000000000000000000" - }, - { - "delegator_address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n", - "validator_address": "cosmosvaloper16auet6ducwkpuehn97wvz5k5rsws8a7laj05kq", - "shares": "13444158275.000000000000000000" - }, - { - "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "shares": "2280542883.000000000000000000" - }, - { - "delegator_address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", - "validator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "shares": "90986838.000000000000000000" - }, - { - "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", - "validator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "shares": "1523447464.000000000000000000" - }, - { - "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", - "validator_address": "cosmosvaloper16ll03qy5htuech4u0z432zertwhyxynl39y2mt", - "shares": "3562717063.000000000000000000" - }, - { - "delegator_address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "shares": "11761380768.000000000000000000" - }, - { - "delegator_address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", - "validator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "shares": "3799625898.000000000000000000" - }, - { - "delegator_address": "cosmos1mzsvp23mjrjkspddkz6nta0x7kte6a23atg6ml", - "validator_address": "cosmosvaloper1mzsvp23mjrjkspddkz6nta0x7kte6a23clu0hv", - "shares": "2228698398.000000000000000000" - }, - { - "delegator_address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", - "validator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "shares": "7881585438.000000000000000000" - }, - { - "delegator_address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", - "validator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "shares": "11902636114.000000000000000000" - }, - { - "delegator_address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", - "validator_address": "cosmosvaloper1mgnalmnc45uj6yhamy9tpc9q6s2exswns33jxg", - "shares": "965626724.000000000000000000" - }, - { - "delegator_address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "shares": "22330517668.000000000000000000" - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3ulnqjw", - "shares": "245003068.000000000000000000" - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "shares": "2561447038.000000000000000000" - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "shares": "3452658290.000000000000000000" - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "shares": "1753289412.000000000000000000" - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "shares": "1407135534.000000000000000000" - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "shares": "385810656.000000000000000000" - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "shares": "349164048.000000000000000000" - }, - { - "delegator_address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", - "validator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "shares": "14577877248.000000000000000000" - }, - { - "delegator_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "shares": "466196437.000000000000000000" - }, - { - "delegator_address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", - "validator_address": "cosmosvaloper1m2n6v8dy6hw5798d3l8uvd4wjg6vsswsq456uq", - "shares": "2479274676.000000000000000000" - }, - { - "delegator_address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", - "validator_address": "cosmosvaloper1m26w2aa36gfwzmn58l7w739edmlrhfn4fqu8nk", - "shares": "4394402323.000000000000000000" - }, - { - "delegator_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "shares": "43994659.000000000000000000" - }, - { - "delegator_address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", - "validator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "shares": "32603015.000000000000000000" - }, - { - "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", - "validator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "shares": "1040485229.000000000000000000" - }, - { - "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "shares": "13388065636.000000000000000000" - }, - { - "delegator_address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "shares": "18071051811.000000000000000000" - }, - { - "delegator_address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", - "validator_address": "cosmosvaloper1s34kukvsrdgap0pjh0alnql7vvv9m83m0w7jz7", - "shares": "610981525.000000000000000000" - }, - { - "delegator_address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "shares": "315677262.000000000000000000" - }, - { - "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", - "validator_address": "cosmosvaloper18nsp3hvv530ge4ag3qwa27jr8r65s8ll0ksrte", - "shares": "712016860.000000000000000000" - }, - { - "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", - "validator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "shares": "18830990390.000000000000000000" - }, - { - "delegator_address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", - "validator_address": "cosmosvaloper1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkfazfyk", - "shares": "1199437642.000000000000000000" - }, - { - "delegator_address": "cosmos1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfej3rle", - "validator_address": "cosmosvaloper1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfux9kn2", - "shares": "1494931451.000000000000000000" - }, - { - "delegator_address": "cosmos1m4xvwvq7qrr0wy0ryeu24eu8482h4n7en2x2mh", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "shares": "10673600913.000000000000000000" - }, - { - "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "shares": "97785114.000000000000000000" - }, - { - "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", - "validator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "shares": "22087360379.000000000000000000" - }, - { - "delegator_address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "shares": "1744984549.000000000000000000" - }, - { - "delegator_address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "shares": "8455755268.000000000000000000" - }, - { - "delegator_address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "shares": "8173781116.000000000000000000" - }, - { - "delegator_address": "cosmos1mcc0dq93nrt3u6hl6ju82hyw3rdfun029jx4v2", - "validator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "shares": "3120721396.000000000000000000" - }, - { - "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "validator_address": "cosmosvaloper1q03kay3adsttv6watm3agqktnpuuxs65c3fhsl", - "shares": "319721226.000000000000000000" - }, - { - "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "validator_address": "cosmosvaloper18nag9zrh49uaxypx83fmlz85umq0t9j73q3svu", - "shares": "2104208415.000000000000000000" - }, - { - "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "shares": "4301090429.000000000000000000" - }, - { - "delegator_address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "shares": "2332669614.000000000000000000" - }, - { - "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", - "validator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "shares": "3420827405.000000000000000000" - }, - { - "delegator_address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", - "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "shares": "24395123.000000000000000000" - }, - { - "delegator_address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "shares": "1067919041.000000000000000000" - }, - { - "delegator_address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", - "validator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "shares": "482001747.000000000000000000" - }, - { - "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "validator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "shares": "5366509387.000000000000000000" - }, - { - "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "validator_address": "cosmosvaloper1yr5ztk7t7w329lllmylgz6wnfk664qu0j7gshs", - "shares": "508102761.000000000000000000" - }, - { - "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "shares": "12895342060.000000000000000000" - }, - { - "delegator_address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "validator_address": "cosmosvaloper1mltm55z9lk9me9qle2jyajcw8dkwnf4myve6pu", - "shares": "781062755.000000000000000000" - }, - { - "delegator_address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "shares": "8844305443.000000000000000000" - }, - { - "delegator_address": "cosmos1urnp7yp6u27nut8kvsrapgmmvk8sh6u5wd5dez", - "validator_address": "cosmosvaloper1urnp7yp6u27nut8kvsrapgmmvk8sh6u5teqc43", - "shares": "13977340603.000000000000000000" - }, - { - "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", - "validator_address": "cosmosvaloper1k0ymmgnecsq72nsytp97wtvrr5zu4gm3edqa8e", - "shares": "69406130.000000000000000000" - }, - { - "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", - "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", - "shares": "120397764.000000000000000000" - }, - { - "delegator_address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", - "validator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "shares": "163640358.000000000000000000" - }, - { - "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "validator_address": "cosmosvaloper189mctxmcxlrl7rjzrnlpshzvn5lr775cp379j0", - "shares": "254035.000000000000000000" - }, - { - "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "validator_address": "cosmosvaloper12k6u60mgp8wldpz2xs2u3p3skmghtrjyq2cwpp", - "shares": "111239871.000000000000000000" - }, - { - "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "validator_address": "cosmosvaloper1m6pn2hzhw44x5f0ev95yfav50l4annkghp3cmr", - "shares": "24027809.000000000000000000" - }, - { - "delegator_address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "validator_address": "cosmosvaloper1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lhwnx4x", - "shares": "251933.000000000000000000" - }, - { - "delegator_address": "cosmos1uvm96xdewfpdwymw5ywt8j5efq6jhpyl35pzg8", - "validator_address": "cosmosvaloper1uvm96xdewfpdwymw5ywt8j5efq6jhpyl5q4hy5", - "shares": "7577447491.000000000000000000" - }, - { - "delegator_address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "shares": "5904983738.000000000000000000" - }, - { - "delegator_address": "cosmos1uuk9ewj0532rzlhlg86tserdxvtnm3kq2k2zww", - "validator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", - "validator_address": "cosmosvaloper1hxdqddf3u8vjm080ytpe959uktn4axda49g4mv", - "shares": "663734465.000000000000000000" - }, - { - "delegator_address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", - "validator_address": "cosmosvaloper1u7rqjvmm9sss60dm8urfjhcdet0tmafawspkhh", - "shares": "763826873.000000000000000000" - }, - { - "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", - "validator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "shares": "1330954959.000000000000000000" - }, - { - "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", - "validator_address": "cosmosvaloper1n3lnhxzzm7ntheu78h6v4zag7zmrlp48wx8z9z", - "shares": "449732008.000000000000000000" - }, - { - "delegator_address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "shares": "140255592.000000000000000000" - }, - { - "delegator_address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "shares": "627370738.000000000000000000" - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1z7ruhrtfg8v2xv8egfyxldt2xaygspyk4k87wl", - "shares": "11523735546.000000000000000000" - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "shares": "1576940428.000000000000000000" - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "shares": "607901853.000000000000000000" - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "shares": "108025410.000000000000000000" - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "shares": "212323217.000000000000000000" - }, - { - "delegator_address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "shares": "7597437829.000000000000000000" - }, - { - "delegator_address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", - "validator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "shares": "1420797965.000000000000000000" - }, - { - "delegator_address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", - "validator_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "shares": "9361230791.000000000000000000" - }, - { - "delegator_address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", - "validator_address": "cosmosvaloper1artlw5e2222rk3wzyewk9qse8spp9t3kv4q6u2", - "shares": "82979650.000000000000000000" - }, - { - "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "shares": "11238205953.000000000000000000" - }, - { - "delegator_address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "shares": "330891000.000000000000000000" - }, - { - "delegator_address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", - "validator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "shares": "8106199.000000000000000000" - }, - { - "delegator_address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", - "validator_address": "cosmosvaloper1a2us5nm6r2azfwqefh5u9r3g36ddduzra4ag4g", - "shares": "6631273690.000000000000000000" - }, - { - "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", - "validator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "shares": "24565420625.000000000000000000" - }, - { - "delegator_address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", - "validator_address": "cosmosvaloper1atqlhvdg7slrrkrhpqc44vk6nqhnvdsf6jng9c", - "shares": "5682430.000000000000000000" - }, - { - "delegator_address": "cosmos1adwsqn58aype530jae9qrwknsxyf3wmwdr523z", - "validator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", - "validator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "shares": "10992310558.000000000000000000" - }, - { - "delegator_address": "cosmos1awyus34e6laq3zxqsrv283w6fgn8w62zkwd87d", - "validator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1a0jdqzvk078d6486vuxdr5d0yp6rglue2nh5dn", - "validator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "shares": "9613933711.000000000000000000" - }, - { - "delegator_address": "cosmos1a5fndlfnwtvyzzt7ql4kvuqgnjut7ua7hkfts6", - "validator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "shares": "9415626255.000000000000000000" - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "shares": "3906909228.000000000000000000" - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper18r683wlut54pd8sjzz45ujq8nu4wfr65y8ry4x", - "shares": "5370042726.000000000000000000" - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "shares": "1682096242.000000000000000000" - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "shares": "844335956.000000000000000000" - }, - { - "delegator_address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "validator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "shares": "7764993320.000000000000000000" - }, - { - "delegator_address": "cosmos1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8kl6qt4", - "validator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", - "shares": "15012824613.000000000000000000" - }, - { - "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", - "validator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "shares": "15288776108.000000000000000000" - }, - { - "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", - "validator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "shares": "6780481465.000000000000000000" - }, - { - "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", - "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", - "shares": "228354642.000000000000000000" - }, - { - "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "shares": "7055399052.000000000000000000" - }, - { - "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", - "validator_address": "cosmosvaloper1k2a93ktn30tznww5spyczstxzgvcxd9y6qcrmv", - "shares": "13186298825.000000000000000000" - }, - { - "delegator_address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", - "validator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "shares": "21448624442.000000000000000000" - }, - { - "delegator_address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", - "validator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "shares": "17547096641.000000000000000000" - }, - { - "delegator_address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "shares": "2615326319.000000000000000000" - }, - { - "delegator_address": "cosmos17ph7nmvmxdhm687z4k5phsyd08wvsnv44emkj8", - "validator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "shares": "3648941591.000000000000000000" - }, - { - "delegator_address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", - "validator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "shares": "2878563531.000000000000000000" - }, - { - "delegator_address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", - "validator_address": "cosmosvaloper17zgp4m7ptx9jlvr56dnyu0yx0lz3st28zp9dwe", - "shares": "1820280319.000000000000000000" - }, - { - "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", - "validator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "shares": "22489048481.000000000000000000" - }, - { - "delegator_address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", - "validator_address": "cosmosvaloper17z20092e9s2ttlzkpzv209dsxsxs946jzujtec", - "shares": "2580293599.000000000000000000" - }, - { - "delegator_address": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos178pm30fcgrt5654czwr8nlex050m6y609glx2s", - "validator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "shares": "23703504292.000000000000000000" - }, - { - "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", - "validator_address": "cosmosvaloper13spl9rpkd0wd9c32mpsd9h6phwwnxu3uklhm86", - "shares": "2914482410.000000000000000000" - }, - { - "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", - "validator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "shares": "1110360222.000000000000000000" - }, - { - "delegator_address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "shares": "18525526004.000000000000000000" - }, - { - "delegator_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", - "validator_address": "cosmosvaloper1ryy20he94rlaryj04mkhcj6n4dhuhcytsgx5jz", - "shares": "4722611768.000000000000000000" - }, - { - "delegator_address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", - "validator_address": "cosmosvaloper1fdfwthdupznzgrg2d8e96ryxqz8smppew74lj0", - "shares": "1627510175.000000000000000000" - }, - { - "delegator_address": "cosmos17gpy6jzg7xdsr2xc7kweljagx4uaysxdk2244g", - "validator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "shares": "7651697131.000000000000000000" - }, - { - "delegator_address": "cosmos17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnk5g0lz", - "validator_address": "cosmosvaloper17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnnqu6n3", - "shares": "227804730.000000000000000000" - }, - { - "delegator_address": "cosmos172lmu2psqlkxkthpr46h2ewjffte7lhlmwe6tg", - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos17tecr2sngjcm2rc29dzmadtpad2tkmrhj69whr", - "validator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "shares": "16752793632.000000000000000000" - }, - { - "delegator_address": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", - "validator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "shares": "718921425.000000000000000000" - }, - { - "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", - "validator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "shares": "2738776488.000000000000000000" - }, - { - "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", - "validator_address": "cosmosvaloper1ef5ydlpyvpxnp0pftagpsmfssxm0v2arqh80j9", - "shares": "2115827243.000000000000000000" - }, - { - "delegator_address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", - "validator_address": "cosmosvaloper17da97e4gq5p2zavzcd0zmsh7ez540j0cl4tmlr", - "shares": "1397104980.000000000000000000" - }, - { - "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", - "validator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "shares": "3213489253.000000000000000000" - }, - { - "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", - "validator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "shares": "21648809872.000000000000000000" - }, - { - "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "shares": "146683.000000000000000000" - }, - { - "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "shares": "89280204.000000000000000000" - }, - { - "delegator_address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", - "validator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "shares": "251790.000000000000000000" - }, - { - "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", - "validator_address": "cosmosvaloper1x4yzfjt777agvsfz6cskjst7v7k42xc63ntlst", - "shares": "633536370.000000000000000000" - }, - { - "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", - "validator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "shares": "6767814744.000000000000000000" - }, - { - "delegator_address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "shares": "117960718.000000000000000000" - }, - { - "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", - "validator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "shares": "23981371945.000000000000000000" - }, - { - "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", - "validator_address": "cosmosvaloper17s43pumh0z4fffw7e0sdrh0e894d2h4lv6qk83", - "shares": "300592036.000000000000000000" - }, - { - "delegator_address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "shares": "39160384.000000000000000000" - }, - { - "delegator_address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", - "validator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "shares": "2364587435.000000000000000000" - }, - { - "delegator_address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", - "validator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "shares": "8013043987.000000000000000000" - }, - { - "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", - "validator_address": "cosmosvaloper1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n7lq8kzq", - "shares": "18869340.000000000000000000" - }, - { - "delegator_address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", - "validator_address": "cosmosvaloper1m6x26lfu6lzqfh7g05qf8a46f90sdfpj0cl2vj", - "shares": "218958522.000000000000000000" - }, - { - "delegator_address": "cosmos174ycyhzg358nxm8r6qunzsyx48uk8fc404ckyf", - "validator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "shares": "8680187636.000000000000000000" - }, - { - "delegator_address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", - "validator_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "shares": "1221107604.000000000000000000" - }, - { - "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "validator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "shares": "411136992.000000000000000000" - }, - { - "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "validator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "shares": "1317573671.000000000000000000" - }, - { - "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "shares": "22514769356.000000000000000000" - }, - { - "delegator_address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "validator_address": "cosmosvaloper17k35dydvkrdxup6z8633k3zcc4ecmgnz7zphpv", - "shares": "825862061.000000000000000000" - }, - { - "delegator_address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck", - "validator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "shares": "2602618529.000000000000000000" - }, - { - "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", - "validator_address": "cosmosvaloper19deqn6g9q7mnhzg5j0qr25k9gz74pwlpjq4prs", - "shares": "165098526.000000000000000000" - }, - { - "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", - "validator_address": "cosmosvaloper1twyey6dyu57e7p8lahwgr9ql2pyn6774uqlh48", - "shares": "4718627.000000000000000000" - }, - { - "delegator_address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", - "validator_address": "cosmosvaloper17hc7jg6vkxcfdem4q9rkwrr2azjkygahgpe733", - "shares": "340930766.000000000000000000" - }, - { - "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", - "validator_address": "cosmosvaloper1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljr9z5rml", - "shares": "2968081872.000000000000000000" - }, - { - "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", - "validator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "shares": "1681443586.000000000000000000" - }, - { - "delegator_address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "shares": "5740343356.000000000000000000" - }, - { - "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "validator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "shares": "3023435039.000000000000000000" - }, - { - "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "validator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "shares": "12958021951.000000000000000000" - }, - { - "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "validator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "shares": "3755696144.000000000000000000" - }, - { - "delegator_address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "shares": "17646792.000000000000000000" - }, - { - "delegator_address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", - "validator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "shares": "6724622674.000000000000000000" - }, - { - "delegator_address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", - "validator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "shares": "18344719406.000000000000000000" - }, - { - "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "validator_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "shares": "6656587767.000000000000000000" - }, - { - "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "validator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "shares": "986856358.000000000000000000" - }, - { - "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "validator_address": "cosmosvaloper17uhjt4f6xj7hww44vmettp4a0c8lz44nms8k2q", - "shares": "159276935.000000000000000000" - }, - { - "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "shares": "1168681082.000000000000000000" - }, - { - "delegator_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", - "validator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "shares": "2711574997.000000000000000000" - }, - { - "delegator_address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", - "validator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "shares": "18120372537.000000000000000000" - }, - { - "delegator_address": "cosmos1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpkca4g8", - "validator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "shares": "15023386396.000000000000000000" - }, - { - "delegator_address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", - "validator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "shares": "2867035102.000000000000000000" - }, - { - "delegator_address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", - "validator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "shares": "10621822118.000000000000000000" - }, - { - "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "validator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "shares": "58360958.000000000000000000" - }, - { - "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "validator_address": "cosmosvaloper19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyurmwkx0", - "shares": "81292948.000000000000000000" - }, - { - "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "validator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "shares": "89358777.000000000000000000" - }, - { - "delegator_address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "validator_address": "cosmosvaloper1lxeq6h6a8xvq6587nh7f5xkehdkn3wst98mzfg", - "shares": "281580943.000000000000000000" - }, - { - "delegator_address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", - "validator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "shares": "513446339.000000000000000000" - }, - { - "delegator_address": "cosmos1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqcrj0xk", - "validator_address": "cosmosvaloper1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqahx629", - "shares": "1028714701.000000000000000000" - }, - { - "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", - "validator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "shares": "1078037731.000000000000000000" - }, - { - "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", - "validator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "shares": "252433656.000000000000000000" - }, - { - "delegator_address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", - "validator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "shares": "23612702988.000000000000000000" - }, - { - "delegator_address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "shares": "11614756424.000000000000000000" - }, - { - "delegator_address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", - "validator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "shares": "21096282678.000000000000000000" - }, - { - "delegator_address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", - "validator_address": "cosmosvaloper1r7kh63jvjhwqraux9wtm3jat8ggm437wqvjd2t", - "shares": "9417801394.000000000000000000" - }, - { - "delegator_address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", - "validator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "shares": "2119723899.000000000000000000" - }, - { - "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", - "validator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "shares": "174754983.000000000000000000" - }, - { - "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", - "validator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "shares": "18558143415.000000000000000000" - }, - { - "delegator_address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", - "validator_address": "cosmosvaloper1lderwuws96gg2e5vy8eyhpgegakeswcfkhl8qz", - "shares": "179430222.000000000000000000" - }, - { - "delegator_address": "cosmos1l5d2lg5hku0m4u8mh866zhjcy2dekpk598m8wr", - "validator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "shares": "25069342080.000000000000000000" - }, - { - "delegator_address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", - "validator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "shares": "8362968596.000000000000000000" - }, - { - "delegator_address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", - "validator_address": "cosmosvaloper1w2ly5qah2m47qguaukzr6xx34hszqh8u0xmlah", - "shares": "425532255.000000000000000000" - }, - { - "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", - "validator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "shares": "15967116837.000000000000000000" - }, - { - "delegator_address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", - "validator_address": "cosmosvaloper1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax59g0l4", - "shares": "3907335026.000000000000000000" - }, - { - "delegator_address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn", - "validator_address": "cosmosvaloper1lhkja97vjzfjxakwsglnkspaparrg56pz9l6pq", - "shares": "2977168576.000000000000000000" - }, - { - "delegator_address": "cosmos1l6u5cg3wcptmcjyhxtfrrfq3nu036acdauf0fy", - "validator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "shares": "15368943494.000000000000000000" - }, - { - "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", - "validator_address": "cosmosvaloper1cmw920g9png4x7g5rzjn22qqagz9cyh7mtkg3l", - "shares": "2295367808.000000000000000000" - }, - { - "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", - "validator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "shares": "209859957.000000000000000000" - }, - { - "delegator_address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", - "validator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "shares": "19453723967.000000000000000000" - }, - { - "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "shares": "7497643277.000000000000000000" - }, - { - "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", - "validator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "shares": "8982227181.000000000000000000" - }, - { - "delegator_address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", - "validator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "shares": "13950070710.000000000000000000" - }, - { - "delegator_address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", - "validator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "shares": "11119271370.000000000000000000" - } - ], - "unbonding_delegations": [ - { - "delegator_address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", - "validator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "entries": [ - { - "creation_height": "49", - "completion_time": "9936-01-04T20:29:20Z", - "initial_balance": "183076477", - "balance": "183076477" - } - ] - }, - { - "delegator_address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", - "validator_address": "cosmosvaloper1q3ttxum2fvcfhg44ttdnm3qecrygdevuzue9ce", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2005303616", - "balance": "2005303616" - } - ] - }, - { - "delegator_address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", - "validator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "entries": [ - { - "creation_height": "50", - "completion_time": "9936-01-04T22:14:51Z", - "initial_balance": "15030300002", - "balance": "15030300002" - } - ] - }, - { - "delegator_address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", - "validator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "20593666623", - "balance": "20593666623" - } - ] - }, - { - "delegator_address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", - "validator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "4199831033", - "balance": "4199831033" - } - ] - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "29439356", - "balance": "29439356" - } - ] - }, - { - "delegator_address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", - "validator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "14986173529", - "balance": "14986173529" - } - ] - }, - { - "delegator_address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", - "validator_address": "cosmosvaloper1hyzzthl6vy5vjucaalz9w6fkyqne5p55a2xwt4", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "3732148769", - "balance": "3732148769" - } - ] - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper18cr3udfd35s2ktqlj25fujxnu9sax8h6eyd937", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "25509388", - "balance": "25509388" - } - ] - }, - { - "delegator_address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "validator_address": "cosmosvaloper1sugh75fnvl48jyt6ya59vn9fv74qqkkcv2tq42", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "1895209", - "balance": "1895209" - } - ] - }, - { - "delegator_address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", - "validator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "6983331316", - "balance": "6983331316" - } - ] - }, - { - "delegator_address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", - "validator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "19374447530", - "balance": "19374447530" - } - ] - }, - { - "delegator_address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", - "validator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "335873680", - "balance": "335873680" - } - ] - }, - { - "delegator_address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", - "validator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2656231998", - "balance": "2656231998" - } - ] - }, - { - "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", - "validator_address": "cosmosvaloper1twg3k83aluz6nsqt09pa246rg5wg6fhwevsup4", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "1564778153", - "balance": "1564778153" - } - ] - }, - { - "delegator_address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", - "validator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2570223192", - "balance": "2570223192" - } - ] - }, - { - "delegator_address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "validator_address": "cosmosvaloper1x72py7gr6pd72ch7u380ay04t9mhf3fku0sg6x", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2395235221", - "balance": "2395235221" - } - ] - }, - { - "delegator_address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", - "validator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "entries": [ - { - "creation_height": "50", - "completion_time": "9936-01-04T22:14:51Z", - "initial_balance": "18962902821", - "balance": "18962902821" - } - ] - }, - { - "delegator_address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "validator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "10483079", - "balance": "10483079" - } - ] - }, - { - "delegator_address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "validator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "3109466079", - "balance": "3109466079" - } - ] - }, - { - "delegator_address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "validator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "726017962", - "balance": "726017962" - } - ] - }, - { - "delegator_address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", - "validator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "196636283", - "balance": "196636283" - } - ] - }, - { - "delegator_address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "validator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "240781727", - "balance": "240781727" - } - ] - }, - { - "delegator_address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", - "validator_address": "cosmosvaloper10jgkuly673ukhgeeu95dte84wm7cwtk28x4fmt", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "311403029", - "balance": "311403029" - } - ] - }, - { - "delegator_address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", - "validator_address": "cosmosvaloper10ndcqfr2zwrspryphtuhq883kc49z38f6c4nx4", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2590271094", - "balance": "2590271094" - }, - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "3133575935", - "balance": "3133575935" - } - ] - }, - { - "delegator_address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", - "validator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "716875401", - "balance": "716875401" - } - ] - }, - { - "delegator_address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", - "validator_address": "cosmosvaloper1en4tuzw9trweqsjukz4hyvlw89cptzlqz3lfyd", - "entries": [ - { - "creation_height": "50", - "completion_time": "9936-01-04T22:14:51Z", - "initial_balance": "3339815870", - "balance": "3339815870" - } - ] - }, - { - "delegator_address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", - "validator_address": "cosmosvaloper1j2uu5jpphmr7vk5f6yvx093hs2u2ef9gzrsjyz", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "3944810", - "balance": "3944810" - } - ] - }, - { - "delegator_address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", - "validator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "4956381732", - "balance": "4956381732" - } - ] - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "915982", - "balance": "915982" - } - ] - }, - { - "delegator_address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "validator_address": "cosmosvaloper12zamvlnrz3fvxdaymyhmxfjlnpaz6aw5sg2j0q", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "11358632", - "balance": "11358632" - } - ] - }, - { - "delegator_address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", - "validator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "13733468273", - "balance": "13733468273" - } - ] - }, - { - "delegator_address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", - "validator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "32611419", - "balance": "32611419" - } - ] - }, - { - "delegator_address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", - "validator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "entries": [ - { - "creation_height": "50", - "completion_time": "9936-01-04T22:14:51Z", - "initial_balance": "11282230082", - "balance": "11282230082" - } - ] - }, - { - "delegator_address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "validator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "5091227059", - "balance": "5091227059" - } - ] - }, - { - "delegator_address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", - "validator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "entries": [ - { - "creation_height": "50", - "completion_time": "9936-01-04T22:14:51Z", - "initial_balance": "237207832", - "balance": "237207832" - } - ] - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "156945410", - "balance": "156945410" - } - ] - }, - { - "delegator_address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", - "validator_address": "cosmosvaloper1t87pn4cjpdy0pwtk5hut30pw9jd7swedeandj8", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2401741158", - "balance": "2401741158" - } - ] - }, - { - "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", - "validator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2874294826", - "balance": "2874294826" - } - ] - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "3627849543", - "balance": "3627849543" - } - ] - }, - { - "delegator_address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "validator_address": "cosmosvaloper1cc00387cdawytytnks0gd9yy9fq7ne6wfzzfje", - "entries": [ - { - "creation_height": "50", - "completion_time": "9936-01-04T22:14:51Z", - "initial_balance": "84069", - "balance": "84069" - } - ] - }, - { - "delegator_address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "validator_address": "cosmosvaloper1x9mhtyr2tak88skl0nr4lq6k7jreus6n3r8eqa", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "7503011", - "balance": "7503011" - } - ] - }, - { - "delegator_address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "validator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "16794484703", - "balance": "16794484703" - } - ] - }, - { - "delegator_address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", - "validator_address": "cosmosvaloper1uylhw5z3gvr6nmpc9z3n6qg496z7m54zycaj2d", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "756303091", - "balance": "756303091" - } - ] - }, - { - "delegator_address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", - "validator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "4217365098", - "balance": "4217365098" - } - ] - }, - { - "delegator_address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", - "validator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "16832773759", - "balance": "16832773759" - } - ] - }, - { - "delegator_address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", - "validator_address": "cosmosvaloper1al0nkrxpkc3vpcerakr66sed56zdmmrez7y3fl", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2771729865", - "balance": "2771729865" - } - ] - }, - { - "delegator_address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", - "validator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "8589471622", - "balance": "8589471622" - } - ] - } - ], - "redelegations": [ - { - "delegator_address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", - "validator_src_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "validator_dst_address": "cosmosvaloper1744t93tc6ulm87ccsc47mkl30qz65n8p0cmczz", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "809035601", - "shares_dst": "809035601.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", - "validator_src_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "validator_dst_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "20636678155", - "shares_dst": "20636678155.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", - "validator_src_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "validator_dst_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2172957336", - "shares_dst": "2172957336.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", - "validator_src_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "validator_dst_address": "cosmosvaloper1q9l78v72yp8mmuthy3cmtjmcl48uydwmnp6l98", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "1856911069", - "shares_dst": "1856911069.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "validator_src_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "validator_dst_address": "cosmosvaloper1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta3f38h9", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "510250360", - "shares_dst": "510250360.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "validator_src_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "validator_dst_address": "cosmosvaloper1vsa4xamvkswn3n65ef7jjzldxqy0p5jrq2j6sn", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "5799285", - "shares_dst": "5799285.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", - "validator_src_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "validator_dst_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "3922123176", - "shares_dst": "3922123176.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", - "validator_src_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "validator_dst_address": "cosmosvaloper1yj95f65syc75ptwcy0n7kafdq33awc2vunr7mn", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "127648169", - "shares_dst": "127648169.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "validator_src_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "validator_dst_address": "cosmosvaloper153rklv33fjex4w7r82n9wnwxrwfgae6n8uy45y", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "240453816", - "shares_dst": "240453816.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "validator_src_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "validator_dst_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "7174712260", - "shares_dst": "7174712260.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", - "validator_src_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "validator_dst_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "11095524326", - "shares_dst": "11095524326.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "validator_src_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "validator_dst_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "51693014", - "shares_dst": "51693014.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "validator_src_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "validator_dst_address": "cosmosvaloper1q62pq2jlj6836ynv6r5fra4txa74duu3ffghhp", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "126313", - "shares_dst": "126313.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "validator_src_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "validator_dst_address": "cosmosvaloper1azqlatsdv9cme5y08qknavjfssrtjrna7z5334", - "entries": [ - { - "creation_height": "50", - "completion_time": "9936-01-04T22:14:51Z", - "initial_balance": "671837638", - "shares_dst": "671837638.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "validator_src_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "validator_dst_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "entries": [ - { - "creation_height": "50", - "completion_time": "9936-01-04T22:14:51Z", - "initial_balance": "2696689996", - "shares_dst": "2696689996.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", - "validator_src_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "validator_dst_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "489746723", - "shares_dst": "489746723.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", - "validator_src_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "validator_dst_address": "cosmosvaloper1dge9en6j6xl3njpkk8gvw9n326pgna44cz6yxr", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "1612739646", - "shares_dst": "1612739646.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", - "validator_src_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "validator_dst_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "19455408606", - "shares_dst": "19455408606.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "validator_src_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "validator_dst_address": "cosmosvaloper1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxr2x446", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "543089195", - "shares_dst": "543089195.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "validator_src_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "validator_dst_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "entries": [ - { - "creation_height": "50", - "completion_time": "9936-01-04T22:14:51Z", - "initial_balance": "113007060", - "shares_dst": "113007060.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "validator_src_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "validator_dst_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "2561447038", - "shares_dst": "2561447038.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", - "validator_src_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "validator_dst_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "entries": [ - { - "creation_height": "49", - "completion_time": "9936-01-04T20:29:20Z", - "initial_balance": "21648809872", - "shares_dst": "21648809872.000000000000000000" - } - ] - }, - { - "delegator_address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "validator_src_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "validator_dst_address": "cosmosvaloper144n7h95z7sz0r3k9rm3r8umkc89wt5c7myk80k", - "entries": [ - { - "creation_height": "48", - "completion_time": "9936-01-04T18:13:47Z", - "initial_balance": "6656587767", - "shares_dst": "6656587767.000000000000000000" - } - ] - } - ], - "historical_infos": [ - { - "header": { - "version": {}, - "chain_id": "simulation-app", - "height": "48", - "time": "9936-01-04T13:24:43Z", - "last_block_id": { - "parts_header": {} - }, - "proposer_address": "ejlFDTFrxPCQ7Xmj4b6HBcqUNQg=" - }, - "valset": [ - { - "operator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels7tpscy", - "status": 3, - "tokens": "24767745772", - "delegator_shares": "24767745772.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.064962829627143450", - "max_rate": "0.700000000000000000", - "max_change_rate": "0.524524837966075502" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xt2s2vh", - "status": 3, - "tokens": "40149298125", - "delegator_shares": "40149298125.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.020987080088521851", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.079654399773437862" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk7tt4rl", - "status": 3, - "tokens": "33873720903", - "delegator_shares": "33873720903.000000000000000000", - "description": { - "moniker": "mLoNnmWUiV", - "identity": "RHiUhLQQnZ", - "website": "GdVEOYibSd", - "security_contact": "DcfUpyGSpE", - "details": "kaQgULDDFV" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.793635545567707656", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.546926599085395557" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcrkzkl0", - "status": 3, - "tokens": "76742997299", - "delegator_shares": "76742997299.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.159853619317053801", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.178173481628386356" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0yv2h8z80vtfttsewrwe2v83haaceax7q3ey95uaeqj8lstf7l674zn3ut", - "status": 3, - "tokens": "16016194501", - "delegator_shares": "16016194501.000000000000000000", - "description": { - "moniker": "WVhrVMjLnZ", - "identity": "QiIQjemxtv", - "website": "KCKlbRarYk", - "security_contact": "AwimEeOMDq", - "details": "omCiVdOfZS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.636807270475032336", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.762928812525012131" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghknhrvft", - "status": 3, - "tokens": "32824956781", - "delegator_shares": "32824956781.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.063963134401067102" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgt7tyq6", - "status": 3, - "tokens": "15545552914", - "delegator_shares": "15545552914.000000000000000000", - "description": { - "moniker": "VaOLitHrfh", - "identity": "zYkbJeTdPC", - "website": "RWLWpQBLTs", - "security_contact": "EEFOrnsvml", - "details": "xRXuWfcvoz" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.209346043397093808", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.261491014079542938" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpvkknmf7", - "status": 3, - "tokens": "34783743330", - "delegator_shares": "34783743330.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.412168984856446389", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.601152598273329028" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qk5quugdx54zsrteg9hpee0ke3z35meukxs34t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4645lf2dka2qs2renc2n2rts24k9xfmxnx5fkhvj3squp8nv5ugyr2nj8", - "status": 3, - "tokens": "25741111893", - "delegator_shares": "25741111893.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.005185006676002722", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.268395235691771325" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvw0g93n8", - "status": 3, - "tokens": "24037432303", - "delegator_shares": "24037432303.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.140843713075627976", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.124247346623493378" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtxrkpudghuhgsu0he7ntk7q0asqa5ax23y7rnn5mfjr2d68z4emsrwqssp", - "status": 3, - "tokens": "44972041218", - "delegator_shares": "44972041218.000000000000000000", - "description": { - "moniker": "eJECwiPlqs", - "identity": "TywZsaZwgH", - "website": "jtFVQJUofX", - "security_contact": "fstanspUpc", - "details": "RQddrwMsIR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.005369299901591159", - "max_rate": "0.030000000000000000", - "max_change_rate": "0.010979308887356502" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwz2zelc", - "status": 3, - "tokens": "24972834479", - "delegator_shares": "24972834479.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118883162683785924", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.582076368438090700" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q205udc4", - "status": 3, - "tokens": "48048764683", - "delegator_shares": "48048764683.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.150000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.137121313165408722" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zycdvvrg7", - "status": 3, - "tokens": "26109827309", - "delegator_shares": "26109827309.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.272379182115041576" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "consensus_pubkey": "cosmosvalconspub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwlhqscf", - "status": 3, - "tokens": "25214890343", - "delegator_shares": "25214890343.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.276804190595109972", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.303611347820460701" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2u3gzal", - "status": 3, - "tokens": "21697576499", - "delegator_shares": "21697576499.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289943655120962524", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.271265684659427360" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgh4tj7q", - "status": 3, - "tokens": "49505425616", - "delegator_shares": "49505425616.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.519126528788995280", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw55ftmtn", - "status": 3, - "tokens": "51494857888", - "delegator_shares": "51494857888.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.006443603339396517", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.110565720532816181" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavc40dh4", - "status": 3, - "tokens": "69365122054", - "delegator_shares": "69365122054.000000000000000000", - "description": { - "moniker": "IoqkplxtIQ", - "identity": "SYtEYnqVjz", - "website": "cbrMdhVrVp", - "security_contact": "eWitXxyhJZ", - "details": "FCojJQQFCQ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.745132980800690980", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.321606633967630124" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tugphy2d", - "status": 3, - "tokens": "17054284690", - "delegator_shares": "17054284690.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.602634897210355218", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.136597759514787421" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jztkylp", - "status": 3, - "tokens": "36407556988", - "delegator_shares": "36407556988.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.052047960532670175", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgrwz3gl", - "status": 3, - "tokens": "17768682341", - "delegator_shares": "17768682341.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.141929485726276362" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yr97z8g", - "status": 3, - "tokens": "22598538029", - "delegator_shares": "22598538029.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.335354744004515496", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.096800797786563611" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2zq3f3j", - "status": 3, - "tokens": "27149799034", - "delegator_shares": "27149799034.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.158969199652087770", - "max_rate": "0.220000000000000000", - "max_change_rate": "0.220000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq246sxc5kns0ym6st5wyf6mk0x2cayek9wngczyvgk8phxrat02cqh8w5p2", - "status": 3, - "tokens": "49314038732", - "delegator_shares": "49314038732.000000000000000000", - "description": { - "moniker": "caRBWwzxXd", - "identity": "BJSnkbfQjh", - "website": "ELsVPBoBHb", - "security_contact": "nZkoSMuzKV", - "details": "AuAKjeoitI" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.010525961964940541", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.045814731203367877" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jhhj4uv", - "status": 3, - "tokens": "26185707851", - "delegator_shares": "26185707851.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.568319127244896272", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.226261076338173049" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5u4v4q5", - "status": 3, - "tokens": "32785129607", - "delegator_shares": "32785129607.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.009044195385937429", - "max_rate": "0.010000000000000000", - "max_change_rate": "0.002281789765845776" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpqq8zx8p", - "status": 3, - "tokens": "33846192792", - "delegator_shares": "33846192792.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.094250378854551281", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.043420993012939508" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv79a2a0wcq9kr62m5yupvx82mlxwxw6hx7c8dyl4trf8k2w7vh3w5wlhy0", - "status": 3, - "tokens": "25066394767", - "delegator_shares": "25066394767.000000000000000000", - "description": { - "moniker": "liMRThtiLT", - "identity": "QPHsvzHnkx", - "website": "BytvAmppJT", - "security_contact": "iBgKxrOkqF", - "details": "RcELAgZeDN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.115126355797501393", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.289658857878369113" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfp9mvx6gjdezn2vfxn9jk7jm2urml0xyvt3yg64s03yzkfphrthsdy925d", - "status": 3, - "tokens": "25061237568", - "delegator_shares": "25061237568.000000000000000000", - "description": { - "moniker": "wmxxGOZTpL", - "identity": "azxfwYYUUt", - "website": "izxOUVhQSX", - "security_contact": "lRgXsoitme", - "details": "eebhMKbHXO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.578049895054733896", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.402405887034980654" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc255eyr9", - "status": 3, - "tokens": "76621873132", - "delegator_shares": "76621873132.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.321194785873117781", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.561602155526895676" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u43hapa", - "status": 3, - "tokens": "18750673243", - "delegator_shares": "18750673243.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.188948913118426394", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.274693773376656673" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvpup8kv2mmqajfs08aks8yu8kcuwd323y4f0wu9e3k5grynt0g6ule9mjg", - "status": 3, - "tokens": "24248574347", - "delegator_shares": "24248574347.000000000000000000", - "description": { - "moniker": "bsrCMyYTRM", - "identity": "cTWbJOIMRX", - "website": "EMzKHBarjX", - "security_contact": "spsTAIOECF", - "details": "fTrZtqJTUr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.455524678875180233", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-01T06:29:20Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d29fg079", - "status": 3, - "tokens": "82798702711", - "delegator_shares": "82798702711.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289674444273548704", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.060992257943659564" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgss8cv9u", - "status": 3, - "tokens": "26155915081", - "delegator_shares": "26155915081.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.333198345990187069", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.410926346802169727" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "consensus_pubkey": "cosmosvalconspub1addwnpepqghlm3r37c95q3p3wvr8fxw8mvvdtj3tvhgduhzgzh4238ynz6f06f0rjfd", - "status": 3, - "tokens": "32485653471", - "delegator_shares": "32485653471.000000000000000000", - "description": { - "moniker": "hjulbVDPpf", - "identity": "pRsBrwBRzq", - "website": "VjiSZKAfKB", - "security_contact": "UHZkwTciXO", - "details": "JTfVgehmsi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.311759176624756474" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19ve7rrjrngdgf6pfaj87csf4rwykqdmhuqr3x0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqge9z0fefq3xpf8y4q8j57c89x65luk2vtcx5mln75662ukq00f6sqefz8w", - "status": 3, - "tokens": "17425230490", - "delegator_shares": "17425230490.000000000000000000", - "description": { - "moniker": "pGvmyXHQYo", - "identity": "cCQHGXFLSL", - "website": "BaxemamtmF", - "security_contact": "wpZarCOeDy", - "details": "XYyJPmrQVh" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.209082457058936007", - "max_rate": "0.470000000000000000", - "max_change_rate": "0.166552912196145925" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwus66jdl", - "status": 3, - "tokens": "54108139534", - "delegator_shares": "54108139534.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.500000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22ep2k8n", - "status": 3, - "tokens": "69316998057", - "delegator_shares": "69316998057.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.624946300778690751", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.204995912261423056" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7ejhy28", - "status": 3, - "tokens": "27808118568", - "delegator_shares": "27808118568.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.067795278161998694", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.011309118617844055" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5kc0mzw", - "status": 3, - "tokens": "21672426398", - "delegator_shares": "21672426398.000000000000000000", - "description": { - "moniker": "uloyQQWkyI", - "identity": "gFyXSGlhKI", - "website": "ewFltsApZk", - "security_contact": "YGvOhkEKJw", - "details": "vIoOsfiLuj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.068730439287548849", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.118090772640391070" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv0pnal4w8hydpq3vydqgjxmmxz7zg2g9lsj5vedvjq3pw6typfdcjfm5tc", - "status": 3, - "tokens": "16342492210", - "delegator_shares": "16342492210.000000000000000000", - "description": { - "moniker": "jKdcmnPYfC", - "identity": "exfUuYgqmd", - "website": "XdNCNZIBOf", - "security_contact": "hmiwPGchGt", - "details": "nUnBufZQah" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.330000000000000000", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.051583680374523519" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057uxwdfy", - "status": 3, - "tokens": "23352431465", - "delegator_shares": "23352431465.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.760000000000000000", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.183753469845780730" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvy095yf8a7eknhlnwzkum0wt53njxxww60vte7qkutwczt534dwhaclpm", - "status": 3, - "tokens": "34693121909", - "delegator_shares": "34693121909.000000000000000000", - "description": { - "moniker": "MeTXVRIPJJ", - "identity": "TUfYXCkdwb", - "website": "hRiHdgBoDj", - "security_contact": "uoLwAibjAn", - "details": "fXXnusiKCw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.012519787105018298", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.005395717096845063" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef5gg2q6z", - "status": 3, - "tokens": "42958814024", - "delegator_shares": "42958814024.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.077000158168963029", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.197697608060710078" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwv7ukq0", - "status": 3, - "tokens": "21104467943", - "delegator_shares": "21104467943.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.460679550676466675", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.165088210560206816" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwc7h5wds8u3tspx3mwpfh5l3q3rv0t6ff33dt205v2zy2kxev9sykcs9uv", - "status": 3, - "tokens": "29256610441", - "delegator_shares": "29256610441.000000000000000000", - "description": { - "moniker": "iYUgQcrziE", - "identity": "hDYXNaKKIu", - "website": "FYsreoPnoD", - "security_contact": "FGAHzGKfjM", - "details": "gkHwWfssaE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.585764113115952818", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz4r8scm", - "status": 3, - "tokens": "62352159921", - "delegator_shares": "62352159921.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.041535797793389960", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.029250263820409753" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2cxeaw4", - "status": 3, - "tokens": "38271499795", - "delegator_shares": "38271499795.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.416117321788354038", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.139830256647094326" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazfcl7f9", - "status": 3, - "tokens": "26982328993", - "delegator_shares": "26982328993.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.170000000000000000", - "max_change_rate": "0.024288054259102348" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgxqjc3u3", - "status": 3, - "tokens": "45028692546", - "delegator_shares": "45028692546.000000000000000000", - "description": { - "moniker": "UeFBWJANuQ", - "identity": "gypzUiAlRd", - "website": "zZezcKCiKy", - "security_contact": "KSXTvslQOC", - "details": "qqNIBlVIYk" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.075610127679217055", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.290000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xwmrp7sq", - "status": 3, - "tokens": "35018830437", - "delegator_shares": "35018830437.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.405901469124460870" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "consensus_pubkey": "cosmosvalconspub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc92g545rl", - "status": 3, - "tokens": "17547285969", - "delegator_shares": "17547285969.000000000000000000", - "description": {}, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.073548473514397047", - "max_rate": "0.440000000000000000", - "max_change_rate": "0.413655116572301617" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wyr7x83", - "status": 3, - "tokens": "25071600389", - "delegator_shares": "25071600389.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.280000000000000000", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.063599161373317498" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymswdv67m", - "status": 3, - "tokens": "27784307296", - "delegator_shares": "27784307296.000000000000000000", - "description": { - "moniker": "mjkYspzJbE", - "identity": "xWPMeIdPEi", - "website": "xtRPXfTiQB", - "security_contact": "sdKpqtdpNe", - "details": "MnLujfMpnW" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.100000000000000000", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.072530327063185081" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslqg7mlcx", - "status": 3, - "tokens": "31634692393", - "delegator_shares": "31634692393.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.554757466700447989", - "max_rate": "0.820000000000000000", - "max_change_rate": "0.408903182457515462" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvlfyhyylne6t33wzse5vhjd3xxyrfkjfmdyvk3gq4rrdhe2e0ul2n637uw", - "status": 3, - "tokens": "22842571937", - "delegator_shares": "22842571937.000000000000000000", - "description": { - "moniker": "MCiuCZVGkF", - "identity": "YVlJRRVogl", - "website": "iBpLGvpPpo", - "security_contact": "bvXcaUSxzJ", - "details": "zsHdsXWXhJ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.012334216153398550" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v67hlsk", - "status": 3, - "tokens": "16236700229", - "delegator_shares": "16236700229.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.498536222135788025" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5l4jsmp", - "status": 3, - "tokens": "42927955154", - "delegator_shares": "42927955154.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.190381602916620701", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.303876600993529705" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g7drc35", - "status": 3, - "tokens": "36911230696", - "delegator_shares": "36911230696.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.194945225911581915", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.300000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcas8xka", - "status": 3, - "tokens": "39363181311", - "delegator_shares": "39363181311.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.028169322828760497", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.050000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcvjsxyz", - "status": 3, - "tokens": "27734813665", - "delegator_shares": "27734813665.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.015116864220436494", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskj3a67t", - "status": 3, - "tokens": "24423311847", - "delegator_shares": "24423311847.000000000000000000", - "description": { - "moniker": "OtyVVqWsup", - "identity": "EqaejuaTwX", - "website": "egvJRLAnYF", - "security_contact": "KTzlQLiomS", - "details": "ETXsigXuTY" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.372711230134865265", - "max_rate": "0.460000000000000000", - "max_change_rate": "0.056760418592473079" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjzxhelr", - "status": 3, - "tokens": "25592800910", - "delegator_shares": "25592800910.000000000000000000", - "description": { - "moniker": "NYvAvaIOdj", - "identity": "lYbVDursvX", - "website": "UXtFzZcHjM", - "security_contact": "PNNMeOJqcl", - "details": "ROVIgdvaJl" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.193312772989594496", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.226297820963910157" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsuh3jpet", - "status": 3, - "tokens": "50488222690", - "delegator_shares": "50488222690.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.801397182624616334", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.592521503076154232" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfk090csv4thlsr4kx3fuucwcsk79lqs6gr5zse6m4xmwpq94hy2w3yuqp6", - "status": 3, - "tokens": "20659893696", - "delegator_shares": "20659893696.000000000000000000", - "description": { - "moniker": "gqjwubbLDT", - "identity": "OsKsdzWbsv", - "website": "rhWGeqAAVi", - "security_contact": "FmaEvvcaAr", - "details": "uMULjHPlYr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.168812875456833709" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5t7pxck", - "status": 3, - "tokens": "53644768786", - "delegator_shares": "53644768786.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.180000000000000000", - "max_change_rate": "0.029528662482337368" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2z47zet", - "status": 3, - "tokens": "22907460275", - "delegator_shares": "22907460275.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.026318239077074162", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.076792434560738120" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyw0np92", - "status": 3, - "tokens": "27374742411", - "delegator_shares": "27374742411.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.053895535796610462", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.182737583024108345" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2al69u7pnek9kcrmz83vstrst5szxuz6z03z0d848kuh3ekkjlfgr96q6z", - "status": 3, - "tokens": "20929858941", - "delegator_shares": "20929858941.000000000000000000", - "description": { - "moniker": "ciowxbJZpb", - "identity": "XgDAZmwEir", - "website": "moPXkGzyqT", - "security_contact": "WTLysotltH", - "details": "qoTHCiKGoL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003240694138410597", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.013650990946439583" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12rjah2jl9jpqwddh20vph9yu448d76257c5cw6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtq4rjflca8vgyn08w3vkpqeq57d80dmja25rd0ntqrx5fxm96gtw0umkjg", - "status": 3, - "tokens": "24938844767", - "delegator_shares": "24938844767.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.639608494106780282", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.911798500947612916" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper128xc6r596pllf46ev2cpaetcujfgmhay2c3yzv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwz7uypw37mz5eky5vktatrwu84geyy9r8jp9dccd73kw62x5hkn54qgedr", - "status": 3, - "tokens": "15286357237", - "delegator_shares": "15286357237.000000000000000000", - "description": { - "moniker": "rXurTMjZPL", - "identity": "AwsdgVtWKY", - "website": "MqIvWlvqZq", - "security_contact": "hoJFiVyrtB", - "details": "FWXLLEocRp" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.298667840621478601", - "max_rate": "0.620000000000000000", - "max_change_rate": "0.023377726384901617" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzvca96h", - "status": 3, - "tokens": "70162120947", - "delegator_shares": "70162120947.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.545864029263808659", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.533310660658318421" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqlk7nha", - "status": 3, - "tokens": "20279593182", - "delegator_shares": "20279593182.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.069908236020668720", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.009891358364124589" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqva0a8amjektwyshzjv38f6dw5uwat88kscw834kf3026r5ksn77gf0857j", - "status": 3, - "tokens": "27984332905", - "delegator_shares": "27984332905.000000000000000000", - "description": { - "moniker": "BKQyTeKaLC", - "identity": "eCoPebxrNV", - "website": "auQgzJBeZR", - "security_contact": "bLlknxqKWU", - "details": "amiXFmUGDr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.900000000000000000", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.031968764827487641" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4cv2x09p", - "status": 3, - "tokens": "22768989048", - "delegator_shares": "22768989048.000000000000000000", - "description": { - "moniker": "EVTkHBKcpE", - "identity": "hMErYohFOn", - "website": "QaWaMRxOKv", - "security_contact": "qaxyuRDTeX", - "details": "ELwgPpPDKw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.386471695225710439" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfjcp62cfnelz8s5cl5qar8ymfjd5sjjkkr4tayrqrtzpf638hkjqmg9q4z", - "status": 3, - "tokens": "26491705865", - "delegator_shares": "26491705865.000000000000000000", - "description": { - "moniker": "SJeSnSdrXp", - "identity": "OTlQTOJbcV", - "website": "sulWDbaxDh", - "security_contact": "XTGtIDYHdJ", - "details": "KNeohKLilE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.965860683215034339", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.778196912581936923" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "consensus_pubkey": "cosmosvalconspub1addwnpepq28myc67l0yhmnn6n2vq8hcmpaxesglyyqg825ujgrxdt9afwlsfx4ezupt", - "status": 3, - "tokens": "16246649557", - "delegator_shares": "16246649557.000000000000000000", - "description": { - "moniker": "mtHVFaNGLx", - "identity": "YTyhLHiifY", - "website": "JFeCDRXGYc", - "security_contact": "HndWqVmQvE", - "details": "JFVkeOUSbg" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.018292046092814578", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.057525240491425891" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z6ckp5s", - "status": 3, - "tokens": "65372138643", - "delegator_shares": "65372138643.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.323440196337864016" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng9t438v", - "status": 3, - "tokens": "22515450726", - "delegator_shares": "22515450726.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.752425052602923482" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6mcm2m0", - "status": 3, - "tokens": "29556680915", - "delegator_shares": "29556680915.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289048467390880739", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.476925303769745140" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswzcmkck", - "status": 3, - "tokens": "25121635132", - "delegator_shares": "25121635132.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.541820589241677763" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "consensus_pubkey": "cosmosvalconspub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z2xdtk5", - "status": 3, - "tokens": "25474072165", - "delegator_shares": "25474072165.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.493962290871886167", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.601549819261141285" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vype2jq", - "status": 3, - "tokens": "59694062218", - "delegator_shares": "59694062218.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.047504130944412074", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.160000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xzg536q0eksvxd2297ycyctfwp6x7rk0wq6d0murld346cjs756v0jnxn", - "status": 3, - "tokens": "16949426508", - "delegator_shares": "16949426508.000000000000000000", - "description": { - "moniker": "dNCvXIwisF", - "identity": "PInuRSnoAB", - "website": "IFaDEJuVii", - "security_contact": "DiiitKvkqG", - "details": "wJQyZMjCjC" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083382298074645848", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.156261937510636548" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag73jg46g", - "status": 3, - "tokens": "41973269906", - "delegator_shares": "41973269906.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.742458631966852296", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.368222450098111604" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4d6e962zqejqu3jeypzp740n4k62xte2qnj82q03y28v6wkshycxxdg5w", - "status": 3, - "tokens": "18158211957", - "delegator_shares": "18158211957.000000000000000000", - "description": { - "moniker": "cVYtBkXobK", - "identity": "JOBpTikHPq", - "website": "NyobvRjfBj", - "security_contact": "bKDbHWcmSW", - "details": "xGfkOaAoAb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.340000000000000000", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.117974822314921419" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4cv0e5r0", - "status": 3, - "tokens": "18240625178", - "delegator_shares": "18240625178.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.004320117912957935", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.000447271047532656" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwfwqlzf", - "status": 3, - "tokens": "16806010630", - "delegator_shares": "16806010630.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.926805735750034881", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.482844926743337660" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qavly08", - "status": 3, - "tokens": "17705677177", - "delegator_shares": "17705677177.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.615745867723667485", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.398263247650399274" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwv80xev", - "status": 3, - "tokens": "26461821776", - "delegator_shares": "26461821776.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.157167562506066789", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.091234306987583436" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwudpuh36geydlpx0yjqu0vhauacf294sn2uetg4ush97p382kqag6sxlqg", - "status": 3, - "tokens": "17862559018", - "delegator_shares": "17862559018.000000000000000000", - "description": { - "moniker": "wSgJTwBWiv", - "identity": "AEATmOIHsP", - "website": "WsuxwwJUIx", - "security_contact": "nzWdiJbKcf", - "details": "WXwvQKoIbT" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.120000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.027292850423387945" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq4e58fv", - "status": 3, - "tokens": "112536605413", - "delegator_shares": "112536605413.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.592057337572123856", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.208226705977271974" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7kquya74", - "status": 3, - "tokens": "27525740131", - "delegator_shares": "27525740131.000000000000000000", - "description": { - "moniker": "ajDNnhnkbN", - "identity": "nkdfsqWVlx", - "website": "CeqAfYeTdW", - "security_contact": "KMQJbxKkbm", - "details": "cvAUuqNFYs" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.780000000000000000", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.550890306122411684" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj4x3m9h", - "status": 3, - "tokens": "57637848348", - "delegator_shares": "57637848348.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.081821299211443922", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.458576374327765136" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey2vtdvu", - "status": 3, - "tokens": "19834101875", - "delegator_shares": "19834101875.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.491522368582129610", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.085253529277298261" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0aa00frx8hxrq5pegc0vnt69pj54z3dhwzy8uumr3nhgsc772h0zyr473p", - "status": 3, - "tokens": "37175356106", - "delegator_shares": "37175356106.000000000000000000", - "description": { - "moniker": "oedtWfExZY", - "identity": "taFwTdIwwz", - "website": "oGBHKapVuy", - "security_contact": "hnggEiQcYu", - "details": "qOFIRfzDGP" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083784124252551147", - "max_rate": "0.650000000000000000", - "max_change_rate": "0.550897578676987786" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dsktaxw5", - "status": 3, - "tokens": "55634424696", - "delegator_shares": "55634424696.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.016380613584719475", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.310000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "consensus_pubkey": "cosmosvalconspub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz28vhtm", - "status": 3, - "tokens": "17891746276", - "delegator_shares": "17891746276.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.528106308050967540" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqehts4m", - "status": 3, - "tokens": "56186314306", - "delegator_shares": "56186314306.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.128525196978986815", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.100900376719373255" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru72w0xm", - "status": 3, - "tokens": "18560827275", - "delegator_shares": "18560827275.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.100218404029226728", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.881639682871578638" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00qxpqlwy0p6y9tl23yu7fpu55lhznxa3hrhvsuma6h7lu4c3ekks4wvua", - "status": 3, - "tokens": "22083357722", - "delegator_shares": "22083357722.000000000000000000", - "description": { - "moniker": "LvOuePvVwo", - "identity": "vfegdQlOfT", - "website": "mYvkvMZuDp", - "security_contact": "cfrddDLOlu", - "details": "yHfcxdGyEO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.122593865256918850", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.840000000000000000" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxkm9kvvp", - "status": 3, - "tokens": "26763354026", - "delegator_shares": "26763354026.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.027810962515737967", - "max_rate": "0.070000000000000000", - "max_change_rate": "0.034717076557320762" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvykaseh7", - "status": 3, - "tokens": "68955304480", - "delegator_shares": "68955304480.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.208925360976246176", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.463634503057540350" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peggwy7x5", - "status": 3, - "tokens": "48684061528", - "delegator_shares": "48684061528.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.338644152469426553", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.069153802725768656" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxz2ead4", - "status": 3, - "tokens": "19233426986", - "delegator_shares": "19233426986.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.373154376676147691", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wjfqd63", - "status": 3, - "tokens": "25961659072", - "delegator_shares": "25961659072.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.068613373696134985", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.073351676068018235" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7ul2hc3", - "status": 3, - "tokens": "33320443806", - "delegator_shares": "33320443806.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118849597906926326", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.228258187539755185" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7whvstg", - "status": 3, - "tokens": "36328452639", - "delegator_shares": "36328452639.000000000000000000", - "description": { - "moniker": "cVUXvMdRgs", - "identity": "AHkjmtOkYK", - "website": "KLRPQOyDoY", - "security_contact": "VHwCrfhVnI", - "details": "qdFVvUucvR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.182731553781057822", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.045316794895420248" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqde6g57cex9ff650ku6dqdqtfulfnzkacecf6k436xl0dd07zglxx5659h9", - "status": 3, - "tokens": "34893400220", - "delegator_shares": "34893400220.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.905848795661145449", - "max_rate": "0.950000000000000000", - "max_change_rate": "0.476775855507110704" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy7220f9ul3", - "status": 3, - "tokens": "33772482275", - "delegator_shares": "33772482275.000000000000000000", - "description": { - "moniker": "znFMdpLOQw", - "identity": "LEMEnpcxqp", - "website": "TjKmeKjDGm", - "security_contact": "ZOXcBhlDyq", - "details": "WpmmnksSqL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.834910862331446014", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cuyxrn7n", - "status": 3, - "tokens": "24587685968", - "delegator_shares": "24587685968.000000000000000000", - "description": { - "moniker": "tlYEYvdvKp", - "identity": "fQFtYLRSZA", - "website": "ecuAofwdaj", - "security_contact": "gwsuBeDyJU", - "details": "gELFJGuwPs" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.499259642246008210", - "max_rate": "0.560000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jet5tg3", - "status": 3, - "tokens": "62232444428", - "delegator_shares": "62232444428.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.153116543667039838", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.230000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yfudg7m", - "status": 3, - "tokens": "25948607110", - "delegator_shares": "25948607110.000000000000000000", - "description": { - "moniker": "IssGiFwTJv", - "identity": "VgTaqmOLtN", - "website": "BpkICmEqwF", - "security_contact": "qmrIWxiWft", - "details": "sLtbcsMFgA" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.136694009459855954", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.056116480834729575" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4c8wkdlg", - "status": 3, - "tokens": "18426946099", - "delegator_shares": "18426946099.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.469814499540087620", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.960000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvquc4jf3", - "status": 3, - "tokens": "16774945156", - "delegator_shares": "16774945156.000000000000000000", - "description": { - "moniker": "hZvyDgtWxX", - "identity": "TPMmELNQYL", - "website": "YxTdbJnobM", - "security_contact": "ZURHxVMZoL", - "details": "zVjWraUVyE" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.258972799025106506", - "max_rate": "0.910000000000000000", - "max_change_rate": "0.304259315697044502" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprs83zeag", - "status": 3, - "tokens": "29277603589", - "delegator_shares": "29277603589.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.351977697440288211" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvly6j0pyezy88s9lnat6taglylzq03vvsvyw4uy2tv3vcl3200ej0nev4k", - "status": 3, - "tokens": "16864097437", - "delegator_shares": "16864097437.000000000000000000", - "description": { - "moniker": "lasYiVeRDA", - "identity": "TFiGxJBNUs", - "website": "xswbDClAxs", - "security_contact": "HYUurzqzcC", - "details": "EVSfzEFSuo" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.036542719943188247", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.304756516958654494" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66dra0w3", - "status": 3, - "tokens": "19540440011", - "delegator_shares": "19540440011.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.065303820000927065", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.134868108685582589" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afqga9sv8", - "status": 3, - "tokens": "26083594771", - "delegator_shares": "26083594771.000000000000000000", - "description": { - "moniker": "uVtPIVoLeB", - "identity": "UQUjtBkUkU", - "website": "lrfjDXnSyH", - "security_contact": "tPWaAehpKA", - "details": "YCcmQgJRnO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.859185512301348293", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.915098787337318307" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrq06r4ck", - "status": 3, - "tokens": "41543247193", - "delegator_shares": "41543247193.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.119695944592116460" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4vjajc6x", - "status": 3, - "tokens": "61843733534", - "delegator_shares": "61843733534.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.437478542817284441", - "max_rate": "0.530000000000000000", - "max_change_rate": "0.308410375933996023" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvghhzrgz", - "status": 3, - "tokens": "34513851602", - "delegator_shares": "34513851602.000000000000000000", - "description": { - "moniker": "rUZvoFLmub", - "identity": "dQGYIJXPFq", - "website": "ZPoXnJmgzU", - "security_contact": "MdbwPJFNHC", - "details": "NdoQBlpUhN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.670000000000000000", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.629855974067904060" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz4luxgn", - "status": 3, - "tokens": "33206633235", - "delegator_shares": "33206633235.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.229284159886860129", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.212917450108859841" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw24c76ax", - "status": 3, - "tokens": "27567655084", - "delegator_shares": "27567655084.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.216560651737526756", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.026445047137608599" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qpu7x5c", - "status": 3, - "tokens": "27671960609", - "delegator_shares": "27671960609.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.077841535313299819", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.054979434313866047" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2wcjjal", - "status": 3, - "tokens": "25069342080", - "delegator_shares": "25069342080.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.249161816461641720", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.693944288516379645" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akutfqm7", - "status": 3, - "tokens": "55737096951", - "delegator_shares": "55737096951.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.498362112747574396", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.645641814068879323" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693hazjkkehy", - "status": 3, - "tokens": "38011116376", - "delegator_shares": "38011116376.000000000000000000", - "description": { - "moniker": "mUQFKtnPLD", - "identity": "xsxoaAIVkh", - "website": "EBARfZhhON", - "security_contact": "GynbBFtcRq", - "details": "RftDCeMUPi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.123876475355091478", - "max_rate": "0.860000000000000000", - "max_change_rate": "0.141162753552435345" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v30nmws", - "status": 3, - "tokens": "78601464028", - "delegator_shares": "78601464028.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083731202536014652", - "max_rate": "0.860000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9ykjrzn93", - "status": 3, - "tokens": "18090212819", - "delegator_shares": "18090212819.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.081582427988342735", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.086390137368972014" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06my86wxz2", - "status": 3, - "tokens": "33968139195", - "delegator_shares": "33968139195.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.247483015769197525", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.837420192496215212" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2crvswax", - "status": 3, - "tokens": "16516288319", - "delegator_shares": "16516288319.000000000000000000", - "description": { - "moniker": "kVNZIBYAxD", - "identity": "ChbsAFHanI", - "website": "SvHMthzzzB", - "security_contact": "cMJXUgGCfx", - "details": "PWsrYNKuPZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.540000000000000000", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.491525012965837080" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2kj4krx", - "status": 3, - "tokens": "45010236382", - "delegator_shares": "45010236382.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.095070637134115497" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveesw5rr6m", - "status": 3, - "tokens": "54609814420", - "delegator_shares": "54609814420.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.328146514360581742", - "max_rate": "0.810000000000000000", - "max_change_rate": "0.166428198995593213" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68yqxsxnt", - "status": 3, - "tokens": "25326342688", - "delegator_shares": "25326342688.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.785486462764506620", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.356882054361860100" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzlcd6kj", - "status": 3, - "tokens": "67804970220", - "delegator_shares": "67804970220.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.264013069771684883" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4v8fm8e8", - "status": 3, - "tokens": "38042330922", - "delegator_shares": "38042330922.000000000000000000", - "description": { - "moniker": "LDEzyylLGV", - "identity": "NaLpENvFnX", - "website": "ooOcvgIJwr", - "security_contact": "aQaxAlCyFx", - "details": "CxEFcmLmkI" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.099339754970547702", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.111217397607280422" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15qje22esqaz79y27940s3ng7r7afx3vvntdwjt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt5s2m60xv2n7sxjv7lhzlf83u75fh7yc0pjv3thqf5vkdunr32ksh4xsdu", - "status": 3, - "tokens": "15174649749", - "delegator_shares": "15174649749.000000000000000000", - "description": { - "moniker": "VCTScqQSKa", - "identity": "WzaIRwbXgo", - "website": "BAOhQWhmkQ", - "security_contact": "NncLgAxHdH", - "details": "URrsiopqUa" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.047510383078156072", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.032290417291892447" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k907nvf", - "status": 3, - "tokens": "28676349495", - "delegator_shares": "28676349495.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.609184993023386704", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.699887495531371188" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper158hwrawjlg586d47zl4xk9kg3em02vyp4rcuzd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdzvxgkmxur34cmgyyfzr0mkhrysd6xdqpkz6k0qd62y4hl325qd62h02f4", - "status": 3, - "tokens": "17972090246", - "delegator_shares": "17972090246.000000000000000000", - "description": {}, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.870000000000000000", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.063255826123136327" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "consensus_pubkey": "cosmosvalconspub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjtszrqs", - "status": 3, - "tokens": "49921160762", - "delegator_shares": "49921160762.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.810000000000000000", - "max_rate": "0.810000000000000000", - "max_change_rate": "0.810000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "consensus_pubkey": "cosmosvalconspub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku73m9m0", - "status": 3, - "tokens": "17327949928", - "delegator_shares": "17327949928.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.406968367525101581", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.487609794856186092" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfcdg0aax", - "status": 3, - "tokens": "16967510024", - "delegator_shares": "16967510024.000000000000000000", - "description": { - "moniker": "YKKhjZGayb", - "identity": "IvgiPDjmYA", - "website": "gScrUtVzvh", - "security_contact": "kGHySpHXgu", - "details": "IyuehlcoPM" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.093407705950029411", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.187465926844434813" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7zgmra8", - "status": 3, - "tokens": "26261718579", - "delegator_shares": "26261718579.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.210000000000000000", - "max_change_rate": "0.067309904771533509" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqnavslf", - "status": 3, - "tokens": "51218832094", - "delegator_shares": "51218832094.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.895728278286976959", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.140752130806369269" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jyyn3gu", - "status": 3, - "tokens": "19834661379", - "delegator_shares": "19834661379.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.008115100503323252", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yagkfrr", - "status": 3, - "tokens": "46543454731", - "delegator_shares": "46543454731.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.060188716749386269", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.350000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "consensus_pubkey": "cosmosvalconspub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kwmez9k", - "status": 3, - "tokens": "16420725988", - "delegator_shares": "16420725988.000000000000000000", - "description": { - "moniker": "LVfceOUKZE", - "identity": "ZyVUuaCAJZ", - "website": "rliAdTPvEK", - "security_contact": "hVtZPHOsKh", - "details": "QjmMKruCba" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.036920301680485403" - }, - "update_time": "9936-01-01T16:55:11Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq77rpqn", - "status": 3, - "tokens": "22691569600", - "delegator_shares": "22691569600.000000000000000000", - "description": { - "moniker": "BFoqLaJLDn", - "identity": "weLorPCgTe", - "website": "oyhVcpSOLq", - "security_contact": "hdnvhDJTDC", - "details": "SAZISvvmwB" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.160832184115355939", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xw03emk4", - "status": 3, - "tokens": "44313010729", - "delegator_shares": "44313010729.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083856723472306849", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.569378562223247850" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6yp7zp3n", - "status": 3, - "tokens": "25164533156", - "delegator_shares": "25164533156.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.330000000000000000", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.314039829028852779" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvn899z9u9a7h28682292n9y77yr6yuyrg2xvg8eaammccqfuc9e5jp63vn", - "status": 3, - "tokens": "16985369823", - "delegator_shares": "16985369823.000000000000000000", - "description": { - "moniker": "oVMoJSrGgV", - "identity": "ydZuwvoyLe", - "website": "EdyJLNhNGZ", - "security_contact": "QauDavDNuL", - "details": "CVkbnFlumN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.276325858271560152", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.108166159043578444" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwshp63n", - "status": 3, - "tokens": "18994769458", - "delegator_shares": "18994769458.000000000000000000", - "description": { - "moniker": "KODmaZYfBO", - "identity": "dQoWoZcHpD", - "website": "QRjjuYKVNR", - "security_contact": "BHWzdORGfc", - "details": "dZGTxQmqIN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003392332242825811", - "max_rate": "0.060000000000000000", - "max_change_rate": "0.027187395396712775" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqv0lje47", - "status": 3, - "tokens": "54901950842", - "delegator_shares": "54901950842.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.193375046872051394", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.161750559623523660" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc9m7uvt", - "status": 3, - "tokens": "15374405822", - "delegator_shares": "15374405820.680335249007925874", - "description": { - "moniker": "eomlzRaIRN", - "identity": "PaBTVBXpcj", - "website": "frMwzGwrdS", - "security_contact": "XwCgZGftYO", - "details": "oynChhccDw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.014913519812752309", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.219118316904950121" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7dsh8mr", - "status": 3, - "tokens": "31376033263", - "delegator_shares": "31376033263.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.074914975922116628" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14upsvttjem96xlz8rfsw4zqt234jnqy8c4066q", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtplsxcj5j56ms8j7lerl57al6asnrh53uft4efkzvuhv50gq8azx0l5f9w", - "status": 3, - "tokens": "25214408688", - "delegator_shares": "25214408688.000000000000000000", - "description": { - "moniker": "qQzVEWDfcL", - "identity": "LQVrYguqLe", - "website": "BJddIAyseo", - "security_contact": "trbqxTDxYA", - "details": "TTjZQrCkYO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.299140431481446428", - "max_rate": "0.510000000000000000", - "max_change_rate": "0.367721024197463519" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axhh8p8f", - "status": 3, - "tokens": "49683234188", - "delegator_shares": "49683234188.000000000000000000", - "description": { - "moniker": "MJAduJwrkS", - "identity": "YpKMJsMpdh", - "website": "rmUXbHIGjh", - "security_contact": "KxyJSeDEJS", - "details": "gQmDpfNyLZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.637063248045666486", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.100218674012239339" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmkm3zs42", - "status": 3, - "tokens": "34289428306", - "delegator_shares": "34289428306.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.026475742223507385", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.008016543161851368" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw3fj2ga", - "status": 3, - "tokens": "29885998584", - "delegator_shares": "29885998584.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.208832068199199828", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.835848953294536000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2vncgld", - "status": 3, - "tokens": "34516338524", - "delegator_shares": "34516338524.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.400358972669819604", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.343431675789315867" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrywn9e6w", - "status": 3, - "tokens": "32328037984", - "delegator_shares": "32328037984.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.039339062684741866", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.021256256594527078" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus2udpwh", - "status": 3, - "tokens": "15813863385", - "delegator_shares": "15813863385.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.543747468021249371", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.392045382869085556" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwujx3ap2", - "status": 3, - "tokens": "25957780472", - "delegator_shares": "25957780472.000000000000000000", - "description": { - "moniker": "hoLpIoNUFo", - "identity": "LCpoujNFyW", - "website": "AOTlTXjPul", - "security_contact": "elgNvDzEfH", - "details": "hwOSWkTDMH" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.347272379813626146", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kjupa2w6rlhzj9fjxz35m02g2wpz790fgw0urp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtj39qcdlmh7fr77am26s8as06l9v3p426z5gr5dyfvc4fr5gqyevxe8agn", - "status": 3, - "tokens": "18831480577", - "delegator_shares": "18831480577.000000000000000000", - "description": { - "moniker": "hjYgiDHhzz", - "identity": "KrwRKCSMYC", - "website": "VKtCXTAtbA", - "security_contact": "kqWNgIhnNy", - "details": "etaTpRtVAp" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.344371628918599076", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.334517383567629324" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9ugfdlq9", - "status": 3, - "tokens": "47141129937", - "delegator_shares": "47141129937.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.340626334815374555", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkxmnmkq", - "status": 3, - "tokens": "26977915837", - "delegator_shares": "26977915837.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.605944631117636209", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.639343774657574630" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqk8ct27q", - "status": 3, - "tokens": "22456561633", - "delegator_shares": "22456561633.000000000000000000", - "description": { - "moniker": "DPTpRIdXgW", - "identity": "qysDMlMxpi", - "website": "xWbmLVlZvB", - "security_contact": "QtpKTducMv", - "details": "UWYfFdNOxg" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.057271144965717909", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.075138495309274904" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd7u4d80m4e6sfhyzj84k6y34v30g9cstzx7cmrazvxdtfe40urcvran9t8", - "status": 3, - "tokens": "45811135531", - "delegator_shares": "45811135531.000000000000000000", - "description": { - "moniker": "zcPImZiDZD", - "identity": "zkcTihefFl", - "website": "mIjAaWRNkf", - "security_contact": "gTafXNexkI", - "details": "tJJDPwaiAf" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.079222020883406460", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.311112908017536993" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggxauhp0sadc5npdva6f492f3n4a76fldyt3lca6lk36685s624ucakcrh", - "status": 3, - "tokens": "25100106074", - "delegator_shares": "25100106074.000000000000000000", - "description": { - "moniker": "dLwrEevbbD", - "identity": "ubSqqBoPRs", - "website": "MNuXpKVOXc", - "security_contact": "lNXuEDYSJp", - "details": "CvXURllZqF" - }, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.200000000000000000", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.175531415042829217" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqwclfkt", - "status": 3, - "tokens": "34459325260", - "delegator_shares": "34459325260.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.033986343509044787", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.090000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7t4673v", - "status": 3, - "tokens": "54014760938", - "delegator_shares": "54014760938.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.440048441195653325", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.180789237411591672" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5r4xrdd", - "status": 3, - "tokens": "15675831119", - "delegator_shares": "15675831119.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czwem9y4", - "status": 3, - "tokens": "25088017519", - "delegator_shares": "25088017519.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.177753292751501209", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.323174353688819429" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxe7jutz", - "status": 3, - "tokens": "46591477836", - "delegator_shares": "46591477836.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.017452646416466178", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.020000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4svau85d", - "status": 3, - "tokens": "31770155824", - "delegator_shares": "31770155824.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.138735148670316454", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.286634953103815529" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf0u600sgl3zdn3uh4jd6jmw6fc0jc40r0l2crvz3sla3f8d32flghwtxaq", - "status": 3, - "tokens": "40258437865", - "delegator_shares": "40258437865.000000000000000000", - "description": { - "moniker": "BUZauhlQrt", - "identity": "yuIKzyGzQS", - "website": "fDSmxAmazc", - "security_contact": "jVDWgXPhkM", - "details": "LBFAwsUoyi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.244517333363622892", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.153245122134586562" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzue70ade", - "status": 3, - "tokens": "38186556308", - "delegator_shares": "38186556308.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.260000000000000000", - "max_rate": "0.260000000000000000", - "max_change_rate": "0.239035612898447459" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj2sy3f5", - "status": 3, - "tokens": "26856561942", - "delegator_shares": "26856561942.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.420000000000000000", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.295551090875771737" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvhet24yk50y4m60mceffquewu9p4enwrgcum0csceuull7a59u6567nn0v", - "status": 3, - "tokens": "20405570669", - "delegator_shares": "20405570669.000000000000000000", - "description": { - "moniker": "ZeprycSOnc", - "identity": "ZcHuivhMFq", - "website": "hCsVpTWmaL", - "security_contact": "AIKsDuUCDR", - "details": "EgpxVbAOaK" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.054000324644638628", - "max_rate": "0.380000000000000000", - "max_change_rate": "0.120973196882786975" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6k07476", - "status": 3, - "tokens": "25102040344", - "delegator_shares": "25102040344.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.599184934718890393", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5whh6fg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt0sk5rhcpv85mjvladxx3ygs0auglwcm4xpurjqeex8z99ya86363zl4ug", - "status": 3, - "tokens": "24641977345", - "delegator_shares": "24641977345.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.546622488015386807", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.175928838659210799" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "consensus_pubkey": "cosmosvalconspub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjycl58l", - "status": 3, - "tokens": "41928862316", - "delegator_shares": "41928862316.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.025162698699691548" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75fh3auv", - "status": 3, - "tokens": "19565632897", - "delegator_shares": "19565632897.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.579061375935434182", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwskjpjy", - "status": 3, - "tokens": "44648874284", - "delegator_shares": "44648874284.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.258140043497759741", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.447039357737510640" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg57gy4ef", - "status": 3, - "tokens": "34209671267", - "delegator_shares": "34209671267.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.480455308806333346", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55hrcqtd", - "status": 3, - "tokens": "25069342080", - "delegator_shares": "25069342080.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.409558857679769509", - "max_rate": "0.930000000000000000", - "max_change_rate": "0.610998804526507722" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0sgshv9mf8qy7ff303mqqv5zppu3q4mcwrnheue8d3kq0ytyynkxlak2ae", - "status": 3, - "tokens": "28980476016", - "delegator_shares": "28980476016.000000000000000000", - "description": { - "moniker": "hVYOUraqpo", - "identity": "XRliNUdYgt", - "website": "FYzwRNeFsW", - "security_contact": "AYYtrdbBmx", - "details": "NaWAwUYhir" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxd2wcms", - "status": 3, - "tokens": "27742737411", - "delegator_shares": "27742737411.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.870000000000000000", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.402061609548054151" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2x30aum6t8lauwqh72szktjx6fmgf5ux7vcs38uukp9a5h287wawhv5mfv", - "status": 3, - "tokens": "17377751306", - "delegator_shares": "17377751306.000000000000000000", - "description": { - "moniker": "SslqJkEqrN", - "identity": "qMdXPqvbCt", - "website": "HDwwjWlugU", - "security_contact": "LzWMObthwF", - "details": "zlyoRqwOQS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.498765541593724538", - "max_rate": "0.530000000000000000", - "max_change_rate": "0.156108348646223859" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3lu0qw8kj", - "status": 3, - "tokens": "23737653202", - "delegator_shares": "23737653202.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.450461328836777178", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.254665389885134513" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcf30j9c", - "status": 3, - "tokens": "74690344989", - "delegator_shares": "74690344989.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.882630947578979215", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.960000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr2mqfkju", - "status": 3, - "tokens": "27874325464", - "delegator_shares": "27874325464.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.459241580368376871", - "max_rate": "0.490000000000000000", - "max_change_rate": "0.448990769658695281" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngklt9fqt", - "status": 3, - "tokens": "67833673918", - "delegator_shares": "67833673918.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.280411773058535090", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.009358685901125498" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdq8fheeu", - "status": 3, - "tokens": "25475671492", - "delegator_shares": "25475671492.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.073669961838812257", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.338443455873010612" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdjuv3ql5rv5njym62quduw7554as4aa8seufp7f4zv6q28tds2e23v4cv5", - "status": 3, - "tokens": "35741739231", - "delegator_shares": "35741739231.000000000000000000", - "description": { - "moniker": "MoJgIrbTvT", - "identity": "rTfyDjhPlV", - "website": "fXpRItnlwS", - "security_contact": "tIlMCZPLDi", - "details": "QoSUrnFXNb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.037606710200997532", - "max_rate": "0.610000000000000000", - "max_change_rate": "0.432717335122536998" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwvhpfht", - "status": 3, - "tokens": "19637280062", - "delegator_shares": "19637280062.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118259925415637398", - "max_rate": "0.220000000000000000", - "max_change_rate": "0.176572964585642890" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwaazwez", - "status": 3, - "tokens": "56856814851", - "delegator_shares": "56856814851.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.093189165744722643", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.044880981942823250" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf7lunwah", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtcxreszx2wu4ngd3amegdgh9549fr4yh4mgvs862ea44ugjv0leywawqen", - "status": 3, - "tokens": "18846592576", - "delegator_shares": "18846592576.000000000000000000", - "description": { - "moniker": "kcMqvkQeGm", - "identity": "ZKjzktvrAj", - "website": "EzWzZovCJZ", - "security_contact": "hwPlfWocdU", - "details": "vvHigjWyJK" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.307501014763216711", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.592156519673221532" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyvxmu04", - "status": 3, - "tokens": "36122807193", - "delegator_shares": "36122807193.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.414145633705698803", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.500000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2p3sa8dkvz36pz6nusjdhm9aqlnrrldrszzuqd5qy7ssqztn99ggqpcdlz", - "status": 3, - "tokens": "48540826744", - "delegator_shares": "48540826744.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003549575739989554", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.001119527935415439" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycjhwrn7", - "status": 3, - "tokens": "29401856985", - "delegator_shares": "29401856985.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.243341366114153903", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.628404054381210058" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdaa2szanfjwhzucqfj0ct7ljhc3kew8am3h8sr8wqzlnh8df06g5th460y", - "status": 3, - "tokens": "24697024268", - "delegator_shares": "24697024268.000000000000000000", - "description": { - "moniker": "XYWZXrqRDE", - "identity": "MFgElwSSlb", - "website": "ZPGkarWAml", - "security_contact": "dFzxEZXTfo", - "details": "HRGbXKBEeq" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.550000000000000000", - "max_change_rate": "0.376530136432859216" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8ntw48x", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgtrcqtxc62uk24ac873z7ns2gz75znes579xk2m0xzxpjqswh08kh6nrm0", - "status": 3, - "tokens": "15012824613", - "delegator_shares": "15012824613.000000000000000000", - "description": { - "moniker": "TzIitNrGWU", - "identity": "UtpzgJMsxj", - "website": "KMxjEKqFGe", - "security_contact": "GczmfoVPHm", - "details": "fMoGrNqroM" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.413119742047134521", - "max_rate": "0.590000000000000000", - "max_change_rate": "0.590000000000000000" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w4r0vhq", - "status": 3, - "tokens": "41494205421", - "delegator_shares": "41494205421.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.070000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgc0dahup", - "status": 3, - "tokens": "54398813120", - "delegator_shares": "54398813120.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.109747630034489371", - "max_rate": "0.970000000000000000", - "max_change_rate": "0.461346401411912639" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkn6paax", - "status": 3, - "tokens": "23703504292", - "delegator_shares": "23703504292.000000000000000000", - "description": { - "moniker": "eXfwGKuzGb", - "identity": "dYpMrjwrPA", - "website": "DzaFOsditE", - "security_contact": "GuNLPoNZsM", - "details": "iALsKeROvR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.087538799057934086", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.859363741701174499" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyt542en", - "status": 3, - "tokens": "69725274862", - "delegator_shares": "69725274862.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.077835183941357357", - "max_rate": "0.630000000000000000", - "max_change_rate": "0.287966636331923139" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsrp7s99", - "status": 3, - "tokens": "25470495498", - "delegator_shares": "25470495498.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.420000000000000000", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.006473324874363207" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd5jsj53j7m0umzvh90dwanxhfxmpydhfazmsz978v9yuh05q0kxcyqtdla", - "status": 3, - "tokens": "16747268503", - "delegator_shares": "16747268503.000000000000000000", - "description": { - "moniker": "OuShqctNnC", - "identity": "MfQbnbeXdv", - "website": "OfOpteXCQn", - "security_contact": "qaSLhJmnUG", - "details": "vIuRzAnYuu" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.589668369513377579", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.640000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge726q0dwq", - "status": 3, - "tokens": "56914095343", - "delegator_shares": "56914095343.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.561558403350280399", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.088588598076790894" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0us7fav4", - "status": 3, - "tokens": "41972647667", - "delegator_shares": "41972647667.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.148502470554898869", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.005661642347781868" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw32mxlzzzmmpks775cgclcsmypqhhz7765v03wnjf8cn4hsrw67tq2l8n", - "status": 3, - "tokens": "20301516153", - "delegator_shares": "20301516153.000000000000000000", - "description": { - "moniker": "ibdjDFXkFg", - "identity": "BhaqDbDPwH", - "website": "KoHplbnTSd", - "security_contact": "zgJBSepZRt", - "details": "anTLerUmWY" - }, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.092279263137073204", - "max_rate": "0.130000000000000000", - "max_change_rate": "0.062347977318301413" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4umtaftt", - "status": 3, - "tokens": "23438430919", - "delegator_shares": "23438430919.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.065104244001935780", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.087973256413395308" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wu8lrdvr", - "status": 3, - "tokens": "23476663612", - "delegator_shares": "23476663612.000000000000000000", - "description": { - "moniker": "qNlNvDKQWh", - "identity": "PdEEmVXzOP", - "website": "jyQRsxutdI", - "security_contact": "hTNdvfWkVQ", - "details": "gPNrXPrkeL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.830000000000000000", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.679717803083962746" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7pax9cuqs5vjjvhpmcgvy5dkqrrtrg6336c3xhyrchtegy2m387ccs037", - "status": 3, - "tokens": "19815525788", - "delegator_shares": "19815525788.000000000000000000", - "description": { - "moniker": "sJKzLUYWBq", - "identity": "ZzbWnFqPTq", - "website": "dlevXyAGdk", - "security_contact": "bnQNzwNRYP", - "details": "PaxiDbFCJj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.291627565410574418", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.017987067010819344" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wel7d3l", - "status": 3, - "tokens": "25456865344", - "delegator_shares": "25456865344.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.293848609442759777", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.580000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6u59lzkg", - "status": 3, - "tokens": "32989599899", - "delegator_shares": "32989599899.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.045106108515206331", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.610987430943531252" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xvdql9k", - "status": 3, - "tokens": "25311353934", - "delegator_shares": "25311353934.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.324580145668396309", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.480000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujgucg2ktdn", - "status": 3, - "tokens": "33288895711", - "delegator_shares": "33288895711.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.322505571100731689", - "max_rate": "0.520000000000000000", - "max_change_rate": "0.183472725952677048" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592jkkxzm", - "status": 3, - "tokens": "21858111883", - "delegator_shares": "21858111883.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.799310131872627643", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.706235617003159879" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxtyq8dz", - "status": 3, - "tokens": "16946315559", - "delegator_shares": "16946315559.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.174404138163737710", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.360000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - } - ] - }, - { - "header": { - "version": {}, - "chain_id": "simulation-app", - "height": "49", - "time": "9936-01-04T15:40:16Z", - "last_block_id": { - "parts_header": {} - }, - "proposer_address": "LmPwns0Mxbb7x0GEW4Bz6Zx4B7E=" - }, - "valset": [ - { - "operator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels7tpscy", - "status": 3, - "tokens": "24767745772", - "delegator_shares": "24767745772.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.064962829627143450", - "max_rate": "0.700000000000000000", - "max_change_rate": "0.524524837966075502" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xt2s2vh", - "status": 3, - "tokens": "40149298125", - "delegator_shares": "40149298125.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.020987080088521851", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.079654399773437862" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk7tt4rl", - "status": 3, - "tokens": "33873720903", - "delegator_shares": "33873720903.000000000000000000", - "description": { - "moniker": "mLoNnmWUiV", - "identity": "RHiUhLQQnZ", - "website": "GdVEOYibSd", - "security_contact": "DcfUpyGSpE", - "details": "kaQgULDDFV" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.793635545567707656", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.546926599085395557" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfkykt89x2wmxt2w74v340hwp8azwyzswzgxzmcv46995zwggpu66ans7kn", - "status": 3, - "tokens": "17076084961", - "delegator_shares": "17076084961.000000000000000000", - "description": { - "moniker": "qorkgLHbbW", - "identity": "vVsXuupmaH", - "website": "GASCHEJsbz", - "security_contact": "KEcXQQooNh", - "details": "UlGvDMHBgm" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.150351690116871266", - "max_rate": "0.470000000000000000", - "max_change_rate": "0.232118363435586291" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcrkzkl0", - "status": 3, - "tokens": "76742997299", - "delegator_shares": "76742997299.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.159853619317053801", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.178173481628386356" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0yv2h8z80vtfttsewrwe2v83haaceax7q3ey95uaeqj8lstf7l674zn3ut", - "status": 3, - "tokens": "16016194501", - "delegator_shares": "16016194501.000000000000000000", - "description": { - "moniker": "WVhrVMjLnZ", - "identity": "QiIQjemxtv", - "website": "KCKlbRarYk", - "security_contact": "AwimEeOMDq", - "details": "omCiVdOfZS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.636807270475032336", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.762928812525012131" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghknhrvft", - "status": 3, - "tokens": "32584502965", - "delegator_shares": "32584502965.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.063963134401067102" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgt7tyq6", - "status": 3, - "tokens": "15545552914", - "delegator_shares": "15545552914.000000000000000000", - "description": { - "moniker": "VaOLitHrfh", - "identity": "zYkbJeTdPC", - "website": "RWLWpQBLTs", - "security_contact": "EEFOrnsvml", - "details": "xRXuWfcvoz" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.209346043397093808", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.261491014079542938" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpvkknmf7", - "status": 3, - "tokens": "35273490053", - "delegator_shares": "35273490053.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.412168984856446389", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.601152598273329028" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvw0g93n8", - "status": 3, - "tokens": "24353363633", - "delegator_shares": "24353363633.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.140843713075627976", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.124247346623493378" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtxrkpudghuhgsu0he7ntk7q0asqa5ax23y7rnn5mfjr2d68z4emsrwqssp", - "status": 3, - "tokens": "44979344173", - "delegator_shares": "44979344173.000000000000000000", - "description": { - "moniker": "eJECwiPlqs", - "identity": "TywZsaZwgH", - "website": "jtFVQJUofX", - "security_contact": "fstanspUpc", - "details": "RQddrwMsIR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.005369299901591159", - "max_rate": "0.030000000000000000", - "max_change_rate": "0.010979308887356502" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwz2zelc", - "status": 3, - "tokens": "24972834479", - "delegator_shares": "24972834479.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118883162683785924", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.582076368438090700" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1pv9f0ze6vmq3qvy29fywmj2eh2cpneymj9hnjn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2dcqs6jwgqs06hz297xdv606lcyx76wnyf228c98wsnmrarnjg7qdrlhmh", - "status": 3, - "tokens": "15307584671", - "delegator_shares": "15307584671.000000000000000000", - "description": { - "moniker": "MLAiGifuge", - "identity": "YmgtyeQqKn", - "website": "tgmRpbrPqg", - "security_contact": "EoVdOQlqiF", - "details": "MFxkDUZjLF" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.079450929148714776", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.213073238635972528" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q205udc4", - "status": 3, - "tokens": "37286335725", - "delegator_shares": "37286335725.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.150000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.137121313165408722" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zycdvvrg7", - "status": 3, - "tokens": "26109827309", - "delegator_shares": "26109827309.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.272379182115041576" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "consensus_pubkey": "cosmosvalconspub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwlhqscf", - "status": 3, - "tokens": "25204407264", - "delegator_shares": "25204407264.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.276804190595109972", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.303611347820460701" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2u3gzal", - "status": 3, - "tokens": "23014258552", - "delegator_shares": "23014258552.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289943655120962524", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.271265684659427360" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgh4tj7q", - "status": 3, - "tokens": "49505425616", - "delegator_shares": "49505425616.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.519126528788995280", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw55ftmtn", - "status": 3, - "tokens": "52891997390", - "delegator_shares": "52891997390.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.006443603339396517", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.110565720532816181" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavc40dh4", - "status": 3, - "tokens": "69365122054", - "delegator_shares": "69365122054.000000000000000000", - "description": { - "moniker": "IoqkplxtIQ", - "identity": "SYtEYnqVjz", - "website": "cbrMdhVrVp", - "security_contact": "eWitXxyhJZ", - "details": "FCojJQQFCQ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.745132980800690980", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.321606633967630124" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tugphy2d", - "status": 3, - "tokens": "17054284690", - "delegator_shares": "17054284690.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.602634897210355218", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.136597759514787421" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jztkylp", - "status": 3, - "tokens": "55080258715", - "delegator_shares": "55080258715.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.052047960532670175", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgrwz3gl", - "status": 3, - "tokens": "17768682341", - "delegator_shares": "17768682341.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.141929485726276362" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yr97z8g", - "status": 3, - "tokens": "22598538029", - "delegator_shares": "22598538029.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.335354744004515496", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.096800797786563611" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2zq3f3j", - "status": 3, - "tokens": "27149799034", - "delegator_shares": "27149799034.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.158969199652087770", - "max_rate": "0.220000000000000000", - "max_change_rate": "0.220000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq246sxc5kns0ym6st5wyf6mk0x2cayek9wngczyvgk8phxrat02cqh8w5p2", - "status": 3, - "tokens": "49314038732", - "delegator_shares": "49314038732.000000000000000000", - "description": { - "moniker": "caRBWwzxXd", - "identity": "BJSnkbfQjh", - "website": "ELsVPBoBHb", - "security_contact": "nZkoSMuzKV", - "details": "AuAKjeoitI" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.010525961964940541", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.045814731203367877" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jhhj4uv", - "status": 3, - "tokens": "26185707851", - "delegator_shares": "26185707851.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.568319127244896272", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.226261076338173049" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5u4v4q5", - "status": 3, - "tokens": "32785129607", - "delegator_shares": "32785129607.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.009044195385937429", - "max_rate": "0.010000000000000000", - "max_change_rate": "0.002281789765845776" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpqq8zx8p", - "status": 3, - "tokens": "33846192792", - "delegator_shares": "33846192792.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.094250378854551281", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.043420993012939508" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv79a2a0wcq9kr62m5yupvx82mlxwxw6hx7c8dyl4trf8k2w7vh3w5wlhy0", - "status": 3, - "tokens": "25066394767", - "delegator_shares": "25066394767.000000000000000000", - "description": { - "moniker": "liMRThtiLT", - "identity": "QPHsvzHnkx", - "website": "BytvAmppJT", - "security_contact": "iBgKxrOkqF", - "details": "RcELAgZeDN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.115126355797501393", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.289658857878369113" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfp9mvx6gjdezn2vfxn9jk7jm2urml0xyvt3yg64s03yzkfphrthsdy925d", - "status": 3, - "tokens": "25061237568", - "delegator_shares": "25061237568.000000000000000000", - "description": { - "moniker": "wmxxGOZTpL", - "identity": "azxfwYYUUt", - "website": "izxOUVhQSX", - "security_contact": "lRgXsoitme", - "details": "eebhMKbHXO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.578049895054733896", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.402405887034980654" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc255eyr9", - "status": 3, - "tokens": "76719658246", - "delegator_shares": "76719658246.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.321194785873117781", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.561602155526895676" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u43hapa", - "status": 3, - "tokens": "18750673243", - "delegator_shares": "18750673243.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.188948913118426394", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.274693773376656673" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvpup8kv2mmqajfs08aks8yu8kcuwd323y4f0wu9e3k5grynt0g6ule9mjg", - "status": 3, - "tokens": "24248574347", - "delegator_shares": "24248574347.000000000000000000", - "description": { - "moniker": "bsrCMyYTRM", - "identity": "cTWbJOIMRX", - "website": "EMzKHBarjX", - "security_contact": "spsTAIOECF", - "details": "fTrZtqJTUr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.455524678875180233", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-01T06:29:20Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d29fg079", - "status": 3, - "tokens": "82798702711", - "delegator_shares": "82798702711.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289674444273548704", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.060992257943659564" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgss8cv9u", - "status": 3, - "tokens": "26155915081", - "delegator_shares": "26155915081.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.333198345990187069", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.410926346802169727" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "consensus_pubkey": "cosmosvalconspub1addwnpepqghlm3r37c95q3p3wvr8fxw8mvvdtj3tvhgduhzgzh4238ynz6f06f0rjfd", - "status": 3, - "tokens": "32485653471", - "delegator_shares": "32485653471.000000000000000000", - "description": { - "moniker": "hjulbVDPpf", - "identity": "pRsBrwBRzq", - "website": "VjiSZKAfKB", - "security_contact": "UHZkwTciXO", - "details": "JTfVgehmsi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.311759176624756474" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwus66jdl", - "status": 3, - "tokens": "54108139534", - "delegator_shares": "54108139534.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.500000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22ep2k8n", - "status": 3, - "tokens": "69316998057", - "delegator_shares": "69316998057.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.624946300778690751", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.204995912261423056" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7ejhy28", - "status": 3, - "tokens": "27808118568", - "delegator_shares": "27808118568.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.067795278161998694", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.011309118617844055" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5kc0mzw", - "status": 3, - "tokens": "17750303222", - "delegator_shares": "17750303222.000000000000000000", - "description": { - "moniker": "uloyQQWkyI", - "identity": "gFyXSGlhKI", - "website": "ewFltsApZk", - "security_contact": "YGvOhkEKJw", - "details": "vIoOsfiLuj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.068730439287548849", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.118090772640391070" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv0pnal4w8hydpq3vydqgjxmmxz7zg2g9lsj5vedvjq3pw6typfdcjfm5tc", - "status": 3, - "tokens": "16214844041", - "delegator_shares": "16214844041.000000000000000000", - "description": { - "moniker": "jKdcmnPYfC", - "identity": "exfUuYgqmd", - "website": "XdNCNZIBOf", - "security_contact": "hmiwPGchGt", - "details": "nUnBufZQah" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.330000000000000000", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.051583680374523519" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057uxwdfy", - "status": 3, - "tokens": "23352431465", - "delegator_shares": "23352431465.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.760000000000000000", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.183753469845780730" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvy095yf8a7eknhlnwzkum0wt53njxxww60vte7qkutwczt534dwhaclpm", - "status": 3, - "tokens": "34693121909", - "delegator_shares": "34693121909.000000000000000000", - "description": { - "moniker": "RuzZVxWXdB", - "identity": "QjsgdqaNzA", - "website": "UtlkBZyIyQ", - "security_contact": "vnsfyiwxFP", - "details": "dOxLDmGKTb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.005447024365505786", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.005395717096845063" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef5gg2q6z", - "status": 3, - "tokens": "42958814024", - "delegator_shares": "42958814024.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.077000158168963029", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.197697608060710078" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwv7ukq0", - "status": 3, - "tokens": "21734647779", - "delegator_shares": "21734647779.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.460679550676466675", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.165088210560206816" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwc7h5wds8u3tspx3mwpfh5l3q3rv0t6ff33dt205v2zy2kxev9sykcs9uv", - "status": 3, - "tokens": "29256610441", - "delegator_shares": "29256610441.000000000000000000", - "description": { - "moniker": "iYUgQcrziE", - "identity": "hDYXNaKKIu", - "website": "FYsreoPnoD", - "security_contact": "FGAHzGKfjM", - "details": "gkHwWfssaE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.585764113115952818", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz4r8scm", - "status": 3, - "tokens": "65051132532", - "delegator_shares": "65051132532.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.041535797793389960", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.029250263820409753" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2cxeaw4", - "status": 3, - "tokens": "18897052265", - "delegator_shares": "18897052265.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.416117321788354038", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.139830256647094326" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazfcl7f9", - "status": 3, - "tokens": "27157083976", - "delegator_shares": "27157083976.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.170000000000000000", - "max_change_rate": "0.024288054259102348" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgxqjc3u3", - "status": 3, - "tokens": "45028692546", - "delegator_shares": "45028692546.000000000000000000", - "description": { - "moniker": "UeFBWJANuQ", - "identity": "gypzUiAlRd", - "website": "zZezcKCiKy", - "security_contact": "KSXTvslQOC", - "details": "qqNIBlVIYk" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.075610127679217055", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.290000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xwmrp7sq", - "status": 3, - "tokens": "35018830437", - "delegator_shares": "35018830437.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.405901469124460870" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "consensus_pubkey": "cosmosvalconspub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc92g545rl", - "status": 3, - "tokens": "17547285969", - "delegator_shares": "17547285969.000000000000000000", - "description": {}, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.073548473514397047", - "max_rate": "0.440000000000000000", - "max_change_rate": "0.413655116572301617" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wyr7x83", - "status": 3, - "tokens": "25071600389", - "delegator_shares": "25071600389.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.280000000000000000", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.063599161373317498" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymswdv67m", - "status": 3, - "tokens": "27784307296", - "delegator_shares": "27784307296.000000000000000000", - "description": { - "moniker": "mjkYspzJbE", - "identity": "xWPMeIdPEi", - "website": "xtRPXfTiQB", - "security_contact": "sdKpqtdpNe", - "details": "MnLujfMpnW" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.100000000000000000", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.072530327063185081" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslqg7mlcx", - "status": 3, - "tokens": "31634692393", - "delegator_shares": "31634692393.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.554757466700447989", - "max_rate": "0.820000000000000000", - "max_change_rate": "0.408903182457515462" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvlfyhyylne6t33wzse5vhjd3xxyrfkjfmdyvk3gq4rrdhe2e0ul2n637uw", - "status": 3, - "tokens": "25080486106", - "delegator_shares": "25080486106.000000000000000000", - "description": { - "moniker": "MCiuCZVGkF", - "identity": "YVlJRRVogl", - "website": "iBpLGvpPpo", - "security_contact": "bvXcaUSxzJ", - "details": "zsHdsXWXhJ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.012334216153398550" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v67hlsk", - "status": 3, - "tokens": "16236700229", - "delegator_shares": "16236700229.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.498536222135788025" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5l4jsmp", - "status": 3, - "tokens": "42927955154", - "delegator_shares": "42927955154.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.190381602916620701", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.303876600993529705" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g7drc35", - "status": 3, - "tokens": "36911230696", - "delegator_shares": "36911230696.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.194945225911581915", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.300000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcas8xka", - "status": 3, - "tokens": "39363181311", - "delegator_shares": "39363181311.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.028169322828760497", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.050000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcvjsxyz", - "status": 3, - "tokens": "27734813665", - "delegator_shares": "27734813665.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.015116864220436494", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd5nsxkua92z9eamd4hccf0pxeh3chye2475vcrwc22dpxj4lmkvuy950w7", - "status": 3, - "tokens": "27605610764", - "delegator_shares": "27605610764.000000000000000000", - "description": { - "moniker": "RLaOPuFvKx", - "identity": "LQfktbUgZN", - "website": "JiRhAUTjQG", - "security_contact": "LTGuZUEvcW", - "details": "QjLWSYAXxH" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskj3a67t", - "status": 3, - "tokens": "24423311847", - "delegator_shares": "24423311847.000000000000000000", - "description": { - "moniker": "OtyVVqWsup", - "identity": "EqaejuaTwX", - "website": "egvJRLAnYF", - "security_contact": "KTzlQLiomS", - "details": "ETXsigXuTY" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.372711230134865265", - "max_rate": "0.460000000000000000", - "max_change_rate": "0.056760418592473079" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjzxhelr", - "status": 3, - "tokens": "25592800910", - "delegator_shares": "25592800910.000000000000000000", - "description": { - "moniker": "NYvAvaIOdj", - "identity": "lYbVDursvX", - "website": "UXtFzZcHjM", - "security_contact": "PNNMeOJqcl", - "details": "ROVIgdvaJl" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.193312772989594496", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.226297820963910157" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvvur4tyyl553c4jeyvce0w3d0ezrrmsr6a2kcdksca4wpflc3lj7nf6fm9", - "status": 3, - "tokens": "25675698411", - "delegator_shares": "25675698411.000000000000000000", - "description": { - "moniker": "wDAGDTplVL", - "identity": "VUJoHvcuZs", - "website": "JzvbSfINxu", - "security_contact": "cROcYcTImn", - "details": "bdBDwVnOvM" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.108086670177688287", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.123495090782214164" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsuh3jpet", - "status": 3, - "tokens": "50488222690", - "delegator_shares": "50488222690.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.801397182624616334", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.592521503076154232" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfk090csv4thlsr4kx3fuucwcsk79lqs6gr5zse6m4xmwpq94hy2w3yuqp6", - "status": 3, - "tokens": "20659893696", - "delegator_shares": "20659893696.000000000000000000", - "description": { - "moniker": "gqjwubbLDT", - "identity": "OsKsdzWbsv", - "website": "rhWGeqAAVi", - "security_contact": "FmaEvvcaAr", - "details": "uMULjHPlYr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.168812875456833709" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5t7pxck", - "status": 3, - "tokens": "53644768786", - "delegator_shares": "53644768786.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.180000000000000000", - "max_change_rate": "0.029528662482337368" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2z47zet", - "status": 3, - "tokens": "21168715051", - "delegator_shares": "21168715051.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.026318239077074162", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.076792434560738120" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyw0np92", - "status": 3, - "tokens": "27374742411", - "delegator_shares": "27374742411.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.053895535796610462", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.182737583024108345" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2al69u7pnek9kcrmz83vstrst5szxuz6z03z0d848kuh3ekkjlfgr96q6z", - "status": 3, - "tokens": "20929858941", - "delegator_shares": "20929858941.000000000000000000", - "description": { - "moniker": "ciowxbJZpb", - "identity": "XgDAZmwEir", - "website": "moPXkGzyqT", - "security_contact": "WTLysotltH", - "details": "qoTHCiKGoL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003240694138410597", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.013650990946439583" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzvca96h", - "status": 3, - "tokens": "70162120947", - "delegator_shares": "70162120947.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.545864029263808659", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.533310660658318421" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqlk7nha", - "status": 3, - "tokens": "20279593182", - "delegator_shares": "20279593182.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.069908236020668720", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.009891358364124589" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqva0a8amjektwyshzjv38f6dw5uwat88kscw834kf3026r5ksn77gf0857j", - "status": 3, - "tokens": "31584297936", - "delegator_shares": "31584297936.000000000000000000", - "description": { - "moniker": "BKQyTeKaLC", - "identity": "eCoPebxrNV", - "website": "auQgzJBeZR", - "security_contact": "bLlknxqKWU", - "details": "amiXFmUGDr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.900000000000000000", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.031968764827487641" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4cv2x09p", - "status": 3, - "tokens": "22768989048", - "delegator_shares": "22768989048.000000000000000000", - "description": { - "moniker": "EVTkHBKcpE", - "identity": "hMErYohFOn", - "website": "QaWaMRxOKv", - "security_contact": "qaxyuRDTeX", - "details": "ELwgPpPDKw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.386471695225710439" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfjcp62cfnelz8s5cl5qar8ymfjd5sjjkkr4tayrqrtzpf638hkjqmg9q4z", - "status": 3, - "tokens": "26491705865", - "delegator_shares": "26491705865.000000000000000000", - "description": { - "moniker": "SJeSnSdrXp", - "identity": "OTlQTOJbcV", - "website": "sulWDbaxDh", - "security_contact": "XTGtIDYHdJ", - "details": "KNeohKLilE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.965860683215034339", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.778196912581936923" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "consensus_pubkey": "cosmosvalconspub1addwnpepq28myc67l0yhmnn6n2vq8hcmpaxesglyyqg825ujgrxdt9afwlsfx4ezupt", - "status": 3, - "tokens": "16246649557", - "delegator_shares": "16246649557.000000000000000000", - "description": { - "moniker": "mtHVFaNGLx", - "identity": "YTyhLHiifY", - "website": "JFeCDRXGYc", - "security_contact": "HndWqVmQvE", - "details": "JFVkeOUSbg" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.018292046092814578", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.057525240491425891" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z6ckp5s", - "status": 3, - "tokens": "62801915451", - "delegator_shares": "62801915451.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.323440196337864016" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng9t438v", - "status": 3, - "tokens": "22515450726", - "delegator_shares": "22515450726.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.752425052602923482" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6mcm2m0", - "status": 3, - "tokens": "29556680915", - "delegator_shares": "29556680915.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289048467390880739", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.476925303769745140" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswzcmkck", - "status": 3, - "tokens": "25121635132", - "delegator_shares": "25121635132.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.541820589241677763" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "consensus_pubkey": "cosmosvalconspub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z2xdtk5", - "status": 3, - "tokens": "25662668318", - "delegator_shares": "25662668318.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.493962290871886167", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.601549819261141285" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vype2jq", - "status": 3, - "tokens": "59694062218", - "delegator_shares": "59694062218.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.047504130944412074", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.160000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xzg536q0eksvxd2297ycyctfwp6x7rk0wq6d0murld346cjs756v0jnxn", - "status": 3, - "tokens": "16949426508", - "delegator_shares": "16949426508.000000000000000000", - "description": { - "moniker": "dNCvXIwisF", - "identity": "PInuRSnoAB", - "website": "IFaDEJuVii", - "security_contact": "DiiitKvkqG", - "details": "wJQyZMjCjC" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083382298074645848", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.156261937510636548" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag73jg46g", - "status": 3, - "tokens": "41973269906", - "delegator_shares": "41973269906.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.742458631966852296", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.368222450098111604" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4d6e962zqejqu3jeypzp740n4k62xte2qnj82q03y28v6wkshycxxdg5w", - "status": 3, - "tokens": "18158211957", - "delegator_shares": "18158211957.000000000000000000", - "description": { - "moniker": "cVYtBkXobK", - "identity": "JOBpTikHPq", - "website": "NyobvRjfBj", - "security_contact": "bKDbHWcmSW", - "details": "xGfkOaAoAb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.340000000000000000", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.117974822314921419" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4cv0e5r0", - "status": 3, - "tokens": "25435646393", - "delegator_shares": "25435646393.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.004320117912957935", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.000447271047532656" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwfwqlzf", - "status": 3, - "tokens": "16773399211", - "delegator_shares": "16773399211.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.926805735750034881", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.482844926743337660" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qavly08", - "status": 3, - "tokens": "17705677177", - "delegator_shares": "17705677177.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.615745867723667485", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.398263247650399274" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwv80xev", - "status": 3, - "tokens": "26461821776", - "delegator_shares": "26461821776.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.157167562506066789", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.091234306987583436" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwudpuh36geydlpx0yjqu0vhauacf294sn2uetg4ush97p382kqag6sxlqg", - "status": 3, - "tokens": "17862559018", - "delegator_shares": "17862559018.000000000000000000", - "description": { - "moniker": "wSgJTwBWiv", - "identity": "AEATmOIHsP", - "website": "WsuxwwJUIx", - "security_contact": "nzWdiJbKcf", - "details": "WXwvQKoIbT" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.120000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.027292850423387945" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq4e58fv", - "status": 3, - "tokens": "112536605413", - "delegator_shares": "112536605413.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.592057337572123856", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.208226705977271974" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7kquya74", - "status": 3, - "tokens": "27525740131", - "delegator_shares": "27525740131.000000000000000000", - "description": { - "moniker": "ajDNnhnkbN", - "identity": "nkdfsqWVlx", - "website": "CeqAfYeTdW", - "security_contact": "KMQJbxKkbm", - "details": "cvAUuqNFYs" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.780000000000000000", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.550890306122411684" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj4x3m9h", - "status": 3, - "tokens": "57637848348", - "delegator_shares": "57637848348.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.081821299211443922", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.458576374327765136" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey2vtdvu", - "status": 3, - "tokens": "19834101875", - "delegator_shares": "19834101875.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.491522368582129610", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.085253529277298261" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0aa00frx8hxrq5pegc0vnt69pj54z3dhwzy8uumr3nhgsc772h0zyr473p", - "status": 3, - "tokens": "37175356106", - "delegator_shares": "37175356106.000000000000000000", - "description": { - "moniker": "oedtWfExZY", - "identity": "taFwTdIwwz", - "website": "oGBHKapVuy", - "security_contact": "hnggEiQcYu", - "details": "qOFIRfzDGP" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083784124252551147", - "max_rate": "0.650000000000000000", - "max_change_rate": "0.550897578676987786" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dsktaxw5", - "status": 3, - "tokens": "55634424696", - "delegator_shares": "55634424696.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.016380613584719475", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.310000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "consensus_pubkey": "cosmosvalconspub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz28vhtm", - "status": 3, - "tokens": "20453193314", - "delegator_shares": "20453193314.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.528106308050967540" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqehts4m", - "status": 3, - "tokens": "52558464763", - "delegator_shares": "52558464763.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.128525196978986815", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.100900376719373255" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru72w0xm", - "status": 3, - "tokens": "18560827275", - "delegator_shares": "18560827275.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.100218404029226728", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.881639682871578638" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00qxpqlwy0p6y9tl23yu7fpu55lhznxa3hrhvsuma6h7lu4c3ekks4wvua", - "status": 3, - "tokens": "22083357722", - "delegator_shares": "22083357722.000000000000000000", - "description": { - "moniker": "LvOuePvVwo", - "identity": "vfegdQlOfT", - "website": "mYvkvMZuDp", - "security_contact": "cfrddDLOlu", - "details": "yHfcxdGyEO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.122593865256918850", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.840000000000000000" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxkm9kvvp", - "status": 3, - "tokens": "26763354026", - "delegator_shares": "26763354026.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.027810962515737967", - "max_rate": "0.070000000000000000", - "max_change_rate": "0.034717076557320762" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdpwvxyz0d0thr5hw72lswav4tdfuwkgfqjdjkaws99y4dw5fzncg487kz6", - "status": 3, - "tokens": "23838299895", - "delegator_shares": "23838299895.000000000000000000", - "description": { - "moniker": "anqFIENyYy", - "identity": "LYtCTmovif", - "website": "nDcnuLjZla", - "security_contact": "KhBXWuJORy", - "details": "rcnhuNfFoO" - }, - "unbonding_height": "13", - "unbonding_time": "9936-01-01T19:46:26Z", - "commission": { - "commission_rates": { - "rate": "0.489033782311246085", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.501117175906227815" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvykaseh7", - "status": 3, - "tokens": "68955304480", - "delegator_shares": "68955304480.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.208925360976246176", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.463634503057540350" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peggwy7x5", - "status": 3, - "tokens": "49844884060", - "delegator_shares": "49844884060.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.338644152469426553", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.069153802725768656" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxz2ead4", - "status": 3, - "tokens": "19233426986", - "delegator_shares": "19233426986.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.373154376676147691", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wjfqd63", - "status": 3, - "tokens": "25961659072", - "delegator_shares": "25961659072.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.068613373696134985", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.073351676068018235" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7ul2hc3", - "status": 3, - "tokens": "33320443806", - "delegator_shares": "33320443806.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118849597906926326", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.228258187539755185" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7whvstg", - "status": 3, - "tokens": "37445650387", - "delegator_shares": "37445650387.000000000000000000", - "description": { - "moniker": "cVUXvMdRgs", - "identity": "AHkjmtOkYK", - "website": "KLRPQOyDoY", - "security_contact": "VHwCrfhVnI", - "details": "qdFVvUucvR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.182731553781057822", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.045316794895420248" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqde6g57cex9ff650ku6dqdqtfulfnzkacecf6k436xl0dd07zglxx5659h9", - "status": 3, - "tokens": "27718687960", - "delegator_shares": "27718687960.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.905848795661145449", - "max_rate": "0.950000000000000000", - "max_change_rate": "0.476775855507110704" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy7220f9ul3", - "status": 3, - "tokens": "33772482275", - "delegator_shares": "33772482275.000000000000000000", - "description": { - "moniker": "znFMdpLOQw", - "identity": "LEMEnpcxqp", - "website": "TjKmeKjDGm", - "security_contact": "ZOXcBhlDyq", - "details": "WpmmnksSqL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.834910862331446014", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cuyxrn7n", - "status": 3, - "tokens": "24587685968", - "delegator_shares": "24587685968.000000000000000000", - "description": { - "moniker": "tlYEYvdvKp", - "identity": "fQFtYLRSZA", - "website": "ecuAofwdaj", - "security_contact": "gwsuBeDyJU", - "details": "gELFJGuwPs" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.499259642246008210", - "max_rate": "0.560000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jet5tg3", - "status": 3, - "tokens": "62232444428", - "delegator_shares": "62232444428.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.153116543667039838", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.230000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yfudg7m", - "status": 3, - "tokens": "25948607110", - "delegator_shares": "25948607110.000000000000000000", - "description": { - "moniker": "IssGiFwTJv", - "identity": "VgTaqmOLtN", - "website": "BpkICmEqwF", - "security_contact": "qmrIWxiWft", - "details": "sLtbcsMFgA" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.136694009459855954", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.056116480834729575" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4c8wkdlg", - "status": 3, - "tokens": "18426946099", - "delegator_shares": "18426946099.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.469814499540087620", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.960000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvquc4jf3", - "status": 3, - "tokens": "16774945156", - "delegator_shares": "16774945156.000000000000000000", - "description": { - "moniker": "hZvyDgtWxX", - "identity": "TPMmELNQYL", - "website": "YxTdbJnobM", - "security_contact": "ZURHxVMZoL", - "details": "zVjWraUVyE" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.258972799025106506", - "max_rate": "0.910000000000000000", - "max_change_rate": "0.304259315697044502" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprs83zeag", - "status": 3, - "tokens": "32156167120", - "delegator_shares": "32156167120.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.351977697440288211" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvly6j0pyezy88s9lnat6taglylzq03vvsvyw4uy2tv3vcl3200ej0nev4k", - "status": 3, - "tokens": "16811362128", - "delegator_shares": "16811362128.000000000000000000", - "description": { - "moniker": "lasYiVeRDA", - "identity": "TFiGxJBNUs", - "website": "xswbDClAxs", - "security_contact": "HYUurzqzcC", - "details": "EVSfzEFSuo" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.036542719943188247", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.304756516958654494" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66dra0w3", - "status": 3, - "tokens": "19540440011", - "delegator_shares": "19540440011.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.065303820000927065", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.134868108685582589" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afqga9sv8", - "status": 3, - "tokens": "33258307031", - "delegator_shares": "33258307031.000000000000000000", - "description": { - "moniker": "uVtPIVoLeB", - "identity": "UQUjtBkUkU", - "website": "lrfjDXnSyH", - "security_contact": "tPWaAehpKA", - "details": "YCcmQgJRnO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.859185512301348293", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.915098787337318307" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrq06r4ck", - "status": 3, - "tokens": "41543247193", - "delegator_shares": "41543247193.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.119695944592116460" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4vjajc6x", - "status": 3, - "tokens": "61843733534", - "delegator_shares": "61843733534.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.437478542817284441", - "max_rate": "0.530000000000000000", - "max_change_rate": "0.308410375933996023" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvghhzrgz", - "status": 3, - "tokens": "36037299066", - "delegator_shares": "36037299066.000000000000000000", - "description": { - "moniker": "rUZvoFLmub", - "identity": "dQGYIJXPFq", - "website": "ZPoXnJmgzU", - "security_contact": "MdbwPJFNHC", - "details": "NdoQBlpUhN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.670000000000000000", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.629855974067904060" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz4luxgn", - "status": 3, - "tokens": "33206633235", - "delegator_shares": "33206633235.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.229284159886860129", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.212917450108859841" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw24c76ax", - "status": 3, - "tokens": "27567655084", - "delegator_shares": "27567655084.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.216560651737526756", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.026445047137608599" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qpu7x5c", - "status": 3, - "tokens": "27671960609", - "delegator_shares": "27671960609.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.077841535313299819", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.054979434313866047" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2wcjjal", - "status": 3, - "tokens": "25069342080", - "delegator_shares": "25069342080.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.249161816461641720", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.693944288516379645" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akutfqm7", - "status": 3, - "tokens": "55737096951", - "delegator_shares": "55737096951.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.498362112747574396", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.645641814068879323" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693hazjkkehy", - "status": 3, - "tokens": "33054734644", - "delegator_shares": "33054734644.000000000000000000", - "description": { - "moniker": "mUQFKtnPLD", - "identity": "xsxoaAIVkh", - "website": "EBARfZhhON", - "security_contact": "GynbBFtcRq", - "details": "RftDCeMUPi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.123876475355091478", - "max_rate": "0.860000000000000000", - "max_change_rate": "0.141162753552435345" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v30nmws", - "status": 3, - "tokens": "78601464028", - "delegator_shares": "78601464028.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083731202536014652", - "max_rate": "0.860000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9ykjrzn93", - "status": 3, - "tokens": "18090212819", - "delegator_shares": "18090212819.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.081582427988342735", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.086390137368972014" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06my86wxz2", - "status": 3, - "tokens": "33968139195", - "delegator_shares": "33968139195.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.247483015769197525", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.837420192496215212" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtufvzu2k2knnce8l9jcwuntray9m8hnlal8a4jkcjazppr5p7pyus6emm0", - "status": 3, - "tokens": "19857350032", - "delegator_shares": "19857350032.000000000000000000", - "description": { - "moniker": "PfGefIRkUQ", - "identity": "PQNdBVtoxj", - "website": "nyfnvHyjNl", - "security_contact": "ewMiIvfvCh", - "details": "ttKmCVgWXS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.239149115387739677", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.173620767408899960" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv9w0yqrekktvu6gd7ak8u7wkwqj47llgrtl2vp2gtdvfafwatyysclj3nm", - "status": 3, - "tokens": "23726914937", - "delegator_shares": "23726914937.000000000000000000", - "description": {}, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.522454157166611225", - "max_rate": "0.820000000000000000", - "max_change_rate": "0.329662780053528069" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2crvswax", - "status": 3, - "tokens": "16516288319", - "delegator_shares": "16516288319.000000000000000000", - "description": { - "moniker": "kVNZIBYAxD", - "identity": "ChbsAFHanI", - "website": "SvHMthzzzB", - "security_contact": "cMJXUgGCfx", - "details": "PWsrYNKuPZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.540000000000000000", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.491525012965837080" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2kj4krx", - "status": 3, - "tokens": "45010236382", - "delegator_shares": "45010236382.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.095070637134115497" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveesw5rr6m", - "status": 3, - "tokens": "54768547781", - "delegator_shares": "54768547781.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.328146514360581742", - "max_rate": "0.810000000000000000", - "max_change_rate": "0.166428198995593213" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68yqxsxnt", - "status": 3, - "tokens": "25326342688", - "delegator_shares": "25326342688.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.785486462764506620", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.356882054361860100" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzlcd6kj", - "status": 3, - "tokens": "67804970220", - "delegator_shares": "67804970220.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.264013069771684883" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4v8fm8e8", - "status": 3, - "tokens": "41964454098", - "delegator_shares": "41964454098.000000000000000000", - "description": { - "moniker": "LDEzyylLGV", - "identity": "NaLpENvFnX", - "website": "ooOcvgIJwr", - "security_contact": "aQaxAlCyFx", - "details": "CxEFcmLmkI" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.099339754970547702", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.111217397607280422" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k907nvf", - "status": 3, - "tokens": "28676349495", - "delegator_shares": "28676349495.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.609184993023386704", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.699887495531371188" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "consensus_pubkey": "cosmosvalconspub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjtszrqs", - "status": 3, - "tokens": "34574952843", - "delegator_shares": "34574952843.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.810000000000000000", - "max_rate": "0.810000000000000000", - "max_change_rate": "0.810000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "consensus_pubkey": "cosmosvalconspub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku73m9m0", - "status": 3, - "tokens": "16992076248", - "delegator_shares": "16992076248.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.406968367525101581", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.487609794856186092" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfcdg0aax", - "status": 3, - "tokens": "16967510024", - "delegator_shares": "16967510024.000000000000000000", - "description": { - "moniker": "YKKhjZGayb", - "identity": "IvgiPDjmYA", - "website": "gScrUtVzvh", - "security_contact": "kGHySpHXgu", - "details": "IyuehlcoPM" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.093407705950029411", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.187465926844434813" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7zgmra8", - "status": 3, - "tokens": "26261718579", - "delegator_shares": "26261718579.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.210000000000000000", - "max_change_rate": "0.067309904771533509" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqnavslf", - "status": 3, - "tokens": "46127605035", - "delegator_shares": "46127605035.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.895728278286976959", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.140752130806369269" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jyyn3gu", - "status": 3, - "tokens": "22487156484", - "delegator_shares": "22487156484.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.008115100503323252", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yagkfrr", - "status": 3, - "tokens": "39560123415", - "delegator_shares": "39560123415.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.060188716749386269", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.350000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "consensus_pubkey": "cosmosvalconspub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kwmez9k", - "status": 3, - "tokens": "16420725988", - "delegator_shares": "16420725988.000000000000000000", - "description": { - "moniker": "LVfceOUKZE", - "identity": "ZyVUuaCAJZ", - "website": "rliAdTPvEK", - "security_contact": "hVtZPHOsKh", - "details": "QjmMKruCba" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.036920301680485403" - }, - "update_time": "9936-01-01T16:55:11Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq77rpqn", - "status": 3, - "tokens": "22691569600", - "delegator_shares": "22691569600.000000000000000000", - "description": { - "moniker": "BFoqLaJLDn", - "identity": "weLorPCgTe", - "website": "oyhVcpSOLq", - "security_contact": "hdnvhDJTDC", - "details": "SAZISvvmwB" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.160832184115355939", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xw03emk4", - "status": 3, - "tokens": "44313010729", - "delegator_shares": "44313010729.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083856723472306849", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.569378562223247850" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6yp7zp3n", - "status": 3, - "tokens": "25164533156", - "delegator_shares": "25164533156.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.330000000000000000", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.314039829028852779" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvn899z9u9a7h28682292n9y77yr6yuyrg2xvg8eaammccqfuc9e5jp63vn", - "status": 3, - "tokens": "16985369823", - "delegator_shares": "16985369823.000000000000000000", - "description": { - "moniker": "oVMoJSrGgV", - "identity": "ydZuwvoyLe", - "website": "EdyJLNhNGZ", - "security_contact": "QauDavDNuL", - "details": "CVkbnFlumN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.276325858271560152", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.108166159043578444" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwshp63n", - "status": 3, - "tokens": "25367511082", - "delegator_shares": "25367511082.000000000000000000", - "description": { - "moniker": "KODmaZYfBO", - "identity": "dQoWoZcHpD", - "website": "QRjjuYKVNR", - "security_contact": "BHWzdORGfc", - "details": "dZGTxQmqIN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003392332242825811", - "max_rate": "0.060000000000000000", - "max_change_rate": "0.027187395396712775" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqv0lje47", - "status": 3, - "tokens": "54901950842", - "delegator_shares": "54901950842.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.193375046872051394", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.161750559623523660" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc9m7uvt", - "status": 3, - "tokens": "15374405822", - "delegator_shares": "15374405820.680335249007925874", - "description": { - "moniker": "eomlzRaIRN", - "identity": "PaBTVBXpcj", - "website": "frMwzGwrdS", - "security_contact": "XwCgZGftYO", - "details": "oynChhccDw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.014913519812752309", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.219118316904950121" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7dsh8mr", - "status": 3, - "tokens": "31376033263", - "delegator_shares": "31376033263.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.074914975922116628" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axhh8p8f", - "status": 3, - "tokens": "49683234188", - "delegator_shares": "49683234188.000000000000000000", - "description": { - "moniker": "MJAduJwrkS", - "identity": "YpKMJsMpdh", - "website": "rmUXbHIGjh", - "security_contact": "KxyJSeDEJS", - "details": "gQmDpfNyLZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.637063248045666486", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.100218674012239339" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmkm3zs42", - "status": 3, - "tokens": "34289428306", - "delegator_shares": "34289428306.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.026475742223507385", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.008016543161851368" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw3fj2ga", - "status": 3, - "tokens": "29885998584", - "delegator_shares": "29885998584.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.208832068199199828", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.835848953294536000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv7nw49k6j8sg6379dy0lemj7vee2el49mt5rmypwujwk6lua8duyrr8zrn", - "status": 3, - "tokens": "21181468286", - "delegator_shares": "21181468286.000000000000000000", - "description": { - "moniker": "TgLltHAWtO", - "identity": "zpriAAvZuw", - "website": "pWVJnIqFBY", - "security_contact": "TyuWOjmMFF", - "details": "CbbpwkidBS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.237822850366335221", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.134613352727411591" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2vncgld", - "status": 3, - "tokens": "39430946332", - "delegator_shares": "39430946332.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.400358972669819604", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.343431675789315867" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrywn9e6w", - "status": 3, - "tokens": "32328037984", - "delegator_shares": "32328037984.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.039339062684741866", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.021256256594527078" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus2udpwh", - "status": 3, - "tokens": "15813863385", - "delegator_shares": "15813863385.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.543747468021249371", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.392045382869085556" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwujx3ap2", - "status": 3, - "tokens": "25957780472", - "delegator_shares": "25957780472.000000000000000000", - "description": { - "moniker": "hoLpIoNUFo", - "identity": "LCpoujNFyW", - "website": "AOTlTXjPul", - "security_contact": "elgNvDzEfH", - "details": "hwOSWkTDMH" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.347272379813626146", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9ugfdlq9", - "status": 3, - "tokens": "45284218868", - "delegator_shares": "45284218868.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.340626334815374555", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkxmnmkq", - "status": 3, - "tokens": "44505127913", - "delegator_shares": "44505127913.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.605944631117636209", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.639343774657574630" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqk8ct27q", - "status": 3, - "tokens": "22456561633", - "delegator_shares": "22456561633.000000000000000000", - "description": { - "moniker": "DPTpRIdXgW", - "identity": "qysDMlMxpi", - "website": "xWbmLVlZvB", - "security_contact": "QtpKTducMv", - "details": "UWYfFdNOxg" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.057271144965717909", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.075138495309274904" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd7u4d80m4e6sfhyzj84k6y34v30g9cstzx7cmrazvxdtfe40urcvran9t8", - "status": 3, - "tokens": "45811135531", - "delegator_shares": "45811135531.000000000000000000", - "description": { - "moniker": "zcPImZiDZD", - "identity": "zkcTihefFl", - "website": "mIjAaWRNkf", - "security_contact": "gTafXNexkI", - "details": "tJJDPwaiAf" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.079222020883406460", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.311112908017536993" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggxauhp0sadc5npdva6f492f3n4a76fldyt3lca6lk36685s624ucakcrh", - "status": 3, - "tokens": "24610359351", - "delegator_shares": "24610359351.000000000000000000", - "description": { - "moniker": "dLwrEevbbD", - "identity": "ubSqqBoPRs", - "website": "MNuXpKVOXc", - "security_contact": "lNXuEDYSJp", - "details": "CvXURllZqF" - }, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.200000000000000000", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.175531415042829217" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqwclfkt", - "status": 3, - "tokens": "34459325260", - "delegator_shares": "34459325260.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.033986343509044787", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.090000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7t4673v", - "status": 3, - "tokens": "55948291091", - "delegator_shares": "55948291091.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.440048441195653325", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.180789237411591672" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5r4xrdd", - "status": 3, - "tokens": "15675831119", - "delegator_shares": "15675831119.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czwem9y4", - "status": 3, - "tokens": "37181480786", - "delegator_shares": "37181480786.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.177753292751501209", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.323174353688819429" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxe7jutz", - "status": 3, - "tokens": "24261774404", - "delegator_shares": "24261774404.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.017452646416466178", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.020000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4svau85d", - "status": 3, - "tokens": "31770155824", - "delegator_shares": "31770155824.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.138735148670316454", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.286634953103815529" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf0u600sgl3zdn3uh4jd6jmw6fc0jc40r0l2crvz3sla3f8d32flghwtxaq", - "status": 3, - "tokens": "37602205867", - "delegator_shares": "37602205867.000000000000000000", - "description": { - "moniker": "BUZauhlQrt", - "identity": "yuIKzyGzQS", - "website": "fDSmxAmazc", - "security_contact": "jVDWgXPhkM", - "details": "LBFAwsUoyi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.244517333363622892", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.153245122134586562" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzue70ade", - "status": 3, - "tokens": "37676305948", - "delegator_shares": "37676305948.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.260000000000000000", - "max_rate": "0.260000000000000000", - "max_change_rate": "0.239035612898447459" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj2sy3f5", - "status": 3, - "tokens": "26850762657", - "delegator_shares": "26850762657.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.420000000000000000", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.295551090875771737" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvhet24yk50y4m60mceffquewu9p4enwrgcum0csceuull7a59u6567nn0v", - "status": 3, - "tokens": "20405570669", - "delegator_shares": "20405570669.000000000000000000", - "description": { - "moniker": "ZeprycSOnc", - "identity": "ZcHuivhMFq", - "website": "hCsVpTWmaL", - "security_contact": "AIKsDuUCDR", - "details": "EgpxVbAOaK" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.054000324644638628", - "max_rate": "0.380000000000000000", - "max_change_rate": "0.120973196882786975" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6k07476", - "status": 3, - "tokens": "25102040344", - "delegator_shares": "25102040344.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.599184934718890393", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgh9lxfuk4amzsp0w28t8dkdwf2xk8yrxjj7xz0lnmzs2lyahrdz2f2yy35", - "status": 3, - "tokens": "17609505538", - "delegator_shares": "17609505538.000000000000000000", - "description": { - "moniker": "yAwjGcNsZH", - "identity": "STCkyPeJjc", - "website": "yvmEPebWkk", - "security_contact": "ZficJLXKJM", - "details": "qAWHtJiitW" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.690000000000000000", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.509977105992119960" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "consensus_pubkey": "cosmosvalconspub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjycl58l", - "status": 3, - "tokens": "41119826715", - "delegator_shares": "41119826715.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.025162698699691548" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75fh3auv", - "status": 3, - "tokens": "19565632897", - "delegator_shares": "19565632897.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.579061375935434182", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwskjpjy", - "status": 3, - "tokens": "44648874284", - "delegator_shares": "44648874284.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.258140043497759741", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.447039357737510640" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg57gy4ef", - "status": 3, - "tokens": "34209671267", - "delegator_shares": "34209671267.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.480455308806333346", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55hrcqtd", - "status": 3, - "tokens": "25069342080", - "delegator_shares": "25069342080.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.409558857679769509", - "max_rate": "0.930000000000000000", - "max_change_rate": "0.610998804526507722" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0sgshv9mf8qy7ff303mqqv5zppu3q4mcwrnheue8d3kq0ytyynkxlak2ae", - "status": 3, - "tokens": "28980476016", - "delegator_shares": "28980476016.000000000000000000", - "description": { - "moniker": "hVYOUraqpo", - "identity": "XRliNUdYgt", - "website": "FYzwRNeFsW", - "security_contact": "AYYtrdbBmx", - "details": "NaWAwUYhir" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxd2wcms", - "status": 3, - "tokens": "27742737411", - "delegator_shares": "27742737411.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.870000000000000000", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.402061609548054151" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2x30aum6t8lauwqh72szktjx6fmgf5ux7vcs38uukp9a5h287wawhv5mfv", - "status": 3, - "tokens": "17377751306", - "delegator_shares": "17377751306.000000000000000000", - "description": { - "moniker": "SslqJkEqrN", - "identity": "qMdXPqvbCt", - "website": "HDwwjWlugU", - "security_contact": "LzWMObthwF", - "details": "zlyoRqwOQS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.498765541593724538", - "max_rate": "0.530000000000000000", - "max_change_rate": "0.156108348646223859" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3lu0qw8kj", - "status": 3, - "tokens": "23737653202", - "delegator_shares": "23737653202.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.450461328836777178", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.254665389885134513" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcf30j9c", - "status": 3, - "tokens": "74690344989", - "delegator_shares": "74690344989.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.882630947578979215", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.960000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr2mqfkju", - "status": 3, - "tokens": "27874325464", - "delegator_shares": "27874325464.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.459241580368376871", - "max_rate": "0.490000000000000000", - "max_change_rate": "0.448990769658695281" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngklt9fqt", - "status": 3, - "tokens": "67833673918", - "delegator_shares": "67833673918.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.280411773058535090", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.009358685901125498" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdq8fheeu", - "status": 3, - "tokens": "25446232136", - "delegator_shares": "25446232136.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.073669961838812257", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.338443455873010612" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdjuv3ql5rv5njym62quduw7554as4aa8seufp7f4zv6q28tds2e23v4cv5", - "status": 3, - "tokens": "35741739231", - "delegator_shares": "35741739231.000000000000000000", - "description": { - "moniker": "MoJgIrbTvT", - "identity": "rTfyDjhPlV", - "website": "fXpRItnlwS", - "security_contact": "tIlMCZPLDi", - "details": "QoSUrnFXNb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.037606710200997532", - "max_rate": "0.610000000000000000", - "max_change_rate": "0.432717335122536998" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwvhpfht", - "status": 3, - "tokens": "19637280062", - "delegator_shares": "19637280062.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118259925415637398", - "max_rate": "0.220000000000000000", - "max_change_rate": "0.176572964585642890" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwaazwez", - "status": 3, - "tokens": "56856814851", - "delegator_shares": "56856814851.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.093189165744722643", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.044880981942823250" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyvxmu04", - "status": 3, - "tokens": "36122807193", - "delegator_shares": "36122807193.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.414145633705698803", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.500000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd2gmrd8aux64z50e58tu00n3yjunvqduf4xv3g3p6j3wpuxddex59mpcfe", - "status": 3, - "tokens": "16807158123", - "delegator_shares": "16807158123.000000000000000000", - "description": { - "moniker": "ZHKMxyLBmy", - "identity": "EwvvJnavFX", - "website": "DHXlVcQLfr", - "security_contact": "cqkJGwinbb", - "details": "CwxLKqsDci" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.054776212220005616", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.012318363733558931" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2p3sa8dkvz36pz6nusjdhm9aqlnrrldrszzuqd5qy7ssqztn99ggqpcdlz", - "status": 3, - "tokens": "48540826744", - "delegator_shares": "48540826744.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003549575739989554", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.001119527935415439" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycjhwrn7", - "status": 3, - "tokens": "29401856985", - "delegator_shares": "29401856985.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.243341366114153903", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.628404054381210058" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdaa2szanfjwhzucqfj0ct7ljhc3kew8am3h8sr8wqzlnh8df06g5th460y", - "status": 3, - "tokens": "24697024268", - "delegator_shares": "24697024268.000000000000000000", - "description": { - "moniker": "XYWZXrqRDE", - "identity": "MFgElwSSlb", - "website": "ZPGkarWAml", - "security_contact": "dFzxEZXTfo", - "details": "HRGbXKBEeq" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.550000000000000000", - "max_change_rate": "0.376530136432859216" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w4r0vhq", - "status": 3, - "tokens": "41494205421", - "delegator_shares": "41494205421.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.070000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgc0dahup", - "status": 3, - "tokens": "54450506134", - "delegator_shares": "54450506134.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.109747630034489371", - "max_rate": "0.970000000000000000", - "max_change_rate": "0.461346401411912639" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkn6paax", - "status": 3, - "tokens": "23703504292", - "delegator_shares": "23703504292.000000000000000000", - "description": { - "moniker": "eXfwGKuzGb", - "identity": "dYpMrjwrPA", - "website": "DzaFOsditE", - "security_contact": "GuNLPoNZsM", - "details": "iALsKeROvR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.087538799057934086", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.859363741701174499" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyt542en", - "status": 3, - "tokens": "69725274862", - "delegator_shares": "69725274862.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.077835183941357357", - "max_rate": "0.630000000000000000", - "max_change_rate": "0.287966636331923139" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwfq28wcw9gn3mynr4pjdpd5hhert9hheg8qus862ymrt5ex6j75jlkuhe3", - "status": 3, - "tokens": "21764467799", - "delegator_shares": "21764467799.000000000000000000", - "description": { - "moniker": "ObWwGUpRaY", - "identity": "BCfhwnVexY", - "website": "SBehiPUtRR", - "security_contact": "jMhyvuyFaP", - "details": "LHYAZFxdaS" - }, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.075332177620667120", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.039077923270826524" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsrp7s99", - "status": 3, - "tokens": "25229713771", - "delegator_shares": "25229713771.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.420000000000000000", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.006473324874363207" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd5jsj53j7m0umzvh90dwanxhfxmpydhfazmsz978v9yuh05q0kxcyqtdla", - "status": 3, - "tokens": "16747268503", - "delegator_shares": "16747268503.000000000000000000", - "description": { - "moniker": "OuShqctNnC", - "identity": "MfQbnbeXdv", - "website": "OfOpteXCQn", - "security_contact": "qaSLhJmnUG", - "details": "vIuRzAnYuu" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.589668369513377579", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.640000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge726q0dwq", - "status": 3, - "tokens": "56914095343", - "delegator_shares": "56914095343.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.561558403350280399", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.088588598076790894" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0us7fav4", - "status": 3, - "tokens": "53587404091", - "delegator_shares": "53587404091.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.148502470554898869", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.005661642347781868" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw32mxlzzzmmpks775cgclcsmypqhhz7765v03wnjf8cn4hsrw67tq2l8n", - "status": 3, - "tokens": "20301516153", - "delegator_shares": "20301516153.000000000000000000", - "description": { - "moniker": "ibdjDFXkFg", - "identity": "BhaqDbDPwH", - "website": "KoHplbnTSd", - "security_contact": "zgJBSepZRt", - "details": "anTLerUmWY" - }, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.092279263137073204", - "max_rate": "0.130000000000000000", - "max_change_rate": "0.062347977318301413" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4umtaftt", - "status": 3, - "tokens": "23438430919", - "delegator_shares": "23438430919.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.065104244001935780", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.087973256413395308" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wu8lrdvr", - "status": 3, - "tokens": "23476663612", - "delegator_shares": "23476663612.000000000000000000", - "description": { - "moniker": "qNlNvDKQWh", - "identity": "PdEEmVXzOP", - "website": "jyQRsxutdI", - "security_contact": "hTNdvfWkVQ", - "details": "gPNrXPrkeL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.830000000000000000", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.679717803083962746" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7pax9cuqs5vjjvhpmcgvy5dkqrrtrg6336c3xhyrchtegy2m387ccs037", - "status": 3, - "tokens": "19815525788", - "delegator_shares": "19815525788.000000000000000000", - "description": { - "moniker": "sJKzLUYWBq", - "identity": "ZzbWnFqPTq", - "website": "dlevXyAGdk", - "security_contact": "bnQNzwNRYP", - "details": "PaxiDbFCJj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.291627565410574418", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.017987067010819344" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wel7d3l", - "status": 3, - "tokens": "25456865344", - "delegator_shares": "25456865344.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.293848609442759777", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.580000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6u59lzkg", - "status": 3, - "tokens": "44085124225", - "delegator_shares": "44085124225.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.045106108515206331", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.610987430943531252" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xvdql9k", - "status": 3, - "tokens": "25311353934", - "delegator_shares": "25311353934.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.324580145668396309", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.480000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujgucg2ktdn", - "status": 3, - "tokens": "32745806516", - "delegator_shares": "32745806516.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.322505571100731689", - "max_rate": "0.520000000000000000", - "max_change_rate": "0.183472725952677048" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592jkkxzm", - "status": 3, - "tokens": "21858111883", - "delegator_shares": "21858111883.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.799310131872627643", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.706235617003159879" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxtyq8dz", - "status": 3, - "tokens": "28684472849", - "delegator_shares": "28684472849.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.174404138163737710", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.360000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - } - ] - }, - { - "header": { - "version": {}, - "chain_id": "simulation-app", - "height": "50", - "time": "9936-01-04T17:25:47Z", - "last_block_id": { - "parts_header": {} - }, - "proposer_address": "jgjZuluGDLAuRHWL1Yy8d/evPjs=" - }, - "valset": [ - { - "operator_address": "cosmosvaloper1qqxeqqvjkh2ls3a0taukd8rydrqqad6928jr5t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels7tpscy", - "status": 3, - "tokens": "24767745772", - "delegator_shares": "24767745772.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.064962829627143450", - "max_rate": "0.700000000000000000", - "max_change_rate": "0.524524837966075502" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qpj52qsl708aqhazaqehhjw7cdj4her9krlq29", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xt2s2vh", - "status": 3, - "tokens": "40149298125", - "delegator_shares": "40149298125.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.020987080088521851", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.079654399773437862" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qzj5kxv664trtfn4h0aznrsljtt2q95qg3hlv7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk7tt4rl", - "status": 3, - "tokens": "33873720903", - "delegator_shares": "33873720903.000000000000000000", - "description": { - "moniker": "mLoNnmWUiV", - "identity": "RHiUhLQQnZ", - "website": "GdVEOYibSd", - "security_contact": "DcfUpyGSpE", - "details": "kaQgULDDFV" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.793635545567707656", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.546926599085395557" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qy0qwzljplfauvyhgayw6nxte2zxujh4w856f3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfkykt89x2wmxt2w74v340hwp8azwyzswzgxzmcv46995zwggpu66ans7kn", - "status": 3, - "tokens": "49524189675", - "delegator_shares": "49524189675.000000000000000000", - "description": { - "moniker": "qorkgLHbbW", - "identity": "vVsXuupmaH", - "website": "GASCHEJsbz", - "security_contact": "KEcXQQooNh", - "details": "UlGvDMHBgm" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.150351690116871266", - "max_rate": "0.470000000000000000", - "max_change_rate": "0.232118363435586291" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q9ed2n5wvzcrymaqltypazqzd2xv8d5atqnunc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcrkzkl0", - "status": 3, - "tokens": "76742997299", - "delegator_shares": "76742997299.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.159853619317053801", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.178173481628386356" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qw9wqlz92hj8y6mcj24l6wu68er03njuk00ex3", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0yv2h8z80vtfttsewrwe2v83haaceax7q3ey95uaeqj8lstf7l674zn3ut", - "status": 3, - "tokens": "16016194501", - "delegator_shares": "16016194501.000000000000000000", - "description": { - "moniker": "WVhrVMjLnZ", - "identity": "QiIQjemxtv", - "website": "KCKlbRarYk", - "security_contact": "AwimEeOMDq", - "details": "omCiVdOfZS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.636807270475032336", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.762928812525012131" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qsxjdj8z2urjdxpp7uu37pp2pf3chjjclca49g", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghknhrvft", - "status": 3, - "tokens": "32584502965", - "delegator_shares": "32584502965.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.063963134401067102" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1qs5htj5ayfgg27t0xnng837lzllla5y298q230", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgt7tyq6", - "status": 3, - "tokens": "15545552914", - "delegator_shares": "15545552914.000000000000000000", - "description": { - "moniker": "VaOLitHrfh", - "identity": "zYkbJeTdPC", - "website": "RWLWpQBLTs", - "security_contact": "EEFOrnsvml", - "details": "xRXuWfcvoz" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.209346043397093808", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.261491014079542938" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1q55pmsr0wnpzlcx25p9vqde6c52ekjnvsrnquu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpvkknmf7", - "status": 3, - "tokens": "35273490053", - "delegator_shares": "35273490053.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.412168984856446389", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.601152598273329028" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ql2jawqmha8d2xdgda7njakszmhvt75rcx3r2x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvw0g93n8", - "status": 3, - "tokens": "24353363633", - "delegator_shares": "24353363633.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.140843713075627976", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.124247346623493378" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfvt083j", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtxrkpudghuhgsu0he7ntk7q0asqa5ax23y7rnn5mfjr2d68z4emsrwqssp", - "status": 3, - "tokens": "44979344173", - "delegator_shares": "44979344173.000000000000000000", - "description": { - "moniker": "eJECwiPlqs", - "identity": "TywZsaZwgH", - "website": "jtFVQJUofX", - "security_contact": "fstanspUpc", - "details": "RQddrwMsIR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.005369299901591159", - "max_rate": "0.030000000000000000", - "max_change_rate": "0.010979308887356502" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ptu2vxfcsyl2gpeg73ehzte7t3va459lxfkvnz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwz2zelc", - "status": 3, - "tokens": "24972834479", - "delegator_shares": "24972834479.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118883162683785924", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.582076368438090700" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1pjwsvz9745jftv0p0c99t36m6kf9e8rxve9myn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q205udc4", - "status": 3, - "tokens": "37286335725", - "delegator_shares": "37286335725.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.150000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.137121313165408722" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zyp4lvynuuz8vzmzprpy8mxm4rkql6ryw8uemh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zycdvvrg7", - "status": 3, - "tokens": "26109827309", - "delegator_shares": "26109827309.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.272379182115041576" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1z97a2xx0rzwtfftg3k9yt693dwxx9j802xks63", - "consensus_pubkey": "cosmosvalconspub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwlhqscf", - "status": 3, - "tokens": "25204407264", - "delegator_shares": "25204407264.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.276804190595109972", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.303611347820460701" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zf34ku927tasyr9fswhasvqt0x49janz0jgd5v", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2u3gzal", - "status": 3, - "tokens": "23014258552", - "delegator_shares": "23014258552.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289943655120962524", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.271265684659427360" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgrr3msw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgh4tj7q", - "status": 3, - "tokens": "49505425616", - "delegator_shares": "49505425616.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.519126528788995280", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zscesuffz58dc0lq7yy6n6z3j5fhkr3dgdwqnh", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw55ftmtn", - "status": 3, - "tokens": "52891997390", - "delegator_shares": "52891997390.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.006443603339396517", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.110565720532816181" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zjw6x8t95zuaxprcyl0x6l7u0ag6626vm63pgm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavc40dh4", - "status": 3, - "tokens": "69365122054", - "delegator_shares": "69365122054.000000000000000000", - "description": { - "moniker": "IoqkplxtIQ", - "identity": "SYtEYnqVjz", - "website": "cbrMdhVrVp", - "security_contact": "eWitXxyhJZ", - "details": "FCojJQQFCQ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.745132980800690980", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.321606633967630124" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1znvq8jqpwxt5hk2lg5654l7eg7kap3rpdx0qke", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tugphy2d", - "status": 3, - "tokens": "17054284690", - "delegator_shares": "17054284690.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.602634897210355218", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.136597759514787421" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zu50umwgah6jhx07sw04ry0pv7fnvkpj78nenk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jztkylp", - "status": 3, - "tokens": "55080258715", - "delegator_shares": "55080258715.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.052047960532670175", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1zah0g92ytwdvpchd3sceuanu7knhtu22sc87c9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgrwz3gl", - "status": 3, - "tokens": "17768682341", - "delegator_shares": "17768682341.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.141929485726276362" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rq7tvegh0yqan5fpp90rya7q9lks5nyx6u934n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yr97z8g", - "status": 3, - "tokens": "22598538029", - "delegator_shares": "22598538029.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.335354744004515496", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.096800797786563611" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rpxgsrsrx8jntwa6q9m0a4xxypnphs9z8hmsdm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2zq3f3j", - "status": 3, - "tokens": "27149799034", - "delegator_shares": "27149799034.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.158969199652087770", - "max_rate": "0.220000000000000000", - "max_change_rate": "0.220000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r5tg7kujl8x77c84dedr2z9agsjyp8tq55yl5x", - "consensus_pubkey": "cosmosvalconspub1addwnpepq246sxc5kns0ym6st5wyf6mk0x2cayek9wngczyvgk8phxrat02cqh8w5p2", - "status": 3, - "tokens": "49314038732", - "delegator_shares": "49314038732.000000000000000000", - "description": { - "moniker": "caRBWwzxXd", - "identity": "BJSnkbfQjh", - "website": "ELsVPBoBHb", - "security_contact": "nZkoSMuzKV", - "details": "AuAKjeoitI" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.010525961964940541", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.045814731203367877" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1rkl7umzewantxm5e8mf2l2tcxc3t7hj8ep3800", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jhhj4uv", - "status": 3, - "tokens": "26185707851", - "delegator_shares": "26185707851.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.568319127244896272", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.226261076338173049" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1re5reme6kyayzfanalqm89u2r9an6wu92muvqh", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5u4v4q5", - "status": 3, - "tokens": "32785129607", - "delegator_shares": "32785129607.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.009044195385937429", - "max_rate": "0.010000000000000000", - "max_change_rate": "0.002281789765845776" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkxja3el", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpqq8zx8p", - "status": 3, - "tokens": "33846192792", - "delegator_shares": "33846192792.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.094250378854551281", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.043420993012939508" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yva09usdkzdsqekaasgcqvm50v9vv5pusaesaz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv79a2a0wcq9kr62m5yupvx82mlxwxw6hx7c8dyl4trf8k2w7vh3w5wlhy0", - "status": 3, - "tokens": "25066394767", - "delegator_shares": "25066394767.000000000000000000", - "description": { - "moniker": "liMRThtiLT", - "identity": "QPHsvzHnkx", - "website": "BytvAmppJT", - "security_contact": "iBgKxrOkqF", - "details": "RcELAgZeDN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.115126355797501393", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.289658857878369113" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yezuhyh4htsy74jkhfey9p7urgwhg00j5jdl89", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfp9mvx6gjdezn2vfxn9jk7jm2urml0xyvt3yg64s03yzkfphrthsdy925d", - "status": 3, - "tokens": "25061237568", - "delegator_shares": "25061237568.000000000000000000", - "description": { - "moniker": "wmxxGOZTpL", - "identity": "azxfwYYUUt", - "website": "izxOUVhQSX", - "security_contact": "lRgXsoitme", - "details": "eebhMKbHXO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.578049895054733896", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.402405887034980654" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1yalqz5m4qcjtss37pdnvalz5kaws3yjy9y2f9d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc255eyr9", - "status": 3, - "tokens": "76719658246", - "delegator_shares": "76719658246.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.321194785873117781", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.561602155526895676" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1y7m2ga0zpxr6q000a4a924fdaeycw5edpzhy6z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u43hapa", - "status": 3, - "tokens": "18750673243", - "delegator_shares": "18750673243.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.188948913118426394", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.274693773376656673" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ylf26t6vhvugawg87328ng2ug4d8f25spj40et", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvpup8kv2mmqajfs08aks8yu8kcuwd323y4f0wu9e3k5grynt0g6ule9mjg", - "status": 3, - "tokens": "24248574347", - "delegator_shares": "24248574347.000000000000000000", - "description": { - "moniker": "bsrCMyYTRM", - "identity": "cTWbJOIMRX", - "website": "EMzKHBarjX", - "security_contact": "spsTAIOECF", - "details": "fTrZtqJTUr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.455524678875180233", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-01T06:29:20Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19qqvhp8aacjvxjhtgwncctmtrmjelqs67wsfu4", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d29fg079", - "status": 3, - "tokens": "82798702711", - "delegator_shares": "82798702711.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289674444273548704", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.060992257943659564" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19yplr2r5lu70jlymwrumzuc8tqeeu7fgq4kpea", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgss8cv9u", - "status": 3, - "tokens": "26155915081", - "delegator_shares": "26155915081.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.333198345990187069", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.410926346802169727" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19fa3uz9n80megf46sfu7kzepfup4mjccl6dy77", - "consensus_pubkey": "cosmosvalconspub1addwnpepqghlm3r37c95q3p3wvr8fxw8mvvdtj3tvhgduhzgzh4238ynz6f06f0rjfd", - "status": 3, - "tokens": "32302576994", - "delegator_shares": "32302576994.000000000000000000", - "description": { - "moniker": "hjulbVDPpf", - "identity": "pRsBrwBRzq", - "website": "VjiSZKAfKB", - "security_contact": "UHZkwTciXO", - "details": "JTfVgehmsi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.311759176624756474" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19wgl6sjkktp7mysmmtzqnecd5v2xn7gs2uek3m", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwus66jdl", - "status": 3, - "tokens": "54108139534", - "delegator_shares": "54108139534.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.500000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper193pvwgxpxnd6tgz0gtyl00dq8r3ygeflkrfndg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22ep2k8n", - "status": 3, - "tokens": "69316998057", - "delegator_shares": "69316998057.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.624946300778690751", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.204995912261423056" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper19e3lp8kdpnzmd778gxz9hqrnaxw8spa3w2x2fa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7ejhy28", - "status": 3, - "tokens": "27808118568", - "delegator_shares": "27808118568.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.067795278161998694", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.011309118617844055" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xw7mpsuf4vma4a2thsad2623wjcgcy6unhhmuu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5kc0mzw", - "status": 3, - "tokens": "17750303222", - "delegator_shares": "17750303222.000000000000000000", - "description": { - "moniker": "uloyQQWkyI", - "identity": "gFyXSGlhKI", - "website": "ewFltsApZk", - "security_contact": "YGvOhkEKJw", - "details": "vIoOsfiLuj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.068730439287548849", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.118090772640391070" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xnh4mumajk76tlnsp8d3d95r7hjnt4drg2v3x6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw4vh38c7e44vpvszes4lcvjkz3ah25sja3jyj8a2jyfk44fn033xtu5ld3", - "status": 3, - "tokens": "22144783949", - "delegator_shares": "22144783949.000000000000000000", - "description": { - "moniker": "cJZANkQgEs", - "identity": "BMLCKDJfbU", - "website": "EvRCcPcNDz", - "security_contact": "wYcIjPQECa", - "details": "FTToLCGlSp" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.490000000000000000", - "max_rate": "0.490000000000000000", - "max_change_rate": "0.478812992279810912" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1x76xgyet9jkq94uqcckrwm20l85gt2kxjfn952", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv0pnal4w8hydpq3vydqgjxmmxz7zg2g9lsj5vedvjq3pw6typfdcjfm5tc", - "status": 3, - "tokens": "16214844041", - "delegator_shares": "16214844041.000000000000000000", - "description": { - "moniker": "jKdcmnPYfC", - "identity": "exfUuYgqmd", - "website": "XdNCNZIBOf", - "security_contact": "hmiwPGchGt", - "details": "nUnBufZQah" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.330000000000000000", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.051583680374523519" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmtdxs42", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057uxwdfy", - "status": 3, - "tokens": "23352431465", - "delegator_shares": "23352431465.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.760000000000000000", - "max_rate": "0.760000000000000000", - "max_change_rate": "0.183753469845780730" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18p7qvgvjcpl85mjwtvepe9reevevnm9fcfuglt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvy095yf8a7eknhlnwzkum0wt53njxxww60vte7qkutwczt534dwhaclpm", - "status": 3, - "tokens": "34693121909", - "delegator_shares": "34693121909.000000000000000000", - "description": { - "moniker": "RuzZVxWXdB", - "identity": "QjsgdqaNzA", - "website": "UtlkBZyIyQ", - "security_contact": "vnsfyiwxFP", - "details": "dOxLDmGKTb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.005447024365505786", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.005395717096845063" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper188yd2umzwfwen7es68wrlh6auu3p8jhz25aa4p", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef5gg2q6z", - "status": 3, - "tokens": "42958814024", - "delegator_shares": "42958814024.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.077000158168963029", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.197697608060710078" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18gmd4r8ydls55yvgda4d8pfandk0xem592dg85", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwv7ukq0", - "status": 3, - "tokens": "21734647779", - "delegator_shares": "21734647779.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.460679550676466675", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.165088210560206816" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18fkw6s4hnj2llxljrkleetgns2y0h0vjdnzw46", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwc7h5wds8u3tspx3mwpfh5l3q3rv0t6ff33dt205v2zy2kxev9sykcs9uv", - "status": 3, - "tokens": "29256610441", - "delegator_shares": "29256610441.000000000000000000", - "description": { - "moniker": "iYUgQcrziE", - "identity": "hDYXNaKKIu", - "website": "FYsreoPnoD", - "security_contact": "FGAHzGKfjM", - "details": "gkHwWfssaE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.585764113115952818", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9936-01-04T11:36:07Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn542ej4td", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz4r8scm", - "status": 3, - "tokens": "65051132532", - "delegator_shares": "65051132532.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.041535797793389960", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.029250263820409753" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper18d56e7qz5869wegeca967hrxrmfduxde8n3w5r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2cxeaw4", - "status": 3, - "tokens": "18897052265", - "delegator_shares": "18897052265.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.416117321788354038", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.139830256647094326" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1864wj4twqatq54rrxl5jmfey55tmh0hvd0esga", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazfcl7f9", - "status": 3, - "tokens": "27157083976", - "delegator_shares": "27157083976.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.170000000000000000", - "max_change_rate": "0.024288054259102348" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper187wgdejp6c2h502gtkzxcpn6qgrw9q54292w5l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgxqjc3u3", - "status": 3, - "tokens": "45028692546", - "delegator_shares": "45028692546.000000000000000000", - "description": { - "moniker": "UeFBWJANuQ", - "identity": "gypzUiAlRd", - "website": "zZezcKCiKy", - "security_contact": "KSXTvslQOC", - "details": "qqNIBlVIYk" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.075610127679217055", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.290000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gpk39c5dc4xnevhz4c7m2sjxequw30s378km5p", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xwmrp7sq", - "status": 3, - "tokens": "35018830437", - "delegator_shares": "35018830437.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.740000000000000000", - "max_change_rate": "0.405901469124460870" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g95xvy8qgzcvcl05fse0mpxzdfv3w88tydj35s", - "consensus_pubkey": "cosmosvalconspub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc92g545rl", - "status": 3, - "tokens": "17547285969", - "delegator_shares": "17547285969.000000000000000000", - "description": {}, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.073548473514397047", - "max_rate": "0.440000000000000000", - "max_change_rate": "0.413655116572301617" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqky3rk0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wyr7x83", - "status": 3, - "tokens": "25071600389", - "delegator_shares": "25071600389.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.280000000000000000", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.063599161373317498" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1gfta9y4c4j5dd08mju2zf23cmdn7ylauctcdcp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymswdv67m", - "status": 3, - "tokens": "27784307296", - "delegator_shares": "27784307296.000000000000000000", - "description": { - "moniker": "mjkYspzJbE", - "identity": "xWPMeIdPEi", - "website": "xtRPXfTiQB", - "security_contact": "sdKpqtdpNe", - "details": "MnLujfMpnW" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.100000000000000000", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.072530327063185081" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g58m70guf3p7y6hhf5trqmhzpzn99rvrngvpcr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslqg7mlcx", - "status": 3, - "tokens": "31634692393", - "delegator_shares": "31634692393.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.554757466700447989", - "max_rate": "0.820000000000000000", - "max_change_rate": "0.408903182457515462" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1g7huk7g00saw6ntyqq7s8ek7l0hz4w2zkjkt5t", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvlfyhyylne6t33wzse5vhjd3xxyrfkjfmdyvk3gq4rrdhe2e0ul2n637uw", - "status": 3, - "tokens": "25080486106", - "delegator_shares": "25080486106.000000000000000000", - "description": { - "moniker": "MCiuCZVGkF", - "identity": "YVlJRRVogl", - "website": "iBpLGvpPpo", - "security_contact": "bvXcaUSxzJ", - "details": "zsHdsXWXhJ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.012334216153398550" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1glku8mx4nzp5crkjt7px9lfe4flfge3zvwp7s7", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v67hlsk", - "status": 3, - "tokens": "16236700229", - "delegator_shares": "16236700229.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.498536222135788025" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fqmkps3v8evytw9jmpg3g83a6s0fy8m2jak2du", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5l4jsmp", - "status": 3, - "tokens": "42927955154", - "delegator_shares": "42927955154.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.190381602916620701", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.303876600993529705" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1frjkqcr3r5fpwds4kypq5e9n865qss6uxq6u0e", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g7drc35", - "status": 3, - "tokens": "36911230696", - "delegator_shares": "36911230696.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.194945225911581915", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.300000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f2pvewnws73u0z5wsfmv5uqudwxl6jupv0wx8w", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcas8xka", - "status": 3, - "tokens": "39363181311", - "delegator_shares": "39363181311.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.028169322828760497", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.050000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f2sunjkaqyu2wr9jupyjkl7qhlnesag7dmncn0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcvjsxyz", - "status": 3, - "tokens": "27734813665", - "delegator_shares": "27734813665.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.015116864220436494", - "max_rate": "0.050000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fv35lda8ltd6juk384yqceqalcxyfj4k4vjh8c", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd5nsxkua92z9eamd4hccf0pxeh3chye2475vcrwc22dpxj4lmkvuy950w7", - "status": 3, - "tokens": "27605610764", - "delegator_shares": "27605610764.000000000000000000", - "description": { - "moniker": "RLaOPuFvKx", - "identity": "LQfktbUgZN", - "website": "JiRhAUTjQG", - "security_contact": "LTGuZUEvcW", - "details": "QjLWSYAXxH" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f3j0m80ey8ujgfg783838jqnuw63h3v0sln0da", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskj3a67t", - "status": 3, - "tokens": "24423311847", - "delegator_shares": "24423311847.000000000000000000", - "description": { - "moniker": "OtyVVqWsup", - "identity": "EqaejuaTwX", - "website": "egvJRLAnYF", - "security_contact": "KTzlQLiomS", - "details": "ETXsigXuTY" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.372711230134865265", - "max_rate": "0.460000000000000000", - "max_change_rate": "0.056760418592473079" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fjct2f29ymrw9h7aqffafx863c4tkxdhqtkgg5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjzxhelr", - "status": 3, - "tokens": "25592800910", - "delegator_shares": "25592800910.000000000000000000", - "description": { - "moniker": "NYvAvaIOdj", - "identity": "lYbVDursvX", - "website": "UXtFzZcHjM", - "security_contact": "PNNMeOJqcl", - "details": "ROVIgdvaJl" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.193312772989594496", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.226297820963910157" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fhpyqq3eex5zcctlgsxj3s3dgz64am964luqka", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvvur4tyyl553c4jeyvce0w3d0ezrrmsr6a2kcdksca4wpflc3lj7nf6fm9", - "status": 3, - "tokens": "25675698411", - "delegator_shares": "25675698411.000000000000000000", - "description": { - "moniker": "wDAGDTplVL", - "identity": "VUJoHvcuZs", - "website": "JzvbSfINxu", - "security_contact": "cROcYcTImn", - "details": "bdBDwVnOvM" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.108086670177688287", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.123495090782214164" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fhnwxus6yyk6lman2qf9fzuqtekl7gcwrntmvx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsuh3jpet", - "status": 3, - "tokens": "50488222690", - "delegator_shares": "50488222690.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.801397182624616334", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.592521503076154232" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fc96780mrsxn5kgplhtna40qepjgrm9w4st3re", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfk090csv4thlsr4kx3fuucwcsk79lqs6gr5zse6m4xmwpq94hy2w3yuqp6", - "status": 3, - "tokens": "20659893696", - "delegator_shares": "20659893696.000000000000000000", - "description": { - "moniker": "gqjwubbLDT", - "identity": "OsKsdzWbsv", - "website": "rhWGeqAAVi", - "security_contact": "FmaEvvcaAr", - "details": "uMULjHPlYr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.168812875456833709" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1f6qxvzgn7lfsvg2f86m30pshf8wuygk76daup9", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5t7pxck", - "status": 3, - "tokens": "53644768786", - "delegator_shares": "53644768786.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.180000000000000000", - "max_change_rate": "0.029528662482337368" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1fuge5wmj546lq6ljv9zfzjjgknrfmngv2jcgdp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2z47zet", - "status": 3, - "tokens": "21168715051", - "delegator_shares": "21168715051.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.026318239077074162", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.076792434560738120" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12q3w0j5hp023hdjafgc357hy7kkha296vpjk76", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyw0np92", - "status": 3, - "tokens": "27374742411", - "delegator_shares": "27374742411.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.053895535796610462", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.182737583024108345" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12r0m6hwrnn0jy02tnhmk328d7p68x2rngkl678", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2al69u7pnek9kcrmz83vstrst5szxuz6z03z0d848kuh3ekkjlfgr96q6z", - "status": 3, - "tokens": "20929858941", - "delegator_shares": "20929858941.000000000000000000", - "description": { - "moniker": "ciowxbJZpb", - "identity": "XgDAZmwEir", - "website": "moPXkGzyqT", - "security_contact": "WTLysotltH", - "details": "qoTHCiKGoL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003240694138410597", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.013650990946439583" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12dh9h444s238r7hjrrd2kg6wrw4cwfk33kk6nm", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzvca96h", - "status": 3, - "tokens": "70162120947", - "delegator_shares": "70162120947.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.545864029263808659", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.533310660658318421" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper12nv5therrzkwjmvrmmnng6uqk2d8u6y7ma28dz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqlk7nha", - "status": 3, - "tokens": "20279593182", - "delegator_shares": "20279593182.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.069908236020668720", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.009891358364124589" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tz087eh88lqkesr77yl6ys9dw95qysfqwaapxw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqva0a8amjektwyshzjv38f6dw5uwat88kscw834kf3026r5ksn77gf0857j", - "status": 3, - "tokens": "31584297936", - "delegator_shares": "31584297936.000000000000000000", - "description": { - "moniker": "BKQyTeKaLC", - "identity": "eCoPebxrNV", - "website": "auQgzJBeZR", - "security_contact": "bLlknxqKWU", - "details": "amiXFmUGDr" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.900000000000000000", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.031968764827487641" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1trkrhq6mxwktf24u8jepelvumpd9l6ler2v2u8", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4cv2x09p", - "status": 3, - "tokens": "22768989048", - "delegator_shares": "22768989048.000000000000000000", - "description": { - "moniker": "EVTkHBKcpE", - "identity": "hMErYohFOn", - "website": "QaWaMRxOKv", - "security_contact": "qaxyuRDTeX", - "details": "ELwgPpPDKw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.386471695225710439" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ty5s8h0gwtc285mnxwq43cyt2s58g25ga056hm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfjcp62cfnelz8s5cl5qar8ymfjd5sjjkkr4tayrqrtzpf638hkjqmg9q4z", - "status": 3, - "tokens": "26491705865", - "delegator_shares": "26491705865.000000000000000000", - "description": { - "moniker": "SJeSnSdrXp", - "identity": "OTlQTOJbcV", - "website": "sulWDbaxDh", - "security_contact": "XTGtIDYHdJ", - "details": "KNeohKLilE" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.965860683215034339", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.778196912581936923" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tftatt0lp0v59qqf449pdqar8w3yj7n7rf296f", - "consensus_pubkey": "cosmosvalconspub1addwnpepq28myc67l0yhmnn6n2vq8hcmpaxesglyyqg825ujgrxdt9afwlsfx4ezupt", - "status": 3, - "tokens": "16257375002", - "delegator_shares": "16257375002.000000000000000000", - "description": { - "moniker": "mtHVFaNGLx", - "identity": "YTyhLHiifY", - "website": "JFeCDRXGYc", - "security_contact": "HndWqVmQvE", - "details": "JFVkeOUSbg" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.018292046092814578", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.057525240491425891" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1twu2lvgp3erk6gups2a8nae3jdahaj2x7tguuw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z6ckp5s", - "status": 3, - "tokens": "62801915451", - "delegator_shares": "62801915451.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.323440196337864016" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1tnh79aat8d4m82pfm7gqa0z5kzzh7zty3q3eaj", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng9t438v", - "status": 3, - "tokens": "22515450726", - "delegator_shares": "22515450726.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.752425052602923482" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7gwpyly", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6mcm2m0", - "status": 3, - "tokens": "29556680915", - "delegator_shares": "29556680915.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.289048467390880739", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.476925303769745140" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1terlqq72gje366346skcmzfgg4lqypf52kamah", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswzcmkck", - "status": 3, - "tokens": "25121635132", - "delegator_shares": "25121635132.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.541820589241677763" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1t6k46y53tkcjvdttujt542pcfrwanw0ftn4wxf", - "consensus_pubkey": "cosmosvalconspub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z2xdtk5", - "status": 3, - "tokens": "25662668318", - "delegator_shares": "25662668318.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.493962290871886167", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.601549819261141285" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1taucnwfqfkpq6c6y345j6h8jt5fffgla3sldvg", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vype2jq", - "status": 3, - "tokens": "59694062218", - "delegator_shares": "59694062218.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.047504130944412074", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.160000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vqm5fdsflvnee33gk3d5pz7j6tf6dsp2zddw5n", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2xzg536q0eksvxd2297ycyctfwp6x7rk0wq6d0murld346cjs756v0jnxn", - "status": 3, - "tokens": "16949426508", - "delegator_shares": "16949426508.000000000000000000", - "description": { - "moniker": "dNCvXIwisF", - "identity": "PInuRSnoAB", - "website": "IFaDEJuVii", - "security_contact": "DiiitKvkqG", - "details": "wJQyZMjCjC" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083382298074645848", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.156261937510636548" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4az224k", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag73jg46g", - "status": 3, - "tokens": "20324460034", - "delegator_shares": "20324460034.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.742458631966852296", - "max_rate": "0.750000000000000000", - "max_change_rate": "0.368222450098111604" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vfcm9c4psqrkv9zecgjw7zxvw2jnpe7322w04f", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4d6e962zqejqu3jeypzp740n4k62xte2qnj82q03y28v6wkshycxxdg5w", - "status": 3, - "tokens": "18158211957", - "delegator_shares": "18158211957.000000000000000000", - "description": { - "moniker": "cVYtBkXobK", - "identity": "JOBpTikHPq", - "website": "NyobvRjfBj", - "security_contact": "bKDbHWcmSW", - "details": "xGfkOaAoAb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.340000000000000000", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.117974822314921419" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1vsuhkup8jznqt89zgv9nw8c3u3a7l3u8mvhthm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4cv0e5r0", - "status": 3, - "tokens": "25435646393", - "delegator_shares": "25435646393.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.004320117912957935", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.000447271047532656" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8dd4zvd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwfwqlzf", - "status": 3, - "tokens": "16773399211", - "delegator_shares": "16773399211.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.926805735750034881", - "max_rate": "0.990000000000000000", - "max_change_rate": "0.482844926743337660" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dzuk49ssprfz3ala9tea3x74x8n2nlyzp3pgxn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qavly08", - "status": 3, - "tokens": "17705677177", - "delegator_shares": "17705677177.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.615745867723667485", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.398263247650399274" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dtdk5uytf6kv668r6l6d6cf947mdu38fqyac3q", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwv80xev", - "status": 3, - "tokens": "26461821776", - "delegator_shares": "26461821776.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.157167562506066789", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.091234306987583436" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpgrdlt7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwudpuh36geydlpx0yjqu0vhauacf294sn2uetg4ush97p382kqag6sxlqg", - "status": 3, - "tokens": "17862559018", - "delegator_shares": "17862559018.000000000000000000", - "description": { - "moniker": "wSgJTwBWiv", - "identity": "AEATmOIHsP", - "website": "WsuxwwJUIx", - "security_contact": "nzWdiJbKcf", - "details": "WXwvQKoIbT" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.120000000000000000", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.027292850423387945" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dn2s4tgdyjcgpcq6pfw5shzry50veuh8ctnfwe", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq4e58fv", - "status": 3, - "tokens": "112536605413", - "delegator_shares": "112536605413.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.592057337572123856", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.208226705977271974" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dkwuxswrh5mx3mmmsny2qhwm4xtu33ty8c2klg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7kquya74", - "status": 3, - "tokens": "27525740131", - "delegator_shares": "27525740131.000000000000000000", - "description": { - "moniker": "ajDNnhnkbN", - "identity": "nkdfsqWVlx", - "website": "CeqAfYeTdW", - "security_contact": "KMQJbxKkbm", - "details": "cvAUuqNFYs" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.780000000000000000", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.550890306122411684" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lp4dgp7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj4x3m9h", - "status": 3, - "tokens": "57637848348", - "delegator_shares": "57637848348.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.081821299211443922", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.458576374327765136" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1dle2tkls5kffwdqhan4rs0dgckjxunfscuve6j", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey2vtdvu", - "status": 3, - "tokens": "19834101875", - "delegator_shares": "19834101875.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.491522368582129610", - "max_rate": "0.900000000000000000", - "max_change_rate": "0.085253529277298261" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wzmzdml4fsakuyukmaa6qqee3g6w6qtc9r38wn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0aa00frx8hxrq5pegc0vnt69pj54z3dhwzy8uumr3nhgsc772h0zyr473p", - "status": 3, - "tokens": "37175356106", - "delegator_shares": "37175356106.000000000000000000", - "description": { - "moniker": "oedtWfExZY", - "identity": "taFwTdIwwz", - "website": "oGBHKapVuy", - "security_contact": "hnggEiQcYu", - "details": "qOFIRfzDGP" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083784124252551147", - "max_rate": "0.650000000000000000", - "max_change_rate": "0.550897578676987786" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wr9032gj6t9s9schc5vnwe9kkee7qkgp0wau8a", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dsktaxw5", - "status": 3, - "tokens": "55634424696", - "delegator_shares": "55634424696.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.016380613584719475", - "max_rate": "0.310000000000000000", - "max_change_rate": "0.310000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wr3nyvxgsdrfcadp9f97m5fsj5f0ey560wqf0p", - "consensus_pubkey": "cosmosvalconspub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz28vhtm", - "status": 3, - "tokens": "20453193314", - "delegator_shares": "20453193314.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.680000000000000000", - "max_change_rate": "0.528106308050967540" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wnn8xrn46u6ryq4kqf7tcf650fe2gl57g9uaar", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqehts4m", - "status": 3, - "tokens": "52558464763", - "delegator_shares": "52558464763.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.128525196978986815", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.100900376719373255" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3vs972n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru72w0xm", - "status": 3, - "tokens": "18560827275", - "delegator_shares": "18560827275.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.100218404029226728", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.881639682871578638" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10qj9cj3dxecyu826gaw72ylwum96jkkhq4p0xn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq00qxpqlwy0p6y9tl23yu7fpu55lhznxa3hrhvsuma6h7lu4c3ekks4wvua", - "status": 3, - "tokens": "22083357722", - "delegator_shares": "22083357722.000000000000000000", - "description": { - "moniker": "LvOuePvVwo", - "identity": "vfegdQlOfT", - "website": "mYvkvMZuDp", - "security_contact": "cfrddDLOlu", - "details": "yHfcxdGyEO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.122593865256918850", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.840000000000000000" - }, - "update_time": "9935-12-31T21:25:29Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10gu52rf3d0z0py8d0x37r058qh9fgdgg3qwtz7", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxkm9kvvp", - "status": 3, - "tokens": "26763354026", - "delegator_shares": "26763354026.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.027810962515737967", - "max_rate": "0.070000000000000000", - "max_change_rate": "0.034717076557320762" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper10t3ld5fvsvy7kye7p409he8dk5q23tep308jmp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdpwvxyz0d0thr5hw72lswav4tdfuwkgfqjdjkaws99y4dw5fzncg487kz6", - "status": 3, - "tokens": "25943967606", - "delegator_shares": "25943967606.000000000000000000", - "description": { - "moniker": "anqFIENyYy", - "identity": "LYtCTmovif", - "website": "nDcnuLjZla", - "security_contact": "KhBXWuJORy", - "details": "rcnhuNfFoO" - }, - "unbonding_height": "13", - "unbonding_time": "9936-01-01T19:46:26Z", - "commission": { - "commission_rates": { - "rate": "0.489033782311246085", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.501117175906227815" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sp9hxsl3s8pyj3cs84acgwrkxl85yk886g8y9l", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvykaseh7", - "status": 3, - "tokens": "68955304480", - "delegator_shares": "68955304480.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.208925360976246176", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.463634503057540350" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sxmqgulmqw6nxw4f9lxt565hzyj246nj32gmtp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peggwy7x5", - "status": 3, - "tokens": "49844884060", - "delegator_shares": "49844884060.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.338644152469426553", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.069153802725768656" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s28wuj4yrqsmjm2cckx6mu037e92up2m7azx22", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxz2ead4", - "status": 3, - "tokens": "19233426986", - "delegator_shares": "19233426986.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.373154376676147691", - "max_rate": "0.980000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s30d8tgwhwavwtvanggkj92quj8ucecy5v3wwd", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wjfqd63", - "status": 3, - "tokens": "25961659072", - "delegator_shares": "25961659072.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.068613373696134985", - "max_rate": "0.080000000000000000", - "max_change_rate": "0.073351676068018235" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1sjhhg2yl2cqszte7pjyrp6lx5tg383lryxs4rg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7ul2hc3", - "status": 3, - "tokens": "33320443806", - "delegator_shares": "33320443806.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118849597906926326", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.228258187539755185" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1s6sl7pyvn33lptf7edmux0gex06ffzjznvetnz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7whvstg", - "status": 3, - "tokens": "59094460259", - "delegator_shares": "59094460259.000000000000000000", - "description": { - "moniker": "cVUXvMdRgs", - "identity": "AHkjmtOkYK", - "website": "KLRPQOyDoY", - "security_contact": "VHwCrfhVnI", - "details": "qdFVvUucvR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.182731553781057822", - "max_rate": "0.270000000000000000", - "max_change_rate": "0.045316794895420248" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13yzpngckxvtky2k25j60qxlkekx0jfaus4xzwq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqde6g57cex9ff650ku6dqdqtfulfnzkacecf6k436xl0dd07zglxx5659h9", - "status": 3, - "tokens": "27718687960", - "delegator_shares": "27718687960.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.905848795661145449", - "max_rate": "0.950000000000000000", - "max_change_rate": "0.476775855507110704" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13y2zjpgaj07umx7a3dsg9ffhpkk22g73s372cz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy7220f9ul3", - "status": 3, - "tokens": "33772482275", - "delegator_shares": "33772482275.000000000000000000", - "description": { - "moniker": "znFMdpLOQw", - "identity": "LEMEnpcxqp", - "website": "TjKmeKjDGm", - "security_contact": "ZOXcBhlDyq", - "details": "WpmmnksSqL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.834910862331446014", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper138ueargdn7h3qhwdpvusu9uduacvm393susy5r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cuyxrn7n", - "status": 3, - "tokens": "24587685968", - "delegator_shares": "24587685968.000000000000000000", - "description": { - "moniker": "tlYEYvdvKp", - "identity": "fQFtYLRSZA", - "website": "ecuAofwdaj", - "security_contact": "gwsuBeDyJU", - "details": "gELFJGuwPs" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.499259642246008210", - "max_rate": "0.560000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13fyamuv3fexmuuamtgqtwkz48ynl3hd5xmgrmx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jet5tg3", - "status": 3, - "tokens": "62232444428", - "delegator_shares": "62232444428.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.153116543667039838", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.230000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13fvz5er8rdttgtuwvcuaku00j2nw2v6kuvjvmp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yfudg7m", - "status": 3, - "tokens": "25948607110", - "delegator_shares": "25948607110.000000000000000000", - "description": { - "moniker": "IssGiFwTJv", - "identity": "VgTaqmOLtN", - "website": "BpkICmEqwF", - "security_contact": "qmrIWxiWft", - "details": "sLtbcsMFgA" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.136694009459855954", - "max_rate": "0.140000000000000000", - "max_change_rate": "0.056116480834729575" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13296rs6uwadjwya2l2uc2jzxgyllcjm2yvuchw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4c8wkdlg", - "status": 3, - "tokens": "18426946099", - "delegator_shares": "18426946099.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.469814499540087620", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.960000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13tfk4n07c9dz5swkw7vafmlrd9e0d28ff26zyw", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvquc4jf3", - "status": 3, - "tokens": "16774945156", - "delegator_shares": "16774945156.000000000000000000", - "description": { - "moniker": "hZvyDgtWxX", - "identity": "TPMmELNQYL", - "website": "YxTdbJnobM", - "security_contact": "ZURHxVMZoL", - "details": "zVjWraUVyE" - }, - "unbonding_height": "7", - "unbonding_time": "9936-01-01T06:43:57Z", - "commission": { - "commission_rates": { - "rate": "0.258972799025106506", - "max_rate": "0.910000000000000000", - "max_change_rate": "0.304259315697044502" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1333066cp52k7fgmug2dwylafnymdxcg6kptv4r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprs83zeag", - "status": 3, - "tokens": "32156167120", - "delegator_shares": "32156167120.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.351977697440288211" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13jxw6xalnpvapujvmm6mc6qn3dk4sn6kl60adg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvly6j0pyezy88s9lnat6taglylzq03vvsvyw4uy2tv3vcl3200ej0nev4k", - "status": 3, - "tokens": "16811362128", - "delegator_shares": "16811362128.000000000000000000", - "description": { - "moniker": "lasYiVeRDA", - "identity": "TFiGxJBNUs", - "website": "xswbDClAxs", - "security_contact": "HYUurzqzcC", - "details": "EVSfzEFSuo" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.036542719943188247", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.304756516958654494" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13nemj0k45u4pflkfeyey88n8u8sv4wgzzvalcz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66dra0w3", - "status": 3, - "tokens": "19540440011", - "delegator_shares": "19540440011.000000000000000000", - "description": {}, - "unbonding_height": "12", - "unbonding_time": "9936-01-01T17:01:39Z", - "commission": { - "commission_rates": { - "rate": "0.065303820000927065", - "max_rate": "0.160000000000000000", - "max_change_rate": "0.134868108685582589" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13cydnwjmscxtqtjywk9atr9uwlm6703mtlsdls", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afqga9sv8", - "status": 3, - "tokens": "33258307031", - "delegator_shares": "33258307031.000000000000000000", - "description": { - "moniker": "uVtPIVoLeB", - "identity": "UQUjtBkUkU", - "website": "lrfjDXnSyH", - "security_contact": "tPWaAehpKA", - "details": "YCcmQgJRnO" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.859185512301348293", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.915098787337318307" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper13mztfedkzpz634g7u5fh8henfmvzyrfftadlta", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrq06r4ck", - "status": 3, - "tokens": "41543247193", - "delegator_shares": "41543247193.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.119695944592116460" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jqkfaju29z0270cmm4zhygtzwjcuqjzx37xfwu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4vjajc6x", - "status": 3, - "tokens": "61843733534", - "delegator_shares": "61843733534.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.437478542817284441", - "max_rate": "0.530000000000000000", - "max_change_rate": "0.308410375933996023" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jp0tqhr79uwqt2rh66vcd378rrhslg49gacdfq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvghhzrgz", - "status": 3, - "tokens": "36037299066", - "delegator_shares": "36037299066.000000000000000000", - "description": { - "moniker": "rUZvoFLmub", - "identity": "dQGYIJXPFq", - "website": "ZPoXnJmgzU", - "security_contact": "MdbwPJFNHC", - "details": "NdoQBlpUhN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.670000000000000000", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.629855974067904060" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1jsd99e3zfrxrr3nh057u0tvmu0847zkr03altl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz4luxgn", - "status": 3, - "tokens": "33206633235", - "delegator_shares": "33206633235.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.229284159886860129", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.212917450108859841" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0cxr45d", - "consensus_pubkey": "cosmosvalconspub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw24c76ax", - "status": 3, - "tokens": "27567655084", - "delegator_shares": "27567655084.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.216560651737526756", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.026445047137608599" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1j7352v6z3xcf9y5qusgdxectvn8dv962red0gt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qpu7x5c", - "status": 3, - "tokens": "27671960609", - "delegator_shares": "27671960609.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.077841535313299819", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.054979434313866047" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nz5hp6p6wn4fvnaxe9x6fq35daamxvhhw32kd2", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2wcjjal", - "status": 3, - "tokens": "25069342080", - "delegator_shares": "25069342080.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.249161816461641720", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.693944288516379645" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nrugh7am9s584k6qlf5nxlpetarxs2csdtlqka", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akutfqm7", - "status": 3, - "tokens": "55737096951", - "delegator_shares": "55737096951.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.498362112747574396", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.645641814068879323" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nraptt0aagws66pcvnc92kjus460k3l03aezej", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693hazjkkehy", - "status": 3, - "tokens": "33054734644", - "delegator_shares": "33054734644.000000000000000000", - "description": { - "moniker": "mUQFKtnPLD", - "identity": "xsxoaAIVkh", - "website": "EBARfZhhON", - "security_contact": "GynbBFtcRq", - "details": "RftDCeMUPi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.123876475355091478", - "max_rate": "0.860000000000000000", - "max_change_rate": "0.141162753552435345" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9dqelmmf5kfysk24m6chqfdcgz6r75um04fzy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v30nmws", - "status": 3, - "tokens": "78601464028", - "delegator_shares": "78601464028.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083731202536014652", - "max_rate": "0.860000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y50grnvf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9ykjrzn93", - "status": 3, - "tokens": "18090212819", - "delegator_shares": "18090212819.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.081582427988342735", - "max_rate": "0.120000000000000000", - "max_change_rate": "0.086390137368972014" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n9lefg5g0mz4glppdt994nsxzg6pxscq7ujazn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06my86wxz2", - "status": 3, - "tokens": "33968139195", - "delegator_shares": "33968139195.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.247483015769197525", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.837420192496215212" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nxr7alffy7zt9gg4285a67ts977pcgaahsdryv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtufvzu2k2knnce8l9jcwuntray9m8hnlal8a4jkcjazppr5p7pyus6emm0", - "status": 3, - "tokens": "19857350032", - "delegator_shares": "19857350032.000000000000000000", - "description": { - "moniker": "PfGefIRkUQ", - "identity": "PQNdBVtoxj", - "website": "nyfnvHyjNl", - "security_contact": "ewMiIvfvCh", - "details": "ttKmCVgWXS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.239149115387739677", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.173620767408899960" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n8emgp25g5wh4d9204lpd06gsznurtlpguk387", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv9w0yqrekktvu6gd7ak8u7wkwqj47llgrtl2vp2gtdvfafwatyysclj3nm", - "status": 3, - "tokens": "23726914937", - "delegator_shares": "23726914937.000000000000000000", - "description": {}, - "unbonding_height": "47", - "unbonding_time": "9936-01-04T16:25:11Z", - "commission": { - "commission_rates": { - "rate": "0.522454157166611225", - "max_rate": "0.820000000000000000", - "max_change_rate": "0.329662780053528069" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ng5m6spxngyne4qzce35fdg0whl0yqgvqtus8c", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2crvswax", - "status": 3, - "tokens": "16516288319", - "delegator_shares": "16516288319.000000000000000000", - "description": { - "moniker": "kVNZIBYAxD", - "identity": "ChbsAFHanI", - "website": "SvHMthzzzB", - "security_contact": "cMJXUgGCfx", - "details": "PWsrYNKuPZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.540000000000000000", - "max_rate": "0.540000000000000000", - "max_change_rate": "0.491525012965837080" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ng7vpl5wh98pshfef327gfnzyrwh6z4en5fed6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2kj4krx", - "status": 3, - "tokens": "45010236382", - "delegator_shares": "45010236382.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.095070637134115497" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nfurwjwfy3zhw0g9eqcclzeejf9nqw62dagjgz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveesw5rr6m", - "status": 3, - "tokens": "54768547781", - "delegator_shares": "54768547781.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.328146514360581742", - "max_rate": "0.810000000000000000", - "max_change_rate": "0.166428198995593213" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n08duqdkxwmqmtjaha236esw6r72njd2jhu4hf", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68yqxsxnt", - "status": 3, - "tokens": "25326342688", - "delegator_shares": "25326342688.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.785486462764506620", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.356882054361860100" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1n5n6d47c4ntac509rtq3s620vmcqcf97sm9sjc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzlcd6kj", - "status": 3, - "tokens": "67804970220", - "delegator_shares": "67804970220.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.264013069771684883" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1nas3l2avd9hymfeqznjmrw7sde8ual5kq68tqr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4v8fm8e8", - "status": 3, - "tokens": "41964454098", - "delegator_shares": "41964454098.000000000000000000", - "description": { - "moniker": "LDEzyylLGV", - "identity": "NaLpENvFnX", - "website": "ooOcvgIJwr", - "security_contact": "aQaxAlCyFx", - "details": "CxEFcmLmkI" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.099339754970547702", - "max_rate": "0.320000000000000000", - "max_change_rate": "0.111217397607280422" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15zqzxj663h8g8naxyz324j2rpd3rnw4rfljvde", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k907nvf", - "status": 3, - "tokens": "28676349495", - "delegator_shares": "28676349495.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.609184993023386704", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.699887495531371188" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15tf0n2rqlh49324hrn0vzmj33fr7yk9txruqdt", - "consensus_pubkey": "cosmosvalconspub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjtszrqs", - "status": 3, - "tokens": "34574952843", - "delegator_shares": "34574952843.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.810000000000000000", - "max_rate": "0.810000000000000000", - "max_change_rate": "0.810000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15dt0e900x5cv9w870mevztqwy88hhu2sl54t25", - "consensus_pubkey": "cosmosvalconspub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku73m9m0", - "status": 3, - "tokens": "16992076248", - "delegator_shares": "16992076248.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.406968367525101581", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.487609794856186092" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15jcgjq7sc62rj4s0dlm4sapdcgw06jfusryxkp", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfcdg0aax", - "status": 3, - "tokens": "16967510024", - "delegator_shares": "16967510024.000000000000000000", - "description": { - "moniker": "YKKhjZGayb", - "identity": "IvgiPDjmYA", - "website": "gScrUtVzvh", - "security_contact": "kGHySpHXgu", - "details": "IyuehlcoPM" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.093407705950029411", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.187465926844434813" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper155znzxm9g8j53k8vyp2d5qmrkzdum4d0feq2xu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7zgmra8", - "status": 3, - "tokens": "26261718579", - "delegator_shares": "26261718579.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.210000000000000000", - "max_change_rate": "0.067309904771533509" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1557a6swa3yv3ew9yk8hcfpyqu3ce7te0e0wrqz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqnavslf", - "status": 3, - "tokens": "46127605035", - "delegator_shares": "46127605035.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.895728278286976959", - "max_rate": "0.920000000000000000", - "max_change_rate": "0.140752130806369269" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper154epq0mwqz393frj38lh265h9slwdynm69h6vy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jyyn3gu", - "status": 3, - "tokens": "22487156484", - "delegator_shares": "22487156484.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.008115100503323252", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15cnzrhl4pe7ekkp0djmyupahdsjjmmkvmn5n4c", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yagkfrr", - "status": 3, - "tokens": "39560123415", - "delegator_shares": "39560123415.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.060188716749386269", - "max_rate": "0.350000000000000000", - "max_change_rate": "0.350000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15a8hadw3wttrnr3qx37ewmzre4w7cjmtzz04rs", - "consensus_pubkey": "cosmosvalconspub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kwmez9k", - "status": 3, - "tokens": "16420725988", - "delegator_shares": "16420725988.000000000000000000", - "description": { - "moniker": "LVfceOUKZE", - "identity": "ZyVUuaCAJZ", - "website": "rliAdTPvEK", - "security_contact": "hVtZPHOsKh", - "details": "QjmMKruCba" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.230000000000000000", - "max_change_rate": "0.036920301680485403" - }, - "update_time": "9936-01-01T16:55:11Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper15772l3g3u9kk2qk5cmsl8tr6lshgd443vlchzj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq77rpqn", - "status": 3, - "tokens": "26062927309", - "delegator_shares": "26062927309.000000000000000000", - "description": { - "moniker": "BFoqLaJLDn", - "identity": "weLorPCgTe", - "website": "oyhVcpSOLq", - "security_contact": "hdnvhDJTDC", - "details": "SAZISvvmwB" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.160832184115355939", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14qy520rhr0qytqxdtsjsu9rgw708n2w6d4ewhn", - "consensus_pubkey": "cosmosvalconspub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xw03emk4", - "status": 3, - "tokens": "44313010729", - "delegator_shares": "44313010729.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.083856723472306849", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.569378562223247850" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14q9rupnazu0mmkjd9skpn2zdfs8d0hlgjk4rrl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6yp7zp3n", - "status": 3, - "tokens": "25164533156", - "delegator_shares": "25164533156.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.330000000000000000", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.314039829028852779" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14dp6lpg8dqs4e0aq34vhcwpxt37nltefhean9h", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvn899z9u9a7h28682292n9y77yr6yuyrg2xvg8eaammccqfuc9e5jp63vn", - "status": 3, - "tokens": "16985369823", - "delegator_shares": "16985369823.000000000000000000", - "description": { - "moniker": "oVMoJSrGgV", - "identity": "ydZuwvoyLe", - "website": "EdyJLNhNGZ", - "security_contact": "QauDavDNuL", - "details": "CVkbnFlumN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.276325858271560152", - "max_rate": "0.600000000000000000", - "max_change_rate": "0.108166159043578444" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14jvurctjcvs69hlppa0dkjplczns7zlqlysqq9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwshp63n", - "status": 3, - "tokens": "25367511082", - "delegator_shares": "25367511082.000000000000000000", - "description": { - "moniker": "KODmaZYfBO", - "identity": "dQoWoZcHpD", - "website": "QRjjuYKVNR", - "security_contact": "BHWzdORGfc", - "details": "dZGTxQmqIN" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003392332242825811", - "max_rate": "0.060000000000000000", - "max_change_rate": "0.027187395396712775" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14j4mehgc448s2m7cr0uqm3pmvjxav94w75n6zx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqv0lje47", - "status": 3, - "tokens": "54901950842", - "delegator_shares": "54901950842.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.193375046872051394", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.161750559623523660" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14kdxam68sthcd72526kc5ea42hfq5c2gf8lerx", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc9m7uvt", - "status": 3, - "tokens": "15374405822", - "delegator_shares": "15374405820.680335249007925874", - "description": { - "moniker": "eomlzRaIRN", - "identity": "PaBTVBXpcj", - "website": "frMwzGwrdS", - "security_contact": "XwCgZGftYO", - "details": "oynChhccDw" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.014913519812752309", - "max_rate": "0.330000000000000000", - "max_change_rate": "0.219118316904950121" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper14e68cy8rvnmva3fzvhmq67m94zffpvntmkldpc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7dsh8mr", - "status": 3, - "tokens": "31376033263", - "delegator_shares": "31376033263.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.074914975922116628" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper147pq4rzswl76kdeyx8sc7pagf4nhjpnq0rtkmz", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axhh8p8f", - "status": 3, - "tokens": "49683234188", - "delegator_shares": "49683234188.000000000000000000", - "description": { - "moniker": "MJAduJwrkS", - "identity": "YpKMJsMpdh", - "website": "rmUXbHIGjh", - "security_contact": "KxyJSeDEJS", - "details": "gQmDpfNyLZ" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.637063248045666486", - "max_rate": "0.800000000000000000", - "max_change_rate": "0.100218674012239339" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1478sx3zdfylsts5sus5rlz4dgvyvacqpevr8k6", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmkm3zs42", - "status": 3, - "tokens": "34289428306", - "delegator_shares": "34289428306.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.026475742223507385", - "max_rate": "0.040000000000000000", - "max_change_rate": "0.008016543161851368" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kz20p7j939s8cqadmqqws80c6z93qdtydnj7rl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw3fj2ga", - "status": 3, - "tokens": "29885998584", - "delegator_shares": "29885998584.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.208832068199199828", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.835848953294536000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kfnt5d5fcma9kh4c5jk85yu75jer72kwgtlaer", - "consensus_pubkey": "cosmosvalconspub1addwnpepqv7nw49k6j8sg6379dy0lemj7vee2el49mt5rmypwujwk6lua8duyrr8zrn", - "status": 3, - "tokens": "21181468286", - "delegator_shares": "21181468286.000000000000000000", - "description": { - "moniker": "TgLltHAWtO", - "identity": "zpriAAvZuw", - "website": "pWVJnIqFBY", - "security_contact": "TyuWOjmMFF", - "details": "CbbpwkidBS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.237822850366335221", - "max_rate": "0.300000000000000000", - "max_change_rate": "0.134613352727411591" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ktnuvrm3q8h30y3k70yzvmvwme77e9yyvq8pzm", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2vncgld", - "status": 3, - "tokens": "39430946332", - "delegator_shares": "39430946332.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.400358972669819604", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.343431675789315867" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k0z97vlulcmdrrajhms2x9k8srvtmxwu3vu8mu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrywn9e6w", - "status": 3, - "tokens": "32328037984", - "delegator_shares": "32328037984.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.039339062684741866", - "max_rate": "0.150000000000000000", - "max_change_rate": "0.021256256594527078" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlcglmgu", - "consensus_pubkey": "cosmosvalconspub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus2udpwh", - "status": 3, - "tokens": "15813863385", - "delegator_shares": "15813863385.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.543747468021249371", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.392045382869085556" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1kses5l7n9382eay7524cmut5p7en64ldsv3wzt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwujx3ap2", - "status": 3, - "tokens": "25957780472", - "delegator_shares": "25957780472.000000000000000000", - "description": { - "moniker": "hoLpIoNUFo", - "identity": "LCpoujNFyW", - "website": "AOTlTXjPul", - "security_contact": "elgNvDzEfH", - "details": "hwOSWkTDMH" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.347272379813626146", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1k7dl7gc3umxp45u8m8zc6evvus2gvjvcfmrynz", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9ugfdlq9", - "status": 3, - "tokens": "45284218868", - "delegator_shares": "45284218868.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.340626334815374555", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hpwfm40p8dwmwtmhdnmazywy79uywk8xj4kyyy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkxmnmkq", - "status": 3, - "tokens": "44505127913", - "delegator_shares": "44505127913.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.605944631117636209", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.639343774657574630" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a2ywgwl", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqk8ct27q", - "status": 3, - "tokens": "22456561633", - "delegator_shares": "22456561633.000000000000000000", - "description": { - "moniker": "DPTpRIdXgW", - "identity": "qysDMlMxpi", - "website": "xWbmLVlZvB", - "security_contact": "QtpKTducMv", - "details": "UWYfFdNOxg" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.057271144965717909", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.075138495309274904" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc3prljj", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd7u4d80m4e6sfhyzj84k6y34v30g9cstzx7cmrazvxdtfe40urcvran9t8", - "status": 3, - "tokens": "45811135531", - "delegator_shares": "45811135531.000000000000000000", - "description": { - "moniker": "zcPImZiDZD", - "identity": "zkcTihefFl", - "website": "mIjAaWRNkf", - "security_contact": "gTafXNexkI", - "details": "tJJDPwaiAf" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.079222020883406460", - "max_rate": "0.410000000000000000", - "max_change_rate": "0.311112908017536993" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h8wfu2kqcjeev96yddv3nj9r4q003essxellhs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggxauhp0sadc5npdva6f492f3n4a76fldyt3lca6lk36685s624ucakcrh", - "status": 3, - "tokens": "24610359351", - "delegator_shares": "24610359351.000000000000000000", - "description": { - "moniker": "dLwrEevbbD", - "identity": "ubSqqBoPRs", - "website": "MNuXpKVOXc", - "security_contact": "lNXuEDYSJp", - "details": "CvXURllZqF" - }, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.200000000000000000", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.175531415042829217" - }, - "update_time": "9935-12-31T19:49:14Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hsq728kpcxgr77ncj8asxa0383pyx7vq465z8n", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqwclfkt", - "status": 3, - "tokens": "34459325260", - "delegator_shares": "34459325260.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.033986343509044787", - "max_rate": "0.090000000000000000", - "max_change_rate": "0.090000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1h6j4lyvuenmz9m7vq3hler8j7pg5ldpewmjufw", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7t4673v", - "status": 3, - "tokens": "55948291091", - "delegator_shares": "55948291091.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.440048441195653325", - "max_rate": "0.450000000000000000", - "max_change_rate": "0.180789237411591672" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1hu260773mytzz030tuq0kffmlyxzs7vgqa6h6y", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5r4xrdd", - "status": 3, - "tokens": "15675831119", - "delegator_shares": "15675831119.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c2tutqjg5cqcvt6qen2x6enval6t5pydeaqpcc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czwem9y4", - "status": 3, - "tokens": "45487475001", - "delegator_shares": "45487475001.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.177753292751501209", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.323174353688819429" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1cdvntn6mwvvv4qxnty6zp2jwvemg20yu5g7vuc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxe7jutz", - "status": 3, - "tokens": "24261774404", - "delegator_shares": "24261774404.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.017452646416466178", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.020000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1c08mlht3skve88xx8eth4zgtpr2nhjfa6haxvn", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4svau85d", - "status": 3, - "tokens": "31770155824", - "delegator_shares": "31770155824.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.138735148670316454", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.286634953103815529" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1chjcdfygnalpfjrjc8ku8vknx782xf7e0kz768", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf0u600sgl3zdn3uh4jd6jmw6fc0jc40r0l2crvz3sla3f8d32flghwtxaq", - "status": 3, - "tokens": "37602205867", - "delegator_shares": "37602205867.000000000000000000", - "description": { - "moniker": "BUZauhlQrt", - "identity": "yuIKzyGzQS", - "website": "fDSmxAmazc", - "security_contact": "jVDWgXPhkM", - "details": "LBFAwsUoyi" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.244517333363622892", - "max_rate": "0.290000000000000000", - "max_change_rate": "0.153245122134586562" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1e8fdmnscnm6axht542696jupnqlkm40emp2470", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzue70ade", - "status": 3, - "tokens": "37676305948", - "delegator_shares": "37676305948.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.260000000000000000", - "max_rate": "0.260000000000000000", - "max_change_rate": "0.239035612898447459" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3j8kahk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj2sy3f5", - "status": 3, - "tokens": "26850762657", - "delegator_shares": "26850762657.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.420000000000000000", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.295551090875771737" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1evqmj6ahqf76keas4ymhvf4r992kg7wrchmu00", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvhet24yk50y4m60mceffquewu9p4enwrgcum0csceuull7a59u6567nn0v", - "status": 3, - "tokens": "20405570669", - "delegator_shares": "20405570669.000000000000000000", - "description": { - "moniker": "ZeprycSOnc", - "identity": "ZcHuivhMFq", - "website": "hCsVpTWmaL", - "security_contact": "AIKsDuUCDR", - "details": "EgpxVbAOaK" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.054000324644638628", - "max_rate": "0.380000000000000000", - "max_change_rate": "0.120973196882786975" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ekx8n2y3x9qq34c2uy8fdh400hp8msquanm3mc", - "consensus_pubkey": "cosmosvalconspub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6k07476", - "status": 3, - "tokens": "25102040344", - "delegator_shares": "25102040344.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.599184934718890393", - "max_rate": "0.770000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vwtetz0", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgh9lxfuk4amzsp0w28t8dkdwf2xk8yrxjj7xz0lnmzs2lyahrdz2f2yy35", - "status": 3, - "tokens": "17609505538", - "delegator_shares": "17609505538.000000000000000000", - "description": { - "moniker": "yAwjGcNsZH", - "identity": "STCkyPeJjc", - "website": "yvmEPebWkk", - "security_contact": "ZficJLXKJM", - "details": "qAWHtJiitW" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.690000000000000000", - "max_rate": "0.690000000000000000", - "max_change_rate": "0.509977105992119960" - }, - "update_time": "9936-01-01T01:54:53Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1eausepxh2ujd0lpjup9vahjekpz9as2fuqesph", - "consensus_pubkey": "cosmosvalconspub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjycl58l", - "status": 3, - "tokens": "41119826715", - "delegator_shares": "41119826715.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.240000000000000000", - "max_change_rate": "0.025162698699691548" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1elu2xlg8qw8st5nppxvgszeyzhm4ht8zrrvm5g", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75fh3auv", - "status": 3, - "tokens": "19565632897", - "delegator_shares": "19565632897.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.579061375935434182", - "max_rate": "0.780000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16rv5x3545upw3qgemu6kz0cjd36lhvz2zeta3z", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwskjpjy", - "status": 3, - "tokens": "44648874284", - "delegator_shares": "44648874284.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.258140043497759741", - "max_rate": "0.570000000000000000", - "max_change_rate": "0.447039357737510640" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16xal57nga5gd2qxkz869qv7hm20xn0rks60vz3", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg57gy4ef", - "status": 3, - "tokens": "34209671267", - "delegator_shares": "34209671267.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.480455308806333346", - "max_rate": "0.710000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16tr72kn90g5zl7qhyhuqkjflejz00uzlntwpup", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55hrcqtd", - "status": 3, - "tokens": "25069342080", - "delegator_shares": "25069342080.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.409558857679769509", - "max_rate": "0.930000000000000000", - "max_change_rate": "0.610998804526507722" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper16v3h2mggt8tnkxp0vq5tq25fhr3knvf4h6p6n8", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0sgshv9mf8qy7ff303mqqv5zppu3q4mcwrnheue8d3kq0ytyynkxlak2ae", - "status": 3, - "tokens": "28980476016", - "delegator_shares": "28980476016.000000000000000000", - "description": { - "moniker": "hVYOUraqpo", - "identity": "XRliNUdYgt", - "website": "FYzwRNeFsW", - "security_contact": "AYYtrdbBmx", - "details": "NaWAwUYhir" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.940000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "9935-12-31T23:32:57Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mqg9gtapd36mwxqk43gpqjh7h8f5cq5w6yhzqg", - "consensus_pubkey": "cosmosvalconspub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxd2wcms", - "status": 3, - "tokens": "27742737411", - "delegator_shares": "27742737411.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.870000000000000000", - "max_rate": "0.870000000000000000", - "max_change_rate": "0.402061609548054151" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m8gpgklc8a2yla9ah9y8mlu226n0mu4y0zn3wc", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2x30aum6t8lauwqh72szktjx6fmgf5ux7vcs38uukp9a5h287wawhv5mfv", - "status": 3, - "tokens": "17377751306", - "delegator_shares": "17377751306.000000000000000000", - "description": { - "moniker": "SslqJkEqrN", - "identity": "qMdXPqvbCt", - "website": "HDwwjWlugU", - "security_contact": "LzWMObthwF", - "details": "zlyoRqwOQS" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.498765541593724538", - "max_rate": "0.530000000000000000", - "max_change_rate": "0.156108348646223859" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mfldj5ly78eg08sd2k3nygggjx765vvwhzrpxa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3lu0qw8kj", - "status": 3, - "tokens": "25431851328", - "delegator_shares": "25431851328.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.450461328836777178", - "max_rate": "0.840000000000000000", - "max_change_rate": "0.254665389885134513" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mdes9dapqu6vr094qc6wyhd9jt7qfwvj08tczs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcf30j9c", - "status": 3, - "tokens": "74690344989", - "delegator_shares": "74690344989.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.882630947578979215", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.960000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mh9g99ncua6cecyd5meepx9hecyy3e24sds9gy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr2mqfkju", - "status": 3, - "tokens": "27874325464", - "delegator_shares": "27874325464.000000000000000000", - "description": {}, - "unbonding_height": "1", - "unbonding_time": "9935-12-31T19:10:44Z", - "commission": { - "commission_rates": { - "rate": "0.459241580368376871", - "max_rate": "0.490000000000000000", - "max_change_rate": "0.448990769658695281" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mcvztyynwvn7lelqx89xuzzuguhx5xm7grvfsj", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngklt9fqt", - "status": 3, - "tokens": "68086107574", - "delegator_shares": "68086107574.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.280411773058535090", - "max_rate": "0.880000000000000000", - "max_change_rate": "0.009358685901125498" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjaz8hul", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdq8fheeu", - "status": 3, - "tokens": "25446232136", - "delegator_shares": "25446232136.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.073669961838812257", - "max_rate": "0.340000000000000000", - "max_change_rate": "0.338443455873010612" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1mmjkdjsqluxlggcl082j977kv8fwp4u04x6vm3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdjuv3ql5rv5njym62quduw7554as4aa8seufp7f4zv6q28tds2e23v4cv5", - "status": 3, - "tokens": "35741739231", - "delegator_shares": "35741739231.000000000000000000", - "description": { - "moniker": "MoJgIrbTvT", - "identity": "rTfyDjhPlV", - "website": "fXpRItnlwS", - "security_contact": "tIlMCZPLDi", - "details": "QoSUrnFXNb" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.037606710200997532", - "max_rate": "0.610000000000000000", - "max_change_rate": "0.432717335122536998" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1up7x3srs54xhq897rlda86hdsf4sy7ncd3zz7j", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwvhpfht", - "status": 3, - "tokens": "19637280062", - "delegator_shares": "19637280062.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.118259925415637398", - "max_rate": "0.220000000000000000", - "max_change_rate": "0.176572964585642890" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1uuk9ewj0532rzlhlg86tserdxvtnm3kq0z7hza", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwaazwez", - "status": 3, - "tokens": "56856814851", - "delegator_shares": "56856814851.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.093189165744722643", - "max_rate": "0.250000000000000000", - "max_change_rate": "0.044880981942823250" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1adwsqn58aype530jae9qrwknsxyf3wmwghqla3", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyvxmu04", - "status": 3, - "tokens": "36122807193", - "delegator_shares": "36122807193.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.414145633705698803", - "max_rate": "0.500000000000000000", - "max_change_rate": "0.500000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1awq0hzrn6zckeq5y6xfgj7vyfcjtd0uxm6lx09", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd2gmrd8aux64z50e58tu00n3yjunvqduf4xv3g3p6j3wpuxddex59mpcfe", - "status": 3, - "tokens": "16807158123", - "delegator_shares": "16807158123.000000000000000000", - "description": { - "moniker": "ZHKMxyLBmy", - "identity": "EwvvJnavFX", - "website": "DHXlVcQLfr", - "security_contact": "cqkJGwinbb", - "details": "CwxLKqsDci" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.054776212220005616", - "max_rate": "0.370000000000000000", - "max_change_rate": "0.012318363733558931" - }, - "update_time": "9936-01-04T13:24:43Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1awyus34e6laq3zxqsrv283w6fgn8w62zn6ejj7", - "consensus_pubkey": "cosmosvalconspub1addwnpepq2p3sa8dkvz36pz6nusjdhm9aqlnrrldrszzuqd5qy7ssqztn99ggqpcdlz", - "status": 3, - "tokens": "48540826744", - "delegator_shares": "48540826744.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.003549575739989554", - "max_rate": "0.020000000000000000", - "max_change_rate": "0.001119527935415439" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1a0jdqzvk078d6486vuxdr5d0yp6rglue08rppq", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycjhwrn7", - "status": 3, - "tokens": "29401856985", - "delegator_shares": "29401856985.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.243341366114153903", - "max_rate": "0.670000000000000000", - "max_change_rate": "0.628404054381210058" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1a4nlyf59n25qmh4myas5mdunvu9r4wlsa6vfrk", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdaa2szanfjwhzucqfj0ct7ljhc3kew8am3h8sr8wqzlnh8df06g5th460y", - "status": 3, - "tokens": "24697024268", - "delegator_shares": "24697024268.000000000000000000", - "description": { - "moniker": "XYWZXrqRDE", - "identity": "MFgElwSSlb", - "website": "ZPGkarWAml", - "security_contact": "dFzxEZXTfo", - "details": "HRGbXKBEeq" - }, - "unbonding_height": "4", - "unbonding_time": "9936-01-01T00:38:18Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.550000000000000000", - "max_change_rate": "0.376530136432859216" - }, - "update_time": "9935-12-31T16:20:47Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17qavkakyqgh62k39frjf5v9pj0c78m2df9rn3y", - "consensus_pubkey": "cosmosvalconspub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w4r0vhq", - "status": 3, - "tokens": "41494205421", - "delegator_shares": "41494205421.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.000000000000000000", - "max_rate": "0.070000000000000000", - "max_change_rate": "0.000000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper179uxhryqvrkxa2wtnw2cnptdt80qc24kzrgen9", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgc0dahup", - "status": 3, - "tokens": "54450506134", - "delegator_shares": "54450506134.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.109747630034489371", - "max_rate": "0.970000000000000000", - "max_change_rate": "0.461346401411912639" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper178pm30fcgrt5654czwr8nlex050m6y60qutnxr", - "consensus_pubkey": "cosmosvalconspub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkn6paax", - "status": 3, - "tokens": "23703504292", - "delegator_shares": "23703504292.000000000000000000", - "description": { - "moniker": "eXfwGKuzGb", - "identity": "dYpMrjwrPA", - "website": "DzaFOsditE", - "security_contact": "GuNLPoNZsM", - "details": "iALsKeROvR" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.087538799057934086", - "max_rate": "0.960000000000000000", - "max_change_rate": "0.859363741701174499" - }, - "update_time": "9936-01-01T04:09:39Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper178gvnxtnq2n4m23492m7agshjv3zgzy3k3mfjv", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyt542en", - "status": 3, - "tokens": "69725274862", - "delegator_shares": "69725274862.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.077835183941357357", - "max_rate": "0.630000000000000000", - "max_change_rate": "0.287966636331923139" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17gpy6jzg7xdsr2xc7kweljagx4uaysxdn77qem", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwfq28wcw9gn3mynr4pjdpd5hhert9hheg8qus862ymrt5ex6j75jlkuhe3", - "status": 3, - "tokens": "21764467799", - "delegator_shares": "21764467799.000000000000000000", - "description": { - "moniker": "ObWwGUpRaY", - "identity": "BCfhwnVexY", - "website": "SBehiPUtRR", - "security_contact": "jMhyvuyFaP", - "details": "LHYAZFxdaS" - }, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.075332177620667120", - "max_rate": "0.100000000000000000", - "max_change_rate": "0.039077923270826524" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper172lmu2psqlkxkthpr46h2ewjffte7lhl76d08m", - "consensus_pubkey": "cosmosvalconspub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsrp7s99", - "status": 3, - "tokens": "25229713771", - "delegator_shares": "25229713771.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.420000000000000000", - "max_rate": "0.420000000000000000", - "max_change_rate": "0.006473324874363207" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1707yw2jgerkawrdyylsj4vll8k2ww5evxg4ycu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd5jsj53j7m0umzvh90dwanxhfxmpydhfazmsz978v9yuh05q0kxcyqtdla", - "status": 3, - "tokens": "16747268503", - "delegator_shares": "16747268503.000000000000000000", - "description": { - "moniker": "OuShqctNnC", - "identity": "MfQbnbeXdv", - "website": "OfOpteXCQn", - "security_contact": "qaSLhJmnUG", - "details": "vIuRzAnYuu" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.589668369513377579", - "max_rate": "0.640000000000000000", - "max_change_rate": "0.640000000000000000" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17nckqnw09secacg9y6r7pay02nhemww639rr4s", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge726q0dwq", - "status": 3, - "tokens": "56914095343", - "delegator_shares": "56914095343.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.561558403350280399", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.088588598076790894" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17er26f88ee6l369a2qk7xmnt248gqtucsqds23", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0us7fav4", - "status": 3, - "tokens": "53587404091", - "delegator_shares": "53587404091.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.148502470554898869", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.005661642347781868" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5n05z3f", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvw32mxlzzzmmpks775cgclcsmypqhhz7765v03wnjf8cn4hsrw67tq2l8n", - "status": 3, - "tokens": "20301516153", - "delegator_shares": "20301516153.000000000000000000", - "description": { - "moniker": "ibdjDFXkFg", - "identity": "BhaqDbDPwH", - "website": "KoHplbnTSd", - "security_contact": "zgJBSepZRt", - "details": "anTLerUmWY" - }, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.092279263137073204", - "max_rate": "0.130000000000000000", - "max_change_rate": "0.062347977318301413" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17uqc5hqs6x7ccr7pcrafp8tfwsezt07ex69gge", - "consensus_pubkey": "cosmosvalconspub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4umtaftt", - "status": 3, - "tokens": "23438430919", - "delegator_shares": "23438430919.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.065104244001935780", - "max_rate": "0.280000000000000000", - "max_change_rate": "0.087973256413395308" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper17uusex4s7mds872wzvkpaty29g02n8etrvze0r", - "consensus_pubkey": "cosmosvalconspub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wu8lrdvr", - "status": 3, - "tokens": "23476663612", - "delegator_shares": "23476663612.000000000000000000", - "description": { - "moniker": "qNlNvDKQWh", - "identity": "PdEEmVXzOP", - "website": "jyQRsxutdI", - "security_contact": "hTNdvfWkVQ", - "details": "gPNrXPrkeL" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.830000000000000000", - "max_rate": "0.830000000000000000", - "max_change_rate": "0.679717803083962746" - }, - "update_time": "9935-12-31T14:21:40Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpnvfqy5", - "consensus_pubkey": "cosmosvalconspub1addwnpepqt7pax9cuqs5vjjvhpmcgvy5dkqrrtrg6336c3xhyrchtegy2m387ccs037", - "status": 3, - "tokens": "19815525788", - "delegator_shares": "19815525788.000000000000000000", - "description": { - "moniker": "sJKzLUYWBq", - "identity": "ZzbWnFqPTq", - "website": "dlevXyAGdk", - "security_contact": "bnQNzwNRYP", - "details": "PaxiDbFCJj" - }, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.291627565410574418", - "max_rate": "0.660000000000000000", - "max_change_rate": "0.017987067010819344" - }, - "update_time": "9936-01-01T12:12:35Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1l2mzrv0nvs75mjj5nzz966jxklfn9wt6t88vzt", - "consensus_pubkey": "cosmosvalconspub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wel7d3l", - "status": 3, - "tokens": "25456865344", - "delegator_shares": "25456865344.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.293848609442759777", - "max_rate": "0.580000000000000000", - "max_change_rate": "0.580000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7azayzu", - "consensus_pubkey": "cosmosvalconspub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6u59lzkg", - "status": 3, - "tokens": "44085124225", - "delegator_shares": "44085124225.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.045106108515206331", - "max_rate": "0.850000000000000000", - "max_change_rate": "0.610987430943531252" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1l5d2lg5hku0m4u8mh866zhjcy2dekpk5qn0jzs", - "consensus_pubkey": "cosmosvalconspub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xvdql9k", - "status": 3, - "tokens": "25311353934", - "delegator_shares": "25311353934.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.324580145668396309", - "max_rate": "0.480000000000000000", - "max_change_rate": "0.480000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1luynvvt3qre3hzald2tdjtah6vw00hdc4xvdps", - "consensus_pubkey": "cosmosvalconspub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujgucg2ktdn", - "status": 3, - "tokens": "32745806516", - "delegator_shares": "32745806516.000000000000000000", - "description": {}, - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.322505571100731689", - "max_rate": "0.520000000000000000", - "max_change_rate": "0.183472725952677048" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1lamxh5pswk923tm9mtmvd4t6pqru5cdtxqs6sa", - "consensus_pubkey": "cosmosvalconspub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592jkkxzm", - "status": 3, - "tokens": "21858111883", - "delegator_shares": "21858111883.000000000000000000", - "description": {}, - "unbonding_height": "2", - "unbonding_time": "9935-12-31T21:09:51Z", - "commission": { - "commission_rates": { - "rate": "0.799310131872627643", - "max_rate": "0.890000000000000000", - "max_change_rate": "0.706235617003159879" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - }, - { - "operator_address": "cosmosvaloper1ll2f2v79ssg5teg5trglr0wecm877apr63lumy", - "consensus_pubkey": "cosmosvalconspub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxtyq8dz", - "status": 3, - "tokens": "28684472849", - "delegator_shares": "28684472849.000000000000000000", - "description": {}, - "unbonding_height": "5", - "unbonding_time": "9936-01-01T02:14:33Z", - "commission": { - "commission_rates": { - "rate": "0.174404138163737710", - "max_rate": "0.360000000000000000", - "max_change_rate": "0.360000000000000000" - }, - "update_time": "1970-01-01T00:00:00Z" - }, - "min_self_delegation": "1" - } - ] - } - ], - "exported": true - }, - "upgrade": {}, - "genutil": { - "gentxs": [] - }, - "auth": { - "params": { - "max_memo_characters": "193", - "tx_sig_limit": "5", - "tx_size_cost_per_byte": "12", - "sig_verify_cost_ed25519": "796", - "sig_verify_cost_secp256k1": "548" - }, - "accounts": [ - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qqxeqqvjkh2ls3a0taukd8rydrqqad690nxkcc", - "public_key": "cosmospub1addwnpepqv7j7mnn8eu00sz64xkvyuhdmfeaz8arvjf2exaptrn2a4wsmkels38sdnz", - "account_number": 109, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1qqexr0y3fxueg3v366ctzlqctexhj5mplmznm4", - "public_key": null, - "account_number": "738", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "11536924691" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383975314" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qqe0t0j86umq0379kjcmjg00yd6ddrdw5l77az", - "public_key": "cosmospub1addwnpepq2clak7n0wuffqrj9ltzxmj7mp8nfd4mupcs2qx8wcntcmqmrhlg5r9qfec", - "account_number": 311, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qpj52qsl708aqhazaqehhjw7cdj4her9nht4xk", - "public_key": "cosmospub1addwnpepqtrc9xaqt82k3rt02qf2vt9rn0egrfdfda2cezxvgwwkudqtd2g5xyxph83", - "account_number": 220, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qp6s6vzf6l0mzeglw0a9d75h7ch4w99ahux3j2", - "public_key": "cosmospub1addwnpepqtehxgdl0fyj92rj04phntj46w906r25ju5aewgplujeau7ytvptyzmztr5", - "account_number": 592, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qzj5kxv664trtfn4h0aznrsljtt2q95qd9r2qd", - "public_key": "cosmospub1addwnpepqwk6yyar7ttm04nzft4zz9ytsf73lxz8ktwg55eeu9jxmc0azusfk386gge", - "account_number": 367, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1qy0qwzljplfauvyhgayw6nxte2zxujh4tnq09z", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmxLLOUynbMtTvVZGr7uCfonEFBwkGFvDK6KWgnIQHmt" - }, - "account_number": "364", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "15991078449" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384290305", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1q9tcvremyhu80vylcpenp9str7wn0qf0pptva3", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AzKvVGnnfGTgV0kcCJtg0X0MRK782Ad8OXZSDjfexm+a" - }, - "account_number": "294", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "18560225561" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382597370" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1q9ed2n5wvzcrymaqltypazqzd2xv8d5aw58flt", - "public_key": "cosmospub1addwnpepqdc0sd0usmudn8v7x2edx5gq3zrwyauw0w9sa8zuwa0umnx9262mcv6nt5f", - "account_number": 235, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1q9l78v72yp8mmuthy3cmtjmcl48uydwmk4w2f5", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxSGiSW7KWQfHOqY3d9SqFnDr0BcQT77txd2iNj0FcFo" - }, - "account_number": "561", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "19779982592" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382580775", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1q2gfyuktwxwm9jcccdlqtvg0u6uv9c39zfegkz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A2guY1n6F6/cJVl04VWd8rZ+VmzEkRpSH2PtvMnUIzmQ" - }, - "account_number": "714", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "19372177963" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383817284" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qdzgpyxu8cev4wjz9e567nfdlc2cru8ygy9gz7", - "public_key": "", - "account_number": 690, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1qdfm96r5gmzg9js5hf633anmcfu00lgdn83429", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ap1p4gE1BbDNY8TEiiLY2ONiDCxM7xfMMeA2JgZS2fKM" - }, - "account_number": "832", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "13273656975" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383758174" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1qw9wqlz92hj8y6mcj24l6wu68er03njunmmv2z", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A8jFXOI72LStcMuG7KmHjfvcZ6bwI5IWnO5BI/4LT7+v" - }, - "account_number": "453", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "16609259804" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382587419", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1q03kay3adsttv6watm3agqktnpuuxs65a9azuv", - "public_key": "cosmospub1addwnpepqwstfpc6n2mx2kwfz0p6cqcp2d4am2xavsgtdncu3aqwvuvr8672z0rjrvk", - "account_number": 188, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1q0cw6hmrm4myx5c3zzmw6deelygsl2hrts2ju4", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A8acbo9MomVT/Kt+NmCBTsefjGsOLOoCdTXE52eL/EYe" - }, - "account_number": "391", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "8276558209" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382587682" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "public_key": "cosmospub1addwnpepq0kvcrpdk5llgrvvp222wgr5a032zzpt5asqp3ah4g55f4z8enghkumj3zd", - "account_number": 127, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qs5htj5ayfgg27t0xnng837lzllla5y2qn5lau", - "public_key": "cosmospub1addwnpepq0wlpdxwafzxqlunejuhht0dzrx3e25dczn62j3refk4r6x0f3cjgyj6etu", - "account_number": 338, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1q3ttxum2fvcfhg44ttdnm3qecrygdevu8gds52", - "public_key": "cosmospub1addwnpepqgvt8hk8ugsx3spnywmwca23g5n2mefgl9wqae5apg5c8rfjqejczfj2c2d", - "account_number": 841, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1q3mptmfxfd03myzy847p0mrssqw0sh006086eg", - "public_key": "cosmospub1addwnpepq2c22ya9l2vg3zdlw4s92cc95t82zela03cjewxma2dylwgwhtf972cc8v5", - "account_number": 605, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", - "public_key": "cosmospub1addwnpepqdhs8x9jxh3zj8x9khc8mxzmschyuglut7qc08pgnsvsez40ejvagefk52j", - "account_number": 668, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1q5py82x5cf8gqdx7d358cdnwuzyxx7htq3vncn", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ArecICb+Dq/DKH3tx1VLm7Z6RaOSbKSeRQroefKYO5bo" - }, - "account_number": "602", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "23749174959" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383166471" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1q55pmsr0wnpzlcx25p9vqde6c52ekjnv4h84s0", - "public_key": "cosmospub1addwnpepqwtcujcngz8swew93eweljkprc7tzpe4rleu2n0vnxyqeyqgektpve6zxzc", - "account_number": 120, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1q54ra6ur0wgyamdtgkn7fnmawf00tcj6ftvzsj", - "public_key": "cosmospub1addwnpepq2yn5flk79h6vhzu7xp0heeklwgkac6whhz9ezkvj2k0920k58qvqnsw5fk", - "account_number": 78, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qk5quugdx54zsrteg9hpee0ke3z35meunjyyec", - "public_key": "cosmospub1addwnpepqv4645lf2dka2qs2renc2n2rts24k9xfmxnx5fkhvj3squp8nv5ugt0mwep", - "account_number": 242, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qenyuc4ljgvkp7g2jhg274k2uzcgdc4vdzfr7z", - "public_key": "cosmospub1addwnpepqdfv5gth68zqmx6ma2ukyx2yskt2wy93yc6n68whzvqe0te49r2gzxnj8l6", - "account_number": 599, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1qecwnfw9y8td376t2ure5k8fu8f79qt30s3nug", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "At7U12yVspu1yjfrRx2nSL8pPxEc8ruMzQaUbZmM5YvM" - }, - "account_number": "265", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "12131214825" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382598342" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1q62pq2jlj6836ynv6r5fra4txa74duu3vauzmj", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A0BfehdLSU0AHc0bIYhTJPVgMVClEXPJY6Ihuy1ybBjf" - }, - "account_number": "246", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "12074854154" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382605308", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1q6eeennfulay5kz3lym38up6gq5ruf6h43cg94", - "public_key": "cosmospub1addwnpepqd9jg6thjt2qjfgak9v4z8yk9alj7c022mup6uqf8pstxp6dfhkmk6vc9kn", - "account_number": 911, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1q74af09jhrvg2ntxvcfu7pdn4zmhxyvlgahaj3", - "public_key": "", - "account_number": 322, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ql2jawqmha8d2xdgda7njakszmhvt75raj9kx4", - "public_key": "cosmospub1addwnpepq2fky0uhwwkpwt9zytza9ddewhgeueudleju2ez8w85lv4n5zkmvwqy5vcp", - "account_number": 54, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1qlkz3yutzuz0el2ullpyyaflfp78x8rr2cgld7", - "public_key": "cosmospub1addwnpepq0z8s7cuw4zf43uw0gnqlnk7wf4tus2vxyfgwe07gcqnldx4taw9jzf09gy", - "account_number": 402, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1py3htj8kmztj0ecdrhcgcmet6vupr9hvlhxkwe", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AlfsKLtw+wMBuslY6UW5lTsyTkyfm0d0r0z5lIVf+303" - }, - "account_number": "656", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "24014084679" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382616874", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1p9v6wdsjttx9yqu2gkrpx63uq52ec2gfflmjap", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Asw7B41F+XRDj759NdvAf2AO06ZUSeHOdNpkNTdHFXO4" - }, - "account_number": "853", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "17454514646" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382594761" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1p9wm55eaeux7v9eqf3szfqt77w70djrj7wpeh5", - "public_key": "cosmospub1addwnpepqgaxl8yk35t2yefh2j0wntqwzynu8ques0zaxj2dqga6yu04zk36vjqlhxw", - "account_number": 715, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1p9lzwaw02vs55dglhdr3dldmkwgm4km9shedwl", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A8Ku8hTgFQVM2eYSVqxwfmyAcpvpCI80ki5ObSRM7qCk" - }, - "account_number": "795", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "3198654462" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382817884", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1pxwj79qtf9y8jugqgf7vxwhvgd85vapq4ndldk", - "public_key": null, - "account_number": "606", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "10355479768" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382589233" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1pgf7qk5njqqq6fleca24pnamx0g226zahtf83a", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AjrfFU5ZJ8vsoZ3oogSn5uGlQ/RWs9ue9ZxDwBqN58gG" - }, - "account_number": "373", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "19201518243" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382597950", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", - "public_key": "cosmospub1addwnpepqfmgy2kzd8ed6w94f6cd2zfy6sj6f0h2234tljrmmgkgj3xx4dckwdxny57", - "account_number": 139, - "sequence": 173 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ptumt3vhyu0y7wc05dgrkl0rscntypr0gg0hvs", - "public_key": "cosmospub1addwnpepqgu3hhq5qxra529uses54z6mnfxgdvykhx3ervqzf5mv43xn5e7py020px9", - "account_number": 527, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1pv9f0ze6vmq3qvy29fywmj2eh2cpneymh3rx7q", - "public_key": "cosmospub1addwnpepq2dcqs6jwgqs06hz297xdv606lcyx76wnyf228c98wsnmrarnjg7qz0w2s3", - "account_number": 529, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1p0sp7r6mzt05772xq9eqg47rvssgxhf4ktctah", - "public_key": null, - "account_number": "461", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "4151971935" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382613494", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1p0u57pfl53kwefqrrr652pd3sm2hhv9gn599wv", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A9Ct90Z1DpXu0DRt5ljvdpOC45vNBPu+hCYh1Nis0ojr" - }, - "account_number": "465", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "20282066246" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384538442", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1pjwsvz9745jftv0p0c99t36m6kf9e8rxfd3wgq", - "public_key": "cosmospub1addwnpepqv9lgp9m4zw22uv7947yqpdhvctahd7zn3h3ucnal7c27d7fe00q2qcdsnn", - "account_number": 89, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1p5h9hzhyeske3uwhsf6k5nq38r5pxrejpjw49v", - "public_key": "", - "account_number": 259, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1pca5ng2s37clfh72ea806j9fwvpng4fjq3ey5s", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ApaO8ii3BOaQmTuiTa2myEPn5fSMTEbtzg73c9WYr5+a" - }, - "account_number": "618", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "5641576477" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382594452" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1pmjfpv056kk3jk3qfljph9fthrvqtufxe3nwml", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AuLVZvU7jdYyE/6DTeaOy5K3Efzk9BzNDb8w3ShooyGT" - }, - "account_number": "357", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "323583139" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382606410" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1p7sc667drjvsjlha0nwz5zxxpt38m9dn50u925", - "public_key": null, - "account_number": "301", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "11307273438" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382600123", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zpsu55hh9prdl4zw7dmemtmaqhxc9w3lzg8dnq", - "public_key": "cosmospub1addwnpepqt032nytxy3x5xdysx4nyqd43jz9ty6she7qzs8ng7tjyy2rnrstypzepl7", - "account_number": 275, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1zzca9hed282xcq9s7v69ysyyjls42ppxp37ywc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AlIiNO5qErfs6liqTWVSyWpn/wXsQGfGSCPaHQlhgvfZ" - }, - "account_number": "462", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "21178724" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384651288", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zzey9t59j5x7j5z9f3urms7faq0gq9dwmes0c2", - "public_key": "cosmospub1addwnpepqvfjj8axcs74r3vxh3lclw7upds6cn5ru6ggy2ptzjsp4e6j8racwdlek79", - "account_number": 65, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1zrer8vupwlnxlhk9p3w83xtgc9tlzl0ud5vw42", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A23i79DyZbd43mFdBaUZ0szyFZ+2dAe45pu0YbASNM3n" - }, - "account_number": "703", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "9719942655" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383631006", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zyqwy3xft00u9ljp4q7suc9m0y8cenyymm8e6c", - "public_key": "cosmospub1addwnpepqtlevdnat4yy9zcjfyfq6ms07gxsx9gwc9fnnjjps3pxqvpfkassjwlx2sd", - "account_number": 742, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zyp4lvynuuz8vzmzprpy8mxm4rkql6rytngvhy", - "public_key": "cosmospub1addwnpepqweyhw7decaxfeft5w4ds0tkq8t64utq3r758ryr8fkcf94383zyczqa7rc", - "account_number": 189, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zyz0twnwwk26pwn3w83d2lj7rda7lfr5d0m64v", - "public_key": "", - "account_number": 616, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1zygw824f55tk5srwxl00hhmx6lrl4npkgeqwqj", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwAnLopZSFC7vYpVB227OX5NUcyjFyi6nGCorlXK3fhP" - }, - "account_number": "893", - "sequence": "7", - "original_vesting": [ - { - "denom": "stake", - "amount": "2045484002" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383363912", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zyu5csqfxaxacgwegnhrysl0val4t48kfhj9ws", - "public_key": "cosmospub1addwnpepqgr62hm3rqc645prkl55rkd6t55dn30efmml2en9k4nyya7500f9sq6086u", - "account_number": 499, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1z9ns26y62x3qd3d8vs9eyxk8ndssa6gxtv2c06", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A+/Zuh00Dq+H3yoHkFBGXIZf40x1p0H/LVnneja/uyUe" - }, - "account_number": "712", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "15326381025" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384689508", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1z97a2xx0rzwtfftg3k9yt693dwxx9j800jz9kz", - "public_key": "cosmospub1addwnpepq23wa8hk95enf0xjzw2c5zyaeacqfmfw8244lnakcegyp2fqpasxwsm3dn0", - "account_number": 11, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zxpp6x3x0p0gcuuazft5ycgrxsa5wwsgl854uk", - "public_key": "cosmospub1addwnpepq2nrkgu970mta0gwsxdmz6gjvwwn2t27p9esend8p2pmwu3fxf4hynnl276", - "account_number": 638, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zgsxapl5dwq6c8nf7hjn2qa7aytg0m365jhs39", - "public_key": "", - "account_number": 635, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1zg7fduehxe98ny57l2rtdv8xxas25kyh6mm3np", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwoJuQXE3s0qMHmxNMznYmcd8gS6lftRSlzMuvSorVf+" - }, - "account_number": "433", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "21133346450" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382601763" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zf34ku927tasyr9fswhasvqt0x49janz2xuccl", - "public_key": "cosmospub1addwnpepqfvwh88427qm2s4k3c940tfkc8hf5h4cuc5cq600afwldesn7sgd2naelke", - "account_number": 213, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1z2ynmntxdesahja6gh76cunudwfmrhgcx7krhv", - "public_key": "", - "account_number": 680, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1z2grrxdha2ylfcx7jxtzqx9lvtt5pqfx2y5ypm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwIX5o1ywVGfTp7GlnalU04MthNeP+D3ckZwDDhR0D6+" - }, - "account_number": "847", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "16423278953" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384247065" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1z2tx3hdya2v33gwsph5ms8l0xuzwn5y6m0yvnh", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AylpbFcBoPjJhzjj7WlFMR/XHwnWQnZWbYJYImf7aBYQ" - }, - "account_number": "537", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "16374404528" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382602799", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zvax0zjqhu8dm20l40sgcquljpe7zkpvqjf3y2", - "public_key": "cosmospub1addwnpepqwt7h659ckadre4vsy98aw47wtrrrfyzpqsgqxy46h3j9c9dvp05jrkkg5g", - "account_number": 274, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zwmjz8q7wzqnx0d5rqgu3aeu3w9v3pwgxh9wua", - "public_key": "cosmospub1addwnpepq2qzhxf8qc6jpuncrsqvazm9jmkjkgrgs63y2znqkacrpryxnwvrgce604x", - "account_number": 62, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1zsspke0nqudcl0lh747ppqcsy396245akc2vtl", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "An+FohdUKtKMThLp3iKxISxZGHvc/YM6ajPv30KoFw3w" - }, - "account_number": "912", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "3378104205" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382597949", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1zsjzwew0ychx7allxldgtzrqykvx2e9h23pqd6", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AjA+BkynDT2bbzPUa3zqTJW3CRGkB8mGwdKMPzgCo3B6" - }, - "account_number": "287", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "10941659131" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383414945", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", - "public_key": "cosmospub1addwnpepqtrd0n303yml4ntd02dvgcxqdw02n6n3ar3mvx0w6rg76ngurktw5m96xq4", - "account_number": 16, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zs6hn5hf6qxjwmvntrzwhjkgvu963d0g8hz2z8", - "public_key": "cosmospub1addwnpepq2dyjl2cke8x058new73pnls3uj9pd2f7ad8nekyq5t8743k6xfqklnacgl", - "account_number": 821, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zjzkk7l2jalrspy6500my8v0yy6ycz7el534zw", - "public_key": "cosmospub1addwnpepq0x07aykzgfl7xjmd49u0dnc0xc69xv3cftdhly8hgc7y3djgfpqczjpld6", - "account_number": 97, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zjw6x8t95zuaxprcyl0x6l7u0ag6626v7w95yg", - "public_key": "cosmospub1addwnpepqfy7y8afz0k0almsg29x9jdzjjwgshx867sttjjpwax0mdru8umavhe7sun", - "account_number": 4, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1znvq8jqpwxt5hk2lg5654l7eg7kap3rpgjm462", - "public_key": "cosmospub1addwnpepqfrmh8r3t9ugfng9emenh9a4nr6ad508sp0akmnf3y9662trpu6tu8dxept", - "account_number": 22, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1znvpcj20duymyac6cl4r8kcf827aqu60vuxu8j", - "public_key": "cosmospub1addwnpepqfhaz3cwkjvqxwcgmpg4h52j5ta6tnanf0ngtkcreptep0al8vqdqfxj3hm", - "account_number": 46, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1z4f6qcdk8pt7hu7m6k4eu7fge3gcxhna5yamt6", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A4/EkwUQxvneHuIjAUpaqj7uy0VI31jrM9kE2fZ91eGj" - }, - "account_number": "603", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "17008905034" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382619751", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1zc80fmnzrxu2ksxugtpa2vtkh7sstkqh6yn9de", - "public_key": null, - "account_number": "374", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "17694130941" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383478253", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zcjpltwefj47au6pkrysjffvxq46a8wf4w57nm", - "public_key": "cosmospub1addwnpepqwy30hc84s6fc3dpzg84jxghuzt49rmgvjz9c09gcqtdsj0ed3wmq0wy502", - "account_number": 434, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ze4gfc6jhh7anrm0w4p2tga3a57xxthff3nar7", - "public_key": "cosmospub1addwnpepqgmgstj32dm22qll893mgf9u8d997g0w5g0nlpm3jpa7xec29h9hgyfkjds", - "account_number": 746, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1z6f7gdevn6dfvpls7tlqmqmzr54le7a4vtmjj3", - "public_key": "cosmospub1addwnpepqghfgrvv86d4rtnt8zqrrmnj8vqrm75e4xsl7wr9rww7tewvzj2py8hf39h", - "account_number": 609, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zu50umwgah6jhx07sw04ry0pv7fnvkpjmn8vl9", - "public_key": "cosmospub1addwnpepqtx6gll2j5wr9tuxfcw2yyzsfdalfapmzf6kspjzgtawfhz0r772jd88e58", - "account_number": 135, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zukq6nknswp76ckcj5s9rnvmye974n7cquu7nl", - "public_key": "cosmospub1addwnpepqwuthwk4ulyfx4j6f8q9ql4cwhnu923da4m63sg3n4hldpa2rzr2x3hkkwm", - "account_number": 172, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zah0g92ytwdvpchd3sceuanu7knhtu224vnt5k", - "public_key": "cosmospub1addwnpepqvs0kl8srv442e38s7c7un3h0kwnxwnfkfdzzmj0h9zry4kll0slgvznvre", - "account_number": 137, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1zaeen6u4n0ulkaus2q6y5ceec4wuhsvtnq0fce", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ak5pG+GoZjwcfODrUPRiK+Ud75A6ckFSIS5sXaZ2rtE8" - }, - "account_number": "639", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "9307136339" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382918615", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1z7ruhrtfg8v2xv8egfyxldt2xaygspykszntzv", - "public_key": "cosmospub1addwnpepqd45mshdzdsn0zpnemh0zghvu25ukrxkn9r0nk0mc8qz44k2fpdn6xd6ane", - "account_number": 619, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1z7sj5sg2cnkg4phzrswwjkkq8p2d6434pcyv2p", - "public_key": "cosmospub1addwnpepqgm0kt3s90754tqnknjvrhxpqvgnr8k4jjzzujl8p68erlluacplw79j5qh", - "account_number": 545, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1zlyfewtaxumsyj34fkml4t54yvhqcls4eemanf", - "public_key": "cosmospub1addwnpepqf2ugr68h5nt2x6k4c6ag0f69f4ey80uv5w4u9ludsdpdtrhw07lvs3geyu", - "account_number": 199, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1zlu0kkfr24psuwq54mzdtt7uk7068ameyk8hug", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A8JIkX9/GnENJD0u2+xS5SOysMxweSuYf4/KihulMETr" - }, - "account_number": "487", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "11242547373" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382616560" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rq7tvegh0yqan5fpp90rya7q9lks5nyxlg3yeq", - "public_key": "cosmospub1addwnpepqf3tl3y5qptacmhg5vtwj3ye3ptax7vpamcrp9d0syfg2fak2m33yvf0lvw", - "account_number": 177, - "sequence": 9 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rpxgsrsrx8jntwa6q9m0a4xxypnphs9zzr09pg", - "public_key": "cosmospub1addwnpepqt07zac2d8y68v5y9ka86637vek6nzagfgue4q3yn0phmf03tpza2dvq565", - "account_number": 207, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1rpmw7y7cw2cu3kwsryy8z8uskn4eymh89hmq5g", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A1lbwhW9UvyBB4zfaD+KzN5K/+sA5elDtbykEe2j9Cvn" - }, - "account_number": "861", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "6569291679" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382892388", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rzynfn4000ww456my9ke4jf72q306sp4w8qs3m", - "public_key": "", - "account_number": 611, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1rz3n04g9vg0ygh3h2x96wh5ceq44pcjmt3lgag", - "public_key": null, - "account_number": "874", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "15150073021" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382584957" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rzuu7jf5f66jyhqjsusre7uuha0hw5e8ff7tar", - "public_key": "cosmospub1addwnpepqfptqtt25tnasc5hjvfl64gqm79l8d5kxkxgplxy5x4r74jmthr7q660k0m", - "account_number": 899, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1rrp0lpmx2yzd8d62y7flvg2eyh2n49l3ql47ed", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A+mnj8+qhScj10/SOH849GYuEzK1w8ow9f3TU0votb6t" - }, - "account_number": "380", - "sequence": "7", - "original_vesting": [ - { - "denom": "stake", - "amount": "3868847355" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382583987", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rrahhju34rdpmlnaww9r5egq0su2u6f44eve27", - "public_key": "cosmospub1addwnpepqg9x5hm4v6l3wx5ehy3jjpzhusclnzfqqf74qpehunhu4j5d865h5t33lcm", - "account_number": 835, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1ryp2xkqe74y5kx6zffqtdc3wzgny8xg8eguupq", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A9O9zz0BkCnefcEYcijJcfMbKzX942XDGMgtmU2RZ6vG" - }, - "account_number": "271", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "3707562566" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382593045" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ryy20he94rlaryj04mkhcj6n4dhuhcyt4ujp73", - "public_key": "cosmospub1addwnpepqt8n7x4t7x2kvd3dr00mfuuemuc4spvhdt35g05vatvjpfvw5uww57y4tgr", - "account_number": 205, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1r2ncmjrd4efnk9cjrftq7sw7347xqyu3a6jjm4", - "public_key": "cosmospub1addwnpepqvelvh903wf0ufp2qn3rpt50zlv3ffp0n767urfar7af9jt0ng57k30q55g", - "account_number": 813, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1rtw2ev4xm89vaqzwc7k520jlvrvlqnevk5f53y", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A/9/EfVe14EyYvrmu5KAYvbTVWKe3LKL2mXvtvtzp+nA" - }, - "account_number": "660", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "5762646824" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382602892", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rddjpyvg3v3ft7aqfh449z4dzp2m6rdl3klap7", - "public_key": "cosmospub1addwnpepqgmdqzgfkwp0d39hlj690r9338gpflvzfvcv8vjhtq2ntv8g6yhvyxt2m79", - "account_number": 249, - "sequence": 9 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rs7csfnnwetmd2dcjsv4p59w3t46g77lt0wq5l", - "public_key": "", - "account_number": 384, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1r35ejcqcmv94r87zwrx4xngsutjppj3yx280jm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Aw7zQ8konZtNR5Jt9FQXGf0cxBl4fC9kfkAFNvSfGCB0" - }, - "account_number": "770", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "14105664945" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384805407" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1r3e4elvyszkwjyp85erl5havx6emrk5t7k9tzh", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Aiu5nlas+9+2JIcjy+sT2GBopsafjZHGZDfwZIvfROjq" - }, - "account_number": "393", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "12068860638" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384240724" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1r5tg7kujl8x77c84dedr2z9agsjyp8tq3qs2c4", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AquoGxS04PJvUF0cROt2eZWOkzYrpowIjEWOG5h9W9WA" - }, - "account_number": "590", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "10793715881" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382601156" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1r572vr0k388gpjw5h2u75ppmarvgma20rqj2ws", - "public_key": "cosmospub1addwnpepq0dwzc24j2j76srsg3dk705j73p26s985sckn34g8d85m49nz2mxq5fmge3", - "account_number": 566, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1r4czpmmu87t7zhlh34zrzna9gkex4ap5g82a0z", - "public_key": "cosmospub1addwnpepqdn6uzyl56y7nttklxx49wtfnz925n96ut22xx3s7t8hphp4mrh5gmv8stq", - "account_number": 74, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rkl7umzewantxm5e8mf2l2tcxc3t7hj8u49jru", - "public_key": "cosmospub1addwnpepqt94a0th746ahxr6ssntr5wlen06p398rsg3y5h2w7atc3g788l5jcmrgh2", - "account_number": 108, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1rhc7hrsjmzlqfz4n400j53ztytqafe9qqqq38l", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ai/T3oRkESImnR/wIYPQRrZquUWYnPrZgEN0i1Uispor" - }, - "account_number": "514", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "21397083756" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585616" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rhmkvfn9rzns2satkhlglyv7m58nk64c3jx50r", - "public_key": "cosmospub1addwnpepqduhk88juvx02jj3wm9l47qzf7xhfufcucf2z3zhdsvynmqvqpppyxp4nf6", - "account_number": 497, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rcru2vteas2kunww3zt4knx28krlestxydpwza", - "public_key": "cosmospub1addwnpepqv2std6eyvykrswpyvs6k64fe0nxngrh6p3n96j956uhfnehn3trw36cs5q", - "account_number": 463, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1renmf3hfgfq3p7wzenfa45alrhtc92f9geghu7", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "As8H67414cjhDyfCh3YXJkbN7/bRl0xUzOVYXUa0rbEL" - }, - "account_number": "331", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "10087834154" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585271", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", - "public_key": "cosmospub1addwnpepq2sk0mz0kd578jmhd05magqr44kj39ly4r6a2ccud5yt3xp9t5ar5neagtj", - "account_number": 136, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1r6j2xkpnnjve9c00c854laqp7l7zv8pxeksxrz", - "public_key": "cosmospub1addwnpepqw29w9fxpsx87s4zlpx8wh80nx4hpm5793kej5lr2xjj4dfen87ms7nfyjw", - "account_number": 522, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1rmyk79ktv6c8q48u78udw5p906fp0w058796d0", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AzUjU+T3olsA63SxGeZGQQO+sTl3Q7pLT54r2V/4T/nc" - }, - "account_number": "399", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "818342307" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251385156802" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1rmuuqfp6pup9t88wt3chxlklug8rchgftgl5mc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AvCiAefdh/pBQp1X34KxqaRRr/kMrwk8nAtMR+JBVvBP" - }, - "account_number": "565", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "19919188059" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382594294", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1r7v8zc5t2ylfm3v9zc8zrjf9w6rmtmwkrxfy4v", - "public_key": "cosmospub1addwnpepqgu6hhhxpcd2m9xecq7cntlv67qmfx2ngqf0497y76fs86mkehdpq0tnmv8", - "account_number": 159, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1r7kh63jvjhwqraux9wtm3jat8ggm437w9cxcxc", - "public_key": "cosmospub1addwnpepqtje4agendhh34cze964xcknahtyj03ung7v6k9f73rdpvv435jkztydcwa", - "account_number": 862, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1r764cqpxtae8ed0zyy0v6sxut9dm4fuqj95xgc", - "public_key": "cosmospub1addwnpepq064pvv2h504yls65tm9s8uchpekrtur8fzrrqls7p20rdn0ga8755g6kf9", - "account_number": 405, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1rlzurkn0mywyldswcafhu7r8r0tha4s5prs34u", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AzLFWy573WjvoAKs3mANqQ3N07ChH3pHfybDcZZmoLYn" - }, - "account_number": "442", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "13544919961" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382592037", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1rlltvm5ks32kh683c0w7epsjvg8aq2hvct27p6", - "public_key": "cosmospub1addwnpepqdzy52g8msawc0kat2egte3fx2z02trjsl77u9dz4xxy9y60zge5wj48gda", - "account_number": 571, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1yqt74740zamtyag7qu9naqgrauz5wdzl4290wt", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "At1L8wk3va5ZQ37ta+pfU0NN7xHUuDkpwNz1gUoviwNv" - }, - "account_number": "450", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "24610806346" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382615405" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1yqc7yxdxgz9etrp3avxg8t6ppfm73wxnzyf360", - "public_key": "cosmospub1addwnpepqw20j4ku4csznlvaxwlkxjd5dm93w9q0cvwpwkqrpm253trhzzevc75yhan", - "account_number": 833, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ypg3z7gmuzg2g3ajwzf26kv8tzhch640hc9202", - "public_key": "cosmospub1addwnpepqt4nq6de8f6dhcg3wckrz9f58vpagjhq6hp85hzf4e8vgxxm6zx2x22pp5y", - "account_number": 552, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1yrdtzqfkyum94q4v3j3xllrtf09qv0jvympw86", - "public_key": "cosmospub1addwnpepqv53053cnvql8sp5lyptdrrd2dh7ddl5ad9q82tk532ayyjx2lgtz0nuef9", - "account_number": 408, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1yr5ztk7t7w329lllmylgz6wnfk664qu0h2u9mr", - "public_key": "cosmospub1addwnpepqv2xfr6pcx5axa04hegq38yjvz5wm0lj6nkvexrzlxe7lga96sasz4cttgw", - "account_number": 100, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1y8jqa6t7g9m9g2l5u7m7lvm36pj4ssqyas8vdh", - "public_key": "cosmospub1addwnpepqd6w7k27fsjpuxkc5xq7gyytx3nvy7h3037qhhkcuw4t85j84uz2gs33ya0", - "account_number": 670, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1y2whyxm3k2mtz3j0hvjev7ztq8q0cz0vqrphgt", - "public_key": "", - "account_number": 512, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1yt9s823gnqayrjasrra5j43pj9c48ae9exgq5d", - "public_key": "cosmospub1addwnpepqvhgqx90svcvk6htmhwpfudunnc0ne989y7ymdyltcssu7n3p4kw5qt76vu", - "account_number": 745, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1yvn8kgpuuepzefm90rydcladzwwqa9agadsyus", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A2rrXFw5WPGvlYPBD3PBQcZ4HilTAK0L7d2GS692F54y" - }, - "account_number": "701", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "12294556362" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382602733", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1yva09usdkzdsqekaasgcqvm50v9vv5pu4fd933", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Azxeq692AFsPSt0JwLDHVv5nGdq5vYO0n6rGk9lO8y8X" - }, - "account_number": "843", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "15405600669" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383534110" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ywe4qsw399leu3wza5jpny3mmrs69a3gj3hlt8", - "public_key": "cosmospub1addwnpepqgn8ffnhd2tj3w4kf7vzykvts2c25hedmy6m8zzhxs3h0v0jnfs25rwvkjp", - "account_number": 563, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1y30ftjd79f3p68mssyd9zug24q2avh0z8uhx2m", - "public_key": "cosmospub1addwnpepq06lz2fxdcn3tph2mnllznwszzja7vtlpm36t97zgrsycq2mdsw5qh08ptn", - "account_number": 30, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1y3h72de80x06cz7fs3adwlnp0r8pjazw0r5707", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AoO6m7BnElNDbo08fsLR5jftHDh79N0WElUWqXkBCwwZ" - }, - "account_number": "771", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "7070821988" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383121840", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1yj95f65syc75ptwcy0n7kafdq33awc2ve8hthq", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AuuL56D8+Cv/t6dN/R93o+9C7yVtb9f5//OiKeP+83/b" - }, - "account_number": "831", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "15482923369" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382604027" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1y4yrpwaae4cysuyxsg2qa3gnn6f6rpu3et847a", - "public_key": "cosmospub1addwnpepqtuw2axfye4m3vrjyu733k608nkh57vj62zx3ew7uzpf5lejemapjg5jr50", - "account_number": 143, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ykavqzwglmeyx0hdrtmfhe8g20fmvlx2fphklq", - "public_key": "cosmospub1addwnpepq04m4crs7rhxhslqgnakermccrsunsp5zty5awqaevlxhl6amrnq7c3arzc", - "account_number": 509, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1yezuhyh4htsy74jkhfey9p7urgwhg00j3xe2tk", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkJdsNpEm5FNTEmmWVvS2rg9/eYjFxIjVYPiQVkhuNd4" - }, - "account_number": "558", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "14579822792" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382612048", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1yalqz5m4qcjtss37pdnvalz5kaws3yjyqs7uf7", - "public_key": "cosmospub1addwnpepqfwtkejmrhg8p5e05xp6llhc4x0wt679t9xw9p6uarawq64jqucc2mcgegr", - "account_number": 42, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1y78hvz86672la4agrx7n6lcmgjfgegpkldazmd", - "public_key": "cosmospub1addwnpepqv5kwv0ddfvkzl957cq5mccpjfe0umpt3ypgem267f58k4cmnsnyy0n0xz8", - "account_number": 880, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1y7m2ga0zpxr6q000a4a924fdaeycw5edykr3k3", - "public_key": "cosmospub1addwnpepqdft9yd8phsuwjafdzqgcyptqnu9pxmt5n87kr70wg8kfhz2wxa6u6axq2m", - "account_number": 112, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1ylf26t6vhvugawg87328ng2ug4d8f25syxp64c", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwPAnsxW9g7JMHn7aBycPbHHNiqJKpe7hcxtRAyTW9Gu" - }, - "account_number": "800", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "22972055437" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384511147", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19qqvhp8aacjvxjhtgwncctmtrmjelqs6m6yusx", - "public_key": "cosmospub1addwnpepqtccrpk75z6e7ae36lhwfeate5wz6xa3pua2ldt6hp3f664tc99d229ej4r", - "account_number": 240, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos19rn7ykwqdrc2ftrwefkqqgq9te3q78nkzxkl9h", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ang5poSntZZi8710ftJ7YvH/9JAh5pDS1EaxrnkFcJG5" - }, - "account_number": "244", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "16030340306" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383385496" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos19rlals9yl7q50rfww4n70m26vna9envvsqj886", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AsXFcdEGEsyAbHLnnAjYBOU5p3+Ob4uWDRvowMzfcusF" - }, - "account_number": "344", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "8580085181" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382588197" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19yplr2r5lu70jlymwrumzuc8tqeeu7fg9pz54w", - "public_key": "cosmospub1addwnpepqggyu0ngddtzyfty960c8zxyv9q9tkugh3kdfn80l432quqnd2kgsltf3w6", - "account_number": 122, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos199mt855sp3pqqxarqyjffjgm2v6uzru4fhslp6", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AsTA3MV1yYLXp5UsBMM63zmRMjbGRck3mjbf1DeYQ/Mi" - }, - "account_number": "445", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "3063048900" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382592855", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19xyafr0fc2g0rvemhmruyj8ywas8qamfnps2zx", - "public_key": "cosmospub1addwnpepqdtshp8mmye2xpryf4u4xa9r8x2kvkdgpd65ek0gxpzgy870g9j87xtzexx", - "account_number": 361, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos198k0ah8pnjzthydgvnq30s24s8jd3wad6puc3q", - "public_key": "cosmospub1addwnpepqwk536xvr3zt636maqukru49mcw4tpux4gx5eva4suyllphkyhzkvjpzpq7", - "account_number": 538, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", - "public_key": "cosmospub1addwnpepqwcgreqxwc4ws8pjkut4e8jrjtym2sv7fl3am0x6678xtuhl8hsfspm09ev", - "account_number": 477, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ai/9xHH2C0BEMXMGdJnH2xjVyitl0N5cSBXqqJyTFpL9" - }, - "account_number": "272", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "23749732992" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382609053" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos192358ethggxe3vxsmyqgqhs3n2ullhagq90zer", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmhKqR5/6XEZdPl4icm/FOW3uOgwNF0cQRodxUnooAqb" - }, - "account_number": "631", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "1341493520" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382621064" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos19tvzgu6dmna8qljv8ex42vpek4r2handdn09d7", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A/NfHryvPeXxQt+Z6uvgkhAR6RYoZKLVaCD+uzwA/ajt" - }, - "account_number": "804", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "15400521236" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382587861" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19t7ynn7yzrc7ugvsdkvz5rtr9gmz6jyux06r2u", - "public_key": "cosmospub1addwnpepqg2e2fy2hl6cn40sx780nvd228x9u40cfcpjvdnmn3mqfapyjt3m2mzkpvv", - "account_number": 87, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19ve7rrjrngdgf6pfaj87csf4rwykqdmhe5hy2u", - "public_key": "cosmospub1addwnpepqge9z0fefq3xpf8y4q8j57c89x65luk2vtcx5mln75662ukq00f6s04clvg", - "account_number": 585, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19vugh7w9vrp6x3nqzjph59zg0d28c0fkzejc2l", - "public_key": "cosmospub1addwnpepqgmnkn2nw2c6m0s6nrrcyxksg9j50sesj03xzxa867yvgrzw6rhgjhe9ej6", - "account_number": 55, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos19dvdx04jp6j0ltpweee8kaaxm36arfsv2fv9rr", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Av0gT1zLvxZABQuhuDt2eG4cedPvp/KlrP/xwGOpDfva" - }, - "account_number": "901", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "24871225862" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382609607" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19deqn6g9q7mnhzg5j0qr25k9gz74pwlph5p50r", - "public_key": "cosmospub1addwnpepqvqtq2puvhmk7g8aa2fzxkjrjrvq2hfczxjcvfal8gtzjm7tts96kh32s73", - "account_number": 443, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19wgl6sjkktp7mysmmtzqnecd5v2xn7gs0gdrag", - "public_key": "cosmospub1addwnpepqvc65rl00msmtxck04xwlvz5atca95tsyg7d4ryv65ez6sgnhvpwulkt0xe", - "account_number": 164, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos190kcpcyvl46xva8ya8vs5wmmg4nygvut4z6qhj", - "public_key": "cosmospub1addwnpepqwvdjhxcmtkq3y39crkc6ue3q2xdgct97gggllt8a4wyuquyf9u26lqyf20", - "account_number": 51, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos19szahkq3g937j62shd224cdtla3dv8rcwvekj9", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Atmfr6tk5qZtMMfGYzf6bEb6hAKyXw/FQtQ93s+cLhMv" - }, - "account_number": "914", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "10021547629" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383470555", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos19stzlsklhmx4akvnq7s2jvl828hrt6zdm6dhys", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A1NLLSC9/7tzys8OUTkDGGHBlRbS1zOrThR764azQG9b" - }, - "account_number": "671", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "14889404486" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382599490", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos193pvwgxpxnd6tgz0gtyl00dq8r3ygeflnhaxpm", - "public_key": "cosmospub1addwnpepq08srfvgm7g6jp2xxp4sqgm7m8ys3sqvdtcd5vwr6j42eaw8raq22kdmtv4", - "account_number": 174, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19num42c3egx8a4calkn0pz9qxaay7svyyh8vfz", - "public_key": "cosmospub1addwnpepqfq5uqj5at0tnvnpdd6ejla6a348n44j0d89cnxswghgetrp9kwhz44h05z", - "account_number": 845, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos194x33ngarpaach5g69g60cd2pjq8h0hqkfvk35", - "public_key": "cosmospub1addwnpepqteyhg2k2hn9lyv0ydvaae5gy4azvwyhvetpl9ctzu2gflnvp8dyxjfp9td", - "account_number": 755, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19e3lp8kdpnzmd778gxz9hqrnaxw8spa3t7jl9w", - "public_key": "cosmospub1addwnpepqtghv24fwjdplvpkcrxndg299t5y0xdmrj9uqv2wmskfah6ufh4m7k7xepp", - "account_number": 116, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos19ehwyhhnu55mw9d96929sus947zw6eee4ue38p", - "public_key": null, - "account_number": "576", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "10669949438" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382591784", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos19akemnyuu0rgf2y0rrd6wrxpkyd74q5gzkgm5q", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ahl5VXPKdkiUXpoyNQfSVbPlzgTmoYJKQkoeGsixsBJk" - }, - "account_number": "317", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "13798860848" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382599118" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos197wzfp3g9xq92szucsjce5qfd2p4nrl5cj8lz8", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5SQ1IUvBfNdSpLKiNZDZSqGkFwgmsh5TV1Tc8omy4G/" - }, - "account_number": "677", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "6679282515" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383494332" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos19lvag94alj6tknd5jxjku46qq330x9r5aa7h6s", - "public_key": "", - "account_number": 812, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1xqzjt0ncnwqxen7y2xetkzpnvdf6fz75pf45v0", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AoFuxTkv/PJ6muMvOzsvwX0Mih4SJkwS4uVDSEYVCS0y" - }, - "account_number": "683", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "11230513351" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382618456" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xq58llsgh49tsz22grs28jk0p7tvswlcjcrl32", - "public_key": "cosmospub1addwnpepqv8t92hg5h8d39cmznd7xfwudv744yj782rg7jx6utajy3xyzfypg6sns9g", - "account_number": 892, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xychruegs8u4cd4s3l7tkcc23ev90zydd4n92v", - "public_key": "", - "account_number": 319, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1x9mhtyr2tak88skl0nr4lq6k7jreus6n5hnvvw", - "public_key": "cosmospub1addwnpepqwpunsvkz6dm8s4ngxsnzrk4hhlgtg92t2a0wprx9hyrxgun9nn97mj868h", - "account_number": 763, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1xxurm2uymwd04sjxqedjae5r0zxhalh26skxct", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ao97MTAU0BRgKLfKhe5E3faYNdfrlCsasDATyurI8wND" - }, - "account_number": "346", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "17450447338" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383588030", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1x8z2epqz2rn6eknljym3ddjyg0z9tgtldaukjd", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A66yHvf0pW6YkPuxA1OfjV0WpfGgo2w3zJX7QPNDGkK7" - }, - "account_number": "424", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "11875627180" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384530535", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xghyawtulyzs449mhe8drctaaxnmdnmkd90yx9", - "public_key": "cosmospub1addwnpepqfj9ar8t6crdlv2ytmapdjl5my6j6yt08rgt2hk66gw43tslkflkklqyxhr", - "account_number": 533, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xfqsntajat3kv06ptad8zsqacmjrsjc2sa5ajt", - "public_key": "cosmospub1addwnpepqvn9lh70feerf3cjcmcxe8gxqqewppel2legf2f4t6v05sf6rwm7yuundjf", - "account_number": 570, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1xfps7nht3lsfdzp092ast50aev4nhkaxtf7gh7", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5C4vigREixYQyMAjg8oxG7BwdSQN8jZ1qFDzqALTOok" - }, - "account_number": "632", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "15162979006" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383339833" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xtw84l3v4vv9ezf4r5ddtr6cgfgjzalavv03x7", - "public_key": "cosmospub1addwnpepqd9rxlxauf0f8wdquzctrg47q24aa3n20rel24g7wn8q2xyyy2cmwndj8kn", - "account_number": 307, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xwjpulj30k4y0smg9krxwx80hk83r3zhs48jes", - "public_key": "", - "account_number": 332, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xw7mpsuf4vma4a2thsad2623wjcgcy6ukrrws0", - "public_key": "cosmospub1addwnpepq0777tgejvm3kqc7vhe2jdv3tag9svm3hm636dqq6k4txnv48kcg5e57xfg", - "account_number": 593, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1x3mfvxtp5x7dx6jepcv9y5my5pc7l5fwfdc0mv", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AzSQZOMkAgucowy9oxlwqi8EgdCMVFGQVx6wRASxqN6g" - }, - "account_number": "780", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "8642534120" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384717213", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1x3u97k0k8xxxjvt2vca8fy9g3qm7wtgp8wtmqs", - "public_key": null, - "account_number": "485", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "23715398268" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382593856", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xj9uqw0tfn80gwvrsv0hghs9jvfyw3lpz963de", - "public_key": "cosmospub1addwnpepqgpthjaszzcvylsczd42sr0lhanxdjkx07ec2r0g27mpwcmw55z0vnz6gql", - "account_number": 320, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1xjf53m679qpvrg95pz4zn8yr63tj4nyy6quvpc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A8Oq6E/eilRyTVY6zd6gluRNVfWvaP3XqmXRu04orWTa" - }, - "account_number": "260", - "sequence": "7", - "original_vesting": [ - { - "denom": "stake", - "amount": "727021434" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384488508" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xnh4mumajk76tlnsp8d3d95r7hjnt4drd7cy2f", - "public_key": "cosmospub1addwnpepqw4vh38c7e44vpvszes4lcvjkz3ah25sja3jyj8a2jyfk44fn033xys9zxh", - "account_number": 620, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1x5tgg6j5hqh0swtw3wqymfdcju0mmy2uff8zee", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmS/ygIryBg8MznRY5EnBbRBl6ZPuoD7Tct0VSzqrkun" - }, - "account_number": "395", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "17917842626" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382583601", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1x5ag3znvs0jt8lx5l708ndj5rt3jc9dqkh3pw9", - "public_key": "cosmospub1addwnpepq2yt8nure838qnxhq7fygya55rxvx7z0jfga4ed4c0nm6xuc89hxvyy2r3t", - "account_number": 382, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1x4yzfjt777agvsfz6cskjst7v7k42xc658l2uc", - "public_key": "cosmospub1addwnpepqt4hew3dkv9ytm47sg7767ktkthyt4jqgednnvcnhnzqx4fznylc2peqxrs", - "account_number": 140, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1x4u73wvuayr5w5gfs96jak2nrs3k4r96tknr63", - "public_key": "cosmospub1addwnpepq2fyhe0cvqmsj022qm5ss4ph3fselmkxpuruhh83vcm9qemuj03jv2mr92p", - "account_number": 741, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xenmhldpnwfl0x8ze8qvu2qc4v58zr7qkz73sz", - "public_key": "cosmospub1addwnpepqwnwchhjxrz9v0xlwrnp6x4ewsyv2gmc3ys8c565zpskc6dq0qy075z6uh4", - "account_number": 856, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xec6kclrpkc4ws7lwf5j0u8207nyg6dzjapeya", - "public_key": "cosmospub1addwnpepqfvnelws9nysntl02t3hn42jsvg37krjan0y9ef0ff6qvyyeuflqx58a9ks", - "account_number": 49, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xau5jp7uyewxcwg9tzwsxm895v3mf0fn7j6tmp", - "public_key": "cosmospub1addwnpepqw0gk7g6ldfltzcg4evfrv6g75hp9d9raerpg574606nwrv8zy8fsnccga9", - "account_number": 13, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1x72py7gr6pd72ch7u380ay04t9mhf3fkemyak4", - "public_key": "cosmospub1addwnpepqf5qh85wpx6k2c76xt38sxea46jc7929269hg8x9ddjeexhgrggjsva2td0", - "account_number": 38, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1x76xgyet9jkq94uqcckrwm20l85gt2kxha8sce", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ax4Z9/Vx7kaEEWEaBEjb2YXhIUgv4SozLWSBELtLIFLc" - }, - "account_number": "610", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "8972475158" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382583060" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1xl99x9a2fgqrm8kcpvp8rx7xlhgw5hzmwej9ee", - "public_key": "cosmospub1addwnpepqdrulg45uxsvsphx74g95782fw0czp4yp6ppg0qulae96jaedp057n2lszz", - "account_number": 33, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos18p7qvgvjcpl85mjwtvepe9reevevnm9faaganc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AthHloRJ++zad/zcK3NvcukZyMZztPYvPgW4t2BLpGrX" - }, - "account_number": "476", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "16963604024" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383989413" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", - "public_key": "cosmospub1addwnpepqv368hqruqrftx368wx44f2uaslv95nk3dx7mahejcnruuqhfx9j5l95h56", - "account_number": 773, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18rzc0m3vlq3cwee4tckg5grjjc02gu3dv9csx2", - "public_key": "", - "account_number": 482, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18r683wlut54pd8sjzz45ujq8nu4wfr65pnh3e4", - "public_key": "cosmospub1addwnpepqd265f66tdc7mtewx4ayd6d4lls7m4ma9eehyac8s8jn93gxkw0k63lzqfn", - "account_number": 106, - "sequence": 10 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos189mctxmcxlrl7rjzrnlpshzvn5lr775cy92s7u", - "public_key": "cosmospub1addwnpepqf4ddylkupthgx8vutwclv8y5m3e5yzya2xsl84hl3fhth7y5xdm774pxrf", - "account_number": 747, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18xzukww2e9ufj2ae0ath48ul8ycfyv9nq7h362", - "public_key": "cosmospub1addwnpepqw0az8gndyp5xhrfxn2n9n8m2vjtjp43dcska4rw9pneucsw0ucfud4sd5v", - "account_number": 293, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos188yd2umzwfwen7es68wrlh6auu3p8jhz0qfgej", - "public_key": "cosmospub1addwnpepqg03uue63acrdqmxf6sszfd8ksstwr6y25xmh4kpxa69wawcccef58yma3y", - "account_number": 60, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1884glx2vk6nxcurpf2dtjp3qgsl8zh5pm09rs0", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwD4CBQtiWlXr1PVrAbb8qm6VMAQ4u/l+9WzPS7uNRwV" - }, - "account_number": "581", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "6114761282" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384276183", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18gmd4r8ydls55yvgda4d8pfandk0xem5q7eat8", - "public_key": "cosmospub1addwnpepqwgfqcvy5tm2jzdcpfw2az2h6c9ug6yff843wncnn8jl6wye3amqwrjdttf", - "account_number": 206, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18fp6y4z2ze4tdqn5ghl70erq5wpe444p548y5l", - "public_key": "cosmospub1addwnpepq273na8xr4a7kykxadftya2lk05vxupfl86ylpjjc2a25flvgwm5qq2xj6y", - "account_number": 535, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18fxku8d7wa5vjz9ta2xr7asvdfdrqnpdjfqpe5", - "public_key": "cosmospub1addwnpepqw7yu9urxgr66vmwhaqry4ae68kx9sn3mr5c6gxqly4w4h5hl556qpp6qfw", - "account_number": 390, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos18fkw6s4hnj2llxljrkleetgns2y0h0vjg8kmef", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A7Hr0c2B+RXAJo7cFN6fiCI2PXpKYxatT6MUIirGywsC" - }, - "account_number": "292", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "9381392771" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382610089", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1823pz6pxtqgm8hdcxaysccpyd8fx83hm287sld", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AowP66Vk7yzkgKfcBR2HLVKDTqG9jkSPKK8dnK5VCwwZ" - }, - "account_number": "469", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "3098439245" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382593966" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18d3x3nhe0kdfnd3yg0qh3e8s6ua7xn540dxq87", - "public_key": "cosmospub1addwnpepqw3kt8dw6vfpay860cnyprfgw9xph9whh9fuwx7v3g03kdtpckjjz60kdna", - "account_number": 26, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18d56e7qz5869wegeca967hrxrmfduxdez89mcs", - "public_key": "cosmospub1addwnpepqgu3084y2uzw2a6cseptpce263l6rxhl89rhekt20vyfstqdjlzt2h2gq9n", - "account_number": 129, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18dh648kgh2zpwkdkr4cg3x50ruzucv60ln7csc", - "public_key": "cosmospub1addwnpepqgr3yz0pw3dl98dsljzz82u99665wlgyya6ymlhm7vgjypm39jwkymc6j9y", - "account_number": 902, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18wfnjhyqjzjpa5pgd3r5n987uet7qczjuwg2vq", - "public_key": "cosmospub1addwnpepq2897we7j0jrf6mg2c7z2vekjpvq4m4rrqpdmpxe7ccnac5smad7zurr5mn", - "account_number": 121, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos18037phaq40fkqdr4pxk2jajnsq8prfyyl4tzvz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkypAK9nLDhiwl/FmwO9FovOj8pXHtV2yRlUo2Njohw+" - }, - "account_number": "383", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "4550939975" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384358693" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "public_key": "cosmospub1addwnpepqvj4d7pjfcg6fcckuyh02wkr8vtz82zttnsu2f7say2pwsvyxn52uehvrgg", - "account_number": 7, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos183sdz4kk0lueuxfu7zzgp8tzcjndf3pfw3ks0c", - "public_key": "cosmospub1addwnpepq055lazk86cjz6r0s6jgcj7454fm7lscn6ylxwq5stu7lxxve6c8zqkwtcu", - "account_number": 852, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos183htwql45eyjphvtv9ga6jvrgzmpnfs6ax95pq", - "public_key": "cosmospub1addwnpepqt0vwa2zcjnfg22u6clrl463zp5hlt7qm6ucx8642styraaq76s3uv5k5pl", - "account_number": 396, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18nsp3hvv530ge4ag3qwa27jr8r65s8ll2zyk82", - "public_key": "cosmospub1addwnpepqt6v4va58n8u0husyys4q2qk258zswwu2m8xh8wq3te6jlg45zcjxewldu2", - "account_number": 601, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18nag9zrh49uaxypx83fmlz85umq0t9j75599q0", - "public_key": "cosmospub1addwnpepqf26xhga7sa872e20kwjg5wglmv508l9ukcq43k7alqqnjsqq0wrsc547rg", - "account_number": 167, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18k4yz84xrjqvrq9u7sehvje3ax4aspcksauctw", - "public_key": "cosmospub1addwnpepqg5954elsry83raausa5d90y69mvsfv8mtp455u6ynd3feg207vgjc230r5", - "account_number": 597, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos18kcmwj6z3gwmsscam9f04ty3tm8std0mw0upfc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A+rhDXuxivLvbjxAYnXlM0IxERSw4vjiLHygTQPQg/B+" - }, - "account_number": "652", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "1955991160" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251385136560" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos18ku7lzv6a0d3t63d2tsn2x69u04uv3g8sgf8kq", - "public_key": null, - "account_number": "559", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "23535369237" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383554343" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos18h7dxvzs4vn07gfgwxgjsvl7f2nhn4fspaggvf", - "public_key": null, - "account_number": "534", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "13481456084" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384487464" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos18cr3udfd35s2ktqlj25fujxnu9sax8h6usesad", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AoyYq3JIMoiVoPAwLFw68IU/5BZjCY4dUe0bo5V9D3Po" - }, - "account_number": "762", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "598797234" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384470229", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos18cuwder4hvd0dxu2x6wqs2uy2n0g5jdsypemhd", - "public_key": "cosmospub1addwnpepq2d0au20k4prd7jmwck4gnd7swhwylcq952x5mscay8h334aq6w0x5msx59", - "account_number": 409, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1864wj4twqatq54rrxl5jmfey55tmh0hvgmd9yw", - "public_key": "cosmospub1addwnpepqwa5t7ltkdv0jgnha47rj446cc9awk72ycda02dspm9jnh7l8qpazx5wrzr", - "account_number": 104, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos187t4e0t0xwp8ntfjkvec64kcwruph736hqxmkn", - "public_key": "", - "account_number": 661, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos187wgdejp6c2h502gtkzxcpn6qgrw9q54037mcv", - "public_key": "cosmospub1addwnpepqfe6dj39f6663ugywsr5usg63m234alngjn0p3096ldjv9scyddgx07fvhh", - "account_number": 356, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1gp93nsn0kdl5qhn5xn2wyqfug6uxu26sfmfal8", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxDZD8ij8yya7mS7Dsf8dL5gZIFJplKnjmmQvBSMBtpU" - }, - "account_number": "521", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "10779047310" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382596023", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gpk39c5dc4xnevhz4c7m2sjxequw30s3mnzwcj", - "public_key": "cosmospub1addwnpepq2kskxs5puu784kcprrwvtt96lzh7e24y5r9vgxadcqg2h9kry2xw50srmx", - "account_number": 151, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1gy49x7p6xpgdfhv8v9dh8kfgsef479cq3u8fzr", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AnDZBbT9+05xOsfIkc2BxVfkr57G7PkRMSQUg93jMvlp" - }, - "account_number": "870", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "9691091859" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383224661" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1g95xvy8qgzcvcl05fse0mpxzdfv3w88tpexycr", - "public_key": "cosmospub1addwnpepq02l45v2qcmsvtdmkp28uzkfzyfw2sjq9233amzpwwdtf272ghc928cyfge", - "account_number": 107, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gxdt4y0aqlm3s4rj9ukeecaq8jv3tgrqns9k6u", - "public_key": "cosmospub1addwnpepqw76nntvkvzve9n3vg872n0z8zdph4ef92lfcddqpzfvmg0ed6z9wt00mvh", - "account_number": 34, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gfta9y4c4j5dd08mju2zf23cmdn7ylaualvc5j", - "public_key": "cosmospub1addwnpepqgpjmce57au8t9nfdjn9q2zq3cedue04lgfvyeyykqaz669eluymsppa84a", - "account_number": 18, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1g2x2lp54k9wntyh774ga64hyp5d7f0paagzznd", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ahwzmm62n0OMpO9XJWjLp599bEmFNLnNS7I8SMiBjTQB" - }, - "account_number": "806", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "22222636130" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383593264", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1g2nzzd4sqk48066wu82atssmn5cs7vrczjnhnm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmeChT9zmV0WYwsPPrM+uBqmVdEmOCyCyuTfANBhXXRy" - }, - "account_number": "910", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "14087179165" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382604431" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1gtv2yjxfwhgrwrv6uag9pnqw69q0p5z8mzdddn", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AnzRKF//UpZVzOZHust4WwdqJOAewFPkmeGR2+JwlLyM" - }, - "account_number": "429", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "17085375123" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382612249" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gd779gn33yuxxla5pm5dphglcyx4ulzdkacyf4", - "public_key": "cosmospub1addwnpepq2xu8de8m8m8r6s3gdlzevgnuyjxqnerdhdt27a89w2euju4urw8yjd09rk", - "account_number": 158, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gwwltgyatg8yfe54447dxnyvs2nt6xxsl6lv2m", - "public_key": "cosmospub1addwnpepqf8sv0x7g6haj9p0t0ycp4t4qtrrwkddhnkkhczs5de58u03hkh4k05urfm", - "account_number": 486, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gw6f5uf38mv5dng9uwfzv4r9whvdd2f60ay2ra", - "public_key": "cosmospub1addwnpepqvm58tuxw7rj3dq4udtdgm49vg4q9pnlwlmfnwtydaamektrdh7fvl0a32k", - "account_number": 705, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1g04020ghngvh7lj8hmhequs5a83ly7xxyh0q8w", - "public_key": "cosmospub1addwnpepqw99ssq2lzjy4g26w7qwwuh36eglqyjn4nyahglh6ykwpctxhjlpws2rher", - "account_number": 531, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1g37aedx6gtmnkp8gpq33lnxwt2f320yt5twaxm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AvqAhn95HX0b1EQXbUhugozxAewwjl1qOZ/1CSNuuG/c" - }, - "account_number": "386", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "21471315017" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382938892" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1gjvdfxer9zkj43txxvgd5uf2lq9vx9zqh8gqrp", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ArXEYydH/+Hux9sq6E+lXxRqd/1A+Qaw4XIBGmhxYWrP" - }, - "account_number": "663", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "10747545130" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382601941" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gnpkhqvfq42exjx6cqaa3d7xnw8uexgncdd4e2", - "public_key": "cosmospub1addwnpepqdhcupcamks7erjfhcvl7f0ec9032vygtnraq5xg6uehjy0amzwmq29hgfs", - "account_number": 58, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1g58m70guf3p7y6hhf5trqmhzpzn99rvrkuc55s", - "public_key": "cosmospub1addwnpepqvptq754nmz385309zgntkv6y8lf44a6e5wac55dz7tcv2v94lslq8j2znq", - "account_number": 142, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1g4xvhqhxrwynlc8kq8gzjwp2x8mz9ljrqkqkhv", - "public_key": "cosmospub1addwnpepqta2kryj27uenxysne52plp50tn9tnc5t8nd2geytjcht6c68yppzhpst6a", - "account_number": 219, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gkdgukkcx52r2w82q2usyncf67s30g7hmqc74n", - "public_key": "", - "account_number": 340, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gh67zgx4f9d64ctqhtascuh87805v8yffrfytl", - "public_key": "cosmospub1addwnpepqtcpp77982hl5fhudkwv9mr6aqf3ree6t34697uvuqptnh6kj4ys5j5qa2r", - "account_number": 306, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1guuf6ntr5ujawszq99gkq2gqeevz37adzp2fmy", - "public_key": null, - "account_number": "814", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "27974118" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384000179", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1gayzja3zz6unep8ftnpunt2wefazs3jhunl5az", - "public_key": "cosmospub1addwnpepqdn9m93wfkj62hphl0uep7etngtrwe6mtl6gaf8f9e3a7f7g55npyd3nz2c", - "account_number": 101, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1g7zpua5k7smc8n8lkv099v06trk98rhpxgrtaz", - "public_key": "cosmospub1addwnpepqdwwmumvva86wmx94fr3hgtnt8gs40wxy3wt2heja430emv5lxxuvcumqwp", - "account_number": 495, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1g7sk4y3cf2473ff36mlcx9ydvted9evr4rugtc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AvV51T8duMyDhiKve4mt42q27oabr06iWAQ7VEs4oaRF" - }, - "account_number": "719", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "6905217040" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384889824", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1g7huk7g00saw6ntyqq7s8ek7l0hz4w2znxz7cc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Az6SXIT886XGLhQzRl5NiYxBptJO2kZaKAVGNt8qy/n1" - }, - "account_number": "776", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "5291392908" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382599824" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1glku8mx4nzp5crkjt7px9lfe4flfge3zf64tud", - "public_key": "cosmospub1addwnpepq00c9s7aadj53xmkfyr98d5kc84sxfmzys4pxuegwfth5ye5hem3v4jxzms", - "account_number": 152, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1fqmkps3v8evytw9jmpg3g83a6s0fy8m2hfzlp0", - "public_key": "cosmospub1addwnpepqvxxn9uqen6q7cmsadnksw37tkz5x00lq99ar79fyakp09qcn76u5serds8", - "account_number": 24, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1fpr9dacqv3ww2tq3vxsc5zxkejnqkcphfj74nt", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A1jKAEZCXdbMiIBk78y4feetRuKgdU4BMUihhLw/FT3u" - }, - "account_number": "882", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "16337977170" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382602700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1frjkqcr3r5fpwds4kypq5e9n865qss6ur5wfr2", - "public_key": "cosmospub1addwnpepq0gd23y0r54347syu5vw9sq25r8vsqkkdwgp47rwnc8tpgrxl4x4g3pj96j", - "account_number": 237, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1fxdty0drndqphzcpq7v3jz3hhwp0sdhdatraf6", - "public_key": "cosmospub1addwnpepqfuau0cn7csxsrxxhnpaqgaus98xjypq44dymc9zj5d6kd87f4h35zyua5l", - "account_number": 516, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1ff2vzyfjcwwgk07cqv7hgkpvj0yazgcpez9jg5", - "public_key": null, - "account_number": "867", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "2017285126" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382590889", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1ffaxjdp4v8w7kzgjsnf6nf4fvvndhrk6s9syf6", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A53L2pyVMpUUTgggISMfQEdEoUPkh1npwsApRvFce3J4" - }, - "account_number": "266", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "13796058501" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383768526" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1f2pvewnws73u0z5wsfmv5uqudwxl6jupfm6nta", - "public_key": "cosmospub1addwnpepqf7mq20pv8g7y9pw9ld39p3rkv6l64apz7w8nwd0q67xsytxec3mcjukmam", - "account_number": 185, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1f2tr8j23vqevt4hwk3073y6pvu0cgjg4jx4lja", - "public_key": "cosmospub1addwnpepqgxczxjtjfl39afnrsy4jxvvt2a037rydw4zvlyp23r2eu4stx0455yhd4q", - "account_number": 586, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1f2sunjkaqyu2wr9jupyjkl7qhlnesag7g08dlu", - "public_key": "cosmospub1addwnpepqtvptk4nrdkucwuw9hp6pt396mgychvg83wdwlhh6cg4jj6ruqvrcr7pm0y", - "account_number": 56, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1ftwtj8rwrz4n7e9y5gnnx47g2vtxkqkg26megt", - "public_key": null, - "account_number": "472", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "2085194196" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382620775", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ft0e05t5rl8ycw6a0nfa6jswvckycan4lfmv0q", - "public_key": "cosmospub1addwnpepqtct64cpw3n5hl3gxe0le6kqsq5ad7s9efelqpkg2g4kgzuxyym9700xs8a", - "account_number": 269, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ftj05w0hmw2xxw5p7gvr258j2824qd8r2xdk9e", - "public_key": "cosmospub1addwnpepqfyj2hu5pg92u3yd4zaugmzvkn9wpjp96lflmfrgr2jekcwljh9lwvvurtq", - "account_number": 797, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1fv35lda8ltd6juk384yqceqalcxyfj4kscxztt", - "public_key": "cosmospub1addwnpepqd5nsxkua92z9eamd4hccf0pxeh3chye2475vcrwc22dpxj4lmkvutf9j9c", - "account_number": 842, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1fdfwthdupznzgrg2d8e96ryxqz8smppet2p27u", - "public_key": "cosmospub1addwnpepqwsa0gtfg8nxze044y6vynaz5f5z0kz4ar9tghvyr9cpacl28c76kg5cp0k", - "account_number": 86, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1f09q88gqlava96kfz8xljgtj02rt4tmcpap5ya", - "public_key": "", - "account_number": 694, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1f3j0m80ey8ujgfg783838jqnuw63h3v04t86pw", - "public_key": "cosmospub1addwnpepqvdfq8tjs0fhrxwy8tgxw66832pt70yxwjrytz60yt7npdtu53nskaav84d", - "account_number": 673, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1fj43j5263mk8whetx8ru0gm4yf48xkg20txll7", - "public_key": null, - "account_number": "329", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "9926594367" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384970072", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1fjct2f29ymrw9h7aqffafx863c4tkxdh9lzay8", - "public_key": "cosmospub1addwnpepqvfa6uxm7xdeqjfv3v0j4tvz75mn9htveadtme665h84n0akmp7hjd2xy59", - "account_number": 410, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1fn4p8kkhtz5efwz4hzvspcnwm8x30hsvmasluh", - "public_key": "cosmospub1addwnpepq0cqxf0agdn2c6cgr2gkkzahntmu5uhyu2d0cs5smcz90nz04djcx53vskw", - "account_number": 414, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1f58nf9lzm4d5x9grnt3a3vd9c75szj95f6mm5s", - "public_key": "cosmospub1addwnpepq2y3052wcj9aq5ykg2tf8c0cx6c9dwpgyl53urcnygwly065f6hg6p0a7cu", - "account_number": 345, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1fhpyqq3eex5zcctlgsxj3s3dgz64am96stg46w", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxnB1WQn6UjisskZjL3Ra/Ihj3AeuqthtoY7VwU/xH8v" - }, - "account_number": "440", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "5561526745" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585751" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1fhg5564ngg2lhahuclhrx9jphuzfyrv7lgc020", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Amm0Qt3iJuUeqCsFiwd9XQpf8ezH103hj/YmZjmd99/j" - }, - "account_number": "517", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "20094731489" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384501420", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1fhnwxus6yyk6lman2qf9fzuqtekl7gcwx8lwq4", - "public_key": "cosmospub1addwnpepqt2ps67ppvhkqjqt8c5ju6kj8w7hn8768edfl34k9rn532e0xglsucarujd", - "account_number": 197, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1fh5qqypfpgrlkv89t4eevv6xu2z7tvp2gh5cdw", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A99he4k/Z30gPQURzBhU5SRk29R3o4emtzR2PLBacbND" - }, - "account_number": "608", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "2191920881" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382584848" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1fc96780mrsxn5kgplhtna40qepjgrm9wsyly02", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmzyvxBlV3/AdbGinnMOxC3i/BDSB0FDOt1NtwQFrcin" - }, - "account_number": "305", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "1957116334" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382579769" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1f6qxvzgn7lfsvg2f86m30pshf8wuygk7leffdk", - "public_key": "cosmospub1addwnpepq0m6290l4um82zn4zrpvcrx4fwaletxajr89rgtx5ukxmu03efnu5yjsmns", - "account_number": 76, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1fuge5wmj546lq6ljv9zfzjjgknrfmngv0xvapj", - "public_key": "cosmospub1addwnpepqdkhzwa2lk8ew5zpd0luq7wazwh4zn6r8qc2rdza0vky339q4ket2de0ljd", - "account_number": 93, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1fatqhwhj663ccu99utevpxrcsed6888nzc5ze6", - "public_key": "cosmospub1addwnpepqt0thvaytymy6nqsz555n4hw0kfdx08g98yhpjaucmpm49wfuy9gvex2p3g", - "account_number": 667, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1f7wpuyc6ehg8p8rxag43j8fyfaur3jy0ujhs2t", - "public_key": "cosmospub1addwnpepqg5fj7u33myzlk4ltuul7rdw0q42lm7wzd3uj6gppcm4ymxwtet9cte64h0", - "account_number": 436, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1f7utq63ae24m6aqw4metxjrc5q76j8h4gcgaxd", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkkttVIv/LtML0gKlqHYQrBGLvKKzaj7Lk5/CPLb3IhM" - }, - "account_number": "446", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "21385201198" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382955236" - } - }, - { - "type": "cosmos-sdk/ModuleAccount", - "value": { - "address": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh", - "public_key": "", - "account_number": 918, - "sequence": 0, - "name": "bonded_tokens_pool", - "permissions": [ - "burner", - "staking" - ] - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos12qzdh6cxrgn3t4v0e90m8005mrqakqauyyh5rz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A8yBMcuzl7cBkf1bWSYyyoDHU4qB04bzMkxiM/yWd8Yi" - }, - "account_number": "520", - "sequence": "7", - "original_vesting": [ - { - "denom": "stake", - "amount": "5048948618" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384085261" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos12qsn5ukkpvy0ymcsfh85yqp4paw5ew9mcg8z0y", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ay/WnReCwD0kUCYGyI0H6du67hcHNPwioYdJnQ3/b2/9" - }, - "account_number": "362", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "2298131693" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384430815", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12q3w0j5hp023hdjafgc357hy7kkha296f4xrjf", - "public_key": "cosmospub1addwnpepqfpnyhzqdcpx0unt5q0zue6kv5su0uyqlyecgxy45csr2tme32ucyprzuwv", - "account_number": 186, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12zkyjh3kjyz2ka0z7lskxqxhvtmgg2pzg8gn96", - "public_key": "", - "account_number": 878, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12zamvlnrz3fvxdaymyhmxfjlnpaz6aw54u78rn", - "public_key": "cosmospub1addwnpepq0hcte6yrzm8ppqms3l3vw92tc8cqqdacl8wkavpcjshum9a0rty275pfxp", - "account_number": 200, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12rrjnzeppeagkvqw6d26hn03kr0uvwk4sfw6v6", - "public_key": "", - "account_number": 526, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12r8vqqwmfeffg8s2egfhkhnh2mw6wcwpgzwl9m", - "public_key": "cosmospub1addwnpepq242jjldxy02w8e4d8mgh6tx6k9rdhy0rgn56wac2ng7gvjsc8yn7dz0agz", - "account_number": 820, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos12r0m6hwrnn0jy02tnhmk328d7p68x2rndzt0j5", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Arv9F54M82LbA9iPFkFjgukBG4LQnxE9p6nty8c2tL6U" - }, - "account_number": "474", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "7457647665" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382599125", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12rjah2jl9jpqwddh20vph9yu448d7625mvqdzf", - "public_key": "cosmospub1addwnpepqtq4rjflca8vgyn08w3vkpqeq57d80dmja25rd0ntqrx5fxm96gtwqs2tew", - "account_number": 53, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1289vtnyn8vg9rwv7jdcy2ht3h68627ht942k3c", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Atf75jS/MDbJt8EHObI2Qh0nH+Ld0s9cT2Y0Jm8i8oo5" - }, - "account_number": "507", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "11330787049" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384116759", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos128xc6r596pllf46ev2cpaetcujfgmhay0v93wl", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A4XuEC6PtipmxKMsvqxu4eqMkIUZ5BK3GG+jZ2lGpe06" - }, - "account_number": "557", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "320378521" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382582039", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1280ce9aj6ezeduu5adlery5cjmd4fy7yfe4s35", - "public_key": "", - "account_number": 765, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos12gup0vvqv32z5nvdy4ycrhp77dnax5hfmcjav0", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A/S5QqwhiQOlFMUiOfazhvy5Z797zKaXJv3KwE6SKOsA" - }, - "account_number": "297", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "20008020745" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382870868" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12f4fpl936ld8c64dxqgwv65p42na8dcnv9g7ku", - "public_key": "cosmospub1addwnpepqddlzcmsy4vds97qxa5a5xs4mvgeyp9zhmm7fqfdr888nhp0sftrjer622m", - "account_number": 193, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos122g652ynclgpadeusqvg8xatyvtvyuqplgqxdq", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A99E4NBvKh+ntmzMGJaIJmqeFOClOv4iBmm8QFiWEZN4" - }, - "account_number": "722", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "22942834889" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585973", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos12vzdkp2z75x4paa9nf0dvg638l92n5s8e0jk0w", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxMEz5zQyJYz/KAOizvEv8u+8oQTRCyOGCcbwwBYYHFf" - }, - "account_number": "281", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "17036639471" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384070698" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12v9agrn9wlpru2pc7keev0zyrnm5hyry0ycr98", - "public_key": "cosmospub1addwnpepqwu9dzd2h5zv0m8kky3yvwpp6zjy723lw2uptrcz5877vhy4xwywxae0wdf", - "account_number": 354, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12dh9h444s238r7hjrrd2kg6wrw4cwfk35zz0lg", - "public_key": "cosmospub1addwnpepq0nupdwltm7k6qv5j4x3z8u2572nkkjpazq4g7l5t8hedjn4nqtgzr5vc33", - "account_number": 241, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "public_key": "cosmospub1addwnpepq2vpcxra7jn5ph969c4cnj2qngyr09hzyssh4m2rvwkneqt2x00t7g70crc", - "account_number": 766, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos12sx0qw8yggnh7scj90gu08k66q7j8wqq88y25h", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AqTqR7au/LPljZL+sZhC484/6qIVmswVIOHRd9VOsEXW" - }, - "account_number": "468", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "2995278906" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382915835" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos123suyah6ulkjtdx2kgtz8sue98yswyz9d9kwz0", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AjkbidSdgf+C27tmz0uaFq/a3ppSlbvDhu5ymkGl6YtC" - }, - "account_number": "413", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "14333368778" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382605814" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12362v43p57f8dgc2dx396rpanj24j67pkcvy2h", - "public_key": "cosmospub1addwnpepqf80y65l3dn5hax76t9kkme9cctn0swqxr2327lqll9lkk0thdmcxzhdqk4", - "account_number": 411, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", - "public_key": "cosmospub1addwnpepqgsfrplz9dym7ma6y03ussxvrv8gn369dm9ftum6jq3hvhgpmmlrqs60wum", - "account_number": 239, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1250k2ymtkl6hf0ty6syhkxft33v580fhmr25qc", - "public_key": "cosmospub1addwnpepqv2m6qycqv50020tp8rke2pm0xwt5nd5z476jlq3k36jw0l5t7kdx34kuyd", - "account_number": 328, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos125334yspnrcgu7es23745xr4wtmrzyh8m8vmj0", - "public_key": "", - "account_number": 314, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos124wz6pnykadgf3xchp6rdn9s2t9z5sgvl7597p", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Azj9nQ8PMNc1EUjCsrqjftz3BsDfek5OpTnrwVyg1eEd" - }, - "account_number": "417", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "9716215648" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383801826", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos12k9kcewq2045n20vsa0u5a9m98k4se0rxtacum", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ap8/jibKZnaT7unNngjC7qEEWQjppSyeapgCiB3ZQHvd" - }, - "account_number": "803", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "15501591516" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382586898", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12k6u60mgp8wldpz2xs2u3p3skmghtrjy97vmdj", - "public_key": "cosmospub1addwnpepqgm73g3mrpuk5y0aykvt6zmtpassp8qwu5r4hxrlw8umkqdw6wk5kuhc9wj", - "account_number": 672, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos12eynrdzx2jqz5u92hgmhl9ga6hmghqfv0xvns8", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A2Mo014lcxun5LW4JFcr143pe9hx6df2oF0BEWvcLNOY" - }, - "account_number": "254", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "24469943486" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585072" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos12marehfknnseqtft88ut8gehf0lvcun3mymcme", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A147Q2xV6l1SrBZXjIZ4cyGbbPXlEZ5AktcTNsppXCid" - }, - "account_number": "740", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "7494827222" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382591926", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos12ud83clhrm4jemkal6v0489e0cdm8x0ltwyqts", - "public_key": "cosmospub1addwnpepqdlvalhvj0k0kqflaruuvyxjndwjaepha9wm0mphnauaf4tpjy0rzyczp64", - "account_number": 1, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1tqk0l38afmllffqs7g3uqaanhwpksytxtgnlj2", - "public_key": "", - "account_number": 785, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1tpxdvj93x9rqz89zhh0tszegcwtq8mgtdknrw5", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ap1j5426j9zyzWTU5VGvI5sBiIwNCmgfRcluVjeV+4uK" - }, - "account_number": "691", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "14879386908" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382848155" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1tzz5l8sw05e0tm5l0gxuvp04qt42stu3kqwf4s", - "public_key": "cosmospub1addwnpepq0y2whh2mx9stzswaxevw5ku8aznuvf0dgaznc4z8wz6fc4ahy35c8q3raa", - "account_number": 871, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1tzgwtuyftq8f686z0d8zvyqh37la70pje3nmxt", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmKe1SE909I8d4eHBddzniyrRbQk1uPJbqqZBNJ1TqST" - }, - "account_number": "326", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "2581389113" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382593904", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1tzt5ayvd6xpwxfcsxawlleluwylr2dhl46qvw2", - "public_key": null, - "account_number": "437", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "20205645171" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585819", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1tz087eh88lqkesr77yl6ys9dw95qysfqtff52a", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Azr+n7uWbLcSFxSZE6dNdTjurOe0MOPGtkxerQ6WhP3k" - }, - "account_number": "734", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "18343845903" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251385002878", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1trfuwl660334tfu6d8lvjhhqlgfnhgwav5udhj", - "public_key": "cosmospub1addwnpepq0t6u9e52u3cm4kjgwrevgnvrehpk7rlrkwr7nt4695992urhzszq5j2j60", - "account_number": 376, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1trs75ceuvsg83y9dje9k79em4v684dm5e9ya49", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmQCn3QqnDymqOAVEp7SCv0KocBIKLDUpwZhAUNd20Ad" - }, - "account_number": "300", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "10185014984" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382918000", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1trkrhq6mxwktf24u8jepelvumpd9l6lex7cls5", - "public_key": "cosmospub1addwnpepqwaasup2t793yav36hdag76kxr7rwsx9azvlh7xvk0ph5c9kjdf4crxhjw8", - "account_number": 336, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ModuleAccount", - "value": { - "address": "cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r", - "public_key": "", - "account_number": 919, - "sequence": 0, - "name": "not_bonded_tokens_pool", - "permissions": [ - "burner", - "staking" - ] - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1ty5s8h0gwtc285mnxwq43cyt2s58g25gcmq0mg", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmWA6VhM8/EeFMfoDozk2mTaQlK1h1X0gwDWIKdRPe0g" - }, - "account_number": "466", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "23893202797" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382588916" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1t929u2r8p5vtvuwn390l506achd08udrwx4ah3", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AjAT5cAoiL9fVbOrnh3CTH3LG1RN3VPToI/SQz6d9Thm" - }, - "account_number": "366", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "13256822165" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382594619" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1t9wtmy7958scpjw6dwdvqwlrnjaglqqk90lds7", - "public_key": "cosmospub1addwnpepqfmytfwgk0ys49ezxq0e2rm54nkdg4m0eelhzzxrctpp2use3yuzvgz3h66", - "account_number": 825, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1t87pn4cjpdy0pwtk5hut30pw9jd7sweduf8c75", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmUHAd9eiYf8eNk7l4QE7omwc6to0F5xJi13oMUuMART" - }, - "account_number": "809", - "sequence": "8", - "original_vesting": [ - { - "denom": "stake", - "amount": "20808467107" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382595226" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1tgghhdcxdgxay7hp2p0lv2fs656c4c0xfzlga5", - "public_key": "cosmospub1addwnpepqvvxtcls2a9qfjq04usrzv3ekvavu52z7twu9w3fguenpjett5zpwxkm7tu", - "account_number": 769, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1tftatt0lp0v59qqf449pdqar8w3yj7n7xa7sk6", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ao+yY177yX3OepqYA98bD02YI+QgEHVTkkDM1Zepd+CT" - }, - "account_number": "464", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "17454582252" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383830804", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1t2uupuuf6p4xr0szwsz47gn682kw64m9wmnewf", - "public_key": "", - "account_number": 387, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1tv8x2sctvryfspc68rypwrld99099hvrh8vxz6", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AipxECoVjWqt1VbbShVOcA7o6kMPZ6WlbzGmqPzZFKkN" - }, - "account_number": "637", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "14179685715" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384578094" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1twyey6dyu57e7p8lahwgr9ql2pyn6774e5tze5", - "public_key": "cosmospub1addwnpepqfjk3l28hkcd6jl265j6aypx77uqhm4hjwq6j75klu4apy6gl6ze76q09g0", - "account_number": 0, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1twg3k83aluz6nsqt09pa246rg5wg6fhwucyfdx", - "public_key": "cosmospub1addwnpepqgzjwcddk2z8kmnvgh2yyftgqknzry0cp2f9g7tlprezsj3p8yupxad64eh", - "account_number": 23, - "sequence": 10 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1twu2lvgp3erk6gups2a8nae3jdahaj2xmlufsa", - "public_key": "cosmospub1addwnpepqvwyxdzdufg3jnzyvf555yqtl2jegtnw0vsgxnzuzs4sfkssluj2z458ulk", - "account_number": 126, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1t0m9uvcqa3w09srgy3z6725mpj2kcxkk356k7z", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AlX7l1HcFN/NiwUPrGARgFfm57hNdESUcb1Fn0GrCCdV" - }, - "account_number": "394", - "sequence": "7", - "original_vesting": [ - { - "denom": "stake", - "amount": "13933984019" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382770570", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1tsmp448mysp6vr09f26ee7wa02vpcpppk3jgqf", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A7035NUmOTlfGRb2GGWdKSZUDlFfFK7pdICGJJMCAwk3" - }, - "account_number": "432", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "1773996319" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384218521", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1tnh79aat8d4m82pfm7gqa0z5kzzh7zty559v3p", - "public_key": "cosmospub1addwnpepq2ds07np87tqeageh7p5pv7vyfcg3qmand5ne2rv63086zr5f47ng28yvv2", - "account_number": 150, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1t5qg5zwaq20drkrxt5flzlzfrwhmtyj7d643nh", - "public_key": "cosmospub1addwnpepqdkk554j5yr0k2zccktrddk8hvk8s3ce5gqwy0esx605s9jc22tu6552hsf", - "account_number": 72, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1t58fj97xgxsvsyn89lc75hd0naa6v6c0c340cv", - "public_key": "cosmospub1addwnpepq25nespfkz7h9g9pefln8qmftkawz4mxedfmwtrjqj2dtlxfclj9qfgznr8", - "account_number": 676, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1tczlc2ruuvetu9w9rq9ka0v7va00ye9vsyxf37", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ArC7nT8HQpvzAZjWYoH2BiYGjflULiIRZyFtaqZrp5uh" - }, - "account_number": "310", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "519941039" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383513574" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1tcaxfulvlrwt9ua2f4hrfpx6wvymwxksnurv3m", - "public_key": "cosmospub1addwnpepqtpk9wdpkuz96ravz5nqvwavwfzfc032clfafxqypm7x3lhc8x532tj5cw7", - "account_number": 781, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1terlqq72gje366346skcmzfgg4lqypf50zfw3y", - "public_key": "cosmospub1addwnpepqtqquf3fwchpue55dfahx3kyzlgld7qk8xh9e8qvvw0suy9pdjwswd52tns", - "account_number": 15, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1tev427ee36jl7akdy26wu09vdt7kgp85y7l8je", - "public_key": "cosmospub1addwnpepqdle8tezdjw3eyrzypex6335tna26ekqqaptxr4pjfmjfauuujcs7fytzuw", - "account_number": 854, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1t6k46y53tkcjvdttujt542pcfrwanw0fw8pm26", - "public_key": "cosmospub1addwnpepq29upz6t90uzgm7ftsh3twkqaq3znxukl0t68zzvfyfy292w3te9z92ukaj", - "account_number": 234, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1tmddg4wjnj38wrd8t6xq092jyw3x4hcup6n00u", - "public_key": "cosmospub1addwnpepqt5fpnmky0a402kgyu04yww96a839ydaxaakw75da6xq6n2d8evcunrt0vd", - "account_number": 264, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1tumqllzfwyg69qwm5rh23rcmz7pjc84axn9v0s", - "public_key": "cosmospub1addwnpepq206cdqqkhuqmwg0nhyh5k8e9wyqgvlwvpcxn2w4x8fzmc5upx3r5ey49xz", - "account_number": 844, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1taucnwfqfkpq6c6y345j6h8jt5fffgla5ytcqm", - "public_key": "cosmospub1addwnpepq2xfwql2mfn00plsgpteeg7czv2r4jp3yd6d0x5ejw3nm2jwlme6vtdghex", - "account_number": 145, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1t7wt4qjfsa4kncvvya5m99mq0m53n9e83zunpx", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ai5f182dWvLbRv2dydeEs/xtF8XHVD3qU+CaPLeP2eK1" - }, - "account_number": "729", - "sequence": "10", - "original_vesting": [ - { - "denom": "stake", - "amount": "262606423" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382608974" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1t7m8vs498jhd3jnsxxg33lk37uacc2n50j3dcm", - "public_key": "cosmospub1addwnpepqfzsv864d6pzxm7jr4fnjd0u74phhasnmhne8tp9xk2nwu9j0m7rz4jp06q", - "account_number": 569, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1tl9mmfa626vgrsz3plpr42cmeqcn2zugg523y3", - "public_key": "cosmospub1addwnpepqdjd5xt0z7jup7zfplqtzplltrfp0yzydef3sqjwlfnrz3v8hpkzz4f8q4c", - "account_number": 503, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1vqm5fdsflvnee33gk3d5pz7j6tf6dsp28eemcq", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AowkUjoD82gwzVKL4mCYWlwdG8Oz3A01++D+2NdYlD1N" - }, - "account_number": "879", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "19841569559" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384588704", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vpnmy3wsyx04tan3x80c5js8ws5slhpkmflxqt", - "public_key": "cosmospub1addwnpepqdazuvwg72zd5mg4lf9mf9eyj7flqcmsw4a03283v0wssdljlj607u89kvm", - "account_number": 378, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vp5qy8nvwavthpk6lxx9fcxtsuaq6vqplew9xd", - "public_key": "cosmospub1addwnpepqflsm7achydcfh2ajnk9d3r4p2ckuphgyw9chrquhyy4xhcct8jc7ecf7cs", - "account_number": 5, - "sequence": 10 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vpc637uayw7rm4a48cuzuynvu9yse45me0jdmr", - "public_key": "", - "account_number": 441, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vpensuylw0rg7f6pnx7qm0acs3tmqgv485faen", - "public_key": "cosmospub1addwnpepqddgkww76904d4ggeshu7m9t68446zgfnj3tlrxr0eut858j5sd72pk84x0", - "account_number": 488, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1v9frpsrct2tplfv0r2en28wh8le3f9chavr65w", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A44TlZCS+L6J85oBykDfkToRNlPYKqqfUU7PxUKn8CTF" - }, - "account_number": "749", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "21342460274" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382608947", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1v9k0h7s32ujfeu777jkc7z69gctz4zwfy7q49l", - "public_key": "cosmospub1addwnpepqd2me5dmymmpsqz4yyfu0x5rturv3ka5v3ld5xqgf95l07mrpn78kp2dxdn", - "account_number": 439, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vx0z58vgegsfc8e56jzmjtvj8cvprywvnm7l9j", - "public_key": "cosmospub1addwnpepqdhksqqmv2sx6yefnz7p8rxmjr0mxpvn34hquj39zk3hegu3e4adg3umw94", - "account_number": 858, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1v8rh7yfvv24sryauav5dc7ck4x76xgyda3yrza", - "public_key": "cosmospub1addwnpepqww4cd27af2gje0s58yu3gsj8rdvc692mu7mlvd32afwq3lrldpvzpflj3t", - "account_number": 423, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vgl6kc9qwpk0r0fqegp4yg5ywjdf66s4ck7le9", - "public_key": "cosmospub1addwnpepqtwa75757pdjk3qtnzwm8hk3v8l06ckp7hpgzmdhjlcew6g86vag777eg3w", - "account_number": 160, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vf0r0fg74jmm6qxq4dj8amhr64acs32333ua0d", - "public_key": "", - "account_number": 313, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1vfcm9c4psqrkv9zecgjw7zxvw2jnpe730766e6", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AurdZLpQgZkDkZZIEQfVfOttKMvKgTkdQHxIo7NOtC5M" - }, - "account_number": "283", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "6911431250" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382591085" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vfect9js0f8535fas4ly6waxvavc2s92ny3w8q", - "public_key": "cosmospub1addwnpepqfs8twrdeftqq3tvq55hq9mxn0duh577l043csvdjhxefl97p3aqqm8l0az", - "account_number": 519, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vtqnkp3uat764qv4z02qwc7ysnre8q9ph5kklc", - "public_key": "cosmospub1addwnpepqf40773hc9w2fr3lxtxtxf0p94apylv7tr98lwnjfekfw83psmyr2dkcj4s", - "account_number": 270, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vwgt6t9vd9heg0jwq6gk0x7egw4cmp4w79yuyy", - "public_key": "cosmospub1addwnpepqwczxz60gwaq5z3ncfgjnc79uzx2ckz924q06h8gqtl3j0q0drq4z003fse", - "account_number": 654, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vw3dl2j248ypyvvjfu7036hlup5p2gpwgvg7qd", - "public_key": "", - "account_number": 876, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vwja3gc3e37f8fkddj38gp74cs7sccnf4zs509", - "public_key": "cosmospub1addwnpepq200h9jck2lup7rttjujqt7scyy8ekwyjpmv7dery4ple6hmer9auwxgrec", - "account_number": 273, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1v08dcmtc5f444sxqfvqv8mxdclmc27592searv", - "public_key": "cosmospub1addwnpepqvkllp9u9v05plyvdmyftgwv96a87j477397tyyrkj50cnaanygrs6gluhk", - "account_number": 826, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vsuhkup8jznqt89zgv9nw8c3u3a7l3u87cr7mg", - "public_key": "cosmospub1addwnpepqwzlpddjj0258jwj7lgz5pagup2v4d36y4e5uxjt28wxr7yl4fv4crrgfgf", - "account_number": 224, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1vsa4xamvkswn3n65ef7jjzldxqy0p5jr97x0uq", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AnqMdbDtIKZmdsZDJcnnG2c7H8G7RfdD9UF6y1ufIbTB" - }, - "account_number": "881", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "11384887844" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251385084522" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vjj3g3vkh56g04yqqsdn0yxcul9pve2r6gjq8v", - "public_key": "cosmospub1addwnpepqvz55wnnaw48qrudyvxm2np0px6xma93kxc0zh8va6xf9ekz7k8nsmdvzrn", - "account_number": 92, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1vjm2s6e2mu4v08mluhgry9chyewhtd2cm79j5s", - "public_key": "", - "account_number": 824, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1vnceu3qp3cw2qjq3jqmvfgwgv50y4yze7fe22y", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxTXojEjRNN1xkFYCeh492aag5NfI989QKHZOXgyLg5b" - }, - "account_number": "658", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "7490727045" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382616571", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1v4tnxaxwtfjm0ctu0mu5vazqvx46d5s8gephq7", - "public_key": "cosmospub1addwnpepqtz2yyz3e387xqn4wjglqvjz2phhnw0f09rrhgff8gtlpvnhc5ygwxz3zf0", - "account_number": 94, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1vej5grhtwzmyd6jyktnfucjvm6x2eeqhjvem76", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AoIYnmm0/M/CJU71deWNtYv5Ar2usqQY6XdDeT4Kzm4k" - }, - "account_number": "335", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "17590970270" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383129090", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1vmvwvumaa496wtckezlp52e5lzen7vgwt5834j", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AiYjN/mWbI4vtAgsnFMGG+Fb20NpQD3LHrweaQn6QtzW" - }, - "account_number": "500", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "7346895419" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382984377" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1vuws77sz0xzvz8y0dg6wjz9fzd7plxpk29ljn7", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A1b6pdzyag9jHjYWMWpuP0KtOlGQkF9jnSLM6HsjR1Vl" - }, - "account_number": "760", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "23297021045" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382596851" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1vlvxlpzzrk5eye9c3z9uedk0085h7fdvehv32n", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A9+I461saOCOXdZSaeZQa3xJU1POKl3i9qtgNQojYJwy" - }, - "account_number": "655", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "20596731311" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382611750", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1vlk4n5np4lzzg3f0ygjwgn7t5djezk8kj0yfkr", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ArmVhXiDis5pLZE1SzVKQpdXCMHkTs/HG6f8NrLlySKB" - }, - "account_number": "421", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "2652386103" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383053641" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1dqy85v6mhztkrd72t5f05xgt2e28c3fmgardfz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AsMvlkLMd92d31yc4RrnuuuSEs2/ngLui8L92I0cVn3z" - }, - "account_number": "315", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "7735735418" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382612123", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dqukz2u9cssszcudyrjxzf47aeydmfardn09hw", - "public_key": "cosmospub1addwnpepqt95d8pk0f3dgfh0zteuqa6adrpskp2m4krf47jzvwlmqez8287zs4lvkdd", - "account_number": 277, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", - "public_key": "cosmospub1addwnpepqf407jnnxg4tr9g6yffgl3fddzeqq4w2f7y643pqnta3u2lcg249qjqweyp", - "account_number": 50, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dywwlckrglrq4kr0xlpcmcxgshghwht5hs7es7", - "public_key": "cosmospub1addwnpepqgdne4suza7cv9aspke30rvuwyqpd07ns2s5jcfnskyfvafygyyhqenkvav", - "account_number": 401, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1d9cqjx7xh2j23utvyrns2kgtz4w8e694vqw6h6", - "public_key": "cosmospub1addwnpepqdv2p7tyn8u7apd8g9nu37t69hrw9zat3uf92v5y9y9ku4kyns4f5xklu5t", - "account_number": 451, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1d9m3l8khcrx0zhftehkuw67zzszf9v9le5dvrm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AvMEuEw6ZuuyqjDAkqK0I6kuF8HTCxdwK24Jn+HwyL+b" - }, - "account_number": "801", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "14002405995" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384896507" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1dgzvesl67z96ttlt5ulga25phe8pnspt663dvr", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwH0Mt7qKQjcKQc10ncPMlj8mV17x6KWs77SfDR7+gg8" - }, - "account_number": "458", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "13826121764" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383829848" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1dge9en6j6xl3njpkk8gvw9n326pgna44akw32s", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ArIASLNFB8KL32lADVk/kLlGPGG5UXehNBENWS8P6uOE" - }, - "account_number": "908", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "10017074133" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382617614", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AzWlQF+NPXzTcon71qE/CtsiRi0lgdrIuNnrlufNhviT" - }, - "account_number": "877", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "8818079614" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382761706" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dtdk5uytf6kv668r6l6d6cf947mdu38f9sfdan", - "public_key": "cosmospub1addwnpepqfd2hn4egt5wkl52xsd0lhmfzut50w5c0pwf64n5y5vf33dt2m5kwrt7mj2", - "account_number": 178, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dvav9u8d2a4j8f9salk7kk6pz0aa7e07axp9jv", - "public_key": "cosmospub1addwnpepqf558mk5ff9u9tx0nq76pfgenl6lzddnddywjsy9m5dq6hz9peqj6savc4y", - "account_number": 511, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dwha0rccawlvhudcgdpzcf3eq2c0gqyzwctms8", - "public_key": "cosmospub1addwnpepqgmhvev79eltw87wpn44627waqanjhx882xl0a37s0f0tz3fjuz825vctth", - "account_number": 543, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1d0vmvut9ezxmv9wj0zqeaxtacasxp55u04hzjh", - "public_key": "cosmospub1addwnpepqwfxtmquurmzgwsxl8fjzlglw489hnrulfvcc29xqtmxwf9m9tr4vlvj8ul", - "account_number": 634, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1d0dq8hxzyywrcx73v4z44e8p8685znzml58dg2", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AhdwJ3lW5Xw56g5hBuihqu4nXjhCtCLSHSDD0ewatuU3" - }, - "account_number": "422", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "18610536319" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384232987", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1dsq96nq0xxcvzh9x9tgxwxx2ve9qetwpdhe28d", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A7jQ8vHSMkb8JnkkDj2X7zuEqLWE1cytFeQuXwYnVYHU" - }, - "account_number": "308", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "21923992439" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383331802", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dn2s4tgdyjcgpcq6pfw5shzry50veuh8al8uz2", - "public_key": "cosmospub1addwnpepqt8029tmentkz533832s3sadcjs63ndh58hrtfmkarxqwlwn5f8nq6496z2", - "account_number": 84, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dnt8cpf6lwldf4r99n03kuv8fqwfqkfcy522k3", - "public_key": "cosmospub1addwnpepqtc9vugqcyl9agyk5jfajuhq55zgvrxnn3cjw375k6zdn3cw3pf0740w9kz", - "account_number": 184, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1d5vv20893q06tx29mlqmefnyf0w3hn0v07w9p9", - "public_key": "cosmospub1addwnpepqtdldypck872t677fwgapgk44dy7hhw2ghufuda3qtfzqcd8a5095lzjfjf", - "account_number": 105, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1d4jyeaslp5p85mmkxqsem6g99l67nqa6uym3c4", - "public_key": null, - "account_number": "905", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "16761520335" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382581745", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dkrlkjzv49mxcjhcvjwkx4w3m2jf2u4wnn2muz", - "public_key": "cosmospub1addwnpepq29d27xgflxpx9j63q2e9hrfcujjw3w5g89f58g94net69gx8lvcu98n2u4", - "account_number": 381, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dkwuxswrh5mx3mmmsny2qhwm4xtu33tyzv7rnm", - "public_key": "cosmospub1addwnpepqfc7v83c8h59qrg6an7ff5gngnnhm5r6a0mj4kxuq49k89yrzkw7k0s4q4n", - "account_number": 600, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dk3lge8q3vdnsn2hmmwdmeqvrfuc3v7lypeadd", - "public_key": "cosmospub1addwnpepqdwlvpljf7yyp5p7w5ns3mqkmsuaux3845kp8gtmchuxz03rn0lpj62qxw3", - "account_number": 6, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1dle2tkls5kffwdqhan4rs0dgckjxunfsagcvkp", - "public_key": "cosmospub1addwnpepqgmpcl886vmt5eddwxllr6cfvd0nskguldrcw8un7aw7zh4wusqey9q6s86", - "account_number": 226, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wpxkfcmhsmv7d5hdzx4tw9w009fd9wwj7hv682", - "public_key": "", - "account_number": 256, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1wzmzdml4fsakuyukmaa6qqee3g6w6qtcqh9jzq", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A/vXvSMx7mGCgcow9k16KGVKii27hEPzmxxndEMe8q7x" - }, - "account_number": "687", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "751349096" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382592060" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wr9032gj6t9s9schc5vnwe9kkee7qkgp26fftw", - "public_key": "cosmospub1addwnpepqgdm6qzy5flnpae5p89hkqqpkgrz5fduptejhehgj880samxct3dse8vm9j", - "account_number": 99, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wr3nyvxgsdrfcadp9f97m5fsj5f0ey56265urj", - "public_key": "cosmospub1addwnpepq27kdq0ymgtxalr5ynuy2pep0pjvq6qgwnhkce3s4qyqr638xdscz9ta2qa", - "account_number": 77, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1wy59rs74dnqqs0xz70sn2q5hyv9yrethtjx59g", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A78W4qmMI+MdXIPeBbIVGsJVlSz4ItchB3b1q86dbU8k" - }, - "account_number": "312", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "13067070201" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382611372" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1wykcmn3r389hklplushrjl43cz76djt44yuc2d", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AgvKBcI07ZFPvLLNJDJQbqoG8R02Nh+x0tt8vIrmIp83" - }, - "account_number": "630", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "18145178781" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382604285" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wxe397ys4qtk9gs96cs7e2x2malekw5fvg7jy3", - "public_key": "cosmospub1addwnpepqdgylnekrukj2u2dlx3fkexe74qyd0nqymanj0dcs0ymn53p9jrn6u4a5hs", - "account_number": 659, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wgf8vydwh6zrtyr0f9uphml5z27df8kxuwgslp", - "public_key": "cosmospub1addwnpepqfrehcj7qxnx02dvvqzwym4tfq8dr6ttextvvjznu3xkrtkq9ysfcwc2zlx", - "account_number": 255, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1wgslx9j6ct5pczy3h5rjl98yyn78r3sel0ulth", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ash8k4Ivl9y44xQcYt9AcF/OCLpWeoAOdx+Kc0zQ4I4B" - }, - "account_number": "767", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "15088034388" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382885184" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1w2vujuajxpvqtdsne0gn6j0x0y0xw3kqtj6jtu", - "public_key": "cosmospub1addwnpepqv6qrul7n98dffvgvqyfrz7pc9cy8l22pdp9g5rxn08rlaep06unck9qacd", - "account_number": 846, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1w2ly5qah2m47qguaukzr6xx34hszqh8u2j023y", - "public_key": "cosmospub1addwnpepqfxc6u7t75qnm04w78j2ngxr4mpnuqy4f3em3l6mv72kg8ezx4hyyt85lms", - "account_number": 626, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wtn9tf6wjwmwmddrk377cdl8fd96hexajyhfat", - "public_key": "cosmospub1addwnpepqw29rqhlwdtjtv265lp4yhf6mkljp6qwtjnnej4an2m6waky69sg5hg759a", - "account_number": 484, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1wvzq2f252674u3gvmqhnq8g4n6lmxedmzs0czm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ay4CwyPX1ndSFPULXseHDw1cJ1nrC0x4owYLePgoMtnx" - }, - "account_number": "333", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "1828902041" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382617707", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1wve3m263mdhqqpg0yjd8vmveflugrk5dk2cr0z", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A54OIQScAyF3FhxPLgIa3a9WKWLcZYXX7xdo2Rsvufs6" - }, - "account_number": "573", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "15733791808" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382583599", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1wdm9ge7hjzrlh2epwtwu3nsunfd2r7alqhc7r2", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Am+EQXaMi5T77tJgY85EBCia8tD8pG4n+osQNbv+LvPN" - }, - "account_number": "588", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "23969763741" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384645927" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wwp7j40k9xffj757s4uurkcegskfwq25ef268l", - "public_key": "cosmospub1addwnpepqdq5f9adw92h3mgmnaq3u9ykqy6stmq5f5whhlfjgcdlkcujyn3f7l5u8sz", - "account_number": 420, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1w0050eew8g7zyvg7ap0tjhd6yzvew3ndls3v0f", - "public_key": null, - "account_number": "572", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "3345569032" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383342154" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1w0j4ecghl96s9xayk967z4hnrxlsfht7rawmrc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ApvN0yhzxk+rIKuEJFRERLBLPo+VDQ7FMP7v6XoL4ckb" - }, - "account_number": "518", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "12298589295" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383364879" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wnn8xrn46u6ryq4kqf7tcf650fe2gl57d3gg3s", - "public_key": "cosmospub1addwnpepqw75cz3m4fjwdg86527th3jlyqdu2jrfxjk764spx7jlkq5j6p7jqkm6d7a", - "account_number": 10, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wnu44nwfn43e66cgm6kqyxurhytzxkp0c7yq2r", - "public_key": "cosmospub1addwnpepqvlz0fenag3kgjcp0c0qrwyjhrxfxg9ers6mfje4lha7c3hk2qdg67f7qk2", - "account_number": 735, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wkt8xe20zdph4ak9vqx2supe3v2gq3wyje2jnt", - "public_key": "cosmospub1addwnpepqg2887df2cynsehyycldy24y3a4sps3m4w8gmrdfuvw4h9hrc7555nrvedp", - "account_number": 14, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wc5kgetgqtfmjz9v87d9epwhlne2we0lzd8qn6", - "public_key": "", - "account_number": 496, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1w69f6s0dqsqfqq93hczddadwgeq86zr9dfmddq", - "public_key": "cosmospub1addwnpepqdutk576dwhq7zcc6g2nc3m0ys67pzqzn4rrwkhmxlg03pzn8ynrq7tayw0", - "account_number": 869, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1wmq3vxnh6tn2x54tfa9xhj0aaxuz7ka3fy3txq", - "public_key": "cosmospub1addwnpepqvw6v2zt94l5n72h6zknmqaqfvd7wukulply3538dejpux9ujtwru3xljda", - "account_number": 45, - "sequence": 9 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1waql7pehyspkf8l9q04gt508c0khx0nt64jsxj", - "public_key": "cosmospub1addwnpepq08t54wd3776kxjrtqewrlnl3ag6mxhvye4ksq2dr7gtd7g2hd03w6g0u30", - "account_number": 779, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1w7vdr6ccvyacjgesypy4xqjaxlhh7kcc5e2726", - "public_key": "cosmospub1addwnpepqtf9tfhe40sv84mfh95z0fxa243e5zlnfvym5nhfz30uc2ll6xmj6zgrjwu", - "account_number": 492, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos10qgdg2qynlsl0nff0cd9renqv2tzd0f5kmvs4s", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ApAwJ3zthZs8uszhi/blGaA/UIya+5WtCCBoOqeNT7Xe" - }, - "account_number": "707", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "8589454947" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382617815", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos10qj9cj3dxecyu826gaw72ylwum96jkkh9p462q", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A94DBB9xHh0Qq/qiTnkh5Sn7imbsbjuyHN91f3+VxHNr" - }, - "account_number": "369", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "5251905003" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382599091", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos10qernplwz439sjmxwllhpp4sujq6a9r0rqdee2", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A+Wbfz0iayZ/gH7gwFolsN8Kakj2LlTV1+x5/ZF/C3LI" - }, - "account_number": "733", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "13161760877" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384119950" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10p78pcqm2slk4x0pfxl9ht5spskwquhzptwzt8", - "public_key": "cosmospub1addwnpepqgsfa58j33rwe9qghpdwlvh556pl2pman9k3r39vcwvlc3htu8l5xqau3jj", - "account_number": 578, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos10rqahajykyr5fjzf393tg34vmph05ygwj28fpy", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AnwozEWIdMnyERwHDABc+ZN6b2YssUOSEVuaR8f65kKG" - }, - "account_number": "650", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "6229875472" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382608878" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10xwf26gupjlr4xt69pl779346w7yytxhvjrjwa", - "public_key": "cosmospub1addwnpepq0dp72r2p4adzlsmg95kzs69rdhltghkjvuvmfsac3cdpunr9ctvy9w3c0w", - "account_number": 622, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10x0lg2djw0uq8qp5hgzujsu34zpreavnhmv0sc", - "public_key": "", - "account_number": 756, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10g2yfqkuyaxgyyj7hhyswh8cmhplvpanrc9tya", - "public_key": "cosmospub1addwnpepqdlqzf0gu7z7kx256zr2njnta6lyxyhvkuvazwzcpxz7nwftd84z5u7m99u", - "account_number": 772, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwvVsh/gVSExiN//lU0zlc2iYH/bCsMe9hTHmC8ZthzH" - }, - "account_number": "782", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "19683051102" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382608142" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10gu52rf3d0z0py8d0x37r058qh9fgdgg5567wd", - "public_key": "cosmospub1addwnpepqtf0w9jhj62kmqlw6wcev8rrvpmrflkllv2ued2rquhkpg5yj8lxk5f8388", - "account_number": 203, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos102sgufwszag3yuhtzcftpyvc8jqtqske4xug7d", - "public_key": "cosmospub1addwnpepq0xvdglnqk4yfwsh5jz8r5v8j08a6ynzzzp960qnwxx4xnjnzfe2564xnml", - "account_number": 623, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos10t3ld5fvsvy7kye7p409he8dk5q23tep5mn8hj", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A0LmGIJ7XruOl3eV+DusqtqeOshIJNlbroFKSrXUSKeE" - }, - "account_number": "528", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "15675936208" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382589769", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ModuleAccount", - "value": { - "address": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn", - "public_key": "", - "account_number": 920, - "sequence": 0, - "name": "gov", - "permissions": [ - "burner" - ] - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10d3vd6yx9k9ns6v82r4krm3d4ragw04cysm62c", - "public_key": "cosmospub1addwnpepqtndwvyp0hczl37xh8z2kg32d5jfzkagkdh5mhnfrcemedgavsdaujv5560", - "account_number": 130, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos100n7juhwat88nkufshpadznw5fe5l3ew50936v", - "public_key": "cosmospub1addwnpepq22jjjqgknexwz2kx3cv78gjktd2sqecy0qy64a5ytw8zl3648cwuep85s0", - "account_number": 564, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10jgkuly673ukhgeeu95dte84wm7cwtk2zjpuhc", - "public_key": "cosmospub1addwnpepqf3e3e79cz6a8a5ej2sup5a6gr8qjke6y4munem0amzs953pdee6qfnwdk7", - "account_number": 248, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10ndcqfr2zwrspryphtuhq883kc49z38flvpx2x", - "public_key": "cosmospub1addwnpepq2y3kj4vhmzue7mqncfd7q98j62a3kcey0mz6faen6sqxeew447lgpx3tgl", - "account_number": 836, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos105wkwqdhq8tquat285v7u24q37nnxqflz0qx8z", - "public_key": "cosmospub1addwnpepq24753jujgdgdlncfnw6shcvtkk6skjp2wv8guwenwp9uck6083sccsld7f", - "account_number": 863, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10572shcaewknpzsj6nnrruww0049hnmjymva38", - "public_key": "cosmospub1addwnpepqdxnhkarz06ut8ar22x3d5t4g9l02k52mr6ea8eux2c80u6hyhltg4069r4", - "account_number": 778, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos104v634ezzajvzu3x8r9q9uhz4dd9xm6f2g3qaj", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A6mhcWo6xqfBFgTMZP+CPpZhMAY+xtF0tXdBy9do+lv/" - }, - "account_number": "883", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "7247997772" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382584887" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10ke8m795c8svtt2h24n6dad2xp9a8mevtx3cdj", - "public_key": "cosmospub1addwnpepqf4eys884495jxdra6k9jqdps582ftj6cp8mjyxws7w6nrxxlhpp7x5laf5", - "account_number": 141, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos10kmduud4gcmgkl9vuxff6ztp8qcnl8kzklv4sa", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ArBnfanvlcuSmcQR5PUiwbkuJmc1KHplecftniqS6wnL" - }, - "account_number": "562", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "21929317327" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382603431" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10cl6sallgwf882apcyagjqa2lx4j8592cjw0gf", - "public_key": "cosmospub1addwnpepq0sra5mkmllmenj9ymu00ky4wcpwtanyldal7xt3chkm6ksnnhvvjamcetx", - "account_number": 3, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos10ed8tmu5n2xfhtcyht4kahkmzqaxk2u7ks7k9u", - "public_key": "cosmospub1addwnpepqgjs6fuam9stnrwxnjtmqravghgs8gxvfnt6z240p3pn2f7elrr0utpc349", - "account_number": 875, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos10ajx4nktldvyukmjdrx876mmwazd5sz860eu6p", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AoxBNp02bKLC8a0eUfaly+uW5t36siQ6GviNj6df8Bm5" - }, - "account_number": "794", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "13653383216" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382587751", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "public_key": "cosmospub1addwnpepqv4npjdnld89s2n5t07xflzktdzfdhugg8uels3phsa4asz6f7cvye3pyuc", - "account_number": 190, - "sequence": 9 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AnXszHhNrHRNZUurODZV8JfS4hqXBqX2aknGM8LMwK/M" - }, - "account_number": "684", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "22584764663" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382597248", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sr6u63sxsprpzv7tedc7e88tn6elrxkjnucszy", - "public_key": "cosmospub1addwnpepq0p07qsysalkdawpfwskzp67z557yf7y0cypg4xm2nk7m6w3ukk4c8vqgh2", - "account_number": 887, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1syn6uv0ma6a0qn6n8gy6qrc7jdp8ghr6vva3jn", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Az2ky9RifL2XOzp+Bzc7VEVYaoAR+ACs24AbypS8g1zs" - }, - "account_number": "555", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "5422012300" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382609871", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sx6zljj8wum2q942vntunudnq7uqywjp737s7a", - "public_key": "cosmospub1addwnpepqf22js8fjl3t24zekqtuvly44vzllatz5d5rfzlzh6ppmqf5txff548tlqg", - "account_number": 489, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sxmqgulmqw6nxw4f9lxt565hzyj246nj57uw8j", - "public_key": "cosmospub1addwnpepqwuedf7e0zcvjs855v4xqlg4fyedmwau9cjx6085hehcu93q79peg8z4rdj", - "account_number": 221, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1s8c3pza7vnx7e62k94z5jgx5jqtfh7ux2wh592", - "public_key": "", - "account_number": 790, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sgtd0affxylfrgz234cj9ywnw6525y6xqwsxze", - "public_key": "cosmospub1addwnpepq2wk8yhzl32d4k0w4ufp77gjpn0anll27ymgsu6f02606xeg3puqwdgw354", - "account_number": 243, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sgj2stu89zswe28gqh46gv8sp6reppxc9addtd", - "public_key": "cosmospub1addwnpepq2knku3h43s5ch3duw9pkm7g3udyhhgr8jjmve944h5z883r0jaly5vqakm", - "account_number": 323, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1sf8sh4chfvczkme5pahqstcu76uysz2674ey0q", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A9Il9diF3yAkSz8acC0t4w4oNbAazq+M2ux8+E6TcDPF" - }, - "account_number": "491", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "6277382244" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382582455", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sfewn0rgaw0fqw8lks6ygek6ulmcy3nmyuvcgx", - "public_key": "cosmospub1addwnpepqd76980jyxlezsdfpr4nwaahyuge8958rjpwz7lp7f0shjj445vkq65wqwx", - "account_number": 17, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1s28wuj4yrqsmjm2cckx6mu037e92up2mmfknxe", - "public_key": "cosmospub1addwnpepqt4tjcwnv8z49jyfmwgp4wwntnfwlt8met08tp86r5kq5uu62lmwxdxgqxn", - "account_number": 223, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1stvzt8re3hz8dme2gscrjxzyx9hcefvhjtvuzh", - "public_key": "cosmospub1addwnpepqvreza8nm7mppsynlkqqegvltdg0k2duvq4vcl82x0hupet5y5hg28h7ztx", - "account_number": 907, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1svzznavdqmklwjyxfhaa5sfz690d6339c0726f", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AhLXZ7/r118poYZPhXdb+jfmgR43S4vQk73bIKDbQu68" - }, - "account_number": "706", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "3069440430" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382606774" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1sd0jepmznzu54wy89g022t34rchk2wd2apktwp", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A/06ypUeMNWq1Q0Q6kn9q/jaOFf6EuWpOwcCvoy1WA1o" - }, - "account_number": "556", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "13842188728" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382606518", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1s0r2g8pzwre6tvywfw0h8vy8qg7spd2ytfkx70", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AiCdK75l3e6uP6o36ZSYfbK7u/rJJNq3qnN0+WIyVDFt" - }, - "account_number": "731", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "22598592720" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382622064", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1s30d8tgwhwavwtvanggkj92quj8ucecy3c9mz7", - "public_key": "cosmospub1addwnpepqvd0z62pd2t729vejwmwjctg3ej903rq5qlf7ljm0ecv69efduc8wa93s3h", - "account_number": 149, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1s34kukvsrdgap0pjh0alnql7vvv9m83m2628wd", - "public_key": "cosmospub1addwnpepqgt5lvqw32z2z8wtgskc0gs6wl42agj8p8sjl4rnpkrmrqyy9cagcvdaee8", - "account_number": 278, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sjg96xpaa2cayeym6w3a2t38n7gm9zcsrzj0gk", - "public_key": "cosmospub1addwnpepqgtqlt7ucs3nxwwc47qmc03sehv59ttyqhsd537upgtc20ylarm3ujsgmh2", - "account_number": 232, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sjhhg2yl2cqszte7pjyrp6lx5tg383lrpjyq0m", - "public_key": "cosmospub1addwnpepqv5ftrlcygdxuvv8e8y3ysc069rjgsmgm5467vralwgu6agk60eh7nnm2nh", - "account_number": 128, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1snewspdc9kfseux88dqd004g48k9f08p24rucz", - "public_key": "cosmospub1addwnpepqv9h32mkjsyhnv6tqahp659wm0dc20p32t8yr8lqexcvf6xac8ayqlf5dkj", - "account_number": 403, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sc26mz3pwry0wm9yynh6w02ypx6k6ckpsjgjr2", - "public_key": "", - "account_number": 791, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1seq3r2t3gzvv422nsy9m7fjvjywx57q3nftf68", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A3fXD1TGkcSUYF1Rwty9yXtI+it9JK8opCdaxukUQajB" - }, - "account_number": "849", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "19422922015" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382862080" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1sed5gwrv6g8x0pwddqmat3nffg66fwkdp0leyj", - "public_key": "cosmospub1addwnpepqf0wrcap4980h90m65rv3pqwfal4gyy0qt8us030hjxhla2t65jlq2k3wfr", - "account_number": 736, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1s6sl7pyvn33lptf7edmux0gex06ffzjzkcd7l3", - "public_key": "cosmospub1addwnpepqtf0llsm7dtlevrxtfn2qn4wc7wy32mhxsfseyxptpnvmkp9zvum7pmadqw", - "account_number": 204, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1smkdl46ly7zg2v5adsvzhnf0sgxvxwmcakyzgc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A+R7Lpnmp7i3qEIYLcrKmMaS4hxvRl347i+v7G6w50S1" - }, - "account_number": "490", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "4430737307" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383235576" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1sugh75fnvl48jyt6ya59vn9fv74qqkkcf7l4ee", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5LHrX+dAgBezT63XkkVHToc690K/BSSlYzpJFaVo7uZ" - }, - "account_number": "889", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "17299124236" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383197493", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1s728ea54m9u76dkd4x9ea3l5cvjjjkk5u03wg7", - "public_key": "cosmospub1addwnpepq0kzzpw5g9xn2d6zd2tnarw362fwfvt0evc9gq55lru2xfnw5sum2rq5p58", - "account_number": 40, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1s7e8ukt3awex0xh6qw27pramwg3hkgeqtm0nfs", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A4HVxlqlm5YkKlwFHk+iGR2OBjL6huaHlsWmIysb46Kg" - }, - "account_number": "664", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "270491061" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382613690", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13q5vwanrgz5ff2f6y07c9236xj4ergak73hgrt", - "public_key": "cosmospub1addwnpepqwg6cat6uz2sy8dvkgwt443qv85dz6wjmsln2j9qqm6zgkwuw5anwf8w3uz", - "account_number": 263, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos13ps0cszg8lqn0mkzndvhxwaew8yd56s8tl9j20", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxnHejxF6FccQUyn0f8LErZkBAR6PYhSxZAjawR2Nvak" - }, - "account_number": "262", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "15962416097" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585067" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13yzpngckxvtky2k25j60qxlkekx0jfau4pjhzn", - "public_key": "", - "account_number": 79, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13y2zjpgaj07umx7a3dsg9ffhpkk22g73492l53", - "public_key": "cosmospub1addwnpepqv6srnvz27xqa65mvt3p3y2zcvtsgat2a2clghnuw3s3eepfvy722q95p5h", - "account_number": 267, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13y6fzxm4933kag94elyy4jgfyhgf3jhwakccun", - "public_key": "cosmospub1addwnpepqvgjcey760f0um2fa3um38puaavry6ycvdtj55cp34cjtyg7tepnx5d2rua", - "account_number": 460, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos139yreyw4l9jthf99c896sc4q7yvx9su4a95294", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ax1Db+jKCKw59DkURrtd/16bjmIAQDf4L2yKwQC/7APR" - }, - "account_number": "359", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "14441908009" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384645608", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos139v4g5wz06vtagh95xkkjkt8nlm6krfxtn2hs3", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AuyZYDQcyRJ0HfKpphdcPD3qmwaaBoUJORi7VzMhVmfr" - }, - "account_number": "245", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "4009366611" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382580773" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13x5pze8uxrt4ea9jmskzdl8j3avc03n2h0xwq9", - "public_key": "cosmospub1addwnpepqd8ua2f60nuxkgxqguncxzce8vmhdkmxgfcvz323jg9dq73w9gkhvns6ngl", - "account_number": 392, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos13xm9km2se2am890j398ttvyjhuh8zndwr2p68d", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A/HEUS7Q9hhXFh/QMN7Jkqh+AzLKvFObvoj2NbMYg+4e" - }, - "account_number": "568", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "258737406" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383411850" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos138cypx3g3puv720atyg9x9dvap8k52y0c09myu", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkLZJW43lOu3n+L5b+F6uEyvLZZJYV9SSpXk8Nz9h+3A" - }, - "account_number": "839", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "24830896918" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382604634" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos138ueargdn7h3qhwdpvusu9uduacvm3934gy3cs", - "public_key": "cosmospub1addwnpepqve08ydkhjfnnlygfu3pzqgsgc66mtu5dwn68r98ayj7ygstwl2cut2jw44", - "account_number": 584, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13fyamuv3fexmuuamtgqtwkz48ynl3hd5r0ukh4", - "public_key": "cosmospub1addwnpepqt7gye6suu2cukhfzlegwa43nca74272f0gku3tllz4dtgnu9q05jk89krh", - "account_number": 75, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13fvz5er8rdttgtuwvcuaku00j2nw2v6kecxehj", - "public_key": "cosmospub1addwnpepqthqmutt4wrz6wjhny7vwjxk3xcphdt9s0tez5655yq80uq0d0j7yxsu44a", - "account_number": 860, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13296rs6uwadjwya2l2uc2jzxgyllcjm2pcgdma", - "public_key": "cosmospub1addwnpepqwefs34kla09tv2x5k8p5em0l0y5e854t6qar70pyn75w0klntc4cgz8s5w", - "account_number": 96, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos13t9majnryrvy3525hwzjhu3udqjldxuhrs8890", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A2lNfYgUDueEZqzd8YUzS2sbp1LIunBnLtY1flJU9EBG" - }, - "account_number": "349", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "14878144991" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384665169", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13tfk4n07c9dz5swkw7vafmlrd9e0d28fv7whga", - "public_key": "cosmospub1addwnpepq0ksfhsq3ys2qxhx6w3gxz3jmeejemnncxvmy2ck7er286hruvtvqn5y0zh", - "account_number": 83, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", - "public_key": "cosmospub1addwnpepqghsxshh5tdsf3g9q3a0f7mdq36lcmrxcjcsw0zwx7h6mhrkqt7gx039x5h", - "account_number": 187, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos130kk7kw4kx7rfrq9sa4k673zqt3nf6s4l3a0lg", - "public_key": "cosmospub1addwnpepqglvr53h6nz2tpvjjk5zn77ul4kh6v0uhwr8cyv394nv2zskxqydxeh3t94", - "account_number": 840, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13spl9rpkd0wd9c32mpsd9h6phwwnxu3untrwtf", - "public_key": "cosmospub1addwnpepqwyktyc4e9j89pv0syud54z03g7tg9j5nx66ceq6gqf698l8h7x8gyymcsn", - "account_number": 59, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos133te0rttmtywzgexuxkdhn8yttrsar2tlvdndj", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AiMmxKGuR93Cfb0W5iv1EmrmEnUoxPKoXK39fYwNQdLH" - }, - "account_number": "648", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "23757000561" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382588717", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1333066cp52k7fgmug2dwylafnymdxcg6n4lees", - "public_key": "cosmospub1addwnpepqdx697nurv98xhevaazzerprymyt4xk428628hyzlgm4uuz6uqprsganykw", - "account_number": 36, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos13jxw6xalnpvapujvmm6mc6qn3dk4sn6k6wmgpm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Az5NSeEmREOeBfz6vS+o+T4gPixkGEdXhFLZFmPxU9+Z" - }, - "account_number": "455", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "21003040257" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382598072", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13jfnddzl23pkks9f7ahgjeqaz4pyfx43mluaa4", - "public_key": "", - "account_number": 904, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13nemj0k45u4pflkfeyey88n8u8sv4wgz8cf253", - "public_key": "cosmospub1addwnpepqv04nsutcx08nsshva6ujkage5qpjve00ap0kknl5n4mup78ulz66z0vj9h", - "account_number": 156, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos135e4v2rg4uz2767zhtdksls7n0s5eleunwdxyx", - "public_key": null, - "account_number": "855", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "1432712798" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382605010", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos13kv948cw98pdf4g2gjv9qr97rzvqxmvcyfar9y", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Aj+1jh7jpTqNnbanE2cRMCNjmOyhQg5MNq1bYsZslaLI" - }, - "account_number": "830", - "sequence": "8", - "original_vesting": [ - { - "denom": "stake", - "amount": "5838654707" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382608071" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13cydnwjmscxtqtjywk9atr9uwlm6703mwtycnr", - "public_key": "cosmospub1addwnpepqdp6ld9jqxquy4fme4prx2wt2crv0euq657776cmnss54lgts6afq835d8p", - "account_number": 368, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1369zs5htywxarh8cl6rvmzgatfql00pmvmewet", - "public_key": null, - "account_number": "577", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "2250098945" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384873115" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos136jetl40d2fmx3w0a0t2jj7zyp72g850c9j4ez", - "public_key": "cosmospub1addwnpepq2asecf0tapds4p2jy8edxs4754909q079nm4qcyj3tjz86mymacz5w3exd", - "account_number": 685, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos13mztfedkzpz634g7u5fh8henfmvzyrffwfe28w", - "public_key": "cosmospub1addwnpepqdkspcjecz79luwkt4ya2q92p5ssvj67acxdsnhxfqyujy5yllhrqqkjgns", - "account_number": 69, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos13acm7994qxzmemx0fekg6s3qtagck36erqgsz8", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5dh2Bb3bPXttHs4f9pncJLXIe3WQR8MwR738J3rfua6" - }, - "account_number": "280", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "13230569708" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382602456", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos13ljukhcdmvlmaa773v3582cufv74vudsyc59x2", - "public_key": null, - "account_number": "641", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "6706625986" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384576238" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jqkfaju29z0270cmm4zhygtzwjcuqjzx52juz0", - "public_key": "cosmospub1addwnpepqw0faf9mtshxux3vmp2fngcsd5ecg7yqkmrvchyq9kcsukd9gqw4va3r93q", - "account_number": 111, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jqcu69j3gly66mg8z9g8vwy0fgx6vmj0feqd7d", - "public_key": "cosmospub1addwnpepq2kkwpf7hyzukxnwcrvdq477h5xqcufeyxgldkcashy8cxxhu3qmjc4ypka", - "account_number": 704, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1jp8nnep04hdcxckh0hg4knp4fu4zmzkycwwexl", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A+x2M6EKicIoOyyL+S1JhffcDwexF7taCjxVqlnAky8i" - }, - "account_number": "431", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "4098379796" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383410994", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jp0tqhr79uwqt2rh66vcd378rrhslg49dfvc9n", - "public_key": "cosmospub1addwnpepqv4ska2p4qcfwypf2xczqk04r9euhhtau6usph3unet903cwxvqvgcmn7ry", - "account_number": 261, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jzsqvang4mtxu9ljjeyscqq609mvg93ky8vrc9", - "public_key": "cosmospub1addwnpepqglwtjkhf3v4kynwhtydykpsr3jkhujq3sjg7zg37mfv6qypj0yykl374cn", - "account_number": 859, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jzhlspgxp578kzg9dtvg8tm2w9k7tnmcpstzry", - "public_key": "cosmospub1addwnpepqwus7hq2vx3cfemr5gpc36fphkmusldfanzk3a3jnfrlyjgzfkxvy9uvnxm", - "account_number": 299, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1j9vhccgf8520gtz7zn5jxj9lk3nqg0wx479kwp", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AygV31+NDv74EjR2oNblfvCnjEh50RKelz3eDHCTQl73" - }, - "account_number": "649", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "4039306257" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382937462", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1j9jq7pea9y4y7fersmc0wlk99sxj3vgdya3hm3", - "public_key": "cosmospub1addwnpepqgkedd4mx9tjk96xd4wl3yly7g4mjf8dqpjwlwhka2nw3dw4hn90vah5ayn", - "account_number": 897, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1j8hxsxxd4yxne97ca9xx0r82hpmdqdqr93wl4y", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A4Mt+wj9Uf3Z6vvVrwfSq881AM9fw+T4IT6D/2F1suyt" - }, - "account_number": "674", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "21294145609" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384881136", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1jf2rfeaukfmdhrd6prqdmqhcdyr8ezak8sm2wd", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Akx5G5wGacccZrqN8eQzJHFy8/Vw3Zx3p1obeiBhkQEr" - }, - "account_number": "752", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "6831411503" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384268265" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jf2wka8xprke2q6qxq2vz3khe4mqxv75rt0m0c", - "public_key": "cosmospub1addwnpepqdnmydex2xjhqnhfeudkqhkhj888kjzw67pqdw859u8g909jcyn4xe3asx4", - "account_number": 201, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1j2uu5jpphmr7vk5f6yvx093hs2u2ef9g8hy8g3", - "public_key": "cosmospub1addwnpepq25a99sz5z4ux5fahn5g6gh7xsyckplenzjnxztza85ww393mdwe7e7n2ec", - "account_number": 481, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/ModuleAccount", - "value": { - "address": "cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl", - "public_key": "", - "account_number": 917, - "sequence": 0, - "name": "distribution", - "permissions": null - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jv7lxeryc30c0w4p7p92nxywgcnswuhsxt9l3p", - "public_key": "cosmospub1addwnpepqf5zqt6stst6y23klsfpcjspr7tkpmjdlckv7wx6vrsewknw0m2a2zxgak2", - "account_number": 170, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1j07ypsk6cukpxq0epq5t9rhpmyez0g5rkas5sn", - "public_key": "cosmospub1addwnpepqgsd0angdq54jvwzg0fd6jkvns3w8ncaul5nf06d04hz5729q6flj9aapm2", - "account_number": 768, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jsgcz2u9tgrn3j49t2xg4er3hjhnryzr6w9dqs", - "public_key": "cosmospub1addwnpepq2lz883x5qpf8k0j79p9tm323s4z3lsex6472hwjymwvxlh4tg8rsglxu08", - "account_number": 324, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jsfel7tdxv09dm4lsqesfuhlpnlhhpeh4fdl27", - "public_key": "cosmospub1addwnpepq0xy2hgnr5wpzjf6rs9nqcznwzqdsp3kugtlpecux22n2lmf46klyqhsw06", - "account_number": 574, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jsd99e3zfrxrr3nh057u0tvmu0847zkr29f28v", - "public_key": "cosmospub1addwnpepqv3kyczy8gfvum8lr5287tekyeyjsn5na2dq0l8vlft69wq56sggz6ndmr4", - "account_number": 176, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jjav2y88kx0jempjzz5jcc9y4yatkyn7xnnvsv", - "public_key": "cosmospub1addwnpepq0wfqs2yq2h5xvja9hhg6atrr59l2nlck2fduh8dy86k3yftpqzxcar9j47", - "account_number": 247, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jn8g39pdp9zaz750v6x7kspqv4wdfcg8dluy5p", - "public_key": "cosmospub1addwnpepqgxqts3ye6zkc9eglp90ntej2jp7eenhp3zqus9u04g0lfgekqfjspgs4jt", - "account_number": 819, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jn4dp0s3ewkwarqmra50czqlm6g7cf9plthphn", - "public_key": "cosmospub1addwnpepqd6dzzh4tef4q7czn8wumngkz8nyrlwsn8ru8vg0r49t07caedwxv5zc2x9", - "account_number": 617, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1j5fx2wm7gvl8sssx0wpd9luxegxs5he8jyucwr", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ai/J1mbNmi/jIuUyEnwmUgbqMguOFxcnG1U5C96lkuX5" - }, - "account_number": "318", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "9704458018" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383337721" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1j487gq8cnf03mdf4vq0j5rv6ttdgrrv0ajhqc7", - "public_key": "cosmospub1addwnpepqttklaapl63vk5xshw0k00lwjy8dnwa59evnea4psvkukxh3jnaw26508kq", - "account_number": 133, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jhvqn320w9nqxcs3ar7250jqg7us9vuszw9cwq", - "public_key": "cosmospub1addwnpepqwx7dceg20dahx5zwg5a5elq6am8h0zgvd8d2cxvn3nzahj94mzswhhssnx", - "account_number": 739, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jcr5vg5nfeyynxggdtv9ncd6av42tetdgkhpus", - "public_key": "cosmospub1addwnpepqdwls2cwhnhc6eapdv49a8e2l4pfhl4kyna3gasjle7qd3tw0csrgxudj9v", - "account_number": 583, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1jewrkm9gpjfa2pych0te47zjj5jg8vaznvy7wa", - "public_key": "cosmospub1addwnpepqvfl4jhnn58u9xpcrc7wpduc4x3tyhpk7syv0jcdh33xrmgfa6hgjl56909", - "account_number": 629, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1jm7g49wwdxpsuv4u4r2vl7kaayz05uyxx7jqef", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AjCfyciqfHJF2qMLycGqPFdqdUI0FbStT4rQ5BJAR9Om" - }, - "account_number": "295", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "9268777247" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382990724", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1jakgqseuh502xcapt7ctxtwaz2w4xyh7kdqqw4", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AhavIvRmhRK+vsHhy96A/2KMvAo6+dJrSBwqCZSeYccb" - }, - "account_number": "351", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "20561986979" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382590789" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1j7352v6z3xcf9y5qusgdxectvn8dv962xde6yc", - "public_key": "cosmospub1addwnpepqgsq6sk03u9c2js9pxvmw8nmu5g6e9esq0qyf9r284t4mt57mqs4qws0ml7", - "account_number": 88, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1nqlclz6g890zaeq4gadtl82e3f9kwzp60sqrqm", - "public_key": null, - "account_number": "850", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "13908817508" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382615766", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1npd5ddcq5cm3q938pk02dqa4te3jnfy25c5gnn", - "public_key": "cosmospub1addwnpepqg4s2agzlr0rjrzqz3vqzz9dgvzmyz9x8ueu08rkhruc79guf20xsrva0ep", - "account_number": 657, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1npnutw8qwkvz0sleh593kaawfdygp6r25d0qy9", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A3MVVCcQfGMB3PnMJhW+KmvQdhL4N6ga+duvNWfFGKku" - }, - "account_number": "352", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "5400833576" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382698186", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nz5hp6p6wn4fvnaxe9x6fq35daamxvhht97rpe", - "public_key": "cosmospub1addwnpepqvdr2f90gme94y09hqt5x9sztn6h0pdralz8x8kgq0yutcjhgalc2p5r0ke", - "account_number": 182, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nrpxld0kz90xzcacgy5dazgean49jk7a2c0zak", - "public_key": "cosmospub1addwnpepqgdzcxnrymr534cwr904euu0qwdsjmngaqvvj3lnzxh8mrdl8dukypzz53d", - "account_number": 807, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nrugh7am9s584k6qlf5nxlpetarxs2csglt46w", - "public_key": "cosmospub1addwnpepqwzc3ketwkxjxwktg4rr33ga9fukd89p5dev2fvqkts6a0y3qm9akn8casc", - "account_number": 31, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nraptt0aagws66pcvnc92kjus460k3l05fdh4p", - "public_key": "cosmospub1addwnpepqtc7hqgxa5espm4a2glucf07c8znn9hajz6tdpfvsw27fcn693haza68yuz", - "account_number": 388, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n9dqelmmf5kfysk24m6chqfdcgz6r75u7mpuwh", - "public_key": "cosmospub1addwnpepqd0lzlcvdhysrp0vsg068kz6qh55rwx04dgtta9afafjsaku3ju2v7rzx9k", - "account_number": 119, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n9ds2q3tyjrg0jqg70qfhc5dk7cgj3y52uhxq6", - "public_key": "cosmospub1addwnpepqgyjm6qqcr3as48hyxd72n9gvtdsgg5w0er4xmzjlh27slmjqq9yka0nwwh", - "account_number": 124, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1n90ws7ttdk07s42xkm8gvhu75728hwrq2l3szx", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A1LA8eOZZhFEThT61iiQjGtO6cGKveynRNNGO1QTpPeO" - }, - "account_number": "720", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "11467278300" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382622258", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n9lefg5g0mz4glppdt994nsxzg6pxscqmgxgwq", - "public_key": "cosmospub1addwnpepqdyzwenw5krlhxa0dtrz432vlmc9j827tvgkpl23jcx8w7j6g06mygklmfv", - "account_number": 225, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1nxr7alffy7zt9gg4285a67ts977pcgaajyekgl", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AviWC4qyrTnjJ/llh3JrH0hdnvP/fn7WVsS6IIR0D4JO" - }, - "account_number": "642", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "16920159314" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382594923", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n8emgp25g5wh4d9204lpd06gsznurtlpdgzytd", - "public_key": "cosmospub1addwnpepqv9w0yqrekktvu6gd7ak8u7wkwqj47llgrtl2vp2gtdvfafwatyyshnrvca", - "account_number": 154, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1n8ugy8hee9hnzntcr7rkyhrrkcgclg3385vkd7", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A4wQKjQ0/imWtlghCTJmRDtwDMSRaL0RgogIfcT3H/Tp" - }, - "account_number": "828", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "12728206427" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382604229", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ng5m6spxngyne4qzce35fdg0whl0yqgv9lg9tt", - "public_key": "cosmospub1addwnpepq0t4vhyu6uhy8edptm64gws2qdtmdddy5xyyfeujj3qslxhrghf2cvqpnkq", - "account_number": 494, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ng7vpl5wh98pshfef327gfnzyrwh6z4ekqavpf", - "public_key": "cosmospub1addwnpepqtqwrclmyu2h4w6js7m9lg4daqvrjyn8mjfayft5k7y67qj9z2xt2e7ytgq", - "account_number": 180, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nfurwjwfy3zhw0g9eqcclzeejf9nqw62gfu8y3", - "public_key": "cosmospub1addwnpepqt3ycgjwgckg49jp3vr0sk53x7zejlyrvs0lz48t52fw4kcraveespcj73a", - "account_number": 20, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n20sc20x53kyms9vhrxlr8r79hptq3p2gwfj44", - "public_key": "cosmospub1addwnpepqtjadacgcc9v3sptf62zr88pm3xd82gtxx7fl0vllavvx2vu5gckqjyfjgq", - "account_number": 214, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1n26yqrk2fzt4m09qdslvslgfmrfqfjraw0pcq0", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkA/e3022PSBdqMK9d65GXvKbsLfDO8JTJRYBuqcmNH2" - }, - "account_number": "298", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "10951876744" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382616021", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ndff2ha25wm2nhunxgfrzlnhvc5j06zvgawa43", - "public_key": "cosmospub1addwnpepqv59z3edalxhrq233upfrlzdpa2y4qqaahn8u4s56jf9utdxpnnnxudcmq5", - "account_number": 47, - "sequence": 14 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ndjmq7ee0g2lmxrx5q0npcmv64km6hysk0qnvn", - "public_key": "", - "account_number": 748, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n0qd05zlz0pr3eajdjukezg8l2str3twyjel3y", - "public_key": "", - "account_number": 725, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n08duqdkxwmqmtjaha236esw6r72njd2hrgqm6", - "public_key": "cosmospub1addwnpepqw2dey68nc64p2fmavt9j2myhs8v2pu3dkfj4l38r78re2hucg68y02pmcd", - "account_number": 166, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1n0f0kcjjwrjqvva5wq6x5nj0c45vddc2rr29k3", - "public_key": null, - "account_number": "549", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "18276027667" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383108269", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n3lnhxzzm7ntheu78h6v4zag7zmrlp48tjnhf3", - "public_key": "cosmospub1addwnpepqflpdacrnmymf2nxz0z27wu4c42cyqfqued97l9pvln873ptnj722az9wu7", - "account_number": 114, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1njvscahg6cus5fy9k5gkq72cxj4kcahlgy00dj", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ApKohxuMnLAS7QJklWtYf9Mlpu/uHWI2hUsLvhhK75Hh" - }, - "account_number": "358", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "7296698093" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585002", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n5qqy42c6su9dv0tjpt3867mu7sdfhz6juqdns", - "public_key": "cosmospub1addwnpepq06dv2xjatc7d24rfhxu6zl3srqzzse6xv6nkc7h28dt5vrp8ru8xanm33j", - "account_number": 554, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n5t5rr83k3emp5e446qjprj0svsh06rwqkkv70", - "public_key": "cosmospub1addwnpepqdlqwps7uuk7l2pszryqcmflpr6rdgvfmkgga6fkjvsydts2s6udk02trmu", - "account_number": 64, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n5n6d47c4ntac509rtq3s620vmcqcf9740397t", - "public_key": "cosmospub1addwnpepqwu02ldkuf2q29fevzqkrkj5pr6w4mp7a8v2va2epsenvt6gctqgzs5u8a5", - "account_number": 110, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n4jy3exn7fyzt2pfkvqkh8u5c00tg3n765nrwn", - "public_key": "cosmospub1addwnpepqfdzh8ar6wwm3h8dd0n9rxk3vfv753568dq62g3xdqepgen0gkcnssfmmkq", - "account_number": 157, - "sequence": 12 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1n44p6u7280zd652tkgyxy4jg0pp0agcvw3d2wj", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5f4Wdr23d8m8HObEXSCyqxjwDOhucDcOpty1MuREEd1" - }, - "account_number": "334", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "10142093219" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383344721" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nkywcdu694al4mm44np7uy08jujqvwjzarzs3n", - "public_key": "cosmospub1addwnpepqwkwjjd07zlqsej7l5nn7msjch8467sdpcn8gc6vn6lav8tctzgdzuh7hz5", - "account_number": 732, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nky4q5h5wurtumxwsf9w79vmw3l4682879kly4", - "public_key": "", - "account_number": 544, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nmexjngk0j8jhgmywrkd7r98dgd9hzxpal8zsj", - "public_key": "cosmospub1addwnpepq07ahy07m2ymqkwra0tzkgs0588p94nraj84wvmymmueg8dupcqv7maysqj", - "account_number": 236, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nutj5al03vv5r46uawslcg4mq696v2m48allaa", - "public_key": "cosmospub1addwnpepqgpcv88wh7cxe9f0nfttw07dyvc0zsjwlc5dqv944lfsvtdctt26j6d9vf8", - "account_number": 412, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1nas3l2avd9hymfeqznjmrw7sde8ual5k9wn7vs", - "public_key": "cosmospub1addwnpepqwj2h0wf5ufypyxmx2tpmn4rycw6dv5zevgq83fdqmejc64w0mf4vg926jp", - "account_number": 873, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1n7xczt8lt4a5c2hzdhhvn2e4uanyu8cx9m9eav", - "public_key": "cosmospub1addwnpepq0rs6tt6rmqemes8jnlxsawqja89rdvyntyjuhwl73ajeelhrhee7rs2m0s", - "account_number": 868, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos15qwf797q6u0vsv6q5ph4a7pu30w8sdlkfcme7t", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Aw/DRiymogx5GdyAyiKbC4ydEdBPCUT2/0JFqw6h7NLF" - }, - "account_number": "523", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "8258854720" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382620801", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos15qje22esqaz79y27940s3ng7r7afx3vvklem7c", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AukFb08zFT9A0me/cX0njz1E38TDwyZFdwJoyzeTHFVo" - }, - "account_number": "700", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "3451208364" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382596301" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A1pBEbH6ArPIf7bCgoHXyZQvbhOnOmYV1dZDCjLbxqzu" - }, - "account_number": "792", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "7146894644" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384895125" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15pl2c2umxszwar75aft99kns0ltmpepnnpt9y0", - "public_key": "cosmospub1addwnpepqgnwhgwtgfqyxwfp86e906zysx5p02kh5rjzsweq2984lm2e5f3qvltaaxh", - "account_number": 57, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15zqzxj663h8g8naxyz324j2rpd3rnw4rvtxep2", - "public_key": "cosmospub1addwnpepqtaxkpa8x0da0e0dr2fgxsl4u9sfqdqlnvyk8ahas6zzv8gg8l77k2r0w80", - "account_number": 44, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1598m5w5wpz27dtq3er8uq2czcdvrwpffh7w03h", - "public_key": "cosmospub1addwnpepqweqdtlvakvxcygk8ezwyf26n9mt7z94qdpa4mjlev24q2zl8e3h6trpd29", - "account_number": 418, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1590defm6q73eu39x8ndt9vwmv5fhvp9q4vf96f", - "public_key": "cosmospub1addwnpepqd9pazpyfrvusrzwt24gap58zk2ygess4u2rvp6j80f0jcwvzhcqjp3dsdg", - "account_number": 539, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos158hwrawjlg586d47zl4xk9kg3em02vypshvfw7", - "public_key": "cosmospub1addwnpepqdzvxgkmxur34cmgyyfzr0mkhrysd6xdqpkz6k0qd62y4hl325qd69m7hzn", - "account_number": 35, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos15gpfeumr9nk4a99ntj5mrwuxxdg3m8kz0k0njm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A3w+W+YQHAFHilt/eNs/et9I6REJuR8Oqj651lh7N5W+" - }, - "account_number": "447", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "20291805980" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585265" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos152q4kxkr5dn8g88qs7fpq49au2xasn3yw8l894", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A2vmnUQ2Rd4sXqjUKl1Cdc0E2LqY+QOsAx8W2OMKqfpI" - }, - "account_number": "822", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "18086272324" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382601215" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1528cn79dzm0p5tgyaclsdcuav6qetanhx9dwum", - "public_key": "cosmospub1addwnpepqwtn8ugzsxv8v9hapgqve099fu4aeyrlum2mfwph2h9spr2adxshwpdsmzx", - "account_number": 744, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos152vx4n8032chkrgh97h05rs3mtdz3nucm37xh6", - "public_key": "cosmospub1addwnpepqw5h9ggnz7amw48v648wer50qeen3hv283fgyxaytq5l0y5ggz40x7wex79", - "account_number": 231, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos152haw4xa8p89az8fws3x38vr4cr4l5h0c5hsjx", - "public_key": "cosmospub1addwnpepq0rqul6xj8hmgnxpn5uetndpuwr038mjpzecdpazxyfwgkqceg2ej0axy2m", - "account_number": 818, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15tf0n2rqlh49324hrn0vzmj33fr7yk9trhg4pc", - "public_key": "cosmospub1addwnpepq20k8gx3w5z8kvg34eym8yq882cj39e3yudld3ug7swddclrhl6kjyun7tk", - "account_number": 192, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos15tv54z32xgqechywvr7ymsfdvr2mmx3553j8rd", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Au1B1VAZe/+EqYIu/7ZHSjadt+erjtIqMB1rygiU+Yij" - }, - "account_number": "786", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "24951038861" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382595111" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15v8xd8v7uey5kvt4tmf4llur7pfun480dee565", - "public_key": "cosmospub1addwnpepqtrma4umy3zc02gue9jzkgw0n6e63a9gh5jsufmx4yhnrl3daczxjnt0m3u", - "account_number": 653, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos15vf60ssrdq6fh9ln5a9wtd6f3q64sktl6vk2ss", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AzuFn7eAmTb2QDD6p0c0/mKxkXsJTAQB2DVASxGoN55F" - }, - "account_number": "708", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "9611753193" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382614115" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos15v4py2nqd8a7amn63g3jgtedtzd8qlajg32mtr", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AzcUSJisCLOFkh7TyD9kUedVECmWvEZWmYKosOFsUy5s" - }, - "account_number": "834", - "sequence": "7", - "original_vesting": [ - { - "denom": "stake", - "amount": "19374837709" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382597065", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", - "public_key": "cosmospub1addwnpepq04uuaaqtp03ae30fnpd777v808e52tldrar92pkuwm760gl4xmku3a2csf", - "account_number": 66, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos15wqxlh0da39gzvp3x50mrju8cj7ppfgachrxd5", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5AXP2q4gT1zRSAAYaTKEHByIb7NifInpDRpkswJWFBg" - }, - "account_number": "498", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "23710189980" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382620382", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos153rklv33fjex4w7r82n9wnwxrwfgae6nzgsqch", - "public_key": "cosmospub1addwnpepqw0np49ksk7pxwauu8jkfp7gf9dqwahdc8yknp53jvc0zcq6ugplxfqdhaj", - "account_number": 21, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15jcgjq7sc62rj4s0dlm4sapdcgw06jfu4hsn6j", - "public_key": "cosmospub1addwnpepqtqhh2fy0njv8jmwfwpvhlw22m5vtla93kj54crcqucgnxrmpmrfczy7qkq", - "account_number": 385, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15n9dz9j0ycu0wxd2kjexgpxtv7fj6zw4edm2ej", - "public_key": "cosmospub1addwnpepq0e5h85jydylerz95nl4y6hms29agglx4p9mtwxp4e98r6wckmy3qduaacv", - "account_number": 171, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15njmhwxm9ehmgm63dhg9rze2kfuk35qf7qfe84", - "public_key": "cosmospub1addwnpepq228r4rpxclcs5ufhlytsyx6dxkvwvecxvjhlsvglg26jg6l9kpy6mgpga7", - "account_number": 444, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos155znzxm9g8j53k8vyp2d5qmrkzdum4d0vd5l20", - "public_key": "cosmospub1addwnpepqwcv8elyagwcqh5yv789qq2qex5p783pstgykf9at380f2hh7g7p7dy27kp", - "account_number": 29, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1556dzhyv2gth4huxdlyur65c2sm3np2en3zzhl", - "public_key": "cosmospub1addwnpepqfea7dk2x68zc2ah8axxkcvg8lv2wuendx9tm77k7xxwzqx3t45cg9jgydc", - "account_number": 651, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1557a6swa3yv3ew9yk8hcfpyqu3ce7te0um6kv3", - "public_key": "cosmospub1addwnpepqgkljrd4y2g4v5v7ztnc0wvaadccsps08a4xf2ng8uaxl09n4auhqu3ad50", - "account_number": 37, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos154epq0mwqz393frj38lh265h9slwdynml3r0qh", - "public_key": "cosmospub1addwnpepqtslw0ycl3vmfhqkav8r0034nc4g27qkz4dv2knaa8u0euv3gsj0jtgzvr6", - "account_number": 12, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos15hqa5fj9sx7mjvmquhknrcxkxkeudguk9zpqqy", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AzMvySAuGnTZrPw+UXJWaf0LgNNwifD4C3N5jgyS0QU2" - }, - "account_number": "726", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "25049046818" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382586318" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15cfduq92j3uvam8u942xj4egs42tjzl6p33fu5", - "public_key": "cosmospub1addwnpepqwmplgyppurr7j6knpfavaza6xrg007n907th4lslha4qx45q82twgza0fd", - "account_number": 612, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15cnzrhl4pe7ekkp0djmyupahdsjjmmkv78qxet", - "public_key": "cosmospub1addwnpepqtjrhvpvnejk0z2dydgfsjwm65s2q547w0znjl55hg54lmvprac0yjy85g9", - "account_number": 147, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos15mxavsffqqj7enxpy7e3ayywd4jn4hz6ncjfft", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Au+3+75I2nP3ASHrUplrt0UxZQlFamQgCXSSfsR6ic7/" - }, - "account_number": "811", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "15664943513" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382607003", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos15uqsf4wke3ylyp0elnka2rvaefhsmhgjhe5mxf", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkvII0LqmgvX7omk+5RjQtK7vTr+F8ZGzmehu9/nwLEc" - }, - "account_number": "285", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "13873921582" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384430274", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15ughagcacjqyaa0f7d28xtev88v5vh69qvqq8k", - "public_key": "cosmospub1addwnpepqwckstndv9w0luxt6p3a694qazxat6kerfnpsr3qafypj9adchjaqf9l3x9", - "account_number": 41, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15a8hadw3wttrnr3qx37ewmzre4w7cjmt8kmq0r", - "public_key": "cosmospub1addwnpepq25h3lvs69gst4dm4ysx4af5xy6hs4r2d75ma474azeg6jezwlg4kphglws", - "account_number": 113, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos15772l3g3u9kk2qk5cmsl8tr6lshgd443ftvzwp", - "public_key": "cosmospub1addwnpepqgsxxu3kvk7pw3y62wd90a3arukvwm6x8z9qewawm99vufx556fyq3jjut4", - "account_number": 398, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14qy520rhr0qytqxdtsjsu9rgw708n2w6gpdmmq", - "public_key": "cosmospub1addwnpepq29cazq36ffnyv3kvc3swcfmtzhxglw9lr4j28g6wvdcvesv5x7xwqagxan", - "account_number": 228, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14q9rupnazu0mmkjd9skpn2zdfs8d0hlghzpk0v", - "public_key": "cosmospub1addwnpepqt5ecav54482c2jxecrrvf4p0jfflazlnshsptrsycccq2ya9pd6ywjnu64", - "account_number": 163, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos14rtpks2cfh8luvywtgrry3hhycwacwtkq6hyp5", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AvRAq8j88LzVD/gBJP1aVMeszSo5kIabgtRVXkj6uefu" - }, - "account_number": "891", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "16380650070" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382615962", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14rhly0ayx5ewyldmrp8kn564wnn8aascl7ay5h", - "public_key": "cosmospub1addwnpepqdd48dqgku8keethq2dtl8zmgnjprm0gmc2gawzwr6z3hp4m8s802pkkfwk", - "account_number": 169, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14fh7r7lj6928pd5tyqhfc62l5xnw7rq2zpnulw", - "public_key": "", - "account_number": 613, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos142ry9umgkn4wrh4tldeu8jtet3g38w35j20f5n", - "public_key": "cosmospub1addwnpepqtpesndd2za4kavuzc79nqxjzsmgh5fh0mc2h3lx82vucngmq22vg4m6tn5", - "account_number": 407, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14t66r5m6p8n9egwdxs45ljca5p4hra74vyz9j0", - "public_key": "cosmospub1addwnpepqvwfqajv633m2wgq0httfmpmz2h6gezk3eh5s2pe2atwr8jrlp3a2j5cpyy", - "account_number": 425, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos14dp6lpg8dqs4e0aq34vhcwpxt37nltefjdfxfy", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AyZylEXhe+uo+jqUVUyk94g9E4QaFGYg+e93vGAJ5gua" - }, - "account_number": "633", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "17434455945" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384339866", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14se5hzhf43yk83pkztukhtlfu683s4ktf89pvz", - "public_key": "cosmospub1addwnpepqgv72p8pxj6dc526aynu6gkcg0cfrvjmjv6tnrhtp3stacy3jgezzs6uxz2", - "account_number": 91, - "sequence": 13 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", - "public_key": "cosmospub1addwnpepqwzzgje6yfu6z0nc3myr0kyxuyjksy0zdwwh93u7m0r0dyqsmffwwlms864", - "account_number": 802, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14j4mehgc448s2m7cr0uqm3pmvjxav94wmq80w4", - "public_key": "cosmospub1addwnpepqtkmm2ttt9fxfgwj9sjvznyrejvmw0cdz4xn8c4h32pwxy0hk4qqvqnry7c", - "account_number": 148, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos144n7h95z7sz0r3k9rm3r8umkc89wt5c77szjr9", - "public_key": "cosmospub1addwnpepqtcvgnxpkww6h60yke0z0rmvv34tw9ycuwr02pvw67kgaygtvgku20x27ed", - "account_number": 63, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14kdxam68sthcd72526kc5ea42hfq5c2gvntv04", - "public_key": "cosmospub1addwnpepqt9adtwjxnm9y98ar2d2erh5jsp25zfelal48vqv0l56khay5rhsc2h0p8d", - "account_number": 470, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14hr55k3es7xfc54gwgu3plde0vaxkgerljee6v", - "public_key": "cosmospub1addwnpepqtr5h2qsd2d5hhwhl6mxd45aw5gz0ttgw6tmt72d3p9symgd35udg98p2kv", - "account_number": 587, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos14e4xnla8ulqmvgc825jaerhgw3sh7excwag0n3", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AoENN7Wox3lq8lZ77qrSncpM46xZ1ve0ZNTbTSWSxclw" - }, - "account_number": "598", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "11757858776" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382610635" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14e68cy8rvnmva3fzvhmq67m94zffpvnt7ztcdt", - "public_key": "cosmospub1addwnpepq0wd58g5gf7hn954gsrut2526vxgrkkvwuqzmvj0h2kyefzeu2aw7zux6s9", - "account_number": 146, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos14m0pzuhkpjnx2esurz6kcxcjvlkcdzk7e43krz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A9IG2koFVjvOxq8y6ifDIb07fvypS9QGmtyoFECfAOTt" - }, - "account_number": "915", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "19366487896" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382591284", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14upsvttjem96xlz8rfsw4zqt234jnqy8apm0kn", - "public_key": "cosmospub1addwnpepqtplsxcj5j56ms8j7lerl57al6asnrh53uft4efkzvuhv50gq8azxqn95wg", - "account_number": 774, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos14urapj7e6tj2s8clcsgyat6xmkppj7nm4qtewf", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Azgt6HgPaXjbaMzNh9Qdc58fVPdyg/CCZCWph5Ag/6U3" - }, - "account_number": "551", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "4773666419" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384830695", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos147pq4rzswl76kdeyx8sc7pagf4nhjpnq2hlrh3", - "public_key": "cosmospub1addwnpepqfu3238svg6mflrysqqgxmm8g025352ytfxzq3ge3h3ew69qr95axcmkuv0", - "account_number": 375, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos147xrqy22fnlj0ksdjlhsh5u6hz55sjn5hzzvfh", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A2blTJtAzIJ+YnPKO1cRYO2D9rYBQi2sUkcxYGFq3qhB" - }, - "account_number": "808", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "2441259561" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383179702", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1478sx3zdfylsts5sus5rlz4dgvyvacqpuchj6f", - "public_key": "cosmospub1addwnpepqt0jfhq5ndqpt8hv5aytl7scc0xnzsxsnnxqyuzvt8puzf5t65hmk5and7v", - "account_number": 68, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos147lwcm3tx6uhtjphxwwmk7u32mucukalplv80z", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A0hOEP1GKLFl0B1YoLsh8xgbrjDqtEhTD3/EML+SYebu" - }, - "account_number": "560", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "1743386664" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384351634" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos14lwqx5380234f0fshaycluz08yw74chl5fmgjd", - "public_key": "cosmospub1addwnpepq00s4avel98xmrp04dalj5dv5cm0szqd8fy6hfqlgtzwtxq3y566yh52rds", - "account_number": 161, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1kz2tqczu8ndyhnt879r6ctn2lxlf3lldgnat4c", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A9hn81vFP34UNBYnQXhgCE/BYwMrOzXg4kbVA9jNfArG" - }, - "account_number": "784", - "sequence": "8", - "original_vesting": [ - { - "denom": "stake", - "amount": "15293467106" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383184893" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kz20p7j939s8cqadmqqws80c6z93qdtyg8xt0v", - "public_key": "cosmospub1addwnpepqga9gw3sr8hvl6luh4mz0jkz58dverrfa39vmepwvp66wvdewmnsw79rhrm", - "account_number": 39, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1kxl7gsad663he7lgn66wx6gr3egnfj85dt22pv", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkyEVdtAu2wHGw+Ro8n0LalqcxvsisSgDIZAi3OA+v6V" - }, - "account_number": "890", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "5059098630" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382612906", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1kfnt5d5fcma9kh4c5jk85yu75jer72kwdltg4s", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Az03VLbUjwRqPitI/+dy8zOVZ/Uu10HsgXck62v86dvC" - }, - "account_number": "864", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "22892956798" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382603253" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1k22576dxnqasv25wy542wc3sgj30gm4gmdpec2", - "public_key": "cosmospub1addwnpepqfdercwusxjpjk5f48rmarw39e50pvs97e3grajdaavy0q37p789wpw90zv", - "account_number": 515, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1k2a93ktn30tznww5spyczstxzgvcxd9yl5vkhl", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Au8SL/yeRcXhJB16nuIOlZxAt2/396sbNbq7lzN7K9dM" - }, - "account_number": "754", - "sequence": "9", - "original_vesting": [ - { - "denom": "stake", - "amount": "348571452" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384789735", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ktnuvrm3q8h30y3k70yzvmvwme77e9yyf5n5wg", - "public_key": "cosmospub1addwnpepqw5wu82287289egku0jr89v4vluxwh244ct9qzal7ec6tnnwyj2r2rlf45t", - "account_number": 61, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1kt478tfpgnua34rv4jzv8c69h5827ngh4dxwlh", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AyrL/jOSqkVYGxHdVelG8+fRp9lZUQ2iuE9oWpBCw4ML" - }, - "account_number": "872", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "16788523620" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382589970", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1kv74z5g0s02jv72npe59l4qkn45q7r46xwx6nv", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Av7yEbWMkJv5N7S26XCo6AyXb8LVIsWWEEI8zxk1IuaW" - }, - "account_number": "258", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "1132497455" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382607881" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kwqgs5v74u9wvxjerktm4mkaxqn4w7z3u6w6pq", - "public_key": "cosmospub1addwnpepq2zzp0ap65gqsflg4796v6nklfmtsqzh80unaf0jyam4x8ywynfq73nuz49", - "account_number": 448, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kw46xpry8rw4xn0fvv84g0af2mfuhxpyd2m273", - "public_key": "cosmospub1addwnpepqfu4nd4pj9p99l44dyqc4rqf85ueyt7g398zfzg7u79mvgsz4lfvjgzv8yf", - "account_number": 857, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1k0z97vlulcmdrrajhms2x9k8srvtmxwu5cgjh0", - "public_key": "cosmospub1addwnpepq0ppyzhqhz855tkjkvagnc5ftg826nxwznm3g7wq0kknjun796jrypl5y3g", - "account_number": 131, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1k0ymmgnecsq72nsytp97wtvrr5zu4gm3ue5gt2", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AuE1SL976KwEaxLFwwsOgHNgcImZQFmL61ZEoKRYZzUr" - }, - "account_number": "730", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "8589655212" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384910275", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ksqjrpqv0k8zvzaak0wsesh29dl0y4nlautwy0", - "public_key": "cosmospub1addwnpepq08jl8q2f34fqzjum269x5305vly6csczwqekux8lyt6d93zhxkus9suu93", - "account_number": 85, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1kszz383fcxdtxhn3xr42hvzp8rfkaaqevxmrtf", - "public_key": null, - "account_number": "438", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "21199999636" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382619441", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kses5l7n9382eay7524cmut5p7en64ld4c9mwc", - "public_key": "cosmospub1addwnpepqvktpm8ymvm7epjkxsjmestmmz3jckzmnvddctyzrm6az4g9x6gwua2qq2v", - "account_number": 666, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1k3rapsk6gmfzeugjq5w2c4msuj7t4qhat0xn4m", - "public_key": "cosmospub1addwnpepqvasmgxsvyqzgtzfy8mf76ryxd9m0pz5hdkjvpurvhmfmj2t6vyp7ule3ey", - "account_number": 459, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1k34mg8jd05mfuw3pmcll4sz4fyhxqvghkp5s42", - "public_key": "cosmospub1addwnpepq2pnmqvu6uvxhy0t5zyez5wjcvsh5pkqlmta3uyeqy0yzf7tp0n76fpsh8t", - "account_number": 548, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kj8uw44q0fh3znllyxdxr8tc05qwnswd6fv304", - "public_key": "", - "account_number": 896, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kjkf4umv6g2pperq6g74mayntlrp4a7xypuvmr", - "public_key": "cosmospub1addwnpepqd5g67rxh3lwyx38nsp82d077qcj950af5dgsegzntu2x4mqmu876dajt6y", - "account_number": 682, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kjupa2w6rlhzj9fjxz35m02g2wpz790fd6mf0j", - "public_key": "cosmospub1addwnpepqtj39qcdlmh7fr77am26s8as06l9v3p426z5gr5dyfvc4fr5gqyevf4kqr4", - "account_number": 546, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1k4qedk6rmc4rjhpu8jzlhcp3hrms3kx8sl7xyc", - "public_key": "cosmospub1addwnpepqwdhe2nv5ugezx2nkyx7t7z255pj3xle6kgcpfdkmwdng4vp7sa3y6rly3u", - "account_number": 222, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kkruz0zwzf7ynu5y9y40ef950f2n3jrdp0lkr2", - "public_key": "", - "account_number": 686, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kmly2aspt8rk9h4ukdt8h52k24alvc34qukp2n", - "public_key": "cosmospub1addwnpepqwac5an6ey8yprrjfh3640q8l5hg7w4fgrlu54dm8dzacu0msnv479043tp", - "account_number": 350, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1kueuhkfx5cvcuakpfd62y9kzxw3unlef07g2u4", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwZFQFC+Nfemfy6nkm9M8q41mAxfplIAeKT7H+k7/fcA" - }, - "account_number": "615", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "10263331477" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585626" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1kum8rm8vqscd4zafpt39uhsdmcsdcxmrg7znxy", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5VBku5DuEoMyiNcwnJzwhjtTGeHn8SakMkPXbGVdRFc" - }, - "account_number": "757", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "23168113123" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383783348" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1ka5lq4qt6jlckltagh8tv9ujrskdwkrc6jncru", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AuCG8oHnLjwMqFy354Kdvy+5saGG6z4lEBz10h09wTmF" - }, - "account_number": "483", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "9286705427" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382837408" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kaunlwq2aakrheyvm206dd2dh4sjtfa02e2h2n", - "public_key": "cosmospub1addwnpepqtwlwcajqxexfgfd38r4f3zhqxzvupczp89m9y39kt4xqufa4n33csw883h", - "account_number": 289, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1k7dl7gc3umxp45u8m8zc6evvus2gvjvcv0h3l3", - "public_key": "cosmospub1addwnpepq0yf68j32r38cus7kutgz9wcsl0dq0vfhh62lwgam3z5t73u5wk9u89uztr", - "account_number": 227, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1kl0sk9crf0ru82ejpk8a7zexp2kudszsug5u8z", - "public_key": "cosmospub1addwnpepqvqxjjehndk20k8m2eryzf7us2je23gc4x6m3lydtnucmdyv2jaauhgjvth", - "account_number": 644, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1hq6jh5rru27mkd4c9hye0a4wkq9f9w4n4jx9zj", - "public_key": null, - "account_number": "480", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "14635056784" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383954298" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hpwfm40p8dwmwtmhdnmazywy79uywk8xhpz3gh", - "public_key": "cosmospub1addwnpepqtgtkafy5r04r63fmf4kfqnjymcy4t9ma4z8cw2qkxraddzcpfrnkfhzxax", - "account_number": 73, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hrl3j64d97qdx4k8gcztwtn7qxfx5n0a0s6azv", - "public_key": "cosmospub1addwnpepqfwuzrly3sn5c82zqgqrgweajs0fj9lx2sk9j9edj93typvvrujqkg56h4x", - "account_number": 327, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hyzzthl6vy5vjucaalz9w6fkyqne5p55c7jm8x", - "public_key": "cosmospub1addwnpepqtwvf7g53a6nlvcr6exwkhumshdv59mh0jaa8umfdts70dtupqctxp6p87v", - "account_number": 43, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hyv7jjh3kswlfc6nh0xp545rl5ttty2xge4wlr", - "public_key": "cosmospub1addwnpepqdrvr2ne6f9hgqca4s5fe3uwfxctwdr4ne2lkmmqsgfv5uw226l85z3pjep", - "account_number": 155, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1h9wg5q5x4gxkkca0x7krw7953h0ce2xwr2cwl8", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AlwOPlDnD5fwpHOqKL3ULbhS+Y+1tXFggcQ0JJFW3eH1" - }, - "account_number": "286", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "22658384934" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382601738" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1h9sv6zz2jdqj2u674r2j7srnx2ad4kr25h3lxe", - "public_key": "cosmospub1addwnpepqg048v7u9cfmrxvk8kp4rwr3z3cn7lwsag6nyf5m9696lrdquk44ypzwq8x", - "account_number": 377, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hxdqddf3u8vjm080ytpe959uktn4axdas3uqhl", - "public_key": "cosmospub1addwnpepqdm5qzsy6r8f29za6hghdk4ej8hujywh6dsyteyguvxm5h64an8rxqen7nq", - "account_number": 625, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hx0cc2lvfagl5q5x34qea2fc53hhr7mtgdy75v", - "public_key": "cosmospub1addwnpepq2tprqyechvwunl6fmukhs8ffz5rfhl6hf9m6zdrnqdqc9ngtgem2jxyj2f", - "account_number": 698, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hx7pezmj2euq3u088xluep0fywggztge2607yv", - "public_key": "cosmospub1addwnpepqvfuwjyepzrr7elzg5d2u9m6z4aujww6l25gnscerc76t68tvnjd5y8rup2", - "account_number": 435, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1h8ga9y7uvgrw3ze2c5s0l2r7us4ea7jc54h27p", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A33KtO/dc6gm5BSPW2iRqyL0FxBYjexsfRMM1ac1fweG" - }, - "account_number": "783", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "5881381635" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382610250", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1h8wfu2kqcjeev96yddv3nj9r4q003essrdt2mr", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AhBu8uF8OtxSYWs7pNSqTGde+0n7SLj/HdftHWj0hpVe" - }, - "account_number": "810", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "488919738" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383227856", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1h84c3yuxd6k7950wh868tcsj5tmvzetykv8lld", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AvS7EY+ToyDgW0e68mS4OLCoNg58UGqP8QSn+yUiFzIi" - }, - "account_number": "827", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "19906435459" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382582697", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hfshektc9gmedj5aly922qvvtwh9fj2pdp4jq3", - "public_key": "cosmospub1addwnpepq0xhfz0m55nz4txp2v7ttr3zxa9339nx6tjfv24xth38qs7s9qw56jgvkqa", - "account_number": 728, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hfjku50s3uhp66wuqexafzc3kl73z3xzhj5nqv", - "public_key": "", - "account_number": 681, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1h2h0yaw5g6yr8xjxjcqwx6l5lshegkta5a9jmk", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AzCLa80Ql3sKdSSQkDw+LVUrmkGdc096AmXFqbsfuqa8" - }, - "account_number": "796", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "8860992734" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382871829" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hvfg35av2nfcjvx8ks035jk66dzvfvl24twzza", - "public_key": "cosmospub1addwnpepqwey499g8fa68wl6c36dhtg5psjtsc47daxxkh8vvwer5azmfvlvxqlutm9", - "account_number": 702, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1hwt3fl2gylwdechqwq8uhmhsl04gn6ksw6lxlt", - "public_key": null, - "account_number": "838", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "14484645995" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251385143788", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hwvpltdvjus4euanyzcp97l96gfsg86eay0tca", - "public_key": "cosmospub1addwnpepqt7vpfm9vgvxg3sqwsn8y6yacfnwvqf3760dck340wqzsnnpntcgymm70qn", - "account_number": 906, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hwea4x7eagt83nvaz93q3q5gpje64nczg4x63r", - "public_key": "cosmospub1addwnpepqvg5y5xv9eu0yd4rfztn6pehqnxcc0hy7wxll35vfthehmg2w59nv06kj22", - "account_number": 115, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hsq728kpcxgr77ncj8asxa0383pyx7vqswqhtq", - "public_key": "cosmospub1addwnpepqvyng2hkmh28kmxy7e5unf5q4ewzs3rhsaghgygtu0e9qtwve75hqp5w5ad", - "account_number": 19, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1h3dugek69sk93jqvmtmhljdazta6n5pes683hf", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A6zgOW3xxZawyk94+zY3kpjRD0qy3Aiz6lsO1XdqNTfN" - }, - "account_number": "454", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "14841485341" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383865686" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hn79l8dj3u5llk78cjhsxcvlaz0jh966x4ez7z", - "public_key": "", - "account_number": 837, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hksxwc7h56mzm9evkpyg9hevlj94g5v003rs9w", - "public_key": "cosmospub1addwnpepqdm59h2t75g2sv24f65vl5lg4336wnhwsxdqq2jwertm839sc4p8z7dajtj", - "account_number": 669, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hc5k2vf82jswmnlfrrav6u2kf6rn39mpspdawp", - "public_key": "cosmospub1addwnpepqt7ah3flgscnydj0lgv96mv5s6lwsnvj7spwh06kke4exwq5m0aqzgkmzyl", - "account_number": 208, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1h6j4lyvuenmz9m7vq3hler8j7pg5ldpet0xf9a", - "public_key": "cosmospub1addwnpepqwcfhktzrvy5epegwsch5ryevh3lea3vf844yp7ggadzw8ld2y0e7yetr62", - "account_number": 90, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1h65n2jz4ka75akxt8wm2fjk7guvx6qfmnkaf7p", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmXrCmqBfLXn7SwgQBPSQ/H7zeK4Ti4527uPw17ox5FR" - }, - "account_number": "627", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "9509006434" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382603483", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hu260773mytzz030tuq0kffmlyxzs7vg9fwzkh", - "public_key": "cosmospub1addwnpepqgf4w25zlu3q7d5kf6jhu6nkau09v0yjtnkp4jslva63jydj8wwe5veh7xt", - "account_number": 95, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1haw8fcay84fjlsdl5cyev275ldj30z3r27m0g5", - "public_key": "cosmospub1addwnpepqt9e2p4a9lmvuvcsxqvmv2qejkvuf0tgad5g7y9guk9j8gqgl0ggq72vltz", - "account_number": 250, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1h72kkqt83nth0npqvgmardgelg6jyx7zupnypp", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AtTYkm3LN+C4/8JUX/BHAGrPQtPwynEvFQ4CC4o9GS0M" - }, - "account_number": "493", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "22467032737" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384258650" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1h7nkedpkxm0t752j0q88rhgwjn94p4y25s8ync", - "public_key": "cosmospub1addwnpepqvvf87wq27y92aaj8csgp4s4vqu69xtm4td3qdp3pr5etfrdn6v7wlaxds2", - "account_number": 195, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1hll5qzyzy4vrtdad5rqnf2jvf7srdnsy2va23t", - "public_key": "cosmospub1addwnpepqt62glh2fvu9vulmgvh6xqupdqk49yzpk497jcjayystchx48f4kxgq9chf", - "account_number": 81, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1c94nv4daewywxch72mfuzx87wesh73upv4dkxy", - "public_key": "cosmospub1addwnpepqv3wv7f8kkr7rvmkgeqj96y9yz0nkfmh3wq9ah8ky35trmr8upsavtmw578", - "account_number": 888, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1c8j30gd3vsk9ll6zwqwf8wj29mzzw6ptd8zyma", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Au9HDVpvofXyT34gP8UxF8hZm5Kv7JIB9xvMM2E80uAq" - }, - "account_number": "540", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "9605917851" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382619921" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1c2tutqjg5cqcvt6qen2x6enval6t5pyduf555t", - "public_key": "cosmospub1addwnpepqf3hcr46v9qzexalzn723hegy29mpjvllptwvaxxsd45dflmaa6czp42c0n", - "account_number": 9, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1cvhkglegj4zamjrdulawtk4rq658wnm9te6tgl", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AggA8N91ceSGaDEwQB2+P7k67ma4cyynE3JL6jpBsYAq" - }, - "account_number": "304", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "21462868930" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382594033" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1cv6mc68xznavrjel5fth3vry84wnwjy29mqn33", - "public_key": "cosmospub1addwnpepqfyw84lqddzlu0ts4fe3jnndrkkzu4c86283dl3mgz69t6uyhkx3qxyaq06", - "account_number": 750, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1cdvntn6mwvvv4qxnty6zp2jwvemg20yu3u2est", - "public_key": "cosmospub1addwnpepq27jdhnfzka6r79eg3m45we6zj85ty9cecpf67tej2600f534n0xxkjrpqy", - "account_number": 183, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1cwpm5e50rjg609rem4kshynpntwnu46wed80vs", - "public_key": "cosmospub1addwnpepqw0vltqp3vc6p6cm0rwsxyxw3f20w29z9kex0epxxaxnnmufz8rs29ty2z5", - "account_number": 595, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1cwk6x5smzaqhtrz95z0sf90d8a8d9vfrpaufnl", - "public_key": "cosmospub1addwnpepq2xv4j2entw32gleec66tekjggte54d28w887kknecju9ah2k538cxdes3p", - "account_number": 541, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1cwl6ck677m959vqnjhyynnlpx4n3keh5ujzmm7", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A6PbpIkGvR0roCcqNV7KjxZZD/d6uG3AT/6JM5Hjoz6a" - }, - "account_number": "532", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "18024237910" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383411944" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1c08mlht3skve88xx8eth4zgtpr2nhjfalrfnqq", - "public_key": "cosmospub1addwnpepqd0pannsh32yls8jk7202t4dmvqdt3fw3waz77ld8cz7mx888fr4sr3d6lt", - "account_number": 132, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1c07ez82s6kcfyg9szzg0pgghdpl7a2k0dljnpx", - "public_key": "cosmospub1addwnpepqtumyzl7hulm5v6delsx7hdpcye3stda9rxz6jgjf2eykqm2jh20kk75wm5", - "account_number": 233, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1c3jzrd6ju4l55yna9pcrc49x0xkcv2hczxjw3u", - "public_key": "cosmospub1addwnpepqtveqm5g7826cznecdhw55ya8dvfq6zug79fvxy6va5gaqthxdp427py9ua", - "account_number": 416, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1c4qcdf8mqwyf7rwgkvlputdfwdfnk42lul4d5j", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A23RVmFk8n8SW+HpwhOgbfF4N2nLozhP55o11ZdX4Yq8" - }, - "account_number": "268", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "24135596321" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384292647", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1c4w30j37que0ncnss65vr40nuy7d5msegmhgs7", - "public_key": "", - "account_number": 473, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1c4lft2m4yyrzjsxyu7nzsrxuskgtlr2crzzwwd", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkU30UDYVkL4ofv1i6yPRLxq98qR4fplZLZReeZbJ0+G" - }, - "account_number": "699", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "15882518869" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382596750", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ckrj43y28ta0rxfvdudtmtvvkrvev4342xzfah", - "public_key": "cosmospub1addwnpepq2n3nxrwxc027jequjln9ps5546ahg3p2h3t3lm4u9vmahke8kxw6sh5545", - "account_number": 430, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1chjcdfygnalpfjrjc8ku8vknx782xf7e2zktk5", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Al/NPfBH4ibOPL1k3Utu0nD5Yq8b/qwNgow/2KTtipP0" - }, - "account_number": "743", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "16731364774" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384463202", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1cc00387cdawytytnks0gd9yy9fq7ne6wvkku72", - "public_key": "cosmospub1addwnpepqduttph6whz8ngwywhy0hu3c9kxww3hqh0f0mrdkjcvg2h8q3u8cvxs7aae", - "account_number": 279, - "sequence": 11 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1c6afa9c3repulws30tzpsggt5jfdpc88ct47wz", - "public_key": "cosmospub1addwnpepqdnczv83gvvtr3vvyq8950052656kfmkfh6mgzgusa8xcjjkps22w2mwyjq", - "account_number": 614, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1cmw920g9png4x7g5rzjn22qqagz9cyh77lzaav", - "public_key": "cosmospub1addwnpepq0zx0lgud48vvwy6lts09r2l9e8yd5smkjfzzmfsfw9ps33400vwgzspy5y", - "account_number": 764, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1cupqtankeqe6wsmdgph5p289es2j5wd5pgp52r", - "public_key": "cosmospub1addwnpepq2prz4vype8mhmwnvw537vf53ftm02nlpgefm002drthw6py3533277lfju", - "account_number": 343, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1cud0s54s6cf9sl786mhjlnzhm58v5cp324fxv3", - "public_key": null, - "account_number": "290", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "15083188523" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382592977" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1c7qvxxyeu8qd4h76m3z9cyazzw2gmwx6x000jc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwdqS/i2wpfAIG391T6gXnC4QhTYpsh/0JLRlZ9wGhTz" - }, - "account_number": "510", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "15756319400" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383886036", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1er8j0tqpn9jftqscdkr7cnlgvedcxwnmfddy4u", - "public_key": "cosmospub1addwnpepqvhqzk07yeludsgh0nffk465d2seqmav2prd2rs6alu56l75w3dyyrjcppp", - "account_number": 341, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1e8fdmnscnm6axht542696jupnqlkm40e747qju", - "public_key": "cosmospub1addwnpepq2cuvyywaj3v5r3h0qz3dhav56326u69dasv3pg498rgt6t7lvfzukj7qxl", - "account_number": 215, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1e87dgtw7cd28mt4mm3s4uaaxpapanexw9grzmg", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A9gUNRKj2CO306ZR1r/NAPdmB6gQbX/A62ybaC/ZThl1" - }, - "account_number": "321", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "19823952642" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383235785", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1effy5ep0h5dn0ww4w6xqc7z3ptdwq5r3hnzgm9", - "public_key": "cosmospub1addwnpepqfx2yd7rz5y986qy95csp3ef5ua9r70cuy7celrqvejskdyacr7sj9u4vzj", - "account_number": 138, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ef5ydlpyvpxnp0pftagpsmfssxm0v2ar9rn67k", - "public_key": "cosmospub1addwnpepqgxhtkut5ur5pju0zjkw8lhhfyusz3x409c6qet8yrpd0p7czcadg7uevsq", - "account_number": 181, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1e2vx7q54npgmck0sf4kwseav50c5tewxvgjvs7", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A47CVOEAoQCP+7sWxeH3uc/2R5wWsrmv4plmAUwqGfLo" - }, - "account_number": "347", - "sequence": "8", - "original_vesting": [ - { - "denom": "stake", - "amount": "21152707569" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382596691", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1e2jxyxe4ekjsnkzcup35r8404hxxmntmhpwsgr", - "public_key": "cosmospub1addwnpepqwtfyc6jllhvpgtxalykgrt50jt3npwjymnuuat4u0y35flmeeld68nhe97", - "account_number": 679, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1etrkjjjjvuej87yu2pv4mcmhjsjqsn5hm9n043", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AsmrfunCum3cMzqtk5xMw4R9764J+rVwIqh1Lft+9ovR" - }, - "account_number": "452", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "15181358386" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382943578" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1evqmj6ahqf76keas4ymhvf4r992kg7wrar0fru", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ay+VqqS1HkrvT94ylIOZdwoa5m4aMc2/EMZ5z//doXmq" - }, - "account_number": "710", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "8434446711" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382594307" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1evys94earewfdh658d0u67j28lq2ltezr3uh2k", - "public_key": "cosmospub1addwnpepqww4ac9sdmwjurlwyea8de788rvdqu2gwzv5ukdqnsefzyfjdjtgvdnnvr9", - "account_number": 179, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1edwe9quhqnxa4yvqu2ks656guv6rjzhteye266", - "public_key": "cosmospub1addwnpepq28x4gcrklk8r22c650tktvywp0hfwv8hwtc0heq6d8wr2kagh2j624vpex", - "account_number": 123, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1ewpkqsyqwzcjhrr3qzu9jde5xw4uf7na3dahq6", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A6CacgMtPikJmS9D6NfNr07oPSMkVNfVR8nz/eVbqbNQ" - }, - "account_number": "596", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "6651076569" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383266107", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ewm28x3e9t3huptgm36wnwx0zcx4aa7numjadx", - "public_key": "", - "account_number": 276, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1esp738xp0yaksp9qf6td5nhl9m0w0v6n4zs8mx", - "public_key": "cosmospub1addwnpepqg5xpfg42kdy5fyasz6fs6wh4c8g8jmnfehkx77jk9lk5kwhhm2uurgqtt5", - "account_number": 884, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1en4tuzw9trweqsjukz4hyvlw89cptzlq89tug7", - "public_key": "cosmospub1addwnpepqgh6neaxc5qc82vrng427tmhlw78y4205pselprm387vgy5vkgvhcgqn22p", - "account_number": 816, - "sequence": 9 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1e5zmgnq6y7zxn5c642ty3jxur3lk0n0ca4wyym", - "public_key": "cosmospub1addwnpepqf3wz7kcmyvwszetwvsrfvehwqyu8znd47489s5udpzq3jekpgm9sxn3gwt", - "account_number": 758, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1e4zygycdhs6kpgem9cpddmvk5zyh8wr8xhnmk6", - "public_key": "cosmospub1addwnpepq2z0tus4q4stns9dvru8ju7zdsjqqupgjwf3g4zlux4805ku0ccck99xkpm", - "account_number": 303, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ekx8n2y3x9qq34c2uy8fdh400hp8msquc80yht", - "public_key": "cosmospub1addwnpepqthm7dnwnymwlk7dxc4qa8rtam4pq6j8tnmxp5hdqsy3wwrpfw7g6er0g4u", - "account_number": 209, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ecfsusjtvmp57t8n22j9vqx75g6yxdra5vk49e", - "public_key": "cosmospub1addwnpepqfvvqyk2hxwxa98ane0z709sa6dffy880dzk8sdl9mwhvgcd4we7zccuugh", - "account_number": 711, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1ecn2jwtj8tlrmt3wqh0z69pv4y4uw76vtld7wu", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ai5fmTy1e7FAL3KOs7bNclRrHIM0peMJ/57FBXyduNol" - }, - "account_number": "502", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "21735949807" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382591535", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1eccz4hnumvgsqzpfgmvhc5vwh4ugptm5trr09m", - "public_key": "cosmospub1addwnpepqt0sk5rhcpv85mjvladxx3ygs0auglwcm4xpurjqeex8z99ya86367wwghw", - "account_number": 71, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1e6ffgexkzs2lke6dywcju2ltqcjej2e7y4q8e2", - "public_key": "cosmospub1addwnpepqvy2kxmycme83ha7v8dcamwvjae53qzxs5k57sf4c35asdjxlcgmvhkmpm6", - "account_number": 525, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1em3y3h4g7n8ue3wjcramnpmz0x8rwakrpjmrgz", - "public_key": "cosmospub1addwnpepqdhcc8jww3jnsk9s3syxvwqdur5w8lzgvgujsu0j8n944m68ux2d2ehtcss", - "account_number": 291, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1eufhma2qvy0gvw6a30awgjkrt38spjs3dtj5zm", - "public_key": "cosmospub1addwnpepqvd9wuh5nnx26hudxvsypaaylga405wrhenxwmrju8ts6s52xra8j6jlusg", - "account_number": 365, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1eumpungfa2vmx20e27wnu6t0rtmrlmv3d54z4z", - "public_key": "cosmospub1addwnpepqghn86gscad5np6l2h0zte7qa4gylqvkzdznqwknhrxk6v7al09zv0qnxvk", - "account_number": 218, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1easmlky76c302my07gffjxjw0a2usueaw8j46t", - "public_key": "cosmospub1addwnpepqgejk6vtn62t483xtjytvg3dq8h3mh8jhhkt0m2quhwzrzlk3apxyvasxan", - "account_number": 342, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1eausepxh2ujd0lpjup9vahjekpz9as2fe5d9dy", - "public_key": "cosmospub1addwnpepqttsntl44pt900pqlguy6hgass8q69vcfv2unkdluun3sxv9pklxjt5wfve", - "account_number": 118, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1elu2xlg8qw8st5nppxvgszeyzhm4ht8zxhcwcm", - "public_key": "cosmospub1addwnpepqdp4dlgd8prhuga5hq04yx6wzx83g6q7s29t8uczv29n0hapclg75xmqqh2", - "account_number": 25, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ellx23lw5uxmdnyjpnn03expxvu89kd6xvcwj5", - "public_key": "cosmospub1addwnpepq0k56l5wh6qrl4fmp9jl0v78qy4jahrkkl6xqjc2zmap6tjg4h23gg7yjw9", - "account_number": 67, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos16p082pp2g44jm5sa7x8egm2089gw908s85szsm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkwElCYsDk6ViVa6g5lWW1yhTt1zy2+rkZnsnK76/uOE" - }, - "account_number": "851", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "1857575892" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383285179" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16p0aw2u5chfc470xkpc6vasz5ys9smqcx40qq9", - "public_key": "cosmospub1addwnpepqdkpkujsj0msclz3najretvktts8n9jxzhptqc558fapdglwgkxs7ua0pna", - "account_number": 400, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16rv5x3545upw3qgemu6kz0cjd36lhvz28dlga3", - "public_key": "cosmospub1addwnpepqd9ll4dw568gzv46gp68rkac8k226594fayfc33jm29t6f56yvfnwl6ruez", - "account_number": 8, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos169npylnywp0w5vqy8adcn3h3ywrechlda7sap8", - "public_key": "cosmospub1addwnpepqdluksf6scu7m7p5ggj4da3flt6jk97kaygv4ut3lsqjepkwtk6qqzd8mvl", - "account_number": 628, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos16x5vyv6aej2868kn56wpxpgzhvtvyegpjpwecw", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ay7QtwrrJjfxC8J9E17vHiF5AzReJqt7Ok45KDNGDeqH" - }, - "account_number": "898", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "23396058414" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384783069", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16xal57nga5gd2qxkz869qv7hm20xn0rk4wmewz", - "public_key": "cosmospub1addwnpepq0hzgwswjyhy8mv33hfdfdvn2y2uw5jk29y5zq5xns2xngpe75gg53y4gj0", - "account_number": 194, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16tr72kn90g5zl7qhyhuqkjflejz00uzlkl65sj", - "public_key": "cosmospub1addwnpepqgp4h7pthtzrvjpz2xj6w2eqp2cdh7wa7x994r8nc7q7amhzpeh55c0faqt", - "account_number": 48, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16tgzg562uhpczcma5at24uvw4a3n0u322jurd2", - "public_key": "cosmospub1addwnpepqwpv4t6jfup40cxuzd36t2acyk9re34rxu6ca2wv23gavncz6whaktjhtnu", - "account_number": 282, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos16v3h2mggt8tnkxp0vq5tq25fhr3knvf4jw40l5", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A+CIXYXaTgJ5KYvjsAGUEEPIgrvDhzvnmTtjYDyLISdj" - }, - "account_number": "371", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "24340309841" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382621640", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos16035vhhlcxkxysgfkruk204jvw3lmyhpkn0ffv", - "public_key": null, - "account_number": "885", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "22970686311" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382604971", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos160jtaz9c35nr7dx349ezfzvs3xfdzm3mlxgulk", - "public_key": "cosmospub1addwnpepqf93mjmpp8lvclzkkfvx5k76mqyscz7d9dws74zevaxu5z9tv7kuz23p56a", - "account_number": 787, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16sn6wjtd0kw4yvc7780cpayhz0x45d27f27ew5", - "public_key": "cosmospub1addwnpepq2d8k6kg75hjwqyknda4mj9wc65v7rzcqenfv039tnkwjss5tuq727mp602", - "account_number": 153, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1639hgh9ke9sxqy7kpcdcu6srk983upzjlf8mwx", - "public_key": "cosmospub1addwnpepqdnd5ugq8svul038v2sszz5kss342wyxg9k0aa3tdt76e9cj5psw72e63u8", - "account_number": 284, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos16jj80c7d94m772cn77zwcuhnqcl6y95kepxvja", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ArMCLEOuM7kIv3fGebyQj6MOOFDJ8co9abVkVRlHwsnr" - }, - "account_number": "428", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "6516026536" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384991661" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16kuse8g39wn4yzx64shrzned2lgnk0kepcuu9t", - "public_key": "cosmospub1addwnpepq0unlz4edy8fx2yfrmx3rwwakfwjlp2m9paey6agfupzrnknzwepj5arm5w", - "account_number": 591, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16erf80gpn7xquce9qmk2uzf4lzdgcgc55ra2y3", - "public_key": "cosmospub1addwnpepq2msqpv5ce7q9hkpgjje7mvfy7fep6jmmxr2hj2jdy0em4ph8fqm7r4adrp", - "account_number": 709, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos16e0y65dxvzn3zqlpql9uc3cmc3adtv8f9gf9ue", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AyMjsNIWTXtTkZ9VJ2kLEfqWCgb1gGAbfMRKLzKynmWC" - }, - "account_number": "823", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "15979511514" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383548464", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16a2sxhxlq7qfvkam3afnh9y6ph2lga8fn6fyqa", - "public_key": "", - "account_number": 302, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos16adevt9lhqf3q4dwnmhty7ndr8478thakltsdj", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5Chg1TuB8OyuW4Mflfwfj6pxTVjedmFuYhBdm9gxl5l" - }, - "account_number": "449", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "21563268573" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383296500" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16auet6ducwkpuehn97wvz5k5rsws8a7lcxmp6n", - "public_key": "cosmospub1addwnpepqwux9qwtmnuzxkw7203qndplmsvj6lpw9670wlu6sgaw6y30tzuhjcrs463", - "account_number": 789, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos167vm99jlv005jgyzh6spd2amy4drgsvnkaxt3s", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "An4mdU0NCkdAWr9+8UAJ6CAWP9B7Tf9wBF+5a9U2RDby" - }, - "account_number": "689", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "635421657" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382594263", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos16l54emw4lwhremfds2mnnlxcu06eknp8gxhgq7", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AocYTNJKOxpnL3xHvmz9AL+qtVbxLKr0VmQuSfvcVss/" - }, - "account_number": "257", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "20469989764" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251385065256" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos16ll03qy5htuech4u0z432zertwhyxynl53slhc", - "public_key": "cosmospub1addwnpepqwa26gwxuwwnhmgz57tcvyqvj23qft9wryeutcms0z4ss9f5tujfcg8mgy8", - "account_number": 217, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mqg9gtapd36mwxqk43gpqjh7h8f5cq5wlsrhvm", - "public_key": "cosmospub1addwnpepqduylw2z3sqttr57gmadyje3dj2ya25ny3gkgra9duvhcq2jr4szxzxl9sk", - "account_number": 27, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mzsvp23mjrjkspddkz6nta0x7kte6a23atg6ml", - "public_key": "cosmospub1addwnpepqw2gxruh52umsuh8jd7g78587jx0qd4skze2u2dm0sm8shx64tvcck7gh4f", - "account_number": 196, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1m8gpgklc8a2yla9ah9y8mlu226n0mu4y2k8yzt", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ao0X95vSz/7xwL+VAVlyNpO0Jpw3mYhE/OWCXtLqP53X" - }, - "account_number": "363", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "19675956933" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383287647", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1m8g0mk56ne6uutj5a8drc92um8cjk9frunx8s7", - "public_key": null, - "account_number": "817", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "4113451544" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382622776", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1mgnalmnc45uj6yhamy9tpc9q6s2exswn49982m", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AucVdMYLinH6gshVh5K0AmiWoW/kY1vzYZvOgzHjNwna" - }, - "account_number": "372", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "5833365049" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384611150", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1mfa9me7lxg0gja78krqzv2sxqpehlgrystzdvm", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ArphUB/rBBtZQbRoe8JXv7/D4o7lpcrs3l1bdxBeTXSF" - }, - "account_number": "296", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "7617475832" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384296169", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mfldj5ly78eg08sd2k3nygggjx765vvwjkh52w", - "public_key": "cosmospub1addwnpepqtvx7deky7n95f87p8nlj4gwfkzec7mp7lh70cmj60adavyl7q3luqvl6a5", - "account_number": 211, - "sequence": 12 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1m2dhppd8z4428ztvskxxveuy6u4pdva8fw57e5", - "public_key": "cosmospub1addwnpepqvurn7xmqx4f0jluk6suggumrnxx9zsz00q6fgfggpnzt8yz5gfawdrfxsa", - "account_number": 467, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", - "public_key": "cosmospub1addwnpepqwvyafhmcqnhjk3t6jzdah2rzaq2cqpmz9fgll8493g9nrpcxz4sc3s2gzd", - "account_number": 316, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1m26w2aa36gfwzmn58l7w739edmlrhfn4v5gjl9", - "public_key": "cosmospub1addwnpepqvtj36dsackmy4p87dys4377ysum2zku3v7tjqtf5jhluzgxk5vqqs54prr", - "account_number": 379, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1m2unyrnd4rnuvz9hmnsc7wx8adjzlvzlfqk7mf", - "public_key": "cosmospub1addwnpepqva6nvhvu5wjsfmu4qhdxwe6jtwnjmpzxkhs8f4e006anzaaqv5tv9vdhyl", - "account_number": 805, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1md3expnuxrws0qg9dpqxh5stns8ugvd6uh0jrk", - "public_key": null, - "account_number": "713", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "3063833227" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384310671", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mdes9dapqu6vr094qc6wyhd9jt7qfwvj2nldwr", - "public_key": "cosmospub1addwnpepqdngnkvhhzue788lzsycjdjggeaupk90azfvhks48pge5uhdmr3gcxa70w7", - "account_number": 125, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mdupf3evjq68azd9q7dcjq0analav5ru2empex", - "public_key": "cosmospub1addwnpepq2aplsutfgppd2msqrnrmeeejzrx8232yksx5v4lxf902rc3e59hspu4jr6", - "account_number": 799, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ModuleAccount", - "value": { - "address": "cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q", - "public_key": "", - "account_number": 921, - "sequence": 0, - "name": "mint", - "permissions": [ - "minter" - ] - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mnpu5cw9sxvp4gz322xt3nfylq6zfwrkvfkug9", - "public_key": "cosmospub1addwnpepqv9arcz0k33sqlng4lqppz6wjctjdpru7slvs2hrdhgagads37lr6fhd2sm", - "account_number": 175, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1mnyr4jhsjrulzkhrqekgu9fzru9g7vtfej3rle", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A0eDAMOIc45IjXiwb1/3FGCJ5oQcMKbR48dLI/rcAWDZ" - }, - "account_number": "751", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "2111619031" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382926881", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mn2w84lgjyemsggq7eyw8fw0wreclx0w6hfmcw", - "public_key": "cosmospub1addwnpepq00nh3dxxhtu0npunnf7qdj5lqqczklt2msk4km4s598482h4dunzf4pst3", - "account_number": 348, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1m5aynwlefn0dn8pk5d6j705zh29qstsp4dh02h", - "public_key": null, - "account_number": "478", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "8833783710" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384225738", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1m4xvwvq7qrr0wy0ryeu24eu8482h4n7en2x2mh", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AqkasSiFULDtF1Ut9JseVDGXgqB5EawSKMYToyU4aJwS" - }, - "account_number": "471", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "4112522009" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384725177", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mh9g99ncua6cecyd5meepx9hecyy3e244eysyh", - "public_key": "cosmospub1addwnpepqvrhnrjs2detmwtcy66s8xlj8gyxqyzpshffnfldjjwmeycgshwr25vcte6", - "account_number": 82, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mcvztyynwvn7lelqx89xuzzuguhx5xm7dhcuup", - "public_key": "cosmospub1addwnpepq0pp83ughv4ut9acme2gt3r0872wdehj2c8e4vrvekmfd0srf4ngks855td", - "account_number": 2, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mcc0dq93nrt3u6hl6ju82hyw3rdfun029jx4v2", - "public_key": "cosmospub1addwnpepqwgl56x4s43fltc3trfq7lsj32xtrfdnc37tfevage4uv7cr3ukkj4czs9t", - "account_number": 579, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1m6pn2hzhw44x5f0ev95yfav50l4annkgj49dhs", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AiKkmhzKCYhYOT7PsVurApE3oyqffhU8ydsk2EdIOMi4" - }, - "account_number": "693", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "16903055958" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382615165", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1m6y73jlmfnl8ywzrjggruy4nfk8hkgnwve5t8x", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A0inxd7Un3TdC9Oxx82HbM5i2I33Mtv6N9hD7i9td+7g" - }, - "account_number": "504", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "15099636055" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382590974", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1m6x26lfu6lzqfh7g05qf8a46f90sdfpj2vtlqp", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmJStpKM9W7k3b91rmByHXqBM3bRgkJSv7oASp9bvnyX" - }, - "account_number": "397", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "10725654048" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382604856", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1m67juyqlc06a6j9dxrpgw3xdl3rhvqxjcknzsv", - "public_key": "cosmospub1addwnpepq2z0nz80u2t0uv4l3wnxpalyj9rx3scme9765awv2qc97nedxnkdqg9xyj6", - "account_number": 229, - "sequence": 6 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1mmjkdjsqluxlggcl082j977kv8fwp4u0sjwehz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A2XGRB+g2UnIm9KBxvHepSvYV708M8SHyaiZoCjrbBWV" - }, - "account_number": "427", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "1186041662" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382619443" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1munf3xa25sdu0sdxwyqxhz88c8l90llmjsslvj", - "public_key": "cosmospub1addwnpepqgqxdugstqxww8xf38psl7unt6y40jcakwqjcqufu5rw02z4r829wmkthf0", - "account_number": 607, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1m75flstcn3hpq9am7dnvkw79e6jckkkjd59p9h", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Azmo6vEVQ6XMhEnXv12xGnRd8aYYBqRw20Ag6ENHARHT" - }, - "account_number": "415", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "10616187068" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382615331", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1m7m72dd80k54s8vg0v5z6h334lumvj3ehn0pyp", - "public_key": "cosmospub1addwnpepqgncsvs6kpx7ef6flhdg87smgdv9lrnkvtp6zk8kv37esheg6wkcgel7uvw", - "account_number": 645, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1mltm55z9lk9me9qle2jyajcw8dkwnf4mpcd0d0", - "public_key": "cosmospub1addwnpepqgkr2p0m3r8u4xaeydfcgmy66nr6whqkfc3fjk7ja0uzw7jzyw46xt2m44m", - "account_number": 727, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1uptqu7jt4krnqwlx98nlxs5fg2a0fncvpyhptj", - "public_key": null, - "account_number": "913", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "10289348273" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384243574", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1up7x3srs54xhq897rlda86hdsf4sy7ncg9khjp", - "public_key": "cosmospub1addwnpepq2yrtjl6z636spx2430pe2hun03j3zdmp92wu544847kytak6w3dwrms5ud", - "account_number": 210, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1urnp7yp6u27nut8kvsrapgmmvk8sh6u5wd5dez", - "public_key": "cosmospub1addwnpepqwajn7v8p6zuv8er2l5c5qwa2v3c86xw8sfhrj37a7x8353g2jspw2kscxh", - "account_number": 640, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1uylhw5z3gvr6nmpc9z3n6qg496z7m54zpvf8x7", - "public_key": "cosmospub1addwnpepqd9mxy4p6jva75efmzsjq5avn59j4n829vx6x9stw90wzg9urga0qmh2r7g", - "account_number": 717, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1u2uakvrpv8htq6a7n29hlpxxec956caj2akqcu", - "public_key": "cosmospub1addwnpepqw9qy7tfy32w0vdxwhqta2hmmk7kmfnpjedz6lu4j5pw5p2wjy3mxk83f6t", - "account_number": 580, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1utvswajc660d0mg3s8l0tvs6nnf7ctxqvyp5pd", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Aidi6GS9OuDYI/kJjbAV7dA3Ups2zVFpAVGjhU8HTQjo" - }, - "account_number": "553", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "455358399" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383844784", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1uth46wl4nuyhl6e6v7dxucy6dpqp2e9lj68ne4", - "public_key": "cosmospub1addwnpepq2y0j3sd9kxmqftpqxy9enzjuyzn08t26d5nk02anpwc0hezkzg4x0kandp", - "account_number": 513, - "sequence": 8 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1uvm96xdewfpdwymw5ywt8j5efq6jhpyl35pzg8", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxjlZftjBh1AKiP9ayuiHNP49UTuAPpyjqeEV4JBVNA5" - }, - "account_number": "426", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "7430382120" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384473140", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1uwx5cecec8v2af2mdrq3p6gv9gtv4gza5006gx", - "public_key": "cosmospub1addwnpepq0eu2nu0k7vvglv36lukp9x5phn9njy50n5px2taz292gd6f5gz05rz5yjk", - "account_number": 325, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1uk8d0xdv7kdhlx3wh4pwff6v6rcx8f970fyjgm", - "public_key": "cosmospub1addwnpepqwt0pya09r22w4ndrfcvrfr4aga6w5pmnc603m5x5kdel2h62h8vwu2xqxm", - "account_number": 505, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1uc7vywh0zn8g5mqqj8lvtuqhuaw6nsg9lqj3wj", - "public_key": "cosmospub1addwnpepqv3hq6a80j5hvu0na7e5llp5gnfn4kjdc5dyctlvcqrqzvrnkg03j00wwy0", - "account_number": 866, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1umn8dwc5l034syha3xehk0kmjaajdfyedajtka", - "public_key": "cosmospub1addwnpepqgnkw6ntpx4l4p94m62ln8y7hugqdyt6af8maxh6w2hw4z2xq6sg5e5xfkm", - "account_number": 355, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1uuk9ewj0532rzlhlg86tserdxvtnm3kq2k2zww", - "public_key": "cosmospub1addwnpepqg5cp4slckxk3kxcvenhvpamdezh8ytn2804vtehws04yjn6khylwj3nnjy", - "account_number": 191, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1u7rqjvmm9sss60dm8urfjhcdet0tmafaty4rmy", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A/WXt3XJFfiqZrjJjuRaPlDl7lorFgfcPvZ8tOsB/OWK" - }, - "account_number": "647", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "17214281111" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384027658", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", - "public_key": "cosmospub1addwnpepqt5anqq3knyh2wydkq3u8cwjfqnmqw633ca60tlzd0al29dnl0lsypsh6yz", - "account_number": 903, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1u7e0dy2dr65lfs5c2scvn9xzrntteew7lvuw7w", - "public_key": null, - "account_number": "406", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "4718441430" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382602884" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1apfvj8jjrf42cwl5nsgp3p5j3zdlxaf76g8m3y", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AvBh5gIyncrNDY93lDUXLSpUjqS9doZA+lZ7WvESY/+S" - }, - "account_number": "777", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "4761380400" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384504666" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1aps68js63cz2sd2h6zq299tzczdwg8m5aqcvdj", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A/d98xvFJ1Pvb9ri8BGi804YgSvnNa+9CfqMxklfhXqh" - }, - "account_number": "646", - "sequence": "7", - "original_vesting": [ - { - "denom": "stake", - "amount": "7928869580" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382592142", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1azqlatsdv9cme5y08qknavjfssrtjrnamkqyax", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AtrDzlimhk2FeccycJtXMlKi+Ms8YadHeiTesxH5qVF4" - }, - "account_number": "530", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "6621813014" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382604624" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1artlw5e2222rk3wzyewk9qse8spp9t3kfp50se", - "public_key": "cosmospub1addwnpepqd53md7mk6edgy52e2svr0j93ugzvz9s29axp9mcktw4d02fjcy66qw333v", - "account_number": 775, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1a9x55gc6wp5wm39rx6exfwd9zf6t95ascyvwlc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AksIfPCdaieHnczGZfdiLGzxtc7sfdfwj50iWC935xQH" - }, - "account_number": "604", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "16834614865" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382592451", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1ax56w233q9c43whd6sdy52v2qhuc8lpjs7gks5", - "public_key": null, - "account_number": "624", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "756065317" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383577052" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1af3ljdelv635n7yh76vvvkcs9adg6pq5z78lqn", - "public_key": "cosmospub1addwnpepqwhgf2gz58tewjlj7l5rgy30npr98jnzxvjqx7f6e4sfy83xxup876fgtk7", - "account_number": 753, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1af6mnuvcs8ypz2272x4vhdw9dkc25ac87z04l8", - "public_key": null, - "account_number": "723", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "360329391" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382908810" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1a2sgqjezvkgzc6vhvmevtsjh8m8rp52zcfu7ga", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ApZlmB5TSabB6uw5onnEU2En5HSYF8KqDQRWgEZnhbzn" - }, - "account_number": "339", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "14044295291" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382616349" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1a2us5nm6r2azfwqefh5u9r3g36ddduzrcpfaem", - "public_key": "cosmospub1addwnpepqvj6juduaknlhehjt785gk6vkv8qhqykv5d6zupvwafe38t0unzxglv5xk6", - "account_number": 688, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1atqlhvdg7slrrkrhpqc44vk6nqhnvdsflx8aft", - "public_key": "cosmospub1addwnpepqfw46rg95l70w7lekt8eh7szxr7ms8mfhqvz0ywnpc7fu25f6hj728cjap9", - "account_number": 665, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1adwsqn58aype530jae9qrwknsxyf3wmwdr523z", - "public_key": "cosmospub1addwnpepqvk5vcerf4d2l27rckcadgpg8evllyvr96c4xgr4lkww8vtc8skhyr22pyn", - "account_number": 162, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ad5vqqf6lruklvkyyqvx3926cpjyn0wuz6ga64", - "public_key": "cosmospub1addwnpepq2pfevuuxhe2mmy4nxjhtv9s27zmucxjw79q9y6jl4a27fxr2zxlyssfn6k", - "account_number": 894, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1awq0hzrn6zckeq5y6xfgj7vyfcjtd0ux7wtnrk", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A1SNjafvDaqKj80Ovj3ziSXJsA3iamZFEQ6lFweGa3Jq" - }, - "account_number": "501", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "17720129901" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382586222", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1awyus34e6laq3zxqsrv283w6fgn8w62zkwd87d", - "public_key": "", - "account_number": 212, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1a0jdqzvk078d6486vuxdr5d0yp6rglue2nh5dn", - "public_key": "cosmospub1addwnpepqvw3j57xqqawyxthw95x7udstqh2u4nntq5hulw8zsp407c24ucycaml7cc", - "account_number": 173, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1a5fndlfnwtvyzzt7ql4kvuqgnjut7ua7hkfts6", - "public_key": "cosmospub1addwnpepq09td8a5eszp6sn03gnwlzkynt5m9fgp8qja28pxqhrwfvaj5mdzz2rwryg", - "account_number": 508, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1a4nlyf59n25qmh4myas5mdunvu9r4wlscwcu09", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A3vVQF2aZOuLmAJk/C/flfEbZcfu43PAZ3AF+dztS/SK" - }, - "account_number": "524", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "21170621637" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384866197" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1ah3yy9ql35jh5ehykl626e848t2rrsyze8w8nz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AoBN3TFLm4Epk9t2AH+R5wNVM+6N/lTQR0Mo/P4uc4iC" - }, - "account_number": "793", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "1907148058" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384552953", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "ApiEXjoSexWw0Jw9qJuKrs+HUFx7nTczjg5dOEME4mTS" - }, - "account_number": "479", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "14888612438" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384548806" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1alxfwr8v98tw6tm4jhgdu2hu5gy0umv8kl6qt4", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AhY8AWbGlcsqvcH9EXpwUgXqCnmFPFNZW3mEYMgQdd57" - }, - "account_number": "547", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "21150835180" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382609896" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1al0nkrxpkc3vpcerakr66sed56zdmmre82sy9v", - "public_key": "cosmospub1addwnpepqdefatxypu4fp0z52tp76zfp6sjx0feg8ffe5res6pxs520evrxdcjjcm0v", - "account_number": 80, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17qavkakyqgh62k39frjf5v9pj0c78m2dv3hxah", - "public_key": "cosmospub1addwnpepq0cqdgqv5t9h99zje00vfz64sx6n5u07j6pmhypt3ahsspc7nc57w6073ux", - "account_number": 28, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos17ql89l8ghyguux4u4jghja9hmw9vjkwpkle699", - "public_key": null, - "account_number": "759", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "10598075729" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384805464" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos17phumh35wytl6rf7en2m2m678fwdtclwp6ma6a", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Al5V19lfHB1aGsASC3BaKwN3a8h5gyf9gGQWEhCAzfVH" - }, - "account_number": "330", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "20354737444" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383874583" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17ph7nmvmxdhm687z4k5phsyd08wvsnv44emkj8", - "public_key": "cosmospub1addwnpepqvn4quutlzny26a2narrthzju9dsgk05yjf0vk96lum7vl7rqke5jvzaqjw", - "account_number": 589, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17zgp4m7ptx9jlvr56dnyu0yx0lz3st28843cz2", - "public_key": "cosmospub1addwnpepq0qr3zl5rz8qxk4863w768w20vr6gx26sh7uxr5fvvv7d68jjr805k3v3a9", - "account_number": 900, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17z20092e9s2ttlzkpzv209dsxsxs946j8gx74t", - "public_key": "cosmospub1addwnpepq0p5kfy8kvyj0rl0lguwv5fmqwpsa5cg7gm8mzldlej5smsm6hhmqw7c8zy", - "account_number": 198, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos17z26jlgg6x0hlj4qnl7pxtve270fr7teanj8gr", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AwdV+2fSR/sNHVB4tEULyIjIoEzu9oyEbfZjT8sVHHsy" - }, - "account_number": "404", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "19608075505" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585887", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos179c5a9235h4z7h56gz9dhrj6gyaugvxmjt2e63", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A3qDoODCP/vg2CwZHPIGGfbnU0OFhxiKGTkxSX37eIyT" - }, - "account_number": "457", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "23446843723" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382620239", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", - "public_key": "cosmospub1addwnpepqf92c2w4zln6h47ewmal4xqtpqnj5qysg5p0dmr9glyqcnsqtgfgcqpv2h8", - "account_number": 102, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ModuleAccount", - "value": { - "address": "cosmos17xpfvakm2amg962yls6f84z3kell8c5lserqta", - "public_key": "", - "account_number": 916, - "sequence": 0, - "name": "fee_collector", - "permissions": null - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos178pm30fcgrt5654czwr8nlex050m6y609glx2s", - "public_key": "cosmospub1addwnpepqg363wp7607dlyufmxu94us4u25gu4kgylh2yzpjsasfcur95rnmkuksqkq", - "account_number": 761, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos178gvnxtnq2n4m23492m7agshjv3zgzy3n90u7l", - "public_key": "cosmospub1addwnpepqdg8aq2udcun9p754czwdrzqzm42vza3gd79kevlllytg956rqwhyycyhj4", - "account_number": 168, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1786au0nvqyqk8zjzeg9j3pdngasqvmknn2f02m", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AqFX72w4+ZiEspun4R4Du1qFIhHs8TpEo4qstPGP4DFP" - }, - "account_number": "895", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "10902416771" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382622281", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos17gpy6jzg7xdsr2xc7kweljagx4uaysxdk2244g", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5IFHdhxUTjskx1DJoW0vfI1lvfKDg5A+lE2NdMm1L1J" - }, - "account_number": "662", - "sequence": "5", - "original_vesting": [ - { - "denom": "stake", - "amount": "11542147313" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382616337" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17g3wgr4wy0x5nv9ep2eenc2tucpulq5yjy50st", - "public_key": "", - "account_number": 886, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17fffsvdgtsagwjrc3gxqh9fkl872q40wpvajv0", - "public_key": "cosmospub1addwnpepqgknkrr3ydnutmfjh4q7tdlm45kjvjy9wn6xpntzudfc7598uc9f6krm67u", - "account_number": 721, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17f4qf7nwcrkpjkxyepfd3e66l0yf2mwnk5g0lz", - "public_key": "cosmospub1addwnpepqwa4x4g5600flnra6sk3xek8rqvuxsgcl2e6mh500hd5ukvn5hea2r6lknx", - "account_number": 716, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos172lmu2psqlkxkthpr46h2ewjffte7lhlmwe6tg", - "public_key": "cosmospub1addwnpepqw3kyga8adqavqeh4ztg35kpnwfnqwql8w2rxhw848e4yccd6knxsvd0dwr", - "account_number": 230, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos17tphcpvwdr8ezywpz5qqglxul6hvx7elsl6h27", - "public_key": null, - "account_number": "353", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "23004313935" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384257285" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17tecr2sngjcm2rc29dzmadtpad2tkmrhj69whr", - "public_key": "cosmospub1addwnpepqw69rhp94kqtr8wre7ehst7hkkurh5fr57kl87da063cw7tzhq2syfu8487", - "account_number": 582, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17vfaz9kp0wysnuhu9pmd9smh4x7s99dkeh8vcc", - "public_key": "cosmospub1addwnpepqgt0gmkfsvl7dynef82pvxke5vnmmwq4uk2whzn3u4g7n3cclzqaxudweq8", - "account_number": 337, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", - "public_key": "cosmospub1addwnpepqwuws3zcs8qd3425yvan5takx2vhud4jlvtfk3lrgtdl5xffs0mlzjh5zt9", - "account_number": 675, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17da97e4gq5p2zavzcd0zmsh7ez540j0c6plwns", - "public_key": "cosmospub1addwnpepq2u42wlmn9vx90thlzxmuckxdqt93w6ekdghk9v3rr8jvpp28tghvj2uljz", - "account_number": 165, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos17wyymev6a4m34wr8ztjpr5fl209qkuvn92rsym", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxTnwDuX6WBiJlTmSiqZneWMEgycb+eNqrbY5J1pzztP" - }, - "account_number": "252", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "1352830596" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382677350" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17wmh6m5ecmp3hwdmvsy3gdlsp7m8m0sd3tg9sy", - "public_key": "cosmospub1addwnpepqgvjqzk2vmqxm3j5ftywy5hf04xfg8gl90tsqd463jyrvfprhsu0k8g5w8s", - "account_number": 370, - "sequence": 7 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1707yw2jgerkawrdyylsj4vll8k2ww5evrup350", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A2koSpGXtv5sTLle13Zmuk2wkbdPRbgIvjsKTl30A+xs" - }, - "account_number": "288", - "sequence": "6", - "original_vesting": [ - { - "denom": "stake", - "amount": "5058301403" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382583606", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos17s43pumh0z4fffw7e0sdrh0e894d2h4lfw5rtz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ahr3420WLPiIPKslkdwLOsL13fXGAgJmBglj9GUl5Vgu" - }, - "account_number": "456", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "7559720651" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382618848", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos17nxn4xkn8mvyjl9xg3erms4y43xeazku7rw5rc", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AyA6UeH0mf/x7pySjpFTovPMdT1OAYAfqK6TB/dfhIus" - }, - "account_number": "253", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "19280955030" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383380280", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17nckqnw09secacg9y6r7pay02nhemww653hker", - "public_key": "cosmospub1addwnpepqdvwjsag7thdgled69x89hs4cg8rpqp485w0zw8gazmd42mz9ge724v7s9x", - "account_number": 98, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", - "public_key": "cosmospub1addwnpepqf40hwnfaxv6w3yvaaaau2r5c9rumdcp06jd36kln2kt8enm6hqzsy97jkg", - "account_number": 536, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos174ycyhzg358nxm8r6qunzsyx48uk8fc404ckyf", - "public_key": "cosmospub1addwnpepqwqphn8fd6fvcv0kr6ljjtf362wgneqrpky2wzap5srcyz6vhf6770vrct7", - "account_number": 550, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1744t93tc6ulm87ccsc47mkl30qz65n8p2v0dw3", - "public_key": "cosmospub1addwnpepqwzwg260rcucyql9q6rnkhayydygkjxk7ly526ue3nwsz356fe38jrmslqy", - "account_number": 594, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17k35dydvkrdxup6z8633k3zcc4ecmgnzmk4zdl", - "public_key": "cosmospub1addwnpepqwkc23a70ndeeapn057plztghd0udz8jvf06nxym6tzd305p2kgux2llfpz", - "account_number": 52, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17htq20pelerzxya0e4rszn9g72lhtu96wuqwck", - "public_key": "cosmospub1addwnpepqgql4k8d6fyftkac7dtfncw40l2z7ytrz5sk60df7vhrf73z5znxcjm7fzc", - "account_number": 737, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17hc7jg6vkxcfdem4q9rkwrr2azjkygahd4dtaz", - "public_key": "cosmospub1addwnpepqvpvaw73dlelg9r4uclgtvvylvfysht9usz0wgsvrl5ztsca98fwurtayae", - "account_number": 718, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17er26f88ee6l369a2qk7xmnt248gqtuc45e9xz", - "public_key": "cosmospub1addwnpepqd57sf3wed732scy2tln9znsxarss8el0q8nu3m9f6u7c4we4he0uljcq8n", - "account_number": 144, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos17e6r58yvwdtyrzxudfrp8gp3zk2mdxd5kmqha6", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ax0VbN8Qhb2G0PephGP4hsgQXuL3tUY+LpySfE63gN2v" - }, - "account_number": "389", - "sequence": "8", - "original_vesting": [ - { - "denom": "stake", - "amount": "19490996406" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382593038", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos17eadsw26t8798nfaw2uq6rnmfw6tn3u7np2yfs", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A/fpCGELGoFD3vd6ote1xtdzHJ5IUgEqHLESmD6J6Ory" - }, - "account_number": "692", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "19880742654" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382617181" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos17m4lyrws32kta4pj2atdcc2d7z2qrwkpqk0exs", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AmGzAIwI30MLrRYvx80iz/2A6jqzZeYN5JGzrvWuEuem" - }, - "account_number": "567", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "10938256700" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382585876", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17uqc5hqs6x7ccr7pcrafp8tfwsezt07erw3ay2", - "public_key": "cosmospub1addwnpepqdvnk3q229cfc6luz228yn4eeysyrz2jfgv8djn8phwhprhhwts4u58v5qd", - "account_number": 216, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos17uhjt4f6xj7hww44vmettp4a0c8lz44n7ynrxn", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A1vxGgyVHy3rjoBUWfOxpJU192cqaoWo6FZ25DP0h4+p" - }, - "account_number": "724", - "sequence": "8", - "original_vesting": [ - { - "denom": "stake", - "amount": "2758412087" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382601614" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos17uusex4s7mds872wzvkpaty29g02n8etxckvrs", - "public_key": "cosmospub1addwnpepqd92ds9wcr9ut54rhq62upy8nfrvv6fv5t5v4zcwkqdh8xf2xe3wugnjs89", - "account_number": 865, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos17lfwqsp85symf9ftal8wdsmvavla0we4h9kkxy", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AyT2FjRoquHB89GZ/GpU07QLSUW0fF5PkY1TKjG0yVUd" - }, - "account_number": "848", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "6720783748" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384976604", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1lzkm2de9d5nh9wjzn9yhjj5xzc63mxtpkca4g8", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AvwemLjgIUZKTLh3hDCUbYAxrGjUY6xE1yDxdeUEVuJ/" - }, - "account_number": "678", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "24768164162" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384624439" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ly9aff4ptcun94q3cs26cfzqnq59j5rw2gl89u", - "public_key": "cosmospub1addwnpepqwexd522g9wrnztyvpa8k0x44sased9erd90c2vzdwc6lwetxxdxggacgfe", - "account_number": 788, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1lyvwlk45d2fs5aq5c4x97npemgzqy8yd6p6u7w", - "public_key": "cosmospub1addwnpepqdrt48pxhqjvt0yjfxe64vdaknu42wr4dmdt6tah95e6vja950fzv8pvncy", - "account_number": 621, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1lxeq6h6a8xvq6587nh7f5xkehdkn3wstqn0h9m", - "public_key": "cosmospub1addwnpepqd7yjw34urmgndhr8r8xr2pclxfx0djpjd0vtfgs3swpdwzprcjczashgtk", - "account_number": 134, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "Ap1EavCQrvUmMFxZ36MrfIMDPcETo6RaupVpktpDTklg" - }, - "account_number": "696", - "sequence": "3", - "original_vesting": [ - { - "denom": "stake", - "amount": "4910213287" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382618476", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1l802gyymr2zukzel8ge4ddnqdevjvhnm3g4kk9", - "public_key": "cosmospub1addwnpepqv0zmmgdpyvtphzy08gh9r4e4g75352hjm9derqdkhapxxaavyxt2ukmrc8", - "account_number": 542, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1l8slnw5jukpc47xr0s76htvfftpuku2g26f0h8", - "public_key": "", - "account_number": 419, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1lfqxuvenwj9gsm5sf5w7ezazwhrwmnfqcrj0xk", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A2iqq8yt3Sy+KjfgzSEiZoPVKr6WeuXJ15mm1mBMPe5s" - }, - "account_number": "506", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "18456773828" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382604366" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1l2mzrv0nvs75mjj5nzz966jxklfn9wt6wnnewc", - "public_key": "cosmospub1addwnpepqvzjl59epxw0px4m7m0tyxgas8x7lrj9g9sasa05g2ddel9eu254wkn0s6e", - "account_number": 202, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1lt52c2mwdcqfy5mu4ygz8ctlcuuaqhp7ckf3w0", - "public_key": "cosmospub1addwnpepqgnh2v5cycdsnajemntzeqyj8sqe9ksund2ultkltm856anxl9r6umfwlaw", - "account_number": 70, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1lvzau6mkgwnyewqvd09h307algs2ncrpp2ukjw", - "public_key": "cosmospub1addwnpepqttpsp75lqp82wj00fc0da47jkfptr6d9q88j68n500uytnxkzlskxtfx4t", - "account_number": 636, - "sequence": 1 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1lvr89hwsmkm9r4ahcllqylmk9ar2zeqtc2yjy2", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxiWxqb9ljypNgNJlaikId7Dv4M1Xeu4gTR44kAXVMMO" - }, - "account_number": "815", - "sequence": "4", - "original_vesting": [ - { - "denom": "stake", - "amount": "24365366613" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382583374", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1lderwuws96gg2e5vy8eyhpgegakeswcfnrtjv3", - "public_key": "cosmospub1addwnpepqw6x8r9cuvkvguqdx24myp74yx7pxgsg2yfl7eqgghyspvqw2tylqvzj7kt", - "account_number": 829, - "sequence": 4 - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1l5vty6svhxd023rl280aqu0eqjffv0qct2kywn", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AkTvMgRhX7m9fwdnWgNHpiRmJAgDhAqbs0t+mr6cuJT2" - }, - "account_number": "309", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "1767787627" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382608246", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1l5d2lg5hku0m4u8mh866zhjcy2dekpk598m8wr", - "public_key": "cosmospub1addwnpepqggx4jz70xdutt2n3l5xxd8yd3h6967vuqt0avxzu9hq0z84qpn9xrp3zws", - "account_number": 32, - "sequence": 2 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1l577787urj3qccxypxaznnasxvnn9k8wq5lxf8", - "public_key": "cosmospub1addwnpepqvmsdhudqln86snh6fpr7qfjs5n0u0xst27dfvujtdwfadej57tayryyz74", - "account_number": 695, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1l4g7xwjrlfy5lhcq4lwj2069zm3llvqrzhz07h", - "public_key": "cosmospub1addwnpepq06v5yue3dkzf9qc3tctcdw9pxmyqz7fm8k9tlw5nc9uzlcah08zux3rmtr", - "account_number": 575, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1l4dqy53d57ul42xd8wzs5zxk4ywkc7ax33u6nx", - "public_key": "cosmospub1addwnpepqfd79ep9f3sj30yn4uvl5f65q6dzmddudu5a3m0szgpwlv3hjr0a6f032gw", - "account_number": 798, - "sequence": 5 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1lh5v2ew6gwrugasrmt9tr8dql6qnj802lqrn63", - "public_key": "", - "account_number": 360, - "sequence": 0 - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1lhkja97vjzfjxakwsglnkspaparrg56p83t0dn", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A12yzICH9MwUu0q3uG+SpE9U1108g+L5OA1KBAeCt0Bq" - }, - "account_number": "643", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "9452886687" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382606921" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1ledlljk33qdj6z6lssp3w88cq2q38kg0j4vrvc", - "public_key": null, - "account_number": "909", - "sequence": "0", - "original_vesting": [ - { - "denom": "stake", - "amount": "11544444180" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382601252" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1l6u5cg3wcptmcjyhxtfrrfq3nu036acdauf0fy", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AxSRu4YhKaJMizzQLgycMyGL2+PWNI+4ayBz0DGaMNmq" - }, - "account_number": "475", - "sequence": "2", - "original_vesting": [ - { - "denom": "stake", - "amount": "16220446022" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251382601114", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/ContinuousVestingAccount", - "value": { - "address": "cosmos1l6uepmju2xg0h8rzkx8wku0hsncargw5ruhhfz", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AgVFLrXBadh053j0StrLY4Mn+EeNhclivXUQpGpoNX0t" - }, - "account_number": "251", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "16040652970" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251383553923", - "start_time": "251382579700" - } - }, - { - "type": "cosmos-sdk/DelayedVestingAccount", - "value": { - "address": "cosmos1lmkyqhjshfd4mqsgk5stvaxlsxkmdmfhfwh7p2", - "public_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "AnpiWNopLsBUXqvcM8GMspvRouwdrKEhQ4AXQ8HSKBDd" - }, - "account_number": "697", - "sequence": "1", - "original_vesting": [ - { - "denom": "stake", - "amount": "501013200" - } - ], - "delegated_free": [], - "delegated_vesting": [], - "end_time": "251384688518" - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1luynvvt3qre3hzald2tdjtah6vw00hdcsjccdr", - "public_key": "cosmospub1addwnpepqfkvt64fwc4t63pkxex4rc39ptmq2vgnq5s5vg7k7ddz0dgvujguc8x8kx4", - "account_number": 103, - "sequence": 11 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1lamxh5pswk923tm9mtmvd4t6pqru5cdtr5y0uw", - "public_key": "cosmospub1addwnpepqwpcf9aehefdxlvem9240m8jg5vs2sptj6dy0uy4h6sejes6g0592a68mfa", - "account_number": 117, - "sequence": 3 - } - }, - { - "type": "cosmos-sdk/Account", - "value": { - "address": "cosmos1ll2f2v79ssg5teg5trglr0wecm877aprl9tfhh", - "public_key": "cosmospub1addwnpepqf5l045r2e8w0mmvs575e7vyj96d2mcm89wp6zddgum2sjk74c4rxyg36xy", - "account_number": 238, - "sequence": 2 - } - } - ] - }, - "supply": { - "supply": [ - { - "denom": "stake", - "amount": "29053485105638" - } - ] - }, - "gov": { - "starting_proposal_id": "76", - "deposits": [ - { - "proposal_id": "58", - "depositor": "cosmos15ppnu758napp54m693ypq4fw7hzj8gd2ezydud", - "amount": [ - { - "denom": "stake", - "amount": "41" - } - ] - }, - { - "proposal_id": "58", - "depositor": "cosmos14jvurctjcvs69hlppa0dkjplczns7zlq6sy4vk", - "amount": [ - { - "denom": "stake", - "amount": "167" - } - ] - }, - { - "proposal_id": "58", - "depositor": "cosmos179uxhryqvrkxa2wtnw2cnptdt80qc24k8huvlk", - "amount": [ - { - "denom": "stake", - "amount": "33" - } - ] - }, - { - "proposal_id": "67", - "depositor": "cosmos1trs75ceuvsg83y9dje9k79em4v684dm5e9ya49", - "amount": [ - { - "denom": "stake", - "amount": "198" - } - ] - }, - { - "proposal_id": "67", - "depositor": "cosmos1m2n6v8dy6hw5798d3l8uvd4wjg6vssws9pq0sn", - "amount": [ - { - "denom": "stake", - "amount": "148" - } - ] - }, - { - "proposal_id": "67", - "depositor": "cosmos1lxmeul0xs7n8zed8xuanjlujhnfkx4d60yp6k5", - "amount": [ - { - "denom": "stake", - "amount": "9" - } - ] - }, - { - "proposal_id": "68", - "depositor": "cosmos1c6afa9c3repulws30tzpsggt5jfdpc88ct47wz", - "amount": [ - { - "denom": "stake", - "amount": "190" - } - ] - }, - { - "proposal_id": "69", - "depositor": "cosmos12nv5therrzkwjmvrmmnng6uqk2d8u6y77f7jp3", - "amount": [ - { - "denom": "stake", - "amount": "19" - } - ] - }, - { - "proposal_id": "69", - "depositor": "cosmos15dt0e900x5cv9w870mevztqwy88hhu2s6qp7x8", - "amount": [ - { - "denom": "stake", - "amount": "119" - } - ] - }, - { - "proposal_id": "70", - "depositor": "cosmos1qsxjdj8z2urjdxpp7uu37pp2pf3chjjc6vfqfm", - "amount": [ - { - "denom": "stake", - "amount": "204" - } - ] - }, - { - "proposal_id": "70", - "depositor": "cosmos198m9w8g65k5pc4hj9awpkexj37hctryqtv7ap3", - "amount": [ - { - "denom": "stake", - "amount": "123" - } - ] - }, - { - "proposal_id": "71", - "depositor": "cosmos1qj464sdtg245k3leszy29lh27h3texnhv0l8ft", - "amount": [ - { - "denom": "stake", - "amount": "18" - } - ] - }, - { - "proposal_id": "71", - "depositor": "cosmos18056m2nw355q2tjmvdslp9fqadmca5upmwl6vu", - "amount": [ - { - "denom": "stake", - "amount": "142" - } - ] - }, - { - "proposal_id": "71", - "depositor": "cosmos1spekj3vznh0a5lsky0hsk64w5nhkqwwker37dd", - "amount": [ - { - "denom": "stake", - "amount": "147" - } - ] - }, - { - "proposal_id": "72", - "depositor": "cosmos12wh7xjav34zj2s3ykpllnq58leslqaaypjvk76", - "amount": [ - { - "denom": "stake", - "amount": "163" - } - ] - }, - { - "proposal_id": "72", - "depositor": "cosmos13w024ysyklmnrq9c6udp98qx93jqynhge33crn", - "amount": [ - { - "denom": "stake", - "amount": "108" - } - ] - }, - { - "proposal_id": "73", - "depositor": "cosmos175ymjcx74rnpkhg0vsnxgqlpxk4e0tqumyvsma", - "amount": [ - { - "denom": "stake", - "amount": "164" - } - ] - }, - { - "proposal_id": "74", - "depositor": "cosmos10gssrkyrs34zkv6uldl38s3jhn5dqk84zgsgkz", - "amount": [ - { - "denom": "stake", - "amount": "58" - } - ] - }, - { - "proposal_id": "75", - "depositor": "cosmos1zscesuffz58dc0lq7yy6n6z3j5fhkr3dde64ly", - "amount": [ - { - "denom": "stake", - "amount": "71" - } - ] - } - ], - "votes": [ - { - "proposal_id": "58", - "voter": "cosmos1ptu2vxfcsyl2gpeg73ehzte7t3va459lrazel3", - "option": "Abstain" - } - ], - "proposals": [ - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "YkFEBYEiJOemASPgePTuWgWbCtPMFXrPawtBnmZGIahHdwBsSYJVfTrdzMeFNNoAhdQYhVjPxMaDQHiQuSZepgrGkwzyxDpcOJuNijZwZjrWZrrdPJheCFBcsGyoBwpHNGGoVbGFPrRP", - "description": "sNufnasYkHdSVMBSOtsMzQinBPerRwqHdsXYXenFLsAWUdzvwTKfzpyLzYuMMOmHhsJZCQtfgZkjEdgIUFJgIjpHZtvlSRECioEGodiWfoNDhYgKliFetusZMxERcYUPLgolTVCiVWhsBtrJnkBBqorrRotaSJoSVdwkYDdNvxcFXhCCapYzBvBrAGhEmKsCDNcwRZHyodxQFmwCkJJahNROJIgLBQAlrqTcSuEexXGVAUemVxlyyPzBLMJormlaEXxJrseyRThoRyXIUWlTgnXQzUcvmkZfQVOTdeoXpGNPtnJZqPmSLaTMPilAvOgyrSwpXdNRHLSIiMDHnYwqCIhMurIzMhSYyoOFXvtrlVfZlGuqgyRWmnmmbQRJXepnuUUTIexmaYIRcSnGwQznVXbVEbKmrnUrPsWVLbeVDMsPiRqGHpwirsTamPvdbFTFmgTAKKAmxKqwdjqcutpTiqvQkCaMhqVxAruUwRxctUQJUnbMieaUTlqjWGTSsobBaQiMhyMTbZUSwZatUOeIvTTgNpxKEEChAQYjCcbNxcZvbcLjJsukkMUKYfLwpoDkMRtZqsRawXkoEmkRtdlIwYCundwunTZNPVpGUIJJBVPHfTEGelFgdjYVYRAuMUvdSyYGlBwtwgqngHQhWwUSbZmjMiJNnlYYnOqnPSQkgUqSMxbFbiGLmhoNvzHvhqnFFmUuCYFagjGugzbKseTcukqPoHkdOXiNMJXMpQKeiOotzYiWVTbmgDXJjOxubIloUbuwbkeqAYzXrhNewBpeokaMPskfsWIylswjQlHcgTqJSCFXKgJAIwDXRTQYmKevjpaIkMwrQmOKViZUcSeAkjDLDxnQaMOuInExEPynOvQxXdFMeDOsVqDUOqawILrVPqrAKWvEqcPHnqzGnnWGOLCzGYVaqtFjLxHHCBParSWYLRCynDYYakjSGdUwOuzERUNsrEMdcLNgzQuxkdDybuoTTxMvtTebokSelJwHDAESkkiOAHrkYEdLxpMcuehFEZpgRFIqyIOLlGOZoinTyyntboAPYkFWHFweTgPVcEXqknnByEkZhiOaIYshnZfOyHWTfNbXwLIVZwuHzwdghYlbvwtojKmzMNdBhAWWkNEAaYMNYOcYjaVLrtXQpzasahLKDoCrxjUbaKqWbQmhIibXXJwNaaeVNhFgZiQJlhtCpJldmCYNxASQvMXkonuMnXAruUikjtqsiBmLnCTSgtuOWKKxCPkFzlfFkwTfcaUusDrZBQVOpVHAfFyRsuyheFjKwCfvQnvsLDJEBnvPOjlgJbgkilAfhRWpTOtsswBxCwlPQROHjVzvGQspFoNwxXDqYMfbXhQFAttvmgkBIPjIxlGvlvuEvTTBnapoJkndsHWCxfEoPKTBhWdQbIMmKXeLCIoyIoGTYAJsVfqWljflerpzwkZQdmbOONJvzArNAvBTJIwAsyyGONWmQdYCRMQThEOTAyTdHpNJOmKlaGFGrrUyOCRSbnhjkDSsRvDhlrLmFFjasxjhJldOVBohpjrKcvMXYdHeoUbjgIflqpDzmGYXkAGlbWnvPAOFmSOhzytRDesxLkCBLAqCiEtENURvEvuZRWUfsLwVjgOoPvHUnbUMChxjQKvhPNOBYyIKjUiFliPbhbIDZwPqdbofviGwiSXxZXdFYodvNTUsPABXCNTTIFGRFeksHMuURnXpZMfGDsRjhSSUsgiOyGwmahBoUnVvjrOuYiSLWKPwEzmnCCzFwNSxwdyMGFEKpqhdEmZjpWaxPGpSnZxmzhCxJtlbphqhBgLdCwljdqYBhdLRuCNQBVRCacKfDqYlICwbzdcfLYMBdwWHHdJtPPpnVJEyZJMRmSlpiqhNnUHTMdYpPHrNAMcFDYvWmWqcDBwSQWWEhzhhnioAtLeqeAtPRoSItUIcXejVVmEYMpWAFwHvWUYmVHxdWnKjCIxKTMoUrFLzlGmwpFJFyAARqFiyZuHySgyoPZTonpgVCOXbRUSylLjmCRTsPKsTdAOiUNpxjHFnPEElfrecwSMgHGKhlDrOcFUddGgZIOhkarRezLqVvrWjVFpKeRKyeaYKoEUqgsftxbVZHEIwBEkfkXccMHtfkPqaZgngsPtZbZCAkGcJgdSFbZzryuEJEIsRcEUMgEcfsfamsaVhPEVamtUnRLKYuRGbELaqiQItWLGuvlyClVIECXMxSGLySMOjgrFVDehATPXcuUnanirQCKuiJiYVoGwFEJbJFFvNKHTPmWJCubvNpYUyWODwXQXOuFsyBkWKkpUEitwjBUGMdllUKCtWvScsKuKcrPTpCYcQQIgLDvIjSfXXiHFlgIhBIPsJrSpgbrdGWCDjTxJPAFczHuyqexHoaObPPtzjtjtNtVdiiQloxheZNfbqzbyLTjhirJYYgekbXPcLOWcGnjVajHdGZQOewbUASHbSmoRQGvpDgvQUchaErwdcHRznZBAFQlMlIQUSPlSLFhBMFKfnMJZqSnzOnwtcuSidSnLfhGkZgKmHNiempoNsfPvQifvsegjIbKtEzqnHluglmoKtxRhRvpfHDbDMsVfvDqddjuXFehRJAYsjpyiRoyTwCjTZafPohJsKRwfEblmNuZssqQmPgLCEOsRWOHnoRdfpDzoLRelpqVGctdzKbHGpLcPADBXDNWaSUlLasNmXTSUQJmAvQiaQWkmapvyxDQLITNKiSLgYcxYSHyyciQYLgbhnitaOamndjsoHpcUQfKXtwactIgHoMQDRwUXTnhCFpugOnFAuMMOlcaXyjijloLoycIJYMSWQCEXyWzcqOoxIsySxcpYGaBHOWHVbgkZPfxlgZjRxAtmQEvgdmLtolSnWVmcMuLTlyDDBvCyiWSBKKoYkAOKKakXbTBftJuROktyDiEBoYwaCziGFfyGRBYlZnNSuzIeyylqJAYTQbOtQFqySPPyOOSeOaukCEqBenUjPNgNmwKlRsidHaGAkXsxllwArXxhbRLlKAlPIRJhNhnbEgvcahygegUAjQPPjrdRDipXMOVNaNpDFRYSObCGvPzXGHYmktKYScOlfBPfqOgQWsJogiuITTopufeujZuFvByNoanpTBNcgEOLYbyFatcYwLwiNNSptuOBgtnbTuYBajEWpxridWilCWuiERdaxbtRggooCArGVjfjocgDHJCvtEMzRkcTJNwCsgqaUvnLskFsXeGLuUTcDfZBciVsvLenCBLjPBLMttbGSPmbiCmgfacFsZWzKRVtWOMFvNjWkpyrSTpFVzAduLLPApLEGGcyrBYMxoumAtbxOMdDhueaCuwaygckbzjMMSjdrZUjwYthAxDXnGFjNeiATjwuCHwszzEjsCdmkTNtTmdwrCOqMPEAdmzTRoLXOvKflQvgvLwhjwTSZydAWbyANLedCQkzIpeszyaFlLwECaHKHRCNcmMNCLteyJURoCahLxilxcmqBJPLMjLkTlSQxdYkvxSbzyWPGzysufObAFreEAbzQshHXDNcNaKhVQSvqaWBwpsDATweRDaXOeGlgKwalgBqKueDvwNYCmarjUnlDXmaClkfwmbBkzNRaZXBxlrABnbZgBSkOVbKxwXqgluHirdKlyruenBuUpSMVCpWPbGNbNoIwOoFAJbWpktspIUVzOPkWxLkSCqtLytGGWrDuXewJhDRpuZqtDHbOfdmZNiLDCZetdAdwooegQxrXNKwMnvLgwCAvRUfUbEiOqgNASYdTONUhyldLCyMvGfocKuMkFmXVzZMrlGDzuHqVyhRlUDQByhSmLXMkAkYUPSCmHWzLPFgzAXSZbDWGAXrywdPMTPacCZMtYGYVWMpRhAhtXXdKxkIjzqZsDgWyxYhithPdOtxZxlTyeJdnovavrrPIdnlybiiHnpGIWpOffhgLMiuhBdctDUsxTNBxitYCkIMajKLaVpkCrTGezqIjoUBdvtHBethJngmHcgWYGlSRUcduLTFjoFrnNCKMjiqBHYjiddeXaGPBOVnuFXfefJiSGvTPCmpAdChXGfQkFLNugvYTvEYtPKyKVjOmcySGCMZemzRKzjSxCnXILIpCaGlMYJlwxGUHEMJXVIHuFHXGlRjuwEeZJArYRXlIYJLsZUNHPfHqwaMRKBTolUEIQewAWdFJexnjkVgVovzDvIiZHlcuCUTiFpveVRhFIAaHtpgbinvrHYCcXHxANRoMsmosmCxiTvmodEAjaIDhUaQEBvNRvTyPHqsRvUJnZQTMbqhgjEMNOqgOIMFMSmSHEdcRoxXSoiHbBqHkqCCOlkmpJAsoHVMWIYyeRCqhAkvHqvZTLqyqFwYQuqbEhnJdRBOecRBhrrFqFekfbMdvnoEYfbprwEehDPEUfReKJfhtxVfYUYxVwiEZDyTVkkYDDOrMOKSQxiaDUhjsflNJWqyNwxpVLXGbhnUShiGSiuCNPKtWQhTgeXsKCmlunEzJtoxmabdFycsGiBXHiadppalNIvKYgQAMZcmCjLxRugqxCkitPXVPYpyWBLdaquOXenBXJleAGIIWNWfbWXGZPgwpmetHBXRAYATdwHoRiEeKXdJzFpCgTEXpAWsMtnTFeLMsaPDphwRcDkBBZDbtBihZpkclTdAapoxzCkQUPzgLrztpsZNEKxeWrZUYmCPHkGfCAWEjpvkEYSXAXJAAoFTOcjNurgzZmHFImwHAlcvxtxaMdJsWTKpdKHIEnakaVeuvocmJDnkLBTOATEbztGPgEBUWXyjHQlPuRBPBsTjiSZBbmBoyTWrFQxyrehVAfIXYhwtTVxEeYCZNRBaGzNOrHpEarCHWIQwdJMpMKHOAGTLqNpPfEWQFseWKrWfgDqpkGBqkSqyqsHgqblHMUyHqPZfkecAQjzvuCWbYqkCIdzuCxNoeOGnBRrGbFLzZJXFEViTrMdeaEZqjRKwmSHNEQWZzwTwRjpzlpnPKsmbxRVCVFbvnZXxPjGKiYNPBfvkuedovlgQQmHxOvIkxKasMSPBM", - "changes": [ - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"11\"" - } - ] - } - }, - "ProposalBase": { - "id": "14", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24914473521" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "379" - } - ], - "voting_start_time": "9935-12-31T14:21:40Z", - "voting_end_time": "9936-01-03T17:40:38Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "bWJHwQHLNnEvNLfLsccikFqiNdLdPngIRNWSNbkPXJkniBPnjCsFrTKMhqqwghDtPqILYkLPVeCGctBLsfnXfrOYGgjnnTkuesgGvrFEDHaAHoXHHwRHzCNGtVtZnckDLaqHZfayjbyz", - "description": "dxqSCpFwFdKuQIwabArPeVFfiCtaMhSUOhErUNiOcHWeHtmLFvaNKIUReoIMHSHiVzxniOvEggVdxOitTWDuEfPVqSWcNLVCQlXYOmWxANhPNBtsfoIfkrqItYsmwCcjDovjXPetnWkrJlwbEUQJuMAVylAzURzQPlAJXkUxfzLJtLRdSKwpmzwsWyHCQSffHHBUpIbGkzTJvOdzfYycGgmfHSbsVuSIghzDySUlVRiTMBfxEFPgmBxwMsajgqeoFyGFpTkUGUSUNAYqBIpmysiiWUFJclYwCNDMhZXXCicSgcfECrzVcGGuaHZfVVzIXGybpEKoFQXTNoxbktLMxNvRNzICjZVIxtCLmoSzPprWdXZclkJcvMPJtMqwkFGnjVlFbSVpNPhzuZdAfXATsCFZKGtDeYNXHKfngdTiUVcGHpoTLgHiiaXOoqubTRbKhelUOOKQxnVgwXuxKvEqhSogvApHbOQhTWFJaSmphVhnEjOWtDCzgIzraUlosZyqXyLuQKVBIHEfnFrQacRxLZKrglVjCdHjQpRENgmnRXCAChqutERhKmxvwSysWzwToKrYIUUnsGpOkNWTQdJhDHFrcOllWeVPgtdDZNcJIWgcxKiRksGVskQmkcmrEouGPWiDPFkHcvSbIFtDfzKsWpacOhuqpNoDHpOQSYRJamuuvshvrdbMAdciyvyauFHLxajzYhCuCJhkQVSnynJUYLbqohKIvAbmodEFWgTxbTNvpBQmFnMcmHRpooMOZKQAqblAzMYtQnUdQXBPJBrvUnsKmdxzzEqwISykFtTrQgnZxxSExwTjuVDUYzGvMEDDPTPVjyupaJmblxoGVyDfJQITVvLXrzTbHEkuGdlFzxgpAhyqKyJVpTnlmBOqsCclYyyEOQWqcEMbFaymxDwXFAmECPiOqfPddcOgUZvAqVqPEMtUEpFkqfbXNQKPSnNeoawixOEPhTazfsegmpSkQvBhuWKSJrpmrCQNUZdoHstArsTRYWoYylNuSqhsNiykMARmzVdhNGeJkaCAmIPhonhREaOiOGumCwanYlIXjmyjkyLAEqyzcivhLMhAtbiIQFDJAMiXkKrTlzcfOjydwqiqGiDzDCUgbYxBHdbkhmrXvzQpgjpjDIzozDlOMecpghkYCdgQqUMktEwIkgDWvEdLqZeCViInHKkUibUIqaOUNXIqGoIkQAkHpMfVBhfJoPXJEiSSQgxmJoxISpEWRnXTXwvkzHiIBBNJBClKpLdqKqtIlkvokmtUoINMhobeXlrDvmsFjIkJMkFSKLZbRLCxXadhRGYjAPTqHQNtOVQegCpHvEWbxfceOmxuZOkknmtaBmwSjXQaWhJkWuKkidsCjYWHehEcjkOJyaYExZcAErrROBUjYXnSiilPHAirJFhOBbjoAsNvitRtlDPLtwZfrwblsSXgtjLavmxTnOKNfWQKUcuhXiSaWJnNpxnsPHUHFbbfjidDBSegzBnBmcFkRxAFnmOynEmIADbGLjcGEQUWOitGXvnyHcHyxBDfDfRpZNCcbKxjMQiHaobUuBjxRhgiOAPbLHuhJIdHURDYlRUXTcUVMIbOBXPUNiBBvEjSPXlggkOitFVRsWQnEwcTqhxNCjnhrlDPcaedCFwsyYKozEzVkRvwXejOldittCuepOZLLZQUKmdZwLERpFHSAdIpnJcgwWXjcLEfdOcKgTuLWdZDRCWcDnGkIBJgDaxqBffCwDUPxKvOyjISmPdPbnJGsAVnLOGowFHyqxAhRDqDtDLPhbOjqKnUMSDhLnilaLXvxgAJIfXncdFaYxuTkZqpZkdIeoxhwSZMkGEeItLVLCLrWjWVEUvzQNRtPEPdjtPMWQdzDMVDApOSWhBGgduPatuWIAtNAxlEaEMaaihHFOrnQnKqJhihvjHLTDRLZFfHlLBxfFDVdLEkkGVSiInZrdQewoAeXQLzNbCXCeCIucVwPCoCfZfJxCpdxnJkHyWrFMKDUUcobbZBWztTAhBWhUlYDqAzTOBEeKkOAfwJQOKtWEOBUrrIoCHmismmZyWqAVcwTltGfNDrhupGvALTNEDSuqFLofJEmjnufQzdpbazyvvJMWNQHRrNubmusdgMluEfCoQQmgKfRLaiQPLqjMlsDcmkKJWhkjHIrsygURdXbOFUYxtPGorjFnszyEKcCZjFdqFXuIJgPZmtUFWvMKgBXOiAXHZlxbHvPqRkCXKPAeysBJpzjbLHsMKMvVGfGAXeFODAjMcyHTiBhHbMEUBxPVZJhQRzyZbsuFfLEiYcwcyeedlhUcTiWedIoZirbPLBsrdqGCwjTrNxfriZXBXFjxAOkrTsfJIIWwcWegPsagnBSNwUgHlIIVVlWHiwHJTOKmEpFSbwKcnffCVPhtrztNJSlsoKmxHXbRbAyQbNouWcdWGQvzbHrXRqIIGvKzGYPQDhEIPKpdRMUMiVnJFnZzSpkjRMyhGtoBmHOjBZYciGrjcHFisHsdoeehTOzaletWYJBVfxZDEQqJqezVehfFmzJrQoPCVjoBsOENSgFIYRuxudDbFijBkBmMrtHSyokCfZBALlnXnZYklHCgqltrfQuBHGadnOAGCUCTkAxQxXPGapjxHZnRDdsoHXifEQtRRtyXSWSVKFPMzfBrphAopxBVOMJKkUNmdxUiNuTUQdxbUpNJaDCNPdSsHUtFwFkMAGGaliSdsAlIcIPvFYVyDFFMAjiMRZZMCIDAwkNbzIwmgtbGkvLrcWNZkvyWHyklJEgafGCLVblrPDBcwZuwDqOJzDXeAZzPCgcNFmQHjgNuCggwUBImCisuDZlGHEaDDCMFUQxZfZbYjvsJWpLVYlzqTKtfRySwkzVCmLcqrUuytsrlFjKCEauwLMEpaAPJFlciEXWZnBkBHxBUUcdonsrsdMtTlGJbXloJWfMAXtdBSBqFkrNOxDaZVqTRExLVZusiEKaUCTKTOLmwEjtyspIHgOMrgPxPKnLepZiWPVxrjUOOHiPuDygEIWtVIJNrdTARHTSGBmRseYgoMOlhxRsqvpBsKIaSrTdgBOhzQHkPcjyTAaRZYkgcRlNadajmBEcDMAiaFhSMEyrBxblkOuNUsIxvyqlTOESwrHPzsBmqryQfTzSnTRPreYXduyGsiGKgmYTcRcIGCFhjObqRPaQGbEqLbFkIAiRdDXMMPICGopEMoryHINWFOkldaDUsMkPEVBaJImHFMhxgFyiRLHqybDfiWdwIYsdFjTIuHRhpaASVIdmFDLmPwseoWjBuRkNaEMKmpfwLbLMiOAfyxqEWBwsYpSjgykerItDAyHpDCIOksIdeIFKtcTIRIrjXrvGpBMgWYzGSsUdAPxohhthNKIqidewxjenorHutNPNGSUMINMPCrPvSvXnlnCXVpxDevTjvfRYKHlxvzXQfLGYHyRQryaJAcJOLXLSpNjFEcdCcxDQnmAqQsEyliutHwqwmZNEsNibcMycejQJPafHLszTvCmuKRsrYVrrTTlHSRPAegiWvnavuEpFDbAweNquMPEEvOdWoFKlzkzLrngPeLPKdILtKjISgCSXWXaPhuNBHvFQOSdoNFtVlLLiEvMuQoeESLoXGsoYHpSUmIbfHcGepGRiXFhuEPMnronalIjRhfpHmxIDdyUlwHWUKNrkooBCuRrQfDOQphnphgrjZCsXvgOsgcLVZzVZOSiksnbpWmSKlWltvlBNxrjYsJRQADjqvrdrfThqOsKSCprNtuRycqHsaHqcbIKMfkpiOyDqYpWJxJpAXlxRZOcVOOpjBHIicboLmnsZKIDGbAYZKcYgLCykvvvYuuBqTsZRefTQNtqNqClylADaSzLpkiXMpXBxJEzDyaNPwyfrlCkeIzeLmlOcmjWQSfbXDpzRUCrNTuXcgyhmvDlSlghxzJzNLNWaIEKYmRKFSMuifEqEsjLerwifqoQavxjJSXyfvVzYzBVQtLGYDEnMsrHWsbMJptOVOizOoEfxmXRbkrekhIgxxlkSYJdgFcfMJROlvVhbCNzNJIfrgyvceiWpffMQzYiqQJyboDbIiAbleeYXlfNJnwPIBHGuQZvviVNOnLoXdTsIAdRGeSuIpeMSPBnOzJUbgDYbCotZSLdeoIRAXimPASepFKnlKmnqMfRIdWFGcGWdsIcBQYHTtmVHzYNHQZLJCopozIJGxWgJPWsxSAnXejDwHetzRJdawrXvRUeQRCzRXVcyVKcrrTmzfQxiVGwRNOcOxgWQXtvzrBLxRQkqWifsXCpadrVFZKjWAaoDejLCsahzdFZulZBGrZkefRupAplBWxOfiEVihKECOUyUYZpVxRnzFRahVCXprHSVNnsyGsZRdlzegwpKLPJyTrCXDuMkpQJZbqmJykGKAWmFCzMziNEsTNcLumujUpexqywWFguHSCmdFfuidNfoUHUupvIlqTKSehYMCQVqsLZXGpJaidgqZkUvgTwXiuyGVgldgHBmxJhdGoknRJWsJwVKTwomZwQLprSDJzAAjbfGfeRMBuRCfhBLNaslRrAZiQqZoQuSLPSpQVMiXpJtJNnccCLWwALUzQUlVFEqyZkuKjzrEqXTlbUYIwIaFNnIHZtEojiYigmJeSotHzjaiTueIakOmAEKeQgohPXVXXNcdguIdZjUiOOTIqrpUBQFHDqofRYLVZRLyFRlCTQyaWTfCwhAKNQCDrWZfchhFUibKEkTfoZTIlAXqylIXEhvICsDTOUMznjwUqoJxINpUVoHjfNMCtVkhXSkfedhvtBiAtPBjjmsjPxNeIskwnXqqsbnoFmwzRjAQKeBrtGfrXuNWMjBqzjYxpCDdRFOjZdBKMEleJBPAETRBskwrycyCFmlEYwuVZBlwUCUDhsgImEFObdooPfncaNcEzBHaXPwguaxbbeFxHySSOxsaZUYohBcQTAHdxywhaufHjTemrqwmsCmmuwBYzOUEVlliRWyErTNQFzthNuOHAjzDJbUIyJfAUbESDq", - "changes": [ - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"469\"" - }, - { - "subspace": "distribution", - "key": "communitytax", - "value": "\"0.270000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.000000000000000000\"" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"8\"" - }, - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.150000000000000000\"" - }, - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"65875000000000\"}" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"140338000000000\"" - }, - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.140000000000000000\"" - }, - { - "subspace": "slashing", - "key": "SlashFractionDowntime", - "value": "\"0.006896551724137931\"" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"140\"" - }, - { - "subspace": "mint", - "key": "GoalBonded", - "value": "\"0.670000000000000000\"" - }, - { - "subspace": "gov", - "key": "tallyparams", - "value": "{\"threshold\":\"0.528000000000000000\",\"veto\":\"0.268000000000000000\"}" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"8\"" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.180000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - } - ] - } - }, - "ProposalBase": { - "id": "15", - "status": "Rejected", - "final_tally_result": { - "yes": "24914473521", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "279" - } - ], - "voting_start_time": "9935-12-31T14:21:40Z", - "voting_end_time": "9936-01-03T17:40:38Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "GnyeCBHlVGTTJOygZEldArmWduzARmgGqgmaJHWUzBaswudWraMspToviTFqlUrDpkUoWvlvzftyZMZbOvIySZUUxxsFnvvnsUYtfJuhgqbuhiyHcyMWrIIwBDJaVagQhCWATBYgmAwn", - "description": "BapgczncJLcGwJHgFYEBebKdPrzNeYFVJcLOrdGGBVrRWXjcppVlHYHKwZWGoDRCKWOFFvsaYbvpdpiDvhOQVCKXYiKCNdcAeVfjBZFuJytPQPvyyCKgWEpDUHCdcLBjyKxYGjGWDpoYkIvpOJTNYIlaUKvPclZkCOfUTURCtdMUqaTrvAYZrRGhYzBLBIZWQrviedFegGlTMtTkCpCPVGTYCFChuLoqkYpIIrYQYGRSsXnyBmEglGleKbeLHKDsOmYcmMKIPSTEBZFmtHJAIkMnvSCfgHWazoOnWlkRcLXJXORKDcQbMrqHRFcaBZkVhUNYLtKdfnQZRwzDCcvuAcaAyjFKIfhubhUhFcSJaUTiUhHpjnyBSOTsEiMuElAwHxfEEyMBiLjIPImZOVdzpjNksbcYqQqInfYoBKNfRvKphzkPpjxHeRgcSVttnDKgmmsEkLVfXIcIPpnAPhroRUCrEBQaQdErLkffxcpEqQJjpgthBNltQyiMifhILAztKZmNYyOFURFFYQYuGgiaGykPgXxLzzqNvsOqQsWzlNFufuhjqLMkcELTHnvmwZAGFWTBBspkJmbcIiGWfwCSOGqnJWsYzFjSifzwSOBzisTMdVrALbRjuWHKpMWQQWFcSYXUuwtxtWgmKWQkPerPnKzrjkzNZBbrSWrlNHfbApERmBRQNRVtllPQZEsMWkpcASugiHnpaoKtstAWkTahFFYFetJrdzdnrqTPEpjYdoYbdBcDwvZelwETOtNZpEVFwhdoqIOhJJttXUvmqbAPTiRnbDvohKADvFqEJgugUFafEyABnGnDUecGCyqxqYogsxZavrxQarmIirckHNQcYLKJTazjgciyUJCbSfqIePoNqTYfQYVgpMKzJtIfrzqUDwvHfvkBGRMYlCWZidhtkkaBAyPerGClafdpcSBHHTmUnHGOTHqYjreNYNoKYHVvrFIJoOiBsHVzWJwskMrkBJcuedDpoSPQdxKIfKyduKmPHbaokBNgtcHfJeTrpmhLlndYeDttTQiawTYPUOHSUCsheFGVvjtQJSZbGouiegADLsWtxcCHUpkMSfJfnaeheSWyLsuhnUKpircsOkscKYPRXhlQLkcUFOmnTyOUpxXuAmSRWiRpsCcWhkaCTTALUEEdnnMMneWoKXzGibjJEVLPRYIboERkZbipYhWDAPlCGHnklRxeXVgKLsofrHOlSeVJbZKrMDsuiOiepkPlreMNMZYZiPkvarYKLShJlWXcYQLlJlKKyJyBvCVJYCvWlJSCtsoUbJKBHHNbxDOThtUryjroRhIcwSeEoNsmrrgmoaOsNQCSwQxvFNwPwBTZUMODcIFMXtIGrebvWPKitjagReLfbViJlkvjQuuPpQwHdESFYEXEwgXdPAXNmrmsOdWJRODBObLfKdhPMkftweUVoPTDLbKiqIgATaDnBEEWpPdgQcneRWtlHnkEOWdBAukqYfKFOiYYmwgSPBJjlxYmfPCNNLHcIAfNPIlQlBeqFUtbdwoWmluNoMvfSIEEiJxxjupAbggRxeeywAfOiqYOgvpeqNGvuZQjGoijUUusmvJZiQpvquxsfCXhvGioxzHrFLObyBYOSQmEnIDqMOtTYxCcJuoOhEUVadgclXTtdpoPPvyCLTUGlLRmZjtQhsjPnvKRqWItLOoGcLQQPhuHKKclovBDwtpDIMJjdOvQObgAprUQZAvBhdEXLkGCJXlTtyDixWTHlQkdSfBfeIpDvhubvwIRRlJYTLCuFKwrBNQQsjEpXOCALTbCWBNTCkspryNRstHwgPnppNMWoNuWWWveFODYRkAqTOVMcHIQfxsQCDkUJsCEIcUOFkEKtiupIBZDMoIebqHVlzZfBIVmWRdDjuXSDLAbIaoLOepehwBAOjLLaphNJzAnDZjmsmVoHffBFjtPGxESpausHsmkRjUsCZwLRaCSTzdopQHfMQhGVbBfKjuAbGcoUOnkxCZqTvazzqtNdAHTKqrlcNbelsNQIjsGDgrTnuozOpZOQudwYBSYxURwiEbRuHykZIZHllGpfkqEecMRnHwEgoyHYOVaUBqXuJjbRbnzdCoapmyIBTncQTkgjVUVBIPLlYIjvtjhPGEsuwMQNxOlVIpUGMfObgnsjsoYwzPadkKXkmicMuQHycpRsFvTUnxGtNHzXEKniWfOzlvPoiizgIxYcgSfPpXWshbXXwZTgxVRKMokDwsOtbFVoIbKCVxaViAffugXURyxIExUPUOMtgRMCTlCdcvxzDZYwbmHKcfqJzFqtoyEeEFgjSbVkXXTVGKWmYuHZmaSHtuaZdrAGfSJHlSeEkgxKRndNtdKKRQuDTyfeXPgiMGZKnLCoRfkflJVRDQjTcVFhypbGALSrbAXOUJIQnjGmlUhchIYYIJVRQnHvcHgtpaiidAVzxlXnwuvPPDLrWBsYkPbkRdWdkAUchyNCPZMCZJKmlcZvHFdgsqTIVSNqXgUmPbwsYXeciANfoHpvUFjisXcTCVbQWbksqNYpgABWZVTdXzwjixLzADkpSjcKkTXtVEfJvmtVLHZTquTJDlDGWlFmBkqwQdFNojpGyUirvQdftDKnlbZKKThOSYEpJUfAonuGKoqGPBTeupWYkmNTJjnDnIKrQONFzeASWvlRMnhVhZXKWITRDTUofBQwFxZxGfMvpNeJoQNJpcRdhhgfywgxpHiJwljKMfQYNBpmOppGfZbzaQDQBQKndNKdwjMGufABFKNmCUbDvCtcKUhbIkiRonlxDQhQDMlPqlycgsSlehMYxvHdrHlnpcJBLALBIMcQVWLVvXzuFFPAgRCHHCNdiiEgBUzdDCSzUWmBCXLmJGTWgFGlkpYiLjaVrXntjsVBMjEKaREKUXXfxKqaGjotzholsTsJfJQmjXzVSTiSYXeIDVOqvvmrChZCdwVbXIlfkdYNRizUyWFJMBjRjEZHayyFoPkbiedkualskGUymMpruiLmGyimgPnhfbreovLMxlUObLFJJuTJBpCKSKcxKbCAoICCgAxvIKYnMixBZiIYUSgpOVRhuEngjcbRHPaVetrJhrndNzmpJrwUFCjOWoqObZQhZRUnehNHglKQWLWrZeOBvZjsZkGfoekxbFAPTjwKoeFTHjMTqrGMwvtvkDaomnpIUwePYbAnpkDYfzPCYISnsGNDxzmhDAkBkSomjnpoMBYIMeDIQNQFnLJnoKGoNmaYAtakOMOhdkdQFNDUzMUVezHzhtzwIJIWwppJHMpIBZUlQZgXCODjbTgksMIoixgtGPevzzOdVauAGDgywXLlsUlrGJvkMfxXmbkIEWjNMhOcUxvpikTaIZrdOsIlzocSMANEiShwPjaFujZGsiDuZWtLpHPHbfVAtfSDANndqgdJLkMLzAOIyvTGUDuZRtzSgakbMGwFfSTeCSEhfBzgIKdNxAXbXwRYcAaYOLngiOGprsFiEGrnpifmKNwPXRcuDzGigILwOCCkaoKBVYyEGVWefIRsRxkuLdpesmLRflPbqYnblxhbPhEPUwjLfmaJvytVSpTOTLiUCyAmFaknecbozuwXuQldoEXglRwDMUprIUkzbktrqkwbQBbjKlBMYAdFofCVmRJPgpJBNSeEotiifnWRFdIGVRZgVWDLBtnVNbhFQDbLLELlTBxWfTwktocidCGyallXzUXmzHrWHIbfqhQesKdGIAypIaXmAavcFNZpkIZQURixGEUuvcMgAbVvbpyFVroIjjdjTdFEyqjVfZWdmHwcxpTeiRzsXwBNwCrPwMdDtzEGZXxJeUkfhQCMAYZWNHlYwggvMfNoinVxYpvPLFTjLXmyDwnBxJFgCaPbCNtqSszSHQiLwjtrtbqzmNKRpWOvyVFVbeeCVlskeTrdhsrrKDRPUMIaWQZjyjATLxOcIRwTWqNBJTpddrekPXihWBJxPWJTBGtBeRMJLUFcVzNspDVaPZpvmXfpcWTDUbquCsNJVndomnJfPuqSGyQeErzJRkvAHElNyFMehBKVsSxNBjLYHZFrVuGXEPURpXToqgEgQuZuDJdhxbBQfJjrfYAaNHoIionbnJLzyAUXZQRNfWkZXSRTmugcUSMnIIeAYekNrkuRtZIjxmSqDfDAzoseEBjwemVjkSOJBEyKfMpVxNHumWbvHkqzqPTwEksQoNAxGEeHvlmPoozXAOeROjYkIANrpRkdtuhunJSkCykvTwABwCopMPESbOHcxQOLesYnXWioEHRLzlHJgZOwAiPJTHOUnDkUJHfTicReoFiOOuGwyyLCxoqkNgAtMrsanqsNEUDbKeGjtQXKkXHxdVeEzZOFQoDcYMDcwkljRxmIluwpvzXBEaabYtGvADjwAPFWNicosZEtZjiEBPohHyBXNHGKPXTGaGBuPgRHdZDDELkunznfXZHUpuhoKEajIGSDhWhntJxSdoCVcnzYUwuwhPFkKDeKavNfFaOROHiJotRKOmYvtupiBSUlAhmMWaERLBOZSyOqPZoQRzavEsHcJKjPHzwiwpkaIkWYtqIPWMbzpLlYYQvZfjuLSpnwNOdbqPyTLzZvBuelwZRwNycDTUTRLMRVShsfYTWdjFpQYtWLlOoWikyxrMzjPMbsMJBOrnUJUcxylGTRVkIypivQXAKlPNfdHNtEZwwaquZJledQIuJPkFUEGXDOHBDaQlXAdEijNvZKexOioatXFmnmhRWwczBdQsBLVTndgxWNPihnHYDpwJFvlNRqClICCwnRKVbKotXEsnNRGDbkdbXSGxKQFLTnldPJqfMzLAdtrDNKGeSEesvEXvKmatyOzaiFnOoQwmVZWFfJCCRUBvxPcKsxwcuzuUakGKiOzVKMZtbSCtJcdhqTtVmhnCNcSxdLBrocXGwPbKSZTeEgzuQhFvmKWSTAajXDvCTUnyMjhpIDlXiOxJKdqIhlnqQQJkLmOvqChHUIrfmFSoLzfOeehgiAiWwBcKEuPKWcULWnSqBRYhAXqZVhUJx" - } - }, - "ProposalBase": { - "id": "16", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "232" - } - ], - "voting_start_time": "9935-12-31T14:21:40Z", - "voting_end_time": "9936-01-03T17:40:38Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "wLrSnpntRR", - "description": "MhceRGXcPEMkpWdqmfznNlzyIWGlBCqORsFdlwOcBeWyEfRIpeRKlypBbiLdsuRUqIFAtgAcdeWkOrzkggPujLaIEjqokLJAjPbn", - "recipient": "cosmos1sp9hxsl3s8pyj3cs84acgwrkxl85yk88lun3fv", - "amount": [ - { - "denom": "stake", - "amount": "126215517818" - } - ] - } - }, - "ProposalBase": { - "id": "17", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "24914473521", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "240" - } - ], - "voting_start_time": "9935-12-31T14:21:40Z", - "voting_end_time": "9936-01-03T17:40:38Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "AEgQMtqCqU", - "description": "sDiuIDTlFvDiMzvTvrcQVyssKNDZXzBqThtQJZJMFaUzNKkqkALkcDBsuXXQtbRNWgOyojgfkiRCUTXarAMMNpilSurPDyLrfAPK", - "recipient": "cosmos1re5reme6kyayzfanalqm89u2r9an6wu900gevy", - "amount": [ - { - "denom": "stake", - "amount": "83790607203" - } - ] - } - }, - "ProposalBase": { - "id": "18", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "222" - } - ], - "voting_start_time": "9935-12-31T14:21:40Z", - "voting_end_time": "9936-01-03T17:40:38Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "VZMIpFAucKozazhmWhhCpEcgImqejNAhjmcsSrYBClfHDCPJVXKpMLPzVFgSuygbrPNjliNiBxJeRjUkEovHaTsBPGVkSVhCunQpDIWZeLqoxWGtlpSRNPIzABmhoqUuEgjXIdjRKPaY", - "description": "kiDBLECXiyfqlXJZPGsXGJKCFstZEOuDYCWyAazvbkhWqCGUVpJgiBGeSetMxPRoHmDEwYYEsZNTXywLZUyULWJCFBihGMMkJrNQouXfHUXLhOVVLQZwxlPXYJZnfilBBGBBIEgvFXZQwwiKFjfzVMNLspvwwDsqneXvoAFKXXIhkAOoiUbPnPawOriRhxYbkzzyIvYmmbZpgInfhWfSsfoNOULcTrXkjuweLKQrmaICdmrdmrhYJGAEmPLtWvzCzsXfVThZGdauqXNAVFNRiGpWkvMspHKvJucHEVCGZirqMIylMHtRKnrxAYOmVbDIFiZBBUqoZIGHqczIotLoCcpFVozoVytHzUowmCXqUKUYkBNJKZdyGxAXKLKBjIDvgfZteVWTqcqeavUljINMudaFrorRAAplOUMbpnIkMeuXgGqjZgFBNxTHTBOVJUjrBXqqQIOhAGkcgUuboUFdiyOsVjBmVziWraLlabMsYHqgPEWvRCSgEVsIScmaZHWCTnfxWxShgTGailgXfnOWhescBpRuCpiAfMKaySlJZxvrjPGSYFVjIApHjndalfQUnWWQruCwJydHdyCvyOMdeKIWtfkYprEUqXlDcZDrhRWVHrjULQxmtoiafOjflhTLjnyBLQMngvjJKSztLpsRDnIdcEHkTEDWstaPgqsNNWFVkxjSOeHVfhyHOTLZpCyXVjswzxRyzvaitQVnbkFyxwgRKOHqUDsRSVldHnaRQKTtnRXhsiNIVMcubeQiDmzEQxzjqmAQvnFYdENFkemAVEdeaTewvqCOIedNyZdtgbDpbIkBOnkQFJYjUNdXLUPWABEcqDMPRbUkmUCekwDNdRfLwhjplnzavrYvVldiXFoTBUktUUPVpujJVRuLDrUgjgKbGKirMsskscdticsQoCCpBoPAIoOhJRpBydTxVQeXCSlWlvOpkFsVXFKPTQVBewqUEhKXvreNSmOQhlNGFvbUZSuPtJdNUzHNtXGZAQYUyBhvknvyiVWwOmQXaKzldmfBWMIYFatRxWzhRxebDRRaUcrCJVmCzdphUPDdpssmfOwpIhrovnLIDEcYQRyyhncPtzxdzLyMDvyAzXlYYNcgNvClZPoqXNsbKFWvhRBpPyTcOtkcKSMPVYKfRBWJXPnKOcNPgctvBoKiWHgIJgipJBbeEvThUeUGLPcLoTsOIBPgDWUZEDoPPuiiAlxSmsEDPipjMTbeoDWLEmiyyIFRHQXGVWarGVohmWotXncyJzjipwuXJEkHziaMBRepehuAOucQHERzdCNsyWqAbjtlyyZpSpnBGDxGhGKvVfSgJZMySrSgwZwWUvsLyjekUckmGjBpKefQOHcuJIfypSJJfumGrnBepWDigqCQiHbpdcNzmIFJQOgFBFydlZoEoUzgVPwHwTJFOHvunatOVwxViPPDtayxTJsRJAhqLUfiFWKguWFyxZSuQgcuSrdMtxFBiegoudLIdYcIvKTvDjBzarvOCYaHxqwTcfmzQBnufLyeWgSzBWZLQiOIMUEUcnkNWrPVocOmtIaWQchCRWGWjPMKpHJTyLSppSiDWaCgaXLxgyvShiLcegDQEMdZKjVycOGANEgHknCueIekmmuOkFCucKsaOUnYWPTSBFUkCwRFobkTAvgwJGQFVplGMJezOosuUIMETvsbkpNldPlQkovmerxDYGmjiDRpzWitHJarafYEiDlwByABQsWcvZNjfHComMAcAdieFxftwitBJCFxbAnHqzuNfmvsuzJDmDvGBzjHAFOcAydwAzEzImxftWUnQWsATsQYhEpYkGtQleLByixjSGWWlPGPgWeIKyDTDSatoGxVBVHoILanXrKuLkmbOdXjaHobyOHqqjhZWOVxlHGGIecxpeIprzYNixewBafZdAoXrSyGttFXfqEbOrhyTpLOQzOEMvjrmASbEOwQtUUXPFwQLXmWqMVccWlmEoowNYuVANmomGQzUYSSaLUBiFUVjXvgppTmJcusphwmUueMHKSBHUAEhnovPGbEoyAQnZAuIZuOdsxBUUKpuFOwsRmJBIdtzvTvHniCOQmXiQUlsESZZqfquBxHewBCQaLWWhCVaVmoBVzuXVqbyUcjBowIhuYHHpkpJiYpafpNPfpXXRLcilumhOZTdHXNiptQquwlWvKFJsvoRfDzxwAXuvtnTQWUXZohokjvUGivlxXOTgNSjRMgAAtQNmhTOvLUqxZBbCGSBicaDhtBLPCqnlLLxUpJwnPZEQUBbAgHnsxOxCXugDGvYYtqHiXDFMoTqtCycZLqeWJUgUXBdWbVqrUCUheVKgVfwkOjbNSxDZguXBAZditFNphHVPETqZSnWeJZjIVDDcBtGGeFkTAtGHfqWLPAbhrxZAiNFSZYQiwspnuehzrBEiOIjOEcPcUeJBYxPamtpvQoZseYSdFhnQRzKqlFLkPeGxrNraIQUEXUTBrxDpTvmCgONhBqDMAeavaySobXKPhAjUNGSEADbzpVGSFbMRcbVGwGcixalsScCcGMTSrGivIlQUqclLZEWQQgSEtfrLBNIhtGJPFQeRYMRhjmEEMOHujwWwzmGyPWemnumyiTXXGsArXOMhOMNboXgXYHnvhsmspTuZojwciLXUtUNKBzWoiAAZYFDBphViiiJslwWUZCZTFEsXVNXYENLegpuoLXFeEVJldDukCyAjPQWlboSPPJlvuNIeuUFpFCQIKxJthxvIVYgiYOrhxOtkFHCScGOVrXFrZirEnbzmVMTIbmMiFyJazhQWlOIHbsKLQfhAtvfcfysjMWPQicwBTJqhkwNPAEDHmthPVKYpEdeMjIKpCIBSMXQsbJxMMvwselSNigiFunaPLWOtNJFjjubgmvZiTlByGlGvUtWLLkIijRzWSGKxSnnZOfuCiWXtWMiEgYtCYICntakCJPCXvAdqtuHdLJeIGBbDymwEiolKAOMkIKMTTQEIdJkvKMnizOfdiyoBjiaYKNXlanivtkvaOAaAgxRDCskOgPRAVTiTZkxtzBZjVcRwletGllGlnjpYPZxiLHUTvdkdOZdaudCZYjSIgpjZutYSKEMCUQNyUCnjrjavKkLwauVzBrumlTcAJXaGbLsvgsabPMUzaKYfbqTwSxFaEpHylZQNzSOigdMqmHcvIwHFywVOoCwHWFMiWjMwtyJeeSBPWdpAghsxvvlyGaVguNfsLmFPKAVMuCpIdPOpllstUNwxjMWDkakWSudljxEeOTBQsjPUEndhWnkpkXcNxhnzSvUlkgVWqrEwZgcFUawlGgJkeuyawKQWWdjJOEBxdwrEzWJKxrDkiSJTnrFKWATReUwWNJYRaLqqyMIeFGYwOiCuWwdNTYvUutfsAhgSPGVphZlFUnXlxNyOOlAHIhIkUnUuHkpOooTViSFHfXrWHTRuoFCBUlbexwNJuShLYNkjCwvxCEKFyjoplhrtkZChbGIXpvHsqOGEmquKvDCzSioNpOkYFeCjZIUrcuhmPzPsdBAaXzsruspjDQQDdQGrBgYHpaOzGVyGUuKibgpVSzpFIBXYzNXobrgfqYOmRzmWVVOYCQmUvAQiGAJFQnUnnbTLifMjpMjiUJdQSzmroJSCnfcnZXPsEyMZaINAVpKWpinziQhjHnDZUhtIeOmwAJnDPbzDtpzagkfyRpNyXRTaDAGNSkZHrlmANNGYeHyVHcGMHcRIXdBfDzevOLdZVPONOBzMtpVfZipFVcoQxRMaFFDUAmiUxXuDBfGdKPYBHBetvUfumeVTRnjNseyCZssDsbbilzSyNNXLTXVdKkvQqSPrUhizRmChgEmhDRNYjnGvGBZGkCIRlNqYLjWmRQTBbtARkMZtMUKAbYsiMxGiUINbwIyWPagouREbedEqZsORirMzcJyaCLnGpalDnVZBJZmEKmCWhKZhSVutsimKLMaMIDWdVIHNsYzpMGsWAAdUztZRgRhdcnwXzNjtLrCtHyFGAwwnHEpmWNAVyNrfcEvuGIIVeMIPFDtZXLghXXpLXImQowvhreVJBqdCLqmeuDYtSIcxwzPccIAhhEmGJJrxvIrtJGacPHQebkPAAGwozDmNNVwSJncjenPQjGuPvKHRxhcLtItTMjlbYHCzoZTwVAIllMfCkXlzNWjUdgdSWxVacpIFjeYMbTIhYEKLyRIwEiJmXSQtdoWURyYQLvGewvrhsUXWnfScabbUpqnyoHBTzfLhBWnlMFsggVAkNdgHPywpiEJDmlAZlkzNKhYJhNZjjBWpnnvTBXssxXKDCnOgxjJXpmJpkMrUgJJNdcIkSpqqKYLRaHwrjYNpYztquytHFNaRGMTluBdJWuFGTXUghJMtxmelEaRwnSrYFdLjSjaCJgrGuVBmrhJjMFUtApTSPJYOQUKzaMYvbVRxhTqkOloaVLdBdpjBMYsTzGvSbsUsQUdiUYjYafZvlZnUFqToeJuWzabzgmHhttJDtlJCxDqFMQoSavUaQQXadwNSGvoRmXjhDNXFemmXqpupaCBNnjDHkGsSBCAVhBNGpXEWtVZlIQasbpNzCEFBCMiKTgrwtrGBOxWcKFrhQqvGUBJmQmcGvLwVJlNsYdfcGRFxgaSqZEKDbBmMetNduVvaILgZyRaJKyxMoXQMDHLjZdwlTyhuedmKdFNoeadiwAUKYZAymrmIgCMSHcbJkrdWJfarwJnTnOSJUlLYMDjwbZTyQWCXpSBvfllKgJikeeOZBdanlcNxAHhEgsvTkJxbPIvToLOmlPtEmlaxvnPGnNujwNLulYzsVzzCTehokFcMSEqrbpvPVzShlvsUhTteiZQxHbsjqXdnkZEbdzzrbyzEowlVSYuZLFJkNrSRIQXSLPteudlHMdXJYvxjoHkykKozVmGqEfcXsntcipuovjMxUSjApBLKeJoKwteNLvSoPtviMotJIwkhXGXnMhPQmbWaJKRBKPVwIyKabLeAnKbVoZfZKSlNblKNwjTLUGoxZdXUQZkxqL" - } - }, - "ProposalBase": { - "id": "19", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24914473521" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "223" - } - ], - "voting_start_time": "9935-12-31T14:21:40Z", - "voting_end_time": "9936-01-03T17:40:38Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "UVqZEdeaVzZMEMEnpyVkitoboYREaHmQbsMLduwSKCGTVbbjGSPxdqGaRtMfKYfZApqdlNODloHpMStFBCNQLirOHZkkFFIpXCuYhZVbcFINUuSNjRFvfntkQIKkqSsiKneRicwRTFmJ", - "description": "UzmjfKXzvhGxdDqtBZCcqcDBMClOkjbGCCpBugiQmBLEBaOcPfJhYKCsmeZVpBDozGdYuImjhWLcENLQxsLxGfwtdLjExzWBHQhjkPJIlWTAIsKNnHwHQIAIcxkdzRQgJSwUcnaiDCOFwpdHgApHRunQbIHIzxsVjsADRnDqXFLUuSJdPLgbacFmjiTmBcknAoikMDBLtyhNFQXcXUgQHDCARCZBmgvvufzFGXTfBTyUECHZZSHNUwIMTFKDUWuPSOYqDGTqJPuwEhEcFSLPXbnWfePhkkuWLPBoaFtJiwaXkKupLDdEbsdncrFMXDfmcLJBjXmntIzmZxAUDznNVfEAEWQKZsUXgYLInRUZbCdBldQoxbFFfGlNmrmyYgAZQtrItflRsACmcuUAYQlsXnFPIXeYxfIzdWDOTfcXSVwvpxjLOfHoSeqAnyMujVQnTeDxGyBGODXrzYkMxevTaAhxFfWDEdqjKlCBjlUiPNgDFJIAVKBwOFCHrBLuLDIGVZpURlcFIyeIsfsXYUMgNUxejZzvznWlWDVMJmDumvYXgXVuAXGMhbltWIdqEUuMHaYkLTipPNiAykFGFBujucjHQjQuHrOMoRhODTmthVGbVKgVrRdyxXuJFdGTxWkSpwnxpFgUYBOuUKNcPGUineTmIuwKECklmQhPZSgfViTbeAMqWxxZkTLPNEwkaVbbIvdPLUEmrSRmJQERjwjvFxzbfHPfNjKzCIHUcOkJrEnUyjVeSpoRougIwQuGUzqbQYLefXCgcuyUqQxnKHJWPtYOsexxOqimFScWRuXEXXlCedQYgxwmmPEzzkdsktjsceXTLoHLfLLYaouRHFlPyesPjofLXHeCPFUwpDOGUsCHTgJfcOIAVScKFhMctNypsruocjUFGFwHuCSFqmcZOLYYMISFhZWiyNFjvBPTbXyBJljZQClNZJEDIVAuFvENlTYgEkRBQffYjhlqsuaudFgLtDuzlPdwYGtBhIAcHdWOaGSIwNsKQuAXxgvRUpHpfIAFHEplIVSAKLhwFyYdLasAizaEPzzoNQvCCriFpSEoGzNKdDZvIVvWyMgleAOICGBVbjNsfcMrMdrrLYFnDkzPricEJbEsZZwoTBYfuqPUtqONSCUUATAqwgjuTDGDkRGfFmAxNVcZFMPHlAztSsVGfrYESlUbOtAxjWlhcBnzehJTPcqaPSXeZxwyBIJlZbXSvUUUPvaPBdbtTDTMPYNrStlgnIyqBlDgifDzEdXTKdVxxhpxpTWAeWCGvddzzTfujzVcNsiwvZkQXZyFUFSQvMwRHRsBLKQlYnYanWLURqHzAJHspkopBoCMVLtQERHVdPQakKxlrSyLqMxaFqAqGWPEGCvvsDZpDclQfHKxXuRGyfkDxPqiolwsvTvJKsHLjWaIKQpwiaFptRCqdxOEZAqaEkCcGIhavdsgsIBYnVFWJNITYGHTrbLDsAfrPfFivDPcWqgBoqzzWNmOlaQqXPhlvuKreWqwJcrckPbcoJUhHPndxqRgdjUeXbCIetPLrOxRRdsCsvirmNqvXbSRNYkdoBZXlaOHjrLpjXdDJPEqRyMhphlNMPBNGVQnKYBSuamTBkuFCjUiosmItvCYSWvCjfKDbiJYEHnymcHGJwaTuJgRrNXEYJzzGThGfsDoqlFPbBgdprGyFennJdWYCecOXOPyYPZSbwgzIqCAhNUKupYTnqROblMfIqRxDBCERiexkwmqMueEwvnEDONlbEqxZJZGomUOCUMDIjTNWWVKHWuAMSdPNRBBnqJyiEVQxwDSfBuyfVmJxaUOwyjPrNrvIGOdRggiNcNdBEkYvapBupXItFPjupTpHHRPrmStJMvLslwwYwuNNEtIrBEPaZvvALpBDCNFEQfKBBjvsPjtlkNHnAYixyGEZDvmIctATINBwtnfthVvXWvYDRlegXgvmVNcClRHLqcMMkzdFQhTqOJYUhMtvmrrqqcCmwrZCjltbKbPmJwtxRqrihLODOnKYaQWhtglPltKqSoieNDgqCitvroHimiTcIXovyDkTWkwIKeDlQfZEYXqRBshYTYcHnjYazlOrZopzusBaiEtQDSjEstmExSuIXfocsDvRzHqHvJdavBJkfDkNuQIJwmkNlbouzJgtyqKDjevjjJFkkpIgZOVTcFpxyjmFSzESZZLBkWceGBuWlidULaVBOkxcMaXfIXrrNXJmAdNbetixNuGEDSyZlgmTVFAmECfyvULzNyjtHfDTwtRhryENlDhqvmcRORaVJWqFVclWwdofSWQBMvkaUyKiVNVhWcIxaJnMOkfCBQVPnUsHqBgJYXHjmQXskFhiNgoybKTefQdUMYWgEjmpSoArbBcKbRfCqZiEXHIKiteEGJvJrRguAvzAXEQPYJAYmiUPjUzZtJlqfbgmmbPbLvCFZraWpWTyrauamdPEqonSrmvbzgjOMDwxEETyKrdfScNbNgVRhiGyCUgpoiYpLkUzMAwDzjAZiYoEXOVmYbHWdZlQtbxdTvYFflmJosKOUsGutXaRAsZQlwBXeOiKsMKgOBpDBFpWkvXlGQRwsGMaYVUQBxGOfuASIIxXAQEoWHvExVueSUruVNsDzkkFVwpCszJDhQNlEhTJEwxXLDbJXShtlaOKByEEHKlyKtOMtOaUwyJNYsZYhdXPWLVimBcCNIbiMYAQrvpRHfpKIhqTYhngulkxyVJvhtURQiqXbJXYQspzuOEwMDnJMsevtdJmmTWDhERXONUanHvAWXlIIunnKEpUiCTHATwDaPejxRtLLIyTfncJgUdZcMTmRxiFaFDHZamKPaOICuGmUNCDhBaxJWpOyabHHtYjcsTrqBzzjDiDGELkGgwcylCMjNJqTiarfLqVSppJSsEkuRJKuwFpPgtKzGxplDdLoaGCRrXKnukhaKLjTBkdVEjKJxbAgmmncQtQTkVfdWxHYMSujxngaJpyvZXppBQzoBYXspnxdOfYQSAEXQiLBfBRFUOvASfOrWjtsrGngLwzTGPiHhXGKkTjKrazzEmClPFbSiBhhahlAgeYKrHfiZOEhOFXsHuuUwfLdqtbVzMNcBMUEnuZwguNTUQJjfkNmkMcpnfPZVzFiJCeWvpGLPkovMiphPXhMWwSzzqGxFYYCXvFIcYmaTKYrZugskktZJZOWKEXIiQjvmYkxNXFvrLEgtvJGypdcwVBzPaaeLxLpKdAGLNptThveGHMTmgxcAWNAtsabEGpwihjTHzScxHGdSmhbaYHtMOmhpWNxdVlNCqWWQiRwQVKSyQTpQCPqTnnPCDPjXQvNypFTNgouxdeCkJaQemveccAhOqtHeGvqkbrSsTfoQUfmwuqEYEdGuWuGozKvvFiLeOxYxXQrpCYsduqtTnUWEcvSqxIqUzPQqxowGkhNYYEQCkTczKEgNwhHlWRYAGmzJdzpzovLVXAhsqsGlAOKtCNhWyFcePUFXxOTAdoJtPqGNYOQOCZwiydAUKwWNEOndZwqSTpiiIPwfnemFrWfJNzkfZyPCCAspgpoeBsSlwKhiITYhEHrchXYqaTgzCtboXxCjXUNMFiEIxYfJppZIQYuqeAtfZhctFGfzZprDnukqduGxaxJHmzbGlhSvxuaxcDHRYNKhxQjbfAsYhOCNdaKhKECstdARKvPBqyCoXtjdIRvANahJbebqquEbxawSoWxIEfIudZuQzrBDnQGdHSVrcnuORRAyvkUIKhCNxlYyoPCGiWHlsPlpcQGBfXUdtUThbFMtEDDGbGGIQhkeObqFIsbZKmrYDKyVqeKDOMZBpGEOezJmyDNLNvyrEekMxNugpJrufeokRPuRtkhLsnhtXfQcehOJGjdPQeQrwNrcyUsRrNRvNMEtgJbxeIDhYHfralOaWmTPzrZUiOxxQWSFmrpmpGhZIHcWZuLtHwShOAekRYlpxYyxqsKzqlqXnuavTxDYDvDbRHYKPQEhwdLKGetwdnNMmckpkPPxDWoeBfHgeeZroZvZmaGkEUTuNSCrMxOCiFofjUTXzPpRIJBQmNqTjGmgvhHHWyfFWCBwEDjvAjZmgohtGfrheiUiJCyKeeJGLNeXhzfhJTOtrfABocgPYxWJDVJWtvLwdIvGENglLMlIxaBTUSLvzuNARsUVnBvYcoBbjDNKQCBHsZmaphDAibYjxSmDskqXCPYTHhHNUDjgQYnnOQJBrKkETDaBOvolVsLejyvYNcANRbKUxiRSdlePcuhPcSLtatCROTGJdnSTDfMtAPKwFOZDhRBNdpRKUjgoWqFscIdReJpZPPiMmfeXVHAIooMmBPtWIKttcqnJTcKJPuJTZlTXKcqepazecXQWarzRzcdJAZErFYBbAdRhBaHauRpjGqVbrpGbFQFzdDyyQdgeQCltUrwfJaXUxWDKoiSLCqGwuSFeGSaJUdLNwnYhhfUJGYYQSEBTINMIjTXcDELKTWBOPglkAEzJiicSbsprASUKqMUpHYDcEJuNZkHHDrrJNxfDPKKJHbMbuxKazEJZGGEHHmusHGEddBEDQLpoUjYfDuRrvWjbLJOXVpGObXAzolOLyuYLRbDIjVVIfUpemgkejkUmrqrPlGdKBlxflmkGutzUARFFjXpSMwiDrDiuPddFGNWcsgVWfwAmwZmisXhDzlcFsrPEPmCKsJTqoayZyjwfXZmAwEJHBXBuADikNjAVTxEwyMkVZtOXRnWAFKGRIgtzjaulFpnOonBXoGSjwzthPPppjmgXoOzhGwElpbUPJLhgDbblSrUkAgEPRrHlAnRvRstyVjiufElDnQKrDVohkcwIkMVAlVKpQgJxwewcDgeqROBoBEHDQCpUDXazJNNOzGnxiuDEeIUAipCnEfpvldpiWCsRLZQuXQqJKZEguTQSVvPsbsrmSGNBpaZXMKNoRHruykvxnspZMWLwHeXdmscyfjoEUxCbdXKfoubNHehQjdPYZdsCKWhxscaQZWXZtRGeDpDCvRfXmyxabyFam", - "changes": [ - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"11\"" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"165419000000000\"" - }, - { - "subspace": "gov", - "key": "tallyparams", - "value": "{\"quorum\":\"0.449000000000000000\"}" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"6\"" - }, - { - "subspace": "slashing", - "key": "SlashFractionDowntime", - "value": "\"0.011363636363636364\"" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"148400000000000\"}" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"187\"" - }, - { - "subspace": "distribution", - "key": "communitytax", - "value": "\"0.210000000000000000\"" - }, - { - "subspace": "mint", - "key": "GoalBonded", - "value": "\"0.670000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.800000000000000000\"" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.250000000000000000\"" - }, - { - "subspace": "gov", - "key": "depositparams", - "value": "{\"max_deposit_period\": \"277630000000000\"}" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.800000000000000000\"" - }, - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.160000000000000000\"" - } - ] - } - }, - "ProposalBase": { - "id": "20", - "status": "Rejected", - "final_tally_result": { - "yes": "24914473521", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "299" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "XabNyZfMSllVYCVxILlGRMfNKLHVGjUaoBkAkpXQxEVOcSUTwMHrOuseyvPnpmcGfAeQgxTjnatiSivfFyGKxsikkkKFxYyJrlfOJcPyKmduaCNrkRbIXTIksaPwdCgDzxUoydRuqsRU", - "description": "DGoIjnYbygAtiZIjzTLZrscqeQNJkmujNRleHpHQROuyeOafJnozibJrezrTMubVpyacobphDRlThnAcpCuKOvgmKlmTSbzOeScMLSKRvkZdWborIIOZpkosOcbusabSQsJEhofwSzZnsrSfXwijAQBDqELBVJWmkhyNKAsjfhAuerWzjpxjZLevNApUYOZjRnfymTLAvHnUjAwrMOeQjcTqkXsWhBlKdfaCzjrxBoNtdgXnUoKFqElqSgXBvsqPwrAFIExsrMfNPGsmzJkiuqQBaBroJvAuEsCCWfgPeAsLxrBmgMqEwEXBVfvhlpiZNGifbHLbsfVQfTePbRiNTWfrhcJKXSXrJJXwZayzHgXnDIgpFFqwOJWwIHyfsfudUyizYHBFZRFXwLCLOkhjEkQaNgcUeRRWLkezlhEbZaXrrzkRRpSYhxBHKzYiNgZzJckrYlAbONlaboNLbZJJiVJtiAyxxXSxlAKvqoLAxAiuaJpQRMCAKmujvyrFkFpUlyQZnrxiWfvoCBvEUVEmVRbeTBrzLcHJLeejcHfwmEbwiQqnVkgAPKALBIUqlvinfJiSnSmtLjIDNDSaciyhbhNoseiwJBBIiZwaNmvBsVECFmIVwuVCbjnYrlsrlrqXeFiAHnPEqIdhIWzFRoxwPsyIMDHqzgUQFLSqQXuvIxVBljaDqKnZDWwZDrThoJjmvLSUvSkzuMifHvPSkGmqpqgOuVHPQIsBAJaISZObdIvqQCBWYxemQdpweAPSKiKgwQfNhBlBNqZDlBjNEhXGjFMGUQcBMRnYYjRqeNVcxBTCViBZKXdgvzHknKwTztwgzamKDQFJgJfOwkWEnbZAvoLObxRfFGrpQXRFZneZpFZqZJNhqKyAuVbYpVMQELtxhoVqBWQFBkGrAzQXgpBtsamlbRTzCRbmaoWHpDLQdXYzJHrUtcwGbNctktxIxUjRGVxZreGSuIYqmebSqTZHJlUgRJzAqDRnVfxSfiewTfhGtwZEjRsQBmtAoNXpuDeSxjKryrqxwiLkzvQcMnmwCgUBoiGmRjXxaVIIGGwxNEFTLEbxexFtOmoJhNsFLPKQfLvAkACuhTXItpOeYyCqKbhVvlDQNIQIKfumJdCXjrmPZESzGgNMLCMLUBaqTaZfpBVfqSgYhHQTafAWOULkEzUtXCunHcaIhoaoyyVnjmvhbrbahDrNpkQGnCDQmQntFwJFywAcRXcCygBIGBxJQeFiakiQKegqjAAujLgmuWDCUFbFWqrZuutaeEtqyTAbOrbwyphsLqFwRrxCxPyYCCqphZuPTtBomHcEnvomPkSMmzkJIchrJkelCBzVxAHWCdyxmvTIljotyhVdVjVhBWiqkoUwOsPqkhqHMSmgRWdYxwYlCSyeEWBcJNJYaPHziOYUZRyrQDNSIwSwaLgTUfXeSZMPqfYrAHwTAVVORIrVSpdSvlDWxmWzMIpvLWCKVPkYZPsNRurzGGnrfiJxDaxwFXtaDUArSEUyVKfbvSdFKGczQODUUtOqUIfJFuiTICBsyJHwAsavAyXwSIMWeSBLrXujlFWXMMJFrhyTtFnLZiqCNUdpnrzNXVtBKEaPjqUOcgeWSWKRBZhEmjtbUqSwWLyXlPOPJzyChkydTziEbjtxQXYoUGaHoccqwPoEfhochHIKioZbxxfFIZxkNbeQyESojXQSqigMaxKwjEzSNNMjLriLbcNLuwrFWlQJnWHFWoVkFcmMppIcHjqZHCUuRzBAPTWqJnYHGkUvTXfwCnxQdWOXjjmrMzrlXBflfPRnzfjBelWebihuPkqbzWHGypPaGBoqEBHWKdfqoaNOpFNTneJZXyiDMINkLshXdlJgDzYmnOmjysuhoSjpURXtbRTwwdyYmEwlJqLaUeDcrZFgzbeBqnFYkIXSdxULapbWLFfwhzluHULzmsLWIhRsuRHJpwnIqblStqmnSYuvzCMUccEcqzSFTBNyCBYeBhNrlmOekRCnzhswhWmBCZLozyTOMfLRZBHkfmWvycdgIpRiHbGpcwUPwmeFAGVJcCmTOJVGeJcqFivQRIaKaHSiiaceEBnpuisEqjxYTHXuvBnUXLhoPTLEWCzEQdhjSrsBvidBwXYcTNRxiCJaCzXGGCecxOniRMeVUWTyfDugwuBsZXQwWCZqExoFIHiREuAvjLCOcMDCZzkvppHAmHgSgfFPtKseLjdIJxFtlxXnKoKkSqcuQqYxsGVTaFvWpoFlmwuQpzPPyzlBqtliFzhSJMljMnWHQOoGdAKPntVvibdOvMLrcNtVQVhtYnnzdxqJCvVMidpzZcMvCfHdHqgAjWTFBqfMewyPVXVgzmAAlsMldzNeMcFBjenSnSzyddqbnRPvWJHVPiZzNFgMoPgddlMMahJnWEfjJnUCaWDxjhJuXRJOHtMivyCEuHCscSIrXYcKtfSLiaAjaBTNapIvznPLVrzKddXHfFgVoYZQKdkKrNtiMdOZWJqezHdnUJvYMbvQWNdoWCevCQQHYcnkXFYePiaLbAwIaXDSCCABUyrlAvlCtfCHDXSDbLFMiwppdjWFnfdQjjGjvOUgQZwoFWOuipsRyDPEavOqHbnXYoszBtRoFKAJeCJuYytHytIonFRpNQcQvhKpXaLMkDQuyopgqHShZiGfIcGluGpbEOLvVHUzTzBbFPJwXXEYoKoViwQWNRiQRNDrPYUitnvmlphRmvskQBEdhzlaraEflAHEpgbTKtWdSyLAydmgVMaeEUWuzxYELQMEvGTzAtKfzsYbTcdXMdKhayeAScukqsnygfZKgXYrrlWNBwPDQHYaSzofhxwSzOOfYQLMtGecMNGTLuqmnyhdIyZBPDCUPymKSSrYSyUPLjFllRMMXLFJQKsvwAznlTWuTOtgqnWckzqVRSTKvTlZztHRghNoXOVKodBXrCBqAOBGkPQSsuDQVXwDgyhSrNqdHxDagSEneGIIZqpIPkdAZQJsipkbMWJOlHtVQMoYfuXSmEVvxUopqxZjLCpEDwbGcJpdHiRCvyhueWKbxqXcbVlLMkGdjijRquzuQGMHByUNisRXyzFwRHWhBeIcuNQdoWgobXkYkTKriuYSncNiAQqzewIziTZTGMvsNmMUHwhAFTqFLUmqKJzuzTXSZJofOOsDRfEdYbhJseWEIBdjHLwGPYCEjKwYqYynNOhryxYgkQnBzLxcCRRmHKcMDnDRxHBuUeZoLVzJCfmMTymtiIYnPWQxbneeDLXmZTbrqKbVcUGYpFEDRyOjeCSnEIWTFQMeuWwlOiUCbWdBEBQeQKbPjRFSNFUMcbOcutvzLIBnkhVSFqYwFGTOwBqOAOOSIitGlwROnsoxyflsHsWkHFAiCmoKYQsXbpcZdFhYjdzkOYoeCIaHTqaVRfjwlErlEBBvSaiWTrwQXTqzuRlSNEcEqrMNHcYSLfgEZecRZrNBkivLaCcyfUGsQkNCrXiWGOWjAPnTdGJZIUPaFgngNZgCQwfeEacWlarrBtYbxhwpTWxfFpiSAEUgOBsPnHmBwRWwkVgxIViXcnmDuAEwtMFLeTQcFaKyhZXdYdTBVGpoMpQUFxjAfHAzrRKaWppxJGppijuXPxmwlRZNVOPNZkbBLXpYzPNVJhmNLXwSbJZAswZmhZTeIwGwEbMbZHJWOAFcCUgcZtkuZVbArVSSQUcMVLJmGHNYGZcnVFouYUevAUaZtLSjhZAScsrjBgRyNxZKomoAiGGBiVgHoDwERsrRnRuUygdVOsOnUEcXZrEvtHoSywgitVyJGbuzKUgwXnSneYbAEskgKcFEYIWflXQJEovdWklVDHKdChSLUcVOvcmYRWNHsVlvJJWXVwWCrkLXLlMeQSeZRTpUyUXCuClaZydfklzilJACNPnDQOTxybYlPDznqHkJTThXIMpFDvNjiAZBqDBLscsTyXXaWWdgiZdqoKHFeOaTJecTymnAYVudclixdzfqfLbDJNOnTEuaDfZzhVSVpISxMJpFkaISJQJXYTrChIuorxoRpqhMWMSsXxtdcXpDWOhksdRoeONnXoODDhXndxwDrXfjQMewPoaJdCbCYnrAjSNTmvZeiXPvNysKjbhYdAacZgihGRozulXfUhqdoBcrVqwfQGnXtTgmMscbliwXhLMYhvVYiSdHHvNQcxJQqOecWqEVHRJBTiNZmeGxVszAcVvJNJwwTcsfznUcxIcaCyMZSYXWRKrjxhTWlBeMjWbTYPuEzBNcUOVDEWKGGIMIgWswTGsICgaTXZmcNreXwUIkgqpCAlpvptMAOKXPLarwaEeiGFHJzHCQpLLKuJLfIFJaTRzmMyPWuqDKrurmqArXifnbXplZgcgxcTuTqohkjcqjWFDwphoILXZuqUGbPhjaMUrxqNRhtlhYmqFVPpFzesihctXqhpNVlSFuZtjypNFQsDKoFBLeQBxuJlxqerQMzHYImVXdpjYehArnAAmmUzYbRKSAmjFjWOHOsotWRFwWVvJHHHAOOFSlAyYLFNfFZfWHCdqxrOAYmGHUxigrTvhvGysfckfSaahbbtkwXnkfJWDimFLYleYLtaJuErbCbnyKlIOAetfNhxSJIIDenmQbzffhoPiZWDHgeiWqqnsnFHDIqNOoTkyKCyxTouioaUqXmMTAXPrJkuNsOxMXWImVEoRsASPdunXVdQsLTAwuldSdoDAJvqvwgVGYBSxqQhLpAsjHPcXwvjwzPbJISJFXKXWHMRqHFUgDStPKhInljZQaEvjWOwrZxhxrhgFWohOKFYhTCRIswjLqbwUkKjgscAHQFmHQDvjAWLIvLAZzMbRbDOPPazxumdirdqYrEWvZTvRmRGGRxrXbFLoPhHlGQNPeNrOMzReyNqOKeRioWScOxkiFPwQTXAwhUqxbbQojJVcicsDzAjVghdvxpDeISKuRmbObNOOHpkFkwEKbUfywFyRYSVJmPsIaLvKhzWZhBOvBzDDLTVFihXvvGIVsrVJLbRGKsdXE" - } - }, - "ProposalBase": { - "id": "21", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "274" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "VgemKLXqyUGykWDXTQUfQnKNNQvMAXIQGzJbTLhfuFoaCYznfiVdovuzSPkTbQBsjDHlUBuazcelrnBZkYuINsmsHRpMeMChQveuGGXDmqWOzpGONfXNPHIvzWmPznPAYVHGizxuELlN", - "description": "yBofHJibWSMqRspXpNvfcSpIcrsrrsLFZjfdoCqqxttLozzVoEfGHhtykzXYesHgofxaDHtMLJfAIMSpGCTiPtudFBpFaOTMSxliuvUEFjdDraiuIsmYEhhcgFkZVMSnLgzJvvuGaVaSLxFjRDFHrfHqgSKkFwEbkfSZIwZaouScCVNLZQaomxaajwmaaikwlJGWUrLkRzEAxyZHHwDqqndudBEclsnGyxduNnZjWpHFMCjjvPpUDiihIDAGNeARtjKAjjEckFXDRcSGNPacalukPinsifnybBrggjVRqCkOSlSVPSUwgwwXNXjMctUwUVyTmrrrPKeLvQvzfQpTuPkWhIPWaNvXmwQYrYjCDVFNctXBxukmUpmPWIWHFnXtkbYIezzvspshtUHtdlauvKTySEGGTOLmPxelJzHgMozGiDiBLmcqxsvvDsdkAtmllqCKCVnuwNoFiZzSOAFVztckCVtqbwDnPbycXVGlPnqWOIfzPqZQEODeOsxScfwWTiijWdCATIZeazGKyMhmCVfEAbKdvoJElBdSyeDUAbmmGAUJKmIlxCiOGmClQkcPXFTCMPSwxJdxZnCsBKaLIuAcUudUEGzSPasoLxJGKMEqrIVVpvHqkoYSsXMdqnMYXxxlntJxfNqyVqYNtpgONmkRvSjEYymQFDKlLryBrgUNWFWsrmmDfbsuNAKqGPcKTcqrbeJDdjuymgvqxCleSdRvYYpkhteIPEqIYqlQKZvsfuYVTAuLMjLkohERMPlekIeXtHBdGLEqOspwTtNZIyrGwAITxyBtEISMAlZdqbLjULAQPdEBxNHTHHPzuJdmOJPOSKSEDEMDbrxxHSOiJIHADgnmrqImJKrTcXwvaqXoXemHLAQdQFcuAuJyZTFabQUpndEsOLfmbllaMYxGhmlIvoPmkNJZnuaEkVesCRhPxrCLpteiiphwygGofZmvdXNYEwyefoHnHTfFnvrCOLaPIDaGueAqdFGrCzZOyrEQESvIxlHtqQQILJKwoXNZjswNeNsMPrgLnFYwReGXNniPSUTxccxBZEINmQqLRFciMatmxCtoaqySlqvjjVILwqEVjkwaYIDnldBUXphPUKqIZlUeKfnBYURJDOngPHkDkQXMmveiRKNxXZUmtnxwqnNvgOYiqfbTAAkTJfMCnllKWAjvoGwTVvpxlXWVyZqzFspGQqfRjYAuVPoDTumHIvXNBBmwDkDtLJObgimVfUmonoMmWzBpmobOhixYcfVgNbTzUYTyBVqNZKLXcQAymzhcaXIrEbLVGvjXBfzTXlYZFIiXMVCQwMANQocEyFhBbpLHXnWDEQyoYBQUMFidzFCsCGPvnArIDMdNhcnuLoyvQsbRphPjybOhGVnFXvYVBrCZEyZbBoNMqBChclqDbqjqIZnhxofoZPFHGlVGZGWmXIIEwjKilYvGWWzjNPiyqElPkhqJwHwNMAfidCQsQGiHdENCUVrYNLfNGIAeteDlmGwPmaofSGjrdrhlauUtCyAXPDJBvdwmeWVSdyyHixJwxphpyIpITKpOGhaWxqShJuYSDbdUudwPWEPRAjVHoMgZMTRbGlgdvqwmGLRcyQBAvTQLUdbfBEPAvqqJNKvAJfyoMtwqPtwpcWvyVrQrYlTsIhiNwrbgMthPvLsYTgZOGqkZrwpBrFEsLvovmBoMQKyZtdFWuEahyfkRQcEQBhnHCgUZwuMrAQdEDaLfuvkNPredykXofZsHzYBNfXCdRazEkKbfizXqVyqqzKppQCdUtntqSUgoDtJUuaTkNlFjVQNiyJuxxzpyzbjUUrOLNbpBOycVTZHUInZvGIWdMAuzDVYnRnWJuWhOvLpzOnYSjyEpTbrAkgpFLeSXeBTrARNzJREIreYiWbEUJpJPNRrOCVgxTNckETTbwsQwmbCXOgQAczybzRnXuXBCRzLMlBpdLmXhGBnAvlLfpdSNTycfwpupulWsBAENHTDUwHfTXuqiQrMWxQGRYGUFApyagTqaPxQBrSENeqCemjYllHsYqjNLIvKubgVDBSfWVyradGSrpdmPGexIwAIPcDKKSdkGVHTNhYZIhGgKxKCqRoufiGUagNwORvrpBjDbAaYbNosNonPWdNGkVQFOweeaDlQSnBgLyUKBEmXboXhnnIOtGeuiyMGTgezRboFFgboudNnkdsGUCGJPyLwTXMrHAkZbhAwAHHRdpLGSLONJSWoqvPmNrkbSvRKPygARwOztpWriVIMPUnHpFkxStDYXeWYQJvSNtToyJBlwOUkvJSriooveGMDgJhiPzUpKEaAlOjteUDylKTLsElBZGQuqBLWqJLAjMfuVeDhUDLKjOxjOQOGMNTDzhadRZRUefTPnxWnEFLJGVDEtiexMqHCpqSASUoiWWXmLHwnYcBoOSZpBRZBkIIHtzWnfDuXiVPajipeefInrxKSaaPwFELIaQXlqOeeldHkdHeWXetIINNlLhMoSHAtAiKBrMsmouXjQDOcHQvxNyBKtsVjgWzKIehAssKzdhwmHwpHWNGxpfUCwYVuuTTDKhicxCipAOQmEOJOXfMJsBRLxlwIFAjmKbPMydyUVepUibpSKfIBGQiwMeUmWOzqTQgGpvGFKeYxPrCJRdULRhKPZHRzTopoMoSqxaljzHhxcMrTnHokzMUZmLNurQPPEIVMlcuQaBUIegqIXPofAKGlMIoMcfUUbGjcEWUUQixwmNvUQrfPXJcblyXFMhTmsHyltQPUUlKIOxOCJJpgqncFJWaFtlzcWVEWRKkcvMTORjuZxhdSafIZhNcWyJJJooIGQbmkeOAWkoqnUsEMrQTPrrMnACWBQxvZFTuSfPOMdGQvieJksYdtNetKitxpZKnWKmnXaaLrnzDbrpPJVWCEahMyqwIwvMtjrEaozKPhvoYPtaMBLqiiCUWhCIDvSeYTfZXMBytDFyeyCnioWKYKQYuORccfmqTGiEeNDiHkiiToNYbmtOqampZXoDzOHEbTyJlGldcdboLqvwhmWMceUdgWAjyzRQlcLQgDaYNLYDoRTnjWPEXxNuYcmjqRfAuUTHUuzPurdHFuzPLWfuLixKMHUDFzdHFiNCNTzbznYPuKMtEnvDoUeifZfEQShZkaXVmPxatBuPQVXonQuVopAIogsoHkkFVtTeqnKEelWSycOfaCKPhhLUelpdWXqHNJbBeCRfnQEAKxKmXqnLHobhYmHWtYvWwkpHCryfrBGxtBDJnTIEQCNfCXRhJswpcsCkBCvSgPGljQgVOhSGjPFxVBfmisnFUaGQQjTiUzIKSkRJYnTHtghvyHzXKTzqypqIDMSqwULcQepDIIUrFJyGwZxFOJUnfMPEkZgFSQCxKlfPsJKwlxxFxspKlSOGXtIpktDJiyIWoNGnKxAzxTWggCIzDmHBUlOziqmgJvHKtfuwvwuBFKMtXSGGLCUeDpSIOQvGizwELeCdDeXmgamabanVCitOHmlFFlFqDtRwCmKLhgbuOoDhCLVzbskGhOSlARiTZEsKoRIFRoGRvuzvvThBnhErCRJgVhTarFRGhGTembzvAijrTBFjLvAuyBwLEdKEXteoOTyThrBtQhMPtHqwUOARSgNkTojTNubTtEOFChHcuqEhXcpvepJJkJJezETLkFbPVauXNIwKbAiqcZoDyiDcZmdEURZPxPZwAQIQTmfzIbosEdtDDAsvtpprDzQmxJHnKNwXXJcrobSYijgNhIQagbRnlbIDVoIozgkhWhyfnQpmropJljREoeWJrEfvutoMKnuBXeeaOjKMgddvUjBLDKXfXObOucHxBcYyDVyHUTWqczcjXKPxtBbgAjOWEUaEDThzjvgoWuPOywlCUWlPWfejmndthWRPfyAEGpgHPPdeMoulwHZGTKVyJnGAcZmsTOihkcZzZWlknBToKmZNhFBJclfmLqnvxObXAKdxChCbBRTNyUPWHKPPKricILYvBtWfiOXvtBAKMqEtMgHgRBlKYDvqPVNaOtcejRQYpuOeViazItLchvkbNTwHRAJJrEBaVZRgtrAlQVMHJeeWXfBwbjBnfifGXagZMmABLGtTuufHuOwhtTOBjTZiQSESCIbCuiUbQRzcTKTMZptIguckDBvyTVHEAUnPDHqmSGajbRBmNCRxLeTjJEOmefedUnJKOdzCmsQXoGacwmUzWxxJGmwRCqojRawMFaGXqefCevJEKaHaFmDYpxpHcdCAZQElEomeofpxPqiCkotmDzDfComAsJdPRzxzVXAxPSZPKnVCPYHYwISufXTKHSmGRaOwEVCvliWLVrBDkyAFWglVEeYJqQRpqZGFoPfEiQKpYNInZAjVSlEhIVvYtNTDmaneCLMngGAKFXuiWrjiiQtrFgdNBckksekmcYrhFdkPNxVCAWfjOQTprwVeVlHDmGbffqTKxmKRTiaWEuBXNrSQjeHiGEmyDHoceEnHyQZAxFkdeyZArBmkeaCdVxtCGmpbBHfXAFDyoKHXdkUrjwrMhNdQKvdPfKfpqHspcjRXDZhGouwLIUITUcVZQMauSolOxYWtgMZUyyDhuzJdsvpCSMfZwQNZFKTJVLLmFNmBEjdPGZpWlVTzWuhFsqyjzOfKmzfgGCTKfhKvplGsShrRKGWhrhLAJuhwtBtlzijGEVbeeMfzwdNZxSJCrKiOKXUUjzOXKMKlBVqfsYwHFjehbwdQXuKGSqFTaCOXblanwVOFvFtwYhqkMPfZrOQpAhZsKQQAYpSYejzjtqNIxouHIFjBjSavYpYIbtbFNcuiWZZZRDMTUNQsRzMPWqJxdkMxDLvqrCFPEDzvLvUUgfGBfqQLKUPXRxvXWRhAodhMdwDebXjNjtYMdBHhgZoNqEBXmUvpFbdgQiUNhLKdgXYIPbEbGtvugbSSintTAInSrYNCYsbiulPVmurDFmXyyDBdcVsLjhmcGJbbKfSxutuwWqLRpwAkAOdBMyrMBBebibabTYKkIdUpQMmaSwyZoBV", - "changes": [ - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"9\"" - }, - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.390000000000000000\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"549\"" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.240000000000000000\"" - }, - { - "subspace": "gov", - "key": "tallyparams", - "value": "{\"quorum\":\"0.446000000000000000\"}" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"7\"" - }, - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"198445000000000\"}" - }, - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.280000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.500000000000000000\"" - }, - { - "subspace": "slashing", - "key": "SlashFractionDowntime", - "value": "\"0.019230769230769231\"" - }, - { - "subspace": "gov", - "key": "depositparams", - "value": "{\"max_deposit_period\": \"215818000000000\"}" - } - ] - } - }, - "ProposalBase": { - "id": "22", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "24914473521", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "430" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "krwJEAfSwt", - "description": "mmYIsRjXDxOfkhnapaKJpUmYaIziGDYyphzBcylXFrzVeWPmREXHoiSCESkdRxYjdlibfdAljHKbCGKtnMZGKgkqIcVltqOtVamo", - "recipient": "cosmos1df5pnfpc8n8as0nhlqwm9rqv2fszwavjws3njl", - "amount": [ - { - "denom": "stake", - "amount": "73837738778" - } - ] - } - }, - "ProposalBase": { - "id": "23", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T14:21:40Z", - "deposit_end_time": "9936-01-01T02:39:58Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "221" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "xYOFuaGOIn", - "description": "lpBXdraAWYLGEnkiPaQhAkwwuCOHIDlkNInRMOdPxBspeXiiPKmQccGafphGIJiyycRuFVaPSAtZXpPwoGsHejrHgawguZPSvlLw", - "recipient": "cosmos17dgrx4jla0zuywkj76xl5yjaes8dfrr0mpsfhs", - "amount": [ - { - "denom": "stake", - "amount": "588279322451" - } - ] - } - }, - "ProposalBase": { - "id": "24", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "386" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "noreiUazat", - "description": "RMFkdUuwIioyJnTEWMUNomWHyyoFxNbMrVFtcABdgGfPQtJRAmrXKFEFWOCytGLaYRWQzoQENUnYoxHIPNayTnWqHvCpmqJewntg", - "recipient": "cosmos1jp8nnep04hdcxckh0hg4knp4fu4zmzkycwwexl", - "amount": [ - { - "denom": "stake", - "amount": "44229105385" - } - ] - } - }, - "ProposalBase": { - "id": "25", - "status": "Rejected", - "final_tally_result": { - "yes": "24914473521", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "278" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "fGyQdeoZAIgvFkETFIcLLvMxwuHQkRVxsNoIgAKursNKvneVliTVftRIKxIiNlWesQqpXusYKddxPajdppTZDaRjFKCEDLlCodqVGCRzTYXMUsqSfFskvXTYJXYaeWjsSZSgUtRlcrWV", - "description": "RESndybjBKXlapLazUOtuRGmIxZPqFMIiATHeQqGWSILADfBiypwtLiOIqVDPFKgXVmFvUzBLStaVUMjxXQEIIbhFuGDHsYtXTViXpOrKzHABdneyLvRodnBGkNVioqgHkqiaPsoCCkGjmJBqmtHUfXlstwTDMlbBfkRMxmkugYtJnBNpkZiZBQcwzyyWOyAMNZAfJxtZfRyvFflvGDNlYvRIGadqjCLlQYyBsmKhlQREPwfHKuOnFUyGfxRhVdrnamHSfSWKLrElPhsulwNxVzovMyurHUpFRwiFpMOxbbjVmYrsaGeLrHJUuQiSiFwnsGZokZmiuWNetruuCgUqnfhsMiowqzpVdKhZiGbyeKYxBFtUuqBAOzmIRzUalIIAhIJbkzHqVuSNZCBfikaKtHtKmjmoIkaxrsGNvxaYKwRQiPEbWpBjjFCnWNaOljuDlCAhWqCbUQOcexHQJqTsZuPnEGJRUguMcRefaNOgbflarVVLvUCOdsvzlDSGaqUyKrBeybLjoJjrRitbewOrAHUmGsaTWwEyTpxAxDtobZZOtqMQIlkysGqtqjdAqsTEcpEmSvNPmIPWSavOJWJWlDghObxboZHHMZjKFkQubPUSmTXZNusbOBDfaZpiMEoUsnPlrfbzhCChcgDnglsulwvMhiIAXWnYyyrERZthKCpEnyHWhzkrNauQSLdCIbumGFNBmRwWfVxngCNiwvQYzXpEXQfTyLQDloONxpRiUiVMnvnshmCPkJjejxYGEeYTRHqzWZftJIvPLuRymfLPyYSHhTMnSSvuDqXSAMGSXCilxbFgjNvwHtNYWmCTLpBgccsuSklkBStbwXdUKgVrNyJDntGZIMCxsgJDprLbxszmkKOgzDeCLqNldOdopsUxDIHovhnyJZnoanfXPkuUkJrQLtSrKmVBCwEiUpIYTcjVUsgWUohpAuIIbmDdKRuytoQLJIyCokcBvrxCYuSROduFWNiehtmMiAYBhYoZPtwbpsmRmvdYNIClOyiiGjMegnpgdaIflThLvxWwuqrGQPHvLiMdtfENuBjQsWvHQuBytwppmlTRonNDNVuLXguvetxxeicNOyiHrDvmkERBWAypwmTxNKdJzrpGYfKRwdpBqXOGwoHdsHJsskfkzkJqyySlncTyIUlAtdLUiUrVMGQJWlEUqlYTouaCrXdSRBDeSBLZFIWbljzpaoDnWkYSNVvjTaYfDyKyOftlUgzpqGgNqIjeShPLamcqayzInXMnjokbOtDpIFpYRfVUpLDEJnVapZDDgbEiMtXcyrKyILxpGwkqsAPnHwnBKxdSXSsIkQFVcapNHZVcMFxqVkHnSDvomfZEsocFJTIiBVJmiQhSMjetTPjOEZbtQOLQVKKMLYbhiGfFGziRdEsgMrioCKBAtFvDRwkBfSlJERcSmWnSwYftUxmsgyxwWQcrcYcLEnpdFdnLQhDjqQCnUlcOrDDWrTvTmLeajvYLHsnQifpSMxWrfRwtmOnfWykWXhwWKOuSEMLDEcNuvxVhjaWPTAMxZCBJPVnZtMzFKilWwXxVeDWemslHcMfrOAiWVENwmPkEbdgJJvHSmZpHeAPlitfqfyumzlJtdyASkhGIjXNEURVHIpLsTfverqPawpaLltrjSxGfUikcoXhaTMsOWdFfoCIjOJiDFcfzIHlpxsKHrQAWQhyRACqlEpagYiOcDmAVltQKDmLVSttXRvMZiSACBVBNzLXZWLDNjOFMyVmLtvARzOleMoeJaUkpIDmCGCEavoehAhGrmamxAzJPLndoZUydTFiABpwdCQUCSAYuJyULSYVPsoUVGiwNDtRhzlWFDIuvhEqpSqtIKoQLHNWBzKceBJoIjokSibNlqRcyGKlMQIMbqMcQXTBgxzZqaDSMlDagAJWERbWRaxImJLgqsQGHPKjtiBmgffgaZmnwusWpKyHZpiDMnKMtkjwHErQJYLJAEDOPsGWapSBBGyWVytmKsbSjNwsyFVjIArQbbviLWqdCzBJEzfwwYlvzfqUXaEGKZTnEyFJXqxXMMmmYGquuZBiNEBVMciSsPyNcmDAPUsbHjHwdoPESaIDzTwYFTMTNwkaHIvDzdQLcLHhpNZAoSwgbfaGjjcDRGjVkVCOqPfhCvVwEPmMHALnQAmiDgYrQCPgDFDmoDXHFFJFVwQUVHfkJKwfehHtZdkAJILFxjLYsKVreQNBXZOIbZUQSVFFmMqmxfSdbroZjiUDcelRTZQldxCFbnQFYgcPhjhmcTVJnILvsGgUEIOViYNfvaODetWwNpDNxWbpDxxfCUYuEgwFcOMEqaOZGcibcDZmikVoWokXMPwCKvvVOFwPbzyFrgXzRGroKAeSPHIPHarxMUyetysmUKBSCOAasafWfCvMvrRotfTqYHNJsiSTChcfQMCEmSNCsJKzSevliZunVSUcNBJPmJexQkplTZkbGQRTmESRIwBcwjrGQaRcSMtjwssSEuAeRmXHKKLTeldJuEIZIVypnCbovzNomeYnUIXwKGEuyrGinqAPowblmXhNTqcMwwPBqXAJrEvCCmECGlsplnkeIsxgSdCfqsvODpRKeznXiZpLYKrWTUUjGYzCgBidoMWbjThzUqejocPEykjfLQcvCKBByHrGiqdEtZtxCbHLTNLDjkVWauwLjBgYWgtiACVYmVujiYLpJnOfuGThpQNLWuVDeZPITyRruaNPrQOkkOCrDMeTRZQWhJDAAcohpBYyaiWpYAelOLhEiDoSWlSSHfevQaLnNqXRkLRtyYrhNwGTHWiqgXEHmkuwkzBlTupXrxrqueeVJTSEyGyctAvJQsAMRrgqpZrxkfNiLrJvycpOZQtVnwHmwzmasIMsfwUybJWaaJIUaKbuYGmYhFnNkHifTrZMFyOvfUkNMbqqcoFTjGtniqIzPHcIUkJbFWgPvRXxKuKjjxkYbXNblfUdpoXRGyiWQMIMvtlKPgEYycIIBmyMhRbprtvcQbUjnfdXeKSOEScozxAqvCoPALMFKFDkVUfGMkZCvlvEBghpBAtgWPzKvhskznqrQooZwRQbzeqOuSUXCEqiAjrrFNyQMmIEoTgxwuBPJsFmritNfgfiHStJUJJqEEHwvjFHblEiuhjQPgGgXnWNhxHYSsiaHYhfXnqhwFOcyXCWiuPkIqyjVbqwHnguNUCENCmpvcUXUcBTWgIajHlSgqDTJVaLsBTuyUnfgSAKeIaMtIOiecXFQCgfBQYREFFfhiLSQwkOlEeiuujmVJVJWLLHVpbcrqciNxchjbIhVDSocQhtqCjtkBBreqYLGkUPIsxZUCLDgnfECQwuTRQoKpGmHVhHGVeYWJBsqllHYJISzQTOUDaWjAfdxcCHUElYEULoZCdGmapzdTBHVwpMLMSVjMfJbHxAXNmAkHngAXpVebvLpeWTHPpfvKMwFMqzTjHlFCpsVPwdINRvJsKzEGvCRfvTptjdLOwYxXIjGsOtdjliOWvQsnrTrocTVRcRnwvxbMRwghfcCAcATRvfuyhCFWUJDyUkzEthJwfXrsJDSDjuspqNwLPFLBSyiSVCMoiDuYPcGZnVDaOLwaAfnIoxVOfWyDyfFSWIqEkUgRXKDrozwudsbcnnSVkkcZmNGeWJOUQxyqCqpojbKLsxvuKmlXMdIKODbXtySNfPndUCUeFjEvbBbzzVIHrfhFrukeYkHVUJMEsOgjfpINpHRcKDPtKGDneYsMCxfsbEqnUfpnaHMQOThlRLQTdmesuzpYjkrkdtwHNDzlZoswTgyHrxnTgWVqjBpWYFpZHbMSmnMUHqTuqPAlEInrAzfPCikvhSuxGuXqIPFUBWgFQXWAJVRMikGWuwzbnxfQkwlLOfuoeFtzgqXAwgnGiYKVxvbYUHPFpxprKCbqCQOvQNULBcaxrSPcLZuXESsFfvIsEmjpsuCSmeJywjMtIttIgTkluOhCKVjkCTVysUspEMsiYEbppbxIeZbYZbyLlpYKmQRUKspqGHzdqFbWszvxzQEbCCuyKVRyBcoaffcaHTkQRxpuMUjOZOaqMIQKMLuyiJLHjdomPXkxbkgFdnCFibfqEtZJoCmfnQXAnTGGxhiZKyHLsiItVAQeKccqhcDpXNjUqgjHKSMCzOgSnEHMTgpXcMbbERYHXQwONNNVXRXGrFZzThqWWhTDkgftSzrGoKVLERTBYGLCoWHDoMKZxIorArZVIOioIWyjukLHwjqJnfOCjfbSBLuEwEyOCzpqctnSkbaZnlWwKJlzbBvpTSEOHcweEeYzcwGamtzDWdCkgXBqTwzolSmmOQQHFaOxVEVxiagUzlooBpWwuSLWAxwWNDxgfUvomRoCYETKznPycytKKIbZDghHcJoeuvFoSvsxickpyUBuwIYNvXFDhfkFoewBISOZjKTxSLqCiQZuBulfAPsQzJaHrUpMcainpbFHWqEPwJSITejHfmvFmhgsfFDwHGeVVgbIiuNgAGrVtZOFIrPpOyPgnrRVPEVOhdJTqBnMvQXjWuvwPvBfcjBCEDQSkDIuIYrCJJIqwBcmucCumyhCSpzjRPlVdOJHVvNOsHtDksjKssvjLrIfzkkfvsuSVsOcFLHPBVkaVFGThzoxMoCqtpDvVUSppVlqsdYeNuYupNaglgdWxVuokJKKEaVWJXcefiztIieJonmeEiwCzfqFzBcaYoCTsjslvDbMUUrjQcRRUZXNDSsYvrgRYAaUJESfJwfuzocoDurERieAhyHZzoLwhRCCFyclGNoLvVOKGPnDkVkasNdtYCyhOAMiGxEjZIVdtKrFqApANBZgWHomQiNoDKBMTrejEBgNQrIdNDTKyCGipEtjMVYRXNMvjzePpdszXWeVDLgnNccJsZUlPmeDXLpRTlUORvyYbsooANoZxjKRrMDToXNiubEPeCCCBOtYLEHMHKGAjgLoYwwSQfRGqoZbSfZjDxgPDSnCCYumJDxPVUipdCJCTaZzjpOpHhfCQYnRJN", - "changes": [ - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"112\"" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"196907000000000\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"822\"" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.500000000000000000\"" - } - ] - } - }, - "ProposalBase": { - "id": "26", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "368" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "ixiJpFrxkmdeswTRGYwiYGRQWXsQCycyRULezGRSaMUjvniHRdYyCLLahMsarpdAVxAQWwYvFXIbZrSSKmftGwlpvZYTLJGgQnaiGpKDPrSNCSeveEeNzyYxqddBIVpLexhpGthMRogE", - "description": "shDmfZkgwhLDsWdTOnBvsZsgLUEGcUaFbvoWxsaaWSQWlQfvscBIpPHHlTZdSgjqAnslLCMVhJOqQPfMwFpIeMPmkEDdbxEscDNPlChhTSoYIbqMcyxHndXEpZBRFdQcpcpRRSJiNNJEwigaCCGFVQdqTAgZvSrahKkvDsgFFqKsrAKGHaUSUoDAqwpMxEggHqYekYWYptMOqdntHLOyETGYlngCJzTygWHcoNdnCwtGzXLIQSvAhXUAvntsWPqDcZqMXIGKhKCAuUjDAYxlBDnCPKkrLPFPQZUkaZiovaCFiNVQsdOIPsCEKIIOpRrxzffSKjmcrSnSxkCEePmXoCpJVyXnNPdrosuYqHaUuiJckxAgldXVipAutCmbjiVaWAIiioPCuVFrREAhkdbqwXBglngafumzFyOMJuCWCvlLYFQTaawXQaBLRVyxSrFrSNssNMmipAkdfwZYiGJRCmbsfGAEfevBAdsSZYrSryVktwFSoeIHKXeGIbWdRWIjhfsJPyQvEmEFbnZDPIcrGkNkMcCrsVFUShyNiYttDsxUbrLnNNyQwOXzCbXLQTTrXVhGpvUFMkmiwpifkRaFGyxQdgPWKTdCcvzAunZLFnDZTXWbtHxecNQbjLjLCbpzdcXJxmnGihvPfIbYTvMtkLLZJpMBIjfHnFEmcwdMuwYNfKUQTjrdeFUNoLgtgZhkHGyKElbwiBLaoFAKLFrVpzNaGrGJstdJlnbNUwZDKwJcUggYiqclwWrrVJOjxIAQJrHdxxCRoIPXLybIadCzBvAzcKKPZMTOXYsfJkJsCFEpHuFPFcViJTOVASuMsDXjqkkArfEHBoQQKpkGJZJsCakzblwCiGcrOqnRoajAXMpGaZuknysjYmSJVFdSwlVooifYJvEiknLwNQgvJQYJtwbrEPbXbEtMmHtpyEEexdFgjHZBmqLfsWbXvYSJVSHjWgLUDZNponzXxeHRgusQirCxzXmTemCyJlLrsLrdLIaRaJqZItDdDVPKhOtuJUiMgKWAFYcuizwdLxsUqngoTLmdCAAItqKYVlrwXpaOXeUZIDujuwOCGKBiEGpUnmWwTBQXtgUleLotTktTBtfjhsqsQXcugQULkGFUsSwafaQyIaoQZchAjpGvJdKVvBvAXtrmssOXKYNdGCLwsTQOSBMnBiQDgGoZqGvnGCYrAHufgfcBGLmTmoZAhUqVltGNskGhToEDpWMIRVomGOEFenbbBAnBQQDtzROpfYQxyZDXKYZKjYwskEqcsSxgFcpWFBFSFGhkgFrcHTQtIqeSIspzfmAmSwEFsZHDLyrnANNqrjZOSBwZAyvQABsNJWgMCcNZlTNMDcpfJmkxKXrJuKuFHhcvpsRugmwOfTbobntkejbnvRylZAyfFMIcFnvXsPBzyMLCWMszpUoaVeDWirQnjAwXeIIwmcOPNMHAmSBXQJOTONEXHUwfjGpGXpPXFnCHjDwEYgbVibWNitqkSKXYwBjgxCefmjEbBzjhRMOYPFMkEWIDfiRmbfyjfenvIFakRTSnkKuqrANNSVJtdIrFdaiWRhRAdvlJeUyDhBhWrZjDrLDcRJUVZFHjDqfGmAGYvpfaKUQTBqbSvorxPWnPJVFtZIanMreTkvbWcXeQHmrjvRPqlJbqpDbvacrzkBNxmMfmvuhozgPcisyKzpFYfuIVOmVCmThLiCzMTuTPoKPzWxFNBWdxKmyyRlkifCqZvBEuzRyviefshMikoPulHfmxmIPGlrNMZsXijMeHeAsDWncQCuUAtrKJkhbgklhwxdPJnfRLNSRqVIpoFkrHBtsugrJUFktuQBhnwwOhbPUDvDxnSgeCxcZXfAViCuckmjnLDeHnsSzXESnMkEsAjmhJAvpWJixEznsOWQreDgdkzrHaSwKOpWJtLHpIUeSTCWNFZsVFmOzxwqWJjxqogKgMpcRCqWpojivlRAPMyixsvqWwQhGhTPxmFPTwwUnEWMooUTPpDfpcsJukpttVFvyOPllJbrSQViMkjbFgeaUgNorvOxNbuuVFKAduVzMEvzhGRJuDsMztvdvHNwgrEeVumBzxilHjQHAlvZKYAaPjqqAVdeJkUwloAQVedRHiDZLIuASrrBbrPxyaLAEPwxPbRcyrUFaezlsHbVSxzUSbyuOsCuYNCGDBLHmDQiEEfUGELwnsNNifuZdhEWqjfnlbHMyBblrzkmJpUdQpuoYClBGEdvvKcDzxrBdOyBrHdiMezTjPYlDJLPzzjIMJqwZxqYDaNdphfZdsKzoFEHSwQBlNnQpEqwJyVYZkBNcEBZKIRJujjzVXrunxJQZMVOjQgdPyimWcxjRpmhKkfBEAhMikznCxOaHflEguOseTYxFJPhgnOdOEGlCzRdpjupqFDGzMMvuRtabTPmyLOkkdkYOaaKkxMcwFmCWXSRtllenPaVBBbNmlbNVMbAVQdMtiorhvkXgDMecTwmCgxmgbjOiDilVSnEDTlwbScRZoUoLlcExjTEuIwpObOeLfcghCDjrCqUMEXUQRYCutAxKxKIYKaHDstzKKFFJAaBAupGVPvmFXwzeqOzYuMxshHXwmgmPPZkTrZjmCENnYNXJtBkjNIvyNmcwekYMRbFmTEfHYznhrYHZCmRfSbQMaijsJEsHAjbIUtzIULSiCppadRcFlkXwPYVLSHoLXBzsRplXDqpnjsuTdwLtyRBeZfXzSDzRkbZPkElVLuBCfCIUYbzFBRFjDmBLBEQfXIZEdGawGxACcjPKECfrIIFQKIaSBBbzQOoQxOivObqzrgiIRJszSKqUgqOESEngDoFFpjgsThrbhOLaxGCIjzkgzWSakZRswFHYIXMkDAqNFzSYpWPDMFsYbQgwDnWiJEMDWYZyPZAyEBiFcuBprytgXAsaSfkYaDQTGjcKQlhkdvgbfdEAGUmbrifaRgIgSXSUGEvhTvmPokHfUXrSXmhGiBjPHxwelTcgIplWJTAaBqbFFcmZVjqvVjNvzJWTLMWhICztGJudhLazrcyzYEvxiYDvMdGDxBEVdbvkyQkGVyKTvuyfYuPpdRhXrtaTuvTOTVdEswlheLUTxXPaafmGmEUbmsYgxmSnGYfEvNmRNDSJouugZfDiPPFAUgytmHfYEbyyseXoGgjYcUUEsbTxnGEWuUaZmIZsBIUIIKTlOFOzTALbHhYgZIJNcaaHEMfEmFtkcFDWqAcrgmTzgryIanOdYhfVsGJqdWoGGpfwfNmxHAkioSwLCFzCGsUdEWzKZsPjlRGRpBIQPLDMRtRTYPGNqDofVlclVPEvSWQpvjGsGEIjoSoIHQYOaWkHrbsMdMPiSeGRKCsYFaIBkbAqOEkEGvLdKtPWSssTgozEnDBOFhiZklcZbrHWEMNtgxSCNCuAjzfoSPZEhhUaBZjNOOljiNNJAOAIbZAoFsoEbCPYbXRBJGrgHSMfigjxyFutXPrnrskdqJOYdndAfkEocQlBIeAqOXWNNRurtsZkNoOmVspUOPICpeucTGdXpmBkxQTHpCZsBTdyDYrCPniuZCfSVBNYcYPXYGPObJpfVvNLwXxoGqJUObuyAhrLFNDSOBuUISmEuhiatiAZVuOhEmTdfiJJDtYuYnVQxCANABaOSsgAaatqLTEBhEDiKovwwTjDqzyytRPxBtSULPeaCEMaSXpJyVkXtwKKlCwHSOIAoNOUFmRljsTVEUbPzKfeSxHAgJDwnMzmfrPUrqQvkLIkhyaGeKyYebOXFebVfxZZDrZsUDmrywmYUqTvHogxduVgrcBhciSfbrehOvmteotwTXXuyjWXkhGCzouqqrqxeRvoNwpeahPgSTMixvVikgLbBwbUgXLmVKpKhBXaynrABPVYrbbgDiquxpOBugGShrsvPnXTChkOQPndiieWSzjUUTdWSKjJkIBfFUjaPWRlyQiIIugkJmPwXdLWGByZPZfXASHAtwNOzhFChzAJqdoyRCSmmRianYFYiIzOFolpxyhAWCluayukuApckfWHhGMSPOddGtnsDBPuoEryeeKeokBTDqOPTxPVAnlLHgiHhlJyubuftCGmXHYUnDhcSmSSEjjGHNmgDbTeCkTDTXWaCKYpWUrSQBQzfYoyQtKRMwFopiwqFJbrLayakXDtIEutpXISUISfUHggRjTtHjjEaRPvtKTrdDVCLDBnrisgNxmhLuzaazNNISAFWjmwzOWULCRIVozolZETesUrrEyvftXBPQXPaTMybEIxWUhFOhVWsCTCRDeMhdDBkgcBAcXlofBwJQjnJvdfuJOVFRGVvpXStVagOJbGLPHVnftqyNdAlXFLMdGNQzjukqoHcCBmtWguxaUAzkhhAXZfFmmTPzFcvdfuDZPGxASTrkAvwiyziKERoUgOeevMaViTrUWZGwJgzKGFfvXiWTeHKiRYuNkWwJIvudFmkpMSgMGFIwnLqTqmqovcssFnUVuPOwZUeQgANSXySiKKxDRGUKWrUhhLhJKJJaRXBoiopLmiBgHYsCjqPjcCahrIzlfcQsaNMHeoRujXnzFoLrJMTZleRajojIzLmWFGfLTfhoiacsBqYZhZEuUxjQFKvAjACaPrSUWfWqIUoPRdNmyAaWngwompHWPvfShbjlgENrjnTzCkcayJCfOXWYoDUGEOIazohoGJxxgsPEHXmyaYYCziGSTWuvOGzkHnFlJlTovSwVruEnjciFLhSjbWwchIywmhMbHlqjYlGhtrbDpwWhLNGsOCemFcSIcgYzGkkSGBrICYJZSRccKEbLccDtPinbjVfVSxawfojNVrsgrXvSACwCqRQhIBDtAdnztUDBErdOMKqpCjYVvGBDvKjXrAYnzqUroozMiZlnMlkGJPLVIUJCklkEnGywvVmeBjbGXwDKWXrfTDLpRpYvsoBlSTESYDROXzjyLrNUtbkvKfEpeAIKXrivTsbQLYBLirrrfLctqjaoRbQJsIEhpiwZBoETzfkEGytnRFQLDYTxziKcMkf" - } - }, - "ProposalBase": { - "id": "27", - "status": "Rejected", - "final_tally_result": { - "yes": "24914473521", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "277" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "VxMHsCQejd", - "description": "PegFUgrFHgUoDYiJnuOGjBblNPMqrOJyavhOGrpyAUItRPoovYesWSGSQboBCfTiCypwdzusrkhNkTMdlsvjyRMJTPtXlTKCPMZI", - "recipient": "cosmos1n0f0kcjjwrjqvva5wq6x5nj0c45vddc2rr29k3", - "amount": [ - { - "denom": "stake", - "amount": "390762837487" - } - ] - } - }, - "ProposalBase": { - "id": "28", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24914473521" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "418" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "GDSFXfaPaOKOZBvhBPhfFkEbHdnmwQfbBcjHuNOuKEdlQzPHbPwnkhhgYcJjWwYPDVydeUGGSgsUGZWLtREUBrLJNVhFVDBWANcUwcUpbbGiaHSihjzZQihaNPtqrJDqDgIRQaMwTUvJ", - "description": "lYOhEgbxMFHthcmHlxEabufYhHErQYHkkxtrRpTzIWWrHwixGgeBMIdFkesjzteOEdcMfkKAsOYyUyOLjUuwUdzOLNBeFKGSCsRpvvZslSRqFVhybYasqZFGHDbIqmSpEnDgNAhoKbBzpBaWPYeOhbGQIsRYKDLtXLuKrcGhvGqguiRXWlqMDLsiFYHddHIcxMoOVUyiOBgPhJAUPeBTTgUkVYfqLJnEhlvLnrUsnfYuyhWHHMGinYsHRlbYoLFJmfsdujmsamOiCBGhXAqtvuIUTxZWcEWJRVVEzRtvJQrOltlYOhJPClojNEadwLohDSVCyFTWjMGskvLVyNwalDqiBUcgFvXOyLhIXgfAHPSOGzuYMetEvcKyDbAjQQNQsHcLFWOlMKLoInFoaAYxYFsRBGDKVYkcxsIeDURCcnmazlgJskXkrBjKpbrIvAqLRTVddGMPkXrzUIGuWUQZPooyjkaSFszMyxGvMgwPmRhPTcGUyetCHQnQutxmLFBNBhtJUWNSkUpUefjNHRvlymIjgkXrSxYtbyRnGYOqXDUfhRUyTLhQiDmzvyHPEwwSpuqVLDmSTmtELDPcYlyyxJRYiXEXiyzYTNKCFsuokDeidfnVuGAMSfPPYtpwISSwjYUABIqvzTrLZMqfOaDsVClisMEpEpsJbSORgGVRXmhTJFCeltQKWDuKfagaTtLHRNVOgDARawOvNkFuNnebxDPKfxsLHboeScmlSihaftxgrZGVIDFOloKlGlDtLPhfbxKRrnxUvfzRFotqyDowKEVDvcoZsiQOpzSgECVwfyCYEuEHxnKJehKLEwtcWWCLoHEhfXldTNTdlxcgfglbpkIDnQyrcizDLIwWfDzVSEwxjSeJnKCQZuLdsIovwlMJpCqKOsizBHAIItFGEBpEYLevSUfylAlpOjZIqfnbKujeyTXdfQMYoOQgUqsxouAGpAzbOWblSrBdtqAiNJUMEmBDbfxJAOKMPwbNfzWupNnpsTBqIojSRjxQBaIwUXxEKqWGCCnQahPcwoAAYFCHnzqcBaiHYVBwIelTwvslSojjCanIBlscCyXVUBSRxBoNAWNcjAGZsDTqyVhpXfvsKoKpmyARRyUOPsQKPWxVSeqWtvIsVWdGZdVcoCIRgftYSlVGviZMTzepIWCZSgyZfzvczoMPAQoGmfYyEYeiqVTHTgyeTNvIOwIayVUqoOxkHLWEFQpAKcbcoCuQiquleqNrTKPJmVaOdiRNRHqNVicPtaJtUFUtdhsxxVHMsaenVhsZTnDcAPaSmurXzjqtHeoWJeAhRFgGmjQAQORaWKFYnFngJmUHZqZtluQOpPkEEBtfjIcdpFvzqPGwRiCPhBcbiENFDJhNUegfWKvqDROGdRjRPeudGYXdoobqjMXsbqZbfOiBuuzmVtZydYDSxBsROUYBCoLwuQcayovPpoFvNPEeCbDMXIuaSxkiFlNTLhoNLupCnzmzEgujvKughywiqRkptPyuNyYVvCbQGoWbErBwBBODEwdQdsDZHkvZqzeONgoaGRxMbXGcnXOuBeoyXzXYcfxCsNKGlZhoxsScBzPmgAfsQYSAYisStRQXOgTUjtNdPmdpCrIrmUAJALQvEUZMDRcZthzLJcXaTjzfgDiDlaLYXjTRxhNoOwLgKAApKaOfzzVHsWGTahrqscFYhREfbFubBzQVFBqNVqGMZRdCrHbwCDElifaShJPvsKmCiAesEwiwMzKSFMnFojkdAsRzwqzdfoLlJukfaHMyWSUimjWLGOFEtGXMOUsTPimZAHQpiZjDzGABGvpvVSaXttaBgfpZtWxFSfjHvokjTygHrsZsJQDdrUVsipXjXIQXjkfDVKypIEeedqJgNkufvHBnMxFxrDyBfNzvxsZDamwJzlZVlDnUuEfHyYMiycRZVryLxlSIWIyizGIWcfbsIvTcaipFFlZysZtwFIsXDAnpZriZwbVaqbHpmxArqIYWpYqbtpFAgfPswqnCwZlyVvPybCesHUhkEiFDPuUeohkCayUGtaLhkpBnHEPuQujlpGWAXbOiRYQGmrSrVWcSXeEfTytFgczEFajiiQntYuPUcxCsGOennmYWhZCJIOmScaqcQenUmYfGvPftiStidLaXUEedIbAzmlwBCzoIgalQglnzrqWAtDgCxjKeRirXLZrJZqjRyJoVhRIPzJZOsOzMMjwvkAvJELEgHKkNAKodREcsRWslaHscIGfNRgtWZbHXpvUQhwQLaRzFwUGBtIiYCiisldaAaLivCZjXWPsbfLCAjVGJKVHpwfSyWeHWqRZkqBJgAguSDQQJwTlIACqUCuMSgnlcbPmAEvpCEPTIBDEdenypgIIUExKJBWBOvGqeslTtWWFdrankNBEirhETNCfmxVWPkoqpReLeGJeKDhdOoiTfEWqJJjbFvbJKtnOlLjJWMlBitTbVrqkHJFoBKWstolnZiFUCgCOYxLvrRokbsLGqYfCEAYEDygqIzmhedFxmIVTbhzrhWwfKxkJZCneKVIFgqOhuHPOvnMOdxrrJGwfihTJYgXigZwOeJJgTmkCpCFwDUecBiSehTxjmTQMFbUInogNNIKYWXvmypznMubSUAQnSjdyxxkGxMoTfILuZKBBBZhSWRZwXXDVNuewurgXBnLrvDahNrYyctQiRPHWlbKiTVHvqoRuEJbnFcoQYwqBLKYKrEBiTOWfjhdQjwDYuIcYNjRShRyGWiClYJqoNteWhrsoPHIbMJQrFzNFXrfBnZebNMjcZrVvTloLaGRrjQyBNwcUtJZJYntseKKYWARqXRaShQoruieTgWKqDhtXjdzfayNTJvRyQGUDWFwGWHOdLtlYeMRWvXrwlplByTWNoWUsNOsnWMFUnAgMDTXXHcjfnfRYCcixFRUGUbvTfSBdnSpCjLLMfzvnxidGFmjdbhpqfWeDkRGclHdTptmVCeCQZcVOagKwIsyZjZPjgGIAefqCLeRweADnURXUPlmunIGUQqpCVTVdJKkjMqMRNlaeLyTQsvqwrwltlxSvkdOMcLWPEINbpXUyIwveUuXrXlwKpRkhIcvSzeVqiUGfvMTCJgpObfgHzMKZvhwIwklZxCTsQuHsvCqUkyLXjOIDbNZpOQUwlEPsvWMzeObhLBUzHVpCuSbBnanERzNjEwYnAmwSyBleHyITZeyvpbCEZYMGJBKiMipjGMHbIhnUATgaYIfcwkaaSQeajKYHXAPtTjHokbqiWWeelhtNdqQpFewomTukDHegfWHywpbJBgEhOrWjVhpylRehjsxZRjALmTHKYeTjPCXgMsmIqRnjjjdcPWmbBTQoFsEGfjvrJIPabncOaQctzawCgsgnwdBPMEkIthQDwLhKzFzFFHGvgwjbzNYEIkZOgOEZzxpcpYOCfDtqbZJjIkHCSFRqfodvMNrwHdSejnafhmjuhKVgmlfelHXQdPRaJLLpEPrQqACyCvPTQzMOvoHHZlyUcYseuwBLIhEiWOblWKPQeQuheVBGkHJXOutQQivgcMTxpFiyNdndVLflzBnLbOpUguwMVwjjYahQCPQioDBcykBefJJHTMhsFeldxMKpwGbmkFRDkacGWTWhAIZJpMSNqsfGAmucclykOUWZdpBRALvykxJsnXxkMLOexxIJdoLpUQLMsHHRgBZNcAedtsXQNTaFihijjzOyPjsCHPyRpHZHJwPCsEAExHJcGiDPjBhyetsiXmuBaTYSmtNJcQyKTkqVxwNXoXVmOyhzBeiZUduJTgJpScphxNHvTKASIimQRMDNBJclPXlGyODZxgIXsViYAhKVKhpZkfjnSBEEvWHAsbAzZdznNVyeIYGXAtQJSYyfInzPWXloQULRNyusCRVBifdHBMMAqvShySpkvjthjgnkavtFUyPsGdDAPcqmuPzNctbccffotPwEKMdLYDCeGNvLVBacNLvMOcsJkxySjoRHNxoCzTycPZWAWiDWCogMVvpyamAlWDOPmsHcQWhzBCoSuknZMNfhSWYcoOGyYCOlEGCXeoXdVkRaKqkRwDGJcDJPMPKAuTDAlcpKFQcIxuGgcqabjiUsSykGdxwzsBgKpHdxSpXwDDHtwFeIlDvgJCcjMwKXoeKDwnIIoAeBectJcmAqACwKBwyXIMejElbXqoEitcCPhuxnvYktIugizYNiMmZkEHPZexShBTbRMyQpWVMeWEmhZHCKOYTnunkUIYZJdIHuRJtiVKEJHHSCnEWTGskbGKOgBHzTsEqmeYluqVgcSXqiLnzeUKcRlYAqrcSSrmWojskkRBMawMMgLsZaCRsvyPgDcetiuuBLpttLVclasHmrFeAFzQfVPTnkFuIJrsmYmMLpckErSqFhNhoGzWAdXCRzImdgeiyoHWAaSfZvUAdxlGatBhZbAHhXkbtGFeMITVzmbLXyZeZKMqRGpnOFcHZDOfmdZoPKBkrnTKsMpzvBuTlHKULpppCaCCjkJtxoVdZqNJoztrDRiwclmOLZaSZYAZAOaTAYqBgSIOzXHIqqjRLiviSuxZbhjshAnBxITrYlKIddhygoPCTigfzWHVsHhCQRCuCLlKpRQEjAaylcSdlpHQwGaghvDaxaziyQQTzHBQGukSPZOZpfJdcyEBYJkXrzNtCMyEAkbzxUVtqAtmTxDxaSSOeaRFUAJaqQliLGDLaGUEKZVpdekJvQBmMtkbPEHYumbZsNoEUnZojzKdIFGShrMGRpqCUgjerwnefvqlJvUrGmWjsVNTzPoMugLWtAOTTokzbuoQQtLSevHSOKyfrYKiXwrjRuyglQFxEIVOXfqpylGqSQvHFpPWSdckrKqqIaZspRclaBTIFzZMKaJYxRjnXjrpAHoEUMgRrEdxhECiUGuufhcAPgQPVmJbhdbtBkQuuNvbdlVmQmsmFkvqSQKxdFrbjmfrgDRPYCsbKEIQVnwHBsNNAGbAkgkGkMQjACuEqeXEEaLZVQyIuPpzRnZPgpGgmIdcnwM", - "changes": [ - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"9\"" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"11\"" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "staking", - "key": "MaxValidators", - "value": "220" - }, - { - "subspace": "gov", - "key": "tallyparams", - "value": "{\"quorum\":\"0.419000000000000000\",\"veto\":\"0.332000000000000000\"}" - }, - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"221801000000000\"}" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "gov", - "key": "depositparams", - "value": "{\"max_deposit_period\": \"338637000000000\"}" - }, - { - "subspace": "mint", - "key": "GoalBonded", - "value": "\"0.670000000000000000\"" - }, - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.280000000000000000\"" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"175\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"754\"" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.030000000000000000\"" - } - ] - } - }, - "ProposalBase": { - "id": "29", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24914473521" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "334" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "LwwgzugSIVSkUXGrQrFlHbbqBnjBYIbMKvrJyNgBSxOlVCrpbwndyPHQGtiAOxZQNJoZVWzwfRYzBJqxjypeaBeIWGFBYGbEHXlmNWilcyerkTHYRHEaYOrZcODDmzISnAWjvqnaiEZe", - "description": "sMOVlkjyyPJNTVIJiLCWHWRtnXfuyQWPMumEATuMdkxNiHTzcAwNSIUMzpPzTQiNqgUWfXpkSXOWelIYvqtDUAzEovtchYZFvWnmwGdLOfKMalhawzkRYYTKjZTpZZQyqJXTqclqHDWItkjxPBizJpESUgvjsEaWslUGeSgBiVRBaitXhWgJEqNCphWkBYQTeghikpiGgBhyOyvKtHfBNvMSlIpXwmgvJrRGfiySVBdXqXXKYWgjUobedbVSscZMnNwvOeXSiqkBLGZCefegIjetkvmYQEhXyCTDWZdDlcXBCfewBexSfCHbQSyCZBDJrnPHdgUgmrQiWOkySkeTzKbZjRkKDyUdAZYuxLWOoyqJfDdGAiWAXygtQyQYHlfwGHvvgQWgGkufruYCtnkgoVDqPKBOpgiNdLpCywuMRcwYvuRwPlvPtbjFlTZFoRdPwtQnvZGXhPcQwGRsWKRfzkGkHShdEiofScRlRtQFaPxHTZPIMMiKuLgFGmQYvcMNlkowKbPFfZtSgTTjkwgraoPyBoxqTKPSlswisVyptbunKYBSVxJbveWYpAyzMvUsPtudTBRohKzsjmOBJetafdwQtERfWFthbOwwSaZSPwgwnttzRveqxiMThhZGxHXPdtsyjwRQoGoOLAMhTaihFMpjabtESPVjexTRyDtIIKMLsLxPGefiDmbkFgsREUPCuZdXfjqYyyiVMIEUlVLPobYWWvoVQFlJaXMMKZpWJJFbJWjUCMpPzLyRmVgPSFnJGqZUSMgsriRhrlokOhOpsbzcaKWDEaTIyMKqnWUkHmNWOvAYnNNLVfvAmHxKAtSjMTrtBVobEottZLPyekVQEajUkByllItXAcdLcEIleTGLLjCRxQBBATlzMnuJrslHvsfbmnmoGqvlnvUNPaSagduaAhTnxNNjanLeIcaPFGCMtyWBJMQZTtcySESEpctxNRlUIceRwPLsdtdfpPpNogaVLynPrDYjKbRfWzrXSJxvVsylmpZPNgoBafEJrpLajBdseYcSRWUnWTxhBPCVgNzTPRfFAfUXAAWopgwDWjwnekHKTwjSZcHCYUIvUMeFZQmSEPKGcFyrUdKdqMXYVATMfBYVVLDSQcySoxLGvuMMLMXTTLSlAXiiqDYANAEbBJQRmMHcLCrXocXKWsAzlayLKwNrfSWFfVtqwxfHQEbLHtNXFWoEhsPdouJhrZygBnfFNjWwuTIlIFlGQwDGnnyWxaUEnHUMieTpjJEMYRHMyjeIJsuZjANmiMJjvxsarGsenPzhTWThqCbPLGCfDfjUsnWgVCQBYYYMvzdiIsqIYzFbUQcXQiarKANutpZUBVMzSlHHlqTqCZyELBtqRHZfUyreejRgmsteLKVeRenzUCJISLhHaFUrIBhhgsQMXyCWnnrfNFbzQXZkZmQZGxQkHPVfxqTXzCQYxsWIVTfVurFmLORADbrAGCwpHFodCRAulGeHWrlMUEWFbeiIXmxBBaLOenOpltggIyGbFUKZMADlXVmbhXRAFctvRMawnMkjlizTGgnwkcxwcdDOqLFRSTtgTZzoLXzQblyjtwSEopZUWxBCZiHnCImJGXzmnmWxioTgLeJikmNeyNdoGoAwvwEaUvvJdPFfkXWwqzSHgqWSSSRlKojsAhZpGkswrncOGKMFrqCDjAKlEsrWqbOQYOHamADNYDgHWSBzFszFTpZidCxmtWjAaFMSmKEQbJCZolQkGywbbPLUBdUaFsTtBiXcskNOEqaWDFjLglYePVgyYrVcXLSSfFnGxjDQEhwTTyFtTdITMrqhwaRrxhYqBItPXilFYHHCRFgcYmznXwKxFzcwSaUQgbKRhSdiUXkdAJGrJQlytTrAnljtehDJjhiMVuuizdFdmjabbVnzbjdKPrZonsJJFoZlxffAzetBoSmMgAZuUSbWmrscVbWDHZfklmRLevrfiKFuWZlsqqvQxpJflWJkoQaFHaMlxOnCRZmpgOZyjrlrCRlxVQvagmtXSgslvFGaMayMknMtCVraIZeVfGJNtbphZFWamlZDmAfigmQWXExteONoCfAqKXttUHPylLKYeakJmnaYezdjJRqipKtaXLPQCIlGaaRevnEFiVmSlYvnxxcHxzKXKrMgEHgqKPuxSgZDvbNKOdgqfqawgyupXWEqNTaotFxQpgCLmlnpnWbvFsGdAeWWfLLGjUEpIqDQbiHdJemtqfTfMcRyUXnuJscznVeNwCozeywOhaLOEBdJAXqOfJHdqvBRvFsMqvJfuifZSnLkVUvElRhLpJevQxiyxPoEGlQChQNoHFeAtEtKmQdPFKeRqQkkiqXQUASPFgzuYJjawmvYMTPPTrJGphFWWgHDgMCvSEkYjPGvLpndbakQGPedjbDVzheTXCPoLxjNhsCZExnCtfJHWvVllxpQlwOuijaUAsFHhdnRsXQvPyEyZOqaqGtRYKmobDcaLlQQKCuzLptPvDCLGuDubIucsQKUpEWSljHwGlJCnZWOXwlhGLEdADeAGCmgoCGGJoUwyJEtFzTVKnNcdeiDqfHosnILRXJPPChgqrIPocbWXMfziJhTqNMmrCQBoIarMcCGOaFTiwEUbDEAuYryrmweIjSmVVBKYhKCsDuNujaddeDLcokxKFxxmJNEfMsFXzyAqFGATgdxtfHzgVtFfBzkJvPtqfMzMdvgXfxLmrzzdlylSpRCfkbjghCVlKCDhjKkttyPLvSlGBBKWNGdiDCJjUrECAHfxEfWtzMgTHpxNzJXdJhBYKAXczxYRfqpZQeCCZvuetIQQriEvWLDeiXiSwfPdpgyHKjzRRprdqZCrZdEWucEFiYyPkUGTFEjTFNfXWscijTSfNQLMsvAgKPKwgJNlBprtjbHoXnkKrxhIKtEeypGapHRciSlWqTemvnyemqjhkNiTyQRDTNLVxLxwMasMwwqpnxCZuogVlSTzQiLuIlWxvUmGFNCZtvBvJxGhaSaGujFPxXmfZqjDuSmFGEwMUYgVZLzweACiAWhHoGoNYBKnXvlBmoLATMAVjsjAEBCvntfrVhnZsJseUOlgSvEVCFdjWgaidHabXoEsttNbYEVJanxWxXPrcBPXmOHLQSGOsOjIkGUKQgIfVUqhsUbgQRHfIFgvGSUXrNKDLHMkbbmaUOPcsCiIgzsXHypmCLtFafgUosnvNLXXpRXgDMldPcBpRdLhEhiEZUAxqNuXreaPkaBGWJVdPYwTPFmAViDVbCrvvnYIlQIAOMrEVemWXSGScrRyAqyWMvrSilOgaYBmOcaDcXCiGjqxgHOupzcpeboTwCLrczCojBhBdHHruheukQdRIvTnQOXYipwoFJVfpMrvRYJDHToZbLLdnBwBTVCukrnapaRcihCDDJTOUXrWYpbDShyUTxjAmqYoSCXtDxEcrHCBJdlMGekoOVTUfCJGSpsMnhWGouzERyQNMxDoMqOqTEynhYzdaYfJWZDkjnUfgPUqQxFyovvTTmAxpWkVVumyvjelmwGxLhMBpYaCiOBUNEKjRjXOgoMcbXFJbgwXoJmDZcfFGUulHDZgzrStzgEwAyLGWCmTksZSQrWYiPLQKJiSTNCwgWemhAnxepQicZhChLavNdolZnoSrpCbMqseklMIapWfCkKmfWvNASRWnthYgiWNZSPIerGskiKjYVZKiPjfVnOTuJSiZDUzwspuwZINMXZaUyRjmLpMArYpSiFYaPxBCgGZXnFDQdlhmotShYxAVWXYlazzsgyHdkESjkcDNZyZZyBKAvcvQqfJLYmTnWGOyPNolqDqTTNTbLtJmkMWZrtUubSkHYKorwygoctTXPjdqlSkLKcUvVUQnlGrRUPErFWDwWgjHQMuazShbRbrxVLpMepUzedVKEYWyLBHZloRrzFaIUhfXKmsgRErpGJMjCGkcCArPAdzNVfaQdjfhTXOrYXLjEIANYpQjDEgLaLzxlkFRUXyAqLkMipxSCyUNfEjzXwuXJbdMrCCQUUfQZFWWmAatseObvexRfUDkPVEIekwueTuCHIrepLRNPWRvInVrsKuejFQtCYSmhoxAyamJESKtCYpnfsycAbCNCbJUGMxfBbxptcDoqXfhuvUrCRrJQJzodViEwdyRringowDWRaMNRJfWqBhNdEjgYqMzxCCChDWfkgyBXFljTWzjwvNoxHnESHeMVHDBmQenlIosWIMQilcauZbFZATLSRmjiJiUvNnEiwwLtqnqPyNnRBYXhFXhBNHcAValWJcqCOPtkBVXAfCWkoMrdgHYbLsWfUraiCyWrDNJgLmUVWpHUnmSAvVlEKOqxYqsmspzlGIOpQeEpmrVrMTPcnbqkpJvbAVvygenbGNlmXByenApnZBtCCXswlHjXyvRhHkCgPfwrZhazvygZMLSfupSLaoRXqzpJlGENzvloCFRIlTPlzBwXaeIuhqmVHdbmzyliZIVroGcvONaBSUiNUrAhNuWigbVtJglUPhYLOiNAgwCrbaERyvxgcCtWbgurIswCizYwQIwVbWhtASoTVdbyZKEhYBArYDTskIGAXhdhjpTlODmidIqWIahqWWslJSZAOvklIZCGYwLtAqKYoHjnOAEQMLWZNVFTKyXvBlcJatmHXYnxXbLQCngabpuJPaluhobWqlHsBsahJcqUxgKABEqpmXtsMbUrCdNodVgnqmNNmOoEOOStoFCZExPtFOomjQPpcQIeQjpnrwVFhWpyyneuILvsAjsmtCbtdznctOxospbBDQQhqVvgKIIFEKlSgTjqSmVJnPMgaEERiiiAlyEjlqISPjDxXAchPVEltCbaYRUDjfKBIiOZJaXdbKnAWkPtzQbgvzfGkQVqkjDuDXPESoxTMTvppsurfrnZAFkqZErffvpzkEPiwrIqSWJelydkctzQQPVtjlWadwoKramRUgOhznEABddNSPhCijVCqkiCDTwatBzApqeWKQklBBFJbCmbwOhunUbkQSJqJrnltJliIiRzz" - } - }, - "ProposalBase": { - "id": "30", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "257" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "aVOvuSkuXU", - "description": "sfxVWHdImIQozgplnkSNFtWQTyvVgPkRiKepvhSZfeHcsdoKGfdFqsDThSNvmYMnXbzzHDQrcfVZoHYJVESNCWGXQpugcNYBldfZ", - "recipient": "cosmos1waql7pehyspkf8l9q04gt508c0khx0nt64jsxj", - "amount": [ - { - "denom": "stake", - "amount": "598671584082" - } - ] - } - }, - "ProposalBase": { - "id": "31", - "status": "Rejected", - "final_tally_result": { - "yes": "24914473521", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "244" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "hVaLhkXVmCRkbDgBgSFKaYKqXKJLhiYbMnlOCQddqtStsnkPNjlcyeaTTWXsCFkPObhFvrDniFlDimEkNnqojnYvXiyvOVuuFmQCTcAyLlOsncrKgWGPDIPpfAMaDmFfOzXPcmgpFORe", - "description": "jTjaZCkBxMNfRtcYEVgVUdmgiWMiFBeWXaIKCwRuykYdFmRHNiznNgFTPHMcKpRqlJdupUFdMPrPKqKBfSMqpKYsFkuBChuitfPVRvAcOfndAhjldqCyPIseVvvEDFCOQVqhkIWuETvdvvaQtKhLuaxkcLElONPUuSWGbHltDXuuQMnOOTWnRxAGVjBrPsguNcEBnQDSSJoxRwkJaeZNbxZHYmkPVKsslytEyNqkENoWZJfzeRvzyJykkEQjMXrPkfQLyFnsrbhsiTqytKNUFQrNTXBSnlLgThiPMMAljUfJEHKhqQaaABZjInJsnhZxkHUBYKqioLAcBNRKtnAgBdFDILqBUoIZGxkYnuAfHmDggMjOvZXrmPSOwPcpFltcejgOVYAmBfIfUJeDalCZdfNpuspBdFmZdwPuAZfaOIouZLVRheTnMgZodxzOMsBqsYbgrCmwLNobHTcQcQhNhnGzxBLekjCUGNhGZCTiRSyMNauyzwkQYnbpjyVzoaMjBxVaBuiCoESbvzXlwrrjPnOerGVTburUEdLgtgwkVDlguFvnNRqnstfznqACbLGIiqjwBfrfzpCRovteyllNeWARCsyxcRGGMlVPQeYaJOXYlqIHxAfUXxxmwnTPMmRonEiCzWjVWjQscruXUavoloumzUntPtymEJjFZCiCpVBJiRCVlmNLoCHsYbVdryMrOleLyxnKQeRPihmcCUsFcObFOGBFHqzMdWQYPcLnssQBdChIrAjGPsiQlOaobzkhbPOrCkYEjIfAqTwdxqbYdZkDEWGfLhraaXuXEFqGxhgPuNfTaSxoDWPWXHZjKyfcAFurQvYjMDmPgwBYQtQmTiUlykfsiUaFjXxkZQDPvNiFzljHRFztosDTmqxLyLUURvVBRAfxIDedSeUUFpBnCdlbTFXlSVJhzaTzaPKAaBLDVyTAXPVQphTqTzOKbHKtSkbvhFUhiGKbuPSZrlOCOEZwLgpBRblFUrQsyBTPCmPryvpHiuGZjTEotfwJxqIaPOOPUkAQExYZiALfpcgFMgjNJyDfNVwEBSoaUtWfhLxcTbUYEwzBojoQksNfTRwZRxzbnzFFQMtSBAObSbJvOLHiOelzPBuPVuQfzVYUDYJJQYenivyFgjktfJYlzbUnxFCOgNhnjwofvhLVyhxxvtnWOyXXMlTyHmjXPxYyubduEmunwnqUPDKkKJuzsahMyOmqXNRLHBZoJlVERDiWFRhfvCtmIqEJnmTyKisDxQZZUAsUZyobxJczJFXwUqUCoTbgpRxoLutAUVwEQmVuXObqXnCxpHiExqDEXYHUeDyNqhimUZHuVvpLNeLvKGSVmCaMWSDbZxWHLuHAuPfrvcxvPwwaREugannGCKABFWoQjcLgfgVQSsvIYNhGVILSePKwdYlHOcYCYcGiMowzlEsTElBeYSxSOYjTQwLomqYUHxoYhVQUgtMZbwNAiyHJmOqrLNKYkzPAioWvFXqGKdQFDFusgAvDiVgqmqEdTUBOZEQXySwksCAjQgrOzeQVKGNNJLQDOGSLBfzrEhQKdQXIIRUCYiwOGCzMNCIRogaLFQhOqjfQsKiGDnkQocaOJfTktyxOxdMJmQffjQVWEDIbTFrycgCbfJiOtMPjdbaceGhphNRugKkYaMeYwbHlcBpeYORqzEnGwJHeADagrgsfrXncDpEpmxlqloiFgDMdEMvMWWMwwEhbokXWbrrUuoQPzXkSaHWVWVNDAHfFnMCXlzfrclKqgxHDeNQuISUpymIxxfHKDLuZsmcrnQMPGJRRmdXkTqYluKsGcuCkhfoYOSQwzUHOBNfjTFCUEHjblogpjCThafyQdtMdyrjiCYMMNLXmbxTtrFidvwzLtDaFSasDcWoTlwvlDMEHNiyaktbrgMAHPCQitrMKtdZyAodiEtUsPDHQywPQIqGXXDUHYelWccxCpPecAVEcDMDpvzguLLEUvSDTEQAQgKVvUJKYICxDCKoOdFSeoOSbInOvtlwDNcuoRSdxkWLOkqDCRyJqvnSxBySrYxqNmYVCWlBAXVKaBIvUBAbuYjjYtnybxzUYWRmFEYRSkKMrEGpqxZYvvhqBmRbiZnInqIcJmNXCCYdumKKkCpwiyLEdrSaeMIECXZciAActPAQFkmgREXuEmAmpavREizIssHxlUEdljDRgQXyMvLJUNlNrRiEwPKYsSPNwefNHYJooGVsquTuDksXhOxynfreDLikBVKtbPDosatpTSCLcxLlZkeRkgPIemTvteWiepCMywtYOJJdYfRMvEmQOrTSHVNzsPQwUPtaytJmCwzzGFtnxATtQdjtCEjqAxwHMPYtsUpWXrflChTPuqaERLxfixjBtgeIWGMVehgFrcjJKWJEdwQVRxpGRUaHqoUhcFnnvSEpdvjhcxfRkWIygfNUATgxfdLogCicRBbySmXXcxbzqTISwFiJiVsgKlUAcqBisKzDbVKvbmOkJyuWQLzKpFSJuGhiAtavSSEWJFlzGqOdixZCcFdZXXXGsbatHeetRIaFucfgEdZMZgcWAGSYXqnkodRmjndDaYFrhzAGLdsyYxiQFFOkeGfcGxXLToemYfHaSLgNkXZSecVpCOmXTITXEQDLyPsaSdVrJtZzgFZihCFtkQwFBZKiRDyvKZHXEddBCBbrbNqqdHsfRVDhERIMBGWAKQgGSIKezDbGxGAiGZrfyXTeJEQBJIobkWVsdelEYIDQNWaILymOwziefKaTXExKbMSdbiOqtZvEKwyfhFuCAtAkmHVuCfhdMOawyHlcLSzpoAiBqDtSSKwLdIGJCiNOYwEebRxqSsVQwpdmQBmPUCMqaSCozFoBSuNDPkrBlrLQRTEdFcgaVTeXzHwkfszmLBwzhMVzMXCxtAnlnKoxPIpONEsjzYAiUifxNZqzWGRjAInkMvXLWxXLWJpBAJVBWQZNBnVUyCzwLqPyNbvoCVYTXiEBBiEUBnHTqHXElYGUhxrbmLWksucavrDGCbxpbfDEIoeOXxRSOmjHfglQWwwVYyKbxBevengxzikloGVbIkUeSklSMerLJQzTSoxqxizQpXMjlqEjLFWQRaLogiQCwOFOydYpJpXrneBMRsZYXQVBiAAnFfUynIzumMTfehvgTUXqKkUOCimsCorQWfSxxqjmTAZQylBHpQoUdCOJmbWZxwbVXYiWXYgMAhUKgfitKQhFhPuJMROCvTISsRcudfXPuwvUIHmfHmdOrDYxzQpFnSZKMUnwkgDaqOTYeoMEVQxNzBTZopYtdaXQdgznvEvAmmvWfEPUOuoiHGpkyayKoQxbaHtKoidyCdHXiBJzrFgTNirshXysGUfvKLHDVidQIXkRmriUqDZuntTtFRFpVCbRFVIpBZLNNbYiMuAbTggclVNxWJSDjesHeTuPLucQzRJDLoAgtkAXhUqJaXhSBkuywjbOdLzFFHbSmtdQkFvLioQWtRVTqtHKPONAgEQRxdjRVMUioFhAUHHmaNQfdqMMfNlJclTyKTPIrxIrfyIOZEPhpOFINFycrhcKGfTEtCKphLHzMGFacuPxxVgsqfkhyobfodnZxlyweGJerQGfuFJFAmiWFLJFWsnIOeBLkmWPqHtgwLOKRoUEGLAZYlzZautjTjtkdnesJKcUtcREnXfbNpXyWxQRxZgWsgSydNevGKMpnpSaRvDRFfsPHHiGzBxTOwdjzuzQtfIwWTHMdPuMGuyWfzEnZWKbaJdMVCMyonOowIveYAqJYFVkIhdSzapofFoINhBdHVdRqNfxjHroXeUjjfVHpPpZMOQrqrTrJMhuPvrrTrzPwDCsndDTdjCLSPvLWcEAYwpMEyemaMPMhJoLgluGoBvGmmhNoWGxzNSIvvctfTgCMSmIuwnTSHYyRAcUKTiOUIZUQjwaFpnMmHnBpbOyWLnvGftExTaltsmpcRXlJLhoCKzmNwfgqhsVKJobqRmlECcHANstwVqohsSrgSCeQLgIfCtoFtbPVqANXmwimOhJpzAnEryfLWLAYqcgfeCVGLwzFoxkxRNrquqfLrgAHWkcNMmhbvDhjPOqOtHsAFAHFgLEgyPgqlaauFsEdfJpRcbHFrvWvwMEqBTYheReOwXXuwLKMusmeZxxeecFGJXxZVlHhBqZuRmrlBxnCoYifaOcxDeVqSaQzntoxVUENyoovsglzrJqkOhYxvJmxhGComEfMeUdgLZCXQPiOYtAAbStjoQFAfkFavFgUZBtMdyaJkAcewuSjidmSipItGebSpIkLkmxnWBZjvtJVISTWFfOWByqCFCkEuGzljGhziNXasIvVtrdPtuOyqyTnnZgLypGfdDYDmoasdgWiAyytCalQEAAgcymwWekMziuNzsWkEgWNXEhcuyQxAjpQLLPboCTaTexdLOJijUsXMzzFThTNzbbDMyGhQmqbHUBlFKNBHrrCPLcmkGoJOtpoeFyFaaGDcdElWWdPckOJXtyEKRmjsJMEqOUKePthumJoBwHZJibflaWZdFSFrwUYPlmDuCxtsFSEfYDsRTkLJUxOQTYSdMNarnVePUmGhMIrxPfARsdRXBlXuDiOQIfkfijaLwiCsOhvVrHTXBrAbYjDRHNIdIRDMvqiNRAdkjCsVRoINZAThRhBINfjoSvLrUQLOUCODBxtlZLmZfFuvoczMUHvcsxQfmKTXeVoVtlfXNSWZibDQOcPBJAyYwxHZhnXocddZJGPGkgobcANCaWpVXDPBKuWFOIkrwIXiIPecLcbpPSjmhIDlNPtOiHCzYBFnwUjXAqpZfpwaCsZqlDCUiJAbRgJDBDUBCLWGLEwPAbwJkLcoXjYmJDTMDwIdOJwpDNMNgAJpxkkcYdJqBejcsUWzbTaSPEHEooCCaFRHbUCryWIZTeKUzEhqjloSjFGlxOlWmeuTndOmAqHIvZAUQTliBoNOhqRREKZbEvRjaTLYEzzIqdcHSjkzddjgvuuUNkHITGpQaCdbJJIcebZRJJH" - } - }, - "ProposalBase": { - "id": "32", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "256" - } - ], - "voting_start_time": "9935-12-31T16:20:47Z", - "voting_end_time": "9936-01-03T19:39:45Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "uKIxCIZaezWMpEldIjAXerdEctvoAPYUlNigsOAALJzGEzbYsXIpyumKPrfnJwOyQzkHMcojdUSmOvrXBXZPXJNNUvDxWWVkrcVSPokLsACmHFdtRdjcPBTtzMEJGgdDwgqKqmKVyyXs", - "description": "sStOsEQSjEVkZrlpKWMTHNOQgnlvHWntzBAIVwiyQwKqkvcPPFXWjBtisiobVfhJkfRBvQAORlhJAbjKyWIsThGNFJjVKzPEQivVfhYASSfPaoAfPzVOHsGRPuKQiSLNEWLlDnccOATYiCnfhKpmMHyGshFGqIPWUbyRxGbQbCuJADpgNRyuEeLcRiOZyvEqVGEnkmkwKnNewsfNtfHcuWCfnHeHElIRCNjDlxqpuawlrYmyesAMydytBMNvXDCTfSrqeSOThjjdqpwvWqxfbEwWTSzYRMSObdCeGIdNOfjbOmcHEVzFpKgsFnynSJrMNzbXfPhWtHLFSakamMhLSAkSBskADgskMaKqFqfkHsWXJDBtyaHypuRmYgeEPmBRzlCLojZDvVgjCvHpiUlRLIlGEKEHncINHEApIrngygNbVFnYTFtoCvKufVgPANsWyVPkWHwvgZmEcIjbIlBuRPRiHYVGLvCPWyAcEGGtJIfYEONQDvvsUXxtsgomDNxSpXSAbrfjKDWXXerlBVZVgzovqAVtSmYUuSvfVlDNPBLtVNOhtRRatIHbbuDmnNyrlwFwqczvQmIkjOINfCuebfFRpTqZZDcnsaXCSuwBLKvagmutaybIJLVFZMWlXSpmqzaedLMuaDmqRLcUOxZhaHbXBAYItPGNpjtNnjaGngkLsjndiaDwvLPZAbyWlOtqWBxiNUiSRgQWFtIXKJAMjpqdHhLKfyfAQjQFqzvaFMWsRKHqbjsSrzHanAoZrHmMJDBTsNVXASTERXKAYoRyvVSVzYPQhDHpnJXhQmZQJUbXiGMJohrhsZJcMtljJvowawlexodcFYZiHTetUQWsAlHfQYmfmrKpytiqWFKBXSUKpVQMejmEoVqhuSIwVyotWCuJmCYpIWdgrwiDRmORIqcSRPFYphRmwwklRXBpHxbqgeMeLTcSgLVJTDNepRZIfeHskGJocbnGmSTsSqcYXzTnpukfeHQKHfQvDaKissBoGhAECiWMiNFLDTyUytJOPiFSDtxTrntbpoPiTKveCDNfFRiveExDaJQZstHbncBhGEfPBMIBhBsBmIWzJioZBGSHKmrLiZthZqfoTaxXFNPFIcRSlDoKaHsrQAfdSBdnpaIftCdxqLKDlhpKjNRVSNxVZpbgttfYxGrHnMBVPSvRVTtnukuKRivdjRdIwHMvzLmAHiDeFzPsWPWgWsndIMXaAWUnJDLYxFAbXvvMkWUZRNojrsiFqvmEzphHBRDMPCCBmYLbZGvMYyFHXbpMzZeQSPSqFVfppdLLSycIUKmktWTnAGOiVBuOqRYWqBmTcniXhqPACXmtRmzrcRkzJgbNdSNmLSIsxryJVUpjpAAfqnOxbUYTyJuQACCJTcTHHFbyvvsiLqPevmoBNkKldEHKLXrVlliAncOlbNOLvalekiXbsSvJBxYLbVgbfTivfOmWevzooqPhTZLmGJlIbhokJQMBeWgkeXDDMaxfasCwUdpAwwffcMEwrRiznIHBymeljoNkZZkoxnvOPLhVPZEeqaqoDvsXvDdAQKbZJamRweqnirTVKtFiuCoBcpyegHOTBBVhEMLAbrOrXadhhMNhVMiwGzfalRwySnQFiDxWjcQRJSZduDHvLCOPGYAxiogyxcqZNczfrxLwayyslpONJRxxRHXJYbXigvlUQcPeXknKSbnoPwhuQtaVffhQvvUelEaASMQukkFxFCXvAwLepcpgDDuClAiHPLppSYugTuicoSswDwbJYFROWZYDqbUErphNSmyJXMaYvUZnzYLidCFVgXUIpCxJLGndIvJWAuPJEJcNfpDcFYSjHBMGzQNEjrSxXAEWPyQSUvoaVMIFGvIAOPKlrhyJHVgRwOIAukdSRMrvdFkYXlJeADeTqtQcPAteodEaYTheYnPFCJoXshuncteYUiPIwrRstjIcBiOQKOzlusFSXLkriVvkhEfiizXTyrdvWNBnHMoqwAphGnmwsfASWnhhtuNrwkwoOYcMhlLVhFZBNRNVBFNrPEKPgPVjbkXdaJGYnSbZgJenSUaabOwmPvcUOnVLjjEOCaiyvDmxaemPniOexVZHajtPDxxtpTqWfOQMaKAdMLaXCuujVGEbztfeIoEvatLWKEqosgOSVvItYRzKOSLxxnEvnPQirGDHcrWCXnfGhLKitOHNJFQhMxjSlCxHgIMwCIADtWdUqyFWOCfgRyBBwklZTmlbPMlHOCtxzDySrgIRRKMrrXUQnWXzlxepnXZQyUKxkThKkmmakJBVzJZNONxbFcrptEyyfLxpHLrvidhoVLKnKXReOAMyBJFxlcZEpDEEISajrnobKEngxzuwOEDUgpwiqooQUAdSevWKfWuumrxoynqWDLviCljnVCdlPPRuQhUiHFFcgbqjXIpfYgOBmMcHHKGjLPaqOBfpNzUwLXxQiFcQEggXaUDsMAEkrcxhYOSgiAtgsKiQDgtRuHFAGDVnNTuLswhrgZGUvLCaIKPBZzbQAnPBDRxeCDHfuwXfshyKEdaAbeCJKjiuOVIdHKpNXUOpIuViQAIgGlkzObaMIhlMYiOwPxnsyVGbCaLksZeAYLLqZsVbeSWikgcwWYlgAJRDNjHvRJRkOKbeepfCTtumjjZgeRauuyfCJWylQSSCZtqXvgFVQZolRyzcjbVWpmrTSvxUkgnLaltFinaIdtTficackDOjPhUxftIuXYUDjZIInAiHsVfkYWbxlZydjHxUFNIcraaoTCwhOCUZibgBsewCObmGmbLnEgXfhgUUdGKlubCzSMqrXOrgyVqWrEveGlqwQTfrDdfVnPaGgGTligknjzFDywlEbmLpMWHCgMhDKhcfomVvfMhUETSzrsfSrbHUlGDIPxFUnozCMOoRjiiwEeFSRPyJWHHhiqOESbqUXCoTdeUYshOmsIAmQlbHJXaQFrSkPnkNDnHnUYEoLmlvnrgYvYGKmJjWsBZCYOOVZIlkIiKgCyhSKSPJZcrYKSPWFGrmSNOVmFSRqlnzLNzFyDpilKNJkuXqAfeUyZxWSduWWPXCrEJlyeHnZCMLoUAbHEfchEDwWsXVFKsUhkFUpzDyXSrzpaHrkAtGGSYFRCDPkUGMrnULeTzNeHJchXwOIZYWMWnMlIIKFxACovrZoNLPBHfUNuzCQHqBTGFPYgaGolTTmkCBWBPpQShAUtGwuFXXZscaVgYsKtiAemDuoWePpCnFgmeMJuBeGrbbjoFTwhSLwaXgyOtQQrztvlmfszdnnhuPjbqxaBUPCnojCxldhttNGJIgeFXjDVdNVgzyvzUfkVPwUWZFOKxRTMCgJykkvWneYKFHixfZtITtsHRmOlDQiailMfTdKRlWSLBHAnjxUubKBWshkJPkVTQfKcgJzBeqNHEGqAhNMkRvMaKQYIGfvnhGdXmZUituYAzAOhxDOaUyqpMkGuzbwWnnyXLRBMPMLeohoHsQWxCtvCTGCZPOKEIdcnoCLglBZmOclmgIRjZFJIlpRiewbmBDFTQPYscSJENLcSyWtPkalZgyvXMLsuqiNGTmiLnDdjixOLOktOwNyOEzdfumCtgJHPJCVgeBzVrKFdxMyudQTIOkBbOFGxHzBNoxMiHnStuIoUkpyLhRbSVOevlIkfsuRyLjvacjrDeJCpckSYWJpiqHCOUmqdmuVfuYtjnjEOYmTnWXKkFUPooIAOyoWYCTkKYJcwtRTXuxyUvwhMqIANzEHJSqFyuHedpbptmWgENQEyhYKJDDEcBGVVnFYbnxjgcKDjxRrOXeIcKXImsimSInMKvcjtMMVUzfKvDpHaBKiouvSokHzhVGjUZaijAnLoYvFHkVwXUPWGFfdzBjwtSugLCfmxwPfsJQQNfnvQVDuHwtOEPdvaEMuOhBPdxkSucMKShUGgHBJkCXEIRVoGsyrvUbECnoEFSxWyYGeMkqZtIVqNkcffOBpbcCYCQQolUAdRBFzesbRIvyTVUZCLzJQGEhqZMZBNcAbfXQbKbXwIaYEtKXAcvEuZxIEApCIeaqRHCcrcSsAWkzRiUvSJloOLZLfrYMtqCeykyXNXHlyavcusJyovjxiJLqlRNLRmFzUziQNaHrygRiKyVmigsiNlKNjawXmTFbDahwTNYhIPWQxDznAoVnTbhDdXjQzkyPMhtfnVGUgCPutMbrLClwXtZRNYaOKItNVeVGAfNyiluJzTKgsvvMQyfsZxWStrlSXxjVwRQmBFVzEFxSbeTmyuegMYDeVmQcswRPBcTEUlpcdWOomnuoojYJjGtlQxaSsVxXqJmOWKILrIjxUWDYAvbGmcDKBpnQHCJNEyBIYixYdRJIvZuLKSVTNuTdkwVchKwhvzlXumtMMIpCMBvRQBgGFBcSOFbVQCTXzPPLrIENjNjJKqcJtVifAFIiiEdEwdpSRHdXHznvPnFsJUgnrwPTmmQVMFXsjMIMxOoOsGZEkvSozpwjjyyBjXqKUONBllhtFRrchxIInOyekemBYEgnZZRpwylWxcKVCquqaOneqRJCJMofFrcoDvGJrOczZmqnfLuEedVQDWnedLGxaAVlqVVIqhqyPYyKWRHlFfQbXonpsosWboiCtKYyvOLjTfQNOgODYxuHPEwwqDcJbhrEHVEVTxzkOjjvqnDWJwxrQDOQrfwLxJJBlEfoWtrUDBDwMnZyVjZxjbejxjCLSXBzcDHKUJyFhJhaZfatZaNOCQbNsifLEsnkbvOkaNItVKhgwfjDbfthFalXfsRpjCPxJkwjxVGTIUGsBVasWzDBxxMvjBkYMwybIfFxISxVxGUttNUIqlETmOfjhPPnbBmnFeOBRFuGyLmwdmwmFufFRuYkAHghWVtapXFZXSftbTVQmnTnftDrwHgeNasmIhAzjFeELgmNMPXnyOjvtidrWqjrVkXCudWvVKKQmjDLdPcujHDpRCOOeSzLOqrAwXMBpUzqCSYPfMqNUxkPLIQGNijFvYIAdeIhmklKampfmxTMJqlR" - } - }, - "ProposalBase": { - "id": "33", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T16:20:47Z", - "deposit_end_time": "9936-01-01T04:39:05Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "240" - } - ], - "voting_start_time": "9935-12-31T21:25:29Z", - "voting_end_time": "9936-01-04T00:44:27Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "ePBtUGbretHtAJKGwKyIIYsDsliWnyjRKoyCByxEbEfJUACjRyoriStIcsHCGGxbHRdHcgpRAhWIAQVuOJFXgfusTuWkzAcvxeEdXAlyqGjKIKfqiGGwmumzrOvkblnPdxCKjyzulpJY", - "description": "VLByaWYvLPoFvpoARWSIYeZRrdzUajAWCsUVTuLJKnUxjXXfcdqfldQSSJribsKzxpppYxFDufjzrwTCyaBhMSeLeGaLyUqPgijNmtnGMyyouhJCEyNOQSIblZDzrMfJJfjIpqUsmvoloBuSnbuYJuDzyFVtmMjsqaOzhZvLUfCtlgisvMFVrCPPEqEZXXFemtKVZimbVbdWJsfFqCOUcPVdypaOhqdYhdXVJsEdYyyuBhBOPkTPinkQaQLYUnxPKqrEAKmUSxTLMmrmZzjbVYDRQTotIvGiMmNvwGxjqcTLCNZLWYOtUoNptxxJiFpiqKpMfRocDfBJOSwwLbFAFjjhTCsFwKnhNhOeeLiKEnnZydlYkSDyQaihGkpOiWxtXmqOODouTlhuAfKoyOfsmSMxseUWrgxOwHeaWSSOkSHsaNSQQUIUpDgMokeIhwMYvtMUHahGfbbtCUzewikdPLYRONWqroPGntSRxcOgDduMyzbchjTUausdNRLpShDZoopIkVVJKrYBgqcTuZZxDCXNBNDqThQoVzwGzNvzFpvjibwXYfXiRIWXMJoTgPOUvuOsFJwHdecOJAGOwhMzflHCEkAmjQLnEQvtaQDxFZCyhvGEaFKnJGYjSSASxFyHuPiqOWvEnqEJGisxJLZaKiTrJLsMwWrMwiMMMdrpHcVpMoATixEetlfBtatUZHgAEkjXhVeEPJyUPIDqSdtbvLFJgABtQWKRdxUPIaMcmOTyRvghGryFgfHSjEgrvVCMwsmkLfdrguiejITudfmiglfMuFCywjnWotcNQRujJKiWIOXGzvgeOnBXHPjWPBUFAjiDaltNQDKwERrHTtwaLGJFbbZNvonsibOAcMNqsYJTJAHDqEdtnePAwJAFmcMkBLHISmntNLwcJLkkAGUZJLYEkVsXIhtjjTXiTqFLbhumyFRDxzZIyjgnXMIkwiIsdPHUBJAsAsNJTMPNZFsYJSwHjkkqLSCtLrEHlBGrjJWhKYtvzvaaGJzFOQqTyUXJCQtAMSnLeINpgSslgcJjYvoMRoJozDSyAdLMcNUOFhizpMumLTuqkTnXCXstSEznUSvkQyhHedYXenIyZtcrfpOtbNWDvoUFaAmhwRIfwBsQuSAcXoaSQQjTbKNScCAIUMfWZvJByuXTLndhUocIEleutLHmsaELtaMgEMsxDJVVpBTHYKGXhnSXUvQbgBlsDLjBMSHZlguWLfhCVcriadrbhdHYgVniTubbzCrDRPeSjwiJsYdxBHxrEUDlnYwnPcerDILMDTwkIedOQQkVbexxXocRGoMSDavrghAalujBEBfXgdOogvzzfEsonfGHWMuKWtAvcLOFCtmpoqlIcajpHtpFKHiInkDLlcpnIvnWVITccWDgSySfsmQbFeWDPOroJlnOiSuwwmHEgElozJdBDeOwZKsbVMyMInfXADgAVOwqoKssvHrRQyKuKWDmVIWXFUDDifLzMAQQCMuQyTyTeADmHgVQJyZkmxrddxqqiEwSdknoXLlOIIRjChBIuKzZLnMplFlaOTyOsyvQdCCNAuAAJYgGbsAwDQgAIFwYIaYeUpDRDSlsESfFoEyiWxhKibveIQOTyYGkIVKtywOGTCKxwkobckLIxNUhbPWNIaEqQVnoeCvNHhyRsqSenUYKBvERDHbNSKiBUBLRrAvXErIBNkWEggRRLorCjXNnKkPiiQbzUgeWVAEgaqbavizSLgfCqchFPgVReKogXHoDBzKDmSQvdILNMXUozuCanrexxjZuilZSKDjtEbMUHPwGxzcIsrgoaAZzDkUsCnJuMmMPpmdVwmixswAvhxqzubrHwPfVGYMPqKgzQmvUwanuncUsWTUrsCfLcIohDZHPOPgMdKTSWPEZrXLYQubPskoeXvvkbpYtPUxZIXYxrYKeITIfZuDnFfFsfeSIKFXXiUMdksvmWjDyKvehKZOZcprxUbjsCQEkShYhhZeKbqoIRsvogZvlXRYGhyRBRjqfCBUOTJbmFVnkLxfOuiAKFlpTixvDreGzOlthSApQxYhpgjNsxWiNYECtuXOwoXrlSsymAcQcEbdfHNqdKIkIOFskpuFMTnbUHalFufNQBmswqPLdWQwgvcTdSgMjSDeMesubDpbMMcudeKXkRQbPPkjNBlrwSKvNJpANWxgDzYpeHtideEotpOtlrfbUpshmoaLtaNwNWSvqAoqLXhSqAcxIgAhpCjjQlcuABxnVyaCZNrayQMVjEYEiWReKDXNcORojefCtJjGqahGEexIRdfeRIQbBgCfybHpTnjHMOEaFvNPFkZLfWYmRmlUcySPrizfgpSMrcQRHtrBRYVgXrgVYjSwUSAXepnwSCZPFYSWLRtQaaYBFZHkKJGUAJirzOCUzUZkRROocTXDXlGJMLIUAYjLVOnlucUFWYoWckAdMcIdUtvEWGODdFgLsxKWqbcGWKktUAVkBftKSUbfQRykxTLVxPPTArZisBUOzDucugoKIKFXANOlYprDnUzPNVdpBJcDXbuKcKpDqTKwRdOdOjHmRIondwzUMvtiQbCyOfWApfVCPKSHPuIGOKUAbgjYzCKCIESVVkUGyLphBRauoPsguuavrohsllZzBGtXGKeoVESkxAFQAVgnqaIBpLbKYhIJiqVwufpoFDtzMTTEAyPuWRqVoRQdjsauEBKFFNErseHZFjXrxogJIfSbZsQrfxUaNXGCHvyDGeMIAifNIkGjFDhGcINvFNPENLKcXKCewWVUnqiEqahSqOrVAucrtjJYVrQgTuEGpmuTwHLZzOGWrNmRfHrXJHHafxYakuKKudVieCNxCrHiTzMndzwKdmvjNcRakenHORzTNYCHZxbmeOJvWkiapZawGRgABeMgViIjvalkTvguwQjhWTRYifqxtpBwFqVjcnuwIqgXunzABfBffvMCQwAzLprUEbUMkTsETADuRnRPuxVhWpUpIZaNhayEOfElqbeuTnKIWLanJQKWMKmMAYzarlXnuwWShnKGLFWXYjAuDyDleojyJPhgjWFOGyXExDaYVBLTAazMODnaWvlinWKREPjYhqIBIObhFIufCDQWWCRthrVrYiYVUwodkZsCtcREGcPuwYBeXzGhBTbIXVCXPEpPCFsZaGGTzJNaJvavgeZfGWXqQxyAcGfKNPnrToqCgHlKMgewrAJFVWMKLtxfrZvVJUAkjMDwhJCdKDcEzzdneTStjqxMSpLfdqIxDqMiJJBGolsqlCjnArAPUSJmLBEfcRuLTbHjkDXhGcRWBVYdaxdxMJsEIsXwBuodxqAWnYZnNWbtJJXgZVmyIZAZVQDxTQWDbZeqJNVrqmCtNJIhiZngexvgywXzNhWFJaKMxHrLWqtFfWGMhQSYfsBvTWnuLwYMrYnOSfjLzHipqEWZQjWYfEIRGVIEaQeZBJAJuxHxYszLxonqjOKGWHuyGGYMwrSVCrRiNBqnVlzASWPapuobunoXChUeYApkQnYqiEkUxYKBYAoCTlKBjhqAuXAmKlDneHgSIMvqNiENYoDpVQdRrswPgoKBbQpOqBioMcXFabFnToWQwSAgmdWvJuERPGoYTUFqFTwQTsrnvhxLmgSKAmjtyHmBhPBfthyyplrcPnyzakPoKvdKqVaYPtturBzYlfGxPZbGMcKORVtLRGQRxCyltnSkhuwnVoKnkXUAGAOwvwBJYYRkndbrgvzAsgjqwoGzuNGJMzSCzDjySQdCHbiPbtJKMdbilTjPSiYoMfOkqJibETwMTbZUkWWSEtdLhbLlRIrneszAiewlpVfGUHtTWEYepesRbeNmAhcUFcBIWuPJCNTyWRSndjQasTQgeowbySVDNLSYNCgBmspsIrcbXLXggOxqpkOOBdZrQcFgfTxASCLQVZgHWklWzRsstxsJpSQgUNOKBqWLyEdeFKvhreHPoBDvuZCTsRTGmyWOPvOIniwgivJFyehAljbpJXmalpMGlfSZtrDvEtcSqjkVbdzjQqMUVuyzWhoNoBKFSjlWulzKwBnyqSglwMLWtYQvqaHPUlytdLrOPWdujqXooGUcyIxtcAuUeUyfnESJcNFqgTsixMqsdbBIZrQkWxyNGBbTdyjFFOAJOvsmsGYZaAzFJkxaakXzZyrdjoBohsptqHaGfSSIEqAFXSaLPaFsFHlmylUzncuhdlNUaZekzdopHJbYptztTuIULGYTtJcqzSYmngptDTwuEATbOrFvWJcBNPEUdiskRABAbdVsZnHDGwMpGbQxAFSuRyljroAAeKWXzcnpYawTRfkHdJEndZBkGZNBmTGcOYpNoNktPqfFdHbhYJgXVsyBcbbeeSuCjDmyWznIemoLmlsZDqwKhMIlMJOkRqtPxNfIDuOnfjmDiJHNWNtexXdOGXeYEHueUAgtjWKlUWtsyfdqJIKQqDQKGKelvkMJhOhekaksLnmyIRAZSjbMUDZHyQeYaycoeMeTMmNigGuBNdiQSPwrIPgTJFYVlLuhvHPzuzAlZozHBqTBwYJnDIOfczpvwnPtqIlVhCRPpCmLRxItlCsNVZpbYJAYGmBBUUBfOZNkkzpptlSbkHqSZzcGqKOKCRXcNHBMEAuxSRIncKebghpKfHQEKrtklRrSFmtTSCxFFUVVNLZdysJrbrSDwadayxjkheSovNdaILsRJhhXWgJAPebpNmsueBDdfPmSUxYXWrSlmQIlyXwZAkdScPFaeVwzdXZJlHAVWkryMFxvrtGZRSgKtgYUKCMPIKucGKyklpYQNXrsSGCbDtmrmYargXgHcANTerSNXUWhAEkhcVSsOZjSzTmwnEotawmcuhTIPjbQmPuTMaEiVaYCFaYsibMDZSJBoUQUKePxipTtrHMcdBBFCTzZjpYshOOWWVJgEBpuGzzdrDoXOxchbHNwPHdCfOjRGZnWgepYyJdTFhNusupWydJdsxUwxciAdpqJofrwswPAmHzWBkuxcJtqTYKdQZWOXeIbfyhZcwHSN", - "changes": [ - { - "subspace": "staking", - "key": "MaxValidators", - "value": "206" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"11\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"18\"" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"167\"" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.700000000000000000\"" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"8\"" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "distribution", - "key": "communitytax", - "value": "\"0.030000000000000000\"" - }, - { - "subspace": "mint", - "key": "GoalBonded", - "value": "\"0.670000000000000000\"" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"441969000000000\"" - } - ] - } - }, - "ProposalBase": { - "id": "34", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24914473521" - }, - "submit_time": "9935-12-31T19:49:14Z", - "deposit_end_time": "9936-01-01T08:07:32Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "346" - } - ], - "voting_start_time": "9935-12-31T21:25:29Z", - "voting_end_time": "9936-01-04T00:44:27Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "XQXTYSCRDtfMZkwkDXoogrsCLMVXYioEWGhAVtdwDjBIedXunPCYzFDGEZjVojUrdsLrdEfxAKaHHxGEZHiLRbrJyqtsIcuBkVWkXBBTCRnxfxQXvGJCzOkXxsjVxdPcRcvMzRnPaxgN", - "description": "sDQTatnsqifTpuokqGiPbEGCzVJGbdpswSfbWlHEobbpQkQpLGoLpqczKXaVbEEsqmymspwjYanOIEabuLkUuHNnAQqyxmdwigbJTUbtoXoKapZHGJdIVDoZkhsVyiZYzPIYtlFdHraBprWQnAjsmFqVvkEytXfZVcWfONiMvVeWIZmBRPDNsAZvMCEqBRBLTUXeiUZFwUzuZdTNjzZvNYfAEuydpEZdJdSvABSMaCoYSuAFbVLJIaTLsHpjMjSXzZlOYYZegIAZicqlpWkNJYEkvWwtuKggxUluzsbVqKPLmMvfEUXkAmuEXZkESFQjrQtRyEckpmqNlqzWnLYmpScEOkbhwJDTiTZkIhlTWZaibxdWagXIAkUXzuPSrqqDnEUVCKBxPoIOHSwwBYwmkWjbBxGNhSgRgdPQBWQtuXLMpzRVOrAsLaqhCiwPTrQgtyfSIcICWmWKhiONVGZwvzePSpcOzopZENesryUtuiYiyBqdTcLvhUxiqWDcBnNesZcOPOnnnRCfFyBiOqoSdBOSJhvTbELOGsXBZOTUniXzNZHTrChWjWchYXdcZGjTJdeyyzXXPZyVXLjDUvqMvWwTCbLKDiRZJFCIXTgcnsKpEvelInwebntobjDItkJjKvSwZiDqZkeEexowyKEUESmkAFRkJDFbrbHZnkrSYaRPNMEkjGLQSaEZEseJLFVbQjIIaMTpBuGZXjJIwyMiDsltAuQgLAiwjWDrjdJIxHdrhJBWIxbTymWvTIegELKCsUxDqPVFbSkfHjoAHOGcgRdSbztTMlbRKfZQjopfqhfmDBasyFCXbRpxuhcpYbAykmNMzLsUAGZwiYGvruAXxfhgesZafPkHeONQXlcHOBMzIAslyHZwQTFXVnnwNADoNyjeWAnjEWJMbufaElbhUFjpqgsumBCXaAoRZisKHxNGXzUOPZsqMoBmtvGjSNwWbqsbjwvzeQAqpRIrDVBCKoxHFNUuBFLMxVWuHBcIdpeoeSpKyjTZALqDBHRcBzIPqVENiwZOaHIOJNzNykwPYHNfkIQZAyPxidBgZGohUMWlJYLJxdVKqshCdwFQVaHBPQdRLprIKUaZHYcHPKWGvZCYMixnzpqrlCQKoIzkflgVavwtCQfXHpIlyoTsOlClTEDgtfWXATnoLRgCFuizybKHgguECYFLclfIbDwFXVuLcXFfVRzLTFNYBVeXswcZddeAAXLTErNCBRWCSmFrjBHMvERwWBnDdIUADiaUSFcPLiwZVeozSgvUvWnvnwdpzGxiIFHiYtrBBHIahPBNQiEDnsjUyhxtofCjWTssJiWCGJguxZPBMAFREGSThzxNdbYzRnQQPpDKChxYmknoHWRhUUtqKzBpiFtNRmAwuAnxLJMSluMJsyWqVKPmDiBKczjTfwoCIfdAahlFIoIlkGQXuiZqxDrkqAqwFBSOfOzkjBOSZwzBHYdFIMpRjIgFdnGYEwMjljMTfqyDiSFTJpEsbPIaLsaUVxyBaxfdzKxAvFGUizirWjeMfqLdpIPmRcuFJzqzRPwFAaIKAdiKfDcLnWcUeKfoQelaTnqzdWCHaBSTUVeJctFxaOnfbvIBSSqRAeiARUFjFnSMVDsLdoliRBOsdUKqCBynsZzUxjhTdGFYDajuZQmwRTmhZrdDQALRlQDiSlGwyPYGQYJyzaexMahRhPROCKvyJJPxxJGuvAbfDkuEhIrjHqBRmRPqqjvLCzaWXOUpoIQwOVZLktOVNNndWjIAQutVvPFtfeEAbtMObIUmEfiXoQqEDuzfePRZYUoibTfqrILTQkQnbadGYHMymstpUQBlgGuVsUZNLktBavoXaQdwEiRcNksmDcMLWtKJUyWhpnlLyCRbnqQUgXETmFXeQPYDVkVXSqWJuWFcAsIAWhtXMqdiciPIKHWXEeJFNAWGAnbGtPTkHfooXAhGnQeHnbWWrrCFKDCHCdRMHBLTcSbmEmEgduXePuwfUEhpLOoGKnszJpWtkSRKJjmnYMxmWjCntYPyYGmDFetGytNWPFiBarLFMpdlRcKusfMxogojarZdypgsoNVRECqGogAVcMbgEBFXrWJciaRBtvKgtoSRMkdCjzgiJVESELjPQneAdWNscSFKewJiOBWLHvXwUEWKMpFEhgPwyWAeEhuRNdnzUtmzeIZbSkgOjslqCeOYjlyBBkPSXwNThaMqFUzoMpYYBTyZXBMKCtHSpoyeVpZHZJFKpFsxNQFZWPMWcwaeldhqLuwZxOxHavISepvAEnTExRRVtBHwXcTRNUDZNeSGcxcIQdLfRPnOvsZvznjyLfyNqvhPOAPVPrSULFEBigZtVzbYcYvnZzKhPHVvlEFiORZPbYkYtsCIZUsHVoLyCRuIKALMvFoaoKLGmsMwWRQgrnafKxpzDhEfkUHuYSlYLhHUvsMAsLGPVrhZueQwKFvqjPjgUnZpuiAvshzdpUOdTsrqwEDAmlejqREnFVEDMrFvxFXcQSKsGeNDecMUocZbdetXnDGqDGfdfdpbdqmWXySNMdhxqSslAnjjAfACEflIteIzsaDogTaAOJuUiiJTcHKEmHSvdMHAHufOQsSccTpnXnNcqsXDflbNwVRFXrtyXNKTrkkrHsjBQZnTxSAiQVPsaTuJxPlegYdMTefKQFSwKJRSKPwRvsPMGSadTamPXsRsJzuDkvjxydimMZniWLiwTJdNMSfNhAPTgYLHkLBgRQYZwkjgWzQAxGuijsvrPBQBdoXhedUnxnFkZgubzMjWbQBiTUYqMTCjcGeZprFIxetRzuogIozzZqgntXmrYRFNrZhkvFIVQHduvDAzgnRNUrBPIDTOxRrUaWEHeDxoSpxHiRvhsxRIfBzyMsetHPkrAIIbgOMJDIOrZvJhpzKjINuNJSkhFmZuFLdeJUDoYcuPKeHAZjpZmDCZUbsZROcYsqLgORUhkJtZFJnkBsrNyYGiabOaqFFgaUKBQVEClzDZNWXHFKSLFUCxyPWKnbSGXzNnOJuDHDohvzIBkVwuWkVyLGDCidbrkjtkKMpJSmcrjWPYnfTkBtnhjaOrZvjevUrqYsMqqdJmsbPAnEJwHTEbDvdPPAknYaqEYmxHEjRKdEOWuWtiRNLjyGwtHnimIRwcKIIOBzzwdWJLJvcqZXxFBTzjDjqRZDviIciNJTrHEjolDNGtnLjGpAgBDGoLxuEtDGYCeNWcCBPFlxqznMrLIlWviaPGCWvelMgeATWVUfwYPiBUaTKkketQcyVfOUZiRmDqynhWttLEBmLYtDRhdUaNbitMsJsTKEOuEqqyJgVvLgoUOmXIacuEXbHIrjCGJyUmByUVzykTgiypZiXFalWUjcMGlnrwUaKQWVGEQHnjTiOiPEyRkalwOVkxCHCBSmvSAAjSPkZoBIsdtUkNryZbRWrjGaaeomPXeXNIJTKmNxRkGoewOZhIrdUVFKqKGYtcUPmBcrJkqeqARIQAiwAGILShggvffQWdIGlTZqwYyJRBJssAPyNhjeYQHrinNeKmFZdHMxTFpZbOgpcoPZSMGucTSIaKkmYzTUEcQlsEIpDppyFhDzwZPvQzfZAgpqHfajicwoIwkGKZjtDechxycOYsYgVsoQMPtsmXoPQAwgclOWKVcdVmihQdvinYRwhJpwUYblxXzVBijBUJYusZvNmtDODMdhaELqgsDZBArEkDubRClwXimsEWoqbaahSJffvciSuUQtTfkuIcZxRbVkIEPfteNFGTYZHxJpYWGrpdnvUeAItgkRtZHuDjgtgMvWXSuIsruNBvyBfkzHUYjBwDgAOdeLabmwdOUTuizCDZDfsQxwAWhedUpTNOZwUpgquOLwEwbGVmhgkJuqyfkLANBTTzloeoWNyFGYyOcMqLEuIWWVxWrNPdEJNKIHYLMSOnXgiaWsbbDBTdVQLOAlOpsoDpJyWAvdszgcyjeHvDPKndpkZZSVOkDewOqSgjwedyfpiqZqMfBCSUlpbNKkkKzhoNkReXXntYdkuXutVJlSWRmExHlMqFINpjlhpyRNzeCwYPpBQhaxHXARXbCTVDnMsDBvbtudBrlhnqtmPSEJICHyPLhNNEFvCPvSUSruVEZUCepnxvDoPVXxLwzPmbwJLSQLUnhKHFaAaELzeoXiJjDqzRbzEYTnlBFIuuwEKzdemTVblpLufMFdclWqbctRpOupZssZhXAoGBpNoZqVKuzdtqQjkyyuuPsZdufhZrhQAycEAIxwnOOVFFVBpVkmhTrnRNknEbSydBNJpdTWeJBZGtYXiLbVcfqpHQBmAoRwLyhCCBrPlTcFEYkfFbcTRfqWckTECgfIskhOxzkJBucUbCbVbzEzaKSertnNyFhrEAXHHsMGeaCQayDGpssHcIbQaBKusUTPTvPBZZuLgbIBTBUUVVrbwzFNtooViWdsJrvtsliFxkjuweHRcxEibYVfVlWwjbmCJotIOPBYnPZfVbiTGXXqevkpnBJZycERCioxoyERjJeYMNkvhwzuwPdPGxWgwsoifpKWyfzXNeAtRDmRznpKGoJVWazcNlRXvUZDuUNRIisBrNnRFthvfAugZWsiDNMDPiFXpDDLCHsjwIcbVRXblBNzcuUTyKKkUfvFoIGZKpVuQngnXceipFLdBfsdRZSvJHlTeLvBfikEXJotNerILJSeWObduoCBQAwVCinlUNxtFszyqDkjdpYauFoNzKxMocSYZvBseRxfSFLJEWpHmIKFyfwstVXISOshvWGTOMoBloqEFswifpabBWqaIEoeOLsOokYUKAzJNlotivDWtxByrfpMXmzqBSUJYtiUYHTZdYWWiouYMTgeRTrFzjHiTmbMJfITrPiqRLddLYGQwGejFWaMeobDBOLIdRQpaCFBFeoePaWUOABEJRaGitqHrjFvIEWxbCRNkZVtMqRJoWXpfhoaSJKgjQZOyFDMGyXVsWuPQfKeaJizLLvhtuZNjtIZzXCJxvTVSBdJpnviTMroVo" - } - }, - "ProposalBase": { - "id": "35", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24914473521" - }, - "submit_time": "9935-12-31T19:49:14Z", - "deposit_end_time": "9936-01-01T08:07:32Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "437" - } - ], - "voting_start_time": "9935-12-31T21:25:29Z", - "voting_end_time": "9936-01-04T00:44:27Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "ZDsjpqnxNKCrfqAymXjETfBAGoDYhOOQDhCFssWcZyKLIcYEeVKstiLbVaSOGepRWVmDagAUkLTVjMtdrnOuYlKDzhSWvxAicrSrggeBeseROMShKcqxRLqgzfwBJjaMZwttFVSNocCE", - "description": "eLbFYrHqyOrXjWlUNantJSKBvKOYOvLlZmLsQeRYjZReCfffWWGVUhMyNuNRyhHYzaTVhxcYiVVGSeMoYiMhgkxnVjXRfTMnBtPCLYhfaxDYNfIUytiHdOVPZxESTjmhpJZyhBmghotbxabkYhPuXzAWNykukgLFewoBopBOUwPOjGWtUxaJGSpUNfmcSPNMhZVWrLfHpPwpxJiwBweSBNWivqYlxiYYwXipZZHZmDdDKwUojVMRWlSRvMelDsxPcQEeQTlEauWXCtNxijUBGHBjDacJZcHLOCShESnytSBQXeEDNzJusLauBPneGnCZggjXzAGIqZXizEGkixDucMaiBmHhiequjweayHuBKNmnXlWDDUSNSldmdXwBRFBcOLxFQrYOJEwRHlGYvZYJwoIfgdRiUQbgxRQuAoCZYLwiAffuVXcPxNjznAwFbTIylzNFUCQWOBnPLIkblsbgXKilZRfnzDWbIkKkNHGbqGnlnhNxzNoiKCEgNgJqxTqkOmIjwnxFCGnDqPPYfTrmfCTzkdPwjAQEdrhpjSwQGqkLjbkjjRyjcCTWmnCvJkuxMcDDgHxhztRzaqkqqabvJJLbDrtPuyMWpwjhocInYKEgnsXFFOexJfDFoOissejUHBjWbdEWBSEKiaoKShRJKiKMmYfkgxasGmvgFwUevUKZHLhtAupmExbrIwLtjFrFIAMPnsCqSYvYOLBaUcMssRygDExEwPNONHqSTtwZILmvDGBOEwDpfFWbKeseHDoNFFDvmtgAVTJaJZGfvuUKxHIJwzsuBRdIRKVQsvvfxaAjrDNSwevJNnDCVIEJdDGrkuoQTiDGODVBZqTFeLKQCYjGxQdZlAxiagOwggRGOWACeoYEkDgoFkJhqJinDSDBrxGcnkzqPCLHUcFZffRaAngaadkjNROHqcGsuqGVAOxJmOFsQQDNfenMEAFJiUKIfBSEliBWzifSLyAJfqJStTXPtNyTGCGojokqLWtmKBaYlKjWiwjJMywcHZWKqcQeNFUivftMVSELNpSoQhlFuWBEMwXNNskiwCBSTVYQNNtlbsuWGQHOidlDOzUDIGaqOUqNxhBsrBbNjZzABeFhCMvAnbZARNkbqwlqDXhjuJUWGLqiNRIpMJJdKUFgnksyGFUiYqcSCzYkYLISOiCqqLNufOCTQsSunWsjQGSpdUZPfcpgrpUlrYtfEnkSaBsMqmOGirYmoJljEtTdiMmYvbFLUFbeNTGaFNZzMUmthfFEqAIDQpouuIisuCuSIbKgsjhEfQWmbKcaYWneymoXXWNOVoVDqBofryoWMoIRximhmUcsatbxuniSZCIFQvLbOCZPOtbMkTBfNVKbGFvwuVvDPYyPpgApTaNZnqTFcmwBMCaxThSsRencqrMhqfSLxvmfKFWGIlXgpQmBzzlWlYdZHfBwiUFJNphutLiugpyQDLMxZVXPPKUebXcjpFAjPEMoJwcUaMjwAQjulytWdQEzmYdTmMjDnkZWodxIAetMxdLGTeFzPSJCERsOgyKBEqrmzSuIjXhGRDOYUdRDrEAHetytVGCElIrEOcOFGdPOKbGbaEKPxqsjQRcqHILkjUMxLXKLVCJkTbPRREpwcCKLadqXEyBtPmDTIhUYXAEoQPCfBiuhWcgiujEvUAcULHFJcHAcOsJNrVEXOmXHXoufAKJcOjyzuKFlWcCueUOqVnsywJgnULdGhxmqMaCFhDDsGwnqOmIdBMxfGdVEGkIFISlhlyVdDgjhZMMfLCTIbtzIcrlxInUwGUaazyqFTdbdQJSNdkfLxFcVJlPmeWfxHTZiesGgLNSTBYtkHcLvUceuZraHLmGueIvqAMSnPWAvGJZkXsDnZNPYnFCVMUwwYfYmBGBHbQZVbstXevnJjVSYaGFjUvDuFVczWPsNfjffsBYclieZiHIxrFIANSEWVxxBRzqBUtnrqeaKtBbGcCchFgLttiJFxzSxQMexzSEoSQmwCjArERkkRaIxKLaavqKwxCiIAZoEdyxipnCnJCjhDmxpecluEIZnuSGsRFYiolUHIclRcBUCFGcczLUeCVhdlDvjBKPllUNEAmKJVQMZJxRQxEbwrbMaUiBMaqvGzSQoiFQulGASZWTsOoOjKvRcmXcGSmmnkLvXNHTsYjxumuKLdHVfIweZMTBFrpLLIZFIKvsXEJstCFmOgDazirKtNvyubMBTDlJgTzBkdWYGZdcZrYuCiTlarimcbVWKZWoQgDBFEMNMbYqaQbqjhnPGnNfsJOKIwjsBVCFHNZotYeLeyulOtvVyvaEzcIOvrJzycjjALVabYMgfKnpyFAiMppOTRSQWeZkyYuHoCVdiUDWNooiiQaeutBvCUYKmdncFJcseUXqZqVnakZgqfuBcKwwlfkKArtXEvWJctWFQnDjHCAurzZIfTBETyAgCLiDayadQrZClFpntyQIVVsqWiAsHAcBYjywtQRcYVAWZRQYFyVWhQDJEvAkKlKhSFZCArlfyWuqUzKmHrmlyddnSavEbAOoqQznSbeyCtHEwWHbfORTVDaoyDnuXnUsFsvqTEDmRDOBcEXEiLBtVKWtsQdvnoLvwNElhZfspKvdVIKzIVkkwzoutaAbhNUtKtKBomjCoMWkRmKplIzsYIPEbKeqGttLuntHyfxnOlQLWJEGiDCZdbOMmibZxSApeiizGMBMvICFoWWhSNNjGqtYXvOmtdqhArZRYOOgPwrbLhTqoFlOmAjpEhCdJxlyLoPuCWchgHGyfzJCCgFXTQKvWvYsygjOJhARTWrEZtPEhxBpRrhLYpurIcAdJnrIVwENmcDwRkOQbivMmplBbhFzdqCkTHubbtpxzYwKEfFaLvtyRXvtGXxsIJbeFqUDOWeVDLntBhkrUDpnyAascvlOzAYFIlTtfsHCrOMfHbPVqJYxJRqHECLtoqtikBsnEwQfDedNOwQkoMnJYtBHWldtOdJnyigvQWaDjoDINVGpHzRrwPgozmvBOvxZgjmSswReTcHcglmQuYutnuOwwYdKQWmyVPmlEFIMWkrimdDTCLnUmbohdeyxihgiOzYponzdgqyKNVeXLjxiLPpYhWrJUogWRNDTeElXqgZAsOhgrLUMurezkqxlTZTUvFFZzxcEAKaxGrgyxfpGokqNGcwAjmMutlQCAsrVCNZqpmKyoPikSrUsFVSWBCbIsaSMMVpIKFYsUrpqSIrsoeJdVUPCDFQCGGrbWRCjwhnrrenQGbzdfLVXtJCSaeYmdrwWcuNEdlybdaIYQFybSRDcyVFTwseWHIWFfjRmPlGHIgkqTOcKnantiIWjgnmAfDADSxRbkJHMMPtYuYsnBJhLYotIBanHCoNdxXuyFgTyOQAniduQMQIAhNPhZyWtDvSmNwVkBECigfbpWuGDNMGYmwnvovimhDjAsArhRoNaAplQEPXgHtYpTfjzWVJZszKopQIlcXsZAsvQwVCLubJmJxYHFnPqwLoqdNBkhUFLqHXKtcJArWsgzKkuUuaUpVmBAGixYyslwOWlWOizrFdHOajhxFIOvYgLUosOiakXXEXsEYhgOzJmyaTwaHuJgULNVgYaeCKJfQMmeDVxXGLmAyfgudLSHzNTzoTWxwkqrJoLwMqmNESeKbIrKsivSOkzhwBaiIgDGjXuNeTmveSiDojwzltjKwqqFcfidApMMSKByGHBHAQHfLeVdSJZbSlSHpoivHWHPaewbnPVvTvJRUetGYsIkFKlPqicxRVOdoNdAVTvhufKQjZMdtNxAoDySakUcnLKNDDOMwGiFXRdDrtRqTmbtUeeivaTlVREpcDIsrgoAdaRIbrJSgvsXwABqjCCiPjXyLkMrHjRzXGJpDuvBRyexKMgVGgzgWesuvbceBiaAdRBMKlmKfyjezTpijTLAUApFWfQluLqHyMRuQursrgRsnqzxWbnsVYEzrvyPuRigzVryKkWsISxpYpBuymzGPdcPqiRafTvHpIOYqWMCivIxTGMWQqeFKQJKAjiFAyXbqAiuXBHLXnZKjAhlAiiNgEJRltamOYXWWGjdQhHdlYknMxfWZuEvijahOlgidTYJGdBTQaPmLdhNStuMyKFRcmyPJuzbESaKmPwLDiwFMxzmIeQxQAmhgsrIPiwGwbRIsHqKGKnRXCvwjbEsgeidobAccocuiLgvDeTIhFCikoDFXJeuKcBwSAXGBEMiMgYgOPKrHtoNaIoaxgVuNFktRnaoGtFelWXKVToXLKcnPBmyXEofZKPHwHcYLwOcbuavEjNMsXAXmftAvsjxRLcsAwZptJMVfGJeQThYoBtGZHMTorjFGwAMlvHtOIZvJmKjtTwXkMSHnZonzQoxXsdTWplVZCjcCfFIlGZYptDBIKJSoaJnLUGJlpkWfkfXXENvxBTOMvckZyAWpuYzsPHGNsgAJSVZOUGTIOOFoqrODPkGcuszbDhbeHcxeiFHBDOZFNSCmruxqGiwqNTMVDjncRwBfqwBfWPkmEyUTanxyvcTmgsSNQogEiCkvmtKjSJXTHYrqwXjYlLbbqriDupyDhtdsBpuVQFzoJlQpBDKlgNITdrprEQKFkfSXtXCeuwrJWwWuscpHLvonSbsDNRQATqwmJZOQZPYjnMJFntgbgEdTyRrvpcgIrdsNKdgNhgRZDCBfKyzcYfmHGwCwDTOLBpzpiAahASqtSOPwtVQjXxBMwAoaVHaVnqizpzRnatMaHQhVQSJGnMMUJGvkNdZAZgOZqtGMpwGBYzTMPyLkWLMtGvyZsPQUvTuwvUOSOyrNwJIWyXuTAxSJyFcuDAlYgYWgmNnBVbnDvoMnPrRZFwLDEPqThHcTCmLLAttMKgvRuzcRSwPxLKgLapOjaeskkTvaujaajlhypejvTauaRstllxlUoojZyIgzCZCAyuzIaOSCzxVhXstcoUEbPlnfVUGCgzRTGtqdkKmpqLCGCQDEXCIlFmwAoBZMKDcQWXXzqmvswmCvrWbcWInfwAN" - } - }, - "ProposalBase": { - "id": "36", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "24914473521", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T19:49:14Z", - "deposit_end_time": "9936-01-01T08:07:32Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "274" - } - ], - "voting_start_time": "9935-12-31T19:49:14Z", - "voting_end_time": "9936-01-03T23:08:12Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "gXuCzYBOcH", - "description": "ZiYMPxBseFtfXbYQAxwESELolRKhLcbZDSsIkuQhCACbfvLCcvFgvpSaYcmBfmQvltbruqdJEEdHIOmYbxaYyQFXCtuxVxRYwdVT", - "recipient": "cosmos1u70l8rx738e3vq54042ykcgtg3mxcxmehnfcdd", - "amount": [ - { - "denom": "stake", - "amount": "878575312449" - } - ] - } - }, - "ProposalBase": { - "id": "37", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T19:49:14Z", - "deposit_end_time": "9936-01-01T08:07:32Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "278" - } - ], - "voting_start_time": "9936-01-01T04:09:39Z", - "voting_end_time": "9936-01-04T07:28:37Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "qsESAidpcVFxLVUcRtRnSTHnBcjTORKywkTCJkHmkdIaNjqiwIDTeLzDSZuLJyGNxiEiSMIMEVGLtOEgzTMLWBSpaneexJtwIQGgUlrfFGNxMqoyvVemeoxJfVCsVHEXByeAoSzmtVHC", - "description": "SttkhdVbNyXrccSZDlVNdBXUAzkxFKPgVdWZYXGYahhMvGmsubhcfnvBMyoFckRytTxWcITeDbQCxmqPYWBtlhycWXBZFykAQmRqhWphYOYmDrHWfQWYGUhGvDAuGRezGBDNGEHDnPVljDqOjIeKaKZsFDtwHumLttgXXwTkxoLOBGaHpzFRZXUpZrGsJctbYHbvnRxDvbGvilGgIfoMpvvcGFaWwrcYrQcNqpwhlybOuqsioVrCYOWXfjuvryWWjQFbTAgTiWDcdncMNvuzpaWEkxRkhXGLBIXkqPOCENTktLLTtiidfwnWwczgaiZqLvoMQTjQgAqaSeuXigOLqgPMypqdDJoIRlUsayfuMsRUnDZUfCiWiMlckSdHzTfEGhLGdTmsfnZySIAVENvqEihTEeEHYsUwZbyFaTXufrrBzLphnssGEgDjVHWBNUqurjguqjpFRDVTqyVfUDOKpmwfyiyDHDkDoSRbEAlLjikEaaucDCmPrXDqDAGIwjPahzaPRTCEkDSfPsSCXGpSTSifOuwpeTvWiPhblZYXcZAXXSCtAVjpAycPxAcKcbbZcUanVPMSVGvYZBDCsLGurKfdNWNtEFhjpzpUymrYZwXZEvZdehDwKUBHktRvfiSPEpkgeZsrAXpAvqeCSMNeuBPTBMdRgmzXsbSifTRMDslTuYvqPnMozRmnhYTXfAbGntodGLdbNvkFiKBySsiBtqrYNacbRsfsvbwAXubdRQTvTCISZlTbIPsDOfERpJaqxfeuAhODoAwgjakfljCDwOQWdcqZqVWTZGvUsmdydBdZDhLMlPYtSxilaKYHjiLoRlLcNlosYzQdUyzSXdIHlPadOBjGvlWsfbxTgwrMounrkybSmtqjZnXCdHehyZtPjwfneGkAfhQEdRzULmfWLIlwnOJgkjrgFIQgYgJIPXCYLnJfblGoFrRQetAyUZfXyMOFIRggAAEkemrXEhPzbluyByGznrVATGDzoDDxFFnxIvHurIMskftkbJhodadUGHGbrVRNGSFPVgnicaJoPKJCZTFiEfCVDptWldmMxzmJMqMLIgfBPsQUhxhLieBSPFnoDjGutODrvhlVotRRQXnYjtXKkedlcfBZABnAqpAREdXQzTUqlOUpBLGmrsTqNqKSqyxjoJJJJpoaPpYfneegCxVMVETdMVOkgcdShanzElWFdsYKhSFBrzjXygUVwwjXwKYXmSNiZIoIDRNPzJDPShLDTKBecFSoyMxZHHNdUAEmqlybebEtiqnRWwnzikURvasvwvCEubhoypScEgPwSAnfKjLNzNnQzLhVfOtnbkawGiltkIyEfWgOdatzQFXVOYiGSiJkjvmWcbrKFXOXSVNcCUhHRWZDPnHiqzRrGHQFxkvxSborclEufaXPmbTksqHRMvKKaBzxsDBAjbPYAHsGOOwWqerFZKiUzepzIjJNwqYbOpglPVZNItDsOBOxrbpsJuFIwzxDIGVkNoTTMsQcMmMRLpLYbGtyBwEnBFuosbEWpwnHtZXVVNQbfCDOggnUgwLKOIbRzRrDgWYwPKwSeqHqrpKiRxratReKNbQnfMRgcFuHLEVifjnzphjibHTpLTxsgBODVPlvQXzhPJpGyAhpDFRBbxSSmdeeQSfBEdAiGribaqeqIVJVstSqxGttFUMuGqydicSxJkgSlMnjBReVlFhCMhYVFDBCGBFNoCdQXGAVoUIaFdVqzqUvlpICQqSjYYzrBzcFSLNliMcVtwgiexROIESOCNcgWOgSCYtuaudRVoFxabicgxrfJgEbsruwuQmDapcLyEXyxrwxrNnGzlgKDmGooyGwZgOCitGkzeyniIETyBNoVKpEYIsLFqrNsaMJrVTzJdsREDUMYZnBbcErJWeCPioxgBporbTgrqEyNAccvkmsVEtyFYdMYzILULARJnNttfesRNcQjbEDfNeZphYnpmLcyPpzgQYOydCmScABAEILUGGvTkRCwaycHYmAcfCaEUBoKsJluBJcVBJdhOlQWZSxLfXBdxwafgQCJeOYoouBJkFhjsFHFuOSfdzecUbCqfCxwyAYzXNOwcoSGYVgJTWZrlvzTsLHWzpDXzYSRJWEJLBUttnNKmqTRGUWHdEOzkKqFnFeKdookpCBPAiPkTEQIVPXUeLhrVnONMHkCItHizrzqbXaBiVAnNPAwayhmPxnyRjPpbTXFZpxhwYYFAcCmWkqiDCLaXSiZbPIJWpSqTIofANjOCNQlSjdFkojkqPHFrHbUIHkikUdTuEQOZleYCygynWIgTHqJHxNuUcgDuGtEbmJJjSvBzMewpbOLlFEhtJlvILUlslpGDTNQKBJgnEUHmFVLxGpYtMHkxDDZZdGOxoxmmjUXFuFXGZlLJaiNJRSIXfOEaPhVtfARQhCVCaUYBOyCVfLdIGPfHpjkbBjcCOunnlbJJjlvbTHCCEgUTZkaxSXSSbMAgkwLBUPGXEvDxbGjqNEcZqjTaJfFAPKoUSkBbTvQjDpjamDQBiazljbUxdwCTgqMMxsFwOgsPoOiJobLCYccvorIHqntErjEFWpNnJnFTXdzDRhrhgQOUKJbJQmddGMZXcwIArPXihEiRnYpNRawajNcDxfOCYCgoNcZTDcpLrORTEgLVqWOkaSPzSpNLfqQFWenIMSyDToxNxNEdAlSzMfjqXRUPULkcbShhionslyFIZgqGCuPaGxAIRuFNFEpMoqAEwMwWlrMdOFoPKjNsHqovpbLwIOLwfREZkfNyeZbJXUFxPWEbMACuTiGBsPmqyvMIzMonQuXusbFXfGadDjPVPsWbrkqmIPCBYhcDwnUTimAdzJGoecTvuPbRebKnJYquTHbZEoMpcBSgdxiYxJFBtNguMOQjzePkFUremHaJkCrYpozvChfHSipwFzsAdbqXrbLmJSRhWWcABRvgowmPpoWdaPEqQzeGkCfDVAjJBkRQSmgYPMekJqMYlEjBAyADHPlkiRDweaQtgoZXweRHPuFHpYdPUDMeSyYxBeZCGJhlaNqaUFAqKSJrVaLkZzyreVMyuFLMtpPUDcbxrxdAXlgJvLkVBgTRgtspAGUAfiTdDnwPvufwMDfkuCNqfLeGYjvzjGgSuKTBNXyGWvyckscumYKgOCxdhncwQvtVCQYRLUhSDCGwjHJNnrnyMxflSvJZdxDAPXkNvaQraDLbRCtFjwSfdlAWdghrrjoGYOQWFNZOxYecyLGkswNlIQWoLtImZLdjMueOIXNYzFEzYKVmCYqcwWAsvHcdztWTIsDivAJbWJjFsVwahboXDmauVJuFEHZTYDpLDVyRRUSMvTwMXrJkYZneQuraBelgKzXtBcIwNXONkawZVjdqrmuoRcptCtGvOEWMoIiwffPhqJbbuOuyTmEMLwkfgqdRyfxGdEtCepdavbskTkkxeWEfCYXPMOvkigvMDdPZyGkVNbMZCEpgdfkHifSAvZfyYvKalDSRoKNMYbGTClnWYHTiUDrGIOFesiGVCRQRXIyJClcejiANlrYShWoxNMreVyaisLFsIrgiMfxmWWbXZZttnCYengIGjTWGRnfgDGcqMMRxhRXvGBkZPqVlSoMGsbXFQQgVQdsBNdhiAPPyibOroQQeMmzzWrDqsJlkSfIEDdjLBPTLvOsVdLrBznBRQHDlzDgRkNNgzYoTDdlYFCZaSJPydShMaAAkxThPzpeazGAtlZMXinykDYChcvJMcsUHnLfvXbbBWYlXeRmYiuCJQapYnUmxNVLNblkxHcrgNwKyVWvuMBtuEYAFoSVkticFAxriBlZQJrZNbfLrKIgFLPwHFjrNloLYeWEETFGeMfQiIriaxBzBENvXqGrxSKsVmNEFNsAHlTtOOhFSjQuNuhADNQJXAkGSmKxmkMbyQRkVpDKytgftSwVQaTQsRVIQJglJxCVqPxVTwnAwAsLaVEzHyedPJzTqtTLmDxsVSOWqwHfUABFVCengwKQWZwrlLPPvimJwVvkjCePySARDItmIeCqQpnWABkTzpFOOixYQvaKhFJbTimxPVyPGXnScTiQlWRkOTdXpwThNPgobTDmTYMXdxkfNrTnCVtxOzEiLtUZKTMIzvODbBKvAwvSiWdNBRejnqzseCOArkGIuzxbqueUhkhaUscnfFpdDnnlPFcFmkWiQDSsQDvUmKRXBQIRljHbkMjllBUeuzEeoIxRZhwNmnBYHAPftUMZvLzhZtULwJoEvmvhuyddURyXGAQHxWBIQBxSXcBpZSGmIwFcJaLDsSuZgaozapCInufQVoNSeXQKMUoYpuxnBRuYBcrcvVyPSIwxgnNnIFBywpmYNWaQxbjSCCuzXkkKwKiQkxoidzAnuhcoWzmLvnCUuqglfEzTKKTPrysyxBoyjFbFrSpmVabUAMnPpGpqBTrTjrhRfaHxtuwWhekQxKLzwvEhrVwDyCsGBletldXbLJjYFzZedqaNjybRNVUIIHltuuPqVxzSQsxxRtxSIZSLxCHvoWkfuQRdxkOBQKKZMvACxTYkCCmcXftTCJvIsSaNloTdsjPjxcnLZsgPQeYZordJCAFscrlPYTHIJfvIaKJaQUOkVbJQfexdpbTcOMzlHwhqgXqVnuNZHSfwgRPwXPsUkAKWCdAKyEpDYmtsClNyUMxjTxjcTNSslVVMBPHveoGWJfcjlJAJkJzMzdxZxBpPbUqEdGsyAaGJXczvtZRUluJMUVkIrZYllDOqZKgWkVZiVuhvDMxbRvihIbelzicuMKEdgsAcBSHRoklmtvjCLxOdMBXNMmDHslGlPjbxXfmofrDgsycVKdnHEfuwSjFEGbbgCvahKznbcdGPQQaiwMKjerCwdFWkUQSgEOmakSKyxcXtXwduVphTYFLpheurGproYpOczKkYBWhirYKcvSfTjucaEtGYgpwbvYUJSXImnhMGBJuWMpLieFlDhFhIYKckNjkgOHUQkmkuWOfXrcMCBnczZmZnrxacBtrIOKwQBCI" - } - }, - "ProposalBase": { - "id": "38", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T19:49:14Z", - "deposit_end_time": "9936-01-01T08:07:32Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "377" - } - ], - "voting_start_time": "9936-01-01T04:09:39Z", - "voting_end_time": "9936-01-04T07:28:37Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "JFTcBkbkOVtTcBwowhLWODDrtswDmGbVTyDCzcEZqqxYRjSqzgpYSnOZzfAEXlbVfhvgcyJVEyCRGyIIlNQFmWnUcjDESlVhgfcejjVWDETWdWQOOnlaqAliOVTFNaDebuJyxSzOMdkR", - "description": "FBnyEMIITbpMBVKlFPWPOBpnfoDVluqZGGFOFyHWsvwbTtfpBPuKvwakKGjAhZiWUPjmnkoeQvtBqIYYpFdyBlPNybduyOVmceVywXjmUIjTnpCUlgmYDcCrYUKwcvmPumkAMqGWkrZQhukehxcQRUmcHwrAtSIfuilJvtUGJTpdIjRrKTZHkPvoCDzJzyNvrSZzKksVDqBgBuFYXEfYDXVCdaHvnyAFCXDQKbepLCWjOETPFWqVweBwurhGjETrELdAZQxbEiybVFsRPRVIlaJvdtRWApAtogLdyUbgSyOhtZtqSlULYUqGCivSfvIyKBwdOsyIXsGTZBAABmIZUYepHQGgudHfesseRhctqwyqTPcbHByOfoCHQlggzvvFilSOftXbopRiZIYwyDtNywSwzMydwgwWRfAIaLuonrauUOqGgxgzCBkmkTLqXZmndtkVvWXsHTRfgfWmhwnWtRmwnKnkFxwXwMuNIZPkLOnnUEfFdwXummGibNlGyMyPnkBmJRovbrGSCUZnKgzdsgUJTJJcHKRFwCpUFhvufFBBzxhqRlwonSAPkDxlDUrzmgoNbfwmasDpjvogmuxNndHeiHWobygLdBrxzQjhfBHDgHWhCQxYBGoTJjsVBMoZxSYNJWxcDMqJwxbGDyswOpIvbyLTmrljgRASKfgsIolAMGTuEoXXeZreKqtctLBCzehhjBatrLOHHyyiTXJJkhVnJUSHkMMRMrYeVeEHXTWDTqKrJOHDGkDTBeKGZPdtxGDvHnAmtvbsLgLeFEjJfOtrmmOhXHHrqeZaMrWcbKKatsBBVDeYXWNolJkCwnyGDnCpOuMvvFSrfPNyKoEOcKLoJSJeUVYNvBHNMOPPsmYvHPKbhdHnGjDMwyrXbHvOculmpQRxIsRPVNCYAWbiTsOUneYXUXVZiTzAmmFbONmOwXPlDgkpJOUxvNhVuronbZiqQnDebFvHSdVyRjznIjOVlqejhovmVmcJPLFVRXDgqNvyfLmbosGGYyHkJrIsFvRhDuNvQLMfVfGsDdjZqFvjnbpaxMwwYKzHNXvMRHVzZVYbpDiNFeJeLzGfbngqFjADRpmgXROnnbPVuufZHJWcqIchbRCzEKDOwWwulJedCrvdtelABoYmyGpyuyrgtHgjdycWXZZklkARGMPPWbQessQHuCJQNzYUbPsZlLtQYbjLkecPagTIwdkdvwokQWRbdcpAvMTCfTEqfTgtCCHTjSiwKHFMEynjcrrycVWLAeybrobyJohsvOasISRWZYLlQZbAapAVkokxQTrDaQVdnIahYyYHiDPXudRhiYSpAAaqgKEfUUHUHcGuvMYyeEfRVFIUYegHGKZnzsgefXzBfbVTzrPQhnwzvefysuvdlwKaFGnpfpsAWyeEHJbGnQtAYqYHnEKbfIgHGWyZeYWpEWJQGqzyXPMkVYybOEbuKKGSNtsQnJUxPAvXVBviOESvIZwKAYriAyAMSclcfYJevGmPPulVNXretyhMGHtKsKBSAPJePNkvdOVkNAtCeRbvKYXMJUSScZYBHEahCLoCKuxXpPpXGxGMwkQyaJZDMkusLpgPcJOJaaalaykcdujwqAfhPOTuDcWzgQJPHijSCPvOPjRpGRMIsWxvtrNnhbeUTeHXBiAEcqtVNkSkvQbrOfLsvHrCCbEqOUNhhPDXLlSCLabadmzUdTUayKSnlfBIBKAVzbSxNYVWceiLQYkXHoGTUzXWJcRCrBPedLbMgajaUtXpLqRBBGdPPcxkRBcDCCwGDinKNOxjXIQVKJAMCmrfRxljFHSWcgyXmJboxzfZAPRvIXwFRWfHVevwTyNQZtpZibSJPMXqqnHzOmEgPEdSHRpLsvhqCVoYVZxlkGaKsSPSIMSjUABYKPKioQXFQAWGHreyQbMUgsKdnYniNfgExThMpcIvvluyulDJKxbFaDzjFCRYkudYQfZUfeJyQRzfqJIxrcujoLvngFhvCyLHfPSgGJEYpFlWjKqtsfhbHYAxQkLBcyBqsuNmHvVAKDZdfMZVtKTdjjGwmnMDGeUZxZndOlCyeJjauecNAszNhozKqOlDRHgHndzatsuwWtOKFQAuwqJSdiIwzclhKNogSsgcYkceizxwrLXEeKUkebPLUlZwvjxIyFzWVfvDoQiBHwOXZiiKwiRKOmhLjBRFvKnDPlxEffoCYUlYwHftxeKBUCbhiZOYdfLaGJdyJcwpUqIxKxomUJnBrUtezBKpZHzXiJhWDYQMDneosDAkTnoCWuSNkpXFwkaaslxazeGgTpYrjhnYuZlXNKjJGrqzPgRAPkzBCTJuNTUmkhDurQVxifrIeKknjtlaYQvCVMrYnjaHBJptlNRtejVhsrbrDpLaAUggubpDqnFsBAUzxFaWAlhJozRYtSKRZqdJYSuAuATVrcbDUJYttmlBuNJRIaCiIkgcQqDnygecDtYYMIJhuFCUmjIKrtywaJmygvBcudWfcqVzwFWEtTqeEcIKKyYnADAyzkXgEmLNjoqEJfCRULAaXMwkUMcceoxyDOlxwbBTAhMlZxJSrzbSKfVODoAJgbYFmmkguVnnGhewxCctbdQcbayhMGYZdBKesjAtDiHwrWWyWqNKWTxYlNTahCOfuUYLhHBvfFjhAinoUGJRpjdAQgYeVOrRvDDRIWehiMdwRQmyrjMQtPcSMfhyGwEjmRzzWhgiDNBTfmOhnthjrFSOaBMzKYLIbkvWEzRTNudTjRSZCXaJxtIfXMrQjrYGJsBITXCCfZRWWTibIauWMogRrduLtTcjbpPSkWJrmQCAJtMPCGKFXnbitvIBxvaMHxttViNCdMgWodLPKlIUeLwDUHLvIxrylBbLftJkyRZWcCSBZiyGRDwkIodTkITrGcCebauJfNVFQnytNPdNMeXDOkSFfrYecvGKWdPMnrWkmXXDfHWwtSZjlhNkTJikHhNDVUeyaiiaeBEdckjHzlwGHbIarrlKRoKNgnhlnYytnmpXkBtKFdLeAsokcvQveHtuhnvZiWYyAgUPOGxloiJqDAyGFLbYTCfphsKWXFQrFlihbuzXWbSCyPyhfwYZGoVyzcuEFcMOBVVrFZzLxsTTdjZCHwVyXpfNUHnJHZYnKgZkEJmtfGMMjrBlsRbsAXwrtGerEkRkNqYVdjTKYxZspbHyLGFaXEJZoYrnRarSZUrjPXeAdLXZkyqhXsjMeVjnNwHIFZWddNuOOEHHtntyTbEBZmzZkunUcmBAgaeSdznzjgEgpAcupPpvOnGQpQIfjiQschqdzlIByeNbwBcPSPvjybLdPXVrYkkQyPnSUYeuKENdBWVAuqnFOxYRxnyWnilDbQZWsQNRyhCfdKxEGoZLHQymcGTEmnalbsBJGSRciQHOYjkKcmNwokjZdCQbLKOJlkPDhSPLUiOrbbgRBhwQaEjbmEMbRVeHNeXWtvRRhbKZeWeQqyAObPYrvEXomfPudsxtWktBDadrMBUTdCZNTLtwfrmUUygimzFqkeXKeRiwrHnXOFhBUGhcgzMUhGrHGBfbjuqHxBoXUKkznduHYvxeSvWZddlQGWeQnrolwycjaUuMQiydqoWCodIdTjcVugnQttTWkSpDFXEiUPJJCdBPsApVLLWuabzsZdtiloRzZdeEBaArSNFHRGoNWCyvdRgkUiLNEMtavqubfsjcYFPPXTGZkCvdBSFeDcHXLeaAePgCFaPSYlpyTpfzddqMKYnRAvIabctvlIQNHQYeqHLKUObUskCoqyWHxxoWqsJeglGuojdTZiAFzjkxQRyhZlUvTVuBMuZQWeibqUysjtnFTQJIZEmAPpeGMIxNQYnkIqfGxzsrEqIYjJDtFaJbeAZhSrvVRAUHxloCuBvaItUCAmNsIQREqFQNxLWPwfjGalLKxOWEOtWwhzGeQlqNiAIZtuybdSTKfWZGbylVdmzdeSJNiRtOHFHQGrTBiYBPGwbBTjIVecGIxwRNsftRcMShVBbHYanYdCNJzoFVuSVcEwPELtapeUmlqomRcdMewmEaZjJLuymdQIGMuQijONxjLZZXyjAYcnrkegRNizWZWkQETwryFDINQyUeqtByTbjRfCCDBqeYWAgwmxQckKihIdZsQBEdaZxRPbPlwywmveOLfuwOwjInfvynBbBNJSHfEulqMdAbonmxzEWxeRYclSVacgGJgCZsuZiXAbAfOCrGAblegnxnKRaeSiDdpKdkHTnxfQpmqixYmWKJzHbjAOFaXuLpGCyLYoTxgpDsSYqbSUrTfDRqMoBvyhvVqmZGZWUaCjNQuvnppyTHZyEWwzZJElyFzBSzsmkwkmWDpQVVZKQHFveQWOglSjDtTGQlILmjPdDwKAUThFrZOdgsBRIzlshufrWYxZudSXhyKtAyHrwSEEEKNlfZHvzdBCpGoaQjWRvYstIrDKeemMAgnZYgQpBEMQRxDIYmkJqzbPYtLJwDeXLLYDdwLIzvICMnaAyZksCqdHnNZcVCvonhooJxMtDknsuuZNsQCYRStLEkUAklTzfgsXLygpginBPqYMhSTTeSYjrkrRTHhcbUNRFeLuExHVgIwxTFoyhQbLtYjqTaNlgRCOPyedFvrAHeqGWyrzDOmFBSEmyaYAwvcWMNkSJzxXVlNrrlQWnhBPqHMTSjoGCzBflJzltnxKoUAzMBtuIAYvZeiMkkhwPgLpyZhUmOgKmKXJowDDYgEcbbFquYIZoIwhUjTpHhWxovWtQJllUyeXiheglnwHswEMdKoDGCxklkUajaExhuicjfYQZYeHwmsAdaMEQTieKMEPFNDPlgFcRQybGTYYzSVpuzTkVVZlCIIllzRPgHlSlEhZfTveyJJOsWZiiSJjqUPiIgpXENkaywdAPNoHxbARmkizTiefJgpiFUhAgYIqXSljYUWiPCAaNNlnKAdQSnKLxIGtocSsHPHCfcURlnVyXsDRVRADEHdQsNcQZbuOZDYzJZzIiMuxPgCHwmAwcarRcj" - } - }, - "ProposalBase": { - "id": "39", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T19:49:14Z", - "deposit_end_time": "9936-01-01T08:07:32Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "265" - } - ], - "voting_start_time": "9935-12-31T19:49:14Z", - "voting_end_time": "9936-01-03T23:08:12Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "AsaMyVpiymWdEhFeeiBYtcSfWKgHmfCWarvMGodLSyysCgemBrJSHltcRAywuQPPdyWWjWlHCSrJYTOEtjxSWxZKEgYoBWgyZBQdzQYRHZsrwLxZYBeqCIMgRjRAjjLWMNDfTCFSYntV", - "description": "yieEmDLtAUwEfssFIeBKmcvvyezfRmwrimtNKJRBxyTseDtAcyKzllWjWiKjytNanHZKmlLoJZqGtpfmqTSpZPLFhRoNSsLFLLQcoqvStsvzExiTomQRQODfAjzjFEzQgNmtitFxtEjxWQBTTnTYMhDGJSTdTkMNSXplCZEsxDUsmfMcvMbHobqSpDgqgaWqQPGYBgVKEOoxvspQBLikhfPbjmOXCFJrwToiKDpvLrMYexqlbTwluXRIHCNLEqWyGMkJzbXHIdhFtGmqGlMwOPvQUVWLmecUZBFFUTdBCgjxVIzJQLXnSmfYWliRMHydyHDLHaisaQpWDYTKubLJAxjZwCLwVLnyikZjFRDAwROUATaKInskThlkmRyTbuRBLrjPCGVRCeDDXvuYdEbHxRgRMYumeDOjxPFzzIifqdIOMNujPgigYkHUytebnjiPMTRRFxMwgLZLDhOhraBXEBoVQQiOFdrlpJBkImOTjExwgXjKQqCIUfKoIAOolZNioQKqVamOnrWDBgZKbeJVmlYInbyDpRtIMedjlEySbQbETOCVvfvjHVMANxecstdSXMoygVeXkSdVapTDYPiuoBOEXMnqDSetDQjTIfTJXWcHsQjuJyyjBjxaNFjkzRpvkLEByXFSMBkqZULblvzIvONkHYfAqMyPCIShoClDpRSZNNVoWtnoMhWuylPdshKrAMKEWFiyLRSpHItJvNXuyHpQtrRcStkWNIywuwLjGVbYgrxxyiPRaSOWJzGQwxdsXWSvRjirBGdLsqeQEzwiMSJDfUpyuGJBIgDlFueDDVYUUdOQowhnztBaZZwxRKLRDyaxJqeHwokDmgMnmefzZipTppqvfYRGvNUJOpHYauhYJZMZgjmPGyHhQbXtoebwfhmfPzVPBmxzPaVhtXdHPqbRlluCXINgWdGXBOIQDYzNCBSgulpvfrKnwTqgdgIcGIuTTHkSqvFfzqdaEHAnyYuuZXGyGDafSOmyyTTifoEgLcVrJHcddZhVrcxnqVqTkVfKMUIhQxtbKHlXnZvOaWmhlBbZUCRPDrouGTNbjFQUQWIrDjKpUrMsCTasEwFyHVEEtwklrwpuwhXVAYPHGZANXvChXZbleGRsobbFuLkjFhRPEQRvTcZpyvqZQViAYQqlvEUOZVUkgKOuWIQykceqTFqsbZYxDfEUVqOQchSZUIfgzLRlqCmeBydmEwYZarIgZGdJTtnUSslwxnQJmouIwBrtOudVChgzXcSTtNwBSLobgTDrhXHVJurYmmTmSwBHkwUudCQDSfcfKJuwVlYUTUEgZWSJRmooOXOqHCeqcMxDDVNYCGeszERQvFAODsOYJmMyWkazINESNYEyenuytABVGAraCXTsAEpJQoPFyzHWPAjkGHPjTuwWTDLWBambGyTWUMolwXUtTHnpDYmlAUWwkizpxMwXMjtJCITlCLKXDEXHHvghiGbHFxrEAhYZGMvcZuLjIsEwVcxUlNZffxsTeSrrYUoIoehhKeATwpVkFrarVoERZIrSsiRBYUdoXyyaHzMmCMHoicqjwafBZSaWbDviLqtIFNAZWFqGyoAqBteyQghjipVUzblVhxeivdElyCxQBOqWcqrXSbSVhstCyStKEOXPfizdypbCUefMKVJwNCcuZoQMCNKFyzUZmsEpLVneiExEgSjFYRVWMCYXvAmPxzvtJlntWQDTgOnLizYEIXgWeabwIbuugvzuZWbavOkjVApepuHkcKaSzrFJprCMAFWOLJKfMNdxkxvxJUCxtdBxWipYQspTWIcZQkmeSlJyDEicDIfwFOjZVdUezXPgwmgbGVPpuJPzVxGVUNLAGdTdgsZKdvajhZGdyUkfLFTWaNTdEjjWwBshNbtrVixMnZOfrZuFSCLURfTtJZsDKyJDmJQzHfuyzMCNvdhLvYxnCWStvBrQhGZSTjQcgoASRQiseeMuZvbXAkQfyAXTxdISumaLFeZoCbnOHQWyZXHohPOaYGoIApWoYnzyGnFbOizDfBwgNbWOEZXiGYLTHwOlSPiqciKoStcNZTpaaGKumLDsrkQZBTFDUIHcuUOxWjZbHycfoetlqloEDiMKlOznGVOxwQTpAribBStNQQEqXttmVHuwclYLCfgROyXqdHVAYCXWgxMKWvfGJbMgKYLLXCjeByEoxZvXWeoqcZwkcAbkilOAjMkSTAtqpvieCoKclPKcwjUWuSYtcfJIVfkoZoiPoysqhimthqsNLZtsIfdVfRtFuAWHrqKMtNEWczxMWQHqAbulJSZUuYdOstewyjrKKniwsjznoaIlkAoaMgJfyiKzlmUpxDMUpaZvgJjBaiOCHsdLuOIZHTvGYWDVXCSHCcHAdOLwtXDNUkcqIqPebokRThSGKNxqWrAPICgEATFxRaVNaSMYIURNtZUCbQOXdshapgWsQuemIUudhybiywOYihCPlianWLGpCnkhgrsnuvwTUcMWQBHNtBxehgONyxvfZnMEZWlPDcwfYhwxgSvFBEmGyNycgqxXApIeNVNhokKBVUGGkDmfwaAFaRGsrqxaVItdKhqzBRdVxfQWidfibzfDxssnGqMxCJVbSfAZdPPApgSHLTncSkrgVdjFoMAXYTpMZQRSzotGNOLURJBUhPlluSfIoFQQhAzthyoMqKtxDygxJFywvmWtiAeOqELyGsrmYYiBKMXJgSflNbEzPzHszzCdpGDoossyNCXCwvBEiOoqACxIupDhtuLdGgPEQamZSrIyMCuFYnmzOmLDjZxTQLVsXiUduTKTozSxUdexnYZzmvXWiRDjKqDwVCBdQOAWLwVWhJQJvCvHuIwBwreIqnUZfTmKUOzpNTKgFeKFbDBMdXXvKGMcyfEGqqTdmecLboXnpgOQHhlnPCgsUhnEupNTLmwJEuuqenlIqhQCsaMAgSAPWUkFPLkCMblPniWugAKpvfEoZhRmjLAfaahdLROyZkscOMURCqkCFSxmzHdabNnAdupwsIsDiEZTpupUUiQjMxXpNNEEYEFqIbbyuUVpBgdUGcVXQSRPlUjwtPmeWZsAjWdcpTBeZTPwoXnwTOwXXwFxYjBdMAvnhrtBvjAZFlMgPrdfrIUuZVEgIjFggDyCNuQQNVQFhEVxJPLOKSnVWMGLSzmskjKNZJHeuVvidwHheOKIwFhSKieqStaWNJsryVThbDPXRVZFVLWmWJkuSsUQqyfjAmYVHmmXmbTUvWwMGwGCiClovHkkmSvRcTbASHfTktxpiquJpEbnXeHxYtMifWXjohiXdDQZHtavIJIKstKFSJDEkCtjLdqATZBMvIWrRZxfYfowWTpVQLuvrIEYuHfSJcBguAfWgsXlaRIjIDgSsujGCnLBioSeYcrsXDmKJNvBDbmhNPoBATELeXVqxRLTNMKBGEjyaKVOPLoeiQfJvfqhysegiYbSKRRTMjsijgtWVTBibGEYvfDBgsSbCbYbUBWsmJtgNkuxpbksxJpGQdFLQmxjobZFOZstlNBxEViupuTpxDbQVBGirOfUemxcpldZjINHerDDsJFSzXRwqJKDNVfDYKLFQJUoBsmqWvBDfcSvLuGZKVEtIYlmcrhDgFhbCJSFBkXuqCuVUcoTjCrIqSNeWsYSREjUtySaXRvJzYlKIghzxCNCVqbaBoFvNIJRChvmiKIhEuQPTbPjRFkyVivqUperpwfJJgsNqigbxfxmkOFHvVfyoNdRwJdLDkSkhbKPFVJeSrLvzyzFStdSvczuFByqLWpUyvEZZGjgSoiNnqOIfEIygwbUcWvOveeyZmBRCXQAnjQCeaMBftHwuHcTVTinopNyIEubsZpUofGjNtEszwZjAmLduHbCjNAXckQGitpYOWrVNhmhGicvsDyuRQifGDaHRdgtWADdnSOSTwxheFHpFHQPvpAqSKFGLRTBGYDTkWTKOAnCEqVfiGeXlxHxbKfYyjgkmbilTwsFWNPiRLzIEprEPkZBFTVxFZjFRdfwZSPrgsRNjmYHxATamjsjCtJHOARTtyGojAXdUXcmnfbrIWGfAqdfaKGAgqlwUhNsVyKYSNbVQBWQgAyenNoVAHNoIvpVUgCCfcLSafladMxsNyvhImqppyQyvEKKFSTyhjTMkFNtsolUYRaqiKreMrjbhpfiLiSNPpuaqlGbuvpRbpLbTLHdrhOEuhtEoGRTiCJdxLDYRdTvYDUAFzSuIrvSiwuADKjlIRJldZLAbCKpNJnvOfZfvCoWcfAgywzOenPhcJEmdGsiQihiwjHTiDWcdQsWbnXiBpoajxNkmFvnRoDfdVGZJvKkajiHYpSdyNAQnrJjPpjajYyXJrWFGMXZiSiFkIxVWWEdAFNnxABJlHtHApMkmTkbYkapCoReNVfKDKhrBpGpbZIHoJVpwFVeohjtxxSdLoJOOjHCNCOFjzOAfGWRjEoFcyhsQBebCkXLJbJvXzNUxRtoSPCgTtRkULVNCDaBchlHhqKvSSVaeoAqMFimhBFcyBsKKHAUCBJicYuSHiyBlJtwooiUuUrzgzQcqRmrovFCCDQMgFkXHLbUinkFzmTeDqqLVPdecKRBkgldnjqDqRCgYcHhYRVpkxMffbpJPncEUFvfVjfLkbCCYwqguOuOUrTJqVsgarrnrrAUigzeXAZYnGqxDeHCRTkXJAVLzcDbqlRfQthKlAKKdKMYmxgkXRqzNjnvGotUgXmWaXfCccgIHbMcdKgxaeaPnirUkwKkVUnAaKcINelBxGTctVZqOMeRVupsUqZbhnUvwtEuuNZLJIIbhorUuDsjArVqZjTeFoNBYmAjNLbgNsOSRkeEYGxJwqoqDHXHYsfkinvsxqHIjrRfJjmCUACrFqVqlWfcaaFFQBdUfAqaHvXnQszckZUunYKFLbJrfQdiAXSxWnveCLFCTnxowmchiSMyedOlgqalSkXOumcfXjrbwGidjlDzMrLOmRbqPbWnxtNepVnyrfGDfHYwHZvrfFpxYrMkqUuWSVIB", - "changes": [ - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.100000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.080000000000000000\"" - }, - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"234699000000000\"}" - }, - { - "subspace": "gov", - "key": "depositparams", - "value": "{\"max_deposit_period\": \"8250000000000\"}" - }, - { - "subspace": "staking", - "key": "MaxValidators", - "value": "42" - }, - { - "subspace": "mint", - "key": "GoalBonded", - "value": "\"0.670000000000000000\"" - }, - { - "subspace": "distribution", - "key": "communitytax", - "value": "\"0.150000000000000000\"" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"177\"" - }, - { - "subspace": "gov", - "key": "tallyparams", - "value": "{\"threshold\":\"0.529000000000000000\",\"veto\":\"0.317000000000000000\"}" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.100000000000000000\"" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"216667000000000\"" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.010000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"9\"" - }, - { - "subspace": "slashing", - "key": "SlashFractionDowntime", - "value": "\"0.005000000000000000\"" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"5\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"242\"" - } - ] - } - }, - "ProposalBase": { - "id": "40", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24914473521" - }, - "submit_time": "9935-12-31T21:25:29Z", - "deposit_end_time": "9936-01-01T09:43:47Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "338" - } - ], - "voting_start_time": "9935-12-31T21:25:29Z", - "voting_end_time": "9936-01-04T00:44:27Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "SAkQGHUsafluovdPAohenMWpBXBCjgiXEltgbbkxYMxSxnPtFQjVSgeXbEIWzHMxpJGVwIaqtyQBtXIFBaGslergpYKmWEZiSWARDSGNONYnldyruhHzcVcZhuSzXteawJXovDuvKehD", - "description": "UvSEEemWvUUncAXoQSmtzzpSLUUqDFnUKhIRKwvYWogvqdRIBuUCjwNWimDVmDqMppXjYWkBSpxApKfHVOdfjmvqTQXhiVObWkvqNTTAUyzbAmywwZSpWumompPTbjJjTyMdflhtXIykPIamdjGDMDTXCdznQmInyNbXhmtWhpstlPQCVGzqJERqIWHQvgXmRlezqBANnXKzVIhHRYWSlTbpcXJHxgolTHpIMgHcLktSLuaRyeyKHdDCOwLMaeFpMzuoTzIzDOCXyCIxaqgwKImXsrfbSGkKYroQgJfUnZnsojesQOmgXpuWCaMsZeVFjZlifcuaiiNWLYkoZoctMKooAUsJxDGVlNPeRVxaToueIprVArLIknLWrKHIIDdSoanyrGKzIcXuDGwEggFYCEUDGmCQnKlDUcBQWeQYabPdhSvueidXLOWFqWciopfPVmqqslafWdubcloVpxebPpmSVDFZkVbWRKAhyMnidtrCylOVevgNnUGEjjLTWzFEsRjdwdsWtGthexQqILtydJekhcWGLetxfocUyFoUqMJAEmIwvjgWBRwVGHWDBQzJiJxMyPdMBnsdoNgQOJrEMliXtHPUOVtIyXPsyqogpNqStzkNSqbMQrUVnRjlHAYmCLcbQVNRrQjzpqYraEnfubZNrolbuDKwgmRdLnmYtsekHLvewSTBukzuOPVqhnolwCQMVpcjXrXmAWGAhGmtVqnjdZNQESheGAcHtzcLdVHrDZlFBqBmBAhGdhCbuyqplyfpCtxRedzdAEPHyubmLxOXZISaMuUYDqammbRCbFRlddvLMjokKJehNARolieAaTYCLMVKChtVainCiedZUMmbQIrVDeazYDyoGCLOBQaoOsOGbzLvTrfPwqAqavGJeXNjGoPPyyxiUMknGCdUFDoRzsmNrqziumejRhDxAfGOTgDlwiSTbsDXbPsOvJqmcFGOZRJGTdsOzYyuVbDcnXYGUvQBPKJPDzwAENbYkfRNdUXxrALvJRjIOAjYaOczXGrYoZkuFxJwrkdwLvPqwcObwpJzxfscgeVVaKqnYNbgPUfxqrVHMxlyUsLaAoJdwaxGnIdiUowTabXLiwSOUxjhwrdPsLRXwuKjlfvFWcQeLssrECzEBypbIOriJXBfSGZzBmznroyzeqymcNWrfBWqdfdsdOUMmXaOEBJSgmtvhFDMTQTrYHsqAGfdsZueWJAYYoQaZUxtXAFYLckwpBsDYkApiJFoBdWjmkInxKXqrvzpvQJURKPQajOwLekFXoiCXYoHmYDZFlUqpArumEuYfHdaEkeylssvkRrrrRHRephIgdnxKuszRztaDKQUknTyKSMrvPbRYsngShXlVEliiGYKMyXoRVvZZctkVaQXrgfooqJoNguDrtrTvFyRSHAjHnZyLxVHhWVsoLZogvubJBAKseOFZtKHYahKqiWQFxOqyDntzCKECVDiefKQzcKVTlVWMDmdOzcPedfRzupxmlzuacEEdeWRNZvUASJnniXguJhwABsfITvOkUMhtICNxLagULZWqgcDTLQJZTQqONiMsUETwkPNAYKaLwCMNiMbxyBPaSCdLAkMATfcZxuyiRfbwHDYjgIcADUnekaANBljlJoygvkWEdomizotjfqXtlNYcRFOqXmAYTxroJxgFOeVjNvBwTHBwjVLwGAPOGSEqtLSkmEcyYoFIJgOeoZIMECPeOXKCEzUurscYGRkcGlacMEBTaTcXLNdbyNGOvMHeLeHKSCibRAywBQlwiFjRNrPbEkFYkJcUfubjKUIyvKdsdVptKUUVndOZXzmXyUVMPinklCzGlLsEHbgyjVnsLSFpdhPgLKFQseAlUUqmmBVzANWOUltzMkyarWESyILltQFlJlDptvXHlUDvXwriRZsJpvbqgMESmJCNCEQgPcuiQSJSYEEsAXQZyqEHETMJHsBrVmTVXQoFtAPLNvbQXGxyvvfuqbeVjNvjEGuWtqeCAqutocKEHMBDSNLNEprRnsynzOCgudNjuWDKWDfLyVWKAmRmVQMqfnHgYzGiLrYITfFEmGkeDTiEFtQmsyqEUgxuLhsDFgXYlUMPqvsAELSiVvXuxfpbjKwfmyxNKWhqpqDyPMrTtTDibKTXTqPKIjfhPqjHIGQYFLICGgVrKBMDkcnMjdLcWuXVVpNIFlYcctWPlquzwSrYLtMqAZHpgrSdcfZeSZmVMstCEmuAQdQOJSyVpXhHbWcNlNindFpSsIbUOUBXVCSQFdUafuMheGvhQAyKVgHxWtirCQZDJmtUMVlqfkWmBjAyUtStcAjfsousGtQMiPLXRFBLvustLuJWSxelFuDJGohiRhcLFjbhJUBUiqXAflGzeDhtrcbMngiukqInCYEpFROGRjPUzNmVHsVYDOnVFgoMmayrBBwWibPVcdzjZxtXychCuciOdwFUmnmdUkhPLmZqcINGnlcleWRsImxhHcDweJmKltoHXyrhiktcREQSUpIUvUtxEhDGWAeSQQYTCVdpmawwVnYipyipSjklWJuawsJrSkVWwOfwKuzxZbajelodwvSJiCgFBqwIFdZcdubDUnOlOjjTxqOYcIdunJVWeHvnoqbHuKGACNjJCpuznZiNMIFxGarlvpckzOvJELeHGxTLOULnYYpiKaPwmdTdZwHnJQuFIoHbrgmFvfeCoUgrkAAVwSsVPyhwjrXtJjlvpPkSbMkwpFKUVbtcYxeAyPRpwQxlXapTWbRaNZSPfwJFuSzmZkWqpelGfkfjFCnEtjIxajrwHlsQpMfvgkEnPtBTcvVBRcghprbsWRJxgfQWxeTeYtIrLLdZBBaezYhMfgQpwCAcLEFBigzyPOCczhfQEgzYGPqgcURldrPcsZWraeYiVQqaPqVXMOpKiLfCQSzfkUUFPyyiKvuEbnPxRjEfstZKdSKRGWVQCHRVZflRnhDJHfEuHLHBGqTjDUtiskJuMuOqFPgmOpmWYiRsFoRSTzhEKeapEQmNdZGhgWsKNYdFVsJYmbKJZSeQHebJSQItHofusZXESHytEuxfAdqbbWglaUrqafKyGgxtHDnBhxZTpyoEjowDgDfHeeNSUeNfxtmfswemPdlnuIawrBgDlmDuHNNwuZlHQDTeEJSqsFiSnHgsFiVfyBhaZFqiSFupmMgrKeDleRAWctubnkLJAgYCuKsQzWlVxCGTgxwTdSaWRajlJGRiINOkzRdxFXDpxtLDWcocIjdRalPuFTWVoVrmwMMuqexbphFZTXlfgOyDkJDDhrORTZWvUPwghMkvBeIJIeXGCOCJztlDTENKiJVubnSiaMwqGjcUTXMVtkXMoIDyWFgxUrapmoXRldBOFrDTPEQcRUfVUuGWaNyjPKcvZtCFFmYGPVqDkiinShAcKAPRtuOYzsWaeCicSPwBKCXNLTyiHNeUUpfSNISQTnseLSprnSPUpRhydQopVMDPuuNjwIuNUsAzvRaEKvAmwjgnTQLbOGLJYERiCkrcYCHslqDOwEaiRlzTfsQFbmyVMlFIPqyjtqkEKcLKaaZDLEauNKYBprUYAPIcDBdziZtkJbvUTgpDAOuGYgKEUYuZIHuXbgpceNYfHVxgfXAaamlBkyeGwMjJTqKovVNlWGWUozeCQvBoVeJPKzBCNxpzHwBWKTjhJhwpKNTNEzfzTuvnkIukahrLYnCksftTXCWqOZHbncvcwTJNFNlirfAflvNLdOfCJDQEaeUAlWISGivdZaeAQRZJcxqLsslzJrkBzZlQHOxXbiwyAUgUluqRicdlxZDoMTJqAsBWeJxXJvCKAyorQMZaNdVKbLAsDdkjRhqITIVJiZkkrUoNriJifMoMiBaLqLPVPzdXFJvjKIrKvFRktkiFsjWcTtAwZPioJSthbdkzSJWzNAIcJkKqMCrLEHdwvWOcojRqwFvZQXOHOJJugLYyflkyURfZJGyXKORgGJaJDzrRSJnINddwuaeLiIvxeXsrlOYBPWrgGGaWcbQxbQZpWnHbawkmtxnLsPZJOsdpgCGSNbvuxiXVTUWoZIdiqdFZCbrFfXtNJrCXScpOMDIMugpWycdSDpBDGHCFEjXRTkPtfWARXhQCnqsuQrgdHinWLftwAJoUZIywWiYUoANVXVuxKBylPrgZkvAoEogHUteQAaeDZNjyTRYRQZaYScFqyKmsloHZFuyGZrKCsSwLegNGJRBmtuoSApxGQIqYGrMWdBHeLiBGQElViUZZCbNNiCqrzQwlHwOYCgvVCYIUpXibSoijsnTRrszVOpnmoZqmrbGIxZbsGOwooxkDVFlCTEeRKHEcijiJEgsIAAeSNAhsXijlnwYukvXDcrVEVscVcBzVUbjdumFKEDgzvbFZWdexdYdHMUQmxbfGMzBNskHPvYFokfCFTTbjsobWnRzSBUUPbSGEWOxSwpKRXGwPbkFxPqaPYJJjKLEZWFgnvFaEzlDhIOYSnNTFJSbmKVjXiRYtJOvCMqSPsTvTQinrpllHcpNLVGGskWBymSqeXsIJQPsFwKFOzHHtpFIQAzRHjIjqvulZFRVpVCbNRRrfMIKhTfXPxwGPLCKnldUqjdLcHFPnGNgnPxUSVJlrYQiyilvDkZgazenamEFGcxzwyDeQoemJRBoDGJBjkoZCwPnwFTadTBKHXfjFWtXuBSiptmHmQnHATQnmuRoIWdQNdjAwdHalWnCOQSGuatdAgjODyepzuTIMIQwhnmMeZfxKiAaBOjrZbzYcJHLAjDdTnSLBFLuXlUdjaWpGbuVmqRpqxbMflltPmNvGVJvNMKiQZOHoeJEWTYqVhKAYrYqDLokbpCcrsrCnoLpIfuXRdHqSxpseMXOLbHGncVhgzQclEEzZveJFHxnYLiutqrgIGigdCZNZLfnydFJnoqcrolhoxTSsAHlHdmWdbusxypGnxlqhJDRXKTpQgpHGPScRCWFfUBOPIzyyhPJlFYumRhoXtToJOlmImecsQgtzcHiFWQOrowo", - "changes": [ - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"36619000000000\"}" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"500985000000000\"" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.400000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.900000000000000000\"" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"10\"" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.170000000000000000\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"816\"" - }, - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.260000000000000000\"" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"9\"" - }, - { - "subspace": "gov", - "key": "depositparams", - "value": "{\"max_deposit_period\": \"140795000000000\"}" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"181\"" - } - ] - } - }, - "ProposalBase": { - "id": "41", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T21:25:29Z", - "deposit_end_time": "9936-01-01T09:43:47Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "320" - } - ], - "voting_start_time": "9936-01-01T04:09:39Z", - "voting_end_time": "9936-01-04T07:28:37Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "ciOCXYlcnJfKOLbAbmouDwzlXsVaJMcQwHqfcaGzAkTviHrdhCavGBvwJylRwhKnVxmJziEoxyagEBauxCQtRJAkBjbKPtDFeTslMAntDTUchtEMafcZjXRLMbEnedxukoSVXdBdjXAR", - "description": "VUcBmllrPbvvwtjeGyDMfXlbRcXbflWHBmmcphyuiscoQtHZBegKjrWIHynqAavGfREtmozPovxMjSVPSkjgifgFTtpjisGIIZoHzyxJExABEHAJbnbJqgiwoRkltMetUTqepPWIObKKRHIiSKpItUCbRjOdiNPgTSCqZfNvpnWHsoRRoVvZnxhDGiMhTWKrTturuozrNxxcsHdYozilRjUMLlWzQsAMkEBHGoXBPMDHxlSEJFkbNMIJvfkCFffkoVCfdRqXiLlDKdtDGIYeIuEMFvnFgbSHReBYXiLqXjxxyUxvNXmQscryUvfxBEKffCYqFCTQfyHMNAPKXAOyDoJGrWcNhLceYAvLYcLrrnZslLSbTtoXIChAuhmAKFTNiPFqMdGUhFICXTODEJZNhSUocAKZYeiJNpDsqVMCmmWJXNiCHlgvlpcLWswbYdvLrzxJMgXfpJbVOZGmGdacUnMzVFDzFIPCcNDgRddakfhpnrxaqnLoWYQqAkZLoTUrOfDOZEYIKqnQLtoLOLPJlnilZGtyvbjsbuHGRabaMiaolqhCcQnhBZwuGepjxHGgfsEsaiBuwQLXVaqzTetFkhBjlPyxRcHKRdUhAQWXUHhiFDEFlaQXQGRoJksXJyQvNXaZdAZTGgEiqLCodvEDtaeRAYCgIbHWQjZxnymcoxLNPcTcPuzqmkMQWmuPOzCHLTWzogprjvmlBaJmrgwPbgPaAPSCOEgkLjEQzwzQdhrUmAKSwFfQwnetRWvUlgpyykQvYCFCGgsFOqsimhnhzKWNEQxMVMWUVOMtMcJeBVhYtvjCLQQcgCrkwOkIDeSRKSiCAnrVbtOsyWmkiJdvZVQtVYvzljyCRsxxlXhsRjSRDYmmWQFzQoXqKtUwKmWLCgLhtotNxypFVWlsvgDlEUFQTYqPxCscVdYKkevyoaNswFgjASBojZDGdDJdwbBaTwsjMBykMaLomqbQRTeTmKcxiXMGIVXXeDOXFkyzEXijVSrncFNrzXKlYrvhTvSYzpqXFqxPkwIoUSGqwKIbRzpFNSVGCmGiqOfsHvIDtLCRxMuIrcWtYQvVEjLTohyVPobmonNfMSppxmcyiUIhrLNfXKVkwsklrOSOBxGwEkgMuXrvTtmUEdvgAZHqMWmofKZKDEVOfACJhXZtFCriGkKFRClzWCKfoKEnsURoTQXUOKSZgZoMxgbymeLNbWfJnCkssHRdWGfZmcfHCepVatBQcBlSCrcOguBpSjEIykHXPqPTUTRfGDxlxfIFsQomNzumqmyQVedotNGHeJWUVywieUCOyCGokmjtthxDiWANQKBhtpBXtlDPnXadRRzFQWWcOQWXMhmQmsMZZptHdEJjzbBoDefpqqxEKbjbjayjVdsHEDzctMHeQRKkgbdaKxNUTIbhKdDkYZgfxFrErEIFUpXRmmpHLzJdoFAkjmsBjtZxAdwKzYYyzrHHizFJbFDmmDvFjqwcEygJUrOwrnbBDJjsNWoEGbGcHnwpOvofjbJtrklxZiAHDDLqoIxEwZcuvdfSCKCFCSGdSwaMpkCeRTrjPNLzIiqXcpHSWXDpXMqNeCMjrVYESssrBRnxrnzQsVGlDLOSMDwXxVfdtsHuRiIEVNCwqlYicizXDYlhqqlRYtjNhCvTjikqySQDZSAwdnjaBRqewgbBzfhOLBGDbhIybBvpPRRDwcOZhTLOxFuXmLqespeupPDMzLhqBnBKwREKaxMFLiXibnkOtGugEFdOmeatXEjyWCFegZvPryFdYCpeZGLzfCdCuRIokZGQNhYnUTfZbcPXayMMlvWxunaxRhoejeiVurfzhtHowlEuHyfAKpuDutEfAEqfUWHOBGsDbQkItBanRwOwjyaLeedDodcoFWlgiwYbQJSKVOYtCjDbLPRrmysnXwnlBtIITBggcjLGJLwUmiAZHETJrBcMRNytbKospQSeFVkQTOGWqkCzkMaKzVgAUFkzeGigxWpivMnIvIWdzfPKuRPslFLVrOUuVPNTzNvKDvlQrIfIkaWXvtKsgVsVqwRAtyfPUerhqMKxKmAaslLetstNoZwOSxDnkrqDcRfmwWMFXjmoEJXATmZvrMPGwACDLVEoZKnVuIXPbJLAPvCpdbWDkZlyKORNHdeMqaGVALxOiScfaBnjgtrwVJeQRPbVwVmNaxGWWlmPDsQKBHhegdFuJhOJoSJVGPANnhRcjKyknKBklmGoDiXWQIALizjTefvckTDhukLdoPIobvoAlcjjivlniBgGOvGeyEwBXLhxxEWebJPrubzQomvdIyBkbHOBEkCAbODPmBqmmxjrGQgVaGJoLMTeTjayvFABafyfBXCYRbFgwedWJsKtgcSauCecfxvkZFxkailjZPWCrTLDyttEoLkazsEukibulUBkXlFjgEGuvkVeKBcGyHhSRAShmxRVcXGHHPHdneXDhVLzAmZmPSQRRcNWZthxEKvrofXfXGEQiritAEImQXLnHTRcRrBBvDjOciUaDeCnySsvaiBgMFxVHhhKLmRECCYgfEOggnFFoBksHRNYfUYgXDnCGaMliysGZESHwiPZAtJALzMQIqhSFeyfEhFuasmuAXSBcPYffesQiqkWWssiiMFxfqTvYYtEjQMYCsRgqhFGaOVerIRxpZYEKgXJtlcbhwHoafRyOrwgvvmyMncfQPczabeVoCRJixeZNzMOGmuRcwaqqqhALBcOAbUawxdXLqJTUrywxYBjEATBEIaqxXeodQElnSRgeSYEXrtrgrRSmNbtUYQENxQWrTaETOqvqznafIpkBaEhllOTuQfPzEiZffTwFqOYAjfvlBPEsJdMquOMHjilVUkoiDKJMwjfzOHyEUSvGIQAGbiirRzdLbZbjFrGZhmjGRLvraexpMAAZYNAlKHnZXmVkRoHsvyeBYuXDYCdUxgvsoAANCiksHElNlLbzrAUHDsdTiExLbxDLaZBTMEGqxQidJaiFktDzKFqjBrjoMlwRKCJThFophZfiBxidTKTUBjQJidwxppIVZyQitdFSaIZIqwMtePEuIcYfuHdeVzSphLkRtBbRHtoRpgGyEvGrzvOKQFOJdNCMORXusEJmzZykvsQyrRjYThnqPvhDvwHkoYfaEpJveZLlSoFqOHJHnYZrpvLtzAsNTlMWIDBqdJHcEAQfjKZxMyvnUDnYcATZQThzXVjkSkMYvBaXtUGgqaXVSnWdpJXqJjiVcPrAYbjXQiguQaBBSKJBbrBRIfvIOcvcLrmbVWaVLnKFEHgGQgZtOfOYhJIsdWFSlBzoDbHMnoZKHpwlHYMUvjtXZzwOgWnFHAQWSXCOEbSUcFcBzpheRWAhWbHOGeAgboQfuirkkkyGsPzoMkkeGjiQDBHbYbLleEtykBWwggmCSJadzqorlCjDyigWGXUgmvRcpLtQtvEATNtRWpQPYtROpWuneVKvVpDDlMNnJYpCKwhRpmZpHOybYOylxgAZbdPjEDhZLPpNwrGJhrqkUlcqExveVdPTARiskjhlOoENKupyUOjaBfvjexqzKoUqMOEqEjcAfFaAYELGwuPyQUYOoKtZhumgTdgedwWkMTubgRnbvwFaQUkHrVBdzcQHzsWqQYDenyLITdYqbefaXwzImXJZdlTtihbuGcxijSDtbzsTJblUwdzdWUMahxoRDNXxDsJzmdIIjksuurwvLlxQUHsifAmGGXtXsjbuyikcyAouYaimSBEKgNKEUNjGMsLyvuwXIRpoHFBmejoJqkmbrXQUYYTnBipUlXjFVsgpFfBgXjuBHhMvIYwmtIZXCmliCvWJyKSUPDcEzzLmXjgxrhKaPVGLxwAuovfYzEjAxQDcwtFSdIfwSTQynxEzLvCipCWdcDeXRjWusAkVNqjYhngDguwMfcQEzcfyxHphXeaGWxwlQWbcNzjlgTPSNkywyqSkxRjHvIiFcEMbgyapBictzQvMavxckZQufGJFbOJzEntxUgMtPJSwBPflyQCIYBwTlwFNlXLJWQGEcsZeJTpQnCoPmQguioyQpUKQxFqepGBEyArvgXrMWSXJfVaOtZabZvbsMATSLfTrhRdeiPILLNPpzUabILZOWDonSKxezPwVTMdRtbRfSCttKJqWtyuKZmOAMlcWRtpoiwjHzYfQnvQtpvcFQCjgtZkfozETDYRqeOmckENpAYCRGJimyYYCbbEkGXolnotJnhalmxGzEkFeDgBDCFrcWJAgyeqtDYUORXfkwYrJGgGRMwtpIpLHDrqiQDnDajOXTUVEXMURCFfcYUmRYWQOBukLNvqysITusMOkrkOpcTxzINFXmHcfgmloPtAcFWZmxlEDyJXUuDXNPRdnWdcItUKNoIOTvcXsFxtiYcilsiTlpgWkYqIzFylPLBYxqPltksUNtugwJYtPEdNqhtQpxMoBEjcooXYKXPvWMYjJCCYkEQRDKjWNBuYBNuVkZymNVqulZAvnNzxRFhGoQhtKbyRhzSIsQshTBJvdLNSxrzxfDknuszVIMTPEwwGmILpXGCIVKARBfowOHkcQoSjBYQRgrRhenvJPrKsnoWUnZdOyEKJHwYsjZaqgmzbpuvcArTfYOxRtypOatdfcuIauinrwiuLtvblXOtezOjjXdoINXRNGQffYMZBqRZaMFFelAuWAlvzoplwNTujwySbsTmOrcNOkiVRbsODFXSCtxLfEGKiEOKAEFvCttzEJDCPTVMECyqEeUcjYZypVYIQbwKbSLIWmJIkfirVMGynhnYDjNmuqENNQRwlDbtzyOfGwalvjTJUPGGzlLdjQzdtGYhViBmjqOiVBNhjgCdgkivfgSeXGCWbvSxJQwnYtdNrZGAlqvhrYSJdhZPlgJMCYwPkiBSsOeRokwRqVUlInEZQldqPbZzbaTdYaYFRzHhpxCHLHKDxkdxLBKYXdIOfQPZjHhLCCAPFJpRZKaWVaCKHMNWsLYOjhWzpBOawsmZwNTjYIbEIWAeyoPIkiDXdeRUJ" - } - }, - "ProposalBase": { - "id": "42", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24972834479" - }, - "submit_time": "9935-12-31T21:25:29Z", - "deposit_end_time": "9936-01-01T09:43:47Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "363" - } - ], - "voting_start_time": "9936-01-01T08:09:55Z", - "voting_end_time": "9936-01-04T11:28:53Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "RWgNLhgdqfzARFfhQYGcSGNWcnQbcOPmObMiwCCxgIlBFDiSslpXJDyGyyVKMCOZubjCChHfLyprWydGmxiIYgOgbWtdOEuSfJWYUByDZxxmRLdHSIlNlHIEYrqCcBrQgLxSelUMyZpi", - "description": "RgLwfhMdZERbDZmgYTSTULrdnrkAfGQVgriJMHFuMfvZuAJNcuRMGmvqnhxIZSmJeLWQDnVbwJknJGozwpozHmbbljMuAWHDhaKDiymxJljSzGbAjHBGiVvNVgLjdYloePjUrAeYErlDgHzPWWjpyiTYRlkeiRiZbCiWLeDktTCuUZoSFnKjNTVrLCuKVdvzoussLKbqcypZOalQQVCZCMfPIkUMeRPPHeaQIztbQeQtiFXZAGwEsXnXObocoAZjqxFJLCXrvJLtkxeJFTNzzxJKUfRdiAuqfVIYmVdPDPVDgXdXgIbYdRuBVBAWNotiPXKVwGzMYDEwvXaOEKNTEqXIOxyKXnNrIQTcYvGRptIzCeLGacVWStzAYMzFsoTuVsSQQsyXyWQKRvqJiwEyMWQFzghVNOBaDohrMvfEbdvJbNnDWtsFNlydxeRqWqXhPZDaicUvXPWKgAAJcKpdgjKCLZpOioqNaLuMIuiyRSXrEgVVNgpQJNZcemNcETWPZmumgaMeiCDNGNxUGGetwadcfJyDqWHPUiNhqgjcTjXhwNKdazzIvTtUYuOIeUtgCXPfhWbeYZQQIfEPgxmvCmfNmxPKzbJkvbBApxIbdYoQlIWinrQMIRlviTOioIwohPXxCUkyOSqAZFwiXtRQyxdGTBrtVWEfAimvMYZasHIEAmginqvCJfjHnddvmRMdFqPFBiqiWSLGJALhAtCvUhYqgxtMmbuTHfwjcPxzKjALQvTKBFpbuEcUqkuYPapblzmpaCYoJiwNXPzytOTzqkTlMoYVPaJGLxgIgyUVoQlYtkMALMcOfHYEwMnTgIDXgSkHJYZocHnaYGjoyuzKwEtBYBQoevtWoehUHCjQVvrrkvRLglCurWoRLVBBPsfXqtHPWEYiQkfYfwIqoqEdgEEtEdxSicXsawcDwekUWiwnBWpaTtuVpNxMrrsssIjiXiwEafSiBkIcIzQsLfZGQpMFmRAWeyIOheSjkhZvkRgARxVdcBeKJXcomgtIuyFoRxnxwFTLkHDnqzgxltcwTnbFDttEcAvYRWpcLHRrNGUMTTjtKMNJWZuxcPtWOFkvNnUpbkMWBPITNIumwJvRvFqbMhEuesvUHyeoWIThPLTYNprPpKfFDsXeqikaEipvAvEOSiyOWSgnsfDQqycwbSdQCUQeeahikyWFnPFhdGpxIPnqYjJkFSGuJTmQjpkVEsrDGLRwahvyQhEriyuYCNiyuoKsecKDdNAnavaQWOkxnASVBrYwZUGwKsyGlfsinrhsSOcZWFkLqdsfOvXJFPlSRWWjvDlqjQHKiINbVroOszSQjZWUadLHBusGSaNpcRBCXnwfRkwnYHsVQqvhrMvqpLODsmbyUcqsBzxQgovMToyIrUSDhYbsmkasmEdULPwnHOVzEPwBMwAPZoctXQVeFqgfupHQAqacwMwTrOfAfyVuvpozNwbKSjtVlZDySbmRduZQzSZMqjqtFPMDUWTSGYDVPTyjnKxvblNatxxSHnGICcmLkbizHWwTYAUiczSpCIneYyGMlUMWtycqGLtPnwBUOFMVmMYhScswRBOKOoIzcwpYeHUNyRIedmaJrXHfjfRJvGRpSLgbOKFRGUxOQdzBUepDKKLtucVcAOAnFWRodJXGSktSzNyJarpnwaXOuEGrpxmMtBdiIPOymQfMRddqkRAJEGymgEETvwlgRyeozxCYbZwCfpMNbvbyomyVwzMvXHJQTuQSLKRHHAFVinJnJgUczXJqyNDSMxeaEXcXtJuAeLrgJIpRkwnatusNAIWLzxlyiGpVdZBortZhzWLhfKuFjgYotutmXJrFJVcyjcrxplPLXtATYauyguweUDlBlycggtmXEjoNFwpWTbChWpFjWoeLGRaJEFpPvJIogveDSYIctaBHkoxNhxSBFREfFyNmlmLqRPTCoWyJoGibntyUueDsMkkAmdWUXlCoGmKRvFqYkuobOgwDQCpFQfxutKXAFdwfvEIXBVZqdbptIUEwHvCvKOBGVeuVzksppcXBHcNUywIyShmDKyNbtCQelhFQvBHPanAlvhaXmKZycTOwvFrzcnJqTMolokyHQWigDcIOiahSrQLeoXlQlBGkcqByXciEMNhUgHyRmRKMhmrCMjblKmTdlWZjrmNXlNJknvPEXFUUvtAGeVJUijlsBTetQyHItaSRDuMaIXujmFEpuNZNpQOiABuSKyifhevPABUtjdJiEFWGSJkIGACzYverOavjcMVcWmejGKopEiDQSYiYQOzhveWyxdxGoEVKZPbepFnuDLkTjXMTNleQNdbnhaartVOXvvMqCdOihWALlSIiPJNdDBScLfgxbYQnesZwbwPlTWgYWXRvkCociWfojLlnkEnqmUJJYLJASZmLpprdXMNqIYwPVcQmPwXYKUYfmodtQiexjlqAbKspHQdAnoMszaifyflzVWeWCfqUbgFdzaypRgVBsaZEDQLpLrUIlJHJnwwdlTamiIYgfBQkUQvhwBDPZKCkqUNejpAspaqcgwoikybdDQBbxBmRUISgSylGoBKzJhBKcDOzjCYGTcuyTNacCPRTbnMqyCLCmvyEYktTZRUfpQoQZJBEGUGXugedkJNPCVqCzALwIOCTdlUZrkyNUbNrggULncbDXblJHfSBEXblgEvVCFdJGEhDAwwRAFYLFgAMyoXkqaVmTLTwjFLkWAtwzDrysDGeVGzdBzvTCHfEQkQzpMetNcBMHnZCDccoNmxFcDLyrCWaeDboitZhjBlDXQdpcJVPKDKpNOufnlBEQNSJgTTCiIAAxiqEgBkNquHVeMcpnZPiQEwpzQgmFQbKffcPfjHmSsvpDgvtEiGDwcPRjDSEpJZgwfxSpyIkEhGSFkcErmsZmOlLADevPrQelgxQvsgKzpoMxYmKfXLfSQhfBTDhPbdcbMTUxrPgyxoZNZOsYGluaIvdwwiWcgOrtOmtUOPodghLgsIBmpUAkgfDfuzgfydICRKOUfbOnZhOjWuUipgGtjBSSuFRETCoHIjJYFjamLqRyZegOJeSaYhWFKwVCxFTQuwCMJdgwkpBrKFRMlTfKheyZUAYRBQPxMgdWkGZpxfAtUDZriAvizysugrtQhUIiYBBaIIKpnQhbGpqAnjfsIYaVpmGmDpCCwPiDTvFcXDuCncYxEFPhRuSMueFIizDGwUoODQKfiqOXRyTvVYaygOGttbiptNxkphVmqFVYlCuLafrCMYBCSVWtLTVlUewZgVcZiZnpWCDFMDSHeWzsxPsxJvZeGdTGTnEfYjaRMoXFeGSYhVCobWCvusYTwHXYbaaULowtBCZeXhTxkgMPLHYAGiyKGuGtbTUkXXGHIWxobhFjkcJqpNZXHXgdCkYDPPQcYhRNWSrByQBoLHEzotUzcUrmFqJiLGBJHNdSXVPCWjRnSUiYltiTzfXXzQYavbMDJyHzVBcJpJiThBVqRKbxdsjKmBIKirvWiqajEwIMxQcmMvPpmnycSLYjpUOPCIwIbOhMtQsSWKjSxbaaJyIOEnskNhJiXrYCTDzBiNRDdCcTGqaqdKFEyExrIIaWhXMVoWSxkySeKyOSfdmnhlbDWdtdaZVtqXDMSNKpBQFnXZDfmHKDEQNDXvPTYpgZXSxRFAIcZUvwrEEJgLhzXrJSGnkXmgYEVrQAYStcLOBEjGVYSxXomvmaGAADMDmPaPMLIpMAzrxkDzCUKEfMvBfsXHQPDrcFEyBdSIUGjcdaKCmOOoXqetcdEpHlORmLMhRlGeNvPpJoJinglmFTOwPQiAIPQVnTbQnRkJPUjfCpGCDfCprGtqvvhZGEAqlyBGTnoQnqKMSQOXtbRICpREBqKqIJWcnqDcCsARHxsbuwlaQZdDiYSZdLKRmNhqmcVwZLsIgqdEEipJXutkUYHIIERwHoShJwwvVjJRBPHfjILnDiAhCOaThoXuHphSfYyNhtdwznTAZmcnkItowODGFmHOVfIyfElIlxyJpzwXinFEFzEoOIPdKSExNQczCFONAKLHQPlJpxSTBqSwyVZEiazzPbEtVtZscmqmaPjxhFBngYhnurDCDEgRuLZxwXlCYqEPurGAVXNUZtUvbkPdWNiJokVLIMEHkXnrcgJLuHDACdfEigRagWoadSIgAlSJbscxognUChJDdJjpBtZhGsmZrUhKHfymohQkyppPVRUYADVlfqvxEnAvlCBFnHvNgLbVQhJlAqkyWUZSgJDatWSggOynIZBfMYKfCwrlLjAbelMkbABVnHSNtOdkNYJLRWGDUFHesAcZFgxYVfsdCWTdNfVWxeERQYSnVkgkpXuuRUfgQKlhNRRFOSKYFTxURNkJTBWXtSXyapbaFAVmcDIKYPMXYkZFaIogbOYdFxPuEmFqrhpczXwaJHMcjCSMiFaRrpTTuTgJgoDHJNEcsfLBIbqVhMWqKlBFRpHxtGTmYAZcmtQccBQIUtgrUUcrJzmMFmeujwwbyGJnQklLUZrNIxPEpFxgUXNButBkjWhQaTjQAsXaraiRxjgfgrwBzYjGTQoNruMiPUwBtTIUgkxWdEWGZvoqmADFTxGCOIKxLOufVFzgAJnzMACaobAfGsRmPltRWVlBqAFpQYGEiyxfMUxUJGKrJNfyzhrZpeUzZomcmGotRbMRBOjRbIUanahYnkGpWhYyidUslwbxkSzTxrfhbLgoZbwrUgQDZRMHCRAPxldgbHAaeNEtvXUjsJHpKepWTmLzpIQTLTaoCtEhOlsyUqUPVLXMChxZwWvWmenTeDgzzCwXYoNJWxVEVcPwrwDLEJpSfntpiYScuOqGnvZAXzAFSnhuwbpPpccTUQwWidlIUoBJTmsCvOxhxRuGBrASCkBCdnXIdiVcvIxlSQfLRCxUSiiAgEkFMwXsRvxKydtUqerXETdwDyNsCtPcMhehJWrnBNLWXSshdcRXTLLXwCTspmDUsaXvPidAPBbHtpeXvRqrjzrIiTnSswuJPMoildtdR", - "changes": [ - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.850000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"190\"" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.400000000000000000\"" - }, - { - "subspace": "slashing", - "key": "SlashFractionDowntime", - "value": "\"0.015384615384615385\"" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "gov", - "key": "depositparams", - "value": "{\"max_deposit_period\": \"125145000000000\"}" - }, - { - "subspace": "gov", - "key": "tallyparams", - "value": "{\"threshold\":\"0.474000000000000000\",\"veto\":\"0.312000000000000000\"}" - } - ] - } - }, - "ProposalBase": { - "id": "43", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "24914473521", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9935-12-31T23:32:57Z", - "deposit_end_time": "9936-01-01T11:51:15Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "334" - } - ], - "voting_start_time": "9935-12-31T23:32:57Z", - "voting_end_time": "9936-01-04T02:51:55Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "PAlpMWxaWAdEazyrNLgCMQzQTxZKxsGqlXfhDCWNkZarzBykGbxUSeliteOWkorRQZXLQbjgoLRNZtyEtqZVYOLGLDkMNkkUQjySAGabwCFkOaKTknAyJEJrXKgwzWWELUFjvtpaBSBY", - "description": "NyJemyknmQAyICVAiHxtzvXXeFAojqAYZcpPlzQtxliuVAxKnYIDyRbDiSjkbQWUIDpqdNldNQbXQoyyQsDzelXvXriyISvuTKPaJPZvRUNomHAarnLVGHQHmPooSKUiHwOYBFFUhgbyBaNLGpVjXTKXMFGyAWiAXYLagAcSoUAbQsWwPAQceuJMaEGwPLQuHvtAatSfMwTUClqDyCjcIDgQxhWLQYbGxBvgktFmKLNCNxWReSnIPgQJWNSVuJWLBmUxgwEIlpskZxisjeczrprtlOGVkaOsDUFAgTwMoOiITxvaLoLHFXplkOuMUbrarUbAvqXpNNOPFFhfKPBPefTLoETMDTcaxdSCytpjxtjsTVTetzvLbYEGiqLmbhhOKIxrsjPnDFIvZTZlkealDaSYkmcYEfSbgcdCLGzEJvCweISQmdrmawXFqBgQGCrGhHGnmygwkKjogQdVnPohFwsXkivQrVlomsbxCdhekHbZspsNtNvUfGBxdTDLewEQUGeqMFRhTzPtRZgxikBorsPfmUHZmJYmgJdZLzazmctoeiXEYMGPLRrkigEQRbqGgOVWJislSWYWwalgaSwEopaApIhLsWtWQcKBhoCnsjiyLaCKswHLYYGzDIhudEvTqnvpXkfRCdZtIOFkskXZNzIVJYMQvwwxWzuBDdaEcbEZQZRDtUJrDEUqIHanzPjlOZSihDiQDIhEqpSvUCQuWGGONOCsAlZKeayjxSPZtpnOYISmDPNiuZxrqzisoWIXBqLsulWrNkddCoAfhugPOKZOKkxQYWIfnVtQWIrnkxjOhXhrOCCaMxeHOHRLKLXJYBKxaCkKprNfFkfEgYpAptzGkXqbpmWbxZSUPMJQilyaMSZSsHsjgnAFJrybiAPwCIwnvtcMRIpMHbwWHQMTQfcDJweTgzIfbjuadUAWeJLWXjFcoWaxYBQDqlWQpbeCKSnlZnidHsPzqCRGBxTvAfJZWjLIvxydmNrSqxCcibkeEtMtCjwXPGLvooNExziHpHTMEgSsKNDaSiOFpCYAeZPixFOttxncxPzYEjuoWNeRFoUmqLmWalCkUalYtzpqEprljhcxhXFPnNdcMqypvFfjvTLEzkCRQBeFUzjClWanBrGknKSeqRrwrFahohYtIpomXlCDrmGCVDwUQPlThwNvBIhqigpAaXzssBZehsBRTedUWBaNZvdsfZpBOPQxOVZcsUWXXkEIVquMjtcfyUneuDWpPASpkpGskTSrxIoMagAJygHDONhTIxDzryFGFpZBzCOpuJomeBQlRWxwdFQqQMNakSLhGCRPBwZyzeGKmEFQQhYGmEUxFnTCHhijocVkzaJdbHXtzLSfFZZJGIzwYxbCumtTzryZSXzqCFwjrtMqFbaPadWFVXPjpOzYkxcLulNcHkHukqzrlDuINpFdZolxhQJSSdFYPJTQSXWNIgUnqveQIMxzMGtNmROYNpjfLoiSdfXJdRuStClAjeaGCTgfXTIhOzVIKCRcpXZFpKJwyQQULrMDzFwxOrjThBriSjBYHMkQkFyZWbhMxLyBtVVpKyumXgPAsNOLrseqriTdtIAEHLfRllbwuwofiHQuwPTssxKsoOXqMQcwPKPtOOJFhmFGxWdWaUIUZqMLpmfroiwdhxnWbLolkkwxYJCyuIXqNHwrKDxtigcxNAaFPUVMaiOjYgoEwbuiadIHYPtQlQymNMUtBWkFmpJIsuUUcwGINIdKzOsUQpgzPSFwSynuDGKzgtSkuVYizsLGzPLdvCtCLuiiJgkYbAlueLigWBzkRBKcYyquaSCTuaHNgVxJEVqASoTFAtluaNkTQoOSMDFEXQMczuvqhLQydtYFjFWHKKpBTWjRFwKwJPaVqntRwjdEtijqHWNAjiJdxqjIVlWOYsPFQmecNGJzMysfRrlJrKnRdBcrxoCCCLCEUypfpaALrhbOyPlHuuaxGTZUKFGmygsLLelXXXrYxYdDhBGhEWhwjMvWvRamuUKgYezTyDqFAXDNFPHgmXPQwpXGvEnIZFJMYmDkzaTALrlFKzDMNKIaonQNMhmVjrenGOGvikmvaYicawnkemhDxgZuEletHOBrPLxiHwYhsBXHWoKGoqMneOOkOPfasmxMqJcAzNzFhdQNXuXbaQtqvEFlJddizgHrwokTlIxyFFnFqsLiFtibEiaEeOZEhgphFwvrqWaAGdBoZghQePrEgzIIMvqTpaCDQcWPNORVXNpCWEqhhMIuFucmiHOTzHMhftwUwYWxCzIKcKvRAJKvIBqibnGmbOtmJquoEFzVrrVPCtOHnfWrQsfsUxNehEaApGCLrdKjOqUyTGcVxPiEPkUmIvPUxyHlqJjeWVhGkUpSJtzjgpUOSWbkyxTaWRmUnfAPSnNtaWgQbbSmQHydqlSeQTmkpEkLocxvcHkxUhHYAFKPdNybYmvycvxXqZpSCRhGrRNuYebNoVgMgtNbvDSdYpbDhwvmzoHmaEweugHpJkSzXxyTKUVZTCFoqIGolopzqddsXFAXklfrHCqinNcpolMGGMzPAduFQJAEkolPxosaqGdrKKYdSNDeMNYlWuNZnihMmCxWLQTvnmAmyAnWfeIhmqkYjXPCeoYbxoHaEKKzhYHqvroxOKczFxkgLqZIpYAhrPJWxSqPGuDlOHWPgfkbtnjyxtQAihUzPimOEbvtulYqFPOBmhfmmwXOcRlkDVquwaCbJyFzPyzQYXwiGANhDJaiMLZABAQvjuBashYknUdhgtSOvRhSBZUFROKtZIMBBeIkdeyfimVbdqSySmlgFKhCUAVZzgXxoFauteAnxLzOhrkQkKSpYhlbAqeEpUqPqyDZQOIAqoFHGZHdBEBELlceVKmqaZSUyHFuUShAmVEtbDkFXjsAFGLsYbTDwPpToDbvmEfjzrKRfrFdqZxciWrXhctoBnPKusMNYSpkWtrftTPMwKHniYRLOdpOUBYSYjQFsueeCDYrcNYPNxlQbiOZfubwethbkrQWFBuRCXRGIIUrHfdZkpTizvpqXixocwWEAvDPAKPubAJNxHagPjAeUdRtdJlwhMNsIzEXzLMeWIAjeSHKxvIhwefjMGAFfmoEJpjCgVanPmlTXQCcpbjbIjkDYTAgEdZmlLksCIrIhykIxkpFvHVnsKIAHqAzGvxUQmxNjEidXheybzQXiyakeMjtOmObdFzEyvwppcjNzcBdotczuziRzHbrdvWWqmBOCmQqRanwHDGAJyKgScqtuePlqClZdGtFlpdjCfEcwZHnSSTekWyEtdUCMJvPJEmfACAonhveTagHxnDuRpXflAKcPalNVDEAnziiTDfesjjUesVApWTyhDujhbirjZCZvaPEmSfJhRiveDbmyllaVPKQFlnbzkNSzKvrNLQWQRLssAVWDuLshvEmKqJTKEbpUpEZyDfhpZvfRfUUxCVyLEJnXdWdACnWWWaVyVuPABrpBqGjEfXDcvnNVUuSZsIdqBRwFzQJopKchVMYYiKgtHdzhilFlMTyhxgOfNwBRtPbiTOhOZwaJybpcpInVUXEnEOpNhhAsTmTdbUudetwymiwYqAnmfurrerHnjzIbpooezqbyenJdWnBldaxjcYcgpVxLUxykKlkCwLZlRWFbgitUPfdozTmLqsvONNfUsdzcbqAopxohekRhyRNTPRdrHAYHnEjIRYyFORsytMqdlDqikEJYqhUiJAYOpUdVGfRREhMLiHbmzJLnOPkiApTUgvifWmJVGJBXrkhlgsGAtLGZkHmKubVKvNqfrpDwhVeBoMzspwfyFDghOdwqpNLLPEqeeKihNNKtmPgfiPAKKBYVaEsUAWcgbJyXfmaHDHLPyNrXobMLZPivhKFiaLcdEKjUsqxMkDdbAClRYFUrVYRGAlyxCOAwFHTpODCmstEqyzKxDdwDQtaqoZEkCGWfNtpfDywsUVlwcUIpIgJDzscfLdDYKMgUpQzQiRIaaLqEHISNQJOBuLnQHiVnDBleqUaLOxMZyFPLvFDsIdpEbuoWhytBEGKDFPtuIHKJrCRWhKpPbNopGAYccVcnIlePLSrRXjHfLfOWBMvBIXWMzHZOraZsJCYaXCMXjUdeAdMRVEOmimfNmtFCaICVSGzWduofeVYUxlexavtTMEDeKPQVgXWrSGBugLACQImVhvgvFYDRgODRAawnuLPSqyPqPhvaFZKJycobxaWpoONYfhZGvPwAszXhQFZZnXomlVRggZLqdZiKTzcXebJbBQyXSbOdVDVYtYOIsYuOdgrxBjobpzgjpoBYZCBLGwcnSuotOfwOcQaezBgbBMBRWGYjEvUFQUWOhtpEAoFtGVjLlsKnyIfZMzlaGOrFjychfDAbmKlOLDwcjMmlTNJPwVcztnMSymjstgSpvcjZbTJbGxRJQtEsuQPfdNOuIooyrkhGIEgmxOSvhuRETykXhZlIJsMuPfFsWHxGQrOMRCsrOuZIYwPJbDoDcckgYkNqBfdVKjdVQhTVdEgJppnjvwAAzvCFYTXJIaEUgSxzEPZssBqLylsLTmJFDSpipJQnwqyyBZFryeMSuQcsEcTzRvYEzkaLlSTxbvqIHRChdpvlgGwXCCulOScGhBFcKACmajSsmauxjiwrjVHSTTgQAtcmSjcGWIzPADwCIGeARxiTOwmBTIssIdkACKyfVvirpUCHhWzreFzrMjETJyAtqGJjKenltoXmtgeuWLaPoFFZScMXLmSCNnCQMnxenfJcFghrvUptXxoCtYVTckzsDqdHTQRqiBStGegASJNzZrfhZIIGURqhBPhBSWCknDkHVxJdVotGoDrwcYqDrLDFBFRdfICudIHtwUwryBfZaYhiCDkwVNiKrqWsHaClAtIhtkZWFvGWrfijuuXBxYgSWcUKGKIjcgWgtuHjZTFAFhZgCuyvTZoZldHPFHYZdBhnuABEGSXPEjhJiiauqAXkHXEECuuPqIhCwdwhZCdlCZtZtJGkOQXKGHSKXIz", - "changes": [ - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"129\"" - }, - { - "subspace": "gov", - "key": "depositparams", - "value": "{\"max_deposit_period\": \"136625000000000\"}" - }, - { - "subspace": "distribution", - "key": "communitytax", - "value": "\"0.160000000000000000\"" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"487105000000000\"" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"10\"" - }, - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"116272000000000\"}" - }, - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.190000000000000000\"" - } - ] - } - }, - "ProposalBase": { - "id": "45", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "24914473521", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-01T01:54:53Z", - "deposit_end_time": "9936-01-01T14:13:11Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "223" - } - ], - "voting_start_time": "9936-01-01T04:09:39Z", - "voting_end_time": "9936-01-04T07:28:37Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "TmBxUVlJUf", - "description": "okbKXYjboGlKJuMumTFkAfLiJQFINYgNFeLRbZzMIWTspqZInwVVySwLUwyKPhEVqwLXcFnGFYRQHHKADEqUizvnZLPkInmiiwiL", - "recipient": "cosmos19fa3uz9n80megf46sfu7kzepfup4mjcc6we3jd", - "amount": [ - { - "denom": "stake", - "amount": "1789097633104" - } - ] - } - }, - "ProposalBase": { - "id": "46", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "24914473521", - "no_with_veto": "0" - }, - "submit_time": "9936-01-01T01:54:53Z", - "deposit_end_time": "9936-01-01T14:13:11Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "375" - } - ], - "voting_start_time": "9936-01-01T04:09:39Z", - "voting_end_time": "9936-01-04T07:28:37Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "NhelLubJEyWlLPaFDtKNAfdxUKszgocvKXifOFQRlCyJJrMGdhqZSXJaBRwwCkNZpBAsrVLXeYuUHAlyRnDGgUpqUsiljYvEyUxhcbkxrJyqeAmxQdYXWxbgBmcCIsKGDyNgmiWeXOgB", - "description": "nnQiHILMvvxHBVbQenufzeOQDPEyBzVDqeIQCVdOWlcXVQXKxAjHMguuckObWeawsKHFqCDKbZCTRTsXnnMpnXinukRocUKMuWRMKpeMaEjtjIDVgUCYqpsrhLNARHffROjdLriWoTVZBVSbWuKBMyKHOhGwqwbOFQJLeOdECkJwCoXWlkgMwWCodBTlxlzUPepjzzUCbkkReJoNfMsEbJCotrYkOKtgZMxINVuWmTeDyEhsGUhvBycAgOKfIaYMehVHoXQmfZtmHargmYmIQdDnJkMTcplEyzmZUbMTnxnjfJKynxhraPdUtHVbgRfoKICrdBhDjqPrgDSfqshBVpREWFGdOEIbgVeejQPaJijIqGpwCApooHIVlWqQpnctEcKSMrPZroJPuJNpZNFAFCCFiZVaqLdGdZdkOrhSsLopemsTCUUpHVgGAHNoCOCVTMbfnnRachuPEjapInuOrZHmmxcWZBfmXkRzqalTmxTUFpSeMulvZlDyccRdvSJurrZfiRdUnTiBIAooZMRzwdYGasWvprnVTyTSoTXLBgeqpSNufekYZxKVdlKkKOxihJrAkYByZcsppWjVcmYwZtxOJSjzEbKOWSJHNFwEBarSrRgbFCbMxHTPLDMtcuWCzIICMqRtWtTaMuRuSoqHOYFLXuzSdVnUdjXKnFLVsaCEsknBNWNmtzFdaCOQLrjCjYrsiXCBebCAosMTHzqcPuIBrGECdpfUTOiZexJHKCXgKXrSnQLsQiPaXFYzpPenafsGENmJZFERRrQreDLvgCykapHbXeDGWlteyHyZyUCInEPgnzfUsJOnBUqwqSpdbsGpJWFmUJpFtVtiRoByJwBBEvqveflxxFaAWfRZyehwFCdswGKRKsiEaTvhuTKxhmDrxHSmWeFOQkaluQmCnNItkLQAKFrqimYSzRTeENdBQqpfBoZapvcUjErUaeirWnTuBFuxEwOvHJAXkUsfnMYEzcfLOpEMiUqMsHBXYebOQEGvLXdUVGZrLUNoJQKuljUNrxKnbGZYMYsHXfTdpkPdyPcUfmyDcrXaMkcohUkJgAlqkWNjcQkVPRPysMWngocSXWZSkVUdsKLANaZEFKNczgCvziyqkmMBfMSMAhFYReolzZmTjWQEUhXpAEMtbXBVeOzqJMPVgzVeRCfEfdKKXHZJePbsctVLfwKOJJLVWRMvussiTtHdHLSeUsMgEkoElSFaBOAWGwPtIAiOucjgFuhDeiIPRBVbmLaEbgiwcBScCjpZlVHncLXNthBoaHfIeZUoEWTzHJwtqxtlTJPrEACZidxUIUGMgUPpdOVclpQYNWCbjBgLSzeUlSxhyRLAAUlkKukwPPopgRAQaMMLuPqgdeEVXslgDTvPUPNyGrcOnhBiuukjzAxOmmeCiSCoJTyIgizSQsbksBCjVvEiZNofhFLbVJweatAvhkcFXuzQMiKjYlfJLtmTLOqeoQdAIREGjqEGvHWSrlMAnCRJgnxswBzIjKJlECkSdlvIjjppZBZYfrijDmSFVxQMRtYrJUTiSyedeUHODfETDAIPXQDSQCcnvShImNHCvIHxjAcFlHWLlKRIzZgltOgkVXogKyqJJsBJbjMizSSWnWGxkSfUAOaKJrHWUWwhHGNdNlKjqxTSejMwmbecoTiPMPSQyfcmRgbFYsMuhtxJGrtBmRHZuTtBNTtqcfJTkZOmrvbVNLOgPRGYTRyvPCRsDPdfrQToMErWsNvQQPEXjYkPwVecUFPwVwkPjvbsNhFBqGnltvMPDrchlyhmRljekjnKfXojmLaPmrnsDczAbHEDmAEXnNbRluZRqNevsXkTNFrZlbtrIQXELUpqiZehzxykGvrfAiczOBQuUJpcSEluOvAFFhoIRiRRtbMHxYLUHzmxaEhIWQAcQsZuqKHMocwWRYhYaPQHmkfhsehUZSsUHuhkKZCFcOStxqRjLRjpwYeKNDgdrEZZHbaURKcDFcNRYxqnjZcpXyibdpfUVPVLhlLZgFKQdJzvEqVHxLtMmogecdeUrjmnGCPgwtSGtCeyOpqBwTFYdXyjukqTPoXzlpqgRVtDWJuHaUbrQmqLNqADSOfLHWJzVhHgcxyLhjMYiaKLvrVJXEUqIVhtxaaLZNnJiFtBPwvdhWVaWtqfIKOIDumvYGDsFWfdokpDFFCfAqdhEvaNzItlkQARupxuySKagbjMEjKdHRCXzXtnnDlFRJVXuJRLEofQUbzyQFTVhTuxkWShqFQxmEwcSsjziBoorvbcJHaFXVHYvXREZSyzKQnqlgDxjtFejDGZPPLzDqBFJfTdmTxTVCzYOBkbvLTusONPMLUdDuGpHzSJmqibjwPoZQeEQTEkSSaOBlxzeIAStuorgnvqGSKxbaZNqiRGfomPxiBxEzQOmtoCIKPlZhEXOXOBgwAASwHokjwQsbBcXRZqRMlnhhSijDkPQofQPTkSGsSqyOpVrSUnKCymIdDhdoBUTvQUkzGbxNzDKQmHAMlMtTlwsfMlDFCEQqgBzRVnRcxsczNLcxTKYcicnPOlISyLLevyPuZDgkKoUnogVjGHmebPJtSGvwNTOLalrHlCicWnmavKLcvBhESSabSufdUsBXXNrhmPVhAHuzSPSAmNxTCHDpTtRCEiSAAgBiEhJuleiYjCGhGSRLUPJMdvKrPowXsMYJOtThGtZeEZoWaMawNZwlveWRahDoihegmTBYVHLCqVCCVjrmjrKyIgSxAmFbGOazzHayHkwYCsforfSvXIzfIxfCRVubuUYOLAQmZJChhvOzYNGkyoDxeraWOSPdYJdCqzWTPJKRdCdhLIceYDDbZASgKJRMgJjNUTZGEHdXIBAuSvtNhYfXxBnyvngSgDxXcNAJKVWmZVWlREFvswUQsgImOsoYiKrxFqgSGRUUHIohlsAfJDysYPdtXmEALuKHhJDgMwXmxkLhFMupeGrNZEUxSpvNFNPBNajiltTKLDmMKnGgwbwkCBhSgsLhXHTnsFvBBAjtfDluwdmxnmdiOxSTLwvzwsJliIdBRIcVjsmwjEGcAVxLzJILOWOOfgoNFqoxteflOmxpETpQNBiURVawFYCYjNKDAEcpLLnYIhDMeeXJPSmReCxhbGoTuWVFFCqpgAEdenZBCzlmNHXSHQmrgpTaPKbILOpwFgMCkBrhBvvkzrDqAxylHkeGeKWUzxDARVMooDadsrRhflKsTEtbOkDoXDGZZEjjqcJycyosnUsYfdvsruBUzlMrFnEtAzvdDrTJAJLmDDgErJCJoEfrEADasqdqZbQQRMwLkQctcLewcCxPzVcYFkytCYETpnOKyOVqAVntqSzaZLdjEoBbYmHVucPfaGSKpIUsWlIRLXnPwrSOcAyIDcAicsTaFjlhMdIohFBRMMjkJZVJmqxUukHcFpfLlfQcXNaRrFynvTiKgjjpHAKZSPnoJgudMQVJqBuiSmmSKgkNgHqjXKNilCEzIHKdOmGcmXSmkHQCIWzRdaxIjJGUHxJUAgluPEoseNzXdsfVYImaKPMHCNfifiQOVtdITcKGhaNmUeOFkrsgqGmjLhxxWhwpSlCMvZiRvLhCZBVQVBSduNkbaGzWFLOTiULkHpsJHtwgQahuHVTzNkFYpuwsnNeGLaNFOzSaPypQlkhmZiHSnPIRIRLichCSDguKOCWXFAdmoVXPGEcsyEeqjNBBdeyReizLyusiBbkIAVhAHIvyoDcsbhoRPpRkWpNQUDuQczodcFGIEFzNbjSnmeOPYYoaeDfUJQpMcwWwzvoNodyCmoGixzvHluvDesapITPrKDZxegLEnKRAKOTOzPaNziZhHZUPtLDcHZdSrbfhGVPrGFxRnwFJgTiSdXzXukWIgfpQUioISTjOjrVMQZmziqMnSunNTPDgNIkhFlnmyiYLFFCxxTSlnvAAqBEgkhJOocSjgpFtfJnbGOTCSAVTYyNgxwmhtHLKhvMLYqKkmZtIZolGXKxznaMnXVSfUGUvpRgcXZOVmwfoNoueYLaAOMZhbxJaoRiCWQayYAzNHIqABjZApoVeGauxqPuOHirgqeeEbowQcuiBOBmNGQDHooYKkwsYXCGkLuIaEtTIJGujrxPHpmrQqiqhCqKdwiGcKNSiuITbxolPZpUOGuMckPTfKnMIJawvGAKkXumknorckmkrImupnMtVgkwMEqveQRNEvcwseWUWkogJVHykbOuGPSMJDcarHiYHUMIIGgyoLykLtlWltWltljHKUtYimNlPxVKsuEquVobWotZxLKrDkdVYlUmrrgNjfMFJEWlTDgLJTWWJjLVypjzPGTLJCKUAAXuqHXCUNZmiFXeBIqgiryPkRCoJZTCQRhDVSbJxIYDpmSaxOuoLjLvLCiqXylgeLmuurGFiiGcliiiDycxPZbkuuVkQkMKzfihcKEZLpGWWAskRnIXoMXtQQGtjQoHsJEvqdkeQcKldUgDMsEUbHBoliSOSvvfyvWTffERUCTTXdlSudHgPvfXzRoLlaMqBRWtUXpcbTHPblaTBbTWZoQDowjNVAJBhACHaoIYystezEpVBBWACKDtBvqSMKvnbEfubSNsuyecipKAfZJvBpAEfVzTbCQeBMVhmkoPgXmjDSCFAwnNofvzulkZlPFhtIqeGuEyljewLaYyVFooJYegKiZlJUChXEooiNSdThqvjcDMDISTkZudHSrcYhtYNQGISEVQpftstGiksETztzTCnxJwEIDUkVPWYtCaQsUUXNfMsuiVBSJHMocKqyyrwAGmjXCBoUNFHQDmCDCpcnvSfYCLyBOUNCjtWvSOqNochItHPxiTMlEVtyJLJEyDHXXMHEFIKHpMrGOMeNGCtFobbblbSEBBKzAICEuudJHpmKRUXfECvOeQvnZOsZgoTCloZeZvufajpDDItPOJqqldOTnqhjAJyayrXmavtiVryTpwzwowSqTFbAulVFcYffuBYNxOfVBFYGgvhreBORqlHrxNqHpDlNC" - } - }, - "ProposalBase": { - "id": "47", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24914473521" - }, - "submit_time": "9936-01-01T01:54:53Z", - "deposit_end_time": "9936-01-01T14:13:11Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "321" - } - ], - "voting_start_time": "9936-01-01T04:09:39Z", - "voting_end_time": "9936-01-04T07:28:37Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "DToYQDMGpyahUFEyImhLGAvtpsDWSgFnkZZflACeIPPoCIedCrUOjwFQWDrdAqIWZxAcQfmrowibaMuHQwkJRANqnmJumoWAYNFXpHSZHyiQOCrUWHiRsCcRROijJJXOtTsNhfZiNyBo", - "description": "nTnficHzaRoCdJYEGknqiWTzxZqXVLrUvImOPmhQBdesnBLwDvxqfiNBYtnrzgMCiayMVaMKIOyCtsyfmYLinFkgRUsuqYToIThCNdxKyrAoDxlHTYfQGdvwqakOIVOqGmrQYRpzsLABqJKqgAJzLYWNWWSEizejWezpNRTfOPkmNuIkCnDQPUTuLOLVDoRZbiipqIjzbuwwMXqjUSwYmUGYcliaTNPiTnKybXzIgXZVKraeoEiuXztUPBszHPJdBsvBFkEuOERFZmsPiKHjjCAXKRnQModQpdzPZXyvjgchtIbxuArzCgUordxyyrIjtuySRphvfrFAeiZXGLJtPWKXiSFFAQXxcfwWzBRqmWYELKmgJotOUlFBmZVtDWGBWYLfrxFDEABGgsbXZFSSXzCwZxOnNXkmwWFaWKIhofUvGHtjFLglvmdrteAAKzOISzHrRcIHIpvetvLtLISGQhDZcXqKaLcXbjIYcTPWUvGeIlsihkoCyrzkfyQVfCeonfwvSJBdIartZoOoUOyAncfUtotkStNAQRfhmfgTWZvJuHjlXfzFUzARCswUIQEnyedcthXwyYEEcOPRDhTHwmsgqTTbzlOuyXFUDupIqWQwDrBpEuBumFlCfLojiqxiRYmQYeLWsXDNCFdpqfEsdPLiINxPTXOUlFYeYNoJfDFOcFtJtivjDGUiSJAZbFvbefrcOUWQLMTLASvHQvkmMDywGWhTETrRHFzYoFDUFLEGRHuCLFtEJYjmtshTTRoeptRghPjkAfabFswUGvmcLYBlSGKgXbebmyssyCpfftBTDZeHlZxtnqzvYtmwtEJABwsESWfxeQYLhUnijnKuBOYeCdwnrSiWrSkBPSXvvGRnvMsFARfhpOQdmnWiWaaIvJxsrDdGaHgEZfojTDTymNnfwDFAveBbValRYQnPHyTLumEANVHmncqQapiunlUszTOmrplKKrOuoAPvPxidBNpQpiUHmFnkGBERaRvRBqOiuarUaJxTItxPfptzrcnfRzDIzSrZCpquKjfpKTGzKQzKKllwRtoPGeINWjYBUOhXHIlFoZlhjXFHfVfUyycnHAYFQYaOXNtcNnvIgrJTgrPgBMnpjXocVuQzobFKjQQWMaUZgtTblQhOOQeUOcxhumNDjtoBOrDTisYkHzYHyeWcUfggNsihpRcLbPHdYqtHceJAoYtEHoSJmuInfNQiPAcXfYYPduqrCgdQPtpMDFwFeRDoYlIojAHzPgOYJotjfxEJHnnrVoHzBmZLJWJZBHNPnmwmXDyPxuPaKDwXtLSmrNqOfDdgrgONZuiiVwOOBKlBAgefTNRHZvvpgpJeEKAZuHrLGtfsxeowhIDTjSRFDrLLcGipGVshHpbpdymrTOWGlLrGhcLiDmNoyfvzcRxUiILpKwXGovMKenamTyqSOfPNZFatveFeHjPxoxiFdmFBisnTHVbnUhHTcHRRXOIHVXjDgPnGvVOkwmUhsnlVzhFfWdTdFNEulJSEeerOkZJZQPiTfZXKgaNqmuMoGACyOxxHjEyXrxWCPVTAtmLVfJQvTmgPIgrjJPUYHnRzwJOqguLfxdMZMRFaKFfnGwfxCSTccnPvicjCMQQsNmxKKADGWHZFkGDbPFSlDdGyGPeoSarQZMNewqktIAeltWuVILiyWDDqwsPKFwZuBqSpciepShtcHBsGYQbGcoMoHGmhswmmJRfdotQOGWvgrRzBCMWeQKwpghFNdVBnkGPwdZRoCvwjfLRFmVsQGzqHrJjhvAyhavXfzQYqkHAtYvvsUtswZzNWqdijnfNGlylTZDMdFPqEesrtcolaARJuhZbkiepBSCMKcPqIElJFAxclgFabPVSBLeHFSAVgnrbQKdsMeFdRqgChxtzZCdHLNhOuHxdXjfvSMjMhpeSqljtPZoGWGYcFxrITuigGNaCZfNTMRrQbmazdGqvfcoQaWbEvXSbuCdSTFReAlFWEsBgukQPasiZOZKhJahpiNsJnvRnXEQYxoGzojTdicKaBkLVxHUycjDphuVGBzyPxkANLuEJZMFEGXGjgPwNJGGxTyDJFWUlJswyywFrTCQgvLxyVfOnhauxkMVOapmaAafFEhBeWluralxDviLDObPywnMHyNomZPdRHUZsCuRlaRCHdGhwynxMcLzfdLAEHjOSHoheCsMSgptbmbCTcaLHIsIQbqecfNgbnupXrtpcFRPAHmmDqsFTgQzLvrpWToAcCxuBsoGvIOzSAINAbwgPsiiUvQiGxMrHRzLXehWEXfQWEhuStPFmXXYwRDAKsmOTtwofhIyfMbPiuncgURfkutgynYxYKmQrdnhspgSZwnLPUYceESSEPtCdKFqNRrupuEcmmBFCCFRPfptbEBcBafANALnVlQVQwyUQHQBgjQnhjHGhEpflOGSJmnMwgGQOxzajeOUXleNZUJPlKTiUjgLDnKWsSbwaypsnGAnjESdHVCTQFNUSxPbycLalvKhkrbBQLwqXFtqPJmqAqwAOeQIINCksYFMwxCCwwwOpseoFyFQsZQPZalUxiIPchzTXzvocVoFSDlqbshoWxUFMwQALNqUwtDlGIXCNBhgaLyIBeDrBcFwXeQPMjoazUQnhJRbiuUddaWlKIABlDjfdOTWkaxiuzIPbovrlJSBmIlhkyYovdXKqsKOtzpPYxEvJvZuYkfxKkRbNalNkqtLVYgBQzqVJUrGGNElIakBgQolxHzlVaFmrYKhIneZmgPckudvFQfUEmBbJAxXTYlcaNWPlHWuSNcSKVDeDSBTFdFrzmxvMhPRNCSgHmeagRQDCLSHLkdYWTovMCtzxTDeelgOjklzQVntBHuBIfZkaIhKbDpoutrYRxKVRNQcELmpguNuxHnFtrNnehKpNrbtXZbgIRxXrGZRJOAKBEiYUXtMLAwfSxHxzGWIqZXwaJMYBbFYeoiCggVJrWVnAPnsZqPtBLhJPUmNCwBKUxwXImvVKBUQjdJpkpnPRRqLTDxBbxxhorrKntVOurUtGsgLYdvigApLgwNFGisVRVcCZukKMCrEUpDwSJjCsRtwKAxxbRWDtUwzOTJjCAYvrssdmyvMTSwnKoOpTanVpSYkvjPyUbaIwKELDilNOIeOrcUSjBhbbEyIzbALbzyTZkPsafcsEykhGQMAlkZyjxvfSuHJTgkvsJOqPgPIUaahZFmpbXnyetvzJGTLeTNZsbnkQKiyOjDmAtesUgBOxgFYCqNDOusgKSjJsfTDVcxEZlwcjpiPYQZGyWbISDLfNMCnYcTeGiKNlZUKcvBgqkQgwdTAdfDgMhaIQRUFyPtKKuPKCyWACsbPBUXktzyMYFTRAfPawHwOfYDhmGVwXWCtDFVInDqEugTDZLDIOSLrnmeICqdcmXTIxMdHhuOJjzxkGEALHxwwBbOMVDqTKTcWGMJCeuzwhocbSHKLpFwwSvjAxwPLYMfiLioYfpypLeSODPvgItUQMyAoVbxoWVKqSwRgdhrDYYkEbmqTNxLuJGyFqZHEaNZqUYZtgsUFmqannodZNVuGaOHhKaQkOgzjyMhBKfUDTAOfCXVFiWCRxDVgTkiFNjepivKxKpRqxccKYDwGALoVHlRarJUfcJlFaamWmyrCbyNWzQflEyMMWPaolksNPyORQGcgfwOkPedRIrCMSpNgEfqEABdtZNhFKWJzumuYsMoUudZrxyBHeSVAeZhEtJCZkKxVtQNxAwczYRAqOpvTjMqCUATTBZLBeEPMACjfMDqBuHylWKECMkwWEAOXtxsoulvQsWqOryHUukAMwOggduIiZtgOzVqrPLjpjmhlIylrYCVJzNoLuvKrvlRNnIcyfwgkdHNIOtBPCLmzuvuISkWlzMYPuVIsHZBCTJnqyxoRdBYwgffbNEASdndQvXcxJQJxKEOKRgTBLUswiFTpyyepsKfmlvgpBVZWqJOzUbgUyvUuRgprhPcXoYWVJcDninFrdpwTouaXquvyaoXaBRuHMiYKdbGhocHxSznKCwnxAuwamTCvIUWSHkcAmPMvusKgeJcRNQdHyvVSxapwGyTipKqACWXmIPWowTyRrkhywMuDOiusMArXJwJdJLzRBGyDIjeSAhbCmNSWhhLWQpzsIzbtENheFUMWTcfEbIxbLwqcdNavyEOETRWkLoOtpAcWXgdTaEvyuzyEPhjMYsgkaRTfnWOycfUWEcFvGWKSYkjxcVrUBPTWzMQGCMMgNXxEpiWmKBuzOfQWGAjeZoFdZTjtMzutTmgIuXCseQgnRlPAjZRhtDxzMQEIqhhmcVdLldpBSodPxTMVhScRDzgkifWOrUkYdVwPmGwLjEAwRjXfLzevNRKGOsljgEHXDeptoSAdFsflhdsDSXPRKFMncRuJTGypTkVWWFmhWqjbArBUzKJJayGKyPCocVGoIEMYhMsJPcLzJWLVDJRSMuAwyFvYjBXUHaQbllXjTxocZrdwJSPLEXQVdtuvjzgkFvdgtqXcAtXLOSThHiPcWtXQlyxyBWQHzgpXnXSxmaeKbpcEHaWJFVLtnZzSTDcWSDNJCUYwynevCcNQpJsinZJoYARSBTGXfmOoOYrcWScUcaFeDwzZUzeRuyMxVgJXuysDJTMGwkulEapwpVFquCQnZOnygpVvVCXZZWCNbSiKRXXvJsJfshfPhydFoKzLciyUQjfYmCUVaweJKtyjAJHhpsWxDgYFOqYtcbzqRhyRYoOeHeCgjghnwvCkpxvnxAbYlXdJvjBCoOsYvSisxLLbYfafQpMlOHGoYhYDShEiWeYQpaQMOfeagOyhyIQbDbiVTJUvRelwcVlLaXKMmQMUejhdtXXMLdlJNvvGakIXqPfkJPOYesKYheCIuDFcESQmtKsKnaHGZFIgDSAmmPriwTTEliEvDNAlrLYKsVcOlcywketRWlNaMerzlLhhFgkvlftLWIsblRbNlvUGuYLsXZuBOaQGwXsaejJbqoyZRKjwIbLClkFbunFgzM", - "changes": [ - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.790000000000000000\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"54\"" - }, - { - "subspace": "slashing", - "key": "SlashFractionDowntime", - "value": "\"0.333333333333333333\"" - }, - { - "subspace": "gov", - "key": "depositparams", - "value": "{\"max_deposit_period\": \"172223000000000\"}" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.900000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "staking", - "key": "MaxValidators", - "value": "38" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"6\"" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"339868000000000\"}" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"124\"" - }, - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.140000000000000000\"" - }, - { - "subspace": "mint", - "key": "GoalBonded", - "value": "\"0.670000000000000000\"" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.080000000000000000\"" - } - ] - } - }, - "ProposalBase": { - "id": "49", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24972834479" - }, - "submit_time": "9936-01-01T04:09:39Z", - "deposit_end_time": "9936-01-01T16:27:57Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "391" - } - ], - "voting_start_time": "9936-01-01T08:09:55Z", - "voting_end_time": "9936-01-04T11:28:53Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "KqWOmEIXVnbYarPwshcafKDmWoluAlZjwKeKutGrVXOEZENnarupfnJPRfMguUFXMbExdErUkXClOHicBXbdVkxzLZPbpXavLVBEjyipekjthmyQBYeLUFTfHyxTiNMVGxyrbPgzNdjx", - "description": "lOnsoQypLMgGqYVoZfhsrAsJPznEgJpLaIPQFXZHabiaKHBywZuvfcmuiiUrTzCWSLRkxCFWlONsgxiXabKtXSoqZNjXEEvEoBaPufvMBgnAxwOXwNdzhFpaoBYyrhINwXRdNKGydpdpLkhOHUwIXTBjlrcBDEgJCJYAATwKAymuTfZJRBEdXzsBDiFFjieFFlubvNjBLiALVtcjbKmPIjfmzxaDGtbkjstByzSvTqDREjnoenWzMPSSoWojMWzLLiiIgSHwFrknxxcWPBcSuJDpPjxHZcgYDHGEVJkWxSLqBkQstoTCJTtLLTvuOzZHXnqBwpZAGwyIbwbqaTmWthREoVVnxIUeseUDqGJkGANrsFrQgyMxNvCHqLHwDhnNANGOxXPtJhTilMrMkfpWaruWJlbcTwchrpOogGXTtdZinyICSoiKzdhCnQGabAoFZaBemajOgaRWkYbWNfJFEEObvdvbzctJkBgOOxnQKKgGKPMiPfBbPOyYmqTCOqTcrxMqUnQDOrsxvtPAbOjCjimyLmAPiwwgqqkzLffszMhxtUsjTddMtAPSKhZjMHmXCcjYCwpGZnxHWdVYnvNFleDYzZNsVkgeevWjeMUAeQnVbxEvFBrjNeWsFdFuPrYMmUakeNiqBneSssqwEyxeBJDzjypILzZPiagSkAZpPTMSPpzMQIPhvQTaoHPSZQOBtboJlkhXqzznHBchYXQpIeZFslHNTcvuFtypChiGgMDZsZnvnotajRElzOyJutYDAPCmWBkXxXNgjUomSaFNKsSqtTfiDUqmhrtjXNZOoqhVeSZcKtgcZPoTbSIZSoyIQuFkHtcuwqMDLlLxASIbnegPZJraDFbscjUgZTdncqNqjuAYUeoAHFxMBbGfGVNJgRKPgbveeutAJwjsANmdfkoZKyBMZfNdWCnGfHAISSNVXmajatKfYaxfaJBQlVUxlZjQyVOWIoglxBxvZIBkxZchGgxHeUPtiSzicLbImOhaoZpiApWXzAMzhuprtfOQWTWJxMIPWyCRcEzZkldRctXWAQNGmixBzFaAjtufqmmhSgIVNPQuKjnbBLjRMQgRksRjuEWZUalUWptNocsfloDpdTHSooVdFELzgbXAowAbhsIwzfFgLvMTTVqjGYMNMKFxXDuviTzhQzPkDEvxgPRZytsnhuHFUTZiuuqCWSQCTsVcXUVwLiiEIGvnsoArwTFCJxbqXiEOtyXfhDToCfFJDgVZrobxrtNnrUPzjyNlSocVMJIdgBECSbfBeIfoJzpPbrlNyLPSLFCYnnRIaryKtbwwxhLAjCZkjizvKGgSwQxjnOcabArHicnhfNXuUJNOPlKBvMcKRkXJxSOglIdrStijmzQjsfxaaIFcKGovanlqXkANVNoxmFYjueprvvdaHVgxJZzqlozRqepGLCxJMWWYXkiiqRJZMCIJXHhEuJUNzMmKlywewjJwLGfFyKgKMtpfWWJwMkuoAJGicYicdJvVmlAyqaxvtNZUJEBSBFWYOtDqUAhBophTuOEXhBnNZaTaQGBuDEPhYewJunqZbJYAxsDVksdfSXpLNCxcplftNWckTjrjmiLtGOerzHeJRVqgDWaimBfBiKlzwCsQwmCHUqBYWRreqVWesTOTAcnwedimrSajflynCnqZadBEKoaVhWJeEBCCgmCLPGBIQBFKWHEDvChiJCqSVCwrikvgkTHwxQJSZqaHDhpDEzNUKtViFWoDvDMMDnAPKJTzMARDyqOqASViTwVpfyPtlyuAuNKsHAkghSSgVokSiHmPqDyxogKpsqSlxHpgfpLULQmTwKeTXZPoHzTOqkFzLfEgpOICWbAtjupWtkxxsfzjDIlpJKXcUbgzqPTcDwEOgdTDVjSUWJTjKyXevGZvLdtZqwFEWzvNHZSLTqUIJvydRHcTJImazEkxRRzsCgHOoeUAlkbMhpaVnOsWRCcZMhYNsIDIyQYubLclPxiDSyrAKLakLrZmaKxLXCuIdywSOjlgsSifPKwqYAWgWlDBcjfoEWECMJlCsjbBAyMyebxxZzpAWreeqhowabLljzcdRndhybbpkClXpKrzeDQJKQezezXMLxTTYALpZeanFYkKVSBlVwADsVthOqLFXoXrsKMunYBXxhsYOBlNAqUFYnzUTyrEwcjBVIdEXfbUYhFGKTfdUjlyJmVpUCXtqsTaZSWYwUhEjztRRjxKAlnYGZqqIngYMbhLfFJEKTLBOJxayDSouZWTpbuLduTylNNcxBYgGGZnxOnrmYTmJgElLipdixEWjZATpgvkeIbUTfOnzawCrYrfEMVCDHSZMdEeZLZpAoKLYhJaDNaTPBpEEIQWQiqVuWlYIivkwEccmlXdAvPtddNlrkWNtGiWmbTXAOFceySGrsaNvqYlSVSpilgbDkOgHkzCFUjGRxRAItMlWcWDnIkokRKHOsEvxPATEtmHjHhfHoRXvvXKdlhYwMvRfIaJlyWgUJAYsGhvhfqZhDVtcpQjDPPdLWotMKqSkATjSrlrNjCJQcFTpsGySonBMuThExzjBycCeSBqQufVchCBOlmWbcpETfyFlXtFRBYhInvpHlLvBMGLQlMkthmnTBxuRSXbumeLGdWVTiVVAjIBYbZbwiqqlxbzLBkmRhHjbclxbfsaiLlcBgikcIiAnwYhBAAeBXSRfsTYqmfJBdZiYnsUWqiKsKAfLkhhIOsNGuVlxCGBToxBmhRgWyaJEvaPmhHNSISwnMvahaEFvZtZZVAzODuVFZQcRFaujvQSvxBKUpfTiKdFSZeBMdLBSUHffLzRRivnhgJpBnqjyWZjUUoNzMXkzqvGoSAgylyqOrsTZfMbWZlRppJdnoWcdrEFYAQBzhCnYOismWENFIJWkLrBkbxJakuwMMFECDcGmInWtmtdfIiWbwDWlHAnRrmkFIoOjoGdYvKVlCBDlEHjprwwVeMEqhKcfkFAFLOeeIGTFmoTgzbWznfZnKurIjrbvArQlAklHoLaaQONBQFOXIdYikbPtyKYEtPujTwcEZQmdXXZKABdvTMcCZFZeIBhfehqynNkOjwCxrqfRbUbJQrvIcJWMwBEpJZiSBlGAsnDKwJsKAWxxOGiWtDDXRwGkZAVDYUfXTkvPjASlkKICtqUsbywLmVNTLDFjnIQurePDJNjTKyydbGWlKvehdHkGrLXqDLYNihvfLIAwKgvSqPaHNCsUumEZREsxqczjOzQknrPvQzxfnPsoXZbhhtbEnrzCluboWOZzdIHMYGEIsbEjfeytwgneanAxVlDemlSLDnjVtmteKjcOdHJWiwkOOEuBwvnFNlNKRqerbALkTCgkmGGaKIrQfFEhZjTuPgQGuqnaqNNFmBRamZmLQSwDmIbyNWhkzDXtyjKaohmPBcasyFyqwaFFrMbVgICIvzWIAxuCCveyMTRPzAmcxXsaqCMCflTHbnkjieZhfNmfWtqbRxbIrqibYQKFElsOLBYYXcJMANKpGnTKfOSocXCGAbJpbMAaKNhGiZGuPYNtUSAPzWzhSbewrqMfdaKzgBiyVIuuvULhfBWunHuaQoiLWxPOYFcegejfnuOBxzEmQbXFHlehULDfbrbwjXpenkyBgfsBfrbTUIIGRlPHqMOzGZPiJBHjqUwIreosWCwGnYtajwNLyScCNQnAdrlmgrIrNxCDyPTTxRyCBGQqSqQmcOYJlrPlhxkdMELZGUGqFbkwxwLpwdMVvuTpXePcQOcxsSRfXTeBndpSMrNXMZSZJIbVXnxdvXBOJOSrCZSHEiFEbHnGYffmOQtUQWKDlmFLXeyXRiXiZEiFRtQqZAAoayCdNibsbxSJhZlrEEizbUrcRJiHnIAFnuzGvygGUQbjDsoJvyXCgBLhpgBNFFPWwPtSStJfRRoehDEnOKQDxlNBrrmsfcLRplYQPZZAcsExsdlohXXXUPgfhdDWLIbghvLJUDnRaGeLDfasqtRQPYgvyptYfnaOObFbJUOXWNEsnvjIuRaUqaceBwnxDyVSTMqatJDbmLqQvbjtiPFGPmWImkyWMvPMNtrUMSIanmgerLeriweArlKfowuWaXNNkAffCUwQNAbByCQDICaBQfVeiMxdZOGuFbWoVbwxKUWpITDjOJKsfUMreyoQhEKPbYbJjpqblLtlvLauLOlYSbBpbtQviwTpFUuIpuhRGIHnuZmTqZfjcMxBynJlJsfHNrOsvQlYNmZLaMghXTGXEZtLiXKmLGfYstPdccSRkxmioBmYpbHdnEoLERvstfKXpIXaNIqlkAhxRCMTogSLIrzFXRzbWdzyrgltqzMTRAUbSZTPhEXwyrhAJsgeNxmrkZZhVksXYWbcVjOLvmYwuUuKIiyzjDeIuQntsoPLrdBxHEmaumRxWikRvzCjMfYsXyHxHtCEbgjAAnmfCTLmdCkAfMfPKHEhwRojGLuAsxgSNDodvnjwLvOfmbzadoeilEqCxdJEAhrUeOHNJnLSIjIuExLffOKSHhvXKqwgFwZeMxdhYLjuNzQcOAqvofhWsHkkcBAeDwQeXNMUiUahiELXWMbobSSnaTkFRehJtptbEdtdteWEGBhvRTouuvngZCEircMKtCOEIXHuEiUhBbIrTwRzKCypzzyQZsqquuEgMzJBRfXcqpxNmpfagaxBEpxBZzoKSwpDMLsRgsPgcywUGHnKAIOJDwdFiNjMRnSSquQzdmpatbXMYHJXvkyNyoLlYtshRWLMKujpmagCJSlWBUOFOWPXlipWLHGgMZHmhQzmGZnsQdrRpeoYXINhoOiXJPEsuScNEquEAyFeoBdrTlKgHNcIXcwwSTorXMPwkeaZtPEHUBQsqIvsowZilvpuHxNLAngoMXxKEDiCqUMMdZvKsdhNXDgIDNmBHWHUNZOtaeotwuKjQVsyHDovMeAYlLHXzncqpxsmfUqHKNUYmoGUWZFTZjvKEepilakPCuRtMuHxCoVvbUcHoYSFphbjxaDHkfQSNMTsgme" - } - }, - "ProposalBase": { - "id": "52", - "status": "Rejected", - "final_tally_result": { - "yes": "24914473521", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-01T04:09:39Z", - "deposit_end_time": "9936-01-01T16:27:57Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "229" - } - ], - "voting_start_time": "9936-01-01T04:09:39Z", - "voting_end_time": "9936-01-04T07:28:37Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "fgXBqrbNNT", - "description": "vXAnRhpqBHZjlONvPosWHFScUMDRyJPtzucqkDFSrPGhtPaYQaflFboaaXOcAVVuxKCjjjPHWMjMuwRcpaOiDeGDrYjdWxDvOETP", - "recipient": "cosmos19rlals9yl7q50rfww4n70m26vna9envvsqj886", - "amount": [ - { - "denom": "stake", - "amount": "1061444452021" - } - ] - } - }, - "ProposalBase": { - "id": "55", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "24914473521", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-01T04:09:39Z", - "deposit_end_time": "9936-01-01T16:27:57Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "340" - } - ], - "voting_start_time": "9936-01-01T04:09:39Z", - "voting_end_time": "9936-01-04T07:28:37Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "qdUrTIBHSaGQZZsmAZdIOJRhgDeEUxvWcJrjjWnDbybwkGTuGJVyGdhcjnxVAruCFqOjbspcbloUggaCDGrBelaJXXoXXbezBVRgNhPJUbQUegtuyuqMEJokwALMQbbdZDwycTKjYeSb", - "description": "fMJcyfKjQSyVSuqoRObgZnDBzGahbKHcNqCYoPLBAhJaXiqFyyDMQtsKFCXsHkMQjPQLntENobjaVIAJMzvYZPhtUWklEnPfIJHVEAETiHtkgJBueYSvWDDLwmKqSdHsdiRecFUuvHqvqkGEWeqpyAzNsIHHbFscMTcWstgydLMabSdXkEpZbkjwSDeRfAQRxxMAAGhwHXiQUrHGcSAWwTLRasVQcHCzHCMiEBIXcYRDTYjAEXoOpnxbwUBELSvyLtAPgkocmmcUuzrBXxtnbTSKEQhYDeWLAbdaSdduMBDdgFxGUKpEegoKjkFWITrpImVSdPcCPkocLBZjEpLVGnqcPzMLVdPFUxXBvsrDyOvbFayHKGpYUsNnlzbXNqEDMyEqgQEsnoIqPNdzqSnjjwkqRJGEwtQuGzCABfAJaSAwBgxfalLfSpRDHBBeOMlUBxaeNaLdnPzMdNidHoSXAJOOWnhhgHkYksPhgSMVazojcjBOmanKxPbRAmmjJUrcUxyTixXQGFonjotTtqfIERUVrCeWpaXwTYPcmIqOBbwuTiBfqhGlfwaWvXngHFlLgVxEvmDUUsUJFstXwHepCLmRMmzkGKXYylVNrHsbpGmwVWpgltZNnycqaaLLufhrZjRFeZhBdPEjjCSIvuahVrHuQMCuxBcRnCALLTCfGJEKMGtHOGKCxjcyGdEWfrmCexqyDMOvogZyLyCQhXWGhfLtmxyTSBeeEANfdcANbSwDPXwtjmgPkNPkDYugCmJJQTDKsWyakdvkLnEnnAHfAXpGhatGmsRjKaULwbgrysnsTnKFXHysFbcbIgSiYXVvbWzofkjJAaEzBDMGOSHKMdlXjAuzIKkyXejsgEagafcHpaZlNOyeuinosvVHIgXPSnTZysTAAHfiqRrnLvmvMtzUvyPwXrPRFnszrTqyPeiyjJJOAwDMpZAVeVBxUMGZUQHnRqMllTxWTbrSZvSkZgGXYInTYvPpGEtGkbryJFHgpyHUzSKJUaJDbRWUmqPuizoSvEsTRlSUXtVjzWuDCvOBlyvosCZpbRtVoQjnqFNJZzaYbrqywuUgEuinwfYIIcntoyBLzcavjXEGLpvAfAEPGjSYfCTtnVIKBLoZOvmkfwOtPDzZofVlVMatahiUDsyqqViXphSHicRkhMkLgPdgJRmrAAHRPaSsxgbCfcDFGSJnRCSaQeWidJZFZjBtjAnCjBpjWoztxRUuVXqoHxnJpsRoRtAByOeLwJNbJmSUnvkqzBhSbVapzSQoJcZutpttRsYMyUzhrwizplVJcHYQVsvjyHHBCRZBHtWxZaBQxfRhtwsfAGkmMAPtBTihJcTuXetCKlmseSizIfSFipoFowmaOPsxtaXZBlMoepkNNQqmjCxqZLeXYHLYWowRzLkCfhHdZvMerHUzyofBgsNCAkFsrZkyFqGVPhBWEThfZldaEbLsagPJqziwtrGKQpbnXvVAxmeSXxRLDcYCttiEJtsEACSWfSZTlEHijtBQmbTYKzZEQABmnyFrwueQiYtsWSosMacaEOhlLBADhutvUoHKVdsHNkCkdYtxIJXvlrUPIzwyJFyAcGtrtnNqzVtsarKSjnfEKVxHMEBVrofJhRgdOvYFPNZhCnEhlnkfUdkkuyCdfKeZwsNLZgfhJrDTwdLUjoyLTuIjBswvbByOlTJNKUaJiNoBycKXyRASGzmtWnQpupIBPcBOkJqVCWWEytMKqzvPqapgqCDKcnkKirXzhzpYpRpxqfiYWXgXjJUnfDNwRLqKDtfYLtebuclOhwXupAcpOtWrOPMLTzFerYmXQRxGICoWkLrltNCbMGQenRQDrpOsvfyMUurtSGIBDVfutjQJtMApAFIKfTGtyqlJKYMmjmYgapfySXbjkjRCtZvMVZEubrawwUEOJXYFHSWBtBzWVXGIWQsEGPdlfwTxIdejUBcZICuHFjcNsTsYyYUhpJhXYpaSMeVouwXXGPEnvhALXcUvdvRlsicrfuHhArxmVqjHMpcWdlnFdNyiDPGyZeSODYqJGCreEBgskeYCEJOZfoCBuolCcCrbfdQIuvaYgEEgNQISBXaJTlqsVuJXfKIjPJMcTCkNStInKJaQeoeOHAnfbCpPgDAxiUlxYGvsueuMshEYSceZAPrAwchkyWJxINRoVhqkzrWkPmmNWOdMzUiguQhFTcjkwwGIMrhuGOwCZLjoGSBmcossoWnUtwwyAeRWYyLYJBTrovuLzunXrMBitvNGGZrzhXTOPsvCBBLcRSBdBpOjfVCEUVuhHQDCfIVeNPXXfZdZsueDOAqVqDNoXAvekwqXzsMefKWuLQERrSClnEbNfpkihdLRqZBDZEGlwUqOfcXccJjLMsvSfSfLjlzWNTEpdETfKYUmDEygLaXsonjQnemwRdDsSqIMoQPkDboGfIbiGTLXUFGytVrMLnAoEGaLfvtolpSorIQKgxTEjUZkfthDsxilcJmBgJCuJiZUdcbIkigvIcPNFJXCrMbsTMYneQsTSfoeKnKPRGqOXfWYEdhhgNZYcAZkhMgnQQHBazMXtffnHWDINgeAPSYHBRnTylrGOOTxLYhiWKWLSSPIbTtLxzJdxZVPenQdhUeEDzIoSarmxeUPCNRGftcCTirYahAXNoWSQjDLTMTVmVkYZrYjGwafjLubZSkKYhTpXqFIbohpTIotQcRuBhYWfpKYSGjgzvYvqhfPrbxLKvtJRhSmLbyMRbDonewDWptzsZHDtINulkUEBKIJPLbOLtYGEKTorIpizsTmbxcPpjTNvhVBSSAMdlaXfakeUyPEPjTnNAMfRmcHhrITTMiaVQBdyqbVWXrYhGMJGPFhwpSsQrmXFMUxedVSUHPTJvbuPaPQDMhdBTxeSCTxIBYfJPfAiNnkkFebOGeRVlcSnqWSuZqCeZUvNZWLcFFdEPvbpyRaDUHavZuXFTPRWdPGpyUmgVQVCrFefBwSsZJeQNiPboFlsVnxZmzsCrMkvvcVLmkCToQPRGHQLUzqXCzzHXOWbBRAVlrEFVftIyGDjaErbcznLLOBxdOKyezbVBQPAfFMiBSsTcczZNaVJlLFiXzkWlLEedpLQxxepZIMnqPFtxGFDvCnPzbnkAWSlYdSIwZJDRXkLIAZLRcBDdhjsEUGNZCAngvuiIPvcxVQqFXtKpdQKOGMFRoeXQsYDspZUhDrSlKnEyuAgRFQjydIuDfiJEJJwoZMuaNFKONJLabFGcxLYiuoapKQqUHEPgeCjEClLrEGqpjEvXkcDCdciRTXmNrSGCIzstdrofXDeiVpOfEUoetwWMQHATAtLvFiaaGbmwiYvDlUfbYdrtYoenDXThtVZqNjhgIBGEnZEqFEOiawVXJRaPSnQjmjwAnAdAGLqnqvyHkJsuvDerYuXjGcBWwCLFUQqQbYshFXiwUOVypCtGIyIwbUoCRrgWMcxQhfQDaoALFWlaZgYzZspqFRIbnzQTBMvqhxcjiYdYesxMgZNnxhgdVTjOzWWhCoJmHaneSvwehiHnPXIfTTlqDyRhEbzCNquKLqiGZMcZyEmViDwgvuHIVhhhhhgrpLtWtyTHvQMFHdxNGzygtraKTjhwDSMhMhFLRkNOcSyecSZdBLkaugCGnDgHfAOCkKZMDnBxlboBxCPsTaXwhdBrvBxNOqJHbOzCbAmhVdhluVHVuqUkmqQERAzNCOKDMCIeaUoTBIcMuEWULLSDzuFWxLcnHOQiVTSnFPywdphLtXuVXkKtuAbSRFxEvvArViitSsWJJIDjDomskjLChslwsJNIXvwiILlqmgMkZifwhuNHVFqbYibxolGpkqKpWIuXRQWwqDJMMwsQymMHFJTtCpmdmHsYlZvzBNDxYyIDmGyOaTlsQiYfWGltUrpHwNRyucRDDObdlYFosZGdPZKpDAmQriGMmtbKoMNmXJjvjxKYASvvhlJjdDcrCHzfqXSBmvBYvcrrdIttkrNGaonloMnAsOlilbNrrCDpGVXbtJvpwiloIeSTmkiKCbnIVWRcZKvNMdMMDPeDPpNOziuDMcwhKVSxTLPelIBqcoOrqoKozhjJBiRysHGCADViVGZtgytSMHkyePWjoYtWlHQJkSQSXBzGTyzpoXrAYxGQULESMVvXDoZIdAEhIPMFKiBQHiCviORWiUPJFKjQAUZlDsxPLUzMKimiqaJRgHktHITZkiJywnmwhnXBKwgdlYWpykkmfQAnnfvXEbzoGQFGxMLVfdJuKlQiDeYDDumBRjdLpupXhYiHOZeQqFgyPABdwTPaaTxjsNeMhfQjngqVAXzjwEmNrSqRelbzHkOuFUMmhwDvYcrtmqqFBRGrvXcLOiNKEDAUaamgMwXgPbKKBwPAKmrjPRqribUPFNIKooliFZilzpVYCMYDevqKJKqSAINnCgHPzENwQPSVozcupBEzXmMomMbKILHvQuakIPmrNikaUONurmehCXgAJOhOZkvOkUpRvIuODRMzCvVGJlCiMClRNnmeAJyTjgZukqkyAJzMlUNmgVOoYZeDqkRzCvqgSZPQhPTxCBGXuuVtpNTpOcmXOMUOKPsBsOKRIkYiFRJxAacefyXcXsOfeoyIbaIIdAbKRAbIoxCyuXLRAzymILFoIMXpPbRdalUkKUYdzioldIGltZpFtZybyCLCJyYOpbBNeXAxcQkOIneeXtxHVcRcvaJUrIiBDPYvKvVCrxMYDwfbTMheRpQNAfiIGZLenskEiSJdYToIGqPKjqAOhOZPubULemocYeFlzFWQFJRhILtEAGNypEwKhbMPpWjdpRMiZJPRuPwguavAZKjzEXGcFHJOsclVAcjZigLuErMOylKGWrvkmHHQwkSzQCrKzAnhhfiHEqMsJbTILYVKpBtuYYjUXckwxgGekjccmozphLqQNLLHdsrChuYSbpnbhLlkChVyOJIzbAVKdWcMaOvnhrvkXYGqPpvExMWGiqvuXrTZapxFBZRwyOMYQaJgpC" - } - }, - "ProposalBase": { - "id": "58", - "status": "VotingPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-01T04:09:39Z", - "deposit_end_time": "9936-01-01T16:27:57Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "241" - } - ], - "voting_start_time": "9936-01-01T16:55:11Z", - "voting_end_time": "9936-01-04T20:14:09Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "sskgihpFEtoGfClpvDGmAPzkiOXSNfIJbvGrLCeNgenOvbMxhIzJYshGmsXXiCQCyilfxZdgPRjsDYvDlrqRGTwsxmttNBIPUJcTQSnsrHIdzXxDvYVPEYqJuOeWntblYmCEbjUyitjc", - "description": "cVcvAaxYojEpXPwiqimIloBeClWrHPprJTymCGYangpkQvtjiTVGanIpjEwVZWnUDiplswnXhVJrskUEoluZriofalizZzKuvDbZGIEGvSzQEAwZKudkfruyGsvuekLeIMtPViqLnKNRTDnPGEGDWdUyxQYvTlVODkSFsTGfOfnZSVztVoccaPSAslJwfexURvKjdBHbHkImCsZtlTJWtGHsWaCErWKRdbiHAFTaUkTssCbbAXCdWIpeQUmJdWYJQclsXMxmMhjvLDVEcgSinULzhcsDONZrKwlqpAIjCoFcFbHlInnzPOgylxBJNTswhfEgLjqsXewopesuUKIOSeVBrihzozdDQipdolmSiyYzXwfVvlyjwpSQegsEBXExSfmiGclzJxfsurnOQAeEXQqaWugtMqLGrIAUrwBduSfiZpDFQLOMdANdHDKmrYoisALprQpkulSLOKOejSxQHGhEtKKNlUUqHSnjgvRnyeAxbecyyXFDEkycMFxFTCguBigiciWKvNdHiXiWbHuqOJEfmumIwhkjGScsXWYxcNuWRcCeuudOPcXipOQlLSTXToGlJrpmbiepBbpuIKrmLaLEhswpiCjyeJUAhVNSkNqiMlCusxHWxIIOAIrUlprQfILsvitcIhunuApJCsjPYVDLrkNIBAokDlaekXIafzJAeZhURHZcWroAfMCQMSKQOJapymLhRCqcgHzbRPALJDBsbNhrZtDxcVQIYnUnTisGfkUbmXRkTAmECRrnIUzGNeitBlWGMyirTyNXiNXIxUzsUuONvOygasRooWMmtISvypHXlWtWmpRUBKHfTcQpdYPjUxnaXtOnfIOISfrPyfDanmZuXBBMcohYDeaRWiqEjvJeoRgbGpyWDwqjTkoYZDXhGdFKmTthqIFqztDALPMsHAONxmzIETOVoYCGOxIxsBOtgPWDMxLcbOjoJajYMLakynSYXxHFbiWIHTIZVBhKWjWDuOBCxMUwOURRjzuBhHFyncKBDoybeKAdJwKPfjQJVsQPBgHqcNeHOJUUgSXmUQeTRdPhvcRMuQcNqKXcXnHCRDdJGcSdEKNlleFvSrXxaRUngOCHOwvDxBiFyeSgMPqbGZJpZtaCPgQfHGylvQwNzfHFbjjNGtGGJUDgwwgVpELWXfCqAxlYvAmOiViCeCcAxcjeLjLUxOeKQtEvOtpZgHpAWEesqALRZjAAVOtilZzIdlxqQCZCNgDtbOxHYyeOMAXWoVNtgLHyzbBbQaMTYSLUkdNBsWSkSaSXkvcqYbQPlXLiLuZhhvjxEOGqZirDjiTjUiPNdepbrRBurFVYgKcEnLuItvxjSIzwnOtGgECRaerqwXPZUwSpsVfTBUQarXttlntuuQihDTlMppndVSgKxoSuTnasWmxRJszMjXAIHQloQGwtsnlTWIbkkrCKTSvTOVdddEdNDXCBTOjhDtwMqUxSDeuvoNHUOUWeaQPfYnYQivDrwVbjSaVawJhhUAQvmjNTtixqguSlrIcczoMzlOmQESMxlAiNCpagGIvaeuCSfjtxBWZjjLVWVUVejSeXyChYBZaKZhkRwSBDRTxUABGDwyGBKaCFncIqUoDkAciodntqyVNTgBGtwdhkqAAbemWPzDhRuLgTUoazCkmIeNMNJdrjYguUcsYuZQpMtzcOeQEcZXDDIWbLdsrWzUnDAzlVQJTLAGqnBNrvQTSzwaVQWyIKWdhstvHSbDtlYrtHoNgHyqXaDvLmZjhEVhoNswbNEKpqYAzgVlOJccnExCZgRGKIWXundbADwaESRyDGzxYShssyXDdUuQXjsklRFKiPzSXtsIeGvOKFyjNNtykZSNOAwMaXtvSFynsQKKflHPPPNhvuZvTNTUqlCNmoZDJPaVXDzsUAuZumVPzUOWLKnTlhwenxhhhWXBOdMdvRfPdaBQIcqLhyNkjuawHvguUVKfBqzbECLmGkHMugzhWZhYgRsXvFQFluVBhbmwRgnauSCLzGOnBEPcVsmtpkBaXhYyviFHxltkxjEsFlIfaDUdzHoakPUyQSOpsTqWmQxGWXzdalDwJEUkruurSQeFRMHhJQZbSApbxOnffMFkBwziNZcFxbacqaeapJxVPHrBvuYOiKvTroCaooVLuaddujWomkIvqBmJiPhqhWcvKFAKJzNuhwTizAvPfcRqTgbxShcpaQdFrRXFxdqxtzkZYivQhTQSaiLDpPRxxYsMctsXHwGPofEomPbdkKkucmpYZmQkLteGpkinJiRRaHhCUdynwHtMEWeMmZrrXFTjnSCtDUZrkHtdnAMhqIHYWViFSAIVSycwhnufSropSEnSLySHyvKrSMCZciaIoYzrcJqwowWHMPaATJaAMvQeKJbsYZtnEaNUisDfZozMNifTeoAcAXTJgmPYNAJwbDrjtuFKqHNRyMsAbGAZRvmCnbgqhDLQEQSRYJyAnSVdGeZOfldyAJtXVhFZbLPMVDWxGUbzbtLLjsJtZDujqnZytFjgDbcTQKtVxGflseVGsIlYOwtjmErRrTNyUEbzzdzpjLtgMregLpZMrOkkCCkMwXpaFhFHlGqDGQDYJROCwffqfiJGZtkarutZMHlPLDbOXxIGcFKbyHwfhHxEqMVcYDJaahsLRXlIWlcrnbwqdhVaXsziIHvGGZfldcbbEDJwpITfeQnBHmECrzQEIwQmYAtJIFwZzFIqWjWssiifMDoBNfQNIoKqWqyRvPfsiKCuVxPrYvARGxOaZtMNMnkvIJnVHsdJotmwMjvgyAMxKhBhEicBeOoaDEAYAbBHJmcLIaWxpLZvrlLbrGEvYHYqtiqgDuWEWCpefDLjiGLlQNnBecwzlKzpAqCRscDcMaBgztuHxZbwMPImGCMVzQwPrdWYcKRDjogVCohqPOqcOTxjSkYYzLkaqSikKYqCpSuujojuMcoJgbNZyyeRnFGimavvxHhcvxZCnyvEBTxDGGDhaUdwtvXnmHTJfpkynQABWXJIJhKygIqCdTPrlzAyFLiuQkEwPiIgllhKmkhbLKSpnmoaypqHyNNryTAcAQgHzNtRrgRFWnQAgNkkFUJmFMXPLEVfuBzuoxyrrECfKQlkZHuJOrLKoBpBhEicwJeLawKTcJyTfYsgdZmQtAiqWpvtCpweZXYiATmburfmmvCCpiaBzxqnInrVxtDJFlijFTkHdpLnFXsyKXpjzfmmaVUhoQZeDYkVDRxgknxYtTgdXbFQrVPhaMBxRHABFzyeTRFwVATKPQrpPWuScvxVnVZNljPateFZoZSgcbjvfaTIpjvzQKwQJyqNJNFgbWHBghUSLSEeVnqvpdkxbFpqXAjMyezzVhqHAobECoEofGjgWWJPSQKXZsmWFzMTfuCbbZpsIyrMONwwMwtwqHSHHTXRfHWliPCtQcUMSqdnMsPlHYyHOsVZJVzJQYonPMnZFLZWemKBtosyjpMOZlHpgHTSBSHcZftqEYmSFDsxDPiGkFbaPInoUvquAsoDTqkcmqCDdtWNKjPxgYwaHKqzFXyZbJtDiqllCOxTQCdZlvkGPtsKNZHxuskzFqSnySfBfgpeSclmPzYIZhzjNsvMOWidjMQhcZshqPAXXnlpzEEmrGDCDFdsglkNHzhsZLQYvMGWQNYRYFhAbJGIRQLKMAZNgzlhDBgZsXNwyqNCVvDwGfagIrDvfJukUgPJftlHGJjVNqowUSJNMeIbxlOnUZtJfhMDlJeYeWmtBzpnEYiJXLdcvMWdWhwsaMlfIvCjfLTlGQoBGUBjGTXgdcFNhAMUempKbXyWbnPPAQtnJZFCEibhWfeugMNKtCwsNaUTIeXOUaqPNyMVLMwYgijiROdQrfzsRYOWRkrWWzBlJxkVzBiuPrfyKRTPsdNerpgqYmgVioywIRAFawRiQHoZUwJuKSQanXNuvyXnwHMCdkgEcOrALnDulRfzvqYwdjFXIdUkQxwHqntAOLIrJLmVfzsadukUlUcpBOhrIFqlFrZLwPPTCWMTINMUPeHexZPhhTJjcxEMoGWaShufLobglebKySrlwaFjoTeiIlRuOEiHdddeqxlrgvSKrEyQfdPYhRCLsyzrMBlnXieUSQqQqRBaNwwPrUhPzWppWLwUpJdVtDCgpllvsivOwHXetPBwLCFzmElsYBGfmIMiBEtRjmCuLSOaSBbQrNWKiAdynxpWNCVFAUAbgdZXGSpDEmLiRbPoRqREaOyWTSatIRbDOjEqsGiQmPzfCOtumAXkHPCdVHGvSBzDhwhAgiTiOotiOaePzuLiZDvlLUeYXtYmPVheMjLdcHvjoMINNvjeovJdQcAHrmoAIJtqOyAbYRPXZutuZfzjSxqSaoADLYgIizauMrbeuCaukhiYcCXcPBsJvuXQSPtaraCoMxCqevAhhRdfbqELLdYurHeLrTMpdtbhIbURHjTFdohiPdUPfTqLZmFPtMjMmQceMuckOBdDNmQymTUBAhqIXMKFkJoFYXoDuOZBnlCnMBkrYnxgsYAkCSnErwDIuUXaSosOHcRLHPxvLwFVVdpDWbppbDMuIxuJkTHYCJcQbOsBjncqehNiZwUvYMuvwUmtbsvGyOmVFubhOAOWhOsjDFdcjXnbQkDfisCQhdVIvcltVFRtCidudEYzCiMlQUItUdvpPLPvDoRnGgIOZttRqesjsNJssaGAVcLLodWPgzSVhMxSTsVPpvCPhWkTXrboGlqlOaLBEaBAhsYvVFppIjhYEgKXGfRrbmemWAShOxUMWqmEKNkBbkMzRcwvjbqCuANXwZBqGNmOeYFLdNmvoDoSUdqTYNLplwfhzEONifpsgyzSCHYQdNAYMLyZIXCZiPcEpUCAcUCMYrpyyHbLAQNDerZJxMQYkJMzxdODRNGLqqNWznlkOFvExwtmLTRoCyXTsSoMVheglBNcpwsvxobdTycEtdXRlEEcOKgDmmTMBfzebosgSqyoNZrgneHmJcDSByIAxfLTwMhbXXRmVqizVN" - } - }, - "ProposalBase": { - "id": "62", - "status": "Rejected", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "24972834479" - }, - "submit_time": "9936-01-01T12:12:35Z", - "deposit_end_time": "9936-01-02T00:30:53Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "280" - } - ], - "voting_start_time": "9936-01-01T12:12:35Z", - "voting_end_time": "9936-01-04T15:31:33Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "cWkZWXSygzIaBoZdPtVeTLyWZzoSSnnkxIcqDEeasHpiAiKqIWyxcYTKoErlTdJpNMCvDGxfxJemObIbDcoHfyRIsCwruwUssRQkAAuajobUnhTVddTBCbvlgvVFAglfCzSdnIARoTTj", - "description": "rkxBHDvGyfFVRUdWlbrumbYWVDGAyioZHeYPCzVOuGtFxKzjwgutSyooGYCefgueTTOZwgzRZbPSmYhPgFqowbgvwWOqinVtcESaYfqCOXzDWRFBNQBKuQWsHubGncjmmYavKeBbtYwZzXjkUMlMxDGVXKHScZnAkmrKHbANsvCnILmiDEbQRavSWMpgyIENfUmOMjRGmUFUpjlmrhRojKpZweQdHTCuAvGlRoulntDiRoFFuQUpRXLQKxlWZVnruHzFQFzTQLRasNNzezxLlfWskkgKYpTmvalgcdWGGxlAYxpKDgStUOXaskhjDSYxHOQdorbIbFFuZFLytGzypbguTldIKofWHVFCbJMlBuummuFYWlvydVUWIVzRVBCyhcsbUsSoQfaJVqQAQEAimwHMlrBCPUnOOoycEMIugwFKQCySaXvbKChAlQdtkGHHWHDQeMUaQvDXztmhSwXuQdBDUUxwIpVacpTuRbfXnkJcnTKJcZhSZQstVhZhctZtYJfAKmthPzkWGKUhbmCUQWxzlQIVeyWznBeVwaBKyEibCYsLyGKoWNpzgmXuqtHOGTSLKJKhHkcNNjcbrPPSXyCErFXelhWacxhXYhrXLvmufOTDYKRkAZwPaXVOZvweNGdBBlBaCpMIlqihEuQWuVZsqBftyJWlCqTRLTNLrNKxioyzgAoRYlQrNysulhwpdMxaYbwXMVOdLeoEShNzhjFulxzfHSczhleKKfXfjoutEBYcdXOWIJKIJnhPiBbAAiEcWUPSJphYxRyhYNGZebAWIpuwBJHgaqbnzGnSMyqhYKUCukVCHvijSbniidHRzIKRqaolhvMNgRGgSqKoYZSjqcIJQInbRrJzZyVPClgbPkUlAcVxAWfldQlQUBhXAlvhWDdxQNdArgaNRNxEmrcvghAWKzkgZhlUqnUYEehHgqFlviQryKsZPzVyoGgaLsqrajiusxFHTgkvAYcShfcfTdYOQGUqaJsLkmfyIzaNsFFkatOTdctsaKUDRIAnrPJJPwlpOyeriCWdGNbUGLhWEhnjQLvjYUtaXdIRvfuhnrSRHVfmpZytSwGrQnuJFWxrPRtjIOldXBRTLGmcixilqEmzihsnEyCEMtcnLOMORGmYKfIIgbKEglhdaUYtxNTnWwrTbuHtNIBVjStJAXHVtUxPnXxmigjaWzfegpkahIqmJcPxRCkAMrAddQYIupIStWhEKyARrSPeNUovNGiNVIFlQaBDutUJiMvRkLgLBWakRQiLYuzZBqRJoprTDXaWrwOYzpmqTlWDuxvlPIPEUhDuhKyYLRJGzLeYBrNHGEuygJJRcxsanfghNVzdUAqLwWxdIWMyrgspaWYaijZsCuCaGYxTNnsOWBXWUDDPuMkCfAECbGeqnfEdxpDznrzPGAyvaKEuXtAnrLdpTRRZLxfcsPVXSujgRgxqdSXiQKNcbRTVVtcidqBiuuDfsGIlnLFanrvsNUqWqBUVEdVqtRPMQyuIJwHreFPOdQrEScQKInuKdOBkCPWrWsHMNQIVgVAjOmcfYHkndWhtPTlkuMPxJbqoltliMcTArKqplWaXrMYoePebibQVfGVDhMMtzLtNCKdCERkjQfUlDhwrIBWLzPMFTJAoClsHkDkueRhPqIAcezYDJZawSDhRlSnEuVsxkmdtyCPRtoAYnnHLYJESJHDkjMAdHpMVyxxFHwjYyKzxtvTJPitrmpPqxisZDlUPJNthlVWiXgVTnTFVsKAfLjRekRobQbzyvTHuZpvmGxhJQRghBiUBRvBeenlgvsYDaoahsdXfWSOzlzgFonBCbxRLWAHULxanwRKBpiduPPKrwmefgQucgUWNUwhhTdUvVnqjGMtGbhbippJpagaRKKYiVskSYHSnAnrkpmkkvixDSUzHlRjofDnMsYOiDymlCktxVHALFDdPRNmEdmUiQtILBjjiazUkjTpUIlbjydPiasGLpsyKFKbIaZnUcGMYlYgaoUpORuUwwTWwkPvPwHaDoqXEaVSplODAANukkvFpmwokNnEYxcowBJsZcahQQGQUkQkTTEQtCyxjfjRUUfLyPJolfEZOMYdGrYrVNleRSgGtMBPoFlZZScvATWQqwtZOrLRBYSlgHSwkHzcbPXRdendEqvTexcRJLcZNmgjAkNAseBTsTgkDswKDyZYvfJEuXjntuqPpmvSjVcgEBZxECixLZAriHavzEERoFuxzzIKmIYyAnmbVyApRCezoWWpGUupRHoVyZamULugxcwMbZoiZtEiTuMdzHJOuGzuOBEjERlATWcDSSVgeufFTUezDbSRdmTeBgNsScDVioboMzLUQNhShbTfPEhOTkwsRLSIKXZSnGhjGuiklJDSkFAqVabDCjdwQpLwFcTJnWZeKcytaNaTEewfDdJUbvkbHoyXxkLeFYrxyKCKYMyNptXNNQGaWemAHFupksBLLwRDxQpbLBkkaSzUqGfObnqkuAvkKEJTRPQOysgRsXkEVEKLKXGLcNjBfSAVWthpVjdssyzZwKAklLhhwOkAbpDhVIfcsYtQzLwUcWhGRHgbiUMJiHHjosyAkVqKIfNftdyiawrnCKOFKfEVUkThhaTggPjDkQRulfVVIVOfwUKXpXqKooJEdgJgrbOqSqSzmakCYLRFFMavjkVQhnnFOJqtVxBjFlkLBnwGRBTZcNfjrLknbixDGLcbTFdYQYiUKcyzJiIelmPUJrUOfiDSWjAeWUcSvvqCedyEQcAxAEquGLaSUjtpFnYVqhMCejEcexSsavMiyGVPYXPXReSnRqGyoQVFtNexgqYDPMsKkOBTeGkjQdgFpbdAgnqLZKxodLFJiZYKiADGVjeumKgCeYdZIyVExGTKiCXvvVFCDKzVSAVqnFTCcqNNJzAWFTMVzmPUTOdDbAkIFubLYfUilGiqmnJERuuhRhiANeILLsCPikMJSoQqusXgdSkVjzxHrymopkoUfpINpCQWzkuJahmhVcWufNBPnuKsKUswdnhPBJaUlVeyydbyZBfHvLuwrrwoDiqvaWnhCzIlhXAbjozTPzoENZYWGijNMBzUnlIpxwAfoihxDsQucZDisOLJCdMxixfXeJkVGhtAqXnJbdXzYgseVkivuwUPdtomPnUalAWrGcYEKeWcrvVgvtADXxqowDtXOLWwKlTwanONrtIFXxLqCmHKXdJqoEKhpOWeFfKmzMmAfcxIkEUCGNyshrWURzgTUSLrNHlVgmlGvCIlQjvlSMrRTckmMKFroUYDbixdyXJuHWEctvYzNHCyWocLfCelriRKfXuHHqIZYpjrwwByLAcQbUdLIBXAvLhvQejGwuMtwqdBMwmdCnUrbLSddPGvpWKBhtIrvRYwVOQIvFxRwmJkXXmTAtDBYSeSQQnmMxDTBQcYPtUfIKJXQnVafAyLZGJGsZxUNyDEdQIpTeUhxhPEeSApnfKijSVjEwZhPvdVMcwzlAqdikjkKTmfFolMTVnMnXjjuNUbnqkVuVsdCGPTDngnmzEtJshuGhvXEfjutSVRfIgAMxzyXTDbKpBiDDhZMMauGEkmKwQEJCtNqUDtrLcUbQrKiZpqPuQehwBlXOXbZBSofgZYZWqaFxQULrHybOqbnneNvLtaVBKrRGVXRSxhFXTLzVjtOZFrawuprigJJbOsdYBdpZPxBxzOFwqnhwFKVGtYDrCKtKpserRWxUjfLxCIRRBwvKrRXKCzbhxOWEthgWsKPKLvgBgIskYMnYwGZHcDxDqUznNWIXaakLWOVBfClCQTzcSqLXJzEvhJrzPTdDlBKVvbsyjBpTgfVzXihpVBpSqKQMwiUfvodAMOUTxgplNLHMphTtEtzxlTAavjMUPISCXARhTywgerOdqvqrCdRrOqGtmsCiydUErtTtnSHrytxxDPFXWTeoILrUhuUbtoRwPJqaTELYerOIWIxZwSfCkVKVUnEFAfmZFYKFLgGpwJvTGxXEfPZtzExowsMtAeCfqjBudaQyjYLDQHvvzhMhistyqFEpvVxAJsBXQfYnMnYXzIyWBZBUjBxpfRhtmtcrctEIwwhsswtTqOdXupSXQCTUKbwsstempkzTXgUXGiVJtUJVuDHFGFFRdUpkQhqhoWOwqnquZWDIBpskRgYerdOwQuMpbsnSXCnWxwBgcVRVwcCQtMJBvgvKeSEbjcDQDeqzxWDLbDJgZssuvpEMYrYNIhXcNnExYFBqZTFuqMJrISXCZBrHrAfcPxSxeIQMkZmQRjsPPnDmlolKBUCnTioEOnuQCGdkLiwKoVJcLYTyYNyvBXcfanJYcrSYNIsBailiGJLPUAUjxloxYcKjQPbVddlGpXDUvMVOmrcyTnWcWahaZpFekPfVeoxNdjBNVzYAbaymfTtUlPJQOxfDncmAIOAVLItbAefrQYzdibJatWqBCTTFzuupguBBmHIkFCdXoEswhvkBlUPlNLRYcLavrxmjXIjEQORobOrbEZvoZMLkeEKWHTtjuiVmKvxDJGjAmOQMluiUIbxgpuWbkTrYpDQBNsbfvWrYsVJqpsnxRHMLAPXErtPumMpXOJFNTXMHIBcFtUdpuiRrfpJZJUlymEfezkUKmDYemdDDjQuRcQCRxhiNCClcnjxwfASMEAXnKwbgkGmTYpluJVFiRUwsMzdsFELiUIXisxghMujHCSauPAUsflvrAFPCBJJWeySWdHKLibDzSrwIUMrdluOHXPECblncLFtlunwSkqHyBLUORncvmqODBKaBCTPIhlPUqxFoduFlmmnnbusVtOetWnXTjZqKXnWCNGozqOWGRPTOzYPvMPIkqLAKlWhBELiBNqtFMFDxaoVhrdQigwkvnqyykRMMdnSWDMLwfqDOhyvFelJWuacVEmjWtMIXVCDjLPIXaAPWNTqfsbSgVxpHGPocdcmqgSrYoVSMxwGdFhMYBKEynoAbZIeIKrqSkdmAQdseCITgmELcjmLSeVGXvtVeONrouARsvQKOdHl" - } - }, - "ProposalBase": { - "id": "65", - "status": "Rejected", - "final_tally_result": { - "yes": "24972834479", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-01T12:12:35Z", - "deposit_end_time": "9936-01-02T00:30:53Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "280" - } - ], - "voting_start_time": "9936-01-01T12:12:35Z", - "voting_end_time": "9936-01-04T15:31:33Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "nxLRmtWBXPHZCRovFNDcMriPazWxartBGkXAMsubOYiUcGNtbKpFtlECvbnGUGBpmjMVQjVOmTojfqhSOgESWVChOKwnbycHQppEFcpeHjKlNhaNuOrXOLTtjlnLXjxDfHoCwkJlLFdj", - "description": "aPxDGBZIgrBGpTuqabhDGShdqRLtEVXmTqnklHcIDIPdOvimCzDhMUXDlYLrKleSNsdKxHvgjDmVHqNhwHFjpoiFejQzVLjyhoKBhrapAzJGvHTjFOwzxwlNtZKiKVeVVLTNGtsbgztglouGniyAIMJiuoRTvKamfFStCqppxnfrRQYNshPEguihYJiEyMsYBCCcYVnpQIDqBdisPMZUUyiuGaIBZapmkCHveXPFYEmVHQupEOmYPAPojRFqAiXgMwMLImAdKiTbmUrCPeQLxHYMjZCnIfGCoyUJcvbUAMjjvdJkPOqiOVSHxmzBzDrAlDgLVvVgiiatsWxmMDVSJhqRNtWXfEJgyCGXLSeHyNGOMnAbKABQLzMcOXfbEKgKDOuLuiMFRMsRiLOOsJgzoZqNiSEZuCwAaYrwCAaUdJzbDSEmwmanQMxDNwygsYpvSQNJgpyAixcirfnfpAKtFkXZqxQOhPyTuVayNksSFOKFhzLMVLjwTtTzYzzWAvutslplFOvujfjFzPdelKHfphRGNOLJTiPjsOTPYcxOjzvBCLlovMbXfcjsHjSWfXIOGcOPNkYlbvvwmYFfOPLSxIYfZxUcGqDTiYNqNiVVXYBQORiMIyCCIikQDQrFbueeghgzJTTCMNGJhZuIjHtqzWfolozurhCdcUmiOTpTfswnktvmZuZMPAAoCOBRELungQuScDmAklDJyQxmTZqOMElpPXvwogaqcwLeRMQBDzidqxicDmrsNGQSTkidUFdjmOyonTvggYeBSKGiqwHuTOmLOjwUZPwbGoMdwWaRIPyVtYbqdXWqWdbLqyYpxyfdNghoxHKoiQjWlAziAgdnyOACwsgLXbEVZetfoMMytrVvzAroNHROXObfBQQjwjSxMJMwVYIMvNlUhFGoNbeiTUkmTLgOAqdGbyNKEEasKBwBGRHEWTEGIAGUjWwGefaBUQIfZAqrRvxGsilJsOeGNWnmkmYHyrrMPrAzOzJNIOvbyNPLMvxHJbKgmZIFvrKfUSvewxHVUHaBrnTpYMrRpHrBcFFtSubRQnAKnlKCgcFnRCfowJWHoUYreninIXxNbvQiRgkMklltADNRWWeaKTDTQhsBGnTOPmqSdaptxjYGnVPSUGUWqxODlPHYNtKLnAkAnCPyGdslTGTqGIROzMaLPDQyYhDOvaxmjdxSehLSAGnfETeUvdVbjislUZdXKcsHpoDbzDQOCDKWQxjhHHsZsVzjsfRLnkCTTcqHwikTgfiSpEjfAOPSpotjPkbOWPjZfUPGfrFENUGRoYYhDYZfLgZZAkPBPDXBnDKLTiJFwEqtKwtCHufjMjaZBUcGcyTuSCTXggioHbZOHeogorpepjPnKtuTyRYFcIkxXzfEkfPQKFraeMrVCNbuvkTnikkRuUuxoallJwaIFdMuQfXAlWfavHinGNzhXkjagqRnlYLlQQCYQXrdAdgdrWBLFFkdGMaUGuWFInpswizSpmAcszsWcJtWziDNCbTjthoWyCCPMPbFCpFqXUASEYNTDeDtzizAYVORQnZYdobLueYBygJQkLtfmPwcPXwpAVgtlMPNCUFCHuGcauXIMysjbxdpCOZpSHyEdiAnFRfYUjfybOmJyhJcxNYuTnUaITmWHFxHZCpUNrCNlBcYmqsQXsIsbCVgEUETUEnAwCUiGsvcauANTPOBMoqVSaKyQTMrgKJjvJZnswfCkvtgeFgHYNwCmzyjPPqykafPyHLqRivOMPdTjDWEBCBCQbVaiBGfbnJSvmGgyiuueqlahjzpeuQeDqcouCcYBFiCowgXkyUzRTrZJfYDlZCLLgrsRPlPWYeIRVAWqLHfsyYdUMyogqUttZMXTWpVxtaFWqSrDSANMPxPHgkolwNmBjRemhjRpdJKgoDTwhmoDmIfTDRIbDwrjFZkfhJzKSXGnbuQgwSnLnqeaNDJwZPxckRoZTcCrdkBRVujkGqLKLVFXwHSdFznVCxckLQVHpbtJWBnvHiuEQvsCFGsNWpugwqdeNKjSutARtovERDfGlLQETzJSWQEddaZjvpertReCNqGJgSppkXfLVyzXdCyLezvFCkyQfYcriietzMghzJcgheIDMmtXaKRlsdJqxUsaMrbaZdnjwMSmuBAEcxNmmdhDLzysGtlKAahLRoSxewNVauPHsvsWVdDhIPsyZvDqVnkoDYUazXBVkbFyVKPcIZsmOceoxIvkvJknmEuEANNiYAVtkCIeamzdhoMqgELGvXypfVffgmdoNiDaRQdGhtRwpYKTWHgUgkyIUreHukuPnrnhWHDIduAxDJxGzKpVJoYAzEMPgsIVfSvWJfCSDlfzjlVKeJomvYMEoWNsDYfiVBUPBfdDgoxhKhkkLcKNbWdDQWCgdnjNldAQQLRkiSvWcwDGycOIqKVEOvOGGUBaSPWSXrOXvJBEpVyCzNikwGqzHbGOjUkpqQJGcIaaokRYNcttQmgXOqwtmKwxmlmsuUqufBBkrMeuOlMdCmpmUZLWfAIXrJmpmXhLycUWixgyWcXUmIoSNgjzpoMTVcsEmVJjAIGceCJqHvUmbbFKArfLPlFiBtxlEacCuGzjXcxyIiocRNgnoWBetPXxXtsFyLfZTKNgJpOTiqqbKuJjJonheUXoTpWDXgiWBaACHCtdvTWAfRyxuiZFuYptuFpmWfEtkgfrhADsAYDnhZYfAdUhbdSJITsmnarAnCSmOTFWQotJCJbHtnzTNVJDwoCNloPUudhxyqJoeuDIAadfjHtSaMUcfiAaOEdWSzJhRVVdqtfZtgMFiIkuwsVYathuwdjCAFGOVdOQghVsJJIvEBShoZIXrcqUuwghobaXVwqVhSQYYripMJWNWqZvjVcIGmmHDFQdNdWVgJByYgwXrNuVroxgpxWHHrWROqwgRoscucxhhiQfVkvLekGbKLzNDPxYpGZjjeWGDshquPxlFCalDHTZetWctIrCJQUvYmMhRzYfqFrTnxKqzqehArdrnxLpqTjmzLhoYSNDbsdILiDDSRyNHkQdwRAqrFLOTOTehYtWnQLerEjMYDIASQVEfxZmKwwTHfDkeIEMwxVZuzncWjyhkcvDAampSVmhgqUJSKMJbZlQOiHxgRPrSxoElkEdQwzonGcKVYspShveDAxcVDXcgSyDARORysStvpwoJVEJnafBoOfwDcMKnDQPFiJptbmydpcVSIUSlINAynPvXlFpWNopfnCcVElKziKHYhTAgIGyiczplVVNcrIYqMCTMtHdrkBJVVVgSgnIigeooPFvNZOPZMwqBTitUcrbVcVXJCRiMyxvXIFQRAWnTngwmVhfHWZMbDrFbDNdXVnZowwgGccQOmdaoqJZFCvOajOtPpLJkfhkfGhRnOlNyiOQrfMHXvnzJmmadpsnSMsqRJpIkBBJBMXUcJLFKRureZbIOBmaONljTFeIFtPrbuXLezvqKTVDuJHZFzdoSPyhnotIgyCqgJZQQbuUxntXqdoXdNqqHpBWCOGttAAyyAMSSgLNgnLzrFyyDzZhkYHuzeLHqoTJxwBGLFtaFlUYrMshQdIAuTtdcbSpXoTFOGwHdAFxelJEvXoGtnbIKfEQpijExCCbREhWhcPobNIarrmaObJTQfqsGaItPZcYLNlZwyQwrRlcvxEdVkykuQBCuIlmGXvYxWMDKQoprzulgyzBLmxlWtHWGovpMlpHZdQQJlWdSZHtaNHcULVyDBMLETDTboOzBReoifeGCcFOglTGuTPXHqcoxKqWUIwrEpNTwcFTtzssJUeUZvIrnLUwvLKahuOzCcTUPiBKSpGGIYFrusPOwMnBwNETxNkrogJUopAkymgXfKTzShTpmBzabWFZwgYttAullFSHBjwzRQEstnBjlrqOXRVwSGTJnyKaPKFQlPyIskMHPfuTSGBOFfUPONmqIyXNfAVzOjsxzgPdyFsZgOYfPGHhAWSGFsRMqTqHgHaCTAwfbhjWHltqeqQVjLNPexNzSipnjKvMJbsRRYhTIkapOozCLDzkAxKoJIrXlRESVhWXMpcNXpFNGtMhrkyxRSrzYiZtmuhWSwhsEaTZtRqUCGvQyHazeaimSkLOBzixaFjtNmJlYpYJjXxvtoPjJlEnrjJTaEUEVkvwDUurLHfaiYlZgKehNFmdqOCijHuyNBUGcyyRQFjtOvQFFTBxnpzUColtkVXZMeyoyOLBuHaaNyddVdoxbKVFMFFtRWtyeeTzwmBpDIHagsCyUbjUdVxuEcaDziMVpHfrKipvjSgSannPOiOYrVjlSpPFzMLrLpWlTscvddCkXNFfxPaiawlewgOIVMlRYVlPFsKSFkrGIXtwyzTVGLpgjgVaYmpHLxBzZfErBqFvqzuyPnqOyZJRMmqHhSrEAyzUxGJpkYJCtmNrJqkIzAghrkUVmdcrYEPhWOdEMigYvQEoVLyqOUrtqPsGxpODLyOYCyTilnwLrIvNzgIvdIWnGJFtsreLteSQdpbANVFELGrxjPIHdHDTMtFVMUObPPPlqayEJpVlQrGbdEOKnRwTSBDYMpddrSWHTVfyOEeYXSaEPKEVbBzktLFDiHNgFaerFomaccIITRaTMHLkkVkKpKnPcnkGgZesNpjsaGPWvGJbezlkatKjeNbasBSrnSpgWddpidIaJjxgREKbPLAYetYNCHEbDAkACfAgkcZasqaTBzwFpSJlVzyzUZRUjjYytqOFhxslGCtGsZfJPMZNkUzvABfvwQraaOBafWKpdHLwEKOXuoLQhEuiwklxnKBiGVwLoNlKZZfJhxPTNjIRZIXeddYZHjrhjCSEQhYYNExutgUgWcurmXSAFbVVuPEDNfEDsYUtlOEvmqBPdibZdnSqPxYofICiGErMhruYrAnksBphLNzkzwiScYVwsUUobyWXzjmLJwYJPopkcDpIuOXQHuRxfYdBHjTkYlxBoZSjOiNdJYrkfdAfSwPHjCHASzvtDTuTKnGoGVMutnCFOcmHTIr", - "changes": [ - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.300000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"95\"" - }, - { - "subspace": "gov", - "key": "tallyparams", - "value": "{\"veto\":\"0.271000000000000000\"}" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"10\"" - }, - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.620000000000000000\"" - }, - { - "subspace": "staking", - "key": "MaxValidators", - "value": "52" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.270000000000000000\"" - }, - { - "subspace": "distribution", - "key": "communitytax", - "value": "\"0.220000000000000000\"" - } - ] - } - }, - "ProposalBase": { - "id": "67", - "status": "VotingPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-04T11:36:07Z", - "deposit_end_time": "9936-01-04T23:54:25Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "355" - } - ], - "voting_start_time": "9936-01-04T15:40:16Z", - "voting_end_time": "9936-01-07T18:59:14Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "MsHLpqGHtDzzqzACHaGOqiPDNkrNcvGvUwvdSmuMwQESgQAmDZrbHymDnGBavdMUiTUEWWKkdaUJypPxEuwCtIwCpUUnqkfAXqoHVTBhjCbhncjWgHpcicMJLtRRxPVRrnATbvqXJpyG", - "description": "wUYCUlBzuVxMhHOBauMIOxJnRVQIdYybUYNZbkcrkxZwnAPfQtyWegkIRtrYBOqApJMwqIrDUjVKsjXjmtKWlWGRvthBNWbkdJymLGcakGQNQaQsuAfriAKvxcaxjqsduSurMZPshcbBuNvwGIxWSBHpEmYZWQliSMMavzNOOMSDELGXsLwwkTENjfFPmbwfmcpbEbRZZXdMJmJFkSzjumqRLcUEbNOIJZUJcKBwnNBGcdhvMgxKEnMhFBbwLTjBsZlcgYuXgUBXoRSLYsPacKdsuNxZuvDVdNAhfaxWtNZTwjkCSjcfMHuTzYJuPPigzLIYxFCdqcTplakLQwLsckldDJFgrNYmaSKYvqWDkPTJBMwCXLzehCvRbTxABFrXUDDBPwJYuWDtylEzfKPfpjEIUsiTblQDWalyWkagijArJnIxDZSdknCSASRuZZCFwFiyjORUjaOPgmLswIGWtqpkehExEZMszYqcXyuyeEkRVYSQHoXnjvKiBktHUsBobVtUqAOLOuQzHpMtIArDTMAefWaOsCTwUJGgcVFnraVaLONfEWzBxXftyqVNmlznvErdbWuOwCQVhNStEBdMfucGFzQJiXxRBcDzDUrpbRQrsKOikkmpKoKvZnKELWubiqsoDYcaszlOMrhkyKjlYWxvVbtWBtkLFJKVZCgrKVPnoGKSSJutZMBgQHjupCEvlprHqWvmAhritYrteHnScdLsCJNOKgzjwhcdxIihyYkiAEoeMLfKhNTwiRtyUraguywDgiwGIvBwuOtsVXjBFPUAHGJthYwryanuKFneRHyvYzuwqUMoobqficfifIaqUcDbDZjVjiahZxysMJhnuOJcbQWRsUoahuJCShHPFSveqhvwQaUFofeSfRdxLbrrwTqzJoeiUoKyDECvebuFdzkdKJFRYGPWkmdlNoFceJLlVOtLWQubCSCEEWtncEjqeBoQxSQwGeuvdqzTUJopJaCeagmXdWPSAdMIlsiASDlqXlYwACaKVAClJzDONHOKLmtxGqIPfQqlbWbvJzrakskQGLYuNpkcfEbmjfsJLNhYCjquZqUrLMWYohoblZuTtfdnsCkVtNnYLTeWOMNfrBDLQfDySqpiRKXfpKtJDlhthZoxJLBVicHAfTZgeQxOkHUVXQyhkzhpFAZdPkRHUJOIuWPFhGzTMNCiQtzFxHvGzsMQKyzSRxFOOiTgiDxYTBMBpdqouljAkYAXJgbNIlUSjQieCwXTdtiWpStYFtAmyWdEeiudGZZtUTmQoXwtYqDVERYRUqHawRAMfEJNFtpaKcBEDTIingpqPrVaeqmdJtKVXXPWmFFfxViZyBPDlWXWhkKSzxaIPOJyjQCZyJwbOwiCOEbYcHeEpHOKweiXXPclXmuoFvZfLuiWqIBirDalzFlSRrFZdKxGQZDdOfYvxpLaovNJRlLQmxnYzmHWUrpAzcoJlyeLCzXSvrWlDFoVybczIfFFjrnzwmLtbjlOWphDjxjJYnTAkPWYPdxajGJMRiacwLIOjbcyBcwkKnJNTYQtfclrDlfYarSoaUyWRaXDydFAfMpqMLTaZNtMZwnbrBShaulIlIFMHnLAtzCPRlUntRZhwDPXlYQTYoLElEcKArleoBKFNnjoiFsMrThZdjbVforSaeasazTAxmHdgadXIuURyXlylQJWlzrXgmMweKyEJQtONTRqNzwUwSLSpfOisTewkJVVnaIYFymnDWipnmZKPtHRWlgfbRaqvSXqHLUedninmhHPLToOgnYudtIHTvBrhlVKzNuHqrEczYlUPSCwpWlSFeUTNUtwImRluisqrtVhFeBdbILuZyErBrNtswaFzhdIfFltIgoLOAweACnLXUvbxAJAlAWhuxVXGvWFEgQNgtkLXtTAygXWWihIDpNFnNnMhjKRNMZrGdPvTJbnQCPoNzyZfihTaikpuSCVxccDcmjahIRCPTJeTyxwbHwgUcvilKJAUeWNrJTKXvLjewroCtceJnQCeVQRQEqfCWwSssRuPCqvbDopFSdasrRpDbSCqrKeWoAnptbvcOZAzYzhJAmecbZImTkBplNOeVpFnssKscRqypKoBjwdbYgILyTIPdAUrWIgXZJmQCSvIOoijCwfKTujmVWqTSPeZgmXPdCcfLRDmzqUrLJjOZdGwtgBatJfNbwvDivkBFcnrUcQIbYeZtSKVGguCEViDGoemCEdCmPXamgHIwLCxTNdTEvefOLgZCtmmuOTWOpmWsPVVYGXFZczJVFjzLIJtSrgUqUmXlHiNvisaDYvSLEaBfbMFYIeNrJhBxFYKKQSeiYkdvAxIHjRevvWmTGHVYtMFoJzrXDVWjPkldbTjFniyhaYpsfMeLmBSdBNOouPYsbtDFzHsfVOMQjaEPkvaZSkBvaDzdOewaZUUgGPRGIdjPHCychYJCOkFydJoBGrHhITUxwDefzlsUBwHNYLAIoSAKxnfVjHNPRYanziASmNBFiyNxTrDKXJvPHnMfnsreBkWBgHSvUapaHMKuFDrjnDRRzcFHwrSbCFiPLZnmWbyetZoNYZoyZIVJywWhHFJwTIhwwtaFiKaVFghvJHtJLVzRoYGQwcPglJvFIvXZTZUHwpfRieuvGaxpqbfkREvpkaXdZOiVcEREWfOvhgBuUwmwCiucskSMElqgsnqKekNbmuyGhhLRzOSwYZlEuYyIiGGwrIhzttlOTUyPMzgPJSLAYMLvtpxHqpnIuERWlyibxGfjyApqXAylArBlzayoKILLrFhOLuXnExnEtVNjMaudXChERvNLEpROVjXrgemKqzBSAObFTFrYLWmKEZfIIldQZnbPdaeaUTlmOAoJdjQVAncMPdYqEpWouMbfSWYjOGWoLsVLvRADfBEPoKkKhOqFyIXCksQksHNxBBRsCOgUcPiLXDkFduhOtzpNFNrOCCTFWLdZNzFuHfErQoOaMJylLafGSprPmIXFtAKsORiDnCVOxZGzIeGeqpZSobCdMLyAJcbWVFpnYJmaFgTqadifjZbKDZzonFvoZFHjtqevcCRUGgGhdRWUZyoAecjurmmxahxmWvQtbHBCkvWaRVbmbQAgtNlKbekKVDxEvxUPGhbBgysGGfnEsOaKPXLpdmrjWXsGKefrsgXllnaDoIHCqSqRoBbQofeZmqrSGGXYgixfxoEePyIDBiHMGqCAPtnHwDfcKrhIInVUyvUetKzkEMrRtVMXPWNwgeTTszcTCZiGDXRVanHLuCHuSJRQVixpLUaKdOatAkjbSGHCwEwtZiUZNJAmxxcIQExPkwQhhCyqZipqkVpOZNpdApdVcukQxWSfIeTWnjTyKhBPMITgCHDARhNInJWixpMQmskQwZiiBqVPOpvUFWxGJXjhecHOswlhbXToRKjVEItQLIMgmbpaasugGpAveDHhLfjHrQiOnjtiRmXPZwjONppkMXrZwUXYVROoBaQCrcReAgprhMjPdpIGTHPyvPgSojyyFxsTBSuYBNNBKLuwXtHuDWnhEiemLhVgSKNwrVvXrlgGnFcAiIJuioOQfYEJpsAyQPhKPWgpNdWADrRwqWWEfzZqMcbaDNaexCHwjLgEfxmiREVZsFKsLiJoJmokiNZcwmuvpVsGzVbVporMIFbCNvRfBTJUpwwISNUjLwUUSTKIsawtmjEgfpdQynklbBTRDFxCoHxJbXlbIqGgEdVLzbIZWcBelIpgNdnbORWbzuCkofMLqFtQdfHXnLoXHkvARCpcMbuygZPQyoJHjwKkjNJEiXYigDdsHllWzvTSlmDcDZyluMInvlVVowjwwTYAKAFmYkCCzOtKdquGdmmFJPMbdrDvyhXFNimYmLrQQtuWLraFXRqrCOWWuwVkVHkKKIzBOroTJPhKhcMlfxRoGaYcxqBVkEGHlsmbNNnhVywfphbxutVVMuvseOhxtWayrWcFSftWVlrsIveShmuDxtriNmAnLXOcESnhuoTglzVciAoBcAXKaJqEpGkPngryQFnkQHbSnxbJqHGuITUoQcspviRzjpHxShSBwOnGxLDivvyEuNEvRbyPhylhoofifJdOvsEWPPlCruEnJTZTQSAnYCpBhHZkvTUYhpMoFMeIbxtbdjhBQXJWWugNwgSiGomgBNfycLhEtscOdDbOCqjIeahBMBJPXyYIlhgDfwASvpjeNOgnRyjBrxnnuENsGjNzBLtlaVhQayqrhmUVEiJiqnTOjyvyuWCkkzMgoZGjlEswJMaxPqQnUOIwgGiEOfXsUKqAHXEprSiNYFQYWOWYyhfYbFMGyiejsBsDvvkodzAdXNclscGlLmaTzBhOolEGyzOMlfqlpnnoixPPoLmosYZnjQwOiYDWkVsdAXczvGSgZZXKQvkAUiGoFnWZAKWWmAuiFYazUzfoQlgOSpgdQsWPjAzuZiNXjcwVxguiarzGKDoiBvptBmFhCSvmzLGSfOkdPpvXGjHASiVczzNsmXTPtVdAmYTAqPTNjabftWUeAeuVCJjmIpALGPqfRqAuXEOVlxhUmxjHoDyCpsdvcpZzWFWroJNmceCYRGyVLAIgyouOIOZQgyIrxSecNkKslBwTHifpXqiidEMDCvEhlFGbHIkIhWjYprMzKPvpZaqNmvoTtywAIcpLchRKqHTYknKvHCOWySYuLnYvCBeUehKfSjiHghMadUYOotYOkhODtLYMrdDLRmvpLKUtUWvkOGNHfIqTqhCcvslkKDnwQECJtpsLfGvwYzmCVjOJErNMfgGDzdMcNBhFKuqlqHNzYUaIVNrZiQupUOiATTXiDfLSbCgWTeTxfmddNcQsGNkYxGgTfMKvqkpplUwyhYTUefXYvJvfhzgfLZmOnxcjARSixSHigxAvYswihKKoKTOWQhBahLRuVezJBvVTDJVZdUPOgrAuqAsMDzzVXmCifOJyAndCnDggMSwEdCZeIoHIQVLJfMNFMFTGorMTgYLvNRCenZMQmpFVgHwaagnjtoJUuxOcJB", - "changes": [ - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"330529000000000\"}" - }, - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.300000000000000000\"" - }, - { - "subspace": "gov", - "key": "tallyparams", - "value": "{\"threshold\":\"0.481000000000000000\"}" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.400000000000000000\"" - }, - { - "subspace": "mint", - "key": "GoalBonded", - "value": "\"0.670000000000000000\"" - }, - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.030000000000000000\"" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"9\"" - }, - { - "subspace": "staking", - "key": "MaxValidators", - "value": "148" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"8\"" - }, - { - "subspace": "slashing", - "key": "SlashFractionDowntime", - "value": "\"0.018518518518518519\"" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"167\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"615\"" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"79858000000000\"" - } - ] - } - }, - "ProposalBase": { - "id": "68", - "status": "DepositPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-04T13:24:43Z", - "deposit_end_time": "9936-01-05T01:43:01Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "190" - } - ], - "voting_start_time": "0001-01-01T00:00:00Z", - "voting_end_time": "0001-01-01T00:00:00Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "FIxEAdEyEmgRyGbtmOGeBducacJPpnCVJtknPHwcWbOPfPEsDcyKfrzZJedKxZiihRMAjTDNntCSinDOahbWcKNmLjsEGmpPnzfKrWCrbdJvgJZZNJiYiIAvdzVFKtbMBTlmwbGAqClz", - "description": "uiOjdZvWBbttkZTIQSzcJDXfPLCvGQYaDHlXFQLCjGiwixTcgWFyRqKnDiwchTlJumaADhVsRXZPLQjPnRDqTVNulYqElSRLrqRRazLSwTAdbHebKTmsLUBTHWExfmsQCtAZfDxaHXAdAkVbcTESISbFoJBNFbvbsDWYHIolJwBnZKIAVcOokhcytVvaAHxrgXeMEOkShfRdzfYpFESSMuDNVOVXhcwkzKxlqwJlDPIZfIDoVnnDUPdgGOaUKzVTOUSobFzqdvODdEsgatLnlDolxMarcdQyiMnnjmGbhhuhOWOPiBRUjJcecgqduaeDrIjgZqrudGpkXbTCxdbUJAyrxiplZyXHAVaYSkHRofmQKEcWyYKmROGoQRerzyKVUohSgNoINIKfXTnDnfFXLxYQpqAbTkLdGVwsIrjyqVpMzBZBndPAWtEOFmPSOEubeYWSYNLYhcZHOccvZkQfWrvohFIWIvkOFVEzTHojHoeBVZOZhzbQeTbwRecDbxVNqpktdSzeiyOTXsCLSMSbHJJIgRuJfpTDnwRVGgpybyYEpPxGDHSyMBALepeDooNNoPlHPvCYVFOvzvXZbHKDYPcRNaNRaRRquwzptqRXcdJtYuiAWvnzsBVvTedwMRVOkgUMcyLZMDNzGzUEDbIVpqOcVtcfthCuSXiKrOXjCYVIKaWTXTGCUaQXiVhOTSNCRncoVcmPxtbTERUwGCOzREUyXRaoIwNDOsrvwfEKjJCurnjzwipibHcxlfDDuenmHOcVOzyThZaYnlSkwdRfTBNJEBmCjfoIcHKZbXGIcPMckxXVVRFsGvlthmbsgbYOBDdWSxQKFxJLsszCreVFMzlqYODIoqDTNHezVjzXGTImhpYtnblLfCtKMqWeRwzZxOMsAalktaNhgczKbNjuNKRpUWvPEcepFruVPSFtDQEyPuYiybhtpPlrvyBeFTGmCXjJqYhoATwAyCkbsbjIvkxWtqIMouBpdybyWHflRdFRslScecCgYmTsnZdzJdTwTKnrVRFsLmMYwgRKRFXCwLSXlMiKYdjxlsuyiGCiPKDSJgLwxCDyIptmwjjsBXFkhkTiQfjeqxlPsxvvmdwXlMmqupSErcjgIWxENgWzvJWoZHdJOAjjVKcLxQocOSqfrzaFVihuaYblhHEdnMFUvbBMOZzqDUUUAAVQhANSFerANXjOrUKccxjeiWiMoDFfopsTroyDKFtqTrNtaAkbImfhDgXDJuHsUQMpqiUxCIZFovhyKdSGKCJUlEIgAlhWtupkzUwHYzlaVaTasQKKbIaJlzNsPwLmqpUqGNFLFMsMkQvSSUfVutRctwFnGskbRBPNyMBqfYNjUcDDtWfZHSaVGrlfqccqDqYrbtWQzpiFAwPUiOoBknVTboHVZMZdmuyFJcaDPVTUVjxtIBOxptSVMtwGgbAcHDlDdzqdVnvrwDPMyKzkdgKDtFBTFsbDpScyxCyujpIhOWFVPCxrfkvMshBecDJNTbHvOvysSDicYtgQeAmflshsIQukPXoHIWgOaxCQsJwOUJuFcPlqdwRITbWgVpnhWUGrhBaDNPCMmQMAOpLiOgyBNsrfVjZLMenUgeZRyTtqVKAUughBomTDlrFnImBhPrtpXfmTVlSuBmYiXNIXYXvLYrfzdVnYwEwQwaiyqrmriOgGYcSwxpLQNkFJGntEXZXGLSjdIgfkHkKQlRGiFUDHjpfzxbIVkRzzngHcbtevbxvzULVoxlVSheIJSRKjUjScmZFnqjdTYtTsKOMqTIDLONnmfCIVKbzHWhZGtPfoPMlnnuZKVDshiveNsfwApsknWxCtpxALtCPcVlUPfhzoPpTKytRAnGFhYUakiLLIHGDGFFiDOoLChtZjFFeujofMxtVjNpOPqyiwfzemzCMuWbUtxXmmvwShFuvIZIvSNTvkyAYAodBjsOEtmErWHosPtAhwvDEGiJVBTGyxPGZjnNpAjWQPAyibZEheEAYZAnObVxZNtYzPhtHMWyDXRPsQgLFeAwepbFgBdZrdUoxEqamDVlCxYokPFCyiWguNZuxJcWxIOQBmuSbpFIWSWiyCMSBuBusqPZOhcvdKLIgUswQBoItlVAexCyenpeGmjqHTcsAPlovJHVGAHFnUrKyXbfUOemVJBrwvvaSWOolXIoTxGdwocuiJoUuWVoMVofDwcaMGRXkoDXCFAiyIXxpvokStzSdewOFhNKXqIWHmSvPoNYsRttokCdFaXXfFftrCgpGSwUWBuXDDRjoqVsVSTaXdcthCwupmOsQNpVyAJBHveXExeXKeaWjRKCDbYJIIutbvFBuRDJKnOHyZRZRnQmMHSpVybImrSNZKAiWchcoLwWYJTkUytpDYzdeczhrlNbslWtIReLAJGiAsZflnLAadYIjGKvnRKHuRmjxhrTvwhddXIpnTMMlekBqExtxESYqWwfrLIJGnEVTgRYiyNnWuMyICwJrbIPyXYCwgVkbHtMTUIIwKbASHqvSPcwIsttIVXylsEixvbEUVsjAdgFvtGsttTAvoKPBUKCYoBDcNJSdTcOMUNKmYcCqokIFMYovxZdQXBQeywpDckYrqVJueuywxmJCMjOEVrLgnVsCsXfahmikhQDdMwZkJpKSYcyIgRIaTHMAsFWvDymryBUOmpwUdVYvoWHtwZDWuwOtCcrUVVlbSbCyacMzlEPHmxggybBbZZdAEPrPBeqADzJWNlRvfBQeQqztrWhgFRmXbgNvtEsbqPCmDZWkNohGIFGhDijdOamhXLFcAMiVaDXTroJdSckGoAWXHfgNbKEzpBRbjcOTwcXWIsrYUUFkWBtuFYnpdggSLIFXiDgqbUAJyGFmInNzgCtBvySbJduPAEMKrHZJfgLCZettyGuDyvNnxiIRnDbbapWAkxDfdcPpmMlkADZlpVkPJPpnWpDYSppvXdJcDIAaHydKzTNghnceVTiNwVnQAbQKwyRWLkTJeJbokQcYjApvbwhrDTcvmVCXtKDmkRLUUYpnjaSHJFKjQMIIZkKcwtbXwUqKUidurWBVNrYtWZyPoaHUslMhCkFfeTonnaEEvrzbbLhwPDzsGyJXfUtdDDDpxTRswLLRpCQGTOIboCLgfPMsqfSzHhxNBohOQEEZYzDWGhzifCAVehLfLucdMHULcYanwZsfCseuWmCOUZJefrqcGYweqleOZmdKGmsHelUVWWyHzzauikEstTepJJPpjfHmdedIHyuuwcdIOjTEiCaMdtPtcjRhjceyjPlVhcsMvRYFplGjdCKBLhOdnFcODrGZSZOxSVUMcoDAxEKLxtiyBltMtoSWnNBuTwaxmRAesZTVOKDuzSZpRcycFUYyjzSCRuVTYODmHAaUiqqztqzBdoUEDIBMuRIypKmHhkvMArHihzbqAsVaJQHJJyYAHgALBuphKiMADfgXpywBqiBwcraJLtaEWGokKjRwLlLSYrcTYvjHNWgPyQVRtfOnXVLDnOTTUyByidjJGStGwQXAVycApUWLDlObQpfMkjLYrYtOcjdJnWYhPcGlrnwizEUWzjpxkVvkFeItfEwohKpoCeuBtKuVpTiiirRZNbMLcERCqKtAfuaiPXLqqAEOwzZancofxdClrdDssNpnUUypkYXwqyUhIIpPwwmREWDpgFuasWYiZZMtENkpJOnNrrRdwZifKGoqOaEEfIhduGOSjXMEYrBHpFVpilNIhzbNBKIpPgxkuRqYPohWhOlLsDfQixdVbLBWjUczMaXFEBVyUxasYYhSVCWGLVFNFzPOOSrcbFufjhDGrznRecBzzYGnnFjTHNVOmSfUnlZbMhvwNPbRzCEhsOajuEbVjkwhLAmaldTLamaFdxxzKEnlIzNGUEDZKqoTybFFWnVzclPpQKPFqbhQWZGMSODiNVecDtgVzpekHPYVCcOjbGfOQMCSRfFCfSFEDowVBOBFwZlJCVzcdSpeggfOrFQsRBHobFOxWTxYgfboXTadismgOwskSliZBkXjbUzLTvCQidmYUmItzUFQZVpyWwBcTWfftfssJYxQrbXMHKRyjjjvBzpmJfSKZpCznNNmiYSSmsbOrMEIOSITiwKeFlJRzgpgjIGuyplYnFvyNlEtvSdiqUWSfXKtaqhLHwtyfFZiHNlBIDCqWyKNUIxtipslUybQohbyKUJpMHkmsJYPJNsFqKQztcVYtONScPpXEqafNduPKKldKohAavvOIUABEdxDIXtvTFUKLryCymdPthPjuSICdIKWBFdZjOZPmpkOpcpCKTKEuJDkWXOPIuoUkwkGjmlOpQKKYmDkxGkFhIcHvcmjNVHwdeJfjsIZeFPCtGoidrQOKBZtEyAeutTiSGbzMFUgNtnkAvuhsoysYUJnWpAdJpcqLBsBInZTHdxhQWNzjjUqPaJBTziNKFXtTlIcZlwQjUCoeWrpkwjruYNHRxiCqmhNPJgdAiXcnmpZPcwSuzgFBWQwOortvfxJLlJHsYDpPNmVrSeZtGIgnqLGKPGNQHWOHAMKygULdDQddHNsYeDWNoqSnxQzSkbVMvrgyYDzDKwrFkalcUcmCWkGMeDBYOaCVhgwSUwxluxQrmUybvqKNTASRVFWcHWzuGbHGSfMylmBtmIHwWMuYfPidxizBecodqZyfDbdMuNllCSVBZpJYVNSOUTNYXmQHFmwlwOjtczlWfdOzxeTEAsidhaozXiGeOZfjsStSsWvhShHWMmJCwjczmGlrAZdTvoRRJtWnNJkEAyOcjpjAQWbtzlsvVEHughikBsVdxAIihksOSAFvwAuWPZCnoYtUQabTMHHMSxhbXoBLEbTfyfPqRJQUkDSCcWCepnEgoVOnENQfePpFYJinOHNLGImIzUWSuicNgipJQEaJvCBdhiwWiLAYQsZGHvjbYZnLNaXDfBapMeeDfKwTNCumKTTtJsbYIvIYTTpvLuweGiUOOSZzWSpKZAyCLhGkQLLAUNUJrJxukLqkjDPWCEkENyrD", - "changes": [ - { - "subspace": "distribution", - "key": "bonusproposerreward", - "value": "\"0.260000000000000000\"" - }, - { - "subspace": "slashing", - "key": "MinSignedPerWindow", - "value": "\"0.600000000000000000\"" - }, - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.210000000000000000\"" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"9\"" - }, - { - "subspace": "distribution", - "key": "communitytax", - "value": "\"0.270000000000000000\"" - }, - { - "subspace": "slashing", - "key": "SlashFractionDowntime", - "value": "\"0.006289308176100629\"" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "staking", - "key": "MaxValidators", - "value": "128" - }, - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.640000000000000000\"" - }, - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"230335000000000\"}" - }, - { - "subspace": "mint", - "key": "InflationMin", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "mint", - "key": "GoalBonded", - "value": "\"0.670000000000000000\"" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"155\"" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"421\"" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"204145000000000\"" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"5\"" - } - ] - } - }, - "ProposalBase": { - "id": "69", - "status": "DepositPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-04T13:24:43Z", - "deposit_end_time": "9936-01-05T01:43:01Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "138" - } - ], - "voting_start_time": "0001-01-01T00:00:00Z", - "voting_end_time": "0001-01-01T00:00:00Z" - } - }, - { - "content": { - "type": "cosmos-sdk/TextProposal", - "value": { - "title": "pOEmMucrNnrauabhxZuGhLoDGesHzrGTEKvYRIMBIKyJAWOZfbhbImjUXNUlHSzhnWYPmKGZCFGyNSBKClnmCMWSBDCbSwJJYvqmZuzKWSinuPfKeWuMeIdyJPTDPUrgaUOgmiDwsthv", - "description": "LemUlDSDgWjugDIixCgBmiRYJYfjdDhPwxfwCTvCbuseHBLCojwMyhynuZwPBjYZUMpGNukWEIiMlJxrEKufAiqIZifelGZbxPOeHzxKwdsyBxrUTcPbQjPYEcJULzPVJkENUeOxpumEXZcZRiiADEqCXzeWtTKEAeFARGFKwSOGIuYAJAmZoibbQWvwlEZOPiISaYyuYnIAUcbPNGRnxiWDDcvlvdsGhSanPYjDrfvNEetHFxyQncQUfbLABrDRgWDgTCwdbcfpLtDPfvpdvEuCGkMSZzgVOSzHVNJeYQHvRmnXWnlMymeTdDtFzfhnOeXFzkkHFIEzcXJXHWRUvNcbkRWDHPwLfZmxwydVjiUgUMqivmHPrqntZmBpsqUnlmpeiZvyZzsiaarGPOdYzotUZjvMKkBimtWIeuIAjfRZlHRuXLIzQUXTzlWAVWUsvEjoQmwlMVqXKpydesvGRZFhiLxCLDiShhbVVbuoIEndYCISXfgkbDxrzzAyZqFJHrOqtOWnshQPetjPhksHZEvGcbbPeVaAKuETUseGsrPPAXKLygCtpftJRqVjjzhwhwhPPZzQHTNbyXgtqMYlTkTgVbgKZOchKllyIEgPqnushFMMmTRMsWNpoyitDKYxoGEeTspSuHhZeznHJIqOmuApLmSPEjFztXsjaySqXIYAPLQiFBCcSZDwUNjGDPyMyNuYgorXMCtgOYvNcGifPaPOJtfCzbGHvhhlPdVvSAXBDLfdnJeCzhTTlrhJQhemQcirmuQkPuMcqsBwNoNVCEYGkHJnoTJmdIppTojzQsTNqirNGHpYGqHtiITFNaqpsfHTGCiVjjRsrXVkuywQlJJSybOyJGbGVssjlZKFZuGEUSCwcVafzAqBzMBCbxQYIBTPiSBRoutnqZgyhhuUsBfMKlLdldioxDFlxeaaixGggMqanRVtRyeNZOhoQOSyUmxYXouHSsVMrRYPQMSahOCNoiaBIGVweLOfHLGHcQQpdmvmctsQzNZVCzIpUvikPsaUuPydXTlOrTYDsGPFZmZObKNZuLbxnUAtCgvRuyhUMfxRBJJdxNGfyTVmUTTxcRNkSqqjMhcYOvGQvJqGTfgrWDwyajaMYxHUBIDMdJLIxaVocMwUNjBMyjTRpSIpUPfCoLbzvdpeitZQwvSjbHjrcPtlVaXbTleFeLZqtOCyrLURbOmZlNnVjfLQtorMAfHbohOFbaHoFzmjqBHmxAqIUzZCbUYMERsvXUZiHNGGoreGByLkIRPamGPCWxDlQGsHyPBNuhKPPVPsoVqCxRBJbYifXfGdRDkakQuipjhqnNLOrjuQNaRXdkZeJboJrUeqJjNqTeSDHftluAUeKKyqzagmxtDqbwZLnsdtNQAphZkLaqFvuXYcHamMiDZGWCqYFkUcVYDPwRqaQzNzYJALsJCiyBTfcQmdlylKMYpMgYgCUgtnaaKPlqkSymaTfTEvJVGFCGxEelpdLUDzyLAkiSJpxtuUtFuKUtQrfWMlodLrdqToEzpixEjUawHwQCxCCvFCrZNXjcLopaEIkMErcMMhgNzuxCLvitZtASPjWXBhrtDtfsPfwmUnwGgpFsUVxBRkAKvtlvfbwDRJTiMgunIOpBbbsEfBeuAaxBCluPZyeGLzjoxcoFWGEfDrQBRqaWcUkKuAReIBswXdekPOsStvessqhQnbxeKxgkttEijTFPwFrgEgJAPzspglXBKHKKJikWffbxWiyYrxvihyLyxIgeDsVgDLqYfLuAWexgANwnpBNeMfBEQeXqflVQWonCnrzETonrFYVHJinipltKzyrGDVZsUpxuAWwrUxnbucKJDhQnkKcVWTURlNKpwvzmganrrdhalFWnvhSUHuJmVcPKzKSqNgdNQnYMuywqgMPqXCKmoFPykqsgMGwUILMKRPDyPBpfETgGSJihZGhEIDgvbNdApqABrDnEYmCqGTwDpnnoGkmhQcCKZMvYhSQfZDdBgKmEhBgXBGiVwaBIzmmSJexsYiSAtlgCLBpRVGyNrinToTtdNdYOXGZPvoYaPWOBDFYYyhOdyiZQjiwcIpMspHcYDIlCgiDvtJyZpyLadHXcWjBugtTChiryHQYqlfPaFLSnOebDgGcJiepUGPsgePcdjsNpERtzuCOAJrUaeBCdioApdNMczRVKhKckmyOQQLBWUpmoGZLuKfOmisaeBYEKWsBQOQWEExvKdGLBNpHJRCwYQTQKyCRolVyLTerKvgnhPpXOYFYOCQrMrbBHGIYTkfJFHUCbjRFxyNpmUTRdJXlJXqxyfhYAPbhIRFIXxDwDSolEfyrqnWhfqxadfyPzoRQLzLtCEcbnbQrDaXlEZEtKGBRObpPBeikRjdGcyiSubRGOIXrDGIiATrMkZEfTynnQHfixcKqYwldUDUCcTnyiZtvbFOMfEcFFuWRGVkMcBkdqJDuVHWawioVBdxGJowUEmoKTImUlNnOADKknGuuToFjmjIAYtrgjaOssqmfzNXoLZgKlMKyzlDaacPQQCXZMyXzlCXHJOlrNFwKraHZiOVQxCuALTvWIYneHemmrveGGBzkRrVZfINzADTgEppRZbFhzoWKQsBpaJzVftCmooZgzVOJomkXYZTnnivQGKdhuCWGIWqIXJRbJRRfaRlZPvNHhjCSNPuLRzaRZChimeoXxJQHJMyenprhwKhnBikSvBOtZpASjeeCnKBtiJvJLRqqQorHUXQTkEJURWoPwZSwDwgmpZmONFBvCxZCAUrCPiRjsTRqNlryhVjlmLLbrEnhlOrRAjpNcZsvObWqyvMAZlYSuHZGWQmVBHLRRReCJZQDVRMbeBvqdtfPjyTDCTjQNTgLjYqPYCAJREhZwnOncIMfcmGiHoXKFVSjsFrxdonkBcoBCpaGVXtrxCWYWbdOKiUcURgmuHdfwAWhUqyJJZhsAemSWaxuzTpmcsLscBpWBItZuoyuffQamIHMTrOzuzSGyXbMnqYAwTvWdTXhCnqYzAdiLhoHYZQkzwaZOGeRrJvHiAIiocqZaNjrsZqawQNiJIBSPdPOZjwPeFrpmOBBDbLocwjMvsxJyeLCSbyADOVGhLWPjwJSZLHTuuOUCaJcbnSlsHEmyvOQEflLGvrgRkLBSAEwMeTpfVaVrNLSBTWBCKdNwlrjbUVQfjWjZTBUqLxXKEYVVmjPwIJtmdupnIrWQbPPGSMPyYzSUYZTlfxRPbKGCFjXFAFVAiXpVBCJBWBEJMDjENqdBMQhwtyKYztxcRfdRgTjBeCrUEJKdybAmbnkcNnyZLItKDQrnSIKZefNnrwEcakDIvjGJFUcBtkSBYnrhkMCZOIroitvVwIwkTWOnhECUeOUPklPSWWbUCyjNWeMFOicurxGDPLLNZOCOtaoGHAeEyxABLGFJAgsVckXsIDGRLdikFbvkbXzInYDlTohYMxyDMPIhmMKUyPZpowGzuRXiwPICOpWloGFqmUHQJEtWqkBQDTuvBrRjtXIsklLBRuRCAqkSCsNOWZDkEIocyNLuujpWxsWkmugsiHwMNQZEWRljHGwuDPkGXoZdGfCqgKLnJXVdYBucKCLLkanvIxVWkoTSfuZsxndHYejudMXspScNlwwemwwTicMIquozlHpfUlTQfFRGcKNYbIbMLPZFcfYRhbKKcYerpMdImGdRyoIQJPiFeajQBWlfZtCUYvSTOVqqzMKXOTGQAieVpAUBhMgDzMbxwrkXDZELUKQxPgQSQRNZtFsvrVoXyokhefpFZpuaQVETMXYwBncavfTklmrgbsVYkWnbTTfFILqZIQSEVXNrfNwPGczlccdAywoNyRkKMHNUPjADCcmfWHkGAQBOizaUFseuCptKaagoGOKYVJZnZdsfoFgabpzBuqDMuTOvlFKTlhHxMFTjtTlgXjQFlarrcnnYLRoZcZiRsnfDPdgkJCRNKgQvybxKaOXkPQYxvPZmcgFdfBvxFUESZZSCqJxDIqHLEoWkaLYpRDNcCmQlFFwemMyUxGhEBwEBDGZmHTSCnNiAeWQZhnTKHUsgDTwwiMiSzHOyFiXXVwWZkpupbtIDWQxfZTqJWdMLVpDsMVUaYEHiEEWWPxbdngsoFbSUKwSjLLHLatsizGdZLvoFWBlScMReNyoWMfbQNQNxzFqZGoaHbVKZzrTyXBpCJhDMmVgOqpqRwWDaagCunvYldpPPTpoLzUWCzBlLoNKvzSeemDpnsNEurABqZzqsKcprpXwEFfMnPkGJUumLEIOSWyNMapJnDtyfcLnnNWKywXIXBOigznyNfqAkGamokmbRhFtwMGSBTJYpjcplXAUmInyjvnhZAjEUsyCsPeLppptRqNaudtJINVrxDrBvocmfYIIAfYsdPBIRbWGhgBqgqaqQjGiaPjAUvPBVycOJvpePVHghUTUUYSvxXFWbTCCETLtCROmvDtpTRNXFWIXzKSewmmpzBFLkOxdkrPZCOSnonLToSPisMHytKGtuWVdwMNhuGRQnkCmoTJvQsqteAdCuOKVtuFtYrtebwzCKlYBFoUmRxOlWqCRAxDatKXJvHvRbUQlAlVyZsaEaAgqNGqvIlhGMCwPFmdStGMxdUSfWHszfEEpoXHPNmDXZYRFjbShbkUGmwqmgdHpMPJUDgSEJIDIUzsQZeJahzOuOcOpmyHZtJFZNJdOXmoKlyiEgJBCWvEDAwTOuaZiMPnrlixyGWBqjnlPQEltTLXhmXFZgwCPxAcmKPVnhfwpNNKfddqkEWfwpiRkgKQfLcgkZdsndmSAqEUBBEJayPhKZnWbARRfoyQjQJnjaSFzBQZaypSVZhizwshxNPaNdLbddWbaIjqqbtgYaoUceuXuMLIcGRsvxSiRsYPOOUuHDZBTjMGiiWPMUAVyfTGJhvNvcarkgSPQGBqxQHeuhBUqUaktHGWeVSoVLvpddBkMqHzVNVxnLubPmxGkuUGjHUlQCxSNsOnGiOebzMnoBvoCFTwjufFljTm" - } - }, - "ProposalBase": { - "id": "70", - "status": "VotingPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-04T13:24:43Z", - "deposit_end_time": "9936-01-05T01:43:01Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "327" - } - ], - "voting_start_time": "9936-01-04T13:24:43Z", - "voting_end_time": "9936-01-07T16:43:41Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "hiSuAtSyed", - "description": "hbNHqzPUPujGfTmboMiyqUmEYKOERPYDBrvuJMzNFRHlnSIKoTeodHXPeUZqigdtOWQFMDguuarDJyaTOBJdPBUjcndpxhihdUad", - "recipient": "cosmos1dzuk49ssprfz3ala9tea3x74x8n2nlyzy94a2q", - "amount": [ - { - "denom": "stake", - "amount": "3067193834576" - } - ] - } - }, - "ProposalBase": { - "id": "71", - "status": "VotingPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-04T13:24:43Z", - "deposit_end_time": "9936-01-05T01:43:01Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "307" - } - ], - "voting_start_time": "9936-01-04T13:24:43Z", - "voting_end_time": "9936-01-07T16:43:41Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "xfksQfmPlK", - "description": "BqyJiFnBWwwUUyGaIEjNRSwEnRiJZjSuHMNtdAnildHsIsbmdITnBCdWuvavPOnYhIhPDImWvzFLeITZMsyrIiCTexlFihoNGyJv", - "recipient": "cosmos1amxpld0hdveaqgc3djafgu3zj700502c26lueq", - "amount": [ - { - "denom": "stake", - "amount": "824554033545" - } - ] - } - }, - "ProposalBase": { - "id": "72", - "status": "VotingPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-04T13:24:43Z", - "deposit_end_time": "9936-01-05T01:43:01Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "271" - } - ], - "voting_start_time": "9936-01-04T13:24:43Z", - "voting_end_time": "9936-01-07T16:43:41Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "rJUhNSQaSV", - "description": "xxWkwtlfKntzMvCYFLdvRBmoeTbdASutCprXGfuYizokpcMOXBgaxEmSlrcOkdMEVBEsyGFYbOiemqlEbibrIaZBcwmrUQufzLcA", - "recipient": "cosmos12k9kcewq2045n20vsa0u5a9m98k4se0rxtacum", - "amount": [ - { - "denom": "stake", - "amount": "2224713311426" - } - ] - } - }, - "ProposalBase": { - "id": "73", - "status": "DepositPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-04T13:24:43Z", - "deposit_end_time": "9936-01-05T01:43:01Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "164" - } - ], - "voting_start_time": "0001-01-01T00:00:00Z", - "voting_end_time": "0001-01-01T00:00:00Z" - } - }, - { - "content": { - "type": "cosmos-sdk/ParameterChangeProposal", - "value": { - "title": "AkrXbHnQRGxwaVMHYLWYkCTDTCHcsfclmvaLYufZTgPYwgSghBAQBynubtzYFByvYoKlJHYTmNmqnQrOUVzLHiTtddPoKTAWfFKPDxxlxtHKUcdeBJbbiCbPApILRQClKaEVMYrPqzbE", - "description": "lRdpqwNqYHvAiwNultBrtVJYKJhIkvwxaNCeWSQBDdRPTNFLAPZRJSyOmdXHZHGprdMJWfLqJOIxlcaJzLIZXtbXncWxWzGUakqMeaSoeLsayFvBqhozBqELgvolNEXjecxzPylFRGBSoNEytnIPiAHuAvOXNXZFTXDIguBALWqTKbAvNEGKKAzHlpxiHKTUBEYOvSjnDkJRjUplApjWVWnuBGFvuZeAISOXhrcEIRqjZyzikwLQgagyCHRwpJlwhbYAyOYMyupLPcIASpnGVLGLwRrxZjCvViGMbncEKfCsUlQbNGRGiwpOhTVnHpqdQsOzSBzxOhAriOKWeHEbgqqAjJXYtxZOwpmEdHVTuXDEdLyUpIccpHrHJjZyVPyFBvaZVIxiDcIXXvZfeerHIcuCOKkEPYuIPTtacXzkEgVdbVFuKvtggOcUsKmHapZiZGePliMOSkcqCBrdvgTmbINNNUdefsFgZbwzFyZAmydGGVIDvMsOsmXXxxNbfiKRQZVhoZwRTXlYuGzHdFIeqiucpairLEsQsCUzSHaTcZkYpdsCBALRTToyheXPJfbaPOKxzMjmFnZlZETPMeUBUeXDqmdOwHBPVPqyWbWNwbNgJIlYpCWvgwufeFKygwYRovxEtFLweRgnbimOFDOrqWBzXEadSRAFdszAMKicraVMwbsrbVaMxOKIMgpXZoKNypLXHnauPjvOjteZivwRVXRFUBnAEXQsizPeFphgtSTpnwimiudcGgZkerlGqhLXluzOuWLPADBrJQWUekBiInybvxKBeafCfMPHOmTdzmeKnoFntPMyEUamBcyIPCnTgCFXfKegxsPhRuQPNcDqLRypCzuxmsUNvDxJrYBTaUlBaVRNaxYVFOoSiCDyHVYSYDxPNiNCMxKRfXCEdQfLkPssBDHsLsTTJOkfkyZmjXdeXXlbqJvJCbVpwQPxvFYuwooKzJgzZjRjdxXsTFsJxQIqYrswsWnkGkFFCIZSDpPKVEbNqrmARRyVnBmWwMMnhDjdQghtmzFTKzXjaajuifeCJmewnnnixIhYhaqLKLeOzwdNMMiUnrxUxsLJUllDWkMKuXdGFOAYTsLkNfhWdBJBlaIIgxkjoyclUeRDgZKBhvvcTsQDfbuSVCnEIPFBVoTfymYIfwlldLVxoBoXzXmuniCvhBnkHQNHXkQmNyURtawuyOpEASKbROTGtwbiDqeTYOafubBSggCbVkqdPLsUIIiLeuVwlSgpECKSHXxSHlWivzzCtAdkVFbupTxhpgrbazhXLAxAWongFQiIrrbOHsuqWAImhTbJtrkeeiZeNCJVjFeWyDXCqkYPRPHILpdvJRezXeBxeDiyLPmRIdXgYLRjnbkWwDDUGcVQcynGcFpURyOAOeKmhwCWpawqICzIdZiMErvGZJPNRMjFPXlAXPiXVbGnDHUJNPcHYmbupvwZHUyhtfsHsPlwfhJmLfjXXrycDGTnUHZMhyJkaPowALCkDByAVSznDkQVPYFbUJxAZUDWiGvdyejuCBYKmsnvnEbMXniYgmmVdPIbqiFlyuxVJcHUiPpNMILwdriZsOcVCcKUYbwvulsAZXzxCgvqqnFbLnTJkOTLKVWGWvpGTgAvNvyfgmXPuKdnlFTiSyVLnRzxgdIqNmHSPJKzpVNzzSOZxWLQBSQBQXbCEDgOjLFYfEdISBFerkslHseNbGRrzODWtCUjRGuLmPuztFDzsJVdBwZyDmaKallSCAaSPlwcZxNOvNFwsTrvVaDdbLwOaOGVnmmmrapCggkjguiNwysZobYbxsMNkHiuXmmXPNQnpAlOTTgRhZUXGcyTLqySmwrRjdsdSNAUvtGJRRXwsgxWTSxmrRIzxeFMviXYNAhWOoJSHyhksQDCePyEJJhDZULwDczslKYIQHAHahuPphXEEzYqFhXNHSJNzVnmiVfrUCaIgfFNQuxsUMbzwmXvvAZgbReXbKBUhquWIQmlhLvIIIeWuyRqjjAQhYNbdIhwqLuyeDbesTSRnecujQZuecLiUsomwjIIGBGLgjseiNcatiDEwMdWLkFGCLUgHpAUKZdNkEhXMnWyRHbqzFZVAvnAjHGHrgobHranExDFMOgqbYKJFuUIMYmmzANkoTRnscWAkBqvnHrSVtBnnsiAyioCeiMmJZSWYTblvVQHeZCNMxyFeebCFGnhdBAGyZFWFmTcXfMFKSJJlueiVYVySvjAdcksyPQiPjbeRLFfDVJqfCPzpddlkvzdrrFcmUOwRYtrXtnnouqUhxZzEKXoreogkiYwAiNomOtoOtwftkaLyWNmldGTCgiaFcJUdfmJmGQuEYZTOqJTWouuXzsXmmiDIHDawdbrJBeBDwVRmurmaBLbKWqEAVMMsZzzqcVPJkHMFqfLphsWovZtsvViVKmWYJWlUkyuOmPDkoLgfnQNlTaOwaZaDgvLrcYbWGoidRQEPMgSFmVuXDDzCZcLUxpepStrfVvPIzhSDdDkLBDbamOXvNRZoTMOtJttRjkvlATCahKJbAKKeqgEwYbjPuBEUPHrAuRiAmsuDNQEKPpTYYHwyspZkwxZopupOlFaUflwtqMzskxFKkeaWBhxcKsFhYnqGtJZivxGCyXkPtVSqwuHIiSkeTonbkraMqxqRjlWReQUnzFgMMMUoWiAxobYTFOchuFOSQsVyUlrFdoudRbShqSOjweHSBUryqIpMIPglGHoSNpHYZvUPFAUloEdxLaWeHOxzaEayhEvwQalIoufOlSlZwZlOTaIYgWwpTOHmKEgpqicUaSeyVGFOsrOOthVUTLWULYtqSieTYLIkQKOKFCFapBEBoqFbIWPAaSAksQJITPByRYiHrpxpJboRHUreTlNDrJGvqjNeIEfxQPXpYYEJDsMiyXubGscQsTsBxhtdVJeFyxGMbFHpyUOgZDgCCQYOHxWbpRJcdObocueTSdUTDzYabhdgtrHLkGVRzccxiGvbFqWdHczKfYnEhJhcuxnJgezRVeOluFEcTcfKprXPWNdtgDYswOjrnPJxapXzaVOoJwfOMLYOAhYmYiFGEiDmzZXoFfyjLqnluLULEtevgkrliqMAgkUYduLHhaTzmTHfjdOebHXNrBCmrhnPvqYtHZXfXrsfGzEQEGdvdQUUlRykeWdzKMoGRthIkDSTYfGvTPAUclZHgXciFaLVJcjNAUqwowWdYXnieCmzAjvYaDpTHUGPUBcQgBhyjDvmxHxbXGBrZCiRvwJjbYLtSsUOyWcDzrjHbCLXZVGBaVSWWMtmSzpvTiUoxOGMNQsxuZtFYardhpRDafWlsUwzaQXgCLzaeNJIdjfwpAakRunwqqzEIuQHfXaqKeFikuXvjqkNugfnTMpLRJWLEDNoXvserNMyAVjMJCLbmXlRNzrUVkLYguXnIqnvLYZCqmsSlnaoQEZGFHIQgOFUKIvgKmeXkINVbhvUbSpDeNQsVSvWxcOjwRFOEbLgKsRQVgBWHLAGZdhwrrlsGWPjSJASWROpLtpXLMXXAZelvSjvRXibJWvgLuZonpVAloVmPRpXzBEfqdSNmNyKBAdHrvyXxsQbyeXocEgRhHcrwOntsNBTCegCKpBWNGTfGtpuUSKvLfAtdWZSPQXwhbpesKiszrdBJXSDQVBWxrLbAbYdJFmmrCquUDMsCKutZWCPHKmVQXvMdwiNYYlHQYXPpFVgtAiOzldyAZtprhyPivfZTbLIPhyiUpvPkdlwmfkXLRtNZKBEYXVtrLufDmLxKFnJuwqvvQhyNPTOUDOCsqxlowDugfZxSlxDXPWLAdRXZfAkZlXKflGnXNNTIWTevyqowtwKHDgNAiFzKTRYKEpCjgvbTsiCZKsLTZPutLNazRJbcoDbhtTCFjHJFhvkOFRgpxPosgjHUrATqHxeFVfdrKeKSLNGcSpFFRyOjsOgruMuIzyfibjDorQJfjDMxodjleFjjlMvZNuVoktFVMYksuNPVaeZDJJjuaHJvOOKWJKEvhJgVtFRrJGdMlhOfpaMfLtWDWgNODZySUtnCSaTsajhcwKsUhuDPhtHqWphvmdkONZPQRUgTdylSdXsOoYGRWgXYVNqdrAGKXKhpFayUgTVwjzwFmEtGpfSUGkAGNFDGiDWGjNRwZGzXeUglzuhAvyfcvVXcaiHsWkCVNXjzYkTLsDsXPTzWfankLNATJuqgEXvcDqiVoEtqsIGZpKzZUZvLLLvdUYcTJsDoXEnZThXvkljFQOSRGUdFlphaLVwjNCOYSzXZOuIjXhOplIrkIjJAXStohBtQkjvTFZPWWXjgNKXjlpLdqdMZylxfKztngQYaYLiUKHIkSJZTAnJRCjgBStepsjddoPCKaTaKFoCMshSyqGVqQFIieXAtqOGjvkrEWblrqsWsGeqoaChiCQzLaNUORQawWQEjaBTGdqmsfargNwKxeTmsVzTZAJLrDarTMyeNgpyXiILCgPcvSVAWxjeBfdywivvBvRtFYctEhhJiihCzcbfsqdCZNjqIJHsJDtxTBOiYGasUYLcgerIJcNXOFUKhxKVgGSjaMuecDBGwtufBMsbUJmdXqFrSWwboFeoYLwVgczOcvHeZRdkCPnvaHyQKlaXQtDcneLsqRzJtKiQZOvWPbyBDQxNNzeIQppCtJgDJgbRLwdWgGhIpJPFJOexBzMySjKARDbJpSMTgGVFHFQDSnJswtPWJxvQLLVkNUjECIEPBVenuxjpJHCCusjustPScPAXtCGcrqtZIINmKwTnsVJorJLOJoyeLGcAITcmWBDgoXSyekHPVVLxeyTQowDbhDQjSdbcfgoWTHOMuGiouxRvewJsubQbWPIcyPNqNApBeVUGNfyLDbekbSSXUGchkiMsTKgSWdixZilWanDRJewhsmSyEOXqMReqiMnazgLmCBWWYixHdWDEXrzAhjmgPnefJqxiSBIGPcHGuliMBWVdEsvxThclOCsOECtKcnYbwRBngghyEvBzhuwEUsZ", - "changes": [ - { - "subspace": "distribution", - "key": "baseproposerreward", - "value": "\"0.230000000000000000\"" - }, - { - "subspace": "slashing", - "key": "SlashFractionDowntime", - "value": "\"0.012987012987012987\"" - }, - { - "subspace": "gov", - "key": "tallyparams", - "value": "{\"veto\":\"0.305000000000000000\"}" - }, - { - "subspace": "mint", - "key": "InflationRateChange", - "value": "\"0.380000000000000000\"" - }, - { - "subspace": "distribution", - "key": "communitytax", - "value": "\"0.070000000000000000\"" - }, - { - "subspace": "staking", - "key": "UnbondingTime", - "value": "\"75959000000000\"" - }, - { - "subspace": "auth", - "key": "TxSigLimit", - "value": "\"5\"" - }, - { - "subspace": "auth", - "key": "MaxMemoCharacters", - "value": "\"177\"" - }, - { - "subspace": "staking", - "key": "MaxValidators", - "value": "127" - }, - { - "subspace": "bank", - "key": "sendenabled", - "value": "true" - }, - { - "subspace": "slashing", - "key": "SignedBlocksWindow", - "value": "\"340\"" - }, - { - "subspace": "mint", - "key": "GoalBonded", - "value": "\"0.670000000000000000\"" - }, - { - "subspace": "mint", - "key": "InflationMax", - "value": "\"0.200000000000000000\"" - }, - { - "subspace": "gov", - "key": "votingparams", - "value": "{\"voting_period\": \"329617000000000\"}" - }, - { - "subspace": "auth", - "key": "TxSizeCostPerByte", - "value": "\"9\"" - } - ] - } - }, - "ProposalBase": { - "id": "74", - "status": "DepositPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-04T15:40:16Z", - "deposit_end_time": "9936-01-05T03:58:34Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "58" - } - ], - "voting_start_time": "0001-01-01T00:00:00Z", - "voting_end_time": "0001-01-01T00:00:00Z" - } - }, - { - "content": { - "type": "cosmos-sdk/CommunityPoolSpendProposal", - "value": { - "title": "nhDqMFkWji", - "description": "cUCDxDCHCRUftEVbrffwtHCvOXhXLBmCxcQCyidVuEekdMavEeLqLwLGEsYuZjREgzWeQlTaKQWDZSJaakavDStzaHDaZmKFEmIH", - "recipient": "cosmos18z9fxr2nhp9h2ywqdyq6j2ate0aeupud7qgy3f", - "amount": [ - { - "denom": "stake", - "amount": "733698530436" - } - ] - } - }, - "ProposalBase": { - "id": "75", - "status": "DepositPeriod", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "9936-01-04T15:40:16Z", - "deposit_end_time": "9936-01-05T03:58:34Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "71" - } - ], - "voting_start_time": "0001-01-01T00:00:00Z", - "voting_end_time": "0001-01-01T00:00:00Z" - } - } - ], - "deposit_params": { - "min_deposit": [ - { - "denom": "stake", - "amount": "221" - } - ], - "max_deposit_period": "44298000000000" - }, - "voting_params": { - "voting_period": "271138000000000" - }, - "tally_params": { - "quorum": "0.432000000000000000", - "threshold": "0.524000000000000000", - "veto": "0.259000000000000000" - } - }, - "evidence": { - "params": { - "max_evidence_age": "120000000000" - }, - "evidence": null - } -} \ No newline at end of file From eb3eca97bc48e35738e0d969e4cd7a6c233152ac Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 7 Apr 2020 14:29:11 -0400 Subject: [PATCH 171/176] address comments from review --- x/staking/genesis.go | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/x/staking/genesis.go b/x/staking/genesis.go index 6f02545ab914..580970e9303a 100644 --- a/x/staking/genesis.go +++ b/x/staking/genesis.go @@ -148,11 +148,6 @@ func InitGenesis( // GenesisState will contain the pool, params, validators, and bonds found in // the keeper. func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { - params := keeper.GetParams(ctx) - lastTotalPower := keeper.GetLastTotalPower(ctx) - validators := keeper.GetAllValidators(ctx) - delegations := keeper.GetAllDelegations(ctx) - historicalInfos := keeper.GetAllHistoricalInfo(ctx) var unbondingDelegations []types.UnbondingDelegation keeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd types.UnbondingDelegation) (stop bool) { unbondingDelegations = append(unbondingDelegations, ubd) @@ -170,14 +165,14 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { }) return types.GenesisState{ - Params: params, - LastTotalPower: lastTotalPower, + Params: keeper.GetParams(ctx), + LastTotalPower: keeper.GetLastTotalPower(ctx), LastValidatorPowers: lastValidatorPowers, - Validators: validators, - Delegations: delegations, + Validators: keeper.GetAllValidators(ctx), + Delegations: keeper.GetAllDelegations(ctx), UnbondingDelegations: unbondingDelegations, Redelegations: redelegations, - HistoricalInfos: historicalInfos, + HistoricalInfos: keeper.GetAllHistoricalInfo(ctx), Exported: true, } } From 383a00a897e48505b3adc98f386ff1d4ce1a62ff Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 7 Apr 2020 18:57:37 -0400 Subject: [PATCH 172/176] cleanup ibc-alpha --- x/staking/genesis.go | 5 ----- x/staking/genesis_test.go | 8 -------- x/staking/simulation/decoder.go | 6 ------ x/staking/simulation/decoder_test.go | 4 ---- x/staking/types/genesis.go | 1 - 5 files changed, 24 deletions(-) diff --git a/x/staking/genesis.go b/x/staking/genesis.go index 580970e9303a..76ecf0c5c827 100644 --- a/x/staking/genesis.go +++ b/x/staking/genesis.go @@ -121,10 +121,6 @@ func InitGenesis( supplyKeeper.SetModuleAccount(ctx, notBondedPool) } - for _, hi := range data.HistoricalInfos { - keeper.SetHistoricalInfo(ctx, hi.Header.GetHeight(), hi) - } - // don't need to run Tendermint updates if we exported if data.Exported { for _, lv := range data.LastValidatorPowers { @@ -172,7 +168,6 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { Delegations: keeper.GetAllDelegations(ctx), UnbondingDelegations: unbondingDelegations, Redelegations: redelegations, - HistoricalInfos: keeper.GetAllHistoricalInfo(ctx), Exported: true, } } diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index a1d477ac27d7..3d3419f3ba54 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -64,15 +64,7 @@ func TestInitGenesis(t *testing.T) { validators[1].Tokens = valTokens validators[1].DelegatorShares = valTokens.ToDec() - header1 := abci.Header{ChainID: "gaia", Height: 10} - header2 := abci.Header{ChainID: "gaia", Height: 11} - header3 := abci.Header{ChainID: "gaia", Height: 12} - hist1 := types.HistoricalInfo{Header: header1, Valset: validators} - hist2 := types.HistoricalInfo{Header: header2, Valset: validators} - hist3 := types.HistoricalInfo{Header: header3, Valset: validators} - genesisState := types.NewGenesisState(params, validators, delegations) - genesisState.HistoricalInfos = []types.HistoricalInfo{hist1, hist2, hist3} vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.SupplyKeeper, genesisState) actualGenesis := staking.ExportGenesis(ctx, app.StakingKeeper) diff --git a/x/staking/simulation/decoder.go b/x/staking/simulation/decoder.go index efd8cb917e42..86f1cecc9e00 100644 --- a/x/staking/simulation/decoder.go +++ b/x/staking/simulation/decoder.go @@ -51,12 +51,6 @@ func DecodeStore(cdc *codec.Codec, kvA, kvB tmkv.Pair) string { cdc.MustUnmarshalBinaryBare(kvB.Value, &redB) return fmt.Sprintf("%v\n%v", redA, redB) - case bytes.Equal(kvA.Key[:1], types.HistoricalInfoKey): - var histInfoA, histInfoB types.HistoricalInfo - cdc.MustUnmarshalBinaryBare(kvA.Value, &histInfoA) - cdc.MustUnmarshalBinaryBare(kvB.Value, &histInfoB) - return fmt.Sprintf("%v\n%v", histInfoA, histInfoB) - default: panic(fmt.Sprintf("invalid staking key prefix %X", kvA.Key[:1])) } diff --git a/x/staking/simulation/decoder_test.go b/x/staking/simulation/decoder_test.go index 813f7fc74a6f..40dd39710e84 100644 --- a/x/staking/simulation/decoder_test.go +++ b/x/staking/simulation/decoder_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" tmkv "github.com/tendermint/tendermint/libs/kv" @@ -39,7 +38,6 @@ func TestDecodeStore(t *testing.T) { del := types.NewDelegation(delAddr1, valAddr1, sdk.OneDec()) ubd := types.NewUnbondingDelegation(delAddr1, valAddr1, 15, bondTime, sdk.OneInt()) red := types.NewRedelegation(delAddr1, valAddr1, valAddr1, 12, bondTime, sdk.OneInt(), sdk.OneDec()) - histInfo := types.NewHistoricalInfo(abci.Header{ChainID: "gaia", Height: 10, Time: bondTime}, types.Validators{val}) kvPairs := tmkv.Pairs{ tmkv.Pair{Key: types.LastTotalPowerKey, Value: cdc.MustMarshalBinaryBare(sdk.OneInt())}, @@ -48,7 +46,6 @@ func TestDecodeStore(t *testing.T) { tmkv.Pair{Key: types.GetDelegationKey(delAddr1, valAddr1), Value: cdc.MustMarshalBinaryBare(del)}, tmkv.Pair{Key: types.GetUBDKey(delAddr1, valAddr1), Value: cdc.MustMarshalBinaryBare(ubd)}, tmkv.Pair{Key: types.GetREDKey(delAddr1, valAddr1, valAddr1), Value: cdc.MustMarshalBinaryBare(red)}, - tmkv.Pair{Key: types.GetHistoricalInfoKey(10), Value: cdc.MustMarshalBinaryBare(histInfo)}, tmkv.Pair{Key: []byte{0x99}, Value: []byte{0x99}}, } @@ -62,7 +59,6 @@ func TestDecodeStore(t *testing.T) { {"Delegation", fmt.Sprintf("%v\n%v", del, del)}, {"UnbondingDelegation", fmt.Sprintf("%v\n%v", ubd, ubd)}, {"Redelegation", fmt.Sprintf("%v\n%v", red, red)}, - {"HistoricalInfo", fmt.Sprintf("%v\n%v", histInfo, histInfo)}, {"other", ""}, } for i, tt := range tests { diff --git a/x/staking/types/genesis.go b/x/staking/types/genesis.go index 553215800fcc..943ab4fb31f0 100644 --- a/x/staking/types/genesis.go +++ b/x/staking/types/genesis.go @@ -13,7 +13,6 @@ type GenesisState struct { Delegations Delegations `json:"delegations" yaml:"delegations"` UnbondingDelegations []UnbondingDelegation `json:"unbonding_delegations" yaml:"unbonding_delegations"` Redelegations []Redelegation `json:"redelegations" yaml:"redelegations"` - HistoricalInfos []HistoricalInfo `json:"historical_infos" yaml:"historical_infos"` Exported bool `json:"exported" yaml:"exported"` } From b9c0d3a5f6ffcf5998c417185494db54ffc37454 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Wed, 8 Apr 2020 12:41:47 -0400 Subject: [PATCH 173/176] fix ibc-alpha lint (#5959) --- x/ibc/02-client/keeper/client_test.go | 13 ++++------ x/ibc/02-client/keeper/keeper_test.go | 2 +- x/ibc/03-connection/alias.go | 1 + x/ibc/03-connection/keeper/handshake_test.go | 15 +++++++---- x/ibc/03-connection/keeper/keeper.go | 7 ++++- x/ibc/03-connection/keeper/keeper_test.go | 5 +--- x/ibc/03-connection/keeper/verify_test.go | 7 +++++ x/ibc/04-channel/alias.go | 1 + x/ibc/04-channel/keeper/handshake_test.go | 16 ++++++++++-- x/ibc/04-channel/keeper/keeper_test.go | 5 ---- x/ibc/04-channel/keeper/packet_test.go | 1 + x/ibc/04-channel/keeper/timeout.go | 2 +- x/ibc/04-channel/keeper/timeout_test.go | 5 ++-- x/ibc/20-transfer/handler_test.go | 27 +++----------------- x/ibc/20-transfer/keeper/keeper.go | 10 +++----- x/ibc/20-transfer/keeper/keeper_test.go | 10 ++------ x/ibc/20-transfer/keeper/relay_test.go | 3 +++ x/ibc/23-commitment/types/merkle_test.go | 4 +++ x/ibc/ante/ante_test.go | 8 ------ 19 files changed, 67 insertions(+), 75 deletions(-) diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index 0221be04f3ab..bea5392a3df8 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -18,11 +18,6 @@ const ( ) func (suite *KeeperTestSuite) TestCreateClient() { - type params struct { - clientID string - clientType exported.ClientType - } - suite.keeper.SetClientType(suite.ctx, testClientID2, exported.Tendermint) cases := []struct { @@ -38,7 +33,7 @@ func (suite *KeeperTestSuite) TestCreateClient() { for i, tc := range cases { tc := tc - + i := i if tc.expPanic { suite.Require().Panics(func() { clientState, err := ibctmtypes.Initialize(tc.clientID, trustingPeriod, ubdPeriod, suite.header) @@ -133,6 +128,7 @@ func (suite *KeeperTestSuite) TestUpdateClient() { for i, tc := range cases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.name), func() { suite.SetupTest() @@ -147,7 +143,7 @@ func (suite *KeeperTestSuite) TestUpdateClient() { suite.Require().NoError(err, err) expConsensusState := ibctmtypes.ConsensusState{ - Height: uint64(updateHeader.Height), + Height: updateHeader.GetHeight(), Timestamp: updateHeader.Time, Root: commitmenttypes.NewMerkleRoot(updateHeader.AppHash), ValidatorSet: updateHeader.ValidatorSet, @@ -156,7 +152,7 @@ func (suite *KeeperTestSuite) TestUpdateClient() { clientState, found := suite.keeper.GetClientState(suite.ctx, testClientID) suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) - consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, uint64(updateHeader.GetHeight())) + consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, updateHeader.GetHeight()) suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) tmConsState, ok := consensusState.(ibctmtypes.ConsensusState) suite.Require().True(ok, "consensus state is not a tendermint consensus state") @@ -297,6 +293,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { for i, tc := range testCases { tc := tc + i := i suite.Run(tc.name, func() { suite.SetupTest() // reset diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index 8f02c3d31a82..b636d6a85702 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -47,7 +47,7 @@ type KeeperTestSuite struct { func (suite *KeeperTestSuite) SetupTest() { isCheckTx := false suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) - now2 := suite.now.Add(time.Duration(time.Hour * 1)) + now2 := suite.now.Add(time.Hour) app := simapp.Setup(isCheckTx) suite.cdc = app.Codec() diff --git a/x/ibc/03-connection/alias.go b/x/ibc/03-connection/alias.go index fcd7293ea6a6..7ffb090107ba 100644 --- a/x/ibc/03-connection/alias.go +++ b/x/ibc/03-connection/alias.go @@ -56,6 +56,7 @@ var ( AttributeValueCategory = types.AttributeValueCategory ) +// nolint: golint type ( Keeper = keeper.Keeper ConnectionEnd = types.ConnectionEnd diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index 0df27a306ef2..36a51389580d 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -28,6 +28,8 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { counterparty := connection.NewCounterparty(testClientIDA, testConnectionIDB, suite.chainA.App.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix()) for i, tc := range testCases { + tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -107,6 +109,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { for i, tc := range testCases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -121,7 +124,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( suite.chainB.GetContext(), testConnectionIDB, counterparty, testClientIDA, connection.GetCompatibleVersions(), proofInit, proofConsensus, - uint64(proofHeight+1), consensusHeight, + proofHeight+1, consensusHeight, ) if tc.expPass { @@ -197,6 +200,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { for i, tc := range testCases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -205,12 +209,12 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { connectionKey := ibctypes.KeyConnection(testConnectionIDB) proofTry, proofHeight := queryProof(suite.chainB, connectionKey) - consensusKey := ibctypes.KeyConsensusState(testClientIDA, uint64(consensusHeight)) + consensusKey := ibctypes.KeyConsensusState(testClientIDA, consensusHeight) proofConsensus, _ := queryProof(suite.chainB, consensusKey) err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenAck( suite.chainA.GetContext(), testConnectionIDA, tc.version, proofTry, proofConsensus, - uint64(proofHeight+1), consensusHeight, + proofHeight+1, consensusHeight, ) if tc.expPass { @@ -251,6 +255,7 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { for i, tc := range testCases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -261,12 +266,12 @@ func (suite *KeeperTestSuite) TestConnOpenConfirm() { if tc.expPass { err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( - suite.chainB.GetContext(), testConnectionIDB, proofAck, uint64(proofHeight+1), + suite.chainB.GetContext(), testConnectionIDB, proofAck, proofHeight+1, ) suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) } else { err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenConfirm( - suite.chainB.GetContext(), testConnectionIDB, proofAck, uint64(proofHeight+1), + suite.chainB.GetContext(), testConnectionIDB, proofAck, proofHeight+1, ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } diff --git a/x/ibc/03-connection/keeper/keeper.go b/x/ibc/03-connection/keeper/keeper.go index 3ae51c8b44cb..9b2d5d7d48df 100644 --- a/x/ibc/03-connection/keeper/keeper.go +++ b/x/ibc/03-connection/keeper/keeper.go @@ -97,7 +97,12 @@ func (k Keeper) IterateConnections(ctx sdk.Context, cb func(types.IdentifiedConn k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &connection) identifier := string(iterator.Key()[len(ibctypes.KeyConnectionPrefix)+1:]) - if cb(types.IdentifiedConnectionEnd{connection, identifier}) { + conn := types.IdentifiedConnectionEnd{ + Connection: connection, + Identifier: identifier, + } + + if cb(conn) { break } } diff --git a/x/ibc/03-connection/keeper/keeper_test.go b/x/ibc/03-connection/keeper/keeper_test.go index f70b405eed7e..0317e107d7be 100644 --- a/x/ibc/03-connection/keeper/keeper_test.go +++ b/x/ibc/03-connection/keeper/keeper_test.go @@ -12,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" @@ -24,9 +23,7 @@ import ( ) const ( - clientType = clientexported.Tendermint - storeKey = ibctypes.StoreKey - chainID = "gaia" + storeKey = ibctypes.StoreKey testClientIDA = "testclientida" // chainid for chainA also chainB's clientID for A's liteclient testConnectionIDA = "connectionidatob" diff --git a/x/ibc/03-connection/keeper/verify_test.go b/x/ibc/03-connection/keeper/verify_test.go index bd48000da1c3..152999348001 100644 --- a/x/ibc/03-connection/keeper/verify_test.go +++ b/x/ibc/03-connection/keeper/verify_test.go @@ -55,6 +55,7 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { // Check that we can verify B's consensus state on chain A for i, tc := range cases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -110,6 +111,7 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { // Check that B can verify connection is stored after some updates for i, tc := range cases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -184,6 +186,7 @@ func (suite *KeeperTestSuite) TestVerifyChannelState() { // Check that chainB can verify channel is stored in chain A for i, tc := range cases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -241,6 +244,7 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { // Check that ChainB can verify the PacketCommitment for i, tc := range cases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -295,6 +299,7 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { for i, tc := range cases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -344,6 +349,7 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgementAbsence() { for i, tc := range cases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -391,6 +397,7 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { for i, tc := range cases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset diff --git a/x/ibc/04-channel/alias.go b/x/ibc/04-channel/alias.go index 55b3ac78d0b2..ee12c61e248c 100644 --- a/x/ibc/04-channel/alias.go +++ b/x/ibc/04-channel/alias.go @@ -63,6 +63,7 @@ var ( AttributeValueCategory = types.AttributeValueCategory ) +// nolint: golint type ( Keeper = keeper.Keeper Channel = types.Channel diff --git a/x/ibc/04-channel/keeper/handshake_test.go b/x/ibc/04-channel/keeper/handshake_test.go index 216051db7580..eefb7a30cf4d 100644 --- a/x/ibc/04-channel/keeper/handshake_test.go +++ b/x/ibc/04-channel/keeper/handshake_test.go @@ -45,6 +45,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { } for i, tc := range testCases { + tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -134,6 +136,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { } for i, tc := range testCases { + tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -165,7 +169,7 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { _, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenTry( suite.chainA.GetContext(), exported.ORDERED, []string{testConnectionIDB}, testPort2, testChannel2, portCap, counterparty, testChannelVersion, testChannelVersion, - invalidProof{}, uint64(proofHeight), + invalidProof{}, proofHeight, ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } @@ -266,6 +270,8 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { } for i, tc := range testCases { + tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -385,6 +391,8 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { } for i, tc := range testCases { + tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -467,6 +475,8 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { } for i, tc := range testCases { + tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -580,6 +590,8 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { } for i, tc := range testCases { + tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -602,7 +614,7 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { } else { err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanCloseConfirm( suite.chainB.GetContext(), testPort2, testChannel2, channelCap, - invalidProof{}, uint64(proofHeight), + invalidProof{}, proofHeight, ) suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) } diff --git a/x/ibc/04-channel/keeper/keeper_test.go b/x/ibc/04-channel/keeper/keeper_test.go index 92631bf844b2..1f8bcb5c5cbd 100644 --- a/x/ibc/04-channel/keeper/keeper_test.go +++ b/x/ibc/04-channel/keeper/keeper_test.go @@ -14,7 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" @@ -28,8 +27,6 @@ import ( // define constants used for testing const ( - testClientType = clientexported.Tendermint - testClientIDA = "testclientida" testConnectionIDA = "connectionidatob" @@ -47,8 +44,6 @@ const ( testChannelOrder = exported.ORDERED testChannelVersion = "1.0" - testHeight = 1 - trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) diff --git a/x/ibc/04-channel/keeper/packet_test.go b/x/ibc/04-channel/keeper/packet_test.go index 1d8b5a5522c5..c38d68961ec0 100644 --- a/x/ibc/04-channel/keeper/packet_test.go +++ b/x/ibc/04-channel/keeper/packet_test.go @@ -165,6 +165,7 @@ func (suite *KeeperTestSuite) TestRecvPacket() { } for i, tc := range testCases { + tc := tc suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { suite.SetupTest() // reset tc.malleate() diff --git a/x/ibc/04-channel/keeper/timeout.go b/x/ibc/04-channel/keeper/timeout.go index 9917446131e9..21234f9a26b1 100644 --- a/x/ibc/04-channel/keeper/timeout.go +++ b/x/ibc/04-channel/keeper/timeout.go @@ -149,7 +149,7 @@ func (k Keeper) TimeoutExecuted(ctx sdk.Context, packet exported.PacketI) error // never be received (even if the timeoutHeight has not yet been reached). func (k Keeper) TimeoutOnClose( ctx sdk.Context, - packet types.Packet, + packet types.Packet, // nolint: interfacer proof, proofClosed commitmentexported.Proof, proofHeight, diff --git a/x/ibc/04-channel/keeper/timeout_test.go b/x/ibc/04-channel/keeper/timeout_test.go index 58c51b7fbe33..06bd8a76601a 100644 --- a/x/ibc/04-channel/keeper/timeout_test.go +++ b/x/ibc/04-channel/keeper/timeout_test.go @@ -80,6 +80,7 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { } for i, tc := range testCases { + tc := tc suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { suite.SetupTest() // reset tc.malleate() @@ -222,9 +223,7 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { } -type mockTimeoutPacket struct { - timeoutHeight uint64 -} +type mockTimeoutPacket struct{} func newMockTimeoutPacket() mockTimeoutPacket { return mockTimeoutPacket{} diff --git a/x/ibc/20-transfer/handler_test.go b/x/ibc/20-transfer/handler_test.go index 8e4d3060edef..93097a06bfd6 100644 --- a/x/ibc/20-transfer/handler_test.go +++ b/x/ibc/20-transfer/handler_test.go @@ -12,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" @@ -29,10 +28,8 @@ import ( // define constants used for testing const ( - testChainID = "test-chain-id" - testClientIDA = "testclientida" - testClientIDB = "testclientidb" - testClientType = clientexported.Tendermint + testClientIDA = "testclientida" + testClientIDB = "testclientidb" testConnection = "testconnection" testPort1 = "bank" @@ -40,9 +37,6 @@ const ( testChannel1 = "firstchannel" testChannel2 = "secondchannel" - testChannelOrder = channelexported.UNORDERED - testChannelVersion = "1.0" - trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) @@ -73,21 +67,6 @@ func (suite *HandlerTestSuite) SetupTest() { suite.cdc = suite.chainA.App.Codec() } -func (suite *HandlerTestSuite) queryProof(key []byte) (proof commitmenttypes.MerkleProof, height int64) { - res := suite.chainA.App.Query(abci.RequestQuery{ - Path: fmt.Sprintf("store/%s/key", ibctypes.StoreKey), - Data: key, - Prove: true, - }) - - height = res.Height - proof = commitmenttypes.MerkleProof{ - Proof: res.Proof, - } - - return -} - func (suite *HandlerTestSuite) TestHandleMsgTransfer() { handler := transfer.NewHandler(suite.chainA.App.TransferKeeper) @@ -226,6 +205,7 @@ func (chain *TestChain) CreateClient(client *TestChain) error { // ) } +// nolint: unused func (chain *TestChain) updateClient(client *TestChain) { // Create target ctx ctxTarget := chain.GetContext() @@ -304,6 +284,7 @@ func (chain *TestChain) createConnection( return connection } +// nolint: unused func (chain *TestChain) createChannel( portID, channelID, counterpartyPortID, counterpartyChannelID string, state channelexported.State, order exported.Order, connectionID string, diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index 62b73d835395..3c38c0cf473b 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -26,12 +26,10 @@ type Keeper struct { storeKey sdk.StoreKey cdc *codec.Codec - clientKeeper types.ClientKeeper - connectionKeeper types.ConnectionKeeper - channelKeeper types.ChannelKeeper - bankKeeper types.BankKeeper - supplyKeeper types.SupplyKeeper - scopedKeeper capability.ScopedKeeper + channelKeeper types.ChannelKeeper + bankKeeper types.BankKeeper + supplyKeeper types.SupplyKeeper + scopedKeeper capability.ScopedKeeper } // NewKeeper creates a new IBC transfer Keeper instance diff --git a/x/ibc/20-transfer/keeper/keeper_test.go b/x/ibc/20-transfer/keeper/keeper_test.go index e42c4af302b6..9ddbd3b2f385 100644 --- a/x/ibc/20-transfer/keeper/keeper_test.go +++ b/x/ibc/20-transfer/keeper/keeper_test.go @@ -13,7 +13,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" @@ -28,10 +27,8 @@ import ( // define constants used for testing const ( - testChainID = "test-chain-id" - testClientIDA = "testclientIDA" - testClientIDB = "testClientIDb" - testClientType = clientexported.Tendermint + testClientIDA = "testclientIDA" + testClientIDB = "testClientIDb" testConnection = "testconnectionatob" testPort1 = "bank" @@ -39,9 +36,6 @@ const ( testChannel1 = "firstchannel" testChannel2 = "secondchannel" - testChannelOrder = channelexported.UNORDERED - testChannelVersion = "1.0" - trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) diff --git a/x/ibc/20-transfer/keeper/relay_test.go b/x/ibc/20-transfer/keeper/relay_test.go index 246987dcf4f9..df878f8fe629 100644 --- a/x/ibc/20-transfer/keeper/relay_test.go +++ b/x/ibc/20-transfer/keeper/relay_test.go @@ -81,6 +81,7 @@ func (suite *KeeperTestSuite) TestSendTransfer() { for i, tc := range testCases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset @@ -144,6 +145,7 @@ func (suite *KeeperTestSuite) TestReceiveTransfer() { for i, tc := range testCases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset tc.malleate() @@ -196,6 +198,7 @@ func (suite *KeeperTestSuite) TestTimeoutTransfer() { for i, tc := range testCases { tc := tc + i := i suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset tc.malleate() diff --git a/x/ibc/23-commitment/types/merkle_test.go b/x/ibc/23-commitment/types/merkle_test.go index bb287ecde634..6694ef07fa7d 100644 --- a/x/ibc/23-commitment/types/merkle_test.go +++ b/x/ibc/23-commitment/types/merkle_test.go @@ -56,8 +56,10 @@ func (suite *MerkleTestSuite) TestVerifyMembership() { err := proof.VerifyMembership(root, path, tc.value) if tc.shouldPass { + // nolint: scopelint suite.Require().NoError(err, "test case %d should have passed", i) } else { + // nolint: scopelint suite.Require().Error(err, "test case %d should have failed", i) } }) @@ -109,8 +111,10 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() { err := proof.VerifyNonMembership(root, path) if tc.shouldPass { + // nolint: scopelint suite.Require().NoError(err, "test case %d should have passed", i) } else { + // nolint: scopelint suite.Require().Error(err, "test case %d should have failed", i) } }) diff --git a/x/ibc/ante/ante_test.go b/x/ibc/ante/ante_test.go index a2e9bb463ca3..54d74f8ec6da 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/ante/ante_test.go @@ -13,7 +13,6 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" @@ -30,17 +29,10 @@ import ( // define constants used for testing const ( - testChainID = "test-chain-id" testClientIDA = "testclientida" testClientIDB = "testclientidb" - testClientType = clientexported.Tendermint - testConnection = "testconnection" - testChannelVersion = "1.0" - - height = 10 - trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 ) From 6d6c83229bfbf3502531bcf04ed25531174ac39a Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Wed, 8 Apr 2020 14:46:32 -0400 Subject: [PATCH 174/176] x/ibc: changelog (#5960) * x/ibc: changelog * add reference to the spec --- CHANGELOG.md | 16 +++++++++++++--- x/ibc/spec/README.md | 39 +++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84555f11f9da..59e22714749f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,17 +79,27 @@ to now accept a `codec.JSONMarshaler` for modular serialization of genesis state * (crypto) [\#5880](https://github.com/cosmos/cosmos-sdk/pull/5880) Merge `crypto/keys/mintkey` into `crypto`. * (crypto/hd) [\#5904](https://github.com/cosmos/cosmos-sdk/pull/5904) `crypto/keys/hd` moved to `crypto/hd`. * (crypto/keyring): - - [\#5866](https://github.com/cosmos/cosmos-sdk/pull/5866) Rename `crypto/keys/` to `crypto/keyring/`. - - [\#5904](https://github.com/cosmos/cosmos-sdk/pull/5904) `Keybase` -> `Keyring` interfaces migration. `LegacyKeybase` interface is added in order + * [\#5866](https://github.com/cosmos/cosmos-sdk/pull/5866) Rename `crypto/keys/` to `crypto/keyring/`. + * [\#5904](https://github.com/cosmos/cosmos-sdk/pull/5904) `Keybase` -> `Keyring` interfaces migration. `LegacyKeybase` interface is added in order to guarantee limited backward compatibility with the old Keybase interface for the sole purpose of migrating keys across the new keyring backends. `NewLegacy` constructor is provided [\#5889](https://github.com/cosmos/cosmos-sdk/pull/5889) to allow for smooth migration of keys from the legacy LevelDB based implementation to new keyring backends. Plus, the package and the new keyring no longer depends on the sdk.Config singleton. Please consult the package documentation for more information on how to implement the new `Keyring` interface. - - [\#5858](https://github.com/cosmos/cosmos-sdk/pull/5858) Make Keyring store keys by name and address's hexbytes representation. + * [\#5858](https://github.com/cosmos/cosmos-sdk/pull/5858) Make Keyring store keys by name and address's hexbytes representation. ### Features * (x/ibc) [\#5588](https://github.com/cosmos/cosmos-sdk/pull/5588) Add [ICS 024 - Host State Machine Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements) subpackage to `x/ibc` module. +* (x/ibc) [\#5277](https://github.com/cosmos/cosmos-sdk/pull/5277) `x/ibc` changes from IBC alpha. For more details check the the [`x/ibc/spec`](https://github.com/cosmos/tree/master/x/ibc/spec) directory: + * [ICS 002 - Client Semantics](https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics) subpackage + * [ICS 003 - Connection Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-003-connection-semantics) subpackage + * [ICS 004 - Channel and Packet Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-004-channel-and-packet-semantics) subpackage + * [ICS 005 - Port Allocation](https://github.com/cosmos/ics/blob/master/spec/ics-005-port-allocation) subpackage + * [ICS 007 - Tendermint Client](https://github.com/cosmos/ics/blob/master/spec/ics-007-tendermint-client) subpackage + * [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer) module + * [ICS 023 - Vector Commitments](https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments) subpackage + * (ibc/ante) Implement IBC `AnteHandler` as per [ADR 15 - IBC Packet Receiver](https://github.com/cosmos/tree/master/docs/architecture/adr-015-ibc-packet-receiver.md). +* (x/capability) [\#5828](https://github.com/cosmos/cosmos-sdk/pull/5828) Capability module integration as outlined in [ADR 3 - Dynamic Capability Store](https://github.com/cosmos/tree/master/docs/architecture/adr-003-dynamic-capability-store.md). ### Bug Fixes diff --git a/x/ibc/spec/README.md b/x/ibc/spec/README.md index 9023949b8294..ddaec62fab33 100644 --- a/x/ibc/spec/README.md +++ b/x/ibc/spec/README.md @@ -36,34 +36,37 @@ transaction routing through `Handlers`. The following list is a mapping from each Interchain Standard to their implementation in the SDK's `x/ibc` module: -- [ICS 002 - Client Semantics](https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics): Implemented in [`x/ibc/02-client`](https://github.com/cosmos/x/ibc/02-client) -- [ICS 003 - Connection Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-003-connection-semantics): Implemented in [`x/ibc/03-connection`](https://github.com/cosmos/x/ibc/03-connection) -- [ICS 004 - Channel and Packet Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-004-channel-and-packet-semantics): Implemented in [`x/ibc/04-channel`](https://github.com/cosmos/x/ibc/04-channel) -- [ICS 005 - Port Allocation](https://github.com/cosmos/ics/blob/master/spec/ics-005-port-allocation): Implemented in [`x/ibc/05-port`](https://github.com/cosmos/x/ibc/05-port) -- [ICS 006 - Solo Machine Client](https://github.com/cosmos/ics/blob/master/spec/ics-006-solo-machine-client): To be implemented in [`x/ibc/06-solo`](https://github.com/cosmos/x/ibc/06-solo) -- [ICS 007 - Tendermint Client](https://github.com/cosmos/ics/blob/master/spec/ics-007-tendermint-client): Implemented in [`x/ibc/07-tendermint`](https://github.com/cosmos/x/ibc/07-tendermint) -- [ICS 009 - Loopback Client](https://github.com/cosmos/ics/blob/master/spec/ics-009-loopback-client): To be implemented in [`x/ibc/09-loopback`](https://github.com/cosmos/x/ibc/09-loopback) -- [ICS 018- Relayer Algorithms](https://github.com/cosmos/ics/tree/master/spec/ics-018-relayer-algorithms): Implemented in it's own [relayer repository](https://github.com/cosmos/relayer) -- [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer): Implemented in [`x/ibc/20-transfer`](https://github.com/cosmos/x/ibc/20-transfer) -- [ICS 023 - Vector Commitments](https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments): Implemented in [`x/ibc/23-commitment`](https://github.com/cosmos/x/ibc/23-commitment) -- [ICS 024 - Host Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements): Implemented in [`x/ibc/24-host`](https://github.com/cosmos/x/ibc/24-host) -- [ICS 025 - Handler Interface](https://github.com/cosmos/ics/tree/master/spec/ics-025-handler-interface): Handler interfaces are implemented at the top level in `x/ibc/handler.go`, +* [ICS 002 - Client Semantics](https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics): Implemented in [`x/ibc/02-client`](https://github.com/cosmos/x/ibc/02-client) +* [ICS 003 - Connection Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-003-connection-semantics): Implemented in [`x/ibc/03-connection`](https://github.com/cosmos/x/ibc/03-connection) +* [ICS 004 - Channel and Packet Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-004-channel-and-packet-semantics): Implemented in [`x/ibc/04-channel`](https://github.com/cosmos/x/ibc/04-channel) +* [ICS 005 - Port Allocation](https://github.com/cosmos/ics/blob/master/spec/ics-005-port-allocation): Implemented in [`x/ibc/05-port`](https://github.com/cosmos/x/ibc/05-port) +* [ICS 006 - Solo Machine Client](https://github.com/cosmos/ics/blob/master/spec/ics-006-solo-machine-client): To be implemented in [`x/ibc/06-solo`](https://github.com/cosmos/x/ibc/06-solo) +* [ICS 007 - Tendermint Client](https://github.com/cosmos/ics/blob/master/spec/ics-007-tendermint-client): Implemented in [`x/ibc/07-tendermint`](https://github.com/cosmos/x/ibc/07-tendermint) +* [ICS 009 - Loopback Client](https://github.com/cosmos/ics/blob/master/spec/ics-009-loopback-client): To be implemented in [`x/ibc/09-loopback`](https://github.com/cosmos/x/ibc/09-loopback) +* [ICS 018- Relayer Algorithms](https://github.com/cosmos/ics/tree/master/spec/ics-018-relayer-algorithms): Implemented in it's own [relayer repository](https://github.com/cosmos/relayer) +* [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer): Implemented in [`x/ibc/20-transfer`](https://github.com/cosmos/x/ibc/20-transfer) +* [ICS 023 - Vector Commitments](https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments): Implemented in [`x/ibc/23-commitment`](https://github.com/cosmos/x/ibc/23-commitment) +* [ICS 024 - Host Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements): Implemented in [`x/ibc/24-host`](https://github.com/cosmos/x/ibc/24-host) +* [ICS 025 - Handler Interface](https://github.com/cosmos/ics/tree/master/spec/ics-025-handler-interface): Handler interfaces are implemented at the top level in `x/ibc/handler.go`, which call each ICS submodule's handlers (i.e `x/ibc/{XX-ICS}/handler.go`). -- [ICS 026 - Routing Module](https://github.com/cosmos/ics/blob/master/spec/ics-026-routing-module): Replaced by [ADR 15 - IBC Packet Receiver](../../../docs/architecture/adr-015-ibc-packet-receiver.md). +* [ICS 026 - Routing Module](https://github.com/cosmos/ics/blob/master/spec/ics-026-routing-module): Replaced by [ADR 15 - IBC Packet Receiver](../../../docs/architecture/adr-015-ibc-packet-receiver.md). ### Architecture Decision Records (ADR) The following ADR provide the design and architecture decision of IBC-related components. -- [ADR 10 - Modular AnteHandler](../../../docs/architecture/adr-010-modular-antehandler.md): Introduces a decorator pattern for the [`AnteHandler`](../../../docs/basics/gas-fees.md#antehandler), making it modular. -- [ADR 15 - IBC Packet Receiver](../../../docs/architecture/adr-015-ibc-packet-receiver.md): replaces the ICS26 routing module with [`AnteHandler`](../../../docs/basics/gas-fees.md#antehandler) logic within IBC. This is implemented using the `AnteDecorators` defined in [ADR10]((../../../docs/architecture/adr-010-modular-antehandler.md)) -- [ADR 17 - Historical Header Module](../../../docs/architecture/adr-017-historical-header-module.md): Introduces the ability to introspect past +* [ADR 10 - Modular AnteHandler](../../../docs/architecture/adr-010-modular-antehandler.md): Introduces a decorator pattern for the [`AnteHandler`](../../../docs/basics/gas-fees.md#antehandler), making it modular. +* [ADR 15 - IBC Packet Receiver](../../../docs/architecture/adr-015-ibc-packet-receiver.md): replaces the ICS26 routing module with [`AnteHandler`](../../../docs/basics/gas-fees.md#antehandler) logic within IBC. This is implemented using the `AnteDecorators` defined in [ADR10]((../../../docs/architecture/adr-010-modular-antehandler.md)) +* [ADR 17 - Historical Header Module](../../../docs/architecture/adr-017-historical-header-module.md): Introduces the ability to introspect past consensus states in order to verify their membership in the counterparty clients. -- [ADR 19 - Protobuf State Encoding](../../../docs/architecture/adr-019-protobuf-state-encoding.md): Migration from Amino to Protobuf for state encoding. +* [ADR 19 - Protobuf State Encoding](../../../docs/architecture/adr-019-protobuf-state-encoding.md): Migration from Amino to Protobuf for state encoding. +* [ADR 020 - Protocol Buffer Transaction Encoding](./../../docs/architecture/adr-020-protobuf-transaction-encoding.md): Client side migration to Protobuf. +* [ADR 021 - Protocol Buffer Query Encoding](./../../docs/architecture/adr-020-protobuf-query-encoding.md): Queries migration to Protobuf. ### SDK Modules -- [`x/evidence`](https://github.com/cosmos/x/evidence): The evidence module provides the interfaces and client logic to handle light client misbehaviour. Check [ADR 09 - Evidence Module](../../../docs/architecture/adr-009-evidence-module.md) for more details. +* [`x/capability`](https://github.com/cosmos/tree/master/x/capability): The capability module provides object-capability keys support through scoped keepers in order to authenticate usage of ports or channels. Check [ADR 3 - Dynamic Capability Store](../../../docs/architecture/adr-003-dynamic-capability-store.md) for more details. +* [`x/evidence`](https://github.com/cosmos/tree/master/x/evidence): The evidence module provides the interfaces and client logic to handle light client misbehaviour. Check [ADR 09 - Evidence Module](../../../docs/architecture/adr-009-evidence-module.md) for more details. ## IBC module architecture From b85f82e210662b0765dc68373e8c34a242d2be17 Mon Sep 17 00:00:00 2001 From: Aditya Date: Thu, 9 Apr 2020 04:49:04 +0530 Subject: [PATCH 175/176] Merge PR #5954: Bind Transfer Port on InitChain * Bind transfer port in InitChain * push fixes * address @fedekunze review * Apply suggestions from code review * lint Co-authored-by: Jack Zampolin Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze --- simapp/app.go | 28 +++++++++++---------- x/auth/ante/ante_test.go | 26 +++++++++---------- x/capability/keeper/keeper.go | 6 +++++ x/capability/keeper/keeper_test.go | 8 +++--- x/ibc/05-port/types/router.go | 3 ++- x/ibc/20-transfer/genesis.go | 18 +++++++++++++ x/ibc/20-transfer/keeper/keeper.go | 12 ++++++++- x/ibc/20-transfer/module.go | 6 ++--- x/ibc/20-transfer/types/expected_keepers.go | 5 ++++ x/ibc/20-transfer/types/keys.go | 2 +- x/ibc/keeper/keeper.go | 9 ++++--- x/ibc/keeper/keeper_test.go | 4 +-- x/ibc/module.go | 8 +++--- 13 files changed, 90 insertions(+), 45 deletions(-) diff --git a/simapp/app.go b/simapp/app.go index 5c80409a1a67..47611b3f408c 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -120,7 +120,7 @@ type SimApp struct { CrisisKeeper crisis.Keeper UpgradeKeeper upgrade.Keeper ParamsKeeper params.Keeper - IBCKeeper ibc.Keeper + IBCKeeper *ibc.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly EvidenceKeeper evidence.Keeper TransferKeeper transfer.Keeper @@ -212,16 +212,6 @@ func NewSimApp( ) app.UpgradeKeeper = upgrade.NewKeeper(skipUpgradeHeights, keys[upgrade.StoreKey], appCodec, homePath) - // create evidence keeper with router - evidenceKeeper := evidence.NewKeeper( - appCodec, keys[evidence.StoreKey], app.subspaces[evidence.ModuleName], &app.StakingKeeper, app.SlashingKeeper, - ) - evidenceRouter := evidence.NewRouter(). - AddRoute(ibcclient.RouterKey, ibcclient.HandlerClientMisbehaviour(app.IBCKeeper.ClientKeeper)) - - evidenceKeeper.SetRouter(evidenceRouter) - app.EvidenceKeeper = *evidenceKeeper - // register the proposal types govRouter := gov.NewRouter() govRouter.AddRoute(gov.RouterKey, gov.ProposalHandler). @@ -247,7 +237,8 @@ func NewSimApp( // Create Transfer Keepers app.TransferKeeper = transfer.NewKeeper( app.cdc, keys[transfer.StoreKey], - app.IBCKeeper.ChannelKeeper, app.BankKeeper, app.SupplyKeeper, + app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, + app.BankKeeper, app.SupplyKeeper, scopedTransferKeeper, ) transferModule := transfer.NewAppModule(app.TransferKeeper) @@ -257,6 +248,16 @@ func NewSimApp( ibcRouter.AddRoute(transfer.ModuleName, transferModule) app.IBCKeeper.SetRouter(ibcRouter) + // create evidence keeper with router + evidenceKeeper := evidence.NewKeeper( + appCodec, keys[evidence.StoreKey], app.subspaces[evidence.ModuleName], &app.StakingKeeper, app.SlashingKeeper, + ) + evidenceRouter := evidence.NewRouter(). + AddRoute(ibcclient.RouterKey, ibcclient.HandlerClientMisbehaviour(app.IBCKeeper.ClientKeeper)) + + evidenceKeeper.SetRouter(evidenceRouter) + app.EvidenceKeeper = *evidenceKeeper + // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. app.mm = module.NewManager( @@ -289,6 +290,7 @@ func NewSimApp( auth.ModuleName, distr.ModuleName, staking.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName, mint.ModuleName, supply.ModuleName, crisis.ModuleName, ibc.ModuleName, genutil.ModuleName, evidence.ModuleName, + transfer.ModuleName, ) app.mm.RegisterInvariants(&app.CrisisKeeper) @@ -321,7 +323,7 @@ func NewSimApp( app.SetBeginBlocker(app.BeginBlocker) app.SetAnteHandler( ante.NewAnteHandler( - app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, + app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer, ), ) diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index 0f211dbe9c1a..25b6b2ed33e0 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -38,7 +38,7 @@ func TestSimulateGasCost(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -92,7 +92,7 @@ func TestSimulateGasCost(t *testing.T) { func TestAnteHandlerSigErrors(t *testing.T) { // setup app, ctx := createTestApp(true) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -142,7 +142,7 @@ func TestAnteHandlerAccountNumbers(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -201,7 +201,7 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(0) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -259,7 +259,7 @@ func TestAnteHandlerSequences(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -335,7 +335,7 @@ func TestAnteHandlerSequences(t *testing.T) { func TestAnteHandlerFees(t *testing.T) { // setup app, ctx := createTestApp(true) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -377,7 +377,7 @@ func TestAnteHandlerMemoGas(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -417,7 +417,7 @@ func TestAnteHandlerMultiSigner(t *testing.T) { // setup app, ctx := createTestApp(false) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -467,7 +467,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -544,7 +544,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -662,7 +662,7 @@ func TestAnteHandlerSigLimitExceeded(t *testing.T) { // setup app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // keys and addresses priv1, _, addr1 := types.KeyTestPubAddr() @@ -703,7 +703,7 @@ func TestCustomSignatureVerificationGasConsumer(t *testing.T) { app, ctx := createTestApp(true) ctx = ctx.WithBlockHeight(1) // setup an ante handler that only accepts PubKeyEd25519 - anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, func(meter sdk.GasMeter, sig []byte, pubkey crypto.PubKey, params types.Params) error { + anteHandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, func(meter sdk.GasMeter, sig []byte, pubkey crypto.PubKey, params types.Params) error { switch pubkey := pubkey.(type) { case ed25519.PubKeyEd25519: meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519") @@ -761,7 +761,7 @@ func TestAnteHandlerReCheck(t *testing.T) { app.AccountKeeper.SetAccount(ctx, acc1) app.BankKeeper.SetBalances(ctx, addr1, types.NewTestCoins()) - antehandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) + antehandler := ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer) // test that operations skipped on recheck do not run diff --git a/x/capability/keeper/keeper.go b/x/capability/keeper/keeper.go index 8fc4b5e6cb7e..42b7ce5f3d09 100644 --- a/x/capability/keeper/keeper.go +++ b/x/capability/keeper/keeper.go @@ -114,6 +114,12 @@ func (k *Keeper) InitializeAndSeal(ctx sdk.Context) { k.sealed = true } +// GetLatestIndex returns the latest index of the CapabilityKeeper +func (k Keeper) GetLatestIndex(ctx sdk.Context) uint64 { + store := ctx.KVStore(k.storeKey) + return types.IndexFromKey(store.Get(types.KeyIndex)) +} + // NewCapability attempts to create a new capability with a given name. If the // capability already exists in the in-memory store, an error will be returned. // Otherwise, a new capability is created with the current global unique index. diff --git a/x/capability/keeper/keeper_test.go b/x/capability/keeper/keeper_test.go index 127116dbebbd..d1c0fd10b411 100644 --- a/x/capability/keeper/keeper_test.go +++ b/x/capability/keeper/keeper_test.go @@ -22,7 +22,6 @@ type KeeperTestSuite struct { ctx sdk.Context keeper *keeper.Keeper - app *simapp.SimApp } func (suite *KeeperTestSuite) SetupTest() { @@ -35,19 +34,20 @@ func (suite *KeeperTestSuite) SetupTest() { suite.ctx = app.BaseApp.NewContext(checkTx, abci.Header{Height: 1}) suite.keeper = keeper - suite.app = app } func (suite *KeeperTestSuite) TestInitializeAndSeal() { sk := suite.keeper.ScopeToModule(bank.ModuleName) caps := make([]*types.Capability, 5) + // Get Latest Index before creating new ones to sychronize indices correctly + prevIndex := suite.keeper.GetLatestIndex(suite.ctx) for i := range caps { cap, err := sk.NewCapability(suite.ctx, fmt.Sprintf("transfer-%d", i)) suite.Require().NoError(err) suite.Require().NotNil(cap) - suite.Require().Equal(uint64(i), cap.GetIndex()) + suite.Require().Equal(uint64(i)+prevIndex, cap.GetIndex()) caps[i] = cap } @@ -60,7 +60,7 @@ func (suite *KeeperTestSuite) TestInitializeAndSeal() { got, ok := sk.GetCapability(suite.ctx, fmt.Sprintf("transfer-%d", i)) suite.Require().True(ok) suite.Require().Equal(cap, got) - suite.Require().Equal(uint64(i), got.GetIndex()) + suite.Require().Equal(uint64(i)+prevIndex, got.GetIndex()) } suite.Require().Panics(func() { diff --git a/x/ibc/05-port/types/router.go b/x/ibc/05-port/types/router.go index cb4a5cd79edd..6bfba9076abd 100644 --- a/x/ibc/05-port/types/router.go +++ b/x/ibc/05-port/types/router.go @@ -52,7 +52,8 @@ func (rtr *Router) AddRoute(module string, cbs IBCModule) *Router { // HasRoute returns true if the Router has a module registered or false otherwise. func (rtr *Router) HasRoute(module string) bool { - return rtr.routes[module] != nil + _, ok := rtr.routes[module] + return ok } // GetRoute returns a IBCModule for a given module. diff --git a/x/ibc/20-transfer/genesis.go b/x/ibc/20-transfer/genesis.go index facde722a27d..eefeedd812cd 100644 --- a/x/ibc/20-transfer/genesis.go +++ b/x/ibc/20-transfer/genesis.go @@ -7,8 +7,26 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ) +// GenesisState is currently only used to ensure that the InitGenesis gets run +// by the module manager +type GenesisState struct { + Version string `json:"version,omitempty" yaml:"version,omitempty"` +} + +func DefaultGenesis() GenesisState { + return GenesisState{ + Version: types.Version, + } +} + // InitGenesis sets distribution information for genesis func InitGenesis(ctx sdk.Context, keeper Keeper) { + // transfer module binds to the transfer port on InitChain + // and claims the returned capability + err := keeper.BindPort(ctx, types.PortID) + if err != nil { + panic(fmt.Sprintf("could not claim port capability: %v", err)) + } // check if the module account exists moduleAcc := keeper.GetTransferAccount(ctx) if moduleAcc == nil { diff --git a/x/ibc/20-transfer/keeper/keeper.go b/x/ibc/20-transfer/keeper/keeper.go index 3c38c0cf473b..ffc6550a47a9 100644 --- a/x/ibc/20-transfer/keeper/keeper.go +++ b/x/ibc/20-transfer/keeper/keeper.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/capability" channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" + porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types" "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types" ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types" supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported" @@ -27,6 +28,7 @@ type Keeper struct { cdc *codec.Codec channelKeeper types.ChannelKeeper + portKeeper types.PortKeeper bankKeeper types.BankKeeper supplyKeeper types.SupplyKeeper scopedKeeper capability.ScopedKeeper @@ -35,7 +37,7 @@ type Keeper struct { // NewKeeper creates a new IBC transfer Keeper instance func NewKeeper( cdc *codec.Codec, key sdk.StoreKey, - channelKeeper types.ChannelKeeper, + channelKeeper types.ChannelKeeper, portKeeper types.PortKeeper, bankKeeper types.BankKeeper, supplyKeeper types.SupplyKeeper, scopedKeeper capability.ScopedKeeper, ) Keeper { @@ -49,6 +51,7 @@ func NewKeeper( storeKey: key, cdc: cdc, channelKeeper: channelKeeper, + portKeeper: portKeeper, bankKeeper: bankKeeper, supplyKeeper: supplyKeeper, scopedKeeper: scopedKeeper, @@ -82,6 +85,13 @@ func (k Keeper) ChanCloseInit(ctx sdk.Context, portID, channelID string) error { return k.channelKeeper.ChanCloseInit(ctx, portID, channelID, chanCap) } +// BindPort defines a wrapper function for the ort Keeper's function in +// order to expose it to module's InitGenesis function +func (k Keeper) BindPort(ctx sdk.Context, portID string) error { + cap := k.portKeeper.BindPort(ctx, portID) + return k.ClaimCapability(ctx, cap, porttypes.PortPath(portID)) +} + // TimeoutExecuted defines a wrapper function for the channel Keeper's function // in order to expose it to the ICS20 transfer handler. func (k Keeper) TimeoutExecuted(ctx sdk.Context, packet channelexported.PacketI) error { diff --git a/x/ibc/20-transfer/module.go b/x/ibc/20-transfer/module.go index 5d09a1da36b4..83f3d0260eda 100644 --- a/x/ibc/20-transfer/module.go +++ b/x/ibc/20-transfer/module.go @@ -46,8 +46,8 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { // DefaultGenesis returns default genesis state as raw bytes for the ibc // transfer module. -func (AppModuleBasic) DefaultGenesis(_ codec.JSONMarshaler) json.RawMessage { - return nil +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage { + return cdc.MustMarshalJSON(DefaultGenesis()) } // ValidateGenesis performs genesis state validation for the ibc transfer module. @@ -235,7 +235,7 @@ func (am AppModule) OnRecvPacket( packet channeltypes.Packet, ) (*sdk.Result, error) { var data FungibleTokenPacketData - if err := types.ModuleCdc.UnmarshalBinaryBare(packet.GetData(), &data); err != nil { + if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) } return handlePacketDataTransfer(ctx, am.keeper, packet, data) diff --git a/x/ibc/20-transfer/types/expected_keepers.go b/x/ibc/20-transfer/types/expected_keepers.go index 2abc95b45854..9e924ee8702d 100644 --- a/x/ibc/20-transfer/types/expected_keepers.go +++ b/x/ibc/20-transfer/types/expected_keepers.go @@ -35,6 +35,11 @@ type ConnectionKeeper interface { GetConnection(ctx sdk.Context, connectionID string) (connection connection.ConnectionEnd, found bool) } +// PortKeeper defines the expected IBC port keeper +type PortKeeper interface { + BindPort(ctx sdk.Context, portID string) *capability.Capability +} + // SupplyKeeper expected supply keeper type SupplyKeeper interface { GetModuleAddress(name string) sdk.AccAddress diff --git a/x/ibc/20-transfer/types/keys.go b/x/ibc/20-transfer/types/keys.go index 5dd17e49b717..28f36745d61d 100644 --- a/x/ibc/20-transfer/types/keys.go +++ b/x/ibc/20-transfer/types/keys.go @@ -18,7 +18,7 @@ const ( Version = "ics20-1" // PortID that transfer module binds to - PortID = "bank" + PortID = "transfer" // StoreKey is the store key string for IBC transfer StoreKey = ModuleName diff --git a/x/ibc/keeper/keeper.go b/x/ibc/keeper/keeper.go index 3052c2e25ad2..7b528bbf5c88 100644 --- a/x/ibc/keeper/keeper.go +++ b/x/ibc/keeper/keeper.go @@ -22,13 +22,13 @@ type Keeper struct { // NewKeeper creates a new ibc Keeper func NewKeeper( cdc *codec.Codec, key sdk.StoreKey, stakingKeeper client.StakingKeeper, scopedKeeper capability.ScopedKeeper, -) Keeper { +) *Keeper { clientKeeper := client.NewKeeper(cdc, key, stakingKeeper) connectionKeeper := connection.NewKeeper(cdc, key, clientKeeper) portKeeper := port.NewKeeper(scopedKeeper) channelKeeper := channel.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper, scopedKeeper) - return Keeper{ + return &Keeper{ ClientKeeper: clientKeeper, ConnectionKeeper: connectionKeeper, ChannelKeeper: channelKeeper, @@ -37,7 +37,10 @@ func NewKeeper( } // Set the Router in IBC Keeper and seal it -func (k Keeper) SetRouter(rtr *port.Router) { +func (k *Keeper) SetRouter(rtr *port.Router) { + if k.Router != nil && k.Router.Sealed() { + panic("cannot reset a sealed router") + } k.Router = rtr k.Router.Seal() } diff --git a/x/ibc/keeper/keeper_test.go b/x/ibc/keeper/keeper_test.go index acf6b4a52241..c5b7aa70887a 100644 --- a/x/ibc/keeper/keeper_test.go +++ b/x/ibc/keeper/keeper_test.go @@ -28,8 +28,8 @@ func (suite *KeeperTestSuite) SetupTest() { suite.cdc = app.Codec() suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) - suite.keeper = &app.IBCKeeper - suite.querier = keeper.NewQuerier(app.IBCKeeper) + suite.keeper = app.IBCKeeper + suite.querier = keeper.NewQuerier(*app.IBCKeeper) } func TestKeeperTestSuite(t *testing.T) { diff --git a/x/ibc/module.go b/x/ibc/module.go index acb96a3bfedf..a6168fba8038 100644 --- a/x/ibc/module.go +++ b/x/ibc/module.go @@ -76,11 +76,11 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { // AppModule implements an application module for the ibc module. type AppModule struct { AppModuleBasic - keeper Keeper + keeper *Keeper } // NewAppModule creates a new AppModule object -func NewAppModule(k Keeper) AppModule { +func NewAppModule(k *Keeper) AppModule { return AppModule{ keeper: k, } @@ -103,7 +103,7 @@ func (AppModule) Route() string { // NewHandler returns an sdk.Handler for the ibc module. func (am AppModule) NewHandler() sdk.Handler { - return NewHandler(am.keeper) + return NewHandler(*am.keeper) } // QuerierRoute returns the ibc module's querier route name. @@ -113,7 +113,7 @@ func (AppModule) QuerierRoute() string { // NewQuerierHandler returns the ibc module sdk.Querier. func (am AppModule) NewQuerierHandler() sdk.Querier { - return NewQuerier(am.keeper) + return NewQuerier(*am.keeper) } // InitGenesis performs genesis initialization for the ibc module. It returns From f36eef30368fd1973fc13d32726ec05564bda912 Mon Sep 17 00:00:00 2001 From: Aditya Sripal Date: Thu, 9 Apr 2020 07:07:19 +0530 Subject: [PATCH 176/176] prove counterparty version is in expected channel --- x/ibc/04-channel/keeper/handshake.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/ibc/04-channel/keeper/handshake.go b/x/ibc/04-channel/keeper/handshake.go index c836314c1836..c9074f975733 100644 --- a/x/ibc/04-channel/keeper/handshake.go +++ b/x/ibc/04-channel/keeper/handshake.go @@ -134,7 +134,7 @@ func (k Keeper) ChanOpenTry( expectedCounterparty := types.NewCounterparty(portID, channelID) expectedChannel := types.NewChannel( exported.INIT, channel.Ordering, expectedCounterparty, - counterpartyHops, channel.Version, + counterpartyHops, counterpartyVersion, ) if err := k.connectionKeeper.VerifyChannelState( @@ -205,7 +205,7 @@ func (k Keeper) ChanOpenAck( counterparty := types.NewCounterparty(portID, channelID) expectedChannel := types.NewChannel( exported.TRYOPEN, channel.Ordering, counterparty, - counterpartyHops, channel.Version, + counterpartyHops, counterpartyVersion, ) if err := k.connectionKeeper.VerifyChannelState(